summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJean-Baptiste Queru <jbq@google.com>2009-11-15 12:06:06 -0800
committerJean-Baptiste Queru <jbq@google.com>2009-11-15 12:06:07 -0800
commit011ea3e96111a8c602f0ad256a78ecbe6d78a23c (patch)
tree568e82009b7d4e9f69435e8b1503ebdd8d5cb7c3
parent618669a0423554a0af43cd0aa42101fc80b7d948 (diff)
parenta8c89077d78769bf4840fa91609edc51fe2fa02d (diff)
downloadandroid_external_sonivox-011ea3e96111a8c602f0ad256a78ecbe6d78a23c.tar.gz
android_external_sonivox-011ea3e96111a8c602f0ad256a78ecbe6d78a23c.tar.bz2
android_external_sonivox-011ea3e96111a8c602f0ad256a78ecbe6d78a23c.zip
merge from eclair
-rw-r--r--arm-fm-22k/host_src/eas.h2100
-rw-r--r--arm-fm-22k/host_src/eas_build.h48
-rw-r--r--arm-fm-22k/host_src/eas_chorus.h80
-rw-r--r--arm-fm-22k/host_src/eas_config.c1214
-rw-r--r--arm-fm-22k/host_src/eas_config.h358
-rw-r--r--arm-fm-22k/host_src/eas_debugmsgs.h86
-rw-r--r--arm-fm-22k/host_src/eas_host.h142
-rw-r--r--arm-fm-22k/host_src/eas_hostmm.c1296
-rw-r--r--arm-fm-22k/host_src/eas_main.c898
-rw-r--r--arm-fm-22k/host_src/eas_report.c504
-rw-r--r--arm-fm-22k/host_src/eas_report.h130
-rw-r--r--arm-fm-22k/host_src/eas_reverb.h84
-rw-r--r--arm-fm-22k/host_src/eas_types.h512
-rw-r--r--arm-fm-22k/host_src/eas_wave.c822
-rw-r--r--arm-fm-22k/host_src/eas_wave.h124
-rw-r--r--arm-fm-22k/lib_src/eas_audioconst.h170
-rw-r--r--arm-fm-22k/lib_src/eas_chorus.c1184
-rw-r--r--arm-fm-22k/lib_src/eas_chorusdata.c44
-rw-r--r--arm-fm-22k/lib_src/eas_chorusdata.h296
-rw-r--r--arm-fm-22k/lib_src/eas_ctype.h58
-rw-r--r--arm-fm-22k/lib_src/eas_data.c50
-rw-r--r--arm-fm-22k/lib_src/eas_data.h238
-rw-r--r--arm-fm-22k/lib_src/eas_effects.h98
-rw-r--r--arm-fm-22k/lib_src/eas_fmengine.c1546
-rw-r--r--arm-fm-22k/lib_src/eas_fmengine.h218
-rw-r--r--arm-fm-22k/lib_src/eas_fmsndlib.c3324
-rw-r--r--arm-fm-22k/lib_src/eas_fmsynth.c1796
-rw-r--r--arm-fm-22k/lib_src/eas_fmsynth.h138
-rw-r--r--arm-fm-22k/lib_src/eas_fmtables.c712
-rw-r--r--arm-fm-22k/lib_src/eas_ima_tables.c84
-rw-r--r--arm-fm-22k/lib_src/eas_imaadpcm.c712
-rw-r--r--arm-fm-22k/lib_src/eas_imelody.c3452
-rw-r--r--arm-fm-22k/lib_src/eas_imelodydata.c62
-rw-r--r--arm-fm-22k/lib_src/eas_imelodydata.h122
-rw-r--r--arm-fm-22k/lib_src/eas_math.c312
-rw-r--r--arm-fm-22k/lib_src/eas_math.h800
-rw-r--r--arm-fm-22k/lib_src/eas_midi.c1114
-rw-r--r--arm-fm-22k/lib_src/eas_midi.h118
-rw-r--r--arm-fm-22k/lib_src/eas_midictrl.h104
-rw-r--r--arm-fm-22k/lib_src/eas_mididata.c44
-rw-r--r--arm-fm-22k/lib_src/eas_miditypes.h252
-rw-r--r--arm-fm-22k/lib_src/eas_mixbuf.c48
-rw-r--r--arm-fm-22k/lib_src/eas_mixer.c904
-rw-r--r--arm-fm-22k/lib_src/eas_mixer.h250
-rw-r--r--arm-fm-22k/lib_src/eas_ota.c2130
-rw-r--r--arm-fm-22k/lib_src/eas_otadata.c58
-rw-r--r--arm-fm-22k/lib_src/eas_otadata.h138
-rw-r--r--arm-fm-22k/lib_src/eas_pan.c172
-rw-r--r--arm-fm-22k/lib_src/eas_pan.h108
-rw-r--r--arm-fm-22k/lib_src/eas_parser.h172
-rw-r--r--arm-fm-22k/lib_src/eas_pcm.c2940
-rw-r--r--arm-fm-22k/lib_src/eas_pcm.h694
-rw-r--r--arm-fm-22k/lib_src/eas_pcmdata.c46
-rw-r--r--arm-fm-22k/lib_src/eas_pcmdata.h290
-rw-r--r--arm-fm-22k/lib_src/eas_public.c5170
-rw-r--r--arm-fm-22k/lib_src/eas_reverb.c2284
-rw-r--r--arm-fm-22k/lib_src/eas_reverbdata.c44
-rw-r--r--arm-fm-22k/lib_src/eas_reverbdata.h948
-rw-r--r--arm-fm-22k/lib_src/eas_rtttl.c2370
-rw-r--r--arm-fm-22k/lib_src/eas_rtttldata.c58
-rw-r--r--arm-fm-22k/lib_src/eas_rtttldata.h116
-rw-r--r--arm-fm-22k/lib_src/eas_smf.c2382
-rw-r--r--arm-fm-22k/lib_src/eas_smf.h74
-rw-r--r--arm-fm-22k/lib_src/eas_smfdata.c108
-rw-r--r--arm-fm-22k/lib_src/eas_smfdata.h108
-rw-r--r--arm-fm-22k/lib_src/eas_sndlib.h788
-rw-r--r--arm-fm-22k/lib_src/eas_synth.h766
-rw-r--r--arm-fm-22k/lib_src/eas_synth_protos.h96
-rw-r--r--arm-fm-22k/lib_src/eas_synthcfg.h116
-rw-r--r--arm-fm-22k/lib_src/eas_vm_protos.h2148
-rw-r--r--arm-fm-22k/lib_src/eas_voicemgt.c7918
-rw-r--r--arm-fm-22k/lib_src/eas_wavefile.c1710
-rw-r--r--arm-fm-22k/lib_src/eas_wavefile.h102
-rw-r--r--arm-fm-22k/lib_src/eas_wavefiledata.c42
-rw-r--r--arm-hybrid-22k/host_src/eas.h2100
-rw-r--r--arm-hybrid-22k/host_src/eas_build.h48
-rw-r--r--arm-hybrid-22k/host_src/eas_chorus.h80
-rw-r--r--arm-hybrid-22k/host_src/eas_config.c1214
-rw-r--r--arm-hybrid-22k/host_src/eas_config.h358
-rw-r--r--arm-hybrid-22k/host_src/eas_debugmsgs.h88
-rw-r--r--arm-hybrid-22k/host_src/eas_host.h142
-rw-r--r--arm-hybrid-22k/host_src/eas_hostmm.c1296
-rw-r--r--arm-hybrid-22k/host_src/eas_main.c898
-rw-r--r--arm-hybrid-22k/host_src/eas_report.c504
-rw-r--r--arm-hybrid-22k/host_src/eas_report.h130
-rw-r--r--arm-hybrid-22k/host_src/eas_reverb.h84
-rw-r--r--arm-hybrid-22k/host_src/eas_types.h512
-rw-r--r--arm-hybrid-22k/host_src/eas_wave.c822
-rw-r--r--arm-hybrid-22k/host_src/eas_wave.h124
-rw-r--r--arm-hybrid-22k/lib_src/ARM_synth_constants_gnu.inc306
-rw-r--r--arm-hybrid-22k/lib_src/eas_audioconst.h170
-rw-r--r--arm-hybrid-22k/lib_src/eas_chorus.c1184
-rw-r--r--arm-hybrid-22k/lib_src/eas_chorusdata.c44
-rw-r--r--arm-hybrid-22k/lib_src/eas_chorusdata.h296
-rw-r--r--arm-hybrid-22k/lib_src/eas_ctype.h58
-rw-r--r--arm-hybrid-22k/lib_src/eas_data.c50
-rw-r--r--arm-hybrid-22k/lib_src/eas_data.h238
-rw-r--r--arm-hybrid-22k/lib_src/eas_effects.h98
-rw-r--r--arm-hybrid-22k/lib_src/eas_fmengine.c1546
-rw-r--r--arm-hybrid-22k/lib_src/eas_fmengine.h218
-rw-r--r--arm-hybrid-22k/lib_src/eas_fmsynth.c1796
-rw-r--r--arm-hybrid-22k/lib_src/eas_fmsynth.h138
-rw-r--r--arm-hybrid-22k/lib_src/eas_fmtables.c712
-rw-r--r--arm-hybrid-22k/lib_src/eas_ima_tables.c84
-rw-r--r--arm-hybrid-22k/lib_src/eas_imaadpcm.c712
-rw-r--r--arm-hybrid-22k/lib_src/eas_imelody.c3452
-rw-r--r--arm-hybrid-22k/lib_src/eas_imelodydata.c62
-rw-r--r--arm-hybrid-22k/lib_src/eas_imelodydata.h122
-rw-r--r--arm-hybrid-22k/lib_src/eas_math.c312
-rw-r--r--arm-hybrid-22k/lib_src/eas_math.h800
-rw-r--r--arm-hybrid-22k/lib_src/eas_midi.c1114
-rw-r--r--arm-hybrid-22k/lib_src/eas_midi.h118
-rw-r--r--arm-hybrid-22k/lib_src/eas_midictrl.h104
-rw-r--r--arm-hybrid-22k/lib_src/eas_mididata.c44
-rw-r--r--arm-hybrid-22k/lib_src/eas_miditypes.h252
-rw-r--r--arm-hybrid-22k/lib_src/eas_mixbuf.c48
-rw-r--r--arm-hybrid-22k/lib_src/eas_mixer.c904
-rw-r--r--arm-hybrid-22k/lib_src/eas_mixer.h250
-rw-r--r--arm-hybrid-22k/lib_src/eas_ota.c2130
-rw-r--r--arm-hybrid-22k/lib_src/eas_otadata.c58
-rw-r--r--arm-hybrid-22k/lib_src/eas_otadata.h138
-rw-r--r--arm-hybrid-22k/lib_src/eas_pan.c172
-rw-r--r--arm-hybrid-22k/lib_src/eas_pan.h108
-rw-r--r--arm-hybrid-22k/lib_src/eas_parser.h172
-rw-r--r--arm-hybrid-22k/lib_src/eas_pcm.c2940
-rw-r--r--arm-hybrid-22k/lib_src/eas_pcm.h694
-rw-r--r--arm-hybrid-22k/lib_src/eas_pcmdata.c46
-rw-r--r--arm-hybrid-22k/lib_src/eas_pcmdata.h290
-rw-r--r--arm-hybrid-22k/lib_src/eas_public.c5170
-rw-r--r--arm-hybrid-22k/lib_src/eas_reverb.c2284
-rw-r--r--arm-hybrid-22k/lib_src/eas_reverbdata.c44
-rw-r--r--arm-hybrid-22k/lib_src/eas_reverbdata.h948
-rw-r--r--arm-hybrid-22k/lib_src/eas_rtttl.c2370
-rw-r--r--arm-hybrid-22k/lib_src/eas_rtttldata.c58
-rw-r--r--arm-hybrid-22k/lib_src/eas_rtttldata.h116
-rw-r--r--arm-hybrid-22k/lib_src/eas_smf.c2382
-rw-r--r--arm-hybrid-22k/lib_src/eas_smf.h74
-rw-r--r--arm-hybrid-22k/lib_src/eas_smfdata.c108
-rw-r--r--arm-hybrid-22k/lib_src/eas_smfdata.h108
-rw-r--r--arm-hybrid-22k/lib_src/eas_sndlib.h788
-rw-r--r--arm-hybrid-22k/lib_src/eas_synth.h766
-rw-r--r--arm-hybrid-22k/lib_src/eas_synth_protos.h96
-rw-r--r--arm-hybrid-22k/lib_src/eas_synthcfg.h116
-rw-r--r--arm-hybrid-22k/lib_src/eas_vm_protos.h2148
-rw-r--r--arm-hybrid-22k/lib_src/eas_voicemgt.c7918
-rw-r--r--arm-hybrid-22k/lib_src/eas_wavefile.c1710
-rw-r--r--arm-hybrid-22k/lib_src/eas_wavefile.h102
-rw-r--r--arm-hybrid-22k/lib_src/eas_wavefiledata.c42
-rw-r--r--arm-hybrid-22k/lib_src/eas_wt_IPC_frame.h140
-rw-r--r--arm-hybrid-22k/lib_src/eas_wtengine.c1298
-rw-r--r--arm-hybrid-22k/lib_src/eas_wtengine.h318
-rw-r--r--arm-hybrid-22k/lib_src/eas_wtsynth.c2478
-rw-r--r--arm-hybrid-22k/lib_src/eas_wtsynth.h108
-rw-r--r--arm-hybrid-22k/lib_src/hybrid_22khz_mcu.c10274
-rw-r--r--arm-wt-22k/host_src/eas.h570
-rw-r--r--arm-wt-22k/host_src/eas_build.h48
-rw-r--r--arm-wt-22k/host_src/eas_chorus.h80
-rw-r--r--arm-wt-22k/host_src/eas_config.c1214
-rw-r--r--arm-wt-22k/host_src/eas_config.h358
-rw-r--r--arm-wt-22k/host_src/eas_host.h150
-rw-r--r--arm-wt-22k/host_src/eas_hostmm.c24
-rw-r--r--arm-wt-22k/host_src/eas_main.c674
-rw-r--r--arm-wt-22k/host_src/eas_report.c504
-rw-r--r--arm-wt-22k/host_src/eas_report.h130
-rw-r--r--arm-wt-22k/host_src/eas_reverb.h84
-rw-r--r--arm-wt-22k/host_src/eas_types.h522
-rw-r--r--arm-wt-22k/host_src/eas_wave.c822
-rw-r--r--arm-wt-22k/host_src/eas_wave.h124
-rw-r--r--arm-wt-22k/host_src/jet.h398
-rw-r--r--[-rwxr-xr-x]arm-wt-22k/jetcreator_lib_src/darwin-x86/EASLib.c3618
-rw-r--r--[-rwxr-xr-x]arm-wt-22k/jetcreator_lib_src/darwin-x86/EASLib.h62
-rw-r--r--[-rwxr-xr-x]arm-wt-22k/jetcreator_lib_src/darwin-x86/EASLibVst.c3008
-rw-r--r--[-rwxr-xr-x]arm-wt-22k/jetcreator_lib_src/darwin-x86/eas_host_debug.h94
-rw-r--r--[-rwxr-xr-x]arm-wt-22k/jetcreator_lib_src/darwin-x86/eastestv37.c1998
-rw-r--r--arm-wt-22k/jetcreator_lib_src/darwin-x86/wt_44khz.c29446
-rw-r--r--arm-wt-22k/lib_src/ARM_synth_constants_gnu.inc306
-rw-r--r--arm-wt-22k/lib_src/dls.h536
-rw-r--r--arm-wt-22k/lib_src/dls2.h244
-rw-r--r--arm-wt-22k/lib_src/eas_audioconst.h170
-rw-r--r--arm-wt-22k/lib_src/eas_chorus.c1184
-rw-r--r--arm-wt-22k/lib_src/eas_chorusdata.c44
-rw-r--r--arm-wt-22k/lib_src/eas_chorusdata.h296
-rw-r--r--arm-wt-22k/lib_src/eas_ctype.h58
-rw-r--r--arm-wt-22k/lib_src/eas_data.c50
-rw-r--r--arm-wt-22k/lib_src/eas_data.h242
-rw-r--r--arm-wt-22k/lib_src/eas_dlssynth.c754
-rw-r--r--arm-wt-22k/lib_src/eas_dlssynth.h58
-rw-r--r--arm-wt-22k/lib_src/eas_effects.h98
-rw-r--r--arm-wt-22k/lib_src/eas_flog.c168
-rw-r--r--arm-wt-22k/lib_src/eas_ima_tables.c84
-rw-r--r--arm-wt-22k/lib_src/eas_imaadpcm.c712
-rw-r--r--arm-wt-22k/lib_src/eas_imelody.c3465
-rw-r--r--arm-wt-22k/lib_src/eas_imelodydata.c62
-rw-r--r--arm-wt-22k/lib_src/eas_imelodydata.h123
-rw-r--r--arm-wt-22k/lib_src/eas_math.c312
-rw-r--r--arm-wt-22k/lib_src/eas_math.h800
-rw-r--r--arm-wt-22k/lib_src/eas_mdls.c3928
-rw-r--r--arm-wt-22k/lib_src/eas_mdls.h566
-rw-r--r--arm-wt-22k/lib_src/eas_midi.c1114
-rw-r--r--arm-wt-22k/lib_src/eas_midi.h118
-rw-r--r--arm-wt-22k/lib_src/eas_midictrl.h104
-rw-r--r--arm-wt-22k/lib_src/eas_mididata.c44
-rw-r--r--arm-wt-22k/lib_src/eas_miditypes.h252
-rw-r--r--arm-wt-22k/lib_src/eas_mixbuf.c48
-rw-r--r--arm-wt-22k/lib_src/eas_mixer.c904
-rw-r--r--arm-wt-22k/lib_src/eas_mixer.h250
-rw-r--r--arm-wt-22k/lib_src/eas_ota.c2130
-rw-r--r--arm-wt-22k/lib_src/eas_otadata.c58
-rw-r--r--arm-wt-22k/lib_src/eas_otadata.h138
-rw-r--r--arm-wt-22k/lib_src/eas_pan.c172
-rw-r--r--arm-wt-22k/lib_src/eas_pan.h108
-rw-r--r--arm-wt-22k/lib_src/eas_parser.h172
-rw-r--r--arm-wt-22k/lib_src/eas_pcm.c2940
-rw-r--r--arm-wt-22k/lib_src/eas_pcm.h694
-rw-r--r--arm-wt-22k/lib_src/eas_pcmdata.c46
-rw-r--r--arm-wt-22k/lib_src/eas_pcmdata.h290
-rw-r--r--arm-wt-22k/lib_src/eas_public.c3092
-rw-r--r--arm-wt-22k/lib_src/eas_reverb.c2284
-rw-r--r--arm-wt-22k/lib_src/eas_reverbdata.c44
-rw-r--r--arm-wt-22k/lib_src/eas_reverbdata.h948
-rw-r--r--arm-wt-22k/lib_src/eas_rtttl.c2370
-rw-r--r--arm-wt-22k/lib_src/eas_rtttldata.c58
-rw-r--r--arm-wt-22k/lib_src/eas_rtttldata.h116
-rw-r--r--arm-wt-22k/lib_src/eas_smf.c1636
-rw-r--r--arm-wt-22k/lib_src/eas_smf.h74
-rw-r--r--arm-wt-22k/lib_src/eas_smfdata.c108
-rw-r--r--arm-wt-22k/lib_src/eas_smfdata.h108
-rw-r--r--arm-wt-22k/lib_src/eas_sndlib.h788
-rw-r--r--arm-wt-22k/lib_src/eas_synth.h766
-rw-r--r--arm-wt-22k/lib_src/eas_synth_protos.h96
-rw-r--r--arm-wt-22k/lib_src/eas_synthcfg.h116
-rw-r--r--arm-wt-22k/lib_src/eas_tcdata.c62
-rw-r--r--arm-wt-22k/lib_src/eas_tcdata.h106
-rw-r--r--arm-wt-22k/lib_src/eas_tonecontrol.c1858
-rw-r--r--arm-wt-22k/lib_src/eas_vm_protos.h2148
-rw-r--r--arm-wt-22k/lib_src/eas_voicemgt.c7918
-rw-r--r--arm-wt-22k/lib_src/eas_wavefile.c1710
-rw-r--r--arm-wt-22k/lib_src/eas_wavefile.h102
-rw-r--r--arm-wt-22k/lib_src/eas_wavefiledata.c42
-rw-r--r--arm-wt-22k/lib_src/eas_wt_IPC_frame.h140
-rw-r--r--arm-wt-22k/lib_src/eas_wtengine.c898
-rw-r--r--arm-wt-22k/lib_src/eas_wtengine.h318
-rw-r--r--arm-wt-22k/lib_src/eas_wtsynth.c1428
-rw-r--r--arm-wt-22k/lib_src/eas_wtsynth.h108
-rw-r--r--arm-wt-22k/lib_src/eas_xmf.c1676
-rw-r--r--arm-wt-22k/lib_src/eas_xmf.h96
-rw-r--r--arm-wt-22k/lib_src/eas_xmfdata.c64
-rw-r--r--arm-wt-22k/lib_src/eas_xmfdata.h86
-rw-r--r--arm-wt-22k/lib_src/jet.c2258
-rw-r--r--arm-wt-22k/lib_src/jet_data.h342
-rw-r--r--arm-wt-22k/lib_src/wt_22khz.c29280
-rw-r--r--arm-wt-22k/misc/eas_host.c1550
252 files changed, 132829 insertions, 132823 deletions
diff --git a/arm-fm-22k/host_src/eas.h b/arm-fm-22k/host_src/eas.h
index 0bb04fe..c64af49 100644
--- a/arm-fm-22k/host_src/eas.h
+++ b/arm-fm-22k/host_src/eas.h
@@ -1,17 +1,17 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas.h
- *
- * Contents and purpose:
- * The public interface header for the EAS synthesizer.
- *
- * This header only contains declarations that are specific
- * to this implementation.
- *
- * DO NOT MODIFY THIS FILE!
- *
- * Copyright Sonic Network Inc. 2005, 2006
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas.h
+ *
+ * Contents and purpose:
+ * The public interface header for the EAS synthesizer.
+ *
+ * This header only contains declarations that are specific
+ * to this implementation.
+ *
+ * DO NOT MODIFY THIS FILE!
+ *
+ * Copyright Sonic Network Inc. 2005, 2006
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -24,1039 +24,1039 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 852 $
- * $Date: 2007-09-04 11:43:49 -0700 (Tue, 04 Sep 2007) $
- *----------------------------------------------------------------------------
-*/
-
-#ifndef _EAS_H
-#define _EAS_H
-
-#include "eas_types.h"
-
-/* for C++ linkage */
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* library version macro */
-#define MAKE_LIB_VERSION(a,b,c,d) (((((((EAS_U32) a <<8) | (EAS_U32) b) << 8) | (EAS_U32) c) << 8) | (EAS_U32) d)
-#define LIB_VERSION MAKE_LIB_VERSION(3, 6, 10, 14)
-
-typedef struct
-{
- EAS_U32 libVersion;
- EAS_BOOL checkedVersion;
- EAS_I32 maxVoices;
- EAS_I32 numChannels;
- EAS_I32 sampleRate;
- EAS_I32 mixBufferSize;
- EAS_BOOL filterEnabled;
- EAS_U32 buildTimeStamp;
- EAS_CHAR *buildGUID;
-} S_EAS_LIB_CONFIG;
-
-/* enumerated effects module numbers for configuration */
-typedef enum
-{
- EAS_MODULE_ENHANCER = 0,
- EAS_MODULE_COMPRESSOR,
- EAS_MODULE_REVERB,
- EAS_MODULE_CHORUS,
- EAS_MODULE_WIDENER,
- EAS_MODULE_GRAPHIC_EQ,
- EAS_MODULE_WOW,
- EAS_MODULE_MAXIMIZER,
- EAS_MODULE_TONECONTROLEQ,
- NUM_EFFECTS_MODULES
-} E_FX_MODULES;
-
-/* enumerated optional module numbers for configuration */
-typedef enum
-{
- EAS_MODULE_MMAPI_TONE_CONTROL = 0,
- EAS_MODULE_METRICS
-} E_OPT_MODULES;
-#define NUM_OPTIONAL_MODULES 2
-
-/* enumerated audio decoders for configuration */
-typedef enum
-{
- EAS_DECODER_PCM = 0,
- EAS_DECODER_SMAF_ADPCM,
- EAS_DECODER_IMA_ADPCM,
- EAS_DECODER_7BIT_SMAF_ADPCM,
- EAS_DECODER_NOT_SUPPORTED
-} E_DECODER_MODULES;
-#define NUM_DECODER_MODULES 4
-
-/* defines for EAS_PEOpenStream flags parameter */
-#define PCM_FLAGS_STEREO 0x00000100 /* stream is stereo */
-#define PCM_FLAGS_8_BIT 0x00000001 /* 8-bit format */
-#define PCM_FLAGS_UNSIGNED 0x00000010 /* unsigned format */
-#define PCM_FLAGS_STREAMING 0x80000000 /* streaming mode */
-
-/* maximum volume setting */
-#define EAS_MAX_VOLUME 100
-
-/*----------------------------------------------------------------------------
- * EAS_Init()
- *----------------------------------------------------------------------------
- * Purpose:
- * Initialize the synthesizer library
- *
- * Inputs:
- * polyphony - number of voices to play (dynamic memory model only)
- * ppLibData - pointer to data handle variable for this instance
- *
- * Outputs:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_Init (EAS_DATA_HANDLE *ppEASData);
-
-/*----------------------------------------------------------------------------
- * EAS_Config()
- *----------------------------------------------------------------------------
- * Purpose:
- * Returns a pointer to a structure containing the configuration options
- * in this library build.
- *
- * Inputs:
- *
- * Outputs:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC const S_EAS_LIB_CONFIG *EAS_Config (void);
-
-/*----------------------------------------------------------------------------
- * EAS_Shutdown()
- *----------------------------------------------------------------------------
- * Purpose:
- * Shuts down the library. Deallocates any memory associated with the
- * synthesizer (dynamic memory model only)
- *
- * Inputs:
- * pEASData - handle to data for this instance
- *
- * Outputs:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_Shutdown (EAS_DATA_HANDLE pEASData);
-
-/*----------------------------------------------------------------------------
- * EAS_Render()
- *----------------------------------------------------------------------------
- * Purpose:
- * Parse the Midi data and render PCM audio data.
- *
- * Inputs:
- * pEASData - buffer for internal EAS data
- * pOut - output buffer pointer
- * nNumRequested - requested num samples to generate
- * pnNumGenerated - actual number of samples generated
- *
- * Outputs:
- * EAS_SUCCESS if PCM data was successfully rendered
- *
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_Render (EAS_DATA_HANDLE pEASData, EAS_PCM *pOut, EAS_I32 numRequested, EAS_I32 *pNumGenerated);
-
-/*----------------------------------------------------------------------------
- * EAS_SetRepeat()
- *----------------------------------------------------------------------------
- * Purpose:
- * Set the selected stream to repeat.
- *
- * Inputs:
- * pEASData - handle to data for this instance
- * streamHandle - handle to stream
- * repeatCount - repeat count (0 = no repeat, -1 = repeat forever)
- *
- * Outputs:
- *
- * Side Effects:
- *
- * Notes:
- * 0 = no repeat
- * 1 = repeat once, i.e. play through twice
- * -1 = repeat forever
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_SetRepeat (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle, EAS_I32 repeatCount);
-
-/*----------------------------------------------------------------------------
- * EAS_GetRepeat()
- *----------------------------------------------------------------------------
- * Purpose:
- * Gets the current repeat count for the selected stream.
- *
- * Inputs:
- * pEASData - handle to data for this instance
- * streamHandle - handle to stream
- * pRrepeatCount - pointer to variable to hold repeat count
- *
- * Outputs:
- *
- * Side Effects:
- *
- * Notes:
- * 0 = no repeat
- * 1 = repeat once, i.e. play through twice
- * -1 = repeat forever
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_GetRepeat (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle, EAS_I32 *pRepeatCount);
-
-/*----------------------------------------------------------------------------
- * EAS_SetPlaybackRate()
- *----------------------------------------------------------------------------
- * Purpose:
- * Set the playback rate.
- *
- * Inputs:
- * pEASData - handle to data for this instance
- * streamHandle - handle to stream
- * rate - rate (28-bit fractional amount)
- *
- * Outputs:
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_SetPlaybackRate (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle, EAS_U32 rate);
-#define MAX_PLAYBACK_RATE (EAS_U32)(1L << 29)
-#define MIN_PLAYBACK_RATE (EAS_U32)(1L << 27)
-
-/*----------------------------------------------------------------------------
- * EAS_SetTransposition)
- *----------------------------------------------------------------------------
- * Purpose:
- * Sets the key tranposition for the synthesizer. Transposes all
- * melodic instruments by the specified amount. Range is limited
- * to +/-12 semitones.
- *
- * Inputs:
- * pEASData - handle to data for this instance
- * streamHandle - handle to stream
- * transposition - +/-12 semitones
- *
- * Outputs:
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_SetTransposition (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle, EAS_I32 transposition);
-#define MAX_TRANSPOSE 12
-
-/*----------------------------------------------------------------------------
- * EAS_SetSynthPolyphony()
- *----------------------------------------------------------------------------
- * Purpose:
- * Set the polyphony of the synthesizer. Value must be >= 1 and <= the
- * maximum number of voices. This function will pin the polyphony
- * at those limits
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * synthNum - synthesizer number (0 = onboard, 1 = DSP)
- * polyphonyCount - the desired polyphony count
- *
- * Outputs:
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_SetSynthPolyphony (EAS_DATA_HANDLE pEASData, EAS_I32 synthNum, EAS_I32 polyphonyCount);
-
-/*----------------------------------------------------------------------------
- * EAS_GetSynthPolyphony()
- *----------------------------------------------------------------------------
- * Purpose:
- * Returns the current polyphony setting of the synthesizer
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * synthNum - synthesizer number (0 = onboard, 1 = DSP)
- * pPolyphonyCount - pointer to variable to receive polyphony count
- *
- * Outputs:
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_GetSynthPolyphony (EAS_DATA_HANDLE pEASData, EAS_I32 synthNum, EAS_I32 *pPolyphonyCount);
-
-/*----------------------------------------------------------------------------
- * EAS_SetPolyphony()
- *----------------------------------------------------------------------------
- * Purpose:
- * Set the polyphony of the stream. Value must be >= 1 and <= the
- * maximum number of voices. This function will pin the polyphony
- * at those limits
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * streamHandle - handle returned by EAS_OpenFile
- * polyphonyCount - the desired polyphony count
- *
- * Outputs:
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_SetPolyphony (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle, EAS_I32 polyphonyCount);
-
-/*----------------------------------------------------------------------------
- * EAS_GetPolyphony()
- *----------------------------------------------------------------------------
- * Purpose:
- * Returns the current polyphony setting of the stream
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * streamHandle - handle returned by EAS_OpenFile
- * pPolyphonyCount - pointer to variable to receive polyphony count
- *
- * Outputs:
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_GetPolyphony (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle, EAS_I32 *pPolyphonyCount);
-
-/*----------------------------------------------------------------------------
- * EAS_SetPriority()
- *----------------------------------------------------------------------------
- * Purpose:
- * Set the priority of the stream. Determines which stream's voices
- * are stolen when there are insufficient voices for all notes.
- * Value must be in the range of 1-255, lower values are higher
- * priority. The default priority is 50.
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * streamHandle - handle returned by EAS_OpenFile
- * polyphonyCount - the desired polyphony count
- *
- * Outputs:
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_SetPriority (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle, EAS_I32 priority);
-
-/*----------------------------------------------------------------------------
- * EAS_GetPriority()
- *----------------------------------------------------------------------------
- * Purpose:
- * Returns the current priority setting of the stream
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * streamHandle - handle returned by EAS_OpenFile
- * pPriority - pointer to variable to receive priority
- *
- * Outputs:
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_GetPriority (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle, EAS_I32 *pPriority);
-
-/*----------------------------------------------------------------------------
- * EAS_SetVolume()
- *----------------------------------------------------------------------------
- * Purpose:
- * Set the master volume for the mixer. The default volume setting is
- * 90 (-10 dB). The volume range is 0 to 100 in 1dB increments.
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * volume - the desired master volume
- *
- * Outputs:
- *
- *
- * Side Effects:
- * overrides any previously set master volume from sysex
- *
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_SetVolume (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle, EAS_I32 volume);
-
-/*----------------------------------------------------------------------------
- * EAS_GetVolume()
- *----------------------------------------------------------------------------
- * Purpose:
- * Returns the master volume for the mixer in 1dB increments.
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * volume - the desired master volume
- *
- * Outputs:
- *
- *
- * Side Effects:
- * overrides any previously set master volume from sysex
- *
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_I32 EAS_GetVolume (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle);
-
-/*----------------------------------------------------------------------------
- * EAS_SetMaxLoad()
- *----------------------------------------------------------------------------
- * Purpose:
- * Sets the maximum workload the parsers will do in a single call to
- * EAS_Render. The units are currently arbitrary, but should correlate
- * well to the actual CPU cycles consumed. The primary effect is to
- * reduce the occasional peaks in CPU cycles consumed when parsing
- * dense parts of a MIDI score. Setting maxWorkLoad to zero disables
- * the workload limiting function.
- *
- * Inputs:
- * pEASData - handle to data for this instance
- * maxLoad - the desired maximum workload
- *
- * Outputs:
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_SetMaxLoad (EAS_DATA_HANDLE pEASData, EAS_I32 maxLoad);
-
-/*----------------------------------------------------------------------------
- * EAS_SetMaxPCMStreams()
- *----------------------------------------------------------------------------
- * Sets the maximum number of PCM streams allowed in parsers that
- * use PCM streaming.
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * streamHandle - handle returned by EAS_OpenFile
- * maxNumStreams - maximum number of PCM streams
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_SetMaxPCMStreams (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_I32 maxNumStreams);
-
-/*----------------------------------------------------------------------------
- * EAS_OpenFile()
- *----------------------------------------------------------------------------
- * Purpose:
- * Opens a file for audio playback.
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * locator - pointer to filename or other locating information
- * pStreamHandle - pointer to stream handle variable
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_OpenFile (EAS_DATA_HANDLE pEASData, EAS_FILE_LOCATOR locator, EAS_HANDLE *pStreamHandle);
-
-#ifdef MMAPI_SUPPORT
-/*----------------------------------------------------------------------------
- * EAS_MMAPIToneControl()
- *----------------------------------------------------------------------------
- * Purpose:
- * Opens a ToneControl file for audio playback.
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * locator - pointer to filename or other locating information
- * pStreamHandle - pointer to stream handle variable
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_MMAPIToneControl (EAS_DATA_HANDLE pEASData, EAS_FILE_LOCATOR locator, EAS_HANDLE *pStreamHandle);
-
-/*----------------------------------------------------------------------------
- * EAS_GetWaveFmtChunk
- *----------------------------------------------------------------------------
- * Helper function to retrieve WAVE file fmt chunk for MMAPI
- *----------------------------------------------------------------------------
- * pEASData - pointer to EAS persistent data object
- * streamHandle - stream handle
- * pFmtChunk - pointer to pointer to FMT chunk data
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_GetWaveFmtChunk (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle, EAS_VOID_PTR *ppFmtChunk);
-#endif
-
-/*----------------------------------------------------------------------------
- * EAS_GetFileType
- *----------------------------------------------------------------------------
- * Returns the file type (see eas_types.h for enumerations)
- *----------------------------------------------------------------------------
- * pEASData - pointer to EAS persistent data object
- * streamHandle - stream handle
- * pFileType - pointer to variable to receive file type
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_GetFileType (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle, EAS_I32 *pFileType);
-
-/*----------------------------------------------------------------------------
- * EAS_ParseMetaData()
- *----------------------------------------------------------------------------
- * Purpose:
- *
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * streamHandle - file or stream handle
- * playLength - pointer to variable to store the play length (in msecs)
- *
- * Outputs:
- *
- *
- * Side Effects:
- * - resets the parser to the start of the file
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_ParseMetaData (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle, EAS_I32 *pPlayLength);
-
-/*----------------------------------------------------------------------------
- * EAS_Prepare()
- *----------------------------------------------------------------------------
- * Purpose:
- * Prepares the synthesizer to play the file or stream. Parses the first
- * frame of data from the file and arms the synthesizer.
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * streamHandle - file or stream handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_Prepare (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle);
-
-/*----------------------------------------------------------------------------
- * EAS_State()
- *----------------------------------------------------------------------------
- * Purpose:
- * Returns the state of an audio file or stream.
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * streamHandle - file or stream handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_State (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle, EAS_STATE *pState);
-
-/*----------------------------------------------------------------------------
- * EAS_RegisterMetaDataCallback()
- *----------------------------------------------------------------------------
- * Purpose:
- * Registers a metadata callback function for parsed metadata. To
- * de-register the callback, call this function again with parameter
- * cbFunc set to NULL.
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * streamHandle - file or stream handle
- * cbFunc - pointer to host callback function
- * metaDataBuffer - pointer to metadata buffer
- * metaDataBufSize - maximum size of the metadata buffer
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_RegisterMetaDataCallback (
- EAS_DATA_HANDLE pEASData,
- EAS_HANDLE streamHandle,
- EAS_METADATA_CBFUNC cbFunc,
- char *metaDataBuffer,
- EAS_I32 metaDataBufSize,
- EAS_VOID_PTR pUserData);
-
-/*----------------------------------------------------------------------------
- * EAS_GetNoteCount ()
- *----------------------------------------------------------------------------
- * Returns the total number of notes played in this stream
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * streamHandle - file or stream handle
- * pNoteCount - pointer to variable to receive note count
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_GetNoteCount (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_I32 *pNoteCount);
-
-/*----------------------------------------------------------------------------
- * EAS_CloseFile()
- *----------------------------------------------------------------------------
- * Purpose:
- * Closes an audio file or stream. Playback should have either paused or
- * completed (EAS_State returns EAS_PAUSED or EAS_STOPPED).
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * streamHandle - file or stream handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_CloseFile (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle);
-
-/*----------------------------------------------------------------------------
- * EAS_OpenMIDIStream()
- *----------------------------------------------------------------------------
- * Purpose:
- * Opens a raw MIDI stream allowing the host to route MIDI cable data directly to the synthesizer
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * pStreamHandle - pointer to variable to hold file or stream handle
- * streamHandle - open stream or NULL for new synthesizer instance
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_OpenMIDIStream (EAS_DATA_HANDLE pEASData, EAS_HANDLE *pStreamHandle, EAS_HANDLE streamHandle);
-
-/*----------------------------------------------------------------------------
- * EAS_WriteMIDIStream()
- *----------------------------------------------------------------------------
- * Purpose:
- * Send data to the MIDI stream device
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * streamHandle - stream handle
- * pBuffer - pointer to buffer
- * count - number of bytes to write
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_WriteMIDIStream(EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle, EAS_U8 *pBuffer, EAS_I32 count);
-
-/*----------------------------------------------------------------------------
- * EAS_CloseMIDIStream()
- *----------------------------------------------------------------------------
- * Purpose:
- * Closes a raw MIDI stream
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * streamHandle - stream handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_CloseMIDIStream (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle);
-
-/*----------------------------------------------------------------------------
- * EAS_Locate()
- *----------------------------------------------------------------------------
- * Purpose:
- * Locate into the file associated with the handle.
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * streamHandle - file handle
- * milliseconds - playback offset from start of file in milliseconds
- *
- * Outputs:
- *
- *
- * Side Effects:
- * the actual offset will be quantized to the closest update period, typically
- * a resolution of 5.9ms. Notes that are started prior to this time will not
- * sound. Any notes currently playing will be shut off.
- *
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_Locate (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle, EAS_I32 milliseconds, EAS_BOOL offset);
-
-/*----------------------------------------------------------------------------
- * EAS_GetRenderTime()
- *----------------------------------------------------------------------------
- * Purpose:
- * Returns the current playback offset
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- *
- * Outputs:
- * Gets the render time clock in msecs.
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_GetRenderTime (EAS_DATA_HANDLE pEASData, EAS_I32 *pTime);
-
-/*----------------------------------------------------------------------------
- * EAS_GetLocation()
- *----------------------------------------------------------------------------
- * Purpose:
- * Returns the current playback offset
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * streamHandle - file handle
- *
- * Outputs:
- * The offset in milliseconds from the start of the current sequence, quantized
- * to the nearest update period. Actual resolution is typically 5.9 ms.
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_GetLocation (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle, EAS_I32 *pTime);
-
-/*----------------------------------------------------------------------------
- * EAS_Pause()
- *----------------------------------------------------------------------------
- * Purpose:
- * Pauses the playback of the data associated with this handle. The audio
- * is gracefully ramped down to prevent clicks and pops. It may take several
- * buffers of audio before the audio is muted.
- *
- * Inputs:
- * psEASData - pointer to overall EAS data structure
- * streamHandle - file or stream handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_Pause (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle);
-
-/*----------------------------------------------------------------------------
- * EAS_Resume()
- *----------------------------------------------------------------------------
- * Purpose:
- * Resumes the playback of the data associated with this handle. The audio
- * is gracefully ramped up to prevent clicks and pops.
- *
- * Inputs:
- * psEASData - pointer to overall EAS data structure
- * streamHandle - file or stream handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_Resume (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle);
-
-/*----------------------------------------------------------------------------
- * EAS_GetParameter()
- *----------------------------------------------------------------------------
- * Purpose:
- * Set the parameter of a module. See E_MODULES for a list of modules
- * and the header files of the modules for a list of parameters.
- *
- * Inputs:
- * psEASData - pointer to overall EAS data structure
- * module - enumerated module number
- * param - enumerated parameter number
- * pValue - pointer to variable to receive parameter value
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_GetParameter (EAS_DATA_HANDLE pEASData, EAS_I32 module, EAS_I32 param, EAS_I32 *pValue);
-
-/*----------------------------------------------------------------------------
- * EAS_SetParameter()
- *----------------------------------------------------------------------------
- * Purpose:
- * Set the parameter of a module. See E_MODULES for a list of modules
- * and the header files of the modules for a list of parameters.
- *
- * Inputs:
- * psEASData - pointer to overall EAS data structure
- * handle - file or stream handle
- * module - enumerated module number
- * param - enumerated parameter number
- * value - new parameter value
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_SetParameter (EAS_DATA_HANDLE pEASData, EAS_I32 module, EAS_I32 param, EAS_I32 value);
-
-#ifdef _METRICS_ENABLED
-/*----------------------------------------------------------------------------
- * EAS_MetricsReport()
- *----------------------------------------------------------------------------
- * Purpose:
- * Displays the current metrics through the EAS_Report interface.
- *
- * Inputs:
- * pEASData - instance data handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_MetricsReport (EAS_DATA_HANDLE pEASData);
-
-/*----------------------------------------------------------------------------
- * EAS_MetricsReset()
- *----------------------------------------------------------------------------
- * Purpose:
- * Displays the current metrics through the EAS_Report interface.
- *
- * Inputs:
- * pEASData - instance data handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_MetricsReset (EAS_DATA_HANDLE pEASData);
-#endif
-
-/*----------------------------------------------------------------------------
- * EAS_SetSoundLibrary()
- *----------------------------------------------------------------------------
- * Purpose:
- * Sets the location of the sound library.
- *
- * Inputs:
- * pEASData - instance data handle
- * streamHandle - file or stream handle
- * pSoundLib - pointer to sound library
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_SetSoundLibrary (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle, EAS_SNDLIB_HANDLE pSndLib);
-
-/*----------------------------------------------------------------------------
- * EAS_SetHeaderSearchFlag()
- *----------------------------------------------------------------------------
- * By default, when EAS_OpenFile is called, the parsers check the
- * first few bytes of the file looking for a specific header. Some
- * mobile devices may add a header to the start of a file, which
- * will prevent the parser from recognizing the file. If the
- * searchFlag is set to EAS_TRUE, the parser will search the entire
- * file looking for the header. This may enable EAS to recognize
- * some files that it would ordinarily reject. The negative is that
- * it make take slightly longer to process the EAS_OpenFile request.
- *
- * Inputs:
- * pEASData - instance data handle
- * searchFlag - search flag (EAS_TRUE or EAS_FALSE)
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_SetHeaderSearchFlag (EAS_DATA_HANDLE pEASData, EAS_BOOL searchFlag);
-
-/*----------------------------------------------------------------------------
- * EAS_SetPlayMode()
- *----------------------------------------------------------------------------
- * Some file formats support special play modes, such as iMode partial
- * play mode. This call can be used to change the play mode. The
- * default play mode (usually straight playback) is always zero.
- *
- * Inputs:
- * pEASData - instance data handle
- * handle - file or stream handle
- * playMode - play mode (see eas_types.h for enumerations)
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_SetPlayMode (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_I32 playMode);
-
-#ifdef DLS_SYNTHESIZER
-/*----------------------------------------------------------------------------
- * EAS_LoadDLSCollection()
- *----------------------------------------------------------------------------
- * Purpose:
- * Downloads a DLS collection
- *
- * Inputs:
- * pEASData - instance data handle
- * streamHandle - file or stream handle
- * locator - file locator
- *
- * Outputs:
- *
- *
- * Side Effects:
- * May overlay instruments in the GM sound set
- *
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_LoadDLSCollection (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle, EAS_FILE_LOCATOR locator);
-#endif
-
-/*----------------------------------------------------------------------------
- * EAS_SetFrameBuffer()
- *----------------------------------------------------------------------------
- * Purpose:
- * Sets the frame buffer pointer passed to the IPC communications functions
- *
- * Inputs:
- * pEASData - instance data handle
- * locator - file locator
- *
- * Outputs:
- *
- *
- * Side Effects:
- * May overlay instruments in the GM sound set
- *
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_SetFrameBuffer (EAS_DATA_HANDLE pEASData, EAS_FRAME_BUFFER_HANDLE pFrameBuffer);
-
-#ifdef EXTERNAL_AUDIO
-/*----------------------------------------------------------------------------
- * EAS_RegExtAudioCallback()
- *----------------------------------------------------------------------------
- * Purpose:
- * Registers callback functions for audio events.
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * streamHandle - file or stream handle
- * cbProgChgFunc - pointer to host callback function for program change
- * cbEventFunc - pointer to host callback functio for note events
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_RegExtAudioCallback (EAS_DATA_HANDLE pEASData,
- EAS_HANDLE streamHandle,
- EAS_VOID_PTR pInstData,
- EAS_EXT_PRG_CHG_FUNC cbProgChgFunc,
- EAS_EXT_EVENT_FUNC cbEventFunc);
-
-/*----------------------------------------------------------------------------
- * EAS_GetMIDIControllers()
- *----------------------------------------------------------------------------
- * Purpose:
- * Returns the current state of MIDI controllers on the requested channel.
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * streamHandle - file or stream handle
- * pControl - pointer to structure to receive data
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_GetMIDIControllers (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle, EAS_U8 channel, S_MIDI_CONTROLLERS *pControl);
-#endif
-
-/*----------------------------------------------------------------------------
- * EAS_SearchFile
- *----------------------------------------------------------------------------
- * Search file for specific sequence starting at current file
- * position. Returns offset to start of sequence.
- *
- * Inputs:
- * pEASData - pointer to EAS persistent data object
- * fileHandle - file handle
- * searchString - pointer to search sequence
- * len - length of search sequence
- * pOffset - pointer to variable to store offset to sequence
- *
- * Returns EAS_EOF if end-of-file is reached
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT EAS_SearchFile (EAS_DATA_HANDLE pEASData, EAS_FILE_HANDLE fileHandle, const EAS_U8 *searchString, EAS_I32 len, EAS_I32 *pOffset);
-
-#ifdef __cplusplus
-} /* end extern "C" */
-#endif
-
-#endif /* #ifndef _EAS_H */
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 852 $
+ * $Date: 2007-09-04 11:43:49 -0700 (Tue, 04 Sep 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+#ifndef _EAS_H
+#define _EAS_H
+
+#include "eas_types.h"
+
+/* for C++ linkage */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* library version macro */
+#define MAKE_LIB_VERSION(a,b,c,d) (((((((EAS_U32) a <<8) | (EAS_U32) b) << 8) | (EAS_U32) c) << 8) | (EAS_U32) d)
+#define LIB_VERSION MAKE_LIB_VERSION(3, 6, 10, 14)
+
+typedef struct
+{
+ EAS_U32 libVersion;
+ EAS_BOOL checkedVersion;
+ EAS_I32 maxVoices;
+ EAS_I32 numChannels;
+ EAS_I32 sampleRate;
+ EAS_I32 mixBufferSize;
+ EAS_BOOL filterEnabled;
+ EAS_U32 buildTimeStamp;
+ EAS_CHAR *buildGUID;
+} S_EAS_LIB_CONFIG;
+
+/* enumerated effects module numbers for configuration */
+typedef enum
+{
+ EAS_MODULE_ENHANCER = 0,
+ EAS_MODULE_COMPRESSOR,
+ EAS_MODULE_REVERB,
+ EAS_MODULE_CHORUS,
+ EAS_MODULE_WIDENER,
+ EAS_MODULE_GRAPHIC_EQ,
+ EAS_MODULE_WOW,
+ EAS_MODULE_MAXIMIZER,
+ EAS_MODULE_TONECONTROLEQ,
+ NUM_EFFECTS_MODULES
+} E_FX_MODULES;
+
+/* enumerated optional module numbers for configuration */
+typedef enum
+{
+ EAS_MODULE_MMAPI_TONE_CONTROL = 0,
+ EAS_MODULE_METRICS
+} E_OPT_MODULES;
+#define NUM_OPTIONAL_MODULES 2
+
+/* enumerated audio decoders for configuration */
+typedef enum
+{
+ EAS_DECODER_PCM = 0,
+ EAS_DECODER_SMAF_ADPCM,
+ EAS_DECODER_IMA_ADPCM,
+ EAS_DECODER_7BIT_SMAF_ADPCM,
+ EAS_DECODER_NOT_SUPPORTED
+} E_DECODER_MODULES;
+#define NUM_DECODER_MODULES 4
+
+/* defines for EAS_PEOpenStream flags parameter */
+#define PCM_FLAGS_STEREO 0x00000100 /* stream is stereo */
+#define PCM_FLAGS_8_BIT 0x00000001 /* 8-bit format */
+#define PCM_FLAGS_UNSIGNED 0x00000010 /* unsigned format */
+#define PCM_FLAGS_STREAMING 0x80000000 /* streaming mode */
+
+/* maximum volume setting */
+#define EAS_MAX_VOLUME 100
+
+/*----------------------------------------------------------------------------
+ * EAS_Init()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Initialize the synthesizer library
+ *
+ * Inputs:
+ * polyphony - number of voices to play (dynamic memory model only)
+ * ppLibData - pointer to data handle variable for this instance
+ *
+ * Outputs:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_Init (EAS_DATA_HANDLE *ppEASData);
+
+/*----------------------------------------------------------------------------
+ * EAS_Config()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Returns a pointer to a structure containing the configuration options
+ * in this library build.
+ *
+ * Inputs:
+ *
+ * Outputs:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC const S_EAS_LIB_CONFIG *EAS_Config (void);
+
+/*----------------------------------------------------------------------------
+ * EAS_Shutdown()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Shuts down the library. Deallocates any memory associated with the
+ * synthesizer (dynamic memory model only)
+ *
+ * Inputs:
+ * pEASData - handle to data for this instance
+ *
+ * Outputs:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_Shutdown (EAS_DATA_HANDLE pEASData);
+
+/*----------------------------------------------------------------------------
+ * EAS_Render()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Parse the Midi data and render PCM audio data.
+ *
+ * Inputs:
+ * pEASData - buffer for internal EAS data
+ * pOut - output buffer pointer
+ * nNumRequested - requested num samples to generate
+ * pnNumGenerated - actual number of samples generated
+ *
+ * Outputs:
+ * EAS_SUCCESS if PCM data was successfully rendered
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_Render (EAS_DATA_HANDLE pEASData, EAS_PCM *pOut, EAS_I32 numRequested, EAS_I32 *pNumGenerated);
+
+/*----------------------------------------------------------------------------
+ * EAS_SetRepeat()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Set the selected stream to repeat.
+ *
+ * Inputs:
+ * pEASData - handle to data for this instance
+ * streamHandle - handle to stream
+ * repeatCount - repeat count (0 = no repeat, -1 = repeat forever)
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ *
+ * Notes:
+ * 0 = no repeat
+ * 1 = repeat once, i.e. play through twice
+ * -1 = repeat forever
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_SetRepeat (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle, EAS_I32 repeatCount);
+
+/*----------------------------------------------------------------------------
+ * EAS_GetRepeat()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Gets the current repeat count for the selected stream.
+ *
+ * Inputs:
+ * pEASData - handle to data for this instance
+ * streamHandle - handle to stream
+ * pRrepeatCount - pointer to variable to hold repeat count
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ *
+ * Notes:
+ * 0 = no repeat
+ * 1 = repeat once, i.e. play through twice
+ * -1 = repeat forever
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_GetRepeat (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle, EAS_I32 *pRepeatCount);
+
+/*----------------------------------------------------------------------------
+ * EAS_SetPlaybackRate()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Set the playback rate.
+ *
+ * Inputs:
+ * pEASData - handle to data for this instance
+ * streamHandle - handle to stream
+ * rate - rate (28-bit fractional amount)
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_SetPlaybackRate (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle, EAS_U32 rate);
+#define MAX_PLAYBACK_RATE (EAS_U32)(1L << 29)
+#define MIN_PLAYBACK_RATE (EAS_U32)(1L << 27)
+
+/*----------------------------------------------------------------------------
+ * EAS_SetTransposition)
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Sets the key tranposition for the synthesizer. Transposes all
+ * melodic instruments by the specified amount. Range is limited
+ * to +/-12 semitones.
+ *
+ * Inputs:
+ * pEASData - handle to data for this instance
+ * streamHandle - handle to stream
+ * transposition - +/-12 semitones
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_SetTransposition (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle, EAS_I32 transposition);
+#define MAX_TRANSPOSE 12
+
+/*----------------------------------------------------------------------------
+ * EAS_SetSynthPolyphony()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Set the polyphony of the synthesizer. Value must be >= 1 and <= the
+ * maximum number of voices. This function will pin the polyphony
+ * at those limits
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * synthNum - synthesizer number (0 = onboard, 1 = DSP)
+ * polyphonyCount - the desired polyphony count
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_SetSynthPolyphony (EAS_DATA_HANDLE pEASData, EAS_I32 synthNum, EAS_I32 polyphonyCount);
+
+/*----------------------------------------------------------------------------
+ * EAS_GetSynthPolyphony()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Returns the current polyphony setting of the synthesizer
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * synthNum - synthesizer number (0 = onboard, 1 = DSP)
+ * pPolyphonyCount - pointer to variable to receive polyphony count
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_GetSynthPolyphony (EAS_DATA_HANDLE pEASData, EAS_I32 synthNum, EAS_I32 *pPolyphonyCount);
+
+/*----------------------------------------------------------------------------
+ * EAS_SetPolyphony()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Set the polyphony of the stream. Value must be >= 1 and <= the
+ * maximum number of voices. This function will pin the polyphony
+ * at those limits
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * streamHandle - handle returned by EAS_OpenFile
+ * polyphonyCount - the desired polyphony count
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_SetPolyphony (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle, EAS_I32 polyphonyCount);
+
+/*----------------------------------------------------------------------------
+ * EAS_GetPolyphony()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Returns the current polyphony setting of the stream
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * streamHandle - handle returned by EAS_OpenFile
+ * pPolyphonyCount - pointer to variable to receive polyphony count
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_GetPolyphony (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle, EAS_I32 *pPolyphonyCount);
+
+/*----------------------------------------------------------------------------
+ * EAS_SetPriority()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Set the priority of the stream. Determines which stream's voices
+ * are stolen when there are insufficient voices for all notes.
+ * Value must be in the range of 1-255, lower values are higher
+ * priority. The default priority is 50.
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * streamHandle - handle returned by EAS_OpenFile
+ * polyphonyCount - the desired polyphony count
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_SetPriority (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle, EAS_I32 priority);
+
+/*----------------------------------------------------------------------------
+ * EAS_GetPriority()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Returns the current priority setting of the stream
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * streamHandle - handle returned by EAS_OpenFile
+ * pPriority - pointer to variable to receive priority
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_GetPriority (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle, EAS_I32 *pPriority);
+
+/*----------------------------------------------------------------------------
+ * EAS_SetVolume()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Set the master volume for the mixer. The default volume setting is
+ * 90 (-10 dB). The volume range is 0 to 100 in 1dB increments.
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * volume - the desired master volume
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ * overrides any previously set master volume from sysex
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_SetVolume (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle, EAS_I32 volume);
+
+/*----------------------------------------------------------------------------
+ * EAS_GetVolume()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Returns the master volume for the mixer in 1dB increments.
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * volume - the desired master volume
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ * overrides any previously set master volume from sysex
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_I32 EAS_GetVolume (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle);
+
+/*----------------------------------------------------------------------------
+ * EAS_SetMaxLoad()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Sets the maximum workload the parsers will do in a single call to
+ * EAS_Render. The units are currently arbitrary, but should correlate
+ * well to the actual CPU cycles consumed. The primary effect is to
+ * reduce the occasional peaks in CPU cycles consumed when parsing
+ * dense parts of a MIDI score. Setting maxWorkLoad to zero disables
+ * the workload limiting function.
+ *
+ * Inputs:
+ * pEASData - handle to data for this instance
+ * maxLoad - the desired maximum workload
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_SetMaxLoad (EAS_DATA_HANDLE pEASData, EAS_I32 maxLoad);
+
+/*----------------------------------------------------------------------------
+ * EAS_SetMaxPCMStreams()
+ *----------------------------------------------------------------------------
+ * Sets the maximum number of PCM streams allowed in parsers that
+ * use PCM streaming.
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * streamHandle - handle returned by EAS_OpenFile
+ * maxNumStreams - maximum number of PCM streams
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_SetMaxPCMStreams (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_I32 maxNumStreams);
+
+/*----------------------------------------------------------------------------
+ * EAS_OpenFile()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Opens a file for audio playback.
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * locator - pointer to filename or other locating information
+ * pStreamHandle - pointer to stream handle variable
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_OpenFile (EAS_DATA_HANDLE pEASData, EAS_FILE_LOCATOR locator, EAS_HANDLE *pStreamHandle);
+
+#ifdef MMAPI_SUPPORT
+/*----------------------------------------------------------------------------
+ * EAS_MMAPIToneControl()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Opens a ToneControl file for audio playback.
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * locator - pointer to filename or other locating information
+ * pStreamHandle - pointer to stream handle variable
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_MMAPIToneControl (EAS_DATA_HANDLE pEASData, EAS_FILE_LOCATOR locator, EAS_HANDLE *pStreamHandle);
+
+/*----------------------------------------------------------------------------
+ * EAS_GetWaveFmtChunk
+ *----------------------------------------------------------------------------
+ * Helper function to retrieve WAVE file fmt chunk for MMAPI
+ *----------------------------------------------------------------------------
+ * pEASData - pointer to EAS persistent data object
+ * streamHandle - stream handle
+ * pFmtChunk - pointer to pointer to FMT chunk data
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_GetWaveFmtChunk (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle, EAS_VOID_PTR *ppFmtChunk);
+#endif
+
+/*----------------------------------------------------------------------------
+ * EAS_GetFileType
+ *----------------------------------------------------------------------------
+ * Returns the file type (see eas_types.h for enumerations)
+ *----------------------------------------------------------------------------
+ * pEASData - pointer to EAS persistent data object
+ * streamHandle - stream handle
+ * pFileType - pointer to variable to receive file type
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_GetFileType (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle, EAS_I32 *pFileType);
+
+/*----------------------------------------------------------------------------
+ * EAS_ParseMetaData()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ *
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * streamHandle - file or stream handle
+ * playLength - pointer to variable to store the play length (in msecs)
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ * - resets the parser to the start of the file
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_ParseMetaData (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle, EAS_I32 *pPlayLength);
+
+/*----------------------------------------------------------------------------
+ * EAS_Prepare()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Prepares the synthesizer to play the file or stream. Parses the first
+ * frame of data from the file and arms the synthesizer.
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * streamHandle - file or stream handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_Prepare (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle);
+
+/*----------------------------------------------------------------------------
+ * EAS_State()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Returns the state of an audio file or stream.
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * streamHandle - file or stream handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_State (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle, EAS_STATE *pState);
+
+/*----------------------------------------------------------------------------
+ * EAS_RegisterMetaDataCallback()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Registers a metadata callback function for parsed metadata. To
+ * de-register the callback, call this function again with parameter
+ * cbFunc set to NULL.
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * streamHandle - file or stream handle
+ * cbFunc - pointer to host callback function
+ * metaDataBuffer - pointer to metadata buffer
+ * metaDataBufSize - maximum size of the metadata buffer
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_RegisterMetaDataCallback (
+ EAS_DATA_HANDLE pEASData,
+ EAS_HANDLE streamHandle,
+ EAS_METADATA_CBFUNC cbFunc,
+ char *metaDataBuffer,
+ EAS_I32 metaDataBufSize,
+ EAS_VOID_PTR pUserData);
+
+/*----------------------------------------------------------------------------
+ * EAS_GetNoteCount ()
+ *----------------------------------------------------------------------------
+ * Returns the total number of notes played in this stream
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * streamHandle - file or stream handle
+ * pNoteCount - pointer to variable to receive note count
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_GetNoteCount (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_I32 *pNoteCount);
+
+/*----------------------------------------------------------------------------
+ * EAS_CloseFile()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Closes an audio file or stream. Playback should have either paused or
+ * completed (EAS_State returns EAS_PAUSED or EAS_STOPPED).
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * streamHandle - file or stream handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_CloseFile (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle);
+
+/*----------------------------------------------------------------------------
+ * EAS_OpenMIDIStream()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Opens a raw MIDI stream allowing the host to route MIDI cable data directly to the synthesizer
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * pStreamHandle - pointer to variable to hold file or stream handle
+ * streamHandle - open stream or NULL for new synthesizer instance
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_OpenMIDIStream (EAS_DATA_HANDLE pEASData, EAS_HANDLE *pStreamHandle, EAS_HANDLE streamHandle);
+
+/*----------------------------------------------------------------------------
+ * EAS_WriteMIDIStream()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Send data to the MIDI stream device
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * streamHandle - stream handle
+ * pBuffer - pointer to buffer
+ * count - number of bytes to write
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_WriteMIDIStream(EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle, EAS_U8 *pBuffer, EAS_I32 count);
+
+/*----------------------------------------------------------------------------
+ * EAS_CloseMIDIStream()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Closes a raw MIDI stream
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * streamHandle - stream handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_CloseMIDIStream (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle);
+
+/*----------------------------------------------------------------------------
+ * EAS_Locate()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Locate into the file associated with the handle.
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * streamHandle - file handle
+ * milliseconds - playback offset from start of file in milliseconds
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ * the actual offset will be quantized to the closest update period, typically
+ * a resolution of 5.9ms. Notes that are started prior to this time will not
+ * sound. Any notes currently playing will be shut off.
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_Locate (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle, EAS_I32 milliseconds, EAS_BOOL offset);
+
+/*----------------------------------------------------------------------------
+ * EAS_GetRenderTime()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Returns the current playback offset
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ * Gets the render time clock in msecs.
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_GetRenderTime (EAS_DATA_HANDLE pEASData, EAS_I32 *pTime);
+
+/*----------------------------------------------------------------------------
+ * EAS_GetLocation()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Returns the current playback offset
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * streamHandle - file handle
+ *
+ * Outputs:
+ * The offset in milliseconds from the start of the current sequence, quantized
+ * to the nearest update period. Actual resolution is typically 5.9 ms.
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_GetLocation (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle, EAS_I32 *pTime);
+
+/*----------------------------------------------------------------------------
+ * EAS_Pause()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Pauses the playback of the data associated with this handle. The audio
+ * is gracefully ramped down to prevent clicks and pops. It may take several
+ * buffers of audio before the audio is muted.
+ *
+ * Inputs:
+ * psEASData - pointer to overall EAS data structure
+ * streamHandle - file or stream handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_Pause (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle);
+
+/*----------------------------------------------------------------------------
+ * EAS_Resume()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Resumes the playback of the data associated with this handle. The audio
+ * is gracefully ramped up to prevent clicks and pops.
+ *
+ * Inputs:
+ * psEASData - pointer to overall EAS data structure
+ * streamHandle - file or stream handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_Resume (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle);
+
+/*----------------------------------------------------------------------------
+ * EAS_GetParameter()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Set the parameter of a module. See E_MODULES for a list of modules
+ * and the header files of the modules for a list of parameters.
+ *
+ * Inputs:
+ * psEASData - pointer to overall EAS data structure
+ * module - enumerated module number
+ * param - enumerated parameter number
+ * pValue - pointer to variable to receive parameter value
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_GetParameter (EAS_DATA_HANDLE pEASData, EAS_I32 module, EAS_I32 param, EAS_I32 *pValue);
+
+/*----------------------------------------------------------------------------
+ * EAS_SetParameter()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Set the parameter of a module. See E_MODULES for a list of modules
+ * and the header files of the modules for a list of parameters.
+ *
+ * Inputs:
+ * psEASData - pointer to overall EAS data structure
+ * handle - file or stream handle
+ * module - enumerated module number
+ * param - enumerated parameter number
+ * value - new parameter value
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_SetParameter (EAS_DATA_HANDLE pEASData, EAS_I32 module, EAS_I32 param, EAS_I32 value);
+
+#ifdef _METRICS_ENABLED
+/*----------------------------------------------------------------------------
+ * EAS_MetricsReport()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Displays the current metrics through the EAS_Report interface.
+ *
+ * Inputs:
+ * pEASData - instance data handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_MetricsReport (EAS_DATA_HANDLE pEASData);
+
+/*----------------------------------------------------------------------------
+ * EAS_MetricsReset()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Displays the current metrics through the EAS_Report interface.
+ *
+ * Inputs:
+ * pEASData - instance data handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_MetricsReset (EAS_DATA_HANDLE pEASData);
+#endif
+
+/*----------------------------------------------------------------------------
+ * EAS_SetSoundLibrary()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Sets the location of the sound library.
+ *
+ * Inputs:
+ * pEASData - instance data handle
+ * streamHandle - file or stream handle
+ * pSoundLib - pointer to sound library
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_SetSoundLibrary (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle, EAS_SNDLIB_HANDLE pSndLib);
+
+/*----------------------------------------------------------------------------
+ * EAS_SetHeaderSearchFlag()
+ *----------------------------------------------------------------------------
+ * By default, when EAS_OpenFile is called, the parsers check the
+ * first few bytes of the file looking for a specific header. Some
+ * mobile devices may add a header to the start of a file, which
+ * will prevent the parser from recognizing the file. If the
+ * searchFlag is set to EAS_TRUE, the parser will search the entire
+ * file looking for the header. This may enable EAS to recognize
+ * some files that it would ordinarily reject. The negative is that
+ * it make take slightly longer to process the EAS_OpenFile request.
+ *
+ * Inputs:
+ * pEASData - instance data handle
+ * searchFlag - search flag (EAS_TRUE or EAS_FALSE)
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_SetHeaderSearchFlag (EAS_DATA_HANDLE pEASData, EAS_BOOL searchFlag);
+
+/*----------------------------------------------------------------------------
+ * EAS_SetPlayMode()
+ *----------------------------------------------------------------------------
+ * Some file formats support special play modes, such as iMode partial
+ * play mode. This call can be used to change the play mode. The
+ * default play mode (usually straight playback) is always zero.
+ *
+ * Inputs:
+ * pEASData - instance data handle
+ * handle - file or stream handle
+ * playMode - play mode (see eas_types.h for enumerations)
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_SetPlayMode (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_I32 playMode);
+
+#ifdef DLS_SYNTHESIZER
+/*----------------------------------------------------------------------------
+ * EAS_LoadDLSCollection()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Downloads a DLS collection
+ *
+ * Inputs:
+ * pEASData - instance data handle
+ * streamHandle - file or stream handle
+ * locator - file locator
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ * May overlay instruments in the GM sound set
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_LoadDLSCollection (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle, EAS_FILE_LOCATOR locator);
+#endif
+
+/*----------------------------------------------------------------------------
+ * EAS_SetFrameBuffer()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Sets the frame buffer pointer passed to the IPC communications functions
+ *
+ * Inputs:
+ * pEASData - instance data handle
+ * locator - file locator
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ * May overlay instruments in the GM sound set
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_SetFrameBuffer (EAS_DATA_HANDLE pEASData, EAS_FRAME_BUFFER_HANDLE pFrameBuffer);
+
+#ifdef EXTERNAL_AUDIO
+/*----------------------------------------------------------------------------
+ * EAS_RegExtAudioCallback()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Registers callback functions for audio events.
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * streamHandle - file or stream handle
+ * cbProgChgFunc - pointer to host callback function for program change
+ * cbEventFunc - pointer to host callback functio for note events
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_RegExtAudioCallback (EAS_DATA_HANDLE pEASData,
+ EAS_HANDLE streamHandle,
+ EAS_VOID_PTR pInstData,
+ EAS_EXT_PRG_CHG_FUNC cbProgChgFunc,
+ EAS_EXT_EVENT_FUNC cbEventFunc);
+
+/*----------------------------------------------------------------------------
+ * EAS_GetMIDIControllers()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Returns the current state of MIDI controllers on the requested channel.
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * streamHandle - file or stream handle
+ * pControl - pointer to structure to receive data
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_GetMIDIControllers (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle, EAS_U8 channel, S_MIDI_CONTROLLERS *pControl);
+#endif
+
+/*----------------------------------------------------------------------------
+ * EAS_SearchFile
+ *----------------------------------------------------------------------------
+ * Search file for specific sequence starting at current file
+ * position. Returns offset to start of sequence.
+ *
+ * Inputs:
+ * pEASData - pointer to EAS persistent data object
+ * fileHandle - file handle
+ * searchString - pointer to search sequence
+ * len - length of search sequence
+ * pOffset - pointer to variable to store offset to sequence
+ *
+ * Returns EAS_EOF if end-of-file is reached
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_SearchFile (EAS_DATA_HANDLE pEASData, EAS_FILE_HANDLE fileHandle, const EAS_U8 *searchString, EAS_I32 len, EAS_I32 *pOffset);
+
+#ifdef __cplusplus
+} /* end extern "C" */
+#endif
+
+#endif /* #ifndef _EAS_H */
diff --git a/arm-fm-22k/host_src/eas_build.h b/arm-fm-22k/host_src/eas_build.h
index 64ccf5a..5b058e7 100644
--- a/arm-fm-22k/host_src/eas_build.h
+++ b/arm-fm-22k/host_src/eas_build.h
@@ -1,15 +1,15 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * host_src\eas_build.h
- *
- * Contents and purpose:
- * This file contains the build configuration for this
- * build. The buildGUIDStr is a GUID created during
- * the build process and is guaranteed to be unique
- * for each build.
- *
- * Copyright Sonic Network Inc. 2006
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * host_src\eas_build.h
+ *
+ * Contents and purpose:
+ * This file contains the build configuration for this
+ * build. The buildGUIDStr is a GUID created during
+ * the build process and is guaranteed to be unique
+ * for each build.
+ *
+ * Copyright Sonic Network Inc. 2006
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -22,15 +22,15 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * This file was autogenerated by buildid.exe
- *----------------------------------------------------------------------------
-*/
-
-#ifndef _GUID_53c2509edf8f42e3975a054126c0cc1b_
-#define _GUID_53c2509edf8f42e3975a054126c0cc1b_
-
-#define _BUILD_VERSION_ "53c2509e-df8f-42e3-975a-054126c0cc1b"
-#define _BUILD_TIME_ 0x4743b8c9
-
-#endif /* _GUID_53c2509edf8f42e3975a054126c0cc1b_ */
+ *
+ * This file was autogenerated by buildid.exe
+ *----------------------------------------------------------------------------
+*/
+
+#ifndef _GUID_53c2509edf8f42e3975a054126c0cc1b_
+#define _GUID_53c2509edf8f42e3975a054126c0cc1b_
+
+#define _BUILD_VERSION_ "53c2509e-df8f-42e3-975a-054126c0cc1b"
+#define _BUILD_TIME_ 0x4743b8c9
+
+#endif /* _GUID_53c2509edf8f42e3975a054126c0cc1b_ */
diff --git a/arm-fm-22k/host_src/eas_chorus.h b/arm-fm-22k/host_src/eas_chorus.h
index 0e9057f..998a828 100644
--- a/arm-fm-22k/host_src/eas_chorus.h
+++ b/arm-fm-22k/host_src/eas_chorus.h
@@ -1,13 +1,13 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_chorus.h
- *
- * Contents and purpose:
- * Contains parameter enumerations for the Chorus effect
- *
- *
- * Copyright Sonic Network Inc. 2006
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_chorus.h
+ *
+ * Contents and purpose:
+ * Contains parameter enumerations for the Chorus effect
+ *
+ *
+ * Copyright Sonic Network Inc. 2006
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,34 +20,34 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 309 $
- * $Date: 2006-09-12 18:52:45 -0700 (Tue, 12 Sep 2006) $
- *----------------------------------------------------------------------------
-*/
-
-#ifndef EAS_CHORUS_H
-#define EAS_CHORUS_H
-
-/* enumerated parameter settings for Chorus effect */
-typedef enum
-{
- EAS_PARAM_CHORUS_BYPASS,
- EAS_PARAM_CHORUS_PRESET,
- EAS_PARAM_CHORUS_RATE,
- EAS_PARAM_CHORUS_DEPTH,
- EAS_PARAM_CHORUS_LEVEL
-} E_CHORUS_PARAMS;
-
-typedef enum
-{
- EAS_PARAM_CHORUS_PRESET1,
- EAS_PARAM_CHORUS_PRESET2,
- EAS_PARAM_CHORUS_PRESET3,
- EAS_PARAM_CHORUS_PRESET4
-} E_CHORUS_PRESETS;
-
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 309 $
+ * $Date: 2006-09-12 18:52:45 -0700 (Tue, 12 Sep 2006) $
+ *----------------------------------------------------------------------------
+*/
+
+#ifndef EAS_CHORUS_H
+#define EAS_CHORUS_H
+
+/* enumerated parameter settings for Chorus effect */
+typedef enum
+{
+ EAS_PARAM_CHORUS_BYPASS,
+ EAS_PARAM_CHORUS_PRESET,
+ EAS_PARAM_CHORUS_RATE,
+ EAS_PARAM_CHORUS_DEPTH,
+ EAS_PARAM_CHORUS_LEVEL
+} E_CHORUS_PARAMS;
+
+typedef enum
+{
+ EAS_PARAM_CHORUS_PRESET1,
+ EAS_PARAM_CHORUS_PRESET2,
+ EAS_PARAM_CHORUS_PRESET3,
+ EAS_PARAM_CHORUS_PRESET4
+} E_CHORUS_PRESETS;
+
+
#endif \ No newline at end of file
diff --git a/arm-fm-22k/host_src/eas_config.c b/arm-fm-22k/host_src/eas_config.c
index c45fbb7..0b92357 100644
--- a/arm-fm-22k/host_src/eas_config.c
+++ b/arm-fm-22k/host_src/eas_config.c
@@ -1,22 +1,22 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_config.c
- *
- * Contents and purpose:
- * This file contains the Configuration Module interface (CM). The CM
- * is a module compiled external to the library that sets the configuration
- * for this build. It allows the library to find optional components and
- * links to static memory allocations (when used in a static configuration).
- *
- * DO NOT MODIFY THIS FILE!
- *
- * NOTE: This module is not intended to be modified by the customer. It
- * needs to be included in the build process with the correct configuration
- * defines (see the library documentation for information on how to configure
- * the library).
- *
- * Copyright Sonic Network Inc. 2004-2006
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_config.c
+ *
+ * Contents and purpose:
+ * This file contains the Configuration Module interface (CM). The CM
+ * is a module compiled external to the library that sets the configuration
+ * for this build. It allows the library to find optional components and
+ * links to static memory allocations (when used in a static configuration).
+ *
+ * DO NOT MODIFY THIS FILE!
+ *
+ * NOTE: This module is not intended to be modified by the customer. It
+ * needs to be included in the build process with the correct configuration
+ * defines (see the library documentation for information on how to configure
+ * the library).
+ *
+ * Copyright Sonic Network Inc. 2004-2006
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -29,591 +29,591 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 796 $
- * $Date: 2007-08-01 00:15:25 -0700 (Wed, 01 Aug 2007) $
- *----------------------------------------------------------------------------
-*/
-
-#include "eas.h"
-#include "eas_config.h"
-
-
-#ifdef _MFI_PARSER
-/*----------------------------------------------------------------------------
- * Vendor/Device ID for MFi Extensions
- *
- * Define the preprocessor symbols to establish the vendor ID and
- * device ID for the MFi PCM/ADPCM extensions.
- *----------------------------------------------------------------------------
-*/
-const EAS_U8 eas_MFIVendorIDMSB = (MFI_VENDOR_ID >> 8) & 0xff;
-const EAS_U8 eas_MFIVendorIDLSB = MFI_VENDOR_ID & 0xff;
-const EAS_U8 eas_MFIDeviceID = MFI_DEVICE_ID;
-#endif
-
-/*----------------------------------------------------------------------------
- *
- * parserModules
- *
- * This structure is used by the EAS library to locate file parsing
- * modules.
- *----------------------------------------------------------------------------
-*/
-
-/* define the external file parsers */
-extern EAS_VOID_PTR EAS_SMF_Parser;
-
-#ifdef _XMF_PARSER
-extern EAS_VOID_PTR EAS_XMF_Parser;
-#endif
-
-#ifdef _SMAF_PARSER
-extern EAS_VOID_PTR EAS_SMAF_Parser;
-#endif
-
-#ifdef _WAVE_PARSER
-extern EAS_VOID_PTR EAS_Wave_Parser;
-#endif
-
-#ifdef _OTA_PARSER
-extern EAS_VOID_PTR EAS_OTA_Parser;
-#endif
-
-#ifdef _IMELODY_PARSER
-extern EAS_VOID_PTR EAS_iMelody_Parser;
-#endif
-
-#ifdef _RTTTL_PARSER
-extern EAS_VOID_PTR EAS_RTTTL_Parser;
-#endif
-
-#if defined (_CMX_PARSER) || defined(_MFI_PARSER)
-extern EAS_VOID_PTR EAS_CMF_Parser;
-#endif
-
-/* initalize pointers to parser interfaces */
-/*lint -e{605} not pretty, but it works */
-EAS_VOID_PTR const parserModules[] =
-{
- &EAS_SMF_Parser,
-
-#ifdef _XMF_PARSER
- &EAS_XMF_Parser,
-#endif
-
-#ifdef _WAVE_PARSER
- &EAS_Wave_Parser,
-#endif
-
-#ifdef _SMAF_PARSER
- &EAS_SMAF_Parser,
-#endif
-
-#ifdef _OTA_PARSER
- &EAS_OTA_Parser,
-#endif
-
-#ifdef _IMELODY_PARSER
- &EAS_iMelody_Parser,
-#endif
-
-#ifdef _RTTTL_PARSER
- &EAS_RTTTL_Parser,
-#endif
-
-#if defined (_CMX_PARSER) || defined(_MFI_PARSER)
- &EAS_CMF_Parser
-#endif
-};
-#define NUM_PARSER_MODULES (sizeof(parserModules) / sizeof(EAS_VOID_PTR))
-
-/*----------------------------------------------------------------------------
- * Data Modules
- *----------------------------------------------------------------------------
-*/
-
-#ifdef _STATIC_MEMORY
-extern EAS_VOID_PTR eas_SMFData;
-extern EAS_VOID_PTR eas_Data;
-extern EAS_VOID_PTR eas_MixBuffer;
-extern EAS_VOID_PTR eas_Synth;
-extern EAS_VOID_PTR eas_MIDI;
-extern EAS_VOID_PTR eas_PCMData;
-extern EAS_VOID_PTR eas_MIDIData;
-
-#ifdef _XMF_PARSER
-extern EAS_VOID_PTR eas_XMFData;
-#endif
-
-#ifdef _SMAF_PARSER
-extern EAS_VOID_PTR eas_SMAFData;
-#endif
-
-#ifdef _OTA_PARSER
-extern EAS_VOID_PTR eas_OTAData;
-#endif
-
-#ifdef _IMELODY_PARSER
-extern EAS_VOID_PTR eas_iMelodyData;
-#endif
-
-#ifdef _RTTTL_PARSER
-extern EAS_VOID_PTR eas_RTTTLData;
-#endif
-
-#ifdef _WAVE_PARSER
-extern EAS_VOID_PTR eas_WaveData;
-#endif
-
-#if defined (_CMX_PARSER) || defined(_MFI_PARSER)
-extern EAS_VOID_PTR eas_CMFData;
-#endif
-#endif
-
-/*----------------------------------------------------------------------------
- *
- * Effects Modules
- *
- * These declarations are used by the EAS library to locate
- * effects modules.
- *----------------------------------------------------------------------------
-*/
-
-#ifdef _ENHANCER_ENABLED
-extern EAS_VOID_PTR EAS_Enhancer;
-#define EAS_ENHANCER_INTERFACE &EAS_Enhancer
-#ifdef _STATIC_MEMORY
-extern EAS_VOID_PTR eas_EnhancerData;
-#define EAS_ENHANCER_DATA &eas_EnhancerData
-#else
-#define EAS_ENHANCER_DATA NULL
-#endif
-#else
-#define EAS_ENHANCER_INTERFACE NULL
-#define EAS_ENHANCER_DATA NULL
-#endif
-
-#ifdef _COMPRESSOR_ENABLED
-extern EAS_VOID_PTR EAS_Compressor;
-#define EAS_COMPRESSOR_INTERFACE &EAS_Compressor
-#ifdef _STATIC_MEMORY
-extern EAS_VOID_PTR eas_CompressorData;
-#define EAS_COMPRESSOR_DATA &eas_CompressorData
-#else
-#define EAS_COMPRESSOR_DATA NULL
-#endif
-#else
-#define EAS_COMPRESSOR_INTERFACE NULL
-#define EAS_COMPRESSOR_DATA NULL
-#endif
-
-#ifdef _MAXIMIZER_ENABLED
-extern EAS_VOID_PTR EAS_Maximizer;
-#define EAS_MAXIMIZER_INTERFACE &EAS_Maximizer
-#ifdef _STATIC_MEMORY
-extern EAS_VOID_PTR eas_MaximizerData;
-#define EAS_MAXIMIZER_DATA &eas_MaximizerData
-#else
-#define EAS_MAXIMIZER_DATA NULL
-#endif
-#else
-#define EAS_MAXIMIZER_INTERFACE NULL
-#define EAS_MAXIMIZER_DATA NULL
-#endif
-
-
-#ifdef _REVERB_ENABLED
-extern EAS_VOID_PTR EAS_Reverb;
-#define EAS_REVERB_INTERFACE &EAS_Reverb
-#ifdef _STATIC_MEMORY
-extern EAS_VOID_PTR eas_ReverbData;
-#define EAS_REVERB_DATA &eas_ReverbData
-#else
-#define EAS_REVERB_DATA NULL
-#endif
-#else
-#define EAS_REVERB_INTERFACE NULL
-#define EAS_REVERB_DATA NULL
-#endif
-
-#ifdef _CHORUS_ENABLED
-extern EAS_VOID_PTR EAS_Chorus;
-#define EAS_CHORUS_INTERFACE &EAS_Chorus
-#ifdef _STATIC_MEMORY
-extern EAS_VOID_PTR eas_ChorusData;
-#define EAS_CHORUS_DATA &eas_ChorusData
-#else
-#define EAS_CHORUS_DATA NULL
-#endif
-#else
-#define EAS_CHORUS_INTERFACE NULL
-#define EAS_CHORUS_DATA NULL
-#endif
-
-#ifdef _WIDENER_ENABLED
-extern EAS_VOID_PTR EAS_Widener;
-#define EAS_WIDENER_INTERFACE &EAS_Widener
-#ifdef _STATIC_MEMORY
-extern EAS_VOID_PTR eas_WidenerData;
-#define EAS_WIDENER_DATA &eas_WidenerData
-#else
-#define EAS_WIDENER_DATA NULL
-#endif
-#else
-#define EAS_WIDENER_INTERFACE NULL
-#define EAS_WIDENER_DATA NULL
-#endif
-
-#ifdef _GRAPHIC_EQ_ENABLED
-extern EAS_VOID_PTR EAS_GraphicEQ;
-#define EAS_GRAPHIC_EQ_INTERFACE &EAS_GraphicEQ
-#ifdef _STATIC_MEMORY
-extern EAS_VOID_PTR eas_GraphicEQData;
-#define EAS_GRAPHIC_EQ_DATA &eas_GraphicEQData
-#else
-#define EAS_GRAPHIC_EQ_DATA NULL
-#endif
-#else
-#define EAS_GRAPHIC_EQ_INTERFACE NULL
-#define EAS_GRAPHIC_EQ_DATA NULL
-#endif
-
-#ifdef _WOW_ENABLED
-extern EAS_VOID_PTR EAS_Wow;
-#define EAS_WOW_INTERFACE &EAS_Wow
-#ifdef _STATIC_MEMORY
-#error "WOW module requires dynamic memory model"
-#else
-#define EAS_WOW_DATA NULL
-#endif
-#else
-#define EAS_WOW_INTERFACE NULL
-#define EAS_WOW_DATA NULL
-#endif
-
-#ifdef _TONECONTROLEQ_ENABLED
-extern EAS_VOID_PTR EAS_ToneControlEQ;
-#define EAS_TONECONTROLEQ_INTERFACE &EAS_ToneControlEQ
-#ifdef _STATIC_MEMORY
-extern EAS_VOID_PTR eas_ToneControlEQData;
-#define EAS_TONECONTROLEQ_DATA &eas_ToneControlEQData
-#else
-#define EAS_TONECONTROLEQ_DATA NULL
-#endif
-#else
-#define EAS_TONECONTROLEQ_INTERFACE NULL
-#define EAS_TONECONTROLEQ_DATA NULL
-#endif
-
-/*lint -e{605} not pretty, but it works */
-EAS_VOID_PTR const effectsModules[] =
-{
- EAS_ENHANCER_INTERFACE,
- EAS_COMPRESSOR_INTERFACE,
- EAS_REVERB_INTERFACE,
- EAS_CHORUS_INTERFACE,
- EAS_WIDENER_INTERFACE,
- EAS_GRAPHIC_EQ_INTERFACE,
- EAS_WOW_INTERFACE,
- EAS_MAXIMIZER_INTERFACE,
- EAS_TONECONTROLEQ_INTERFACE
-};
-
-EAS_VOID_PTR const effectsData[] =
-{
- EAS_ENHANCER_DATA,
- EAS_COMPRESSOR_DATA,
- EAS_REVERB_DATA,
- EAS_CHORUS_DATA,
- EAS_WIDENER_DATA,
- EAS_GRAPHIC_EQ_DATA,
- EAS_WOW_DATA,
- EAS_MAXIMIZER_DATA,
- EAS_TONECONTROLEQ_DATA
-};
-
-/*----------------------------------------------------------------------------
- *
- * Optional Modules
- *
- * These declarations are used by the EAS library to locate
- * effects modules.
- *----------------------------------------------------------------------------
-*/
-
-#ifdef _METRICS_ENABLED
-extern EAS_VOID_PTR EAS_Metrics;
-#define EAS_METRICS_INTERFACE &EAS_Metrics
-#ifdef _STATIC_MEMORY
-extern EAS_VOID_PTR eas_MetricsData;
-#define EAS_METRICS_DATA &eas_MetricsData
-#else
-#define EAS_METRICS_DATA NULL
-#endif
-#else
-#define EAS_METRICS_INTERFACE NULL
-#define EAS_METRICS_DATA NULL
-#endif
-
-#ifdef MMAPI_SUPPORT
-extern EAS_VOID_PTR EAS_TC_Parser;
-#define EAS_TONE_CONTROL_PARSER &EAS_TC_Parser
-#ifdef _STATIC_MEMORY
-extern EAS_VOID_PTR eas_TCData;
-#define EAS_TONE_CONTROL_DATA &eas_TCData
-#else
-#define EAS_TONE_CONTROL_DATA NULL
-#endif
-#else
-#define EAS_TONE_CONTROL_PARSER NULL
-#define EAS_TONE_CONTROL_DATA NULL
-#endif
-
-/*lint -e{605} not pretty, but it works */
-EAS_VOID_PTR const optionalModules[] =
-{
- EAS_TONE_CONTROL_PARSER,
- EAS_METRICS_INTERFACE
-};
-
-EAS_VOID_PTR const optionalData[] =
-{
- EAS_TONE_CONTROL_DATA,
- EAS_METRICS_DATA
-};
-
-/*----------------------------------------------------------------------------
- * EAS_CMStaticMemoryModel()
- *----------------------------------------------------------------------------
- * Purpose:
- * This function returns true if EAS has been configured for
- * a static memory model. There are some limitations in the
- * static memory model, see the documentation for more
- * information.
- *
- * Outputs:
- * returns EAS_TRUE if a module is found
- *----------------------------------------------------------------------------
-*/
-EAS_BOOL EAS_CMStaticMemoryModel (void)
-{
-#ifdef _STATIC_MEMORY
- return EAS_TRUE;
-#else
- return EAS_FALSE;
-#endif
-}
-
-/*----------------------------------------------------------------------------
- * EAS_CMEnumModules()
- *----------------------------------------------------------------------------
- * Purpose:
- * This function is used to find pointers to optional modules.
- *
- * Inputs:
- * module - module number
- *
- * Outputs:
- * returns a pointer to the module function table or NULL if no module
- *----------------------------------------------------------------------------
-*/
-EAS_VOID_PTR EAS_CMEnumModules (EAS_INT module)
-{
-
- if (module >= (EAS_INT) NUM_PARSER_MODULES)
- return NULL;
- return parserModules[module];
-}
-
-/*----------------------------------------------------------------------------
- * EAS_CMEnumData()
- *----------------------------------------------------------------------------
- * Purpose:
- * This function is used to find pointers to static memory allocations.
- *
- * Inputs:
- * dataModule - enumerated module number
- *
- * Outputs:
- * Returns handle to data or NULL if not found
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, dataModule) used only when _STATIC_MEMORY is defined */
-EAS_VOID_PTR EAS_CMEnumData (EAS_INT dataModule)
-{
-
-#ifdef _STATIC_MEMORY
- switch (dataModule)
- {
-
- /* main instance data for synthesizer */
- case EAS_CM_EAS_DATA:
- return &eas_Data;
-
- /* mix buffer for mix engine */
- case EAS_CM_MIX_BUFFER:
- /*lint -e{545} lint doesn't like this because it sees the underlying type */
- return &eas_MixBuffer;
-
- /* instance data for synth */
- case EAS_CM_SYNTH_DATA:
- return &eas_Synth;
-
- /* instance data for MIDI parser */
- case EAS_CM_MIDI_DATA:
- return &eas_MIDI;
-
- /* instance data for SMF parser */
- case EAS_CM_SMF_DATA:
- return &eas_SMFData;
-
-#ifdef _XMF_PARSER
- /* instance data for XMF parser */
- case EAS_CM_XMF_DATA:
- return &eas_XMFData;
-#endif
-
-#ifdef _SMAF_PARSER
- /* instance data for SMAF parser */
- case EAS_CM_SMAF_DATA:
- return &eas_SMAFData;
-#endif
-
- /* instance data for the PCM engine */
- case EAS_CM_PCM_DATA:
- /*lint -e{545} lint doesn't like this because it sees the underlying type */
- return &eas_PCMData;
-
- case EAS_CM_MIDI_STREAM_DATA:
- return &eas_MIDIData;
-
-#ifdef _OTA_PARSER
- /* instance data for OTA parser */
- case EAS_CM_OTA_DATA:
- return &eas_OTAData;
-#endif
-
-#ifdef _IMELODY_PARSER
- /* instance data for iMelody parser */
- case EAS_CM_IMELODY_DATA:
- return &eas_iMelodyData;
-#endif
-
-#ifdef _RTTTL_PARSER
- /* instance data for RTTTL parser */
- case EAS_CM_RTTTL_DATA:
- return &eas_RTTTLData;
-#endif
-
-#ifdef _WAVE_PARSER
- /* instance data for WAVE parser */
- case EAS_CM_WAVE_DATA:
- return &eas_WaveData;
-#endif
-
-#if defined (_CMX_PARSER) || defined(_MFI_PARSER)
- /* instance data for CMF parser */
- case EAS_CM_CMF_DATA:
- return &eas_CMFData;
-#endif
-
- default:
- return NULL;
- }
-
-#else
- return NULL;
-#endif
-}
-
-/*----------------------------------------------------------------------------
- * EAS_CMEnumFXModules()
- *----------------------------------------------------------------------------
- * Purpose:
- * This function is used to find pointers to optional effects modules.
- *
- * Inputs:
- * module - enumerated module number
- * pModule - pointer to module interface
- *
- * Outputs:
- * Returns pointer to function table or NULL if not found
- *----------------------------------------------------------------------------
-*/
-EAS_VOID_PTR EAS_CMEnumFXModules (EAS_INT module)
-{
-
- if (module >= NUM_EFFECTS_MODULES)
- return NULL;
- return effectsModules[module];
-}
-
-/*----------------------------------------------------------------------------
- * EAS_CMEnumFXData()
- *----------------------------------------------------------------------------
- * Purpose:
- * This function is used to find pointers to static memory allocations.
- *
- * Inputs:
- * dataModule - enumerated module number
- * pData - pointer to handle variable
- *
- * Outputs:
- * Returns handle to data or NULL if not found
- *----------------------------------------------------------------------------
-*/
-EAS_VOID_PTR EAS_CMEnumFXData (EAS_INT dataModule)
-{
-
- if (dataModule >= NUM_EFFECTS_MODULES)
- return NULL;
- return effectsData[dataModule];
-}
-
-/*----------------------------------------------------------------------------
- * EAS_CMEnumOptModules()
- *----------------------------------------------------------------------------
- * Purpose:
- * This function is used to find pointers to optional modules.
- *
- * Inputs:
- * module - enumerated module number
- *
- * Outputs:
- * returns pointer to function table or NULL if no module
- *----------------------------------------------------------------------------
-*/
-EAS_VOID_PTR EAS_CMEnumOptModules (EAS_INT module)
-{
-
- /* sanity check */
- if (module >= NUM_OPTIONAL_MODULES)
- return EAS_FALSE;
- return optionalModules[module];
-}
-
-/*----------------------------------------------------------------------------
- * EAS_CMEnumOptData()
- *----------------------------------------------------------------------------
- * Purpose:
- * This function is used to find pointers to static memory allocations.
- *
- * Inputs:
- * dataModule - enumerated module number
- *
- * Outputs:
- * Returns handle to data or NULL if not found
- *----------------------------------------------------------------------------
-*/
-EAS_VOID_PTR EAS_CMEnumOptData (EAS_INT dataModule)
-{
-
- if (dataModule >= NUM_OPTIONAL_MODULES)
- return NULL;
- return optionalData[dataModule];
-}
-
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 796 $
+ * $Date: 2007-08-01 00:15:25 -0700 (Wed, 01 Aug 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+#include "eas.h"
+#include "eas_config.h"
+
+
+#ifdef _MFI_PARSER
+/*----------------------------------------------------------------------------
+ * Vendor/Device ID for MFi Extensions
+ *
+ * Define the preprocessor symbols to establish the vendor ID and
+ * device ID for the MFi PCM/ADPCM extensions.
+ *----------------------------------------------------------------------------
+*/
+const EAS_U8 eas_MFIVendorIDMSB = (MFI_VENDOR_ID >> 8) & 0xff;
+const EAS_U8 eas_MFIVendorIDLSB = MFI_VENDOR_ID & 0xff;
+const EAS_U8 eas_MFIDeviceID = MFI_DEVICE_ID;
+#endif
+
+/*----------------------------------------------------------------------------
+ *
+ * parserModules
+ *
+ * This structure is used by the EAS library to locate file parsing
+ * modules.
+ *----------------------------------------------------------------------------
+*/
+
+/* define the external file parsers */
+extern EAS_VOID_PTR EAS_SMF_Parser;
+
+#ifdef _XMF_PARSER
+extern EAS_VOID_PTR EAS_XMF_Parser;
+#endif
+
+#ifdef _SMAF_PARSER
+extern EAS_VOID_PTR EAS_SMAF_Parser;
+#endif
+
+#ifdef _WAVE_PARSER
+extern EAS_VOID_PTR EAS_Wave_Parser;
+#endif
+
+#ifdef _OTA_PARSER
+extern EAS_VOID_PTR EAS_OTA_Parser;
+#endif
+
+#ifdef _IMELODY_PARSER
+extern EAS_VOID_PTR EAS_iMelody_Parser;
+#endif
+
+#ifdef _RTTTL_PARSER
+extern EAS_VOID_PTR EAS_RTTTL_Parser;
+#endif
+
+#if defined (_CMX_PARSER) || defined(_MFI_PARSER)
+extern EAS_VOID_PTR EAS_CMF_Parser;
+#endif
+
+/* initalize pointers to parser interfaces */
+/*lint -e{605} not pretty, but it works */
+EAS_VOID_PTR const parserModules[] =
+{
+ &EAS_SMF_Parser,
+
+#ifdef _XMF_PARSER
+ &EAS_XMF_Parser,
+#endif
+
+#ifdef _WAVE_PARSER
+ &EAS_Wave_Parser,
+#endif
+
+#ifdef _SMAF_PARSER
+ &EAS_SMAF_Parser,
+#endif
+
+#ifdef _OTA_PARSER
+ &EAS_OTA_Parser,
+#endif
+
+#ifdef _IMELODY_PARSER
+ &EAS_iMelody_Parser,
+#endif
+
+#ifdef _RTTTL_PARSER
+ &EAS_RTTTL_Parser,
+#endif
+
+#if defined (_CMX_PARSER) || defined(_MFI_PARSER)
+ &EAS_CMF_Parser
+#endif
+};
+#define NUM_PARSER_MODULES (sizeof(parserModules) / sizeof(EAS_VOID_PTR))
+
+/*----------------------------------------------------------------------------
+ * Data Modules
+ *----------------------------------------------------------------------------
+*/
+
+#ifdef _STATIC_MEMORY
+extern EAS_VOID_PTR eas_SMFData;
+extern EAS_VOID_PTR eas_Data;
+extern EAS_VOID_PTR eas_MixBuffer;
+extern EAS_VOID_PTR eas_Synth;
+extern EAS_VOID_PTR eas_MIDI;
+extern EAS_VOID_PTR eas_PCMData;
+extern EAS_VOID_PTR eas_MIDIData;
+
+#ifdef _XMF_PARSER
+extern EAS_VOID_PTR eas_XMFData;
+#endif
+
+#ifdef _SMAF_PARSER
+extern EAS_VOID_PTR eas_SMAFData;
+#endif
+
+#ifdef _OTA_PARSER
+extern EAS_VOID_PTR eas_OTAData;
+#endif
+
+#ifdef _IMELODY_PARSER
+extern EAS_VOID_PTR eas_iMelodyData;
+#endif
+
+#ifdef _RTTTL_PARSER
+extern EAS_VOID_PTR eas_RTTTLData;
+#endif
+
+#ifdef _WAVE_PARSER
+extern EAS_VOID_PTR eas_WaveData;
+#endif
+
+#if defined (_CMX_PARSER) || defined(_MFI_PARSER)
+extern EAS_VOID_PTR eas_CMFData;
+#endif
+#endif
+
+/*----------------------------------------------------------------------------
+ *
+ * Effects Modules
+ *
+ * These declarations are used by the EAS library to locate
+ * effects modules.
+ *----------------------------------------------------------------------------
+*/
+
+#ifdef _ENHANCER_ENABLED
+extern EAS_VOID_PTR EAS_Enhancer;
+#define EAS_ENHANCER_INTERFACE &EAS_Enhancer
+#ifdef _STATIC_MEMORY
+extern EAS_VOID_PTR eas_EnhancerData;
+#define EAS_ENHANCER_DATA &eas_EnhancerData
+#else
+#define EAS_ENHANCER_DATA NULL
+#endif
+#else
+#define EAS_ENHANCER_INTERFACE NULL
+#define EAS_ENHANCER_DATA NULL
+#endif
+
+#ifdef _COMPRESSOR_ENABLED
+extern EAS_VOID_PTR EAS_Compressor;
+#define EAS_COMPRESSOR_INTERFACE &EAS_Compressor
+#ifdef _STATIC_MEMORY
+extern EAS_VOID_PTR eas_CompressorData;
+#define EAS_COMPRESSOR_DATA &eas_CompressorData
+#else
+#define EAS_COMPRESSOR_DATA NULL
+#endif
+#else
+#define EAS_COMPRESSOR_INTERFACE NULL
+#define EAS_COMPRESSOR_DATA NULL
+#endif
+
+#ifdef _MAXIMIZER_ENABLED
+extern EAS_VOID_PTR EAS_Maximizer;
+#define EAS_MAXIMIZER_INTERFACE &EAS_Maximizer
+#ifdef _STATIC_MEMORY
+extern EAS_VOID_PTR eas_MaximizerData;
+#define EAS_MAXIMIZER_DATA &eas_MaximizerData
+#else
+#define EAS_MAXIMIZER_DATA NULL
+#endif
+#else
+#define EAS_MAXIMIZER_INTERFACE NULL
+#define EAS_MAXIMIZER_DATA NULL
+#endif
+
+
+#ifdef _REVERB_ENABLED
+extern EAS_VOID_PTR EAS_Reverb;
+#define EAS_REVERB_INTERFACE &EAS_Reverb
+#ifdef _STATIC_MEMORY
+extern EAS_VOID_PTR eas_ReverbData;
+#define EAS_REVERB_DATA &eas_ReverbData
+#else
+#define EAS_REVERB_DATA NULL
+#endif
+#else
+#define EAS_REVERB_INTERFACE NULL
+#define EAS_REVERB_DATA NULL
+#endif
+
+#ifdef _CHORUS_ENABLED
+extern EAS_VOID_PTR EAS_Chorus;
+#define EAS_CHORUS_INTERFACE &EAS_Chorus
+#ifdef _STATIC_MEMORY
+extern EAS_VOID_PTR eas_ChorusData;
+#define EAS_CHORUS_DATA &eas_ChorusData
+#else
+#define EAS_CHORUS_DATA NULL
+#endif
+#else
+#define EAS_CHORUS_INTERFACE NULL
+#define EAS_CHORUS_DATA NULL
+#endif
+
+#ifdef _WIDENER_ENABLED
+extern EAS_VOID_PTR EAS_Widener;
+#define EAS_WIDENER_INTERFACE &EAS_Widener
+#ifdef _STATIC_MEMORY
+extern EAS_VOID_PTR eas_WidenerData;
+#define EAS_WIDENER_DATA &eas_WidenerData
+#else
+#define EAS_WIDENER_DATA NULL
+#endif
+#else
+#define EAS_WIDENER_INTERFACE NULL
+#define EAS_WIDENER_DATA NULL
+#endif
+
+#ifdef _GRAPHIC_EQ_ENABLED
+extern EAS_VOID_PTR EAS_GraphicEQ;
+#define EAS_GRAPHIC_EQ_INTERFACE &EAS_GraphicEQ
+#ifdef _STATIC_MEMORY
+extern EAS_VOID_PTR eas_GraphicEQData;
+#define EAS_GRAPHIC_EQ_DATA &eas_GraphicEQData
+#else
+#define EAS_GRAPHIC_EQ_DATA NULL
+#endif
+#else
+#define EAS_GRAPHIC_EQ_INTERFACE NULL
+#define EAS_GRAPHIC_EQ_DATA NULL
+#endif
+
+#ifdef _WOW_ENABLED
+extern EAS_VOID_PTR EAS_Wow;
+#define EAS_WOW_INTERFACE &EAS_Wow
+#ifdef _STATIC_MEMORY
+#error "WOW module requires dynamic memory model"
+#else
+#define EAS_WOW_DATA NULL
+#endif
+#else
+#define EAS_WOW_INTERFACE NULL
+#define EAS_WOW_DATA NULL
+#endif
+
+#ifdef _TONECONTROLEQ_ENABLED
+extern EAS_VOID_PTR EAS_ToneControlEQ;
+#define EAS_TONECONTROLEQ_INTERFACE &EAS_ToneControlEQ
+#ifdef _STATIC_MEMORY
+extern EAS_VOID_PTR eas_ToneControlEQData;
+#define EAS_TONECONTROLEQ_DATA &eas_ToneControlEQData
+#else
+#define EAS_TONECONTROLEQ_DATA NULL
+#endif
+#else
+#define EAS_TONECONTROLEQ_INTERFACE NULL
+#define EAS_TONECONTROLEQ_DATA NULL
+#endif
+
+/*lint -e{605} not pretty, but it works */
+EAS_VOID_PTR const effectsModules[] =
+{
+ EAS_ENHANCER_INTERFACE,
+ EAS_COMPRESSOR_INTERFACE,
+ EAS_REVERB_INTERFACE,
+ EAS_CHORUS_INTERFACE,
+ EAS_WIDENER_INTERFACE,
+ EAS_GRAPHIC_EQ_INTERFACE,
+ EAS_WOW_INTERFACE,
+ EAS_MAXIMIZER_INTERFACE,
+ EAS_TONECONTROLEQ_INTERFACE
+};
+
+EAS_VOID_PTR const effectsData[] =
+{
+ EAS_ENHANCER_DATA,
+ EAS_COMPRESSOR_DATA,
+ EAS_REVERB_DATA,
+ EAS_CHORUS_DATA,
+ EAS_WIDENER_DATA,
+ EAS_GRAPHIC_EQ_DATA,
+ EAS_WOW_DATA,
+ EAS_MAXIMIZER_DATA,
+ EAS_TONECONTROLEQ_DATA
+};
+
+/*----------------------------------------------------------------------------
+ *
+ * Optional Modules
+ *
+ * These declarations are used by the EAS library to locate
+ * effects modules.
+ *----------------------------------------------------------------------------
+*/
+
+#ifdef _METRICS_ENABLED
+extern EAS_VOID_PTR EAS_Metrics;
+#define EAS_METRICS_INTERFACE &EAS_Metrics
+#ifdef _STATIC_MEMORY
+extern EAS_VOID_PTR eas_MetricsData;
+#define EAS_METRICS_DATA &eas_MetricsData
+#else
+#define EAS_METRICS_DATA NULL
+#endif
+#else
+#define EAS_METRICS_INTERFACE NULL
+#define EAS_METRICS_DATA NULL
+#endif
+
+#ifdef MMAPI_SUPPORT
+extern EAS_VOID_PTR EAS_TC_Parser;
+#define EAS_TONE_CONTROL_PARSER &EAS_TC_Parser
+#ifdef _STATIC_MEMORY
+extern EAS_VOID_PTR eas_TCData;
+#define EAS_TONE_CONTROL_DATA &eas_TCData
+#else
+#define EAS_TONE_CONTROL_DATA NULL
+#endif
+#else
+#define EAS_TONE_CONTROL_PARSER NULL
+#define EAS_TONE_CONTROL_DATA NULL
+#endif
+
+/*lint -e{605} not pretty, but it works */
+EAS_VOID_PTR const optionalModules[] =
+{
+ EAS_TONE_CONTROL_PARSER,
+ EAS_METRICS_INTERFACE
+};
+
+EAS_VOID_PTR const optionalData[] =
+{
+ EAS_TONE_CONTROL_DATA,
+ EAS_METRICS_DATA
+};
+
+/*----------------------------------------------------------------------------
+ * EAS_CMStaticMemoryModel()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * This function returns true if EAS has been configured for
+ * a static memory model. There are some limitations in the
+ * static memory model, see the documentation for more
+ * information.
+ *
+ * Outputs:
+ * returns EAS_TRUE if a module is found
+ *----------------------------------------------------------------------------
+*/
+EAS_BOOL EAS_CMStaticMemoryModel (void)
+{
+#ifdef _STATIC_MEMORY
+ return EAS_TRUE;
+#else
+ return EAS_FALSE;
+#endif
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_CMEnumModules()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * This function is used to find pointers to optional modules.
+ *
+ * Inputs:
+ * module - module number
+ *
+ * Outputs:
+ * returns a pointer to the module function table or NULL if no module
+ *----------------------------------------------------------------------------
+*/
+EAS_VOID_PTR EAS_CMEnumModules (EAS_INT module)
+{
+
+ if (module >= (EAS_INT) NUM_PARSER_MODULES)
+ return NULL;
+ return parserModules[module];
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_CMEnumData()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * This function is used to find pointers to static memory allocations.
+ *
+ * Inputs:
+ * dataModule - enumerated module number
+ *
+ * Outputs:
+ * Returns handle to data or NULL if not found
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, dataModule) used only when _STATIC_MEMORY is defined */
+EAS_VOID_PTR EAS_CMEnumData (EAS_INT dataModule)
+{
+
+#ifdef _STATIC_MEMORY
+ switch (dataModule)
+ {
+
+ /* main instance data for synthesizer */
+ case EAS_CM_EAS_DATA:
+ return &eas_Data;
+
+ /* mix buffer for mix engine */
+ case EAS_CM_MIX_BUFFER:
+ /*lint -e{545} lint doesn't like this because it sees the underlying type */
+ return &eas_MixBuffer;
+
+ /* instance data for synth */
+ case EAS_CM_SYNTH_DATA:
+ return &eas_Synth;
+
+ /* instance data for MIDI parser */
+ case EAS_CM_MIDI_DATA:
+ return &eas_MIDI;
+
+ /* instance data for SMF parser */
+ case EAS_CM_SMF_DATA:
+ return &eas_SMFData;
+
+#ifdef _XMF_PARSER
+ /* instance data for XMF parser */
+ case EAS_CM_XMF_DATA:
+ return &eas_XMFData;
+#endif
+
+#ifdef _SMAF_PARSER
+ /* instance data for SMAF parser */
+ case EAS_CM_SMAF_DATA:
+ return &eas_SMAFData;
+#endif
+
+ /* instance data for the PCM engine */
+ case EAS_CM_PCM_DATA:
+ /*lint -e{545} lint doesn't like this because it sees the underlying type */
+ return &eas_PCMData;
+
+ case EAS_CM_MIDI_STREAM_DATA:
+ return &eas_MIDIData;
+
+#ifdef _OTA_PARSER
+ /* instance data for OTA parser */
+ case EAS_CM_OTA_DATA:
+ return &eas_OTAData;
+#endif
+
+#ifdef _IMELODY_PARSER
+ /* instance data for iMelody parser */
+ case EAS_CM_IMELODY_DATA:
+ return &eas_iMelodyData;
+#endif
+
+#ifdef _RTTTL_PARSER
+ /* instance data for RTTTL parser */
+ case EAS_CM_RTTTL_DATA:
+ return &eas_RTTTLData;
+#endif
+
+#ifdef _WAVE_PARSER
+ /* instance data for WAVE parser */
+ case EAS_CM_WAVE_DATA:
+ return &eas_WaveData;
+#endif
+
+#if defined (_CMX_PARSER) || defined(_MFI_PARSER)
+ /* instance data for CMF parser */
+ case EAS_CM_CMF_DATA:
+ return &eas_CMFData;
+#endif
+
+ default:
+ return NULL;
+ }
+
+#else
+ return NULL;
+#endif
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_CMEnumFXModules()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * This function is used to find pointers to optional effects modules.
+ *
+ * Inputs:
+ * module - enumerated module number
+ * pModule - pointer to module interface
+ *
+ * Outputs:
+ * Returns pointer to function table or NULL if not found
+ *----------------------------------------------------------------------------
+*/
+EAS_VOID_PTR EAS_CMEnumFXModules (EAS_INT module)
+{
+
+ if (module >= NUM_EFFECTS_MODULES)
+ return NULL;
+ return effectsModules[module];
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_CMEnumFXData()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * This function is used to find pointers to static memory allocations.
+ *
+ * Inputs:
+ * dataModule - enumerated module number
+ * pData - pointer to handle variable
+ *
+ * Outputs:
+ * Returns handle to data or NULL if not found
+ *----------------------------------------------------------------------------
+*/
+EAS_VOID_PTR EAS_CMEnumFXData (EAS_INT dataModule)
+{
+
+ if (dataModule >= NUM_EFFECTS_MODULES)
+ return NULL;
+ return effectsData[dataModule];
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_CMEnumOptModules()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * This function is used to find pointers to optional modules.
+ *
+ * Inputs:
+ * module - enumerated module number
+ *
+ * Outputs:
+ * returns pointer to function table or NULL if no module
+ *----------------------------------------------------------------------------
+*/
+EAS_VOID_PTR EAS_CMEnumOptModules (EAS_INT module)
+{
+
+ /* sanity check */
+ if (module >= NUM_OPTIONAL_MODULES)
+ return EAS_FALSE;
+ return optionalModules[module];
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_CMEnumOptData()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * This function is used to find pointers to static memory allocations.
+ *
+ * Inputs:
+ * dataModule - enumerated module number
+ *
+ * Outputs:
+ * Returns handle to data or NULL if not found
+ *----------------------------------------------------------------------------
+*/
+EAS_VOID_PTR EAS_CMEnumOptData (EAS_INT dataModule)
+{
+
+ if (dataModule >= NUM_OPTIONAL_MODULES)
+ return NULL;
+ return optionalData[dataModule];
+}
+
+
diff --git a/arm-fm-22k/host_src/eas_config.h b/arm-fm-22k/host_src/eas_config.h
index d16be4a..49c2ef2 100644
--- a/arm-fm-22k/host_src/eas_config.h
+++ b/arm-fm-22k/host_src/eas_config.h
@@ -1,22 +1,22 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_config.h
- *
- * Contents and purpose:
- * This header declares the Configuration Module interface (CM). The CM
- * is a module compiled external to the library that sets the configuration
- * for this build. It allows the library to find optional components and
- * links to static memory allocations (when used in a static configuration).
- *
- * NOTE: This module is not intended to be modified by the customer. It
- * needs to be included in the build process with the correct configuration
- * defines (see the library documentation for information on how to configure
- * the library).
- *
- * DO NOT MODIFY THIS FILE!
- *
- * Copyright 2005 Sonic Network Inc.
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_config.h
+ *
+ * Contents and purpose:
+ * This header declares the Configuration Module interface (CM). The CM
+ * is a module compiled external to the library that sets the configuration
+ * for this build. It allows the library to find optional components and
+ * links to static memory allocations (when used in a static configuration).
+ *
+ * NOTE: This module is not intended to be modified by the customer. It
+ * needs to be included in the build process with the correct configuration
+ * defines (see the library documentation for information on how to configure
+ * the library).
+ *
+ * DO NOT MODIFY THIS FILE!
+ *
+ * Copyright 2005 Sonic Network Inc.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -29,163 +29,163 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 82 $
- * $Date: 2006-07-10 11:45:19 -0700 (Mon, 10 Jul 2006) $
- *----------------------------------------------------------------------------
-*/
-
-// sentinel
-#ifndef _EAS_CONFIG_H
-#define _EAS_CONFIG_H
-
-#include "eas_types.h"
-
-/* list of enumerators for optional modules */
-typedef enum {
- EAS_CM_FILE_PARSERS = 1
-} E_CM_ENUM_MODULES;
-
-/* list of enumerators for module and memory pointers */
-typedef enum {
- EAS_CM_EAS_DATA = 1,
- EAS_CM_MIX_BUFFER,
- EAS_CM_SYNTH_DATA,
- EAS_CM_MIDI_DATA,
- EAS_CM_SMF_DATA,
- EAS_CM_XMF_DATA,
- EAS_CM_SMAF_DATA,
- EAS_CM_PCM_DATA,
- EAS_CM_MIDI_STREAM_DATA,
- EAS_CM_METRICS_DATA,
- EAS_CM_OTA_DATA,
- EAS_CM_IMELODY_DATA,
- EAS_CM_RTTTL_DATA,
- EAS_CM_WAVE_DATA,
- EAS_CM_CMF_DATA
-} E_CM_DATA_MODULES;
-
-typedef struct
-{
- int maxSMFStreams;
- void *pSMFData;
- void *pSMFStream;
-} S_EAS_SMF_PTRS;
-
-typedef struct
-{
- int maxSMAFStreams;
- void *pSMAFData;
- void *pSMAFStream;
-} S_EAS_SMAF_PTRS;
-
-/*----------------------------------------------------------------------------
- * EAS_CMStaticMemoryModel()
- *----------------------------------------------------------------------------
- * Purpose:
- * This function returns true if EAS has been configured for
- * a static memory model. There are some limitations in the
- * static memory model, see the documentation for more
- * information.
- *
- * Outputs:
- * returns EAS_TRUE if a module is found
- *----------------------------------------------------------------------------
-*/
-EAS_BOOL EAS_CMStaticMemoryModel (void);
-
-/*----------------------------------------------------------------------------
- * EAS_CMEnumModules()
- *----------------------------------------------------------------------------
- * Purpose:
- * This function is used to find pointers to optional modules.
- *
- * Inputs:
- * module - module number
- *
- * Outputs:
- * returns a pointer to the module function table or NULL if no module
- *----------------------------------------------------------------------------
-*/
-EAS_VOID_PTR EAS_CMEnumModules (EAS_INT module);
-
-/*----------------------------------------------------------------------------
- * EAS_CMEnumData()
- *----------------------------------------------------------------------------
- * Purpose:
- * This function is used to find pointers to static memory allocations.
- *
- * Inputs:
- * dataModule - enumerated module number
- *
- * Outputs:
- * Returns handle to data or NULL if not found
- *----------------------------------------------------------------------------
-*/
-EAS_VOID_PTR EAS_CMEnumData (EAS_INT dataModule);
-
-/*----------------------------------------------------------------------------
- * EAS_CMEnumFXModules()
- *----------------------------------------------------------------------------
- * Purpose:
- * This function is used to find pointers to optional effects modules.
- *
- * Inputs:
- * module - enumerated module number
- * pModule - pointer to module interface
- *
- * Outputs:
- * Returns pointer to function table or NULL if not found
- *----------------------------------------------------------------------------
-*/
-EAS_VOID_PTR EAS_CMEnumFXModules (EAS_INT module);
-
-/*----------------------------------------------------------------------------
- * EAS_CMEnumFXData()
- *----------------------------------------------------------------------------
- * Purpose:
- * This function is used to find pointers to static memory allocations.
- *
- * Inputs:
- * dataModule - enumerated module number
- * pData - pointer to handle variable
- *
- * Outputs:
- * Returns handle to data or NULL if not found
- *----------------------------------------------------------------------------
-*/
-EAS_VOID_PTR EAS_CMEnumFXData (EAS_INT dataModule);
-
-/*----------------------------------------------------------------------------
- * EAS_CMEnumOptModules()
- *----------------------------------------------------------------------------
- * Purpose:
- * This function is used to find pointers to optional modules.
- *
- * Inputs:
- * module - enumerated module number
- *
- * Outputs:
- * returns pointer to function table or NULL if no module
- *----------------------------------------------------------------------------
-*/
-EAS_VOID_PTR EAS_CMEnumOptModules (EAS_INT module);
-
-/*----------------------------------------------------------------------------
- * EAS_CMEnumOptData()
- *----------------------------------------------------------------------------
- * Purpose:
- * This function is used to find pointers to static memory allocations.
- *
- * Inputs:
- * dataModule - enumerated module number
- *
- * Outputs:
- * Returns handle to data or NULL if not found
- *----------------------------------------------------------------------------
-*/
-EAS_VOID_PTR EAS_CMEnumOptData (EAS_INT dataModule);
-
-#endif /* end _EAS_CONFIG_H */
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 82 $
+ * $Date: 2006-07-10 11:45:19 -0700 (Mon, 10 Jul 2006) $
+ *----------------------------------------------------------------------------
+*/
+
+// sentinel
+#ifndef _EAS_CONFIG_H
+#define _EAS_CONFIG_H
+
+#include "eas_types.h"
+
+/* list of enumerators for optional modules */
+typedef enum {
+ EAS_CM_FILE_PARSERS = 1
+} E_CM_ENUM_MODULES;
+
+/* list of enumerators for module and memory pointers */
+typedef enum {
+ EAS_CM_EAS_DATA = 1,
+ EAS_CM_MIX_BUFFER,
+ EAS_CM_SYNTH_DATA,
+ EAS_CM_MIDI_DATA,
+ EAS_CM_SMF_DATA,
+ EAS_CM_XMF_DATA,
+ EAS_CM_SMAF_DATA,
+ EAS_CM_PCM_DATA,
+ EAS_CM_MIDI_STREAM_DATA,
+ EAS_CM_METRICS_DATA,
+ EAS_CM_OTA_DATA,
+ EAS_CM_IMELODY_DATA,
+ EAS_CM_RTTTL_DATA,
+ EAS_CM_WAVE_DATA,
+ EAS_CM_CMF_DATA
+} E_CM_DATA_MODULES;
+
+typedef struct
+{
+ int maxSMFStreams;
+ void *pSMFData;
+ void *pSMFStream;
+} S_EAS_SMF_PTRS;
+
+typedef struct
+{
+ int maxSMAFStreams;
+ void *pSMAFData;
+ void *pSMAFStream;
+} S_EAS_SMAF_PTRS;
+
+/*----------------------------------------------------------------------------
+ * EAS_CMStaticMemoryModel()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * This function returns true if EAS has been configured for
+ * a static memory model. There are some limitations in the
+ * static memory model, see the documentation for more
+ * information.
+ *
+ * Outputs:
+ * returns EAS_TRUE if a module is found
+ *----------------------------------------------------------------------------
+*/
+EAS_BOOL EAS_CMStaticMemoryModel (void);
+
+/*----------------------------------------------------------------------------
+ * EAS_CMEnumModules()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * This function is used to find pointers to optional modules.
+ *
+ * Inputs:
+ * module - module number
+ *
+ * Outputs:
+ * returns a pointer to the module function table or NULL if no module
+ *----------------------------------------------------------------------------
+*/
+EAS_VOID_PTR EAS_CMEnumModules (EAS_INT module);
+
+/*----------------------------------------------------------------------------
+ * EAS_CMEnumData()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * This function is used to find pointers to static memory allocations.
+ *
+ * Inputs:
+ * dataModule - enumerated module number
+ *
+ * Outputs:
+ * Returns handle to data or NULL if not found
+ *----------------------------------------------------------------------------
+*/
+EAS_VOID_PTR EAS_CMEnumData (EAS_INT dataModule);
+
+/*----------------------------------------------------------------------------
+ * EAS_CMEnumFXModules()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * This function is used to find pointers to optional effects modules.
+ *
+ * Inputs:
+ * module - enumerated module number
+ * pModule - pointer to module interface
+ *
+ * Outputs:
+ * Returns pointer to function table or NULL if not found
+ *----------------------------------------------------------------------------
+*/
+EAS_VOID_PTR EAS_CMEnumFXModules (EAS_INT module);
+
+/*----------------------------------------------------------------------------
+ * EAS_CMEnumFXData()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * This function is used to find pointers to static memory allocations.
+ *
+ * Inputs:
+ * dataModule - enumerated module number
+ * pData - pointer to handle variable
+ *
+ * Outputs:
+ * Returns handle to data or NULL if not found
+ *----------------------------------------------------------------------------
+*/
+EAS_VOID_PTR EAS_CMEnumFXData (EAS_INT dataModule);
+
+/*----------------------------------------------------------------------------
+ * EAS_CMEnumOptModules()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * This function is used to find pointers to optional modules.
+ *
+ * Inputs:
+ * module - enumerated module number
+ *
+ * Outputs:
+ * returns pointer to function table or NULL if no module
+ *----------------------------------------------------------------------------
+*/
+EAS_VOID_PTR EAS_CMEnumOptModules (EAS_INT module);
+
+/*----------------------------------------------------------------------------
+ * EAS_CMEnumOptData()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * This function is used to find pointers to static memory allocations.
+ *
+ * Inputs:
+ * dataModule - enumerated module number
+ *
+ * Outputs:
+ * Returns handle to data or NULL if not found
+ *----------------------------------------------------------------------------
+*/
+EAS_VOID_PTR EAS_CMEnumOptData (EAS_INT dataModule);
+
+#endif /* end _EAS_CONFIG_H */
diff --git a/arm-fm-22k/host_src/eas_debugmsgs.h b/arm-fm-22k/host_src/eas_debugmsgs.h
index 436875b..de60259 100644
--- a/arm-fm-22k/host_src/eas_debugmsgs.h
+++ b/arm-fm-22k/host_src/eas_debugmsgs.h
@@ -1,43 +1,43 @@
-/* Auto-generated from source file: eas_chorusdata.c */
-/* Auto-generated from source file: eas_imelodydata.c */
-/* Auto-generated from source file: eas_mididata.c */
-/* Auto-generated from source file: eas_pan.c */
-/* Auto-generated from source file: eas_wavefiledata.c */
-/* Auto-generated from source file: eas_voicemgt.c */
-/* Auto-generated from source file: eas_ota.c */
-/* Auto-generated from source file: eas_mixbuf.c */
-/* Auto-generated from source file: eas_fmsndlib.c */
-/* Auto-generated from source file: eas_rtttl.c */
-/* Auto-generated from source file: eas_reverb.c */
-/* Auto-generated from source file: eas_fmsynth.c */
-/* Auto-generated from source file: eas_pcmdata.c */
-/* Auto-generated from source file: eas_chorus.c */
-/* Auto-generated from source file: eas_math.c */
-/* Auto-generated from source file: eas_fmengine.c */
-/* Auto-generated from source file: eas_smfdata.c */
-/* Auto-generated from source file: eas_fmtables.c */
-/* Auto-generated from source file: eas_imelody.c */
-/* Auto-generated from source file: eas_public.c */
-/* Auto-generated from source file: eas_rtttldata.c */
-/* Auto-generated from source file: eas_reverbdata.c */
-/* Auto-generated from source file: eas_imaadpcm.c */
-{ 0x2380b977, 0x00000006, "eas_imaadpcm.c[305]: IMADecoderLocate: Time=%d, samples=%d\n" },
-{ 0x2380b977, 0x00000007, "eas_imaadpcm.c[328]: IMADecoderLocate: Looped sample, numBlocks=%d, samplesPerLoop=%d, samplesInLastBlock=%d, samples=%d\n" },
-{ 0x2380b977, 0x00000008, "eas_imaadpcm.c[335]: IMADecoderLocate: Byte location in audio = %d\n" },
-{ 0x2380b977, 0x00000009, "eas_imaadpcm.c[345]: IMADecoderLocate: bytesLeft = %d\n" },
-/* Auto-generated from source file: eas_midi.c */
-/* Auto-generated from source file: eas_otadata.c */
-/* Auto-generated from source file: eas_ima_tables.c */
-/* Auto-generated from source file: eas_data.c */
-/* Auto-generated from source file: eas_pcm.c */
-/* Auto-generated from source file: eas_mixer.c */
-/* Auto-generated from source file: eas_wavefile.c */
-/* Auto-generated from source file: eas_smf.c */
-/* Auto-generated from source file: eas_wave.c */
-/* Auto-generated from source file: eas_hostmm.c */
-{ 0x1a54b6e8, 0x00000001, "eas_hostmm.c[586]: Vibrate state: %d\n" },
-{ 0x1a54b6e8, 0x00000002, "eas_hostmm.c[601]: LED state: %d\n" },
-{ 0x1a54b6e8, 0x00000003, "eas_hostmm.c[616]: Backlight state: %d\n" },
-/* Auto-generated from source file: eas_config.c */
-/* Auto-generated from source file: eas_main.c */
-{ 0xe624f4d9, 0x00000005, "eas_main.c[106]: Play length: %d.%03d (secs)\n" },
+/* Auto-generated from source file: eas_chorusdata.c */
+/* Auto-generated from source file: eas_imelodydata.c */
+/* Auto-generated from source file: eas_mididata.c */
+/* Auto-generated from source file: eas_pan.c */
+/* Auto-generated from source file: eas_wavefiledata.c */
+/* Auto-generated from source file: eas_voicemgt.c */
+/* Auto-generated from source file: eas_ota.c */
+/* Auto-generated from source file: eas_mixbuf.c */
+/* Auto-generated from source file: eas_fmsndlib.c */
+/* Auto-generated from source file: eas_rtttl.c */
+/* Auto-generated from source file: eas_reverb.c */
+/* Auto-generated from source file: eas_fmsynth.c */
+/* Auto-generated from source file: eas_pcmdata.c */
+/* Auto-generated from source file: eas_chorus.c */
+/* Auto-generated from source file: eas_math.c */
+/* Auto-generated from source file: eas_fmengine.c */
+/* Auto-generated from source file: eas_smfdata.c */
+/* Auto-generated from source file: eas_fmtables.c */
+/* Auto-generated from source file: eas_imelody.c */
+/* Auto-generated from source file: eas_public.c */
+/* Auto-generated from source file: eas_rtttldata.c */
+/* Auto-generated from source file: eas_reverbdata.c */
+/* Auto-generated from source file: eas_imaadpcm.c */
+{ 0x2380b977, 0x00000006, "eas_imaadpcm.c[305]: IMADecoderLocate: Time=%d, samples=%d\n" },
+{ 0x2380b977, 0x00000007, "eas_imaadpcm.c[328]: IMADecoderLocate: Looped sample, numBlocks=%d, samplesPerLoop=%d, samplesInLastBlock=%d, samples=%d\n" },
+{ 0x2380b977, 0x00000008, "eas_imaadpcm.c[335]: IMADecoderLocate: Byte location in audio = %d\n" },
+{ 0x2380b977, 0x00000009, "eas_imaadpcm.c[345]: IMADecoderLocate: bytesLeft = %d\n" },
+/* Auto-generated from source file: eas_midi.c */
+/* Auto-generated from source file: eas_otadata.c */
+/* Auto-generated from source file: eas_ima_tables.c */
+/* Auto-generated from source file: eas_data.c */
+/* Auto-generated from source file: eas_pcm.c */
+/* Auto-generated from source file: eas_mixer.c */
+/* Auto-generated from source file: eas_wavefile.c */
+/* Auto-generated from source file: eas_smf.c */
+/* Auto-generated from source file: eas_wave.c */
+/* Auto-generated from source file: eas_hostmm.c */
+{ 0x1a54b6e8, 0x00000001, "eas_hostmm.c[586]: Vibrate state: %d\n" },
+{ 0x1a54b6e8, 0x00000002, "eas_hostmm.c[601]: LED state: %d\n" },
+{ 0x1a54b6e8, 0x00000003, "eas_hostmm.c[616]: Backlight state: %d\n" },
+/* Auto-generated from source file: eas_config.c */
+/* Auto-generated from source file: eas_main.c */
+{ 0xe624f4d9, 0x00000005, "eas_main.c[106]: Play length: %d.%03d (secs)\n" },
diff --git a/arm-fm-22k/host_src/eas_host.h b/arm-fm-22k/host_src/eas_host.h
index 0db0e30..b356982 100644
--- a/arm-fm-22k/host_src/eas_host.h
+++ b/arm-fm-22k/host_src/eas_host.h
@@ -1,16 +1,16 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_host.h
- *
- * Contents and purpose:
- * This header defines the host wrapper functions for stdio, stdlib, etc.
- * The host application must provide an abstraction layer for these functions
- * to support certain features, such as SMAF and SMF-1 conversion.
- *
- * DO NOT MODIFY THIS FILE!
- *
- * Copyright 2005 Sonic Network Inc.
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_host.h
+ *
+ * Contents and purpose:
+ * This header defines the host wrapper functions for stdio, stdlib, etc.
+ * The host application must provide an abstraction layer for these functions
+ * to support certain features, such as SMAF and SMF-1 conversion.
+ *
+ * DO NOT MODIFY THIS FILE!
+ *
+ * Copyright 2005 Sonic Network Inc.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -23,61 +23,61 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 82 $
- * $Date: 2006-07-10 11:45:19 -0700 (Mon, 10 Jul 2006) $
- *----------------------------------------------------------------------------
-*/
-
-// sentinel
-#ifndef _EAS_HOST_H
-#define _EAS_HOST_H
-
-#include "eas_types.h"
-
-/* for C++ linkage */
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* initialization and shutdown routines */
-extern EAS_RESULT EAS_HWInit(EAS_HW_DATA_HANDLE *hwInstData);
-extern EAS_RESULT EAS_HWShutdown(EAS_HW_DATA_HANDLE hwInstData);
-
-/* memory functions */
-extern void *EAS_HWMemSet(void *s, int c, EAS_I32 n);
-extern void *EAS_HWMemCpy(void *s1, const void *s2, EAS_I32 n);
-extern EAS_I32 EAS_HWMemCmp(const void *s1, const void *s2, EAS_I32 n);
-
-/* memory allocation */
-extern void *EAS_HWMalloc(EAS_HW_DATA_HANDLE hwInstData, EAS_I32 size);
-extern void EAS_HWFree(EAS_HW_DATA_HANDLE hwInstData, void *p);
-
-/* file I/O */
-extern EAS_RESULT EAS_HWOpenFile(EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_LOCATOR locator, EAS_FILE_HANDLE *pFile, EAS_FILE_MODE mode);
-extern EAS_RESULT EAS_HWReadFile(EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, void *pBuffer, EAS_I32 n, EAS_I32 *pBytesRead);
-extern EAS_RESULT EAS_HWGetByte(EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, void *p);
-extern EAS_RESULT EAS_HWGetWord (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, void *p, EAS_BOOL msbFirst);
-extern EAS_RESULT EAS_HWGetDWord (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, void *p, EAS_BOOL msbFirst);
-extern EAS_RESULT EAS_HWFilePos (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, EAS_I32 *pPosition);
-extern EAS_RESULT EAS_HWFileSeek (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, EAS_I32 position);
-extern EAS_RESULT EAS_HWFileSeekOfs (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, EAS_I32 position);
-extern EAS_RESULT EAS_HWFileLength (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, EAS_I32 *pLength);
-extern EAS_RESULT EAS_HWDupHandle (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, EAS_FILE_HANDLE* pFile);
-extern EAS_RESULT EAS_HWCloseFile (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file);
-
-/* vibrate, LED, and backlight functions */
-extern EAS_RESULT EAS_HWVibrate(EAS_HW_DATA_HANDLE hwInstData, EAS_BOOL state);
-extern EAS_RESULT EAS_HWLED(EAS_HW_DATA_HANDLE hwInstData, EAS_BOOL state);
-extern EAS_RESULT EAS_HWBackLight(EAS_HW_DATA_HANDLE hwInstData, EAS_BOOL state);
-
-#ifdef __cplusplus
-} /* end extern "C" */
-#endif
-
-
-/* host yield function */
-extern EAS_BOOL EAS_HWYield(EAS_HW_DATA_HANDLE hwInstData);
-#endif /* end _EAS_HOST_H */
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 82 $
+ * $Date: 2006-07-10 11:45:19 -0700 (Mon, 10 Jul 2006) $
+ *----------------------------------------------------------------------------
+*/
+
+// sentinel
+#ifndef _EAS_HOST_H
+#define _EAS_HOST_H
+
+#include "eas_types.h"
+
+/* for C++ linkage */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* initialization and shutdown routines */
+extern EAS_RESULT EAS_HWInit(EAS_HW_DATA_HANDLE *hwInstData);
+extern EAS_RESULT EAS_HWShutdown(EAS_HW_DATA_HANDLE hwInstData);
+
+/* memory functions */
+extern void *EAS_HWMemSet(void *s, int c, EAS_I32 n);
+extern void *EAS_HWMemCpy(void *s1, const void *s2, EAS_I32 n);
+extern EAS_I32 EAS_HWMemCmp(const void *s1, const void *s2, EAS_I32 n);
+
+/* memory allocation */
+extern void *EAS_HWMalloc(EAS_HW_DATA_HANDLE hwInstData, EAS_I32 size);
+extern void EAS_HWFree(EAS_HW_DATA_HANDLE hwInstData, void *p);
+
+/* file I/O */
+extern EAS_RESULT EAS_HWOpenFile(EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_LOCATOR locator, EAS_FILE_HANDLE *pFile, EAS_FILE_MODE mode);
+extern EAS_RESULT EAS_HWReadFile(EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, void *pBuffer, EAS_I32 n, EAS_I32 *pBytesRead);
+extern EAS_RESULT EAS_HWGetByte(EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, void *p);
+extern EAS_RESULT EAS_HWGetWord (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, void *p, EAS_BOOL msbFirst);
+extern EAS_RESULT EAS_HWGetDWord (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, void *p, EAS_BOOL msbFirst);
+extern EAS_RESULT EAS_HWFilePos (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, EAS_I32 *pPosition);
+extern EAS_RESULT EAS_HWFileSeek (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, EAS_I32 position);
+extern EAS_RESULT EAS_HWFileSeekOfs (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, EAS_I32 position);
+extern EAS_RESULT EAS_HWFileLength (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, EAS_I32 *pLength);
+extern EAS_RESULT EAS_HWDupHandle (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, EAS_FILE_HANDLE* pFile);
+extern EAS_RESULT EAS_HWCloseFile (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file);
+
+/* vibrate, LED, and backlight functions */
+extern EAS_RESULT EAS_HWVibrate(EAS_HW_DATA_HANDLE hwInstData, EAS_BOOL state);
+extern EAS_RESULT EAS_HWLED(EAS_HW_DATA_HANDLE hwInstData, EAS_BOOL state);
+extern EAS_RESULT EAS_HWBackLight(EAS_HW_DATA_HANDLE hwInstData, EAS_BOOL state);
+
+#ifdef __cplusplus
+} /* end extern "C" */
+#endif
+
+
+/* host yield function */
+extern EAS_BOOL EAS_HWYield(EAS_HW_DATA_HANDLE hwInstData);
+#endif /* end _EAS_HOST_H */
diff --git a/arm-fm-22k/host_src/eas_hostmm.c b/arm-fm-22k/host_src/eas_hostmm.c
index 7e58838..df24cf2 100644
--- a/arm-fm-22k/host_src/eas_hostmm.c
+++ b/arm-fm-22k/host_src/eas_hostmm.c
@@ -1,33 +1,33 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_hostmm.c
- *
- * Contents and purpose:
- * This file contains the host wrapper functions for stdio, stdlib, etc.
- * This is a sample version that maps the requested files to an
- * allocated memory block and uses in-memory pointers to replace
- * file system calls. The file locator (EAS_FILE_LOCATOR) handle passed
- * HWOpenFile is the same one that is passed to EAS_OpenFile. If your
- * system stores data in fixed locations (such as flash) instead of
- * using a file system, you can use the locator handle to point to
- * your memory. You will need a way of knowing the length of the
- * data stored at that location in order to respond correctly in the
- * HW_FileLength function.
- *
- * Modify this file to suit the needs of your particular system.
- *
- * EAS_MAX_FILE_HANDLES sets the maximum number of MIDI streams within
- * a MIDI type 1 file that can be played.
- *
- * EAS_HW_FILE is a structure to support the file I/O functions. It
- * comprises the base memory pointer, the file read pointer, and
- * the dup flag, which when sets, indicates that the file handle has
- * been duplicated. If your system uses in-memory resources, you
- * can eliminate the duplicate handle logic, and simply copy the
- * base memory pointer and file read pointer to the duplicate handle.
- *
- * Copyright 2005 Sonic Network Inc.
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_hostmm.c
+ *
+ * Contents and purpose:
+ * This file contains the host wrapper functions for stdio, stdlib, etc.
+ * This is a sample version that maps the requested files to an
+ * allocated memory block and uses in-memory pointers to replace
+ * file system calls. The file locator (EAS_FILE_LOCATOR) handle passed
+ * HWOpenFile is the same one that is passed to EAS_OpenFile. If your
+ * system stores data in fixed locations (such as flash) instead of
+ * using a file system, you can use the locator handle to point to
+ * your memory. You will need a way of knowing the length of the
+ * data stored at that location in order to respond correctly in the
+ * HW_FileLength function.
+ *
+ * Modify this file to suit the needs of your particular system.
+ *
+ * EAS_MAX_FILE_HANDLES sets the maximum number of MIDI streams within
+ * a MIDI type 1 file that can be played.
+ *
+ * EAS_HW_FILE is a structure to support the file I/O functions. It
+ * comprises the base memory pointer, the file read pointer, and
+ * the dup flag, which when sets, indicates that the file handle has
+ * been duplicated. If your system uses in-memory resources, you
+ * can eliminate the duplicate handle logic, and simply copy the
+ * base memory pointer and file read pointer to the duplicate handle.
+ *
+ * Copyright 2005 Sonic Network Inc.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -40,621 +40,621 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 795 $
- * $Date: 2007-08-01 00:14:45 -0700 (Wed, 01 Aug 2007) $
- *----------------------------------------------------------------------------
-*/
-
-#ifdef _lint
-#include "lint_stdlib.h"
-#else
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#endif
-
-#include "eas_host.h"
-
-/* Only for debugging LED, vibrate, and backlight functions */
-#include "eas_report.h"
-
-/* this module requires dynamic memory support */
-#ifdef _STATIC_MEMORY
-#error "eas_hostmm.c requires the dynamic memory model!\n"
-#endif
-
-#ifndef EAS_MAX_FILE_HANDLES
-#define EAS_MAX_FILE_HANDLES 32
-#endif
-
-/*
- * this structure and the related function are here
- * to support the ability to create duplicate handles
- * and buffering it in memory. If your system uses
- * in-memory resources, you can eliminate the calls
- * to malloc and free, the dup flag, and simply track
- * the file size and read position.
- */
-typedef struct eas_hw_file_tag
-{
- EAS_I32 fileSize;
- EAS_I32 filePos;
- EAS_BOOL dup;
- EAS_U8 *buffer;
-} EAS_HW_FILE;
-
-typedef struct eas_hw_inst_data_tag
-{
- EAS_HW_FILE files[EAS_MAX_FILE_HANDLES];
-} EAS_HW_INST_DATA;
-
-/*----------------------------------------------------------------------------
- * EAS_HWInit
- *
- * Initialize host wrapper interface
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT EAS_HWInit (EAS_HW_DATA_HANDLE *pHWInstData)
-{
-
- /* need to track file opens for duplicate handles */
- *pHWInstData = malloc(sizeof(EAS_HW_INST_DATA));
- if (!(*pHWInstData))
- return EAS_ERROR_MALLOC_FAILED;
-
- EAS_HWMemSet(*pHWInstData, 0, sizeof(EAS_HW_INST_DATA));
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * EAS_HWShutdown
- *
- * Shut down host wrapper interface
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT EAS_HWShutdown (EAS_HW_DATA_HANDLE hwInstData)
-{
-
- free(hwInstData);
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- *
- * EAS_HWMalloc
- *
- * Allocates dynamic memory
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, hwInstData) hwInstData available for customer use */
-void *EAS_HWMalloc (EAS_HW_DATA_HANDLE hwInstData, EAS_I32 size)
-{
- return malloc((size_t) size);
-}
-
-/*----------------------------------------------------------------------------
- *
- * EAS_HWFree
- *
- * Frees dynamic memory
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, hwInstData) hwInstData available for customer use */
-void EAS_HWFree (EAS_HW_DATA_HANDLE hwInstData, void *p)
-{
- free(p);
-}
-
-/*----------------------------------------------------------------------------
- *
- * EAS_HWMemCpy
- *
- * Copy memory wrapper
- *
- *----------------------------------------------------------------------------
-*/
-void *EAS_HWMemCpy (void *dest, const void *src, EAS_I32 amount)
-{
- return memcpy(dest, src, (size_t) amount);
-}
-
-/*----------------------------------------------------------------------------
- *
- * EAS_HWMemSet
- *
- * Set memory wrapper
- *
- *----------------------------------------------------------------------------
-*/
-void *EAS_HWMemSet (void *dest, int val, EAS_I32 amount)
-{
- return memset(dest, val, (size_t) amount);
-}
-
-/*----------------------------------------------------------------------------
- *
- * EAS_HWMemCmp
- *
- * Compare memory wrapper
- *
- *----------------------------------------------------------------------------
-*/
-EAS_I32 EAS_HWMemCmp (const void *s1, const void *s2, EAS_I32 amount)
-{
- return (EAS_I32) memcmp(s1, s2, (size_t) amount);
-}
-
-/*----------------------------------------------------------------------------
- *
- * EAS_HWOpenFile
- *
- * Open a file for read or write
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT EAS_HWOpenFile (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_LOCATOR locator, EAS_FILE_HANDLE *pFile, EAS_FILE_MODE mode)
-{
- EAS_HW_FILE *file;
- FILE *ioFile;
- int i, temp;
-
- /* set return value to NULL */
- *pFile = NULL;
-
- /* only support read mode at this time */
- if (mode != EAS_FILE_READ)
- return EAS_ERROR_INVALID_FILE_MODE;
-
- /* find an empty entry in the file table */
- file = hwInstData->files;
- for (i = 0; i < EAS_MAX_FILE_HANDLES; i++)
- {
- /* is this slot being used? */
- if (file->buffer == NULL)
- {
- /* open the file */
- if ((ioFile = fopen(locator,"rb")) == NULL)
- return EAS_ERROR_FILE_OPEN_FAILED;
-
- /* determine the file size */
- if (fseek(ioFile, 0L, SEEK_END) != 0)
- return EAS_ERROR_FILE_LENGTH;
- if ((file->fileSize = ftell(ioFile)) == -1L)
- return EAS_ERROR_FILE_LENGTH;
- if (fseek(ioFile, 0L, SEEK_SET) != 0)
- return EAS_ERROR_FILE_LENGTH;
-
- /* allocate a buffer */
- file->buffer = EAS_HWMalloc(hwInstData, file->fileSize);
- if (file->buffer == NULL)
- {
- fclose(ioFile);
- return EAS_ERROR_MALLOC_FAILED;
- }
-
- /* read the file into memory */
- temp = (int) fread(file->buffer, (size_t) file->fileSize, 1, ioFile);
-
- /* close the file - don't need it any more */
- fclose(ioFile);
-
- /* check for error reading file */
- if (temp != 1)
- return EAS_ERROR_FILE_READ_FAILED;
-
- /* initialize some values */
- file->filePos = 0;
- file->dup = EAS_FALSE;
-
- *pFile = file;
- return EAS_SUCCESS;
- }
- file++;
- }
-
- /* too many open files */
- return EAS_ERROR_MAX_FILES_OPEN;
-}
-
-/*----------------------------------------------------------------------------
- *
- * EAS_HWReadFile
- *
- * Read data from a file
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, hwInstData) hwInstData available for customer use */
-EAS_RESULT EAS_HWReadFile (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, void *pBuffer, EAS_I32 n, EAS_I32 *pBytesRead)
-{
- EAS_I32 count;
-
- /* make sure we have a valid handle */
- if (file->buffer == NULL)
- return EAS_ERROR_INVALID_HANDLE;
-
- /* calculate the bytes to read */
- count = file->fileSize - file->filePos;
- if (n < count)
- count = n;
-
- /* copy the data to the requested location, and advance the pointer */
- if (count)
- EAS_HWMemCpy(pBuffer, &file->buffer[file->filePos], count);
- file->filePos += count;
- *pBytesRead = count;
-
- /* were n bytes read? */
- if (count!= n)
- return EAS_EOF;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- *
- * EAS_HWGetByte
- *
- * Read a byte from a file
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, hwInstData) hwInstData available for customer use */
-EAS_RESULT EAS_HWGetByte (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, void *p)
-{
-
- /* make sure we have a valid handle */
- if (file->buffer == NULL)
- return EAS_ERROR_INVALID_HANDLE;
-
- /* check for end of file */
- if (file->filePos >= file->fileSize)
- {
- *((EAS_U8*) p) = 0;
- return EAS_EOF;
- }
-
- /* get a character from the buffer */
- *((EAS_U8*) p) = file->buffer[file->filePos++];
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- *
- * EAS_HWGetWord
- *
- * Returns the current location in the file
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, hwInstData) hwInstData available for customer use */
-EAS_RESULT EAS_HWGetWord (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, void *p, EAS_BOOL msbFirst)
-{
- EAS_RESULT result;
- EAS_U8 c1, c2;
-
- /* read 2 bytes from the file */
- if ((result = EAS_HWGetByte(hwInstData, file, &c1)) != EAS_SUCCESS)
- return result;
- if ((result = EAS_HWGetByte(hwInstData, file, &c2)) != EAS_SUCCESS)
- return result;
-
- /* order them as requested */
- if (msbFirst)
- *((EAS_U16*) p) = ((EAS_U16) c1 << 8) | c2;
- else
- *((EAS_U16*) p) = ((EAS_U16) c2 << 8) | c1;
-
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- *
- * EAS_HWGetDWord
- *
- * Returns the current location in the file
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, hwInstData) hwInstData available for customer use */
-EAS_RESULT EAS_HWGetDWord (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, void *p, EAS_BOOL msbFirst)
-{
- EAS_RESULT result;
- EAS_U8 c1, c2,c3,c4;
-
- /* read 4 bytes from the file */
- if ((result = EAS_HWGetByte(hwInstData, file, &c1)) != EAS_SUCCESS)
- return result;
- if ((result = EAS_HWGetByte(hwInstData, file, &c2)) != EAS_SUCCESS)
- return result;
- if ((result = EAS_HWGetByte(hwInstData, file, &c3)) != EAS_SUCCESS)
- return result;
- if ((result = EAS_HWGetByte(hwInstData, file, &c4)) != EAS_SUCCESS)
- return result;
-
- /* order them as requested */
- if (msbFirst)
- *((EAS_U32*) p) = ((EAS_U32) c1 << 24) | ((EAS_U32) c2 << 16) | ((EAS_U32) c3 << 8) | c4;
- else
- *((EAS_U32*) p)= ((EAS_U32) c4 << 24) | ((EAS_U32) c3 << 16) | ((EAS_U32) c2 << 8) | c1;
-
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- *
- * EAS_HWFilePos
- *
- * Returns the current location in the file
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, hwInstData) hwInstData available for customer use */
-EAS_RESULT EAS_HWFilePos (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, EAS_I32 *pPosition)
-{
-
- /* make sure we have a valid handle */
- if (file->buffer == NULL)
- return EAS_ERROR_INVALID_HANDLE;
-
- *pPosition = file->filePos;
- return EAS_SUCCESS;
-} /* end EAS_HWFilePos */
-
-/*----------------------------------------------------------------------------
- *
- * EAS_HWFileSeek
- *
- * Seek to a specific location in the file
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, hwInstData) hwInstData available for customer use */
-EAS_RESULT EAS_HWFileSeek (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, EAS_I32 position)
-{
-
- /* make sure we have a valid handle */
- if (file->buffer == NULL)
- return EAS_ERROR_INVALID_HANDLE;
-
- /* validate new position */
- if ((position < 0) || (position > file->fileSize))
- return EAS_ERROR_FILE_SEEK;
-
- /* save new position */
- file->filePos = position;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- *
- * EAS_HWFileSeekOfs
- *
- * Seek forward or back relative to the current position
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, hwInstData) hwInstData available for customer use */
-EAS_RESULT EAS_HWFileSeekOfs (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, EAS_I32 position)
-{
-
- /* make sure we have a valid handle */
- if (file->buffer == NULL)
- return EAS_ERROR_INVALID_HANDLE;
-
- /* determine the file position */
- position += file->filePos;
- if ((position < 0) || (position > file->fileSize))
- return EAS_ERROR_FILE_SEEK;
-
- /* save new position */
- file->filePos = position;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- *
- * EAS_HWFileLength
- *
- * Return the file length
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, hwInstData) hwInstData available for customer use */
-EAS_RESULT EAS_HWFileLength (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, EAS_I32 *pLength)
-{
-
- /* make sure we have a valid handle */
- if (file->buffer == NULL)
- return EAS_ERROR_INVALID_HANDLE;
-
- *pLength = file->fileSize;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- *
- * EAS_HWDupHandle
- *
- * Duplicate a file handle
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT EAS_HWDupHandle (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, EAS_FILE_HANDLE *pDupFile)
-{
- EAS_HW_FILE *dupFile;
- int i;
-
- /* make sure we have a valid handle */
- if (file->buffer == NULL)
- return EAS_ERROR_INVALID_HANDLE;
-
- /* find an empty entry in the file table */
- dupFile = hwInstData->files;
- for (i = 0; i < EAS_MAX_FILE_HANDLES; i++)
- {
- /* is this slot being used? */
- if (dupFile->buffer == NULL)
- {
-
- /* copy info from the handle to be duplicated */
- dupFile->filePos = file->filePos;
- dupFile->fileSize = file->fileSize;
- dupFile->buffer = file->buffer;
-
- /* set the duplicate handle flag */
- dupFile->dup = file->dup = EAS_TRUE;
-
- *pDupFile = dupFile;
- return EAS_SUCCESS;
- }
- dupFile++;
- }
-
- /* too many open files */
- return EAS_ERROR_MAX_FILES_OPEN;
-}
-
-/*----------------------------------------------------------------------------
- *
- * EAS_HWClose
- *
- * Wrapper for fclose function
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT EAS_HWCloseFile (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file1)
-{
- EAS_HW_FILE *file2,*dupFile;
- int i;
-
-
- /* make sure we have a valid handle */
- if (file1->buffer == NULL)
- return EAS_ERROR_INVALID_HANDLE;
-
- /* check for duplicate handle */
- if (file1->dup)
- {
- dupFile = NULL;
- file2 = hwInstData->files;
- for (i = 0; i < EAS_MAX_FILE_HANDLES; i++)
- {
- /* check for duplicate */
- if ((file1 != file2) && (file2->buffer == file1->buffer))
- {
- /* is there more than one duplicate? */
- if (dupFile != NULL)
- {
- /* clear this entry and return */
- file1->buffer = NULL;
- return EAS_SUCCESS;
- }
-
- /* this is the first duplicate found */
- else
- dupFile = file2;
- }
- file2++;
- }
-
- /* there is only one duplicate, clear the dup flag */
- if (dupFile)
- dupFile->dup = EAS_FALSE;
- else
- /* if we get here, there's a serious problem */
- return EAS_ERROR_HANDLE_INTEGRITY;
-
- /* clear this entry and return */
- file1->buffer = NULL;
- return EAS_SUCCESS;
- }
-
- /* no duplicates -free the buffer */
- EAS_HWFree(hwInstData, file1->buffer);
-
- /* clear this entry and return */
- file1->buffer = NULL;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- *
- * EAS_HWVibrate
- *
- * Turn on/off vibrate function
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, hwInstData) hwInstData available for customer use */
-EAS_RESULT EAS_HWVibrate (EAS_HW_DATA_HANDLE hwInstData, EAS_BOOL state)
-{
- EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x1a54b6e8, 0x00000001 , state);
- return EAS_SUCCESS;
-} /* end EAS_HWVibrate */
-
-/*----------------------------------------------------------------------------
- *
- * EAS_HWLED
- *
- * Turn on/off LED
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, hwInstData) hwInstData available for customer use */
-EAS_RESULT EAS_HWLED (EAS_HW_DATA_HANDLE hwInstData, EAS_BOOL state)
-{
- EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x1a54b6e8, 0x00000002 , state);
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- *
- * EAS_HWBackLight
- *
- * Turn on/off backlight
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, hwInstData) hwInstData available for customer use */
-EAS_RESULT EAS_HWBackLight (EAS_HW_DATA_HANDLE hwInstData, EAS_BOOL state)
-{
- EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x1a54b6e8, 0x00000003 , state);
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- *
- * EAS_HWYield
- *
- * This function is called periodically by the EAS library to give the
- * host an opportunity to allow other tasks to run. There are two ways to
- * use this call:
- *
- * If you have a multi-tasking OS, you can call the yield function in the
- * OS to allow other tasks to run. In this case, return EAS_FALSE to tell
- * the EAS library to continue processing when control returns from this
- * function.
- *
- * If tasks run in a single thread by sequential function calls (sometimes
- * call a "commutator loop"), return EAS_TRUE to cause the EAS Library to
- * return to the caller. Be sure to check the number of bytes rendered
- * before passing the audio buffer to the codec - it may not be filled.
- * The next call to EAS_Render will continue processing until the buffer
- * has been filled.
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, hwInstData) hwInstData available for customer use */
-EAS_BOOL EAS_HWYield (EAS_HW_DATA_HANDLE hwInstData)
-{
- /* put your code here */
- return EAS_FALSE;
-}
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 795 $
+ * $Date: 2007-08-01 00:14:45 -0700 (Wed, 01 Aug 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+#ifdef _lint
+#include "lint_stdlib.h"
+#else
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#endif
+
+#include "eas_host.h"
+
+/* Only for debugging LED, vibrate, and backlight functions */
+#include "eas_report.h"
+
+/* this module requires dynamic memory support */
+#ifdef _STATIC_MEMORY
+#error "eas_hostmm.c requires the dynamic memory model!\n"
+#endif
+
+#ifndef EAS_MAX_FILE_HANDLES
+#define EAS_MAX_FILE_HANDLES 32
+#endif
+
+/*
+ * this structure and the related function are here
+ * to support the ability to create duplicate handles
+ * and buffering it in memory. If your system uses
+ * in-memory resources, you can eliminate the calls
+ * to malloc and free, the dup flag, and simply track
+ * the file size and read position.
+ */
+typedef struct eas_hw_file_tag
+{
+ EAS_I32 fileSize;
+ EAS_I32 filePos;
+ EAS_BOOL dup;
+ EAS_U8 *buffer;
+} EAS_HW_FILE;
+
+typedef struct eas_hw_inst_data_tag
+{
+ EAS_HW_FILE files[EAS_MAX_FILE_HANDLES];
+} EAS_HW_INST_DATA;
+
+/*----------------------------------------------------------------------------
+ * EAS_HWInit
+ *
+ * Initialize host wrapper interface
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_HWInit (EAS_HW_DATA_HANDLE *pHWInstData)
+{
+
+ /* need to track file opens for duplicate handles */
+ *pHWInstData = malloc(sizeof(EAS_HW_INST_DATA));
+ if (!(*pHWInstData))
+ return EAS_ERROR_MALLOC_FAILED;
+
+ EAS_HWMemSet(*pHWInstData, 0, sizeof(EAS_HW_INST_DATA));
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_HWShutdown
+ *
+ * Shut down host wrapper interface
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_HWShutdown (EAS_HW_DATA_HANDLE hwInstData)
+{
+
+ free(hwInstData);
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_HWMalloc
+ *
+ * Allocates dynamic memory
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, hwInstData) hwInstData available for customer use */
+void *EAS_HWMalloc (EAS_HW_DATA_HANDLE hwInstData, EAS_I32 size)
+{
+ return malloc((size_t) size);
+}
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_HWFree
+ *
+ * Frees dynamic memory
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, hwInstData) hwInstData available for customer use */
+void EAS_HWFree (EAS_HW_DATA_HANDLE hwInstData, void *p)
+{
+ free(p);
+}
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_HWMemCpy
+ *
+ * Copy memory wrapper
+ *
+ *----------------------------------------------------------------------------
+*/
+void *EAS_HWMemCpy (void *dest, const void *src, EAS_I32 amount)
+{
+ return memcpy(dest, src, (size_t) amount);
+}
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_HWMemSet
+ *
+ * Set memory wrapper
+ *
+ *----------------------------------------------------------------------------
+*/
+void *EAS_HWMemSet (void *dest, int val, EAS_I32 amount)
+{
+ return memset(dest, val, (size_t) amount);
+}
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_HWMemCmp
+ *
+ * Compare memory wrapper
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_I32 EAS_HWMemCmp (const void *s1, const void *s2, EAS_I32 amount)
+{
+ return (EAS_I32) memcmp(s1, s2, (size_t) amount);
+}
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_HWOpenFile
+ *
+ * Open a file for read or write
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_HWOpenFile (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_LOCATOR locator, EAS_FILE_HANDLE *pFile, EAS_FILE_MODE mode)
+{
+ EAS_HW_FILE *file;
+ FILE *ioFile;
+ int i, temp;
+
+ /* set return value to NULL */
+ *pFile = NULL;
+
+ /* only support read mode at this time */
+ if (mode != EAS_FILE_READ)
+ return EAS_ERROR_INVALID_FILE_MODE;
+
+ /* find an empty entry in the file table */
+ file = hwInstData->files;
+ for (i = 0; i < EAS_MAX_FILE_HANDLES; i++)
+ {
+ /* is this slot being used? */
+ if (file->buffer == NULL)
+ {
+ /* open the file */
+ if ((ioFile = fopen(locator,"rb")) == NULL)
+ return EAS_ERROR_FILE_OPEN_FAILED;
+
+ /* determine the file size */
+ if (fseek(ioFile, 0L, SEEK_END) != 0)
+ return EAS_ERROR_FILE_LENGTH;
+ if ((file->fileSize = ftell(ioFile)) == -1L)
+ return EAS_ERROR_FILE_LENGTH;
+ if (fseek(ioFile, 0L, SEEK_SET) != 0)
+ return EAS_ERROR_FILE_LENGTH;
+
+ /* allocate a buffer */
+ file->buffer = EAS_HWMalloc(hwInstData, file->fileSize);
+ if (file->buffer == NULL)
+ {
+ fclose(ioFile);
+ return EAS_ERROR_MALLOC_FAILED;
+ }
+
+ /* read the file into memory */
+ temp = (int) fread(file->buffer, (size_t) file->fileSize, 1, ioFile);
+
+ /* close the file - don't need it any more */
+ fclose(ioFile);
+
+ /* check for error reading file */
+ if (temp != 1)
+ return EAS_ERROR_FILE_READ_FAILED;
+
+ /* initialize some values */
+ file->filePos = 0;
+ file->dup = EAS_FALSE;
+
+ *pFile = file;
+ return EAS_SUCCESS;
+ }
+ file++;
+ }
+
+ /* too many open files */
+ return EAS_ERROR_MAX_FILES_OPEN;
+}
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_HWReadFile
+ *
+ * Read data from a file
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, hwInstData) hwInstData available for customer use */
+EAS_RESULT EAS_HWReadFile (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, void *pBuffer, EAS_I32 n, EAS_I32 *pBytesRead)
+{
+ EAS_I32 count;
+
+ /* make sure we have a valid handle */
+ if (file->buffer == NULL)
+ return EAS_ERROR_INVALID_HANDLE;
+
+ /* calculate the bytes to read */
+ count = file->fileSize - file->filePos;
+ if (n < count)
+ count = n;
+
+ /* copy the data to the requested location, and advance the pointer */
+ if (count)
+ EAS_HWMemCpy(pBuffer, &file->buffer[file->filePos], count);
+ file->filePos += count;
+ *pBytesRead = count;
+
+ /* were n bytes read? */
+ if (count!= n)
+ return EAS_EOF;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_HWGetByte
+ *
+ * Read a byte from a file
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, hwInstData) hwInstData available for customer use */
+EAS_RESULT EAS_HWGetByte (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, void *p)
+{
+
+ /* make sure we have a valid handle */
+ if (file->buffer == NULL)
+ return EAS_ERROR_INVALID_HANDLE;
+
+ /* check for end of file */
+ if (file->filePos >= file->fileSize)
+ {
+ *((EAS_U8*) p) = 0;
+ return EAS_EOF;
+ }
+
+ /* get a character from the buffer */
+ *((EAS_U8*) p) = file->buffer[file->filePos++];
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_HWGetWord
+ *
+ * Returns the current location in the file
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, hwInstData) hwInstData available for customer use */
+EAS_RESULT EAS_HWGetWord (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, void *p, EAS_BOOL msbFirst)
+{
+ EAS_RESULT result;
+ EAS_U8 c1, c2;
+
+ /* read 2 bytes from the file */
+ if ((result = EAS_HWGetByte(hwInstData, file, &c1)) != EAS_SUCCESS)
+ return result;
+ if ((result = EAS_HWGetByte(hwInstData, file, &c2)) != EAS_SUCCESS)
+ return result;
+
+ /* order them as requested */
+ if (msbFirst)
+ *((EAS_U16*) p) = ((EAS_U16) c1 << 8) | c2;
+ else
+ *((EAS_U16*) p) = ((EAS_U16) c2 << 8) | c1;
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_HWGetDWord
+ *
+ * Returns the current location in the file
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, hwInstData) hwInstData available for customer use */
+EAS_RESULT EAS_HWGetDWord (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, void *p, EAS_BOOL msbFirst)
+{
+ EAS_RESULT result;
+ EAS_U8 c1, c2,c3,c4;
+
+ /* read 4 bytes from the file */
+ if ((result = EAS_HWGetByte(hwInstData, file, &c1)) != EAS_SUCCESS)
+ return result;
+ if ((result = EAS_HWGetByte(hwInstData, file, &c2)) != EAS_SUCCESS)
+ return result;
+ if ((result = EAS_HWGetByte(hwInstData, file, &c3)) != EAS_SUCCESS)
+ return result;
+ if ((result = EAS_HWGetByte(hwInstData, file, &c4)) != EAS_SUCCESS)
+ return result;
+
+ /* order them as requested */
+ if (msbFirst)
+ *((EAS_U32*) p) = ((EAS_U32) c1 << 24) | ((EAS_U32) c2 << 16) | ((EAS_U32) c3 << 8) | c4;
+ else
+ *((EAS_U32*) p)= ((EAS_U32) c4 << 24) | ((EAS_U32) c3 << 16) | ((EAS_U32) c2 << 8) | c1;
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_HWFilePos
+ *
+ * Returns the current location in the file
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, hwInstData) hwInstData available for customer use */
+EAS_RESULT EAS_HWFilePos (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, EAS_I32 *pPosition)
+{
+
+ /* make sure we have a valid handle */
+ if (file->buffer == NULL)
+ return EAS_ERROR_INVALID_HANDLE;
+
+ *pPosition = file->filePos;
+ return EAS_SUCCESS;
+} /* end EAS_HWFilePos */
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_HWFileSeek
+ *
+ * Seek to a specific location in the file
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, hwInstData) hwInstData available for customer use */
+EAS_RESULT EAS_HWFileSeek (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, EAS_I32 position)
+{
+
+ /* make sure we have a valid handle */
+ if (file->buffer == NULL)
+ return EAS_ERROR_INVALID_HANDLE;
+
+ /* validate new position */
+ if ((position < 0) || (position > file->fileSize))
+ return EAS_ERROR_FILE_SEEK;
+
+ /* save new position */
+ file->filePos = position;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_HWFileSeekOfs
+ *
+ * Seek forward or back relative to the current position
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, hwInstData) hwInstData available for customer use */
+EAS_RESULT EAS_HWFileSeekOfs (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, EAS_I32 position)
+{
+
+ /* make sure we have a valid handle */
+ if (file->buffer == NULL)
+ return EAS_ERROR_INVALID_HANDLE;
+
+ /* determine the file position */
+ position += file->filePos;
+ if ((position < 0) || (position > file->fileSize))
+ return EAS_ERROR_FILE_SEEK;
+
+ /* save new position */
+ file->filePos = position;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_HWFileLength
+ *
+ * Return the file length
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, hwInstData) hwInstData available for customer use */
+EAS_RESULT EAS_HWFileLength (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, EAS_I32 *pLength)
+{
+
+ /* make sure we have a valid handle */
+ if (file->buffer == NULL)
+ return EAS_ERROR_INVALID_HANDLE;
+
+ *pLength = file->fileSize;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_HWDupHandle
+ *
+ * Duplicate a file handle
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_HWDupHandle (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, EAS_FILE_HANDLE *pDupFile)
+{
+ EAS_HW_FILE *dupFile;
+ int i;
+
+ /* make sure we have a valid handle */
+ if (file->buffer == NULL)
+ return EAS_ERROR_INVALID_HANDLE;
+
+ /* find an empty entry in the file table */
+ dupFile = hwInstData->files;
+ for (i = 0; i < EAS_MAX_FILE_HANDLES; i++)
+ {
+ /* is this slot being used? */
+ if (dupFile->buffer == NULL)
+ {
+
+ /* copy info from the handle to be duplicated */
+ dupFile->filePos = file->filePos;
+ dupFile->fileSize = file->fileSize;
+ dupFile->buffer = file->buffer;
+
+ /* set the duplicate handle flag */
+ dupFile->dup = file->dup = EAS_TRUE;
+
+ *pDupFile = dupFile;
+ return EAS_SUCCESS;
+ }
+ dupFile++;
+ }
+
+ /* too many open files */
+ return EAS_ERROR_MAX_FILES_OPEN;
+}
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_HWClose
+ *
+ * Wrapper for fclose function
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_HWCloseFile (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file1)
+{
+ EAS_HW_FILE *file2,*dupFile;
+ int i;
+
+
+ /* make sure we have a valid handle */
+ if (file1->buffer == NULL)
+ return EAS_ERROR_INVALID_HANDLE;
+
+ /* check for duplicate handle */
+ if (file1->dup)
+ {
+ dupFile = NULL;
+ file2 = hwInstData->files;
+ for (i = 0; i < EAS_MAX_FILE_HANDLES; i++)
+ {
+ /* check for duplicate */
+ if ((file1 != file2) && (file2->buffer == file1->buffer))
+ {
+ /* is there more than one duplicate? */
+ if (dupFile != NULL)
+ {
+ /* clear this entry and return */
+ file1->buffer = NULL;
+ return EAS_SUCCESS;
+ }
+
+ /* this is the first duplicate found */
+ else
+ dupFile = file2;
+ }
+ file2++;
+ }
+
+ /* there is only one duplicate, clear the dup flag */
+ if (dupFile)
+ dupFile->dup = EAS_FALSE;
+ else
+ /* if we get here, there's a serious problem */
+ return EAS_ERROR_HANDLE_INTEGRITY;
+
+ /* clear this entry and return */
+ file1->buffer = NULL;
+ return EAS_SUCCESS;
+ }
+
+ /* no duplicates -free the buffer */
+ EAS_HWFree(hwInstData, file1->buffer);
+
+ /* clear this entry and return */
+ file1->buffer = NULL;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_HWVibrate
+ *
+ * Turn on/off vibrate function
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, hwInstData) hwInstData available for customer use */
+EAS_RESULT EAS_HWVibrate (EAS_HW_DATA_HANDLE hwInstData, EAS_BOOL state)
+{
+ EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x1a54b6e8, 0x00000001 , state);
+ return EAS_SUCCESS;
+} /* end EAS_HWVibrate */
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_HWLED
+ *
+ * Turn on/off LED
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, hwInstData) hwInstData available for customer use */
+EAS_RESULT EAS_HWLED (EAS_HW_DATA_HANDLE hwInstData, EAS_BOOL state)
+{
+ EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x1a54b6e8, 0x00000002 , state);
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_HWBackLight
+ *
+ * Turn on/off backlight
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, hwInstData) hwInstData available for customer use */
+EAS_RESULT EAS_HWBackLight (EAS_HW_DATA_HANDLE hwInstData, EAS_BOOL state)
+{
+ EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x1a54b6e8, 0x00000003 , state);
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_HWYield
+ *
+ * This function is called periodically by the EAS library to give the
+ * host an opportunity to allow other tasks to run. There are two ways to
+ * use this call:
+ *
+ * If you have a multi-tasking OS, you can call the yield function in the
+ * OS to allow other tasks to run. In this case, return EAS_FALSE to tell
+ * the EAS library to continue processing when control returns from this
+ * function.
+ *
+ * If tasks run in a single thread by sequential function calls (sometimes
+ * call a "commutator loop"), return EAS_TRUE to cause the EAS Library to
+ * return to the caller. Be sure to check the number of bytes rendered
+ * before passing the audio buffer to the codec - it may not be filled.
+ * The next call to EAS_Render will continue processing until the buffer
+ * has been filled.
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, hwInstData) hwInstData available for customer use */
+EAS_BOOL EAS_HWYield (EAS_HW_DATA_HANDLE hwInstData)
+{
+ /* put your code here */
+ return EAS_FALSE;
+}
+
diff --git a/arm-fm-22k/host_src/eas_main.c b/arm-fm-22k/host_src/eas_main.c
index 809a132..6ebb13e 100644
--- a/arm-fm-22k/host_src/eas_main.c
+++ b/arm-fm-22k/host_src/eas_main.c
@@ -1,13 +1,13 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_main.c
- *
- * Contents and purpose:
- * The entry point and high-level functions for the EAS Synthesizer test
- * harness.
- *
- * Copyright Sonic Network Inc. 2004
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_main.c
+ *
+ * Contents and purpose:
+ * The entry point and high-level functions for the EAS Synthesizer test
+ * harness.
+ *
+ * Copyright Sonic Network Inc. 2004
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,442 +20,442 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 775 $
- * $Date: 2007-07-20 10:11:11 -0700 (Fri, 20 Jul 2007) $
- *----------------------------------------------------------------------------
-*/
-
-#ifdef _lint
-#include "lint_stdlib.h"
-#else
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <time.h>
-#endif
-
-#include "eas.h"
-#include "eas_wave.h"
-#include "eas_report.h"
-
-/* determines how many EAS buffers to fill a host buffer */
-#define NUM_BUFFERS 8
-
-/* default file to play if no filename is specified on the command line */
-static const char defaultTestFile[] = "test.mid";
-
-EAS_I32 polyphony;
-
-/* prototypes for helper functions */
-static void StrCopy(char *dest, const char *src, EAS_I32 size);
-static EAS_BOOL ChangeFileExt(char *str, const char *ext, EAS_I32 size);
-static EAS_RESULT PlayFile (EAS_DATA_HANDLE easData, const char* filename, const char* outputFile, const S_EAS_LIB_CONFIG *pLibConfig, void *buffer, EAS_I32 bufferSize);
-static EAS_BOOL EASLibraryCheck (const S_EAS_LIB_CONFIG *pLibConfig);
-
-/* main is defined after playfile to avoid the need for two passes through lint */
-
-/*----------------------------------------------------------------------------
- * PlayFile()
- *----------------------------------------------------------------------------
- * Purpose:
- * This function plays the file requested by filename
- *
- * Inputs:
- *
- * Outputs:
- *
- *----------------------------------------------------------------------------
-*/
-
-static EAS_RESULT PlayFile (EAS_DATA_HANDLE easData, const char* filename, const char* outputFile, const S_EAS_LIB_CONFIG *pLibConfig, void *buffer, EAS_I32 bufferSize)
-{
- EAS_HANDLE handle;
- EAS_RESULT result, reportResult;
- EAS_I32 count;
- EAS_STATE state;
- EAS_I32 playTime;
- char waveFilename[256];
- WAVE_FILE *wFile;
- EAS_INT i;
- EAS_PCM *p;
-
- /* determine the name of the output file */
- wFile = NULL;
- if (outputFile == NULL)
- {
- StrCopy(waveFilename, filename, sizeof(waveFilename));
- if (!ChangeFileExt(waveFilename, "wav", sizeof(waveFilename)))
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Error in output filename %s\n", waveFilename); */ }
- return EAS_FAILURE;
- }
- outputFile = waveFilename;
- }
-
- /* call EAS library to open file */
- if ((reportResult = EAS_OpenFile(easData, filename, &handle)) != EAS_SUCCESS)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "EAS_OpenFile returned %ld\n", reportResult); */ }
- return reportResult;
- }
-
- /* prepare to play the file */
- if ((result = EAS_Prepare(easData, handle)) != EAS_SUCCESS)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "EAS_Prepare returned %ld\n", result); */ }
- reportResult = result;
- }
-
- /* get play length */
- if ((result = EAS_ParseMetaData(easData, handle, &playTime)) != EAS_SUCCESS)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "EAS_ParseMetaData returned %ld\n", result); */ }
- return result;
- }
- EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0xe624f4d9, 0x00000005 , playTime / 1000, playTime % 1000);
-
- if (reportResult == EAS_SUCCESS)
- {
- /* create the output file */
- wFile = WaveFileCreate(outputFile, pLibConfig->numChannels, pLibConfig->sampleRate, sizeof(EAS_PCM) * 8);
- if (!wFile)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Unable to create output file %s\n", waveFilename); */ }
- reportResult = EAS_FAILURE;
- }
- }
-
- /* rendering loop */
- while (reportResult == EAS_SUCCESS)
- {
-
- /* we may render several buffers here to fill one host buffer */
- for (i = 0, p = buffer; i < NUM_BUFFERS; i++, p+= pLibConfig->mixBufferSize * pLibConfig->numChannels)
- {
-
- /* get the current time */
- if ((result = EAS_GetLocation(easData, handle, &playTime)) != EAS_SUCCESS)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "EAS_GetLocation returned %d\n",result); */ }
- if (reportResult == EAS_SUCCESS)
- reportResult = result;
- break;
- }
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Parser time: %d.%03d\n", playTime / 1000, playTime % 1000); */ }
-
- /* render a buffer of audio */
- if ((result = EAS_Render(easData, p, pLibConfig->mixBufferSize, &count)) != EAS_SUCCESS)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "EAS_Render returned %d\n",result); */ }
- if (reportResult == EAS_SUCCESS)
- reportResult = result;
- }
- }
-
- if (result == EAS_SUCCESS)
- {
- /* write it to the wave file */
- if (WaveFileWrite(wFile, buffer, bufferSize) != bufferSize)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "WaveFileWrite failed\n"); */ }
- reportResult = EAS_FAILURE;
- }
- }
-
- if (reportResult == EAS_SUCCESS)
- {
- /* check stream state */
- if ((result = EAS_State(easData, handle, &state)) != EAS_SUCCESS)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "EAS_State returned %d\n", result); */ }
- reportResult = result;
- }
-
- /* is playback complete */
- if ((state == EAS_STATE_STOPPED) || (state == EAS_STATE_ERROR))
- break;
- }
- }
-
- /* close the output file */
- if (wFile)
- {
- if (!WaveFileClose(wFile))
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Error closing wave file %s\n", waveFilename); */ }
- if (reportResult == EAS_SUCCESS)
- result = EAS_FAILURE;
- }
- }
-
- /* close the input file */
- if ((result = EAS_CloseFile(easData,handle)) != EAS_SUCCESS)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "EAS_Close returned %ld\n", result); */ }
- if (reportResult == EAS_SUCCESS)
- result = EAS_FAILURE;
- }
-
- return reportResult;
-} /* end PlayFile */
-
-/*----------------------------------------------------------------------------
- * main()
- *----------------------------------------------------------------------------
- * Purpose: The entry point for the EAS sample application
- *
- * Inputs:
- *
- * Outputs:
- *
- *----------------------------------------------------------------------------
-*/
-int main( int argc, char **argv )
-{
- EAS_DATA_HANDLE easData;
- const S_EAS_LIB_CONFIG *pLibConfig;
- void *buffer;
- EAS_RESULT result, playResult;
- EAS_I32 bufferSize;
- int i;
- int temp;
- FILE *debugFile;
- char *outputFile = NULL;
-
- /* set the error reporting level */
- EAS_SetDebugLevel(_EAS_SEVERITY_INFO);
- debugFile = NULL;
-
- /* process command-line arguments */
- for (i = 1; i < argc; i++)
- {
- /* check for switch */
- if (argv[i][0] == '-')
- {
- switch (argv[i][1])
- {
- case 'd':
- temp = argv[i][2];
- if ((temp >= '0') || (temp <= '9'))
- EAS_SetDebugLevel(temp);
- else
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Invalid debug level %d\n", temp); */ }
- break;
- case 'f':
- if ((debugFile = fopen(&argv[i][2],"w")) == NULL)
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Unable to create debug file %s\n", &argv[i][2]); */ }
- else
- EAS_SetDebugFile(debugFile, EAS_TRUE);
- break;
- case 'o':
- outputFile = &argv[i][2];
- break;
- case 'p':
- polyphony = atoi(&argv[i][2]);
- if (polyphony < 1)
- polyphony = 1;
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "Polyphony set to %d\n", polyphony); */ }
- break;
- default:
- break;
- }
- continue;
- }
- }
-
- /* assume success */
- playResult = EAS_SUCCESS;
-
- /* get the library configuration */
- pLibConfig = EAS_Config();
- if (!EASLibraryCheck(pLibConfig))
- return -1;
- if (polyphony > pLibConfig->maxVoices)
- polyphony = pLibConfig->maxVoices;
-
- /* calculate buffer size */
- bufferSize = pLibConfig->mixBufferSize * pLibConfig->numChannels * (EAS_I32)sizeof(EAS_PCM) * NUM_BUFFERS;
-
- /* allocate output buffer memory */
- buffer = malloc((EAS_U32)bufferSize);
- if (!buffer)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_FATAL, "Error allocating memory for audio buffer\n"); */ }
- return EAS_FAILURE;
- }
-
- /* initialize the EAS library */
- polyphony = pLibConfig->maxVoices;
- if ((result = EAS_Init(&easData)) != EAS_SUCCESS)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_FATAL, "EAS_Init returned %ld - aborting!\n", result); */ }
- free(buffer);
- return result;
- }
-
- /*
- * Some debugging environments don't allow for passed parameters.
- * In this case, just play the default MIDI file "test.mid"
- */
- if (argc < 2)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "Playing '%s'\n", defaultTestFile); */ }
- if ((playResult = PlayFile(easData, defaultTestFile, NULL, pLibConfig, buffer, bufferSize)) != EAS_SUCCESS)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Error %d playing file %s\n", playResult, defaultTestFile); */ }
- }
- }
- /* iterate through the list of files to be played */
- else
- {
- for (i = 1; i < argc; i++)
- {
- /* check for switch */
- if (argv[i][0] != '-')
- {
-
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "Playing '%s'\n", argv[i]); */ }
- if ((playResult = PlayFile(easData, argv[i], outputFile, pLibConfig, buffer, bufferSize)) != EAS_SUCCESS)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Error %d playing file %s\n", playResult, argv[i]); */ }
- break;
- }
- }
- }
- }
-
- /* shutdown the EAS library */
- if ((result = EAS_Shutdown(easData)) != EAS_SUCCESS)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_FATAL, "EAS_Shutdown returned %ld\n", result); */ }
- }
-
- /* free the output buffer */
- free(buffer);
-
- /* close the debug file */
- if (debugFile)
- fclose(debugFile);
-
- /* play errors take precedence over shutdown errors */
- if (playResult != EAS_SUCCESS)
- return playResult;
- return result;
-} /* end main */
-
-/*----------------------------------------------------------------------------
- * StrCopy()
- *----------------------------------------------------------------------------
- * Purpose:
- * Safe string copy
- *
- * Inputs:
- *
- * Outputs:
- *
- *----------------------------------------------------------------------------
-*/
-static void StrCopy(char *dest, const char *src, EAS_I32 size)
-{
- int len;
-
- strncpy(dest, src, (size_t) size-1);
- len = (int) strlen(src);
- if (len < size)
- dest[len] = 0;
-} /* end StrCopy */
-
-/*----------------------------------------------------------------------------
- * ChangeFileExt()
- *----------------------------------------------------------------------------
- * Purpose:
- * Changes the file extension of a filename
- *
- * Inputs:
- *
- * Outputs:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_BOOL ChangeFileExt(char *str, const char *ext, EAS_I32 size)
-{
- char *p;
-
- /* find the extension, if any */
- p = strrchr(str,'.');
- if (!p)
- {
- if ((EAS_I32)(strlen(str) + 5) > size)
- return EAS_FALSE;
- strcat(str,".");
- strcat(str,ext);
- return EAS_TRUE;
- }
-
- /* make sure there's room for the extension */
- p++;
- *p = 0;
- if ((EAS_I32)(strlen(str) + 4) > size)
- return EAS_FALSE;
- strcat(str,ext);
- return EAS_TRUE;
-} /* end ChangeFileExt */
-
-/*----------------------------------------------------------------------------
- * EASLibraryCheck()
- *----------------------------------------------------------------------------
- * Purpose:
- * Displays the library version and checks it against the header
- * file used to build this code.
- *
- * Inputs:
- * pLibConfig - library configuration retrieved from the library
- *
- * Outputs:
- * returns EAS_TRUE if matched
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_BOOL EASLibraryCheck (const S_EAS_LIB_CONFIG *pLibConfig)
-{
-
- /* display the library version */
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "EAS Library Version %d.%d.%d.%d\n",
- pLibConfig->libVersion >> 24,
- (pLibConfig->libVersion >> 16) & 0x0f,
- (pLibConfig->libVersion >> 8) & 0x0f,
- pLibConfig->libVersion & 0x0f); */ }
-
- /* display some info about the library build */
- if (pLibConfig->checkedVersion)
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "\tChecked library\n"); */ }
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "\tMaximum polyphony: %d\n", pLibConfig->maxVoices); */ }
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "\tNumber of channels: %d\n", pLibConfig->numChannels); */ }
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "\tSample rate: %d\n", pLibConfig->sampleRate); */ }
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "\tMix buffer size: %d\n", pLibConfig->mixBufferSize); */ }
- if (pLibConfig->filterEnabled)
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "\tFilter enabled\n"); */ }
-#ifndef _WIN32_WCE
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "\tLibrary Build Timestamp: %s", ctime((time_t*)&pLibConfig->buildTimeStamp)); */ }
-#endif
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "\tLibrary Build ID: %s\n", pLibConfig->buildGUID); */ }
-
- /* check it against the header file used to build this code */
- /*lint -e{778} constant expression used for display purposes may evaluate to zero */
- if (LIB_VERSION != pLibConfig->libVersion)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_FATAL, "Library version does not match header files. EAS Header Version %d.%d.%d.%d\n",
- LIB_VERSION >> 24,
- (LIB_VERSION >> 16) & 0x0f,
- (LIB_VERSION >> 8) & 0x0f,
- LIB_VERSION & 0x0f); */ }
- return EAS_FALSE;
- }
- return EAS_TRUE;
-} /* end EASLibraryCheck */
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 775 $
+ * $Date: 2007-07-20 10:11:11 -0700 (Fri, 20 Jul 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+#ifdef _lint
+#include "lint_stdlib.h"
+#else
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <time.h>
+#endif
+
+#include "eas.h"
+#include "eas_wave.h"
+#include "eas_report.h"
+
+/* determines how many EAS buffers to fill a host buffer */
+#define NUM_BUFFERS 8
+
+/* default file to play if no filename is specified on the command line */
+static const char defaultTestFile[] = "test.mid";
+
+EAS_I32 polyphony;
+
+/* prototypes for helper functions */
+static void StrCopy(char *dest, const char *src, EAS_I32 size);
+static EAS_BOOL ChangeFileExt(char *str, const char *ext, EAS_I32 size);
+static EAS_RESULT PlayFile (EAS_DATA_HANDLE easData, const char* filename, const char* outputFile, const S_EAS_LIB_CONFIG *pLibConfig, void *buffer, EAS_I32 bufferSize);
+static EAS_BOOL EASLibraryCheck (const S_EAS_LIB_CONFIG *pLibConfig);
+
+/* main is defined after playfile to avoid the need for two passes through lint */
+
+/*----------------------------------------------------------------------------
+ * PlayFile()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * This function plays the file requested by filename
+ *
+ * Inputs:
+ *
+ * Outputs:
+ *
+ *----------------------------------------------------------------------------
+*/
+
+static EAS_RESULT PlayFile (EAS_DATA_HANDLE easData, const char* filename, const char* outputFile, const S_EAS_LIB_CONFIG *pLibConfig, void *buffer, EAS_I32 bufferSize)
+{
+ EAS_HANDLE handle;
+ EAS_RESULT result, reportResult;
+ EAS_I32 count;
+ EAS_STATE state;
+ EAS_I32 playTime;
+ char waveFilename[256];
+ WAVE_FILE *wFile;
+ EAS_INT i;
+ EAS_PCM *p;
+
+ /* determine the name of the output file */
+ wFile = NULL;
+ if (outputFile == NULL)
+ {
+ StrCopy(waveFilename, filename, sizeof(waveFilename));
+ if (!ChangeFileExt(waveFilename, "wav", sizeof(waveFilename)))
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Error in output filename %s\n", waveFilename); */ }
+ return EAS_FAILURE;
+ }
+ outputFile = waveFilename;
+ }
+
+ /* call EAS library to open file */
+ if ((reportResult = EAS_OpenFile(easData, filename, &handle)) != EAS_SUCCESS)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "EAS_OpenFile returned %ld\n", reportResult); */ }
+ return reportResult;
+ }
+
+ /* prepare to play the file */
+ if ((result = EAS_Prepare(easData, handle)) != EAS_SUCCESS)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "EAS_Prepare returned %ld\n", result); */ }
+ reportResult = result;
+ }
+
+ /* get play length */
+ if ((result = EAS_ParseMetaData(easData, handle, &playTime)) != EAS_SUCCESS)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "EAS_ParseMetaData returned %ld\n", result); */ }
+ return result;
+ }
+ EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0xe624f4d9, 0x00000005 , playTime / 1000, playTime % 1000);
+
+ if (reportResult == EAS_SUCCESS)
+ {
+ /* create the output file */
+ wFile = WaveFileCreate(outputFile, pLibConfig->numChannels, pLibConfig->sampleRate, sizeof(EAS_PCM) * 8);
+ if (!wFile)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Unable to create output file %s\n", waveFilename); */ }
+ reportResult = EAS_FAILURE;
+ }
+ }
+
+ /* rendering loop */
+ while (reportResult == EAS_SUCCESS)
+ {
+
+ /* we may render several buffers here to fill one host buffer */
+ for (i = 0, p = buffer; i < NUM_BUFFERS; i++, p+= pLibConfig->mixBufferSize * pLibConfig->numChannels)
+ {
+
+ /* get the current time */
+ if ((result = EAS_GetLocation(easData, handle, &playTime)) != EAS_SUCCESS)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "EAS_GetLocation returned %d\n",result); */ }
+ if (reportResult == EAS_SUCCESS)
+ reportResult = result;
+ break;
+ }
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Parser time: %d.%03d\n", playTime / 1000, playTime % 1000); */ }
+
+ /* render a buffer of audio */
+ if ((result = EAS_Render(easData, p, pLibConfig->mixBufferSize, &count)) != EAS_SUCCESS)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "EAS_Render returned %d\n",result); */ }
+ if (reportResult == EAS_SUCCESS)
+ reportResult = result;
+ }
+ }
+
+ if (result == EAS_SUCCESS)
+ {
+ /* write it to the wave file */
+ if (WaveFileWrite(wFile, buffer, bufferSize) != bufferSize)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "WaveFileWrite failed\n"); */ }
+ reportResult = EAS_FAILURE;
+ }
+ }
+
+ if (reportResult == EAS_SUCCESS)
+ {
+ /* check stream state */
+ if ((result = EAS_State(easData, handle, &state)) != EAS_SUCCESS)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "EAS_State returned %d\n", result); */ }
+ reportResult = result;
+ }
+
+ /* is playback complete */
+ if ((state == EAS_STATE_STOPPED) || (state == EAS_STATE_ERROR))
+ break;
+ }
+ }
+
+ /* close the output file */
+ if (wFile)
+ {
+ if (!WaveFileClose(wFile))
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Error closing wave file %s\n", waveFilename); */ }
+ if (reportResult == EAS_SUCCESS)
+ result = EAS_FAILURE;
+ }
+ }
+
+ /* close the input file */
+ if ((result = EAS_CloseFile(easData,handle)) != EAS_SUCCESS)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "EAS_Close returned %ld\n", result); */ }
+ if (reportResult == EAS_SUCCESS)
+ result = EAS_FAILURE;
+ }
+
+ return reportResult;
+} /* end PlayFile */
+
+/*----------------------------------------------------------------------------
+ * main()
+ *----------------------------------------------------------------------------
+ * Purpose: The entry point for the EAS sample application
+ *
+ * Inputs:
+ *
+ * Outputs:
+ *
+ *----------------------------------------------------------------------------
+*/
+int main( int argc, char **argv )
+{
+ EAS_DATA_HANDLE easData;
+ const S_EAS_LIB_CONFIG *pLibConfig;
+ void *buffer;
+ EAS_RESULT result, playResult;
+ EAS_I32 bufferSize;
+ int i;
+ int temp;
+ FILE *debugFile;
+ char *outputFile = NULL;
+
+ /* set the error reporting level */
+ EAS_SetDebugLevel(_EAS_SEVERITY_INFO);
+ debugFile = NULL;
+
+ /* process command-line arguments */
+ for (i = 1; i < argc; i++)
+ {
+ /* check for switch */
+ if (argv[i][0] == '-')
+ {
+ switch (argv[i][1])
+ {
+ case 'd':
+ temp = argv[i][2];
+ if ((temp >= '0') || (temp <= '9'))
+ EAS_SetDebugLevel(temp);
+ else
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Invalid debug level %d\n", temp); */ }
+ break;
+ case 'f':
+ if ((debugFile = fopen(&argv[i][2],"w")) == NULL)
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Unable to create debug file %s\n", &argv[i][2]); */ }
+ else
+ EAS_SetDebugFile(debugFile, EAS_TRUE);
+ break;
+ case 'o':
+ outputFile = &argv[i][2];
+ break;
+ case 'p':
+ polyphony = atoi(&argv[i][2]);
+ if (polyphony < 1)
+ polyphony = 1;
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "Polyphony set to %d\n", polyphony); */ }
+ break;
+ default:
+ break;
+ }
+ continue;
+ }
+ }
+
+ /* assume success */
+ playResult = EAS_SUCCESS;
+
+ /* get the library configuration */
+ pLibConfig = EAS_Config();
+ if (!EASLibraryCheck(pLibConfig))
+ return -1;
+ if (polyphony > pLibConfig->maxVoices)
+ polyphony = pLibConfig->maxVoices;
+
+ /* calculate buffer size */
+ bufferSize = pLibConfig->mixBufferSize * pLibConfig->numChannels * (EAS_I32)sizeof(EAS_PCM) * NUM_BUFFERS;
+
+ /* allocate output buffer memory */
+ buffer = malloc((EAS_U32)bufferSize);
+ if (!buffer)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_FATAL, "Error allocating memory for audio buffer\n"); */ }
+ return EAS_FAILURE;
+ }
+
+ /* initialize the EAS library */
+ polyphony = pLibConfig->maxVoices;
+ if ((result = EAS_Init(&easData)) != EAS_SUCCESS)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_FATAL, "EAS_Init returned %ld - aborting!\n", result); */ }
+ free(buffer);
+ return result;
+ }
+
+ /*
+ * Some debugging environments don't allow for passed parameters.
+ * In this case, just play the default MIDI file "test.mid"
+ */
+ if (argc < 2)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "Playing '%s'\n", defaultTestFile); */ }
+ if ((playResult = PlayFile(easData, defaultTestFile, NULL, pLibConfig, buffer, bufferSize)) != EAS_SUCCESS)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Error %d playing file %s\n", playResult, defaultTestFile); */ }
+ }
+ }
+ /* iterate through the list of files to be played */
+ else
+ {
+ for (i = 1; i < argc; i++)
+ {
+ /* check for switch */
+ if (argv[i][0] != '-')
+ {
+
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "Playing '%s'\n", argv[i]); */ }
+ if ((playResult = PlayFile(easData, argv[i], outputFile, pLibConfig, buffer, bufferSize)) != EAS_SUCCESS)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Error %d playing file %s\n", playResult, argv[i]); */ }
+ break;
+ }
+ }
+ }
+ }
+
+ /* shutdown the EAS library */
+ if ((result = EAS_Shutdown(easData)) != EAS_SUCCESS)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_FATAL, "EAS_Shutdown returned %ld\n", result); */ }
+ }
+
+ /* free the output buffer */
+ free(buffer);
+
+ /* close the debug file */
+ if (debugFile)
+ fclose(debugFile);
+
+ /* play errors take precedence over shutdown errors */
+ if (playResult != EAS_SUCCESS)
+ return playResult;
+ return result;
+} /* end main */
+
+/*----------------------------------------------------------------------------
+ * StrCopy()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Safe string copy
+ *
+ * Inputs:
+ *
+ * Outputs:
+ *
+ *----------------------------------------------------------------------------
+*/
+static void StrCopy(char *dest, const char *src, EAS_I32 size)
+{
+ int len;
+
+ strncpy(dest, src, (size_t) size-1);
+ len = (int) strlen(src);
+ if (len < size)
+ dest[len] = 0;
+} /* end StrCopy */
+
+/*----------------------------------------------------------------------------
+ * ChangeFileExt()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Changes the file extension of a filename
+ *
+ * Inputs:
+ *
+ * Outputs:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_BOOL ChangeFileExt(char *str, const char *ext, EAS_I32 size)
+{
+ char *p;
+
+ /* find the extension, if any */
+ p = strrchr(str,'.');
+ if (!p)
+ {
+ if ((EAS_I32)(strlen(str) + 5) > size)
+ return EAS_FALSE;
+ strcat(str,".");
+ strcat(str,ext);
+ return EAS_TRUE;
+ }
+
+ /* make sure there's room for the extension */
+ p++;
+ *p = 0;
+ if ((EAS_I32)(strlen(str) + 4) > size)
+ return EAS_FALSE;
+ strcat(str,ext);
+ return EAS_TRUE;
+} /* end ChangeFileExt */
+
+/*----------------------------------------------------------------------------
+ * EASLibraryCheck()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Displays the library version and checks it against the header
+ * file used to build this code.
+ *
+ * Inputs:
+ * pLibConfig - library configuration retrieved from the library
+ *
+ * Outputs:
+ * returns EAS_TRUE if matched
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_BOOL EASLibraryCheck (const S_EAS_LIB_CONFIG *pLibConfig)
+{
+
+ /* display the library version */
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "EAS Library Version %d.%d.%d.%d\n",
+ pLibConfig->libVersion >> 24,
+ (pLibConfig->libVersion >> 16) & 0x0f,
+ (pLibConfig->libVersion >> 8) & 0x0f,
+ pLibConfig->libVersion & 0x0f); */ }
+
+ /* display some info about the library build */
+ if (pLibConfig->checkedVersion)
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "\tChecked library\n"); */ }
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "\tMaximum polyphony: %d\n", pLibConfig->maxVoices); */ }
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "\tNumber of channels: %d\n", pLibConfig->numChannels); */ }
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "\tSample rate: %d\n", pLibConfig->sampleRate); */ }
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "\tMix buffer size: %d\n", pLibConfig->mixBufferSize); */ }
+ if (pLibConfig->filterEnabled)
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "\tFilter enabled\n"); */ }
+#ifndef _WIN32_WCE
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "\tLibrary Build Timestamp: %s", ctime((time_t*)&pLibConfig->buildTimeStamp)); */ }
+#endif
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "\tLibrary Build ID: %s\n", pLibConfig->buildGUID); */ }
+
+ /* check it against the header file used to build this code */
+ /*lint -e{778} constant expression used for display purposes may evaluate to zero */
+ if (LIB_VERSION != pLibConfig->libVersion)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_FATAL, "Library version does not match header files. EAS Header Version %d.%d.%d.%d\n",
+ LIB_VERSION >> 24,
+ (LIB_VERSION >> 16) & 0x0f,
+ (LIB_VERSION >> 8) & 0x0f,
+ LIB_VERSION & 0x0f); */ }
+ return EAS_FALSE;
+ }
+ return EAS_TRUE;
+} /* end EASLibraryCheck */
+
diff --git a/arm-fm-22k/host_src/eas_report.c b/arm-fm-22k/host_src/eas_report.c
index d4dd22c..04a828c 100644
--- a/arm-fm-22k/host_src/eas_report.c
+++ b/arm-fm-22k/host_src/eas_report.c
@@ -1,13 +1,13 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_report.c
- *
- * Contents and purpose:
- * This file contains the debug message handling routines for the EAS library.
- * These routines should be modified as needed for your system.
- *
- * Copyright 2005 Sonic Network Inc.
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_report.c
+ *
+ * Contents and purpose:
+ * This file contains the debug message handling routines for the EAS library.
+ * These routines should be modified as needed for your system.
+ *
+ * Copyright 2005 Sonic Network Inc.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,245 +20,245 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 659 $
- * $Date: 2007-04-24 13:36:35 -0700 (Tue, 24 Apr 2007) $
- *----------------------------------------------------------------------------
-*/
-
-#ifdef _lint
-#include "lint_stdlib.h"
-#else
-#include <stdlib.h>
-#include <stdio.h>
-#include <stdarg.h>
-#endif
-
-#include "eas_report.h"
-
-static int severityLevel = 9999;
-
-/* debug file */
-static FILE *debugFile = NULL;
-int flush = 0;
-
-#ifndef _NO_DEBUG_PREPROCESSOR
-
-/* structure should have an #include for each error message header file */
-S_DEBUG_MESSAGES debugMessages[] =
-{
-#ifndef UNIFIED_DEBUG_MESSAGES
-#include "eas_config_msgs.h"
-
-
-#include "eas_host_msgs.h"
-#include "eas_hostmm_msgs.h"
-#include "eas_math_msgs.h"
-#include "eas_midi_msgs.h"
-#include "eas_mixer_msgs.h"
-#include "eas_pcm_msgs.h"
-#include "eas_public_msgs.h"
-#include "eas_smf_msgs.h"
-#include "eas_wave_msgs.h"
-#include "eas_voicemgt_msgs.h"
-
-#ifdef _FM_SYNTH
-#include "eas_fmsynth_msgs.h"
-#include "eas_fmengine_msgs.h"
-#endif
-
-#ifdef _WT_SYNTH
-#include "eas_wtsynth_msgs.h"
-#include "eas_wtengine_msgs.h"
-#endif
-
-#ifdef _ARM_TEST_MAIN
-#include "arm_main_msgs.h"
-#endif
-
-#ifdef _EAS_MAIN
-#include "eas_main_msgs.h"
-#endif
-
-#ifdef _EAS_MAIN_IPC
-#include "eas_main_ipc_msgs.h"
-#endif
-
-#ifdef _METRICS_ENABLED
-#include "eas_perf_msgs.h"
-#endif
-
-#ifdef _COMPRESSOR_ENABLED
-#include "eas_compressor_msgs.h"
-#endif
-
-#ifdef _ENHANCER_ENABLED
-#include "eas_enhancer_msgs.h"
-#endif
-
-#ifdef _WOW_ENABLED
-#include "eas_wow_msgs.h"
-#endif
-
-#ifdef _SMAF_PARSER
-#include "eas_smaf_msgs.h"
-#endif
-
-#ifdef _OTA_PARSER
-#include "eas_ota_msgs.h"
-#endif
-
-#ifdef _IMELODY_PARSER
-#include "eas_imelody_msgs.h"
-#endif
-
-#ifdef _WAVE_PARSER
-#include "eas_wavefile_msgs.h"
-#endif
-
-#if defined(_CMX_PARSER) || defined(_MFI_PARSER)
-#include "eas_cmf_msgs.h"
-#endif
-
-#if defined(_CMX_PARSER) || defined(_MFI_PARSER) || defined(_WAVE_PARSER)
-#include "eas_imaadpcm_msgs.h"
-#endif
-
-#else
-#include "eas_debugmsgs.h"
-#endif
-
-/* denotes end of error messages */
-{ 0,0,0 }
-};
-
-/*----------------------------------------------------------------------------
- * EAS_ReportEx()
- *
- * This is the error message handler. The default handler outputs error
- * messages to stdout. Modify this as needed for your system.
- *----------------------------------------------------------------------------
-*/
-void EAS_ReportEx (int severity, unsigned long hashCode, int serialNum, ...)
-{
- va_list vargs;
- int i;
-
- /* check severity level */
- if (severity > severityLevel)
- return;
-
- /* find the error message and output to stdout */
- /*lint -e{661} we check for NULL pointer - no fence post error here */
- for (i = 0; debugMessages[i].m_pDebugMsg; i++)
- {
- if ((debugMessages[i].m_nHashCode == hashCode) &&
- (debugMessages[i].m_nSerialNum == serialNum))
- {
- /*lint -e{826} <allow variable args> */
- va_start(vargs, serialNum);
- if (debugFile)
- {
- vfprintf(debugFile, debugMessages[i].m_pDebugMsg, vargs);
- if (flush)
- fflush(debugFile);
- }
- else
- {
- vprintf(debugMessages[i].m_pDebugMsg, vargs);
- }
- va_end(vargs);
- return;
- }
- }
- printf("Unrecognized error: Severity=%d; HashCode=%lu; SerialNum=%d\n", severity, hashCode, serialNum);
-} /* end EAS_ReportEx */
-
-#else
-/*----------------------------------------------------------------------------
- * EAS_Report()
- *
- * This is the error message handler. The default handler outputs error
- * messages to stdout. Modify this as needed for your system.
- *----------------------------------------------------------------------------
-*/
-void EAS_Report (int severity, const char *fmt, ...)
-{
- va_list vargs;
-
- /* check severity level */
- if (severity > severityLevel)
- return;
-
- /*lint -e{826} <allow variable args> */
- va_start(vargs, fmt);
- if (debugFile)
- {
- vfprintf(debugFile, fmt, vargs);
- if (flush)
- fflush(debugFile);
- }
- else
- {
- vprintf(fmt, vargs);
- }
- va_end(vargs);
-} /* end EAS_Report */
-
-/*----------------------------------------------------------------------------
- * EAS_ReportX()
- *
- * This is the error message handler. The default handler outputs error
- * messages to stdout. Modify this as needed for your system.
- *----------------------------------------------------------------------------
-*/
-void EAS_ReportX (int severity, const char *fmt, ...)
-{
- va_list vargs;
-
- /* check severity level */
- if (severity > severityLevel)
- return;
-
- /*lint -e{826} <allow variable args> */
- va_start(vargs, fmt);
- if (debugFile)
- {
- vfprintf(debugFile, fmt, vargs);
- if (flush)
- fflush(debugFile);
- }
- else
- {
- vprintf(fmt, vargs);
- }
- va_end(vargs);
-} /* end EAS_ReportX */
-#endif
-
-/*----------------------------------------------------------------------------
- * EAS_SetDebugLevel()
- *
- * Sets the level for debug message output
- *----------------------------------------------------------------------------
-*/
-
-void EAS_SetDebugLevel (int severity)
-{
- severityLevel = severity;
-} /* end EAS_SetDebugLevel */
-
-/*----------------------------------------------------------------------------
- * EAS_SetDebugFile()
- *
- * Redirect debugger output to the specified file.
- *----------------------------------------------------------------------------
-*/
-void EAS_SetDebugFile (void *file, int flushAfterWrite)
-{
- debugFile = (FILE*) file;
- flush = flushAfterWrite;
-} /* end EAS_SetDebugFile */
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 659 $
+ * $Date: 2007-04-24 13:36:35 -0700 (Tue, 24 Apr 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+#ifdef _lint
+#include "lint_stdlib.h"
+#else
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdarg.h>
+#endif
+
+#include "eas_report.h"
+
+static int severityLevel = 9999;
+
+/* debug file */
+static FILE *debugFile = NULL;
+int flush = 0;
+
+#ifndef _NO_DEBUG_PREPROCESSOR
+
+/* structure should have an #include for each error message header file */
+S_DEBUG_MESSAGES debugMessages[] =
+{
+#ifndef UNIFIED_DEBUG_MESSAGES
+#include "eas_config_msgs.h"
+
+
+#include "eas_host_msgs.h"
+#include "eas_hostmm_msgs.h"
+#include "eas_math_msgs.h"
+#include "eas_midi_msgs.h"
+#include "eas_mixer_msgs.h"
+#include "eas_pcm_msgs.h"
+#include "eas_public_msgs.h"
+#include "eas_smf_msgs.h"
+#include "eas_wave_msgs.h"
+#include "eas_voicemgt_msgs.h"
+
+#ifdef _FM_SYNTH
+#include "eas_fmsynth_msgs.h"
+#include "eas_fmengine_msgs.h"
+#endif
+
+#ifdef _WT_SYNTH
+#include "eas_wtsynth_msgs.h"
+#include "eas_wtengine_msgs.h"
+#endif
+
+#ifdef _ARM_TEST_MAIN
+#include "arm_main_msgs.h"
+#endif
+
+#ifdef _EAS_MAIN
+#include "eas_main_msgs.h"
+#endif
+
+#ifdef _EAS_MAIN_IPC
+#include "eas_main_ipc_msgs.h"
+#endif
+
+#ifdef _METRICS_ENABLED
+#include "eas_perf_msgs.h"
+#endif
+
+#ifdef _COMPRESSOR_ENABLED
+#include "eas_compressor_msgs.h"
+#endif
+
+#ifdef _ENHANCER_ENABLED
+#include "eas_enhancer_msgs.h"
+#endif
+
+#ifdef _WOW_ENABLED
+#include "eas_wow_msgs.h"
+#endif
+
+#ifdef _SMAF_PARSER
+#include "eas_smaf_msgs.h"
+#endif
+
+#ifdef _OTA_PARSER
+#include "eas_ota_msgs.h"
+#endif
+
+#ifdef _IMELODY_PARSER
+#include "eas_imelody_msgs.h"
+#endif
+
+#ifdef _WAVE_PARSER
+#include "eas_wavefile_msgs.h"
+#endif
+
+#if defined(_CMX_PARSER) || defined(_MFI_PARSER)
+#include "eas_cmf_msgs.h"
+#endif
+
+#if defined(_CMX_PARSER) || defined(_MFI_PARSER) || defined(_WAVE_PARSER)
+#include "eas_imaadpcm_msgs.h"
+#endif
+
+#else
+#include "eas_debugmsgs.h"
+#endif
+
+/* denotes end of error messages */
+{ 0,0,0 }
+};
+
+/*----------------------------------------------------------------------------
+ * EAS_ReportEx()
+ *
+ * This is the error message handler. The default handler outputs error
+ * messages to stdout. Modify this as needed for your system.
+ *----------------------------------------------------------------------------
+*/
+void EAS_ReportEx (int severity, unsigned long hashCode, int serialNum, ...)
+{
+ va_list vargs;
+ int i;
+
+ /* check severity level */
+ if (severity > severityLevel)
+ return;
+
+ /* find the error message and output to stdout */
+ /*lint -e{661} we check for NULL pointer - no fence post error here */
+ for (i = 0; debugMessages[i].m_pDebugMsg; i++)
+ {
+ if ((debugMessages[i].m_nHashCode == hashCode) &&
+ (debugMessages[i].m_nSerialNum == serialNum))
+ {
+ /*lint -e{826} <allow variable args> */
+ va_start(vargs, serialNum);
+ if (debugFile)
+ {
+ vfprintf(debugFile, debugMessages[i].m_pDebugMsg, vargs);
+ if (flush)
+ fflush(debugFile);
+ }
+ else
+ {
+ vprintf(debugMessages[i].m_pDebugMsg, vargs);
+ }
+ va_end(vargs);
+ return;
+ }
+ }
+ printf("Unrecognized error: Severity=%d; HashCode=%lu; SerialNum=%d\n", severity, hashCode, serialNum);
+} /* end EAS_ReportEx */
+
+#else
+/*----------------------------------------------------------------------------
+ * EAS_Report()
+ *
+ * This is the error message handler. The default handler outputs error
+ * messages to stdout. Modify this as needed for your system.
+ *----------------------------------------------------------------------------
+*/
+void EAS_Report (int severity, const char *fmt, ...)
+{
+ va_list vargs;
+
+ /* check severity level */
+ if (severity > severityLevel)
+ return;
+
+ /*lint -e{826} <allow variable args> */
+ va_start(vargs, fmt);
+ if (debugFile)
+ {
+ vfprintf(debugFile, fmt, vargs);
+ if (flush)
+ fflush(debugFile);
+ }
+ else
+ {
+ vprintf(fmt, vargs);
+ }
+ va_end(vargs);
+} /* end EAS_Report */
+
+/*----------------------------------------------------------------------------
+ * EAS_ReportX()
+ *
+ * This is the error message handler. The default handler outputs error
+ * messages to stdout. Modify this as needed for your system.
+ *----------------------------------------------------------------------------
+*/
+void EAS_ReportX (int severity, const char *fmt, ...)
+{
+ va_list vargs;
+
+ /* check severity level */
+ if (severity > severityLevel)
+ return;
+
+ /*lint -e{826} <allow variable args> */
+ va_start(vargs, fmt);
+ if (debugFile)
+ {
+ vfprintf(debugFile, fmt, vargs);
+ if (flush)
+ fflush(debugFile);
+ }
+ else
+ {
+ vprintf(fmt, vargs);
+ }
+ va_end(vargs);
+} /* end EAS_ReportX */
+#endif
+
+/*----------------------------------------------------------------------------
+ * EAS_SetDebugLevel()
+ *
+ * Sets the level for debug message output
+ *----------------------------------------------------------------------------
+*/
+
+void EAS_SetDebugLevel (int severity)
+{
+ severityLevel = severity;
+} /* end EAS_SetDebugLevel */
+
+/*----------------------------------------------------------------------------
+ * EAS_SetDebugFile()
+ *
+ * Redirect debugger output to the specified file.
+ *----------------------------------------------------------------------------
+*/
+void EAS_SetDebugFile (void *file, int flushAfterWrite)
+{
+ debugFile = (FILE*) file;
+ flush = flushAfterWrite;
+} /* end EAS_SetDebugFile */
+
diff --git a/arm-fm-22k/host_src/eas_report.h b/arm-fm-22k/host_src/eas_report.h
index 9d7c8e8..b603b12 100644
--- a/arm-fm-22k/host_src/eas_report.h
+++ b/arm-fm-22k/host_src/eas_report.h
@@ -1,15 +1,15 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_report.h
- *
- * Contents and purpose:
- * This file contains the debug message handling routines for the EAS library.
- * These routines should be modified as needed for your system.
- *
- * DO NOT MODIFY THIS FILE!
- *
- * Copyright 2005 Sonic Network Inc.
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_report.h
+ *
+ * Contents and purpose:
+ * This file contains the debug message handling routines for the EAS library.
+ * These routines should be modified as needed for your system.
+ *
+ * DO NOT MODIFY THIS FILE!
+ *
+ * Copyright 2005 Sonic Network Inc.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -22,56 +22,56 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 82 $
- * $Date: 2006-07-10 11:45:19 -0700 (Mon, 10 Jul 2006) $
- *----------------------------------------------------------------------------
-*/
-
-/* sentinel */
-#ifndef _EAS_REPORT_H
-#define _EAS_REPORT_H
-
-#define _EAS_SEVERITY_NOFILTER 0
-#define _EAS_SEVERITY_FATAL 1
-#define _EAS_SEVERITY_ERROR 2
-#define _EAS_SEVERITY_WARNING 3
-#define _EAS_SEVERITY_INFO 4
-#define _EAS_SEVERITY_DETAIL 5
-
-/* for C++ linkage */
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifndef _NO_DEBUG_PREPROCESSOR
-
-/* structure for included debug message header files */
-typedef struct
-{
- unsigned long m_nHashCode;
- int m_nSerialNum;
- char *m_pDebugMsg;
-} S_DEBUG_MESSAGES;
-
-/* debug message handling prototypes */
-extern void EAS_ReportEx (int severity, unsigned long hashCode, int serialNum, ...);
-
-#else
-
-/* these prototypes are used if the debug preprocessor is not used */
-extern void EAS_Report (int severity, const char* fmt, ...);
-extern void EAS_ReportX (int severity, const char* fmt, ...);
-
-#endif
-
-extern void EAS_SetDebugLevel (int severity);
-extern void EAS_SetDebugFile (void *file, int flushAfterWrite);
-
-#ifdef __cplusplus
-} /* end extern "C" */
-#endif
-
-#endif
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 82 $
+ * $Date: 2006-07-10 11:45:19 -0700 (Mon, 10 Jul 2006) $
+ *----------------------------------------------------------------------------
+*/
+
+/* sentinel */
+#ifndef _EAS_REPORT_H
+#define _EAS_REPORT_H
+
+#define _EAS_SEVERITY_NOFILTER 0
+#define _EAS_SEVERITY_FATAL 1
+#define _EAS_SEVERITY_ERROR 2
+#define _EAS_SEVERITY_WARNING 3
+#define _EAS_SEVERITY_INFO 4
+#define _EAS_SEVERITY_DETAIL 5
+
+/* for C++ linkage */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef _NO_DEBUG_PREPROCESSOR
+
+/* structure for included debug message header files */
+typedef struct
+{
+ unsigned long m_nHashCode;
+ int m_nSerialNum;
+ char *m_pDebugMsg;
+} S_DEBUG_MESSAGES;
+
+/* debug message handling prototypes */
+extern void EAS_ReportEx (int severity, unsigned long hashCode, int serialNum, ...);
+
+#else
+
+/* these prototypes are used if the debug preprocessor is not used */
+extern void EAS_Report (int severity, const char* fmt, ...);
+extern void EAS_ReportX (int severity, const char* fmt, ...);
+
+#endif
+
+extern void EAS_SetDebugLevel (int severity);
+extern void EAS_SetDebugFile (void *file, int flushAfterWrite);
+
+#ifdef __cplusplus
+} /* end extern "C" */
+#endif
+
+#endif
diff --git a/arm-fm-22k/host_src/eas_reverb.h b/arm-fm-22k/host_src/eas_reverb.h
index a2535fb..559abed 100644
--- a/arm-fm-22k/host_src/eas_reverb.h
+++ b/arm-fm-22k/host_src/eas_reverb.h
@@ -1,13 +1,13 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_reverb.h
- *
- * Contents and purpose:
- * Contains parameter enumerations for the Reverb effect
- *
- *
- * Copyright Sonic Network Inc. 2006
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_reverb.h
+ *
+ * Contents and purpose:
+ * Contains parameter enumerations for the Reverb effect
+ *
+ *
+ * Copyright Sonic Network Inc. 2006
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,35 +20,35 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 300 $
- * $Date: 2006-09-11 17:37:20 -0700 (Mon, 11 Sep 2006) $
- *----------------------------------------------------------------------------
-*/
-
-#ifndef _EAS_REVERB_H
-#define _EAS_REVERB_H
-
-
-/* enumerated parameter settings for Reverb effect */
-typedef enum
-{
- EAS_PARAM_REVERB_BYPASS,
- EAS_PARAM_REVERB_PRESET,
- EAS_PARAM_REVERB_WET,
- EAS_PARAM_REVERB_DRY
-} E_REVERB_PARAMS;
-
-
-typedef enum
-{
- EAS_PARAM_REVERB_LARGE_HALL,
- EAS_PARAM_REVERB_HALL,
- EAS_PARAM_REVERB_CHAMBER,
- EAS_PARAM_REVERB_ROOM,
-} E_REVERB_PRESETS;
-
-
-#endif /* _REVERB_H */
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 300 $
+ * $Date: 2006-09-11 17:37:20 -0700 (Mon, 11 Sep 2006) $
+ *----------------------------------------------------------------------------
+*/
+
+#ifndef _EAS_REVERB_H
+#define _EAS_REVERB_H
+
+
+/* enumerated parameter settings for Reverb effect */
+typedef enum
+{
+ EAS_PARAM_REVERB_BYPASS,
+ EAS_PARAM_REVERB_PRESET,
+ EAS_PARAM_REVERB_WET,
+ EAS_PARAM_REVERB_DRY
+} E_REVERB_PARAMS;
+
+
+typedef enum
+{
+ EAS_PARAM_REVERB_LARGE_HALL,
+ EAS_PARAM_REVERB_HALL,
+ EAS_PARAM_REVERB_CHAMBER,
+ EAS_PARAM_REVERB_ROOM,
+} E_REVERB_PRESETS;
+
+
+#endif /* _REVERB_H */
diff --git a/arm-fm-22k/host_src/eas_types.h b/arm-fm-22k/host_src/eas_types.h
index f0293ef..45fa4b2 100644
--- a/arm-fm-22k/host_src/eas_types.h
+++ b/arm-fm-22k/host_src/eas_types.h
@@ -1,17 +1,17 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_types.h
- *
- * Contents and purpose:
- * The public interface header for the EAS synthesizer.
- *
- * This header only contains declarations that are specific
- * to this implementation.
- *
- * DO NOT MODIFY THIS FILE!
- *
- * Copyright Sonic Network Inc. 2004
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_types.h
+ *
+ * Contents and purpose:
+ * The public interface header for the EAS synthesizer.
+ *
+ * This header only contains declarations that are specific
+ * to this implementation.
+ *
+ * DO NOT MODIFY THIS FILE!
+ *
+ * Copyright Sonic Network Inc. 2004
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -24,245 +24,245 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 726 $
- * $Date: 2007-06-14 23:10:46 -0700 (Thu, 14 Jun 2007) $
- *----------------------------------------------------------------------------
-*/
-
-#ifndef _EAS_TYPES_H
-#define _EAS_TYPES_H
-
-/* EAS_RESULT return codes */
-typedef long EAS_RESULT;
-#define EAS_SUCCESS 0
-#define EAS_FAILURE -1
-#define EAS_ERROR_INVALID_MODULE -2
-#define EAS_ERROR_MALLOC_FAILED -3
-#define EAS_ERROR_FILE_POS -4
-#define EAS_ERROR_INVALID_FILE_MODE -5
-#define EAS_ERROR_FILE_SEEK -6
-#define EAS_ERROR_FILE_LENGTH -7
-#define EAS_ERROR_NOT_IMPLEMENTED -8
-#define EAS_ERROR_CLOSE_FAILED -9
-#define EAS_ERROR_FILE_OPEN_FAILED -10
-#define EAS_ERROR_INVALID_HANDLE -11
-#define EAS_ERROR_NO_MIX_BUFFER -12
-#define EAS_ERROR_PARAMETER_RANGE -13
-#define EAS_ERROR_MAX_FILES_OPEN -14
-#define EAS_ERROR_UNRECOGNIZED_FORMAT -15
-#define EAS_BUFFER_SIZE_MISMATCH -16
-#define EAS_ERROR_FILE_FORMAT -17
-#define EAS_ERROR_SMF_NOT_INITIALIZED -18
-#define EAS_ERROR_LOCATE_BEYOND_END -19
-#define EAS_ERROR_INVALID_PCM_TYPE -20
-#define EAS_ERROR_MAX_PCM_STREAMS -21
-#define EAS_ERROR_NO_VOICE_ALLOCATED -22
-#define EAS_ERROR_INVALID_CHANNEL -23
-#define EAS_ERROR_ALREADY_STOPPED -24
-#define EAS_ERROR_FILE_READ_FAILED -25
-#define EAS_ERROR_HANDLE_INTEGRITY -26
-#define EAS_ERROR_MAX_STREAMS_OPEN -27
-#define EAS_ERROR_INVALID_PARAMETER -28
-#define EAS_ERROR_FEATURE_NOT_AVAILABLE -29
-#define EAS_ERROR_SOUND_LIBRARY -30
-#define EAS_ERROR_NOT_VALID_IN_THIS_STATE -31
-#define EAS_ERROR_NO_VIRTUAL_SYNTHESIZER -32
-#define EAS_ERROR_FILE_ALREADY_OPEN -33
-#define EAS_ERROR_FILE_ALREADY_CLOSED -34
-#define EAS_ERROR_INCOMPATIBLE_VERSION -35
-#define EAS_ERROR_QUEUE_IS_FULL -36
-#define EAS_ERROR_QUEUE_IS_EMPTY -37
-#define EAS_ERROR_FEATURE_ALREADY_ACTIVE -38
-
-/* special return codes */
-#define EAS_EOF 3
-#define EAS_STREAM_BUFFERING 4
-#define EAS_BUFFER_FULL 5
-
-/* EAS_STATE return codes */
-typedef long EAS_STATE;
-typedef enum
-{
- EAS_STATE_READY = 0,
- EAS_STATE_PLAY,
- EAS_STATE_STOPPING,
- EAS_STATE_PAUSING,
- EAS_STATE_STOPPED,
- EAS_STATE_PAUSED,
- EAS_STATE_OPEN,
- EAS_STATE_ERROR,
- EAS_STATE_EMPTY
-} E_EAS_STATE;
-
-/* constants */
-#ifndef EAS_CONST
-#define EAS_CONST const
-#endif
-
-/* definition for public interface functions */
-#ifndef EAS_PUBLIC
-#define EAS_PUBLIC
-#endif
-
-/* boolean values */
-typedef unsigned EAS_BOOL;
-typedef unsigned char EAS_BOOL8;
-
-#define EAS_FALSE 0
-#define EAS_TRUE 1
-
-/* scalar variable definitions */
-typedef unsigned char EAS_U8;
-typedef signed char EAS_I8;
-typedef char EAS_CHAR;
-
-typedef unsigned short EAS_U16;
-typedef short EAS_I16;
-
-typedef unsigned long EAS_U32;
-typedef long EAS_I32;
-
-typedef unsigned EAS_UINT;
-typedef int EAS_INT;
-typedef long EAS_LONG;
-
-/* audio output type */
-typedef short EAS_PCM;
-
-/* file open modes */
-typedef EAS_I32 EAS_FILE_MODE;
-#define EAS_FILE_READ 1
-#define EAS_FILE_WRITE 2
-
-/* file locator e.g. filename or memory pointer */
-typedef const void *EAS_FILE_LOCATOR;
-
-/* handle to stream */
-typedef struct s_eas_stream_tag *EAS_HANDLE;
-
-/* handle to file */
-typedef struct eas_hw_file_tag *EAS_FILE_HANDLE;
-
-/* handle for synthesizer data */
-typedef struct s_eas_data_tag *EAS_DATA_HANDLE;
-
-/* handle to persistent data for host wrapper interface */
-typedef struct eas_hw_inst_data_tag *EAS_HW_DATA_HANDLE;
-
-/* handle to sound library */
-typedef struct s_eas_sndlib_tag *EAS_SNDLIB_HANDLE;
-typedef struct s_eas_dls_tag *EAS_DLSLIB_HANDLE;
-
-/* pointer to frame buffer - used in split architecture only */
-typedef struct s_eas_frame_buffer_tag *EAS_FRAME_BUFFER_HANDLE;
-
-/* untyped pointer for instance data */
-typedef void *EAS_VOID_PTR;
-
-/* inline functions */
-#ifndef EAS_INLINE
-#if defined (__XCC__)
-#define EAS_INLINE __inline__
-#elif defined (__GNUC__)
-#define EAS_INLINE inline static
-#else
-#define EAS_INLINE __inline
-#endif
-#endif
-
-/* define NULL value */
-#ifndef NULL
-#define NULL 0
-#endif
-
-/* metadata types for metadata return codes */
-typedef enum
-{
- EAS_METADATA_UNKNOWN = 0,
- EAS_METADATA_TITLE,
- EAS_METADATA_AUTHOR,
- EAS_METADATA_COPYRIGHT,
- EAS_METADATA_LYRIC,
- EAS_METADATA_TEXT
-} E_EAS_METADATA_TYPE;
-
-/* metadata callback function */
-typedef void (*EAS_METADATA_CBFUNC) (E_EAS_METADATA_TYPE metaDataType, char *metaDataBuf, EAS_VOID_PTR pUserData);
-
-/* file types for metadata return codes */
-typedef enum
-{
- EAS_FILE_UNKNOWN = 0,
- EAS_FILE_SMF0,
- EAS_FILE_SMF1,
- EAS_FILE_SMAF_UNKNOWN,
- EAS_FILE_SMAF_MA2,
- EAS_FILE_SMAF_MA3,
- EAS_FILE_SMAF_MA5,
- EAS_FILE_CMX,
- EAS_FILE_MFI,
- EAS_FILE_OTA,
- EAS_FILE_IMELODY,
- EAS_FILE_RTTTL,
- EAS_FILE_XMF0,
- EAS_FILE_XMF1,
- EAS_FILE_WAVE_PCM,
- EAS_FILE_WAVE_IMA_ADPCM,
- EAS_FILE_MMAPI_TONE_CONTROL
-} E_EAS_FILE_TYPE;
-
-/* enumeration for synthesizers */
-typedef enum
-{
- EAS_MCU_SYNTH = 0,
- EAS_DSP_SYNTH
-} E_SYNTHESIZER;
-
-/* external audio callback program change */
-typedef struct s_ext_audio_prg_chg_tag
-{
- EAS_U16 bank;
- EAS_U8 program;
- EAS_U8 channel;
-} S_EXT_AUDIO_PRG_CHG;
-
-/* external audio callback event */
-typedef struct s_ext_audio_event_tag
-{
- EAS_U8 channel;
- EAS_U8 note;
- EAS_U8 velocity;
- EAS_BOOL8 noteOn;
-} S_EXT_AUDIO_EVENT;
-
-typedef struct s_midi_controllers_tag
-{
- EAS_U8 modWheel; /* CC1 */
- EAS_U8 volume; /* CC7 */
- EAS_U8 pan; /* CC10 */
- EAS_U8 expression; /* CC11 */
- EAS_U8 channelPressure; /* MIDI channel pressure */
-
-#ifdef _REVERB
- EAS_U8 reverbSend; /* CC91 */
-#endif
-
-#ifdef _CHORUS
- EAS_U8 chorusSend; /* CC93 */
-#endif
-} S_MIDI_CONTROLLERS;
-
-/* iMode play modes enumeration for EAS_SetPlayMode */
-typedef enum
-{
- IMODE_PLAY_ALL = 0,
- IMODE_PLAY_PARTIAL
-} E_I_MODE_PLAY_MODE;
-
-typedef EAS_BOOL (*EAS_EXT_PRG_CHG_FUNC) (EAS_VOID_PTR pInstData, S_EXT_AUDIO_PRG_CHG *pPrgChg);
-typedef EAS_BOOL (*EAS_EXT_EVENT_FUNC) (EAS_VOID_PTR pInstData, S_EXT_AUDIO_EVENT *pEvent);
-
-#endif /* #ifndef _EAS_TYPES_H */
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 726 $
+ * $Date: 2007-06-14 23:10:46 -0700 (Thu, 14 Jun 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+#ifndef _EAS_TYPES_H
+#define _EAS_TYPES_H
+
+/* EAS_RESULT return codes */
+typedef long EAS_RESULT;
+#define EAS_SUCCESS 0
+#define EAS_FAILURE -1
+#define EAS_ERROR_INVALID_MODULE -2
+#define EAS_ERROR_MALLOC_FAILED -3
+#define EAS_ERROR_FILE_POS -4
+#define EAS_ERROR_INVALID_FILE_MODE -5
+#define EAS_ERROR_FILE_SEEK -6
+#define EAS_ERROR_FILE_LENGTH -7
+#define EAS_ERROR_NOT_IMPLEMENTED -8
+#define EAS_ERROR_CLOSE_FAILED -9
+#define EAS_ERROR_FILE_OPEN_FAILED -10
+#define EAS_ERROR_INVALID_HANDLE -11
+#define EAS_ERROR_NO_MIX_BUFFER -12
+#define EAS_ERROR_PARAMETER_RANGE -13
+#define EAS_ERROR_MAX_FILES_OPEN -14
+#define EAS_ERROR_UNRECOGNIZED_FORMAT -15
+#define EAS_BUFFER_SIZE_MISMATCH -16
+#define EAS_ERROR_FILE_FORMAT -17
+#define EAS_ERROR_SMF_NOT_INITIALIZED -18
+#define EAS_ERROR_LOCATE_BEYOND_END -19
+#define EAS_ERROR_INVALID_PCM_TYPE -20
+#define EAS_ERROR_MAX_PCM_STREAMS -21
+#define EAS_ERROR_NO_VOICE_ALLOCATED -22
+#define EAS_ERROR_INVALID_CHANNEL -23
+#define EAS_ERROR_ALREADY_STOPPED -24
+#define EAS_ERROR_FILE_READ_FAILED -25
+#define EAS_ERROR_HANDLE_INTEGRITY -26
+#define EAS_ERROR_MAX_STREAMS_OPEN -27
+#define EAS_ERROR_INVALID_PARAMETER -28
+#define EAS_ERROR_FEATURE_NOT_AVAILABLE -29
+#define EAS_ERROR_SOUND_LIBRARY -30
+#define EAS_ERROR_NOT_VALID_IN_THIS_STATE -31
+#define EAS_ERROR_NO_VIRTUAL_SYNTHESIZER -32
+#define EAS_ERROR_FILE_ALREADY_OPEN -33
+#define EAS_ERROR_FILE_ALREADY_CLOSED -34
+#define EAS_ERROR_INCOMPATIBLE_VERSION -35
+#define EAS_ERROR_QUEUE_IS_FULL -36
+#define EAS_ERROR_QUEUE_IS_EMPTY -37
+#define EAS_ERROR_FEATURE_ALREADY_ACTIVE -38
+
+/* special return codes */
+#define EAS_EOF 3
+#define EAS_STREAM_BUFFERING 4
+#define EAS_BUFFER_FULL 5
+
+/* EAS_STATE return codes */
+typedef long EAS_STATE;
+typedef enum
+{
+ EAS_STATE_READY = 0,
+ EAS_STATE_PLAY,
+ EAS_STATE_STOPPING,
+ EAS_STATE_PAUSING,
+ EAS_STATE_STOPPED,
+ EAS_STATE_PAUSED,
+ EAS_STATE_OPEN,
+ EAS_STATE_ERROR,
+ EAS_STATE_EMPTY
+} E_EAS_STATE;
+
+/* constants */
+#ifndef EAS_CONST
+#define EAS_CONST const
+#endif
+
+/* definition for public interface functions */
+#ifndef EAS_PUBLIC
+#define EAS_PUBLIC
+#endif
+
+/* boolean values */
+typedef unsigned EAS_BOOL;
+typedef unsigned char EAS_BOOL8;
+
+#define EAS_FALSE 0
+#define EAS_TRUE 1
+
+/* scalar variable definitions */
+typedef unsigned char EAS_U8;
+typedef signed char EAS_I8;
+typedef char EAS_CHAR;
+
+typedef unsigned short EAS_U16;
+typedef short EAS_I16;
+
+typedef unsigned long EAS_U32;
+typedef long EAS_I32;
+
+typedef unsigned EAS_UINT;
+typedef int EAS_INT;
+typedef long EAS_LONG;
+
+/* audio output type */
+typedef short EAS_PCM;
+
+/* file open modes */
+typedef EAS_I32 EAS_FILE_MODE;
+#define EAS_FILE_READ 1
+#define EAS_FILE_WRITE 2
+
+/* file locator e.g. filename or memory pointer */
+typedef const void *EAS_FILE_LOCATOR;
+
+/* handle to stream */
+typedef struct s_eas_stream_tag *EAS_HANDLE;
+
+/* handle to file */
+typedef struct eas_hw_file_tag *EAS_FILE_HANDLE;
+
+/* handle for synthesizer data */
+typedef struct s_eas_data_tag *EAS_DATA_HANDLE;
+
+/* handle to persistent data for host wrapper interface */
+typedef struct eas_hw_inst_data_tag *EAS_HW_DATA_HANDLE;
+
+/* handle to sound library */
+typedef struct s_eas_sndlib_tag *EAS_SNDLIB_HANDLE;
+typedef struct s_eas_dls_tag *EAS_DLSLIB_HANDLE;
+
+/* pointer to frame buffer - used in split architecture only */
+typedef struct s_eas_frame_buffer_tag *EAS_FRAME_BUFFER_HANDLE;
+
+/* untyped pointer for instance data */
+typedef void *EAS_VOID_PTR;
+
+/* inline functions */
+#ifndef EAS_INLINE
+#if defined (__XCC__)
+#define EAS_INLINE __inline__
+#elif defined (__GNUC__)
+#define EAS_INLINE inline static
+#else
+#define EAS_INLINE __inline
+#endif
+#endif
+
+/* define NULL value */
+#ifndef NULL
+#define NULL 0
+#endif
+
+/* metadata types for metadata return codes */
+typedef enum
+{
+ EAS_METADATA_UNKNOWN = 0,
+ EAS_METADATA_TITLE,
+ EAS_METADATA_AUTHOR,
+ EAS_METADATA_COPYRIGHT,
+ EAS_METADATA_LYRIC,
+ EAS_METADATA_TEXT
+} E_EAS_METADATA_TYPE;
+
+/* metadata callback function */
+typedef void (*EAS_METADATA_CBFUNC) (E_EAS_METADATA_TYPE metaDataType, char *metaDataBuf, EAS_VOID_PTR pUserData);
+
+/* file types for metadata return codes */
+typedef enum
+{
+ EAS_FILE_UNKNOWN = 0,
+ EAS_FILE_SMF0,
+ EAS_FILE_SMF1,
+ EAS_FILE_SMAF_UNKNOWN,
+ EAS_FILE_SMAF_MA2,
+ EAS_FILE_SMAF_MA3,
+ EAS_FILE_SMAF_MA5,
+ EAS_FILE_CMX,
+ EAS_FILE_MFI,
+ EAS_FILE_OTA,
+ EAS_FILE_IMELODY,
+ EAS_FILE_RTTTL,
+ EAS_FILE_XMF0,
+ EAS_FILE_XMF1,
+ EAS_FILE_WAVE_PCM,
+ EAS_FILE_WAVE_IMA_ADPCM,
+ EAS_FILE_MMAPI_TONE_CONTROL
+} E_EAS_FILE_TYPE;
+
+/* enumeration for synthesizers */
+typedef enum
+{
+ EAS_MCU_SYNTH = 0,
+ EAS_DSP_SYNTH
+} E_SYNTHESIZER;
+
+/* external audio callback program change */
+typedef struct s_ext_audio_prg_chg_tag
+{
+ EAS_U16 bank;
+ EAS_U8 program;
+ EAS_U8 channel;
+} S_EXT_AUDIO_PRG_CHG;
+
+/* external audio callback event */
+typedef struct s_ext_audio_event_tag
+{
+ EAS_U8 channel;
+ EAS_U8 note;
+ EAS_U8 velocity;
+ EAS_BOOL8 noteOn;
+} S_EXT_AUDIO_EVENT;
+
+typedef struct s_midi_controllers_tag
+{
+ EAS_U8 modWheel; /* CC1 */
+ EAS_U8 volume; /* CC7 */
+ EAS_U8 pan; /* CC10 */
+ EAS_U8 expression; /* CC11 */
+ EAS_U8 channelPressure; /* MIDI channel pressure */
+
+#ifdef _REVERB
+ EAS_U8 reverbSend; /* CC91 */
+#endif
+
+#ifdef _CHORUS
+ EAS_U8 chorusSend; /* CC93 */
+#endif
+} S_MIDI_CONTROLLERS;
+
+/* iMode play modes enumeration for EAS_SetPlayMode */
+typedef enum
+{
+ IMODE_PLAY_ALL = 0,
+ IMODE_PLAY_PARTIAL
+} E_I_MODE_PLAY_MODE;
+
+typedef EAS_BOOL (*EAS_EXT_PRG_CHG_FUNC) (EAS_VOID_PTR pInstData, S_EXT_AUDIO_PRG_CHG *pPrgChg);
+typedef EAS_BOOL (*EAS_EXT_EVENT_FUNC) (EAS_VOID_PTR pInstData, S_EXT_AUDIO_EVENT *pEvent);
+
+#endif /* #ifndef _EAS_TYPES_H */
diff --git a/arm-fm-22k/host_src/eas_wave.c b/arm-fm-22k/host_src/eas_wave.c
index 02fed6e..4f6ffbd 100644
--- a/arm-fm-22k/host_src/eas_wave.c
+++ b/arm-fm-22k/host_src/eas_wave.c
@@ -1,13 +1,13 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_wave.c
- *
- * Contents and purpose:
- * This module contains .WAV file functions for the EAS synthesizer
- * test harness.
- *
- * Copyright Sonic Network Inc. 2005
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_wave.c
+ *
+ * Contents and purpose:
+ * This module contains .WAV file functions for the EAS synthesizer
+ * test harness.
+ *
+ * Copyright Sonic Network Inc. 2005
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,404 +20,404 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 658 $
- * $Date: 2007-04-24 13:35:49 -0700 (Tue, 24 Apr 2007) $
- *----------------------------------------------------------------------------
-*/
-
-/* lint complaints about most C library headers, so we use our own during lint step */
-#ifdef _lint
-#include "lint_stdlib.h"
-#else
-#include <stdio.h>
-#include <stdlib.h>
-#endif
-
-#include "eas_wave.h"
-
-/* .WAV file format tags */
-const EAS_U32 riffTag = 0x46464952;
-const EAS_U32 waveTag = 0x45564157;
-const EAS_U32 fmtTag = 0x20746d66;
-const EAS_U32 dataTag = 0x61746164;
-
-#ifdef _BIG_ENDIAN
-/*----------------------------------------------------------------------------
- * FlipDWord()
- *----------------------------------------------------------------------------
- * Purpose: Endian flip a DWORD for big-endian processors
- *
- * Inputs:
- *
- * Outputs:
- *
- *----------------------------------------------------------------------------
-*/
-static void FlipDWord (EAS_U32 *pValue)
-{
- EAS_U8 *p;
- EAS_U32 temp;
-
- p = (EAS_U8*) pValue;
- temp = (((((p[3] << 8) | p[2]) << 8) | p[1]) << 8) | p[0];
- *pValue = temp;
-}
-
-/*----------------------------------------------------------------------------
- * FlipWord()
- *----------------------------------------------------------------------------
- * Purpose: Endian flip a WORD for big-endian processors
- *
- * Inputs:
- *
- * Outputs:
- *
- *----------------------------------------------------------------------------
-*/
-static void FlipWord (EAS_U16 *pValue)
-{
- EAS_U8 *p;
- EAS_U16 temp;
-
- p = (EAS_U8*) pValue;
- temp = (p[1] << 8) | p[0];
- *pValue = temp;
-}
-
-/*----------------------------------------------------------------------------
- * FlipWaveHeader()
- *----------------------------------------------------------------------------
- * Purpose: Endian flip the wave header for big-endian processors
- *
- * Inputs:
- *
- * Outputs:
- *
- *----------------------------------------------------------------------------
-*/
-static void FlipWaveHeader (WAVE_HEADER *p)
-{
-
- FlipDWord(&p->nRiffTag);
- FlipDWord(&p->nRiffSize);
- FlipDWord(&p->nWaveTag);
- FlipDWord(&p->nFmtTag);
- FlipDWord(&p->nFmtSize);
- FlipDWord(&p->nDataTag);
- FlipDWord(&p->nDataSize);
- FlipWord(&p->fc.wFormatTag);
- FlipWord(&p->fc.nChannels);
- FlipDWord(&p->fc.nSamplesPerSec);
- FlipDWord(&p->fc.nAvgBytesPerSec);
- FlipWord(&p->fc.nBlockAlign);
- FlipWord(&p->fc.wBitsPerSample);
-
-}
-#endif
-
-/*----------------------------------------------------------------------------
- * WaveFileCreate()
- *----------------------------------------------------------------------------
- * Purpose: Opens a wave file for writing and writes the header
- *
- * Inputs:
- *
- * Outputs:
- *
- *----------------------------------------------------------------------------
-*/
-
-WAVE_FILE *WaveFileCreate (const char *filename, EAS_I32 nChannels, EAS_I32 nSamplesPerSec, EAS_I32 wBitsPerSample)
-{
- WAVE_FILE *wFile;
-
- /* allocate memory */
- wFile = malloc(sizeof(WAVE_FILE));
- if (!wFile)
- return NULL;
- wFile->write = EAS_TRUE;
-
- /* create the file */
- wFile->file = fopen(filename,"wb");
- if (!wFile->file)
- {
- free(wFile);
- return NULL;
- }
-
- /* initialize PCM format .WAV file header */
- wFile->wh.nRiffTag = riffTag;
- wFile->wh.nRiffSize = sizeof(WAVE_HEADER) - 8;
- wFile->wh.nWaveTag = waveTag;
- wFile->wh.nFmtTag = fmtTag;
- wFile->wh.nFmtSize = sizeof(FMT_CHUNK);
-
- /* initalize 'fmt' chunk */
- wFile->wh.fc.wFormatTag = 1;
- wFile->wh.fc.nChannels = (EAS_U16) nChannels;
- wFile->wh.fc.nSamplesPerSec = (EAS_U32) nSamplesPerSec;
- wFile->wh.fc.wBitsPerSample = (EAS_U16) wBitsPerSample;
- wFile->wh.fc.nBlockAlign = (EAS_U16) (nChannels * (EAS_U16) (wBitsPerSample / 8));
- wFile->wh.fc.nAvgBytesPerSec = wFile->wh.fc.nBlockAlign * (EAS_U32) nSamplesPerSec;
-
- /* initialize 'data' chunk */
- wFile->wh.nDataTag = dataTag;
- wFile->wh.nDataSize = 0;
-
-#ifdef _BIG_ENDIAN
- FlipWaveHeader(&wFile->wh);
-#endif
-
- /* write the header */
- if (fwrite(&wFile->wh, sizeof(WAVE_HEADER), 1, wFile->file) != 1)
- {
- fclose(wFile->file);
- free(wFile);
- return NULL;
- }
-
-#ifdef _BIG_ENDIAN
- FlipWaveHeader(&wFile->wh);
-#endif
-
- /* return the file handle */
- return wFile;
-} /* end WaveFileCreate */
-
-/*----------------------------------------------------------------------------
- * WaveFileWrite()
- *----------------------------------------------------------------------------
- * Purpose: Writes data to the wave file
- *
- * Inputs:
- *
- * Outputs:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_I32 WaveFileWrite (WAVE_FILE *wFile, void *buffer, EAS_I32 n)
-{
- EAS_I32 count;
-
- /* make sure we have an open file */
- if (wFile == NULL)
- {
- return 0;
- }
-
-#ifdef _BIG_ENDIAN
- {
- EAS_I32 i;
- EAS_U16 *p;
- p = buffer;
- i = n >> 1;
- while (i--)
- FlipWord(p++);
- }
-#endif
-
- /* write the data */
- count = (EAS_I32) fwrite(buffer, 1, (size_t) n, wFile->file);
-
- /* add the number of bytes written */
- wFile->wh.nRiffSize += (EAS_U32) count;
- wFile->wh.nDataSize += (EAS_U32) count;
-
- /* return the count of bytes written */
- return count;
-} /* end WriteWaveHeader */
-
-/*----------------------------------------------------------------------------
- * WaveFileClose()
- *----------------------------------------------------------------------------
- * Purpose: Opens a wave file for writing and writes the header
- *
- * Inputs:
- *
- * Outputs:
- *
- *----------------------------------------------------------------------------
-*/
-
-EAS_BOOL WaveFileClose (WAVE_FILE *wFile)
-{
- EAS_I32 count = 1;
-
- /* return to beginning of file and write the header */
- if (wFile->write)
- {
- if (fseek(wFile->file, 0L, SEEK_SET) == 0)
- {
-
-#ifdef _BIG_ENDIAN
- FlipWaveHeader(&wFile->wh);
-#endif
- count = (EAS_I32) fwrite(&wFile->wh, sizeof(WAVE_HEADER), 1, wFile->file);
-#ifdef _BIG_ENDIAN
- FlipWaveHeader(&wFile->wh);
-#endif
- }
- }
-
- /* close the file */
- if (fclose(wFile->file) != 0)
- count = 0;
-
- /* free the memory */
- free(wFile);
-
- /* return the file handle */
- return (count == 1 ? EAS_TRUE : EAS_FALSE);
-} /* end WaveFileClose */
-
-#ifdef _WAVE_FILE_READ
-#ifdef _BIG_ENDIAN
-#error "WaveFileOpen not currently supported on big-endian processors"
-#endif
-/*----------------------------------------------------------------------------
- * WaveFileOpen()
- *----------------------------------------------------------------------------
- * Purpose: Opens a wave file for reading and reads the header
- *
- * Inputs:
- *
- * Outputs:
- *
- *----------------------------------------------------------------------------
-*/
-
-WAVE_FILE *WaveFileOpen (const char *filename)
-{
- WAVE_FILE *wFile;
- struct
- {
- EAS_U32 tag;
- EAS_U32 size;
- } chunk;
- EAS_U32 tag;
- EAS_I32 startChunkPos;
- EAS_INT state;
- EAS_BOOL done;
-
- /* allocate memory */
- wFile = malloc(sizeof(WAVE_FILE));
- if (!wFile)
- return NULL;
-
- /* open the file */
- wFile->write = EAS_FALSE;
- wFile->file = fopen(filename,"rb");
- if (!wFile->file)
- {
- free(wFile);
- return NULL;
- }
-
- /* make lint happy */
- chunk.tag = chunk.size = 0;
- startChunkPos = 0;
-
- /* read the RIFF tag and file size */
- state = 0;
- done = EAS_FALSE;
- while (!done)
- {
-
- switch(state)
- {
- /* read the RIFF tag */
- case 0:
- if (fread(&chunk, sizeof(chunk), 1, wFile->file) != 1)
- done = EAS_TRUE;
- else
- {
- if (chunk.tag != riffTag)
- done = EAS_TRUE;
- else
- state++;
- }
- break;
-
- /* read the WAVE tag */
- case 1:
- if (fread(&tag, sizeof(tag), 1, wFile->file) != 1)
- done = EAS_TRUE;
- else
- {
- if (tag != waveTag)
- done = EAS_TRUE;
- else
- state++;
- }
- break;
-
- /* looking for fmt chunk */
- case 2:
- if (fread(&chunk, sizeof(chunk), 1, wFile->file) != 1)
- done = EAS_TRUE;
- else
- {
- startChunkPos = ftell(wFile->file);
-
- /* not fmt tag, skip it */
- if (chunk.tag != fmtTag)
- fseek(wFile->file, startChunkPos + (EAS_I32) chunk.size, SEEK_SET);
- else
- state++;
- }
- break;
-
- /* read fmt chunk */
- case 3:
- if (fread(&wFile->wh.fc, sizeof(FMT_CHUNK), 1, wFile->file) != 1)
- done = EAS_TRUE;
- else
- {
- fseek(wFile->file, startChunkPos + (EAS_I32) chunk.size, SEEK_SET);
- state++;
- }
- break;
-
- /* looking for data chunk */
- case 4:
- if (fread(&chunk, sizeof(chunk), 1, wFile->file) != 1)
- done = EAS_TRUE;
- else
- {
- startChunkPos = ftell(wFile->file);
-
- /* not data tag, skip it */
- if (chunk.tag != dataTag)
- fseek(wFile->file, startChunkPos + (EAS_I32) chunk.size, SEEK_SET);
- else
- {
- wFile->dataSize = chunk.size;
- state++;
- done = EAS_TRUE;
- }
- }
- break;
-
- default:
- done = EAS_TRUE;
- break;
- }
- }
-
- /* if not final state, an error occurred */
- if (state != 5)
- {
- fclose(wFile->file);
- free(wFile);
- return NULL;
- }
-
- /* return the file handle */
- return wFile;
-} /* end WaveFileOpen */
-#endif
-
-
-
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 658 $
+ * $Date: 2007-04-24 13:35:49 -0700 (Tue, 24 Apr 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+/* lint complaints about most C library headers, so we use our own during lint step */
+#ifdef _lint
+#include "lint_stdlib.h"
+#else
+#include <stdio.h>
+#include <stdlib.h>
+#endif
+
+#include "eas_wave.h"
+
+/* .WAV file format tags */
+const EAS_U32 riffTag = 0x46464952;
+const EAS_U32 waveTag = 0x45564157;
+const EAS_U32 fmtTag = 0x20746d66;
+const EAS_U32 dataTag = 0x61746164;
+
+#ifdef _BIG_ENDIAN
+/*----------------------------------------------------------------------------
+ * FlipDWord()
+ *----------------------------------------------------------------------------
+ * Purpose: Endian flip a DWORD for big-endian processors
+ *
+ * Inputs:
+ *
+ * Outputs:
+ *
+ *----------------------------------------------------------------------------
+*/
+static void FlipDWord (EAS_U32 *pValue)
+{
+ EAS_U8 *p;
+ EAS_U32 temp;
+
+ p = (EAS_U8*) pValue;
+ temp = (((((p[3] << 8) | p[2]) << 8) | p[1]) << 8) | p[0];
+ *pValue = temp;
+}
+
+/*----------------------------------------------------------------------------
+ * FlipWord()
+ *----------------------------------------------------------------------------
+ * Purpose: Endian flip a WORD for big-endian processors
+ *
+ * Inputs:
+ *
+ * Outputs:
+ *
+ *----------------------------------------------------------------------------
+*/
+static void FlipWord (EAS_U16 *pValue)
+{
+ EAS_U8 *p;
+ EAS_U16 temp;
+
+ p = (EAS_U8*) pValue;
+ temp = (p[1] << 8) | p[0];
+ *pValue = temp;
+}
+
+/*----------------------------------------------------------------------------
+ * FlipWaveHeader()
+ *----------------------------------------------------------------------------
+ * Purpose: Endian flip the wave header for big-endian processors
+ *
+ * Inputs:
+ *
+ * Outputs:
+ *
+ *----------------------------------------------------------------------------
+*/
+static void FlipWaveHeader (WAVE_HEADER *p)
+{
+
+ FlipDWord(&p->nRiffTag);
+ FlipDWord(&p->nRiffSize);
+ FlipDWord(&p->nWaveTag);
+ FlipDWord(&p->nFmtTag);
+ FlipDWord(&p->nFmtSize);
+ FlipDWord(&p->nDataTag);
+ FlipDWord(&p->nDataSize);
+ FlipWord(&p->fc.wFormatTag);
+ FlipWord(&p->fc.nChannels);
+ FlipDWord(&p->fc.nSamplesPerSec);
+ FlipDWord(&p->fc.nAvgBytesPerSec);
+ FlipWord(&p->fc.nBlockAlign);
+ FlipWord(&p->fc.wBitsPerSample);
+
+}
+#endif
+
+/*----------------------------------------------------------------------------
+ * WaveFileCreate()
+ *----------------------------------------------------------------------------
+ * Purpose: Opens a wave file for writing and writes the header
+ *
+ * Inputs:
+ *
+ * Outputs:
+ *
+ *----------------------------------------------------------------------------
+*/
+
+WAVE_FILE *WaveFileCreate (const char *filename, EAS_I32 nChannels, EAS_I32 nSamplesPerSec, EAS_I32 wBitsPerSample)
+{
+ WAVE_FILE *wFile;
+
+ /* allocate memory */
+ wFile = malloc(sizeof(WAVE_FILE));
+ if (!wFile)
+ return NULL;
+ wFile->write = EAS_TRUE;
+
+ /* create the file */
+ wFile->file = fopen(filename,"wb");
+ if (!wFile->file)
+ {
+ free(wFile);
+ return NULL;
+ }
+
+ /* initialize PCM format .WAV file header */
+ wFile->wh.nRiffTag = riffTag;
+ wFile->wh.nRiffSize = sizeof(WAVE_HEADER) - 8;
+ wFile->wh.nWaveTag = waveTag;
+ wFile->wh.nFmtTag = fmtTag;
+ wFile->wh.nFmtSize = sizeof(FMT_CHUNK);
+
+ /* initalize 'fmt' chunk */
+ wFile->wh.fc.wFormatTag = 1;
+ wFile->wh.fc.nChannels = (EAS_U16) nChannels;
+ wFile->wh.fc.nSamplesPerSec = (EAS_U32) nSamplesPerSec;
+ wFile->wh.fc.wBitsPerSample = (EAS_U16) wBitsPerSample;
+ wFile->wh.fc.nBlockAlign = (EAS_U16) (nChannels * (EAS_U16) (wBitsPerSample / 8));
+ wFile->wh.fc.nAvgBytesPerSec = wFile->wh.fc.nBlockAlign * (EAS_U32) nSamplesPerSec;
+
+ /* initialize 'data' chunk */
+ wFile->wh.nDataTag = dataTag;
+ wFile->wh.nDataSize = 0;
+
+#ifdef _BIG_ENDIAN
+ FlipWaveHeader(&wFile->wh);
+#endif
+
+ /* write the header */
+ if (fwrite(&wFile->wh, sizeof(WAVE_HEADER), 1, wFile->file) != 1)
+ {
+ fclose(wFile->file);
+ free(wFile);
+ return NULL;
+ }
+
+#ifdef _BIG_ENDIAN
+ FlipWaveHeader(&wFile->wh);
+#endif
+
+ /* return the file handle */
+ return wFile;
+} /* end WaveFileCreate */
+
+/*----------------------------------------------------------------------------
+ * WaveFileWrite()
+ *----------------------------------------------------------------------------
+ * Purpose: Writes data to the wave file
+ *
+ * Inputs:
+ *
+ * Outputs:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_I32 WaveFileWrite (WAVE_FILE *wFile, void *buffer, EAS_I32 n)
+{
+ EAS_I32 count;
+
+ /* make sure we have an open file */
+ if (wFile == NULL)
+ {
+ return 0;
+ }
+
+#ifdef _BIG_ENDIAN
+ {
+ EAS_I32 i;
+ EAS_U16 *p;
+ p = buffer;
+ i = n >> 1;
+ while (i--)
+ FlipWord(p++);
+ }
+#endif
+
+ /* write the data */
+ count = (EAS_I32) fwrite(buffer, 1, (size_t) n, wFile->file);
+
+ /* add the number of bytes written */
+ wFile->wh.nRiffSize += (EAS_U32) count;
+ wFile->wh.nDataSize += (EAS_U32) count;
+
+ /* return the count of bytes written */
+ return count;
+} /* end WriteWaveHeader */
+
+/*----------------------------------------------------------------------------
+ * WaveFileClose()
+ *----------------------------------------------------------------------------
+ * Purpose: Opens a wave file for writing and writes the header
+ *
+ * Inputs:
+ *
+ * Outputs:
+ *
+ *----------------------------------------------------------------------------
+*/
+
+EAS_BOOL WaveFileClose (WAVE_FILE *wFile)
+{
+ EAS_I32 count = 1;
+
+ /* return to beginning of file and write the header */
+ if (wFile->write)
+ {
+ if (fseek(wFile->file, 0L, SEEK_SET) == 0)
+ {
+
+#ifdef _BIG_ENDIAN
+ FlipWaveHeader(&wFile->wh);
+#endif
+ count = (EAS_I32) fwrite(&wFile->wh, sizeof(WAVE_HEADER), 1, wFile->file);
+#ifdef _BIG_ENDIAN
+ FlipWaveHeader(&wFile->wh);
+#endif
+ }
+ }
+
+ /* close the file */
+ if (fclose(wFile->file) != 0)
+ count = 0;
+
+ /* free the memory */
+ free(wFile);
+
+ /* return the file handle */
+ return (count == 1 ? EAS_TRUE : EAS_FALSE);
+} /* end WaveFileClose */
+
+#ifdef _WAVE_FILE_READ
+#ifdef _BIG_ENDIAN
+#error "WaveFileOpen not currently supported on big-endian processors"
+#endif
+/*----------------------------------------------------------------------------
+ * WaveFileOpen()
+ *----------------------------------------------------------------------------
+ * Purpose: Opens a wave file for reading and reads the header
+ *
+ * Inputs:
+ *
+ * Outputs:
+ *
+ *----------------------------------------------------------------------------
+*/
+
+WAVE_FILE *WaveFileOpen (const char *filename)
+{
+ WAVE_FILE *wFile;
+ struct
+ {
+ EAS_U32 tag;
+ EAS_U32 size;
+ } chunk;
+ EAS_U32 tag;
+ EAS_I32 startChunkPos;
+ EAS_INT state;
+ EAS_BOOL done;
+
+ /* allocate memory */
+ wFile = malloc(sizeof(WAVE_FILE));
+ if (!wFile)
+ return NULL;
+
+ /* open the file */
+ wFile->write = EAS_FALSE;
+ wFile->file = fopen(filename,"rb");
+ if (!wFile->file)
+ {
+ free(wFile);
+ return NULL;
+ }
+
+ /* make lint happy */
+ chunk.tag = chunk.size = 0;
+ startChunkPos = 0;
+
+ /* read the RIFF tag and file size */
+ state = 0;
+ done = EAS_FALSE;
+ while (!done)
+ {
+
+ switch(state)
+ {
+ /* read the RIFF tag */
+ case 0:
+ if (fread(&chunk, sizeof(chunk), 1, wFile->file) != 1)
+ done = EAS_TRUE;
+ else
+ {
+ if (chunk.tag != riffTag)
+ done = EAS_TRUE;
+ else
+ state++;
+ }
+ break;
+
+ /* read the WAVE tag */
+ case 1:
+ if (fread(&tag, sizeof(tag), 1, wFile->file) != 1)
+ done = EAS_TRUE;
+ else
+ {
+ if (tag != waveTag)
+ done = EAS_TRUE;
+ else
+ state++;
+ }
+ break;
+
+ /* looking for fmt chunk */
+ case 2:
+ if (fread(&chunk, sizeof(chunk), 1, wFile->file) != 1)
+ done = EAS_TRUE;
+ else
+ {
+ startChunkPos = ftell(wFile->file);
+
+ /* not fmt tag, skip it */
+ if (chunk.tag != fmtTag)
+ fseek(wFile->file, startChunkPos + (EAS_I32) chunk.size, SEEK_SET);
+ else
+ state++;
+ }
+ break;
+
+ /* read fmt chunk */
+ case 3:
+ if (fread(&wFile->wh.fc, sizeof(FMT_CHUNK), 1, wFile->file) != 1)
+ done = EAS_TRUE;
+ else
+ {
+ fseek(wFile->file, startChunkPos + (EAS_I32) chunk.size, SEEK_SET);
+ state++;
+ }
+ break;
+
+ /* looking for data chunk */
+ case 4:
+ if (fread(&chunk, sizeof(chunk), 1, wFile->file) != 1)
+ done = EAS_TRUE;
+ else
+ {
+ startChunkPos = ftell(wFile->file);
+
+ /* not data tag, skip it */
+ if (chunk.tag != dataTag)
+ fseek(wFile->file, startChunkPos + (EAS_I32) chunk.size, SEEK_SET);
+ else
+ {
+ wFile->dataSize = chunk.size;
+ state++;
+ done = EAS_TRUE;
+ }
+ }
+ break;
+
+ default:
+ done = EAS_TRUE;
+ break;
+ }
+ }
+
+ /* if not final state, an error occurred */
+ if (state != 5)
+ {
+ fclose(wFile->file);
+ free(wFile);
+ return NULL;
+ }
+
+ /* return the file handle */
+ return wFile;
+} /* end WaveFileOpen */
+#endif
+
+
+
diff --git a/arm-fm-22k/host_src/eas_wave.h b/arm-fm-22k/host_src/eas_wave.h
index ca388f5..968782f 100644
--- a/arm-fm-22k/host_src/eas_wave.h
+++ b/arm-fm-22k/host_src/eas_wave.h
@@ -1,14 +1,14 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_wave.h
- *
- * Contents and purpose:
- * Writes output to a .WAV file
- *
- * DO NOT MODIFY THIS FILE!
- *
- * Copyright Sonic Network Inc. 2005
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_wave.h
+ *
+ * Contents and purpose:
+ * Writes output to a .WAV file
+ *
+ * DO NOT MODIFY THIS FILE!
+ *
+ * Copyright Sonic Network Inc. 2005
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,54 +21,54 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 82 $
- * $Date: 2006-07-10 11:45:19 -0700 (Mon, 10 Jul 2006) $
- *----------------------------------------------------------------------------
-*/
-
-#include "eas_types.h"
-
-/* sentinel */
-#ifndef _EAS_WAVE_H
-#define _EAS_WAVE_H
-
-/* .WAV file format chunk */
-typedef struct {
- EAS_U16 wFormatTag;
- EAS_U16 nChannels;
- EAS_U32 nSamplesPerSec;
- EAS_U32 nAvgBytesPerSec;
- EAS_U16 nBlockAlign;
- EAS_U16 wBitsPerSample;
-} FMT_CHUNK;
-
-/* .WAV file header */
-typedef struct {
- EAS_U32 nRiffTag;
- EAS_U32 nRiffSize;
- EAS_U32 nWaveTag;
- EAS_U32 nFmtTag;
- EAS_U32 nFmtSize;
- FMT_CHUNK fc;
- EAS_U32 nDataTag;
- EAS_U32 nDataSize;
-} WAVE_HEADER;
-
-typedef struct {
- WAVE_HEADER wh;
- FILE *file;
- EAS_BOOL write;
- EAS_U32 dataSize;
-} WAVE_FILE;
-
-WAVE_FILE *WaveFileCreate (const char *filename, EAS_I32 nChannels, EAS_I32 nSamplesPerSec, EAS_I32 wBitsPerSample);
-EAS_I32 WaveFileWrite (WAVE_FILE *wFile, void *buffer, EAS_I32 n);
-EAS_BOOL WaveFileClose (WAVE_FILE *wFile);
-WAVE_FILE *WaveFileOpen (const char *filename);
-
-#endif /* end #ifndef _EAS_WAVE_H */
-
-
-
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 82 $
+ * $Date: 2006-07-10 11:45:19 -0700 (Mon, 10 Jul 2006) $
+ *----------------------------------------------------------------------------
+*/
+
+#include "eas_types.h"
+
+/* sentinel */
+#ifndef _EAS_WAVE_H
+#define _EAS_WAVE_H
+
+/* .WAV file format chunk */
+typedef struct {
+ EAS_U16 wFormatTag;
+ EAS_U16 nChannels;
+ EAS_U32 nSamplesPerSec;
+ EAS_U32 nAvgBytesPerSec;
+ EAS_U16 nBlockAlign;
+ EAS_U16 wBitsPerSample;
+} FMT_CHUNK;
+
+/* .WAV file header */
+typedef struct {
+ EAS_U32 nRiffTag;
+ EAS_U32 nRiffSize;
+ EAS_U32 nWaveTag;
+ EAS_U32 nFmtTag;
+ EAS_U32 nFmtSize;
+ FMT_CHUNK fc;
+ EAS_U32 nDataTag;
+ EAS_U32 nDataSize;
+} WAVE_HEADER;
+
+typedef struct {
+ WAVE_HEADER wh;
+ FILE *file;
+ EAS_BOOL write;
+ EAS_U32 dataSize;
+} WAVE_FILE;
+
+WAVE_FILE *WaveFileCreate (const char *filename, EAS_I32 nChannels, EAS_I32 nSamplesPerSec, EAS_I32 wBitsPerSample);
+EAS_I32 WaveFileWrite (WAVE_FILE *wFile, void *buffer, EAS_I32 n);
+EAS_BOOL WaveFileClose (WAVE_FILE *wFile);
+WAVE_FILE *WaveFileOpen (const char *filename);
+
+#endif /* end #ifndef _EAS_WAVE_H */
+
+
+
diff --git a/arm-fm-22k/lib_src/eas_audioconst.h b/arm-fm-22k/lib_src/eas_audioconst.h
index 1cfa404..066148e 100644
--- a/arm-fm-22k/lib_src/eas_audioconst.h
+++ b/arm-fm-22k/lib_src/eas_audioconst.h
@@ -1,13 +1,13 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_audioconst.h
- *
- * Contents and purpose:
- * Defines audio constants related to the sample rate, bit size, etc.
- *
- *
- * Copyright Sonic Network Inc. 2005
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_audioconst.h
+ *
+ * Contents and purpose:
+ * Defines audio constants related to the sample rate, bit size, etc.
+ *
+ *
+ * Copyright Sonic Network Inc. 2005
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,78 +20,78 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 82 $
- * $Date: 2006-07-10 11:45:19 -0700 (Mon, 10 Jul 2006) $
- *----------------------------------------------------------------------------
-*/
-
-#ifndef _EAS_AUDIOCONST_H
-#define _EAS_AUDIOCONST_H
-
-/*----------------------------------------------------------------------------
- * These macros define the various characteristics of the defined sample rates
- *----------------------------------------------------------------------------
- * BUFFER_SIZE_IN_MONO_SAMPLES size of buffer in samples
- * _OUTPUT_SAMPLE_RATE compiled output sample rate
- * AUDIO_FRAME_LENGTH length of an audio frame in 256ths of a millisecond
- * SYNTH_UPDATE_PERIOD_IN_BITS length of an audio frame (2^x samples)
- *----------------------------------------------------------------------------
-*/
-
-#if defined (_SAMPLE_RATE_8000)
-#define BUFFER_SIZE_IN_MONO_SAMPLES 32
-#define _OUTPUT_SAMPLE_RATE 8000
-#define AUDIO_FRAME_LENGTH 1024
-#define SYNTH_UPDATE_PERIOD_IN_BITS 5
-
-#elif defined (_SAMPLE_RATE_16000)
-#define BUFFER_SIZE_IN_MONO_SAMPLES 64
-#define _OUTPUT_SAMPLE_RATE 16000
-#define AUDIO_FRAME_LENGTH 1024
-#define SYNTH_UPDATE_PERIOD_IN_BITS 6
-
-#elif defined (_SAMPLE_RATE_20000)
-#define BUFFER_SIZE_IN_MONO_SAMPLES 128
-#define _OUTPUT_SAMPLE_RATE 20000
-#define AUDIO_FRAME_LENGTH 1638
-#define SYNTH_UPDATE_PERIOD_IN_BITS 7
-
-#elif defined (_SAMPLE_RATE_22050)
-#define BUFFER_SIZE_IN_MONO_SAMPLES 128
-#define _OUTPUT_SAMPLE_RATE 22050
-#define AUDIO_FRAME_LENGTH 1486
-#define SYNTH_UPDATE_PERIOD_IN_BITS 7
-
-#elif defined (_SAMPLE_RATE_24000)
-#define BUFFER_SIZE_IN_MONO_SAMPLES 128
-#define _OUTPUT_SAMPLE_RATE 24000
-#define AUDIO_FRAME_LENGTH 1365
-#define SYNTH_UPDATE_PERIOD_IN_BITS 7
-
-#elif defined (_SAMPLE_RATE_32000)
-#define BUFFER_SIZE_IN_MONO_SAMPLES 128
-#define _OUTPUT_SAMPLE_RATE 32000
-#define AUDIO_FRAME_LENGTH 1024
-#define SYNTH_UPDATE_PERIOD_IN_BITS 7
-
-#elif defined (_SAMPLE_RATE_44100)
-#define BUFFER_SIZE_IN_MONO_SAMPLES 256
-#define _OUTPUT_SAMPLE_RATE 44100
-#define AUDIO_FRAME_LENGTH 1486
-#define SYNTH_UPDATE_PERIOD_IN_BITS 8
-
-#elif defined (_SAMPLE_RATE_48000)
-#define BUFFER_SIZE_IN_MONO_SAMPLES 256
-#define _OUTPUT_SAMPLE_RATE 48000
-#define AUDIO_FRAME_LENGTH 1365
-#define SYNTH_UPDATE_PERIOD_IN_BITS 8
-
-#else
-#error "_SAMPLE_RATE_XXXXX must be defined to valid rate"
-#endif
-
-#endif /* #ifndef _EAS_AUDIOCONST_H */
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 82 $
+ * $Date: 2006-07-10 11:45:19 -0700 (Mon, 10 Jul 2006) $
+ *----------------------------------------------------------------------------
+*/
+
+#ifndef _EAS_AUDIOCONST_H
+#define _EAS_AUDIOCONST_H
+
+/*----------------------------------------------------------------------------
+ * These macros define the various characteristics of the defined sample rates
+ *----------------------------------------------------------------------------
+ * BUFFER_SIZE_IN_MONO_SAMPLES size of buffer in samples
+ * _OUTPUT_SAMPLE_RATE compiled output sample rate
+ * AUDIO_FRAME_LENGTH length of an audio frame in 256ths of a millisecond
+ * SYNTH_UPDATE_PERIOD_IN_BITS length of an audio frame (2^x samples)
+ *----------------------------------------------------------------------------
+*/
+
+#if defined (_SAMPLE_RATE_8000)
+#define BUFFER_SIZE_IN_MONO_SAMPLES 32
+#define _OUTPUT_SAMPLE_RATE 8000
+#define AUDIO_FRAME_LENGTH 1024
+#define SYNTH_UPDATE_PERIOD_IN_BITS 5
+
+#elif defined (_SAMPLE_RATE_16000)
+#define BUFFER_SIZE_IN_MONO_SAMPLES 64
+#define _OUTPUT_SAMPLE_RATE 16000
+#define AUDIO_FRAME_LENGTH 1024
+#define SYNTH_UPDATE_PERIOD_IN_BITS 6
+
+#elif defined (_SAMPLE_RATE_20000)
+#define BUFFER_SIZE_IN_MONO_SAMPLES 128
+#define _OUTPUT_SAMPLE_RATE 20000
+#define AUDIO_FRAME_LENGTH 1638
+#define SYNTH_UPDATE_PERIOD_IN_BITS 7
+
+#elif defined (_SAMPLE_RATE_22050)
+#define BUFFER_SIZE_IN_MONO_SAMPLES 128
+#define _OUTPUT_SAMPLE_RATE 22050
+#define AUDIO_FRAME_LENGTH 1486
+#define SYNTH_UPDATE_PERIOD_IN_BITS 7
+
+#elif defined (_SAMPLE_RATE_24000)
+#define BUFFER_SIZE_IN_MONO_SAMPLES 128
+#define _OUTPUT_SAMPLE_RATE 24000
+#define AUDIO_FRAME_LENGTH 1365
+#define SYNTH_UPDATE_PERIOD_IN_BITS 7
+
+#elif defined (_SAMPLE_RATE_32000)
+#define BUFFER_SIZE_IN_MONO_SAMPLES 128
+#define _OUTPUT_SAMPLE_RATE 32000
+#define AUDIO_FRAME_LENGTH 1024
+#define SYNTH_UPDATE_PERIOD_IN_BITS 7
+
+#elif defined (_SAMPLE_RATE_44100)
+#define BUFFER_SIZE_IN_MONO_SAMPLES 256
+#define _OUTPUT_SAMPLE_RATE 44100
+#define AUDIO_FRAME_LENGTH 1486
+#define SYNTH_UPDATE_PERIOD_IN_BITS 8
+
+#elif defined (_SAMPLE_RATE_48000)
+#define BUFFER_SIZE_IN_MONO_SAMPLES 256
+#define _OUTPUT_SAMPLE_RATE 48000
+#define AUDIO_FRAME_LENGTH 1365
+#define SYNTH_UPDATE_PERIOD_IN_BITS 8
+
+#else
+#error "_SAMPLE_RATE_XXXXX must be defined to valid rate"
+#endif
+
+#endif /* #ifndef _EAS_AUDIOCONST_H */
+
diff --git a/arm-fm-22k/lib_src/eas_chorus.c b/arm-fm-22k/lib_src/eas_chorus.c
index bc42237..4a2c8d0 100644
--- a/arm-fm-22k/lib_src/eas_chorus.c
+++ b/arm-fm-22k/lib_src/eas_chorus.c
@@ -1,13 +1,13 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_chorus.c
- *
- * Contents and purpose:
- * Contains the implementation of the Chorus effect.
- *
- *
- * Copyright Sonic Network Inc. 2006
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_chorus.c
+ *
+ * Contents and purpose:
+ * Contains the implementation of the Chorus effect.
+ *
+ *
+ * Copyright Sonic Network Inc. 2006
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,585 +20,585 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 499 $
- * $Date: 2006-12-11 16:07:20 -0800 (Mon, 11 Dec 2006) $
- *----------------------------------------------------------------------------
-*/
-
-#include "eas_data.h"
-#include "eas_effects.h"
-#include "eas_math.h"
-#include "eas_chorusdata.h"
-#include "eas_chorus.h"
-#include "eas_config.h"
-#include "eas_host.h"
-#include "eas_report.h"
-
-/* prototypes for effects interface */
-static EAS_RESULT ChorusInit (EAS_DATA_HANDLE pEASData, EAS_VOID_PTR *pInstData);
-static void ChorusProcess (EAS_VOID_PTR pInstData, EAS_PCM *pSrc, EAS_PCM *pDst, EAS_I32 numSamples);
-static EAS_RESULT ChorusShutdown (EAS_DATA_HANDLE pEASData, EAS_VOID_PTR pInstData);
-static EAS_RESULT ChorusGetParam (EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue);
-static EAS_RESULT ChorusSetParam (EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value);
-
-/* common effects interface for configuration module */
-const S_EFFECTS_INTERFACE EAS_Chorus =
-{
- ChorusInit,
- ChorusProcess,
- ChorusShutdown,
- ChorusGetParam,
- ChorusSetParam
-};
-
-
-
-//LFO shape table used by the chorus, larger table would sound better
-//this is a sine wave, where 32767 = 1.0
-static const EAS_I16 EAS_chorusShape[CHORUS_SHAPE_SIZE] = {
- 0, 1608, 3212, 4808, 6393, 7962, 9512, 11309, 12539, 14010, 15446, 16846, 18204, 19519, 20787, 22005, 23170,
- 24279, 25329, 26319, 27245, 28105, 28898, 29621, 30273, 30852, 31356, 31785, 32137, 32412, 32609, 32728,
- 32767, 32728, 32609, 32412, 32137, 31785, 31356, 30852, 30273, 29621, 28898, 28105, 27245, 26319, 25329,
- 24279, 23170, 22005, 20787, 19519, 18204, 16846, 15446, 14010, 12539, 11039, 9512, 7962, 6393, 4808, 3212,
- 1608, 0, -1608, -3212, -4808, -6393, -7962, -9512, -11309, -12539, -14010, -15446, -16846, -18204, -19519,
- -20787, -22005, -23170, -24279, -25329, -26319, -27245, -28105, -28898, -29621, -30273, -30852, -31356, -31785,
- -32137, -32412, -32609, -32728, -32767, -32728, -32609, -32412, -32137, -31785, -31356, -30852, -30273, -29621,
- -28898, -28105, -27245, -26319, -25329, -24279, -23170, -22005, -20787, -19519, -18204, -16846, -15446, -14010,
- -12539, -11039, -9512, -7962, -6393, -4808, -3212, -1608
-};
-
-/*----------------------------------------------------------------------------
- * InitializeChorus()
- *----------------------------------------------------------------------------
- * Purpose: Initializes chorus parameters
- *
- *
- * Inputs:
- *
- * Outputs:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT ChorusInit (EAS_DATA_HANDLE pEASData, EAS_VOID_PTR *pInstData)
-{
- S_CHORUS_OBJECT *pChorusData;
- S_CHORUS_PRESET *pPreset;
- EAS_I32 index;
-
- /* check Configuration Module for data allocation */
- if (pEASData->staticMemoryModel)
- pChorusData = EAS_CMEnumFXData(EAS_MODULE_CHORUS);
-
- /* allocate dynamic memory */
- else
- pChorusData = EAS_HWMalloc(pEASData->hwInstData, sizeof(S_CHORUS_OBJECT));
-
- if (pChorusData == NULL)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_FATAL, "Failed to allocate Chorus memory\n"); */ }
- return EAS_ERROR_MALLOC_FAILED;
- }
-
- /* clear the structure */
- EAS_HWMemSet(pChorusData, 0, sizeof(S_CHORUS_OBJECT));
-
- ChorusReadInPresets(pChorusData);
-
- /* set some default values */
- pChorusData->bypass = EAS_CHORUS_BYPASS_DEFAULT;
- pChorusData->preset = EAS_CHORUS_PRESET_DEFAULT;
- pChorusData->m_nLevel = EAS_CHORUS_LEVEL_DEFAULT;
- pChorusData->m_nRate = EAS_CHORUS_RATE_DEFAULT;
- pChorusData->m_nDepth = EAS_CHORUS_DEPTH_DEFAULT;
-
- //chorus rate and depth need some massaging from preset value (which is sample rate independent)
-
- //convert rate from steps of .05 Hz to value which can be used as phase increment,
- //with current CHORUS_SHAPE_SIZE and rate limits, this fits into 16 bits
- //want to compute ((shapeSize * 65536) * (storedRate/20))/sampleRate;
- //computing it as below allows rate steps to be evenly spaced
- //uses 32 bit divide, but only once when new value is selected
- pChorusData->m_nRate = (EAS_I16)
- ((((EAS_I32)CHORUS_SHAPE_SIZE<<16)/(20*(EAS_I32)_OUTPUT_SAMPLE_RATE)) * pChorusData->m_nRate);
-
- //convert depth from steps of .05 ms, to samples, with 16 bit whole part, discard fraction
- //want to compute ((depth * sampleRate)/20000)
- //use the following approximation since 105/32 is roughly 65536/20000
- /*lint -e{704} use shift for performance */
- pChorusData->m_nDepth = (EAS_I16)
- (((((EAS_I32)pChorusData->m_nDepth * _OUTPUT_SAMPLE_RATE)>>5) * 105) >> 16);
-
- pChorusData->m_nLevel = pChorusData->m_nLevel;
-
- //zero delay memory for chorus
- for (index = CHORUS_L_SIZE - 1; index >= 0; index--)
- {
- pChorusData->chorusDelayL[index] = 0;
- }
- for (index = CHORUS_R_SIZE - 1; index >= 0; index--)
- {
- pChorusData->chorusDelayR[index] = 0;
- }
-
- //init delay line index, these are used to implement circular delay buffer
- pChorusData->chorusIndexL = 0;
- pChorusData->chorusIndexR = 0;
-
- //init LFO phase
- //16 bit whole part, 16 bit fraction
- pChorusData->lfoLPhase = 0;
- pChorusData->lfoRPhase = (CHORUS_SHAPE_SIZE << 16) >> 2; // 1/4 of total, i.e. 90 degrees out of phase;
-
- //init chorus delay position
- //right now chorus delay is a compile-time value, as is sample rate
- pChorusData->chorusTapPosition = (EAS_I16)((CHORUS_DELAY_MS * _OUTPUT_SAMPLE_RATE)/1000);
-
- //now copy from the new preset into Chorus
- pPreset = &pChorusData->m_sPreset.m_sPreset[pChorusData->m_nNextChorus];
-
- pChorusData->m_nLevel = pPreset->m_nLevel;
- pChorusData->m_nRate = pPreset->m_nRate;
- pChorusData->m_nDepth = pPreset->m_nDepth;
-
- pChorusData->m_nRate = (EAS_I16)
- ((((EAS_I32)CHORUS_SHAPE_SIZE<<16)/(20*(EAS_I32)_OUTPUT_SAMPLE_RATE)) * pChorusData->m_nRate);
-
- /*lint -e{704} use shift for performance */
- pChorusData->m_nDepth = (EAS_I16)
- (((((EAS_I32)pChorusData->m_nDepth * _OUTPUT_SAMPLE_RATE)>>5) * 105) >> 16);
-
- *pInstData = pChorusData;
-
- return EAS_SUCCESS;
-} /* end ChorusInit */
-
-/*----------------------------------------------------------------------------
- * WeightedTap()
- *----------------------------------------------------------------------------
- * Purpose: Does fractional array look-up using linear interpolation
- *
- * first convert indexDesired to actual desired index by taking into account indexReference
- * then do linear interpolation between two actual samples using fractional part
- *
- * Inputs:
- * array: pointer to array of signed 16 bit values, typically either PCM data or control data
- * indexReference: the circular buffer relative offset
- * indexDesired: the fractional index we are looking up (16 bits index + 16 bits fraction)
- * indexLimit: the total size of the array, used to compute buffer wrap
- *
- * Outputs:
- * Value from the input array, linearly interpolated between two actual data values
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_I16 WeightedTap(const EAS_I16 *array, EAS_I16 indexReference, EAS_I32 indexDesired, EAS_I16 indexLimit)
-{
- EAS_I16 index;
- EAS_I16 fraction;
- EAS_I16 val1;
- EAS_I16 val2;
-
- //separate indexDesired into whole and fractional parts
- /*lint -e{704} use shift for performance */
- index = (EAS_I16)(indexDesired >> 16);
- /*lint -e{704} use shift for performance */
- fraction = (EAS_I16)((indexDesired>>1) & 0x07FFF); //just use 15 bits of fractional part
-
- //adjust whole part by indexReference
- index = indexReference - index;
- //make sure we stay within array bounds, this implements circular buffer
- while (index < 0)
- {
- index += indexLimit;
- }
-
- //get two adjacent values from the array
- val1 = array[index];
-
- //handle special case when index == 0, else typical case
- if (index == 0)
- {
- val2 = array[indexLimit-1]; //get last value from array
- }
- else
- {
- val2 = array[index-1]; //get previous value from array
- }
-
- //compute linear interpolation as (val1 + ((val2-val1)*fraction))
- return(val1 + (EAS_I16)MULT_EG1_EG1(val2-val1,fraction));
-}
-
-/*----------------------------------------------------------------------------
- * ChorusProcess()
- *----------------------------------------------------------------------------
- * Purpose: compute the chorus on the input buffer, and mix into output buffer
- *
- *
- * Inputs:
- * src: pointer to input buffer of PCM values to be processed
- * dst: pointer to output buffer of PCM values we are to sume the result with
- * bufSize: the number of sample frames (i.e. stereo samples) in the buffer
- *
- * Outputs:
- * None
- *
- *----------------------------------------------------------------------------
-*/
-//compute the chorus, and mix into output buffer
-static void ChorusProcess (EAS_VOID_PTR pInstData, EAS_PCM *pSrc, EAS_PCM *pDst, EAS_I32 numSamples)
-{
- EAS_I32 ix;
- EAS_I32 nChannelNumber;
- EAS_I16 lfoValueLeft;
- EAS_I16 lfoValueRight;
- EAS_I32 positionOffsetL;
- EAS_I32 positionOffsetR;
- EAS_PCM tapL;
- EAS_PCM tapR;
- EAS_I32 tempValue;
- EAS_PCM nInputSample;
- EAS_I32 nOutputSample;
- EAS_PCM *pIn;
- EAS_PCM *pOut;
-
- S_CHORUS_OBJECT *pChorusData;
-
- pChorusData = (S_CHORUS_OBJECT*) pInstData;
-
- //if the chorus is disabled or turned all the way down
- if (pChorusData->bypass == EAS_TRUE || pChorusData->m_nLevel == 0)
- {
- if (pSrc != pDst)
- EAS_HWMemCpy(pSrc, pDst, numSamples * NUM_OUTPUT_CHANNELS * (EAS_I32) sizeof(EAS_PCM));
- return;
- }
-
- if (pChorusData->m_nNextChorus != pChorusData->m_nCurrentChorus)
- {
- ChorusUpdate(pChorusData);
- }
-
- for (nChannelNumber = 0; nChannelNumber < NUM_OUTPUT_CHANNELS; nChannelNumber++)
- {
-
- pIn = pSrc + nChannelNumber;
- pOut = pDst + nChannelNumber;
-
- if(nChannelNumber==0)
- {
- for (ix = 0; ix < numSamples; ix++)
- {
- nInputSample = *pIn;
- pIn += NUM_OUTPUT_CHANNELS;
-
- //feed input into chorus delay line
- pChorusData->chorusDelayL[pChorusData->chorusIndexL] = nInputSample;
-
- //compute chorus lfo value using phase as fractional index into chorus shape table
- //resulting value is between -1.0 and 1.0, expressed as signed 16 bit number
- lfoValueLeft = WeightedTap(EAS_chorusShape, 0, pChorusData->lfoLPhase, CHORUS_SHAPE_SIZE);
-
- //scale chorus depth by lfo value to get relative fractional sample index
- //index is expressed as 32 bit number with 16 bit fractional part
- /*lint -e{703} use shift for performance */
- positionOffsetL = pChorusData->m_nDepth * (((EAS_I32)lfoValueLeft) << 1);
-
- //add fixed chorus delay to get actual fractional sample index
- positionOffsetL += ((EAS_I32)pChorusData->chorusTapPosition) << 16;
-
- //get tap value from chorus delay using fractional sample index
- tapL = WeightedTap(pChorusData->chorusDelayL, pChorusData->chorusIndexL, positionOffsetL, CHORUS_L_SIZE);
-
- //scale by chorus level, then sum with input buffer contents and saturate
- tempValue = MULT_EG1_EG1(tapL, pChorusData->m_nLevel);
- nOutputSample = SATURATE(tempValue + nInputSample);
-
- *pOut = (EAS_I16)SATURATE(nOutputSample);
- pOut += NUM_OUTPUT_CHANNELS;
-
-
- //increment chorus delay index and make it wrap as needed
- //this implements circular buffer
- if ((pChorusData->chorusIndexL+=1) >= CHORUS_L_SIZE)
- pChorusData->chorusIndexL = 0;
-
- //increment fractional lfo phase, and make it wrap as needed
- pChorusData->lfoLPhase += pChorusData->m_nRate;
- while (pChorusData->lfoLPhase >= (CHORUS_SHAPE_SIZE<<16))
- {
- pChorusData->lfoLPhase -= (CHORUS_SHAPE_SIZE<<16);
- }
- }
- }
- else
- {
- for (ix = 0; ix < numSamples; ix++)
- {
- nInputSample = *pIn;
- pIn += NUM_OUTPUT_CHANNELS;
-
- //feed input into chorus delay line
- pChorusData->chorusDelayR[pChorusData->chorusIndexR] = nInputSample;
-
- //compute chorus lfo value using phase as fractional index into chorus shape table
- //resulting value is between -1.0 and 1.0, expressed as signed 16 bit number
- lfoValueRight = WeightedTap(EAS_chorusShape, 0, pChorusData->lfoRPhase, CHORUS_SHAPE_SIZE);
-
- //scale chorus depth by lfo value to get relative fractional sample index
- //index is expressed as 32 bit number with 16 bit fractional part
- /*lint -e{703} use shift for performance */
- positionOffsetR = pChorusData->m_nDepth * (((EAS_I32)lfoValueRight) << 1);
-
- //add fixed chorus delay to get actual fractional sample index
- positionOffsetR += ((EAS_I32)pChorusData->chorusTapPosition) << 16;
-
- //get tap value from chorus delay using fractional sample index
- tapR = WeightedTap(pChorusData->chorusDelayR, pChorusData->chorusIndexR, positionOffsetR, CHORUS_R_SIZE);
-
- //scale by chorus level, then sum with output buffer contents and saturate
- tempValue = MULT_EG1_EG1(tapR, pChorusData->m_nLevel);
- nOutputSample = SATURATE(tempValue + nInputSample);
-
- *pOut = (EAS_I16)SATURATE(nOutputSample);
- pOut += NUM_OUTPUT_CHANNELS;
-
- //increment chorus delay index and make it wrap as needed
- //this implements circular buffer
- if ((pChorusData->chorusIndexR+=1) >= CHORUS_R_SIZE)
- pChorusData->chorusIndexR = 0;
-
- //increment fractional lfo phase, and make it wrap as needed
- pChorusData->lfoRPhase += pChorusData->m_nRate;
- while (pChorusData->lfoRPhase >= (CHORUS_SHAPE_SIZE<<16))
- {
- pChorusData->lfoRPhase -= (CHORUS_SHAPE_SIZE<<16);
- }
- }
- }
-
- }
-} /* end ChorusProcess */
-
-
-
-/*----------------------------------------------------------------------------
- * ChorusShutdown()
- *----------------------------------------------------------------------------
- * Purpose:
- * Initializes the Chorus effect.
- *
- * Inputs:
- * pInstData - handle to instance data
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT ChorusShutdown (EAS_DATA_HANDLE pEASData, EAS_VOID_PTR pInstData)
-{
- /* check Configuration Module for static memory allocation */
- if (!pEASData->staticMemoryModel)
- EAS_HWFree(pEASData->hwInstData, pInstData);
- return EAS_SUCCESS;
-} /* end ChorusShutdown */
-
-/*----------------------------------------------------------------------------
- * ChorusGetParam()
- *----------------------------------------------------------------------------
- * Purpose:
- * Get a Chorus parameter
- *
- * Inputs:
- * pInstData - handle to instance data
- * param - parameter index
- * *pValue - pointer to variable to hold retrieved value
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT ChorusGetParam (EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue)
-{
- S_CHORUS_OBJECT *p;
-
- p = (S_CHORUS_OBJECT*) pInstData;
-
- switch (param)
- {
- case EAS_PARAM_CHORUS_BYPASS:
- *pValue = (EAS_I32) p->bypass;
- break;
- case EAS_PARAM_CHORUS_PRESET:
- *pValue = (EAS_I8) p->m_nCurrentChorus;
- break;
- case EAS_PARAM_CHORUS_RATE:
- *pValue = (EAS_I32) p->m_nRate;
- break;
- case EAS_PARAM_CHORUS_DEPTH:
- *pValue = (EAS_I32) p->m_nDepth;
- break;
- case EAS_PARAM_CHORUS_LEVEL:
- *pValue = (EAS_I32) p->m_nLevel;
- break;
- default:
- return EAS_ERROR_INVALID_PARAMETER;
- }
- return EAS_SUCCESS;
-} /* end ChorusGetParam */
-
-
-/*----------------------------------------------------------------------------
- * ChorusSetParam()
- *----------------------------------------------------------------------------
- * Purpose:
- * Set a Chorus parameter
- *
- * Inputs:
- * pInstData - handle to instance data
- * param - parameter index
- * *pValue - new paramter value
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT ChorusSetParam (EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value)
-{
- S_CHORUS_OBJECT *p;
-
- p = (S_CHORUS_OBJECT*) pInstData;
-
- switch (param)
- {
- case EAS_PARAM_CHORUS_BYPASS:
- p->bypass = (EAS_BOOL) value;
- break;
- case EAS_PARAM_CHORUS_PRESET:
- if(value!=EAS_PARAM_CHORUS_PRESET1 && value!=EAS_PARAM_CHORUS_PRESET2 &&
- value!=EAS_PARAM_CHORUS_PRESET3 && value!=EAS_PARAM_CHORUS_PRESET4)
- return EAS_ERROR_INVALID_PARAMETER;
- p->m_nNextChorus = (EAS_I8)value;
- break;
- case EAS_PARAM_CHORUS_RATE:
- if(value<EAS_CHORUS_RATE_MIN || value>EAS_CHORUS_RATE_MAX)
- return EAS_ERROR_INVALID_PARAMETER;
- p->m_nRate = (EAS_I16) value;
- break;
- case EAS_PARAM_CHORUS_DEPTH:
- if(value<EAS_CHORUS_DEPTH_MIN || value>EAS_CHORUS_DEPTH_MAX)
- return EAS_ERROR_INVALID_PARAMETER;
- p->m_nDepth = (EAS_I16) value;
- break;
- case EAS_PARAM_CHORUS_LEVEL:
- if(value<EAS_CHORUS_LEVEL_MIN || value>EAS_CHORUS_LEVEL_MAX)
- return EAS_ERROR_INVALID_PARAMETER;
- p->m_nLevel = (EAS_I16) value;
- break;
-
- default:
- return EAS_ERROR_INVALID_PARAMETER;
- }
- return EAS_SUCCESS;
-} /* end ChorusSetParam */
-
-
-/*----------------------------------------------------------------------------
- * ChorusReadInPresets()
- *----------------------------------------------------------------------------
- * Purpose: sets global Chorus preset bank to defaults
- *
- * Inputs:
- *
- * Outputs:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT ChorusReadInPresets(S_CHORUS_OBJECT *pChorusData)
-{
-
- int preset = 0;
- int defaultPreset = 0;
-
- //now init any remaining presets to defaults
- for (defaultPreset = preset; defaultPreset < CHORUS_MAX_TYPE; defaultPreset++)
- {
- S_CHORUS_PRESET *pPreset = &pChorusData->m_sPreset.m_sPreset[defaultPreset];
- if (defaultPreset == 0 || defaultPreset > CHORUS_MAX_TYPE-1)
- {
- pPreset->m_nDepth = 39;
- pPreset->m_nRate = 30;
- pPreset->m_nLevel = 32767;
- }
- else if (defaultPreset == 1)
- {
- pPreset->m_nDepth = 21;
- pPreset->m_nRate = 45;
- pPreset->m_nLevel = 25000;
- }
- else if (defaultPreset == 2)
- {
- pPreset->m_nDepth = 53;
- pPreset->m_nRate = 25;
- pPreset->m_nLevel = 32000;
- }
- else if (defaultPreset == 3)
- {
- pPreset->m_nDepth = 32;
- pPreset->m_nRate = 37;
- pPreset->m_nLevel = 29000;
- }
- }
-
- return EAS_SUCCESS;
-}
-
-
-/*----------------------------------------------------------------------------
- * ChorusUpdate
- *----------------------------------------------------------------------------
- * Purpose:
- * Update the Chorus preset parameters as required
- *
- * Inputs:
- *
- * Outputs:
- *
- *
- * Side Effects:
- * - chorus paramters will be changed
- * - m_nCurrentRoom := m_nNextRoom
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT ChorusUpdate(S_CHORUS_OBJECT *pChorusData)
-{
- S_CHORUS_PRESET *pPreset = &pChorusData->m_sPreset.m_sPreset[pChorusData->m_nNextChorus];
-
- pChorusData->m_nLevel = pPreset->m_nLevel;
- pChorusData->m_nRate = pPreset->m_nRate;
- pChorusData->m_nDepth = pPreset->m_nDepth;
-
- pChorusData->m_nRate = (EAS_I16)
- ((((EAS_I32)CHORUS_SHAPE_SIZE<<16)/(20*(EAS_I32)_OUTPUT_SAMPLE_RATE)) * pChorusData->m_nRate);
-
- /*lint -e{704} use shift for performance */
- pChorusData->m_nDepth = (EAS_I16)
- (((((EAS_I32)pChorusData->m_nDepth * _OUTPUT_SAMPLE_RATE)>>5) * 105) >> 16);
-
- pChorusData->m_nCurrentChorus = pChorusData->m_nNextChorus;
-
- return EAS_SUCCESS;
-
-} /* end ChorusUpdate */
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 499 $
+ * $Date: 2006-12-11 16:07:20 -0800 (Mon, 11 Dec 2006) $
+ *----------------------------------------------------------------------------
+*/
+
+#include "eas_data.h"
+#include "eas_effects.h"
+#include "eas_math.h"
+#include "eas_chorusdata.h"
+#include "eas_chorus.h"
+#include "eas_config.h"
+#include "eas_host.h"
+#include "eas_report.h"
+
+/* prototypes for effects interface */
+static EAS_RESULT ChorusInit (EAS_DATA_HANDLE pEASData, EAS_VOID_PTR *pInstData);
+static void ChorusProcess (EAS_VOID_PTR pInstData, EAS_PCM *pSrc, EAS_PCM *pDst, EAS_I32 numSamples);
+static EAS_RESULT ChorusShutdown (EAS_DATA_HANDLE pEASData, EAS_VOID_PTR pInstData);
+static EAS_RESULT ChorusGetParam (EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue);
+static EAS_RESULT ChorusSetParam (EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value);
+
+/* common effects interface for configuration module */
+const S_EFFECTS_INTERFACE EAS_Chorus =
+{
+ ChorusInit,
+ ChorusProcess,
+ ChorusShutdown,
+ ChorusGetParam,
+ ChorusSetParam
+};
+
+
+
+//LFO shape table used by the chorus, larger table would sound better
+//this is a sine wave, where 32767 = 1.0
+static const EAS_I16 EAS_chorusShape[CHORUS_SHAPE_SIZE] = {
+ 0, 1608, 3212, 4808, 6393, 7962, 9512, 11309, 12539, 14010, 15446, 16846, 18204, 19519, 20787, 22005, 23170,
+ 24279, 25329, 26319, 27245, 28105, 28898, 29621, 30273, 30852, 31356, 31785, 32137, 32412, 32609, 32728,
+ 32767, 32728, 32609, 32412, 32137, 31785, 31356, 30852, 30273, 29621, 28898, 28105, 27245, 26319, 25329,
+ 24279, 23170, 22005, 20787, 19519, 18204, 16846, 15446, 14010, 12539, 11039, 9512, 7962, 6393, 4808, 3212,
+ 1608, 0, -1608, -3212, -4808, -6393, -7962, -9512, -11309, -12539, -14010, -15446, -16846, -18204, -19519,
+ -20787, -22005, -23170, -24279, -25329, -26319, -27245, -28105, -28898, -29621, -30273, -30852, -31356, -31785,
+ -32137, -32412, -32609, -32728, -32767, -32728, -32609, -32412, -32137, -31785, -31356, -30852, -30273, -29621,
+ -28898, -28105, -27245, -26319, -25329, -24279, -23170, -22005, -20787, -19519, -18204, -16846, -15446, -14010,
+ -12539, -11039, -9512, -7962, -6393, -4808, -3212, -1608
+};
+
+/*----------------------------------------------------------------------------
+ * InitializeChorus()
+ *----------------------------------------------------------------------------
+ * Purpose: Initializes chorus parameters
+ *
+ *
+ * Inputs:
+ *
+ * Outputs:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT ChorusInit (EAS_DATA_HANDLE pEASData, EAS_VOID_PTR *pInstData)
+{
+ S_CHORUS_OBJECT *pChorusData;
+ S_CHORUS_PRESET *pPreset;
+ EAS_I32 index;
+
+ /* check Configuration Module for data allocation */
+ if (pEASData->staticMemoryModel)
+ pChorusData = EAS_CMEnumFXData(EAS_MODULE_CHORUS);
+
+ /* allocate dynamic memory */
+ else
+ pChorusData = EAS_HWMalloc(pEASData->hwInstData, sizeof(S_CHORUS_OBJECT));
+
+ if (pChorusData == NULL)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_FATAL, "Failed to allocate Chorus memory\n"); */ }
+ return EAS_ERROR_MALLOC_FAILED;
+ }
+
+ /* clear the structure */
+ EAS_HWMemSet(pChorusData, 0, sizeof(S_CHORUS_OBJECT));
+
+ ChorusReadInPresets(pChorusData);
+
+ /* set some default values */
+ pChorusData->bypass = EAS_CHORUS_BYPASS_DEFAULT;
+ pChorusData->preset = EAS_CHORUS_PRESET_DEFAULT;
+ pChorusData->m_nLevel = EAS_CHORUS_LEVEL_DEFAULT;
+ pChorusData->m_nRate = EAS_CHORUS_RATE_DEFAULT;
+ pChorusData->m_nDepth = EAS_CHORUS_DEPTH_DEFAULT;
+
+ //chorus rate and depth need some massaging from preset value (which is sample rate independent)
+
+ //convert rate from steps of .05 Hz to value which can be used as phase increment,
+ //with current CHORUS_SHAPE_SIZE and rate limits, this fits into 16 bits
+ //want to compute ((shapeSize * 65536) * (storedRate/20))/sampleRate;
+ //computing it as below allows rate steps to be evenly spaced
+ //uses 32 bit divide, but only once when new value is selected
+ pChorusData->m_nRate = (EAS_I16)
+ ((((EAS_I32)CHORUS_SHAPE_SIZE<<16)/(20*(EAS_I32)_OUTPUT_SAMPLE_RATE)) * pChorusData->m_nRate);
+
+ //convert depth from steps of .05 ms, to samples, with 16 bit whole part, discard fraction
+ //want to compute ((depth * sampleRate)/20000)
+ //use the following approximation since 105/32 is roughly 65536/20000
+ /*lint -e{704} use shift for performance */
+ pChorusData->m_nDepth = (EAS_I16)
+ (((((EAS_I32)pChorusData->m_nDepth * _OUTPUT_SAMPLE_RATE)>>5) * 105) >> 16);
+
+ pChorusData->m_nLevel = pChorusData->m_nLevel;
+
+ //zero delay memory for chorus
+ for (index = CHORUS_L_SIZE - 1; index >= 0; index--)
+ {
+ pChorusData->chorusDelayL[index] = 0;
+ }
+ for (index = CHORUS_R_SIZE - 1; index >= 0; index--)
+ {
+ pChorusData->chorusDelayR[index] = 0;
+ }
+
+ //init delay line index, these are used to implement circular delay buffer
+ pChorusData->chorusIndexL = 0;
+ pChorusData->chorusIndexR = 0;
+
+ //init LFO phase
+ //16 bit whole part, 16 bit fraction
+ pChorusData->lfoLPhase = 0;
+ pChorusData->lfoRPhase = (CHORUS_SHAPE_SIZE << 16) >> 2; // 1/4 of total, i.e. 90 degrees out of phase;
+
+ //init chorus delay position
+ //right now chorus delay is a compile-time value, as is sample rate
+ pChorusData->chorusTapPosition = (EAS_I16)((CHORUS_DELAY_MS * _OUTPUT_SAMPLE_RATE)/1000);
+
+ //now copy from the new preset into Chorus
+ pPreset = &pChorusData->m_sPreset.m_sPreset[pChorusData->m_nNextChorus];
+
+ pChorusData->m_nLevel = pPreset->m_nLevel;
+ pChorusData->m_nRate = pPreset->m_nRate;
+ pChorusData->m_nDepth = pPreset->m_nDepth;
+
+ pChorusData->m_nRate = (EAS_I16)
+ ((((EAS_I32)CHORUS_SHAPE_SIZE<<16)/(20*(EAS_I32)_OUTPUT_SAMPLE_RATE)) * pChorusData->m_nRate);
+
+ /*lint -e{704} use shift for performance */
+ pChorusData->m_nDepth = (EAS_I16)
+ (((((EAS_I32)pChorusData->m_nDepth * _OUTPUT_SAMPLE_RATE)>>5) * 105) >> 16);
+
+ *pInstData = pChorusData;
+
+ return EAS_SUCCESS;
+} /* end ChorusInit */
+
+/*----------------------------------------------------------------------------
+ * WeightedTap()
+ *----------------------------------------------------------------------------
+ * Purpose: Does fractional array look-up using linear interpolation
+ *
+ * first convert indexDesired to actual desired index by taking into account indexReference
+ * then do linear interpolation between two actual samples using fractional part
+ *
+ * Inputs:
+ * array: pointer to array of signed 16 bit values, typically either PCM data or control data
+ * indexReference: the circular buffer relative offset
+ * indexDesired: the fractional index we are looking up (16 bits index + 16 bits fraction)
+ * indexLimit: the total size of the array, used to compute buffer wrap
+ *
+ * Outputs:
+ * Value from the input array, linearly interpolated between two actual data values
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_I16 WeightedTap(const EAS_I16 *array, EAS_I16 indexReference, EAS_I32 indexDesired, EAS_I16 indexLimit)
+{
+ EAS_I16 index;
+ EAS_I16 fraction;
+ EAS_I16 val1;
+ EAS_I16 val2;
+
+ //separate indexDesired into whole and fractional parts
+ /*lint -e{704} use shift for performance */
+ index = (EAS_I16)(indexDesired >> 16);
+ /*lint -e{704} use shift for performance */
+ fraction = (EAS_I16)((indexDesired>>1) & 0x07FFF); //just use 15 bits of fractional part
+
+ //adjust whole part by indexReference
+ index = indexReference - index;
+ //make sure we stay within array bounds, this implements circular buffer
+ while (index < 0)
+ {
+ index += indexLimit;
+ }
+
+ //get two adjacent values from the array
+ val1 = array[index];
+
+ //handle special case when index == 0, else typical case
+ if (index == 0)
+ {
+ val2 = array[indexLimit-1]; //get last value from array
+ }
+ else
+ {
+ val2 = array[index-1]; //get previous value from array
+ }
+
+ //compute linear interpolation as (val1 + ((val2-val1)*fraction))
+ return(val1 + (EAS_I16)MULT_EG1_EG1(val2-val1,fraction));
+}
+
+/*----------------------------------------------------------------------------
+ * ChorusProcess()
+ *----------------------------------------------------------------------------
+ * Purpose: compute the chorus on the input buffer, and mix into output buffer
+ *
+ *
+ * Inputs:
+ * src: pointer to input buffer of PCM values to be processed
+ * dst: pointer to output buffer of PCM values we are to sume the result with
+ * bufSize: the number of sample frames (i.e. stereo samples) in the buffer
+ *
+ * Outputs:
+ * None
+ *
+ *----------------------------------------------------------------------------
+*/
+//compute the chorus, and mix into output buffer
+static void ChorusProcess (EAS_VOID_PTR pInstData, EAS_PCM *pSrc, EAS_PCM *pDst, EAS_I32 numSamples)
+{
+ EAS_I32 ix;
+ EAS_I32 nChannelNumber;
+ EAS_I16 lfoValueLeft;
+ EAS_I16 lfoValueRight;
+ EAS_I32 positionOffsetL;
+ EAS_I32 positionOffsetR;
+ EAS_PCM tapL;
+ EAS_PCM tapR;
+ EAS_I32 tempValue;
+ EAS_PCM nInputSample;
+ EAS_I32 nOutputSample;
+ EAS_PCM *pIn;
+ EAS_PCM *pOut;
+
+ S_CHORUS_OBJECT *pChorusData;
+
+ pChorusData = (S_CHORUS_OBJECT*) pInstData;
+
+ //if the chorus is disabled or turned all the way down
+ if (pChorusData->bypass == EAS_TRUE || pChorusData->m_nLevel == 0)
+ {
+ if (pSrc != pDst)
+ EAS_HWMemCpy(pSrc, pDst, numSamples * NUM_OUTPUT_CHANNELS * (EAS_I32) sizeof(EAS_PCM));
+ return;
+ }
+
+ if (pChorusData->m_nNextChorus != pChorusData->m_nCurrentChorus)
+ {
+ ChorusUpdate(pChorusData);
+ }
+
+ for (nChannelNumber = 0; nChannelNumber < NUM_OUTPUT_CHANNELS; nChannelNumber++)
+ {
+
+ pIn = pSrc + nChannelNumber;
+ pOut = pDst + nChannelNumber;
+
+ if(nChannelNumber==0)
+ {
+ for (ix = 0; ix < numSamples; ix++)
+ {
+ nInputSample = *pIn;
+ pIn += NUM_OUTPUT_CHANNELS;
+
+ //feed input into chorus delay line
+ pChorusData->chorusDelayL[pChorusData->chorusIndexL] = nInputSample;
+
+ //compute chorus lfo value using phase as fractional index into chorus shape table
+ //resulting value is between -1.0 and 1.0, expressed as signed 16 bit number
+ lfoValueLeft = WeightedTap(EAS_chorusShape, 0, pChorusData->lfoLPhase, CHORUS_SHAPE_SIZE);
+
+ //scale chorus depth by lfo value to get relative fractional sample index
+ //index is expressed as 32 bit number with 16 bit fractional part
+ /*lint -e{703} use shift for performance */
+ positionOffsetL = pChorusData->m_nDepth * (((EAS_I32)lfoValueLeft) << 1);
+
+ //add fixed chorus delay to get actual fractional sample index
+ positionOffsetL += ((EAS_I32)pChorusData->chorusTapPosition) << 16;
+
+ //get tap value from chorus delay using fractional sample index
+ tapL = WeightedTap(pChorusData->chorusDelayL, pChorusData->chorusIndexL, positionOffsetL, CHORUS_L_SIZE);
+
+ //scale by chorus level, then sum with input buffer contents and saturate
+ tempValue = MULT_EG1_EG1(tapL, pChorusData->m_nLevel);
+ nOutputSample = SATURATE(tempValue + nInputSample);
+
+ *pOut = (EAS_I16)SATURATE(nOutputSample);
+ pOut += NUM_OUTPUT_CHANNELS;
+
+
+ //increment chorus delay index and make it wrap as needed
+ //this implements circular buffer
+ if ((pChorusData->chorusIndexL+=1) >= CHORUS_L_SIZE)
+ pChorusData->chorusIndexL = 0;
+
+ //increment fractional lfo phase, and make it wrap as needed
+ pChorusData->lfoLPhase += pChorusData->m_nRate;
+ while (pChorusData->lfoLPhase >= (CHORUS_SHAPE_SIZE<<16))
+ {
+ pChorusData->lfoLPhase -= (CHORUS_SHAPE_SIZE<<16);
+ }
+ }
+ }
+ else
+ {
+ for (ix = 0; ix < numSamples; ix++)
+ {
+ nInputSample = *pIn;
+ pIn += NUM_OUTPUT_CHANNELS;
+
+ //feed input into chorus delay line
+ pChorusData->chorusDelayR[pChorusData->chorusIndexR] = nInputSample;
+
+ //compute chorus lfo value using phase as fractional index into chorus shape table
+ //resulting value is between -1.0 and 1.0, expressed as signed 16 bit number
+ lfoValueRight = WeightedTap(EAS_chorusShape, 0, pChorusData->lfoRPhase, CHORUS_SHAPE_SIZE);
+
+ //scale chorus depth by lfo value to get relative fractional sample index
+ //index is expressed as 32 bit number with 16 bit fractional part
+ /*lint -e{703} use shift for performance */
+ positionOffsetR = pChorusData->m_nDepth * (((EAS_I32)lfoValueRight) << 1);
+
+ //add fixed chorus delay to get actual fractional sample index
+ positionOffsetR += ((EAS_I32)pChorusData->chorusTapPosition) << 16;
+
+ //get tap value from chorus delay using fractional sample index
+ tapR = WeightedTap(pChorusData->chorusDelayR, pChorusData->chorusIndexR, positionOffsetR, CHORUS_R_SIZE);
+
+ //scale by chorus level, then sum with output buffer contents and saturate
+ tempValue = MULT_EG1_EG1(tapR, pChorusData->m_nLevel);
+ nOutputSample = SATURATE(tempValue + nInputSample);
+
+ *pOut = (EAS_I16)SATURATE(nOutputSample);
+ pOut += NUM_OUTPUT_CHANNELS;
+
+ //increment chorus delay index and make it wrap as needed
+ //this implements circular buffer
+ if ((pChorusData->chorusIndexR+=1) >= CHORUS_R_SIZE)
+ pChorusData->chorusIndexR = 0;
+
+ //increment fractional lfo phase, and make it wrap as needed
+ pChorusData->lfoRPhase += pChorusData->m_nRate;
+ while (pChorusData->lfoRPhase >= (CHORUS_SHAPE_SIZE<<16))
+ {
+ pChorusData->lfoRPhase -= (CHORUS_SHAPE_SIZE<<16);
+ }
+ }
+ }
+
+ }
+} /* end ChorusProcess */
+
+
+
+/*----------------------------------------------------------------------------
+ * ChorusShutdown()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Initializes the Chorus effect.
+ *
+ * Inputs:
+ * pInstData - handle to instance data
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT ChorusShutdown (EAS_DATA_HANDLE pEASData, EAS_VOID_PTR pInstData)
+{
+ /* check Configuration Module for static memory allocation */
+ if (!pEASData->staticMemoryModel)
+ EAS_HWFree(pEASData->hwInstData, pInstData);
+ return EAS_SUCCESS;
+} /* end ChorusShutdown */
+
+/*----------------------------------------------------------------------------
+ * ChorusGetParam()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Get a Chorus parameter
+ *
+ * Inputs:
+ * pInstData - handle to instance data
+ * param - parameter index
+ * *pValue - pointer to variable to hold retrieved value
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT ChorusGetParam (EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue)
+{
+ S_CHORUS_OBJECT *p;
+
+ p = (S_CHORUS_OBJECT*) pInstData;
+
+ switch (param)
+ {
+ case EAS_PARAM_CHORUS_BYPASS:
+ *pValue = (EAS_I32) p->bypass;
+ break;
+ case EAS_PARAM_CHORUS_PRESET:
+ *pValue = (EAS_I8) p->m_nCurrentChorus;
+ break;
+ case EAS_PARAM_CHORUS_RATE:
+ *pValue = (EAS_I32) p->m_nRate;
+ break;
+ case EAS_PARAM_CHORUS_DEPTH:
+ *pValue = (EAS_I32) p->m_nDepth;
+ break;
+ case EAS_PARAM_CHORUS_LEVEL:
+ *pValue = (EAS_I32) p->m_nLevel;
+ break;
+ default:
+ return EAS_ERROR_INVALID_PARAMETER;
+ }
+ return EAS_SUCCESS;
+} /* end ChorusGetParam */
+
+
+/*----------------------------------------------------------------------------
+ * ChorusSetParam()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Set a Chorus parameter
+ *
+ * Inputs:
+ * pInstData - handle to instance data
+ * param - parameter index
+ * *pValue - new paramter value
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT ChorusSetParam (EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value)
+{
+ S_CHORUS_OBJECT *p;
+
+ p = (S_CHORUS_OBJECT*) pInstData;
+
+ switch (param)
+ {
+ case EAS_PARAM_CHORUS_BYPASS:
+ p->bypass = (EAS_BOOL) value;
+ break;
+ case EAS_PARAM_CHORUS_PRESET:
+ if(value!=EAS_PARAM_CHORUS_PRESET1 && value!=EAS_PARAM_CHORUS_PRESET2 &&
+ value!=EAS_PARAM_CHORUS_PRESET3 && value!=EAS_PARAM_CHORUS_PRESET4)
+ return EAS_ERROR_INVALID_PARAMETER;
+ p->m_nNextChorus = (EAS_I8)value;
+ break;
+ case EAS_PARAM_CHORUS_RATE:
+ if(value<EAS_CHORUS_RATE_MIN || value>EAS_CHORUS_RATE_MAX)
+ return EAS_ERROR_INVALID_PARAMETER;
+ p->m_nRate = (EAS_I16) value;
+ break;
+ case EAS_PARAM_CHORUS_DEPTH:
+ if(value<EAS_CHORUS_DEPTH_MIN || value>EAS_CHORUS_DEPTH_MAX)
+ return EAS_ERROR_INVALID_PARAMETER;
+ p->m_nDepth = (EAS_I16) value;
+ break;
+ case EAS_PARAM_CHORUS_LEVEL:
+ if(value<EAS_CHORUS_LEVEL_MIN || value>EAS_CHORUS_LEVEL_MAX)
+ return EAS_ERROR_INVALID_PARAMETER;
+ p->m_nLevel = (EAS_I16) value;
+ break;
+
+ default:
+ return EAS_ERROR_INVALID_PARAMETER;
+ }
+ return EAS_SUCCESS;
+} /* end ChorusSetParam */
+
+
+/*----------------------------------------------------------------------------
+ * ChorusReadInPresets()
+ *----------------------------------------------------------------------------
+ * Purpose: sets global Chorus preset bank to defaults
+ *
+ * Inputs:
+ *
+ * Outputs:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT ChorusReadInPresets(S_CHORUS_OBJECT *pChorusData)
+{
+
+ int preset = 0;
+ int defaultPreset = 0;
+
+ //now init any remaining presets to defaults
+ for (defaultPreset = preset; defaultPreset < CHORUS_MAX_TYPE; defaultPreset++)
+ {
+ S_CHORUS_PRESET *pPreset = &pChorusData->m_sPreset.m_sPreset[defaultPreset];
+ if (defaultPreset == 0 || defaultPreset > CHORUS_MAX_TYPE-1)
+ {
+ pPreset->m_nDepth = 39;
+ pPreset->m_nRate = 30;
+ pPreset->m_nLevel = 32767;
+ }
+ else if (defaultPreset == 1)
+ {
+ pPreset->m_nDepth = 21;
+ pPreset->m_nRate = 45;
+ pPreset->m_nLevel = 25000;
+ }
+ else if (defaultPreset == 2)
+ {
+ pPreset->m_nDepth = 53;
+ pPreset->m_nRate = 25;
+ pPreset->m_nLevel = 32000;
+ }
+ else if (defaultPreset == 3)
+ {
+ pPreset->m_nDepth = 32;
+ pPreset->m_nRate = 37;
+ pPreset->m_nLevel = 29000;
+ }
+ }
+
+ return EAS_SUCCESS;
+}
+
+
+/*----------------------------------------------------------------------------
+ * ChorusUpdate
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Update the Chorus preset parameters as required
+ *
+ * Inputs:
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ * - chorus paramters will be changed
+ * - m_nCurrentRoom := m_nNextRoom
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT ChorusUpdate(S_CHORUS_OBJECT *pChorusData)
+{
+ S_CHORUS_PRESET *pPreset = &pChorusData->m_sPreset.m_sPreset[pChorusData->m_nNextChorus];
+
+ pChorusData->m_nLevel = pPreset->m_nLevel;
+ pChorusData->m_nRate = pPreset->m_nRate;
+ pChorusData->m_nDepth = pPreset->m_nDepth;
+
+ pChorusData->m_nRate = (EAS_I16)
+ ((((EAS_I32)CHORUS_SHAPE_SIZE<<16)/(20*(EAS_I32)_OUTPUT_SAMPLE_RATE)) * pChorusData->m_nRate);
+
+ /*lint -e{704} use shift for performance */
+ pChorusData->m_nDepth = (EAS_I16)
+ (((((EAS_I32)pChorusData->m_nDepth * _OUTPUT_SAMPLE_RATE)>>5) * 105) >> 16);
+
+ pChorusData->m_nCurrentChorus = pChorusData->m_nNextChorus;
+
+ return EAS_SUCCESS;
+
+} /* end ChorusUpdate */
diff --git a/arm-fm-22k/lib_src/eas_chorusdata.c b/arm-fm-22k/lib_src/eas_chorusdata.c
index caee1ed..ec71ff8 100644
--- a/arm-fm-22k/lib_src/eas_chorusdata.c
+++ b/arm-fm-22k/lib_src/eas_chorusdata.c
@@ -1,13 +1,13 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_chorusdata.c
- *
- * Contents and purpose:
- * Contains the static data allocation for the Chorus effect
- *
- *
- * Copyright Sonic Network Inc. 2006
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_chorusdata.c
+ *
+ * Contents and purpose:
+ * Contains the static data allocation for the Chorus effect
+ *
+ *
+ * Copyright Sonic Network Inc. 2006
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,15 +20,15 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 550 $
- * $Date: 2007-02-02 09:37:03 -0800 (Fri, 02 Feb 2007) $
- *----------------------------------------------------------------------------
-*/
-
-#include "eas_chorusdata.h"
-
-S_CHORUS_OBJECT eas_ChorusData;
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 550 $
+ * $Date: 2007-02-02 09:37:03 -0800 (Fri, 02 Feb 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+#include "eas_chorusdata.h"
+
+S_CHORUS_OBJECT eas_ChorusData;
+
diff --git a/arm-fm-22k/lib_src/eas_chorusdata.h b/arm-fm-22k/lib_src/eas_chorusdata.h
index 4420ddd..ec8daa4 100644
--- a/arm-fm-22k/lib_src/eas_chorusdata.h
+++ b/arm-fm-22k/lib_src/eas_chorusdata.h
@@ -1,13 +1,13 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_chorusdata.h
- *
- * Contents and purpose:
- * Contains the prototypes for the Chorus effect.
- *
- *
- * Copyright Sonic Network Inc. 2006
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_chorusdata.h
+ *
+ * Contents and purpose:
+ * Contains the prototypes for the Chorus effect.
+ *
+ *
+ * Copyright Sonic Network Inc. 2006
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,141 +20,141 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 309 $
- * $Date: 2006-09-12 18:52:45 -0700 (Tue, 12 Sep 2006) $
- *----------------------------------------------------------------------------
-*/
-
-#ifndef _EAS_CHORUS_H
-#define _EAS_CHORUS_H
-
-#include "eas_types.h"
-#include "eas_audioconst.h"
-
-//defines for chorus
-
-#define EAS_CHORUS_BYPASS_DEFAULT 1
-#define EAS_CHORUS_PRESET_DEFAULT 0
-#define EAS_CHORUS_RATE_DEFAULT 30
-#define EAS_CHORUS_DEPTH_DEFAULT 39
-#define EAS_CHORUS_LEVEL_DEFAULT 32767
-
-#define EAS_CHORUS_LEVEL_MIN 0
-#define EAS_CHORUS_LEVEL_MAX 32767
-
-#define EAS_CHORUS_RATE_MIN 10
-#define EAS_CHORUS_RATE_MAX 50
-
-#define EAS_CHORUS_DEPTH_MIN 15
-#define EAS_CHORUS_DEPTH_MAX 60
-
-#define CHORUS_SIZE_MS 20
-#define CHORUS_L_SIZE ((CHORUS_SIZE_MS*_OUTPUT_SAMPLE_RATE)/1000)
-#define CHORUS_R_SIZE CHORUS_L_SIZE
-#define CHORUS_SHAPE_SIZE 128
-#define CHORUS_DELAY_MS 10
-
-#define CHORUS_MAX_TYPE 4 // any Chorus numbers larger than this are invalid
-
-typedef struct
-{
- EAS_I16 m_nRate;
- EAS_I16 m_nDepth;
- EAS_I16 m_nLevel;
-
-} S_CHORUS_PRESET;
-
-typedef struct
-{
- S_CHORUS_PRESET m_sPreset[CHORUS_MAX_TYPE]; //array of presets
-
-} S_CHORUS_PRESET_BANK;
-
-/* parameters for each Chorus */
-typedef struct
-{
- EAS_I32 lfoLPhase;
- EAS_I32 lfoRPhase;
- EAS_I16 chorusIndexL;
- EAS_I16 chorusIndexR;
- EAS_U16 chorusTapPosition;
-
- EAS_I16 m_nRate;
- EAS_I16 m_nDepth;
- EAS_I16 m_nLevel;
-
- //delay lines used by the chorus, longer would sound better
- EAS_PCM chorusDelayL[CHORUS_L_SIZE];
- EAS_PCM chorusDelayR[CHORUS_R_SIZE];
-
- EAS_BOOL bypass;
- EAS_I8 preset;
-
- EAS_I16 m_nCurrentChorus; // preset number for current Chorus
- EAS_I16 m_nNextChorus; // preset number for next Chorus
-
- S_CHORUS_PRESET pPreset;
-
- S_CHORUS_PRESET_BANK m_sPreset;
-
-} S_CHORUS_OBJECT;
-
-
-/*----------------------------------------------------------------------------
- * WeightedTap()
- *----------------------------------------------------------------------------
- * Purpose: Does fractional array look-up using linear interpolation
- *
- * first convert indexDesired to actual desired index by taking into account indexReference
- * then do linear interpolation between two actual samples using fractional part
- *
- * Inputs:
- * array: pointer to array of signed 16 bit values, typically either PCM data or control data
- * indexReference: the circular buffer relative offset
- * indexDesired: the fractional index we are looking up (16 bits index + 16 bits fraction)
- * indexLimit: the total size of the array, used to compute buffer wrap
- *
- * Outputs:
- * Value from the input array, linearly interpolated between two actual data values
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_I16 WeightedTap(const EAS_I16 *array, EAS_I16 indexReference, EAS_I32 indexDesired, EAS_I16 indexLimit);
-
-/*----------------------------------------------------------------------------
- * ChorusReadInPresets()
- *----------------------------------------------------------------------------
- * Purpose: sets global Chorus preset bank to defaults
- *
- * Inputs:
- *
- * Outputs:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT ChorusReadInPresets(S_CHORUS_OBJECT *pChorusData);
-
-/*----------------------------------------------------------------------------
- * ChorusUpdate
- *----------------------------------------------------------------------------
- * Purpose:
- * Update the Chorus preset parameters as required
- *
- * Inputs:
- *
- * Outputs:
- *
- *
- * Side Effects:
- * - chorus paramters will be changed
- * - m_nCurrentChorus := m_nNextChorus
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT ChorusUpdate(S_CHORUS_OBJECT* pChorusData);
-
-#endif /* #ifndef _EAS_CHORUSDATA_H */
-
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 309 $
+ * $Date: 2006-09-12 18:52:45 -0700 (Tue, 12 Sep 2006) $
+ *----------------------------------------------------------------------------
+*/
+
+#ifndef _EAS_CHORUS_H
+#define _EAS_CHORUS_H
+
+#include "eas_types.h"
+#include "eas_audioconst.h"
+
+//defines for chorus
+
+#define EAS_CHORUS_BYPASS_DEFAULT 1
+#define EAS_CHORUS_PRESET_DEFAULT 0
+#define EAS_CHORUS_RATE_DEFAULT 30
+#define EAS_CHORUS_DEPTH_DEFAULT 39
+#define EAS_CHORUS_LEVEL_DEFAULT 32767
+
+#define EAS_CHORUS_LEVEL_MIN 0
+#define EAS_CHORUS_LEVEL_MAX 32767
+
+#define EAS_CHORUS_RATE_MIN 10
+#define EAS_CHORUS_RATE_MAX 50
+
+#define EAS_CHORUS_DEPTH_MIN 15
+#define EAS_CHORUS_DEPTH_MAX 60
+
+#define CHORUS_SIZE_MS 20
+#define CHORUS_L_SIZE ((CHORUS_SIZE_MS*_OUTPUT_SAMPLE_RATE)/1000)
+#define CHORUS_R_SIZE CHORUS_L_SIZE
+#define CHORUS_SHAPE_SIZE 128
+#define CHORUS_DELAY_MS 10
+
+#define CHORUS_MAX_TYPE 4 // any Chorus numbers larger than this are invalid
+
+typedef struct
+{
+ EAS_I16 m_nRate;
+ EAS_I16 m_nDepth;
+ EAS_I16 m_nLevel;
+
+} S_CHORUS_PRESET;
+
+typedef struct
+{
+ S_CHORUS_PRESET m_sPreset[CHORUS_MAX_TYPE]; //array of presets
+
+} S_CHORUS_PRESET_BANK;
+
+/* parameters for each Chorus */
+typedef struct
+{
+ EAS_I32 lfoLPhase;
+ EAS_I32 lfoRPhase;
+ EAS_I16 chorusIndexL;
+ EAS_I16 chorusIndexR;
+ EAS_U16 chorusTapPosition;
+
+ EAS_I16 m_nRate;
+ EAS_I16 m_nDepth;
+ EAS_I16 m_nLevel;
+
+ //delay lines used by the chorus, longer would sound better
+ EAS_PCM chorusDelayL[CHORUS_L_SIZE];
+ EAS_PCM chorusDelayR[CHORUS_R_SIZE];
+
+ EAS_BOOL bypass;
+ EAS_I8 preset;
+
+ EAS_I16 m_nCurrentChorus; // preset number for current Chorus
+ EAS_I16 m_nNextChorus; // preset number for next Chorus
+
+ S_CHORUS_PRESET pPreset;
+
+ S_CHORUS_PRESET_BANK m_sPreset;
+
+} S_CHORUS_OBJECT;
+
+
+/*----------------------------------------------------------------------------
+ * WeightedTap()
+ *----------------------------------------------------------------------------
+ * Purpose: Does fractional array look-up using linear interpolation
+ *
+ * first convert indexDesired to actual desired index by taking into account indexReference
+ * then do linear interpolation between two actual samples using fractional part
+ *
+ * Inputs:
+ * array: pointer to array of signed 16 bit values, typically either PCM data or control data
+ * indexReference: the circular buffer relative offset
+ * indexDesired: the fractional index we are looking up (16 bits index + 16 bits fraction)
+ * indexLimit: the total size of the array, used to compute buffer wrap
+ *
+ * Outputs:
+ * Value from the input array, linearly interpolated between two actual data values
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_I16 WeightedTap(const EAS_I16 *array, EAS_I16 indexReference, EAS_I32 indexDesired, EAS_I16 indexLimit);
+
+/*----------------------------------------------------------------------------
+ * ChorusReadInPresets()
+ *----------------------------------------------------------------------------
+ * Purpose: sets global Chorus preset bank to defaults
+ *
+ * Inputs:
+ *
+ * Outputs:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT ChorusReadInPresets(S_CHORUS_OBJECT *pChorusData);
+
+/*----------------------------------------------------------------------------
+ * ChorusUpdate
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Update the Chorus preset parameters as required
+ *
+ * Inputs:
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ * - chorus paramters will be changed
+ * - m_nCurrentChorus := m_nNextChorus
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT ChorusUpdate(S_CHORUS_OBJECT* pChorusData);
+
+#endif /* #ifndef _EAS_CHORUSDATA_H */
+
+
diff --git a/arm-fm-22k/lib_src/eas_ctype.h b/arm-fm-22k/lib_src/eas_ctype.h
index 8503870..14fa96f 100644
--- a/arm-fm-22k/lib_src/eas_ctype.h
+++ b/arm-fm-22k/lib_src/eas_ctype.h
@@ -1,14 +1,14 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_ctype.h
- *
- * Contents and purpose:
- * This is a replacement for the CRT ctype.h functions. These
- * functions are currently ASCII only, but eventually, we will want
- * to support wide-characters for localization.
- *
- * Copyright (c) 2005 Sonic Network Inc.
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_ctype.h
+ *
+ * Contents and purpose:
+ * This is a replacement for the CRT ctype.h functions. These
+ * functions are currently ASCII only, but eventually, we will want
+ * to support wide-characters for localization.
+ *
+ * Copyright (c) 2005 Sonic Network Inc.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,21 +21,21 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 429 $
- * $Date: 2006-10-19 23:50:15 -0700 (Thu, 19 Oct 2006) $
- *----------------------------------------------------------------------------
-*/
-
-#ifndef _EAS_CTYPE_H
-#define _EAS_CTYPE_H
-
-EAS_INLINE EAS_I8 IsDigit (EAS_I8 c) { return ((c >= '0') && (c <= '9')); }
-EAS_INLINE EAS_I8 IsSpace (EAS_I8 c) { return (((c >= 9) && (c <= 13)) || (c == ' ')); }
-EAS_INLINE EAS_I8 ToUpper (EAS_I8 c) { if ((c >= 'a') && (c <= 'z')) return c & ~0x20; else return c; }
-EAS_INLINE EAS_I8 ToLower (EAS_I8 c) { if ((c >= 'A') && (c <= 'Z')) return c |= 0x20; else return c; }
-
-#endif
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 429 $
+ * $Date: 2006-10-19 23:50:15 -0700 (Thu, 19 Oct 2006) $
+ *----------------------------------------------------------------------------
+*/
+
+#ifndef _EAS_CTYPE_H
+#define _EAS_CTYPE_H
+
+EAS_INLINE EAS_I8 IsDigit (EAS_I8 c) { return ((c >= '0') && (c <= '9')); }
+EAS_INLINE EAS_I8 IsSpace (EAS_I8 c) { return (((c >= 9) && (c <= 13)) || (c == ' ')); }
+EAS_INLINE EAS_I8 ToUpper (EAS_I8 c) { if ((c >= 'a') && (c <= 'z')) return c & ~0x20; else return c; }
+EAS_INLINE EAS_I8 ToLower (EAS_I8 c) { if ((c >= 'A') && (c <= 'Z')) return c |= 0x20; else return c; }
+
+#endif
+
diff --git a/arm-fm-22k/lib_src/eas_data.c b/arm-fm-22k/lib_src/eas_data.c
index bb60ef2..31a4e6a 100644
--- a/arm-fm-22k/lib_src/eas_data.c
+++ b/arm-fm-22k/lib_src/eas_data.c
@@ -1,12 +1,12 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_data.c
- *
- * Contents and purpose:
- * Contains a data allocation for synthesizer
- *
- * Copyright Sonic Network Inc. 2004
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_data.c
+ *
+ * Contents and purpose:
+ * Contains a data allocation for synthesizer
+ *
+ * Copyright Sonic Network Inc. 2004
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,19 +19,19 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 547 $
- * $Date: 2007-01-31 16:30:17 -0800 (Wed, 31 Jan 2007) $
- *----------------------------------------------------------------------------
-*/
-
-// includes
-#include "eas_data.h"
-
-// globals
-S_EAS_DATA eas_Data;
-S_VOICE_MGR eas_Synth;
-S_SYNTH eas_MIDI;
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 547 $
+ * $Date: 2007-01-31 16:30:17 -0800 (Wed, 31 Jan 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+// includes
+#include "eas_data.h"
+
+// globals
+S_EAS_DATA eas_Data;
+S_VOICE_MGR eas_Synth;
+S_SYNTH eas_MIDI;
+
diff --git a/arm-fm-22k/lib_src/eas_data.h b/arm-fm-22k/lib_src/eas_data.h
index 0a47d04..e2fcb1a 100644
--- a/arm-fm-22k/lib_src/eas_data.h
+++ b/arm-fm-22k/lib_src/eas_data.h
@@ -1,13 +1,13 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_data.h
- *
- * Contents and purpose:
- * This header defines all types, to support dynamic allocation of the
- * memory resources needed for persistent EAS data.
- *
- * Copyright 2004 Sonic Network Inc.
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_data.h
+ *
+ * Contents and purpose:
+ * This header defines all types, to support dynamic allocation of the
+ * memory resources needed for persistent EAS data.
+ *
+ * Copyright 2004 Sonic Network Inc.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,112 +20,112 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 842 $
- * $Date: 2007-08-23 14:32:31 -0700 (Thu, 23 Aug 2007) $
- *----------------------------------------------------------------------------
-*/
-
-#ifndef _EAS_DATA_H
-#define _EAS_DATA_H
-
-#include "eas_types.h"
-#include "eas_synthcfg.h"
-#include "eas.h"
-#include "eas_audioconst.h"
-#include "eas_sndlib.h"
-#include "eas_pcm.h"
-#include "eas_pcmdata.h"
-#include "eas_synth.h"
-#include "eas_miditypes.h"
-#include "eas_effects.h"
-
-#ifdef AUX_MIXER
-#include "eas_auxmixdata.h"
-#endif
-
-#ifdef JET_INTERFACE
-#include "jet.h"
-#endif
-
-#ifdef _METRICS_ENABLED
-#include "eas_perf.h"
-#endif
-
-#ifndef MAX_NUMBER_STREAMS
-#define MAX_NUMBER_STREAMS 4
-#endif
-
-/* flags for S_EAS_STREAM */
-#define STREAM_FLAGS_PARSED 1
-#define STREAM_FLAGS_PAUSE 2
-#define STREAM_FLAGS_LOCATE 4
-#define STREAM_FLAGS_RESUME 8
-
-/* structure for parsing a stream */
-typedef struct s_eas_stream_tag
-{
- void *pParserModule;
- EAS_U32 time;
- EAS_U32 frameLength;
- EAS_I32 repeatCount;
- EAS_VOID_PTR handle;
- EAS_U8 volume;
- EAS_BOOL8 streamFlags;
-} S_EAS_STREAM;
-
-/* default master volume is -10dB */
-#define DEFAULT_VOLUME 90
-#define DEFAULT_STREAM_VOLUME 100
-#define DEFAULT_STREAM_GAIN 14622
-
-/* 10 dB of boost available for individual parsers */
-#define STREAM_VOLUME_HEADROOM 10
-
-/* amalgamated persistent data type */
-typedef struct s_eas_data_tag
-{
-#ifdef _CHECKED_BUILD
- EAS_U32 handleCheck;
-#endif
- EAS_HW_DATA_HANDLE hwInstData;
-
- S_EFFECTS_MODULE effectsModules[NUM_EFFECTS_MODULES];
-
-#ifdef _METRICS_ENABLED
- S_METRICS_INTERFACE *pMetricsModule;
- EAS_VOID_PTR pMetricsData;
-#endif
-
- EAS_I32 *pMixBuffer;
- EAS_PCM *pOutputAudioBuffer;
-
-#ifdef AUX_MIXER
- S_EAS_AUX_MIXER auxMixer;
-#endif
-
-#ifdef _MAXIMIZER_ENABLED
- EAS_VOID_PTR pMaximizerData;
-#endif
-
- S_EAS_STREAM streams[MAX_NUMBER_STREAMS];
-
- S_PCM_STATE *pPCMStreams;
-
- S_VOICE_MGR *pVoiceMgr;
-
-#ifdef JET_INTERFACE
- JET_DATA_HANDLE jetHandle;
-#endif
-
- EAS_U32 renderTime;
- EAS_I16 masterGain;
- EAS_U8 masterVolume;
- EAS_BOOL8 staticMemoryModel;
- EAS_BOOL8 searchHeaderFlag;
-} S_EAS_DATA;
-
-#endif
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 842 $
+ * $Date: 2007-08-23 14:32:31 -0700 (Thu, 23 Aug 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+#ifndef _EAS_DATA_H
+#define _EAS_DATA_H
+
+#include "eas_types.h"
+#include "eas_synthcfg.h"
+#include "eas.h"
+#include "eas_audioconst.h"
+#include "eas_sndlib.h"
+#include "eas_pcm.h"
+#include "eas_pcmdata.h"
+#include "eas_synth.h"
+#include "eas_miditypes.h"
+#include "eas_effects.h"
+
+#ifdef AUX_MIXER
+#include "eas_auxmixdata.h"
+#endif
+
+#ifdef JET_INTERFACE
+#include "jet.h"
+#endif
+
+#ifdef _METRICS_ENABLED
+#include "eas_perf.h"
+#endif
+
+#ifndef MAX_NUMBER_STREAMS
+#define MAX_NUMBER_STREAMS 4
+#endif
+
+/* flags for S_EAS_STREAM */
+#define STREAM_FLAGS_PARSED 1
+#define STREAM_FLAGS_PAUSE 2
+#define STREAM_FLAGS_LOCATE 4
+#define STREAM_FLAGS_RESUME 8
+
+/* structure for parsing a stream */
+typedef struct s_eas_stream_tag
+{
+ void *pParserModule;
+ EAS_U32 time;
+ EAS_U32 frameLength;
+ EAS_I32 repeatCount;
+ EAS_VOID_PTR handle;
+ EAS_U8 volume;
+ EAS_BOOL8 streamFlags;
+} S_EAS_STREAM;
+
+/* default master volume is -10dB */
+#define DEFAULT_VOLUME 90
+#define DEFAULT_STREAM_VOLUME 100
+#define DEFAULT_STREAM_GAIN 14622
+
+/* 10 dB of boost available for individual parsers */
+#define STREAM_VOLUME_HEADROOM 10
+
+/* amalgamated persistent data type */
+typedef struct s_eas_data_tag
+{
+#ifdef _CHECKED_BUILD
+ EAS_U32 handleCheck;
+#endif
+ EAS_HW_DATA_HANDLE hwInstData;
+
+ S_EFFECTS_MODULE effectsModules[NUM_EFFECTS_MODULES];
+
+#ifdef _METRICS_ENABLED
+ S_METRICS_INTERFACE *pMetricsModule;
+ EAS_VOID_PTR pMetricsData;
+#endif
+
+ EAS_I32 *pMixBuffer;
+ EAS_PCM *pOutputAudioBuffer;
+
+#ifdef AUX_MIXER
+ S_EAS_AUX_MIXER auxMixer;
+#endif
+
+#ifdef _MAXIMIZER_ENABLED
+ EAS_VOID_PTR pMaximizerData;
+#endif
+
+ S_EAS_STREAM streams[MAX_NUMBER_STREAMS];
+
+ S_PCM_STATE *pPCMStreams;
+
+ S_VOICE_MGR *pVoiceMgr;
+
+#ifdef JET_INTERFACE
+ JET_DATA_HANDLE jetHandle;
+#endif
+
+ EAS_U32 renderTime;
+ EAS_I16 masterGain;
+ EAS_U8 masterVolume;
+ EAS_BOOL8 staticMemoryModel;
+ EAS_BOOL8 searchHeaderFlag;
+} S_EAS_DATA;
+
+#endif
+
diff --git a/arm-fm-22k/lib_src/eas_effects.h b/arm-fm-22k/lib_src/eas_effects.h
index 01e64c0..86dedac 100644
--- a/arm-fm-22k/lib_src/eas_effects.h
+++ b/arm-fm-22k/lib_src/eas_effects.h
@@ -1,12 +1,12 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_effects.h
- *
- * Contents and purpose:
- * Defines a generic effects interface.
- *
- * Copyright Sonic Network Inc. 2005
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_effects.h
+ *
+ * Contents and purpose:
+ * Defines a generic effects interface.
+ *
+ * Copyright Sonic Network Inc. 2005
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,43 +19,43 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 82 $
- * $Date: 2006-07-10 11:45:19 -0700 (Mon, 10 Jul 2006) $
- *----------------------------------------------------------------------------
-*/
-
-#ifndef _EAS_EFFECTS_H
-#define _EAS_EFFECTS_H
-
-#include "eas_types.h"
-
-typedef struct
-{
- EAS_RESULT (*pfInit)(EAS_DATA_HANDLE pEASData, EAS_VOID_PTR *pInstData);
- void (*pfProcess)(EAS_VOID_PTR pInstData, EAS_PCM *in, EAS_PCM *out, EAS_I32 numSamples);
- EAS_RESULT (*pfShutdown)(EAS_DATA_HANDLE pEASData, EAS_VOID_PTR pInstData);
- EAS_RESULT (*pFGetParam)(EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue);
- EAS_RESULT (*pFSetParam)(EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value);
-} S_EFFECTS_INTERFACE;
-
-typedef struct
-{
- EAS_RESULT (*pfInit)(EAS_DATA_HANDLE pEASData, EAS_VOID_PTR *pInstData);
- void (*pfProcess)(EAS_VOID_PTR pInstData, EAS_I32 *in, EAS_I32 *out, EAS_I32 numSamples);
- EAS_RESULT (*pfShutdown)(EAS_DATA_HANDLE pEASData, EAS_VOID_PTR pInstData);
- EAS_RESULT (*pFGetParam)(EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue);
- EAS_RESULT (*pFSetParam)(EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value);
-} S_EFFECTS32_INTERFACE;
-
-/* mixer instance data */
-typedef struct
-{
- S_EFFECTS_INTERFACE *effect;
- EAS_VOID_PTR effectData;
-} S_EFFECTS_MODULE;
-
-#endif /* end _EAS_EFFECTS_H */
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 82 $
+ * $Date: 2006-07-10 11:45:19 -0700 (Mon, 10 Jul 2006) $
+ *----------------------------------------------------------------------------
+*/
+
+#ifndef _EAS_EFFECTS_H
+#define _EAS_EFFECTS_H
+
+#include "eas_types.h"
+
+typedef struct
+{
+ EAS_RESULT (*pfInit)(EAS_DATA_HANDLE pEASData, EAS_VOID_PTR *pInstData);
+ void (*pfProcess)(EAS_VOID_PTR pInstData, EAS_PCM *in, EAS_PCM *out, EAS_I32 numSamples);
+ EAS_RESULT (*pfShutdown)(EAS_DATA_HANDLE pEASData, EAS_VOID_PTR pInstData);
+ EAS_RESULT (*pFGetParam)(EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue);
+ EAS_RESULT (*pFSetParam)(EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value);
+} S_EFFECTS_INTERFACE;
+
+typedef struct
+{
+ EAS_RESULT (*pfInit)(EAS_DATA_HANDLE pEASData, EAS_VOID_PTR *pInstData);
+ void (*pfProcess)(EAS_VOID_PTR pInstData, EAS_I32 *in, EAS_I32 *out, EAS_I32 numSamples);
+ EAS_RESULT (*pfShutdown)(EAS_DATA_HANDLE pEASData, EAS_VOID_PTR pInstData);
+ EAS_RESULT (*pFGetParam)(EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue);
+ EAS_RESULT (*pFSetParam)(EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value);
+} S_EFFECTS32_INTERFACE;
+
+/* mixer instance data */
+typedef struct
+{
+ S_EFFECTS_INTERFACE *effect;
+ EAS_VOID_PTR effectData;
+} S_EFFECTS_MODULE;
+
+#endif /* end _EAS_EFFECTS_H */
+
diff --git a/arm-fm-22k/lib_src/eas_fmengine.c b/arm-fm-22k/lib_src/eas_fmengine.c
index 9c3da66..ea7f69c 100644
--- a/arm-fm-22k/lib_src/eas_fmengine.c
+++ b/arm-fm-22k/lib_src/eas_fmengine.c
@@ -1,12 +1,12 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_fmengine.c
- *
- * Contents and purpose:
- * Implements the low-level FM synthesizer functions.
- *
- * Copyright Sonic Network Inc. 2004, 2005
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_fmengine.c
+ *
+ * Contents and purpose:
+ * Implements the low-level FM synthesizer functions.
+ *
+ * Copyright Sonic Network Inc. 2004, 2005
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,767 +19,767 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 795 $
- * $Date: 2007-08-01 00:14:45 -0700 (Wed, 01 Aug 2007) $
- *----------------------------------------------------------------------------
-*/
-
-/* includes */
-#include "eas_types.h"
-#include "eas_math.h"
-#include "eas_audioconst.h"
-#include "eas_fmengine.h"
-
-#if defined(EAS_FM_SYNTH) || defined(EAS_HYBRID_SYNTH) || defined(EAS_SPLIT_HYBRID_SYNTH) || defined(EAS_SPLIT_FM_SYNTH)
-#include "eas_data.h"
-#endif
-
-/* externals */
-extern const EAS_I16 sineTable[];
-extern const EAS_U8 fmScaleTable[16];
-
-// saturation constants for 32-bit to 16-bit conversion
-#define _EAS_MAX_OUTPUT 32767
-#define _EAS_MIN_OUTPUT -32767
-
-static S_FM_ENG_VOICE voices[NUM_FM_VOICES];
-
-/* local prototypes */
-void FM_SynthMixVoice (S_FM_ENG_VOICE *p, EAS_U16 gainTarget, EAS_I32 numSamplesToAdd, EAS_PCM *pInputBuffer, EAS_I32 *pBuffer);
-
-/* used in development environment */
-#if defined(_SATURATION_MONITOR)
-static EAS_BOOL bSaturated = EAS_FALSE;
-
-/*----------------------------------------------------------------------------
- * FM_CheckSaturation()
- *----------------------------------------------------------------------------
- * Purpose:
- * Allows the sound development tool to check for saturation at the voice
- * level. Useful for tuning the level controls.
- *
- * Inputs:
- *
- * Outputs:
- * Returns true if saturation has occurred since the last time the function
- * was called.
- *
- * Side Effects:
- * Resets the saturation flag
- *----------------------------------------------------------------------------
-*/
-EAS_BOOL FM_CheckSaturation ()
-{
- EAS_BOOL bTemp;
- bTemp = bSaturated;
- bSaturated = EAS_FALSE;
- return bTemp;
-}
-#endif
-
-/*----------------------------------------------------------------------------
- * FM_Saturate()
- *----------------------------------------------------------------------------
- * Purpose:
- * This inline function saturates a 32-bit number to 16-bits
- *
- * Inputs:
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- * Returns a 16-bit integer
- *----------------------------------------------------------------------------
-*/
-EAS_INLINE EAS_I16 FM_Saturate (EAS_I32 nValue)
-{
- if (nValue > _EAS_MAX_OUTPUT)
- {
-#if defined(_SATURATION_MONITOR)
- bSaturated = EAS_TRUE;
-#endif
- return _EAS_MAX_OUTPUT;
- }
- if (nValue < _EAS_MIN_OUTPUT)
- {
-#if defined(_SATURATION_MONITOR)
- bSaturated = EAS_TRUE;
-#endif
- return _EAS_MIN_OUTPUT;
- }
- return (EAS_I16) nValue;
-}
-
-/*----------------------------------------------------------------------------
- * FM_Noise()
- *----------------------------------------------------------------------------
- * Purpose:
- * A 31-bit low-cost linear congruential PRNG algorithm used to
- * generate noise.
- *
- * Inputs:
- * pnSeed - pointer to 32-bit PRNG seed
- *
- * Outputs:
- * Returns a 16-bit integer
- *----------------------------------------------------------------------------
-*/
-EAS_INLINE EAS_I16 FM_Noise (EAS_U32 *pnSeed)
-{
- *pnSeed = *pnSeed * 214013L + 2531011L;
- return (EAS_I16) ((*pnSeed >> 15) & 0xffff);
-}
-
-/*----------------------------------------------------------------------------
- * FM_PhaseInc()
- *----------------------------------------------------------------------------
- * Purpose:
- * Transform pitch cents to linear phase increment
- *
- * Inputs:
- * nCents - measured in cents
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- * nResult - int.frac result (where frac has NUM_DENTS_FRAC_BITS)
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_I32 FM_PhaseInc (EAS_I32 nCents)
-{
- EAS_I32 nDents;
- EAS_I32 nExponentInt, nExponentFrac;
- EAS_I32 nTemp1, nTemp2;
- EAS_I32 nResult;
-
- /* convert cents to dents */
- nDents = FMUL_15x15(nCents, CENTS_TO_DENTS);
- nExponentInt = GET_DENTS_INT_PART(nDents) + (32 - SINE_TABLE_SIZE_IN_BITS - NUM_EG1_FRAC_BITS);
- nExponentFrac = GET_DENTS_FRAC_PART(nDents);
-
- /* implement 2^(fracPart) as a power series */
- nTemp1 = GN2_TO_X2 + MULT_DENTS_COEF(nExponentFrac, GN2_TO_X3);
- nTemp2 = GN2_TO_X1 + MULT_DENTS_COEF(nExponentFrac, nTemp1);
- nTemp1 = GN2_TO_X0 + MULT_DENTS_COEF(nExponentFrac, nTemp2);
-
- /*
- implement 2^(intPart) as
- a left shift for intPart >= 0 or
- a left shift for intPart < 0
- */
- if (nExponentInt >= 0)
- {
- /* left shift for positive exponents */
- /*lint -e{703} <avoid multiply for performance>*/
- nResult = nTemp1 << nExponentInt;
- }
- else
- {
- /* right shift for negative exponents */
- nExponentInt = -nExponentInt;
- nResult = nTemp1 >> nExponentInt;
- }
-
- return nResult;
-}
-
-#if (NUM_OUTPUT_CHANNELS == 2)
-/*----------------------------------------------------------------------------
- * FM_CalculatePan()
- *----------------------------------------------------------------------------
- * Purpose:
- * Assign the left and right gain values corresponding to the given pan value.
- *
- * Inputs:
- * psVoice - ptr to the voice we have assigned for this channel
- * psArticulation - ptr to this voice's articulation
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- *
- * Side Effects:
- * the given voice's m_nGainLeft and m_nGainRight are assigned
- *----------------------------------------------------------------------------
-*/
-static void FM_CalculatePan (EAS_I16 pan, EAS_U16 *pGainLeft, EAS_U16 *pGainRight)
-{
- EAS_I32 nTemp;
- EAS_INT nNetAngle;
-
- /*
- Implement the following
- sin(x) = (2-4*c)*x^2 + c + x
- cos(x) = (2-4*c)*x^2 + c - x
-
- where c = 1/sqrt(2)
- using the a0 + x*(a1 + x*a2) approach
- */
-
- /*
- Get the Midi CC10 pan value for this voice's channel
- convert the pan value to an "angle" representation suitable for
- our sin, cos calculator. This representation is NOT necessarily the same
- as the transform in the GM manuals because of our sin, cos calculator.
- "angle" = (CC10 - 64)/128
- */
- /*lint -e{703} <avoid multiply for performance reasons>*/
- nNetAngle = ((EAS_I32) pan) << (NUM_EG1_FRAC_BITS -7);
-
- /* calculate sin */
- nTemp = EG1_ONE + FMUL_15x15(COEFF_PAN_G2, nNetAngle);
- nTemp = COEFF_PAN_G0 + FMUL_15x15(nTemp, nNetAngle);
-
- if (nTemp > SYNTH_FULL_SCALE_EG1_GAIN)
- nTemp = SYNTH_FULL_SCALE_EG1_GAIN;
- else if (nTemp < 0)
- nTemp = 0;
-
- *pGainRight = (EAS_U16) nTemp;
-
- /* calculate cos */
- nTemp = -EG1_ONE + FMUL_15x15(COEFF_PAN_G2, nNetAngle);
- nTemp = COEFF_PAN_G0 + FMUL_15x15(nTemp, nNetAngle);
-
- if (nTemp > SYNTH_FULL_SCALE_EG1_GAIN)
- nTemp = SYNTH_FULL_SCALE_EG1_GAIN;
- else if (nTemp < 0)
- nTemp = 0;
-
- *pGainLeft = (EAS_U16) nTemp;
-}
-#endif /* #if (NUM_OUTPUT_CHANNELS == 2) */
-
-/*----------------------------------------------------------------------------
- * FM_Operator()
- *----------------------------------------------------------------------------
- * Purpose:
- * Synthesizes a buffer of samples based on passed parameters.
- *
- * Inputs:
- * nNumSamplesToAdd - number of samples to synthesize
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-void FM_Operator (
- S_FM_ENG_OPER *p,
- EAS_I32 numSamplesToAdd,
- EAS_PCM *pBuffer,
- EAS_PCM *pModBuffer,
- EAS_BOOL mix,
- EAS_U16 gainTarget,
- EAS_I16 pitch,
- EAS_U8 feedback,
- EAS_I16 *pLastOutput)
-{
- EAS_I32 gain;
- EAS_I32 gainInc;
- EAS_U32 phase;
- EAS_U32 phaseInc;
- EAS_U32 phaseTemp;
- EAS_I32 temp;
- EAS_I32 temp2;
-
- /* establish local gain variable */
- gain = (EAS_I32) p->gain << 16;
-
- /* calculate gain increment */
- /*lint -e{703} use shift for performance */
- gainInc = ((EAS_I32) gainTarget - (EAS_I32) p->gain) << (16 - SYNTH_UPDATE_PERIOD_IN_BITS);
-
- /* establish local phase variables */
- phase = p->phase;
-
- /* calculate the new phase increment */
- phaseInc = (EAS_U32) FM_PhaseInc(pitch);
-
- /* restore final output from previous frame for feedback loop */
- if (pLastOutput)
- temp = *pLastOutput;
- else
- temp = 0;
-
- /* generate a buffer of samples */
- while (numSamplesToAdd--)
- {
-
- /* incorporate modulation */
- if (pModBuffer)
- {
- /*lint -e{701} use shift for performance */
- temp = *pModBuffer++ << FM_MODULATOR_INPUT_SHIFT;
- }
-
- /* incorporate feedback */
- else
- {
- /*lint -e{703} use shift for performance */
- temp = (temp * (EAS_I32) feedback) << FM_FEEDBACK_SHIFT;
- }
-
- /*lint -e{737} <use this behavior to avoid extra mask step> */
- phaseTemp = phase + temp;
-
- /* fetch sample from wavetable */
- temp = sineTable[phaseTemp >> (32 - SINE_TABLE_SIZE_IN_BITS)];
-
- /* increment operator phase */
- phase += phaseInc;
-
- /* internal gain for modulation effects */
- temp = FMUL_15x15(temp, (gain >> 16));
-
- /* output gain calculation */
- temp2 = FMUL_15x15(temp, p->outputGain);
-
- /* saturating add to buffer */
- if (mix)
- {
- temp2 += *pBuffer;
- *pBuffer++ = FM_Saturate(temp2);
- }
-
- /* output to buffer */
- else
- *pBuffer++ = (EAS_I16) temp2;
-
- /* increment gain */
- gain += gainInc;
-
- }
-
- /* save phase and gain */
- p->phase = phase;
- p->gain = gainTarget;
-
- /* save last output for feedback in next frame */
- if (pLastOutput)
- *pLastOutput = (EAS_I16) temp;
-}
-
-/*----------------------------------------------------------------------------
- * FM_NoiseOperator()
- *----------------------------------------------------------------------------
- * Purpose:
- * Synthesizes a buffer of samples based on passed parameters.
- *
- * Inputs:
- * nNumSamplesToAdd - number of samples to synthesize
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-void FM_NoiseOperator (
- S_FM_ENG_OPER *p,
- EAS_I32 numSamplesToAdd,
- EAS_PCM *pBuffer,
- EAS_BOOL mix,
- EAS_U16 gainTarget,
- EAS_U8 feedback,
- EAS_I16 *pLastOutput)
-{
- EAS_I32 gain;
- EAS_I32 gainInc;
- EAS_U32 phase;
- EAS_I32 temp;
- EAS_I32 temp2;
-
- /* establish local gain variable */
- gain = (EAS_I32) p->gain << 16;
-
- /* calculate gain increment */
- /*lint -e{703} use shift for performance */
- gainInc = ((EAS_I32) gainTarget - (EAS_I32) p->gain) << (16 - SYNTH_UPDATE_PERIOD_IN_BITS);
-
- /* establish local phase variables */
- phase = p->phase;
-
- /* establish local phase variables */
- phase = p->phase;
-
- /* recall last sample for filter Z-1 term */
- temp = 0;
- if (pLastOutput)
- temp = *pLastOutput;
-
- /* generate a buffer of samples */
- while (numSamplesToAdd--)
- {
-
- /* if using filter */
- if (pLastOutput)
- {
- /* use PRNG for noise */
- temp2 = FM_Noise(&phase);
-
- /*lint -e{704} use shift for performance */
- temp += ((temp2 -temp) * feedback) >> 8;
- }
- else
- {
- temp = FM_Noise(&phase);
- }
-
- /* internal gain for modulation effects */
- temp2 = FMUL_15x15(temp, (gain >> 16));
-
- /* output gain calculation */
- temp2 = FMUL_15x15(temp2, p->outputGain);
-
- /* saturating add to buffer */
- if (mix)
- {
- temp2 += *pBuffer;
- *pBuffer++ = FM_Saturate(temp2);
- }
-
- /* output to buffer */
- else
- *pBuffer++ = (EAS_I16) temp2;
-
- /* increment gain */
- gain += gainInc;
-
- }
-
- /* save phase and gain */
- p->phase = phase;
- p->gain = gainTarget;
-
- /* save last output for feedback in next frame */
- if (pLastOutput)
- *pLastOutput = (EAS_I16) temp;
-}
-
-/*----------------------------------------------------------------------------
- * FM_ConfigVoice()
- *----------------------------------------------------------------------------
- * Purpose:
- * Receives parameters to start a new voice.
- *
- * Inputs:
- * voiceNum - voice number to start
- * vCfg - configuration data
- * pMixBuffer - pointer to host supplied buffer
- *
- * Outputs:
- *
- * Side Effects:
- *
- * Notes:
- * pFrameBuffer is not used in the test version, but is passed as a
- * courtesy to split architecture implementations. It can be used as
- * as pointer to the interprocessor communications buffer when the
- * synthesis parameters are passed off to a DSP for synthesis.
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, pFrameBuffer) pFrameBuffer not used in test version - see above */
-void FM_ConfigVoice (EAS_I32 voiceNum, S_FM_VOICE_CONFIG *vCfg, EAS_FRAME_BUFFER_HANDLE pFrameBuffer)
-{
- S_FM_ENG_VOICE *pVoice;
- EAS_INT i;
-
- /* establish pointer to voice data */
- pVoice = &voices[voiceNum];
-
- /* save data */
- pVoice->feedback = vCfg->feedback;
- pVoice->flags = vCfg->flags;
- pVoice->voiceGain = vCfg->voiceGain;
-
- /* initialize Z-1 terms */
- pVoice->op1Out = 0;
- pVoice->op3Out = 0;
-
- /* initialize operators */
- for (i = 0; i < 4; i++)
- {
- /* save operator data */
- pVoice->oper[i].gain = vCfg->gain[i];
- pVoice->oper[i].outputGain = vCfg->outputGain[i];
- pVoice->oper[i].outputGain = vCfg->outputGain[i];
-
- /* initalize operator */
- pVoice->oper[i].phase = 0;
- }
-
- /* calculate pan */
-#if NUM_OUTPUT_CHANNELS == 2
- FM_CalculatePan(vCfg->pan, &pVoice->gainLeft, &pVoice->gainRight);
-#endif
-}
-
-/*----------------------------------------------------------------------------
- * FM_ProcessVoice()
- *----------------------------------------------------------------------------
- * Purpose:
- * Synthesizes a buffer of samples based on calculated parameters.
- *
- * Inputs:
- * nNumSamplesToAdd - number of samples to synthesize
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- *
- * Side Effects:
- *
- * Notes:
- * pOut is not used in the test version, but is passed as a
- * courtesy to split architecture implementations. It can be used as
- * as pointer to the interprocessor communications buffer when the
- * synthesis parameters are passed off to a DSP for synthesis.
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, pOut) pOut not used in test version - see above */
-void FM_ProcessVoice (
- EAS_I32 voiceNum,
- S_FM_VOICE_FRAME *pFrame,
- EAS_I32 numSamplesToAdd,
- EAS_PCM *pTempBuffer,
- EAS_PCM *pBuffer,
- EAS_I32 *pMixBuffer,
- EAS_FRAME_BUFFER_HANDLE pFrameBuffer)
-{
- S_FM_ENG_VOICE *p;
- EAS_PCM *pOutBuf;
- EAS_PCM *pMod;
- EAS_BOOL mix;
- EAS_U8 feedback1;
- EAS_U8 feedback3;
- EAS_U8 mode;
-
- /* establish pointer to voice data */
- p = &voices[voiceNum];
- mode = p->flags & 0x07;
-
- /* lookup feedback values */
- feedback1 = fmScaleTable[p->feedback >> 4];
- feedback3 = fmScaleTable[p->feedback & 0x0f];
-
- /* operator 3 is on output bus in modes 0, 1, and 3 */
- if ((mode == 0) || (mode == 1) || (mode == 3))
- pOutBuf = pBuffer;
- else
- pOutBuf = pTempBuffer;
-
- if (p->flags & FLAG_FM_ENG_VOICE_OP3_NOISE)
- {
- FM_NoiseOperator(
- p->oper + 2,
- numSamplesToAdd,
- pOutBuf,
- EAS_FALSE,
- pFrame->gain[2],
- feedback3,
- &p->op3Out);
- }
- else
- {
- FM_Operator(
- p->oper + 2,
- numSamplesToAdd,
- pOutBuf,
- 0,
- EAS_FALSE,
- pFrame->gain[2],
- pFrame->pitch[2],
- feedback3,
- &p->op3Out);
- }
-
- /* operator 4 is on output bus in modes 0, 1, and 2 */
- if (mode < 3)
- pOutBuf = pBuffer;
- else
- pOutBuf = pTempBuffer;
-
- /* operator 4 is modulated in modes 2, 4, and 5 */
- if ((mode == 2) || (mode == 4) || (mode == 5))
- pMod = pTempBuffer;
- else
- pMod = 0;
-
- /* operator 4 is in mix mode in modes 0 and 1 */
- mix = (mode < 2);
-
- if (p->flags & FLAG_FM_ENG_VOICE_OP4_NOISE)
- {
- FM_NoiseOperator(
- p->oper + 3,
- numSamplesToAdd,
- pOutBuf,
- mix,
- pFrame->gain[3],
- 0,
- 0);
- }
- else
- {
- FM_Operator(
- p->oper + 3,
- numSamplesToAdd,
- pOutBuf,
- pMod,
- mix,
- pFrame->gain[3],
- pFrame->pitch[3],
- 0,
- 0);
- }
-
- /* operator 1 is on output bus in mode 0 */
- if (mode == 0)
- pOutBuf = pBuffer;
- else
- pOutBuf = pTempBuffer;
-
- /* operator 1 is modulated in modes 3 and 4 */
- if ((mode == 3) || (mode == 4))
- pMod = pTempBuffer;
- else
- pMod = 0;
-
- /* operator 1 is in mix mode in modes 0 and 5 */
- mix = ((mode == 0) || (mode == 5));
-
- if (p->flags & FLAG_FM_ENG_VOICE_OP1_NOISE)
- {
- FM_NoiseOperator(
- p->oper,
- numSamplesToAdd,
- pOutBuf,
- mix,
- pFrame->gain[0],
- feedback1,
- &p->op1Out);
- }
- else
- {
- FM_Operator(
- p->oper,
- numSamplesToAdd,
- pOutBuf,
- pMod,
- mix,
- pFrame->gain[0],
- pFrame->pitch[0],
- feedback1,
- &p->op1Out);
- }
-
- /* operator 2 is modulated in all modes except 0 */
- if (mode != 0)
- pMod = pTempBuffer;
- else
- pMod = 0;
-
- /* operator 1 is in mix mode in modes 0 -3 */
- mix = (mode < 4);
-
- if (p->flags & FLAG_FM_ENG_VOICE_OP2_NOISE)
- {
- FM_NoiseOperator(
- p->oper + 1,
- numSamplesToAdd,
- pBuffer,
- mix,
- pFrame->gain[1],
- 0,
- 0);
- }
- else
- {
- FM_Operator(
- p->oper + 1,
- numSamplesToAdd,
- pBuffer,
- pMod,
- mix,
- pFrame->gain[1],
- pFrame->pitch[1],
- 0,
- 0);
- }
-
- /* mix voice output to synthesizer output buffer */
- FM_SynthMixVoice(p, pFrame->voiceGain, numSamplesToAdd, pBuffer, pMixBuffer);
-}
-
-/*----------------------------------------------------------------------------
- * FM_SynthMixVoice()
- *----------------------------------------------------------------------------
- * Purpose:
- * Mixes the voice output buffer into the final mix using an anti-zipper
- * filter.
- *
- * Inputs:
- * nNumSamplesToAdd - number of samples to synthesize
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-void FM_SynthMixVoice(S_FM_ENG_VOICE *p, EAS_U16 nGainTarget, EAS_I32 numSamplesToAdd, EAS_PCM *pInputBuffer, EAS_I32 *pBuffer)
-{
- EAS_I32 nGain;
- EAS_I32 nGainInc;
- EAS_I32 nTemp;
-
- /* restore previous gain */
- /*lint -e{703} <use shift for performance> */
- nGain = (EAS_I32) p->voiceGain << 16;
-
- /* calculate gain increment */
- /*lint -e{703} <use shift for performance> */
- nGainInc = ((EAS_I32) nGainTarget - (EAS_I32) p->voiceGain) << (16 - SYNTH_UPDATE_PERIOD_IN_BITS);
-
- /* mix the output buffer */
- while (numSamplesToAdd--)
- {
- /* output gain calculation */
- nTemp = *pInputBuffer++;
-
- /* sum to output buffer */
-#if (NUM_OUTPUT_CHANNELS == 2)
-
- /*lint -e{704} <use shift for performance> */
- nTemp = ((EAS_I32) nTemp * (nGain >> 16)) >> FM_GAIN_SHIFT;
-
- /*lint -e{704} <use shift for performance> */
- {
- EAS_I32 nTemp2;
- nTemp = nTemp >> FM_STEREO_PRE_GAIN_SHIFT;
- nTemp2 = (nTemp * p->gainLeft) >> FM_STEREO_POST_GAIN_SHIFT;
- *pBuffer++ += nTemp2;
- nTemp2 = (nTemp * p->gainRight) >> FM_STEREO_POST_GAIN_SHIFT;
- *pBuffer++ += nTemp2;
- }
-#else
- /*lint -e{704} <use shift for performance> */
- nTemp = ((EAS_I32) nTemp * (nGain >> 16)) >> FM_MONO_GAIN_SHIFT;
- *pBuffer++ += nTemp;
-#endif
-
- /* increment gain for anti-zipper filter */
- nGain += nGainInc;
- }
-
- /* save gain */
- p->voiceGain = nGainTarget;
-}
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 795 $
+ * $Date: 2007-08-01 00:14:45 -0700 (Wed, 01 Aug 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+/* includes */
+#include "eas_types.h"
+#include "eas_math.h"
+#include "eas_audioconst.h"
+#include "eas_fmengine.h"
+
+#if defined(EAS_FM_SYNTH) || defined(EAS_HYBRID_SYNTH) || defined(EAS_SPLIT_HYBRID_SYNTH) || defined(EAS_SPLIT_FM_SYNTH)
+#include "eas_data.h"
+#endif
+
+/* externals */
+extern const EAS_I16 sineTable[];
+extern const EAS_U8 fmScaleTable[16];
+
+// saturation constants for 32-bit to 16-bit conversion
+#define _EAS_MAX_OUTPUT 32767
+#define _EAS_MIN_OUTPUT -32767
+
+static S_FM_ENG_VOICE voices[NUM_FM_VOICES];
+
+/* local prototypes */
+void FM_SynthMixVoice (S_FM_ENG_VOICE *p, EAS_U16 gainTarget, EAS_I32 numSamplesToAdd, EAS_PCM *pInputBuffer, EAS_I32 *pBuffer);
+
+/* used in development environment */
+#if defined(_SATURATION_MONITOR)
+static EAS_BOOL bSaturated = EAS_FALSE;
+
+/*----------------------------------------------------------------------------
+ * FM_CheckSaturation()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Allows the sound development tool to check for saturation at the voice
+ * level. Useful for tuning the level controls.
+ *
+ * Inputs:
+ *
+ * Outputs:
+ * Returns true if saturation has occurred since the last time the function
+ * was called.
+ *
+ * Side Effects:
+ * Resets the saturation flag
+ *----------------------------------------------------------------------------
+*/
+EAS_BOOL FM_CheckSaturation ()
+{
+ EAS_BOOL bTemp;
+ bTemp = bSaturated;
+ bSaturated = EAS_FALSE;
+ return bTemp;
+}
+#endif
+
+/*----------------------------------------------------------------------------
+ * FM_Saturate()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * This inline function saturates a 32-bit number to 16-bits
+ *
+ * Inputs:
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ * Returns a 16-bit integer
+ *----------------------------------------------------------------------------
+*/
+EAS_INLINE EAS_I16 FM_Saturate (EAS_I32 nValue)
+{
+ if (nValue > _EAS_MAX_OUTPUT)
+ {
+#if defined(_SATURATION_MONITOR)
+ bSaturated = EAS_TRUE;
+#endif
+ return _EAS_MAX_OUTPUT;
+ }
+ if (nValue < _EAS_MIN_OUTPUT)
+ {
+#if defined(_SATURATION_MONITOR)
+ bSaturated = EAS_TRUE;
+#endif
+ return _EAS_MIN_OUTPUT;
+ }
+ return (EAS_I16) nValue;
+}
+
+/*----------------------------------------------------------------------------
+ * FM_Noise()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * A 31-bit low-cost linear congruential PRNG algorithm used to
+ * generate noise.
+ *
+ * Inputs:
+ * pnSeed - pointer to 32-bit PRNG seed
+ *
+ * Outputs:
+ * Returns a 16-bit integer
+ *----------------------------------------------------------------------------
+*/
+EAS_INLINE EAS_I16 FM_Noise (EAS_U32 *pnSeed)
+{
+ *pnSeed = *pnSeed * 214013L + 2531011L;
+ return (EAS_I16) ((*pnSeed >> 15) & 0xffff);
+}
+
+/*----------------------------------------------------------------------------
+ * FM_PhaseInc()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Transform pitch cents to linear phase increment
+ *
+ * Inputs:
+ * nCents - measured in cents
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ * nResult - int.frac result (where frac has NUM_DENTS_FRAC_BITS)
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_I32 FM_PhaseInc (EAS_I32 nCents)
+{
+ EAS_I32 nDents;
+ EAS_I32 nExponentInt, nExponentFrac;
+ EAS_I32 nTemp1, nTemp2;
+ EAS_I32 nResult;
+
+ /* convert cents to dents */
+ nDents = FMUL_15x15(nCents, CENTS_TO_DENTS);
+ nExponentInt = GET_DENTS_INT_PART(nDents) + (32 - SINE_TABLE_SIZE_IN_BITS - NUM_EG1_FRAC_BITS);
+ nExponentFrac = GET_DENTS_FRAC_PART(nDents);
+
+ /* implement 2^(fracPart) as a power series */
+ nTemp1 = GN2_TO_X2 + MULT_DENTS_COEF(nExponentFrac, GN2_TO_X3);
+ nTemp2 = GN2_TO_X1 + MULT_DENTS_COEF(nExponentFrac, nTemp1);
+ nTemp1 = GN2_TO_X0 + MULT_DENTS_COEF(nExponentFrac, nTemp2);
+
+ /*
+ implement 2^(intPart) as
+ a left shift for intPart >= 0 or
+ a left shift for intPart < 0
+ */
+ if (nExponentInt >= 0)
+ {
+ /* left shift for positive exponents */
+ /*lint -e{703} <avoid multiply for performance>*/
+ nResult = nTemp1 << nExponentInt;
+ }
+ else
+ {
+ /* right shift for negative exponents */
+ nExponentInt = -nExponentInt;
+ nResult = nTemp1 >> nExponentInt;
+ }
+
+ return nResult;
+}
+
+#if (NUM_OUTPUT_CHANNELS == 2)
+/*----------------------------------------------------------------------------
+ * FM_CalculatePan()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Assign the left and right gain values corresponding to the given pan value.
+ *
+ * Inputs:
+ * psVoice - ptr to the voice we have assigned for this channel
+ * psArticulation - ptr to this voice's articulation
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ * the given voice's m_nGainLeft and m_nGainRight are assigned
+ *----------------------------------------------------------------------------
+*/
+static void FM_CalculatePan (EAS_I16 pan, EAS_U16 *pGainLeft, EAS_U16 *pGainRight)
+{
+ EAS_I32 nTemp;
+ EAS_INT nNetAngle;
+
+ /*
+ Implement the following
+ sin(x) = (2-4*c)*x^2 + c + x
+ cos(x) = (2-4*c)*x^2 + c - x
+
+ where c = 1/sqrt(2)
+ using the a0 + x*(a1 + x*a2) approach
+ */
+
+ /*
+ Get the Midi CC10 pan value for this voice's channel
+ convert the pan value to an "angle" representation suitable for
+ our sin, cos calculator. This representation is NOT necessarily the same
+ as the transform in the GM manuals because of our sin, cos calculator.
+ "angle" = (CC10 - 64)/128
+ */
+ /*lint -e{703} <avoid multiply for performance reasons>*/
+ nNetAngle = ((EAS_I32) pan) << (NUM_EG1_FRAC_BITS -7);
+
+ /* calculate sin */
+ nTemp = EG1_ONE + FMUL_15x15(COEFF_PAN_G2, nNetAngle);
+ nTemp = COEFF_PAN_G0 + FMUL_15x15(nTemp, nNetAngle);
+
+ if (nTemp > SYNTH_FULL_SCALE_EG1_GAIN)
+ nTemp = SYNTH_FULL_SCALE_EG1_GAIN;
+ else if (nTemp < 0)
+ nTemp = 0;
+
+ *pGainRight = (EAS_U16) nTemp;
+
+ /* calculate cos */
+ nTemp = -EG1_ONE + FMUL_15x15(COEFF_PAN_G2, nNetAngle);
+ nTemp = COEFF_PAN_G0 + FMUL_15x15(nTemp, nNetAngle);
+
+ if (nTemp > SYNTH_FULL_SCALE_EG1_GAIN)
+ nTemp = SYNTH_FULL_SCALE_EG1_GAIN;
+ else if (nTemp < 0)
+ nTemp = 0;
+
+ *pGainLeft = (EAS_U16) nTemp;
+}
+#endif /* #if (NUM_OUTPUT_CHANNELS == 2) */
+
+/*----------------------------------------------------------------------------
+ * FM_Operator()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Synthesizes a buffer of samples based on passed parameters.
+ *
+ * Inputs:
+ * nNumSamplesToAdd - number of samples to synthesize
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+void FM_Operator (
+ S_FM_ENG_OPER *p,
+ EAS_I32 numSamplesToAdd,
+ EAS_PCM *pBuffer,
+ EAS_PCM *pModBuffer,
+ EAS_BOOL mix,
+ EAS_U16 gainTarget,
+ EAS_I16 pitch,
+ EAS_U8 feedback,
+ EAS_I16 *pLastOutput)
+{
+ EAS_I32 gain;
+ EAS_I32 gainInc;
+ EAS_U32 phase;
+ EAS_U32 phaseInc;
+ EAS_U32 phaseTemp;
+ EAS_I32 temp;
+ EAS_I32 temp2;
+
+ /* establish local gain variable */
+ gain = (EAS_I32) p->gain << 16;
+
+ /* calculate gain increment */
+ /*lint -e{703} use shift for performance */
+ gainInc = ((EAS_I32) gainTarget - (EAS_I32) p->gain) << (16 - SYNTH_UPDATE_PERIOD_IN_BITS);
+
+ /* establish local phase variables */
+ phase = p->phase;
+
+ /* calculate the new phase increment */
+ phaseInc = (EAS_U32) FM_PhaseInc(pitch);
+
+ /* restore final output from previous frame for feedback loop */
+ if (pLastOutput)
+ temp = *pLastOutput;
+ else
+ temp = 0;
+
+ /* generate a buffer of samples */
+ while (numSamplesToAdd--)
+ {
+
+ /* incorporate modulation */
+ if (pModBuffer)
+ {
+ /*lint -e{701} use shift for performance */
+ temp = *pModBuffer++ << FM_MODULATOR_INPUT_SHIFT;
+ }
+
+ /* incorporate feedback */
+ else
+ {
+ /*lint -e{703} use shift for performance */
+ temp = (temp * (EAS_I32) feedback) << FM_FEEDBACK_SHIFT;
+ }
+
+ /*lint -e{737} <use this behavior to avoid extra mask step> */
+ phaseTemp = phase + temp;
+
+ /* fetch sample from wavetable */
+ temp = sineTable[phaseTemp >> (32 - SINE_TABLE_SIZE_IN_BITS)];
+
+ /* increment operator phase */
+ phase += phaseInc;
+
+ /* internal gain for modulation effects */
+ temp = FMUL_15x15(temp, (gain >> 16));
+
+ /* output gain calculation */
+ temp2 = FMUL_15x15(temp, p->outputGain);
+
+ /* saturating add to buffer */
+ if (mix)
+ {
+ temp2 += *pBuffer;
+ *pBuffer++ = FM_Saturate(temp2);
+ }
+
+ /* output to buffer */
+ else
+ *pBuffer++ = (EAS_I16) temp2;
+
+ /* increment gain */
+ gain += gainInc;
+
+ }
+
+ /* save phase and gain */
+ p->phase = phase;
+ p->gain = gainTarget;
+
+ /* save last output for feedback in next frame */
+ if (pLastOutput)
+ *pLastOutput = (EAS_I16) temp;
+}
+
+/*----------------------------------------------------------------------------
+ * FM_NoiseOperator()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Synthesizes a buffer of samples based on passed parameters.
+ *
+ * Inputs:
+ * nNumSamplesToAdd - number of samples to synthesize
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+void FM_NoiseOperator (
+ S_FM_ENG_OPER *p,
+ EAS_I32 numSamplesToAdd,
+ EAS_PCM *pBuffer,
+ EAS_BOOL mix,
+ EAS_U16 gainTarget,
+ EAS_U8 feedback,
+ EAS_I16 *pLastOutput)
+{
+ EAS_I32 gain;
+ EAS_I32 gainInc;
+ EAS_U32 phase;
+ EAS_I32 temp;
+ EAS_I32 temp2;
+
+ /* establish local gain variable */
+ gain = (EAS_I32) p->gain << 16;
+
+ /* calculate gain increment */
+ /*lint -e{703} use shift for performance */
+ gainInc = ((EAS_I32) gainTarget - (EAS_I32) p->gain) << (16 - SYNTH_UPDATE_PERIOD_IN_BITS);
+
+ /* establish local phase variables */
+ phase = p->phase;
+
+ /* establish local phase variables */
+ phase = p->phase;
+
+ /* recall last sample for filter Z-1 term */
+ temp = 0;
+ if (pLastOutput)
+ temp = *pLastOutput;
+
+ /* generate a buffer of samples */
+ while (numSamplesToAdd--)
+ {
+
+ /* if using filter */
+ if (pLastOutput)
+ {
+ /* use PRNG for noise */
+ temp2 = FM_Noise(&phase);
+
+ /*lint -e{704} use shift for performance */
+ temp += ((temp2 -temp) * feedback) >> 8;
+ }
+ else
+ {
+ temp = FM_Noise(&phase);
+ }
+
+ /* internal gain for modulation effects */
+ temp2 = FMUL_15x15(temp, (gain >> 16));
+
+ /* output gain calculation */
+ temp2 = FMUL_15x15(temp2, p->outputGain);
+
+ /* saturating add to buffer */
+ if (mix)
+ {
+ temp2 += *pBuffer;
+ *pBuffer++ = FM_Saturate(temp2);
+ }
+
+ /* output to buffer */
+ else
+ *pBuffer++ = (EAS_I16) temp2;
+
+ /* increment gain */
+ gain += gainInc;
+
+ }
+
+ /* save phase and gain */
+ p->phase = phase;
+ p->gain = gainTarget;
+
+ /* save last output for feedback in next frame */
+ if (pLastOutput)
+ *pLastOutput = (EAS_I16) temp;
+}
+
+/*----------------------------------------------------------------------------
+ * FM_ConfigVoice()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Receives parameters to start a new voice.
+ *
+ * Inputs:
+ * voiceNum - voice number to start
+ * vCfg - configuration data
+ * pMixBuffer - pointer to host supplied buffer
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ *
+ * Notes:
+ * pFrameBuffer is not used in the test version, but is passed as a
+ * courtesy to split architecture implementations. It can be used as
+ * as pointer to the interprocessor communications buffer when the
+ * synthesis parameters are passed off to a DSP for synthesis.
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pFrameBuffer) pFrameBuffer not used in test version - see above */
+void FM_ConfigVoice (EAS_I32 voiceNum, S_FM_VOICE_CONFIG *vCfg, EAS_FRAME_BUFFER_HANDLE pFrameBuffer)
+{
+ S_FM_ENG_VOICE *pVoice;
+ EAS_INT i;
+
+ /* establish pointer to voice data */
+ pVoice = &voices[voiceNum];
+
+ /* save data */
+ pVoice->feedback = vCfg->feedback;
+ pVoice->flags = vCfg->flags;
+ pVoice->voiceGain = vCfg->voiceGain;
+
+ /* initialize Z-1 terms */
+ pVoice->op1Out = 0;
+ pVoice->op3Out = 0;
+
+ /* initialize operators */
+ for (i = 0; i < 4; i++)
+ {
+ /* save operator data */
+ pVoice->oper[i].gain = vCfg->gain[i];
+ pVoice->oper[i].outputGain = vCfg->outputGain[i];
+ pVoice->oper[i].outputGain = vCfg->outputGain[i];
+
+ /* initalize operator */
+ pVoice->oper[i].phase = 0;
+ }
+
+ /* calculate pan */
+#if NUM_OUTPUT_CHANNELS == 2
+ FM_CalculatePan(vCfg->pan, &pVoice->gainLeft, &pVoice->gainRight);
+#endif
+}
+
+/*----------------------------------------------------------------------------
+ * FM_ProcessVoice()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Synthesizes a buffer of samples based on calculated parameters.
+ *
+ * Inputs:
+ * nNumSamplesToAdd - number of samples to synthesize
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ *
+ * Notes:
+ * pOut is not used in the test version, but is passed as a
+ * courtesy to split architecture implementations. It can be used as
+ * as pointer to the interprocessor communications buffer when the
+ * synthesis parameters are passed off to a DSP for synthesis.
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pOut) pOut not used in test version - see above */
+void FM_ProcessVoice (
+ EAS_I32 voiceNum,
+ S_FM_VOICE_FRAME *pFrame,
+ EAS_I32 numSamplesToAdd,
+ EAS_PCM *pTempBuffer,
+ EAS_PCM *pBuffer,
+ EAS_I32 *pMixBuffer,
+ EAS_FRAME_BUFFER_HANDLE pFrameBuffer)
+{
+ S_FM_ENG_VOICE *p;
+ EAS_PCM *pOutBuf;
+ EAS_PCM *pMod;
+ EAS_BOOL mix;
+ EAS_U8 feedback1;
+ EAS_U8 feedback3;
+ EAS_U8 mode;
+
+ /* establish pointer to voice data */
+ p = &voices[voiceNum];
+ mode = p->flags & 0x07;
+
+ /* lookup feedback values */
+ feedback1 = fmScaleTable[p->feedback >> 4];
+ feedback3 = fmScaleTable[p->feedback & 0x0f];
+
+ /* operator 3 is on output bus in modes 0, 1, and 3 */
+ if ((mode == 0) || (mode == 1) || (mode == 3))
+ pOutBuf = pBuffer;
+ else
+ pOutBuf = pTempBuffer;
+
+ if (p->flags & FLAG_FM_ENG_VOICE_OP3_NOISE)
+ {
+ FM_NoiseOperator(
+ p->oper + 2,
+ numSamplesToAdd,
+ pOutBuf,
+ EAS_FALSE,
+ pFrame->gain[2],
+ feedback3,
+ &p->op3Out);
+ }
+ else
+ {
+ FM_Operator(
+ p->oper + 2,
+ numSamplesToAdd,
+ pOutBuf,
+ 0,
+ EAS_FALSE,
+ pFrame->gain[2],
+ pFrame->pitch[2],
+ feedback3,
+ &p->op3Out);
+ }
+
+ /* operator 4 is on output bus in modes 0, 1, and 2 */
+ if (mode < 3)
+ pOutBuf = pBuffer;
+ else
+ pOutBuf = pTempBuffer;
+
+ /* operator 4 is modulated in modes 2, 4, and 5 */
+ if ((mode == 2) || (mode == 4) || (mode == 5))
+ pMod = pTempBuffer;
+ else
+ pMod = 0;
+
+ /* operator 4 is in mix mode in modes 0 and 1 */
+ mix = (mode < 2);
+
+ if (p->flags & FLAG_FM_ENG_VOICE_OP4_NOISE)
+ {
+ FM_NoiseOperator(
+ p->oper + 3,
+ numSamplesToAdd,
+ pOutBuf,
+ mix,
+ pFrame->gain[3],
+ 0,
+ 0);
+ }
+ else
+ {
+ FM_Operator(
+ p->oper + 3,
+ numSamplesToAdd,
+ pOutBuf,
+ pMod,
+ mix,
+ pFrame->gain[3],
+ pFrame->pitch[3],
+ 0,
+ 0);
+ }
+
+ /* operator 1 is on output bus in mode 0 */
+ if (mode == 0)
+ pOutBuf = pBuffer;
+ else
+ pOutBuf = pTempBuffer;
+
+ /* operator 1 is modulated in modes 3 and 4 */
+ if ((mode == 3) || (mode == 4))
+ pMod = pTempBuffer;
+ else
+ pMod = 0;
+
+ /* operator 1 is in mix mode in modes 0 and 5 */
+ mix = ((mode == 0) || (mode == 5));
+
+ if (p->flags & FLAG_FM_ENG_VOICE_OP1_NOISE)
+ {
+ FM_NoiseOperator(
+ p->oper,
+ numSamplesToAdd,
+ pOutBuf,
+ mix,
+ pFrame->gain[0],
+ feedback1,
+ &p->op1Out);
+ }
+ else
+ {
+ FM_Operator(
+ p->oper,
+ numSamplesToAdd,
+ pOutBuf,
+ pMod,
+ mix,
+ pFrame->gain[0],
+ pFrame->pitch[0],
+ feedback1,
+ &p->op1Out);
+ }
+
+ /* operator 2 is modulated in all modes except 0 */
+ if (mode != 0)
+ pMod = pTempBuffer;
+ else
+ pMod = 0;
+
+ /* operator 1 is in mix mode in modes 0 -3 */
+ mix = (mode < 4);
+
+ if (p->flags & FLAG_FM_ENG_VOICE_OP2_NOISE)
+ {
+ FM_NoiseOperator(
+ p->oper + 1,
+ numSamplesToAdd,
+ pBuffer,
+ mix,
+ pFrame->gain[1],
+ 0,
+ 0);
+ }
+ else
+ {
+ FM_Operator(
+ p->oper + 1,
+ numSamplesToAdd,
+ pBuffer,
+ pMod,
+ mix,
+ pFrame->gain[1],
+ pFrame->pitch[1],
+ 0,
+ 0);
+ }
+
+ /* mix voice output to synthesizer output buffer */
+ FM_SynthMixVoice(p, pFrame->voiceGain, numSamplesToAdd, pBuffer, pMixBuffer);
+}
+
+/*----------------------------------------------------------------------------
+ * FM_SynthMixVoice()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Mixes the voice output buffer into the final mix using an anti-zipper
+ * filter.
+ *
+ * Inputs:
+ * nNumSamplesToAdd - number of samples to synthesize
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+void FM_SynthMixVoice(S_FM_ENG_VOICE *p, EAS_U16 nGainTarget, EAS_I32 numSamplesToAdd, EAS_PCM *pInputBuffer, EAS_I32 *pBuffer)
+{
+ EAS_I32 nGain;
+ EAS_I32 nGainInc;
+ EAS_I32 nTemp;
+
+ /* restore previous gain */
+ /*lint -e{703} <use shift for performance> */
+ nGain = (EAS_I32) p->voiceGain << 16;
+
+ /* calculate gain increment */
+ /*lint -e{703} <use shift for performance> */
+ nGainInc = ((EAS_I32) nGainTarget - (EAS_I32) p->voiceGain) << (16 - SYNTH_UPDATE_PERIOD_IN_BITS);
+
+ /* mix the output buffer */
+ while (numSamplesToAdd--)
+ {
+ /* output gain calculation */
+ nTemp = *pInputBuffer++;
+
+ /* sum to output buffer */
+#if (NUM_OUTPUT_CHANNELS == 2)
+
+ /*lint -e{704} <use shift for performance> */
+ nTemp = ((EAS_I32) nTemp * (nGain >> 16)) >> FM_GAIN_SHIFT;
+
+ /*lint -e{704} <use shift for performance> */
+ {
+ EAS_I32 nTemp2;
+ nTemp = nTemp >> FM_STEREO_PRE_GAIN_SHIFT;
+ nTemp2 = (nTemp * p->gainLeft) >> FM_STEREO_POST_GAIN_SHIFT;
+ *pBuffer++ += nTemp2;
+ nTemp2 = (nTemp * p->gainRight) >> FM_STEREO_POST_GAIN_SHIFT;
+ *pBuffer++ += nTemp2;
+ }
+#else
+ /*lint -e{704} <use shift for performance> */
+ nTemp = ((EAS_I32) nTemp * (nGain >> 16)) >> FM_MONO_GAIN_SHIFT;
+ *pBuffer++ += nTemp;
+#endif
+
+ /* increment gain for anti-zipper filter */
+ nGain += nGainInc;
+ }
+
+ /* save gain */
+ p->voiceGain = nGainTarget;
+}
+
diff --git a/arm-fm-22k/lib_src/eas_fmengine.h b/arm-fm-22k/lib_src/eas_fmengine.h
index 4ddc12b..dd248f8 100644
--- a/arm-fm-22k/lib_src/eas_fmengine.h
+++ b/arm-fm-22k/lib_src/eas_fmengine.h
@@ -1,12 +1,12 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_fmengine.h
- *
- * Contents and purpose:
- * Declarations, interfaces, and prototypes for FM synthesize low-level.
- *
- * Copyright Sonic Network Inc. 2004
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_fmengine.h
+ *
+ * Contents and purpose:
+ * Declarations, interfaces, and prototypes for FM synthesize low-level.
+ *
+ * Copyright Sonic Network Inc. 2004
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,103 +19,103 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 664 $
- * $Date: 2007-04-25 13:11:22 -0700 (Wed, 25 Apr 2007) $
- *----------------------------------------------------------------------------
-*/
-
-/* sentinel */
-#ifndef _FMENGINE_H
-#define _FMENGINE_H
-
-/* check for split architecture */
-#if defined (EAS_SPLIT_HYBRID_SYNTH) || defined(EAS_SPLIT_FM_SYNTH)
-#define FM_OFFBOARD
-#endif
-
-/* output level to mix buffer (3 = -24dB) */
-#define FM_GAIN_SHIFT 3
-#define FM_MONO_GAIN_SHIFT 9
-
-/* voice output level for stereo 15 = +6dB */
-#define FM_STEREO_PRE_GAIN_SHIFT 11
-#define FM_STEREO_POST_GAIN_SHIFT 10
-
-/* modulator input level shift (21 = -30dB) */
-#define FM_MODULATOR_INPUT_SHIFT 21
-
-/* feedback control level shift (7 = 0dB) */
-#define FM_FEEDBACK_SHIFT 7
-
-/* synth final output level */
-#define SYNTH_POST_GAIN_SHIFT 14
-
-/* LFO modulation to gain control */
-#define FM_LFO_GAIN_SHIFT 12
-
-/* sine table is always a power of 2 - saves cycles in inner loop */
-#define SINE_TABLE_SIZE_IN_BITS 11
-#define SINE_TABLE_SIZE 2048
-
-/* operator structure for FM engine */
-typedef struct
-{
- EAS_U32 phase; /* current waveform phase */
- EAS_U16 gain; /* current internal gain */
- EAS_U16 outputGain; /* current output gain */
-} S_FM_ENG_OPER;
-
-typedef struct
-{
- S_FM_ENG_OPER oper[4]; /* operator data */
- EAS_I16 op1Out; /* op1 output for feedback loop */
- EAS_I16 op3Out; /* op3 output for feedback loop */
- EAS_U16 voiceGain; /* LFO + channel parameters */
-#if (NUM_OUTPUT_CHANNELS == 2)
- EAS_U16 gainLeft; /* left gain multiplier */
- EAS_U16 gainRight; /* right gain multiplier */
-#endif
- EAS_U8 flags; /* mode bits and noise waveform flags */
- EAS_U8 feedback; /* feedback for Op1 and Op3 */
-} S_FM_ENG_VOICE;
-
-typedef struct
-{
- EAS_U16 gain[4]; /* initial operator gain value */
- EAS_U16 outputGain[4]; /* initial operator output gain value */
- EAS_U16 voiceGain; /* initial voice gain */
- EAS_U8 flags; /* mode bits and noise waveform flags */
- EAS_U8 feedback; /* feedback for Op1 and Op3 */
-#if (NUM_OUTPUT_CHANNELS == 2)
- EAS_I8 pan; /* pan value +/-64 */
-#endif
-} S_FM_VOICE_CONFIG;
-
-typedef struct
-{
- EAS_U16 gain[4]; /* new operator gain value */
- EAS_I16 pitch[4]; /* new pitch value */
- EAS_U16 voiceGain; /* new voice gain */
-} S_FM_VOICE_FRAME;
-
-/* bit definitions for S_FM_ENG_VOICE.flags */
-#define FLAG_FM_ENG_VOICE_OP1_NOISE 0x10 /* operator 1 source is PRNG */
-#define FLAG_FM_ENG_VOICE_OP2_NOISE 0x20 /* operator 2 source is PRNG */
-#define FLAG_FM_ENG_VOICE_OP3_NOISE 0x40 /* operator 3 source is PRNG */
-#define FLAG_FM_ENG_VOICE_OP4_NOISE 0x80 /* operator 4 source is PRNG */
-
-#ifdef FM_OFFBOARD
-extern EAS_BOOL FM_StartFrame (EAS_FRAME_BUFFER_HANDLE pFrameBuffer);
-extern EAS_BOOL FM_EndFrame (EAS_FRAME_BUFFER_HANDLE pFrameBuffe, EAS_I32 *pMixBuffer, EAS_I16 masterGain);
-#endif
-
-/* FM engine prototypes */
-extern void FM_ConfigVoice (EAS_I32 voiceNum, S_FM_VOICE_CONFIG *vCfg, EAS_FRAME_BUFFER_HANDLE pFrameBuffer);
-extern void FM_ProcessVoice (EAS_I32 voiceNum, S_FM_VOICE_FRAME *pFrame, EAS_I32 numSamplesToAdd, EAS_PCM *pTempBuffer, EAS_PCM *pBuffer, EAS_I32 *pMixBuffer, EAS_FRAME_BUFFER_HANDLE pFrameBuffer);
-
-#endif
-/* #ifndef _FMENGINE_H */
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 664 $
+ * $Date: 2007-04-25 13:11:22 -0700 (Wed, 25 Apr 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+/* sentinel */
+#ifndef _FMENGINE_H
+#define _FMENGINE_H
+
+/* check for split architecture */
+#if defined (EAS_SPLIT_HYBRID_SYNTH) || defined(EAS_SPLIT_FM_SYNTH)
+#define FM_OFFBOARD
+#endif
+
+/* output level to mix buffer (3 = -24dB) */
+#define FM_GAIN_SHIFT 3
+#define FM_MONO_GAIN_SHIFT 9
+
+/* voice output level for stereo 15 = +6dB */
+#define FM_STEREO_PRE_GAIN_SHIFT 11
+#define FM_STEREO_POST_GAIN_SHIFT 10
+
+/* modulator input level shift (21 = -30dB) */
+#define FM_MODULATOR_INPUT_SHIFT 21
+
+/* feedback control level shift (7 = 0dB) */
+#define FM_FEEDBACK_SHIFT 7
+
+/* synth final output level */
+#define SYNTH_POST_GAIN_SHIFT 14
+
+/* LFO modulation to gain control */
+#define FM_LFO_GAIN_SHIFT 12
+
+/* sine table is always a power of 2 - saves cycles in inner loop */
+#define SINE_TABLE_SIZE_IN_BITS 11
+#define SINE_TABLE_SIZE 2048
+
+/* operator structure for FM engine */
+typedef struct
+{
+ EAS_U32 phase; /* current waveform phase */
+ EAS_U16 gain; /* current internal gain */
+ EAS_U16 outputGain; /* current output gain */
+} S_FM_ENG_OPER;
+
+typedef struct
+{
+ S_FM_ENG_OPER oper[4]; /* operator data */
+ EAS_I16 op1Out; /* op1 output for feedback loop */
+ EAS_I16 op3Out; /* op3 output for feedback loop */
+ EAS_U16 voiceGain; /* LFO + channel parameters */
+#if (NUM_OUTPUT_CHANNELS == 2)
+ EAS_U16 gainLeft; /* left gain multiplier */
+ EAS_U16 gainRight; /* right gain multiplier */
+#endif
+ EAS_U8 flags; /* mode bits and noise waveform flags */
+ EAS_U8 feedback; /* feedback for Op1 and Op3 */
+} S_FM_ENG_VOICE;
+
+typedef struct
+{
+ EAS_U16 gain[4]; /* initial operator gain value */
+ EAS_U16 outputGain[4]; /* initial operator output gain value */
+ EAS_U16 voiceGain; /* initial voice gain */
+ EAS_U8 flags; /* mode bits and noise waveform flags */
+ EAS_U8 feedback; /* feedback for Op1 and Op3 */
+#if (NUM_OUTPUT_CHANNELS == 2)
+ EAS_I8 pan; /* pan value +/-64 */
+#endif
+} S_FM_VOICE_CONFIG;
+
+typedef struct
+{
+ EAS_U16 gain[4]; /* new operator gain value */
+ EAS_I16 pitch[4]; /* new pitch value */
+ EAS_U16 voiceGain; /* new voice gain */
+} S_FM_VOICE_FRAME;
+
+/* bit definitions for S_FM_ENG_VOICE.flags */
+#define FLAG_FM_ENG_VOICE_OP1_NOISE 0x10 /* operator 1 source is PRNG */
+#define FLAG_FM_ENG_VOICE_OP2_NOISE 0x20 /* operator 2 source is PRNG */
+#define FLAG_FM_ENG_VOICE_OP3_NOISE 0x40 /* operator 3 source is PRNG */
+#define FLAG_FM_ENG_VOICE_OP4_NOISE 0x80 /* operator 4 source is PRNG */
+
+#ifdef FM_OFFBOARD
+extern EAS_BOOL FM_StartFrame (EAS_FRAME_BUFFER_HANDLE pFrameBuffer);
+extern EAS_BOOL FM_EndFrame (EAS_FRAME_BUFFER_HANDLE pFrameBuffe, EAS_I32 *pMixBuffer, EAS_I16 masterGain);
+#endif
+
+/* FM engine prototypes */
+extern void FM_ConfigVoice (EAS_I32 voiceNum, S_FM_VOICE_CONFIG *vCfg, EAS_FRAME_BUFFER_HANDLE pFrameBuffer);
+extern void FM_ProcessVoice (EAS_I32 voiceNum, S_FM_VOICE_FRAME *pFrame, EAS_I32 numSamplesToAdd, EAS_PCM *pTempBuffer, EAS_PCM *pBuffer, EAS_I32 *pMixBuffer, EAS_FRAME_BUFFER_HANDLE pFrameBuffer);
+
+#endif
+/* #ifndef _FMENGINE_H */
+
diff --git a/arm-fm-22k/lib_src/eas_fmsndlib.c b/arm-fm-22k/lib_src/eas_fmsndlib.c
index bdd063c..dcde967 100644
--- a/arm-fm-22k/lib_src/eas_fmsndlib.c
+++ b/arm-fm-22k/lib_src/eas_fmsndlib.c
@@ -1,8 +1,8 @@
-/********************************************************************
- *
- * fmsndlib.c
- *
- * (c) Copyright 2005 Sonic Network, Inc. All Rights Reserved
+/********************************************************************
+ *
+ * fmsndlib.c
+ *
+ * (c) Copyright 2005 Sonic Network, Inc. All Rights Reserved
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,1660 +15,1660 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * Source: C:\Sonic\Source\Gen3.3\FMSynth\GMdblib-3.fml
- ********************************************************************/
-
-
-#include "eas_data.h"
-
-/* begin region data */
-/*lint -e{651} lint complains about unnecessary brackets */
-const S_FM_REGION regions[] =
-{
-
- /* Region 0 */
- {
- 0x8005, 0, 127, 0, 255, 8, 0,
- 514, 239, 47, 97, 0, 184, 3,
- 1, 244, 89, 114, 0, 248, 2,
- 3370, 244, 49, 76, 40, 192, 2,
- -1, 227, 97, 51, 160, 212, 2
- },
-
- /* Region 1 */
- {
- 0x8005, 0, 127, 160, 255, 8, 0,
- 2514, 223, 95, 72, 0, 176, 3,
- 1, 244, 73, 145, 0, 244, 2,
- 3600, 245, 81, 198, 40, 192, 2,
- 3, 246, 81, 163, 108, 212, 2
- },
-
- /* Region 2 */
- {
- 0x8005, 0, 127, 160, 255, 119, 0,
- 0, 216, 79, 72, 0, 216, 2,
- 2, 244, 73, 145, 0, 244, 2,
- 3370, 247, 33, 182, 60, 204, 2,
- 1200, 246, 65, 163, 108, 204, 2
- },
-
- /* Region 3 */
- {
- 0x8005, 0, 127, 160, 255, 1, 0,
- 3369, 248, 65, 71, 40, 208, 2,
- -3, 245, 88, 113, 0, 244, 2,
- 2784, 225, 65, 133, 80, 192, 2,
- 3, 241, 81, 113, 80, 216, 2
- },
-
- /* Region 4 */
- {
- 0x8002, 0, 127, 0, 255, 128, 0,
- 0, 229, 155, 183, 0, 228, 2,
- -3, 243, 90, 81, 0, 244, 2,
- 4800, 248, 109, 180, 36, 192, 2,
- 3, 245, 90, 85, 16, 244, 2
- },
-
- /* Region 5 */
- {
- 0x8002, 0, 127, 9, 96, 192, 0,
- 1200, 229, 157, 180, 0, 216, 2,
- -3, 244, 90, 81, 0, 244, 2,
- 1902, 255, 111, 182, 80, 208, 2,
- 3, 246, 92, 83, 0, 244, 2
- },
-
- /* Region 6 */
- {
- 0x8002, 0, 127, 0, 255, 154, 0,
- 3102, 244, 63, 102, 228, 228, 2,
- 1200, 247, 93, 97, 0, 236, 2,
- 1902, 255, 63, 98, 156, 220, 2,
- 1200, 244, 92, 98, 0, 236, 2
- },
-
- /* Region 7 */
- {
- 0x8005, 0, 127, 0, 255, 202, 0,
- 0, 251, 131, 19, 216, 220, 2,
- 1201, 247, 62, 113, 0, 240, 2,
- 0, 243, 154, 36, 240, 224, 2,
- 2784, 250, 61, 36, 240, 208, 2
- },
-
- /* Region 8 */
- {
- 0x8001, 0, 127, 0, 255, 80, 0,
- -1, 213, 191, 183, 0, 204, 2,
- 1, 245, 154, 129, 0, 244, 2,
- 3831, 252, 159, 100, 0, 200, 2,
- 1197, 246, 91, 182, 0, 244, 2
- },
-
- /* Region 9 */
- {
- 0x8002, 0, 127, 48, 80, 21, 0,
- 2982, 255, 43, 96, 0, 196, 3,
- 3, 247, 71, 130, 0, 244, 2,
- 3358, 253, 40, 98, 144, 208, 2,
- -2, 246, 70, 130, 0, 236, 2
- },
-
- /* Region 10 */
- {
- 0x8002, 0, 127, 48, 80, 26, 0,
- 3096, 249, 72, 100, 0, 208, 2,
- 2185, 249, 102, 130, 0, 240, 2,
- 3386, 247, 66, 100, 144, 212, 2,
- -2, 247, 102, 130, 0, 240, 2
- },
-
- /* Region 11 */
- {
- 0x8002, 0, 127, 92, 67, 21, 0,
- 2982, 255, 27, 146, 0, 200, 3,
- 3, 246, 68, 146, 0, 240, 2,
- 3358, 250, 149, 116, 144, 208, 2,
- -3, 245, 68, 146, 0, 240, 0
- },
-
- /* Region 12 */
- {
- 0x8002, 0, 127, 0, 67, 0, 0,
- 1500, 239, 60, 151, 0, 220, 2,
- 0, 247, 76, 146, 0, 240, 2,
- 2398, 234, 156, 151, 0, 212, 2,
- 0, 246, 105, 146, 0, 244, 2
- },
-
- /* Region 13 */
- {
- 0x8002, 0, 127, 0, 67, 0, 0,
- 2500, 255, 60, 151, 0, 220, 2,
- 0, 249, 92, 146, 0, 244, 2,
- 3369, 250, 156, 151, 0, 196, 2,
- 0, 248, 89, 146, 0, 244, 2
- },
-
- /* Region 14 */
- {
- 0x8005, 0, 127, 160, 255, 0, 0,
- 2300, 229, 112, 49, 0, 208, 2,
- -3, 247, 67, 50, 0, 248, 2,
- 1074, 255, 41, 49, 0, 196, 2,
- 686, 240, 97, 18, 0, 196, 2
- },
-
- /* Region 15 */
- {
- 0x8005, 0, 127, 160, 255, 219, 0,
- 3369, 255, 65, 70, 40, 216, 2,
- 1, 246, 72, 113, 0, 240, 2,
- 1902, 225, 33, 129, 80, 204, 2,
- 2400, 225, 97, 113, 80, 200, 2
- },
-
- /* Region 16 */
- {
- 0x8003, 0, 127, 32, 48, 151, 0,
- 1201, 215, 35, 66, 252, 208, 0,
- -9581, 254, 63, 177, 240, 240, 3,
- 1902, 248, 47, 64, 112, 244, 2,
- 0, 247, 35, 66, 208, 212, 2
- },
-
- /* Region 17 */
- {
- 0x8001, 0, 127, 0, 255, 153, 0,
- 1, 252, 31, 3, 244, 196, 2,
- -1, 208, 31, 4, 248, 244, 2,
- 1205, 209, 31, 4, 248, 236, 2,
- 1899, 250, 31, 32, 0, 240, 2
- },
-
- /* Region 18 */
- {
- 0x8002, 0, 127, 32, 49, 201, 0,
- 1, 220, 47, 3, 244, 220, 0,
- -10000, 208, 63, 1, 248, 240, 3,
- 1586, 255, 47, 3, 188, 216, 2,
- -1, 202, 63, 32, 80, 232, 2
- },
-
- /* Region 19 */
- {
- 0x8001, 0, 127, 0, 143, 29, 0,
- -1200, 223, 64, 0, 252, 216, 2,
- 1200, 96, 41, 35, 248, 240, 2,
- 1200, 143, 41, 64, 252, 224, 2,
- 3102, 161, 41, 96, 248, 216, 2
- },
-
- /* Region 20 */
- {
- 0x8002, 0, 127, 0, 143, 34, 0,
- -1200, 133, 79, 1, 252, 212, 2,
- 1201, 112, 46, 34, 248, 232, 2,
- 0, 116, 79, 65, 252, 200, 2,
- 1900, 161, 46, 98, 248, 232, 2
- },
-
- /* Region 21 */
- {
- 0x8002, 0, 127, 0, 143, 187, 0,
- 1202, 80, 74, 1, 252, 216, 2,
- 2402, 112, 46, 34, 248, 232, 2,
- 0, 99, 78, 97, 184, 216, 2,
- 1899, 81, 46, 98, 236, 232, 2
- },
-
- /* Region 22 */
- {
- 0x8005, 0, 127, 22, 141, 34, 0,
- 2787, 176, 79, 4, 252, 208, 2,
- 2785, 144, 45, 34, 248, 236, 2,
- 3369, 83, 77, 100, 184, 172, 2,
- 1902, 102, 45, 100, 172, 212, 0
- },
-
- /* Region 23 */
- {
- 0x8002, 0, 127, 0, 143, 135, 0,
- 1900, 112, 79, 3, 252, 220, 2,
- 2400, 128, 45, 34, 248, 232, 2,
- 1200, 115, 77, 98, 184, 220, 2,
- 1904, 97, 45, 98, 236, 232, 2
- },
-
- /* Region 24 */
- {
- 0x8005, 0, 127, 0, 255, 157, 0,
- 1200, 244, 54, 4, 20, 200, 2,
- 0, 245, 92, 130, 0, 244, 2,
- 3802, 247, 68, 21, 0, 196, 2,
- 1, 245, 43, 114, 0, 204, 2
- },
-
- /* Region 25 */
- {
- 0x8005, 0, 127, 0, 128, 83, 0,
- 0, 244, 51, 4, 200, 204, 0,
- 0, 247, 108, 129, 0, 248, 0,
- 2786, 243, 31, 70, 200, 220, 0,
- 1902, 246, 44, 113, 12, 188, 0
- },
-
- /* Region 26 */
- {
- 0x8005, 0, 127, 0, 128, 61, 0,
- 0, 246, 51, 97, 76, 204, 0,
- 0, 244, 60, 97, 0, 240, 0,
- 1786, 255, 31, 64, 0, 180, 0,
- 1200, 247, 60, 97, 12, 204, 0
- },
-
- /* Region 27 */
- {
- 0x8005, 0, 127, 0, 128, 153, 0,
- -2, 243, 53, 99, 96, 200, 0,
- 0, 243, 60, 97, 0, 240, 0,
- 3983, 247, 63, 100, 24, 204, 0,
- 2, 242, 53, 99, 52, 212, 0
- },
-
- /* Region 28 */
- {
- 0x8005, 0, 127, 0, 128, 205, 0,
- -2, 244, 47, 97, 20, 208, 0,
- 0, 252, 75, 193, 0, 248, 0,
- 0, 254, 63, 98, 132, 224, 0,
- 2786, 251, 63, 98, 52, 192, 0
- },
-
- /* Region 29 */
- {
- 0x8005, 0, 127, 0, 128, 221, 0,
- -1, 208, 191, 99, 220, 224, 0,
- 1200, 243, 92, 97, 0, 244, 0,
- 3984, 212, 11, 96, 168, 196, 0,
- 1, 242, 127, 98, 108, 204, 0
- },
-
- /* Region 30 */
- {
- 0x8005, 0, 127, 0, 128, 174, 0,
- -3, 212, 207, 99, 0, 228, 0,
- 1902, 241, 108, 97, 0, 248, 0,
- 3805, 212, 59, 98, 0, 220, 0,
- 1902, 146, 107, 98, 144, 196, 0
- },
-
- /* Region 31 */
- {
- 0x8009, 0, 127, 0, 255, 128, 0,
- 1206, 239, 43, 69, 0, 216, 2,
- 4, 254, 42, 66, 0, 244, 2,
- 702, 88, 55, 66, 0, 204, 2,
- -4, 71, 55, 66, 0, 240, 2
- },
-
- /* Region 32 */
- {
- 0x8005, 0, 127, 0, 255, 85, 0,
- 500, 239, 95, 82, 0, 184, 3,
- 0, 248, 73, 132, 0, 252, 2,
- 2786, 203, 59, 130, 0, 176, 2,
- 0, 216, 42, 100, 0, 208, 2
- },
-
- /* Region 33 */
- {
- 0x8005, 0, 127, 0, 128, 73, 0,
- 1, 229, 54, 131, 160, 208, 0,
- -1, 244, 62, 97, 0, 248, 0,
- 3986, 227, 127, 69, 140, 184, 0,
- 1201, 249, 92, 114, 0, 204, 0
- },
-
- /* Region 34 */
- {
- 0x8005, 0, 127, 0, 128, 73, 0,
- 1, 225, 54, 100, 200, 212, 0,
- -1, 244, 94, 97, 0, 248, 0,
- 3986, 249, 127, 88, 112, 188, 0,
- 1201, 249, 92, 85, 52, 208, 0
- },
-
- /* Region 35 */
- {
- 0x8005, 0, 127, 0, 128, 188, 0,
- -3, 198, 92, 179, 28, 212, 0,
- 0, 243, 90, 145, 0, 248, 0,
- 1901, 215, 95, 69, 28, 196, 0,
- 3, 84, 108, 196, 32, 208, 0
- },
-
- /* Region 36 */
- {
- 0x8005, 0, 127, 0, 136, 6, 0,
- 0, 226, 99, 36, 224, 216, 0,
- 1902, 248, 78, 33, 0, 252, 0,
- 3369, 239, 250, 33, 0, 204, 0,
- 0, 230, 253, 33, 0, 208, 0
- },
-
- /* Region 37 */
- {
- 0x8005, 0, 127, 0, 136, 195, 0,
- 0, 245, 99, 36, 152, 208, 0,
- 1200, 248, 78, 33, 0, 252, 0,
- 3369, 246, 250, 33, 0, 216, 0,
- 0, 246, 61, 33, 0, 180, 0
- },
-
- /* Region 38 */
- {
- 0x8002, 0, 127, 0, 133, 221, 0,
- 1, 244, 67, 35, 80, 220, 0,
- 3, 246, 94, 33, 0, 244, 0,
- -1, 245, 70, 35, 80, 236, 2,
- -3, 246, 63, 33, 0, 236, 2
- },
-
- /* Region 39 */
- {
- 0x8002, 0, 127, 0, 133, 220, 0,
- 0, 114, 51, 34, 132, 208, 0,
- 3, 214, 62, 33, 0, 248, 0,
- 0, 85, 54, 34, 44, 224, 2,
- -3, 214, 63, 33, 0, 236, 2
- },
-
- /* Region 40 */
- {
- 0x8005, 0, 127, 48, 142, 187, 0,
- -1, 33, 22, 33, 200, 208, 0,
- 0, 81, 105, 33, 220, 240, 0,
- 2786, 245, 19, 50, 208, 192, 0,
- 1, 245, 21, 82, 200, 220, 0
- },
-
- /* Region 41 */
- {
- 0x8005, 0, 127, 48, 126, 103, 0,
- -1, 193, 22, 33, 228, 212, 0,
- 0, 81, 105, 33, 220, 244, 0,
- 0, 245, 19, 50, 216, 228, 0,
- 1200, 245, 19, 82, 200, 188, 0
- },
-
- /* Region 42 */
- {
- 0x8005, 0, 127, 16, 126, 202, 0,
- -1, 49, 24, 41, 200, 212, 0,
- 0, 81, 71, 49, 220, 244, 0,
- 3371, 243, 19, 36, 232, 192, 0,
- 1, 242, 24, 36, 220, 212, 0
- },
-
- /* Region 43 */
- {
- 0x8005, 0, 127, 16, 124, 205, 0,
- 0, 129, 24, 49, 208, 200, 0,
- 0, 67, 102, 81, 224, 244, 0,
- 3804, 246, 23, 36, 160, 196, 0,
- 1200, 244, 24, 35, 208, 200, 0
- },
-
- /* Region 44 */
- {
- 0x8005, 0, 127, 48, 144, 208, 0,
- -3, 209, 22, 33, 200, 204, 2,
- 0, 81, 89, 33, 220, 240, 2,
- -5000, 208, 6, 33, 244, 188, 3,
- 3, 97, 89, 33, 224, 200, 0
- },
-
- /* Region 45 */
- {
- 0x8005, 0, 127, 0, 255, 186, 0,
- 500, 223, 95, 0, 0, 192, 3,
- 0, 247, 89, 100, 0, 248, 2,
- 3369, 255, 59, 168, 0, 212, 2,
- 0, 216, 42, 97, 0, 212, 2
- },
-
- /* Region 46 */
- {
- 0x8002, 0, 127, 0, 255, 221, 0,
- 1206, 235, 70, 69, 0, 216, 2,
- 4, 248, 84, 66, 0, 244, 2,
- 1902, 247, 52, 137, 80, 216, 2,
- -4, 245, 84, 131, 0, 240, 2
- },
-
- /* Region 47 */
- {
- 0x8005, 0, 127, 0, 255, 105, 0,
- 387, 231, 115, 34, 4, 216, 2,
- 0, 248, 37, 65, 0, 252, 2,
- 3308, 248, 117, 34, 8, 200, 2,
- 1900, 213, 82, 50, 0, 192, 2
- },
-
- /* Region 48 */
- {
- 0x8002, 0, 127, 32, 160, 221, 0,
- -7, 209, 22, 33, 200, 204, 2,
- -7, 81, 73, 33, 220, 244, 0,
- 7, 209, 22, 33, 200, 208, 0,
- 7, 97, 73, 33, 224, 244, 2
- },
-
- /* Region 49 */
- {
- 0x8002, 0, 127, 64, 128, 189, 0,
- -2, 209, 54, 32, 224, 216, 2,
- -7726, 97, 105, 33, 220, 240, 3,
- 1902, 209, 54, 34, 216, 208, 0,
- 2, 81, 105, 33, 224, 236, 0
- },
-
- /* Region 50 */
- {
- 0x8002, 0, 127, 80, 144, 206, 0,
- -3, 179, 38, 33, 160, 220, 2,
- -7726, 81, 69, 34, 220, 244, 3,
- 3, 193, 38, 33, 240, 212, 0,
- -8000, 65, 69, 34, 224, 236, 3
- },
-
- /* Region 51 */
- {
- 0x8005, 0, 127, 96, 128, 204, 0,
- -3, 97, 38, 33, 180, 216, 0,
- 0, 81, 69, 34, 220, 240, 2,
- 3369, 145, 38, 33, 240, 196, 2,
- -13190, 65, 69, 34, 240, 200, 3
- },
-
- /* Region 52 */
- {
- 0x8002, 0, 127, 64, 128, 108, 0,
- -3, 193, 37, 35, 236, 208, 0,
- 2394, 97, 90, 36, 224, 232, 2,
- 3, 65, 40, 35, 236, 204, 2,
- 1203, 97, 89, 33, 224, 240, 0
- },
-
- /* Region 53 */
- {
- 0x8005, 0, 127, 128, 128, 122, 0,
- 0, 193, 21, 34, 236, 188, 0,
- 3, 97, 74, 36, 224, 248, 2,
- 1906, 251, 24, 32, 96, 192, 3,
- 1200, 97, 73, 32, 224, 184, 0
- },
-
- /* Region 54 */
- {
- 0x8002, 0, 127, 64, 133, 135, 0,
- 0, 194, 25, 35, 120, 200, 2,
- 0, 97, 75, 36, 224, 240, 0,
- 2906, 254, 28, 48, 0, 184, 3,
- 0, 216, 75, 80, 204, 240, 2
- },
-
- /* Region 55 */
- {
- 0x8009, 0, 127, 208, 64, 255, 0,
- 475, 249, 16, 32, 252, 240, 2,
- 702, 248, 71, 32, 0, 244, 2,
- 1136, 232, 27, 32, 216, 248, 0,
- 0, 249, 23, 48, 0, 248, 2
- },
-
- /* Region 56 */
- {
- 0x8005, 0, 127, 0, 132, 233, 0,
- 0, 195, 95, 64, 240, 208, 0,
- 0, 225, 94, 64, 248, 240, 0,
- 0, 254, 127, 0, 4, 196, 4,
- 1902, 228, 95, 1, 248, 200, 0
- },
-
- /* Region 57 */
- {
- 0x8005, 0, 127, 16, 140, 238, 0,
- 0, 163, 90, 67, 228, 208, 0,
- 0, 209, 77, 65, 248, 240, 0,
- 1969, 173, 58, 65, 0, 176, 0,
- 0, 210, 61, 52, 204, 220, 0
- },
-
- /* Region 58 */
- {
- 0x8005, 0, 127, 16, 140, 222, 0,
- 0, 119, 74, 67, 160, 212, 0,
- 0, 146, 61, 65, 248, 244, 0,
- 1900, 137, 58, 65, 100, 196, 0,
- 0, 119, 61, 52, 120, 200, 0
- },
-
- /* Region 59 */
- {
- 0x8005, 0, 127, 16, 135, 219, 0,
- 0, 176, 79, 69, 240, 216, 0,
- 0, 193, 79, 64, 248, 236, 0,
- 0, 178, 123, 54, 92, 228, 0,
- 3369, 212, 95, 38, 144, 212, 0
- },
-
- /* Region 60 */
- {
- 0x8002, 0, 127, 0, 119, 203, 0,
- 2, 65, 77, 66, 228, 204, 0,
- 2, 161, 74, 64, 240, 240, 0,
- -2, 85, 60, 66, 180, 216, 2,
- -2, 162, 74, 64, 220, 240, 2
- },
-
- /* Region 61 */
- {
- 0x8002, 0, 127, 16, 154, 237, 0,
- 0, 179, 42, 64, 216, 208, 0,
- 0, 209, 61, 64, 248, 244, 0,
- -1200, 226, 55, 65, 244, 220, 2,
- 1902, 162, 62, 52, 204, 236, 2
- },
-
- /* Region 62 */
- {
- 0x8002, 0, 127, 48, 119, 221, 0,
- 2, 119, 79, 64, 208, 212, 0,
- 2, 209, 110, 64, 248, 236, 0,
- -2, 84, 79, 64, 136, 212, 2,
- -2, 209, 110, 64, 240, 240, 2
- },
-
- /* Region 63 */
- {
- 0x8002, 0, 127, 32, 135, 221, 0,
- 2, 165, 79, 64, 152, 216, 0,
- 2, 225, 110, 64, 248, 236, 0,
- -2, 132, 79, 64, 72, 224, 2,
- -2, 241, 110, 64, 252, 236, 2
- },
-
- /* Region 64 */
- {
- 0x8005, 0, 127, 17, 127, 190, 0,
- 0, 209, 60, 67, 244, 208, 0,
- 1200, 145, 94, 65, 248, 244, 2,
- 3369, 197, 47, 4, 128, 192, 0,
- 1902, 167, 94, 6, 200, 200, 0
- },
-
- /* Region 65 */
- {
- 0x8005, 0, 127, 17, 143, 190, 0,
- 0, 209, 60, 67, 244, 216, 0,
- 1902, 145, 62, 65, 248, 240, 2,
- 3369, 197, 47, 4, 128, 196, 0,
- 2400, 167, 94, 6, 200, 212, 2
- },
-
- /* Region 66 */
- {
- 0x8005, 0, 127, 17, 143, 190, 0,
- 0, 209, 60, 67, 244, 208, 0,
- 1902, 145, 62, 65, 248, 240, 2,
- 3369, 197, 47, 4, 128, 192, 0,
- 1902, 167, 94, 6, 200, 216, 2
- },
-
- /* Region 67 */
- {
- 0x8005, 0, 127, 17, 125, 190, 0,
- 0, 114, 109, 67, 244, 224, 0,
- 1902, 166, 93, 97, 200, 240, 0,
- 2786, 165, 95, 52, 160, 200, 0,
- 2400, 173, 78, 54, 240, 212, 2
- },
-
- /* Region 68 */
- {
- 0x8002, 0, 127, 16, 140, 205, 0,
- 0, 211, 55, 66, 244, 208, 0,
- 1902, 193, 93, 65, 248, 240, 0,
- 0, 204, 47, 4, 244, 216, 0,
- 3600, 183, 95, 6, 160, 232, 0
- },
-
- /* Region 69 */
- {
- 0x8002, 0, 127, 16, 126, 222, 0,
- 0, 243, 36, 66, 172, 200, 0,
- 1200, 193, 110, 67, 248, 244, 0,
- 0, 215, 33, 2, 232, 212, 0,
- 3369, 178, 63, 6, 184, 240, 0
- },
-
- /* Region 70 */
- {
- 0x8002, 0, 127, 16, 140, 221, 0,
- 1200, 213, 61, 66, 136, 200, 0,
- 1902, 193, 93, 68, 248, 240, 0,
- 0, 197, 47, 2, 228, 216, 0,
- 3369, 183, 95, 2, 160, 236, 0
- },
-
- /* Region 71 */
- {
- 0x8002, 0, 127, 16, 124, 201, 0,
- 1200, 195, 55, 68, 240, 208, 0,
- 0, 209, 76, 65, 248, 236, 0,
- 1902, 147, 47, 19, 208, 212, 0,
- 0, 183, 79, 22, 156, 228, 0
- },
-
- /* Region 72 */
- {
- 0x8005, 0, 127, 32, 110, 234, 0,
- 500, 237, 60, 68, 0, 192, 1,
- 1, 161, 93, 65, 248, 240, 2,
- 3365, 154, 47, 16, 48, 180, 6,
- 1200, 165, 92, 52, 160, 212, 2
- },
-
- /* Region 73 */
- {
- 0x8005, 0, 127, 32, 142, 200, 0,
- 0, 193, 60, 68, 248, 200, 0,
- 1, 129, 61, 65, 248, 240, 2,
- 3365, 154, 47, 16, 68, 184, 6,
- 1200, 169, 92, 52, 160, 204, 2
- },
-
- /* Region 74 */
- {
- 0x8003, 0, 127, 32, 135, 36, 0,
- 1199, 165, 79, 66, 152, 192, 2,
- -3, 145, 110, 64, 248, 240, 2,
- 0, 199, 79, 66, 44, 236, 2,
- 2986, 136, 110, 67, 100, 196, 2
- },
-
- /* Region 75 */
- {
- 0x8005, 0, 127, 32, 190, 71, 0,
- 868, 202, 140, 16, 24, 188, 2,
- 0, 176, 77, 65, 248, 240, 2,
- 3750, 169, 127, 16, 36, 228, 6,
- 2400, 195, 60, 17, 232, 172, 2
- },
-
- /* Region 76 */
- {
- 0x8005, 0, 127, 224, 16, 123, 0,
- 275, 202, 14, 2, 44, 196, 2,
- 0, 165, 89, 65, 56, 244, 2,
- 0, 255, 12, 2, 64, 216, 6,
- 963, 169, 14, 4, 40, 196, 2
- },
-
- /* Region 77 */
- {
- 0x8012, 0, 127, 192, 128, 100, 0,
- 1500, 202, 79, 68, 76, 204, 2,
- -2, 97, 26, 64, 248, 232, 2,
- 1588, 202, 223, 69, 4, 220, 0,
- 3, 188, 121, 67, 48, 252, 2
- },
-
- /* Region 78 */
- {
- 0x8002, 0, 127, 112, 140, 205, 0,
- 0, 68, 47, 66, 60, 176, 2,
- -2, 113, 94, 64, 248, 236, 0,
- 5000, 121, 47, 64, 32, 168, 7,
- 3, 136, 94, 64, 0, 236, 0
- },
-
- /* Region 79 */
- {
- 0x8003, 0, 127, 32, 135, 33, 0,
- 1199, 197, 79, 66, 152, 184, 2,
- 0, 161, 110, 64, 248, 240, 2,
- 0, 199, 79, 66, 44, 236, 2,
- 2400, 255, 110, 65, 36, 208, 6
- },
-
- /* Region 80 */
- {
- 0x8002, 0, 127, 0, 192, 170, 0,
- 1199, 192, 77, 33, 200, 212, 0,
- 0, 209, 107, 33, 232, 240, 0,
- 1201, 80, 77, 33, 200, 212, 0,
- 0, 241, 107, 33, 232, 240, 0
- },
-
- /* Region 81 */
- {
- 0x8002, 0, 127, 0, 192, 221, 0,
- -1, 192, 45, 33, 200, 212, 0,
- -1, 209, 107, 33, 232, 244, 0,
- 1, 80, 45, 33, 200, 212, 0,
- 1, 241, 107, 33, 232, 244, 0
- },
-
- /* Region 82 */
- {
- 0x8005, 0, 127, 0, 112, 255, 0,
- 4750, 221, 45, 34, 48, 172, 4,
- -10000, 161, 107, 33, 200, 244, 3,
- 2204, 137, 45, 37, 64, 184, 0,
- -2, 211, 107, 33, 160, 208, 0
- },
-
- /* Region 83 */
- {
- 0x8005, 0, 127, 16, 127, 238, 0,
- 2, 248, 45, 32, 204, 208, 0,
- -9500, 241, 107, 33, 200, 240, 3,
- 3369, 186, 45, 38, 24, 208, 0,
- -2, 211, 107, 32, 220, 212, 0
- },
-
- /* Region 84 */
- {
- 0x8005, 0, 127, 0, 128, 221, 0,
- -1, 192, 191, 99, 220, 216, 0,
- 1200, 243, 92, 97, 0, 244, 0,
- 3984, 200, 11, 96, 168, 192, 0,
- 1, 194, 127, 98, 108, 200, 0
- },
-
- /* Region 85 */
- {
- 0x8002, 0, 127, 128, 128, 111, 0,
- 1, 194, 25, 35, 120, 204, 2,
- -9750, 193, 107, 36, 224, 244, 3,
- 3906, 255, 28, 50, 12, 188, 3,
- -1, 216, 107, 80, 204, 240, 2
- },
-
- /* Region 86 */
- {
- 0x8002, 0, 127, 32, 134, 222, 0,
- 0, 195, 52, 33, 200, 208, 0,
- 0, 177, 90, 33, 232, 240, 2,
- 702, 195, 52, 33, 200, 208, 2,
- 702, 177, 90, 34, 232, 240, 2
- },
-
- /* Region 87 */
- {
- 0x8002, 0, 127, 32, 134, 205, 0,
- 0, 198, 75, 36, 120, 220, 2,
- 0, 225, 78, 52, 40, 244, 2,
- 0, 246, 47, 32, 220, 208, 2,
- 1902, 241, 124, 32, 240, 236, 2
- },
-
- /* Region 88 */
- {
- 0x8003, 0, 127, 32, 120, 14, 0,
- 3600, 244, 67, 34, 88, 208, 0,
- 3, 194, 84, 33, 84, 240, 2,
- -3, 194, 84, 33, 172, 236, 2,
- 902, 254, 114, 34, 0, 224, 3
- },
-
- /* Region 89 */
- {
- 0x8002, 0, 127, 64, 169, 170, 0,
- -3, 83, 69, 34, 184, 212, 0,
- -7500, 50, 69, 33, 176, 244, 3,
- 3, 81, 69, 34, 212, 212, 2,
- -8500, 66, 69, 33, 176, 244, 3
- },
-
- /* Region 90 */
- {
- 0x8002, 0, 127, 64, 120, 221, 0,
- -2, 82, 69, 34, 244, 216, 0,
- 0, 145, 102, 33, 228, 240, 0,
- 2, 81, 69, 34, 244, 208, 2,
- 0, 145, 102, 33, 224, 240, 2
- },
-
- /* Region 91 */
- {
- 0x8003, 0, 127, 32, 138, 14, 0,
- 2400, 148, 67, 34, 176, 200, 0,
- 3, 194, 85, 33, 220, 236, 2,
- -3, 194, 69, 33, 220, 236, 2,
- 1905, 254, 114, 34, 48, 224, 2
- },
-
- /* Region 92 */
- {
- 0x8002, 0, 127, 82, 67, 71, 0,
- 2982, 228, 22, 146, 88, 192, 3,
- 3, 102, 84, 146, 196, 240, 2,
- 3358, 50, 149, 116, 144, 208, 2,
- -3, 85, 84, 146, 120, 240, 0
- },
-
- /* Region 93 */
- {
- 0x8005, 0, 127, 48, 126, 219, 0,
- -3, 49, 19, 33, 120, 200, 0,
- 0, 81, 70, 33, 220, 240, 0,
- 3804, 242, 18, 50, 200, 200, 0,
- 1203, 82, 19, 82, 200, 176, 0
- },
-
- /* Region 94 */
- {
- 0x8003, 0, 127, 32, 138, 13, 0,
- 2786, 116, 67, 34, 204, 184, 0,
- 1902, 114, 69, 33, 192, 232, 2,
- -3, 178, 69, 33, 188, 232, 2,
- 3804, 254, 82, 34, 164, 228, 2
- },
-
- /* Region 95 */
- {
- 0x8002, 0, 127, 48, 135, 238, 0,
- -2, 34, 85, 34, 184, 224, 0,
- 1, 113, 70, 33, 228, 236, 0,
- 2, 19, 85, 34, 156, 224, 2,
- -1, 129, 70, 33, 224, 236, 2
- },
-
- /* Region 96 */
- {
- 0x8012, 0, 127, 240, 112, 221, 0,
- 3369, 213, 69, 32, 0, 204, 0,
- 0, 193, 70, 33, 112, 232, 2,
- 0, 145, 69, 34, 244, 208, 2,
- -9000, 145, 70, 33, 224, 236, 3
- },
-
- /* Region 97 */
- {
- 0x8002, 0, 127, 96, 122, 168, 0,
- -1, 99, 51, 33, 200, 208, 0,
- -8500, 81, 83, 33, 232, 240, 3,
- 702, 99, 52, 33, 200, 208, 2,
- -9500, 65, 83, 34, 224, 240, 3
- },
-
- /* Region 98 */
- {
- 0x8002, 0, 127, 0, 67, 0, 0,
- 1500, 217, 55, 151, 20, 224, 2,
- 3, 231, 70, 146, 88, 220, 2,
- 2369, 115, 148, 151, 32, 196, 2,
- -3, 118, 36, 146, 64, 244, 2
- },
-
- /* Region 99 */
- {
- 0x8002, 0, 127, 64, 169, 204, 0,
- -3, 228, 69, 34, 148, 220, 0,
- -7448, 243, 69, 33, 200, 240, 3,
- 3, 81, 68, 34, 212, 212, 2,
- -8526, 65, 68, 33, 196, 240, 3
- },
-
- /* Region 100 */
- {
- 0x8002, 0, 127, 64, 119, 187, 0,
- 2786, 228, 22, 146, 176, 192, 0,
- 3, 102, 68, 146, 196, 236, 2,
- 3369, 178, 149, 116, 176, 208, 2,
- -3, 231, 68, 146, 120, 240, 0
- },
-
- /* Region 101 */
- {
- 0x8002, 0, 127, 240, 144, 239, 0,
- -2, 49, 69, 34, 236, 208, 2,
- -9000, 113, 102, 33, 228, 236, 3,
- 2400, 149, 69, 34, 12, 216, 1,
- 0, 145, 102, 33, 224, 236, 2
- },
-
- /* Region 102 */
- {
- 0x8012, 0, 127, 241, 176, 6, 0,
- 1200, 247, 49, 64, 252, 204, 0,
- 3804, 246, 101, 32, 0, 232, 2,
- 1902, 247, 32, 32, 112, 188, 2,
- 0, 228, 84, 32, 0, 240, 2
- },
-
- /* Region 103 */
- {
- 0x8005, 0, 127, 64, 101, 221, 0,
- 1, 194, 68, 97, 196, 200, 2,
- -10001, 247, 100, 114, 176, 240, 3,
- 3370, 213, 33, 70, 52, 200, 2,
- -1, 178, 68, 49, 208, 212, 0
- },
-
- /* Region 104 */
- {
- 0x8002, 0, 127, 0, 255, 203, 0,
- -3, 245, 82, 99, 200, 232, 2,
- 2787, 244, 84, 96, 0, 236, 2,
- 1198, 133, 81, 100, 196, 220, 2,
- 1902, 147, 67, 80, 0, 232, 2
- },
-
- /* Region 105 */
- {
- 0x8005, 0, 127, 0, 255, 140, 0,
- 500, 255, 137, 179, 0, 200, 3,
- 1902, 248, 90, 160, 0, 244, 2,
- 3804, 245, 57, 35, 164, 204, 2,
- 0, 245, 38, 51, 196, 208, 2
- },
-
- /* Region 106 */
- {
- 0x8005, 0, 127, 0, 255, 72, 0,
- 1000, 238, 57, 65, 0, 188, 3,
- 1902, 247, 103, 112, 0, 244, 2,
- 2786, 250, 36, 81, 68, 212, 2,
- 0, 249, 50, 49, 172, 204, 2
- },
-
- /* Region 107 */
- {
- 0x8005, 0, 127, 16, 119, 72, 0,
- 1500, 255, 89, 65, 0, 196, 3,
- 2790, 246, 39, 112, 0, 240, 0,
- 1905, 246, 36, 81, 168, 208, 0,
- 0, 249, 114, 49, 172, 212, 0
- },
-
- /* Region 108 */
- {
- 0x8005, 0, 127, 0, 255, 237, 0,
- 1902, 254, 89, 65, 0, 212, 2,
- 0, 248, 87, 112, 0, 240, 2,
- 3369, 231, 62, 81, 0, 208, 2,
- 3, 245, 118, 49, 96, 196, 2
- },
-
- /* Region 109 */
- {
- 0x8002, 0, 127, 16, 188, 205, 0,
- -2, 179, 47, 50, 244, 224, 2,
- 1900, 145, 94, 49, 248, 232, 2,
- 3, 210, 46, 2, 244, 208, 2,
- 2789, 133, 93, 4, 180, 244, 2
- },
-
- /* Region 110 */
- {
- 0x8005, 0, 127, 48, 135, 220, 0,
- 1901, 162, 25, 35, 144, 208, 0,
- 0, 113, 105, 65, 220, 240, 0,
- 3369, 233, 88, 51, 120, 212, 0,
- 0, 229, 24, 84, 200, 208, 0
- },
-
- /* Region 111 */
- {
- 0x8002, 0, 127, 112, 32, 190, 0,
- 0, 53, 79, 66, 152, 212, 2,
- 1200, 53, 75, 64, 136, 244, 2,
- 500, 149, 60, 66, 16, 208, 2,
- 1902, 200, 78, 64, 0, 248, 0
- },
-
- /* Region 112 */
- {
- 0x8005, 0, 127, 0, 144, 130, 0,
- 2514, 255, 68, 53, 0, 204, 2,
- 2400, 247, 133, 48, 0, 240, 2,
- 4151, 243, 67, 50, 0, 212, 2,
- 3369, 243, 66, 56, 0, 204, 2
- },
-
- /* Region 113 */
- {
- 0x8005, 0, 127, 0, 255, 0, 0,
- 514, 253, 79, 51, 0, 196, 3,
- 1905, 252, 89, 51, 0, 244, 2,
- 4349, 245, 35, 51, 0, 208, 2,
- 1205, 247, 34, 51, 0, 208, 2
- },
-
- /* Region 114 */
- {
- 0x8005, 0, 127, 0, 255, 0, 0,
- 514, 221, 69, 35, 0, 204, 3,
- 0, 250, 86, 115, 0, 252, 2,
- 1884, 244, 116, 51, 0, 200, 2,
- 1208, 210, 35, 51, 0, 208, 2
- },
-
- /* Region 115 */
- {
- 0x8005, 0, 127, 0, 255, 16, 0,
- 514, 222, 85, 163, 0, 192, 3,
- 0, 254, 108, 163, 0, 252, 2,
- 3800, 255, 143, 160, 0, 176, 2,
- 1200, 250, 105, 163, 0, 212, 2
- },
-
- /* Region 116 */
- {
- 0x8005, 0, 127, 0, 255, 16, 0,
- 1514, 249, 101, 163, 0, 204, 3,
- -1200, 249, 87, 160, 0, 252, 2,
- 0, 235, 143, 160, 0, 204, 2,
- 1200, 234, 73, 163, 0, 204, 2
- },
-
- /* Region 117 */
- {
- 0x8005, 0, 127, 0, 255, 16, 0,
- 500, 239, 101, 160, 0, 204, 3,
- -1195, 248, 104, 160, 0, 252, 2,
- 1898, 252, 72, 163, 0, 216, 2,
- 1239, 248, 87, 163, 0, 196, 2
- },
-
- /* Region 118 */
- {
- 0x8005, 0, 127, 0, 255, 255, 0,
- 500, 255, 98, 160, 0, 196, 3,
- -1, 249, 105, 160, 0, 252, 2,
- 1907, 250, 71, 160, 0, 252, 2,
- 1182, 249, 87, 161, 0, 192, 2
- },
-
- /* Region 119 */
- {
- 0x8005, 0, 127, 0, 0, 100, 0,
- 600, 32, 15, 0, 252, 224, 6,
- 0, 47, 111, 65, 0, 244, 2,
- 1826, 16, 47, 0, 252, 216, 2,
- 3551, 240, 47, 0, 252, 212, 2
- },
-
- /* Region 120 */
- {
- 0x8014, 0, 127, 240, 128, 235, 0,
- 1228, 161, 47, 17, 196, 200, 3,
- 3000, 123, 75, 17, 0, 240, 2,
- 7022, 72, 43, 17, 0, 216, 0,
- 4000, 150, 79, 17, 48, 196, 3
- },
-
- /* Region 121 */
- {
- 0x8005, 0, 127, 224, 16, 86, 0,
- 275, 251, 6, 0, 36, 200, 2,
- 0, 101, 104, 65, 56, 240, 2,
- 0, 240, 6, 0, 252, 208, 6,
- 1000, 195, 8, 0, 248, 200, 2
- },
-
- /* Region 122 */
- {
- 0x8002, 0, 127, 0, 0, 185, 0,
- 600, 35, 66, 17, 72, 224, 4,
- -13000, 81, 67, 17, 228, 244, 2,
- 702, 97, 38, 17, 212, 196, 6,
- -14000, 81, 65, 17, 224, 244, 3
- },
-
- /* Region 123 */
- {
- 0x8012, 0, 127, 240, 112, 237, 0,
- -6528, 153, 127, 16, 0, 252, 3,
- 1200, 105, 109, 16, 0, 216, 2,
- -6022, 179, 139, 17, 0, 248, 3,
- 2000, 104, 79, 17, 0, 240, 0
- },
-
- /* Region 124 */
- {
- 0x8012, 0, 127, 240, 240, 16, 0,
- 1914, 240, 64, 160, 240, 208, 2,
- 1200, 240, 73, 163, 240, 244, 0,
- 1900, 240, 64, 160, 240, 148, 2,
- 4151, 240, 73, 163, 240, 244, 0
- },
-
- /* Region 125 */
- {
- 0x8002, 0, 127, 240, 56, 235, 0,
- -5522, 97, 32, 17, 196, 240, 3,
- 0, 84, 75, 17, 180, 248, 3,
- 702, 65, 38, 17, 224, 212, 6,
- -4000, 161, 73, 17, 224, 252, 1
- },
-
- /* Region 126 */
- {
- 0x8015, 0, 127, 240, 248, 37, 0,
- 1050, 243, 0, 0, 252, 224, 7,
- 2000, 49, 68, 0, 224, 236, 3,
- 350, 240, 0, 0, 252, 216, 1,
- 700, 240, 0, 0, 252, 212, 3
- },
-
- /* Region 127 */
- {
- 0x8015, 0, 127, 240, 248, 37, 0,
- 1050, 245, 85, 0, 0, 244, 7,
- -5000, 247, 71, 0, 0, 252, 3,
- 350, 240, 0, 0, 0, 164, 0,
- 700, 32, 0, 0, 0, 252, 2
- },
-
- /* Region 128 */
- {
- 0x0005, 35, 35, 0, 255, 103, 0,
- 3, 215, 68, 65, 0, 204, 2,
- -1700, 249, 95, 177, 0, 252, 2,
- 5374, 236, 144, 204, 0, 176, 3,
- 114, 253, 144, 179, 0, 200, 3
- },
-
- /* Region 129 */
- {
- 0x0005, 36, 36, 0, 255, 103, 0,
- 3, 219, 68, 65, 0, 204, 2,
- -1700, 251, 95, 177, 0, 252, 2,
- 5374, 255, 144, 204, 0, 176, 3,
- 114, 255, 144, 179, 0, 208, 3
- },
-
- /* Region 130 */
- {
- 0x001a, 37, 37, 240, 128, 216, 0,
- 2780, 255, 16, 0, 112, 200, 3,
- 3800, 255, 32, 0, 0, 240, 3,
- 2501, 251, 48, 0, 48, 240, 3,
- 2751, 254, 48, 0, 0, 244, 3
- },
-
- /* Region 131 */
- {
- 0x000d, 38, 38, 0, 255, 190, 0,
- -2000, 239, 48, 128, 0, 236, 3,
- -2400, 254, 92, 128, 0, 252, 2,
- 3374, 255, 33, 192, 240, 244, 2,
- 1000, 255, 49, 176, 240, 204, 2
- },
-
- /* Region 132 */
- {
- 0x001a, 39, 39, 240, 128, 254, -10,
- 5780, 186, 16, 0, 112, 240, 3,
- 3800, 254, 32, 0, 0, 248, 3,
- 5780, 234, 16, 0, 112, 240, 3,
- 4829, 254, 32, 0, 0, 252, 3
- },
-
- /* Region 133 */
- {
- 0x000d, 40, 40, 0, 255, 203, 0,
- 0, 254, 74, 128, 0, 176, 3,
- -600, 252, 73, 128, 0, 252, 3,
- 3368, 251, 80, 192, 0, 244, 3,
- 1200, 254, 64, 176, 0, 208, 3
- },
-
- /* Region 134 */
- {
- 0x000d, 41, 41, 208, 16, 187, -30,
- -600, 247, 128, 0, 0, 204, 1,
- -890, 248, 88, 0, 0, 252, 3,
- 1068, 250, 182, 0, 0, 200, 3,
- -100, 249, 116, 0, 0, 208, 3
- },
-
- /* Region 135 */
- {
- 0x0005, 42, 42, 160, 255, 126, 20,
- 3514, 247, 23, 72, 0, 212, 3,
- 400, 255, 94, 177, 0, 232, 2,
- 2347, 250, 47, 0, 196, 184, 6,
- 4388, 248, 26, 0, 136, 224, 2
- },
-
- /* Region 136 */
- {
- 0x000d, 43, 43, 208, 16, 187, -20,
- -500, 247, 128, 0, 0, 204, 1,
- -690, 249, 88, 0, 0, 252, 3,
- 1068, 254, 182, 0, 0, 200, 3,
- 0, 249, 116, 0, 0, 208, 3
- },
-
- /* Region 137 */
- {
- 0x0005, 44, 44, 160, 255, 126, 20,
- 3514, 151, 20, 72, 0, 244, 3,
- 400, 223, 92, 177, 0, 240, 2,
- 2347, 134, 34, 0, 176, 208, 6,
- 4388, 200, 21, 0, 100, 220, 2
- },
-
- /* Region 138 */
- {
- 0x000d, 45, 45, 208, 16, 187, -10,
- -350, 246, 128, 0, 0, 204, 1,
- -590, 249, 88, 0, 0, 252, 3,
- 2368, 254, 182, 0, 0, 196, 3,
- 500, 249, 116, 0, 0, 208, 3
- },
-
- /* Region 139 */
- {
- 0x0005, 46, 46, 160, 255, 126, 20,
- 3510, 147, 51, 72, 0, 236, 3,
- 400, 219, 90, 177, 0, 240, 2,
- 2347, 134, 66, 0, 176, 224, 6,
- 4388, 200, 84, 0, 100, 212, 2
- },
-
- /* Region 140 */
- {
- 0x000d, 47, 47, 176, 32, 187, 10,
- 0, 247, 128, 0, 0, 204, 1,
- -280, 249, 88, 0, 0, 252, 3,
- 2968, 255, 182, 0, 0, 200, 3,
- 700, 250, 116, 0, 0, 204, 3
- },
-
- /* Region 141 */
- {
- 0x000d, 48, 48, 0, 255, 187, 20,
- 10, 247, 128, 0, 0, 204, 3,
- -130, 249, 88, 0, 0, 252, 3,
- 3068, 255, 182, 0, 0, 188, 3,
- 800, 250, 116, 0, 0, 204, 3
- },
-
- /* Region 142 */
- {
- 0x000d, 49, 49, 160, 255, 215, 20,
- 3986, 18, 6, 8, 0, 252, 2,
- 0, 247, 70, 1, 0, 240, 2,
- 5354, 242, 48, 0, 252, 216, 2,
- 3868, 193, 48, 0, 212, 208, 2
- },
-
- /* Region 143 */
- {
- 0x000d, 50, 50, 0, 255, 201, 30,
- 200, 247, 128, 0, 0, 208, 3,
- 20, 249, 88, 0, 0, 252, 3,
- 3368, 255, 182, 0, 0, 200, 3,
- 1100, 250, 116, 0, 0, 204, 3
- },
-
- /* Region 144 */
- {
- 0x000d, 51, 51, 160, 255, 97, -20,
- 3831, 240, 39, 0, 232, 224, 3,
- 1258, 246, 102, 0, 0, 232, 3,
- 4323, 242, 32, 0, 0, 216, 3,
- 868, 243, 64, 0, 0, 204, 3
- },
-
- /* Region 145 */
- {
- 0x000d, 52, 52, 112, 128, 234, -20,
- 725, 228, 32, 0, 0, 208, 1,
- 400, 248, 86, 0, 0, 248, 3,
- 2003, 53, 32, 0, 0, 236, 3,
- 100, 209, 32, 0, 0, 212, 1
- },
-
- /* Region 146 */
- {
- 0x000d, 53, 53, 160, 255, 97, -20,
- 3831, 240, 39, 0, 232, 224, 3,
- 1258, 246, 102, 0, 0, 232, 3,
- 4323, 242, 32, 0, 0, 224, 3,
- 868, 243, 64, 0, 0, 196, 3
- },
-
- /* Region 147 */
- {
- 0x001d, 54, 54, 240, 240, 242, 10,
- -1, 245, 71, 1, 24, 236, 0,
- 1200, 218, 102, 1, 0, 236, 2,
- 1354, 255, 48, 0, 0, 208, 2,
- 5868, 209, 48, 0, 160, 212, 0
- },
-
- /* Region 148 */
- {
- 0x000d, 55, 55, 48, 32, 234, -10,
- 725, 228, 32, 0, 0, 208, 3,
- 900, 249, 86, 0, 0, 240, 3,
- 2303, 69, 32, 0, 0, 236, 1,
- 400, 177, 32, 0, 0, 212, 3
- },
-
- /* Region 149 */
- {
- 0x000d, 56, 56, 0, 255, 149, 20,
- 414, 254, 123, 48, 0, 204, 3,
- 1986, 252, 118, 48, 0, 244, 3,
- 4383, 242, 67, 48, 0, 200, 3,
- 4205, 243, 81, 48, 0, 204, 3
- },
-
- /* Region 150 */
- {
- 0x000d, 57, 57, 48, 32, 234, -20,
- 526, 210, 32, 0, 0, 200, 3,
- 719, 246, 86, 0, 0, 240, 3,
- 1303, 48, 32, 0, 0, 236, 1,
- 202, 98, 32, 0, 0, 212, 3
- },
-
- /* Region 151 */
- {
- 0x001d, 58, 58, 240, 240, 204, -40,
- 5650, 247, 16, 0, 84, 220, 1,
- 3800, 248, 32, 0, 0, 248, 3,
- 1780, 252, 16, 0, 0, 152, 3,
- 6825, 245, 32, 0, 0, 208, 1
- },
-
- /* Region 152 */
- {
- 0x000d, 59, 59, 144, 0, 108, -20,
- 3531, 240, 103, 0, 232, 220, 3,
- 1058, 246, 102, 0, 0, 232, 3,
- 5331, 242, 64, 0, 0, 220, 3,
- 1968, 243, 64, 0, 0, 204, 1
- },
-
- /* Region 153 */
- {
- 0x000d, 60, 60, 192, 64, 155, 40,
- 700, 214, 84, 0, 0, 208, 1,
- 950, 253, 76, 0, 0, 248, 3,
- 2803, 255, 127, 0, 0, 200, 3,
- 750, 255, 89, 0, 0, 204, 3
- },
-
- /* Region 154 */
- {
- 0x000d, 61, 61, 224, 48, 91, 40,
- 400, 229, 68, 0, 0, 204, 1,
- 700, 251, 76, 0, 0, 248, 3,
- 1803, 255, 95, 0, 0, 196, 3,
- 450, 255, 89, 0, 0, 208, 3
- },
-
- /* Region 155 */
- {
- 0x000d, 62, 62, 240, 32, 191, 25,
- 214, 237, 69, 0, 0, 204, 1,
- 400, 252, 78, 0, 0, 248, 3,
- 2830, 255, 95, 0, 0, 208, 3,
- 2500, 255, 25, 0, 0, 192, 3
- },
-
- /* Region 156 */
- {
- 0x000d, 63, 63, 240, 32, 91, 25,
- 400, 229, 68, 0, 0, 188, 1,
- -100, 250, 76, 0, 0, 248, 3,
- 1803, 254, 95, 0, 0, 200, 3,
- 450, 238, 89, 0, 0, 200, 3
- },
-
- /* Region 157 */
- {
- 0x000d, 64, 64, 240, 16, 91, 20,
- 300, 210, 68, 0, 0, 196, 1,
- -400, 250, 76, 0, 0, 248, 3,
- 1803, 254, 95, 0, 0, 200, 3,
- 550, 238, 89, 0, 0, 200, 3
- },
-
- /* Region 158 */
- {
- 0x001c, 65, 65, 240, 128, 223, 20,
- 1780, 234, 16, 0, 112, 208, 3,
- 800, 251, 32, 0, 0, 248, 3,
- 5501, 231, 48, 0, 48, 200, 3,
- 2751, 232, 48, 0, 0, 220, 3
- },
-
- /* Region 159 */
- {
- 0x001c, 66, 66, 240, 128, 223, 20,
- 1580, 234, 16, 0, 112, 208, 3,
- 600, 250, 32, 0, 0, 248, 3,
- 5201, 231, 48, 0, 48, 200, 3,
- 2510, 232, 48, 0, 0, 220, 3
- },
-
- /* Region 160 */
- {
- 0x000d, 67, 67, 0, 255, 0, -35,
- 1514, 255, 63, 51, 0, 184, 3,
- 4830, 251, 73, 51, 0, 252, 3,
- 4349, 245, 67, 51, 0, 212, 3,
- 5267, 246, 65, 51, 0, 200, 3
- },
-
- /* Region 161 */
- {
- 0x000d, 68, 68, 0, 255, 0, -35,
- 1514, 255, 63, 51, 0, 196, 3,
- 4905, 251, 73, 51, 0, 252, 3,
- 4349, 245, 67, 51, 0, 196, 3,
- 5214, 246, 65, 51, 0, 208, 3
- },
-
- /* Region 162 */
- {
- 0x000a, 69, 69, 240, 240, 243, -35,
- 10000, 160, 68, 0, 0, 200, 3,
- 7000, 156, 140, 0, 0, 228, 3,
- 1586, 176, 16, 0, 0, 228, 7,
- 8000, 140, 80, 0, 0, 236, 3
- },
-
- /* Region 163 */
- {
- 0x001a, 70, 70, 240, 240, 227, -38,
- 500, 240, 52, 0, 0, 220, 1,
- 8000, 188, 124, 0, 0, 228, 3,
- 1586, 240, 16, 0, 0, 224, 7,
- 8000, 203, 80, 0, 0, 228, 3
- },
-
- /* Region 164 */
- {
- 0x0004, 71, 71, 226, 240, 181, 35,
- 7253, 224, 32, 48, 0, 184, 3,
- 3594, 224, 79, 48, 0, 248, 1,
- 220, 97, 19, 48, 156, 152, 3,
- 5243, 172, 16, 48, 92, 204, 1
- },
-
- /* Region 165 */
- {
- 0x0004, 72, 72, 240, 241, 181, 35,
- 6253, 134, 32, 48, 0, 184, 3,
- 3994, 176, 76, 48, 160, 248, 1,
- 22, 183, 19, 48, 156, 172, 3,
- 1243, 160, 16, 48, 240, 188, 3
- },
-
- /* Region 166 */
- {
- 0x001a, 73, 73, 240, 224, 155, 30,
- -2145, 240, 70, 0, 0, 252, 3,
- 600, 109, 111, 0, 0, 240, 3,
- -1800, 240, 71, 0, 0, 248, 3,
- 200, 173, 111, 0, 0, 240, 3
- },
-
- /* Region 167 */
- {
- 0x0012, 74, 74, 240, 224, 119, 30,
- -2545, 240, 70, 0, 252, 252, 3,
- 0, 153, 111, 0, 0, 240, 3,
- -2400, 240, 71, 0, 252, 252, 3,
- 100, 137, 111, 0, 0, 240, 3
- },
-
- /* Region 168 */
- {
- 0x001a, 75, 75, 240, 128, 240, 20,
- 3780, 255, 16, 0, 252, 188, 2,
- 800, 255, 64, 0, 0, 248, 2,
- 2501, 255, 48, 0, 252, 208, 0,
- 751, 255, 48, 0, 0, 236, 2
- },
-
- /* Region 169 */
- {
- 0x000d, 76, 76, 0, 255, 68, 35,
- 1100, 239, 69, 0, 0, 184, 3,
- 2600, 255, 76, 0, 0, 252, 3,
- 5000, 255, 111, 0, 0, 204, 3,
- 3400, 254, 73, 0, 0, 184, 3
- },
-
- /* Region 170 */
- {
- 0x000d, 77, 77, 0, 255, 68, 35,
- 914, 239, 69, 0, 0, 180, 3,
- 1801, 254, 76, 0, 0, 252, 3,
- 4800, 255, 111, 0, 0, 192, 3,
- 3200, 254, 73, 0, 0, 192, 3
- },
-
- /* Region 171 */
- {
- 0x000d, 78, 78, 240, 32, 197, -20,
- 1200, 216, 86, 0, 0, 180, 1,
- 1800, 189, 127, 0, 0, 244, 3,
- 2700, 156, 102, 0, 0, 196, 1,
- 700, 109, 104, 0, 0, 196, 1
- },
-
- /* Region 172 */
- {
- 0x000d, 79, 79, 240, 32, 197, -20,
- 1200, 216, 86, 0, 0, 196, 1,
- 2200, 171, 127, 0, 0, 244, 3,
- 2700, 145, 102, 0, 0, 192, 1,
- 700, 106, 104, 0, 0, 192, 1
- },
-
- /* Region 173 */
- {
- 0x000d, 80, 80, 0, 255, 0, -40,
- 3514, 254, 79, 51, 0, 196, 3,
- 5905, 252, 73, 51, 0, 248, 3,
- 6348, 245, 35, 51, 0, 176, 3,
- 2203, 244, 33, 51, 0, 216, 3
- },
-
- /* Region 174 */
- {
- 0x800d, 81, 81, 0, 255, 0, -40,
- 3514, 255, 79, 51, 0, 192, 3,
- 5905, 246, 73, 51, 0, 252, 3,
- 6348, 241, 35, 51, 0, 180, 3,
- 2203, 242, 33, 51, 0, 212, 3
- }
-};
-
-
-/*----------------------------------------------------------------------------
- * Programs
- *----------------------------------------------------------------------------
-*/
-const S_PROGRAM programs[] =
-{
- { 7864320, 128 } /* program 0 */
-}; /* end Programs */
-
-/*----------------------------------------------------------------------------
- * Banks
- *----------------------------------------------------------------------------
-*/
-const S_BANK banks[] =
-{
- { /* bank 0 */
- 30976,
- {
- 0, 1, 2, 3, 4, 5, 6, 7,
- 8, 9, 10, 11, 12, 13, 14, 15,
- 16, 17, 18, 19, 20, 21, 22, 23,
- 24, 25, 26, 27, 28, 29, 30, 31,
- 32, 33, 34, 35, 36, 37, 38, 39,
- 40, 41, 42, 43, 44, 45, 46, 47,
- 48, 49, 50, 51, 52, 53, 54, 55,
- 56, 57, 58, 59, 60, 61, 62, 63,
- 64, 65, 66, 67, 68, 69, 70, 71,
- 72, 73, 74, 75, 76, 77, 78, 79,
- 80, 81, 82, 83, 84, 85, 86, 87,
- 88, 89, 90, 91, 92, 93, 94, 95,
- 96, 97, 98, 99, 100, 101, 102, 103,
- 104, 105, 106, 107, 108, 109, 110, 111,
- 112, 113, 114, 115, 116, 117, 118, 119,
- 120, 121, 122, 123, 124, 125, 126, 127
- }
- }
-}; /* end Banks */
-
-/*----------------------------------------------------------------------------
- * S_EAS
- *----------------------------------------------------------------------------
-*/
-const S_EAS easSoundLib =
-{
- 0x01534145,
- 0x00105622,
-
- banks,
- programs,
-
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
-
- regions,
-
- 1,
- 1,
-
- 0,
- 0,
- 0,
-
- 175
-}; /* end S_EAS */
-/* end sound library */
+ *
+ * Source: C:\Sonic\Source\Gen3.3\FMSynth\GMdblib-3.fml
+ ********************************************************************/
+
+
+#include "eas_data.h"
+
+/* begin region data */
+/*lint -e{651} lint complains about unnecessary brackets */
+const S_FM_REGION regions[] =
+{
+
+ /* Region 0 */
+ {
+ 0x8005, 0, 127, 0, 255, 8, 0,
+ 514, 239, 47, 97, 0, 184, 3,
+ 1, 244, 89, 114, 0, 248, 2,
+ 3370, 244, 49, 76, 40, 192, 2,
+ -1, 227, 97, 51, 160, 212, 2
+ },
+
+ /* Region 1 */
+ {
+ 0x8005, 0, 127, 160, 255, 8, 0,
+ 2514, 223, 95, 72, 0, 176, 3,
+ 1, 244, 73, 145, 0, 244, 2,
+ 3600, 245, 81, 198, 40, 192, 2,
+ 3, 246, 81, 163, 108, 212, 2
+ },
+
+ /* Region 2 */
+ {
+ 0x8005, 0, 127, 160, 255, 119, 0,
+ 0, 216, 79, 72, 0, 216, 2,
+ 2, 244, 73, 145, 0, 244, 2,
+ 3370, 247, 33, 182, 60, 204, 2,
+ 1200, 246, 65, 163, 108, 204, 2
+ },
+
+ /* Region 3 */
+ {
+ 0x8005, 0, 127, 160, 255, 1, 0,
+ 3369, 248, 65, 71, 40, 208, 2,
+ -3, 245, 88, 113, 0, 244, 2,
+ 2784, 225, 65, 133, 80, 192, 2,
+ 3, 241, 81, 113, 80, 216, 2
+ },
+
+ /* Region 4 */
+ {
+ 0x8002, 0, 127, 0, 255, 128, 0,
+ 0, 229, 155, 183, 0, 228, 2,
+ -3, 243, 90, 81, 0, 244, 2,
+ 4800, 248, 109, 180, 36, 192, 2,
+ 3, 245, 90, 85, 16, 244, 2
+ },
+
+ /* Region 5 */
+ {
+ 0x8002, 0, 127, 9, 96, 192, 0,
+ 1200, 229, 157, 180, 0, 216, 2,
+ -3, 244, 90, 81, 0, 244, 2,
+ 1902, 255, 111, 182, 80, 208, 2,
+ 3, 246, 92, 83, 0, 244, 2
+ },
+
+ /* Region 6 */
+ {
+ 0x8002, 0, 127, 0, 255, 154, 0,
+ 3102, 244, 63, 102, 228, 228, 2,
+ 1200, 247, 93, 97, 0, 236, 2,
+ 1902, 255, 63, 98, 156, 220, 2,
+ 1200, 244, 92, 98, 0, 236, 2
+ },
+
+ /* Region 7 */
+ {
+ 0x8005, 0, 127, 0, 255, 202, 0,
+ 0, 251, 131, 19, 216, 220, 2,
+ 1201, 247, 62, 113, 0, 240, 2,
+ 0, 243, 154, 36, 240, 224, 2,
+ 2784, 250, 61, 36, 240, 208, 2
+ },
+
+ /* Region 8 */
+ {
+ 0x8001, 0, 127, 0, 255, 80, 0,
+ -1, 213, 191, 183, 0, 204, 2,
+ 1, 245, 154, 129, 0, 244, 2,
+ 3831, 252, 159, 100, 0, 200, 2,
+ 1197, 246, 91, 182, 0, 244, 2
+ },
+
+ /* Region 9 */
+ {
+ 0x8002, 0, 127, 48, 80, 21, 0,
+ 2982, 255, 43, 96, 0, 196, 3,
+ 3, 247, 71, 130, 0, 244, 2,
+ 3358, 253, 40, 98, 144, 208, 2,
+ -2, 246, 70, 130, 0, 236, 2
+ },
+
+ /* Region 10 */
+ {
+ 0x8002, 0, 127, 48, 80, 26, 0,
+ 3096, 249, 72, 100, 0, 208, 2,
+ 2185, 249, 102, 130, 0, 240, 2,
+ 3386, 247, 66, 100, 144, 212, 2,
+ -2, 247, 102, 130, 0, 240, 2
+ },
+
+ /* Region 11 */
+ {
+ 0x8002, 0, 127, 92, 67, 21, 0,
+ 2982, 255, 27, 146, 0, 200, 3,
+ 3, 246, 68, 146, 0, 240, 2,
+ 3358, 250, 149, 116, 144, 208, 2,
+ -3, 245, 68, 146, 0, 240, 0
+ },
+
+ /* Region 12 */
+ {
+ 0x8002, 0, 127, 0, 67, 0, 0,
+ 1500, 239, 60, 151, 0, 220, 2,
+ 0, 247, 76, 146, 0, 240, 2,
+ 2398, 234, 156, 151, 0, 212, 2,
+ 0, 246, 105, 146, 0, 244, 2
+ },
+
+ /* Region 13 */
+ {
+ 0x8002, 0, 127, 0, 67, 0, 0,
+ 2500, 255, 60, 151, 0, 220, 2,
+ 0, 249, 92, 146, 0, 244, 2,
+ 3369, 250, 156, 151, 0, 196, 2,
+ 0, 248, 89, 146, 0, 244, 2
+ },
+
+ /* Region 14 */
+ {
+ 0x8005, 0, 127, 160, 255, 0, 0,
+ 2300, 229, 112, 49, 0, 208, 2,
+ -3, 247, 67, 50, 0, 248, 2,
+ 1074, 255, 41, 49, 0, 196, 2,
+ 686, 240, 97, 18, 0, 196, 2
+ },
+
+ /* Region 15 */
+ {
+ 0x8005, 0, 127, 160, 255, 219, 0,
+ 3369, 255, 65, 70, 40, 216, 2,
+ 1, 246, 72, 113, 0, 240, 2,
+ 1902, 225, 33, 129, 80, 204, 2,
+ 2400, 225, 97, 113, 80, 200, 2
+ },
+
+ /* Region 16 */
+ {
+ 0x8003, 0, 127, 32, 48, 151, 0,
+ 1201, 215, 35, 66, 252, 208, 0,
+ -9581, 254, 63, 177, 240, 240, 3,
+ 1902, 248, 47, 64, 112, 244, 2,
+ 0, 247, 35, 66, 208, 212, 2
+ },
+
+ /* Region 17 */
+ {
+ 0x8001, 0, 127, 0, 255, 153, 0,
+ 1, 252, 31, 3, 244, 196, 2,
+ -1, 208, 31, 4, 248, 244, 2,
+ 1205, 209, 31, 4, 248, 236, 2,
+ 1899, 250, 31, 32, 0, 240, 2
+ },
+
+ /* Region 18 */
+ {
+ 0x8002, 0, 127, 32, 49, 201, 0,
+ 1, 220, 47, 3, 244, 220, 0,
+ -10000, 208, 63, 1, 248, 240, 3,
+ 1586, 255, 47, 3, 188, 216, 2,
+ -1, 202, 63, 32, 80, 232, 2
+ },
+
+ /* Region 19 */
+ {
+ 0x8001, 0, 127, 0, 143, 29, 0,
+ -1200, 223, 64, 0, 252, 216, 2,
+ 1200, 96, 41, 35, 248, 240, 2,
+ 1200, 143, 41, 64, 252, 224, 2,
+ 3102, 161, 41, 96, 248, 216, 2
+ },
+
+ /* Region 20 */
+ {
+ 0x8002, 0, 127, 0, 143, 34, 0,
+ -1200, 133, 79, 1, 252, 212, 2,
+ 1201, 112, 46, 34, 248, 232, 2,
+ 0, 116, 79, 65, 252, 200, 2,
+ 1900, 161, 46, 98, 248, 232, 2
+ },
+
+ /* Region 21 */
+ {
+ 0x8002, 0, 127, 0, 143, 187, 0,
+ 1202, 80, 74, 1, 252, 216, 2,
+ 2402, 112, 46, 34, 248, 232, 2,
+ 0, 99, 78, 97, 184, 216, 2,
+ 1899, 81, 46, 98, 236, 232, 2
+ },
+
+ /* Region 22 */
+ {
+ 0x8005, 0, 127, 22, 141, 34, 0,
+ 2787, 176, 79, 4, 252, 208, 2,
+ 2785, 144, 45, 34, 248, 236, 2,
+ 3369, 83, 77, 100, 184, 172, 2,
+ 1902, 102, 45, 100, 172, 212, 0
+ },
+
+ /* Region 23 */
+ {
+ 0x8002, 0, 127, 0, 143, 135, 0,
+ 1900, 112, 79, 3, 252, 220, 2,
+ 2400, 128, 45, 34, 248, 232, 2,
+ 1200, 115, 77, 98, 184, 220, 2,
+ 1904, 97, 45, 98, 236, 232, 2
+ },
+
+ /* Region 24 */
+ {
+ 0x8005, 0, 127, 0, 255, 157, 0,
+ 1200, 244, 54, 4, 20, 200, 2,
+ 0, 245, 92, 130, 0, 244, 2,
+ 3802, 247, 68, 21, 0, 196, 2,
+ 1, 245, 43, 114, 0, 204, 2
+ },
+
+ /* Region 25 */
+ {
+ 0x8005, 0, 127, 0, 128, 83, 0,
+ 0, 244, 51, 4, 200, 204, 0,
+ 0, 247, 108, 129, 0, 248, 0,
+ 2786, 243, 31, 70, 200, 220, 0,
+ 1902, 246, 44, 113, 12, 188, 0
+ },
+
+ /* Region 26 */
+ {
+ 0x8005, 0, 127, 0, 128, 61, 0,
+ 0, 246, 51, 97, 76, 204, 0,
+ 0, 244, 60, 97, 0, 240, 0,
+ 1786, 255, 31, 64, 0, 180, 0,
+ 1200, 247, 60, 97, 12, 204, 0
+ },
+
+ /* Region 27 */
+ {
+ 0x8005, 0, 127, 0, 128, 153, 0,
+ -2, 243, 53, 99, 96, 200, 0,
+ 0, 243, 60, 97, 0, 240, 0,
+ 3983, 247, 63, 100, 24, 204, 0,
+ 2, 242, 53, 99, 52, 212, 0
+ },
+
+ /* Region 28 */
+ {
+ 0x8005, 0, 127, 0, 128, 205, 0,
+ -2, 244, 47, 97, 20, 208, 0,
+ 0, 252, 75, 193, 0, 248, 0,
+ 0, 254, 63, 98, 132, 224, 0,
+ 2786, 251, 63, 98, 52, 192, 0
+ },
+
+ /* Region 29 */
+ {
+ 0x8005, 0, 127, 0, 128, 221, 0,
+ -1, 208, 191, 99, 220, 224, 0,
+ 1200, 243, 92, 97, 0, 244, 0,
+ 3984, 212, 11, 96, 168, 196, 0,
+ 1, 242, 127, 98, 108, 204, 0
+ },
+
+ /* Region 30 */
+ {
+ 0x8005, 0, 127, 0, 128, 174, 0,
+ -3, 212, 207, 99, 0, 228, 0,
+ 1902, 241, 108, 97, 0, 248, 0,
+ 3805, 212, 59, 98, 0, 220, 0,
+ 1902, 146, 107, 98, 144, 196, 0
+ },
+
+ /* Region 31 */
+ {
+ 0x8009, 0, 127, 0, 255, 128, 0,
+ 1206, 239, 43, 69, 0, 216, 2,
+ 4, 254, 42, 66, 0, 244, 2,
+ 702, 88, 55, 66, 0, 204, 2,
+ -4, 71, 55, 66, 0, 240, 2
+ },
+
+ /* Region 32 */
+ {
+ 0x8005, 0, 127, 0, 255, 85, 0,
+ 500, 239, 95, 82, 0, 184, 3,
+ 0, 248, 73, 132, 0, 252, 2,
+ 2786, 203, 59, 130, 0, 176, 2,
+ 0, 216, 42, 100, 0, 208, 2
+ },
+
+ /* Region 33 */
+ {
+ 0x8005, 0, 127, 0, 128, 73, 0,
+ 1, 229, 54, 131, 160, 208, 0,
+ -1, 244, 62, 97, 0, 248, 0,
+ 3986, 227, 127, 69, 140, 184, 0,
+ 1201, 249, 92, 114, 0, 204, 0
+ },
+
+ /* Region 34 */
+ {
+ 0x8005, 0, 127, 0, 128, 73, 0,
+ 1, 225, 54, 100, 200, 212, 0,
+ -1, 244, 94, 97, 0, 248, 0,
+ 3986, 249, 127, 88, 112, 188, 0,
+ 1201, 249, 92, 85, 52, 208, 0
+ },
+
+ /* Region 35 */
+ {
+ 0x8005, 0, 127, 0, 128, 188, 0,
+ -3, 198, 92, 179, 28, 212, 0,
+ 0, 243, 90, 145, 0, 248, 0,
+ 1901, 215, 95, 69, 28, 196, 0,
+ 3, 84, 108, 196, 32, 208, 0
+ },
+
+ /* Region 36 */
+ {
+ 0x8005, 0, 127, 0, 136, 6, 0,
+ 0, 226, 99, 36, 224, 216, 0,
+ 1902, 248, 78, 33, 0, 252, 0,
+ 3369, 239, 250, 33, 0, 204, 0,
+ 0, 230, 253, 33, 0, 208, 0
+ },
+
+ /* Region 37 */
+ {
+ 0x8005, 0, 127, 0, 136, 195, 0,
+ 0, 245, 99, 36, 152, 208, 0,
+ 1200, 248, 78, 33, 0, 252, 0,
+ 3369, 246, 250, 33, 0, 216, 0,
+ 0, 246, 61, 33, 0, 180, 0
+ },
+
+ /* Region 38 */
+ {
+ 0x8002, 0, 127, 0, 133, 221, 0,
+ 1, 244, 67, 35, 80, 220, 0,
+ 3, 246, 94, 33, 0, 244, 0,
+ -1, 245, 70, 35, 80, 236, 2,
+ -3, 246, 63, 33, 0, 236, 2
+ },
+
+ /* Region 39 */
+ {
+ 0x8002, 0, 127, 0, 133, 220, 0,
+ 0, 114, 51, 34, 132, 208, 0,
+ 3, 214, 62, 33, 0, 248, 0,
+ 0, 85, 54, 34, 44, 224, 2,
+ -3, 214, 63, 33, 0, 236, 2
+ },
+
+ /* Region 40 */
+ {
+ 0x8005, 0, 127, 48, 142, 187, 0,
+ -1, 33, 22, 33, 200, 208, 0,
+ 0, 81, 105, 33, 220, 240, 0,
+ 2786, 245, 19, 50, 208, 192, 0,
+ 1, 245, 21, 82, 200, 220, 0
+ },
+
+ /* Region 41 */
+ {
+ 0x8005, 0, 127, 48, 126, 103, 0,
+ -1, 193, 22, 33, 228, 212, 0,
+ 0, 81, 105, 33, 220, 244, 0,
+ 0, 245, 19, 50, 216, 228, 0,
+ 1200, 245, 19, 82, 200, 188, 0
+ },
+
+ /* Region 42 */
+ {
+ 0x8005, 0, 127, 16, 126, 202, 0,
+ -1, 49, 24, 41, 200, 212, 0,
+ 0, 81, 71, 49, 220, 244, 0,
+ 3371, 243, 19, 36, 232, 192, 0,
+ 1, 242, 24, 36, 220, 212, 0
+ },
+
+ /* Region 43 */
+ {
+ 0x8005, 0, 127, 16, 124, 205, 0,
+ 0, 129, 24, 49, 208, 200, 0,
+ 0, 67, 102, 81, 224, 244, 0,
+ 3804, 246, 23, 36, 160, 196, 0,
+ 1200, 244, 24, 35, 208, 200, 0
+ },
+
+ /* Region 44 */
+ {
+ 0x8005, 0, 127, 48, 144, 208, 0,
+ -3, 209, 22, 33, 200, 204, 2,
+ 0, 81, 89, 33, 220, 240, 2,
+ -5000, 208, 6, 33, 244, 188, 3,
+ 3, 97, 89, 33, 224, 200, 0
+ },
+
+ /* Region 45 */
+ {
+ 0x8005, 0, 127, 0, 255, 186, 0,
+ 500, 223, 95, 0, 0, 192, 3,
+ 0, 247, 89, 100, 0, 248, 2,
+ 3369, 255, 59, 168, 0, 212, 2,
+ 0, 216, 42, 97, 0, 212, 2
+ },
+
+ /* Region 46 */
+ {
+ 0x8002, 0, 127, 0, 255, 221, 0,
+ 1206, 235, 70, 69, 0, 216, 2,
+ 4, 248, 84, 66, 0, 244, 2,
+ 1902, 247, 52, 137, 80, 216, 2,
+ -4, 245, 84, 131, 0, 240, 2
+ },
+
+ /* Region 47 */
+ {
+ 0x8005, 0, 127, 0, 255, 105, 0,
+ 387, 231, 115, 34, 4, 216, 2,
+ 0, 248, 37, 65, 0, 252, 2,
+ 3308, 248, 117, 34, 8, 200, 2,
+ 1900, 213, 82, 50, 0, 192, 2
+ },
+
+ /* Region 48 */
+ {
+ 0x8002, 0, 127, 32, 160, 221, 0,
+ -7, 209, 22, 33, 200, 204, 2,
+ -7, 81, 73, 33, 220, 244, 0,
+ 7, 209, 22, 33, 200, 208, 0,
+ 7, 97, 73, 33, 224, 244, 2
+ },
+
+ /* Region 49 */
+ {
+ 0x8002, 0, 127, 64, 128, 189, 0,
+ -2, 209, 54, 32, 224, 216, 2,
+ -7726, 97, 105, 33, 220, 240, 3,
+ 1902, 209, 54, 34, 216, 208, 0,
+ 2, 81, 105, 33, 224, 236, 0
+ },
+
+ /* Region 50 */
+ {
+ 0x8002, 0, 127, 80, 144, 206, 0,
+ -3, 179, 38, 33, 160, 220, 2,
+ -7726, 81, 69, 34, 220, 244, 3,
+ 3, 193, 38, 33, 240, 212, 0,
+ -8000, 65, 69, 34, 224, 236, 3
+ },
+
+ /* Region 51 */
+ {
+ 0x8005, 0, 127, 96, 128, 204, 0,
+ -3, 97, 38, 33, 180, 216, 0,
+ 0, 81, 69, 34, 220, 240, 2,
+ 3369, 145, 38, 33, 240, 196, 2,
+ -13190, 65, 69, 34, 240, 200, 3
+ },
+
+ /* Region 52 */
+ {
+ 0x8002, 0, 127, 64, 128, 108, 0,
+ -3, 193, 37, 35, 236, 208, 0,
+ 2394, 97, 90, 36, 224, 232, 2,
+ 3, 65, 40, 35, 236, 204, 2,
+ 1203, 97, 89, 33, 224, 240, 0
+ },
+
+ /* Region 53 */
+ {
+ 0x8005, 0, 127, 128, 128, 122, 0,
+ 0, 193, 21, 34, 236, 188, 0,
+ 3, 97, 74, 36, 224, 248, 2,
+ 1906, 251, 24, 32, 96, 192, 3,
+ 1200, 97, 73, 32, 224, 184, 0
+ },
+
+ /* Region 54 */
+ {
+ 0x8002, 0, 127, 64, 133, 135, 0,
+ 0, 194, 25, 35, 120, 200, 2,
+ 0, 97, 75, 36, 224, 240, 0,
+ 2906, 254, 28, 48, 0, 184, 3,
+ 0, 216, 75, 80, 204, 240, 2
+ },
+
+ /* Region 55 */
+ {
+ 0x8009, 0, 127, 208, 64, 255, 0,
+ 475, 249, 16, 32, 252, 240, 2,
+ 702, 248, 71, 32, 0, 244, 2,
+ 1136, 232, 27, 32, 216, 248, 0,
+ 0, 249, 23, 48, 0, 248, 2
+ },
+
+ /* Region 56 */
+ {
+ 0x8005, 0, 127, 0, 132, 233, 0,
+ 0, 195, 95, 64, 240, 208, 0,
+ 0, 225, 94, 64, 248, 240, 0,
+ 0, 254, 127, 0, 4, 196, 4,
+ 1902, 228, 95, 1, 248, 200, 0
+ },
+
+ /* Region 57 */
+ {
+ 0x8005, 0, 127, 16, 140, 238, 0,
+ 0, 163, 90, 67, 228, 208, 0,
+ 0, 209, 77, 65, 248, 240, 0,
+ 1969, 173, 58, 65, 0, 176, 0,
+ 0, 210, 61, 52, 204, 220, 0
+ },
+
+ /* Region 58 */
+ {
+ 0x8005, 0, 127, 16, 140, 222, 0,
+ 0, 119, 74, 67, 160, 212, 0,
+ 0, 146, 61, 65, 248, 244, 0,
+ 1900, 137, 58, 65, 100, 196, 0,
+ 0, 119, 61, 52, 120, 200, 0
+ },
+
+ /* Region 59 */
+ {
+ 0x8005, 0, 127, 16, 135, 219, 0,
+ 0, 176, 79, 69, 240, 216, 0,
+ 0, 193, 79, 64, 248, 236, 0,
+ 0, 178, 123, 54, 92, 228, 0,
+ 3369, 212, 95, 38, 144, 212, 0
+ },
+
+ /* Region 60 */
+ {
+ 0x8002, 0, 127, 0, 119, 203, 0,
+ 2, 65, 77, 66, 228, 204, 0,
+ 2, 161, 74, 64, 240, 240, 0,
+ -2, 85, 60, 66, 180, 216, 2,
+ -2, 162, 74, 64, 220, 240, 2
+ },
+
+ /* Region 61 */
+ {
+ 0x8002, 0, 127, 16, 154, 237, 0,
+ 0, 179, 42, 64, 216, 208, 0,
+ 0, 209, 61, 64, 248, 244, 0,
+ -1200, 226, 55, 65, 244, 220, 2,
+ 1902, 162, 62, 52, 204, 236, 2
+ },
+
+ /* Region 62 */
+ {
+ 0x8002, 0, 127, 48, 119, 221, 0,
+ 2, 119, 79, 64, 208, 212, 0,
+ 2, 209, 110, 64, 248, 236, 0,
+ -2, 84, 79, 64, 136, 212, 2,
+ -2, 209, 110, 64, 240, 240, 2
+ },
+
+ /* Region 63 */
+ {
+ 0x8002, 0, 127, 32, 135, 221, 0,
+ 2, 165, 79, 64, 152, 216, 0,
+ 2, 225, 110, 64, 248, 236, 0,
+ -2, 132, 79, 64, 72, 224, 2,
+ -2, 241, 110, 64, 252, 236, 2
+ },
+
+ /* Region 64 */
+ {
+ 0x8005, 0, 127, 17, 127, 190, 0,
+ 0, 209, 60, 67, 244, 208, 0,
+ 1200, 145, 94, 65, 248, 244, 2,
+ 3369, 197, 47, 4, 128, 192, 0,
+ 1902, 167, 94, 6, 200, 200, 0
+ },
+
+ /* Region 65 */
+ {
+ 0x8005, 0, 127, 17, 143, 190, 0,
+ 0, 209, 60, 67, 244, 216, 0,
+ 1902, 145, 62, 65, 248, 240, 2,
+ 3369, 197, 47, 4, 128, 196, 0,
+ 2400, 167, 94, 6, 200, 212, 2
+ },
+
+ /* Region 66 */
+ {
+ 0x8005, 0, 127, 17, 143, 190, 0,
+ 0, 209, 60, 67, 244, 208, 0,
+ 1902, 145, 62, 65, 248, 240, 2,
+ 3369, 197, 47, 4, 128, 192, 0,
+ 1902, 167, 94, 6, 200, 216, 2
+ },
+
+ /* Region 67 */
+ {
+ 0x8005, 0, 127, 17, 125, 190, 0,
+ 0, 114, 109, 67, 244, 224, 0,
+ 1902, 166, 93, 97, 200, 240, 0,
+ 2786, 165, 95, 52, 160, 200, 0,
+ 2400, 173, 78, 54, 240, 212, 2
+ },
+
+ /* Region 68 */
+ {
+ 0x8002, 0, 127, 16, 140, 205, 0,
+ 0, 211, 55, 66, 244, 208, 0,
+ 1902, 193, 93, 65, 248, 240, 0,
+ 0, 204, 47, 4, 244, 216, 0,
+ 3600, 183, 95, 6, 160, 232, 0
+ },
+
+ /* Region 69 */
+ {
+ 0x8002, 0, 127, 16, 126, 222, 0,
+ 0, 243, 36, 66, 172, 200, 0,
+ 1200, 193, 110, 67, 248, 244, 0,
+ 0, 215, 33, 2, 232, 212, 0,
+ 3369, 178, 63, 6, 184, 240, 0
+ },
+
+ /* Region 70 */
+ {
+ 0x8002, 0, 127, 16, 140, 221, 0,
+ 1200, 213, 61, 66, 136, 200, 0,
+ 1902, 193, 93, 68, 248, 240, 0,
+ 0, 197, 47, 2, 228, 216, 0,
+ 3369, 183, 95, 2, 160, 236, 0
+ },
+
+ /* Region 71 */
+ {
+ 0x8002, 0, 127, 16, 124, 201, 0,
+ 1200, 195, 55, 68, 240, 208, 0,
+ 0, 209, 76, 65, 248, 236, 0,
+ 1902, 147, 47, 19, 208, 212, 0,
+ 0, 183, 79, 22, 156, 228, 0
+ },
+
+ /* Region 72 */
+ {
+ 0x8005, 0, 127, 32, 110, 234, 0,
+ 500, 237, 60, 68, 0, 192, 1,
+ 1, 161, 93, 65, 248, 240, 2,
+ 3365, 154, 47, 16, 48, 180, 6,
+ 1200, 165, 92, 52, 160, 212, 2
+ },
+
+ /* Region 73 */
+ {
+ 0x8005, 0, 127, 32, 142, 200, 0,
+ 0, 193, 60, 68, 248, 200, 0,
+ 1, 129, 61, 65, 248, 240, 2,
+ 3365, 154, 47, 16, 68, 184, 6,
+ 1200, 169, 92, 52, 160, 204, 2
+ },
+
+ /* Region 74 */
+ {
+ 0x8003, 0, 127, 32, 135, 36, 0,
+ 1199, 165, 79, 66, 152, 192, 2,
+ -3, 145, 110, 64, 248, 240, 2,
+ 0, 199, 79, 66, 44, 236, 2,
+ 2986, 136, 110, 67, 100, 196, 2
+ },
+
+ /* Region 75 */
+ {
+ 0x8005, 0, 127, 32, 190, 71, 0,
+ 868, 202, 140, 16, 24, 188, 2,
+ 0, 176, 77, 65, 248, 240, 2,
+ 3750, 169, 127, 16, 36, 228, 6,
+ 2400, 195, 60, 17, 232, 172, 2
+ },
+
+ /* Region 76 */
+ {
+ 0x8005, 0, 127, 224, 16, 123, 0,
+ 275, 202, 14, 2, 44, 196, 2,
+ 0, 165, 89, 65, 56, 244, 2,
+ 0, 255, 12, 2, 64, 216, 6,
+ 963, 169, 14, 4, 40, 196, 2
+ },
+
+ /* Region 77 */
+ {
+ 0x8012, 0, 127, 192, 128, 100, 0,
+ 1500, 202, 79, 68, 76, 204, 2,
+ -2, 97, 26, 64, 248, 232, 2,
+ 1588, 202, 223, 69, 4, 220, 0,
+ 3, 188, 121, 67, 48, 252, 2
+ },
+
+ /* Region 78 */
+ {
+ 0x8002, 0, 127, 112, 140, 205, 0,
+ 0, 68, 47, 66, 60, 176, 2,
+ -2, 113, 94, 64, 248, 236, 0,
+ 5000, 121, 47, 64, 32, 168, 7,
+ 3, 136, 94, 64, 0, 236, 0
+ },
+
+ /* Region 79 */
+ {
+ 0x8003, 0, 127, 32, 135, 33, 0,
+ 1199, 197, 79, 66, 152, 184, 2,
+ 0, 161, 110, 64, 248, 240, 2,
+ 0, 199, 79, 66, 44, 236, 2,
+ 2400, 255, 110, 65, 36, 208, 6
+ },
+
+ /* Region 80 */
+ {
+ 0x8002, 0, 127, 0, 192, 170, 0,
+ 1199, 192, 77, 33, 200, 212, 0,
+ 0, 209, 107, 33, 232, 240, 0,
+ 1201, 80, 77, 33, 200, 212, 0,
+ 0, 241, 107, 33, 232, 240, 0
+ },
+
+ /* Region 81 */
+ {
+ 0x8002, 0, 127, 0, 192, 221, 0,
+ -1, 192, 45, 33, 200, 212, 0,
+ -1, 209, 107, 33, 232, 244, 0,
+ 1, 80, 45, 33, 200, 212, 0,
+ 1, 241, 107, 33, 232, 244, 0
+ },
+
+ /* Region 82 */
+ {
+ 0x8005, 0, 127, 0, 112, 255, 0,
+ 4750, 221, 45, 34, 48, 172, 4,
+ -10000, 161, 107, 33, 200, 244, 3,
+ 2204, 137, 45, 37, 64, 184, 0,
+ -2, 211, 107, 33, 160, 208, 0
+ },
+
+ /* Region 83 */
+ {
+ 0x8005, 0, 127, 16, 127, 238, 0,
+ 2, 248, 45, 32, 204, 208, 0,
+ -9500, 241, 107, 33, 200, 240, 3,
+ 3369, 186, 45, 38, 24, 208, 0,
+ -2, 211, 107, 32, 220, 212, 0
+ },
+
+ /* Region 84 */
+ {
+ 0x8005, 0, 127, 0, 128, 221, 0,
+ -1, 192, 191, 99, 220, 216, 0,
+ 1200, 243, 92, 97, 0, 244, 0,
+ 3984, 200, 11, 96, 168, 192, 0,
+ 1, 194, 127, 98, 108, 200, 0
+ },
+
+ /* Region 85 */
+ {
+ 0x8002, 0, 127, 128, 128, 111, 0,
+ 1, 194, 25, 35, 120, 204, 2,
+ -9750, 193, 107, 36, 224, 244, 3,
+ 3906, 255, 28, 50, 12, 188, 3,
+ -1, 216, 107, 80, 204, 240, 2
+ },
+
+ /* Region 86 */
+ {
+ 0x8002, 0, 127, 32, 134, 222, 0,
+ 0, 195, 52, 33, 200, 208, 0,
+ 0, 177, 90, 33, 232, 240, 2,
+ 702, 195, 52, 33, 200, 208, 2,
+ 702, 177, 90, 34, 232, 240, 2
+ },
+
+ /* Region 87 */
+ {
+ 0x8002, 0, 127, 32, 134, 205, 0,
+ 0, 198, 75, 36, 120, 220, 2,
+ 0, 225, 78, 52, 40, 244, 2,
+ 0, 246, 47, 32, 220, 208, 2,
+ 1902, 241, 124, 32, 240, 236, 2
+ },
+
+ /* Region 88 */
+ {
+ 0x8003, 0, 127, 32, 120, 14, 0,
+ 3600, 244, 67, 34, 88, 208, 0,
+ 3, 194, 84, 33, 84, 240, 2,
+ -3, 194, 84, 33, 172, 236, 2,
+ 902, 254, 114, 34, 0, 224, 3
+ },
+
+ /* Region 89 */
+ {
+ 0x8002, 0, 127, 64, 169, 170, 0,
+ -3, 83, 69, 34, 184, 212, 0,
+ -7500, 50, 69, 33, 176, 244, 3,
+ 3, 81, 69, 34, 212, 212, 2,
+ -8500, 66, 69, 33, 176, 244, 3
+ },
+
+ /* Region 90 */
+ {
+ 0x8002, 0, 127, 64, 120, 221, 0,
+ -2, 82, 69, 34, 244, 216, 0,
+ 0, 145, 102, 33, 228, 240, 0,
+ 2, 81, 69, 34, 244, 208, 2,
+ 0, 145, 102, 33, 224, 240, 2
+ },
+
+ /* Region 91 */
+ {
+ 0x8003, 0, 127, 32, 138, 14, 0,
+ 2400, 148, 67, 34, 176, 200, 0,
+ 3, 194, 85, 33, 220, 236, 2,
+ -3, 194, 69, 33, 220, 236, 2,
+ 1905, 254, 114, 34, 48, 224, 2
+ },
+
+ /* Region 92 */
+ {
+ 0x8002, 0, 127, 82, 67, 71, 0,
+ 2982, 228, 22, 146, 88, 192, 3,
+ 3, 102, 84, 146, 196, 240, 2,
+ 3358, 50, 149, 116, 144, 208, 2,
+ -3, 85, 84, 146, 120, 240, 0
+ },
+
+ /* Region 93 */
+ {
+ 0x8005, 0, 127, 48, 126, 219, 0,
+ -3, 49, 19, 33, 120, 200, 0,
+ 0, 81, 70, 33, 220, 240, 0,
+ 3804, 242, 18, 50, 200, 200, 0,
+ 1203, 82, 19, 82, 200, 176, 0
+ },
+
+ /* Region 94 */
+ {
+ 0x8003, 0, 127, 32, 138, 13, 0,
+ 2786, 116, 67, 34, 204, 184, 0,
+ 1902, 114, 69, 33, 192, 232, 2,
+ -3, 178, 69, 33, 188, 232, 2,
+ 3804, 254, 82, 34, 164, 228, 2
+ },
+
+ /* Region 95 */
+ {
+ 0x8002, 0, 127, 48, 135, 238, 0,
+ -2, 34, 85, 34, 184, 224, 0,
+ 1, 113, 70, 33, 228, 236, 0,
+ 2, 19, 85, 34, 156, 224, 2,
+ -1, 129, 70, 33, 224, 236, 2
+ },
+
+ /* Region 96 */
+ {
+ 0x8012, 0, 127, 240, 112, 221, 0,
+ 3369, 213, 69, 32, 0, 204, 0,
+ 0, 193, 70, 33, 112, 232, 2,
+ 0, 145, 69, 34, 244, 208, 2,
+ -9000, 145, 70, 33, 224, 236, 3
+ },
+
+ /* Region 97 */
+ {
+ 0x8002, 0, 127, 96, 122, 168, 0,
+ -1, 99, 51, 33, 200, 208, 0,
+ -8500, 81, 83, 33, 232, 240, 3,
+ 702, 99, 52, 33, 200, 208, 2,
+ -9500, 65, 83, 34, 224, 240, 3
+ },
+
+ /* Region 98 */
+ {
+ 0x8002, 0, 127, 0, 67, 0, 0,
+ 1500, 217, 55, 151, 20, 224, 2,
+ 3, 231, 70, 146, 88, 220, 2,
+ 2369, 115, 148, 151, 32, 196, 2,
+ -3, 118, 36, 146, 64, 244, 2
+ },
+
+ /* Region 99 */
+ {
+ 0x8002, 0, 127, 64, 169, 204, 0,
+ -3, 228, 69, 34, 148, 220, 0,
+ -7448, 243, 69, 33, 200, 240, 3,
+ 3, 81, 68, 34, 212, 212, 2,
+ -8526, 65, 68, 33, 196, 240, 3
+ },
+
+ /* Region 100 */
+ {
+ 0x8002, 0, 127, 64, 119, 187, 0,
+ 2786, 228, 22, 146, 176, 192, 0,
+ 3, 102, 68, 146, 196, 236, 2,
+ 3369, 178, 149, 116, 176, 208, 2,
+ -3, 231, 68, 146, 120, 240, 0
+ },
+
+ /* Region 101 */
+ {
+ 0x8002, 0, 127, 240, 144, 239, 0,
+ -2, 49, 69, 34, 236, 208, 2,
+ -9000, 113, 102, 33, 228, 236, 3,
+ 2400, 149, 69, 34, 12, 216, 1,
+ 0, 145, 102, 33, 224, 236, 2
+ },
+
+ /* Region 102 */
+ {
+ 0x8012, 0, 127, 241, 176, 6, 0,
+ 1200, 247, 49, 64, 252, 204, 0,
+ 3804, 246, 101, 32, 0, 232, 2,
+ 1902, 247, 32, 32, 112, 188, 2,
+ 0, 228, 84, 32, 0, 240, 2
+ },
+
+ /* Region 103 */
+ {
+ 0x8005, 0, 127, 64, 101, 221, 0,
+ 1, 194, 68, 97, 196, 200, 2,
+ -10001, 247, 100, 114, 176, 240, 3,
+ 3370, 213, 33, 70, 52, 200, 2,
+ -1, 178, 68, 49, 208, 212, 0
+ },
+
+ /* Region 104 */
+ {
+ 0x8002, 0, 127, 0, 255, 203, 0,
+ -3, 245, 82, 99, 200, 232, 2,
+ 2787, 244, 84, 96, 0, 236, 2,
+ 1198, 133, 81, 100, 196, 220, 2,
+ 1902, 147, 67, 80, 0, 232, 2
+ },
+
+ /* Region 105 */
+ {
+ 0x8005, 0, 127, 0, 255, 140, 0,
+ 500, 255, 137, 179, 0, 200, 3,
+ 1902, 248, 90, 160, 0, 244, 2,
+ 3804, 245, 57, 35, 164, 204, 2,
+ 0, 245, 38, 51, 196, 208, 2
+ },
+
+ /* Region 106 */
+ {
+ 0x8005, 0, 127, 0, 255, 72, 0,
+ 1000, 238, 57, 65, 0, 188, 3,
+ 1902, 247, 103, 112, 0, 244, 2,
+ 2786, 250, 36, 81, 68, 212, 2,
+ 0, 249, 50, 49, 172, 204, 2
+ },
+
+ /* Region 107 */
+ {
+ 0x8005, 0, 127, 16, 119, 72, 0,
+ 1500, 255, 89, 65, 0, 196, 3,
+ 2790, 246, 39, 112, 0, 240, 0,
+ 1905, 246, 36, 81, 168, 208, 0,
+ 0, 249, 114, 49, 172, 212, 0
+ },
+
+ /* Region 108 */
+ {
+ 0x8005, 0, 127, 0, 255, 237, 0,
+ 1902, 254, 89, 65, 0, 212, 2,
+ 0, 248, 87, 112, 0, 240, 2,
+ 3369, 231, 62, 81, 0, 208, 2,
+ 3, 245, 118, 49, 96, 196, 2
+ },
+
+ /* Region 109 */
+ {
+ 0x8002, 0, 127, 16, 188, 205, 0,
+ -2, 179, 47, 50, 244, 224, 2,
+ 1900, 145, 94, 49, 248, 232, 2,
+ 3, 210, 46, 2, 244, 208, 2,
+ 2789, 133, 93, 4, 180, 244, 2
+ },
+
+ /* Region 110 */
+ {
+ 0x8005, 0, 127, 48, 135, 220, 0,
+ 1901, 162, 25, 35, 144, 208, 0,
+ 0, 113, 105, 65, 220, 240, 0,
+ 3369, 233, 88, 51, 120, 212, 0,
+ 0, 229, 24, 84, 200, 208, 0
+ },
+
+ /* Region 111 */
+ {
+ 0x8002, 0, 127, 112, 32, 190, 0,
+ 0, 53, 79, 66, 152, 212, 2,
+ 1200, 53, 75, 64, 136, 244, 2,
+ 500, 149, 60, 66, 16, 208, 2,
+ 1902, 200, 78, 64, 0, 248, 0
+ },
+
+ /* Region 112 */
+ {
+ 0x8005, 0, 127, 0, 144, 130, 0,
+ 2514, 255, 68, 53, 0, 204, 2,
+ 2400, 247, 133, 48, 0, 240, 2,
+ 4151, 243, 67, 50, 0, 212, 2,
+ 3369, 243, 66, 56, 0, 204, 2
+ },
+
+ /* Region 113 */
+ {
+ 0x8005, 0, 127, 0, 255, 0, 0,
+ 514, 253, 79, 51, 0, 196, 3,
+ 1905, 252, 89, 51, 0, 244, 2,
+ 4349, 245, 35, 51, 0, 208, 2,
+ 1205, 247, 34, 51, 0, 208, 2
+ },
+
+ /* Region 114 */
+ {
+ 0x8005, 0, 127, 0, 255, 0, 0,
+ 514, 221, 69, 35, 0, 204, 3,
+ 0, 250, 86, 115, 0, 252, 2,
+ 1884, 244, 116, 51, 0, 200, 2,
+ 1208, 210, 35, 51, 0, 208, 2
+ },
+
+ /* Region 115 */
+ {
+ 0x8005, 0, 127, 0, 255, 16, 0,
+ 514, 222, 85, 163, 0, 192, 3,
+ 0, 254, 108, 163, 0, 252, 2,
+ 3800, 255, 143, 160, 0, 176, 2,
+ 1200, 250, 105, 163, 0, 212, 2
+ },
+
+ /* Region 116 */
+ {
+ 0x8005, 0, 127, 0, 255, 16, 0,
+ 1514, 249, 101, 163, 0, 204, 3,
+ -1200, 249, 87, 160, 0, 252, 2,
+ 0, 235, 143, 160, 0, 204, 2,
+ 1200, 234, 73, 163, 0, 204, 2
+ },
+
+ /* Region 117 */
+ {
+ 0x8005, 0, 127, 0, 255, 16, 0,
+ 500, 239, 101, 160, 0, 204, 3,
+ -1195, 248, 104, 160, 0, 252, 2,
+ 1898, 252, 72, 163, 0, 216, 2,
+ 1239, 248, 87, 163, 0, 196, 2
+ },
+
+ /* Region 118 */
+ {
+ 0x8005, 0, 127, 0, 255, 255, 0,
+ 500, 255, 98, 160, 0, 196, 3,
+ -1, 249, 105, 160, 0, 252, 2,
+ 1907, 250, 71, 160, 0, 252, 2,
+ 1182, 249, 87, 161, 0, 192, 2
+ },
+
+ /* Region 119 */
+ {
+ 0x8005, 0, 127, 0, 0, 100, 0,
+ 600, 32, 15, 0, 252, 224, 6,
+ 0, 47, 111, 65, 0, 244, 2,
+ 1826, 16, 47, 0, 252, 216, 2,
+ 3551, 240, 47, 0, 252, 212, 2
+ },
+
+ /* Region 120 */
+ {
+ 0x8014, 0, 127, 240, 128, 235, 0,
+ 1228, 161, 47, 17, 196, 200, 3,
+ 3000, 123, 75, 17, 0, 240, 2,
+ 7022, 72, 43, 17, 0, 216, 0,
+ 4000, 150, 79, 17, 48, 196, 3
+ },
+
+ /* Region 121 */
+ {
+ 0x8005, 0, 127, 224, 16, 86, 0,
+ 275, 251, 6, 0, 36, 200, 2,
+ 0, 101, 104, 65, 56, 240, 2,
+ 0, 240, 6, 0, 252, 208, 6,
+ 1000, 195, 8, 0, 248, 200, 2
+ },
+
+ /* Region 122 */
+ {
+ 0x8002, 0, 127, 0, 0, 185, 0,
+ 600, 35, 66, 17, 72, 224, 4,
+ -13000, 81, 67, 17, 228, 244, 2,
+ 702, 97, 38, 17, 212, 196, 6,
+ -14000, 81, 65, 17, 224, 244, 3
+ },
+
+ /* Region 123 */
+ {
+ 0x8012, 0, 127, 240, 112, 237, 0,
+ -6528, 153, 127, 16, 0, 252, 3,
+ 1200, 105, 109, 16, 0, 216, 2,
+ -6022, 179, 139, 17, 0, 248, 3,
+ 2000, 104, 79, 17, 0, 240, 0
+ },
+
+ /* Region 124 */
+ {
+ 0x8012, 0, 127, 240, 240, 16, 0,
+ 1914, 240, 64, 160, 240, 208, 2,
+ 1200, 240, 73, 163, 240, 244, 0,
+ 1900, 240, 64, 160, 240, 148, 2,
+ 4151, 240, 73, 163, 240, 244, 0
+ },
+
+ /* Region 125 */
+ {
+ 0x8002, 0, 127, 240, 56, 235, 0,
+ -5522, 97, 32, 17, 196, 240, 3,
+ 0, 84, 75, 17, 180, 248, 3,
+ 702, 65, 38, 17, 224, 212, 6,
+ -4000, 161, 73, 17, 224, 252, 1
+ },
+
+ /* Region 126 */
+ {
+ 0x8015, 0, 127, 240, 248, 37, 0,
+ 1050, 243, 0, 0, 252, 224, 7,
+ 2000, 49, 68, 0, 224, 236, 3,
+ 350, 240, 0, 0, 252, 216, 1,
+ 700, 240, 0, 0, 252, 212, 3
+ },
+
+ /* Region 127 */
+ {
+ 0x8015, 0, 127, 240, 248, 37, 0,
+ 1050, 245, 85, 0, 0, 244, 7,
+ -5000, 247, 71, 0, 0, 252, 3,
+ 350, 240, 0, 0, 0, 164, 0,
+ 700, 32, 0, 0, 0, 252, 2
+ },
+
+ /* Region 128 */
+ {
+ 0x0005, 35, 35, 0, 255, 103, 0,
+ 3, 215, 68, 65, 0, 204, 2,
+ -1700, 249, 95, 177, 0, 252, 2,
+ 5374, 236, 144, 204, 0, 176, 3,
+ 114, 253, 144, 179, 0, 200, 3
+ },
+
+ /* Region 129 */
+ {
+ 0x0005, 36, 36, 0, 255, 103, 0,
+ 3, 219, 68, 65, 0, 204, 2,
+ -1700, 251, 95, 177, 0, 252, 2,
+ 5374, 255, 144, 204, 0, 176, 3,
+ 114, 255, 144, 179, 0, 208, 3
+ },
+
+ /* Region 130 */
+ {
+ 0x001a, 37, 37, 240, 128, 216, 0,
+ 2780, 255, 16, 0, 112, 200, 3,
+ 3800, 255, 32, 0, 0, 240, 3,
+ 2501, 251, 48, 0, 48, 240, 3,
+ 2751, 254, 48, 0, 0, 244, 3
+ },
+
+ /* Region 131 */
+ {
+ 0x000d, 38, 38, 0, 255, 190, 0,
+ -2000, 239, 48, 128, 0, 236, 3,
+ -2400, 254, 92, 128, 0, 252, 2,
+ 3374, 255, 33, 192, 240, 244, 2,
+ 1000, 255, 49, 176, 240, 204, 2
+ },
+
+ /* Region 132 */
+ {
+ 0x001a, 39, 39, 240, 128, 254, -10,
+ 5780, 186, 16, 0, 112, 240, 3,
+ 3800, 254, 32, 0, 0, 248, 3,
+ 5780, 234, 16, 0, 112, 240, 3,
+ 4829, 254, 32, 0, 0, 252, 3
+ },
+
+ /* Region 133 */
+ {
+ 0x000d, 40, 40, 0, 255, 203, 0,
+ 0, 254, 74, 128, 0, 176, 3,
+ -600, 252, 73, 128, 0, 252, 3,
+ 3368, 251, 80, 192, 0, 244, 3,
+ 1200, 254, 64, 176, 0, 208, 3
+ },
+
+ /* Region 134 */
+ {
+ 0x000d, 41, 41, 208, 16, 187, -30,
+ -600, 247, 128, 0, 0, 204, 1,
+ -890, 248, 88, 0, 0, 252, 3,
+ 1068, 250, 182, 0, 0, 200, 3,
+ -100, 249, 116, 0, 0, 208, 3
+ },
+
+ /* Region 135 */
+ {
+ 0x0005, 42, 42, 160, 255, 126, 20,
+ 3514, 247, 23, 72, 0, 212, 3,
+ 400, 255, 94, 177, 0, 232, 2,
+ 2347, 250, 47, 0, 196, 184, 6,
+ 4388, 248, 26, 0, 136, 224, 2
+ },
+
+ /* Region 136 */
+ {
+ 0x000d, 43, 43, 208, 16, 187, -20,
+ -500, 247, 128, 0, 0, 204, 1,
+ -690, 249, 88, 0, 0, 252, 3,
+ 1068, 254, 182, 0, 0, 200, 3,
+ 0, 249, 116, 0, 0, 208, 3
+ },
+
+ /* Region 137 */
+ {
+ 0x0005, 44, 44, 160, 255, 126, 20,
+ 3514, 151, 20, 72, 0, 244, 3,
+ 400, 223, 92, 177, 0, 240, 2,
+ 2347, 134, 34, 0, 176, 208, 6,
+ 4388, 200, 21, 0, 100, 220, 2
+ },
+
+ /* Region 138 */
+ {
+ 0x000d, 45, 45, 208, 16, 187, -10,
+ -350, 246, 128, 0, 0, 204, 1,
+ -590, 249, 88, 0, 0, 252, 3,
+ 2368, 254, 182, 0, 0, 196, 3,
+ 500, 249, 116, 0, 0, 208, 3
+ },
+
+ /* Region 139 */
+ {
+ 0x0005, 46, 46, 160, 255, 126, 20,
+ 3510, 147, 51, 72, 0, 236, 3,
+ 400, 219, 90, 177, 0, 240, 2,
+ 2347, 134, 66, 0, 176, 224, 6,
+ 4388, 200, 84, 0, 100, 212, 2
+ },
+
+ /* Region 140 */
+ {
+ 0x000d, 47, 47, 176, 32, 187, 10,
+ 0, 247, 128, 0, 0, 204, 1,
+ -280, 249, 88, 0, 0, 252, 3,
+ 2968, 255, 182, 0, 0, 200, 3,
+ 700, 250, 116, 0, 0, 204, 3
+ },
+
+ /* Region 141 */
+ {
+ 0x000d, 48, 48, 0, 255, 187, 20,
+ 10, 247, 128, 0, 0, 204, 3,
+ -130, 249, 88, 0, 0, 252, 3,
+ 3068, 255, 182, 0, 0, 188, 3,
+ 800, 250, 116, 0, 0, 204, 3
+ },
+
+ /* Region 142 */
+ {
+ 0x000d, 49, 49, 160, 255, 215, 20,
+ 3986, 18, 6, 8, 0, 252, 2,
+ 0, 247, 70, 1, 0, 240, 2,
+ 5354, 242, 48, 0, 252, 216, 2,
+ 3868, 193, 48, 0, 212, 208, 2
+ },
+
+ /* Region 143 */
+ {
+ 0x000d, 50, 50, 0, 255, 201, 30,
+ 200, 247, 128, 0, 0, 208, 3,
+ 20, 249, 88, 0, 0, 252, 3,
+ 3368, 255, 182, 0, 0, 200, 3,
+ 1100, 250, 116, 0, 0, 204, 3
+ },
+
+ /* Region 144 */
+ {
+ 0x000d, 51, 51, 160, 255, 97, -20,
+ 3831, 240, 39, 0, 232, 224, 3,
+ 1258, 246, 102, 0, 0, 232, 3,
+ 4323, 242, 32, 0, 0, 216, 3,
+ 868, 243, 64, 0, 0, 204, 3
+ },
+
+ /* Region 145 */
+ {
+ 0x000d, 52, 52, 112, 128, 234, -20,
+ 725, 228, 32, 0, 0, 208, 1,
+ 400, 248, 86, 0, 0, 248, 3,
+ 2003, 53, 32, 0, 0, 236, 3,
+ 100, 209, 32, 0, 0, 212, 1
+ },
+
+ /* Region 146 */
+ {
+ 0x000d, 53, 53, 160, 255, 97, -20,
+ 3831, 240, 39, 0, 232, 224, 3,
+ 1258, 246, 102, 0, 0, 232, 3,
+ 4323, 242, 32, 0, 0, 224, 3,
+ 868, 243, 64, 0, 0, 196, 3
+ },
+
+ /* Region 147 */
+ {
+ 0x001d, 54, 54, 240, 240, 242, 10,
+ -1, 245, 71, 1, 24, 236, 0,
+ 1200, 218, 102, 1, 0, 236, 2,
+ 1354, 255, 48, 0, 0, 208, 2,
+ 5868, 209, 48, 0, 160, 212, 0
+ },
+
+ /* Region 148 */
+ {
+ 0x000d, 55, 55, 48, 32, 234, -10,
+ 725, 228, 32, 0, 0, 208, 3,
+ 900, 249, 86, 0, 0, 240, 3,
+ 2303, 69, 32, 0, 0, 236, 1,
+ 400, 177, 32, 0, 0, 212, 3
+ },
+
+ /* Region 149 */
+ {
+ 0x000d, 56, 56, 0, 255, 149, 20,
+ 414, 254, 123, 48, 0, 204, 3,
+ 1986, 252, 118, 48, 0, 244, 3,
+ 4383, 242, 67, 48, 0, 200, 3,
+ 4205, 243, 81, 48, 0, 204, 3
+ },
+
+ /* Region 150 */
+ {
+ 0x000d, 57, 57, 48, 32, 234, -20,
+ 526, 210, 32, 0, 0, 200, 3,
+ 719, 246, 86, 0, 0, 240, 3,
+ 1303, 48, 32, 0, 0, 236, 1,
+ 202, 98, 32, 0, 0, 212, 3
+ },
+
+ /* Region 151 */
+ {
+ 0x001d, 58, 58, 240, 240, 204, -40,
+ 5650, 247, 16, 0, 84, 220, 1,
+ 3800, 248, 32, 0, 0, 248, 3,
+ 1780, 252, 16, 0, 0, 152, 3,
+ 6825, 245, 32, 0, 0, 208, 1
+ },
+
+ /* Region 152 */
+ {
+ 0x000d, 59, 59, 144, 0, 108, -20,
+ 3531, 240, 103, 0, 232, 220, 3,
+ 1058, 246, 102, 0, 0, 232, 3,
+ 5331, 242, 64, 0, 0, 220, 3,
+ 1968, 243, 64, 0, 0, 204, 1
+ },
+
+ /* Region 153 */
+ {
+ 0x000d, 60, 60, 192, 64, 155, 40,
+ 700, 214, 84, 0, 0, 208, 1,
+ 950, 253, 76, 0, 0, 248, 3,
+ 2803, 255, 127, 0, 0, 200, 3,
+ 750, 255, 89, 0, 0, 204, 3
+ },
+
+ /* Region 154 */
+ {
+ 0x000d, 61, 61, 224, 48, 91, 40,
+ 400, 229, 68, 0, 0, 204, 1,
+ 700, 251, 76, 0, 0, 248, 3,
+ 1803, 255, 95, 0, 0, 196, 3,
+ 450, 255, 89, 0, 0, 208, 3
+ },
+
+ /* Region 155 */
+ {
+ 0x000d, 62, 62, 240, 32, 191, 25,
+ 214, 237, 69, 0, 0, 204, 1,
+ 400, 252, 78, 0, 0, 248, 3,
+ 2830, 255, 95, 0, 0, 208, 3,
+ 2500, 255, 25, 0, 0, 192, 3
+ },
+
+ /* Region 156 */
+ {
+ 0x000d, 63, 63, 240, 32, 91, 25,
+ 400, 229, 68, 0, 0, 188, 1,
+ -100, 250, 76, 0, 0, 248, 3,
+ 1803, 254, 95, 0, 0, 200, 3,
+ 450, 238, 89, 0, 0, 200, 3
+ },
+
+ /* Region 157 */
+ {
+ 0x000d, 64, 64, 240, 16, 91, 20,
+ 300, 210, 68, 0, 0, 196, 1,
+ -400, 250, 76, 0, 0, 248, 3,
+ 1803, 254, 95, 0, 0, 200, 3,
+ 550, 238, 89, 0, 0, 200, 3
+ },
+
+ /* Region 158 */
+ {
+ 0x001c, 65, 65, 240, 128, 223, 20,
+ 1780, 234, 16, 0, 112, 208, 3,
+ 800, 251, 32, 0, 0, 248, 3,
+ 5501, 231, 48, 0, 48, 200, 3,
+ 2751, 232, 48, 0, 0, 220, 3
+ },
+
+ /* Region 159 */
+ {
+ 0x001c, 66, 66, 240, 128, 223, 20,
+ 1580, 234, 16, 0, 112, 208, 3,
+ 600, 250, 32, 0, 0, 248, 3,
+ 5201, 231, 48, 0, 48, 200, 3,
+ 2510, 232, 48, 0, 0, 220, 3
+ },
+
+ /* Region 160 */
+ {
+ 0x000d, 67, 67, 0, 255, 0, -35,
+ 1514, 255, 63, 51, 0, 184, 3,
+ 4830, 251, 73, 51, 0, 252, 3,
+ 4349, 245, 67, 51, 0, 212, 3,
+ 5267, 246, 65, 51, 0, 200, 3
+ },
+
+ /* Region 161 */
+ {
+ 0x000d, 68, 68, 0, 255, 0, -35,
+ 1514, 255, 63, 51, 0, 196, 3,
+ 4905, 251, 73, 51, 0, 252, 3,
+ 4349, 245, 67, 51, 0, 196, 3,
+ 5214, 246, 65, 51, 0, 208, 3
+ },
+
+ /* Region 162 */
+ {
+ 0x000a, 69, 69, 240, 240, 243, -35,
+ 10000, 160, 68, 0, 0, 200, 3,
+ 7000, 156, 140, 0, 0, 228, 3,
+ 1586, 176, 16, 0, 0, 228, 7,
+ 8000, 140, 80, 0, 0, 236, 3
+ },
+
+ /* Region 163 */
+ {
+ 0x001a, 70, 70, 240, 240, 227, -38,
+ 500, 240, 52, 0, 0, 220, 1,
+ 8000, 188, 124, 0, 0, 228, 3,
+ 1586, 240, 16, 0, 0, 224, 7,
+ 8000, 203, 80, 0, 0, 228, 3
+ },
+
+ /* Region 164 */
+ {
+ 0x0004, 71, 71, 226, 240, 181, 35,
+ 7253, 224, 32, 48, 0, 184, 3,
+ 3594, 224, 79, 48, 0, 248, 1,
+ 220, 97, 19, 48, 156, 152, 3,
+ 5243, 172, 16, 48, 92, 204, 1
+ },
+
+ /* Region 165 */
+ {
+ 0x0004, 72, 72, 240, 241, 181, 35,
+ 6253, 134, 32, 48, 0, 184, 3,
+ 3994, 176, 76, 48, 160, 248, 1,
+ 22, 183, 19, 48, 156, 172, 3,
+ 1243, 160, 16, 48, 240, 188, 3
+ },
+
+ /* Region 166 */
+ {
+ 0x001a, 73, 73, 240, 224, 155, 30,
+ -2145, 240, 70, 0, 0, 252, 3,
+ 600, 109, 111, 0, 0, 240, 3,
+ -1800, 240, 71, 0, 0, 248, 3,
+ 200, 173, 111, 0, 0, 240, 3
+ },
+
+ /* Region 167 */
+ {
+ 0x0012, 74, 74, 240, 224, 119, 30,
+ -2545, 240, 70, 0, 252, 252, 3,
+ 0, 153, 111, 0, 0, 240, 3,
+ -2400, 240, 71, 0, 252, 252, 3,
+ 100, 137, 111, 0, 0, 240, 3
+ },
+
+ /* Region 168 */
+ {
+ 0x001a, 75, 75, 240, 128, 240, 20,
+ 3780, 255, 16, 0, 252, 188, 2,
+ 800, 255, 64, 0, 0, 248, 2,
+ 2501, 255, 48, 0, 252, 208, 0,
+ 751, 255, 48, 0, 0, 236, 2
+ },
+
+ /* Region 169 */
+ {
+ 0x000d, 76, 76, 0, 255, 68, 35,
+ 1100, 239, 69, 0, 0, 184, 3,
+ 2600, 255, 76, 0, 0, 252, 3,
+ 5000, 255, 111, 0, 0, 204, 3,
+ 3400, 254, 73, 0, 0, 184, 3
+ },
+
+ /* Region 170 */
+ {
+ 0x000d, 77, 77, 0, 255, 68, 35,
+ 914, 239, 69, 0, 0, 180, 3,
+ 1801, 254, 76, 0, 0, 252, 3,
+ 4800, 255, 111, 0, 0, 192, 3,
+ 3200, 254, 73, 0, 0, 192, 3
+ },
+
+ /* Region 171 */
+ {
+ 0x000d, 78, 78, 240, 32, 197, -20,
+ 1200, 216, 86, 0, 0, 180, 1,
+ 1800, 189, 127, 0, 0, 244, 3,
+ 2700, 156, 102, 0, 0, 196, 1,
+ 700, 109, 104, 0, 0, 196, 1
+ },
+
+ /* Region 172 */
+ {
+ 0x000d, 79, 79, 240, 32, 197, -20,
+ 1200, 216, 86, 0, 0, 196, 1,
+ 2200, 171, 127, 0, 0, 244, 3,
+ 2700, 145, 102, 0, 0, 192, 1,
+ 700, 106, 104, 0, 0, 192, 1
+ },
+
+ /* Region 173 */
+ {
+ 0x000d, 80, 80, 0, 255, 0, -40,
+ 3514, 254, 79, 51, 0, 196, 3,
+ 5905, 252, 73, 51, 0, 248, 3,
+ 6348, 245, 35, 51, 0, 176, 3,
+ 2203, 244, 33, 51, 0, 216, 3
+ },
+
+ /* Region 174 */
+ {
+ 0x800d, 81, 81, 0, 255, 0, -40,
+ 3514, 255, 79, 51, 0, 192, 3,
+ 5905, 246, 73, 51, 0, 252, 3,
+ 6348, 241, 35, 51, 0, 180, 3,
+ 2203, 242, 33, 51, 0, 212, 3
+ }
+};
+
+
+/*----------------------------------------------------------------------------
+ * Programs
+ *----------------------------------------------------------------------------
+*/
+const S_PROGRAM programs[] =
+{
+ { 7864320, 128 } /* program 0 */
+}; /* end Programs */
+
+/*----------------------------------------------------------------------------
+ * Banks
+ *----------------------------------------------------------------------------
+*/
+const S_BANK banks[] =
+{
+ { /* bank 0 */
+ 30976,
+ {
+ 0, 1, 2, 3, 4, 5, 6, 7,
+ 8, 9, 10, 11, 12, 13, 14, 15,
+ 16, 17, 18, 19, 20, 21, 22, 23,
+ 24, 25, 26, 27, 28, 29, 30, 31,
+ 32, 33, 34, 35, 36, 37, 38, 39,
+ 40, 41, 42, 43, 44, 45, 46, 47,
+ 48, 49, 50, 51, 52, 53, 54, 55,
+ 56, 57, 58, 59, 60, 61, 62, 63,
+ 64, 65, 66, 67, 68, 69, 70, 71,
+ 72, 73, 74, 75, 76, 77, 78, 79,
+ 80, 81, 82, 83, 84, 85, 86, 87,
+ 88, 89, 90, 91, 92, 93, 94, 95,
+ 96, 97, 98, 99, 100, 101, 102, 103,
+ 104, 105, 106, 107, 108, 109, 110, 111,
+ 112, 113, 114, 115, 116, 117, 118, 119,
+ 120, 121, 122, 123, 124, 125, 126, 127
+ }
+ }
+}; /* end Banks */
+
+/*----------------------------------------------------------------------------
+ * S_EAS
+ *----------------------------------------------------------------------------
+*/
+const S_EAS easSoundLib =
+{
+ 0x01534145,
+ 0x00105622,
+
+ banks,
+ programs,
+
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+
+ regions,
+
+ 1,
+ 1,
+
+ 0,
+ 0,
+ 0,
+
+ 175
+}; /* end S_EAS */
+/* end sound library */
diff --git a/arm-fm-22k/lib_src/eas_fmsynth.c b/arm-fm-22k/lib_src/eas_fmsynth.c
index 83f0087..629506a 100644
--- a/arm-fm-22k/lib_src/eas_fmsynth.c
+++ b/arm-fm-22k/lib_src/eas_fmsynth.c
@@ -1,12 +1,12 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * fmsynth.c
- *
- * Contents and purpose:
- * Implements the high-level FM synthesizer functions.
- *
- * Copyright Sonic Network Inc. 2004
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * fmsynth.c
+ *
+ * Contents and purpose:
+ * Implements the high-level FM synthesizer functions.
+ *
+ * Copyright Sonic Network Inc. 2004
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,892 +19,892 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 795 $
- * $Date: 2007-08-01 00:14:45 -0700 (Wed, 01 Aug 2007) $
- *----------------------------------------------------------------------------
-*/
-
-// includes
-#include "eas_host.h"
-#include "eas_report.h"
-
-#include "eas_data.h"
-#include "eas_synth_protos.h"
-#include "eas_audioconst.h"
-#include "eas_fmengine.h"
-#include "eas_math.h"
-
-/* option sanity check */
-#ifdef _REVERB
-#error "No reverb for FM synthesizer"
-#endif
-#ifdef _CHORUS
-#error "No chorus for FM synthesizer"
-#endif
-
-/*
- * WARNING: These macros can cause unwanted side effects. Use them
- * with care. For example, min(x++,y++) will cause either x or y to be
- * incremented twice.
- */
-#define min(a,b) ((a) < (b) ? (a) : (b))
-#define max(a,b) ((a) > (b) ? (a) : (b))
-
-/* pivot point for keyboard scalars */
-#define EG_SCALE_PIVOT_POINT 64
-#define KEY_SCALE_PIVOT_POINT 36
-
-/* This number is the negative of the frequency of the note (in cents) of
- * the sine wave played at unity. The number can be calculated as follows:
- *
- * MAGIC_NUMBER = 1200 * log(base2) (SINE_TABLE_SIZE * 8.175798916 / SAMPLE_RATE)
- *
- * 8.17578 is a reference to the frequency of MIDI note 0
- */
-#if defined (_SAMPLE_RATE_8000)
-#define MAGIC_NUMBER 1279
-#elif defined (_SAMPLE_RATE_16000)
-#define MAGIC_NUMBER 79
-#elif defined (_SAMPLE_RATE_20000)
-#define MAGIC_NUMBER -308
-#elif defined (_SAMPLE_RATE_22050)
-#define MAGIC_NUMBER -477
-#elif defined (_SAMPLE_RATE_24000)
-#define MAGIC_NUMBER -623
-#elif defined (_SAMPLE_RATE_32000)
-#define MAGIC_NUMBER -1121
-#elif defined (_SAMPLE_RATE_44100)
-#define MAGIC_NUMBER -1677
-#elif defined (_SAMPLE_RATE_48000)
-#define MAGIC_NUMBER -1823
-#endif
-
-/* externs */
-extern const EAS_I16 fmControlTable[128];
-extern const EAS_U16 fmRateTable[256];
-extern const EAS_U16 fmAttackTable[16];
-extern const EAS_U8 fmDecayTable[16];
-extern const EAS_U8 fmReleaseTable[16];
-extern const EAS_U8 fmScaleTable[16];
-
-/* local prototypes */
-/*lint -esym(715, pVoiceMgr) standard synthesizer interface - pVoiceMgr not used */
-static EAS_RESULT FM_Initialize (S_VOICE_MGR *pVoiceMgr) { return EAS_SUCCESS; }
-static EAS_RESULT FM_StartVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, EAS_I32 voiceNum, EAS_U16 regionIndex);
-static EAS_BOOL FM_UpdateVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, EAS_I32 voiceNum, EAS_I32 *pMixBuffer, EAS_I32 numSamples);
-static void FM_ReleaseVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, EAS_I32 voiceNum);
-static void FM_MuteVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, EAS_I32 voiceNum);
-static void FM_SustainPedal (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, S_SYNTH_CHANNEL *pChannel, EAS_I32 voiceNum);
-static void FM_UpdateChannel (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel);
-
-
-/*----------------------------------------------------------------------------
- * Synthesizer interface
- *----------------------------------------------------------------------------
-*/
-const S_SYNTH_INTERFACE fmSynth =
-{
- FM_Initialize,
- FM_StartVoice,
- FM_UpdateVoice,
- FM_ReleaseVoice,
- FM_MuteVoice,
- FM_SustainPedal,
- FM_UpdateChannel
-};
-
-#ifdef FM_OFFBOARD
-const S_FRAME_INTERFACE fmFrameInterface =
-{
- FM_StartFrame,
- FM_EndFrame
-};
-#endif
-
-/*----------------------------------------------------------------------------
- * inline functions
- *----------------------------------------------------------------------------
- */
-EAS_INLINE S_FM_VOICE *GetFMVoicePtr (S_VOICE_MGR *pVoiceMgr, EAS_INT voiceNum)
-{
- return &pVoiceMgr->fmVoices[voiceNum];
-}
-EAS_INLINE S_SYNTH_CHANNEL *GetChannelPtr (S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice)
-{
- return &pSynth->channels[pVoice->channel & 15];
-}
-EAS_INLINE const S_FM_REGION *GetFMRegionPtr (S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice)
-{
-#ifdef _SECONDARY_SYNTH
- return &pSynth->pEAS->pFMRegions[pVoice->regionIndex & REGION_INDEX_MASK];
-#else
- return &pSynth->pEAS->pFMRegions[pVoice->regionIndex];
-#endif
-}
-
-/*----------------------------------------------------------------------------
- * FM_SynthIsOutputOperator
- *----------------------------------------------------------------------------
- * Purpose:
- * Returns true if the operator is a direct output and not muted
- *
- * Inputs:
- *
- * Outputs:
- * Returns boolean
- *----------------------------------------------------------------------------
-*/
-static EAS_BOOL FM_SynthIsOutputOperator (const S_FM_REGION *pRegion, EAS_INT operIndex)
-{
-
- /* see if voice is muted */
- if ((pRegion->oper[operIndex].gain & 0xfc) == 0)
- return 0;
-
- /* check based on mode */
- switch (pRegion->region.keyGroupAndFlags & 7)
- {
-
- /* mode 0 - all operators are external */
- case 0:
- return EAS_TRUE;
-
- /* mode 1 - operators 1-3 are external */
- case 1:
- if (operIndex != 0)
- return EAS_TRUE;
- break;
-
- /* mode 2 - operators 1 & 3 are external */
- case 2:
- if ((operIndex == 1) || (operIndex == 3))
- return EAS_TRUE;
- break;
-
- /* mode 2 - operators 1 & 2 are external */
- case 3:
- if ((operIndex == 1) || (operIndex == 2))
- return EAS_TRUE;
- break;
-
- /* modes 4 & 5 - operator 1 is external */
- case 4:
- case 5:
- if (operIndex == 1)
- return EAS_TRUE;
- break;
-
- default:
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_FATAL,"Invalid voice mode: %d",
- pRegion->region.keyGroupAndFlags & 7); */ }
- }
-
- return EAS_FALSE;
-}
-
-/*----------------------------------------------------------------------------
- * FM_CalcEGRate()
- *----------------------------------------------------------------------------
- * Purpose:
- *
- * Inputs:
- * nKeyNumber - MIDI note
- * nLogRate - logarithmic scale rate from patch data
- * nKeyScale - key scaling factor for this EG
- *
- * Outputs:
- * 16-bit linear multiplier
- *----------------------------------------------------------------------------
-*/
-
-static EAS_U16 FM_CalcEGRate (EAS_U8 nKeyNumber, EAS_U8 nLogRate, EAS_U8 nEGScale)
-{
- EAS_I32 temp;
-
- /* incorporate key scaling on release rate */
- temp = (EAS_I32) nLogRate << 7;
- temp += ((EAS_I32) nKeyNumber - EG_SCALE_PIVOT_POINT) * (EAS_I32) nEGScale;
-
- /* saturate */
- temp = max(temp, 0);
- temp = min(temp, 32767);
-
- /* look up in rate table */
- /*lint -e{704} use shift for performance */
- return fmRateTable[temp >> 8];
-}
-
-/*----------------------------------------------------------------------------
- * FM_ReleaseVoice()
- *----------------------------------------------------------------------------
- * Purpose:
- * The selected voice is being released.
- *
- * Inputs:
- * psEASData - pointer to S_EAS_DATA
- * pVoice - pointer to voice to release
- *
- * Outputs:
- * None
- *----------------------------------------------------------------------------
-*/
-static void FM_ReleaseVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, EAS_I32 voiceNum)
-{
- EAS_INT operIndex;
- const S_FM_REGION *pRegion;
- S_FM_VOICE *pFMVoice;
-
- /* check to see if voice responds to NOTE-OFF's */
- pRegion = GetFMRegionPtr(pSynth, pVoice);
- if (pRegion->region.keyGroupAndFlags & REGION_FLAG_ONE_SHOT)
- return;
-
- /* set all envelopes to release state */
- pFMVoice = GetFMVoicePtr(pVoiceMgr, voiceNum);
- for (operIndex = 0; operIndex < 4; operIndex++)
- {
- pFMVoice->oper[operIndex].envState = eFMEnvelopeStateRelease;
-
- /* incorporate key scaling on release rate */
- pFMVoice->oper[operIndex].envRate = FM_CalcEGRate(
- pVoice->note,
- fmReleaseTable[pRegion->oper[operIndex].velocityRelease & 0x0f],
- fmScaleTable[pRegion->oper[operIndex].egKeyScale >> 4]);
- } /* end for (operIndex = 0; operIndex < 4; operIndex++) */
-}
-
-/*----------------------------------------------------------------------------
- * FM_MuteVoice()
- *----------------------------------------------------------------------------
- * Purpose:
- * The selected voice is being muted.
- *
- * Inputs:
- * pVoice - pointer to voice to release
- *
- * Outputs:
- * None
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, pSynth) standard interface, pVoiceMgr not used */
-static void FM_MuteVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, EAS_I32 voiceNum)
-{
- S_FM_VOICE *pFMVoice;
-
- /* clear deferred action flags */
- pVoice->voiceFlags &=
- ~(VOICE_FLAG_DEFER_MIDI_NOTE_OFF |
- VOICE_FLAG_SUSTAIN_PEDAL_DEFER_NOTE_OFF |
- VOICE_FLAG_DEFER_MUTE);
-
- /* set all envelopes to muted state */
- pFMVoice = GetFMVoicePtr(pVoiceMgr, voiceNum);
- pFMVoice->oper[0].envState = eFMEnvelopeStateMuted;
- pFMVoice->oper[1].envState = eFMEnvelopeStateMuted;
- pFMVoice->oper[2].envState = eFMEnvelopeStateMuted;
- pFMVoice->oper[3].envState = eFMEnvelopeStateMuted;
-}
-
-/*----------------------------------------------------------------------------
- * FM_SustainPedal()
- *----------------------------------------------------------------------------
- * Purpose:
- * The selected voice is held due to sustain pedal
- *
- * Inputs:
- * pVoice - pointer to voice to sustain
- *
- * Outputs:
- * None
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, pChannel) standard interface, pVoiceMgr not used */
-static void FM_SustainPedal (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, S_SYNTH_CHANNEL *pChannel, EAS_I32 voiceNum)
-{
- const S_FM_REGION *pRegion;
- S_FM_VOICE *pFMVoice;
- EAS_INT operIndex;
-
- pRegion = GetFMRegionPtr(pSynth, pVoice);
- pFMVoice = GetFMVoicePtr(pVoiceMgr, voiceNum);
-
- /* check to see if any envelopes are above the sustain level */
- for (operIndex = 0; operIndex < 4; operIndex++)
- {
-
- /* if level control or envelope gain is zero, skip this envelope */
- if (((pRegion->oper[operIndex].gain & 0xfc) == 0) ||
- (pFMVoice->oper[operIndex].envGain == 0))
- {
- continue;
- }
-
- /* if the envelope gain is above the sustain level, we need to catch this voice */
- if (pFMVoice->oper[operIndex].envGain >= ((EAS_U16) (pRegion->oper[operIndex].sustain & 0xfc) << 7))
- {
-
- /* reset envelope to decay state */
- pFMVoice->oper[operIndex].envState = eFMEnvelopeStateDecay;
-
- pFMVoice->oper[operIndex].envRate = FM_CalcEGRate(
- pVoice->note,
- fmDecayTable[pRegion->oper[operIndex].attackDecay & 0x0f],
- fmScaleTable[pRegion->oper[operIndex].egKeyScale >> 4]);
-
- /* set voice to decay state */
- pVoice->voiceState = eVoiceStatePlay;
-
- /* set sustain flag */
- pVoice->voiceFlags |= VOICE_FLAG_SUSTAIN_PEDAL_DEFER_NOTE_OFF;
- }
- } /* end for (operIndex = 0; operIndex < 4; operIndex++) */
-}
-
-/*----------------------------------------------------------------------------
- * FM_StartVoice()
- *----------------------------------------------------------------------------
- * Purpose:
- * Assign the region for the given instrument using the midi key number
- * and the RPN2 (coarse tuning) value. By using RPN2 as part of the
- * region selection process, we reduce the amount a given sample has
- * to be transposed by selecting the closest recorded root instead.
- *
- * This routine is the second half of SynthAssignRegion().
- * If the region was successfully found by SynthFindRegionIndex(),
- * then assign the region's parameters to the voice.
- *
- * Setup and initialize the following voice parameters:
- * m_nRegionIndex
- *
- * Inputs:
- * pVoice - ptr to the voice we have assigned for this channel
- * nRegionIndex - index of the region
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- * success - could find and assign the region for this voice's note otherwise
- * failure - could not find nor assign the region for this voice's note
- *
- * Side Effects:
- * psSynthObject->m_sVoice[].m_nRegionIndex is assigned
- * psSynthObject->m_sVoice[] parameters are assigned
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT FM_StartVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, EAS_I32 voiceNum, EAS_U16 regionIndex)
-{
- S_FM_VOICE *pFMVoice;
- S_SYNTH_CHANNEL *pChannel;
- const S_FM_REGION *pRegion;
- EAS_I32 temp;
- EAS_INT operIndex;
-
- /* establish pointers to data */
- pVoice->regionIndex = regionIndex;
- pFMVoice = GetFMVoicePtr(pVoiceMgr, voiceNum);
- pChannel = GetChannelPtr(pSynth, pVoice);
- pRegion = GetFMRegionPtr(pSynth, pVoice);
-
- /* update static channel parameters */
- if (pChannel->channelFlags & CHANNEL_FLAG_UPDATE_CHANNEL_PARAMETERS)
- FM_UpdateChannel(pVoiceMgr, pSynth, pVoice->channel & 15);
-
- /* init the LFO */
- pFMVoice->lfoValue = 0;
- pFMVoice->lfoPhase = 0;
- pFMVoice->lfoDelay = (EAS_U16) (fmScaleTable[pRegion->lfoFreqDelay & 0x0f] >> 1);
-
-#if (NUM_OUTPUT_CHANNELS == 2)
- /* calculate pan gain values only if stereo output */
- /* set up panning only at note start */
- temp = (EAS_I32) pChannel->pan - 64;
- temp += (EAS_I32) pRegion->pan;
- if (temp < -64)
- temp = -64;
- if (temp > 64)
- temp = 64;
- pFMVoice->pan = (EAS_I8) temp;
-#endif /* #if (NUM_OUTPUT_CHANNELS == 2) */
-
- /* no samples have been synthesized for this note yet */
- pVoice->voiceFlags = VOICE_FLAG_NO_SAMPLES_SYNTHESIZED_YET;
-
- /* initialize gain value for anti-zipper filter */
- pFMVoice->voiceGain = (EAS_I16) EAS_LogToLinear16(pChannel->staticGain);
- pFMVoice->voiceGain = (EAS_I16) FMUL_15x15(pFMVoice->voiceGain, pSynth->masterVolume);
-
- /* initialize the operators */
- for (operIndex = 0; operIndex < 4; operIndex++)
- {
-
- /* establish operator output gain level */
- /*lint -e{701} <use shift for performance> */
- pFMVoice->oper[operIndex].outputGain = EAS_LogToLinear16(((EAS_I16) (pRegion->oper[operIndex].gain & 0xfc) - 0xfc) << 7);
-
- /* check for linear velocity flag */
- /*lint -e{703} <use shift for performance> */
- if (pRegion->oper[operIndex].flags & FM_OPER_FLAG_LINEAR_VELOCITY)
- temp = (EAS_I32) (pVoice->velocity - 127) << 5;
- else
- temp = (EAS_I32) fmControlTable[pVoice->velocity];
-
- /* scale velocity */
- /*lint -e{704} use shift for performance */
- temp = (temp * (EAS_I32)(pRegion->oper[operIndex].velocityRelease & 0xf0)) >> 7;
-
- /* include key scalar */
- temp -= ((EAS_I32) pVoice->note - KEY_SCALE_PIVOT_POINT) * (EAS_I32) fmScaleTable[pRegion->oper[operIndex].egKeyScale & 0x0f];
-
- /* saturate */
- temp = min(temp, 0);
- temp = max(temp, -32768);
-
- /* save static gain parameters */
- pFMVoice->oper[operIndex].baseGain = (EAS_I16) EAS_LogToLinear16(temp);
-
- /* incorporate key scaling on decay rate */
- pFMVoice->oper[operIndex].envRate = FM_CalcEGRate(
- pVoice->note,
- fmDecayTable[pRegion->oper[operIndex].attackDecay & 0x0f],
- fmScaleTable[pRegion->oper[operIndex].egKeyScale >> 4]);
-
- /* if zero attack time, max out envelope and jump to decay state */
- if ((pRegion->oper[operIndex].attackDecay & 0xf0) == 0xf0)
- {
-
- /* start out envelope at max */
- pFMVoice->oper[operIndex].envGain = 0x7fff;
-
- /* set envelope to decay state */
- pFMVoice->oper[operIndex].envState = eFMEnvelopeStateDecay;
- }
-
- /* start envelope at zero and start in attack state */
- else
- {
- pFMVoice->oper[operIndex].envGain = 0;
- pFMVoice->oper[operIndex].envState = eFMEnvelopeStateAttack;
- }
- }
-
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * FM_UpdateChannel()
- *----------------------------------------------------------------------------
- * Purpose:
- * Calculate and assign static channel parameters
- * These values only need to be updated if one of the controller values
- * for this channel changes.
- * Called when CHANNEL_FLAG_UPDATE_CHANNEL_PARAMETERS flag is set.
- *
- * Inputs:
- * nChannel - channel to update
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- *
- * Side Effects:
- * - the given channel's static gain and static pitch are updated
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, pVoiceMgr) standard interface, pVoiceMgr not used */
-static void FM_UpdateChannel (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel)
-{
- S_SYNTH_CHANNEL *pChannel;
- EAS_I32 temp;
-
- pChannel = &pSynth->channels[channel];
-
- /* convert CC7 volume controller to log scale */
- temp = fmControlTable[pChannel->volume];
-
- /* incorporate CC11 expression controller */
- temp += fmControlTable[pChannel->expression];
-
- /* saturate */
- pChannel->staticGain = (EAS_I16) max(temp,-32768);
-
- /* calculate pitch bend */
- /*lint -e{703} <avoid multiply for performance>*/
- temp = (((EAS_I32)(pChannel->pitchBend) << 2) - 32768);
-
- temp = FMUL_15x15(temp, pChannel->pitchBendSensitivity);
-
- /* include "magic number" compensation for sample rate and lookup table size */
- temp += MAGIC_NUMBER;
-
- /* if this is not a drum channel, then add in the per-channel tuning */
- if (!(pChannel->channelFlags & CHANNEL_FLAG_RHYTHM_CHANNEL))
- temp += (pChannel->finePitch + (pChannel->coarsePitch * 100));
-
- /* save static pitch */
- pChannel->staticPitch = temp;
-
- /* Calculate LFO modulation depth */
- /* mod wheel to LFO depth */
- temp = FMUL_15x15(DEFAULT_LFO_MOD_WHEEL_TO_PITCH_CENTS,
- pChannel->modWheel << (NUM_EG1_FRAC_BITS -7));
-
- /* channel pressure to LFO depth */
- pChannel->lfoAmt = (EAS_I16) (temp +
- FMUL_15x15(DEFAULT_LFO_CHANNEL_PRESSURE_TO_PITCH_CENTS,
- pChannel->channelPressure << (NUM_EG1_FRAC_BITS -7)));
-
- /* clear update flag */
- pChannel->channelFlags &= ~CHANNEL_FLAG_UPDATE_CHANNEL_PARAMETERS;
- return;
-}
-
-/*----------------------------------------------------------------------------
- * FM_UpdateLFO()
- *----------------------------------------------------------------------------
- * Purpose:
- * Calculate the LFO for the given voice
- *
- * Inputs:
- * pVoice - ptr to the voice whose LFO we want to update
- * psEASData - pointer to overall EAS data structure - used for debug only
- *
- * Outputs:
- *
- * Side Effects:
- * - updates LFO values for the given voice
- *----------------------------------------------------------------------------
-*/
-static void FM_UpdateLFO (S_FM_VOICE *pFMVoice, const S_FM_REGION *pRegion)
-{
-
- /* increment the LFO phase if the delay time has elapsed */
- if (!pFMVoice->lfoDelay)
- {
- /*lint -e{701} <use shift for performance> */
- pFMVoice->lfoPhase = pFMVoice->lfoPhase + (EAS_U16) (-fmControlTable[((15 - (pRegion->lfoFreqDelay >> 4)) << 3) + 4]);
-
- /* square wave LFO? */
- if (pRegion->region.keyGroupAndFlags & REGION_FLAG_SQUARE_WAVE)
- pFMVoice->lfoValue = (EAS_I16)(pFMVoice->lfoPhase & 0x8000 ? -32767 : 32767);
-
- /* trick to get a triangle wave out of a sawtooth */
- else
- {
- pFMVoice->lfoValue = (EAS_I16) (pFMVoice->lfoPhase << 1);
- /*lint -e{502} <shortcut to turn sawtooth into sine wave> */
- if ((pFMVoice->lfoPhase > 0x3fff) && (pFMVoice->lfoPhase < 0xC000))
- pFMVoice->lfoValue = ~pFMVoice->lfoValue;
- }
- }
-
- /* still in delay */
- else
- pFMVoice->lfoDelay--;
-
- return;
-}
-
-/*----------------------------------------------------------------------------
- * FM_UpdateEG()
- *----------------------------------------------------------------------------
- * Purpose:
- * Calculate the synthesis parameters for an operator to be used during
- * the next buffer
- *
- * Inputs:
- * pVoice - pointer to the voice being updated
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_BOOL FM_UpdateEG (S_SYNTH_VOICE *pVoice, S_OPERATOR *pOper, const S_FM_OPER *pOperData, EAS_BOOL oneShot)
-{
- EAS_U32 temp;
- EAS_BOOL done;
-
- /* set flag assuming the envelope is not done */
- done = EAS_FALSE;
-
- /* take appropriate action based on state */
- switch (pOper->envState)
- {
-
- case eFMEnvelopeStateAttack:
-
- /* the envelope is linear during the attack, so add the value */
- temp = pOper->envGain + fmAttackTable[pOperData->attackDecay >> 4];
-
- /* check for end of attack */
- if (temp >= 0x7fff)
- {
- pOper->envGain = 0x7fff;
- pOper->envState = eFMEnvelopeStateDecay;
- }
- else
- pOper->envGain = (EAS_U16) temp;
- break;
-
- case eFMEnvelopeStateDecay:
-
- /* decay is exponential, multiply by decay rate */
- pOper->envGain = (EAS_U16) FMUL_15x15(pOper->envGain, pOper->envRate);
-
- /* check for sustain level reached */
- temp = (EAS_U32) (pOperData->sustain & 0xfc) << 7;
- if (pOper->envGain <= (EAS_U16) temp)
- {
- /* if this is a one-shot patch, go directly to release phase */
- if (oneShot)
- {
- pOper->envRate = FM_CalcEGRate(
- pVoice->note,
- fmReleaseTable[pOperData->velocityRelease & 0x0f],
- fmScaleTable[pOperData->egKeyScale >> 4]);
- pOper->envState = eFMEnvelopeStateRelease;
- }
-
- /* normal sustaining type */
- else
- {
- pOper->envGain = (EAS_U16) temp;
- pOper->envState = eFMEnvelopeStateSustain;
- }
- }
- break;
-
- case eFMEnvelopeStateSustain:
- pOper->envGain = (EAS_U16)((EAS_U16)(pOperData->sustain & 0xfc) << 7);
- break;
-
- case eFMEnvelopeStateRelease:
-
- /* release is exponential, multiply by release rate */
- pOper->envGain = (EAS_U16) FMUL_15x15(pOper->envGain, pOper->envRate);
-
- /* fully released */
- if (pOper->envGain == 0)
- {
- pOper->envGain = 0;
- pOper->envState = eFMEnvelopeStateMuted;
- done = EAS_TRUE;
- }
- break;
-
- case eFMEnvelopeStateMuted:
- pOper->envGain = 0;
- done = EAS_TRUE;
- break;
- default:
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_FATAL,"Invalid operator state: %d", pOper->envState); */ }
- } /* end switch (pOper->m_eState) */
-
- return done;
-}
-
-/*----------------------------------------------------------------------------
- * FM_UpdateDynamic()
- *----------------------------------------------------------------------------
- * Purpose:
- * Calculate the synthesis parameters for this voice that will be used to
- * synthesize the next buffer
- *
- * Inputs:
- * pVoice - pointer to the voice being updated
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- * Returns EAS_TRUE if voice will be fully ramped to zero at the end of
- * the next synthesized buffer.
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_BOOL FM_UpdateDynamic (S_SYNTH_VOICE *pVoice, S_FM_VOICE *pFMVoice, const S_FM_REGION *pRegion, S_SYNTH_CHANNEL *pChannel)
-{
- EAS_I32 temp;
- EAS_I32 pitch;
- EAS_I32 lfoPitch;
- EAS_INT operIndex;
- EAS_BOOL done;
-
- /* increment LFO phase */
- FM_UpdateLFO(pFMVoice, pRegion);
-
- /* base pitch in cents */
- pitch = pVoice->note * 100;
-
- /* LFO amount includes LFO depth from programming + channel dynamics */
- temp = (fmScaleTable[pRegion->vibTrem >> 4] >> 1) + pChannel->lfoAmt;
-
- /* multiply by LFO output to get final pitch modulation */
- lfoPitch = FMUL_15x15(pFMVoice->lfoValue, temp);
-
- /* flag to indicate this voice is done */
- done = EAS_TRUE;
-
- /* iterate through operators to establish parameters */
- for (operIndex = 0; operIndex < 4; operIndex++)
- {
- EAS_BOOL bTemp;
-
- /* set base phase increment for each operator */
- temp = pRegion->oper[operIndex].tuning +
- pChannel->staticPitch;
-
- /* add vibrato effect unless it is disabled for this operator */
- if ((pRegion->oper[operIndex].flags & FM_OPER_FLAG_NO_VIBRATO) == 0)
- temp += lfoPitch;
-
- /* if note is monotonic, bias to MIDI note 60 */
- if (pRegion->oper[operIndex].flags & FM_OPER_FLAG_MONOTONE)
- temp += 6000;
- else
- temp += pitch;
- pFMVoice->oper[operIndex].pitch = (EAS_I16) temp;
-
- /* calculate envelope, returns true if done */
- bTemp = FM_UpdateEG(pVoice, &pFMVoice->oper[operIndex], &pRegion->oper[operIndex], pRegion->region.keyGroupAndFlags & REGION_FLAG_ONE_SHOT);
-
- /* check if all output envelopes have completed */
- if (FM_SynthIsOutputOperator(pRegion, operIndex))
- done = done && bTemp;
- }
-
- return done;
-}
-
-/*----------------------------------------------------------------------------
- * FM_UpdateVoice()
- *----------------------------------------------------------------------------
- * Purpose:
- * Synthesize a block of samples for the given voice.
- *
- * Inputs:
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- * number of samples actually written to buffer
- *
- * Side Effects:
- * - samples are added to the presently free buffer
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_BOOL FM_UpdateVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, EAS_I32 voiceNum, EAS_I32 *pMixBuffer, EAS_I32 numSamples)
-{
- S_SYNTH_CHANNEL *pChannel;
- const S_FM_REGION *pRegion;
- S_FM_VOICE *pFMVoice;
- S_FM_VOICE_CONFIG vCfg;
- S_FM_VOICE_FRAME vFrame;
- EAS_I32 temp;
- EAS_INT oper;
- EAS_U16 voiceGainTarget;
- EAS_BOOL done;
-
- /* setup some pointers */
- pChannel = GetChannelPtr(pSynth, pVoice);
- pRegion = GetFMRegionPtr(pSynth, pVoice);
- pFMVoice = GetFMVoicePtr(pVoiceMgr, voiceNum);
-
- /* if the voice is just starting, get the voice configuration data */
- if (pVoice->voiceFlags & VOICE_FLAG_NO_SAMPLES_SYNTHESIZED_YET)
- {
-
- /* split architecture may limit the number of voice starts */
-#ifdef MAX_VOICE_STARTS
- if (pVoiceMgr->numVoiceStarts == MAX_VOICE_STARTS)
- return EAS_FALSE;
- pVoiceMgr->numVoiceStarts++;
-#endif
-
- /* get initial parameters */
- vCfg.feedback = pRegion->feedback;
- vCfg.voiceGain = (EAS_U16) pFMVoice->voiceGain;
-
-#if (NUM_OUTPUT_CHANNELS == 2)
- vCfg.pan = pFMVoice->pan;
-#endif
-
- /* get voice mode */
- vCfg.flags = pRegion->region.keyGroupAndFlags & 7;
-
- /* get operator parameters */
- for (oper = 0; oper < 4; oper++)
- {
- /* calculate initial gain */
- vCfg.gain[oper] = (EAS_U16) FMUL_15x15(pFMVoice->oper[oper].baseGain, pFMVoice->oper[oper].envGain);
- vCfg.outputGain[oper] = pFMVoice->oper[oper].outputGain;
-
- /* copy noise waveform flag */
- if (pRegion->oper[oper].flags & FM_OPER_FLAG_NOISE)
- vCfg.flags |= (EAS_U8) (FLAG_FM_ENG_VOICE_OP1_NOISE << oper);
- }
-
-#ifdef FM_OFFBOARD
- FM_ConfigVoice(voiceNum, &vCfg, pVoiceMgr->pFrameBuffer);
-#else
- FM_ConfigVoice(voiceNum, &vCfg, NULL);
-#endif
-
- /* clear startup flag */
- pVoice->voiceFlags &= ~VOICE_FLAG_NO_SAMPLES_SYNTHESIZED_YET;
- }
-
- /* calculate new synthesis parameters */
- done = FM_UpdateDynamic(pVoice, pFMVoice, pRegion, pChannel);
-
- /* calculate LFO gain modulation */
- /*lint -e{702} <use shift for performance> */
- temp = ((fmScaleTable[pRegion->vibTrem & 0x0f] >> 1) * pFMVoice->lfoValue) >> FM_LFO_GAIN_SHIFT;
-
- /* include channel gain */
- temp += pChannel->staticGain;
-
- /* -32768 or lower is infinite attenuation */
- if (temp < -32767)
- voiceGainTarget = 0;
-
- /* translate to linear gain multiplier */
- else
- voiceGainTarget = EAS_LogToLinear16(temp);
-
- /* include synth master volume */
- voiceGainTarget = (EAS_U16) FMUL_15x15(voiceGainTarget, pSynth->masterVolume);
-
- /* save target values for this frame */
- vFrame.voiceGain = voiceGainTarget;
-
- /* assume voice output is zero */
- pVoice->gain = 0;
-
- /* save operator targets for this frame */
- for (oper = 0; oper < 4; oper++)
- {
- vFrame.gain[oper] = (EAS_U16) FMUL_15x15(pFMVoice->oper[oper].baseGain, pFMVoice->oper[oper].envGain);
- vFrame.pitch[oper] = pFMVoice->oper[oper].pitch;
-
- /* use the highest output envelope level as the gain for the voice stealing algorithm */
- if (FM_SynthIsOutputOperator(pRegion, oper))
- pVoice->gain = max(pVoice->gain, (EAS_I16) vFrame.gain[oper]);
- }
-
- /* consider voice gain multiplier in calculating gain for stealing algorithm */
- pVoice->gain = (EAS_I16) FMUL_15x15(voiceGainTarget, pVoice->gain);
-
- /* synthesize samples */
-#ifdef FM_OFFBOARD
- FM_ProcessVoice(voiceNum, &vFrame, numSamples, pVoiceMgr->operMixBuffer, pVoiceMgr->voiceBuffer, pMixBuffer, pVoiceMgr->pFrameBuffer);
-#else
- FM_ProcessVoice(voiceNum, &vFrame, numSamples, pVoiceMgr->operMixBuffer, pVoiceMgr->voiceBuffer, pMixBuffer, NULL);
-#endif
-
- return done;
-}
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 795 $
+ * $Date: 2007-08-01 00:14:45 -0700 (Wed, 01 Aug 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+// includes
+#include "eas_host.h"
+#include "eas_report.h"
+
+#include "eas_data.h"
+#include "eas_synth_protos.h"
+#include "eas_audioconst.h"
+#include "eas_fmengine.h"
+#include "eas_math.h"
+
+/* option sanity check */
+#ifdef _REVERB
+#error "No reverb for FM synthesizer"
+#endif
+#ifdef _CHORUS
+#error "No chorus for FM synthesizer"
+#endif
+
+/*
+ * WARNING: These macros can cause unwanted side effects. Use them
+ * with care. For example, min(x++,y++) will cause either x or y to be
+ * incremented twice.
+ */
+#define min(a,b) ((a) < (b) ? (a) : (b))
+#define max(a,b) ((a) > (b) ? (a) : (b))
+
+/* pivot point for keyboard scalars */
+#define EG_SCALE_PIVOT_POINT 64
+#define KEY_SCALE_PIVOT_POINT 36
+
+/* This number is the negative of the frequency of the note (in cents) of
+ * the sine wave played at unity. The number can be calculated as follows:
+ *
+ * MAGIC_NUMBER = 1200 * log(base2) (SINE_TABLE_SIZE * 8.175798916 / SAMPLE_RATE)
+ *
+ * 8.17578 is a reference to the frequency of MIDI note 0
+ */
+#if defined (_SAMPLE_RATE_8000)
+#define MAGIC_NUMBER 1279
+#elif defined (_SAMPLE_RATE_16000)
+#define MAGIC_NUMBER 79
+#elif defined (_SAMPLE_RATE_20000)
+#define MAGIC_NUMBER -308
+#elif defined (_SAMPLE_RATE_22050)
+#define MAGIC_NUMBER -477
+#elif defined (_SAMPLE_RATE_24000)
+#define MAGIC_NUMBER -623
+#elif defined (_SAMPLE_RATE_32000)
+#define MAGIC_NUMBER -1121
+#elif defined (_SAMPLE_RATE_44100)
+#define MAGIC_NUMBER -1677
+#elif defined (_SAMPLE_RATE_48000)
+#define MAGIC_NUMBER -1823
+#endif
+
+/* externs */
+extern const EAS_I16 fmControlTable[128];
+extern const EAS_U16 fmRateTable[256];
+extern const EAS_U16 fmAttackTable[16];
+extern const EAS_U8 fmDecayTable[16];
+extern const EAS_U8 fmReleaseTable[16];
+extern const EAS_U8 fmScaleTable[16];
+
+/* local prototypes */
+/*lint -esym(715, pVoiceMgr) standard synthesizer interface - pVoiceMgr not used */
+static EAS_RESULT FM_Initialize (S_VOICE_MGR *pVoiceMgr) { return EAS_SUCCESS; }
+static EAS_RESULT FM_StartVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, EAS_I32 voiceNum, EAS_U16 regionIndex);
+static EAS_BOOL FM_UpdateVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, EAS_I32 voiceNum, EAS_I32 *pMixBuffer, EAS_I32 numSamples);
+static void FM_ReleaseVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, EAS_I32 voiceNum);
+static void FM_MuteVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, EAS_I32 voiceNum);
+static void FM_SustainPedal (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, S_SYNTH_CHANNEL *pChannel, EAS_I32 voiceNum);
+static void FM_UpdateChannel (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel);
+
+
+/*----------------------------------------------------------------------------
+ * Synthesizer interface
+ *----------------------------------------------------------------------------
+*/
+const S_SYNTH_INTERFACE fmSynth =
+{
+ FM_Initialize,
+ FM_StartVoice,
+ FM_UpdateVoice,
+ FM_ReleaseVoice,
+ FM_MuteVoice,
+ FM_SustainPedal,
+ FM_UpdateChannel
+};
+
+#ifdef FM_OFFBOARD
+const S_FRAME_INTERFACE fmFrameInterface =
+{
+ FM_StartFrame,
+ FM_EndFrame
+};
+#endif
+
+/*----------------------------------------------------------------------------
+ * inline functions
+ *----------------------------------------------------------------------------
+ */
+EAS_INLINE S_FM_VOICE *GetFMVoicePtr (S_VOICE_MGR *pVoiceMgr, EAS_INT voiceNum)
+{
+ return &pVoiceMgr->fmVoices[voiceNum];
+}
+EAS_INLINE S_SYNTH_CHANNEL *GetChannelPtr (S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice)
+{
+ return &pSynth->channels[pVoice->channel & 15];
+}
+EAS_INLINE const S_FM_REGION *GetFMRegionPtr (S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice)
+{
+#ifdef _SECONDARY_SYNTH
+ return &pSynth->pEAS->pFMRegions[pVoice->regionIndex & REGION_INDEX_MASK];
+#else
+ return &pSynth->pEAS->pFMRegions[pVoice->regionIndex];
+#endif
+}
+
+/*----------------------------------------------------------------------------
+ * FM_SynthIsOutputOperator
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Returns true if the operator is a direct output and not muted
+ *
+ * Inputs:
+ *
+ * Outputs:
+ * Returns boolean
+ *----------------------------------------------------------------------------
+*/
+static EAS_BOOL FM_SynthIsOutputOperator (const S_FM_REGION *pRegion, EAS_INT operIndex)
+{
+
+ /* see if voice is muted */
+ if ((pRegion->oper[operIndex].gain & 0xfc) == 0)
+ return 0;
+
+ /* check based on mode */
+ switch (pRegion->region.keyGroupAndFlags & 7)
+ {
+
+ /* mode 0 - all operators are external */
+ case 0:
+ return EAS_TRUE;
+
+ /* mode 1 - operators 1-3 are external */
+ case 1:
+ if (operIndex != 0)
+ return EAS_TRUE;
+ break;
+
+ /* mode 2 - operators 1 & 3 are external */
+ case 2:
+ if ((operIndex == 1) || (operIndex == 3))
+ return EAS_TRUE;
+ break;
+
+ /* mode 2 - operators 1 & 2 are external */
+ case 3:
+ if ((operIndex == 1) || (operIndex == 2))
+ return EAS_TRUE;
+ break;
+
+ /* modes 4 & 5 - operator 1 is external */
+ case 4:
+ case 5:
+ if (operIndex == 1)
+ return EAS_TRUE;
+ break;
+
+ default:
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_FATAL,"Invalid voice mode: %d",
+ pRegion->region.keyGroupAndFlags & 7); */ }
+ }
+
+ return EAS_FALSE;
+}
+
+/*----------------------------------------------------------------------------
+ * FM_CalcEGRate()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ *
+ * Inputs:
+ * nKeyNumber - MIDI note
+ * nLogRate - logarithmic scale rate from patch data
+ * nKeyScale - key scaling factor for this EG
+ *
+ * Outputs:
+ * 16-bit linear multiplier
+ *----------------------------------------------------------------------------
+*/
+
+static EAS_U16 FM_CalcEGRate (EAS_U8 nKeyNumber, EAS_U8 nLogRate, EAS_U8 nEGScale)
+{
+ EAS_I32 temp;
+
+ /* incorporate key scaling on release rate */
+ temp = (EAS_I32) nLogRate << 7;
+ temp += ((EAS_I32) nKeyNumber - EG_SCALE_PIVOT_POINT) * (EAS_I32) nEGScale;
+
+ /* saturate */
+ temp = max(temp, 0);
+ temp = min(temp, 32767);
+
+ /* look up in rate table */
+ /*lint -e{704} use shift for performance */
+ return fmRateTable[temp >> 8];
+}
+
+/*----------------------------------------------------------------------------
+ * FM_ReleaseVoice()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * The selected voice is being released.
+ *
+ * Inputs:
+ * psEASData - pointer to S_EAS_DATA
+ * pVoice - pointer to voice to release
+ *
+ * Outputs:
+ * None
+ *----------------------------------------------------------------------------
+*/
+static void FM_ReleaseVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, EAS_I32 voiceNum)
+{
+ EAS_INT operIndex;
+ const S_FM_REGION *pRegion;
+ S_FM_VOICE *pFMVoice;
+
+ /* check to see if voice responds to NOTE-OFF's */
+ pRegion = GetFMRegionPtr(pSynth, pVoice);
+ if (pRegion->region.keyGroupAndFlags & REGION_FLAG_ONE_SHOT)
+ return;
+
+ /* set all envelopes to release state */
+ pFMVoice = GetFMVoicePtr(pVoiceMgr, voiceNum);
+ for (operIndex = 0; operIndex < 4; operIndex++)
+ {
+ pFMVoice->oper[operIndex].envState = eFMEnvelopeStateRelease;
+
+ /* incorporate key scaling on release rate */
+ pFMVoice->oper[operIndex].envRate = FM_CalcEGRate(
+ pVoice->note,
+ fmReleaseTable[pRegion->oper[operIndex].velocityRelease & 0x0f],
+ fmScaleTable[pRegion->oper[operIndex].egKeyScale >> 4]);
+ } /* end for (operIndex = 0; operIndex < 4; operIndex++) */
+}
+
+/*----------------------------------------------------------------------------
+ * FM_MuteVoice()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * The selected voice is being muted.
+ *
+ * Inputs:
+ * pVoice - pointer to voice to release
+ *
+ * Outputs:
+ * None
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pSynth) standard interface, pVoiceMgr not used */
+static void FM_MuteVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, EAS_I32 voiceNum)
+{
+ S_FM_VOICE *pFMVoice;
+
+ /* clear deferred action flags */
+ pVoice->voiceFlags &=
+ ~(VOICE_FLAG_DEFER_MIDI_NOTE_OFF |
+ VOICE_FLAG_SUSTAIN_PEDAL_DEFER_NOTE_OFF |
+ VOICE_FLAG_DEFER_MUTE);
+
+ /* set all envelopes to muted state */
+ pFMVoice = GetFMVoicePtr(pVoiceMgr, voiceNum);
+ pFMVoice->oper[0].envState = eFMEnvelopeStateMuted;
+ pFMVoice->oper[1].envState = eFMEnvelopeStateMuted;
+ pFMVoice->oper[2].envState = eFMEnvelopeStateMuted;
+ pFMVoice->oper[3].envState = eFMEnvelopeStateMuted;
+}
+
+/*----------------------------------------------------------------------------
+ * FM_SustainPedal()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * The selected voice is held due to sustain pedal
+ *
+ * Inputs:
+ * pVoice - pointer to voice to sustain
+ *
+ * Outputs:
+ * None
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pChannel) standard interface, pVoiceMgr not used */
+static void FM_SustainPedal (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, S_SYNTH_CHANNEL *pChannel, EAS_I32 voiceNum)
+{
+ const S_FM_REGION *pRegion;
+ S_FM_VOICE *pFMVoice;
+ EAS_INT operIndex;
+
+ pRegion = GetFMRegionPtr(pSynth, pVoice);
+ pFMVoice = GetFMVoicePtr(pVoiceMgr, voiceNum);
+
+ /* check to see if any envelopes are above the sustain level */
+ for (operIndex = 0; operIndex < 4; operIndex++)
+ {
+
+ /* if level control or envelope gain is zero, skip this envelope */
+ if (((pRegion->oper[operIndex].gain & 0xfc) == 0) ||
+ (pFMVoice->oper[operIndex].envGain == 0))
+ {
+ continue;
+ }
+
+ /* if the envelope gain is above the sustain level, we need to catch this voice */
+ if (pFMVoice->oper[operIndex].envGain >= ((EAS_U16) (pRegion->oper[operIndex].sustain & 0xfc) << 7))
+ {
+
+ /* reset envelope to decay state */
+ pFMVoice->oper[operIndex].envState = eFMEnvelopeStateDecay;
+
+ pFMVoice->oper[operIndex].envRate = FM_CalcEGRate(
+ pVoice->note,
+ fmDecayTable[pRegion->oper[operIndex].attackDecay & 0x0f],
+ fmScaleTable[pRegion->oper[operIndex].egKeyScale >> 4]);
+
+ /* set voice to decay state */
+ pVoice->voiceState = eVoiceStatePlay;
+
+ /* set sustain flag */
+ pVoice->voiceFlags |= VOICE_FLAG_SUSTAIN_PEDAL_DEFER_NOTE_OFF;
+ }
+ } /* end for (operIndex = 0; operIndex < 4; operIndex++) */
+}
+
+/*----------------------------------------------------------------------------
+ * FM_StartVoice()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Assign the region for the given instrument using the midi key number
+ * and the RPN2 (coarse tuning) value. By using RPN2 as part of the
+ * region selection process, we reduce the amount a given sample has
+ * to be transposed by selecting the closest recorded root instead.
+ *
+ * This routine is the second half of SynthAssignRegion().
+ * If the region was successfully found by SynthFindRegionIndex(),
+ * then assign the region's parameters to the voice.
+ *
+ * Setup and initialize the following voice parameters:
+ * m_nRegionIndex
+ *
+ * Inputs:
+ * pVoice - ptr to the voice we have assigned for this channel
+ * nRegionIndex - index of the region
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ * success - could find and assign the region for this voice's note otherwise
+ * failure - could not find nor assign the region for this voice's note
+ *
+ * Side Effects:
+ * psSynthObject->m_sVoice[].m_nRegionIndex is assigned
+ * psSynthObject->m_sVoice[] parameters are assigned
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT FM_StartVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, EAS_I32 voiceNum, EAS_U16 regionIndex)
+{
+ S_FM_VOICE *pFMVoice;
+ S_SYNTH_CHANNEL *pChannel;
+ const S_FM_REGION *pRegion;
+ EAS_I32 temp;
+ EAS_INT operIndex;
+
+ /* establish pointers to data */
+ pVoice->regionIndex = regionIndex;
+ pFMVoice = GetFMVoicePtr(pVoiceMgr, voiceNum);
+ pChannel = GetChannelPtr(pSynth, pVoice);
+ pRegion = GetFMRegionPtr(pSynth, pVoice);
+
+ /* update static channel parameters */
+ if (pChannel->channelFlags & CHANNEL_FLAG_UPDATE_CHANNEL_PARAMETERS)
+ FM_UpdateChannel(pVoiceMgr, pSynth, pVoice->channel & 15);
+
+ /* init the LFO */
+ pFMVoice->lfoValue = 0;
+ pFMVoice->lfoPhase = 0;
+ pFMVoice->lfoDelay = (EAS_U16) (fmScaleTable[pRegion->lfoFreqDelay & 0x0f] >> 1);
+
+#if (NUM_OUTPUT_CHANNELS == 2)
+ /* calculate pan gain values only if stereo output */
+ /* set up panning only at note start */
+ temp = (EAS_I32) pChannel->pan - 64;
+ temp += (EAS_I32) pRegion->pan;
+ if (temp < -64)
+ temp = -64;
+ if (temp > 64)
+ temp = 64;
+ pFMVoice->pan = (EAS_I8) temp;
+#endif /* #if (NUM_OUTPUT_CHANNELS == 2) */
+
+ /* no samples have been synthesized for this note yet */
+ pVoice->voiceFlags = VOICE_FLAG_NO_SAMPLES_SYNTHESIZED_YET;
+
+ /* initialize gain value for anti-zipper filter */
+ pFMVoice->voiceGain = (EAS_I16) EAS_LogToLinear16(pChannel->staticGain);
+ pFMVoice->voiceGain = (EAS_I16) FMUL_15x15(pFMVoice->voiceGain, pSynth->masterVolume);
+
+ /* initialize the operators */
+ for (operIndex = 0; operIndex < 4; operIndex++)
+ {
+
+ /* establish operator output gain level */
+ /*lint -e{701} <use shift for performance> */
+ pFMVoice->oper[operIndex].outputGain = EAS_LogToLinear16(((EAS_I16) (pRegion->oper[operIndex].gain & 0xfc) - 0xfc) << 7);
+
+ /* check for linear velocity flag */
+ /*lint -e{703} <use shift for performance> */
+ if (pRegion->oper[operIndex].flags & FM_OPER_FLAG_LINEAR_VELOCITY)
+ temp = (EAS_I32) (pVoice->velocity - 127) << 5;
+ else
+ temp = (EAS_I32) fmControlTable[pVoice->velocity];
+
+ /* scale velocity */
+ /*lint -e{704} use shift for performance */
+ temp = (temp * (EAS_I32)(pRegion->oper[operIndex].velocityRelease & 0xf0)) >> 7;
+
+ /* include key scalar */
+ temp -= ((EAS_I32) pVoice->note - KEY_SCALE_PIVOT_POINT) * (EAS_I32) fmScaleTable[pRegion->oper[operIndex].egKeyScale & 0x0f];
+
+ /* saturate */
+ temp = min(temp, 0);
+ temp = max(temp, -32768);
+
+ /* save static gain parameters */
+ pFMVoice->oper[operIndex].baseGain = (EAS_I16) EAS_LogToLinear16(temp);
+
+ /* incorporate key scaling on decay rate */
+ pFMVoice->oper[operIndex].envRate = FM_CalcEGRate(
+ pVoice->note,
+ fmDecayTable[pRegion->oper[operIndex].attackDecay & 0x0f],
+ fmScaleTable[pRegion->oper[operIndex].egKeyScale >> 4]);
+
+ /* if zero attack time, max out envelope and jump to decay state */
+ if ((pRegion->oper[operIndex].attackDecay & 0xf0) == 0xf0)
+ {
+
+ /* start out envelope at max */
+ pFMVoice->oper[operIndex].envGain = 0x7fff;
+
+ /* set envelope to decay state */
+ pFMVoice->oper[operIndex].envState = eFMEnvelopeStateDecay;
+ }
+
+ /* start envelope at zero and start in attack state */
+ else
+ {
+ pFMVoice->oper[operIndex].envGain = 0;
+ pFMVoice->oper[operIndex].envState = eFMEnvelopeStateAttack;
+ }
+ }
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * FM_UpdateChannel()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Calculate and assign static channel parameters
+ * These values only need to be updated if one of the controller values
+ * for this channel changes.
+ * Called when CHANNEL_FLAG_UPDATE_CHANNEL_PARAMETERS flag is set.
+ *
+ * Inputs:
+ * nChannel - channel to update
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ * - the given channel's static gain and static pitch are updated
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pVoiceMgr) standard interface, pVoiceMgr not used */
+static void FM_UpdateChannel (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel)
+{
+ S_SYNTH_CHANNEL *pChannel;
+ EAS_I32 temp;
+
+ pChannel = &pSynth->channels[channel];
+
+ /* convert CC7 volume controller to log scale */
+ temp = fmControlTable[pChannel->volume];
+
+ /* incorporate CC11 expression controller */
+ temp += fmControlTable[pChannel->expression];
+
+ /* saturate */
+ pChannel->staticGain = (EAS_I16) max(temp,-32768);
+
+ /* calculate pitch bend */
+ /*lint -e{703} <avoid multiply for performance>*/
+ temp = (((EAS_I32)(pChannel->pitchBend) << 2) - 32768);
+
+ temp = FMUL_15x15(temp, pChannel->pitchBendSensitivity);
+
+ /* include "magic number" compensation for sample rate and lookup table size */
+ temp += MAGIC_NUMBER;
+
+ /* if this is not a drum channel, then add in the per-channel tuning */
+ if (!(pChannel->channelFlags & CHANNEL_FLAG_RHYTHM_CHANNEL))
+ temp += (pChannel->finePitch + (pChannel->coarsePitch * 100));
+
+ /* save static pitch */
+ pChannel->staticPitch = temp;
+
+ /* Calculate LFO modulation depth */
+ /* mod wheel to LFO depth */
+ temp = FMUL_15x15(DEFAULT_LFO_MOD_WHEEL_TO_PITCH_CENTS,
+ pChannel->modWheel << (NUM_EG1_FRAC_BITS -7));
+
+ /* channel pressure to LFO depth */
+ pChannel->lfoAmt = (EAS_I16) (temp +
+ FMUL_15x15(DEFAULT_LFO_CHANNEL_PRESSURE_TO_PITCH_CENTS,
+ pChannel->channelPressure << (NUM_EG1_FRAC_BITS -7)));
+
+ /* clear update flag */
+ pChannel->channelFlags &= ~CHANNEL_FLAG_UPDATE_CHANNEL_PARAMETERS;
+ return;
+}
+
+/*----------------------------------------------------------------------------
+ * FM_UpdateLFO()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Calculate the LFO for the given voice
+ *
+ * Inputs:
+ * pVoice - ptr to the voice whose LFO we want to update
+ * psEASData - pointer to overall EAS data structure - used for debug only
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ * - updates LFO values for the given voice
+ *----------------------------------------------------------------------------
+*/
+static void FM_UpdateLFO (S_FM_VOICE *pFMVoice, const S_FM_REGION *pRegion)
+{
+
+ /* increment the LFO phase if the delay time has elapsed */
+ if (!pFMVoice->lfoDelay)
+ {
+ /*lint -e{701} <use shift for performance> */
+ pFMVoice->lfoPhase = pFMVoice->lfoPhase + (EAS_U16) (-fmControlTable[((15 - (pRegion->lfoFreqDelay >> 4)) << 3) + 4]);
+
+ /* square wave LFO? */
+ if (pRegion->region.keyGroupAndFlags & REGION_FLAG_SQUARE_WAVE)
+ pFMVoice->lfoValue = (EAS_I16)(pFMVoice->lfoPhase & 0x8000 ? -32767 : 32767);
+
+ /* trick to get a triangle wave out of a sawtooth */
+ else
+ {
+ pFMVoice->lfoValue = (EAS_I16) (pFMVoice->lfoPhase << 1);
+ /*lint -e{502} <shortcut to turn sawtooth into sine wave> */
+ if ((pFMVoice->lfoPhase > 0x3fff) && (pFMVoice->lfoPhase < 0xC000))
+ pFMVoice->lfoValue = ~pFMVoice->lfoValue;
+ }
+ }
+
+ /* still in delay */
+ else
+ pFMVoice->lfoDelay--;
+
+ return;
+}
+
+/*----------------------------------------------------------------------------
+ * FM_UpdateEG()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Calculate the synthesis parameters for an operator to be used during
+ * the next buffer
+ *
+ * Inputs:
+ * pVoice - pointer to the voice being updated
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_BOOL FM_UpdateEG (S_SYNTH_VOICE *pVoice, S_OPERATOR *pOper, const S_FM_OPER *pOperData, EAS_BOOL oneShot)
+{
+ EAS_U32 temp;
+ EAS_BOOL done;
+
+ /* set flag assuming the envelope is not done */
+ done = EAS_FALSE;
+
+ /* take appropriate action based on state */
+ switch (pOper->envState)
+ {
+
+ case eFMEnvelopeStateAttack:
+
+ /* the envelope is linear during the attack, so add the value */
+ temp = pOper->envGain + fmAttackTable[pOperData->attackDecay >> 4];
+
+ /* check for end of attack */
+ if (temp >= 0x7fff)
+ {
+ pOper->envGain = 0x7fff;
+ pOper->envState = eFMEnvelopeStateDecay;
+ }
+ else
+ pOper->envGain = (EAS_U16) temp;
+ break;
+
+ case eFMEnvelopeStateDecay:
+
+ /* decay is exponential, multiply by decay rate */
+ pOper->envGain = (EAS_U16) FMUL_15x15(pOper->envGain, pOper->envRate);
+
+ /* check for sustain level reached */
+ temp = (EAS_U32) (pOperData->sustain & 0xfc) << 7;
+ if (pOper->envGain <= (EAS_U16) temp)
+ {
+ /* if this is a one-shot patch, go directly to release phase */
+ if (oneShot)
+ {
+ pOper->envRate = FM_CalcEGRate(
+ pVoice->note,
+ fmReleaseTable[pOperData->velocityRelease & 0x0f],
+ fmScaleTable[pOperData->egKeyScale >> 4]);
+ pOper->envState = eFMEnvelopeStateRelease;
+ }
+
+ /* normal sustaining type */
+ else
+ {
+ pOper->envGain = (EAS_U16) temp;
+ pOper->envState = eFMEnvelopeStateSustain;
+ }
+ }
+ break;
+
+ case eFMEnvelopeStateSustain:
+ pOper->envGain = (EAS_U16)((EAS_U16)(pOperData->sustain & 0xfc) << 7);
+ break;
+
+ case eFMEnvelopeStateRelease:
+
+ /* release is exponential, multiply by release rate */
+ pOper->envGain = (EAS_U16) FMUL_15x15(pOper->envGain, pOper->envRate);
+
+ /* fully released */
+ if (pOper->envGain == 0)
+ {
+ pOper->envGain = 0;
+ pOper->envState = eFMEnvelopeStateMuted;
+ done = EAS_TRUE;
+ }
+ break;
+
+ case eFMEnvelopeStateMuted:
+ pOper->envGain = 0;
+ done = EAS_TRUE;
+ break;
+ default:
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_FATAL,"Invalid operator state: %d", pOper->envState); */ }
+ } /* end switch (pOper->m_eState) */
+
+ return done;
+}
+
+/*----------------------------------------------------------------------------
+ * FM_UpdateDynamic()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Calculate the synthesis parameters for this voice that will be used to
+ * synthesize the next buffer
+ *
+ * Inputs:
+ * pVoice - pointer to the voice being updated
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ * Returns EAS_TRUE if voice will be fully ramped to zero at the end of
+ * the next synthesized buffer.
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_BOOL FM_UpdateDynamic (S_SYNTH_VOICE *pVoice, S_FM_VOICE *pFMVoice, const S_FM_REGION *pRegion, S_SYNTH_CHANNEL *pChannel)
+{
+ EAS_I32 temp;
+ EAS_I32 pitch;
+ EAS_I32 lfoPitch;
+ EAS_INT operIndex;
+ EAS_BOOL done;
+
+ /* increment LFO phase */
+ FM_UpdateLFO(pFMVoice, pRegion);
+
+ /* base pitch in cents */
+ pitch = pVoice->note * 100;
+
+ /* LFO amount includes LFO depth from programming + channel dynamics */
+ temp = (fmScaleTable[pRegion->vibTrem >> 4] >> 1) + pChannel->lfoAmt;
+
+ /* multiply by LFO output to get final pitch modulation */
+ lfoPitch = FMUL_15x15(pFMVoice->lfoValue, temp);
+
+ /* flag to indicate this voice is done */
+ done = EAS_TRUE;
+
+ /* iterate through operators to establish parameters */
+ for (operIndex = 0; operIndex < 4; operIndex++)
+ {
+ EAS_BOOL bTemp;
+
+ /* set base phase increment for each operator */
+ temp = pRegion->oper[operIndex].tuning +
+ pChannel->staticPitch;
+
+ /* add vibrato effect unless it is disabled for this operator */
+ if ((pRegion->oper[operIndex].flags & FM_OPER_FLAG_NO_VIBRATO) == 0)
+ temp += lfoPitch;
+
+ /* if note is monotonic, bias to MIDI note 60 */
+ if (pRegion->oper[operIndex].flags & FM_OPER_FLAG_MONOTONE)
+ temp += 6000;
+ else
+ temp += pitch;
+ pFMVoice->oper[operIndex].pitch = (EAS_I16) temp;
+
+ /* calculate envelope, returns true if done */
+ bTemp = FM_UpdateEG(pVoice, &pFMVoice->oper[operIndex], &pRegion->oper[operIndex], pRegion->region.keyGroupAndFlags & REGION_FLAG_ONE_SHOT);
+
+ /* check if all output envelopes have completed */
+ if (FM_SynthIsOutputOperator(pRegion, operIndex))
+ done = done && bTemp;
+ }
+
+ return done;
+}
+
+/*----------------------------------------------------------------------------
+ * FM_UpdateVoice()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Synthesize a block of samples for the given voice.
+ *
+ * Inputs:
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ * number of samples actually written to buffer
+ *
+ * Side Effects:
+ * - samples are added to the presently free buffer
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_BOOL FM_UpdateVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, EAS_I32 voiceNum, EAS_I32 *pMixBuffer, EAS_I32 numSamples)
+{
+ S_SYNTH_CHANNEL *pChannel;
+ const S_FM_REGION *pRegion;
+ S_FM_VOICE *pFMVoice;
+ S_FM_VOICE_CONFIG vCfg;
+ S_FM_VOICE_FRAME vFrame;
+ EAS_I32 temp;
+ EAS_INT oper;
+ EAS_U16 voiceGainTarget;
+ EAS_BOOL done;
+
+ /* setup some pointers */
+ pChannel = GetChannelPtr(pSynth, pVoice);
+ pRegion = GetFMRegionPtr(pSynth, pVoice);
+ pFMVoice = GetFMVoicePtr(pVoiceMgr, voiceNum);
+
+ /* if the voice is just starting, get the voice configuration data */
+ if (pVoice->voiceFlags & VOICE_FLAG_NO_SAMPLES_SYNTHESIZED_YET)
+ {
+
+ /* split architecture may limit the number of voice starts */
+#ifdef MAX_VOICE_STARTS
+ if (pVoiceMgr->numVoiceStarts == MAX_VOICE_STARTS)
+ return EAS_FALSE;
+ pVoiceMgr->numVoiceStarts++;
+#endif
+
+ /* get initial parameters */
+ vCfg.feedback = pRegion->feedback;
+ vCfg.voiceGain = (EAS_U16) pFMVoice->voiceGain;
+
+#if (NUM_OUTPUT_CHANNELS == 2)
+ vCfg.pan = pFMVoice->pan;
+#endif
+
+ /* get voice mode */
+ vCfg.flags = pRegion->region.keyGroupAndFlags & 7;
+
+ /* get operator parameters */
+ for (oper = 0; oper < 4; oper++)
+ {
+ /* calculate initial gain */
+ vCfg.gain[oper] = (EAS_U16) FMUL_15x15(pFMVoice->oper[oper].baseGain, pFMVoice->oper[oper].envGain);
+ vCfg.outputGain[oper] = pFMVoice->oper[oper].outputGain;
+
+ /* copy noise waveform flag */
+ if (pRegion->oper[oper].flags & FM_OPER_FLAG_NOISE)
+ vCfg.flags |= (EAS_U8) (FLAG_FM_ENG_VOICE_OP1_NOISE << oper);
+ }
+
+#ifdef FM_OFFBOARD
+ FM_ConfigVoice(voiceNum, &vCfg, pVoiceMgr->pFrameBuffer);
+#else
+ FM_ConfigVoice(voiceNum, &vCfg, NULL);
+#endif
+
+ /* clear startup flag */
+ pVoice->voiceFlags &= ~VOICE_FLAG_NO_SAMPLES_SYNTHESIZED_YET;
+ }
+
+ /* calculate new synthesis parameters */
+ done = FM_UpdateDynamic(pVoice, pFMVoice, pRegion, pChannel);
+
+ /* calculate LFO gain modulation */
+ /*lint -e{702} <use shift for performance> */
+ temp = ((fmScaleTable[pRegion->vibTrem & 0x0f] >> 1) * pFMVoice->lfoValue) >> FM_LFO_GAIN_SHIFT;
+
+ /* include channel gain */
+ temp += pChannel->staticGain;
+
+ /* -32768 or lower is infinite attenuation */
+ if (temp < -32767)
+ voiceGainTarget = 0;
+
+ /* translate to linear gain multiplier */
+ else
+ voiceGainTarget = EAS_LogToLinear16(temp);
+
+ /* include synth master volume */
+ voiceGainTarget = (EAS_U16) FMUL_15x15(voiceGainTarget, pSynth->masterVolume);
+
+ /* save target values for this frame */
+ vFrame.voiceGain = voiceGainTarget;
+
+ /* assume voice output is zero */
+ pVoice->gain = 0;
+
+ /* save operator targets for this frame */
+ for (oper = 0; oper < 4; oper++)
+ {
+ vFrame.gain[oper] = (EAS_U16) FMUL_15x15(pFMVoice->oper[oper].baseGain, pFMVoice->oper[oper].envGain);
+ vFrame.pitch[oper] = pFMVoice->oper[oper].pitch;
+
+ /* use the highest output envelope level as the gain for the voice stealing algorithm */
+ if (FM_SynthIsOutputOperator(pRegion, oper))
+ pVoice->gain = max(pVoice->gain, (EAS_I16) vFrame.gain[oper]);
+ }
+
+ /* consider voice gain multiplier in calculating gain for stealing algorithm */
+ pVoice->gain = (EAS_I16) FMUL_15x15(voiceGainTarget, pVoice->gain);
+
+ /* synthesize samples */
+#ifdef FM_OFFBOARD
+ FM_ProcessVoice(voiceNum, &vFrame, numSamples, pVoiceMgr->operMixBuffer, pVoiceMgr->voiceBuffer, pMixBuffer, pVoiceMgr->pFrameBuffer);
+#else
+ FM_ProcessVoice(voiceNum, &vFrame, numSamples, pVoiceMgr->operMixBuffer, pVoiceMgr->voiceBuffer, pMixBuffer, NULL);
+#endif
+
+ return done;
+}
+
diff --git a/arm-fm-22k/lib_src/eas_fmsynth.h b/arm-fm-22k/lib_src/eas_fmsynth.h
index 76f8adc..8ceda46 100644
--- a/arm-fm-22k/lib_src/eas_fmsynth.h
+++ b/arm-fm-22k/lib_src/eas_fmsynth.h
@@ -1,12 +1,12 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_fmsynth.h
- *
- * Contents and purpose:
- * Implements the FM synthesizer functions.
- *
- * Copyright Sonic Network Inc. 2004
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_fmsynth.h
+ *
+ * Contents and purpose:
+ * Implements the FM synthesizer functions.
+ *
+ * Copyright Sonic Network Inc. 2004
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,63 +19,63 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 90 $
- * $Date: 2006-07-11 20:18:13 -0700 (Tue, 11 Jul 2006) $
- *----------------------------------------------------------------------------
-*/
-
-#ifndef fmsynthH
-#define fmsynthH
-
-#include "eas_data.h"
-
-#if defined (_FM_SYNTH)
-
-/* FM envelope state */
-typedef enum {
- eFMEnvelopeStateAttack = 0,
- eFMEnvelopeStateDecay,
- eFMEnvelopeStateSustain,
- eFMEnvelopeStateRelease,
- eFMEnvelopeStateMuted,
- eFMEnvelopeStateInvalid /* should never be in this state! */
-} E_FM_ENVELOPE_STATE;
-
-/*------------------------------------
- * S_OPERATOR data structure
- *------------------------------------
-*/
-typedef struct s_operator_tag
-{
- EAS_I16 pitch; /* operator pitch in cents */
- EAS_U16 envGain; /* envelope target */
- EAS_I16 baseGain; /* patch gain (inc. vel & key scale) */
- EAS_U16 outputGain; /* current output gain */
- EAS_U16 envRate; /* calculated envelope rate */
- EAS_U8 envState; /* envelope state */
- EAS_U8 pad; /* pad to 16-bits */
-} S_OPERATOR;
-#endif
-
-typedef struct s_fm_voice_tag
-{
- S_OPERATOR oper[4]; /* operator data */
- EAS_I16 voiceGain; /* LFO + channel parameters */
- EAS_U16 lfoPhase; /* LFO current phase */
- EAS_I16 lfoValue; /* LFO current value */
- EAS_U16 lfoDelay; /* keeps track of elapsed delay time */
- EAS_I8 pan; /* stereo pan value (-64 to +64) */
- EAS_I8 pad; /* reserved to maintain alignment */
-} S_FM_VOICE;
-
-#ifdef _FM_EDITOR
-extern S_FM_REGION newPatch;
-extern S_FM_REGION OriginalPatch;
-#endif
-
-extern EAS_U32 freqTable[];
-
-#endif
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 90 $
+ * $Date: 2006-07-11 20:18:13 -0700 (Tue, 11 Jul 2006) $
+ *----------------------------------------------------------------------------
+*/
+
+#ifndef fmsynthH
+#define fmsynthH
+
+#include "eas_data.h"
+
+#if defined (_FM_SYNTH)
+
+/* FM envelope state */
+typedef enum {
+ eFMEnvelopeStateAttack = 0,
+ eFMEnvelopeStateDecay,
+ eFMEnvelopeStateSustain,
+ eFMEnvelopeStateRelease,
+ eFMEnvelopeStateMuted,
+ eFMEnvelopeStateInvalid /* should never be in this state! */
+} E_FM_ENVELOPE_STATE;
+
+/*------------------------------------
+ * S_OPERATOR data structure
+ *------------------------------------
+*/
+typedef struct s_operator_tag
+{
+ EAS_I16 pitch; /* operator pitch in cents */
+ EAS_U16 envGain; /* envelope target */
+ EAS_I16 baseGain; /* patch gain (inc. vel & key scale) */
+ EAS_U16 outputGain; /* current output gain */
+ EAS_U16 envRate; /* calculated envelope rate */
+ EAS_U8 envState; /* envelope state */
+ EAS_U8 pad; /* pad to 16-bits */
+} S_OPERATOR;
+#endif
+
+typedef struct s_fm_voice_tag
+{
+ S_OPERATOR oper[4]; /* operator data */
+ EAS_I16 voiceGain; /* LFO + channel parameters */
+ EAS_U16 lfoPhase; /* LFO current phase */
+ EAS_I16 lfoValue; /* LFO current value */
+ EAS_U16 lfoDelay; /* keeps track of elapsed delay time */
+ EAS_I8 pan; /* stereo pan value (-64 to +64) */
+ EAS_I8 pad; /* reserved to maintain alignment */
+} S_FM_VOICE;
+
+#ifdef _FM_EDITOR
+extern S_FM_REGION newPatch;
+extern S_FM_REGION OriginalPatch;
+#endif
+
+extern EAS_U32 freqTable[];
+
+#endif
diff --git a/arm-fm-22k/lib_src/eas_fmtables.c b/arm-fm-22k/lib_src/eas_fmtables.c
index 25c6961..a8ff0a2 100644
--- a/arm-fm-22k/lib_src/eas_fmtables.c
+++ b/arm-fm-22k/lib_src/eas_fmtables.c
@@ -1,13 +1,13 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_fmtables.c
- *
- * Contents and purpose:
- * Contains lookup tables for the FM synthesizer
- *
- *
- * Copyright Sonic Network Inc. 2005
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_fmtables.c
+ *
+ * Contents and purpose:
+ * Contains lookup tables for the FM synthesizer
+ *
+ *
+ * Copyright Sonic Network Inc. 2005
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,349 +20,349 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 82 $
- * $Date: 2006-07-10 11:45:19 -0700 (Mon, 10 Jul 2006) $
- *
- *----------------------------------------------------------------------------
-*/
-
-
-#include "eas_types.h"
-
-/* this table is needed by the DSP and the main processor */
-const EAS_U8 fmScaleTable[16] =
-{
- 0,8,16,24,32,40,48,56,64,72,80,96,128,160,192,255
-};
-
-/* these tables are needed on the main processor */
-#ifndef _DSP_CODE
-const EAS_I16 fmControlTable[128] =
-{
- -32768,-14313,-12265,-11067,-10217,-9558,-9019,-8563,
- -8169,-7821,-7510,-7228,-6971,-6734,-6515,-6312,
- -6121,-5942,-5773,-5613,-5462,-5317,-5180,-5049,
- -4923,-4802,-4686,-4575,-4467,-4364,-4264,-4167,
- -4073,-3982,-3894,-3808,-3725,-3644,-3565,-3488,
- -3414,-3341,-3269,-3200,-3132,-3066,-3001,-2937,
- -2875,-2814,-2754,-2696,-2638,-2582,-2527,-2473,
- -2419,-2367,-2316,-2265,-2216,-2167,-2119,-2071,
- -2025,-1979,-1934,-1889,-1846,-1803,-1760,-1718,
- -1677,-1636,-1596,-1556,-1517,-1478,-1440,-1403,
- -1366,-1329,-1293,-1257,-1221,-1186,-1152,-1118,
- -1084,-1051,-1018,-985,-953,-921,-889,-858,
- -827,-796,-766,-736,-706,-677,-648,-619,
- -590,-562,-534,-506,-479,-452,-425,-398,
- -371,-345,-319,-293,-268,-242,-217,-192,
- -168,-143,-119,-95,-71,-47,-23,0
-};
-
-const EAS_U16 fmRateTable[128] =
-{
- 32767,32764,32758,32747,32731,32712,32688,32659,
- 32627,32590,32548,32503,32453,32398,32340,32277,
- 32211,32140,32065,31985,31902,31815,31724,31628,
- 31529,31426,31319,31208,31094,30976,30854,30728,
- 30599,30466,30330,30191,30048,29902,29752,29599,
- 29443,29285,29123,28958,28790,28619,28445,28269,
- 28090,27909,27725,27538,27349,27158,26964,26769,
- 26571,26371,26169,25965,25760,25552,25343,25132,
- 24920,24706,24490,24274,24056,23836,23616,23394,
- 23172,22948,22724,22499,22273,22046,21819,21591,
- 21363,21135,20906,20676,20447,20217,19987,19758,
- 19528,19298,19069,18840,18610,18382,18153,17926,
- 17698,17471,17245,17020,16795,16571,16347,16125,
- 15903,15683,15463,15245,15027,14811,14596,14382,
- 14169,13957,13747,13538,13331,13125,12920,12717,
- 12516,12316,12117,11921,11725,11532,11340,0
-};
-
-const EAS_U16 fmAttackTable[15] =
-{
- 27,54,109,327,655,1310,2730,4095,
- 4681,5461,6553,8191,10922,16383,32767
-};
-
-const EAS_U8 fmDecayTable[16] =
-{
- 4,7,10,15,20,25,30,35,40,50,60,70,80,90,100,127
-};
-
-const EAS_U8 fmReleaseTable[16] =
-{
- 10,15,20,25,30,35,40,45,50,60,70,80,90,100,113,127
-};
-#endif
-
-/* this table is needed only on the DSP */
-#if defined(_DSP_CODE) || !defined(_SPLIT_ARCHITECTURE)
-//---------------------------------------------------------------------
-// sineTable
-//
-// Contains sine lookup table
-//---------------------------------------------------------------------
-
-const EAS_I16 sineTable[2048] =
-{
- 0,101,201,302,402,503,603,704,
- 804,905,1005,1106,1206,1307,1407,1507,
- 1608,1708,1809,1909,2009,2110,2210,2310,
- 2410,2511,2611,2711,2811,2911,3012,3112,
- 3212,3312,3412,3512,3612,3712,3811,3911,
- 4011,4111,4210,4310,4410,4509,4609,4708,
- 4808,4907,5007,5106,5205,5305,5404,5503,
- 5602,5701,5800,5899,5998,6096,6195,6294,
- 6393,6491,6590,6688,6786,6885,6983,7081,
- 7179,7277,7375,7473,7571,7669,7767,7864,
- 7962,8059,8157,8254,8351,8448,8545,8642,
- 8739,8836,8933,9030,9126,9223,9319,9416,
- 9512,9608,9704,9800,9896,9992,10087,10183,
- 10278,10374,10469,10564,10659,10754,10849,10944,
- 11039,11133,11228,11322,11417,11511,11605,11699,
- 11793,11886,11980,12074,12167,12260,12353,12446,
- 12539,12632,12725,12817,12910,13002,13094,13187,
- 13279,13370,13462,13554,13645,13736,13828,13919,
- 14010,14101,14191,14282,14372,14462,14553,14643,
- 14732,14822,14912,15001,15090,15180,15269,15358,
- 15446,15535,15623,15712,15800,15888,15976,16063,
- 16151,16238,16325,16413,16499,16586,16673,16759,
- 16846,16932,17018,17104,17189,17275,17360,17445,
- 17530,17615,17700,17784,17869,17953,18037,18121,
- 18204,18288,18371,18454,18537,18620,18703,18785,
- 18868,18950,19032,19113,19195,19276,19357,19438,
- 19519,19600,19680,19761,19841,19921,20000,20080,
- 20159,20238,20317,20396,20475,20553,20631,20709,
- 20787,20865,20942,21019,21096,21173,21250,21326,
- 21403,21479,21554,21630,21705,21781,21856,21930,
- 22005,22079,22154,22227,22301,22375,22448,22521,
- 22594,22667,22739,22812,22884,22956,23027,23099,
- 23170,23241,23311,23382,23452,23522,23592,23662,
- 23731,23801,23870,23938,24007,24075,24143,24211,
- 24279,24346,24413,24480,24547,24613,24680,24746,
- 24811,24877,24942,25007,25072,25137,25201,25265,
- 25329,25393,25456,25519,25582,25645,25708,25770,
- 25832,25893,25955,26016,26077,26138,26198,26259,
- 26319,26378,26438,26497,26556,26615,26674,26732,
- 26790,26848,26905,26962,27019,27076,27133,27189,
- 27245,27300,27356,27411,27466,27521,27575,27629,
- 27683,27737,27790,27843,27896,27949,28001,28053,
- 28105,28157,28208,28259,28310,28360,28411,28460,
- 28510,28560,28609,28658,28706,28755,28803,28850,
- 28898,28945,28992,29039,29085,29131,29177,29223,
- 29268,29313,29358,29403,29447,29491,29534,29578,
- 29621,29664,29706,29749,29791,29832,29874,29915,
- 29956,29997,30037,30077,30117,30156,30195,30234,
- 30273,30311,30349,30387,30424,30462,30498,30535,
- 30571,30607,30643,30679,30714,30749,30783,30818,
- 30852,30885,30919,30952,30985,31017,31050,31082,
- 31113,31145,31176,31206,31237,31267,31297,31327,
- 31356,31385,31414,31442,31470,31498,31526,31553,
- 31580,31607,31633,31659,31685,31710,31736,31760,
- 31785,31809,31833,31857,31880,31903,31926,31949,
- 31971,31993,32014,32036,32057,32077,32098,32118,
- 32137,32157,32176,32195,32213,32232,32250,32267,
- 32285,32302,32318,32335,32351,32367,32382,32397,
- 32412,32427,32441,32455,32469,32482,32495,32508,
- 32521,32533,32545,32556,32567,32578,32589,32599,
- 32609,32619,32628,32637,32646,32655,32663,32671,
- 32678,32685,32692,32699,32705,32711,32717,32722,
- 32728,32732,32737,32741,32745,32748,32752,32755,
- 32757,32759,32761,32763,32765,32766,32766,32767,
- 32767,32767,32766,32766,32765,32763,32761,32759,
- 32757,32755,32752,32748,32745,32741,32737,32732,
- 32728,32722,32717,32711,32705,32699,32692,32685,
- 32678,32671,32663,32655,32646,32637,32628,32619,
- 32609,32599,32589,32578,32567,32556,32545,32533,
- 32521,32508,32495,32482,32469,32455,32441,32427,
- 32412,32397,32382,32367,32351,32335,32318,32302,
- 32285,32267,32250,32232,32213,32195,32176,32157,
- 32137,32118,32098,32077,32057,32036,32014,31993,
- 31971,31949,31926,31903,31880,31857,31833,31809,
- 31785,31760,31736,31710,31685,31659,31633,31607,
- 31580,31553,31526,31498,31470,31442,31414,31385,
- 31356,31327,31297,31267,31237,31206,31176,31145,
- 31113,31082,31050,31017,30985,30952,30919,30885,
- 30852,30818,30783,30749,30714,30679,30643,30607,
- 30571,30535,30498,30462,30424,30387,30349,30311,
- 30273,30234,30195,30156,30117,30077,30037,29997,
- 29956,29915,29874,29832,29791,29749,29706,29664,
- 29621,29578,29534,29491,29447,29403,29358,29313,
- 29268,29223,29177,29131,29085,29039,28992,28945,
- 28898,28850,28803,28755,28706,28658,28609,28560,
- 28510,28460,28411,28360,28310,28259,28208,28157,
- 28105,28053,28001,27949,27896,27843,27790,27737,
- 27683,27629,27575,27521,27466,27411,27356,27300,
- 27245,27189,27133,27076,27019,26962,26905,26848,
- 26790,26732,26674,26615,26556,26497,26438,26378,
- 26319,26259,26198,26138,26077,26016,25955,25893,
- 25832,25770,25708,25645,25582,25519,25456,25393,
- 25329,25265,25201,25137,25072,25007,24942,24877,
- 24811,24746,24680,24613,24547,24480,24413,24346,
- 24279,24211,24143,24075,24007,23938,23870,23801,
- 23731,23662,23592,23522,23452,23382,23311,23241,
- 23170,23099,23027,22956,22884,22812,22739,22667,
- 22594,22521,22448,22375,22301,22227,22154,22079,
- 22005,21930,21856,21781,21705,21630,21554,21479,
- 21403,21326,21250,21173,21096,21019,20942,20865,
- 20787,20709,20631,20553,20475,20396,20317,20238,
- 20159,20080,20000,19921,19841,19761,19680,19600,
- 19519,19438,19357,19276,19195,19113,19032,18950,
- 18868,18785,18703,18620,18537,18454,18371,18288,
- 18204,18121,18037,17953,17869,17784,17700,17615,
- 17530,17445,17360,17275,17189,17104,17018,16932,
- 16846,16759,16673,16586,16499,16413,16325,16238,
- 16151,16063,15976,15888,15800,15712,15623,15535,
- 15446,15358,15269,15180,15090,15001,14912,14822,
- 14732,14643,14553,14462,14372,14282,14191,14101,
- 14010,13919,13828,13736,13645,13554,13462,13370,
- 13279,13187,13094,13002,12910,12817,12725,12632,
- 12539,12446,12353,12260,12167,12074,11980,11886,
- 11793,11699,11605,11511,11417,11322,11228,11133,
- 11039,10944,10849,10754,10659,10564,10469,10374,
- 10278,10183,10087,9992,9896,9800,9704,9608,
- 9512,9416,9319,9223,9126,9030,8933,8836,
- 8739,8642,8545,8448,8351,8254,8157,8059,
- 7962,7864,7767,7669,7571,7473,7375,7277,
- 7179,7081,6983,6885,6786,6688,6590,6491,
- 6393,6294,6195,6096,5998,5899,5800,5701,
- 5602,5503,5404,5305,5205,5106,5007,4907,
- 4808,4708,4609,4509,4410,4310,4210,4111,
- 4011,3911,3811,3712,3612,3512,3412,3312,
- 3212,3112,3012,2911,2811,2711,2611,2511,
- 2410,2310,2210,2110,2009,1909,1809,1708,
- 1608,1507,1407,1307,1206,1106,1005,905,
- 804,704,603,503,402,302,201,101,
- 0,-101,-201,-302,-402,-503,-603,-704,
- -804,-905,-1005,-1106,-1206,-1307,-1407,-1507,
- -1608,-1708,-1809,-1909,-2009,-2110,-2210,-2310,
- -2410,-2511,-2611,-2711,-2811,-2911,-3012,-3112,
- -3212,-3312,-3412,-3512,-3612,-3712,-3811,-3911,
- -4011,-4111,-4210,-4310,-4410,-4509,-4609,-4708,
- -4808,-4907,-5007,-5106,-5205,-5305,-5404,-5503,
- -5602,-5701,-5800,-5899,-5998,-6096,-6195,-6294,
- -6393,-6491,-6590,-6688,-6786,-6885,-6983,-7081,
- -7179,-7277,-7375,-7473,-7571,-7669,-7767,-7864,
- -7962,-8059,-8157,-8254,-8351,-8448,-8545,-8642,
- -8739,-8836,-8933,-9030,-9126,-9223,-9319,-9416,
- -9512,-9608,-9704,-9800,-9896,-9992,-10087,-10183,
- -10278,-10374,-10469,-10564,-10659,-10754,-10849,-10944,
- -11039,-11133,-11228,-11322,-11417,-11511,-11605,-11699,
- -11793,-11886,-11980,-12074,-12167,-12260,-12353,-12446,
- -12539,-12632,-12725,-12817,-12910,-13002,-13094,-13187,
- -13279,-13370,-13462,-13554,-13645,-13736,-13828,-13919,
- -14010,-14101,-14191,-14282,-14372,-14462,-14553,-14643,
- -14732,-14822,-14912,-15001,-15090,-15180,-15269,-15358,
- -15446,-15535,-15623,-15712,-15800,-15888,-15976,-16063,
- -16151,-16238,-16325,-16413,-16499,-16586,-16673,-16759,
- -16846,-16932,-17018,-17104,-17189,-17275,-17360,-17445,
- -17530,-17615,-17700,-17784,-17869,-17953,-18037,-18121,
- -18204,-18288,-18371,-18454,-18537,-18620,-18703,-18785,
- -18868,-18950,-19032,-19113,-19195,-19276,-19357,-19438,
- -19519,-19600,-19680,-19761,-19841,-19921,-20000,-20080,
- -20159,-20238,-20317,-20396,-20475,-20553,-20631,-20709,
- -20787,-20865,-20942,-21019,-21096,-21173,-21250,-21326,
- -21403,-21479,-21554,-21630,-21705,-21781,-21856,-21930,
- -22005,-22079,-22154,-22227,-22301,-22375,-22448,-22521,
- -22594,-22667,-22739,-22812,-22884,-22956,-23027,-23099,
- -23170,-23241,-23311,-23382,-23452,-23522,-23592,-23662,
- -23731,-23801,-23870,-23938,-24007,-24075,-24143,-24211,
- -24279,-24346,-24413,-24480,-24547,-24613,-24680,-24746,
- -24811,-24877,-24942,-25007,-25072,-25137,-25201,-25265,
- -25329,-25393,-25456,-25519,-25582,-25645,-25708,-25770,
- -25832,-25893,-25955,-26016,-26077,-26138,-26198,-26259,
- -26319,-26378,-26438,-26497,-26556,-26615,-26674,-26732,
- -26790,-26848,-26905,-26962,-27019,-27076,-27133,-27189,
- -27245,-27300,-27356,-27411,-27466,-27521,-27575,-27629,
- -27683,-27737,-27790,-27843,-27896,-27949,-28001,-28053,
- -28105,-28157,-28208,-28259,-28310,-28360,-28411,-28460,
- -28510,-28560,-28609,-28658,-28706,-28755,-28803,-28850,
- -28898,-28945,-28992,-29039,-29085,-29131,-29177,-29223,
- -29268,-29313,-29358,-29403,-29447,-29491,-29534,-29578,
- -29621,-29664,-29706,-29749,-29791,-29832,-29874,-29915,
- -29956,-29997,-30037,-30077,-30117,-30156,-30195,-30234,
- -30273,-30311,-30349,-30387,-30424,-30462,-30498,-30535,
- -30571,-30607,-30643,-30679,-30714,-30749,-30783,-30818,
- -30852,-30885,-30919,-30952,-30985,-31017,-31050,-31082,
- -31113,-31145,-31176,-31206,-31237,-31267,-31297,-31327,
- -31356,-31385,-31414,-31442,-31470,-31498,-31526,-31553,
- -31580,-31607,-31633,-31659,-31685,-31710,-31736,-31760,
- -31785,-31809,-31833,-31857,-31880,-31903,-31926,-31949,
- -31971,-31993,-32014,-32036,-32057,-32077,-32098,-32118,
- -32137,-32157,-32176,-32195,-32213,-32232,-32250,-32267,
- -32285,-32302,-32318,-32335,-32351,-32367,-32382,-32397,
- -32412,-32427,-32441,-32455,-32469,-32482,-32495,-32508,
- -32521,-32533,-32545,-32556,-32567,-32578,-32589,-32599,
- -32609,-32619,-32628,-32637,-32646,-32655,-32663,-32671,
- -32678,-32685,-32692,-32699,-32705,-32711,-32717,-32722,
- -32728,-32732,-32737,-32741,-32745,-32748,-32752,-32755,
- -32757,-32759,-32761,-32763,-32765,-32766,-32766,-32767,
- -32767,-32767,-32766,-32766,-32765,-32763,-32761,-32759,
- -32757,-32755,-32752,-32748,-32745,-32741,-32737,-32732,
- -32728,-32722,-32717,-32711,-32705,-32699,-32692,-32685,
- -32678,-32671,-32663,-32655,-32646,-32637,-32628,-32619,
- -32609,-32599,-32589,-32578,-32567,-32556,-32545,-32533,
- -32521,-32508,-32495,-32482,-32469,-32455,-32441,-32427,
- -32412,-32397,-32382,-32367,-32351,-32335,-32318,-32302,
- -32285,-32267,-32250,-32232,-32213,-32195,-32176,-32157,
- -32137,-32118,-32098,-32077,-32057,-32036,-32014,-31993,
- -31971,-31949,-31926,-31903,-31880,-31857,-31833,-31809,
- -31785,-31760,-31736,-31710,-31685,-31659,-31633,-31607,
- -31580,-31553,-31526,-31498,-31470,-31442,-31414,-31385,
- -31356,-31327,-31297,-31267,-31237,-31206,-31176,-31145,
- -31113,-31082,-31050,-31017,-30985,-30952,-30919,-30885,
- -30852,-30818,-30783,-30749,-30714,-30679,-30643,-30607,
- -30571,-30535,-30498,-30462,-30424,-30387,-30349,-30311,
- -30273,-30234,-30195,-30156,-30117,-30077,-30037,-29997,
- -29956,-29915,-29874,-29832,-29791,-29749,-29706,-29664,
- -29621,-29578,-29534,-29491,-29447,-29403,-29358,-29313,
- -29268,-29223,-29177,-29131,-29085,-29039,-28992,-28945,
- -28898,-28850,-28803,-28755,-28706,-28658,-28609,-28560,
- -28510,-28460,-28411,-28360,-28310,-28259,-28208,-28157,
- -28105,-28053,-28001,-27949,-27896,-27843,-27790,-27737,
- -27683,-27629,-27575,-27521,-27466,-27411,-27356,-27300,
- -27245,-27189,-27133,-27076,-27019,-26962,-26905,-26848,
- -26790,-26732,-26674,-26615,-26556,-26497,-26438,-26378,
- -26319,-26259,-26198,-26138,-26077,-26016,-25955,-25893,
- -25832,-25770,-25708,-25645,-25582,-25519,-25456,-25393,
- -25329,-25265,-25201,-25137,-25072,-25007,-24942,-24877,
- -24811,-24746,-24680,-24613,-24547,-24480,-24413,-24346,
- -24279,-24211,-24143,-24075,-24007,-23938,-23870,-23801,
- -23731,-23662,-23592,-23522,-23452,-23382,-23311,-23241,
- -23170,-23099,-23027,-22956,-22884,-22812,-22739,-22667,
- -22594,-22521,-22448,-22375,-22301,-22227,-22154,-22079,
- -22005,-21930,-21856,-21781,-21705,-21630,-21554,-21479,
- -21403,-21326,-21250,-21173,-21096,-21019,-20942,-20865,
- -20787,-20709,-20631,-20553,-20475,-20396,-20317,-20238,
- -20159,-20080,-20000,-19921,-19841,-19761,-19680,-19600,
- -19519,-19438,-19357,-19276,-19195,-19113,-19032,-18950,
- -18868,-18785,-18703,-18620,-18537,-18454,-18371,-18288,
- -18204,-18121,-18037,-17953,-17869,-17784,-17700,-17615,
- -17530,-17445,-17360,-17275,-17189,-17104,-17018,-16932,
- -16846,-16759,-16673,-16586,-16499,-16413,-16325,-16238,
- -16151,-16063,-15976,-15888,-15800,-15712,-15623,-15535,
- -15446,-15358,-15269,-15180,-15090,-15001,-14912,-14822,
- -14732,-14643,-14553,-14462,-14372,-14282,-14191,-14101,
- -14010,-13919,-13828,-13736,-13645,-13554,-13462,-13370,
- -13279,-13187,-13094,-13002,-12910,-12817,-12725,-12632,
- -12539,-12446,-12353,-12260,-12167,-12074,-11980,-11886,
- -11793,-11699,-11605,-11511,-11417,-11322,-11228,-11133,
- -11039,-10944,-10849,-10754,-10659,-10564,-10469,-10374,
- -10278,-10183,-10087,-9992,-9896,-9800,-9704,-9608,
- -9512,-9416,-9319,-9223,-9126,-9030,-8933,-8836,
- -8739,-8642,-8545,-8448,-8351,-8254,-8157,-8059,
- -7962,-7864,-7767,-7669,-7571,-7473,-7375,-7277,
- -7179,-7081,-6983,-6885,-6786,-6688,-6590,-6491,
- -6393,-6294,-6195,-6096,-5998,-5899,-5800,-5701,
- -5602,-5503,-5404,-5305,-5205,-5106,-5007,-4907,
- -4808,-4708,-4609,-4509,-4410,-4310,-4210,-4111,
- -4011,-3911,-3811,-3712,-3612,-3512,-3412,-3312,
- -3212,-3112,-3012,-2911,-2811,-2711,-2611,-2511,
- -2410,-2310,-2210,-2110,-2009,-1909,-1809,-1708,
- -1608,-1507,-1407,-1307,-1206,-1106,-1005,-905,
- -804,-704,-603,-503,-402,-302,-201,-101
-};
-#endif
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 82 $
+ * $Date: 2006-07-10 11:45:19 -0700 (Mon, 10 Jul 2006) $
+ *
+ *----------------------------------------------------------------------------
+*/
+
+
+#include "eas_types.h"
+
+/* this table is needed by the DSP and the main processor */
+const EAS_U8 fmScaleTable[16] =
+{
+ 0,8,16,24,32,40,48,56,64,72,80,96,128,160,192,255
+};
+
+/* these tables are needed on the main processor */
+#ifndef _DSP_CODE
+const EAS_I16 fmControlTable[128] =
+{
+ -32768,-14313,-12265,-11067,-10217,-9558,-9019,-8563,
+ -8169,-7821,-7510,-7228,-6971,-6734,-6515,-6312,
+ -6121,-5942,-5773,-5613,-5462,-5317,-5180,-5049,
+ -4923,-4802,-4686,-4575,-4467,-4364,-4264,-4167,
+ -4073,-3982,-3894,-3808,-3725,-3644,-3565,-3488,
+ -3414,-3341,-3269,-3200,-3132,-3066,-3001,-2937,
+ -2875,-2814,-2754,-2696,-2638,-2582,-2527,-2473,
+ -2419,-2367,-2316,-2265,-2216,-2167,-2119,-2071,
+ -2025,-1979,-1934,-1889,-1846,-1803,-1760,-1718,
+ -1677,-1636,-1596,-1556,-1517,-1478,-1440,-1403,
+ -1366,-1329,-1293,-1257,-1221,-1186,-1152,-1118,
+ -1084,-1051,-1018,-985,-953,-921,-889,-858,
+ -827,-796,-766,-736,-706,-677,-648,-619,
+ -590,-562,-534,-506,-479,-452,-425,-398,
+ -371,-345,-319,-293,-268,-242,-217,-192,
+ -168,-143,-119,-95,-71,-47,-23,0
+};
+
+const EAS_U16 fmRateTable[128] =
+{
+ 32767,32764,32758,32747,32731,32712,32688,32659,
+ 32627,32590,32548,32503,32453,32398,32340,32277,
+ 32211,32140,32065,31985,31902,31815,31724,31628,
+ 31529,31426,31319,31208,31094,30976,30854,30728,
+ 30599,30466,30330,30191,30048,29902,29752,29599,
+ 29443,29285,29123,28958,28790,28619,28445,28269,
+ 28090,27909,27725,27538,27349,27158,26964,26769,
+ 26571,26371,26169,25965,25760,25552,25343,25132,
+ 24920,24706,24490,24274,24056,23836,23616,23394,
+ 23172,22948,22724,22499,22273,22046,21819,21591,
+ 21363,21135,20906,20676,20447,20217,19987,19758,
+ 19528,19298,19069,18840,18610,18382,18153,17926,
+ 17698,17471,17245,17020,16795,16571,16347,16125,
+ 15903,15683,15463,15245,15027,14811,14596,14382,
+ 14169,13957,13747,13538,13331,13125,12920,12717,
+ 12516,12316,12117,11921,11725,11532,11340,0
+};
+
+const EAS_U16 fmAttackTable[15] =
+{
+ 27,54,109,327,655,1310,2730,4095,
+ 4681,5461,6553,8191,10922,16383,32767
+};
+
+const EAS_U8 fmDecayTable[16] =
+{
+ 4,7,10,15,20,25,30,35,40,50,60,70,80,90,100,127
+};
+
+const EAS_U8 fmReleaseTable[16] =
+{
+ 10,15,20,25,30,35,40,45,50,60,70,80,90,100,113,127
+};
+#endif
+
+/* this table is needed only on the DSP */
+#if defined(_DSP_CODE) || !defined(_SPLIT_ARCHITECTURE)
+//---------------------------------------------------------------------
+// sineTable
+//
+// Contains sine lookup table
+//---------------------------------------------------------------------
+
+const EAS_I16 sineTable[2048] =
+{
+ 0,101,201,302,402,503,603,704,
+ 804,905,1005,1106,1206,1307,1407,1507,
+ 1608,1708,1809,1909,2009,2110,2210,2310,
+ 2410,2511,2611,2711,2811,2911,3012,3112,
+ 3212,3312,3412,3512,3612,3712,3811,3911,
+ 4011,4111,4210,4310,4410,4509,4609,4708,
+ 4808,4907,5007,5106,5205,5305,5404,5503,
+ 5602,5701,5800,5899,5998,6096,6195,6294,
+ 6393,6491,6590,6688,6786,6885,6983,7081,
+ 7179,7277,7375,7473,7571,7669,7767,7864,
+ 7962,8059,8157,8254,8351,8448,8545,8642,
+ 8739,8836,8933,9030,9126,9223,9319,9416,
+ 9512,9608,9704,9800,9896,9992,10087,10183,
+ 10278,10374,10469,10564,10659,10754,10849,10944,
+ 11039,11133,11228,11322,11417,11511,11605,11699,
+ 11793,11886,11980,12074,12167,12260,12353,12446,
+ 12539,12632,12725,12817,12910,13002,13094,13187,
+ 13279,13370,13462,13554,13645,13736,13828,13919,
+ 14010,14101,14191,14282,14372,14462,14553,14643,
+ 14732,14822,14912,15001,15090,15180,15269,15358,
+ 15446,15535,15623,15712,15800,15888,15976,16063,
+ 16151,16238,16325,16413,16499,16586,16673,16759,
+ 16846,16932,17018,17104,17189,17275,17360,17445,
+ 17530,17615,17700,17784,17869,17953,18037,18121,
+ 18204,18288,18371,18454,18537,18620,18703,18785,
+ 18868,18950,19032,19113,19195,19276,19357,19438,
+ 19519,19600,19680,19761,19841,19921,20000,20080,
+ 20159,20238,20317,20396,20475,20553,20631,20709,
+ 20787,20865,20942,21019,21096,21173,21250,21326,
+ 21403,21479,21554,21630,21705,21781,21856,21930,
+ 22005,22079,22154,22227,22301,22375,22448,22521,
+ 22594,22667,22739,22812,22884,22956,23027,23099,
+ 23170,23241,23311,23382,23452,23522,23592,23662,
+ 23731,23801,23870,23938,24007,24075,24143,24211,
+ 24279,24346,24413,24480,24547,24613,24680,24746,
+ 24811,24877,24942,25007,25072,25137,25201,25265,
+ 25329,25393,25456,25519,25582,25645,25708,25770,
+ 25832,25893,25955,26016,26077,26138,26198,26259,
+ 26319,26378,26438,26497,26556,26615,26674,26732,
+ 26790,26848,26905,26962,27019,27076,27133,27189,
+ 27245,27300,27356,27411,27466,27521,27575,27629,
+ 27683,27737,27790,27843,27896,27949,28001,28053,
+ 28105,28157,28208,28259,28310,28360,28411,28460,
+ 28510,28560,28609,28658,28706,28755,28803,28850,
+ 28898,28945,28992,29039,29085,29131,29177,29223,
+ 29268,29313,29358,29403,29447,29491,29534,29578,
+ 29621,29664,29706,29749,29791,29832,29874,29915,
+ 29956,29997,30037,30077,30117,30156,30195,30234,
+ 30273,30311,30349,30387,30424,30462,30498,30535,
+ 30571,30607,30643,30679,30714,30749,30783,30818,
+ 30852,30885,30919,30952,30985,31017,31050,31082,
+ 31113,31145,31176,31206,31237,31267,31297,31327,
+ 31356,31385,31414,31442,31470,31498,31526,31553,
+ 31580,31607,31633,31659,31685,31710,31736,31760,
+ 31785,31809,31833,31857,31880,31903,31926,31949,
+ 31971,31993,32014,32036,32057,32077,32098,32118,
+ 32137,32157,32176,32195,32213,32232,32250,32267,
+ 32285,32302,32318,32335,32351,32367,32382,32397,
+ 32412,32427,32441,32455,32469,32482,32495,32508,
+ 32521,32533,32545,32556,32567,32578,32589,32599,
+ 32609,32619,32628,32637,32646,32655,32663,32671,
+ 32678,32685,32692,32699,32705,32711,32717,32722,
+ 32728,32732,32737,32741,32745,32748,32752,32755,
+ 32757,32759,32761,32763,32765,32766,32766,32767,
+ 32767,32767,32766,32766,32765,32763,32761,32759,
+ 32757,32755,32752,32748,32745,32741,32737,32732,
+ 32728,32722,32717,32711,32705,32699,32692,32685,
+ 32678,32671,32663,32655,32646,32637,32628,32619,
+ 32609,32599,32589,32578,32567,32556,32545,32533,
+ 32521,32508,32495,32482,32469,32455,32441,32427,
+ 32412,32397,32382,32367,32351,32335,32318,32302,
+ 32285,32267,32250,32232,32213,32195,32176,32157,
+ 32137,32118,32098,32077,32057,32036,32014,31993,
+ 31971,31949,31926,31903,31880,31857,31833,31809,
+ 31785,31760,31736,31710,31685,31659,31633,31607,
+ 31580,31553,31526,31498,31470,31442,31414,31385,
+ 31356,31327,31297,31267,31237,31206,31176,31145,
+ 31113,31082,31050,31017,30985,30952,30919,30885,
+ 30852,30818,30783,30749,30714,30679,30643,30607,
+ 30571,30535,30498,30462,30424,30387,30349,30311,
+ 30273,30234,30195,30156,30117,30077,30037,29997,
+ 29956,29915,29874,29832,29791,29749,29706,29664,
+ 29621,29578,29534,29491,29447,29403,29358,29313,
+ 29268,29223,29177,29131,29085,29039,28992,28945,
+ 28898,28850,28803,28755,28706,28658,28609,28560,
+ 28510,28460,28411,28360,28310,28259,28208,28157,
+ 28105,28053,28001,27949,27896,27843,27790,27737,
+ 27683,27629,27575,27521,27466,27411,27356,27300,
+ 27245,27189,27133,27076,27019,26962,26905,26848,
+ 26790,26732,26674,26615,26556,26497,26438,26378,
+ 26319,26259,26198,26138,26077,26016,25955,25893,
+ 25832,25770,25708,25645,25582,25519,25456,25393,
+ 25329,25265,25201,25137,25072,25007,24942,24877,
+ 24811,24746,24680,24613,24547,24480,24413,24346,
+ 24279,24211,24143,24075,24007,23938,23870,23801,
+ 23731,23662,23592,23522,23452,23382,23311,23241,
+ 23170,23099,23027,22956,22884,22812,22739,22667,
+ 22594,22521,22448,22375,22301,22227,22154,22079,
+ 22005,21930,21856,21781,21705,21630,21554,21479,
+ 21403,21326,21250,21173,21096,21019,20942,20865,
+ 20787,20709,20631,20553,20475,20396,20317,20238,
+ 20159,20080,20000,19921,19841,19761,19680,19600,
+ 19519,19438,19357,19276,19195,19113,19032,18950,
+ 18868,18785,18703,18620,18537,18454,18371,18288,
+ 18204,18121,18037,17953,17869,17784,17700,17615,
+ 17530,17445,17360,17275,17189,17104,17018,16932,
+ 16846,16759,16673,16586,16499,16413,16325,16238,
+ 16151,16063,15976,15888,15800,15712,15623,15535,
+ 15446,15358,15269,15180,15090,15001,14912,14822,
+ 14732,14643,14553,14462,14372,14282,14191,14101,
+ 14010,13919,13828,13736,13645,13554,13462,13370,
+ 13279,13187,13094,13002,12910,12817,12725,12632,
+ 12539,12446,12353,12260,12167,12074,11980,11886,
+ 11793,11699,11605,11511,11417,11322,11228,11133,
+ 11039,10944,10849,10754,10659,10564,10469,10374,
+ 10278,10183,10087,9992,9896,9800,9704,9608,
+ 9512,9416,9319,9223,9126,9030,8933,8836,
+ 8739,8642,8545,8448,8351,8254,8157,8059,
+ 7962,7864,7767,7669,7571,7473,7375,7277,
+ 7179,7081,6983,6885,6786,6688,6590,6491,
+ 6393,6294,6195,6096,5998,5899,5800,5701,
+ 5602,5503,5404,5305,5205,5106,5007,4907,
+ 4808,4708,4609,4509,4410,4310,4210,4111,
+ 4011,3911,3811,3712,3612,3512,3412,3312,
+ 3212,3112,3012,2911,2811,2711,2611,2511,
+ 2410,2310,2210,2110,2009,1909,1809,1708,
+ 1608,1507,1407,1307,1206,1106,1005,905,
+ 804,704,603,503,402,302,201,101,
+ 0,-101,-201,-302,-402,-503,-603,-704,
+ -804,-905,-1005,-1106,-1206,-1307,-1407,-1507,
+ -1608,-1708,-1809,-1909,-2009,-2110,-2210,-2310,
+ -2410,-2511,-2611,-2711,-2811,-2911,-3012,-3112,
+ -3212,-3312,-3412,-3512,-3612,-3712,-3811,-3911,
+ -4011,-4111,-4210,-4310,-4410,-4509,-4609,-4708,
+ -4808,-4907,-5007,-5106,-5205,-5305,-5404,-5503,
+ -5602,-5701,-5800,-5899,-5998,-6096,-6195,-6294,
+ -6393,-6491,-6590,-6688,-6786,-6885,-6983,-7081,
+ -7179,-7277,-7375,-7473,-7571,-7669,-7767,-7864,
+ -7962,-8059,-8157,-8254,-8351,-8448,-8545,-8642,
+ -8739,-8836,-8933,-9030,-9126,-9223,-9319,-9416,
+ -9512,-9608,-9704,-9800,-9896,-9992,-10087,-10183,
+ -10278,-10374,-10469,-10564,-10659,-10754,-10849,-10944,
+ -11039,-11133,-11228,-11322,-11417,-11511,-11605,-11699,
+ -11793,-11886,-11980,-12074,-12167,-12260,-12353,-12446,
+ -12539,-12632,-12725,-12817,-12910,-13002,-13094,-13187,
+ -13279,-13370,-13462,-13554,-13645,-13736,-13828,-13919,
+ -14010,-14101,-14191,-14282,-14372,-14462,-14553,-14643,
+ -14732,-14822,-14912,-15001,-15090,-15180,-15269,-15358,
+ -15446,-15535,-15623,-15712,-15800,-15888,-15976,-16063,
+ -16151,-16238,-16325,-16413,-16499,-16586,-16673,-16759,
+ -16846,-16932,-17018,-17104,-17189,-17275,-17360,-17445,
+ -17530,-17615,-17700,-17784,-17869,-17953,-18037,-18121,
+ -18204,-18288,-18371,-18454,-18537,-18620,-18703,-18785,
+ -18868,-18950,-19032,-19113,-19195,-19276,-19357,-19438,
+ -19519,-19600,-19680,-19761,-19841,-19921,-20000,-20080,
+ -20159,-20238,-20317,-20396,-20475,-20553,-20631,-20709,
+ -20787,-20865,-20942,-21019,-21096,-21173,-21250,-21326,
+ -21403,-21479,-21554,-21630,-21705,-21781,-21856,-21930,
+ -22005,-22079,-22154,-22227,-22301,-22375,-22448,-22521,
+ -22594,-22667,-22739,-22812,-22884,-22956,-23027,-23099,
+ -23170,-23241,-23311,-23382,-23452,-23522,-23592,-23662,
+ -23731,-23801,-23870,-23938,-24007,-24075,-24143,-24211,
+ -24279,-24346,-24413,-24480,-24547,-24613,-24680,-24746,
+ -24811,-24877,-24942,-25007,-25072,-25137,-25201,-25265,
+ -25329,-25393,-25456,-25519,-25582,-25645,-25708,-25770,
+ -25832,-25893,-25955,-26016,-26077,-26138,-26198,-26259,
+ -26319,-26378,-26438,-26497,-26556,-26615,-26674,-26732,
+ -26790,-26848,-26905,-26962,-27019,-27076,-27133,-27189,
+ -27245,-27300,-27356,-27411,-27466,-27521,-27575,-27629,
+ -27683,-27737,-27790,-27843,-27896,-27949,-28001,-28053,
+ -28105,-28157,-28208,-28259,-28310,-28360,-28411,-28460,
+ -28510,-28560,-28609,-28658,-28706,-28755,-28803,-28850,
+ -28898,-28945,-28992,-29039,-29085,-29131,-29177,-29223,
+ -29268,-29313,-29358,-29403,-29447,-29491,-29534,-29578,
+ -29621,-29664,-29706,-29749,-29791,-29832,-29874,-29915,
+ -29956,-29997,-30037,-30077,-30117,-30156,-30195,-30234,
+ -30273,-30311,-30349,-30387,-30424,-30462,-30498,-30535,
+ -30571,-30607,-30643,-30679,-30714,-30749,-30783,-30818,
+ -30852,-30885,-30919,-30952,-30985,-31017,-31050,-31082,
+ -31113,-31145,-31176,-31206,-31237,-31267,-31297,-31327,
+ -31356,-31385,-31414,-31442,-31470,-31498,-31526,-31553,
+ -31580,-31607,-31633,-31659,-31685,-31710,-31736,-31760,
+ -31785,-31809,-31833,-31857,-31880,-31903,-31926,-31949,
+ -31971,-31993,-32014,-32036,-32057,-32077,-32098,-32118,
+ -32137,-32157,-32176,-32195,-32213,-32232,-32250,-32267,
+ -32285,-32302,-32318,-32335,-32351,-32367,-32382,-32397,
+ -32412,-32427,-32441,-32455,-32469,-32482,-32495,-32508,
+ -32521,-32533,-32545,-32556,-32567,-32578,-32589,-32599,
+ -32609,-32619,-32628,-32637,-32646,-32655,-32663,-32671,
+ -32678,-32685,-32692,-32699,-32705,-32711,-32717,-32722,
+ -32728,-32732,-32737,-32741,-32745,-32748,-32752,-32755,
+ -32757,-32759,-32761,-32763,-32765,-32766,-32766,-32767,
+ -32767,-32767,-32766,-32766,-32765,-32763,-32761,-32759,
+ -32757,-32755,-32752,-32748,-32745,-32741,-32737,-32732,
+ -32728,-32722,-32717,-32711,-32705,-32699,-32692,-32685,
+ -32678,-32671,-32663,-32655,-32646,-32637,-32628,-32619,
+ -32609,-32599,-32589,-32578,-32567,-32556,-32545,-32533,
+ -32521,-32508,-32495,-32482,-32469,-32455,-32441,-32427,
+ -32412,-32397,-32382,-32367,-32351,-32335,-32318,-32302,
+ -32285,-32267,-32250,-32232,-32213,-32195,-32176,-32157,
+ -32137,-32118,-32098,-32077,-32057,-32036,-32014,-31993,
+ -31971,-31949,-31926,-31903,-31880,-31857,-31833,-31809,
+ -31785,-31760,-31736,-31710,-31685,-31659,-31633,-31607,
+ -31580,-31553,-31526,-31498,-31470,-31442,-31414,-31385,
+ -31356,-31327,-31297,-31267,-31237,-31206,-31176,-31145,
+ -31113,-31082,-31050,-31017,-30985,-30952,-30919,-30885,
+ -30852,-30818,-30783,-30749,-30714,-30679,-30643,-30607,
+ -30571,-30535,-30498,-30462,-30424,-30387,-30349,-30311,
+ -30273,-30234,-30195,-30156,-30117,-30077,-30037,-29997,
+ -29956,-29915,-29874,-29832,-29791,-29749,-29706,-29664,
+ -29621,-29578,-29534,-29491,-29447,-29403,-29358,-29313,
+ -29268,-29223,-29177,-29131,-29085,-29039,-28992,-28945,
+ -28898,-28850,-28803,-28755,-28706,-28658,-28609,-28560,
+ -28510,-28460,-28411,-28360,-28310,-28259,-28208,-28157,
+ -28105,-28053,-28001,-27949,-27896,-27843,-27790,-27737,
+ -27683,-27629,-27575,-27521,-27466,-27411,-27356,-27300,
+ -27245,-27189,-27133,-27076,-27019,-26962,-26905,-26848,
+ -26790,-26732,-26674,-26615,-26556,-26497,-26438,-26378,
+ -26319,-26259,-26198,-26138,-26077,-26016,-25955,-25893,
+ -25832,-25770,-25708,-25645,-25582,-25519,-25456,-25393,
+ -25329,-25265,-25201,-25137,-25072,-25007,-24942,-24877,
+ -24811,-24746,-24680,-24613,-24547,-24480,-24413,-24346,
+ -24279,-24211,-24143,-24075,-24007,-23938,-23870,-23801,
+ -23731,-23662,-23592,-23522,-23452,-23382,-23311,-23241,
+ -23170,-23099,-23027,-22956,-22884,-22812,-22739,-22667,
+ -22594,-22521,-22448,-22375,-22301,-22227,-22154,-22079,
+ -22005,-21930,-21856,-21781,-21705,-21630,-21554,-21479,
+ -21403,-21326,-21250,-21173,-21096,-21019,-20942,-20865,
+ -20787,-20709,-20631,-20553,-20475,-20396,-20317,-20238,
+ -20159,-20080,-20000,-19921,-19841,-19761,-19680,-19600,
+ -19519,-19438,-19357,-19276,-19195,-19113,-19032,-18950,
+ -18868,-18785,-18703,-18620,-18537,-18454,-18371,-18288,
+ -18204,-18121,-18037,-17953,-17869,-17784,-17700,-17615,
+ -17530,-17445,-17360,-17275,-17189,-17104,-17018,-16932,
+ -16846,-16759,-16673,-16586,-16499,-16413,-16325,-16238,
+ -16151,-16063,-15976,-15888,-15800,-15712,-15623,-15535,
+ -15446,-15358,-15269,-15180,-15090,-15001,-14912,-14822,
+ -14732,-14643,-14553,-14462,-14372,-14282,-14191,-14101,
+ -14010,-13919,-13828,-13736,-13645,-13554,-13462,-13370,
+ -13279,-13187,-13094,-13002,-12910,-12817,-12725,-12632,
+ -12539,-12446,-12353,-12260,-12167,-12074,-11980,-11886,
+ -11793,-11699,-11605,-11511,-11417,-11322,-11228,-11133,
+ -11039,-10944,-10849,-10754,-10659,-10564,-10469,-10374,
+ -10278,-10183,-10087,-9992,-9896,-9800,-9704,-9608,
+ -9512,-9416,-9319,-9223,-9126,-9030,-8933,-8836,
+ -8739,-8642,-8545,-8448,-8351,-8254,-8157,-8059,
+ -7962,-7864,-7767,-7669,-7571,-7473,-7375,-7277,
+ -7179,-7081,-6983,-6885,-6786,-6688,-6590,-6491,
+ -6393,-6294,-6195,-6096,-5998,-5899,-5800,-5701,
+ -5602,-5503,-5404,-5305,-5205,-5106,-5007,-4907,
+ -4808,-4708,-4609,-4509,-4410,-4310,-4210,-4111,
+ -4011,-3911,-3811,-3712,-3612,-3512,-3412,-3312,
+ -3212,-3112,-3012,-2911,-2811,-2711,-2611,-2511,
+ -2410,-2310,-2210,-2110,-2009,-1909,-1809,-1708,
+ -1608,-1507,-1407,-1307,-1206,-1106,-1005,-905,
+ -804,-704,-603,-503,-402,-302,-201,-101
+};
+#endif
+
diff --git a/arm-fm-22k/lib_src/eas_ima_tables.c b/arm-fm-22k/lib_src/eas_ima_tables.c
index 56bd1eb..b03b4d4 100644
--- a/arm-fm-22k/lib_src/eas_ima_tables.c
+++ b/arm-fm-22k/lib_src/eas_ima_tables.c
@@ -1,12 +1,12 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_ima_tables.c
- *
- * Contents and purpose:
- * Contains the constant tables for IMA encode/decode
- *
- * Copyright (c) 2005 Sonic Network Inc.
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_ima_tables.c
+ *
+ * Contents and purpose:
+ * Contains the constant tables for IMA encode/decode
+ *
+ * Copyright (c) 2005 Sonic Network Inc.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,36 +19,36 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 760 $
- * $Date: 2007-07-17 23:09:36 -0700 (Tue, 17 Jul 2007) $
- *----------------------------------------------------------------------------
-*/
-
-#include "eas_types.h"
-
-/*----------------------------------------------------------------------------
- * ADPCM decode tables
- *----------------------------------------------------------------------------
-*/
-const EAS_I16 imaIndexTable[16] =
-{
- -1, -1, -1, -1, 2, 4, 6, 8,
- -1, -1, -1, -1, 2, 4, 6, 8
-};
-
-const EAS_I16 imaStepSizeTable[89] =
-{
- 7, 8, 9, 10, 11, 12, 13, 14, 16, 17,
- 19, 21, 23, 25, 28, 31, 34, 37, 41, 45,
- 50, 55, 60, 66, 73, 80, 88, 97, 107, 118,
- 130, 143, 157, 173, 190, 209, 230, 253, 279, 307,
- 337, 371, 408, 449, 494, 544, 598, 658, 724, 796,
- 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066,
- 2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358,
- 5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,
- 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767
-};
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 760 $
+ * $Date: 2007-07-17 23:09:36 -0700 (Tue, 17 Jul 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+#include "eas_types.h"
+
+/*----------------------------------------------------------------------------
+ * ADPCM decode tables
+ *----------------------------------------------------------------------------
+*/
+const EAS_I16 imaIndexTable[16] =
+{
+ -1, -1, -1, -1, 2, 4, 6, 8,
+ -1, -1, -1, -1, 2, 4, 6, 8
+};
+
+const EAS_I16 imaStepSizeTable[89] =
+{
+ 7, 8, 9, 10, 11, 12, 13, 14, 16, 17,
+ 19, 21, 23, 25, 28, 31, 34, 37, 41, 45,
+ 50, 55, 60, 66, 73, 80, 88, 97, 107, 118,
+ 130, 143, 157, 173, 190, 209, 230, 253, 279, 307,
+ 337, 371, 408, 449, 494, 544, 598, 658, 724, 796,
+ 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066,
+ 2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358,
+ 5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,
+ 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767
+};
+
diff --git a/arm-fm-22k/lib_src/eas_imaadpcm.c b/arm-fm-22k/lib_src/eas_imaadpcm.c
index 68bf257..41280b5 100644
--- a/arm-fm-22k/lib_src/eas_imaadpcm.c
+++ b/arm-fm-22k/lib_src/eas_imaadpcm.c
@@ -1,12 +1,12 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_imaadpcm.c
- *
- * Contents and purpose:
- * Implements the IMA ADPCM decoder
- *
- * Copyright Sonic Network Inc. 2005
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_imaadpcm.c
+ *
+ * Contents and purpose:
+ * Implements the IMA ADPCM decoder
+ *
+ * Copyright Sonic Network Inc. 2005
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,350 +19,350 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 847 $
- * $Date: 2007-08-27 21:30:08 -0700 (Mon, 27 Aug 2007) $
- *----------------------------------------------------------------------------
-*/
-
-#include "eas_data.h"
-#include "eas_host.h"
-#include "eas_pcm.h"
-#include "eas_math.h"
-#include "eas_report.h"
-
-// #define _DEBUG_IMA_ADPCM_LOCATE
-
-/*----------------------------------------------------------------------------
- * externs
- *----------------------------------------------------------------------------
-*/
-extern const EAS_I16 imaIndexTable[];
-extern const EAS_I16 imaStepSizeTable[];
-
-/*----------------------------------------------------------------------------
- * prototypes
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT IMADecoderInit (EAS_DATA_HANDLE pEASData, S_PCM_STATE *pState);
-static EAS_RESULT IMADecoderSample (EAS_DATA_HANDLE pEASData, S_PCM_STATE *pState);
-static void IMADecoderADPCM (S_DECODER_STATE *pState, EAS_U8 nibble);
-static EAS_RESULT IMADecoderLocate (EAS_DATA_HANDLE pEASData, S_PCM_STATE *pState, EAS_I32 time);
-
-/*----------------------------------------------------------------------------
- * IMA ADPCM Decoder interface
- *----------------------------------------------------------------------------
-*/
-const S_DECODER_INTERFACE IMADecoder =
-{
- IMADecoderInit,
- IMADecoderSample,
- IMADecoderLocate
-};
-
-/*----------------------------------------------------------------------------
- * IMADecoderInit()
- *----------------------------------------------------------------------------
- * Purpose:
- * Initializes the IMA ADPCM decoder
- *
- * Inputs:
- *
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, pEASData) common decoder interface - pEASData not used */
-static EAS_RESULT IMADecoderInit (EAS_DATA_HANDLE pEASData, S_PCM_STATE *pState)
-{
- pState->decoderL.step = 0;
- pState->decoderR.step = 0;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * IMADecoderSample()
- *----------------------------------------------------------------------------
- * Purpose:
- * Decodes an IMA ADPCM sample
- *
- * Inputs:
- *
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT IMADecoderSample (EAS_DATA_HANDLE pEASData, S_PCM_STATE *pState)
-{
- EAS_RESULT result;
- EAS_I16 sTemp;
-
- /* if high nibble, decode */
- if (pState->hiNibble)
- {
- IMADecoderADPCM(&pState->decoderL, (EAS_U8)(pState->srcByte >> 4));
- pState->hiNibble = EAS_FALSE;
- }
-
- /* low nibble, need to fetch another byte */
- else
- {
- /* check for loop */
- if ((pState->bytesLeft == 0) && (pState->loopSamples != 0))
- {
- /* seek to start of loop */
- if ((result = EAS_HWFileSeek(pEASData->hwInstData, pState->fileHandle, (EAS_I32) (pState->startPos + pState->loopLocation))) != EAS_SUCCESS)
- return result;
- pState->bytesLeft = pState->byteCount = (EAS_I32) pState->bytesLeftLoop;
- pState->blockCount = 0;
- pState->flags &= ~PCM_FLAGS_EMPTY;
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMADecoderSample: Rewind file to %d, bytesLeft = %d\n", pState->startPos, pState->bytesLeft); */ }
- }
-
- /* if start of block, fetch new predictor and step index */
- if ((pState->blockSize != 0) && (pState->blockCount == 0) && (pState->bytesLeft != 0))
- {
-
- /* get predicted sample for left channel */
- if ((result = EAS_HWGetWord(pEASData->hwInstData, pState->fileHandle, &sTemp, EAS_FALSE)) != EAS_SUCCESS)
- return result;
-#ifdef _DEBUG_IMA_ADPCM
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Predictor: Was %d, now %d\n", pState->decoderL.acc, sTemp); */ }
-#endif
- pState->decoderL.acc = pState->decoderL.x1 = sTemp;
-
- /* get step index for left channel - upper 8 bits are reserved */
- if ((result = EAS_HWGetWord(pEASData->hwInstData, pState->fileHandle, &sTemp, EAS_FALSE)) != EAS_SUCCESS)
- return result;
-#ifdef _DEBUG_IMA_ADPCM
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Step: Was %d, now %d\n", pState->decoderL.step, sTemp); */ }
-#endif
- pState->decoderL.step = sTemp & 0xff;
-
- if (pState->flags & PCM_FLAGS_STEREO)
- {
- /* get predicted sample for right channel */
- if ((result = EAS_HWGetWord(pEASData->hwInstData, pState->fileHandle, &sTemp, EAS_FALSE)) != EAS_SUCCESS)
- return result;
- pState->decoderR.acc = pState->decoderR.x1 = sTemp;
-
- /* get step index for right channel - upper 8 bits are reserved */
- if ((result = EAS_HWGetWord(pEASData->hwInstData, pState->fileHandle, &sTemp, EAS_FALSE)) != EAS_SUCCESS)
- return result;
-#ifdef _DEBUG_IMA_ADPCM
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Step: Was %d, now %d\n", pState->decoderR.step, sTemp); */ }
-#endif
- pState->decoderR.step = sTemp & 0xff;
-
- pState->blockCount = pState->blockSize - 8;
- pState->bytesLeft -= 8;
- }
- else
- {
- pState->blockCount = pState->blockSize - 4;
- pState->bytesLeft -= 4;
- }
- }
- else
- {
-
- /* get another ADPCM data pair */
- if (pState->bytesLeft)
- {
-
- if ((result = EAS_HWGetByte(pEASData->hwInstData, pState->fileHandle, &pState->srcByte)) != EAS_SUCCESS)
- return result;
-
- /* decode the low nibble */
- pState->bytesLeft--;
- pState->blockCount--;
- IMADecoderADPCM(&pState->decoderL, (EAS_U8)(pState->srcByte & 0x0f));
-
- if (pState->flags & PCM_FLAGS_STEREO)
- IMADecoderADPCM(&pState->decoderR, (EAS_U8)(pState->srcByte >> 4));
- else
- pState->hiNibble = EAS_TRUE;
- }
-
- /* out of ADPCM data, generate enough samples to fill buffer */
- else
- {
- pState->decoderL.x1 = pState->decoderL.x0;
- pState->decoderR.x1 = pState->decoderR.x0;
- }
- }
- }
-
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * IMADecoderADPCM()
- *----------------------------------------------------------------------------
- * Purpose:
- * Decodes an IMA ADPCM sample
- *
- * Inputs:
- *
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static void IMADecoderADPCM (S_DECODER_STATE *pState, EAS_U8 nibble)
-{
- EAS_INT delta;
- EAS_INT stepSize;
-
- /* get stepsize from table */
- stepSize = imaStepSizeTable[pState->step];
-
- /* delta = (abs(delta) + 0.5) * step / 4 */
- delta = 0;
- if (nibble & 4)
- delta += stepSize;
-
- if (nibble & 2)
- /*lint -e{702} use shift for performance */
- delta += stepSize >> 1;
-
- if (nibble & 1)
- /*lint -e{702} use shift for performance */
- delta += stepSize >> 2;
-
- /*lint -e{702} use shift for performance */
- delta += stepSize >> 3;
-
- /* integrate the delta */
- if (nibble & 8)
- pState->acc -= delta;
- else
- pState->acc += delta;
-
- /* saturate */
- if (pState->acc > 32767)
- pState->acc = 32767;
- if (pState->acc < -32768)
- pState->acc = -32768;
- pState->x1 = (EAS_PCM) pState->acc;
-
- /* compute new step size */
- pState->step += imaIndexTable[nibble];
- if (pState->step < 0)
- pState->step = 0;
- if (pState->step > 88)
- pState->step = 88;
-
-#ifdef _DEBUG_IMA_ADPCM
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "In=%u, Pred=%d, Step=%d\n", nibble, pState->acc, imaStepSizeTable[pState->step]); */ }
-#endif
-}
-
-/*----------------------------------------------------------------------------
- * IMADecoderLocate()
- *----------------------------------------------------------------------------
- * Locate in an IMA ADPCM stream
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT IMADecoderLocate (EAS_DATA_HANDLE pEASData, S_PCM_STATE *pState, EAS_I32 time)
-{
- EAS_RESULT result;
- EAS_I32 temp;
- EAS_I32 samplesPerBlock;
- EAS_I32 secs, msecs;
-
- /* no need to calculate if time is zero */
- if (time == 0)
- temp = 0;
-
- /* not zero */
- else
- {
-
- /* can't seek if not a blocked file */
- if (pState->blockSize == 0)
- return EAS_ERROR_FEATURE_NOT_AVAILABLE;
-
- /* calculate number of samples per block */
- if (pState->flags & PCM_FLAGS_STEREO)
- samplesPerBlock = pState->blockSize - 7;
- else
- samplesPerBlock = (pState->blockSize << 1) - 7;
-
- /* break down into secs and msecs */
- secs = time / 1000;
- msecs = time - (secs * 1000);
-
- /* calculate sample number fraction from msecs */
- temp = (msecs * pState->sampleRate);
- temp = (temp >> 10) + ((temp * 49) >> 21);
-
- /* add integer sample count */
- temp += secs * pState->sampleRate;
-
-#ifdef _DEBUG_IMA_ADPCM_LOCATE
- EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x2380b977, 0x00000006 , time, temp);
-#endif
-
- /* for looped samples, calculate position in the loop */
- if ((temp > pState->byteCount) && (pState->loopSamples != 0))
- {
- EAS_I32 numBlocks;
- EAS_I32 samplesPerLoop;
- EAS_I32 samplesInLastBlock;
-
- numBlocks = (EAS_I32) (pState->loopStart / pState->blockSize);
- samplesInLastBlock = (EAS_I32) pState->loopStart - (numBlocks * pState->blockSize);
- if (samplesInLastBlock)
- {
- if (pState->flags & PCM_FLAGS_STEREO)
- samplesInLastBlock = samplesInLastBlock - 7;
- else
- /*lint -e{703} use shift for performance */
- samplesInLastBlock = (samplesInLastBlock << 1) - 7;
- }
- samplesPerLoop = numBlocks * samplesPerBlock + samplesInLastBlock;
- temp = temp % samplesPerLoop;
-#ifdef _DEBUG_IMA_ADPCM_LOCATE
- EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x2380b977, 0x00000007 , numBlocks, samplesPerLoop, samplesInLastBlock, temp);
-#endif
- }
-
- /* find start of block for requested sample */
- temp = (temp / samplesPerBlock) * pState->blockSize;
-#ifdef _DEBUG_IMA_ADPCM_LOCATE
- EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x2380b977, 0x00000008 , temp);
-#endif
-
- }
-
- /* seek to new location */
- if ((result = EAS_PESeek(pEASData, pState, &temp)) != EAS_SUCCESS)
- return result;
-
-#ifdef _DEBUG_IMA_ADPCM_LOCATE
- EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x2380b977, 0x00000009 , pState->bytesLeft);
-#endif
-
- /* reset state */
- pState->blockCount = 0;
- pState->hiNibble = EAS_FALSE;
- if ((pState->state != EAS_STATE_PAUSING) && (pState->state != EAS_STATE_PAUSED))
- pState->state = EAS_STATE_READY;
-
- return EAS_SUCCESS;
-}
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 847 $
+ * $Date: 2007-08-27 21:30:08 -0700 (Mon, 27 Aug 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+#include "eas_data.h"
+#include "eas_host.h"
+#include "eas_pcm.h"
+#include "eas_math.h"
+#include "eas_report.h"
+
+// #define _DEBUG_IMA_ADPCM_LOCATE
+
+/*----------------------------------------------------------------------------
+ * externs
+ *----------------------------------------------------------------------------
+*/
+extern const EAS_I16 imaIndexTable[];
+extern const EAS_I16 imaStepSizeTable[];
+
+/*----------------------------------------------------------------------------
+ * prototypes
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT IMADecoderInit (EAS_DATA_HANDLE pEASData, S_PCM_STATE *pState);
+static EAS_RESULT IMADecoderSample (EAS_DATA_HANDLE pEASData, S_PCM_STATE *pState);
+static void IMADecoderADPCM (S_DECODER_STATE *pState, EAS_U8 nibble);
+static EAS_RESULT IMADecoderLocate (EAS_DATA_HANDLE pEASData, S_PCM_STATE *pState, EAS_I32 time);
+
+/*----------------------------------------------------------------------------
+ * IMA ADPCM Decoder interface
+ *----------------------------------------------------------------------------
+*/
+const S_DECODER_INTERFACE IMADecoder =
+{
+ IMADecoderInit,
+ IMADecoderSample,
+ IMADecoderLocate
+};
+
+/*----------------------------------------------------------------------------
+ * IMADecoderInit()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Initializes the IMA ADPCM decoder
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pEASData) common decoder interface - pEASData not used */
+static EAS_RESULT IMADecoderInit (EAS_DATA_HANDLE pEASData, S_PCM_STATE *pState)
+{
+ pState->decoderL.step = 0;
+ pState->decoderR.step = 0;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * IMADecoderSample()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Decodes an IMA ADPCM sample
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT IMADecoderSample (EAS_DATA_HANDLE pEASData, S_PCM_STATE *pState)
+{
+ EAS_RESULT result;
+ EAS_I16 sTemp;
+
+ /* if high nibble, decode */
+ if (pState->hiNibble)
+ {
+ IMADecoderADPCM(&pState->decoderL, (EAS_U8)(pState->srcByte >> 4));
+ pState->hiNibble = EAS_FALSE;
+ }
+
+ /* low nibble, need to fetch another byte */
+ else
+ {
+ /* check for loop */
+ if ((pState->bytesLeft == 0) && (pState->loopSamples != 0))
+ {
+ /* seek to start of loop */
+ if ((result = EAS_HWFileSeek(pEASData->hwInstData, pState->fileHandle, (EAS_I32) (pState->startPos + pState->loopLocation))) != EAS_SUCCESS)
+ return result;
+ pState->bytesLeft = pState->byteCount = (EAS_I32) pState->bytesLeftLoop;
+ pState->blockCount = 0;
+ pState->flags &= ~PCM_FLAGS_EMPTY;
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMADecoderSample: Rewind file to %d, bytesLeft = %d\n", pState->startPos, pState->bytesLeft); */ }
+ }
+
+ /* if start of block, fetch new predictor and step index */
+ if ((pState->blockSize != 0) && (pState->blockCount == 0) && (pState->bytesLeft != 0))
+ {
+
+ /* get predicted sample for left channel */
+ if ((result = EAS_HWGetWord(pEASData->hwInstData, pState->fileHandle, &sTemp, EAS_FALSE)) != EAS_SUCCESS)
+ return result;
+#ifdef _DEBUG_IMA_ADPCM
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Predictor: Was %d, now %d\n", pState->decoderL.acc, sTemp); */ }
+#endif
+ pState->decoderL.acc = pState->decoderL.x1 = sTemp;
+
+ /* get step index for left channel - upper 8 bits are reserved */
+ if ((result = EAS_HWGetWord(pEASData->hwInstData, pState->fileHandle, &sTemp, EAS_FALSE)) != EAS_SUCCESS)
+ return result;
+#ifdef _DEBUG_IMA_ADPCM
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Step: Was %d, now %d\n", pState->decoderL.step, sTemp); */ }
+#endif
+ pState->decoderL.step = sTemp & 0xff;
+
+ if (pState->flags & PCM_FLAGS_STEREO)
+ {
+ /* get predicted sample for right channel */
+ if ((result = EAS_HWGetWord(pEASData->hwInstData, pState->fileHandle, &sTemp, EAS_FALSE)) != EAS_SUCCESS)
+ return result;
+ pState->decoderR.acc = pState->decoderR.x1 = sTemp;
+
+ /* get step index for right channel - upper 8 bits are reserved */
+ if ((result = EAS_HWGetWord(pEASData->hwInstData, pState->fileHandle, &sTemp, EAS_FALSE)) != EAS_SUCCESS)
+ return result;
+#ifdef _DEBUG_IMA_ADPCM
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Step: Was %d, now %d\n", pState->decoderR.step, sTemp); */ }
+#endif
+ pState->decoderR.step = sTemp & 0xff;
+
+ pState->blockCount = pState->blockSize - 8;
+ pState->bytesLeft -= 8;
+ }
+ else
+ {
+ pState->blockCount = pState->blockSize - 4;
+ pState->bytesLeft -= 4;
+ }
+ }
+ else
+ {
+
+ /* get another ADPCM data pair */
+ if (pState->bytesLeft)
+ {
+
+ if ((result = EAS_HWGetByte(pEASData->hwInstData, pState->fileHandle, &pState->srcByte)) != EAS_SUCCESS)
+ return result;
+
+ /* decode the low nibble */
+ pState->bytesLeft--;
+ pState->blockCount--;
+ IMADecoderADPCM(&pState->decoderL, (EAS_U8)(pState->srcByte & 0x0f));
+
+ if (pState->flags & PCM_FLAGS_STEREO)
+ IMADecoderADPCM(&pState->decoderR, (EAS_U8)(pState->srcByte >> 4));
+ else
+ pState->hiNibble = EAS_TRUE;
+ }
+
+ /* out of ADPCM data, generate enough samples to fill buffer */
+ else
+ {
+ pState->decoderL.x1 = pState->decoderL.x0;
+ pState->decoderR.x1 = pState->decoderR.x0;
+ }
+ }
+ }
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * IMADecoderADPCM()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Decodes an IMA ADPCM sample
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static void IMADecoderADPCM (S_DECODER_STATE *pState, EAS_U8 nibble)
+{
+ EAS_INT delta;
+ EAS_INT stepSize;
+
+ /* get stepsize from table */
+ stepSize = imaStepSizeTable[pState->step];
+
+ /* delta = (abs(delta) + 0.5) * step / 4 */
+ delta = 0;
+ if (nibble & 4)
+ delta += stepSize;
+
+ if (nibble & 2)
+ /*lint -e{702} use shift for performance */
+ delta += stepSize >> 1;
+
+ if (nibble & 1)
+ /*lint -e{702} use shift for performance */
+ delta += stepSize >> 2;
+
+ /*lint -e{702} use shift for performance */
+ delta += stepSize >> 3;
+
+ /* integrate the delta */
+ if (nibble & 8)
+ pState->acc -= delta;
+ else
+ pState->acc += delta;
+
+ /* saturate */
+ if (pState->acc > 32767)
+ pState->acc = 32767;
+ if (pState->acc < -32768)
+ pState->acc = -32768;
+ pState->x1 = (EAS_PCM) pState->acc;
+
+ /* compute new step size */
+ pState->step += imaIndexTable[nibble];
+ if (pState->step < 0)
+ pState->step = 0;
+ if (pState->step > 88)
+ pState->step = 88;
+
+#ifdef _DEBUG_IMA_ADPCM
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "In=%u, Pred=%d, Step=%d\n", nibble, pState->acc, imaStepSizeTable[pState->step]); */ }
+#endif
+}
+
+/*----------------------------------------------------------------------------
+ * IMADecoderLocate()
+ *----------------------------------------------------------------------------
+ * Locate in an IMA ADPCM stream
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT IMADecoderLocate (EAS_DATA_HANDLE pEASData, S_PCM_STATE *pState, EAS_I32 time)
+{
+ EAS_RESULT result;
+ EAS_I32 temp;
+ EAS_I32 samplesPerBlock;
+ EAS_I32 secs, msecs;
+
+ /* no need to calculate if time is zero */
+ if (time == 0)
+ temp = 0;
+
+ /* not zero */
+ else
+ {
+
+ /* can't seek if not a blocked file */
+ if (pState->blockSize == 0)
+ return EAS_ERROR_FEATURE_NOT_AVAILABLE;
+
+ /* calculate number of samples per block */
+ if (pState->flags & PCM_FLAGS_STEREO)
+ samplesPerBlock = pState->blockSize - 7;
+ else
+ samplesPerBlock = (pState->blockSize << 1) - 7;
+
+ /* break down into secs and msecs */
+ secs = time / 1000;
+ msecs = time - (secs * 1000);
+
+ /* calculate sample number fraction from msecs */
+ temp = (msecs * pState->sampleRate);
+ temp = (temp >> 10) + ((temp * 49) >> 21);
+
+ /* add integer sample count */
+ temp += secs * pState->sampleRate;
+
+#ifdef _DEBUG_IMA_ADPCM_LOCATE
+ EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x2380b977, 0x00000006 , time, temp);
+#endif
+
+ /* for looped samples, calculate position in the loop */
+ if ((temp > pState->byteCount) && (pState->loopSamples != 0))
+ {
+ EAS_I32 numBlocks;
+ EAS_I32 samplesPerLoop;
+ EAS_I32 samplesInLastBlock;
+
+ numBlocks = (EAS_I32) (pState->loopStart / pState->blockSize);
+ samplesInLastBlock = (EAS_I32) pState->loopStart - (numBlocks * pState->blockSize);
+ if (samplesInLastBlock)
+ {
+ if (pState->flags & PCM_FLAGS_STEREO)
+ samplesInLastBlock = samplesInLastBlock - 7;
+ else
+ /*lint -e{703} use shift for performance */
+ samplesInLastBlock = (samplesInLastBlock << 1) - 7;
+ }
+ samplesPerLoop = numBlocks * samplesPerBlock + samplesInLastBlock;
+ temp = temp % samplesPerLoop;
+#ifdef _DEBUG_IMA_ADPCM_LOCATE
+ EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x2380b977, 0x00000007 , numBlocks, samplesPerLoop, samplesInLastBlock, temp);
+#endif
+ }
+
+ /* find start of block for requested sample */
+ temp = (temp / samplesPerBlock) * pState->blockSize;
+#ifdef _DEBUG_IMA_ADPCM_LOCATE
+ EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x2380b977, 0x00000008 , temp);
+#endif
+
+ }
+
+ /* seek to new location */
+ if ((result = EAS_PESeek(pEASData, pState, &temp)) != EAS_SUCCESS)
+ return result;
+
+#ifdef _DEBUG_IMA_ADPCM_LOCATE
+ EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x2380b977, 0x00000009 , pState->bytesLeft);
+#endif
+
+ /* reset state */
+ pState->blockCount = 0;
+ pState->hiNibble = EAS_FALSE;
+ if ((pState->state != EAS_STATE_PAUSING) && (pState->state != EAS_STATE_PAUSED))
+ pState->state = EAS_STATE_READY;
+
+ return EAS_SUCCESS;
+}
+
diff --git a/arm-fm-22k/lib_src/eas_imelody.c b/arm-fm-22k/lib_src/eas_imelody.c
index 9f4d541..698c7df 100644
--- a/arm-fm-22k/lib_src/eas_imelody.c
+++ b/arm-fm-22k/lib_src/eas_imelody.c
@@ -1,12 +1,12 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_imelody.c
- *
- * Contents and purpose:
- * iMelody parser
- *
- * Copyright Sonic Network Inc. 2005
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_imelody.c
+ *
+ * Contents and purpose:
+ * iMelody parser
+ *
+ * Copyright Sonic Network Inc. 2005
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,1720 +19,1720 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 797 $
- * $Date: 2007-08-01 00:15:56 -0700 (Wed, 01 Aug 2007) $
- *----------------------------------------------------------------------------
-*/
-
-/* lint doesn't like the way some string.h files look */
-#ifdef _lint
-#include "lint_stdlib.h"
-#else
-#include <string.h>
-#endif
-
-#include "eas_data.h"
-#include "eas_miditypes.h"
-#include "eas_parser.h"
-#include "eas_report.h"
-#include "eas_host.h"
-#include "eas_midi.h"
-#include "eas_config.h"
-#include "eas_vm_protos.h"
-#include "eas_imelodydata.h"
-#include "eas_ctype.h"
-
-// #define _DEBUG_IMELODY
-
-/* increase gain for mono ringtones */
-#define IMELODY_GAIN_OFFSET 8
-
-/* length of 32nd note in 1/256ths of a msec for 120 BPM tempo */
-#define DEFAULT_TICK_CONV 16000
-#define TICK_CONVERT 1920000
-
-/* default channel and program for iMelody playback */
-#define IMELODY_CHANNEL 0
-#define IMELODY_PROGRAM 80
-#define IMELODY_VEL_MUL 4
-#define IMELODY_VEL_OFS 67
-
-/* multiplier for fixed point triplet conversion */
-#define TRIPLET_MULTIPLIER 683
-#define TRIPLET_SHIFT 10
-
-static const char* const tokens[] =
-{
- "BEGIN:IMELODY",
- "VERSION:",
- "FORMAT:CLASS",
- "NAME:",
- "COMPOSER:",
- "BEAT:",
- "STYLE:",
- "VOLUME:",
- "MELODY:",
- "END:IMELODY"
-};
-
-/* ledon or ledoff */
-static const char ledStr[] = "edo";
-
-/* vibeon or vibeoff */
-static const char vibeStr[] = "ibeo";
-
-/* backon or backoff */
-static const char backStr[] = "cko";
-
-typedef enum
-{
- TOKEN_BEGIN,
- TOKEN_VERSION,
- TOKEN_FORMAT,
- TOKEN_NAME,
- TOKEN_COMPOSER,
- TOKEN_BEAT,
- TOKEN_STYLE,
- TOKEN_VOLUME,
- TOKEN_MELODY,
- TOKEN_END,
- TOKEN_INVALID
-} ENUM_IMELODY_TOKENS;
-
-/* lookup table for note values */
-static const EAS_I8 noteTable[] = { 9, 11, 0, 2, 4, 5, 7 };
-
-/* inline functions */
-#ifdef _DEBUG_IMELODY
-static void PutBackChar (S_IMELODY_DATA *pData)
-{
- if (pData->index)
- pData->index--;
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "PutBackChar '%c'\n", pData->buffer[pData->index]); */ }
-}
-#else
-EAS_INLINE void PutBackChar (S_IMELODY_DATA *pData) { if (pData->index) pData->index--; }
-#endif
-
-
-/* local prototypes */
-static EAS_RESULT IMY_CheckFileType (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle, EAS_VOID_PTR *ppHandle, EAS_I32 offset);
-static EAS_RESULT IMY_Prepare (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
-static EAS_RESULT IMY_Time (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_U32 *pTime);
-static EAS_RESULT IMY_Event (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_INT parserMode);
-static EAS_RESULT IMY_State (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_STATE *pState);
-static EAS_RESULT IMY_Close (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
-static EAS_RESULT IMY_Reset (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
-static EAS_RESULT IMY_Pause (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
-static EAS_RESULT IMY_Resume (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
-static EAS_RESULT IMY_SetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value);
-static EAS_RESULT IMY_GetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue);
-static EAS_BOOL IMY_PlayNote (S_EAS_DATA *pEASData, S_IMELODY_DATA *pData, EAS_I8 note, EAS_INT parserMode);
-static EAS_BOOL IMY_PlayRest (S_EAS_DATA *pEASData, S_IMELODY_DATA *pData);
-static EAS_BOOL IMY_GetDuration (EAS_HW_DATA_HANDLE hwInstData, S_IMELODY_DATA *pData, EAS_I32 *pDuration);
-static EAS_BOOL IMY_GetLEDState (S_EAS_DATA *pEASData, S_IMELODY_DATA *pData);
-static EAS_BOOL IMY_GetVibeState (S_EAS_DATA *pEASData, S_IMELODY_DATA *pData);
-static EAS_BOOL IMY_GetBackState (S_EAS_DATA *pEASData, S_IMELODY_DATA *pData);
-static EAS_BOOL IMY_GetVolume (EAS_HW_DATA_HANDLE hwInstData, S_IMELODY_DATA *pData, EAS_BOOL inHeader);
-static EAS_BOOL IMY_GetNumber (EAS_HW_DATA_HANDLE hwInstData, S_IMELODY_DATA *pData, EAS_INT *temp, EAS_BOOL inHeader);
-static EAS_RESULT IMY_ParseHeader (S_EAS_DATA *pEASData, S_IMELODY_DATA* pData);
-static EAS_I8 IMY_GetNextChar (EAS_HW_DATA_HANDLE hwInstData, S_IMELODY_DATA *pData, EAS_BOOL inHeader);
-static EAS_RESULT IMY_ReadLine (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE fileHandle, EAS_I8 *buffer, EAS_I32 *pStartLine);
-static EAS_INT IMY_ParseLine (EAS_I8 *buffer, EAS_U8 *pIndex);
-
-
-/*----------------------------------------------------------------------------
- *
- * EAS_iMelody_Parser
- *
- * This structure contains the functional interface for the iMelody parser
- *----------------------------------------------------------------------------
-*/
-const S_FILE_PARSER_INTERFACE EAS_iMelody_Parser =
-{
- IMY_CheckFileType,
- IMY_Prepare,
- IMY_Time,
- IMY_Event,
- IMY_State,
- IMY_Close,
- IMY_Reset,
- IMY_Pause,
- IMY_Resume,
- NULL,
- IMY_SetData,
- IMY_GetData,
- NULL
-};
-
-/*----------------------------------------------------------------------------
- * IMY_CheckFileType()
- *----------------------------------------------------------------------------
- * Purpose:
- * Check the file type to see if we can parse it
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT IMY_CheckFileType (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle, EAS_VOID_PTR *ppHandle, EAS_I32 offset)
-{
- S_IMELODY_DATA* pData;
- EAS_I8 buffer[MAX_LINE_SIZE+1];
- EAS_U8 index;
-
-#ifdef _DEBUG_IMELODY
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Enter IMY_CheckFileType\n"); */ }
-#endif
-
- /* read the first line of the file */
- *ppHandle = NULL;
- if (IMY_ReadLine(pEASData->hwInstData, fileHandle, buffer, NULL) != EAS_SUCCESS)
- return EAS_SUCCESS;
-
- /* check for header string */
- if (IMY_ParseLine(buffer, &index) == TOKEN_BEGIN)
- {
-
- /* check for static memory allocation */
- if (pEASData->staticMemoryModel)
- pData = EAS_CMEnumData(EAS_CM_IMELODY_DATA);
- else
- pData = EAS_HWMalloc(pEASData->hwInstData, sizeof(S_IMELODY_DATA));
- if (!pData)
- return EAS_ERROR_MALLOC_FAILED;
- EAS_HWMemSet(pData, 0, sizeof(S_IMELODY_DATA));
-
- /* initialize */
- pData->fileHandle = fileHandle;
- pData->fileOffset = offset;
- pData->state = EAS_STATE_ERROR;
- pData->state = EAS_STATE_OPEN;
-
- /* return a pointer to the instance data */
- *ppHandle = pData;
- }
-
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * IMY_Prepare()
- *----------------------------------------------------------------------------
- * Purpose:
- * Prepare to parse the file. Allocates instance data (or uses static allocation for
- * static memory model).
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT IMY_Prepare (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
-{
- S_IMELODY_DATA* pData;
- EAS_RESULT result;
-
-#ifdef _DEBUG_IMELODY
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Enter IMY_Prepare\n"); */ }
-#endif
-
- /* check for valid state */
- pData = (S_IMELODY_DATA*) pInstData;
- if (pData->state != EAS_STATE_OPEN)
- return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
-
- /* instantiate a synthesizer */
- if ((result = VMInitMIDI(pEASData, &pData->pSynth)) != EAS_SUCCESS)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "VMInitMIDI returned %d\n", result); */ }
- return result;
- }
-
- /* parse the header */
- if ((result = IMY_ParseHeader(pEASData, pData)) != EAS_SUCCESS)
- return result;
-
-#ifdef _DEBUG_IMELODY
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_Prepare: state set to EAS_STATE_READY\n"); */ }
-#endif
-
- pData ->state = EAS_STATE_READY;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * IMY_Time()
- *----------------------------------------------------------------------------
- * Purpose:
- * Returns the time of the next event in msecs
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- * pTime - pointer to variable to hold time of next event (in msecs)
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, pEASData) common decoder interface - pEASData not used */
-static EAS_RESULT IMY_Time (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_U32 *pTime)
-{
- S_IMELODY_DATA *pData;
-
- pData = (S_IMELODY_DATA*) pInstData;
-
- /* return time in milliseconds */
- /*lint -e{704} use shift instead of division */
- *pTime = pData->time >> 8;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * IMY_Event()
- *----------------------------------------------------------------------------
- * Purpose:
- * Parse the next event in the file
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT IMY_Event (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_INT parserMode)
-{
- S_IMELODY_DATA* pData;
- EAS_RESULT result;
- EAS_I8 c;
- EAS_BOOL eof;
- EAS_INT temp;
-
- pData = (S_IMELODY_DATA*) pInstData;
- if (pData->state >= EAS_STATE_OPEN)
- return EAS_SUCCESS;
-
- /* initialize MIDI channel when the track starts playing */
- if (pData->time == 0)
- {
-
-#ifdef _DEBUG_IMELODY
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_Event: Reset\n"); */ }
-#endif
- /* set program to square lead */
- VMProgramChange(pEASData->pVoiceMgr, pData->pSynth, IMELODY_CHANNEL, IMELODY_PROGRAM);
-
- /* set channel volume to max */
- VMControlChange(pEASData->pVoiceMgr, pData->pSynth, IMELODY_CHANNEL, 7, 127);
- }
-
- /* check for end of note */
- if (pData->note)
- {
-
-#ifdef _DEBUG_IMELODY
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Stopping note %d\n", pData->note); */ }
-#endif
- /* stop the note */
- VMStopNote(pEASData->pVoiceMgr, pData->pSynth, IMELODY_CHANNEL, pData->note, 0);
- pData->note = 0;
-
- /* check for rest between notes */
- if (pData->restTicks)
- {
- pData->time += pData->restTicks;
- pData->restTicks = 0;
- return EAS_SUCCESS;
- }
- }
-
- /* parse the next event */
- eof = EAS_FALSE;
- while (!eof)
- {
-
- /* get next character */
- c = IMY_GetNextChar(pEASData->hwInstData, pData, EAS_FALSE);
-
- switch (c)
- {
- /* start repeat */
- case '(':
-
-#ifdef _DEBUG_IMELODY
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Enter repeat section\n", c); */ }
-#endif
-
- if (pData->repeatOffset < 0)
- {
- pData->repeatOffset = pData->startLine + (EAS_I32) pData->index;
-
-#ifdef _DEBUG_IMELODY
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Repeat offset = %d\n", pData->repeatOffset); */ }
-#endif
- }
- else
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Ignoring nested repeat section\n"); */ }
- break;
-
- /* end repeat */
- case ')':
-
-#ifdef _DEBUG_IMELODY
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "End repeat section, repeat offset = %d\n", pData->repeatOffset); */ }
-#endif
- /* ignore invalid repeats */
- if (pData->repeatCount >= 0)
- {
-
- /* decrement repeat count (repeatCount == 0 means infinite loop) */
- if (pData->repeatCount > 0)
- {
- if (--pData->repeatCount == 0)
- {
- pData->repeatCount = -1;
-#ifdef _DEBUG_IMELODY
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Repeat loop complete\n"); */ }
-#endif
- }
- }
-
-//2 TEMPORARY FIX: If locating, don't do infinite loops.
-//3 We need a different mode for metadata parsing where we don't loop at all
- if ((parserMode == eParserModePlay) || (pData->repeatCount != 0))
- {
-
-#ifdef _DEBUG_IMELODY
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Rewinding file for repeat\n"); */ }
-#endif
- /* rewind to start of loop */
- if ((result = EAS_HWFileSeek(pEASData->hwInstData, pData->fileHandle, pData->repeatOffset)) != EAS_SUCCESS)
- return result;
- IMY_ReadLine(pEASData->hwInstData, pData->fileHandle, pData->buffer, &pData->startLine);
- pData->index = 0;
-
- /* if last loop, prevent future loops */
- if (pData->repeatCount == -1)
- pData->repeatOffset = -1;
- }
- }
- break;
-
- /* repeat count */
- case '@':
- if (!IMY_GetNumber(pEASData->hwInstData, pData, &temp, EAS_FALSE))
- eof = EAS_TRUE;
- else if (pData->repeatOffset > 0)
- {
-
-#ifdef _DEBUG_IMELODY
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Repeat count = %dt", pData->repeatCount); */ }
-#endif
- if (pData->repeatCount < 0)
- pData->repeatCount = (EAS_I16) temp;
- }
- break;
-
- /* volume */
- case 'V':
- if (!IMY_GetVolume(pEASData->hwInstData, pData, EAS_FALSE))
- eof = EAS_TRUE;
- break;
-
- /* flat */
- case '&':
- pData->noteModifier = -1;
- break;
-
- /* sharp */
- case '#':
- pData->noteModifier = +1;
- break;
-
- /* octave */
- case '*':
- c = IMY_GetNextChar(pEASData->hwInstData, pData, EAS_FALSE);
- if (IsDigit(c))
- pData->octave = (EAS_U8) ((c - '0' + 1) * 12);
- else if (!c)
- eof = EAS_TRUE;
- break;
-
- /* ledon or ledoff */
- case 'l':
- if (!IMY_GetLEDState(pEASData, pData))
- eof = EAS_TRUE;
- break;
-
- /* vibeon or vibeoff */
- case 'v':
- if (!IMY_GetVibeState(pEASData, pData))
- eof = EAS_TRUE;
- break;
-
- /* either a B note or backon or backoff */
- case 'b':
- if (IMY_GetNextChar(pEASData->hwInstData, pData, EAS_FALSE) == 'a')
- {
- if (!IMY_GetBackState(pEASData, pData))
- eof = EAS_TRUE;
- }
- else
- {
- PutBackChar(pData);
- if (IMY_PlayNote(pEASData, pData, c, parserMode))
- return EAS_SUCCESS;
- eof = EAS_TRUE;
- }
- break;
-
- /* rest */
- case 'r':
- case 'R':
- if (IMY_PlayRest(pEASData, pData))
- return EAS_SUCCESS;
- eof = EAS_TRUE;
- break;
-
- /* EOF */
- case 0:
-#ifdef _DEBUG_IMELODY
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_Event: end of iMelody file detected\n"); */ }
-#endif
- eof = EAS_TRUE;
- break;
-
- /* must be a note */
- default:
- c = ToLower(c);
- if ((c >= 'a') && (c <= 'g'))
- {
- if (IMY_PlayNote(pEASData, pData, c, parserMode))
- return EAS_SUCCESS;
- eof = EAS_TRUE;
- }
- else
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Ignoring unexpected character '%c' [0x%02x]\n", c, c); */ }
- break;
- }
- }
-
- /* handle EOF */
-#ifdef _DEBUG_IMELODY
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_Event: state set to EAS_STATE_STOPPING\n"); */ }
-#endif
- pData->state = EAS_STATE_STOPPING;
- VMReleaseAllVoices(pEASData->pVoiceMgr, pData->pSynth);
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * IMY_State()
- *----------------------------------------------------------------------------
- * Purpose:
- * Returns the current state of the stream
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- * pState - pointer to variable to store state
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, pEASData) common decoder interface - pEASData not used */
-static EAS_RESULT IMY_State (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 *pState)
-{
- S_IMELODY_DATA* pData;
-
- /* establish pointer to instance data */
- pData = (S_IMELODY_DATA*) pInstData;
-
- /* if stopping, check to see if synth voices are active */
- if (pData->state == EAS_STATE_STOPPING)
- {
- if (VMActiveVoices(pData->pSynth) == 0)
- {
- pData->state = EAS_STATE_STOPPED;
-#ifdef _DEBUG_IMELODY
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_State: state set to EAS_STATE_STOPPED\n"); */ }
-#endif
- }
- }
-
- if (pData->state == EAS_STATE_PAUSING)
- {
- if (VMActiveVoices(pData->pSynth) == 0)
- {
-#ifdef _DEBUG_IMELODY
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_State: state set to EAS_STATE_PAUSED\n"); */ }
-#endif
- pData->state = EAS_STATE_PAUSED;
- }
- }
-
- /* return current state */
- *pState = pData->state;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * IMY_Close()
- *----------------------------------------------------------------------------
- * Purpose:
- * Close the file and clean up
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT IMY_Close (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
-{
- S_IMELODY_DATA* pData;
- EAS_RESULT result;
-
-#ifdef _DEBUG_IMELODY
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_Close: close file\n"); */ }
-#endif
-
- pData = (S_IMELODY_DATA*) pInstData;
-
- /* close the file */
- if ((result = EAS_HWCloseFile(pEASData->hwInstData, pData->fileHandle)) != EAS_SUCCESS)
- return result;
-
- /* free the synth */
- if (pData->pSynth != NULL)
- VMMIDIShutdown(pEASData, pData->pSynth);
-
- /* if using dynamic memory, free it */
- if (!pEASData->staticMemoryModel)
- EAS_HWFree(pEASData->hwInstData, pData);
-
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * IMY_Reset()
- *----------------------------------------------------------------------------
- * Purpose:
- * Reset the sequencer. Used for locating backwards in the file.
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT IMY_Reset (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
-{
- S_IMELODY_DATA* pData;
- EAS_RESULT result;
-
-#ifdef _DEBUG_IMELODY
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_Reset: reset file\n"); */ }
-#endif
- pData = (S_IMELODY_DATA*) pInstData;
-
- /* reset the synth */
- VMReset(pEASData->pVoiceMgr, pData->pSynth, EAS_TRUE);
-
- /* reset time to zero */
- pData->time = 0;
- pData->note = 0;
-
- /* reset file position and re-parse header */
- pData->state = EAS_STATE_ERROR;
- if ((result = EAS_HWFileSeek(pEASData->hwInstData, pData->fileHandle, pData->fileOffset)) != EAS_SUCCESS)
- return result;
- if ((result = IMY_ParseHeader (pEASData, pData)) != EAS_SUCCESS)
- return result;
-
-#ifdef _DEBUG_IMELODY
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_Reset: state set to EAS_STATE_ERROR\n"); */ }
-#endif
-
- pData->state = EAS_STATE_READY;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * IMY_Pause()
- *----------------------------------------------------------------------------
- * Purpose:
- * Pauses the sequencer. Mutes all voices and sets state to pause.
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT IMY_Pause (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
-{
- S_IMELODY_DATA *pData;
-
-#ifdef _DEBUG_IMELODY
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_Pause: pause file\n"); */ }
-#endif
-
- /* can't pause a stopped stream */
- pData = (S_IMELODY_DATA*) pInstData;
- if (pData->state == EAS_STATE_STOPPED)
- return EAS_ERROR_ALREADY_STOPPED;
-
- /* mute the synthesizer */
- VMMuteAllVoices(pEASData->pVoiceMgr, pData->pSynth);
- pData->state = EAS_STATE_PAUSING;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * IMY_Resume()
- *----------------------------------------------------------------------------
- * Purpose:
- * Resume playing after a pause, sets state back to playing.
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, pEASData) common decoder interface - pEASData not used */
-static EAS_RESULT IMY_Resume (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
-{
- S_IMELODY_DATA *pData;
-
-#ifdef _DEBUG_IMELODY
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_Resume: resume file\n"); */ }
-#endif
-
- /* can't resume a stopped stream */
- pData = (S_IMELODY_DATA*) pInstData;
- if (pData->state == EAS_STATE_STOPPED)
- return EAS_ERROR_ALREADY_STOPPED;
-
- /* nothing to do but resume playback */
- pData->state = EAS_STATE_PLAY;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * IMY_SetData()
- *----------------------------------------------------------------------------
- * Purpose:
- * Adjust tempo relative to song tempo
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * pInstData - pointer to iMelody instance data
- * rate - rate (28-bit fractional amount)
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, pEASData) common decoder interface - pEASData not used */
-static EAS_RESULT IMY_SetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value)
-{
- S_IMELODY_DATA *pData;
-
- pData = (S_IMELODY_DATA*) pInstData;
- switch (param)
- {
-
- /* set metadata callback */
- case PARSER_DATA_METADATA_CB:
- EAS_HWMemCpy(&pData->metadata, (void*) value, sizeof(S_METADATA_CB));
- break;
-
- default:
- return EAS_ERROR_INVALID_PARAMETER;
- }
-
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * IMY_GetData()
- *----------------------------------------------------------------------------
- * Purpose:
- * Return the file type
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * pInstData - pointer to iMelody instance data
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, pEASData) common decoder interface - pEASData not used */
-static EAS_RESULT IMY_GetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue)
-{
- S_IMELODY_DATA *pData;
-
- pData = (S_IMELODY_DATA*) pInstData;
-
- switch (param)
- {
- /* return file type as iMelody */
- case PARSER_DATA_FILE_TYPE:
- *pValue = EAS_FILE_IMELODY;
- break;
-
- case PARSER_DATA_SYNTH_HANDLE:
- *pValue = (EAS_I32) pData->pSynth;
- break;
-
- case PARSER_DATA_GAIN_OFFSET:
- *pValue = IMELODY_GAIN_OFFSET;
- break;
-
- default:
- return EAS_ERROR_INVALID_PARAMETER;
- }
-
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * IMY_PlayNote()
- *----------------------------------------------------------------------------
- * Purpose:
- *
- *
- * Inputs:
- *
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_BOOL IMY_PlayNote (S_EAS_DATA *pEASData, S_IMELODY_DATA *pData, EAS_I8 note, EAS_INT parserMode)
-{
- EAS_I32 duration;
- EAS_U8 velocity;
-
-
-#ifdef _DEBUG_IMELODY
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_PlayNote: start note %d\n", note); */ }
-#endif
-
- /* get the duration */
- if (!IMY_GetDuration(pEASData->hwInstData, pData, &duration))
- return EAS_FALSE;
-
- /* save note value */
- pData->note = (EAS_U8) (pData->octave + noteTable[note - 'a'] + pData->noteModifier);
- velocity = (EAS_U8) (pData->volume ? pData->volume * IMELODY_VEL_MUL + IMELODY_VEL_OFS : 0);
-
- /* start note only if in play mode */
- if (parserMode == eParserModePlay)
- VMStartNote(pEASData->pVoiceMgr, pData->pSynth, IMELODY_CHANNEL, pData->note, velocity);
-
-#ifdef _DEBUG_IMELODY
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_PlayNote: Start note %d, duration %d\n", pData->note, duration); */ }
-#endif
-
- /* determine note length */
- switch (pData->style)
- {
- case 0:
- /*lint -e{704} shift for performance */
- pData->restTicks = duration >> 4;
- break;
- case 1:
- pData->restTicks = 0;
- break;
- case 2:
- /*lint -e{704} shift for performance */
- pData->restTicks = duration >> 1;
- break;
- default:
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "IMY_PlayNote: Note style out of range: %d\n", pData->style); */ }
- /*lint -e{704} shift for performance */
- pData->restTicks = duration >> 4;
- break;
- }
-
- /* next event is at end of this note */
- pData->time += duration - pData->restTicks;
-
- /* reset the flat/sharp modifier */
- pData->noteModifier = 0;
-
- return EAS_TRUE;
-}
-
-/*----------------------------------------------------------------------------
- * IMY_PlayRest()
- *----------------------------------------------------------------------------
- * Purpose:
- *
- *
- * Inputs:
- *
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_BOOL IMY_PlayRest (S_EAS_DATA *pEASData, S_IMELODY_DATA *pData)
-{
- EAS_I32 duration;
-
-#ifdef _DEBUG_IMELODY
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Enter IMY_PlayRest]n"); */ }
-#endif
-
- /* get the duration */
- if (!IMY_GetDuration(pEASData->hwInstData, pData, &duration))
- return EAS_FALSE;
-
-#ifdef _DEBUG_IMELODY
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_PlayRest: note duration %d\n", duration); */ }
-#endif
-
- /* next event is at end of this note */
- pData->time += duration;
- return EAS_TRUE;
-}
-
-/*----------------------------------------------------------------------------
- * IMY_GetDuration()
- *----------------------------------------------------------------------------
- * Purpose:
- *
- *
- * Inputs:
- *
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-
-static EAS_BOOL IMY_GetDuration (EAS_HW_DATA_HANDLE hwInstData, S_IMELODY_DATA *pData, EAS_I32 *pDuration)
-{
- EAS_I32 duration;
- EAS_I8 c;
-
- /* get the duration */
- *pDuration = 0;
- c = IMY_GetNextChar(hwInstData, pData, EAS_FALSE);
- if (!c)
- return EAS_FALSE;
- if ((c < '0') || (c > '5'))
- {
-#ifdef _DEBUG_IMELODY
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_GetDuration: error in duration '%c'\n", c); */ }
-#endif
- return EAS_FALSE;
- }
-
- /* calculate total length of note */
- duration = pData->tick * (1 << ('5' - c));
-
- /* check for duration modifier */
- c = IMY_GetNextChar(hwInstData, pData, EAS_FALSE);
- if (c)
- {
- if (c == '.')
- /*lint -e{704} shift for performance */
- duration += duration >> 1;
- else if (c == ':')
- /*lint -e{704} shift for performance */
- duration += (duration >> 1) + (duration >> 2);
- else if (c == ';')
- /*lint -e{704} shift for performance */
- duration = (duration * TRIPLET_MULTIPLIER) >> TRIPLET_SHIFT;
- else
- PutBackChar(pData);
- }
-
- *pDuration = duration;
- return EAS_TRUE;
-}
-
-/*----------------------------------------------------------------------------
- * IMY_GetLEDState()
- *----------------------------------------------------------------------------
- * Purpose:
- *
- *
- * Inputs:
- *
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_BOOL IMY_GetLEDState (S_EAS_DATA *pEASData, S_IMELODY_DATA *pData)
-{
- EAS_I8 c;
- EAS_INT i;
-
-#ifdef _DEBUG_IMELODY
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Enter IMY_GetLEDState\n"); */ }
-#endif
-
- for (i = 0; i < 5; i++)
- {
- c = IMY_GetNextChar(pEASData->hwInstData, pData, EAS_FALSE);
- if (!c)
- return EAS_FALSE;
- switch (i)
- {
- case 3:
- if (c == 'n')
- {
-#ifdef _DEBUG_IMELODY
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_GetLEDState: LED on\n"); */ }
-#endif
- EAS_HWLED(pEASData->hwInstData, EAS_TRUE);
- return EAS_TRUE;
- }
- else if (c != 'f')
- return EAS_FALSE;
- break;
-
- case 4:
- if (c == 'f')
- {
-#ifdef _DEBUG_IMELODY
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_GetLEDState: LED off\n"); */ }
-#endif
- EAS_HWLED(pEASData->hwInstData, EAS_FALSE);
- return EAS_TRUE;
- }
- return EAS_FALSE;
-
- default:
- if (c != ledStr[i])
- return EAS_FALSE;
- break;
- }
- }
- return EAS_FALSE;
-}
-
-/*----------------------------------------------------------------------------
- * IMY_GetVibeState()
- *----------------------------------------------------------------------------
- * Purpose:
- *
- *
- * Inputs:
- *
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_BOOL IMY_GetVibeState (S_EAS_DATA *pEASData, S_IMELODY_DATA *pData)
-{
- EAS_I8 c;
- EAS_INT i;
-
-#ifdef _DEBUG_IMELODY
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Enter IMY_GetVibeState\n"); */ }
-#endif
-
- for (i = 0; i < 6; i++)
- {
- c = IMY_GetNextChar(pEASData->hwInstData, pData, EAS_FALSE);
- if (!c)
- return EAS_FALSE;
- switch (i)
- {
- case 4:
- if (c == 'n')
- {
-#ifdef _DEBUG_IMELODY
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_GetVibeState: vibrate on\n"); */ }
-#endif
- EAS_HWVibrate(pEASData->hwInstData, EAS_TRUE);
- return EAS_TRUE;
- }
- else if (c != 'f')
- return EAS_FALSE;
- break;
-
- case 5:
- if (c == 'f')
- {
-#ifdef _DEBUG_IMELODY
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_GetVibeState: vibrate off\n"); */ }
-#endif
- EAS_HWVibrate(pEASData->hwInstData, EAS_FALSE);
- return EAS_TRUE;
- }
- return EAS_FALSE;
-
- default:
- if (c != vibeStr[i])
- return EAS_FALSE;
- break;
- }
- }
- return EAS_FALSE;
-}
-
-/*----------------------------------------------------------------------------
- * IMY_GetBackState()
- *----------------------------------------------------------------------------
- * Purpose:
- *
- *
- * Inputs:
- *
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_BOOL IMY_GetBackState (S_EAS_DATA *pEASData, S_IMELODY_DATA *pData)
-{
- EAS_I8 c;
- EAS_INT i;
-
-#ifdef _DEBUG_IMELODY
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Enter IMY_GetBackState\n"); */ }
-#endif
-
- for (i = 0; i < 5; i++)
- {
- c = IMY_GetNextChar(pEASData->hwInstData, pData, EAS_FALSE);
- if (!c)
- return EAS_FALSE;
- switch (i)
- {
- case 3:
- if (c == 'n')
- {
-#ifdef _DEBUG_IMELODY
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_GetBackState: backlight on\n"); */ }
-#endif
- EAS_HWBackLight(pEASData->hwInstData, EAS_TRUE);
- return EAS_TRUE;
- }
- else if (c != 'f')
- return EAS_FALSE;
- break;
-
- case 4:
- if (c == 'f')
- {
-#ifdef _DEBUG_IMELODY
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_GetBackState: backlight off\n"); */ }
-#endif
- EAS_HWBackLight(pEASData->hwInstData, EAS_FALSE);
- return EAS_TRUE;
- }
- return EAS_FALSE;
-
- default:
- if (c != backStr[i])
- return EAS_FALSE;
- break;
- }
- }
- return EAS_FALSE;
-}
-
-/*----------------------------------------------------------------------------
- * IMY_GetVolume()
- *----------------------------------------------------------------------------
- * Purpose:
- *
- *
- * Inputs:
- *
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_BOOL IMY_GetVolume (EAS_HW_DATA_HANDLE hwInstData, S_IMELODY_DATA *pData, EAS_BOOL inHeader)
-{
- EAS_INT temp;
- EAS_I8 c;
-
-#ifdef _DEBUG_IMELODY
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Enter IMY_GetVolume\n"); */ }
-#endif
-
- c = IMY_GetNextChar(hwInstData, pData, inHeader);
- if (c == '+')
- {
- if (pData->volume < 15)
- pData->volume++;
- return EAS_TRUE;
- }
- else if (c == '-')
- {
- if (pData->volume > 0)
- pData->volume--;
- return EAS_TRUE;
- }
- else if (IsDigit(c))
- temp = c - '0';
- else
- return EAS_FALSE;
-
- c = IMY_GetNextChar(hwInstData, pData, inHeader);
- if (IsDigit(c))
- temp = temp * 10 + c - '0';
- else if (c)
- PutBackChar(pData);
- if ((temp >= 0) && (temp <= 15))
- {
- if (inHeader && (temp == 0))
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Ignoring V0 encountered in header\n"); */ }
- else
- pData->volume = (EAS_U8) temp;
- }
- return EAS_TRUE;
-}
-
-/*----------------------------------------------------------------------------
- * IMY_GetNumber()
- *----------------------------------------------------------------------------
- * Purpose:
- *
- *
- * Inputs:
- *
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_BOOL IMY_GetNumber (EAS_HW_DATA_HANDLE hwInstData, S_IMELODY_DATA *pData, EAS_INT *temp, EAS_BOOL inHeader)
-{
- EAS_BOOL ok;
- EAS_I8 c;
-
-#ifdef _DEBUG_IMELODY
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Enter IMY_GetNumber\n"); */ }
-#endif
-
- *temp = 0;
- ok = EAS_FALSE;
- for (;;)
- {
- c = IMY_GetNextChar(hwInstData, pData, inHeader);
- if (IsDigit(c))
- {
- *temp = *temp * 10 + c - '0';
- ok = EAS_TRUE;
- }
- else
- {
- if (c)
- PutBackChar(pData);
-
-#ifdef _DEBUG_IMELODY
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_GetNumber: value %d\n", *temp); */ }
-#endif
-
- return ok;
- }
- }
-}
-
-/*----------------------------------------------------------------------------
- * IMY_GetVersion()
- *----------------------------------------------------------------------------
- * Purpose:
- *
- *
- * Inputs:
- *
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_BOOL IMY_GetVersion (S_IMELODY_DATA *pData, EAS_INT *pVersion)
-{
- EAS_I8 c;
- EAS_INT temp;
- EAS_INT version;
-
- version = temp = 0;
- for (;;)
- {
- c = pData->buffer[pData->index++];
- if ((c == 0) || (c == '.'))
- {
- /*lint -e{701} use shift for performance */
- version = (version << 8) + temp;
- if (c == 0)
- {
-
-#ifdef _DEBUG_IMELODY
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_GetVersion: version 0x%04x\n", version); */ }
-#endif
-
- *pVersion = version;
- return EAS_TRUE;
- }
- temp = 0;
- }
- else if (IsDigit(c))
- temp = (temp * 10) + c - '0';
- }
-}
-
-/*----------------------------------------------------------------------------
- * IMY_MetaData()
- *----------------------------------------------------------------------------
- * Purpose:
- * Prepare to parse the file. Allocates instance data (or uses static allocation for
- * static memory model).
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static void IMY_MetaData (S_IMELODY_DATA *pData, E_EAS_METADATA_TYPE metaType, EAS_I8 *buffer)
-{
- EAS_I32 len;
-
- /* check for callback */
- if (!pData->metadata.callback)
- return;
-
- /* copy data to host buffer */
- len = (EAS_I32) strlen((char*) buffer);
- if (len >pData->metadata.bufferSize)
- len = pData->metadata.bufferSize;
- strncpy((char*) pData->metadata.buffer, (char*) buffer, (size_t) len);
- pData->metadata.buffer[len] = 0;
-
- /* callback to host */
- pData->metadata.callback(metaType, pData->metadata.buffer, pData->metadata.pUserData);
-}
-
-/*----------------------------------------------------------------------------
- * IMY_ParseHeader()
- *----------------------------------------------------------------------------
- * Purpose:
- * Prepare to parse the file. Allocates instance data (or uses static allocation for
- * static memory model).
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT IMY_ParseHeader (S_EAS_DATA *pEASData, S_IMELODY_DATA* pData)
-{
- EAS_RESULT result;
- EAS_INT token;
- EAS_INT temp;
- EAS_I8 c;
-
-#ifdef _DEBUG_IMELODY
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Enter IMY_ParseHeader\n"); */ }
-#endif
-
- /* initialize some defaults */
- pData->time = 0;
- pData->tick = DEFAULT_TICK_CONV;
- pData->note = 0;
- pData->noteModifier = 0;
- pData ->restTicks = 0;
- pData->volume = 7;
- pData->octave = 60;
- pData->repeatOffset = -1;
- pData->repeatCount = -1;
- pData->style = 0;
-
- /* force the read of the first line */
- pData->index = 1;
-
- /* read data until we get to melody */
- for (;;)
- {
- /* read a line from the file and parse the token */
- if (pData->index != 0)
- {
- if ((result = IMY_ReadLine(pEASData->hwInstData, pData->fileHandle, pData->buffer, &pData->startLine)) != EAS_SUCCESS)
- {
-#ifdef _DEBUG_IMELODY
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_ParseHeader: IMY_ReadLine returned %d\n", result); */ }
-#endif
- return result;
- }
- }
- token = IMY_ParseLine(pData->buffer, &pData->index);
-
- switch (token)
- {
- /* ignore these valid tokens */
- case TOKEN_BEGIN:
- break;
-
- case TOKEN_FORMAT:
- if (!IMY_GetVersion(pData, &temp))
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Invalid FORMAT field '%s'\n", pData->buffer); */ }
- return EAS_ERROR_FILE_FORMAT;
- }
- if ((temp != 0x0100) && (temp != 0x0200))
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Unsupported FORMAT %02x\n", temp); */ }
- return EAS_ERROR_UNRECOGNIZED_FORMAT;
- }
- break;
-
- case TOKEN_VERSION:
- if (!IMY_GetVersion(pData, &temp))
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Invalid VERSION field '%s'\n", pData->buffer); */ }
- return EAS_ERROR_FILE_FORMAT;
- }
- if ((temp != 0x0100) && (temp != 0x0102))
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Unsupported VERSION %02x\n", temp); */ }
- return EAS_ERROR_UNRECOGNIZED_FORMAT;
- }
- break;
-
- case TOKEN_NAME:
- IMY_MetaData(pData, EAS_METADATA_TITLE, pData->buffer + pData->index);
- break;
-
- case TOKEN_COMPOSER:
- IMY_MetaData(pData, EAS_METADATA_AUTHOR, pData->buffer + pData->index);
- break;
-
- /* handle beat */
- case TOKEN_BEAT:
- IMY_GetNumber(pEASData->hwInstData, pData, &temp, EAS_TRUE);
- if ((temp >= 25) && (temp <= 900))
- pData->tick = TICK_CONVERT / temp;
- break;
-
- /* handle style */
- case TOKEN_STYLE:
- c = IMY_GetNextChar(pEASData->hwInstData, pData, EAS_TRUE);
- if (c == 'S')
- c = IMY_GetNextChar(pEASData->hwInstData, pData, EAS_TRUE);
- if ((c >= '0') && (c <= '2'))
- pData->style = (EAS_U8) (c - '0');
- else
- {
- PutBackChar(pData);
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Error in style command: %s\n", pData->buffer); */ }
- }
- break;
-
- /* handle volume */
- case TOKEN_VOLUME:
- c = IMY_GetNextChar(pEASData->hwInstData, pData, EAS_TRUE);
- if (c != 'V')
- {
- PutBackChar(pData);
- if (!IsDigit(c))
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Error in volume command: %s\n", pData->buffer); */ }
- break;
- }
- }
- IMY_GetVolume(pEASData->hwInstData, pData, EAS_TRUE);
- break;
-
- case TOKEN_MELODY:
-#ifdef _DEBUG_IMELODY
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Header successfully parsed\n"); */ }
-#endif
- return EAS_SUCCESS;
-
- case TOKEN_END:
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Unexpected END:IMELODY encountered\n"); */ }
- return EAS_ERROR_FILE_FORMAT;
-
- default:
- /* force a read of the next line */
- pData->index = 1;
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Ignoring unrecognized token in iMelody file: %s\n", pData->buffer); */ }
- break;
- }
- }
-}
-
-/*----------------------------------------------------------------------------
- * IMY_GetNextChar()
- *----------------------------------------------------------------------------
- * Purpose:
- *
- *
- * Inputs:
- *
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_I8 IMY_GetNextChar (EAS_HW_DATA_HANDLE hwInstData, S_IMELODY_DATA *pData, EAS_BOOL inHeader)
-{
- EAS_I8 c;
- EAS_U8 index;
-
- for (;;)
- {
- /* get next character */
- c = pData->buffer[pData->index++];
-
- /* buffer empty, read more */
- if (!c)
- {
- /* don't read the next line in the header */
- if (inHeader)
- return 0;
-
- pData->index = 0;
- pData->buffer[0] = 0;
- if (IMY_ReadLine(hwInstData, pData->fileHandle, pData->buffer, &pData->startLine) != EAS_SUCCESS)
- {
-#ifdef _DEBUG_IMELODY
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_GetNextChar: EOF\n"); */ }
-#endif
- return 0;
- }
-
- /* check for END:IMELODY token */
- if (IMY_ParseLine(pData->buffer, &index) == TOKEN_END)
- {
-#ifdef _DEBUG_IMELODY
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_GetNextChar: found END:IMELODY\n"); */ }
-#endif
- pData->buffer[0] = 0;
- return 0;
- }
- continue;
- }
-
- /* ignore white space */
- if (!IsSpace(c))
- {
-
-#ifdef _DEBUG_IMELODY
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_GetNextChar returned '%c'\n", c); */ }
-#endif
- return c;
- }
- }
-}
-
-/*----------------------------------------------------------------------------
- * IMY_ReadLine()
- *----------------------------------------------------------------------------
- * Purpose:
- * Reads a line of input from the file, discarding the CR/LF
- *
- * Inputs:
- *
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT IMY_ReadLine (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE fileHandle, EAS_I8 *buffer, EAS_I32 *pStartLine)
-{
- EAS_RESULT result;
- EAS_INT i;
- EAS_I8 c;
-
- /* fetch current file position and save it */
- if (pStartLine != NULL)
- {
- if ((result = EAS_HWFilePos(hwInstData, fileHandle, pStartLine)) != EAS_SUCCESS)
- {
-#ifdef _DEBUG_IMELODY
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_ParseHeader: EAS_HWFilePos returned %d\n", result); */ }
-#endif
- return result;
- }
- }
-
- buffer[0] = 0;
- for (i = 0; i < MAX_LINE_SIZE; )
- {
- if ((result = EAS_HWGetByte(hwInstData, fileHandle, &c)) != EAS_SUCCESS)
- {
- if ((result == EAS_EOF) && (i > 0))
- break;
- return result;
- }
-
- /* return on LF or end of data */
- if (c == '\n')
- break;
-
- /* store characters in buffer */
- if (c != '\r')
- buffer[i++] = c;
- }
- buffer[i] = 0;
-
-#ifdef _DEBUG_IMELODY
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_ReadLine read %s\n", buffer); */ }
-#endif
-
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * IMY_ParseLine()
- *----------------------------------------------------------------------------
- * Purpose:
- *
- *
- * Inputs:
- *
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_INT IMY_ParseLine (EAS_I8 *buffer, EAS_U8 *pIndex)
-{
- EAS_INT i;
- EAS_INT j;
-
- /* there's no strnicmp() in stdlib, so we have to roll our own */
- for (i = 0; i < TOKEN_INVALID; i++)
- {
- for (j = 0; ; j++)
- {
- /* end of token, must be a match */
- if (tokens[i][j] == 0)
- {
-#ifdef _DEBUG_IMELODY
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_ParseLine found token %d\n", i); */ }
-#endif
- *pIndex = (EAS_U8) j;
- return i;
- }
- if (tokens[i][j] != ToUpper(buffer[j]))
- break;
- }
- }
-#ifdef _DEBUG_IMELODY
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_ParseLine: no token found\n"); */ }
-#endif
- return TOKEN_INVALID;
-}
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 797 $
+ * $Date: 2007-08-01 00:15:56 -0700 (Wed, 01 Aug 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+/* lint doesn't like the way some string.h files look */
+#ifdef _lint
+#include "lint_stdlib.h"
+#else
+#include <string.h>
+#endif
+
+#include "eas_data.h"
+#include "eas_miditypes.h"
+#include "eas_parser.h"
+#include "eas_report.h"
+#include "eas_host.h"
+#include "eas_midi.h"
+#include "eas_config.h"
+#include "eas_vm_protos.h"
+#include "eas_imelodydata.h"
+#include "eas_ctype.h"
+
+// #define _DEBUG_IMELODY
+
+/* increase gain for mono ringtones */
+#define IMELODY_GAIN_OFFSET 8
+
+/* length of 32nd note in 1/256ths of a msec for 120 BPM tempo */
+#define DEFAULT_TICK_CONV 16000
+#define TICK_CONVERT 1920000
+
+/* default channel and program for iMelody playback */
+#define IMELODY_CHANNEL 0
+#define IMELODY_PROGRAM 80
+#define IMELODY_VEL_MUL 4
+#define IMELODY_VEL_OFS 67
+
+/* multiplier for fixed point triplet conversion */
+#define TRIPLET_MULTIPLIER 683
+#define TRIPLET_SHIFT 10
+
+static const char* const tokens[] =
+{
+ "BEGIN:IMELODY",
+ "VERSION:",
+ "FORMAT:CLASS",
+ "NAME:",
+ "COMPOSER:",
+ "BEAT:",
+ "STYLE:",
+ "VOLUME:",
+ "MELODY:",
+ "END:IMELODY"
+};
+
+/* ledon or ledoff */
+static const char ledStr[] = "edo";
+
+/* vibeon or vibeoff */
+static const char vibeStr[] = "ibeo";
+
+/* backon or backoff */
+static const char backStr[] = "cko";
+
+typedef enum
+{
+ TOKEN_BEGIN,
+ TOKEN_VERSION,
+ TOKEN_FORMAT,
+ TOKEN_NAME,
+ TOKEN_COMPOSER,
+ TOKEN_BEAT,
+ TOKEN_STYLE,
+ TOKEN_VOLUME,
+ TOKEN_MELODY,
+ TOKEN_END,
+ TOKEN_INVALID
+} ENUM_IMELODY_TOKENS;
+
+/* lookup table for note values */
+static const EAS_I8 noteTable[] = { 9, 11, 0, 2, 4, 5, 7 };
+
+/* inline functions */
+#ifdef _DEBUG_IMELODY
+static void PutBackChar (S_IMELODY_DATA *pData)
+{
+ if (pData->index)
+ pData->index--;
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "PutBackChar '%c'\n", pData->buffer[pData->index]); */ }
+}
+#else
+EAS_INLINE void PutBackChar (S_IMELODY_DATA *pData) { if (pData->index) pData->index--; }
+#endif
+
+
+/* local prototypes */
+static EAS_RESULT IMY_CheckFileType (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle, EAS_VOID_PTR *ppHandle, EAS_I32 offset);
+static EAS_RESULT IMY_Prepare (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
+static EAS_RESULT IMY_Time (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_U32 *pTime);
+static EAS_RESULT IMY_Event (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_INT parserMode);
+static EAS_RESULT IMY_State (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_STATE *pState);
+static EAS_RESULT IMY_Close (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
+static EAS_RESULT IMY_Reset (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
+static EAS_RESULT IMY_Pause (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
+static EAS_RESULT IMY_Resume (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
+static EAS_RESULT IMY_SetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value);
+static EAS_RESULT IMY_GetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue);
+static EAS_BOOL IMY_PlayNote (S_EAS_DATA *pEASData, S_IMELODY_DATA *pData, EAS_I8 note, EAS_INT parserMode);
+static EAS_BOOL IMY_PlayRest (S_EAS_DATA *pEASData, S_IMELODY_DATA *pData);
+static EAS_BOOL IMY_GetDuration (EAS_HW_DATA_HANDLE hwInstData, S_IMELODY_DATA *pData, EAS_I32 *pDuration);
+static EAS_BOOL IMY_GetLEDState (S_EAS_DATA *pEASData, S_IMELODY_DATA *pData);
+static EAS_BOOL IMY_GetVibeState (S_EAS_DATA *pEASData, S_IMELODY_DATA *pData);
+static EAS_BOOL IMY_GetBackState (S_EAS_DATA *pEASData, S_IMELODY_DATA *pData);
+static EAS_BOOL IMY_GetVolume (EAS_HW_DATA_HANDLE hwInstData, S_IMELODY_DATA *pData, EAS_BOOL inHeader);
+static EAS_BOOL IMY_GetNumber (EAS_HW_DATA_HANDLE hwInstData, S_IMELODY_DATA *pData, EAS_INT *temp, EAS_BOOL inHeader);
+static EAS_RESULT IMY_ParseHeader (S_EAS_DATA *pEASData, S_IMELODY_DATA* pData);
+static EAS_I8 IMY_GetNextChar (EAS_HW_DATA_HANDLE hwInstData, S_IMELODY_DATA *pData, EAS_BOOL inHeader);
+static EAS_RESULT IMY_ReadLine (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE fileHandle, EAS_I8 *buffer, EAS_I32 *pStartLine);
+static EAS_INT IMY_ParseLine (EAS_I8 *buffer, EAS_U8 *pIndex);
+
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_iMelody_Parser
+ *
+ * This structure contains the functional interface for the iMelody parser
+ *----------------------------------------------------------------------------
+*/
+const S_FILE_PARSER_INTERFACE EAS_iMelody_Parser =
+{
+ IMY_CheckFileType,
+ IMY_Prepare,
+ IMY_Time,
+ IMY_Event,
+ IMY_State,
+ IMY_Close,
+ IMY_Reset,
+ IMY_Pause,
+ IMY_Resume,
+ NULL,
+ IMY_SetData,
+ IMY_GetData,
+ NULL
+};
+
+/*----------------------------------------------------------------------------
+ * IMY_CheckFileType()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Check the file type to see if we can parse it
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT IMY_CheckFileType (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle, EAS_VOID_PTR *ppHandle, EAS_I32 offset)
+{
+ S_IMELODY_DATA* pData;
+ EAS_I8 buffer[MAX_LINE_SIZE+1];
+ EAS_U8 index;
+
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Enter IMY_CheckFileType\n"); */ }
+#endif
+
+ /* read the first line of the file */
+ *ppHandle = NULL;
+ if (IMY_ReadLine(pEASData->hwInstData, fileHandle, buffer, NULL) != EAS_SUCCESS)
+ return EAS_SUCCESS;
+
+ /* check for header string */
+ if (IMY_ParseLine(buffer, &index) == TOKEN_BEGIN)
+ {
+
+ /* check for static memory allocation */
+ if (pEASData->staticMemoryModel)
+ pData = EAS_CMEnumData(EAS_CM_IMELODY_DATA);
+ else
+ pData = EAS_HWMalloc(pEASData->hwInstData, sizeof(S_IMELODY_DATA));
+ if (!pData)
+ return EAS_ERROR_MALLOC_FAILED;
+ EAS_HWMemSet(pData, 0, sizeof(S_IMELODY_DATA));
+
+ /* initialize */
+ pData->fileHandle = fileHandle;
+ pData->fileOffset = offset;
+ pData->state = EAS_STATE_ERROR;
+ pData->state = EAS_STATE_OPEN;
+
+ /* return a pointer to the instance data */
+ *ppHandle = pData;
+ }
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * IMY_Prepare()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Prepare to parse the file. Allocates instance data (or uses static allocation for
+ * static memory model).
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT IMY_Prepare (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
+{
+ S_IMELODY_DATA* pData;
+ EAS_RESULT result;
+
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Enter IMY_Prepare\n"); */ }
+#endif
+
+ /* check for valid state */
+ pData = (S_IMELODY_DATA*) pInstData;
+ if (pData->state != EAS_STATE_OPEN)
+ return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
+
+ /* instantiate a synthesizer */
+ if ((result = VMInitMIDI(pEASData, &pData->pSynth)) != EAS_SUCCESS)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "VMInitMIDI returned %d\n", result); */ }
+ return result;
+ }
+
+ /* parse the header */
+ if ((result = IMY_ParseHeader(pEASData, pData)) != EAS_SUCCESS)
+ return result;
+
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_Prepare: state set to EAS_STATE_READY\n"); */ }
+#endif
+
+ pData ->state = EAS_STATE_READY;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * IMY_Time()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Returns the time of the next event in msecs
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ * pTime - pointer to variable to hold time of next event (in msecs)
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pEASData) common decoder interface - pEASData not used */
+static EAS_RESULT IMY_Time (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_U32 *pTime)
+{
+ S_IMELODY_DATA *pData;
+
+ pData = (S_IMELODY_DATA*) pInstData;
+
+ /* return time in milliseconds */
+ /*lint -e{704} use shift instead of division */
+ *pTime = pData->time >> 8;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * IMY_Event()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Parse the next event in the file
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT IMY_Event (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_INT parserMode)
+{
+ S_IMELODY_DATA* pData;
+ EAS_RESULT result;
+ EAS_I8 c;
+ EAS_BOOL eof;
+ EAS_INT temp;
+
+ pData = (S_IMELODY_DATA*) pInstData;
+ if (pData->state >= EAS_STATE_OPEN)
+ return EAS_SUCCESS;
+
+ /* initialize MIDI channel when the track starts playing */
+ if (pData->time == 0)
+ {
+
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_Event: Reset\n"); */ }
+#endif
+ /* set program to square lead */
+ VMProgramChange(pEASData->pVoiceMgr, pData->pSynth, IMELODY_CHANNEL, IMELODY_PROGRAM);
+
+ /* set channel volume to max */
+ VMControlChange(pEASData->pVoiceMgr, pData->pSynth, IMELODY_CHANNEL, 7, 127);
+ }
+
+ /* check for end of note */
+ if (pData->note)
+ {
+
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Stopping note %d\n", pData->note); */ }
+#endif
+ /* stop the note */
+ VMStopNote(pEASData->pVoiceMgr, pData->pSynth, IMELODY_CHANNEL, pData->note, 0);
+ pData->note = 0;
+
+ /* check for rest between notes */
+ if (pData->restTicks)
+ {
+ pData->time += pData->restTicks;
+ pData->restTicks = 0;
+ return EAS_SUCCESS;
+ }
+ }
+
+ /* parse the next event */
+ eof = EAS_FALSE;
+ while (!eof)
+ {
+
+ /* get next character */
+ c = IMY_GetNextChar(pEASData->hwInstData, pData, EAS_FALSE);
+
+ switch (c)
+ {
+ /* start repeat */
+ case '(':
+
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Enter repeat section\n", c); */ }
+#endif
+
+ if (pData->repeatOffset < 0)
+ {
+ pData->repeatOffset = pData->startLine + (EAS_I32) pData->index;
+
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Repeat offset = %d\n", pData->repeatOffset); */ }
+#endif
+ }
+ else
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Ignoring nested repeat section\n"); */ }
+ break;
+
+ /* end repeat */
+ case ')':
+
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "End repeat section, repeat offset = %d\n", pData->repeatOffset); */ }
+#endif
+ /* ignore invalid repeats */
+ if (pData->repeatCount >= 0)
+ {
+
+ /* decrement repeat count (repeatCount == 0 means infinite loop) */
+ if (pData->repeatCount > 0)
+ {
+ if (--pData->repeatCount == 0)
+ {
+ pData->repeatCount = -1;
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Repeat loop complete\n"); */ }
+#endif
+ }
+ }
+
+//2 TEMPORARY FIX: If locating, don't do infinite loops.
+//3 We need a different mode for metadata parsing where we don't loop at all
+ if ((parserMode == eParserModePlay) || (pData->repeatCount != 0))
+ {
+
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Rewinding file for repeat\n"); */ }
+#endif
+ /* rewind to start of loop */
+ if ((result = EAS_HWFileSeek(pEASData->hwInstData, pData->fileHandle, pData->repeatOffset)) != EAS_SUCCESS)
+ return result;
+ IMY_ReadLine(pEASData->hwInstData, pData->fileHandle, pData->buffer, &pData->startLine);
+ pData->index = 0;
+
+ /* if last loop, prevent future loops */
+ if (pData->repeatCount == -1)
+ pData->repeatOffset = -1;
+ }
+ }
+ break;
+
+ /* repeat count */
+ case '@':
+ if (!IMY_GetNumber(pEASData->hwInstData, pData, &temp, EAS_FALSE))
+ eof = EAS_TRUE;
+ else if (pData->repeatOffset > 0)
+ {
+
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Repeat count = %dt", pData->repeatCount); */ }
+#endif
+ if (pData->repeatCount < 0)
+ pData->repeatCount = (EAS_I16) temp;
+ }
+ break;
+
+ /* volume */
+ case 'V':
+ if (!IMY_GetVolume(pEASData->hwInstData, pData, EAS_FALSE))
+ eof = EAS_TRUE;
+ break;
+
+ /* flat */
+ case '&':
+ pData->noteModifier = -1;
+ break;
+
+ /* sharp */
+ case '#':
+ pData->noteModifier = +1;
+ break;
+
+ /* octave */
+ case '*':
+ c = IMY_GetNextChar(pEASData->hwInstData, pData, EAS_FALSE);
+ if (IsDigit(c))
+ pData->octave = (EAS_U8) ((c - '0' + 1) * 12);
+ else if (!c)
+ eof = EAS_TRUE;
+ break;
+
+ /* ledon or ledoff */
+ case 'l':
+ if (!IMY_GetLEDState(pEASData, pData))
+ eof = EAS_TRUE;
+ break;
+
+ /* vibeon or vibeoff */
+ case 'v':
+ if (!IMY_GetVibeState(pEASData, pData))
+ eof = EAS_TRUE;
+ break;
+
+ /* either a B note or backon or backoff */
+ case 'b':
+ if (IMY_GetNextChar(pEASData->hwInstData, pData, EAS_FALSE) == 'a')
+ {
+ if (!IMY_GetBackState(pEASData, pData))
+ eof = EAS_TRUE;
+ }
+ else
+ {
+ PutBackChar(pData);
+ if (IMY_PlayNote(pEASData, pData, c, parserMode))
+ return EAS_SUCCESS;
+ eof = EAS_TRUE;
+ }
+ break;
+
+ /* rest */
+ case 'r':
+ case 'R':
+ if (IMY_PlayRest(pEASData, pData))
+ return EAS_SUCCESS;
+ eof = EAS_TRUE;
+ break;
+
+ /* EOF */
+ case 0:
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_Event: end of iMelody file detected\n"); */ }
+#endif
+ eof = EAS_TRUE;
+ break;
+
+ /* must be a note */
+ default:
+ c = ToLower(c);
+ if ((c >= 'a') && (c <= 'g'))
+ {
+ if (IMY_PlayNote(pEASData, pData, c, parserMode))
+ return EAS_SUCCESS;
+ eof = EAS_TRUE;
+ }
+ else
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Ignoring unexpected character '%c' [0x%02x]\n", c, c); */ }
+ break;
+ }
+ }
+
+ /* handle EOF */
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_Event: state set to EAS_STATE_STOPPING\n"); */ }
+#endif
+ pData->state = EAS_STATE_STOPPING;
+ VMReleaseAllVoices(pEASData->pVoiceMgr, pData->pSynth);
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * IMY_State()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Returns the current state of the stream
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ * pState - pointer to variable to store state
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pEASData) common decoder interface - pEASData not used */
+static EAS_RESULT IMY_State (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 *pState)
+{
+ S_IMELODY_DATA* pData;
+
+ /* establish pointer to instance data */
+ pData = (S_IMELODY_DATA*) pInstData;
+
+ /* if stopping, check to see if synth voices are active */
+ if (pData->state == EAS_STATE_STOPPING)
+ {
+ if (VMActiveVoices(pData->pSynth) == 0)
+ {
+ pData->state = EAS_STATE_STOPPED;
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_State: state set to EAS_STATE_STOPPED\n"); */ }
+#endif
+ }
+ }
+
+ if (pData->state == EAS_STATE_PAUSING)
+ {
+ if (VMActiveVoices(pData->pSynth) == 0)
+ {
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_State: state set to EAS_STATE_PAUSED\n"); */ }
+#endif
+ pData->state = EAS_STATE_PAUSED;
+ }
+ }
+
+ /* return current state */
+ *pState = pData->state;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * IMY_Close()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Close the file and clean up
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT IMY_Close (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
+{
+ S_IMELODY_DATA* pData;
+ EAS_RESULT result;
+
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_Close: close file\n"); */ }
+#endif
+
+ pData = (S_IMELODY_DATA*) pInstData;
+
+ /* close the file */
+ if ((result = EAS_HWCloseFile(pEASData->hwInstData, pData->fileHandle)) != EAS_SUCCESS)
+ return result;
+
+ /* free the synth */
+ if (pData->pSynth != NULL)
+ VMMIDIShutdown(pEASData, pData->pSynth);
+
+ /* if using dynamic memory, free it */
+ if (!pEASData->staticMemoryModel)
+ EAS_HWFree(pEASData->hwInstData, pData);
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * IMY_Reset()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Reset the sequencer. Used for locating backwards in the file.
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT IMY_Reset (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
+{
+ S_IMELODY_DATA* pData;
+ EAS_RESULT result;
+
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_Reset: reset file\n"); */ }
+#endif
+ pData = (S_IMELODY_DATA*) pInstData;
+
+ /* reset the synth */
+ VMReset(pEASData->pVoiceMgr, pData->pSynth, EAS_TRUE);
+
+ /* reset time to zero */
+ pData->time = 0;
+ pData->note = 0;
+
+ /* reset file position and re-parse header */
+ pData->state = EAS_STATE_ERROR;
+ if ((result = EAS_HWFileSeek(pEASData->hwInstData, pData->fileHandle, pData->fileOffset)) != EAS_SUCCESS)
+ return result;
+ if ((result = IMY_ParseHeader (pEASData, pData)) != EAS_SUCCESS)
+ return result;
+
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_Reset: state set to EAS_STATE_ERROR\n"); */ }
+#endif
+
+ pData->state = EAS_STATE_READY;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * IMY_Pause()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Pauses the sequencer. Mutes all voices and sets state to pause.
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT IMY_Pause (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
+{
+ S_IMELODY_DATA *pData;
+
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_Pause: pause file\n"); */ }
+#endif
+
+ /* can't pause a stopped stream */
+ pData = (S_IMELODY_DATA*) pInstData;
+ if (pData->state == EAS_STATE_STOPPED)
+ return EAS_ERROR_ALREADY_STOPPED;
+
+ /* mute the synthesizer */
+ VMMuteAllVoices(pEASData->pVoiceMgr, pData->pSynth);
+ pData->state = EAS_STATE_PAUSING;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * IMY_Resume()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Resume playing after a pause, sets state back to playing.
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pEASData) common decoder interface - pEASData not used */
+static EAS_RESULT IMY_Resume (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
+{
+ S_IMELODY_DATA *pData;
+
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_Resume: resume file\n"); */ }
+#endif
+
+ /* can't resume a stopped stream */
+ pData = (S_IMELODY_DATA*) pInstData;
+ if (pData->state == EAS_STATE_STOPPED)
+ return EAS_ERROR_ALREADY_STOPPED;
+
+ /* nothing to do but resume playback */
+ pData->state = EAS_STATE_PLAY;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * IMY_SetData()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Adjust tempo relative to song tempo
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * pInstData - pointer to iMelody instance data
+ * rate - rate (28-bit fractional amount)
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pEASData) common decoder interface - pEASData not used */
+static EAS_RESULT IMY_SetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value)
+{
+ S_IMELODY_DATA *pData;
+
+ pData = (S_IMELODY_DATA*) pInstData;
+ switch (param)
+ {
+
+ /* set metadata callback */
+ case PARSER_DATA_METADATA_CB:
+ EAS_HWMemCpy(&pData->metadata, (void*) value, sizeof(S_METADATA_CB));
+ break;
+
+ default:
+ return EAS_ERROR_INVALID_PARAMETER;
+ }
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * IMY_GetData()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Return the file type
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * pInstData - pointer to iMelody instance data
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pEASData) common decoder interface - pEASData not used */
+static EAS_RESULT IMY_GetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue)
+{
+ S_IMELODY_DATA *pData;
+
+ pData = (S_IMELODY_DATA*) pInstData;
+
+ switch (param)
+ {
+ /* return file type as iMelody */
+ case PARSER_DATA_FILE_TYPE:
+ *pValue = EAS_FILE_IMELODY;
+ break;
+
+ case PARSER_DATA_SYNTH_HANDLE:
+ *pValue = (EAS_I32) pData->pSynth;
+ break;
+
+ case PARSER_DATA_GAIN_OFFSET:
+ *pValue = IMELODY_GAIN_OFFSET;
+ break;
+
+ default:
+ return EAS_ERROR_INVALID_PARAMETER;
+ }
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * IMY_PlayNote()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ *
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_BOOL IMY_PlayNote (S_EAS_DATA *pEASData, S_IMELODY_DATA *pData, EAS_I8 note, EAS_INT parserMode)
+{
+ EAS_I32 duration;
+ EAS_U8 velocity;
+
+
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_PlayNote: start note %d\n", note); */ }
+#endif
+
+ /* get the duration */
+ if (!IMY_GetDuration(pEASData->hwInstData, pData, &duration))
+ return EAS_FALSE;
+
+ /* save note value */
+ pData->note = (EAS_U8) (pData->octave + noteTable[note - 'a'] + pData->noteModifier);
+ velocity = (EAS_U8) (pData->volume ? pData->volume * IMELODY_VEL_MUL + IMELODY_VEL_OFS : 0);
+
+ /* start note only if in play mode */
+ if (parserMode == eParserModePlay)
+ VMStartNote(pEASData->pVoiceMgr, pData->pSynth, IMELODY_CHANNEL, pData->note, velocity);
+
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_PlayNote: Start note %d, duration %d\n", pData->note, duration); */ }
+#endif
+
+ /* determine note length */
+ switch (pData->style)
+ {
+ case 0:
+ /*lint -e{704} shift for performance */
+ pData->restTicks = duration >> 4;
+ break;
+ case 1:
+ pData->restTicks = 0;
+ break;
+ case 2:
+ /*lint -e{704} shift for performance */
+ pData->restTicks = duration >> 1;
+ break;
+ default:
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "IMY_PlayNote: Note style out of range: %d\n", pData->style); */ }
+ /*lint -e{704} shift for performance */
+ pData->restTicks = duration >> 4;
+ break;
+ }
+
+ /* next event is at end of this note */
+ pData->time += duration - pData->restTicks;
+
+ /* reset the flat/sharp modifier */
+ pData->noteModifier = 0;
+
+ return EAS_TRUE;
+}
+
+/*----------------------------------------------------------------------------
+ * IMY_PlayRest()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ *
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_BOOL IMY_PlayRest (S_EAS_DATA *pEASData, S_IMELODY_DATA *pData)
+{
+ EAS_I32 duration;
+
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Enter IMY_PlayRest]n"); */ }
+#endif
+
+ /* get the duration */
+ if (!IMY_GetDuration(pEASData->hwInstData, pData, &duration))
+ return EAS_FALSE;
+
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_PlayRest: note duration %d\n", duration); */ }
+#endif
+
+ /* next event is at end of this note */
+ pData->time += duration;
+ return EAS_TRUE;
+}
+
+/*----------------------------------------------------------------------------
+ * IMY_GetDuration()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ *
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+
+static EAS_BOOL IMY_GetDuration (EAS_HW_DATA_HANDLE hwInstData, S_IMELODY_DATA *pData, EAS_I32 *pDuration)
+{
+ EAS_I32 duration;
+ EAS_I8 c;
+
+ /* get the duration */
+ *pDuration = 0;
+ c = IMY_GetNextChar(hwInstData, pData, EAS_FALSE);
+ if (!c)
+ return EAS_FALSE;
+ if ((c < '0') || (c > '5'))
+ {
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_GetDuration: error in duration '%c'\n", c); */ }
+#endif
+ return EAS_FALSE;
+ }
+
+ /* calculate total length of note */
+ duration = pData->tick * (1 << ('5' - c));
+
+ /* check for duration modifier */
+ c = IMY_GetNextChar(hwInstData, pData, EAS_FALSE);
+ if (c)
+ {
+ if (c == '.')
+ /*lint -e{704} shift for performance */
+ duration += duration >> 1;
+ else if (c == ':')
+ /*lint -e{704} shift for performance */
+ duration += (duration >> 1) + (duration >> 2);
+ else if (c == ';')
+ /*lint -e{704} shift for performance */
+ duration = (duration * TRIPLET_MULTIPLIER) >> TRIPLET_SHIFT;
+ else
+ PutBackChar(pData);
+ }
+
+ *pDuration = duration;
+ return EAS_TRUE;
+}
+
+/*----------------------------------------------------------------------------
+ * IMY_GetLEDState()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ *
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_BOOL IMY_GetLEDState (S_EAS_DATA *pEASData, S_IMELODY_DATA *pData)
+{
+ EAS_I8 c;
+ EAS_INT i;
+
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Enter IMY_GetLEDState\n"); */ }
+#endif
+
+ for (i = 0; i < 5; i++)
+ {
+ c = IMY_GetNextChar(pEASData->hwInstData, pData, EAS_FALSE);
+ if (!c)
+ return EAS_FALSE;
+ switch (i)
+ {
+ case 3:
+ if (c == 'n')
+ {
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_GetLEDState: LED on\n"); */ }
+#endif
+ EAS_HWLED(pEASData->hwInstData, EAS_TRUE);
+ return EAS_TRUE;
+ }
+ else if (c != 'f')
+ return EAS_FALSE;
+ break;
+
+ case 4:
+ if (c == 'f')
+ {
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_GetLEDState: LED off\n"); */ }
+#endif
+ EAS_HWLED(pEASData->hwInstData, EAS_FALSE);
+ return EAS_TRUE;
+ }
+ return EAS_FALSE;
+
+ default:
+ if (c != ledStr[i])
+ return EAS_FALSE;
+ break;
+ }
+ }
+ return EAS_FALSE;
+}
+
+/*----------------------------------------------------------------------------
+ * IMY_GetVibeState()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ *
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_BOOL IMY_GetVibeState (S_EAS_DATA *pEASData, S_IMELODY_DATA *pData)
+{
+ EAS_I8 c;
+ EAS_INT i;
+
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Enter IMY_GetVibeState\n"); */ }
+#endif
+
+ for (i = 0; i < 6; i++)
+ {
+ c = IMY_GetNextChar(pEASData->hwInstData, pData, EAS_FALSE);
+ if (!c)
+ return EAS_FALSE;
+ switch (i)
+ {
+ case 4:
+ if (c == 'n')
+ {
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_GetVibeState: vibrate on\n"); */ }
+#endif
+ EAS_HWVibrate(pEASData->hwInstData, EAS_TRUE);
+ return EAS_TRUE;
+ }
+ else if (c != 'f')
+ return EAS_FALSE;
+ break;
+
+ case 5:
+ if (c == 'f')
+ {
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_GetVibeState: vibrate off\n"); */ }
+#endif
+ EAS_HWVibrate(pEASData->hwInstData, EAS_FALSE);
+ return EAS_TRUE;
+ }
+ return EAS_FALSE;
+
+ default:
+ if (c != vibeStr[i])
+ return EAS_FALSE;
+ break;
+ }
+ }
+ return EAS_FALSE;
+}
+
+/*----------------------------------------------------------------------------
+ * IMY_GetBackState()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ *
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_BOOL IMY_GetBackState (S_EAS_DATA *pEASData, S_IMELODY_DATA *pData)
+{
+ EAS_I8 c;
+ EAS_INT i;
+
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Enter IMY_GetBackState\n"); */ }
+#endif
+
+ for (i = 0; i < 5; i++)
+ {
+ c = IMY_GetNextChar(pEASData->hwInstData, pData, EAS_FALSE);
+ if (!c)
+ return EAS_FALSE;
+ switch (i)
+ {
+ case 3:
+ if (c == 'n')
+ {
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_GetBackState: backlight on\n"); */ }
+#endif
+ EAS_HWBackLight(pEASData->hwInstData, EAS_TRUE);
+ return EAS_TRUE;
+ }
+ else if (c != 'f')
+ return EAS_FALSE;
+ break;
+
+ case 4:
+ if (c == 'f')
+ {
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_GetBackState: backlight off\n"); */ }
+#endif
+ EAS_HWBackLight(pEASData->hwInstData, EAS_FALSE);
+ return EAS_TRUE;
+ }
+ return EAS_FALSE;
+
+ default:
+ if (c != backStr[i])
+ return EAS_FALSE;
+ break;
+ }
+ }
+ return EAS_FALSE;
+}
+
+/*----------------------------------------------------------------------------
+ * IMY_GetVolume()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ *
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_BOOL IMY_GetVolume (EAS_HW_DATA_HANDLE hwInstData, S_IMELODY_DATA *pData, EAS_BOOL inHeader)
+{
+ EAS_INT temp;
+ EAS_I8 c;
+
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Enter IMY_GetVolume\n"); */ }
+#endif
+
+ c = IMY_GetNextChar(hwInstData, pData, inHeader);
+ if (c == '+')
+ {
+ if (pData->volume < 15)
+ pData->volume++;
+ return EAS_TRUE;
+ }
+ else if (c == '-')
+ {
+ if (pData->volume > 0)
+ pData->volume--;
+ return EAS_TRUE;
+ }
+ else if (IsDigit(c))
+ temp = c - '0';
+ else
+ return EAS_FALSE;
+
+ c = IMY_GetNextChar(hwInstData, pData, inHeader);
+ if (IsDigit(c))
+ temp = temp * 10 + c - '0';
+ else if (c)
+ PutBackChar(pData);
+ if ((temp >= 0) && (temp <= 15))
+ {
+ if (inHeader && (temp == 0))
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Ignoring V0 encountered in header\n"); */ }
+ else
+ pData->volume = (EAS_U8) temp;
+ }
+ return EAS_TRUE;
+}
+
+/*----------------------------------------------------------------------------
+ * IMY_GetNumber()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ *
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_BOOL IMY_GetNumber (EAS_HW_DATA_HANDLE hwInstData, S_IMELODY_DATA *pData, EAS_INT *temp, EAS_BOOL inHeader)
+{
+ EAS_BOOL ok;
+ EAS_I8 c;
+
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Enter IMY_GetNumber\n"); */ }
+#endif
+
+ *temp = 0;
+ ok = EAS_FALSE;
+ for (;;)
+ {
+ c = IMY_GetNextChar(hwInstData, pData, inHeader);
+ if (IsDigit(c))
+ {
+ *temp = *temp * 10 + c - '0';
+ ok = EAS_TRUE;
+ }
+ else
+ {
+ if (c)
+ PutBackChar(pData);
+
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_GetNumber: value %d\n", *temp); */ }
+#endif
+
+ return ok;
+ }
+ }
+}
+
+/*----------------------------------------------------------------------------
+ * IMY_GetVersion()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ *
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_BOOL IMY_GetVersion (S_IMELODY_DATA *pData, EAS_INT *pVersion)
+{
+ EAS_I8 c;
+ EAS_INT temp;
+ EAS_INT version;
+
+ version = temp = 0;
+ for (;;)
+ {
+ c = pData->buffer[pData->index++];
+ if ((c == 0) || (c == '.'))
+ {
+ /*lint -e{701} use shift for performance */
+ version = (version << 8) + temp;
+ if (c == 0)
+ {
+
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_GetVersion: version 0x%04x\n", version); */ }
+#endif
+
+ *pVersion = version;
+ return EAS_TRUE;
+ }
+ temp = 0;
+ }
+ else if (IsDigit(c))
+ temp = (temp * 10) + c - '0';
+ }
+}
+
+/*----------------------------------------------------------------------------
+ * IMY_MetaData()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Prepare to parse the file. Allocates instance data (or uses static allocation for
+ * static memory model).
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static void IMY_MetaData (S_IMELODY_DATA *pData, E_EAS_METADATA_TYPE metaType, EAS_I8 *buffer)
+{
+ EAS_I32 len;
+
+ /* check for callback */
+ if (!pData->metadata.callback)
+ return;
+
+ /* copy data to host buffer */
+ len = (EAS_I32) strlen((char*) buffer);
+ if (len >pData->metadata.bufferSize)
+ len = pData->metadata.bufferSize;
+ strncpy((char*) pData->metadata.buffer, (char*) buffer, (size_t) len);
+ pData->metadata.buffer[len] = 0;
+
+ /* callback to host */
+ pData->metadata.callback(metaType, pData->metadata.buffer, pData->metadata.pUserData);
+}
+
+/*----------------------------------------------------------------------------
+ * IMY_ParseHeader()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Prepare to parse the file. Allocates instance data (or uses static allocation for
+ * static memory model).
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT IMY_ParseHeader (S_EAS_DATA *pEASData, S_IMELODY_DATA* pData)
+{
+ EAS_RESULT result;
+ EAS_INT token;
+ EAS_INT temp;
+ EAS_I8 c;
+
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Enter IMY_ParseHeader\n"); */ }
+#endif
+
+ /* initialize some defaults */
+ pData->time = 0;
+ pData->tick = DEFAULT_TICK_CONV;
+ pData->note = 0;
+ pData->noteModifier = 0;
+ pData ->restTicks = 0;
+ pData->volume = 7;
+ pData->octave = 60;
+ pData->repeatOffset = -1;
+ pData->repeatCount = -1;
+ pData->style = 0;
+
+ /* force the read of the first line */
+ pData->index = 1;
+
+ /* read data until we get to melody */
+ for (;;)
+ {
+ /* read a line from the file and parse the token */
+ if (pData->index != 0)
+ {
+ if ((result = IMY_ReadLine(pEASData->hwInstData, pData->fileHandle, pData->buffer, &pData->startLine)) != EAS_SUCCESS)
+ {
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_ParseHeader: IMY_ReadLine returned %d\n", result); */ }
+#endif
+ return result;
+ }
+ }
+ token = IMY_ParseLine(pData->buffer, &pData->index);
+
+ switch (token)
+ {
+ /* ignore these valid tokens */
+ case TOKEN_BEGIN:
+ break;
+
+ case TOKEN_FORMAT:
+ if (!IMY_GetVersion(pData, &temp))
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Invalid FORMAT field '%s'\n", pData->buffer); */ }
+ return EAS_ERROR_FILE_FORMAT;
+ }
+ if ((temp != 0x0100) && (temp != 0x0200))
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Unsupported FORMAT %02x\n", temp); */ }
+ return EAS_ERROR_UNRECOGNIZED_FORMAT;
+ }
+ break;
+
+ case TOKEN_VERSION:
+ if (!IMY_GetVersion(pData, &temp))
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Invalid VERSION field '%s'\n", pData->buffer); */ }
+ return EAS_ERROR_FILE_FORMAT;
+ }
+ if ((temp != 0x0100) && (temp != 0x0102))
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Unsupported VERSION %02x\n", temp); */ }
+ return EAS_ERROR_UNRECOGNIZED_FORMAT;
+ }
+ break;
+
+ case TOKEN_NAME:
+ IMY_MetaData(pData, EAS_METADATA_TITLE, pData->buffer + pData->index);
+ break;
+
+ case TOKEN_COMPOSER:
+ IMY_MetaData(pData, EAS_METADATA_AUTHOR, pData->buffer + pData->index);
+ break;
+
+ /* handle beat */
+ case TOKEN_BEAT:
+ IMY_GetNumber(pEASData->hwInstData, pData, &temp, EAS_TRUE);
+ if ((temp >= 25) && (temp <= 900))
+ pData->tick = TICK_CONVERT / temp;
+ break;
+
+ /* handle style */
+ case TOKEN_STYLE:
+ c = IMY_GetNextChar(pEASData->hwInstData, pData, EAS_TRUE);
+ if (c == 'S')
+ c = IMY_GetNextChar(pEASData->hwInstData, pData, EAS_TRUE);
+ if ((c >= '0') && (c <= '2'))
+ pData->style = (EAS_U8) (c - '0');
+ else
+ {
+ PutBackChar(pData);
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Error in style command: %s\n", pData->buffer); */ }
+ }
+ break;
+
+ /* handle volume */
+ case TOKEN_VOLUME:
+ c = IMY_GetNextChar(pEASData->hwInstData, pData, EAS_TRUE);
+ if (c != 'V')
+ {
+ PutBackChar(pData);
+ if (!IsDigit(c))
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Error in volume command: %s\n", pData->buffer); */ }
+ break;
+ }
+ }
+ IMY_GetVolume(pEASData->hwInstData, pData, EAS_TRUE);
+ break;
+
+ case TOKEN_MELODY:
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Header successfully parsed\n"); */ }
+#endif
+ return EAS_SUCCESS;
+
+ case TOKEN_END:
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Unexpected END:IMELODY encountered\n"); */ }
+ return EAS_ERROR_FILE_FORMAT;
+
+ default:
+ /* force a read of the next line */
+ pData->index = 1;
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Ignoring unrecognized token in iMelody file: %s\n", pData->buffer); */ }
+ break;
+ }
+ }
+}
+
+/*----------------------------------------------------------------------------
+ * IMY_GetNextChar()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ *
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_I8 IMY_GetNextChar (EAS_HW_DATA_HANDLE hwInstData, S_IMELODY_DATA *pData, EAS_BOOL inHeader)
+{
+ EAS_I8 c;
+ EAS_U8 index;
+
+ for (;;)
+ {
+ /* get next character */
+ c = pData->buffer[pData->index++];
+
+ /* buffer empty, read more */
+ if (!c)
+ {
+ /* don't read the next line in the header */
+ if (inHeader)
+ return 0;
+
+ pData->index = 0;
+ pData->buffer[0] = 0;
+ if (IMY_ReadLine(hwInstData, pData->fileHandle, pData->buffer, &pData->startLine) != EAS_SUCCESS)
+ {
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_GetNextChar: EOF\n"); */ }
+#endif
+ return 0;
+ }
+
+ /* check for END:IMELODY token */
+ if (IMY_ParseLine(pData->buffer, &index) == TOKEN_END)
+ {
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_GetNextChar: found END:IMELODY\n"); */ }
+#endif
+ pData->buffer[0] = 0;
+ return 0;
+ }
+ continue;
+ }
+
+ /* ignore white space */
+ if (!IsSpace(c))
+ {
+
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_GetNextChar returned '%c'\n", c); */ }
+#endif
+ return c;
+ }
+ }
+}
+
+/*----------------------------------------------------------------------------
+ * IMY_ReadLine()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Reads a line of input from the file, discarding the CR/LF
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT IMY_ReadLine (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE fileHandle, EAS_I8 *buffer, EAS_I32 *pStartLine)
+{
+ EAS_RESULT result;
+ EAS_INT i;
+ EAS_I8 c;
+
+ /* fetch current file position and save it */
+ if (pStartLine != NULL)
+ {
+ if ((result = EAS_HWFilePos(hwInstData, fileHandle, pStartLine)) != EAS_SUCCESS)
+ {
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_ParseHeader: EAS_HWFilePos returned %d\n", result); */ }
+#endif
+ return result;
+ }
+ }
+
+ buffer[0] = 0;
+ for (i = 0; i < MAX_LINE_SIZE; )
+ {
+ if ((result = EAS_HWGetByte(hwInstData, fileHandle, &c)) != EAS_SUCCESS)
+ {
+ if ((result == EAS_EOF) && (i > 0))
+ break;
+ return result;
+ }
+
+ /* return on LF or end of data */
+ if (c == '\n')
+ break;
+
+ /* store characters in buffer */
+ if (c != '\r')
+ buffer[i++] = c;
+ }
+ buffer[i] = 0;
+
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_ReadLine read %s\n", buffer); */ }
+#endif
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * IMY_ParseLine()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ *
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_INT IMY_ParseLine (EAS_I8 *buffer, EAS_U8 *pIndex)
+{
+ EAS_INT i;
+ EAS_INT j;
+
+ /* there's no strnicmp() in stdlib, so we have to roll our own */
+ for (i = 0; i < TOKEN_INVALID; i++)
+ {
+ for (j = 0; ; j++)
+ {
+ /* end of token, must be a match */
+ if (tokens[i][j] == 0)
+ {
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_ParseLine found token %d\n", i); */ }
+#endif
+ *pIndex = (EAS_U8) j;
+ return i;
+ }
+ if (tokens[i][j] != ToUpper(buffer[j]))
+ break;
+ }
+ }
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_ParseLine: no token found\n"); */ }
+#endif
+ return TOKEN_INVALID;
+}
+
diff --git a/arm-fm-22k/lib_src/eas_imelodydata.c b/arm-fm-22k/lib_src/eas_imelodydata.c
index e72dc0b..9437e08 100644
--- a/arm-fm-22k/lib_src/eas_imelodydata.c
+++ b/arm-fm-22k/lib_src/eas_imelodydata.c
@@ -1,14 +1,14 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_imelodydata.c
- *
- * Contents and purpose:
- * SMF File Parser
- *
- * This file contains data definitions for the SMF parser.
- *
- * Copyright Sonic Network Inc. 2005
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_imelodydata.c
+ *
+ * Contents and purpose:
+ * SMF File Parser
+ *
+ * This file contains data definitions for the SMF parser.
+ *
+ * Copyright Sonic Network Inc. 2005
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,23 +21,23 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 547 $
- * $Date: 2007-01-31 16:30:17 -0800 (Wed, 31 Jan 2007) $
- *----------------------------------------------------------------------------
-*/
-
-#include "eas_types.h"
-#include "eas_imelodydata.h"
-
-/*----------------------------------------------------------------------------
- *
- * eas_iMelodyData
- *
- * Static memory allocation for iMelody parser
- *----------------------------------------------------------------------------
-*/
-S_IMELODY_DATA eas_iMelodyData;
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 547 $
+ * $Date: 2007-01-31 16:30:17 -0800 (Wed, 31 Jan 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+#include "eas_types.h"
+#include "eas_imelodydata.h"
+
+/*----------------------------------------------------------------------------
+ *
+ * eas_iMelodyData
+ *
+ * Static memory allocation for iMelody parser
+ *----------------------------------------------------------------------------
+*/
+S_IMELODY_DATA eas_iMelodyData;
+
diff --git a/arm-fm-22k/lib_src/eas_imelodydata.h b/arm-fm-22k/lib_src/eas_imelodydata.h
index 303b8f6..57c1ed0 100644
--- a/arm-fm-22k/lib_src/eas_imelodydata.h
+++ b/arm-fm-22k/lib_src/eas_imelodydata.h
@@ -1,14 +1,14 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_imelodydata.h
- *
- * Contents and purpose:
- * SMF File Parser
- *
- * This file contains data declarations for the iMelody parser.
- *
- * Copyright Sonic Network Inc. 2005
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_imelodydata.h
+ *
+ * Contents and purpose:
+ * SMF File Parser
+ *
+ * This file contains data declarations for the iMelody parser.
+ *
+ * Copyright Sonic Network Inc. 2005
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,53 +21,53 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 778 $
- * $Date: 2007-07-23 16:45:17 -0700 (Mon, 23 Jul 2007) $
- *----------------------------------------------------------------------------
-*/
-
-#ifndef EAS_IMELODYDATA_H
-#define EAS_IMELODYDATA_H
-
-#include "eas_data.h"
-
-/* maximum line size as specified in iMelody V1.2 spec */
-#define MAX_LINE_SIZE 75
-
-/*----------------------------------------------------------------------------
- *
- * S_IMELODY_DATA
- *
- * This structure contains the state data for the iMelody parser
- *----------------------------------------------------------------------------
-*/
-
-typedef struct
-{
- EAS_FILE_HANDLE fileHandle; /* file handle */
- S_SYNTH *pSynth; /* pointer to synth */
- EAS_I32 fileOffset; /* offset to start of data */
- EAS_I32 time; /* current time in 256ths of a msec */
- EAS_I32 tickBase; /* basline length of 32nd note in 256th of a msec */
- EAS_I32 tick; /* actual length of 32nd note in 256th of a msec */
- EAS_I32 restTicks; /* ticks to rest after current note */
- EAS_I32 startLine; /* file offset at start of line (for repeats) */
- EAS_I32 repeatOffset; /* file offset to start of repeat section */
- S_METADATA_CB metadata; /* metadata callback */
- EAS_I16 repeatCount; /* repeat counter */
- EAS_U8 state; /* current state EAS_STATE_XXXX */
- EAS_U8 style; /* from STYLE */
- EAS_U8 index; /* index into buffer */
- EAS_U8 octave; /* octave prefix */
- EAS_U8 volume; /* current volume */
- EAS_U8 note; /* MIDI note number */
- EAS_I8 noteModifier; /* sharp or flat */
- EAS_I8 buffer[MAX_LINE_SIZE+1]; /* buffer for ASCII data */
-} S_IMELODY_DATA;
-
-#endif
-
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 778 $
+ * $Date: 2007-07-23 16:45:17 -0700 (Mon, 23 Jul 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+#ifndef EAS_IMELODYDATA_H
+#define EAS_IMELODYDATA_H
+
+#include "eas_data.h"
+
+/* maximum line size as specified in iMelody V1.2 spec */
+#define MAX_LINE_SIZE 75
+
+/*----------------------------------------------------------------------------
+ *
+ * S_IMELODY_DATA
+ *
+ * This structure contains the state data for the iMelody parser
+ *----------------------------------------------------------------------------
+*/
+
+typedef struct
+{
+ EAS_FILE_HANDLE fileHandle; /* file handle */
+ S_SYNTH *pSynth; /* pointer to synth */
+ EAS_I32 fileOffset; /* offset to start of data */
+ EAS_I32 time; /* current time in 256ths of a msec */
+ EAS_I32 tickBase; /* basline length of 32nd note in 256th of a msec */
+ EAS_I32 tick; /* actual length of 32nd note in 256th of a msec */
+ EAS_I32 restTicks; /* ticks to rest after current note */
+ EAS_I32 startLine; /* file offset at start of line (for repeats) */
+ EAS_I32 repeatOffset; /* file offset to start of repeat section */
+ S_METADATA_CB metadata; /* metadata callback */
+ EAS_I16 repeatCount; /* repeat counter */
+ EAS_U8 state; /* current state EAS_STATE_XXXX */
+ EAS_U8 style; /* from STYLE */
+ EAS_U8 index; /* index into buffer */
+ EAS_U8 octave; /* octave prefix */
+ EAS_U8 volume; /* current volume */
+ EAS_U8 note; /* MIDI note number */
+ EAS_I8 noteModifier; /* sharp or flat */
+ EAS_I8 buffer[MAX_LINE_SIZE+1]; /* buffer for ASCII data */
+} S_IMELODY_DATA;
+
+#endif
+
+
diff --git a/arm-fm-22k/lib_src/eas_math.c b/arm-fm-22k/lib_src/eas_math.c
index 12d788e..dc85051 100644
--- a/arm-fm-22k/lib_src/eas_math.c
+++ b/arm-fm-22k/lib_src/eas_math.c
@@ -1,13 +1,13 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_math.c
- *
- * Contents and purpose:
- * Contains common math routines for the various audio engines.
- *
- *
- * Copyright Sonic Network Inc. 2005
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_math.c
+ *
+ * Contents and purpose:
+ * Contains common math routines for the various audio engines.
+ *
+ *
+ * Copyright Sonic Network Inc. 2005
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,149 +20,149 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 586 $
- * $Date: 2007-03-08 20:33:04 -0800 (Thu, 08 Mar 2007) $
- *----------------------------------------------------------------------------
-*/
-
-#include "eas.h"
-#include "eas_math.h"
-
-/* anything less than this converts to a fraction too small to represent in 32-bits */
-#define MIN_CENTS -18000
-
-/*----------------------------------------------------------------------------
- * EAS_Calculate2toX()
- *----------------------------------------------------------------------------
- * Purpose:
- * Calculate 2^x
- *
- * Inputs:
- * nCents - measured in cents
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- * nResult - int.frac result (where frac has NUM_DENTS_FRAC_BITS)
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_I32 EAS_Calculate2toX (EAS_I32 nCents)
-{
- EAS_I32 nDents;
- EAS_I32 nExponentInt, nExponentFrac;
- EAS_I32 nTemp1, nTemp2;
- EAS_I32 nResult;
-
- /* check for minimum value */
- if (nCents < MIN_CENTS)
- return 0;
-
- /* for the time being, convert cents to dents */
- nDents = FMUL_15x15(nCents, CENTS_TO_DENTS);
-
- nExponentInt = GET_DENTS_INT_PART(nDents);
- nExponentFrac = GET_DENTS_FRAC_PART(nDents);
-
- /*
- implement 2^(fracPart) as a power series
- */
- nTemp1 = GN2_TO_X2 + MULT_DENTS_COEF(nExponentFrac, GN2_TO_X3);
- nTemp2 = GN2_TO_X1 + MULT_DENTS_COEF(nExponentFrac, nTemp1);
- nTemp1 = GN2_TO_X0 + MULT_DENTS_COEF(nExponentFrac, nTemp2);
-
- /*
- implement 2^(intPart) as
- a left shift for intPart >= 0 or
- a left shift for intPart < 0
- */
- if (nExponentInt >= 0)
- {
- /* left shift for positive exponents */
- /*lint -e{703} <avoid multiply for performance>*/
- nResult = nTemp1 << nExponentInt;
- }
- else
- {
- /* right shift for negative exponents */
- nExponentInt = -nExponentInt;
- nResult = nTemp1 >> nExponentInt;
- }
-
- return nResult;
-}
-
-/*----------------------------------------------------------------------------
- * EAS_LogToLinear16()
- *----------------------------------------------------------------------------
- * Purpose:
- * Transform log value to linear gain multiplier using piece-wise linear
- * approximation
- *
- * Inputs:
- * nGain - log scale value in 20.10 format. Even though gain is normally
- * stored in 6.10 (16-bit) format we use 32-bit numbers here to eliminate
- * the need for saturation checking when combining gain values.
- *
- * Outputs:
- * Returns a 16-bit linear value approximately equal to 2^(nGain/1024)
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_U16 EAS_LogToLinear16 (EAS_I32 nGain)
-{
- EAS_INT nExp;
- EAS_U16 nTemp;
-
- /* bias to positive */
- nGain += 32767;
-
- /* check for infinite attenuation */
- if (nGain < 0)
- return 0;
-
- /* extract the exponent */
- nExp = 31 - (nGain >> 10);
-
- /* check for maximum output */
- if (nExp < 0)
- return 0x7fff;
-
- /* extract mantissa and restore implied 1 bit */
- nTemp = (EAS_U16)((((nGain & 0x3ff) << 4) | 0x4000) >> nExp);
-
- /* use shift to approximate power-of-2 operation */
- return nTemp;
-}
-
-/*----------------------------------------------------------------------------
- * EAS_VolumeToGain()
- *----------------------------------------------------------------------------
- * Purpose:
- * Transform volume control in 1dB increments to gain multiplier
- *
- * Inputs:
- * volume - 100 = 0dB, 99 = -1dB, 0 = -inf
- *
- * Outputs:
- * Returns a 16-bit linear value
- *----------------------------------------------------------------------------
-*/
-EAS_I16 EAS_VolumeToGain (EAS_INT volume)
-{
- /* check for limits */
- if (volume <= 0)
- return 0;
- if (volume >= 100)
- return 0x7fff;
-
- /*lint -e{702} use shift instead of division */
- return (EAS_I16) EAS_Calculate2toX((((volume - EAS_MAX_VOLUME) * 204099) >> 10) - 1);
-}
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 586 $
+ * $Date: 2007-03-08 20:33:04 -0800 (Thu, 08 Mar 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+#include "eas.h"
+#include "eas_math.h"
+
+/* anything less than this converts to a fraction too small to represent in 32-bits */
+#define MIN_CENTS -18000
+
+/*----------------------------------------------------------------------------
+ * EAS_Calculate2toX()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Calculate 2^x
+ *
+ * Inputs:
+ * nCents - measured in cents
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ * nResult - int.frac result (where frac has NUM_DENTS_FRAC_BITS)
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_I32 EAS_Calculate2toX (EAS_I32 nCents)
+{
+ EAS_I32 nDents;
+ EAS_I32 nExponentInt, nExponentFrac;
+ EAS_I32 nTemp1, nTemp2;
+ EAS_I32 nResult;
+
+ /* check for minimum value */
+ if (nCents < MIN_CENTS)
+ return 0;
+
+ /* for the time being, convert cents to dents */
+ nDents = FMUL_15x15(nCents, CENTS_TO_DENTS);
+
+ nExponentInt = GET_DENTS_INT_PART(nDents);
+ nExponentFrac = GET_DENTS_FRAC_PART(nDents);
+
+ /*
+ implement 2^(fracPart) as a power series
+ */
+ nTemp1 = GN2_TO_X2 + MULT_DENTS_COEF(nExponentFrac, GN2_TO_X3);
+ nTemp2 = GN2_TO_X1 + MULT_DENTS_COEF(nExponentFrac, nTemp1);
+ nTemp1 = GN2_TO_X0 + MULT_DENTS_COEF(nExponentFrac, nTemp2);
+
+ /*
+ implement 2^(intPart) as
+ a left shift for intPart >= 0 or
+ a left shift for intPart < 0
+ */
+ if (nExponentInt >= 0)
+ {
+ /* left shift for positive exponents */
+ /*lint -e{703} <avoid multiply for performance>*/
+ nResult = nTemp1 << nExponentInt;
+ }
+ else
+ {
+ /* right shift for negative exponents */
+ nExponentInt = -nExponentInt;
+ nResult = nTemp1 >> nExponentInt;
+ }
+
+ return nResult;
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_LogToLinear16()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Transform log value to linear gain multiplier using piece-wise linear
+ * approximation
+ *
+ * Inputs:
+ * nGain - log scale value in 20.10 format. Even though gain is normally
+ * stored in 6.10 (16-bit) format we use 32-bit numbers here to eliminate
+ * the need for saturation checking when combining gain values.
+ *
+ * Outputs:
+ * Returns a 16-bit linear value approximately equal to 2^(nGain/1024)
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_U16 EAS_LogToLinear16 (EAS_I32 nGain)
+{
+ EAS_INT nExp;
+ EAS_U16 nTemp;
+
+ /* bias to positive */
+ nGain += 32767;
+
+ /* check for infinite attenuation */
+ if (nGain < 0)
+ return 0;
+
+ /* extract the exponent */
+ nExp = 31 - (nGain >> 10);
+
+ /* check for maximum output */
+ if (nExp < 0)
+ return 0x7fff;
+
+ /* extract mantissa and restore implied 1 bit */
+ nTemp = (EAS_U16)((((nGain & 0x3ff) << 4) | 0x4000) >> nExp);
+
+ /* use shift to approximate power-of-2 operation */
+ return nTemp;
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_VolumeToGain()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Transform volume control in 1dB increments to gain multiplier
+ *
+ * Inputs:
+ * volume - 100 = 0dB, 99 = -1dB, 0 = -inf
+ *
+ * Outputs:
+ * Returns a 16-bit linear value
+ *----------------------------------------------------------------------------
+*/
+EAS_I16 EAS_VolumeToGain (EAS_INT volume)
+{
+ /* check for limits */
+ if (volume <= 0)
+ return 0;
+ if (volume >= 100)
+ return 0x7fff;
+
+ /*lint -e{702} use shift instead of division */
+ return (EAS_I16) EAS_Calculate2toX((((volume - EAS_MAX_VOLUME) * 204099) >> 10) - 1);
+}
+
diff --git a/arm-fm-22k/lib_src/eas_math.h b/arm-fm-22k/lib_src/eas_math.h
index 719270b..f240b51 100644
--- a/arm-fm-22k/lib_src/eas_math.h
+++ b/arm-fm-22k/lib_src/eas_math.h
@@ -1,13 +1,13 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_math.h
- *
- * Contents and purpose:
- * Contains common math routines for the various audio engines.
- *
- *
- * Copyright Sonic Network Inc. 2005
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_math.h
+ *
+ * Contents and purpose:
+ * Contains common math routines for the various audio engines.
+ *
+ *
+ * Copyright Sonic Network Inc. 2005
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,393 +20,393 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 584 $
- * $Date: 2007-03-08 09:49:24 -0800 (Thu, 08 Mar 2007) $
- *----------------------------------------------------------------------------
-*/
-
-#ifndef _EAS_MATH_H
-#define _EAS_MATH_H
-
-
-/** coefs for pan, generates sin, cos */
-#define COEFF_PAN_G2 -27146 /* -0.82842712474619 = 2 - 4/sqrt(2) */
-#define COEFF_PAN_G0 23170 /* 0.707106781186547 = 1/sqrt(2) */
-
-/*
-coefficients for approximating
-2^x = gn2toX0 + gn2toX1*x + gn2toX2*x^2 + gn2toX3*x^3
-where x is a int.frac number representing number of octaves.
-Actually, we approximate only the 2^(frac) using the power series
-and implement the 2^(int) as a shift, so that
-2^x == 2^(int.frac) == 2^(int) * 2^(fract)
- == (gn2toX0 + gn2toX1*x + gn2toX2*x^2 + gn2toX3*x^3) << (int)
-
-The gn2toX.. were generated using a best fit for a 3rd
-order polynomial, instead of taking the coefficients from
-a truncated Taylor (or Maclaurin?) series.
-*/
-
-#define GN2_TO_X0 32768 /* 1 */
-#define GN2_TO_X1 22833 /* 0.696807861328125 */
-#define GN2_TO_X2 7344 /* 0.22412109375 */
-#define GN2_TO_X3 2588 /* 0.0789794921875 */
-
-/*----------------------------------------------------------------------------
- * Fixed Point Math
- *----------------------------------------------------------------------------
- * These macros are used for fixed point multiplies. If the processor
- * supports fixed point multiplies, replace these macros with inline
- * assembly code to improve performance.
- *----------------------------------------------------------------------------
-*/
-
-/* Fixed point multiply 0.15 x 0.15 = 0.15 returned as 32-bits */
-#define FMUL_15x15(a,b) \
- /*lint -e(704) <avoid multiply for performance>*/ \
- (((EAS_I32)(a) * (EAS_I32)(b)) >> 15)
-
-/* Fixed point multiply 0.7 x 0.7 = 0.15 returned as 32-bits */
-#define FMUL_7x7(a,b) \
- /*lint -e(704) <avoid multiply for performance>*/ \
- (((EAS_I32)(a) * (EAS_I32)(b) ) << 1)
-
-/* Fixed point multiply 0.8 x 0.8 = 0.15 returned as 32-bits */
-#define FMUL_8x8(a,b) \
- /*lint -e(704) <avoid multiply for performance>*/ \
- (((EAS_I32)(a) * (EAS_I32)(b) ) >> 1)
-
-/* Fixed point multiply 0.8 x 1.15 = 0.15 returned as 32-bits */
-#define FMUL_8x15(a,b) \
- /*lint -e(704) <avoid divide for performance>*/ \
- (((EAS_I32)((a) << 7) * (EAS_I32)(b)) >> 15)
-
-/* macros for fractional phase accumulator */
-/*
-Note: changed the _U32 to _I32 on 03/14/02. This should not
-affect the phase calculations, and should allow us to reuse these
-macros for other audio sample related math.
-*/
-#define HARDWARE_BIT_WIDTH 32
-
-#define NUM_PHASE_INT_BITS 1
-#define NUM_PHASE_FRAC_BITS 15
-
-#define PHASE_FRAC_MASK (EAS_U32) ((0x1L << NUM_PHASE_FRAC_BITS) -1)
-
-#define GET_PHASE_INT_PART(x) (EAS_U32)((EAS_U32)(x) >> NUM_PHASE_FRAC_BITS)
-#define GET_PHASE_FRAC_PART(x) (EAS_U32)((EAS_U32)(x) & PHASE_FRAC_MASK)
-
-#define DEFAULT_PHASE_FRAC 0
-#define DEFAULT_PHASE_INT 0
-
-/*
-Linear interpolation calculates:
-output = (1-frac) * sample[n] + (frac) * sample[n+1]
-
-where conceptually 0 <= frac < 1
-
-For a fixed point implementation, frac is actually an integer value
-with an implied binary point one position to the left. The value of
-one (unity) is given by PHASE_ONE
-one half and one quarter are useful for 4-point linear interp.
-*/
-#define PHASE_ONE (EAS_I32) (0x1L << NUM_PHASE_FRAC_BITS)
-
-/*
- Multiply the signed audio sample by the unsigned fraction.
-- a is the signed audio sample
-- b is the unsigned fraction (cast to signed int as long as coef
- uses (n-1) or less bits, where n == hardware bit width)
-*/
-#define MULT_AUDIO_COEF(audio,coef) /*lint -e704 <avoid divide for performance>*/ \
- (EAS_I32)( \
- ( \
- ((EAS_I32)(audio)) * ((EAS_I32)(coef)) \
- ) \
- >> NUM_PHASE_FRAC_BITS \
- ) \
- /* lint +704 <restore checking>*/
-
-/* wet / dry calculation macros */
-#define NUM_WET_DRY_FRAC_BITS 7 // 15
-#define NUM_WET_DRY_INT_BITS 9 // 1
-
-/* define a 1.0 */
-#define WET_DRY_ONE (EAS_I32) ((0x1L << NUM_WET_DRY_FRAC_BITS))
-#define WET_DRY_MINUS_ONE (EAS_I32) (~WET_DRY_ONE)
-#define WET_DRY_FULL_SCALE (EAS_I32) (WET_DRY_ONE - 1)
-
-#define MULT_AUDIO_WET_DRY_COEF(audio,coef) /*lint -e(702) <avoid divide for performance>*/ \
- (EAS_I32)( \
- ( \
- ((EAS_I32)(audio)) * ((EAS_I32)(coef)) \
- ) \
- >> NUM_WET_DRY_FRAC_BITS \
- )
-
-/* Envelope 1 (EG1) calculation macros */
-#define NUM_EG1_INT_BITS 1
-#define NUM_EG1_FRAC_BITS 15
-
-/* the max positive gain used in the synth for EG1 */
-/* SYNTH_FULL_SCALE_EG1_GAIN must match the value in the dls2eas
-converter, otherwise, the values we read from the .eas file are bogus. */
-#define SYNTH_FULL_SCALE_EG1_GAIN (EAS_I32) ((0x1L << NUM_EG1_FRAC_BITS) -1)
-
-/* define a 1.0 */
-#define EG1_ONE (EAS_I32) ((0x1L << NUM_EG1_FRAC_BITS))
-#define EG1_MINUS_ONE (EAS_I32) (~SYNTH_FULL_SCALE_EG1_GAIN)
-
-#define EG1_HALF (EAS_I32) (EG1_ONE/2)
-#define EG1_MINUS_HALF (EAS_I32) (EG1_MINUS_ONE/2)
-
-/*
-We implement the EG1 using a linear gain value, which means that the
-attack segment is handled by incrementing (adding) the linear gain.
-However, EG1 treats the Decay, Sustain, and Release differently than
-the Attack portion. For Decay, Sustain, and Release, the gain is
-linear on dB scale, which is equivalent to exponential damping on
-a linear scale. Because we use a linear gain for EG1, we implement
-the Decay and Release as multiplication (instead of incrementing
-as we did for the attack segment).
-Therefore, we need the following macro to implement the multiplication
-(i.e., exponential damping) during the Decay and Release segments of
-the EG1
-*/
-#define MULT_EG1_EG1(gain,damping) /*lint -e(704) <avoid divide for performance>*/ \
- (EAS_I32)( \
- ( \
- ((EAS_I32)(gain)) * ((EAS_I32)(damping)) \
- ) \
- >> NUM_EG1_FRAC_BITS \
- )
-
-// Use the following macro specifically for the filter, when multiplying
-// the b1 coefficient. The 0 <= |b1| < 2, which therefore might overflow
-// in certain conditions because we store b1 as a 1.15 value.
-// Instead, we could store b1 as b1p (b1' == b1 "prime") where
-// b1p == b1/2, thus ensuring no potential overflow for b1p because
-// 0 <= |b1p| < 1
-// However, during the filter calculation, we must account for the fact
-// that we are using b1p instead of b1, and thereby multiply by
-// an extra factor of 2. Rather than multiply by an extra factor of 2,
-// we can instead shift the result right by one less, hence the
-// modified shift right value of (NUM_EG1_FRAC_BITS -1)
-#define MULT_EG1_EG1_X2(gain,damping) /*lint -e(702) <avoid divide for performance>*/ \
- (EAS_I32)( \
- ( \
- ((EAS_I32)(gain)) * ((EAS_I32)(damping)) \
- ) \
- >> (NUM_EG1_FRAC_BITS -1) \
- )
-
-#define SATURATE_EG1(x) /*lint -e{734} saturation operation */ \
- ((EAS_I32)(x) > SYNTH_FULL_SCALE_EG1_GAIN) ? (SYNTH_FULL_SCALE_EG1_GAIN) : \
- ((EAS_I32)(x) < EG1_MINUS_ONE) ? (EG1_MINUS_ONE) : (x);
-
-
-/* use "digital cents" == "dents" instead of cents */
-/* we coudl re-use the phase frac macros, but if we do,
-we must change the phase macros to cast to _I32 instead of _U32,
-because using a _U32 cast causes problems when shifting the exponent
-for the 2^x calculation, because right shift a negative values MUST
-be sign extended, or else the 2^x calculation is wrong */
-
-/* use "digital cents" == "dents" instead of cents */
-#define NUM_DENTS_FRAC_BITS 12
-#define NUM_DENTS_INT_BITS (HARDWARE_BIT_WIDTH - NUM_DENTS_FRAC_BITS)
-
-#define DENTS_FRAC_MASK (EAS_I32) ((0x1L << NUM_DENTS_FRAC_BITS) -1)
-
-#define GET_DENTS_INT_PART(x) /*lint -e(704) <avoid divide for performance>*/ \
- (EAS_I32)((EAS_I32)(x) >> NUM_DENTS_FRAC_BITS)
-
-#define GET_DENTS_FRAC_PART(x) (EAS_I32)((EAS_I32)(x) & DENTS_FRAC_MASK)
-
-#define DENTS_ONE (EAS_I32) (0x1L << NUM_DENTS_FRAC_BITS)
-
-/* use CENTS_TO_DENTS to convert a value in cents to dents */
-#define CENTS_TO_DENTS (EAS_I32) (DENTS_ONE * (0x1L << NUM_EG1_FRAC_BITS) / 1200L) \
-
-
-/*
-For gain, the LFO generates a value that modulates in terms
-of dB. However, we use a linear gain value, so we must convert
-the LFO value in dB to a linear gain. Normally, we would use
-linear gain = 10^x, where x = LFO value in dB / 20.
-Instead, we implement 10^x using our 2^x approximation.
-because
-
- 10^x = 2^(log2(10^x)) = 2^(x * log2(10))
-
-so we need to multiply by log2(10) which is just a constant.
-Ah, but just wait -- our 2^x actually doesn't exactly implement
-2^x, but it actually assumes that the input is in cents, and within
-the 2^x approximation converts its input from cents to octaves
-by dividing its input by 1200.
-
-So, in order to convert the LFO gain value in dB to something
-that our existing 2^x approximation can use, multiply the LFO gain
-by log2(10) * 1200 / 20
-
-The divide by 20 helps convert dB to linear gain, and we might
-as well incorporate that operation into this conversion.
-Of course, we need to keep some fractional bits, so multiply
-the constant by NUM_EG1_FRAC_BITS
-*/
-
-/* use LFO_GAIN_TO_CENTS to convert the LFO gain value to cents */
-#if 0
-#define DOUBLE_LOG2_10 (double) (3.32192809488736) /* log2(10) */
-
-#define DOUBLE_LFO_GAIN_TO_CENTS (double) \
- ( \
- (DOUBLE_LOG2_10) * \
- 1200.0 / \
- 20.0 \
- )
-
-#define LFO_GAIN_TO_CENTS (EAS_I32) \
- ( \
- DOUBLE_LFO_GAIN_TO_CENTS * \
- (0x1L << NUM_EG1_FRAC_BITS) \
- )
-#endif
-
-#define LFO_GAIN_TO_CENTS (EAS_I32) (1671981156L >> (23 - NUM_EG1_FRAC_BITS))
-
-
-#define MULT_DENTS_COEF(dents,coef) /*lint -e704 <avoid divide for performance>*/ \
- (EAS_I32)( \
- ( \
- ((EAS_I32)(dents)) * ((EAS_I32)(coef)) \
- ) \
- >> NUM_DENTS_FRAC_BITS \
- ) \
- /* lint +e704 <restore checking>*/
-
-/* we use 16-bits in the PC per audio sample */
-#define BITS_PER_AUDIO_SAMPLE 16
-
-/* we define 1 as 1.0 - 1 LSbit */
-#define DISTORTION_ONE (EAS_I32)((0x1L << (BITS_PER_AUDIO_SAMPLE-1)) -1)
-#define DISTORTION_MINUS_ONE (EAS_I32)(~DISTORTION_ONE)
-
-/* drive coef is given as int.frac */
-#define NUM_DRIVE_COEF_INT_BITS 1
-#define NUM_DRIVE_COEF_FRAC_BITS 4
-
-#define MULT_AUDIO_DRIVE(audio,drive) /*lint -e(702) <avoid divide for performance>*/ \
- (EAS_I32) ( \
- ( \
- ((EAS_I32)(audio)) * ((EAS_I32)(drive)) \
- ) \
- >> NUM_DRIVE_COEF_FRAC_BITS \
- )
-
-#define MULT_AUDIO_AUDIO(audio1,audio2) /*lint -e(702) <avoid divide for performance>*/ \
- (EAS_I32) ( \
- ( \
- ((EAS_I32)(audio1)) * ((EAS_I32)(audio2)) \
- ) \
- >> (BITS_PER_AUDIO_SAMPLE-1) \
- )
-
-#define SATURATE(x) \
- ((((EAS_I32)(x)) > DISTORTION_ONE) ? (DISTORTION_ONE) : \
- (((EAS_I32)(x)) < DISTORTION_MINUS_ONE) ? (DISTORTION_MINUS_ONE) : ((EAS_I32)(x)));
-
-
-
-/*----------------------------------------------------------------------------
- * EAS_Calculate2toX()
- *----------------------------------------------------------------------------
- * Purpose:
- * Calculate 2^x
- *
- * Inputs:
- * nCents - measured in cents
- *
- * Outputs:
- * nResult - int.frac result (where frac has NUM_DENTS_FRAC_BITS)
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_I32 EAS_Calculate2toX (EAS_I32 nCents);
-
-/*----------------------------------------------------------------------------
- * EAS_LogToLinear16()
- *----------------------------------------------------------------------------
- * Purpose:
- * Transform log value to linear gain multiplier using piece-wise linear
- * approximation
- *
- * Inputs:
- * nGain - log scale value in 20.10 format. Even though gain is normally
- * stored in 6.10 (16-bit) format we use 32-bit numbers here to eliminate
- * the need for saturation checking when combining gain values.
- *
- * Outputs:
- * Returns a 16-bit linear value approximately equal to 2^(nGain/1024)
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_U16 EAS_LogToLinear16 (EAS_I32 nGain);
-
-/*----------------------------------------------------------------------------
- * EAS_VolumeToGain()
- *----------------------------------------------------------------------------
- * Purpose:
- * Transform volume control in 1dB increments to gain multiplier
- *
- * Inputs:
- * volume - 100 = 0dB, 99 = -1dB, 0 = -inf
- *
- * Outputs:
- * Returns a 16-bit linear value
- *----------------------------------------------------------------------------
-*/
-EAS_I16 EAS_VolumeToGain (EAS_INT volume);
-
-/*----------------------------------------------------------------------------
- * EAS_fsqrt()
- *----------------------------------------------------------------------------
- * Purpose:
- * Calculates the square root of a 32-bit fixed point value
- *
- * Inputs:
- * n = value of interest
- *
- * Outputs:
- * returns the square root of n
- *
- *----------------------------------------------------------------------------
-*/
-EAS_U16 EAS_fsqrt (EAS_U32 n);
-
-/*----------------------------------------------------------------------------
- * EAS_flog2()
- *----------------------------------------------------------------------------
- * Purpose:
- * Calculates the log2 of a 32-bit fixed point value
- *
- * Inputs:
- * n = value of interest
- *
- * Outputs:
- * returns the log2 of n
- *
- *----------------------------------------------------------------------------
-*/
-EAS_I32 EAS_flog2 (EAS_U32 n);
-
-#endif
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 584 $
+ * $Date: 2007-03-08 09:49:24 -0800 (Thu, 08 Mar 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+#ifndef _EAS_MATH_H
+#define _EAS_MATH_H
+
+
+/** coefs for pan, generates sin, cos */
+#define COEFF_PAN_G2 -27146 /* -0.82842712474619 = 2 - 4/sqrt(2) */
+#define COEFF_PAN_G0 23170 /* 0.707106781186547 = 1/sqrt(2) */
+
+/*
+coefficients for approximating
+2^x = gn2toX0 + gn2toX1*x + gn2toX2*x^2 + gn2toX3*x^3
+where x is a int.frac number representing number of octaves.
+Actually, we approximate only the 2^(frac) using the power series
+and implement the 2^(int) as a shift, so that
+2^x == 2^(int.frac) == 2^(int) * 2^(fract)
+ == (gn2toX0 + gn2toX1*x + gn2toX2*x^2 + gn2toX3*x^3) << (int)
+
+The gn2toX.. were generated using a best fit for a 3rd
+order polynomial, instead of taking the coefficients from
+a truncated Taylor (or Maclaurin?) series.
+*/
+
+#define GN2_TO_X0 32768 /* 1 */
+#define GN2_TO_X1 22833 /* 0.696807861328125 */
+#define GN2_TO_X2 7344 /* 0.22412109375 */
+#define GN2_TO_X3 2588 /* 0.0789794921875 */
+
+/*----------------------------------------------------------------------------
+ * Fixed Point Math
+ *----------------------------------------------------------------------------
+ * These macros are used for fixed point multiplies. If the processor
+ * supports fixed point multiplies, replace these macros with inline
+ * assembly code to improve performance.
+ *----------------------------------------------------------------------------
+*/
+
+/* Fixed point multiply 0.15 x 0.15 = 0.15 returned as 32-bits */
+#define FMUL_15x15(a,b) \
+ /*lint -e(704) <avoid multiply for performance>*/ \
+ (((EAS_I32)(a) * (EAS_I32)(b)) >> 15)
+
+/* Fixed point multiply 0.7 x 0.7 = 0.15 returned as 32-bits */
+#define FMUL_7x7(a,b) \
+ /*lint -e(704) <avoid multiply for performance>*/ \
+ (((EAS_I32)(a) * (EAS_I32)(b) ) << 1)
+
+/* Fixed point multiply 0.8 x 0.8 = 0.15 returned as 32-bits */
+#define FMUL_8x8(a,b) \
+ /*lint -e(704) <avoid multiply for performance>*/ \
+ (((EAS_I32)(a) * (EAS_I32)(b) ) >> 1)
+
+/* Fixed point multiply 0.8 x 1.15 = 0.15 returned as 32-bits */
+#define FMUL_8x15(a,b) \
+ /*lint -e(704) <avoid divide for performance>*/ \
+ (((EAS_I32)((a) << 7) * (EAS_I32)(b)) >> 15)
+
+/* macros for fractional phase accumulator */
+/*
+Note: changed the _U32 to _I32 on 03/14/02. This should not
+affect the phase calculations, and should allow us to reuse these
+macros for other audio sample related math.
+*/
+#define HARDWARE_BIT_WIDTH 32
+
+#define NUM_PHASE_INT_BITS 1
+#define NUM_PHASE_FRAC_BITS 15
+
+#define PHASE_FRAC_MASK (EAS_U32) ((0x1L << NUM_PHASE_FRAC_BITS) -1)
+
+#define GET_PHASE_INT_PART(x) (EAS_U32)((EAS_U32)(x) >> NUM_PHASE_FRAC_BITS)
+#define GET_PHASE_FRAC_PART(x) (EAS_U32)((EAS_U32)(x) & PHASE_FRAC_MASK)
+
+#define DEFAULT_PHASE_FRAC 0
+#define DEFAULT_PHASE_INT 0
+
+/*
+Linear interpolation calculates:
+output = (1-frac) * sample[n] + (frac) * sample[n+1]
+
+where conceptually 0 <= frac < 1
+
+For a fixed point implementation, frac is actually an integer value
+with an implied binary point one position to the left. The value of
+one (unity) is given by PHASE_ONE
+one half and one quarter are useful for 4-point linear interp.
+*/
+#define PHASE_ONE (EAS_I32) (0x1L << NUM_PHASE_FRAC_BITS)
+
+/*
+ Multiply the signed audio sample by the unsigned fraction.
+- a is the signed audio sample
+- b is the unsigned fraction (cast to signed int as long as coef
+ uses (n-1) or less bits, where n == hardware bit width)
+*/
+#define MULT_AUDIO_COEF(audio,coef) /*lint -e704 <avoid divide for performance>*/ \
+ (EAS_I32)( \
+ ( \
+ ((EAS_I32)(audio)) * ((EAS_I32)(coef)) \
+ ) \
+ >> NUM_PHASE_FRAC_BITS \
+ ) \
+ /* lint +704 <restore checking>*/
+
+/* wet / dry calculation macros */
+#define NUM_WET_DRY_FRAC_BITS 7 // 15
+#define NUM_WET_DRY_INT_BITS 9 // 1
+
+/* define a 1.0 */
+#define WET_DRY_ONE (EAS_I32) ((0x1L << NUM_WET_DRY_FRAC_BITS))
+#define WET_DRY_MINUS_ONE (EAS_I32) (~WET_DRY_ONE)
+#define WET_DRY_FULL_SCALE (EAS_I32) (WET_DRY_ONE - 1)
+
+#define MULT_AUDIO_WET_DRY_COEF(audio,coef) /*lint -e(702) <avoid divide for performance>*/ \
+ (EAS_I32)( \
+ ( \
+ ((EAS_I32)(audio)) * ((EAS_I32)(coef)) \
+ ) \
+ >> NUM_WET_DRY_FRAC_BITS \
+ )
+
+/* Envelope 1 (EG1) calculation macros */
+#define NUM_EG1_INT_BITS 1
+#define NUM_EG1_FRAC_BITS 15
+
+/* the max positive gain used in the synth for EG1 */
+/* SYNTH_FULL_SCALE_EG1_GAIN must match the value in the dls2eas
+converter, otherwise, the values we read from the .eas file are bogus. */
+#define SYNTH_FULL_SCALE_EG1_GAIN (EAS_I32) ((0x1L << NUM_EG1_FRAC_BITS) -1)
+
+/* define a 1.0 */
+#define EG1_ONE (EAS_I32) ((0x1L << NUM_EG1_FRAC_BITS))
+#define EG1_MINUS_ONE (EAS_I32) (~SYNTH_FULL_SCALE_EG1_GAIN)
+
+#define EG1_HALF (EAS_I32) (EG1_ONE/2)
+#define EG1_MINUS_HALF (EAS_I32) (EG1_MINUS_ONE/2)
+
+/*
+We implement the EG1 using a linear gain value, which means that the
+attack segment is handled by incrementing (adding) the linear gain.
+However, EG1 treats the Decay, Sustain, and Release differently than
+the Attack portion. For Decay, Sustain, and Release, the gain is
+linear on dB scale, which is equivalent to exponential damping on
+a linear scale. Because we use a linear gain for EG1, we implement
+the Decay and Release as multiplication (instead of incrementing
+as we did for the attack segment).
+Therefore, we need the following macro to implement the multiplication
+(i.e., exponential damping) during the Decay and Release segments of
+the EG1
+*/
+#define MULT_EG1_EG1(gain,damping) /*lint -e(704) <avoid divide for performance>*/ \
+ (EAS_I32)( \
+ ( \
+ ((EAS_I32)(gain)) * ((EAS_I32)(damping)) \
+ ) \
+ >> NUM_EG1_FRAC_BITS \
+ )
+
+// Use the following macro specifically for the filter, when multiplying
+// the b1 coefficient. The 0 <= |b1| < 2, which therefore might overflow
+// in certain conditions because we store b1 as a 1.15 value.
+// Instead, we could store b1 as b1p (b1' == b1 "prime") where
+// b1p == b1/2, thus ensuring no potential overflow for b1p because
+// 0 <= |b1p| < 1
+// However, during the filter calculation, we must account for the fact
+// that we are using b1p instead of b1, and thereby multiply by
+// an extra factor of 2. Rather than multiply by an extra factor of 2,
+// we can instead shift the result right by one less, hence the
+// modified shift right value of (NUM_EG1_FRAC_BITS -1)
+#define MULT_EG1_EG1_X2(gain,damping) /*lint -e(702) <avoid divide for performance>*/ \
+ (EAS_I32)( \
+ ( \
+ ((EAS_I32)(gain)) * ((EAS_I32)(damping)) \
+ ) \
+ >> (NUM_EG1_FRAC_BITS -1) \
+ )
+
+#define SATURATE_EG1(x) /*lint -e{734} saturation operation */ \
+ ((EAS_I32)(x) > SYNTH_FULL_SCALE_EG1_GAIN) ? (SYNTH_FULL_SCALE_EG1_GAIN) : \
+ ((EAS_I32)(x) < EG1_MINUS_ONE) ? (EG1_MINUS_ONE) : (x);
+
+
+/* use "digital cents" == "dents" instead of cents */
+/* we coudl re-use the phase frac macros, but if we do,
+we must change the phase macros to cast to _I32 instead of _U32,
+because using a _U32 cast causes problems when shifting the exponent
+for the 2^x calculation, because right shift a negative values MUST
+be sign extended, or else the 2^x calculation is wrong */
+
+/* use "digital cents" == "dents" instead of cents */
+#define NUM_DENTS_FRAC_BITS 12
+#define NUM_DENTS_INT_BITS (HARDWARE_BIT_WIDTH - NUM_DENTS_FRAC_BITS)
+
+#define DENTS_FRAC_MASK (EAS_I32) ((0x1L << NUM_DENTS_FRAC_BITS) -1)
+
+#define GET_DENTS_INT_PART(x) /*lint -e(704) <avoid divide for performance>*/ \
+ (EAS_I32)((EAS_I32)(x) >> NUM_DENTS_FRAC_BITS)
+
+#define GET_DENTS_FRAC_PART(x) (EAS_I32)((EAS_I32)(x) & DENTS_FRAC_MASK)
+
+#define DENTS_ONE (EAS_I32) (0x1L << NUM_DENTS_FRAC_BITS)
+
+/* use CENTS_TO_DENTS to convert a value in cents to dents */
+#define CENTS_TO_DENTS (EAS_I32) (DENTS_ONE * (0x1L << NUM_EG1_FRAC_BITS) / 1200L) \
+
+
+/*
+For gain, the LFO generates a value that modulates in terms
+of dB. However, we use a linear gain value, so we must convert
+the LFO value in dB to a linear gain. Normally, we would use
+linear gain = 10^x, where x = LFO value in dB / 20.
+Instead, we implement 10^x using our 2^x approximation.
+because
+
+ 10^x = 2^(log2(10^x)) = 2^(x * log2(10))
+
+so we need to multiply by log2(10) which is just a constant.
+Ah, but just wait -- our 2^x actually doesn't exactly implement
+2^x, but it actually assumes that the input is in cents, and within
+the 2^x approximation converts its input from cents to octaves
+by dividing its input by 1200.
+
+So, in order to convert the LFO gain value in dB to something
+that our existing 2^x approximation can use, multiply the LFO gain
+by log2(10) * 1200 / 20
+
+The divide by 20 helps convert dB to linear gain, and we might
+as well incorporate that operation into this conversion.
+Of course, we need to keep some fractional bits, so multiply
+the constant by NUM_EG1_FRAC_BITS
+*/
+
+/* use LFO_GAIN_TO_CENTS to convert the LFO gain value to cents */
+#if 0
+#define DOUBLE_LOG2_10 (double) (3.32192809488736) /* log2(10) */
+
+#define DOUBLE_LFO_GAIN_TO_CENTS (double) \
+ ( \
+ (DOUBLE_LOG2_10) * \
+ 1200.0 / \
+ 20.0 \
+ )
+
+#define LFO_GAIN_TO_CENTS (EAS_I32) \
+ ( \
+ DOUBLE_LFO_GAIN_TO_CENTS * \
+ (0x1L << NUM_EG1_FRAC_BITS) \
+ )
+#endif
+
+#define LFO_GAIN_TO_CENTS (EAS_I32) (1671981156L >> (23 - NUM_EG1_FRAC_BITS))
+
+
+#define MULT_DENTS_COEF(dents,coef) /*lint -e704 <avoid divide for performance>*/ \
+ (EAS_I32)( \
+ ( \
+ ((EAS_I32)(dents)) * ((EAS_I32)(coef)) \
+ ) \
+ >> NUM_DENTS_FRAC_BITS \
+ ) \
+ /* lint +e704 <restore checking>*/
+
+/* we use 16-bits in the PC per audio sample */
+#define BITS_PER_AUDIO_SAMPLE 16
+
+/* we define 1 as 1.0 - 1 LSbit */
+#define DISTORTION_ONE (EAS_I32)((0x1L << (BITS_PER_AUDIO_SAMPLE-1)) -1)
+#define DISTORTION_MINUS_ONE (EAS_I32)(~DISTORTION_ONE)
+
+/* drive coef is given as int.frac */
+#define NUM_DRIVE_COEF_INT_BITS 1
+#define NUM_DRIVE_COEF_FRAC_BITS 4
+
+#define MULT_AUDIO_DRIVE(audio,drive) /*lint -e(702) <avoid divide for performance>*/ \
+ (EAS_I32) ( \
+ ( \
+ ((EAS_I32)(audio)) * ((EAS_I32)(drive)) \
+ ) \
+ >> NUM_DRIVE_COEF_FRAC_BITS \
+ )
+
+#define MULT_AUDIO_AUDIO(audio1,audio2) /*lint -e(702) <avoid divide for performance>*/ \
+ (EAS_I32) ( \
+ ( \
+ ((EAS_I32)(audio1)) * ((EAS_I32)(audio2)) \
+ ) \
+ >> (BITS_PER_AUDIO_SAMPLE-1) \
+ )
+
+#define SATURATE(x) \
+ ((((EAS_I32)(x)) > DISTORTION_ONE) ? (DISTORTION_ONE) : \
+ (((EAS_I32)(x)) < DISTORTION_MINUS_ONE) ? (DISTORTION_MINUS_ONE) : ((EAS_I32)(x)));
+
+
+
+/*----------------------------------------------------------------------------
+ * EAS_Calculate2toX()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Calculate 2^x
+ *
+ * Inputs:
+ * nCents - measured in cents
+ *
+ * Outputs:
+ * nResult - int.frac result (where frac has NUM_DENTS_FRAC_BITS)
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_I32 EAS_Calculate2toX (EAS_I32 nCents);
+
+/*----------------------------------------------------------------------------
+ * EAS_LogToLinear16()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Transform log value to linear gain multiplier using piece-wise linear
+ * approximation
+ *
+ * Inputs:
+ * nGain - log scale value in 20.10 format. Even though gain is normally
+ * stored in 6.10 (16-bit) format we use 32-bit numbers here to eliminate
+ * the need for saturation checking when combining gain values.
+ *
+ * Outputs:
+ * Returns a 16-bit linear value approximately equal to 2^(nGain/1024)
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_U16 EAS_LogToLinear16 (EAS_I32 nGain);
+
+/*----------------------------------------------------------------------------
+ * EAS_VolumeToGain()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Transform volume control in 1dB increments to gain multiplier
+ *
+ * Inputs:
+ * volume - 100 = 0dB, 99 = -1dB, 0 = -inf
+ *
+ * Outputs:
+ * Returns a 16-bit linear value
+ *----------------------------------------------------------------------------
+*/
+EAS_I16 EAS_VolumeToGain (EAS_INT volume);
+
+/*----------------------------------------------------------------------------
+ * EAS_fsqrt()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Calculates the square root of a 32-bit fixed point value
+ *
+ * Inputs:
+ * n = value of interest
+ *
+ * Outputs:
+ * returns the square root of n
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_U16 EAS_fsqrt (EAS_U32 n);
+
+/*----------------------------------------------------------------------------
+ * EAS_flog2()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Calculates the log2 of a 32-bit fixed point value
+ *
+ * Inputs:
+ * n = value of interest
+ *
+ * Outputs:
+ * returns the log2 of n
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_I32 EAS_flog2 (EAS_U32 n);
+
+#endif
+
diff --git a/arm-fm-22k/lib_src/eas_midi.c b/arm-fm-22k/lib_src/eas_midi.c
index 08aed72..2c0c793 100644
--- a/arm-fm-22k/lib_src/eas_midi.c
+++ b/arm-fm-22k/lib_src/eas_midi.c
@@ -1,13 +1,13 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_midi.c
- *
- * Contents and purpose:
- * This file implements the MIDI stream parser. It is called by eas_smf.c to parse MIDI messages
- * that are streamed out of the file. It can also parse live MIDI streams.
- *
- * Copyright Sonic Network Inc. 2005
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_midi.c
+ *
+ * Contents and purpose:
+ * This file implements the MIDI stream parser. It is called by eas_smf.c to parse MIDI messages
+ * that are streamed out of the file. It can also parse live MIDI streams.
+ *
+ * Copyright Sonic Network Inc. 2005
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,550 +20,550 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 794 $
- * $Date: 2007-08-01 00:08:48 -0700 (Wed, 01 Aug 2007) $
- *----------------------------------------------------------------------------
-*/
-
-#include "eas_data.h"
-#include "eas_report.h"
-#include "eas_miditypes.h"
-#include "eas_midi.h"
-#include "eas_vm_protos.h"
-#include "eas_parser.h"
-
-#ifdef JET_INTERFACE
-#include "jet_data.h"
-#endif
-
-
-/* state enumerations for ProcessSysExMessage */
-typedef enum
-{
- eSysEx,
- eSysExUnivNonRealTime,
- eSysExUnivNrtTargetID,
- eSysExGMControl,
- eSysExUnivRealTime,
- eSysExUnivRtTargetID,
- eSysExDeviceControl,
- eSysExMasterVolume,
- eSysExMasterVolLSB,
- eSysExSPMIDI,
- eSysExSPMIDIchan,
- eSysExSPMIDIMIP,
- eSysExMfgID1,
- eSysExMfgID2,
- eSysExMfgID3,
- eSysExEnhancer,
- eSysExEnhancerSubID,
- eSysExEnhancerFeedback1,
- eSysExEnhancerFeedback2,
- eSysExEnhancerDrive,
- eSysExEnhancerWet,
- eSysExEOX,
- eSysExIgnore
-} E_SYSEX_STATES;
-
-/* local prototypes */
-static EAS_RESULT ProcessMIDIMessage (S_EAS_DATA *pEASData, S_SYNTH *pSynth, S_MIDI_STREAM *pMIDIStream, EAS_INT parserMode);
-static EAS_RESULT ProcessSysExMessage (S_EAS_DATA *pEASData, S_SYNTH *pSynth, S_MIDI_STREAM *pMIDIStream, EAS_U8 c, EAS_INT parserMode);
-
-/*----------------------------------------------------------------------------
- * EAS_InitMIDIStream()
- *----------------------------------------------------------------------------
- * Purpose:
- * Initializes the MIDI stream state for parsing.
- *
- * Inputs:
- *
- * Outputs:
- * returns EAS_RESULT (EAS_SUCCESS is OK)
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-void EAS_InitMIDIStream (S_MIDI_STREAM *pMIDIStream)
-{
- pMIDIStream->byte3 = EAS_FALSE;
- pMIDIStream->pending = EAS_FALSE;
- pMIDIStream->runningStatus = 0;
- pMIDIStream->status = 0;
-}
-
-/*----------------------------------------------------------------------------
- * EAS_ParseMIDIStream()
- *----------------------------------------------------------------------------
- * Purpose:
- * Parses a MIDI input stream character by character. Characters are pushed (rather than pulled)
- * so the interface works equally well for both file and stream I/O.
- *
- * Inputs:
- * c - character from MIDI stream
- *
- * Outputs:
- * returns EAS_RESULT (EAS_SUCCESS is OK)
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT EAS_ParseMIDIStream (S_EAS_DATA *pEASData, S_SYNTH *pSynth, S_MIDI_STREAM *pMIDIStream, EAS_U8 c, EAS_INT parserMode)
-{
-
- /* check for new status byte */
- if (c & 0x80)
- {
- /* save new running status */
- if (c < 0xf8)
- {
- pMIDIStream->runningStatus = c;
- pMIDIStream->byte3 = EAS_FALSE;
-
- /* deal with SysEx */
- if ((c == 0xf7) || (c == 0xf0))
- {
- if (parserMode == eParserModeMetaData)
- return EAS_SUCCESS;
- return ProcessSysExMessage(pEASData, pSynth, pMIDIStream, c, parserMode);
- }
-
- /* inform the file parser that we're in the middle of a message */
- if ((c < 0xf4) || (c > 0xf6))
- pMIDIStream->pending = EAS_TRUE;
- }
-
- /* real-time message - ignore it */
- return EAS_SUCCESS;
- }
-
- /* 3rd byte of a 3-byte message? */
- if (pMIDIStream->byte3)
- {
- pMIDIStream->d2 = c;
- pMIDIStream->byte3 = EAS_FALSE;
- pMIDIStream->pending = EAS_FALSE;
- if (parserMode == eParserModeMetaData)
- return EAS_SUCCESS;
- return ProcessMIDIMessage(pEASData, pSynth, pMIDIStream, parserMode);
- }
-
- /* check for status received */
- if (pMIDIStream->runningStatus)
- {
-
- /* save new status and data byte */
- pMIDIStream->status = pMIDIStream->runningStatus;
-
- /* check for 3-byte messages */
- if (pMIDIStream->status < 0xc0)
- {
- pMIDIStream->d1 = c;
- pMIDIStream->pending = EAS_TRUE;
- pMIDIStream->byte3 = EAS_TRUE;
- return EAS_SUCCESS;
- }
-
- /* check for 2-byte messages */
- if (pMIDIStream->status < 0xe0)
- {
- pMIDIStream->d1 = c;
- pMIDIStream->pending = EAS_FALSE;
- if (parserMode == eParserModeMetaData)
- return EAS_SUCCESS;
- return ProcessMIDIMessage(pEASData, pSynth, pMIDIStream, parserMode);
- }
-
- /* check for more 3-bytes message */
- if (pMIDIStream->status < 0xf0)
- {
- pMIDIStream->d1 = c;
- pMIDIStream->pending = EAS_TRUE;
- pMIDIStream->byte3 = EAS_TRUE;
- return EAS_SUCCESS;
- }
-
- /* SysEx message? */
- if (pMIDIStream->status == 0xF0)
- {
- if (parserMode == eParserModeMetaData)
- return EAS_SUCCESS;
- return ProcessSysExMessage(pEASData, pSynth, pMIDIStream, c, parserMode);
- }
-
- /* remaining messages all clear running status */
- pMIDIStream->runningStatus = 0;
-
- /* F2 is 3-byte message */
- if (pMIDIStream->status == 0xf2)
- {
- pMIDIStream->byte3 = EAS_TRUE;
- return EAS_SUCCESS;
- }
- }
-
- /* no status byte received, provide a warning, but we should be able to recover */
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Received MIDI data without a valid status byte: %d\n",c); */ }
- pMIDIStream->pending = EAS_FALSE;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * ProcessMIDIMessage()
- *----------------------------------------------------------------------------
- * Purpose:
- * This function processes a typical MIDI message. All of the data has been received, just need
- * to take appropriate action.
- *
- * Inputs:
- *
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT ProcessMIDIMessage (S_EAS_DATA *pEASData, S_SYNTH *pSynth, S_MIDI_STREAM *pMIDIStream, EAS_INT parserMode)
-{
- EAS_U8 channel;
-
- channel = pMIDIStream->status & 0x0f;
- switch (pMIDIStream->status & 0xf0)
- {
- case 0x80:
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL,"NoteOff: %02x %02x %02x\n",
- pMIDIStream->status, pMIDIStream->d1, pMIDIStream->d2); */ }
- if (parserMode < eParserModeMute)
- VMStopNote(pEASData->pVoiceMgr, pSynth, channel, pMIDIStream->d1, pMIDIStream->d2);
- break;
-
- case 0x90:
- if (pMIDIStream->d2)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL,"NoteOn: %02x %02x %02x\n",
- pMIDIStream->status, pMIDIStream->d1, pMIDIStream->d2); */ }
- pMIDIStream->flags |= MIDI_FLAG_FIRST_NOTE;
- if (parserMode == eParserModePlay)
- VMStartNote(pEASData->pVoiceMgr, pSynth, channel, pMIDIStream->d1, pMIDIStream->d2);
- }
- else
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL,"NoteOff: %02x %02x %02x\n",
- pMIDIStream->status, pMIDIStream->d1, pMIDIStream->d2); */ }
- if (parserMode < eParserModeMute)
- VMStopNote(pEASData->pVoiceMgr, pSynth, channel, pMIDIStream->d1, pMIDIStream->d2);
- }
- break;
-
- case 0xa0:
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL,"PolyPres: %02x %02x %02x\n",
- pMIDIStream->status, pMIDIStream->d1, pMIDIStream->d2); */ }
- break;
-
- case 0xb0:
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL,"Control: %02x %02x %02x\n",
- pMIDIStream->status, pMIDIStream->d1, pMIDIStream->d2); */ }
- if (parserMode < eParserModeMute)
- VMControlChange(pEASData->pVoiceMgr, pSynth, channel, pMIDIStream->d1, pMIDIStream->d2);
-#ifdef JET_INTERFACE
- if (pMIDIStream->jetData & MIDI_FLAGS_JET_CB)
- {
- JET_Event(pEASData, pMIDIStream->jetData & (JET_EVENT_SEG_MASK | JET_EVENT_TRACK_MASK),
- channel, pMIDIStream->d1, pMIDIStream->d2);
- }
-#endif
- break;
-
- case 0xc0:
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL,"Program: %02x %02x\n",
- pMIDIStream->status, pMIDIStream->d1); */ }
- if (parserMode < eParserModeMute)
- VMProgramChange(pEASData->pVoiceMgr, pSynth, channel, pMIDIStream->d1);
- break;
-
- case 0xd0:
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL,"ChanPres: %02x %02x\n",
- pMIDIStream->status, pMIDIStream->d1); */ }
- if (parserMode < eParserModeMute)
- VMChannelPressure(pSynth, channel, pMIDIStream->d1);
- break;
-
- case 0xe0:
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL,"PBend: %02x %02x %02x\n",
- pMIDIStream->status, pMIDIStream->d1, pMIDIStream->d2); */ }
- if (parserMode < eParserModeMute)
- VMPitchBend(pSynth, channel, pMIDIStream->d1, pMIDIStream->d2);
- break;
-
- default:
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL,"Unknown: %02x %02x %02x\n",
- pMIDIStream->status, pMIDIStream->d1, pMIDIStream->d2); */ }
- }
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * ProcessSysExMessage()
- *----------------------------------------------------------------------------
- * Purpose:
- * Process a SysEx character byte from the MIDI stream. Since we cannot
- * simply wait for the next character to arrive, we are forced to save
- * state after each character. It would be easier to parse at the file
- * level, but then we lose the nice feature of being able to support
- * these messages in a real-time MIDI stream.
- *
- * Inputs:
- * pEASData - pointer to synthesizer instance data
- * c - character to be processed
- * locating - if true, the sequencer is relocating to a new position
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- * Notes:
- * These are the SysEx messages we can receive:
- *
- * SysEx messages
- * { f0 7e 7f 09 01 f7 } GM 1 On
- * { f0 7e 7f 09 02 f7 } GM 1/2 Off
- * { f0 7e 7f 09 03 f7 } GM 2 On
- * { f0 7f 7f 04 01 lsb msb } Master Volume
- * { f0 7f 7f 0b 01 ch mip [ch mip ...] f7 } SP-MIDI
- * { f0 00 01 3a 04 01 fdbk1 fdbk2 drive wet dry f7 } Enhancer
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT ProcessSysExMessage (S_EAS_DATA *pEASData, S_SYNTH *pSynth, S_MIDI_STREAM *pMIDIStream, EAS_U8 c, EAS_INT parserMode)
-{
-
- /* check for start byte */
- if (c == 0xf0)
- {
- pMIDIStream->sysExState = eSysEx;
- }
- /* check for end byte */
- else if (c == 0xf7)
- {
- /* if this was a MIP message, update the MIP table */
- if ((pMIDIStream->sysExState == eSysExSPMIDIchan) && (parserMode != eParserModeMetaData))
- VMUpdateMIPTable(pEASData->pVoiceMgr, pSynth);
- pMIDIStream->sysExState = eSysExIgnore;
- }
-
- /* process SysEx message */
- else
- {
- switch (pMIDIStream->sysExState)
- {
- case eSysEx:
-
- /* first byte, determine message class */
- switch (c)
- {
- case 0x7e:
- pMIDIStream->sysExState = eSysExUnivNonRealTime;
- break;
- case 0x7f:
- pMIDIStream->sysExState = eSysExUnivRealTime;
- break;
- case 0x00:
- pMIDIStream->sysExState = eSysExMfgID1;
- break;
- default:
- pMIDIStream->sysExState = eSysExIgnore;
- break;
- }
- break;
-
- /* process GM message */
- case eSysExUnivNonRealTime:
- if (c == 0x7f)
- pMIDIStream->sysExState = eSysExUnivNrtTargetID;
- else
- pMIDIStream->sysExState = eSysExIgnore;
- break;
-
- case eSysExUnivNrtTargetID:
- if (c == 0x09)
- pMIDIStream->sysExState = eSysExGMControl;
- else
- pMIDIStream->sysExState = eSysExIgnore;
- break;
-
- case eSysExGMControl:
- if ((c == 1) || (c == 3))
- {
- /* GM 1 or GM2 On, reset synth */
- if (parserMode != eParserModeMetaData)
- {
- pMIDIStream->flags |= MIDI_FLAG_GM_ON;
- VMReset(pEASData->pVoiceMgr, pSynth, EAS_FALSE);
- VMInitMIPTable(pSynth);
- }
- pMIDIStream->sysExState = eSysExEOX;
- }
- else
- pMIDIStream->sysExState = eSysExIgnore;
- break;
-
- /* Process Master Volume and SP-MIDI */
- case eSysExUnivRealTime:
- if (c == 0x7f)
- pMIDIStream->sysExState = eSysExUnivRtTargetID;
- else
- pMIDIStream->sysExState = eSysExIgnore;
- break;
-
- case eSysExUnivRtTargetID:
- if (c == 0x04)
- pMIDIStream->sysExState = eSysExDeviceControl;
- else if (c == 0x0b)
- pMIDIStream->sysExState = eSysExSPMIDI;
- else
- pMIDIStream->sysExState = eSysExIgnore;
- break;
-
- /* process master volume */
- case eSysExDeviceControl:
- if (c == 0x01)
- pMIDIStream->sysExState = eSysExMasterVolume;
- else
- pMIDIStream->sysExState = eSysExIgnore;
- break;
-
- case eSysExMasterVolume:
- /* save LSB */
- pMIDIStream->d1 = c;
- pMIDIStream->sysExState = eSysExMasterVolLSB;
- break;
-
- case eSysExMasterVolLSB:
- if (parserMode != eParserModeMetaData)
- {
- EAS_I32 gain = ((EAS_I32) c << 8) | ((EAS_I32) pMIDIStream->d1 << 1);
- gain = (gain * gain) >> 15;
- VMSetVolume(pSynth, (EAS_U16) gain);
- }
- pMIDIStream->sysExState = eSysExEOX;
- break;
-
- /* process SP-MIDI MIP message */
- case eSysExSPMIDI:
- if (c == 0x01)
- {
- /* assume all channels are muted */
- if (parserMode != eParserModeMetaData)
- VMInitMIPTable(pSynth);
- pMIDIStream->d1 = 0;
- pMIDIStream->sysExState = eSysExSPMIDIchan;
- }
- else
- pMIDIStream->sysExState = eSysExIgnore;
- break;
-
- case eSysExSPMIDIchan:
- if (c < NUM_SYNTH_CHANNELS)
- {
- pMIDIStream->d2 = c;
- pMIDIStream->sysExState = eSysExSPMIDIMIP;
- }
- else
- {
- /* bad MIP message - unmute channels */
- if (parserMode != eParserModeMetaData)
- VMInitMIPTable(pSynth);
- pMIDIStream->sysExState = eSysExIgnore;
- }
- break;
-
- case eSysExSPMIDIMIP:
- /* process MIP entry here */
- if (parserMode != eParserModeMetaData)
- VMSetMIPEntry(pEASData->pVoiceMgr, pSynth, pMIDIStream->d2, pMIDIStream->d1, c);
- pMIDIStream->sysExState = eSysExSPMIDIchan;
-
- /* if 16 channels received, update MIP table */
- if (++pMIDIStream->d1 == NUM_SYNTH_CHANNELS)
- {
- if (parserMode != eParserModeMetaData)
- VMUpdateMIPTable(pEASData->pVoiceMgr, pSynth);
- pMIDIStream->sysExState = eSysExEOX;
- }
- break;
-
- /* process Enhancer */
- case eSysExMfgID1:
- if (c == 0x01)
- pMIDIStream->sysExState = eSysExMfgID1;
- else
- pMIDIStream->sysExState = eSysExIgnore;
- break;
-
- case eSysExMfgID2:
- if (c == 0x3a)
- pMIDIStream->sysExState = eSysExMfgID1;
- else
- pMIDIStream->sysExState = eSysExIgnore;
- break;
-
- case eSysExMfgID3:
- if (c == 0x04)
- pMIDIStream->sysExState = eSysExEnhancer;
- else
- pMIDIStream->sysExState = eSysExIgnore;
- break;
-
- case eSysExEnhancer:
- if (c == 0x01)
- pMIDIStream->sysExState = eSysExEnhancerSubID;
- else
- pMIDIStream->sysExState = eSysExIgnore;
- break;
-
- case eSysExEnhancerSubID:
- pMIDIStream->sysExState = eSysExEnhancerFeedback1;
- break;
-
- case eSysExEnhancerFeedback1:
- pMIDIStream->sysExState = eSysExEnhancerFeedback2;
- break;
-
- case eSysExEnhancerFeedback2:
- pMIDIStream->sysExState = eSysExEnhancerDrive;
- break;
-
- case eSysExEnhancerDrive:
- pMIDIStream->sysExState = eSysExEnhancerWet;
- break;
-
- case eSysExEnhancerWet:
- pMIDIStream->sysExState = eSysExEOX;
- break;
-
- case eSysExEOX:
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Expected F7, received %02x\n", c); */ }
- pMIDIStream->sysExState = eSysExIgnore;
- break;
-
- case eSysExIgnore:
- break;
-
- default:
- pMIDIStream->sysExState = eSysExIgnore;
- break;
- }
- }
-
- if (pMIDIStream->sysExState == eSysExIgnore)
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Ignoring SysEx byte %02x\n", c); */ }
- return EAS_SUCCESS;
-} /* end ProcessSysExMessage */
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 794 $
+ * $Date: 2007-08-01 00:08:48 -0700 (Wed, 01 Aug 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+#include "eas_data.h"
+#include "eas_report.h"
+#include "eas_miditypes.h"
+#include "eas_midi.h"
+#include "eas_vm_protos.h"
+#include "eas_parser.h"
+
+#ifdef JET_INTERFACE
+#include "jet_data.h"
+#endif
+
+
+/* state enumerations for ProcessSysExMessage */
+typedef enum
+{
+ eSysEx,
+ eSysExUnivNonRealTime,
+ eSysExUnivNrtTargetID,
+ eSysExGMControl,
+ eSysExUnivRealTime,
+ eSysExUnivRtTargetID,
+ eSysExDeviceControl,
+ eSysExMasterVolume,
+ eSysExMasterVolLSB,
+ eSysExSPMIDI,
+ eSysExSPMIDIchan,
+ eSysExSPMIDIMIP,
+ eSysExMfgID1,
+ eSysExMfgID2,
+ eSysExMfgID3,
+ eSysExEnhancer,
+ eSysExEnhancerSubID,
+ eSysExEnhancerFeedback1,
+ eSysExEnhancerFeedback2,
+ eSysExEnhancerDrive,
+ eSysExEnhancerWet,
+ eSysExEOX,
+ eSysExIgnore
+} E_SYSEX_STATES;
+
+/* local prototypes */
+static EAS_RESULT ProcessMIDIMessage (S_EAS_DATA *pEASData, S_SYNTH *pSynth, S_MIDI_STREAM *pMIDIStream, EAS_INT parserMode);
+static EAS_RESULT ProcessSysExMessage (S_EAS_DATA *pEASData, S_SYNTH *pSynth, S_MIDI_STREAM *pMIDIStream, EAS_U8 c, EAS_INT parserMode);
+
+/*----------------------------------------------------------------------------
+ * EAS_InitMIDIStream()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Initializes the MIDI stream state for parsing.
+ *
+ * Inputs:
+ *
+ * Outputs:
+ * returns EAS_RESULT (EAS_SUCCESS is OK)
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+void EAS_InitMIDIStream (S_MIDI_STREAM *pMIDIStream)
+{
+ pMIDIStream->byte3 = EAS_FALSE;
+ pMIDIStream->pending = EAS_FALSE;
+ pMIDIStream->runningStatus = 0;
+ pMIDIStream->status = 0;
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_ParseMIDIStream()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Parses a MIDI input stream character by character. Characters are pushed (rather than pulled)
+ * so the interface works equally well for both file and stream I/O.
+ *
+ * Inputs:
+ * c - character from MIDI stream
+ *
+ * Outputs:
+ * returns EAS_RESULT (EAS_SUCCESS is OK)
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_ParseMIDIStream (S_EAS_DATA *pEASData, S_SYNTH *pSynth, S_MIDI_STREAM *pMIDIStream, EAS_U8 c, EAS_INT parserMode)
+{
+
+ /* check for new status byte */
+ if (c & 0x80)
+ {
+ /* save new running status */
+ if (c < 0xf8)
+ {
+ pMIDIStream->runningStatus = c;
+ pMIDIStream->byte3 = EAS_FALSE;
+
+ /* deal with SysEx */
+ if ((c == 0xf7) || (c == 0xf0))
+ {
+ if (parserMode == eParserModeMetaData)
+ return EAS_SUCCESS;
+ return ProcessSysExMessage(pEASData, pSynth, pMIDIStream, c, parserMode);
+ }
+
+ /* inform the file parser that we're in the middle of a message */
+ if ((c < 0xf4) || (c > 0xf6))
+ pMIDIStream->pending = EAS_TRUE;
+ }
+
+ /* real-time message - ignore it */
+ return EAS_SUCCESS;
+ }
+
+ /* 3rd byte of a 3-byte message? */
+ if (pMIDIStream->byte3)
+ {
+ pMIDIStream->d2 = c;
+ pMIDIStream->byte3 = EAS_FALSE;
+ pMIDIStream->pending = EAS_FALSE;
+ if (parserMode == eParserModeMetaData)
+ return EAS_SUCCESS;
+ return ProcessMIDIMessage(pEASData, pSynth, pMIDIStream, parserMode);
+ }
+
+ /* check for status received */
+ if (pMIDIStream->runningStatus)
+ {
+
+ /* save new status and data byte */
+ pMIDIStream->status = pMIDIStream->runningStatus;
+
+ /* check for 3-byte messages */
+ if (pMIDIStream->status < 0xc0)
+ {
+ pMIDIStream->d1 = c;
+ pMIDIStream->pending = EAS_TRUE;
+ pMIDIStream->byte3 = EAS_TRUE;
+ return EAS_SUCCESS;
+ }
+
+ /* check for 2-byte messages */
+ if (pMIDIStream->status < 0xe0)
+ {
+ pMIDIStream->d1 = c;
+ pMIDIStream->pending = EAS_FALSE;
+ if (parserMode == eParserModeMetaData)
+ return EAS_SUCCESS;
+ return ProcessMIDIMessage(pEASData, pSynth, pMIDIStream, parserMode);
+ }
+
+ /* check for more 3-bytes message */
+ if (pMIDIStream->status < 0xf0)
+ {
+ pMIDIStream->d1 = c;
+ pMIDIStream->pending = EAS_TRUE;
+ pMIDIStream->byte3 = EAS_TRUE;
+ return EAS_SUCCESS;
+ }
+
+ /* SysEx message? */
+ if (pMIDIStream->status == 0xF0)
+ {
+ if (parserMode == eParserModeMetaData)
+ return EAS_SUCCESS;
+ return ProcessSysExMessage(pEASData, pSynth, pMIDIStream, c, parserMode);
+ }
+
+ /* remaining messages all clear running status */
+ pMIDIStream->runningStatus = 0;
+
+ /* F2 is 3-byte message */
+ if (pMIDIStream->status == 0xf2)
+ {
+ pMIDIStream->byte3 = EAS_TRUE;
+ return EAS_SUCCESS;
+ }
+ }
+
+ /* no status byte received, provide a warning, but we should be able to recover */
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Received MIDI data without a valid status byte: %d\n",c); */ }
+ pMIDIStream->pending = EAS_FALSE;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * ProcessMIDIMessage()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * This function processes a typical MIDI message. All of the data has been received, just need
+ * to take appropriate action.
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT ProcessMIDIMessage (S_EAS_DATA *pEASData, S_SYNTH *pSynth, S_MIDI_STREAM *pMIDIStream, EAS_INT parserMode)
+{
+ EAS_U8 channel;
+
+ channel = pMIDIStream->status & 0x0f;
+ switch (pMIDIStream->status & 0xf0)
+ {
+ case 0x80:
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL,"NoteOff: %02x %02x %02x\n",
+ pMIDIStream->status, pMIDIStream->d1, pMIDIStream->d2); */ }
+ if (parserMode < eParserModeMute)
+ VMStopNote(pEASData->pVoiceMgr, pSynth, channel, pMIDIStream->d1, pMIDIStream->d2);
+ break;
+
+ case 0x90:
+ if (pMIDIStream->d2)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL,"NoteOn: %02x %02x %02x\n",
+ pMIDIStream->status, pMIDIStream->d1, pMIDIStream->d2); */ }
+ pMIDIStream->flags |= MIDI_FLAG_FIRST_NOTE;
+ if (parserMode == eParserModePlay)
+ VMStartNote(pEASData->pVoiceMgr, pSynth, channel, pMIDIStream->d1, pMIDIStream->d2);
+ }
+ else
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL,"NoteOff: %02x %02x %02x\n",
+ pMIDIStream->status, pMIDIStream->d1, pMIDIStream->d2); */ }
+ if (parserMode < eParserModeMute)
+ VMStopNote(pEASData->pVoiceMgr, pSynth, channel, pMIDIStream->d1, pMIDIStream->d2);
+ }
+ break;
+
+ case 0xa0:
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL,"PolyPres: %02x %02x %02x\n",
+ pMIDIStream->status, pMIDIStream->d1, pMIDIStream->d2); */ }
+ break;
+
+ case 0xb0:
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL,"Control: %02x %02x %02x\n",
+ pMIDIStream->status, pMIDIStream->d1, pMIDIStream->d2); */ }
+ if (parserMode < eParserModeMute)
+ VMControlChange(pEASData->pVoiceMgr, pSynth, channel, pMIDIStream->d1, pMIDIStream->d2);
+#ifdef JET_INTERFACE
+ if (pMIDIStream->jetData & MIDI_FLAGS_JET_CB)
+ {
+ JET_Event(pEASData, pMIDIStream->jetData & (JET_EVENT_SEG_MASK | JET_EVENT_TRACK_MASK),
+ channel, pMIDIStream->d1, pMIDIStream->d2);
+ }
+#endif
+ break;
+
+ case 0xc0:
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL,"Program: %02x %02x\n",
+ pMIDIStream->status, pMIDIStream->d1); */ }
+ if (parserMode < eParserModeMute)
+ VMProgramChange(pEASData->pVoiceMgr, pSynth, channel, pMIDIStream->d1);
+ break;
+
+ case 0xd0:
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL,"ChanPres: %02x %02x\n",
+ pMIDIStream->status, pMIDIStream->d1); */ }
+ if (parserMode < eParserModeMute)
+ VMChannelPressure(pSynth, channel, pMIDIStream->d1);
+ break;
+
+ case 0xe0:
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL,"PBend: %02x %02x %02x\n",
+ pMIDIStream->status, pMIDIStream->d1, pMIDIStream->d2); */ }
+ if (parserMode < eParserModeMute)
+ VMPitchBend(pSynth, channel, pMIDIStream->d1, pMIDIStream->d2);
+ break;
+
+ default:
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL,"Unknown: %02x %02x %02x\n",
+ pMIDIStream->status, pMIDIStream->d1, pMIDIStream->d2); */ }
+ }
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * ProcessSysExMessage()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Process a SysEx character byte from the MIDI stream. Since we cannot
+ * simply wait for the next character to arrive, we are forced to save
+ * state after each character. It would be easier to parse at the file
+ * level, but then we lose the nice feature of being able to support
+ * these messages in a real-time MIDI stream.
+ *
+ * Inputs:
+ * pEASData - pointer to synthesizer instance data
+ * c - character to be processed
+ * locating - if true, the sequencer is relocating to a new position
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ * Notes:
+ * These are the SysEx messages we can receive:
+ *
+ * SysEx messages
+ * { f0 7e 7f 09 01 f7 } GM 1 On
+ * { f0 7e 7f 09 02 f7 } GM 1/2 Off
+ * { f0 7e 7f 09 03 f7 } GM 2 On
+ * { f0 7f 7f 04 01 lsb msb } Master Volume
+ * { f0 7f 7f 0b 01 ch mip [ch mip ...] f7 } SP-MIDI
+ * { f0 00 01 3a 04 01 fdbk1 fdbk2 drive wet dry f7 } Enhancer
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT ProcessSysExMessage (S_EAS_DATA *pEASData, S_SYNTH *pSynth, S_MIDI_STREAM *pMIDIStream, EAS_U8 c, EAS_INT parserMode)
+{
+
+ /* check for start byte */
+ if (c == 0xf0)
+ {
+ pMIDIStream->sysExState = eSysEx;
+ }
+ /* check for end byte */
+ else if (c == 0xf7)
+ {
+ /* if this was a MIP message, update the MIP table */
+ if ((pMIDIStream->sysExState == eSysExSPMIDIchan) && (parserMode != eParserModeMetaData))
+ VMUpdateMIPTable(pEASData->pVoiceMgr, pSynth);
+ pMIDIStream->sysExState = eSysExIgnore;
+ }
+
+ /* process SysEx message */
+ else
+ {
+ switch (pMIDIStream->sysExState)
+ {
+ case eSysEx:
+
+ /* first byte, determine message class */
+ switch (c)
+ {
+ case 0x7e:
+ pMIDIStream->sysExState = eSysExUnivNonRealTime;
+ break;
+ case 0x7f:
+ pMIDIStream->sysExState = eSysExUnivRealTime;
+ break;
+ case 0x00:
+ pMIDIStream->sysExState = eSysExMfgID1;
+ break;
+ default:
+ pMIDIStream->sysExState = eSysExIgnore;
+ break;
+ }
+ break;
+
+ /* process GM message */
+ case eSysExUnivNonRealTime:
+ if (c == 0x7f)
+ pMIDIStream->sysExState = eSysExUnivNrtTargetID;
+ else
+ pMIDIStream->sysExState = eSysExIgnore;
+ break;
+
+ case eSysExUnivNrtTargetID:
+ if (c == 0x09)
+ pMIDIStream->sysExState = eSysExGMControl;
+ else
+ pMIDIStream->sysExState = eSysExIgnore;
+ break;
+
+ case eSysExGMControl:
+ if ((c == 1) || (c == 3))
+ {
+ /* GM 1 or GM2 On, reset synth */
+ if (parserMode != eParserModeMetaData)
+ {
+ pMIDIStream->flags |= MIDI_FLAG_GM_ON;
+ VMReset(pEASData->pVoiceMgr, pSynth, EAS_FALSE);
+ VMInitMIPTable(pSynth);
+ }
+ pMIDIStream->sysExState = eSysExEOX;
+ }
+ else
+ pMIDIStream->sysExState = eSysExIgnore;
+ break;
+
+ /* Process Master Volume and SP-MIDI */
+ case eSysExUnivRealTime:
+ if (c == 0x7f)
+ pMIDIStream->sysExState = eSysExUnivRtTargetID;
+ else
+ pMIDIStream->sysExState = eSysExIgnore;
+ break;
+
+ case eSysExUnivRtTargetID:
+ if (c == 0x04)
+ pMIDIStream->sysExState = eSysExDeviceControl;
+ else if (c == 0x0b)
+ pMIDIStream->sysExState = eSysExSPMIDI;
+ else
+ pMIDIStream->sysExState = eSysExIgnore;
+ break;
+
+ /* process master volume */
+ case eSysExDeviceControl:
+ if (c == 0x01)
+ pMIDIStream->sysExState = eSysExMasterVolume;
+ else
+ pMIDIStream->sysExState = eSysExIgnore;
+ break;
+
+ case eSysExMasterVolume:
+ /* save LSB */
+ pMIDIStream->d1 = c;
+ pMIDIStream->sysExState = eSysExMasterVolLSB;
+ break;
+
+ case eSysExMasterVolLSB:
+ if (parserMode != eParserModeMetaData)
+ {
+ EAS_I32 gain = ((EAS_I32) c << 8) | ((EAS_I32) pMIDIStream->d1 << 1);
+ gain = (gain * gain) >> 15;
+ VMSetVolume(pSynth, (EAS_U16) gain);
+ }
+ pMIDIStream->sysExState = eSysExEOX;
+ break;
+
+ /* process SP-MIDI MIP message */
+ case eSysExSPMIDI:
+ if (c == 0x01)
+ {
+ /* assume all channels are muted */
+ if (parserMode != eParserModeMetaData)
+ VMInitMIPTable(pSynth);
+ pMIDIStream->d1 = 0;
+ pMIDIStream->sysExState = eSysExSPMIDIchan;
+ }
+ else
+ pMIDIStream->sysExState = eSysExIgnore;
+ break;
+
+ case eSysExSPMIDIchan:
+ if (c < NUM_SYNTH_CHANNELS)
+ {
+ pMIDIStream->d2 = c;
+ pMIDIStream->sysExState = eSysExSPMIDIMIP;
+ }
+ else
+ {
+ /* bad MIP message - unmute channels */
+ if (parserMode != eParserModeMetaData)
+ VMInitMIPTable(pSynth);
+ pMIDIStream->sysExState = eSysExIgnore;
+ }
+ break;
+
+ case eSysExSPMIDIMIP:
+ /* process MIP entry here */
+ if (parserMode != eParserModeMetaData)
+ VMSetMIPEntry(pEASData->pVoiceMgr, pSynth, pMIDIStream->d2, pMIDIStream->d1, c);
+ pMIDIStream->sysExState = eSysExSPMIDIchan;
+
+ /* if 16 channels received, update MIP table */
+ if (++pMIDIStream->d1 == NUM_SYNTH_CHANNELS)
+ {
+ if (parserMode != eParserModeMetaData)
+ VMUpdateMIPTable(pEASData->pVoiceMgr, pSynth);
+ pMIDIStream->sysExState = eSysExEOX;
+ }
+ break;
+
+ /* process Enhancer */
+ case eSysExMfgID1:
+ if (c == 0x01)
+ pMIDIStream->sysExState = eSysExMfgID1;
+ else
+ pMIDIStream->sysExState = eSysExIgnore;
+ break;
+
+ case eSysExMfgID2:
+ if (c == 0x3a)
+ pMIDIStream->sysExState = eSysExMfgID1;
+ else
+ pMIDIStream->sysExState = eSysExIgnore;
+ break;
+
+ case eSysExMfgID3:
+ if (c == 0x04)
+ pMIDIStream->sysExState = eSysExEnhancer;
+ else
+ pMIDIStream->sysExState = eSysExIgnore;
+ break;
+
+ case eSysExEnhancer:
+ if (c == 0x01)
+ pMIDIStream->sysExState = eSysExEnhancerSubID;
+ else
+ pMIDIStream->sysExState = eSysExIgnore;
+ break;
+
+ case eSysExEnhancerSubID:
+ pMIDIStream->sysExState = eSysExEnhancerFeedback1;
+ break;
+
+ case eSysExEnhancerFeedback1:
+ pMIDIStream->sysExState = eSysExEnhancerFeedback2;
+ break;
+
+ case eSysExEnhancerFeedback2:
+ pMIDIStream->sysExState = eSysExEnhancerDrive;
+ break;
+
+ case eSysExEnhancerDrive:
+ pMIDIStream->sysExState = eSysExEnhancerWet;
+ break;
+
+ case eSysExEnhancerWet:
+ pMIDIStream->sysExState = eSysExEOX;
+ break;
+
+ case eSysExEOX:
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Expected F7, received %02x\n", c); */ }
+ pMIDIStream->sysExState = eSysExIgnore;
+ break;
+
+ case eSysExIgnore:
+ break;
+
+ default:
+ pMIDIStream->sysExState = eSysExIgnore;
+ break;
+ }
+ }
+
+ if (pMIDIStream->sysExState == eSysExIgnore)
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Ignoring SysEx byte %02x\n", c); */ }
+ return EAS_SUCCESS;
+} /* end ProcessSysExMessage */
+
diff --git a/arm-fm-22k/lib_src/eas_midi.h b/arm-fm-22k/lib_src/eas_midi.h
index 37a03ee..10649a0 100644
--- a/arm-fm-22k/lib_src/eas_midi.h
+++ b/arm-fm-22k/lib_src/eas_midi.h
@@ -1,13 +1,13 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_midi.h
- *
- * Contents and purpose:
- * Prototypes for MIDI stream parsing functions
- *
- *
- * Copyright Sonic Network Inc. 2005
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_midi.h
+ *
+ * Contents and purpose:
+ * Prototypes for MIDI stream parsing functions
+ *
+ *
+ * Copyright Sonic Network Inc. 2005
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,52 +20,52 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 82 $
- * $Date: 2006-07-10 11:45:19 -0700 (Mon, 10 Jul 2006) $
- *----------------------------------------------------------------------------
-*/
-
-#ifndef _EAS_MIDI_H
-#define _EAS_MIDI_H
-
-/*----------------------------------------------------------------------------
- * EAS_InitMIDIStream()
- *----------------------------------------------------------------------------
- * Purpose:
- * Initializes the MIDI stream state for parsing.
- *
- * Inputs:
- *
- * Outputs:
- * returns EAS_RESULT (EAS_SUCCESS is OK)
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-void EAS_InitMIDIStream (S_MIDI_STREAM *pMIDIStream);
-
-/*----------------------------------------------------------------------------
- * EAS_ParseMIDIStream()
- *----------------------------------------------------------------------------
- * Purpose:
- * Parses a MIDI input stream character by character. Characters are pushed (rather than pulled)
- * so the interface works equally well for both file and stream I/O.
- *
- * Inputs:
- * c - character from MIDI stream
- *
- * Outputs:
- * returns EAS_RESULT (EAS_SUCCESS is OK)
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT EAS_ParseMIDIStream (S_EAS_DATA *pEASData, S_SYNTH *pSynth, S_MIDI_STREAM *pMIDIStream, EAS_U8 c, EAS_INT parserMode);
-
-#endif /* #define _EAS_MIDI_H */
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 82 $
+ * $Date: 2006-07-10 11:45:19 -0700 (Mon, 10 Jul 2006) $
+ *----------------------------------------------------------------------------
+*/
+
+#ifndef _EAS_MIDI_H
+#define _EAS_MIDI_H
+
+/*----------------------------------------------------------------------------
+ * EAS_InitMIDIStream()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Initializes the MIDI stream state for parsing.
+ *
+ * Inputs:
+ *
+ * Outputs:
+ * returns EAS_RESULT (EAS_SUCCESS is OK)
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+void EAS_InitMIDIStream (S_MIDI_STREAM *pMIDIStream);
+
+/*----------------------------------------------------------------------------
+ * EAS_ParseMIDIStream()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Parses a MIDI input stream character by character. Characters are pushed (rather than pulled)
+ * so the interface works equally well for both file and stream I/O.
+ *
+ * Inputs:
+ * c - character from MIDI stream
+ *
+ * Outputs:
+ * returns EAS_RESULT (EAS_SUCCESS is OK)
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_ParseMIDIStream (S_EAS_DATA *pEASData, S_SYNTH *pSynth, S_MIDI_STREAM *pMIDIStream, EAS_U8 c, EAS_INT parserMode);
+
+#endif /* #define _EAS_MIDI_H */
+
diff --git a/arm-fm-22k/lib_src/eas_midictrl.h b/arm-fm-22k/lib_src/eas_midictrl.h
index 0c4217d..46fdc4f 100644
--- a/arm-fm-22k/lib_src/eas_midictrl.h
+++ b/arm-fm-22k/lib_src/eas_midictrl.h
@@ -1,15 +1,15 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_midictrl.h
- *
- * Contents and purpose:
- * MIDI controller definitions
- *
- * This header only contains declarations that are specific
- * to this implementation.
- *
- * Copyright Sonic Network Inc. 2005
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_midictrl.h
+ *
+ * Contents and purpose:
+ * MIDI controller definitions
+ *
+ * This header only contains declarations that are specific
+ * to this implementation.
+ *
+ * Copyright Sonic Network Inc. 2005
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -22,43 +22,43 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 82 $
- * $Date: 2006-07-10 11:45:19 -0700 (Mon, 10 Jul 2006) $
- *----------------------------------------------------------------------------
-*/
-
-#ifndef _EAS_MIDICTRL_H
-#define _EAS_MIDICTRL_H
-
-/* define controller types */
-/*
- Note that these controller types are specified in base 10 (decimal)
- and not in hexadecimal. The above midi messages are specified
- in hexadecimal.
-*/
-#define MIDI_CONTROLLER_BANK_SELECT 0
-#define MIDI_CONTROLLER_BANK_SELECT_MSB 0
-#define MIDI_CONTROLLER_MOD_WHEEL 1
-#define MIDI_CONTROLLER_ENTER_DATA_MSB 6
-#define MIDI_CONTROLLER_VOLUME 7
-#define MIDI_CONTROLLER_PAN 10
-#define MIDI_CONTROLLER_EXPRESSION 11
-#define MIDI_CONTROLLER_BANK_SELECT_LSB 32
-#define MIDI_CONTROLLER_ENTER_DATA_LSB 38 /* 0x26 */
-#define MIDI_CONTROLLER_SUSTAIN_PEDAL 64
-#define MIDI_CONTROLLER_SELECT_NRPN_LSB 98
-#define MIDI_CONTROLLER_SELECT_NRPN_MSB 99
-#define MIDI_CONTROLLER_SELECT_RPN_LSB 100 /* 0x64 */
-#define MIDI_CONTROLLER_SELECT_RPN_MSB 101 /* 0x65 */
-#define MIDI_CONTROLLER_ALL_SOUND_OFF 120
-#define MIDI_CONTROLLER_RESET_CONTROLLERS 121
-#define MIDI_CONTROLLER_ALL_NOTES_OFF 123
-#define MIDI_CONTROLLER_OMNI_OFF 124
-#define MIDI_CONTROLLER_OMNI_ON 125
-#define MIDI_CONTROLLER_MONO_ON_POLY_OFF 126
-#define MIDI_CONTROLLER_POLY_ON_MONO_OFF 127
-
-#endif /* #ifndef _EAS_MIDICTRL_H */
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 82 $
+ * $Date: 2006-07-10 11:45:19 -0700 (Mon, 10 Jul 2006) $
+ *----------------------------------------------------------------------------
+*/
+
+#ifndef _EAS_MIDICTRL_H
+#define _EAS_MIDICTRL_H
+
+/* define controller types */
+/*
+ Note that these controller types are specified in base 10 (decimal)
+ and not in hexadecimal. The above midi messages are specified
+ in hexadecimal.
+*/
+#define MIDI_CONTROLLER_BANK_SELECT 0
+#define MIDI_CONTROLLER_BANK_SELECT_MSB 0
+#define MIDI_CONTROLLER_MOD_WHEEL 1
+#define MIDI_CONTROLLER_ENTER_DATA_MSB 6
+#define MIDI_CONTROLLER_VOLUME 7
+#define MIDI_CONTROLLER_PAN 10
+#define MIDI_CONTROLLER_EXPRESSION 11
+#define MIDI_CONTROLLER_BANK_SELECT_LSB 32
+#define MIDI_CONTROLLER_ENTER_DATA_LSB 38 /* 0x26 */
+#define MIDI_CONTROLLER_SUSTAIN_PEDAL 64
+#define MIDI_CONTROLLER_SELECT_NRPN_LSB 98
+#define MIDI_CONTROLLER_SELECT_NRPN_MSB 99
+#define MIDI_CONTROLLER_SELECT_RPN_LSB 100 /* 0x64 */
+#define MIDI_CONTROLLER_SELECT_RPN_MSB 101 /* 0x65 */
+#define MIDI_CONTROLLER_ALL_SOUND_OFF 120
+#define MIDI_CONTROLLER_RESET_CONTROLLERS 121
+#define MIDI_CONTROLLER_ALL_NOTES_OFF 123
+#define MIDI_CONTROLLER_OMNI_OFF 124
+#define MIDI_CONTROLLER_OMNI_ON 125
+#define MIDI_CONTROLLER_MONO_ON_POLY_OFF 126
+#define MIDI_CONTROLLER_POLY_ON_MONO_OFF 127
+
+#endif /* #ifndef _EAS_MIDICTRL_H */
diff --git a/arm-fm-22k/lib_src/eas_mididata.c b/arm-fm-22k/lib_src/eas_mididata.c
index 2ee907e..4463b7e 100644
--- a/arm-fm-22k/lib_src/eas_mididata.c
+++ b/arm-fm-22k/lib_src/eas_mididata.c
@@ -1,13 +1,13 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_mididata.c
- *
- * Contents and purpose:
- * Data module for MIDI stream interface
- *
- *
- * Copyright Sonic Network Inc. 2005
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_mididata.c
+ *
+ * Contents and purpose:
+ * Data module for MIDI stream interface
+ *
+ *
+ * Copyright Sonic Network Inc. 2005
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,15 +20,15 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 547 $
- * $Date: 2007-01-31 16:30:17 -0800 (Wed, 31 Jan 2007) $
- *----------------------------------------------------------------------------
-*/
-
-#include "eas_miditypes.h"
-
-S_INTERACTIVE_MIDI eas_MIDIData;
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 547 $
+ * $Date: 2007-01-31 16:30:17 -0800 (Wed, 31 Jan 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+#include "eas_miditypes.h"
+
+S_INTERACTIVE_MIDI eas_MIDIData;
+
diff --git a/arm-fm-22k/lib_src/eas_miditypes.h b/arm-fm-22k/lib_src/eas_miditypes.h
index 0b7f96e..015f08b 100644
--- a/arm-fm-22k/lib_src/eas_miditypes.h
+++ b/arm-fm-22k/lib_src/eas_miditypes.h
@@ -1,13 +1,13 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_miditypes.h
- *
- * Contents and purpose:
- * Contains declarations for the MIDI stream parser.
- *
- *
- * Copyright Sonic Network Inc. 2005
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_miditypes.h
+ *
+ * Contents and purpose:
+ * Contains declarations for the MIDI stream parser.
+ *
+ *
+ * Copyright Sonic Network Inc. 2005
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,119 +20,119 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 778 $
- * $Date: 2007-07-23 16:45:17 -0700 (Mon, 23 Jul 2007) $
- *----------------------------------------------------------------------------
-*/
-
-#ifndef _EAS_MIDITYPES_H
-#define _EAS_MIDITYPES_H
-
-#include "eas_data.h"
-#include "eas_parser.h"
-
-/*----------------------------------------------------------------------------
- * S_MIDI_STREAM
- *
- * Maintains parser state for the MIDI stream parser
- *
- *----------------------------------------------------------------------------
-*/
-
-typedef struct s_midi_stream_tag
-{
- EAS_BOOL8 byte3; /* flag indicates 3rd byte expected */
- EAS_BOOL8 pending; /* flag indicates more data expected */
- EAS_U8 sysExState; /* maintains the SysEx state */
- EAS_U8 runningStatus; /* last running status received */
- EAS_U8 status; /* status byte */
- EAS_U8 d1; /* first data byte */
- EAS_U8 d2; /* second data byte */
- EAS_U8 flags; /* flags - see below for definition */
-#ifdef JET_INTERFACE
- EAS_U32 jetData; /* JET data */
-#endif
-} S_MIDI_STREAM;
-
-/* flags for S_MIDI_STREAM.flags */
-#define MIDI_FLAG_GM_ON 0x01 /* GM System On message received */
-#define MIDI_FLAG_FIRST_NOTE 0x02 /* first note received */
-
-/* flags for S_MIDI_STREAM.jetFlags */
-#define MIDI_FLAGS_JET_MUTE 0x00000001 /* track is muted */
-#define MIDI_FLAGS_JET_CB 0x00000002 /* JET callback enabled */
-
-/*----------------------------------------------------------------------------
- *
- * S_SMF_STREAM
- *
- * This structure contains data required to parse an SMF stream. For SMF0 files, there
- * will be a single instance of this per file. For SMF1 files, there will be multiple instance,
- * one for each separate stream in the file.
- *
- *----------------------------------------------------------------------------
-*/
-
-typedef struct s_smf_stream_tag
-{
- EAS_FILE_HANDLE fileHandle; /* host wrapper file handle */
- EAS_U32 ticks; /* time of next event in stream */
- EAS_I32 startFilePos; /* start location of track within file */
- S_MIDI_STREAM midiStream; /* MIDI stream state */
-} S_SMF_STREAM;
-
-/*----------------------------------------------------------------------------
- *
- * S_SMF_DATA
- *
- * This structure contains the instance data required to parse an SMF stream.
- *
- *----------------------------------------------------------------------------
-*/
-
-typedef struct s_smf_data_tag
-{
-#ifdef _CHECKED_BUILD
- EAS_U32 handleCheck; /* signature check for checked build */
-#endif
- S_SMF_STREAM *streams; /* pointer to individual streams in file */
- S_SMF_STREAM *nextStream; /* pointer to next stream with event */
- S_SYNTH *pSynth; /* pointer to synth */
- EAS_FILE_HANDLE fileHandle; /* file handle */
- S_METADATA_CB metadata; /* metadata callback */
- EAS_I32 fileOffset; /* for embedded files */
- EAS_I32 time; /* current time in milliseconds/256 */
- EAS_U16 numStreams; /* actual number of streams */
- EAS_U16 tickConv; /* current MIDI tick to msec conversion */
- EAS_U16 ppqn; /* ticks per quarter note */
- EAS_U8 state; /* current state EAS_STATE_XXXX */
- EAS_U8 flags; /* flags - see definitions below */
-} S_SMF_DATA;
-
-#define SMF_FLAGS_CHASE_MODE 0x01 /* chase mode - skip to first note */
-#define SMF_FLAGS_HAS_TIME_SIG 0x02 /* time signature encountered at time 0 */
-#define SMF_FLAGS_HAS_TEMPO 0x04 /* tempo encountered at time 0 */
-#define SMF_FLAGS_HAS_GM_ON 0x08 /* GM System On encountered at time 0 */
-#define SMF_FLAGS_JET_STREAM 0x80 /* JET in use - keep strict timing */
-
-/* combo flags indicate setup bar */
-#define SMF_FLAGS_SETUP_BAR (SMF_FLAGS_HAS_TIME_SIG | SMF_FLAGS_HAS_TEMPO | SMF_FLAGS_HAS_GM_ON)
-
-/*----------------------------------------------------------------------------
- * Interactive MIDI structure
- *----------------------------------------------------------------------------
-*/
-typedef struct s_interactive_midi_tag
-{
-#ifdef _CHECKED_BUILD
- EAS_U32 handleCheck; /* signature check for checked build */
-#endif
- S_SYNTH *pSynth; /* pointer to synth */
- S_MIDI_STREAM stream; /* stream data */
-} S_INTERACTIVE_MIDI;
-
-#endif /* #ifndef _EAS_MIDITYPES_H */
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 778 $
+ * $Date: 2007-07-23 16:45:17 -0700 (Mon, 23 Jul 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+#ifndef _EAS_MIDITYPES_H
+#define _EAS_MIDITYPES_H
+
+#include "eas_data.h"
+#include "eas_parser.h"
+
+/*----------------------------------------------------------------------------
+ * S_MIDI_STREAM
+ *
+ * Maintains parser state for the MIDI stream parser
+ *
+ *----------------------------------------------------------------------------
+*/
+
+typedef struct s_midi_stream_tag
+{
+ EAS_BOOL8 byte3; /* flag indicates 3rd byte expected */
+ EAS_BOOL8 pending; /* flag indicates more data expected */
+ EAS_U8 sysExState; /* maintains the SysEx state */
+ EAS_U8 runningStatus; /* last running status received */
+ EAS_U8 status; /* status byte */
+ EAS_U8 d1; /* first data byte */
+ EAS_U8 d2; /* second data byte */
+ EAS_U8 flags; /* flags - see below for definition */
+#ifdef JET_INTERFACE
+ EAS_U32 jetData; /* JET data */
+#endif
+} S_MIDI_STREAM;
+
+/* flags for S_MIDI_STREAM.flags */
+#define MIDI_FLAG_GM_ON 0x01 /* GM System On message received */
+#define MIDI_FLAG_FIRST_NOTE 0x02 /* first note received */
+
+/* flags for S_MIDI_STREAM.jetFlags */
+#define MIDI_FLAGS_JET_MUTE 0x00000001 /* track is muted */
+#define MIDI_FLAGS_JET_CB 0x00000002 /* JET callback enabled */
+
+/*----------------------------------------------------------------------------
+ *
+ * S_SMF_STREAM
+ *
+ * This structure contains data required to parse an SMF stream. For SMF0 files, there
+ * will be a single instance of this per file. For SMF1 files, there will be multiple instance,
+ * one for each separate stream in the file.
+ *
+ *----------------------------------------------------------------------------
+*/
+
+typedef struct s_smf_stream_tag
+{
+ EAS_FILE_HANDLE fileHandle; /* host wrapper file handle */
+ EAS_U32 ticks; /* time of next event in stream */
+ EAS_I32 startFilePos; /* start location of track within file */
+ S_MIDI_STREAM midiStream; /* MIDI stream state */
+} S_SMF_STREAM;
+
+/*----------------------------------------------------------------------------
+ *
+ * S_SMF_DATA
+ *
+ * This structure contains the instance data required to parse an SMF stream.
+ *
+ *----------------------------------------------------------------------------
+*/
+
+typedef struct s_smf_data_tag
+{
+#ifdef _CHECKED_BUILD
+ EAS_U32 handleCheck; /* signature check for checked build */
+#endif
+ S_SMF_STREAM *streams; /* pointer to individual streams in file */
+ S_SMF_STREAM *nextStream; /* pointer to next stream with event */
+ S_SYNTH *pSynth; /* pointer to synth */
+ EAS_FILE_HANDLE fileHandle; /* file handle */
+ S_METADATA_CB metadata; /* metadata callback */
+ EAS_I32 fileOffset; /* for embedded files */
+ EAS_I32 time; /* current time in milliseconds/256 */
+ EAS_U16 numStreams; /* actual number of streams */
+ EAS_U16 tickConv; /* current MIDI tick to msec conversion */
+ EAS_U16 ppqn; /* ticks per quarter note */
+ EAS_U8 state; /* current state EAS_STATE_XXXX */
+ EAS_U8 flags; /* flags - see definitions below */
+} S_SMF_DATA;
+
+#define SMF_FLAGS_CHASE_MODE 0x01 /* chase mode - skip to first note */
+#define SMF_FLAGS_HAS_TIME_SIG 0x02 /* time signature encountered at time 0 */
+#define SMF_FLAGS_HAS_TEMPO 0x04 /* tempo encountered at time 0 */
+#define SMF_FLAGS_HAS_GM_ON 0x08 /* GM System On encountered at time 0 */
+#define SMF_FLAGS_JET_STREAM 0x80 /* JET in use - keep strict timing */
+
+/* combo flags indicate setup bar */
+#define SMF_FLAGS_SETUP_BAR (SMF_FLAGS_HAS_TIME_SIG | SMF_FLAGS_HAS_TEMPO | SMF_FLAGS_HAS_GM_ON)
+
+/*----------------------------------------------------------------------------
+ * Interactive MIDI structure
+ *----------------------------------------------------------------------------
+*/
+typedef struct s_interactive_midi_tag
+{
+#ifdef _CHECKED_BUILD
+ EAS_U32 handleCheck; /* signature check for checked build */
+#endif
+ S_SYNTH *pSynth; /* pointer to synth */
+ S_MIDI_STREAM stream; /* stream data */
+} S_INTERACTIVE_MIDI;
+
+#endif /* #ifndef _EAS_MIDITYPES_H */
+
diff --git a/arm-fm-22k/lib_src/eas_mixbuf.c b/arm-fm-22k/lib_src/eas_mixbuf.c
index 73e969a..db5bd02 100644
--- a/arm-fm-22k/lib_src/eas_mixbuf.c
+++ b/arm-fm-22k/lib_src/eas_mixbuf.c
@@ -1,12 +1,12 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_mixbuf.c
- *
- * Contents and purpose:
- * Contains a data allocation for synthesizer
- *
- * Copyright Sonic Network Inc. 2004
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_mixbuf.c
+ *
+ * Contents and purpose:
+ * Contains a data allocation for synthesizer
+ *
+ * Copyright Sonic Network Inc. 2004
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,18 +19,18 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 82 $
- * $Date: 2006-07-10 11:45:19 -0700 (Mon, 10 Jul 2006) $
- *----------------------------------------------------------------------------
-*/
-
-// includes
-#include "eas_data.h"
-#include "eas_mixer.h"
-
-// globals
-EAS_I32 eas_MixBuffer[BUFFER_SIZE_IN_MONO_SAMPLES * NUM_OUTPUT_CHANNELS];
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 82 $
+ * $Date: 2006-07-10 11:45:19 -0700 (Mon, 10 Jul 2006) $
+ *----------------------------------------------------------------------------
+*/
+
+// includes
+#include "eas_data.h"
+#include "eas_mixer.h"
+
+// globals
+EAS_I32 eas_MixBuffer[BUFFER_SIZE_IN_MONO_SAMPLES * NUM_OUTPUT_CHANNELS];
+
diff --git a/arm-fm-22k/lib_src/eas_mixer.c b/arm-fm-22k/lib_src/eas_mixer.c
index c4a2f9f..0a839a8 100644
--- a/arm-fm-22k/lib_src/eas_mixer.c
+++ b/arm-fm-22k/lib_src/eas_mixer.c
@@ -1,13 +1,13 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_mixer.c
- *
- * Contents and purpose:
- * This file contains the critical components of the mix engine that
- * must be optimized for best performance.
- *
- * Copyright Sonic Network Inc. 2005
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_mixer.c
+ *
+ * Contents and purpose:
+ * This file contains the critical components of the mix engine that
+ * must be optimized for best performance.
+ *
+ * Copyright Sonic Network Inc. 2005
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,445 +20,445 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 706 $
- * $Date: 2007-05-31 17:22:51 -0700 (Thu, 31 May 2007) $
- *----------------------------------------------------------------------------
-*/
-
-//3 dls: This module is in the midst of being converted from a synth
-//3 specific module to a general purpose mix engine
-
-/*------------------------------------
- * includes
- *------------------------------------
-*/
-#include "eas_data.h"
-#include "eas_host.h"
-#include "eas_math.h"
-#include "eas_mixer.h"
-#include "eas_config.h"
-#include "eas_report.h"
-
-#ifdef _MAXIMIZER_ENABLED
-EAS_I32 MaximizerProcess (EAS_VOID_PTR pInstData, EAS_I32 *pSrc, EAS_I32 *pDst, EAS_I32 numSamples);
-#endif
-
-/*------------------------------------
- * defines
- *------------------------------------
-*/
-
-/* need to boost stereo by ~3dB to compensate for the panner */
-#define STEREO_3DB_GAIN_BOOST 512
-
-/*----------------------------------------------------------------------------
- * EAS_MixEngineInit()
- *----------------------------------------------------------------------------
- * Purpose:
- * Prepares the mix engine for work, allocates buffers, locates effects modules, etc.
- *
- * Inputs:
- * pEASData - instance data
- * pInstData - pointer to variable to receive instance data handle
- *
- * Outputs:
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT EAS_MixEngineInit (S_EAS_DATA *pEASData)
-{
-
- /* check Configuration Module for mix buffer allocation */
- if (pEASData->staticMemoryModel)
- pEASData->pMixBuffer = EAS_CMEnumData(EAS_CM_MIX_BUFFER);
- else
- pEASData->pMixBuffer = EAS_HWMalloc(pEASData->hwInstData, BUFFER_SIZE_IN_MONO_SAMPLES * NUM_OUTPUT_CHANNELS * sizeof(EAS_I32));
- if (pEASData->pMixBuffer == NULL)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_FATAL, "Failed to allocate mix buffer memory\n"); */ }
- return EAS_ERROR_MALLOC_FAILED;
- }
- EAS_HWMemSet((void *)(pEASData->pMixBuffer), 0, BUFFER_SIZE_IN_MONO_SAMPLES * NUM_OUTPUT_CHANNELS * sizeof(EAS_I32));
-
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * EAS_MixEnginePrep()
- *----------------------------------------------------------------------------
- * Purpose:
- * Performs prep before synthesize a buffer of audio, such as clearing
- * audio buffers, etc.
- *
- * Inputs:
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-void EAS_MixEnginePrep (S_EAS_DATA *pEASData, EAS_I32 numSamples)
-{
-
- /* clear the mix buffer */
-#if (NUM_OUTPUT_CHANNELS == 2)
- EAS_HWMemSet(pEASData->pMixBuffer, 0, numSamples * (EAS_I32) sizeof(long) * 2);
-#else
- EAS_HWMemSet(pEASData->pMixBuffer, 0, (EAS_I32) numSamples * (EAS_I32) sizeof(long));
-#endif
-
- /* need to clear other side-chain effect buffers (chorus & reverb) */
-}
-
-/*----------------------------------------------------------------------------
- * EAS_MixEnginePost
- *----------------------------------------------------------------------------
- * Purpose:
- * This routine does the post-processing after all voices have been
- * synthesized. It calls any sweeteners and does the final mixdown to
- * the output buffer.
- *
- * Inputs:
- *
- * Outputs:
- *
- * Notes:
- *----------------------------------------------------------------------------
-*/
-void EAS_MixEnginePost (S_EAS_DATA *pEASData, EAS_I32 numSamples)
-{
- EAS_U16 gain;
-
-//3 dls: Need to restore the mix engine metrics
-
- /* calculate the gain multiplier */
-#ifdef _MAXIMIZER_ENABLED
- if (pEASData->effectsModules[EAS_MODULE_MAXIMIZER].effect)
- {
- EAS_I32 temp;
- temp = MaximizerProcess(pEASData->effectsModules[EAS_MODULE_MAXIMIZER].effectData, pEASData->pMixBuffer, pEASData->pMixBuffer, numSamples);
- temp = (temp * pEASData->masterGain) >> 15;
- if (temp > 32767)
- gain = 32767;
- else
- gain = (EAS_U16) temp;
- }
- else
- gain = (EAS_U16) pEASData->masterGain;
-#else
- gain = (EAS_U16) pEASData->masterGain;
-#endif
-
- /* Not using all the gain bits for now
- * Reduce the input to the compressor by 6dB to prevent saturation
- */
-#ifdef _COMPRESSOR_ENABLED
- if (pEASData->effectsModules[EAS_MODULE_COMPRESSOR].effectData)
- gain = gain >> 5;
- else
- gain = gain >> 4;
-#else
- gain = gain >> 4;
-#endif
-
- /* convert 32-bit mix buffer to 16-bit output format */
-#if (NUM_OUTPUT_CHANNELS == 2)
- SynthMasterGain(pEASData->pMixBuffer, pEASData->pOutputAudioBuffer, gain, (EAS_U16) ((EAS_U16) numSamples * 2));
-#else
- SynthMasterGain(pEASData->pMixBuffer, pEASData->pOutputAudioBuffer, gain, (EAS_U16) numSamples);
-#endif
-
-#ifdef _ENHANCER_ENABLED
- /* enhancer effect */
- if (pEASData->effectsModules[EAS_MODULE_ENHANCER].effectData)
- (*pEASData->effectsModules[EAS_MODULE_ENHANCER].effect->pfProcess)
- (pEASData->effectsModules[EAS_MODULE_ENHANCER].effectData,
- pEASData->pOutputAudioBuffer,
- pEASData->pOutputAudioBuffer,
- numSamples);
-#endif
-
-#ifdef _GRAPHIC_EQ_ENABLED
- /* graphic EQ effect */
- if (pEASData->effectsModules[EAS_MODULE_GRAPHIC_EQ].effectData)
- (*pEASData->effectsModules[EAS_MODULE_GRAPHIC_EQ].effect->pfProcess)
- (pEASData->effectsModules[EAS_MODULE_GRAPHIC_EQ].effectData,
- pEASData->pOutputAudioBuffer,
- pEASData->pOutputAudioBuffer,
- numSamples);
-#endif
-
-#ifdef _COMPRESSOR_ENABLED
- /* compressor effect */
- if (pEASData->effectsModules[EAS_MODULE_COMPRESSOR].effectData)
- (*pEASData->effectsModules[EAS_MODULE_COMPRESSOR].effect->pfProcess)
- (pEASData->effectsModules[EAS_MODULE_COMPRESSOR].effectData,
- pEASData->pOutputAudioBuffer,
- pEASData->pOutputAudioBuffer,
- numSamples);
-#endif
-
-#ifdef _WOW_ENABLED
- /* WOW requires a 32-bit buffer, borrow the mix buffer and
- * pass it as the destination buffer
- */
- /*lint -e{740} temporarily passing a parameter through an existing I/F */
- if (pEASData->effectsModules[EAS_MODULE_WOW].effectData)
- (*pEASData->effectsModules[EAS_MODULE_WOW].effect->pfProcess)
- (pEASData->effectsModules[EAS_MODULE_WOW].effectData,
- pEASData->pOutputAudioBuffer,
- (EAS_PCM*) pEASData->pMixBuffer,
- numSamples);
-#endif
-
-#ifdef _TONECONTROLEQ_ENABLED
- /* ToneControlEQ effect */
- if (pEASData->effectsModules[EAS_MODULE_TONECONTROLEQ].effectData)
- (*pEASData->effectsModules[EAS_MODULE_TONECONTROLEQ].effect->pfProcess)
- (pEASData->effectsModules[EAS_MODULE_TONECONTROLEQ].effectData,
- pEASData->pOutputAudioBuffer,
- pEASData->pOutputAudioBuffer,
- numSamples);
-#endif
-
-#ifdef _REVERB_ENABLED
- /* Reverb effect */
- if (pEASData->effectsModules[EAS_MODULE_REVERB].effectData)
- (*pEASData->effectsModules[EAS_MODULE_REVERB].effect->pfProcess)
- (pEASData->effectsModules[EAS_MODULE_REVERB].effectData,
- pEASData->pOutputAudioBuffer,
- pEASData->pOutputAudioBuffer,
- numSamples);
-#endif
-
-#ifdef _CHORUS_ENABLED
- /* Chorus effect */
- if (pEASData->effectsModules[EAS_MODULE_CHORUS].effectData)
- (*pEASData->effectsModules[EAS_MODULE_CHORUS].effect->pfProcess)
- (pEASData->effectsModules[EAS_MODULE_CHORUS].effectData,
- pEASData->pOutputAudioBuffer,
- pEASData->pOutputAudioBuffer,
- numSamples);
-#endif
-
-}
-
-#ifndef NATIVE_EAS_KERNEL
-/*----------------------------------------------------------------------------
- * SynthMasterGain
- *----------------------------------------------------------------------------
- * Purpose:
- * Mixes down audio from 32-bit to 16-bit target buffer
- *
- * Inputs:
- *
- * Outputs:
- *
- *----------------------------------------------------------------------------
-*/
-void SynthMasterGain (long *pInputBuffer, EAS_PCM *pOutputBuffer, EAS_U16 nGain, EAS_U16 numSamples) {
-
- /* loop through the buffer */
- while (numSamples--) {
- long s;
-
- /* read a sample from the input buffer and add some guard bits */
- s = *pInputBuffer++;
-
- /* add some guard bits */
- /*lint -e{704} <avoid divide for performance>*/
- s = s >> 7;
-
- /* apply master gain */
- s *= (long) nGain;
-
- /* shift to lower 16-bits */
- /*lint -e{704} <avoid divide for performance>*/
- s = s >> 9;
-
- /* saturate */
- s = SATURATE(s);
-
- *pOutputBuffer++ = (EAS_PCM)s;
- }
-}
-#endif
-
-/*----------------------------------------------------------------------------
- * EAS_MixEngineShutdown()
- *----------------------------------------------------------------------------
- * Purpose:
- * Shuts down effects modules and deallocates memory
- *
- * Inputs:
- * pEASData - instance data
- * pInstData - instance data handle
- *
- * Outputs:
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT EAS_MixEngineShutdown (S_EAS_DATA *pEASData)
-{
-
- /* check Configuration Module for static memory allocation */
- if (!pEASData->staticMemoryModel && (pEASData->pMixBuffer != NULL))
- EAS_HWFree(pEASData->hwInstData, pEASData->pMixBuffer);
-
- return EAS_SUCCESS;
-}
-
-#ifdef UNIFIED_MIXER
-#ifndef NATIVE_MIX_STREAM
-/*----------------------------------------------------------------------------
- * EAS_MixStream
- *----------------------------------------------------------------------------
- * Mix a 16-bit stream into a 32-bit buffer
- *
- * pInputBuffer 16-bit input buffer
- * pMixBuffer 32-bit mix buffer
- * numSamples number of samples to mix
- * gainLeft initial gain left or mono
- * gainRight initial gain right
- * gainLeft left gain increment per sample
- * gainRight right gain increment per sample
- * flags bit 0 = stereo source
- * bit 1 = stereo output
- *----------------------------------------------------------------------------
-*/
-void EAS_MixStream (EAS_PCM *pInputBuffer, EAS_I32 *pMixBuffer, EAS_I32 numSamples, EAS_I32 gainLeft, EAS_I32 gainRight, EAS_I32 gainIncLeft, EAS_I32 gainIncRight, EAS_I32 flags)
-{
- EAS_I32 temp;
- EAS_INT src, dest;
-
- /* NOTE: There are a lot of optimizations that can be done
- * in the native implementations based on register
- * availability, etc. For example, it may make sense to
- * break this down into 8 separate routines:
- *
- * 1. Mono source to mono output
- * 2. Mono source to stereo output
- * 3. Stereo source to mono output
- * 4. Stereo source to stereo output
- * 5. Mono source to mono output - no gain change
- * 6. Mono source to stereo output - no gain change
- * 7. Stereo source to mono output - no gain change
- * 8. Stereo source to stereo output - no gain change
- *
- * Other possibilities include loop unrolling, skipping
- * a gain calculation every 2 or 4 samples, etc.
- */
-
- /* no gain change, use fast loops */
- if ((gainIncLeft == 0) && (gainIncRight == 0))
- {
- switch (flags & (MIX_FLAGS_STEREO_SOURCE | MIX_FLAGS_STEREO_OUTPUT))
- {
- /* mono to mono */
- case 0:
- gainLeft >>= 15;
- for (src = dest = 0; src < numSamples; src++, dest++)
- {
-
- pMixBuffer[dest] += (pInputBuffer[src] * gainLeft) >> NUM_MIXER_GUARD_BITS;
- }
- break;
-
- /* mono to stereo */
- case MIX_FLAGS_STEREO_OUTPUT:
- gainLeft >>= 15;
- gainRight >>= 15;
- for (src = dest = 0; src < numSamples; src++, dest+=2)
- {
- pMixBuffer[dest] += (pInputBuffer[src] * gainLeft) >> NUM_MIXER_GUARD_BITS;
- pMixBuffer[dest+1] += (pInputBuffer[src] * gainRight) >> NUM_MIXER_GUARD_BITS;
- }
- break;
-
- /* stereo to mono */
- case MIX_FLAGS_STEREO_SOURCE:
- gainLeft >>= 15;
- gainRight >>= 15;
- for (src = dest = 0; src < numSamples; src+=2, dest++)
- {
- temp = (pInputBuffer[src] * gainLeft) >> NUM_MIXER_GUARD_BITS;
- temp += ((pInputBuffer[src+1] * gainRight) >> NUM_MIXER_GUARD_BITS);
- pMixBuffer[dest] += temp;
- }
- break;
-
- /* stereo to stereo */
- case MIX_FLAGS_STEREO_SOURCE | MIX_FLAGS_STEREO_OUTPUT:
- gainLeft >>= 15;
- gainRight >>= 15;
- for (src = dest = 0; src < numSamples; src+=2, dest+=2)
- {
- pMixBuffer[dest] += (pInputBuffer[src] * gainLeft) >> NUM_MIXER_GUARD_BITS;
- pMixBuffer[dest+1] += (pInputBuffer[src+1] * gainRight) >> NUM_MIXER_GUARD_BITS;
- }
- break;
- }
- }
-
- /* gain change - do gain increment */
- else
- {
- switch (flags & (MIX_FLAGS_STEREO_SOURCE | MIX_FLAGS_STEREO_OUTPUT))
- {
- /* mono to mono */
- case 0:
- for (src = dest = 0; src < numSamples; src++, dest++)
- {
- gainLeft += gainIncLeft;
- pMixBuffer[dest] += (pInputBuffer[src] * (gainLeft >> 15)) >> NUM_MIXER_GUARD_BITS;
- }
- break;
-
- /* mono to stereo */
- case MIX_FLAGS_STEREO_OUTPUT:
- for (src = dest = 0; src < numSamples; src++, dest+=2)
- {
- gainLeft += gainIncLeft;
- gainRight += gainIncRight;
- pMixBuffer[dest] += (pInputBuffer[src] * (gainLeft >> 15)) >> NUM_MIXER_GUARD_BITS;
- pMixBuffer[dest+1] += (pInputBuffer[src] * (gainRight >> 15)) >> NUM_MIXER_GUARD_BITS;
- }
- break;
-
- /* stereo to mono */
- case MIX_FLAGS_STEREO_SOURCE:
- for (src = dest = 0; src < numSamples; src+=2, dest++)
- {
- gainLeft += gainIncLeft;
- gainRight += gainIncRight;
- temp = (pInputBuffer[src] * (gainLeft >> 15)) >> NUM_MIXER_GUARD_BITS;
- temp += ((pInputBuffer[src+1] * (gainRight >> 15)) >> NUM_MIXER_GUARD_BITS);
- pMixBuffer[dest] += temp;
- }
- break;
-
- /* stereo to stereo */
- case MIX_FLAGS_STEREO_SOURCE | MIX_FLAGS_STEREO_OUTPUT:
- for (src = dest = 0; src < numSamples; src+=2, dest+=2)
- {
- gainLeft += gainIncLeft;
- gainRight += gainIncRight;
- pMixBuffer[dest] += (pInputBuffer[src] * (gainLeft >> 15)) >> NUM_MIXER_GUARD_BITS;
- pMixBuffer[dest+1] += (pInputBuffer[src+1] * (gainRight >> 15)) >> NUM_MIXER_GUARD_BITS;
- }
- break;
- }
- }
-}
-#endif
-#endif
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 706 $
+ * $Date: 2007-05-31 17:22:51 -0700 (Thu, 31 May 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+//3 dls: This module is in the midst of being converted from a synth
+//3 specific module to a general purpose mix engine
+
+/*------------------------------------
+ * includes
+ *------------------------------------
+*/
+#include "eas_data.h"
+#include "eas_host.h"
+#include "eas_math.h"
+#include "eas_mixer.h"
+#include "eas_config.h"
+#include "eas_report.h"
+
+#ifdef _MAXIMIZER_ENABLED
+EAS_I32 MaximizerProcess (EAS_VOID_PTR pInstData, EAS_I32 *pSrc, EAS_I32 *pDst, EAS_I32 numSamples);
+#endif
+
+/*------------------------------------
+ * defines
+ *------------------------------------
+*/
+
+/* need to boost stereo by ~3dB to compensate for the panner */
+#define STEREO_3DB_GAIN_BOOST 512
+
+/*----------------------------------------------------------------------------
+ * EAS_MixEngineInit()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Prepares the mix engine for work, allocates buffers, locates effects modules, etc.
+ *
+ * Inputs:
+ * pEASData - instance data
+ * pInstData - pointer to variable to receive instance data handle
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_MixEngineInit (S_EAS_DATA *pEASData)
+{
+
+ /* check Configuration Module for mix buffer allocation */
+ if (pEASData->staticMemoryModel)
+ pEASData->pMixBuffer = EAS_CMEnumData(EAS_CM_MIX_BUFFER);
+ else
+ pEASData->pMixBuffer = EAS_HWMalloc(pEASData->hwInstData, BUFFER_SIZE_IN_MONO_SAMPLES * NUM_OUTPUT_CHANNELS * sizeof(EAS_I32));
+ if (pEASData->pMixBuffer == NULL)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_FATAL, "Failed to allocate mix buffer memory\n"); */ }
+ return EAS_ERROR_MALLOC_FAILED;
+ }
+ EAS_HWMemSet((void *)(pEASData->pMixBuffer), 0, BUFFER_SIZE_IN_MONO_SAMPLES * NUM_OUTPUT_CHANNELS * sizeof(EAS_I32));
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_MixEnginePrep()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Performs prep before synthesize a buffer of audio, such as clearing
+ * audio buffers, etc.
+ *
+ * Inputs:
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+void EAS_MixEnginePrep (S_EAS_DATA *pEASData, EAS_I32 numSamples)
+{
+
+ /* clear the mix buffer */
+#if (NUM_OUTPUT_CHANNELS == 2)
+ EAS_HWMemSet(pEASData->pMixBuffer, 0, numSamples * (EAS_I32) sizeof(long) * 2);
+#else
+ EAS_HWMemSet(pEASData->pMixBuffer, 0, (EAS_I32) numSamples * (EAS_I32) sizeof(long));
+#endif
+
+ /* need to clear other side-chain effect buffers (chorus & reverb) */
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_MixEnginePost
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * This routine does the post-processing after all voices have been
+ * synthesized. It calls any sweeteners and does the final mixdown to
+ * the output buffer.
+ *
+ * Inputs:
+ *
+ * Outputs:
+ *
+ * Notes:
+ *----------------------------------------------------------------------------
+*/
+void EAS_MixEnginePost (S_EAS_DATA *pEASData, EAS_I32 numSamples)
+{
+ EAS_U16 gain;
+
+//3 dls: Need to restore the mix engine metrics
+
+ /* calculate the gain multiplier */
+#ifdef _MAXIMIZER_ENABLED
+ if (pEASData->effectsModules[EAS_MODULE_MAXIMIZER].effect)
+ {
+ EAS_I32 temp;
+ temp = MaximizerProcess(pEASData->effectsModules[EAS_MODULE_MAXIMIZER].effectData, pEASData->pMixBuffer, pEASData->pMixBuffer, numSamples);
+ temp = (temp * pEASData->masterGain) >> 15;
+ if (temp > 32767)
+ gain = 32767;
+ else
+ gain = (EAS_U16) temp;
+ }
+ else
+ gain = (EAS_U16) pEASData->masterGain;
+#else
+ gain = (EAS_U16) pEASData->masterGain;
+#endif
+
+ /* Not using all the gain bits for now
+ * Reduce the input to the compressor by 6dB to prevent saturation
+ */
+#ifdef _COMPRESSOR_ENABLED
+ if (pEASData->effectsModules[EAS_MODULE_COMPRESSOR].effectData)
+ gain = gain >> 5;
+ else
+ gain = gain >> 4;
+#else
+ gain = gain >> 4;
+#endif
+
+ /* convert 32-bit mix buffer to 16-bit output format */
+#if (NUM_OUTPUT_CHANNELS == 2)
+ SynthMasterGain(pEASData->pMixBuffer, pEASData->pOutputAudioBuffer, gain, (EAS_U16) ((EAS_U16) numSamples * 2));
+#else
+ SynthMasterGain(pEASData->pMixBuffer, pEASData->pOutputAudioBuffer, gain, (EAS_U16) numSamples);
+#endif
+
+#ifdef _ENHANCER_ENABLED
+ /* enhancer effect */
+ if (pEASData->effectsModules[EAS_MODULE_ENHANCER].effectData)
+ (*pEASData->effectsModules[EAS_MODULE_ENHANCER].effect->pfProcess)
+ (pEASData->effectsModules[EAS_MODULE_ENHANCER].effectData,
+ pEASData->pOutputAudioBuffer,
+ pEASData->pOutputAudioBuffer,
+ numSamples);
+#endif
+
+#ifdef _GRAPHIC_EQ_ENABLED
+ /* graphic EQ effect */
+ if (pEASData->effectsModules[EAS_MODULE_GRAPHIC_EQ].effectData)
+ (*pEASData->effectsModules[EAS_MODULE_GRAPHIC_EQ].effect->pfProcess)
+ (pEASData->effectsModules[EAS_MODULE_GRAPHIC_EQ].effectData,
+ pEASData->pOutputAudioBuffer,
+ pEASData->pOutputAudioBuffer,
+ numSamples);
+#endif
+
+#ifdef _COMPRESSOR_ENABLED
+ /* compressor effect */
+ if (pEASData->effectsModules[EAS_MODULE_COMPRESSOR].effectData)
+ (*pEASData->effectsModules[EAS_MODULE_COMPRESSOR].effect->pfProcess)
+ (pEASData->effectsModules[EAS_MODULE_COMPRESSOR].effectData,
+ pEASData->pOutputAudioBuffer,
+ pEASData->pOutputAudioBuffer,
+ numSamples);
+#endif
+
+#ifdef _WOW_ENABLED
+ /* WOW requires a 32-bit buffer, borrow the mix buffer and
+ * pass it as the destination buffer
+ */
+ /*lint -e{740} temporarily passing a parameter through an existing I/F */
+ if (pEASData->effectsModules[EAS_MODULE_WOW].effectData)
+ (*pEASData->effectsModules[EAS_MODULE_WOW].effect->pfProcess)
+ (pEASData->effectsModules[EAS_MODULE_WOW].effectData,
+ pEASData->pOutputAudioBuffer,
+ (EAS_PCM*) pEASData->pMixBuffer,
+ numSamples);
+#endif
+
+#ifdef _TONECONTROLEQ_ENABLED
+ /* ToneControlEQ effect */
+ if (pEASData->effectsModules[EAS_MODULE_TONECONTROLEQ].effectData)
+ (*pEASData->effectsModules[EAS_MODULE_TONECONTROLEQ].effect->pfProcess)
+ (pEASData->effectsModules[EAS_MODULE_TONECONTROLEQ].effectData,
+ pEASData->pOutputAudioBuffer,
+ pEASData->pOutputAudioBuffer,
+ numSamples);
+#endif
+
+#ifdef _REVERB_ENABLED
+ /* Reverb effect */
+ if (pEASData->effectsModules[EAS_MODULE_REVERB].effectData)
+ (*pEASData->effectsModules[EAS_MODULE_REVERB].effect->pfProcess)
+ (pEASData->effectsModules[EAS_MODULE_REVERB].effectData,
+ pEASData->pOutputAudioBuffer,
+ pEASData->pOutputAudioBuffer,
+ numSamples);
+#endif
+
+#ifdef _CHORUS_ENABLED
+ /* Chorus effect */
+ if (pEASData->effectsModules[EAS_MODULE_CHORUS].effectData)
+ (*pEASData->effectsModules[EAS_MODULE_CHORUS].effect->pfProcess)
+ (pEASData->effectsModules[EAS_MODULE_CHORUS].effectData,
+ pEASData->pOutputAudioBuffer,
+ pEASData->pOutputAudioBuffer,
+ numSamples);
+#endif
+
+}
+
+#ifndef NATIVE_EAS_KERNEL
+/*----------------------------------------------------------------------------
+ * SynthMasterGain
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Mixes down audio from 32-bit to 16-bit target buffer
+ *
+ * Inputs:
+ *
+ * Outputs:
+ *
+ *----------------------------------------------------------------------------
+*/
+void SynthMasterGain (long *pInputBuffer, EAS_PCM *pOutputBuffer, EAS_U16 nGain, EAS_U16 numSamples) {
+
+ /* loop through the buffer */
+ while (numSamples--) {
+ long s;
+
+ /* read a sample from the input buffer and add some guard bits */
+ s = *pInputBuffer++;
+
+ /* add some guard bits */
+ /*lint -e{704} <avoid divide for performance>*/
+ s = s >> 7;
+
+ /* apply master gain */
+ s *= (long) nGain;
+
+ /* shift to lower 16-bits */
+ /*lint -e{704} <avoid divide for performance>*/
+ s = s >> 9;
+
+ /* saturate */
+ s = SATURATE(s);
+
+ *pOutputBuffer++ = (EAS_PCM)s;
+ }
+}
+#endif
+
+/*----------------------------------------------------------------------------
+ * EAS_MixEngineShutdown()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Shuts down effects modules and deallocates memory
+ *
+ * Inputs:
+ * pEASData - instance data
+ * pInstData - instance data handle
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_MixEngineShutdown (S_EAS_DATA *pEASData)
+{
+
+ /* check Configuration Module for static memory allocation */
+ if (!pEASData->staticMemoryModel && (pEASData->pMixBuffer != NULL))
+ EAS_HWFree(pEASData->hwInstData, pEASData->pMixBuffer);
+
+ return EAS_SUCCESS;
+}
+
+#ifdef UNIFIED_MIXER
+#ifndef NATIVE_MIX_STREAM
+/*----------------------------------------------------------------------------
+ * EAS_MixStream
+ *----------------------------------------------------------------------------
+ * Mix a 16-bit stream into a 32-bit buffer
+ *
+ * pInputBuffer 16-bit input buffer
+ * pMixBuffer 32-bit mix buffer
+ * numSamples number of samples to mix
+ * gainLeft initial gain left or mono
+ * gainRight initial gain right
+ * gainLeft left gain increment per sample
+ * gainRight right gain increment per sample
+ * flags bit 0 = stereo source
+ * bit 1 = stereo output
+ *----------------------------------------------------------------------------
+*/
+void EAS_MixStream (EAS_PCM *pInputBuffer, EAS_I32 *pMixBuffer, EAS_I32 numSamples, EAS_I32 gainLeft, EAS_I32 gainRight, EAS_I32 gainIncLeft, EAS_I32 gainIncRight, EAS_I32 flags)
+{
+ EAS_I32 temp;
+ EAS_INT src, dest;
+
+ /* NOTE: There are a lot of optimizations that can be done
+ * in the native implementations based on register
+ * availability, etc. For example, it may make sense to
+ * break this down into 8 separate routines:
+ *
+ * 1. Mono source to mono output
+ * 2. Mono source to stereo output
+ * 3. Stereo source to mono output
+ * 4. Stereo source to stereo output
+ * 5. Mono source to mono output - no gain change
+ * 6. Mono source to stereo output - no gain change
+ * 7. Stereo source to mono output - no gain change
+ * 8. Stereo source to stereo output - no gain change
+ *
+ * Other possibilities include loop unrolling, skipping
+ * a gain calculation every 2 or 4 samples, etc.
+ */
+
+ /* no gain change, use fast loops */
+ if ((gainIncLeft == 0) && (gainIncRight == 0))
+ {
+ switch (flags & (MIX_FLAGS_STEREO_SOURCE | MIX_FLAGS_STEREO_OUTPUT))
+ {
+ /* mono to mono */
+ case 0:
+ gainLeft >>= 15;
+ for (src = dest = 0; src < numSamples; src++, dest++)
+ {
+
+ pMixBuffer[dest] += (pInputBuffer[src] * gainLeft) >> NUM_MIXER_GUARD_BITS;
+ }
+ break;
+
+ /* mono to stereo */
+ case MIX_FLAGS_STEREO_OUTPUT:
+ gainLeft >>= 15;
+ gainRight >>= 15;
+ for (src = dest = 0; src < numSamples; src++, dest+=2)
+ {
+ pMixBuffer[dest] += (pInputBuffer[src] * gainLeft) >> NUM_MIXER_GUARD_BITS;
+ pMixBuffer[dest+1] += (pInputBuffer[src] * gainRight) >> NUM_MIXER_GUARD_BITS;
+ }
+ break;
+
+ /* stereo to mono */
+ case MIX_FLAGS_STEREO_SOURCE:
+ gainLeft >>= 15;
+ gainRight >>= 15;
+ for (src = dest = 0; src < numSamples; src+=2, dest++)
+ {
+ temp = (pInputBuffer[src] * gainLeft) >> NUM_MIXER_GUARD_BITS;
+ temp += ((pInputBuffer[src+1] * gainRight) >> NUM_MIXER_GUARD_BITS);
+ pMixBuffer[dest] += temp;
+ }
+ break;
+
+ /* stereo to stereo */
+ case MIX_FLAGS_STEREO_SOURCE | MIX_FLAGS_STEREO_OUTPUT:
+ gainLeft >>= 15;
+ gainRight >>= 15;
+ for (src = dest = 0; src < numSamples; src+=2, dest+=2)
+ {
+ pMixBuffer[dest] += (pInputBuffer[src] * gainLeft) >> NUM_MIXER_GUARD_BITS;
+ pMixBuffer[dest+1] += (pInputBuffer[src+1] * gainRight) >> NUM_MIXER_GUARD_BITS;
+ }
+ break;
+ }
+ }
+
+ /* gain change - do gain increment */
+ else
+ {
+ switch (flags & (MIX_FLAGS_STEREO_SOURCE | MIX_FLAGS_STEREO_OUTPUT))
+ {
+ /* mono to mono */
+ case 0:
+ for (src = dest = 0; src < numSamples; src++, dest++)
+ {
+ gainLeft += gainIncLeft;
+ pMixBuffer[dest] += (pInputBuffer[src] * (gainLeft >> 15)) >> NUM_MIXER_GUARD_BITS;
+ }
+ break;
+
+ /* mono to stereo */
+ case MIX_FLAGS_STEREO_OUTPUT:
+ for (src = dest = 0; src < numSamples; src++, dest+=2)
+ {
+ gainLeft += gainIncLeft;
+ gainRight += gainIncRight;
+ pMixBuffer[dest] += (pInputBuffer[src] * (gainLeft >> 15)) >> NUM_MIXER_GUARD_BITS;
+ pMixBuffer[dest+1] += (pInputBuffer[src] * (gainRight >> 15)) >> NUM_MIXER_GUARD_BITS;
+ }
+ break;
+
+ /* stereo to mono */
+ case MIX_FLAGS_STEREO_SOURCE:
+ for (src = dest = 0; src < numSamples; src+=2, dest++)
+ {
+ gainLeft += gainIncLeft;
+ gainRight += gainIncRight;
+ temp = (pInputBuffer[src] * (gainLeft >> 15)) >> NUM_MIXER_GUARD_BITS;
+ temp += ((pInputBuffer[src+1] * (gainRight >> 15)) >> NUM_MIXER_GUARD_BITS);
+ pMixBuffer[dest] += temp;
+ }
+ break;
+
+ /* stereo to stereo */
+ case MIX_FLAGS_STEREO_SOURCE | MIX_FLAGS_STEREO_OUTPUT:
+ for (src = dest = 0; src < numSamples; src+=2, dest+=2)
+ {
+ gainLeft += gainIncLeft;
+ gainRight += gainIncRight;
+ pMixBuffer[dest] += (pInputBuffer[src] * (gainLeft >> 15)) >> NUM_MIXER_GUARD_BITS;
+ pMixBuffer[dest+1] += (pInputBuffer[src+1] * (gainRight >> 15)) >> NUM_MIXER_GUARD_BITS;
+ }
+ break;
+ }
+ }
+}
+#endif
+#endif
+
diff --git a/arm-fm-22k/lib_src/eas_mixer.h b/arm-fm-22k/lib_src/eas_mixer.h
index 2ba2d3d..b2eb33b 100644
--- a/arm-fm-22k/lib_src/eas_mixer.h
+++ b/arm-fm-22k/lib_src/eas_mixer.h
@@ -1,13 +1,13 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_mixer.h
- *
- * Contents and purpose:
- * This file contains the critical components of the mix engine that
- * must be optimized for best performance.
- *
- * Copyright Sonic Network Inc. 2005
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_mixer.h
+ *
+ * Contents and purpose:
+ * This file contains the critical components of the mix engine that
+ * must be optimized for best performance.
+ *
+ * Copyright Sonic Network Inc. 2005
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,118 +20,118 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 706 $
- * $Date: 2007-05-31 17:22:51 -0700 (Thu, 31 May 2007) $
- *----------------------------------------------------------------------------
-*/
-
-#ifndef _EAS_MIXER_H
-#define _EAS_MIXER_H
-
-//3 dls: This module is in the midst of being converted from a synth
-//3 specific module to a general purpose mix engine
-
-#define MIX_FLAGS_STEREO_SOURCE 1
-#define MIX_FLAGS_STEREO_OUTPUT 2
-#define NUM_MIXER_GUARD_BITS 4
-
-#include "eas_effects.h"
-
-extern void SynthMasterGain( long *pInputBuffer, EAS_PCM *pOutputBuffer, EAS_U16 nGain, EAS_U16 nNumLoopSamples);
-
-/*----------------------------------------------------------------------------
- * EAS_MixEngineInit()
- *----------------------------------------------------------------------------
- * Purpose:
- * Prepares the mix engine for work, allocates buffers, locates effects modules, etc.
- *
- * Inputs:
- * pEASData - instance data
- * pInstData - pointer to variable to receive instance data handle
- *
- * Outputs:
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT EAS_MixEngineInit (EAS_DATA_HANDLE pEASData);
-
-/*----------------------------------------------------------------------------
- * EAS_MixEnginePrep()
- *----------------------------------------------------------------------------
- * Purpose:
- * Performs prep before synthesize a buffer of audio, such as clearing
- * audio buffers, etc.
- *
- * Inputs:
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-void EAS_MixEnginePrep (EAS_DATA_HANDLE pEASData, EAS_I32 nNumSamplesToAdd);
-
-/*----------------------------------------------------------------------------
- * EAS_MixEnginePost
- *----------------------------------------------------------------------------
- * Purpose:
- * This routine does the post-processing after all voices have been
- * synthesized. It calls any sweeteners and does the final mixdown to
- * the output buffer.
- *
- * Inputs:
- *
- * Outputs:
- *
- * Notes:
- *----------------------------------------------------------------------------
-*/
-void EAS_MixEnginePost (EAS_DATA_HANDLE pEASData, EAS_I32 nNumSamplesToAdd);
-
-/*----------------------------------------------------------------------------
- * EAS_MixEngineShutdown()
- *----------------------------------------------------------------------------
- * Purpose:
- * Shuts down effects modules and deallocates memory
- *
- * Inputs:
- * pEASData - instance data
- * pInstData - instance data handle
- *
- * Outputs:
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT EAS_MixEngineShutdown (EAS_DATA_HANDLE pEASData);
-
-#ifdef UNIFIED_MIXER
-/*----------------------------------------------------------------------------
- * EAS_MixStream
- *----------------------------------------------------------------------------
- * Mix a 16-bit stream into a 32-bit buffer
- *
- * pInputBuffer 16-bit input buffer
- * pMixBuffer 32-bit mix buffer
- * numSamples number of samples to mix
- * gainLeft initial gain left or mono
- * gainRight initial gain right
- * gainLeft left gain increment per sample
- * gainRight right gain increment per sample
- * flags bit 0 = stereo source
- * bit 1 = stereo output
- *----------------------------------------------------------------------------
-*/
-void EAS_MixStream (EAS_PCM *pInputBuffer, EAS_I32 *pMixBuffer, EAS_I32 numSamples, EAS_I32 gainLeft, EAS_I32 gainRight, EAS_I32 gainIncLeft, EAS_I32 gainIncRight, EAS_I32 flags);
-#endif
-
-#endif /* #ifndef _EAS_MIXER_H */
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 706 $
+ * $Date: 2007-05-31 17:22:51 -0700 (Thu, 31 May 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+#ifndef _EAS_MIXER_H
+#define _EAS_MIXER_H
+
+//3 dls: This module is in the midst of being converted from a synth
+//3 specific module to a general purpose mix engine
+
+#define MIX_FLAGS_STEREO_SOURCE 1
+#define MIX_FLAGS_STEREO_OUTPUT 2
+#define NUM_MIXER_GUARD_BITS 4
+
+#include "eas_effects.h"
+
+extern void SynthMasterGain( long *pInputBuffer, EAS_PCM *pOutputBuffer, EAS_U16 nGain, EAS_U16 nNumLoopSamples);
+
+/*----------------------------------------------------------------------------
+ * EAS_MixEngineInit()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Prepares the mix engine for work, allocates buffers, locates effects modules, etc.
+ *
+ * Inputs:
+ * pEASData - instance data
+ * pInstData - pointer to variable to receive instance data handle
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_MixEngineInit (EAS_DATA_HANDLE pEASData);
+
+/*----------------------------------------------------------------------------
+ * EAS_MixEnginePrep()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Performs prep before synthesize a buffer of audio, such as clearing
+ * audio buffers, etc.
+ *
+ * Inputs:
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+void EAS_MixEnginePrep (EAS_DATA_HANDLE pEASData, EAS_I32 nNumSamplesToAdd);
+
+/*----------------------------------------------------------------------------
+ * EAS_MixEnginePost
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * This routine does the post-processing after all voices have been
+ * synthesized. It calls any sweeteners and does the final mixdown to
+ * the output buffer.
+ *
+ * Inputs:
+ *
+ * Outputs:
+ *
+ * Notes:
+ *----------------------------------------------------------------------------
+*/
+void EAS_MixEnginePost (EAS_DATA_HANDLE pEASData, EAS_I32 nNumSamplesToAdd);
+
+/*----------------------------------------------------------------------------
+ * EAS_MixEngineShutdown()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Shuts down effects modules and deallocates memory
+ *
+ * Inputs:
+ * pEASData - instance data
+ * pInstData - instance data handle
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_MixEngineShutdown (EAS_DATA_HANDLE pEASData);
+
+#ifdef UNIFIED_MIXER
+/*----------------------------------------------------------------------------
+ * EAS_MixStream
+ *----------------------------------------------------------------------------
+ * Mix a 16-bit stream into a 32-bit buffer
+ *
+ * pInputBuffer 16-bit input buffer
+ * pMixBuffer 32-bit mix buffer
+ * numSamples number of samples to mix
+ * gainLeft initial gain left or mono
+ * gainRight initial gain right
+ * gainLeft left gain increment per sample
+ * gainRight right gain increment per sample
+ * flags bit 0 = stereo source
+ * bit 1 = stereo output
+ *----------------------------------------------------------------------------
+*/
+void EAS_MixStream (EAS_PCM *pInputBuffer, EAS_I32 *pMixBuffer, EAS_I32 numSamples, EAS_I32 gainLeft, EAS_I32 gainRight, EAS_I32 gainIncLeft, EAS_I32 gainIncRight, EAS_I32 flags);
+#endif
+
+#endif /* #ifndef _EAS_MIXER_H */
+
diff --git a/arm-fm-22k/lib_src/eas_ota.c b/arm-fm-22k/lib_src/eas_ota.c
index fb81d62..5bc9062 100644
--- a/arm-fm-22k/lib_src/eas_ota.c
+++ b/arm-fm-22k/lib_src/eas_ota.c
@@ -1,12 +1,12 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_ota.c
- *
- * Contents and purpose:
- * OTA parser
- *
- * Copyright Sonic Network Inc. 2005
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_ota.c
+ *
+ * Contents and purpose:
+ * OTA parser
+ *
+ * Copyright Sonic Network Inc. 2005
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,1059 +19,1059 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 795 $
- * $Date: 2007-08-01 00:14:45 -0700 (Wed, 01 Aug 2007) $
- *----------------------------------------------------------------------------
-*/
-
-#include "eas_data.h"
-#include "eas_miditypes.h"
-#include "eas_parser.h"
-#include "eas_report.h"
-#include "eas_host.h"
-#include "eas_midi.h"
-#include "eas_config.h"
-#include "eas_vm_protos.h"
-#include "eas_otadata.h"
-
-/* increase gain for mono ringtones */
-#define OTA_GAIN_OFFSET 8
-
-/* file definitions */
-#define OTA_RINGTONE 0x25
-#define OTA_SOUND 0x1d
-#define OTA_UNICODE 0x22
-
-/* song type definitions */
-#define OTA_BASIC_SONG_TYPE 0x01
-#define OTA_TEMPORARY_SONG_TYPE 0x02
-
-/* instruction ID coding */
-#define OTA_PATTERN_HEADER_ID 0x00
-#define OTA_NOTE_INST_ID 0x01
-#define OTA_SCALE_INST_ID 0x02
-#define OTA_STYLE_INST_ID 0x03
-#define OTA_TEMPO_INST_ID 0x04
-#define OTA_VOLUME_INST_ID 0x05
-
-/* note durations */
-#define OTA_NORMAL_DURATION 0x00
-#define OTA_DOTTED_NOTE 0x01
-#define OTA_DOUBLE_DOTTED_NOTE 0x02
-#define OTA_TRIPLET_NOTE 0x03
-
-/* loop count value for infinite loop */
-#define OTA_INFINITE_LOOP 0x0f
-
-/* length of 32nd note in 1/256ths of a msec for 63 BPM tempo */
-#define DEFAULT_TICK_CONV 30476
-
-/* default channel and program for OTA playback */
-#define OTA_CHANNEL 0
-#define OTA_PROGRAM 80
-#define OTA_VEL_MUL 4
-#define OTA_VEL_OFS 67
-#define OTA_VEL_DEFAULT 95
-
-/* multiplier for fixed point triplet conversion */
-#define TRIPLET_MULTIPLIER 683
-#define TRIPLET_SHIFT 10
-
-/* local prototypes */
-static EAS_RESULT OTA_CheckFileType (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle, EAS_VOID_PTR *ppHandle, EAS_I32 offset);
-static EAS_RESULT OTA_Prepare (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
-static EAS_RESULT OTA_Time (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_U32 *pTime);
-static EAS_RESULT OTA_Event (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_INT parserMode);
-static EAS_RESULT OTA_State (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_STATE *pState);
-static EAS_RESULT OTA_Close (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
-static EAS_RESULT OTA_Reset (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
-static EAS_RESULT OTA_Pause (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
-static EAS_RESULT OTA_Resume (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
-static EAS_RESULT OTA_SetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value);
-static EAS_RESULT OTA_GetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue);
-static EAS_RESULT OTA_ParseHeader (S_EAS_DATA *pEASData, S_OTA_DATA* pData);
-static EAS_RESULT OTA_FetchBitField (EAS_HW_DATA_HANDLE hwInstData, S_OTA_DATA *pData, EAS_I32 numBits, EAS_U8 *pValue);
-static EAS_RESULT OTA_SavePosition (EAS_HW_DATA_HANDLE hwInstData, S_OTA_DATA *pData, S_OTA_LOC *pLoc);
-static EAS_RESULT OTA_RestorePosition (EAS_HW_DATA_HANDLE hwInstData, S_OTA_DATA *pData, S_OTA_LOC *pLoc);
-
-
-/*----------------------------------------------------------------------------
- *
- * EAS_OTA_Parser
- *
- * This structure contains the functional interface for the OTA parser
- *----------------------------------------------------------------------------
-*/
-const S_FILE_PARSER_INTERFACE EAS_OTA_Parser =
-{
- OTA_CheckFileType,
- OTA_Prepare,
- OTA_Time,
- OTA_Event,
- OTA_State,
- OTA_Close,
- OTA_Reset,
- OTA_Pause,
- OTA_Resume,
- NULL,
- OTA_SetData,
- OTA_GetData,
- NULL
-};
-
-/*----------------------------------------------------------------------------
- *
- * bpmTable
- *
- * BPM conversion table. Converts bpm values to 256ths of a millisecond for a 32nd note
- *----------------------------------------------------------------------------
-*/
-static const EAS_U32 bpmTable[32] =
-{
- 76800, 68571, 61935, 54857,
- 48000, 42667, 38400, 34286,
- 30476, 27429, 24000, 21333,
- 19200, 17143, 15360, 13714,
- 12000, 10667, 9600, 8533,
- 7680, 6737, 6000, 5408,
- 4800, 4267, 3840, 3398,
- 3024, 2685, 2400, 2133
-};
-
-/*----------------------------------------------------------------------------
- * OTA_CheckFileType()
- *----------------------------------------------------------------------------
- * Purpose:
- * Check the file type to see if we can parse it
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT OTA_CheckFileType (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle, EAS_VOID_PTR *ppHandle, EAS_I32 offset)
-{
- S_OTA_DATA* pData;
- EAS_RESULT result;
- EAS_INT cmdLen;
- EAS_INT state;
- EAS_U8 temp;
-
- /* read the first byte, should be command length */
- *ppHandle = NULL;
- if ((result = EAS_HWGetByte(pEASData->hwInstData, fileHandle, &temp)) != EAS_SUCCESS)
- return result;
-
- /* read all the commands */
- cmdLen = temp;
- state = 0;
- while (cmdLen--)
- {
-
- /* read the command, upper 7 bits */
- if ((result = EAS_HWGetByte(pEASData->hwInstData, fileHandle, &temp)) != EAS_SUCCESS)
- return result;
- temp = temp >> 1;
-
- if (state == 0)
- {
- if (temp != OTA_RINGTONE)
- break;
- state++;
- }
- else
- {
-
- if (temp == OTA_SOUND)
- {
-
- /* check for static memory allocation */
- if (pEASData->staticMemoryModel)
- pData = EAS_CMEnumData(EAS_CM_OTA_DATA);
- else
- pData = EAS_HWMalloc(pEASData->hwInstData, sizeof(S_OTA_DATA));
- if (!pData)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Malloc failed in OTA_Prepare\n"); */ }
- return EAS_ERROR_MALLOC_FAILED;
- }
- EAS_HWMemSet(pData, 0, sizeof(S_OTA_DATA));
-
- /* return a pointer to the instance data */
- pData->fileHandle = fileHandle;
- pData->fileOffset = offset;
- pData->state = EAS_STATE_OPEN;
- *ppHandle = pData;
- break;
- }
-
- if (temp != OTA_UNICODE)
- break;
- }
- }
-
- /* not recognized */
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * OTA_Prepare()
- *----------------------------------------------------------------------------
- * Purpose:
- * Prepare to parse the file. Allocates instance data (or uses static allocation for
- * static memory model).
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT OTA_Prepare (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
-{
- S_OTA_DATA* pData;
- EAS_RESULT result;
-
- /* check for valid state */
- pData = (S_OTA_DATA*) pInstData;
- if (pData->state != EAS_STATE_OPEN)
- return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
-
- /* instantiate a synthesizer */
- if ((result = VMInitMIDI(pEASData, &pData->pSynth)) != EAS_SUCCESS)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "VMInitMIDI returned %d\n", result); */ }
- return result;
- }
-
- pData->state = EAS_STATE_ERROR;
- if ((result = OTA_ParseHeader(pEASData, pData)) != EAS_SUCCESS)
- return result;
-
- pData->state = EAS_STATE_READY;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * OTA_Time()
- *----------------------------------------------------------------------------
- * Purpose:
- * Returns the time of the next event in msecs
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- * pTime - pointer to variable to hold time of next event (in msecs)
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, pEASData) common decoder interface - pEASData not used */
-static EAS_RESULT OTA_Time (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_U32 *pTime)
-{
- S_OTA_DATA *pData;
-
- pData = (S_OTA_DATA*) pInstData;
-
- /* return time in milliseconds */
- /*lint -e{704} use shift instead of division */
- *pTime = pData->time >> 8;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * OTA_Event()
- *----------------------------------------------------------------------------
- * Purpose:
- * Parse the next event in the file
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT OTA_Event (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_INT parserMode)
-{
- S_OTA_DATA* pData;
- EAS_RESULT result;
- EAS_U32 duration;
- EAS_U8 temp;
-
- pData = (S_OTA_DATA*) pInstData;
- if (pData->state >= EAS_STATE_OPEN)
- return EAS_SUCCESS;
-
- /* initialize MIDI channel when the track starts playing */
- if (pData->time == 0)
- {
- /* set program to square lead */
- if (parserMode != eParserModeMetaData)
- VMProgramChange(pEASData->pVoiceMgr, pData->pSynth, OTA_CHANNEL, OTA_PROGRAM);
-
- /* set channel volume to max */
- if (parserMode != eParserModeMetaData)
- VMControlChange(pEASData->pVoiceMgr, pData->pSynth, OTA_CHANNEL, 7, 127);
- }
-
- /* check for end of note */
- if (pData->note)
- {
- /* stop the note */
- VMStopNote(pEASData->pVoiceMgr, pData->pSynth, OTA_CHANNEL, pData->note, 0);
- pData->note = 0;
-
- /* check for rest between notes */
- if (pData->restTicks)
- {
- pData->time += (EAS_I32) pData->restTicks;
- pData->restTicks = 0;
- return EAS_SUCCESS;
- }
- }
-
- /* if not in a pattern, read the pattern header */
- while (pData->current.patternLen == 0)
- {
-
- /* check for loop - don't do infinite loops when locating */
- if (pData->loopCount && ((parserMode == eParserModePlay) || (pData->loopCount != OTA_INFINITE_LOOP)))
- {
- /* if not infinite loop, decrement loop count */
- if (pData->loopCount != OTA_INFINITE_LOOP)
- pData->loopCount--;
-
- /* back to start of pattern*/
- if ((result = OTA_RestorePosition(pEASData->hwInstData, pData, &pData->patterns[pData->currentPattern])) != EAS_SUCCESS)
- return result;
- }
-
- /* if no previous position to restore, continue forward */
- else if (pData->restore.fileOffset < 0)
- {
-
- /* check for end of song */
- if (pData->numPatterns == 0)
- {
- pData->state = EAS_STATE_STOPPING;
- VMReleaseAllVoices(pEASData->pVoiceMgr, pData->pSynth);
- return EAS_SUCCESS;
- }
-
- /* read the next pattern header */
- if ((result = OTA_FetchBitField(pEASData->hwInstData, pData, 3, &temp)) != EAS_SUCCESS)
- return result;
- if (temp != OTA_PATTERN_HEADER_ID)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Expected OTA pattern header\n"); */ }
- return EAS_ERROR_FILE_FORMAT;
- }
-
- /* get the pattern ID */
- if ((result = OTA_FetchBitField(pEASData->hwInstData, pData, 2, &pData->currentPattern)) != EAS_SUCCESS)
- return result;
-
- /* get the loop count */
- if ((result = OTA_FetchBitField(pEASData->hwInstData, pData, 4, &pData->loopCount)) != EAS_SUCCESS)
- return result;
-
- /* get the pattern length */
- if ((result = OTA_FetchBitField(pEASData->hwInstData, pData, 8, &pData->current.patternLen)) != EAS_SUCCESS)
- return result;
-
- /* if pattern definition, save the current position */
- if (pData->current.patternLen)
- {
- if ((result = OTA_SavePosition(pEASData->hwInstData, pData, &pData->patterns[pData->currentPattern])) != EAS_SUCCESS)
- return result;
- }
-
- /* if pattern length is zero, repeat a previous pattern */
- else
- {
- /* make sure it's a valid pattern */
- if (pData->patterns[pData->currentPattern].fileOffset < 0)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "OTA pattern error, invalid pattern specified\n"); */ }
- return EAS_ERROR_FILE_FORMAT;
- }
-
- /* save current position and data */
- if ((result = OTA_SavePosition(pEASData->hwInstData, pData, &pData->restore)) != EAS_SUCCESS)
- return result;
-
- /* seek to the pattern in the file */
- if ((result = OTA_RestorePosition(pEASData->hwInstData, pData, &pData->patterns[pData->currentPattern])) != EAS_SUCCESS)
- return result;
- }
-
- /* decrement pattern count */
- pData->numPatterns--;
- }
-
- /* restore previous position */
- else
- {
- if ((result = OTA_RestorePosition(pEASData->hwInstData, pData, &pData->restore)) != EAS_SUCCESS)
- return result;
- }
- }
-
- /* get the next event */
- if ((result = OTA_FetchBitField(pEASData->hwInstData, pData, 3, &temp)) != EAS_SUCCESS)
- return result;
-
- switch (temp)
- {
- case OTA_NOTE_INST_ID:
- /* fetch note value */
- if ((result = OTA_FetchBitField(pEASData->hwInstData, pData, 4, &pData->note)) != EAS_SUCCESS)
- return result;
-
- /* fetch note duration */
- if ((result = OTA_FetchBitField(pEASData->hwInstData, pData, 3, &temp)) != EAS_SUCCESS)
- return result;
- duration = pData->tick * (0x20 >> temp);
-
- /* fetch note duration modifier */
- if ((result = OTA_FetchBitField(pEASData->hwInstData, pData, 2, &temp)) != EAS_SUCCESS)
- return result;
- switch (temp)
- {
- case OTA_NORMAL_DURATION:
- break;
-
- case OTA_DOTTED_NOTE:
- duration += duration >> 1;
- break;
-
- case OTA_DOUBLE_DOTTED_NOTE:
- duration += (duration >> 1) + (duration >> 2);
- break;
-
- case OTA_TRIPLET_NOTE:
- duration = (duration * TRIPLET_MULTIPLIER) >> TRIPLET_SHIFT;
- break;
-
- default:
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Unrecognized note duration ignored\n"); */ }
- break;
- }
-
- /* check for note */
- if (pData->note)
- {
-
- /* determine note length based on style */
- switch (pData->style)
- {
- case 0:
- pData->restTicks = duration >> 4;
- break;
- case 1:
- pData->restTicks = 0;
- break;
- case 2:
- pData->restTicks = duration >> 1;
- break;
- default:
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Unrecognized note style ignored\n"); */ }
- }
-
- /* add octave */
- pData->note += pData->octave;
- if (parserMode == eParserModePlay)
- VMStartNote(pEASData->pVoiceMgr, pData->pSynth, OTA_CHANNEL, pData->note, pData->velocity);
- pData->time += (EAS_I32) duration - (EAS_I32) pData->restTicks;
- }
-
- /* this is a rest */
- else
- pData->time += (EAS_I32) duration;
- break;
-
- case OTA_SCALE_INST_ID:
- /* fetch octave */
- if ((result = OTA_FetchBitField(pEASData->hwInstData, pData, 2, &temp)) != EAS_SUCCESS)
- return result;
- pData->octave = (EAS_U8) (temp * 12 + 59);
- break;
-
- case OTA_STYLE_INST_ID:
- /* fetch note style */
- if ((result = OTA_FetchBitField(pEASData->hwInstData, pData, 2, &pData->style)) != EAS_SUCCESS)
- return result;
- break;
-
- case OTA_TEMPO_INST_ID:
- /* fetch tempo */
- if ((result = OTA_FetchBitField(pEASData->hwInstData, pData, 5, &temp)) != EAS_SUCCESS)
- return result;
- pData->tick = bpmTable[temp];
- break;
-
- case OTA_VOLUME_INST_ID:
- /* fetch volume */
- if ((result = OTA_FetchBitField(pEASData->hwInstData, pData, 4, &temp)) != EAS_SUCCESS)
- return result;
- pData->velocity = temp ? (EAS_U8) (temp * OTA_VEL_MUL + OTA_VEL_OFS) : 0;
- break;
-
- default:
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Unexpected instruction ID in OTA stream\n"); */ }
- return EAS_ERROR_FILE_FORMAT;
- }
-
- /* decrement pattern length */
- pData->current.patternLen--;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * OTA_State()
- *----------------------------------------------------------------------------
- * Purpose:
- * Returns the current state of the stream
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- * pState - pointer to variable to store state
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, pEASData) common decoder interface - pEASData not used */
-static EAS_RESULT OTA_State (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 *pState)
-{
- S_OTA_DATA* pData;
-
- /* establish pointer to instance data */
- pData = (S_OTA_DATA*) pInstData;
-
- /* if stopping, check to see if synth voices are active */
- if (pData->state == EAS_STATE_STOPPING)
- {
- if (VMActiveVoices(pData->pSynth) == 0)
- pData->state = EAS_STATE_STOPPED;
- }
-
- if (pData->state == EAS_STATE_PAUSING)
- {
- if (VMActiveVoices(pData->pSynth) == 0)
- pData->state = EAS_STATE_PAUSED;
- }
-
- /* return current state */
- *pState = pData->state;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * OTA_Close()
- *----------------------------------------------------------------------------
- * Purpose:
- * Close the file and clean up
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT OTA_Close (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
-{
- S_OTA_DATA* pData;
- EAS_RESULT result;
-
- pData = (S_OTA_DATA*) pInstData;
-
- /* close the file */
- if ((result = EAS_HWCloseFile(pEASData->hwInstData, pData->fileHandle)) != EAS_SUCCESS)
- return result;
-
- /* free the synth */
- if (pData->pSynth != NULL)
- VMMIDIShutdown(pEASData, pData->pSynth);
-
- /* if using dynamic memory, free it */
- if (!pEASData->staticMemoryModel)
- EAS_HWFree(pEASData->hwInstData, pData);
-
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * OTA_Reset()
- *----------------------------------------------------------------------------
- * Purpose:
- * Reset the sequencer. Used for locating backwards in the file.
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT OTA_Reset (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
-{
- S_OTA_DATA* pData;
- EAS_RESULT result;
-
- pData = (S_OTA_DATA*) pInstData;
-
- /* reset the synth */
- VMReset(pEASData->pVoiceMgr, pData->pSynth, EAS_TRUE);
- pData->note = 0;
-
- /* reset file position and re-parse header */
- pData->state = EAS_STATE_ERROR;
- if ((result = OTA_ParseHeader (pEASData, pData)) != EAS_SUCCESS)
- return result;
-
- pData->state = EAS_STATE_READY;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * OTA_Pause()
- *----------------------------------------------------------------------------
- * Purpose:
- * Pauses the sequencer. Mutes all voices and sets state to pause.
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT OTA_Pause (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
-{
- S_OTA_DATA *pData;
-
- /* can't pause a stopped stream */
- pData = (S_OTA_DATA*) pInstData;
- if (pData->state == EAS_STATE_STOPPED)
- return EAS_ERROR_ALREADY_STOPPED;
-
- /* mute the synthesizer */
- VMMuteAllVoices(pEASData->pVoiceMgr, pData->pSynth);
- pData->state = EAS_STATE_PAUSING;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * OTA_Resume()
- *----------------------------------------------------------------------------
- * Purpose:
- * Resume playing after a pause, sets state back to playing.
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, pEASData) common decoder interface - pEASData not used */
-static EAS_RESULT OTA_Resume (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
-{
- S_OTA_DATA *pData;
-
- /* can't resume a stopped stream */
- pData = (S_OTA_DATA*) pInstData;
- if (pData->state == EAS_STATE_STOPPED)
- return EAS_ERROR_ALREADY_STOPPED;
-
- /* nothing to do but resume playback */
- pData->state = EAS_STATE_PLAY;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * OTA_SetData()
- *----------------------------------------------------------------------------
- * Purpose:
- * Return file type
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, pEASData) common decoder interface - pEASData not used */
-static EAS_RESULT OTA_SetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value)
-{
- S_OTA_DATA *pData;
-
- pData = (S_OTA_DATA *) pInstData;
- switch (param)
- {
-
- /* set metadata callback */
- case PARSER_DATA_METADATA_CB:
- EAS_HWMemCpy(&pData->metadata, (void*) value, sizeof(S_METADATA_CB));
- break;
-
- default:
- return EAS_ERROR_INVALID_PARAMETER;
- }
-
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * OTA_GetData()
- *----------------------------------------------------------------------------
- * Purpose:
- * Return file type
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, pEASData) common decoder interface - pEASData not used */
-static EAS_RESULT OTA_GetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue)
-{
- S_OTA_DATA *pData;
-
- pData = (S_OTA_DATA*) pInstData;
- switch (param)
- {
- /* return file type as OTA */
- case PARSER_DATA_FILE_TYPE:
- *pValue = EAS_FILE_OTA;
- break;
-
-#if 0
- /* set transposition */
- case PARSER_DATA_TRANSPOSITION:
- *pValue = pData->transposition;
- break;
-#endif
-
- case PARSER_DATA_SYNTH_HANDLE:
- *pValue = (EAS_I32) pData->pSynth;
- break;
-
- case PARSER_DATA_GAIN_OFFSET:
- *pValue = OTA_GAIN_OFFSET;
- break;
-
- default:
- return EAS_ERROR_INVALID_PARAMETER;
- }
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * OTA_ParseHeader()
- *----------------------------------------------------------------------------
- * Purpose:
- * Prepare to parse the file. Allocates instance data (or uses static allocation for
- * static memory model).
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT OTA_ParseHeader (S_EAS_DATA *pEASData, S_OTA_DATA* pData)
-{
- EAS_RESULT result;
- EAS_INT i;
- EAS_INT state;
- EAS_U8 temp;
- EAS_U8 titleLen;
-
- /* initialize some data */
- pData->flags = 0;
- pData->time = 0;
- pData->tick = DEFAULT_TICK_CONV;
- pData->patterns[0].fileOffset = pData->patterns[1].fileOffset =
- pData->patterns[2].fileOffset = pData->patterns[3].fileOffset = -1;
- pData->current.bitCount = 0;
- pData->current.patternLen = 0;
- pData->loopCount = 0;
- pData->restore.fileOffset = -1;
- pData->note = 0;
- pData->restTicks = 0;
- pData->velocity = OTA_VEL_DEFAULT;
- pData->style = 0;
- pData->octave = 59;
-
- /* seek to start of data */
- if ((result = EAS_HWFileSeek(pEASData->hwInstData, pData->fileHandle, pData->fileOffset)) != EAS_SUCCESS)
- return result;
-
- /* read the first byte, should be command length */
- if ((result = EAS_HWGetByte(pEASData->hwInstData, pData->fileHandle, &temp)) != EAS_SUCCESS)
- return result;
-
- /* read all the commands */
- i = temp;
- state = 0;
- while (i--)
- {
-
- /* fetch command, always starts on byte boundary */
- pData->current.bitCount = 0;
- if ((result = OTA_FetchBitField(pEASData->hwInstData, pData, 7, &temp)) != EAS_SUCCESS)
- return result;
-
- if (state == 0)
- {
- if (temp != OTA_RINGTONE)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Expected OTA Ring Tone Programming type\n"); */ }
- return EAS_ERROR_FILE_FORMAT;
- }
- state++;
- }
- else
- {
-
- if (temp == OTA_SOUND)
- break;
-
- if (temp == OTA_UNICODE)
- pData->flags |= OTA_FLAGS_UNICODE;
- else
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Expected OTA Sound or Unicode type\n"); */ }
- return EAS_ERROR_FILE_FORMAT;
- }
- }
- }
-
- /* get song type */
- if ((result = OTA_FetchBitField(pEASData->hwInstData, pData, 3, &temp)) != EAS_SUCCESS)
- return result;
-
- /* check for basic song type */
- if (temp == OTA_BASIC_SONG_TYPE)
- {
- /* fetch title length */
- if ((result = OTA_FetchBitField(pEASData->hwInstData, pData, 4, &titleLen)) != EAS_SUCCESS)
- return result;
-
- /* if unicode, double the length */
- if (pData->flags & OTA_FLAGS_UNICODE)
- titleLen = (EAS_U8) (titleLen << 1);
-
- /* zero the metadata buffer */
- if (pData->metadata.buffer)
- EAS_HWMemSet(pData->metadata.buffer, 0, pData->metadata.bufferSize);
-
- /* read the song title */
- for (i = 0; i < titleLen; i++)
- {
- /* fetch character */
- if ((result = OTA_FetchBitField(pEASData->hwInstData, pData, 8, &temp)) != EAS_SUCCESS)
- return result;
-
- /* check for metadata callback */
- if (pData->metadata.callback)
- {
- if (i < (pData->metadata.bufferSize - 1))
- pData->metadata.buffer[i] = (char) temp;
- }
- }
-
- /* if host has registered callback, call it now */
- if (pData->metadata.callback)
- (*pData->metadata.callback)(EAS_METADATA_TITLE, pData->metadata.buffer, pData->metadata.pUserData);
- }
-
- /* must be temporary song */
- else if (temp != OTA_TEMPORARY_SONG_TYPE)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Expected OTA basic or temporary song type\n"); */ }
- return EAS_ERROR_FILE_FORMAT;
- }
-
- /* get the song length */
- if ((result = OTA_FetchBitField(pEASData->hwInstData, pData, 8, &pData->numPatterns)) != EAS_SUCCESS)
- return result;
-
- /* sanity check */
- if (pData->numPatterns == 0)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "OTA number of patterns is zero\n"); */ }
- return EAS_ERROR_FILE_FORMAT;
- }
-
- /* at start of first pattern */
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * OTA_FetchBitField()
- *----------------------------------------------------------------------------
- * Purpose:
- * Fetch a specified number of bits from the input stream
- *
- * Inputs:
- *
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT OTA_FetchBitField (EAS_HW_DATA_HANDLE hwInstData, S_OTA_DATA *pData, EAS_I32 numBits, EAS_U8 *pValue)
-{
- EAS_RESULT result;
- EAS_I32 bitsLeft;
- EAS_U8 value;
-
- value = 0;
-
- /* do we have enough bits? */
- bitsLeft = pData->current.bitCount - numBits;
-
- /* not enough bits, assemble them from 2 characters */
- if (bitsLeft < 0)
- {
- /* grab the remaining bits from the previous byte */
- if (pData->current.bitCount)
- /*lint -e{504,734} this is a legitimate shift operation */
- value = pData->current.dataByte << -bitsLeft;
-
- /* read the next byte */
- if ((result = EAS_HWGetByte(hwInstData, pData->fileHandle, &pData->current.dataByte)) != EAS_SUCCESS)
- return result;
- bitsLeft += 8;
- }
-
- /* more bits than needed? */
- if (bitsLeft > 0)
- {
- value |= pData->current.dataByte >> bitsLeft;
- pData->current.bitCount = (EAS_U8) bitsLeft;
- pData->current.dataByte = pData->current.dataByte & (0xff >> (8 - bitsLeft));
- }
-
- /* exactly the right number of bits */
- else
- {
- value |= pData->current.dataByte;
- pData->current.bitCount = 0;
- }
-
- *pValue = value;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * OTA_SavePosition()
- *----------------------------------------------------------------------------
- * Purpose:
- *
- *
- * Inputs:
- *
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT OTA_SavePosition (EAS_HW_DATA_HANDLE hwInstData, S_OTA_DATA *pData, S_OTA_LOC *pLoc)
-{
- EAS_HWMemCpy(pLoc, &pData->current, sizeof(S_OTA_LOC));
- return EAS_HWFilePos(hwInstData, pData->fileHandle, &pLoc->fileOffset);
-}
-
-/*----------------------------------------------------------------------------
- * OTA_RestorePosition()
- *----------------------------------------------------------------------------
- * Purpose:
- *
- *
- * Inputs:
- *
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT OTA_RestorePosition (EAS_HW_DATA_HANDLE hwInstData, S_OTA_DATA *pData, S_OTA_LOC *pLoc)
-{
- EAS_HWMemCpy(&pData->current, pLoc, sizeof(S_OTA_LOC));
- pData->restore.fileOffset = -1;
- return EAS_HWFileSeek(hwInstData, pData->fileHandle, pLoc->fileOffset);
-}
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 795 $
+ * $Date: 2007-08-01 00:14:45 -0700 (Wed, 01 Aug 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+#include "eas_data.h"
+#include "eas_miditypes.h"
+#include "eas_parser.h"
+#include "eas_report.h"
+#include "eas_host.h"
+#include "eas_midi.h"
+#include "eas_config.h"
+#include "eas_vm_protos.h"
+#include "eas_otadata.h"
+
+/* increase gain for mono ringtones */
+#define OTA_GAIN_OFFSET 8
+
+/* file definitions */
+#define OTA_RINGTONE 0x25
+#define OTA_SOUND 0x1d
+#define OTA_UNICODE 0x22
+
+/* song type definitions */
+#define OTA_BASIC_SONG_TYPE 0x01
+#define OTA_TEMPORARY_SONG_TYPE 0x02
+
+/* instruction ID coding */
+#define OTA_PATTERN_HEADER_ID 0x00
+#define OTA_NOTE_INST_ID 0x01
+#define OTA_SCALE_INST_ID 0x02
+#define OTA_STYLE_INST_ID 0x03
+#define OTA_TEMPO_INST_ID 0x04
+#define OTA_VOLUME_INST_ID 0x05
+
+/* note durations */
+#define OTA_NORMAL_DURATION 0x00
+#define OTA_DOTTED_NOTE 0x01
+#define OTA_DOUBLE_DOTTED_NOTE 0x02
+#define OTA_TRIPLET_NOTE 0x03
+
+/* loop count value for infinite loop */
+#define OTA_INFINITE_LOOP 0x0f
+
+/* length of 32nd note in 1/256ths of a msec for 63 BPM tempo */
+#define DEFAULT_TICK_CONV 30476
+
+/* default channel and program for OTA playback */
+#define OTA_CHANNEL 0
+#define OTA_PROGRAM 80
+#define OTA_VEL_MUL 4
+#define OTA_VEL_OFS 67
+#define OTA_VEL_DEFAULT 95
+
+/* multiplier for fixed point triplet conversion */
+#define TRIPLET_MULTIPLIER 683
+#define TRIPLET_SHIFT 10
+
+/* local prototypes */
+static EAS_RESULT OTA_CheckFileType (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle, EAS_VOID_PTR *ppHandle, EAS_I32 offset);
+static EAS_RESULT OTA_Prepare (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
+static EAS_RESULT OTA_Time (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_U32 *pTime);
+static EAS_RESULT OTA_Event (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_INT parserMode);
+static EAS_RESULT OTA_State (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_STATE *pState);
+static EAS_RESULT OTA_Close (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
+static EAS_RESULT OTA_Reset (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
+static EAS_RESULT OTA_Pause (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
+static EAS_RESULT OTA_Resume (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
+static EAS_RESULT OTA_SetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value);
+static EAS_RESULT OTA_GetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue);
+static EAS_RESULT OTA_ParseHeader (S_EAS_DATA *pEASData, S_OTA_DATA* pData);
+static EAS_RESULT OTA_FetchBitField (EAS_HW_DATA_HANDLE hwInstData, S_OTA_DATA *pData, EAS_I32 numBits, EAS_U8 *pValue);
+static EAS_RESULT OTA_SavePosition (EAS_HW_DATA_HANDLE hwInstData, S_OTA_DATA *pData, S_OTA_LOC *pLoc);
+static EAS_RESULT OTA_RestorePosition (EAS_HW_DATA_HANDLE hwInstData, S_OTA_DATA *pData, S_OTA_LOC *pLoc);
+
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_OTA_Parser
+ *
+ * This structure contains the functional interface for the OTA parser
+ *----------------------------------------------------------------------------
+*/
+const S_FILE_PARSER_INTERFACE EAS_OTA_Parser =
+{
+ OTA_CheckFileType,
+ OTA_Prepare,
+ OTA_Time,
+ OTA_Event,
+ OTA_State,
+ OTA_Close,
+ OTA_Reset,
+ OTA_Pause,
+ OTA_Resume,
+ NULL,
+ OTA_SetData,
+ OTA_GetData,
+ NULL
+};
+
+/*----------------------------------------------------------------------------
+ *
+ * bpmTable
+ *
+ * BPM conversion table. Converts bpm values to 256ths of a millisecond for a 32nd note
+ *----------------------------------------------------------------------------
+*/
+static const EAS_U32 bpmTable[32] =
+{
+ 76800, 68571, 61935, 54857,
+ 48000, 42667, 38400, 34286,
+ 30476, 27429, 24000, 21333,
+ 19200, 17143, 15360, 13714,
+ 12000, 10667, 9600, 8533,
+ 7680, 6737, 6000, 5408,
+ 4800, 4267, 3840, 3398,
+ 3024, 2685, 2400, 2133
+};
+
+/*----------------------------------------------------------------------------
+ * OTA_CheckFileType()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Check the file type to see if we can parse it
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT OTA_CheckFileType (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle, EAS_VOID_PTR *ppHandle, EAS_I32 offset)
+{
+ S_OTA_DATA* pData;
+ EAS_RESULT result;
+ EAS_INT cmdLen;
+ EAS_INT state;
+ EAS_U8 temp;
+
+ /* read the first byte, should be command length */
+ *ppHandle = NULL;
+ if ((result = EAS_HWGetByte(pEASData->hwInstData, fileHandle, &temp)) != EAS_SUCCESS)
+ return result;
+
+ /* read all the commands */
+ cmdLen = temp;
+ state = 0;
+ while (cmdLen--)
+ {
+
+ /* read the command, upper 7 bits */
+ if ((result = EAS_HWGetByte(pEASData->hwInstData, fileHandle, &temp)) != EAS_SUCCESS)
+ return result;
+ temp = temp >> 1;
+
+ if (state == 0)
+ {
+ if (temp != OTA_RINGTONE)
+ break;
+ state++;
+ }
+ else
+ {
+
+ if (temp == OTA_SOUND)
+ {
+
+ /* check for static memory allocation */
+ if (pEASData->staticMemoryModel)
+ pData = EAS_CMEnumData(EAS_CM_OTA_DATA);
+ else
+ pData = EAS_HWMalloc(pEASData->hwInstData, sizeof(S_OTA_DATA));
+ if (!pData)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Malloc failed in OTA_Prepare\n"); */ }
+ return EAS_ERROR_MALLOC_FAILED;
+ }
+ EAS_HWMemSet(pData, 0, sizeof(S_OTA_DATA));
+
+ /* return a pointer to the instance data */
+ pData->fileHandle = fileHandle;
+ pData->fileOffset = offset;
+ pData->state = EAS_STATE_OPEN;
+ *ppHandle = pData;
+ break;
+ }
+
+ if (temp != OTA_UNICODE)
+ break;
+ }
+ }
+
+ /* not recognized */
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * OTA_Prepare()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Prepare to parse the file. Allocates instance data (or uses static allocation for
+ * static memory model).
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT OTA_Prepare (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
+{
+ S_OTA_DATA* pData;
+ EAS_RESULT result;
+
+ /* check for valid state */
+ pData = (S_OTA_DATA*) pInstData;
+ if (pData->state != EAS_STATE_OPEN)
+ return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
+
+ /* instantiate a synthesizer */
+ if ((result = VMInitMIDI(pEASData, &pData->pSynth)) != EAS_SUCCESS)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "VMInitMIDI returned %d\n", result); */ }
+ return result;
+ }
+
+ pData->state = EAS_STATE_ERROR;
+ if ((result = OTA_ParseHeader(pEASData, pData)) != EAS_SUCCESS)
+ return result;
+
+ pData->state = EAS_STATE_READY;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * OTA_Time()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Returns the time of the next event in msecs
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ * pTime - pointer to variable to hold time of next event (in msecs)
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pEASData) common decoder interface - pEASData not used */
+static EAS_RESULT OTA_Time (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_U32 *pTime)
+{
+ S_OTA_DATA *pData;
+
+ pData = (S_OTA_DATA*) pInstData;
+
+ /* return time in milliseconds */
+ /*lint -e{704} use shift instead of division */
+ *pTime = pData->time >> 8;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * OTA_Event()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Parse the next event in the file
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT OTA_Event (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_INT parserMode)
+{
+ S_OTA_DATA* pData;
+ EAS_RESULT result;
+ EAS_U32 duration;
+ EAS_U8 temp;
+
+ pData = (S_OTA_DATA*) pInstData;
+ if (pData->state >= EAS_STATE_OPEN)
+ return EAS_SUCCESS;
+
+ /* initialize MIDI channel when the track starts playing */
+ if (pData->time == 0)
+ {
+ /* set program to square lead */
+ if (parserMode != eParserModeMetaData)
+ VMProgramChange(pEASData->pVoiceMgr, pData->pSynth, OTA_CHANNEL, OTA_PROGRAM);
+
+ /* set channel volume to max */
+ if (parserMode != eParserModeMetaData)
+ VMControlChange(pEASData->pVoiceMgr, pData->pSynth, OTA_CHANNEL, 7, 127);
+ }
+
+ /* check for end of note */
+ if (pData->note)
+ {
+ /* stop the note */
+ VMStopNote(pEASData->pVoiceMgr, pData->pSynth, OTA_CHANNEL, pData->note, 0);
+ pData->note = 0;
+
+ /* check for rest between notes */
+ if (pData->restTicks)
+ {
+ pData->time += (EAS_I32) pData->restTicks;
+ pData->restTicks = 0;
+ return EAS_SUCCESS;
+ }
+ }
+
+ /* if not in a pattern, read the pattern header */
+ while (pData->current.patternLen == 0)
+ {
+
+ /* check for loop - don't do infinite loops when locating */
+ if (pData->loopCount && ((parserMode == eParserModePlay) || (pData->loopCount != OTA_INFINITE_LOOP)))
+ {
+ /* if not infinite loop, decrement loop count */
+ if (pData->loopCount != OTA_INFINITE_LOOP)
+ pData->loopCount--;
+
+ /* back to start of pattern*/
+ if ((result = OTA_RestorePosition(pEASData->hwInstData, pData, &pData->patterns[pData->currentPattern])) != EAS_SUCCESS)
+ return result;
+ }
+
+ /* if no previous position to restore, continue forward */
+ else if (pData->restore.fileOffset < 0)
+ {
+
+ /* check for end of song */
+ if (pData->numPatterns == 0)
+ {
+ pData->state = EAS_STATE_STOPPING;
+ VMReleaseAllVoices(pEASData->pVoiceMgr, pData->pSynth);
+ return EAS_SUCCESS;
+ }
+
+ /* read the next pattern header */
+ if ((result = OTA_FetchBitField(pEASData->hwInstData, pData, 3, &temp)) != EAS_SUCCESS)
+ return result;
+ if (temp != OTA_PATTERN_HEADER_ID)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Expected OTA pattern header\n"); */ }
+ return EAS_ERROR_FILE_FORMAT;
+ }
+
+ /* get the pattern ID */
+ if ((result = OTA_FetchBitField(pEASData->hwInstData, pData, 2, &pData->currentPattern)) != EAS_SUCCESS)
+ return result;
+
+ /* get the loop count */
+ if ((result = OTA_FetchBitField(pEASData->hwInstData, pData, 4, &pData->loopCount)) != EAS_SUCCESS)
+ return result;
+
+ /* get the pattern length */
+ if ((result = OTA_FetchBitField(pEASData->hwInstData, pData, 8, &pData->current.patternLen)) != EAS_SUCCESS)
+ return result;
+
+ /* if pattern definition, save the current position */
+ if (pData->current.patternLen)
+ {
+ if ((result = OTA_SavePosition(pEASData->hwInstData, pData, &pData->patterns[pData->currentPattern])) != EAS_SUCCESS)
+ return result;
+ }
+
+ /* if pattern length is zero, repeat a previous pattern */
+ else
+ {
+ /* make sure it's a valid pattern */
+ if (pData->patterns[pData->currentPattern].fileOffset < 0)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "OTA pattern error, invalid pattern specified\n"); */ }
+ return EAS_ERROR_FILE_FORMAT;
+ }
+
+ /* save current position and data */
+ if ((result = OTA_SavePosition(pEASData->hwInstData, pData, &pData->restore)) != EAS_SUCCESS)
+ return result;
+
+ /* seek to the pattern in the file */
+ if ((result = OTA_RestorePosition(pEASData->hwInstData, pData, &pData->patterns[pData->currentPattern])) != EAS_SUCCESS)
+ return result;
+ }
+
+ /* decrement pattern count */
+ pData->numPatterns--;
+ }
+
+ /* restore previous position */
+ else
+ {
+ if ((result = OTA_RestorePosition(pEASData->hwInstData, pData, &pData->restore)) != EAS_SUCCESS)
+ return result;
+ }
+ }
+
+ /* get the next event */
+ if ((result = OTA_FetchBitField(pEASData->hwInstData, pData, 3, &temp)) != EAS_SUCCESS)
+ return result;
+
+ switch (temp)
+ {
+ case OTA_NOTE_INST_ID:
+ /* fetch note value */
+ if ((result = OTA_FetchBitField(pEASData->hwInstData, pData, 4, &pData->note)) != EAS_SUCCESS)
+ return result;
+
+ /* fetch note duration */
+ if ((result = OTA_FetchBitField(pEASData->hwInstData, pData, 3, &temp)) != EAS_SUCCESS)
+ return result;
+ duration = pData->tick * (0x20 >> temp);
+
+ /* fetch note duration modifier */
+ if ((result = OTA_FetchBitField(pEASData->hwInstData, pData, 2, &temp)) != EAS_SUCCESS)
+ return result;
+ switch (temp)
+ {
+ case OTA_NORMAL_DURATION:
+ break;
+
+ case OTA_DOTTED_NOTE:
+ duration += duration >> 1;
+ break;
+
+ case OTA_DOUBLE_DOTTED_NOTE:
+ duration += (duration >> 1) + (duration >> 2);
+ break;
+
+ case OTA_TRIPLET_NOTE:
+ duration = (duration * TRIPLET_MULTIPLIER) >> TRIPLET_SHIFT;
+ break;
+
+ default:
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Unrecognized note duration ignored\n"); */ }
+ break;
+ }
+
+ /* check for note */
+ if (pData->note)
+ {
+
+ /* determine note length based on style */
+ switch (pData->style)
+ {
+ case 0:
+ pData->restTicks = duration >> 4;
+ break;
+ case 1:
+ pData->restTicks = 0;
+ break;
+ case 2:
+ pData->restTicks = duration >> 1;
+ break;
+ default:
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Unrecognized note style ignored\n"); */ }
+ }
+
+ /* add octave */
+ pData->note += pData->octave;
+ if (parserMode == eParserModePlay)
+ VMStartNote(pEASData->pVoiceMgr, pData->pSynth, OTA_CHANNEL, pData->note, pData->velocity);
+ pData->time += (EAS_I32) duration - (EAS_I32) pData->restTicks;
+ }
+
+ /* this is a rest */
+ else
+ pData->time += (EAS_I32) duration;
+ break;
+
+ case OTA_SCALE_INST_ID:
+ /* fetch octave */
+ if ((result = OTA_FetchBitField(pEASData->hwInstData, pData, 2, &temp)) != EAS_SUCCESS)
+ return result;
+ pData->octave = (EAS_U8) (temp * 12 + 59);
+ break;
+
+ case OTA_STYLE_INST_ID:
+ /* fetch note style */
+ if ((result = OTA_FetchBitField(pEASData->hwInstData, pData, 2, &pData->style)) != EAS_SUCCESS)
+ return result;
+ break;
+
+ case OTA_TEMPO_INST_ID:
+ /* fetch tempo */
+ if ((result = OTA_FetchBitField(pEASData->hwInstData, pData, 5, &temp)) != EAS_SUCCESS)
+ return result;
+ pData->tick = bpmTable[temp];
+ break;
+
+ case OTA_VOLUME_INST_ID:
+ /* fetch volume */
+ if ((result = OTA_FetchBitField(pEASData->hwInstData, pData, 4, &temp)) != EAS_SUCCESS)
+ return result;
+ pData->velocity = temp ? (EAS_U8) (temp * OTA_VEL_MUL + OTA_VEL_OFS) : 0;
+ break;
+
+ default:
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Unexpected instruction ID in OTA stream\n"); */ }
+ return EAS_ERROR_FILE_FORMAT;
+ }
+
+ /* decrement pattern length */
+ pData->current.patternLen--;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * OTA_State()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Returns the current state of the stream
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ * pState - pointer to variable to store state
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pEASData) common decoder interface - pEASData not used */
+static EAS_RESULT OTA_State (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 *pState)
+{
+ S_OTA_DATA* pData;
+
+ /* establish pointer to instance data */
+ pData = (S_OTA_DATA*) pInstData;
+
+ /* if stopping, check to see if synth voices are active */
+ if (pData->state == EAS_STATE_STOPPING)
+ {
+ if (VMActiveVoices(pData->pSynth) == 0)
+ pData->state = EAS_STATE_STOPPED;
+ }
+
+ if (pData->state == EAS_STATE_PAUSING)
+ {
+ if (VMActiveVoices(pData->pSynth) == 0)
+ pData->state = EAS_STATE_PAUSED;
+ }
+
+ /* return current state */
+ *pState = pData->state;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * OTA_Close()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Close the file and clean up
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT OTA_Close (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
+{
+ S_OTA_DATA* pData;
+ EAS_RESULT result;
+
+ pData = (S_OTA_DATA*) pInstData;
+
+ /* close the file */
+ if ((result = EAS_HWCloseFile(pEASData->hwInstData, pData->fileHandle)) != EAS_SUCCESS)
+ return result;
+
+ /* free the synth */
+ if (pData->pSynth != NULL)
+ VMMIDIShutdown(pEASData, pData->pSynth);
+
+ /* if using dynamic memory, free it */
+ if (!pEASData->staticMemoryModel)
+ EAS_HWFree(pEASData->hwInstData, pData);
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * OTA_Reset()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Reset the sequencer. Used for locating backwards in the file.
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT OTA_Reset (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
+{
+ S_OTA_DATA* pData;
+ EAS_RESULT result;
+
+ pData = (S_OTA_DATA*) pInstData;
+
+ /* reset the synth */
+ VMReset(pEASData->pVoiceMgr, pData->pSynth, EAS_TRUE);
+ pData->note = 0;
+
+ /* reset file position and re-parse header */
+ pData->state = EAS_STATE_ERROR;
+ if ((result = OTA_ParseHeader (pEASData, pData)) != EAS_SUCCESS)
+ return result;
+
+ pData->state = EAS_STATE_READY;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * OTA_Pause()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Pauses the sequencer. Mutes all voices and sets state to pause.
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT OTA_Pause (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
+{
+ S_OTA_DATA *pData;
+
+ /* can't pause a stopped stream */
+ pData = (S_OTA_DATA*) pInstData;
+ if (pData->state == EAS_STATE_STOPPED)
+ return EAS_ERROR_ALREADY_STOPPED;
+
+ /* mute the synthesizer */
+ VMMuteAllVoices(pEASData->pVoiceMgr, pData->pSynth);
+ pData->state = EAS_STATE_PAUSING;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * OTA_Resume()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Resume playing after a pause, sets state back to playing.
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pEASData) common decoder interface - pEASData not used */
+static EAS_RESULT OTA_Resume (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
+{
+ S_OTA_DATA *pData;
+
+ /* can't resume a stopped stream */
+ pData = (S_OTA_DATA*) pInstData;
+ if (pData->state == EAS_STATE_STOPPED)
+ return EAS_ERROR_ALREADY_STOPPED;
+
+ /* nothing to do but resume playback */
+ pData->state = EAS_STATE_PLAY;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * OTA_SetData()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Return file type
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pEASData) common decoder interface - pEASData not used */
+static EAS_RESULT OTA_SetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value)
+{
+ S_OTA_DATA *pData;
+
+ pData = (S_OTA_DATA *) pInstData;
+ switch (param)
+ {
+
+ /* set metadata callback */
+ case PARSER_DATA_METADATA_CB:
+ EAS_HWMemCpy(&pData->metadata, (void*) value, sizeof(S_METADATA_CB));
+ break;
+
+ default:
+ return EAS_ERROR_INVALID_PARAMETER;
+ }
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * OTA_GetData()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Return file type
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pEASData) common decoder interface - pEASData not used */
+static EAS_RESULT OTA_GetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue)
+{
+ S_OTA_DATA *pData;
+
+ pData = (S_OTA_DATA*) pInstData;
+ switch (param)
+ {
+ /* return file type as OTA */
+ case PARSER_DATA_FILE_TYPE:
+ *pValue = EAS_FILE_OTA;
+ break;
+
+#if 0
+ /* set transposition */
+ case PARSER_DATA_TRANSPOSITION:
+ *pValue = pData->transposition;
+ break;
+#endif
+
+ case PARSER_DATA_SYNTH_HANDLE:
+ *pValue = (EAS_I32) pData->pSynth;
+ break;
+
+ case PARSER_DATA_GAIN_OFFSET:
+ *pValue = OTA_GAIN_OFFSET;
+ break;
+
+ default:
+ return EAS_ERROR_INVALID_PARAMETER;
+ }
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * OTA_ParseHeader()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Prepare to parse the file. Allocates instance data (or uses static allocation for
+ * static memory model).
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT OTA_ParseHeader (S_EAS_DATA *pEASData, S_OTA_DATA* pData)
+{
+ EAS_RESULT result;
+ EAS_INT i;
+ EAS_INT state;
+ EAS_U8 temp;
+ EAS_U8 titleLen;
+
+ /* initialize some data */
+ pData->flags = 0;
+ pData->time = 0;
+ pData->tick = DEFAULT_TICK_CONV;
+ pData->patterns[0].fileOffset = pData->patterns[1].fileOffset =
+ pData->patterns[2].fileOffset = pData->patterns[3].fileOffset = -1;
+ pData->current.bitCount = 0;
+ pData->current.patternLen = 0;
+ pData->loopCount = 0;
+ pData->restore.fileOffset = -1;
+ pData->note = 0;
+ pData->restTicks = 0;
+ pData->velocity = OTA_VEL_DEFAULT;
+ pData->style = 0;
+ pData->octave = 59;
+
+ /* seek to start of data */
+ if ((result = EAS_HWFileSeek(pEASData->hwInstData, pData->fileHandle, pData->fileOffset)) != EAS_SUCCESS)
+ return result;
+
+ /* read the first byte, should be command length */
+ if ((result = EAS_HWGetByte(pEASData->hwInstData, pData->fileHandle, &temp)) != EAS_SUCCESS)
+ return result;
+
+ /* read all the commands */
+ i = temp;
+ state = 0;
+ while (i--)
+ {
+
+ /* fetch command, always starts on byte boundary */
+ pData->current.bitCount = 0;
+ if ((result = OTA_FetchBitField(pEASData->hwInstData, pData, 7, &temp)) != EAS_SUCCESS)
+ return result;
+
+ if (state == 0)
+ {
+ if (temp != OTA_RINGTONE)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Expected OTA Ring Tone Programming type\n"); */ }
+ return EAS_ERROR_FILE_FORMAT;
+ }
+ state++;
+ }
+ else
+ {
+
+ if (temp == OTA_SOUND)
+ break;
+
+ if (temp == OTA_UNICODE)
+ pData->flags |= OTA_FLAGS_UNICODE;
+ else
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Expected OTA Sound or Unicode type\n"); */ }
+ return EAS_ERROR_FILE_FORMAT;
+ }
+ }
+ }
+
+ /* get song type */
+ if ((result = OTA_FetchBitField(pEASData->hwInstData, pData, 3, &temp)) != EAS_SUCCESS)
+ return result;
+
+ /* check for basic song type */
+ if (temp == OTA_BASIC_SONG_TYPE)
+ {
+ /* fetch title length */
+ if ((result = OTA_FetchBitField(pEASData->hwInstData, pData, 4, &titleLen)) != EAS_SUCCESS)
+ return result;
+
+ /* if unicode, double the length */
+ if (pData->flags & OTA_FLAGS_UNICODE)
+ titleLen = (EAS_U8) (titleLen << 1);
+
+ /* zero the metadata buffer */
+ if (pData->metadata.buffer)
+ EAS_HWMemSet(pData->metadata.buffer, 0, pData->metadata.bufferSize);
+
+ /* read the song title */
+ for (i = 0; i < titleLen; i++)
+ {
+ /* fetch character */
+ if ((result = OTA_FetchBitField(pEASData->hwInstData, pData, 8, &temp)) != EAS_SUCCESS)
+ return result;
+
+ /* check for metadata callback */
+ if (pData->metadata.callback)
+ {
+ if (i < (pData->metadata.bufferSize - 1))
+ pData->metadata.buffer[i] = (char) temp;
+ }
+ }
+
+ /* if host has registered callback, call it now */
+ if (pData->metadata.callback)
+ (*pData->metadata.callback)(EAS_METADATA_TITLE, pData->metadata.buffer, pData->metadata.pUserData);
+ }
+
+ /* must be temporary song */
+ else if (temp != OTA_TEMPORARY_SONG_TYPE)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Expected OTA basic or temporary song type\n"); */ }
+ return EAS_ERROR_FILE_FORMAT;
+ }
+
+ /* get the song length */
+ if ((result = OTA_FetchBitField(pEASData->hwInstData, pData, 8, &pData->numPatterns)) != EAS_SUCCESS)
+ return result;
+
+ /* sanity check */
+ if (pData->numPatterns == 0)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "OTA number of patterns is zero\n"); */ }
+ return EAS_ERROR_FILE_FORMAT;
+ }
+
+ /* at start of first pattern */
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * OTA_FetchBitField()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Fetch a specified number of bits from the input stream
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT OTA_FetchBitField (EAS_HW_DATA_HANDLE hwInstData, S_OTA_DATA *pData, EAS_I32 numBits, EAS_U8 *pValue)
+{
+ EAS_RESULT result;
+ EAS_I32 bitsLeft;
+ EAS_U8 value;
+
+ value = 0;
+
+ /* do we have enough bits? */
+ bitsLeft = pData->current.bitCount - numBits;
+
+ /* not enough bits, assemble them from 2 characters */
+ if (bitsLeft < 0)
+ {
+ /* grab the remaining bits from the previous byte */
+ if (pData->current.bitCount)
+ /*lint -e{504,734} this is a legitimate shift operation */
+ value = pData->current.dataByte << -bitsLeft;
+
+ /* read the next byte */
+ if ((result = EAS_HWGetByte(hwInstData, pData->fileHandle, &pData->current.dataByte)) != EAS_SUCCESS)
+ return result;
+ bitsLeft += 8;
+ }
+
+ /* more bits than needed? */
+ if (bitsLeft > 0)
+ {
+ value |= pData->current.dataByte >> bitsLeft;
+ pData->current.bitCount = (EAS_U8) bitsLeft;
+ pData->current.dataByte = pData->current.dataByte & (0xff >> (8 - bitsLeft));
+ }
+
+ /* exactly the right number of bits */
+ else
+ {
+ value |= pData->current.dataByte;
+ pData->current.bitCount = 0;
+ }
+
+ *pValue = value;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * OTA_SavePosition()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ *
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT OTA_SavePosition (EAS_HW_DATA_HANDLE hwInstData, S_OTA_DATA *pData, S_OTA_LOC *pLoc)
+{
+ EAS_HWMemCpy(pLoc, &pData->current, sizeof(S_OTA_LOC));
+ return EAS_HWFilePos(hwInstData, pData->fileHandle, &pLoc->fileOffset);
+}
+
+/*----------------------------------------------------------------------------
+ * OTA_RestorePosition()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ *
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT OTA_RestorePosition (EAS_HW_DATA_HANDLE hwInstData, S_OTA_DATA *pData, S_OTA_LOC *pLoc)
+{
+ EAS_HWMemCpy(&pData->current, pLoc, sizeof(S_OTA_LOC));
+ pData->restore.fileOffset = -1;
+ return EAS_HWFileSeek(hwInstData, pData->fileHandle, pLoc->fileOffset);
+}
+
diff --git a/arm-fm-22k/lib_src/eas_otadata.c b/arm-fm-22k/lib_src/eas_otadata.c
index 237f832..7463a0c 100644
--- a/arm-fm-22k/lib_src/eas_otadata.c
+++ b/arm-fm-22k/lib_src/eas_otadata.c
@@ -1,12 +1,12 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_otadata..c
- *
- * Contents and purpose:
- * OTA Stream Parser data module for static memory model
- *
- * Copyright Sonic Network Inc. 2005
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_otadata..c
+ *
+ * Contents and purpose:
+ * OTA Stream Parser data module for static memory model
+ *
+ * Copyright Sonic Network Inc. 2005
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,23 +19,23 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 547 $
- * $Date: 2007-01-31 16:30:17 -0800 (Wed, 31 Jan 2007) $
- *----------------------------------------------------------------------------
-*/
-
-#include "eas_types.h"
-#include "eas_otadata.h"
-
-/*----------------------------------------------------------------------------
- *
- * eas_OTAData
- *
- * Static memory allocation for OTA parser
- *----------------------------------------------------------------------------
-*/
-S_OTA_DATA eas_OTAData;
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 547 $
+ * $Date: 2007-01-31 16:30:17 -0800 (Wed, 31 Jan 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+#include "eas_types.h"
+#include "eas_otadata.h"
+
+/*----------------------------------------------------------------------------
+ *
+ * eas_OTAData
+ *
+ * Static memory allocation for OTA parser
+ *----------------------------------------------------------------------------
+*/
+S_OTA_DATA eas_OTAData;
+
diff --git a/arm-fm-22k/lib_src/eas_otadata.h b/arm-fm-22k/lib_src/eas_otadata.h
index 63e963f..c06e3d3 100644
--- a/arm-fm-22k/lib_src/eas_otadata.h
+++ b/arm-fm-22k/lib_src/eas_otadata.h
@@ -1,14 +1,14 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_otadata.h
- *
- * Contents and purpose:
- * OTA File Parser
- *
- * This file contains data declarations for the OTA parser.
- *
- * Copyright Sonic Network Inc. 2005
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_otadata.h
+ *
+ * Contents and purpose:
+ * OTA File Parser
+ *
+ * This file contains data declarations for the OTA parser.
+ *
+ * Copyright Sonic Network Inc. 2005
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,61 +21,61 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 82 $
- * $Date: 2006-07-10 11:45:19 -0700 (Mon, 10 Jul 2006) $
- *----------------------------------------------------------------------------
-*/
-
-#ifndef EAS_OTADATA_H
-#define EAS_OTADATA_H
-
-#include "eas_data.h"
-
-/* definition for state flags */
-#define OTA_FLAGS_UNICODE 0x01 /* unicode text */
-
-/*----------------------------------------------------------------------------
- *
- * S_OTA_DATA
- *
- * This structure contains the state data for the OTA parser
- *----------------------------------------------------------------------------
-*/
-
-typedef struct
-{
- EAS_I32 fileOffset; /* offset to location in file */
- EAS_U8 patternLen; /* length of current pattern */
- EAS_U8 dataByte; /* previous char from file */
- EAS_U8 bitCount; /* bit count in char */
-} S_OTA_LOC;
-
-typedef struct
-{
- EAS_FILE_HANDLE fileHandle; /* file handle */
- S_SYNTH *pSynth; /* synth handle */
- EAS_I32 fileOffset; /* offset to start of data */
- EAS_I32 time; /* current time in 256ths of a msec */
- EAS_U32 tick; /* length of 32nd note in 256th of a msec */
- EAS_U32 restTicks; /* ticks to rest after current note */
- S_OTA_LOC patterns[4]; /* pattern locations */
- S_OTA_LOC current; /* current location */
- S_OTA_LOC restore; /* previous location */
- S_METADATA_CB metadata; /* metadata callback */
- EAS_U8 flags; /* bit flags */
- EAS_U8 numPatterns; /* number of patterns left in song */
- EAS_U8 currentPattern; /* current pattern for loop */
- EAS_U8 note; /* MIDI note number */
- EAS_U8 octave; /* octave modifier */
- EAS_U8 style; /* from STYLE */
- EAS_U8 velocity; /* current volume */
- EAS_U8 state; /* current state EAS_STATE_XXXX */
- EAS_U8 loopCount; /* loop count for pattern */
-} S_OTA_DATA;
-
-#endif
-
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 82 $
+ * $Date: 2006-07-10 11:45:19 -0700 (Mon, 10 Jul 2006) $
+ *----------------------------------------------------------------------------
+*/
+
+#ifndef EAS_OTADATA_H
+#define EAS_OTADATA_H
+
+#include "eas_data.h"
+
+/* definition for state flags */
+#define OTA_FLAGS_UNICODE 0x01 /* unicode text */
+
+/*----------------------------------------------------------------------------
+ *
+ * S_OTA_DATA
+ *
+ * This structure contains the state data for the OTA parser
+ *----------------------------------------------------------------------------
+*/
+
+typedef struct
+{
+ EAS_I32 fileOffset; /* offset to location in file */
+ EAS_U8 patternLen; /* length of current pattern */
+ EAS_U8 dataByte; /* previous char from file */
+ EAS_U8 bitCount; /* bit count in char */
+} S_OTA_LOC;
+
+typedef struct
+{
+ EAS_FILE_HANDLE fileHandle; /* file handle */
+ S_SYNTH *pSynth; /* synth handle */
+ EAS_I32 fileOffset; /* offset to start of data */
+ EAS_I32 time; /* current time in 256ths of a msec */
+ EAS_U32 tick; /* length of 32nd note in 256th of a msec */
+ EAS_U32 restTicks; /* ticks to rest after current note */
+ S_OTA_LOC patterns[4]; /* pattern locations */
+ S_OTA_LOC current; /* current location */
+ S_OTA_LOC restore; /* previous location */
+ S_METADATA_CB metadata; /* metadata callback */
+ EAS_U8 flags; /* bit flags */
+ EAS_U8 numPatterns; /* number of patterns left in song */
+ EAS_U8 currentPattern; /* current pattern for loop */
+ EAS_U8 note; /* MIDI note number */
+ EAS_U8 octave; /* octave modifier */
+ EAS_U8 style; /* from STYLE */
+ EAS_U8 velocity; /* current volume */
+ EAS_U8 state; /* current state EAS_STATE_XXXX */
+ EAS_U8 loopCount; /* loop count for pattern */
+} S_OTA_DATA;
+
+#endif
+
+
diff --git a/arm-fm-22k/lib_src/eas_pan.c b/arm-fm-22k/lib_src/eas_pan.c
index 373d90e..ae4c69d 100644
--- a/arm-fm-22k/lib_src/eas_pan.c
+++ b/arm-fm-22k/lib_src/eas_pan.c
@@ -1,16 +1,16 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_pan.c
- *
- * Contents and purpose:
- * Calculates left and right gain multipliers based on a pan value from -63 to +63
- *
- * NOTES:
- * The _CMX_PARSER and _MFI_PARSER preprocessor symbols determine
- * whether the parser works for those particular file formats.
- *
- * Copyright Sonic Network Inc. 2005
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_pan.c
+ *
+ * Contents and purpose:
+ * Calculates left and right gain multipliers based on a pan value from -63 to +63
+ *
+ * NOTES:
+ * The _CMX_PARSER and _MFI_PARSER preprocessor symbols determine
+ * whether the parser works for those particular file formats.
+ *
+ * Copyright Sonic Network Inc. 2005
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -23,76 +23,76 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 82 $
- * $Date: 2006-07-10 11:45:19 -0700 (Mon, 10 Jul 2006) $
- *----------------------------------------------------------------------------
-*/
-
-#include "eas_pan.h"
-#include "eas_math.h"
-
-/*----------------------------------------------------------------------------
- * EAS_CalcPanControl()
- *----------------------------------------------------------------------------
- * Purpose:
- * Assign the left and right gain values corresponding to the given pan value.
- *
- * This routine uses sin/cos approximations for an equal power curve:
- *
- * sin(x) = (2-4*c)*x^2 + c + x
- * cos(x) = (2-4*c)*x^2 + c - x
- *
- * where c = 1/sqrt(2)
- * using the a0 + x*(a1 + x*a2) approach
- *
- * Inputs:
- * pan - pan value (-63 to + 63)
- *
- * Outputs:
- * pGainLeft linear gain multiplier for left channel (15-bit fraction)
- * pGainRight linear gain multiplier for left channel (15-bit fraction)
- *
- * Side Effects:
- *----------------------------------------------------------------------------
-*/
-void EAS_CalcPanControl (EAS_INT pan, EAS_I16 *pGainLeft, EAS_I16 *pGainRight)
-{
- EAS_INT temp;
- EAS_INT netAngle;
-
- /* impose hard limit */
- if (pan < -63)
- netAngle = -63;
- else if (pan > 63)
- netAngle = 63;
- else
- netAngle = pan;
-
- /*lint -e{701} <avoid multiply for performance reasons>*/
- netAngle = netAngle << 8;
-
- /* calculate sin */
- temp = EG1_ONE + FMUL_15x15(COEFF_PAN_G2, netAngle);
- temp = COEFF_PAN_G0 + FMUL_15x15(temp, netAngle);
-
- if (temp > SYNTH_FULL_SCALE_EG1_GAIN)
- temp = SYNTH_FULL_SCALE_EG1_GAIN;
- else if (temp < 0)
- temp = 0;
-
- *pGainRight = (EAS_I16) temp;
-
- /* calculate cos */
- temp = -EG1_ONE + FMUL_15x15(COEFF_PAN_G2, netAngle);
- temp = COEFF_PAN_G0 + FMUL_15x15(temp, netAngle);
- if (temp > SYNTH_FULL_SCALE_EG1_GAIN)
- temp = SYNTH_FULL_SCALE_EG1_GAIN;
- else if (temp < 0)
- temp = 0;
-
- *pGainLeft = (EAS_I16) temp;
-}
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 82 $
+ * $Date: 2006-07-10 11:45:19 -0700 (Mon, 10 Jul 2006) $
+ *----------------------------------------------------------------------------
+*/
+
+#include "eas_pan.h"
+#include "eas_math.h"
+
+/*----------------------------------------------------------------------------
+ * EAS_CalcPanControl()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Assign the left and right gain values corresponding to the given pan value.
+ *
+ * This routine uses sin/cos approximations for an equal power curve:
+ *
+ * sin(x) = (2-4*c)*x^2 + c + x
+ * cos(x) = (2-4*c)*x^2 + c - x
+ *
+ * where c = 1/sqrt(2)
+ * using the a0 + x*(a1 + x*a2) approach
+ *
+ * Inputs:
+ * pan - pan value (-63 to + 63)
+ *
+ * Outputs:
+ * pGainLeft linear gain multiplier for left channel (15-bit fraction)
+ * pGainRight linear gain multiplier for left channel (15-bit fraction)
+ *
+ * Side Effects:
+ *----------------------------------------------------------------------------
+*/
+void EAS_CalcPanControl (EAS_INT pan, EAS_I16 *pGainLeft, EAS_I16 *pGainRight)
+{
+ EAS_INT temp;
+ EAS_INT netAngle;
+
+ /* impose hard limit */
+ if (pan < -63)
+ netAngle = -63;
+ else if (pan > 63)
+ netAngle = 63;
+ else
+ netAngle = pan;
+
+ /*lint -e{701} <avoid multiply for performance reasons>*/
+ netAngle = netAngle << 8;
+
+ /* calculate sin */
+ temp = EG1_ONE + FMUL_15x15(COEFF_PAN_G2, netAngle);
+ temp = COEFF_PAN_G0 + FMUL_15x15(temp, netAngle);
+
+ if (temp > SYNTH_FULL_SCALE_EG1_GAIN)
+ temp = SYNTH_FULL_SCALE_EG1_GAIN;
+ else if (temp < 0)
+ temp = 0;
+
+ *pGainRight = (EAS_I16) temp;
+
+ /* calculate cos */
+ temp = -EG1_ONE + FMUL_15x15(COEFF_PAN_G2, netAngle);
+ temp = COEFF_PAN_G0 + FMUL_15x15(temp, netAngle);
+ if (temp > SYNTH_FULL_SCALE_EG1_GAIN)
+ temp = SYNTH_FULL_SCALE_EG1_GAIN;
+ else if (temp < 0)
+ temp = 0;
+
+ *pGainLeft = (EAS_I16) temp;
+}
+
diff --git a/arm-fm-22k/lib_src/eas_pan.h b/arm-fm-22k/lib_src/eas_pan.h
index cefa650..cb0a90d 100644
--- a/arm-fm-22k/lib_src/eas_pan.h
+++ b/arm-fm-22k/lib_src/eas_pan.h
@@ -1,16 +1,16 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_pan.h
- *
- * Contents and purpose:
- * Calculates left and right gain multipliers based on a pan value from -63 to +63
- *
- * NOTES:
- * The _CMX_PARSER and _MFI_PARSER preprocessor symbols determine
- * whether the parser works for those particular file formats.
- *
- * Copyright Sonic Network Inc. 2005
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_pan.h
+ *
+ * Contents and purpose:
+ * Calculates left and right gain multipliers based on a pan value from -63 to +63
+ *
+ * NOTES:
+ * The _CMX_PARSER and _MFI_PARSER preprocessor symbols determine
+ * whether the parser works for those particular file formats.
+ *
+ * Copyright Sonic Network Inc. 2005
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -23,44 +23,44 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 82 $
- * $Date: 2006-07-10 11:45:19 -0700 (Mon, 10 Jul 2006) $
- *----------------------------------------------------------------------------
-*/
-
-#ifndef EAS_PAN_H
-#define _EAS_PAN_H
-
-#include "eas_types.h"
-
-/*----------------------------------------------------------------------------
- * EAS_CalcPanControl()
- *----------------------------------------------------------------------------
- * Purpose:
- * Assign the left and right gain values corresponding to the given pan value.
- *
- * This routine uses sin/cos approximations for an equal power curve:
- *
- * sin(x) = (2-4*c)*x^2 + c + x
- * cos(x) = (2-4*c)*x^2 + c - x
- *
- * where c = 1/sqrt(2)
- * using the a0 + x*(a1 + x*a2) approach
- *
- * Inputs:
- * pan - pan value (-63 to + 63)
- *
- * Outputs:
- * pGainLeft linear gain multiplier for left channel (15-bit fraction)
- * pGainRight linear gain multiplier for left channel (15-bit fraction)
- *
- * Side Effects:
- *----------------------------------------------------------------------------
-*/
-void EAS_CalcPanControl (EAS_INT pan, EAS_I16 *pGainLeft, EAS_I16 *pGainRight);
-
-#endif
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 82 $
+ * $Date: 2006-07-10 11:45:19 -0700 (Mon, 10 Jul 2006) $
+ *----------------------------------------------------------------------------
+*/
+
+#ifndef EAS_PAN_H
+#define _EAS_PAN_H
+
+#include "eas_types.h"
+
+/*----------------------------------------------------------------------------
+ * EAS_CalcPanControl()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Assign the left and right gain values corresponding to the given pan value.
+ *
+ * This routine uses sin/cos approximations for an equal power curve:
+ *
+ * sin(x) = (2-4*c)*x^2 + c + x
+ * cos(x) = (2-4*c)*x^2 + c - x
+ *
+ * where c = 1/sqrt(2)
+ * using the a0 + x*(a1 + x*a2) approach
+ *
+ * Inputs:
+ * pan - pan value (-63 to + 63)
+ *
+ * Outputs:
+ * pGainLeft linear gain multiplier for left channel (15-bit fraction)
+ * pGainRight linear gain multiplier for left channel (15-bit fraction)
+ *
+ * Side Effects:
+ *----------------------------------------------------------------------------
+*/
+void EAS_CalcPanControl (EAS_INT pan, EAS_I16 *pGainLeft, EAS_I16 *pGainRight);
+
+#endif
+
diff --git a/arm-fm-22k/lib_src/eas_parser.h b/arm-fm-22k/lib_src/eas_parser.h
index 5512c82..96ec35b 100644
--- a/arm-fm-22k/lib_src/eas_parser.h
+++ b/arm-fm-22k/lib_src/eas_parser.h
@@ -1,15 +1,15 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_parser.h
- *
- * Contents and purpose:
- * Interface declarations for the generic parser interface
- *
- * This header only contains declarations that are specific
- * to this implementation.
- *
- * Copyright Sonic Network Inc. 2005
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_parser.h
+ *
+ * Contents and purpose:
+ * Interface declarations for the generic parser interface
+ *
+ * This header only contains declarations that are specific
+ * to this implementation.
+ *
+ * Copyright Sonic Network Inc. 2005
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -22,77 +22,77 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 767 $
- * $Date: 2007-07-19 13:47:31 -0700 (Thu, 19 Jul 2007) $
- *----------------------------------------------------------------------------
-*/
-
-#ifndef _EAS_PARSER_H
-#define _EAS_PARSER_H
-
-#include "eas_types.h"
-
-
-/* metadata callback */
-typedef struct s_metadata_cb_tag
-{
- EAS_METADATA_CBFUNC callback;
- char *buffer;
- EAS_VOID_PTR pUserData;
- EAS_I32 bufferSize;
-} S_METADATA_CB;
-
-/* generic parser interface */
-typedef struct
-{
- EAS_RESULT (* EAS_CONST pfCheckFileType)(struct s_eas_data_tag *pEASData, EAS_FILE_HANDLE fileHandle, EAS_VOID_PTR *ppHandle, EAS_I32 offset);
- EAS_RESULT (* EAS_CONST pfPrepare)(struct s_eas_data_tag *pEASData, EAS_VOID_PTR pInstData);
- EAS_RESULT (* EAS_CONST pfTime)(struct s_eas_data_tag *pEASData, EAS_VOID_PTR pInstData, EAS_U32 *pTime);
- EAS_RESULT (* EAS_CONST pfEvent)(struct s_eas_data_tag *pEASData, EAS_VOID_PTR pInstData, EAS_INT parseMode);
- EAS_RESULT (* EAS_CONST pfState)(struct s_eas_data_tag *pEASData, EAS_VOID_PTR pInstData, EAS_STATE *pState);
- EAS_RESULT (* EAS_CONST pfClose)(struct s_eas_data_tag *pEASData, EAS_VOID_PTR pInstData);
- EAS_RESULT (* EAS_CONST pfReset)(struct s_eas_data_tag *pEASData, EAS_VOID_PTR pInstData);
- EAS_RESULT (* EAS_CONST pfPause)(struct s_eas_data_tag *pEASData, EAS_VOID_PTR pInstData);
- EAS_RESULT (* EAS_CONST pfResume)(struct s_eas_data_tag *pEASData, EAS_VOID_PTR pInstData);
- EAS_RESULT (* EAS_CONST pfLocate)(struct s_eas_data_tag *pEASData, EAS_VOID_PTR pInstData, EAS_I32 time, EAS_BOOL *pParserLocate);
- EAS_RESULT (* EAS_CONST pfSetData)(struct s_eas_data_tag *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value);
- EAS_RESULT (* EAS_CONST pfGetData)(struct s_eas_data_tag *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue);
- EAS_RESULT (* EAS_CONST pfGetMetaData)(struct s_eas_data_tag *pEASData, EAS_VOID_PTR pInstData, EAS_I32 *pMediaLength);
-} S_FILE_PARSER_INTERFACE;
-
-typedef enum
-{
- eParserModePlay,
- eParserModeLocate,
- eParserModeMute,
- eParserModeMetaData
-} E_PARSE_MODE;
-
-typedef enum
-{
- PARSER_DATA_FILE_TYPE,
- PARSER_DATA_PLAYBACK_RATE,
- PARSER_DATA_TRANSPOSITION,
- PARSER_DATA_VOLUME,
- PARSER_DATA_SYNTH_HANDLE,
- PARSER_DATA_METADATA_CB,
- PARSER_DATA_DLS_COLLECTION,
- PARSER_DATA_EAS_LIBRARY,
- PARSER_DATA_POLYPHONY,
- PARSER_DATA_PRIORITY,
- PARSER_DATA_FORMAT,
- PARSER_DATA_MEDIA_LENGTH,
- PARSER_DATA_JET_CB,
- PARSER_DATA_MUTE_FLAGS,
- PARSER_DATA_SET_MUTE,
- PARSER_DATA_CLEAR_MUTE,
- PARSER_DATA_NOTE_COUNT,
- PARSER_DATA_MAX_PCM_STREAMS,
- PARSER_DATA_GAIN_OFFSET,
- PARSER_DATA_PLAY_MODE
-} E_PARSER_DATA;
-
-#endif /* #ifndef _EAS_PARSER_H */
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 767 $
+ * $Date: 2007-07-19 13:47:31 -0700 (Thu, 19 Jul 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+#ifndef _EAS_PARSER_H
+#define _EAS_PARSER_H
+
+#include "eas_types.h"
+
+
+/* metadata callback */
+typedef struct s_metadata_cb_tag
+{
+ EAS_METADATA_CBFUNC callback;
+ char *buffer;
+ EAS_VOID_PTR pUserData;
+ EAS_I32 bufferSize;
+} S_METADATA_CB;
+
+/* generic parser interface */
+typedef struct
+{
+ EAS_RESULT (* EAS_CONST pfCheckFileType)(struct s_eas_data_tag *pEASData, EAS_FILE_HANDLE fileHandle, EAS_VOID_PTR *ppHandle, EAS_I32 offset);
+ EAS_RESULT (* EAS_CONST pfPrepare)(struct s_eas_data_tag *pEASData, EAS_VOID_PTR pInstData);
+ EAS_RESULT (* EAS_CONST pfTime)(struct s_eas_data_tag *pEASData, EAS_VOID_PTR pInstData, EAS_U32 *pTime);
+ EAS_RESULT (* EAS_CONST pfEvent)(struct s_eas_data_tag *pEASData, EAS_VOID_PTR pInstData, EAS_INT parseMode);
+ EAS_RESULT (* EAS_CONST pfState)(struct s_eas_data_tag *pEASData, EAS_VOID_PTR pInstData, EAS_STATE *pState);
+ EAS_RESULT (* EAS_CONST pfClose)(struct s_eas_data_tag *pEASData, EAS_VOID_PTR pInstData);
+ EAS_RESULT (* EAS_CONST pfReset)(struct s_eas_data_tag *pEASData, EAS_VOID_PTR pInstData);
+ EAS_RESULT (* EAS_CONST pfPause)(struct s_eas_data_tag *pEASData, EAS_VOID_PTR pInstData);
+ EAS_RESULT (* EAS_CONST pfResume)(struct s_eas_data_tag *pEASData, EAS_VOID_PTR pInstData);
+ EAS_RESULT (* EAS_CONST pfLocate)(struct s_eas_data_tag *pEASData, EAS_VOID_PTR pInstData, EAS_I32 time, EAS_BOOL *pParserLocate);
+ EAS_RESULT (* EAS_CONST pfSetData)(struct s_eas_data_tag *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value);
+ EAS_RESULT (* EAS_CONST pfGetData)(struct s_eas_data_tag *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue);
+ EAS_RESULT (* EAS_CONST pfGetMetaData)(struct s_eas_data_tag *pEASData, EAS_VOID_PTR pInstData, EAS_I32 *pMediaLength);
+} S_FILE_PARSER_INTERFACE;
+
+typedef enum
+{
+ eParserModePlay,
+ eParserModeLocate,
+ eParserModeMute,
+ eParserModeMetaData
+} E_PARSE_MODE;
+
+typedef enum
+{
+ PARSER_DATA_FILE_TYPE,
+ PARSER_DATA_PLAYBACK_RATE,
+ PARSER_DATA_TRANSPOSITION,
+ PARSER_DATA_VOLUME,
+ PARSER_DATA_SYNTH_HANDLE,
+ PARSER_DATA_METADATA_CB,
+ PARSER_DATA_DLS_COLLECTION,
+ PARSER_DATA_EAS_LIBRARY,
+ PARSER_DATA_POLYPHONY,
+ PARSER_DATA_PRIORITY,
+ PARSER_DATA_FORMAT,
+ PARSER_DATA_MEDIA_LENGTH,
+ PARSER_DATA_JET_CB,
+ PARSER_DATA_MUTE_FLAGS,
+ PARSER_DATA_SET_MUTE,
+ PARSER_DATA_CLEAR_MUTE,
+ PARSER_DATA_NOTE_COUNT,
+ PARSER_DATA_MAX_PCM_STREAMS,
+ PARSER_DATA_GAIN_OFFSET,
+ PARSER_DATA_PLAY_MODE
+} E_PARSER_DATA;
+
+#endif /* #ifndef _EAS_PARSER_H */
diff --git a/arm-fm-22k/lib_src/eas_pcm.c b/arm-fm-22k/lib_src/eas_pcm.c
index 64b8f71..ff3f6f9 100644
--- a/arm-fm-22k/lib_src/eas_pcm.c
+++ b/arm-fm-22k/lib_src/eas_pcm.c
@@ -1,12 +1,12 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_pcm.c
- *
- * Contents and purpose:
- * Implements the PCM engine including ADPCM decode for SMAF and CMX audio playback.
- *
- * Copyright Sonic Network Inc. 2005
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_pcm.c
+ *
+ * Contents and purpose:
+ * Implements the PCM engine including ADPCM decode for SMAF and CMX audio playback.
+ *
+ * Copyright Sonic Network Inc. 2005
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,1464 +19,1464 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 849 $
- * $Date: 2007-08-28 08:59:11 -0700 (Tue, 28 Aug 2007) $
- *----------------------------------------------------------------------------
-*/
-
-#include "eas_data.h"
-#include "eas_report.h"
-#include "eas_host.h"
-#include "eas_config.h"
-#include "eas_parser.h"
-#include "eas_pcm.h"
-#include "eas_math.h"
-#include "eas_mixer.h"
-
-#define PCM_MIXER_GUARD_BITS (NUM_MIXER_GUARD_BITS + 1)
-
-/*----------------------------------------------------------------------------
- * Decoder interfaces
- *----------------------------------------------------------------------------
-*/
-
-static EAS_RESULT LinearPCMDecode (EAS_DATA_HANDLE pEASData, S_PCM_STATE *pState);
-static EAS_RESULT LinearPCMLocate (EAS_DATA_HANDLE pEASData, S_PCM_STATE *pState, EAS_I32 time);
-
-static const S_DECODER_INTERFACE PCMDecoder =
-{
- NULL,
- LinearPCMDecode,
- LinearPCMLocate,
-};
-
-/* SMAF ADPCM decoder */
-#ifdef _SMAF_PARSER
-extern S_DECODER_INTERFACE SmafDecoder;
-#define SMAF_DECODER &SmafDecoder
-extern S_DECODER_INTERFACE Smaf7BitDecoder;
-#define SMAF_7BIT_DECODER &Smaf7BitDecoder
-#else
-#define SMAF_DECODER NULL
-#define SMAF_7BIT_DECODER NULL
-#endif
-
-/* IMA ADPCM decoder */
-#ifdef _IMA_DECODER
-extern S_DECODER_INTERFACE IMADecoder;
-#define IMA_DECODER &IMADecoder
-#else
-#define IMA_DECODER NULL
-#endif
-
-static const S_DECODER_INTERFACE * const decoders[] =
-{
- &PCMDecoder,
- SMAF_DECODER,
- IMA_DECODER,
- SMAF_7BIT_DECODER
-};
-
-/*----------------------------------------------------------------------------
- * Sample rate conversion
- *----------------------------------------------------------------------------
-*/
-
-#define SRC_RATE_MULTIPLER (0x40000000 / _OUTPUT_SAMPLE_RATE)
-
-#ifdef _LOOKUP_SAMPLE_RATE
-static const EAS_U32 srcConvRate[][2] =
-{
- 4000L, (4000L << 15) / _OUTPUT_SAMPLE_RATE,
- 8000L, (8000L << 15) / _OUTPUT_SAMPLE_RATE,
- 11025L, (11025L << 15) / _OUTPUT_SAMPLE_RATE,
- 12000L, (12000L << 15) / _OUTPUT_SAMPLE_RATE,
- 16000L, (16000L << 15) / _OUTPUT_SAMPLE_RATE,
- 22050L, (22050L << 15) / _OUTPUT_SAMPLE_RATE,
- 24000L, (24000L << 15) / _OUTPUT_SAMPLE_RATE,
- 32000L, (32000L << 15) / _OUTPUT_SAMPLE_RATE
-};
-static EAS_U32 CalcBaseFreq (EAS_U32 sampleRate);
-#define SRC_CONV_RATE_ENTRIES (sizeof(srcConvRate)/sizeof(EAS_U32)/2)
-#endif
-
-
-/* interface prototypes */
-static EAS_RESULT RenderPCMStream (S_EAS_DATA *pEASData, S_PCM_STATE *pState, EAS_I32 numSamples);
-
-
-/* local prototypes */
-static S_PCM_STATE *FindSlot (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle, EAS_PCM_CALLBACK pCallbackFunc, EAS_VOID_PTR cbInstData);
-static EAS_RESULT InitPCMStream (S_EAS_DATA *pEASData, S_PCM_STATE *pState);
-
-/*----------------------------------------------------------------------------
- * EAS_PEInit()
- *----------------------------------------------------------------------------
- * Purpose:
- * Initializes the PCM engine
- *
- * Inputs:
- *
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT EAS_PEInit (S_EAS_DATA *pEASData)
-{
- S_PCM_STATE *pState;
- EAS_INT i;
-
- /* check for static memory allocation */
- if (pEASData->staticMemoryModel)
- pEASData->pPCMStreams = EAS_CMEnumData(EAS_CM_PCM_DATA);
- /* allocate dynamic memory */
- else
- pEASData->pPCMStreams = EAS_HWMalloc(pEASData->hwInstData, sizeof(S_PCM_STATE) * MAX_PCM_STREAMS);
-
- if (!pEASData->pPCMStreams)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_FATAL, "Failed to allocate memory for PCM streams\n"); */ }
- return EAS_ERROR_MALLOC_FAILED;
- }
-
- //zero the memory to insure complete initialization
- EAS_HWMemSet((void *)(pEASData->pPCMStreams),0, sizeof(S_PCM_STATE) * MAX_PCM_STREAMS);
-
- /* initialize the state data */
- for (i = 0, pState = pEASData->pPCMStreams; i < MAX_PCM_STREAMS; i++, pState++)
- pState->fileHandle = NULL;
-
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * EAS_PEShutdown()
- *----------------------------------------------------------------------------
- * Purpose:
- * Shuts down the PCM engine
- *
- * Inputs:
- *
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT EAS_PEShutdown (S_EAS_DATA *pEASData)
-{
-
- /* free any dynamic memory */
- if (!pEASData->staticMemoryModel)
- {
- if (pEASData->pPCMStreams)
- {
- EAS_HWFree(pEASData->hwInstData, pEASData->pPCMStreams);
- pEASData->pPCMStreams = NULL;
- }
- }
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * EAS_PERender()
- *----------------------------------------------------------------------------
- * Purpose:
- * Render a buffer of PCM audio
- *
- * Inputs:
- *
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT EAS_PERender (S_EAS_DATA* pEASData, EAS_I32 numSamples)
-{
- S_PCM_STATE *pState;
- EAS_RESULT result;
- EAS_INT i;
-
- /* render all the active streams */
- for (i = 0, pState = pEASData->pPCMStreams; i < MAX_PCM_STREAMS; i++, pState++)
- {
- if ((pState->fileHandle) && (pState->state != EAS_STATE_STOPPED) && (pState->state != EAS_STATE_PAUSED))
- if ((result = RenderPCMStream(pEASData, pState, numSamples)) != EAS_SUCCESS)
- return result;
- }
- return EAS_SUCCESS;
-}
-
-
-/*----------------------------------------------------------------------------
- * EAS_PEState()
- *----------------------------------------------------------------------------
- * Purpose:
- * Returns the current state of the stream
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- * pState - pointer to variable to store state
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- * Notes:
- * This interface is also exposed in the internal library for use by the other modules.
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, pEASData) reserved for future use */
-EAS_RESULT EAS_PEState (S_EAS_DATA *pEASData, EAS_PCM_HANDLE pInstData, EAS_STATE *pState)
-{
- /* return current state */
- *pState = pInstData->state;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * EAS_PEClose()
- *----------------------------------------------------------------------------
- * Purpose:
- * Close the file and clean up
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT EAS_PEClose (S_EAS_DATA *pEASData, EAS_PCM_HANDLE pState)
-{
- EAS_RESULT result;
-
- if ((result = EAS_HWCloseFile(pEASData->hwInstData, pState->fileHandle)) != EAS_SUCCESS)
- return result;
-
- pState->fileHandle = NULL;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * PCM_Reset()
- *----------------------------------------------------------------------------
- * Purpose:
- * Reset the sequencer. Used for locating backwards in the file.
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT EAS_PEReset (S_EAS_DATA *pEASData, EAS_PCM_HANDLE pState)
-{
- EAS_RESULT result;
-
- /* reset file position to first byte of data in the stream */
- if ((result = EAS_HWFileSeek(pEASData->hwInstData, pState->fileHandle, pState->startPos)) != EAS_SUCCESS)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Error %d seeking to start of PCM file\n", result); */ }
- return result;
- }
-
- /* re-initialize stream */
- return InitPCMStream(pEASData, pState);
-}
-
-/*----------------------------------------------------------------------------
- * EAS_PEOpenStream()
- *----------------------------------------------------------------------------
- * Purpose:
- * Starts up a PCM playback
- *
- * Inputs:
- *
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT EAS_PEOpenStream (S_EAS_DATA *pEASData, S_PCM_OPEN_PARAMS *pParams, EAS_PCM_HANDLE *pHandle)
-{
- EAS_RESULT result;
- S_PCM_STATE *pState;
- EAS_I32 filePos;
-
- /* make sure we support this decoder */
- if (pParams->decoder >= NUM_DECODER_MODULES)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Decoder selector out of range\n"); */ }
- return EAS_ERROR_PARAMETER_RANGE;
- }
- if (decoders[pParams->decoder] == NULL)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Decoder module not available\n"); */ }
- return EAS_ERROR_FEATURE_NOT_AVAILABLE;
- }
-
- /* find a slot for the new stream */
- if ((pState = FindSlot(pEASData, pParams->fileHandle, pParams->pCallbackFunc, pParams->cbInstData)) == NULL)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Unable to open ADPCM stream, too many streams open\n"); */ }
- return EAS_ERROR_MAX_PCM_STREAMS;
- }
-
- /* get the current file position */
- if ((result = EAS_HWFilePos(pEASData->hwInstData, pState->fileHandle, &filePos)) != EAS_SUCCESS)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "EAS_HWFilePos returned %ld\n",result); */ }
- pState->fileHandle = NULL;
- return result;
- }
-
- pState->pDecoder = decoders[pParams->decoder];
- pState->startPos = filePos;
- pState->bytesLeftLoop = pState->byteCount = pParams->size;
- pState->loopStart = pParams->loopStart;
- pState->samplesTilLoop = (EAS_I32) pState->loopStart;
- pState->loopSamples = pParams->loopSamples;
- pState->samplesInLoop = 0;
- pState->blockSize = (EAS_U16) pParams->blockSize;
- pState->flags = pParams->flags;
- pState->envData = pParams->envData;
- pState->volume = pParams->volume;
- pState->sampleRate = (EAS_U16) pParams->sampleRate;
-
- /* set the base frequency */
- pState->basefreq = (SRC_RATE_MULTIPLER * (EAS_U32) pParams->sampleRate) >> 15;
-
- /* calculate shift for frequencies > 1.0 */
- pState->rateShift = 0;
- while (pState->basefreq > 32767)
- {
- pState->basefreq = pState->basefreq >> 1;
- pState->rateShift++;
- }
-
- /* initialize */
- if ((result = InitPCMStream(pEASData, pState)) != EAS_SUCCESS)
- return result;
-
- *pHandle = pState;
-
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "EAS_PEOpenStream: StartPos=%d, byteCount = %d, loopSamples=%d\n",
- pState->startPos, pState->byteCount, pState->loopSamples); */ }
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * EAS_PEContinueStream()
- *----------------------------------------------------------------------------
- * Purpose:
- * Continues a PCM stream
- *
- * Inputs:
- *
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -e{715} reserved for future use */
-EAS_RESULT EAS_PEContinueStream (S_EAS_DATA *pEASData, EAS_PCM_HANDLE pState, EAS_I32 size)
-{
-
- /* add new samples to count */
- pState->bytesLeft += size;
- if (pState->bytesLeft > 0)
- pState->flags &= ~PCM_FLAGS_EMPTY;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * EAS_PEGetFileHandle()
- *----------------------------------------------------------------------------
- * Purpose:
- * Returns the file handle of a stream
- *
- * Inputs:
- *
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, pEASData) reserved for future use */
-EAS_RESULT EAS_PEGetFileHandle (S_EAS_DATA *pEASData, EAS_PCM_HANDLE pState, EAS_FILE_HANDLE *pFileHandle)
-{
- *pFileHandle = pState->fileHandle;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * EAS_PEUpdateParams()
- *----------------------------------------------------------------------------
- * Purpose:
- * Update the pitch and volume parameters for a PCM stream
- *
- * Inputs:
- * pEASData - pointer to EAS library instance data
- * handle - pointer to S_PCM_STATE for this stream
- * gainLeft - linear gain multipler in 1.15 fraction format
- * gainRight - linear gain multipler in 1.15 fraction format
- * pitch - pitch shift in cents
- * initial - initial settings, set current gain
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- * Notes
- * In mono mode, leftGain controls the output gain and rightGain is ignored
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, pEASData) reserved for future use */
-/*lint -esym(715, gainRight) used only in 2-channel version */
-EAS_RESULT EAS_PEUpdateParams (S_EAS_DATA* pEASData, EAS_PCM_HANDLE pState, EAS_I16 pitch, EAS_I16 gainLeft, EAS_I16 gainRight)
-{
-
- pState->gainLeft = gainLeft;
-
-#if (NUM_OUTPUT_CHANNELS == 2)
- pState->gainRight = gainRight;
-#endif
-
- pState->pitch = pitch;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * EAS_PELocate()
- *----------------------------------------------------------------------------
- * Purpose:
- * This function seeks to the requested place in the file. Accuracy
- * is dependent on the sample rate and block size.
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * pState - stream handle
- * time - media time in milliseconds
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT EAS_PELocate (S_EAS_DATA *pEASData, EAS_PCM_HANDLE pState, EAS_I32 time)
-{
- if (pState->pDecoder->pfLocate == NULL)
- return EAS_ERROR_FEATURE_NOT_AVAILABLE;
-
- return pState->pDecoder->pfLocate(pEASData, pState, time);
-}
-
-/*----------------------------------------------------------------------------
- * EAS_PEUpdateVolume()
- *----------------------------------------------------------------------------
- * Purpose:
- * Update the volume parameters for a PCM stream
- *
- * Inputs:
- * pEASData - pointer to EAS library instance data
- * handle - pointer to S_PCM_STATE for this stream
- * gainLeft - linear gain multipler in 1.15 fraction format
- * gainRight - linear gain multipler in 1.15 fraction format
- * initial - initial settings, set current gain
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- * Notes
- * In mono mode, leftGain controls the output gain and rightGain is ignored
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, pEASData) reserved for future use */
-EAS_RESULT EAS_PEUpdateVolume (S_EAS_DATA* pEASData, EAS_PCM_HANDLE pState, EAS_I16 volume)
-{
- pState->volume = volume;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * EAS_PEUpdatePitch()
- *----------------------------------------------------------------------------
- * Purpose:
- * Update the pitch parameter for a PCM stream
- *
- * Inputs:
- * pEASData - pointer to EAS library instance data
- * pState - pointer to S_PCM_STATE for this stream
- * pitch - new pitch value in pitch cents
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, pEASData) reserved for future use */
-EAS_RESULT EAS_PEUpdatePitch (S_EAS_DATA* pEASData, EAS_PCM_HANDLE pState, EAS_I16 pitch)
-{
- pState->pitch = pitch;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * EAS_PEPause()
- *----------------------------------------------------------------------------
- * Purpose:
- * Mute and stop rendering a PCM stream. Sets the gain target to zero and stops the playback
- * at the end of the next audio frame.
- *
- * Inputs:
- * pEASData - pointer to EAS library instance data
- * handle - pointer to S_PCM_STATE for this stream
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, pEASData) reserved for future use */
-EAS_RESULT EAS_PEPause (S_EAS_DATA *pEASData, EAS_PCM_HANDLE pState)
-{
- /* set state to stopping */
- pState->state = EAS_STATE_PAUSING;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * EAS_PEResume()
- *----------------------------------------------------------------------------
- * Purpose:
- * Resume rendering a PCM stream. Sets the gain target back to its
- * previous setting and restarts playback at the end of the next audio
- * frame.
- *
- * Inputs:
- * pEASData - pointer to EAS library instance data
- * handle - pointer to S_PCM_STATE for this stream
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, pEASData) reserved for future use */
-EAS_RESULT EAS_PEResume (S_EAS_DATA *pEASData, EAS_PCM_HANDLE pState)
-{
- /* set state to stopping */
- pState->state = EAS_STATE_PLAY;
- return EAS_SUCCESS;
-}
-
-EAS_U32 getDecayScale(EAS_U32 index)
-{
- EAS_U32 utemp;
-
- //envelope decay segment
- switch (index)
- {
- case 0: //no decay
- utemp = 512;//32768;
- break;
- case 1: //.0156 dB per update
- utemp = 511;//32709;
- break;
- case 2: //.03125
- utemp = 510;//32649;
- break;
- case 3: //.0625
- utemp = 508;//32532;
- break;
- case 4: //.125
- utemp = 505;//32298;
- break;
- case 5: //.25
- utemp = 497;//31835;
- break;
- case 6: //.5
- utemp = 483;//30929;
- break;
- case 7: //1.0
- utemp = 456;//29193;
- break;
- case 8: //2.0
- utemp = 406;//26008;
- break;
- case 9: //4.0
- utemp = 323;//20642;
- break;
- case 10: //8.0
- utemp = 203;//13004;
- break;
- case 11: //16.0
- utemp = 81;//5160;
- break;
- case 12: //32.0
- utemp = 13;//813;
- break;
- case 13: //64.0
- utemp = 0;//20;
- break;
- case 14: //128.0
- utemp = 0;
- break;
- case 15: //256.0
- default:
- utemp = 0;
- break;
- }
- //printf("getdecayscale returned %d\n",utemp);
- return utemp;
-}
-
-EAS_U32 getAttackIncrement(EAS_U32 index)
-{
- EAS_U32 utemp;
-
- //envelope decay segment
- switch (index)
- {
- case 0:
- utemp = 32;
- break;
- case 1:
- utemp = 64;
- break;
- case 2:
- utemp = 128;
- break;
- case 3:
- utemp = 256;
- break;
- case 4:
- utemp = 512;
- break;
- case 5:
- utemp = 1024;
- break;
- case 6:
- utemp = 2048;
- break;
- case 7:
- utemp = 4096;
- break;
- case 8:
- utemp = 8192;
- break;
- case 9:
- utemp = 16384;
- break;
- case 10:
- utemp = 32768;
- break;
- case 11:
- utemp = 65536;
- break;
- case 12:
- utemp = 65536;
- break;
- case 13:
- utemp = 65536;
- break;
- case 14:
- utemp = 65535;
- break;
- case 15:
- default:
- utemp = 0;
- break;
- }
- //printf("getattackincrement returned %d\n",utemp);
- return utemp;
-}
-
-/*----------------------------------------------------------------------------
- * EAS_PERelease()
- *----------------------------------------------------------------------------
- * Purpose:
- * Put the PCM stream envelope into release.
- *
- * Inputs:
- * pEASData - pointer to EAS library instance data
- * handle - pointer to S_PCM_STATE for this stream
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, pEASData) reserved for future use */
-EAS_RESULT EAS_PERelease (S_EAS_DATA *pEASData, EAS_PCM_HANDLE pState)
-{
- EAS_U32 utemp;
-
- //printf("handling note-off part of envelope\n");
- /*if the note is not ignore release or sustained*/
- if (((pState->envData >> 24) & 0x0F)==0)
- {
- /* set envelope state to release */
- pState->envState = PCM_ENV_RELEASE;
- utemp = ((pState->envData >> 20) & 0x0F);
- pState->envScale = getDecayScale(utemp); //getReleaseScale(utemp);
- }
- else
- {
- /*else change envelope state to sustain */
- pState->envState = PCM_ENV_SUSTAIN;
- utemp = ((pState->envData >> 28) & 0x0F);
- pState->envScale = getDecayScale(utemp); //getSustainScale(utemp);
- }
- //since we are in release, don't let anything hang around too long
- //printf("checking env scale, val = %d\n",((S_PCM_STATE*) handle)->envScale);
- if (pState->envScale > 505)
- pState->envScale = 505;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * FindSlot()
- *----------------------------------------------------------------------------
- * Purpose:
- * Locates an empty stream slot and assigns the file handle
- *
- * Inputs:
- * pEASData - pointer to EAS library instance data
- * fileHandle - file handle
- * pCallbackFunc - function to be called back upon EAS_STATE_STOPPED
- *
- * Outputs:
- * returns handle to slot or NULL if all slots are used
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static S_PCM_STATE *FindSlot (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle, EAS_PCM_CALLBACK pCallbackFunc, EAS_VOID_PTR cbInstData)
-{
- EAS_INT i;
- S_PCM_STATE *pState;
-
-#ifndef NO_PCM_STEAL
- S_PCM_STATE *foundState = NULL;
- EAS_INT count = 0;
- EAS_U32 startOrder = 0xFFFFFFFF;
- S_PCM_STATE *stealState = NULL;
- EAS_U32 youngest = 0;
-
- /* find an empty slot, count total in use, and find oldest in use (lowest start order) */
- for (i = 0, pState = pEASData->pPCMStreams; i < MAX_PCM_STREAMS; i++, pState++)
- {
- /* if this one is available */
- if (pState->fileHandle == NULL)
- {
- foundState = pState;
- }
- /* else this one is in use, so see if it is the oldest, and count total in use */
- /* also find youngest */
- else
- {
- /*one more voice in use*/
- count++;
- /* is this the oldest? (lowest start order) */
- if ((pState->state != EAS_STATE_STOPPING) && (pState->startOrder < startOrder))
- {
- /* remember this one */
- stealState = pState;
- /* remember the oldest so far */
- startOrder = pState->startOrder;
- }
- /* is this the youngest? (highest start order) */
- if (pState->startOrder >= youngest)
- {
- youngest = pState->startOrder;
- }
- }
- }
-
- /* if there are too many voices active, stop the oldest one */
- if (count > PCM_STREAM_THRESHOLD)
- {
- //printf("stealing!!!\n");
- /* make sure we got one, although we should always have one at this point */
- if (stealState != NULL)
- {
- //flag this as stopping, so it will get shut off
- stealState->state = EAS_STATE_STOPPING;
- }
- }
-
- /* if there are no available open streams (we won't likely see this, due to stealing) */
- if (foundState == NULL)
- return NULL;
-
- /* save info */
- foundState->startOrder = youngest + 1;
- foundState->fileHandle = fileHandle;
- foundState->pCallback = pCallbackFunc;
- foundState->cbInstData = cbInstData;
- return foundState;
-#else
- /* find an empty slot*/
- for (i = 0; i < MAX_PCM_STREAMS; i++)
- {
- pState = &pEASData->pPCMStreams[i];
- if (pState->fileHandle != NULL)
- continue;
-
- pState->fileHandle = fileHandle;
- pState->pCallback = pCallbackFunc;
- pState->cbInstData = cbInstData;
- return pState;
- }
- return NULL;
-#endif
-}
-
-#ifdef _LOOKUP_SAMPLE_RATE
-/*----------------------------------------------------------------------------
- * CalcBaseFreq()
- *----------------------------------------------------------------------------
- * Purpose:
- * Calculates the fractional phase increment for the sample rate converter
- *
- * Inputs:
- * sampleRate - sample rate in samples/sec
- *
- * Outputs:
- * Returns fractional sample rate with a 15-bit fraction
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_U32 CalcBaseFreq (EAS_U32 sampleRate)
-{
- EAS_INT i;
-
- /* look up the conversion rate */
- for (i = 0; i < (EAS_INT)(SRC_CONV_RATE_ENTRIES); i ++)
- {
- if (srcConvRate[i][0] == sampleRate)
- return srcConvRate[i][1];
- }
-
- /* if not found in table, do it the long way */
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Sample rate %u not in table, calculating by division\n", sampleRate); */ }
-
- return (SRC_RATE_MULTIPLER * (EAS_U32) sampleRate) >> 15;
-}
-#endif
-
-/*----------------------------------------------------------------------------
- * InitPCMStream()
- *----------------------------------------------------------------------------
- * Purpose:
- * Start an ADPCM stream playback. Decodes the header, preps the engine.
- *
- * Inputs:
- *
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT InitPCMStream (S_EAS_DATA *pEASData, S_PCM_STATE *pState)
-{
-
- /* initialize the data structure */
- pState->bytesLeft = pState->byteCount;
- pState->phase = 0;
- pState->srcByte = 0;
- pState->decoderL.acc = 0;
- pState->decoderL.output = 0;
- pState->decoderL.x0 = pState->decoderL.x1 = 0;
- pState->decoderL.step = 0;
- pState->decoderR.acc = 0;
- pState->decoderR.output = 0;
- pState->decoderR.x0 = pState->decoderR.x1 = 0;
- pState->decoderR.step = 0;
- pState->hiNibble = EAS_FALSE;
- pState->pitch = 0;
- pState->blockCount = 0;
- pState->gainLeft = PCM_DEFAULT_GAIN_SETTING;
-// pState->currentGainLeft = PCM_DEFAULT_GAIN_SETTING;
- pState->envValue = 0;
- pState->envState = PCM_ENV_START;
-
-#if (NUM_OUTPUT_CHANNELS == 2)
- pState->gainRight = PCM_DEFAULT_GAIN_SETTING;
-// pState->currentGainRight = PCM_DEFAULT_GAIN_SETTING;
-#endif
- pState->state = EAS_STATE_READY;
-
- /* initialize the decoder */
- if (pState->pDecoder->pfInit)
- return (*pState->pDecoder->pfInit)(pEASData, pState);
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * RenderPCMStream()
- *----------------------------------------------------------------------------
- * Purpose:
- * Decodes a buffer of ADPCM data.
- *
- * Inputs:
- *
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT RenderPCMStream (S_EAS_DATA *pEASData, S_PCM_STATE *pState, EAS_I32 numSamples)
-{
- EAS_RESULT result;
- EAS_U32 phaseInc;
- EAS_I32 gainLeft, gainIncLeft;
- EAS_I32 *pOut;
- EAS_I32 temp;
- EAS_U32 utemp;
-
-#if (NUM_OUTPUT_CHANNELS == 2)
- EAS_I32 gainRight, gainIncRight;
-#endif
-
-#if 0
- printf("env data: AR = %d, DR = %d, SL = %d, SR = %d, RR = %d\n",
- ((pState->envData >> 12) & 0x0F),
- ((pState->envData >> 16) & 0x0F),
- ((pState->envData >> 8) & 0x0F),
- ((pState->envData >> 28) & 0x0F),
- ((pState->envData >> 20) & 0x0F));
-#endif
-
- if (pState->envState == PCM_ENV_START)
- {
- //printf("env start\n");
- utemp = ((pState->envData >> 12) & 0x0F);
- //if fastest rate, attack is already completed
- //do the same for slowest rate, since that allows zero to be passed for default envelope
- if (utemp == 0x0F || utemp == 0x00)
- {
- //start envelope at full
- pState->envValue = (32768<<7);
- //jump right into decay
- utemp = ((pState->envData >> 16) & 0x0F);
- pState->envScale = getDecayScale(utemp);
- pState->envState = PCM_ENV_DECAY;
- pState->currentGainLeft = (EAS_I16) FMUL_15x15(pState->gainLeft, pState->volume);
- pState->currentGainRight = (EAS_I16) FMUL_15x15(pState->gainRight, pState->volume);
- }
- //else attack has a ramp
- else
- {
- //start the envelope very low
- pState->envValue = (2<<7);
- pState->currentGainLeft = 0;
- pState->currentGainRight = 0;
- //get envelope attack scaling value
- pState->envScale = getAttackIncrement(utemp);
- //go to attack state
- pState->envState = PCM_ENV_ATTACK;
- }
- }
- if (pState->envState == PCM_ENV_ATTACK)
- {
- //printf("env attack, env value = %d, env scale = %d\n",pState->envValue>>7,pState->envScale);
- //update envelope value
- pState->envValue = pState->envValue + (pState->envScale << 7);
- //check envelope level and update state if needed
- if (pState->envValue >= (32768<<7))
- {
- pState->envValue = (32768<<7);
- utemp = ((pState->envData >> 16) & 0x0F);
- pState->envScale = getDecayScale(utemp);
- pState->envState = PCM_ENV_DECAY;
- }
- }
- else if (pState->envState == PCM_ENV_DECAY)
- {
- //printf("env decay, env value = %d, env scale = %d\n",pState->envValue>>7,pState->envScale);
- //update envelope value
- pState->envValue = (pState->envValue * pState->envScale)>>9;
- //check envelope level against sustain level and update state if needed
- utemp = ((pState->envData >> 8) & 0x0F);
- if (utemp == (EAS_U32)0x0F)
- utemp = (2<<7);
- else
- {
- utemp = ((32769<<7) >> (utemp>>1));
- }
- if (pState->envValue <= utemp)
- {
- utemp = ((pState->envData >> 28) & 0x0F);
- pState->envScale = getDecayScale(utemp); //getSustainScale(utemp);
- pState->envState = PCM_ENV_SUSTAIN;
- }
- }
- else if (pState->envState == PCM_ENV_SUSTAIN)
- {
- //printf("env sustain, env value = %d, env scale = %d\n",pState->envValue>>7,pState->envScale);
- //update envelope value
- pState->envValue = (pState->envValue * pState->envScale)>>9;
- //check envelope level against bottom level and update state if needed
- if (pState->envValue <= (2<<7))
- {
- //no more decay
- pState->envScale = 512;
- pState->envState = PCM_ENV_END;
- }
- }
- else if (pState->envState == PCM_ENV_RELEASE)
- {
- //printf("env release, env value = %d, env scale = %d\n",pState->envValue>>7,pState->envScale);
- //update envelope value
- pState->envValue = (pState->envValue * pState->envScale)>>9;
- //check envelope level against bottom level and update state if needed
- if (pState->envValue <= (2<<7))
- {
- //no more decay
- pState->envScale = 512;
- pState->envState = PCM_ENV_END;
- }
- }
- else if (pState->envState == PCM_ENV_END)
- {
- //printf("env end\n");
- /* set state to stopping, already ramped down */
- pState->state = EAS_STATE_STOPPING;
- }
-
- //pState->gainLeft = (EAS_U16)((pState->gainLeft * (pState->envValue>>7))>>15);
- //pState->gainRight = (EAS_U16)((pState->gainRight * (pState->envValue>>7))>>15);
-
- /* gain to 32-bits to increase resolution on anti-zipper filter */
- /*lint -e{703} use shift for performance */
- gainLeft = (EAS_I32) pState->currentGainLeft << SYNTH_UPDATE_PERIOD_IN_BITS;
-#if (NUM_OUTPUT_CHANNELS == 2)
- /*lint -e{703} use shift for performance */
- gainRight = (EAS_I32) pState->currentGainRight << SYNTH_UPDATE_PERIOD_IN_BITS;
-#endif
-
- /* calculate a new gain increment, gain target is zero if pausing */
- if ((pState->state == EAS_STATE_PAUSING) || (pState->state == EAS_STATE_PAUSED))
- {
- gainIncLeft = -pState->currentGainLeft;
-#if (NUM_OUTPUT_CHANNELS == 2)
- gainIncRight= -pState->currentGainRight;
-#endif
- }
- else
- {
- EAS_I32 gain = FMUL_15x15(pState->envValue >> 7, pState->volume);
- gainIncLeft = FMUL_15x15(pState->gainLeft, gain) - pState->currentGainLeft;
-#if (NUM_OUTPUT_CHANNELS == 2)
- gainIncRight = FMUL_15x15(pState->gainRight, gain) - pState->currentGainRight;
-#endif
- }
-
- /* calculate phase increment */
- phaseInc = pState->basefreq;
-
- /* convert pitch cents to linear multiplier */
- if (pState->pitch)
- {
- temp = EAS_Calculate2toX(pState->pitch);
- phaseInc = FMUL_15x15(phaseInc, temp);
- }
- phaseInc = phaseInc << pState->rateShift;
-
- /* pointer to mix buffer */
- pOut = pEASData->pMixBuffer;
-
- /* render a buffer of samples */
- while (numSamples--)
- {
-
- /* interpolate an output sample */
- pState->decoderL.output = pState->decoderL.x0 + FMUL_15x15((pState->decoderL.x1 - pState->decoderL.x0), pState->phase & PHASE_FRAC_MASK);
-
- /* stereo output */
-#if (NUM_OUTPUT_CHANNELS == 2)
-
- /* stereo stream? */
- if (pState->flags & PCM_FLAGS_STEREO)
- pState->decoderR.output = pState->decoderR.x0 + FMUL_15x15((pState->decoderR.x1 - pState->decoderR.x0), pState->phase & PHASE_FRAC_MASK);
-
- /* gain scale and mix */
- /*lint -e{704} use shift instead of division */
- *pOut++ += (pState->decoderL.output * (gainLeft >> SYNTH_UPDATE_PERIOD_IN_BITS)) >> PCM_MIXER_GUARD_BITS;
- gainLeft += gainIncLeft;
-
- /*lint -e{704} use shift instead of division */
- if (pState->flags & PCM_FLAGS_STEREO)
- *pOut++ += (pState->decoderR.output * (gainRight >> SYNTH_UPDATE_PERIOD_IN_BITS)) >> PCM_MIXER_GUARD_BITS;
- else
- *pOut++ += (pState->decoderL.output * (gainRight >> SYNTH_UPDATE_PERIOD_IN_BITS)) >> PCM_MIXER_GUARD_BITS;
-
- gainRight += gainIncRight;
-
- /* mono output */
-#else
- /* if stereo stream, decode right channel and mix to mono */
- if (pState->flags & PCM_FLAGS_STEREO)
- {
- pState->decoderR.output= pState->decoderR.x0 + FMUL_15x15((pState->decoderR.x1 - pState->decoderR.x0), pState->phase & PHASE_FRAC_MASK);
-
- /* for mono, sum stereo ADPCM to mono */
- /*lint -e{704} use shift instead of division */
- *pOut++ += ((pState->decoderL.output + pState->decoderR.output) * (gainLeft >> SYNTH_UPDATE_PERIOD_IN_BITS)) >> PCM_MIXER_GUARD_BITS;
- }
- else
- /*lint -e{704} use shift instead of division */
- *pOut++ += (pState->decoderL.output * (gainLeft >> SYNTH_UPDATE_PERIOD_IN_BITS)) >> PCM_MIXER_GUARD_BITS;
-
- gainLeft += gainIncLeft;
-#endif
-
- /* advance phase accumulator */
- pState->phase += phaseInc;
-
- /* if integer part of phase accumulator is non-zero, advance to next sample */
- while (pState->phase & ~PHASE_FRAC_MASK)
- {
- pState->decoderL.x0 = pState->decoderL.x1;
- pState->decoderR.x0 = pState->decoderR.x1;
-
- /* give the source a chance to continue the stream */
- if (!pState->bytesLeft && pState->pCallback && ((pState->flags & PCM_FLAGS_EMPTY) == 0))
- {
- pState->flags |= PCM_FLAGS_EMPTY;
- (*pState->pCallback)(pEASData, pState->cbInstData, pState, EAS_STATE_EMPTY);
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "RenderPCMStream: After empty callback, bytesLeft = %d\n", pState->bytesLeft); */ }
- }
-
- /* decode the next sample */
- if ((result = (*pState->pDecoder->pfDecodeSample)(pEASData, pState)) != EAS_SUCCESS)
- return result;
-
- /* adjust phase by one sample */
- pState->phase -= (1L << NUM_PHASE_FRAC_BITS);
- }
-
- }
-
- /* save new gain */
- /*lint -e{704} use shift instead of division */
- pState->currentGainLeft = (EAS_I16) (gainLeft >> SYNTH_UPDATE_PERIOD_IN_BITS);
-
-#if (NUM_OUTPUT_CHANNELS == 2)
- /*lint -e{704} use shift instead of division */
- pState->currentGainRight = (EAS_I16) (gainRight >> SYNTH_UPDATE_PERIOD_IN_BITS);
-#endif
-
- /* if pausing, set new state and notify */
- if (pState->state == EAS_STATE_PAUSING)
- {
- pState->state = EAS_STATE_PAUSED;
- if (pState->pCallback)
- (*pState->pCallback)(pEASData, pState->cbInstData, pState, pState->state);
- }
-
- /* if out of data, set stopped state and notify */
- if (pState->bytesLeft == 0 || pState->state == EAS_STATE_STOPPING)
- {
- pState->state = EAS_STATE_STOPPED;
-
- /* do callback unless the file has already been closed */
- if (pState->pCallback && pState->fileHandle)
- (*pState->pCallback)(pEASData, pState->cbInstData, pState, pState->state);
- }
-
- if (pState->state == EAS_STATE_READY)
- pState->state = EAS_STATE_PLAY;
-
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * LinearPCMDecode()
- *----------------------------------------------------------------------------
- * Purpose:
- * Decodes a PCM sample
- *
- * Inputs:
- *
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT LinearPCMDecode (EAS_DATA_HANDLE pEASData, S_PCM_STATE *pState)
-{
- EAS_RESULT result;
- EAS_HW_DATA_HANDLE hwInstData;
-
- hwInstData = ((S_EAS_DATA*) pEASData)->hwInstData;
-
- /* if out of data, check for loop */
- if ((pState->bytesLeft == 0) && (pState->loopSamples != 0))
- {
- if ((result = EAS_HWFileSeek(pEASData->hwInstData, pState->fileHandle, (EAS_I32) (pState->startPos + pState->loopLocation))) != EAS_SUCCESS)
- return result;
- pState->bytesLeft = pState->byteCount = (EAS_I32) pState->bytesLeftLoop;
- pState->flags &= ~PCM_FLAGS_EMPTY;
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "LinearPCMDecode: Rewind file to %d, bytesLeft = %d\n", pState->startPos, pState->bytesLeft); */ }
- }
-
- if (pState->bytesLeft)
- {
-
- /* check format byte for 8-bit samples */
- if (pState->flags & PCM_FLAGS_8_BIT)
- {
- /* fetch left or mono sample */
- if ((result = EAS_HWGetByte(hwInstData, pState->fileHandle, &pState->srcByte)) != EAS_SUCCESS)
- return result;
-
- /* if unsigned */
- if (pState->flags & PCM_FLAGS_UNSIGNED)
- {
- /*lint -e{734} converting unsigned 8-bit to signed 16-bit */
- pState->decoderL.x1 = (EAS_PCM)(((EAS_PCM) pState->srcByte << 8) ^ 0x8000);
- }
- else
- {
- /*lint -e{734} converting signed 8-bit to signed 16-bit */
- pState->decoderL.x1 = (EAS_PCM)((EAS_PCM) pState->srcByte << 8);
- }
- pState->bytesLeft--;
-
- /* fetch right sample */
- if(pState->flags & PCM_FLAGS_STEREO)
- {
- if ((result = EAS_HWGetByte(hwInstData, pState->fileHandle, &pState->srcByte)) != EAS_SUCCESS)
- return result;
-
- /* if unsigned */
- if (pState->flags & PCM_FLAGS_UNSIGNED)
- {
- /*lint -e{734} converting unsigned 8-bit to signed 16-bit */
- pState->decoderR.x1 = (EAS_PCM)(((EAS_PCM) pState->srcByte << 8) ^ 0x8000);
- }
- else
- {
- /*lint -e{734} converting signed 8-bit to signed 16-bit */
- pState->decoderR.x1 = (EAS_PCM)((EAS_PCM) pState->srcByte << 8);
- }
- pState->bytesLeft--;
- }
- }
-
- /* must be 16-bit samples */
- else
- {
- //unsigned 16 bit currently not supported
- if (pState->flags & PCM_FLAGS_UNSIGNED)
- {
- return EAS_ERROR_INVALID_PCM_TYPE;
- }
-
- /* fetch left or mono sample */
- if ((result = EAS_HWGetWord(hwInstData, pState->fileHandle, &pState->decoderL.x1, EAS_FALSE)) != EAS_SUCCESS)
- return result;
- pState->bytesLeft -= 2;
-
- /* fetch right sample */
- if(pState->flags & PCM_FLAGS_STEREO)
- {
- if ((result = EAS_HWGetWord(hwInstData, pState->fileHandle, &pState->decoderR.x1, EAS_FALSE)) != EAS_SUCCESS)
- return result;
- pState->bytesLeft -= 2;
- }
- }
- }
-
- /* no more data, force zero samples */
- else
- pState->decoderL.x1 = pState->decoderR.x1 = 0;
-
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * LinearPCMLocate()
- *----------------------------------------------------------------------------
- * Purpose:
- * Locate in a linear PCM stream
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT LinearPCMLocate (EAS_DATA_HANDLE pEASData, S_PCM_STATE *pState, EAS_I32 time)
-{
- EAS_RESULT result;
- EAS_I32 temp;
- EAS_I32 secs, msecs;
- EAS_INT shift;
-
- /* calculate size of sample frame */
- if (pState->flags & PCM_FLAGS_8_BIT)
- shift = 0;
- else
- shift = 1;
- if (pState->flags & PCM_FLAGS_STEREO)
- shift++;
-
- /* break down into secs and msecs */
- secs = time / 1000;
- msecs = time - (secs * 1000);
-
- /* calculate sample number fraction from msecs */
- temp = (msecs * pState->sampleRate);
- temp = (temp >> 10) + ((temp * 49) >> 21);
-
- /* add integer sample count */
- temp += secs * pState->sampleRate;
-
- /* calculate the position based on sample frame size */
- /*lint -e{703} use shift for performance */
- temp <<= shift;
-
- /* past end of sample? */
- if (temp > (EAS_I32) pState->loopStart)
- {
- /* if not looped, flag error */
- if (pState->loopSamples == 0)
- {
- pState->bytesLeft = 0;
- pState->flags |= PCM_FLAGS_EMPTY;
- return EAS_ERROR_LOCATE_BEYOND_END;
- }
-
- /* looped sample - calculate position in loop */
- while (temp > (EAS_I32) pState->loopStart)
- temp -= (EAS_I32) pState->loopStart;
- }
-
- /* seek to new position */
- if ((result = EAS_PESeek(pEASData, pState, &temp)) != EAS_SUCCESS)
- return result;
-
- /* reset state */
- if ((pState->state != EAS_STATE_PAUSING) && (pState->state != EAS_STATE_PAUSED))
- pState->state = EAS_STATE_READY;
-
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * EAS_PESeek
- *----------------------------------------------------------------------------
- * Purpose:
- * Locate to a particular byte in a PCM stream
- *----------------------------------------------------------------------------
- * This bit is tricky because the chunks may not be contiguous,
- * so we have to rely on the parser to position in the file. We
- * do this by seeking to the end of each chunk and simulating an
- * empty buffer condition until we get to where we want to go.
- *
- * A better solution would be a parser API for re-positioning,
- * but there isn't time at the moment to re-factor all the
- * parsers to support a new API.
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT EAS_PESeek (S_EAS_DATA *pEASData, S_PCM_STATE *pState, EAS_I32 *pLocation)
-{
- EAS_RESULT result;
-
- /* seek to start of audio */
- if ((result = EAS_HWFileSeek(pEASData->hwInstData, pState->fileHandle, pState->startPos)) != EAS_SUCCESS)
- {
- pState->state = EAS_STATE_ERROR;
- return result;
- }
- pState->bytesLeft = pState->bytesLeftLoop;
-
- /* skip through chunks until we find the right chunk */
- while (*pLocation > (EAS_I32) pState->bytesLeft)
- {
- /* seek to end of audio chunk */
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "EAS_PESeek: Seek to offset = %d\n", pState->bytesLeft); */ }
- if ((result = EAS_HWFileSeekOfs(pEASData->hwInstData, pState->fileHandle, pState->bytesLeft)) != EAS_SUCCESS)
- {
- pState->state = EAS_STATE_ERROR;
- return result;
- }
- *pLocation -= pState->bytesLeft;
- pState->bytesLeft = 0;
- pState->flags |= PCM_FLAGS_EMPTY;
-
- /* retrieve more data */
- if (pState->pCallback)
- (*pState->pCallback)(pEASData, pState->cbInstData, pState, EAS_STATE_EMPTY);
-
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "EAS_PESeek: bytesLeft=%d, byte location = %d\n", pState->bytesLeft, *pLocation); */ }
-
- /* no more samples */
- if (pState->bytesLeft == 0)
- return EAS_ERROR_LOCATE_BEYOND_END;
- }
-
- /* seek to new offset in current chunk */
- if (*pLocation > 0)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "EAS_PESeek: Seek to offset = %d\n", *pLocation); */ }
- if ((result = EAS_HWFileSeekOfs(pEASData->hwInstData, pState->fileHandle, *pLocation)) != EAS_SUCCESS)
- {
- pState->state = EAS_STATE_ERROR;
- return result;
- }
-
- /* if not streamed, calculate number of bytes left */
- if (pState->flags & PCM_FLAGS_STREAMING)
- pState->bytesLeft = 0x7fffffff;
- else
- pState->bytesLeft -= *pLocation;
- }
- return EAS_SUCCESS;
-}
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 849 $
+ * $Date: 2007-08-28 08:59:11 -0700 (Tue, 28 Aug 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+#include "eas_data.h"
+#include "eas_report.h"
+#include "eas_host.h"
+#include "eas_config.h"
+#include "eas_parser.h"
+#include "eas_pcm.h"
+#include "eas_math.h"
+#include "eas_mixer.h"
+
+#define PCM_MIXER_GUARD_BITS (NUM_MIXER_GUARD_BITS + 1)
+
+/*----------------------------------------------------------------------------
+ * Decoder interfaces
+ *----------------------------------------------------------------------------
+*/
+
+static EAS_RESULT LinearPCMDecode (EAS_DATA_HANDLE pEASData, S_PCM_STATE *pState);
+static EAS_RESULT LinearPCMLocate (EAS_DATA_HANDLE pEASData, S_PCM_STATE *pState, EAS_I32 time);
+
+static const S_DECODER_INTERFACE PCMDecoder =
+{
+ NULL,
+ LinearPCMDecode,
+ LinearPCMLocate,
+};
+
+/* SMAF ADPCM decoder */
+#ifdef _SMAF_PARSER
+extern S_DECODER_INTERFACE SmafDecoder;
+#define SMAF_DECODER &SmafDecoder
+extern S_DECODER_INTERFACE Smaf7BitDecoder;
+#define SMAF_7BIT_DECODER &Smaf7BitDecoder
+#else
+#define SMAF_DECODER NULL
+#define SMAF_7BIT_DECODER NULL
+#endif
+
+/* IMA ADPCM decoder */
+#ifdef _IMA_DECODER
+extern S_DECODER_INTERFACE IMADecoder;
+#define IMA_DECODER &IMADecoder
+#else
+#define IMA_DECODER NULL
+#endif
+
+static const S_DECODER_INTERFACE * const decoders[] =
+{
+ &PCMDecoder,
+ SMAF_DECODER,
+ IMA_DECODER,
+ SMAF_7BIT_DECODER
+};
+
+/*----------------------------------------------------------------------------
+ * Sample rate conversion
+ *----------------------------------------------------------------------------
+*/
+
+#define SRC_RATE_MULTIPLER (0x40000000 / _OUTPUT_SAMPLE_RATE)
+
+#ifdef _LOOKUP_SAMPLE_RATE
+static const EAS_U32 srcConvRate[][2] =
+{
+ 4000L, (4000L << 15) / _OUTPUT_SAMPLE_RATE,
+ 8000L, (8000L << 15) / _OUTPUT_SAMPLE_RATE,
+ 11025L, (11025L << 15) / _OUTPUT_SAMPLE_RATE,
+ 12000L, (12000L << 15) / _OUTPUT_SAMPLE_RATE,
+ 16000L, (16000L << 15) / _OUTPUT_SAMPLE_RATE,
+ 22050L, (22050L << 15) / _OUTPUT_SAMPLE_RATE,
+ 24000L, (24000L << 15) / _OUTPUT_SAMPLE_RATE,
+ 32000L, (32000L << 15) / _OUTPUT_SAMPLE_RATE
+};
+static EAS_U32 CalcBaseFreq (EAS_U32 sampleRate);
+#define SRC_CONV_RATE_ENTRIES (sizeof(srcConvRate)/sizeof(EAS_U32)/2)
+#endif
+
+
+/* interface prototypes */
+static EAS_RESULT RenderPCMStream (S_EAS_DATA *pEASData, S_PCM_STATE *pState, EAS_I32 numSamples);
+
+
+/* local prototypes */
+static S_PCM_STATE *FindSlot (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle, EAS_PCM_CALLBACK pCallbackFunc, EAS_VOID_PTR cbInstData);
+static EAS_RESULT InitPCMStream (S_EAS_DATA *pEASData, S_PCM_STATE *pState);
+
+/*----------------------------------------------------------------------------
+ * EAS_PEInit()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Initializes the PCM engine
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_PEInit (S_EAS_DATA *pEASData)
+{
+ S_PCM_STATE *pState;
+ EAS_INT i;
+
+ /* check for static memory allocation */
+ if (pEASData->staticMemoryModel)
+ pEASData->pPCMStreams = EAS_CMEnumData(EAS_CM_PCM_DATA);
+ /* allocate dynamic memory */
+ else
+ pEASData->pPCMStreams = EAS_HWMalloc(pEASData->hwInstData, sizeof(S_PCM_STATE) * MAX_PCM_STREAMS);
+
+ if (!pEASData->pPCMStreams)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_FATAL, "Failed to allocate memory for PCM streams\n"); */ }
+ return EAS_ERROR_MALLOC_FAILED;
+ }
+
+ //zero the memory to insure complete initialization
+ EAS_HWMemSet((void *)(pEASData->pPCMStreams),0, sizeof(S_PCM_STATE) * MAX_PCM_STREAMS);
+
+ /* initialize the state data */
+ for (i = 0, pState = pEASData->pPCMStreams; i < MAX_PCM_STREAMS; i++, pState++)
+ pState->fileHandle = NULL;
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_PEShutdown()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Shuts down the PCM engine
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_PEShutdown (S_EAS_DATA *pEASData)
+{
+
+ /* free any dynamic memory */
+ if (!pEASData->staticMemoryModel)
+ {
+ if (pEASData->pPCMStreams)
+ {
+ EAS_HWFree(pEASData->hwInstData, pEASData->pPCMStreams);
+ pEASData->pPCMStreams = NULL;
+ }
+ }
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_PERender()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Render a buffer of PCM audio
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_PERender (S_EAS_DATA* pEASData, EAS_I32 numSamples)
+{
+ S_PCM_STATE *pState;
+ EAS_RESULT result;
+ EAS_INT i;
+
+ /* render all the active streams */
+ for (i = 0, pState = pEASData->pPCMStreams; i < MAX_PCM_STREAMS; i++, pState++)
+ {
+ if ((pState->fileHandle) && (pState->state != EAS_STATE_STOPPED) && (pState->state != EAS_STATE_PAUSED))
+ if ((result = RenderPCMStream(pEASData, pState, numSamples)) != EAS_SUCCESS)
+ return result;
+ }
+ return EAS_SUCCESS;
+}
+
+
+/*----------------------------------------------------------------------------
+ * EAS_PEState()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Returns the current state of the stream
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ * pState - pointer to variable to store state
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ * Notes:
+ * This interface is also exposed in the internal library for use by the other modules.
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pEASData) reserved for future use */
+EAS_RESULT EAS_PEState (S_EAS_DATA *pEASData, EAS_PCM_HANDLE pInstData, EAS_STATE *pState)
+{
+ /* return current state */
+ *pState = pInstData->state;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_PEClose()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Close the file and clean up
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_PEClose (S_EAS_DATA *pEASData, EAS_PCM_HANDLE pState)
+{
+ EAS_RESULT result;
+
+ if ((result = EAS_HWCloseFile(pEASData->hwInstData, pState->fileHandle)) != EAS_SUCCESS)
+ return result;
+
+ pState->fileHandle = NULL;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * PCM_Reset()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Reset the sequencer. Used for locating backwards in the file.
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_PEReset (S_EAS_DATA *pEASData, EAS_PCM_HANDLE pState)
+{
+ EAS_RESULT result;
+
+ /* reset file position to first byte of data in the stream */
+ if ((result = EAS_HWFileSeek(pEASData->hwInstData, pState->fileHandle, pState->startPos)) != EAS_SUCCESS)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Error %d seeking to start of PCM file\n", result); */ }
+ return result;
+ }
+
+ /* re-initialize stream */
+ return InitPCMStream(pEASData, pState);
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_PEOpenStream()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Starts up a PCM playback
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_PEOpenStream (S_EAS_DATA *pEASData, S_PCM_OPEN_PARAMS *pParams, EAS_PCM_HANDLE *pHandle)
+{
+ EAS_RESULT result;
+ S_PCM_STATE *pState;
+ EAS_I32 filePos;
+
+ /* make sure we support this decoder */
+ if (pParams->decoder >= NUM_DECODER_MODULES)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Decoder selector out of range\n"); */ }
+ return EAS_ERROR_PARAMETER_RANGE;
+ }
+ if (decoders[pParams->decoder] == NULL)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Decoder module not available\n"); */ }
+ return EAS_ERROR_FEATURE_NOT_AVAILABLE;
+ }
+
+ /* find a slot for the new stream */
+ if ((pState = FindSlot(pEASData, pParams->fileHandle, pParams->pCallbackFunc, pParams->cbInstData)) == NULL)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Unable to open ADPCM stream, too many streams open\n"); */ }
+ return EAS_ERROR_MAX_PCM_STREAMS;
+ }
+
+ /* get the current file position */
+ if ((result = EAS_HWFilePos(pEASData->hwInstData, pState->fileHandle, &filePos)) != EAS_SUCCESS)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "EAS_HWFilePos returned %ld\n",result); */ }
+ pState->fileHandle = NULL;
+ return result;
+ }
+
+ pState->pDecoder = decoders[pParams->decoder];
+ pState->startPos = filePos;
+ pState->bytesLeftLoop = pState->byteCount = pParams->size;
+ pState->loopStart = pParams->loopStart;
+ pState->samplesTilLoop = (EAS_I32) pState->loopStart;
+ pState->loopSamples = pParams->loopSamples;
+ pState->samplesInLoop = 0;
+ pState->blockSize = (EAS_U16) pParams->blockSize;
+ pState->flags = pParams->flags;
+ pState->envData = pParams->envData;
+ pState->volume = pParams->volume;
+ pState->sampleRate = (EAS_U16) pParams->sampleRate;
+
+ /* set the base frequency */
+ pState->basefreq = (SRC_RATE_MULTIPLER * (EAS_U32) pParams->sampleRate) >> 15;
+
+ /* calculate shift for frequencies > 1.0 */
+ pState->rateShift = 0;
+ while (pState->basefreq > 32767)
+ {
+ pState->basefreq = pState->basefreq >> 1;
+ pState->rateShift++;
+ }
+
+ /* initialize */
+ if ((result = InitPCMStream(pEASData, pState)) != EAS_SUCCESS)
+ return result;
+
+ *pHandle = pState;
+
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "EAS_PEOpenStream: StartPos=%d, byteCount = %d, loopSamples=%d\n",
+ pState->startPos, pState->byteCount, pState->loopSamples); */ }
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_PEContinueStream()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Continues a PCM stream
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -e{715} reserved for future use */
+EAS_RESULT EAS_PEContinueStream (S_EAS_DATA *pEASData, EAS_PCM_HANDLE pState, EAS_I32 size)
+{
+
+ /* add new samples to count */
+ pState->bytesLeft += size;
+ if (pState->bytesLeft > 0)
+ pState->flags &= ~PCM_FLAGS_EMPTY;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_PEGetFileHandle()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Returns the file handle of a stream
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pEASData) reserved for future use */
+EAS_RESULT EAS_PEGetFileHandle (S_EAS_DATA *pEASData, EAS_PCM_HANDLE pState, EAS_FILE_HANDLE *pFileHandle)
+{
+ *pFileHandle = pState->fileHandle;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_PEUpdateParams()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Update the pitch and volume parameters for a PCM stream
+ *
+ * Inputs:
+ * pEASData - pointer to EAS library instance data
+ * handle - pointer to S_PCM_STATE for this stream
+ * gainLeft - linear gain multipler in 1.15 fraction format
+ * gainRight - linear gain multipler in 1.15 fraction format
+ * pitch - pitch shift in cents
+ * initial - initial settings, set current gain
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ * Notes
+ * In mono mode, leftGain controls the output gain and rightGain is ignored
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pEASData) reserved for future use */
+/*lint -esym(715, gainRight) used only in 2-channel version */
+EAS_RESULT EAS_PEUpdateParams (S_EAS_DATA* pEASData, EAS_PCM_HANDLE pState, EAS_I16 pitch, EAS_I16 gainLeft, EAS_I16 gainRight)
+{
+
+ pState->gainLeft = gainLeft;
+
+#if (NUM_OUTPUT_CHANNELS == 2)
+ pState->gainRight = gainRight;
+#endif
+
+ pState->pitch = pitch;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_PELocate()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * This function seeks to the requested place in the file. Accuracy
+ * is dependent on the sample rate and block size.
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * pState - stream handle
+ * time - media time in milliseconds
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_PELocate (S_EAS_DATA *pEASData, EAS_PCM_HANDLE pState, EAS_I32 time)
+{
+ if (pState->pDecoder->pfLocate == NULL)
+ return EAS_ERROR_FEATURE_NOT_AVAILABLE;
+
+ return pState->pDecoder->pfLocate(pEASData, pState, time);
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_PEUpdateVolume()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Update the volume parameters for a PCM stream
+ *
+ * Inputs:
+ * pEASData - pointer to EAS library instance data
+ * handle - pointer to S_PCM_STATE for this stream
+ * gainLeft - linear gain multipler in 1.15 fraction format
+ * gainRight - linear gain multipler in 1.15 fraction format
+ * initial - initial settings, set current gain
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ * Notes
+ * In mono mode, leftGain controls the output gain and rightGain is ignored
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pEASData) reserved for future use */
+EAS_RESULT EAS_PEUpdateVolume (S_EAS_DATA* pEASData, EAS_PCM_HANDLE pState, EAS_I16 volume)
+{
+ pState->volume = volume;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_PEUpdatePitch()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Update the pitch parameter for a PCM stream
+ *
+ * Inputs:
+ * pEASData - pointer to EAS library instance data
+ * pState - pointer to S_PCM_STATE for this stream
+ * pitch - new pitch value in pitch cents
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pEASData) reserved for future use */
+EAS_RESULT EAS_PEUpdatePitch (S_EAS_DATA* pEASData, EAS_PCM_HANDLE pState, EAS_I16 pitch)
+{
+ pState->pitch = pitch;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_PEPause()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Mute and stop rendering a PCM stream. Sets the gain target to zero and stops the playback
+ * at the end of the next audio frame.
+ *
+ * Inputs:
+ * pEASData - pointer to EAS library instance data
+ * handle - pointer to S_PCM_STATE for this stream
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pEASData) reserved for future use */
+EAS_RESULT EAS_PEPause (S_EAS_DATA *pEASData, EAS_PCM_HANDLE pState)
+{
+ /* set state to stopping */
+ pState->state = EAS_STATE_PAUSING;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_PEResume()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Resume rendering a PCM stream. Sets the gain target back to its
+ * previous setting and restarts playback at the end of the next audio
+ * frame.
+ *
+ * Inputs:
+ * pEASData - pointer to EAS library instance data
+ * handle - pointer to S_PCM_STATE for this stream
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pEASData) reserved for future use */
+EAS_RESULT EAS_PEResume (S_EAS_DATA *pEASData, EAS_PCM_HANDLE pState)
+{
+ /* set state to stopping */
+ pState->state = EAS_STATE_PLAY;
+ return EAS_SUCCESS;
+}
+
+EAS_U32 getDecayScale(EAS_U32 index)
+{
+ EAS_U32 utemp;
+
+ //envelope decay segment
+ switch (index)
+ {
+ case 0: //no decay
+ utemp = 512;//32768;
+ break;
+ case 1: //.0156 dB per update
+ utemp = 511;//32709;
+ break;
+ case 2: //.03125
+ utemp = 510;//32649;
+ break;
+ case 3: //.0625
+ utemp = 508;//32532;
+ break;
+ case 4: //.125
+ utemp = 505;//32298;
+ break;
+ case 5: //.25
+ utemp = 497;//31835;
+ break;
+ case 6: //.5
+ utemp = 483;//30929;
+ break;
+ case 7: //1.0
+ utemp = 456;//29193;
+ break;
+ case 8: //2.0
+ utemp = 406;//26008;
+ break;
+ case 9: //4.0
+ utemp = 323;//20642;
+ break;
+ case 10: //8.0
+ utemp = 203;//13004;
+ break;
+ case 11: //16.0
+ utemp = 81;//5160;
+ break;
+ case 12: //32.0
+ utemp = 13;//813;
+ break;
+ case 13: //64.0
+ utemp = 0;//20;
+ break;
+ case 14: //128.0
+ utemp = 0;
+ break;
+ case 15: //256.0
+ default:
+ utemp = 0;
+ break;
+ }
+ //printf("getdecayscale returned %d\n",utemp);
+ return utemp;
+}
+
+EAS_U32 getAttackIncrement(EAS_U32 index)
+{
+ EAS_U32 utemp;
+
+ //envelope decay segment
+ switch (index)
+ {
+ case 0:
+ utemp = 32;
+ break;
+ case 1:
+ utemp = 64;
+ break;
+ case 2:
+ utemp = 128;
+ break;
+ case 3:
+ utemp = 256;
+ break;
+ case 4:
+ utemp = 512;
+ break;
+ case 5:
+ utemp = 1024;
+ break;
+ case 6:
+ utemp = 2048;
+ break;
+ case 7:
+ utemp = 4096;
+ break;
+ case 8:
+ utemp = 8192;
+ break;
+ case 9:
+ utemp = 16384;
+ break;
+ case 10:
+ utemp = 32768;
+ break;
+ case 11:
+ utemp = 65536;
+ break;
+ case 12:
+ utemp = 65536;
+ break;
+ case 13:
+ utemp = 65536;
+ break;
+ case 14:
+ utemp = 65535;
+ break;
+ case 15:
+ default:
+ utemp = 0;
+ break;
+ }
+ //printf("getattackincrement returned %d\n",utemp);
+ return utemp;
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_PERelease()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Put the PCM stream envelope into release.
+ *
+ * Inputs:
+ * pEASData - pointer to EAS library instance data
+ * handle - pointer to S_PCM_STATE for this stream
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pEASData) reserved for future use */
+EAS_RESULT EAS_PERelease (S_EAS_DATA *pEASData, EAS_PCM_HANDLE pState)
+{
+ EAS_U32 utemp;
+
+ //printf("handling note-off part of envelope\n");
+ /*if the note is not ignore release or sustained*/
+ if (((pState->envData >> 24) & 0x0F)==0)
+ {
+ /* set envelope state to release */
+ pState->envState = PCM_ENV_RELEASE;
+ utemp = ((pState->envData >> 20) & 0x0F);
+ pState->envScale = getDecayScale(utemp); //getReleaseScale(utemp);
+ }
+ else
+ {
+ /*else change envelope state to sustain */
+ pState->envState = PCM_ENV_SUSTAIN;
+ utemp = ((pState->envData >> 28) & 0x0F);
+ pState->envScale = getDecayScale(utemp); //getSustainScale(utemp);
+ }
+ //since we are in release, don't let anything hang around too long
+ //printf("checking env scale, val = %d\n",((S_PCM_STATE*) handle)->envScale);
+ if (pState->envScale > 505)
+ pState->envScale = 505;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * FindSlot()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Locates an empty stream slot and assigns the file handle
+ *
+ * Inputs:
+ * pEASData - pointer to EAS library instance data
+ * fileHandle - file handle
+ * pCallbackFunc - function to be called back upon EAS_STATE_STOPPED
+ *
+ * Outputs:
+ * returns handle to slot or NULL if all slots are used
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static S_PCM_STATE *FindSlot (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle, EAS_PCM_CALLBACK pCallbackFunc, EAS_VOID_PTR cbInstData)
+{
+ EAS_INT i;
+ S_PCM_STATE *pState;
+
+#ifndef NO_PCM_STEAL
+ S_PCM_STATE *foundState = NULL;
+ EAS_INT count = 0;
+ EAS_U32 startOrder = 0xFFFFFFFF;
+ S_PCM_STATE *stealState = NULL;
+ EAS_U32 youngest = 0;
+
+ /* find an empty slot, count total in use, and find oldest in use (lowest start order) */
+ for (i = 0, pState = pEASData->pPCMStreams; i < MAX_PCM_STREAMS; i++, pState++)
+ {
+ /* if this one is available */
+ if (pState->fileHandle == NULL)
+ {
+ foundState = pState;
+ }
+ /* else this one is in use, so see if it is the oldest, and count total in use */
+ /* also find youngest */
+ else
+ {
+ /*one more voice in use*/
+ count++;
+ /* is this the oldest? (lowest start order) */
+ if ((pState->state != EAS_STATE_STOPPING) && (pState->startOrder < startOrder))
+ {
+ /* remember this one */
+ stealState = pState;
+ /* remember the oldest so far */
+ startOrder = pState->startOrder;
+ }
+ /* is this the youngest? (highest start order) */
+ if (pState->startOrder >= youngest)
+ {
+ youngest = pState->startOrder;
+ }
+ }
+ }
+
+ /* if there are too many voices active, stop the oldest one */
+ if (count > PCM_STREAM_THRESHOLD)
+ {
+ //printf("stealing!!!\n");
+ /* make sure we got one, although we should always have one at this point */
+ if (stealState != NULL)
+ {
+ //flag this as stopping, so it will get shut off
+ stealState->state = EAS_STATE_STOPPING;
+ }
+ }
+
+ /* if there are no available open streams (we won't likely see this, due to stealing) */
+ if (foundState == NULL)
+ return NULL;
+
+ /* save info */
+ foundState->startOrder = youngest + 1;
+ foundState->fileHandle = fileHandle;
+ foundState->pCallback = pCallbackFunc;
+ foundState->cbInstData = cbInstData;
+ return foundState;
+#else
+ /* find an empty slot*/
+ for (i = 0; i < MAX_PCM_STREAMS; i++)
+ {
+ pState = &pEASData->pPCMStreams[i];
+ if (pState->fileHandle != NULL)
+ continue;
+
+ pState->fileHandle = fileHandle;
+ pState->pCallback = pCallbackFunc;
+ pState->cbInstData = cbInstData;
+ return pState;
+ }
+ return NULL;
+#endif
+}
+
+#ifdef _LOOKUP_SAMPLE_RATE
+/*----------------------------------------------------------------------------
+ * CalcBaseFreq()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Calculates the fractional phase increment for the sample rate converter
+ *
+ * Inputs:
+ * sampleRate - sample rate in samples/sec
+ *
+ * Outputs:
+ * Returns fractional sample rate with a 15-bit fraction
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_U32 CalcBaseFreq (EAS_U32 sampleRate)
+{
+ EAS_INT i;
+
+ /* look up the conversion rate */
+ for (i = 0; i < (EAS_INT)(SRC_CONV_RATE_ENTRIES); i ++)
+ {
+ if (srcConvRate[i][0] == sampleRate)
+ return srcConvRate[i][1];
+ }
+
+ /* if not found in table, do it the long way */
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Sample rate %u not in table, calculating by division\n", sampleRate); */ }
+
+ return (SRC_RATE_MULTIPLER * (EAS_U32) sampleRate) >> 15;
+}
+#endif
+
+/*----------------------------------------------------------------------------
+ * InitPCMStream()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Start an ADPCM stream playback. Decodes the header, preps the engine.
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT InitPCMStream (S_EAS_DATA *pEASData, S_PCM_STATE *pState)
+{
+
+ /* initialize the data structure */
+ pState->bytesLeft = pState->byteCount;
+ pState->phase = 0;
+ pState->srcByte = 0;
+ pState->decoderL.acc = 0;
+ pState->decoderL.output = 0;
+ pState->decoderL.x0 = pState->decoderL.x1 = 0;
+ pState->decoderL.step = 0;
+ pState->decoderR.acc = 0;
+ pState->decoderR.output = 0;
+ pState->decoderR.x0 = pState->decoderR.x1 = 0;
+ pState->decoderR.step = 0;
+ pState->hiNibble = EAS_FALSE;
+ pState->pitch = 0;
+ pState->blockCount = 0;
+ pState->gainLeft = PCM_DEFAULT_GAIN_SETTING;
+// pState->currentGainLeft = PCM_DEFAULT_GAIN_SETTING;
+ pState->envValue = 0;
+ pState->envState = PCM_ENV_START;
+
+#if (NUM_OUTPUT_CHANNELS == 2)
+ pState->gainRight = PCM_DEFAULT_GAIN_SETTING;
+// pState->currentGainRight = PCM_DEFAULT_GAIN_SETTING;
+#endif
+ pState->state = EAS_STATE_READY;
+
+ /* initialize the decoder */
+ if (pState->pDecoder->pfInit)
+ return (*pState->pDecoder->pfInit)(pEASData, pState);
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * RenderPCMStream()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Decodes a buffer of ADPCM data.
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT RenderPCMStream (S_EAS_DATA *pEASData, S_PCM_STATE *pState, EAS_I32 numSamples)
+{
+ EAS_RESULT result;
+ EAS_U32 phaseInc;
+ EAS_I32 gainLeft, gainIncLeft;
+ EAS_I32 *pOut;
+ EAS_I32 temp;
+ EAS_U32 utemp;
+
+#if (NUM_OUTPUT_CHANNELS == 2)
+ EAS_I32 gainRight, gainIncRight;
+#endif
+
+#if 0
+ printf("env data: AR = %d, DR = %d, SL = %d, SR = %d, RR = %d\n",
+ ((pState->envData >> 12) & 0x0F),
+ ((pState->envData >> 16) & 0x0F),
+ ((pState->envData >> 8) & 0x0F),
+ ((pState->envData >> 28) & 0x0F),
+ ((pState->envData >> 20) & 0x0F));
+#endif
+
+ if (pState->envState == PCM_ENV_START)
+ {
+ //printf("env start\n");
+ utemp = ((pState->envData >> 12) & 0x0F);
+ //if fastest rate, attack is already completed
+ //do the same for slowest rate, since that allows zero to be passed for default envelope
+ if (utemp == 0x0F || utemp == 0x00)
+ {
+ //start envelope at full
+ pState->envValue = (32768<<7);
+ //jump right into decay
+ utemp = ((pState->envData >> 16) & 0x0F);
+ pState->envScale = getDecayScale(utemp);
+ pState->envState = PCM_ENV_DECAY;
+ pState->currentGainLeft = (EAS_I16) FMUL_15x15(pState->gainLeft, pState->volume);
+ pState->currentGainRight = (EAS_I16) FMUL_15x15(pState->gainRight, pState->volume);
+ }
+ //else attack has a ramp
+ else
+ {
+ //start the envelope very low
+ pState->envValue = (2<<7);
+ pState->currentGainLeft = 0;
+ pState->currentGainRight = 0;
+ //get envelope attack scaling value
+ pState->envScale = getAttackIncrement(utemp);
+ //go to attack state
+ pState->envState = PCM_ENV_ATTACK;
+ }
+ }
+ if (pState->envState == PCM_ENV_ATTACK)
+ {
+ //printf("env attack, env value = %d, env scale = %d\n",pState->envValue>>7,pState->envScale);
+ //update envelope value
+ pState->envValue = pState->envValue + (pState->envScale << 7);
+ //check envelope level and update state if needed
+ if (pState->envValue >= (32768<<7))
+ {
+ pState->envValue = (32768<<7);
+ utemp = ((pState->envData >> 16) & 0x0F);
+ pState->envScale = getDecayScale(utemp);
+ pState->envState = PCM_ENV_DECAY;
+ }
+ }
+ else if (pState->envState == PCM_ENV_DECAY)
+ {
+ //printf("env decay, env value = %d, env scale = %d\n",pState->envValue>>7,pState->envScale);
+ //update envelope value
+ pState->envValue = (pState->envValue * pState->envScale)>>9;
+ //check envelope level against sustain level and update state if needed
+ utemp = ((pState->envData >> 8) & 0x0F);
+ if (utemp == (EAS_U32)0x0F)
+ utemp = (2<<7);
+ else
+ {
+ utemp = ((32769<<7) >> (utemp>>1));
+ }
+ if (pState->envValue <= utemp)
+ {
+ utemp = ((pState->envData >> 28) & 0x0F);
+ pState->envScale = getDecayScale(utemp); //getSustainScale(utemp);
+ pState->envState = PCM_ENV_SUSTAIN;
+ }
+ }
+ else if (pState->envState == PCM_ENV_SUSTAIN)
+ {
+ //printf("env sustain, env value = %d, env scale = %d\n",pState->envValue>>7,pState->envScale);
+ //update envelope value
+ pState->envValue = (pState->envValue * pState->envScale)>>9;
+ //check envelope level against bottom level and update state if needed
+ if (pState->envValue <= (2<<7))
+ {
+ //no more decay
+ pState->envScale = 512;
+ pState->envState = PCM_ENV_END;
+ }
+ }
+ else if (pState->envState == PCM_ENV_RELEASE)
+ {
+ //printf("env release, env value = %d, env scale = %d\n",pState->envValue>>7,pState->envScale);
+ //update envelope value
+ pState->envValue = (pState->envValue * pState->envScale)>>9;
+ //check envelope level against bottom level and update state if needed
+ if (pState->envValue <= (2<<7))
+ {
+ //no more decay
+ pState->envScale = 512;
+ pState->envState = PCM_ENV_END;
+ }
+ }
+ else if (pState->envState == PCM_ENV_END)
+ {
+ //printf("env end\n");
+ /* set state to stopping, already ramped down */
+ pState->state = EAS_STATE_STOPPING;
+ }
+
+ //pState->gainLeft = (EAS_U16)((pState->gainLeft * (pState->envValue>>7))>>15);
+ //pState->gainRight = (EAS_U16)((pState->gainRight * (pState->envValue>>7))>>15);
+
+ /* gain to 32-bits to increase resolution on anti-zipper filter */
+ /*lint -e{703} use shift for performance */
+ gainLeft = (EAS_I32) pState->currentGainLeft << SYNTH_UPDATE_PERIOD_IN_BITS;
+#if (NUM_OUTPUT_CHANNELS == 2)
+ /*lint -e{703} use shift for performance */
+ gainRight = (EAS_I32) pState->currentGainRight << SYNTH_UPDATE_PERIOD_IN_BITS;
+#endif
+
+ /* calculate a new gain increment, gain target is zero if pausing */
+ if ((pState->state == EAS_STATE_PAUSING) || (pState->state == EAS_STATE_PAUSED))
+ {
+ gainIncLeft = -pState->currentGainLeft;
+#if (NUM_OUTPUT_CHANNELS == 2)
+ gainIncRight= -pState->currentGainRight;
+#endif
+ }
+ else
+ {
+ EAS_I32 gain = FMUL_15x15(pState->envValue >> 7, pState->volume);
+ gainIncLeft = FMUL_15x15(pState->gainLeft, gain) - pState->currentGainLeft;
+#if (NUM_OUTPUT_CHANNELS == 2)
+ gainIncRight = FMUL_15x15(pState->gainRight, gain) - pState->currentGainRight;
+#endif
+ }
+
+ /* calculate phase increment */
+ phaseInc = pState->basefreq;
+
+ /* convert pitch cents to linear multiplier */
+ if (pState->pitch)
+ {
+ temp = EAS_Calculate2toX(pState->pitch);
+ phaseInc = FMUL_15x15(phaseInc, temp);
+ }
+ phaseInc = phaseInc << pState->rateShift;
+
+ /* pointer to mix buffer */
+ pOut = pEASData->pMixBuffer;
+
+ /* render a buffer of samples */
+ while (numSamples--)
+ {
+
+ /* interpolate an output sample */
+ pState->decoderL.output = pState->decoderL.x0 + FMUL_15x15((pState->decoderL.x1 - pState->decoderL.x0), pState->phase & PHASE_FRAC_MASK);
+
+ /* stereo output */
+#if (NUM_OUTPUT_CHANNELS == 2)
+
+ /* stereo stream? */
+ if (pState->flags & PCM_FLAGS_STEREO)
+ pState->decoderR.output = pState->decoderR.x0 + FMUL_15x15((pState->decoderR.x1 - pState->decoderR.x0), pState->phase & PHASE_FRAC_MASK);
+
+ /* gain scale and mix */
+ /*lint -e{704} use shift instead of division */
+ *pOut++ += (pState->decoderL.output * (gainLeft >> SYNTH_UPDATE_PERIOD_IN_BITS)) >> PCM_MIXER_GUARD_BITS;
+ gainLeft += gainIncLeft;
+
+ /*lint -e{704} use shift instead of division */
+ if (pState->flags & PCM_FLAGS_STEREO)
+ *pOut++ += (pState->decoderR.output * (gainRight >> SYNTH_UPDATE_PERIOD_IN_BITS)) >> PCM_MIXER_GUARD_BITS;
+ else
+ *pOut++ += (pState->decoderL.output * (gainRight >> SYNTH_UPDATE_PERIOD_IN_BITS)) >> PCM_MIXER_GUARD_BITS;
+
+ gainRight += gainIncRight;
+
+ /* mono output */
+#else
+ /* if stereo stream, decode right channel and mix to mono */
+ if (pState->flags & PCM_FLAGS_STEREO)
+ {
+ pState->decoderR.output= pState->decoderR.x0 + FMUL_15x15((pState->decoderR.x1 - pState->decoderR.x0), pState->phase & PHASE_FRAC_MASK);
+
+ /* for mono, sum stereo ADPCM to mono */
+ /*lint -e{704} use shift instead of division */
+ *pOut++ += ((pState->decoderL.output + pState->decoderR.output) * (gainLeft >> SYNTH_UPDATE_PERIOD_IN_BITS)) >> PCM_MIXER_GUARD_BITS;
+ }
+ else
+ /*lint -e{704} use shift instead of division */
+ *pOut++ += (pState->decoderL.output * (gainLeft >> SYNTH_UPDATE_PERIOD_IN_BITS)) >> PCM_MIXER_GUARD_BITS;
+
+ gainLeft += gainIncLeft;
+#endif
+
+ /* advance phase accumulator */
+ pState->phase += phaseInc;
+
+ /* if integer part of phase accumulator is non-zero, advance to next sample */
+ while (pState->phase & ~PHASE_FRAC_MASK)
+ {
+ pState->decoderL.x0 = pState->decoderL.x1;
+ pState->decoderR.x0 = pState->decoderR.x1;
+
+ /* give the source a chance to continue the stream */
+ if (!pState->bytesLeft && pState->pCallback && ((pState->flags & PCM_FLAGS_EMPTY) == 0))
+ {
+ pState->flags |= PCM_FLAGS_EMPTY;
+ (*pState->pCallback)(pEASData, pState->cbInstData, pState, EAS_STATE_EMPTY);
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "RenderPCMStream: After empty callback, bytesLeft = %d\n", pState->bytesLeft); */ }
+ }
+
+ /* decode the next sample */
+ if ((result = (*pState->pDecoder->pfDecodeSample)(pEASData, pState)) != EAS_SUCCESS)
+ return result;
+
+ /* adjust phase by one sample */
+ pState->phase -= (1L << NUM_PHASE_FRAC_BITS);
+ }
+
+ }
+
+ /* save new gain */
+ /*lint -e{704} use shift instead of division */
+ pState->currentGainLeft = (EAS_I16) (gainLeft >> SYNTH_UPDATE_PERIOD_IN_BITS);
+
+#if (NUM_OUTPUT_CHANNELS == 2)
+ /*lint -e{704} use shift instead of division */
+ pState->currentGainRight = (EAS_I16) (gainRight >> SYNTH_UPDATE_PERIOD_IN_BITS);
+#endif
+
+ /* if pausing, set new state and notify */
+ if (pState->state == EAS_STATE_PAUSING)
+ {
+ pState->state = EAS_STATE_PAUSED;
+ if (pState->pCallback)
+ (*pState->pCallback)(pEASData, pState->cbInstData, pState, pState->state);
+ }
+
+ /* if out of data, set stopped state and notify */
+ if (pState->bytesLeft == 0 || pState->state == EAS_STATE_STOPPING)
+ {
+ pState->state = EAS_STATE_STOPPED;
+
+ /* do callback unless the file has already been closed */
+ if (pState->pCallback && pState->fileHandle)
+ (*pState->pCallback)(pEASData, pState->cbInstData, pState, pState->state);
+ }
+
+ if (pState->state == EAS_STATE_READY)
+ pState->state = EAS_STATE_PLAY;
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * LinearPCMDecode()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Decodes a PCM sample
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT LinearPCMDecode (EAS_DATA_HANDLE pEASData, S_PCM_STATE *pState)
+{
+ EAS_RESULT result;
+ EAS_HW_DATA_HANDLE hwInstData;
+
+ hwInstData = ((S_EAS_DATA*) pEASData)->hwInstData;
+
+ /* if out of data, check for loop */
+ if ((pState->bytesLeft == 0) && (pState->loopSamples != 0))
+ {
+ if ((result = EAS_HWFileSeek(pEASData->hwInstData, pState->fileHandle, (EAS_I32) (pState->startPos + pState->loopLocation))) != EAS_SUCCESS)
+ return result;
+ pState->bytesLeft = pState->byteCount = (EAS_I32) pState->bytesLeftLoop;
+ pState->flags &= ~PCM_FLAGS_EMPTY;
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "LinearPCMDecode: Rewind file to %d, bytesLeft = %d\n", pState->startPos, pState->bytesLeft); */ }
+ }
+
+ if (pState->bytesLeft)
+ {
+
+ /* check format byte for 8-bit samples */
+ if (pState->flags & PCM_FLAGS_8_BIT)
+ {
+ /* fetch left or mono sample */
+ if ((result = EAS_HWGetByte(hwInstData, pState->fileHandle, &pState->srcByte)) != EAS_SUCCESS)
+ return result;
+
+ /* if unsigned */
+ if (pState->flags & PCM_FLAGS_UNSIGNED)
+ {
+ /*lint -e{734} converting unsigned 8-bit to signed 16-bit */
+ pState->decoderL.x1 = (EAS_PCM)(((EAS_PCM) pState->srcByte << 8) ^ 0x8000);
+ }
+ else
+ {
+ /*lint -e{734} converting signed 8-bit to signed 16-bit */
+ pState->decoderL.x1 = (EAS_PCM)((EAS_PCM) pState->srcByte << 8);
+ }
+ pState->bytesLeft--;
+
+ /* fetch right sample */
+ if(pState->flags & PCM_FLAGS_STEREO)
+ {
+ if ((result = EAS_HWGetByte(hwInstData, pState->fileHandle, &pState->srcByte)) != EAS_SUCCESS)
+ return result;
+
+ /* if unsigned */
+ if (pState->flags & PCM_FLAGS_UNSIGNED)
+ {
+ /*lint -e{734} converting unsigned 8-bit to signed 16-bit */
+ pState->decoderR.x1 = (EAS_PCM)(((EAS_PCM) pState->srcByte << 8) ^ 0x8000);
+ }
+ else
+ {
+ /*lint -e{734} converting signed 8-bit to signed 16-bit */
+ pState->decoderR.x1 = (EAS_PCM)((EAS_PCM) pState->srcByte << 8);
+ }
+ pState->bytesLeft--;
+ }
+ }
+
+ /* must be 16-bit samples */
+ else
+ {
+ //unsigned 16 bit currently not supported
+ if (pState->flags & PCM_FLAGS_UNSIGNED)
+ {
+ return EAS_ERROR_INVALID_PCM_TYPE;
+ }
+
+ /* fetch left or mono sample */
+ if ((result = EAS_HWGetWord(hwInstData, pState->fileHandle, &pState->decoderL.x1, EAS_FALSE)) != EAS_SUCCESS)
+ return result;
+ pState->bytesLeft -= 2;
+
+ /* fetch right sample */
+ if(pState->flags & PCM_FLAGS_STEREO)
+ {
+ if ((result = EAS_HWGetWord(hwInstData, pState->fileHandle, &pState->decoderR.x1, EAS_FALSE)) != EAS_SUCCESS)
+ return result;
+ pState->bytesLeft -= 2;
+ }
+ }
+ }
+
+ /* no more data, force zero samples */
+ else
+ pState->decoderL.x1 = pState->decoderR.x1 = 0;
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * LinearPCMLocate()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Locate in a linear PCM stream
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT LinearPCMLocate (EAS_DATA_HANDLE pEASData, S_PCM_STATE *pState, EAS_I32 time)
+{
+ EAS_RESULT result;
+ EAS_I32 temp;
+ EAS_I32 secs, msecs;
+ EAS_INT shift;
+
+ /* calculate size of sample frame */
+ if (pState->flags & PCM_FLAGS_8_BIT)
+ shift = 0;
+ else
+ shift = 1;
+ if (pState->flags & PCM_FLAGS_STEREO)
+ shift++;
+
+ /* break down into secs and msecs */
+ secs = time / 1000;
+ msecs = time - (secs * 1000);
+
+ /* calculate sample number fraction from msecs */
+ temp = (msecs * pState->sampleRate);
+ temp = (temp >> 10) + ((temp * 49) >> 21);
+
+ /* add integer sample count */
+ temp += secs * pState->sampleRate;
+
+ /* calculate the position based on sample frame size */
+ /*lint -e{703} use shift for performance */
+ temp <<= shift;
+
+ /* past end of sample? */
+ if (temp > (EAS_I32) pState->loopStart)
+ {
+ /* if not looped, flag error */
+ if (pState->loopSamples == 0)
+ {
+ pState->bytesLeft = 0;
+ pState->flags |= PCM_FLAGS_EMPTY;
+ return EAS_ERROR_LOCATE_BEYOND_END;
+ }
+
+ /* looped sample - calculate position in loop */
+ while (temp > (EAS_I32) pState->loopStart)
+ temp -= (EAS_I32) pState->loopStart;
+ }
+
+ /* seek to new position */
+ if ((result = EAS_PESeek(pEASData, pState, &temp)) != EAS_SUCCESS)
+ return result;
+
+ /* reset state */
+ if ((pState->state != EAS_STATE_PAUSING) && (pState->state != EAS_STATE_PAUSED))
+ pState->state = EAS_STATE_READY;
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_PESeek
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Locate to a particular byte in a PCM stream
+ *----------------------------------------------------------------------------
+ * This bit is tricky because the chunks may not be contiguous,
+ * so we have to rely on the parser to position in the file. We
+ * do this by seeking to the end of each chunk and simulating an
+ * empty buffer condition until we get to where we want to go.
+ *
+ * A better solution would be a parser API for re-positioning,
+ * but there isn't time at the moment to re-factor all the
+ * parsers to support a new API.
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_PESeek (S_EAS_DATA *pEASData, S_PCM_STATE *pState, EAS_I32 *pLocation)
+{
+ EAS_RESULT result;
+
+ /* seek to start of audio */
+ if ((result = EAS_HWFileSeek(pEASData->hwInstData, pState->fileHandle, pState->startPos)) != EAS_SUCCESS)
+ {
+ pState->state = EAS_STATE_ERROR;
+ return result;
+ }
+ pState->bytesLeft = pState->bytesLeftLoop;
+
+ /* skip through chunks until we find the right chunk */
+ while (*pLocation > (EAS_I32) pState->bytesLeft)
+ {
+ /* seek to end of audio chunk */
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "EAS_PESeek: Seek to offset = %d\n", pState->bytesLeft); */ }
+ if ((result = EAS_HWFileSeekOfs(pEASData->hwInstData, pState->fileHandle, pState->bytesLeft)) != EAS_SUCCESS)
+ {
+ pState->state = EAS_STATE_ERROR;
+ return result;
+ }
+ *pLocation -= pState->bytesLeft;
+ pState->bytesLeft = 0;
+ pState->flags |= PCM_FLAGS_EMPTY;
+
+ /* retrieve more data */
+ if (pState->pCallback)
+ (*pState->pCallback)(pEASData, pState->cbInstData, pState, EAS_STATE_EMPTY);
+
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "EAS_PESeek: bytesLeft=%d, byte location = %d\n", pState->bytesLeft, *pLocation); */ }
+
+ /* no more samples */
+ if (pState->bytesLeft == 0)
+ return EAS_ERROR_LOCATE_BEYOND_END;
+ }
+
+ /* seek to new offset in current chunk */
+ if (*pLocation > 0)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "EAS_PESeek: Seek to offset = %d\n", *pLocation); */ }
+ if ((result = EAS_HWFileSeekOfs(pEASData->hwInstData, pState->fileHandle, *pLocation)) != EAS_SUCCESS)
+ {
+ pState->state = EAS_STATE_ERROR;
+ return result;
+ }
+
+ /* if not streamed, calculate number of bytes left */
+ if (pState->flags & PCM_FLAGS_STREAMING)
+ pState->bytesLeft = 0x7fffffff;
+ else
+ pState->bytesLeft -= *pLocation;
+ }
+ return EAS_SUCCESS;
+}
+
diff --git a/arm-fm-22k/lib_src/eas_pcm.h b/arm-fm-22k/lib_src/eas_pcm.h
index c161757..4fc77e9 100644
--- a/arm-fm-22k/lib_src/eas_pcm.h
+++ b/arm-fm-22k/lib_src/eas_pcm.h
@@ -1,13 +1,13 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_pcm.h
- *
- * Contents and purpose:
- * External function prototypes for eas_pcm.c module
- *
- *
- * Copyright Sonic Network Inc. 2005
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_pcm.h
+ *
+ * Contents and purpose:
+ * External function prototypes for eas_pcm.c module
+ *
+ *
+ * Copyright Sonic Network Inc. 2005
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,340 +20,340 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 847 $
- * $Date: 2007-08-27 21:30:08 -0700 (Mon, 27 Aug 2007) $
- *----------------------------------------------------------------------------
-*/
-
-#ifndef _EAS_PCM_H
-#define _EAS_PCM_H
-
-/* default gain setting - roughly unity gain */
-#define PCM_DEFAULT_GAIN_SETTING 0x6000
-
-typedef struct s_pcm_state_tag *EAS_PCM_HANDLE;
-typedef void (*EAS_PCM_CALLBACK) (EAS_DATA_HANDLE pEASData, EAS_VOID_PTR cbInstData, EAS_PCM_HANDLE pcmHandle, EAS_STATE state);
-
-/* parameters for EAS_PEOpenStream */
-typedef struct s_pcm_open_params_tag
-{
- EAS_FILE_HANDLE fileHandle;
- EAS_I32 decoder;
- EAS_U32 sampleRate;
- EAS_I32 size;
- EAS_U32 loopStart;
- EAS_U32 loopSamples;
- EAS_I32 blockSize;
- EAS_U32 flags;
- EAS_U32 envData;
- EAS_I16 volume;
- EAS_PCM_CALLBACK pCallbackFunc;
- EAS_VOID_PTR cbInstData;
- } S_PCM_OPEN_PARAMS;
-
-/*----------------------------------------------------------------------------
- * EAS_PEInit()
- *----------------------------------------------------------------------------
- * Purpose:
- * Initializes the PCM engine
- *
- * Inputs:
- *
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT EAS_PEInit (EAS_DATA_HANDLE pEASData);
-
-/*----------------------------------------------------------------------------
- * EAS_PEShutdown()
- *----------------------------------------------------------------------------
- * Purpose:
- * Shuts down the PCM engine
- *
- * Inputs:
- *
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT EAS_PEShutdown (EAS_DATA_HANDLE pEASData);
-
-/*----------------------------------------------------------------------------
- * EAS_PEOpenStream()
- *----------------------------------------------------------------------------
- * Purpose:
- * Starts up a PCM playback
- *
- * Inputs:
- *
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT EAS_PEOpenStream (EAS_DATA_HANDLE pEASData, S_PCM_OPEN_PARAMS *pParams, EAS_PCM_HANDLE *pHandle);
-
-/*----------------------------------------------------------------------------
- * EAS_PEContinueStream()
- *----------------------------------------------------------------------------
- * Purpose:
- * Continues a PCM stream
- *
- * Inputs:
- *
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT EAS_PEContinueStream (EAS_DATA_HANDLE pEASData, EAS_PCM_HANDLE handle, EAS_I32 size);
-
-/*----------------------------------------------------------------------------
- * EAS_PEGetFileHandle()
- *----------------------------------------------------------------------------
- * Purpose:
- * Returns the file handle of a stream
- *
- * Inputs:
- *
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT EAS_PEGetFileHandle (EAS_DATA_HANDLE pEASData, EAS_PCM_HANDLE handle, EAS_FILE_HANDLE *pFileHandle);
-
-/*----------------------------------------------------------------------------
- * EAS_PERender()
- *----------------------------------------------------------------------------
- * Purpose:
- * Render a buffer of PCM audio
- *
- * Inputs:
- *
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT EAS_PERender (EAS_DATA_HANDLE pEASData, EAS_I32 numSamples);
-
-/*----------------------------------------------------------------------------
- * EAS_PEUpdateParams()
- *----------------------------------------------------------------------------
- * Purpose:
- * Update the pitch and volume parameters using MIDI controls
- *
- * Inputs:
- *
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT EAS_PEUpdateParams (EAS_DATA_HANDLE pEASData, EAS_PCM_HANDLE pState, EAS_I16 pitch, EAS_I16 gainLeft, EAS_I16 gainRight);
-
-/*----------------------------------------------------------------------------
- * EAS_PELocate()
- *----------------------------------------------------------------------------
- * Purpose:
- * This function seeks to the requested place in the file. Accuracy
- * is dependent on the sample rate and block size.
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * pState - stream handle
- * time - media time in milliseconds
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT EAS_PELocate (EAS_DATA_HANDLE pEASData, EAS_PCM_HANDLE pState, EAS_I32 time);
-
-/*----------------------------------------------------------------------------
- * EAS_PEUpdateVolume()
- *----------------------------------------------------------------------------
- * Purpose:
- * Update the volume parameters for a PCM stream
- *
- * Inputs:
- * pEASData - pointer to EAS library instance data
- * handle - pointer to S_PCM_STATE for this stream
- * gainLeft - linear gain multipler in 1.15 fraction format
- * gainRight - linear gain multipler in 1.15 fraction format
- * initial - initial settings, set current gain
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- * Notes
- * In mono mode, leftGain controls the output gain and rightGain is ignored
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, pEASData) reserved for future use */
-EAS_RESULT EAS_PEUpdateVolume (EAS_DATA_HANDLE pEASData, EAS_PCM_HANDLE pState, EAS_I16 volume);
-
-/*----------------------------------------------------------------------------
- * EAS_PEUpdatePitch()
- *----------------------------------------------------------------------------
- * Purpose:
- * Update the pitch parameter for a PCM stream
- *
- * Inputs:
- * pEASData - pointer to EAS library instance data
- * pState - pointer to S_PCM_STATE for this stream
- * pitch - new pitch value in pitch cents
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, pEASData) reserved for future use */
-EAS_RESULT EAS_PEUpdatePitch (EAS_DATA_HANDLE pEASData, EAS_PCM_HANDLE pState, EAS_I16 pitch);
-
-/*----------------------------------------------------------------------------
- * EAS_PEState()
- *----------------------------------------------------------------------------
- * Purpose:
- * Returns the current state of the stream
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- * pState - pointer to variable to store state
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- * Notes:
- * This interface is also exposed in the internal library for use by the other modules.
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT EAS_PEState (EAS_DATA_HANDLE pEASData, EAS_PCM_HANDLE handle, EAS_STATE *pState);
-
-/*----------------------------------------------------------------------------
- * EAS_PEClose()
- *----------------------------------------------------------------------------
- * Purpose:
- * Close the file and clean up
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT EAS_PEClose (EAS_DATA_HANDLE pEASData, EAS_PCM_HANDLE handle);
-
-/*----------------------------------------------------------------------------
- * EAS_PEReset()
- *----------------------------------------------------------------------------
- * Purpose:
- * Reset the sequencer. Used for locating backwards in the file.
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT EAS_PEReset (EAS_DATA_HANDLE pEASData, EAS_PCM_HANDLE handle);
-
-/*----------------------------------------------------------------------------
- * EAS_PEPause()
- *----------------------------------------------------------------------------
- * Purpose:
- * Mute and pause rendering a PCM stream. Sets the gain target to zero and stops the playback
- * at the end of the next audio frame.
- *
- * Inputs:
- * pEASData - pointer to EAS library instance data
- * handle - pointer to S_PCM_STATE for this stream
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT EAS_PEPause (EAS_DATA_HANDLE pEASData, EAS_PCM_HANDLE handle);
-
-/*----------------------------------------------------------------------------
- * EAS_PEResume()
- *----------------------------------------------------------------------------
- * Purpose:
- * Resume rendering a PCM stream. Sets the gain target back to its
- * previous setting and restarts playback at the end of the next audio
- * frame.
- *
- * Inputs:
- * pEASData - pointer to EAS library instance data
- * handle - pointer to S_PCM_STATE for this stream
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT EAS_PEResume (EAS_DATA_HANDLE pEASData, EAS_PCM_HANDLE handle);
-
-/*----------------------------------------------------------------------------
- * EAS_PERelease()
- *----------------------------------------------------------------------------
- * Purpose:
- * Put the PCM stream envelope into release.
- *
- * Inputs:
- * pEASData - pointer to EAS library instance data
- * handle - pointer to S_PCM_STATE for this stream
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT EAS_PERelease (EAS_DATA_HANDLE pEASData, EAS_PCM_HANDLE handle);
-
-#endif /* end _EAS_PCM_H */
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 847 $
+ * $Date: 2007-08-27 21:30:08 -0700 (Mon, 27 Aug 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+#ifndef _EAS_PCM_H
+#define _EAS_PCM_H
+
+/* default gain setting - roughly unity gain */
+#define PCM_DEFAULT_GAIN_SETTING 0x6000
+
+typedef struct s_pcm_state_tag *EAS_PCM_HANDLE;
+typedef void (*EAS_PCM_CALLBACK) (EAS_DATA_HANDLE pEASData, EAS_VOID_PTR cbInstData, EAS_PCM_HANDLE pcmHandle, EAS_STATE state);
+
+/* parameters for EAS_PEOpenStream */
+typedef struct s_pcm_open_params_tag
+{
+ EAS_FILE_HANDLE fileHandle;
+ EAS_I32 decoder;
+ EAS_U32 sampleRate;
+ EAS_I32 size;
+ EAS_U32 loopStart;
+ EAS_U32 loopSamples;
+ EAS_I32 blockSize;
+ EAS_U32 flags;
+ EAS_U32 envData;
+ EAS_I16 volume;
+ EAS_PCM_CALLBACK pCallbackFunc;
+ EAS_VOID_PTR cbInstData;
+ } S_PCM_OPEN_PARAMS;
+
+/*----------------------------------------------------------------------------
+ * EAS_PEInit()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Initializes the PCM engine
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_PEInit (EAS_DATA_HANDLE pEASData);
+
+/*----------------------------------------------------------------------------
+ * EAS_PEShutdown()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Shuts down the PCM engine
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_PEShutdown (EAS_DATA_HANDLE pEASData);
+
+/*----------------------------------------------------------------------------
+ * EAS_PEOpenStream()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Starts up a PCM playback
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_PEOpenStream (EAS_DATA_HANDLE pEASData, S_PCM_OPEN_PARAMS *pParams, EAS_PCM_HANDLE *pHandle);
+
+/*----------------------------------------------------------------------------
+ * EAS_PEContinueStream()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Continues a PCM stream
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_PEContinueStream (EAS_DATA_HANDLE pEASData, EAS_PCM_HANDLE handle, EAS_I32 size);
+
+/*----------------------------------------------------------------------------
+ * EAS_PEGetFileHandle()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Returns the file handle of a stream
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_PEGetFileHandle (EAS_DATA_HANDLE pEASData, EAS_PCM_HANDLE handle, EAS_FILE_HANDLE *pFileHandle);
+
+/*----------------------------------------------------------------------------
+ * EAS_PERender()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Render a buffer of PCM audio
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_PERender (EAS_DATA_HANDLE pEASData, EAS_I32 numSamples);
+
+/*----------------------------------------------------------------------------
+ * EAS_PEUpdateParams()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Update the pitch and volume parameters using MIDI controls
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_PEUpdateParams (EAS_DATA_HANDLE pEASData, EAS_PCM_HANDLE pState, EAS_I16 pitch, EAS_I16 gainLeft, EAS_I16 gainRight);
+
+/*----------------------------------------------------------------------------
+ * EAS_PELocate()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * This function seeks to the requested place in the file. Accuracy
+ * is dependent on the sample rate and block size.
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * pState - stream handle
+ * time - media time in milliseconds
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_PELocate (EAS_DATA_HANDLE pEASData, EAS_PCM_HANDLE pState, EAS_I32 time);
+
+/*----------------------------------------------------------------------------
+ * EAS_PEUpdateVolume()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Update the volume parameters for a PCM stream
+ *
+ * Inputs:
+ * pEASData - pointer to EAS library instance data
+ * handle - pointer to S_PCM_STATE for this stream
+ * gainLeft - linear gain multipler in 1.15 fraction format
+ * gainRight - linear gain multipler in 1.15 fraction format
+ * initial - initial settings, set current gain
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ * Notes
+ * In mono mode, leftGain controls the output gain and rightGain is ignored
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pEASData) reserved for future use */
+EAS_RESULT EAS_PEUpdateVolume (EAS_DATA_HANDLE pEASData, EAS_PCM_HANDLE pState, EAS_I16 volume);
+
+/*----------------------------------------------------------------------------
+ * EAS_PEUpdatePitch()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Update the pitch parameter for a PCM stream
+ *
+ * Inputs:
+ * pEASData - pointer to EAS library instance data
+ * pState - pointer to S_PCM_STATE for this stream
+ * pitch - new pitch value in pitch cents
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pEASData) reserved for future use */
+EAS_RESULT EAS_PEUpdatePitch (EAS_DATA_HANDLE pEASData, EAS_PCM_HANDLE pState, EAS_I16 pitch);
+
+/*----------------------------------------------------------------------------
+ * EAS_PEState()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Returns the current state of the stream
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ * pState - pointer to variable to store state
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ * Notes:
+ * This interface is also exposed in the internal library for use by the other modules.
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_PEState (EAS_DATA_HANDLE pEASData, EAS_PCM_HANDLE handle, EAS_STATE *pState);
+
+/*----------------------------------------------------------------------------
+ * EAS_PEClose()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Close the file and clean up
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_PEClose (EAS_DATA_HANDLE pEASData, EAS_PCM_HANDLE handle);
+
+/*----------------------------------------------------------------------------
+ * EAS_PEReset()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Reset the sequencer. Used for locating backwards in the file.
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_PEReset (EAS_DATA_HANDLE pEASData, EAS_PCM_HANDLE handle);
+
+/*----------------------------------------------------------------------------
+ * EAS_PEPause()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Mute and pause rendering a PCM stream. Sets the gain target to zero and stops the playback
+ * at the end of the next audio frame.
+ *
+ * Inputs:
+ * pEASData - pointer to EAS library instance data
+ * handle - pointer to S_PCM_STATE for this stream
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_PEPause (EAS_DATA_HANDLE pEASData, EAS_PCM_HANDLE handle);
+
+/*----------------------------------------------------------------------------
+ * EAS_PEResume()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Resume rendering a PCM stream. Sets the gain target back to its
+ * previous setting and restarts playback at the end of the next audio
+ * frame.
+ *
+ * Inputs:
+ * pEASData - pointer to EAS library instance data
+ * handle - pointer to S_PCM_STATE for this stream
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_PEResume (EAS_DATA_HANDLE pEASData, EAS_PCM_HANDLE handle);
+
+/*----------------------------------------------------------------------------
+ * EAS_PERelease()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Put the PCM stream envelope into release.
+ *
+ * Inputs:
+ * pEASData - pointer to EAS library instance data
+ * handle - pointer to S_PCM_STATE for this stream
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_PERelease (EAS_DATA_HANDLE pEASData, EAS_PCM_HANDLE handle);
+
+#endif /* end _EAS_PCM_H */
+
diff --git a/arm-fm-22k/lib_src/eas_pcmdata.c b/arm-fm-22k/lib_src/eas_pcmdata.c
index 5649f07..2d85ac2 100644
--- a/arm-fm-22k/lib_src/eas_pcmdata.c
+++ b/arm-fm-22k/lib_src/eas_pcmdata.c
@@ -1,12 +1,12 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_pcmdata.c
- *
- * Contents and purpose:
- * Contains the static data for the PCM engine.
- *
- * Copyright Sonic Network Inc. 2005
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_pcmdata.c
+ *
+ * Contents and purpose:
+ * Contains the static data for the PCM engine.
+ *
+ * Copyright Sonic Network Inc. 2005
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,17 +19,17 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 547 $
- * $Date: 2007-01-31 16:30:17 -0800 (Wed, 31 Jan 2007) $
- *----------------------------------------------------------------------------
-*/
-
-#include "eas_data.h"
-
-/* static data allocation */
-S_PCM_STATE eas_PCMData[MAX_PCM_STREAMS];
-
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 547 $
+ * $Date: 2007-01-31 16:30:17 -0800 (Wed, 31 Jan 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+#include "eas_data.h"
+
+/* static data allocation */
+S_PCM_STATE eas_PCMData[MAX_PCM_STREAMS];
+
+
diff --git a/arm-fm-22k/lib_src/eas_pcmdata.h b/arm-fm-22k/lib_src/eas_pcmdata.h
index be2f8e5..ae18d6d 100644
--- a/arm-fm-22k/lib_src/eas_pcmdata.h
+++ b/arm-fm-22k/lib_src/eas_pcmdata.h
@@ -1,13 +1,13 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_pcmdata.h
- *
- * Contents and purpose:
- * Data declarations for the PCM engine
- *
- *
- * Copyright Sonic Network Inc. 2005
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_pcmdata.h
+ *
+ * Contents and purpose:
+ * Data declarations for the PCM engine
+ *
+ *
+ * Copyright Sonic Network Inc. 2005
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,138 +20,138 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 847 $
- * $Date: 2007-08-27 21:30:08 -0700 (Mon, 27 Aug 2007) $
- *----------------------------------------------------------------------------
-*/
-
-#ifndef _EAS_PCMDATA_H
-#define _EAS_PCMDATA_H
-
-/* sets the maximum number of simultaneous PCM streams */
-#ifndef MAX_PCM_STREAMS
-#define MAX_PCM_STREAMS 16
-#define PCM_STREAM_THRESHOLD (MAX_PCM_STREAMS - 4)
-#endif
-
-/* coefficents for high-pass filter in ADPCM */
-#define INTEGRATOR_COEFFICIENT 100 /* coefficient for leaky integrator */
-
-/* additional flags in S_PCM_STATE.flags used internal to module */
-#define PCM_FLAGS_EMPTY 0x01000000 /* unsigned format */
-
-/*----------------------------------------------------------------------------
- * S_PCM_STATE
- *
- * Retains state information for PCM streams.
- *----------------------------------------------------------------------------
-*/
-typedef struct s_decoder_state_tag
-{
- EAS_I32 output; /* last output for DC offset filter */
- EAS_I32 acc; /* accumulator for DC offset filter */
- EAS_I32 step; /* current ADPCM step size */
- EAS_PCM x1; /* current generated sample */
- EAS_PCM x0; /* previous generated sample */
-} S_DECODER_STATE;
-
-typedef enum
-{
- PCM_ENV_START = 0,
- PCM_ENV_ATTACK,
- PCM_ENV_DECAY,
- PCM_ENV_SUSTAIN,
- PCM_ENV_RELEASE,
- PCM_ENV_END
-} E_PCM_ENV_STATE;
-
-typedef struct s_pcm_state_tag
-{
-#ifdef _CHECKED_BUILD
- EAS_U32 handleCheck; /* signature check for checked build */
-#endif
- EAS_FILE_HANDLE fileHandle; /* pointer to input file */
- EAS_PCM_CALLBACK pCallback; /* pointer to callback function */
- EAS_VOID_PTR cbInstData; /* instance data for callback function */
- struct s_decoder_interface_tag EAS_CONST * pDecoder; /* pointer to decoder interface */
- EAS_STATE state; /* stream state */
- EAS_I32 time; /* media time */
- EAS_I32 startPos; /* start of PCM stream */
- EAS_I32 loopLocation; /* file location where loop starts */
- EAS_I32 byteCount; /* size of file */
- EAS_U32 loopStart; /* loop start, offset in samples from startPos */
- /* NOTE: For CMF, we use this to store total sample size */
- EAS_U32 loopSamples; /* total loop length, in samples, 0 means no loop */
- /* NOTE: For CMF, non-zero means looped */
- EAS_U32 samplesInLoop; /* samples left in the loop to play back */
- EAS_I32 samplesTilLoop; /* samples left to play until top of loop */
- EAS_I32 bytesLeft; /* count of bytes left in stream */
- EAS_I32 bytesLeftLoop; /* count of bytes left in stream, value at start of loop */
- EAS_U32 phase; /* current phase for interpolator */
- EAS_U32 basefreq; /* frequency multiplier */
- EAS_U32 flags; /* stream flags */
- EAS_U32 envData; /* envelope data (and LFO data) */
- EAS_U32 envValue; /* current envelope value */
- EAS_U32 envScale; /* current envelope scale */
- EAS_U32 startOrder; /* start order index, first is 0, next is 1, etc. */
- S_DECODER_STATE decoderL; /* left (mono) ADPCM state */
- S_DECODER_STATE decoderR; /* right ADPCM state */
- S_DECODER_STATE decoderLLoop; /* left (mono) ADPCM state, value at start of loop */
- S_DECODER_STATE decoderRLoop; /* right ADPCM state, value at start of loop */
- E_PCM_ENV_STATE envState; /* current envelope state */
- EAS_I16 volume; /* volume for stream */
- EAS_I16 pitch; /* relative pitch in cents - zero is unity playback */
- EAS_I16 gainLeft; /* requested gain */
- EAS_I16 gainRight; /* requested gain */
- EAS_I16 currentGainLeft; /* current gain for anti-zipper filter */
- EAS_I16 currentGainRight; /* current gain for anti-zipper filter */
- EAS_U16 blockSize; /* block size for ADPCM decoder */
- EAS_U16 blockCount; /* block counter for ADPCM decoder */
- EAS_U16 sampleRate; /* input sample rate */
- EAS_U8 srcByte; /* source byte */
- EAS_U8 msBitCount; /* count keeps track of MS bits */
- EAS_U8 msBitMask; /* mask keeps track of MS bits */
- EAS_U8 msBitValue; /* value keeps track of MS bits */
- EAS_U8 msBitCountLoop; /* count keeps track of MS bits, value at loop start */
- EAS_U8 msBitMaskLoop; /* mask keeps track of MS bits, value at loop start */
- EAS_U8 msBitValueLoop; /* value keeps track of MS bits, value at loop start */
- EAS_BOOL8 hiNibble; /* indicates high/low nibble is next */
- EAS_BOOL8 hiNibbleLoop; /* indicates high/low nibble is next, value loop start */
- EAS_U8 rateShift; /* for playback rate greater than 1.0 */
-} S_PCM_STATE;
-
-/*----------------------------------------------------------------------------
- * S_DECODER_INTERFACE
- *
- * Generic interface for audio decoders
- *----------------------------------------------------------------------------
-*/
-typedef struct s_decoder_interface_tag
-{
- EAS_RESULT (* EAS_CONST pfInit)(EAS_DATA_HANDLE pEASData, S_PCM_STATE *pState);
- EAS_RESULT (* EAS_CONST pfDecodeSample)(EAS_DATA_HANDLE pEASData, S_PCM_STATE *pState);
- EAS_RESULT (* EAS_CONST pfLocate)(EAS_DATA_HANDLE pEASData, S_PCM_STATE *pState, EAS_I32 time);
-} S_DECODER_INTERFACE;
-
-
-/* header chunk for SMAF ADPCM */
-#define TAG_YAMAHA_ADPCM 0x4d776100
-#define TAG_MASK 0xffffff00
-#define TAG_RIFF_FILE 0x52494646
-#define TAG_WAVE_CHUNK 0x57415645
-#define TAG_FMT_CHUNK 0x666d7420
-
-/*----------------------------------------------------------------------------
- * EAS_PESeek
- *----------------------------------------------------------------------------
- * Purpose:
- * Locate to a particular byte in a PCM stream
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT EAS_PESeek (EAS_DATA_HANDLE pEASData, S_PCM_STATE *pState, EAS_I32 *pLocation);
-
-#endif /* _EAS_PCMDATA_H */
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 847 $
+ * $Date: 2007-08-27 21:30:08 -0700 (Mon, 27 Aug 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+#ifndef _EAS_PCMDATA_H
+#define _EAS_PCMDATA_H
+
+/* sets the maximum number of simultaneous PCM streams */
+#ifndef MAX_PCM_STREAMS
+#define MAX_PCM_STREAMS 16
+#define PCM_STREAM_THRESHOLD (MAX_PCM_STREAMS - 4)
+#endif
+
+/* coefficents for high-pass filter in ADPCM */
+#define INTEGRATOR_COEFFICIENT 100 /* coefficient for leaky integrator */
+
+/* additional flags in S_PCM_STATE.flags used internal to module */
+#define PCM_FLAGS_EMPTY 0x01000000 /* unsigned format */
+
+/*----------------------------------------------------------------------------
+ * S_PCM_STATE
+ *
+ * Retains state information for PCM streams.
+ *----------------------------------------------------------------------------
+*/
+typedef struct s_decoder_state_tag
+{
+ EAS_I32 output; /* last output for DC offset filter */
+ EAS_I32 acc; /* accumulator for DC offset filter */
+ EAS_I32 step; /* current ADPCM step size */
+ EAS_PCM x1; /* current generated sample */
+ EAS_PCM x0; /* previous generated sample */
+} S_DECODER_STATE;
+
+typedef enum
+{
+ PCM_ENV_START = 0,
+ PCM_ENV_ATTACK,
+ PCM_ENV_DECAY,
+ PCM_ENV_SUSTAIN,
+ PCM_ENV_RELEASE,
+ PCM_ENV_END
+} E_PCM_ENV_STATE;
+
+typedef struct s_pcm_state_tag
+{
+#ifdef _CHECKED_BUILD
+ EAS_U32 handleCheck; /* signature check for checked build */
+#endif
+ EAS_FILE_HANDLE fileHandle; /* pointer to input file */
+ EAS_PCM_CALLBACK pCallback; /* pointer to callback function */
+ EAS_VOID_PTR cbInstData; /* instance data for callback function */
+ struct s_decoder_interface_tag EAS_CONST * pDecoder; /* pointer to decoder interface */
+ EAS_STATE state; /* stream state */
+ EAS_I32 time; /* media time */
+ EAS_I32 startPos; /* start of PCM stream */
+ EAS_I32 loopLocation; /* file location where loop starts */
+ EAS_I32 byteCount; /* size of file */
+ EAS_U32 loopStart; /* loop start, offset in samples from startPos */
+ /* NOTE: For CMF, we use this to store total sample size */
+ EAS_U32 loopSamples; /* total loop length, in samples, 0 means no loop */
+ /* NOTE: For CMF, non-zero means looped */
+ EAS_U32 samplesInLoop; /* samples left in the loop to play back */
+ EAS_I32 samplesTilLoop; /* samples left to play until top of loop */
+ EAS_I32 bytesLeft; /* count of bytes left in stream */
+ EAS_I32 bytesLeftLoop; /* count of bytes left in stream, value at start of loop */
+ EAS_U32 phase; /* current phase for interpolator */
+ EAS_U32 basefreq; /* frequency multiplier */
+ EAS_U32 flags; /* stream flags */
+ EAS_U32 envData; /* envelope data (and LFO data) */
+ EAS_U32 envValue; /* current envelope value */
+ EAS_U32 envScale; /* current envelope scale */
+ EAS_U32 startOrder; /* start order index, first is 0, next is 1, etc. */
+ S_DECODER_STATE decoderL; /* left (mono) ADPCM state */
+ S_DECODER_STATE decoderR; /* right ADPCM state */
+ S_DECODER_STATE decoderLLoop; /* left (mono) ADPCM state, value at start of loop */
+ S_DECODER_STATE decoderRLoop; /* right ADPCM state, value at start of loop */
+ E_PCM_ENV_STATE envState; /* current envelope state */
+ EAS_I16 volume; /* volume for stream */
+ EAS_I16 pitch; /* relative pitch in cents - zero is unity playback */
+ EAS_I16 gainLeft; /* requested gain */
+ EAS_I16 gainRight; /* requested gain */
+ EAS_I16 currentGainLeft; /* current gain for anti-zipper filter */
+ EAS_I16 currentGainRight; /* current gain for anti-zipper filter */
+ EAS_U16 blockSize; /* block size for ADPCM decoder */
+ EAS_U16 blockCount; /* block counter for ADPCM decoder */
+ EAS_U16 sampleRate; /* input sample rate */
+ EAS_U8 srcByte; /* source byte */
+ EAS_U8 msBitCount; /* count keeps track of MS bits */
+ EAS_U8 msBitMask; /* mask keeps track of MS bits */
+ EAS_U8 msBitValue; /* value keeps track of MS bits */
+ EAS_U8 msBitCountLoop; /* count keeps track of MS bits, value at loop start */
+ EAS_U8 msBitMaskLoop; /* mask keeps track of MS bits, value at loop start */
+ EAS_U8 msBitValueLoop; /* value keeps track of MS bits, value at loop start */
+ EAS_BOOL8 hiNibble; /* indicates high/low nibble is next */
+ EAS_BOOL8 hiNibbleLoop; /* indicates high/low nibble is next, value loop start */
+ EAS_U8 rateShift; /* for playback rate greater than 1.0 */
+} S_PCM_STATE;
+
+/*----------------------------------------------------------------------------
+ * S_DECODER_INTERFACE
+ *
+ * Generic interface for audio decoders
+ *----------------------------------------------------------------------------
+*/
+typedef struct s_decoder_interface_tag
+{
+ EAS_RESULT (* EAS_CONST pfInit)(EAS_DATA_HANDLE pEASData, S_PCM_STATE *pState);
+ EAS_RESULT (* EAS_CONST pfDecodeSample)(EAS_DATA_HANDLE pEASData, S_PCM_STATE *pState);
+ EAS_RESULT (* EAS_CONST pfLocate)(EAS_DATA_HANDLE pEASData, S_PCM_STATE *pState, EAS_I32 time);
+} S_DECODER_INTERFACE;
+
+
+/* header chunk for SMAF ADPCM */
+#define TAG_YAMAHA_ADPCM 0x4d776100
+#define TAG_MASK 0xffffff00
+#define TAG_RIFF_FILE 0x52494646
+#define TAG_WAVE_CHUNK 0x57415645
+#define TAG_FMT_CHUNK 0x666d7420
+
+/*----------------------------------------------------------------------------
+ * EAS_PESeek
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Locate to a particular byte in a PCM stream
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_PESeek (EAS_DATA_HANDLE pEASData, S_PCM_STATE *pState, EAS_I32 *pLocation);
+
+#endif /* _EAS_PCMDATA_H */
+
diff --git a/arm-fm-22k/lib_src/eas_public.c b/arm-fm-22k/lib_src/eas_public.c
index ac43261..394a9a1 100644
--- a/arm-fm-22k/lib_src/eas_public.c
+++ b/arm-fm-22k/lib_src/eas_public.c
@@ -1,12 +1,12 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_public.c
- *
- * Contents and purpose:
- * Contains EAS library public interface
- *
- * Copyright Sonic Network Inc. 2004
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_public.c
+ *
+ * Contents and purpose:
+ * Contains EAS library public interface
+ *
+ * Copyright Sonic Network Inc. 2004
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,2579 +19,2579 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 842 $
- * $Date: 2007-08-23 14:32:31 -0700 (Thu, 23 Aug 2007) $
- *----------------------------------------------------------------------------
-*/
-
-#include "eas_synthcfg.h"
-#include "eas.h"
-#include "eas_config.h"
-#include "eas_host.h"
-#include "eas_report.h"
-#include "eas_data.h"
-#include "eas_parser.h"
-#include "eas_pcm.h"
-#include "eas_midi.h"
-#include "eas_mixer.h"
-#include "eas_build.h"
-#include "eas_vm_protos.h"
-#include "eas_math.h"
-
-#ifdef JET_INTERFACE
-#include "jet_data.h"
-#endif
-
-#ifdef DLS_SYNTHESIZER
-#include "eas_mdls.h"
-#endif
-
-/* number of events to parse before calling EAS_HWYield function */
-#define YIELD_EVENT_COUNT 10
-
-/*----------------------------------------------------------------------------
- * easLibConfig
- *
- * This structure is available through the EAS public interface to allow
- * the user to check the configuration of the library.
- *----------------------------------------------------------------------------
-*/
-static const S_EAS_LIB_CONFIG easLibConfig =
-{
- LIB_VERSION,
-#ifdef _CHECKED_BUILD
- EAS_TRUE,
-#else
- EAS_FALSE,
-#endif
- MAX_SYNTH_VOICES,
- NUM_OUTPUT_CHANNELS,
- _OUTPUT_SAMPLE_RATE,
- BUFFER_SIZE_IN_MONO_SAMPLES,
-#ifdef _FILTER_ENABLED
- EAS_TRUE,
-#else
- EAS_FALSE,
-#endif
- _BUILD_TIME_,
- _BUILD_VERSION_
-};
-
-/* local prototypes */
-static EAS_RESULT EAS_ParseEvents (S_EAS_DATA *pEASData, S_EAS_STREAM *pStream, EAS_U32 endTime, EAS_INT parseMode);
-
-/*----------------------------------------------------------------------------
- * EAS_SetStreamParameter
- *----------------------------------------------------------------------------
- * Sets the specified parameter in the stream. Allows access to
- * customizable settings within the individual file parsers.
- *----------------------------------------------------------------------------
- * pEASData - pointer to EAS persistent data object
- * pStream - stream handle
- * param - enumerated parameter (see eas_parser.h)
- * value - new value
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT EAS_SetStreamParameter (S_EAS_DATA *pEASData, EAS_HANDLE pStream, EAS_I32 param, EAS_I32 value)
-{
- S_FILE_PARSER_INTERFACE *pParserModule;
-
- pParserModule = (S_FILE_PARSER_INTERFACE*) pStream->pParserModule;
- if (pParserModule->pfSetData)
- return (*pParserModule->pfSetData)(pEASData, pStream->handle, param, value);
- return EAS_ERROR_FEATURE_NOT_AVAILABLE;
-}
-
-/*----------------------------------------------------------------------------
- * EAS_GetStreamParameter
- *----------------------------------------------------------------------------
- * Sets the specified parameter in the stream. Allows access to
- * customizable settings within the individual file parsers.
- *----------------------------------------------------------------------------
- * pEASData - pointer to EAS persistent data object
- * pStream - stream handle
- * param - enumerated parameter (see eas_parser.h)
- * pValue - pointer to variable to receive current setting
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT EAS_GetStreamParameter (S_EAS_DATA *pEASData, EAS_HANDLE pStream, EAS_I32 param, EAS_I32 *pValue)
-{
- S_FILE_PARSER_INTERFACE *pParserModule;
-
- pParserModule = (S_FILE_PARSER_INTERFACE*) pStream->pParserModule;
- if (pParserModule->pfGetData)
- return (*pParserModule->pfGetData)(pEASData, pStream->handle, param, pValue);
- return EAS_ERROR_FEATURE_NOT_AVAILABLE;
-}
-
-/*----------------------------------------------------------------------------
- * EAS_StreamReady()
- *----------------------------------------------------------------------------
- * This routine sets common parameters like transpose, volume, etc.
- * First, it attempts to use the parser EAS_SetStreamParameter interface. If that
- * fails, it attempts to get the synth handle from the parser and
- * set the parameter directly on the synth. This eliminates duplicate
- * code in the parser.
- *----------------------------------------------------------------------------
-*/
-EAS_BOOL EAS_StreamReady (S_EAS_DATA *pEASData, EAS_HANDLE pStream)
-{
- S_FILE_PARSER_INTERFACE *pParserModule;
- EAS_STATE state;
-
- pParserModule = (S_FILE_PARSER_INTERFACE*) pStream->pParserModule;
- if (pParserModule->pfState(pEASData, pStream->handle, &state) != EAS_SUCCESS)
- return EAS_FALSE;
- return (state < EAS_STATE_OPEN);
-}
-
-/*----------------------------------------------------------------------------
- * EAS_IntSetStrmParam()
- *----------------------------------------------------------------------------
- * This routine sets common parameters like transpose, volume, etc.
- * First, it attempts to use the parser EAS_SetStreamParameter interface. If that
- * fails, it attempts to get the synth handle from the parser and
- * set the parameter directly on the synth. This eliminates duplicate
- * code in the parser.
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT EAS_IntSetStrmParam (S_EAS_DATA *pEASData, EAS_HANDLE pStream, EAS_INT param, EAS_I32 value)
-{
- S_SYNTH *pSynth;
-
- /* try to set the parameter using stream interface */
- if (EAS_SetStreamParameter(pEASData, pStream, param, value) == EAS_SUCCESS)
- return EAS_SUCCESS;
-
- /* get a pointer to the synth object and set it directly */
- /*lint -e{740} we are cheating by passing a pointer through this interface */
- if (EAS_GetStreamParameter(pEASData, pStream, PARSER_DATA_SYNTH_HANDLE, (EAS_I32*) &pSynth) != EAS_SUCCESS)
- return EAS_ERROR_INVALID_PARAMETER;
-
- if (pSynth == NULL)
- return EAS_ERROR_INVALID_PARAMETER;
-
- switch (param)
- {
-
-#ifdef DLS_SYNTHESIZER
- case PARSER_DATA_DLS_COLLECTION:
- {
- EAS_RESULT result = VMSetDLSLib(pSynth, (EAS_DLSLIB_HANDLE) value);
- if (result == EAS_SUCCESS)
- {
- DLSAddRef((S_DLS*) value);
- VMInitializeAllChannels(pEASData->pVoiceMgr, pSynth);
- }
- return result;
- }
-#endif
-
- case PARSER_DATA_EAS_LIBRARY:
- return VMSetEASLib(pSynth, (EAS_SNDLIB_HANDLE) value);
-
- case PARSER_DATA_POLYPHONY:
- return VMSetPolyphony(pEASData->pVoiceMgr, pSynth, value);
-
- case PARSER_DATA_PRIORITY:
- return VMSetPriority(pEASData->pVoiceMgr, pSynth, value);
-
- case PARSER_DATA_TRANSPOSITION:
- VMSetTranposition(pSynth, value);
- break;
-
- case PARSER_DATA_VOLUME:
- VMSetVolume(pSynth, (EAS_U16) value);
- break;
-
- default:
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Invalid paramter %d in call to EAS_IntSetStrmParam", param); */ }
- return EAS_ERROR_INVALID_PARAMETER;
- }
-
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * EAS_IntGetStrmParam()
- *----------------------------------------------------------------------------
- * This routine gets common parameters like transpose, volume, etc.
- * First, it attempts to use the parser EAS_GetStreamParameter interface. If that
- * fails, it attempts to get the synth handle from the parser and
- * get the parameter directly on the synth.
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT EAS_IntGetStrmParam (S_EAS_DATA *pEASData, EAS_HANDLE pStream, EAS_INT param, EAS_I32 *pValue)
-{
- S_SYNTH *pSynth;
-
- /* try to set the parameter */
- if (EAS_GetStreamParameter(pEASData, pStream, param, pValue) == EAS_SUCCESS)
- return EAS_SUCCESS;
-
- /* get a pointer to the synth object and retrieve data directly */
- /*lint -e{740} we are cheating by passing a pointer through this interface */
- if (EAS_GetStreamParameter(pEASData, pStream, PARSER_DATA_SYNTH_HANDLE, (EAS_I32*) &pSynth) != EAS_SUCCESS)
- return EAS_ERROR_INVALID_PARAMETER;
-
- if (pSynth == NULL)
- return EAS_ERROR_INVALID_PARAMETER;
-
- switch (param)
- {
- case PARSER_DATA_POLYPHONY:
- return VMGetPolyphony(pEASData->pVoiceMgr, pSynth, pValue);
-
- case PARSER_DATA_PRIORITY:
- return VMGetPriority(pEASData->pVoiceMgr, pSynth, pValue);
-
- case PARSER_DATA_TRANSPOSITION:
- VMGetTranposition(pSynth, pValue);
- break;
-
- case PARSER_DATA_NOTE_COUNT:
- *pValue = VMGetNoteCount(pSynth);
- break;
-
- default:
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Invalid paramter %d in call to EAS_IntSetStrmParam", param); */ }
- return EAS_ERROR_INVALID_PARAMETER;
- }
-
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * EAS_AllocateStream()
- *----------------------------------------------------------------------------
- * Purpose:
- * Allocates a stream handle
- *
- * Inputs:
- *
- * Outputs:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_INT EAS_AllocateStream (EAS_DATA_HANDLE pEASData)
-{
- EAS_INT streamNum;
-
- /* check for static allocation, only one stream allowed */
- if (pEASData->staticMemoryModel)
- {
- if (pEASData->streams[0].handle != NULL)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Attempt to open multiple streams in static model\n"); */ }
- return -1;
- }
- return 0;
- }
-
- /* dynamic model */
- for (streamNum = 0; streamNum < MAX_NUMBER_STREAMS; streamNum++)
- if (pEASData->streams[streamNum].handle == NULL)
- break;
- if (streamNum == MAX_NUMBER_STREAMS)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Exceeded maximum number of open streams\n"); */ }
- return -1;
- }
- return streamNum;
-}
-
-/*----------------------------------------------------------------------------
- * EAS_InitStream()
- *----------------------------------------------------------------------------
- * Purpose:
- * Initialize a stream
- *
- * Inputs:
- *
- * Outputs:
- *
- *----------------------------------------------------------------------------
-*/
-static void EAS_InitStream (S_EAS_STREAM *pStream, EAS_VOID_PTR pParserModule, EAS_VOID_PTR streamHandle)
-{
- pStream->pParserModule = pParserModule;
- pStream->handle = streamHandle;
- pStream->time = 0;
- pStream->frameLength = AUDIO_FRAME_LENGTH;
- pStream->repeatCount = 0;
- pStream->volume = DEFAULT_STREAM_VOLUME;
-}
-
-/*----------------------------------------------------------------------------
- * EAS_Config()
- *----------------------------------------------------------------------------
- * Purpose:
- * Returns a pointer to a structure containing the configuration options
- * in this library build.
- *
- * Inputs:
- *
- * Outputs:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC const S_EAS_LIB_CONFIG *EAS_Config (void)
-{
- return &easLibConfig;
-}
-
-/*----------------------------------------------------------------------------
- * EAS_Init()
- *----------------------------------------------------------------------------
- * Purpose:
- * Initialize the synthesizer library
- *
- * Inputs:
- * ppEASData - pointer to data handle variable for this instance
- *
- * Outputs:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_Init (EAS_DATA_HANDLE *ppEASData)
-{
- EAS_HW_DATA_HANDLE pHWInstData;
- EAS_RESULT result;
- S_EAS_DATA *pEASData;
- EAS_INT module;
- EAS_BOOL staticMemoryModel;
-
- /* get the memory model */
- staticMemoryModel = EAS_CMStaticMemoryModel();
-
- /* initialize the host wrapper interface */
- *ppEASData = NULL;
- if ((result = EAS_HWInit(&pHWInstData)) != EAS_SUCCESS)
- return result;
-
- /* check Configuration Module for S_EAS_DATA allocation */
- if (staticMemoryModel)
- pEASData = EAS_CMEnumData(EAS_CM_EAS_DATA);
- else
- pEASData = EAS_HWMalloc(pHWInstData, sizeof(S_EAS_DATA));
- if (!pEASData)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_FATAL, "Failed to allocate EAS library memory\n"); */ }
- return EAS_ERROR_MALLOC_FAILED;
- }
-
- /* initialize some data */
- EAS_HWMemSet(pEASData, 0, sizeof(S_EAS_DATA));
- pEASData->staticMemoryModel = (EAS_BOOL8) staticMemoryModel;
- pEASData->hwInstData = pHWInstData;
- pEASData->renderTime = 0;
-
- /* set header search flag */
-#ifdef FILE_HEADER_SEARCH
- pEASData->searchHeaderFlag = EAS_TRUE;
-#endif
-
- /* initalize parameters */
- EAS_SetVolume(pEASData, NULL, DEFAULT_VOLUME);
-
-#ifdef _METRICS_ENABLED
- /* initalize the metrics module */
- pEASData->pMetricsModule = EAS_CMEnumOptModules(EAS_MODULE_METRICS);
- if (pEASData->pMetricsModule != NULL)
- {
- if ((result = (*pEASData->pMetricsModule->pfInit)(pEASData, &pEASData->pMetricsData)) != EAS_SUCCESS)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Error %ld initializing metrics module\n", result); */ }
- return result;
- }
- }
-#endif
-
- /* initailize the voice manager & synthesizer */
- if ((result = VMInitialize(pEASData)) != EAS_SUCCESS)
- return result;
-
- /* initialize mix engine */
- if ((result = EAS_MixEngineInit(pEASData)) != EAS_SUCCESS)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Error %ld starting up mix engine\n", result); */ }
- return result;
- }
-
- /* initialize effects modules */
- for (module = 0; module < NUM_EFFECTS_MODULES; module++)
- {
- pEASData->effectsModules[module].effect = EAS_CMEnumFXModules(module);
- if (pEASData->effectsModules[module].effect != NULL)
- {
- if ((result = (*pEASData->effectsModules[module].effect->pfInit)(pEASData, &pEASData->effectsModules[module].effectData)) != EAS_SUCCESS)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_FATAL, "Initialization of effects module %d returned %d\n", module, result); */ }
- return result;
- }
- }
- }
-
- /* initialize PCM engine */
- if ((result = EAS_PEInit(pEASData)) != EAS_SUCCESS)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_FATAL, "EAS_PEInit failed with error code %ld\n", result); */ }
- return result;
- }
-
- /* return instance data pointer to host */
- *ppEASData = pEASData;
-
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * EAS_Shutdown()
- *----------------------------------------------------------------------------
- * Purpose:
- * Shuts down the library. Deallocates any memory associated with the
- * synthesizer (dynamic memory model only)
- *
- * Inputs:
- * pEASData - handle to data for this instance
- *
- * Outputs:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_Shutdown (EAS_DATA_HANDLE pEASData)
-{
- EAS_HW_DATA_HANDLE hwInstData;
- EAS_RESULT result, reportResult;
- EAS_INT i;
-
- /* establish pointers */
- hwInstData = pEASData->hwInstData;
-
- /* check for NULL handle */
- if (!pEASData)
- return EAS_ERROR_HANDLE_INTEGRITY;
-
- /* if there are streams open, close them */
- reportResult = EAS_SUCCESS;
- for (i = 0; i < MAX_NUMBER_STREAMS; i++)
- {
- if (pEASData->streams[i].pParserModule && pEASData->streams[i].handle)
- {
- if ((result = (*((S_FILE_PARSER_INTERFACE*)(pEASData->streams[i].pParserModule))->pfClose)(pEASData, pEASData->streams[i].handle)) != EAS_SUCCESS)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Error %ld shutting down parser module\n", result); */ }
- reportResult = result;
- }
- }
- }
-
- /* shutdown PCM engine */
- if ((result = EAS_PEShutdown(pEASData)) != EAS_SUCCESS)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Error %ld shutting down PCM engine\n", result); */ }
- if (reportResult == EAS_SUCCESS)
- reportResult = result;
- }
-
- /* shutdown mix engine */
- if ((result = EAS_MixEngineShutdown(pEASData)) != EAS_SUCCESS)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Error %ld shutting down mix engine\n", result); */ }
- if (reportResult == EAS_SUCCESS)
- reportResult = result;
- }
-
- /* shutdown effects modules */
- for (i = 0; i < NUM_EFFECTS_MODULES; i++)
- {
- if (pEASData->effectsModules[i].effect)
- {
- if ((result = (*pEASData->effectsModules[i].effect->pfShutdown)(pEASData, pEASData->effectsModules[i].effectData)) != EAS_SUCCESS)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_FATAL, "Shutdown of effects module %d returned %d\n", i, result); */ }
- if (reportResult == EAS_SUCCESS)
- reportResult = result;
- }
- }
- }
-
- /* shutdown the voice manager & synthesizer */
- VMShutdown(pEASData);
-
-#ifdef _METRICS_ENABLED
- /* shutdown the metrics module */
- if (pEASData->pMetricsModule != NULL)
- {
- if ((result = (*pEASData->pMetricsModule->pfShutdown)(pEASData, pEASData->pMetricsData)) != EAS_SUCCESS)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Error %ld shutting down metrics module\n", result); */ }
- if (reportResult == EAS_SUCCESS)
- reportResult = result;
- }
- }
-#endif
-
- /* release allocated memory */
- if (!pEASData->staticMemoryModel)
- EAS_HWFree(hwInstData, pEASData);
-
- /* shutdown host wrappers */
- if (hwInstData)
- {
- if ((result = EAS_HWShutdown(hwInstData)) != EAS_SUCCESS)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Error %ld shutting down host wrappers\n", result); */ }
- if (reportResult == EAS_SUCCESS)
- reportResult = result;
- }
- }
-
- return reportResult;
-}
-
-#ifdef JET_INTERFACE
-/*----------------------------------------------------------------------------
- * EAS_OpenJETStream()
- *----------------------------------------------------------------------------
- * Private interface for JET to open an SMF stream with an offset
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT EAS_OpenJETStream (EAS_DATA_HANDLE pEASData, EAS_FILE_HANDLE fileHandle, EAS_I32 offset, EAS_HANDLE *ppStream)
-{
- EAS_RESULT result;
- EAS_VOID_PTR streamHandle;
- S_FILE_PARSER_INTERFACE *pParserModule;
- EAS_INT streamNum;
-
- /* allocate a stream */
- if ((streamNum = EAS_AllocateStream(pEASData)) < 0)
- return EAS_ERROR_MAX_STREAMS_OPEN;
-
- /* check Configuration Module for SMF parser */
- *ppStream = NULL;
- streamHandle = NULL;
- pParserModule = (S_FILE_PARSER_INTERFACE *) EAS_CMEnumModules(0);
- if (pParserModule == NULL)
- return EAS_ERROR_UNRECOGNIZED_FORMAT;
-
- /* see if SMF parser recognizes the file */
- if ((result = (*pParserModule->pfCheckFileType)(pEASData, fileHandle, &streamHandle, offset)) != EAS_SUCCESS)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "CheckFileType returned error %ld\n", result); */ }
- return result;
- }
-
- /* parser recognized the file, return the handle */
- if (streamHandle)
- {
- EAS_InitStream(&pEASData->streams[streamNum], pParserModule, streamHandle);
- *ppStream = &pEASData->streams[streamNum];
- return EAS_SUCCESS;
- }
-
- return EAS_ERROR_UNRECOGNIZED_FORMAT;
-}
-#endif
-
-/*----------------------------------------------------------------------------
- * EAS_OpenFile()
- *----------------------------------------------------------------------------
- * Purpose:
- * Opens a file for audio playback.
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * pHandle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_OpenFile (EAS_DATA_HANDLE pEASData, EAS_FILE_LOCATOR locator, EAS_HANDLE *ppStream)
-{
- EAS_RESULT result;
- EAS_FILE_HANDLE fileHandle;
- EAS_VOID_PTR streamHandle;
- S_FILE_PARSER_INTERFACE *pParserModule;
- EAS_INT streamNum;
- EAS_INT moduleNum;
-
- /* open the file */
- if ((result = EAS_HWOpenFile(pEASData->hwInstData, locator, &fileHandle, EAS_FILE_READ)) != EAS_SUCCESS)
- return result;
-
- /* allocate a stream */
- if ((streamNum = EAS_AllocateStream(pEASData)) < 0)
- return EAS_ERROR_MAX_STREAMS_OPEN;
-
- /* check Configuration Module for file parsers */
- pParserModule = NULL;
- *ppStream = NULL;
- streamHandle = NULL;
- for (moduleNum = 0; ; moduleNum++)
- {
- pParserModule = (S_FILE_PARSER_INTERFACE *) EAS_CMEnumModules(moduleNum);
- if (pParserModule == NULL)
- break;
-
- /* see if this parser recognizes it */
- if ((result = (*pParserModule->pfCheckFileType)(pEASData, fileHandle, &streamHandle, 0L)) != EAS_SUCCESS)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "CheckFileType returned error %ld\n", result); */ }
- return result;
- }
-
- /* parser recognized the file, return the handle */
- if (streamHandle)
- {
-
- /* save the parser pointer and file handle */
- EAS_InitStream(&pEASData->streams[streamNum], pParserModule, streamHandle);
- *ppStream = &pEASData->streams[streamNum];
- return EAS_SUCCESS;
- }
-
- /* rewind the file for the next parser */
- if ((result = EAS_HWFileSeek(pEASData->hwInstData, fileHandle, 0L)) != EAS_SUCCESS)
- return result;
- }
-
- /* no parser was able to recognize the file, close it and return an error */
- EAS_HWCloseFile(pEASData->hwInstData, fileHandle);
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "No parser recognized the requested file\n"); */ }
- return EAS_ERROR_UNRECOGNIZED_FORMAT;
-}
-
-#ifdef MMAPI_SUPPORT
-/*----------------------------------------------------------------------------
- * EAS_MMAPIToneControl()
- *----------------------------------------------------------------------------
- * Purpose:
- * Opens a ToneControl file for audio playback.
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * pHandle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_MMAPIToneControl (EAS_DATA_HANDLE pEASData, EAS_FILE_LOCATOR locator, EAS_HANDLE *ppStream)
-{
- EAS_RESULT result;
- EAS_FILE_HANDLE fileHandle;
- EAS_VOID_PTR streamHandle;
- S_FILE_PARSER_INTERFACE *pParserModule;
- EAS_INT streamNum;
-
- /* check if the tone control parser is available */
- *ppStream = NULL;
- streamHandle = NULL;
- pParserModule = EAS_CMEnumOptModules(EAS_MODULE_MMAPI_TONE_CONTROL);
- if (pParserModule == NULL)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "EAS_MMAPIToneControl: ToneControl parser not available\n"); */ }
- return EAS_ERROR_FEATURE_NOT_AVAILABLE;
- }
-
- /* open the file */
- if ((result = EAS_HWOpenFile(pEASData->hwInstData, locator, &fileHandle, EAS_FILE_READ)) != EAS_SUCCESS)
- return result;
-
- /* allocate a stream */
- if ((streamNum = EAS_AllocateStream(pEASData)) < 0)
- return EAS_ERROR_MAX_STREAMS_OPEN;
-
- /* see if ToneControl parser recognizes it */
- if ((result = (*pParserModule->pfCheckFileType)(pEASData, fileHandle, &streamHandle, 0L)) != EAS_SUCCESS)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "CheckFileType returned error %ld\n", result); */ }
- return result;
- }
-
- /* parser accepted the file, return the handle */
- if (streamHandle)
- {
-
- /* save the parser pointer and file handle */
- EAS_InitStream(&pEASData->streams[streamNum], pParserModule, streamHandle);
- *ppStream = &pEASData->streams[streamNum];
- return EAS_SUCCESS;
- }
-
- /* parser did not recognize the file, close it and return an error */
- EAS_HWCloseFile(pEASData->hwInstData, fileHandle);
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "No parser recognized the requested file\n"); */ }
- return EAS_ERROR_UNRECOGNIZED_FORMAT;
-}
-
-/*----------------------------------------------------------------------------
- * EAS_GetWaveFmtChunk
- *----------------------------------------------------------------------------
- * Helper function to retrieve WAVE file fmt chunk for MMAPI
- *----------------------------------------------------------------------------
- * pEASData - pointer to EAS persistent data object
- * pStream - stream handle
- * pFmtChunk - pointer to variable to receive current setting
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_GetWaveFmtChunk (S_EAS_DATA *pEASData, EAS_HANDLE pStream, EAS_VOID_PTR *ppFmtChunk)
-{
- EAS_RESULT result;
- EAS_I32 value;
-
- if ((result = EAS_GetStreamParameter(pEASData, pStream, PARSER_DATA_FORMAT, &value)) != EAS_SUCCESS)
- return result;
- *ppFmtChunk = (EAS_VOID_PTR) value;
- return EAS_SUCCESS;
-}
-#endif
-
-/*----------------------------------------------------------------------------
- * EAS_GetFileType
- *----------------------------------------------------------------------------
- * Returns the file type (see eas_types.h for enumerations)
- *----------------------------------------------------------------------------
- * pEASData - pointer to EAS persistent data object
- * pStream - stream handle
- * pFileType - pointer to variable to receive file type
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_GetFileType (S_EAS_DATA *pEASData, EAS_HANDLE pStream, EAS_I32 *pFileType)
-{
- if (!EAS_StreamReady (pEASData, pStream))
- return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
- return EAS_GetStreamParameter(pEASData, pStream, PARSER_DATA_FILE_TYPE, pFileType);
-}
-
-/*----------------------------------------------------------------------------
- * EAS_Prepare()
- *----------------------------------------------------------------------------
- * Purpose:
- * Prepares the synthesizer to play the file or stream. Parses the first
- * frame of data from the file and arms the synthesizer.
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - file or stream handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_Prepare (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream)
-{
- S_FILE_PARSER_INTERFACE *pParserModule;
- EAS_STATE state;
- EAS_RESULT result;
-
- pParserModule = (S_FILE_PARSER_INTERFACE*) pStream->pParserModule;
- if (pParserModule == NULL)
- return EAS_ERROR_FEATURE_NOT_AVAILABLE;
-
- /* check for valid state */
- result = pParserModule->pfState(pEASData, pStream->handle, &state);
- if (result == EAS_SUCCESS)
- {
- /* prepare the stream */
- if (state == EAS_STATE_OPEN)
- {
- pParserModule = (S_FILE_PARSER_INTERFACE*) pStream->pParserModule;
- result = (*pParserModule->pfPrepare)(pEASData, pStream->handle);
-
- /* set volume */
- if (result == EAS_SUCCESS)
- result = EAS_SetVolume(pEASData, pStream, pStream->volume);
- }
- else
- result = EAS_ERROR_NOT_VALID_IN_THIS_STATE;
-
- }
-
- return result;
-}
-
-/*----------------------------------------------------------------------------
- * EAS_Render()
- *----------------------------------------------------------------------------
- * Purpose:
- * Parse the Midi data and render PCM audio data.
- *
- * Inputs:
- * pEASData - buffer for internal EAS data
- * pOut - output buffer pointer
- * nNumRequested - requested num samples to generate
- * pnNumGenerated - actual number of samples generated
- *
- * Outputs:
- * EAS_SUCCESS if PCM data was successfully rendered
- *
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_Render (EAS_DATA_HANDLE pEASData, EAS_PCM *pOut, EAS_I32 numRequested, EAS_I32 *pNumGenerated)
-{
- S_FILE_PARSER_INTERFACE *pParserModule;
- EAS_RESULT result;
- EAS_I32 voicesRendered;
- EAS_STATE parserState;
- EAS_INT streamNum;
-
- /* assume no samples generated and reset workload */
- *pNumGenerated = 0;
- VMInitWorkload(pEASData->pVoiceMgr);
-
- /* no support for other buffer sizes yet */
- if (numRequested != BUFFER_SIZE_IN_MONO_SAMPLES)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "This library supports only %ld samples in buffer, host requested %ld samples\n",
- (EAS_I32) BUFFER_SIZE_IN_MONO_SAMPLES, numRequested); */ }
- return EAS_BUFFER_SIZE_MISMATCH;
- }
-
-#ifdef _METRICS_ENABLED
- /* start performance counter */
- if (pEASData->pMetricsData)
- (*pEASData->pMetricsModule->pfStartTimer)(pEASData->pMetricsData, EAS_PM_TOTAL_TIME);
-#endif
-
- /* prep the frame buffer, do mix engine prep only if TRUE */
-#ifdef _SPLIT_ARCHITECTURE
- if (VMStartFrame(pEASData))
- EAS_MixEnginePrep(pEASData, numRequested);
-#else
- /* prep the mix engine */
- EAS_MixEnginePrep(pEASData, numRequested);
-#endif
-
- /* save the output buffer pointer */
- pEASData->pOutputAudioBuffer = pOut;
-
-
-#ifdef _METRICS_ENABLED
- /* start performance counter */
- if (pEASData->pMetricsData)
- (*pEASData->pMetricsModule->pfStartTimer)(pEASData->pMetricsData, EAS_PM_PARSE_TIME);
-#endif
-
- /* if we haven't finished parsing from last time, do it now */
- /* need to parse another frame of events before we render again */
- for (streamNum = 0; streamNum < MAX_NUMBER_STREAMS; streamNum++)
- {
- /* clear the locate flag */
- pEASData->streams[streamNum].streamFlags &= ~STREAM_FLAGS_LOCATE;
-
- if (pEASData->streams[streamNum].pParserModule)
- {
-
- /* establish pointer to parser module */
- pParserModule = pEASData->streams[streamNum].pParserModule;
-
- /* handle pause */
- if (pEASData->streams[streamNum].streamFlags & STREAM_FLAGS_PAUSE)
- {
- if (pParserModule->pfPause)
- result = pParserModule->pfPause(pEASData, pEASData->streams[streamNum].handle);
- pEASData->streams[streamNum].streamFlags &= ~STREAM_FLAGS_PAUSE;
- }
-
- /* get current state */
- if ((result = (*pParserModule->pfState)(pEASData, pEASData->streams[streamNum].handle, &parserState)) != EAS_SUCCESS)
- return result;
-
- /* handle resume */
- if (parserState == EAS_STATE_PAUSED)
- {
- if (pEASData->streams[streamNum].streamFlags & STREAM_FLAGS_RESUME)
- {
- if (pParserModule->pfResume)
- result = pParserModule->pfResume(pEASData, pEASData->streams[streamNum].handle);
- pEASData->streams[streamNum].streamFlags &= ~STREAM_FLAGS_RESUME;
- }
- }
-
- /* if necessary, parse stream */
- if ((pEASData->streams[streamNum].streamFlags & STREAM_FLAGS_PARSED) == 0)
- if ((result = EAS_ParseEvents(pEASData, &pEASData->streams[streamNum], pEASData->streams[streamNum].time + pEASData->streams[streamNum].frameLength, eParserModePlay)) != EAS_SUCCESS)
- return result;
-
- /* check for an early abort */
- if ((pEASData->streams[streamNum].streamFlags) == 0)
- {
-
-#ifdef _METRICS_ENABLED
- /* stop performance counter */
- if (pEASData->pMetricsData)
- (*pEASData->pMetricsModule->pfStartTimer)(pEASData->pMetricsData, EAS_PM_TOTAL_TIME);
-#endif
-
- return EAS_SUCCESS;
- }
-
- /* check for repeat */
- if (pEASData->streams[streamNum].repeatCount)
- {
-
- /* check for stopped state */
- if ((result = (*pParserModule->pfState)(pEASData, pEASData->streams[streamNum].handle, &parserState)) != EAS_SUCCESS)
- return result;
- if (parserState == EAS_STATE_STOPPED)
- {
-
- /* decrement repeat count, unless it is negative */
- if (pEASData->streams[streamNum].repeatCount > 0)
- pEASData->streams[streamNum].repeatCount--;
-
- /* reset the parser */
- if ((result = (*pParserModule->pfReset)(pEASData, pEASData->streams[streamNum].handle)) != EAS_SUCCESS)
- return result;
- pEASData->streams[streamNum].time = 0;
- }
- }
- }
- }
-
-#ifdef _METRICS_ENABLED
- /* stop performance counter */
- if (pEASData->pMetricsData)
- (void)(*pEASData->pMetricsModule->pfStopTimer)(pEASData->pMetricsData, EAS_PM_PARSE_TIME);
-#endif
-
-#ifdef _METRICS_ENABLED
- /* start the render timer */
- if (pEASData->pMetricsData)
- (*pEASData->pMetricsModule->pfStartTimer)(pEASData->pMetricsData, EAS_PM_RENDER_TIME);
-#endif
-
- /* render audio */
- if ((result = VMRender(pEASData->pVoiceMgr, BUFFER_SIZE_IN_MONO_SAMPLES, pEASData->pMixBuffer, &voicesRendered)) != EAS_SUCCESS)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "pfRender function returned error %ld\n", result); */ }
- return result;
- }
-
-#ifdef _METRICS_ENABLED
- /* stop the render timer */
- if (pEASData->pMetricsData) {
- (*pEASData->pMetricsModule->pfIncrementCounter)(pEASData->pMetricsData, EAS_PM_FRAME_COUNT, 1);
- (void)(*pEASData->pMetricsModule->pfStopTimer)(pEASData->pMetricsData, EAS_PM_RENDER_TIME);
- (*pEASData->pMetricsModule->pfIncrementCounter)(pEASData->pMetricsData, EAS_PM_TOTAL_VOICE_COUNT, (EAS_U32) voicesRendered);
- (void)(*pEASData->pMetricsModule->pfRecordMaxValue)(pEASData->pMetricsData, EAS_PM_MAX_VOICES, (EAS_U32) voicesRendered);
- }
-#endif
-
- //2 Do we really need frameParsed?
- /* need to parse another frame of events before we render again */
- for (streamNum = 0; streamNum < MAX_NUMBER_STREAMS; streamNum++)
- if (pEASData->streams[streamNum].pParserModule != NULL)
- pEASData->streams[streamNum].streamFlags &= ~STREAM_FLAGS_PARSED;
-
-#ifdef _METRICS_ENABLED
- /* start performance counter */
- if (pEASData->pMetricsData)
- (*pEASData->pMetricsModule->pfStartTimer)(pEASData->pMetricsData, EAS_PM_STREAM_TIME);
-#endif
-
- /* render PCM audio */
- if ((result = EAS_PERender(pEASData, numRequested)) != EAS_SUCCESS)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "EAS_PERender returned error %ld\n", result); */ }
- return result;
- }
-
-#ifdef _METRICS_ENABLED
- /* stop the stream timer */
- if (pEASData->pMetricsData)
- (void)(*pEASData->pMetricsModule->pfStopTimer)(pEASData->pMetricsData, EAS_PM_STREAM_TIME);
-#endif
-
-#ifdef _METRICS_ENABLED
- /* start the post timer */
- if (pEASData->pMetricsData)
- (*pEASData->pMetricsModule->pfStartTimer)(pEASData->pMetricsData, EAS_PM_POST_TIME);
-#endif
-
- /* for split architecture, send DSP vectors. Do post only if return is TRUE */
-#ifdef _SPLIT_ARCHITECTURE
- if (VMEndFrame(pEASData))
- {
- /* now do post-processing */
- EAS_MixEnginePost(pEASData, numRequested);
- *pNumGenerated = numRequested;
- }
-#else
- /* now do post-processing */
- EAS_MixEnginePost(pEASData, numRequested);
- *pNumGenerated = numRequested;
-#endif
-
-#ifdef _METRICS_ENABLED
- /* stop the post timer */
- if (pEASData->pMetricsData)
- (void)(*pEASData->pMetricsModule->pfStopTimer)(pEASData->pMetricsData, EAS_PM_POST_TIME);
-#endif
-
- /* advance render time */
- pEASData->renderTime += AUDIO_FRAME_LENGTH;
-
-#if 0
- /* dump workload for debug */
- if (pEASData->pVoiceMgr->workload)
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Workload = %d\n", pEASData->pVoiceMgr->workload); */ }
-#endif
-
-#ifdef _METRICS_ENABLED
- /* stop performance counter */
- if (pEASData->pMetricsData)
- {
- PERF_TIMER temp;
- temp = (*pEASData->pMetricsModule->pfStopTimer)(pEASData->pMetricsData, EAS_PM_TOTAL_TIME);
-
- /* if max render time, record the number of voices and time */
- if ((*pEASData->pMetricsModule->pfRecordMaxValue)
- (pEASData->pMetricsData, EAS_PM_MAX_CYCLES, (EAS_U32) temp))
- {
- (*pEASData->pMetricsModule->pfRecordValue)(pEASData->pMetricsData, EAS_PM_MAX_CYCLES_VOICES, (EAS_U32) voicesRendered);
- (*pEASData->pMetricsModule->pfRecordValue)(pEASData->pMetricsData, EAS_PM_MAX_CYCLES_TIME, (EAS_I32) (pEASData->renderTime >> 8));
- }
- }
-#endif
-
-#ifdef JET_INTERFACE
- /* let JET to do its thing */
- if (pEASData->jetHandle != NULL)
- {
- result = JET_Process(pEASData);
- if (result != EAS_SUCCESS)
- return result;
- }
-#endif
-
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * EAS_SetRepeat()
- *----------------------------------------------------------------------------
- * Purpose:
- * Set the selected stream to repeat.
- *
- * Inputs:
- * pEASData - handle to data for this instance
- * handle - handle to stream
- * repeatCount - repeat count
- *
- * Outputs:
- *
- * Side Effects:
- *
- * Notes:
- * 0 = no repeat
- * 1 = repeat once, i.e. play through twice
- * -1 = repeat forever
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, pEASData) reserved for future use */
-EAS_PUBLIC EAS_RESULT EAS_SetRepeat (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_I32 repeatCount)
-{
- pStream->repeatCount = repeatCount;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * EAS_GetRepeat()
- *----------------------------------------------------------------------------
- * Purpose:
- * Gets the current repeat count for the selected stream.
- *
- * Inputs:
- * pEASData - handle to data for this instance
- * handle - handle to stream
- * pRrepeatCount - pointer to variable to hold repeat count
- *
- * Outputs:
- *
- * Side Effects:
- *
- * Notes:
- * 0 = no repeat
- * 1 = repeat once, i.e. play through twice
- * -1 = repeat forever
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, pEASData) reserved for future use */
-EAS_PUBLIC EAS_RESULT EAS_GetRepeat (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_I32 *pRepeatCount)
-{
- *pRepeatCount = pStream->repeatCount;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * EAS_SetPlaybackRate()
- *----------------------------------------------------------------------------
- * Purpose:
- * Sets the playback rate.
- *
- * Inputs:
- * pEASData - handle to data for this instance
- * handle - handle to stream
- * rate - rate (28-bit fractional amount)
- *
- * Outputs:
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, pEASData) reserved for future use */
-EAS_PUBLIC EAS_RESULT EAS_SetPlaybackRate (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_U32 rate)
-{
-
- /* check range */
- if ((rate < (1 << 27)) || (rate > (1 << 29)))
- return EAS_ERROR_INVALID_PARAMETER;
-
- /* calculate new frame length
- *
- * NOTE: The maximum frame length we can accomodate based on a
- * maximum rate of 2.0 (2^28) is 2047 (2^13-1). To accomodate a
- * longer frame length or a higher maximum rate, the fixed point
- * divide below will need to be adjusted
- */
- pStream->frameLength = (AUDIO_FRAME_LENGTH * (rate >> 8)) >> 20;
-
- /* notify stream of new playback rate */
- EAS_SetStreamParameter(pEASData, pStream, PARSER_DATA_PLAYBACK_RATE, (EAS_I32) rate);
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * EAS_SetTransposition)
- *----------------------------------------------------------------------------
- * Purpose:
- * Sets the key tranposition for the synthesizer. Transposes all
- * melodic instruments by the specified amount. Range is limited
- * to +/-12 semitones.
- *
- * Inputs:
- * pEASData - handle to data for this instance
- * handle - handle to stream
- * transposition - +/-12 semitones
- *
- * Outputs:
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_SetTransposition (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_I32 transposition)
-{
-
- /* check range */
- if ((transposition < -12) || (transposition > 12))
- return EAS_ERROR_INVALID_PARAMETER;
-
- if (!EAS_StreamReady(pEASData, pStream))
- return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
- return EAS_IntSetStrmParam(pEASData, pStream, PARSER_DATA_TRANSPOSITION, transposition);
-}
-
-/*----------------------------------------------------------------------------
- * EAS_ParseEvents()
- *----------------------------------------------------------------------------
- * Purpose:
- * Parse events in the current streams until the desired time is reached.
- *
- * Inputs:
- * pEASData - buffer for internal EAS data
- * endTime - stop parsing if this time is reached
- * parseMode - play, locate, or metadata
- *
- * Outputs:
- * EAS_SUCCESS if PCM data was successfully rendered
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT EAS_ParseEvents (S_EAS_DATA *pEASData, EAS_HANDLE pStream, EAS_U32 endTime, EAS_INT parseMode)
-{
- S_FILE_PARSER_INTERFACE *pParserModule;
- EAS_RESULT result;
- EAS_I32 parserState;
- EAS_BOOL done;
- EAS_INT yieldCount = YIELD_EVENT_COUNT;
- EAS_U32 time = 0;
-
- /* does this parser have a time function? */
- pParserModule = pStream->pParserModule;
- if (pParserModule->pfTime == NULL)
- {
- /* check state */
- if ((result = (*pParserModule->pfState)(pEASData, pStream->handle, &parserState)) != EAS_SUCCESS)
- return result;
- /* if play state, advance time */
- if ((parserState >= EAS_STATE_READY) && (parserState <= EAS_STATE_PAUSING))
- pStream->time += pStream->frameLength;
- done = EAS_TRUE;
- }
-
- /* assume we're not done, in case we abort out */
- else
- {
- pStream->streamFlags &= ~STREAM_FLAGS_PARSED;
- done = EAS_FALSE;
- }
-
- while (!done)
- {
-
- /* check for stopped state */
- if ((result = (*pParserModule->pfState)(pEASData, pStream->handle, &parserState)) != EAS_SUCCESS)
- return result;
- if (parserState > EAS_STATE_PLAY)
- {
- /* save current time if we're not in play mode */
- if (parseMode != eParserModePlay)
- pStream->time = time << 8;
- done = EAS_TRUE;
- break;
- }
-
- /* get the next event time */
- if (pParserModule->pfTime)
- {
- if ((result = (*pParserModule->pfTime)(pEASData, pStream->handle, &time)) != EAS_SUCCESS)
- return result;
-
- /* if next event is within this frame, parse it */
- if (time < (endTime >> 8))
- {
-
- /* parse the next event */
- if (pParserModule->pfEvent)
- if ((result = (*pParserModule->pfEvent)(pEASData, pStream->handle, parseMode)) != EAS_SUCCESS)
- return result;
- }
-
- /* no more events in this frame, advance time */
- else
- {
- pStream->time = endTime;
- done = EAS_TRUE;
- }
- }
-
- /* check for max workload exceeded */
- if (VMCheckWorkload(pEASData->pVoiceMgr))
- {
- /* stop even though we may not have parsed
- * all the events in this frame. The parser will try to
- * catch up on the next frame.
- */
- break;
- }
-
- /* give host a chance for an early abort */
- if (--yieldCount == 0)
- {
- if (EAS_HWYield(pEASData->hwInstData))
- break;
- yieldCount = YIELD_EVENT_COUNT;
- }
- }
-
- /* if no early abort, parsing is complete for this frame */
- if (done)
- pStream->streamFlags |= STREAM_FLAGS_PARSED;
-
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * EAS_ParseMetaData()
- *----------------------------------------------------------------------------
- * Purpose:
- *
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - file or stream handle
- * playLength - pointer to variable to store the play length (in msecs)
- *
- * Outputs:
- *
- *
- * Side Effects:
- * - resets the parser to the start of the file
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_ParseMetaData (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_I32 *playLength)
-{
- S_FILE_PARSER_INTERFACE *pParserModule;
- EAS_RESULT result;
- EAS_STATE state;
-
- pParserModule = (S_FILE_PARSER_INTERFACE*) pStream->pParserModule;
- if (pParserModule == NULL)
- return EAS_ERROR_FEATURE_NOT_AVAILABLE;
-
- /* check parser state */
- if ((result = (*pParserModule->pfState)(pEASData, pStream->handle, &state)) != EAS_SUCCESS)
- return result;
- if (state >= EAS_STATE_OPEN)
- return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
-
- /* if parser has metadata function, use that */
- if (pParserModule->pfGetMetaData != NULL)
- return pParserModule->pfGetMetaData(pEASData, pStream->handle, playLength);
-
- /* reset the parser to the beginning */
- if ((result = (*pParserModule->pfReset)(pEASData, pStream->handle)) != EAS_SUCCESS)
- return result;
-
- /* parse the file to end */
- pStream->time = 0;
- VMInitWorkload(pEASData->pVoiceMgr);
- if ((result = EAS_ParseEvents(pEASData, pStream, 0x7fffffff, eParserModeMetaData)) != EAS_SUCCESS)
- return result;
-
- /* get the parser time */
- if ((result = EAS_GetLocation(pEASData, pStream, playLength)) != EAS_SUCCESS)
- return result;
-
- /* reset the parser to the beginning */
- pStream->time = 0;
- return (*pParserModule->pfReset)(pEASData, pStream->handle);
-}
-
-/*----------------------------------------------------------------------------
- * EAS_RegisterMetaDataCallback()
- *----------------------------------------------------------------------------
- * Purpose:
- * Registers a metadata callback function for parsed metadata.
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - file or stream handle
- * cbFunc - pointer to host callback function
- * metaDataBuffer - pointer to metadata buffer
- * metaDataBufSize - maximum size of the metadata buffer
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_RegisterMetaDataCallback (
- EAS_DATA_HANDLE pEASData,
- EAS_HANDLE pStream,
- EAS_METADATA_CBFUNC cbFunc,
- char *metaDataBuffer,
- EAS_I32 metaDataBufSize,
- EAS_VOID_PTR pUserData)
-{
- S_METADATA_CB metadata;
-
- if (!EAS_StreamReady(pEASData, pStream))
- return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
-
- /* register callback function */
- metadata.callback = cbFunc;
- metadata.buffer = metaDataBuffer;
- metadata.bufferSize = metaDataBufSize;
- metadata.pUserData = pUserData;
- return EAS_SetStreamParameter(pEASData, pStream, PARSER_DATA_METADATA_CB, (EAS_I32) &metadata);
-}
-
-/*----------------------------------------------------------------------------
- * EAS_GetNoteCount ()
- *----------------------------------------------------------------------------
- * Returns the total number of notes played in this stream
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_GetNoteCount (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_I32 *pNoteCount)
-{
- if (!EAS_StreamReady(pEASData, pStream))
- return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
- return EAS_IntGetStrmParam(pEASData, pStream, PARSER_DATA_NOTE_COUNT, pNoteCount);
-}
-
-/*----------------------------------------------------------------------------
- * EAS_CloseFile()
- *----------------------------------------------------------------------------
- * Purpose:
- * Closes an audio file or stream. Playback should have either paused or
- * completed (EAS_State returns EAS_PAUSED or EAS_STOPPED).
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - file or stream handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_CloseFile (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream)
-{
- S_FILE_PARSER_INTERFACE *pParserModule;
- EAS_RESULT result;
-
- /* call the close function */
- pParserModule = (S_FILE_PARSER_INTERFACE*) pStream->pParserModule;
- if (pParserModule == NULL)
- return EAS_ERROR_FEATURE_NOT_AVAILABLE;
-
- result = (*pParserModule->pfClose)(pEASData, pStream->handle);
-
- /* clear the handle and parser interface pointer */
- pStream->handle = NULL;
- pStream->pParserModule = NULL;
- return result;
-}
-
-/*----------------------------------------------------------------------------
- * EAS_OpenMIDIStream()
- *----------------------------------------------------------------------------
- * Purpose:
- * Opens a raw MIDI stream allowing the host to route MIDI cable data directly to the synthesizer
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * pHandle - pointer to variable to hold file or stream handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_OpenMIDIStream (EAS_DATA_HANDLE pEASData, EAS_HANDLE *ppStream, EAS_HANDLE streamHandle)
-{
- EAS_RESULT result;
- S_INTERACTIVE_MIDI *pMIDIStream;
- EAS_INT streamNum;
-
- /* initialize some pointers */
- *ppStream = NULL;
-
- /* allocate a stream */
- if ((streamNum = EAS_AllocateStream(pEASData)) < 0)
- return EAS_ERROR_MAX_STREAMS_OPEN;
-
- /* check Configuration Module for S_EAS_DATA allocation */
- if (pEASData->staticMemoryModel)
- pMIDIStream = EAS_CMEnumData(EAS_CM_MIDI_STREAM_DATA);
- else
- pMIDIStream = EAS_HWMalloc(pEASData->hwInstData, sizeof(S_INTERACTIVE_MIDI));
-
- /* allocate dynamic memory */
- if (!pMIDIStream)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_FATAL, "Failed to allocate MIDI stream data\n"); */ }
- return EAS_ERROR_MALLOC_FAILED;
- }
-
- /* zero the memory to insure complete initialization */
- EAS_HWMemSet(pMIDIStream, 0, sizeof(S_INTERACTIVE_MIDI));
- EAS_InitStream(&pEASData->streams[streamNum], NULL, pMIDIStream);
-
- /* instantiate a new synthesizer */
- if (streamHandle == NULL)
- {
- result = VMInitMIDI(pEASData, &pMIDIStream->pSynth);
- }
-
- /* use an existing synthesizer */
- else
- {
- EAS_I32 value;
- result = EAS_GetStreamParameter(pEASData, streamHandle, PARSER_DATA_SYNTH_HANDLE, &value);
- pMIDIStream->pSynth = (S_SYNTH*) value;
- VMIncRefCount(pMIDIStream->pSynth);
- }
- if (result != EAS_SUCCESS)
- {
- EAS_CloseMIDIStream(pEASData, &pEASData->streams[streamNum]);
- return result;
- }
-
- /* initialize the MIDI stream data */
- EAS_InitMIDIStream(&pMIDIStream->stream);
-
- *ppStream = (EAS_HANDLE) &pEASData->streams[streamNum];
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * EAS_WriteMIDIStream()
- *----------------------------------------------------------------------------
- * Purpose:
- * Send data to the MIDI stream device
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - stream handle
- * pBuffer - pointer to buffer
- * count - number of bytes to write
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_WriteMIDIStream (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_U8 *pBuffer, EAS_I32 count)
-{
- S_INTERACTIVE_MIDI *pMIDIStream;
- EAS_RESULT result;
-
- pMIDIStream = (S_INTERACTIVE_MIDI*) pStream->handle;
-
- /* send the entire buffer */
- while (count--)
- {
- if ((result = EAS_ParseMIDIStream(pEASData, pMIDIStream->pSynth, &pMIDIStream->stream, *pBuffer++, eParserModePlay)) != EAS_SUCCESS)
- return result;
- }
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * EAS_CloseMIDIStream()
- *----------------------------------------------------------------------------
- * Purpose:
- * Closes a raw MIDI stream
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - stream handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_CloseMIDIStream (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream)
-{
- S_INTERACTIVE_MIDI *pMIDIStream;
-
- pMIDIStream = (S_INTERACTIVE_MIDI*) pStream->handle;
-
- /* close synth */
- if (pMIDIStream->pSynth != NULL)
- {
- VMMIDIShutdown(pEASData, pMIDIStream->pSynth);
- pMIDIStream->pSynth = NULL;
- }
-
- /* release allocated memory */
- if (!pEASData->staticMemoryModel)
- EAS_HWFree(((S_EAS_DATA*) pEASData)->hwInstData, pMIDIStream);
-
- pStream->handle = NULL;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * EAS_State()
- *----------------------------------------------------------------------------
- * Purpose:
- * Returns the state of an audio file or stream.
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - file or stream handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_State (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_STATE *pState)
-{
- S_FILE_PARSER_INTERFACE *pParserModule;
- EAS_RESULT result;
-
- /* call the parser to return state */
- pParserModule = (S_FILE_PARSER_INTERFACE*) pStream->pParserModule;
- if (pParserModule == NULL)
- return EAS_ERROR_FEATURE_NOT_AVAILABLE;
-
- if ((result = (*pParserModule->pfState)(pEASData, pStream->handle, pState)) != EAS_SUCCESS)
- return result;
-
- /* if repeat count is set for this parser, mask the stopped state from the application */
- if (pStream->repeatCount && (*pState == EAS_STATE_STOPPED))
- *pState = EAS_STATE_PLAY;
-
- /* if we're not ready or playing, we don't need to hide state from host */
- if (*pState > EAS_STATE_PLAY)
- return EAS_SUCCESS;
-
- /* if stream is about to be paused, report it as paused */
- if (pStream->streamFlags & STREAM_FLAGS_PAUSE)
- {
- if (pStream->streamFlags & STREAM_FLAGS_LOCATE)
- *pState = EAS_STATE_PAUSED;
- else
- *pState = EAS_STATE_PAUSING;
- }
-
- /* if stream is about to resume, report it as playing */
- if (pStream->streamFlags & STREAM_FLAGS_RESUME)
- *pState = EAS_STATE_PLAY;
-
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * EAS_SetPolyphony()
- *----------------------------------------------------------------------------
- * Purpose:
- * Set the polyphony of the stream. A value of 0 allows the stream
- * to use all voices (set by EAS_SetSynthPolyphony).
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * streamHandle - handle returned by EAS_OpenFile
- * polyphonyCount - the desired polyphony count
- *
- * Outputs:
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_SetPolyphony (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_I32 polyphonyCount)
-{
- if (!EAS_StreamReady(pEASData, pStream))
- return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
- return EAS_IntSetStrmParam(pEASData, pStream, PARSER_DATA_POLYPHONY, polyphonyCount);
-}
-
-/*----------------------------------------------------------------------------
- * EAS_GetPolyphony()
- *----------------------------------------------------------------------------
- * Purpose:
- * Returns the current polyphony setting of the stream
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * streamHandle - handle returned by EAS_OpenFile
- * pPolyphonyCount - pointer to variable to receive polyphony count
- *
- * Outputs:
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_GetPolyphony (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_I32 *pPolyphonyCount)
-{
- if (!EAS_StreamReady(pEASData, pStream))
- return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
- return EAS_IntGetStrmParam(pEASData, pStream, PARSER_DATA_POLYPHONY, pPolyphonyCount);
-}
-
-/*----------------------------------------------------------------------------
- * EAS_SetSynthPolyphony()
- *----------------------------------------------------------------------------
- * Purpose:
- * Set the polyphony of the synth . Value must be >= 1 and <= the
- * maximum number of voices. This function will pin the polyphony
- * at those limits
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * synthNum - synthesizer number (0 = onboard, 1 = DSP)
- * polyphonyCount - the desired polyphony count
- *
- * Outputs:
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_SetSynthPolyphony (EAS_DATA_HANDLE pEASData, EAS_I32 synthNum, EAS_I32 polyphonyCount)
-{
- return VMSetSynthPolyphony(pEASData->pVoiceMgr, synthNum, polyphonyCount);
-}
-
-/*----------------------------------------------------------------------------
- * EAS_GetSynthPolyphony()
- *----------------------------------------------------------------------------
- * Purpose:
- * Returns the current polyphony setting of the synth
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * synthNum - synthesizer number (0 = onboard, 1 = DSP)
- * pPolyphonyCount - pointer to variable to receive polyphony count
- *
- * Outputs:
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_GetSynthPolyphony (EAS_DATA_HANDLE pEASData, EAS_I32 synthNum, EAS_I32 *pPolyphonyCount)
-{
- return VMGetSynthPolyphony(pEASData->pVoiceMgr, synthNum, pPolyphonyCount);
-}
-
-/*----------------------------------------------------------------------------
- * EAS_SetPriority()
- *----------------------------------------------------------------------------
- * Purpose:
- * Set the priority of the stream. Determines which stream's voices
- * are stolen when there are insufficient voices for all notes.
- * Value must be in the range of 1-15, lower values are higher
- * priority.
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * streamHandle - handle returned by EAS_OpenFile
- * polyphonyCount - the desired polyphony count
- *
- * Outputs:
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_SetPriority (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_I32 priority)
-{
- if (!EAS_StreamReady(pEASData, pStream))
- return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
- return EAS_IntSetStrmParam(pEASData, pStream, PARSER_DATA_PRIORITY, priority);
-}
-
-/*----------------------------------------------------------------------------
- * EAS_GetPriority()
- *----------------------------------------------------------------------------
- * Purpose:
- * Returns the current priority setting of the stream
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * streamHandle - handle returned by EAS_OpenFile
- * pPriority - pointer to variable to receive priority
- *
- * Outputs:
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_GetPriority (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_I32 *pPriority)
-{
- if (!EAS_StreamReady(pEASData, pStream))
- return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
- return EAS_IntGetStrmParam(pEASData, pStream, PARSER_DATA_PRIORITY, pPriority);
-}
-
-/*----------------------------------------------------------------------------
- * EAS_SetVolume()
- *----------------------------------------------------------------------------
- * Purpose:
- * Set the master gain for the mix engine in 1dB increments
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * volume - the desired master gain (100 is max)
- * handle - file or stream handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- * overrides any previously set master volume from sysex
- *
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_SetVolume (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_I32 volume)
-{
- EAS_I16 gain;
-
- /* check range */
- if ((volume < 0) || (volume > EAS_MAX_VOLUME))
- return EAS_ERROR_PARAMETER_RANGE;
-
- /* stream volume */
- if (pStream != NULL)
- {
- EAS_I32 gainOffset;
- EAS_RESULT result;
-
- if (!EAS_StreamReady(pEASData, pStream))
- return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
-
- /* get gain offset */
- pStream->volume = (EAS_U8) volume;
- result = EAS_GetStreamParameter(pEASData, pStream, PARSER_DATA_GAIN_OFFSET, &gainOffset);
- if (result == EAS_SUCCESS)
- volume += gainOffset;
-
- /* set stream volume */
- gain = EAS_VolumeToGain(volume - STREAM_VOLUME_HEADROOM);
-
- /* convert to linear scalar */
- return EAS_IntSetStrmParam(pEASData, pStream, PARSER_DATA_VOLUME, gain);
- }
-
- /* master volume */
- pEASData->masterVolume = (EAS_U8) volume;
-#if (NUM_OUTPUT_CHANNELS == 1)
- /* leave 3dB headroom for mono output */
- volume -= 3;
-#endif
-
- gain = EAS_VolumeToGain(volume - STREAM_VOLUME_HEADROOM);
- pEASData->masterGain = gain;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * EAS_GetVolume()
- *----------------------------------------------------------------------------
- * Purpose:
- * Returns the master volume for the synthesizer. The default volume setting is
- * 50. The volume range is 0 to 100;
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * volume - the desired master volume
- * handle - file or stream handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- * overrides any previously set master volume from sysex
- *
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_I32 EAS_GetVolume (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream)
-{
- if (pStream == NULL)
- return pEASData->masterVolume;
-
- if (!EAS_StreamReady(pEASData, pStream))
- return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
- return pStream->volume;
-}
-
-/*----------------------------------------------------------------------------
- * EAS_SetMaxLoad()
- *----------------------------------------------------------------------------
- * Purpose:
- * Sets the maximum workload the parsers will do in a single call to
- * EAS_Render. The units are currently arbitrary, but should correlate
- * well to the actual CPU cycles consumed. The primary effect is to
- * reduce the occasional peaks in CPU cycles consumed when parsing
- * dense parts of a MIDI score.
- *
- * Inputs:
- * pEASData - handle to data for this instance
- * maxLoad - the desired maximum workload
- *
- * Outputs:
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_SetMaxLoad (EAS_DATA_HANDLE pEASData, EAS_I32 maxLoad)
-{
- VMSetWorkload(pEASData->pVoiceMgr, maxLoad);
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * EAS_SetMaxPCMStreams()
- *----------------------------------------------------------------------------
- * Sets the maximum number of PCM streams allowed in parsers that
- * use PCM streaming.
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * streamHandle - handle returned by EAS_OpenFile
- * maxNumStreams - maximum number of PCM streams
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_SetMaxPCMStreams (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_I32 maxNumStreams)
-{
- if (!EAS_StreamReady(pEASData, pStream))
- return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
- return EAS_IntSetStrmParam(pEASData, pStream, PARSER_DATA_MAX_PCM_STREAMS, maxNumStreams);
-}
-
-/*----------------------------------------------------------------------------
- * EAS_Locate()
- *----------------------------------------------------------------------------
- * Purpose:
- * Locate into the file associated with the handle.
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - file handle
- * milliseconds - playback offset from start of file in milliseconds
- *
- * Outputs:
- *
- *
- * Side Effects:
- * the actual offset will be quantized to the closest update period, typically
- * a resolution of 5.9ms. Notes that are started prior to this time will not
- * sound. Any notes currently playing will be shut off.
- *
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_Locate (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_I32 milliseconds, EAS_BOOL offset)
-{
- S_FILE_PARSER_INTERFACE *pParserModule;
- EAS_RESULT result;
- EAS_U32 requestedTime;
- EAS_STATE state;
-
- /* get pointer to parser function table */
- pParserModule = (S_FILE_PARSER_INTERFACE*) pStream->pParserModule;
- if (pParserModule == NULL)
- return EAS_ERROR_FEATURE_NOT_AVAILABLE;
-
- if ((result = (*pParserModule->pfState)(pEASData, pStream->handle, &state)) != EAS_SUCCESS)
- return result;
- if (state >= EAS_STATE_OPEN)
- return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
-
- /* handle offset and limit to start of file */
- /*lint -e{704} use shift for performance*/
- if (offset)
- milliseconds += (EAS_I32) pStream->time >> 8;
- if (milliseconds < 0)
- milliseconds = 0;
-
- /* check to see if the request is different from the current time */
- requestedTime = (EAS_U32) milliseconds;
- if (requestedTime == (pStream->time >> 8))
- return EAS_SUCCESS;
-
- /* set the locate flag */
- pStream->streamFlags |= STREAM_FLAGS_LOCATE;
-
- /* use the parser locate function, if available */
- if (pParserModule->pfLocate != NULL)
- {
- EAS_BOOL parserLocate = EAS_FALSE;
- result = pParserModule->pfLocate(pEASData, pStream->handle, (EAS_I32) requestedTime, &parserLocate);
- if (!parserLocate)
- {
- if (result == EAS_SUCCESS)
- pStream->time = requestedTime << 8;
- return result;
- }
- }
-
- /* if we were paused and not going to resume, set pause request flag */
- if (((state == EAS_STATE_PAUSING) || (state == EAS_STATE_PAUSED)) && ((pStream->streamFlags & STREAM_FLAGS_RESUME) == 0))
- pStream->streamFlags |= STREAM_FLAGS_PAUSE;
-
- /* reset the synth and parser */
- if ((result = (*pParserModule->pfReset)(pEASData, pStream->handle)) != EAS_SUCCESS)
- return result;
- pStream->time = 0;
-
- /* locating forward, clear parsed flag and parse data until we get to the requested location */
- if ((result = EAS_ParseEvents(pEASData, pStream, requestedTime << 8, eParserModeLocate)) != EAS_SUCCESS)
- return result;
-
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * EAS_GetLocation()
- *----------------------------------------------------------------------------
- * Purpose:
- * Returns the current playback offset
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - file handle
- *
- * Outputs:
- * The offset in milliseconds from the start of the current sequence, quantized
- * to the nearest update period. Actual resolution is typically 5.9 ms.
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, pEASData) reserved for future use */
-EAS_PUBLIC EAS_RESULT EAS_GetLocation (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_I32 *pTime)
-{
- if (!EAS_StreamReady(pEASData, pStream))
- return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
-
- *pTime = pStream->time >> 8;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * EAS_GetRenderTime()
- *----------------------------------------------------------------------------
- * Purpose:
- * Returns the current playback offset
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- *
- * Outputs:
- * Gets the render time clock in msecs.
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_GetRenderTime (EAS_DATA_HANDLE pEASData, EAS_I32 *pTime)
-{
- *pTime = pEASData->renderTime >> 8;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * EAS_Pause()
- *----------------------------------------------------------------------------
- * Purpose:
- * Pauses the playback of the data associated with this handle. The audio
- * is gracefully ramped down to prevent clicks and pops. It may take several
- * buffers of audio before the audio is muted.
- *
- * Inputs:
- * psEASData - pointer to overall EAS data structure
- * handle - file or stream handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_Pause (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream)
-{
- S_FILE_PARSER_INTERFACE *pParserModule;
- EAS_STATE state;
- EAS_RESULT result;
-
- pParserModule = (S_FILE_PARSER_INTERFACE*) pStream->pParserModule;
- if (pParserModule == NULL)
- return EAS_ERROR_FEATURE_NOT_AVAILABLE;
-
- /* check for valid state */
- result = pParserModule->pfState(pEASData, pStream->handle, &state);
- if (result == EAS_SUCCESS)
- {
- if ((state != EAS_STATE_PLAY) && (state != EAS_STATE_READY) && ((pStream->streamFlags & STREAM_FLAGS_RESUME) == 0))
- return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
-
- /* make sure parser implements pause */
- if (pParserModule->pfPause == NULL)
- result = EAS_ERROR_NOT_IMPLEMENTED;
-
- /* clear resume flag */
- pStream->streamFlags &= ~STREAM_FLAGS_RESUME;
-
- /* set pause flag */
- pStream->streamFlags |= STREAM_FLAGS_PAUSE;
-
-#if 0
- /* pause the stream */
- if (pParserModule->pfPause)
- result = pParserModule->pfPause(pEASData, pStream->handle);
- else
- result = EAS_ERROR_NOT_IMPLEMENTED;
-#endif
- }
-
- return result;
-}
-
-/*----------------------------------------------------------------------------
- * EAS_Resume()
- *----------------------------------------------------------------------------
- * Purpose:
- * Resumes the playback of the data associated with this handle. The audio
- * is gracefully ramped up to prevent clicks and pops.
- *
- * Inputs:
- * psEASData - pointer to overall EAS data structure
- * handle - file or stream handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_Resume (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream)
-{
- S_FILE_PARSER_INTERFACE *pParserModule;
- EAS_STATE state;
- EAS_RESULT result;
-
- pParserModule = (S_FILE_PARSER_INTERFACE*) pStream->pParserModule;
- if (pParserModule == NULL)
- return EAS_ERROR_FEATURE_NOT_AVAILABLE;
-
- /* check for valid state */
- result = pParserModule->pfState(pEASData, pStream->handle, &state);
- if (result == EAS_SUCCESS)
- {
- if ((state != EAS_STATE_PAUSED) && (state != EAS_STATE_PAUSING) && ((pStream->streamFlags & STREAM_FLAGS_PAUSE) == 0))
- return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
-
- /* make sure parser implements this function */
- if (pParserModule->pfResume == NULL)
- result = EAS_ERROR_NOT_IMPLEMENTED;
-
- /* clear pause flag */
- pStream->streamFlags &= ~STREAM_FLAGS_PAUSE;
-
- /* set resume flag */
- pStream->streamFlags |= STREAM_FLAGS_RESUME;
-
-#if 0
- /* resume the stream */
- if (pParserModule->pfResume)
- result = pParserModule->pfResume(pEASData, pStream->handle);
- else
- result = EAS_ERROR_NOT_IMPLEMENTED;
-#endif
- }
-
- return result;
-}
-
-/*----------------------------------------------------------------------------
- * EAS_GetParameter()
- *----------------------------------------------------------------------------
- * Purpose:
- * Set the parameter of a module. See E_MODULES for a list of modules
- * and the header files of the modules for a list of parameters.
- *
- * Inputs:
- * psEASData - pointer to overall EAS data structure
- * handle - file or stream handle
- * module - enumerated module number
- * param - enumerated parameter number
- * pValue - pointer to variable to receive parameter value
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_GetParameter (EAS_DATA_HANDLE pEASData, EAS_I32 module, EAS_I32 param, EAS_I32 *pValue)
-{
-
- if (module >= NUM_EFFECTS_MODULES)
- return EAS_ERROR_INVALID_MODULE;
-
- if (pEASData->effectsModules[module].effectData == NULL)
- return EAS_ERROR_INVALID_MODULE;
-
- return (*pEASData->effectsModules[module].effect->pFGetParam)
- (pEASData->effectsModules[module].effectData, param, pValue);
-}
-
-/*----------------------------------------------------------------------------
- * EAS_SetParameter()
- *----------------------------------------------------------------------------
- * Purpose:
- * Set the parameter of a module. See E_MODULES for a list of modules
- * and the header files of the modules for a list of parameters.
- *
- * Inputs:
- * psEASData - pointer to overall EAS data structure
- * handle - file or stream handle
- * module - enumerated module number
- * param - enumerated parameter number
- * value - new parameter value
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_SetParameter (EAS_DATA_HANDLE pEASData, EAS_I32 module, EAS_I32 param, EAS_I32 value)
-{
-
- if (module >= NUM_EFFECTS_MODULES)
- return EAS_ERROR_INVALID_MODULE;
-
- if (pEASData->effectsModules[module].effectData == NULL)
- return EAS_ERROR_INVALID_MODULE;
-
- return (*pEASData->effectsModules[module].effect->pFSetParam)
- (pEASData->effectsModules[module].effectData, param, value);
-}
-
-#ifdef _METRICS_ENABLED
-/*----------------------------------------------------------------------------
- * EAS_MetricsReport()
- *----------------------------------------------------------------------------
- * Purpose:
- * Displays the current metrics through the metrics interface.
- *
- * Inputs:
- * p - instance data handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_MetricsReport (EAS_DATA_HANDLE pEASData)
-{
- if (!pEASData->pMetricsModule)
- return EAS_ERROR_INVALID_MODULE;
-
- return (*pEASData->pMetricsModule->pfReport)(pEASData->pMetricsData);
-}
-
-/*----------------------------------------------------------------------------
- * EAS_MetricsReset()
- *----------------------------------------------------------------------------
- * Purpose:
- * Resets the metrics.
- *
- * Inputs:
- * p - instance data handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_MetricsReset (EAS_DATA_HANDLE pEASData)
-{
-
- if (!pEASData->pMetricsModule)
- return EAS_ERROR_INVALID_MODULE;
-
- return (*pEASData->pMetricsModule->pfReset)(pEASData->pMetricsData);
-}
-#endif
-
-/*----------------------------------------------------------------------------
- * EAS_SetSoundLibrary()
- *----------------------------------------------------------------------------
- * Purpose:
- * Sets the location of the sound library.
- *
- * Inputs:
- * pEASData - instance data handle
- * pSoundLib - pointer to sound library
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_SetSoundLibrary (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_SNDLIB_HANDLE pSndLib)
-{
- if (pStream)
- {
- if (!EAS_StreamReady(pEASData, pStream))
- return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
- return EAS_IntSetStrmParam(pEASData, pStream, PARSER_DATA_EAS_LIBRARY, (EAS_I32) pSndLib);
- }
-
- return VMSetGlobalEASLib(pEASData->pVoiceMgr, pSndLib);
-}
-
-/*----------------------------------------------------------------------------
- * EAS_SetHeaderSearchFlag()
- *----------------------------------------------------------------------------
- * By default, when EAS_OpenFile is called, the parsers check the
- * first few bytes of the file looking for a specific header. Some
- * mobile devices may add a header to the start of a file, which
- * will prevent the parser from recognizing the file. If the
- * searchFlag is set to EAS_TRUE, the parser will search the entire
- * file looking for the header. This may enable EAS to recognize
- * some files that it would ordinarily reject. The negative is that
- * it make take slightly longer to process the EAS_OpenFile request.
- *
- * Inputs:
- * pEASData - instance data handle
- * searchFlag - search flag (EAS_TRUE or EAS_FALSE)
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_SetHeaderSearchFlag (EAS_DATA_HANDLE pEASData, EAS_BOOL searchFlag)
-{
- pEASData->searchHeaderFlag = (EAS_BOOL8) searchFlag;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * EAS_SetPlayMode()
- *----------------------------------------------------------------------------
- * Some file formats support special play modes, such as iMode partial
- * play mode. This call can be used to change the play mode. The
- * default play mode (usually straight playback) is always zero.
- *
- * Inputs:
- * pEASData - instance data handle
- * handle - file or stream handle
- * playMode - play mode (see file parser for specifics)
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_SetPlayMode (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_I32 playMode)
-{
- return EAS_IntSetStrmParam(pEASData, pStream, PARSER_DATA_PLAY_MODE, playMode);
-}
-
-#ifdef DLS_SYNTHESIZER
-/*----------------------------------------------------------------------------
- * EAS_LoadDLSCollection()
- *----------------------------------------------------------------------------
- * Purpose:
- * Sets the location of the sound library.
- *
- * Inputs:
- * pEASData - instance data handle
- * pSoundLib - pointer to sound library
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_LoadDLSCollection (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_FILE_LOCATOR locator)
-{
- EAS_FILE_HANDLE fileHandle;
- EAS_RESULT result;
- EAS_DLSLIB_HANDLE pDLS;
-
- if (pStream != NULL)
- {
- if (!EAS_StreamReady(pEASData, pStream))
- return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
- }
-
- /* open the file */
- if ((result = EAS_HWOpenFile(pEASData->hwInstData, locator, &fileHandle, EAS_FILE_READ)) != EAS_SUCCESS)
- return result;
-
- /* parse the file */
- result = DLSParser(pEASData->hwInstData, fileHandle, 0, &pDLS);
- EAS_HWCloseFile(pEASData->hwInstData, fileHandle);
-
- if (result == EAS_SUCCESS)
- {
-
- /* if a stream pStream is specified, point it to the DLS collection */
- if (pStream)
- result = EAS_IntSetStrmParam(pEASData, pStream, PARSER_DATA_DLS_COLLECTION, (EAS_I32) pDLS);
-
- /* global DLS load */
- else
- result = VMSetGlobalDLSLib(pEASData, pDLS);
- }
-
- return result;
-}
-#endif
-
-#ifdef EXTERNAL_AUDIO
-/*----------------------------------------------------------------------------
- * EAS_RegExtAudioCallback()
- *----------------------------------------------------------------------------
- * Purpose:
- * Registers callback functions for audio events.
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - file or stream handle
- * cbProgChgFunc - pointer to host callback function for program change
- * cbEventFunc - pointer to host callback functio for note events
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_RegExtAudioCallback (EAS_DATA_HANDLE pEASData,
- EAS_HANDLE pStream,
- EAS_VOID_PTR pInstData,
- EAS_EXT_PRG_CHG_FUNC cbProgChgFunc,
- EAS_EXT_EVENT_FUNC cbEventFunc)
-{
- S_SYNTH *pSynth;
-
- if (!EAS_StreamReady(pEASData, pStream))
- return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
-
- if (EAS_GetStreamParameter(pEASData, pStream, PARSER_DATA_SYNTH_HANDLE, (EAS_I32*) &pSynth) != EAS_SUCCESS)
- return EAS_ERROR_INVALID_PARAMETER;
-
- if (pSynth == NULL)
- return EAS_ERROR_INVALID_PARAMETER;
-
- VMRegExtAudioCallback(pSynth, pInstData, cbProgChgFunc, cbEventFunc);
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * EAS_GetMIDIControllers()
- *----------------------------------------------------------------------------
- * Purpose:
- * Returns the current state of MIDI controllers on the requested channel.
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - file or stream handle
- * pControl - pointer to structure to receive data
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_GetMIDIControllers (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_U8 channel, S_MIDI_CONTROLLERS *pControl)
-{
- S_SYNTH *pSynth;
-
- if (!EAS_StreamReady(pEASData, pStream))
- return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
-
- if (EAS_GetStreamParameter(pEASData, pStream, PARSER_DATA_SYNTH_HANDLE, (EAS_I32*) &pSynth) != EAS_SUCCESS)
- return EAS_ERROR_INVALID_PARAMETER;
-
- if (pSynth == NULL)
- return EAS_ERROR_INVALID_PARAMETER;
-
- VMGetMIDIControllers(pSynth, channel, pControl);
- return EAS_SUCCESS;
-}
-#endif
-
-#ifdef _SPLIT_ARCHITECTURE
-/*----------------------------------------------------------------------------
- * EAS_SetFrameBuffer()
- *----------------------------------------------------------------------------
- * Purpose:
- * Sets the frame buffer pointer passed to the IPC communications functions
- *
- * Inputs:
- * pEASData - instance data handle
- * locator - file locator
- *
- * Outputs:
- *
- *
- * Side Effects:
- * May overlay instruments in the GM sound set
- *
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_SetFrameBuffer (EAS_DATA_HANDLE pEASData, EAS_FRAME_BUFFER_HANDLE pFrameBuffer)
-{
- if (pEASData->pVoiceMgr)
- pEASData->pVoiceMgr->pFrameBuffer = pFrameBuffer;
- return EAS_SUCCESS;
-}
-#endif
-
-/*----------------------------------------------------------------------------
- * EAS_SearchFile
- *----------------------------------------------------------------------------
- * Search file for specific sequence starting at current file
- * position. Returns offset to start of sequence.
- *
- * Inputs:
- * pEASData - pointer to EAS persistent data object
- * fileHandle - file handle
- * searchString - pointer to search sequence
- * len - length of search sequence
- * pOffset - pointer to variable to store offset to sequence
- *
- * Returns EAS_EOF if end-of-file is reached
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT EAS_SearchFile (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle, const EAS_U8 *searchString, EAS_I32 len, EAS_I32 *pOffset)
-{
- EAS_RESULT result;
- EAS_INT index;
- EAS_U8 c;
-
- *pOffset = -1;
- index = 0;
- for (;;)
- {
- result = EAS_HWGetByte(pEASData->hwInstData, fileHandle, &c);
- if (result != EAS_SUCCESS)
- return result;
- if (c == searchString[index])
- {
- index++;
- if (index == 4)
- {
- result = EAS_HWFilePos(pEASData->hwInstData, fileHandle, pOffset);
- if (result != EAS_SUCCESS)
- return result;
- *pOffset -= len;
- break;
- }
- }
- else
- index = 0;
- }
- return EAS_SUCCESS;
-}
-
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 842 $
+ * $Date: 2007-08-23 14:32:31 -0700 (Thu, 23 Aug 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+#include "eas_synthcfg.h"
+#include "eas.h"
+#include "eas_config.h"
+#include "eas_host.h"
+#include "eas_report.h"
+#include "eas_data.h"
+#include "eas_parser.h"
+#include "eas_pcm.h"
+#include "eas_midi.h"
+#include "eas_mixer.h"
+#include "eas_build.h"
+#include "eas_vm_protos.h"
+#include "eas_math.h"
+
+#ifdef JET_INTERFACE
+#include "jet_data.h"
+#endif
+
+#ifdef DLS_SYNTHESIZER
+#include "eas_mdls.h"
+#endif
+
+/* number of events to parse before calling EAS_HWYield function */
+#define YIELD_EVENT_COUNT 10
+
+/*----------------------------------------------------------------------------
+ * easLibConfig
+ *
+ * This structure is available through the EAS public interface to allow
+ * the user to check the configuration of the library.
+ *----------------------------------------------------------------------------
+*/
+static const S_EAS_LIB_CONFIG easLibConfig =
+{
+ LIB_VERSION,
+#ifdef _CHECKED_BUILD
+ EAS_TRUE,
+#else
+ EAS_FALSE,
+#endif
+ MAX_SYNTH_VOICES,
+ NUM_OUTPUT_CHANNELS,
+ _OUTPUT_SAMPLE_RATE,
+ BUFFER_SIZE_IN_MONO_SAMPLES,
+#ifdef _FILTER_ENABLED
+ EAS_TRUE,
+#else
+ EAS_FALSE,
+#endif
+ _BUILD_TIME_,
+ _BUILD_VERSION_
+};
+
+/* local prototypes */
+static EAS_RESULT EAS_ParseEvents (S_EAS_DATA *pEASData, S_EAS_STREAM *pStream, EAS_U32 endTime, EAS_INT parseMode);
+
+/*----------------------------------------------------------------------------
+ * EAS_SetStreamParameter
+ *----------------------------------------------------------------------------
+ * Sets the specified parameter in the stream. Allows access to
+ * customizable settings within the individual file parsers.
+ *----------------------------------------------------------------------------
+ * pEASData - pointer to EAS persistent data object
+ * pStream - stream handle
+ * param - enumerated parameter (see eas_parser.h)
+ * value - new value
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_SetStreamParameter (S_EAS_DATA *pEASData, EAS_HANDLE pStream, EAS_I32 param, EAS_I32 value)
+{
+ S_FILE_PARSER_INTERFACE *pParserModule;
+
+ pParserModule = (S_FILE_PARSER_INTERFACE*) pStream->pParserModule;
+ if (pParserModule->pfSetData)
+ return (*pParserModule->pfSetData)(pEASData, pStream->handle, param, value);
+ return EAS_ERROR_FEATURE_NOT_AVAILABLE;
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_GetStreamParameter
+ *----------------------------------------------------------------------------
+ * Sets the specified parameter in the stream. Allows access to
+ * customizable settings within the individual file parsers.
+ *----------------------------------------------------------------------------
+ * pEASData - pointer to EAS persistent data object
+ * pStream - stream handle
+ * param - enumerated parameter (see eas_parser.h)
+ * pValue - pointer to variable to receive current setting
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_GetStreamParameter (S_EAS_DATA *pEASData, EAS_HANDLE pStream, EAS_I32 param, EAS_I32 *pValue)
+{
+ S_FILE_PARSER_INTERFACE *pParserModule;
+
+ pParserModule = (S_FILE_PARSER_INTERFACE*) pStream->pParserModule;
+ if (pParserModule->pfGetData)
+ return (*pParserModule->pfGetData)(pEASData, pStream->handle, param, pValue);
+ return EAS_ERROR_FEATURE_NOT_AVAILABLE;
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_StreamReady()
+ *----------------------------------------------------------------------------
+ * This routine sets common parameters like transpose, volume, etc.
+ * First, it attempts to use the parser EAS_SetStreamParameter interface. If that
+ * fails, it attempts to get the synth handle from the parser and
+ * set the parameter directly on the synth. This eliminates duplicate
+ * code in the parser.
+ *----------------------------------------------------------------------------
+*/
+EAS_BOOL EAS_StreamReady (S_EAS_DATA *pEASData, EAS_HANDLE pStream)
+{
+ S_FILE_PARSER_INTERFACE *pParserModule;
+ EAS_STATE state;
+
+ pParserModule = (S_FILE_PARSER_INTERFACE*) pStream->pParserModule;
+ if (pParserModule->pfState(pEASData, pStream->handle, &state) != EAS_SUCCESS)
+ return EAS_FALSE;
+ return (state < EAS_STATE_OPEN);
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_IntSetStrmParam()
+ *----------------------------------------------------------------------------
+ * This routine sets common parameters like transpose, volume, etc.
+ * First, it attempts to use the parser EAS_SetStreamParameter interface. If that
+ * fails, it attempts to get the synth handle from the parser and
+ * set the parameter directly on the synth. This eliminates duplicate
+ * code in the parser.
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_IntSetStrmParam (S_EAS_DATA *pEASData, EAS_HANDLE pStream, EAS_INT param, EAS_I32 value)
+{
+ S_SYNTH *pSynth;
+
+ /* try to set the parameter using stream interface */
+ if (EAS_SetStreamParameter(pEASData, pStream, param, value) == EAS_SUCCESS)
+ return EAS_SUCCESS;
+
+ /* get a pointer to the synth object and set it directly */
+ /*lint -e{740} we are cheating by passing a pointer through this interface */
+ if (EAS_GetStreamParameter(pEASData, pStream, PARSER_DATA_SYNTH_HANDLE, (EAS_I32*) &pSynth) != EAS_SUCCESS)
+ return EAS_ERROR_INVALID_PARAMETER;
+
+ if (pSynth == NULL)
+ return EAS_ERROR_INVALID_PARAMETER;
+
+ switch (param)
+ {
+
+#ifdef DLS_SYNTHESIZER
+ case PARSER_DATA_DLS_COLLECTION:
+ {
+ EAS_RESULT result = VMSetDLSLib(pSynth, (EAS_DLSLIB_HANDLE) value);
+ if (result == EAS_SUCCESS)
+ {
+ DLSAddRef((S_DLS*) value);
+ VMInitializeAllChannels(pEASData->pVoiceMgr, pSynth);
+ }
+ return result;
+ }
+#endif
+
+ case PARSER_DATA_EAS_LIBRARY:
+ return VMSetEASLib(pSynth, (EAS_SNDLIB_HANDLE) value);
+
+ case PARSER_DATA_POLYPHONY:
+ return VMSetPolyphony(pEASData->pVoiceMgr, pSynth, value);
+
+ case PARSER_DATA_PRIORITY:
+ return VMSetPriority(pEASData->pVoiceMgr, pSynth, value);
+
+ case PARSER_DATA_TRANSPOSITION:
+ VMSetTranposition(pSynth, value);
+ break;
+
+ case PARSER_DATA_VOLUME:
+ VMSetVolume(pSynth, (EAS_U16) value);
+ break;
+
+ default:
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Invalid paramter %d in call to EAS_IntSetStrmParam", param); */ }
+ return EAS_ERROR_INVALID_PARAMETER;
+ }
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_IntGetStrmParam()
+ *----------------------------------------------------------------------------
+ * This routine gets common parameters like transpose, volume, etc.
+ * First, it attempts to use the parser EAS_GetStreamParameter interface. If that
+ * fails, it attempts to get the synth handle from the parser and
+ * get the parameter directly on the synth.
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_IntGetStrmParam (S_EAS_DATA *pEASData, EAS_HANDLE pStream, EAS_INT param, EAS_I32 *pValue)
+{
+ S_SYNTH *pSynth;
+
+ /* try to set the parameter */
+ if (EAS_GetStreamParameter(pEASData, pStream, param, pValue) == EAS_SUCCESS)
+ return EAS_SUCCESS;
+
+ /* get a pointer to the synth object and retrieve data directly */
+ /*lint -e{740} we are cheating by passing a pointer through this interface */
+ if (EAS_GetStreamParameter(pEASData, pStream, PARSER_DATA_SYNTH_HANDLE, (EAS_I32*) &pSynth) != EAS_SUCCESS)
+ return EAS_ERROR_INVALID_PARAMETER;
+
+ if (pSynth == NULL)
+ return EAS_ERROR_INVALID_PARAMETER;
+
+ switch (param)
+ {
+ case PARSER_DATA_POLYPHONY:
+ return VMGetPolyphony(pEASData->pVoiceMgr, pSynth, pValue);
+
+ case PARSER_DATA_PRIORITY:
+ return VMGetPriority(pEASData->pVoiceMgr, pSynth, pValue);
+
+ case PARSER_DATA_TRANSPOSITION:
+ VMGetTranposition(pSynth, pValue);
+ break;
+
+ case PARSER_DATA_NOTE_COUNT:
+ *pValue = VMGetNoteCount(pSynth);
+ break;
+
+ default:
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Invalid paramter %d in call to EAS_IntSetStrmParam", param); */ }
+ return EAS_ERROR_INVALID_PARAMETER;
+ }
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_AllocateStream()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Allocates a stream handle
+ *
+ * Inputs:
+ *
+ * Outputs:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_INT EAS_AllocateStream (EAS_DATA_HANDLE pEASData)
+{
+ EAS_INT streamNum;
+
+ /* check for static allocation, only one stream allowed */
+ if (pEASData->staticMemoryModel)
+ {
+ if (pEASData->streams[0].handle != NULL)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Attempt to open multiple streams in static model\n"); */ }
+ return -1;
+ }
+ return 0;
+ }
+
+ /* dynamic model */
+ for (streamNum = 0; streamNum < MAX_NUMBER_STREAMS; streamNum++)
+ if (pEASData->streams[streamNum].handle == NULL)
+ break;
+ if (streamNum == MAX_NUMBER_STREAMS)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Exceeded maximum number of open streams\n"); */ }
+ return -1;
+ }
+ return streamNum;
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_InitStream()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Initialize a stream
+ *
+ * Inputs:
+ *
+ * Outputs:
+ *
+ *----------------------------------------------------------------------------
+*/
+static void EAS_InitStream (S_EAS_STREAM *pStream, EAS_VOID_PTR pParserModule, EAS_VOID_PTR streamHandle)
+{
+ pStream->pParserModule = pParserModule;
+ pStream->handle = streamHandle;
+ pStream->time = 0;
+ pStream->frameLength = AUDIO_FRAME_LENGTH;
+ pStream->repeatCount = 0;
+ pStream->volume = DEFAULT_STREAM_VOLUME;
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_Config()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Returns a pointer to a structure containing the configuration options
+ * in this library build.
+ *
+ * Inputs:
+ *
+ * Outputs:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC const S_EAS_LIB_CONFIG *EAS_Config (void)
+{
+ return &easLibConfig;
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_Init()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Initialize the synthesizer library
+ *
+ * Inputs:
+ * ppEASData - pointer to data handle variable for this instance
+ *
+ * Outputs:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_Init (EAS_DATA_HANDLE *ppEASData)
+{
+ EAS_HW_DATA_HANDLE pHWInstData;
+ EAS_RESULT result;
+ S_EAS_DATA *pEASData;
+ EAS_INT module;
+ EAS_BOOL staticMemoryModel;
+
+ /* get the memory model */
+ staticMemoryModel = EAS_CMStaticMemoryModel();
+
+ /* initialize the host wrapper interface */
+ *ppEASData = NULL;
+ if ((result = EAS_HWInit(&pHWInstData)) != EAS_SUCCESS)
+ return result;
+
+ /* check Configuration Module for S_EAS_DATA allocation */
+ if (staticMemoryModel)
+ pEASData = EAS_CMEnumData(EAS_CM_EAS_DATA);
+ else
+ pEASData = EAS_HWMalloc(pHWInstData, sizeof(S_EAS_DATA));
+ if (!pEASData)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_FATAL, "Failed to allocate EAS library memory\n"); */ }
+ return EAS_ERROR_MALLOC_FAILED;
+ }
+
+ /* initialize some data */
+ EAS_HWMemSet(pEASData, 0, sizeof(S_EAS_DATA));
+ pEASData->staticMemoryModel = (EAS_BOOL8) staticMemoryModel;
+ pEASData->hwInstData = pHWInstData;
+ pEASData->renderTime = 0;
+
+ /* set header search flag */
+#ifdef FILE_HEADER_SEARCH
+ pEASData->searchHeaderFlag = EAS_TRUE;
+#endif
+
+ /* initalize parameters */
+ EAS_SetVolume(pEASData, NULL, DEFAULT_VOLUME);
+
+#ifdef _METRICS_ENABLED
+ /* initalize the metrics module */
+ pEASData->pMetricsModule = EAS_CMEnumOptModules(EAS_MODULE_METRICS);
+ if (pEASData->pMetricsModule != NULL)
+ {
+ if ((result = (*pEASData->pMetricsModule->pfInit)(pEASData, &pEASData->pMetricsData)) != EAS_SUCCESS)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Error %ld initializing metrics module\n", result); */ }
+ return result;
+ }
+ }
+#endif
+
+ /* initailize the voice manager & synthesizer */
+ if ((result = VMInitialize(pEASData)) != EAS_SUCCESS)
+ return result;
+
+ /* initialize mix engine */
+ if ((result = EAS_MixEngineInit(pEASData)) != EAS_SUCCESS)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Error %ld starting up mix engine\n", result); */ }
+ return result;
+ }
+
+ /* initialize effects modules */
+ for (module = 0; module < NUM_EFFECTS_MODULES; module++)
+ {
+ pEASData->effectsModules[module].effect = EAS_CMEnumFXModules(module);
+ if (pEASData->effectsModules[module].effect != NULL)
+ {
+ if ((result = (*pEASData->effectsModules[module].effect->pfInit)(pEASData, &pEASData->effectsModules[module].effectData)) != EAS_SUCCESS)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_FATAL, "Initialization of effects module %d returned %d\n", module, result); */ }
+ return result;
+ }
+ }
+ }
+
+ /* initialize PCM engine */
+ if ((result = EAS_PEInit(pEASData)) != EAS_SUCCESS)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_FATAL, "EAS_PEInit failed with error code %ld\n", result); */ }
+ return result;
+ }
+
+ /* return instance data pointer to host */
+ *ppEASData = pEASData;
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_Shutdown()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Shuts down the library. Deallocates any memory associated with the
+ * synthesizer (dynamic memory model only)
+ *
+ * Inputs:
+ * pEASData - handle to data for this instance
+ *
+ * Outputs:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_Shutdown (EAS_DATA_HANDLE pEASData)
+{
+ EAS_HW_DATA_HANDLE hwInstData;
+ EAS_RESULT result, reportResult;
+ EAS_INT i;
+
+ /* establish pointers */
+ hwInstData = pEASData->hwInstData;
+
+ /* check for NULL handle */
+ if (!pEASData)
+ return EAS_ERROR_HANDLE_INTEGRITY;
+
+ /* if there are streams open, close them */
+ reportResult = EAS_SUCCESS;
+ for (i = 0; i < MAX_NUMBER_STREAMS; i++)
+ {
+ if (pEASData->streams[i].pParserModule && pEASData->streams[i].handle)
+ {
+ if ((result = (*((S_FILE_PARSER_INTERFACE*)(pEASData->streams[i].pParserModule))->pfClose)(pEASData, pEASData->streams[i].handle)) != EAS_SUCCESS)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Error %ld shutting down parser module\n", result); */ }
+ reportResult = result;
+ }
+ }
+ }
+
+ /* shutdown PCM engine */
+ if ((result = EAS_PEShutdown(pEASData)) != EAS_SUCCESS)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Error %ld shutting down PCM engine\n", result); */ }
+ if (reportResult == EAS_SUCCESS)
+ reportResult = result;
+ }
+
+ /* shutdown mix engine */
+ if ((result = EAS_MixEngineShutdown(pEASData)) != EAS_SUCCESS)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Error %ld shutting down mix engine\n", result); */ }
+ if (reportResult == EAS_SUCCESS)
+ reportResult = result;
+ }
+
+ /* shutdown effects modules */
+ for (i = 0; i < NUM_EFFECTS_MODULES; i++)
+ {
+ if (pEASData->effectsModules[i].effect)
+ {
+ if ((result = (*pEASData->effectsModules[i].effect->pfShutdown)(pEASData, pEASData->effectsModules[i].effectData)) != EAS_SUCCESS)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_FATAL, "Shutdown of effects module %d returned %d\n", i, result); */ }
+ if (reportResult == EAS_SUCCESS)
+ reportResult = result;
+ }
+ }
+ }
+
+ /* shutdown the voice manager & synthesizer */
+ VMShutdown(pEASData);
+
+#ifdef _METRICS_ENABLED
+ /* shutdown the metrics module */
+ if (pEASData->pMetricsModule != NULL)
+ {
+ if ((result = (*pEASData->pMetricsModule->pfShutdown)(pEASData, pEASData->pMetricsData)) != EAS_SUCCESS)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Error %ld shutting down metrics module\n", result); */ }
+ if (reportResult == EAS_SUCCESS)
+ reportResult = result;
+ }
+ }
+#endif
+
+ /* release allocated memory */
+ if (!pEASData->staticMemoryModel)
+ EAS_HWFree(hwInstData, pEASData);
+
+ /* shutdown host wrappers */
+ if (hwInstData)
+ {
+ if ((result = EAS_HWShutdown(hwInstData)) != EAS_SUCCESS)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Error %ld shutting down host wrappers\n", result); */ }
+ if (reportResult == EAS_SUCCESS)
+ reportResult = result;
+ }
+ }
+
+ return reportResult;
+}
+
+#ifdef JET_INTERFACE
+/*----------------------------------------------------------------------------
+ * EAS_OpenJETStream()
+ *----------------------------------------------------------------------------
+ * Private interface for JET to open an SMF stream with an offset
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_OpenJETStream (EAS_DATA_HANDLE pEASData, EAS_FILE_HANDLE fileHandle, EAS_I32 offset, EAS_HANDLE *ppStream)
+{
+ EAS_RESULT result;
+ EAS_VOID_PTR streamHandle;
+ S_FILE_PARSER_INTERFACE *pParserModule;
+ EAS_INT streamNum;
+
+ /* allocate a stream */
+ if ((streamNum = EAS_AllocateStream(pEASData)) < 0)
+ return EAS_ERROR_MAX_STREAMS_OPEN;
+
+ /* check Configuration Module for SMF parser */
+ *ppStream = NULL;
+ streamHandle = NULL;
+ pParserModule = (S_FILE_PARSER_INTERFACE *) EAS_CMEnumModules(0);
+ if (pParserModule == NULL)
+ return EAS_ERROR_UNRECOGNIZED_FORMAT;
+
+ /* see if SMF parser recognizes the file */
+ if ((result = (*pParserModule->pfCheckFileType)(pEASData, fileHandle, &streamHandle, offset)) != EAS_SUCCESS)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "CheckFileType returned error %ld\n", result); */ }
+ return result;
+ }
+
+ /* parser recognized the file, return the handle */
+ if (streamHandle)
+ {
+ EAS_InitStream(&pEASData->streams[streamNum], pParserModule, streamHandle);
+ *ppStream = &pEASData->streams[streamNum];
+ return EAS_SUCCESS;
+ }
+
+ return EAS_ERROR_UNRECOGNIZED_FORMAT;
+}
+#endif
+
+/*----------------------------------------------------------------------------
+ * EAS_OpenFile()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Opens a file for audio playback.
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * pHandle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_OpenFile (EAS_DATA_HANDLE pEASData, EAS_FILE_LOCATOR locator, EAS_HANDLE *ppStream)
+{
+ EAS_RESULT result;
+ EAS_FILE_HANDLE fileHandle;
+ EAS_VOID_PTR streamHandle;
+ S_FILE_PARSER_INTERFACE *pParserModule;
+ EAS_INT streamNum;
+ EAS_INT moduleNum;
+
+ /* open the file */
+ if ((result = EAS_HWOpenFile(pEASData->hwInstData, locator, &fileHandle, EAS_FILE_READ)) != EAS_SUCCESS)
+ return result;
+
+ /* allocate a stream */
+ if ((streamNum = EAS_AllocateStream(pEASData)) < 0)
+ return EAS_ERROR_MAX_STREAMS_OPEN;
+
+ /* check Configuration Module for file parsers */
+ pParserModule = NULL;
+ *ppStream = NULL;
+ streamHandle = NULL;
+ for (moduleNum = 0; ; moduleNum++)
+ {
+ pParserModule = (S_FILE_PARSER_INTERFACE *) EAS_CMEnumModules(moduleNum);
+ if (pParserModule == NULL)
+ break;
+
+ /* see if this parser recognizes it */
+ if ((result = (*pParserModule->pfCheckFileType)(pEASData, fileHandle, &streamHandle, 0L)) != EAS_SUCCESS)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "CheckFileType returned error %ld\n", result); */ }
+ return result;
+ }
+
+ /* parser recognized the file, return the handle */
+ if (streamHandle)
+ {
+
+ /* save the parser pointer and file handle */
+ EAS_InitStream(&pEASData->streams[streamNum], pParserModule, streamHandle);
+ *ppStream = &pEASData->streams[streamNum];
+ return EAS_SUCCESS;
+ }
+
+ /* rewind the file for the next parser */
+ if ((result = EAS_HWFileSeek(pEASData->hwInstData, fileHandle, 0L)) != EAS_SUCCESS)
+ return result;
+ }
+
+ /* no parser was able to recognize the file, close it and return an error */
+ EAS_HWCloseFile(pEASData->hwInstData, fileHandle);
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "No parser recognized the requested file\n"); */ }
+ return EAS_ERROR_UNRECOGNIZED_FORMAT;
+}
+
+#ifdef MMAPI_SUPPORT
+/*----------------------------------------------------------------------------
+ * EAS_MMAPIToneControl()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Opens a ToneControl file for audio playback.
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * pHandle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_MMAPIToneControl (EAS_DATA_HANDLE pEASData, EAS_FILE_LOCATOR locator, EAS_HANDLE *ppStream)
+{
+ EAS_RESULT result;
+ EAS_FILE_HANDLE fileHandle;
+ EAS_VOID_PTR streamHandle;
+ S_FILE_PARSER_INTERFACE *pParserModule;
+ EAS_INT streamNum;
+
+ /* check if the tone control parser is available */
+ *ppStream = NULL;
+ streamHandle = NULL;
+ pParserModule = EAS_CMEnumOptModules(EAS_MODULE_MMAPI_TONE_CONTROL);
+ if (pParserModule == NULL)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "EAS_MMAPIToneControl: ToneControl parser not available\n"); */ }
+ return EAS_ERROR_FEATURE_NOT_AVAILABLE;
+ }
+
+ /* open the file */
+ if ((result = EAS_HWOpenFile(pEASData->hwInstData, locator, &fileHandle, EAS_FILE_READ)) != EAS_SUCCESS)
+ return result;
+
+ /* allocate a stream */
+ if ((streamNum = EAS_AllocateStream(pEASData)) < 0)
+ return EAS_ERROR_MAX_STREAMS_OPEN;
+
+ /* see if ToneControl parser recognizes it */
+ if ((result = (*pParserModule->pfCheckFileType)(pEASData, fileHandle, &streamHandle, 0L)) != EAS_SUCCESS)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "CheckFileType returned error %ld\n", result); */ }
+ return result;
+ }
+
+ /* parser accepted the file, return the handle */
+ if (streamHandle)
+ {
+
+ /* save the parser pointer and file handle */
+ EAS_InitStream(&pEASData->streams[streamNum], pParserModule, streamHandle);
+ *ppStream = &pEASData->streams[streamNum];
+ return EAS_SUCCESS;
+ }
+
+ /* parser did not recognize the file, close it and return an error */
+ EAS_HWCloseFile(pEASData->hwInstData, fileHandle);
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "No parser recognized the requested file\n"); */ }
+ return EAS_ERROR_UNRECOGNIZED_FORMAT;
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_GetWaveFmtChunk
+ *----------------------------------------------------------------------------
+ * Helper function to retrieve WAVE file fmt chunk for MMAPI
+ *----------------------------------------------------------------------------
+ * pEASData - pointer to EAS persistent data object
+ * pStream - stream handle
+ * pFmtChunk - pointer to variable to receive current setting
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_GetWaveFmtChunk (S_EAS_DATA *pEASData, EAS_HANDLE pStream, EAS_VOID_PTR *ppFmtChunk)
+{
+ EAS_RESULT result;
+ EAS_I32 value;
+
+ if ((result = EAS_GetStreamParameter(pEASData, pStream, PARSER_DATA_FORMAT, &value)) != EAS_SUCCESS)
+ return result;
+ *ppFmtChunk = (EAS_VOID_PTR) value;
+ return EAS_SUCCESS;
+}
+#endif
+
+/*----------------------------------------------------------------------------
+ * EAS_GetFileType
+ *----------------------------------------------------------------------------
+ * Returns the file type (see eas_types.h for enumerations)
+ *----------------------------------------------------------------------------
+ * pEASData - pointer to EAS persistent data object
+ * pStream - stream handle
+ * pFileType - pointer to variable to receive file type
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_GetFileType (S_EAS_DATA *pEASData, EAS_HANDLE pStream, EAS_I32 *pFileType)
+{
+ if (!EAS_StreamReady (pEASData, pStream))
+ return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
+ return EAS_GetStreamParameter(pEASData, pStream, PARSER_DATA_FILE_TYPE, pFileType);
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_Prepare()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Prepares the synthesizer to play the file or stream. Parses the first
+ * frame of data from the file and arms the synthesizer.
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - file or stream handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_Prepare (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream)
+{
+ S_FILE_PARSER_INTERFACE *pParserModule;
+ EAS_STATE state;
+ EAS_RESULT result;
+
+ pParserModule = (S_FILE_PARSER_INTERFACE*) pStream->pParserModule;
+ if (pParserModule == NULL)
+ return EAS_ERROR_FEATURE_NOT_AVAILABLE;
+
+ /* check for valid state */
+ result = pParserModule->pfState(pEASData, pStream->handle, &state);
+ if (result == EAS_SUCCESS)
+ {
+ /* prepare the stream */
+ if (state == EAS_STATE_OPEN)
+ {
+ pParserModule = (S_FILE_PARSER_INTERFACE*) pStream->pParserModule;
+ result = (*pParserModule->pfPrepare)(pEASData, pStream->handle);
+
+ /* set volume */
+ if (result == EAS_SUCCESS)
+ result = EAS_SetVolume(pEASData, pStream, pStream->volume);
+ }
+ else
+ result = EAS_ERROR_NOT_VALID_IN_THIS_STATE;
+
+ }
+
+ return result;
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_Render()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Parse the Midi data and render PCM audio data.
+ *
+ * Inputs:
+ * pEASData - buffer for internal EAS data
+ * pOut - output buffer pointer
+ * nNumRequested - requested num samples to generate
+ * pnNumGenerated - actual number of samples generated
+ *
+ * Outputs:
+ * EAS_SUCCESS if PCM data was successfully rendered
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_Render (EAS_DATA_HANDLE pEASData, EAS_PCM *pOut, EAS_I32 numRequested, EAS_I32 *pNumGenerated)
+{
+ S_FILE_PARSER_INTERFACE *pParserModule;
+ EAS_RESULT result;
+ EAS_I32 voicesRendered;
+ EAS_STATE parserState;
+ EAS_INT streamNum;
+
+ /* assume no samples generated and reset workload */
+ *pNumGenerated = 0;
+ VMInitWorkload(pEASData->pVoiceMgr);
+
+ /* no support for other buffer sizes yet */
+ if (numRequested != BUFFER_SIZE_IN_MONO_SAMPLES)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "This library supports only %ld samples in buffer, host requested %ld samples\n",
+ (EAS_I32) BUFFER_SIZE_IN_MONO_SAMPLES, numRequested); */ }
+ return EAS_BUFFER_SIZE_MISMATCH;
+ }
+
+#ifdef _METRICS_ENABLED
+ /* start performance counter */
+ if (pEASData->pMetricsData)
+ (*pEASData->pMetricsModule->pfStartTimer)(pEASData->pMetricsData, EAS_PM_TOTAL_TIME);
+#endif
+
+ /* prep the frame buffer, do mix engine prep only if TRUE */
+#ifdef _SPLIT_ARCHITECTURE
+ if (VMStartFrame(pEASData))
+ EAS_MixEnginePrep(pEASData, numRequested);
+#else
+ /* prep the mix engine */
+ EAS_MixEnginePrep(pEASData, numRequested);
+#endif
+
+ /* save the output buffer pointer */
+ pEASData->pOutputAudioBuffer = pOut;
+
+
+#ifdef _METRICS_ENABLED
+ /* start performance counter */
+ if (pEASData->pMetricsData)
+ (*pEASData->pMetricsModule->pfStartTimer)(pEASData->pMetricsData, EAS_PM_PARSE_TIME);
+#endif
+
+ /* if we haven't finished parsing from last time, do it now */
+ /* need to parse another frame of events before we render again */
+ for (streamNum = 0; streamNum < MAX_NUMBER_STREAMS; streamNum++)
+ {
+ /* clear the locate flag */
+ pEASData->streams[streamNum].streamFlags &= ~STREAM_FLAGS_LOCATE;
+
+ if (pEASData->streams[streamNum].pParserModule)
+ {
+
+ /* establish pointer to parser module */
+ pParserModule = pEASData->streams[streamNum].pParserModule;
+
+ /* handle pause */
+ if (pEASData->streams[streamNum].streamFlags & STREAM_FLAGS_PAUSE)
+ {
+ if (pParserModule->pfPause)
+ result = pParserModule->pfPause(pEASData, pEASData->streams[streamNum].handle);
+ pEASData->streams[streamNum].streamFlags &= ~STREAM_FLAGS_PAUSE;
+ }
+
+ /* get current state */
+ if ((result = (*pParserModule->pfState)(pEASData, pEASData->streams[streamNum].handle, &parserState)) != EAS_SUCCESS)
+ return result;
+
+ /* handle resume */
+ if (parserState == EAS_STATE_PAUSED)
+ {
+ if (pEASData->streams[streamNum].streamFlags & STREAM_FLAGS_RESUME)
+ {
+ if (pParserModule->pfResume)
+ result = pParserModule->pfResume(pEASData, pEASData->streams[streamNum].handle);
+ pEASData->streams[streamNum].streamFlags &= ~STREAM_FLAGS_RESUME;
+ }
+ }
+
+ /* if necessary, parse stream */
+ if ((pEASData->streams[streamNum].streamFlags & STREAM_FLAGS_PARSED) == 0)
+ if ((result = EAS_ParseEvents(pEASData, &pEASData->streams[streamNum], pEASData->streams[streamNum].time + pEASData->streams[streamNum].frameLength, eParserModePlay)) != EAS_SUCCESS)
+ return result;
+
+ /* check for an early abort */
+ if ((pEASData->streams[streamNum].streamFlags) == 0)
+ {
+
+#ifdef _METRICS_ENABLED
+ /* stop performance counter */
+ if (pEASData->pMetricsData)
+ (*pEASData->pMetricsModule->pfStartTimer)(pEASData->pMetricsData, EAS_PM_TOTAL_TIME);
+#endif
+
+ return EAS_SUCCESS;
+ }
+
+ /* check for repeat */
+ if (pEASData->streams[streamNum].repeatCount)
+ {
+
+ /* check for stopped state */
+ if ((result = (*pParserModule->pfState)(pEASData, pEASData->streams[streamNum].handle, &parserState)) != EAS_SUCCESS)
+ return result;
+ if (parserState == EAS_STATE_STOPPED)
+ {
+
+ /* decrement repeat count, unless it is negative */
+ if (pEASData->streams[streamNum].repeatCount > 0)
+ pEASData->streams[streamNum].repeatCount--;
+
+ /* reset the parser */
+ if ((result = (*pParserModule->pfReset)(pEASData, pEASData->streams[streamNum].handle)) != EAS_SUCCESS)
+ return result;
+ pEASData->streams[streamNum].time = 0;
+ }
+ }
+ }
+ }
+
+#ifdef _METRICS_ENABLED
+ /* stop performance counter */
+ if (pEASData->pMetricsData)
+ (void)(*pEASData->pMetricsModule->pfStopTimer)(pEASData->pMetricsData, EAS_PM_PARSE_TIME);
+#endif
+
+#ifdef _METRICS_ENABLED
+ /* start the render timer */
+ if (pEASData->pMetricsData)
+ (*pEASData->pMetricsModule->pfStartTimer)(pEASData->pMetricsData, EAS_PM_RENDER_TIME);
+#endif
+
+ /* render audio */
+ if ((result = VMRender(pEASData->pVoiceMgr, BUFFER_SIZE_IN_MONO_SAMPLES, pEASData->pMixBuffer, &voicesRendered)) != EAS_SUCCESS)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "pfRender function returned error %ld\n", result); */ }
+ return result;
+ }
+
+#ifdef _METRICS_ENABLED
+ /* stop the render timer */
+ if (pEASData->pMetricsData) {
+ (*pEASData->pMetricsModule->pfIncrementCounter)(pEASData->pMetricsData, EAS_PM_FRAME_COUNT, 1);
+ (void)(*pEASData->pMetricsModule->pfStopTimer)(pEASData->pMetricsData, EAS_PM_RENDER_TIME);
+ (*pEASData->pMetricsModule->pfIncrementCounter)(pEASData->pMetricsData, EAS_PM_TOTAL_VOICE_COUNT, (EAS_U32) voicesRendered);
+ (void)(*pEASData->pMetricsModule->pfRecordMaxValue)(pEASData->pMetricsData, EAS_PM_MAX_VOICES, (EAS_U32) voicesRendered);
+ }
+#endif
+
+ //2 Do we really need frameParsed?
+ /* need to parse another frame of events before we render again */
+ for (streamNum = 0; streamNum < MAX_NUMBER_STREAMS; streamNum++)
+ if (pEASData->streams[streamNum].pParserModule != NULL)
+ pEASData->streams[streamNum].streamFlags &= ~STREAM_FLAGS_PARSED;
+
+#ifdef _METRICS_ENABLED
+ /* start performance counter */
+ if (pEASData->pMetricsData)
+ (*pEASData->pMetricsModule->pfStartTimer)(pEASData->pMetricsData, EAS_PM_STREAM_TIME);
+#endif
+
+ /* render PCM audio */
+ if ((result = EAS_PERender(pEASData, numRequested)) != EAS_SUCCESS)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "EAS_PERender returned error %ld\n", result); */ }
+ return result;
+ }
+
+#ifdef _METRICS_ENABLED
+ /* stop the stream timer */
+ if (pEASData->pMetricsData)
+ (void)(*pEASData->pMetricsModule->pfStopTimer)(pEASData->pMetricsData, EAS_PM_STREAM_TIME);
+#endif
+
+#ifdef _METRICS_ENABLED
+ /* start the post timer */
+ if (pEASData->pMetricsData)
+ (*pEASData->pMetricsModule->pfStartTimer)(pEASData->pMetricsData, EAS_PM_POST_TIME);
+#endif
+
+ /* for split architecture, send DSP vectors. Do post only if return is TRUE */
+#ifdef _SPLIT_ARCHITECTURE
+ if (VMEndFrame(pEASData))
+ {
+ /* now do post-processing */
+ EAS_MixEnginePost(pEASData, numRequested);
+ *pNumGenerated = numRequested;
+ }
+#else
+ /* now do post-processing */
+ EAS_MixEnginePost(pEASData, numRequested);
+ *pNumGenerated = numRequested;
+#endif
+
+#ifdef _METRICS_ENABLED
+ /* stop the post timer */
+ if (pEASData->pMetricsData)
+ (void)(*pEASData->pMetricsModule->pfStopTimer)(pEASData->pMetricsData, EAS_PM_POST_TIME);
+#endif
+
+ /* advance render time */
+ pEASData->renderTime += AUDIO_FRAME_LENGTH;
+
+#if 0
+ /* dump workload for debug */
+ if (pEASData->pVoiceMgr->workload)
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Workload = %d\n", pEASData->pVoiceMgr->workload); */ }
+#endif
+
+#ifdef _METRICS_ENABLED
+ /* stop performance counter */
+ if (pEASData->pMetricsData)
+ {
+ PERF_TIMER temp;
+ temp = (*pEASData->pMetricsModule->pfStopTimer)(pEASData->pMetricsData, EAS_PM_TOTAL_TIME);
+
+ /* if max render time, record the number of voices and time */
+ if ((*pEASData->pMetricsModule->pfRecordMaxValue)
+ (pEASData->pMetricsData, EAS_PM_MAX_CYCLES, (EAS_U32) temp))
+ {
+ (*pEASData->pMetricsModule->pfRecordValue)(pEASData->pMetricsData, EAS_PM_MAX_CYCLES_VOICES, (EAS_U32) voicesRendered);
+ (*pEASData->pMetricsModule->pfRecordValue)(pEASData->pMetricsData, EAS_PM_MAX_CYCLES_TIME, (EAS_I32) (pEASData->renderTime >> 8));
+ }
+ }
+#endif
+
+#ifdef JET_INTERFACE
+ /* let JET to do its thing */
+ if (pEASData->jetHandle != NULL)
+ {
+ result = JET_Process(pEASData);
+ if (result != EAS_SUCCESS)
+ return result;
+ }
+#endif
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_SetRepeat()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Set the selected stream to repeat.
+ *
+ * Inputs:
+ * pEASData - handle to data for this instance
+ * handle - handle to stream
+ * repeatCount - repeat count
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ *
+ * Notes:
+ * 0 = no repeat
+ * 1 = repeat once, i.e. play through twice
+ * -1 = repeat forever
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pEASData) reserved for future use */
+EAS_PUBLIC EAS_RESULT EAS_SetRepeat (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_I32 repeatCount)
+{
+ pStream->repeatCount = repeatCount;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_GetRepeat()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Gets the current repeat count for the selected stream.
+ *
+ * Inputs:
+ * pEASData - handle to data for this instance
+ * handle - handle to stream
+ * pRrepeatCount - pointer to variable to hold repeat count
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ *
+ * Notes:
+ * 0 = no repeat
+ * 1 = repeat once, i.e. play through twice
+ * -1 = repeat forever
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pEASData) reserved for future use */
+EAS_PUBLIC EAS_RESULT EAS_GetRepeat (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_I32 *pRepeatCount)
+{
+ *pRepeatCount = pStream->repeatCount;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_SetPlaybackRate()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Sets the playback rate.
+ *
+ * Inputs:
+ * pEASData - handle to data for this instance
+ * handle - handle to stream
+ * rate - rate (28-bit fractional amount)
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pEASData) reserved for future use */
+EAS_PUBLIC EAS_RESULT EAS_SetPlaybackRate (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_U32 rate)
+{
+
+ /* check range */
+ if ((rate < (1 << 27)) || (rate > (1 << 29)))
+ return EAS_ERROR_INVALID_PARAMETER;
+
+ /* calculate new frame length
+ *
+ * NOTE: The maximum frame length we can accomodate based on a
+ * maximum rate of 2.0 (2^28) is 2047 (2^13-1). To accomodate a
+ * longer frame length or a higher maximum rate, the fixed point
+ * divide below will need to be adjusted
+ */
+ pStream->frameLength = (AUDIO_FRAME_LENGTH * (rate >> 8)) >> 20;
+
+ /* notify stream of new playback rate */
+ EAS_SetStreamParameter(pEASData, pStream, PARSER_DATA_PLAYBACK_RATE, (EAS_I32) rate);
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_SetTransposition)
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Sets the key tranposition for the synthesizer. Transposes all
+ * melodic instruments by the specified amount. Range is limited
+ * to +/-12 semitones.
+ *
+ * Inputs:
+ * pEASData - handle to data for this instance
+ * handle - handle to stream
+ * transposition - +/-12 semitones
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_SetTransposition (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_I32 transposition)
+{
+
+ /* check range */
+ if ((transposition < -12) || (transposition > 12))
+ return EAS_ERROR_INVALID_PARAMETER;
+
+ if (!EAS_StreamReady(pEASData, pStream))
+ return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
+ return EAS_IntSetStrmParam(pEASData, pStream, PARSER_DATA_TRANSPOSITION, transposition);
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_ParseEvents()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Parse events in the current streams until the desired time is reached.
+ *
+ * Inputs:
+ * pEASData - buffer for internal EAS data
+ * endTime - stop parsing if this time is reached
+ * parseMode - play, locate, or metadata
+ *
+ * Outputs:
+ * EAS_SUCCESS if PCM data was successfully rendered
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT EAS_ParseEvents (S_EAS_DATA *pEASData, EAS_HANDLE pStream, EAS_U32 endTime, EAS_INT parseMode)
+{
+ S_FILE_PARSER_INTERFACE *pParserModule;
+ EAS_RESULT result;
+ EAS_I32 parserState;
+ EAS_BOOL done;
+ EAS_INT yieldCount = YIELD_EVENT_COUNT;
+ EAS_U32 time = 0;
+
+ /* does this parser have a time function? */
+ pParserModule = pStream->pParserModule;
+ if (pParserModule->pfTime == NULL)
+ {
+ /* check state */
+ if ((result = (*pParserModule->pfState)(pEASData, pStream->handle, &parserState)) != EAS_SUCCESS)
+ return result;
+ /* if play state, advance time */
+ if ((parserState >= EAS_STATE_READY) && (parserState <= EAS_STATE_PAUSING))
+ pStream->time += pStream->frameLength;
+ done = EAS_TRUE;
+ }
+
+ /* assume we're not done, in case we abort out */
+ else
+ {
+ pStream->streamFlags &= ~STREAM_FLAGS_PARSED;
+ done = EAS_FALSE;
+ }
+
+ while (!done)
+ {
+
+ /* check for stopped state */
+ if ((result = (*pParserModule->pfState)(pEASData, pStream->handle, &parserState)) != EAS_SUCCESS)
+ return result;
+ if (parserState > EAS_STATE_PLAY)
+ {
+ /* save current time if we're not in play mode */
+ if (parseMode != eParserModePlay)
+ pStream->time = time << 8;
+ done = EAS_TRUE;
+ break;
+ }
+
+ /* get the next event time */
+ if (pParserModule->pfTime)
+ {
+ if ((result = (*pParserModule->pfTime)(pEASData, pStream->handle, &time)) != EAS_SUCCESS)
+ return result;
+
+ /* if next event is within this frame, parse it */
+ if (time < (endTime >> 8))
+ {
+
+ /* parse the next event */
+ if (pParserModule->pfEvent)
+ if ((result = (*pParserModule->pfEvent)(pEASData, pStream->handle, parseMode)) != EAS_SUCCESS)
+ return result;
+ }
+
+ /* no more events in this frame, advance time */
+ else
+ {
+ pStream->time = endTime;
+ done = EAS_TRUE;
+ }
+ }
+
+ /* check for max workload exceeded */
+ if (VMCheckWorkload(pEASData->pVoiceMgr))
+ {
+ /* stop even though we may not have parsed
+ * all the events in this frame. The parser will try to
+ * catch up on the next frame.
+ */
+ break;
+ }
+
+ /* give host a chance for an early abort */
+ if (--yieldCount == 0)
+ {
+ if (EAS_HWYield(pEASData->hwInstData))
+ break;
+ yieldCount = YIELD_EVENT_COUNT;
+ }
+ }
+
+ /* if no early abort, parsing is complete for this frame */
+ if (done)
+ pStream->streamFlags |= STREAM_FLAGS_PARSED;
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_ParseMetaData()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ *
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - file or stream handle
+ * playLength - pointer to variable to store the play length (in msecs)
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ * - resets the parser to the start of the file
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_ParseMetaData (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_I32 *playLength)
+{
+ S_FILE_PARSER_INTERFACE *pParserModule;
+ EAS_RESULT result;
+ EAS_STATE state;
+
+ pParserModule = (S_FILE_PARSER_INTERFACE*) pStream->pParserModule;
+ if (pParserModule == NULL)
+ return EAS_ERROR_FEATURE_NOT_AVAILABLE;
+
+ /* check parser state */
+ if ((result = (*pParserModule->pfState)(pEASData, pStream->handle, &state)) != EAS_SUCCESS)
+ return result;
+ if (state >= EAS_STATE_OPEN)
+ return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
+
+ /* if parser has metadata function, use that */
+ if (pParserModule->pfGetMetaData != NULL)
+ return pParserModule->pfGetMetaData(pEASData, pStream->handle, playLength);
+
+ /* reset the parser to the beginning */
+ if ((result = (*pParserModule->pfReset)(pEASData, pStream->handle)) != EAS_SUCCESS)
+ return result;
+
+ /* parse the file to end */
+ pStream->time = 0;
+ VMInitWorkload(pEASData->pVoiceMgr);
+ if ((result = EAS_ParseEvents(pEASData, pStream, 0x7fffffff, eParserModeMetaData)) != EAS_SUCCESS)
+ return result;
+
+ /* get the parser time */
+ if ((result = EAS_GetLocation(pEASData, pStream, playLength)) != EAS_SUCCESS)
+ return result;
+
+ /* reset the parser to the beginning */
+ pStream->time = 0;
+ return (*pParserModule->pfReset)(pEASData, pStream->handle);
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_RegisterMetaDataCallback()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Registers a metadata callback function for parsed metadata.
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - file or stream handle
+ * cbFunc - pointer to host callback function
+ * metaDataBuffer - pointer to metadata buffer
+ * metaDataBufSize - maximum size of the metadata buffer
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_RegisterMetaDataCallback (
+ EAS_DATA_HANDLE pEASData,
+ EAS_HANDLE pStream,
+ EAS_METADATA_CBFUNC cbFunc,
+ char *metaDataBuffer,
+ EAS_I32 metaDataBufSize,
+ EAS_VOID_PTR pUserData)
+{
+ S_METADATA_CB metadata;
+
+ if (!EAS_StreamReady(pEASData, pStream))
+ return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
+
+ /* register callback function */
+ metadata.callback = cbFunc;
+ metadata.buffer = metaDataBuffer;
+ metadata.bufferSize = metaDataBufSize;
+ metadata.pUserData = pUserData;
+ return EAS_SetStreamParameter(pEASData, pStream, PARSER_DATA_METADATA_CB, (EAS_I32) &metadata);
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_GetNoteCount ()
+ *----------------------------------------------------------------------------
+ * Returns the total number of notes played in this stream
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_GetNoteCount (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_I32 *pNoteCount)
+{
+ if (!EAS_StreamReady(pEASData, pStream))
+ return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
+ return EAS_IntGetStrmParam(pEASData, pStream, PARSER_DATA_NOTE_COUNT, pNoteCount);
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_CloseFile()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Closes an audio file or stream. Playback should have either paused or
+ * completed (EAS_State returns EAS_PAUSED or EAS_STOPPED).
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - file or stream handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_CloseFile (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream)
+{
+ S_FILE_PARSER_INTERFACE *pParserModule;
+ EAS_RESULT result;
+
+ /* call the close function */
+ pParserModule = (S_FILE_PARSER_INTERFACE*) pStream->pParserModule;
+ if (pParserModule == NULL)
+ return EAS_ERROR_FEATURE_NOT_AVAILABLE;
+
+ result = (*pParserModule->pfClose)(pEASData, pStream->handle);
+
+ /* clear the handle and parser interface pointer */
+ pStream->handle = NULL;
+ pStream->pParserModule = NULL;
+ return result;
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_OpenMIDIStream()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Opens a raw MIDI stream allowing the host to route MIDI cable data directly to the synthesizer
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * pHandle - pointer to variable to hold file or stream handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_OpenMIDIStream (EAS_DATA_HANDLE pEASData, EAS_HANDLE *ppStream, EAS_HANDLE streamHandle)
+{
+ EAS_RESULT result;
+ S_INTERACTIVE_MIDI *pMIDIStream;
+ EAS_INT streamNum;
+
+ /* initialize some pointers */
+ *ppStream = NULL;
+
+ /* allocate a stream */
+ if ((streamNum = EAS_AllocateStream(pEASData)) < 0)
+ return EAS_ERROR_MAX_STREAMS_OPEN;
+
+ /* check Configuration Module for S_EAS_DATA allocation */
+ if (pEASData->staticMemoryModel)
+ pMIDIStream = EAS_CMEnumData(EAS_CM_MIDI_STREAM_DATA);
+ else
+ pMIDIStream = EAS_HWMalloc(pEASData->hwInstData, sizeof(S_INTERACTIVE_MIDI));
+
+ /* allocate dynamic memory */
+ if (!pMIDIStream)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_FATAL, "Failed to allocate MIDI stream data\n"); */ }
+ return EAS_ERROR_MALLOC_FAILED;
+ }
+
+ /* zero the memory to insure complete initialization */
+ EAS_HWMemSet(pMIDIStream, 0, sizeof(S_INTERACTIVE_MIDI));
+ EAS_InitStream(&pEASData->streams[streamNum], NULL, pMIDIStream);
+
+ /* instantiate a new synthesizer */
+ if (streamHandle == NULL)
+ {
+ result = VMInitMIDI(pEASData, &pMIDIStream->pSynth);
+ }
+
+ /* use an existing synthesizer */
+ else
+ {
+ EAS_I32 value;
+ result = EAS_GetStreamParameter(pEASData, streamHandle, PARSER_DATA_SYNTH_HANDLE, &value);
+ pMIDIStream->pSynth = (S_SYNTH*) value;
+ VMIncRefCount(pMIDIStream->pSynth);
+ }
+ if (result != EAS_SUCCESS)
+ {
+ EAS_CloseMIDIStream(pEASData, &pEASData->streams[streamNum]);
+ return result;
+ }
+
+ /* initialize the MIDI stream data */
+ EAS_InitMIDIStream(&pMIDIStream->stream);
+
+ *ppStream = (EAS_HANDLE) &pEASData->streams[streamNum];
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_WriteMIDIStream()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Send data to the MIDI stream device
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - stream handle
+ * pBuffer - pointer to buffer
+ * count - number of bytes to write
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_WriteMIDIStream (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_U8 *pBuffer, EAS_I32 count)
+{
+ S_INTERACTIVE_MIDI *pMIDIStream;
+ EAS_RESULT result;
+
+ pMIDIStream = (S_INTERACTIVE_MIDI*) pStream->handle;
+
+ /* send the entire buffer */
+ while (count--)
+ {
+ if ((result = EAS_ParseMIDIStream(pEASData, pMIDIStream->pSynth, &pMIDIStream->stream, *pBuffer++, eParserModePlay)) != EAS_SUCCESS)
+ return result;
+ }
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_CloseMIDIStream()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Closes a raw MIDI stream
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - stream handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_CloseMIDIStream (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream)
+{
+ S_INTERACTIVE_MIDI *pMIDIStream;
+
+ pMIDIStream = (S_INTERACTIVE_MIDI*) pStream->handle;
+
+ /* close synth */
+ if (pMIDIStream->pSynth != NULL)
+ {
+ VMMIDIShutdown(pEASData, pMIDIStream->pSynth);
+ pMIDIStream->pSynth = NULL;
+ }
+
+ /* release allocated memory */
+ if (!pEASData->staticMemoryModel)
+ EAS_HWFree(((S_EAS_DATA*) pEASData)->hwInstData, pMIDIStream);
+
+ pStream->handle = NULL;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_State()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Returns the state of an audio file or stream.
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - file or stream handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_State (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_STATE *pState)
+{
+ S_FILE_PARSER_INTERFACE *pParserModule;
+ EAS_RESULT result;
+
+ /* call the parser to return state */
+ pParserModule = (S_FILE_PARSER_INTERFACE*) pStream->pParserModule;
+ if (pParserModule == NULL)
+ return EAS_ERROR_FEATURE_NOT_AVAILABLE;
+
+ if ((result = (*pParserModule->pfState)(pEASData, pStream->handle, pState)) != EAS_SUCCESS)
+ return result;
+
+ /* if repeat count is set for this parser, mask the stopped state from the application */
+ if (pStream->repeatCount && (*pState == EAS_STATE_STOPPED))
+ *pState = EAS_STATE_PLAY;
+
+ /* if we're not ready or playing, we don't need to hide state from host */
+ if (*pState > EAS_STATE_PLAY)
+ return EAS_SUCCESS;
+
+ /* if stream is about to be paused, report it as paused */
+ if (pStream->streamFlags & STREAM_FLAGS_PAUSE)
+ {
+ if (pStream->streamFlags & STREAM_FLAGS_LOCATE)
+ *pState = EAS_STATE_PAUSED;
+ else
+ *pState = EAS_STATE_PAUSING;
+ }
+
+ /* if stream is about to resume, report it as playing */
+ if (pStream->streamFlags & STREAM_FLAGS_RESUME)
+ *pState = EAS_STATE_PLAY;
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_SetPolyphony()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Set the polyphony of the stream. A value of 0 allows the stream
+ * to use all voices (set by EAS_SetSynthPolyphony).
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * streamHandle - handle returned by EAS_OpenFile
+ * polyphonyCount - the desired polyphony count
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_SetPolyphony (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_I32 polyphonyCount)
+{
+ if (!EAS_StreamReady(pEASData, pStream))
+ return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
+ return EAS_IntSetStrmParam(pEASData, pStream, PARSER_DATA_POLYPHONY, polyphonyCount);
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_GetPolyphony()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Returns the current polyphony setting of the stream
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * streamHandle - handle returned by EAS_OpenFile
+ * pPolyphonyCount - pointer to variable to receive polyphony count
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_GetPolyphony (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_I32 *pPolyphonyCount)
+{
+ if (!EAS_StreamReady(pEASData, pStream))
+ return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
+ return EAS_IntGetStrmParam(pEASData, pStream, PARSER_DATA_POLYPHONY, pPolyphonyCount);
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_SetSynthPolyphony()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Set the polyphony of the synth . Value must be >= 1 and <= the
+ * maximum number of voices. This function will pin the polyphony
+ * at those limits
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * synthNum - synthesizer number (0 = onboard, 1 = DSP)
+ * polyphonyCount - the desired polyphony count
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_SetSynthPolyphony (EAS_DATA_HANDLE pEASData, EAS_I32 synthNum, EAS_I32 polyphonyCount)
+{
+ return VMSetSynthPolyphony(pEASData->pVoiceMgr, synthNum, polyphonyCount);
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_GetSynthPolyphony()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Returns the current polyphony setting of the synth
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * synthNum - synthesizer number (0 = onboard, 1 = DSP)
+ * pPolyphonyCount - pointer to variable to receive polyphony count
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_GetSynthPolyphony (EAS_DATA_HANDLE pEASData, EAS_I32 synthNum, EAS_I32 *pPolyphonyCount)
+{
+ return VMGetSynthPolyphony(pEASData->pVoiceMgr, synthNum, pPolyphonyCount);
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_SetPriority()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Set the priority of the stream. Determines which stream's voices
+ * are stolen when there are insufficient voices for all notes.
+ * Value must be in the range of 1-15, lower values are higher
+ * priority.
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * streamHandle - handle returned by EAS_OpenFile
+ * polyphonyCount - the desired polyphony count
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_SetPriority (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_I32 priority)
+{
+ if (!EAS_StreamReady(pEASData, pStream))
+ return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
+ return EAS_IntSetStrmParam(pEASData, pStream, PARSER_DATA_PRIORITY, priority);
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_GetPriority()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Returns the current priority setting of the stream
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * streamHandle - handle returned by EAS_OpenFile
+ * pPriority - pointer to variable to receive priority
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_GetPriority (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_I32 *pPriority)
+{
+ if (!EAS_StreamReady(pEASData, pStream))
+ return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
+ return EAS_IntGetStrmParam(pEASData, pStream, PARSER_DATA_PRIORITY, pPriority);
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_SetVolume()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Set the master gain for the mix engine in 1dB increments
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * volume - the desired master gain (100 is max)
+ * handle - file or stream handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ * overrides any previously set master volume from sysex
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_SetVolume (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_I32 volume)
+{
+ EAS_I16 gain;
+
+ /* check range */
+ if ((volume < 0) || (volume > EAS_MAX_VOLUME))
+ return EAS_ERROR_PARAMETER_RANGE;
+
+ /* stream volume */
+ if (pStream != NULL)
+ {
+ EAS_I32 gainOffset;
+ EAS_RESULT result;
+
+ if (!EAS_StreamReady(pEASData, pStream))
+ return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
+
+ /* get gain offset */
+ pStream->volume = (EAS_U8) volume;
+ result = EAS_GetStreamParameter(pEASData, pStream, PARSER_DATA_GAIN_OFFSET, &gainOffset);
+ if (result == EAS_SUCCESS)
+ volume += gainOffset;
+
+ /* set stream volume */
+ gain = EAS_VolumeToGain(volume - STREAM_VOLUME_HEADROOM);
+
+ /* convert to linear scalar */
+ return EAS_IntSetStrmParam(pEASData, pStream, PARSER_DATA_VOLUME, gain);
+ }
+
+ /* master volume */
+ pEASData->masterVolume = (EAS_U8) volume;
+#if (NUM_OUTPUT_CHANNELS == 1)
+ /* leave 3dB headroom for mono output */
+ volume -= 3;
+#endif
+
+ gain = EAS_VolumeToGain(volume - STREAM_VOLUME_HEADROOM);
+ pEASData->masterGain = gain;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_GetVolume()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Returns the master volume for the synthesizer. The default volume setting is
+ * 50. The volume range is 0 to 100;
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * volume - the desired master volume
+ * handle - file or stream handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ * overrides any previously set master volume from sysex
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_I32 EAS_GetVolume (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream)
+{
+ if (pStream == NULL)
+ return pEASData->masterVolume;
+
+ if (!EAS_StreamReady(pEASData, pStream))
+ return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
+ return pStream->volume;
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_SetMaxLoad()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Sets the maximum workload the parsers will do in a single call to
+ * EAS_Render. The units are currently arbitrary, but should correlate
+ * well to the actual CPU cycles consumed. The primary effect is to
+ * reduce the occasional peaks in CPU cycles consumed when parsing
+ * dense parts of a MIDI score.
+ *
+ * Inputs:
+ * pEASData - handle to data for this instance
+ * maxLoad - the desired maximum workload
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_SetMaxLoad (EAS_DATA_HANDLE pEASData, EAS_I32 maxLoad)
+{
+ VMSetWorkload(pEASData->pVoiceMgr, maxLoad);
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_SetMaxPCMStreams()
+ *----------------------------------------------------------------------------
+ * Sets the maximum number of PCM streams allowed in parsers that
+ * use PCM streaming.
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * streamHandle - handle returned by EAS_OpenFile
+ * maxNumStreams - maximum number of PCM streams
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_SetMaxPCMStreams (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_I32 maxNumStreams)
+{
+ if (!EAS_StreamReady(pEASData, pStream))
+ return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
+ return EAS_IntSetStrmParam(pEASData, pStream, PARSER_DATA_MAX_PCM_STREAMS, maxNumStreams);
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_Locate()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Locate into the file associated with the handle.
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - file handle
+ * milliseconds - playback offset from start of file in milliseconds
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ * the actual offset will be quantized to the closest update period, typically
+ * a resolution of 5.9ms. Notes that are started prior to this time will not
+ * sound. Any notes currently playing will be shut off.
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_Locate (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_I32 milliseconds, EAS_BOOL offset)
+{
+ S_FILE_PARSER_INTERFACE *pParserModule;
+ EAS_RESULT result;
+ EAS_U32 requestedTime;
+ EAS_STATE state;
+
+ /* get pointer to parser function table */
+ pParserModule = (S_FILE_PARSER_INTERFACE*) pStream->pParserModule;
+ if (pParserModule == NULL)
+ return EAS_ERROR_FEATURE_NOT_AVAILABLE;
+
+ if ((result = (*pParserModule->pfState)(pEASData, pStream->handle, &state)) != EAS_SUCCESS)
+ return result;
+ if (state >= EAS_STATE_OPEN)
+ return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
+
+ /* handle offset and limit to start of file */
+ /*lint -e{704} use shift for performance*/
+ if (offset)
+ milliseconds += (EAS_I32) pStream->time >> 8;
+ if (milliseconds < 0)
+ milliseconds = 0;
+
+ /* check to see if the request is different from the current time */
+ requestedTime = (EAS_U32) milliseconds;
+ if (requestedTime == (pStream->time >> 8))
+ return EAS_SUCCESS;
+
+ /* set the locate flag */
+ pStream->streamFlags |= STREAM_FLAGS_LOCATE;
+
+ /* use the parser locate function, if available */
+ if (pParserModule->pfLocate != NULL)
+ {
+ EAS_BOOL parserLocate = EAS_FALSE;
+ result = pParserModule->pfLocate(pEASData, pStream->handle, (EAS_I32) requestedTime, &parserLocate);
+ if (!parserLocate)
+ {
+ if (result == EAS_SUCCESS)
+ pStream->time = requestedTime << 8;
+ return result;
+ }
+ }
+
+ /* if we were paused and not going to resume, set pause request flag */
+ if (((state == EAS_STATE_PAUSING) || (state == EAS_STATE_PAUSED)) && ((pStream->streamFlags & STREAM_FLAGS_RESUME) == 0))
+ pStream->streamFlags |= STREAM_FLAGS_PAUSE;
+
+ /* reset the synth and parser */
+ if ((result = (*pParserModule->pfReset)(pEASData, pStream->handle)) != EAS_SUCCESS)
+ return result;
+ pStream->time = 0;
+
+ /* locating forward, clear parsed flag and parse data until we get to the requested location */
+ if ((result = EAS_ParseEvents(pEASData, pStream, requestedTime << 8, eParserModeLocate)) != EAS_SUCCESS)
+ return result;
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_GetLocation()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Returns the current playback offset
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - file handle
+ *
+ * Outputs:
+ * The offset in milliseconds from the start of the current sequence, quantized
+ * to the nearest update period. Actual resolution is typically 5.9 ms.
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pEASData) reserved for future use */
+EAS_PUBLIC EAS_RESULT EAS_GetLocation (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_I32 *pTime)
+{
+ if (!EAS_StreamReady(pEASData, pStream))
+ return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
+
+ *pTime = pStream->time >> 8;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_GetRenderTime()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Returns the current playback offset
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ * Gets the render time clock in msecs.
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_GetRenderTime (EAS_DATA_HANDLE pEASData, EAS_I32 *pTime)
+{
+ *pTime = pEASData->renderTime >> 8;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_Pause()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Pauses the playback of the data associated with this handle. The audio
+ * is gracefully ramped down to prevent clicks and pops. It may take several
+ * buffers of audio before the audio is muted.
+ *
+ * Inputs:
+ * psEASData - pointer to overall EAS data structure
+ * handle - file or stream handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_Pause (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream)
+{
+ S_FILE_PARSER_INTERFACE *pParserModule;
+ EAS_STATE state;
+ EAS_RESULT result;
+
+ pParserModule = (S_FILE_PARSER_INTERFACE*) pStream->pParserModule;
+ if (pParserModule == NULL)
+ return EAS_ERROR_FEATURE_NOT_AVAILABLE;
+
+ /* check for valid state */
+ result = pParserModule->pfState(pEASData, pStream->handle, &state);
+ if (result == EAS_SUCCESS)
+ {
+ if ((state != EAS_STATE_PLAY) && (state != EAS_STATE_READY) && ((pStream->streamFlags & STREAM_FLAGS_RESUME) == 0))
+ return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
+
+ /* make sure parser implements pause */
+ if (pParserModule->pfPause == NULL)
+ result = EAS_ERROR_NOT_IMPLEMENTED;
+
+ /* clear resume flag */
+ pStream->streamFlags &= ~STREAM_FLAGS_RESUME;
+
+ /* set pause flag */
+ pStream->streamFlags |= STREAM_FLAGS_PAUSE;
+
+#if 0
+ /* pause the stream */
+ if (pParserModule->pfPause)
+ result = pParserModule->pfPause(pEASData, pStream->handle);
+ else
+ result = EAS_ERROR_NOT_IMPLEMENTED;
+#endif
+ }
+
+ return result;
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_Resume()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Resumes the playback of the data associated with this handle. The audio
+ * is gracefully ramped up to prevent clicks and pops.
+ *
+ * Inputs:
+ * psEASData - pointer to overall EAS data structure
+ * handle - file or stream handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_Resume (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream)
+{
+ S_FILE_PARSER_INTERFACE *pParserModule;
+ EAS_STATE state;
+ EAS_RESULT result;
+
+ pParserModule = (S_FILE_PARSER_INTERFACE*) pStream->pParserModule;
+ if (pParserModule == NULL)
+ return EAS_ERROR_FEATURE_NOT_AVAILABLE;
+
+ /* check for valid state */
+ result = pParserModule->pfState(pEASData, pStream->handle, &state);
+ if (result == EAS_SUCCESS)
+ {
+ if ((state != EAS_STATE_PAUSED) && (state != EAS_STATE_PAUSING) && ((pStream->streamFlags & STREAM_FLAGS_PAUSE) == 0))
+ return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
+
+ /* make sure parser implements this function */
+ if (pParserModule->pfResume == NULL)
+ result = EAS_ERROR_NOT_IMPLEMENTED;
+
+ /* clear pause flag */
+ pStream->streamFlags &= ~STREAM_FLAGS_PAUSE;
+
+ /* set resume flag */
+ pStream->streamFlags |= STREAM_FLAGS_RESUME;
+
+#if 0
+ /* resume the stream */
+ if (pParserModule->pfResume)
+ result = pParserModule->pfResume(pEASData, pStream->handle);
+ else
+ result = EAS_ERROR_NOT_IMPLEMENTED;
+#endif
+ }
+
+ return result;
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_GetParameter()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Set the parameter of a module. See E_MODULES for a list of modules
+ * and the header files of the modules for a list of parameters.
+ *
+ * Inputs:
+ * psEASData - pointer to overall EAS data structure
+ * handle - file or stream handle
+ * module - enumerated module number
+ * param - enumerated parameter number
+ * pValue - pointer to variable to receive parameter value
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_GetParameter (EAS_DATA_HANDLE pEASData, EAS_I32 module, EAS_I32 param, EAS_I32 *pValue)
+{
+
+ if (module >= NUM_EFFECTS_MODULES)
+ return EAS_ERROR_INVALID_MODULE;
+
+ if (pEASData->effectsModules[module].effectData == NULL)
+ return EAS_ERROR_INVALID_MODULE;
+
+ return (*pEASData->effectsModules[module].effect->pFGetParam)
+ (pEASData->effectsModules[module].effectData, param, pValue);
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_SetParameter()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Set the parameter of a module. See E_MODULES for a list of modules
+ * and the header files of the modules for a list of parameters.
+ *
+ * Inputs:
+ * psEASData - pointer to overall EAS data structure
+ * handle - file or stream handle
+ * module - enumerated module number
+ * param - enumerated parameter number
+ * value - new parameter value
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_SetParameter (EAS_DATA_HANDLE pEASData, EAS_I32 module, EAS_I32 param, EAS_I32 value)
+{
+
+ if (module >= NUM_EFFECTS_MODULES)
+ return EAS_ERROR_INVALID_MODULE;
+
+ if (pEASData->effectsModules[module].effectData == NULL)
+ return EAS_ERROR_INVALID_MODULE;
+
+ return (*pEASData->effectsModules[module].effect->pFSetParam)
+ (pEASData->effectsModules[module].effectData, param, value);
+}
+
+#ifdef _METRICS_ENABLED
+/*----------------------------------------------------------------------------
+ * EAS_MetricsReport()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Displays the current metrics through the metrics interface.
+ *
+ * Inputs:
+ * p - instance data handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_MetricsReport (EAS_DATA_HANDLE pEASData)
+{
+ if (!pEASData->pMetricsModule)
+ return EAS_ERROR_INVALID_MODULE;
+
+ return (*pEASData->pMetricsModule->pfReport)(pEASData->pMetricsData);
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_MetricsReset()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Resets the metrics.
+ *
+ * Inputs:
+ * p - instance data handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_MetricsReset (EAS_DATA_HANDLE pEASData)
+{
+
+ if (!pEASData->pMetricsModule)
+ return EAS_ERROR_INVALID_MODULE;
+
+ return (*pEASData->pMetricsModule->pfReset)(pEASData->pMetricsData);
+}
+#endif
+
+/*----------------------------------------------------------------------------
+ * EAS_SetSoundLibrary()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Sets the location of the sound library.
+ *
+ * Inputs:
+ * pEASData - instance data handle
+ * pSoundLib - pointer to sound library
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_SetSoundLibrary (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_SNDLIB_HANDLE pSndLib)
+{
+ if (pStream)
+ {
+ if (!EAS_StreamReady(pEASData, pStream))
+ return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
+ return EAS_IntSetStrmParam(pEASData, pStream, PARSER_DATA_EAS_LIBRARY, (EAS_I32) pSndLib);
+ }
+
+ return VMSetGlobalEASLib(pEASData->pVoiceMgr, pSndLib);
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_SetHeaderSearchFlag()
+ *----------------------------------------------------------------------------
+ * By default, when EAS_OpenFile is called, the parsers check the
+ * first few bytes of the file looking for a specific header. Some
+ * mobile devices may add a header to the start of a file, which
+ * will prevent the parser from recognizing the file. If the
+ * searchFlag is set to EAS_TRUE, the parser will search the entire
+ * file looking for the header. This may enable EAS to recognize
+ * some files that it would ordinarily reject. The negative is that
+ * it make take slightly longer to process the EAS_OpenFile request.
+ *
+ * Inputs:
+ * pEASData - instance data handle
+ * searchFlag - search flag (EAS_TRUE or EAS_FALSE)
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_SetHeaderSearchFlag (EAS_DATA_HANDLE pEASData, EAS_BOOL searchFlag)
+{
+ pEASData->searchHeaderFlag = (EAS_BOOL8) searchFlag;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_SetPlayMode()
+ *----------------------------------------------------------------------------
+ * Some file formats support special play modes, such as iMode partial
+ * play mode. This call can be used to change the play mode. The
+ * default play mode (usually straight playback) is always zero.
+ *
+ * Inputs:
+ * pEASData - instance data handle
+ * handle - file or stream handle
+ * playMode - play mode (see file parser for specifics)
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_SetPlayMode (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_I32 playMode)
+{
+ return EAS_IntSetStrmParam(pEASData, pStream, PARSER_DATA_PLAY_MODE, playMode);
+}
+
+#ifdef DLS_SYNTHESIZER
+/*----------------------------------------------------------------------------
+ * EAS_LoadDLSCollection()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Sets the location of the sound library.
+ *
+ * Inputs:
+ * pEASData - instance data handle
+ * pSoundLib - pointer to sound library
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_LoadDLSCollection (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_FILE_LOCATOR locator)
+{
+ EAS_FILE_HANDLE fileHandle;
+ EAS_RESULT result;
+ EAS_DLSLIB_HANDLE pDLS;
+
+ if (pStream != NULL)
+ {
+ if (!EAS_StreamReady(pEASData, pStream))
+ return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
+ }
+
+ /* open the file */
+ if ((result = EAS_HWOpenFile(pEASData->hwInstData, locator, &fileHandle, EAS_FILE_READ)) != EAS_SUCCESS)
+ return result;
+
+ /* parse the file */
+ result = DLSParser(pEASData->hwInstData, fileHandle, 0, &pDLS);
+ EAS_HWCloseFile(pEASData->hwInstData, fileHandle);
+
+ if (result == EAS_SUCCESS)
+ {
+
+ /* if a stream pStream is specified, point it to the DLS collection */
+ if (pStream)
+ result = EAS_IntSetStrmParam(pEASData, pStream, PARSER_DATA_DLS_COLLECTION, (EAS_I32) pDLS);
+
+ /* global DLS load */
+ else
+ result = VMSetGlobalDLSLib(pEASData, pDLS);
+ }
+
+ return result;
+}
+#endif
+
+#ifdef EXTERNAL_AUDIO
+/*----------------------------------------------------------------------------
+ * EAS_RegExtAudioCallback()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Registers callback functions for audio events.
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - file or stream handle
+ * cbProgChgFunc - pointer to host callback function for program change
+ * cbEventFunc - pointer to host callback functio for note events
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_RegExtAudioCallback (EAS_DATA_HANDLE pEASData,
+ EAS_HANDLE pStream,
+ EAS_VOID_PTR pInstData,
+ EAS_EXT_PRG_CHG_FUNC cbProgChgFunc,
+ EAS_EXT_EVENT_FUNC cbEventFunc)
+{
+ S_SYNTH *pSynth;
+
+ if (!EAS_StreamReady(pEASData, pStream))
+ return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
+
+ if (EAS_GetStreamParameter(pEASData, pStream, PARSER_DATA_SYNTH_HANDLE, (EAS_I32*) &pSynth) != EAS_SUCCESS)
+ return EAS_ERROR_INVALID_PARAMETER;
+
+ if (pSynth == NULL)
+ return EAS_ERROR_INVALID_PARAMETER;
+
+ VMRegExtAudioCallback(pSynth, pInstData, cbProgChgFunc, cbEventFunc);
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_GetMIDIControllers()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Returns the current state of MIDI controllers on the requested channel.
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - file or stream handle
+ * pControl - pointer to structure to receive data
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_GetMIDIControllers (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_U8 channel, S_MIDI_CONTROLLERS *pControl)
+{
+ S_SYNTH *pSynth;
+
+ if (!EAS_StreamReady(pEASData, pStream))
+ return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
+
+ if (EAS_GetStreamParameter(pEASData, pStream, PARSER_DATA_SYNTH_HANDLE, (EAS_I32*) &pSynth) != EAS_SUCCESS)
+ return EAS_ERROR_INVALID_PARAMETER;
+
+ if (pSynth == NULL)
+ return EAS_ERROR_INVALID_PARAMETER;
+
+ VMGetMIDIControllers(pSynth, channel, pControl);
+ return EAS_SUCCESS;
+}
+#endif
+
+#ifdef _SPLIT_ARCHITECTURE
+/*----------------------------------------------------------------------------
+ * EAS_SetFrameBuffer()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Sets the frame buffer pointer passed to the IPC communications functions
+ *
+ * Inputs:
+ * pEASData - instance data handle
+ * locator - file locator
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ * May overlay instruments in the GM sound set
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_SetFrameBuffer (EAS_DATA_HANDLE pEASData, EAS_FRAME_BUFFER_HANDLE pFrameBuffer)
+{
+ if (pEASData->pVoiceMgr)
+ pEASData->pVoiceMgr->pFrameBuffer = pFrameBuffer;
+ return EAS_SUCCESS;
+}
+#endif
+
+/*----------------------------------------------------------------------------
+ * EAS_SearchFile
+ *----------------------------------------------------------------------------
+ * Search file for specific sequence starting at current file
+ * position. Returns offset to start of sequence.
+ *
+ * Inputs:
+ * pEASData - pointer to EAS persistent data object
+ * fileHandle - file handle
+ * searchString - pointer to search sequence
+ * len - length of search sequence
+ * pOffset - pointer to variable to store offset to sequence
+ *
+ * Returns EAS_EOF if end-of-file is reached
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_SearchFile (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle, const EAS_U8 *searchString, EAS_I32 len, EAS_I32 *pOffset)
+{
+ EAS_RESULT result;
+ EAS_INT index;
+ EAS_U8 c;
+
+ *pOffset = -1;
+ index = 0;
+ for (;;)
+ {
+ result = EAS_HWGetByte(pEASData->hwInstData, fileHandle, &c);
+ if (result != EAS_SUCCESS)
+ return result;
+ if (c == searchString[index])
+ {
+ index++;
+ if (index == 4)
+ {
+ result = EAS_HWFilePos(pEASData->hwInstData, fileHandle, pOffset);
+ if (result != EAS_SUCCESS)
+ return result;
+ *pOffset -= len;
+ break;
+ }
+ }
+ else
+ index = 0;
+ }
+ return EAS_SUCCESS;
+}
+
+
diff --git a/arm-fm-22k/lib_src/eas_reverb.c b/arm-fm-22k/lib_src/eas_reverb.c
index 6d99862..cd5befe 100644
--- a/arm-fm-22k/lib_src/eas_reverb.c
+++ b/arm-fm-22k/lib_src/eas_reverb.c
@@ -1,13 +1,13 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_reverb.c
- *
- * Contents and purpose:
- * Contains the implementation of the Reverb effect.
- *
- *
- * Copyright Sonic Network Inc. 2006
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_reverb.c
+ *
+ * Contents and purpose:
+ * Contains the implementation of the Reverb effect.
+ *
+ *
+ * Copyright Sonic Network Inc. 2006
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,1135 +20,1135 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 510 $
- * $Date: 2006-12-19 01:47:33 -0800 (Tue, 19 Dec 2006) $
- *----------------------------------------------------------------------------
-*/
-
-/*------------------------------------
- * includes
- *------------------------------------
-*/
-
-#include "eas_data.h"
-#include "eas_effects.h"
-#include "eas_math.h"
-#include "eas_reverbdata.h"
-#include "eas_reverb.h"
-#include "eas_config.h"
-#include "eas_host.h"
-#include "eas_report.h"
-
-/* prototypes for effects interface */
-static EAS_RESULT ReverbInit (EAS_DATA_HANDLE pEASData, EAS_VOID_PTR *pInstData);
-static void ReverbProcess (EAS_VOID_PTR pInstData, EAS_PCM *pSrc, EAS_PCM *pDst, EAS_I32 numSamples);
-static EAS_RESULT ReverbShutdown (EAS_DATA_HANDLE pEASData, EAS_VOID_PTR pInstData);
-static EAS_RESULT ReverbGetParam (EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue);
-static EAS_RESULT ReverbSetParam (EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value);
-
-/* common effects interface for configuration module */
-const S_EFFECTS_INTERFACE EAS_Reverb =
-{
- ReverbInit,
- ReverbProcess,
- ReverbShutdown,
- ReverbGetParam,
- ReverbSetParam
-};
-
-
-
-/*----------------------------------------------------------------------------
- * InitializeReverb()
- *----------------------------------------------------------------------------
- * Purpose:
- *
- * Inputs:
- *
- * Outputs:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT ReverbInit(EAS_DATA_HANDLE pEASData, EAS_VOID_PTR *pInstData)
-{
- EAS_I32 i;
- EAS_U16 nOffset;
- EAS_INT temp;
-
- S_REVERB_OBJECT *pReverbData;
- S_REVERB_PRESET *pPreset;
-
- /* check Configuration Module for data allocation */
- if (pEASData->staticMemoryModel)
- pReverbData = EAS_CMEnumFXData(EAS_MODULE_REVERB);
-
- /* allocate dynamic memory */
- else
- pReverbData = EAS_HWMalloc(pEASData->hwInstData, sizeof(S_REVERB_OBJECT));
-
- if (pReverbData == NULL)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_FATAL, "Failed to allocate Reverb memory\n"); */ }
- return EAS_ERROR_MALLOC_FAILED;
- }
-
- /* clear the structure */
- EAS_HWMemSet(pReverbData, 0, sizeof(S_REVERB_OBJECT));
-
- ReverbReadInPresets(pReverbData);
-
- pReverbData->m_nMinSamplesToAdd = REVERB_UPDATE_PERIOD_IN_SAMPLES;
-
- pReverbData->m_nRevOutFbkR = 0;
- pReverbData->m_nRevOutFbkL = 0;
-
- pReverbData->m_sAp0.m_zApIn = AP0_IN;
- pReverbData->m_sAp0.m_zApOut = AP0_IN + DEFAULT_AP0_LENGTH;
- pReverbData->m_sAp0.m_nApGain = DEFAULT_AP0_GAIN;
-
- pReverbData->m_zD0In = DELAY0_IN;
-
- pReverbData->m_sAp1.m_zApIn = AP1_IN;
- pReverbData->m_sAp1.m_zApOut = AP1_IN + DEFAULT_AP1_LENGTH;
- pReverbData->m_sAp1.m_nApGain = DEFAULT_AP1_GAIN;
-
- pReverbData->m_zD1In = DELAY1_IN;
-
- pReverbData->m_zLpf0 = 0;
- pReverbData->m_zLpf1 = 0;
- pReverbData->m_nLpfFwd = 8837;
- pReverbData->m_nLpfFbk = 6494;
-
- pReverbData->m_nSin = 0;
- pReverbData->m_nCos = 0;
- pReverbData->m_nSinIncrement = 0;
- pReverbData->m_nCosIncrement = 0;
-
- // set xfade parameters
- pReverbData->m_nXfadeInterval = (EAS_U16)REVERB_XFADE_PERIOD_IN_SAMPLES;
- pReverbData->m_nXfadeCounter = pReverbData->m_nXfadeInterval + 1; // force update on first iteration
- pReverbData->m_nPhase = -32768;
- pReverbData->m_nPhaseIncrement = REVERB_XFADE_PHASE_INCREMENT;
-
- pReverbData->m_nNoise = (EAS_I16)0xABCD;
-
- pReverbData->m_nMaxExcursion = 0x007F;
-
- // set delay tap lengths
- nOffset = ReverbCalculateNoise( pReverbData->m_nMaxExcursion,
- &pReverbData->m_nNoise );
-
- pReverbData->m_zD1Cross =
- DELAY1_OUT - pReverbData->m_nMaxExcursion + nOffset;
-
- nOffset = ReverbCalculateNoise( pReverbData->m_nMaxExcursion,
- &pReverbData->m_nNoise );
-
- pReverbData->m_zD0Cross =
- DELAY1_OUT - pReverbData->m_nMaxExcursion - nOffset;
-
- nOffset = ReverbCalculateNoise( pReverbData->m_nMaxExcursion,
- &pReverbData->m_nNoise );
-
- pReverbData->m_zD0Self =
- DELAY0_OUT - pReverbData->m_nMaxExcursion - nOffset;
-
- nOffset = ReverbCalculateNoise( pReverbData->m_nMaxExcursion,
- &pReverbData->m_nNoise );
-
- pReverbData->m_zD1Self =
- DELAY1_OUT - pReverbData->m_nMaxExcursion + nOffset;
-
- // for debugging purposes, allow noise generator
- pReverbData->m_bUseNoise = EAS_FALSE;
-
- // for debugging purposes, allow bypass
- pReverbData->m_bBypass = EAS_TRUE; //EAS_FALSE;
-
- pReverbData->m_nNextRoom = 1;
-
- pReverbData->m_nCurrentRoom = pReverbData->m_nNextRoom + 1; // force update on first iteration
-
- pReverbData->m_nWet = REVERB_DEFAULT_WET;
-
- pReverbData->m_nDry = REVERB_DEFAULT_DRY;
-
- // set base index into circular buffer
- pReverbData->m_nBaseIndex = 0;
-
- // set the early reflections, L
- pReverbData->m_sEarlyL.m_nLpfFbk = 4915;
- pReverbData->m_sEarlyL.m_nLpfFwd = 27852;
- pReverbData->m_sEarlyL.m_zLpf = 0;
-
- for (i=0; i < REVERB_MAX_NUM_REFLECTIONS; i++)
- {
- pReverbData->m_sEarlyL.m_nGain[i] = 0;
- pReverbData->m_sEarlyL.m_zDelay[i] = 0;
- }
-
- // set the early reflections, R
- pReverbData->m_sEarlyR.m_nLpfFbk = 4915;
- pReverbData->m_sEarlyR.m_nLpfFwd = 27852;
- pReverbData->m_sEarlyR.m_zLpf = 0;
-
- for (i=0; i < REVERB_MAX_NUM_REFLECTIONS; i++)
- {
- pReverbData->m_sEarlyR.m_nGain[i] = 0;
- pReverbData->m_sEarlyR.m_zDelay[i] = 0;
- }
-
- // clear the reverb delay line
- for (i=0; i < REVERB_BUFFER_SIZE_IN_SAMPLES; i++)
- {
- pReverbData->m_nDelayLine[i] = 0;
- }
-
- ////////////////////////////////
- ///code from the EAS DEMO Reverb
- //now copy from the new preset into the reverb
- pPreset = &pReverbData->m_sPreset.m_sPreset[pReverbData->m_nNextRoom];
-
- pReverbData->m_nLpfFbk = pPreset->m_nLpfFbk;
- pReverbData->m_nLpfFwd = pPreset->m_nLpfFwd;
-
- pReverbData->m_nEarly = pPreset->m_nEarly;
- pReverbData->m_nWet = pPreset->m_nWet;
- pReverbData->m_nDry = pPreset->m_nDry;
-
- pReverbData->m_nMaxExcursion = pPreset->m_nMaxExcursion;
- //stored as time based, convert to sample based
- temp = pPreset->m_nXfadeInterval;
- /*lint -e{702} shift for performance */
- temp = (temp * _OUTPUT_SAMPLE_RATE) >> 16;
- pReverbData->m_nXfadeInterval = (EAS_U16) temp;
- //gsReverbObject.m_nXfadeInterval = pPreset->m_nXfadeInterval;
-
- pReverbData->m_sAp0.m_nApGain = pPreset->m_nAp0_ApGain;
- //stored as time based, convert to absolute sample value
- temp = pPreset->m_nAp0_ApOut;
- /*lint -e{702} shift for performance */
- temp = (temp * _OUTPUT_SAMPLE_RATE) >> 16;
- pReverbData->m_sAp0.m_zApOut = (EAS_U16) (pReverbData->m_sAp0.m_zApIn + temp);
- //gsReverbObject.m_sAp0.m_zApOut = pPreset->m_nAp0_ApOut;
-
- pReverbData->m_sAp1.m_nApGain = pPreset->m_nAp1_ApGain;
- //stored as time based, convert to absolute sample value
- temp = pPreset->m_nAp1_ApOut;
- /*lint -e{702} shift for performance */
- temp = (temp * _OUTPUT_SAMPLE_RATE) >> 16;
- pReverbData->m_sAp1.m_zApOut = (EAS_U16) (pReverbData->m_sAp1.m_zApIn + temp);
- //gsReverbObject.m_sAp1.m_zApOut = pPreset->m_nAp1_ApOut;
- ///code from the EAS DEMO Reverb
- ////////////////////////////////
-
- *pInstData = pReverbData;
-
- return EAS_SUCCESS;
-
-} /* end InitializeReverb */
-
-
-
-/*----------------------------------------------------------------------------
- * ReverbProcess()
- *----------------------------------------------------------------------------
- * Purpose:
- * Reverberate the requested number of samples (block based processing)
- *
- * Inputs:
- * pInputBuffer - src buffer
- * pOutputBuffer - dst buffer
- * nNumSamplesToAdd - number of samples to write to buffer
- *
- * Outputs:
- * number of samples actually written to buffer
- *
- * Side Effects:
- * - samples are added to the presently free buffer
- *
- *----------------------------------------------------------------------------
-*/
-static void ReverbProcess(EAS_VOID_PTR pInstData, EAS_PCM *pSrc, EAS_PCM *pDst, EAS_I32 numSamples)
-{
- S_REVERB_OBJECT *pReverbData;
-
- pReverbData = (S_REVERB_OBJECT*) pInstData;
-
- //if bypassed or the preset forces the signal to be completely dry
- if (pReverbData->m_bBypass ||
- (pReverbData->m_nWet == 0 && pReverbData->m_nDry == 32767))
- {
- if (pSrc != pDst)
- EAS_HWMemCpy(pSrc, pDst, numSamples * NUM_OUTPUT_CHANNELS * (EAS_I32) sizeof(EAS_PCM));
- return;
- }
-
- if (pReverbData->m_nNextRoom != pReverbData->m_nCurrentRoom)
- {
- ReverbUpdateRoom(pReverbData);
- }
-
- ReverbUpdateXfade(pReverbData, numSamples);
-
- Reverb(pReverbData, numSamples, pDst, pSrc);
-
- /* check if update counter needs to be reset */
- if (pReverbData->m_nUpdateCounter >= REVERB_MODULO_UPDATE_PERIOD_IN_SAMPLES)
- {
- /* update interval has elapsed, so reset counter */
- pReverbData->m_nUpdateCounter = 0;
- } /* end if m_nUpdateCounter >= update interval */
-
- /* increment update counter */
- pReverbData->m_nUpdateCounter += (EAS_I16)numSamples;
-
-} /* end ComputeReverb */
-
-/*----------------------------------------------------------------------------
- * ReverbUpdateXfade
- *----------------------------------------------------------------------------
- * Purpose:
- * Update the xfade parameters as required
- *
- * Inputs:
- * nNumSamplesToAdd - number of samples to write to buffer
- *
- * Outputs:
- *
- *
- * Side Effects:
- * - xfade parameters will be changed
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT ReverbUpdateXfade(S_REVERB_OBJECT *pReverbData, EAS_INT nNumSamplesToAdd)
-{
- EAS_U16 nOffset;
- EAS_I16 tempCos;
- EAS_I16 tempSin;
-
- if (pReverbData->m_nXfadeCounter >= pReverbData->m_nXfadeInterval)
- {
- /* update interval has elapsed, so reset counter */
- pReverbData->m_nXfadeCounter = 0;
-
- // Pin the sin,cos values to min / max values to ensure that the
- // modulated taps' coefs are zero (thus no clicks)
- if (pReverbData->m_nPhaseIncrement > 0)
- {
- // if phase increment > 0, then sin -> 1, cos -> 0
- pReverbData->m_nSin = 32767;
- pReverbData->m_nCos = 0;
-
- // reset the phase to match the sin, cos values
- pReverbData->m_nPhase = 32767;
-
- // modulate the cross taps because their tap coefs are zero
- nOffset = ReverbCalculateNoise( pReverbData->m_nMaxExcursion, &pReverbData->m_nNoise );
-
- pReverbData->m_zD1Cross =
- DELAY1_OUT - pReverbData->m_nMaxExcursion + nOffset;
-
- nOffset = ReverbCalculateNoise( pReverbData->m_nMaxExcursion, &pReverbData->m_nNoise );
-
- pReverbData->m_zD0Cross =
- DELAY0_OUT - pReverbData->m_nMaxExcursion - nOffset;
- }
- else
- {
- // if phase increment < 0, then sin -> 0, cos -> 1
- pReverbData->m_nSin = 0;
- pReverbData->m_nCos = 32767;
-
- // reset the phase to match the sin, cos values
- pReverbData->m_nPhase = -32768;
-
- // modulate the self taps because their tap coefs are zero
- nOffset = ReverbCalculateNoise( pReverbData->m_nMaxExcursion, &pReverbData->m_nNoise );
-
- pReverbData->m_zD0Self =
- DELAY0_OUT - pReverbData->m_nMaxExcursion - nOffset;
-
- nOffset = ReverbCalculateNoise( pReverbData->m_nMaxExcursion, &pReverbData->m_nNoise );
-
- pReverbData->m_zD1Self =
- DELAY1_OUT - pReverbData->m_nMaxExcursion + nOffset;
-
- } // end if-else (pReverbData->m_nPhaseIncrement > 0)
-
- // Reverse the direction of the sin,cos so that the
- // tap whose coef was previously increasing now decreases
- // and vice versa
- pReverbData->m_nPhaseIncrement = -pReverbData->m_nPhaseIncrement;
-
- } // end if counter >= update interval
-
- //compute what phase will be next time
- pReverbData->m_nPhase += pReverbData->m_nPhaseIncrement;
-
- //calculate what the new sin and cos need to reach by the next update
- ReverbCalculateSinCos(pReverbData->m_nPhase, &tempSin, &tempCos);
-
- //calculate the per-sample increment required to get there by the next update
- /*lint -e{702} shift for performance */
- pReverbData->m_nSinIncrement =
- (tempSin - pReverbData->m_nSin) >> REVERB_UPDATE_PERIOD_IN_BITS;
-
- /*lint -e{702} shift for performance */
- pReverbData->m_nCosIncrement =
- (tempCos - pReverbData->m_nCos) >> REVERB_UPDATE_PERIOD_IN_BITS;
-
-
- /* increment update counter */
- pReverbData->m_nXfadeCounter += (EAS_U16) nNumSamplesToAdd;
-
- return EAS_SUCCESS;
-
-} /* end ReverbUpdateXfade */
-
-
-/*----------------------------------------------------------------------------
- * ReverbCalculateNoise
- *----------------------------------------------------------------------------
- * Purpose:
- * Calculate a noise sample and limit its value
- *
- * Inputs:
- * nMaxExcursion - noise value is limited to this value
- * pnNoise - return new noise sample in this (not limited)
- *
- * Outputs:
- * new limited noise value
- *
- * Side Effects:
- * - *pnNoise noise value is updated
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_U16 ReverbCalculateNoise(EAS_U16 nMaxExcursion, EAS_I16 *pnNoise)
-{
- // calculate new noise value
- *pnNoise = (EAS_I16) (*pnNoise * 5 + 1);
-
-#if 0 // 1xxx, test
- *pnNoise = 0;
-#endif // 1xxx, test
-
- // return the limited noise value
- return (nMaxExcursion & (*pnNoise));
-
-} /* end ReverbCalculateNoise */
-
-/*----------------------------------------------------------------------------
- * ReverbCalculateSinCos
- *----------------------------------------------------------------------------
- * Purpose:
- * Calculate a new sin and cosine value based on the given phase
- *
- * Inputs:
- * nPhase - phase angle
- * pnSin - input old value, output new value
- * pnCos - input old value, output new value
- *
- * Outputs:
- *
- * Side Effects:
- * - *pnSin, *pnCos are updated
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT ReverbCalculateSinCos(EAS_I16 nPhase, EAS_I16 *pnSin, EAS_I16 *pnCos)
-{
- EAS_I32 nTemp;
- EAS_I32 nNetAngle;
-
- // -1 <= nPhase < 1
- // However, for the calculation, we need a value
- // that ranges from -1/2 to +1/2, so divide the phase by 2
- /*lint -e{702} shift for performance */
- nNetAngle = nPhase >> 1;
-
- /*
- Implement the following
- sin(x) = (2-4*c)*x^2 + c + x
- cos(x) = (2-4*c)*x^2 + c - x
-
- where c = 1/sqrt(2)
- using the a0 + x*(a1 + x*a2) approach
- */
-
- /* limit the input "angle" to be between -0.5 and +0.5 */
- if (nNetAngle > EG1_HALF)
- {
- nNetAngle = EG1_HALF;
- }
- else if (nNetAngle < EG1_MINUS_HALF)
- {
- nNetAngle = EG1_MINUS_HALF;
- }
-
- /* calculate sin */
- nTemp = EG1_ONE + MULT_EG1_EG1(REVERB_PAN_G2, nNetAngle);
- nTemp = REVERB_PAN_G0 + MULT_EG1_EG1(nTemp, nNetAngle);
- *pnSin = (EAS_I16) SATURATE_EG1(nTemp);
-
- /* calculate cos */
- nTemp = -EG1_ONE + MULT_EG1_EG1(REVERB_PAN_G2, nNetAngle);
- nTemp = REVERB_PAN_G0 + MULT_EG1_EG1(nTemp, nNetAngle);
- *pnCos = (EAS_I16) SATURATE_EG1(nTemp);
-
- return EAS_SUCCESS;
-} /* end ReverbCalculateSinCos */
-
-/*----------------------------------------------------------------------------
- * Reverb
- *----------------------------------------------------------------------------
- * Purpose:
- * apply reverb to the given signal
- *
- * Inputs:
- * nNu
- * pnSin - input old value, output new value
- * pnCos - input old value, output new value
- *
- * Outputs:
- * number of samples actually reverberated
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT Reverb(S_REVERB_OBJECT *pReverbData, EAS_INT nNumSamplesToAdd, EAS_PCM *pOutputBuffer, EAS_PCM *pInputBuffer)
-{
- EAS_I32 i;
- EAS_I32 nDelayOut;
- EAS_U16 nBase;
-
- EAS_U32 nAddr;
- EAS_I32 nTemp1;
- EAS_I32 nTemp2;
- EAS_I32 nApIn;
- EAS_I32 nApOut;
-
- EAS_I32 j;
- EAS_I32 nEarlyOut;
-
- EAS_I32 tempValue;
-
-
- // get the base address
- nBase = pReverbData->m_nBaseIndex;
-
- for (i=0; i < nNumSamplesToAdd; i++)
- {
- // ********** Left Allpass - start
- // left input = (left dry/4) + right feedback from previous period
- /*lint -e{702} use shift for performance */
- nApIn = ((*pInputBuffer++)>>2) + pReverbData->m_nRevOutFbkR;
-// nApIn = *pInputBuffer++; // 1xxx test and debug ap
-
- // fetch allpass delay line out
- //nAddr = CIRCULAR(nBase, psAp0->m_zApOut, REVERB_BUFFER_MASK);
- nAddr = CIRCULAR(nBase, pReverbData->m_sAp0.m_zApOut, REVERB_BUFFER_MASK);
- nDelayOut = pReverbData->m_nDelayLine[nAddr];
-
- // calculate allpass feedforward; subtract the feedforward result
- nTemp1 = MULT_EG1_EG1(nApIn, pReverbData->m_sAp0.m_nApGain);
- nApOut = SATURATE(nDelayOut - nTemp1); // allpass output
-
- // calculate allpass feedback; add the feedback result
- nTemp1 = MULT_EG1_EG1(nApOut, pReverbData->m_sAp0.m_nApGain);
- nTemp1 = SATURATE(nApIn + nTemp1);
-
- // inject into allpass delay
- nAddr = CIRCULAR(nBase, pReverbData->m_sAp0.m_zApIn, REVERB_BUFFER_MASK);
- pReverbData->m_nDelayLine[nAddr] = (EAS_PCM) nTemp1;
-
- // inject allpass output into delay line
- nAddr = CIRCULAR(nBase, pReverbData->m_zD0In, REVERB_BUFFER_MASK);
- pReverbData->m_nDelayLine[nAddr] = (EAS_PCM) nApOut;
-
- // ********** Left Allpass - end
-
- // ********** Right Allpass - start
- // right input = (right dry/4) + left feedback from previous period
- /*lint -e{702} use shift for performance */
- nApIn = ((*pInputBuffer++)>>2) + pReverbData->m_nRevOutFbkL;
-// nApIn = *pInputBuffer++; // 1xxx test and debug ap
-
- // fetch allpass delay line out
- nAddr = CIRCULAR(nBase, pReverbData->m_sAp1.m_zApOut, REVERB_BUFFER_MASK);
- nDelayOut = pReverbData->m_nDelayLine[nAddr];
-
- // calculate allpass feedforward; subtract the feedforward result
- nTemp1 = MULT_EG1_EG1(nApIn, pReverbData->m_sAp1.m_nApGain);
- nApOut = SATURATE(nDelayOut - nTemp1); // allpass output
-
- // calculate allpass feedback; add the feedback result
- nTemp1 = MULT_EG1_EG1(nApOut, pReverbData->m_sAp1.m_nApGain);
- nTemp1 = SATURATE(nApIn + nTemp1);
-
- // inject into allpass delay
- nAddr = CIRCULAR(nBase, pReverbData->m_sAp1.m_zApIn, REVERB_BUFFER_MASK);
- pReverbData->m_nDelayLine[nAddr] = (EAS_PCM) nTemp1;
-
- // inject allpass output into delay line
- nAddr = CIRCULAR(nBase, pReverbData->m_zD1In, REVERB_BUFFER_MASK);
- pReverbData->m_nDelayLine[nAddr] = (EAS_PCM) nApOut;
-
- // ********** Right Allpass - end
-
- // ********** D0 output - start
- // fetch delay line self out
- nAddr = CIRCULAR(nBase, pReverbData->m_zD0Self, REVERB_BUFFER_MASK);
- nDelayOut = pReverbData->m_nDelayLine[nAddr];
-
- // calculate delay line self out
- nTemp1 = MULT_EG1_EG1(nDelayOut, pReverbData->m_nSin);
-
- // fetch delay line cross out
- nAddr = CIRCULAR(nBase, pReverbData->m_zD1Cross, REVERB_BUFFER_MASK);
- nDelayOut = pReverbData->m_nDelayLine[nAddr];
-
- // calculate delay line self out
- nTemp2 = MULT_EG1_EG1(nDelayOut, pReverbData->m_nCos);
-
- // calculate unfiltered delay out
- nDelayOut = SATURATE(nTemp1 + nTemp2);
-
- // calculate lowpass filter (mixer scale factor included in LPF feedforward)
- nTemp1 = MULT_EG1_EG1(nDelayOut, pReverbData->m_nLpfFwd);
-
- nTemp2 = MULT_EG1_EG1(pReverbData->m_zLpf0, pReverbData->m_nLpfFbk);
-
- // calculate filtered delay out and simultaneously update LPF state variable
- // filtered delay output is stored in m_zLpf0
- pReverbData->m_zLpf0 = (EAS_PCM) SATURATE(nTemp1 + nTemp2);
-
- // ********** D0 output - end
-
- // ********** D1 output - start
- // fetch delay line self out
- nAddr = CIRCULAR(nBase, pReverbData->m_zD1Self, REVERB_BUFFER_MASK);
- nDelayOut = pReverbData->m_nDelayLine[nAddr];
-
- // calculate delay line self out
- nTemp1 = MULT_EG1_EG1(nDelayOut, pReverbData->m_nSin);
-
- // fetch delay line cross out
- nAddr = CIRCULAR(nBase, pReverbData->m_zD0Cross, REVERB_BUFFER_MASK);
- nDelayOut = pReverbData->m_nDelayLine[nAddr];
-
- // calculate delay line self out
- nTemp2 = MULT_EG1_EG1(nDelayOut, pReverbData->m_nCos);
-
- // calculate unfiltered delay out
- nDelayOut = SATURATE(nTemp1 + nTemp2);
-
- // calculate lowpass filter (mixer scale factor included in LPF feedforward)
- nTemp1 = MULT_EG1_EG1(nDelayOut, pReverbData->m_nLpfFwd);
-
- nTemp2 = MULT_EG1_EG1(pReverbData->m_zLpf1, pReverbData->m_nLpfFbk);
-
- // calculate filtered delay out and simultaneously update LPF state variable
- // filtered delay output is stored in m_zLpf1
- pReverbData->m_zLpf1 = (EAS_PCM)SATURATE(nTemp1 + nTemp2);
-
- // ********** D1 output - end
-
- // ********** mixer and feedback - start
- // sum is fedback to right input (R + L)
- pReverbData->m_nRevOutFbkL =
- (EAS_PCM)SATURATE((EAS_I32)pReverbData->m_zLpf1 + (EAS_I32)pReverbData->m_zLpf0);
-
- // difference is feedback to left input (R - L)
- /*lint -e{685} lint complains that it can't saturate negative */
- pReverbData->m_nRevOutFbkR =
- (EAS_PCM)SATURATE((EAS_I32)pReverbData->m_zLpf1 - (EAS_I32)pReverbData->m_zLpf0);
-
- // ********** mixer and feedback - end
-
- // ********** start early reflection generator, left
- //psEarly = &(pReverbData->m_sEarlyL);
-
- nEarlyOut = 0;
-
- for (j=0; j < REVERB_MAX_NUM_REFLECTIONS; j++)
- {
- // fetch delay line out
- //nAddr = CIRCULAR(nBase, psEarly->m_zDelay[j], REVERB_BUFFER_MASK);
- nAddr = CIRCULAR(nBase, pReverbData->m_sEarlyL.m_zDelay[j], REVERB_BUFFER_MASK);
-
- nDelayOut = pReverbData->m_nDelayLine[nAddr];
-
- // calculate reflection
- //nTemp1 = MULT_EG1_EG1(nDelayOut, psEarly->m_nGain[j]);
- nTemp1 = MULT_EG1_EG1(nDelayOut, pReverbData->m_sEarlyL.m_nGain[j]);
-
- nEarlyOut = SATURATE(nEarlyOut + nTemp1);
-
- } // end for (j=0; j < REVERB_MAX_NUM_REFLECTIONS; j++)
-
- // apply lowpass to early reflections
- //nTemp1 = MULT_EG1_EG1(nEarlyOut, psEarly->m_nLpfFwd);
- nTemp1 = MULT_EG1_EG1(nEarlyOut, pReverbData->m_sEarlyL.m_nLpfFwd);
-
- //nTemp2 = MULT_EG1_EG1(psEarly->m_zLpf, psEarly->m_nLpfFbk);
- nTemp2 = MULT_EG1_EG1(pReverbData->m_sEarlyL.m_zLpf, pReverbData->m_sEarlyL.m_nLpfFbk);
-
-
- // calculate filtered out and simultaneously update LPF state variable
- // filtered output is stored in m_zLpf1
- //psEarly->m_zLpf = SATURATE(nTemp1 + nTemp2);
- pReverbData->m_sEarlyL.m_zLpf = (EAS_PCM) SATURATE(nTemp1 + nTemp2);
-
- // combine filtered early and late reflections for output
- //*pOutputBuffer++ = inL;
- //tempValue = SATURATE(psEarly->m_zLpf + pReverbData->m_nRevOutFbkL);
- tempValue = SATURATE((EAS_I32)pReverbData->m_sEarlyL.m_zLpf + (EAS_I32)pReverbData->m_nRevOutFbkL);
- //scale reverb output by wet level
- /*lint -e{701} use shift for performance */
- tempValue = MULT_EG1_EG1(tempValue, (pReverbData->m_nWet<<1));
- //sum with output buffer
- tempValue += *pOutputBuffer;
- *pOutputBuffer++ = (EAS_PCM)SATURATE(tempValue);
-
- // ********** end early reflection generator, left
-
- // ********** start early reflection generator, right
- //psEarly = &(pReverbData->m_sEarlyR);
-
- nEarlyOut = 0;
-
- for (j=0; j < REVERB_MAX_NUM_REFLECTIONS; j++)
- {
- // fetch delay line out
- nAddr = CIRCULAR(nBase, pReverbData->m_sEarlyR.m_zDelay[j], REVERB_BUFFER_MASK);
- nDelayOut = pReverbData->m_nDelayLine[nAddr];
-
- // calculate reflection
- nTemp1 = MULT_EG1_EG1(nDelayOut, pReverbData->m_sEarlyR.m_nGain[j]);
-
- nEarlyOut = SATURATE(nEarlyOut + nTemp1);
-
- } // end for (j=0; j < REVERB_MAX_NUM_REFLECTIONS; j++)
-
- // apply lowpass to early reflections
- nTemp1 = MULT_EG1_EG1(nEarlyOut, pReverbData->m_sEarlyR.m_nLpfFwd);
-
- nTemp2 = MULT_EG1_EG1(pReverbData->m_sEarlyR.m_zLpf, pReverbData->m_sEarlyR.m_nLpfFbk);
-
- // calculate filtered out and simultaneously update LPF state variable
- // filtered output is stored in m_zLpf1
- pReverbData->m_sEarlyR.m_zLpf = (EAS_PCM)SATURATE(nTemp1 + nTemp2);
-
- // combine filtered early and late reflections for output
- //*pOutputBuffer++ = inR;
- tempValue = SATURATE((EAS_I32)pReverbData->m_sEarlyR.m_zLpf + (EAS_I32)pReverbData->m_nRevOutFbkR);
- //scale reverb output by wet level
- /*lint -e{701} use shift for performance */
- tempValue = MULT_EG1_EG1(tempValue, (pReverbData->m_nWet << 1));
- //sum with output buffer
- tempValue = tempValue + *pOutputBuffer;
- *pOutputBuffer++ = (EAS_PCM)SATURATE(tempValue);
-
- // ********** end early reflection generator, right
-
- // decrement base addr for next sample period
- nBase--;
-
- pReverbData->m_nSin += pReverbData->m_nSinIncrement;
- pReverbData->m_nCos += pReverbData->m_nCosIncrement;
-
- } // end for (i=0; i < nNumSamplesToAdd; i++)
-
- // store the most up to date version
- pReverbData->m_nBaseIndex = nBase;
-
- return EAS_SUCCESS;
-} /* end Reverb */
-
-
-
-/*----------------------------------------------------------------------------
- * ReverbShutdown()
- *----------------------------------------------------------------------------
- * Purpose:
- * Initializes the Reverb effect.
- *
- * Inputs:
- * pInstData - handle to instance data
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT ReverbShutdown (EAS_DATA_HANDLE pEASData, EAS_VOID_PTR pInstData)
-{
- /* check Configuration Module for static memory allocation */
- if (!pEASData->staticMemoryModel)
- EAS_HWFree(pEASData->hwInstData, pInstData);
- return EAS_SUCCESS;
-} /* end ReverbShutdown */
-
-/*----------------------------------------------------------------------------
- * ReverbGetParam()
- *----------------------------------------------------------------------------
- * Purpose:
- * Get a Reverb parameter
- *
- * Inputs:
- * pInstData - handle to instance data
- * param - parameter index
- * *pValue - pointer to variable to hold retrieved value
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT ReverbGetParam (EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue)
-{
- S_REVERB_OBJECT *p;
-
- p = (S_REVERB_OBJECT*) pInstData;
-
- switch (param)
- {
- case EAS_PARAM_REVERB_BYPASS:
- *pValue = (EAS_I32) p->m_bBypass;
- break;
- case EAS_PARAM_REVERB_PRESET:
- *pValue = (EAS_I8) p->m_nCurrentRoom;
- break;
- case EAS_PARAM_REVERB_WET:
- *pValue = p->m_nWet;
- break;
- case EAS_PARAM_REVERB_DRY:
- *pValue = p->m_nDry;
- break;
- default:
- return EAS_ERROR_INVALID_PARAMETER;
- }
- return EAS_SUCCESS;
-} /* end ReverbGetParam */
-
-
-/*----------------------------------------------------------------------------
- * ReverbSetParam()
- *----------------------------------------------------------------------------
- * Purpose:
- * Set a Reverb parameter
- *
- * Inputs:
- * pInstData - handle to instance data
- * param - parameter index
- * *pValue - new paramter value
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT ReverbSetParam (EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value)
-{
- S_REVERB_OBJECT *p;
-
- p = (S_REVERB_OBJECT*) pInstData;
-
- switch (param)
- {
- case EAS_PARAM_REVERB_BYPASS:
- p->m_bBypass = (EAS_BOOL) value;
- break;
- case EAS_PARAM_REVERB_PRESET:
- if(value!=EAS_PARAM_REVERB_LARGE_HALL && value!=EAS_PARAM_REVERB_HALL &&
- value!=EAS_PARAM_REVERB_CHAMBER && value!=EAS_PARAM_REVERB_ROOM)
- return EAS_ERROR_INVALID_PARAMETER;
- p->m_nNextRoom = (EAS_I16)value;
- break;
- case EAS_PARAM_REVERB_WET:
- if(value>EAS_REVERB_WET_MAX || value<EAS_REVERB_WET_MIN)
- return EAS_ERROR_INVALID_PARAMETER;
- p->m_nWet = (EAS_I16)value;
- break;
- case EAS_PARAM_REVERB_DRY:
- if(value>EAS_REVERB_DRY_MAX || value<EAS_REVERB_DRY_MIN)
- return EAS_ERROR_INVALID_PARAMETER;
- p->m_nDry = (EAS_I16)value;
- break;
- default:
- return EAS_ERROR_INVALID_PARAMETER;
- }
- return EAS_SUCCESS;
-} /* end ReverbSetParam */
-
-
-/*----------------------------------------------------------------------------
- * ReverbUpdateRoom
- *----------------------------------------------------------------------------
- * Purpose:
- * Update the room's preset parameters as required
- *
- * Inputs:
- *
- * Outputs:
- *
- *
- * Side Effects:
- * - reverb paramters (fbk, fwd, etc) will be changed
- * - m_nCurrentRoom := m_nNextRoom
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT ReverbUpdateRoom(S_REVERB_OBJECT *pReverbData)
-{
- EAS_INT temp;
-
- S_REVERB_PRESET *pPreset = &pReverbData->m_sPreset.m_sPreset[pReverbData->m_nNextRoom];
-
- pReverbData->m_nLpfFwd = pPreset->m_nLpfFwd;
- pReverbData->m_nLpfFbk = pPreset->m_nLpfFbk;
-
- pReverbData->m_nEarly = pPreset->m_nEarly;
- pReverbData->m_nWet = pPreset->m_nWet;
- pReverbData->m_nDry = pPreset->m_nDry;
-
-
- pReverbData->m_nMaxExcursion = pPreset->m_nMaxExcursion;
- //stored as time based, convert to sample based
- temp = pPreset->m_nXfadeInterval;
- /*lint -e{702} shift for performance */
- temp = (temp * _OUTPUT_SAMPLE_RATE) >> 16;
- pReverbData->m_nXfadeInterval = (EAS_U16) temp;
- //gpsReverbObject->m_nXfadeInterval = pPreset->m_nXfadeInterval;
- pReverbData->m_sAp0.m_nApGain = pPreset->m_nAp0_ApGain;
- //stored as time based, convert to absolute sample value
- temp = pPreset->m_nAp0_ApOut;
- /*lint -e{702} shift for performance */
- temp = (temp * _OUTPUT_SAMPLE_RATE) >> 16;
- pReverbData->m_sAp0.m_zApOut = (EAS_U16) (pReverbData->m_sAp0.m_zApIn + temp);
- //gpsReverbObject->m_sAp0.m_zApOut = pPreset->m_nAp0_ApOut;
- pReverbData->m_sAp1.m_nApGain = pPreset->m_nAp1_ApGain;
- //stored as time based, convert to absolute sample value
- temp = pPreset->m_nAp1_ApOut;
- /*lint -e{702} shift for performance */
- temp = (temp * _OUTPUT_SAMPLE_RATE) >> 16;
- pReverbData->m_sAp1.m_zApOut = (EAS_U16) (pReverbData->m_sAp1.m_zApIn + temp);
- //gpsReverbObject->m_sAp1.m_zApOut = pPreset->m_nAp1_ApOut;
-
- pReverbData->m_nCurrentRoom = pReverbData->m_nNextRoom;
-
- return EAS_SUCCESS;
-
-} /* end ReverbUpdateRoom */
-
-
-/*----------------------------------------------------------------------------
- * ReverbReadInPresets()
- *----------------------------------------------------------------------------
- * Purpose: sets global reverb preset bank to defaults
- *
- * Inputs:
- *
- * Outputs:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT ReverbReadInPresets(S_REVERB_OBJECT *pReverbData)
-{
-
- int preset = 0;
- int defaultPreset = 0;
-
- //now init any remaining presets to defaults
- for (defaultPreset = preset; defaultPreset < REVERB_MAX_ROOM_TYPE; defaultPreset++)
- {
- S_REVERB_PRESET *pPreset = &pReverbData->m_sPreset.m_sPreset[defaultPreset];
- if (defaultPreset == 0 || defaultPreset > REVERB_MAX_ROOM_TYPE-1)
- {
- pPreset->m_nLpfFbk = 8307;
- pPreset->m_nLpfFwd = 14768;
- pPreset->m_nEarly = 0;
- pPreset->m_nWet = 27690;
- pPreset->m_nDry = 32767;
- pPreset->m_nEarlyL_LpfFbk = 3692;
- pPreset->m_nEarlyL_LpfFwd = 29075;
- pPreset->m_nEarlyL_Delay0 = 922;
- pPreset->m_nEarlyL_Gain0 = 22152;
- pPreset->m_nEarlyL_Delay1 = 1462;
- pPreset->m_nEarlyL_Gain1 = 17537;
- pPreset->m_nEarlyL_Delay2 = 0;
- pPreset->m_nEarlyL_Gain2 = 14768;
- pPreset->m_nEarlyL_Delay3 = 1221;
- pPreset->m_nEarlyL_Gain3 = 14307;
- pPreset->m_nEarlyL_Delay4 = 0;
- pPreset->m_nEarlyL_Gain4 = 13384;
- pPreset->m_nEarlyR_Delay0 = 502;
- pPreset->m_nEarlyR_Gain0 = 20306;
- pPreset->m_nEarlyR_Delay1 = 1762;
- pPreset->m_nEarlyR_Gain1 = 17537;
- pPreset->m_nEarlyR_Delay2 = 0;
- pPreset->m_nEarlyR_Gain2 = 14768;
- pPreset->m_nEarlyR_Delay3 = 0;
- pPreset->m_nEarlyR_Gain3 = 16153;
- pPreset->m_nEarlyR_Delay4 = 0;
- pPreset->m_nEarlyR_Gain4 = 13384;
- pPreset->m_nMaxExcursion = 127;
- pPreset->m_nXfadeInterval = 6388;
- pPreset->m_nAp0_ApGain = 15691;
- pPreset->m_nAp0_ApOut = 711;
- pPreset->m_nAp1_ApGain = 17999;
- pPreset->m_nAp1_ApOut = 1113;
- pPreset->m_rfu4 = 0;
- pPreset->m_rfu5 = 0;
- pPreset->m_rfu6 = 0;
- pPreset->m_rfu7 = 0;
- pPreset->m_rfu8 = 0;
- pPreset->m_rfu9 = 0;
- pPreset->m_rfu10 = 0;
- }
- else if (defaultPreset == 1)
- {
- pPreset->m_nLpfFbk = 6461;
- pPreset->m_nLpfFwd = 14307;
- pPreset->m_nEarly = 0;
- pPreset->m_nWet = 27690;
- pPreset->m_nDry = 32767;
- pPreset->m_nEarlyL_LpfFbk = 3692;
- pPreset->m_nEarlyL_LpfFwd = 29075;
- pPreset->m_nEarlyL_Delay0 = 922;
- pPreset->m_nEarlyL_Gain0 = 22152;
- pPreset->m_nEarlyL_Delay1 = 1462;
- pPreset->m_nEarlyL_Gain1 = 17537;
- pPreset->m_nEarlyL_Delay2 = 0;
- pPreset->m_nEarlyL_Gain2 = 14768;
- pPreset->m_nEarlyL_Delay3 = 1221;
- pPreset->m_nEarlyL_Gain3 = 14307;
- pPreset->m_nEarlyL_Delay4 = 0;
- pPreset->m_nEarlyL_Gain4 = 13384;
- pPreset->m_nEarlyR_Delay0 = 502;
- pPreset->m_nEarlyR_Gain0 = 20306;
- pPreset->m_nEarlyR_Delay1 = 1762;
- pPreset->m_nEarlyR_Gain1 = 17537;
- pPreset->m_nEarlyR_Delay2 = 0;
- pPreset->m_nEarlyR_Gain2 = 14768;
- pPreset->m_nEarlyR_Delay3 = 0;
- pPreset->m_nEarlyR_Gain3 = 16153;
- pPreset->m_nEarlyR_Delay4 = 0;
- pPreset->m_nEarlyR_Gain4 = 13384;
- pPreset->m_nMaxExcursion = 127;
- pPreset->m_nXfadeInterval = 6391;
- pPreset->m_nAp0_ApGain = 15230;
- pPreset->m_nAp0_ApOut = 708;
- pPreset->m_nAp1_ApGain = 9692;
- pPreset->m_nAp1_ApOut = 1113;
- pPreset->m_rfu4 = 0;
- pPreset->m_rfu5 = 0;
- pPreset->m_rfu6 = 0;
- pPreset->m_rfu7 = 0;
- pPreset->m_rfu8 = 0;
- pPreset->m_rfu9 = 0;
- pPreset->m_rfu10 = 0;
- }
- else if (defaultPreset == 2)
- {
- pPreset->m_nLpfFbk = 5077;
- pPreset->m_nLpfFwd = 12922;
- pPreset->m_nEarly = 0;
- pPreset->m_nWet = 24460;
- pPreset->m_nDry = 32767;
- pPreset->m_nEarlyL_LpfFbk = 3692;
- pPreset->m_nEarlyL_LpfFwd = 29075;
- pPreset->m_nEarlyL_Delay0 = 922;
- pPreset->m_nEarlyL_Gain0 = 22152;
- pPreset->m_nEarlyL_Delay1 = 1462;
- pPreset->m_nEarlyL_Gain1 = 17537;
- pPreset->m_nEarlyL_Delay2 = 0;
- pPreset->m_nEarlyL_Gain2 = 14768;
- pPreset->m_nEarlyL_Delay3 = 1221;
- pPreset->m_nEarlyL_Gain3 = 14307;
- pPreset->m_nEarlyL_Delay4 = 0;
- pPreset->m_nEarlyL_Gain4 = 13384;
- pPreset->m_nEarlyR_Delay0 = 502;
- pPreset->m_nEarlyR_Gain0 = 20306;
- pPreset->m_nEarlyR_Delay1 = 1762;
- pPreset->m_nEarlyR_Gain1 = 17537;
- pPreset->m_nEarlyR_Delay2 = 0;
- pPreset->m_nEarlyR_Gain2 = 14768;
- pPreset->m_nEarlyR_Delay3 = 0;
- pPreset->m_nEarlyR_Gain3 = 16153;
- pPreset->m_nEarlyR_Delay4 = 0;
- pPreset->m_nEarlyR_Gain4 = 13384;
- pPreset->m_nMaxExcursion = 127;
- pPreset->m_nXfadeInterval = 6449;
- pPreset->m_nAp0_ApGain = 15691;
- pPreset->m_nAp0_ApOut = 774;
- pPreset->m_nAp1_ApGain = 15691;
- pPreset->m_nAp1_ApOut = 1113;
- pPreset->m_rfu4 = 0;
- pPreset->m_rfu5 = 0;
- pPreset->m_rfu6 = 0;
- pPreset->m_rfu7 = 0;
- pPreset->m_rfu8 = 0;
- pPreset->m_rfu9 = 0;
- pPreset->m_rfu10 = 0;
- }
- else if (defaultPreset == 3)
- {
- pPreset->m_nLpfFbk = 5077;
- pPreset->m_nLpfFwd = 11076;
- pPreset->m_nEarly = 0;
- pPreset->m_nWet = 23075;
- pPreset->m_nDry = 32767;
- pPreset->m_nEarlyL_LpfFbk = 3692;
- pPreset->m_nEarlyL_LpfFwd = 29075;
- pPreset->m_nEarlyL_Delay0 = 922;
- pPreset->m_nEarlyL_Gain0 = 22152;
- pPreset->m_nEarlyL_Delay1 = 1462;
- pPreset->m_nEarlyL_Gain1 = 17537;
- pPreset->m_nEarlyL_Delay2 = 0;
- pPreset->m_nEarlyL_Gain2 = 14768;
- pPreset->m_nEarlyL_Delay3 = 1221;
- pPreset->m_nEarlyL_Gain3 = 14307;
- pPreset->m_nEarlyL_Delay4 = 0;
- pPreset->m_nEarlyL_Gain4 = 13384;
- pPreset->m_nEarlyR_Delay0 = 502;
- pPreset->m_nEarlyR_Gain0 = 20306;
- pPreset->m_nEarlyR_Delay1 = 1762;
- pPreset->m_nEarlyR_Gain1 = 17537;
- pPreset->m_nEarlyR_Delay2 = 0;
- pPreset->m_nEarlyR_Gain2 = 14768;
- pPreset->m_nEarlyR_Delay3 = 0;
- pPreset->m_nEarlyR_Gain3 = 16153;
- pPreset->m_nEarlyR_Delay4 = 0;
- pPreset->m_nEarlyR_Gain4 = 13384;
- pPreset->m_nMaxExcursion = 127;
- pPreset->m_nXfadeInterval = 6470; //6483;
- pPreset->m_nAp0_ApGain = 14768;
- pPreset->m_nAp0_ApOut = 792;
- pPreset->m_nAp1_ApGain = 15783;
- pPreset->m_nAp1_ApOut = 1113;
- pPreset->m_rfu4 = 0;
- pPreset->m_rfu5 = 0;
- pPreset->m_rfu6 = 0;
- pPreset->m_rfu7 = 0;
- pPreset->m_rfu8 = 0;
- pPreset->m_rfu9 = 0;
- pPreset->m_rfu10 = 0;
-
- }
- }
-
- return EAS_SUCCESS;
-}
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 510 $
+ * $Date: 2006-12-19 01:47:33 -0800 (Tue, 19 Dec 2006) $
+ *----------------------------------------------------------------------------
+*/
+
+/*------------------------------------
+ * includes
+ *------------------------------------
+*/
+
+#include "eas_data.h"
+#include "eas_effects.h"
+#include "eas_math.h"
+#include "eas_reverbdata.h"
+#include "eas_reverb.h"
+#include "eas_config.h"
+#include "eas_host.h"
+#include "eas_report.h"
+
+/* prototypes for effects interface */
+static EAS_RESULT ReverbInit (EAS_DATA_HANDLE pEASData, EAS_VOID_PTR *pInstData);
+static void ReverbProcess (EAS_VOID_PTR pInstData, EAS_PCM *pSrc, EAS_PCM *pDst, EAS_I32 numSamples);
+static EAS_RESULT ReverbShutdown (EAS_DATA_HANDLE pEASData, EAS_VOID_PTR pInstData);
+static EAS_RESULT ReverbGetParam (EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue);
+static EAS_RESULT ReverbSetParam (EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value);
+
+/* common effects interface for configuration module */
+const S_EFFECTS_INTERFACE EAS_Reverb =
+{
+ ReverbInit,
+ ReverbProcess,
+ ReverbShutdown,
+ ReverbGetParam,
+ ReverbSetParam
+};
+
+
+
+/*----------------------------------------------------------------------------
+ * InitializeReverb()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ *
+ * Inputs:
+ *
+ * Outputs:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT ReverbInit(EAS_DATA_HANDLE pEASData, EAS_VOID_PTR *pInstData)
+{
+ EAS_I32 i;
+ EAS_U16 nOffset;
+ EAS_INT temp;
+
+ S_REVERB_OBJECT *pReverbData;
+ S_REVERB_PRESET *pPreset;
+
+ /* check Configuration Module for data allocation */
+ if (pEASData->staticMemoryModel)
+ pReverbData = EAS_CMEnumFXData(EAS_MODULE_REVERB);
+
+ /* allocate dynamic memory */
+ else
+ pReverbData = EAS_HWMalloc(pEASData->hwInstData, sizeof(S_REVERB_OBJECT));
+
+ if (pReverbData == NULL)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_FATAL, "Failed to allocate Reverb memory\n"); */ }
+ return EAS_ERROR_MALLOC_FAILED;
+ }
+
+ /* clear the structure */
+ EAS_HWMemSet(pReverbData, 0, sizeof(S_REVERB_OBJECT));
+
+ ReverbReadInPresets(pReverbData);
+
+ pReverbData->m_nMinSamplesToAdd = REVERB_UPDATE_PERIOD_IN_SAMPLES;
+
+ pReverbData->m_nRevOutFbkR = 0;
+ pReverbData->m_nRevOutFbkL = 0;
+
+ pReverbData->m_sAp0.m_zApIn = AP0_IN;
+ pReverbData->m_sAp0.m_zApOut = AP0_IN + DEFAULT_AP0_LENGTH;
+ pReverbData->m_sAp0.m_nApGain = DEFAULT_AP0_GAIN;
+
+ pReverbData->m_zD0In = DELAY0_IN;
+
+ pReverbData->m_sAp1.m_zApIn = AP1_IN;
+ pReverbData->m_sAp1.m_zApOut = AP1_IN + DEFAULT_AP1_LENGTH;
+ pReverbData->m_sAp1.m_nApGain = DEFAULT_AP1_GAIN;
+
+ pReverbData->m_zD1In = DELAY1_IN;
+
+ pReverbData->m_zLpf0 = 0;
+ pReverbData->m_zLpf1 = 0;
+ pReverbData->m_nLpfFwd = 8837;
+ pReverbData->m_nLpfFbk = 6494;
+
+ pReverbData->m_nSin = 0;
+ pReverbData->m_nCos = 0;
+ pReverbData->m_nSinIncrement = 0;
+ pReverbData->m_nCosIncrement = 0;
+
+ // set xfade parameters
+ pReverbData->m_nXfadeInterval = (EAS_U16)REVERB_XFADE_PERIOD_IN_SAMPLES;
+ pReverbData->m_nXfadeCounter = pReverbData->m_nXfadeInterval + 1; // force update on first iteration
+ pReverbData->m_nPhase = -32768;
+ pReverbData->m_nPhaseIncrement = REVERB_XFADE_PHASE_INCREMENT;
+
+ pReverbData->m_nNoise = (EAS_I16)0xABCD;
+
+ pReverbData->m_nMaxExcursion = 0x007F;
+
+ // set delay tap lengths
+ nOffset = ReverbCalculateNoise( pReverbData->m_nMaxExcursion,
+ &pReverbData->m_nNoise );
+
+ pReverbData->m_zD1Cross =
+ DELAY1_OUT - pReverbData->m_nMaxExcursion + nOffset;
+
+ nOffset = ReverbCalculateNoise( pReverbData->m_nMaxExcursion,
+ &pReverbData->m_nNoise );
+
+ pReverbData->m_zD0Cross =
+ DELAY1_OUT - pReverbData->m_nMaxExcursion - nOffset;
+
+ nOffset = ReverbCalculateNoise( pReverbData->m_nMaxExcursion,
+ &pReverbData->m_nNoise );
+
+ pReverbData->m_zD0Self =
+ DELAY0_OUT - pReverbData->m_nMaxExcursion - nOffset;
+
+ nOffset = ReverbCalculateNoise( pReverbData->m_nMaxExcursion,
+ &pReverbData->m_nNoise );
+
+ pReverbData->m_zD1Self =
+ DELAY1_OUT - pReverbData->m_nMaxExcursion + nOffset;
+
+ // for debugging purposes, allow noise generator
+ pReverbData->m_bUseNoise = EAS_FALSE;
+
+ // for debugging purposes, allow bypass
+ pReverbData->m_bBypass = EAS_TRUE; //EAS_FALSE;
+
+ pReverbData->m_nNextRoom = 1;
+
+ pReverbData->m_nCurrentRoom = pReverbData->m_nNextRoom + 1; // force update on first iteration
+
+ pReverbData->m_nWet = REVERB_DEFAULT_WET;
+
+ pReverbData->m_nDry = REVERB_DEFAULT_DRY;
+
+ // set base index into circular buffer
+ pReverbData->m_nBaseIndex = 0;
+
+ // set the early reflections, L
+ pReverbData->m_sEarlyL.m_nLpfFbk = 4915;
+ pReverbData->m_sEarlyL.m_nLpfFwd = 27852;
+ pReverbData->m_sEarlyL.m_zLpf = 0;
+
+ for (i=0; i < REVERB_MAX_NUM_REFLECTIONS; i++)
+ {
+ pReverbData->m_sEarlyL.m_nGain[i] = 0;
+ pReverbData->m_sEarlyL.m_zDelay[i] = 0;
+ }
+
+ // set the early reflections, R
+ pReverbData->m_sEarlyR.m_nLpfFbk = 4915;
+ pReverbData->m_sEarlyR.m_nLpfFwd = 27852;
+ pReverbData->m_sEarlyR.m_zLpf = 0;
+
+ for (i=0; i < REVERB_MAX_NUM_REFLECTIONS; i++)
+ {
+ pReverbData->m_sEarlyR.m_nGain[i] = 0;
+ pReverbData->m_sEarlyR.m_zDelay[i] = 0;
+ }
+
+ // clear the reverb delay line
+ for (i=0; i < REVERB_BUFFER_SIZE_IN_SAMPLES; i++)
+ {
+ pReverbData->m_nDelayLine[i] = 0;
+ }
+
+ ////////////////////////////////
+ ///code from the EAS DEMO Reverb
+ //now copy from the new preset into the reverb
+ pPreset = &pReverbData->m_sPreset.m_sPreset[pReverbData->m_nNextRoom];
+
+ pReverbData->m_nLpfFbk = pPreset->m_nLpfFbk;
+ pReverbData->m_nLpfFwd = pPreset->m_nLpfFwd;
+
+ pReverbData->m_nEarly = pPreset->m_nEarly;
+ pReverbData->m_nWet = pPreset->m_nWet;
+ pReverbData->m_nDry = pPreset->m_nDry;
+
+ pReverbData->m_nMaxExcursion = pPreset->m_nMaxExcursion;
+ //stored as time based, convert to sample based
+ temp = pPreset->m_nXfadeInterval;
+ /*lint -e{702} shift for performance */
+ temp = (temp * _OUTPUT_SAMPLE_RATE) >> 16;
+ pReverbData->m_nXfadeInterval = (EAS_U16) temp;
+ //gsReverbObject.m_nXfadeInterval = pPreset->m_nXfadeInterval;
+
+ pReverbData->m_sAp0.m_nApGain = pPreset->m_nAp0_ApGain;
+ //stored as time based, convert to absolute sample value
+ temp = pPreset->m_nAp0_ApOut;
+ /*lint -e{702} shift for performance */
+ temp = (temp * _OUTPUT_SAMPLE_RATE) >> 16;
+ pReverbData->m_sAp0.m_zApOut = (EAS_U16) (pReverbData->m_sAp0.m_zApIn + temp);
+ //gsReverbObject.m_sAp0.m_zApOut = pPreset->m_nAp0_ApOut;
+
+ pReverbData->m_sAp1.m_nApGain = pPreset->m_nAp1_ApGain;
+ //stored as time based, convert to absolute sample value
+ temp = pPreset->m_nAp1_ApOut;
+ /*lint -e{702} shift for performance */
+ temp = (temp * _OUTPUT_SAMPLE_RATE) >> 16;
+ pReverbData->m_sAp1.m_zApOut = (EAS_U16) (pReverbData->m_sAp1.m_zApIn + temp);
+ //gsReverbObject.m_sAp1.m_zApOut = pPreset->m_nAp1_ApOut;
+ ///code from the EAS DEMO Reverb
+ ////////////////////////////////
+
+ *pInstData = pReverbData;
+
+ return EAS_SUCCESS;
+
+} /* end InitializeReverb */
+
+
+
+/*----------------------------------------------------------------------------
+ * ReverbProcess()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Reverberate the requested number of samples (block based processing)
+ *
+ * Inputs:
+ * pInputBuffer - src buffer
+ * pOutputBuffer - dst buffer
+ * nNumSamplesToAdd - number of samples to write to buffer
+ *
+ * Outputs:
+ * number of samples actually written to buffer
+ *
+ * Side Effects:
+ * - samples are added to the presently free buffer
+ *
+ *----------------------------------------------------------------------------
+*/
+static void ReverbProcess(EAS_VOID_PTR pInstData, EAS_PCM *pSrc, EAS_PCM *pDst, EAS_I32 numSamples)
+{
+ S_REVERB_OBJECT *pReverbData;
+
+ pReverbData = (S_REVERB_OBJECT*) pInstData;
+
+ //if bypassed or the preset forces the signal to be completely dry
+ if (pReverbData->m_bBypass ||
+ (pReverbData->m_nWet == 0 && pReverbData->m_nDry == 32767))
+ {
+ if (pSrc != pDst)
+ EAS_HWMemCpy(pSrc, pDst, numSamples * NUM_OUTPUT_CHANNELS * (EAS_I32) sizeof(EAS_PCM));
+ return;
+ }
+
+ if (pReverbData->m_nNextRoom != pReverbData->m_nCurrentRoom)
+ {
+ ReverbUpdateRoom(pReverbData);
+ }
+
+ ReverbUpdateXfade(pReverbData, numSamples);
+
+ Reverb(pReverbData, numSamples, pDst, pSrc);
+
+ /* check if update counter needs to be reset */
+ if (pReverbData->m_nUpdateCounter >= REVERB_MODULO_UPDATE_PERIOD_IN_SAMPLES)
+ {
+ /* update interval has elapsed, so reset counter */
+ pReverbData->m_nUpdateCounter = 0;
+ } /* end if m_nUpdateCounter >= update interval */
+
+ /* increment update counter */
+ pReverbData->m_nUpdateCounter += (EAS_I16)numSamples;
+
+} /* end ComputeReverb */
+
+/*----------------------------------------------------------------------------
+ * ReverbUpdateXfade
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Update the xfade parameters as required
+ *
+ * Inputs:
+ * nNumSamplesToAdd - number of samples to write to buffer
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ * - xfade parameters will be changed
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT ReverbUpdateXfade(S_REVERB_OBJECT *pReverbData, EAS_INT nNumSamplesToAdd)
+{
+ EAS_U16 nOffset;
+ EAS_I16 tempCos;
+ EAS_I16 tempSin;
+
+ if (pReverbData->m_nXfadeCounter >= pReverbData->m_nXfadeInterval)
+ {
+ /* update interval has elapsed, so reset counter */
+ pReverbData->m_nXfadeCounter = 0;
+
+ // Pin the sin,cos values to min / max values to ensure that the
+ // modulated taps' coefs are zero (thus no clicks)
+ if (pReverbData->m_nPhaseIncrement > 0)
+ {
+ // if phase increment > 0, then sin -> 1, cos -> 0
+ pReverbData->m_nSin = 32767;
+ pReverbData->m_nCos = 0;
+
+ // reset the phase to match the sin, cos values
+ pReverbData->m_nPhase = 32767;
+
+ // modulate the cross taps because their tap coefs are zero
+ nOffset = ReverbCalculateNoise( pReverbData->m_nMaxExcursion, &pReverbData->m_nNoise );
+
+ pReverbData->m_zD1Cross =
+ DELAY1_OUT - pReverbData->m_nMaxExcursion + nOffset;
+
+ nOffset = ReverbCalculateNoise( pReverbData->m_nMaxExcursion, &pReverbData->m_nNoise );
+
+ pReverbData->m_zD0Cross =
+ DELAY0_OUT - pReverbData->m_nMaxExcursion - nOffset;
+ }
+ else
+ {
+ // if phase increment < 0, then sin -> 0, cos -> 1
+ pReverbData->m_nSin = 0;
+ pReverbData->m_nCos = 32767;
+
+ // reset the phase to match the sin, cos values
+ pReverbData->m_nPhase = -32768;
+
+ // modulate the self taps because their tap coefs are zero
+ nOffset = ReverbCalculateNoise( pReverbData->m_nMaxExcursion, &pReverbData->m_nNoise );
+
+ pReverbData->m_zD0Self =
+ DELAY0_OUT - pReverbData->m_nMaxExcursion - nOffset;
+
+ nOffset = ReverbCalculateNoise( pReverbData->m_nMaxExcursion, &pReverbData->m_nNoise );
+
+ pReverbData->m_zD1Self =
+ DELAY1_OUT - pReverbData->m_nMaxExcursion + nOffset;
+
+ } // end if-else (pReverbData->m_nPhaseIncrement > 0)
+
+ // Reverse the direction of the sin,cos so that the
+ // tap whose coef was previously increasing now decreases
+ // and vice versa
+ pReverbData->m_nPhaseIncrement = -pReverbData->m_nPhaseIncrement;
+
+ } // end if counter >= update interval
+
+ //compute what phase will be next time
+ pReverbData->m_nPhase += pReverbData->m_nPhaseIncrement;
+
+ //calculate what the new sin and cos need to reach by the next update
+ ReverbCalculateSinCos(pReverbData->m_nPhase, &tempSin, &tempCos);
+
+ //calculate the per-sample increment required to get there by the next update
+ /*lint -e{702} shift for performance */
+ pReverbData->m_nSinIncrement =
+ (tempSin - pReverbData->m_nSin) >> REVERB_UPDATE_PERIOD_IN_BITS;
+
+ /*lint -e{702} shift for performance */
+ pReverbData->m_nCosIncrement =
+ (tempCos - pReverbData->m_nCos) >> REVERB_UPDATE_PERIOD_IN_BITS;
+
+
+ /* increment update counter */
+ pReverbData->m_nXfadeCounter += (EAS_U16) nNumSamplesToAdd;
+
+ return EAS_SUCCESS;
+
+} /* end ReverbUpdateXfade */
+
+
+/*----------------------------------------------------------------------------
+ * ReverbCalculateNoise
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Calculate a noise sample and limit its value
+ *
+ * Inputs:
+ * nMaxExcursion - noise value is limited to this value
+ * pnNoise - return new noise sample in this (not limited)
+ *
+ * Outputs:
+ * new limited noise value
+ *
+ * Side Effects:
+ * - *pnNoise noise value is updated
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_U16 ReverbCalculateNoise(EAS_U16 nMaxExcursion, EAS_I16 *pnNoise)
+{
+ // calculate new noise value
+ *pnNoise = (EAS_I16) (*pnNoise * 5 + 1);
+
+#if 0 // 1xxx, test
+ *pnNoise = 0;
+#endif // 1xxx, test
+
+ // return the limited noise value
+ return (nMaxExcursion & (*pnNoise));
+
+} /* end ReverbCalculateNoise */
+
+/*----------------------------------------------------------------------------
+ * ReverbCalculateSinCos
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Calculate a new sin and cosine value based on the given phase
+ *
+ * Inputs:
+ * nPhase - phase angle
+ * pnSin - input old value, output new value
+ * pnCos - input old value, output new value
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ * - *pnSin, *pnCos are updated
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT ReverbCalculateSinCos(EAS_I16 nPhase, EAS_I16 *pnSin, EAS_I16 *pnCos)
+{
+ EAS_I32 nTemp;
+ EAS_I32 nNetAngle;
+
+ // -1 <= nPhase < 1
+ // However, for the calculation, we need a value
+ // that ranges from -1/2 to +1/2, so divide the phase by 2
+ /*lint -e{702} shift for performance */
+ nNetAngle = nPhase >> 1;
+
+ /*
+ Implement the following
+ sin(x) = (2-4*c)*x^2 + c + x
+ cos(x) = (2-4*c)*x^2 + c - x
+
+ where c = 1/sqrt(2)
+ using the a0 + x*(a1 + x*a2) approach
+ */
+
+ /* limit the input "angle" to be between -0.5 and +0.5 */
+ if (nNetAngle > EG1_HALF)
+ {
+ nNetAngle = EG1_HALF;
+ }
+ else if (nNetAngle < EG1_MINUS_HALF)
+ {
+ nNetAngle = EG1_MINUS_HALF;
+ }
+
+ /* calculate sin */
+ nTemp = EG1_ONE + MULT_EG1_EG1(REVERB_PAN_G2, nNetAngle);
+ nTemp = REVERB_PAN_G0 + MULT_EG1_EG1(nTemp, nNetAngle);
+ *pnSin = (EAS_I16) SATURATE_EG1(nTemp);
+
+ /* calculate cos */
+ nTemp = -EG1_ONE + MULT_EG1_EG1(REVERB_PAN_G2, nNetAngle);
+ nTemp = REVERB_PAN_G0 + MULT_EG1_EG1(nTemp, nNetAngle);
+ *pnCos = (EAS_I16) SATURATE_EG1(nTemp);
+
+ return EAS_SUCCESS;
+} /* end ReverbCalculateSinCos */
+
+/*----------------------------------------------------------------------------
+ * Reverb
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * apply reverb to the given signal
+ *
+ * Inputs:
+ * nNu
+ * pnSin - input old value, output new value
+ * pnCos - input old value, output new value
+ *
+ * Outputs:
+ * number of samples actually reverberated
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT Reverb(S_REVERB_OBJECT *pReverbData, EAS_INT nNumSamplesToAdd, EAS_PCM *pOutputBuffer, EAS_PCM *pInputBuffer)
+{
+ EAS_I32 i;
+ EAS_I32 nDelayOut;
+ EAS_U16 nBase;
+
+ EAS_U32 nAddr;
+ EAS_I32 nTemp1;
+ EAS_I32 nTemp2;
+ EAS_I32 nApIn;
+ EAS_I32 nApOut;
+
+ EAS_I32 j;
+ EAS_I32 nEarlyOut;
+
+ EAS_I32 tempValue;
+
+
+ // get the base address
+ nBase = pReverbData->m_nBaseIndex;
+
+ for (i=0; i < nNumSamplesToAdd; i++)
+ {
+ // ********** Left Allpass - start
+ // left input = (left dry/4) + right feedback from previous period
+ /*lint -e{702} use shift for performance */
+ nApIn = ((*pInputBuffer++)>>2) + pReverbData->m_nRevOutFbkR;
+// nApIn = *pInputBuffer++; // 1xxx test and debug ap
+
+ // fetch allpass delay line out
+ //nAddr = CIRCULAR(nBase, psAp0->m_zApOut, REVERB_BUFFER_MASK);
+ nAddr = CIRCULAR(nBase, pReverbData->m_sAp0.m_zApOut, REVERB_BUFFER_MASK);
+ nDelayOut = pReverbData->m_nDelayLine[nAddr];
+
+ // calculate allpass feedforward; subtract the feedforward result
+ nTemp1 = MULT_EG1_EG1(nApIn, pReverbData->m_sAp0.m_nApGain);
+ nApOut = SATURATE(nDelayOut - nTemp1); // allpass output
+
+ // calculate allpass feedback; add the feedback result
+ nTemp1 = MULT_EG1_EG1(nApOut, pReverbData->m_sAp0.m_nApGain);
+ nTemp1 = SATURATE(nApIn + nTemp1);
+
+ // inject into allpass delay
+ nAddr = CIRCULAR(nBase, pReverbData->m_sAp0.m_zApIn, REVERB_BUFFER_MASK);
+ pReverbData->m_nDelayLine[nAddr] = (EAS_PCM) nTemp1;
+
+ // inject allpass output into delay line
+ nAddr = CIRCULAR(nBase, pReverbData->m_zD0In, REVERB_BUFFER_MASK);
+ pReverbData->m_nDelayLine[nAddr] = (EAS_PCM) nApOut;
+
+ // ********** Left Allpass - end
+
+ // ********** Right Allpass - start
+ // right input = (right dry/4) + left feedback from previous period
+ /*lint -e{702} use shift for performance */
+ nApIn = ((*pInputBuffer++)>>2) + pReverbData->m_nRevOutFbkL;
+// nApIn = *pInputBuffer++; // 1xxx test and debug ap
+
+ // fetch allpass delay line out
+ nAddr = CIRCULAR(nBase, pReverbData->m_sAp1.m_zApOut, REVERB_BUFFER_MASK);
+ nDelayOut = pReverbData->m_nDelayLine[nAddr];
+
+ // calculate allpass feedforward; subtract the feedforward result
+ nTemp1 = MULT_EG1_EG1(nApIn, pReverbData->m_sAp1.m_nApGain);
+ nApOut = SATURATE(nDelayOut - nTemp1); // allpass output
+
+ // calculate allpass feedback; add the feedback result
+ nTemp1 = MULT_EG1_EG1(nApOut, pReverbData->m_sAp1.m_nApGain);
+ nTemp1 = SATURATE(nApIn + nTemp1);
+
+ // inject into allpass delay
+ nAddr = CIRCULAR(nBase, pReverbData->m_sAp1.m_zApIn, REVERB_BUFFER_MASK);
+ pReverbData->m_nDelayLine[nAddr] = (EAS_PCM) nTemp1;
+
+ // inject allpass output into delay line
+ nAddr = CIRCULAR(nBase, pReverbData->m_zD1In, REVERB_BUFFER_MASK);
+ pReverbData->m_nDelayLine[nAddr] = (EAS_PCM) nApOut;
+
+ // ********** Right Allpass - end
+
+ // ********** D0 output - start
+ // fetch delay line self out
+ nAddr = CIRCULAR(nBase, pReverbData->m_zD0Self, REVERB_BUFFER_MASK);
+ nDelayOut = pReverbData->m_nDelayLine[nAddr];
+
+ // calculate delay line self out
+ nTemp1 = MULT_EG1_EG1(nDelayOut, pReverbData->m_nSin);
+
+ // fetch delay line cross out
+ nAddr = CIRCULAR(nBase, pReverbData->m_zD1Cross, REVERB_BUFFER_MASK);
+ nDelayOut = pReverbData->m_nDelayLine[nAddr];
+
+ // calculate delay line self out
+ nTemp2 = MULT_EG1_EG1(nDelayOut, pReverbData->m_nCos);
+
+ // calculate unfiltered delay out
+ nDelayOut = SATURATE(nTemp1 + nTemp2);
+
+ // calculate lowpass filter (mixer scale factor included in LPF feedforward)
+ nTemp1 = MULT_EG1_EG1(nDelayOut, pReverbData->m_nLpfFwd);
+
+ nTemp2 = MULT_EG1_EG1(pReverbData->m_zLpf0, pReverbData->m_nLpfFbk);
+
+ // calculate filtered delay out and simultaneously update LPF state variable
+ // filtered delay output is stored in m_zLpf0
+ pReverbData->m_zLpf0 = (EAS_PCM) SATURATE(nTemp1 + nTemp2);
+
+ // ********** D0 output - end
+
+ // ********** D1 output - start
+ // fetch delay line self out
+ nAddr = CIRCULAR(nBase, pReverbData->m_zD1Self, REVERB_BUFFER_MASK);
+ nDelayOut = pReverbData->m_nDelayLine[nAddr];
+
+ // calculate delay line self out
+ nTemp1 = MULT_EG1_EG1(nDelayOut, pReverbData->m_nSin);
+
+ // fetch delay line cross out
+ nAddr = CIRCULAR(nBase, pReverbData->m_zD0Cross, REVERB_BUFFER_MASK);
+ nDelayOut = pReverbData->m_nDelayLine[nAddr];
+
+ // calculate delay line self out
+ nTemp2 = MULT_EG1_EG1(nDelayOut, pReverbData->m_nCos);
+
+ // calculate unfiltered delay out
+ nDelayOut = SATURATE(nTemp1 + nTemp2);
+
+ // calculate lowpass filter (mixer scale factor included in LPF feedforward)
+ nTemp1 = MULT_EG1_EG1(nDelayOut, pReverbData->m_nLpfFwd);
+
+ nTemp2 = MULT_EG1_EG1(pReverbData->m_zLpf1, pReverbData->m_nLpfFbk);
+
+ // calculate filtered delay out and simultaneously update LPF state variable
+ // filtered delay output is stored in m_zLpf1
+ pReverbData->m_zLpf1 = (EAS_PCM)SATURATE(nTemp1 + nTemp2);
+
+ // ********** D1 output - end
+
+ // ********** mixer and feedback - start
+ // sum is fedback to right input (R + L)
+ pReverbData->m_nRevOutFbkL =
+ (EAS_PCM)SATURATE((EAS_I32)pReverbData->m_zLpf1 + (EAS_I32)pReverbData->m_zLpf0);
+
+ // difference is feedback to left input (R - L)
+ /*lint -e{685} lint complains that it can't saturate negative */
+ pReverbData->m_nRevOutFbkR =
+ (EAS_PCM)SATURATE((EAS_I32)pReverbData->m_zLpf1 - (EAS_I32)pReverbData->m_zLpf0);
+
+ // ********** mixer and feedback - end
+
+ // ********** start early reflection generator, left
+ //psEarly = &(pReverbData->m_sEarlyL);
+
+ nEarlyOut = 0;
+
+ for (j=0; j < REVERB_MAX_NUM_REFLECTIONS; j++)
+ {
+ // fetch delay line out
+ //nAddr = CIRCULAR(nBase, psEarly->m_zDelay[j], REVERB_BUFFER_MASK);
+ nAddr = CIRCULAR(nBase, pReverbData->m_sEarlyL.m_zDelay[j], REVERB_BUFFER_MASK);
+
+ nDelayOut = pReverbData->m_nDelayLine[nAddr];
+
+ // calculate reflection
+ //nTemp1 = MULT_EG1_EG1(nDelayOut, psEarly->m_nGain[j]);
+ nTemp1 = MULT_EG1_EG1(nDelayOut, pReverbData->m_sEarlyL.m_nGain[j]);
+
+ nEarlyOut = SATURATE(nEarlyOut + nTemp1);
+
+ } // end for (j=0; j < REVERB_MAX_NUM_REFLECTIONS; j++)
+
+ // apply lowpass to early reflections
+ //nTemp1 = MULT_EG1_EG1(nEarlyOut, psEarly->m_nLpfFwd);
+ nTemp1 = MULT_EG1_EG1(nEarlyOut, pReverbData->m_sEarlyL.m_nLpfFwd);
+
+ //nTemp2 = MULT_EG1_EG1(psEarly->m_zLpf, psEarly->m_nLpfFbk);
+ nTemp2 = MULT_EG1_EG1(pReverbData->m_sEarlyL.m_zLpf, pReverbData->m_sEarlyL.m_nLpfFbk);
+
+
+ // calculate filtered out and simultaneously update LPF state variable
+ // filtered output is stored in m_zLpf1
+ //psEarly->m_zLpf = SATURATE(nTemp1 + nTemp2);
+ pReverbData->m_sEarlyL.m_zLpf = (EAS_PCM) SATURATE(nTemp1 + nTemp2);
+
+ // combine filtered early and late reflections for output
+ //*pOutputBuffer++ = inL;
+ //tempValue = SATURATE(psEarly->m_zLpf + pReverbData->m_nRevOutFbkL);
+ tempValue = SATURATE((EAS_I32)pReverbData->m_sEarlyL.m_zLpf + (EAS_I32)pReverbData->m_nRevOutFbkL);
+ //scale reverb output by wet level
+ /*lint -e{701} use shift for performance */
+ tempValue = MULT_EG1_EG1(tempValue, (pReverbData->m_nWet<<1));
+ //sum with output buffer
+ tempValue += *pOutputBuffer;
+ *pOutputBuffer++ = (EAS_PCM)SATURATE(tempValue);
+
+ // ********** end early reflection generator, left
+
+ // ********** start early reflection generator, right
+ //psEarly = &(pReverbData->m_sEarlyR);
+
+ nEarlyOut = 0;
+
+ for (j=0; j < REVERB_MAX_NUM_REFLECTIONS; j++)
+ {
+ // fetch delay line out
+ nAddr = CIRCULAR(nBase, pReverbData->m_sEarlyR.m_zDelay[j], REVERB_BUFFER_MASK);
+ nDelayOut = pReverbData->m_nDelayLine[nAddr];
+
+ // calculate reflection
+ nTemp1 = MULT_EG1_EG1(nDelayOut, pReverbData->m_sEarlyR.m_nGain[j]);
+
+ nEarlyOut = SATURATE(nEarlyOut + nTemp1);
+
+ } // end for (j=0; j < REVERB_MAX_NUM_REFLECTIONS; j++)
+
+ // apply lowpass to early reflections
+ nTemp1 = MULT_EG1_EG1(nEarlyOut, pReverbData->m_sEarlyR.m_nLpfFwd);
+
+ nTemp2 = MULT_EG1_EG1(pReverbData->m_sEarlyR.m_zLpf, pReverbData->m_sEarlyR.m_nLpfFbk);
+
+ // calculate filtered out and simultaneously update LPF state variable
+ // filtered output is stored in m_zLpf1
+ pReverbData->m_sEarlyR.m_zLpf = (EAS_PCM)SATURATE(nTemp1 + nTemp2);
+
+ // combine filtered early and late reflections for output
+ //*pOutputBuffer++ = inR;
+ tempValue = SATURATE((EAS_I32)pReverbData->m_sEarlyR.m_zLpf + (EAS_I32)pReverbData->m_nRevOutFbkR);
+ //scale reverb output by wet level
+ /*lint -e{701} use shift for performance */
+ tempValue = MULT_EG1_EG1(tempValue, (pReverbData->m_nWet << 1));
+ //sum with output buffer
+ tempValue = tempValue + *pOutputBuffer;
+ *pOutputBuffer++ = (EAS_PCM)SATURATE(tempValue);
+
+ // ********** end early reflection generator, right
+
+ // decrement base addr for next sample period
+ nBase--;
+
+ pReverbData->m_nSin += pReverbData->m_nSinIncrement;
+ pReverbData->m_nCos += pReverbData->m_nCosIncrement;
+
+ } // end for (i=0; i < nNumSamplesToAdd; i++)
+
+ // store the most up to date version
+ pReverbData->m_nBaseIndex = nBase;
+
+ return EAS_SUCCESS;
+} /* end Reverb */
+
+
+
+/*----------------------------------------------------------------------------
+ * ReverbShutdown()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Initializes the Reverb effect.
+ *
+ * Inputs:
+ * pInstData - handle to instance data
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT ReverbShutdown (EAS_DATA_HANDLE pEASData, EAS_VOID_PTR pInstData)
+{
+ /* check Configuration Module for static memory allocation */
+ if (!pEASData->staticMemoryModel)
+ EAS_HWFree(pEASData->hwInstData, pInstData);
+ return EAS_SUCCESS;
+} /* end ReverbShutdown */
+
+/*----------------------------------------------------------------------------
+ * ReverbGetParam()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Get a Reverb parameter
+ *
+ * Inputs:
+ * pInstData - handle to instance data
+ * param - parameter index
+ * *pValue - pointer to variable to hold retrieved value
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT ReverbGetParam (EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue)
+{
+ S_REVERB_OBJECT *p;
+
+ p = (S_REVERB_OBJECT*) pInstData;
+
+ switch (param)
+ {
+ case EAS_PARAM_REVERB_BYPASS:
+ *pValue = (EAS_I32) p->m_bBypass;
+ break;
+ case EAS_PARAM_REVERB_PRESET:
+ *pValue = (EAS_I8) p->m_nCurrentRoom;
+ break;
+ case EAS_PARAM_REVERB_WET:
+ *pValue = p->m_nWet;
+ break;
+ case EAS_PARAM_REVERB_DRY:
+ *pValue = p->m_nDry;
+ break;
+ default:
+ return EAS_ERROR_INVALID_PARAMETER;
+ }
+ return EAS_SUCCESS;
+} /* end ReverbGetParam */
+
+
+/*----------------------------------------------------------------------------
+ * ReverbSetParam()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Set a Reverb parameter
+ *
+ * Inputs:
+ * pInstData - handle to instance data
+ * param - parameter index
+ * *pValue - new paramter value
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT ReverbSetParam (EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value)
+{
+ S_REVERB_OBJECT *p;
+
+ p = (S_REVERB_OBJECT*) pInstData;
+
+ switch (param)
+ {
+ case EAS_PARAM_REVERB_BYPASS:
+ p->m_bBypass = (EAS_BOOL) value;
+ break;
+ case EAS_PARAM_REVERB_PRESET:
+ if(value!=EAS_PARAM_REVERB_LARGE_HALL && value!=EAS_PARAM_REVERB_HALL &&
+ value!=EAS_PARAM_REVERB_CHAMBER && value!=EAS_PARAM_REVERB_ROOM)
+ return EAS_ERROR_INVALID_PARAMETER;
+ p->m_nNextRoom = (EAS_I16)value;
+ break;
+ case EAS_PARAM_REVERB_WET:
+ if(value>EAS_REVERB_WET_MAX || value<EAS_REVERB_WET_MIN)
+ return EAS_ERROR_INVALID_PARAMETER;
+ p->m_nWet = (EAS_I16)value;
+ break;
+ case EAS_PARAM_REVERB_DRY:
+ if(value>EAS_REVERB_DRY_MAX || value<EAS_REVERB_DRY_MIN)
+ return EAS_ERROR_INVALID_PARAMETER;
+ p->m_nDry = (EAS_I16)value;
+ break;
+ default:
+ return EAS_ERROR_INVALID_PARAMETER;
+ }
+ return EAS_SUCCESS;
+} /* end ReverbSetParam */
+
+
+/*----------------------------------------------------------------------------
+ * ReverbUpdateRoom
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Update the room's preset parameters as required
+ *
+ * Inputs:
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ * - reverb paramters (fbk, fwd, etc) will be changed
+ * - m_nCurrentRoom := m_nNextRoom
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT ReverbUpdateRoom(S_REVERB_OBJECT *pReverbData)
+{
+ EAS_INT temp;
+
+ S_REVERB_PRESET *pPreset = &pReverbData->m_sPreset.m_sPreset[pReverbData->m_nNextRoom];
+
+ pReverbData->m_nLpfFwd = pPreset->m_nLpfFwd;
+ pReverbData->m_nLpfFbk = pPreset->m_nLpfFbk;
+
+ pReverbData->m_nEarly = pPreset->m_nEarly;
+ pReverbData->m_nWet = pPreset->m_nWet;
+ pReverbData->m_nDry = pPreset->m_nDry;
+
+
+ pReverbData->m_nMaxExcursion = pPreset->m_nMaxExcursion;
+ //stored as time based, convert to sample based
+ temp = pPreset->m_nXfadeInterval;
+ /*lint -e{702} shift for performance */
+ temp = (temp * _OUTPUT_SAMPLE_RATE) >> 16;
+ pReverbData->m_nXfadeInterval = (EAS_U16) temp;
+ //gpsReverbObject->m_nXfadeInterval = pPreset->m_nXfadeInterval;
+ pReverbData->m_sAp0.m_nApGain = pPreset->m_nAp0_ApGain;
+ //stored as time based, convert to absolute sample value
+ temp = pPreset->m_nAp0_ApOut;
+ /*lint -e{702} shift for performance */
+ temp = (temp * _OUTPUT_SAMPLE_RATE) >> 16;
+ pReverbData->m_sAp0.m_zApOut = (EAS_U16) (pReverbData->m_sAp0.m_zApIn + temp);
+ //gpsReverbObject->m_sAp0.m_zApOut = pPreset->m_nAp0_ApOut;
+ pReverbData->m_sAp1.m_nApGain = pPreset->m_nAp1_ApGain;
+ //stored as time based, convert to absolute sample value
+ temp = pPreset->m_nAp1_ApOut;
+ /*lint -e{702} shift for performance */
+ temp = (temp * _OUTPUT_SAMPLE_RATE) >> 16;
+ pReverbData->m_sAp1.m_zApOut = (EAS_U16) (pReverbData->m_sAp1.m_zApIn + temp);
+ //gpsReverbObject->m_sAp1.m_zApOut = pPreset->m_nAp1_ApOut;
+
+ pReverbData->m_nCurrentRoom = pReverbData->m_nNextRoom;
+
+ return EAS_SUCCESS;
+
+} /* end ReverbUpdateRoom */
+
+
+/*----------------------------------------------------------------------------
+ * ReverbReadInPresets()
+ *----------------------------------------------------------------------------
+ * Purpose: sets global reverb preset bank to defaults
+ *
+ * Inputs:
+ *
+ * Outputs:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT ReverbReadInPresets(S_REVERB_OBJECT *pReverbData)
+{
+
+ int preset = 0;
+ int defaultPreset = 0;
+
+ //now init any remaining presets to defaults
+ for (defaultPreset = preset; defaultPreset < REVERB_MAX_ROOM_TYPE; defaultPreset++)
+ {
+ S_REVERB_PRESET *pPreset = &pReverbData->m_sPreset.m_sPreset[defaultPreset];
+ if (defaultPreset == 0 || defaultPreset > REVERB_MAX_ROOM_TYPE-1)
+ {
+ pPreset->m_nLpfFbk = 8307;
+ pPreset->m_nLpfFwd = 14768;
+ pPreset->m_nEarly = 0;
+ pPreset->m_nWet = 27690;
+ pPreset->m_nDry = 32767;
+ pPreset->m_nEarlyL_LpfFbk = 3692;
+ pPreset->m_nEarlyL_LpfFwd = 29075;
+ pPreset->m_nEarlyL_Delay0 = 922;
+ pPreset->m_nEarlyL_Gain0 = 22152;
+ pPreset->m_nEarlyL_Delay1 = 1462;
+ pPreset->m_nEarlyL_Gain1 = 17537;
+ pPreset->m_nEarlyL_Delay2 = 0;
+ pPreset->m_nEarlyL_Gain2 = 14768;
+ pPreset->m_nEarlyL_Delay3 = 1221;
+ pPreset->m_nEarlyL_Gain3 = 14307;
+ pPreset->m_nEarlyL_Delay4 = 0;
+ pPreset->m_nEarlyL_Gain4 = 13384;
+ pPreset->m_nEarlyR_Delay0 = 502;
+ pPreset->m_nEarlyR_Gain0 = 20306;
+ pPreset->m_nEarlyR_Delay1 = 1762;
+ pPreset->m_nEarlyR_Gain1 = 17537;
+ pPreset->m_nEarlyR_Delay2 = 0;
+ pPreset->m_nEarlyR_Gain2 = 14768;
+ pPreset->m_nEarlyR_Delay3 = 0;
+ pPreset->m_nEarlyR_Gain3 = 16153;
+ pPreset->m_nEarlyR_Delay4 = 0;
+ pPreset->m_nEarlyR_Gain4 = 13384;
+ pPreset->m_nMaxExcursion = 127;
+ pPreset->m_nXfadeInterval = 6388;
+ pPreset->m_nAp0_ApGain = 15691;
+ pPreset->m_nAp0_ApOut = 711;
+ pPreset->m_nAp1_ApGain = 17999;
+ pPreset->m_nAp1_ApOut = 1113;
+ pPreset->m_rfu4 = 0;
+ pPreset->m_rfu5 = 0;
+ pPreset->m_rfu6 = 0;
+ pPreset->m_rfu7 = 0;
+ pPreset->m_rfu8 = 0;
+ pPreset->m_rfu9 = 0;
+ pPreset->m_rfu10 = 0;
+ }
+ else if (defaultPreset == 1)
+ {
+ pPreset->m_nLpfFbk = 6461;
+ pPreset->m_nLpfFwd = 14307;
+ pPreset->m_nEarly = 0;
+ pPreset->m_nWet = 27690;
+ pPreset->m_nDry = 32767;
+ pPreset->m_nEarlyL_LpfFbk = 3692;
+ pPreset->m_nEarlyL_LpfFwd = 29075;
+ pPreset->m_nEarlyL_Delay0 = 922;
+ pPreset->m_nEarlyL_Gain0 = 22152;
+ pPreset->m_nEarlyL_Delay1 = 1462;
+ pPreset->m_nEarlyL_Gain1 = 17537;
+ pPreset->m_nEarlyL_Delay2 = 0;
+ pPreset->m_nEarlyL_Gain2 = 14768;
+ pPreset->m_nEarlyL_Delay3 = 1221;
+ pPreset->m_nEarlyL_Gain3 = 14307;
+ pPreset->m_nEarlyL_Delay4 = 0;
+ pPreset->m_nEarlyL_Gain4 = 13384;
+ pPreset->m_nEarlyR_Delay0 = 502;
+ pPreset->m_nEarlyR_Gain0 = 20306;
+ pPreset->m_nEarlyR_Delay1 = 1762;
+ pPreset->m_nEarlyR_Gain1 = 17537;
+ pPreset->m_nEarlyR_Delay2 = 0;
+ pPreset->m_nEarlyR_Gain2 = 14768;
+ pPreset->m_nEarlyR_Delay3 = 0;
+ pPreset->m_nEarlyR_Gain3 = 16153;
+ pPreset->m_nEarlyR_Delay4 = 0;
+ pPreset->m_nEarlyR_Gain4 = 13384;
+ pPreset->m_nMaxExcursion = 127;
+ pPreset->m_nXfadeInterval = 6391;
+ pPreset->m_nAp0_ApGain = 15230;
+ pPreset->m_nAp0_ApOut = 708;
+ pPreset->m_nAp1_ApGain = 9692;
+ pPreset->m_nAp1_ApOut = 1113;
+ pPreset->m_rfu4 = 0;
+ pPreset->m_rfu5 = 0;
+ pPreset->m_rfu6 = 0;
+ pPreset->m_rfu7 = 0;
+ pPreset->m_rfu8 = 0;
+ pPreset->m_rfu9 = 0;
+ pPreset->m_rfu10 = 0;
+ }
+ else if (defaultPreset == 2)
+ {
+ pPreset->m_nLpfFbk = 5077;
+ pPreset->m_nLpfFwd = 12922;
+ pPreset->m_nEarly = 0;
+ pPreset->m_nWet = 24460;
+ pPreset->m_nDry = 32767;
+ pPreset->m_nEarlyL_LpfFbk = 3692;
+ pPreset->m_nEarlyL_LpfFwd = 29075;
+ pPreset->m_nEarlyL_Delay0 = 922;
+ pPreset->m_nEarlyL_Gain0 = 22152;
+ pPreset->m_nEarlyL_Delay1 = 1462;
+ pPreset->m_nEarlyL_Gain1 = 17537;
+ pPreset->m_nEarlyL_Delay2 = 0;
+ pPreset->m_nEarlyL_Gain2 = 14768;
+ pPreset->m_nEarlyL_Delay3 = 1221;
+ pPreset->m_nEarlyL_Gain3 = 14307;
+ pPreset->m_nEarlyL_Delay4 = 0;
+ pPreset->m_nEarlyL_Gain4 = 13384;
+ pPreset->m_nEarlyR_Delay0 = 502;
+ pPreset->m_nEarlyR_Gain0 = 20306;
+ pPreset->m_nEarlyR_Delay1 = 1762;
+ pPreset->m_nEarlyR_Gain1 = 17537;
+ pPreset->m_nEarlyR_Delay2 = 0;
+ pPreset->m_nEarlyR_Gain2 = 14768;
+ pPreset->m_nEarlyR_Delay3 = 0;
+ pPreset->m_nEarlyR_Gain3 = 16153;
+ pPreset->m_nEarlyR_Delay4 = 0;
+ pPreset->m_nEarlyR_Gain4 = 13384;
+ pPreset->m_nMaxExcursion = 127;
+ pPreset->m_nXfadeInterval = 6449;
+ pPreset->m_nAp0_ApGain = 15691;
+ pPreset->m_nAp0_ApOut = 774;
+ pPreset->m_nAp1_ApGain = 15691;
+ pPreset->m_nAp1_ApOut = 1113;
+ pPreset->m_rfu4 = 0;
+ pPreset->m_rfu5 = 0;
+ pPreset->m_rfu6 = 0;
+ pPreset->m_rfu7 = 0;
+ pPreset->m_rfu8 = 0;
+ pPreset->m_rfu9 = 0;
+ pPreset->m_rfu10 = 0;
+ }
+ else if (defaultPreset == 3)
+ {
+ pPreset->m_nLpfFbk = 5077;
+ pPreset->m_nLpfFwd = 11076;
+ pPreset->m_nEarly = 0;
+ pPreset->m_nWet = 23075;
+ pPreset->m_nDry = 32767;
+ pPreset->m_nEarlyL_LpfFbk = 3692;
+ pPreset->m_nEarlyL_LpfFwd = 29075;
+ pPreset->m_nEarlyL_Delay0 = 922;
+ pPreset->m_nEarlyL_Gain0 = 22152;
+ pPreset->m_nEarlyL_Delay1 = 1462;
+ pPreset->m_nEarlyL_Gain1 = 17537;
+ pPreset->m_nEarlyL_Delay2 = 0;
+ pPreset->m_nEarlyL_Gain2 = 14768;
+ pPreset->m_nEarlyL_Delay3 = 1221;
+ pPreset->m_nEarlyL_Gain3 = 14307;
+ pPreset->m_nEarlyL_Delay4 = 0;
+ pPreset->m_nEarlyL_Gain4 = 13384;
+ pPreset->m_nEarlyR_Delay0 = 502;
+ pPreset->m_nEarlyR_Gain0 = 20306;
+ pPreset->m_nEarlyR_Delay1 = 1762;
+ pPreset->m_nEarlyR_Gain1 = 17537;
+ pPreset->m_nEarlyR_Delay2 = 0;
+ pPreset->m_nEarlyR_Gain2 = 14768;
+ pPreset->m_nEarlyR_Delay3 = 0;
+ pPreset->m_nEarlyR_Gain3 = 16153;
+ pPreset->m_nEarlyR_Delay4 = 0;
+ pPreset->m_nEarlyR_Gain4 = 13384;
+ pPreset->m_nMaxExcursion = 127;
+ pPreset->m_nXfadeInterval = 6470; //6483;
+ pPreset->m_nAp0_ApGain = 14768;
+ pPreset->m_nAp0_ApOut = 792;
+ pPreset->m_nAp1_ApGain = 15783;
+ pPreset->m_nAp1_ApOut = 1113;
+ pPreset->m_rfu4 = 0;
+ pPreset->m_rfu5 = 0;
+ pPreset->m_rfu6 = 0;
+ pPreset->m_rfu7 = 0;
+ pPreset->m_rfu8 = 0;
+ pPreset->m_rfu9 = 0;
+ pPreset->m_rfu10 = 0;
+
+ }
+ }
+
+ return EAS_SUCCESS;
+}
diff --git a/arm-fm-22k/lib_src/eas_reverbdata.c b/arm-fm-22k/lib_src/eas_reverbdata.c
index 5d48c1b..db34b48 100644
--- a/arm-fm-22k/lib_src/eas_reverbdata.c
+++ b/arm-fm-22k/lib_src/eas_reverbdata.c
@@ -1,13 +1,13 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_reverbdata.c
- *
- * Contents and purpose:
- * Contains the static data allocation for the Reverb effect
- *
- *
- * Copyright Sonic Network Inc. 2006
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_reverbdata.c
+ *
+ * Contents and purpose:
+ * Contains the static data allocation for the Reverb effect
+ *
+ *
+ * Copyright Sonic Network Inc. 2006
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,15 +20,15 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 550 $
- * $Date: 2007-02-02 09:37:03 -0800 (Fri, 02 Feb 2007) $
- *----------------------------------------------------------------------------
-*/
-
-#include "eas_reverbdata.h"
-
-S_REVERB_OBJECT eas_ReverbData;
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 550 $
+ * $Date: 2007-02-02 09:37:03 -0800 (Fri, 02 Feb 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+#include "eas_reverbdata.h"
+
+S_REVERB_OBJECT eas_ReverbData;
+
diff --git a/arm-fm-22k/lib_src/eas_reverbdata.h b/arm-fm-22k/lib_src/eas_reverbdata.h
index ef424da..926ea2e 100644
--- a/arm-fm-22k/lib_src/eas_reverbdata.h
+++ b/arm-fm-22k/lib_src/eas_reverbdata.h
@@ -1,13 +1,13 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_reverbdata.h
- *
- * Contents and purpose:
- * Contains the prototypes for the Reverb effect.
- *
- *
- * Copyright Sonic Network Inc. 2006
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_reverbdata.h
+ *
+ * Contents and purpose:
+ * Contains the prototypes for the Reverb effect.
+ *
+ *
+ * Copyright Sonic Network Inc. 2006
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,467 +20,467 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 499 $
- * $Date: 2006-12-11 16:07:20 -0800 (Mon, 11 Dec 2006) $
- *----------------------------------------------------------------------------
-*/
-
-#ifndef _EAS_REVERBDATA_H
-#define _EAS_REVERBDATA_H
-
-#include "eas_types.h"
-#include "eas_audioconst.h"
-
-/*------------------------------------
- * defines
- *------------------------------------
-*/
-
-/*
-CIRCULAR() calculates the array index using modulo arithmetic.
-The "trick" is that modulo arithmetic is simplified by masking
-the effective address where the mask is (2^n)-1. This only works
-if the buffer size is a power of two.
-*/
-#define CIRCULAR(base,offset,size) (EAS_U32)( \
- ( \
- ((EAS_I32)(base)) + ((EAS_I32)(offset)) \
- ) \
- & size \
- )
-
-/* reverb parameters are updated every 2^(REVERB_UPDATE_PERIOD_IN_BITS) samples */
-#if defined (_SAMPLE_RATE_8000)
-
-#define REVERB_UPDATE_PERIOD_IN_BITS 5
-#define REVERB_BUFFER_SIZE_IN_SAMPLES 2048
-
-#elif defined (_SAMPLE_RATE_16000)
-
-#define REVERB_UPDATE_PERIOD_IN_BITS 6
-#define REVERB_BUFFER_SIZE_IN_SAMPLES 4096
-
-#elif defined (_SAMPLE_RATE_22050)
-
-#define REVERB_UPDATE_PERIOD_IN_BITS 7
-#define REVERB_BUFFER_SIZE_IN_SAMPLES 4096
-
-#elif defined (_SAMPLE_RATE_32000)
-
-#define REVERB_UPDATE_PERIOD_IN_BITS 7
-#define REVERB_BUFFER_SIZE_IN_SAMPLES 8192
-
-#elif defined (_SAMPLE_RATE_44100)
-
-#define REVERB_UPDATE_PERIOD_IN_BITS 8
-#define REVERB_BUFFER_SIZE_IN_SAMPLES 8192
-
-#elif defined (_SAMPLE_RATE_48000)
-
-#define REVERB_UPDATE_PERIOD_IN_BITS 8
-#define REVERB_BUFFER_SIZE_IN_SAMPLES 8192
-
-#endif
-
-// Define a mask for circular addressing, so that array index
-// can wraparound and stay in array boundary of 0, 1, ..., (buffer size -1)
-// The buffer size MUST be a power of two
-#define REVERB_BUFFER_MASK (REVERB_BUFFER_SIZE_IN_SAMPLES -1)
-
-#define REVERB_MAX_ROOM_TYPE 4 // any room numbers larger than this are invalid
-#define REVERB_MAX_NUM_REFLECTIONS 5 // max num reflections per channel
-
-/* synth parameters are updated every SYNTH_UPDATE_PERIOD_IN_SAMPLES */
-#define REVERB_UPDATE_PERIOD_IN_SAMPLES (EAS_I32)(0x1L << REVERB_UPDATE_PERIOD_IN_BITS)
-
-/*
-calculate the update counter by bitwise ANDING with this value to
-generate a 2^n modulo value
-*/
-#define REVERB_MODULO_UPDATE_PERIOD_IN_SAMPLES (EAS_I32)(REVERB_UPDATE_PERIOD_IN_SAMPLES -1)
-
-/* synth parameters are updated every SYNTH_UPDATE_PERIOD_IN_SECONDS seconds */
-#define REVERB_UPDATE_PERIOD_IN_SECONDS (REVERB_UPDATE_PERIOD_IN_SAMPLES / _OUTPUT_SAMPLE_RATE)
-
-// xfade parameters
-#define REVERB_XFADE_PERIOD_IN_SECONDS (100.0 / 1000.0) // xfade once every this many seconds
-
-#define REVERB_XFADE_PERIOD_IN_SAMPLES (REVERB_XFADE_PERIOD_IN_SECONDS * _OUTPUT_SAMPLE_RATE)
-
-#define REVERB_XFADE_PHASE_INCREMENT (EAS_I16)(65536 / ((EAS_I16)REVERB_XFADE_PERIOD_IN_SAMPLES/(EAS_I16)REVERB_UPDATE_PERIOD_IN_SAMPLES))
-
-/**********/
-/* the entire synth uses various flags in a bit field */
-
-/* if flag is set, synth reset has been requested */
-#define REVERB_FLAG_RESET_IS_REQUESTED 0x01 /* bit 0 */
-#define MASK_REVERB_RESET_IS_REQUESTED 0x01
-#define MASK_REVERB_RESET_IS_NOT_REQUESTED (EAS_U32)(~MASK_REVERB_RESET_IS_REQUESTED)
-
-/*
-by default, we always want to update ALL channel parameters
-when we reset the synth (e.g., during GM ON)
-*/
-#define DEFAULT_REVERB_FLAGS 0x0
-
-/* coefficients for generating sin, cos */
-#define REVERB_PAN_G2 4294940151 /* -0.82842712474619 = 2 - 4/sqrt(2) */
-/*
-EAS_I32 nPanG1 = +1.0 for sin
-EAS_I32 nPanG1 = -1.0 for cos
-*/
-#define REVERB_PAN_G0 23170 /* 0.707106781186547 = 1/sqrt(2) */
-
-/*************************************************************/
-// define the input injection points
-#define GUARD 5 // safety guard of this many samples
-
-#define MAX_AP_TIME (double) (20.0/1000.0) // delay time in milliseconds
-#define MAX_DELAY_TIME (double) (65.0/1000.0) // delay time in milliseconds
-
-#define MAX_AP_SAMPLES (int)(((double) MAX_AP_TIME) * ((double) _OUTPUT_SAMPLE_RATE))
-#define MAX_DELAY_SAMPLES (int)(((double) MAX_DELAY_TIME) * ((double) _OUTPUT_SAMPLE_RATE))
-
-#define AP0_IN 0
-#define AP1_IN (AP0_IN + MAX_AP_SAMPLES + GUARD)
-#define DELAY0_IN (AP1_IN + MAX_AP_SAMPLES + GUARD)
-#define DELAY1_IN (DELAY0_IN + MAX_DELAY_SAMPLES + GUARD)
-
-// Define the max offsets for the end points of each section
-// i.e., we don't expect a given section's taps to go beyond
-// the following limits
-#define AP0_OUT (AP0_IN + MAX_AP_SAMPLES -1)
-#define AP1_OUT (AP1_IN + MAX_AP_SAMPLES -1)
-#define DELAY0_OUT (DELAY0_IN + MAX_DELAY_SAMPLES -1)
-#define DELAY1_OUT (DELAY1_IN + MAX_DELAY_SAMPLES -1)
-
-#define REVERB_DEFAULT_ROOM_NUMBER 1 // default preset number
-#define DEFAULT_AP0_LENGTH (int)(((double) (17.0/1000.0)) * ((double) _OUTPUT_SAMPLE_RATE))
-#define DEFAULT_AP0_GAIN 19400
-#define DEFAULT_AP1_LENGTH (int)(((double) (16.5/1000.0)) * ((double) _OUTPUT_SAMPLE_RATE))
-#define DEFAULT_AP1_GAIN -19400
-
-#define REVERB_DEFAULT_WET 32767
-#define REVERB_DEFAULT_DRY 0
-
-#define EAS_REVERB_WET_MAX 32767
-#define EAS_REVERB_WET_MIN 0
-#define EAS_REVERB_DRY_MAX 32767
-#define EAS_REVERB_DRY_MIN 0
-
-/* parameters for each allpass */
-typedef struct
-{
- EAS_U16 m_zApOut; // delay offset for ap out
-
- EAS_I16 m_nApGain; // gain for ap
-
- EAS_U16 m_zApIn; // delay offset for ap in
-
-} S_ALLPASS_OBJECT;
-
-
-/* parameters for each allpass */
-typedef struct
-{
- EAS_PCM m_zLpf; // actual state variable, not a length
-
- EAS_I16 m_nLpfFwd; // lpf forward gain
-
- EAS_I16 m_nLpfFbk; // lpf feedback gain
-
- EAS_U16 m_zDelay[REVERB_MAX_NUM_REFLECTIONS]; // delay offset for ap out
-
- EAS_I16 m_nGain[REVERB_MAX_NUM_REFLECTIONS]; // gain for ap
-
-} S_EARLY_REFLECTION_OBJECT;
-
-//demo
-typedef struct
-{
- EAS_I16 m_nLpfFbk;
- EAS_I16 m_nLpfFwd;
-
- EAS_I16 m_nEarly;
- EAS_I16 m_nWet;
- EAS_I16 m_nDry;
-
- EAS_I16 m_nEarlyL_LpfFbk;
- EAS_I16 m_nEarlyL_LpfFwd;
-
- EAS_I16 m_nEarlyL_Delay0; //8
- EAS_I16 m_nEarlyL_Gain0;
- EAS_I16 m_nEarlyL_Delay1;
- EAS_I16 m_nEarlyL_Gain1;
- EAS_I16 m_nEarlyL_Delay2;
- EAS_I16 m_nEarlyL_Gain2;
- EAS_I16 m_nEarlyL_Delay3;
- EAS_I16 m_nEarlyL_Gain3;
- EAS_I16 m_nEarlyL_Delay4;
- EAS_I16 m_nEarlyL_Gain4;
-
- EAS_I16 m_nEarlyR_Delay0; //18
- EAS_I16 m_nEarlyR_Gain0;
- EAS_I16 m_nEarlyR_Delay1;
- EAS_I16 m_nEarlyR_Gain1;
- EAS_I16 m_nEarlyR_Delay2;
- EAS_I16 m_nEarlyR_Gain2;
- EAS_I16 m_nEarlyR_Delay3;
- EAS_I16 m_nEarlyR_Gain3;
- EAS_I16 m_nEarlyR_Delay4;
- EAS_I16 m_nEarlyR_Gain4;
-
- EAS_U16 m_nMaxExcursion; //28
- EAS_I16 m_nXfadeInterval;
-
- EAS_I16 m_nAp0_ApGain; //30
- EAS_I16 m_nAp0_ApOut;
- EAS_I16 m_nAp1_ApGain;
- EAS_I16 m_nAp1_ApOut;
-
- EAS_I16 m_rfu4;
- EAS_I16 m_rfu5;
- EAS_I16 m_rfu6;
- EAS_I16 m_rfu7;
- EAS_I16 m_rfu8;
- EAS_I16 m_rfu9;
- EAS_I16 m_rfu10; //43
-
-} S_REVERB_PRESET;
-
-typedef struct
-{
- S_REVERB_PRESET m_sPreset[REVERB_MAX_ROOM_TYPE]; //array of presets
-
-} S_REVERB_PRESET_BANK;
-
-/* parameters for each reverb */
-typedef struct
-{
- /* controls entire reverb playback volume */
- /* to conserve memory, use the MSB and ignore the LSB */
- EAS_U8 m_nMasterVolume;
-
- /* update counter keeps track of when synth params need updating */
- /* only needs to be as large as REVERB_UPDATE_PERIOD_IN_SAMPLES */
- EAS_I16 m_nUpdateCounter;
-
- EAS_U16 m_nMinSamplesToAdd; /* ComputeReverb() generates this many samples */
-
- EAS_U8 m_nFlags; /* misc flags/bit fields */
-
- EAS_PCM *m_pOutputBuffer;
- EAS_PCM *m_pInputBuffer;
-
- EAS_U16 m_nNumSamplesInOutputBuffer;
- EAS_U16 m_nNumSamplesInInputBuffer;
-
- EAS_U16 m_nNumInputSamplesRead; // if m_nNumInputSamplesRead >= NumSamplesInInputBuffer
- // then get a new input buffer
- EAS_PCM *m_pNextInputSample;
-
- EAS_U16 m_nBaseIndex; // base index for circular buffer
-
- // reverb delay line offsets, allpass parameters, etc:
-
- EAS_PCM m_nRevOutFbkR; // combine feedback reverb right out with dry left in
-
- S_ALLPASS_OBJECT m_sAp0; // allpass 0 (left channel)
-
- EAS_U16 m_zD0In; // delay offset for delay line D0 in
-
- EAS_PCM m_nRevOutFbkL; // combine feedback reverb left out with dry right in
-
- S_ALLPASS_OBJECT m_sAp1; // allpass 1 (right channel)
-
- EAS_U16 m_zD1In; // delay offset for delay line D1 in
-
- // delay output taps, notice criss cross order
- EAS_U16 m_zD0Self; // self feeds forward d0 --> d0
-
- EAS_U16 m_zD1Cross; // cross feeds across d1 --> d0
-
- EAS_PCM m_zLpf0; // actual state variable, not a length
-
- EAS_U16 m_zD1Self; // self feeds forward d1 --> d1
-
- EAS_U16 m_zD0Cross; // cross feeds across d0 --> d1
-
- EAS_PCM m_zLpf1; // actual state variable, not a length
-
- EAS_I16 m_nSin; // gain for self taps
-
- EAS_I16 m_nCos; // gain for cross taps
-
- EAS_I16 m_nSinIncrement; // increment for gain
-
- EAS_I16 m_nCosIncrement; // increment for gain
-
- EAS_I16 m_nLpfFwd; // lpf forward gain (includes scaling for mixer)
-
- EAS_I16 m_nLpfFbk; // lpf feedback gain
-
- EAS_U16 m_nXfadeInterval; // update/xfade after this many samples
-
- EAS_U16 m_nXfadeCounter; // keep track of when to xfade
-
- EAS_I16 m_nPhase; // -1 <= m_nPhase < 1
- // but during sin,cos calculations
- // use m_nPhase/2
-
- EAS_I16 m_nPhaseIncrement; // add this to m_nPhase each frame
-
- EAS_I16 m_nNoise; // random noise sample
-
- EAS_U16 m_nMaxExcursion; // the taps can excurse +/- this amount
-
- EAS_BOOL m_bUseNoise; // if EAS_TRUE, use noise as input signal
-
- EAS_BOOL m_bBypass; // if EAS_TRUE, then bypass reverb and copy input to output
-
- EAS_I16 m_nCurrentRoom; // preset number for current room
-
- EAS_I16 m_nNextRoom; // preset number for next room
-
- EAS_I16 m_nWet; // gain for wet (processed) signal
-
- EAS_I16 m_nDry; // gain for dry (unprocessed) signal
-
- EAS_I16 m_nEarly; // gain for early (widen) signal
-
- S_EARLY_REFLECTION_OBJECT m_sEarlyL; // left channel early reflections
- S_EARLY_REFLECTION_OBJECT m_sEarlyR; // right channel early reflections
-
- EAS_PCM m_nDelayLine[REVERB_BUFFER_SIZE_IN_SAMPLES]; // one large delay line for all reverb elements
-
- S_REVERB_PRESET pPreset;
-
- S_REVERB_PRESET_BANK m_sPreset;
-
- //EAS_I8 preset;
-
-} S_REVERB_OBJECT;
-
-
-/*------------------------------------
- * prototypes
- *------------------------------------
-*/
-
-/*----------------------------------------------------------------------------
- * ReverbUpdateXfade
- *----------------------------------------------------------------------------
- * Purpose:
- * Update the xfade parameters as required
- *
- * Inputs:
- * nNumSamplesToAdd - number of samples to write to buffer
- *
- * Outputs:
- *
- *
- * Side Effects:
- * - xfade parameters will be changed
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT ReverbUpdateXfade(S_REVERB_OBJECT* pReverbData, EAS_INT nNumSamplesToAdd);
-
-/*----------------------------------------------------------------------------
- * ReverbCalculateNoise
- *----------------------------------------------------------------------------
- * Purpose:
- * Calculate a noise sample and limit its value
- *
- * Inputs:
- * nMaxExcursion - noise value is limited to this value
- * pnNoise - return new noise sample in this (not limited)
- *
- * Outputs:
- * new limited noise value
- *
- * Side Effects:
- * - *pnNoise noise value is updated
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_U16 ReverbCalculateNoise(EAS_U16 nMaxExcursion, EAS_I16 *pnNoise);
-
-/*----------------------------------------------------------------------------
- * ReverbCalculateSinCos
- *----------------------------------------------------------------------------
- * Purpose:
- * Calculate a new sin and cosine value based on the given phase
- *
- * Inputs:
- * nPhase - phase angle
- * pnSin - input old value, output new value
- * pnCos - input old value, output new value
- *
- * Outputs:
- *
- * Side Effects:
- * - *pnSin, *pnCos are updated
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT ReverbCalculateSinCos(EAS_I16 nPhase, EAS_I16 *pnSin, EAS_I16 *pnCos);
-
-/*----------------------------------------------------------------------------
- * Reverb
- *----------------------------------------------------------------------------
- * Purpose:
- * apply reverb to the given signal
- *
- * Inputs:
- * nNu
- * pnSin - input old value, output new value
- * pnCos - input old value, output new value
- *
- * Outputs:
- * number of samples actually reverberated
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT Reverb(S_REVERB_OBJECT* pReverbData, EAS_INT nNumSamplesToAdd, EAS_PCM *pOutputBuffer, EAS_PCM *pInputBuffer);
-
-/*----------------------------------------------------------------------------
- * ReverbReadInPresets()
- *----------------------------------------------------------------------------
- * Purpose: sets global reverb preset bank to defaults
- *
- * Inputs:
- *
- * Outputs:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT ReverbReadInPresets(S_REVERB_OBJECT* pReverbData);
-
-
-/*----------------------------------------------------------------------------
- * ReverbUpdateRoom
- *----------------------------------------------------------------------------
- * Purpose:
- * Update the room's preset parameters as required
- *
- * Inputs:
- *
- * Outputs:
- *
- *
- * Side Effects:
- * - reverb paramters (fbk, fwd, etc) will be changed
- * - m_nCurrentRoom := m_nNextRoom
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT ReverbUpdateRoom(S_REVERB_OBJECT* pReverbData);
-
-#endif /* #ifndef _EAS_REVERBDATA_H */
-
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 499 $
+ * $Date: 2006-12-11 16:07:20 -0800 (Mon, 11 Dec 2006) $
+ *----------------------------------------------------------------------------
+*/
+
+#ifndef _EAS_REVERBDATA_H
+#define _EAS_REVERBDATA_H
+
+#include "eas_types.h"
+#include "eas_audioconst.h"
+
+/*------------------------------------
+ * defines
+ *------------------------------------
+*/
+
+/*
+CIRCULAR() calculates the array index using modulo arithmetic.
+The "trick" is that modulo arithmetic is simplified by masking
+the effective address where the mask is (2^n)-1. This only works
+if the buffer size is a power of two.
+*/
+#define CIRCULAR(base,offset,size) (EAS_U32)( \
+ ( \
+ ((EAS_I32)(base)) + ((EAS_I32)(offset)) \
+ ) \
+ & size \
+ )
+
+/* reverb parameters are updated every 2^(REVERB_UPDATE_PERIOD_IN_BITS) samples */
+#if defined (_SAMPLE_RATE_8000)
+
+#define REVERB_UPDATE_PERIOD_IN_BITS 5
+#define REVERB_BUFFER_SIZE_IN_SAMPLES 2048
+
+#elif defined (_SAMPLE_RATE_16000)
+
+#define REVERB_UPDATE_PERIOD_IN_BITS 6
+#define REVERB_BUFFER_SIZE_IN_SAMPLES 4096
+
+#elif defined (_SAMPLE_RATE_22050)
+
+#define REVERB_UPDATE_PERIOD_IN_BITS 7
+#define REVERB_BUFFER_SIZE_IN_SAMPLES 4096
+
+#elif defined (_SAMPLE_RATE_32000)
+
+#define REVERB_UPDATE_PERIOD_IN_BITS 7
+#define REVERB_BUFFER_SIZE_IN_SAMPLES 8192
+
+#elif defined (_SAMPLE_RATE_44100)
+
+#define REVERB_UPDATE_PERIOD_IN_BITS 8
+#define REVERB_BUFFER_SIZE_IN_SAMPLES 8192
+
+#elif defined (_SAMPLE_RATE_48000)
+
+#define REVERB_UPDATE_PERIOD_IN_BITS 8
+#define REVERB_BUFFER_SIZE_IN_SAMPLES 8192
+
+#endif
+
+// Define a mask for circular addressing, so that array index
+// can wraparound and stay in array boundary of 0, 1, ..., (buffer size -1)
+// The buffer size MUST be a power of two
+#define REVERB_BUFFER_MASK (REVERB_BUFFER_SIZE_IN_SAMPLES -1)
+
+#define REVERB_MAX_ROOM_TYPE 4 // any room numbers larger than this are invalid
+#define REVERB_MAX_NUM_REFLECTIONS 5 // max num reflections per channel
+
+/* synth parameters are updated every SYNTH_UPDATE_PERIOD_IN_SAMPLES */
+#define REVERB_UPDATE_PERIOD_IN_SAMPLES (EAS_I32)(0x1L << REVERB_UPDATE_PERIOD_IN_BITS)
+
+/*
+calculate the update counter by bitwise ANDING with this value to
+generate a 2^n modulo value
+*/
+#define REVERB_MODULO_UPDATE_PERIOD_IN_SAMPLES (EAS_I32)(REVERB_UPDATE_PERIOD_IN_SAMPLES -1)
+
+/* synth parameters are updated every SYNTH_UPDATE_PERIOD_IN_SECONDS seconds */
+#define REVERB_UPDATE_PERIOD_IN_SECONDS (REVERB_UPDATE_PERIOD_IN_SAMPLES / _OUTPUT_SAMPLE_RATE)
+
+// xfade parameters
+#define REVERB_XFADE_PERIOD_IN_SECONDS (100.0 / 1000.0) // xfade once every this many seconds
+
+#define REVERB_XFADE_PERIOD_IN_SAMPLES (REVERB_XFADE_PERIOD_IN_SECONDS * _OUTPUT_SAMPLE_RATE)
+
+#define REVERB_XFADE_PHASE_INCREMENT (EAS_I16)(65536 / ((EAS_I16)REVERB_XFADE_PERIOD_IN_SAMPLES/(EAS_I16)REVERB_UPDATE_PERIOD_IN_SAMPLES))
+
+/**********/
+/* the entire synth uses various flags in a bit field */
+
+/* if flag is set, synth reset has been requested */
+#define REVERB_FLAG_RESET_IS_REQUESTED 0x01 /* bit 0 */
+#define MASK_REVERB_RESET_IS_REQUESTED 0x01
+#define MASK_REVERB_RESET_IS_NOT_REQUESTED (EAS_U32)(~MASK_REVERB_RESET_IS_REQUESTED)
+
+/*
+by default, we always want to update ALL channel parameters
+when we reset the synth (e.g., during GM ON)
+*/
+#define DEFAULT_REVERB_FLAGS 0x0
+
+/* coefficients for generating sin, cos */
+#define REVERB_PAN_G2 4294940151 /* -0.82842712474619 = 2 - 4/sqrt(2) */
+/*
+EAS_I32 nPanG1 = +1.0 for sin
+EAS_I32 nPanG1 = -1.0 for cos
+*/
+#define REVERB_PAN_G0 23170 /* 0.707106781186547 = 1/sqrt(2) */
+
+/*************************************************************/
+// define the input injection points
+#define GUARD 5 // safety guard of this many samples
+
+#define MAX_AP_TIME (double) (20.0/1000.0) // delay time in milliseconds
+#define MAX_DELAY_TIME (double) (65.0/1000.0) // delay time in milliseconds
+
+#define MAX_AP_SAMPLES (int)(((double) MAX_AP_TIME) * ((double) _OUTPUT_SAMPLE_RATE))
+#define MAX_DELAY_SAMPLES (int)(((double) MAX_DELAY_TIME) * ((double) _OUTPUT_SAMPLE_RATE))
+
+#define AP0_IN 0
+#define AP1_IN (AP0_IN + MAX_AP_SAMPLES + GUARD)
+#define DELAY0_IN (AP1_IN + MAX_AP_SAMPLES + GUARD)
+#define DELAY1_IN (DELAY0_IN + MAX_DELAY_SAMPLES + GUARD)
+
+// Define the max offsets for the end points of each section
+// i.e., we don't expect a given section's taps to go beyond
+// the following limits
+#define AP0_OUT (AP0_IN + MAX_AP_SAMPLES -1)
+#define AP1_OUT (AP1_IN + MAX_AP_SAMPLES -1)
+#define DELAY0_OUT (DELAY0_IN + MAX_DELAY_SAMPLES -1)
+#define DELAY1_OUT (DELAY1_IN + MAX_DELAY_SAMPLES -1)
+
+#define REVERB_DEFAULT_ROOM_NUMBER 1 // default preset number
+#define DEFAULT_AP0_LENGTH (int)(((double) (17.0/1000.0)) * ((double) _OUTPUT_SAMPLE_RATE))
+#define DEFAULT_AP0_GAIN 19400
+#define DEFAULT_AP1_LENGTH (int)(((double) (16.5/1000.0)) * ((double) _OUTPUT_SAMPLE_RATE))
+#define DEFAULT_AP1_GAIN -19400
+
+#define REVERB_DEFAULT_WET 32767
+#define REVERB_DEFAULT_DRY 0
+
+#define EAS_REVERB_WET_MAX 32767
+#define EAS_REVERB_WET_MIN 0
+#define EAS_REVERB_DRY_MAX 32767
+#define EAS_REVERB_DRY_MIN 0
+
+/* parameters for each allpass */
+typedef struct
+{
+ EAS_U16 m_zApOut; // delay offset for ap out
+
+ EAS_I16 m_nApGain; // gain for ap
+
+ EAS_U16 m_zApIn; // delay offset for ap in
+
+} S_ALLPASS_OBJECT;
+
+
+/* parameters for each allpass */
+typedef struct
+{
+ EAS_PCM m_zLpf; // actual state variable, not a length
+
+ EAS_I16 m_nLpfFwd; // lpf forward gain
+
+ EAS_I16 m_nLpfFbk; // lpf feedback gain
+
+ EAS_U16 m_zDelay[REVERB_MAX_NUM_REFLECTIONS]; // delay offset for ap out
+
+ EAS_I16 m_nGain[REVERB_MAX_NUM_REFLECTIONS]; // gain for ap
+
+} S_EARLY_REFLECTION_OBJECT;
+
+//demo
+typedef struct
+{
+ EAS_I16 m_nLpfFbk;
+ EAS_I16 m_nLpfFwd;
+
+ EAS_I16 m_nEarly;
+ EAS_I16 m_nWet;
+ EAS_I16 m_nDry;
+
+ EAS_I16 m_nEarlyL_LpfFbk;
+ EAS_I16 m_nEarlyL_LpfFwd;
+
+ EAS_I16 m_nEarlyL_Delay0; //8
+ EAS_I16 m_nEarlyL_Gain0;
+ EAS_I16 m_nEarlyL_Delay1;
+ EAS_I16 m_nEarlyL_Gain1;
+ EAS_I16 m_nEarlyL_Delay2;
+ EAS_I16 m_nEarlyL_Gain2;
+ EAS_I16 m_nEarlyL_Delay3;
+ EAS_I16 m_nEarlyL_Gain3;
+ EAS_I16 m_nEarlyL_Delay4;
+ EAS_I16 m_nEarlyL_Gain4;
+
+ EAS_I16 m_nEarlyR_Delay0; //18
+ EAS_I16 m_nEarlyR_Gain0;
+ EAS_I16 m_nEarlyR_Delay1;
+ EAS_I16 m_nEarlyR_Gain1;
+ EAS_I16 m_nEarlyR_Delay2;
+ EAS_I16 m_nEarlyR_Gain2;
+ EAS_I16 m_nEarlyR_Delay3;
+ EAS_I16 m_nEarlyR_Gain3;
+ EAS_I16 m_nEarlyR_Delay4;
+ EAS_I16 m_nEarlyR_Gain4;
+
+ EAS_U16 m_nMaxExcursion; //28
+ EAS_I16 m_nXfadeInterval;
+
+ EAS_I16 m_nAp0_ApGain; //30
+ EAS_I16 m_nAp0_ApOut;
+ EAS_I16 m_nAp1_ApGain;
+ EAS_I16 m_nAp1_ApOut;
+
+ EAS_I16 m_rfu4;
+ EAS_I16 m_rfu5;
+ EAS_I16 m_rfu6;
+ EAS_I16 m_rfu7;
+ EAS_I16 m_rfu8;
+ EAS_I16 m_rfu9;
+ EAS_I16 m_rfu10; //43
+
+} S_REVERB_PRESET;
+
+typedef struct
+{
+ S_REVERB_PRESET m_sPreset[REVERB_MAX_ROOM_TYPE]; //array of presets
+
+} S_REVERB_PRESET_BANK;
+
+/* parameters for each reverb */
+typedef struct
+{
+ /* controls entire reverb playback volume */
+ /* to conserve memory, use the MSB and ignore the LSB */
+ EAS_U8 m_nMasterVolume;
+
+ /* update counter keeps track of when synth params need updating */
+ /* only needs to be as large as REVERB_UPDATE_PERIOD_IN_SAMPLES */
+ EAS_I16 m_nUpdateCounter;
+
+ EAS_U16 m_nMinSamplesToAdd; /* ComputeReverb() generates this many samples */
+
+ EAS_U8 m_nFlags; /* misc flags/bit fields */
+
+ EAS_PCM *m_pOutputBuffer;
+ EAS_PCM *m_pInputBuffer;
+
+ EAS_U16 m_nNumSamplesInOutputBuffer;
+ EAS_U16 m_nNumSamplesInInputBuffer;
+
+ EAS_U16 m_nNumInputSamplesRead; // if m_nNumInputSamplesRead >= NumSamplesInInputBuffer
+ // then get a new input buffer
+ EAS_PCM *m_pNextInputSample;
+
+ EAS_U16 m_nBaseIndex; // base index for circular buffer
+
+ // reverb delay line offsets, allpass parameters, etc:
+
+ EAS_PCM m_nRevOutFbkR; // combine feedback reverb right out with dry left in
+
+ S_ALLPASS_OBJECT m_sAp0; // allpass 0 (left channel)
+
+ EAS_U16 m_zD0In; // delay offset for delay line D0 in
+
+ EAS_PCM m_nRevOutFbkL; // combine feedback reverb left out with dry right in
+
+ S_ALLPASS_OBJECT m_sAp1; // allpass 1 (right channel)
+
+ EAS_U16 m_zD1In; // delay offset for delay line D1 in
+
+ // delay output taps, notice criss cross order
+ EAS_U16 m_zD0Self; // self feeds forward d0 --> d0
+
+ EAS_U16 m_zD1Cross; // cross feeds across d1 --> d0
+
+ EAS_PCM m_zLpf0; // actual state variable, not a length
+
+ EAS_U16 m_zD1Self; // self feeds forward d1 --> d1
+
+ EAS_U16 m_zD0Cross; // cross feeds across d0 --> d1
+
+ EAS_PCM m_zLpf1; // actual state variable, not a length
+
+ EAS_I16 m_nSin; // gain for self taps
+
+ EAS_I16 m_nCos; // gain for cross taps
+
+ EAS_I16 m_nSinIncrement; // increment for gain
+
+ EAS_I16 m_nCosIncrement; // increment for gain
+
+ EAS_I16 m_nLpfFwd; // lpf forward gain (includes scaling for mixer)
+
+ EAS_I16 m_nLpfFbk; // lpf feedback gain
+
+ EAS_U16 m_nXfadeInterval; // update/xfade after this many samples
+
+ EAS_U16 m_nXfadeCounter; // keep track of when to xfade
+
+ EAS_I16 m_nPhase; // -1 <= m_nPhase < 1
+ // but during sin,cos calculations
+ // use m_nPhase/2
+
+ EAS_I16 m_nPhaseIncrement; // add this to m_nPhase each frame
+
+ EAS_I16 m_nNoise; // random noise sample
+
+ EAS_U16 m_nMaxExcursion; // the taps can excurse +/- this amount
+
+ EAS_BOOL m_bUseNoise; // if EAS_TRUE, use noise as input signal
+
+ EAS_BOOL m_bBypass; // if EAS_TRUE, then bypass reverb and copy input to output
+
+ EAS_I16 m_nCurrentRoom; // preset number for current room
+
+ EAS_I16 m_nNextRoom; // preset number for next room
+
+ EAS_I16 m_nWet; // gain for wet (processed) signal
+
+ EAS_I16 m_nDry; // gain for dry (unprocessed) signal
+
+ EAS_I16 m_nEarly; // gain for early (widen) signal
+
+ S_EARLY_REFLECTION_OBJECT m_sEarlyL; // left channel early reflections
+ S_EARLY_REFLECTION_OBJECT m_sEarlyR; // right channel early reflections
+
+ EAS_PCM m_nDelayLine[REVERB_BUFFER_SIZE_IN_SAMPLES]; // one large delay line for all reverb elements
+
+ S_REVERB_PRESET pPreset;
+
+ S_REVERB_PRESET_BANK m_sPreset;
+
+ //EAS_I8 preset;
+
+} S_REVERB_OBJECT;
+
+
+/*------------------------------------
+ * prototypes
+ *------------------------------------
+*/
+
+/*----------------------------------------------------------------------------
+ * ReverbUpdateXfade
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Update the xfade parameters as required
+ *
+ * Inputs:
+ * nNumSamplesToAdd - number of samples to write to buffer
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ * - xfade parameters will be changed
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT ReverbUpdateXfade(S_REVERB_OBJECT* pReverbData, EAS_INT nNumSamplesToAdd);
+
+/*----------------------------------------------------------------------------
+ * ReverbCalculateNoise
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Calculate a noise sample and limit its value
+ *
+ * Inputs:
+ * nMaxExcursion - noise value is limited to this value
+ * pnNoise - return new noise sample in this (not limited)
+ *
+ * Outputs:
+ * new limited noise value
+ *
+ * Side Effects:
+ * - *pnNoise noise value is updated
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_U16 ReverbCalculateNoise(EAS_U16 nMaxExcursion, EAS_I16 *pnNoise);
+
+/*----------------------------------------------------------------------------
+ * ReverbCalculateSinCos
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Calculate a new sin and cosine value based on the given phase
+ *
+ * Inputs:
+ * nPhase - phase angle
+ * pnSin - input old value, output new value
+ * pnCos - input old value, output new value
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ * - *pnSin, *pnCos are updated
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT ReverbCalculateSinCos(EAS_I16 nPhase, EAS_I16 *pnSin, EAS_I16 *pnCos);
+
+/*----------------------------------------------------------------------------
+ * Reverb
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * apply reverb to the given signal
+ *
+ * Inputs:
+ * nNu
+ * pnSin - input old value, output new value
+ * pnCos - input old value, output new value
+ *
+ * Outputs:
+ * number of samples actually reverberated
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT Reverb(S_REVERB_OBJECT* pReverbData, EAS_INT nNumSamplesToAdd, EAS_PCM *pOutputBuffer, EAS_PCM *pInputBuffer);
+
+/*----------------------------------------------------------------------------
+ * ReverbReadInPresets()
+ *----------------------------------------------------------------------------
+ * Purpose: sets global reverb preset bank to defaults
+ *
+ * Inputs:
+ *
+ * Outputs:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT ReverbReadInPresets(S_REVERB_OBJECT* pReverbData);
+
+
+/*----------------------------------------------------------------------------
+ * ReverbUpdateRoom
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Update the room's preset parameters as required
+ *
+ * Inputs:
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ * - reverb paramters (fbk, fwd, etc) will be changed
+ * - m_nCurrentRoom := m_nNextRoom
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT ReverbUpdateRoom(S_REVERB_OBJECT* pReverbData);
+
+#endif /* #ifndef _EAS_REVERBDATA_H */
+
+
diff --git a/arm-fm-22k/lib_src/eas_rtttl.c b/arm-fm-22k/lib_src/eas_rtttl.c
index 486ad60..d8253fb 100644
--- a/arm-fm-22k/lib_src/eas_rtttl.c
+++ b/arm-fm-22k/lib_src/eas_rtttl.c
@@ -1,12 +1,12 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_rtttl.c
- *
- * Contents and purpose:
- * RTTTL parser
- *
- * Copyright Sonic Network Inc. 2005
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_rtttl.c
+ *
+ * Contents and purpose:
+ * RTTTL parser
+ *
+ * Copyright Sonic Network Inc. 2005
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,1179 +19,1179 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 795 $
- * $Date: 2007-08-01 00:14:45 -0700 (Wed, 01 Aug 2007) $
- *----------------------------------------------------------------------------
-*/
-
-#include "eas_data.h"
-#include "eas_miditypes.h"
-#include "eas_parser.h"
-#include "eas_report.h"
-#include "eas_host.h"
-#include "eas_midi.h"
-#include "eas_config.h"
-#include "eas_vm_protos.h"
-#include "eas_rtttldata.h"
-#include "eas_ctype.h"
-
-/* increase gain for mono ringtones */
-#define RTTTL_GAIN_OFFSET 8
-
-/* maximum title length including colon separator */
-#define RTTTL_MAX_TITLE_LEN 32
-#define RTTTL_INFINITE_LOOP 15
-
-/* length of 32nd note in 1/256ths of a msec for 63 BPM tempo */
-#define DEFAULT_TICK_CONV 30476
-#define TICK_CONVERT 1920000
-
-/* default channel and program for RTTTL playback */
-#define RTTTL_CHANNEL 0
-#define RTTTL_PROGRAM 80
-#define RTTTL_VELOCITY 127
-
-/* note used for rest */
-#define RTTTL_REST 1
-
-/* multiplier for fixed point triplet conversion */
-#define TRIPLET_MULTIPLIER 683
-#define TRIPLET_SHIFT 10
-
-/* local prototypes */
-static EAS_RESULT RTTTL_CheckFileType (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle, EAS_VOID_PTR *ppHandle, EAS_I32 offset);
-static EAS_RESULT RTTTL_Prepare (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
-static EAS_RESULT RTTTL_Time (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_U32 *pTime);
-static EAS_RESULT RTTTL_Event (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_INT parserMode);
-static EAS_RESULT RTTTL_State (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_STATE *pState);
-static EAS_RESULT RTTTL_Close (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
-static EAS_RESULT RTTTL_Reset (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
-static EAS_RESULT RTTTL_Pause (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
-static EAS_RESULT RTTTL_Resume (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
-static EAS_RESULT RTTTL_SetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value);
-static EAS_RESULT RTTTL_GetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue);
-static EAS_RESULT RTTTL_GetStyle (EAS_HW_DATA_HANDLE hwInstData, S_RTTTL_DATA *pData);
-static EAS_RESULT RTTTL_GetDuration (EAS_HW_DATA_HANDLE hwInstData, S_RTTTL_DATA *pData, EAS_I8 *pDuration);
-static EAS_RESULT RTTTL_GetOctave (EAS_HW_DATA_HANDLE hwInstData, S_RTTTL_DATA *pData, EAS_U8 *pOctave);
-static EAS_RESULT RTTTL_GetTempo (EAS_HW_DATA_HANDLE hwInstData, S_RTTTL_DATA *pData);
-static EAS_RESULT RTTTL_GetNumber (EAS_HW_DATA_HANDLE hwInstData, S_RTTTL_DATA *pData, EAS_I32 *pValue);
-static EAS_RESULT RTTTL_ParseHeader (S_EAS_DATA *pEASData, S_RTTTL_DATA* pData, EAS_BOOL metaData);
-static EAS_RESULT RTTTL_GetNextChar (EAS_HW_DATA_HANDLE hwInstData, S_RTTTL_DATA *pData, EAS_I8 *pValue);
-static EAS_RESULT RTTTL_PeekNextChar (EAS_HW_DATA_HANDLE hwInstData, S_RTTTL_DATA *pData, EAS_I8 *pValue);
-
-/* inline functions */
-EAS_INLINE void RTTTL_PutBackChar (S_RTTTL_DATA *pData, EAS_I8 value) { pData->dataByte = value; }
-
-
-/* lookup table for note values */
-static const EAS_U8 noteTable[] = { 21, 23, 12, 14, 16, 17, 19, 23 };
-
-/*----------------------------------------------------------------------------
- *
- * EAS_RTTTL_Parser
- *
- * This structure contains the functional interface for the iMelody parser
- *----------------------------------------------------------------------------
-*/
-const S_FILE_PARSER_INTERFACE EAS_RTTTL_Parser =
-{
- RTTTL_CheckFileType,
- RTTTL_Prepare,
- RTTTL_Time,
- RTTTL_Event,
- RTTTL_State,
- RTTTL_Close,
- RTTTL_Reset,
- RTTTL_Pause,
- RTTTL_Resume,
- NULL,
- RTTTL_SetData,
- RTTTL_GetData,
- NULL
-};
-
-/*----------------------------------------------------------------------------
- * RTTTL_CheckFileType()
- *----------------------------------------------------------------------------
- * Purpose:
- * Check the file type to see if we can parse it
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT RTTTL_CheckFileType (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle, EAS_VOID_PTR *ppHandle, EAS_I32 offset)
-{
- S_RTTTL_DATA data;
- S_RTTTL_DATA *pData;
-
- /* see if we can parse the header */
- data.fileHandle = fileHandle;
- data.fileOffset = offset;
- *ppHandle= NULL;
- if (RTTTL_ParseHeader (pEASData, &data, EAS_FALSE) == EAS_SUCCESS)
- {
-
- /* check for static memory allocation */
- if (pEASData->staticMemoryModel)
- pData = EAS_CMEnumData(EAS_CM_RTTTL_DATA);
- else
- pData = EAS_HWMalloc(pEASData->hwInstData, sizeof(S_RTTTL_DATA));
- if (!pData)
- return EAS_ERROR_MALLOC_FAILED;
- EAS_HWMemSet(pData, 0, sizeof(S_RTTTL_DATA));
-
- /* return a pointer to the instance data */
- pData->fileHandle = fileHandle;
- pData->fileOffset = offset;
- pData->state = EAS_STATE_OPEN;
- *ppHandle = pData;
- }
-
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * RTTTL_Prepare()
- *----------------------------------------------------------------------------
- * Purpose:
- * Prepare to parse the file. Allocates instance data (or uses static allocation for
- * static memory model).
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT RTTTL_Prepare (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
-{
- S_RTTTL_DATA* pData;
- EAS_RESULT result;
-
- /* check for valid state */
- pData = (S_RTTTL_DATA*) pInstData;
- if (pData->state != EAS_STATE_OPEN)
- return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
-
- /* instantiate a synthesizer */
- if ((result = VMInitMIDI(pEASData, &pData->pSynth)) != EAS_SUCCESS)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "VMInitMIDI returned %d\n", result); */ }
- return result;
- }
-
- pData->state = EAS_STATE_ERROR;
- if ((result = RTTTL_ParseHeader (pEASData, pData, (EAS_BOOL) (pData->metadata.callback != NULL))) != EAS_SUCCESS)
- {
- /* if using dynamic memory, free it */
- if (!pEASData->staticMemoryModel)
- EAS_HWFree(pEASData->hwInstData, pData);
- return result;
- }
-
- pData->state = EAS_STATE_READY;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * RTTTL_Time()
- *----------------------------------------------------------------------------
- * Purpose:
- * Returns the time of the next event in msecs
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- * pTime - pointer to variable to hold time of next event (in msecs)
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, pEASData) reserved for future use */
-static EAS_RESULT RTTTL_Time (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_U32 *pTime)
-{
- S_RTTTL_DATA *pData;
-
- pData = (S_RTTTL_DATA*) pInstData;
-
- /* return time in milliseconds */
- /*lint -e{704} use shift instead of division */
- *pTime = pData->time >> 8;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * RTTTL_Event()
- *----------------------------------------------------------------------------
- * Purpose:
- * Parse the next event in the file
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT RTTTL_Event (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_INT parserMode)
-{
- S_RTTTL_DATA* pData;
- EAS_RESULT result;
- EAS_I32 ticks;
- EAS_I32 temp;
- EAS_I8 c;
- EAS_U8 note;
- EAS_U8 octave;
-
- pData = (S_RTTTL_DATA*) pInstData;
- if (pData->state >= EAS_STATE_OPEN)
- return EAS_SUCCESS;
-
- /* initialize MIDI channel when the track starts playing */
- if (pData->time == 0)
- {
- /* set program to square lead */
- VMProgramChange(pEASData->pVoiceMgr, pData->pSynth, RTTTL_CHANNEL, RTTTL_PROGRAM);
-
- /* set channel volume to max */
- VMControlChange(pEASData->pVoiceMgr, pData->pSynth, RTTTL_CHANNEL, 7, 127);
- }
-
- /* check for end of note */
- if (pData->note)
- {
- /* stop the note */
- VMStopNote(pEASData->pVoiceMgr, pData->pSynth, RTTTL_CHANNEL, pData->note, 0);
- pData->note = 0;
-
- /* check for rest between notes */
- if (pData->restTicks)
- {
- pData->time += pData->restTicks;
- pData->restTicks = 0;
- return EAS_SUCCESS;
- }
- }
-
- /* parse the next event */
- octave = pData->octave;
- note = 0;
- ticks = pData->duration * pData->tick;
- for (;;)
- {
-
- /* get next character */
- if ((result = RTTTL_GetNextChar(pEASData->hwInstData, pData, &c)) != EAS_SUCCESS)
- {
- if (result != EAS_EOF)
- return result;
-
- /* end of file, if no notes to process, check for looping */
- if (!note)
- {
- /* if no loop set state to stopping */
- if (pData->repeatCount == 0)
- {
- pData->state = EAS_STATE_STOPPING;
- VMReleaseAllVoices(pEASData->pVoiceMgr, pData->pSynth);
- return EAS_SUCCESS;
- }
-
- /* decrement loop count */
- if (pData->repeatCount != RTTTL_INFINITE_LOOP)
- pData->repeatCount--;
-
- /* if locating, ignore infinite loops */
- else if (parserMode != eParserModePlay)
- {
- pData->state = EAS_STATE_STOPPING;
- VMReleaseAllVoices(pEASData->pVoiceMgr, pData->pSynth);
- return EAS_SUCCESS;
- }
-
- /* loop back to start of notes */
- if ((result = EAS_HWFileSeek(pEASData->hwInstData, pData->fileHandle, pData->repeatOffset)) != EAS_SUCCESS)
- return result;
- continue;
- }
-
- /* still have a note to process */
- else
- c = ',';
- }
-
- /* bpm */
- if (c == 'b')
- {
- /* peek at next character */
- if ((result = RTTTL_PeekNextChar(pEASData->hwInstData, pData, &c)) != EAS_SUCCESS)
- return result;
-
- /* if a number, must be octave or tempo */
- if (IsDigit(c))
- {
- if ((result = RTTTL_GetNumber(pEASData->hwInstData, pData, &temp)) != EAS_SUCCESS)
- return result;
-
- /* check for octave first */
- if ((temp >= 4) && (temp <= 7))
- {
- octave = (EAS_U8) temp;
- }
-
- /* check for tempo */
- else if ((temp >= 25) && (temp <= 900))
- {
- pData->tick = TICK_CONVERT / (EAS_U32) temp;
- }
-
- /* don't know what it was */
- else
- return EAS_ERROR_FILE_FORMAT;
- }
-
- /* must be a note */
- else
- {
- note = noteTable[1];
- }
- }
-
- /* octave */
- else if (c == 'o')
- {
- if ((result = RTTTL_GetOctave(pEASData->hwInstData, pData, &pData->octave)) != EAS_SUCCESS)
- return result;
- }
-
- /* style */
- else if (c == 's')
- {
- if ((result = RTTTL_GetStyle(pEASData->hwInstData, pData)) != EAS_SUCCESS)
- return result;
- }
-
- /* duration or octave */
- else if (IsDigit(c))
- {
- RTTTL_PutBackChar(pData, c);
-
- /* duration comes before note */
- if (!note)
- {
- if ((result = RTTTL_GetDuration(pEASData->hwInstData, pData, &c)) != EAS_SUCCESS)
- return result;
- ticks = c * pData->tick;
- }
-
- /* octave comes after note */
- else
- {
- if ((result = RTTTL_GetOctave(pEASData->hwInstData, pData, &octave)) != EAS_SUCCESS)
- return result;
- }
- }
-
- /* note or rest */
- else if ((c >= 'a') && (c <= 'h'))
- {
- note = noteTable[c - 'a'];
- }
-
- else if (c == 'p')
- {
- note = RTTTL_REST;
- }
-
- /* dotted note */
- else if (c == '.')
- {
- /*lint -e{704} shift for performance */
- ticks += ticks >> 1;
- }
-
- /* accidental */
- else if (c == '#')
- {
- if (note)
- note++;
- }
-
- /* end of event */
- else if ((c == ',') && note)
- {
-
- /* handle note events */
- if (note != RTTTL_REST)
- {
-
- /* save note and start it */
- pData->note = note + octave;
- if (parserMode == eParserModePlay)
- VMStartNote(pEASData->pVoiceMgr, pData->pSynth, RTTTL_CHANNEL, pData->note, RTTTL_VELOCITY);
-
- /* determine note length */
- switch (pData->style)
- {
- /* natural */
- case 'n':
- /*lint -e{704} shift for performance */
- pData->restTicks = ticks >> 4;
- break;
- /* continuous */
-
- case 'c':
- pData->restTicks = 0;
- break;
-
- /* staccato */
- case 's':
- /*lint -e{704} shift for performance */
- pData->restTicks = ticks >> 1;
- break;
-
- default:
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "RTTTL_Event: Unexpected style type %c\n", pData->style); */ }
- break;
- }
-
- /* next event is at end of this note */
- pData->time += ticks - pData->restTicks;
- }
-
- /* rest */
- else
- pData->time += ticks;
-
- /* event found, return to caller */
- break;
- }
- }
-
- pData->state = EAS_STATE_PLAY;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * RTTTL_State()
- *----------------------------------------------------------------------------
- * Purpose:
- * Returns the current state of the stream
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- * pState - pointer to variable to store state
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, pEASData) reserved for future use */
-static EAS_RESULT RTTTL_State (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 *pState)
-{
- S_RTTTL_DATA* pData;
-
- /* establish pointer to instance data */
- pData = (S_RTTTL_DATA*) pInstData;
-
- /* if stopping, check to see if synth voices are active */
- if (pData->state == EAS_STATE_STOPPING)
- {
- if (VMActiveVoices(pData->pSynth) == 0)
- pData->state = EAS_STATE_STOPPED;
- }
-
- if (pData->state == EAS_STATE_PAUSING)
- {
- if (VMActiveVoices(pData->pSynth) == 0)
- pData->state = EAS_STATE_PAUSED;
- }
-
- /* return current state */
- *pState = pData->state;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * RTTTL_Close()
- *----------------------------------------------------------------------------
- * Purpose:
- * Close the file and clean up
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT RTTTL_Close (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
-{
- S_RTTTL_DATA* pData;
- EAS_RESULT result;
-
- pData = (S_RTTTL_DATA*) pInstData;
-
- /* close the file */
- if ((result = EAS_HWCloseFile(pEASData->hwInstData, pData->fileHandle)) != EAS_SUCCESS)
- return result;
-
- /* free the synth */
- if (pData->pSynth != NULL)
- VMMIDIShutdown(pEASData, pData->pSynth);
-
- /* if using dynamic memory, free it */
- if (!pEASData->staticMemoryModel)
- EAS_HWFree(pEASData->hwInstData, pData);
-
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * RTTTL_Reset()
- *----------------------------------------------------------------------------
- * Purpose:
- * Reset the sequencer. Used for locating backwards in the file.
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT RTTTL_Reset (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
-{
- S_RTTTL_DATA* pData;
- EAS_RESULT result;
-
- pData = (S_RTTTL_DATA*) pInstData;
-
- /* reset the synth */
- VMReset(pEASData->pVoiceMgr, pData->pSynth, EAS_TRUE);
-
- /* reset time to zero */
- pData->time = 0;
- pData->note = 0;
-
- /* reset file position and re-parse header */
- pData->state = EAS_STATE_ERROR;
- if ((result = EAS_HWFileSeek(pEASData->hwInstData, pData->fileHandle, pData->fileOffset)) != EAS_SUCCESS)
- return result;
- if ((result = RTTTL_ParseHeader (pEASData, pData, EAS_TRUE)) != EAS_SUCCESS)
- return result;
-
- pData->state = EAS_STATE_READY;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * RTTTL_Pause()
- *----------------------------------------------------------------------------
- * Purpose:
- * Pauses the sequencer. Mutes all voices and sets state to pause.
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT RTTTL_Pause (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
-{
- S_RTTTL_DATA *pData;
-
- /* can't pause a stopped stream */
- pData = (S_RTTTL_DATA*) pInstData;
- if (pData->state == EAS_STATE_STOPPED)
- return EAS_ERROR_ALREADY_STOPPED;
-
- /* mute the synthesizer */
- VMMuteAllVoices(pEASData->pVoiceMgr, pData->pSynth);
- pData->state = EAS_STATE_PAUSING;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * RTTTL_Resume()
- *----------------------------------------------------------------------------
- * Purpose:
- * Resume playing after a pause, sets state back to playing.
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, pEASData) reserved for future use */
-static EAS_RESULT RTTTL_Resume (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
-{
- S_RTTTL_DATA *pData;
-
- /* can't resume a stopped stream */
- pData = (S_RTTTL_DATA*) pInstData;
- if (pData->state == EAS_STATE_STOPPED)
- return EAS_ERROR_ALREADY_STOPPED;
-
- /* nothing to do but resume playback */
- pData->state = EAS_STATE_PLAY;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * RTTTL_SetData()
- *----------------------------------------------------------------------------
- * Purpose:
- * Return file type
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, pEASData) reserved for future use */
-static EAS_RESULT RTTTL_SetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value)
-{
- S_RTTTL_DATA *pData;
-
- pData = (S_RTTTL_DATA *) pInstData;
- switch (param)
- {
-
- /* set metadata callback */
- case PARSER_DATA_METADATA_CB:
- EAS_HWMemCpy(&pData->metadata, (void*) value, sizeof(S_METADATA_CB));
- break;
-
- default:
- return EAS_ERROR_INVALID_PARAMETER;
- }
-
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * RTTTL_GetData()
- *----------------------------------------------------------------------------
- * Purpose:
- * Return file type
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, pEASData) reserved for future use */
-static EAS_RESULT RTTTL_GetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue)
-{
- S_RTTTL_DATA *pData;
-
- pData = (S_RTTTL_DATA *) pInstData;
- switch (param)
- {
- /* return file type as RTTTL */
- case PARSER_DATA_FILE_TYPE:
- *pValue = EAS_FILE_RTTTL;
- break;
-
-#if 0
- /* set transposition */
- case PARSER_DATA_TRANSPOSITION:
- *pValue = pData->transposition;
- break;
-#endif
-
- case PARSER_DATA_SYNTH_HANDLE:
- *pValue = (EAS_I32) pData->pSynth;
- break;
-
- case PARSER_DATA_GAIN_OFFSET:
- *pValue = RTTTL_GAIN_OFFSET;
- break;
-
- default:
- return EAS_ERROR_INVALID_PARAMETER;
- }
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * RTTTL_GetStyle()
- *----------------------------------------------------------------------------
- * Purpose:
- *
- *
- * Inputs:
- *
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT RTTTL_GetStyle (EAS_HW_DATA_HANDLE hwInstData, S_RTTTL_DATA *pData)
-{
- EAS_RESULT result;
- EAS_I8 style;
-
- /* get style */
- if ((result = RTTTL_GetNextChar(hwInstData, pData, &style)) != EAS_SUCCESS)
- return result;
-
- if ((style != 's') && (style != 'n') && (style != 'c'))
- return EAS_ERROR_FILE_FORMAT;
-
- pData->style = style;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * RTTTL_GetDuration()
- *----------------------------------------------------------------------------
- * Purpose:
- *
- *
- * Inputs:
- *
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT RTTTL_GetDuration (EAS_HW_DATA_HANDLE hwInstData, S_RTTTL_DATA *pData, EAS_I8 *pDuration)
-{
- EAS_RESULT result;
- EAS_I32 duration;
- EAS_I8 temp;
-
- /* get the duration */
- if ((result = RTTTL_GetNumber(hwInstData, pData, &duration)) != EAS_SUCCESS)
- return result;
-
- if ((duration != 1) && (duration != 2) && (duration != 4) && (duration != 8) && (duration != 16) && (duration != 32))
- return EAS_ERROR_FILE_FORMAT;
-
- temp = 64;
- while (duration)
- {
- /*lint -e{704} shift for performance */
- duration = duration >> 1;
- /*lint -e{702} use shift for performance */
- temp = temp >> 1;
- }
-
- *pDuration = temp;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * RTTTL_GetOctave()
- *----------------------------------------------------------------------------
- * Purpose:
- *
- *
- * Inputs:
- *
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT RTTTL_GetOctave (EAS_HW_DATA_HANDLE hwInstData, S_RTTTL_DATA *pData, EAS_U8 *pOctave)
-{
- EAS_RESULT result;
- EAS_I32 octave;
-
- /* get the tempo */
- if ((result = RTTTL_GetNumber(hwInstData, pData, &octave)) != EAS_SUCCESS)
- return result;
-
- if ((octave < 4) || (octave > 7))
- return EAS_ERROR_FILE_FORMAT;
-
- *pOctave = (EAS_U8) (octave * 12);
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * RTTTL_GetTempo()
- *----------------------------------------------------------------------------
- * Purpose:
- *
- *
- * Inputs:
- *
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT RTTTL_GetTempo (EAS_HW_DATA_HANDLE hwInstData, S_RTTTL_DATA *pData)
-{
- EAS_RESULT result;
- EAS_I32 tempo;
-
- /* get the tempo */
- if ((result = RTTTL_GetNumber(hwInstData, pData, &tempo)) != EAS_SUCCESS)
- return result;
-
- if ((tempo < 25) || (tempo > 900))
- return EAS_ERROR_FILE_FORMAT;
-
- pData->tick = TICK_CONVERT / (EAS_U32) tempo;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * RTTTL_GetNumber()
- *----------------------------------------------------------------------------
- * Purpose:
- *
- *
- * Inputs:
- *
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT RTTTL_GetNumber (EAS_HW_DATA_HANDLE hwInstData, S_RTTTL_DATA *pData, EAS_I32 *pValue)
-{
- EAS_RESULT result;
- EAS_INT temp;
- EAS_I8 c;
-
- *pValue = -1;
- temp = 0;
- for (;;)
- {
- if ((result = RTTTL_PeekNextChar(hwInstData, pData, &c)) != EAS_SUCCESS)
- {
- if ((result == EAS_EOF) && (*pValue != -1))
- return EAS_SUCCESS;
- return result;
- }
-
- if (IsDigit(c))
- {
- pData->dataByte = 0;
- temp = temp * 10 + c - '0';
- *pValue = temp;
- }
- else
- return EAS_SUCCESS;
- }
-}
-
-/*----------------------------------------------------------------------------
- * RTTTL_ParseHeader()
- *----------------------------------------------------------------------------
- * Purpose:
- * Prepare to parse the file. Allocates instance data (or uses static allocation for
- * static memory model).
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT RTTTL_ParseHeader (S_EAS_DATA *pEASData, S_RTTTL_DATA* pData, EAS_BOOL metaData)
-{
- EAS_RESULT result;
- EAS_I32 i;
- EAS_I8 temp;
- EAS_I8 control;
-
- /* initialize some defaults */
- pData->time = 0;
- pData->tick = DEFAULT_TICK_CONV;
- pData->note = 0;
- pData->duration = 4;
- pData ->restTicks = 0;
- pData->octave = 60;
- pData->repeatOffset = -1;
- pData->repeatCount = 0;
- pData->style = 'n';
- pData->dataByte = 0;
-
- metaData = metaData && (pData->metadata.buffer != NULL) && (pData->metadata.callback != NULL);
-
- /* seek to start of data */
- if ((result = EAS_HWFileSeek(pEASData->hwInstData, pData->fileHandle, pData->fileOffset)) != EAS_SUCCESS)
- return result;
-
- /* zero the metadata buffer */
- if (metaData)
- EAS_HWMemSet(pData->metadata.buffer, 0, pData->metadata.bufferSize);
-
- /* read the title */
- for (i = 0; i < RTTTL_MAX_TITLE_LEN; i++)
- {
- if ((result = EAS_HWGetByte(pEASData->hwInstData, pData->fileHandle, &temp)) != EAS_SUCCESS)
- return result;
-
- if (temp == ':')
- break;
-
- /* pass along metadata */
- if (metaData)
- {
- if (i < (pData->metadata.bufferSize- 1))
- pData->metadata.buffer[i] = (char) temp;
- }
- }
-
- /* check for error in title */
- if (i == RTTTL_MAX_TITLE_LEN)
- return EAS_ERROR_FILE_FORMAT;
-
- /* pass along metadata */
- if (metaData)
- (*pData->metadata.callback)(EAS_METADATA_TITLE, pData->metadata.buffer, pData->metadata.pUserData);
-
- /* control fields */
- for (;;)
- {
-
- /* get control type */
- if ((result = RTTTL_GetNextChar(pEASData->hwInstData, pData, &control)) != EAS_SUCCESS)
- return result;
-
- /* next char should be equal sign */
- if ((result = RTTTL_GetNextChar(pEASData->hwInstData, pData, &temp)) != EAS_SUCCESS)
- return result;
- if (temp != '=')
- return EAS_ERROR_FILE_FORMAT;
-
- /* get the control value */
- switch (control)
- {
-
- /* bpm */
- case 'b':
- if ((result = RTTTL_GetTempo(pEASData->hwInstData, pData)) != EAS_SUCCESS)
- return result;
- break;
-
- /* duration */
- case 'd':
- if ((result = RTTTL_GetDuration(pEASData->hwInstData, pData, &temp)) != EAS_SUCCESS)
- return result;
- pData->duration = temp;
- break;
-
- /* loop */
- case 'l':
- if ((result = RTTTL_GetNumber(pEASData->hwInstData, pData, &i)) != EAS_SUCCESS)
- return result;
- if ((i < 0) || (i > 15))
- return EAS_ERROR_FILE_FORMAT;
- pData->repeatCount = (EAS_U8) i;
- break;
-
- /* octave */
- case 'o':
- if ((result = RTTTL_GetOctave(pEASData->hwInstData, pData, &pData->octave)) != EAS_SUCCESS)
- return result;
- break;
-
- /* get style */
- case 's':
- if ((result = RTTTL_GetStyle(pEASData->hwInstData, pData)) != EAS_SUCCESS)
- return result;
- break;
-
- /* unrecognized control */
- default:
- return EAS_ERROR_FILE_FORMAT;
- }
-
- /* next character should be comma or colon */
- if ((result = RTTTL_GetNextChar(pEASData->hwInstData, pData, &temp)) != EAS_SUCCESS)
- return result;
-
- /* check for end of control field */
- if (temp == ':')
- break;
-
- /* must be a comma */
- if (temp != ',')
- return EAS_ERROR_FILE_FORMAT;
- }
-
- /* should be at the start of the music block */
- if ((result = EAS_HWFilePos(pEASData->hwInstData, pData->fileHandle, &pData->repeatOffset)) != EAS_SUCCESS)
- return result;
-
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * RTTTL_GetNextChar()
- *----------------------------------------------------------------------------
- * Purpose:
- *
- *
- * Inputs:
- *
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT RTTTL_GetNextChar (EAS_HW_DATA_HANDLE hwInstData, S_RTTTL_DATA *pData, EAS_I8 *pValue)
-{
- EAS_RESULT result;
- EAS_I8 temp;
-
- *pValue = 0;
- for(;;)
- {
-
- /* check for character that has been put back */
- if (pData->dataByte)
- {
- temp = pData->dataByte;
- pData->dataByte = 0;
- }
- else
- {
- if ((result = EAS_HWGetByte(hwInstData, pData->fileHandle, &temp)) != EAS_SUCCESS)
- return result;
- }
-
- /* ignore white space */
- if (!IsSpace(temp))
- {
- *pValue = ToLower(temp);
- return EAS_SUCCESS;
- }
- }
-}
-
-/*----------------------------------------------------------------------------
- * RTTTL_PeekNextChar()
- *----------------------------------------------------------------------------
- * Purpose:
- *
- *
- * Inputs:
- *
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT RTTTL_PeekNextChar (EAS_HW_DATA_HANDLE hwInstData, S_RTTTL_DATA *pData, EAS_I8 *pValue)
-{
- EAS_RESULT result;
- EAS_I8 temp;
-
- *pValue = 0;
- for(;;)
- {
-
- /* read a character from the file, if necessary */
- if (!pData->dataByte)
- {
- if ((result = EAS_HWGetByte(hwInstData, pData->fileHandle, &pData->dataByte)) != EAS_SUCCESS)
- return result;
-
- }
- temp = pData->dataByte;
-
- /* ignore white space */
- if (!IsSpace(temp))
- {
- *pValue = ToLower(temp);
- return EAS_SUCCESS;
- }
- pData->dataByte = 0;
- }
-}
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 795 $
+ * $Date: 2007-08-01 00:14:45 -0700 (Wed, 01 Aug 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+#include "eas_data.h"
+#include "eas_miditypes.h"
+#include "eas_parser.h"
+#include "eas_report.h"
+#include "eas_host.h"
+#include "eas_midi.h"
+#include "eas_config.h"
+#include "eas_vm_protos.h"
+#include "eas_rtttldata.h"
+#include "eas_ctype.h"
+
+/* increase gain for mono ringtones */
+#define RTTTL_GAIN_OFFSET 8
+
+/* maximum title length including colon separator */
+#define RTTTL_MAX_TITLE_LEN 32
+#define RTTTL_INFINITE_LOOP 15
+
+/* length of 32nd note in 1/256ths of a msec for 63 BPM tempo */
+#define DEFAULT_TICK_CONV 30476
+#define TICK_CONVERT 1920000
+
+/* default channel and program for RTTTL playback */
+#define RTTTL_CHANNEL 0
+#define RTTTL_PROGRAM 80
+#define RTTTL_VELOCITY 127
+
+/* note used for rest */
+#define RTTTL_REST 1
+
+/* multiplier for fixed point triplet conversion */
+#define TRIPLET_MULTIPLIER 683
+#define TRIPLET_SHIFT 10
+
+/* local prototypes */
+static EAS_RESULT RTTTL_CheckFileType (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle, EAS_VOID_PTR *ppHandle, EAS_I32 offset);
+static EAS_RESULT RTTTL_Prepare (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
+static EAS_RESULT RTTTL_Time (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_U32 *pTime);
+static EAS_RESULT RTTTL_Event (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_INT parserMode);
+static EAS_RESULT RTTTL_State (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_STATE *pState);
+static EAS_RESULT RTTTL_Close (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
+static EAS_RESULT RTTTL_Reset (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
+static EAS_RESULT RTTTL_Pause (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
+static EAS_RESULT RTTTL_Resume (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
+static EAS_RESULT RTTTL_SetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value);
+static EAS_RESULT RTTTL_GetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue);
+static EAS_RESULT RTTTL_GetStyle (EAS_HW_DATA_HANDLE hwInstData, S_RTTTL_DATA *pData);
+static EAS_RESULT RTTTL_GetDuration (EAS_HW_DATA_HANDLE hwInstData, S_RTTTL_DATA *pData, EAS_I8 *pDuration);
+static EAS_RESULT RTTTL_GetOctave (EAS_HW_DATA_HANDLE hwInstData, S_RTTTL_DATA *pData, EAS_U8 *pOctave);
+static EAS_RESULT RTTTL_GetTempo (EAS_HW_DATA_HANDLE hwInstData, S_RTTTL_DATA *pData);
+static EAS_RESULT RTTTL_GetNumber (EAS_HW_DATA_HANDLE hwInstData, S_RTTTL_DATA *pData, EAS_I32 *pValue);
+static EAS_RESULT RTTTL_ParseHeader (S_EAS_DATA *pEASData, S_RTTTL_DATA* pData, EAS_BOOL metaData);
+static EAS_RESULT RTTTL_GetNextChar (EAS_HW_DATA_HANDLE hwInstData, S_RTTTL_DATA *pData, EAS_I8 *pValue);
+static EAS_RESULT RTTTL_PeekNextChar (EAS_HW_DATA_HANDLE hwInstData, S_RTTTL_DATA *pData, EAS_I8 *pValue);
+
+/* inline functions */
+EAS_INLINE void RTTTL_PutBackChar (S_RTTTL_DATA *pData, EAS_I8 value) { pData->dataByte = value; }
+
+
+/* lookup table for note values */
+static const EAS_U8 noteTable[] = { 21, 23, 12, 14, 16, 17, 19, 23 };
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_RTTTL_Parser
+ *
+ * This structure contains the functional interface for the iMelody parser
+ *----------------------------------------------------------------------------
+*/
+const S_FILE_PARSER_INTERFACE EAS_RTTTL_Parser =
+{
+ RTTTL_CheckFileType,
+ RTTTL_Prepare,
+ RTTTL_Time,
+ RTTTL_Event,
+ RTTTL_State,
+ RTTTL_Close,
+ RTTTL_Reset,
+ RTTTL_Pause,
+ RTTTL_Resume,
+ NULL,
+ RTTTL_SetData,
+ RTTTL_GetData,
+ NULL
+};
+
+/*----------------------------------------------------------------------------
+ * RTTTL_CheckFileType()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Check the file type to see if we can parse it
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT RTTTL_CheckFileType (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle, EAS_VOID_PTR *ppHandle, EAS_I32 offset)
+{
+ S_RTTTL_DATA data;
+ S_RTTTL_DATA *pData;
+
+ /* see if we can parse the header */
+ data.fileHandle = fileHandle;
+ data.fileOffset = offset;
+ *ppHandle= NULL;
+ if (RTTTL_ParseHeader (pEASData, &data, EAS_FALSE) == EAS_SUCCESS)
+ {
+
+ /* check for static memory allocation */
+ if (pEASData->staticMemoryModel)
+ pData = EAS_CMEnumData(EAS_CM_RTTTL_DATA);
+ else
+ pData = EAS_HWMalloc(pEASData->hwInstData, sizeof(S_RTTTL_DATA));
+ if (!pData)
+ return EAS_ERROR_MALLOC_FAILED;
+ EAS_HWMemSet(pData, 0, sizeof(S_RTTTL_DATA));
+
+ /* return a pointer to the instance data */
+ pData->fileHandle = fileHandle;
+ pData->fileOffset = offset;
+ pData->state = EAS_STATE_OPEN;
+ *ppHandle = pData;
+ }
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * RTTTL_Prepare()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Prepare to parse the file. Allocates instance data (or uses static allocation for
+ * static memory model).
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT RTTTL_Prepare (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
+{
+ S_RTTTL_DATA* pData;
+ EAS_RESULT result;
+
+ /* check for valid state */
+ pData = (S_RTTTL_DATA*) pInstData;
+ if (pData->state != EAS_STATE_OPEN)
+ return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
+
+ /* instantiate a synthesizer */
+ if ((result = VMInitMIDI(pEASData, &pData->pSynth)) != EAS_SUCCESS)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "VMInitMIDI returned %d\n", result); */ }
+ return result;
+ }
+
+ pData->state = EAS_STATE_ERROR;
+ if ((result = RTTTL_ParseHeader (pEASData, pData, (EAS_BOOL) (pData->metadata.callback != NULL))) != EAS_SUCCESS)
+ {
+ /* if using dynamic memory, free it */
+ if (!pEASData->staticMemoryModel)
+ EAS_HWFree(pEASData->hwInstData, pData);
+ return result;
+ }
+
+ pData->state = EAS_STATE_READY;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * RTTTL_Time()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Returns the time of the next event in msecs
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ * pTime - pointer to variable to hold time of next event (in msecs)
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pEASData) reserved for future use */
+static EAS_RESULT RTTTL_Time (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_U32 *pTime)
+{
+ S_RTTTL_DATA *pData;
+
+ pData = (S_RTTTL_DATA*) pInstData;
+
+ /* return time in milliseconds */
+ /*lint -e{704} use shift instead of division */
+ *pTime = pData->time >> 8;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * RTTTL_Event()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Parse the next event in the file
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT RTTTL_Event (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_INT parserMode)
+{
+ S_RTTTL_DATA* pData;
+ EAS_RESULT result;
+ EAS_I32 ticks;
+ EAS_I32 temp;
+ EAS_I8 c;
+ EAS_U8 note;
+ EAS_U8 octave;
+
+ pData = (S_RTTTL_DATA*) pInstData;
+ if (pData->state >= EAS_STATE_OPEN)
+ return EAS_SUCCESS;
+
+ /* initialize MIDI channel when the track starts playing */
+ if (pData->time == 0)
+ {
+ /* set program to square lead */
+ VMProgramChange(pEASData->pVoiceMgr, pData->pSynth, RTTTL_CHANNEL, RTTTL_PROGRAM);
+
+ /* set channel volume to max */
+ VMControlChange(pEASData->pVoiceMgr, pData->pSynth, RTTTL_CHANNEL, 7, 127);
+ }
+
+ /* check for end of note */
+ if (pData->note)
+ {
+ /* stop the note */
+ VMStopNote(pEASData->pVoiceMgr, pData->pSynth, RTTTL_CHANNEL, pData->note, 0);
+ pData->note = 0;
+
+ /* check for rest between notes */
+ if (pData->restTicks)
+ {
+ pData->time += pData->restTicks;
+ pData->restTicks = 0;
+ return EAS_SUCCESS;
+ }
+ }
+
+ /* parse the next event */
+ octave = pData->octave;
+ note = 0;
+ ticks = pData->duration * pData->tick;
+ for (;;)
+ {
+
+ /* get next character */
+ if ((result = RTTTL_GetNextChar(pEASData->hwInstData, pData, &c)) != EAS_SUCCESS)
+ {
+ if (result != EAS_EOF)
+ return result;
+
+ /* end of file, if no notes to process, check for looping */
+ if (!note)
+ {
+ /* if no loop set state to stopping */
+ if (pData->repeatCount == 0)
+ {
+ pData->state = EAS_STATE_STOPPING;
+ VMReleaseAllVoices(pEASData->pVoiceMgr, pData->pSynth);
+ return EAS_SUCCESS;
+ }
+
+ /* decrement loop count */
+ if (pData->repeatCount != RTTTL_INFINITE_LOOP)
+ pData->repeatCount--;
+
+ /* if locating, ignore infinite loops */
+ else if (parserMode != eParserModePlay)
+ {
+ pData->state = EAS_STATE_STOPPING;
+ VMReleaseAllVoices(pEASData->pVoiceMgr, pData->pSynth);
+ return EAS_SUCCESS;
+ }
+
+ /* loop back to start of notes */
+ if ((result = EAS_HWFileSeek(pEASData->hwInstData, pData->fileHandle, pData->repeatOffset)) != EAS_SUCCESS)
+ return result;
+ continue;
+ }
+
+ /* still have a note to process */
+ else
+ c = ',';
+ }
+
+ /* bpm */
+ if (c == 'b')
+ {
+ /* peek at next character */
+ if ((result = RTTTL_PeekNextChar(pEASData->hwInstData, pData, &c)) != EAS_SUCCESS)
+ return result;
+
+ /* if a number, must be octave or tempo */
+ if (IsDigit(c))
+ {
+ if ((result = RTTTL_GetNumber(pEASData->hwInstData, pData, &temp)) != EAS_SUCCESS)
+ return result;
+
+ /* check for octave first */
+ if ((temp >= 4) && (temp <= 7))
+ {
+ octave = (EAS_U8) temp;
+ }
+
+ /* check for tempo */
+ else if ((temp >= 25) && (temp <= 900))
+ {
+ pData->tick = TICK_CONVERT / (EAS_U32) temp;
+ }
+
+ /* don't know what it was */
+ else
+ return EAS_ERROR_FILE_FORMAT;
+ }
+
+ /* must be a note */
+ else
+ {
+ note = noteTable[1];
+ }
+ }
+
+ /* octave */
+ else if (c == 'o')
+ {
+ if ((result = RTTTL_GetOctave(pEASData->hwInstData, pData, &pData->octave)) != EAS_SUCCESS)
+ return result;
+ }
+
+ /* style */
+ else if (c == 's')
+ {
+ if ((result = RTTTL_GetStyle(pEASData->hwInstData, pData)) != EAS_SUCCESS)
+ return result;
+ }
+
+ /* duration or octave */
+ else if (IsDigit(c))
+ {
+ RTTTL_PutBackChar(pData, c);
+
+ /* duration comes before note */
+ if (!note)
+ {
+ if ((result = RTTTL_GetDuration(pEASData->hwInstData, pData, &c)) != EAS_SUCCESS)
+ return result;
+ ticks = c * pData->tick;
+ }
+
+ /* octave comes after note */
+ else
+ {
+ if ((result = RTTTL_GetOctave(pEASData->hwInstData, pData, &octave)) != EAS_SUCCESS)
+ return result;
+ }
+ }
+
+ /* note or rest */
+ else if ((c >= 'a') && (c <= 'h'))
+ {
+ note = noteTable[c - 'a'];
+ }
+
+ else if (c == 'p')
+ {
+ note = RTTTL_REST;
+ }
+
+ /* dotted note */
+ else if (c == '.')
+ {
+ /*lint -e{704} shift for performance */
+ ticks += ticks >> 1;
+ }
+
+ /* accidental */
+ else if (c == '#')
+ {
+ if (note)
+ note++;
+ }
+
+ /* end of event */
+ else if ((c == ',') && note)
+ {
+
+ /* handle note events */
+ if (note != RTTTL_REST)
+ {
+
+ /* save note and start it */
+ pData->note = note + octave;
+ if (parserMode == eParserModePlay)
+ VMStartNote(pEASData->pVoiceMgr, pData->pSynth, RTTTL_CHANNEL, pData->note, RTTTL_VELOCITY);
+
+ /* determine note length */
+ switch (pData->style)
+ {
+ /* natural */
+ case 'n':
+ /*lint -e{704} shift for performance */
+ pData->restTicks = ticks >> 4;
+ break;
+ /* continuous */
+
+ case 'c':
+ pData->restTicks = 0;
+ break;
+
+ /* staccato */
+ case 's':
+ /*lint -e{704} shift for performance */
+ pData->restTicks = ticks >> 1;
+ break;
+
+ default:
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "RTTTL_Event: Unexpected style type %c\n", pData->style); */ }
+ break;
+ }
+
+ /* next event is at end of this note */
+ pData->time += ticks - pData->restTicks;
+ }
+
+ /* rest */
+ else
+ pData->time += ticks;
+
+ /* event found, return to caller */
+ break;
+ }
+ }
+
+ pData->state = EAS_STATE_PLAY;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * RTTTL_State()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Returns the current state of the stream
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ * pState - pointer to variable to store state
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pEASData) reserved for future use */
+static EAS_RESULT RTTTL_State (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 *pState)
+{
+ S_RTTTL_DATA* pData;
+
+ /* establish pointer to instance data */
+ pData = (S_RTTTL_DATA*) pInstData;
+
+ /* if stopping, check to see if synth voices are active */
+ if (pData->state == EAS_STATE_STOPPING)
+ {
+ if (VMActiveVoices(pData->pSynth) == 0)
+ pData->state = EAS_STATE_STOPPED;
+ }
+
+ if (pData->state == EAS_STATE_PAUSING)
+ {
+ if (VMActiveVoices(pData->pSynth) == 0)
+ pData->state = EAS_STATE_PAUSED;
+ }
+
+ /* return current state */
+ *pState = pData->state;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * RTTTL_Close()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Close the file and clean up
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT RTTTL_Close (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
+{
+ S_RTTTL_DATA* pData;
+ EAS_RESULT result;
+
+ pData = (S_RTTTL_DATA*) pInstData;
+
+ /* close the file */
+ if ((result = EAS_HWCloseFile(pEASData->hwInstData, pData->fileHandle)) != EAS_SUCCESS)
+ return result;
+
+ /* free the synth */
+ if (pData->pSynth != NULL)
+ VMMIDIShutdown(pEASData, pData->pSynth);
+
+ /* if using dynamic memory, free it */
+ if (!pEASData->staticMemoryModel)
+ EAS_HWFree(pEASData->hwInstData, pData);
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * RTTTL_Reset()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Reset the sequencer. Used for locating backwards in the file.
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT RTTTL_Reset (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
+{
+ S_RTTTL_DATA* pData;
+ EAS_RESULT result;
+
+ pData = (S_RTTTL_DATA*) pInstData;
+
+ /* reset the synth */
+ VMReset(pEASData->pVoiceMgr, pData->pSynth, EAS_TRUE);
+
+ /* reset time to zero */
+ pData->time = 0;
+ pData->note = 0;
+
+ /* reset file position and re-parse header */
+ pData->state = EAS_STATE_ERROR;
+ if ((result = EAS_HWFileSeek(pEASData->hwInstData, pData->fileHandle, pData->fileOffset)) != EAS_SUCCESS)
+ return result;
+ if ((result = RTTTL_ParseHeader (pEASData, pData, EAS_TRUE)) != EAS_SUCCESS)
+ return result;
+
+ pData->state = EAS_STATE_READY;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * RTTTL_Pause()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Pauses the sequencer. Mutes all voices and sets state to pause.
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT RTTTL_Pause (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
+{
+ S_RTTTL_DATA *pData;
+
+ /* can't pause a stopped stream */
+ pData = (S_RTTTL_DATA*) pInstData;
+ if (pData->state == EAS_STATE_STOPPED)
+ return EAS_ERROR_ALREADY_STOPPED;
+
+ /* mute the synthesizer */
+ VMMuteAllVoices(pEASData->pVoiceMgr, pData->pSynth);
+ pData->state = EAS_STATE_PAUSING;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * RTTTL_Resume()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Resume playing after a pause, sets state back to playing.
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pEASData) reserved for future use */
+static EAS_RESULT RTTTL_Resume (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
+{
+ S_RTTTL_DATA *pData;
+
+ /* can't resume a stopped stream */
+ pData = (S_RTTTL_DATA*) pInstData;
+ if (pData->state == EAS_STATE_STOPPED)
+ return EAS_ERROR_ALREADY_STOPPED;
+
+ /* nothing to do but resume playback */
+ pData->state = EAS_STATE_PLAY;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * RTTTL_SetData()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Return file type
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pEASData) reserved for future use */
+static EAS_RESULT RTTTL_SetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value)
+{
+ S_RTTTL_DATA *pData;
+
+ pData = (S_RTTTL_DATA *) pInstData;
+ switch (param)
+ {
+
+ /* set metadata callback */
+ case PARSER_DATA_METADATA_CB:
+ EAS_HWMemCpy(&pData->metadata, (void*) value, sizeof(S_METADATA_CB));
+ break;
+
+ default:
+ return EAS_ERROR_INVALID_PARAMETER;
+ }
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * RTTTL_GetData()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Return file type
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pEASData) reserved for future use */
+static EAS_RESULT RTTTL_GetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue)
+{
+ S_RTTTL_DATA *pData;
+
+ pData = (S_RTTTL_DATA *) pInstData;
+ switch (param)
+ {
+ /* return file type as RTTTL */
+ case PARSER_DATA_FILE_TYPE:
+ *pValue = EAS_FILE_RTTTL;
+ break;
+
+#if 0
+ /* set transposition */
+ case PARSER_DATA_TRANSPOSITION:
+ *pValue = pData->transposition;
+ break;
+#endif
+
+ case PARSER_DATA_SYNTH_HANDLE:
+ *pValue = (EAS_I32) pData->pSynth;
+ break;
+
+ case PARSER_DATA_GAIN_OFFSET:
+ *pValue = RTTTL_GAIN_OFFSET;
+ break;
+
+ default:
+ return EAS_ERROR_INVALID_PARAMETER;
+ }
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * RTTTL_GetStyle()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ *
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT RTTTL_GetStyle (EAS_HW_DATA_HANDLE hwInstData, S_RTTTL_DATA *pData)
+{
+ EAS_RESULT result;
+ EAS_I8 style;
+
+ /* get style */
+ if ((result = RTTTL_GetNextChar(hwInstData, pData, &style)) != EAS_SUCCESS)
+ return result;
+
+ if ((style != 's') && (style != 'n') && (style != 'c'))
+ return EAS_ERROR_FILE_FORMAT;
+
+ pData->style = style;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * RTTTL_GetDuration()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ *
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT RTTTL_GetDuration (EAS_HW_DATA_HANDLE hwInstData, S_RTTTL_DATA *pData, EAS_I8 *pDuration)
+{
+ EAS_RESULT result;
+ EAS_I32 duration;
+ EAS_I8 temp;
+
+ /* get the duration */
+ if ((result = RTTTL_GetNumber(hwInstData, pData, &duration)) != EAS_SUCCESS)
+ return result;
+
+ if ((duration != 1) && (duration != 2) && (duration != 4) && (duration != 8) && (duration != 16) && (duration != 32))
+ return EAS_ERROR_FILE_FORMAT;
+
+ temp = 64;
+ while (duration)
+ {
+ /*lint -e{704} shift for performance */
+ duration = duration >> 1;
+ /*lint -e{702} use shift for performance */
+ temp = temp >> 1;
+ }
+
+ *pDuration = temp;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * RTTTL_GetOctave()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ *
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT RTTTL_GetOctave (EAS_HW_DATA_HANDLE hwInstData, S_RTTTL_DATA *pData, EAS_U8 *pOctave)
+{
+ EAS_RESULT result;
+ EAS_I32 octave;
+
+ /* get the tempo */
+ if ((result = RTTTL_GetNumber(hwInstData, pData, &octave)) != EAS_SUCCESS)
+ return result;
+
+ if ((octave < 4) || (octave > 7))
+ return EAS_ERROR_FILE_FORMAT;
+
+ *pOctave = (EAS_U8) (octave * 12);
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * RTTTL_GetTempo()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ *
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT RTTTL_GetTempo (EAS_HW_DATA_HANDLE hwInstData, S_RTTTL_DATA *pData)
+{
+ EAS_RESULT result;
+ EAS_I32 tempo;
+
+ /* get the tempo */
+ if ((result = RTTTL_GetNumber(hwInstData, pData, &tempo)) != EAS_SUCCESS)
+ return result;
+
+ if ((tempo < 25) || (tempo > 900))
+ return EAS_ERROR_FILE_FORMAT;
+
+ pData->tick = TICK_CONVERT / (EAS_U32) tempo;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * RTTTL_GetNumber()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ *
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT RTTTL_GetNumber (EAS_HW_DATA_HANDLE hwInstData, S_RTTTL_DATA *pData, EAS_I32 *pValue)
+{
+ EAS_RESULT result;
+ EAS_INT temp;
+ EAS_I8 c;
+
+ *pValue = -1;
+ temp = 0;
+ for (;;)
+ {
+ if ((result = RTTTL_PeekNextChar(hwInstData, pData, &c)) != EAS_SUCCESS)
+ {
+ if ((result == EAS_EOF) && (*pValue != -1))
+ return EAS_SUCCESS;
+ return result;
+ }
+
+ if (IsDigit(c))
+ {
+ pData->dataByte = 0;
+ temp = temp * 10 + c - '0';
+ *pValue = temp;
+ }
+ else
+ return EAS_SUCCESS;
+ }
+}
+
+/*----------------------------------------------------------------------------
+ * RTTTL_ParseHeader()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Prepare to parse the file. Allocates instance data (or uses static allocation for
+ * static memory model).
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT RTTTL_ParseHeader (S_EAS_DATA *pEASData, S_RTTTL_DATA* pData, EAS_BOOL metaData)
+{
+ EAS_RESULT result;
+ EAS_I32 i;
+ EAS_I8 temp;
+ EAS_I8 control;
+
+ /* initialize some defaults */
+ pData->time = 0;
+ pData->tick = DEFAULT_TICK_CONV;
+ pData->note = 0;
+ pData->duration = 4;
+ pData ->restTicks = 0;
+ pData->octave = 60;
+ pData->repeatOffset = -1;
+ pData->repeatCount = 0;
+ pData->style = 'n';
+ pData->dataByte = 0;
+
+ metaData = metaData && (pData->metadata.buffer != NULL) && (pData->metadata.callback != NULL);
+
+ /* seek to start of data */
+ if ((result = EAS_HWFileSeek(pEASData->hwInstData, pData->fileHandle, pData->fileOffset)) != EAS_SUCCESS)
+ return result;
+
+ /* zero the metadata buffer */
+ if (metaData)
+ EAS_HWMemSet(pData->metadata.buffer, 0, pData->metadata.bufferSize);
+
+ /* read the title */
+ for (i = 0; i < RTTTL_MAX_TITLE_LEN; i++)
+ {
+ if ((result = EAS_HWGetByte(pEASData->hwInstData, pData->fileHandle, &temp)) != EAS_SUCCESS)
+ return result;
+
+ if (temp == ':')
+ break;
+
+ /* pass along metadata */
+ if (metaData)
+ {
+ if (i < (pData->metadata.bufferSize- 1))
+ pData->metadata.buffer[i] = (char) temp;
+ }
+ }
+
+ /* check for error in title */
+ if (i == RTTTL_MAX_TITLE_LEN)
+ return EAS_ERROR_FILE_FORMAT;
+
+ /* pass along metadata */
+ if (metaData)
+ (*pData->metadata.callback)(EAS_METADATA_TITLE, pData->metadata.buffer, pData->metadata.pUserData);
+
+ /* control fields */
+ for (;;)
+ {
+
+ /* get control type */
+ if ((result = RTTTL_GetNextChar(pEASData->hwInstData, pData, &control)) != EAS_SUCCESS)
+ return result;
+
+ /* next char should be equal sign */
+ if ((result = RTTTL_GetNextChar(pEASData->hwInstData, pData, &temp)) != EAS_SUCCESS)
+ return result;
+ if (temp != '=')
+ return EAS_ERROR_FILE_FORMAT;
+
+ /* get the control value */
+ switch (control)
+ {
+
+ /* bpm */
+ case 'b':
+ if ((result = RTTTL_GetTempo(pEASData->hwInstData, pData)) != EAS_SUCCESS)
+ return result;
+ break;
+
+ /* duration */
+ case 'd':
+ if ((result = RTTTL_GetDuration(pEASData->hwInstData, pData, &temp)) != EAS_SUCCESS)
+ return result;
+ pData->duration = temp;
+ break;
+
+ /* loop */
+ case 'l':
+ if ((result = RTTTL_GetNumber(pEASData->hwInstData, pData, &i)) != EAS_SUCCESS)
+ return result;
+ if ((i < 0) || (i > 15))
+ return EAS_ERROR_FILE_FORMAT;
+ pData->repeatCount = (EAS_U8) i;
+ break;
+
+ /* octave */
+ case 'o':
+ if ((result = RTTTL_GetOctave(pEASData->hwInstData, pData, &pData->octave)) != EAS_SUCCESS)
+ return result;
+ break;
+
+ /* get style */
+ case 's':
+ if ((result = RTTTL_GetStyle(pEASData->hwInstData, pData)) != EAS_SUCCESS)
+ return result;
+ break;
+
+ /* unrecognized control */
+ default:
+ return EAS_ERROR_FILE_FORMAT;
+ }
+
+ /* next character should be comma or colon */
+ if ((result = RTTTL_GetNextChar(pEASData->hwInstData, pData, &temp)) != EAS_SUCCESS)
+ return result;
+
+ /* check for end of control field */
+ if (temp == ':')
+ break;
+
+ /* must be a comma */
+ if (temp != ',')
+ return EAS_ERROR_FILE_FORMAT;
+ }
+
+ /* should be at the start of the music block */
+ if ((result = EAS_HWFilePos(pEASData->hwInstData, pData->fileHandle, &pData->repeatOffset)) != EAS_SUCCESS)
+ return result;
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * RTTTL_GetNextChar()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ *
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT RTTTL_GetNextChar (EAS_HW_DATA_HANDLE hwInstData, S_RTTTL_DATA *pData, EAS_I8 *pValue)
+{
+ EAS_RESULT result;
+ EAS_I8 temp;
+
+ *pValue = 0;
+ for(;;)
+ {
+
+ /* check for character that has been put back */
+ if (pData->dataByte)
+ {
+ temp = pData->dataByte;
+ pData->dataByte = 0;
+ }
+ else
+ {
+ if ((result = EAS_HWGetByte(hwInstData, pData->fileHandle, &temp)) != EAS_SUCCESS)
+ return result;
+ }
+
+ /* ignore white space */
+ if (!IsSpace(temp))
+ {
+ *pValue = ToLower(temp);
+ return EAS_SUCCESS;
+ }
+ }
+}
+
+/*----------------------------------------------------------------------------
+ * RTTTL_PeekNextChar()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ *
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT RTTTL_PeekNextChar (EAS_HW_DATA_HANDLE hwInstData, S_RTTTL_DATA *pData, EAS_I8 *pValue)
+{
+ EAS_RESULT result;
+ EAS_I8 temp;
+
+ *pValue = 0;
+ for(;;)
+ {
+
+ /* read a character from the file, if necessary */
+ if (!pData->dataByte)
+ {
+ if ((result = EAS_HWGetByte(hwInstData, pData->fileHandle, &pData->dataByte)) != EAS_SUCCESS)
+ return result;
+
+ }
+ temp = pData->dataByte;
+
+ /* ignore white space */
+ if (!IsSpace(temp))
+ {
+ *pValue = ToLower(temp);
+ return EAS_SUCCESS;
+ }
+ pData->dataByte = 0;
+ }
+}
+
diff --git a/arm-fm-22k/lib_src/eas_rtttldata.c b/arm-fm-22k/lib_src/eas_rtttldata.c
index 7a500bd..708a1d9 100644
--- a/arm-fm-22k/lib_src/eas_rtttldata.c
+++ b/arm-fm-22k/lib_src/eas_rtttldata.c
@@ -1,12 +1,12 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_rtttldata.c
- *
- * Contents and purpose:
- * RTTTL File Parser data module for static memory models
- *
- * Copyright Sonic Network Inc. 2005
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_rtttldata.c
+ *
+ * Contents and purpose:
+ * RTTTL File Parser data module for static memory models
+ *
+ * Copyright Sonic Network Inc. 2005
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,23 +19,23 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 547 $
- * $Date: 2007-01-31 16:30:17 -0800 (Wed, 31 Jan 2007) $
- *----------------------------------------------------------------------------
-*/
-
-#include "eas_types.h"
-#include "eas_rtttldata.h"
-
-/*----------------------------------------------------------------------------
- *
- * eas_RTTTLData
- *
- * Static memory allocation for RTTTL parser
- *----------------------------------------------------------------------------
-*/
-S_RTTTL_DATA eas_RTTTLData;
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 547 $
+ * $Date: 2007-01-31 16:30:17 -0800 (Wed, 31 Jan 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+#include "eas_types.h"
+#include "eas_rtttldata.h"
+
+/*----------------------------------------------------------------------------
+ *
+ * eas_RTTTLData
+ *
+ * Static memory allocation for RTTTL parser
+ *----------------------------------------------------------------------------
+*/
+S_RTTTL_DATA eas_RTTTLData;
+
diff --git a/arm-fm-22k/lib_src/eas_rtttldata.h b/arm-fm-22k/lib_src/eas_rtttldata.h
index bf4c38b..31dd522 100644
--- a/arm-fm-22k/lib_src/eas_rtttldata.h
+++ b/arm-fm-22k/lib_src/eas_rtttldata.h
@@ -1,14 +1,14 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_rtttldata.h
- *
- * Contents and purpose:
- * SMF File Parser
- *
- * This file contains data declarations for the RTTTL parser.
- *
- * Copyright Sonic Network Inc. 2005
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_rtttldata.h
+ *
+ * Contents and purpose:
+ * SMF File Parser
+ *
+ * This file contains data declarations for the RTTTL parser.
+ *
+ * Copyright Sonic Network Inc. 2005
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,50 +21,50 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 82 $
- * $Date: 2006-07-10 11:45:19 -0700 (Mon, 10 Jul 2006) $
- *----------------------------------------------------------------------------
-*/
-
-#ifndef EAS_RTTTLDATA_H
-#define EAS_RTTTLDATA_H
-
-#include "eas_data.h"
-
-
-/* maximum line size as specified in iMelody V1.2 spec */
-#define MAX_LINE_SIZE 75
-
-/*----------------------------------------------------------------------------
- *
- * S_RTTTL_DATA
- *
- * This structure contains the state data for the iMelody parser
- *----------------------------------------------------------------------------
-*/
-
-typedef struct
-{
- EAS_FILE_HANDLE fileHandle; /* file handle */
- S_SYNTH *pSynth; /* synthesizer handle */
- S_METADATA_CB metadata; /* metadata callback */
- EAS_I32 fileOffset; /* offset to start of data */
- EAS_I32 time; /* current time in 256ths of a msec */
- EAS_I32 tick; /* length of 32nd note in 256th of a msec */
- EAS_I32 restTicks; /* ticks to rest after current note */
- EAS_I32 repeatOffset; /* file offset to start of repeat section */
- EAS_U8 repeatCount; /* repeat counter */
- EAS_I8 dataByte; /* storage for characters that are "put back" */
- EAS_U8 state; /* current state EAS_STATE_XXXX */
- EAS_I8 style; /* from STYLE */
- EAS_U8 note; /* MIDI note number */
- EAS_U8 octave; /* decault octave prefix */
- EAS_I8 duration; /* default note duration */
-} S_RTTTL_DATA;
-
-#endif
-
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 82 $
+ * $Date: 2006-07-10 11:45:19 -0700 (Mon, 10 Jul 2006) $
+ *----------------------------------------------------------------------------
+*/
+
+#ifndef EAS_RTTTLDATA_H
+#define EAS_RTTTLDATA_H
+
+#include "eas_data.h"
+
+
+/* maximum line size as specified in iMelody V1.2 spec */
+#define MAX_LINE_SIZE 75
+
+/*----------------------------------------------------------------------------
+ *
+ * S_RTTTL_DATA
+ *
+ * This structure contains the state data for the iMelody parser
+ *----------------------------------------------------------------------------
+*/
+
+typedef struct
+{
+ EAS_FILE_HANDLE fileHandle; /* file handle */
+ S_SYNTH *pSynth; /* synthesizer handle */
+ S_METADATA_CB metadata; /* metadata callback */
+ EAS_I32 fileOffset; /* offset to start of data */
+ EAS_I32 time; /* current time in 256ths of a msec */
+ EAS_I32 tick; /* length of 32nd note in 256th of a msec */
+ EAS_I32 restTicks; /* ticks to rest after current note */
+ EAS_I32 repeatOffset; /* file offset to start of repeat section */
+ EAS_U8 repeatCount; /* repeat counter */
+ EAS_I8 dataByte; /* storage for characters that are "put back" */
+ EAS_U8 state; /* current state EAS_STATE_XXXX */
+ EAS_I8 style; /* from STYLE */
+ EAS_U8 note; /* MIDI note number */
+ EAS_U8 octave; /* decault octave prefix */
+ EAS_I8 duration; /* default note duration */
+} S_RTTTL_DATA;
+
+#endif
+
+
diff --git a/arm-fm-22k/lib_src/eas_smf.c b/arm-fm-22k/lib_src/eas_smf.c
index 7b56e97..e609583 100644
--- a/arm-fm-22k/lib_src/eas_smf.c
+++ b/arm-fm-22k/lib_src/eas_smf.c
@@ -1,14 +1,14 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_smf.c
- *
- * Contents and purpose:
- * SMF Type 0 and 1 File Parser
- *
- * For SMF timebase analysis, see "MIDI Sequencer Analysis.xls".
- *
- * Copyright Sonic Network Inc. 2005
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_smf.c
+ *
+ * Contents and purpose:
+ * SMF Type 0 and 1 File Parser
+ *
+ * For SMF timebase analysis, see "MIDI Sequencer Analysis.xls".
+ *
+ * Copyright Sonic Network Inc. 2005
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,1183 +21,1183 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 803 $
- * $Date: 2007-08-01 09:57:00 -0700 (Wed, 01 Aug 2007) $
- *----------------------------------------------------------------------------
-*/
-
-#include "eas_data.h"
-#include "eas_miditypes.h"
-#include "eas_parser.h"
-#include "eas_report.h"
-#include "eas_host.h"
-#include "eas_midi.h"
-#include "eas_config.h"
-#include "eas_vm_protos.h"
-#include "eas_smfdata.h"
-#include "eas_smf.h"
-
-#ifdef JET_INTERFACE
-#include "jet_data.h"
-#endif
-
-//3 dls: The timebase for this module is adequate to keep MIDI and
-//3 digital audio synchronized for only a few minutes. It should be
-//3 sufficient for most mobile applications. If better accuracy is
-//3 required, more fractional bits should be added to the timebase.
-
-static const EAS_U8 smfHeader[] = { 'M', 'T', 'h', 'd' };
-
-/* local prototypes */
-static EAS_RESULT SMF_GetVarLenData (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE fileHandle, EAS_U32 *pData);
-static EAS_RESULT SMF_ParseMetaEvent (S_EAS_DATA *pEASData, S_SMF_DATA *pSMFData, S_SMF_STREAM *pSMFStream);
-static EAS_RESULT SMF_ParseSysEx (S_EAS_DATA *pEASData, S_SMF_DATA *pSMFData, S_SMF_STREAM *pSMFStream, EAS_U8 f0, EAS_INT parserMode);
-static EAS_RESULT SMF_ParseEvent (S_EAS_DATA *pEASData, S_SMF_DATA *pSMFData, S_SMF_STREAM *pSMFStream, EAS_INT parserMode);
-static EAS_RESULT SMF_GetDeltaTime (EAS_HW_DATA_HANDLE hwInstData, S_SMF_STREAM *pSMFStream);
-static void SMF_UpdateTime (S_SMF_DATA *pSMFData, EAS_U32 ticks);
-
-
-/*----------------------------------------------------------------------------
- *
- * SMF_Parser
- *
- * This structure contains the functional interface for the SMF parser
- *----------------------------------------------------------------------------
-*/
-const S_FILE_PARSER_INTERFACE EAS_SMF_Parser =
-{
- SMF_CheckFileType,
- SMF_Prepare,
- SMF_Time,
- SMF_Event,
- SMF_State,
- SMF_Close,
- SMF_Reset,
- SMF_Pause,
- SMF_Resume,
- NULL,
- SMF_SetData,
- SMF_GetData,
- NULL
-};
-
-/*----------------------------------------------------------------------------
- * SMF_CheckFileType()
- *----------------------------------------------------------------------------
- * Purpose:
- * Check the file type to see if we can parse it
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT SMF_CheckFileType (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle, EAS_VOID_PTR *ppHandle, EAS_I32 offset)
-{
- S_SMF_DATA* pSMFData;
- EAS_RESULT result;
-
- /* seek to starting offset - usually 0 */
- *ppHandle = NULL;
- if ((result = EAS_HWFileSeek(pEASData->hwInstData, fileHandle, offset)) != EAS_SUCCESS)
- return result;
-
- /* search through file for header - slow method */
- if (pEASData->searchHeaderFlag)
- {
- result = EAS_SearchFile(pEASData, fileHandle, smfHeader, sizeof(smfHeader), &offset);
- if (result != EAS_SUCCESS)
- return (result == EAS_EOF) ? EAS_SUCCESS : result;
- }
-
- /* read the first 4 bytes of the file - quick method */
- else {
- EAS_U8 header[4];
- EAS_I32 count;
- if ((result = EAS_HWReadFile(pEASData->hwInstData, fileHandle, header, sizeof(header), &count)) != EAS_SUCCESS)
- return result;
-
- /* check for 'MTrk' - return if no match */
- if ((header[0] != 'M') || (header[1] != 'T') || (header[2] != 'h') || (header[3] != 'd'))
- return EAS_SUCCESS;
- }
-
- /* check for static memory allocation */
- if (pEASData->staticMemoryModel)
- pSMFData = EAS_CMEnumData(EAS_CM_SMF_DATA);
- else
- {
- pSMFData = EAS_HWMalloc(pEASData->hwInstData, sizeof(S_SMF_DATA));
- EAS_HWMemSet((void *)pSMFData,0, sizeof(S_SMF_DATA));
- }
- if (!pSMFData)
- return EAS_ERROR_MALLOC_FAILED;
-
- /* initialize some critical data */
- pSMFData->fileHandle = fileHandle;
- pSMFData->fileOffset = offset;
- pSMFData->pSynth = NULL;
- pSMFData->time = 0;
- pSMFData->state = EAS_STATE_OPEN;
- *ppHandle = pSMFData;
-
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * SMF_Prepare()
- *----------------------------------------------------------------------------
- * Purpose:
- * Prepare to parse the file. Allocates instance data (or uses static allocation for
- * static memory model).
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT SMF_Prepare (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
-{
- S_SMF_DATA* pSMFData;
- EAS_RESULT result;
-
- /* check for valid state */
- pSMFData = (S_SMF_DATA *) pInstData;
- if (pSMFData->state != EAS_STATE_OPEN)
- return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
-
- /* instantiate a synthesizer */
- if ((result = VMInitMIDI(pEASData, &pSMFData->pSynth)) != EAS_SUCCESS)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "VMInitMIDI returned %d\n", result); */ }
- return result;
- }
-
- /* parse the file header and setup the individual stream parsers */
- if ((result = SMF_ParseHeader(pEASData->hwInstData, pSMFData)) != EAS_SUCCESS)
- return result;
-
- /* ready to play */
- pSMFData->state = EAS_STATE_READY;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * SMF_Time()
- *----------------------------------------------------------------------------
- * Purpose:
- * Returns the time of the next event in msecs
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- * pTime - pointer to variable to hold time of next event (in msecs)
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, pEASData) reserved for future use */
-EAS_RESULT SMF_Time (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_U32 *pTime)
-{
- S_SMF_DATA *pSMFData;
-
- pSMFData = (S_SMF_DATA*) pInstData;
-
- /* sanity check */
-#ifdef _CHECKED_BUILD
- if (pSMFData->state == EAS_STATE_STOPPED)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Can't ask for time on a stopped stream\n"); */ }
- }
-
- if (pSMFData->nextStream == NULL)
- {
- { /* dpp: EAS_ReportEx( _EAS_SEVERITY_ERROR, "no is NULL\n"); */ }
- }
-#endif
-
-#if 0
- /* return time in milliseconds */
- /* if chase mode, lie about time */
- if (pSMFData->flags & SMF_FLAGS_CHASE_MODE)
- *pTime = 0;
-
- else
-#endif
-
- /*lint -e{704} use shift instead of division */
- *pTime = pSMFData->time >> 8;
-
- *pTime = pSMFData->time >> 8;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * SMF_Event()
- *----------------------------------------------------------------------------
- * Purpose:
- * Parse the next event in the file
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT SMF_Event (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_INT parserMode)
-{
- S_SMF_DATA* pSMFData;
- EAS_RESULT result;
- EAS_I32 i;
- EAS_U32 ticks;
- EAS_U32 temp;
-
- /* establish pointer to instance data */
- pSMFData = (S_SMF_DATA*) pInstData;
- if (pSMFData->state >= EAS_STATE_OPEN)
- return EAS_SUCCESS;
-
- /* get current ticks */
- ticks = pSMFData->nextStream->ticks;
-
- /* assume that an error occurred */
- pSMFData->state = EAS_STATE_ERROR;
-
-#ifdef JET_INTERFACE
- /* if JET has track muted, set parser mode to mute */
- if (pSMFData->nextStream->midiStream.jetData & MIDI_FLAGS_JET_MUTE)
- parserMode = eParserModeMute;
-#endif
-
- /* parse the next event from all the streams */
- if ((result = SMF_ParseEvent(pEASData, pSMFData, pSMFData->nextStream, parserMode)) != EAS_SUCCESS)
- {
- /* check for unexpected end-of-file */
- if (result != EAS_EOF)
- return result;
-
- /* indicate end of track for this stream */
- pSMFData->nextStream->ticks = SMF_END_OF_TRACK;
- }
-
- /* get next delta time, unless already at end of track */
- else if (pSMFData->nextStream->ticks != SMF_END_OF_TRACK)
- {
- if ((result = SMF_GetDeltaTime(pEASData->hwInstData, pSMFData->nextStream)) != EAS_SUCCESS)
- {
- /* check for unexpected end-of-file */
- if (result != EAS_EOF)
- return result;
-
- /* indicate end of track for this stream */
- pSMFData->nextStream->ticks = SMF_END_OF_TRACK;
- }
-
- /* if zero delta to next event, stay with this stream */
- else if (pSMFData->nextStream->ticks == ticks)
- {
- pSMFData->state = EAS_STATE_PLAY;
- return EAS_SUCCESS;
- }
- }
-
- /* find next event in all streams */
- temp = 0x7ffffff;
- pSMFData->nextStream = NULL;
- for (i = 0; i < pSMFData->numStreams; i++)
- {
- if (pSMFData->streams[i].ticks < temp)
- {
- temp = pSMFData->streams[i].ticks;
- pSMFData->nextStream = &pSMFData->streams[i];
- }
- }
-
- /* are there any more events to parse? */
- if (pSMFData->nextStream)
- {
- pSMFData->state = EAS_STATE_PLAY;
-
- /* update the time of the next event */
- SMF_UpdateTime(pSMFData, pSMFData->nextStream->ticks - ticks);
- }
- else
- {
- pSMFData->state = EAS_STATE_STOPPING;
- VMReleaseAllVoices(pEASData->pVoiceMgr, pSMFData->pSynth);
- }
-
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * SMF_State()
- *----------------------------------------------------------------------------
- * Purpose:
- * Returns the current state of the stream
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- * pState - pointer to variable to store state
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, pEASData) reserved for future use */
-EAS_RESULT SMF_State (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 *pState)
-{
- S_SMF_DATA* pSMFData;
-
- /* establish pointer to instance data */
- pSMFData = (S_SMF_DATA*) pInstData;
-
- /* if stopping, check to see if synth voices are active */
- if (pSMFData->state == EAS_STATE_STOPPING)
- {
- if (VMActiveVoices(pSMFData->pSynth) == 0)
- pSMFData->state = EAS_STATE_STOPPED;
- }
-
- if (pSMFData->state == EAS_STATE_PAUSING)
- {
- if (VMActiveVoices(pSMFData->pSynth) == 0)
- pSMFData->state = EAS_STATE_PAUSED;
- }
-
- /* return current state */
- *pState = pSMFData->state;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * SMF_Close()
- *----------------------------------------------------------------------------
- * Purpose:
- * Close the file and clean up
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT SMF_Close (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
-{
- S_SMF_DATA* pSMFData;
- EAS_I32 i;
- EAS_RESULT result;
-
- pSMFData = (S_SMF_DATA*) pInstData;
-
- /* close all the streams */
- for (i = 0; i < pSMFData->numStreams; i++)
- {
- if (pSMFData->streams[i].fileHandle != NULL)
- {
- if ((result = EAS_HWCloseFile(pEASData->hwInstData, pSMFData->streams[i].fileHandle)) != EAS_SUCCESS)
- return result;
- }
- }
- if (pSMFData->fileHandle != NULL)
- if ((result = EAS_HWCloseFile(pEASData->hwInstData, pSMFData->fileHandle)) != EAS_SUCCESS)
- return result;
-
- /* free the synth */
- if (pSMFData->pSynth != NULL)
- VMMIDIShutdown(pEASData, pSMFData->pSynth);
-
- /* if using dynamic memory, free it */
- if (!pEASData->staticMemoryModel)
- {
- if (pSMFData->streams)
- EAS_HWFree(pEASData->hwInstData, pSMFData->streams);
-
- /* free the instance data */
- EAS_HWFree(pEASData->hwInstData, pSMFData);
- }
-
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * SMF_Reset()
- *----------------------------------------------------------------------------
- * Purpose:
- * Reset the sequencer. Used for locating backwards in the file.
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT SMF_Reset (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
-{
- S_SMF_DATA* pSMFData;
- EAS_I32 i;
- EAS_RESULT result;
- EAS_U32 ticks;
-
- pSMFData = (S_SMF_DATA*) pInstData;
-
- /* reset time to zero */
- pSMFData->time = 0;
-
- /* reset the synth */
- VMReset(pEASData->pVoiceMgr, pSMFData->pSynth, EAS_TRUE);
-
- /* find the start of each track */
- ticks = 0x7fffffffL;
- pSMFData->nextStream = NULL;
- for (i = 0; i < pSMFData->numStreams; i++)
- {
-
- /* reset file position to first byte of data in track */
- if ((result = EAS_HWFileSeek(pEASData->hwInstData, pSMFData->streams[i].fileHandle, pSMFData->streams[i].startFilePos)) != EAS_SUCCESS)
- return result;
-
- /* initalize some data */
- pSMFData->streams[i].ticks = 0;
-
- /* initalize the MIDI parser data */
- EAS_InitMIDIStream(&pSMFData->streams[i].midiStream);
-
- /* parse the first delta time in each stream */
- if ((result = SMF_GetDeltaTime(pEASData->hwInstData,&pSMFData->streams[i])) != EAS_SUCCESS)
- return result;
- if (pSMFData->streams[i].ticks < ticks)
- {
- ticks = pSMFData->streams[i].ticks;
- pSMFData->nextStream = &pSMFData->streams[i];
- }
- }
-
-
- pSMFData->state = EAS_STATE_READY;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * SMF_Pause()
- *----------------------------------------------------------------------------
- * Purpose:
- * Pauses the sequencer. Mutes all voices and sets state to pause.
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT SMF_Pause (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
-{
- S_SMF_DATA *pSMFData;
-
- /* can't pause a stopped stream */
- pSMFData = (S_SMF_DATA*) pInstData;
- if (pSMFData->state == EAS_STATE_STOPPED)
- return EAS_ERROR_ALREADY_STOPPED;
-
- /* mute the synthesizer */
- VMMuteAllVoices(pEASData->pVoiceMgr, pSMFData->pSynth);
- pSMFData->state = EAS_STATE_PAUSING;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * SMF_Resume()
- *----------------------------------------------------------------------------
- * Purpose:
- * Resume playing after a pause, sets state back to playing.
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, pEASData) reserved for future use */
-EAS_RESULT SMF_Resume (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
-{
- S_SMF_DATA *pSMFData;
-
- /* can't resume a stopped stream */
- pSMFData = (S_SMF_DATA*) pInstData;
- if (pSMFData->state == EAS_STATE_STOPPED)
- return EAS_ERROR_ALREADY_STOPPED;
-
- /* nothing to do but resume playback */
- pSMFData->state = EAS_STATE_PLAY;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * SMF_SetData()
- *----------------------------------------------------------------------------
- * Purpose:
- * Sets parser parameters
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, pEASData) reserved for future use */
-EAS_RESULT SMF_SetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value)
-{
- S_SMF_DATA *pSMFData;
-
- pSMFData = (S_SMF_DATA*) pInstData;
- switch (param)
- {
-
- /* set metadata callback */
- case PARSER_DATA_METADATA_CB:
- EAS_HWMemCpy(&pSMFData->metadata, (void*) value, sizeof(S_METADATA_CB));
- break;
-
-#ifdef JET_INTERFACE
- /* set jet segment and track ID of all tracks for callback function */
- case PARSER_DATA_JET_CB:
- {
- EAS_U32 i;
- EAS_U32 bit = (EAS_U32) value;
- bit = (bit << JET_EVENT_SEG_SHIFT) & JET_EVENT_SEG_MASK;
- for (i = 0; i < pSMFData->numStreams; i++)
- pSMFData->streams[i].midiStream.jetData =
- (pSMFData->streams[i].midiStream.jetData &
- ~(JET_EVENT_TRACK_MASK | JET_EVENT_SEG_MASK)) |
- i << JET_EVENT_TRACK_SHIFT | bit | MIDI_FLAGS_JET_CB;
- pSMFData->flags |= SMF_FLAGS_JET_STREAM;
- }
- break;
-
- /* set state of all mute flags at once */
- case PARSER_DATA_MUTE_FLAGS:
- {
- EAS_INT i;
- EAS_U32 bit = (EAS_U32) value;
- for (i = 0; i < pSMFData->numStreams; i++)
- {
- if (bit & 1)
- pSMFData->streams[i].midiStream.jetData |= MIDI_FLAGS_JET_MUTE;
- else
- pSMFData->streams[i].midiStream.jetData &= ~MIDI_FLAGS_JET_MUTE;
- bit >>= 1;
- }
- }
- break;
-
- /* set track mute */
- case PARSER_DATA_SET_MUTE:
- if (value < pSMFData->numStreams)
- pSMFData->streams[value].midiStream.jetData |= MIDI_FLAGS_JET_MUTE;
- else
- return EAS_ERROR_PARAMETER_RANGE;
- break;
-
- /* clear track mute */
- case PARSER_DATA_CLEAR_MUTE:
- if (value < pSMFData->numStreams)
- pSMFData->streams[value].midiStream.jetData &= ~MIDI_FLAGS_JET_MUTE;
- else
- return EAS_ERROR_PARAMETER_RANGE;
- break;
-#endif
-
- default:
- return EAS_ERROR_INVALID_PARAMETER;
- }
-
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * SMF_GetData()
- *----------------------------------------------------------------------------
- * Purpose:
- * Retrieves parser parameters
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, pEASData) reserved for future use */
-EAS_RESULT SMF_GetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue)
-{
- S_SMF_DATA *pSMFData;
-
- pSMFData = (S_SMF_DATA*) pInstData;
- switch (param)
- {
- /* return file type */
- case PARSER_DATA_FILE_TYPE:
- if (pSMFData->numStreams == 1)
- *pValue = EAS_FILE_SMF0;
- else
- *pValue = EAS_FILE_SMF1;
- break;
-
-/* now handled in eas_public.c */
-#if 0
- case PARSER_DATA_POLYPHONY:
- if (pSMFData->pSynth)
- VMGetPolyphony(pEASData->pVoiceMgr, pSMFData->pSynth, pValue);
- else
- return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
- break;
-
- case PARSER_DATA_PRIORITY:
- if (pSMFData->pSynth)
- VMGetPriority(pEASData->pVoiceMgr, pSMFData->pSynth, pValue);
- break;
-
- /* set transposition */
- case PARSER_DATA_TRANSPOSITION:
- *pValue = pSMFData->transposition;
- break;
-#endif
-
- case PARSER_DATA_SYNTH_HANDLE:
- *pValue = (EAS_I32) pSMFData->pSynth;
- break;
-
- default:
- return EAS_ERROR_INVALID_PARAMETER;
- }
-
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * SMF_GetVarLenData()
- *----------------------------------------------------------------------------
- * Purpose:
- * Reads a varible length quantity from an SMF file
- *
- * Inputs:
- *
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT SMF_GetVarLenData (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE fileHandle, EAS_U32 *pData)
-{
- EAS_RESULT result;
- EAS_U32 data;
- EAS_U8 c;
-
- /* read until bit 7 is zero */
- data = 0;
- do
- {
- if ((result = EAS_HWGetByte(hwInstData, fileHandle,&c)) != EAS_SUCCESS)
- return result;
- data = (data << 7) | (c & 0x7f);
- } while (c & 0x80);
- *pData = data;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * SMF_GetDeltaTime()
- *----------------------------------------------------------------------------
- * Purpose:
- * Reads a varible length quantity from an SMF file
- *
- * Inputs:
- *
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT SMF_GetDeltaTime (EAS_HW_DATA_HANDLE hwInstData, S_SMF_STREAM *pSMFStream)
-{
- EAS_RESULT result;
- EAS_U32 ticks;
-
- if ((result = SMF_GetVarLenData(hwInstData, pSMFStream->fileHandle, &ticks)) != EAS_SUCCESS)
- return result;
-
- pSMFStream->ticks += ticks;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * SMF_ParseMetaEvent()
- *----------------------------------------------------------------------------
- * Purpose:
- * Reads a varible length quantity from an SMF file
- *
- * Inputs:
- *
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT SMF_ParseMetaEvent (S_EAS_DATA *pEASData, S_SMF_DATA *pSMFData, S_SMF_STREAM *pSMFStream)
-{
- EAS_RESULT result;
- EAS_U32 len;
- EAS_I32 pos;
- EAS_U32 temp;
- EAS_U8 c;
-
- /* get the meta-event type */
- if ((result = EAS_HWGetByte(pEASData->hwInstData, pSMFStream->fileHandle, &c)) != EAS_SUCCESS)
- return result;
-
- /* get the length */
- if ((result = SMF_GetVarLenData(pEASData->hwInstData, pSMFStream->fileHandle, &len)) != EAS_SUCCESS)
- return result;
-
- /* get the current file position so we can skip the event */
- if ((result = EAS_HWFilePos(pEASData->hwInstData, pSMFStream->fileHandle, &pos)) != EAS_SUCCESS)
- return result;
- pos += (EAS_I32) len;
-
- /* end of track? */
- if (c == SMF_META_END_OF_TRACK)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Meta-event: end of track\n", c, len); */ }
- pSMFStream->ticks = SMF_END_OF_TRACK;
- }
-
- /* tempo event? */
- else if (c == SMF_META_TEMPO)
- {
- /* read the 3-byte timebase value */
- temp = 0;
- while (len--)
- {
- if ((result = EAS_HWGetByte(pEASData->hwInstData, pSMFStream->fileHandle, &c)) != EAS_SUCCESS)
- return result;
- temp = (temp << 8) | c;
- }
-
- pSMFData->tickConv = (EAS_U16) (((temp * 1024) / pSMFData->ppqn + 500) / 1000);
- pSMFData->flags |= SMF_FLAGS_HAS_TEMPO;
- }
-
- /* check for time signature - see iMelody spec V1.4 section 4.1.2.2.3.6 */
- else if (c == SMF_META_TIME_SIGNATURE)
- {
- pSMFData->flags |= SMF_FLAGS_HAS_TIME_SIG;
- }
-
- /* if the host has registered a metadata callback return the metadata */
- else if (pSMFData->metadata.callback)
- {
- EAS_I32 readLen;
- E_EAS_METADATA_TYPE metaType;
-
- metaType = EAS_METADATA_UNKNOWN;
-
- /* only process title on the first track */
- if (c == SMF_META_SEQTRK_NAME)
- metaType = EAS_METADATA_TITLE;
- else if (c == SMF_META_TEXT)
- metaType = EAS_METADATA_TEXT;
- else if (c == SMF_META_COPYRIGHT)
- metaType = EAS_METADATA_COPYRIGHT;
- else if (c == SMF_META_LYRIC)
- metaType = EAS_METADATA_LYRIC;
-
- if (metaType != EAS_METADATA_UNKNOWN)
- {
- readLen = pSMFData->metadata.bufferSize - 1;
- if ((EAS_I32) len < readLen)
- readLen = (EAS_I32) len;
- if ((result = EAS_HWReadFile(pEASData->hwInstData, pSMFStream->fileHandle, pSMFData->metadata.buffer, readLen, &readLen)) != EAS_SUCCESS)
- return result;
- pSMFData->metadata.buffer[readLen] = 0;
- pSMFData->metadata.callback(metaType, pSMFData->metadata.buffer, pSMFData->metadata.pUserData);
- }
- }
-
- /* position file to next event - in case we ignored all or part of the meta-event */
- if ((result = EAS_HWFileSeek(pEASData->hwInstData, pSMFStream->fileHandle, pos)) != EAS_SUCCESS)
- return result;
-
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Meta-event: type=%02x, len=%d\n", c, len); */ }
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * SMF_ParseSysEx()
- *----------------------------------------------------------------------------
- * Purpose:
- * Reads a varible length quantity from an SMF file
- *
- * Inputs:
- *
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT SMF_ParseSysEx (S_EAS_DATA *pEASData, S_SMF_DATA *pSMFData, S_SMF_STREAM *pSMFStream, EAS_U8 f0, EAS_INT parserMode)
-{
- EAS_RESULT result;
- EAS_U32 len;
- EAS_U8 c;
-
- /* get the length */
- if ((result = SMF_GetVarLenData(pEASData->hwInstData, pSMFStream->fileHandle, &len)) != EAS_SUCCESS)
- return result;
-
- /* start of SysEx message? */
- if (f0 == 0xf0)
- {
- if ((result = EAS_ParseMIDIStream(pEASData, pSMFData->pSynth, &pSMFStream->midiStream, f0, parserMode)) != EAS_SUCCESS)
- return result;
- }
-
- /* feed the SysEx to the stream parser */
- while (len--)
- {
- if ((result = EAS_HWGetByte(pEASData->hwInstData, pSMFStream->fileHandle, &c)) != EAS_SUCCESS)
- return result;
- if ((result = EAS_ParseMIDIStream(pEASData, pSMFData->pSynth, &pSMFStream->midiStream, c, parserMode)) != EAS_SUCCESS)
- return result;
-
- /* check for GM system ON */
- if (pSMFStream->midiStream.flags & MIDI_FLAG_GM_ON)
- pSMFData->flags |= SMF_FLAGS_HAS_GM_ON;
- }
-
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * SMF_ParseEvent()
- *----------------------------------------------------------------------------
- * Purpose:
- * Reads a varible length quantity from an SMF file
- *
- * Inputs:
- *
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT SMF_ParseEvent (S_EAS_DATA *pEASData, S_SMF_DATA *pSMFData, S_SMF_STREAM *pSMFStream, EAS_INT parserMode)
-{
- EAS_RESULT result;
- EAS_U8 c;
-
- /* get the event type */
- if ((result = EAS_HWGetByte(pEASData->hwInstData, pSMFStream->fileHandle, &c)) != EAS_SUCCESS)
- return result;
-
- /* parse meta-event */
- if (c == 0xff)
- {
- if ((result = SMF_ParseMetaEvent(pEASData, pSMFData, pSMFStream)) != EAS_SUCCESS)
- return result;
- }
-
- /* parse SysEx */
- else if ((c == 0xf0) || (c == 0xf7))
- {
- if ((result = SMF_ParseSysEx(pEASData, pSMFData, pSMFStream, c, parserMode)) != EAS_SUCCESS)
- return result;
- }
-
- /* parse MIDI message */
- else
- {
- if ((result = EAS_ParseMIDIStream(pEASData, pSMFData->pSynth, &pSMFStream->midiStream, c, parserMode)) != EAS_SUCCESS)
- return result;
-
- /* keep streaming data to the MIDI parser until the message is complete */
- while (pSMFStream->midiStream.pending)
- {
- if ((result = EAS_HWGetByte(pEASData->hwInstData, pSMFStream->fileHandle, &c)) != EAS_SUCCESS)
- return result;
- if ((result = EAS_ParseMIDIStream(pEASData, pSMFData->pSynth, &pSMFStream->midiStream, c, parserMode)) != EAS_SUCCESS)
- return result;
- }
-
- }
-
- /* chase mode logic */
- if (pSMFData->time == 0)
- {
- if (pSMFData->flags & SMF_FLAGS_CHASE_MODE)
- {
- if (pSMFStream->midiStream.flags & MIDI_FLAG_FIRST_NOTE)
- pSMFData->flags &= ~SMF_FLAGS_CHASE_MODE;
- }
- else if ((pSMFData->flags & SMF_FLAGS_SETUP_BAR) == SMF_FLAGS_SETUP_BAR)
- pSMFData->flags = (pSMFData->flags & ~SMF_FLAGS_SETUP_BAR) | SMF_FLAGS_CHASE_MODE;
- }
-
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * SMF_ParseHeader()
- *----------------------------------------------------------------------------
- * Purpose:
- * Parses the header of an SMF file, allocates memory the stream parsers and initializes the
- * stream parsers.
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * pSMFData - pointer to parser instance data
- * fileHandle - file handle
- * fileOffset - offset in the file where the header data starts, usually 0
- *
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -e{801} we know that 'goto' is deprecated - but it's cleaner in this case */
-EAS_RESULT SMF_ParseHeader (EAS_HW_DATA_HANDLE hwInstData, S_SMF_DATA *pSMFData)
-{
- EAS_RESULT result;
- EAS_I32 i;
- EAS_U16 division;
- EAS_U32 chunkSize;
- EAS_U32 chunkStart;
- EAS_U32 temp;
- EAS_U32 ticks;
-
- /* rewind the file and find the end of the header chunk */
- if ((result = EAS_HWFileSeek(hwInstData, pSMFData->fileHandle, pSMFData->fileOffset + SMF_OFS_HEADER_SIZE)) != EAS_SUCCESS)
- goto ReadError;
- if ((result = EAS_HWGetDWord(hwInstData, pSMFData->fileHandle, &chunkSize, EAS_TRUE)) != EAS_SUCCESS)
- goto ReadError;
-
- /* determine the number of tracks */
- if ((result = EAS_HWFileSeek(hwInstData, pSMFData->fileHandle, pSMFData->fileOffset + SMF_OFS_NUM_TRACKS)) != EAS_SUCCESS)
- goto ReadError;
- if ((result = EAS_HWGetWord(hwInstData, pSMFData->fileHandle, &pSMFData->numStreams, EAS_TRUE)) != EAS_SUCCESS)
- goto ReadError;
-
- /* limit the number of tracks */
- if (pSMFData->numStreams > MAX_SMF_STREAMS)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "SMF file contains %u tracks, playing %d tracks\n", pSMFData->numStreams, MAX_SMF_STREAMS); */ }
- pSMFData->numStreams = MAX_SMF_STREAMS;
- }
-
- /* get the time division */
- if ((result = EAS_HWGetWord(hwInstData, pSMFData->fileHandle, &division, EAS_TRUE)) != EAS_SUCCESS)
- goto ReadError;
-
- /* setup default timebase for 120 bpm */
- pSMFData->ppqn = 192;
- if (division & 0x8000)
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING,"No support for SMPTE code timebase\n"); */ }
- else
- pSMFData->ppqn = (division & 0x7fff);
- pSMFData->tickConv = (EAS_U16) (((SMF_DEFAULT_TIMEBASE * 1024) / pSMFData->ppqn + 500) / 1000);
-
- /* dynamic memory allocation, allocate memory for streams */
- if (pSMFData->streams == NULL)
- {
- pSMFData->streams = EAS_HWMalloc(hwInstData,sizeof(S_SMF_STREAM) * pSMFData->numStreams);
- if (pSMFData->streams == NULL)
- return EAS_ERROR_MALLOC_FAILED;
-
- /* zero the memory to insure complete initialization */
- EAS_HWMemSet((void *)(pSMFData->streams), 0, sizeof(S_SMF_STREAM) * pSMFData->numStreams);
- }
-
- /* find the start of each track */
- chunkStart = (EAS_U32) pSMFData->fileOffset;
- ticks = 0x7fffffffL;
- pSMFData->nextStream = NULL;
- for (i = 0; i < pSMFData->numStreams; i++)
- {
-
- for (;;)
- {
-
- /* calculate start of next chunk - checking for errors */
- temp = chunkStart + SMF_CHUNK_INFO_SIZE + chunkSize;
- if (temp <= chunkStart)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING,"Error in chunk size at offset %d\n", chunkStart); */ }
- return EAS_ERROR_FILE_FORMAT;
- }
- chunkStart = temp;
-
- /* seek to the start of the next chunk */
- if ((result = EAS_HWFileSeek(hwInstData, pSMFData->fileHandle, (EAS_I32) chunkStart)) != EAS_SUCCESS)
- goto ReadError;
-
- /* read the chunk identifier */
- if ((result = EAS_HWGetDWord(hwInstData, pSMFData->fileHandle, &temp, EAS_TRUE)) != EAS_SUCCESS)
- goto ReadError;
-
- /* read the chunk size */
- if ((result = EAS_HWGetDWord(hwInstData, pSMFData->fileHandle, &chunkSize, EAS_TRUE)) != EAS_SUCCESS)
- goto ReadError;
-
- /* make sure this is an 'MTrk' chunk */
- if (temp == SMF_CHUNK_TYPE_TRACK)
- break;
-
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING,"Unexpected chunk type: 0x%08x\n", temp); */ }
- }
-
- /* initalize some data */
- pSMFData->streams[i].ticks = 0;
- pSMFData->streams[i].fileHandle = pSMFData->fileHandle;
-
- /* NULL the file handle so we don't try to close it twice */
- pSMFData->fileHandle = NULL;
-
- /* save this file position as the start of the track */
- pSMFData->streams[i].startFilePos = (EAS_I32) chunkStart + SMF_CHUNK_INFO_SIZE;
-
- /* initalize the MIDI parser data */
- EAS_InitMIDIStream(&pSMFData->streams[i].midiStream);
-
- /* parse the first delta time in each stream */
- if ((result = SMF_GetDeltaTime(hwInstData, &pSMFData->streams[i])) != EAS_SUCCESS)
- goto ReadError;
-
- if (pSMFData->streams[i].ticks < ticks)
- {
- ticks = pSMFData->streams[i].ticks;
- pSMFData->nextStream = &pSMFData->streams[i];
- }
-
- /* more tracks to do, create a duplicate file handle */
- if (i < (pSMFData->numStreams - 1))
- {
- if ((result = EAS_HWDupHandle(hwInstData, pSMFData->streams[i].fileHandle, &pSMFData->fileHandle)) != EAS_SUCCESS)
- goto ReadError;
- }
- }
-
- /* update the time of the next event */
- if (pSMFData->nextStream)
- SMF_UpdateTime(pSMFData, pSMFData->nextStream->ticks);
-
- return EAS_SUCCESS;
-
- /* ugly goto: but simpler than structured */
- ReadError:
- if (result == EAS_EOF)
- return EAS_ERROR_FILE_FORMAT;
- return result;
-}
-
-/*----------------------------------------------------------------------------
- * SMF_UpdateTime()
- *----------------------------------------------------------------------------
- * Purpose:
- * Update the millisecond time base by converting the ticks into millieconds
- *
- * Inputs:
- *
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static void SMF_UpdateTime (S_SMF_DATA *pSMFData, EAS_U32 ticks)
-{
- EAS_U32 temp1, temp2;
-
- if (pSMFData->flags & SMF_FLAGS_CHASE_MODE)
- return;
-
- temp1 = (ticks >> 10) * pSMFData->tickConv;
- temp2 = (ticks & 0x3ff) * pSMFData->tickConv;
- pSMFData->time += (EAS_I32)((temp1 << 8) + (temp2 >> 2));
-}
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 803 $
+ * $Date: 2007-08-01 09:57:00 -0700 (Wed, 01 Aug 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+#include "eas_data.h"
+#include "eas_miditypes.h"
+#include "eas_parser.h"
+#include "eas_report.h"
+#include "eas_host.h"
+#include "eas_midi.h"
+#include "eas_config.h"
+#include "eas_vm_protos.h"
+#include "eas_smfdata.h"
+#include "eas_smf.h"
+
+#ifdef JET_INTERFACE
+#include "jet_data.h"
+#endif
+
+//3 dls: The timebase for this module is adequate to keep MIDI and
+//3 digital audio synchronized for only a few minutes. It should be
+//3 sufficient for most mobile applications. If better accuracy is
+//3 required, more fractional bits should be added to the timebase.
+
+static const EAS_U8 smfHeader[] = { 'M', 'T', 'h', 'd' };
+
+/* local prototypes */
+static EAS_RESULT SMF_GetVarLenData (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE fileHandle, EAS_U32 *pData);
+static EAS_RESULT SMF_ParseMetaEvent (S_EAS_DATA *pEASData, S_SMF_DATA *pSMFData, S_SMF_STREAM *pSMFStream);
+static EAS_RESULT SMF_ParseSysEx (S_EAS_DATA *pEASData, S_SMF_DATA *pSMFData, S_SMF_STREAM *pSMFStream, EAS_U8 f0, EAS_INT parserMode);
+static EAS_RESULT SMF_ParseEvent (S_EAS_DATA *pEASData, S_SMF_DATA *pSMFData, S_SMF_STREAM *pSMFStream, EAS_INT parserMode);
+static EAS_RESULT SMF_GetDeltaTime (EAS_HW_DATA_HANDLE hwInstData, S_SMF_STREAM *pSMFStream);
+static void SMF_UpdateTime (S_SMF_DATA *pSMFData, EAS_U32 ticks);
+
+
+/*----------------------------------------------------------------------------
+ *
+ * SMF_Parser
+ *
+ * This structure contains the functional interface for the SMF parser
+ *----------------------------------------------------------------------------
+*/
+const S_FILE_PARSER_INTERFACE EAS_SMF_Parser =
+{
+ SMF_CheckFileType,
+ SMF_Prepare,
+ SMF_Time,
+ SMF_Event,
+ SMF_State,
+ SMF_Close,
+ SMF_Reset,
+ SMF_Pause,
+ SMF_Resume,
+ NULL,
+ SMF_SetData,
+ SMF_GetData,
+ NULL
+};
+
+/*----------------------------------------------------------------------------
+ * SMF_CheckFileType()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Check the file type to see if we can parse it
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT SMF_CheckFileType (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle, EAS_VOID_PTR *ppHandle, EAS_I32 offset)
+{
+ S_SMF_DATA* pSMFData;
+ EAS_RESULT result;
+
+ /* seek to starting offset - usually 0 */
+ *ppHandle = NULL;
+ if ((result = EAS_HWFileSeek(pEASData->hwInstData, fileHandle, offset)) != EAS_SUCCESS)
+ return result;
+
+ /* search through file for header - slow method */
+ if (pEASData->searchHeaderFlag)
+ {
+ result = EAS_SearchFile(pEASData, fileHandle, smfHeader, sizeof(smfHeader), &offset);
+ if (result != EAS_SUCCESS)
+ return (result == EAS_EOF) ? EAS_SUCCESS : result;
+ }
+
+ /* read the first 4 bytes of the file - quick method */
+ else {
+ EAS_U8 header[4];
+ EAS_I32 count;
+ if ((result = EAS_HWReadFile(pEASData->hwInstData, fileHandle, header, sizeof(header), &count)) != EAS_SUCCESS)
+ return result;
+
+ /* check for 'MTrk' - return if no match */
+ if ((header[0] != 'M') || (header[1] != 'T') || (header[2] != 'h') || (header[3] != 'd'))
+ return EAS_SUCCESS;
+ }
+
+ /* check for static memory allocation */
+ if (pEASData->staticMemoryModel)
+ pSMFData = EAS_CMEnumData(EAS_CM_SMF_DATA);
+ else
+ {
+ pSMFData = EAS_HWMalloc(pEASData->hwInstData, sizeof(S_SMF_DATA));
+ EAS_HWMemSet((void *)pSMFData,0, sizeof(S_SMF_DATA));
+ }
+ if (!pSMFData)
+ return EAS_ERROR_MALLOC_FAILED;
+
+ /* initialize some critical data */
+ pSMFData->fileHandle = fileHandle;
+ pSMFData->fileOffset = offset;
+ pSMFData->pSynth = NULL;
+ pSMFData->time = 0;
+ pSMFData->state = EAS_STATE_OPEN;
+ *ppHandle = pSMFData;
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * SMF_Prepare()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Prepare to parse the file. Allocates instance data (or uses static allocation for
+ * static memory model).
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT SMF_Prepare (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
+{
+ S_SMF_DATA* pSMFData;
+ EAS_RESULT result;
+
+ /* check for valid state */
+ pSMFData = (S_SMF_DATA *) pInstData;
+ if (pSMFData->state != EAS_STATE_OPEN)
+ return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
+
+ /* instantiate a synthesizer */
+ if ((result = VMInitMIDI(pEASData, &pSMFData->pSynth)) != EAS_SUCCESS)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "VMInitMIDI returned %d\n", result); */ }
+ return result;
+ }
+
+ /* parse the file header and setup the individual stream parsers */
+ if ((result = SMF_ParseHeader(pEASData->hwInstData, pSMFData)) != EAS_SUCCESS)
+ return result;
+
+ /* ready to play */
+ pSMFData->state = EAS_STATE_READY;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * SMF_Time()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Returns the time of the next event in msecs
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ * pTime - pointer to variable to hold time of next event (in msecs)
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pEASData) reserved for future use */
+EAS_RESULT SMF_Time (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_U32 *pTime)
+{
+ S_SMF_DATA *pSMFData;
+
+ pSMFData = (S_SMF_DATA*) pInstData;
+
+ /* sanity check */
+#ifdef _CHECKED_BUILD
+ if (pSMFData->state == EAS_STATE_STOPPED)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Can't ask for time on a stopped stream\n"); */ }
+ }
+
+ if (pSMFData->nextStream == NULL)
+ {
+ { /* dpp: EAS_ReportEx( _EAS_SEVERITY_ERROR, "no is NULL\n"); */ }
+ }
+#endif
+
+#if 0
+ /* return time in milliseconds */
+ /* if chase mode, lie about time */
+ if (pSMFData->flags & SMF_FLAGS_CHASE_MODE)
+ *pTime = 0;
+
+ else
+#endif
+
+ /*lint -e{704} use shift instead of division */
+ *pTime = pSMFData->time >> 8;
+
+ *pTime = pSMFData->time >> 8;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * SMF_Event()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Parse the next event in the file
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT SMF_Event (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_INT parserMode)
+{
+ S_SMF_DATA* pSMFData;
+ EAS_RESULT result;
+ EAS_I32 i;
+ EAS_U32 ticks;
+ EAS_U32 temp;
+
+ /* establish pointer to instance data */
+ pSMFData = (S_SMF_DATA*) pInstData;
+ if (pSMFData->state >= EAS_STATE_OPEN)
+ return EAS_SUCCESS;
+
+ /* get current ticks */
+ ticks = pSMFData->nextStream->ticks;
+
+ /* assume that an error occurred */
+ pSMFData->state = EAS_STATE_ERROR;
+
+#ifdef JET_INTERFACE
+ /* if JET has track muted, set parser mode to mute */
+ if (pSMFData->nextStream->midiStream.jetData & MIDI_FLAGS_JET_MUTE)
+ parserMode = eParserModeMute;
+#endif
+
+ /* parse the next event from all the streams */
+ if ((result = SMF_ParseEvent(pEASData, pSMFData, pSMFData->nextStream, parserMode)) != EAS_SUCCESS)
+ {
+ /* check for unexpected end-of-file */
+ if (result != EAS_EOF)
+ return result;
+
+ /* indicate end of track for this stream */
+ pSMFData->nextStream->ticks = SMF_END_OF_TRACK;
+ }
+
+ /* get next delta time, unless already at end of track */
+ else if (pSMFData->nextStream->ticks != SMF_END_OF_TRACK)
+ {
+ if ((result = SMF_GetDeltaTime(pEASData->hwInstData, pSMFData->nextStream)) != EAS_SUCCESS)
+ {
+ /* check for unexpected end-of-file */
+ if (result != EAS_EOF)
+ return result;
+
+ /* indicate end of track for this stream */
+ pSMFData->nextStream->ticks = SMF_END_OF_TRACK;
+ }
+
+ /* if zero delta to next event, stay with this stream */
+ else if (pSMFData->nextStream->ticks == ticks)
+ {
+ pSMFData->state = EAS_STATE_PLAY;
+ return EAS_SUCCESS;
+ }
+ }
+
+ /* find next event in all streams */
+ temp = 0x7ffffff;
+ pSMFData->nextStream = NULL;
+ for (i = 0; i < pSMFData->numStreams; i++)
+ {
+ if (pSMFData->streams[i].ticks < temp)
+ {
+ temp = pSMFData->streams[i].ticks;
+ pSMFData->nextStream = &pSMFData->streams[i];
+ }
+ }
+
+ /* are there any more events to parse? */
+ if (pSMFData->nextStream)
+ {
+ pSMFData->state = EAS_STATE_PLAY;
+
+ /* update the time of the next event */
+ SMF_UpdateTime(pSMFData, pSMFData->nextStream->ticks - ticks);
+ }
+ else
+ {
+ pSMFData->state = EAS_STATE_STOPPING;
+ VMReleaseAllVoices(pEASData->pVoiceMgr, pSMFData->pSynth);
+ }
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * SMF_State()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Returns the current state of the stream
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ * pState - pointer to variable to store state
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pEASData) reserved for future use */
+EAS_RESULT SMF_State (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 *pState)
+{
+ S_SMF_DATA* pSMFData;
+
+ /* establish pointer to instance data */
+ pSMFData = (S_SMF_DATA*) pInstData;
+
+ /* if stopping, check to see if synth voices are active */
+ if (pSMFData->state == EAS_STATE_STOPPING)
+ {
+ if (VMActiveVoices(pSMFData->pSynth) == 0)
+ pSMFData->state = EAS_STATE_STOPPED;
+ }
+
+ if (pSMFData->state == EAS_STATE_PAUSING)
+ {
+ if (VMActiveVoices(pSMFData->pSynth) == 0)
+ pSMFData->state = EAS_STATE_PAUSED;
+ }
+
+ /* return current state */
+ *pState = pSMFData->state;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * SMF_Close()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Close the file and clean up
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT SMF_Close (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
+{
+ S_SMF_DATA* pSMFData;
+ EAS_I32 i;
+ EAS_RESULT result;
+
+ pSMFData = (S_SMF_DATA*) pInstData;
+
+ /* close all the streams */
+ for (i = 0; i < pSMFData->numStreams; i++)
+ {
+ if (pSMFData->streams[i].fileHandle != NULL)
+ {
+ if ((result = EAS_HWCloseFile(pEASData->hwInstData, pSMFData->streams[i].fileHandle)) != EAS_SUCCESS)
+ return result;
+ }
+ }
+ if (pSMFData->fileHandle != NULL)
+ if ((result = EAS_HWCloseFile(pEASData->hwInstData, pSMFData->fileHandle)) != EAS_SUCCESS)
+ return result;
+
+ /* free the synth */
+ if (pSMFData->pSynth != NULL)
+ VMMIDIShutdown(pEASData, pSMFData->pSynth);
+
+ /* if using dynamic memory, free it */
+ if (!pEASData->staticMemoryModel)
+ {
+ if (pSMFData->streams)
+ EAS_HWFree(pEASData->hwInstData, pSMFData->streams);
+
+ /* free the instance data */
+ EAS_HWFree(pEASData->hwInstData, pSMFData);
+ }
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * SMF_Reset()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Reset the sequencer. Used for locating backwards in the file.
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT SMF_Reset (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
+{
+ S_SMF_DATA* pSMFData;
+ EAS_I32 i;
+ EAS_RESULT result;
+ EAS_U32 ticks;
+
+ pSMFData = (S_SMF_DATA*) pInstData;
+
+ /* reset time to zero */
+ pSMFData->time = 0;
+
+ /* reset the synth */
+ VMReset(pEASData->pVoiceMgr, pSMFData->pSynth, EAS_TRUE);
+
+ /* find the start of each track */
+ ticks = 0x7fffffffL;
+ pSMFData->nextStream = NULL;
+ for (i = 0; i < pSMFData->numStreams; i++)
+ {
+
+ /* reset file position to first byte of data in track */
+ if ((result = EAS_HWFileSeek(pEASData->hwInstData, pSMFData->streams[i].fileHandle, pSMFData->streams[i].startFilePos)) != EAS_SUCCESS)
+ return result;
+
+ /* initalize some data */
+ pSMFData->streams[i].ticks = 0;
+
+ /* initalize the MIDI parser data */
+ EAS_InitMIDIStream(&pSMFData->streams[i].midiStream);
+
+ /* parse the first delta time in each stream */
+ if ((result = SMF_GetDeltaTime(pEASData->hwInstData,&pSMFData->streams[i])) != EAS_SUCCESS)
+ return result;
+ if (pSMFData->streams[i].ticks < ticks)
+ {
+ ticks = pSMFData->streams[i].ticks;
+ pSMFData->nextStream = &pSMFData->streams[i];
+ }
+ }
+
+
+ pSMFData->state = EAS_STATE_READY;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * SMF_Pause()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Pauses the sequencer. Mutes all voices and sets state to pause.
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT SMF_Pause (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
+{
+ S_SMF_DATA *pSMFData;
+
+ /* can't pause a stopped stream */
+ pSMFData = (S_SMF_DATA*) pInstData;
+ if (pSMFData->state == EAS_STATE_STOPPED)
+ return EAS_ERROR_ALREADY_STOPPED;
+
+ /* mute the synthesizer */
+ VMMuteAllVoices(pEASData->pVoiceMgr, pSMFData->pSynth);
+ pSMFData->state = EAS_STATE_PAUSING;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * SMF_Resume()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Resume playing after a pause, sets state back to playing.
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pEASData) reserved for future use */
+EAS_RESULT SMF_Resume (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
+{
+ S_SMF_DATA *pSMFData;
+
+ /* can't resume a stopped stream */
+ pSMFData = (S_SMF_DATA*) pInstData;
+ if (pSMFData->state == EAS_STATE_STOPPED)
+ return EAS_ERROR_ALREADY_STOPPED;
+
+ /* nothing to do but resume playback */
+ pSMFData->state = EAS_STATE_PLAY;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * SMF_SetData()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Sets parser parameters
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pEASData) reserved for future use */
+EAS_RESULT SMF_SetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value)
+{
+ S_SMF_DATA *pSMFData;
+
+ pSMFData = (S_SMF_DATA*) pInstData;
+ switch (param)
+ {
+
+ /* set metadata callback */
+ case PARSER_DATA_METADATA_CB:
+ EAS_HWMemCpy(&pSMFData->metadata, (void*) value, sizeof(S_METADATA_CB));
+ break;
+
+#ifdef JET_INTERFACE
+ /* set jet segment and track ID of all tracks for callback function */
+ case PARSER_DATA_JET_CB:
+ {
+ EAS_U32 i;
+ EAS_U32 bit = (EAS_U32) value;
+ bit = (bit << JET_EVENT_SEG_SHIFT) & JET_EVENT_SEG_MASK;
+ for (i = 0; i < pSMFData->numStreams; i++)
+ pSMFData->streams[i].midiStream.jetData =
+ (pSMFData->streams[i].midiStream.jetData &
+ ~(JET_EVENT_TRACK_MASK | JET_EVENT_SEG_MASK)) |
+ i << JET_EVENT_TRACK_SHIFT | bit | MIDI_FLAGS_JET_CB;
+ pSMFData->flags |= SMF_FLAGS_JET_STREAM;
+ }
+ break;
+
+ /* set state of all mute flags at once */
+ case PARSER_DATA_MUTE_FLAGS:
+ {
+ EAS_INT i;
+ EAS_U32 bit = (EAS_U32) value;
+ for (i = 0; i < pSMFData->numStreams; i++)
+ {
+ if (bit & 1)
+ pSMFData->streams[i].midiStream.jetData |= MIDI_FLAGS_JET_MUTE;
+ else
+ pSMFData->streams[i].midiStream.jetData &= ~MIDI_FLAGS_JET_MUTE;
+ bit >>= 1;
+ }
+ }
+ break;
+
+ /* set track mute */
+ case PARSER_DATA_SET_MUTE:
+ if (value < pSMFData->numStreams)
+ pSMFData->streams[value].midiStream.jetData |= MIDI_FLAGS_JET_MUTE;
+ else
+ return EAS_ERROR_PARAMETER_RANGE;
+ break;
+
+ /* clear track mute */
+ case PARSER_DATA_CLEAR_MUTE:
+ if (value < pSMFData->numStreams)
+ pSMFData->streams[value].midiStream.jetData &= ~MIDI_FLAGS_JET_MUTE;
+ else
+ return EAS_ERROR_PARAMETER_RANGE;
+ break;
+#endif
+
+ default:
+ return EAS_ERROR_INVALID_PARAMETER;
+ }
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * SMF_GetData()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Retrieves parser parameters
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pEASData) reserved for future use */
+EAS_RESULT SMF_GetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue)
+{
+ S_SMF_DATA *pSMFData;
+
+ pSMFData = (S_SMF_DATA*) pInstData;
+ switch (param)
+ {
+ /* return file type */
+ case PARSER_DATA_FILE_TYPE:
+ if (pSMFData->numStreams == 1)
+ *pValue = EAS_FILE_SMF0;
+ else
+ *pValue = EAS_FILE_SMF1;
+ break;
+
+/* now handled in eas_public.c */
+#if 0
+ case PARSER_DATA_POLYPHONY:
+ if (pSMFData->pSynth)
+ VMGetPolyphony(pEASData->pVoiceMgr, pSMFData->pSynth, pValue);
+ else
+ return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
+ break;
+
+ case PARSER_DATA_PRIORITY:
+ if (pSMFData->pSynth)
+ VMGetPriority(pEASData->pVoiceMgr, pSMFData->pSynth, pValue);
+ break;
+
+ /* set transposition */
+ case PARSER_DATA_TRANSPOSITION:
+ *pValue = pSMFData->transposition;
+ break;
+#endif
+
+ case PARSER_DATA_SYNTH_HANDLE:
+ *pValue = (EAS_I32) pSMFData->pSynth;
+ break;
+
+ default:
+ return EAS_ERROR_INVALID_PARAMETER;
+ }
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * SMF_GetVarLenData()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Reads a varible length quantity from an SMF file
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT SMF_GetVarLenData (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE fileHandle, EAS_U32 *pData)
+{
+ EAS_RESULT result;
+ EAS_U32 data;
+ EAS_U8 c;
+
+ /* read until bit 7 is zero */
+ data = 0;
+ do
+ {
+ if ((result = EAS_HWGetByte(hwInstData, fileHandle,&c)) != EAS_SUCCESS)
+ return result;
+ data = (data << 7) | (c & 0x7f);
+ } while (c & 0x80);
+ *pData = data;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * SMF_GetDeltaTime()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Reads a varible length quantity from an SMF file
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT SMF_GetDeltaTime (EAS_HW_DATA_HANDLE hwInstData, S_SMF_STREAM *pSMFStream)
+{
+ EAS_RESULT result;
+ EAS_U32 ticks;
+
+ if ((result = SMF_GetVarLenData(hwInstData, pSMFStream->fileHandle, &ticks)) != EAS_SUCCESS)
+ return result;
+
+ pSMFStream->ticks += ticks;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * SMF_ParseMetaEvent()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Reads a varible length quantity from an SMF file
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT SMF_ParseMetaEvent (S_EAS_DATA *pEASData, S_SMF_DATA *pSMFData, S_SMF_STREAM *pSMFStream)
+{
+ EAS_RESULT result;
+ EAS_U32 len;
+ EAS_I32 pos;
+ EAS_U32 temp;
+ EAS_U8 c;
+
+ /* get the meta-event type */
+ if ((result = EAS_HWGetByte(pEASData->hwInstData, pSMFStream->fileHandle, &c)) != EAS_SUCCESS)
+ return result;
+
+ /* get the length */
+ if ((result = SMF_GetVarLenData(pEASData->hwInstData, pSMFStream->fileHandle, &len)) != EAS_SUCCESS)
+ return result;
+
+ /* get the current file position so we can skip the event */
+ if ((result = EAS_HWFilePos(pEASData->hwInstData, pSMFStream->fileHandle, &pos)) != EAS_SUCCESS)
+ return result;
+ pos += (EAS_I32) len;
+
+ /* end of track? */
+ if (c == SMF_META_END_OF_TRACK)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Meta-event: end of track\n", c, len); */ }
+ pSMFStream->ticks = SMF_END_OF_TRACK;
+ }
+
+ /* tempo event? */
+ else if (c == SMF_META_TEMPO)
+ {
+ /* read the 3-byte timebase value */
+ temp = 0;
+ while (len--)
+ {
+ if ((result = EAS_HWGetByte(pEASData->hwInstData, pSMFStream->fileHandle, &c)) != EAS_SUCCESS)
+ return result;
+ temp = (temp << 8) | c;
+ }
+
+ pSMFData->tickConv = (EAS_U16) (((temp * 1024) / pSMFData->ppqn + 500) / 1000);
+ pSMFData->flags |= SMF_FLAGS_HAS_TEMPO;
+ }
+
+ /* check for time signature - see iMelody spec V1.4 section 4.1.2.2.3.6 */
+ else if (c == SMF_META_TIME_SIGNATURE)
+ {
+ pSMFData->flags |= SMF_FLAGS_HAS_TIME_SIG;
+ }
+
+ /* if the host has registered a metadata callback return the metadata */
+ else if (pSMFData->metadata.callback)
+ {
+ EAS_I32 readLen;
+ E_EAS_METADATA_TYPE metaType;
+
+ metaType = EAS_METADATA_UNKNOWN;
+
+ /* only process title on the first track */
+ if (c == SMF_META_SEQTRK_NAME)
+ metaType = EAS_METADATA_TITLE;
+ else if (c == SMF_META_TEXT)
+ metaType = EAS_METADATA_TEXT;
+ else if (c == SMF_META_COPYRIGHT)
+ metaType = EAS_METADATA_COPYRIGHT;
+ else if (c == SMF_META_LYRIC)
+ metaType = EAS_METADATA_LYRIC;
+
+ if (metaType != EAS_METADATA_UNKNOWN)
+ {
+ readLen = pSMFData->metadata.bufferSize - 1;
+ if ((EAS_I32) len < readLen)
+ readLen = (EAS_I32) len;
+ if ((result = EAS_HWReadFile(pEASData->hwInstData, pSMFStream->fileHandle, pSMFData->metadata.buffer, readLen, &readLen)) != EAS_SUCCESS)
+ return result;
+ pSMFData->metadata.buffer[readLen] = 0;
+ pSMFData->metadata.callback(metaType, pSMFData->metadata.buffer, pSMFData->metadata.pUserData);
+ }
+ }
+
+ /* position file to next event - in case we ignored all or part of the meta-event */
+ if ((result = EAS_HWFileSeek(pEASData->hwInstData, pSMFStream->fileHandle, pos)) != EAS_SUCCESS)
+ return result;
+
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Meta-event: type=%02x, len=%d\n", c, len); */ }
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * SMF_ParseSysEx()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Reads a varible length quantity from an SMF file
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT SMF_ParseSysEx (S_EAS_DATA *pEASData, S_SMF_DATA *pSMFData, S_SMF_STREAM *pSMFStream, EAS_U8 f0, EAS_INT parserMode)
+{
+ EAS_RESULT result;
+ EAS_U32 len;
+ EAS_U8 c;
+
+ /* get the length */
+ if ((result = SMF_GetVarLenData(pEASData->hwInstData, pSMFStream->fileHandle, &len)) != EAS_SUCCESS)
+ return result;
+
+ /* start of SysEx message? */
+ if (f0 == 0xf0)
+ {
+ if ((result = EAS_ParseMIDIStream(pEASData, pSMFData->pSynth, &pSMFStream->midiStream, f0, parserMode)) != EAS_SUCCESS)
+ return result;
+ }
+
+ /* feed the SysEx to the stream parser */
+ while (len--)
+ {
+ if ((result = EAS_HWGetByte(pEASData->hwInstData, pSMFStream->fileHandle, &c)) != EAS_SUCCESS)
+ return result;
+ if ((result = EAS_ParseMIDIStream(pEASData, pSMFData->pSynth, &pSMFStream->midiStream, c, parserMode)) != EAS_SUCCESS)
+ return result;
+
+ /* check for GM system ON */
+ if (pSMFStream->midiStream.flags & MIDI_FLAG_GM_ON)
+ pSMFData->flags |= SMF_FLAGS_HAS_GM_ON;
+ }
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * SMF_ParseEvent()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Reads a varible length quantity from an SMF file
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT SMF_ParseEvent (S_EAS_DATA *pEASData, S_SMF_DATA *pSMFData, S_SMF_STREAM *pSMFStream, EAS_INT parserMode)
+{
+ EAS_RESULT result;
+ EAS_U8 c;
+
+ /* get the event type */
+ if ((result = EAS_HWGetByte(pEASData->hwInstData, pSMFStream->fileHandle, &c)) != EAS_SUCCESS)
+ return result;
+
+ /* parse meta-event */
+ if (c == 0xff)
+ {
+ if ((result = SMF_ParseMetaEvent(pEASData, pSMFData, pSMFStream)) != EAS_SUCCESS)
+ return result;
+ }
+
+ /* parse SysEx */
+ else if ((c == 0xf0) || (c == 0xf7))
+ {
+ if ((result = SMF_ParseSysEx(pEASData, pSMFData, pSMFStream, c, parserMode)) != EAS_SUCCESS)
+ return result;
+ }
+
+ /* parse MIDI message */
+ else
+ {
+ if ((result = EAS_ParseMIDIStream(pEASData, pSMFData->pSynth, &pSMFStream->midiStream, c, parserMode)) != EAS_SUCCESS)
+ return result;
+
+ /* keep streaming data to the MIDI parser until the message is complete */
+ while (pSMFStream->midiStream.pending)
+ {
+ if ((result = EAS_HWGetByte(pEASData->hwInstData, pSMFStream->fileHandle, &c)) != EAS_SUCCESS)
+ return result;
+ if ((result = EAS_ParseMIDIStream(pEASData, pSMFData->pSynth, &pSMFStream->midiStream, c, parserMode)) != EAS_SUCCESS)
+ return result;
+ }
+
+ }
+
+ /* chase mode logic */
+ if (pSMFData->time == 0)
+ {
+ if (pSMFData->flags & SMF_FLAGS_CHASE_MODE)
+ {
+ if (pSMFStream->midiStream.flags & MIDI_FLAG_FIRST_NOTE)
+ pSMFData->flags &= ~SMF_FLAGS_CHASE_MODE;
+ }
+ else if ((pSMFData->flags & SMF_FLAGS_SETUP_BAR) == SMF_FLAGS_SETUP_BAR)
+ pSMFData->flags = (pSMFData->flags & ~SMF_FLAGS_SETUP_BAR) | SMF_FLAGS_CHASE_MODE;
+ }
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * SMF_ParseHeader()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Parses the header of an SMF file, allocates memory the stream parsers and initializes the
+ * stream parsers.
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * pSMFData - pointer to parser instance data
+ * fileHandle - file handle
+ * fileOffset - offset in the file where the header data starts, usually 0
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -e{801} we know that 'goto' is deprecated - but it's cleaner in this case */
+EAS_RESULT SMF_ParseHeader (EAS_HW_DATA_HANDLE hwInstData, S_SMF_DATA *pSMFData)
+{
+ EAS_RESULT result;
+ EAS_I32 i;
+ EAS_U16 division;
+ EAS_U32 chunkSize;
+ EAS_U32 chunkStart;
+ EAS_U32 temp;
+ EAS_U32 ticks;
+
+ /* rewind the file and find the end of the header chunk */
+ if ((result = EAS_HWFileSeek(hwInstData, pSMFData->fileHandle, pSMFData->fileOffset + SMF_OFS_HEADER_SIZE)) != EAS_SUCCESS)
+ goto ReadError;
+ if ((result = EAS_HWGetDWord(hwInstData, pSMFData->fileHandle, &chunkSize, EAS_TRUE)) != EAS_SUCCESS)
+ goto ReadError;
+
+ /* determine the number of tracks */
+ if ((result = EAS_HWFileSeek(hwInstData, pSMFData->fileHandle, pSMFData->fileOffset + SMF_OFS_NUM_TRACKS)) != EAS_SUCCESS)
+ goto ReadError;
+ if ((result = EAS_HWGetWord(hwInstData, pSMFData->fileHandle, &pSMFData->numStreams, EAS_TRUE)) != EAS_SUCCESS)
+ goto ReadError;
+
+ /* limit the number of tracks */
+ if (pSMFData->numStreams > MAX_SMF_STREAMS)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "SMF file contains %u tracks, playing %d tracks\n", pSMFData->numStreams, MAX_SMF_STREAMS); */ }
+ pSMFData->numStreams = MAX_SMF_STREAMS;
+ }
+
+ /* get the time division */
+ if ((result = EAS_HWGetWord(hwInstData, pSMFData->fileHandle, &division, EAS_TRUE)) != EAS_SUCCESS)
+ goto ReadError;
+
+ /* setup default timebase for 120 bpm */
+ pSMFData->ppqn = 192;
+ if (division & 0x8000)
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING,"No support for SMPTE code timebase\n"); */ }
+ else
+ pSMFData->ppqn = (division & 0x7fff);
+ pSMFData->tickConv = (EAS_U16) (((SMF_DEFAULT_TIMEBASE * 1024) / pSMFData->ppqn + 500) / 1000);
+
+ /* dynamic memory allocation, allocate memory for streams */
+ if (pSMFData->streams == NULL)
+ {
+ pSMFData->streams = EAS_HWMalloc(hwInstData,sizeof(S_SMF_STREAM) * pSMFData->numStreams);
+ if (pSMFData->streams == NULL)
+ return EAS_ERROR_MALLOC_FAILED;
+
+ /* zero the memory to insure complete initialization */
+ EAS_HWMemSet((void *)(pSMFData->streams), 0, sizeof(S_SMF_STREAM) * pSMFData->numStreams);
+ }
+
+ /* find the start of each track */
+ chunkStart = (EAS_U32) pSMFData->fileOffset;
+ ticks = 0x7fffffffL;
+ pSMFData->nextStream = NULL;
+ for (i = 0; i < pSMFData->numStreams; i++)
+ {
+
+ for (;;)
+ {
+
+ /* calculate start of next chunk - checking for errors */
+ temp = chunkStart + SMF_CHUNK_INFO_SIZE + chunkSize;
+ if (temp <= chunkStart)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING,"Error in chunk size at offset %d\n", chunkStart); */ }
+ return EAS_ERROR_FILE_FORMAT;
+ }
+ chunkStart = temp;
+
+ /* seek to the start of the next chunk */
+ if ((result = EAS_HWFileSeek(hwInstData, pSMFData->fileHandle, (EAS_I32) chunkStart)) != EAS_SUCCESS)
+ goto ReadError;
+
+ /* read the chunk identifier */
+ if ((result = EAS_HWGetDWord(hwInstData, pSMFData->fileHandle, &temp, EAS_TRUE)) != EAS_SUCCESS)
+ goto ReadError;
+
+ /* read the chunk size */
+ if ((result = EAS_HWGetDWord(hwInstData, pSMFData->fileHandle, &chunkSize, EAS_TRUE)) != EAS_SUCCESS)
+ goto ReadError;
+
+ /* make sure this is an 'MTrk' chunk */
+ if (temp == SMF_CHUNK_TYPE_TRACK)
+ break;
+
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING,"Unexpected chunk type: 0x%08x\n", temp); */ }
+ }
+
+ /* initalize some data */
+ pSMFData->streams[i].ticks = 0;
+ pSMFData->streams[i].fileHandle = pSMFData->fileHandle;
+
+ /* NULL the file handle so we don't try to close it twice */
+ pSMFData->fileHandle = NULL;
+
+ /* save this file position as the start of the track */
+ pSMFData->streams[i].startFilePos = (EAS_I32) chunkStart + SMF_CHUNK_INFO_SIZE;
+
+ /* initalize the MIDI parser data */
+ EAS_InitMIDIStream(&pSMFData->streams[i].midiStream);
+
+ /* parse the first delta time in each stream */
+ if ((result = SMF_GetDeltaTime(hwInstData, &pSMFData->streams[i])) != EAS_SUCCESS)
+ goto ReadError;
+
+ if (pSMFData->streams[i].ticks < ticks)
+ {
+ ticks = pSMFData->streams[i].ticks;
+ pSMFData->nextStream = &pSMFData->streams[i];
+ }
+
+ /* more tracks to do, create a duplicate file handle */
+ if (i < (pSMFData->numStreams - 1))
+ {
+ if ((result = EAS_HWDupHandle(hwInstData, pSMFData->streams[i].fileHandle, &pSMFData->fileHandle)) != EAS_SUCCESS)
+ goto ReadError;
+ }
+ }
+
+ /* update the time of the next event */
+ if (pSMFData->nextStream)
+ SMF_UpdateTime(pSMFData, pSMFData->nextStream->ticks);
+
+ return EAS_SUCCESS;
+
+ /* ugly goto: but simpler than structured */
+ ReadError:
+ if (result == EAS_EOF)
+ return EAS_ERROR_FILE_FORMAT;
+ return result;
+}
+
+/*----------------------------------------------------------------------------
+ * SMF_UpdateTime()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Update the millisecond time base by converting the ticks into millieconds
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static void SMF_UpdateTime (S_SMF_DATA *pSMFData, EAS_U32 ticks)
+{
+ EAS_U32 temp1, temp2;
+
+ if (pSMFData->flags & SMF_FLAGS_CHASE_MODE)
+ return;
+
+ temp1 = (ticks >> 10) * pSMFData->tickConv;
+ temp2 = (ticks & 0x3ff) * pSMFData->tickConv;
+ pSMFData->time += (EAS_I32)((temp1 << 8) + (temp2 >> 2));
+}
+
diff --git a/arm-fm-22k/lib_src/eas_smf.h b/arm-fm-22k/lib_src/eas_smf.h
index 9f66ab9..37c0790 100644
--- a/arm-fm-22k/lib_src/eas_smf.h
+++ b/arm-fm-22k/lib_src/eas_smf.h
@@ -1,12 +1,12 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_smf.h
- *
- * Contents and purpose:
- * SMF Type 0 and 1 File Parser
- *
- * Copyright Sonic Network Inc. 2005
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_smf.h
+ *
+ * Contents and purpose:
+ * SMF Type 0 and 1 File Parser
+ *
+ * Copyright Sonic Network Inc. 2005
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,31 +19,31 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 82 $
- * $Date: 2006-07-10 11:45:19 -0700 (Mon, 10 Jul 2006) $
- *----------------------------------------------------------------------------
-*/
-
-#ifndef _EAS_SMF_H
-#define _EAS_SMF_H
-
-/* prototypes for private interface to SMF parser */
-EAS_RESULT SMF_CheckFileType (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle, EAS_VOID_PTR *ppHandle, EAS_I32 offset);
-EAS_RESULT SMF_Prepare (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
-EAS_RESULT SMF_Time (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_U32 *pTime);
-EAS_RESULT SMF_Event (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_INT parserMode);
-EAS_RESULT SMF_State (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_STATE *pState);
-EAS_RESULT SMF_Close (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
-EAS_RESULT SMF_Reset (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
-EAS_RESULT SMF_Pause (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
-EAS_RESULT SMF_Resume (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
-EAS_RESULT SMF_SetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value);
-EAS_RESULT SMF_GetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue);
-EAS_RESULT SMF_ParseHeader (EAS_HW_DATA_HANDLE hwInstData, S_SMF_DATA *pSMFData);
-
-#endif /* end _EAS_SMF_H */
-
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 82 $
+ * $Date: 2006-07-10 11:45:19 -0700 (Mon, 10 Jul 2006) $
+ *----------------------------------------------------------------------------
+*/
+
+#ifndef _EAS_SMF_H
+#define _EAS_SMF_H
+
+/* prototypes for private interface to SMF parser */
+EAS_RESULT SMF_CheckFileType (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle, EAS_VOID_PTR *ppHandle, EAS_I32 offset);
+EAS_RESULT SMF_Prepare (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
+EAS_RESULT SMF_Time (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_U32 *pTime);
+EAS_RESULT SMF_Event (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_INT parserMode);
+EAS_RESULT SMF_State (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_STATE *pState);
+EAS_RESULT SMF_Close (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
+EAS_RESULT SMF_Reset (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
+EAS_RESULT SMF_Pause (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
+EAS_RESULT SMF_Resume (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
+EAS_RESULT SMF_SetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value);
+EAS_RESULT SMF_GetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue);
+EAS_RESULT SMF_ParseHeader (EAS_HW_DATA_HANDLE hwInstData, S_SMF_DATA *pSMFData);
+
+#endif /* end _EAS_SMF_H */
+
+
diff --git a/arm-fm-22k/lib_src/eas_smfdata.c b/arm-fm-22k/lib_src/eas_smfdata.c
index 5c27551..383d7f3 100644
--- a/arm-fm-22k/lib_src/eas_smfdata.c
+++ b/arm-fm-22k/lib_src/eas_smfdata.c
@@ -1,14 +1,14 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_smfdata.c
- *
- * Contents and purpose:
- * SMF File Parser
- *
- * This file contains data definitions for the SMF parser.
- *
- * Copyright Sonic Network Inc. 2005
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_smfdata.c
+ *
+ * Contents and purpose:
+ * SMF File Parser
+ *
+ * This file contains data definitions for the SMF parser.
+ *
+ * Copyright Sonic Network Inc. 2005
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,46 +21,46 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 778 $
- * $Date: 2007-07-23 16:45:17 -0700 (Mon, 23 Jul 2007) $
- *----------------------------------------------------------------------------
-*/
-
-#include "eas_miditypes.h"
-#include "eas_smfdata.h"
-
-/*----------------------------------------------------------------------------
- *
- * S_SMF_STREAM
- *
- * Static memory allocation for SMF parser
- *----------------------------------------------------------------------------
-*/
-static S_SMF_STREAM eas_SMFStreams[MAX_SMF_STREAMS];
-
-/*----------------------------------------------------------------------------
- *
- * eas_SMFData
- *
- * Static memory allocation for SMF parser
- *----------------------------------------------------------------------------
-*/
-S_SMF_DATA eas_SMFData =
-{
- eas_SMFStreams, /* pointer to individual streams in file */
- 0, /* pointer to next stream with event */
- 0, /* pointer to synth */
- 0, /* file handle */
- { 0, 0, 0, 0}, /* metadata callback */
- 0, /* file offset */
- 0, /* current time in milliseconds/256 */
- 0, /* actual number of streams */
- 0, /* current MIDI tick to msec conversion */
- 0, /* ticks per quarter note */
- 0, /* current state EAS_STATE_XXXX */
- 0 /* flags */
-};
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 778 $
+ * $Date: 2007-07-23 16:45:17 -0700 (Mon, 23 Jul 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+#include "eas_miditypes.h"
+#include "eas_smfdata.h"
+
+/*----------------------------------------------------------------------------
+ *
+ * S_SMF_STREAM
+ *
+ * Static memory allocation for SMF parser
+ *----------------------------------------------------------------------------
+*/
+static S_SMF_STREAM eas_SMFStreams[MAX_SMF_STREAMS];
+
+/*----------------------------------------------------------------------------
+ *
+ * eas_SMFData
+ *
+ * Static memory allocation for SMF parser
+ *----------------------------------------------------------------------------
+*/
+S_SMF_DATA eas_SMFData =
+{
+ eas_SMFStreams, /* pointer to individual streams in file */
+ 0, /* pointer to next stream with event */
+ 0, /* pointer to synth */
+ 0, /* file handle */
+ { 0, 0, 0, 0}, /* metadata callback */
+ 0, /* file offset */
+ 0, /* current time in milliseconds/256 */
+ 0, /* actual number of streams */
+ 0, /* current MIDI tick to msec conversion */
+ 0, /* ticks per quarter note */
+ 0, /* current state EAS_STATE_XXXX */
+ 0 /* flags */
+};
+
diff --git a/arm-fm-22k/lib_src/eas_smfdata.h b/arm-fm-22k/lib_src/eas_smfdata.h
index cf59cdc..8861d90 100644
--- a/arm-fm-22k/lib_src/eas_smfdata.h
+++ b/arm-fm-22k/lib_src/eas_smfdata.h
@@ -1,14 +1,14 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_smfdata.h
- *
- * Contents and purpose:
- * SMF File Parser
- *
- * This file contains data definitions for the SMF parser.
- *
- * Copyright Sonic Network Inc. 2005
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_smfdata.h
+ *
+ * Contents and purpose:
+ * SMF File Parser
+ *
+ * This file contains data definitions for the SMF parser.
+ *
+ * Copyright Sonic Network Inc. 2005
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,46 +21,46 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 686 $
- * $Date: 2007-05-03 14:10:54 -0700 (Thu, 03 May 2007) $
- *----------------------------------------------------------------------------
-*/
-
-#ifndef _EAS_SMF_DATA_H
-#define _EAS_SMF_DATA_H
-
-#ifndef MAX_SMF_STREAMS
-#define MAX_SMF_STREAMS 17
-#endif
-
-/* offsets in to the SMF file */
-#define SMF_OFS_HEADER_SIZE 4
-#define SMF_OFS_FILE_TYPE 8
-#define SMF_OFS_NUM_TRACKS 10
-
-/* size of chunk info (chunk ID + chunk size) */
-#define SMF_CHUNK_INFO_SIZE 8
-
-/* 'MTrk' track chunk ID */
-#define SMF_CHUNK_TYPE_TRACK 0x4d54726bL
-
-/* some useful meta-events */
-#define SMF_META_TEXT 0x01
-#define SMF_META_COPYRIGHT 0x02
-#define SMF_META_SEQTRK_NAME 0x03
-#define SMF_META_LYRIC 0x05
-#define SMF_META_END_OF_TRACK 0x2f
-#define SMF_META_TEMPO 0x51
-#define SMF_META_TIME_SIGNATURE 0x58
-
-/* default timebase (120BPM) */
-#define SMF_DEFAULT_TIMEBASE 500000L
-
-/* value for pSMFStream->ticks to signify end of track */
-#define SMF_END_OF_TRACK 0xffffffff
-
-#endif
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 686 $
+ * $Date: 2007-05-03 14:10:54 -0700 (Thu, 03 May 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+#ifndef _EAS_SMF_DATA_H
+#define _EAS_SMF_DATA_H
+
+#ifndef MAX_SMF_STREAMS
+#define MAX_SMF_STREAMS 17
+#endif
+
+/* offsets in to the SMF file */
+#define SMF_OFS_HEADER_SIZE 4
+#define SMF_OFS_FILE_TYPE 8
+#define SMF_OFS_NUM_TRACKS 10
+
+/* size of chunk info (chunk ID + chunk size) */
+#define SMF_CHUNK_INFO_SIZE 8
+
+/* 'MTrk' track chunk ID */
+#define SMF_CHUNK_TYPE_TRACK 0x4d54726bL
+
+/* some useful meta-events */
+#define SMF_META_TEXT 0x01
+#define SMF_META_COPYRIGHT 0x02
+#define SMF_META_SEQTRK_NAME 0x03
+#define SMF_META_LYRIC 0x05
+#define SMF_META_END_OF_TRACK 0x2f
+#define SMF_META_TEMPO 0x51
+#define SMF_META_TIME_SIGNATURE 0x58
+
+/* default timebase (120BPM) */
+#define SMF_DEFAULT_TIMEBASE 500000L
+
+/* value for pSMFStream->ticks to signify end of track */
+#define SMF_END_OF_TRACK 0xffffffff
+
+#endif
+
diff --git a/arm-fm-22k/lib_src/eas_sndlib.h b/arm-fm-22k/lib_src/eas_sndlib.h
index e05bee0..416be6e 100644
--- a/arm-fm-22k/lib_src/eas_sndlib.h
+++ b/arm-fm-22k/lib_src/eas_sndlib.h
@@ -1,12 +1,12 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_sndlib.h
- *
- * Contents and purpose:
- * Declarations for the sound library
- *
- * Copyright Sonic Network Inc. 2005
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_sndlib.h
+ *
+ * Contents and purpose:
+ * Declarations for the sound library
+ *
+ * Copyright Sonic Network Inc. 2005
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,388 +19,388 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 550 $
- * $Date: 2007-02-02 09:37:03 -0800 (Fri, 02 Feb 2007) $
- *----------------------------------------------------------------------------
-*/
-
-#ifndef _EAS_SNDLIB_H
-#define _EAS_SNDLIB_H
-
-#include "eas_types.h"
-#include "eas_synthcfg.h"
-
-#ifdef _WT_SYNTH
-#include "eas_wtengine.h"
-#endif
-
-/*----------------------------------------------------------------------------
- * This is bit of a hack to allow us to keep the same structure
- * declarations for the DLS parser. Normally, the data is located
- * in read-only memory, but for DLS, we store the data in RW
- * memory.
- *----------------------------------------------------------------------------
-*/
-#ifndef SCNST
-#define SCNST const
-#endif
-
-/*----------------------------------------------------------------------------
- * sample size
- *----------------------------------------------------------------------------
-*/
-#ifdef _16_BIT_SAMPLES
-typedef EAS_I16 EAS_SAMPLE;
-#else
-typedef EAS_I8 EAS_SAMPLE;
-#endif
-
-/*----------------------------------------------------------------------------
- * EAS Library ID - quick check for valid library and version
- *----------------------------------------------------------------------------
-*/
-#define _EAS_LIBRARY_VERSION 0x01534145
-
-#define NUM_PROGRAMS_IN_BANK 128
-#define INVALID_REGION_INDEX 0xffff
-
-/* this bit in region index indicates that region is for secondary synth */
-#define FLAG_RGN_IDX_FM_SYNTH 0x8000
-#define FLAG_RGN_IDX_DLS_SYNTH 0x4000
-#define REGION_INDEX_MASK 0x3fff
-
-/*----------------------------------------------------------------------------
- * Generic region data structure
- *
- * This must be the first element in each region structure
- *----------------------------------------------------------------------------
-*/
-typedef struct s_region_tag
-{
- EAS_U16 keyGroupAndFlags;
- EAS_U8 rangeLow;
- EAS_U8 rangeHigh;
-} S_REGION;
-
-/*
- * Bit fields for m_nKeyGroupAndFlags
- * Bits 0-2 are mode bits in FM synth
- * Bits 8-11 are the key group
- */
-#define REGION_FLAG_IS_LOOPED 0x01
-#define REGION_FLAG_USE_WAVE_GENERATOR 0x02
-#define REGION_FLAG_USE_ADPCM 0x04
-#define REGION_FLAG_ONE_SHOT 0x08
-#define REGION_FLAG_SQUARE_WAVE 0x10
-#define REGION_FLAG_OFF_CHIP 0x20
-#define REGION_FLAG_NON_SELF_EXCLUSIVE 0x40
-#define REGION_FLAG_LAST_REGION 0x8000
-
-/*----------------------------------------------------------------------------
- * Envelope data structure
- *----------------------------------------------------------------------------
-*/
-typedef struct s_envelope_tag
-{
- EAS_I16 attackTime;
- EAS_I16 decayTime;
- EAS_I16 sustainLevel;
- EAS_I16 releaseTime;
-} S_ENVELOPE;
-
-/*----------------------------------------------------------------------------
- * DLS envelope data structure
- *----------------------------------------------------------------------------
-*/
-typedef struct s_dls_envelope_tag
-{
- EAS_I16 delayTime;
- EAS_I16 attackTime;
- EAS_I16 holdTime;
- EAS_I16 decayTime;
- EAS_I16 sustainLevel;
- EAS_I16 releaseTime;
- EAS_I16 velToAttack;
- EAS_I16 keyNumToDecay;
- EAS_I16 keyNumToHold;
-} S_DLS_ENVELOPE;
-
-/*----------------------------------------------------------------------------
- * LFO data structure
- *----------------------------------------------------------------------------
-*/
-typedef struct s_lfo_params_tag
-{
- EAS_I16 lfoFreq;
- EAS_I16 lfoDelay;
-} S_LFO_PARAMS;
-
-/*----------------------------------------------------------------------------
- * Articulation data structure
- *----------------------------------------------------------------------------
-*/
-typedef struct s_articulation_tag
-{
- S_ENVELOPE eg1;
- S_ENVELOPE eg2;
- EAS_I16 lfoToPitch;
- EAS_I16 lfoDelay;
- EAS_I16 lfoFreq;
- EAS_I16 eg2ToPitch;
- EAS_I16 eg2ToFc;
- EAS_I16 filterCutoff;
- EAS_I8 lfoToGain;
- EAS_U8 filterQ;
- EAS_I8 pan;
-} S_ARTICULATION;
-
-/*----------------------------------------------------------------------------
- * DLS articulation data structure
- *----------------------------------------------------------------------------
-*/
-
-typedef struct s_dls_articulation_tag
-{
- S_LFO_PARAMS modLFO;
- S_LFO_PARAMS vibLFO;
-
- S_DLS_ENVELOPE eg1;
- S_DLS_ENVELOPE eg2;
-
- EAS_I16 eg1ShutdownTime;
-
- EAS_I16 filterCutoff;
- EAS_I16 modLFOToFc;
- EAS_I16 modLFOCC1ToFc;
- EAS_I16 modLFOChanPressToFc;
- EAS_I16 eg2ToFc;
- EAS_I16 velToFc;
- EAS_I16 keyNumToFc;
-
- EAS_I16 modLFOToGain;
- EAS_I16 modLFOCC1ToGain;
- EAS_I16 modLFOChanPressToGain;
-
- EAS_I16 tuning;
- EAS_I16 keyNumToPitch;
- EAS_I16 vibLFOToPitch;
- EAS_I16 vibLFOCC1ToPitch;
- EAS_I16 vibLFOChanPressToPitch;
- EAS_I16 modLFOToPitch;
- EAS_I16 modLFOCC1ToPitch;
- EAS_I16 modLFOChanPressToPitch;
- EAS_I16 eg2ToPitch;
-
- /* pad to 4-byte boundary */
- EAS_U16 pad;
-
- EAS_I8 pan;
- EAS_U8 filterQandFlags;
-
-#ifdef _REVERB
- EAS_I16 reverbSend;
- EAS_I16 cc91ToReverbSend;
-#endif
-
-#ifdef _CHORUS
- EAS_I16 chorusSend;
- EAS_I16 cc93ToChorusSend;
-#endif
-} S_DLS_ARTICULATION;
-
-/* flags in filterQandFlags
- * NOTE: Q is stored in bottom 5 bits
- */
-#define FLAG_DLS_VELOCITY_SENSITIVE 0x80
-#define FILTER_Q_MASK 0x1f
-
-/*----------------------------------------------------------------------------
- * Wavetable region data structure
- *----------------------------------------------------------------------------
-*/
-typedef struct s_wt_region_tag
-{
- S_REGION region;
- EAS_I16 tuning;
- EAS_I16 gain;
- EAS_U32 loopStart;
- EAS_U32 loopEnd;
- EAS_U16 waveIndex;
- EAS_U16 artIndex;
-} S_WT_REGION;
-
-/*----------------------------------------------------------------------------
- * DLS region data structure
- *----------------------------------------------------------------------------
-*/
-typedef struct s_dls_region_tag
-{
- S_WT_REGION wtRegion;
- EAS_U8 velLow;
- EAS_U8 velHigh;
-} S_DLS_REGION;
-
-/*----------------------------------------------------------------------------
- * FM synthesizer data structures
- *----------------------------------------------------------------------------
-*/
-typedef struct s_fm_oper_tag
-{
- EAS_I16 tuning;
- EAS_U8 attackDecay;
- EAS_U8 velocityRelease;
- EAS_U8 egKeyScale;
- EAS_U8 sustain;
- EAS_U8 gain;
- EAS_U8 flags;
-} S_FM_OPER;
-
-/* defines for S_FM_OPER.m_nFlags */
-#define FM_OPER_FLAG_MONOTONE 0x01
-#define FM_OPER_FLAG_NO_VIBRATO 0x02
-#define FM_OPER_FLAG_NOISE 0x04
-#define FM_OPER_FLAG_LINEAR_VELOCITY 0x08
-
-/* NOTE: The first two structure elements are common with S_WT_REGION
- * and we will rely on that in the voice management code and must
- * remain there unless the voice management code is revisited.
- */
-typedef struct s_fm_region_tag
-{
- S_REGION region;
- EAS_U8 vibTrem;
- EAS_U8 lfoFreqDelay;
- EAS_U8 feedback;
- EAS_I8 pan;
- S_FM_OPER oper[4];
-} S_FM_REGION;
-
-/*----------------------------------------------------------------------------
- * Common data structures
- *----------------------------------------------------------------------------
-*/
-
-/*----------------------------------------------------------------------------
- * Program data structure
- * Used for individual programs not stored as a complete bank.
- *----------------------------------------------------------------------------
-*/
-typedef struct s_program_tag
-{
- EAS_U32 locale;
- EAS_U16 regionIndex;
-} S_PROGRAM;
-
-/*----------------------------------------------------------------------------
- * Bank data structure
- *
- * A bank always consists of 128 programs. If a bank is less than 128
- * programs, it should be stored as a spare matrix in the pPrograms
- * array.
- *
- * bankNum: MSB/LSB of MIDI bank select controller
- * regionIndex: Index of first region in program
- *----------------------------------------------------------------------------
-*/
-typedef struct s_bank_tag
-{
- EAS_U16 locale;
- EAS_U16 regionIndex[NUM_PROGRAMS_IN_BANK];
-} S_BANK;
-
-
-/* defines for libFormat field
- * bits 0-17 are the sample rate
- * bit 18 is true if wavetable is present
- * bit 19 is true if FM is present
- * bit 20 is true if filter is enabled
- * bit 21 is sample depth (0 = 8-bits, 1 = 16-bits)
- * bits 22-31 are reserved
- */
-#define LIBFORMAT_SAMPLE_RATE_MASK 0x0003ffff
-#define LIB_FORMAT_TYPE_MASK 0x000c0000
-#define LIB_FORMAT_WAVETABLE 0x00000000
-#define LIB_FORMAT_FM 0x00040000
-#define LIB_FORMAT_HYBRID 0x00080000
-#define LIB_FORMAT_FILTER_ENABLED 0x00100000
-#define LIB_FORMAT_16_BIT_SAMPLES 0x00200000
-
-#ifdef DLS_SYNTHESIZER
-/*----------------------------------------------------------------------------
- * DLS data structure
- *
- * pDLSPrograms pointer to array of DLS programs
- * pDLSRegions pointer to array of DLS regions
- * pDLSArticulations pointer to array of DLS articulations
- * pSampleLen pointer to array of sample lengths
- * ppSamples pointer to array of sample pointers
- * numDLSPrograms number of DLS programs
- * numDLSRegions number of DLS regions
- * numDLSArticulations number of DLS articulations
- * numDLSSamples number of DLS samples
- *----------------------------------------------------------------------------
-*/
-typedef struct s_eas_dls_tag
-{
- S_PROGRAM *pDLSPrograms;
- S_DLS_REGION *pDLSRegions;
- S_DLS_ARTICULATION *pDLSArticulations;
- EAS_U32 *pDLSSampleLen;
- EAS_U32 *pDLSSampleOffsets;
- EAS_SAMPLE *pDLSSamples;
- EAS_U16 numDLSPrograms;
- EAS_U16 numDLSRegions;
- EAS_U16 numDLSArticulations;
- EAS_U16 numDLSSamples;
- EAS_U8 refCount;
-} S_DLS;
-#endif
-
-/*----------------------------------------------------------------------------
- * Sound library data structure
- *
- * pBanks pointer to array of banks
- * pPrograms pointer to array of programs
- * pWTRegions pointer to array of wavetable regions
- * pFMRegions pointer to array of FM regions
- * pArticulations pointer to array of articulations
- * pSampleLen pointer to array of sample lengths
- * ppSamples pointer to array of sample pointers
- * numBanks number of banks
- * numPrograms number of individual program
- * numRegions number of regions
- * numArticulations number of articulations
- * numSamples number of samples
- *----------------------------------------------------------------------------
-*/
-typedef struct s_eas_sndlib_tag
-{
- SCNST EAS_U32 identifier;
- SCNST EAS_U32 libAttr;
-
- SCNST S_BANK *pBanks;
- SCNST S_PROGRAM *pPrograms;
-
- SCNST S_WT_REGION *pWTRegions;
- SCNST S_ARTICULATION *pArticulations;
- SCNST EAS_U32 *pSampleLen;
- SCNST EAS_U32 *pSampleOffsets;
- SCNST EAS_SAMPLE *pSamples;
-
- SCNST S_FM_REGION *pFMRegions;
-
- SCNST EAS_U16 numBanks;
- SCNST EAS_U16 numPrograms;
-
- SCNST EAS_U16 numWTRegions;
- SCNST EAS_U16 numArticulations;
- SCNST EAS_U16 numSamples;
-
- SCNST EAS_U16 numFMRegions;
-} S_EAS;
-
-#endif
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 550 $
+ * $Date: 2007-02-02 09:37:03 -0800 (Fri, 02 Feb 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+#ifndef _EAS_SNDLIB_H
+#define _EAS_SNDLIB_H
+
+#include "eas_types.h"
+#include "eas_synthcfg.h"
+
+#ifdef _WT_SYNTH
+#include "eas_wtengine.h"
+#endif
+
+/*----------------------------------------------------------------------------
+ * This is bit of a hack to allow us to keep the same structure
+ * declarations for the DLS parser. Normally, the data is located
+ * in read-only memory, but for DLS, we store the data in RW
+ * memory.
+ *----------------------------------------------------------------------------
+*/
+#ifndef SCNST
+#define SCNST const
+#endif
+
+/*----------------------------------------------------------------------------
+ * sample size
+ *----------------------------------------------------------------------------
+*/
+#ifdef _16_BIT_SAMPLES
+typedef EAS_I16 EAS_SAMPLE;
+#else
+typedef EAS_I8 EAS_SAMPLE;
+#endif
+
+/*----------------------------------------------------------------------------
+ * EAS Library ID - quick check for valid library and version
+ *----------------------------------------------------------------------------
+*/
+#define _EAS_LIBRARY_VERSION 0x01534145
+
+#define NUM_PROGRAMS_IN_BANK 128
+#define INVALID_REGION_INDEX 0xffff
+
+/* this bit in region index indicates that region is for secondary synth */
+#define FLAG_RGN_IDX_FM_SYNTH 0x8000
+#define FLAG_RGN_IDX_DLS_SYNTH 0x4000
+#define REGION_INDEX_MASK 0x3fff
+
+/*----------------------------------------------------------------------------
+ * Generic region data structure
+ *
+ * This must be the first element in each region structure
+ *----------------------------------------------------------------------------
+*/
+typedef struct s_region_tag
+{
+ EAS_U16 keyGroupAndFlags;
+ EAS_U8 rangeLow;
+ EAS_U8 rangeHigh;
+} S_REGION;
+
+/*
+ * Bit fields for m_nKeyGroupAndFlags
+ * Bits 0-2 are mode bits in FM synth
+ * Bits 8-11 are the key group
+ */
+#define REGION_FLAG_IS_LOOPED 0x01
+#define REGION_FLAG_USE_WAVE_GENERATOR 0x02
+#define REGION_FLAG_USE_ADPCM 0x04
+#define REGION_FLAG_ONE_SHOT 0x08
+#define REGION_FLAG_SQUARE_WAVE 0x10
+#define REGION_FLAG_OFF_CHIP 0x20
+#define REGION_FLAG_NON_SELF_EXCLUSIVE 0x40
+#define REGION_FLAG_LAST_REGION 0x8000
+
+/*----------------------------------------------------------------------------
+ * Envelope data structure
+ *----------------------------------------------------------------------------
+*/
+typedef struct s_envelope_tag
+{
+ EAS_I16 attackTime;
+ EAS_I16 decayTime;
+ EAS_I16 sustainLevel;
+ EAS_I16 releaseTime;
+} S_ENVELOPE;
+
+/*----------------------------------------------------------------------------
+ * DLS envelope data structure
+ *----------------------------------------------------------------------------
+*/
+typedef struct s_dls_envelope_tag
+{
+ EAS_I16 delayTime;
+ EAS_I16 attackTime;
+ EAS_I16 holdTime;
+ EAS_I16 decayTime;
+ EAS_I16 sustainLevel;
+ EAS_I16 releaseTime;
+ EAS_I16 velToAttack;
+ EAS_I16 keyNumToDecay;
+ EAS_I16 keyNumToHold;
+} S_DLS_ENVELOPE;
+
+/*----------------------------------------------------------------------------
+ * LFO data structure
+ *----------------------------------------------------------------------------
+*/
+typedef struct s_lfo_params_tag
+{
+ EAS_I16 lfoFreq;
+ EAS_I16 lfoDelay;
+} S_LFO_PARAMS;
+
+/*----------------------------------------------------------------------------
+ * Articulation data structure
+ *----------------------------------------------------------------------------
+*/
+typedef struct s_articulation_tag
+{
+ S_ENVELOPE eg1;
+ S_ENVELOPE eg2;
+ EAS_I16 lfoToPitch;
+ EAS_I16 lfoDelay;
+ EAS_I16 lfoFreq;
+ EAS_I16 eg2ToPitch;
+ EAS_I16 eg2ToFc;
+ EAS_I16 filterCutoff;
+ EAS_I8 lfoToGain;
+ EAS_U8 filterQ;
+ EAS_I8 pan;
+} S_ARTICULATION;
+
+/*----------------------------------------------------------------------------
+ * DLS articulation data structure
+ *----------------------------------------------------------------------------
+*/
+
+typedef struct s_dls_articulation_tag
+{
+ S_LFO_PARAMS modLFO;
+ S_LFO_PARAMS vibLFO;
+
+ S_DLS_ENVELOPE eg1;
+ S_DLS_ENVELOPE eg2;
+
+ EAS_I16 eg1ShutdownTime;
+
+ EAS_I16 filterCutoff;
+ EAS_I16 modLFOToFc;
+ EAS_I16 modLFOCC1ToFc;
+ EAS_I16 modLFOChanPressToFc;
+ EAS_I16 eg2ToFc;
+ EAS_I16 velToFc;
+ EAS_I16 keyNumToFc;
+
+ EAS_I16 modLFOToGain;
+ EAS_I16 modLFOCC1ToGain;
+ EAS_I16 modLFOChanPressToGain;
+
+ EAS_I16 tuning;
+ EAS_I16 keyNumToPitch;
+ EAS_I16 vibLFOToPitch;
+ EAS_I16 vibLFOCC1ToPitch;
+ EAS_I16 vibLFOChanPressToPitch;
+ EAS_I16 modLFOToPitch;
+ EAS_I16 modLFOCC1ToPitch;
+ EAS_I16 modLFOChanPressToPitch;
+ EAS_I16 eg2ToPitch;
+
+ /* pad to 4-byte boundary */
+ EAS_U16 pad;
+
+ EAS_I8 pan;
+ EAS_U8 filterQandFlags;
+
+#ifdef _REVERB
+ EAS_I16 reverbSend;
+ EAS_I16 cc91ToReverbSend;
+#endif
+
+#ifdef _CHORUS
+ EAS_I16 chorusSend;
+ EAS_I16 cc93ToChorusSend;
+#endif
+} S_DLS_ARTICULATION;
+
+/* flags in filterQandFlags
+ * NOTE: Q is stored in bottom 5 bits
+ */
+#define FLAG_DLS_VELOCITY_SENSITIVE 0x80
+#define FILTER_Q_MASK 0x1f
+
+/*----------------------------------------------------------------------------
+ * Wavetable region data structure
+ *----------------------------------------------------------------------------
+*/
+typedef struct s_wt_region_tag
+{
+ S_REGION region;
+ EAS_I16 tuning;
+ EAS_I16 gain;
+ EAS_U32 loopStart;
+ EAS_U32 loopEnd;
+ EAS_U16 waveIndex;
+ EAS_U16 artIndex;
+} S_WT_REGION;
+
+/*----------------------------------------------------------------------------
+ * DLS region data structure
+ *----------------------------------------------------------------------------
+*/
+typedef struct s_dls_region_tag
+{
+ S_WT_REGION wtRegion;
+ EAS_U8 velLow;
+ EAS_U8 velHigh;
+} S_DLS_REGION;
+
+/*----------------------------------------------------------------------------
+ * FM synthesizer data structures
+ *----------------------------------------------------------------------------
+*/
+typedef struct s_fm_oper_tag
+{
+ EAS_I16 tuning;
+ EAS_U8 attackDecay;
+ EAS_U8 velocityRelease;
+ EAS_U8 egKeyScale;
+ EAS_U8 sustain;
+ EAS_U8 gain;
+ EAS_U8 flags;
+} S_FM_OPER;
+
+/* defines for S_FM_OPER.m_nFlags */
+#define FM_OPER_FLAG_MONOTONE 0x01
+#define FM_OPER_FLAG_NO_VIBRATO 0x02
+#define FM_OPER_FLAG_NOISE 0x04
+#define FM_OPER_FLAG_LINEAR_VELOCITY 0x08
+
+/* NOTE: The first two structure elements are common with S_WT_REGION
+ * and we will rely on that in the voice management code and must
+ * remain there unless the voice management code is revisited.
+ */
+typedef struct s_fm_region_tag
+{
+ S_REGION region;
+ EAS_U8 vibTrem;
+ EAS_U8 lfoFreqDelay;
+ EAS_U8 feedback;
+ EAS_I8 pan;
+ S_FM_OPER oper[4];
+} S_FM_REGION;
+
+/*----------------------------------------------------------------------------
+ * Common data structures
+ *----------------------------------------------------------------------------
+*/
+
+/*----------------------------------------------------------------------------
+ * Program data structure
+ * Used for individual programs not stored as a complete bank.
+ *----------------------------------------------------------------------------
+*/
+typedef struct s_program_tag
+{
+ EAS_U32 locale;
+ EAS_U16 regionIndex;
+} S_PROGRAM;
+
+/*----------------------------------------------------------------------------
+ * Bank data structure
+ *
+ * A bank always consists of 128 programs. If a bank is less than 128
+ * programs, it should be stored as a spare matrix in the pPrograms
+ * array.
+ *
+ * bankNum: MSB/LSB of MIDI bank select controller
+ * regionIndex: Index of first region in program
+ *----------------------------------------------------------------------------
+*/
+typedef struct s_bank_tag
+{
+ EAS_U16 locale;
+ EAS_U16 regionIndex[NUM_PROGRAMS_IN_BANK];
+} S_BANK;
+
+
+/* defines for libFormat field
+ * bits 0-17 are the sample rate
+ * bit 18 is true if wavetable is present
+ * bit 19 is true if FM is present
+ * bit 20 is true if filter is enabled
+ * bit 21 is sample depth (0 = 8-bits, 1 = 16-bits)
+ * bits 22-31 are reserved
+ */
+#define LIBFORMAT_SAMPLE_RATE_MASK 0x0003ffff
+#define LIB_FORMAT_TYPE_MASK 0x000c0000
+#define LIB_FORMAT_WAVETABLE 0x00000000
+#define LIB_FORMAT_FM 0x00040000
+#define LIB_FORMAT_HYBRID 0x00080000
+#define LIB_FORMAT_FILTER_ENABLED 0x00100000
+#define LIB_FORMAT_16_BIT_SAMPLES 0x00200000
+
+#ifdef DLS_SYNTHESIZER
+/*----------------------------------------------------------------------------
+ * DLS data structure
+ *
+ * pDLSPrograms pointer to array of DLS programs
+ * pDLSRegions pointer to array of DLS regions
+ * pDLSArticulations pointer to array of DLS articulations
+ * pSampleLen pointer to array of sample lengths
+ * ppSamples pointer to array of sample pointers
+ * numDLSPrograms number of DLS programs
+ * numDLSRegions number of DLS regions
+ * numDLSArticulations number of DLS articulations
+ * numDLSSamples number of DLS samples
+ *----------------------------------------------------------------------------
+*/
+typedef struct s_eas_dls_tag
+{
+ S_PROGRAM *pDLSPrograms;
+ S_DLS_REGION *pDLSRegions;
+ S_DLS_ARTICULATION *pDLSArticulations;
+ EAS_U32 *pDLSSampleLen;
+ EAS_U32 *pDLSSampleOffsets;
+ EAS_SAMPLE *pDLSSamples;
+ EAS_U16 numDLSPrograms;
+ EAS_U16 numDLSRegions;
+ EAS_U16 numDLSArticulations;
+ EAS_U16 numDLSSamples;
+ EAS_U8 refCount;
+} S_DLS;
+#endif
+
+/*----------------------------------------------------------------------------
+ * Sound library data structure
+ *
+ * pBanks pointer to array of banks
+ * pPrograms pointer to array of programs
+ * pWTRegions pointer to array of wavetable regions
+ * pFMRegions pointer to array of FM regions
+ * pArticulations pointer to array of articulations
+ * pSampleLen pointer to array of sample lengths
+ * ppSamples pointer to array of sample pointers
+ * numBanks number of banks
+ * numPrograms number of individual program
+ * numRegions number of regions
+ * numArticulations number of articulations
+ * numSamples number of samples
+ *----------------------------------------------------------------------------
+*/
+typedef struct s_eas_sndlib_tag
+{
+ SCNST EAS_U32 identifier;
+ SCNST EAS_U32 libAttr;
+
+ SCNST S_BANK *pBanks;
+ SCNST S_PROGRAM *pPrograms;
+
+ SCNST S_WT_REGION *pWTRegions;
+ SCNST S_ARTICULATION *pArticulations;
+ SCNST EAS_U32 *pSampleLen;
+ SCNST EAS_U32 *pSampleOffsets;
+ SCNST EAS_SAMPLE *pSamples;
+
+ SCNST S_FM_REGION *pFMRegions;
+
+ SCNST EAS_U16 numBanks;
+ SCNST EAS_U16 numPrograms;
+
+ SCNST EAS_U16 numWTRegions;
+ SCNST EAS_U16 numArticulations;
+ SCNST EAS_U16 numSamples;
+
+ SCNST EAS_U16 numFMRegions;
+} S_EAS;
+
+#endif
+
diff --git a/arm-fm-22k/lib_src/eas_synth.h b/arm-fm-22k/lib_src/eas_synth.h
index b242b03..6274b7d 100644
--- a/arm-fm-22k/lib_src/eas_synth.h
+++ b/arm-fm-22k/lib_src/eas_synth.h
@@ -1,12 +1,12 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_synth.h
- *
- * Contents and purpose:
- * Declarations, interfaces, and prototypes for synth.
- *
- * Copyright Sonic Network Inc. 2004, 2005
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_synth.h
+ *
+ * Contents and purpose:
+ * Declarations, interfaces, and prototypes for synth.
+ *
+ * Copyright Sonic Network Inc. 2004, 2005
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,377 +19,377 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 718 $
- * $Date: 2007-06-08 16:43:16 -0700 (Fri, 08 Jun 2007) $
- *----------------------------------------------------------------------------
-*/
-
-#ifndef _EAS_SYNTH_H
-#define _EAS_SYNTH_H
-
-#include "eas_types.h"
-#include "eas_sndlib.h"
-
-#ifdef _WT_SYNTH
-#include "eas_wtsynth.h"
-#endif
-
-#ifdef _FM_SYNTH
-#include "eas_fmsynth.h"
-#endif
-
-#ifndef NUM_OUTPUT_CHANNELS
-#define NUM_OUTPUT_CHANNELS 2
-#endif
-
-#ifndef MAX_SYNTH_VOICES
-#define MAX_SYNTH_VOICES 64
-#endif
-
-#ifndef MAX_VIRTUAL_SYNTHESIZERS
-#define MAX_VIRTUAL_SYNTHESIZERS 4
-#endif
-
-/* defines */
-#ifndef NUM_PRIMARY_VOICES
-#define NUM_PRIMARY_VOICES MAX_SYNTH_VOICES
-#elif !defined(NUM_SECONDARY_VOICES)
-#define NUM_SECONDARY_VOICES (MAX_SYNTH_VOICES - NUM_PRIMARY_VOICES)
-#endif
-
-#if defined(EAS_WT_SYNTH)
-#define NUM_WT_VOICES MAX_SYNTH_VOICES
-
-/* FM on MCU */
-#elif defined(EAS_FM_SYNTH)
-#define NUM_FM_VOICES MAX_SYNTH_VOICES
-
-/* wavetable drums on MCU, wavetable melodic on DSP */
-#elif defined(EAS_SPLIT_WT_SYNTH)
-#define NUM_WT_VOICES MAX_SYNTH_VOICES
-
-/* wavetable drums and FM melodic on MCU */
-#elif defined(EAS_HYBRID_SYNTH)
-#define NUM_WT_VOICES NUM_PRIMARY_VOICES
-#define NUM_FM_VOICES NUM_SECONDARY_VOICES
-
-/* wavetable drums on MCU, FM melodic on DSP */
-#elif defined(EAS_SPLIT_HYBRID_SYNTH)
-#define NUM_WT_VOICES NUM_PRIMARY_VOICES
-#define NUM_FM_VOICES NUM_SECONDARY_VOICES
-
-/* FM synth on DSP */
-#elif defined(EAS_SPLIT_FM_SYNTH)
-#define NUM_FM_VOICES MAX_SYNTH_VOICES
-
-#else
-#error "Unrecognized architecture option"
-#endif
-
-#define NUM_SYNTH_CHANNELS 16
-
-#define DEFAULT_SYNTH_VOICES MAX_SYNTH_VOICES
-
-/* use the following values to specify unassigned channels or voices */
-#define UNASSIGNED_SYNTH_CHANNEL NUM_SYNTH_CHANNELS
-#define UNASSIGNED_SYNTH_VOICE MAX_SYNTH_VOICES
-
-
-/* synth parameters are updated every SYNTH_UPDATE_PERIOD_IN_SAMPLES */
-#define SYNTH_UPDATE_PERIOD_IN_SAMPLES (EAS_I32)(0x1L << SYNTH_UPDATE_PERIOD_IN_BITS)
-
-/* stealing weighting factors */
-#define NOTE_AGE_STEAL_WEIGHT 1
-#define NOTE_GAIN_STEAL_WEIGHT 4
-#define CHANNEL_POLY_STEAL_WEIGHT 12
-#define CHANNEL_PRIORITY_STEAL_WEIGHT 2
-#define NOTE_MATCH_PENALTY 128
-#define SYNTH_PRIORITY_WEIGHT 8
-
-/* default synth master volume */
-#define DEFAULT_SYNTH_MASTER_VOLUME 0x7fff
-
-#define DEFAULT_SYNTH_PRIORITY 5
-
-/* default tuning values */
-#define DEFAULT_PITCH_BEND_SENSITIVITY 200 /* 2 semitones */
-#define DEFAULT_FINE_PITCH 0 /* 0 cents */
-#define DEFAULT_COARSE_PITCH 0 /* 0 semitones */
-
-/* default drum channel is 10, but is internally 9 due to unit offset */
-#define DEFAULT_DRUM_CHANNEL 9
-
-/* drum channel can simultaneously play this many voices at most */
-#define DEFAULT_CHANNEL_POLYPHONY_LIMIT 2
-
-/* default instrument is acoustic piano */
-#define DEFAULT_MELODY_BANK_MSB 0x79
-#define DEFAULT_RHYTHM_BANK_MSB 0x78
-#define DEFAULT_MELODY_BANK_NUMBER (DEFAULT_MELODY_BANK_MSB << 8)
-#define DEFAULT_RHYTHM_BANK_NUMBER (DEFAULT_RHYTHM_BANK_MSB << 8)
-#define DEFAULT_SYNTH_PROGRAM_NUMBER 0
-
-#define DEFAULT_PITCH_BEND 0x2000 /* 0x2000 == (0x40 << 7) | 0x00 */
-#define DEFAULT_MOD_WHEEL 0
-#define DEFAULT_CHANNEL_VOLUME 0x64
-#define DEFAULT_PAN 0x40 /* decimal 64, center */
-
-#ifdef _REVERB
-#define DEFAULT_REVERB_SEND 40 /* some reverb */
-#endif
-
-#ifdef _CHORUS
-#define DEFAULT_CHORUS_SEND 0 /* no chorus */
-#endif
-
-#define DEFAULT_EAS_FILTER_CUTOFF_FREQUENCY 0 /* EAS synth uses a different default */
-#define DEFAULT_FILTER_RESONANCE 0
-#define DEFAULT_EXPRESSION 0x7F
-
-#define DEFAULT_CHANNEL_PRESSURE 0
-
-#define DEFAULT_REGISTERED_PARAM 0x3FFF
-
-#define DEFAULT_CHANNEL_STATIC_GAIN 0
-#define DEFAULT_CHANNEL_STATIC_PITCH 0
-
-#define DEFAULT_LFO_MOD_WHEEL_TO_PITCH_CENTS 50
-#define DEFAULT_LFO_CHANNEL_PRESSURE_TO_PITCH_CENTS 50
-
-#define DEFAULT_KEY_NUMBER 0x69
-#define DEFAULT_VELOCITY 0x64
-#define DEFAULT_REGION_INDEX 0
-#define DEFAULT_ARTICULATION_INDEX 0
-#define DEFAULT_VOICE_GAIN 0
-#define DEFAULT_AGE 0
-#define DEFAULT_SP_MIDI_PRIORITY 16
-
-
-/* filter defines */
-#define DEFAULT_FILTER_ZERO 0
-#define FILTER_CUTOFF_MAX_PITCH_CENTS 1919
-#define FILTER_CUTOFF_MIN_PITCH_CENTS -4467
-#define A5_PITCH_OFFSET_IN_CENTS 6900
-
-/*------------------------------------
- * S_SYNTH_CHANNEL data structure
- *------------------------------------
-*/
-
-/* S_SYNTH_CHANNEL.m_nFlags */
-#define CHANNEL_FLAG_SUSTAIN_PEDAL 0x01
-#define CHANNEL_FLAG_MUTE 0x02
-#define CHANNEL_FLAG_UPDATE_CHANNEL_PARAMETERS 0x04
-#define CHANNEL_FLAG_RHYTHM_CHANNEL 0x08
-#define CHANNEL_FLAG_EXTERNAL_AUDIO 0x10
-#define DEFAULT_CHANNEL_FLAGS 0
-
-/* macros for extracting virtual synth and channel numbers */
-#define GET_VSYNTH(a) ((a) >> 4)
-#define GET_CHANNEL(a) ((a) & 15)
-
-typedef struct s_synth_channel_tag
-{
- /* use static channel parameters to reduce MIPs */
- /* parameters shared by multiple voices assigned to same channel */
- EAS_I32 staticPitch; /* (pitch bend * pitch sens) + fine pitch */
- EAS_I16 staticGain; /* (CC7 * CC11 * master vol)^2 */
-
- EAS_U16 regionIndex; /* index of first region in program */
-
- EAS_U16 bankNum; /* play programs from this bank */
- EAS_I16 pitchBend; /* pitch wheel value */
- EAS_I16 pitchBendSensitivity;
- EAS_I16 registeredParam; /* currently selected registered param */
-
-
-#if defined(_FM_SYNTH)
- EAS_I16 lfoAmt; /* amount of LFO to apply to voice */
-#endif
-
- EAS_U8 programNum; /* play this instrument number */
- EAS_U8 modWheel; /* CC1 */
- EAS_U8 volume; /* CC7 */
- EAS_U8 pan; /* CC10 */
-
- EAS_U8 expression; /* CC11 */
-
- /* the following parameters are controlled by RPNs */
- EAS_I8 finePitch;
- EAS_I8 coarsePitch;
-
- EAS_U8 channelPressure; /* applied to all voices on a given channel */
-
- EAS_U8 channelFlags; /* bit field channelFlags for */
- /* CC64, SP-MIDI channel masking */
-
- EAS_U8 pool; /* SPMIDI channel voice pool */
- EAS_U8 mip; /* SPMIDI MIP setting */
-
-#ifdef _REVERB
- EAS_U8 reverbSend; /* CC91 */
-#endif
-
-#ifdef _CHORUS
- EAS_U8 chorusSend; /* CC93 */
-#endif
-} S_SYNTH_CHANNEL;
-
-/*------------------------------------
- * S_SYNTH_VOICE data structure
- *------------------------------------
-*/
-
-/* S_SYNTH_VOICE.m_nFlags */
-#define VOICE_FLAG_UPDATE_VOICE_PARAMETERS 0x01
-#define VOICE_FLAG_SUSTAIN_PEDAL_DEFER_NOTE_OFF 0x02
-#define VOICE_FLAG_DEFER_MIDI_NOTE_OFF 0x04
-#define VOICE_FLAG_NO_SAMPLES_SYNTHESIZED_YET 0x08
-#define VOICE_FLAG_DEFER_MUTE 0x40
-#define DEFAULT_VOICE_FLAGS 0
-
-/* S_SYNTH_VOICE.m_eState */
-typedef enum {
-
- eVoiceStateFree = 0,
- eVoiceStateStart,
- eVoiceStatePlay,
- eVoiceStateRelease,
- eVoiceStateMuting,
- eVoiceStateStolen,
- eVoiceStateInvalid /* should never be in this state! */
-
-} E_VOICE_STATE;
-#define DEFAULT_VOICE_STATE eVoiceStateFree
-
-typedef struct s_synth_voice_tag
-{
-
-/* These parameters are common to both wavetable and FM
- * synthesizers. The voice manager should only access this data.
- * Any other data should be manipulated by the code that is
- * specific to that synthesizer and reflected back through the
- * common state data available here.
- */
- EAS_U16 regionIndex; /* index to wave and playback params */
- EAS_I16 gain; /* current gain */
- EAS_U16 age; /* large value means old note */
- EAS_U16 nextRegionIndex; /* index to wave and playback params */
- EAS_U8 voiceState; /* current voice state */
- EAS_U8 voiceFlags; /* misc flags/bit fields */
- EAS_U8 channel; /* this voice plays on this synth channel */
- EAS_U8 note; /* 12 <= key number <= 108 */
- EAS_U8 velocity; /* 0 <= velocity <= 127 */
- EAS_U8 nextChannel; /* play stolen voice on this channel */
- EAS_U8 nextNote; /* 12 <= key number <= 108 */
- EAS_U8 nextVelocity; /* 0 <= velocity <= 127 */
-} S_SYNTH_VOICE;
-
-/*------------------------------------
- * S_SYNTH data structure
- *
- * One instance for each MIDI stream
- *------------------------------------
-*/
-
-/* S_SYNTH.m_nFlags */
-#define SYNTH_FLAG_RESET_IS_REQUESTED 0x01
-#define SYNTH_FLAG_SP_MIDI_ON 0x02
-#define SYNTH_FLAG_UPDATE_ALL_CHANNEL_PARAMETERS 0x04
-#define SYNTH_FLAG_DEFERRED_MIDI_NOTE_OFF_PENDING 0x08
-#define DEFAULT_SYNTH_FLAGS SYNTH_FLAG_UPDATE_ALL_CHANNEL_PARAMETERS
-
-typedef struct s_synth_tag
-{
- struct s_eas_data_tag *pEASData;
- const S_EAS *pEAS;
-
-#ifdef DLS_SYNTHESIZER
- S_DLS *pDLS;
-#endif
-
-#ifdef EXTERNAL_AUDIO
- EAS_EXT_PRG_CHG_FUNC cbProgChgFunc;
- EAS_EXT_EVENT_FUNC cbEventFunc;
- EAS_VOID_PTR *pExtAudioInstData;
-#endif
-
- S_SYNTH_CHANNEL channels[NUM_SYNTH_CHANNELS];
- EAS_I32 totalNoteCount;
- EAS_U16 maxPolyphony;
- EAS_U16 numActiveVoices;
- EAS_U16 masterVolume;
- EAS_U8 channelsByPriority[NUM_SYNTH_CHANNELS];
- EAS_U8 poolCount[NUM_SYNTH_CHANNELS];
- EAS_U8 poolAlloc[NUM_SYNTH_CHANNELS];
- EAS_U8 synthFlags;
- EAS_I8 globalTranspose;
- EAS_U8 vSynthNum;
- EAS_U8 refCount;
- EAS_U8 priority;
-} S_SYNTH;
-
-/*------------------------------------
- * S_VOICE_MGR data structure
- *
- * One instance for each EAS library instance
- *------------------------------------
-*/
-typedef struct s_voice_mgr_tag
-{
- S_SYNTH *pSynth[MAX_VIRTUAL_SYNTHESIZERS];
- EAS_PCM voiceBuffer[SYNTH_UPDATE_PERIOD_IN_SAMPLES];
-
-#ifdef _FM_SYNTH
- EAS_PCM operMixBuffer[SYNTH_UPDATE_PERIOD_IN_SAMPLES];
- S_FM_VOICE fmVoices[NUM_FM_VOICES];
-#endif
-
-#ifdef _WT_SYNTH
- S_WT_VOICE wtVoices[NUM_WT_VOICES];
-#endif
-
-#ifdef _REVERB
- EAS_PCM reverbSendBuffer[NUM_OUTPUT_CHANNELS * SYNTH_UPDATE_PERIOD_IN_SAMPLES];
-#endif
-
-#ifdef _CHORUS
- EAS_PCM chorusSendBuffer[NUM_OUTPUT_CHANNELS * SYNTH_UPDATE_PERIOD_IN_SAMPLES];
-#endif
- S_SYNTH_VOICE voices[MAX_SYNTH_VOICES];
-
- EAS_SNDLIB_HANDLE pGlobalEAS;
-
-#ifdef DLS_SYNTHESIZER
- S_DLS *pGlobalDLS;
-#endif
-
-#ifdef _SPLIT_ARCHITECTURE
- EAS_FRAME_BUFFER_HANDLE pFrameBuffer;
-#endif
-
-#if defined(_SECONDARY_SYNTH) || defined(EAS_SPLIT_WT_SYNTH)
- EAS_U16 maxPolyphonyPrimary;
- EAS_U16 maxPolyphonySecondary;
-#endif
-
- EAS_I32 workload;
- EAS_I32 maxWorkLoad;
-
- EAS_U16 activeVoices;
- EAS_U16 maxPolyphony;
-
- EAS_U16 age;
-
-/* limits the number of voice starts in a frame for split architecture */
-#ifdef MAX_VOICE_STARTS
- EAS_U16 numVoiceStarts;
-#endif
-} S_VOICE_MGR;
-
-#endif /* #ifdef _EAS_SYNTH_H */
-
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 718 $
+ * $Date: 2007-06-08 16:43:16 -0700 (Fri, 08 Jun 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+#ifndef _EAS_SYNTH_H
+#define _EAS_SYNTH_H
+
+#include "eas_types.h"
+#include "eas_sndlib.h"
+
+#ifdef _WT_SYNTH
+#include "eas_wtsynth.h"
+#endif
+
+#ifdef _FM_SYNTH
+#include "eas_fmsynth.h"
+#endif
+
+#ifndef NUM_OUTPUT_CHANNELS
+#define NUM_OUTPUT_CHANNELS 2
+#endif
+
+#ifndef MAX_SYNTH_VOICES
+#define MAX_SYNTH_VOICES 64
+#endif
+
+#ifndef MAX_VIRTUAL_SYNTHESIZERS
+#define MAX_VIRTUAL_SYNTHESIZERS 4
+#endif
+
+/* defines */
+#ifndef NUM_PRIMARY_VOICES
+#define NUM_PRIMARY_VOICES MAX_SYNTH_VOICES
+#elif !defined(NUM_SECONDARY_VOICES)
+#define NUM_SECONDARY_VOICES (MAX_SYNTH_VOICES - NUM_PRIMARY_VOICES)
+#endif
+
+#if defined(EAS_WT_SYNTH)
+#define NUM_WT_VOICES MAX_SYNTH_VOICES
+
+/* FM on MCU */
+#elif defined(EAS_FM_SYNTH)
+#define NUM_FM_VOICES MAX_SYNTH_VOICES
+
+/* wavetable drums on MCU, wavetable melodic on DSP */
+#elif defined(EAS_SPLIT_WT_SYNTH)
+#define NUM_WT_VOICES MAX_SYNTH_VOICES
+
+/* wavetable drums and FM melodic on MCU */
+#elif defined(EAS_HYBRID_SYNTH)
+#define NUM_WT_VOICES NUM_PRIMARY_VOICES
+#define NUM_FM_VOICES NUM_SECONDARY_VOICES
+
+/* wavetable drums on MCU, FM melodic on DSP */
+#elif defined(EAS_SPLIT_HYBRID_SYNTH)
+#define NUM_WT_VOICES NUM_PRIMARY_VOICES
+#define NUM_FM_VOICES NUM_SECONDARY_VOICES
+
+/* FM synth on DSP */
+#elif defined(EAS_SPLIT_FM_SYNTH)
+#define NUM_FM_VOICES MAX_SYNTH_VOICES
+
+#else
+#error "Unrecognized architecture option"
+#endif
+
+#define NUM_SYNTH_CHANNELS 16
+
+#define DEFAULT_SYNTH_VOICES MAX_SYNTH_VOICES
+
+/* use the following values to specify unassigned channels or voices */
+#define UNASSIGNED_SYNTH_CHANNEL NUM_SYNTH_CHANNELS
+#define UNASSIGNED_SYNTH_VOICE MAX_SYNTH_VOICES
+
+
+/* synth parameters are updated every SYNTH_UPDATE_PERIOD_IN_SAMPLES */
+#define SYNTH_UPDATE_PERIOD_IN_SAMPLES (EAS_I32)(0x1L << SYNTH_UPDATE_PERIOD_IN_BITS)
+
+/* stealing weighting factors */
+#define NOTE_AGE_STEAL_WEIGHT 1
+#define NOTE_GAIN_STEAL_WEIGHT 4
+#define CHANNEL_POLY_STEAL_WEIGHT 12
+#define CHANNEL_PRIORITY_STEAL_WEIGHT 2
+#define NOTE_MATCH_PENALTY 128
+#define SYNTH_PRIORITY_WEIGHT 8
+
+/* default synth master volume */
+#define DEFAULT_SYNTH_MASTER_VOLUME 0x7fff
+
+#define DEFAULT_SYNTH_PRIORITY 5
+
+/* default tuning values */
+#define DEFAULT_PITCH_BEND_SENSITIVITY 200 /* 2 semitones */
+#define DEFAULT_FINE_PITCH 0 /* 0 cents */
+#define DEFAULT_COARSE_PITCH 0 /* 0 semitones */
+
+/* default drum channel is 10, but is internally 9 due to unit offset */
+#define DEFAULT_DRUM_CHANNEL 9
+
+/* drum channel can simultaneously play this many voices at most */
+#define DEFAULT_CHANNEL_POLYPHONY_LIMIT 2
+
+/* default instrument is acoustic piano */
+#define DEFAULT_MELODY_BANK_MSB 0x79
+#define DEFAULT_RHYTHM_BANK_MSB 0x78
+#define DEFAULT_MELODY_BANK_NUMBER (DEFAULT_MELODY_BANK_MSB << 8)
+#define DEFAULT_RHYTHM_BANK_NUMBER (DEFAULT_RHYTHM_BANK_MSB << 8)
+#define DEFAULT_SYNTH_PROGRAM_NUMBER 0
+
+#define DEFAULT_PITCH_BEND 0x2000 /* 0x2000 == (0x40 << 7) | 0x00 */
+#define DEFAULT_MOD_WHEEL 0
+#define DEFAULT_CHANNEL_VOLUME 0x64
+#define DEFAULT_PAN 0x40 /* decimal 64, center */
+
+#ifdef _REVERB
+#define DEFAULT_REVERB_SEND 40 /* some reverb */
+#endif
+
+#ifdef _CHORUS
+#define DEFAULT_CHORUS_SEND 0 /* no chorus */
+#endif
+
+#define DEFAULT_EAS_FILTER_CUTOFF_FREQUENCY 0 /* EAS synth uses a different default */
+#define DEFAULT_FILTER_RESONANCE 0
+#define DEFAULT_EXPRESSION 0x7F
+
+#define DEFAULT_CHANNEL_PRESSURE 0
+
+#define DEFAULT_REGISTERED_PARAM 0x3FFF
+
+#define DEFAULT_CHANNEL_STATIC_GAIN 0
+#define DEFAULT_CHANNEL_STATIC_PITCH 0
+
+#define DEFAULT_LFO_MOD_WHEEL_TO_PITCH_CENTS 50
+#define DEFAULT_LFO_CHANNEL_PRESSURE_TO_PITCH_CENTS 50
+
+#define DEFAULT_KEY_NUMBER 0x69
+#define DEFAULT_VELOCITY 0x64
+#define DEFAULT_REGION_INDEX 0
+#define DEFAULT_ARTICULATION_INDEX 0
+#define DEFAULT_VOICE_GAIN 0
+#define DEFAULT_AGE 0
+#define DEFAULT_SP_MIDI_PRIORITY 16
+
+
+/* filter defines */
+#define DEFAULT_FILTER_ZERO 0
+#define FILTER_CUTOFF_MAX_PITCH_CENTS 1919
+#define FILTER_CUTOFF_MIN_PITCH_CENTS -4467
+#define A5_PITCH_OFFSET_IN_CENTS 6900
+
+/*------------------------------------
+ * S_SYNTH_CHANNEL data structure
+ *------------------------------------
+*/
+
+/* S_SYNTH_CHANNEL.m_nFlags */
+#define CHANNEL_FLAG_SUSTAIN_PEDAL 0x01
+#define CHANNEL_FLAG_MUTE 0x02
+#define CHANNEL_FLAG_UPDATE_CHANNEL_PARAMETERS 0x04
+#define CHANNEL_FLAG_RHYTHM_CHANNEL 0x08
+#define CHANNEL_FLAG_EXTERNAL_AUDIO 0x10
+#define DEFAULT_CHANNEL_FLAGS 0
+
+/* macros for extracting virtual synth and channel numbers */
+#define GET_VSYNTH(a) ((a) >> 4)
+#define GET_CHANNEL(a) ((a) & 15)
+
+typedef struct s_synth_channel_tag
+{
+ /* use static channel parameters to reduce MIPs */
+ /* parameters shared by multiple voices assigned to same channel */
+ EAS_I32 staticPitch; /* (pitch bend * pitch sens) + fine pitch */
+ EAS_I16 staticGain; /* (CC7 * CC11 * master vol)^2 */
+
+ EAS_U16 regionIndex; /* index of first region in program */
+
+ EAS_U16 bankNum; /* play programs from this bank */
+ EAS_I16 pitchBend; /* pitch wheel value */
+ EAS_I16 pitchBendSensitivity;
+ EAS_I16 registeredParam; /* currently selected registered param */
+
+
+#if defined(_FM_SYNTH)
+ EAS_I16 lfoAmt; /* amount of LFO to apply to voice */
+#endif
+
+ EAS_U8 programNum; /* play this instrument number */
+ EAS_U8 modWheel; /* CC1 */
+ EAS_U8 volume; /* CC7 */
+ EAS_U8 pan; /* CC10 */
+
+ EAS_U8 expression; /* CC11 */
+
+ /* the following parameters are controlled by RPNs */
+ EAS_I8 finePitch;
+ EAS_I8 coarsePitch;
+
+ EAS_U8 channelPressure; /* applied to all voices on a given channel */
+
+ EAS_U8 channelFlags; /* bit field channelFlags for */
+ /* CC64, SP-MIDI channel masking */
+
+ EAS_U8 pool; /* SPMIDI channel voice pool */
+ EAS_U8 mip; /* SPMIDI MIP setting */
+
+#ifdef _REVERB
+ EAS_U8 reverbSend; /* CC91 */
+#endif
+
+#ifdef _CHORUS
+ EAS_U8 chorusSend; /* CC93 */
+#endif
+} S_SYNTH_CHANNEL;
+
+/*------------------------------------
+ * S_SYNTH_VOICE data structure
+ *------------------------------------
+*/
+
+/* S_SYNTH_VOICE.m_nFlags */
+#define VOICE_FLAG_UPDATE_VOICE_PARAMETERS 0x01
+#define VOICE_FLAG_SUSTAIN_PEDAL_DEFER_NOTE_OFF 0x02
+#define VOICE_FLAG_DEFER_MIDI_NOTE_OFF 0x04
+#define VOICE_FLAG_NO_SAMPLES_SYNTHESIZED_YET 0x08
+#define VOICE_FLAG_DEFER_MUTE 0x40
+#define DEFAULT_VOICE_FLAGS 0
+
+/* S_SYNTH_VOICE.m_eState */
+typedef enum {
+
+ eVoiceStateFree = 0,
+ eVoiceStateStart,
+ eVoiceStatePlay,
+ eVoiceStateRelease,
+ eVoiceStateMuting,
+ eVoiceStateStolen,
+ eVoiceStateInvalid /* should never be in this state! */
+
+} E_VOICE_STATE;
+#define DEFAULT_VOICE_STATE eVoiceStateFree
+
+typedef struct s_synth_voice_tag
+{
+
+/* These parameters are common to both wavetable and FM
+ * synthesizers. The voice manager should only access this data.
+ * Any other data should be manipulated by the code that is
+ * specific to that synthesizer and reflected back through the
+ * common state data available here.
+ */
+ EAS_U16 regionIndex; /* index to wave and playback params */
+ EAS_I16 gain; /* current gain */
+ EAS_U16 age; /* large value means old note */
+ EAS_U16 nextRegionIndex; /* index to wave and playback params */
+ EAS_U8 voiceState; /* current voice state */
+ EAS_U8 voiceFlags; /* misc flags/bit fields */
+ EAS_U8 channel; /* this voice plays on this synth channel */
+ EAS_U8 note; /* 12 <= key number <= 108 */
+ EAS_U8 velocity; /* 0 <= velocity <= 127 */
+ EAS_U8 nextChannel; /* play stolen voice on this channel */
+ EAS_U8 nextNote; /* 12 <= key number <= 108 */
+ EAS_U8 nextVelocity; /* 0 <= velocity <= 127 */
+} S_SYNTH_VOICE;
+
+/*------------------------------------
+ * S_SYNTH data structure
+ *
+ * One instance for each MIDI stream
+ *------------------------------------
+*/
+
+/* S_SYNTH.m_nFlags */
+#define SYNTH_FLAG_RESET_IS_REQUESTED 0x01
+#define SYNTH_FLAG_SP_MIDI_ON 0x02
+#define SYNTH_FLAG_UPDATE_ALL_CHANNEL_PARAMETERS 0x04
+#define SYNTH_FLAG_DEFERRED_MIDI_NOTE_OFF_PENDING 0x08
+#define DEFAULT_SYNTH_FLAGS SYNTH_FLAG_UPDATE_ALL_CHANNEL_PARAMETERS
+
+typedef struct s_synth_tag
+{
+ struct s_eas_data_tag *pEASData;
+ const S_EAS *pEAS;
+
+#ifdef DLS_SYNTHESIZER
+ S_DLS *pDLS;
+#endif
+
+#ifdef EXTERNAL_AUDIO
+ EAS_EXT_PRG_CHG_FUNC cbProgChgFunc;
+ EAS_EXT_EVENT_FUNC cbEventFunc;
+ EAS_VOID_PTR *pExtAudioInstData;
+#endif
+
+ S_SYNTH_CHANNEL channels[NUM_SYNTH_CHANNELS];
+ EAS_I32 totalNoteCount;
+ EAS_U16 maxPolyphony;
+ EAS_U16 numActiveVoices;
+ EAS_U16 masterVolume;
+ EAS_U8 channelsByPriority[NUM_SYNTH_CHANNELS];
+ EAS_U8 poolCount[NUM_SYNTH_CHANNELS];
+ EAS_U8 poolAlloc[NUM_SYNTH_CHANNELS];
+ EAS_U8 synthFlags;
+ EAS_I8 globalTranspose;
+ EAS_U8 vSynthNum;
+ EAS_U8 refCount;
+ EAS_U8 priority;
+} S_SYNTH;
+
+/*------------------------------------
+ * S_VOICE_MGR data structure
+ *
+ * One instance for each EAS library instance
+ *------------------------------------
+*/
+typedef struct s_voice_mgr_tag
+{
+ S_SYNTH *pSynth[MAX_VIRTUAL_SYNTHESIZERS];
+ EAS_PCM voiceBuffer[SYNTH_UPDATE_PERIOD_IN_SAMPLES];
+
+#ifdef _FM_SYNTH
+ EAS_PCM operMixBuffer[SYNTH_UPDATE_PERIOD_IN_SAMPLES];
+ S_FM_VOICE fmVoices[NUM_FM_VOICES];
+#endif
+
+#ifdef _WT_SYNTH
+ S_WT_VOICE wtVoices[NUM_WT_VOICES];
+#endif
+
+#ifdef _REVERB
+ EAS_PCM reverbSendBuffer[NUM_OUTPUT_CHANNELS * SYNTH_UPDATE_PERIOD_IN_SAMPLES];
+#endif
+
+#ifdef _CHORUS
+ EAS_PCM chorusSendBuffer[NUM_OUTPUT_CHANNELS * SYNTH_UPDATE_PERIOD_IN_SAMPLES];
+#endif
+ S_SYNTH_VOICE voices[MAX_SYNTH_VOICES];
+
+ EAS_SNDLIB_HANDLE pGlobalEAS;
+
+#ifdef DLS_SYNTHESIZER
+ S_DLS *pGlobalDLS;
+#endif
+
+#ifdef _SPLIT_ARCHITECTURE
+ EAS_FRAME_BUFFER_HANDLE pFrameBuffer;
+#endif
+
+#if defined(_SECONDARY_SYNTH) || defined(EAS_SPLIT_WT_SYNTH)
+ EAS_U16 maxPolyphonyPrimary;
+ EAS_U16 maxPolyphonySecondary;
+#endif
+
+ EAS_I32 workload;
+ EAS_I32 maxWorkLoad;
+
+ EAS_U16 activeVoices;
+ EAS_U16 maxPolyphony;
+
+ EAS_U16 age;
+
+/* limits the number of voice starts in a frame for split architecture */
+#ifdef MAX_VOICE_STARTS
+ EAS_U16 numVoiceStarts;
+#endif
+} S_VOICE_MGR;
+
+#endif /* #ifdef _EAS_SYNTH_H */
+
+
diff --git a/arm-fm-22k/lib_src/eas_synth_protos.h b/arm-fm-22k/lib_src/eas_synth_protos.h
index a2ef10d..b03af0f 100644
--- a/arm-fm-22k/lib_src/eas_synth_protos.h
+++ b/arm-fm-22k/lib_src/eas_synth_protos.h
@@ -1,12 +1,12 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_synth_protos.h
- *
- * Contents and purpose:
- * Declarations, interfaces, and prototypes for synth.
- *
- * Copyright Sonic Network Inc. 2004
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_synth_protos.h
+ *
+ * Contents and purpose:
+ * Declarations, interfaces, and prototypes for synth.
+ *
+ * Copyright Sonic Network Inc. 2004
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,42 +19,42 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 82 $
- * $Date: 2006-07-10 11:45:19 -0700 (Mon, 10 Jul 2006) $
- *----------------------------------------------------------------------------
-*/
-
-#ifndef _EAS_SYNTH_PROTOS_H
-#define _EAS_SYNTH_PROTOS_H
-
-/* includes */
-#include "eas_data.h"
-#include "eas_sndlib.h"
-
-#ifdef _SPLIT_ARCHITECTURE
-typedef struct s_frame_interface_tag
-{
- EAS_BOOL (* EAS_CONST pfStartFrame)(EAS_FRAME_BUFFER_HANDLE pFrameBuffer);
- EAS_BOOL (* EAS_CONST pfEndFrame)(EAS_FRAME_BUFFER_HANDLE pFrameBuffer, EAS_I32 *pMixBuffer, EAS_I16 masterGain);
-} S_FRAME_INTERFACE;
-#endif
-
-/* generic synthesizer interface */
-typedef struct
-{
- EAS_RESULT (* EAS_CONST pfInitialize)(S_VOICE_MGR *pVoiceMgr);
- EAS_RESULT (* EAS_CONST pfStartVoice)(S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, EAS_I32 voiceNum, EAS_U16 regionIndex);
- EAS_BOOL (* EAS_CONST pfUpdateVoice)(S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, EAS_I32 voiceNum, EAS_I32 *pMixBuffer, EAS_I32 numSamples);
- void (* EAS_CONST pfReleaseVoice)(S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, EAS_I32 voiceNum);
- void (* EAS_CONST pfMuteVoice)(S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, EAS_I32 voiceNum);
- void (* EAS_CONST pfSustainPedal)(S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, S_SYNTH_CHANNEL *pChannel, EAS_I32 voiceNum);
- void (* EAS_CONST pfUpdateChannel)(S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel);
-} S_SYNTH_INTERFACE;
-
-#endif
-
-
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 82 $
+ * $Date: 2006-07-10 11:45:19 -0700 (Mon, 10 Jul 2006) $
+ *----------------------------------------------------------------------------
+*/
+
+#ifndef _EAS_SYNTH_PROTOS_H
+#define _EAS_SYNTH_PROTOS_H
+
+/* includes */
+#include "eas_data.h"
+#include "eas_sndlib.h"
+
+#ifdef _SPLIT_ARCHITECTURE
+typedef struct s_frame_interface_tag
+{
+ EAS_BOOL (* EAS_CONST pfStartFrame)(EAS_FRAME_BUFFER_HANDLE pFrameBuffer);
+ EAS_BOOL (* EAS_CONST pfEndFrame)(EAS_FRAME_BUFFER_HANDLE pFrameBuffer, EAS_I32 *pMixBuffer, EAS_I16 masterGain);
+} S_FRAME_INTERFACE;
+#endif
+
+/* generic synthesizer interface */
+typedef struct
+{
+ EAS_RESULT (* EAS_CONST pfInitialize)(S_VOICE_MGR *pVoiceMgr);
+ EAS_RESULT (* EAS_CONST pfStartVoice)(S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, EAS_I32 voiceNum, EAS_U16 regionIndex);
+ EAS_BOOL (* EAS_CONST pfUpdateVoice)(S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, EAS_I32 voiceNum, EAS_I32 *pMixBuffer, EAS_I32 numSamples);
+ void (* EAS_CONST pfReleaseVoice)(S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, EAS_I32 voiceNum);
+ void (* EAS_CONST pfMuteVoice)(S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, EAS_I32 voiceNum);
+ void (* EAS_CONST pfSustainPedal)(S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, S_SYNTH_CHANNEL *pChannel, EAS_I32 voiceNum);
+ void (* EAS_CONST pfUpdateChannel)(S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel);
+} S_SYNTH_INTERFACE;
+
+#endif
+
+
+
diff --git a/arm-fm-22k/lib_src/eas_synthcfg.h b/arm-fm-22k/lib_src/eas_synthcfg.h
index 2491e6d..78a4178 100644
--- a/arm-fm-22k/lib_src/eas_synthcfg.h
+++ b/arm-fm-22k/lib_src/eas_synthcfg.h
@@ -1,12 +1,12 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_synthcfg.h
- *
- * Contents and purpose:
- * Defines for various synth configurations
- *
- * Copyright Sonic Network Inc. 2004, 2005
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_synthcfg.h
+ *
+ * Contents and purpose:
+ * Defines for various synth configurations
+ *
+ * Copyright Sonic Network Inc. 2004, 2005
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,52 +19,52 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 664 $
- * $Date: 2007-04-25 13:11:22 -0700 (Wed, 25 Apr 2007) $
- *----------------------------------------------------------------------------
-*/
-
-#ifndef _EAS_SYNTHCFG_H
-#define _EAS_SYNTHCFG_H
-
-#if defined(EAS_WT_SYNTH)
-#define _WT_SYNTH
-
-/* FM on MCU */
-#elif defined(EAS_FM_SYNTH)
-#define _FM_SYNTH
-
-/* wavetable drums and FM melodic on MCU */
-#elif defined(EAS_HYBRID_SYNTH)
-#define _WT_SYNTH
-#define _FM_SYNTH
-#define _SECONDARY_SYNTH
-#define _HYBRID_SYNTH
-
-/* wavetable drums on MCU, wavetable melodic on DSP */
-#elif defined(EAS_SPLIT_WT_SYNTH)
-#define _WT_SYNTH
-#define _SPLIT_ARCHITECTURE
-
-/* wavetable drums on MCU, FM melodic on DSP */
-#elif defined(EAS_SPLIT_HYBRID_SYNTH)
-#define _WT_SYNTH
-#define _FM_SYNTH
-#define _SECONDARY_SYNTH
-#define _SPLIT_ARCHITECTURE
-#define _HYBRID_SYNTH
-
-/* FM synth on DSP */
-#elif defined(EAS_SPLIT_FM_SYNTH)
-#define _FM_SYNTH
-#define _SPLIT_ARCHITECTURE
-
-#else
-#error "Unrecognized architecture option"
-#endif
-
-#endif
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 664 $
+ * $Date: 2007-04-25 13:11:22 -0700 (Wed, 25 Apr 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+#ifndef _EAS_SYNTHCFG_H
+#define _EAS_SYNTHCFG_H
+
+#if defined(EAS_WT_SYNTH)
+#define _WT_SYNTH
+
+/* FM on MCU */
+#elif defined(EAS_FM_SYNTH)
+#define _FM_SYNTH
+
+/* wavetable drums and FM melodic on MCU */
+#elif defined(EAS_HYBRID_SYNTH)
+#define _WT_SYNTH
+#define _FM_SYNTH
+#define _SECONDARY_SYNTH
+#define _HYBRID_SYNTH
+
+/* wavetable drums on MCU, wavetable melodic on DSP */
+#elif defined(EAS_SPLIT_WT_SYNTH)
+#define _WT_SYNTH
+#define _SPLIT_ARCHITECTURE
+
+/* wavetable drums on MCU, FM melodic on DSP */
+#elif defined(EAS_SPLIT_HYBRID_SYNTH)
+#define _WT_SYNTH
+#define _FM_SYNTH
+#define _SECONDARY_SYNTH
+#define _SPLIT_ARCHITECTURE
+#define _HYBRID_SYNTH
+
+/* FM synth on DSP */
+#elif defined(EAS_SPLIT_FM_SYNTH)
+#define _FM_SYNTH
+#define _SPLIT_ARCHITECTURE
+
+#else
+#error "Unrecognized architecture option"
+#endif
+
+#endif
+
diff --git a/arm-fm-22k/lib_src/eas_vm_protos.h b/arm-fm-22k/lib_src/eas_vm_protos.h
index eb49ba8..20f7c09 100644
--- a/arm-fm-22k/lib_src/eas_vm_protos.h
+++ b/arm-fm-22k/lib_src/eas_vm_protos.h
@@ -1,12 +1,12 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_vm_protos.h
- *
- * Contents and purpose:
- * Declarations, interfaces, and prototypes for voice manager.
- *
- * Copyright Sonic Network Inc. 2004
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_vm_protos.h
+ *
+ * Contents and purpose:
+ * Declarations, interfaces, and prototypes for voice manager.
+ *
+ * Copyright Sonic Network Inc. 2004
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,1068 +19,1068 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 736 $
- * $Date: 2007-06-22 13:51:24 -0700 (Fri, 22 Jun 2007) $
- *----------------------------------------------------------------------------
-*/
-
-#ifndef _EAS_VM_PROTOS_H
-#define _EAS_VM_PROTOS_H
-
-// includes
-#include "eas_data.h"
-#include "eas_sndlib.h"
-
-/*----------------------------------------------------------------------------
- * VMInitialize()
- *----------------------------------------------------------------------------
- * Purpose:
- *
- * Inputs:
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT VMInitialize (S_EAS_DATA *pEASData);
-
-/*----------------------------------------------------------------------------
- * VMInitMIDI()
- *----------------------------------------------------------------------------
- * Purpose:
- *
- * Inputs:
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT VMInitMIDI (S_EAS_DATA *pEASData, S_SYNTH **ppSynth);
-
-/*----------------------------------------------------------------------------
- * VMInitializeAllChannels()
- *----------------------------------------------------------------------------
- * Purpose:
- *
- * Inputs:
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- *
- *----------------------------------------------------------------------------
-*/
-void VMInitializeAllChannels (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth);
-
-/*----------------------------------------------------------------------------
- * VMResetControllers()
- *----------------------------------------------------------------------------
- * Purpose:
- *
- * Inputs:
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- *
- *----------------------------------------------------------------------------
-*/
-void VMResetControllers (S_SYNTH *pSynth);
-
-/*----------------------------------------------------------------------------
- * VMInitMIPTable()
- *----------------------------------------------------------------------------
- * Purpose:
- * Initialize the SP-MIDI MIP table
- *
- * Inputs:
- * pEASData - pointer to synthesizer instance data
- * mute - EAS_FALSE to unmute channels, EAS_TRUE to mute
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-void VMInitMIPTable (S_SYNTH *pSynth);
-
-/*----------------------------------------------------------------------------
- * VMSetMIPEntry()
- *----------------------------------------------------------------------------
- * Purpose:
- * Sets the priority and MIP level for a MIDI channel
- *
- * Inputs:
- * pEASData - pointer to synthesizer instance data
- * channel - MIDI channel number
- * priority - priority (0-15 with 0 = highest priority)
- * mip - maximum instantaneous polyphony
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-void VMSetMIPEntry (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel, EAS_U8 priority, EAS_U8 mip);
-
-/*----------------------------------------------------------------------------
- * VMUpdateMIPTable()
- *----------------------------------------------------------------------------
- * Purpose:
- * This routine is called when the polyphony count in the synthesizer changes
- *
- * Inputs:
- * pEASData - pointer to synthesizer instance data
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-void VMUpdateMIPTable (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth);
-
-/*----------------------------------------------------------------------------
- * VMInitializeAllVoices()
- *----------------------------------------------------------------------------
- * Purpose:
- *
- * Inputs:
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- *
- *----------------------------------------------------------------------------
-*/
-void VMInitializeAllVoices (S_VOICE_MGR *pVoiceMgr, EAS_INT vSynthNum);
-
-/*----------------------------------------------------------------------------
- * VMStartNote()
- *----------------------------------------------------------------------------
- * Purpose:
- * Update the synth's state to play the requested note on the requested
- * channel if possible.
- *
- * Inputs:
- * nChannel - the MIDI channel
- * nKeyNumber - the MIDI key number for this note
- * nNoteVelocity - the key velocity for this note
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- *
- *----------------------------------------------------------------------------
-*/
-void VMStartNote (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel, EAS_U8 note, EAS_U8 velocity);
-
-/*----------------------------------------------------------------------------
- * VMCheckKeyGroup()
- *----------------------------------------------------------------------------
- * Purpose:
- * If the note that we've been asked to start is in the same key group as
- * any currently playing notes, then we must shut down the currently playing
- * note in the same key group and then start the newly requested note.
- *
- * Inputs:
- * nChannel - synth channel that wants to start a new note
- * nKeyNumber - new note's midi note number
- * nRegionIndex - calling routine finds this index and gives to us
- * nNoteVelocity - new note's velocity
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- * pbVoiceStealingRequired - flag: this routine sets true if we needed to
- * steal a voice
- *
- * Side Effects:
- * gsSynthObject.m_sVoice[free voice num].m_nKeyNumber may be assigned
- * gsSynthObject.m_sVoice[free voice num].m_nVelocity may be assigned
- *----------------------------------------------------------------------------
-*/
-void VMCheckKeyGroup (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U16 keyGroup, EAS_U8 channel);
-
-/*----------------------------------------------------------------------------
- * VMCheckPolyphonyLimiting()
- *----------------------------------------------------------------------------
- * Purpose:
- * We only play at most 2 of the same note on a MIDI channel.
- * E.g., if we are asked to start note 36, and there are already two voices
- * that are playing note 36, then we must steal the voice playing
- * the oldest note 36 and use that stolen voice to play the new note 36.
- *
- * Inputs:
- * nChannel - synth channel that wants to start a new note
- * nKeyNumber - new note's midi note number
- * nNoteVelocity - new note's velocity
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- * pbVoiceStealingRequired - flag: this routine sets true if we needed to
- * steal a voice
- * *
- * Side Effects:
- * psSynthObject->m_sVoice[free voice num].m_nKeyNumber may be assigned
- * psSynthObject->m_sVoice[free voice num].m_nVelocity may be assigned
- *----------------------------------------------------------------------------
-*/
-EAS_BOOL VMCheckPolyphonyLimiting (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel, EAS_U8 note, EAS_U8 velocity, EAS_U16 regionIndex, EAS_I32 lowVoice, EAS_I32 highVoice);
-
-/*----------------------------------------------------------------------------
- * VMStopNote()
- *----------------------------------------------------------------------------
- * Purpose:
- * Update the synth's state to end the requested note on the requested
- * channel.
- *
- * Inputs:
- * nChannel - the MIDI channel
- * nKeyNumber - the key number of the note to stop
- * nNoteVelocity - the note-off velocity
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- * Side Effects:
- * gsSynthObject.m_sVoice[free voice num].m_nSynthChannel may be assigned
- * gsSynthObject.m_sVoice[free voice num].m_nKeyNumber is assigned
- * gsSynthObject.m_sVoice[free voice num].m_nVelocity is assigned
- *----------------------------------------------------------------------------
-*/
-void VMStopNote (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel, EAS_U8 key, EAS_U8 velocity);
-
-/*----------------------------------------------------------------------------
- * VMFindAvailableVoice()
- *----------------------------------------------------------------------------
- * Purpose:
- * Find an available voice and return the voice number if available.
- *
- * Inputs:
- * pnVoiceNumber - really an output, see below
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- * pnVoiceNumber - returns the voice number of available voice if found
- * success - if there is an available voice
- * failure - otherwise
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT VMFindAvailableVoice (S_VOICE_MGR *pVoiceMgr, EAS_INT *pVoiceNumber, EAS_I32 lowVoice, EAS_I32 highVoice);
-
-/*----------------------------------------------------------------------------
- * VMStealVoice()
- *----------------------------------------------------------------------------
- * Purpose:
- * Steal a voice and return the voice number
- *
- * Stealing algorithm: steal the best choice with minimal work, taking into
- * account SP-Midi channel priorities and polyphony allocation.
- *
- * In one pass through all the voices, figure out which voice to steal
- * taking into account a number of different factors:
- * Priority of the voice's MIDI channel
- * Number of voices over the polyphony allocation for voice's MIDI channel
- * Amplitude of the voice
- * Note age
- * Key velocity (for voices that haven't been started yet)
- * If any matching notes are found
- *
- * Inputs:
- * nChannel - the channel that this voice wants to be started on
- * nKeyNumber - the key number for this new voice
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- * pnVoiceNumber - voice stolen
- * EAS_RESULT EAS_SUCCESS - always successful
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT VMStealVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_INT *pVoiceNumber, EAS_U8 channel, EAS_U8 note, EAS_I32 lowVoice, EAS_I32 highVoice);
-
-/*----------------------------------------------------------------------------
- * VMAddSamples()
- *----------------------------------------------------------------------------
- * Purpose:
- * Synthesize the requested number of samples.
- *
- * Inputs:
- * nNumSamplesToAdd - number of samples to write to buffer
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- * number of samples actually written to buffer
- *
- * Side Effects:
- * - samples are added to the presently free buffer
- *
- *----------------------------------------------------------------------------
-*/
-EAS_I32 VMAddSamples (S_VOICE_MGR *pVoiceMgr, EAS_I32 *pMixBuffer, EAS_I32 numSamplesToAdd);
-
-/*----------------------------------------------------------------------------
- * VMProgramChange()
- *----------------------------------------------------------------------------
- * Purpose:
- * Change the instrument (program) for the given channel.
- *
- * Depending on the program number, and the bank selected for this channel, the
- * program may be in ROM, RAM (from SMAF or CMX related RAM wavetable), or
- * Alternate wavetable (from mobile DLS or other DLS file)
- *
- * This function figures out what wavetable should be used, and sets it up as the
- * wavetable to use for this channel. Also the channel may switch from a melodic
- * channel to a rhythm channel, or vice versa.
- *
- * Inputs:
- *
- * Outputs:
- * Side Effects:
- * gsSynthObject.m_sChannel[nChannel].m_nProgramNumber is likely changed
- * gsSynthObject.m_sChannel[nChannel].m_psEAS may be changed
- * gsSynthObject.m_sChannel[nChannel].m_bRhythmChannel may be changed
- *
- *----------------------------------------------------------------------------
-*/
-void VMProgramChange (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel, EAS_U8 program);
-
-/*----------------------------------------------------------------------------
- * VMChannelPressure()
- *----------------------------------------------------------------------------
- * Purpose:
- * Change the channel pressure for the given channel
- *
- * Inputs:
- * nChannel - the MIDI channel
- * nVelocity - the channel pressure value
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- * Side Effects:
- * gsSynthObject.m_sChannel[nChannel].m_nChannelPressure is updated
- *----------------------------------------------------------------------------
-*/
-void VMChannelPressure (S_SYNTH *pSynth, EAS_U8 channel, EAS_U8 value);
-
-/*----------------------------------------------------------------------------
- * VMPitchBend()
- *----------------------------------------------------------------------------
- * Purpose:
- * Change the pitch wheel value for the given channel.
- * This routine constructs the proper 14-bit argument when the calling routine
- * passes the pitch LSB and MSB.
- *
- * Note: some midi disassemblers display a bipolar pitch bend value.
- * We can display the bipolar value using
- * if m_nPitchBend >= 0x2000
- * bipolar pitch bend = postive (m_nPitchBend - 0x2000)
- * else
- * bipolar pitch bend = negative (0x2000 - m_nPitchBend)
- *
- * Inputs:
- * nChannel - the MIDI channel
- * nPitchLSB - the LSB byte from the pitch bend message
- * nPitchMSB - the MSB byte from the message
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- *
- * Side Effects:
- * gsSynthObject.m_sChannel[nChannel].m_nPitchBend is changed
- *
- *----------------------------------------------------------------------------
-*/
-void VMPitchBend (S_SYNTH *pSynth, EAS_U8 channel, EAS_U8 pitchLSB, EAS_U8 pitchMSB);
-
-/*----------------------------------------------------------------------------
- * VMControlChange()
- *----------------------------------------------------------------------------
- * Purpose:
- * Change the controller (or mode) for the given channel.
- *
- * Inputs:
- * nChannel - the MIDI channel
- * nControllerNumber - the controller number
- * nControlValue - the controller number for this control change
- * nControlValue - the value for this control change
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- * Side Effects:
- * gsSynthObject.m_sChannel[nChannel] controller is changed
- *
- *----------------------------------------------------------------------------
-*/
-void VMControlChange (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel, EAS_U8 controller, EAS_U8 value);
-
-/*----------------------------------------------------------------------------
- * VMUpdateRPNStateMachine()
- *----------------------------------------------------------------------------
- * Purpose:
- * Call this function when we want to parse a stream of RPN messages.
- * NOTE: The synth has only one set of global RPN data instead of RPN data
- * per channel.
- * So actually, we don't really need to look at the nChannel parameter,
- * but we pass it to facilitate future upgrades. Furthermore, we only
- * support RPN0 (pitch bend sensitivity), RPN1 (fine tuning) and
- * RPN2 (coarse tuning). Any other RPNs are rejected.
- *
- * Inputs:
- * nChannel - the MIDI channel
- * nControllerNumber - the RPN controller number
- * nControlValue - the value for this control change
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- *
- * Side Effects:
- * gsSynthObject.m_RPN0 (or m_RPN1 or m_RPN2) may be updated if the
- * proper RPN message sequence is parsed.
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT VMUpdateRPNStateMachine (S_SYNTH *pSynth, EAS_U8 channel, EAS_U8 controller, EAS_U8 value);
-
-/*----------------------------------------------------------------------------
- * VMUpdateStaticChannelParameters()
- *----------------------------------------------------------------------------
- * Purpose:
- * Update all of the static channel parameters for channels that have had
- * a controller change values
- * Or if the synth has signalled that all channels must forcibly
- * be updated
- *
- * Inputs:
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- * none
- *
- * Side Effects:
- * - psSynthObject->m_sChannel[].m_nStaticGain and m_nStaticPitch
- * are updated for channels whose controller values have changed
- * or if the synth has signalled that all channels must forcibly
- * be updated
- *----------------------------------------------------------------------------
-*/
-void VMUpdateStaticChannelParameters (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth);
-
-/*----------------------------------------------------------------------------
- * VMReleaseAllDeferredNoteOffs()
- *----------------------------------------------------------------------------
- * Purpose:
- * Call this functin when the sustain flag is presently set but
- * we are now transitioning from damper pedal on to
- * damper pedal off. This means all notes in this channel
- * that received a note off while the damper pedal was on, and
- * had their note-off requests deferred, should now proceed to
- * the release state.
- *
- * Inputs:
- * nChannel - this channel has its sustain pedal transitioning from on to off
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- * Side Effects:
- * any voice with deferred note offs on this channel are updated such that
- *
- *
- *----------------------------------------------------------------------------
-*/
-void VMReleaseAllDeferredNoteOffs (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel);
-
-/*----------------------------------------------------------------------------
- * VMCatchNotesForSustainPedal()
- *----------------------------------------------------------------------------
- * Purpose:
- * Call this function when the sustain flag is presently clear and
- * the damper pedal is off and we are transitioning from damper pedal OFF to
- * damper pedal ON. Currently sounding notes should be left
- * unchanged. However, we should try to "catch" notes if possible.
- * If any notes have levels >= sustain level, catch them,
- * otherwise, let them continue to release.
- *
- * Inputs:
- * nChannel - this channel has its sustain pedal transitioning from on to off
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- * Side Effects:
- * any voice with deferred note offs on this channel are updated such that
- * psVoice->m_sEG1.m_eState = eEnvelopeStateSustainPedal
- *----------------------------------------------------------------------------
-*/
-void VMCatchNotesForSustainPedal (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel);
-
-/*----------------------------------------------------------------------------
- * VMUpdateAllNotesAge()
- *----------------------------------------------------------------------------
- * Purpose:
- * Increment the note age for all voices older than the age of the voice
- * that is stopping, effectively making the voices "younger".
- *
- * Inputs:
- * nAge - age of voice that is going away
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- *
- * Side Effects:
- * m_nAge for some voices is incremented
- *----------------------------------------------------------------------------
-*/
-void VMUpdateAllNotesAge (S_VOICE_MGR *pVoiceMgr, EAS_U16 nAge);
-
-/*----------------------------------------------------------------------------
- * VMFindRegionIndex()
- *----------------------------------------------------------------------------
- * Purpose:
- * Find the region index for the given instrument using the midi key number
- * and the RPN2 (coarse tuning) value. By using RPN2 as part of the
- * region selection process, we reduce the amount a given sample has
- * to be transposed by selecting the closest recorded root instead.
- *
- * Inputs:
- * nChannel - current channel for this note
- * nKeyNumber - current midi note number
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- * pnRegionIndex - valid only if we returned success
- * success if we found the region index number, otherwise
- * failure
- *
- * Side Effects:
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT VMFindRegionIndex (S_VOICE_MGR *pVoiceMgr, EAS_U8 channel, EAS_U8 note, EAS_U16 *pRegionIndex);
-
-/*----------------------------------------------------------------------------
- * VMIncRefCount()
- *----------------------------------------------------------------------------
- * Increment reference count for virtual synth
- *----------------------------------------------------------------------------
-*/
-void VMIncRefCount (S_SYNTH *pSynth);
-
-/*----------------------------------------------------------------------------
- * VMReset()
- *----------------------------------------------------------------------------
- * Purpose:
- * We call this routine to start the process of reseting the synth.
- * This routine sets a flag for the entire synth indicating that we want
- * to reset.
- * We also force all voices to mute quickly.
- * However, we do not actually perform any synthesis in this routine. That
- * is, we do not ramp the voices down from this routine, but instead, we
- * let the "regular" synth processing steps take care of adding the ramp
- * down samples to the output buffer. After we are sure that all voices
- * have completed ramping down, we continue the process of resetting the
- * synth (from another routine).
- *
- * Inputs:
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- *
- * Side Effects:
- * - set a flag (in gsSynthObject.m_nFlags) indicating synth reset requested.
- * - force all voices to update their envelope states to mute
- *
- *----------------------------------------------------------------------------
-*/
-void VMReset (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_BOOL force);
-
-/*----------------------------------------------------------------------------
- * VMMuteAllVoices()
- *----------------------------------------------------------------------------
- * Purpose:
- * We call this in an emergency reset situation.
- * This forces all voices to mute quickly.
- *
- * Inputs:
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- *
- * Side Effects:
- * - forces all voices to update their envelope states to mute
- *
- *----------------------------------------------------------------------------
-*/
-void VMMuteVoice (S_VOICE_MGR *pVoiceMgr, EAS_I32 voiceNum);
-void VMMuteAllVoices (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth);
-
-/*----------------------------------------------------------------------------
- * VMReleaseAllVoices()
- *----------------------------------------------------------------------------
- * Purpose:
- * We call this after we've encountered the end of the Midi file.
- * This ensures all voice are either in release (because we received their
- * note off already) or forces them to mute quickly.
- * We use this as a safety to prevent bad midi files from playing forever.
- *
- * Inputs:
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- *
- * Side Effects:
- * - forces all voices to update their envelope states to release or mute
- *
- *----------------------------------------------------------------------------
-*/
-void VMReleaseAllVoices (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth);
-
-/*----------------------------------------------------------------------------
- * VMAllNotesOff()
- *----------------------------------------------------------------------------
- * Purpose:
- * Quickly mute all notes on the given channel.
- *
- * Inputs:
- * nChannel - quickly turn off all notes on this channel
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- *
- * Side Effects:
- * - forces all voices on this channel to update their envelope states to mute
- *
- *----------------------------------------------------------------------------
-*/
-void VMAllNotesOff (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel);
-
-/*----------------------------------------------------------------------------
- * VMDeferredStopNote()
- *----------------------------------------------------------------------------
- * Purpose:
- * Stop the notes that had deferred note-off requests.
- *
- * Inputs:
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- * None.
- *
- * Side Effects:
- * voices that have had deferred note-off requests are now put into release
- * gsSynthObject.m_sVoice[i].m_nFlags has the VOICE_FLAG_DEFER_MIDI_NOTE_OFF
- * cleared
- *----------------------------------------------------------------------------
-*/
-void VMDeferredStopNote (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth);
-
-/*----------------------------------------------------------------------------
- * VMSetSynthPolyphony()
- *----------------------------------------------------------------------------
- * Purpose:
- * Set the synth to a new polyphony value. Value must be >= 1 and
- * <= MAX_SYNTH_VOICES. This function will pin the polyphony at those limits
- *
- * Inputs:
- * pVoiceMgr pointer to synthesizer data
- * synth synthesizer number (0 = onboard, 1 = DSP)
- * polyphonyCount desired polyphony count
- *
- * Outputs:
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT VMSetSynthPolyphony (S_VOICE_MGR *pVoiceMgr, EAS_I32 synth, EAS_I32 polyphonyCount);
-
-/*----------------------------------------------------------------------------
- * VMGetSynthPolyphony()
- *----------------------------------------------------------------------------
- * Purpose:
- * Set the synth to a new polyphony value. Value must be >= 1 and
- * <= MAX_SYNTH_VOICES. This function will pin the polyphony at those limits
- *
- * Inputs:
- * pVoiceMgr pointer to synthesizer data
- * synth synthesizer number (0 = onboard, 1 = DSP)
- * polyphonyCount desired polyphony count
- *
- * Outputs:
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT VMGetSynthPolyphony (S_VOICE_MGR *pVoiceMgr, EAS_I32 synth, EAS_I32 *pPolyphonyCount);
-
-/*----------------------------------------------------------------------------
- * VMSetPolyphony()
- *----------------------------------------------------------------------------
- * Purpose:
- * Set the virtual synth polyphony. 0 = no limit (i.e. can use
- * all available voices).
- *
- * Inputs:
- * pVoiceMgr pointer to synthesizer data
- * polyphonyCount desired polyphony count
- * pSynth pointer to virtual synth
- *
- * Outputs:
- * Returns error code
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT VMSetPolyphony (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_I32 polyphonyCount);
-
-/*----------------------------------------------------------------------------
- * VMGetPolyphony()
- *----------------------------------------------------------------------------
- * Purpose:
- * Returns the current polyphony setting
- *
- * Inputs:
- * pVoiceMgr pointer to synthesizer data
- * pSynth pointer to virtual synth
- * pPolyphonyCount pointer to variable to receive data
- *
- * Outputs:
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT VMGetPolyphony (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_I32 *pPolyphonyCount);
-
-/*----------------------------------------------------------------------------
- * VMSetPriority()
- *----------------------------------------------------------------------------
- * Purpose:
- * Set the virtual synth priority
- *
- * Inputs:
- * pVoiceMgr pointer to synthesizer data
- * priority new priority
- * pSynth pointer to virtual synth
- *
- * Outputs:
- * Returns error code
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT VMSetPriority (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_I32 priority);
-
-/*----------------------------------------------------------------------------
- * VMGetPriority()
- *----------------------------------------------------------------------------
- * Purpose:
- * Get the virtual synth priority
- *
- * Inputs:
- * pVoiceMgr pointer to synthesizer data
- * pPriority pointer to variable to hold priority
- * pSynth pointer to virtual synth
- *
- * Outputs:
- * Returns error code
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT VMGetPriority (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_I32 *pPriority);
-
-/*----------------------------------------------------------------------------
- * VMSetVolume()
- *----------------------------------------------------------------------------
- * Purpose:
- * Set the master volume for this sequence
- *
- * Inputs:
- * nSynthVolume - the desired master volume
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- *
- *
- * Side Effects:
- * overrides any previously set master volume from sysex
- *
- *----------------------------------------------------------------------------
-*/
-void VMSetVolume (S_SYNTH *pSynth, EAS_U16 masterVolume);
-
-/*----------------------------------------------------------------------------
- * VMSetPitchBendRange()
- *----------------------------------------------------------------------------
- * Set the pitch bend range for the given channel.
- *----------------------------------------------------------------------------
-*/
-void VMSetPitchBendRange (S_SYNTH *pSynth, EAS_INT channel, EAS_I16 pitchBendRange);
-
-/*----------------------------------------------------------------------------
- * VMSetEASLib()
- *----------------------------------------------------------------------------
- * Purpose:
- * Sets the pointer to the sound library
- *
- * Inputs:
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT VMSetGlobalEASLib (S_VOICE_MGR *pVoiceMgr, EAS_SNDLIB_HANDLE pEAS);
-EAS_RESULT VMSetEASLib (S_SYNTH *pSynth, EAS_SNDLIB_HANDLE pEAS);
-
-#ifdef DLS_SYNTHESIZER
-/*----------------------------------------------------------------------------
- * VMSetDLSLib()
- *----------------------------------------------------------------------------
- * Purpose:
- * Sets the pointer to the sound library
- *
- * Inputs:
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT VMSetGlobalDLSLib (EAS_DATA_HANDLE pEASData, EAS_DLSLIB_HANDLE pDLS);
-EAS_RESULT VMSetDLSLib (S_SYNTH *pSynth, EAS_DLSLIB_HANDLE pDLS);
-#endif
-
-/*----------------------------------------------------------------------------
- * VMSetTranposition()
- *----------------------------------------------------------------------------
- * Purpose:
- * Sets the global key transposition used by the synthesizer.
- * Transposes all melodic instruments up or down by the specified
- * amount. Range is limited to +/-12 semitones.
- *
- * Inputs:
- * psEASData - pointer to overall EAS data structure
- * transposition - transpose amount (+/-12)
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-void VMSetTranposition (S_SYNTH *pSynth, EAS_I32 transposition);
-
-/*----------------------------------------------------------------------------
- * VMGetTranposition()
- *----------------------------------------------------------------------------
- * Purpose:
- * Gets the global key transposition used by the synthesizer.
- * Transposes all melodic instruments up or down by the specified
- * amount. Range is limited to +/-12 semitones.
- *
- * Inputs:
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-void VMGetTranposition (S_SYNTH *pSynth, EAS_I32 *pTransposition);
-
-/*----------------------------------------------------------------------------
- * VMGetNoteCount()
- *----------------------------------------------------------------------------
-* Returns the total note count
-*----------------------------------------------------------------------------
-*/
-EAS_I32 VMGetNoteCount (S_SYNTH *pSynth);
-
-/*----------------------------------------------------------------------------
- * VMRender()
- *----------------------------------------------------------------------------
- * Purpose:
- * This routine renders a frame of audio
- *
- * Inputs:
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- * pVoicesRendered - number of voices rendered this frame
- *
- * Side Effects:
- * sets psMidiObject->m_nMaxWorkloadPerFrame
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT VMRender (S_VOICE_MGR *pVoiceMgr, EAS_I32 numSamples, EAS_I32 *pMixBuffer, EAS_I32 *pVoicesRendered);
-
-/*----------------------------------------------------------------------------
- * VMInitWorkload()
- *----------------------------------------------------------------------------
- * Purpose:
- * Clears the workload counter
- *
- * Inputs:
- * pVoiceMgr - pointer to instance data
- *
- * Outputs:
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-void VMInitWorkload (S_VOICE_MGR *pVoiceMgr);
-
-/*----------------------------------------------------------------------------
- * VMSetWorkload()
- *----------------------------------------------------------------------------
- * Purpose:
- * Sets the max workload for a single frame.
- *
- * Inputs:
- * pVoiceMgr - pointer to instance data
- *
- * Outputs:
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-void VMSetWorkload (S_VOICE_MGR *pVoiceMgr, EAS_I32 maxWorkLoad);
-
-/*----------------------------------------------------------------------------
- * VMCheckWorkload()
- *----------------------------------------------------------------------------
- * Purpose:
- * Checks to see if work load has been exceeded on this frame.
- *
- * Inputs:
- * pVoiceMgr - pointer to instance data
- *
- * Outputs:
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_BOOL VMCheckWorkload (S_VOICE_MGR *pVoiceMgr);
-
-/*----------------------------------------------------------------------------
- * VMActiveVoices()
- *----------------------------------------------------------------------------
- * Purpose:
- * Returns the number of active voices in the synthesizer.
- *
- * Inputs:
- * pEASData - pointer to instance data
- *
- * Outputs:
- * Returns the number of active voices
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_I32 VMActiveVoices (S_SYNTH *pSynth);
-
-/*----------------------------------------------------------------------------
- * VMMIDIShutdown()
- *----------------------------------------------------------------------------
- * Purpose:
- * Clean up any Synth related system issues.
- *
- * Inputs:
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- * None
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-void VMMIDIShutdown (S_EAS_DATA *pEASData, S_SYNTH *pSynth);
-
-/*----------------------------------------------------------------------------
- * VMShutdown()
- *----------------------------------------------------------------------------
- * Purpose:
- * Clean up any Synth related system issues.
- *
- * Inputs:
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- * None
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-void VMShutdown (S_EAS_DATA *pEASData);
-
-#ifdef EXTERNAL_AUDIO
-/*----------------------------------------------------------------------------
- * EAS_RegExtAudioCallback()
- *----------------------------------------------------------------------------
- * Register a callback for external audio processing
- *----------------------------------------------------------------------------
-*/
-void VMRegExtAudioCallback (S_SYNTH *pSynth, EAS_VOID_PTR pInstData, EAS_EXT_PRG_CHG_FUNC cbProgChgFunc, EAS_EXT_EVENT_FUNC cbEventFunc);
-
-/*----------------------------------------------------------------------------
- * VMGetMIDIControllers()
- *----------------------------------------------------------------------------
- * Returns the MIDI controller values on the specified channel
- *----------------------------------------------------------------------------
-*/
-void VMGetMIDIControllers (S_SYNTH *pSynth, EAS_U8 channel, S_MIDI_CONTROLLERS *pControl);
-#endif
-
-#ifdef _SPLIT_ARCHITECTURE
-/*----------------------------------------------------------------------------
- * VMStartFrame()
- *----------------------------------------------------------------------------
- * Purpose:
- * Starts an audio frame
- *
- * Inputs:
- *
- * Outputs:
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_BOOL VMStartFrame (S_EAS_DATA *pEASData);
-
-/*----------------------------------------------------------------------------
- * VMEndFrame()
- *----------------------------------------------------------------------------
- * Purpose:
- * Stops an audio frame
- *
- * Inputs:
- *
- * Outputs:
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_BOOL VMEndFrame (S_EAS_DATA *pEASData);
-#endif
-
-#endif /* #ifdef _EAS_VM_PROTOS_H */
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 736 $
+ * $Date: 2007-06-22 13:51:24 -0700 (Fri, 22 Jun 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+#ifndef _EAS_VM_PROTOS_H
+#define _EAS_VM_PROTOS_H
+
+// includes
+#include "eas_data.h"
+#include "eas_sndlib.h"
+
+/*----------------------------------------------------------------------------
+ * VMInitialize()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ *
+ * Inputs:
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT VMInitialize (S_EAS_DATA *pEASData);
+
+/*----------------------------------------------------------------------------
+ * VMInitMIDI()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ *
+ * Inputs:
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT VMInitMIDI (S_EAS_DATA *pEASData, S_SYNTH **ppSynth);
+
+/*----------------------------------------------------------------------------
+ * VMInitializeAllChannels()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ *
+ * Inputs:
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ *
+ *----------------------------------------------------------------------------
+*/
+void VMInitializeAllChannels (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth);
+
+/*----------------------------------------------------------------------------
+ * VMResetControllers()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ *
+ * Inputs:
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ *
+ *----------------------------------------------------------------------------
+*/
+void VMResetControllers (S_SYNTH *pSynth);
+
+/*----------------------------------------------------------------------------
+ * VMInitMIPTable()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Initialize the SP-MIDI MIP table
+ *
+ * Inputs:
+ * pEASData - pointer to synthesizer instance data
+ * mute - EAS_FALSE to unmute channels, EAS_TRUE to mute
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+void VMInitMIPTable (S_SYNTH *pSynth);
+
+/*----------------------------------------------------------------------------
+ * VMSetMIPEntry()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Sets the priority and MIP level for a MIDI channel
+ *
+ * Inputs:
+ * pEASData - pointer to synthesizer instance data
+ * channel - MIDI channel number
+ * priority - priority (0-15 with 0 = highest priority)
+ * mip - maximum instantaneous polyphony
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+void VMSetMIPEntry (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel, EAS_U8 priority, EAS_U8 mip);
+
+/*----------------------------------------------------------------------------
+ * VMUpdateMIPTable()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * This routine is called when the polyphony count in the synthesizer changes
+ *
+ * Inputs:
+ * pEASData - pointer to synthesizer instance data
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+void VMUpdateMIPTable (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth);
+
+/*----------------------------------------------------------------------------
+ * VMInitializeAllVoices()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ *
+ * Inputs:
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ *
+ *----------------------------------------------------------------------------
+*/
+void VMInitializeAllVoices (S_VOICE_MGR *pVoiceMgr, EAS_INT vSynthNum);
+
+/*----------------------------------------------------------------------------
+ * VMStartNote()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Update the synth's state to play the requested note on the requested
+ * channel if possible.
+ *
+ * Inputs:
+ * nChannel - the MIDI channel
+ * nKeyNumber - the MIDI key number for this note
+ * nNoteVelocity - the key velocity for this note
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ *
+ *----------------------------------------------------------------------------
+*/
+void VMStartNote (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel, EAS_U8 note, EAS_U8 velocity);
+
+/*----------------------------------------------------------------------------
+ * VMCheckKeyGroup()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * If the note that we've been asked to start is in the same key group as
+ * any currently playing notes, then we must shut down the currently playing
+ * note in the same key group and then start the newly requested note.
+ *
+ * Inputs:
+ * nChannel - synth channel that wants to start a new note
+ * nKeyNumber - new note's midi note number
+ * nRegionIndex - calling routine finds this index and gives to us
+ * nNoteVelocity - new note's velocity
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ * pbVoiceStealingRequired - flag: this routine sets true if we needed to
+ * steal a voice
+ *
+ * Side Effects:
+ * gsSynthObject.m_sVoice[free voice num].m_nKeyNumber may be assigned
+ * gsSynthObject.m_sVoice[free voice num].m_nVelocity may be assigned
+ *----------------------------------------------------------------------------
+*/
+void VMCheckKeyGroup (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U16 keyGroup, EAS_U8 channel);
+
+/*----------------------------------------------------------------------------
+ * VMCheckPolyphonyLimiting()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * We only play at most 2 of the same note on a MIDI channel.
+ * E.g., if we are asked to start note 36, and there are already two voices
+ * that are playing note 36, then we must steal the voice playing
+ * the oldest note 36 and use that stolen voice to play the new note 36.
+ *
+ * Inputs:
+ * nChannel - synth channel that wants to start a new note
+ * nKeyNumber - new note's midi note number
+ * nNoteVelocity - new note's velocity
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ * pbVoiceStealingRequired - flag: this routine sets true if we needed to
+ * steal a voice
+ * *
+ * Side Effects:
+ * psSynthObject->m_sVoice[free voice num].m_nKeyNumber may be assigned
+ * psSynthObject->m_sVoice[free voice num].m_nVelocity may be assigned
+ *----------------------------------------------------------------------------
+*/
+EAS_BOOL VMCheckPolyphonyLimiting (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel, EAS_U8 note, EAS_U8 velocity, EAS_U16 regionIndex, EAS_I32 lowVoice, EAS_I32 highVoice);
+
+/*----------------------------------------------------------------------------
+ * VMStopNote()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Update the synth's state to end the requested note on the requested
+ * channel.
+ *
+ * Inputs:
+ * nChannel - the MIDI channel
+ * nKeyNumber - the key number of the note to stop
+ * nNoteVelocity - the note-off velocity
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ * Side Effects:
+ * gsSynthObject.m_sVoice[free voice num].m_nSynthChannel may be assigned
+ * gsSynthObject.m_sVoice[free voice num].m_nKeyNumber is assigned
+ * gsSynthObject.m_sVoice[free voice num].m_nVelocity is assigned
+ *----------------------------------------------------------------------------
+*/
+void VMStopNote (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel, EAS_U8 key, EAS_U8 velocity);
+
+/*----------------------------------------------------------------------------
+ * VMFindAvailableVoice()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Find an available voice and return the voice number if available.
+ *
+ * Inputs:
+ * pnVoiceNumber - really an output, see below
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ * pnVoiceNumber - returns the voice number of available voice if found
+ * success - if there is an available voice
+ * failure - otherwise
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT VMFindAvailableVoice (S_VOICE_MGR *pVoiceMgr, EAS_INT *pVoiceNumber, EAS_I32 lowVoice, EAS_I32 highVoice);
+
+/*----------------------------------------------------------------------------
+ * VMStealVoice()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Steal a voice and return the voice number
+ *
+ * Stealing algorithm: steal the best choice with minimal work, taking into
+ * account SP-Midi channel priorities and polyphony allocation.
+ *
+ * In one pass through all the voices, figure out which voice to steal
+ * taking into account a number of different factors:
+ * Priority of the voice's MIDI channel
+ * Number of voices over the polyphony allocation for voice's MIDI channel
+ * Amplitude of the voice
+ * Note age
+ * Key velocity (for voices that haven't been started yet)
+ * If any matching notes are found
+ *
+ * Inputs:
+ * nChannel - the channel that this voice wants to be started on
+ * nKeyNumber - the key number for this new voice
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ * pnVoiceNumber - voice stolen
+ * EAS_RESULT EAS_SUCCESS - always successful
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT VMStealVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_INT *pVoiceNumber, EAS_U8 channel, EAS_U8 note, EAS_I32 lowVoice, EAS_I32 highVoice);
+
+/*----------------------------------------------------------------------------
+ * VMAddSamples()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Synthesize the requested number of samples.
+ *
+ * Inputs:
+ * nNumSamplesToAdd - number of samples to write to buffer
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ * number of samples actually written to buffer
+ *
+ * Side Effects:
+ * - samples are added to the presently free buffer
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_I32 VMAddSamples (S_VOICE_MGR *pVoiceMgr, EAS_I32 *pMixBuffer, EAS_I32 numSamplesToAdd);
+
+/*----------------------------------------------------------------------------
+ * VMProgramChange()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Change the instrument (program) for the given channel.
+ *
+ * Depending on the program number, and the bank selected for this channel, the
+ * program may be in ROM, RAM (from SMAF or CMX related RAM wavetable), or
+ * Alternate wavetable (from mobile DLS or other DLS file)
+ *
+ * This function figures out what wavetable should be used, and sets it up as the
+ * wavetable to use for this channel. Also the channel may switch from a melodic
+ * channel to a rhythm channel, or vice versa.
+ *
+ * Inputs:
+ *
+ * Outputs:
+ * Side Effects:
+ * gsSynthObject.m_sChannel[nChannel].m_nProgramNumber is likely changed
+ * gsSynthObject.m_sChannel[nChannel].m_psEAS may be changed
+ * gsSynthObject.m_sChannel[nChannel].m_bRhythmChannel may be changed
+ *
+ *----------------------------------------------------------------------------
+*/
+void VMProgramChange (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel, EAS_U8 program);
+
+/*----------------------------------------------------------------------------
+ * VMChannelPressure()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Change the channel pressure for the given channel
+ *
+ * Inputs:
+ * nChannel - the MIDI channel
+ * nVelocity - the channel pressure value
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ * Side Effects:
+ * gsSynthObject.m_sChannel[nChannel].m_nChannelPressure is updated
+ *----------------------------------------------------------------------------
+*/
+void VMChannelPressure (S_SYNTH *pSynth, EAS_U8 channel, EAS_U8 value);
+
+/*----------------------------------------------------------------------------
+ * VMPitchBend()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Change the pitch wheel value for the given channel.
+ * This routine constructs the proper 14-bit argument when the calling routine
+ * passes the pitch LSB and MSB.
+ *
+ * Note: some midi disassemblers display a bipolar pitch bend value.
+ * We can display the bipolar value using
+ * if m_nPitchBend >= 0x2000
+ * bipolar pitch bend = postive (m_nPitchBend - 0x2000)
+ * else
+ * bipolar pitch bend = negative (0x2000 - m_nPitchBend)
+ *
+ * Inputs:
+ * nChannel - the MIDI channel
+ * nPitchLSB - the LSB byte from the pitch bend message
+ * nPitchMSB - the MSB byte from the message
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ * gsSynthObject.m_sChannel[nChannel].m_nPitchBend is changed
+ *
+ *----------------------------------------------------------------------------
+*/
+void VMPitchBend (S_SYNTH *pSynth, EAS_U8 channel, EAS_U8 pitchLSB, EAS_U8 pitchMSB);
+
+/*----------------------------------------------------------------------------
+ * VMControlChange()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Change the controller (or mode) for the given channel.
+ *
+ * Inputs:
+ * nChannel - the MIDI channel
+ * nControllerNumber - the controller number
+ * nControlValue - the controller number for this control change
+ * nControlValue - the value for this control change
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ * Side Effects:
+ * gsSynthObject.m_sChannel[nChannel] controller is changed
+ *
+ *----------------------------------------------------------------------------
+*/
+void VMControlChange (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel, EAS_U8 controller, EAS_U8 value);
+
+/*----------------------------------------------------------------------------
+ * VMUpdateRPNStateMachine()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Call this function when we want to parse a stream of RPN messages.
+ * NOTE: The synth has only one set of global RPN data instead of RPN data
+ * per channel.
+ * So actually, we don't really need to look at the nChannel parameter,
+ * but we pass it to facilitate future upgrades. Furthermore, we only
+ * support RPN0 (pitch bend sensitivity), RPN1 (fine tuning) and
+ * RPN2 (coarse tuning). Any other RPNs are rejected.
+ *
+ * Inputs:
+ * nChannel - the MIDI channel
+ * nControllerNumber - the RPN controller number
+ * nControlValue - the value for this control change
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ * gsSynthObject.m_RPN0 (or m_RPN1 or m_RPN2) may be updated if the
+ * proper RPN message sequence is parsed.
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT VMUpdateRPNStateMachine (S_SYNTH *pSynth, EAS_U8 channel, EAS_U8 controller, EAS_U8 value);
+
+/*----------------------------------------------------------------------------
+ * VMUpdateStaticChannelParameters()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Update all of the static channel parameters for channels that have had
+ * a controller change values
+ * Or if the synth has signalled that all channels must forcibly
+ * be updated
+ *
+ * Inputs:
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ * none
+ *
+ * Side Effects:
+ * - psSynthObject->m_sChannel[].m_nStaticGain and m_nStaticPitch
+ * are updated for channels whose controller values have changed
+ * or if the synth has signalled that all channels must forcibly
+ * be updated
+ *----------------------------------------------------------------------------
+*/
+void VMUpdateStaticChannelParameters (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth);
+
+/*----------------------------------------------------------------------------
+ * VMReleaseAllDeferredNoteOffs()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Call this functin when the sustain flag is presently set but
+ * we are now transitioning from damper pedal on to
+ * damper pedal off. This means all notes in this channel
+ * that received a note off while the damper pedal was on, and
+ * had their note-off requests deferred, should now proceed to
+ * the release state.
+ *
+ * Inputs:
+ * nChannel - this channel has its sustain pedal transitioning from on to off
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ * Side Effects:
+ * any voice with deferred note offs on this channel are updated such that
+ *
+ *
+ *----------------------------------------------------------------------------
+*/
+void VMReleaseAllDeferredNoteOffs (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel);
+
+/*----------------------------------------------------------------------------
+ * VMCatchNotesForSustainPedal()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Call this function when the sustain flag is presently clear and
+ * the damper pedal is off and we are transitioning from damper pedal OFF to
+ * damper pedal ON. Currently sounding notes should be left
+ * unchanged. However, we should try to "catch" notes if possible.
+ * If any notes have levels >= sustain level, catch them,
+ * otherwise, let them continue to release.
+ *
+ * Inputs:
+ * nChannel - this channel has its sustain pedal transitioning from on to off
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ * Side Effects:
+ * any voice with deferred note offs on this channel are updated such that
+ * psVoice->m_sEG1.m_eState = eEnvelopeStateSustainPedal
+ *----------------------------------------------------------------------------
+*/
+void VMCatchNotesForSustainPedal (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel);
+
+/*----------------------------------------------------------------------------
+ * VMUpdateAllNotesAge()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Increment the note age for all voices older than the age of the voice
+ * that is stopping, effectively making the voices "younger".
+ *
+ * Inputs:
+ * nAge - age of voice that is going away
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ * m_nAge for some voices is incremented
+ *----------------------------------------------------------------------------
+*/
+void VMUpdateAllNotesAge (S_VOICE_MGR *pVoiceMgr, EAS_U16 nAge);
+
+/*----------------------------------------------------------------------------
+ * VMFindRegionIndex()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Find the region index for the given instrument using the midi key number
+ * and the RPN2 (coarse tuning) value. By using RPN2 as part of the
+ * region selection process, we reduce the amount a given sample has
+ * to be transposed by selecting the closest recorded root instead.
+ *
+ * Inputs:
+ * nChannel - current channel for this note
+ * nKeyNumber - current midi note number
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ * pnRegionIndex - valid only if we returned success
+ * success if we found the region index number, otherwise
+ * failure
+ *
+ * Side Effects:
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT VMFindRegionIndex (S_VOICE_MGR *pVoiceMgr, EAS_U8 channel, EAS_U8 note, EAS_U16 *pRegionIndex);
+
+/*----------------------------------------------------------------------------
+ * VMIncRefCount()
+ *----------------------------------------------------------------------------
+ * Increment reference count for virtual synth
+ *----------------------------------------------------------------------------
+*/
+void VMIncRefCount (S_SYNTH *pSynth);
+
+/*----------------------------------------------------------------------------
+ * VMReset()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * We call this routine to start the process of reseting the synth.
+ * This routine sets a flag for the entire synth indicating that we want
+ * to reset.
+ * We also force all voices to mute quickly.
+ * However, we do not actually perform any synthesis in this routine. That
+ * is, we do not ramp the voices down from this routine, but instead, we
+ * let the "regular" synth processing steps take care of adding the ramp
+ * down samples to the output buffer. After we are sure that all voices
+ * have completed ramping down, we continue the process of resetting the
+ * synth (from another routine).
+ *
+ * Inputs:
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ * - set a flag (in gsSynthObject.m_nFlags) indicating synth reset requested.
+ * - force all voices to update their envelope states to mute
+ *
+ *----------------------------------------------------------------------------
+*/
+void VMReset (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_BOOL force);
+
+/*----------------------------------------------------------------------------
+ * VMMuteAllVoices()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * We call this in an emergency reset situation.
+ * This forces all voices to mute quickly.
+ *
+ * Inputs:
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ * - forces all voices to update their envelope states to mute
+ *
+ *----------------------------------------------------------------------------
+*/
+void VMMuteVoice (S_VOICE_MGR *pVoiceMgr, EAS_I32 voiceNum);
+void VMMuteAllVoices (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth);
+
+/*----------------------------------------------------------------------------
+ * VMReleaseAllVoices()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * We call this after we've encountered the end of the Midi file.
+ * This ensures all voice are either in release (because we received their
+ * note off already) or forces them to mute quickly.
+ * We use this as a safety to prevent bad midi files from playing forever.
+ *
+ * Inputs:
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ * - forces all voices to update their envelope states to release or mute
+ *
+ *----------------------------------------------------------------------------
+*/
+void VMReleaseAllVoices (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth);
+
+/*----------------------------------------------------------------------------
+ * VMAllNotesOff()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Quickly mute all notes on the given channel.
+ *
+ * Inputs:
+ * nChannel - quickly turn off all notes on this channel
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ * - forces all voices on this channel to update their envelope states to mute
+ *
+ *----------------------------------------------------------------------------
+*/
+void VMAllNotesOff (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel);
+
+/*----------------------------------------------------------------------------
+ * VMDeferredStopNote()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Stop the notes that had deferred note-off requests.
+ *
+ * Inputs:
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ * None.
+ *
+ * Side Effects:
+ * voices that have had deferred note-off requests are now put into release
+ * gsSynthObject.m_sVoice[i].m_nFlags has the VOICE_FLAG_DEFER_MIDI_NOTE_OFF
+ * cleared
+ *----------------------------------------------------------------------------
+*/
+void VMDeferredStopNote (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth);
+
+/*----------------------------------------------------------------------------
+ * VMSetSynthPolyphony()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Set the synth to a new polyphony value. Value must be >= 1 and
+ * <= MAX_SYNTH_VOICES. This function will pin the polyphony at those limits
+ *
+ * Inputs:
+ * pVoiceMgr pointer to synthesizer data
+ * synth synthesizer number (0 = onboard, 1 = DSP)
+ * polyphonyCount desired polyphony count
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT VMSetSynthPolyphony (S_VOICE_MGR *pVoiceMgr, EAS_I32 synth, EAS_I32 polyphonyCount);
+
+/*----------------------------------------------------------------------------
+ * VMGetSynthPolyphony()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Set the synth to a new polyphony value. Value must be >= 1 and
+ * <= MAX_SYNTH_VOICES. This function will pin the polyphony at those limits
+ *
+ * Inputs:
+ * pVoiceMgr pointer to synthesizer data
+ * synth synthesizer number (0 = onboard, 1 = DSP)
+ * polyphonyCount desired polyphony count
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT VMGetSynthPolyphony (S_VOICE_MGR *pVoiceMgr, EAS_I32 synth, EAS_I32 *pPolyphonyCount);
+
+/*----------------------------------------------------------------------------
+ * VMSetPolyphony()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Set the virtual synth polyphony. 0 = no limit (i.e. can use
+ * all available voices).
+ *
+ * Inputs:
+ * pVoiceMgr pointer to synthesizer data
+ * polyphonyCount desired polyphony count
+ * pSynth pointer to virtual synth
+ *
+ * Outputs:
+ * Returns error code
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT VMSetPolyphony (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_I32 polyphonyCount);
+
+/*----------------------------------------------------------------------------
+ * VMGetPolyphony()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Returns the current polyphony setting
+ *
+ * Inputs:
+ * pVoiceMgr pointer to synthesizer data
+ * pSynth pointer to virtual synth
+ * pPolyphonyCount pointer to variable to receive data
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT VMGetPolyphony (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_I32 *pPolyphonyCount);
+
+/*----------------------------------------------------------------------------
+ * VMSetPriority()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Set the virtual synth priority
+ *
+ * Inputs:
+ * pVoiceMgr pointer to synthesizer data
+ * priority new priority
+ * pSynth pointer to virtual synth
+ *
+ * Outputs:
+ * Returns error code
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT VMSetPriority (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_I32 priority);
+
+/*----------------------------------------------------------------------------
+ * VMGetPriority()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Get the virtual synth priority
+ *
+ * Inputs:
+ * pVoiceMgr pointer to synthesizer data
+ * pPriority pointer to variable to hold priority
+ * pSynth pointer to virtual synth
+ *
+ * Outputs:
+ * Returns error code
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT VMGetPriority (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_I32 *pPriority);
+
+/*----------------------------------------------------------------------------
+ * VMSetVolume()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Set the master volume for this sequence
+ *
+ * Inputs:
+ * nSynthVolume - the desired master volume
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ * overrides any previously set master volume from sysex
+ *
+ *----------------------------------------------------------------------------
+*/
+void VMSetVolume (S_SYNTH *pSynth, EAS_U16 masterVolume);
+
+/*----------------------------------------------------------------------------
+ * VMSetPitchBendRange()
+ *----------------------------------------------------------------------------
+ * Set the pitch bend range for the given channel.
+ *----------------------------------------------------------------------------
+*/
+void VMSetPitchBendRange (S_SYNTH *pSynth, EAS_INT channel, EAS_I16 pitchBendRange);
+
+/*----------------------------------------------------------------------------
+ * VMSetEASLib()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Sets the pointer to the sound library
+ *
+ * Inputs:
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT VMSetGlobalEASLib (S_VOICE_MGR *pVoiceMgr, EAS_SNDLIB_HANDLE pEAS);
+EAS_RESULT VMSetEASLib (S_SYNTH *pSynth, EAS_SNDLIB_HANDLE pEAS);
+
+#ifdef DLS_SYNTHESIZER
+/*----------------------------------------------------------------------------
+ * VMSetDLSLib()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Sets the pointer to the sound library
+ *
+ * Inputs:
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT VMSetGlobalDLSLib (EAS_DATA_HANDLE pEASData, EAS_DLSLIB_HANDLE pDLS);
+EAS_RESULT VMSetDLSLib (S_SYNTH *pSynth, EAS_DLSLIB_HANDLE pDLS);
+#endif
+
+/*----------------------------------------------------------------------------
+ * VMSetTranposition()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Sets the global key transposition used by the synthesizer.
+ * Transposes all melodic instruments up or down by the specified
+ * amount. Range is limited to +/-12 semitones.
+ *
+ * Inputs:
+ * psEASData - pointer to overall EAS data structure
+ * transposition - transpose amount (+/-12)
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+void VMSetTranposition (S_SYNTH *pSynth, EAS_I32 transposition);
+
+/*----------------------------------------------------------------------------
+ * VMGetTranposition()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Gets the global key transposition used by the synthesizer.
+ * Transposes all melodic instruments up or down by the specified
+ * amount. Range is limited to +/-12 semitones.
+ *
+ * Inputs:
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+void VMGetTranposition (S_SYNTH *pSynth, EAS_I32 *pTransposition);
+
+/*----------------------------------------------------------------------------
+ * VMGetNoteCount()
+ *----------------------------------------------------------------------------
+* Returns the total note count
+*----------------------------------------------------------------------------
+*/
+EAS_I32 VMGetNoteCount (S_SYNTH *pSynth);
+
+/*----------------------------------------------------------------------------
+ * VMRender()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * This routine renders a frame of audio
+ *
+ * Inputs:
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ * pVoicesRendered - number of voices rendered this frame
+ *
+ * Side Effects:
+ * sets psMidiObject->m_nMaxWorkloadPerFrame
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT VMRender (S_VOICE_MGR *pVoiceMgr, EAS_I32 numSamples, EAS_I32 *pMixBuffer, EAS_I32 *pVoicesRendered);
+
+/*----------------------------------------------------------------------------
+ * VMInitWorkload()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Clears the workload counter
+ *
+ * Inputs:
+ * pVoiceMgr - pointer to instance data
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+void VMInitWorkload (S_VOICE_MGR *pVoiceMgr);
+
+/*----------------------------------------------------------------------------
+ * VMSetWorkload()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Sets the max workload for a single frame.
+ *
+ * Inputs:
+ * pVoiceMgr - pointer to instance data
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+void VMSetWorkload (S_VOICE_MGR *pVoiceMgr, EAS_I32 maxWorkLoad);
+
+/*----------------------------------------------------------------------------
+ * VMCheckWorkload()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Checks to see if work load has been exceeded on this frame.
+ *
+ * Inputs:
+ * pVoiceMgr - pointer to instance data
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_BOOL VMCheckWorkload (S_VOICE_MGR *pVoiceMgr);
+
+/*----------------------------------------------------------------------------
+ * VMActiveVoices()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Returns the number of active voices in the synthesizer.
+ *
+ * Inputs:
+ * pEASData - pointer to instance data
+ *
+ * Outputs:
+ * Returns the number of active voices
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_I32 VMActiveVoices (S_SYNTH *pSynth);
+
+/*----------------------------------------------------------------------------
+ * VMMIDIShutdown()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Clean up any Synth related system issues.
+ *
+ * Inputs:
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ * None
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+void VMMIDIShutdown (S_EAS_DATA *pEASData, S_SYNTH *pSynth);
+
+/*----------------------------------------------------------------------------
+ * VMShutdown()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Clean up any Synth related system issues.
+ *
+ * Inputs:
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ * None
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+void VMShutdown (S_EAS_DATA *pEASData);
+
+#ifdef EXTERNAL_AUDIO
+/*----------------------------------------------------------------------------
+ * EAS_RegExtAudioCallback()
+ *----------------------------------------------------------------------------
+ * Register a callback for external audio processing
+ *----------------------------------------------------------------------------
+*/
+void VMRegExtAudioCallback (S_SYNTH *pSynth, EAS_VOID_PTR pInstData, EAS_EXT_PRG_CHG_FUNC cbProgChgFunc, EAS_EXT_EVENT_FUNC cbEventFunc);
+
+/*----------------------------------------------------------------------------
+ * VMGetMIDIControllers()
+ *----------------------------------------------------------------------------
+ * Returns the MIDI controller values on the specified channel
+ *----------------------------------------------------------------------------
+*/
+void VMGetMIDIControllers (S_SYNTH *pSynth, EAS_U8 channel, S_MIDI_CONTROLLERS *pControl);
+#endif
+
+#ifdef _SPLIT_ARCHITECTURE
+/*----------------------------------------------------------------------------
+ * VMStartFrame()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Starts an audio frame
+ *
+ * Inputs:
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_BOOL VMStartFrame (S_EAS_DATA *pEASData);
+
+/*----------------------------------------------------------------------------
+ * VMEndFrame()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Stops an audio frame
+ *
+ * Inputs:
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_BOOL VMEndFrame (S_EAS_DATA *pEASData);
+#endif
+
+#endif /* #ifdef _EAS_VM_PROTOS_H */
+
diff --git a/arm-fm-22k/lib_src/eas_voicemgt.c b/arm-fm-22k/lib_src/eas_voicemgt.c
index 873f29d..ab0b776 100644
--- a/arm-fm-22k/lib_src/eas_voicemgt.c
+++ b/arm-fm-22k/lib_src/eas_voicemgt.c
@@ -1,12 +1,12 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_voicemgt.c
- *
- * Contents and purpose:
- * Implements the synthesizer functions.
- *
- * Copyright Sonic Network Inc. 2004
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_voicemgt.c
+ *
+ * Contents and purpose:
+ * Implements the synthesizer functions.
+ *
+ * Copyright Sonic Network Inc. 2004
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,3953 +19,3953 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 794 $
- * $Date: 2007-08-01 00:08:48 -0700 (Wed, 01 Aug 2007) $
- *----------------------------------------------------------------------------
-*/
-
-/* includes */
-#include "eas.h"
-#include "eas_data.h"
-#include "eas_config.h"
-#include "eas_report.h"
-#include "eas_midictrl.h"
-#include "eas_host.h"
-#include "eas_synth_protos.h"
-#include "eas_vm_protos.h"
-
-#ifdef DLS_SYNTHESIZER
-#include "eas_mdls.h"
-#endif
-
-// #define _DEBUG_VM
-
-/* some defines for workload */
-#define WORKLOAD_AMOUNT_SMALL_INCREMENT 5
-#define WORKLOAD_AMOUNT_START_NOTE 10
-#define WORKLOAD_AMOUNT_STOP_NOTE 10
-#define WORKLOAD_AMOUNT_KEY_GROUP 10
-#define WORKLOAD_AMOUNT_POLY_LIMIT 10
-
-/* pointer to base sound library */
-extern S_EAS easSoundLib;
-
-#ifdef TEST_HARNESS
-extern S_EAS easTestLib;
-EAS_SNDLIB_HANDLE VMGetLibHandle(EAS_INT libNum)
-{
- switch (libNum)
- {
- case 0:
- return &easSoundLib;
-#ifdef _WT_SYNTH
- case 1:
- return &easTestLib;
-#endif
- default:
- return NULL;
- }
-}
-#endif
-
-/* pointer to synthesizer interface(s) */
-#ifdef _WT_SYNTH
-extern const S_SYNTH_INTERFACE wtSynth;
-#endif
-
-#ifdef _FM_SYNTH
-extern const S_SYNTH_INTERFACE fmSynth;
-#endif
-
-typedef S_SYNTH_INTERFACE *S_SYNTH_INTERFACE_HANDLE;
-
-/* wavetable on MCU */
-#if defined(EAS_WT_SYNTH)
-const S_SYNTH_INTERFACE *const pPrimarySynth = &wtSynth;
-
-/* FM on MCU */
-#elif defined(EAS_FM_SYNTH)
-const S_SYNTH_INTERFACE *const pPrimarySynth = &fmSynth;
-
-/* wavetable drums on MCU, FM melodic on DSP */
-#elif defined(EAS_HYBRID_SYNTH)
-const S_SYNTH_INTERFACE *const pPrimarySynth = &wtSynth;
-const S_SYNTH_INTERFACE *const pSecondarySynth = &fmSynth;
-
-/* wavetable drums on MCU, wavetable melodic on DSP */
-#elif defined(EAS_SPLIT_WT_SYNTH)
-const S_SYNTH_INTERFACE *const pPrimarySynth = &wtSynth;
-extern const S_FRAME_INTERFACE wtFrameInterface;
-const S_FRAME_INTERFACE *const pFrameInterface = &wtFrameInterface;
-
-/* wavetable drums on MCU, FM melodic on DSP */
-#elif defined(EAS_SPLIT_HYBRID_SYNTH)
-const S_SYNTH_INTERFACE *const pPrimarySynth = &wtSynth;
-const S_SYNTH_INTERFACE *const pSecondarySynth = &fmSynth;
-extern const S_FRAME_INTERFACE fmFrameInterface;
-const S_FRAME_INTERFACE *const pFrameInterface = &fmFrameInterface;
-
-/* FM on DSP */
-#elif defined(EAS_SPLIT_FM_SYNTH)
-const S_SYNTH_INTERFACE *const pPrimarySynth = &fmSynth;
-extern const S_FRAME_INTERFACE fmFrameInterface;
-const S_FRAME_INTERFACE *const pFrameInterface = &fmFrameInterface;
-
-#else
-#error "Undefined architecture option"
-#endif
-
-/*----------------------------------------------------------------------------
- * inline functions
- *----------------------------------------------------------------------------
-*/
-EAS_INLINE const S_REGION* GetRegionPtr (S_SYNTH *pSynth, EAS_U16 regionIndex)
-{
-#if defined(DLS_SYNTHESIZER)
- if (regionIndex & FLAG_RGN_IDX_DLS_SYNTH)
- return &pSynth->pDLS->pDLSRegions[regionIndex & REGION_INDEX_MASK].wtRegion.region;
-#endif
-#if defined(_HYBRID_SYNTH)
- if (regionIndex & FLAG_RGN_IDX_FM_SYNTH)
- return &pSynth->pEAS->pFMRegions[regionIndex & REGION_INDEX_MASK].region;
- else
- return &pSynth->pEAS->pWTRegions[regionIndex].region;
-#elif defined(_WT_SYNTH)
- return &pSynth->pEAS->pWTRegions[regionIndex].region;
-#elif defined(_FM_SYNTH)
- return &pSynth->pEAS->pFMRegions[regionIndex].region;
-#endif
-}
-
-/*lint -esym(715, voiceNum) used in some implementation */
-EAS_INLINE const S_SYNTH_INTERFACE* GetSynthPtr (EAS_INT voiceNum)
-{
-#if defined(_HYBRID_SYNTH)
- if (voiceNum < NUM_PRIMARY_VOICES)
- return pPrimarySynth;
- else
- return pSecondarySynth;
-#else
- return pPrimarySynth;
-#endif
-}
-
-EAS_INLINE EAS_INT GetAdjustedVoiceNum (EAS_INT voiceNum)
-{
-#if defined(_HYBRID_SYNTH)
- if (voiceNum >= NUM_PRIMARY_VOICES)
- return voiceNum - NUM_PRIMARY_VOICES;
-#endif
- return voiceNum;
-}
-
-EAS_INLINE EAS_U8 VSynthToChannel (S_SYNTH *pSynth, EAS_U8 channel)
-{
- /*lint -e{734} synthNum is always 0-15 */
- return channel | (pSynth->vSynthNum << 4);
-}
-
-/*----------------------------------------------------------------------------
- * InitVoice()
- *----------------------------------------------------------------------------
- * Initialize a synthesizer voice
- *----------------------------------------------------------------------------
-*/
-void InitVoice (S_SYNTH_VOICE *pVoice)
-{
- pVoice->channel = UNASSIGNED_SYNTH_CHANNEL;
- pVoice->nextChannel = UNASSIGNED_SYNTH_CHANNEL;
- pVoice->note = pVoice->nextNote = DEFAULT_KEY_NUMBER;
- pVoice->velocity = pVoice->nextVelocity = DEFAULT_VELOCITY;
- pVoice->regionIndex = DEFAULT_REGION_INDEX;
- pVoice->age = DEFAULT_AGE;
- pVoice->voiceFlags = DEFAULT_VOICE_FLAGS;
- pVoice->voiceState = DEFAULT_VOICE_STATE;
-}
-
-/*----------------------------------------------------------------------------
- * IncVoicePoolCount()
- *----------------------------------------------------------------------------
- * Updates the voice pool count when a voice changes state
- *----------------------------------------------------------------------------
-*/
-static void IncVoicePoolCount (S_VOICE_MGR *pVoiceMgr, S_SYNTH_VOICE *pVoice)
-{
- S_SYNTH *pSynth;
- EAS_INT pool;
-
- /* ignore muting voices */
- if (pVoice->voiceState == eVoiceStateMuting)
- return;
-
- if (pVoice->voiceState == eVoiceStateStolen)
- {
- pSynth = pVoiceMgr->pSynth[GET_VSYNTH(pVoice->nextChannel)];
- pool = pSynth->channels[GET_CHANNEL(pVoice->nextChannel)].pool;
- }
- else
- {
- pSynth = pVoiceMgr->pSynth[GET_VSYNTH(pVoice->channel)];
- pool = pSynth->channels[GET_CHANNEL(pVoice->channel)].pool;
- }
-
- pSynth->poolCount[pool]++;
-
-#ifdef _DEBUG_VM
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IncVoicePoolCount: Synth=%d pool=%d\n", pSynth->vSynthNum, pool); */ }
-#endif
-}
-
-/*----------------------------------------------------------------------------
- * DecVoicePoolCount()
- *----------------------------------------------------------------------------
- * Updates the voice pool count when a voice changes state
- *----------------------------------------------------------------------------
-*/
-static void DecVoicePoolCount (S_VOICE_MGR *pVoiceMgr, S_SYNTH_VOICE *pVoice)
-{
- S_SYNTH *pSynth;
- EAS_INT pool;
-
- /* ignore muting voices */
- if (pVoice->voiceState == eVoiceStateMuting)
- return;
-
- if (pVoice->voiceState == eVoiceStateStolen)
- {
- pSynth = pVoiceMgr->pSynth[GET_VSYNTH(pVoice->nextChannel)];
- pool = pSynth->channels[GET_CHANNEL(pVoice->nextChannel)].pool;
- }
- else
- {
- pSynth = pVoiceMgr->pSynth[GET_VSYNTH(pVoice->channel)];
- pool = pSynth->channels[GET_CHANNEL(pVoice->channel)].pool;
- }
-
- pSynth->poolCount[pool]--;
-
-#ifdef _DEBUG_VM
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "DecVoicePoolCount: Synth=%d pool=%d\n", pSynth->vSynthNum, pool); */ }
-#endif
-}
-
-/*----------------------------------------------------------------------------
- * VMInitialize()
- *----------------------------------------------------------------------------
- * Purpose:
- *
- * Inputs:
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT VMInitialize (S_EAS_DATA *pEASData)
-{
- S_VOICE_MGR *pVoiceMgr;
- EAS_INT i;
-
- /* check Configuration Module for data allocation */
- if (pEASData->staticMemoryModel)
- pVoiceMgr = EAS_CMEnumData(EAS_CM_SYNTH_DATA);
- else
- pVoiceMgr = EAS_HWMalloc(pEASData->hwInstData, sizeof(S_VOICE_MGR));
- if (!pVoiceMgr)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "VMInitialize: Failed to allocate synthesizer memory\n"); */ }
- return EAS_ERROR_MALLOC_FAILED;
- }
- EAS_HWMemSet(pVoiceMgr, 0, sizeof(S_VOICE_MGR));
-
- /* initialize non-zero variables */
- pVoiceMgr->pGlobalEAS = (S_EAS*) &easSoundLib;
- pVoiceMgr->maxPolyphony = (EAS_U16) MAX_SYNTH_VOICES;
-
-#if defined(_SECONDARY_SYNTH) || defined(EAS_SPLIT_WT_SYNTH)
- pVoiceMgr->maxPolyphonyPrimary = NUM_PRIMARY_VOICES;
- pVoiceMgr->maxPolyphonySecondary = NUM_SECONDARY_VOICES;
-#endif
-
- /* set max workload to zero */
- pVoiceMgr->maxWorkLoad = 0;
-
- /* initialize the voice manager parameters */
- for (i = 0; i < MAX_SYNTH_VOICES; i++)
- InitVoice(&pVoiceMgr->voices[i]);
-
- /* initialize the synth */
- /*lint -e{522} return unused at this time */
- pPrimarySynth->pfInitialize(pVoiceMgr);
-
- /* initialize the off-chip synth */
-#ifdef _HYBRID_SYNTH
- /*lint -e{522} return unused at this time */
- pSecondarySynth->pfInitialize(pVoiceMgr);
-#endif
-
- pEASData->pVoiceMgr = pVoiceMgr;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * VMInitMIDI()
- *----------------------------------------------------------------------------
- * Purpose:
- *
- * Inputs:
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT VMInitMIDI (S_EAS_DATA *pEASData, S_SYNTH **ppSynth)
-{
- EAS_RESULT result;
- S_SYNTH *pSynth;
- EAS_INT virtualSynthNum;
-
- *ppSynth = NULL;
-
- /* static memory model only allows one synth */
- if (pEASData->staticMemoryModel)
- {
- if (pEASData->pVoiceMgr->pSynth[0] != NULL)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "VMInitMIDI: No virtual synthesizer support for static memory model\n"); */ }
- return EAS_ERROR_NO_VIRTUAL_SYNTHESIZER;
- }
-
- /* check Configuration Module for data allocation */
- pSynth = EAS_CMEnumData(EAS_CM_MIDI_DATA);
- virtualSynthNum = 0;
- }
-
- /* dynamic memory model */
- else
- {
- for (virtualSynthNum = 0; virtualSynthNum < MAX_VIRTUAL_SYNTHESIZERS; virtualSynthNum++)
- if (pEASData->pVoiceMgr->pSynth[virtualSynthNum] == NULL)
- break;
- if (virtualSynthNum == MAX_VIRTUAL_SYNTHESIZERS)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "VMInitMIDI: Exceeded number of active virtual synthesizers"); */ }
- return EAS_ERROR_NO_VIRTUAL_SYNTHESIZER;
- }
- pSynth = EAS_HWMalloc(pEASData->hwInstData, sizeof(S_SYNTH));
- }
-
- /* make sure we have a valid memory pointer */
- if (pSynth == NULL)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "VMInitMIDI: Failed to allocate synthesizer memory\n"); */ }
- return EAS_ERROR_MALLOC_FAILED;
- }
- EAS_HWMemSet(pSynth, 0, sizeof(S_SYNTH));
-
- /* set the sound library pointer */
- if ((result = VMSetEASLib(pSynth, pEASData->pVoiceMgr->pGlobalEAS)) != EAS_SUCCESS)
- {
- VMMIDIShutdown(pEASData, pSynth);
- return result;
- }
-
- /* link in DLS bank if downloaded */
-#ifdef DLS_SYNTHESIZER
- if (pEASData->pVoiceMgr->pGlobalDLS)
- {
- pSynth->pDLS = pEASData->pVoiceMgr->pGlobalDLS;
- DLSAddRef(pSynth->pDLS);
- }
-#endif
-
- /* initialize MIDI state variables */
- pSynth->synthFlags = DEFAULT_SYNTH_FLAGS;
- pSynth->masterVolume = DEFAULT_SYNTH_MASTER_VOLUME;
- pSynth->refCount = 1;
- pSynth->priority = DEFAULT_SYNTH_PRIORITY;
- pSynth->poolAlloc[0] = (EAS_U8) pEASData->pVoiceMgr->maxPolyphony;
-
- VMInitializeAllChannels(pEASData->pVoiceMgr, pSynth);
-
- pSynth->vSynthNum = (EAS_U8) virtualSynthNum;
- pEASData->pVoiceMgr->pSynth[virtualSynthNum] = pSynth;
-
- *ppSynth = pSynth;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * VMIncRefCount()
- *----------------------------------------------------------------------------
- * Increment reference count for virtual synth
- *----------------------------------------------------------------------------
-*/
-void VMIncRefCount (S_SYNTH *pSynth)
-{
- pSynth->refCount++;
-}
-
-/*----------------------------------------------------------------------------
- * VMReset()
- *----------------------------------------------------------------------------
- * Purpose:
- * We call this routine to start the process of reseting the synth.
- * This routine sets a flag for the entire synth indicating that we want
- * to reset.
- * We also force all voices to mute quickly.
- * However, we do not actually perform any synthesis in this routine. That
- * is, we do not ramp the voices down from this routine, but instead, we
- * let the "regular" synth processing steps take care of adding the ramp
- * down samples to the output buffer. After we are sure that all voices
- * have completed ramping down, we continue the process of resetting the
- * synth (from another routine).
- *
- * Inputs:
- * psEASData - pointer to overall EAS data structure
- * force - force reset even if voices are active
- *
- * Outputs:
- *
- * Side Effects:
- * - set a flag (in psSynthObject->m_nFlags) indicating synth reset requested.
- * - force all voices to update their envelope states to mute
- *
- *----------------------------------------------------------------------------
-*/
-void VMReset (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_BOOL force)
-{
-
-#ifdef _DEBUG_VM
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMReset: request to reset synth. Force = %d\n", force); */ }
-#endif
-
- /* force voices to off state - may cause audio artifacts */
- if (force)
- {
- pVoiceMgr->activeVoices -= pSynth->numActiveVoices;
- pSynth->numActiveVoices = 0;
- VMInitializeAllVoices(pVoiceMgr, pSynth->vSynthNum);
- }
- else
- VMMuteAllVoices(pVoiceMgr, pSynth);
-
- /* don't reset if voices are still playing */
- if (pSynth->numActiveVoices == 0)
- {
- EAS_INT i;
-
-#ifdef _DEBUG_VM
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMReset: complete the reset process\n"); */ }
-#endif
-
- VMInitializeAllChannels(pVoiceMgr, pSynth);
- for (i = 0; i < NUM_SYNTH_CHANNELS; i++)
- pSynth->poolCount[i] = 0;
-
- /* set polyphony */
- if (pSynth->maxPolyphony < pVoiceMgr->maxPolyphony)
- pSynth->poolAlloc[0] = (EAS_U8) pVoiceMgr->maxPolyphony;
- else
- pSynth->poolAlloc[0] = (EAS_U8) pSynth->maxPolyphony;
-
- /* clear reset flag */
- pSynth->synthFlags &= ~SYNTH_FLAG_RESET_IS_REQUESTED;
- }
-
- /* handle reset after voices are muted */
- else
- pSynth->synthFlags |= SYNTH_FLAG_RESET_IS_REQUESTED;
-}
-
-/*----------------------------------------------------------------------------
- * VMInitializeAllChannels()
- *----------------------------------------------------------------------------
- * Purpose:
- *
- * Inputs:
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- *
- *----------------------------------------------------------------------------
-*/
-void VMInitializeAllChannels (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth)
-{
- S_SYNTH_CHANNEL *pChannel;
- EAS_INT i;
-
- VMResetControllers(pSynth);
-
- /* init each channel */
- pChannel = pSynth->channels;
-
- for (i = 0; i < NUM_SYNTH_CHANNELS; i++, pChannel++)
- {
- pChannel->channelFlags = DEFAULT_CHANNEL_FLAGS;
- pChannel->staticGain = DEFAULT_CHANNEL_STATIC_GAIN;
- pChannel->staticPitch = DEFAULT_CHANNEL_STATIC_PITCH;
- pChannel->pool = 0;
-
- /* the drum channel needs a different init */
- if (i == DEFAULT_DRUM_CHANNEL)
- {
- pChannel->bankNum = DEFAULT_RHYTHM_BANK_NUMBER;
- pChannel->channelFlags |= CHANNEL_FLAG_RHYTHM_CHANNEL;
- }
- else
- pChannel->bankNum = DEFAULT_MELODY_BANK_NUMBER;
-
- VMProgramChange(pVoiceMgr, pSynth, (EAS_U8) i, DEFAULT_SYNTH_PROGRAM_NUMBER);
- }
-
-}
-
-/*----------------------------------------------------------------------------
- * VMResetControllers()
- *----------------------------------------------------------------------------
- * Purpose:
- *
- * Inputs:
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- *
- *----------------------------------------------------------------------------
-*/
-void VMResetControllers (S_SYNTH *pSynth)
-{
- S_SYNTH_CHANNEL *pChannel;
- EAS_INT i;
-
- pChannel = pSynth->channels;
-
- for (i = 0; i < NUM_SYNTH_CHANNELS; i++, pChannel++)
- {
- pChannel->pitchBend = DEFAULT_PITCH_BEND;
- pChannel->modWheel = DEFAULT_MOD_WHEEL;
- pChannel->volume = DEFAULT_CHANNEL_VOLUME;
- pChannel->pan = DEFAULT_PAN;
- pChannel->expression = DEFAULT_EXPRESSION;
-
-#ifdef _REVERB
- pSynth->channels[i].reverbSend = DEFAULT_REVERB_SEND;
-#endif
-
-#ifdef _CHORUS
- pSynth->channels[i].chorusSend = DEFAULT_CHORUS_SEND;
-#endif
-
- pChannel->channelPressure = DEFAULT_CHANNEL_PRESSURE;
- pChannel->registeredParam = DEFAULT_REGISTERED_PARAM;
- pChannel->pitchBendSensitivity = DEFAULT_PITCH_BEND_SENSITIVITY;
- pChannel->finePitch = DEFAULT_FINE_PITCH;
- pChannel->coarsePitch = DEFAULT_COARSE_PITCH;
-
- /* update all voices on this channel */
- pChannel->channelFlags |= CHANNEL_FLAG_UPDATE_CHANNEL_PARAMETERS;
- }
-}
-
-/*----------------------------------------------------------------------------
- * VMInitializeAllVoices()
- *----------------------------------------------------------------------------
- * Purpose:
- *
- * Inputs:
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- *
- *----------------------------------------------------------------------------
-*/
-void VMInitializeAllVoices (S_VOICE_MGR *pVoiceMgr, EAS_INT vSynthNum)
-{
- EAS_INT i;
-
- /* initialize the voice manager parameters */
- for (i = 0; i < MAX_SYNTH_VOICES; i++)
- {
- if (pVoiceMgr->voices[i].voiceState != eVoiceStateStolen)
- {
- if (GET_VSYNTH(pVoiceMgr->voices[i].channel) == vSynthNum)
- InitVoice(&pVoiceMgr->voices[i]);
- }
- else
- {
- if (GET_VSYNTH(pVoiceMgr->voices[i].nextChannel) == vSynthNum)
- InitVoice(&pVoiceMgr->voices[i]);
- }
- }
-}
-
-/*----------------------------------------------------------------------------
- * VMMuteVoice()
- *----------------------------------------------------------------------------
- * Mute the selected voice
- *----------------------------------------------------------------------------
-*/
-void VMMuteVoice (S_VOICE_MGR *pVoiceMgr, EAS_I32 voiceNum)
-{
- S_SYNTH *pSynth;
- S_SYNTH_VOICE *pVoice;
-
- /* take no action if voice is already muted */
- pVoice = &pVoiceMgr->voices[voiceNum];
- if ((pVoice->voiceState == eVoiceStateMuting) || (pVoice->voiceState == eVoiceStateFree))
- return;
-
- /* one less voice in pool */
- DecVoicePoolCount(pVoiceMgr, pVoice);
-
- pSynth = pVoiceMgr->pSynth[GET_VSYNTH(pVoice->channel)];
- GetSynthPtr(voiceNum)->pfMuteVoice(pVoiceMgr, pSynth, pVoice, GetAdjustedVoiceNum(voiceNum));
- pVoice->voiceState = eVoiceStateMuting;
-
-}
-
-/*----------------------------------------------------------------------------
- * VMReleaseVoice()
- *----------------------------------------------------------------------------
- * Release the selected voice
- *----------------------------------------------------------------------------
-*/
-void VMReleaseVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_I32 voiceNum)
-{
- S_SYNTH_VOICE *pVoice = &pVoiceMgr->voices[voiceNum];
-
- /* take no action if voice is already free, muting, or releasing */
- if (( pVoice->voiceState == eVoiceStateMuting) ||
- (pVoice->voiceState == eVoiceStateFree) ||
- (pVoice->voiceState == eVoiceStateRelease))
- return;
-
- /* stolen voices should just be muted */
- if (pVoice->voiceState == eVoiceStateStolen)
- VMMuteVoice(pVoiceMgr, voiceNum);
-
- /* release this voice */
- GetSynthPtr(voiceNum)->pfReleaseVoice(pVoiceMgr, pSynth, &pVoiceMgr->voices[voiceNum], GetAdjustedVoiceNum(voiceNum));
- pVoice->voiceState = eVoiceStateRelease;
-}
-
-/*----------------------------------------------------------------------------
- * VMInitMIPTable()
- *----------------------------------------------------------------------------
- * Initialize the SP-MIDI MIP table in preparation for receiving MIP message
- *----------------------------------------------------------------------------
-*/
-void VMInitMIPTable (S_SYNTH *pSynth)
-{
- EAS_INT i;
-
-#ifdef _DEBUG_VM
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMInitMIPTable\n"); */ }
-#endif
-
- /* clear SP-MIDI flag */
- pSynth->synthFlags &= ~SYNTH_FLAG_SP_MIDI_ON;
- for (i = 0; i < NUM_SYNTH_CHANNELS; i++)
- {
- pSynth->channels[i].pool = 0;
- pSynth->channels[i].mip = 0;
- }
-}
-
-/*----------------------------------------------------------------------------
- * VMSetMIPEntry()
- *----------------------------------------------------------------------------
- * Sets the priority and MIP level for a MIDI channel
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, pVoiceMgr) reserved for future use */
-void VMSetMIPEntry (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel, EAS_U8 priority, EAS_U8 mip)
-{
-
-#ifdef _DEBUG_VM
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMSetMIPEntry: channel=%d, priority=%d, MIP=%d\n", channel, priority, mip); */ }
-#endif
-
- /* save data for use by MIP message processing */
- if (priority < NUM_SYNTH_CHANNELS)
- {
- pSynth->channels[channel].pool = priority;
- pSynth->channels[channel].mip = mip;
- }
-}
-
-/*----------------------------------------------------------------------------
- * VMMIPUpdateChannelMuting()
- *----------------------------------------------------------------------------
- * This routine is called after an SP-MIDI message is received and
- * any time the allocated polyphony changes. It mutes or unmutes
- * channels based on polyphony.
- *----------------------------------------------------------------------------
-*/
-void VMMIPUpdateChannelMuting (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth)
-{
- EAS_INT i;
- EAS_INT maxPolyphony;
- EAS_INT channel;
- EAS_INT vSynthNum;
- EAS_INT pool;
-
-#ifdef _DEBUG_VM
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMUpdateMIPTable\n"); */ }
-#endif
-
- /* determine max polyphony */
- if (pSynth->maxPolyphony)
- maxPolyphony = pSynth->maxPolyphony;
- else
- maxPolyphony = pVoiceMgr->maxPolyphony;
-
- /* process channels */
- for (i = 0; i < NUM_SYNTH_CHANNELS; i++)
- {
-
- /* channel must be in MIP message and must meet allocation target */
- if ((pSynth->channels[i].mip != 0) && (pSynth->channels[i].mip <= maxPolyphony))
- pSynth->channels[i].channelFlags &= ~CHANNEL_FLAG_MUTE;
- else
- pSynth->channels[i].channelFlags |= CHANNEL_FLAG_MUTE;
-
- /* reset voice pool count */
- pSynth->poolCount[i] = 0;
- }
-
- /* mute any voices on muted channels, and count unmuted voices */
- for (i = 0; i < MAX_SYNTH_VOICES; i++)
- {
-
- /* ignore free voices */
- if (pVoiceMgr->voices[i].voiceState == eVoiceStateFree)
- continue;
-
- /* get channel and virtual synth */
- if (pVoiceMgr->voices[i].voiceState != eVoiceStateStolen)
- {
- vSynthNum = GET_VSYNTH(pVoiceMgr->voices[i].channel);
- channel = GET_CHANNEL(pVoiceMgr->voices[i].channel);
- }
- else
- {
- vSynthNum = GET_VSYNTH(pVoiceMgr->voices[i].nextChannel);
- channel = GET_CHANNEL(pVoiceMgr->voices[i].nextChannel);
- }
-
- /* ignore voices on other synths */
- if (vSynthNum != pSynth->vSynthNum)
- continue;
-
- /* count voices */
- pool = pSynth->channels[channel].pool;
-
- /* deal with muted channels */
- if (pSynth->channels[channel].channelFlags & CHANNEL_FLAG_MUTE)
- {
- /* mute stolen voices scheduled to play on this channel */
- if (pVoiceMgr->voices[i].voiceState == eVoiceStateStolen)
- pVoiceMgr->voices[i].voiceState = eVoiceStateMuting;
-
- /* release voices that aren't already muting */
- else if (pVoiceMgr->voices[i].voiceState != eVoiceStateMuting)
- {
- VMReleaseVoice(pVoiceMgr, pSynth, i);
- pSynth->poolCount[pool]++;
- }
- }
-
- /* not muted, count this voice */
- else
- pSynth->poolCount[pool]++;
- }
-}
-
-/*----------------------------------------------------------------------------
- * VMUpdateMIPTable()
- *----------------------------------------------------------------------------
- * This routine is called at the end of the SysEx message to allow
- * the Voice Manager to complete the initialization of the MIP
- * table. It assigns channels to the appropriate voice pool based
- * on the MIP setting and calculates the voices allocated for each
- * pool.
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, pVoiceMgr) reserved for future use */
-void VMUpdateMIPTable (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth)
-{
- S_SYNTH_CHANNEL *pChannel;
- EAS_INT i;
- EAS_INT currentMIP;
- EAS_INT currentPool;
- EAS_INT priority[NUM_SYNTH_CHANNELS];
-
-#ifdef _DEBUG_VM
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMUpdateMIPTable\n"); */ }
-#endif
-
- /* set SP-MIDI flag */
- pSynth->synthFlags |= SYNTH_FLAG_SP_MIDI_ON;
-
- /* sort channels into priority order */
- for (i = 0; i < NUM_SYNTH_CHANNELS; i++)
- priority[i] = -1;
- for (i = 0; i < NUM_SYNTH_CHANNELS; i++)
- {
- if (pSynth->channels[i].pool != DEFAULT_SP_MIDI_PRIORITY)
- priority[pSynth->channels[i].pool] = i;
- }
-
- /* process channels in priority order */
- currentMIP = 0;
- currentPool = -1;
- for (i = 0; i < NUM_SYNTH_CHANNELS; i++)
- {
- /* stop when we run out of channels */
- if (priority[i] == -1)
- break;
-
- pChannel = &pSynth->channels[priority[i]];
-
- /* when 2 or more channels have the same MIP setting, they
- * share a common voice pool
- */
- if (pChannel->mip == currentMIP)
- pChannel->pool = (EAS_U8) currentPool;
-
- /* new voice pool */
- else
- {
- currentPool++;
- pSynth->poolAlloc[currentPool] = (EAS_U8) (pChannel->mip - currentMIP);
- currentMIP = pChannel->mip;
- }
- }
-
- /* set SP-MIDI flag */
- pSynth->synthFlags |= SYNTH_FLAG_SP_MIDI_ON;
-
- /* update channel muting */
- VMMIPUpdateChannelMuting (pVoiceMgr, pSynth);
-}
-
-/*----------------------------------------------------------------------------
- * VMMuteAllVoices()
- *----------------------------------------------------------------------------
- * Purpose:
- * We call this in an emergency reset situation.
- * This forces all voices to mute quickly.
- *
- * Inputs:
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- *
- * Side Effects:
- * - forces all voices to update their envelope states to mute
- *
- *----------------------------------------------------------------------------
-*/
-void VMMuteAllVoices (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth)
-{
- EAS_INT i;
-
-#ifdef _DEBUG_VM
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMMuteAllVoices: about to mute all voices!!\n"); */ }
-#endif
-
- for (i = 0; i < MAX_SYNTH_VOICES; i++)
- {
- /* for stolen voices, check new channel */
- if (pVoiceMgr->voices[i].voiceState == eVoiceStateStolen)
- {
- if (GET_VSYNTH(pVoiceMgr->voices[i].nextChannel) == pSynth->vSynthNum)
- VMMuteVoice(pVoiceMgr, i);
- }
-
- else if (pSynth->vSynthNum == GET_VSYNTH(pVoiceMgr->voices[i].channel))
- VMMuteVoice(pVoiceMgr, i);
- }
-}
-
-/*----------------------------------------------------------------------------
- * VMReleaseAllVoices()
- *----------------------------------------------------------------------------
- * Purpose:
- * We call this after we've encountered the end of the Midi file.
- * This ensures all voices are either in release (because we received their
- * note off already) or forces them to mute quickly.
- * We use this as a safety to prevent bad midi files from playing forever.
- *
- * Inputs:
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- *
- * Side Effects:
- * - forces all voices to update their envelope states to release or mute
- *
- *----------------------------------------------------------------------------
-*/
-void VMReleaseAllVoices (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth)
-{
- EAS_INT i;
-
- /* release sustain pedal on all channels */
- for (i = 0; i < NUM_SYNTH_CHANNELS; i++)
- {
- if (pSynth->channels[ i ].channelFlags & CHANNEL_FLAG_SUSTAIN_PEDAL)
- {
- VMReleaseAllDeferredNoteOffs(pVoiceMgr, pSynth, (EAS_U8) i);
- pSynth->channels[i].channelFlags &= ~CHANNEL_FLAG_SUSTAIN_PEDAL;
- }
- }
-
- /* release all voices */
- for (i = 0; i < MAX_SYNTH_VOICES; i++)
- {
-
- switch (pVoiceMgr->voices[i].voiceState)
- {
- case eVoiceStateStart:
- case eVoiceStatePlay:
- /* only release voices on this synth */
- if (GET_VSYNTH(pVoiceMgr->voices[i].channel) == pSynth->vSynthNum)
- VMReleaseVoice(pVoiceMgr, pSynth, i);
- break;
-
- case eVoiceStateStolen:
- if (GET_VSYNTH(pVoiceMgr->voices[i].nextChannel) == pSynth->vSynthNum)
- VMMuteVoice(pVoiceMgr, i);
- break;
-
- case eVoiceStateFree:
- case eVoiceStateRelease:
- case eVoiceStateMuting:
- break;
-
- case eVoiceStateInvalid:
- default:
-#ifdef _DEBUG_VM
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMReleaseAllVoices: error, %d is an unrecognized state\n",
- pVoiceMgr->voices[i].voiceState); */ }
-#endif
- break;
- }
- }
-}
-
-/*----------------------------------------------------------------------------
- * VMAllNotesOff()
- *----------------------------------------------------------------------------
- * Purpose:
- * Quickly mute all notes on the given channel.
- *
- * Inputs:
- * nChannel - quickly turn off all notes on this channel
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- *
- * Side Effects:
- * - forces all voices on this channel to update their envelope states to mute
- *
- *----------------------------------------------------------------------------
-*/
-void VMAllNotesOff (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel)
-{
- EAS_INT voiceNum;
- S_SYNTH_VOICE *pVoice;
-
-#ifdef _DEBUG_VM
- if (channel >= NUM_SYNTH_CHANNELS)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMAllNotesOff: error, %d invalid channel number\n",
- channel); */ }
- return;
- }
-#endif
-
- /* increment workload */
- pVoiceMgr->workload += WORKLOAD_AMOUNT_SMALL_INCREMENT;
-
- /* check each voice */
- channel = VSynthToChannel(pSynth, channel);
- for (voiceNum = 0; voiceNum < MAX_SYNTH_VOICES; voiceNum++)
- {
- pVoice = &pVoiceMgr->voices[voiceNum];
- if (pVoice->voiceState != eVoiceStateFree)
- {
- if (((pVoice->voiceState != eVoiceStateStolen) && (channel == pVoice->channel)) ||
- ((pVoice->voiceState == eVoiceStateStolen) && (channel == pVoice->nextChannel)))
- {
- /* this voice is assigned to the requested channel */
- GetSynthPtr(voiceNum)->pfMuteVoice(pVoiceMgr, pSynth, pVoice, GetAdjustedVoiceNum(voiceNum));
- pVoice->voiceState = eVoiceStateMuting;
- }
- }
- }
-}
-
-/*----------------------------------------------------------------------------
- * VMDeferredStopNote()
- *----------------------------------------------------------------------------
- * Purpose:
- * Stop the notes that had deferred note-off requests.
- *
- * Inputs:
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- * None.
- *
- * Side Effects:
- * voices that have had deferred note-off requests are now put into release
- * psSynthObject->m_sVoice[i].m_nFlags has the VOICE_FLAG_DEFER_MIDI_NOTE_OFF
- * cleared
- *----------------------------------------------------------------------------
-*/
-void VMDeferredStopNote (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth)
-{
- EAS_INT voiceNum;
- EAS_INT channel;
- EAS_BOOL deferredNoteOff;
-
- deferredNoteOff = EAS_FALSE;
-
- /* check each voice to see if it requires a deferred note off */
- for (voiceNum=0; voiceNum < MAX_SYNTH_VOICES; voiceNum++)
- {
- if (pVoiceMgr->voices[voiceNum].voiceFlags & VOICE_FLAG_DEFER_MIDI_NOTE_OFF)
- {
- /* check if this voice was stolen */
- if (pVoiceMgr->voices[voiceNum].voiceState == eVoiceStateStolen)
- {
- /*
- This voice was stolen, AND it also has a deferred note-off.
- The stolen note must be completely ramped down at this point.
- The note that caused the stealing to occur, however, must
- have received a note-off request before the note that caused
- stealing ever had a chance to even start. We want to give
- the note that caused the stealing a chance to play, so we
- start it on the next update interval, and we defer sending
- the note-off request until the subsequent update interval.
- So do not send the note-off request for this voice because
- this voice was stolen and should have completed ramping down,
- Also, do not clear the global flag nor this voice's flag
- because we must indicate that the subsequent update interval,
- after the note that caused stealing has started, should
- then send the deferred note-off request.
- */
- deferredNoteOff = EAS_TRUE;
-
-#ifdef _DEBUG_VM
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMDeferredStopNote: defer request to stop voice %d (channel=%d note=%d) - voice not started\n",
- voiceNum,
- pVoiceMgr->voices[voiceNum].nextChannel,
- pVoiceMgr->voices[voiceNum].note); */ }
-
- /* sanity check: this stolen voice better be ramped to zero */
- if (0 != pVoiceMgr->voices[voiceNum].gain)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMDeferredStopNote: warning, this voice did not complete its ramp to zero\n"); */ }
- }
-#endif // #ifdef _DEBUG_VM
-
- }
- else
- {
- /* clear the flag using exor */
- pVoiceMgr->voices[voiceNum].voiceFlags ^=
- VOICE_FLAG_DEFER_MIDI_NOTE_OFF;
-
-#ifdef _DEBUG_VM
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMDeferredStopNote: Stop voice %d (channel=%d note=%d)\n",
- voiceNum,
- pVoiceMgr->voices[voiceNum].nextChannel,
- pVoiceMgr->voices[voiceNum].note); */ }
-#endif
-
- channel = pVoiceMgr->voices[voiceNum].channel & 15;
-
- /* check if sustain pedal is on */
- if (pSynth->channels[channel].channelFlags & CHANNEL_FLAG_SUSTAIN_PEDAL)
- {
- GetSynthPtr(voiceNum)->pfSustainPedal(pVoiceMgr, pSynth, &pVoiceMgr->voices[voiceNum], &pSynth->channels[channel], GetAdjustedVoiceNum(voiceNum));
- }
-
- /* release this voice */
- else
- VMReleaseVoice(pVoiceMgr, pSynth, voiceNum);
-
- }
-
- }
-
- }
-
- /* clear the deferred note-off flag, unless there's another one pending */
- if (deferredNoteOff == EAS_FALSE)
- pSynth->synthFlags ^= SYNTH_FLAG_DEFERRED_MIDI_NOTE_OFF_PENDING;
-}
-
-/*----------------------------------------------------------------------------
- * VMReleaseAllDeferredNoteOffs()
- *----------------------------------------------------------------------------
- * Purpose:
- * Call this functin when the sustain flag is presently set but
- * we are now transitioning from damper pedal on to
- * damper pedal off. This means all notes in this channel
- * that received a note off while the damper pedal was on, and
- * had their note-off requests deferred, should now proceed to
- * the release state.
- *
- * Inputs:
- * nChannel - this channel has its sustain pedal transitioning from on to off
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- * Side Effects:
- * any voice with deferred note offs on this channel are updated such that
- * pVoice->m_sEG1.m_eState = eEnvelopeStateRelease
- * pVoice->m_sEG1.m_nIncrement = release increment
- * pVoice->m_nFlags = clear the deferred note off flag
- *----------------------------------------------------------------------------
-*/
-void VMReleaseAllDeferredNoteOffs (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel)
-{
- S_SYNTH_VOICE *pVoice;
- EAS_INT voiceNum;
-
-#ifdef _DEBUG_VM
- if (channel >= NUM_SYNTH_CHANNELS)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMReleaseAllDeferredNoteOffs: error, %d invalid channel number\n",
- channel); */ }
- return;
- }
-#endif /* #ifdef _DEBUG_VM */
-
- /* increment workload */
- pVoiceMgr->workload += WORKLOAD_AMOUNT_SMALL_INCREMENT;
-
- /* find all the voices assigned to this channel */
- channel = VSynthToChannel(pSynth, channel);
- for (voiceNum = 0; voiceNum < MAX_SYNTH_VOICES; voiceNum++)
- {
-
- pVoice = &pVoiceMgr->voices[voiceNum];
- if (channel == pVoice->channel)
- {
-
- /* does this voice have a deferred note off? */
- if (pVoice->voiceFlags & VOICE_FLAG_SUSTAIN_PEDAL_DEFER_NOTE_OFF)
- {
- /* release voice */
- VMReleaseVoice(pVoiceMgr, pSynth, voiceNum);
-
- /* use exor to flip bit, clear the flag */
- pVoice->voiceFlags &= ~VOICE_FLAG_SUSTAIN_PEDAL_DEFER_NOTE_OFF;
-
- }
-
- }
- }
-
- return;
-}
-
-/*----------------------------------------------------------------------------
- * VMCatchNotesForSustainPedal()
- *----------------------------------------------------------------------------
- * Purpose:
- * Call this function when the sustain flag is presently clear and
- * the damper pedal is off and we are transitioning from damper pedal OFF to
- * damper pedal ON. Currently sounding notes should be left
- * unchanged. However, we should try to "catch" notes if possible.
- * If any notes are in release and have levels >= sustain level, catch them,
- * otherwise, let them continue to release.
- *
- * Inputs:
- * nChannel - this channel has its sustain pedal transitioning from on to off
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- *----------------------------------------------------------------------------
-*/
-void VMCatchNotesForSustainPedal (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel)
-{
- EAS_INT voiceNum;
-
-#ifdef _DEBUG_VM
- if (channel >= NUM_SYNTH_CHANNELS)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMCatchNotesForSustainPedal: error, %d invalid channel number\n",
- channel); */ }
- return;
- }
-#endif
-
- pVoiceMgr->workload += WORKLOAD_AMOUNT_SMALL_INCREMENT;
- channel = VSynthToChannel(pSynth, channel);
-
- /* find all the voices assigned to this channel */
- for (voiceNum = 0; voiceNum < MAX_SYNTH_VOICES; voiceNum++)
- {
- if (channel == pVoiceMgr->voices[voiceNum].channel)
- {
- if (eVoiceStateRelease == pVoiceMgr->voices[voiceNum].voiceState)
- GetSynthPtr(voiceNum)->pfSustainPedal(pVoiceMgr, pSynth, &pVoiceMgr->voices[voiceNum], &pSynth->channels[channel], GetAdjustedVoiceNum(voiceNum));
- }
- }
-}
-
-/*----------------------------------------------------------------------------
- * VMUpdateAllNotesAge()
- *----------------------------------------------------------------------------
- * Purpose:
- * Increment the note age for all of the active voices.
- *
- * Inputs:
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- *
- * Side Effects:
- * m_nAge for all voices is incremented
- *----------------------------------------------------------------------------
-*/
-void VMUpdateAllNotesAge (S_VOICE_MGR *pVoiceMgr, EAS_U16 age)
-{
- EAS_INT i;
-
- for (i = 0; i < MAX_SYNTH_VOICES; i++)
- {
- if (age - pVoiceMgr->voices[i].age > 0)
- pVoiceMgr->voices[i].age++;
- }
-}
-
-/*----------------------------------------------------------------------------
- * VMStolenVoice()
- *----------------------------------------------------------------------------
- * Purpose:
- * The selected voice is being stolen. Sets the parameters so that the
- * voice will begin playing the new sound on the next buffer.
- *
- * Inputs:
- * pVoice - pointer to voice to steal
- * nChannel - the channel to start a note on
- * nKeyNumber - the key number to start a note for
- * nNoteVelocity - the key velocity from this note
- *
- * Outputs:
- * None
- *----------------------------------------------------------------------------
-*/
-static void VMStolenVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_I32 voiceNum, EAS_U8 channel, EAS_U8 note, EAS_U8 velocity, EAS_U16 regionIndex)
-{
- S_SYNTH_VOICE *pVoice = &pVoiceMgr->voices[voiceNum];
-
- /* one less voice in old pool */
- DecVoicePoolCount(pVoiceMgr, pVoice);
-
- /* mute the sound that is currently playing */
- GetSynthPtr(voiceNum)->pfMuteVoice(pVoiceMgr, pVoiceMgr->pSynth[GET_VSYNTH(pVoice->channel)], &pVoiceMgr->voices[voiceNum], GetAdjustedVoiceNum(voiceNum));
- pVoice->voiceState = eVoiceStateStolen;
-
- /* set new note data */
- pVoice->nextChannel = VSynthToChannel(pSynth, channel);
- pVoice->nextNote = note;
- pVoice->nextVelocity = velocity;
- pVoice->nextRegionIndex = regionIndex;
-
- /* one more voice in new pool */
- IncVoicePoolCount(pVoiceMgr, pVoice);
-
- /* clear the deferred flags */
- pVoice->voiceFlags &=
- ~(VOICE_FLAG_DEFER_MIDI_NOTE_OFF |
- VOICE_FLAG_DEFER_MUTE |
- VOICE_FLAG_SUSTAIN_PEDAL_DEFER_NOTE_OFF);
-
- /* all notes older than this one get "younger" */
- VMUpdateAllNotesAge(pVoiceMgr, pVoice->age);
-
- /* assign current age to this note and increment for the next note */
- pVoice->age = pVoiceMgr->age++;
-}
-
-/*----------------------------------------------------------------------------
- * VMFreeVoice()
- *----------------------------------------------------------------------------
- * Purpose:
- * The selected voice is done playing and being returned to the
- * pool of free voices
- *
- * Inputs:
- * pVoice - pointer to voice to free
- *
- * Outputs:
- * None
- *----------------------------------------------------------------------------
-*/
-static void VMFreeVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice)
-{
-
- /* do nothing if voice is already free */
- if (pVoice->voiceState == eVoiceStateFree)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "VMFreeVoice: Attempt to free voice that is already free\n"); */ }
- return;
- }
-
- /* if we jump directly to free without passing muting stage,
- * we need to adjust the voice count */
- DecVoicePoolCount(pVoiceMgr, pVoice);
-
-
-#ifdef _DEBUG_VM
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "VMFreeVoice: Synth=%d\n", pSynth->vSynthNum); */ }
-#endif
-
- /* return to free voice pool */
- pVoiceMgr->activeVoices--;
- pSynth->numActiveVoices--;
- InitVoice(pVoice);
-
-#ifdef _DEBUG_VM
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMFreeVoice: free voice %d\n", pVoice - pVoiceMgr->voices); */ }
-#endif
-
- /* all notes older than this one get "younger" */
- VMUpdateAllNotesAge(pVoiceMgr, pVoice->age);
- }
-
-/*----------------------------------------------------------------------------
- * VMRetargetStolenVoice()
- *----------------------------------------------------------------------------
- * Purpose:
- * The selected voice has been stolen and needs to be initalized with
- * the paramters of its new note.
- *
- * Inputs:
- * pVoice - pointer to voice to retarget
- *
- * Outputs:
- * None
- *----------------------------------------------------------------------------
-*/
-static EAS_BOOL VMRetargetStolenVoice (S_VOICE_MGR *pVoiceMgr, EAS_I32 voiceNum)
-{
- EAS_U8 flags;
- S_SYNTH_CHANNEL *pMIDIChannel;
- S_SYNTH_VOICE *pVoice;
- S_SYNTH *pSynth;
- S_SYNTH *pNextSynth;
-
- /* establish some pointers */
- pVoice = &pVoiceMgr->voices[voiceNum];
- pSynth = pVoiceMgr->pSynth[GET_VSYNTH(pVoice->channel)];
- pMIDIChannel = &pSynth->channels[pVoice->channel & 15];
- pNextSynth = pVoiceMgr->pSynth[GET_VSYNTH(pVoice->nextChannel)];
-
-#ifdef _DEBUG_VM
-{ /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMRetargetStolenVoice: retargeting stolen voice %d on channel %d\n",
- voiceNum, pVoice->channel); */ }
-
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "\to channel %d note: %d velocity: %d\n",
- pVoice->nextChannel, pVoice->nextNote, pVoice->nextVelocity); */ }
-#endif
-
- /* make sure new channel hasn't been muted by SP-MIDI since the voice was stolen */
- if ((pSynth->synthFlags & SYNTH_FLAG_SP_MIDI_ON) &&
- (pMIDIChannel->channelFlags & CHANNEL_FLAG_MUTE))
- {
- VMFreeVoice(pVoiceMgr, pSynth, &pVoiceMgr->voices[voiceNum]);
- return EAS_FALSE;
- }
-
- /* if assigned to a new synth, correct the active voice count */
- if (pVoice->channel != pVoice->nextChannel)
- {
-#ifdef _DEBUG_VM
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMRetargetStolenVoice: Note assigned to different virtual synth, adjusting numActiveVoices\n"); */ }
-#endif
- pSynth->numActiveVoices--;
- pNextSynth->numActiveVoices++;
- }
-
- /* assign new channel number, and increase channel voice count */
- pVoice->channel = pVoice->nextChannel;
- pMIDIChannel = &pNextSynth->channels[pVoice->channel & 15];
-
- /* assign other data */
- pVoice->note = pVoice->nextNote;
- pVoice->velocity = pVoice->nextVelocity;
- pVoice->nextChannel = UNASSIGNED_SYNTH_CHANNEL;
- pVoice->regionIndex = pVoice->nextRegionIndex;
-
- /* save the flags, pfStartVoice() will clear them */
- flags = pVoice->voiceFlags;
-
- /* keep track of the note-start related workload */
- pVoiceMgr->workload += WORKLOAD_AMOUNT_START_NOTE;
-
- /* setup the voice parameters */
- pVoice->voiceState = eVoiceStateStart;
-
- /*lint -e{522} return not used at this time */
- GetSynthPtr(voiceNum)->pfStartVoice(pVoiceMgr, pNextSynth, &pVoiceMgr->voices[voiceNum], GetAdjustedVoiceNum(voiceNum), pVoice->regionIndex);
-
- /* did the new note already receive a MIDI note-off request? */
- if (flags & VOICE_FLAG_DEFER_MIDI_NOTE_OFF)
- {
-#ifdef _DEBUG_VM
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMRetargetVoice: stolen note note-off request deferred\n"); */ }
-#endif
- pVoice->voiceFlags |= VOICE_FLAG_DEFER_MIDI_NOTE_OFF;
- pNextSynth->synthFlags |= SYNTH_FLAG_DEFERRED_MIDI_NOTE_OFF_PENDING;
- }
-
- return EAS_TRUE;
-}
-
-/*----------------------------------------------------------------------------
- * VMCheckKeyGroup()
- *----------------------------------------------------------------------------
- * If the note that we've been asked to start is in the same key group as
- * any currently playing notes, then we must shut down the currently playing
- * note in the same key group
- *----------------------------------------------------------------------------
-*/
-void VMCheckKeyGroup (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U16 keyGroup, EAS_U8 channel)
-{
- const S_REGION *pRegion;
- EAS_INT voiceNum;
-
- /* increment frame workload */
- pVoiceMgr->workload += WORKLOAD_AMOUNT_KEY_GROUP;
-
- /* need to check all voices in case this is a layered sound */
- channel = VSynthToChannel(pSynth, channel);
- for (voiceNum = 0; voiceNum < MAX_SYNTH_VOICES; voiceNum++)
- {
- if (pVoiceMgr->voices[voiceNum].voiceState != eVoiceStateStolen)
- {
- /* voice must be on the same channel */
- if (channel == pVoiceMgr->voices[voiceNum].channel)
- {
- /* check key group */
- pRegion = GetRegionPtr(pSynth, pVoiceMgr->voices[voiceNum].regionIndex);
- if (keyGroup == (pRegion->keyGroupAndFlags & 0x0f00))
- {
-#ifdef _DEBUG_VM
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMCheckKeyGroup: voice %d matches key group %d\n", voiceNum, keyGroup >> 8); */ }
-#endif
-
- /* if this voice was just started, set it to mute on the next buffer */
- if (pVoiceMgr->voices[voiceNum].voiceFlags & VOICE_FLAG_NO_SAMPLES_SYNTHESIZED_YET)
- pVoiceMgr->voices[voiceNum].voiceFlags |= VOICE_FLAG_DEFER_MUTE;
-
- /* mute immediately */
- else
- VMMuteVoice(pVoiceMgr, voiceNum);
- }
- }
- }
-
- /* for stolen voice, check new values */
- else
- {
- /* voice must be on the same channel */
- if (channel == pVoiceMgr->voices[voiceNum].nextChannel)
- {
- /* check key group */
- pRegion = GetRegionPtr(pSynth, pVoiceMgr->voices[voiceNum].nextRegionIndex);
- if (keyGroup == (pRegion->keyGroupAndFlags & 0x0f00))
- {
-#ifdef _DEBUG_VM
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMCheckKeyGroup: voice %d matches key group %d\n", voiceNum, keyGroup >> 8); */ }
-#endif
-
- /* if this voice was just started, set it to mute on the next buffer */
- if (pVoiceMgr->voices[voiceNum].voiceFlags & VOICE_FLAG_NO_SAMPLES_SYNTHESIZED_YET)
- pVoiceMgr->voices[voiceNum].voiceFlags |= VOICE_FLAG_DEFER_MUTE;
-
- /* mute immediately */
- else
- VMMuteVoice(pVoiceMgr, voiceNum);
- }
- }
-
- }
- }
-}
-
-/*----------------------------------------------------------------------------
- * VMCheckPolyphonyLimiting()
- *----------------------------------------------------------------------------
- * Purpose:
- * We only play at most 2 of the same note on a MIDI channel.
- * E.g., if we are asked to start note 36, and there are already two voices
- * that are playing note 36, then we must steal the voice playing
- * the oldest note 36 and use that stolen voice to play the new note 36.
- *
- * Inputs:
- * nChannel - synth channel that wants to start a new note
- * nKeyNumber - new note's midi note number
- * nNoteVelocity - new note's velocity
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- * pbVoiceStealingRequired - flag: this routine sets true if we needed to
- * steal a voice
- * *
- * Side Effects:
- * psSynthObject->m_sVoice[free voice num].m_nKeyNumber may be assigned
- * psSynthObject->m_sVoice[free voice num].m_nVelocity may be assigned
- *----------------------------------------------------------------------------
-*/
-EAS_BOOL VMCheckPolyphonyLimiting (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel, EAS_U8 note, EAS_U8 velocity, EAS_U16 regionIndex, EAS_I32 lowVoice, EAS_I32 highVoice)
-{
- EAS_INT voiceNum;
- EAS_INT oldestVoiceNum;
- EAS_INT numVoicesPlayingNote;
- EAS_U16 age;
- EAS_U16 oldestNoteAge;
-
- pVoiceMgr->workload += WORKLOAD_AMOUNT_POLY_LIMIT;
-
- numVoicesPlayingNote = 0;
- oldestVoiceNum = MAX_SYNTH_VOICES;
- oldestNoteAge = 0;
- channel = VSynthToChannel(pSynth, channel);
-
- /* examine each voice on this channel playing this note */
- for (voiceNum = lowVoice; voiceNum <= highVoice; voiceNum++)
- {
- /* check stolen notes separately */
- if (pVoiceMgr->voices[voiceNum].voiceState != eVoiceStateStolen)
- {
-
- /* same channel and note ? */
- if ((channel == pVoiceMgr->voices[voiceNum].channel) && (note == pVoiceMgr->voices[voiceNum].note))
- {
- numVoicesPlayingNote++;
- age = pVoiceMgr->age - pVoiceMgr->voices[voiceNum].age;
-
- /* is this the oldest voice for this note? */
- if (age >= oldestNoteAge)
- {
- oldestNoteAge = age;
- oldestVoiceNum = voiceNum;
- }
- }
- }
-
- /* handle stolen voices */
- else
- {
- /* same channel and note ? */
- if ((channel == pVoiceMgr->voices[voiceNum].nextChannel) && (note == pVoiceMgr->voices[voiceNum].nextNote))
- {
- numVoicesPlayingNote++;
- }
- }
- }
-
- /* check to see if we exceeded poly limit */
- if (numVoicesPlayingNote < DEFAULT_CHANNEL_POLYPHONY_LIMIT)
- return EAS_FALSE;
-
- /* make sure we have a voice to steal */
- if (oldestVoiceNum != MAX_SYNTH_VOICES)
- {
-#ifdef _DEBUG_VM
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMCheckPolyphonyLimiting: voice %d has the oldest note\n", oldestVoiceNum); */ }
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "VMCheckPolyphonyLimiting: polyphony limiting requires shutting down note %d \n", pVoiceMgr->voices[oldestVoiceNum].note); */ }
-#endif
- VMStolenVoice(pVoiceMgr, pSynth, oldestVoiceNum, channel, note, velocity, regionIndex);
- return EAS_TRUE;
- }
-
-#ifdef _DEBUG_VM
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "VMCheckPolyphonyLimiting: No oldest voice to steal\n"); */ }
-#endif
- return EAS_FALSE;
-}
-
-/*----------------------------------------------------------------------------
- * VMStartVoice()
- *----------------------------------------------------------------------------
- * Starts a voice given a region index
- *----------------------------------------------------------------------------
-*/
-void VMStartVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel, EAS_U8 note, EAS_U8 velocity, EAS_U16 regionIndex)
-{
- const S_REGION *pRegion;
- S_SYNTH_CHANNEL *pChannel;
- EAS_INT voiceNum;
- EAS_INT maxSynthPoly;
- EAS_I32 lowVoice, highVoice;
- EAS_U16 keyGroup;
-
- pChannel = &pSynth->channels[channel];
- pRegion = GetRegionPtr(pSynth, regionIndex);
-
- /* select correct synth */
-#if defined(_SECONDARY_SYNTH) || defined(EAS_SPLIT_WT_SYNTH)
- {
-#ifdef EAS_SPLIT_WT_SYNTH
- if ((pRegion->keyGroupAndFlags & REGION_FLAG_OFF_CHIP) == 0)
-#else
- if ((regionIndex & FLAG_RGN_IDX_FM_SYNTH) == 0)
-#endif
- {
- lowVoice = 0;
- highVoice = NUM_PRIMARY_VOICES - 1;
- }
- else
- {
- lowVoice = NUM_PRIMARY_VOICES;
- highVoice = MAX_SYNTH_VOICES - 1;
- }
- }
-#else
- lowVoice = 0;
- highVoice = MAX_SYNTH_VOICES - 1;
-#endif
-
- /* keep track of the note-start related workload */
- pVoiceMgr->workload+= WORKLOAD_AMOUNT_START_NOTE;
-
- /* other voices in pool, check for key group and poly limiting */
- if (pSynth->poolCount[pChannel->pool] != 0)
- {
-
- /* check for key group exclusivity */
- keyGroup = pRegion->keyGroupAndFlags & 0x0f00;
- if (keyGroup!= 0)
- VMCheckKeyGroup(pVoiceMgr, pSynth, keyGroup, channel);
-
- /* check polyphony limit and steal a voice if necessary */
- if ((pRegion->keyGroupAndFlags & REGION_FLAG_NON_SELF_EXCLUSIVE) == 0)
- {
- if (VMCheckPolyphonyLimiting(pVoiceMgr, pSynth, channel, note, velocity, regionIndex, lowVoice, highVoice) == EAS_TRUE)
- return;
- }
- }
-
- /* check max poly allocation */
- if ((pSynth->maxPolyphony == 0) || (pVoiceMgr->maxPolyphony < pSynth->maxPolyphony))
- maxSynthPoly = pVoiceMgr->maxPolyphony;
- else
- maxSynthPoly = pSynth->maxPolyphony;
-
- /* any free voices? */
- if ((pVoiceMgr->activeVoices < pVoiceMgr->maxPolyphony) &&
- (pSynth->numActiveVoices < maxSynthPoly) &&
- (EAS_SUCCESS == VMFindAvailableVoice(pVoiceMgr, &voiceNum, lowVoice, highVoice)))
- {
- S_SYNTH_VOICE *pVoice = &pVoiceMgr->voices[voiceNum];
-
-#ifdef _DEBUG_VM
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "VMStartVoice: Synth=%d\n", pSynth->vSynthNum); */ }
-#endif
-
- /* bump voice counts */
- pVoiceMgr->activeVoices++;
- pSynth->numActiveVoices++;
-
-#ifdef _DEBUG_VM
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMStartVoice: voice %d assigned to channel %d note %d velocity %d\n",
- voiceNum, channel, note, velocity); */ }
-#endif
-
- /* save parameters */
- pVoiceMgr->voices[voiceNum].channel = VSynthToChannel(pSynth, channel);
- pVoiceMgr->voices[voiceNum].note = note;
- pVoiceMgr->voices[voiceNum].velocity = velocity;
-
- /* establish note age for voice stealing */
- pVoiceMgr->voices[voiceNum].age = pVoiceMgr->age++;
-
- /* setup the synthesis parameters */
- pVoiceMgr->voices[voiceNum].voiceState = eVoiceStateStart;
-
- /* increment voice pool count */
- IncVoicePoolCount(pVoiceMgr, pVoice);
-
- /* start voice on correct synth */
- /*lint -e{522} return not used at this time */
- GetSynthPtr(voiceNum)->pfStartVoice(pVoiceMgr, pSynth, &pVoiceMgr->voices[voiceNum], GetAdjustedVoiceNum(voiceNum), regionIndex);
- return;
- }
-
- /* no free voices, we have to steal one using appropriate algorithm */
- if (VMStealVoice(pVoiceMgr, pSynth, &voiceNum, channel, note, lowVoice, highVoice) == EAS_SUCCESS)
- VMStolenVoice(pVoiceMgr, pSynth, voiceNum, channel, note, velocity, regionIndex);
-
-#ifdef _DEBUG_VM
- else
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMStartVoice: Could not steal a voice for channel %d note %d velocity %d\n",
- channel, note, velocity); */ }
- }
-#endif
-
- return;
-}
-
-/*----------------------------------------------------------------------------
- * VMStartNote()
- *----------------------------------------------------------------------------
- * Purpose:
- * Update the synth's state to play the requested note on the requested
- * channel if possible.
- *
- * Inputs:
- * nChannel - the channel to start a note on
- * nKeyNumber - the key number to start a note for
- * nNoteVelocity - the key velocity from this note
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- * Side Effects:
- * psSynthObject->m_nNumActiveVoices may be incremented
- * psSynthObject->m_sVoice[free voice num].m_nSynthChannel may be assigned
- * psSynthObject->m_sVoice[free voice num].m_nKeyNumber is assigned
- * psSynthObject->m_sVoice[free voice num].m_nVelocity is assigned
- *----------------------------------------------------------------------------
-*/
-void VMStartNote (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel, EAS_U8 note, EAS_U8 velocity)
-{
- S_SYNTH_CHANNEL *pChannel;
- EAS_U16 regionIndex;
- EAS_I16 adjustedNote;
-
- /* bump note count */
- pSynth->totalNoteCount++;
-
- pChannel = &pSynth->channels[channel];
-
- /* check channel mute */
- if (pChannel->channelFlags & CHANNEL_FLAG_MUTE)
- return;
-
-#ifdef EXTERNAL_AUDIO
- /* pass event to external audio when requested */
- if ((pChannel->channelFlags & CHANNEL_FLAG_EXTERNAL_AUDIO) && (pSynth->cbEventFunc != NULL))
- {
- S_EXT_AUDIO_EVENT event;
- event.channel = channel;
- event.note = note;
- event.velocity = velocity;
- event.noteOn = EAS_TRUE;
- if (pSynth->cbEventFunc(pSynth->pExtAudioInstData, &event))
- return;
- }
-#endif
-
- /* start search at first region */
- regionIndex = pChannel->regionIndex;
-
- /* handle transposition */
- adjustedNote = note;
- if (pChannel->channelFlags & CHANNEL_FLAG_RHYTHM_CHANNEL)
- adjustedNote += pChannel->coarsePitch;
- else
- adjustedNote += pChannel->coarsePitch + pSynth->globalTranspose;
-
- /* limit adjusted key number so it does not wraparound, over/underflow */
- if (adjustedNote < 0)
- {
- adjustedNote = 0;
- }
- else if (adjustedNote > 127)
- {
- adjustedNote = 127;
- }
-
-#if defined(DLS_SYNTHESIZER)
- if (regionIndex & FLAG_RGN_IDX_DLS_SYNTH)
- {
- /* DLS voice */
- for (;;)
- {
- /*lint -e{740,826} cast OK, we know this is actually a DLS region */
- const S_DLS_REGION *pDLSRegion = (S_DLS_REGION*) GetRegionPtr(pSynth, regionIndex);
-
- /* check key against this region's key and velocity range */
- if (((adjustedNote >= pDLSRegion->wtRegion.region.rangeLow) && (adjustedNote <= pDLSRegion->wtRegion.region.rangeHigh)) &&
- ((velocity >= pDLSRegion->velLow) && (velocity <= pDLSRegion->velHigh)))
- {
- VMStartVoice(pVoiceMgr, pSynth, channel, note, velocity, regionIndex);
- }
-
- /* last region in program? */
- if (pDLSRegion->wtRegion.region.keyGroupAndFlags & REGION_FLAG_LAST_REGION)
- break;
-
- /* advance to next region */
- regionIndex++;
- }
- }
- else
-#endif
-
- /* braces here for #if clause */
- {
- /* EAS voice */
- for (;;)
- {
- const S_REGION *pRegion = GetRegionPtr(pSynth, regionIndex);
-
- /* check key against this region's keyrange */
- if ((adjustedNote >= pRegion->rangeLow) && (adjustedNote <= pRegion->rangeHigh))
- {
- VMStartVoice(pVoiceMgr, pSynth, channel, note, velocity, regionIndex);
- break;
- }
-
- /* last region in program? */
- if (pRegion->keyGroupAndFlags & REGION_FLAG_LAST_REGION)
- break;
-
- /* advance to next region */
- regionIndex++;
- }
- }
-}
-
-/*----------------------------------------------------------------------------
- * VMStopNote()
- *----------------------------------------------------------------------------
- * Purpose:
- * Update the synth's state to end the requested note on the requested
- * channel.
- *
- * Inputs:
- * nChannel - the channel to stop a note on
- * nKeyNumber - the key number for this note off
- * nNoteVelocity - the note-off velocity
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- * Side Effects:
- * psSynthObject->m_sVoice[free voice num].m_nSynthChannel may be assigned
- * psSynthObject->m_sVoice[free voice num].m_nKeyNumber is assigned
- * psSynthObject->m_sVoice[free voice num].m_nVelocity is assigned
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, velocity) reserved for future use */
-void VMStopNote (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel, EAS_U8 note, EAS_U8 velocity)
-{
- S_SYNTH_CHANNEL *pChannel;
- EAS_INT voiceNum;
-
- pChannel = &(pSynth->channels[channel]);
-
-#ifdef EXTERNAL_AUDIO
- if ((pChannel->channelFlags & CHANNEL_FLAG_EXTERNAL_AUDIO) && (pSynth->cbEventFunc != NULL))
- {
- S_EXT_AUDIO_EVENT event;
- event.channel = channel;
- event.note = note;
- event.velocity = velocity;
- event.noteOn = EAS_FALSE;
- if (pSynth->cbEventFunc(pSynth->pExtAudioInstData, &event))
- return;
- }
-#endif
-
- /* keep track of the note-start workload */
- pVoiceMgr->workload += WORKLOAD_AMOUNT_STOP_NOTE;
-
- channel = VSynthToChannel(pSynth, channel);
-
- for (voiceNum=0; voiceNum < MAX_SYNTH_VOICES; voiceNum++)
- {
-
- /* stolen notes are handled separately */
- if (eVoiceStateStolen != pVoiceMgr->voices[voiceNum].voiceState)
- {
-
- /* channel and key number must match */
- if ((channel == pVoiceMgr->voices[voiceNum].channel) && (note == pVoiceMgr->voices[voiceNum].note))
- {
-#ifdef _DEBUG_VM
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMStopNote: voice %d channel %d note %d\n",
- voiceNum, channel, note); */ }
-#endif
-
- /* if sustain pedal is down, set deferred note-off flag */
- if (pChannel->channelFlags & CHANNEL_FLAG_SUSTAIN_PEDAL)
- {
- pVoiceMgr->voices[voiceNum].voiceFlags |= VOICE_FLAG_SUSTAIN_PEDAL_DEFER_NOTE_OFF;
- continue;
- }
-
- /* if this note just started, wait before we stop it */
- if (pVoiceMgr->voices[voiceNum].voiceFlags & VOICE_FLAG_NO_SAMPLES_SYNTHESIZED_YET)
- {
-#ifdef _DEBUG_VM
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "\tDeferred: Not started yet\n"); */ }
-#endif
- pVoiceMgr->voices[voiceNum].voiceFlags |= VOICE_FLAG_DEFER_MIDI_NOTE_OFF;
- pSynth->synthFlags |= SYNTH_FLAG_DEFERRED_MIDI_NOTE_OFF_PENDING;
- }
-
- /* release voice */
- else
- VMReleaseVoice(pVoiceMgr, pSynth, voiceNum);
-
- }
- }
-
- /* process stolen notes, new channel and key number must match */
- else if ((channel == pVoiceMgr->voices[voiceNum].nextChannel) && (note == pVoiceMgr->voices[voiceNum].nextNote))
- {
-
-#ifdef _DEBUG_VM
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMStopNote: voice %d channel %d note %d\n\tDeferred: Stolen voice\n",
- voiceNum, channel, note); */ }
-#endif
- pVoiceMgr->voices[voiceNum].voiceFlags |= VOICE_FLAG_DEFER_MIDI_NOTE_OFF;
- }
- }
-}
-
-/*----------------------------------------------------------------------------
- * VMFindAvailableVoice()
- *----------------------------------------------------------------------------
- * Purpose:
- * Find an available voice and return the voice number if available.
- *
- * Inputs:
- * pnVoiceNumber - really an output, returns the voice number found
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- * success - if there is an available voice
- * failure - otherwise
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT VMFindAvailableVoice (S_VOICE_MGR *pVoiceMgr, EAS_INT *pVoiceNumber, EAS_I32 lowVoice, EAS_I32 highVoice)
-{
- EAS_INT voiceNum;
-
- /* Check each voice to see if it has been assigned to a synth channel */
- for (voiceNum = lowVoice; voiceNum <= highVoice; voiceNum++)
- {
- /* check if this voice has been assigned to a synth channel */
- if ( pVoiceMgr->voices[voiceNum].voiceState == eVoiceStateFree)
- {
- *pVoiceNumber = voiceNum; /* this voice is available */
- return EAS_SUCCESS;
- }
- }
-
- /* if we reach here, we have not found a free voice */
- *pVoiceNumber = UNASSIGNED_SYNTH_VOICE;
-
-#ifdef _DEBUG_VM
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMFindAvailableVoice: error, could not find an available voice\n"); */ }
-#endif
- return EAS_FAILURE;
-}
-
-/*----------------------------------------------------------------------------
- * VMStealVoice()
- *----------------------------------------------------------------------------
- * Purpose:
- * Steal a voice and return the voice number
- *
- * Stealing algorithm: steal the best choice with minimal work, taking into
- * account SP-Midi channel priorities and polyphony allocation.
- *
- * In one pass through all the voices, figure out which voice to steal
- * taking into account a number of different factors:
- * Priority of the voice's MIDI channel
- * Number of voices over the polyphony allocation for voice's MIDI channel
- * Amplitude of the voice
- * Note age
- * Key velocity (for voices that haven't been started yet)
- * If any matching notes are found
- *
- * Inputs:
- * pnVoiceNumber - really an output, see below
- * nChannel - the channel that this voice wants to be started on
- * nKeyNumber - the key number for this new voice
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- * pnVoiceNumber - voice number of the voice that was stolen
- * EAS_RESULT EAS_SUCCESS - always successful
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT VMStealVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_INT *pVoiceNumber, EAS_U8 channel, EAS_U8 note, EAS_I32 lowVoice, EAS_I32 highVoice)
-{
- S_SYNTH_VOICE *pCurrVoice;
- S_SYNTH *pCurrSynth;
- EAS_INT voiceNum;
- EAS_INT bestCandidate;
- EAS_U8 currChannel;
- EAS_U8 currNote;
- EAS_I32 bestPriority;
- EAS_I32 currentPriority;
-
- /* determine which voice to steal */
- bestPriority = 0;
- bestCandidate = MAX_SYNTH_VOICES;
-
- for (voiceNum = lowVoice; voiceNum <= highVoice; voiceNum++)
- {
- pCurrVoice = &pVoiceMgr->voices[voiceNum];
-
- /* ignore free voices */
- if (pCurrVoice->voiceState == eVoiceStateFree)
- continue;
-
- /* for stolen voices, use the new parameters, not the old */
- if (pCurrVoice->voiceState == eVoiceStateStolen)
- {
- pCurrSynth = pVoiceMgr->pSynth[GET_VSYNTH(pCurrVoice->nextChannel)];
- currChannel = pCurrVoice->nextChannel;
- currNote = pCurrVoice->nextNote;
- }
- else
- {
- pCurrSynth = pVoiceMgr->pSynth[GET_VSYNTH(pCurrVoice->channel)];
- currChannel = pCurrVoice->channel;
- currNote = pCurrVoice->note;
- }
-
- /* ignore voices that are higher priority */
- if (pSynth->priority > pCurrSynth->priority)
- continue;
-#ifdef _DEBUG_VM
-// { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMStealVoice: New priority = %d exceeds old priority = %d\n", pSynth->priority, pCurrSynth->priority); */ }
-#endif
-
- /* if voice is stolen or just started, reduce the likelihood it will be stolen */
- if (( pCurrVoice->voiceState == eVoiceStateStolen) || (pCurrVoice->voiceFlags & VOICE_FLAG_NO_SAMPLES_SYNTHESIZED_YET))
- {
- currentPriority = 128 - pCurrVoice->nextVelocity;
- }
- else
- {
- /* compute the priority of this voice, higher means better for stealing */
- /* use not age */
- currentPriority = (EAS_I32) pCurrVoice->age << NOTE_AGE_STEAL_WEIGHT;
-
- /* include note gain -higher gain is lower steal value */
- /*lint -e{704} use shift for performance */
- currentPriority += ((32768 >> (12 - NOTE_GAIN_STEAL_WEIGHT)) + 256) -
- ((EAS_I32) pCurrVoice->gain >> (12 - NOTE_GAIN_STEAL_WEIGHT));
- }
-
- /* in SP-MIDI mode, include over poly allocation and channel priority */
- if (pSynth->synthFlags & SYNTH_FLAG_SP_MIDI_ON)
- {
- S_SYNTH_CHANNEL *pChannel = &pCurrSynth->channels[GET_CHANNEL(currChannel)];
- /*lint -e{701} use shift for performance */
- if (pSynth->poolCount[pChannel->pool] >= pSynth->poolAlloc[pChannel->pool])
- currentPriority += (pSynth->poolCount[pChannel->pool] -pSynth->poolAlloc[pChannel->pool] + 1) << CHANNEL_POLY_STEAL_WEIGHT;
-
- /* include channel priority */
- currentPriority += (EAS_I32)(pChannel->pool << CHANNEL_PRIORITY_STEAL_WEIGHT);
- }
-
- /* if a note is already playing that matches this note, consider stealing it more readily */
- if ((note == currNote) && (channel == currChannel))
- currentPriority += NOTE_MATCH_PENALTY;
-
- /* is this the best choice so far? */
- if (currentPriority >= bestPriority)
- {
- bestPriority = currentPriority;
- bestCandidate = voiceNum;
- }
- }
-
- /* may happen if all voices are allocated to a higher priority virtual synth */
- if (bestCandidate == MAX_SYNTH_VOICES)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMStealVoice: Unable to allocate a voice\n"); */ }
- return EAS_ERROR_NO_VOICE_ALLOCATED;
- }
-
-#ifdef _DEBUG_VM
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMStealVoice: Voice %d stolen\n", bestCandidate); */ }
-
- /* are we stealing a stolen voice? */
- if (pVoiceMgr->voices[bestCandidate].voiceState == eVoiceStateStolen)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "VMStealVoice: Voice %d is already marked as stolen and was scheduled to play ch: %d note: %d vel: %d\n",
- bestCandidate,
- pVoiceMgr->voices[bestCandidate].nextChannel,
- pVoiceMgr->voices[bestCandidate].nextNote,
- pVoiceMgr->voices[bestCandidate].nextVelocity); */ }
- }
-#endif
-
- *pVoiceNumber = (EAS_U16) bestCandidate;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * VMChannelPressure()
- *----------------------------------------------------------------------------
- * Purpose:
- * Change the channel pressure for the given channel
- *
- * Inputs:
- * nChannel - the MIDI channel
- * nVelocity - the channel pressure value
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- * Side Effects:
- * psSynthObject->m_sChannel[nChannel].m_nChannelPressure is updated
- *----------------------------------------------------------------------------
-*/
-void VMChannelPressure (S_SYNTH *pSynth, EAS_U8 channel, EAS_U8 value)
-{
- S_SYNTH_CHANNEL *pChannel;
-
- pChannel = &(pSynth->channels[channel]);
- pChannel->channelPressure = value;
-
- /*
- set a channel flag to request parameter updates
- for all the voices associated with this channel
- */
- pChannel->channelFlags |= CHANNEL_FLAG_UPDATE_CHANNEL_PARAMETERS;
-}
-
-/*----------------------------------------------------------------------------
- * VMPitchBend()
- *----------------------------------------------------------------------------
- * Purpose:
- * Change the pitch wheel value for the given channel.
- * This routine constructs the proper 14-bit argument when the calling routine
- * passes the pitch LSB and MSB.
- *
- * Note: some midi disassemblers display a bipolar pitch bend value.
- * We can display the bipolar value using
- * if m_nPitchBend >= 0x2000
- * bipolar pitch bend = postive (m_nPitchBend - 0x2000)
- * else
- * bipolar pitch bend = negative (0x2000 - m_nPitchBend)
- *
- * Inputs:
- * nChannel - the MIDI channel
- * nPitchLSB - the LSB byte of the pitch bend message
- * nPitchMSB - the MSB byte of the pitch bend message
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- *
- * Side Effects:
- * psSynthObject->m_sChannel[nChannel].m_nPitchBend is changed
- *
- *----------------------------------------------------------------------------
-*/
-void VMPitchBend (S_SYNTH *pSynth, EAS_U8 channel, EAS_U8 nPitchLSB, EAS_U8 nPitchMSB)
-{
- S_SYNTH_CHANNEL *pChannel;
-
- pChannel = &(pSynth->channels[channel]);
- pChannel->pitchBend = (EAS_I16) ((nPitchMSB << 7) | nPitchLSB);
-
- /*
- set a channel flag to request parameter updates
- for all the voices associated with this channel
- */
- pChannel->channelFlags |= CHANNEL_FLAG_UPDATE_CHANNEL_PARAMETERS;
-}
-
-/*----------------------------------------------------------------------------
- * VMControlChange()
- *----------------------------------------------------------------------------
- * Purpose:
- * Change the controller (or mode) for the given channel.
- *
- * Inputs:
- * nChannel - the MIDI channel
- * nControllerNumber - the MIDI controller number
- * nControlValue - the value for this controller message
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- * Side Effects:
- * psSynthObject->m_sChannel[nChannel] controller is changed
- *
- *----------------------------------------------------------------------------
-*/
-void VMControlChange (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel, EAS_U8 controller, EAS_U8 value)
-{
- S_SYNTH_CHANNEL *pChannel;
-
- pChannel = &(pSynth->channels[channel]);
-
- /*
- set a channel flag to request parameter updates
- for all the voices associated with this channel
- */
- pChannel->channelFlags |= CHANNEL_FLAG_UPDATE_CHANNEL_PARAMETERS;
-
- switch ( controller )
- {
- case MIDI_CONTROLLER_BANK_SELECT_MSB:
-#ifdef _DEBUG_VM
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMControlChange: Bank Select MSB: msb 0x%X\n", value); */ }
-#endif
- /* use this MSB with a zero LSB, until we get an LSB message */
- pChannel->bankNum = value << 8;
- break;
-
- case MIDI_CONTROLLER_MOD_WHEEL:
- /* we treat mod wheel as a 7-bit controller and only use the MSB */
- pChannel->modWheel = value;
- break;
-
- case MIDI_CONTROLLER_VOLUME:
- /* we treat volume as a 7-bit controller and only use the MSB */
- pChannel->volume = value;
- break;
-
- case MIDI_CONTROLLER_PAN:
- /* we treat pan as a 7-bit controller and only use the MSB */
- pChannel->pan = value;
- break;
-
- case MIDI_CONTROLLER_EXPRESSION:
- /* we treat expression as a 7-bit controller and only use the MSB */
- pChannel->expression = value;
- break;
-
- case MIDI_CONTROLLER_BANK_SELECT_LSB:
-#ifdef _DEBUG_VM
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMControlChange: Bank Select LSB: lsb 0x%X\n", value); */ }
-#endif
- /*
- construct bank number as 7-bits (stored as 8) of existing MSB
- and 7-bits of new LSB (also stored as 8(
- */
- pChannel->bankNum =
- (pChannel->bankNum & 0xFF00) | value;
-
- break;
-
- case MIDI_CONTROLLER_SUSTAIN_PEDAL:
- /* we treat sustain pedal as a boolean on/off bit flag */
- if (value < 64)
- {
- /*
- we are requested to turn the pedal off, but first check
- if the pedal is already on
- */
- if (0 !=
- (pChannel->channelFlags & CHANNEL_FLAG_SUSTAIN_PEDAL)
- )
- {
- /*
- The sustain flag is presently set and the damper pedal is on.
- We are therefore transitioning from damper pedal ON to
- damper pedal OFF. This means all notes in this channel
- that received a note off while the damper pedal was on, and
- had their note-off requests deferred, should now proceed to
- the release state.
- */
- VMReleaseAllDeferredNoteOffs(pVoiceMgr, pSynth, channel);
- } /* end if sustain pedal is already on */
-
- /* turn the sustain pedal off */
- pChannel->channelFlags &= ~CHANNEL_FLAG_SUSTAIN_PEDAL;
- }
- else
- {
- /*
- we are requested to turn the pedal on, but first check
- if the pedal is already off
- */
- if (0 ==
- (pChannel->channelFlags & CHANNEL_FLAG_SUSTAIN_PEDAL)
- )
- {
- /*
- The sustain flag is presently clear and the damper pedal is off.
- We are therefore transitioning from damper pedal OFF to
- damper pedal ON. Currently sounding notes should be left
- unchanged. However, we should try to "catch" notes if possible.
- If any notes have levels >= sustain level, catch them,
- otherwise, let them continue to release.
- */
- VMCatchNotesForSustainPedal(pVoiceMgr, pSynth, channel);
- }
-
- /* turn the sustain pedal on */
- pChannel->channelFlags |= CHANNEL_FLAG_SUSTAIN_PEDAL;
- }
-
- break;
-#ifdef _REVERB
- case MIDI_CONTROLLER_REVERB_SEND:
- /* we treat send as a 7-bit controller and only use the MSB */
- pSynth->channels[channel].reverbSend = value;
- break;
-#endif
-#ifdef _CHORUS
- case MIDI_CONTROLLER_CHORUS_SEND:
- /* we treat send as a 7-bit controller and only use the MSB */
- pSynth->channels[channel].chorusSend = value;
- break;
-#endif
- case MIDI_CONTROLLER_RESET_CONTROLLERS:
- /* despite the Midi message name, not ALL controllers are reset */
- pChannel->modWheel = DEFAULT_MOD_WHEEL;
- pChannel->expression = DEFAULT_EXPRESSION;
-
- /* turn the sustain pedal off as default/reset */
- pChannel->channelFlags &= ~CHANNEL_FLAG_SUSTAIN_PEDAL;
- pChannel->pitchBend = DEFAULT_PITCH_BEND;
-
- /* reset channel pressure */
- pChannel->channelPressure = DEFAULT_CHANNEL_PRESSURE;
-
- /* reset RPN values */
- pChannel->registeredParam = DEFAULT_REGISTERED_PARAM;
- pChannel->pitchBendSensitivity = DEFAULT_PITCH_BEND_SENSITIVITY;
- pChannel->finePitch = DEFAULT_FINE_PITCH;
- pChannel->coarsePitch = DEFAULT_COARSE_PITCH;
-
- /*
- program change, bank select, channel volume CC7, pan CC10
- are NOT reset
- */
- break;
-
- /*
- For logical reasons, the RPN data entry are grouped together.
- However, keep in mind that these cases are not necessarily in
- ascending order.
- e.g., MIDI_CONTROLLER_DATA_ENTRY_MSB == 6,
- whereas MIDI_CONTROLLER_SUSTAIN_PEDAL == 64.
- So arrange these case statements in whatever manner is more efficient for
- the processor / compiler.
- */
- case MIDI_CONTROLLER_ENTER_DATA_MSB:
- case MIDI_CONTROLLER_ENTER_DATA_LSB:
- case MIDI_CONTROLLER_SELECT_RPN_LSB:
- case MIDI_CONTROLLER_SELECT_RPN_MSB:
- case MIDI_CONTROLLER_SELECT_NRPN_MSB:
- case MIDI_CONTROLLER_SELECT_NRPN_LSB:
- VMUpdateRPNStateMachine(pSynth, channel, controller, value);
- break;
-
- case MIDI_CONTROLLER_ALL_SOUND_OFF:
- case MIDI_CONTROLLER_ALL_NOTES_OFF:
- case MIDI_CONTROLLER_OMNI_OFF:
- case MIDI_CONTROLLER_OMNI_ON:
- case MIDI_CONTROLLER_MONO_ON_POLY_OFF:
- case MIDI_CONTROLLER_POLY_ON_MONO_OFF:
- /* NOTE: we treat all sounds off the same as all notes off */
- VMAllNotesOff(pVoiceMgr, pSynth, channel);
- break;
-
- default:
-#ifdef _DEBUG_VM
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMControlChange: controller %d not yet implemented\n", controller); */ }
-#endif
- break;
-
- }
-
- return;
-}
-
-/*----------------------------------------------------------------------------
- * VMUpdateRPNStateMachine()
- *----------------------------------------------------------------------------
- * Purpose:
- * Call this function when we want to parse RPN related controller messages.
- * We only support RPN0 (pitch bend sensitivity), RPN1 (fine tuning) and
- * RPN2 (coarse tuning). Any other RPNs or NRPNs are ignored for now.
- *.
- * Supports any order, so not a state machine anymore. This function was
- * rewritten to work correctly regardless of order.
- *
- * Inputs:
- * nChannel - the channel this controller message is coming from
- * nControllerNumber - which RPN related controller
- * nControlValue - the value of the RPN related controller
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- * returns EAS_RESULT, which is typically EAS_SUCCESS, since there are
- * few possible errors
- *
- * Side Effects:
- * gsSynthObject.m_sChannel[nChannel].m_nPitchBendSensitivity
- * (or m_nFinePitch or m_nCoarsePitch)
- * will be updated if the proper RPN message is received.
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT VMUpdateRPNStateMachine (S_SYNTH *pSynth, EAS_U8 channel, EAS_U8 controller, EAS_U8 value)
-{
- S_SYNTH_CHANNEL *pChannel;
-
-#ifdef _DEBUG_VM
- if (channel >= NUM_SYNTH_CHANNELS)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMUpdateRPNStateMachines: error, %d invalid channel number\n",
- channel); */ }
- return EAS_FAILURE;
- }
-#endif
-
- pChannel = &(pSynth->channels[channel]);
-
- switch (controller)
- {
- case MIDI_CONTROLLER_SELECT_NRPN_MSB:
- case MIDI_CONTROLLER_SELECT_NRPN_LSB:
- pChannel->registeredParam = DEFAULT_REGISTERED_PARAM;
- break;
- case MIDI_CONTROLLER_SELECT_RPN_MSB:
- pChannel->registeredParam =
- (pChannel->registeredParam & 0x7F) | (value<<7);
- break;
- case MIDI_CONTROLLER_SELECT_RPN_LSB:
- pChannel->registeredParam =
- (pChannel->registeredParam & 0x7F00) | value;
- break;
- case MIDI_CONTROLLER_ENTER_DATA_MSB:
- switch (pChannel->registeredParam)
- {
- case 0:
- pChannel->pitchBendSensitivity = value * 100;
- break;
- case 1:
- /*lint -e{702} <avoid division for performance reasons>*/
- pChannel->finePitch = (EAS_I8)((((value << 7) - 8192) * 100) >> 13);
- break;
- case 2:
- pChannel->coarsePitch = (EAS_I8)(value - 64);
- break;
- default:
- break;
- }
- break;
- case MIDI_CONTROLLER_ENTER_DATA_LSB:
- switch (pChannel->registeredParam)
- {
- case 0:
- //ignore lsb
- break;
- case 1:
- //ignore lsb
- break;
- case 2:
- //ignore lsb
- break;
- default:
- break;
- }
- break;
- default:
- return EAS_FAILURE; //not a RPN related controller
- }
-
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * VMUpdateStaticChannelParameters()
- *----------------------------------------------------------------------------
- * Purpose:
- * Update all of the static channel parameters for channels that have had
- * a controller change values
- * Or if the synth has signalled that all channels must forcibly
- * be updated
- *
- * Inputs:
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- * none
- *
- * Side Effects:
- * - psSynthObject->m_sChannel[].m_nStaticGain and m_nStaticPitch
- * are updated for channels whose controller values have changed
- * or if the synth has signalled that all channels must forcibly
- * be updated
- *----------------------------------------------------------------------------
-*/
-void VMUpdateStaticChannelParameters (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth)
-{
- EAS_INT channel;
-
- if (pSynth->synthFlags & SYNTH_FLAG_UPDATE_ALL_CHANNEL_PARAMETERS)
- {
- /*
- the synth wants us to forcibly update all channel
- parameters. This event occurs when we are about to
- finish resetting the synth
- */
- for (channel = 0; channel < NUM_SYNTH_CHANNELS; channel++)
- {
-#ifdef _HYBRID_SYNTH
- if (pSynth->channels[channel].regionIndex & FLAG_RGN_IDX_FM_SYNTH)
- pSecondarySynth->pfUpdateChannel(pVoiceMgr, pSynth, (EAS_U8) channel);
- else
- pPrimarySynth->pfUpdateChannel(pVoiceMgr, pSynth, (EAS_U8) channel);
-#else
- pPrimarySynth->pfUpdateChannel(pVoiceMgr, pSynth, (EAS_U8) channel);
-#endif
- }
-
- /*
- clear the flag to indicates we have now forcibly
- updated all channel parameters
- */
- pSynth->synthFlags &= ~SYNTH_FLAG_UPDATE_ALL_CHANNEL_PARAMETERS;
- }
- else
- {
-
- /* only update channel params if signalled by a channel flag */
- for (channel = 0; channel < NUM_SYNTH_CHANNELS; channel++)
- {
- if ( 0 != (pSynth->channels[channel].channelFlags & CHANNEL_FLAG_UPDATE_CHANNEL_PARAMETERS))
- {
-#ifdef _HYBRID_SYNTH
- if (pSynth->channels[channel].regionIndex & FLAG_RGN_IDX_FM_SYNTH)
- pSecondarySynth->pfUpdateChannel(pVoiceMgr, pSynth, (EAS_U8) channel);
- else
- pPrimarySynth->pfUpdateChannel(pVoiceMgr, pSynth, (EAS_U8) channel);
-#else
- pPrimarySynth->pfUpdateChannel(pVoiceMgr, pSynth, (EAS_U8) channel);
-#endif
- }
- }
-
- }
-
- return;
-}
-
-/*----------------------------------------------------------------------------
- * VMFindProgram()
- *----------------------------------------------------------------------------
- * Purpose:
- * Look up an individual program in sound library. This function
- * searches the bank list for a program, then the individual program
- * list.
- *
- * Inputs:
- *
- * Outputs:
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT VMFindProgram (const S_EAS *pEAS, EAS_U32 bank, EAS_U8 programNum, EAS_U16 *pRegionIndex)
-{
- EAS_U32 locale;
- const S_PROGRAM *p;
- EAS_U16 i;
- EAS_U16 regionIndex;
-
- /* make sure we have a valid sound library */
- if (pEAS == NULL)
- return EAS_FAILURE;
-
- /* search the banks */
- for (i = 0; i < pEAS->numBanks; i++)
- {
- if (bank == (EAS_U32) pEAS->pBanks[i].locale)
- {
- regionIndex = pEAS->pBanks[i].regionIndex[programNum];
- if (regionIndex != INVALID_REGION_INDEX)
- {
- *pRegionIndex = regionIndex;
- return EAS_SUCCESS;
- }
- break;
- }
- }
-
- /* establish locale */
- locale = ( bank << 8) | programNum;
-
- /* search for program */
- for (i = 0, p = pEAS->pPrograms; i < pEAS->numPrograms; i++, p++)
- {
- if (p->locale == locale)
- {
- *pRegionIndex = p->regionIndex;
- return EAS_SUCCESS;
- }
- }
-
- return EAS_FAILURE;
-}
-
-#ifdef DLS_SYNTHESIZER
-/*----------------------------------------------------------------------------
- * VMFindDLSProgram()
- *----------------------------------------------------------------------------
- * Purpose:
- * Look up an individual program in sound library. This function
- * searches the bank list for a program, then the individual program
- * list.
- *
- * Inputs:
- *
- * Outputs:
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT VMFindDLSProgram (const S_DLS *pDLS, EAS_U32 bank, EAS_U8 programNum, EAS_U16 *pRegionIndex)
-{
- EAS_U32 locale;
- const S_PROGRAM *p;
- EAS_U16 i;
-
- /* make sure we have a valid sound library */
- if (pDLS == NULL)
- return EAS_FAILURE;
-
- /* establish locale */
- locale = (bank << 8) | programNum;
-
- /* search for program */
- for (i = 0, p = pDLS->pDLSPrograms; i < pDLS->numDLSPrograms; i++, p++)
- {
- if (p->locale == locale)
- {
- *pRegionIndex = p->regionIndex;
- return EAS_SUCCESS;
- }
- }
-
- return EAS_FAILURE;
-}
-#endif
-
-/*----------------------------------------------------------------------------
- * VMProgramChange()
- *----------------------------------------------------------------------------
- * Purpose:
- * Change the instrument (program) for the given channel.
- *
- * Depending on the program number, and the bank selected for this channel, the
- * program may be in ROM, RAM (from SMAF or CMX related RAM wavetable), or
- * Alternate wavetable (from mobile DLS or other DLS file)
- *
- * This function figures out what wavetable should be used, and sets it up as the
- * wavetable to use for this channel. Also the channel may switch from a melodic
- * channel to a rhythm channel, or vice versa.
- *
- * Inputs:
- *
- * Outputs:
- * Side Effects:
- * gsSynthObject.m_sChannel[nChannel].m_nProgramNumber is likely changed
- * gsSynthObject.m_sChannel[nChannel].m_psEAS may be changed
- * gsSynthObject.m_sChannel[nChannel].m_bRhythmChannel may be changed
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, pVoiceMgr) reserved for future use */
-void VMProgramChange (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel, EAS_U8 program)
-{
- S_SYNTH_CHANNEL *pChannel;
- EAS_U32 bank;
- EAS_U16 regionIndex;
-
-#ifdef _DEBUG_VM
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "VMProgramChange: vSynthNum=%d, channel=%d, program=%d\n", pSynth->vSynthNum, channel, program); */ }
-#endif
-
- /* setup pointer to MIDI channel data */
- pChannel = &pSynth->channels[channel];
- bank = pChannel->bankNum;
-
- /* allow channels to switch between being melodic or rhythm channels, using GM2 CC values */
- if ((bank & 0xFF00) == DEFAULT_RHYTHM_BANK_NUMBER)
- {
- /* make it a rhythm channel */
- pChannel->channelFlags |= CHANNEL_FLAG_RHYTHM_CHANNEL;
- }
- else if ((bank & 0xFF00) == DEFAULT_MELODY_BANK_NUMBER)
- {
- /* make it a melody channel */
- pChannel->channelFlags &= ~CHANNEL_FLAG_RHYTHM_CHANNEL;
- }
-
- regionIndex = DEFAULT_REGION_INDEX;
-
-#ifdef EXTERNAL_AUDIO
- /* give the external audio interface a chance to handle it */
- if (pSynth->cbProgChgFunc != NULL)
- {
- S_EXT_AUDIO_PRG_CHG prgChg;
- prgChg.channel = channel;
- prgChg.bank = (EAS_U16) bank;
- prgChg.program = program;
- if (pSynth->cbProgChgFunc(pSynth->pExtAudioInstData, &prgChg))
- pChannel->channelFlags |= CHANNEL_FLAG_EXTERNAL_AUDIO;
- }
-
-#endif
-
-
-#ifdef DLS_SYNTHESIZER
- /* first check for DLS program that may overlay the internal instrument */
- if (VMFindDLSProgram(pSynth->pDLS, bank, program, &regionIndex) != EAS_SUCCESS)
-#endif
-
- /* braces to support 'if' clause above */
- {
-
- /* look in the internal banks */
- if (VMFindProgram(pSynth->pEAS, bank, program, &regionIndex) != EAS_SUCCESS)
-
- /* fall back to default bank */
- {
- if (pSynth->channels[channel].channelFlags & CHANNEL_FLAG_RHYTHM_CHANNEL)
- bank = DEFAULT_RHYTHM_BANK_NUMBER;
- else
- bank = DEFAULT_MELODY_BANK_NUMBER;
-
- if (VMFindProgram(pSynth->pEAS, bank, program, &regionIndex) != EAS_SUCCESS)
-
- /* switch to program 0 in the default bank */
- {
- if (VMFindProgram(pSynth->pEAS, bank, 0, &regionIndex) != EAS_SUCCESS)
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "VMProgramChange: No program @ %03d:%03d:%03d\n",
- (bank >> 8) & 0x7f, bank & 0x7f, program); */ }
- }
- }
- }
-
- /* we have our new program change for this channel */
- pChannel->programNum = program;
- pChannel->regionIndex = regionIndex;
-
- /*
- set a channel flag to request parameter updates
- for all the voices associated with this channel
- */
- pChannel->channelFlags |= CHANNEL_FLAG_UPDATE_CHANNEL_PARAMETERS;
-
- return;
-}
-
-/*----------------------------------------------------------------------------
- * VMAddSamples()
- *----------------------------------------------------------------------------
- * Purpose:
- * Synthesize the requested number of samples (block based processing)
- *
- * Inputs:
- * nNumSamplesToAdd - number of samples to write to buffer
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- * number of voices rendered
- *
- * Side Effects:
- * - samples are added to the presently free buffer
- *
- *----------------------------------------------------------------------------
-*/
-EAS_I32 VMAddSamples (S_VOICE_MGR *pVoiceMgr, EAS_I32 *pMixBuffer, EAS_I32 numSamples)
-{
- S_SYNTH *pSynth;
- EAS_INT voicesRendered;
- EAS_INT voiceNum;
- EAS_BOOL done;
-
-#ifdef _REVERB
- EAS_PCM *pReverbSendBuffer;
-#endif // ifdef _REVERB
-
-#ifdef _CHORUS
- EAS_PCM *pChorusSendBuffer;
-#endif // ifdef _CHORUS
-
- voicesRendered = 0;
- for (voiceNum = 0; voiceNum < MAX_SYNTH_VOICES; voiceNum++)
- {
-
- /* retarget stolen voices */
- if ((pVoiceMgr->voices[voiceNum].voiceState == eVoiceStateStolen) && (pVoiceMgr->voices[voiceNum].gain <= 0))
- VMRetargetStolenVoice(pVoiceMgr, voiceNum);
-
- /* get pointer to virtual synth */
- pSynth = pVoiceMgr->pSynth[pVoiceMgr->voices[voiceNum].channel >> 4];
-
- /* synthesize active voices */
- if (pVoiceMgr->voices[voiceNum].voiceState != eVoiceStateFree)
- {
- done = GetSynthPtr(voiceNum)->pfUpdateVoice(pVoiceMgr, pSynth, &pVoiceMgr->voices[voiceNum], GetAdjustedVoiceNum(voiceNum), pMixBuffer, numSamples);
- voicesRendered++;
-
- /* voice is finished */
- if (done == EAS_TRUE)
- {
- /* set gain of stolen voice to zero so it will be restarted */
- if (pVoiceMgr->voices[voiceNum].voiceState == eVoiceStateStolen)
- pVoiceMgr->voices[voiceNum].gain = 0;
-
- /* or return it to the free voice pool */
- else
- VMFreeVoice(pVoiceMgr, pSynth, &pVoiceMgr->voices[voiceNum]);
- }
-
- /* if this voice is scheduled to be muted, set the mute flag */
- if (pVoiceMgr->voices[voiceNum].voiceFlags & VOICE_FLAG_DEFER_MUTE)
- {
- pVoiceMgr->voices[voiceNum].voiceFlags &= ~(VOICE_FLAG_DEFER_MUTE | VOICE_FLAG_DEFER_MIDI_NOTE_OFF);
- VMMuteVoice(pVoiceMgr, voiceNum);
- }
-
- /* if voice just started, advance state to play */
- if (pVoiceMgr->voices[voiceNum].voiceState == eVoiceStateStart)
- pVoiceMgr->voices[voiceNum].voiceState = eVoiceStatePlay;
- }
- }
-
- return voicesRendered;
-}
-
-/*----------------------------------------------------------------------------
- * VMRender()
- *----------------------------------------------------------------------------
- * Purpose:
- * This routine renders a frame of audio
- *
- * Inputs:
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- * pVoicesRendered - number of voices rendered this frame
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT VMRender (S_VOICE_MGR *pVoiceMgr, EAS_I32 numSamples, EAS_I32 *pMixBuffer, EAS_I32 *pVoicesRendered)
-{
- S_SYNTH *pSynth;
- EAS_INT i;
- EAS_INT channel;
-
-#ifdef _CHECKED_BUILD
- SanityCheck(pVoiceMgr);
-#endif
-
- /* update MIDI channel parameters */
- *pVoicesRendered = 0;
- for (i = 0; i < MAX_VIRTUAL_SYNTHESIZERS; i++)
- {
- if (pVoiceMgr->pSynth[i] != NULL)
- VMUpdateStaticChannelParameters(pVoiceMgr, pVoiceMgr->pSynth[i]);
- }
-
- /* synthesize a buffer of audio */
- *pVoicesRendered = VMAddSamples(pVoiceMgr, pMixBuffer, numSamples);
-
- /*
- * check for deferred note-off messages
- * If flag is set, that means one or more voices are expecting deferred
- * midi note-off messages because the midi note-on and corresponding midi
- * note-off requests occurred during the same update interval. The goal
- * is the defer the note-off request so that the note can at least start.
- */
- for (i = 0; i < MAX_VIRTUAL_SYNTHESIZERS; i++)
- {
- pSynth = pVoiceMgr->pSynth[i];
-
- if (pSynth== NULL)
- continue;
-
- if (pSynth->synthFlags & SYNTH_FLAG_DEFERRED_MIDI_NOTE_OFF_PENDING)
- VMDeferredStopNote(pVoiceMgr, pSynth);
-
- /* check if we need to reset the synth */
- if ((pSynth->synthFlags & SYNTH_FLAG_RESET_IS_REQUESTED) &&
- (pSynth->numActiveVoices == 0))
- {
- /*
- complete the process of resetting the synth now that
- all voices have muted
- */
-#ifdef _DEBUG_VM
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMAddSamples: complete the reset process\n"); */ }
-#endif
-
- VMInitializeAllChannels(pVoiceMgr, pSynth);
- VMInitializeAllVoices(pVoiceMgr, pSynth->vSynthNum);
-
- /* clear the reset flag */
- pSynth->synthFlags &= ~SYNTH_FLAG_RESET_IS_REQUESTED;
- }
-
- /* clear channel update flags */
- for (channel = 0; channel < NUM_SYNTH_CHANNELS; channel++)
- pSynth->channels[channel].channelFlags &= ~CHANNEL_FLAG_UPDATE_CHANNEL_PARAMETERS;
-
- }
-
-#ifdef _CHECKED_BUILD
- SanityCheck(pVoiceMgr);
-#endif
-
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * VMInitWorkload()
- *----------------------------------------------------------------------------
- * Purpose:
- * Clears the workload counter
- *
- * Inputs:
- * pVoiceMgr - pointer to instance data
- *
- * Outputs:
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-void VMInitWorkload (S_VOICE_MGR *pVoiceMgr)
-{
- pVoiceMgr->workload = 0;
-}
-
-/*----------------------------------------------------------------------------
- * VMSetWorkload()
- *----------------------------------------------------------------------------
- * Purpose:
- * Sets the max workload for a single frame.
- *
- * Inputs:
- * pVoiceMgr - pointer to instance data
- *
- * Outputs:
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-void VMSetWorkload (S_VOICE_MGR *pVoiceMgr, EAS_I32 maxWorkLoad)
-{
- pVoiceMgr->maxWorkLoad = maxWorkLoad;
-}
-
-/*----------------------------------------------------------------------------
- * VMCheckWorkload()
- *----------------------------------------------------------------------------
- * Purpose:
- * Checks to see if work load has been exceeded on this frame.
- *
- * Inputs:
- * pVoiceMgr - pointer to instance data
- *
- * Outputs:
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_BOOL VMCheckWorkload (S_VOICE_MGR *pVoiceMgr)
-{
- if (pVoiceMgr->maxWorkLoad > 0)
- return (EAS_BOOL) (pVoiceMgr->workload >= pVoiceMgr->maxWorkLoad);
- return EAS_FALSE;
-}
-
-/*----------------------------------------------------------------------------
- * VMActiveVoices()
- *----------------------------------------------------------------------------
- * Purpose:
- * Returns the number of active voices in the synthesizer.
- *
- * Inputs:
- * pEASData - pointer to instance data
- *
- * Outputs:
- * Returns the number of active voices
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_I32 VMActiveVoices (S_SYNTH *pSynth)
-{
- return pSynth->numActiveVoices;
-}
-
-/*----------------------------------------------------------------------------
- * VMSetSynthPolyphony()
- *----------------------------------------------------------------------------
- * Purpose:
- * Set the synth to a new polyphony value. Value must be >= 1 and
- * <= MAX_SYNTH_VOICES. This function will pin the polyphony at those limits
- *
- * Inputs:
- * pVoiceMgr pointer to synthesizer data
- * polyphonyCount desired polyphony count
- * synth synthesizer number (0 = onboard, 1 = DSP)
- *
- * Outputs:
- * Returns error code
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT VMSetSynthPolyphony (S_VOICE_MGR *pVoiceMgr, EAS_I32 synth, EAS_I32 polyphonyCount)
-{
- EAS_INT i;
- EAS_INT activeVoices;
-
- /* lower limit */
- if (polyphonyCount < 1)
- polyphonyCount = 1;
-
- /* split architecture */
-#if defined(_SECONDARY_SYNTH) || defined(EAS_SPLIT_WT_SYNTH)
- if (synth == EAS_MCU_SYNTH)
- {
- if (polyphonyCount > NUM_PRIMARY_VOICES)
- polyphonyCount = NUM_PRIMARY_VOICES;
- if (pVoiceMgr->maxPolyphonyPrimary == polyphonyCount)
- return EAS_SUCCESS;
- pVoiceMgr->maxPolyphonyPrimary = (EAS_U16) polyphonyCount;
- }
- else if (synth == EAS_DSP_SYNTH)
- {
- if (polyphonyCount > NUM_SECONDARY_VOICES)
- polyphonyCount = NUM_SECONDARY_VOICES;
- if (pVoiceMgr->maxPolyphonySecondary == polyphonyCount)
- return EAS_SUCCESS;
- pVoiceMgr->maxPolyphonySecondary = (EAS_U16) polyphonyCount;
- }
- else
- return EAS_ERROR_PARAMETER_RANGE;
-
- /* setting for SP-MIDI */
- pVoiceMgr->maxPolyphony = pVoiceMgr->maxPolyphonyPrimary + pVoiceMgr->maxPolyphonySecondary;
-
- /* standard architecture */
-#else
- if (synth != EAS_MCU_SYNTH)
- return EAS_ERROR_PARAMETER_RANGE;
-
- /* pin desired value to possible limits */
- if (polyphonyCount > MAX_SYNTH_VOICES)
- polyphonyCount = MAX_SYNTH_VOICES;
-
- /* set polyphony, if value is different than current value */
- if (pVoiceMgr->maxPolyphony == polyphonyCount)
- return EAS_SUCCESS;
-
- pVoiceMgr->maxPolyphony = (EAS_U16) polyphonyCount;
-#endif
-
- /* if SPMIDI enabled, update channel masking based on new polyphony */
- for (i = 0; i < MAX_VIRTUAL_SYNTHESIZERS; i++)
- {
- if (pVoiceMgr->pSynth[i])
- {
- if (pVoiceMgr->pSynth[i]->synthFlags & SYNTH_FLAG_SP_MIDI_ON)
- VMMIPUpdateChannelMuting(pVoiceMgr, pVoiceMgr->pSynth[i]);
- else
- pVoiceMgr->pSynth[i]->poolAlloc[0] = (EAS_U8) polyphonyCount;
- }
- }
-
- /* are we under polyphony limit? */
- if (pVoiceMgr->activeVoices <= polyphonyCount)
- return EAS_SUCCESS;
-
- /* count the number of active voices */
- activeVoices = 0;
- for (i = 0; i < MAX_SYNTH_VOICES; i++)
- {
-
- /* is voice active? */
- if ((pVoiceMgr->voices[i].voiceState != eVoiceStateFree) && (pVoiceMgr->voices[i].voiceState != eVoiceStateMuting))
- activeVoices++;
- }
-
- /* we may have to mute voices to reach new target */
- while (activeVoices > polyphonyCount)
- {
- S_SYNTH *pSynth;
- S_SYNTH_VOICE *pVoice;
- EAS_I32 currentPriority, bestPriority;
- EAS_INT bestCandidate;
-
- /* find the lowest priority voice */
- bestPriority = bestCandidate = -1;
- for (i = 0; i < MAX_SYNTH_VOICES; i++)
- {
-
- pVoice = &pVoiceMgr->voices[i];
-
- /* ignore free and muting voices */
- if ((pVoice->voiceState == eVoiceStateFree) || (pVoice->voiceState == eVoiceStateMuting))
- continue;
-
- pSynth = pVoiceMgr->pSynth[GET_VSYNTH(pVoice->channel)];
-
- /* if voice is stolen or just started, reduce the likelihood it will be stolen */
- if (( pVoice->voiceState == eVoiceStateStolen) || (pVoice->voiceFlags & VOICE_FLAG_NO_SAMPLES_SYNTHESIZED_YET))
- {
- /* include velocity */
- currentPriority = 128 - pVoice->nextVelocity;
-
- /* include channel priority */
- currentPriority += pSynth->channels[GET_CHANNEL(pVoice->nextChannel)].pool << CHANNEL_PRIORITY_STEAL_WEIGHT;
- }
- else
- {
- /* include age */
- currentPriority = (EAS_I32) pVoice->age << NOTE_AGE_STEAL_WEIGHT;
-
- /* include note gain -higher gain is lower steal value */
- /*lint -e{704} use shift for performance */
- currentPriority += ((32768 >> (12 - NOTE_GAIN_STEAL_WEIGHT)) + 256) -
- ((EAS_I32) pVoice->gain >> (12 - NOTE_GAIN_STEAL_WEIGHT));
-
- /* include channel priority */
- currentPriority += pSynth->channels[GET_CHANNEL(pVoice->channel)].pool << CHANNEL_PRIORITY_STEAL_WEIGHT;
- }
-
- /* include synth priority */
- currentPriority += pSynth->priority << SYNTH_PRIORITY_WEIGHT;
-
- /* is this the best choice so far? */
- if (currentPriority > bestPriority)
- {
- bestPriority = currentPriority;
- bestCandidate = i;
- }
- }
-
- /* shutdown best candidate */
- if (bestCandidate < 0)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "VMSetPolyphony: Unable to reduce polyphony\n"); */ }
- break;
- }
-
- /* shut down this voice */
- /*lint -e{771} pSynth is initialized if bestCandidate >= 0 */
- VMMuteVoice(pVoiceMgr, bestCandidate);
- activeVoices--;
- }
-
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * VMGetSynthPolyphony()
- *----------------------------------------------------------------------------
- * Purpose:
- * Returns the current polyphony setting
- *
- * Inputs:
- * pVoiceMgr pointer to synthesizer data
- * synth synthesizer number (0 = onboard, 1 = DSP)
- *
- * Outputs:
- * Returns actual polyphony value set, as pinned by limits
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT VMGetSynthPolyphony (S_VOICE_MGR *pVoiceMgr, EAS_I32 synth, EAS_I32 *pPolyphonyCount)
-{
-
-#if defined(_SECONDARY_SYNTH) || defined(EAS_SPLIT_WT_SYNTH)
- if (synth == EAS_MCU_SYNTH)
- *pPolyphonyCount = pVoiceMgr->maxPolyphonyPrimary;
- else if (synth == EAS_DSP_SYNTH)
- *pPolyphonyCount = pVoiceMgr->maxPolyphonySecondary;
- else
- return EAS_ERROR_PARAMETER_RANGE;
-#else
- if (synth != EAS_MCU_SYNTH)
- return EAS_ERROR_PARAMETER_RANGE;
- *pPolyphonyCount = pVoiceMgr->maxPolyphony;
-#endif
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * VMSetPolyphony()
- *----------------------------------------------------------------------------
- * Purpose:
- * Set the virtual synth polyphony. 0 = no limit (i.e. can use
- * all available voices).
- *
- * Inputs:
- * pVoiceMgr pointer to synthesizer data
- * polyphonyCount desired polyphony count
- * pSynth pointer to virtual synth
- *
- * Outputs:
- * Returns error code
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT VMSetPolyphony (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_I32 polyphonyCount)
-{
- EAS_INT i;
- EAS_INT activeVoices;
-
- /* check limits */
- if (polyphonyCount < 0)
- return EAS_ERROR_PARAMETER_RANGE;
-
- /* zero is max polyphony */
- if ((polyphonyCount == 0) || (polyphonyCount > MAX_SYNTH_VOICES))
- {
- pSynth->maxPolyphony = 0;
- return EAS_SUCCESS;
- }
-
- /* set new polyphony */
- pSynth->maxPolyphony = (EAS_U16) polyphonyCount;
-
- /* max polyphony is minimum of virtual synth and actual synth */
- if (polyphonyCount > pVoiceMgr->maxPolyphony)
- polyphonyCount = pVoiceMgr->maxPolyphony;
-
- /* if SP-MIDI mode, update the channel muting */
- if (pSynth->synthFlags & SYNTH_FLAG_SP_MIDI_ON)
- VMMIPUpdateChannelMuting(pVoiceMgr, pSynth);
- else
- pSynth->poolAlloc[0] = (EAS_U8) polyphonyCount;
-
- /* are we under polyphony limit? */
- if (pSynth->numActiveVoices <= polyphonyCount)
- return EAS_SUCCESS;
-
- /* count the number of active voices */
- activeVoices = 0;
- for (i = 0; i < MAX_SYNTH_VOICES; i++)
- {
- /* this synth? */
- if (GET_VSYNTH(pVoiceMgr->voices[i].nextChannel) != pSynth->vSynthNum)
- continue;
-
- /* is voice active? */
- if ((pVoiceMgr->voices[i].voiceState != eVoiceStateFree) && (pVoiceMgr->voices[i].voiceState != eVoiceStateMuting))
- activeVoices++;
- }
-
- /* we may have to mute voices to reach new target */
- while (activeVoices > polyphonyCount)
- {
- S_SYNTH_VOICE *pVoice;
- EAS_I32 currentPriority, bestPriority;
- EAS_INT bestCandidate;
-
- /* find the lowest priority voice */
- bestPriority = bestCandidate = -1;
- for (i = 0; i < MAX_SYNTH_VOICES; i++)
- {
- pVoice = &pVoiceMgr->voices[i];
-
- /* this synth? */
- if (GET_VSYNTH(pVoice->nextChannel) != pSynth->vSynthNum)
- continue;
-
- /* if voice is stolen or just started, reduce the likelihood it will be stolen */
- if (( pVoice->voiceState == eVoiceStateStolen) || (pVoice->voiceFlags & VOICE_FLAG_NO_SAMPLES_SYNTHESIZED_YET))
- {
- /* include velocity */
- currentPriority = 128 - pVoice->nextVelocity;
-
- /* include channel priority */
- currentPriority += pSynth->channels[GET_CHANNEL(pVoice->nextChannel)].pool << CHANNEL_PRIORITY_STEAL_WEIGHT;
- }
- else
- {
- /* include age */
- currentPriority = (EAS_I32) pVoice->age << NOTE_AGE_STEAL_WEIGHT;
-
- /* include note gain -higher gain is lower steal value */
- /*lint -e{704} use shift for performance */
- currentPriority += ((32768 >> (12 - NOTE_GAIN_STEAL_WEIGHT)) + 256) -
- ((EAS_I32) pVoice->gain >> (12 - NOTE_GAIN_STEAL_WEIGHT));
-
- /* include channel priority */
- currentPriority += pSynth->channels[GET_CHANNEL(pVoice->nextChannel)].pool << CHANNEL_PRIORITY_STEAL_WEIGHT;
- }
-
- /* is this the best choice so far? */
- if (currentPriority > bestPriority)
- {
- bestPriority = currentPriority;
- bestCandidate = i;
- }
- }
-
- /* shutdown best candidate */
- if (bestCandidate < 0)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "VMSetPolyphony: Unable to reduce polyphony\n"); */ }
- break;
- }
-
- /* shut down this voice */
- VMMuteVoice(pVoiceMgr, bestCandidate);
- activeVoices--;
- }
-
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * VMGetPolyphony()
- *----------------------------------------------------------------------------
- * Purpose:
- * Get the virtual synth polyphony
- *
- * Inputs:
- * pVoiceMgr pointer to synthesizer data
- * pPolyphonyCount pointer to variable to hold polyphony count
- * pSynth pointer to virtual synth
- *
- * Outputs:
- * Returns error code
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, pVoiceMgr) reserved for future use */
-EAS_RESULT VMGetPolyphony (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_I32 *pPolyphonyCount)
-{
- *pPolyphonyCount = (EAS_U16) pSynth->maxPolyphony;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * VMSetPriority()
- *----------------------------------------------------------------------------
- * Purpose:
- * Set the virtual synth priority
- *
- * Inputs:
- * pVoiceMgr pointer to synthesizer data
- * priority new priority
- * pSynth pointer to virtual synth
- *
- * Outputs:
- * Returns error code
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, pVoiceMgr) reserved for future use */
-EAS_RESULT VMSetPriority (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_I32 priority)
-{
- pSynth->priority = (EAS_U8) priority ;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * VMGetPriority()
- *----------------------------------------------------------------------------
- * Purpose:
- * Get the virtual synth priority
- *
- * Inputs:
- * pVoiceMgr pointer to synthesizer data
- * pPriority pointer to variable to hold priority
- * pSynth pointer to virtual synth
- *
- * Outputs:
- * Returns error code
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, pVoiceMgr) reserved for future use */
-EAS_RESULT VMGetPriority (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_I32 *pPriority)
-{
- *pPriority = pSynth->priority;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * VMSetVolume()
- *----------------------------------------------------------------------------
- * Purpose:
- * Set the master volume for this synthesizer for this sequence.
- *
- * Inputs:
- * nSynthVolume - the desired master volume
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- *
- *
- * Side Effects:
- * overrides any previously set master volume from sysex
- *
- *----------------------------------------------------------------------------
-*/
-void VMSetVolume (S_SYNTH *pSynth, EAS_U16 masterVolume)
-{
- pSynth->masterVolume = masterVolume;
- pSynth->synthFlags |= SYNTH_FLAG_UPDATE_ALL_CHANNEL_PARAMETERS;
-}
-
-/*----------------------------------------------------------------------------
- * VMSetPitchBendRange()
- *----------------------------------------------------------------------------
- * Set the pitch bend range for the given channel.
- *----------------------------------------------------------------------------
-*/
-void VMSetPitchBendRange (S_SYNTH *pSynth, EAS_INT channel, EAS_I16 pitchBendRange)
-{
- pSynth->channels[channel].pitchBendSensitivity = pitchBendRange;
-}
-
-/*----------------------------------------------------------------------------
- * VMValidateEASLib()
- *----------------------------------------------------------------------------
- * Validates an EAS library
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT VMValidateEASLib (EAS_SNDLIB_HANDLE pEAS)
-{
- /* validate the sound library */
- if (pEAS)
- {
- if (pEAS->identifier != _EAS_LIBRARY_VERSION)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "VMValidateEASLib: Sound library mismatch in sound library: Read 0x%08x, expected 0x%08x\n",
- pEAS->identifier, _EAS_LIBRARY_VERSION); */ }
- return EAS_ERROR_SOUND_LIBRARY;
- }
-
- /* check sample rate */
- if ((pEAS->libAttr & LIBFORMAT_SAMPLE_RATE_MASK) != _OUTPUT_SAMPLE_RATE)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "VMValidateEASLib: Sample rate mismatch in sound library: Read %lu, expected %lu\n",
- pEAS->libAttr & LIBFORMAT_SAMPLE_RATE_MASK, _OUTPUT_SAMPLE_RATE); */ }
- return EAS_ERROR_SOUND_LIBRARY;
- }
-
-#ifdef _WT_SYNTH
- /* check sample bit depth */
-#ifdef _8_BIT_SAMPLES
- if (pEAS->libAttr & LIB_FORMAT_16_BIT_SAMPLES)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "VMValidateEASLib: Expected 8-bit samples and found 16-bit\n",
- pEAS->libAttr & LIBFORMAT_SAMPLE_RATE_MASK, _OUTPUT_SAMPLE_RATE); */ }
- return EAS_ERROR_SOUND_LIBRARY;
- }
-#endif
-#ifdef _16_BIT_SAMPLES
- if ((pEAS->libAttr & LIB_FORMAT_16_BIT_SAMPLES) == 0)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "VMValidateEASLib: Expected 16-bit samples and found 8-bit\n",
- pEAS->libAttr & LIBFORMAT_SAMPLE_RATE_MASK, _OUTPUT_SAMPLE_RATE); */ }
- return EAS_ERROR_SOUND_LIBRARY;
- }
-#endif
-#endif
- }
-
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * VMSetGlobalEASLib()
- *----------------------------------------------------------------------------
- * Purpose:
- * Sets the EAS library to be used by the synthesizer
- *
- * Inputs:
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT VMSetGlobalEASLib (S_VOICE_MGR *pVoiceMgr, EAS_SNDLIB_HANDLE pEAS)
-{
- EAS_RESULT result;
-
- result = VMValidateEASLib(pEAS);
- if (result != EAS_SUCCESS)
- return result;
-
- pVoiceMgr->pGlobalEAS = pEAS;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * VMSetEASLib()
- *----------------------------------------------------------------------------
- * Purpose:
- * Sets the EAS library to be used by the synthesizer
- *
- * Inputs:
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT VMSetEASLib (S_SYNTH *pSynth, EAS_SNDLIB_HANDLE pEAS)
-{
- EAS_RESULT result;
-
- result = VMValidateEASLib(pEAS);
- if (result != EAS_SUCCESS)
- return result;
-
- pSynth->pEAS = pEAS;
- return EAS_SUCCESS;
-}
-
-#ifdef DLS_SYNTHESIZER
-/*----------------------------------------------------------------------------
- * VMSetGlobalDLSLib()
- *----------------------------------------------------------------------------
- * Purpose:
- * Sets the DLS library to be used by the synthesizer
- *
- * Inputs:
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT VMSetGlobalDLSLib (EAS_DATA_HANDLE pEASData, EAS_DLSLIB_HANDLE pDLS)
-{
-
- if (pEASData->pVoiceMgr->pGlobalDLS)
- DLSCleanup(pEASData->hwInstData, pEASData->pVoiceMgr->pGlobalDLS);
-
- pEASData->pVoiceMgr->pGlobalDLS = pDLS;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * VMSetDLSLib()
- *----------------------------------------------------------------------------
- * Purpose:
- * Sets the DLS library to be used by the synthesizer
- *
- * Inputs:
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT VMSetDLSLib (S_SYNTH *pSynth, EAS_DLSLIB_HANDLE pDLS)
-{
- pSynth->pDLS = pDLS;
- return EAS_SUCCESS;
-}
-#endif
-
-/*----------------------------------------------------------------------------
- * VMSetTranposition()
- *----------------------------------------------------------------------------
- * Purpose:
- * Sets the global key transposition used by the synthesizer.
- * Transposes all melodic instruments up or down by the specified
- * amount. Range is limited to +/-12 semitones.
- *
- * Inputs:
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-void VMSetTranposition (S_SYNTH *pSynth, EAS_I32 transposition)
-{
- pSynth->globalTranspose = (EAS_I8) transposition;
-}
-
-/*----------------------------------------------------------------------------
- * VMGetTranposition()
- *----------------------------------------------------------------------------
- * Purpose:
- * Gets the global key transposition used by the synthesizer.
- * Transposes all melodic instruments up or down by the specified
- * amount. Range is limited to +/-12 semitones.
- *
- * Inputs:
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-void VMGetTranposition (S_SYNTH *pSynth, EAS_I32 *pTransposition)
-{
- *pTransposition = pSynth->globalTranspose;
-}
-
-/*----------------------------------------------------------------------------
- * VMGetNoteCount()
- *----------------------------------------------------------------------------
-* Returns the total note count
-*----------------------------------------------------------------------------
-*/
-EAS_I32 VMGetNoteCount (S_SYNTH *pSynth)
-{
- return pSynth->totalNoteCount;
-}
-
-/*----------------------------------------------------------------------------
- * VMMIDIShutdown()
- *----------------------------------------------------------------------------
- * Purpose:
- * Clean up any Synth related system issues.
- *
- * Inputs:
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- * None
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-void VMMIDIShutdown (S_EAS_DATA *pEASData, S_SYNTH *pSynth)
-{
- EAS_INT vSynthNum;
-
- /* decrement reference count, free if all references are gone */
- if (--pSynth->refCount > 0)
- return;
-
- vSynthNum = pSynth->vSynthNum;
-
- /* cleanup DLS load */
-#ifdef DLS_SYNTHESIZER
- /*lint -e{550} result used only in debugging code */
- if (pSynth->pDLS != NULL)
- {
- EAS_RESULT result;
- if ((result = DLSCleanup(pEASData->hwInstData, pSynth->pDLS)) != EAS_SUCCESS)
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "VMMIDIShutdown: Error %ld cleaning up DLS collection\n", result); */ }
- pSynth->pDLS = NULL;
- }
-#endif
-
- VMReset(pEASData->pVoiceMgr, pSynth, EAS_TRUE);
-
- /* check Configuration Module for static memory allocation */
- if (!pEASData->staticMemoryModel)
- EAS_HWFree(pEASData->hwInstData, pSynth);
-
- /* clear pointer to MIDI state */
- pEASData->pVoiceMgr->pSynth[vSynthNum] = NULL;
-}
-
-/*----------------------------------------------------------------------------
- * VMShutdown()
- *----------------------------------------------------------------------------
- * Purpose:
- * Clean up any Synth related system issues.
- *
- * Inputs:
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- * None
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-void VMShutdown (S_EAS_DATA *pEASData)
-{
-
- /* don't free a NULL pointer */
- if (pEASData->pVoiceMgr == NULL)
- return;
-
-#ifdef DLS_SYNTHESIZER
- /* if we have a global DLS collection, clean it up */
- if (pEASData->pVoiceMgr->pGlobalDLS)
- {
- DLSCleanup(pEASData->hwInstData, pEASData->pVoiceMgr->pGlobalDLS);
- pEASData->pVoiceMgr->pGlobalDLS = NULL;
- }
-#endif
-
- /* check Configuration Module for static memory allocation */
- if (!pEASData->staticMemoryModel)
- EAS_HWFree(pEASData->hwInstData, pEASData->pVoiceMgr);
- pEASData->pVoiceMgr = NULL;
-}
-
-#ifdef EXTERNAL_AUDIO
-/*----------------------------------------------------------------------------
- * EAS_RegExtAudioCallback()
- *----------------------------------------------------------------------------
- * Register a callback for external audio processing
- *----------------------------------------------------------------------------
-*/
-void VMRegExtAudioCallback (S_SYNTH *pSynth, EAS_VOID_PTR pInstData, EAS_EXT_PRG_CHG_FUNC cbProgChgFunc, EAS_EXT_EVENT_FUNC cbEventFunc)
-{
- pSynth->pExtAudioInstData = pInstData;
- pSynth->cbProgChgFunc = cbProgChgFunc;
- pSynth->cbEventFunc = cbEventFunc;
-}
-
-/*----------------------------------------------------------------------------
- * VMGetMIDIControllers()
- *----------------------------------------------------------------------------
- * Returns the MIDI controller values on the specified channel
- *----------------------------------------------------------------------------
-*/
-void VMGetMIDIControllers (S_SYNTH *pSynth, EAS_U8 channel, S_MIDI_CONTROLLERS *pControl)
-{
- pControl->modWheel = pSynth->channels[channel].modWheel;
- pControl->volume = pSynth->channels[channel].volume;
- pControl->pan = pSynth->channels[channel].pan;
- pControl->expression = pSynth->channels[channel].expression;
- pControl->channelPressure = pSynth->channels[channel].channelPressure;
-
-#ifdef _REVERB
- pControl->reverbSend = pSynth->channels[channel].reverbSend;
-#endif
-
-#ifdef _CHORUSE
- pControl->chorusSend = pSynth->channels[channel].chorusSend;
-#endif
-}
-#endif
-
-#ifdef _SPLIT_ARCHITECTURE
-/*----------------------------------------------------------------------------
- * VMStartFrame()
- *----------------------------------------------------------------------------
- * Purpose:
- * Starts an audio frame
- *
- * Inputs:
- *
- * Outputs:
- * Returns true if EAS_MixEnginePrep should be called (onboard mixing)
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_BOOL VMStartFrame (S_EAS_DATA *pEASData)
-{
-
- /* init counter for voices starts in split architecture */
-#ifdef MAX_VOICE_STARTS
- pVoiceMgr->numVoiceStarts = 0;
-#endif
-
- return pFrameInterface->pfStartFrame(pEASData->pVoiceMgr->pFrameBuffer);
-}
-
-/*----------------------------------------------------------------------------
- * VMEndFrame()
- *----------------------------------------------------------------------------
- * Purpose:
- * Stops an audio frame
- *
- * Inputs:
- *
- * Outputs:
- * Returns true if EAS_MixEnginePost should be called (onboard mixing)
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_BOOL VMEndFrame (S_EAS_DATA *pEASData)
-{
-
- return pFrameInterface->pfEndFrame(pEASData->pVoiceMgr->pFrameBuffer, pEASData->pMixBuffer, pEASData->masterGain);
-}
-#endif
-
-#ifdef TEST_HARNESS
-/*----------------------------------------------------------------------------
- * SanityCheck()
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT VMSanityCheck (EAS_DATA_HANDLE pEASData)
-{
- S_SYNTH_VOICE *pVoice;
- S_SYNTH *pSynth;
- EAS_INT i;
- EAS_INT j;
- EAS_INT freeVoices;
- EAS_INT activeVoices;
- EAS_INT playingVoices;
- EAS_INT stolenVoices;
- EAS_INT releasingVoices;
- EAS_INT mutingVoices;
- EAS_INT poolCount[MAX_VIRTUAL_SYNTHESIZERS][NUM_SYNTH_CHANNELS];
- EAS_INT vSynthNum;
- EAS_RESULT result = EAS_SUCCESS;
-
- /* initialize counts */
- EAS_HWMemSet(poolCount, 0, sizeof(poolCount));
- freeVoices = activeVoices = playingVoices = stolenVoices = releasingVoices = mutingVoices = 0;
-
- /* iterate through all voices */
- for (i = 0; i < MAX_SYNTH_VOICES; i++)
- {
- pVoice = &pEASData->pVoiceMgr->voices[i];
- if (pVoice->voiceState != eVoiceStateFree)
- {
- vSynthNum = GET_VSYNTH(pVoice->channel);
- if (vSynthNum >= MAX_VIRTUAL_SYNTHESIZERS)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "VMSanityCheck: Voice %d has invalid virtual synth number %d\n", i, vSynthNum); */ }
- result = EAS_FAILURE;
- continue;
- }
- pSynth = pEASData->pVoiceMgr->pSynth[vSynthNum];
-
- switch (pVoice->voiceState)
- {
- case eVoiceStateMuting:
- activeVoices++;
- mutingVoices++;
- break;
-
- case eVoiceStateStolen:
- vSynthNum = GET_VSYNTH(pVoice->nextChannel);
- if (vSynthNum >= MAX_VIRTUAL_SYNTHESIZERS)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "VMSanityCheck: Voice %d has invalid virtual synth number %d\n", i, vSynthNum); */ }
- result = EAS_FAILURE;
- continue;
- }
- pSynth = pEASData->pVoiceMgr->pSynth[vSynthNum];
- activeVoices++;
- stolenVoices++;
- poolCount[vSynthNum][pSynth->channels[GET_CHANNEL(pVoice->nextChannel)].pool]++;
- break;
-
- case eVoiceStateStart:
- case eVoiceStatePlay:
- activeVoices++;
- playingVoices++;
- poolCount[vSynthNum][pSynth->channels[GET_CHANNEL(pVoice->channel)].pool]++;
- break;
-
- case eVoiceStateRelease:
- activeVoices++;
- releasingVoices++;
- poolCount[vSynthNum][pSynth->channels[GET_CHANNEL(pVoice->channel)].pool]++;
- break;
-
- default:
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "VMSanityCheck : voice %d in invalid state\n", i); */ }
- result = EAS_FAILURE;
- break;
- }
- }
-
- /* count free voices */
- else
- freeVoices++;
- }
-
- /* dump state info */
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "%d free\n", freeVoices); */ }
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "%d active\n", activeVoices); */ }
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "%d playing\n", playingVoices); */ }
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "%d releasing\n", releasingVoices); */ }
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "%d muting\n", mutingVoices); */ }
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "%d stolen\n", stolenVoices); */ }
-
- if (pEASData->pVoiceMgr->activeVoices != activeVoices)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Active voice mismatch was %d should be %d\n",
- pEASData->pVoiceMgr->activeVoices, activeVoices); */ }
- result = EAS_FAILURE;
- }
-
- /* check virtual synth status */
- for (i = 0; i < MAX_VIRTUAL_SYNTHESIZERS; i++)
- {
- if (pEASData->pVoiceMgr->pSynth[i] == NULL)
- continue;
-
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Synth %d numActiveVoices: %d\n", i, pEASData->pVoiceMgr->pSynth[i]->numActiveVoices); */ }
- if (pEASData->pVoiceMgr->pSynth[i]->numActiveVoices > MAX_SYNTH_VOICES)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "VMSanityCheck: Synth %d illegal count for numActiveVoices: %d\n", i, pEASData->pVoiceMgr->pSynth[i]->numActiveVoices); */ }
- result = EAS_FAILURE;
- }
- for (j = 0; j < NUM_SYNTH_CHANNELS; j++)
- {
- if (poolCount[i][j] != pEASData->pVoiceMgr->pSynth[i]->poolCount[j])
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Pool count mismatch synth %d pool %d, was %d, should be %d\n",
- i, j, pEASData->pVoiceMgr->pSynth[i]->poolCount[j], poolCount[i][j]); */ }
- result = EAS_FAILURE;
- }
- }
- }
-
- return result;
-}
-#endif
-
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 794 $
+ * $Date: 2007-08-01 00:08:48 -0700 (Wed, 01 Aug 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+/* includes */
+#include "eas.h"
+#include "eas_data.h"
+#include "eas_config.h"
+#include "eas_report.h"
+#include "eas_midictrl.h"
+#include "eas_host.h"
+#include "eas_synth_protos.h"
+#include "eas_vm_protos.h"
+
+#ifdef DLS_SYNTHESIZER
+#include "eas_mdls.h"
+#endif
+
+// #define _DEBUG_VM
+
+/* some defines for workload */
+#define WORKLOAD_AMOUNT_SMALL_INCREMENT 5
+#define WORKLOAD_AMOUNT_START_NOTE 10
+#define WORKLOAD_AMOUNT_STOP_NOTE 10
+#define WORKLOAD_AMOUNT_KEY_GROUP 10
+#define WORKLOAD_AMOUNT_POLY_LIMIT 10
+
+/* pointer to base sound library */
+extern S_EAS easSoundLib;
+
+#ifdef TEST_HARNESS
+extern S_EAS easTestLib;
+EAS_SNDLIB_HANDLE VMGetLibHandle(EAS_INT libNum)
+{
+ switch (libNum)
+ {
+ case 0:
+ return &easSoundLib;
+#ifdef _WT_SYNTH
+ case 1:
+ return &easTestLib;
+#endif
+ default:
+ return NULL;
+ }
+}
+#endif
+
+/* pointer to synthesizer interface(s) */
+#ifdef _WT_SYNTH
+extern const S_SYNTH_INTERFACE wtSynth;
+#endif
+
+#ifdef _FM_SYNTH
+extern const S_SYNTH_INTERFACE fmSynth;
+#endif
+
+typedef S_SYNTH_INTERFACE *S_SYNTH_INTERFACE_HANDLE;
+
+/* wavetable on MCU */
+#if defined(EAS_WT_SYNTH)
+const S_SYNTH_INTERFACE *const pPrimarySynth = &wtSynth;
+
+/* FM on MCU */
+#elif defined(EAS_FM_SYNTH)
+const S_SYNTH_INTERFACE *const pPrimarySynth = &fmSynth;
+
+/* wavetable drums on MCU, FM melodic on DSP */
+#elif defined(EAS_HYBRID_SYNTH)
+const S_SYNTH_INTERFACE *const pPrimarySynth = &wtSynth;
+const S_SYNTH_INTERFACE *const pSecondarySynth = &fmSynth;
+
+/* wavetable drums on MCU, wavetable melodic on DSP */
+#elif defined(EAS_SPLIT_WT_SYNTH)
+const S_SYNTH_INTERFACE *const pPrimarySynth = &wtSynth;
+extern const S_FRAME_INTERFACE wtFrameInterface;
+const S_FRAME_INTERFACE *const pFrameInterface = &wtFrameInterface;
+
+/* wavetable drums on MCU, FM melodic on DSP */
+#elif defined(EAS_SPLIT_HYBRID_SYNTH)
+const S_SYNTH_INTERFACE *const pPrimarySynth = &wtSynth;
+const S_SYNTH_INTERFACE *const pSecondarySynth = &fmSynth;
+extern const S_FRAME_INTERFACE fmFrameInterface;
+const S_FRAME_INTERFACE *const pFrameInterface = &fmFrameInterface;
+
+/* FM on DSP */
+#elif defined(EAS_SPLIT_FM_SYNTH)
+const S_SYNTH_INTERFACE *const pPrimarySynth = &fmSynth;
+extern const S_FRAME_INTERFACE fmFrameInterface;
+const S_FRAME_INTERFACE *const pFrameInterface = &fmFrameInterface;
+
+#else
+#error "Undefined architecture option"
+#endif
+
+/*----------------------------------------------------------------------------
+ * inline functions
+ *----------------------------------------------------------------------------
+*/
+EAS_INLINE const S_REGION* GetRegionPtr (S_SYNTH *pSynth, EAS_U16 regionIndex)
+{
+#if defined(DLS_SYNTHESIZER)
+ if (regionIndex & FLAG_RGN_IDX_DLS_SYNTH)
+ return &pSynth->pDLS->pDLSRegions[regionIndex & REGION_INDEX_MASK].wtRegion.region;
+#endif
+#if defined(_HYBRID_SYNTH)
+ if (regionIndex & FLAG_RGN_IDX_FM_SYNTH)
+ return &pSynth->pEAS->pFMRegions[regionIndex & REGION_INDEX_MASK].region;
+ else
+ return &pSynth->pEAS->pWTRegions[regionIndex].region;
+#elif defined(_WT_SYNTH)
+ return &pSynth->pEAS->pWTRegions[regionIndex].region;
+#elif defined(_FM_SYNTH)
+ return &pSynth->pEAS->pFMRegions[regionIndex].region;
+#endif
+}
+
+/*lint -esym(715, voiceNum) used in some implementation */
+EAS_INLINE const S_SYNTH_INTERFACE* GetSynthPtr (EAS_INT voiceNum)
+{
+#if defined(_HYBRID_SYNTH)
+ if (voiceNum < NUM_PRIMARY_VOICES)
+ return pPrimarySynth;
+ else
+ return pSecondarySynth;
+#else
+ return pPrimarySynth;
+#endif
+}
+
+EAS_INLINE EAS_INT GetAdjustedVoiceNum (EAS_INT voiceNum)
+{
+#if defined(_HYBRID_SYNTH)
+ if (voiceNum >= NUM_PRIMARY_VOICES)
+ return voiceNum - NUM_PRIMARY_VOICES;
+#endif
+ return voiceNum;
+}
+
+EAS_INLINE EAS_U8 VSynthToChannel (S_SYNTH *pSynth, EAS_U8 channel)
+{
+ /*lint -e{734} synthNum is always 0-15 */
+ return channel | (pSynth->vSynthNum << 4);
+}
+
+/*----------------------------------------------------------------------------
+ * InitVoice()
+ *----------------------------------------------------------------------------
+ * Initialize a synthesizer voice
+ *----------------------------------------------------------------------------
+*/
+void InitVoice (S_SYNTH_VOICE *pVoice)
+{
+ pVoice->channel = UNASSIGNED_SYNTH_CHANNEL;
+ pVoice->nextChannel = UNASSIGNED_SYNTH_CHANNEL;
+ pVoice->note = pVoice->nextNote = DEFAULT_KEY_NUMBER;
+ pVoice->velocity = pVoice->nextVelocity = DEFAULT_VELOCITY;
+ pVoice->regionIndex = DEFAULT_REGION_INDEX;
+ pVoice->age = DEFAULT_AGE;
+ pVoice->voiceFlags = DEFAULT_VOICE_FLAGS;
+ pVoice->voiceState = DEFAULT_VOICE_STATE;
+}
+
+/*----------------------------------------------------------------------------
+ * IncVoicePoolCount()
+ *----------------------------------------------------------------------------
+ * Updates the voice pool count when a voice changes state
+ *----------------------------------------------------------------------------
+*/
+static void IncVoicePoolCount (S_VOICE_MGR *pVoiceMgr, S_SYNTH_VOICE *pVoice)
+{
+ S_SYNTH *pSynth;
+ EAS_INT pool;
+
+ /* ignore muting voices */
+ if (pVoice->voiceState == eVoiceStateMuting)
+ return;
+
+ if (pVoice->voiceState == eVoiceStateStolen)
+ {
+ pSynth = pVoiceMgr->pSynth[GET_VSYNTH(pVoice->nextChannel)];
+ pool = pSynth->channels[GET_CHANNEL(pVoice->nextChannel)].pool;
+ }
+ else
+ {
+ pSynth = pVoiceMgr->pSynth[GET_VSYNTH(pVoice->channel)];
+ pool = pSynth->channels[GET_CHANNEL(pVoice->channel)].pool;
+ }
+
+ pSynth->poolCount[pool]++;
+
+#ifdef _DEBUG_VM
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IncVoicePoolCount: Synth=%d pool=%d\n", pSynth->vSynthNum, pool); */ }
+#endif
+}
+
+/*----------------------------------------------------------------------------
+ * DecVoicePoolCount()
+ *----------------------------------------------------------------------------
+ * Updates the voice pool count when a voice changes state
+ *----------------------------------------------------------------------------
+*/
+static void DecVoicePoolCount (S_VOICE_MGR *pVoiceMgr, S_SYNTH_VOICE *pVoice)
+{
+ S_SYNTH *pSynth;
+ EAS_INT pool;
+
+ /* ignore muting voices */
+ if (pVoice->voiceState == eVoiceStateMuting)
+ return;
+
+ if (pVoice->voiceState == eVoiceStateStolen)
+ {
+ pSynth = pVoiceMgr->pSynth[GET_VSYNTH(pVoice->nextChannel)];
+ pool = pSynth->channels[GET_CHANNEL(pVoice->nextChannel)].pool;
+ }
+ else
+ {
+ pSynth = pVoiceMgr->pSynth[GET_VSYNTH(pVoice->channel)];
+ pool = pSynth->channels[GET_CHANNEL(pVoice->channel)].pool;
+ }
+
+ pSynth->poolCount[pool]--;
+
+#ifdef _DEBUG_VM
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "DecVoicePoolCount: Synth=%d pool=%d\n", pSynth->vSynthNum, pool); */ }
+#endif
+}
+
+/*----------------------------------------------------------------------------
+ * VMInitialize()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ *
+ * Inputs:
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT VMInitialize (S_EAS_DATA *pEASData)
+{
+ S_VOICE_MGR *pVoiceMgr;
+ EAS_INT i;
+
+ /* check Configuration Module for data allocation */
+ if (pEASData->staticMemoryModel)
+ pVoiceMgr = EAS_CMEnumData(EAS_CM_SYNTH_DATA);
+ else
+ pVoiceMgr = EAS_HWMalloc(pEASData->hwInstData, sizeof(S_VOICE_MGR));
+ if (!pVoiceMgr)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "VMInitialize: Failed to allocate synthesizer memory\n"); */ }
+ return EAS_ERROR_MALLOC_FAILED;
+ }
+ EAS_HWMemSet(pVoiceMgr, 0, sizeof(S_VOICE_MGR));
+
+ /* initialize non-zero variables */
+ pVoiceMgr->pGlobalEAS = (S_EAS*) &easSoundLib;
+ pVoiceMgr->maxPolyphony = (EAS_U16) MAX_SYNTH_VOICES;
+
+#if defined(_SECONDARY_SYNTH) || defined(EAS_SPLIT_WT_SYNTH)
+ pVoiceMgr->maxPolyphonyPrimary = NUM_PRIMARY_VOICES;
+ pVoiceMgr->maxPolyphonySecondary = NUM_SECONDARY_VOICES;
+#endif
+
+ /* set max workload to zero */
+ pVoiceMgr->maxWorkLoad = 0;
+
+ /* initialize the voice manager parameters */
+ for (i = 0; i < MAX_SYNTH_VOICES; i++)
+ InitVoice(&pVoiceMgr->voices[i]);
+
+ /* initialize the synth */
+ /*lint -e{522} return unused at this time */
+ pPrimarySynth->pfInitialize(pVoiceMgr);
+
+ /* initialize the off-chip synth */
+#ifdef _HYBRID_SYNTH
+ /*lint -e{522} return unused at this time */
+ pSecondarySynth->pfInitialize(pVoiceMgr);
+#endif
+
+ pEASData->pVoiceMgr = pVoiceMgr;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * VMInitMIDI()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ *
+ * Inputs:
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT VMInitMIDI (S_EAS_DATA *pEASData, S_SYNTH **ppSynth)
+{
+ EAS_RESULT result;
+ S_SYNTH *pSynth;
+ EAS_INT virtualSynthNum;
+
+ *ppSynth = NULL;
+
+ /* static memory model only allows one synth */
+ if (pEASData->staticMemoryModel)
+ {
+ if (pEASData->pVoiceMgr->pSynth[0] != NULL)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "VMInitMIDI: No virtual synthesizer support for static memory model\n"); */ }
+ return EAS_ERROR_NO_VIRTUAL_SYNTHESIZER;
+ }
+
+ /* check Configuration Module for data allocation */
+ pSynth = EAS_CMEnumData(EAS_CM_MIDI_DATA);
+ virtualSynthNum = 0;
+ }
+
+ /* dynamic memory model */
+ else
+ {
+ for (virtualSynthNum = 0; virtualSynthNum < MAX_VIRTUAL_SYNTHESIZERS; virtualSynthNum++)
+ if (pEASData->pVoiceMgr->pSynth[virtualSynthNum] == NULL)
+ break;
+ if (virtualSynthNum == MAX_VIRTUAL_SYNTHESIZERS)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "VMInitMIDI: Exceeded number of active virtual synthesizers"); */ }
+ return EAS_ERROR_NO_VIRTUAL_SYNTHESIZER;
+ }
+ pSynth = EAS_HWMalloc(pEASData->hwInstData, sizeof(S_SYNTH));
+ }
+
+ /* make sure we have a valid memory pointer */
+ if (pSynth == NULL)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "VMInitMIDI: Failed to allocate synthesizer memory\n"); */ }
+ return EAS_ERROR_MALLOC_FAILED;
+ }
+ EAS_HWMemSet(pSynth, 0, sizeof(S_SYNTH));
+
+ /* set the sound library pointer */
+ if ((result = VMSetEASLib(pSynth, pEASData->pVoiceMgr->pGlobalEAS)) != EAS_SUCCESS)
+ {
+ VMMIDIShutdown(pEASData, pSynth);
+ return result;
+ }
+
+ /* link in DLS bank if downloaded */
+#ifdef DLS_SYNTHESIZER
+ if (pEASData->pVoiceMgr->pGlobalDLS)
+ {
+ pSynth->pDLS = pEASData->pVoiceMgr->pGlobalDLS;
+ DLSAddRef(pSynth->pDLS);
+ }
+#endif
+
+ /* initialize MIDI state variables */
+ pSynth->synthFlags = DEFAULT_SYNTH_FLAGS;
+ pSynth->masterVolume = DEFAULT_SYNTH_MASTER_VOLUME;
+ pSynth->refCount = 1;
+ pSynth->priority = DEFAULT_SYNTH_PRIORITY;
+ pSynth->poolAlloc[0] = (EAS_U8) pEASData->pVoiceMgr->maxPolyphony;
+
+ VMInitializeAllChannels(pEASData->pVoiceMgr, pSynth);
+
+ pSynth->vSynthNum = (EAS_U8) virtualSynthNum;
+ pEASData->pVoiceMgr->pSynth[virtualSynthNum] = pSynth;
+
+ *ppSynth = pSynth;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * VMIncRefCount()
+ *----------------------------------------------------------------------------
+ * Increment reference count for virtual synth
+ *----------------------------------------------------------------------------
+*/
+void VMIncRefCount (S_SYNTH *pSynth)
+{
+ pSynth->refCount++;
+}
+
+/*----------------------------------------------------------------------------
+ * VMReset()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * We call this routine to start the process of reseting the synth.
+ * This routine sets a flag for the entire synth indicating that we want
+ * to reset.
+ * We also force all voices to mute quickly.
+ * However, we do not actually perform any synthesis in this routine. That
+ * is, we do not ramp the voices down from this routine, but instead, we
+ * let the "regular" synth processing steps take care of adding the ramp
+ * down samples to the output buffer. After we are sure that all voices
+ * have completed ramping down, we continue the process of resetting the
+ * synth (from another routine).
+ *
+ * Inputs:
+ * psEASData - pointer to overall EAS data structure
+ * force - force reset even if voices are active
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ * - set a flag (in psSynthObject->m_nFlags) indicating synth reset requested.
+ * - force all voices to update their envelope states to mute
+ *
+ *----------------------------------------------------------------------------
+*/
+void VMReset (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_BOOL force)
+{
+
+#ifdef _DEBUG_VM
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMReset: request to reset synth. Force = %d\n", force); */ }
+#endif
+
+ /* force voices to off state - may cause audio artifacts */
+ if (force)
+ {
+ pVoiceMgr->activeVoices -= pSynth->numActiveVoices;
+ pSynth->numActiveVoices = 0;
+ VMInitializeAllVoices(pVoiceMgr, pSynth->vSynthNum);
+ }
+ else
+ VMMuteAllVoices(pVoiceMgr, pSynth);
+
+ /* don't reset if voices are still playing */
+ if (pSynth->numActiveVoices == 0)
+ {
+ EAS_INT i;
+
+#ifdef _DEBUG_VM
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMReset: complete the reset process\n"); */ }
+#endif
+
+ VMInitializeAllChannels(pVoiceMgr, pSynth);
+ for (i = 0; i < NUM_SYNTH_CHANNELS; i++)
+ pSynth->poolCount[i] = 0;
+
+ /* set polyphony */
+ if (pSynth->maxPolyphony < pVoiceMgr->maxPolyphony)
+ pSynth->poolAlloc[0] = (EAS_U8) pVoiceMgr->maxPolyphony;
+ else
+ pSynth->poolAlloc[0] = (EAS_U8) pSynth->maxPolyphony;
+
+ /* clear reset flag */
+ pSynth->synthFlags &= ~SYNTH_FLAG_RESET_IS_REQUESTED;
+ }
+
+ /* handle reset after voices are muted */
+ else
+ pSynth->synthFlags |= SYNTH_FLAG_RESET_IS_REQUESTED;
+}
+
+/*----------------------------------------------------------------------------
+ * VMInitializeAllChannels()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ *
+ * Inputs:
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ *
+ *----------------------------------------------------------------------------
+*/
+void VMInitializeAllChannels (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth)
+{
+ S_SYNTH_CHANNEL *pChannel;
+ EAS_INT i;
+
+ VMResetControllers(pSynth);
+
+ /* init each channel */
+ pChannel = pSynth->channels;
+
+ for (i = 0; i < NUM_SYNTH_CHANNELS; i++, pChannel++)
+ {
+ pChannel->channelFlags = DEFAULT_CHANNEL_FLAGS;
+ pChannel->staticGain = DEFAULT_CHANNEL_STATIC_GAIN;
+ pChannel->staticPitch = DEFAULT_CHANNEL_STATIC_PITCH;
+ pChannel->pool = 0;
+
+ /* the drum channel needs a different init */
+ if (i == DEFAULT_DRUM_CHANNEL)
+ {
+ pChannel->bankNum = DEFAULT_RHYTHM_BANK_NUMBER;
+ pChannel->channelFlags |= CHANNEL_FLAG_RHYTHM_CHANNEL;
+ }
+ else
+ pChannel->bankNum = DEFAULT_MELODY_BANK_NUMBER;
+
+ VMProgramChange(pVoiceMgr, pSynth, (EAS_U8) i, DEFAULT_SYNTH_PROGRAM_NUMBER);
+ }
+
+}
+
+/*----------------------------------------------------------------------------
+ * VMResetControllers()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ *
+ * Inputs:
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ *
+ *----------------------------------------------------------------------------
+*/
+void VMResetControllers (S_SYNTH *pSynth)
+{
+ S_SYNTH_CHANNEL *pChannel;
+ EAS_INT i;
+
+ pChannel = pSynth->channels;
+
+ for (i = 0; i < NUM_SYNTH_CHANNELS; i++, pChannel++)
+ {
+ pChannel->pitchBend = DEFAULT_PITCH_BEND;
+ pChannel->modWheel = DEFAULT_MOD_WHEEL;
+ pChannel->volume = DEFAULT_CHANNEL_VOLUME;
+ pChannel->pan = DEFAULT_PAN;
+ pChannel->expression = DEFAULT_EXPRESSION;
+
+#ifdef _REVERB
+ pSynth->channels[i].reverbSend = DEFAULT_REVERB_SEND;
+#endif
+
+#ifdef _CHORUS
+ pSynth->channels[i].chorusSend = DEFAULT_CHORUS_SEND;
+#endif
+
+ pChannel->channelPressure = DEFAULT_CHANNEL_PRESSURE;
+ pChannel->registeredParam = DEFAULT_REGISTERED_PARAM;
+ pChannel->pitchBendSensitivity = DEFAULT_PITCH_BEND_SENSITIVITY;
+ pChannel->finePitch = DEFAULT_FINE_PITCH;
+ pChannel->coarsePitch = DEFAULT_COARSE_PITCH;
+
+ /* update all voices on this channel */
+ pChannel->channelFlags |= CHANNEL_FLAG_UPDATE_CHANNEL_PARAMETERS;
+ }
+}
+
+/*----------------------------------------------------------------------------
+ * VMInitializeAllVoices()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ *
+ * Inputs:
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ *
+ *----------------------------------------------------------------------------
+*/
+void VMInitializeAllVoices (S_VOICE_MGR *pVoiceMgr, EAS_INT vSynthNum)
+{
+ EAS_INT i;
+
+ /* initialize the voice manager parameters */
+ for (i = 0; i < MAX_SYNTH_VOICES; i++)
+ {
+ if (pVoiceMgr->voices[i].voiceState != eVoiceStateStolen)
+ {
+ if (GET_VSYNTH(pVoiceMgr->voices[i].channel) == vSynthNum)
+ InitVoice(&pVoiceMgr->voices[i]);
+ }
+ else
+ {
+ if (GET_VSYNTH(pVoiceMgr->voices[i].nextChannel) == vSynthNum)
+ InitVoice(&pVoiceMgr->voices[i]);
+ }
+ }
+}
+
+/*----------------------------------------------------------------------------
+ * VMMuteVoice()
+ *----------------------------------------------------------------------------
+ * Mute the selected voice
+ *----------------------------------------------------------------------------
+*/
+void VMMuteVoice (S_VOICE_MGR *pVoiceMgr, EAS_I32 voiceNum)
+{
+ S_SYNTH *pSynth;
+ S_SYNTH_VOICE *pVoice;
+
+ /* take no action if voice is already muted */
+ pVoice = &pVoiceMgr->voices[voiceNum];
+ if ((pVoice->voiceState == eVoiceStateMuting) || (pVoice->voiceState == eVoiceStateFree))
+ return;
+
+ /* one less voice in pool */
+ DecVoicePoolCount(pVoiceMgr, pVoice);
+
+ pSynth = pVoiceMgr->pSynth[GET_VSYNTH(pVoice->channel)];
+ GetSynthPtr(voiceNum)->pfMuteVoice(pVoiceMgr, pSynth, pVoice, GetAdjustedVoiceNum(voiceNum));
+ pVoice->voiceState = eVoiceStateMuting;
+
+}
+
+/*----------------------------------------------------------------------------
+ * VMReleaseVoice()
+ *----------------------------------------------------------------------------
+ * Release the selected voice
+ *----------------------------------------------------------------------------
+*/
+void VMReleaseVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_I32 voiceNum)
+{
+ S_SYNTH_VOICE *pVoice = &pVoiceMgr->voices[voiceNum];
+
+ /* take no action if voice is already free, muting, or releasing */
+ if (( pVoice->voiceState == eVoiceStateMuting) ||
+ (pVoice->voiceState == eVoiceStateFree) ||
+ (pVoice->voiceState == eVoiceStateRelease))
+ return;
+
+ /* stolen voices should just be muted */
+ if (pVoice->voiceState == eVoiceStateStolen)
+ VMMuteVoice(pVoiceMgr, voiceNum);
+
+ /* release this voice */
+ GetSynthPtr(voiceNum)->pfReleaseVoice(pVoiceMgr, pSynth, &pVoiceMgr->voices[voiceNum], GetAdjustedVoiceNum(voiceNum));
+ pVoice->voiceState = eVoiceStateRelease;
+}
+
+/*----------------------------------------------------------------------------
+ * VMInitMIPTable()
+ *----------------------------------------------------------------------------
+ * Initialize the SP-MIDI MIP table in preparation for receiving MIP message
+ *----------------------------------------------------------------------------
+*/
+void VMInitMIPTable (S_SYNTH *pSynth)
+{
+ EAS_INT i;
+
+#ifdef _DEBUG_VM
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMInitMIPTable\n"); */ }
+#endif
+
+ /* clear SP-MIDI flag */
+ pSynth->synthFlags &= ~SYNTH_FLAG_SP_MIDI_ON;
+ for (i = 0; i < NUM_SYNTH_CHANNELS; i++)
+ {
+ pSynth->channels[i].pool = 0;
+ pSynth->channels[i].mip = 0;
+ }
+}
+
+/*----------------------------------------------------------------------------
+ * VMSetMIPEntry()
+ *----------------------------------------------------------------------------
+ * Sets the priority and MIP level for a MIDI channel
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pVoiceMgr) reserved for future use */
+void VMSetMIPEntry (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel, EAS_U8 priority, EAS_U8 mip)
+{
+
+#ifdef _DEBUG_VM
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMSetMIPEntry: channel=%d, priority=%d, MIP=%d\n", channel, priority, mip); */ }
+#endif
+
+ /* save data for use by MIP message processing */
+ if (priority < NUM_SYNTH_CHANNELS)
+ {
+ pSynth->channels[channel].pool = priority;
+ pSynth->channels[channel].mip = mip;
+ }
+}
+
+/*----------------------------------------------------------------------------
+ * VMMIPUpdateChannelMuting()
+ *----------------------------------------------------------------------------
+ * This routine is called after an SP-MIDI message is received and
+ * any time the allocated polyphony changes. It mutes or unmutes
+ * channels based on polyphony.
+ *----------------------------------------------------------------------------
+*/
+void VMMIPUpdateChannelMuting (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth)
+{
+ EAS_INT i;
+ EAS_INT maxPolyphony;
+ EAS_INT channel;
+ EAS_INT vSynthNum;
+ EAS_INT pool;
+
+#ifdef _DEBUG_VM
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMUpdateMIPTable\n"); */ }
+#endif
+
+ /* determine max polyphony */
+ if (pSynth->maxPolyphony)
+ maxPolyphony = pSynth->maxPolyphony;
+ else
+ maxPolyphony = pVoiceMgr->maxPolyphony;
+
+ /* process channels */
+ for (i = 0; i < NUM_SYNTH_CHANNELS; i++)
+ {
+
+ /* channel must be in MIP message and must meet allocation target */
+ if ((pSynth->channels[i].mip != 0) && (pSynth->channels[i].mip <= maxPolyphony))
+ pSynth->channels[i].channelFlags &= ~CHANNEL_FLAG_MUTE;
+ else
+ pSynth->channels[i].channelFlags |= CHANNEL_FLAG_MUTE;
+
+ /* reset voice pool count */
+ pSynth->poolCount[i] = 0;
+ }
+
+ /* mute any voices on muted channels, and count unmuted voices */
+ for (i = 0; i < MAX_SYNTH_VOICES; i++)
+ {
+
+ /* ignore free voices */
+ if (pVoiceMgr->voices[i].voiceState == eVoiceStateFree)
+ continue;
+
+ /* get channel and virtual synth */
+ if (pVoiceMgr->voices[i].voiceState != eVoiceStateStolen)
+ {
+ vSynthNum = GET_VSYNTH(pVoiceMgr->voices[i].channel);
+ channel = GET_CHANNEL(pVoiceMgr->voices[i].channel);
+ }
+ else
+ {
+ vSynthNum = GET_VSYNTH(pVoiceMgr->voices[i].nextChannel);
+ channel = GET_CHANNEL(pVoiceMgr->voices[i].nextChannel);
+ }
+
+ /* ignore voices on other synths */
+ if (vSynthNum != pSynth->vSynthNum)
+ continue;
+
+ /* count voices */
+ pool = pSynth->channels[channel].pool;
+
+ /* deal with muted channels */
+ if (pSynth->channels[channel].channelFlags & CHANNEL_FLAG_MUTE)
+ {
+ /* mute stolen voices scheduled to play on this channel */
+ if (pVoiceMgr->voices[i].voiceState == eVoiceStateStolen)
+ pVoiceMgr->voices[i].voiceState = eVoiceStateMuting;
+
+ /* release voices that aren't already muting */
+ else if (pVoiceMgr->voices[i].voiceState != eVoiceStateMuting)
+ {
+ VMReleaseVoice(pVoiceMgr, pSynth, i);
+ pSynth->poolCount[pool]++;
+ }
+ }
+
+ /* not muted, count this voice */
+ else
+ pSynth->poolCount[pool]++;
+ }
+}
+
+/*----------------------------------------------------------------------------
+ * VMUpdateMIPTable()
+ *----------------------------------------------------------------------------
+ * This routine is called at the end of the SysEx message to allow
+ * the Voice Manager to complete the initialization of the MIP
+ * table. It assigns channels to the appropriate voice pool based
+ * on the MIP setting and calculates the voices allocated for each
+ * pool.
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pVoiceMgr) reserved for future use */
+void VMUpdateMIPTable (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth)
+{
+ S_SYNTH_CHANNEL *pChannel;
+ EAS_INT i;
+ EAS_INT currentMIP;
+ EAS_INT currentPool;
+ EAS_INT priority[NUM_SYNTH_CHANNELS];
+
+#ifdef _DEBUG_VM
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMUpdateMIPTable\n"); */ }
+#endif
+
+ /* set SP-MIDI flag */
+ pSynth->synthFlags |= SYNTH_FLAG_SP_MIDI_ON;
+
+ /* sort channels into priority order */
+ for (i = 0; i < NUM_SYNTH_CHANNELS; i++)
+ priority[i] = -1;
+ for (i = 0; i < NUM_SYNTH_CHANNELS; i++)
+ {
+ if (pSynth->channels[i].pool != DEFAULT_SP_MIDI_PRIORITY)
+ priority[pSynth->channels[i].pool] = i;
+ }
+
+ /* process channels in priority order */
+ currentMIP = 0;
+ currentPool = -1;
+ for (i = 0; i < NUM_SYNTH_CHANNELS; i++)
+ {
+ /* stop when we run out of channels */
+ if (priority[i] == -1)
+ break;
+
+ pChannel = &pSynth->channels[priority[i]];
+
+ /* when 2 or more channels have the same MIP setting, they
+ * share a common voice pool
+ */
+ if (pChannel->mip == currentMIP)
+ pChannel->pool = (EAS_U8) currentPool;
+
+ /* new voice pool */
+ else
+ {
+ currentPool++;
+ pSynth->poolAlloc[currentPool] = (EAS_U8) (pChannel->mip - currentMIP);
+ currentMIP = pChannel->mip;
+ }
+ }
+
+ /* set SP-MIDI flag */
+ pSynth->synthFlags |= SYNTH_FLAG_SP_MIDI_ON;
+
+ /* update channel muting */
+ VMMIPUpdateChannelMuting (pVoiceMgr, pSynth);
+}
+
+/*----------------------------------------------------------------------------
+ * VMMuteAllVoices()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * We call this in an emergency reset situation.
+ * This forces all voices to mute quickly.
+ *
+ * Inputs:
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ * - forces all voices to update their envelope states to mute
+ *
+ *----------------------------------------------------------------------------
+*/
+void VMMuteAllVoices (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth)
+{
+ EAS_INT i;
+
+#ifdef _DEBUG_VM
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMMuteAllVoices: about to mute all voices!!\n"); */ }
+#endif
+
+ for (i = 0; i < MAX_SYNTH_VOICES; i++)
+ {
+ /* for stolen voices, check new channel */
+ if (pVoiceMgr->voices[i].voiceState == eVoiceStateStolen)
+ {
+ if (GET_VSYNTH(pVoiceMgr->voices[i].nextChannel) == pSynth->vSynthNum)
+ VMMuteVoice(pVoiceMgr, i);
+ }
+
+ else if (pSynth->vSynthNum == GET_VSYNTH(pVoiceMgr->voices[i].channel))
+ VMMuteVoice(pVoiceMgr, i);
+ }
+}
+
+/*----------------------------------------------------------------------------
+ * VMReleaseAllVoices()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * We call this after we've encountered the end of the Midi file.
+ * This ensures all voices are either in release (because we received their
+ * note off already) or forces them to mute quickly.
+ * We use this as a safety to prevent bad midi files from playing forever.
+ *
+ * Inputs:
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ * - forces all voices to update their envelope states to release or mute
+ *
+ *----------------------------------------------------------------------------
+*/
+void VMReleaseAllVoices (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth)
+{
+ EAS_INT i;
+
+ /* release sustain pedal on all channels */
+ for (i = 0; i < NUM_SYNTH_CHANNELS; i++)
+ {
+ if (pSynth->channels[ i ].channelFlags & CHANNEL_FLAG_SUSTAIN_PEDAL)
+ {
+ VMReleaseAllDeferredNoteOffs(pVoiceMgr, pSynth, (EAS_U8) i);
+ pSynth->channels[i].channelFlags &= ~CHANNEL_FLAG_SUSTAIN_PEDAL;
+ }
+ }
+
+ /* release all voices */
+ for (i = 0; i < MAX_SYNTH_VOICES; i++)
+ {
+
+ switch (pVoiceMgr->voices[i].voiceState)
+ {
+ case eVoiceStateStart:
+ case eVoiceStatePlay:
+ /* only release voices on this synth */
+ if (GET_VSYNTH(pVoiceMgr->voices[i].channel) == pSynth->vSynthNum)
+ VMReleaseVoice(pVoiceMgr, pSynth, i);
+ break;
+
+ case eVoiceStateStolen:
+ if (GET_VSYNTH(pVoiceMgr->voices[i].nextChannel) == pSynth->vSynthNum)
+ VMMuteVoice(pVoiceMgr, i);
+ break;
+
+ case eVoiceStateFree:
+ case eVoiceStateRelease:
+ case eVoiceStateMuting:
+ break;
+
+ case eVoiceStateInvalid:
+ default:
+#ifdef _DEBUG_VM
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMReleaseAllVoices: error, %d is an unrecognized state\n",
+ pVoiceMgr->voices[i].voiceState); */ }
+#endif
+ break;
+ }
+ }
+}
+
+/*----------------------------------------------------------------------------
+ * VMAllNotesOff()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Quickly mute all notes on the given channel.
+ *
+ * Inputs:
+ * nChannel - quickly turn off all notes on this channel
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ * - forces all voices on this channel to update their envelope states to mute
+ *
+ *----------------------------------------------------------------------------
+*/
+void VMAllNotesOff (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel)
+{
+ EAS_INT voiceNum;
+ S_SYNTH_VOICE *pVoice;
+
+#ifdef _DEBUG_VM
+ if (channel >= NUM_SYNTH_CHANNELS)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMAllNotesOff: error, %d invalid channel number\n",
+ channel); */ }
+ return;
+ }
+#endif
+
+ /* increment workload */
+ pVoiceMgr->workload += WORKLOAD_AMOUNT_SMALL_INCREMENT;
+
+ /* check each voice */
+ channel = VSynthToChannel(pSynth, channel);
+ for (voiceNum = 0; voiceNum < MAX_SYNTH_VOICES; voiceNum++)
+ {
+ pVoice = &pVoiceMgr->voices[voiceNum];
+ if (pVoice->voiceState != eVoiceStateFree)
+ {
+ if (((pVoice->voiceState != eVoiceStateStolen) && (channel == pVoice->channel)) ||
+ ((pVoice->voiceState == eVoiceStateStolen) && (channel == pVoice->nextChannel)))
+ {
+ /* this voice is assigned to the requested channel */
+ GetSynthPtr(voiceNum)->pfMuteVoice(pVoiceMgr, pSynth, pVoice, GetAdjustedVoiceNum(voiceNum));
+ pVoice->voiceState = eVoiceStateMuting;
+ }
+ }
+ }
+}
+
+/*----------------------------------------------------------------------------
+ * VMDeferredStopNote()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Stop the notes that had deferred note-off requests.
+ *
+ * Inputs:
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ * None.
+ *
+ * Side Effects:
+ * voices that have had deferred note-off requests are now put into release
+ * psSynthObject->m_sVoice[i].m_nFlags has the VOICE_FLAG_DEFER_MIDI_NOTE_OFF
+ * cleared
+ *----------------------------------------------------------------------------
+*/
+void VMDeferredStopNote (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth)
+{
+ EAS_INT voiceNum;
+ EAS_INT channel;
+ EAS_BOOL deferredNoteOff;
+
+ deferredNoteOff = EAS_FALSE;
+
+ /* check each voice to see if it requires a deferred note off */
+ for (voiceNum=0; voiceNum < MAX_SYNTH_VOICES; voiceNum++)
+ {
+ if (pVoiceMgr->voices[voiceNum].voiceFlags & VOICE_FLAG_DEFER_MIDI_NOTE_OFF)
+ {
+ /* check if this voice was stolen */
+ if (pVoiceMgr->voices[voiceNum].voiceState == eVoiceStateStolen)
+ {
+ /*
+ This voice was stolen, AND it also has a deferred note-off.
+ The stolen note must be completely ramped down at this point.
+ The note that caused the stealing to occur, however, must
+ have received a note-off request before the note that caused
+ stealing ever had a chance to even start. We want to give
+ the note that caused the stealing a chance to play, so we
+ start it on the next update interval, and we defer sending
+ the note-off request until the subsequent update interval.
+ So do not send the note-off request for this voice because
+ this voice was stolen and should have completed ramping down,
+ Also, do not clear the global flag nor this voice's flag
+ because we must indicate that the subsequent update interval,
+ after the note that caused stealing has started, should
+ then send the deferred note-off request.
+ */
+ deferredNoteOff = EAS_TRUE;
+
+#ifdef _DEBUG_VM
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMDeferredStopNote: defer request to stop voice %d (channel=%d note=%d) - voice not started\n",
+ voiceNum,
+ pVoiceMgr->voices[voiceNum].nextChannel,
+ pVoiceMgr->voices[voiceNum].note); */ }
+
+ /* sanity check: this stolen voice better be ramped to zero */
+ if (0 != pVoiceMgr->voices[voiceNum].gain)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMDeferredStopNote: warning, this voice did not complete its ramp to zero\n"); */ }
+ }
+#endif // #ifdef _DEBUG_VM
+
+ }
+ else
+ {
+ /* clear the flag using exor */
+ pVoiceMgr->voices[voiceNum].voiceFlags ^=
+ VOICE_FLAG_DEFER_MIDI_NOTE_OFF;
+
+#ifdef _DEBUG_VM
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMDeferredStopNote: Stop voice %d (channel=%d note=%d)\n",
+ voiceNum,
+ pVoiceMgr->voices[voiceNum].nextChannel,
+ pVoiceMgr->voices[voiceNum].note); */ }
+#endif
+
+ channel = pVoiceMgr->voices[voiceNum].channel & 15;
+
+ /* check if sustain pedal is on */
+ if (pSynth->channels[channel].channelFlags & CHANNEL_FLAG_SUSTAIN_PEDAL)
+ {
+ GetSynthPtr(voiceNum)->pfSustainPedal(pVoiceMgr, pSynth, &pVoiceMgr->voices[voiceNum], &pSynth->channels[channel], GetAdjustedVoiceNum(voiceNum));
+ }
+
+ /* release this voice */
+ else
+ VMReleaseVoice(pVoiceMgr, pSynth, voiceNum);
+
+ }
+
+ }
+
+ }
+
+ /* clear the deferred note-off flag, unless there's another one pending */
+ if (deferredNoteOff == EAS_FALSE)
+ pSynth->synthFlags ^= SYNTH_FLAG_DEFERRED_MIDI_NOTE_OFF_PENDING;
+}
+
+/*----------------------------------------------------------------------------
+ * VMReleaseAllDeferredNoteOffs()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Call this functin when the sustain flag is presently set but
+ * we are now transitioning from damper pedal on to
+ * damper pedal off. This means all notes in this channel
+ * that received a note off while the damper pedal was on, and
+ * had their note-off requests deferred, should now proceed to
+ * the release state.
+ *
+ * Inputs:
+ * nChannel - this channel has its sustain pedal transitioning from on to off
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ * Side Effects:
+ * any voice with deferred note offs on this channel are updated such that
+ * pVoice->m_sEG1.m_eState = eEnvelopeStateRelease
+ * pVoice->m_sEG1.m_nIncrement = release increment
+ * pVoice->m_nFlags = clear the deferred note off flag
+ *----------------------------------------------------------------------------
+*/
+void VMReleaseAllDeferredNoteOffs (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel)
+{
+ S_SYNTH_VOICE *pVoice;
+ EAS_INT voiceNum;
+
+#ifdef _DEBUG_VM
+ if (channel >= NUM_SYNTH_CHANNELS)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMReleaseAllDeferredNoteOffs: error, %d invalid channel number\n",
+ channel); */ }
+ return;
+ }
+#endif /* #ifdef _DEBUG_VM */
+
+ /* increment workload */
+ pVoiceMgr->workload += WORKLOAD_AMOUNT_SMALL_INCREMENT;
+
+ /* find all the voices assigned to this channel */
+ channel = VSynthToChannel(pSynth, channel);
+ for (voiceNum = 0; voiceNum < MAX_SYNTH_VOICES; voiceNum++)
+ {
+
+ pVoice = &pVoiceMgr->voices[voiceNum];
+ if (channel == pVoice->channel)
+ {
+
+ /* does this voice have a deferred note off? */
+ if (pVoice->voiceFlags & VOICE_FLAG_SUSTAIN_PEDAL_DEFER_NOTE_OFF)
+ {
+ /* release voice */
+ VMReleaseVoice(pVoiceMgr, pSynth, voiceNum);
+
+ /* use exor to flip bit, clear the flag */
+ pVoice->voiceFlags &= ~VOICE_FLAG_SUSTAIN_PEDAL_DEFER_NOTE_OFF;
+
+ }
+
+ }
+ }
+
+ return;
+}
+
+/*----------------------------------------------------------------------------
+ * VMCatchNotesForSustainPedal()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Call this function when the sustain flag is presently clear and
+ * the damper pedal is off and we are transitioning from damper pedal OFF to
+ * damper pedal ON. Currently sounding notes should be left
+ * unchanged. However, we should try to "catch" notes if possible.
+ * If any notes are in release and have levels >= sustain level, catch them,
+ * otherwise, let them continue to release.
+ *
+ * Inputs:
+ * nChannel - this channel has its sustain pedal transitioning from on to off
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ *----------------------------------------------------------------------------
+*/
+void VMCatchNotesForSustainPedal (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel)
+{
+ EAS_INT voiceNum;
+
+#ifdef _DEBUG_VM
+ if (channel >= NUM_SYNTH_CHANNELS)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMCatchNotesForSustainPedal: error, %d invalid channel number\n",
+ channel); */ }
+ return;
+ }
+#endif
+
+ pVoiceMgr->workload += WORKLOAD_AMOUNT_SMALL_INCREMENT;
+ channel = VSynthToChannel(pSynth, channel);
+
+ /* find all the voices assigned to this channel */
+ for (voiceNum = 0; voiceNum < MAX_SYNTH_VOICES; voiceNum++)
+ {
+ if (channel == pVoiceMgr->voices[voiceNum].channel)
+ {
+ if (eVoiceStateRelease == pVoiceMgr->voices[voiceNum].voiceState)
+ GetSynthPtr(voiceNum)->pfSustainPedal(pVoiceMgr, pSynth, &pVoiceMgr->voices[voiceNum], &pSynth->channels[channel], GetAdjustedVoiceNum(voiceNum));
+ }
+ }
+}
+
+/*----------------------------------------------------------------------------
+ * VMUpdateAllNotesAge()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Increment the note age for all of the active voices.
+ *
+ * Inputs:
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ * m_nAge for all voices is incremented
+ *----------------------------------------------------------------------------
+*/
+void VMUpdateAllNotesAge (S_VOICE_MGR *pVoiceMgr, EAS_U16 age)
+{
+ EAS_INT i;
+
+ for (i = 0; i < MAX_SYNTH_VOICES; i++)
+ {
+ if (age - pVoiceMgr->voices[i].age > 0)
+ pVoiceMgr->voices[i].age++;
+ }
+}
+
+/*----------------------------------------------------------------------------
+ * VMStolenVoice()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * The selected voice is being stolen. Sets the parameters so that the
+ * voice will begin playing the new sound on the next buffer.
+ *
+ * Inputs:
+ * pVoice - pointer to voice to steal
+ * nChannel - the channel to start a note on
+ * nKeyNumber - the key number to start a note for
+ * nNoteVelocity - the key velocity from this note
+ *
+ * Outputs:
+ * None
+ *----------------------------------------------------------------------------
+*/
+static void VMStolenVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_I32 voiceNum, EAS_U8 channel, EAS_U8 note, EAS_U8 velocity, EAS_U16 regionIndex)
+{
+ S_SYNTH_VOICE *pVoice = &pVoiceMgr->voices[voiceNum];
+
+ /* one less voice in old pool */
+ DecVoicePoolCount(pVoiceMgr, pVoice);
+
+ /* mute the sound that is currently playing */
+ GetSynthPtr(voiceNum)->pfMuteVoice(pVoiceMgr, pVoiceMgr->pSynth[GET_VSYNTH(pVoice->channel)], &pVoiceMgr->voices[voiceNum], GetAdjustedVoiceNum(voiceNum));
+ pVoice->voiceState = eVoiceStateStolen;
+
+ /* set new note data */
+ pVoice->nextChannel = VSynthToChannel(pSynth, channel);
+ pVoice->nextNote = note;
+ pVoice->nextVelocity = velocity;
+ pVoice->nextRegionIndex = regionIndex;
+
+ /* one more voice in new pool */
+ IncVoicePoolCount(pVoiceMgr, pVoice);
+
+ /* clear the deferred flags */
+ pVoice->voiceFlags &=
+ ~(VOICE_FLAG_DEFER_MIDI_NOTE_OFF |
+ VOICE_FLAG_DEFER_MUTE |
+ VOICE_FLAG_SUSTAIN_PEDAL_DEFER_NOTE_OFF);
+
+ /* all notes older than this one get "younger" */
+ VMUpdateAllNotesAge(pVoiceMgr, pVoice->age);
+
+ /* assign current age to this note and increment for the next note */
+ pVoice->age = pVoiceMgr->age++;
+}
+
+/*----------------------------------------------------------------------------
+ * VMFreeVoice()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * The selected voice is done playing and being returned to the
+ * pool of free voices
+ *
+ * Inputs:
+ * pVoice - pointer to voice to free
+ *
+ * Outputs:
+ * None
+ *----------------------------------------------------------------------------
+*/
+static void VMFreeVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice)
+{
+
+ /* do nothing if voice is already free */
+ if (pVoice->voiceState == eVoiceStateFree)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "VMFreeVoice: Attempt to free voice that is already free\n"); */ }
+ return;
+ }
+
+ /* if we jump directly to free without passing muting stage,
+ * we need to adjust the voice count */
+ DecVoicePoolCount(pVoiceMgr, pVoice);
+
+
+#ifdef _DEBUG_VM
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "VMFreeVoice: Synth=%d\n", pSynth->vSynthNum); */ }
+#endif
+
+ /* return to free voice pool */
+ pVoiceMgr->activeVoices--;
+ pSynth->numActiveVoices--;
+ InitVoice(pVoice);
+
+#ifdef _DEBUG_VM
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMFreeVoice: free voice %d\n", pVoice - pVoiceMgr->voices); */ }
+#endif
+
+ /* all notes older than this one get "younger" */
+ VMUpdateAllNotesAge(pVoiceMgr, pVoice->age);
+ }
+
+/*----------------------------------------------------------------------------
+ * VMRetargetStolenVoice()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * The selected voice has been stolen and needs to be initalized with
+ * the paramters of its new note.
+ *
+ * Inputs:
+ * pVoice - pointer to voice to retarget
+ *
+ * Outputs:
+ * None
+ *----------------------------------------------------------------------------
+*/
+static EAS_BOOL VMRetargetStolenVoice (S_VOICE_MGR *pVoiceMgr, EAS_I32 voiceNum)
+{
+ EAS_U8 flags;
+ S_SYNTH_CHANNEL *pMIDIChannel;
+ S_SYNTH_VOICE *pVoice;
+ S_SYNTH *pSynth;
+ S_SYNTH *pNextSynth;
+
+ /* establish some pointers */
+ pVoice = &pVoiceMgr->voices[voiceNum];
+ pSynth = pVoiceMgr->pSynth[GET_VSYNTH(pVoice->channel)];
+ pMIDIChannel = &pSynth->channels[pVoice->channel & 15];
+ pNextSynth = pVoiceMgr->pSynth[GET_VSYNTH(pVoice->nextChannel)];
+
+#ifdef _DEBUG_VM
+{ /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMRetargetStolenVoice: retargeting stolen voice %d on channel %d\n",
+ voiceNum, pVoice->channel); */ }
+
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "\to channel %d note: %d velocity: %d\n",
+ pVoice->nextChannel, pVoice->nextNote, pVoice->nextVelocity); */ }
+#endif
+
+ /* make sure new channel hasn't been muted by SP-MIDI since the voice was stolen */
+ if ((pSynth->synthFlags & SYNTH_FLAG_SP_MIDI_ON) &&
+ (pMIDIChannel->channelFlags & CHANNEL_FLAG_MUTE))
+ {
+ VMFreeVoice(pVoiceMgr, pSynth, &pVoiceMgr->voices[voiceNum]);
+ return EAS_FALSE;
+ }
+
+ /* if assigned to a new synth, correct the active voice count */
+ if (pVoice->channel != pVoice->nextChannel)
+ {
+#ifdef _DEBUG_VM
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMRetargetStolenVoice: Note assigned to different virtual synth, adjusting numActiveVoices\n"); */ }
+#endif
+ pSynth->numActiveVoices--;
+ pNextSynth->numActiveVoices++;
+ }
+
+ /* assign new channel number, and increase channel voice count */
+ pVoice->channel = pVoice->nextChannel;
+ pMIDIChannel = &pNextSynth->channels[pVoice->channel & 15];
+
+ /* assign other data */
+ pVoice->note = pVoice->nextNote;
+ pVoice->velocity = pVoice->nextVelocity;
+ pVoice->nextChannel = UNASSIGNED_SYNTH_CHANNEL;
+ pVoice->regionIndex = pVoice->nextRegionIndex;
+
+ /* save the flags, pfStartVoice() will clear them */
+ flags = pVoice->voiceFlags;
+
+ /* keep track of the note-start related workload */
+ pVoiceMgr->workload += WORKLOAD_AMOUNT_START_NOTE;
+
+ /* setup the voice parameters */
+ pVoice->voiceState = eVoiceStateStart;
+
+ /*lint -e{522} return not used at this time */
+ GetSynthPtr(voiceNum)->pfStartVoice(pVoiceMgr, pNextSynth, &pVoiceMgr->voices[voiceNum], GetAdjustedVoiceNum(voiceNum), pVoice->regionIndex);
+
+ /* did the new note already receive a MIDI note-off request? */
+ if (flags & VOICE_FLAG_DEFER_MIDI_NOTE_OFF)
+ {
+#ifdef _DEBUG_VM
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMRetargetVoice: stolen note note-off request deferred\n"); */ }
+#endif
+ pVoice->voiceFlags |= VOICE_FLAG_DEFER_MIDI_NOTE_OFF;
+ pNextSynth->synthFlags |= SYNTH_FLAG_DEFERRED_MIDI_NOTE_OFF_PENDING;
+ }
+
+ return EAS_TRUE;
+}
+
+/*----------------------------------------------------------------------------
+ * VMCheckKeyGroup()
+ *----------------------------------------------------------------------------
+ * If the note that we've been asked to start is in the same key group as
+ * any currently playing notes, then we must shut down the currently playing
+ * note in the same key group
+ *----------------------------------------------------------------------------
+*/
+void VMCheckKeyGroup (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U16 keyGroup, EAS_U8 channel)
+{
+ const S_REGION *pRegion;
+ EAS_INT voiceNum;
+
+ /* increment frame workload */
+ pVoiceMgr->workload += WORKLOAD_AMOUNT_KEY_GROUP;
+
+ /* need to check all voices in case this is a layered sound */
+ channel = VSynthToChannel(pSynth, channel);
+ for (voiceNum = 0; voiceNum < MAX_SYNTH_VOICES; voiceNum++)
+ {
+ if (pVoiceMgr->voices[voiceNum].voiceState != eVoiceStateStolen)
+ {
+ /* voice must be on the same channel */
+ if (channel == pVoiceMgr->voices[voiceNum].channel)
+ {
+ /* check key group */
+ pRegion = GetRegionPtr(pSynth, pVoiceMgr->voices[voiceNum].regionIndex);
+ if (keyGroup == (pRegion->keyGroupAndFlags & 0x0f00))
+ {
+#ifdef _DEBUG_VM
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMCheckKeyGroup: voice %d matches key group %d\n", voiceNum, keyGroup >> 8); */ }
+#endif
+
+ /* if this voice was just started, set it to mute on the next buffer */
+ if (pVoiceMgr->voices[voiceNum].voiceFlags & VOICE_FLAG_NO_SAMPLES_SYNTHESIZED_YET)
+ pVoiceMgr->voices[voiceNum].voiceFlags |= VOICE_FLAG_DEFER_MUTE;
+
+ /* mute immediately */
+ else
+ VMMuteVoice(pVoiceMgr, voiceNum);
+ }
+ }
+ }
+
+ /* for stolen voice, check new values */
+ else
+ {
+ /* voice must be on the same channel */
+ if (channel == pVoiceMgr->voices[voiceNum].nextChannel)
+ {
+ /* check key group */
+ pRegion = GetRegionPtr(pSynth, pVoiceMgr->voices[voiceNum].nextRegionIndex);
+ if (keyGroup == (pRegion->keyGroupAndFlags & 0x0f00))
+ {
+#ifdef _DEBUG_VM
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMCheckKeyGroup: voice %d matches key group %d\n", voiceNum, keyGroup >> 8); */ }
+#endif
+
+ /* if this voice was just started, set it to mute on the next buffer */
+ if (pVoiceMgr->voices[voiceNum].voiceFlags & VOICE_FLAG_NO_SAMPLES_SYNTHESIZED_YET)
+ pVoiceMgr->voices[voiceNum].voiceFlags |= VOICE_FLAG_DEFER_MUTE;
+
+ /* mute immediately */
+ else
+ VMMuteVoice(pVoiceMgr, voiceNum);
+ }
+ }
+
+ }
+ }
+}
+
+/*----------------------------------------------------------------------------
+ * VMCheckPolyphonyLimiting()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * We only play at most 2 of the same note on a MIDI channel.
+ * E.g., if we are asked to start note 36, and there are already two voices
+ * that are playing note 36, then we must steal the voice playing
+ * the oldest note 36 and use that stolen voice to play the new note 36.
+ *
+ * Inputs:
+ * nChannel - synth channel that wants to start a new note
+ * nKeyNumber - new note's midi note number
+ * nNoteVelocity - new note's velocity
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ * pbVoiceStealingRequired - flag: this routine sets true if we needed to
+ * steal a voice
+ * *
+ * Side Effects:
+ * psSynthObject->m_sVoice[free voice num].m_nKeyNumber may be assigned
+ * psSynthObject->m_sVoice[free voice num].m_nVelocity may be assigned
+ *----------------------------------------------------------------------------
+*/
+EAS_BOOL VMCheckPolyphonyLimiting (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel, EAS_U8 note, EAS_U8 velocity, EAS_U16 regionIndex, EAS_I32 lowVoice, EAS_I32 highVoice)
+{
+ EAS_INT voiceNum;
+ EAS_INT oldestVoiceNum;
+ EAS_INT numVoicesPlayingNote;
+ EAS_U16 age;
+ EAS_U16 oldestNoteAge;
+
+ pVoiceMgr->workload += WORKLOAD_AMOUNT_POLY_LIMIT;
+
+ numVoicesPlayingNote = 0;
+ oldestVoiceNum = MAX_SYNTH_VOICES;
+ oldestNoteAge = 0;
+ channel = VSynthToChannel(pSynth, channel);
+
+ /* examine each voice on this channel playing this note */
+ for (voiceNum = lowVoice; voiceNum <= highVoice; voiceNum++)
+ {
+ /* check stolen notes separately */
+ if (pVoiceMgr->voices[voiceNum].voiceState != eVoiceStateStolen)
+ {
+
+ /* same channel and note ? */
+ if ((channel == pVoiceMgr->voices[voiceNum].channel) && (note == pVoiceMgr->voices[voiceNum].note))
+ {
+ numVoicesPlayingNote++;
+ age = pVoiceMgr->age - pVoiceMgr->voices[voiceNum].age;
+
+ /* is this the oldest voice for this note? */
+ if (age >= oldestNoteAge)
+ {
+ oldestNoteAge = age;
+ oldestVoiceNum = voiceNum;
+ }
+ }
+ }
+
+ /* handle stolen voices */
+ else
+ {
+ /* same channel and note ? */
+ if ((channel == pVoiceMgr->voices[voiceNum].nextChannel) && (note == pVoiceMgr->voices[voiceNum].nextNote))
+ {
+ numVoicesPlayingNote++;
+ }
+ }
+ }
+
+ /* check to see if we exceeded poly limit */
+ if (numVoicesPlayingNote < DEFAULT_CHANNEL_POLYPHONY_LIMIT)
+ return EAS_FALSE;
+
+ /* make sure we have a voice to steal */
+ if (oldestVoiceNum != MAX_SYNTH_VOICES)
+ {
+#ifdef _DEBUG_VM
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMCheckPolyphonyLimiting: voice %d has the oldest note\n", oldestVoiceNum); */ }
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "VMCheckPolyphonyLimiting: polyphony limiting requires shutting down note %d \n", pVoiceMgr->voices[oldestVoiceNum].note); */ }
+#endif
+ VMStolenVoice(pVoiceMgr, pSynth, oldestVoiceNum, channel, note, velocity, regionIndex);
+ return EAS_TRUE;
+ }
+
+#ifdef _DEBUG_VM
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "VMCheckPolyphonyLimiting: No oldest voice to steal\n"); */ }
+#endif
+ return EAS_FALSE;
+}
+
+/*----------------------------------------------------------------------------
+ * VMStartVoice()
+ *----------------------------------------------------------------------------
+ * Starts a voice given a region index
+ *----------------------------------------------------------------------------
+*/
+void VMStartVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel, EAS_U8 note, EAS_U8 velocity, EAS_U16 regionIndex)
+{
+ const S_REGION *pRegion;
+ S_SYNTH_CHANNEL *pChannel;
+ EAS_INT voiceNum;
+ EAS_INT maxSynthPoly;
+ EAS_I32 lowVoice, highVoice;
+ EAS_U16 keyGroup;
+
+ pChannel = &pSynth->channels[channel];
+ pRegion = GetRegionPtr(pSynth, regionIndex);
+
+ /* select correct synth */
+#if defined(_SECONDARY_SYNTH) || defined(EAS_SPLIT_WT_SYNTH)
+ {
+#ifdef EAS_SPLIT_WT_SYNTH
+ if ((pRegion->keyGroupAndFlags & REGION_FLAG_OFF_CHIP) == 0)
+#else
+ if ((regionIndex & FLAG_RGN_IDX_FM_SYNTH) == 0)
+#endif
+ {
+ lowVoice = 0;
+ highVoice = NUM_PRIMARY_VOICES - 1;
+ }
+ else
+ {
+ lowVoice = NUM_PRIMARY_VOICES;
+ highVoice = MAX_SYNTH_VOICES - 1;
+ }
+ }
+#else
+ lowVoice = 0;
+ highVoice = MAX_SYNTH_VOICES - 1;
+#endif
+
+ /* keep track of the note-start related workload */
+ pVoiceMgr->workload+= WORKLOAD_AMOUNT_START_NOTE;
+
+ /* other voices in pool, check for key group and poly limiting */
+ if (pSynth->poolCount[pChannel->pool] != 0)
+ {
+
+ /* check for key group exclusivity */
+ keyGroup = pRegion->keyGroupAndFlags & 0x0f00;
+ if (keyGroup!= 0)
+ VMCheckKeyGroup(pVoiceMgr, pSynth, keyGroup, channel);
+
+ /* check polyphony limit and steal a voice if necessary */
+ if ((pRegion->keyGroupAndFlags & REGION_FLAG_NON_SELF_EXCLUSIVE) == 0)
+ {
+ if (VMCheckPolyphonyLimiting(pVoiceMgr, pSynth, channel, note, velocity, regionIndex, lowVoice, highVoice) == EAS_TRUE)
+ return;
+ }
+ }
+
+ /* check max poly allocation */
+ if ((pSynth->maxPolyphony == 0) || (pVoiceMgr->maxPolyphony < pSynth->maxPolyphony))
+ maxSynthPoly = pVoiceMgr->maxPolyphony;
+ else
+ maxSynthPoly = pSynth->maxPolyphony;
+
+ /* any free voices? */
+ if ((pVoiceMgr->activeVoices < pVoiceMgr->maxPolyphony) &&
+ (pSynth->numActiveVoices < maxSynthPoly) &&
+ (EAS_SUCCESS == VMFindAvailableVoice(pVoiceMgr, &voiceNum, lowVoice, highVoice)))
+ {
+ S_SYNTH_VOICE *pVoice = &pVoiceMgr->voices[voiceNum];
+
+#ifdef _DEBUG_VM
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "VMStartVoice: Synth=%d\n", pSynth->vSynthNum); */ }
+#endif
+
+ /* bump voice counts */
+ pVoiceMgr->activeVoices++;
+ pSynth->numActiveVoices++;
+
+#ifdef _DEBUG_VM
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMStartVoice: voice %d assigned to channel %d note %d velocity %d\n",
+ voiceNum, channel, note, velocity); */ }
+#endif
+
+ /* save parameters */
+ pVoiceMgr->voices[voiceNum].channel = VSynthToChannel(pSynth, channel);
+ pVoiceMgr->voices[voiceNum].note = note;
+ pVoiceMgr->voices[voiceNum].velocity = velocity;
+
+ /* establish note age for voice stealing */
+ pVoiceMgr->voices[voiceNum].age = pVoiceMgr->age++;
+
+ /* setup the synthesis parameters */
+ pVoiceMgr->voices[voiceNum].voiceState = eVoiceStateStart;
+
+ /* increment voice pool count */
+ IncVoicePoolCount(pVoiceMgr, pVoice);
+
+ /* start voice on correct synth */
+ /*lint -e{522} return not used at this time */
+ GetSynthPtr(voiceNum)->pfStartVoice(pVoiceMgr, pSynth, &pVoiceMgr->voices[voiceNum], GetAdjustedVoiceNum(voiceNum), regionIndex);
+ return;
+ }
+
+ /* no free voices, we have to steal one using appropriate algorithm */
+ if (VMStealVoice(pVoiceMgr, pSynth, &voiceNum, channel, note, lowVoice, highVoice) == EAS_SUCCESS)
+ VMStolenVoice(pVoiceMgr, pSynth, voiceNum, channel, note, velocity, regionIndex);
+
+#ifdef _DEBUG_VM
+ else
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMStartVoice: Could not steal a voice for channel %d note %d velocity %d\n",
+ channel, note, velocity); */ }
+ }
+#endif
+
+ return;
+}
+
+/*----------------------------------------------------------------------------
+ * VMStartNote()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Update the synth's state to play the requested note on the requested
+ * channel if possible.
+ *
+ * Inputs:
+ * nChannel - the channel to start a note on
+ * nKeyNumber - the key number to start a note for
+ * nNoteVelocity - the key velocity from this note
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ * Side Effects:
+ * psSynthObject->m_nNumActiveVoices may be incremented
+ * psSynthObject->m_sVoice[free voice num].m_nSynthChannel may be assigned
+ * psSynthObject->m_sVoice[free voice num].m_nKeyNumber is assigned
+ * psSynthObject->m_sVoice[free voice num].m_nVelocity is assigned
+ *----------------------------------------------------------------------------
+*/
+void VMStartNote (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel, EAS_U8 note, EAS_U8 velocity)
+{
+ S_SYNTH_CHANNEL *pChannel;
+ EAS_U16 regionIndex;
+ EAS_I16 adjustedNote;
+
+ /* bump note count */
+ pSynth->totalNoteCount++;
+
+ pChannel = &pSynth->channels[channel];
+
+ /* check channel mute */
+ if (pChannel->channelFlags & CHANNEL_FLAG_MUTE)
+ return;
+
+#ifdef EXTERNAL_AUDIO
+ /* pass event to external audio when requested */
+ if ((pChannel->channelFlags & CHANNEL_FLAG_EXTERNAL_AUDIO) && (pSynth->cbEventFunc != NULL))
+ {
+ S_EXT_AUDIO_EVENT event;
+ event.channel = channel;
+ event.note = note;
+ event.velocity = velocity;
+ event.noteOn = EAS_TRUE;
+ if (pSynth->cbEventFunc(pSynth->pExtAudioInstData, &event))
+ return;
+ }
+#endif
+
+ /* start search at first region */
+ regionIndex = pChannel->regionIndex;
+
+ /* handle transposition */
+ adjustedNote = note;
+ if (pChannel->channelFlags & CHANNEL_FLAG_RHYTHM_CHANNEL)
+ adjustedNote += pChannel->coarsePitch;
+ else
+ adjustedNote += pChannel->coarsePitch + pSynth->globalTranspose;
+
+ /* limit adjusted key number so it does not wraparound, over/underflow */
+ if (adjustedNote < 0)
+ {
+ adjustedNote = 0;
+ }
+ else if (adjustedNote > 127)
+ {
+ adjustedNote = 127;
+ }
+
+#if defined(DLS_SYNTHESIZER)
+ if (regionIndex & FLAG_RGN_IDX_DLS_SYNTH)
+ {
+ /* DLS voice */
+ for (;;)
+ {
+ /*lint -e{740,826} cast OK, we know this is actually a DLS region */
+ const S_DLS_REGION *pDLSRegion = (S_DLS_REGION*) GetRegionPtr(pSynth, regionIndex);
+
+ /* check key against this region's key and velocity range */
+ if (((adjustedNote >= pDLSRegion->wtRegion.region.rangeLow) && (adjustedNote <= pDLSRegion->wtRegion.region.rangeHigh)) &&
+ ((velocity >= pDLSRegion->velLow) && (velocity <= pDLSRegion->velHigh)))
+ {
+ VMStartVoice(pVoiceMgr, pSynth, channel, note, velocity, regionIndex);
+ }
+
+ /* last region in program? */
+ if (pDLSRegion->wtRegion.region.keyGroupAndFlags & REGION_FLAG_LAST_REGION)
+ break;
+
+ /* advance to next region */
+ regionIndex++;
+ }
+ }
+ else
+#endif
+
+ /* braces here for #if clause */
+ {
+ /* EAS voice */
+ for (;;)
+ {
+ const S_REGION *pRegion = GetRegionPtr(pSynth, regionIndex);
+
+ /* check key against this region's keyrange */
+ if ((adjustedNote >= pRegion->rangeLow) && (adjustedNote <= pRegion->rangeHigh))
+ {
+ VMStartVoice(pVoiceMgr, pSynth, channel, note, velocity, regionIndex);
+ break;
+ }
+
+ /* last region in program? */
+ if (pRegion->keyGroupAndFlags & REGION_FLAG_LAST_REGION)
+ break;
+
+ /* advance to next region */
+ regionIndex++;
+ }
+ }
+}
+
+/*----------------------------------------------------------------------------
+ * VMStopNote()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Update the synth's state to end the requested note on the requested
+ * channel.
+ *
+ * Inputs:
+ * nChannel - the channel to stop a note on
+ * nKeyNumber - the key number for this note off
+ * nNoteVelocity - the note-off velocity
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ * Side Effects:
+ * psSynthObject->m_sVoice[free voice num].m_nSynthChannel may be assigned
+ * psSynthObject->m_sVoice[free voice num].m_nKeyNumber is assigned
+ * psSynthObject->m_sVoice[free voice num].m_nVelocity is assigned
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, velocity) reserved for future use */
+void VMStopNote (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel, EAS_U8 note, EAS_U8 velocity)
+{
+ S_SYNTH_CHANNEL *pChannel;
+ EAS_INT voiceNum;
+
+ pChannel = &(pSynth->channels[channel]);
+
+#ifdef EXTERNAL_AUDIO
+ if ((pChannel->channelFlags & CHANNEL_FLAG_EXTERNAL_AUDIO) && (pSynth->cbEventFunc != NULL))
+ {
+ S_EXT_AUDIO_EVENT event;
+ event.channel = channel;
+ event.note = note;
+ event.velocity = velocity;
+ event.noteOn = EAS_FALSE;
+ if (pSynth->cbEventFunc(pSynth->pExtAudioInstData, &event))
+ return;
+ }
+#endif
+
+ /* keep track of the note-start workload */
+ pVoiceMgr->workload += WORKLOAD_AMOUNT_STOP_NOTE;
+
+ channel = VSynthToChannel(pSynth, channel);
+
+ for (voiceNum=0; voiceNum < MAX_SYNTH_VOICES; voiceNum++)
+ {
+
+ /* stolen notes are handled separately */
+ if (eVoiceStateStolen != pVoiceMgr->voices[voiceNum].voiceState)
+ {
+
+ /* channel and key number must match */
+ if ((channel == pVoiceMgr->voices[voiceNum].channel) && (note == pVoiceMgr->voices[voiceNum].note))
+ {
+#ifdef _DEBUG_VM
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMStopNote: voice %d channel %d note %d\n",
+ voiceNum, channel, note); */ }
+#endif
+
+ /* if sustain pedal is down, set deferred note-off flag */
+ if (pChannel->channelFlags & CHANNEL_FLAG_SUSTAIN_PEDAL)
+ {
+ pVoiceMgr->voices[voiceNum].voiceFlags |= VOICE_FLAG_SUSTAIN_PEDAL_DEFER_NOTE_OFF;
+ continue;
+ }
+
+ /* if this note just started, wait before we stop it */
+ if (pVoiceMgr->voices[voiceNum].voiceFlags & VOICE_FLAG_NO_SAMPLES_SYNTHESIZED_YET)
+ {
+#ifdef _DEBUG_VM
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "\tDeferred: Not started yet\n"); */ }
+#endif
+ pVoiceMgr->voices[voiceNum].voiceFlags |= VOICE_FLAG_DEFER_MIDI_NOTE_OFF;
+ pSynth->synthFlags |= SYNTH_FLAG_DEFERRED_MIDI_NOTE_OFF_PENDING;
+ }
+
+ /* release voice */
+ else
+ VMReleaseVoice(pVoiceMgr, pSynth, voiceNum);
+
+ }
+ }
+
+ /* process stolen notes, new channel and key number must match */
+ else if ((channel == pVoiceMgr->voices[voiceNum].nextChannel) && (note == pVoiceMgr->voices[voiceNum].nextNote))
+ {
+
+#ifdef _DEBUG_VM
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMStopNote: voice %d channel %d note %d\n\tDeferred: Stolen voice\n",
+ voiceNum, channel, note); */ }
+#endif
+ pVoiceMgr->voices[voiceNum].voiceFlags |= VOICE_FLAG_DEFER_MIDI_NOTE_OFF;
+ }
+ }
+}
+
+/*----------------------------------------------------------------------------
+ * VMFindAvailableVoice()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Find an available voice and return the voice number if available.
+ *
+ * Inputs:
+ * pnVoiceNumber - really an output, returns the voice number found
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ * success - if there is an available voice
+ * failure - otherwise
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT VMFindAvailableVoice (S_VOICE_MGR *pVoiceMgr, EAS_INT *pVoiceNumber, EAS_I32 lowVoice, EAS_I32 highVoice)
+{
+ EAS_INT voiceNum;
+
+ /* Check each voice to see if it has been assigned to a synth channel */
+ for (voiceNum = lowVoice; voiceNum <= highVoice; voiceNum++)
+ {
+ /* check if this voice has been assigned to a synth channel */
+ if ( pVoiceMgr->voices[voiceNum].voiceState == eVoiceStateFree)
+ {
+ *pVoiceNumber = voiceNum; /* this voice is available */
+ return EAS_SUCCESS;
+ }
+ }
+
+ /* if we reach here, we have not found a free voice */
+ *pVoiceNumber = UNASSIGNED_SYNTH_VOICE;
+
+#ifdef _DEBUG_VM
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMFindAvailableVoice: error, could not find an available voice\n"); */ }
+#endif
+ return EAS_FAILURE;
+}
+
+/*----------------------------------------------------------------------------
+ * VMStealVoice()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Steal a voice and return the voice number
+ *
+ * Stealing algorithm: steal the best choice with minimal work, taking into
+ * account SP-Midi channel priorities and polyphony allocation.
+ *
+ * In one pass through all the voices, figure out which voice to steal
+ * taking into account a number of different factors:
+ * Priority of the voice's MIDI channel
+ * Number of voices over the polyphony allocation for voice's MIDI channel
+ * Amplitude of the voice
+ * Note age
+ * Key velocity (for voices that haven't been started yet)
+ * If any matching notes are found
+ *
+ * Inputs:
+ * pnVoiceNumber - really an output, see below
+ * nChannel - the channel that this voice wants to be started on
+ * nKeyNumber - the key number for this new voice
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ * pnVoiceNumber - voice number of the voice that was stolen
+ * EAS_RESULT EAS_SUCCESS - always successful
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT VMStealVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_INT *pVoiceNumber, EAS_U8 channel, EAS_U8 note, EAS_I32 lowVoice, EAS_I32 highVoice)
+{
+ S_SYNTH_VOICE *pCurrVoice;
+ S_SYNTH *pCurrSynth;
+ EAS_INT voiceNum;
+ EAS_INT bestCandidate;
+ EAS_U8 currChannel;
+ EAS_U8 currNote;
+ EAS_I32 bestPriority;
+ EAS_I32 currentPriority;
+
+ /* determine which voice to steal */
+ bestPriority = 0;
+ bestCandidate = MAX_SYNTH_VOICES;
+
+ for (voiceNum = lowVoice; voiceNum <= highVoice; voiceNum++)
+ {
+ pCurrVoice = &pVoiceMgr->voices[voiceNum];
+
+ /* ignore free voices */
+ if (pCurrVoice->voiceState == eVoiceStateFree)
+ continue;
+
+ /* for stolen voices, use the new parameters, not the old */
+ if (pCurrVoice->voiceState == eVoiceStateStolen)
+ {
+ pCurrSynth = pVoiceMgr->pSynth[GET_VSYNTH(pCurrVoice->nextChannel)];
+ currChannel = pCurrVoice->nextChannel;
+ currNote = pCurrVoice->nextNote;
+ }
+ else
+ {
+ pCurrSynth = pVoiceMgr->pSynth[GET_VSYNTH(pCurrVoice->channel)];
+ currChannel = pCurrVoice->channel;
+ currNote = pCurrVoice->note;
+ }
+
+ /* ignore voices that are higher priority */
+ if (pSynth->priority > pCurrSynth->priority)
+ continue;
+#ifdef _DEBUG_VM
+// { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMStealVoice: New priority = %d exceeds old priority = %d\n", pSynth->priority, pCurrSynth->priority); */ }
+#endif
+
+ /* if voice is stolen or just started, reduce the likelihood it will be stolen */
+ if (( pCurrVoice->voiceState == eVoiceStateStolen) || (pCurrVoice->voiceFlags & VOICE_FLAG_NO_SAMPLES_SYNTHESIZED_YET))
+ {
+ currentPriority = 128 - pCurrVoice->nextVelocity;
+ }
+ else
+ {
+ /* compute the priority of this voice, higher means better for stealing */
+ /* use not age */
+ currentPriority = (EAS_I32) pCurrVoice->age << NOTE_AGE_STEAL_WEIGHT;
+
+ /* include note gain -higher gain is lower steal value */
+ /*lint -e{704} use shift for performance */
+ currentPriority += ((32768 >> (12 - NOTE_GAIN_STEAL_WEIGHT)) + 256) -
+ ((EAS_I32) pCurrVoice->gain >> (12 - NOTE_GAIN_STEAL_WEIGHT));
+ }
+
+ /* in SP-MIDI mode, include over poly allocation and channel priority */
+ if (pSynth->synthFlags & SYNTH_FLAG_SP_MIDI_ON)
+ {
+ S_SYNTH_CHANNEL *pChannel = &pCurrSynth->channels[GET_CHANNEL(currChannel)];
+ /*lint -e{701} use shift for performance */
+ if (pSynth->poolCount[pChannel->pool] >= pSynth->poolAlloc[pChannel->pool])
+ currentPriority += (pSynth->poolCount[pChannel->pool] -pSynth->poolAlloc[pChannel->pool] + 1) << CHANNEL_POLY_STEAL_WEIGHT;
+
+ /* include channel priority */
+ currentPriority += (EAS_I32)(pChannel->pool << CHANNEL_PRIORITY_STEAL_WEIGHT);
+ }
+
+ /* if a note is already playing that matches this note, consider stealing it more readily */
+ if ((note == currNote) && (channel == currChannel))
+ currentPriority += NOTE_MATCH_PENALTY;
+
+ /* is this the best choice so far? */
+ if (currentPriority >= bestPriority)
+ {
+ bestPriority = currentPriority;
+ bestCandidate = voiceNum;
+ }
+ }
+
+ /* may happen if all voices are allocated to a higher priority virtual synth */
+ if (bestCandidate == MAX_SYNTH_VOICES)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMStealVoice: Unable to allocate a voice\n"); */ }
+ return EAS_ERROR_NO_VOICE_ALLOCATED;
+ }
+
+#ifdef _DEBUG_VM
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMStealVoice: Voice %d stolen\n", bestCandidate); */ }
+
+ /* are we stealing a stolen voice? */
+ if (pVoiceMgr->voices[bestCandidate].voiceState == eVoiceStateStolen)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "VMStealVoice: Voice %d is already marked as stolen and was scheduled to play ch: %d note: %d vel: %d\n",
+ bestCandidate,
+ pVoiceMgr->voices[bestCandidate].nextChannel,
+ pVoiceMgr->voices[bestCandidate].nextNote,
+ pVoiceMgr->voices[bestCandidate].nextVelocity); */ }
+ }
+#endif
+
+ *pVoiceNumber = (EAS_U16) bestCandidate;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * VMChannelPressure()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Change the channel pressure for the given channel
+ *
+ * Inputs:
+ * nChannel - the MIDI channel
+ * nVelocity - the channel pressure value
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ * Side Effects:
+ * psSynthObject->m_sChannel[nChannel].m_nChannelPressure is updated
+ *----------------------------------------------------------------------------
+*/
+void VMChannelPressure (S_SYNTH *pSynth, EAS_U8 channel, EAS_U8 value)
+{
+ S_SYNTH_CHANNEL *pChannel;
+
+ pChannel = &(pSynth->channels[channel]);
+ pChannel->channelPressure = value;
+
+ /*
+ set a channel flag to request parameter updates
+ for all the voices associated with this channel
+ */
+ pChannel->channelFlags |= CHANNEL_FLAG_UPDATE_CHANNEL_PARAMETERS;
+}
+
+/*----------------------------------------------------------------------------
+ * VMPitchBend()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Change the pitch wheel value for the given channel.
+ * This routine constructs the proper 14-bit argument when the calling routine
+ * passes the pitch LSB and MSB.
+ *
+ * Note: some midi disassemblers display a bipolar pitch bend value.
+ * We can display the bipolar value using
+ * if m_nPitchBend >= 0x2000
+ * bipolar pitch bend = postive (m_nPitchBend - 0x2000)
+ * else
+ * bipolar pitch bend = negative (0x2000 - m_nPitchBend)
+ *
+ * Inputs:
+ * nChannel - the MIDI channel
+ * nPitchLSB - the LSB byte of the pitch bend message
+ * nPitchMSB - the MSB byte of the pitch bend message
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ * psSynthObject->m_sChannel[nChannel].m_nPitchBend is changed
+ *
+ *----------------------------------------------------------------------------
+*/
+void VMPitchBend (S_SYNTH *pSynth, EAS_U8 channel, EAS_U8 nPitchLSB, EAS_U8 nPitchMSB)
+{
+ S_SYNTH_CHANNEL *pChannel;
+
+ pChannel = &(pSynth->channels[channel]);
+ pChannel->pitchBend = (EAS_I16) ((nPitchMSB << 7) | nPitchLSB);
+
+ /*
+ set a channel flag to request parameter updates
+ for all the voices associated with this channel
+ */
+ pChannel->channelFlags |= CHANNEL_FLAG_UPDATE_CHANNEL_PARAMETERS;
+}
+
+/*----------------------------------------------------------------------------
+ * VMControlChange()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Change the controller (or mode) for the given channel.
+ *
+ * Inputs:
+ * nChannel - the MIDI channel
+ * nControllerNumber - the MIDI controller number
+ * nControlValue - the value for this controller message
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ * Side Effects:
+ * psSynthObject->m_sChannel[nChannel] controller is changed
+ *
+ *----------------------------------------------------------------------------
+*/
+void VMControlChange (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel, EAS_U8 controller, EAS_U8 value)
+{
+ S_SYNTH_CHANNEL *pChannel;
+
+ pChannel = &(pSynth->channels[channel]);
+
+ /*
+ set a channel flag to request parameter updates
+ for all the voices associated with this channel
+ */
+ pChannel->channelFlags |= CHANNEL_FLAG_UPDATE_CHANNEL_PARAMETERS;
+
+ switch ( controller )
+ {
+ case MIDI_CONTROLLER_BANK_SELECT_MSB:
+#ifdef _DEBUG_VM
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMControlChange: Bank Select MSB: msb 0x%X\n", value); */ }
+#endif
+ /* use this MSB with a zero LSB, until we get an LSB message */
+ pChannel->bankNum = value << 8;
+ break;
+
+ case MIDI_CONTROLLER_MOD_WHEEL:
+ /* we treat mod wheel as a 7-bit controller and only use the MSB */
+ pChannel->modWheel = value;
+ break;
+
+ case MIDI_CONTROLLER_VOLUME:
+ /* we treat volume as a 7-bit controller and only use the MSB */
+ pChannel->volume = value;
+ break;
+
+ case MIDI_CONTROLLER_PAN:
+ /* we treat pan as a 7-bit controller and only use the MSB */
+ pChannel->pan = value;
+ break;
+
+ case MIDI_CONTROLLER_EXPRESSION:
+ /* we treat expression as a 7-bit controller and only use the MSB */
+ pChannel->expression = value;
+ break;
+
+ case MIDI_CONTROLLER_BANK_SELECT_LSB:
+#ifdef _DEBUG_VM
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMControlChange: Bank Select LSB: lsb 0x%X\n", value); */ }
+#endif
+ /*
+ construct bank number as 7-bits (stored as 8) of existing MSB
+ and 7-bits of new LSB (also stored as 8(
+ */
+ pChannel->bankNum =
+ (pChannel->bankNum & 0xFF00) | value;
+
+ break;
+
+ case MIDI_CONTROLLER_SUSTAIN_PEDAL:
+ /* we treat sustain pedal as a boolean on/off bit flag */
+ if (value < 64)
+ {
+ /*
+ we are requested to turn the pedal off, but first check
+ if the pedal is already on
+ */
+ if (0 !=
+ (pChannel->channelFlags & CHANNEL_FLAG_SUSTAIN_PEDAL)
+ )
+ {
+ /*
+ The sustain flag is presently set and the damper pedal is on.
+ We are therefore transitioning from damper pedal ON to
+ damper pedal OFF. This means all notes in this channel
+ that received a note off while the damper pedal was on, and
+ had their note-off requests deferred, should now proceed to
+ the release state.
+ */
+ VMReleaseAllDeferredNoteOffs(pVoiceMgr, pSynth, channel);
+ } /* end if sustain pedal is already on */
+
+ /* turn the sustain pedal off */
+ pChannel->channelFlags &= ~CHANNEL_FLAG_SUSTAIN_PEDAL;
+ }
+ else
+ {
+ /*
+ we are requested to turn the pedal on, but first check
+ if the pedal is already off
+ */
+ if (0 ==
+ (pChannel->channelFlags & CHANNEL_FLAG_SUSTAIN_PEDAL)
+ )
+ {
+ /*
+ The sustain flag is presently clear and the damper pedal is off.
+ We are therefore transitioning from damper pedal OFF to
+ damper pedal ON. Currently sounding notes should be left
+ unchanged. However, we should try to "catch" notes if possible.
+ If any notes have levels >= sustain level, catch them,
+ otherwise, let them continue to release.
+ */
+ VMCatchNotesForSustainPedal(pVoiceMgr, pSynth, channel);
+ }
+
+ /* turn the sustain pedal on */
+ pChannel->channelFlags |= CHANNEL_FLAG_SUSTAIN_PEDAL;
+ }
+
+ break;
+#ifdef _REVERB
+ case MIDI_CONTROLLER_REVERB_SEND:
+ /* we treat send as a 7-bit controller and only use the MSB */
+ pSynth->channels[channel].reverbSend = value;
+ break;
+#endif
+#ifdef _CHORUS
+ case MIDI_CONTROLLER_CHORUS_SEND:
+ /* we treat send as a 7-bit controller and only use the MSB */
+ pSynth->channels[channel].chorusSend = value;
+ break;
+#endif
+ case MIDI_CONTROLLER_RESET_CONTROLLERS:
+ /* despite the Midi message name, not ALL controllers are reset */
+ pChannel->modWheel = DEFAULT_MOD_WHEEL;
+ pChannel->expression = DEFAULT_EXPRESSION;
+
+ /* turn the sustain pedal off as default/reset */
+ pChannel->channelFlags &= ~CHANNEL_FLAG_SUSTAIN_PEDAL;
+ pChannel->pitchBend = DEFAULT_PITCH_BEND;
+
+ /* reset channel pressure */
+ pChannel->channelPressure = DEFAULT_CHANNEL_PRESSURE;
+
+ /* reset RPN values */
+ pChannel->registeredParam = DEFAULT_REGISTERED_PARAM;
+ pChannel->pitchBendSensitivity = DEFAULT_PITCH_BEND_SENSITIVITY;
+ pChannel->finePitch = DEFAULT_FINE_PITCH;
+ pChannel->coarsePitch = DEFAULT_COARSE_PITCH;
+
+ /*
+ program change, bank select, channel volume CC7, pan CC10
+ are NOT reset
+ */
+ break;
+
+ /*
+ For logical reasons, the RPN data entry are grouped together.
+ However, keep in mind that these cases are not necessarily in
+ ascending order.
+ e.g., MIDI_CONTROLLER_DATA_ENTRY_MSB == 6,
+ whereas MIDI_CONTROLLER_SUSTAIN_PEDAL == 64.
+ So arrange these case statements in whatever manner is more efficient for
+ the processor / compiler.
+ */
+ case MIDI_CONTROLLER_ENTER_DATA_MSB:
+ case MIDI_CONTROLLER_ENTER_DATA_LSB:
+ case MIDI_CONTROLLER_SELECT_RPN_LSB:
+ case MIDI_CONTROLLER_SELECT_RPN_MSB:
+ case MIDI_CONTROLLER_SELECT_NRPN_MSB:
+ case MIDI_CONTROLLER_SELECT_NRPN_LSB:
+ VMUpdateRPNStateMachine(pSynth, channel, controller, value);
+ break;
+
+ case MIDI_CONTROLLER_ALL_SOUND_OFF:
+ case MIDI_CONTROLLER_ALL_NOTES_OFF:
+ case MIDI_CONTROLLER_OMNI_OFF:
+ case MIDI_CONTROLLER_OMNI_ON:
+ case MIDI_CONTROLLER_MONO_ON_POLY_OFF:
+ case MIDI_CONTROLLER_POLY_ON_MONO_OFF:
+ /* NOTE: we treat all sounds off the same as all notes off */
+ VMAllNotesOff(pVoiceMgr, pSynth, channel);
+ break;
+
+ default:
+#ifdef _DEBUG_VM
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMControlChange: controller %d not yet implemented\n", controller); */ }
+#endif
+ break;
+
+ }
+
+ return;
+}
+
+/*----------------------------------------------------------------------------
+ * VMUpdateRPNStateMachine()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Call this function when we want to parse RPN related controller messages.
+ * We only support RPN0 (pitch bend sensitivity), RPN1 (fine tuning) and
+ * RPN2 (coarse tuning). Any other RPNs or NRPNs are ignored for now.
+ *.
+ * Supports any order, so not a state machine anymore. This function was
+ * rewritten to work correctly regardless of order.
+ *
+ * Inputs:
+ * nChannel - the channel this controller message is coming from
+ * nControllerNumber - which RPN related controller
+ * nControlValue - the value of the RPN related controller
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ * returns EAS_RESULT, which is typically EAS_SUCCESS, since there are
+ * few possible errors
+ *
+ * Side Effects:
+ * gsSynthObject.m_sChannel[nChannel].m_nPitchBendSensitivity
+ * (or m_nFinePitch or m_nCoarsePitch)
+ * will be updated if the proper RPN message is received.
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT VMUpdateRPNStateMachine (S_SYNTH *pSynth, EAS_U8 channel, EAS_U8 controller, EAS_U8 value)
+{
+ S_SYNTH_CHANNEL *pChannel;
+
+#ifdef _DEBUG_VM
+ if (channel >= NUM_SYNTH_CHANNELS)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMUpdateRPNStateMachines: error, %d invalid channel number\n",
+ channel); */ }
+ return EAS_FAILURE;
+ }
+#endif
+
+ pChannel = &(pSynth->channels[channel]);
+
+ switch (controller)
+ {
+ case MIDI_CONTROLLER_SELECT_NRPN_MSB:
+ case MIDI_CONTROLLER_SELECT_NRPN_LSB:
+ pChannel->registeredParam = DEFAULT_REGISTERED_PARAM;
+ break;
+ case MIDI_CONTROLLER_SELECT_RPN_MSB:
+ pChannel->registeredParam =
+ (pChannel->registeredParam & 0x7F) | (value<<7);
+ break;
+ case MIDI_CONTROLLER_SELECT_RPN_LSB:
+ pChannel->registeredParam =
+ (pChannel->registeredParam & 0x7F00) | value;
+ break;
+ case MIDI_CONTROLLER_ENTER_DATA_MSB:
+ switch (pChannel->registeredParam)
+ {
+ case 0:
+ pChannel->pitchBendSensitivity = value * 100;
+ break;
+ case 1:
+ /*lint -e{702} <avoid division for performance reasons>*/
+ pChannel->finePitch = (EAS_I8)((((value << 7) - 8192) * 100) >> 13);
+ break;
+ case 2:
+ pChannel->coarsePitch = (EAS_I8)(value - 64);
+ break;
+ default:
+ break;
+ }
+ break;
+ case MIDI_CONTROLLER_ENTER_DATA_LSB:
+ switch (pChannel->registeredParam)
+ {
+ case 0:
+ //ignore lsb
+ break;
+ case 1:
+ //ignore lsb
+ break;
+ case 2:
+ //ignore lsb
+ break;
+ default:
+ break;
+ }
+ break;
+ default:
+ return EAS_FAILURE; //not a RPN related controller
+ }
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * VMUpdateStaticChannelParameters()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Update all of the static channel parameters for channels that have had
+ * a controller change values
+ * Or if the synth has signalled that all channels must forcibly
+ * be updated
+ *
+ * Inputs:
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ * none
+ *
+ * Side Effects:
+ * - psSynthObject->m_sChannel[].m_nStaticGain and m_nStaticPitch
+ * are updated for channels whose controller values have changed
+ * or if the synth has signalled that all channels must forcibly
+ * be updated
+ *----------------------------------------------------------------------------
+*/
+void VMUpdateStaticChannelParameters (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth)
+{
+ EAS_INT channel;
+
+ if (pSynth->synthFlags & SYNTH_FLAG_UPDATE_ALL_CHANNEL_PARAMETERS)
+ {
+ /*
+ the synth wants us to forcibly update all channel
+ parameters. This event occurs when we are about to
+ finish resetting the synth
+ */
+ for (channel = 0; channel < NUM_SYNTH_CHANNELS; channel++)
+ {
+#ifdef _HYBRID_SYNTH
+ if (pSynth->channels[channel].regionIndex & FLAG_RGN_IDX_FM_SYNTH)
+ pSecondarySynth->pfUpdateChannel(pVoiceMgr, pSynth, (EAS_U8) channel);
+ else
+ pPrimarySynth->pfUpdateChannel(pVoiceMgr, pSynth, (EAS_U8) channel);
+#else
+ pPrimarySynth->pfUpdateChannel(pVoiceMgr, pSynth, (EAS_U8) channel);
+#endif
+ }
+
+ /*
+ clear the flag to indicates we have now forcibly
+ updated all channel parameters
+ */
+ pSynth->synthFlags &= ~SYNTH_FLAG_UPDATE_ALL_CHANNEL_PARAMETERS;
+ }
+ else
+ {
+
+ /* only update channel params if signalled by a channel flag */
+ for (channel = 0; channel < NUM_SYNTH_CHANNELS; channel++)
+ {
+ if ( 0 != (pSynth->channels[channel].channelFlags & CHANNEL_FLAG_UPDATE_CHANNEL_PARAMETERS))
+ {
+#ifdef _HYBRID_SYNTH
+ if (pSynth->channels[channel].regionIndex & FLAG_RGN_IDX_FM_SYNTH)
+ pSecondarySynth->pfUpdateChannel(pVoiceMgr, pSynth, (EAS_U8) channel);
+ else
+ pPrimarySynth->pfUpdateChannel(pVoiceMgr, pSynth, (EAS_U8) channel);
+#else
+ pPrimarySynth->pfUpdateChannel(pVoiceMgr, pSynth, (EAS_U8) channel);
+#endif
+ }
+ }
+
+ }
+
+ return;
+}
+
+/*----------------------------------------------------------------------------
+ * VMFindProgram()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Look up an individual program in sound library. This function
+ * searches the bank list for a program, then the individual program
+ * list.
+ *
+ * Inputs:
+ *
+ * Outputs:
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT VMFindProgram (const S_EAS *pEAS, EAS_U32 bank, EAS_U8 programNum, EAS_U16 *pRegionIndex)
+{
+ EAS_U32 locale;
+ const S_PROGRAM *p;
+ EAS_U16 i;
+ EAS_U16 regionIndex;
+
+ /* make sure we have a valid sound library */
+ if (pEAS == NULL)
+ return EAS_FAILURE;
+
+ /* search the banks */
+ for (i = 0; i < pEAS->numBanks; i++)
+ {
+ if (bank == (EAS_U32) pEAS->pBanks[i].locale)
+ {
+ regionIndex = pEAS->pBanks[i].regionIndex[programNum];
+ if (regionIndex != INVALID_REGION_INDEX)
+ {
+ *pRegionIndex = regionIndex;
+ return EAS_SUCCESS;
+ }
+ break;
+ }
+ }
+
+ /* establish locale */
+ locale = ( bank << 8) | programNum;
+
+ /* search for program */
+ for (i = 0, p = pEAS->pPrograms; i < pEAS->numPrograms; i++, p++)
+ {
+ if (p->locale == locale)
+ {
+ *pRegionIndex = p->regionIndex;
+ return EAS_SUCCESS;
+ }
+ }
+
+ return EAS_FAILURE;
+}
+
+#ifdef DLS_SYNTHESIZER
+/*----------------------------------------------------------------------------
+ * VMFindDLSProgram()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Look up an individual program in sound library. This function
+ * searches the bank list for a program, then the individual program
+ * list.
+ *
+ * Inputs:
+ *
+ * Outputs:
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT VMFindDLSProgram (const S_DLS *pDLS, EAS_U32 bank, EAS_U8 programNum, EAS_U16 *pRegionIndex)
+{
+ EAS_U32 locale;
+ const S_PROGRAM *p;
+ EAS_U16 i;
+
+ /* make sure we have a valid sound library */
+ if (pDLS == NULL)
+ return EAS_FAILURE;
+
+ /* establish locale */
+ locale = (bank << 8) | programNum;
+
+ /* search for program */
+ for (i = 0, p = pDLS->pDLSPrograms; i < pDLS->numDLSPrograms; i++, p++)
+ {
+ if (p->locale == locale)
+ {
+ *pRegionIndex = p->regionIndex;
+ return EAS_SUCCESS;
+ }
+ }
+
+ return EAS_FAILURE;
+}
+#endif
+
+/*----------------------------------------------------------------------------
+ * VMProgramChange()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Change the instrument (program) for the given channel.
+ *
+ * Depending on the program number, and the bank selected for this channel, the
+ * program may be in ROM, RAM (from SMAF or CMX related RAM wavetable), or
+ * Alternate wavetable (from mobile DLS or other DLS file)
+ *
+ * This function figures out what wavetable should be used, and sets it up as the
+ * wavetable to use for this channel. Also the channel may switch from a melodic
+ * channel to a rhythm channel, or vice versa.
+ *
+ * Inputs:
+ *
+ * Outputs:
+ * Side Effects:
+ * gsSynthObject.m_sChannel[nChannel].m_nProgramNumber is likely changed
+ * gsSynthObject.m_sChannel[nChannel].m_psEAS may be changed
+ * gsSynthObject.m_sChannel[nChannel].m_bRhythmChannel may be changed
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pVoiceMgr) reserved for future use */
+void VMProgramChange (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel, EAS_U8 program)
+{
+ S_SYNTH_CHANNEL *pChannel;
+ EAS_U32 bank;
+ EAS_U16 regionIndex;
+
+#ifdef _DEBUG_VM
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "VMProgramChange: vSynthNum=%d, channel=%d, program=%d\n", pSynth->vSynthNum, channel, program); */ }
+#endif
+
+ /* setup pointer to MIDI channel data */
+ pChannel = &pSynth->channels[channel];
+ bank = pChannel->bankNum;
+
+ /* allow channels to switch between being melodic or rhythm channels, using GM2 CC values */
+ if ((bank & 0xFF00) == DEFAULT_RHYTHM_BANK_NUMBER)
+ {
+ /* make it a rhythm channel */
+ pChannel->channelFlags |= CHANNEL_FLAG_RHYTHM_CHANNEL;
+ }
+ else if ((bank & 0xFF00) == DEFAULT_MELODY_BANK_NUMBER)
+ {
+ /* make it a melody channel */
+ pChannel->channelFlags &= ~CHANNEL_FLAG_RHYTHM_CHANNEL;
+ }
+
+ regionIndex = DEFAULT_REGION_INDEX;
+
+#ifdef EXTERNAL_AUDIO
+ /* give the external audio interface a chance to handle it */
+ if (pSynth->cbProgChgFunc != NULL)
+ {
+ S_EXT_AUDIO_PRG_CHG prgChg;
+ prgChg.channel = channel;
+ prgChg.bank = (EAS_U16) bank;
+ prgChg.program = program;
+ if (pSynth->cbProgChgFunc(pSynth->pExtAudioInstData, &prgChg))
+ pChannel->channelFlags |= CHANNEL_FLAG_EXTERNAL_AUDIO;
+ }
+
+#endif
+
+
+#ifdef DLS_SYNTHESIZER
+ /* first check for DLS program that may overlay the internal instrument */
+ if (VMFindDLSProgram(pSynth->pDLS, bank, program, &regionIndex) != EAS_SUCCESS)
+#endif
+
+ /* braces to support 'if' clause above */
+ {
+
+ /* look in the internal banks */
+ if (VMFindProgram(pSynth->pEAS, bank, program, &regionIndex) != EAS_SUCCESS)
+
+ /* fall back to default bank */
+ {
+ if (pSynth->channels[channel].channelFlags & CHANNEL_FLAG_RHYTHM_CHANNEL)
+ bank = DEFAULT_RHYTHM_BANK_NUMBER;
+ else
+ bank = DEFAULT_MELODY_BANK_NUMBER;
+
+ if (VMFindProgram(pSynth->pEAS, bank, program, &regionIndex) != EAS_SUCCESS)
+
+ /* switch to program 0 in the default bank */
+ {
+ if (VMFindProgram(pSynth->pEAS, bank, 0, &regionIndex) != EAS_SUCCESS)
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "VMProgramChange: No program @ %03d:%03d:%03d\n",
+ (bank >> 8) & 0x7f, bank & 0x7f, program); */ }
+ }
+ }
+ }
+
+ /* we have our new program change for this channel */
+ pChannel->programNum = program;
+ pChannel->regionIndex = regionIndex;
+
+ /*
+ set a channel flag to request parameter updates
+ for all the voices associated with this channel
+ */
+ pChannel->channelFlags |= CHANNEL_FLAG_UPDATE_CHANNEL_PARAMETERS;
+
+ return;
+}
+
+/*----------------------------------------------------------------------------
+ * VMAddSamples()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Synthesize the requested number of samples (block based processing)
+ *
+ * Inputs:
+ * nNumSamplesToAdd - number of samples to write to buffer
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ * number of voices rendered
+ *
+ * Side Effects:
+ * - samples are added to the presently free buffer
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_I32 VMAddSamples (S_VOICE_MGR *pVoiceMgr, EAS_I32 *pMixBuffer, EAS_I32 numSamples)
+{
+ S_SYNTH *pSynth;
+ EAS_INT voicesRendered;
+ EAS_INT voiceNum;
+ EAS_BOOL done;
+
+#ifdef _REVERB
+ EAS_PCM *pReverbSendBuffer;
+#endif // ifdef _REVERB
+
+#ifdef _CHORUS
+ EAS_PCM *pChorusSendBuffer;
+#endif // ifdef _CHORUS
+
+ voicesRendered = 0;
+ for (voiceNum = 0; voiceNum < MAX_SYNTH_VOICES; voiceNum++)
+ {
+
+ /* retarget stolen voices */
+ if ((pVoiceMgr->voices[voiceNum].voiceState == eVoiceStateStolen) && (pVoiceMgr->voices[voiceNum].gain <= 0))
+ VMRetargetStolenVoice(pVoiceMgr, voiceNum);
+
+ /* get pointer to virtual synth */
+ pSynth = pVoiceMgr->pSynth[pVoiceMgr->voices[voiceNum].channel >> 4];
+
+ /* synthesize active voices */
+ if (pVoiceMgr->voices[voiceNum].voiceState != eVoiceStateFree)
+ {
+ done = GetSynthPtr(voiceNum)->pfUpdateVoice(pVoiceMgr, pSynth, &pVoiceMgr->voices[voiceNum], GetAdjustedVoiceNum(voiceNum), pMixBuffer, numSamples);
+ voicesRendered++;
+
+ /* voice is finished */
+ if (done == EAS_TRUE)
+ {
+ /* set gain of stolen voice to zero so it will be restarted */
+ if (pVoiceMgr->voices[voiceNum].voiceState == eVoiceStateStolen)
+ pVoiceMgr->voices[voiceNum].gain = 0;
+
+ /* or return it to the free voice pool */
+ else
+ VMFreeVoice(pVoiceMgr, pSynth, &pVoiceMgr->voices[voiceNum]);
+ }
+
+ /* if this voice is scheduled to be muted, set the mute flag */
+ if (pVoiceMgr->voices[voiceNum].voiceFlags & VOICE_FLAG_DEFER_MUTE)
+ {
+ pVoiceMgr->voices[voiceNum].voiceFlags &= ~(VOICE_FLAG_DEFER_MUTE | VOICE_FLAG_DEFER_MIDI_NOTE_OFF);
+ VMMuteVoice(pVoiceMgr, voiceNum);
+ }
+
+ /* if voice just started, advance state to play */
+ if (pVoiceMgr->voices[voiceNum].voiceState == eVoiceStateStart)
+ pVoiceMgr->voices[voiceNum].voiceState = eVoiceStatePlay;
+ }
+ }
+
+ return voicesRendered;
+}
+
+/*----------------------------------------------------------------------------
+ * VMRender()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * This routine renders a frame of audio
+ *
+ * Inputs:
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ * pVoicesRendered - number of voices rendered this frame
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT VMRender (S_VOICE_MGR *pVoiceMgr, EAS_I32 numSamples, EAS_I32 *pMixBuffer, EAS_I32 *pVoicesRendered)
+{
+ S_SYNTH *pSynth;
+ EAS_INT i;
+ EAS_INT channel;
+
+#ifdef _CHECKED_BUILD
+ SanityCheck(pVoiceMgr);
+#endif
+
+ /* update MIDI channel parameters */
+ *pVoicesRendered = 0;
+ for (i = 0; i < MAX_VIRTUAL_SYNTHESIZERS; i++)
+ {
+ if (pVoiceMgr->pSynth[i] != NULL)
+ VMUpdateStaticChannelParameters(pVoiceMgr, pVoiceMgr->pSynth[i]);
+ }
+
+ /* synthesize a buffer of audio */
+ *pVoicesRendered = VMAddSamples(pVoiceMgr, pMixBuffer, numSamples);
+
+ /*
+ * check for deferred note-off messages
+ * If flag is set, that means one or more voices are expecting deferred
+ * midi note-off messages because the midi note-on and corresponding midi
+ * note-off requests occurred during the same update interval. The goal
+ * is the defer the note-off request so that the note can at least start.
+ */
+ for (i = 0; i < MAX_VIRTUAL_SYNTHESIZERS; i++)
+ {
+ pSynth = pVoiceMgr->pSynth[i];
+
+ if (pSynth== NULL)
+ continue;
+
+ if (pSynth->synthFlags & SYNTH_FLAG_DEFERRED_MIDI_NOTE_OFF_PENDING)
+ VMDeferredStopNote(pVoiceMgr, pSynth);
+
+ /* check if we need to reset the synth */
+ if ((pSynth->synthFlags & SYNTH_FLAG_RESET_IS_REQUESTED) &&
+ (pSynth->numActiveVoices == 0))
+ {
+ /*
+ complete the process of resetting the synth now that
+ all voices have muted
+ */
+#ifdef _DEBUG_VM
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMAddSamples: complete the reset process\n"); */ }
+#endif
+
+ VMInitializeAllChannels(pVoiceMgr, pSynth);
+ VMInitializeAllVoices(pVoiceMgr, pSynth->vSynthNum);
+
+ /* clear the reset flag */
+ pSynth->synthFlags &= ~SYNTH_FLAG_RESET_IS_REQUESTED;
+ }
+
+ /* clear channel update flags */
+ for (channel = 0; channel < NUM_SYNTH_CHANNELS; channel++)
+ pSynth->channels[channel].channelFlags &= ~CHANNEL_FLAG_UPDATE_CHANNEL_PARAMETERS;
+
+ }
+
+#ifdef _CHECKED_BUILD
+ SanityCheck(pVoiceMgr);
+#endif
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * VMInitWorkload()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Clears the workload counter
+ *
+ * Inputs:
+ * pVoiceMgr - pointer to instance data
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+void VMInitWorkload (S_VOICE_MGR *pVoiceMgr)
+{
+ pVoiceMgr->workload = 0;
+}
+
+/*----------------------------------------------------------------------------
+ * VMSetWorkload()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Sets the max workload for a single frame.
+ *
+ * Inputs:
+ * pVoiceMgr - pointer to instance data
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+void VMSetWorkload (S_VOICE_MGR *pVoiceMgr, EAS_I32 maxWorkLoad)
+{
+ pVoiceMgr->maxWorkLoad = maxWorkLoad;
+}
+
+/*----------------------------------------------------------------------------
+ * VMCheckWorkload()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Checks to see if work load has been exceeded on this frame.
+ *
+ * Inputs:
+ * pVoiceMgr - pointer to instance data
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_BOOL VMCheckWorkload (S_VOICE_MGR *pVoiceMgr)
+{
+ if (pVoiceMgr->maxWorkLoad > 0)
+ return (EAS_BOOL) (pVoiceMgr->workload >= pVoiceMgr->maxWorkLoad);
+ return EAS_FALSE;
+}
+
+/*----------------------------------------------------------------------------
+ * VMActiveVoices()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Returns the number of active voices in the synthesizer.
+ *
+ * Inputs:
+ * pEASData - pointer to instance data
+ *
+ * Outputs:
+ * Returns the number of active voices
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_I32 VMActiveVoices (S_SYNTH *pSynth)
+{
+ return pSynth->numActiveVoices;
+}
+
+/*----------------------------------------------------------------------------
+ * VMSetSynthPolyphony()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Set the synth to a new polyphony value. Value must be >= 1 and
+ * <= MAX_SYNTH_VOICES. This function will pin the polyphony at those limits
+ *
+ * Inputs:
+ * pVoiceMgr pointer to synthesizer data
+ * polyphonyCount desired polyphony count
+ * synth synthesizer number (0 = onboard, 1 = DSP)
+ *
+ * Outputs:
+ * Returns error code
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT VMSetSynthPolyphony (S_VOICE_MGR *pVoiceMgr, EAS_I32 synth, EAS_I32 polyphonyCount)
+{
+ EAS_INT i;
+ EAS_INT activeVoices;
+
+ /* lower limit */
+ if (polyphonyCount < 1)
+ polyphonyCount = 1;
+
+ /* split architecture */
+#if defined(_SECONDARY_SYNTH) || defined(EAS_SPLIT_WT_SYNTH)
+ if (synth == EAS_MCU_SYNTH)
+ {
+ if (polyphonyCount > NUM_PRIMARY_VOICES)
+ polyphonyCount = NUM_PRIMARY_VOICES;
+ if (pVoiceMgr->maxPolyphonyPrimary == polyphonyCount)
+ return EAS_SUCCESS;
+ pVoiceMgr->maxPolyphonyPrimary = (EAS_U16) polyphonyCount;
+ }
+ else if (synth == EAS_DSP_SYNTH)
+ {
+ if (polyphonyCount > NUM_SECONDARY_VOICES)
+ polyphonyCount = NUM_SECONDARY_VOICES;
+ if (pVoiceMgr->maxPolyphonySecondary == polyphonyCount)
+ return EAS_SUCCESS;
+ pVoiceMgr->maxPolyphonySecondary = (EAS_U16) polyphonyCount;
+ }
+ else
+ return EAS_ERROR_PARAMETER_RANGE;
+
+ /* setting for SP-MIDI */
+ pVoiceMgr->maxPolyphony = pVoiceMgr->maxPolyphonyPrimary + pVoiceMgr->maxPolyphonySecondary;
+
+ /* standard architecture */
+#else
+ if (synth != EAS_MCU_SYNTH)
+ return EAS_ERROR_PARAMETER_RANGE;
+
+ /* pin desired value to possible limits */
+ if (polyphonyCount > MAX_SYNTH_VOICES)
+ polyphonyCount = MAX_SYNTH_VOICES;
+
+ /* set polyphony, if value is different than current value */
+ if (pVoiceMgr->maxPolyphony == polyphonyCount)
+ return EAS_SUCCESS;
+
+ pVoiceMgr->maxPolyphony = (EAS_U16) polyphonyCount;
+#endif
+
+ /* if SPMIDI enabled, update channel masking based on new polyphony */
+ for (i = 0; i < MAX_VIRTUAL_SYNTHESIZERS; i++)
+ {
+ if (pVoiceMgr->pSynth[i])
+ {
+ if (pVoiceMgr->pSynth[i]->synthFlags & SYNTH_FLAG_SP_MIDI_ON)
+ VMMIPUpdateChannelMuting(pVoiceMgr, pVoiceMgr->pSynth[i]);
+ else
+ pVoiceMgr->pSynth[i]->poolAlloc[0] = (EAS_U8) polyphonyCount;
+ }
+ }
+
+ /* are we under polyphony limit? */
+ if (pVoiceMgr->activeVoices <= polyphonyCount)
+ return EAS_SUCCESS;
+
+ /* count the number of active voices */
+ activeVoices = 0;
+ for (i = 0; i < MAX_SYNTH_VOICES; i++)
+ {
+
+ /* is voice active? */
+ if ((pVoiceMgr->voices[i].voiceState != eVoiceStateFree) && (pVoiceMgr->voices[i].voiceState != eVoiceStateMuting))
+ activeVoices++;
+ }
+
+ /* we may have to mute voices to reach new target */
+ while (activeVoices > polyphonyCount)
+ {
+ S_SYNTH *pSynth;
+ S_SYNTH_VOICE *pVoice;
+ EAS_I32 currentPriority, bestPriority;
+ EAS_INT bestCandidate;
+
+ /* find the lowest priority voice */
+ bestPriority = bestCandidate = -1;
+ for (i = 0; i < MAX_SYNTH_VOICES; i++)
+ {
+
+ pVoice = &pVoiceMgr->voices[i];
+
+ /* ignore free and muting voices */
+ if ((pVoice->voiceState == eVoiceStateFree) || (pVoice->voiceState == eVoiceStateMuting))
+ continue;
+
+ pSynth = pVoiceMgr->pSynth[GET_VSYNTH(pVoice->channel)];
+
+ /* if voice is stolen or just started, reduce the likelihood it will be stolen */
+ if (( pVoice->voiceState == eVoiceStateStolen) || (pVoice->voiceFlags & VOICE_FLAG_NO_SAMPLES_SYNTHESIZED_YET))
+ {
+ /* include velocity */
+ currentPriority = 128 - pVoice->nextVelocity;
+
+ /* include channel priority */
+ currentPriority += pSynth->channels[GET_CHANNEL(pVoice->nextChannel)].pool << CHANNEL_PRIORITY_STEAL_WEIGHT;
+ }
+ else
+ {
+ /* include age */
+ currentPriority = (EAS_I32) pVoice->age << NOTE_AGE_STEAL_WEIGHT;
+
+ /* include note gain -higher gain is lower steal value */
+ /*lint -e{704} use shift for performance */
+ currentPriority += ((32768 >> (12 - NOTE_GAIN_STEAL_WEIGHT)) + 256) -
+ ((EAS_I32) pVoice->gain >> (12 - NOTE_GAIN_STEAL_WEIGHT));
+
+ /* include channel priority */
+ currentPriority += pSynth->channels[GET_CHANNEL(pVoice->channel)].pool << CHANNEL_PRIORITY_STEAL_WEIGHT;
+ }
+
+ /* include synth priority */
+ currentPriority += pSynth->priority << SYNTH_PRIORITY_WEIGHT;
+
+ /* is this the best choice so far? */
+ if (currentPriority > bestPriority)
+ {
+ bestPriority = currentPriority;
+ bestCandidate = i;
+ }
+ }
+
+ /* shutdown best candidate */
+ if (bestCandidate < 0)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "VMSetPolyphony: Unable to reduce polyphony\n"); */ }
+ break;
+ }
+
+ /* shut down this voice */
+ /*lint -e{771} pSynth is initialized if bestCandidate >= 0 */
+ VMMuteVoice(pVoiceMgr, bestCandidate);
+ activeVoices--;
+ }
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * VMGetSynthPolyphony()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Returns the current polyphony setting
+ *
+ * Inputs:
+ * pVoiceMgr pointer to synthesizer data
+ * synth synthesizer number (0 = onboard, 1 = DSP)
+ *
+ * Outputs:
+ * Returns actual polyphony value set, as pinned by limits
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT VMGetSynthPolyphony (S_VOICE_MGR *pVoiceMgr, EAS_I32 synth, EAS_I32 *pPolyphonyCount)
+{
+
+#if defined(_SECONDARY_SYNTH) || defined(EAS_SPLIT_WT_SYNTH)
+ if (synth == EAS_MCU_SYNTH)
+ *pPolyphonyCount = pVoiceMgr->maxPolyphonyPrimary;
+ else if (synth == EAS_DSP_SYNTH)
+ *pPolyphonyCount = pVoiceMgr->maxPolyphonySecondary;
+ else
+ return EAS_ERROR_PARAMETER_RANGE;
+#else
+ if (synth != EAS_MCU_SYNTH)
+ return EAS_ERROR_PARAMETER_RANGE;
+ *pPolyphonyCount = pVoiceMgr->maxPolyphony;
+#endif
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * VMSetPolyphony()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Set the virtual synth polyphony. 0 = no limit (i.e. can use
+ * all available voices).
+ *
+ * Inputs:
+ * pVoiceMgr pointer to synthesizer data
+ * polyphonyCount desired polyphony count
+ * pSynth pointer to virtual synth
+ *
+ * Outputs:
+ * Returns error code
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT VMSetPolyphony (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_I32 polyphonyCount)
+{
+ EAS_INT i;
+ EAS_INT activeVoices;
+
+ /* check limits */
+ if (polyphonyCount < 0)
+ return EAS_ERROR_PARAMETER_RANGE;
+
+ /* zero is max polyphony */
+ if ((polyphonyCount == 0) || (polyphonyCount > MAX_SYNTH_VOICES))
+ {
+ pSynth->maxPolyphony = 0;
+ return EAS_SUCCESS;
+ }
+
+ /* set new polyphony */
+ pSynth->maxPolyphony = (EAS_U16) polyphonyCount;
+
+ /* max polyphony is minimum of virtual synth and actual synth */
+ if (polyphonyCount > pVoiceMgr->maxPolyphony)
+ polyphonyCount = pVoiceMgr->maxPolyphony;
+
+ /* if SP-MIDI mode, update the channel muting */
+ if (pSynth->synthFlags & SYNTH_FLAG_SP_MIDI_ON)
+ VMMIPUpdateChannelMuting(pVoiceMgr, pSynth);
+ else
+ pSynth->poolAlloc[0] = (EAS_U8) polyphonyCount;
+
+ /* are we under polyphony limit? */
+ if (pSynth->numActiveVoices <= polyphonyCount)
+ return EAS_SUCCESS;
+
+ /* count the number of active voices */
+ activeVoices = 0;
+ for (i = 0; i < MAX_SYNTH_VOICES; i++)
+ {
+ /* this synth? */
+ if (GET_VSYNTH(pVoiceMgr->voices[i].nextChannel) != pSynth->vSynthNum)
+ continue;
+
+ /* is voice active? */
+ if ((pVoiceMgr->voices[i].voiceState != eVoiceStateFree) && (pVoiceMgr->voices[i].voiceState != eVoiceStateMuting))
+ activeVoices++;
+ }
+
+ /* we may have to mute voices to reach new target */
+ while (activeVoices > polyphonyCount)
+ {
+ S_SYNTH_VOICE *pVoice;
+ EAS_I32 currentPriority, bestPriority;
+ EAS_INT bestCandidate;
+
+ /* find the lowest priority voice */
+ bestPriority = bestCandidate = -1;
+ for (i = 0; i < MAX_SYNTH_VOICES; i++)
+ {
+ pVoice = &pVoiceMgr->voices[i];
+
+ /* this synth? */
+ if (GET_VSYNTH(pVoice->nextChannel) != pSynth->vSynthNum)
+ continue;
+
+ /* if voice is stolen or just started, reduce the likelihood it will be stolen */
+ if (( pVoice->voiceState == eVoiceStateStolen) || (pVoice->voiceFlags & VOICE_FLAG_NO_SAMPLES_SYNTHESIZED_YET))
+ {
+ /* include velocity */
+ currentPriority = 128 - pVoice->nextVelocity;
+
+ /* include channel priority */
+ currentPriority += pSynth->channels[GET_CHANNEL(pVoice->nextChannel)].pool << CHANNEL_PRIORITY_STEAL_WEIGHT;
+ }
+ else
+ {
+ /* include age */
+ currentPriority = (EAS_I32) pVoice->age << NOTE_AGE_STEAL_WEIGHT;
+
+ /* include note gain -higher gain is lower steal value */
+ /*lint -e{704} use shift for performance */
+ currentPriority += ((32768 >> (12 - NOTE_GAIN_STEAL_WEIGHT)) + 256) -
+ ((EAS_I32) pVoice->gain >> (12 - NOTE_GAIN_STEAL_WEIGHT));
+
+ /* include channel priority */
+ currentPriority += pSynth->channels[GET_CHANNEL(pVoice->nextChannel)].pool << CHANNEL_PRIORITY_STEAL_WEIGHT;
+ }
+
+ /* is this the best choice so far? */
+ if (currentPriority > bestPriority)
+ {
+ bestPriority = currentPriority;
+ bestCandidate = i;
+ }
+ }
+
+ /* shutdown best candidate */
+ if (bestCandidate < 0)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "VMSetPolyphony: Unable to reduce polyphony\n"); */ }
+ break;
+ }
+
+ /* shut down this voice */
+ VMMuteVoice(pVoiceMgr, bestCandidate);
+ activeVoices--;
+ }
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * VMGetPolyphony()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Get the virtual synth polyphony
+ *
+ * Inputs:
+ * pVoiceMgr pointer to synthesizer data
+ * pPolyphonyCount pointer to variable to hold polyphony count
+ * pSynth pointer to virtual synth
+ *
+ * Outputs:
+ * Returns error code
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pVoiceMgr) reserved for future use */
+EAS_RESULT VMGetPolyphony (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_I32 *pPolyphonyCount)
+{
+ *pPolyphonyCount = (EAS_U16) pSynth->maxPolyphony;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * VMSetPriority()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Set the virtual synth priority
+ *
+ * Inputs:
+ * pVoiceMgr pointer to synthesizer data
+ * priority new priority
+ * pSynth pointer to virtual synth
+ *
+ * Outputs:
+ * Returns error code
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pVoiceMgr) reserved for future use */
+EAS_RESULT VMSetPriority (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_I32 priority)
+{
+ pSynth->priority = (EAS_U8) priority ;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * VMGetPriority()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Get the virtual synth priority
+ *
+ * Inputs:
+ * pVoiceMgr pointer to synthesizer data
+ * pPriority pointer to variable to hold priority
+ * pSynth pointer to virtual synth
+ *
+ * Outputs:
+ * Returns error code
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pVoiceMgr) reserved for future use */
+EAS_RESULT VMGetPriority (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_I32 *pPriority)
+{
+ *pPriority = pSynth->priority;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * VMSetVolume()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Set the master volume for this synthesizer for this sequence.
+ *
+ * Inputs:
+ * nSynthVolume - the desired master volume
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ * overrides any previously set master volume from sysex
+ *
+ *----------------------------------------------------------------------------
+*/
+void VMSetVolume (S_SYNTH *pSynth, EAS_U16 masterVolume)
+{
+ pSynth->masterVolume = masterVolume;
+ pSynth->synthFlags |= SYNTH_FLAG_UPDATE_ALL_CHANNEL_PARAMETERS;
+}
+
+/*----------------------------------------------------------------------------
+ * VMSetPitchBendRange()
+ *----------------------------------------------------------------------------
+ * Set the pitch bend range for the given channel.
+ *----------------------------------------------------------------------------
+*/
+void VMSetPitchBendRange (S_SYNTH *pSynth, EAS_INT channel, EAS_I16 pitchBendRange)
+{
+ pSynth->channels[channel].pitchBendSensitivity = pitchBendRange;
+}
+
+/*----------------------------------------------------------------------------
+ * VMValidateEASLib()
+ *----------------------------------------------------------------------------
+ * Validates an EAS library
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT VMValidateEASLib (EAS_SNDLIB_HANDLE pEAS)
+{
+ /* validate the sound library */
+ if (pEAS)
+ {
+ if (pEAS->identifier != _EAS_LIBRARY_VERSION)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "VMValidateEASLib: Sound library mismatch in sound library: Read 0x%08x, expected 0x%08x\n",
+ pEAS->identifier, _EAS_LIBRARY_VERSION); */ }
+ return EAS_ERROR_SOUND_LIBRARY;
+ }
+
+ /* check sample rate */
+ if ((pEAS->libAttr & LIBFORMAT_SAMPLE_RATE_MASK) != _OUTPUT_SAMPLE_RATE)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "VMValidateEASLib: Sample rate mismatch in sound library: Read %lu, expected %lu\n",
+ pEAS->libAttr & LIBFORMAT_SAMPLE_RATE_MASK, _OUTPUT_SAMPLE_RATE); */ }
+ return EAS_ERROR_SOUND_LIBRARY;
+ }
+
+#ifdef _WT_SYNTH
+ /* check sample bit depth */
+#ifdef _8_BIT_SAMPLES
+ if (pEAS->libAttr & LIB_FORMAT_16_BIT_SAMPLES)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "VMValidateEASLib: Expected 8-bit samples and found 16-bit\n",
+ pEAS->libAttr & LIBFORMAT_SAMPLE_RATE_MASK, _OUTPUT_SAMPLE_RATE); */ }
+ return EAS_ERROR_SOUND_LIBRARY;
+ }
+#endif
+#ifdef _16_BIT_SAMPLES
+ if ((pEAS->libAttr & LIB_FORMAT_16_BIT_SAMPLES) == 0)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "VMValidateEASLib: Expected 16-bit samples and found 8-bit\n",
+ pEAS->libAttr & LIBFORMAT_SAMPLE_RATE_MASK, _OUTPUT_SAMPLE_RATE); */ }
+ return EAS_ERROR_SOUND_LIBRARY;
+ }
+#endif
+#endif
+ }
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * VMSetGlobalEASLib()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Sets the EAS library to be used by the synthesizer
+ *
+ * Inputs:
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT VMSetGlobalEASLib (S_VOICE_MGR *pVoiceMgr, EAS_SNDLIB_HANDLE pEAS)
+{
+ EAS_RESULT result;
+
+ result = VMValidateEASLib(pEAS);
+ if (result != EAS_SUCCESS)
+ return result;
+
+ pVoiceMgr->pGlobalEAS = pEAS;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * VMSetEASLib()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Sets the EAS library to be used by the synthesizer
+ *
+ * Inputs:
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT VMSetEASLib (S_SYNTH *pSynth, EAS_SNDLIB_HANDLE pEAS)
+{
+ EAS_RESULT result;
+
+ result = VMValidateEASLib(pEAS);
+ if (result != EAS_SUCCESS)
+ return result;
+
+ pSynth->pEAS = pEAS;
+ return EAS_SUCCESS;
+}
+
+#ifdef DLS_SYNTHESIZER
+/*----------------------------------------------------------------------------
+ * VMSetGlobalDLSLib()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Sets the DLS library to be used by the synthesizer
+ *
+ * Inputs:
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT VMSetGlobalDLSLib (EAS_DATA_HANDLE pEASData, EAS_DLSLIB_HANDLE pDLS)
+{
+
+ if (pEASData->pVoiceMgr->pGlobalDLS)
+ DLSCleanup(pEASData->hwInstData, pEASData->pVoiceMgr->pGlobalDLS);
+
+ pEASData->pVoiceMgr->pGlobalDLS = pDLS;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * VMSetDLSLib()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Sets the DLS library to be used by the synthesizer
+ *
+ * Inputs:
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT VMSetDLSLib (S_SYNTH *pSynth, EAS_DLSLIB_HANDLE pDLS)
+{
+ pSynth->pDLS = pDLS;
+ return EAS_SUCCESS;
+}
+#endif
+
+/*----------------------------------------------------------------------------
+ * VMSetTranposition()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Sets the global key transposition used by the synthesizer.
+ * Transposes all melodic instruments up or down by the specified
+ * amount. Range is limited to +/-12 semitones.
+ *
+ * Inputs:
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+void VMSetTranposition (S_SYNTH *pSynth, EAS_I32 transposition)
+{
+ pSynth->globalTranspose = (EAS_I8) transposition;
+}
+
+/*----------------------------------------------------------------------------
+ * VMGetTranposition()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Gets the global key transposition used by the synthesizer.
+ * Transposes all melodic instruments up or down by the specified
+ * amount. Range is limited to +/-12 semitones.
+ *
+ * Inputs:
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+void VMGetTranposition (S_SYNTH *pSynth, EAS_I32 *pTransposition)
+{
+ *pTransposition = pSynth->globalTranspose;
+}
+
+/*----------------------------------------------------------------------------
+ * VMGetNoteCount()
+ *----------------------------------------------------------------------------
+* Returns the total note count
+*----------------------------------------------------------------------------
+*/
+EAS_I32 VMGetNoteCount (S_SYNTH *pSynth)
+{
+ return pSynth->totalNoteCount;
+}
+
+/*----------------------------------------------------------------------------
+ * VMMIDIShutdown()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Clean up any Synth related system issues.
+ *
+ * Inputs:
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ * None
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+void VMMIDIShutdown (S_EAS_DATA *pEASData, S_SYNTH *pSynth)
+{
+ EAS_INT vSynthNum;
+
+ /* decrement reference count, free if all references are gone */
+ if (--pSynth->refCount > 0)
+ return;
+
+ vSynthNum = pSynth->vSynthNum;
+
+ /* cleanup DLS load */
+#ifdef DLS_SYNTHESIZER
+ /*lint -e{550} result used only in debugging code */
+ if (pSynth->pDLS != NULL)
+ {
+ EAS_RESULT result;
+ if ((result = DLSCleanup(pEASData->hwInstData, pSynth->pDLS)) != EAS_SUCCESS)
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "VMMIDIShutdown: Error %ld cleaning up DLS collection\n", result); */ }
+ pSynth->pDLS = NULL;
+ }
+#endif
+
+ VMReset(pEASData->pVoiceMgr, pSynth, EAS_TRUE);
+
+ /* check Configuration Module for static memory allocation */
+ if (!pEASData->staticMemoryModel)
+ EAS_HWFree(pEASData->hwInstData, pSynth);
+
+ /* clear pointer to MIDI state */
+ pEASData->pVoiceMgr->pSynth[vSynthNum] = NULL;
+}
+
+/*----------------------------------------------------------------------------
+ * VMShutdown()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Clean up any Synth related system issues.
+ *
+ * Inputs:
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ * None
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+void VMShutdown (S_EAS_DATA *pEASData)
+{
+
+ /* don't free a NULL pointer */
+ if (pEASData->pVoiceMgr == NULL)
+ return;
+
+#ifdef DLS_SYNTHESIZER
+ /* if we have a global DLS collection, clean it up */
+ if (pEASData->pVoiceMgr->pGlobalDLS)
+ {
+ DLSCleanup(pEASData->hwInstData, pEASData->pVoiceMgr->pGlobalDLS);
+ pEASData->pVoiceMgr->pGlobalDLS = NULL;
+ }
+#endif
+
+ /* check Configuration Module for static memory allocation */
+ if (!pEASData->staticMemoryModel)
+ EAS_HWFree(pEASData->hwInstData, pEASData->pVoiceMgr);
+ pEASData->pVoiceMgr = NULL;
+}
+
+#ifdef EXTERNAL_AUDIO
+/*----------------------------------------------------------------------------
+ * EAS_RegExtAudioCallback()
+ *----------------------------------------------------------------------------
+ * Register a callback for external audio processing
+ *----------------------------------------------------------------------------
+*/
+void VMRegExtAudioCallback (S_SYNTH *pSynth, EAS_VOID_PTR pInstData, EAS_EXT_PRG_CHG_FUNC cbProgChgFunc, EAS_EXT_EVENT_FUNC cbEventFunc)
+{
+ pSynth->pExtAudioInstData = pInstData;
+ pSynth->cbProgChgFunc = cbProgChgFunc;
+ pSynth->cbEventFunc = cbEventFunc;
+}
+
+/*----------------------------------------------------------------------------
+ * VMGetMIDIControllers()
+ *----------------------------------------------------------------------------
+ * Returns the MIDI controller values on the specified channel
+ *----------------------------------------------------------------------------
+*/
+void VMGetMIDIControllers (S_SYNTH *pSynth, EAS_U8 channel, S_MIDI_CONTROLLERS *pControl)
+{
+ pControl->modWheel = pSynth->channels[channel].modWheel;
+ pControl->volume = pSynth->channels[channel].volume;
+ pControl->pan = pSynth->channels[channel].pan;
+ pControl->expression = pSynth->channels[channel].expression;
+ pControl->channelPressure = pSynth->channels[channel].channelPressure;
+
+#ifdef _REVERB
+ pControl->reverbSend = pSynth->channels[channel].reverbSend;
+#endif
+
+#ifdef _CHORUSE
+ pControl->chorusSend = pSynth->channels[channel].chorusSend;
+#endif
+}
+#endif
+
+#ifdef _SPLIT_ARCHITECTURE
+/*----------------------------------------------------------------------------
+ * VMStartFrame()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Starts an audio frame
+ *
+ * Inputs:
+ *
+ * Outputs:
+ * Returns true if EAS_MixEnginePrep should be called (onboard mixing)
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_BOOL VMStartFrame (S_EAS_DATA *pEASData)
+{
+
+ /* init counter for voices starts in split architecture */
+#ifdef MAX_VOICE_STARTS
+ pVoiceMgr->numVoiceStarts = 0;
+#endif
+
+ return pFrameInterface->pfStartFrame(pEASData->pVoiceMgr->pFrameBuffer);
+}
+
+/*----------------------------------------------------------------------------
+ * VMEndFrame()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Stops an audio frame
+ *
+ * Inputs:
+ *
+ * Outputs:
+ * Returns true if EAS_MixEnginePost should be called (onboard mixing)
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_BOOL VMEndFrame (S_EAS_DATA *pEASData)
+{
+
+ return pFrameInterface->pfEndFrame(pEASData->pVoiceMgr->pFrameBuffer, pEASData->pMixBuffer, pEASData->masterGain);
+}
+#endif
+
+#ifdef TEST_HARNESS
+/*----------------------------------------------------------------------------
+ * SanityCheck()
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT VMSanityCheck (EAS_DATA_HANDLE pEASData)
+{
+ S_SYNTH_VOICE *pVoice;
+ S_SYNTH *pSynth;
+ EAS_INT i;
+ EAS_INT j;
+ EAS_INT freeVoices;
+ EAS_INT activeVoices;
+ EAS_INT playingVoices;
+ EAS_INT stolenVoices;
+ EAS_INT releasingVoices;
+ EAS_INT mutingVoices;
+ EAS_INT poolCount[MAX_VIRTUAL_SYNTHESIZERS][NUM_SYNTH_CHANNELS];
+ EAS_INT vSynthNum;
+ EAS_RESULT result = EAS_SUCCESS;
+
+ /* initialize counts */
+ EAS_HWMemSet(poolCount, 0, sizeof(poolCount));
+ freeVoices = activeVoices = playingVoices = stolenVoices = releasingVoices = mutingVoices = 0;
+
+ /* iterate through all voices */
+ for (i = 0; i < MAX_SYNTH_VOICES; i++)
+ {
+ pVoice = &pEASData->pVoiceMgr->voices[i];
+ if (pVoice->voiceState != eVoiceStateFree)
+ {
+ vSynthNum = GET_VSYNTH(pVoice->channel);
+ if (vSynthNum >= MAX_VIRTUAL_SYNTHESIZERS)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "VMSanityCheck: Voice %d has invalid virtual synth number %d\n", i, vSynthNum); */ }
+ result = EAS_FAILURE;
+ continue;
+ }
+ pSynth = pEASData->pVoiceMgr->pSynth[vSynthNum];
+
+ switch (pVoice->voiceState)
+ {
+ case eVoiceStateMuting:
+ activeVoices++;
+ mutingVoices++;
+ break;
+
+ case eVoiceStateStolen:
+ vSynthNum = GET_VSYNTH(pVoice->nextChannel);
+ if (vSynthNum >= MAX_VIRTUAL_SYNTHESIZERS)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "VMSanityCheck: Voice %d has invalid virtual synth number %d\n", i, vSynthNum); */ }
+ result = EAS_FAILURE;
+ continue;
+ }
+ pSynth = pEASData->pVoiceMgr->pSynth[vSynthNum];
+ activeVoices++;
+ stolenVoices++;
+ poolCount[vSynthNum][pSynth->channels[GET_CHANNEL(pVoice->nextChannel)].pool]++;
+ break;
+
+ case eVoiceStateStart:
+ case eVoiceStatePlay:
+ activeVoices++;
+ playingVoices++;
+ poolCount[vSynthNum][pSynth->channels[GET_CHANNEL(pVoice->channel)].pool]++;
+ break;
+
+ case eVoiceStateRelease:
+ activeVoices++;
+ releasingVoices++;
+ poolCount[vSynthNum][pSynth->channels[GET_CHANNEL(pVoice->channel)].pool]++;
+ break;
+
+ default:
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "VMSanityCheck : voice %d in invalid state\n", i); */ }
+ result = EAS_FAILURE;
+ break;
+ }
+ }
+
+ /* count free voices */
+ else
+ freeVoices++;
+ }
+
+ /* dump state info */
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "%d free\n", freeVoices); */ }
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "%d active\n", activeVoices); */ }
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "%d playing\n", playingVoices); */ }
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "%d releasing\n", releasingVoices); */ }
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "%d muting\n", mutingVoices); */ }
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "%d stolen\n", stolenVoices); */ }
+
+ if (pEASData->pVoiceMgr->activeVoices != activeVoices)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Active voice mismatch was %d should be %d\n",
+ pEASData->pVoiceMgr->activeVoices, activeVoices); */ }
+ result = EAS_FAILURE;
+ }
+
+ /* check virtual synth status */
+ for (i = 0; i < MAX_VIRTUAL_SYNTHESIZERS; i++)
+ {
+ if (pEASData->pVoiceMgr->pSynth[i] == NULL)
+ continue;
+
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Synth %d numActiveVoices: %d\n", i, pEASData->pVoiceMgr->pSynth[i]->numActiveVoices); */ }
+ if (pEASData->pVoiceMgr->pSynth[i]->numActiveVoices > MAX_SYNTH_VOICES)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "VMSanityCheck: Synth %d illegal count for numActiveVoices: %d\n", i, pEASData->pVoiceMgr->pSynth[i]->numActiveVoices); */ }
+ result = EAS_FAILURE;
+ }
+ for (j = 0; j < NUM_SYNTH_CHANNELS; j++)
+ {
+ if (poolCount[i][j] != pEASData->pVoiceMgr->pSynth[i]->poolCount[j])
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Pool count mismatch synth %d pool %d, was %d, should be %d\n",
+ i, j, pEASData->pVoiceMgr->pSynth[i]->poolCount[j], poolCount[i][j]); */ }
+ result = EAS_FAILURE;
+ }
+ }
+ }
+
+ return result;
+}
+#endif
+
+
diff --git a/arm-fm-22k/lib_src/eas_wavefile.c b/arm-fm-22k/lib_src/eas_wavefile.c
index d3f3ba0..f24bde2 100644
--- a/arm-fm-22k/lib_src/eas_wavefile.c
+++ b/arm-fm-22k/lib_src/eas_wavefile.c
@@ -1,12 +1,12 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_wavefile.c
- *
- * Contents and purpose:
- * This file implements the wave file parser.
- *
- * Copyright Sonic Network Inc. 2005
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_wavefile.c
+ *
+ * Contents and purpose:
+ * This file implements the wave file parser.
+ *
+ * Copyright Sonic Network Inc. 2005
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,849 +19,849 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 852 $
- * $Date: 2007-09-04 11:43:49 -0700 (Tue, 04 Sep 2007) $
- *----------------------------------------------------------------------------
-*/
-
-#include "eas_data.h"
-#include "eas_report.h"
-#include "eas_host.h"
-#include "eas_config.h"
-#include "eas_parser.h"
-#include "eas_pcm.h"
-#include "eas_wavefile.h"
-
-/* lint is choking on the ARM math.h file, so we declare the log10 function here */
-extern double log10(double x);
-
-/* increase gain to compensate for loss in mixer */
-#define WAVE_GAIN_OFFSET 6
-
-/* constant for 1200 / log10(2.0) */
-#define PITCH_CENTS_CONVERSION 3986.313714
-
-/*----------------------------------------------------------------------------
- * WAVE file defines
- *----------------------------------------------------------------------------
-*/
-/* RIFF chunks */
-#define CHUNK_TYPE(a,b,c,d) ( \
- ( ((EAS_U32)(a) & 0xFF) << 24 ) \
- + ( ((EAS_U32)(b) & 0xFF) << 16 ) \
- + ( ((EAS_U32)(c) & 0xFF) << 8 ) \
- + ( ((EAS_U32)(d) & 0xFF) ) )
-
-#define CHUNK_RIFF CHUNK_TYPE('R','I','F','F')
-#define CHUNK_WAVE CHUNK_TYPE('W','A','V','E')
-#define CHUNK_FMT CHUNK_TYPE('f','m','t',' ')
-#define CHUNK_DATA CHUNK_TYPE('d','a','t','a')
-#define CHUNK_LIST CHUNK_TYPE('L','I','S','T')
-#define CHUNK_INFO CHUNK_TYPE('I','N','F','O')
-#define CHUNK_INAM CHUNK_TYPE('I','N','A','M')
-#define CHUNK_ICOP CHUNK_TYPE('I','C','O','P')
-#define CHUNK_IART CHUNK_TYPE('I','A','R','T')
-
-/* wave file format identifiers */
-#define WAVE_FORMAT_PCM 0x0001
-#define WAVE_FORMAT_IMA_ADPCM 0x0011
-
-/* file size for streamed file */
-#define FILE_SIZE_STREAMING 0x80000000
-
-/*----------------------------------------------------------------------------
- * prototypes
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT WaveCheckFileType (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle, EAS_VOID_PTR *pHandle, EAS_I32 offset);
-static EAS_RESULT WavePrepare (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
-static EAS_RESULT WaveState (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_STATE *pState);
-static EAS_RESULT WaveClose (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
-static EAS_RESULT WaveReset (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
-static EAS_RESULT WaveLocate (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 time, EAS_BOOL *pParserLocate);
-static EAS_RESULT WavePause (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
-static EAS_RESULT WaveResume (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
-static EAS_RESULT WaveSetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value);
-static EAS_RESULT WaveGetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue);
-static EAS_RESULT WaveParseHeader (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle, S_WAVE_STATE *pWaveData);
-static EAS_RESULT WaveGetMetaData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 *pMediaLength);
-
-#ifdef MMAPI_SUPPORT
-static EAS_RESULT SaveFmtChunk (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle, S_WAVE_STATE *pWaveData, EAS_I32 size);
-#endif
-
-/*----------------------------------------------------------------------------
- *
- * EAS_Wave_Parser
- *
- * This structure contains the functional interface for the Wave file parser
- *----------------------------------------------------------------------------
-*/
-const S_FILE_PARSER_INTERFACE EAS_Wave_Parser =
-{
- WaveCheckFileType,
- WavePrepare,
- NULL,
- NULL,
- WaveState,
- WaveClose,
- WaveReset,
- WavePause,
- WaveResume,
- WaveLocate,
- WaveSetData,
- WaveGetData,
- WaveGetMetaData
-};
-
-/*----------------------------------------------------------------------------
- * WaveCheckFileType()
- *----------------------------------------------------------------------------
- * Purpose:
- * Check the file type to see if we can parse it
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT WaveCheckFileType (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle, EAS_VOID_PTR *pHandle, EAS_I32 offset)
-{
- S_WAVE_STATE *pWaveData;
-
- /* zero the memory to insure complete initialization */
- *pHandle = NULL;
-
- /* read the file header */
- if (WaveParseHeader(pEASData, fileHandle, NULL) == EAS_SUCCESS)
- {
-
- /* check for static memory allocation */
- if (pEASData->staticMemoryModel)
- pWaveData = EAS_CMEnumData(EAS_CM_WAVE_DATA);
- else
- pWaveData = EAS_HWMalloc(pEASData->hwInstData, sizeof(S_WAVE_STATE));
- if (!pWaveData)
- return EAS_ERROR_MALLOC_FAILED;
- EAS_HWMemSet(pWaveData, 0, sizeof(S_WAVE_STATE));
-
- /* return a pointer to the instance data */
- pWaveData->fileHandle = fileHandle;
- pWaveData->fileOffset = offset;
- *pHandle = pWaveData;
- }
-
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * WavePrepare()
- *----------------------------------------------------------------------------
- * Purpose:
- * Prepare to parse the file.
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT WavePrepare (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
-{
- S_WAVE_STATE *pWaveData;
- EAS_RESULT result;
-
- /* validate parser state */
- pWaveData = (S_WAVE_STATE*) pInstData;
- if (pWaveData->streamHandle != NULL)
- return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
-
- /* back to start of file */
- pWaveData->time = 0;
- if ((result = EAS_HWFileSeek(pEASData->hwInstData, pWaveData->fileHandle, pWaveData->fileOffset)) != EAS_SUCCESS)
- return result;
-
- /* parse the file header */
- if ((result = WaveParseHeader(pEASData, pWaveData->fileHandle, pWaveData)) != EAS_SUCCESS)
- return result;
-
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * WaveState()
- *----------------------------------------------------------------------------
- * Purpose:
- * Returns the current state of the stream
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- * pState - pointer to variable to store state
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- * Notes:
- * This interface is also exposed in the internal library for use by the other modules.
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT WaveState (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_STATE *pState)
-{
- S_WAVE_STATE *pWaveData;
-
- /* return current state */
- pWaveData = (S_WAVE_STATE*) pInstData;
- if (pWaveData->streamHandle)
- return EAS_PEState(pEASData, pWaveData->streamHandle, pState);
-
- /* if no stream handle, and time is not zero, we are done */
- if (pWaveData->time > 0)
- *pState = EAS_STATE_STOPPED;
- else
- *pState = EAS_STATE_OPEN;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * WaveClose()
- *----------------------------------------------------------------------------
- * Purpose:
- * Close the file and clean up
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT WaveClose (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
-{
- S_WAVE_STATE *pWaveData;
- EAS_RESULT result;
-
- pWaveData = (S_WAVE_STATE*) pInstData;
-
- /* close the stream */
- if (pWaveData->streamHandle)
- {
- if ((result = EAS_PEClose(pEASData, pWaveData->streamHandle)) != EAS_SUCCESS)
- return result;
- pWaveData->streamHandle = NULL;
- }
-
- /* if using dynamic memory, free it */
- if (!pEASData->staticMemoryModel)
- {
-
-#ifdef MMAPI_SUPPORT
- /* need to free the fmt chunk */
- if (pWaveData->fmtChunk != NULL)
- EAS_HWFree(pEASData->hwInstData, pWaveData->fmtChunk);
-#endif
-
- /* free the instance data */
- EAS_HWFree(pEASData->hwInstData, pWaveData);
-
- }
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * WaveReset()
- *----------------------------------------------------------------------------
- * Purpose:
- * Reset the sequencer. Used for locating backwards in the file.
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT WaveReset (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
-{
- EAS_PCM_HANDLE streamHandle;
-
- /* reset to first byte of data in the stream */
- streamHandle = ((S_WAVE_STATE*)pInstData)->streamHandle;
- if (streamHandle)
- return EAS_PEReset(pEASData, streamHandle);
- return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
-}
-
-/*----------------------------------------------------------------------------
- * WaveLocate()
- *----------------------------------------------------------------------------
- * Purpose:
- * Rewind/fast-forward in file.
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- * time - time (in msecs)
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, pParserLocate) reserved for future use */
-static EAS_RESULT WaveLocate (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 time, EAS_BOOL *pParserLocate)
-{
- EAS_PCM_HANDLE streamHandle;
-
- /* reset to first byte of data in the stream */
- streamHandle = ((S_WAVE_STATE*)pInstData)->streamHandle;
- if (streamHandle)
- return EAS_PELocate(pEASData, streamHandle, time);
- return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
-}
-
-/*----------------------------------------------------------------------------
- * WavePause()
- *----------------------------------------------------------------------------
- * Purpose:
- * Mute and stop rendering a PCM stream. Sets the gain target to zero and stops the playback
- * at the end of the next audio frame.
- *
- * Inputs:
- * pEASData - pointer to EAS library instance data
- * handle - pointer to S_WAVE_STATE for this stream
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, pEASData) reserved for future use */
-static EAS_RESULT WavePause (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
-{
- EAS_PCM_HANDLE streamHandle;
-
- /* pause the stream */
- streamHandle = ((S_WAVE_STATE*)pInstData)->streamHandle;
- if (streamHandle)
- return EAS_PEPause(pEASData, streamHandle);
- return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
-}
-
-/*----------------------------------------------------------------------------
- * WaveResume()
- *----------------------------------------------------------------------------
- * Purpose:
- * Resume rendering a PCM stream. Sets the gain target back to its
- * previous setting and restarts playback at the end of the next audio
- * frame.
- *
- * Inputs:
- * pEASData - pointer to EAS library instance data
- * handle - pointer to S_WAVE_STATE for this stream
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, pEASData) reserved for future use */
-static EAS_RESULT WaveResume (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
-{
- EAS_PCM_HANDLE streamHandle;
-
- /* resume the stream */
- streamHandle = ((S_WAVE_STATE*)pInstData)->streamHandle;
- if (streamHandle)
- return EAS_PEResume(pEASData, streamHandle);
- return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
-}
-
-/*----------------------------------------------------------------------------
- * WaveSetData()
- *----------------------------------------------------------------------------
- * Purpose:
- *
- * Inputs:
- * pEASData - pointer to EAS library instance data
- * handle - pointer to S_WAVE_STATE for this stream
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT WaveSetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value)
-{
- S_WAVE_STATE *pWaveData = (S_WAVE_STATE*) pInstData;
-
- switch (param)
- {
- /* set metadata callback */
- case PARSER_DATA_METADATA_CB:
- EAS_HWMemCpy(&pWaveData->metadata, (void*) value, sizeof(S_METADATA_CB));
- return EAS_SUCCESS;
-
- case PARSER_DATA_PLAYBACK_RATE:
- value = (EAS_I32) (PITCH_CENTS_CONVERSION * log10((double) value / (double) (1 << 28)));
- return EAS_PEUpdatePitch(pEASData, pWaveData->streamHandle, (EAS_I16) value);
-
- case PARSER_DATA_VOLUME:
- return EAS_PEUpdateVolume(pEASData, pWaveData->streamHandle, (EAS_I16) value);
-
- default:
- return EAS_ERROR_INVALID_PARAMETER;
- }
-}
-
-/*----------------------------------------------------------------------------
- * WaveGetData()
- *----------------------------------------------------------------------------
- * Purpose:
- *
- * Inputs:
- * pEASData - pointer to EAS library instance data
- * handle - pointer to S_WAVE_STATE for this stream
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, pEASData) reserved for future use */
-static EAS_RESULT WaveGetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue)
-{
- S_WAVE_STATE *pWaveData;
-
- pWaveData = (S_WAVE_STATE*) pInstData;
- switch (param)
- {
- /* return file type as WAVE */
- case PARSER_DATA_FILE_TYPE:
- *pValue = pWaveData->fileType;
- break;
-
-#ifdef MMAPI_SUPPORT
- /* return pointer to 'fmt' chunk */
- case PARSER_DATA_FORMAT:
- *pValue = (EAS_I32) pWaveData->fmtChunk;
- break;
-#endif
-
- case PARSER_DATA_GAIN_OFFSET:
- *pValue = WAVE_GAIN_OFFSET;
- break;
-
- default:
- return EAS_ERROR_INVALID_PARAMETER;
- }
-
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * WaveParseHeader()
- *----------------------------------------------------------------------------
- * Purpose:
- * Parse the WAVE file header.
- *
- * Inputs:
- * pEASData - pointer to EAS library instance data
- * handle - pointer to S_WAVE_STATE for this stream
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT WaveParseHeader (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle, S_WAVE_STATE *pWaveData)
-{
- S_PCM_OPEN_PARAMS params;
- EAS_RESULT result;
- EAS_U32 tag;
- EAS_U32 fileSize;
- EAS_U32 size;
- EAS_I32 pos;
- EAS_I32 audioOffset;
- EAS_U16 usTemp;
- EAS_BOOL parseDone;
- EAS_U32 avgBytesPerSec;
-
- /* init some data (and keep lint happy) */
- params.sampleRate = 0;
- params.size = 0;
- audioOffset = 0;
- params.decoder = 0;
- params.blockSize = 0;
- params.pCallbackFunc = NULL;
- params.cbInstData = NULL;
- params.loopSamples = 0;
- params.fileHandle = fileHandle;
- params.volume = 0x7fff;
- params.envData = 0;
- avgBytesPerSec = 8000;
-
- /* check for 'RIFF' tag */
- if ((result = EAS_HWGetDWord(pEASData->hwInstData, fileHandle, &tag, EAS_TRUE)) != EAS_FALSE)
- return result;
- if (tag != CHUNK_RIFF)
- return EAS_ERROR_UNRECOGNIZED_FORMAT;
-
- /* get size */
- if ((result = EAS_HWGetDWord(pEASData->hwInstData, fileHandle, &fileSize, EAS_FALSE)) != EAS_FALSE)
- return result;
-
- /* check for 'WAVE' tag */
- if ((result = EAS_HWGetDWord(pEASData->hwInstData, fileHandle, &tag, EAS_TRUE)) != EAS_FALSE)
- return result;
- if (tag != CHUNK_WAVE)
- return EAS_ERROR_UNRECOGNIZED_FORMAT;
-
- /* this is enough to say we recognize the file */
- if (pWaveData == NULL)
- return EAS_SUCCESS;
-
- /* check for streaming mode */
- pWaveData->flags = 0;
- pWaveData->mediaLength = -1;
- pWaveData->infoChunkPos = -1;
- pWaveData->infoChunkSize = -1;
- if (fileSize== FILE_SIZE_STREAMING)
- {
- pWaveData->flags |= PCM_FLAGS_STREAMING;
- fileSize = 0x7fffffff;
- }
-
- /* find out where we're at */
- if ((result = EAS_HWFilePos(pEASData->hwInstData, fileHandle, &pos)) != EAS_SUCCESS)
- return result;
- fileSize -= 4;
-
- parseDone = EAS_FALSE;
- for (;;)
- {
- /* get tag and size for next chunk */
- if ((result = EAS_HWGetDWord(pEASData->hwInstData, fileHandle, &tag, EAS_TRUE)) != EAS_FALSE)
- return result;
- if ((result = EAS_HWGetDWord(pEASData->hwInstData, fileHandle, &size, EAS_FALSE)) != EAS_FALSE)
- return result;
-
- /* process chunk */
- pos += 8;
- switch (tag)
- {
- case CHUNK_FMT:
-
-#ifdef MMAPI_SUPPORT
- if ((result = SaveFmtChunk(pEASData, fileHandle, pWaveData, (EAS_I32) size)) != EAS_SUCCESS)
- return result;
-#endif
-
- /* get audio format */
- if ((result = EAS_HWGetWord(pEASData->hwInstData, fileHandle, &usTemp, EAS_FALSE)) != EAS_FALSE)
- return result;
- if (usTemp == WAVE_FORMAT_PCM)
- {
- params.decoder = EAS_DECODER_PCM;
- pWaveData->fileType = EAS_FILE_WAVE_PCM;
- }
- else if (usTemp == WAVE_FORMAT_IMA_ADPCM)
- {
- params.decoder = EAS_DECODER_IMA_ADPCM;
- pWaveData->fileType = EAS_FILE_WAVE_IMA_ADPCM;
- }
- else
- return EAS_ERROR_UNRECOGNIZED_FORMAT;
-
- /* get number of channels */
- if ((result = EAS_HWGetWord(pEASData->hwInstData, fileHandle, &usTemp, EAS_FALSE)) != EAS_FALSE)
- return result;
- if (usTemp == 2)
- pWaveData->flags |= PCM_FLAGS_STEREO;
- else if (usTemp != 1)
- return EAS_ERROR_UNRECOGNIZED_FORMAT;
-
- /* get sample rate */
- if ((result = EAS_HWGetDWord(pEASData->hwInstData, fileHandle, &params.sampleRate, EAS_FALSE)) != EAS_FALSE)
- return result;
-
- /* get stream rate */
- if ((result = EAS_HWGetDWord(pEASData->hwInstData, fileHandle, &avgBytesPerSec, EAS_FALSE)) != EAS_FALSE)
- return result;
-
- /* get block alignment */
- if ((result = EAS_HWGetWord(pEASData->hwInstData, fileHandle, &usTemp, EAS_FALSE)) != EAS_FALSE)
- return result;
- params.blockSize = usTemp;
-
- /* get bits per sample */
- if ((result = EAS_HWGetWord(pEASData->hwInstData, fileHandle, &usTemp, EAS_FALSE)) != EAS_FALSE)
- return result;
-
- /* PCM, must be 8 or 16 bit samples */
- if (params.decoder == EAS_DECODER_PCM)
- {
- if (usTemp == 8)
- pWaveData->flags |= PCM_FLAGS_8_BIT | PCM_FLAGS_UNSIGNED;
- else if (usTemp != 16)
- return EAS_ERROR_UNRECOGNIZED_FORMAT;
- }
-
- /* for IMA ADPCM, we only support mono 4-bit ADPCM */
- else
- {
- if ((usTemp != 4) || (pWaveData->flags & PCM_FLAGS_STEREO))
- return EAS_ERROR_UNRECOGNIZED_FORMAT;
- }
-
- break;
-
- case CHUNK_DATA:
- audioOffset = pos;
- if (pWaveData->flags & PCM_FLAGS_STREAMING)
- {
- params.size = 0x7fffffff;
- parseDone = EAS_TRUE;
- }
- else
- {
- params.size = (EAS_I32) size;
- params.loopStart = size;
- /* use more accurate method if possible */
- if (size <= (0x7fffffff / 1000))
- pWaveData->mediaLength = (EAS_I32) ((size * 1000) / avgBytesPerSec);
- else
- pWaveData->mediaLength = (EAS_I32) (size / (avgBytesPerSec / 1000));
- }
- break;
-
- case CHUNK_LIST:
- /* get the list type */
- if ((result = EAS_HWGetDWord(pEASData->hwInstData, fileHandle, &tag, EAS_TRUE)) != EAS_FALSE)
- return result;
- if (tag == CHUNK_INFO)
- {
- pWaveData->infoChunkPos = pos + 4;
- pWaveData->infoChunkSize = (EAS_I32) size - 4;
- }
- break;
-
- default:
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "WaveParseHeader: %c%c%c%c chunk - %d byte(s) ignored\n",
- (char) (tag >> 24), (char) (tag >> 16), (char) (tag >> 8), (char) tag, size); */ }
- break;
- }
-
- if (parseDone)
- break;
-
- /* subtract header size */
- fileSize -= 8;
-
- /* account for zero-padding on odd length chunks */
- if (size & 1)
- size++;
-
- /* this check works for files with odd length last chunk and no zero-pad */
- if (size >= fileSize)
- {
- if (size > fileSize)
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "WaveParseHeader: '%c%c%c%c' chunk size exceeds length of file or is not zero-padded\n",
- (char) (tag >> 24), (char) (tag >> 16), (char) (tag >> 8), (char) tag, size); */ }
- break;
- }
-
- /* subtract size of data chunk (including any zero-pad) */
- fileSize -= size;
-
- /* seek to next chunk */
- pos += (EAS_I32) size;
- if ((result = EAS_HWFileSeek(pEASData->hwInstData, fileHandle, pos)) != EAS_SUCCESS)
- return result;
- }
-
- /* check for valid header */
- if ((params.sampleRate == 0) || (params.size == 0))
- return EAS_ERROR_UNRECOGNIZED_FORMAT;
-
- /* save the pertinent information */
- pWaveData->audioOffset = audioOffset;
- params.flags = pWaveData->flags;
-
- /* seek to data */
- if ((result = EAS_HWFileSeek(pEASData->hwInstData, fileHandle, audioOffset)) != EAS_SUCCESS)
- return result;
-
- /* open a stream in the PCM engine */
- return EAS_PEOpenStream(pEASData, &params, &pWaveData->streamHandle);
-}
-
-/*----------------------------------------------------------------------------
- * WaveGetMetaData()
- *----------------------------------------------------------------------------
- * Purpose:
- * Process the INFO chunk and return metadata to host
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT WaveGetMetaData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 *pMediaLength)
-{
- S_WAVE_STATE *pWaveData;
- EAS_RESULT result;
- EAS_I32 pos;
- EAS_U32 size;
- EAS_I32 infoSize;
- EAS_U32 tag;
- EAS_I32 restorePos;
- E_EAS_METADATA_TYPE metaType;
- EAS_I32 metaLen;
-
- /* get current position so we can restore it */
- pWaveData = (S_WAVE_STATE*) pInstData;
-
- /* return media length */
- *pMediaLength = pWaveData->mediaLength;
-
- /* did we encounter an INFO chunk? */
- if (pWaveData->infoChunkPos < 0)
- return EAS_SUCCESS;
-
- if ((result = EAS_HWFilePos(pEASData->hwInstData, pWaveData->fileHandle, &restorePos)) != EAS_SUCCESS)
- return result;
-
- /* offset to start of first chunk in INFO chunk */
- pos = pWaveData->infoChunkPos;
- infoSize = pWaveData->infoChunkSize;
-
- /* read all the chunks in the INFO chunk */
- for (;;)
- {
-
- /* seek to next chunk */
- if ((result = EAS_HWFileSeek(pEASData->hwInstData, pWaveData->fileHandle, pos)) != EAS_SUCCESS)
- return result;
-
- /* get tag and size for next chunk */
- if ((result = EAS_HWGetDWord(pEASData->hwInstData, pWaveData->fileHandle, &tag, EAS_TRUE)) != EAS_FALSE)
- return result;
- if ((result = EAS_HWGetDWord(pEASData->hwInstData, pWaveData->fileHandle, &size, EAS_FALSE)) != EAS_FALSE)
- return result;
-
- /* process chunk */
- pos += 8;
- metaType = EAS_METADATA_UNKNOWN;
- switch (tag)
- {
- case CHUNK_INAM:
- metaType = EAS_METADATA_TITLE;
- break;
-
- case CHUNK_IART:
- metaType = EAS_METADATA_AUTHOR;
- break;
-
- case CHUNK_ICOP:
- metaType = EAS_METADATA_COPYRIGHT;
- break;
-
- default:
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "WaveParseHeader: %c%c%c%c chunk - %d byte(s) ignored\n",
- (char) (tag >> 24), (char) (tag >> 16), (char) (tag >> 8), (char) tag, size); */ }
- break;
- }
-
- /* process known metadata */
- if (metaType != EAS_METADATA_UNKNOWN)
- {
- metaLen = pWaveData->metadata.bufferSize - 1;
- if (metaLen > (EAS_I32) size)
- metaLen = (EAS_I32) size;
- if ((result = EAS_HWReadFile(pEASData->hwInstData, pWaveData->fileHandle, pWaveData->metadata.buffer, metaLen, &metaLen)) != EAS_SUCCESS)
- return result;
- pWaveData->metadata.buffer[metaLen] = 0;
- pWaveData->metadata.callback(metaType, pWaveData->metadata.buffer, pWaveData->metadata.pUserData);
- }
-
- /* subtract this block */
- if (size & 1)
- size++;
- infoSize -= (EAS_I32) size + 8;
- if (infoSize == 0)
- break;
- pos += (EAS_I32) size;
- }
-
-
- /* restore original position */
- return EAS_HWFileSeek(pEASData->hwInstData, pWaveData->fileHandle, restorePos);
-}
-
-#ifdef MMAPI_SUPPORT
-/*----------------------------------------------------------------------------
- * SaveFmtChunk()
- *----------------------------------------------------------------------------
- * Purpose:
- * Save the fmt chunk for the MMAPI library
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT SaveFmtChunk (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle, S_WAVE_STATE *pWaveData, EAS_I32 fmtSize)
-{
- EAS_RESULT result;
- EAS_I32 pos;
- EAS_I32 count;
-
- /* save current file position */
- if ((result = EAS_HWFilePos(pEASData->hwInstData, fileHandle, &pos)) != EAS_SUCCESS)
- return result;
-
- /* allocate a chunk of memory */
- pWaveData->fmtChunk = EAS_HWMalloc(pEASData->hwInstData, fmtSize);
- if (!pWaveData->fmtChunk)
- return EAS_ERROR_MALLOC_FAILED;
-
- /* read the fmt chunk into memory */
- if ((result = EAS_HWReadFile(pEASData->hwInstData, fileHandle, pWaveData->fmtChunk, fmtSize, &count)) != EAS_SUCCESS)
- return result;
- if (count != fmtSize)
- return EAS_ERROR_FILE_READ_FAILED;
-
- /* restore file position */
- return EAS_HWFileSeek(pEASData->hwInstData, fileHandle, pos);
-}
-#endif
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 852 $
+ * $Date: 2007-09-04 11:43:49 -0700 (Tue, 04 Sep 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+#include "eas_data.h"
+#include "eas_report.h"
+#include "eas_host.h"
+#include "eas_config.h"
+#include "eas_parser.h"
+#include "eas_pcm.h"
+#include "eas_wavefile.h"
+
+/* lint is choking on the ARM math.h file, so we declare the log10 function here */
+extern double log10(double x);
+
+/* increase gain to compensate for loss in mixer */
+#define WAVE_GAIN_OFFSET 6
+
+/* constant for 1200 / log10(2.0) */
+#define PITCH_CENTS_CONVERSION 3986.313714
+
+/*----------------------------------------------------------------------------
+ * WAVE file defines
+ *----------------------------------------------------------------------------
+*/
+/* RIFF chunks */
+#define CHUNK_TYPE(a,b,c,d) ( \
+ ( ((EAS_U32)(a) & 0xFF) << 24 ) \
+ + ( ((EAS_U32)(b) & 0xFF) << 16 ) \
+ + ( ((EAS_U32)(c) & 0xFF) << 8 ) \
+ + ( ((EAS_U32)(d) & 0xFF) ) )
+
+#define CHUNK_RIFF CHUNK_TYPE('R','I','F','F')
+#define CHUNK_WAVE CHUNK_TYPE('W','A','V','E')
+#define CHUNK_FMT CHUNK_TYPE('f','m','t',' ')
+#define CHUNK_DATA CHUNK_TYPE('d','a','t','a')
+#define CHUNK_LIST CHUNK_TYPE('L','I','S','T')
+#define CHUNK_INFO CHUNK_TYPE('I','N','F','O')
+#define CHUNK_INAM CHUNK_TYPE('I','N','A','M')
+#define CHUNK_ICOP CHUNK_TYPE('I','C','O','P')
+#define CHUNK_IART CHUNK_TYPE('I','A','R','T')
+
+/* wave file format identifiers */
+#define WAVE_FORMAT_PCM 0x0001
+#define WAVE_FORMAT_IMA_ADPCM 0x0011
+
+/* file size for streamed file */
+#define FILE_SIZE_STREAMING 0x80000000
+
+/*----------------------------------------------------------------------------
+ * prototypes
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT WaveCheckFileType (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle, EAS_VOID_PTR *pHandle, EAS_I32 offset);
+static EAS_RESULT WavePrepare (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
+static EAS_RESULT WaveState (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_STATE *pState);
+static EAS_RESULT WaveClose (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
+static EAS_RESULT WaveReset (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
+static EAS_RESULT WaveLocate (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 time, EAS_BOOL *pParserLocate);
+static EAS_RESULT WavePause (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
+static EAS_RESULT WaveResume (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
+static EAS_RESULT WaveSetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value);
+static EAS_RESULT WaveGetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue);
+static EAS_RESULT WaveParseHeader (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle, S_WAVE_STATE *pWaveData);
+static EAS_RESULT WaveGetMetaData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 *pMediaLength);
+
+#ifdef MMAPI_SUPPORT
+static EAS_RESULT SaveFmtChunk (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle, S_WAVE_STATE *pWaveData, EAS_I32 size);
+#endif
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_Wave_Parser
+ *
+ * This structure contains the functional interface for the Wave file parser
+ *----------------------------------------------------------------------------
+*/
+const S_FILE_PARSER_INTERFACE EAS_Wave_Parser =
+{
+ WaveCheckFileType,
+ WavePrepare,
+ NULL,
+ NULL,
+ WaveState,
+ WaveClose,
+ WaveReset,
+ WavePause,
+ WaveResume,
+ WaveLocate,
+ WaveSetData,
+ WaveGetData,
+ WaveGetMetaData
+};
+
+/*----------------------------------------------------------------------------
+ * WaveCheckFileType()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Check the file type to see if we can parse it
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT WaveCheckFileType (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle, EAS_VOID_PTR *pHandle, EAS_I32 offset)
+{
+ S_WAVE_STATE *pWaveData;
+
+ /* zero the memory to insure complete initialization */
+ *pHandle = NULL;
+
+ /* read the file header */
+ if (WaveParseHeader(pEASData, fileHandle, NULL) == EAS_SUCCESS)
+ {
+
+ /* check for static memory allocation */
+ if (pEASData->staticMemoryModel)
+ pWaveData = EAS_CMEnumData(EAS_CM_WAVE_DATA);
+ else
+ pWaveData = EAS_HWMalloc(pEASData->hwInstData, sizeof(S_WAVE_STATE));
+ if (!pWaveData)
+ return EAS_ERROR_MALLOC_FAILED;
+ EAS_HWMemSet(pWaveData, 0, sizeof(S_WAVE_STATE));
+
+ /* return a pointer to the instance data */
+ pWaveData->fileHandle = fileHandle;
+ pWaveData->fileOffset = offset;
+ *pHandle = pWaveData;
+ }
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * WavePrepare()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Prepare to parse the file.
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT WavePrepare (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
+{
+ S_WAVE_STATE *pWaveData;
+ EAS_RESULT result;
+
+ /* validate parser state */
+ pWaveData = (S_WAVE_STATE*) pInstData;
+ if (pWaveData->streamHandle != NULL)
+ return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
+
+ /* back to start of file */
+ pWaveData->time = 0;
+ if ((result = EAS_HWFileSeek(pEASData->hwInstData, pWaveData->fileHandle, pWaveData->fileOffset)) != EAS_SUCCESS)
+ return result;
+
+ /* parse the file header */
+ if ((result = WaveParseHeader(pEASData, pWaveData->fileHandle, pWaveData)) != EAS_SUCCESS)
+ return result;
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * WaveState()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Returns the current state of the stream
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ * pState - pointer to variable to store state
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ * Notes:
+ * This interface is also exposed in the internal library for use by the other modules.
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT WaveState (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_STATE *pState)
+{
+ S_WAVE_STATE *pWaveData;
+
+ /* return current state */
+ pWaveData = (S_WAVE_STATE*) pInstData;
+ if (pWaveData->streamHandle)
+ return EAS_PEState(pEASData, pWaveData->streamHandle, pState);
+
+ /* if no stream handle, and time is not zero, we are done */
+ if (pWaveData->time > 0)
+ *pState = EAS_STATE_STOPPED;
+ else
+ *pState = EAS_STATE_OPEN;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * WaveClose()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Close the file and clean up
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT WaveClose (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
+{
+ S_WAVE_STATE *pWaveData;
+ EAS_RESULT result;
+
+ pWaveData = (S_WAVE_STATE*) pInstData;
+
+ /* close the stream */
+ if (pWaveData->streamHandle)
+ {
+ if ((result = EAS_PEClose(pEASData, pWaveData->streamHandle)) != EAS_SUCCESS)
+ return result;
+ pWaveData->streamHandle = NULL;
+ }
+
+ /* if using dynamic memory, free it */
+ if (!pEASData->staticMemoryModel)
+ {
+
+#ifdef MMAPI_SUPPORT
+ /* need to free the fmt chunk */
+ if (pWaveData->fmtChunk != NULL)
+ EAS_HWFree(pEASData->hwInstData, pWaveData->fmtChunk);
+#endif
+
+ /* free the instance data */
+ EAS_HWFree(pEASData->hwInstData, pWaveData);
+
+ }
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * WaveReset()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Reset the sequencer. Used for locating backwards in the file.
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT WaveReset (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
+{
+ EAS_PCM_HANDLE streamHandle;
+
+ /* reset to first byte of data in the stream */
+ streamHandle = ((S_WAVE_STATE*)pInstData)->streamHandle;
+ if (streamHandle)
+ return EAS_PEReset(pEASData, streamHandle);
+ return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
+}
+
+/*----------------------------------------------------------------------------
+ * WaveLocate()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Rewind/fast-forward in file.
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ * time - time (in msecs)
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pParserLocate) reserved for future use */
+static EAS_RESULT WaveLocate (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 time, EAS_BOOL *pParserLocate)
+{
+ EAS_PCM_HANDLE streamHandle;
+
+ /* reset to first byte of data in the stream */
+ streamHandle = ((S_WAVE_STATE*)pInstData)->streamHandle;
+ if (streamHandle)
+ return EAS_PELocate(pEASData, streamHandle, time);
+ return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
+}
+
+/*----------------------------------------------------------------------------
+ * WavePause()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Mute and stop rendering a PCM stream. Sets the gain target to zero and stops the playback
+ * at the end of the next audio frame.
+ *
+ * Inputs:
+ * pEASData - pointer to EAS library instance data
+ * handle - pointer to S_WAVE_STATE for this stream
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pEASData) reserved for future use */
+static EAS_RESULT WavePause (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
+{
+ EAS_PCM_HANDLE streamHandle;
+
+ /* pause the stream */
+ streamHandle = ((S_WAVE_STATE*)pInstData)->streamHandle;
+ if (streamHandle)
+ return EAS_PEPause(pEASData, streamHandle);
+ return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
+}
+
+/*----------------------------------------------------------------------------
+ * WaveResume()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Resume rendering a PCM stream. Sets the gain target back to its
+ * previous setting and restarts playback at the end of the next audio
+ * frame.
+ *
+ * Inputs:
+ * pEASData - pointer to EAS library instance data
+ * handle - pointer to S_WAVE_STATE for this stream
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pEASData) reserved for future use */
+static EAS_RESULT WaveResume (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
+{
+ EAS_PCM_HANDLE streamHandle;
+
+ /* resume the stream */
+ streamHandle = ((S_WAVE_STATE*)pInstData)->streamHandle;
+ if (streamHandle)
+ return EAS_PEResume(pEASData, streamHandle);
+ return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
+}
+
+/*----------------------------------------------------------------------------
+ * WaveSetData()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ *
+ * Inputs:
+ * pEASData - pointer to EAS library instance data
+ * handle - pointer to S_WAVE_STATE for this stream
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT WaveSetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value)
+{
+ S_WAVE_STATE *pWaveData = (S_WAVE_STATE*) pInstData;
+
+ switch (param)
+ {
+ /* set metadata callback */
+ case PARSER_DATA_METADATA_CB:
+ EAS_HWMemCpy(&pWaveData->metadata, (void*) value, sizeof(S_METADATA_CB));
+ return EAS_SUCCESS;
+
+ case PARSER_DATA_PLAYBACK_RATE:
+ value = (EAS_I32) (PITCH_CENTS_CONVERSION * log10((double) value / (double) (1 << 28)));
+ return EAS_PEUpdatePitch(pEASData, pWaveData->streamHandle, (EAS_I16) value);
+
+ case PARSER_DATA_VOLUME:
+ return EAS_PEUpdateVolume(pEASData, pWaveData->streamHandle, (EAS_I16) value);
+
+ default:
+ return EAS_ERROR_INVALID_PARAMETER;
+ }
+}
+
+/*----------------------------------------------------------------------------
+ * WaveGetData()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ *
+ * Inputs:
+ * pEASData - pointer to EAS library instance data
+ * handle - pointer to S_WAVE_STATE for this stream
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pEASData) reserved for future use */
+static EAS_RESULT WaveGetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue)
+{
+ S_WAVE_STATE *pWaveData;
+
+ pWaveData = (S_WAVE_STATE*) pInstData;
+ switch (param)
+ {
+ /* return file type as WAVE */
+ case PARSER_DATA_FILE_TYPE:
+ *pValue = pWaveData->fileType;
+ break;
+
+#ifdef MMAPI_SUPPORT
+ /* return pointer to 'fmt' chunk */
+ case PARSER_DATA_FORMAT:
+ *pValue = (EAS_I32) pWaveData->fmtChunk;
+ break;
+#endif
+
+ case PARSER_DATA_GAIN_OFFSET:
+ *pValue = WAVE_GAIN_OFFSET;
+ break;
+
+ default:
+ return EAS_ERROR_INVALID_PARAMETER;
+ }
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * WaveParseHeader()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Parse the WAVE file header.
+ *
+ * Inputs:
+ * pEASData - pointer to EAS library instance data
+ * handle - pointer to S_WAVE_STATE for this stream
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT WaveParseHeader (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle, S_WAVE_STATE *pWaveData)
+{
+ S_PCM_OPEN_PARAMS params;
+ EAS_RESULT result;
+ EAS_U32 tag;
+ EAS_U32 fileSize;
+ EAS_U32 size;
+ EAS_I32 pos;
+ EAS_I32 audioOffset;
+ EAS_U16 usTemp;
+ EAS_BOOL parseDone;
+ EAS_U32 avgBytesPerSec;
+
+ /* init some data (and keep lint happy) */
+ params.sampleRate = 0;
+ params.size = 0;
+ audioOffset = 0;
+ params.decoder = 0;
+ params.blockSize = 0;
+ params.pCallbackFunc = NULL;
+ params.cbInstData = NULL;
+ params.loopSamples = 0;
+ params.fileHandle = fileHandle;
+ params.volume = 0x7fff;
+ params.envData = 0;
+ avgBytesPerSec = 8000;
+
+ /* check for 'RIFF' tag */
+ if ((result = EAS_HWGetDWord(pEASData->hwInstData, fileHandle, &tag, EAS_TRUE)) != EAS_FALSE)
+ return result;
+ if (tag != CHUNK_RIFF)
+ return EAS_ERROR_UNRECOGNIZED_FORMAT;
+
+ /* get size */
+ if ((result = EAS_HWGetDWord(pEASData->hwInstData, fileHandle, &fileSize, EAS_FALSE)) != EAS_FALSE)
+ return result;
+
+ /* check for 'WAVE' tag */
+ if ((result = EAS_HWGetDWord(pEASData->hwInstData, fileHandle, &tag, EAS_TRUE)) != EAS_FALSE)
+ return result;
+ if (tag != CHUNK_WAVE)
+ return EAS_ERROR_UNRECOGNIZED_FORMAT;
+
+ /* this is enough to say we recognize the file */
+ if (pWaveData == NULL)
+ return EAS_SUCCESS;
+
+ /* check for streaming mode */
+ pWaveData->flags = 0;
+ pWaveData->mediaLength = -1;
+ pWaveData->infoChunkPos = -1;
+ pWaveData->infoChunkSize = -1;
+ if (fileSize== FILE_SIZE_STREAMING)
+ {
+ pWaveData->flags |= PCM_FLAGS_STREAMING;
+ fileSize = 0x7fffffff;
+ }
+
+ /* find out where we're at */
+ if ((result = EAS_HWFilePos(pEASData->hwInstData, fileHandle, &pos)) != EAS_SUCCESS)
+ return result;
+ fileSize -= 4;
+
+ parseDone = EAS_FALSE;
+ for (;;)
+ {
+ /* get tag and size for next chunk */
+ if ((result = EAS_HWGetDWord(pEASData->hwInstData, fileHandle, &tag, EAS_TRUE)) != EAS_FALSE)
+ return result;
+ if ((result = EAS_HWGetDWord(pEASData->hwInstData, fileHandle, &size, EAS_FALSE)) != EAS_FALSE)
+ return result;
+
+ /* process chunk */
+ pos += 8;
+ switch (tag)
+ {
+ case CHUNK_FMT:
+
+#ifdef MMAPI_SUPPORT
+ if ((result = SaveFmtChunk(pEASData, fileHandle, pWaveData, (EAS_I32) size)) != EAS_SUCCESS)
+ return result;
+#endif
+
+ /* get audio format */
+ if ((result = EAS_HWGetWord(pEASData->hwInstData, fileHandle, &usTemp, EAS_FALSE)) != EAS_FALSE)
+ return result;
+ if (usTemp == WAVE_FORMAT_PCM)
+ {
+ params.decoder = EAS_DECODER_PCM;
+ pWaveData->fileType = EAS_FILE_WAVE_PCM;
+ }
+ else if (usTemp == WAVE_FORMAT_IMA_ADPCM)
+ {
+ params.decoder = EAS_DECODER_IMA_ADPCM;
+ pWaveData->fileType = EAS_FILE_WAVE_IMA_ADPCM;
+ }
+ else
+ return EAS_ERROR_UNRECOGNIZED_FORMAT;
+
+ /* get number of channels */
+ if ((result = EAS_HWGetWord(pEASData->hwInstData, fileHandle, &usTemp, EAS_FALSE)) != EAS_FALSE)
+ return result;
+ if (usTemp == 2)
+ pWaveData->flags |= PCM_FLAGS_STEREO;
+ else if (usTemp != 1)
+ return EAS_ERROR_UNRECOGNIZED_FORMAT;
+
+ /* get sample rate */
+ if ((result = EAS_HWGetDWord(pEASData->hwInstData, fileHandle, &params.sampleRate, EAS_FALSE)) != EAS_FALSE)
+ return result;
+
+ /* get stream rate */
+ if ((result = EAS_HWGetDWord(pEASData->hwInstData, fileHandle, &avgBytesPerSec, EAS_FALSE)) != EAS_FALSE)
+ return result;
+
+ /* get block alignment */
+ if ((result = EAS_HWGetWord(pEASData->hwInstData, fileHandle, &usTemp, EAS_FALSE)) != EAS_FALSE)
+ return result;
+ params.blockSize = usTemp;
+
+ /* get bits per sample */
+ if ((result = EAS_HWGetWord(pEASData->hwInstData, fileHandle, &usTemp, EAS_FALSE)) != EAS_FALSE)
+ return result;
+
+ /* PCM, must be 8 or 16 bit samples */
+ if (params.decoder == EAS_DECODER_PCM)
+ {
+ if (usTemp == 8)
+ pWaveData->flags |= PCM_FLAGS_8_BIT | PCM_FLAGS_UNSIGNED;
+ else if (usTemp != 16)
+ return EAS_ERROR_UNRECOGNIZED_FORMAT;
+ }
+
+ /* for IMA ADPCM, we only support mono 4-bit ADPCM */
+ else
+ {
+ if ((usTemp != 4) || (pWaveData->flags & PCM_FLAGS_STEREO))
+ return EAS_ERROR_UNRECOGNIZED_FORMAT;
+ }
+
+ break;
+
+ case CHUNK_DATA:
+ audioOffset = pos;
+ if (pWaveData->flags & PCM_FLAGS_STREAMING)
+ {
+ params.size = 0x7fffffff;
+ parseDone = EAS_TRUE;
+ }
+ else
+ {
+ params.size = (EAS_I32) size;
+ params.loopStart = size;
+ /* use more accurate method if possible */
+ if (size <= (0x7fffffff / 1000))
+ pWaveData->mediaLength = (EAS_I32) ((size * 1000) / avgBytesPerSec);
+ else
+ pWaveData->mediaLength = (EAS_I32) (size / (avgBytesPerSec / 1000));
+ }
+ break;
+
+ case CHUNK_LIST:
+ /* get the list type */
+ if ((result = EAS_HWGetDWord(pEASData->hwInstData, fileHandle, &tag, EAS_TRUE)) != EAS_FALSE)
+ return result;
+ if (tag == CHUNK_INFO)
+ {
+ pWaveData->infoChunkPos = pos + 4;
+ pWaveData->infoChunkSize = (EAS_I32) size - 4;
+ }
+ break;
+
+ default:
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "WaveParseHeader: %c%c%c%c chunk - %d byte(s) ignored\n",
+ (char) (tag >> 24), (char) (tag >> 16), (char) (tag >> 8), (char) tag, size); */ }
+ break;
+ }
+
+ if (parseDone)
+ break;
+
+ /* subtract header size */
+ fileSize -= 8;
+
+ /* account for zero-padding on odd length chunks */
+ if (size & 1)
+ size++;
+
+ /* this check works for files with odd length last chunk and no zero-pad */
+ if (size >= fileSize)
+ {
+ if (size > fileSize)
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "WaveParseHeader: '%c%c%c%c' chunk size exceeds length of file or is not zero-padded\n",
+ (char) (tag >> 24), (char) (tag >> 16), (char) (tag >> 8), (char) tag, size); */ }
+ break;
+ }
+
+ /* subtract size of data chunk (including any zero-pad) */
+ fileSize -= size;
+
+ /* seek to next chunk */
+ pos += (EAS_I32) size;
+ if ((result = EAS_HWFileSeek(pEASData->hwInstData, fileHandle, pos)) != EAS_SUCCESS)
+ return result;
+ }
+
+ /* check for valid header */
+ if ((params.sampleRate == 0) || (params.size == 0))
+ return EAS_ERROR_UNRECOGNIZED_FORMAT;
+
+ /* save the pertinent information */
+ pWaveData->audioOffset = audioOffset;
+ params.flags = pWaveData->flags;
+
+ /* seek to data */
+ if ((result = EAS_HWFileSeek(pEASData->hwInstData, fileHandle, audioOffset)) != EAS_SUCCESS)
+ return result;
+
+ /* open a stream in the PCM engine */
+ return EAS_PEOpenStream(pEASData, &params, &pWaveData->streamHandle);
+}
+
+/*----------------------------------------------------------------------------
+ * WaveGetMetaData()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Process the INFO chunk and return metadata to host
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT WaveGetMetaData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 *pMediaLength)
+{
+ S_WAVE_STATE *pWaveData;
+ EAS_RESULT result;
+ EAS_I32 pos;
+ EAS_U32 size;
+ EAS_I32 infoSize;
+ EAS_U32 tag;
+ EAS_I32 restorePos;
+ E_EAS_METADATA_TYPE metaType;
+ EAS_I32 metaLen;
+
+ /* get current position so we can restore it */
+ pWaveData = (S_WAVE_STATE*) pInstData;
+
+ /* return media length */
+ *pMediaLength = pWaveData->mediaLength;
+
+ /* did we encounter an INFO chunk? */
+ if (pWaveData->infoChunkPos < 0)
+ return EAS_SUCCESS;
+
+ if ((result = EAS_HWFilePos(pEASData->hwInstData, pWaveData->fileHandle, &restorePos)) != EAS_SUCCESS)
+ return result;
+
+ /* offset to start of first chunk in INFO chunk */
+ pos = pWaveData->infoChunkPos;
+ infoSize = pWaveData->infoChunkSize;
+
+ /* read all the chunks in the INFO chunk */
+ for (;;)
+ {
+
+ /* seek to next chunk */
+ if ((result = EAS_HWFileSeek(pEASData->hwInstData, pWaveData->fileHandle, pos)) != EAS_SUCCESS)
+ return result;
+
+ /* get tag and size for next chunk */
+ if ((result = EAS_HWGetDWord(pEASData->hwInstData, pWaveData->fileHandle, &tag, EAS_TRUE)) != EAS_FALSE)
+ return result;
+ if ((result = EAS_HWGetDWord(pEASData->hwInstData, pWaveData->fileHandle, &size, EAS_FALSE)) != EAS_FALSE)
+ return result;
+
+ /* process chunk */
+ pos += 8;
+ metaType = EAS_METADATA_UNKNOWN;
+ switch (tag)
+ {
+ case CHUNK_INAM:
+ metaType = EAS_METADATA_TITLE;
+ break;
+
+ case CHUNK_IART:
+ metaType = EAS_METADATA_AUTHOR;
+ break;
+
+ case CHUNK_ICOP:
+ metaType = EAS_METADATA_COPYRIGHT;
+ break;
+
+ default:
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "WaveParseHeader: %c%c%c%c chunk - %d byte(s) ignored\n",
+ (char) (tag >> 24), (char) (tag >> 16), (char) (tag >> 8), (char) tag, size); */ }
+ break;
+ }
+
+ /* process known metadata */
+ if (metaType != EAS_METADATA_UNKNOWN)
+ {
+ metaLen = pWaveData->metadata.bufferSize - 1;
+ if (metaLen > (EAS_I32) size)
+ metaLen = (EAS_I32) size;
+ if ((result = EAS_HWReadFile(pEASData->hwInstData, pWaveData->fileHandle, pWaveData->metadata.buffer, metaLen, &metaLen)) != EAS_SUCCESS)
+ return result;
+ pWaveData->metadata.buffer[metaLen] = 0;
+ pWaveData->metadata.callback(metaType, pWaveData->metadata.buffer, pWaveData->metadata.pUserData);
+ }
+
+ /* subtract this block */
+ if (size & 1)
+ size++;
+ infoSize -= (EAS_I32) size + 8;
+ if (infoSize == 0)
+ break;
+ pos += (EAS_I32) size;
+ }
+
+
+ /* restore original position */
+ return EAS_HWFileSeek(pEASData->hwInstData, pWaveData->fileHandle, restorePos);
+}
+
+#ifdef MMAPI_SUPPORT
+/*----------------------------------------------------------------------------
+ * SaveFmtChunk()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Save the fmt chunk for the MMAPI library
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT SaveFmtChunk (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle, S_WAVE_STATE *pWaveData, EAS_I32 fmtSize)
+{
+ EAS_RESULT result;
+ EAS_I32 pos;
+ EAS_I32 count;
+
+ /* save current file position */
+ if ((result = EAS_HWFilePos(pEASData->hwInstData, fileHandle, &pos)) != EAS_SUCCESS)
+ return result;
+
+ /* allocate a chunk of memory */
+ pWaveData->fmtChunk = EAS_HWMalloc(pEASData->hwInstData, fmtSize);
+ if (!pWaveData->fmtChunk)
+ return EAS_ERROR_MALLOC_FAILED;
+
+ /* read the fmt chunk into memory */
+ if ((result = EAS_HWReadFile(pEASData->hwInstData, fileHandle, pWaveData->fmtChunk, fmtSize, &count)) != EAS_SUCCESS)
+ return result;
+ if (count != fmtSize)
+ return EAS_ERROR_FILE_READ_FAILED;
+
+ /* restore file position */
+ return EAS_HWFileSeek(pEASData->hwInstData, fileHandle, pos);
+}
+#endif
+
diff --git a/arm-fm-22k/lib_src/eas_wavefile.h b/arm-fm-22k/lib_src/eas_wavefile.h
index b8b76df..f8814a8 100644
--- a/arm-fm-22k/lib_src/eas_wavefile.h
+++ b/arm-fm-22k/lib_src/eas_wavefile.h
@@ -1,12 +1,12 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_wavefile.h
- *
- * Contents and purpose:
- * Static data block for wave file parser.
- *
- * Copyright Sonic Network Inc. 2005
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_wavefile.h
+ *
+ * Contents and purpose:
+ * Static data block for wave file parser.
+ *
+ * Copyright Sonic Network Inc. 2005
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,45 +19,45 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 439 $
- * $Date: 2006-10-26 11:53:18 -0700 (Thu, 26 Oct 2006) $
- *----------------------------------------------------------------------------
-*/
-
-#ifndef _EAS_WAVEFILE_H
-#define _EAS_WAVEFILE_H
-
-#include "eas_data.h"
-#include "eas_pcm.h"
-
-/*----------------------------------------------------------------------------
- *
- * S_WAVE_STATE
- *
- * This structure contains the WAVE file parser state information
- *----------------------------------------------------------------------------
-*/
-typedef struct s_wave_state_tag
-{
- EAS_FILE_HANDLE fileHandle;
- EAS_PCM_HANDLE streamHandle;
- S_METADATA_CB metadata;
- EAS_U32 time;
- EAS_I32 fileOffset;
- EAS_I32 audioOffset;
- EAS_I32 mediaLength;
- EAS_U32 audioSize;
- EAS_U32 flags;
- EAS_I16 fileType;
-#ifdef MMAPI_SUPPORT
- EAS_VOID_PTR fmtChunk;
-#endif
- EAS_I32 infoChunkPos;
- EAS_I32 infoChunkSize;
-} S_WAVE_STATE;
-
-#endif
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 439 $
+ * $Date: 2006-10-26 11:53:18 -0700 (Thu, 26 Oct 2006) $
+ *----------------------------------------------------------------------------
+*/
+
+#ifndef _EAS_WAVEFILE_H
+#define _EAS_WAVEFILE_H
+
+#include "eas_data.h"
+#include "eas_pcm.h"
+
+/*----------------------------------------------------------------------------
+ *
+ * S_WAVE_STATE
+ *
+ * This structure contains the WAVE file parser state information
+ *----------------------------------------------------------------------------
+*/
+typedef struct s_wave_state_tag
+{
+ EAS_FILE_HANDLE fileHandle;
+ EAS_PCM_HANDLE streamHandle;
+ S_METADATA_CB metadata;
+ EAS_U32 time;
+ EAS_I32 fileOffset;
+ EAS_I32 audioOffset;
+ EAS_I32 mediaLength;
+ EAS_U32 audioSize;
+ EAS_U32 flags;
+ EAS_I16 fileType;
+#ifdef MMAPI_SUPPORT
+ EAS_VOID_PTR fmtChunk;
+#endif
+ EAS_I32 infoChunkPos;
+ EAS_I32 infoChunkSize;
+} S_WAVE_STATE;
+
+#endif
+
diff --git a/arm-fm-22k/lib_src/eas_wavefiledata.c b/arm-fm-22k/lib_src/eas_wavefiledata.c
index 3742aa6..c224a6c 100644
--- a/arm-fm-22k/lib_src/eas_wavefiledata.c
+++ b/arm-fm-22k/lib_src/eas_wavefiledata.c
@@ -1,12 +1,12 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_wavefiledata.c
- *
- * Contents and purpose:
- * Static data block for wave file parser.
- *
- * Copyright Sonic Network Inc. 2005
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_wavefiledata.c
+ *
+ * Contents and purpose:
+ * Static data block for wave file parser.
+ *
+ * Copyright Sonic Network Inc. 2005
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,15 +19,15 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 547 $
- * $Date: 2007-01-31 16:30:17 -0800 (Wed, 31 Jan 2007) $
- *----------------------------------------------------------------------------
-*/
-
-#include "eas_wavefile.h"
-
-S_WAVE_STATE eas_WaveData;
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 547 $
+ * $Date: 2007-01-31 16:30:17 -0800 (Wed, 31 Jan 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+#include "eas_wavefile.h"
+
+S_WAVE_STATE eas_WaveData;
+
diff --git a/arm-hybrid-22k/host_src/eas.h b/arm-hybrid-22k/host_src/eas.h
index 0bb04fe..c64af49 100644
--- a/arm-hybrid-22k/host_src/eas.h
+++ b/arm-hybrid-22k/host_src/eas.h
@@ -1,17 +1,17 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas.h
- *
- * Contents and purpose:
- * The public interface header for the EAS synthesizer.
- *
- * This header only contains declarations that are specific
- * to this implementation.
- *
- * DO NOT MODIFY THIS FILE!
- *
- * Copyright Sonic Network Inc. 2005, 2006
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas.h
+ *
+ * Contents and purpose:
+ * The public interface header for the EAS synthesizer.
+ *
+ * This header only contains declarations that are specific
+ * to this implementation.
+ *
+ * DO NOT MODIFY THIS FILE!
+ *
+ * Copyright Sonic Network Inc. 2005, 2006
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -24,1039 +24,1039 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 852 $
- * $Date: 2007-09-04 11:43:49 -0700 (Tue, 04 Sep 2007) $
- *----------------------------------------------------------------------------
-*/
-
-#ifndef _EAS_H
-#define _EAS_H
-
-#include "eas_types.h"
-
-/* for C++ linkage */
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* library version macro */
-#define MAKE_LIB_VERSION(a,b,c,d) (((((((EAS_U32) a <<8) | (EAS_U32) b) << 8) | (EAS_U32) c) << 8) | (EAS_U32) d)
-#define LIB_VERSION MAKE_LIB_VERSION(3, 6, 10, 14)
-
-typedef struct
-{
- EAS_U32 libVersion;
- EAS_BOOL checkedVersion;
- EAS_I32 maxVoices;
- EAS_I32 numChannels;
- EAS_I32 sampleRate;
- EAS_I32 mixBufferSize;
- EAS_BOOL filterEnabled;
- EAS_U32 buildTimeStamp;
- EAS_CHAR *buildGUID;
-} S_EAS_LIB_CONFIG;
-
-/* enumerated effects module numbers for configuration */
-typedef enum
-{
- EAS_MODULE_ENHANCER = 0,
- EAS_MODULE_COMPRESSOR,
- EAS_MODULE_REVERB,
- EAS_MODULE_CHORUS,
- EAS_MODULE_WIDENER,
- EAS_MODULE_GRAPHIC_EQ,
- EAS_MODULE_WOW,
- EAS_MODULE_MAXIMIZER,
- EAS_MODULE_TONECONTROLEQ,
- NUM_EFFECTS_MODULES
-} E_FX_MODULES;
-
-/* enumerated optional module numbers for configuration */
-typedef enum
-{
- EAS_MODULE_MMAPI_TONE_CONTROL = 0,
- EAS_MODULE_METRICS
-} E_OPT_MODULES;
-#define NUM_OPTIONAL_MODULES 2
-
-/* enumerated audio decoders for configuration */
-typedef enum
-{
- EAS_DECODER_PCM = 0,
- EAS_DECODER_SMAF_ADPCM,
- EAS_DECODER_IMA_ADPCM,
- EAS_DECODER_7BIT_SMAF_ADPCM,
- EAS_DECODER_NOT_SUPPORTED
-} E_DECODER_MODULES;
-#define NUM_DECODER_MODULES 4
-
-/* defines for EAS_PEOpenStream flags parameter */
-#define PCM_FLAGS_STEREO 0x00000100 /* stream is stereo */
-#define PCM_FLAGS_8_BIT 0x00000001 /* 8-bit format */
-#define PCM_FLAGS_UNSIGNED 0x00000010 /* unsigned format */
-#define PCM_FLAGS_STREAMING 0x80000000 /* streaming mode */
-
-/* maximum volume setting */
-#define EAS_MAX_VOLUME 100
-
-/*----------------------------------------------------------------------------
- * EAS_Init()
- *----------------------------------------------------------------------------
- * Purpose:
- * Initialize the synthesizer library
- *
- * Inputs:
- * polyphony - number of voices to play (dynamic memory model only)
- * ppLibData - pointer to data handle variable for this instance
- *
- * Outputs:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_Init (EAS_DATA_HANDLE *ppEASData);
-
-/*----------------------------------------------------------------------------
- * EAS_Config()
- *----------------------------------------------------------------------------
- * Purpose:
- * Returns a pointer to a structure containing the configuration options
- * in this library build.
- *
- * Inputs:
- *
- * Outputs:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC const S_EAS_LIB_CONFIG *EAS_Config (void);
-
-/*----------------------------------------------------------------------------
- * EAS_Shutdown()
- *----------------------------------------------------------------------------
- * Purpose:
- * Shuts down the library. Deallocates any memory associated with the
- * synthesizer (dynamic memory model only)
- *
- * Inputs:
- * pEASData - handle to data for this instance
- *
- * Outputs:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_Shutdown (EAS_DATA_HANDLE pEASData);
-
-/*----------------------------------------------------------------------------
- * EAS_Render()
- *----------------------------------------------------------------------------
- * Purpose:
- * Parse the Midi data and render PCM audio data.
- *
- * Inputs:
- * pEASData - buffer for internal EAS data
- * pOut - output buffer pointer
- * nNumRequested - requested num samples to generate
- * pnNumGenerated - actual number of samples generated
- *
- * Outputs:
- * EAS_SUCCESS if PCM data was successfully rendered
- *
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_Render (EAS_DATA_HANDLE pEASData, EAS_PCM *pOut, EAS_I32 numRequested, EAS_I32 *pNumGenerated);
-
-/*----------------------------------------------------------------------------
- * EAS_SetRepeat()
- *----------------------------------------------------------------------------
- * Purpose:
- * Set the selected stream to repeat.
- *
- * Inputs:
- * pEASData - handle to data for this instance
- * streamHandle - handle to stream
- * repeatCount - repeat count (0 = no repeat, -1 = repeat forever)
- *
- * Outputs:
- *
- * Side Effects:
- *
- * Notes:
- * 0 = no repeat
- * 1 = repeat once, i.e. play through twice
- * -1 = repeat forever
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_SetRepeat (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle, EAS_I32 repeatCount);
-
-/*----------------------------------------------------------------------------
- * EAS_GetRepeat()
- *----------------------------------------------------------------------------
- * Purpose:
- * Gets the current repeat count for the selected stream.
- *
- * Inputs:
- * pEASData - handle to data for this instance
- * streamHandle - handle to stream
- * pRrepeatCount - pointer to variable to hold repeat count
- *
- * Outputs:
- *
- * Side Effects:
- *
- * Notes:
- * 0 = no repeat
- * 1 = repeat once, i.e. play through twice
- * -1 = repeat forever
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_GetRepeat (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle, EAS_I32 *pRepeatCount);
-
-/*----------------------------------------------------------------------------
- * EAS_SetPlaybackRate()
- *----------------------------------------------------------------------------
- * Purpose:
- * Set the playback rate.
- *
- * Inputs:
- * pEASData - handle to data for this instance
- * streamHandle - handle to stream
- * rate - rate (28-bit fractional amount)
- *
- * Outputs:
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_SetPlaybackRate (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle, EAS_U32 rate);
-#define MAX_PLAYBACK_RATE (EAS_U32)(1L << 29)
-#define MIN_PLAYBACK_RATE (EAS_U32)(1L << 27)
-
-/*----------------------------------------------------------------------------
- * EAS_SetTransposition)
- *----------------------------------------------------------------------------
- * Purpose:
- * Sets the key tranposition for the synthesizer. Transposes all
- * melodic instruments by the specified amount. Range is limited
- * to +/-12 semitones.
- *
- * Inputs:
- * pEASData - handle to data for this instance
- * streamHandle - handle to stream
- * transposition - +/-12 semitones
- *
- * Outputs:
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_SetTransposition (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle, EAS_I32 transposition);
-#define MAX_TRANSPOSE 12
-
-/*----------------------------------------------------------------------------
- * EAS_SetSynthPolyphony()
- *----------------------------------------------------------------------------
- * Purpose:
- * Set the polyphony of the synthesizer. Value must be >= 1 and <= the
- * maximum number of voices. This function will pin the polyphony
- * at those limits
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * synthNum - synthesizer number (0 = onboard, 1 = DSP)
- * polyphonyCount - the desired polyphony count
- *
- * Outputs:
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_SetSynthPolyphony (EAS_DATA_HANDLE pEASData, EAS_I32 synthNum, EAS_I32 polyphonyCount);
-
-/*----------------------------------------------------------------------------
- * EAS_GetSynthPolyphony()
- *----------------------------------------------------------------------------
- * Purpose:
- * Returns the current polyphony setting of the synthesizer
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * synthNum - synthesizer number (0 = onboard, 1 = DSP)
- * pPolyphonyCount - pointer to variable to receive polyphony count
- *
- * Outputs:
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_GetSynthPolyphony (EAS_DATA_HANDLE pEASData, EAS_I32 synthNum, EAS_I32 *pPolyphonyCount);
-
-/*----------------------------------------------------------------------------
- * EAS_SetPolyphony()
- *----------------------------------------------------------------------------
- * Purpose:
- * Set the polyphony of the stream. Value must be >= 1 and <= the
- * maximum number of voices. This function will pin the polyphony
- * at those limits
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * streamHandle - handle returned by EAS_OpenFile
- * polyphonyCount - the desired polyphony count
- *
- * Outputs:
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_SetPolyphony (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle, EAS_I32 polyphonyCount);
-
-/*----------------------------------------------------------------------------
- * EAS_GetPolyphony()
- *----------------------------------------------------------------------------
- * Purpose:
- * Returns the current polyphony setting of the stream
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * streamHandle - handle returned by EAS_OpenFile
- * pPolyphonyCount - pointer to variable to receive polyphony count
- *
- * Outputs:
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_GetPolyphony (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle, EAS_I32 *pPolyphonyCount);
-
-/*----------------------------------------------------------------------------
- * EAS_SetPriority()
- *----------------------------------------------------------------------------
- * Purpose:
- * Set the priority of the stream. Determines which stream's voices
- * are stolen when there are insufficient voices for all notes.
- * Value must be in the range of 1-255, lower values are higher
- * priority. The default priority is 50.
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * streamHandle - handle returned by EAS_OpenFile
- * polyphonyCount - the desired polyphony count
- *
- * Outputs:
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_SetPriority (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle, EAS_I32 priority);
-
-/*----------------------------------------------------------------------------
- * EAS_GetPriority()
- *----------------------------------------------------------------------------
- * Purpose:
- * Returns the current priority setting of the stream
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * streamHandle - handle returned by EAS_OpenFile
- * pPriority - pointer to variable to receive priority
- *
- * Outputs:
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_GetPriority (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle, EAS_I32 *pPriority);
-
-/*----------------------------------------------------------------------------
- * EAS_SetVolume()
- *----------------------------------------------------------------------------
- * Purpose:
- * Set the master volume for the mixer. The default volume setting is
- * 90 (-10 dB). The volume range is 0 to 100 in 1dB increments.
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * volume - the desired master volume
- *
- * Outputs:
- *
- *
- * Side Effects:
- * overrides any previously set master volume from sysex
- *
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_SetVolume (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle, EAS_I32 volume);
-
-/*----------------------------------------------------------------------------
- * EAS_GetVolume()
- *----------------------------------------------------------------------------
- * Purpose:
- * Returns the master volume for the mixer in 1dB increments.
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * volume - the desired master volume
- *
- * Outputs:
- *
- *
- * Side Effects:
- * overrides any previously set master volume from sysex
- *
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_I32 EAS_GetVolume (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle);
-
-/*----------------------------------------------------------------------------
- * EAS_SetMaxLoad()
- *----------------------------------------------------------------------------
- * Purpose:
- * Sets the maximum workload the parsers will do in a single call to
- * EAS_Render. The units are currently arbitrary, but should correlate
- * well to the actual CPU cycles consumed. The primary effect is to
- * reduce the occasional peaks in CPU cycles consumed when parsing
- * dense parts of a MIDI score. Setting maxWorkLoad to zero disables
- * the workload limiting function.
- *
- * Inputs:
- * pEASData - handle to data for this instance
- * maxLoad - the desired maximum workload
- *
- * Outputs:
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_SetMaxLoad (EAS_DATA_HANDLE pEASData, EAS_I32 maxLoad);
-
-/*----------------------------------------------------------------------------
- * EAS_SetMaxPCMStreams()
- *----------------------------------------------------------------------------
- * Sets the maximum number of PCM streams allowed in parsers that
- * use PCM streaming.
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * streamHandle - handle returned by EAS_OpenFile
- * maxNumStreams - maximum number of PCM streams
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_SetMaxPCMStreams (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_I32 maxNumStreams);
-
-/*----------------------------------------------------------------------------
- * EAS_OpenFile()
- *----------------------------------------------------------------------------
- * Purpose:
- * Opens a file for audio playback.
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * locator - pointer to filename or other locating information
- * pStreamHandle - pointer to stream handle variable
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_OpenFile (EAS_DATA_HANDLE pEASData, EAS_FILE_LOCATOR locator, EAS_HANDLE *pStreamHandle);
-
-#ifdef MMAPI_SUPPORT
-/*----------------------------------------------------------------------------
- * EAS_MMAPIToneControl()
- *----------------------------------------------------------------------------
- * Purpose:
- * Opens a ToneControl file for audio playback.
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * locator - pointer to filename or other locating information
- * pStreamHandle - pointer to stream handle variable
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_MMAPIToneControl (EAS_DATA_HANDLE pEASData, EAS_FILE_LOCATOR locator, EAS_HANDLE *pStreamHandle);
-
-/*----------------------------------------------------------------------------
- * EAS_GetWaveFmtChunk
- *----------------------------------------------------------------------------
- * Helper function to retrieve WAVE file fmt chunk for MMAPI
- *----------------------------------------------------------------------------
- * pEASData - pointer to EAS persistent data object
- * streamHandle - stream handle
- * pFmtChunk - pointer to pointer to FMT chunk data
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_GetWaveFmtChunk (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle, EAS_VOID_PTR *ppFmtChunk);
-#endif
-
-/*----------------------------------------------------------------------------
- * EAS_GetFileType
- *----------------------------------------------------------------------------
- * Returns the file type (see eas_types.h for enumerations)
- *----------------------------------------------------------------------------
- * pEASData - pointer to EAS persistent data object
- * streamHandle - stream handle
- * pFileType - pointer to variable to receive file type
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_GetFileType (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle, EAS_I32 *pFileType);
-
-/*----------------------------------------------------------------------------
- * EAS_ParseMetaData()
- *----------------------------------------------------------------------------
- * Purpose:
- *
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * streamHandle - file or stream handle
- * playLength - pointer to variable to store the play length (in msecs)
- *
- * Outputs:
- *
- *
- * Side Effects:
- * - resets the parser to the start of the file
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_ParseMetaData (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle, EAS_I32 *pPlayLength);
-
-/*----------------------------------------------------------------------------
- * EAS_Prepare()
- *----------------------------------------------------------------------------
- * Purpose:
- * Prepares the synthesizer to play the file or stream. Parses the first
- * frame of data from the file and arms the synthesizer.
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * streamHandle - file or stream handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_Prepare (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle);
-
-/*----------------------------------------------------------------------------
- * EAS_State()
- *----------------------------------------------------------------------------
- * Purpose:
- * Returns the state of an audio file or stream.
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * streamHandle - file or stream handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_State (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle, EAS_STATE *pState);
-
-/*----------------------------------------------------------------------------
- * EAS_RegisterMetaDataCallback()
- *----------------------------------------------------------------------------
- * Purpose:
- * Registers a metadata callback function for parsed metadata. To
- * de-register the callback, call this function again with parameter
- * cbFunc set to NULL.
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * streamHandle - file or stream handle
- * cbFunc - pointer to host callback function
- * metaDataBuffer - pointer to metadata buffer
- * metaDataBufSize - maximum size of the metadata buffer
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_RegisterMetaDataCallback (
- EAS_DATA_HANDLE pEASData,
- EAS_HANDLE streamHandle,
- EAS_METADATA_CBFUNC cbFunc,
- char *metaDataBuffer,
- EAS_I32 metaDataBufSize,
- EAS_VOID_PTR pUserData);
-
-/*----------------------------------------------------------------------------
- * EAS_GetNoteCount ()
- *----------------------------------------------------------------------------
- * Returns the total number of notes played in this stream
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * streamHandle - file or stream handle
- * pNoteCount - pointer to variable to receive note count
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_GetNoteCount (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_I32 *pNoteCount);
-
-/*----------------------------------------------------------------------------
- * EAS_CloseFile()
- *----------------------------------------------------------------------------
- * Purpose:
- * Closes an audio file or stream. Playback should have either paused or
- * completed (EAS_State returns EAS_PAUSED or EAS_STOPPED).
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * streamHandle - file or stream handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_CloseFile (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle);
-
-/*----------------------------------------------------------------------------
- * EAS_OpenMIDIStream()
- *----------------------------------------------------------------------------
- * Purpose:
- * Opens a raw MIDI stream allowing the host to route MIDI cable data directly to the synthesizer
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * pStreamHandle - pointer to variable to hold file or stream handle
- * streamHandle - open stream or NULL for new synthesizer instance
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_OpenMIDIStream (EAS_DATA_HANDLE pEASData, EAS_HANDLE *pStreamHandle, EAS_HANDLE streamHandle);
-
-/*----------------------------------------------------------------------------
- * EAS_WriteMIDIStream()
- *----------------------------------------------------------------------------
- * Purpose:
- * Send data to the MIDI stream device
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * streamHandle - stream handle
- * pBuffer - pointer to buffer
- * count - number of bytes to write
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_WriteMIDIStream(EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle, EAS_U8 *pBuffer, EAS_I32 count);
-
-/*----------------------------------------------------------------------------
- * EAS_CloseMIDIStream()
- *----------------------------------------------------------------------------
- * Purpose:
- * Closes a raw MIDI stream
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * streamHandle - stream handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_CloseMIDIStream (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle);
-
-/*----------------------------------------------------------------------------
- * EAS_Locate()
- *----------------------------------------------------------------------------
- * Purpose:
- * Locate into the file associated with the handle.
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * streamHandle - file handle
- * milliseconds - playback offset from start of file in milliseconds
- *
- * Outputs:
- *
- *
- * Side Effects:
- * the actual offset will be quantized to the closest update period, typically
- * a resolution of 5.9ms. Notes that are started prior to this time will not
- * sound. Any notes currently playing will be shut off.
- *
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_Locate (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle, EAS_I32 milliseconds, EAS_BOOL offset);
-
-/*----------------------------------------------------------------------------
- * EAS_GetRenderTime()
- *----------------------------------------------------------------------------
- * Purpose:
- * Returns the current playback offset
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- *
- * Outputs:
- * Gets the render time clock in msecs.
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_GetRenderTime (EAS_DATA_HANDLE pEASData, EAS_I32 *pTime);
-
-/*----------------------------------------------------------------------------
- * EAS_GetLocation()
- *----------------------------------------------------------------------------
- * Purpose:
- * Returns the current playback offset
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * streamHandle - file handle
- *
- * Outputs:
- * The offset in milliseconds from the start of the current sequence, quantized
- * to the nearest update period. Actual resolution is typically 5.9 ms.
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_GetLocation (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle, EAS_I32 *pTime);
-
-/*----------------------------------------------------------------------------
- * EAS_Pause()
- *----------------------------------------------------------------------------
- * Purpose:
- * Pauses the playback of the data associated with this handle. The audio
- * is gracefully ramped down to prevent clicks and pops. It may take several
- * buffers of audio before the audio is muted.
- *
- * Inputs:
- * psEASData - pointer to overall EAS data structure
- * streamHandle - file or stream handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_Pause (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle);
-
-/*----------------------------------------------------------------------------
- * EAS_Resume()
- *----------------------------------------------------------------------------
- * Purpose:
- * Resumes the playback of the data associated with this handle. The audio
- * is gracefully ramped up to prevent clicks and pops.
- *
- * Inputs:
- * psEASData - pointer to overall EAS data structure
- * streamHandle - file or stream handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_Resume (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle);
-
-/*----------------------------------------------------------------------------
- * EAS_GetParameter()
- *----------------------------------------------------------------------------
- * Purpose:
- * Set the parameter of a module. See E_MODULES for a list of modules
- * and the header files of the modules for a list of parameters.
- *
- * Inputs:
- * psEASData - pointer to overall EAS data structure
- * module - enumerated module number
- * param - enumerated parameter number
- * pValue - pointer to variable to receive parameter value
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_GetParameter (EAS_DATA_HANDLE pEASData, EAS_I32 module, EAS_I32 param, EAS_I32 *pValue);
-
-/*----------------------------------------------------------------------------
- * EAS_SetParameter()
- *----------------------------------------------------------------------------
- * Purpose:
- * Set the parameter of a module. See E_MODULES for a list of modules
- * and the header files of the modules for a list of parameters.
- *
- * Inputs:
- * psEASData - pointer to overall EAS data structure
- * handle - file or stream handle
- * module - enumerated module number
- * param - enumerated parameter number
- * value - new parameter value
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_SetParameter (EAS_DATA_HANDLE pEASData, EAS_I32 module, EAS_I32 param, EAS_I32 value);
-
-#ifdef _METRICS_ENABLED
-/*----------------------------------------------------------------------------
- * EAS_MetricsReport()
- *----------------------------------------------------------------------------
- * Purpose:
- * Displays the current metrics through the EAS_Report interface.
- *
- * Inputs:
- * pEASData - instance data handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_MetricsReport (EAS_DATA_HANDLE pEASData);
-
-/*----------------------------------------------------------------------------
- * EAS_MetricsReset()
- *----------------------------------------------------------------------------
- * Purpose:
- * Displays the current metrics through the EAS_Report interface.
- *
- * Inputs:
- * pEASData - instance data handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_MetricsReset (EAS_DATA_HANDLE pEASData);
-#endif
-
-/*----------------------------------------------------------------------------
- * EAS_SetSoundLibrary()
- *----------------------------------------------------------------------------
- * Purpose:
- * Sets the location of the sound library.
- *
- * Inputs:
- * pEASData - instance data handle
- * streamHandle - file or stream handle
- * pSoundLib - pointer to sound library
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_SetSoundLibrary (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle, EAS_SNDLIB_HANDLE pSndLib);
-
-/*----------------------------------------------------------------------------
- * EAS_SetHeaderSearchFlag()
- *----------------------------------------------------------------------------
- * By default, when EAS_OpenFile is called, the parsers check the
- * first few bytes of the file looking for a specific header. Some
- * mobile devices may add a header to the start of a file, which
- * will prevent the parser from recognizing the file. If the
- * searchFlag is set to EAS_TRUE, the parser will search the entire
- * file looking for the header. This may enable EAS to recognize
- * some files that it would ordinarily reject. The negative is that
- * it make take slightly longer to process the EAS_OpenFile request.
- *
- * Inputs:
- * pEASData - instance data handle
- * searchFlag - search flag (EAS_TRUE or EAS_FALSE)
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_SetHeaderSearchFlag (EAS_DATA_HANDLE pEASData, EAS_BOOL searchFlag);
-
-/*----------------------------------------------------------------------------
- * EAS_SetPlayMode()
- *----------------------------------------------------------------------------
- * Some file formats support special play modes, such as iMode partial
- * play mode. This call can be used to change the play mode. The
- * default play mode (usually straight playback) is always zero.
- *
- * Inputs:
- * pEASData - instance data handle
- * handle - file or stream handle
- * playMode - play mode (see eas_types.h for enumerations)
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_SetPlayMode (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_I32 playMode);
-
-#ifdef DLS_SYNTHESIZER
-/*----------------------------------------------------------------------------
- * EAS_LoadDLSCollection()
- *----------------------------------------------------------------------------
- * Purpose:
- * Downloads a DLS collection
- *
- * Inputs:
- * pEASData - instance data handle
- * streamHandle - file or stream handle
- * locator - file locator
- *
- * Outputs:
- *
- *
- * Side Effects:
- * May overlay instruments in the GM sound set
- *
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_LoadDLSCollection (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle, EAS_FILE_LOCATOR locator);
-#endif
-
-/*----------------------------------------------------------------------------
- * EAS_SetFrameBuffer()
- *----------------------------------------------------------------------------
- * Purpose:
- * Sets the frame buffer pointer passed to the IPC communications functions
- *
- * Inputs:
- * pEASData - instance data handle
- * locator - file locator
- *
- * Outputs:
- *
- *
- * Side Effects:
- * May overlay instruments in the GM sound set
- *
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_SetFrameBuffer (EAS_DATA_HANDLE pEASData, EAS_FRAME_BUFFER_HANDLE pFrameBuffer);
-
-#ifdef EXTERNAL_AUDIO
-/*----------------------------------------------------------------------------
- * EAS_RegExtAudioCallback()
- *----------------------------------------------------------------------------
- * Purpose:
- * Registers callback functions for audio events.
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * streamHandle - file or stream handle
- * cbProgChgFunc - pointer to host callback function for program change
- * cbEventFunc - pointer to host callback functio for note events
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_RegExtAudioCallback (EAS_DATA_HANDLE pEASData,
- EAS_HANDLE streamHandle,
- EAS_VOID_PTR pInstData,
- EAS_EXT_PRG_CHG_FUNC cbProgChgFunc,
- EAS_EXT_EVENT_FUNC cbEventFunc);
-
-/*----------------------------------------------------------------------------
- * EAS_GetMIDIControllers()
- *----------------------------------------------------------------------------
- * Purpose:
- * Returns the current state of MIDI controllers on the requested channel.
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * streamHandle - file or stream handle
- * pControl - pointer to structure to receive data
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_GetMIDIControllers (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle, EAS_U8 channel, S_MIDI_CONTROLLERS *pControl);
-#endif
-
-/*----------------------------------------------------------------------------
- * EAS_SearchFile
- *----------------------------------------------------------------------------
- * Search file for specific sequence starting at current file
- * position. Returns offset to start of sequence.
- *
- * Inputs:
- * pEASData - pointer to EAS persistent data object
- * fileHandle - file handle
- * searchString - pointer to search sequence
- * len - length of search sequence
- * pOffset - pointer to variable to store offset to sequence
- *
- * Returns EAS_EOF if end-of-file is reached
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT EAS_SearchFile (EAS_DATA_HANDLE pEASData, EAS_FILE_HANDLE fileHandle, const EAS_U8 *searchString, EAS_I32 len, EAS_I32 *pOffset);
-
-#ifdef __cplusplus
-} /* end extern "C" */
-#endif
-
-#endif /* #ifndef _EAS_H */
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 852 $
+ * $Date: 2007-09-04 11:43:49 -0700 (Tue, 04 Sep 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+#ifndef _EAS_H
+#define _EAS_H
+
+#include "eas_types.h"
+
+/* for C++ linkage */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* library version macro */
+#define MAKE_LIB_VERSION(a,b,c,d) (((((((EAS_U32) a <<8) | (EAS_U32) b) << 8) | (EAS_U32) c) << 8) | (EAS_U32) d)
+#define LIB_VERSION MAKE_LIB_VERSION(3, 6, 10, 14)
+
+typedef struct
+{
+ EAS_U32 libVersion;
+ EAS_BOOL checkedVersion;
+ EAS_I32 maxVoices;
+ EAS_I32 numChannels;
+ EAS_I32 sampleRate;
+ EAS_I32 mixBufferSize;
+ EAS_BOOL filterEnabled;
+ EAS_U32 buildTimeStamp;
+ EAS_CHAR *buildGUID;
+} S_EAS_LIB_CONFIG;
+
+/* enumerated effects module numbers for configuration */
+typedef enum
+{
+ EAS_MODULE_ENHANCER = 0,
+ EAS_MODULE_COMPRESSOR,
+ EAS_MODULE_REVERB,
+ EAS_MODULE_CHORUS,
+ EAS_MODULE_WIDENER,
+ EAS_MODULE_GRAPHIC_EQ,
+ EAS_MODULE_WOW,
+ EAS_MODULE_MAXIMIZER,
+ EAS_MODULE_TONECONTROLEQ,
+ NUM_EFFECTS_MODULES
+} E_FX_MODULES;
+
+/* enumerated optional module numbers for configuration */
+typedef enum
+{
+ EAS_MODULE_MMAPI_TONE_CONTROL = 0,
+ EAS_MODULE_METRICS
+} E_OPT_MODULES;
+#define NUM_OPTIONAL_MODULES 2
+
+/* enumerated audio decoders for configuration */
+typedef enum
+{
+ EAS_DECODER_PCM = 0,
+ EAS_DECODER_SMAF_ADPCM,
+ EAS_DECODER_IMA_ADPCM,
+ EAS_DECODER_7BIT_SMAF_ADPCM,
+ EAS_DECODER_NOT_SUPPORTED
+} E_DECODER_MODULES;
+#define NUM_DECODER_MODULES 4
+
+/* defines for EAS_PEOpenStream flags parameter */
+#define PCM_FLAGS_STEREO 0x00000100 /* stream is stereo */
+#define PCM_FLAGS_8_BIT 0x00000001 /* 8-bit format */
+#define PCM_FLAGS_UNSIGNED 0x00000010 /* unsigned format */
+#define PCM_FLAGS_STREAMING 0x80000000 /* streaming mode */
+
+/* maximum volume setting */
+#define EAS_MAX_VOLUME 100
+
+/*----------------------------------------------------------------------------
+ * EAS_Init()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Initialize the synthesizer library
+ *
+ * Inputs:
+ * polyphony - number of voices to play (dynamic memory model only)
+ * ppLibData - pointer to data handle variable for this instance
+ *
+ * Outputs:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_Init (EAS_DATA_HANDLE *ppEASData);
+
+/*----------------------------------------------------------------------------
+ * EAS_Config()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Returns a pointer to a structure containing the configuration options
+ * in this library build.
+ *
+ * Inputs:
+ *
+ * Outputs:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC const S_EAS_LIB_CONFIG *EAS_Config (void);
+
+/*----------------------------------------------------------------------------
+ * EAS_Shutdown()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Shuts down the library. Deallocates any memory associated with the
+ * synthesizer (dynamic memory model only)
+ *
+ * Inputs:
+ * pEASData - handle to data for this instance
+ *
+ * Outputs:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_Shutdown (EAS_DATA_HANDLE pEASData);
+
+/*----------------------------------------------------------------------------
+ * EAS_Render()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Parse the Midi data and render PCM audio data.
+ *
+ * Inputs:
+ * pEASData - buffer for internal EAS data
+ * pOut - output buffer pointer
+ * nNumRequested - requested num samples to generate
+ * pnNumGenerated - actual number of samples generated
+ *
+ * Outputs:
+ * EAS_SUCCESS if PCM data was successfully rendered
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_Render (EAS_DATA_HANDLE pEASData, EAS_PCM *pOut, EAS_I32 numRequested, EAS_I32 *pNumGenerated);
+
+/*----------------------------------------------------------------------------
+ * EAS_SetRepeat()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Set the selected stream to repeat.
+ *
+ * Inputs:
+ * pEASData - handle to data for this instance
+ * streamHandle - handle to stream
+ * repeatCount - repeat count (0 = no repeat, -1 = repeat forever)
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ *
+ * Notes:
+ * 0 = no repeat
+ * 1 = repeat once, i.e. play through twice
+ * -1 = repeat forever
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_SetRepeat (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle, EAS_I32 repeatCount);
+
+/*----------------------------------------------------------------------------
+ * EAS_GetRepeat()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Gets the current repeat count for the selected stream.
+ *
+ * Inputs:
+ * pEASData - handle to data for this instance
+ * streamHandle - handle to stream
+ * pRrepeatCount - pointer to variable to hold repeat count
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ *
+ * Notes:
+ * 0 = no repeat
+ * 1 = repeat once, i.e. play through twice
+ * -1 = repeat forever
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_GetRepeat (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle, EAS_I32 *pRepeatCount);
+
+/*----------------------------------------------------------------------------
+ * EAS_SetPlaybackRate()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Set the playback rate.
+ *
+ * Inputs:
+ * pEASData - handle to data for this instance
+ * streamHandle - handle to stream
+ * rate - rate (28-bit fractional amount)
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_SetPlaybackRate (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle, EAS_U32 rate);
+#define MAX_PLAYBACK_RATE (EAS_U32)(1L << 29)
+#define MIN_PLAYBACK_RATE (EAS_U32)(1L << 27)
+
+/*----------------------------------------------------------------------------
+ * EAS_SetTransposition)
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Sets the key tranposition for the synthesizer. Transposes all
+ * melodic instruments by the specified amount. Range is limited
+ * to +/-12 semitones.
+ *
+ * Inputs:
+ * pEASData - handle to data for this instance
+ * streamHandle - handle to stream
+ * transposition - +/-12 semitones
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_SetTransposition (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle, EAS_I32 transposition);
+#define MAX_TRANSPOSE 12
+
+/*----------------------------------------------------------------------------
+ * EAS_SetSynthPolyphony()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Set the polyphony of the synthesizer. Value must be >= 1 and <= the
+ * maximum number of voices. This function will pin the polyphony
+ * at those limits
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * synthNum - synthesizer number (0 = onboard, 1 = DSP)
+ * polyphonyCount - the desired polyphony count
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_SetSynthPolyphony (EAS_DATA_HANDLE pEASData, EAS_I32 synthNum, EAS_I32 polyphonyCount);
+
+/*----------------------------------------------------------------------------
+ * EAS_GetSynthPolyphony()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Returns the current polyphony setting of the synthesizer
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * synthNum - synthesizer number (0 = onboard, 1 = DSP)
+ * pPolyphonyCount - pointer to variable to receive polyphony count
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_GetSynthPolyphony (EAS_DATA_HANDLE pEASData, EAS_I32 synthNum, EAS_I32 *pPolyphonyCount);
+
+/*----------------------------------------------------------------------------
+ * EAS_SetPolyphony()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Set the polyphony of the stream. Value must be >= 1 and <= the
+ * maximum number of voices. This function will pin the polyphony
+ * at those limits
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * streamHandle - handle returned by EAS_OpenFile
+ * polyphonyCount - the desired polyphony count
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_SetPolyphony (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle, EAS_I32 polyphonyCount);
+
+/*----------------------------------------------------------------------------
+ * EAS_GetPolyphony()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Returns the current polyphony setting of the stream
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * streamHandle - handle returned by EAS_OpenFile
+ * pPolyphonyCount - pointer to variable to receive polyphony count
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_GetPolyphony (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle, EAS_I32 *pPolyphonyCount);
+
+/*----------------------------------------------------------------------------
+ * EAS_SetPriority()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Set the priority of the stream. Determines which stream's voices
+ * are stolen when there are insufficient voices for all notes.
+ * Value must be in the range of 1-255, lower values are higher
+ * priority. The default priority is 50.
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * streamHandle - handle returned by EAS_OpenFile
+ * polyphonyCount - the desired polyphony count
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_SetPriority (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle, EAS_I32 priority);
+
+/*----------------------------------------------------------------------------
+ * EAS_GetPriority()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Returns the current priority setting of the stream
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * streamHandle - handle returned by EAS_OpenFile
+ * pPriority - pointer to variable to receive priority
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_GetPriority (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle, EAS_I32 *pPriority);
+
+/*----------------------------------------------------------------------------
+ * EAS_SetVolume()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Set the master volume for the mixer. The default volume setting is
+ * 90 (-10 dB). The volume range is 0 to 100 in 1dB increments.
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * volume - the desired master volume
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ * overrides any previously set master volume from sysex
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_SetVolume (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle, EAS_I32 volume);
+
+/*----------------------------------------------------------------------------
+ * EAS_GetVolume()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Returns the master volume for the mixer in 1dB increments.
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * volume - the desired master volume
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ * overrides any previously set master volume from sysex
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_I32 EAS_GetVolume (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle);
+
+/*----------------------------------------------------------------------------
+ * EAS_SetMaxLoad()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Sets the maximum workload the parsers will do in a single call to
+ * EAS_Render. The units are currently arbitrary, but should correlate
+ * well to the actual CPU cycles consumed. The primary effect is to
+ * reduce the occasional peaks in CPU cycles consumed when parsing
+ * dense parts of a MIDI score. Setting maxWorkLoad to zero disables
+ * the workload limiting function.
+ *
+ * Inputs:
+ * pEASData - handle to data for this instance
+ * maxLoad - the desired maximum workload
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_SetMaxLoad (EAS_DATA_HANDLE pEASData, EAS_I32 maxLoad);
+
+/*----------------------------------------------------------------------------
+ * EAS_SetMaxPCMStreams()
+ *----------------------------------------------------------------------------
+ * Sets the maximum number of PCM streams allowed in parsers that
+ * use PCM streaming.
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * streamHandle - handle returned by EAS_OpenFile
+ * maxNumStreams - maximum number of PCM streams
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_SetMaxPCMStreams (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_I32 maxNumStreams);
+
+/*----------------------------------------------------------------------------
+ * EAS_OpenFile()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Opens a file for audio playback.
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * locator - pointer to filename or other locating information
+ * pStreamHandle - pointer to stream handle variable
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_OpenFile (EAS_DATA_HANDLE pEASData, EAS_FILE_LOCATOR locator, EAS_HANDLE *pStreamHandle);
+
+#ifdef MMAPI_SUPPORT
+/*----------------------------------------------------------------------------
+ * EAS_MMAPIToneControl()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Opens a ToneControl file for audio playback.
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * locator - pointer to filename or other locating information
+ * pStreamHandle - pointer to stream handle variable
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_MMAPIToneControl (EAS_DATA_HANDLE pEASData, EAS_FILE_LOCATOR locator, EAS_HANDLE *pStreamHandle);
+
+/*----------------------------------------------------------------------------
+ * EAS_GetWaveFmtChunk
+ *----------------------------------------------------------------------------
+ * Helper function to retrieve WAVE file fmt chunk for MMAPI
+ *----------------------------------------------------------------------------
+ * pEASData - pointer to EAS persistent data object
+ * streamHandle - stream handle
+ * pFmtChunk - pointer to pointer to FMT chunk data
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_GetWaveFmtChunk (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle, EAS_VOID_PTR *ppFmtChunk);
+#endif
+
+/*----------------------------------------------------------------------------
+ * EAS_GetFileType
+ *----------------------------------------------------------------------------
+ * Returns the file type (see eas_types.h for enumerations)
+ *----------------------------------------------------------------------------
+ * pEASData - pointer to EAS persistent data object
+ * streamHandle - stream handle
+ * pFileType - pointer to variable to receive file type
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_GetFileType (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle, EAS_I32 *pFileType);
+
+/*----------------------------------------------------------------------------
+ * EAS_ParseMetaData()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ *
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * streamHandle - file or stream handle
+ * playLength - pointer to variable to store the play length (in msecs)
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ * - resets the parser to the start of the file
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_ParseMetaData (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle, EAS_I32 *pPlayLength);
+
+/*----------------------------------------------------------------------------
+ * EAS_Prepare()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Prepares the synthesizer to play the file or stream. Parses the first
+ * frame of data from the file and arms the synthesizer.
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * streamHandle - file or stream handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_Prepare (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle);
+
+/*----------------------------------------------------------------------------
+ * EAS_State()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Returns the state of an audio file or stream.
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * streamHandle - file or stream handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_State (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle, EAS_STATE *pState);
+
+/*----------------------------------------------------------------------------
+ * EAS_RegisterMetaDataCallback()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Registers a metadata callback function for parsed metadata. To
+ * de-register the callback, call this function again with parameter
+ * cbFunc set to NULL.
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * streamHandle - file or stream handle
+ * cbFunc - pointer to host callback function
+ * metaDataBuffer - pointer to metadata buffer
+ * metaDataBufSize - maximum size of the metadata buffer
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_RegisterMetaDataCallback (
+ EAS_DATA_HANDLE pEASData,
+ EAS_HANDLE streamHandle,
+ EAS_METADATA_CBFUNC cbFunc,
+ char *metaDataBuffer,
+ EAS_I32 metaDataBufSize,
+ EAS_VOID_PTR pUserData);
+
+/*----------------------------------------------------------------------------
+ * EAS_GetNoteCount ()
+ *----------------------------------------------------------------------------
+ * Returns the total number of notes played in this stream
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * streamHandle - file or stream handle
+ * pNoteCount - pointer to variable to receive note count
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_GetNoteCount (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_I32 *pNoteCount);
+
+/*----------------------------------------------------------------------------
+ * EAS_CloseFile()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Closes an audio file or stream. Playback should have either paused or
+ * completed (EAS_State returns EAS_PAUSED or EAS_STOPPED).
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * streamHandle - file or stream handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_CloseFile (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle);
+
+/*----------------------------------------------------------------------------
+ * EAS_OpenMIDIStream()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Opens a raw MIDI stream allowing the host to route MIDI cable data directly to the synthesizer
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * pStreamHandle - pointer to variable to hold file or stream handle
+ * streamHandle - open stream or NULL for new synthesizer instance
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_OpenMIDIStream (EAS_DATA_HANDLE pEASData, EAS_HANDLE *pStreamHandle, EAS_HANDLE streamHandle);
+
+/*----------------------------------------------------------------------------
+ * EAS_WriteMIDIStream()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Send data to the MIDI stream device
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * streamHandle - stream handle
+ * pBuffer - pointer to buffer
+ * count - number of bytes to write
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_WriteMIDIStream(EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle, EAS_U8 *pBuffer, EAS_I32 count);
+
+/*----------------------------------------------------------------------------
+ * EAS_CloseMIDIStream()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Closes a raw MIDI stream
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * streamHandle - stream handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_CloseMIDIStream (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle);
+
+/*----------------------------------------------------------------------------
+ * EAS_Locate()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Locate into the file associated with the handle.
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * streamHandle - file handle
+ * milliseconds - playback offset from start of file in milliseconds
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ * the actual offset will be quantized to the closest update period, typically
+ * a resolution of 5.9ms. Notes that are started prior to this time will not
+ * sound. Any notes currently playing will be shut off.
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_Locate (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle, EAS_I32 milliseconds, EAS_BOOL offset);
+
+/*----------------------------------------------------------------------------
+ * EAS_GetRenderTime()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Returns the current playback offset
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ * Gets the render time clock in msecs.
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_GetRenderTime (EAS_DATA_HANDLE pEASData, EAS_I32 *pTime);
+
+/*----------------------------------------------------------------------------
+ * EAS_GetLocation()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Returns the current playback offset
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * streamHandle - file handle
+ *
+ * Outputs:
+ * The offset in milliseconds from the start of the current sequence, quantized
+ * to the nearest update period. Actual resolution is typically 5.9 ms.
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_GetLocation (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle, EAS_I32 *pTime);
+
+/*----------------------------------------------------------------------------
+ * EAS_Pause()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Pauses the playback of the data associated with this handle. The audio
+ * is gracefully ramped down to prevent clicks and pops. It may take several
+ * buffers of audio before the audio is muted.
+ *
+ * Inputs:
+ * psEASData - pointer to overall EAS data structure
+ * streamHandle - file or stream handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_Pause (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle);
+
+/*----------------------------------------------------------------------------
+ * EAS_Resume()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Resumes the playback of the data associated with this handle. The audio
+ * is gracefully ramped up to prevent clicks and pops.
+ *
+ * Inputs:
+ * psEASData - pointer to overall EAS data structure
+ * streamHandle - file or stream handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_Resume (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle);
+
+/*----------------------------------------------------------------------------
+ * EAS_GetParameter()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Set the parameter of a module. See E_MODULES for a list of modules
+ * and the header files of the modules for a list of parameters.
+ *
+ * Inputs:
+ * psEASData - pointer to overall EAS data structure
+ * module - enumerated module number
+ * param - enumerated parameter number
+ * pValue - pointer to variable to receive parameter value
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_GetParameter (EAS_DATA_HANDLE pEASData, EAS_I32 module, EAS_I32 param, EAS_I32 *pValue);
+
+/*----------------------------------------------------------------------------
+ * EAS_SetParameter()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Set the parameter of a module. See E_MODULES for a list of modules
+ * and the header files of the modules for a list of parameters.
+ *
+ * Inputs:
+ * psEASData - pointer to overall EAS data structure
+ * handle - file or stream handle
+ * module - enumerated module number
+ * param - enumerated parameter number
+ * value - new parameter value
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_SetParameter (EAS_DATA_HANDLE pEASData, EAS_I32 module, EAS_I32 param, EAS_I32 value);
+
+#ifdef _METRICS_ENABLED
+/*----------------------------------------------------------------------------
+ * EAS_MetricsReport()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Displays the current metrics through the EAS_Report interface.
+ *
+ * Inputs:
+ * pEASData - instance data handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_MetricsReport (EAS_DATA_HANDLE pEASData);
+
+/*----------------------------------------------------------------------------
+ * EAS_MetricsReset()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Displays the current metrics through the EAS_Report interface.
+ *
+ * Inputs:
+ * pEASData - instance data handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_MetricsReset (EAS_DATA_HANDLE pEASData);
+#endif
+
+/*----------------------------------------------------------------------------
+ * EAS_SetSoundLibrary()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Sets the location of the sound library.
+ *
+ * Inputs:
+ * pEASData - instance data handle
+ * streamHandle - file or stream handle
+ * pSoundLib - pointer to sound library
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_SetSoundLibrary (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle, EAS_SNDLIB_HANDLE pSndLib);
+
+/*----------------------------------------------------------------------------
+ * EAS_SetHeaderSearchFlag()
+ *----------------------------------------------------------------------------
+ * By default, when EAS_OpenFile is called, the parsers check the
+ * first few bytes of the file looking for a specific header. Some
+ * mobile devices may add a header to the start of a file, which
+ * will prevent the parser from recognizing the file. If the
+ * searchFlag is set to EAS_TRUE, the parser will search the entire
+ * file looking for the header. This may enable EAS to recognize
+ * some files that it would ordinarily reject. The negative is that
+ * it make take slightly longer to process the EAS_OpenFile request.
+ *
+ * Inputs:
+ * pEASData - instance data handle
+ * searchFlag - search flag (EAS_TRUE or EAS_FALSE)
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_SetHeaderSearchFlag (EAS_DATA_HANDLE pEASData, EAS_BOOL searchFlag);
+
+/*----------------------------------------------------------------------------
+ * EAS_SetPlayMode()
+ *----------------------------------------------------------------------------
+ * Some file formats support special play modes, such as iMode partial
+ * play mode. This call can be used to change the play mode. The
+ * default play mode (usually straight playback) is always zero.
+ *
+ * Inputs:
+ * pEASData - instance data handle
+ * handle - file or stream handle
+ * playMode - play mode (see eas_types.h for enumerations)
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_SetPlayMode (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_I32 playMode);
+
+#ifdef DLS_SYNTHESIZER
+/*----------------------------------------------------------------------------
+ * EAS_LoadDLSCollection()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Downloads a DLS collection
+ *
+ * Inputs:
+ * pEASData - instance data handle
+ * streamHandle - file or stream handle
+ * locator - file locator
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ * May overlay instruments in the GM sound set
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_LoadDLSCollection (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle, EAS_FILE_LOCATOR locator);
+#endif
+
+/*----------------------------------------------------------------------------
+ * EAS_SetFrameBuffer()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Sets the frame buffer pointer passed to the IPC communications functions
+ *
+ * Inputs:
+ * pEASData - instance data handle
+ * locator - file locator
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ * May overlay instruments in the GM sound set
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_SetFrameBuffer (EAS_DATA_HANDLE pEASData, EAS_FRAME_BUFFER_HANDLE pFrameBuffer);
+
+#ifdef EXTERNAL_AUDIO
+/*----------------------------------------------------------------------------
+ * EAS_RegExtAudioCallback()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Registers callback functions for audio events.
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * streamHandle - file or stream handle
+ * cbProgChgFunc - pointer to host callback function for program change
+ * cbEventFunc - pointer to host callback functio for note events
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_RegExtAudioCallback (EAS_DATA_HANDLE pEASData,
+ EAS_HANDLE streamHandle,
+ EAS_VOID_PTR pInstData,
+ EAS_EXT_PRG_CHG_FUNC cbProgChgFunc,
+ EAS_EXT_EVENT_FUNC cbEventFunc);
+
+/*----------------------------------------------------------------------------
+ * EAS_GetMIDIControllers()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Returns the current state of MIDI controllers on the requested channel.
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * streamHandle - file or stream handle
+ * pControl - pointer to structure to receive data
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_GetMIDIControllers (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle, EAS_U8 channel, S_MIDI_CONTROLLERS *pControl);
+#endif
+
+/*----------------------------------------------------------------------------
+ * EAS_SearchFile
+ *----------------------------------------------------------------------------
+ * Search file for specific sequence starting at current file
+ * position. Returns offset to start of sequence.
+ *
+ * Inputs:
+ * pEASData - pointer to EAS persistent data object
+ * fileHandle - file handle
+ * searchString - pointer to search sequence
+ * len - length of search sequence
+ * pOffset - pointer to variable to store offset to sequence
+ *
+ * Returns EAS_EOF if end-of-file is reached
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_SearchFile (EAS_DATA_HANDLE pEASData, EAS_FILE_HANDLE fileHandle, const EAS_U8 *searchString, EAS_I32 len, EAS_I32 *pOffset);
+
+#ifdef __cplusplus
+} /* end extern "C" */
+#endif
+
+#endif /* #ifndef _EAS_H */
diff --git a/arm-hybrid-22k/host_src/eas_build.h b/arm-hybrid-22k/host_src/eas_build.h
index 3663322..0e26211 100644
--- a/arm-hybrid-22k/host_src/eas_build.h
+++ b/arm-hybrid-22k/host_src/eas_build.h
@@ -1,15 +1,15 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * host_src\eas_build.h
- *
- * Contents and purpose:
- * This file contains the build configuration for this
- * build. The buildGUIDStr is a GUID created during
- * the build process and is guaranteed to be unique
- * for each build.
- *
- * Copyright Sonic Network Inc. 2006
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * host_src\eas_build.h
+ *
+ * Contents and purpose:
+ * This file contains the build configuration for this
+ * build. The buildGUIDStr is a GUID created during
+ * the build process and is guaranteed to be unique
+ * for each build.
+ *
+ * Copyright Sonic Network Inc. 2006
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -22,15 +22,15 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * This file was autogenerated by buildid.exe
- *----------------------------------------------------------------------------
-*/
-
-#ifndef _GUID_0cbd200ab054487f9ece7d3c8852e426_
-#define _GUID_0cbd200ab054487f9ece7d3c8852e426_
-
-#define _BUILD_VERSION_ "0cbd200a-b054-487f-9ece-7d3c8852e426"
-#define _BUILD_TIME_ 0x4743b9dc
-
-#endif /* _GUID_0cbd200ab054487f9ece7d3c8852e426_ */
+ *
+ * This file was autogenerated by buildid.exe
+ *----------------------------------------------------------------------------
+*/
+
+#ifndef _GUID_0cbd200ab054487f9ece7d3c8852e426_
+#define _GUID_0cbd200ab054487f9ece7d3c8852e426_
+
+#define _BUILD_VERSION_ "0cbd200a-b054-487f-9ece-7d3c8852e426"
+#define _BUILD_TIME_ 0x4743b9dc
+
+#endif /* _GUID_0cbd200ab054487f9ece7d3c8852e426_ */
diff --git a/arm-hybrid-22k/host_src/eas_chorus.h b/arm-hybrid-22k/host_src/eas_chorus.h
index 0e9057f..998a828 100644
--- a/arm-hybrid-22k/host_src/eas_chorus.h
+++ b/arm-hybrid-22k/host_src/eas_chorus.h
@@ -1,13 +1,13 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_chorus.h
- *
- * Contents and purpose:
- * Contains parameter enumerations for the Chorus effect
- *
- *
- * Copyright Sonic Network Inc. 2006
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_chorus.h
+ *
+ * Contents and purpose:
+ * Contains parameter enumerations for the Chorus effect
+ *
+ *
+ * Copyright Sonic Network Inc. 2006
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,34 +20,34 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 309 $
- * $Date: 2006-09-12 18:52:45 -0700 (Tue, 12 Sep 2006) $
- *----------------------------------------------------------------------------
-*/
-
-#ifndef EAS_CHORUS_H
-#define EAS_CHORUS_H
-
-/* enumerated parameter settings for Chorus effect */
-typedef enum
-{
- EAS_PARAM_CHORUS_BYPASS,
- EAS_PARAM_CHORUS_PRESET,
- EAS_PARAM_CHORUS_RATE,
- EAS_PARAM_CHORUS_DEPTH,
- EAS_PARAM_CHORUS_LEVEL
-} E_CHORUS_PARAMS;
-
-typedef enum
-{
- EAS_PARAM_CHORUS_PRESET1,
- EAS_PARAM_CHORUS_PRESET2,
- EAS_PARAM_CHORUS_PRESET3,
- EAS_PARAM_CHORUS_PRESET4
-} E_CHORUS_PRESETS;
-
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 309 $
+ * $Date: 2006-09-12 18:52:45 -0700 (Tue, 12 Sep 2006) $
+ *----------------------------------------------------------------------------
+*/
+
+#ifndef EAS_CHORUS_H
+#define EAS_CHORUS_H
+
+/* enumerated parameter settings for Chorus effect */
+typedef enum
+{
+ EAS_PARAM_CHORUS_BYPASS,
+ EAS_PARAM_CHORUS_PRESET,
+ EAS_PARAM_CHORUS_RATE,
+ EAS_PARAM_CHORUS_DEPTH,
+ EAS_PARAM_CHORUS_LEVEL
+} E_CHORUS_PARAMS;
+
+typedef enum
+{
+ EAS_PARAM_CHORUS_PRESET1,
+ EAS_PARAM_CHORUS_PRESET2,
+ EAS_PARAM_CHORUS_PRESET3,
+ EAS_PARAM_CHORUS_PRESET4
+} E_CHORUS_PRESETS;
+
+
#endif \ No newline at end of file
diff --git a/arm-hybrid-22k/host_src/eas_config.c b/arm-hybrid-22k/host_src/eas_config.c
index c45fbb7..0b92357 100644
--- a/arm-hybrid-22k/host_src/eas_config.c
+++ b/arm-hybrid-22k/host_src/eas_config.c
@@ -1,22 +1,22 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_config.c
- *
- * Contents and purpose:
- * This file contains the Configuration Module interface (CM). The CM
- * is a module compiled external to the library that sets the configuration
- * for this build. It allows the library to find optional components and
- * links to static memory allocations (when used in a static configuration).
- *
- * DO NOT MODIFY THIS FILE!
- *
- * NOTE: This module is not intended to be modified by the customer. It
- * needs to be included in the build process with the correct configuration
- * defines (see the library documentation for information on how to configure
- * the library).
- *
- * Copyright Sonic Network Inc. 2004-2006
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_config.c
+ *
+ * Contents and purpose:
+ * This file contains the Configuration Module interface (CM). The CM
+ * is a module compiled external to the library that sets the configuration
+ * for this build. It allows the library to find optional components and
+ * links to static memory allocations (when used in a static configuration).
+ *
+ * DO NOT MODIFY THIS FILE!
+ *
+ * NOTE: This module is not intended to be modified by the customer. It
+ * needs to be included in the build process with the correct configuration
+ * defines (see the library documentation for information on how to configure
+ * the library).
+ *
+ * Copyright Sonic Network Inc. 2004-2006
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -29,591 +29,591 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 796 $
- * $Date: 2007-08-01 00:15:25 -0700 (Wed, 01 Aug 2007) $
- *----------------------------------------------------------------------------
-*/
-
-#include "eas.h"
-#include "eas_config.h"
-
-
-#ifdef _MFI_PARSER
-/*----------------------------------------------------------------------------
- * Vendor/Device ID for MFi Extensions
- *
- * Define the preprocessor symbols to establish the vendor ID and
- * device ID for the MFi PCM/ADPCM extensions.
- *----------------------------------------------------------------------------
-*/
-const EAS_U8 eas_MFIVendorIDMSB = (MFI_VENDOR_ID >> 8) & 0xff;
-const EAS_U8 eas_MFIVendorIDLSB = MFI_VENDOR_ID & 0xff;
-const EAS_U8 eas_MFIDeviceID = MFI_DEVICE_ID;
-#endif
-
-/*----------------------------------------------------------------------------
- *
- * parserModules
- *
- * This structure is used by the EAS library to locate file parsing
- * modules.
- *----------------------------------------------------------------------------
-*/
-
-/* define the external file parsers */
-extern EAS_VOID_PTR EAS_SMF_Parser;
-
-#ifdef _XMF_PARSER
-extern EAS_VOID_PTR EAS_XMF_Parser;
-#endif
-
-#ifdef _SMAF_PARSER
-extern EAS_VOID_PTR EAS_SMAF_Parser;
-#endif
-
-#ifdef _WAVE_PARSER
-extern EAS_VOID_PTR EAS_Wave_Parser;
-#endif
-
-#ifdef _OTA_PARSER
-extern EAS_VOID_PTR EAS_OTA_Parser;
-#endif
-
-#ifdef _IMELODY_PARSER
-extern EAS_VOID_PTR EAS_iMelody_Parser;
-#endif
-
-#ifdef _RTTTL_PARSER
-extern EAS_VOID_PTR EAS_RTTTL_Parser;
-#endif
-
-#if defined (_CMX_PARSER) || defined(_MFI_PARSER)
-extern EAS_VOID_PTR EAS_CMF_Parser;
-#endif
-
-/* initalize pointers to parser interfaces */
-/*lint -e{605} not pretty, but it works */
-EAS_VOID_PTR const parserModules[] =
-{
- &EAS_SMF_Parser,
-
-#ifdef _XMF_PARSER
- &EAS_XMF_Parser,
-#endif
-
-#ifdef _WAVE_PARSER
- &EAS_Wave_Parser,
-#endif
-
-#ifdef _SMAF_PARSER
- &EAS_SMAF_Parser,
-#endif
-
-#ifdef _OTA_PARSER
- &EAS_OTA_Parser,
-#endif
-
-#ifdef _IMELODY_PARSER
- &EAS_iMelody_Parser,
-#endif
-
-#ifdef _RTTTL_PARSER
- &EAS_RTTTL_Parser,
-#endif
-
-#if defined (_CMX_PARSER) || defined(_MFI_PARSER)
- &EAS_CMF_Parser
-#endif
-};
-#define NUM_PARSER_MODULES (sizeof(parserModules) / sizeof(EAS_VOID_PTR))
-
-/*----------------------------------------------------------------------------
- * Data Modules
- *----------------------------------------------------------------------------
-*/
-
-#ifdef _STATIC_MEMORY
-extern EAS_VOID_PTR eas_SMFData;
-extern EAS_VOID_PTR eas_Data;
-extern EAS_VOID_PTR eas_MixBuffer;
-extern EAS_VOID_PTR eas_Synth;
-extern EAS_VOID_PTR eas_MIDI;
-extern EAS_VOID_PTR eas_PCMData;
-extern EAS_VOID_PTR eas_MIDIData;
-
-#ifdef _XMF_PARSER
-extern EAS_VOID_PTR eas_XMFData;
-#endif
-
-#ifdef _SMAF_PARSER
-extern EAS_VOID_PTR eas_SMAFData;
-#endif
-
-#ifdef _OTA_PARSER
-extern EAS_VOID_PTR eas_OTAData;
-#endif
-
-#ifdef _IMELODY_PARSER
-extern EAS_VOID_PTR eas_iMelodyData;
-#endif
-
-#ifdef _RTTTL_PARSER
-extern EAS_VOID_PTR eas_RTTTLData;
-#endif
-
-#ifdef _WAVE_PARSER
-extern EAS_VOID_PTR eas_WaveData;
-#endif
-
-#if defined (_CMX_PARSER) || defined(_MFI_PARSER)
-extern EAS_VOID_PTR eas_CMFData;
-#endif
-#endif
-
-/*----------------------------------------------------------------------------
- *
- * Effects Modules
- *
- * These declarations are used by the EAS library to locate
- * effects modules.
- *----------------------------------------------------------------------------
-*/
-
-#ifdef _ENHANCER_ENABLED
-extern EAS_VOID_PTR EAS_Enhancer;
-#define EAS_ENHANCER_INTERFACE &EAS_Enhancer
-#ifdef _STATIC_MEMORY
-extern EAS_VOID_PTR eas_EnhancerData;
-#define EAS_ENHANCER_DATA &eas_EnhancerData
-#else
-#define EAS_ENHANCER_DATA NULL
-#endif
-#else
-#define EAS_ENHANCER_INTERFACE NULL
-#define EAS_ENHANCER_DATA NULL
-#endif
-
-#ifdef _COMPRESSOR_ENABLED
-extern EAS_VOID_PTR EAS_Compressor;
-#define EAS_COMPRESSOR_INTERFACE &EAS_Compressor
-#ifdef _STATIC_MEMORY
-extern EAS_VOID_PTR eas_CompressorData;
-#define EAS_COMPRESSOR_DATA &eas_CompressorData
-#else
-#define EAS_COMPRESSOR_DATA NULL
-#endif
-#else
-#define EAS_COMPRESSOR_INTERFACE NULL
-#define EAS_COMPRESSOR_DATA NULL
-#endif
-
-#ifdef _MAXIMIZER_ENABLED
-extern EAS_VOID_PTR EAS_Maximizer;
-#define EAS_MAXIMIZER_INTERFACE &EAS_Maximizer
-#ifdef _STATIC_MEMORY
-extern EAS_VOID_PTR eas_MaximizerData;
-#define EAS_MAXIMIZER_DATA &eas_MaximizerData
-#else
-#define EAS_MAXIMIZER_DATA NULL
-#endif
-#else
-#define EAS_MAXIMIZER_INTERFACE NULL
-#define EAS_MAXIMIZER_DATA NULL
-#endif
-
-
-#ifdef _REVERB_ENABLED
-extern EAS_VOID_PTR EAS_Reverb;
-#define EAS_REVERB_INTERFACE &EAS_Reverb
-#ifdef _STATIC_MEMORY
-extern EAS_VOID_PTR eas_ReverbData;
-#define EAS_REVERB_DATA &eas_ReverbData
-#else
-#define EAS_REVERB_DATA NULL
-#endif
-#else
-#define EAS_REVERB_INTERFACE NULL
-#define EAS_REVERB_DATA NULL
-#endif
-
-#ifdef _CHORUS_ENABLED
-extern EAS_VOID_PTR EAS_Chorus;
-#define EAS_CHORUS_INTERFACE &EAS_Chorus
-#ifdef _STATIC_MEMORY
-extern EAS_VOID_PTR eas_ChorusData;
-#define EAS_CHORUS_DATA &eas_ChorusData
-#else
-#define EAS_CHORUS_DATA NULL
-#endif
-#else
-#define EAS_CHORUS_INTERFACE NULL
-#define EAS_CHORUS_DATA NULL
-#endif
-
-#ifdef _WIDENER_ENABLED
-extern EAS_VOID_PTR EAS_Widener;
-#define EAS_WIDENER_INTERFACE &EAS_Widener
-#ifdef _STATIC_MEMORY
-extern EAS_VOID_PTR eas_WidenerData;
-#define EAS_WIDENER_DATA &eas_WidenerData
-#else
-#define EAS_WIDENER_DATA NULL
-#endif
-#else
-#define EAS_WIDENER_INTERFACE NULL
-#define EAS_WIDENER_DATA NULL
-#endif
-
-#ifdef _GRAPHIC_EQ_ENABLED
-extern EAS_VOID_PTR EAS_GraphicEQ;
-#define EAS_GRAPHIC_EQ_INTERFACE &EAS_GraphicEQ
-#ifdef _STATIC_MEMORY
-extern EAS_VOID_PTR eas_GraphicEQData;
-#define EAS_GRAPHIC_EQ_DATA &eas_GraphicEQData
-#else
-#define EAS_GRAPHIC_EQ_DATA NULL
-#endif
-#else
-#define EAS_GRAPHIC_EQ_INTERFACE NULL
-#define EAS_GRAPHIC_EQ_DATA NULL
-#endif
-
-#ifdef _WOW_ENABLED
-extern EAS_VOID_PTR EAS_Wow;
-#define EAS_WOW_INTERFACE &EAS_Wow
-#ifdef _STATIC_MEMORY
-#error "WOW module requires dynamic memory model"
-#else
-#define EAS_WOW_DATA NULL
-#endif
-#else
-#define EAS_WOW_INTERFACE NULL
-#define EAS_WOW_DATA NULL
-#endif
-
-#ifdef _TONECONTROLEQ_ENABLED
-extern EAS_VOID_PTR EAS_ToneControlEQ;
-#define EAS_TONECONTROLEQ_INTERFACE &EAS_ToneControlEQ
-#ifdef _STATIC_MEMORY
-extern EAS_VOID_PTR eas_ToneControlEQData;
-#define EAS_TONECONTROLEQ_DATA &eas_ToneControlEQData
-#else
-#define EAS_TONECONTROLEQ_DATA NULL
-#endif
-#else
-#define EAS_TONECONTROLEQ_INTERFACE NULL
-#define EAS_TONECONTROLEQ_DATA NULL
-#endif
-
-/*lint -e{605} not pretty, but it works */
-EAS_VOID_PTR const effectsModules[] =
-{
- EAS_ENHANCER_INTERFACE,
- EAS_COMPRESSOR_INTERFACE,
- EAS_REVERB_INTERFACE,
- EAS_CHORUS_INTERFACE,
- EAS_WIDENER_INTERFACE,
- EAS_GRAPHIC_EQ_INTERFACE,
- EAS_WOW_INTERFACE,
- EAS_MAXIMIZER_INTERFACE,
- EAS_TONECONTROLEQ_INTERFACE
-};
-
-EAS_VOID_PTR const effectsData[] =
-{
- EAS_ENHANCER_DATA,
- EAS_COMPRESSOR_DATA,
- EAS_REVERB_DATA,
- EAS_CHORUS_DATA,
- EAS_WIDENER_DATA,
- EAS_GRAPHIC_EQ_DATA,
- EAS_WOW_DATA,
- EAS_MAXIMIZER_DATA,
- EAS_TONECONTROLEQ_DATA
-};
-
-/*----------------------------------------------------------------------------
- *
- * Optional Modules
- *
- * These declarations are used by the EAS library to locate
- * effects modules.
- *----------------------------------------------------------------------------
-*/
-
-#ifdef _METRICS_ENABLED
-extern EAS_VOID_PTR EAS_Metrics;
-#define EAS_METRICS_INTERFACE &EAS_Metrics
-#ifdef _STATIC_MEMORY
-extern EAS_VOID_PTR eas_MetricsData;
-#define EAS_METRICS_DATA &eas_MetricsData
-#else
-#define EAS_METRICS_DATA NULL
-#endif
-#else
-#define EAS_METRICS_INTERFACE NULL
-#define EAS_METRICS_DATA NULL
-#endif
-
-#ifdef MMAPI_SUPPORT
-extern EAS_VOID_PTR EAS_TC_Parser;
-#define EAS_TONE_CONTROL_PARSER &EAS_TC_Parser
-#ifdef _STATIC_MEMORY
-extern EAS_VOID_PTR eas_TCData;
-#define EAS_TONE_CONTROL_DATA &eas_TCData
-#else
-#define EAS_TONE_CONTROL_DATA NULL
-#endif
-#else
-#define EAS_TONE_CONTROL_PARSER NULL
-#define EAS_TONE_CONTROL_DATA NULL
-#endif
-
-/*lint -e{605} not pretty, but it works */
-EAS_VOID_PTR const optionalModules[] =
-{
- EAS_TONE_CONTROL_PARSER,
- EAS_METRICS_INTERFACE
-};
-
-EAS_VOID_PTR const optionalData[] =
-{
- EAS_TONE_CONTROL_DATA,
- EAS_METRICS_DATA
-};
-
-/*----------------------------------------------------------------------------
- * EAS_CMStaticMemoryModel()
- *----------------------------------------------------------------------------
- * Purpose:
- * This function returns true if EAS has been configured for
- * a static memory model. There are some limitations in the
- * static memory model, see the documentation for more
- * information.
- *
- * Outputs:
- * returns EAS_TRUE if a module is found
- *----------------------------------------------------------------------------
-*/
-EAS_BOOL EAS_CMStaticMemoryModel (void)
-{
-#ifdef _STATIC_MEMORY
- return EAS_TRUE;
-#else
- return EAS_FALSE;
-#endif
-}
-
-/*----------------------------------------------------------------------------
- * EAS_CMEnumModules()
- *----------------------------------------------------------------------------
- * Purpose:
- * This function is used to find pointers to optional modules.
- *
- * Inputs:
- * module - module number
- *
- * Outputs:
- * returns a pointer to the module function table or NULL if no module
- *----------------------------------------------------------------------------
-*/
-EAS_VOID_PTR EAS_CMEnumModules (EAS_INT module)
-{
-
- if (module >= (EAS_INT) NUM_PARSER_MODULES)
- return NULL;
- return parserModules[module];
-}
-
-/*----------------------------------------------------------------------------
- * EAS_CMEnumData()
- *----------------------------------------------------------------------------
- * Purpose:
- * This function is used to find pointers to static memory allocations.
- *
- * Inputs:
- * dataModule - enumerated module number
- *
- * Outputs:
- * Returns handle to data or NULL if not found
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, dataModule) used only when _STATIC_MEMORY is defined */
-EAS_VOID_PTR EAS_CMEnumData (EAS_INT dataModule)
-{
-
-#ifdef _STATIC_MEMORY
- switch (dataModule)
- {
-
- /* main instance data for synthesizer */
- case EAS_CM_EAS_DATA:
- return &eas_Data;
-
- /* mix buffer for mix engine */
- case EAS_CM_MIX_BUFFER:
- /*lint -e{545} lint doesn't like this because it sees the underlying type */
- return &eas_MixBuffer;
-
- /* instance data for synth */
- case EAS_CM_SYNTH_DATA:
- return &eas_Synth;
-
- /* instance data for MIDI parser */
- case EAS_CM_MIDI_DATA:
- return &eas_MIDI;
-
- /* instance data for SMF parser */
- case EAS_CM_SMF_DATA:
- return &eas_SMFData;
-
-#ifdef _XMF_PARSER
- /* instance data for XMF parser */
- case EAS_CM_XMF_DATA:
- return &eas_XMFData;
-#endif
-
-#ifdef _SMAF_PARSER
- /* instance data for SMAF parser */
- case EAS_CM_SMAF_DATA:
- return &eas_SMAFData;
-#endif
-
- /* instance data for the PCM engine */
- case EAS_CM_PCM_DATA:
- /*lint -e{545} lint doesn't like this because it sees the underlying type */
- return &eas_PCMData;
-
- case EAS_CM_MIDI_STREAM_DATA:
- return &eas_MIDIData;
-
-#ifdef _OTA_PARSER
- /* instance data for OTA parser */
- case EAS_CM_OTA_DATA:
- return &eas_OTAData;
-#endif
-
-#ifdef _IMELODY_PARSER
- /* instance data for iMelody parser */
- case EAS_CM_IMELODY_DATA:
- return &eas_iMelodyData;
-#endif
-
-#ifdef _RTTTL_PARSER
- /* instance data for RTTTL parser */
- case EAS_CM_RTTTL_DATA:
- return &eas_RTTTLData;
-#endif
-
-#ifdef _WAVE_PARSER
- /* instance data for WAVE parser */
- case EAS_CM_WAVE_DATA:
- return &eas_WaveData;
-#endif
-
-#if defined (_CMX_PARSER) || defined(_MFI_PARSER)
- /* instance data for CMF parser */
- case EAS_CM_CMF_DATA:
- return &eas_CMFData;
-#endif
-
- default:
- return NULL;
- }
-
-#else
- return NULL;
-#endif
-}
-
-/*----------------------------------------------------------------------------
- * EAS_CMEnumFXModules()
- *----------------------------------------------------------------------------
- * Purpose:
- * This function is used to find pointers to optional effects modules.
- *
- * Inputs:
- * module - enumerated module number
- * pModule - pointer to module interface
- *
- * Outputs:
- * Returns pointer to function table or NULL if not found
- *----------------------------------------------------------------------------
-*/
-EAS_VOID_PTR EAS_CMEnumFXModules (EAS_INT module)
-{
-
- if (module >= NUM_EFFECTS_MODULES)
- return NULL;
- return effectsModules[module];
-}
-
-/*----------------------------------------------------------------------------
- * EAS_CMEnumFXData()
- *----------------------------------------------------------------------------
- * Purpose:
- * This function is used to find pointers to static memory allocations.
- *
- * Inputs:
- * dataModule - enumerated module number
- * pData - pointer to handle variable
- *
- * Outputs:
- * Returns handle to data or NULL if not found
- *----------------------------------------------------------------------------
-*/
-EAS_VOID_PTR EAS_CMEnumFXData (EAS_INT dataModule)
-{
-
- if (dataModule >= NUM_EFFECTS_MODULES)
- return NULL;
- return effectsData[dataModule];
-}
-
-/*----------------------------------------------------------------------------
- * EAS_CMEnumOptModules()
- *----------------------------------------------------------------------------
- * Purpose:
- * This function is used to find pointers to optional modules.
- *
- * Inputs:
- * module - enumerated module number
- *
- * Outputs:
- * returns pointer to function table or NULL if no module
- *----------------------------------------------------------------------------
-*/
-EAS_VOID_PTR EAS_CMEnumOptModules (EAS_INT module)
-{
-
- /* sanity check */
- if (module >= NUM_OPTIONAL_MODULES)
- return EAS_FALSE;
- return optionalModules[module];
-}
-
-/*----------------------------------------------------------------------------
- * EAS_CMEnumOptData()
- *----------------------------------------------------------------------------
- * Purpose:
- * This function is used to find pointers to static memory allocations.
- *
- * Inputs:
- * dataModule - enumerated module number
- *
- * Outputs:
- * Returns handle to data or NULL if not found
- *----------------------------------------------------------------------------
-*/
-EAS_VOID_PTR EAS_CMEnumOptData (EAS_INT dataModule)
-{
-
- if (dataModule >= NUM_OPTIONAL_MODULES)
- return NULL;
- return optionalData[dataModule];
-}
-
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 796 $
+ * $Date: 2007-08-01 00:15:25 -0700 (Wed, 01 Aug 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+#include "eas.h"
+#include "eas_config.h"
+
+
+#ifdef _MFI_PARSER
+/*----------------------------------------------------------------------------
+ * Vendor/Device ID for MFi Extensions
+ *
+ * Define the preprocessor symbols to establish the vendor ID and
+ * device ID for the MFi PCM/ADPCM extensions.
+ *----------------------------------------------------------------------------
+*/
+const EAS_U8 eas_MFIVendorIDMSB = (MFI_VENDOR_ID >> 8) & 0xff;
+const EAS_U8 eas_MFIVendorIDLSB = MFI_VENDOR_ID & 0xff;
+const EAS_U8 eas_MFIDeviceID = MFI_DEVICE_ID;
+#endif
+
+/*----------------------------------------------------------------------------
+ *
+ * parserModules
+ *
+ * This structure is used by the EAS library to locate file parsing
+ * modules.
+ *----------------------------------------------------------------------------
+*/
+
+/* define the external file parsers */
+extern EAS_VOID_PTR EAS_SMF_Parser;
+
+#ifdef _XMF_PARSER
+extern EAS_VOID_PTR EAS_XMF_Parser;
+#endif
+
+#ifdef _SMAF_PARSER
+extern EAS_VOID_PTR EAS_SMAF_Parser;
+#endif
+
+#ifdef _WAVE_PARSER
+extern EAS_VOID_PTR EAS_Wave_Parser;
+#endif
+
+#ifdef _OTA_PARSER
+extern EAS_VOID_PTR EAS_OTA_Parser;
+#endif
+
+#ifdef _IMELODY_PARSER
+extern EAS_VOID_PTR EAS_iMelody_Parser;
+#endif
+
+#ifdef _RTTTL_PARSER
+extern EAS_VOID_PTR EAS_RTTTL_Parser;
+#endif
+
+#if defined (_CMX_PARSER) || defined(_MFI_PARSER)
+extern EAS_VOID_PTR EAS_CMF_Parser;
+#endif
+
+/* initalize pointers to parser interfaces */
+/*lint -e{605} not pretty, but it works */
+EAS_VOID_PTR const parserModules[] =
+{
+ &EAS_SMF_Parser,
+
+#ifdef _XMF_PARSER
+ &EAS_XMF_Parser,
+#endif
+
+#ifdef _WAVE_PARSER
+ &EAS_Wave_Parser,
+#endif
+
+#ifdef _SMAF_PARSER
+ &EAS_SMAF_Parser,
+#endif
+
+#ifdef _OTA_PARSER
+ &EAS_OTA_Parser,
+#endif
+
+#ifdef _IMELODY_PARSER
+ &EAS_iMelody_Parser,
+#endif
+
+#ifdef _RTTTL_PARSER
+ &EAS_RTTTL_Parser,
+#endif
+
+#if defined (_CMX_PARSER) || defined(_MFI_PARSER)
+ &EAS_CMF_Parser
+#endif
+};
+#define NUM_PARSER_MODULES (sizeof(parserModules) / sizeof(EAS_VOID_PTR))
+
+/*----------------------------------------------------------------------------
+ * Data Modules
+ *----------------------------------------------------------------------------
+*/
+
+#ifdef _STATIC_MEMORY
+extern EAS_VOID_PTR eas_SMFData;
+extern EAS_VOID_PTR eas_Data;
+extern EAS_VOID_PTR eas_MixBuffer;
+extern EAS_VOID_PTR eas_Synth;
+extern EAS_VOID_PTR eas_MIDI;
+extern EAS_VOID_PTR eas_PCMData;
+extern EAS_VOID_PTR eas_MIDIData;
+
+#ifdef _XMF_PARSER
+extern EAS_VOID_PTR eas_XMFData;
+#endif
+
+#ifdef _SMAF_PARSER
+extern EAS_VOID_PTR eas_SMAFData;
+#endif
+
+#ifdef _OTA_PARSER
+extern EAS_VOID_PTR eas_OTAData;
+#endif
+
+#ifdef _IMELODY_PARSER
+extern EAS_VOID_PTR eas_iMelodyData;
+#endif
+
+#ifdef _RTTTL_PARSER
+extern EAS_VOID_PTR eas_RTTTLData;
+#endif
+
+#ifdef _WAVE_PARSER
+extern EAS_VOID_PTR eas_WaveData;
+#endif
+
+#if defined (_CMX_PARSER) || defined(_MFI_PARSER)
+extern EAS_VOID_PTR eas_CMFData;
+#endif
+#endif
+
+/*----------------------------------------------------------------------------
+ *
+ * Effects Modules
+ *
+ * These declarations are used by the EAS library to locate
+ * effects modules.
+ *----------------------------------------------------------------------------
+*/
+
+#ifdef _ENHANCER_ENABLED
+extern EAS_VOID_PTR EAS_Enhancer;
+#define EAS_ENHANCER_INTERFACE &EAS_Enhancer
+#ifdef _STATIC_MEMORY
+extern EAS_VOID_PTR eas_EnhancerData;
+#define EAS_ENHANCER_DATA &eas_EnhancerData
+#else
+#define EAS_ENHANCER_DATA NULL
+#endif
+#else
+#define EAS_ENHANCER_INTERFACE NULL
+#define EAS_ENHANCER_DATA NULL
+#endif
+
+#ifdef _COMPRESSOR_ENABLED
+extern EAS_VOID_PTR EAS_Compressor;
+#define EAS_COMPRESSOR_INTERFACE &EAS_Compressor
+#ifdef _STATIC_MEMORY
+extern EAS_VOID_PTR eas_CompressorData;
+#define EAS_COMPRESSOR_DATA &eas_CompressorData
+#else
+#define EAS_COMPRESSOR_DATA NULL
+#endif
+#else
+#define EAS_COMPRESSOR_INTERFACE NULL
+#define EAS_COMPRESSOR_DATA NULL
+#endif
+
+#ifdef _MAXIMIZER_ENABLED
+extern EAS_VOID_PTR EAS_Maximizer;
+#define EAS_MAXIMIZER_INTERFACE &EAS_Maximizer
+#ifdef _STATIC_MEMORY
+extern EAS_VOID_PTR eas_MaximizerData;
+#define EAS_MAXIMIZER_DATA &eas_MaximizerData
+#else
+#define EAS_MAXIMIZER_DATA NULL
+#endif
+#else
+#define EAS_MAXIMIZER_INTERFACE NULL
+#define EAS_MAXIMIZER_DATA NULL
+#endif
+
+
+#ifdef _REVERB_ENABLED
+extern EAS_VOID_PTR EAS_Reverb;
+#define EAS_REVERB_INTERFACE &EAS_Reverb
+#ifdef _STATIC_MEMORY
+extern EAS_VOID_PTR eas_ReverbData;
+#define EAS_REVERB_DATA &eas_ReverbData
+#else
+#define EAS_REVERB_DATA NULL
+#endif
+#else
+#define EAS_REVERB_INTERFACE NULL
+#define EAS_REVERB_DATA NULL
+#endif
+
+#ifdef _CHORUS_ENABLED
+extern EAS_VOID_PTR EAS_Chorus;
+#define EAS_CHORUS_INTERFACE &EAS_Chorus
+#ifdef _STATIC_MEMORY
+extern EAS_VOID_PTR eas_ChorusData;
+#define EAS_CHORUS_DATA &eas_ChorusData
+#else
+#define EAS_CHORUS_DATA NULL
+#endif
+#else
+#define EAS_CHORUS_INTERFACE NULL
+#define EAS_CHORUS_DATA NULL
+#endif
+
+#ifdef _WIDENER_ENABLED
+extern EAS_VOID_PTR EAS_Widener;
+#define EAS_WIDENER_INTERFACE &EAS_Widener
+#ifdef _STATIC_MEMORY
+extern EAS_VOID_PTR eas_WidenerData;
+#define EAS_WIDENER_DATA &eas_WidenerData
+#else
+#define EAS_WIDENER_DATA NULL
+#endif
+#else
+#define EAS_WIDENER_INTERFACE NULL
+#define EAS_WIDENER_DATA NULL
+#endif
+
+#ifdef _GRAPHIC_EQ_ENABLED
+extern EAS_VOID_PTR EAS_GraphicEQ;
+#define EAS_GRAPHIC_EQ_INTERFACE &EAS_GraphicEQ
+#ifdef _STATIC_MEMORY
+extern EAS_VOID_PTR eas_GraphicEQData;
+#define EAS_GRAPHIC_EQ_DATA &eas_GraphicEQData
+#else
+#define EAS_GRAPHIC_EQ_DATA NULL
+#endif
+#else
+#define EAS_GRAPHIC_EQ_INTERFACE NULL
+#define EAS_GRAPHIC_EQ_DATA NULL
+#endif
+
+#ifdef _WOW_ENABLED
+extern EAS_VOID_PTR EAS_Wow;
+#define EAS_WOW_INTERFACE &EAS_Wow
+#ifdef _STATIC_MEMORY
+#error "WOW module requires dynamic memory model"
+#else
+#define EAS_WOW_DATA NULL
+#endif
+#else
+#define EAS_WOW_INTERFACE NULL
+#define EAS_WOW_DATA NULL
+#endif
+
+#ifdef _TONECONTROLEQ_ENABLED
+extern EAS_VOID_PTR EAS_ToneControlEQ;
+#define EAS_TONECONTROLEQ_INTERFACE &EAS_ToneControlEQ
+#ifdef _STATIC_MEMORY
+extern EAS_VOID_PTR eas_ToneControlEQData;
+#define EAS_TONECONTROLEQ_DATA &eas_ToneControlEQData
+#else
+#define EAS_TONECONTROLEQ_DATA NULL
+#endif
+#else
+#define EAS_TONECONTROLEQ_INTERFACE NULL
+#define EAS_TONECONTROLEQ_DATA NULL
+#endif
+
+/*lint -e{605} not pretty, but it works */
+EAS_VOID_PTR const effectsModules[] =
+{
+ EAS_ENHANCER_INTERFACE,
+ EAS_COMPRESSOR_INTERFACE,
+ EAS_REVERB_INTERFACE,
+ EAS_CHORUS_INTERFACE,
+ EAS_WIDENER_INTERFACE,
+ EAS_GRAPHIC_EQ_INTERFACE,
+ EAS_WOW_INTERFACE,
+ EAS_MAXIMIZER_INTERFACE,
+ EAS_TONECONTROLEQ_INTERFACE
+};
+
+EAS_VOID_PTR const effectsData[] =
+{
+ EAS_ENHANCER_DATA,
+ EAS_COMPRESSOR_DATA,
+ EAS_REVERB_DATA,
+ EAS_CHORUS_DATA,
+ EAS_WIDENER_DATA,
+ EAS_GRAPHIC_EQ_DATA,
+ EAS_WOW_DATA,
+ EAS_MAXIMIZER_DATA,
+ EAS_TONECONTROLEQ_DATA
+};
+
+/*----------------------------------------------------------------------------
+ *
+ * Optional Modules
+ *
+ * These declarations are used by the EAS library to locate
+ * effects modules.
+ *----------------------------------------------------------------------------
+*/
+
+#ifdef _METRICS_ENABLED
+extern EAS_VOID_PTR EAS_Metrics;
+#define EAS_METRICS_INTERFACE &EAS_Metrics
+#ifdef _STATIC_MEMORY
+extern EAS_VOID_PTR eas_MetricsData;
+#define EAS_METRICS_DATA &eas_MetricsData
+#else
+#define EAS_METRICS_DATA NULL
+#endif
+#else
+#define EAS_METRICS_INTERFACE NULL
+#define EAS_METRICS_DATA NULL
+#endif
+
+#ifdef MMAPI_SUPPORT
+extern EAS_VOID_PTR EAS_TC_Parser;
+#define EAS_TONE_CONTROL_PARSER &EAS_TC_Parser
+#ifdef _STATIC_MEMORY
+extern EAS_VOID_PTR eas_TCData;
+#define EAS_TONE_CONTROL_DATA &eas_TCData
+#else
+#define EAS_TONE_CONTROL_DATA NULL
+#endif
+#else
+#define EAS_TONE_CONTROL_PARSER NULL
+#define EAS_TONE_CONTROL_DATA NULL
+#endif
+
+/*lint -e{605} not pretty, but it works */
+EAS_VOID_PTR const optionalModules[] =
+{
+ EAS_TONE_CONTROL_PARSER,
+ EAS_METRICS_INTERFACE
+};
+
+EAS_VOID_PTR const optionalData[] =
+{
+ EAS_TONE_CONTROL_DATA,
+ EAS_METRICS_DATA
+};
+
+/*----------------------------------------------------------------------------
+ * EAS_CMStaticMemoryModel()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * This function returns true if EAS has been configured for
+ * a static memory model. There are some limitations in the
+ * static memory model, see the documentation for more
+ * information.
+ *
+ * Outputs:
+ * returns EAS_TRUE if a module is found
+ *----------------------------------------------------------------------------
+*/
+EAS_BOOL EAS_CMStaticMemoryModel (void)
+{
+#ifdef _STATIC_MEMORY
+ return EAS_TRUE;
+#else
+ return EAS_FALSE;
+#endif
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_CMEnumModules()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * This function is used to find pointers to optional modules.
+ *
+ * Inputs:
+ * module - module number
+ *
+ * Outputs:
+ * returns a pointer to the module function table or NULL if no module
+ *----------------------------------------------------------------------------
+*/
+EAS_VOID_PTR EAS_CMEnumModules (EAS_INT module)
+{
+
+ if (module >= (EAS_INT) NUM_PARSER_MODULES)
+ return NULL;
+ return parserModules[module];
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_CMEnumData()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * This function is used to find pointers to static memory allocations.
+ *
+ * Inputs:
+ * dataModule - enumerated module number
+ *
+ * Outputs:
+ * Returns handle to data or NULL if not found
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, dataModule) used only when _STATIC_MEMORY is defined */
+EAS_VOID_PTR EAS_CMEnumData (EAS_INT dataModule)
+{
+
+#ifdef _STATIC_MEMORY
+ switch (dataModule)
+ {
+
+ /* main instance data for synthesizer */
+ case EAS_CM_EAS_DATA:
+ return &eas_Data;
+
+ /* mix buffer for mix engine */
+ case EAS_CM_MIX_BUFFER:
+ /*lint -e{545} lint doesn't like this because it sees the underlying type */
+ return &eas_MixBuffer;
+
+ /* instance data for synth */
+ case EAS_CM_SYNTH_DATA:
+ return &eas_Synth;
+
+ /* instance data for MIDI parser */
+ case EAS_CM_MIDI_DATA:
+ return &eas_MIDI;
+
+ /* instance data for SMF parser */
+ case EAS_CM_SMF_DATA:
+ return &eas_SMFData;
+
+#ifdef _XMF_PARSER
+ /* instance data for XMF parser */
+ case EAS_CM_XMF_DATA:
+ return &eas_XMFData;
+#endif
+
+#ifdef _SMAF_PARSER
+ /* instance data for SMAF parser */
+ case EAS_CM_SMAF_DATA:
+ return &eas_SMAFData;
+#endif
+
+ /* instance data for the PCM engine */
+ case EAS_CM_PCM_DATA:
+ /*lint -e{545} lint doesn't like this because it sees the underlying type */
+ return &eas_PCMData;
+
+ case EAS_CM_MIDI_STREAM_DATA:
+ return &eas_MIDIData;
+
+#ifdef _OTA_PARSER
+ /* instance data for OTA parser */
+ case EAS_CM_OTA_DATA:
+ return &eas_OTAData;
+#endif
+
+#ifdef _IMELODY_PARSER
+ /* instance data for iMelody parser */
+ case EAS_CM_IMELODY_DATA:
+ return &eas_iMelodyData;
+#endif
+
+#ifdef _RTTTL_PARSER
+ /* instance data for RTTTL parser */
+ case EAS_CM_RTTTL_DATA:
+ return &eas_RTTTLData;
+#endif
+
+#ifdef _WAVE_PARSER
+ /* instance data for WAVE parser */
+ case EAS_CM_WAVE_DATA:
+ return &eas_WaveData;
+#endif
+
+#if defined (_CMX_PARSER) || defined(_MFI_PARSER)
+ /* instance data for CMF parser */
+ case EAS_CM_CMF_DATA:
+ return &eas_CMFData;
+#endif
+
+ default:
+ return NULL;
+ }
+
+#else
+ return NULL;
+#endif
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_CMEnumFXModules()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * This function is used to find pointers to optional effects modules.
+ *
+ * Inputs:
+ * module - enumerated module number
+ * pModule - pointer to module interface
+ *
+ * Outputs:
+ * Returns pointer to function table or NULL if not found
+ *----------------------------------------------------------------------------
+*/
+EAS_VOID_PTR EAS_CMEnumFXModules (EAS_INT module)
+{
+
+ if (module >= NUM_EFFECTS_MODULES)
+ return NULL;
+ return effectsModules[module];
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_CMEnumFXData()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * This function is used to find pointers to static memory allocations.
+ *
+ * Inputs:
+ * dataModule - enumerated module number
+ * pData - pointer to handle variable
+ *
+ * Outputs:
+ * Returns handle to data or NULL if not found
+ *----------------------------------------------------------------------------
+*/
+EAS_VOID_PTR EAS_CMEnumFXData (EAS_INT dataModule)
+{
+
+ if (dataModule >= NUM_EFFECTS_MODULES)
+ return NULL;
+ return effectsData[dataModule];
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_CMEnumOptModules()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * This function is used to find pointers to optional modules.
+ *
+ * Inputs:
+ * module - enumerated module number
+ *
+ * Outputs:
+ * returns pointer to function table or NULL if no module
+ *----------------------------------------------------------------------------
+*/
+EAS_VOID_PTR EAS_CMEnumOptModules (EAS_INT module)
+{
+
+ /* sanity check */
+ if (module >= NUM_OPTIONAL_MODULES)
+ return EAS_FALSE;
+ return optionalModules[module];
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_CMEnumOptData()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * This function is used to find pointers to static memory allocations.
+ *
+ * Inputs:
+ * dataModule - enumerated module number
+ *
+ * Outputs:
+ * Returns handle to data or NULL if not found
+ *----------------------------------------------------------------------------
+*/
+EAS_VOID_PTR EAS_CMEnumOptData (EAS_INT dataModule)
+{
+
+ if (dataModule >= NUM_OPTIONAL_MODULES)
+ return NULL;
+ return optionalData[dataModule];
+}
+
+
diff --git a/arm-hybrid-22k/host_src/eas_config.h b/arm-hybrid-22k/host_src/eas_config.h
index d16be4a..49c2ef2 100644
--- a/arm-hybrid-22k/host_src/eas_config.h
+++ b/arm-hybrid-22k/host_src/eas_config.h
@@ -1,22 +1,22 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_config.h
- *
- * Contents and purpose:
- * This header declares the Configuration Module interface (CM). The CM
- * is a module compiled external to the library that sets the configuration
- * for this build. It allows the library to find optional components and
- * links to static memory allocations (when used in a static configuration).
- *
- * NOTE: This module is not intended to be modified by the customer. It
- * needs to be included in the build process with the correct configuration
- * defines (see the library documentation for information on how to configure
- * the library).
- *
- * DO NOT MODIFY THIS FILE!
- *
- * Copyright 2005 Sonic Network Inc.
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_config.h
+ *
+ * Contents and purpose:
+ * This header declares the Configuration Module interface (CM). The CM
+ * is a module compiled external to the library that sets the configuration
+ * for this build. It allows the library to find optional components and
+ * links to static memory allocations (when used in a static configuration).
+ *
+ * NOTE: This module is not intended to be modified by the customer. It
+ * needs to be included in the build process with the correct configuration
+ * defines (see the library documentation for information on how to configure
+ * the library).
+ *
+ * DO NOT MODIFY THIS FILE!
+ *
+ * Copyright 2005 Sonic Network Inc.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -29,163 +29,163 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 82 $
- * $Date: 2006-07-10 11:45:19 -0700 (Mon, 10 Jul 2006) $
- *----------------------------------------------------------------------------
-*/
-
-// sentinel
-#ifndef _EAS_CONFIG_H
-#define _EAS_CONFIG_H
-
-#include "eas_types.h"
-
-/* list of enumerators for optional modules */
-typedef enum {
- EAS_CM_FILE_PARSERS = 1
-} E_CM_ENUM_MODULES;
-
-/* list of enumerators for module and memory pointers */
-typedef enum {
- EAS_CM_EAS_DATA = 1,
- EAS_CM_MIX_BUFFER,
- EAS_CM_SYNTH_DATA,
- EAS_CM_MIDI_DATA,
- EAS_CM_SMF_DATA,
- EAS_CM_XMF_DATA,
- EAS_CM_SMAF_DATA,
- EAS_CM_PCM_DATA,
- EAS_CM_MIDI_STREAM_DATA,
- EAS_CM_METRICS_DATA,
- EAS_CM_OTA_DATA,
- EAS_CM_IMELODY_DATA,
- EAS_CM_RTTTL_DATA,
- EAS_CM_WAVE_DATA,
- EAS_CM_CMF_DATA
-} E_CM_DATA_MODULES;
-
-typedef struct
-{
- int maxSMFStreams;
- void *pSMFData;
- void *pSMFStream;
-} S_EAS_SMF_PTRS;
-
-typedef struct
-{
- int maxSMAFStreams;
- void *pSMAFData;
- void *pSMAFStream;
-} S_EAS_SMAF_PTRS;
-
-/*----------------------------------------------------------------------------
- * EAS_CMStaticMemoryModel()
- *----------------------------------------------------------------------------
- * Purpose:
- * This function returns true if EAS has been configured for
- * a static memory model. There are some limitations in the
- * static memory model, see the documentation for more
- * information.
- *
- * Outputs:
- * returns EAS_TRUE if a module is found
- *----------------------------------------------------------------------------
-*/
-EAS_BOOL EAS_CMStaticMemoryModel (void);
-
-/*----------------------------------------------------------------------------
- * EAS_CMEnumModules()
- *----------------------------------------------------------------------------
- * Purpose:
- * This function is used to find pointers to optional modules.
- *
- * Inputs:
- * module - module number
- *
- * Outputs:
- * returns a pointer to the module function table or NULL if no module
- *----------------------------------------------------------------------------
-*/
-EAS_VOID_PTR EAS_CMEnumModules (EAS_INT module);
-
-/*----------------------------------------------------------------------------
- * EAS_CMEnumData()
- *----------------------------------------------------------------------------
- * Purpose:
- * This function is used to find pointers to static memory allocations.
- *
- * Inputs:
- * dataModule - enumerated module number
- *
- * Outputs:
- * Returns handle to data or NULL if not found
- *----------------------------------------------------------------------------
-*/
-EAS_VOID_PTR EAS_CMEnumData (EAS_INT dataModule);
-
-/*----------------------------------------------------------------------------
- * EAS_CMEnumFXModules()
- *----------------------------------------------------------------------------
- * Purpose:
- * This function is used to find pointers to optional effects modules.
- *
- * Inputs:
- * module - enumerated module number
- * pModule - pointer to module interface
- *
- * Outputs:
- * Returns pointer to function table or NULL if not found
- *----------------------------------------------------------------------------
-*/
-EAS_VOID_PTR EAS_CMEnumFXModules (EAS_INT module);
-
-/*----------------------------------------------------------------------------
- * EAS_CMEnumFXData()
- *----------------------------------------------------------------------------
- * Purpose:
- * This function is used to find pointers to static memory allocations.
- *
- * Inputs:
- * dataModule - enumerated module number
- * pData - pointer to handle variable
- *
- * Outputs:
- * Returns handle to data or NULL if not found
- *----------------------------------------------------------------------------
-*/
-EAS_VOID_PTR EAS_CMEnumFXData (EAS_INT dataModule);
-
-/*----------------------------------------------------------------------------
- * EAS_CMEnumOptModules()
- *----------------------------------------------------------------------------
- * Purpose:
- * This function is used to find pointers to optional modules.
- *
- * Inputs:
- * module - enumerated module number
- *
- * Outputs:
- * returns pointer to function table or NULL if no module
- *----------------------------------------------------------------------------
-*/
-EAS_VOID_PTR EAS_CMEnumOptModules (EAS_INT module);
-
-/*----------------------------------------------------------------------------
- * EAS_CMEnumOptData()
- *----------------------------------------------------------------------------
- * Purpose:
- * This function is used to find pointers to static memory allocations.
- *
- * Inputs:
- * dataModule - enumerated module number
- *
- * Outputs:
- * Returns handle to data or NULL if not found
- *----------------------------------------------------------------------------
-*/
-EAS_VOID_PTR EAS_CMEnumOptData (EAS_INT dataModule);
-
-#endif /* end _EAS_CONFIG_H */
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 82 $
+ * $Date: 2006-07-10 11:45:19 -0700 (Mon, 10 Jul 2006) $
+ *----------------------------------------------------------------------------
+*/
+
+// sentinel
+#ifndef _EAS_CONFIG_H
+#define _EAS_CONFIG_H
+
+#include "eas_types.h"
+
+/* list of enumerators for optional modules */
+typedef enum {
+ EAS_CM_FILE_PARSERS = 1
+} E_CM_ENUM_MODULES;
+
+/* list of enumerators for module and memory pointers */
+typedef enum {
+ EAS_CM_EAS_DATA = 1,
+ EAS_CM_MIX_BUFFER,
+ EAS_CM_SYNTH_DATA,
+ EAS_CM_MIDI_DATA,
+ EAS_CM_SMF_DATA,
+ EAS_CM_XMF_DATA,
+ EAS_CM_SMAF_DATA,
+ EAS_CM_PCM_DATA,
+ EAS_CM_MIDI_STREAM_DATA,
+ EAS_CM_METRICS_DATA,
+ EAS_CM_OTA_DATA,
+ EAS_CM_IMELODY_DATA,
+ EAS_CM_RTTTL_DATA,
+ EAS_CM_WAVE_DATA,
+ EAS_CM_CMF_DATA
+} E_CM_DATA_MODULES;
+
+typedef struct
+{
+ int maxSMFStreams;
+ void *pSMFData;
+ void *pSMFStream;
+} S_EAS_SMF_PTRS;
+
+typedef struct
+{
+ int maxSMAFStreams;
+ void *pSMAFData;
+ void *pSMAFStream;
+} S_EAS_SMAF_PTRS;
+
+/*----------------------------------------------------------------------------
+ * EAS_CMStaticMemoryModel()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * This function returns true if EAS has been configured for
+ * a static memory model. There are some limitations in the
+ * static memory model, see the documentation for more
+ * information.
+ *
+ * Outputs:
+ * returns EAS_TRUE if a module is found
+ *----------------------------------------------------------------------------
+*/
+EAS_BOOL EAS_CMStaticMemoryModel (void);
+
+/*----------------------------------------------------------------------------
+ * EAS_CMEnumModules()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * This function is used to find pointers to optional modules.
+ *
+ * Inputs:
+ * module - module number
+ *
+ * Outputs:
+ * returns a pointer to the module function table or NULL if no module
+ *----------------------------------------------------------------------------
+*/
+EAS_VOID_PTR EAS_CMEnumModules (EAS_INT module);
+
+/*----------------------------------------------------------------------------
+ * EAS_CMEnumData()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * This function is used to find pointers to static memory allocations.
+ *
+ * Inputs:
+ * dataModule - enumerated module number
+ *
+ * Outputs:
+ * Returns handle to data or NULL if not found
+ *----------------------------------------------------------------------------
+*/
+EAS_VOID_PTR EAS_CMEnumData (EAS_INT dataModule);
+
+/*----------------------------------------------------------------------------
+ * EAS_CMEnumFXModules()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * This function is used to find pointers to optional effects modules.
+ *
+ * Inputs:
+ * module - enumerated module number
+ * pModule - pointer to module interface
+ *
+ * Outputs:
+ * Returns pointer to function table or NULL if not found
+ *----------------------------------------------------------------------------
+*/
+EAS_VOID_PTR EAS_CMEnumFXModules (EAS_INT module);
+
+/*----------------------------------------------------------------------------
+ * EAS_CMEnumFXData()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * This function is used to find pointers to static memory allocations.
+ *
+ * Inputs:
+ * dataModule - enumerated module number
+ * pData - pointer to handle variable
+ *
+ * Outputs:
+ * Returns handle to data or NULL if not found
+ *----------------------------------------------------------------------------
+*/
+EAS_VOID_PTR EAS_CMEnumFXData (EAS_INT dataModule);
+
+/*----------------------------------------------------------------------------
+ * EAS_CMEnumOptModules()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * This function is used to find pointers to optional modules.
+ *
+ * Inputs:
+ * module - enumerated module number
+ *
+ * Outputs:
+ * returns pointer to function table or NULL if no module
+ *----------------------------------------------------------------------------
+*/
+EAS_VOID_PTR EAS_CMEnumOptModules (EAS_INT module);
+
+/*----------------------------------------------------------------------------
+ * EAS_CMEnumOptData()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * This function is used to find pointers to static memory allocations.
+ *
+ * Inputs:
+ * dataModule - enumerated module number
+ *
+ * Outputs:
+ * Returns handle to data or NULL if not found
+ *----------------------------------------------------------------------------
+*/
+EAS_VOID_PTR EAS_CMEnumOptData (EAS_INT dataModule);
+
+#endif /* end _EAS_CONFIG_H */
diff --git a/arm-hybrid-22k/host_src/eas_debugmsgs.h b/arm-hybrid-22k/host_src/eas_debugmsgs.h
index 3fff38f..df120bc 100644
--- a/arm-hybrid-22k/host_src/eas_debugmsgs.h
+++ b/arm-hybrid-22k/host_src/eas_debugmsgs.h
@@ -1,44 +1,44 @@
-/* Auto-generated from source file: eas_chorusdata.c */
-/* Auto-generated from source file: eas_imelodydata.c */
-/* Auto-generated from source file: eas_mididata.c */
-/* Auto-generated from source file: eas_pan.c */
-/* Auto-generated from source file: eas_wavefiledata.c */
-/* Auto-generated from source file: eas_voicemgt.c */
-/* Auto-generated from source file: eas_ota.c */
-/* Auto-generated from source file: eas_mixbuf.c */
-/* Auto-generated from source file: eas_rtttl.c */
-/* Auto-generated from source file: eas_reverb.c */
-/* Auto-generated from source file: eas_fmsynth.c */
-/* Auto-generated from source file: eas_pcmdata.c */
-/* Auto-generated from source file: eas_chorus.c */
-/* Auto-generated from source file: eas_math.c */
-/* Auto-generated from source file: eas_fmengine.c */
-/* Auto-generated from source file: eas_smfdata.c */
-/* Auto-generated from source file: eas_fmtables.c */
-/* Auto-generated from source file: eas_imelody.c */
-/* Auto-generated from source file: eas_public.c */
-/* Auto-generated from source file: eas_rtttldata.c */
-/* Auto-generated from source file: eas_reverbdata.c */
-/* Auto-generated from source file: eas_wtengine.c */
-/* Auto-generated from source file: eas_imaadpcm.c */
-{ 0x2380b977, 0x00000006, "eas_imaadpcm.c[305]: IMADecoderLocate: Time=%d, samples=%d\n" },
-{ 0x2380b977, 0x00000007, "eas_imaadpcm.c[328]: IMADecoderLocate: Looped sample, numBlocks=%d, samplesPerLoop=%d, samplesInLastBlock=%d, samples=%d\n" },
-{ 0x2380b977, 0x00000008, "eas_imaadpcm.c[335]: IMADecoderLocate: Byte location in audio = %d\n" },
-{ 0x2380b977, 0x00000009, "eas_imaadpcm.c[345]: IMADecoderLocate: bytesLeft = %d\n" },
-/* Auto-generated from source file: eas_midi.c */
-/* Auto-generated from source file: eas_otadata.c */
-/* Auto-generated from source file: eas_ima_tables.c */
-/* Auto-generated from source file: eas_data.c */
-/* Auto-generated from source file: eas_pcm.c */
-/* Auto-generated from source file: eas_mixer.c */
-/* Auto-generated from source file: eas_wavefile.c */
-/* Auto-generated from source file: eas_wtsynth.c */
-/* Auto-generated from source file: eas_smf.c */
-/* Auto-generated from source file: eas_wave.c */
-/* Auto-generated from source file: eas_hostmm.c */
-{ 0x1a54b6e8, 0x00000001, "eas_hostmm.c[586]: Vibrate state: %d\n" },
-{ 0x1a54b6e8, 0x00000002, "eas_hostmm.c[601]: LED state: %d\n" },
-{ 0x1a54b6e8, 0x00000003, "eas_hostmm.c[616]: Backlight state: %d\n" },
-/* Auto-generated from source file: eas_config.c */
-/* Auto-generated from source file: eas_main.c */
-{ 0xe624f4d9, 0x00000005, "eas_main.c[106]: Play length: %d.%03d (secs)\n" },
+/* Auto-generated from source file: eas_chorusdata.c */
+/* Auto-generated from source file: eas_imelodydata.c */
+/* Auto-generated from source file: eas_mididata.c */
+/* Auto-generated from source file: eas_pan.c */
+/* Auto-generated from source file: eas_wavefiledata.c */
+/* Auto-generated from source file: eas_voicemgt.c */
+/* Auto-generated from source file: eas_ota.c */
+/* Auto-generated from source file: eas_mixbuf.c */
+/* Auto-generated from source file: eas_rtttl.c */
+/* Auto-generated from source file: eas_reverb.c */
+/* Auto-generated from source file: eas_fmsynth.c */
+/* Auto-generated from source file: eas_pcmdata.c */
+/* Auto-generated from source file: eas_chorus.c */
+/* Auto-generated from source file: eas_math.c */
+/* Auto-generated from source file: eas_fmengine.c */
+/* Auto-generated from source file: eas_smfdata.c */
+/* Auto-generated from source file: eas_fmtables.c */
+/* Auto-generated from source file: eas_imelody.c */
+/* Auto-generated from source file: eas_public.c */
+/* Auto-generated from source file: eas_rtttldata.c */
+/* Auto-generated from source file: eas_reverbdata.c */
+/* Auto-generated from source file: eas_wtengine.c */
+/* Auto-generated from source file: eas_imaadpcm.c */
+{ 0x2380b977, 0x00000006, "eas_imaadpcm.c[305]: IMADecoderLocate: Time=%d, samples=%d\n" },
+{ 0x2380b977, 0x00000007, "eas_imaadpcm.c[328]: IMADecoderLocate: Looped sample, numBlocks=%d, samplesPerLoop=%d, samplesInLastBlock=%d, samples=%d\n" },
+{ 0x2380b977, 0x00000008, "eas_imaadpcm.c[335]: IMADecoderLocate: Byte location in audio = %d\n" },
+{ 0x2380b977, 0x00000009, "eas_imaadpcm.c[345]: IMADecoderLocate: bytesLeft = %d\n" },
+/* Auto-generated from source file: eas_midi.c */
+/* Auto-generated from source file: eas_otadata.c */
+/* Auto-generated from source file: eas_ima_tables.c */
+/* Auto-generated from source file: eas_data.c */
+/* Auto-generated from source file: eas_pcm.c */
+/* Auto-generated from source file: eas_mixer.c */
+/* Auto-generated from source file: eas_wavefile.c */
+/* Auto-generated from source file: eas_wtsynth.c */
+/* Auto-generated from source file: eas_smf.c */
+/* Auto-generated from source file: eas_wave.c */
+/* Auto-generated from source file: eas_hostmm.c */
+{ 0x1a54b6e8, 0x00000001, "eas_hostmm.c[586]: Vibrate state: %d\n" },
+{ 0x1a54b6e8, 0x00000002, "eas_hostmm.c[601]: LED state: %d\n" },
+{ 0x1a54b6e8, 0x00000003, "eas_hostmm.c[616]: Backlight state: %d\n" },
+/* Auto-generated from source file: eas_config.c */
+/* Auto-generated from source file: eas_main.c */
+{ 0xe624f4d9, 0x00000005, "eas_main.c[106]: Play length: %d.%03d (secs)\n" },
diff --git a/arm-hybrid-22k/host_src/eas_host.h b/arm-hybrid-22k/host_src/eas_host.h
index 0db0e30..b356982 100644
--- a/arm-hybrid-22k/host_src/eas_host.h
+++ b/arm-hybrid-22k/host_src/eas_host.h
@@ -1,16 +1,16 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_host.h
- *
- * Contents and purpose:
- * This header defines the host wrapper functions for stdio, stdlib, etc.
- * The host application must provide an abstraction layer for these functions
- * to support certain features, such as SMAF and SMF-1 conversion.
- *
- * DO NOT MODIFY THIS FILE!
- *
- * Copyright 2005 Sonic Network Inc.
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_host.h
+ *
+ * Contents and purpose:
+ * This header defines the host wrapper functions for stdio, stdlib, etc.
+ * The host application must provide an abstraction layer for these functions
+ * to support certain features, such as SMAF and SMF-1 conversion.
+ *
+ * DO NOT MODIFY THIS FILE!
+ *
+ * Copyright 2005 Sonic Network Inc.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -23,61 +23,61 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 82 $
- * $Date: 2006-07-10 11:45:19 -0700 (Mon, 10 Jul 2006) $
- *----------------------------------------------------------------------------
-*/
-
-// sentinel
-#ifndef _EAS_HOST_H
-#define _EAS_HOST_H
-
-#include "eas_types.h"
-
-/* for C++ linkage */
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* initialization and shutdown routines */
-extern EAS_RESULT EAS_HWInit(EAS_HW_DATA_HANDLE *hwInstData);
-extern EAS_RESULT EAS_HWShutdown(EAS_HW_DATA_HANDLE hwInstData);
-
-/* memory functions */
-extern void *EAS_HWMemSet(void *s, int c, EAS_I32 n);
-extern void *EAS_HWMemCpy(void *s1, const void *s2, EAS_I32 n);
-extern EAS_I32 EAS_HWMemCmp(const void *s1, const void *s2, EAS_I32 n);
-
-/* memory allocation */
-extern void *EAS_HWMalloc(EAS_HW_DATA_HANDLE hwInstData, EAS_I32 size);
-extern void EAS_HWFree(EAS_HW_DATA_HANDLE hwInstData, void *p);
-
-/* file I/O */
-extern EAS_RESULT EAS_HWOpenFile(EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_LOCATOR locator, EAS_FILE_HANDLE *pFile, EAS_FILE_MODE mode);
-extern EAS_RESULT EAS_HWReadFile(EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, void *pBuffer, EAS_I32 n, EAS_I32 *pBytesRead);
-extern EAS_RESULT EAS_HWGetByte(EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, void *p);
-extern EAS_RESULT EAS_HWGetWord (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, void *p, EAS_BOOL msbFirst);
-extern EAS_RESULT EAS_HWGetDWord (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, void *p, EAS_BOOL msbFirst);
-extern EAS_RESULT EAS_HWFilePos (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, EAS_I32 *pPosition);
-extern EAS_RESULT EAS_HWFileSeek (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, EAS_I32 position);
-extern EAS_RESULT EAS_HWFileSeekOfs (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, EAS_I32 position);
-extern EAS_RESULT EAS_HWFileLength (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, EAS_I32 *pLength);
-extern EAS_RESULT EAS_HWDupHandle (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, EAS_FILE_HANDLE* pFile);
-extern EAS_RESULT EAS_HWCloseFile (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file);
-
-/* vibrate, LED, and backlight functions */
-extern EAS_RESULT EAS_HWVibrate(EAS_HW_DATA_HANDLE hwInstData, EAS_BOOL state);
-extern EAS_RESULT EAS_HWLED(EAS_HW_DATA_HANDLE hwInstData, EAS_BOOL state);
-extern EAS_RESULT EAS_HWBackLight(EAS_HW_DATA_HANDLE hwInstData, EAS_BOOL state);
-
-#ifdef __cplusplus
-} /* end extern "C" */
-#endif
-
-
-/* host yield function */
-extern EAS_BOOL EAS_HWYield(EAS_HW_DATA_HANDLE hwInstData);
-#endif /* end _EAS_HOST_H */
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 82 $
+ * $Date: 2006-07-10 11:45:19 -0700 (Mon, 10 Jul 2006) $
+ *----------------------------------------------------------------------------
+*/
+
+// sentinel
+#ifndef _EAS_HOST_H
+#define _EAS_HOST_H
+
+#include "eas_types.h"
+
+/* for C++ linkage */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* initialization and shutdown routines */
+extern EAS_RESULT EAS_HWInit(EAS_HW_DATA_HANDLE *hwInstData);
+extern EAS_RESULT EAS_HWShutdown(EAS_HW_DATA_HANDLE hwInstData);
+
+/* memory functions */
+extern void *EAS_HWMemSet(void *s, int c, EAS_I32 n);
+extern void *EAS_HWMemCpy(void *s1, const void *s2, EAS_I32 n);
+extern EAS_I32 EAS_HWMemCmp(const void *s1, const void *s2, EAS_I32 n);
+
+/* memory allocation */
+extern void *EAS_HWMalloc(EAS_HW_DATA_HANDLE hwInstData, EAS_I32 size);
+extern void EAS_HWFree(EAS_HW_DATA_HANDLE hwInstData, void *p);
+
+/* file I/O */
+extern EAS_RESULT EAS_HWOpenFile(EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_LOCATOR locator, EAS_FILE_HANDLE *pFile, EAS_FILE_MODE mode);
+extern EAS_RESULT EAS_HWReadFile(EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, void *pBuffer, EAS_I32 n, EAS_I32 *pBytesRead);
+extern EAS_RESULT EAS_HWGetByte(EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, void *p);
+extern EAS_RESULT EAS_HWGetWord (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, void *p, EAS_BOOL msbFirst);
+extern EAS_RESULT EAS_HWGetDWord (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, void *p, EAS_BOOL msbFirst);
+extern EAS_RESULT EAS_HWFilePos (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, EAS_I32 *pPosition);
+extern EAS_RESULT EAS_HWFileSeek (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, EAS_I32 position);
+extern EAS_RESULT EAS_HWFileSeekOfs (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, EAS_I32 position);
+extern EAS_RESULT EAS_HWFileLength (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, EAS_I32 *pLength);
+extern EAS_RESULT EAS_HWDupHandle (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, EAS_FILE_HANDLE* pFile);
+extern EAS_RESULT EAS_HWCloseFile (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file);
+
+/* vibrate, LED, and backlight functions */
+extern EAS_RESULT EAS_HWVibrate(EAS_HW_DATA_HANDLE hwInstData, EAS_BOOL state);
+extern EAS_RESULT EAS_HWLED(EAS_HW_DATA_HANDLE hwInstData, EAS_BOOL state);
+extern EAS_RESULT EAS_HWBackLight(EAS_HW_DATA_HANDLE hwInstData, EAS_BOOL state);
+
+#ifdef __cplusplus
+} /* end extern "C" */
+#endif
+
+
+/* host yield function */
+extern EAS_BOOL EAS_HWYield(EAS_HW_DATA_HANDLE hwInstData);
+#endif /* end _EAS_HOST_H */
diff --git a/arm-hybrid-22k/host_src/eas_hostmm.c b/arm-hybrid-22k/host_src/eas_hostmm.c
index 7e58838..df24cf2 100644
--- a/arm-hybrid-22k/host_src/eas_hostmm.c
+++ b/arm-hybrid-22k/host_src/eas_hostmm.c
@@ -1,33 +1,33 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_hostmm.c
- *
- * Contents and purpose:
- * This file contains the host wrapper functions for stdio, stdlib, etc.
- * This is a sample version that maps the requested files to an
- * allocated memory block and uses in-memory pointers to replace
- * file system calls. The file locator (EAS_FILE_LOCATOR) handle passed
- * HWOpenFile is the same one that is passed to EAS_OpenFile. If your
- * system stores data in fixed locations (such as flash) instead of
- * using a file system, you can use the locator handle to point to
- * your memory. You will need a way of knowing the length of the
- * data stored at that location in order to respond correctly in the
- * HW_FileLength function.
- *
- * Modify this file to suit the needs of your particular system.
- *
- * EAS_MAX_FILE_HANDLES sets the maximum number of MIDI streams within
- * a MIDI type 1 file that can be played.
- *
- * EAS_HW_FILE is a structure to support the file I/O functions. It
- * comprises the base memory pointer, the file read pointer, and
- * the dup flag, which when sets, indicates that the file handle has
- * been duplicated. If your system uses in-memory resources, you
- * can eliminate the duplicate handle logic, and simply copy the
- * base memory pointer and file read pointer to the duplicate handle.
- *
- * Copyright 2005 Sonic Network Inc.
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_hostmm.c
+ *
+ * Contents and purpose:
+ * This file contains the host wrapper functions for stdio, stdlib, etc.
+ * This is a sample version that maps the requested files to an
+ * allocated memory block and uses in-memory pointers to replace
+ * file system calls. The file locator (EAS_FILE_LOCATOR) handle passed
+ * HWOpenFile is the same one that is passed to EAS_OpenFile. If your
+ * system stores data in fixed locations (such as flash) instead of
+ * using a file system, you can use the locator handle to point to
+ * your memory. You will need a way of knowing the length of the
+ * data stored at that location in order to respond correctly in the
+ * HW_FileLength function.
+ *
+ * Modify this file to suit the needs of your particular system.
+ *
+ * EAS_MAX_FILE_HANDLES sets the maximum number of MIDI streams within
+ * a MIDI type 1 file that can be played.
+ *
+ * EAS_HW_FILE is a structure to support the file I/O functions. It
+ * comprises the base memory pointer, the file read pointer, and
+ * the dup flag, which when sets, indicates that the file handle has
+ * been duplicated. If your system uses in-memory resources, you
+ * can eliminate the duplicate handle logic, and simply copy the
+ * base memory pointer and file read pointer to the duplicate handle.
+ *
+ * Copyright 2005 Sonic Network Inc.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -40,621 +40,621 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 795 $
- * $Date: 2007-08-01 00:14:45 -0700 (Wed, 01 Aug 2007) $
- *----------------------------------------------------------------------------
-*/
-
-#ifdef _lint
-#include "lint_stdlib.h"
-#else
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#endif
-
-#include "eas_host.h"
-
-/* Only for debugging LED, vibrate, and backlight functions */
-#include "eas_report.h"
-
-/* this module requires dynamic memory support */
-#ifdef _STATIC_MEMORY
-#error "eas_hostmm.c requires the dynamic memory model!\n"
-#endif
-
-#ifndef EAS_MAX_FILE_HANDLES
-#define EAS_MAX_FILE_HANDLES 32
-#endif
-
-/*
- * this structure and the related function are here
- * to support the ability to create duplicate handles
- * and buffering it in memory. If your system uses
- * in-memory resources, you can eliminate the calls
- * to malloc and free, the dup flag, and simply track
- * the file size and read position.
- */
-typedef struct eas_hw_file_tag
-{
- EAS_I32 fileSize;
- EAS_I32 filePos;
- EAS_BOOL dup;
- EAS_U8 *buffer;
-} EAS_HW_FILE;
-
-typedef struct eas_hw_inst_data_tag
-{
- EAS_HW_FILE files[EAS_MAX_FILE_HANDLES];
-} EAS_HW_INST_DATA;
-
-/*----------------------------------------------------------------------------
- * EAS_HWInit
- *
- * Initialize host wrapper interface
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT EAS_HWInit (EAS_HW_DATA_HANDLE *pHWInstData)
-{
-
- /* need to track file opens for duplicate handles */
- *pHWInstData = malloc(sizeof(EAS_HW_INST_DATA));
- if (!(*pHWInstData))
- return EAS_ERROR_MALLOC_FAILED;
-
- EAS_HWMemSet(*pHWInstData, 0, sizeof(EAS_HW_INST_DATA));
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * EAS_HWShutdown
- *
- * Shut down host wrapper interface
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT EAS_HWShutdown (EAS_HW_DATA_HANDLE hwInstData)
-{
-
- free(hwInstData);
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- *
- * EAS_HWMalloc
- *
- * Allocates dynamic memory
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, hwInstData) hwInstData available for customer use */
-void *EAS_HWMalloc (EAS_HW_DATA_HANDLE hwInstData, EAS_I32 size)
-{
- return malloc((size_t) size);
-}
-
-/*----------------------------------------------------------------------------
- *
- * EAS_HWFree
- *
- * Frees dynamic memory
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, hwInstData) hwInstData available for customer use */
-void EAS_HWFree (EAS_HW_DATA_HANDLE hwInstData, void *p)
-{
- free(p);
-}
-
-/*----------------------------------------------------------------------------
- *
- * EAS_HWMemCpy
- *
- * Copy memory wrapper
- *
- *----------------------------------------------------------------------------
-*/
-void *EAS_HWMemCpy (void *dest, const void *src, EAS_I32 amount)
-{
- return memcpy(dest, src, (size_t) amount);
-}
-
-/*----------------------------------------------------------------------------
- *
- * EAS_HWMemSet
- *
- * Set memory wrapper
- *
- *----------------------------------------------------------------------------
-*/
-void *EAS_HWMemSet (void *dest, int val, EAS_I32 amount)
-{
- return memset(dest, val, (size_t) amount);
-}
-
-/*----------------------------------------------------------------------------
- *
- * EAS_HWMemCmp
- *
- * Compare memory wrapper
- *
- *----------------------------------------------------------------------------
-*/
-EAS_I32 EAS_HWMemCmp (const void *s1, const void *s2, EAS_I32 amount)
-{
- return (EAS_I32) memcmp(s1, s2, (size_t) amount);
-}
-
-/*----------------------------------------------------------------------------
- *
- * EAS_HWOpenFile
- *
- * Open a file for read or write
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT EAS_HWOpenFile (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_LOCATOR locator, EAS_FILE_HANDLE *pFile, EAS_FILE_MODE mode)
-{
- EAS_HW_FILE *file;
- FILE *ioFile;
- int i, temp;
-
- /* set return value to NULL */
- *pFile = NULL;
-
- /* only support read mode at this time */
- if (mode != EAS_FILE_READ)
- return EAS_ERROR_INVALID_FILE_MODE;
-
- /* find an empty entry in the file table */
- file = hwInstData->files;
- for (i = 0; i < EAS_MAX_FILE_HANDLES; i++)
- {
- /* is this slot being used? */
- if (file->buffer == NULL)
- {
- /* open the file */
- if ((ioFile = fopen(locator,"rb")) == NULL)
- return EAS_ERROR_FILE_OPEN_FAILED;
-
- /* determine the file size */
- if (fseek(ioFile, 0L, SEEK_END) != 0)
- return EAS_ERROR_FILE_LENGTH;
- if ((file->fileSize = ftell(ioFile)) == -1L)
- return EAS_ERROR_FILE_LENGTH;
- if (fseek(ioFile, 0L, SEEK_SET) != 0)
- return EAS_ERROR_FILE_LENGTH;
-
- /* allocate a buffer */
- file->buffer = EAS_HWMalloc(hwInstData, file->fileSize);
- if (file->buffer == NULL)
- {
- fclose(ioFile);
- return EAS_ERROR_MALLOC_FAILED;
- }
-
- /* read the file into memory */
- temp = (int) fread(file->buffer, (size_t) file->fileSize, 1, ioFile);
-
- /* close the file - don't need it any more */
- fclose(ioFile);
-
- /* check for error reading file */
- if (temp != 1)
- return EAS_ERROR_FILE_READ_FAILED;
-
- /* initialize some values */
- file->filePos = 0;
- file->dup = EAS_FALSE;
-
- *pFile = file;
- return EAS_SUCCESS;
- }
- file++;
- }
-
- /* too many open files */
- return EAS_ERROR_MAX_FILES_OPEN;
-}
-
-/*----------------------------------------------------------------------------
- *
- * EAS_HWReadFile
- *
- * Read data from a file
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, hwInstData) hwInstData available for customer use */
-EAS_RESULT EAS_HWReadFile (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, void *pBuffer, EAS_I32 n, EAS_I32 *pBytesRead)
-{
- EAS_I32 count;
-
- /* make sure we have a valid handle */
- if (file->buffer == NULL)
- return EAS_ERROR_INVALID_HANDLE;
-
- /* calculate the bytes to read */
- count = file->fileSize - file->filePos;
- if (n < count)
- count = n;
-
- /* copy the data to the requested location, and advance the pointer */
- if (count)
- EAS_HWMemCpy(pBuffer, &file->buffer[file->filePos], count);
- file->filePos += count;
- *pBytesRead = count;
-
- /* were n bytes read? */
- if (count!= n)
- return EAS_EOF;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- *
- * EAS_HWGetByte
- *
- * Read a byte from a file
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, hwInstData) hwInstData available for customer use */
-EAS_RESULT EAS_HWGetByte (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, void *p)
-{
-
- /* make sure we have a valid handle */
- if (file->buffer == NULL)
- return EAS_ERROR_INVALID_HANDLE;
-
- /* check for end of file */
- if (file->filePos >= file->fileSize)
- {
- *((EAS_U8*) p) = 0;
- return EAS_EOF;
- }
-
- /* get a character from the buffer */
- *((EAS_U8*) p) = file->buffer[file->filePos++];
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- *
- * EAS_HWGetWord
- *
- * Returns the current location in the file
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, hwInstData) hwInstData available for customer use */
-EAS_RESULT EAS_HWGetWord (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, void *p, EAS_BOOL msbFirst)
-{
- EAS_RESULT result;
- EAS_U8 c1, c2;
-
- /* read 2 bytes from the file */
- if ((result = EAS_HWGetByte(hwInstData, file, &c1)) != EAS_SUCCESS)
- return result;
- if ((result = EAS_HWGetByte(hwInstData, file, &c2)) != EAS_SUCCESS)
- return result;
-
- /* order them as requested */
- if (msbFirst)
- *((EAS_U16*) p) = ((EAS_U16) c1 << 8) | c2;
- else
- *((EAS_U16*) p) = ((EAS_U16) c2 << 8) | c1;
-
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- *
- * EAS_HWGetDWord
- *
- * Returns the current location in the file
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, hwInstData) hwInstData available for customer use */
-EAS_RESULT EAS_HWGetDWord (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, void *p, EAS_BOOL msbFirst)
-{
- EAS_RESULT result;
- EAS_U8 c1, c2,c3,c4;
-
- /* read 4 bytes from the file */
- if ((result = EAS_HWGetByte(hwInstData, file, &c1)) != EAS_SUCCESS)
- return result;
- if ((result = EAS_HWGetByte(hwInstData, file, &c2)) != EAS_SUCCESS)
- return result;
- if ((result = EAS_HWGetByte(hwInstData, file, &c3)) != EAS_SUCCESS)
- return result;
- if ((result = EAS_HWGetByte(hwInstData, file, &c4)) != EAS_SUCCESS)
- return result;
-
- /* order them as requested */
- if (msbFirst)
- *((EAS_U32*) p) = ((EAS_U32) c1 << 24) | ((EAS_U32) c2 << 16) | ((EAS_U32) c3 << 8) | c4;
- else
- *((EAS_U32*) p)= ((EAS_U32) c4 << 24) | ((EAS_U32) c3 << 16) | ((EAS_U32) c2 << 8) | c1;
-
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- *
- * EAS_HWFilePos
- *
- * Returns the current location in the file
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, hwInstData) hwInstData available for customer use */
-EAS_RESULT EAS_HWFilePos (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, EAS_I32 *pPosition)
-{
-
- /* make sure we have a valid handle */
- if (file->buffer == NULL)
- return EAS_ERROR_INVALID_HANDLE;
-
- *pPosition = file->filePos;
- return EAS_SUCCESS;
-} /* end EAS_HWFilePos */
-
-/*----------------------------------------------------------------------------
- *
- * EAS_HWFileSeek
- *
- * Seek to a specific location in the file
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, hwInstData) hwInstData available for customer use */
-EAS_RESULT EAS_HWFileSeek (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, EAS_I32 position)
-{
-
- /* make sure we have a valid handle */
- if (file->buffer == NULL)
- return EAS_ERROR_INVALID_HANDLE;
-
- /* validate new position */
- if ((position < 0) || (position > file->fileSize))
- return EAS_ERROR_FILE_SEEK;
-
- /* save new position */
- file->filePos = position;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- *
- * EAS_HWFileSeekOfs
- *
- * Seek forward or back relative to the current position
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, hwInstData) hwInstData available for customer use */
-EAS_RESULT EAS_HWFileSeekOfs (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, EAS_I32 position)
-{
-
- /* make sure we have a valid handle */
- if (file->buffer == NULL)
- return EAS_ERROR_INVALID_HANDLE;
-
- /* determine the file position */
- position += file->filePos;
- if ((position < 0) || (position > file->fileSize))
- return EAS_ERROR_FILE_SEEK;
-
- /* save new position */
- file->filePos = position;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- *
- * EAS_HWFileLength
- *
- * Return the file length
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, hwInstData) hwInstData available for customer use */
-EAS_RESULT EAS_HWFileLength (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, EAS_I32 *pLength)
-{
-
- /* make sure we have a valid handle */
- if (file->buffer == NULL)
- return EAS_ERROR_INVALID_HANDLE;
-
- *pLength = file->fileSize;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- *
- * EAS_HWDupHandle
- *
- * Duplicate a file handle
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT EAS_HWDupHandle (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, EAS_FILE_HANDLE *pDupFile)
-{
- EAS_HW_FILE *dupFile;
- int i;
-
- /* make sure we have a valid handle */
- if (file->buffer == NULL)
- return EAS_ERROR_INVALID_HANDLE;
-
- /* find an empty entry in the file table */
- dupFile = hwInstData->files;
- for (i = 0; i < EAS_MAX_FILE_HANDLES; i++)
- {
- /* is this slot being used? */
- if (dupFile->buffer == NULL)
- {
-
- /* copy info from the handle to be duplicated */
- dupFile->filePos = file->filePos;
- dupFile->fileSize = file->fileSize;
- dupFile->buffer = file->buffer;
-
- /* set the duplicate handle flag */
- dupFile->dup = file->dup = EAS_TRUE;
-
- *pDupFile = dupFile;
- return EAS_SUCCESS;
- }
- dupFile++;
- }
-
- /* too many open files */
- return EAS_ERROR_MAX_FILES_OPEN;
-}
-
-/*----------------------------------------------------------------------------
- *
- * EAS_HWClose
- *
- * Wrapper for fclose function
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT EAS_HWCloseFile (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file1)
-{
- EAS_HW_FILE *file2,*dupFile;
- int i;
-
-
- /* make sure we have a valid handle */
- if (file1->buffer == NULL)
- return EAS_ERROR_INVALID_HANDLE;
-
- /* check for duplicate handle */
- if (file1->dup)
- {
- dupFile = NULL;
- file2 = hwInstData->files;
- for (i = 0; i < EAS_MAX_FILE_HANDLES; i++)
- {
- /* check for duplicate */
- if ((file1 != file2) && (file2->buffer == file1->buffer))
- {
- /* is there more than one duplicate? */
- if (dupFile != NULL)
- {
- /* clear this entry and return */
- file1->buffer = NULL;
- return EAS_SUCCESS;
- }
-
- /* this is the first duplicate found */
- else
- dupFile = file2;
- }
- file2++;
- }
-
- /* there is only one duplicate, clear the dup flag */
- if (dupFile)
- dupFile->dup = EAS_FALSE;
- else
- /* if we get here, there's a serious problem */
- return EAS_ERROR_HANDLE_INTEGRITY;
-
- /* clear this entry and return */
- file1->buffer = NULL;
- return EAS_SUCCESS;
- }
-
- /* no duplicates -free the buffer */
- EAS_HWFree(hwInstData, file1->buffer);
-
- /* clear this entry and return */
- file1->buffer = NULL;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- *
- * EAS_HWVibrate
- *
- * Turn on/off vibrate function
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, hwInstData) hwInstData available for customer use */
-EAS_RESULT EAS_HWVibrate (EAS_HW_DATA_HANDLE hwInstData, EAS_BOOL state)
-{
- EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x1a54b6e8, 0x00000001 , state);
- return EAS_SUCCESS;
-} /* end EAS_HWVibrate */
-
-/*----------------------------------------------------------------------------
- *
- * EAS_HWLED
- *
- * Turn on/off LED
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, hwInstData) hwInstData available for customer use */
-EAS_RESULT EAS_HWLED (EAS_HW_DATA_HANDLE hwInstData, EAS_BOOL state)
-{
- EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x1a54b6e8, 0x00000002 , state);
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- *
- * EAS_HWBackLight
- *
- * Turn on/off backlight
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, hwInstData) hwInstData available for customer use */
-EAS_RESULT EAS_HWBackLight (EAS_HW_DATA_HANDLE hwInstData, EAS_BOOL state)
-{
- EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x1a54b6e8, 0x00000003 , state);
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- *
- * EAS_HWYield
- *
- * This function is called periodically by the EAS library to give the
- * host an opportunity to allow other tasks to run. There are two ways to
- * use this call:
- *
- * If you have a multi-tasking OS, you can call the yield function in the
- * OS to allow other tasks to run. In this case, return EAS_FALSE to tell
- * the EAS library to continue processing when control returns from this
- * function.
- *
- * If tasks run in a single thread by sequential function calls (sometimes
- * call a "commutator loop"), return EAS_TRUE to cause the EAS Library to
- * return to the caller. Be sure to check the number of bytes rendered
- * before passing the audio buffer to the codec - it may not be filled.
- * The next call to EAS_Render will continue processing until the buffer
- * has been filled.
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, hwInstData) hwInstData available for customer use */
-EAS_BOOL EAS_HWYield (EAS_HW_DATA_HANDLE hwInstData)
-{
- /* put your code here */
- return EAS_FALSE;
-}
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 795 $
+ * $Date: 2007-08-01 00:14:45 -0700 (Wed, 01 Aug 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+#ifdef _lint
+#include "lint_stdlib.h"
+#else
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#endif
+
+#include "eas_host.h"
+
+/* Only for debugging LED, vibrate, and backlight functions */
+#include "eas_report.h"
+
+/* this module requires dynamic memory support */
+#ifdef _STATIC_MEMORY
+#error "eas_hostmm.c requires the dynamic memory model!\n"
+#endif
+
+#ifndef EAS_MAX_FILE_HANDLES
+#define EAS_MAX_FILE_HANDLES 32
+#endif
+
+/*
+ * this structure and the related function are here
+ * to support the ability to create duplicate handles
+ * and buffering it in memory. If your system uses
+ * in-memory resources, you can eliminate the calls
+ * to malloc and free, the dup flag, and simply track
+ * the file size and read position.
+ */
+typedef struct eas_hw_file_tag
+{
+ EAS_I32 fileSize;
+ EAS_I32 filePos;
+ EAS_BOOL dup;
+ EAS_U8 *buffer;
+} EAS_HW_FILE;
+
+typedef struct eas_hw_inst_data_tag
+{
+ EAS_HW_FILE files[EAS_MAX_FILE_HANDLES];
+} EAS_HW_INST_DATA;
+
+/*----------------------------------------------------------------------------
+ * EAS_HWInit
+ *
+ * Initialize host wrapper interface
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_HWInit (EAS_HW_DATA_HANDLE *pHWInstData)
+{
+
+ /* need to track file opens for duplicate handles */
+ *pHWInstData = malloc(sizeof(EAS_HW_INST_DATA));
+ if (!(*pHWInstData))
+ return EAS_ERROR_MALLOC_FAILED;
+
+ EAS_HWMemSet(*pHWInstData, 0, sizeof(EAS_HW_INST_DATA));
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_HWShutdown
+ *
+ * Shut down host wrapper interface
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_HWShutdown (EAS_HW_DATA_HANDLE hwInstData)
+{
+
+ free(hwInstData);
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_HWMalloc
+ *
+ * Allocates dynamic memory
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, hwInstData) hwInstData available for customer use */
+void *EAS_HWMalloc (EAS_HW_DATA_HANDLE hwInstData, EAS_I32 size)
+{
+ return malloc((size_t) size);
+}
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_HWFree
+ *
+ * Frees dynamic memory
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, hwInstData) hwInstData available for customer use */
+void EAS_HWFree (EAS_HW_DATA_HANDLE hwInstData, void *p)
+{
+ free(p);
+}
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_HWMemCpy
+ *
+ * Copy memory wrapper
+ *
+ *----------------------------------------------------------------------------
+*/
+void *EAS_HWMemCpy (void *dest, const void *src, EAS_I32 amount)
+{
+ return memcpy(dest, src, (size_t) amount);
+}
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_HWMemSet
+ *
+ * Set memory wrapper
+ *
+ *----------------------------------------------------------------------------
+*/
+void *EAS_HWMemSet (void *dest, int val, EAS_I32 amount)
+{
+ return memset(dest, val, (size_t) amount);
+}
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_HWMemCmp
+ *
+ * Compare memory wrapper
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_I32 EAS_HWMemCmp (const void *s1, const void *s2, EAS_I32 amount)
+{
+ return (EAS_I32) memcmp(s1, s2, (size_t) amount);
+}
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_HWOpenFile
+ *
+ * Open a file for read or write
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_HWOpenFile (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_LOCATOR locator, EAS_FILE_HANDLE *pFile, EAS_FILE_MODE mode)
+{
+ EAS_HW_FILE *file;
+ FILE *ioFile;
+ int i, temp;
+
+ /* set return value to NULL */
+ *pFile = NULL;
+
+ /* only support read mode at this time */
+ if (mode != EAS_FILE_READ)
+ return EAS_ERROR_INVALID_FILE_MODE;
+
+ /* find an empty entry in the file table */
+ file = hwInstData->files;
+ for (i = 0; i < EAS_MAX_FILE_HANDLES; i++)
+ {
+ /* is this slot being used? */
+ if (file->buffer == NULL)
+ {
+ /* open the file */
+ if ((ioFile = fopen(locator,"rb")) == NULL)
+ return EAS_ERROR_FILE_OPEN_FAILED;
+
+ /* determine the file size */
+ if (fseek(ioFile, 0L, SEEK_END) != 0)
+ return EAS_ERROR_FILE_LENGTH;
+ if ((file->fileSize = ftell(ioFile)) == -1L)
+ return EAS_ERROR_FILE_LENGTH;
+ if (fseek(ioFile, 0L, SEEK_SET) != 0)
+ return EAS_ERROR_FILE_LENGTH;
+
+ /* allocate a buffer */
+ file->buffer = EAS_HWMalloc(hwInstData, file->fileSize);
+ if (file->buffer == NULL)
+ {
+ fclose(ioFile);
+ return EAS_ERROR_MALLOC_FAILED;
+ }
+
+ /* read the file into memory */
+ temp = (int) fread(file->buffer, (size_t) file->fileSize, 1, ioFile);
+
+ /* close the file - don't need it any more */
+ fclose(ioFile);
+
+ /* check for error reading file */
+ if (temp != 1)
+ return EAS_ERROR_FILE_READ_FAILED;
+
+ /* initialize some values */
+ file->filePos = 0;
+ file->dup = EAS_FALSE;
+
+ *pFile = file;
+ return EAS_SUCCESS;
+ }
+ file++;
+ }
+
+ /* too many open files */
+ return EAS_ERROR_MAX_FILES_OPEN;
+}
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_HWReadFile
+ *
+ * Read data from a file
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, hwInstData) hwInstData available for customer use */
+EAS_RESULT EAS_HWReadFile (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, void *pBuffer, EAS_I32 n, EAS_I32 *pBytesRead)
+{
+ EAS_I32 count;
+
+ /* make sure we have a valid handle */
+ if (file->buffer == NULL)
+ return EAS_ERROR_INVALID_HANDLE;
+
+ /* calculate the bytes to read */
+ count = file->fileSize - file->filePos;
+ if (n < count)
+ count = n;
+
+ /* copy the data to the requested location, and advance the pointer */
+ if (count)
+ EAS_HWMemCpy(pBuffer, &file->buffer[file->filePos], count);
+ file->filePos += count;
+ *pBytesRead = count;
+
+ /* were n bytes read? */
+ if (count!= n)
+ return EAS_EOF;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_HWGetByte
+ *
+ * Read a byte from a file
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, hwInstData) hwInstData available for customer use */
+EAS_RESULT EAS_HWGetByte (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, void *p)
+{
+
+ /* make sure we have a valid handle */
+ if (file->buffer == NULL)
+ return EAS_ERROR_INVALID_HANDLE;
+
+ /* check for end of file */
+ if (file->filePos >= file->fileSize)
+ {
+ *((EAS_U8*) p) = 0;
+ return EAS_EOF;
+ }
+
+ /* get a character from the buffer */
+ *((EAS_U8*) p) = file->buffer[file->filePos++];
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_HWGetWord
+ *
+ * Returns the current location in the file
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, hwInstData) hwInstData available for customer use */
+EAS_RESULT EAS_HWGetWord (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, void *p, EAS_BOOL msbFirst)
+{
+ EAS_RESULT result;
+ EAS_U8 c1, c2;
+
+ /* read 2 bytes from the file */
+ if ((result = EAS_HWGetByte(hwInstData, file, &c1)) != EAS_SUCCESS)
+ return result;
+ if ((result = EAS_HWGetByte(hwInstData, file, &c2)) != EAS_SUCCESS)
+ return result;
+
+ /* order them as requested */
+ if (msbFirst)
+ *((EAS_U16*) p) = ((EAS_U16) c1 << 8) | c2;
+ else
+ *((EAS_U16*) p) = ((EAS_U16) c2 << 8) | c1;
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_HWGetDWord
+ *
+ * Returns the current location in the file
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, hwInstData) hwInstData available for customer use */
+EAS_RESULT EAS_HWGetDWord (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, void *p, EAS_BOOL msbFirst)
+{
+ EAS_RESULT result;
+ EAS_U8 c1, c2,c3,c4;
+
+ /* read 4 bytes from the file */
+ if ((result = EAS_HWGetByte(hwInstData, file, &c1)) != EAS_SUCCESS)
+ return result;
+ if ((result = EAS_HWGetByte(hwInstData, file, &c2)) != EAS_SUCCESS)
+ return result;
+ if ((result = EAS_HWGetByte(hwInstData, file, &c3)) != EAS_SUCCESS)
+ return result;
+ if ((result = EAS_HWGetByte(hwInstData, file, &c4)) != EAS_SUCCESS)
+ return result;
+
+ /* order them as requested */
+ if (msbFirst)
+ *((EAS_U32*) p) = ((EAS_U32) c1 << 24) | ((EAS_U32) c2 << 16) | ((EAS_U32) c3 << 8) | c4;
+ else
+ *((EAS_U32*) p)= ((EAS_U32) c4 << 24) | ((EAS_U32) c3 << 16) | ((EAS_U32) c2 << 8) | c1;
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_HWFilePos
+ *
+ * Returns the current location in the file
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, hwInstData) hwInstData available for customer use */
+EAS_RESULT EAS_HWFilePos (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, EAS_I32 *pPosition)
+{
+
+ /* make sure we have a valid handle */
+ if (file->buffer == NULL)
+ return EAS_ERROR_INVALID_HANDLE;
+
+ *pPosition = file->filePos;
+ return EAS_SUCCESS;
+} /* end EAS_HWFilePos */
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_HWFileSeek
+ *
+ * Seek to a specific location in the file
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, hwInstData) hwInstData available for customer use */
+EAS_RESULT EAS_HWFileSeek (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, EAS_I32 position)
+{
+
+ /* make sure we have a valid handle */
+ if (file->buffer == NULL)
+ return EAS_ERROR_INVALID_HANDLE;
+
+ /* validate new position */
+ if ((position < 0) || (position > file->fileSize))
+ return EAS_ERROR_FILE_SEEK;
+
+ /* save new position */
+ file->filePos = position;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_HWFileSeekOfs
+ *
+ * Seek forward or back relative to the current position
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, hwInstData) hwInstData available for customer use */
+EAS_RESULT EAS_HWFileSeekOfs (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, EAS_I32 position)
+{
+
+ /* make sure we have a valid handle */
+ if (file->buffer == NULL)
+ return EAS_ERROR_INVALID_HANDLE;
+
+ /* determine the file position */
+ position += file->filePos;
+ if ((position < 0) || (position > file->fileSize))
+ return EAS_ERROR_FILE_SEEK;
+
+ /* save new position */
+ file->filePos = position;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_HWFileLength
+ *
+ * Return the file length
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, hwInstData) hwInstData available for customer use */
+EAS_RESULT EAS_HWFileLength (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, EAS_I32 *pLength)
+{
+
+ /* make sure we have a valid handle */
+ if (file->buffer == NULL)
+ return EAS_ERROR_INVALID_HANDLE;
+
+ *pLength = file->fileSize;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_HWDupHandle
+ *
+ * Duplicate a file handle
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_HWDupHandle (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, EAS_FILE_HANDLE *pDupFile)
+{
+ EAS_HW_FILE *dupFile;
+ int i;
+
+ /* make sure we have a valid handle */
+ if (file->buffer == NULL)
+ return EAS_ERROR_INVALID_HANDLE;
+
+ /* find an empty entry in the file table */
+ dupFile = hwInstData->files;
+ for (i = 0; i < EAS_MAX_FILE_HANDLES; i++)
+ {
+ /* is this slot being used? */
+ if (dupFile->buffer == NULL)
+ {
+
+ /* copy info from the handle to be duplicated */
+ dupFile->filePos = file->filePos;
+ dupFile->fileSize = file->fileSize;
+ dupFile->buffer = file->buffer;
+
+ /* set the duplicate handle flag */
+ dupFile->dup = file->dup = EAS_TRUE;
+
+ *pDupFile = dupFile;
+ return EAS_SUCCESS;
+ }
+ dupFile++;
+ }
+
+ /* too many open files */
+ return EAS_ERROR_MAX_FILES_OPEN;
+}
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_HWClose
+ *
+ * Wrapper for fclose function
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_HWCloseFile (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file1)
+{
+ EAS_HW_FILE *file2,*dupFile;
+ int i;
+
+
+ /* make sure we have a valid handle */
+ if (file1->buffer == NULL)
+ return EAS_ERROR_INVALID_HANDLE;
+
+ /* check for duplicate handle */
+ if (file1->dup)
+ {
+ dupFile = NULL;
+ file2 = hwInstData->files;
+ for (i = 0; i < EAS_MAX_FILE_HANDLES; i++)
+ {
+ /* check for duplicate */
+ if ((file1 != file2) && (file2->buffer == file1->buffer))
+ {
+ /* is there more than one duplicate? */
+ if (dupFile != NULL)
+ {
+ /* clear this entry and return */
+ file1->buffer = NULL;
+ return EAS_SUCCESS;
+ }
+
+ /* this is the first duplicate found */
+ else
+ dupFile = file2;
+ }
+ file2++;
+ }
+
+ /* there is only one duplicate, clear the dup flag */
+ if (dupFile)
+ dupFile->dup = EAS_FALSE;
+ else
+ /* if we get here, there's a serious problem */
+ return EAS_ERROR_HANDLE_INTEGRITY;
+
+ /* clear this entry and return */
+ file1->buffer = NULL;
+ return EAS_SUCCESS;
+ }
+
+ /* no duplicates -free the buffer */
+ EAS_HWFree(hwInstData, file1->buffer);
+
+ /* clear this entry and return */
+ file1->buffer = NULL;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_HWVibrate
+ *
+ * Turn on/off vibrate function
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, hwInstData) hwInstData available for customer use */
+EAS_RESULT EAS_HWVibrate (EAS_HW_DATA_HANDLE hwInstData, EAS_BOOL state)
+{
+ EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x1a54b6e8, 0x00000001 , state);
+ return EAS_SUCCESS;
+} /* end EAS_HWVibrate */
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_HWLED
+ *
+ * Turn on/off LED
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, hwInstData) hwInstData available for customer use */
+EAS_RESULT EAS_HWLED (EAS_HW_DATA_HANDLE hwInstData, EAS_BOOL state)
+{
+ EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x1a54b6e8, 0x00000002 , state);
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_HWBackLight
+ *
+ * Turn on/off backlight
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, hwInstData) hwInstData available for customer use */
+EAS_RESULT EAS_HWBackLight (EAS_HW_DATA_HANDLE hwInstData, EAS_BOOL state)
+{
+ EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x1a54b6e8, 0x00000003 , state);
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_HWYield
+ *
+ * This function is called periodically by the EAS library to give the
+ * host an opportunity to allow other tasks to run. There are two ways to
+ * use this call:
+ *
+ * If you have a multi-tasking OS, you can call the yield function in the
+ * OS to allow other tasks to run. In this case, return EAS_FALSE to tell
+ * the EAS library to continue processing when control returns from this
+ * function.
+ *
+ * If tasks run in a single thread by sequential function calls (sometimes
+ * call a "commutator loop"), return EAS_TRUE to cause the EAS Library to
+ * return to the caller. Be sure to check the number of bytes rendered
+ * before passing the audio buffer to the codec - it may not be filled.
+ * The next call to EAS_Render will continue processing until the buffer
+ * has been filled.
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, hwInstData) hwInstData available for customer use */
+EAS_BOOL EAS_HWYield (EAS_HW_DATA_HANDLE hwInstData)
+{
+ /* put your code here */
+ return EAS_FALSE;
+}
+
diff --git a/arm-hybrid-22k/host_src/eas_main.c b/arm-hybrid-22k/host_src/eas_main.c
index 809a132..6ebb13e 100644
--- a/arm-hybrid-22k/host_src/eas_main.c
+++ b/arm-hybrid-22k/host_src/eas_main.c
@@ -1,13 +1,13 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_main.c
- *
- * Contents and purpose:
- * The entry point and high-level functions for the EAS Synthesizer test
- * harness.
- *
- * Copyright Sonic Network Inc. 2004
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_main.c
+ *
+ * Contents and purpose:
+ * The entry point and high-level functions for the EAS Synthesizer test
+ * harness.
+ *
+ * Copyright Sonic Network Inc. 2004
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,442 +20,442 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 775 $
- * $Date: 2007-07-20 10:11:11 -0700 (Fri, 20 Jul 2007) $
- *----------------------------------------------------------------------------
-*/
-
-#ifdef _lint
-#include "lint_stdlib.h"
-#else
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <time.h>
-#endif
-
-#include "eas.h"
-#include "eas_wave.h"
-#include "eas_report.h"
-
-/* determines how many EAS buffers to fill a host buffer */
-#define NUM_BUFFERS 8
-
-/* default file to play if no filename is specified on the command line */
-static const char defaultTestFile[] = "test.mid";
-
-EAS_I32 polyphony;
-
-/* prototypes for helper functions */
-static void StrCopy(char *dest, const char *src, EAS_I32 size);
-static EAS_BOOL ChangeFileExt(char *str, const char *ext, EAS_I32 size);
-static EAS_RESULT PlayFile (EAS_DATA_HANDLE easData, const char* filename, const char* outputFile, const S_EAS_LIB_CONFIG *pLibConfig, void *buffer, EAS_I32 bufferSize);
-static EAS_BOOL EASLibraryCheck (const S_EAS_LIB_CONFIG *pLibConfig);
-
-/* main is defined after playfile to avoid the need for two passes through lint */
-
-/*----------------------------------------------------------------------------
- * PlayFile()
- *----------------------------------------------------------------------------
- * Purpose:
- * This function plays the file requested by filename
- *
- * Inputs:
- *
- * Outputs:
- *
- *----------------------------------------------------------------------------
-*/
-
-static EAS_RESULT PlayFile (EAS_DATA_HANDLE easData, const char* filename, const char* outputFile, const S_EAS_LIB_CONFIG *pLibConfig, void *buffer, EAS_I32 bufferSize)
-{
- EAS_HANDLE handle;
- EAS_RESULT result, reportResult;
- EAS_I32 count;
- EAS_STATE state;
- EAS_I32 playTime;
- char waveFilename[256];
- WAVE_FILE *wFile;
- EAS_INT i;
- EAS_PCM *p;
-
- /* determine the name of the output file */
- wFile = NULL;
- if (outputFile == NULL)
- {
- StrCopy(waveFilename, filename, sizeof(waveFilename));
- if (!ChangeFileExt(waveFilename, "wav", sizeof(waveFilename)))
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Error in output filename %s\n", waveFilename); */ }
- return EAS_FAILURE;
- }
- outputFile = waveFilename;
- }
-
- /* call EAS library to open file */
- if ((reportResult = EAS_OpenFile(easData, filename, &handle)) != EAS_SUCCESS)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "EAS_OpenFile returned %ld\n", reportResult); */ }
- return reportResult;
- }
-
- /* prepare to play the file */
- if ((result = EAS_Prepare(easData, handle)) != EAS_SUCCESS)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "EAS_Prepare returned %ld\n", result); */ }
- reportResult = result;
- }
-
- /* get play length */
- if ((result = EAS_ParseMetaData(easData, handle, &playTime)) != EAS_SUCCESS)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "EAS_ParseMetaData returned %ld\n", result); */ }
- return result;
- }
- EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0xe624f4d9, 0x00000005 , playTime / 1000, playTime % 1000);
-
- if (reportResult == EAS_SUCCESS)
- {
- /* create the output file */
- wFile = WaveFileCreate(outputFile, pLibConfig->numChannels, pLibConfig->sampleRate, sizeof(EAS_PCM) * 8);
- if (!wFile)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Unable to create output file %s\n", waveFilename); */ }
- reportResult = EAS_FAILURE;
- }
- }
-
- /* rendering loop */
- while (reportResult == EAS_SUCCESS)
- {
-
- /* we may render several buffers here to fill one host buffer */
- for (i = 0, p = buffer; i < NUM_BUFFERS; i++, p+= pLibConfig->mixBufferSize * pLibConfig->numChannels)
- {
-
- /* get the current time */
- if ((result = EAS_GetLocation(easData, handle, &playTime)) != EAS_SUCCESS)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "EAS_GetLocation returned %d\n",result); */ }
- if (reportResult == EAS_SUCCESS)
- reportResult = result;
- break;
- }
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Parser time: %d.%03d\n", playTime / 1000, playTime % 1000); */ }
-
- /* render a buffer of audio */
- if ((result = EAS_Render(easData, p, pLibConfig->mixBufferSize, &count)) != EAS_SUCCESS)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "EAS_Render returned %d\n",result); */ }
- if (reportResult == EAS_SUCCESS)
- reportResult = result;
- }
- }
-
- if (result == EAS_SUCCESS)
- {
- /* write it to the wave file */
- if (WaveFileWrite(wFile, buffer, bufferSize) != bufferSize)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "WaveFileWrite failed\n"); */ }
- reportResult = EAS_FAILURE;
- }
- }
-
- if (reportResult == EAS_SUCCESS)
- {
- /* check stream state */
- if ((result = EAS_State(easData, handle, &state)) != EAS_SUCCESS)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "EAS_State returned %d\n", result); */ }
- reportResult = result;
- }
-
- /* is playback complete */
- if ((state == EAS_STATE_STOPPED) || (state == EAS_STATE_ERROR))
- break;
- }
- }
-
- /* close the output file */
- if (wFile)
- {
- if (!WaveFileClose(wFile))
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Error closing wave file %s\n", waveFilename); */ }
- if (reportResult == EAS_SUCCESS)
- result = EAS_FAILURE;
- }
- }
-
- /* close the input file */
- if ((result = EAS_CloseFile(easData,handle)) != EAS_SUCCESS)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "EAS_Close returned %ld\n", result); */ }
- if (reportResult == EAS_SUCCESS)
- result = EAS_FAILURE;
- }
-
- return reportResult;
-} /* end PlayFile */
-
-/*----------------------------------------------------------------------------
- * main()
- *----------------------------------------------------------------------------
- * Purpose: The entry point for the EAS sample application
- *
- * Inputs:
- *
- * Outputs:
- *
- *----------------------------------------------------------------------------
-*/
-int main( int argc, char **argv )
-{
- EAS_DATA_HANDLE easData;
- const S_EAS_LIB_CONFIG *pLibConfig;
- void *buffer;
- EAS_RESULT result, playResult;
- EAS_I32 bufferSize;
- int i;
- int temp;
- FILE *debugFile;
- char *outputFile = NULL;
-
- /* set the error reporting level */
- EAS_SetDebugLevel(_EAS_SEVERITY_INFO);
- debugFile = NULL;
-
- /* process command-line arguments */
- for (i = 1; i < argc; i++)
- {
- /* check for switch */
- if (argv[i][0] == '-')
- {
- switch (argv[i][1])
- {
- case 'd':
- temp = argv[i][2];
- if ((temp >= '0') || (temp <= '9'))
- EAS_SetDebugLevel(temp);
- else
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Invalid debug level %d\n", temp); */ }
- break;
- case 'f':
- if ((debugFile = fopen(&argv[i][2],"w")) == NULL)
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Unable to create debug file %s\n", &argv[i][2]); */ }
- else
- EAS_SetDebugFile(debugFile, EAS_TRUE);
- break;
- case 'o':
- outputFile = &argv[i][2];
- break;
- case 'p':
- polyphony = atoi(&argv[i][2]);
- if (polyphony < 1)
- polyphony = 1;
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "Polyphony set to %d\n", polyphony); */ }
- break;
- default:
- break;
- }
- continue;
- }
- }
-
- /* assume success */
- playResult = EAS_SUCCESS;
-
- /* get the library configuration */
- pLibConfig = EAS_Config();
- if (!EASLibraryCheck(pLibConfig))
- return -1;
- if (polyphony > pLibConfig->maxVoices)
- polyphony = pLibConfig->maxVoices;
-
- /* calculate buffer size */
- bufferSize = pLibConfig->mixBufferSize * pLibConfig->numChannels * (EAS_I32)sizeof(EAS_PCM) * NUM_BUFFERS;
-
- /* allocate output buffer memory */
- buffer = malloc((EAS_U32)bufferSize);
- if (!buffer)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_FATAL, "Error allocating memory for audio buffer\n"); */ }
- return EAS_FAILURE;
- }
-
- /* initialize the EAS library */
- polyphony = pLibConfig->maxVoices;
- if ((result = EAS_Init(&easData)) != EAS_SUCCESS)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_FATAL, "EAS_Init returned %ld - aborting!\n", result); */ }
- free(buffer);
- return result;
- }
-
- /*
- * Some debugging environments don't allow for passed parameters.
- * In this case, just play the default MIDI file "test.mid"
- */
- if (argc < 2)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "Playing '%s'\n", defaultTestFile); */ }
- if ((playResult = PlayFile(easData, defaultTestFile, NULL, pLibConfig, buffer, bufferSize)) != EAS_SUCCESS)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Error %d playing file %s\n", playResult, defaultTestFile); */ }
- }
- }
- /* iterate through the list of files to be played */
- else
- {
- for (i = 1; i < argc; i++)
- {
- /* check for switch */
- if (argv[i][0] != '-')
- {
-
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "Playing '%s'\n", argv[i]); */ }
- if ((playResult = PlayFile(easData, argv[i], outputFile, pLibConfig, buffer, bufferSize)) != EAS_SUCCESS)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Error %d playing file %s\n", playResult, argv[i]); */ }
- break;
- }
- }
- }
- }
-
- /* shutdown the EAS library */
- if ((result = EAS_Shutdown(easData)) != EAS_SUCCESS)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_FATAL, "EAS_Shutdown returned %ld\n", result); */ }
- }
-
- /* free the output buffer */
- free(buffer);
-
- /* close the debug file */
- if (debugFile)
- fclose(debugFile);
-
- /* play errors take precedence over shutdown errors */
- if (playResult != EAS_SUCCESS)
- return playResult;
- return result;
-} /* end main */
-
-/*----------------------------------------------------------------------------
- * StrCopy()
- *----------------------------------------------------------------------------
- * Purpose:
- * Safe string copy
- *
- * Inputs:
- *
- * Outputs:
- *
- *----------------------------------------------------------------------------
-*/
-static void StrCopy(char *dest, const char *src, EAS_I32 size)
-{
- int len;
-
- strncpy(dest, src, (size_t) size-1);
- len = (int) strlen(src);
- if (len < size)
- dest[len] = 0;
-} /* end StrCopy */
-
-/*----------------------------------------------------------------------------
- * ChangeFileExt()
- *----------------------------------------------------------------------------
- * Purpose:
- * Changes the file extension of a filename
- *
- * Inputs:
- *
- * Outputs:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_BOOL ChangeFileExt(char *str, const char *ext, EAS_I32 size)
-{
- char *p;
-
- /* find the extension, if any */
- p = strrchr(str,'.');
- if (!p)
- {
- if ((EAS_I32)(strlen(str) + 5) > size)
- return EAS_FALSE;
- strcat(str,".");
- strcat(str,ext);
- return EAS_TRUE;
- }
-
- /* make sure there's room for the extension */
- p++;
- *p = 0;
- if ((EAS_I32)(strlen(str) + 4) > size)
- return EAS_FALSE;
- strcat(str,ext);
- return EAS_TRUE;
-} /* end ChangeFileExt */
-
-/*----------------------------------------------------------------------------
- * EASLibraryCheck()
- *----------------------------------------------------------------------------
- * Purpose:
- * Displays the library version and checks it against the header
- * file used to build this code.
- *
- * Inputs:
- * pLibConfig - library configuration retrieved from the library
- *
- * Outputs:
- * returns EAS_TRUE if matched
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_BOOL EASLibraryCheck (const S_EAS_LIB_CONFIG *pLibConfig)
-{
-
- /* display the library version */
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "EAS Library Version %d.%d.%d.%d\n",
- pLibConfig->libVersion >> 24,
- (pLibConfig->libVersion >> 16) & 0x0f,
- (pLibConfig->libVersion >> 8) & 0x0f,
- pLibConfig->libVersion & 0x0f); */ }
-
- /* display some info about the library build */
- if (pLibConfig->checkedVersion)
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "\tChecked library\n"); */ }
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "\tMaximum polyphony: %d\n", pLibConfig->maxVoices); */ }
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "\tNumber of channels: %d\n", pLibConfig->numChannels); */ }
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "\tSample rate: %d\n", pLibConfig->sampleRate); */ }
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "\tMix buffer size: %d\n", pLibConfig->mixBufferSize); */ }
- if (pLibConfig->filterEnabled)
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "\tFilter enabled\n"); */ }
-#ifndef _WIN32_WCE
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "\tLibrary Build Timestamp: %s", ctime((time_t*)&pLibConfig->buildTimeStamp)); */ }
-#endif
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "\tLibrary Build ID: %s\n", pLibConfig->buildGUID); */ }
-
- /* check it against the header file used to build this code */
- /*lint -e{778} constant expression used for display purposes may evaluate to zero */
- if (LIB_VERSION != pLibConfig->libVersion)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_FATAL, "Library version does not match header files. EAS Header Version %d.%d.%d.%d\n",
- LIB_VERSION >> 24,
- (LIB_VERSION >> 16) & 0x0f,
- (LIB_VERSION >> 8) & 0x0f,
- LIB_VERSION & 0x0f); */ }
- return EAS_FALSE;
- }
- return EAS_TRUE;
-} /* end EASLibraryCheck */
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 775 $
+ * $Date: 2007-07-20 10:11:11 -0700 (Fri, 20 Jul 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+#ifdef _lint
+#include "lint_stdlib.h"
+#else
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <time.h>
+#endif
+
+#include "eas.h"
+#include "eas_wave.h"
+#include "eas_report.h"
+
+/* determines how many EAS buffers to fill a host buffer */
+#define NUM_BUFFERS 8
+
+/* default file to play if no filename is specified on the command line */
+static const char defaultTestFile[] = "test.mid";
+
+EAS_I32 polyphony;
+
+/* prototypes for helper functions */
+static void StrCopy(char *dest, const char *src, EAS_I32 size);
+static EAS_BOOL ChangeFileExt(char *str, const char *ext, EAS_I32 size);
+static EAS_RESULT PlayFile (EAS_DATA_HANDLE easData, const char* filename, const char* outputFile, const S_EAS_LIB_CONFIG *pLibConfig, void *buffer, EAS_I32 bufferSize);
+static EAS_BOOL EASLibraryCheck (const S_EAS_LIB_CONFIG *pLibConfig);
+
+/* main is defined after playfile to avoid the need for two passes through lint */
+
+/*----------------------------------------------------------------------------
+ * PlayFile()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * This function plays the file requested by filename
+ *
+ * Inputs:
+ *
+ * Outputs:
+ *
+ *----------------------------------------------------------------------------
+*/
+
+static EAS_RESULT PlayFile (EAS_DATA_HANDLE easData, const char* filename, const char* outputFile, const S_EAS_LIB_CONFIG *pLibConfig, void *buffer, EAS_I32 bufferSize)
+{
+ EAS_HANDLE handle;
+ EAS_RESULT result, reportResult;
+ EAS_I32 count;
+ EAS_STATE state;
+ EAS_I32 playTime;
+ char waveFilename[256];
+ WAVE_FILE *wFile;
+ EAS_INT i;
+ EAS_PCM *p;
+
+ /* determine the name of the output file */
+ wFile = NULL;
+ if (outputFile == NULL)
+ {
+ StrCopy(waveFilename, filename, sizeof(waveFilename));
+ if (!ChangeFileExt(waveFilename, "wav", sizeof(waveFilename)))
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Error in output filename %s\n", waveFilename); */ }
+ return EAS_FAILURE;
+ }
+ outputFile = waveFilename;
+ }
+
+ /* call EAS library to open file */
+ if ((reportResult = EAS_OpenFile(easData, filename, &handle)) != EAS_SUCCESS)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "EAS_OpenFile returned %ld\n", reportResult); */ }
+ return reportResult;
+ }
+
+ /* prepare to play the file */
+ if ((result = EAS_Prepare(easData, handle)) != EAS_SUCCESS)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "EAS_Prepare returned %ld\n", result); */ }
+ reportResult = result;
+ }
+
+ /* get play length */
+ if ((result = EAS_ParseMetaData(easData, handle, &playTime)) != EAS_SUCCESS)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "EAS_ParseMetaData returned %ld\n", result); */ }
+ return result;
+ }
+ EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0xe624f4d9, 0x00000005 , playTime / 1000, playTime % 1000);
+
+ if (reportResult == EAS_SUCCESS)
+ {
+ /* create the output file */
+ wFile = WaveFileCreate(outputFile, pLibConfig->numChannels, pLibConfig->sampleRate, sizeof(EAS_PCM) * 8);
+ if (!wFile)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Unable to create output file %s\n", waveFilename); */ }
+ reportResult = EAS_FAILURE;
+ }
+ }
+
+ /* rendering loop */
+ while (reportResult == EAS_SUCCESS)
+ {
+
+ /* we may render several buffers here to fill one host buffer */
+ for (i = 0, p = buffer; i < NUM_BUFFERS; i++, p+= pLibConfig->mixBufferSize * pLibConfig->numChannels)
+ {
+
+ /* get the current time */
+ if ((result = EAS_GetLocation(easData, handle, &playTime)) != EAS_SUCCESS)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "EAS_GetLocation returned %d\n",result); */ }
+ if (reportResult == EAS_SUCCESS)
+ reportResult = result;
+ break;
+ }
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Parser time: %d.%03d\n", playTime / 1000, playTime % 1000); */ }
+
+ /* render a buffer of audio */
+ if ((result = EAS_Render(easData, p, pLibConfig->mixBufferSize, &count)) != EAS_SUCCESS)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "EAS_Render returned %d\n",result); */ }
+ if (reportResult == EAS_SUCCESS)
+ reportResult = result;
+ }
+ }
+
+ if (result == EAS_SUCCESS)
+ {
+ /* write it to the wave file */
+ if (WaveFileWrite(wFile, buffer, bufferSize) != bufferSize)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "WaveFileWrite failed\n"); */ }
+ reportResult = EAS_FAILURE;
+ }
+ }
+
+ if (reportResult == EAS_SUCCESS)
+ {
+ /* check stream state */
+ if ((result = EAS_State(easData, handle, &state)) != EAS_SUCCESS)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "EAS_State returned %d\n", result); */ }
+ reportResult = result;
+ }
+
+ /* is playback complete */
+ if ((state == EAS_STATE_STOPPED) || (state == EAS_STATE_ERROR))
+ break;
+ }
+ }
+
+ /* close the output file */
+ if (wFile)
+ {
+ if (!WaveFileClose(wFile))
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Error closing wave file %s\n", waveFilename); */ }
+ if (reportResult == EAS_SUCCESS)
+ result = EAS_FAILURE;
+ }
+ }
+
+ /* close the input file */
+ if ((result = EAS_CloseFile(easData,handle)) != EAS_SUCCESS)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "EAS_Close returned %ld\n", result); */ }
+ if (reportResult == EAS_SUCCESS)
+ result = EAS_FAILURE;
+ }
+
+ return reportResult;
+} /* end PlayFile */
+
+/*----------------------------------------------------------------------------
+ * main()
+ *----------------------------------------------------------------------------
+ * Purpose: The entry point for the EAS sample application
+ *
+ * Inputs:
+ *
+ * Outputs:
+ *
+ *----------------------------------------------------------------------------
+*/
+int main( int argc, char **argv )
+{
+ EAS_DATA_HANDLE easData;
+ const S_EAS_LIB_CONFIG *pLibConfig;
+ void *buffer;
+ EAS_RESULT result, playResult;
+ EAS_I32 bufferSize;
+ int i;
+ int temp;
+ FILE *debugFile;
+ char *outputFile = NULL;
+
+ /* set the error reporting level */
+ EAS_SetDebugLevel(_EAS_SEVERITY_INFO);
+ debugFile = NULL;
+
+ /* process command-line arguments */
+ for (i = 1; i < argc; i++)
+ {
+ /* check for switch */
+ if (argv[i][0] == '-')
+ {
+ switch (argv[i][1])
+ {
+ case 'd':
+ temp = argv[i][2];
+ if ((temp >= '0') || (temp <= '9'))
+ EAS_SetDebugLevel(temp);
+ else
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Invalid debug level %d\n", temp); */ }
+ break;
+ case 'f':
+ if ((debugFile = fopen(&argv[i][2],"w")) == NULL)
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Unable to create debug file %s\n", &argv[i][2]); */ }
+ else
+ EAS_SetDebugFile(debugFile, EAS_TRUE);
+ break;
+ case 'o':
+ outputFile = &argv[i][2];
+ break;
+ case 'p':
+ polyphony = atoi(&argv[i][2]);
+ if (polyphony < 1)
+ polyphony = 1;
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "Polyphony set to %d\n", polyphony); */ }
+ break;
+ default:
+ break;
+ }
+ continue;
+ }
+ }
+
+ /* assume success */
+ playResult = EAS_SUCCESS;
+
+ /* get the library configuration */
+ pLibConfig = EAS_Config();
+ if (!EASLibraryCheck(pLibConfig))
+ return -1;
+ if (polyphony > pLibConfig->maxVoices)
+ polyphony = pLibConfig->maxVoices;
+
+ /* calculate buffer size */
+ bufferSize = pLibConfig->mixBufferSize * pLibConfig->numChannels * (EAS_I32)sizeof(EAS_PCM) * NUM_BUFFERS;
+
+ /* allocate output buffer memory */
+ buffer = malloc((EAS_U32)bufferSize);
+ if (!buffer)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_FATAL, "Error allocating memory for audio buffer\n"); */ }
+ return EAS_FAILURE;
+ }
+
+ /* initialize the EAS library */
+ polyphony = pLibConfig->maxVoices;
+ if ((result = EAS_Init(&easData)) != EAS_SUCCESS)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_FATAL, "EAS_Init returned %ld - aborting!\n", result); */ }
+ free(buffer);
+ return result;
+ }
+
+ /*
+ * Some debugging environments don't allow for passed parameters.
+ * In this case, just play the default MIDI file "test.mid"
+ */
+ if (argc < 2)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "Playing '%s'\n", defaultTestFile); */ }
+ if ((playResult = PlayFile(easData, defaultTestFile, NULL, pLibConfig, buffer, bufferSize)) != EAS_SUCCESS)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Error %d playing file %s\n", playResult, defaultTestFile); */ }
+ }
+ }
+ /* iterate through the list of files to be played */
+ else
+ {
+ for (i = 1; i < argc; i++)
+ {
+ /* check for switch */
+ if (argv[i][0] != '-')
+ {
+
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "Playing '%s'\n", argv[i]); */ }
+ if ((playResult = PlayFile(easData, argv[i], outputFile, pLibConfig, buffer, bufferSize)) != EAS_SUCCESS)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Error %d playing file %s\n", playResult, argv[i]); */ }
+ break;
+ }
+ }
+ }
+ }
+
+ /* shutdown the EAS library */
+ if ((result = EAS_Shutdown(easData)) != EAS_SUCCESS)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_FATAL, "EAS_Shutdown returned %ld\n", result); */ }
+ }
+
+ /* free the output buffer */
+ free(buffer);
+
+ /* close the debug file */
+ if (debugFile)
+ fclose(debugFile);
+
+ /* play errors take precedence over shutdown errors */
+ if (playResult != EAS_SUCCESS)
+ return playResult;
+ return result;
+} /* end main */
+
+/*----------------------------------------------------------------------------
+ * StrCopy()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Safe string copy
+ *
+ * Inputs:
+ *
+ * Outputs:
+ *
+ *----------------------------------------------------------------------------
+*/
+static void StrCopy(char *dest, const char *src, EAS_I32 size)
+{
+ int len;
+
+ strncpy(dest, src, (size_t) size-1);
+ len = (int) strlen(src);
+ if (len < size)
+ dest[len] = 0;
+} /* end StrCopy */
+
+/*----------------------------------------------------------------------------
+ * ChangeFileExt()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Changes the file extension of a filename
+ *
+ * Inputs:
+ *
+ * Outputs:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_BOOL ChangeFileExt(char *str, const char *ext, EAS_I32 size)
+{
+ char *p;
+
+ /* find the extension, if any */
+ p = strrchr(str,'.');
+ if (!p)
+ {
+ if ((EAS_I32)(strlen(str) + 5) > size)
+ return EAS_FALSE;
+ strcat(str,".");
+ strcat(str,ext);
+ return EAS_TRUE;
+ }
+
+ /* make sure there's room for the extension */
+ p++;
+ *p = 0;
+ if ((EAS_I32)(strlen(str) + 4) > size)
+ return EAS_FALSE;
+ strcat(str,ext);
+ return EAS_TRUE;
+} /* end ChangeFileExt */
+
+/*----------------------------------------------------------------------------
+ * EASLibraryCheck()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Displays the library version and checks it against the header
+ * file used to build this code.
+ *
+ * Inputs:
+ * pLibConfig - library configuration retrieved from the library
+ *
+ * Outputs:
+ * returns EAS_TRUE if matched
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_BOOL EASLibraryCheck (const S_EAS_LIB_CONFIG *pLibConfig)
+{
+
+ /* display the library version */
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "EAS Library Version %d.%d.%d.%d\n",
+ pLibConfig->libVersion >> 24,
+ (pLibConfig->libVersion >> 16) & 0x0f,
+ (pLibConfig->libVersion >> 8) & 0x0f,
+ pLibConfig->libVersion & 0x0f); */ }
+
+ /* display some info about the library build */
+ if (pLibConfig->checkedVersion)
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "\tChecked library\n"); */ }
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "\tMaximum polyphony: %d\n", pLibConfig->maxVoices); */ }
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "\tNumber of channels: %d\n", pLibConfig->numChannels); */ }
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "\tSample rate: %d\n", pLibConfig->sampleRate); */ }
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "\tMix buffer size: %d\n", pLibConfig->mixBufferSize); */ }
+ if (pLibConfig->filterEnabled)
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "\tFilter enabled\n"); */ }
+#ifndef _WIN32_WCE
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "\tLibrary Build Timestamp: %s", ctime((time_t*)&pLibConfig->buildTimeStamp)); */ }
+#endif
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "\tLibrary Build ID: %s\n", pLibConfig->buildGUID); */ }
+
+ /* check it against the header file used to build this code */
+ /*lint -e{778} constant expression used for display purposes may evaluate to zero */
+ if (LIB_VERSION != pLibConfig->libVersion)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_FATAL, "Library version does not match header files. EAS Header Version %d.%d.%d.%d\n",
+ LIB_VERSION >> 24,
+ (LIB_VERSION >> 16) & 0x0f,
+ (LIB_VERSION >> 8) & 0x0f,
+ LIB_VERSION & 0x0f); */ }
+ return EAS_FALSE;
+ }
+ return EAS_TRUE;
+} /* end EASLibraryCheck */
+
diff --git a/arm-hybrid-22k/host_src/eas_report.c b/arm-hybrid-22k/host_src/eas_report.c
index d4dd22c..04a828c 100644
--- a/arm-hybrid-22k/host_src/eas_report.c
+++ b/arm-hybrid-22k/host_src/eas_report.c
@@ -1,13 +1,13 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_report.c
- *
- * Contents and purpose:
- * This file contains the debug message handling routines for the EAS library.
- * These routines should be modified as needed for your system.
- *
- * Copyright 2005 Sonic Network Inc.
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_report.c
+ *
+ * Contents and purpose:
+ * This file contains the debug message handling routines for the EAS library.
+ * These routines should be modified as needed for your system.
+ *
+ * Copyright 2005 Sonic Network Inc.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,245 +20,245 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 659 $
- * $Date: 2007-04-24 13:36:35 -0700 (Tue, 24 Apr 2007) $
- *----------------------------------------------------------------------------
-*/
-
-#ifdef _lint
-#include "lint_stdlib.h"
-#else
-#include <stdlib.h>
-#include <stdio.h>
-#include <stdarg.h>
-#endif
-
-#include "eas_report.h"
-
-static int severityLevel = 9999;
-
-/* debug file */
-static FILE *debugFile = NULL;
-int flush = 0;
-
-#ifndef _NO_DEBUG_PREPROCESSOR
-
-/* structure should have an #include for each error message header file */
-S_DEBUG_MESSAGES debugMessages[] =
-{
-#ifndef UNIFIED_DEBUG_MESSAGES
-#include "eas_config_msgs.h"
-
-
-#include "eas_host_msgs.h"
-#include "eas_hostmm_msgs.h"
-#include "eas_math_msgs.h"
-#include "eas_midi_msgs.h"
-#include "eas_mixer_msgs.h"
-#include "eas_pcm_msgs.h"
-#include "eas_public_msgs.h"
-#include "eas_smf_msgs.h"
-#include "eas_wave_msgs.h"
-#include "eas_voicemgt_msgs.h"
-
-#ifdef _FM_SYNTH
-#include "eas_fmsynth_msgs.h"
-#include "eas_fmengine_msgs.h"
-#endif
-
-#ifdef _WT_SYNTH
-#include "eas_wtsynth_msgs.h"
-#include "eas_wtengine_msgs.h"
-#endif
-
-#ifdef _ARM_TEST_MAIN
-#include "arm_main_msgs.h"
-#endif
-
-#ifdef _EAS_MAIN
-#include "eas_main_msgs.h"
-#endif
-
-#ifdef _EAS_MAIN_IPC
-#include "eas_main_ipc_msgs.h"
-#endif
-
-#ifdef _METRICS_ENABLED
-#include "eas_perf_msgs.h"
-#endif
-
-#ifdef _COMPRESSOR_ENABLED
-#include "eas_compressor_msgs.h"
-#endif
-
-#ifdef _ENHANCER_ENABLED
-#include "eas_enhancer_msgs.h"
-#endif
-
-#ifdef _WOW_ENABLED
-#include "eas_wow_msgs.h"
-#endif
-
-#ifdef _SMAF_PARSER
-#include "eas_smaf_msgs.h"
-#endif
-
-#ifdef _OTA_PARSER
-#include "eas_ota_msgs.h"
-#endif
-
-#ifdef _IMELODY_PARSER
-#include "eas_imelody_msgs.h"
-#endif
-
-#ifdef _WAVE_PARSER
-#include "eas_wavefile_msgs.h"
-#endif
-
-#if defined(_CMX_PARSER) || defined(_MFI_PARSER)
-#include "eas_cmf_msgs.h"
-#endif
-
-#if defined(_CMX_PARSER) || defined(_MFI_PARSER) || defined(_WAVE_PARSER)
-#include "eas_imaadpcm_msgs.h"
-#endif
-
-#else
-#include "eas_debugmsgs.h"
-#endif
-
-/* denotes end of error messages */
-{ 0,0,0 }
-};
-
-/*----------------------------------------------------------------------------
- * EAS_ReportEx()
- *
- * This is the error message handler. The default handler outputs error
- * messages to stdout. Modify this as needed for your system.
- *----------------------------------------------------------------------------
-*/
-void EAS_ReportEx (int severity, unsigned long hashCode, int serialNum, ...)
-{
- va_list vargs;
- int i;
-
- /* check severity level */
- if (severity > severityLevel)
- return;
-
- /* find the error message and output to stdout */
- /*lint -e{661} we check for NULL pointer - no fence post error here */
- for (i = 0; debugMessages[i].m_pDebugMsg; i++)
- {
- if ((debugMessages[i].m_nHashCode == hashCode) &&
- (debugMessages[i].m_nSerialNum == serialNum))
- {
- /*lint -e{826} <allow variable args> */
- va_start(vargs, serialNum);
- if (debugFile)
- {
- vfprintf(debugFile, debugMessages[i].m_pDebugMsg, vargs);
- if (flush)
- fflush(debugFile);
- }
- else
- {
- vprintf(debugMessages[i].m_pDebugMsg, vargs);
- }
- va_end(vargs);
- return;
- }
- }
- printf("Unrecognized error: Severity=%d; HashCode=%lu; SerialNum=%d\n", severity, hashCode, serialNum);
-} /* end EAS_ReportEx */
-
-#else
-/*----------------------------------------------------------------------------
- * EAS_Report()
- *
- * This is the error message handler. The default handler outputs error
- * messages to stdout. Modify this as needed for your system.
- *----------------------------------------------------------------------------
-*/
-void EAS_Report (int severity, const char *fmt, ...)
-{
- va_list vargs;
-
- /* check severity level */
- if (severity > severityLevel)
- return;
-
- /*lint -e{826} <allow variable args> */
- va_start(vargs, fmt);
- if (debugFile)
- {
- vfprintf(debugFile, fmt, vargs);
- if (flush)
- fflush(debugFile);
- }
- else
- {
- vprintf(fmt, vargs);
- }
- va_end(vargs);
-} /* end EAS_Report */
-
-/*----------------------------------------------------------------------------
- * EAS_ReportX()
- *
- * This is the error message handler. The default handler outputs error
- * messages to stdout. Modify this as needed for your system.
- *----------------------------------------------------------------------------
-*/
-void EAS_ReportX (int severity, const char *fmt, ...)
-{
- va_list vargs;
-
- /* check severity level */
- if (severity > severityLevel)
- return;
-
- /*lint -e{826} <allow variable args> */
- va_start(vargs, fmt);
- if (debugFile)
- {
- vfprintf(debugFile, fmt, vargs);
- if (flush)
- fflush(debugFile);
- }
- else
- {
- vprintf(fmt, vargs);
- }
- va_end(vargs);
-} /* end EAS_ReportX */
-#endif
-
-/*----------------------------------------------------------------------------
- * EAS_SetDebugLevel()
- *
- * Sets the level for debug message output
- *----------------------------------------------------------------------------
-*/
-
-void EAS_SetDebugLevel (int severity)
-{
- severityLevel = severity;
-} /* end EAS_SetDebugLevel */
-
-/*----------------------------------------------------------------------------
- * EAS_SetDebugFile()
- *
- * Redirect debugger output to the specified file.
- *----------------------------------------------------------------------------
-*/
-void EAS_SetDebugFile (void *file, int flushAfterWrite)
-{
- debugFile = (FILE*) file;
- flush = flushAfterWrite;
-} /* end EAS_SetDebugFile */
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 659 $
+ * $Date: 2007-04-24 13:36:35 -0700 (Tue, 24 Apr 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+#ifdef _lint
+#include "lint_stdlib.h"
+#else
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdarg.h>
+#endif
+
+#include "eas_report.h"
+
+static int severityLevel = 9999;
+
+/* debug file */
+static FILE *debugFile = NULL;
+int flush = 0;
+
+#ifndef _NO_DEBUG_PREPROCESSOR
+
+/* structure should have an #include for each error message header file */
+S_DEBUG_MESSAGES debugMessages[] =
+{
+#ifndef UNIFIED_DEBUG_MESSAGES
+#include "eas_config_msgs.h"
+
+
+#include "eas_host_msgs.h"
+#include "eas_hostmm_msgs.h"
+#include "eas_math_msgs.h"
+#include "eas_midi_msgs.h"
+#include "eas_mixer_msgs.h"
+#include "eas_pcm_msgs.h"
+#include "eas_public_msgs.h"
+#include "eas_smf_msgs.h"
+#include "eas_wave_msgs.h"
+#include "eas_voicemgt_msgs.h"
+
+#ifdef _FM_SYNTH
+#include "eas_fmsynth_msgs.h"
+#include "eas_fmengine_msgs.h"
+#endif
+
+#ifdef _WT_SYNTH
+#include "eas_wtsynth_msgs.h"
+#include "eas_wtengine_msgs.h"
+#endif
+
+#ifdef _ARM_TEST_MAIN
+#include "arm_main_msgs.h"
+#endif
+
+#ifdef _EAS_MAIN
+#include "eas_main_msgs.h"
+#endif
+
+#ifdef _EAS_MAIN_IPC
+#include "eas_main_ipc_msgs.h"
+#endif
+
+#ifdef _METRICS_ENABLED
+#include "eas_perf_msgs.h"
+#endif
+
+#ifdef _COMPRESSOR_ENABLED
+#include "eas_compressor_msgs.h"
+#endif
+
+#ifdef _ENHANCER_ENABLED
+#include "eas_enhancer_msgs.h"
+#endif
+
+#ifdef _WOW_ENABLED
+#include "eas_wow_msgs.h"
+#endif
+
+#ifdef _SMAF_PARSER
+#include "eas_smaf_msgs.h"
+#endif
+
+#ifdef _OTA_PARSER
+#include "eas_ota_msgs.h"
+#endif
+
+#ifdef _IMELODY_PARSER
+#include "eas_imelody_msgs.h"
+#endif
+
+#ifdef _WAVE_PARSER
+#include "eas_wavefile_msgs.h"
+#endif
+
+#if defined(_CMX_PARSER) || defined(_MFI_PARSER)
+#include "eas_cmf_msgs.h"
+#endif
+
+#if defined(_CMX_PARSER) || defined(_MFI_PARSER) || defined(_WAVE_PARSER)
+#include "eas_imaadpcm_msgs.h"
+#endif
+
+#else
+#include "eas_debugmsgs.h"
+#endif
+
+/* denotes end of error messages */
+{ 0,0,0 }
+};
+
+/*----------------------------------------------------------------------------
+ * EAS_ReportEx()
+ *
+ * This is the error message handler. The default handler outputs error
+ * messages to stdout. Modify this as needed for your system.
+ *----------------------------------------------------------------------------
+*/
+void EAS_ReportEx (int severity, unsigned long hashCode, int serialNum, ...)
+{
+ va_list vargs;
+ int i;
+
+ /* check severity level */
+ if (severity > severityLevel)
+ return;
+
+ /* find the error message and output to stdout */
+ /*lint -e{661} we check for NULL pointer - no fence post error here */
+ for (i = 0; debugMessages[i].m_pDebugMsg; i++)
+ {
+ if ((debugMessages[i].m_nHashCode == hashCode) &&
+ (debugMessages[i].m_nSerialNum == serialNum))
+ {
+ /*lint -e{826} <allow variable args> */
+ va_start(vargs, serialNum);
+ if (debugFile)
+ {
+ vfprintf(debugFile, debugMessages[i].m_pDebugMsg, vargs);
+ if (flush)
+ fflush(debugFile);
+ }
+ else
+ {
+ vprintf(debugMessages[i].m_pDebugMsg, vargs);
+ }
+ va_end(vargs);
+ return;
+ }
+ }
+ printf("Unrecognized error: Severity=%d; HashCode=%lu; SerialNum=%d\n", severity, hashCode, serialNum);
+} /* end EAS_ReportEx */
+
+#else
+/*----------------------------------------------------------------------------
+ * EAS_Report()
+ *
+ * This is the error message handler. The default handler outputs error
+ * messages to stdout. Modify this as needed for your system.
+ *----------------------------------------------------------------------------
+*/
+void EAS_Report (int severity, const char *fmt, ...)
+{
+ va_list vargs;
+
+ /* check severity level */
+ if (severity > severityLevel)
+ return;
+
+ /*lint -e{826} <allow variable args> */
+ va_start(vargs, fmt);
+ if (debugFile)
+ {
+ vfprintf(debugFile, fmt, vargs);
+ if (flush)
+ fflush(debugFile);
+ }
+ else
+ {
+ vprintf(fmt, vargs);
+ }
+ va_end(vargs);
+} /* end EAS_Report */
+
+/*----------------------------------------------------------------------------
+ * EAS_ReportX()
+ *
+ * This is the error message handler. The default handler outputs error
+ * messages to stdout. Modify this as needed for your system.
+ *----------------------------------------------------------------------------
+*/
+void EAS_ReportX (int severity, const char *fmt, ...)
+{
+ va_list vargs;
+
+ /* check severity level */
+ if (severity > severityLevel)
+ return;
+
+ /*lint -e{826} <allow variable args> */
+ va_start(vargs, fmt);
+ if (debugFile)
+ {
+ vfprintf(debugFile, fmt, vargs);
+ if (flush)
+ fflush(debugFile);
+ }
+ else
+ {
+ vprintf(fmt, vargs);
+ }
+ va_end(vargs);
+} /* end EAS_ReportX */
+#endif
+
+/*----------------------------------------------------------------------------
+ * EAS_SetDebugLevel()
+ *
+ * Sets the level for debug message output
+ *----------------------------------------------------------------------------
+*/
+
+void EAS_SetDebugLevel (int severity)
+{
+ severityLevel = severity;
+} /* end EAS_SetDebugLevel */
+
+/*----------------------------------------------------------------------------
+ * EAS_SetDebugFile()
+ *
+ * Redirect debugger output to the specified file.
+ *----------------------------------------------------------------------------
+*/
+void EAS_SetDebugFile (void *file, int flushAfterWrite)
+{
+ debugFile = (FILE*) file;
+ flush = flushAfterWrite;
+} /* end EAS_SetDebugFile */
+
diff --git a/arm-hybrid-22k/host_src/eas_report.h b/arm-hybrid-22k/host_src/eas_report.h
index 9d7c8e8..b603b12 100644
--- a/arm-hybrid-22k/host_src/eas_report.h
+++ b/arm-hybrid-22k/host_src/eas_report.h
@@ -1,15 +1,15 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_report.h
- *
- * Contents and purpose:
- * This file contains the debug message handling routines for the EAS library.
- * These routines should be modified as needed for your system.
- *
- * DO NOT MODIFY THIS FILE!
- *
- * Copyright 2005 Sonic Network Inc.
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_report.h
+ *
+ * Contents and purpose:
+ * This file contains the debug message handling routines for the EAS library.
+ * These routines should be modified as needed for your system.
+ *
+ * DO NOT MODIFY THIS FILE!
+ *
+ * Copyright 2005 Sonic Network Inc.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -22,56 +22,56 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 82 $
- * $Date: 2006-07-10 11:45:19 -0700 (Mon, 10 Jul 2006) $
- *----------------------------------------------------------------------------
-*/
-
-/* sentinel */
-#ifndef _EAS_REPORT_H
-#define _EAS_REPORT_H
-
-#define _EAS_SEVERITY_NOFILTER 0
-#define _EAS_SEVERITY_FATAL 1
-#define _EAS_SEVERITY_ERROR 2
-#define _EAS_SEVERITY_WARNING 3
-#define _EAS_SEVERITY_INFO 4
-#define _EAS_SEVERITY_DETAIL 5
-
-/* for C++ linkage */
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifndef _NO_DEBUG_PREPROCESSOR
-
-/* structure for included debug message header files */
-typedef struct
-{
- unsigned long m_nHashCode;
- int m_nSerialNum;
- char *m_pDebugMsg;
-} S_DEBUG_MESSAGES;
-
-/* debug message handling prototypes */
-extern void EAS_ReportEx (int severity, unsigned long hashCode, int serialNum, ...);
-
-#else
-
-/* these prototypes are used if the debug preprocessor is not used */
-extern void EAS_Report (int severity, const char* fmt, ...);
-extern void EAS_ReportX (int severity, const char* fmt, ...);
-
-#endif
-
-extern void EAS_SetDebugLevel (int severity);
-extern void EAS_SetDebugFile (void *file, int flushAfterWrite);
-
-#ifdef __cplusplus
-} /* end extern "C" */
-#endif
-
-#endif
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 82 $
+ * $Date: 2006-07-10 11:45:19 -0700 (Mon, 10 Jul 2006) $
+ *----------------------------------------------------------------------------
+*/
+
+/* sentinel */
+#ifndef _EAS_REPORT_H
+#define _EAS_REPORT_H
+
+#define _EAS_SEVERITY_NOFILTER 0
+#define _EAS_SEVERITY_FATAL 1
+#define _EAS_SEVERITY_ERROR 2
+#define _EAS_SEVERITY_WARNING 3
+#define _EAS_SEVERITY_INFO 4
+#define _EAS_SEVERITY_DETAIL 5
+
+/* for C++ linkage */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef _NO_DEBUG_PREPROCESSOR
+
+/* structure for included debug message header files */
+typedef struct
+{
+ unsigned long m_nHashCode;
+ int m_nSerialNum;
+ char *m_pDebugMsg;
+} S_DEBUG_MESSAGES;
+
+/* debug message handling prototypes */
+extern void EAS_ReportEx (int severity, unsigned long hashCode, int serialNum, ...);
+
+#else
+
+/* these prototypes are used if the debug preprocessor is not used */
+extern void EAS_Report (int severity, const char* fmt, ...);
+extern void EAS_ReportX (int severity, const char* fmt, ...);
+
+#endif
+
+extern void EAS_SetDebugLevel (int severity);
+extern void EAS_SetDebugFile (void *file, int flushAfterWrite);
+
+#ifdef __cplusplus
+} /* end extern "C" */
+#endif
+
+#endif
diff --git a/arm-hybrid-22k/host_src/eas_reverb.h b/arm-hybrid-22k/host_src/eas_reverb.h
index a2535fb..559abed 100644
--- a/arm-hybrid-22k/host_src/eas_reverb.h
+++ b/arm-hybrid-22k/host_src/eas_reverb.h
@@ -1,13 +1,13 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_reverb.h
- *
- * Contents and purpose:
- * Contains parameter enumerations for the Reverb effect
- *
- *
- * Copyright Sonic Network Inc. 2006
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_reverb.h
+ *
+ * Contents and purpose:
+ * Contains parameter enumerations for the Reverb effect
+ *
+ *
+ * Copyright Sonic Network Inc. 2006
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,35 +20,35 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 300 $
- * $Date: 2006-09-11 17:37:20 -0700 (Mon, 11 Sep 2006) $
- *----------------------------------------------------------------------------
-*/
-
-#ifndef _EAS_REVERB_H
-#define _EAS_REVERB_H
-
-
-/* enumerated parameter settings for Reverb effect */
-typedef enum
-{
- EAS_PARAM_REVERB_BYPASS,
- EAS_PARAM_REVERB_PRESET,
- EAS_PARAM_REVERB_WET,
- EAS_PARAM_REVERB_DRY
-} E_REVERB_PARAMS;
-
-
-typedef enum
-{
- EAS_PARAM_REVERB_LARGE_HALL,
- EAS_PARAM_REVERB_HALL,
- EAS_PARAM_REVERB_CHAMBER,
- EAS_PARAM_REVERB_ROOM,
-} E_REVERB_PRESETS;
-
-
-#endif /* _REVERB_H */
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 300 $
+ * $Date: 2006-09-11 17:37:20 -0700 (Mon, 11 Sep 2006) $
+ *----------------------------------------------------------------------------
+*/
+
+#ifndef _EAS_REVERB_H
+#define _EAS_REVERB_H
+
+
+/* enumerated parameter settings for Reverb effect */
+typedef enum
+{
+ EAS_PARAM_REVERB_BYPASS,
+ EAS_PARAM_REVERB_PRESET,
+ EAS_PARAM_REVERB_WET,
+ EAS_PARAM_REVERB_DRY
+} E_REVERB_PARAMS;
+
+
+typedef enum
+{
+ EAS_PARAM_REVERB_LARGE_HALL,
+ EAS_PARAM_REVERB_HALL,
+ EAS_PARAM_REVERB_CHAMBER,
+ EAS_PARAM_REVERB_ROOM,
+} E_REVERB_PRESETS;
+
+
+#endif /* _REVERB_H */
diff --git a/arm-hybrid-22k/host_src/eas_types.h b/arm-hybrid-22k/host_src/eas_types.h
index f0293ef..45fa4b2 100644
--- a/arm-hybrid-22k/host_src/eas_types.h
+++ b/arm-hybrid-22k/host_src/eas_types.h
@@ -1,17 +1,17 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_types.h
- *
- * Contents and purpose:
- * The public interface header for the EAS synthesizer.
- *
- * This header only contains declarations that are specific
- * to this implementation.
- *
- * DO NOT MODIFY THIS FILE!
- *
- * Copyright Sonic Network Inc. 2004
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_types.h
+ *
+ * Contents and purpose:
+ * The public interface header for the EAS synthesizer.
+ *
+ * This header only contains declarations that are specific
+ * to this implementation.
+ *
+ * DO NOT MODIFY THIS FILE!
+ *
+ * Copyright Sonic Network Inc. 2004
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -24,245 +24,245 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 726 $
- * $Date: 2007-06-14 23:10:46 -0700 (Thu, 14 Jun 2007) $
- *----------------------------------------------------------------------------
-*/
-
-#ifndef _EAS_TYPES_H
-#define _EAS_TYPES_H
-
-/* EAS_RESULT return codes */
-typedef long EAS_RESULT;
-#define EAS_SUCCESS 0
-#define EAS_FAILURE -1
-#define EAS_ERROR_INVALID_MODULE -2
-#define EAS_ERROR_MALLOC_FAILED -3
-#define EAS_ERROR_FILE_POS -4
-#define EAS_ERROR_INVALID_FILE_MODE -5
-#define EAS_ERROR_FILE_SEEK -6
-#define EAS_ERROR_FILE_LENGTH -7
-#define EAS_ERROR_NOT_IMPLEMENTED -8
-#define EAS_ERROR_CLOSE_FAILED -9
-#define EAS_ERROR_FILE_OPEN_FAILED -10
-#define EAS_ERROR_INVALID_HANDLE -11
-#define EAS_ERROR_NO_MIX_BUFFER -12
-#define EAS_ERROR_PARAMETER_RANGE -13
-#define EAS_ERROR_MAX_FILES_OPEN -14
-#define EAS_ERROR_UNRECOGNIZED_FORMAT -15
-#define EAS_BUFFER_SIZE_MISMATCH -16
-#define EAS_ERROR_FILE_FORMAT -17
-#define EAS_ERROR_SMF_NOT_INITIALIZED -18
-#define EAS_ERROR_LOCATE_BEYOND_END -19
-#define EAS_ERROR_INVALID_PCM_TYPE -20
-#define EAS_ERROR_MAX_PCM_STREAMS -21
-#define EAS_ERROR_NO_VOICE_ALLOCATED -22
-#define EAS_ERROR_INVALID_CHANNEL -23
-#define EAS_ERROR_ALREADY_STOPPED -24
-#define EAS_ERROR_FILE_READ_FAILED -25
-#define EAS_ERROR_HANDLE_INTEGRITY -26
-#define EAS_ERROR_MAX_STREAMS_OPEN -27
-#define EAS_ERROR_INVALID_PARAMETER -28
-#define EAS_ERROR_FEATURE_NOT_AVAILABLE -29
-#define EAS_ERROR_SOUND_LIBRARY -30
-#define EAS_ERROR_NOT_VALID_IN_THIS_STATE -31
-#define EAS_ERROR_NO_VIRTUAL_SYNTHESIZER -32
-#define EAS_ERROR_FILE_ALREADY_OPEN -33
-#define EAS_ERROR_FILE_ALREADY_CLOSED -34
-#define EAS_ERROR_INCOMPATIBLE_VERSION -35
-#define EAS_ERROR_QUEUE_IS_FULL -36
-#define EAS_ERROR_QUEUE_IS_EMPTY -37
-#define EAS_ERROR_FEATURE_ALREADY_ACTIVE -38
-
-/* special return codes */
-#define EAS_EOF 3
-#define EAS_STREAM_BUFFERING 4
-#define EAS_BUFFER_FULL 5
-
-/* EAS_STATE return codes */
-typedef long EAS_STATE;
-typedef enum
-{
- EAS_STATE_READY = 0,
- EAS_STATE_PLAY,
- EAS_STATE_STOPPING,
- EAS_STATE_PAUSING,
- EAS_STATE_STOPPED,
- EAS_STATE_PAUSED,
- EAS_STATE_OPEN,
- EAS_STATE_ERROR,
- EAS_STATE_EMPTY
-} E_EAS_STATE;
-
-/* constants */
-#ifndef EAS_CONST
-#define EAS_CONST const
-#endif
-
-/* definition for public interface functions */
-#ifndef EAS_PUBLIC
-#define EAS_PUBLIC
-#endif
-
-/* boolean values */
-typedef unsigned EAS_BOOL;
-typedef unsigned char EAS_BOOL8;
-
-#define EAS_FALSE 0
-#define EAS_TRUE 1
-
-/* scalar variable definitions */
-typedef unsigned char EAS_U8;
-typedef signed char EAS_I8;
-typedef char EAS_CHAR;
-
-typedef unsigned short EAS_U16;
-typedef short EAS_I16;
-
-typedef unsigned long EAS_U32;
-typedef long EAS_I32;
-
-typedef unsigned EAS_UINT;
-typedef int EAS_INT;
-typedef long EAS_LONG;
-
-/* audio output type */
-typedef short EAS_PCM;
-
-/* file open modes */
-typedef EAS_I32 EAS_FILE_MODE;
-#define EAS_FILE_READ 1
-#define EAS_FILE_WRITE 2
-
-/* file locator e.g. filename or memory pointer */
-typedef const void *EAS_FILE_LOCATOR;
-
-/* handle to stream */
-typedef struct s_eas_stream_tag *EAS_HANDLE;
-
-/* handle to file */
-typedef struct eas_hw_file_tag *EAS_FILE_HANDLE;
-
-/* handle for synthesizer data */
-typedef struct s_eas_data_tag *EAS_DATA_HANDLE;
-
-/* handle to persistent data for host wrapper interface */
-typedef struct eas_hw_inst_data_tag *EAS_HW_DATA_HANDLE;
-
-/* handle to sound library */
-typedef struct s_eas_sndlib_tag *EAS_SNDLIB_HANDLE;
-typedef struct s_eas_dls_tag *EAS_DLSLIB_HANDLE;
-
-/* pointer to frame buffer - used in split architecture only */
-typedef struct s_eas_frame_buffer_tag *EAS_FRAME_BUFFER_HANDLE;
-
-/* untyped pointer for instance data */
-typedef void *EAS_VOID_PTR;
-
-/* inline functions */
-#ifndef EAS_INLINE
-#if defined (__XCC__)
-#define EAS_INLINE __inline__
-#elif defined (__GNUC__)
-#define EAS_INLINE inline static
-#else
-#define EAS_INLINE __inline
-#endif
-#endif
-
-/* define NULL value */
-#ifndef NULL
-#define NULL 0
-#endif
-
-/* metadata types for metadata return codes */
-typedef enum
-{
- EAS_METADATA_UNKNOWN = 0,
- EAS_METADATA_TITLE,
- EAS_METADATA_AUTHOR,
- EAS_METADATA_COPYRIGHT,
- EAS_METADATA_LYRIC,
- EAS_METADATA_TEXT
-} E_EAS_METADATA_TYPE;
-
-/* metadata callback function */
-typedef void (*EAS_METADATA_CBFUNC) (E_EAS_METADATA_TYPE metaDataType, char *metaDataBuf, EAS_VOID_PTR pUserData);
-
-/* file types for metadata return codes */
-typedef enum
-{
- EAS_FILE_UNKNOWN = 0,
- EAS_FILE_SMF0,
- EAS_FILE_SMF1,
- EAS_FILE_SMAF_UNKNOWN,
- EAS_FILE_SMAF_MA2,
- EAS_FILE_SMAF_MA3,
- EAS_FILE_SMAF_MA5,
- EAS_FILE_CMX,
- EAS_FILE_MFI,
- EAS_FILE_OTA,
- EAS_FILE_IMELODY,
- EAS_FILE_RTTTL,
- EAS_FILE_XMF0,
- EAS_FILE_XMF1,
- EAS_FILE_WAVE_PCM,
- EAS_FILE_WAVE_IMA_ADPCM,
- EAS_FILE_MMAPI_TONE_CONTROL
-} E_EAS_FILE_TYPE;
-
-/* enumeration for synthesizers */
-typedef enum
-{
- EAS_MCU_SYNTH = 0,
- EAS_DSP_SYNTH
-} E_SYNTHESIZER;
-
-/* external audio callback program change */
-typedef struct s_ext_audio_prg_chg_tag
-{
- EAS_U16 bank;
- EAS_U8 program;
- EAS_U8 channel;
-} S_EXT_AUDIO_PRG_CHG;
-
-/* external audio callback event */
-typedef struct s_ext_audio_event_tag
-{
- EAS_U8 channel;
- EAS_U8 note;
- EAS_U8 velocity;
- EAS_BOOL8 noteOn;
-} S_EXT_AUDIO_EVENT;
-
-typedef struct s_midi_controllers_tag
-{
- EAS_U8 modWheel; /* CC1 */
- EAS_U8 volume; /* CC7 */
- EAS_U8 pan; /* CC10 */
- EAS_U8 expression; /* CC11 */
- EAS_U8 channelPressure; /* MIDI channel pressure */
-
-#ifdef _REVERB
- EAS_U8 reverbSend; /* CC91 */
-#endif
-
-#ifdef _CHORUS
- EAS_U8 chorusSend; /* CC93 */
-#endif
-} S_MIDI_CONTROLLERS;
-
-/* iMode play modes enumeration for EAS_SetPlayMode */
-typedef enum
-{
- IMODE_PLAY_ALL = 0,
- IMODE_PLAY_PARTIAL
-} E_I_MODE_PLAY_MODE;
-
-typedef EAS_BOOL (*EAS_EXT_PRG_CHG_FUNC) (EAS_VOID_PTR pInstData, S_EXT_AUDIO_PRG_CHG *pPrgChg);
-typedef EAS_BOOL (*EAS_EXT_EVENT_FUNC) (EAS_VOID_PTR pInstData, S_EXT_AUDIO_EVENT *pEvent);
-
-#endif /* #ifndef _EAS_TYPES_H */
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 726 $
+ * $Date: 2007-06-14 23:10:46 -0700 (Thu, 14 Jun 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+#ifndef _EAS_TYPES_H
+#define _EAS_TYPES_H
+
+/* EAS_RESULT return codes */
+typedef long EAS_RESULT;
+#define EAS_SUCCESS 0
+#define EAS_FAILURE -1
+#define EAS_ERROR_INVALID_MODULE -2
+#define EAS_ERROR_MALLOC_FAILED -3
+#define EAS_ERROR_FILE_POS -4
+#define EAS_ERROR_INVALID_FILE_MODE -5
+#define EAS_ERROR_FILE_SEEK -6
+#define EAS_ERROR_FILE_LENGTH -7
+#define EAS_ERROR_NOT_IMPLEMENTED -8
+#define EAS_ERROR_CLOSE_FAILED -9
+#define EAS_ERROR_FILE_OPEN_FAILED -10
+#define EAS_ERROR_INVALID_HANDLE -11
+#define EAS_ERROR_NO_MIX_BUFFER -12
+#define EAS_ERROR_PARAMETER_RANGE -13
+#define EAS_ERROR_MAX_FILES_OPEN -14
+#define EAS_ERROR_UNRECOGNIZED_FORMAT -15
+#define EAS_BUFFER_SIZE_MISMATCH -16
+#define EAS_ERROR_FILE_FORMAT -17
+#define EAS_ERROR_SMF_NOT_INITIALIZED -18
+#define EAS_ERROR_LOCATE_BEYOND_END -19
+#define EAS_ERROR_INVALID_PCM_TYPE -20
+#define EAS_ERROR_MAX_PCM_STREAMS -21
+#define EAS_ERROR_NO_VOICE_ALLOCATED -22
+#define EAS_ERROR_INVALID_CHANNEL -23
+#define EAS_ERROR_ALREADY_STOPPED -24
+#define EAS_ERROR_FILE_READ_FAILED -25
+#define EAS_ERROR_HANDLE_INTEGRITY -26
+#define EAS_ERROR_MAX_STREAMS_OPEN -27
+#define EAS_ERROR_INVALID_PARAMETER -28
+#define EAS_ERROR_FEATURE_NOT_AVAILABLE -29
+#define EAS_ERROR_SOUND_LIBRARY -30
+#define EAS_ERROR_NOT_VALID_IN_THIS_STATE -31
+#define EAS_ERROR_NO_VIRTUAL_SYNTHESIZER -32
+#define EAS_ERROR_FILE_ALREADY_OPEN -33
+#define EAS_ERROR_FILE_ALREADY_CLOSED -34
+#define EAS_ERROR_INCOMPATIBLE_VERSION -35
+#define EAS_ERROR_QUEUE_IS_FULL -36
+#define EAS_ERROR_QUEUE_IS_EMPTY -37
+#define EAS_ERROR_FEATURE_ALREADY_ACTIVE -38
+
+/* special return codes */
+#define EAS_EOF 3
+#define EAS_STREAM_BUFFERING 4
+#define EAS_BUFFER_FULL 5
+
+/* EAS_STATE return codes */
+typedef long EAS_STATE;
+typedef enum
+{
+ EAS_STATE_READY = 0,
+ EAS_STATE_PLAY,
+ EAS_STATE_STOPPING,
+ EAS_STATE_PAUSING,
+ EAS_STATE_STOPPED,
+ EAS_STATE_PAUSED,
+ EAS_STATE_OPEN,
+ EAS_STATE_ERROR,
+ EAS_STATE_EMPTY
+} E_EAS_STATE;
+
+/* constants */
+#ifndef EAS_CONST
+#define EAS_CONST const
+#endif
+
+/* definition for public interface functions */
+#ifndef EAS_PUBLIC
+#define EAS_PUBLIC
+#endif
+
+/* boolean values */
+typedef unsigned EAS_BOOL;
+typedef unsigned char EAS_BOOL8;
+
+#define EAS_FALSE 0
+#define EAS_TRUE 1
+
+/* scalar variable definitions */
+typedef unsigned char EAS_U8;
+typedef signed char EAS_I8;
+typedef char EAS_CHAR;
+
+typedef unsigned short EAS_U16;
+typedef short EAS_I16;
+
+typedef unsigned long EAS_U32;
+typedef long EAS_I32;
+
+typedef unsigned EAS_UINT;
+typedef int EAS_INT;
+typedef long EAS_LONG;
+
+/* audio output type */
+typedef short EAS_PCM;
+
+/* file open modes */
+typedef EAS_I32 EAS_FILE_MODE;
+#define EAS_FILE_READ 1
+#define EAS_FILE_WRITE 2
+
+/* file locator e.g. filename or memory pointer */
+typedef const void *EAS_FILE_LOCATOR;
+
+/* handle to stream */
+typedef struct s_eas_stream_tag *EAS_HANDLE;
+
+/* handle to file */
+typedef struct eas_hw_file_tag *EAS_FILE_HANDLE;
+
+/* handle for synthesizer data */
+typedef struct s_eas_data_tag *EAS_DATA_HANDLE;
+
+/* handle to persistent data for host wrapper interface */
+typedef struct eas_hw_inst_data_tag *EAS_HW_DATA_HANDLE;
+
+/* handle to sound library */
+typedef struct s_eas_sndlib_tag *EAS_SNDLIB_HANDLE;
+typedef struct s_eas_dls_tag *EAS_DLSLIB_HANDLE;
+
+/* pointer to frame buffer - used in split architecture only */
+typedef struct s_eas_frame_buffer_tag *EAS_FRAME_BUFFER_HANDLE;
+
+/* untyped pointer for instance data */
+typedef void *EAS_VOID_PTR;
+
+/* inline functions */
+#ifndef EAS_INLINE
+#if defined (__XCC__)
+#define EAS_INLINE __inline__
+#elif defined (__GNUC__)
+#define EAS_INLINE inline static
+#else
+#define EAS_INLINE __inline
+#endif
+#endif
+
+/* define NULL value */
+#ifndef NULL
+#define NULL 0
+#endif
+
+/* metadata types for metadata return codes */
+typedef enum
+{
+ EAS_METADATA_UNKNOWN = 0,
+ EAS_METADATA_TITLE,
+ EAS_METADATA_AUTHOR,
+ EAS_METADATA_COPYRIGHT,
+ EAS_METADATA_LYRIC,
+ EAS_METADATA_TEXT
+} E_EAS_METADATA_TYPE;
+
+/* metadata callback function */
+typedef void (*EAS_METADATA_CBFUNC) (E_EAS_METADATA_TYPE metaDataType, char *metaDataBuf, EAS_VOID_PTR pUserData);
+
+/* file types for metadata return codes */
+typedef enum
+{
+ EAS_FILE_UNKNOWN = 0,
+ EAS_FILE_SMF0,
+ EAS_FILE_SMF1,
+ EAS_FILE_SMAF_UNKNOWN,
+ EAS_FILE_SMAF_MA2,
+ EAS_FILE_SMAF_MA3,
+ EAS_FILE_SMAF_MA5,
+ EAS_FILE_CMX,
+ EAS_FILE_MFI,
+ EAS_FILE_OTA,
+ EAS_FILE_IMELODY,
+ EAS_FILE_RTTTL,
+ EAS_FILE_XMF0,
+ EAS_FILE_XMF1,
+ EAS_FILE_WAVE_PCM,
+ EAS_FILE_WAVE_IMA_ADPCM,
+ EAS_FILE_MMAPI_TONE_CONTROL
+} E_EAS_FILE_TYPE;
+
+/* enumeration for synthesizers */
+typedef enum
+{
+ EAS_MCU_SYNTH = 0,
+ EAS_DSP_SYNTH
+} E_SYNTHESIZER;
+
+/* external audio callback program change */
+typedef struct s_ext_audio_prg_chg_tag
+{
+ EAS_U16 bank;
+ EAS_U8 program;
+ EAS_U8 channel;
+} S_EXT_AUDIO_PRG_CHG;
+
+/* external audio callback event */
+typedef struct s_ext_audio_event_tag
+{
+ EAS_U8 channel;
+ EAS_U8 note;
+ EAS_U8 velocity;
+ EAS_BOOL8 noteOn;
+} S_EXT_AUDIO_EVENT;
+
+typedef struct s_midi_controllers_tag
+{
+ EAS_U8 modWheel; /* CC1 */
+ EAS_U8 volume; /* CC7 */
+ EAS_U8 pan; /* CC10 */
+ EAS_U8 expression; /* CC11 */
+ EAS_U8 channelPressure; /* MIDI channel pressure */
+
+#ifdef _REVERB
+ EAS_U8 reverbSend; /* CC91 */
+#endif
+
+#ifdef _CHORUS
+ EAS_U8 chorusSend; /* CC93 */
+#endif
+} S_MIDI_CONTROLLERS;
+
+/* iMode play modes enumeration for EAS_SetPlayMode */
+typedef enum
+{
+ IMODE_PLAY_ALL = 0,
+ IMODE_PLAY_PARTIAL
+} E_I_MODE_PLAY_MODE;
+
+typedef EAS_BOOL (*EAS_EXT_PRG_CHG_FUNC) (EAS_VOID_PTR pInstData, S_EXT_AUDIO_PRG_CHG *pPrgChg);
+typedef EAS_BOOL (*EAS_EXT_EVENT_FUNC) (EAS_VOID_PTR pInstData, S_EXT_AUDIO_EVENT *pEvent);
+
+#endif /* #ifndef _EAS_TYPES_H */
diff --git a/arm-hybrid-22k/host_src/eas_wave.c b/arm-hybrid-22k/host_src/eas_wave.c
index 02fed6e..4f6ffbd 100644
--- a/arm-hybrid-22k/host_src/eas_wave.c
+++ b/arm-hybrid-22k/host_src/eas_wave.c
@@ -1,13 +1,13 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_wave.c
- *
- * Contents and purpose:
- * This module contains .WAV file functions for the EAS synthesizer
- * test harness.
- *
- * Copyright Sonic Network Inc. 2005
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_wave.c
+ *
+ * Contents and purpose:
+ * This module contains .WAV file functions for the EAS synthesizer
+ * test harness.
+ *
+ * Copyright Sonic Network Inc. 2005
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,404 +20,404 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 658 $
- * $Date: 2007-04-24 13:35:49 -0700 (Tue, 24 Apr 2007) $
- *----------------------------------------------------------------------------
-*/
-
-/* lint complaints about most C library headers, so we use our own during lint step */
-#ifdef _lint
-#include "lint_stdlib.h"
-#else
-#include <stdio.h>
-#include <stdlib.h>
-#endif
-
-#include "eas_wave.h"
-
-/* .WAV file format tags */
-const EAS_U32 riffTag = 0x46464952;
-const EAS_U32 waveTag = 0x45564157;
-const EAS_U32 fmtTag = 0x20746d66;
-const EAS_U32 dataTag = 0x61746164;
-
-#ifdef _BIG_ENDIAN
-/*----------------------------------------------------------------------------
- * FlipDWord()
- *----------------------------------------------------------------------------
- * Purpose: Endian flip a DWORD for big-endian processors
- *
- * Inputs:
- *
- * Outputs:
- *
- *----------------------------------------------------------------------------
-*/
-static void FlipDWord (EAS_U32 *pValue)
-{
- EAS_U8 *p;
- EAS_U32 temp;
-
- p = (EAS_U8*) pValue;
- temp = (((((p[3] << 8) | p[2]) << 8) | p[1]) << 8) | p[0];
- *pValue = temp;
-}
-
-/*----------------------------------------------------------------------------
- * FlipWord()
- *----------------------------------------------------------------------------
- * Purpose: Endian flip a WORD for big-endian processors
- *
- * Inputs:
- *
- * Outputs:
- *
- *----------------------------------------------------------------------------
-*/
-static void FlipWord (EAS_U16 *pValue)
-{
- EAS_U8 *p;
- EAS_U16 temp;
-
- p = (EAS_U8*) pValue;
- temp = (p[1] << 8) | p[0];
- *pValue = temp;
-}
-
-/*----------------------------------------------------------------------------
- * FlipWaveHeader()
- *----------------------------------------------------------------------------
- * Purpose: Endian flip the wave header for big-endian processors
- *
- * Inputs:
- *
- * Outputs:
- *
- *----------------------------------------------------------------------------
-*/
-static void FlipWaveHeader (WAVE_HEADER *p)
-{
-
- FlipDWord(&p->nRiffTag);
- FlipDWord(&p->nRiffSize);
- FlipDWord(&p->nWaveTag);
- FlipDWord(&p->nFmtTag);
- FlipDWord(&p->nFmtSize);
- FlipDWord(&p->nDataTag);
- FlipDWord(&p->nDataSize);
- FlipWord(&p->fc.wFormatTag);
- FlipWord(&p->fc.nChannels);
- FlipDWord(&p->fc.nSamplesPerSec);
- FlipDWord(&p->fc.nAvgBytesPerSec);
- FlipWord(&p->fc.nBlockAlign);
- FlipWord(&p->fc.wBitsPerSample);
-
-}
-#endif
-
-/*----------------------------------------------------------------------------
- * WaveFileCreate()
- *----------------------------------------------------------------------------
- * Purpose: Opens a wave file for writing and writes the header
- *
- * Inputs:
- *
- * Outputs:
- *
- *----------------------------------------------------------------------------
-*/
-
-WAVE_FILE *WaveFileCreate (const char *filename, EAS_I32 nChannels, EAS_I32 nSamplesPerSec, EAS_I32 wBitsPerSample)
-{
- WAVE_FILE *wFile;
-
- /* allocate memory */
- wFile = malloc(sizeof(WAVE_FILE));
- if (!wFile)
- return NULL;
- wFile->write = EAS_TRUE;
-
- /* create the file */
- wFile->file = fopen(filename,"wb");
- if (!wFile->file)
- {
- free(wFile);
- return NULL;
- }
-
- /* initialize PCM format .WAV file header */
- wFile->wh.nRiffTag = riffTag;
- wFile->wh.nRiffSize = sizeof(WAVE_HEADER) - 8;
- wFile->wh.nWaveTag = waveTag;
- wFile->wh.nFmtTag = fmtTag;
- wFile->wh.nFmtSize = sizeof(FMT_CHUNK);
-
- /* initalize 'fmt' chunk */
- wFile->wh.fc.wFormatTag = 1;
- wFile->wh.fc.nChannels = (EAS_U16) nChannels;
- wFile->wh.fc.nSamplesPerSec = (EAS_U32) nSamplesPerSec;
- wFile->wh.fc.wBitsPerSample = (EAS_U16) wBitsPerSample;
- wFile->wh.fc.nBlockAlign = (EAS_U16) (nChannels * (EAS_U16) (wBitsPerSample / 8));
- wFile->wh.fc.nAvgBytesPerSec = wFile->wh.fc.nBlockAlign * (EAS_U32) nSamplesPerSec;
-
- /* initialize 'data' chunk */
- wFile->wh.nDataTag = dataTag;
- wFile->wh.nDataSize = 0;
-
-#ifdef _BIG_ENDIAN
- FlipWaveHeader(&wFile->wh);
-#endif
-
- /* write the header */
- if (fwrite(&wFile->wh, sizeof(WAVE_HEADER), 1, wFile->file) != 1)
- {
- fclose(wFile->file);
- free(wFile);
- return NULL;
- }
-
-#ifdef _BIG_ENDIAN
- FlipWaveHeader(&wFile->wh);
-#endif
-
- /* return the file handle */
- return wFile;
-} /* end WaveFileCreate */
-
-/*----------------------------------------------------------------------------
- * WaveFileWrite()
- *----------------------------------------------------------------------------
- * Purpose: Writes data to the wave file
- *
- * Inputs:
- *
- * Outputs:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_I32 WaveFileWrite (WAVE_FILE *wFile, void *buffer, EAS_I32 n)
-{
- EAS_I32 count;
-
- /* make sure we have an open file */
- if (wFile == NULL)
- {
- return 0;
- }
-
-#ifdef _BIG_ENDIAN
- {
- EAS_I32 i;
- EAS_U16 *p;
- p = buffer;
- i = n >> 1;
- while (i--)
- FlipWord(p++);
- }
-#endif
-
- /* write the data */
- count = (EAS_I32) fwrite(buffer, 1, (size_t) n, wFile->file);
-
- /* add the number of bytes written */
- wFile->wh.nRiffSize += (EAS_U32) count;
- wFile->wh.nDataSize += (EAS_U32) count;
-
- /* return the count of bytes written */
- return count;
-} /* end WriteWaveHeader */
-
-/*----------------------------------------------------------------------------
- * WaveFileClose()
- *----------------------------------------------------------------------------
- * Purpose: Opens a wave file for writing and writes the header
- *
- * Inputs:
- *
- * Outputs:
- *
- *----------------------------------------------------------------------------
-*/
-
-EAS_BOOL WaveFileClose (WAVE_FILE *wFile)
-{
- EAS_I32 count = 1;
-
- /* return to beginning of file and write the header */
- if (wFile->write)
- {
- if (fseek(wFile->file, 0L, SEEK_SET) == 0)
- {
-
-#ifdef _BIG_ENDIAN
- FlipWaveHeader(&wFile->wh);
-#endif
- count = (EAS_I32) fwrite(&wFile->wh, sizeof(WAVE_HEADER), 1, wFile->file);
-#ifdef _BIG_ENDIAN
- FlipWaveHeader(&wFile->wh);
-#endif
- }
- }
-
- /* close the file */
- if (fclose(wFile->file) != 0)
- count = 0;
-
- /* free the memory */
- free(wFile);
-
- /* return the file handle */
- return (count == 1 ? EAS_TRUE : EAS_FALSE);
-} /* end WaveFileClose */
-
-#ifdef _WAVE_FILE_READ
-#ifdef _BIG_ENDIAN
-#error "WaveFileOpen not currently supported on big-endian processors"
-#endif
-/*----------------------------------------------------------------------------
- * WaveFileOpen()
- *----------------------------------------------------------------------------
- * Purpose: Opens a wave file for reading and reads the header
- *
- * Inputs:
- *
- * Outputs:
- *
- *----------------------------------------------------------------------------
-*/
-
-WAVE_FILE *WaveFileOpen (const char *filename)
-{
- WAVE_FILE *wFile;
- struct
- {
- EAS_U32 tag;
- EAS_U32 size;
- } chunk;
- EAS_U32 tag;
- EAS_I32 startChunkPos;
- EAS_INT state;
- EAS_BOOL done;
-
- /* allocate memory */
- wFile = malloc(sizeof(WAVE_FILE));
- if (!wFile)
- return NULL;
-
- /* open the file */
- wFile->write = EAS_FALSE;
- wFile->file = fopen(filename,"rb");
- if (!wFile->file)
- {
- free(wFile);
- return NULL;
- }
-
- /* make lint happy */
- chunk.tag = chunk.size = 0;
- startChunkPos = 0;
-
- /* read the RIFF tag and file size */
- state = 0;
- done = EAS_FALSE;
- while (!done)
- {
-
- switch(state)
- {
- /* read the RIFF tag */
- case 0:
- if (fread(&chunk, sizeof(chunk), 1, wFile->file) != 1)
- done = EAS_TRUE;
- else
- {
- if (chunk.tag != riffTag)
- done = EAS_TRUE;
- else
- state++;
- }
- break;
-
- /* read the WAVE tag */
- case 1:
- if (fread(&tag, sizeof(tag), 1, wFile->file) != 1)
- done = EAS_TRUE;
- else
- {
- if (tag != waveTag)
- done = EAS_TRUE;
- else
- state++;
- }
- break;
-
- /* looking for fmt chunk */
- case 2:
- if (fread(&chunk, sizeof(chunk), 1, wFile->file) != 1)
- done = EAS_TRUE;
- else
- {
- startChunkPos = ftell(wFile->file);
-
- /* not fmt tag, skip it */
- if (chunk.tag != fmtTag)
- fseek(wFile->file, startChunkPos + (EAS_I32) chunk.size, SEEK_SET);
- else
- state++;
- }
- break;
-
- /* read fmt chunk */
- case 3:
- if (fread(&wFile->wh.fc, sizeof(FMT_CHUNK), 1, wFile->file) != 1)
- done = EAS_TRUE;
- else
- {
- fseek(wFile->file, startChunkPos + (EAS_I32) chunk.size, SEEK_SET);
- state++;
- }
- break;
-
- /* looking for data chunk */
- case 4:
- if (fread(&chunk, sizeof(chunk), 1, wFile->file) != 1)
- done = EAS_TRUE;
- else
- {
- startChunkPos = ftell(wFile->file);
-
- /* not data tag, skip it */
- if (chunk.tag != dataTag)
- fseek(wFile->file, startChunkPos + (EAS_I32) chunk.size, SEEK_SET);
- else
- {
- wFile->dataSize = chunk.size;
- state++;
- done = EAS_TRUE;
- }
- }
- break;
-
- default:
- done = EAS_TRUE;
- break;
- }
- }
-
- /* if not final state, an error occurred */
- if (state != 5)
- {
- fclose(wFile->file);
- free(wFile);
- return NULL;
- }
-
- /* return the file handle */
- return wFile;
-} /* end WaveFileOpen */
-#endif
-
-
-
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 658 $
+ * $Date: 2007-04-24 13:35:49 -0700 (Tue, 24 Apr 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+/* lint complaints about most C library headers, so we use our own during lint step */
+#ifdef _lint
+#include "lint_stdlib.h"
+#else
+#include <stdio.h>
+#include <stdlib.h>
+#endif
+
+#include "eas_wave.h"
+
+/* .WAV file format tags */
+const EAS_U32 riffTag = 0x46464952;
+const EAS_U32 waveTag = 0x45564157;
+const EAS_U32 fmtTag = 0x20746d66;
+const EAS_U32 dataTag = 0x61746164;
+
+#ifdef _BIG_ENDIAN
+/*----------------------------------------------------------------------------
+ * FlipDWord()
+ *----------------------------------------------------------------------------
+ * Purpose: Endian flip a DWORD for big-endian processors
+ *
+ * Inputs:
+ *
+ * Outputs:
+ *
+ *----------------------------------------------------------------------------
+*/
+static void FlipDWord (EAS_U32 *pValue)
+{
+ EAS_U8 *p;
+ EAS_U32 temp;
+
+ p = (EAS_U8*) pValue;
+ temp = (((((p[3] << 8) | p[2]) << 8) | p[1]) << 8) | p[0];
+ *pValue = temp;
+}
+
+/*----------------------------------------------------------------------------
+ * FlipWord()
+ *----------------------------------------------------------------------------
+ * Purpose: Endian flip a WORD for big-endian processors
+ *
+ * Inputs:
+ *
+ * Outputs:
+ *
+ *----------------------------------------------------------------------------
+*/
+static void FlipWord (EAS_U16 *pValue)
+{
+ EAS_U8 *p;
+ EAS_U16 temp;
+
+ p = (EAS_U8*) pValue;
+ temp = (p[1] << 8) | p[0];
+ *pValue = temp;
+}
+
+/*----------------------------------------------------------------------------
+ * FlipWaveHeader()
+ *----------------------------------------------------------------------------
+ * Purpose: Endian flip the wave header for big-endian processors
+ *
+ * Inputs:
+ *
+ * Outputs:
+ *
+ *----------------------------------------------------------------------------
+*/
+static void FlipWaveHeader (WAVE_HEADER *p)
+{
+
+ FlipDWord(&p->nRiffTag);
+ FlipDWord(&p->nRiffSize);
+ FlipDWord(&p->nWaveTag);
+ FlipDWord(&p->nFmtTag);
+ FlipDWord(&p->nFmtSize);
+ FlipDWord(&p->nDataTag);
+ FlipDWord(&p->nDataSize);
+ FlipWord(&p->fc.wFormatTag);
+ FlipWord(&p->fc.nChannels);
+ FlipDWord(&p->fc.nSamplesPerSec);
+ FlipDWord(&p->fc.nAvgBytesPerSec);
+ FlipWord(&p->fc.nBlockAlign);
+ FlipWord(&p->fc.wBitsPerSample);
+
+}
+#endif
+
+/*----------------------------------------------------------------------------
+ * WaveFileCreate()
+ *----------------------------------------------------------------------------
+ * Purpose: Opens a wave file for writing and writes the header
+ *
+ * Inputs:
+ *
+ * Outputs:
+ *
+ *----------------------------------------------------------------------------
+*/
+
+WAVE_FILE *WaveFileCreate (const char *filename, EAS_I32 nChannels, EAS_I32 nSamplesPerSec, EAS_I32 wBitsPerSample)
+{
+ WAVE_FILE *wFile;
+
+ /* allocate memory */
+ wFile = malloc(sizeof(WAVE_FILE));
+ if (!wFile)
+ return NULL;
+ wFile->write = EAS_TRUE;
+
+ /* create the file */
+ wFile->file = fopen(filename,"wb");
+ if (!wFile->file)
+ {
+ free(wFile);
+ return NULL;
+ }
+
+ /* initialize PCM format .WAV file header */
+ wFile->wh.nRiffTag = riffTag;
+ wFile->wh.nRiffSize = sizeof(WAVE_HEADER) - 8;
+ wFile->wh.nWaveTag = waveTag;
+ wFile->wh.nFmtTag = fmtTag;
+ wFile->wh.nFmtSize = sizeof(FMT_CHUNK);
+
+ /* initalize 'fmt' chunk */
+ wFile->wh.fc.wFormatTag = 1;
+ wFile->wh.fc.nChannels = (EAS_U16) nChannels;
+ wFile->wh.fc.nSamplesPerSec = (EAS_U32) nSamplesPerSec;
+ wFile->wh.fc.wBitsPerSample = (EAS_U16) wBitsPerSample;
+ wFile->wh.fc.nBlockAlign = (EAS_U16) (nChannels * (EAS_U16) (wBitsPerSample / 8));
+ wFile->wh.fc.nAvgBytesPerSec = wFile->wh.fc.nBlockAlign * (EAS_U32) nSamplesPerSec;
+
+ /* initialize 'data' chunk */
+ wFile->wh.nDataTag = dataTag;
+ wFile->wh.nDataSize = 0;
+
+#ifdef _BIG_ENDIAN
+ FlipWaveHeader(&wFile->wh);
+#endif
+
+ /* write the header */
+ if (fwrite(&wFile->wh, sizeof(WAVE_HEADER), 1, wFile->file) != 1)
+ {
+ fclose(wFile->file);
+ free(wFile);
+ return NULL;
+ }
+
+#ifdef _BIG_ENDIAN
+ FlipWaveHeader(&wFile->wh);
+#endif
+
+ /* return the file handle */
+ return wFile;
+} /* end WaveFileCreate */
+
+/*----------------------------------------------------------------------------
+ * WaveFileWrite()
+ *----------------------------------------------------------------------------
+ * Purpose: Writes data to the wave file
+ *
+ * Inputs:
+ *
+ * Outputs:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_I32 WaveFileWrite (WAVE_FILE *wFile, void *buffer, EAS_I32 n)
+{
+ EAS_I32 count;
+
+ /* make sure we have an open file */
+ if (wFile == NULL)
+ {
+ return 0;
+ }
+
+#ifdef _BIG_ENDIAN
+ {
+ EAS_I32 i;
+ EAS_U16 *p;
+ p = buffer;
+ i = n >> 1;
+ while (i--)
+ FlipWord(p++);
+ }
+#endif
+
+ /* write the data */
+ count = (EAS_I32) fwrite(buffer, 1, (size_t) n, wFile->file);
+
+ /* add the number of bytes written */
+ wFile->wh.nRiffSize += (EAS_U32) count;
+ wFile->wh.nDataSize += (EAS_U32) count;
+
+ /* return the count of bytes written */
+ return count;
+} /* end WriteWaveHeader */
+
+/*----------------------------------------------------------------------------
+ * WaveFileClose()
+ *----------------------------------------------------------------------------
+ * Purpose: Opens a wave file for writing and writes the header
+ *
+ * Inputs:
+ *
+ * Outputs:
+ *
+ *----------------------------------------------------------------------------
+*/
+
+EAS_BOOL WaveFileClose (WAVE_FILE *wFile)
+{
+ EAS_I32 count = 1;
+
+ /* return to beginning of file and write the header */
+ if (wFile->write)
+ {
+ if (fseek(wFile->file, 0L, SEEK_SET) == 0)
+ {
+
+#ifdef _BIG_ENDIAN
+ FlipWaveHeader(&wFile->wh);
+#endif
+ count = (EAS_I32) fwrite(&wFile->wh, sizeof(WAVE_HEADER), 1, wFile->file);
+#ifdef _BIG_ENDIAN
+ FlipWaveHeader(&wFile->wh);
+#endif
+ }
+ }
+
+ /* close the file */
+ if (fclose(wFile->file) != 0)
+ count = 0;
+
+ /* free the memory */
+ free(wFile);
+
+ /* return the file handle */
+ return (count == 1 ? EAS_TRUE : EAS_FALSE);
+} /* end WaveFileClose */
+
+#ifdef _WAVE_FILE_READ
+#ifdef _BIG_ENDIAN
+#error "WaveFileOpen not currently supported on big-endian processors"
+#endif
+/*----------------------------------------------------------------------------
+ * WaveFileOpen()
+ *----------------------------------------------------------------------------
+ * Purpose: Opens a wave file for reading and reads the header
+ *
+ * Inputs:
+ *
+ * Outputs:
+ *
+ *----------------------------------------------------------------------------
+*/
+
+WAVE_FILE *WaveFileOpen (const char *filename)
+{
+ WAVE_FILE *wFile;
+ struct
+ {
+ EAS_U32 tag;
+ EAS_U32 size;
+ } chunk;
+ EAS_U32 tag;
+ EAS_I32 startChunkPos;
+ EAS_INT state;
+ EAS_BOOL done;
+
+ /* allocate memory */
+ wFile = malloc(sizeof(WAVE_FILE));
+ if (!wFile)
+ return NULL;
+
+ /* open the file */
+ wFile->write = EAS_FALSE;
+ wFile->file = fopen(filename,"rb");
+ if (!wFile->file)
+ {
+ free(wFile);
+ return NULL;
+ }
+
+ /* make lint happy */
+ chunk.tag = chunk.size = 0;
+ startChunkPos = 0;
+
+ /* read the RIFF tag and file size */
+ state = 0;
+ done = EAS_FALSE;
+ while (!done)
+ {
+
+ switch(state)
+ {
+ /* read the RIFF tag */
+ case 0:
+ if (fread(&chunk, sizeof(chunk), 1, wFile->file) != 1)
+ done = EAS_TRUE;
+ else
+ {
+ if (chunk.tag != riffTag)
+ done = EAS_TRUE;
+ else
+ state++;
+ }
+ break;
+
+ /* read the WAVE tag */
+ case 1:
+ if (fread(&tag, sizeof(tag), 1, wFile->file) != 1)
+ done = EAS_TRUE;
+ else
+ {
+ if (tag != waveTag)
+ done = EAS_TRUE;
+ else
+ state++;
+ }
+ break;
+
+ /* looking for fmt chunk */
+ case 2:
+ if (fread(&chunk, sizeof(chunk), 1, wFile->file) != 1)
+ done = EAS_TRUE;
+ else
+ {
+ startChunkPos = ftell(wFile->file);
+
+ /* not fmt tag, skip it */
+ if (chunk.tag != fmtTag)
+ fseek(wFile->file, startChunkPos + (EAS_I32) chunk.size, SEEK_SET);
+ else
+ state++;
+ }
+ break;
+
+ /* read fmt chunk */
+ case 3:
+ if (fread(&wFile->wh.fc, sizeof(FMT_CHUNK), 1, wFile->file) != 1)
+ done = EAS_TRUE;
+ else
+ {
+ fseek(wFile->file, startChunkPos + (EAS_I32) chunk.size, SEEK_SET);
+ state++;
+ }
+ break;
+
+ /* looking for data chunk */
+ case 4:
+ if (fread(&chunk, sizeof(chunk), 1, wFile->file) != 1)
+ done = EAS_TRUE;
+ else
+ {
+ startChunkPos = ftell(wFile->file);
+
+ /* not data tag, skip it */
+ if (chunk.tag != dataTag)
+ fseek(wFile->file, startChunkPos + (EAS_I32) chunk.size, SEEK_SET);
+ else
+ {
+ wFile->dataSize = chunk.size;
+ state++;
+ done = EAS_TRUE;
+ }
+ }
+ break;
+
+ default:
+ done = EAS_TRUE;
+ break;
+ }
+ }
+
+ /* if not final state, an error occurred */
+ if (state != 5)
+ {
+ fclose(wFile->file);
+ free(wFile);
+ return NULL;
+ }
+
+ /* return the file handle */
+ return wFile;
+} /* end WaveFileOpen */
+#endif
+
+
+
diff --git a/arm-hybrid-22k/host_src/eas_wave.h b/arm-hybrid-22k/host_src/eas_wave.h
index ca388f5..968782f 100644
--- a/arm-hybrid-22k/host_src/eas_wave.h
+++ b/arm-hybrid-22k/host_src/eas_wave.h
@@ -1,14 +1,14 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_wave.h
- *
- * Contents and purpose:
- * Writes output to a .WAV file
- *
- * DO NOT MODIFY THIS FILE!
- *
- * Copyright Sonic Network Inc. 2005
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_wave.h
+ *
+ * Contents and purpose:
+ * Writes output to a .WAV file
+ *
+ * DO NOT MODIFY THIS FILE!
+ *
+ * Copyright Sonic Network Inc. 2005
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,54 +21,54 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 82 $
- * $Date: 2006-07-10 11:45:19 -0700 (Mon, 10 Jul 2006) $
- *----------------------------------------------------------------------------
-*/
-
-#include "eas_types.h"
-
-/* sentinel */
-#ifndef _EAS_WAVE_H
-#define _EAS_WAVE_H
-
-/* .WAV file format chunk */
-typedef struct {
- EAS_U16 wFormatTag;
- EAS_U16 nChannels;
- EAS_U32 nSamplesPerSec;
- EAS_U32 nAvgBytesPerSec;
- EAS_U16 nBlockAlign;
- EAS_U16 wBitsPerSample;
-} FMT_CHUNK;
-
-/* .WAV file header */
-typedef struct {
- EAS_U32 nRiffTag;
- EAS_U32 nRiffSize;
- EAS_U32 nWaveTag;
- EAS_U32 nFmtTag;
- EAS_U32 nFmtSize;
- FMT_CHUNK fc;
- EAS_U32 nDataTag;
- EAS_U32 nDataSize;
-} WAVE_HEADER;
-
-typedef struct {
- WAVE_HEADER wh;
- FILE *file;
- EAS_BOOL write;
- EAS_U32 dataSize;
-} WAVE_FILE;
-
-WAVE_FILE *WaveFileCreate (const char *filename, EAS_I32 nChannels, EAS_I32 nSamplesPerSec, EAS_I32 wBitsPerSample);
-EAS_I32 WaveFileWrite (WAVE_FILE *wFile, void *buffer, EAS_I32 n);
-EAS_BOOL WaveFileClose (WAVE_FILE *wFile);
-WAVE_FILE *WaveFileOpen (const char *filename);
-
-#endif /* end #ifndef _EAS_WAVE_H */
-
-
-
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 82 $
+ * $Date: 2006-07-10 11:45:19 -0700 (Mon, 10 Jul 2006) $
+ *----------------------------------------------------------------------------
+*/
+
+#include "eas_types.h"
+
+/* sentinel */
+#ifndef _EAS_WAVE_H
+#define _EAS_WAVE_H
+
+/* .WAV file format chunk */
+typedef struct {
+ EAS_U16 wFormatTag;
+ EAS_U16 nChannels;
+ EAS_U32 nSamplesPerSec;
+ EAS_U32 nAvgBytesPerSec;
+ EAS_U16 nBlockAlign;
+ EAS_U16 wBitsPerSample;
+} FMT_CHUNK;
+
+/* .WAV file header */
+typedef struct {
+ EAS_U32 nRiffTag;
+ EAS_U32 nRiffSize;
+ EAS_U32 nWaveTag;
+ EAS_U32 nFmtTag;
+ EAS_U32 nFmtSize;
+ FMT_CHUNK fc;
+ EAS_U32 nDataTag;
+ EAS_U32 nDataSize;
+} WAVE_HEADER;
+
+typedef struct {
+ WAVE_HEADER wh;
+ FILE *file;
+ EAS_BOOL write;
+ EAS_U32 dataSize;
+} WAVE_FILE;
+
+WAVE_FILE *WaveFileCreate (const char *filename, EAS_I32 nChannels, EAS_I32 nSamplesPerSec, EAS_I32 wBitsPerSample);
+EAS_I32 WaveFileWrite (WAVE_FILE *wFile, void *buffer, EAS_I32 n);
+EAS_BOOL WaveFileClose (WAVE_FILE *wFile);
+WAVE_FILE *WaveFileOpen (const char *filename);
+
+#endif /* end #ifndef _EAS_WAVE_H */
+
+
+
diff --git a/arm-hybrid-22k/lib_src/ARM_synth_constants_gnu.inc b/arm-hybrid-22k/lib_src/ARM_synth_constants_gnu.inc
index b4cd29a..c0f8df3 100644
--- a/arm-hybrid-22k/lib_src/ARM_synth_constants_gnu.inc
+++ b/arm-hybrid-22k/lib_src/ARM_synth_constants_gnu.inc
@@ -1,153 +1,153 @@
-@***********************************************************
-@ File: ARM_synth_constants.inc
-@ Processor: ARM
-@ Description: Contains constants and defines, most of which
-@ are mirrored in synth.h
-@
-@ Copyright Sonic Network Inc. 2004
-@****************************************************************
-@ Revision Control:
-@ $Revision: 741 $
-@ $Date: 2007-06-22 16:39:21 -0700 (Fri, 22 Jun 2007) $
-@****************************************************************
-
-
- .ifdef SAMPLE_RATE_8000
- .equ SYNTH_UPDATE_PERIOD_IN_BITS, 5
- .equ BUFFER_SIZE_IN_MONO_SAMPLES, 32
- .endif
-
- .ifdef SAMPLE_RATE_16000
- .equ SYNTH_UPDATE_PERIOD_IN_BITS, 6
- .equ BUFFER_SIZE_IN_MONO_SAMPLES, 64
- .endif
-
- .ifdef SAMPLE_RATE_20000
- .equ SYNTH_UPDATE_PERIOD_IN_BITS, 7
- .equ BUFFER_SIZE_IN_MONO_SAMPLES, 128
- .endif
-
- .ifdef SAMPLE_RATE_22050
- .equ SYNTH_UPDATE_PERIOD_IN_BITS, 7
- .equ BUFFER_SIZE_IN_MONO_SAMPLES, 128
- .endif
-
- .ifdef SAMPLE_RATE_24000
- .equ SYNTH_UPDATE_PERIOD_IN_BITS, 7
- .equ BUFFER_SIZE_IN_MONO_SAMPLES, 128
- .endif
-
- .ifdef SAMPLE_RATE_32000
- .equ SYNTH_UPDATE_PERIOD_IN_BITS, 7
- .equ BUFFER_SIZE_IN_MONO_SAMPLES, 128
- .endif
-
- .ifdef SAMPLE_RATE_44100
- .equ SYNTH_UPDATE_PERIOD_IN_BITS, 8
- .equ BUFFER_SIZE_IN_MONO_SAMPLES, 256
- .endif
-
- .ifdef SAMPLE_RATE_48000
- .equ SYNTH_UPDATE_PERIOD_IN_BITS, 8
- .equ BUFFER_SIZE_IN_MONO_SAMPLES, 256
- .endif
-
-
-@ if the OUTPUT PCM sample is 16-bits, then when using indexed addressing,
-@ the next sample is this many bytes away
- .equ NEXT_OUTPUT_PCM, 2
-
-@****************************************************************************
-@/* macros for fractional phase accumulator */
- .equ NUM_PHASE_FRAC_BITS, 15
-
- .equ PHASE_FRAC_MASK, 0x7FFF
-
-@ shift for phase accumulator when fraction carries over
- .ifdef SAMPLES_8_BIT
- .equ NEXT_INPUT_PCM_SHIFT, 0
- .endif
-
- .ifdef SAMPLES_16_BIT
- .equ NEXT_INPUT_PCM_SHIFT, 1
- .endif
-
-@****************************************************************************
- .equ NUM_MIXER_GUARD_BITS, 4
-
-@****************************************************************************
-@/* Envelope 1 (EG1) calculation macros */
- .equ NUM_EG1_FRAC_BITS, 15
-
-@****************************************************************************
-
- .equ NUM_ENHANCER_FILTER_COEF_FRAC_BITS, 5
-
-@****************************************************************************
-
-@
-@ I've temporarily given up on the idea of getting ADS/RV and gcc to
-@ handle a struct in a compatible fashion. Switching to old fashion EQU
-@
-
- .if FILTER_ENABLED
-@**************************************
-@ typedef struct s_filter_tag
- .equ m_z1, 0
- .equ m_z2, 2
- .endif
-
-@**************************************
-@ typedef struct s_wt_frame_tag
- .equ m_gainTarget, 0
- .equ m_phaseIncrement, 4
-
- .if FILTER_ENABLED
- .equ m_k, 8
- .equ m_b1, 12
- .equ m_b2, 16
- .equ m_pAudioBuffer, 20
- .equ m_pMixBuffer, 24
- .equ m_numSamples, 28
- .equ m_prevGain, 32
- .else
- .equ m_pAudioBuffer, 8
- .equ m_pMixBuffer, 12
- .equ m_numSamples, 16
- .equ m_prevGain, 20
- .endif
-
-
-@**************************************
-@ typedef struct s_wt_voice_tag
- .equ m_pLoopEnd, 0 @ /* points to last PCM sample (not 1 beyond last) */
- .equ m_pLoopStart, 4 @ /* points to first sample at start of loop */
- .equ m_pPhaseAccum, 8 @ /* points to first sample at start of loop */
- .equ m_phaseFrac, 12 @ /* points to first sample at start of loop */
-
- .if STEREO_OUTPUT
- .equ m_gainLeft, 16 @ /* current gain, left ch */
- .equ m_gainRight, 18 @ /* current gain, right ch */
- .endif
-
-
-@****************************************************************************
-@ enhancer
- .equ m_nEnhancerFeedForward1, 0
- .equ m_nEnhancerFeedback1, 1
- .equ m_nDriveCoef, 2
- .equ m_nEnhancerFeedback2, 3
- .equ m_nWet, 4
- .equ m_nDry, 5
-
- .equ m_zF0L, 6 @ filter 1 zero state var, left
- .equ m_zF1L, 8 @ filter 1 pole state var, left
- .equ m_zF2L, 10 @ filter 2 zero state var, left
- .equ m_zF0R, 12 @ filter 1 zero state var, right
- .equ m_zF1R, 14 @ filter 1 pole state var, right
- .equ m_zF2R, 16 @ filter 2 zero state var, right
-
-@****************************************************************************
-
-
-
+@***********************************************************
+@ File: ARM_synth_constants.inc
+@ Processor: ARM
+@ Description: Contains constants and defines, most of which
+@ are mirrored in synth.h
+@
+@ Copyright Sonic Network Inc. 2004
+@****************************************************************
+@ Revision Control:
+@ $Revision: 741 $
+@ $Date: 2007-06-22 16:39:21 -0700 (Fri, 22 Jun 2007) $
+@****************************************************************
+
+
+ .ifdef SAMPLE_RATE_8000
+ .equ SYNTH_UPDATE_PERIOD_IN_BITS, 5
+ .equ BUFFER_SIZE_IN_MONO_SAMPLES, 32
+ .endif
+
+ .ifdef SAMPLE_RATE_16000
+ .equ SYNTH_UPDATE_PERIOD_IN_BITS, 6
+ .equ BUFFER_SIZE_IN_MONO_SAMPLES, 64
+ .endif
+
+ .ifdef SAMPLE_RATE_20000
+ .equ SYNTH_UPDATE_PERIOD_IN_BITS, 7
+ .equ BUFFER_SIZE_IN_MONO_SAMPLES, 128
+ .endif
+
+ .ifdef SAMPLE_RATE_22050
+ .equ SYNTH_UPDATE_PERIOD_IN_BITS, 7
+ .equ BUFFER_SIZE_IN_MONO_SAMPLES, 128
+ .endif
+
+ .ifdef SAMPLE_RATE_24000
+ .equ SYNTH_UPDATE_PERIOD_IN_BITS, 7
+ .equ BUFFER_SIZE_IN_MONO_SAMPLES, 128
+ .endif
+
+ .ifdef SAMPLE_RATE_32000
+ .equ SYNTH_UPDATE_PERIOD_IN_BITS, 7
+ .equ BUFFER_SIZE_IN_MONO_SAMPLES, 128
+ .endif
+
+ .ifdef SAMPLE_RATE_44100
+ .equ SYNTH_UPDATE_PERIOD_IN_BITS, 8
+ .equ BUFFER_SIZE_IN_MONO_SAMPLES, 256
+ .endif
+
+ .ifdef SAMPLE_RATE_48000
+ .equ SYNTH_UPDATE_PERIOD_IN_BITS, 8
+ .equ BUFFER_SIZE_IN_MONO_SAMPLES, 256
+ .endif
+
+
+@ if the OUTPUT PCM sample is 16-bits, then when using indexed addressing,
+@ the next sample is this many bytes away
+ .equ NEXT_OUTPUT_PCM, 2
+
+@****************************************************************************
+@/* macros for fractional phase accumulator */
+ .equ NUM_PHASE_FRAC_BITS, 15
+
+ .equ PHASE_FRAC_MASK, 0x7FFF
+
+@ shift for phase accumulator when fraction carries over
+ .ifdef SAMPLES_8_BIT
+ .equ NEXT_INPUT_PCM_SHIFT, 0
+ .endif
+
+ .ifdef SAMPLES_16_BIT
+ .equ NEXT_INPUT_PCM_SHIFT, 1
+ .endif
+
+@****************************************************************************
+ .equ NUM_MIXER_GUARD_BITS, 4
+
+@****************************************************************************
+@/* Envelope 1 (EG1) calculation macros */
+ .equ NUM_EG1_FRAC_BITS, 15
+
+@****************************************************************************
+
+ .equ NUM_ENHANCER_FILTER_COEF_FRAC_BITS, 5
+
+@****************************************************************************
+
+@
+@ I've temporarily given up on the idea of getting ADS/RV and gcc to
+@ handle a struct in a compatible fashion. Switching to old fashion EQU
+@
+
+ .if FILTER_ENABLED
+@**************************************
+@ typedef struct s_filter_tag
+ .equ m_z1, 0
+ .equ m_z2, 2
+ .endif
+
+@**************************************
+@ typedef struct s_wt_frame_tag
+ .equ m_gainTarget, 0
+ .equ m_phaseIncrement, 4
+
+ .if FILTER_ENABLED
+ .equ m_k, 8
+ .equ m_b1, 12
+ .equ m_b2, 16
+ .equ m_pAudioBuffer, 20
+ .equ m_pMixBuffer, 24
+ .equ m_numSamples, 28
+ .equ m_prevGain, 32
+ .else
+ .equ m_pAudioBuffer, 8
+ .equ m_pMixBuffer, 12
+ .equ m_numSamples, 16
+ .equ m_prevGain, 20
+ .endif
+
+
+@**************************************
+@ typedef struct s_wt_voice_tag
+ .equ m_pLoopEnd, 0 @ /* points to last PCM sample (not 1 beyond last) */
+ .equ m_pLoopStart, 4 @ /* points to first sample at start of loop */
+ .equ m_pPhaseAccum, 8 @ /* points to first sample at start of loop */
+ .equ m_phaseFrac, 12 @ /* points to first sample at start of loop */
+
+ .if STEREO_OUTPUT
+ .equ m_gainLeft, 16 @ /* current gain, left ch */
+ .equ m_gainRight, 18 @ /* current gain, right ch */
+ .endif
+
+
+@****************************************************************************
+@ enhancer
+ .equ m_nEnhancerFeedForward1, 0
+ .equ m_nEnhancerFeedback1, 1
+ .equ m_nDriveCoef, 2
+ .equ m_nEnhancerFeedback2, 3
+ .equ m_nWet, 4
+ .equ m_nDry, 5
+
+ .equ m_zF0L, 6 @ filter 1 zero state var, left
+ .equ m_zF1L, 8 @ filter 1 pole state var, left
+ .equ m_zF2L, 10 @ filter 2 zero state var, left
+ .equ m_zF0R, 12 @ filter 1 zero state var, right
+ .equ m_zF1R, 14 @ filter 1 pole state var, right
+ .equ m_zF2R, 16 @ filter 2 zero state var, right
+
+@****************************************************************************
+
+
+
diff --git a/arm-hybrid-22k/lib_src/eas_audioconst.h b/arm-hybrid-22k/lib_src/eas_audioconst.h
index 1cfa404..066148e 100644
--- a/arm-hybrid-22k/lib_src/eas_audioconst.h
+++ b/arm-hybrid-22k/lib_src/eas_audioconst.h
@@ -1,13 +1,13 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_audioconst.h
- *
- * Contents and purpose:
- * Defines audio constants related to the sample rate, bit size, etc.
- *
- *
- * Copyright Sonic Network Inc. 2005
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_audioconst.h
+ *
+ * Contents and purpose:
+ * Defines audio constants related to the sample rate, bit size, etc.
+ *
+ *
+ * Copyright Sonic Network Inc. 2005
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,78 +20,78 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 82 $
- * $Date: 2006-07-10 11:45:19 -0700 (Mon, 10 Jul 2006) $
- *----------------------------------------------------------------------------
-*/
-
-#ifndef _EAS_AUDIOCONST_H
-#define _EAS_AUDIOCONST_H
-
-/*----------------------------------------------------------------------------
- * These macros define the various characteristics of the defined sample rates
- *----------------------------------------------------------------------------
- * BUFFER_SIZE_IN_MONO_SAMPLES size of buffer in samples
- * _OUTPUT_SAMPLE_RATE compiled output sample rate
- * AUDIO_FRAME_LENGTH length of an audio frame in 256ths of a millisecond
- * SYNTH_UPDATE_PERIOD_IN_BITS length of an audio frame (2^x samples)
- *----------------------------------------------------------------------------
-*/
-
-#if defined (_SAMPLE_RATE_8000)
-#define BUFFER_SIZE_IN_MONO_SAMPLES 32
-#define _OUTPUT_SAMPLE_RATE 8000
-#define AUDIO_FRAME_LENGTH 1024
-#define SYNTH_UPDATE_PERIOD_IN_BITS 5
-
-#elif defined (_SAMPLE_RATE_16000)
-#define BUFFER_SIZE_IN_MONO_SAMPLES 64
-#define _OUTPUT_SAMPLE_RATE 16000
-#define AUDIO_FRAME_LENGTH 1024
-#define SYNTH_UPDATE_PERIOD_IN_BITS 6
-
-#elif defined (_SAMPLE_RATE_20000)
-#define BUFFER_SIZE_IN_MONO_SAMPLES 128
-#define _OUTPUT_SAMPLE_RATE 20000
-#define AUDIO_FRAME_LENGTH 1638
-#define SYNTH_UPDATE_PERIOD_IN_BITS 7
-
-#elif defined (_SAMPLE_RATE_22050)
-#define BUFFER_SIZE_IN_MONO_SAMPLES 128
-#define _OUTPUT_SAMPLE_RATE 22050
-#define AUDIO_FRAME_LENGTH 1486
-#define SYNTH_UPDATE_PERIOD_IN_BITS 7
-
-#elif defined (_SAMPLE_RATE_24000)
-#define BUFFER_SIZE_IN_MONO_SAMPLES 128
-#define _OUTPUT_SAMPLE_RATE 24000
-#define AUDIO_FRAME_LENGTH 1365
-#define SYNTH_UPDATE_PERIOD_IN_BITS 7
-
-#elif defined (_SAMPLE_RATE_32000)
-#define BUFFER_SIZE_IN_MONO_SAMPLES 128
-#define _OUTPUT_SAMPLE_RATE 32000
-#define AUDIO_FRAME_LENGTH 1024
-#define SYNTH_UPDATE_PERIOD_IN_BITS 7
-
-#elif defined (_SAMPLE_RATE_44100)
-#define BUFFER_SIZE_IN_MONO_SAMPLES 256
-#define _OUTPUT_SAMPLE_RATE 44100
-#define AUDIO_FRAME_LENGTH 1486
-#define SYNTH_UPDATE_PERIOD_IN_BITS 8
-
-#elif defined (_SAMPLE_RATE_48000)
-#define BUFFER_SIZE_IN_MONO_SAMPLES 256
-#define _OUTPUT_SAMPLE_RATE 48000
-#define AUDIO_FRAME_LENGTH 1365
-#define SYNTH_UPDATE_PERIOD_IN_BITS 8
-
-#else
-#error "_SAMPLE_RATE_XXXXX must be defined to valid rate"
-#endif
-
-#endif /* #ifndef _EAS_AUDIOCONST_H */
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 82 $
+ * $Date: 2006-07-10 11:45:19 -0700 (Mon, 10 Jul 2006) $
+ *----------------------------------------------------------------------------
+*/
+
+#ifndef _EAS_AUDIOCONST_H
+#define _EAS_AUDIOCONST_H
+
+/*----------------------------------------------------------------------------
+ * These macros define the various characteristics of the defined sample rates
+ *----------------------------------------------------------------------------
+ * BUFFER_SIZE_IN_MONO_SAMPLES size of buffer in samples
+ * _OUTPUT_SAMPLE_RATE compiled output sample rate
+ * AUDIO_FRAME_LENGTH length of an audio frame in 256ths of a millisecond
+ * SYNTH_UPDATE_PERIOD_IN_BITS length of an audio frame (2^x samples)
+ *----------------------------------------------------------------------------
+*/
+
+#if defined (_SAMPLE_RATE_8000)
+#define BUFFER_SIZE_IN_MONO_SAMPLES 32
+#define _OUTPUT_SAMPLE_RATE 8000
+#define AUDIO_FRAME_LENGTH 1024
+#define SYNTH_UPDATE_PERIOD_IN_BITS 5
+
+#elif defined (_SAMPLE_RATE_16000)
+#define BUFFER_SIZE_IN_MONO_SAMPLES 64
+#define _OUTPUT_SAMPLE_RATE 16000
+#define AUDIO_FRAME_LENGTH 1024
+#define SYNTH_UPDATE_PERIOD_IN_BITS 6
+
+#elif defined (_SAMPLE_RATE_20000)
+#define BUFFER_SIZE_IN_MONO_SAMPLES 128
+#define _OUTPUT_SAMPLE_RATE 20000
+#define AUDIO_FRAME_LENGTH 1638
+#define SYNTH_UPDATE_PERIOD_IN_BITS 7
+
+#elif defined (_SAMPLE_RATE_22050)
+#define BUFFER_SIZE_IN_MONO_SAMPLES 128
+#define _OUTPUT_SAMPLE_RATE 22050
+#define AUDIO_FRAME_LENGTH 1486
+#define SYNTH_UPDATE_PERIOD_IN_BITS 7
+
+#elif defined (_SAMPLE_RATE_24000)
+#define BUFFER_SIZE_IN_MONO_SAMPLES 128
+#define _OUTPUT_SAMPLE_RATE 24000
+#define AUDIO_FRAME_LENGTH 1365
+#define SYNTH_UPDATE_PERIOD_IN_BITS 7
+
+#elif defined (_SAMPLE_RATE_32000)
+#define BUFFER_SIZE_IN_MONO_SAMPLES 128
+#define _OUTPUT_SAMPLE_RATE 32000
+#define AUDIO_FRAME_LENGTH 1024
+#define SYNTH_UPDATE_PERIOD_IN_BITS 7
+
+#elif defined (_SAMPLE_RATE_44100)
+#define BUFFER_SIZE_IN_MONO_SAMPLES 256
+#define _OUTPUT_SAMPLE_RATE 44100
+#define AUDIO_FRAME_LENGTH 1486
+#define SYNTH_UPDATE_PERIOD_IN_BITS 8
+
+#elif defined (_SAMPLE_RATE_48000)
+#define BUFFER_SIZE_IN_MONO_SAMPLES 256
+#define _OUTPUT_SAMPLE_RATE 48000
+#define AUDIO_FRAME_LENGTH 1365
+#define SYNTH_UPDATE_PERIOD_IN_BITS 8
+
+#else
+#error "_SAMPLE_RATE_XXXXX must be defined to valid rate"
+#endif
+
+#endif /* #ifndef _EAS_AUDIOCONST_H */
+
diff --git a/arm-hybrid-22k/lib_src/eas_chorus.c b/arm-hybrid-22k/lib_src/eas_chorus.c
index bc42237..4a2c8d0 100644
--- a/arm-hybrid-22k/lib_src/eas_chorus.c
+++ b/arm-hybrid-22k/lib_src/eas_chorus.c
@@ -1,13 +1,13 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_chorus.c
- *
- * Contents and purpose:
- * Contains the implementation of the Chorus effect.
- *
- *
- * Copyright Sonic Network Inc. 2006
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_chorus.c
+ *
+ * Contents and purpose:
+ * Contains the implementation of the Chorus effect.
+ *
+ *
+ * Copyright Sonic Network Inc. 2006
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,585 +20,585 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 499 $
- * $Date: 2006-12-11 16:07:20 -0800 (Mon, 11 Dec 2006) $
- *----------------------------------------------------------------------------
-*/
-
-#include "eas_data.h"
-#include "eas_effects.h"
-#include "eas_math.h"
-#include "eas_chorusdata.h"
-#include "eas_chorus.h"
-#include "eas_config.h"
-#include "eas_host.h"
-#include "eas_report.h"
-
-/* prototypes for effects interface */
-static EAS_RESULT ChorusInit (EAS_DATA_HANDLE pEASData, EAS_VOID_PTR *pInstData);
-static void ChorusProcess (EAS_VOID_PTR pInstData, EAS_PCM *pSrc, EAS_PCM *pDst, EAS_I32 numSamples);
-static EAS_RESULT ChorusShutdown (EAS_DATA_HANDLE pEASData, EAS_VOID_PTR pInstData);
-static EAS_RESULT ChorusGetParam (EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue);
-static EAS_RESULT ChorusSetParam (EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value);
-
-/* common effects interface for configuration module */
-const S_EFFECTS_INTERFACE EAS_Chorus =
-{
- ChorusInit,
- ChorusProcess,
- ChorusShutdown,
- ChorusGetParam,
- ChorusSetParam
-};
-
-
-
-//LFO shape table used by the chorus, larger table would sound better
-//this is a sine wave, where 32767 = 1.0
-static const EAS_I16 EAS_chorusShape[CHORUS_SHAPE_SIZE] = {
- 0, 1608, 3212, 4808, 6393, 7962, 9512, 11309, 12539, 14010, 15446, 16846, 18204, 19519, 20787, 22005, 23170,
- 24279, 25329, 26319, 27245, 28105, 28898, 29621, 30273, 30852, 31356, 31785, 32137, 32412, 32609, 32728,
- 32767, 32728, 32609, 32412, 32137, 31785, 31356, 30852, 30273, 29621, 28898, 28105, 27245, 26319, 25329,
- 24279, 23170, 22005, 20787, 19519, 18204, 16846, 15446, 14010, 12539, 11039, 9512, 7962, 6393, 4808, 3212,
- 1608, 0, -1608, -3212, -4808, -6393, -7962, -9512, -11309, -12539, -14010, -15446, -16846, -18204, -19519,
- -20787, -22005, -23170, -24279, -25329, -26319, -27245, -28105, -28898, -29621, -30273, -30852, -31356, -31785,
- -32137, -32412, -32609, -32728, -32767, -32728, -32609, -32412, -32137, -31785, -31356, -30852, -30273, -29621,
- -28898, -28105, -27245, -26319, -25329, -24279, -23170, -22005, -20787, -19519, -18204, -16846, -15446, -14010,
- -12539, -11039, -9512, -7962, -6393, -4808, -3212, -1608
-};
-
-/*----------------------------------------------------------------------------
- * InitializeChorus()
- *----------------------------------------------------------------------------
- * Purpose: Initializes chorus parameters
- *
- *
- * Inputs:
- *
- * Outputs:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT ChorusInit (EAS_DATA_HANDLE pEASData, EAS_VOID_PTR *pInstData)
-{
- S_CHORUS_OBJECT *pChorusData;
- S_CHORUS_PRESET *pPreset;
- EAS_I32 index;
-
- /* check Configuration Module for data allocation */
- if (pEASData->staticMemoryModel)
- pChorusData = EAS_CMEnumFXData(EAS_MODULE_CHORUS);
-
- /* allocate dynamic memory */
- else
- pChorusData = EAS_HWMalloc(pEASData->hwInstData, sizeof(S_CHORUS_OBJECT));
-
- if (pChorusData == NULL)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_FATAL, "Failed to allocate Chorus memory\n"); */ }
- return EAS_ERROR_MALLOC_FAILED;
- }
-
- /* clear the structure */
- EAS_HWMemSet(pChorusData, 0, sizeof(S_CHORUS_OBJECT));
-
- ChorusReadInPresets(pChorusData);
-
- /* set some default values */
- pChorusData->bypass = EAS_CHORUS_BYPASS_DEFAULT;
- pChorusData->preset = EAS_CHORUS_PRESET_DEFAULT;
- pChorusData->m_nLevel = EAS_CHORUS_LEVEL_DEFAULT;
- pChorusData->m_nRate = EAS_CHORUS_RATE_DEFAULT;
- pChorusData->m_nDepth = EAS_CHORUS_DEPTH_DEFAULT;
-
- //chorus rate and depth need some massaging from preset value (which is sample rate independent)
-
- //convert rate from steps of .05 Hz to value which can be used as phase increment,
- //with current CHORUS_SHAPE_SIZE and rate limits, this fits into 16 bits
- //want to compute ((shapeSize * 65536) * (storedRate/20))/sampleRate;
- //computing it as below allows rate steps to be evenly spaced
- //uses 32 bit divide, but only once when new value is selected
- pChorusData->m_nRate = (EAS_I16)
- ((((EAS_I32)CHORUS_SHAPE_SIZE<<16)/(20*(EAS_I32)_OUTPUT_SAMPLE_RATE)) * pChorusData->m_nRate);
-
- //convert depth from steps of .05 ms, to samples, with 16 bit whole part, discard fraction
- //want to compute ((depth * sampleRate)/20000)
- //use the following approximation since 105/32 is roughly 65536/20000
- /*lint -e{704} use shift for performance */
- pChorusData->m_nDepth = (EAS_I16)
- (((((EAS_I32)pChorusData->m_nDepth * _OUTPUT_SAMPLE_RATE)>>5) * 105) >> 16);
-
- pChorusData->m_nLevel = pChorusData->m_nLevel;
-
- //zero delay memory for chorus
- for (index = CHORUS_L_SIZE - 1; index >= 0; index--)
- {
- pChorusData->chorusDelayL[index] = 0;
- }
- for (index = CHORUS_R_SIZE - 1; index >= 0; index--)
- {
- pChorusData->chorusDelayR[index] = 0;
- }
-
- //init delay line index, these are used to implement circular delay buffer
- pChorusData->chorusIndexL = 0;
- pChorusData->chorusIndexR = 0;
-
- //init LFO phase
- //16 bit whole part, 16 bit fraction
- pChorusData->lfoLPhase = 0;
- pChorusData->lfoRPhase = (CHORUS_SHAPE_SIZE << 16) >> 2; // 1/4 of total, i.e. 90 degrees out of phase;
-
- //init chorus delay position
- //right now chorus delay is a compile-time value, as is sample rate
- pChorusData->chorusTapPosition = (EAS_I16)((CHORUS_DELAY_MS * _OUTPUT_SAMPLE_RATE)/1000);
-
- //now copy from the new preset into Chorus
- pPreset = &pChorusData->m_sPreset.m_sPreset[pChorusData->m_nNextChorus];
-
- pChorusData->m_nLevel = pPreset->m_nLevel;
- pChorusData->m_nRate = pPreset->m_nRate;
- pChorusData->m_nDepth = pPreset->m_nDepth;
-
- pChorusData->m_nRate = (EAS_I16)
- ((((EAS_I32)CHORUS_SHAPE_SIZE<<16)/(20*(EAS_I32)_OUTPUT_SAMPLE_RATE)) * pChorusData->m_nRate);
-
- /*lint -e{704} use shift for performance */
- pChorusData->m_nDepth = (EAS_I16)
- (((((EAS_I32)pChorusData->m_nDepth * _OUTPUT_SAMPLE_RATE)>>5) * 105) >> 16);
-
- *pInstData = pChorusData;
-
- return EAS_SUCCESS;
-} /* end ChorusInit */
-
-/*----------------------------------------------------------------------------
- * WeightedTap()
- *----------------------------------------------------------------------------
- * Purpose: Does fractional array look-up using linear interpolation
- *
- * first convert indexDesired to actual desired index by taking into account indexReference
- * then do linear interpolation between two actual samples using fractional part
- *
- * Inputs:
- * array: pointer to array of signed 16 bit values, typically either PCM data or control data
- * indexReference: the circular buffer relative offset
- * indexDesired: the fractional index we are looking up (16 bits index + 16 bits fraction)
- * indexLimit: the total size of the array, used to compute buffer wrap
- *
- * Outputs:
- * Value from the input array, linearly interpolated between two actual data values
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_I16 WeightedTap(const EAS_I16 *array, EAS_I16 indexReference, EAS_I32 indexDesired, EAS_I16 indexLimit)
-{
- EAS_I16 index;
- EAS_I16 fraction;
- EAS_I16 val1;
- EAS_I16 val2;
-
- //separate indexDesired into whole and fractional parts
- /*lint -e{704} use shift for performance */
- index = (EAS_I16)(indexDesired >> 16);
- /*lint -e{704} use shift for performance */
- fraction = (EAS_I16)((indexDesired>>1) & 0x07FFF); //just use 15 bits of fractional part
-
- //adjust whole part by indexReference
- index = indexReference - index;
- //make sure we stay within array bounds, this implements circular buffer
- while (index < 0)
- {
- index += indexLimit;
- }
-
- //get two adjacent values from the array
- val1 = array[index];
-
- //handle special case when index == 0, else typical case
- if (index == 0)
- {
- val2 = array[indexLimit-1]; //get last value from array
- }
- else
- {
- val2 = array[index-1]; //get previous value from array
- }
-
- //compute linear interpolation as (val1 + ((val2-val1)*fraction))
- return(val1 + (EAS_I16)MULT_EG1_EG1(val2-val1,fraction));
-}
-
-/*----------------------------------------------------------------------------
- * ChorusProcess()
- *----------------------------------------------------------------------------
- * Purpose: compute the chorus on the input buffer, and mix into output buffer
- *
- *
- * Inputs:
- * src: pointer to input buffer of PCM values to be processed
- * dst: pointer to output buffer of PCM values we are to sume the result with
- * bufSize: the number of sample frames (i.e. stereo samples) in the buffer
- *
- * Outputs:
- * None
- *
- *----------------------------------------------------------------------------
-*/
-//compute the chorus, and mix into output buffer
-static void ChorusProcess (EAS_VOID_PTR pInstData, EAS_PCM *pSrc, EAS_PCM *pDst, EAS_I32 numSamples)
-{
- EAS_I32 ix;
- EAS_I32 nChannelNumber;
- EAS_I16 lfoValueLeft;
- EAS_I16 lfoValueRight;
- EAS_I32 positionOffsetL;
- EAS_I32 positionOffsetR;
- EAS_PCM tapL;
- EAS_PCM tapR;
- EAS_I32 tempValue;
- EAS_PCM nInputSample;
- EAS_I32 nOutputSample;
- EAS_PCM *pIn;
- EAS_PCM *pOut;
-
- S_CHORUS_OBJECT *pChorusData;
-
- pChorusData = (S_CHORUS_OBJECT*) pInstData;
-
- //if the chorus is disabled or turned all the way down
- if (pChorusData->bypass == EAS_TRUE || pChorusData->m_nLevel == 0)
- {
- if (pSrc != pDst)
- EAS_HWMemCpy(pSrc, pDst, numSamples * NUM_OUTPUT_CHANNELS * (EAS_I32) sizeof(EAS_PCM));
- return;
- }
-
- if (pChorusData->m_nNextChorus != pChorusData->m_nCurrentChorus)
- {
- ChorusUpdate(pChorusData);
- }
-
- for (nChannelNumber = 0; nChannelNumber < NUM_OUTPUT_CHANNELS; nChannelNumber++)
- {
-
- pIn = pSrc + nChannelNumber;
- pOut = pDst + nChannelNumber;
-
- if(nChannelNumber==0)
- {
- for (ix = 0; ix < numSamples; ix++)
- {
- nInputSample = *pIn;
- pIn += NUM_OUTPUT_CHANNELS;
-
- //feed input into chorus delay line
- pChorusData->chorusDelayL[pChorusData->chorusIndexL] = nInputSample;
-
- //compute chorus lfo value using phase as fractional index into chorus shape table
- //resulting value is between -1.0 and 1.0, expressed as signed 16 bit number
- lfoValueLeft = WeightedTap(EAS_chorusShape, 0, pChorusData->lfoLPhase, CHORUS_SHAPE_SIZE);
-
- //scale chorus depth by lfo value to get relative fractional sample index
- //index is expressed as 32 bit number with 16 bit fractional part
- /*lint -e{703} use shift for performance */
- positionOffsetL = pChorusData->m_nDepth * (((EAS_I32)lfoValueLeft) << 1);
-
- //add fixed chorus delay to get actual fractional sample index
- positionOffsetL += ((EAS_I32)pChorusData->chorusTapPosition) << 16;
-
- //get tap value from chorus delay using fractional sample index
- tapL = WeightedTap(pChorusData->chorusDelayL, pChorusData->chorusIndexL, positionOffsetL, CHORUS_L_SIZE);
-
- //scale by chorus level, then sum with input buffer contents and saturate
- tempValue = MULT_EG1_EG1(tapL, pChorusData->m_nLevel);
- nOutputSample = SATURATE(tempValue + nInputSample);
-
- *pOut = (EAS_I16)SATURATE(nOutputSample);
- pOut += NUM_OUTPUT_CHANNELS;
-
-
- //increment chorus delay index and make it wrap as needed
- //this implements circular buffer
- if ((pChorusData->chorusIndexL+=1) >= CHORUS_L_SIZE)
- pChorusData->chorusIndexL = 0;
-
- //increment fractional lfo phase, and make it wrap as needed
- pChorusData->lfoLPhase += pChorusData->m_nRate;
- while (pChorusData->lfoLPhase >= (CHORUS_SHAPE_SIZE<<16))
- {
- pChorusData->lfoLPhase -= (CHORUS_SHAPE_SIZE<<16);
- }
- }
- }
- else
- {
- for (ix = 0; ix < numSamples; ix++)
- {
- nInputSample = *pIn;
- pIn += NUM_OUTPUT_CHANNELS;
-
- //feed input into chorus delay line
- pChorusData->chorusDelayR[pChorusData->chorusIndexR] = nInputSample;
-
- //compute chorus lfo value using phase as fractional index into chorus shape table
- //resulting value is between -1.0 and 1.0, expressed as signed 16 bit number
- lfoValueRight = WeightedTap(EAS_chorusShape, 0, pChorusData->lfoRPhase, CHORUS_SHAPE_SIZE);
-
- //scale chorus depth by lfo value to get relative fractional sample index
- //index is expressed as 32 bit number with 16 bit fractional part
- /*lint -e{703} use shift for performance */
- positionOffsetR = pChorusData->m_nDepth * (((EAS_I32)lfoValueRight) << 1);
-
- //add fixed chorus delay to get actual fractional sample index
- positionOffsetR += ((EAS_I32)pChorusData->chorusTapPosition) << 16;
-
- //get tap value from chorus delay using fractional sample index
- tapR = WeightedTap(pChorusData->chorusDelayR, pChorusData->chorusIndexR, positionOffsetR, CHORUS_R_SIZE);
-
- //scale by chorus level, then sum with output buffer contents and saturate
- tempValue = MULT_EG1_EG1(tapR, pChorusData->m_nLevel);
- nOutputSample = SATURATE(tempValue + nInputSample);
-
- *pOut = (EAS_I16)SATURATE(nOutputSample);
- pOut += NUM_OUTPUT_CHANNELS;
-
- //increment chorus delay index and make it wrap as needed
- //this implements circular buffer
- if ((pChorusData->chorusIndexR+=1) >= CHORUS_R_SIZE)
- pChorusData->chorusIndexR = 0;
-
- //increment fractional lfo phase, and make it wrap as needed
- pChorusData->lfoRPhase += pChorusData->m_nRate;
- while (pChorusData->lfoRPhase >= (CHORUS_SHAPE_SIZE<<16))
- {
- pChorusData->lfoRPhase -= (CHORUS_SHAPE_SIZE<<16);
- }
- }
- }
-
- }
-} /* end ChorusProcess */
-
-
-
-/*----------------------------------------------------------------------------
- * ChorusShutdown()
- *----------------------------------------------------------------------------
- * Purpose:
- * Initializes the Chorus effect.
- *
- * Inputs:
- * pInstData - handle to instance data
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT ChorusShutdown (EAS_DATA_HANDLE pEASData, EAS_VOID_PTR pInstData)
-{
- /* check Configuration Module for static memory allocation */
- if (!pEASData->staticMemoryModel)
- EAS_HWFree(pEASData->hwInstData, pInstData);
- return EAS_SUCCESS;
-} /* end ChorusShutdown */
-
-/*----------------------------------------------------------------------------
- * ChorusGetParam()
- *----------------------------------------------------------------------------
- * Purpose:
- * Get a Chorus parameter
- *
- * Inputs:
- * pInstData - handle to instance data
- * param - parameter index
- * *pValue - pointer to variable to hold retrieved value
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT ChorusGetParam (EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue)
-{
- S_CHORUS_OBJECT *p;
-
- p = (S_CHORUS_OBJECT*) pInstData;
-
- switch (param)
- {
- case EAS_PARAM_CHORUS_BYPASS:
- *pValue = (EAS_I32) p->bypass;
- break;
- case EAS_PARAM_CHORUS_PRESET:
- *pValue = (EAS_I8) p->m_nCurrentChorus;
- break;
- case EAS_PARAM_CHORUS_RATE:
- *pValue = (EAS_I32) p->m_nRate;
- break;
- case EAS_PARAM_CHORUS_DEPTH:
- *pValue = (EAS_I32) p->m_nDepth;
- break;
- case EAS_PARAM_CHORUS_LEVEL:
- *pValue = (EAS_I32) p->m_nLevel;
- break;
- default:
- return EAS_ERROR_INVALID_PARAMETER;
- }
- return EAS_SUCCESS;
-} /* end ChorusGetParam */
-
-
-/*----------------------------------------------------------------------------
- * ChorusSetParam()
- *----------------------------------------------------------------------------
- * Purpose:
- * Set a Chorus parameter
- *
- * Inputs:
- * pInstData - handle to instance data
- * param - parameter index
- * *pValue - new paramter value
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT ChorusSetParam (EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value)
-{
- S_CHORUS_OBJECT *p;
-
- p = (S_CHORUS_OBJECT*) pInstData;
-
- switch (param)
- {
- case EAS_PARAM_CHORUS_BYPASS:
- p->bypass = (EAS_BOOL) value;
- break;
- case EAS_PARAM_CHORUS_PRESET:
- if(value!=EAS_PARAM_CHORUS_PRESET1 && value!=EAS_PARAM_CHORUS_PRESET2 &&
- value!=EAS_PARAM_CHORUS_PRESET3 && value!=EAS_PARAM_CHORUS_PRESET4)
- return EAS_ERROR_INVALID_PARAMETER;
- p->m_nNextChorus = (EAS_I8)value;
- break;
- case EAS_PARAM_CHORUS_RATE:
- if(value<EAS_CHORUS_RATE_MIN || value>EAS_CHORUS_RATE_MAX)
- return EAS_ERROR_INVALID_PARAMETER;
- p->m_nRate = (EAS_I16) value;
- break;
- case EAS_PARAM_CHORUS_DEPTH:
- if(value<EAS_CHORUS_DEPTH_MIN || value>EAS_CHORUS_DEPTH_MAX)
- return EAS_ERROR_INVALID_PARAMETER;
- p->m_nDepth = (EAS_I16) value;
- break;
- case EAS_PARAM_CHORUS_LEVEL:
- if(value<EAS_CHORUS_LEVEL_MIN || value>EAS_CHORUS_LEVEL_MAX)
- return EAS_ERROR_INVALID_PARAMETER;
- p->m_nLevel = (EAS_I16) value;
- break;
-
- default:
- return EAS_ERROR_INVALID_PARAMETER;
- }
- return EAS_SUCCESS;
-} /* end ChorusSetParam */
-
-
-/*----------------------------------------------------------------------------
- * ChorusReadInPresets()
- *----------------------------------------------------------------------------
- * Purpose: sets global Chorus preset bank to defaults
- *
- * Inputs:
- *
- * Outputs:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT ChorusReadInPresets(S_CHORUS_OBJECT *pChorusData)
-{
-
- int preset = 0;
- int defaultPreset = 0;
-
- //now init any remaining presets to defaults
- for (defaultPreset = preset; defaultPreset < CHORUS_MAX_TYPE; defaultPreset++)
- {
- S_CHORUS_PRESET *pPreset = &pChorusData->m_sPreset.m_sPreset[defaultPreset];
- if (defaultPreset == 0 || defaultPreset > CHORUS_MAX_TYPE-1)
- {
- pPreset->m_nDepth = 39;
- pPreset->m_nRate = 30;
- pPreset->m_nLevel = 32767;
- }
- else if (defaultPreset == 1)
- {
- pPreset->m_nDepth = 21;
- pPreset->m_nRate = 45;
- pPreset->m_nLevel = 25000;
- }
- else if (defaultPreset == 2)
- {
- pPreset->m_nDepth = 53;
- pPreset->m_nRate = 25;
- pPreset->m_nLevel = 32000;
- }
- else if (defaultPreset == 3)
- {
- pPreset->m_nDepth = 32;
- pPreset->m_nRate = 37;
- pPreset->m_nLevel = 29000;
- }
- }
-
- return EAS_SUCCESS;
-}
-
-
-/*----------------------------------------------------------------------------
- * ChorusUpdate
- *----------------------------------------------------------------------------
- * Purpose:
- * Update the Chorus preset parameters as required
- *
- * Inputs:
- *
- * Outputs:
- *
- *
- * Side Effects:
- * - chorus paramters will be changed
- * - m_nCurrentRoom := m_nNextRoom
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT ChorusUpdate(S_CHORUS_OBJECT *pChorusData)
-{
- S_CHORUS_PRESET *pPreset = &pChorusData->m_sPreset.m_sPreset[pChorusData->m_nNextChorus];
-
- pChorusData->m_nLevel = pPreset->m_nLevel;
- pChorusData->m_nRate = pPreset->m_nRate;
- pChorusData->m_nDepth = pPreset->m_nDepth;
-
- pChorusData->m_nRate = (EAS_I16)
- ((((EAS_I32)CHORUS_SHAPE_SIZE<<16)/(20*(EAS_I32)_OUTPUT_SAMPLE_RATE)) * pChorusData->m_nRate);
-
- /*lint -e{704} use shift for performance */
- pChorusData->m_nDepth = (EAS_I16)
- (((((EAS_I32)pChorusData->m_nDepth * _OUTPUT_SAMPLE_RATE)>>5) * 105) >> 16);
-
- pChorusData->m_nCurrentChorus = pChorusData->m_nNextChorus;
-
- return EAS_SUCCESS;
-
-} /* end ChorusUpdate */
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 499 $
+ * $Date: 2006-12-11 16:07:20 -0800 (Mon, 11 Dec 2006) $
+ *----------------------------------------------------------------------------
+*/
+
+#include "eas_data.h"
+#include "eas_effects.h"
+#include "eas_math.h"
+#include "eas_chorusdata.h"
+#include "eas_chorus.h"
+#include "eas_config.h"
+#include "eas_host.h"
+#include "eas_report.h"
+
+/* prototypes for effects interface */
+static EAS_RESULT ChorusInit (EAS_DATA_HANDLE pEASData, EAS_VOID_PTR *pInstData);
+static void ChorusProcess (EAS_VOID_PTR pInstData, EAS_PCM *pSrc, EAS_PCM *pDst, EAS_I32 numSamples);
+static EAS_RESULT ChorusShutdown (EAS_DATA_HANDLE pEASData, EAS_VOID_PTR pInstData);
+static EAS_RESULT ChorusGetParam (EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue);
+static EAS_RESULT ChorusSetParam (EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value);
+
+/* common effects interface for configuration module */
+const S_EFFECTS_INTERFACE EAS_Chorus =
+{
+ ChorusInit,
+ ChorusProcess,
+ ChorusShutdown,
+ ChorusGetParam,
+ ChorusSetParam
+};
+
+
+
+//LFO shape table used by the chorus, larger table would sound better
+//this is a sine wave, where 32767 = 1.0
+static const EAS_I16 EAS_chorusShape[CHORUS_SHAPE_SIZE] = {
+ 0, 1608, 3212, 4808, 6393, 7962, 9512, 11309, 12539, 14010, 15446, 16846, 18204, 19519, 20787, 22005, 23170,
+ 24279, 25329, 26319, 27245, 28105, 28898, 29621, 30273, 30852, 31356, 31785, 32137, 32412, 32609, 32728,
+ 32767, 32728, 32609, 32412, 32137, 31785, 31356, 30852, 30273, 29621, 28898, 28105, 27245, 26319, 25329,
+ 24279, 23170, 22005, 20787, 19519, 18204, 16846, 15446, 14010, 12539, 11039, 9512, 7962, 6393, 4808, 3212,
+ 1608, 0, -1608, -3212, -4808, -6393, -7962, -9512, -11309, -12539, -14010, -15446, -16846, -18204, -19519,
+ -20787, -22005, -23170, -24279, -25329, -26319, -27245, -28105, -28898, -29621, -30273, -30852, -31356, -31785,
+ -32137, -32412, -32609, -32728, -32767, -32728, -32609, -32412, -32137, -31785, -31356, -30852, -30273, -29621,
+ -28898, -28105, -27245, -26319, -25329, -24279, -23170, -22005, -20787, -19519, -18204, -16846, -15446, -14010,
+ -12539, -11039, -9512, -7962, -6393, -4808, -3212, -1608
+};
+
+/*----------------------------------------------------------------------------
+ * InitializeChorus()
+ *----------------------------------------------------------------------------
+ * Purpose: Initializes chorus parameters
+ *
+ *
+ * Inputs:
+ *
+ * Outputs:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT ChorusInit (EAS_DATA_HANDLE pEASData, EAS_VOID_PTR *pInstData)
+{
+ S_CHORUS_OBJECT *pChorusData;
+ S_CHORUS_PRESET *pPreset;
+ EAS_I32 index;
+
+ /* check Configuration Module for data allocation */
+ if (pEASData->staticMemoryModel)
+ pChorusData = EAS_CMEnumFXData(EAS_MODULE_CHORUS);
+
+ /* allocate dynamic memory */
+ else
+ pChorusData = EAS_HWMalloc(pEASData->hwInstData, sizeof(S_CHORUS_OBJECT));
+
+ if (pChorusData == NULL)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_FATAL, "Failed to allocate Chorus memory\n"); */ }
+ return EAS_ERROR_MALLOC_FAILED;
+ }
+
+ /* clear the structure */
+ EAS_HWMemSet(pChorusData, 0, sizeof(S_CHORUS_OBJECT));
+
+ ChorusReadInPresets(pChorusData);
+
+ /* set some default values */
+ pChorusData->bypass = EAS_CHORUS_BYPASS_DEFAULT;
+ pChorusData->preset = EAS_CHORUS_PRESET_DEFAULT;
+ pChorusData->m_nLevel = EAS_CHORUS_LEVEL_DEFAULT;
+ pChorusData->m_nRate = EAS_CHORUS_RATE_DEFAULT;
+ pChorusData->m_nDepth = EAS_CHORUS_DEPTH_DEFAULT;
+
+ //chorus rate and depth need some massaging from preset value (which is sample rate independent)
+
+ //convert rate from steps of .05 Hz to value which can be used as phase increment,
+ //with current CHORUS_SHAPE_SIZE and rate limits, this fits into 16 bits
+ //want to compute ((shapeSize * 65536) * (storedRate/20))/sampleRate;
+ //computing it as below allows rate steps to be evenly spaced
+ //uses 32 bit divide, but only once when new value is selected
+ pChorusData->m_nRate = (EAS_I16)
+ ((((EAS_I32)CHORUS_SHAPE_SIZE<<16)/(20*(EAS_I32)_OUTPUT_SAMPLE_RATE)) * pChorusData->m_nRate);
+
+ //convert depth from steps of .05 ms, to samples, with 16 bit whole part, discard fraction
+ //want to compute ((depth * sampleRate)/20000)
+ //use the following approximation since 105/32 is roughly 65536/20000
+ /*lint -e{704} use shift for performance */
+ pChorusData->m_nDepth = (EAS_I16)
+ (((((EAS_I32)pChorusData->m_nDepth * _OUTPUT_SAMPLE_RATE)>>5) * 105) >> 16);
+
+ pChorusData->m_nLevel = pChorusData->m_nLevel;
+
+ //zero delay memory for chorus
+ for (index = CHORUS_L_SIZE - 1; index >= 0; index--)
+ {
+ pChorusData->chorusDelayL[index] = 0;
+ }
+ for (index = CHORUS_R_SIZE - 1; index >= 0; index--)
+ {
+ pChorusData->chorusDelayR[index] = 0;
+ }
+
+ //init delay line index, these are used to implement circular delay buffer
+ pChorusData->chorusIndexL = 0;
+ pChorusData->chorusIndexR = 0;
+
+ //init LFO phase
+ //16 bit whole part, 16 bit fraction
+ pChorusData->lfoLPhase = 0;
+ pChorusData->lfoRPhase = (CHORUS_SHAPE_SIZE << 16) >> 2; // 1/4 of total, i.e. 90 degrees out of phase;
+
+ //init chorus delay position
+ //right now chorus delay is a compile-time value, as is sample rate
+ pChorusData->chorusTapPosition = (EAS_I16)((CHORUS_DELAY_MS * _OUTPUT_SAMPLE_RATE)/1000);
+
+ //now copy from the new preset into Chorus
+ pPreset = &pChorusData->m_sPreset.m_sPreset[pChorusData->m_nNextChorus];
+
+ pChorusData->m_nLevel = pPreset->m_nLevel;
+ pChorusData->m_nRate = pPreset->m_nRate;
+ pChorusData->m_nDepth = pPreset->m_nDepth;
+
+ pChorusData->m_nRate = (EAS_I16)
+ ((((EAS_I32)CHORUS_SHAPE_SIZE<<16)/(20*(EAS_I32)_OUTPUT_SAMPLE_RATE)) * pChorusData->m_nRate);
+
+ /*lint -e{704} use shift for performance */
+ pChorusData->m_nDepth = (EAS_I16)
+ (((((EAS_I32)pChorusData->m_nDepth * _OUTPUT_SAMPLE_RATE)>>5) * 105) >> 16);
+
+ *pInstData = pChorusData;
+
+ return EAS_SUCCESS;
+} /* end ChorusInit */
+
+/*----------------------------------------------------------------------------
+ * WeightedTap()
+ *----------------------------------------------------------------------------
+ * Purpose: Does fractional array look-up using linear interpolation
+ *
+ * first convert indexDesired to actual desired index by taking into account indexReference
+ * then do linear interpolation between two actual samples using fractional part
+ *
+ * Inputs:
+ * array: pointer to array of signed 16 bit values, typically either PCM data or control data
+ * indexReference: the circular buffer relative offset
+ * indexDesired: the fractional index we are looking up (16 bits index + 16 bits fraction)
+ * indexLimit: the total size of the array, used to compute buffer wrap
+ *
+ * Outputs:
+ * Value from the input array, linearly interpolated between two actual data values
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_I16 WeightedTap(const EAS_I16 *array, EAS_I16 indexReference, EAS_I32 indexDesired, EAS_I16 indexLimit)
+{
+ EAS_I16 index;
+ EAS_I16 fraction;
+ EAS_I16 val1;
+ EAS_I16 val2;
+
+ //separate indexDesired into whole and fractional parts
+ /*lint -e{704} use shift for performance */
+ index = (EAS_I16)(indexDesired >> 16);
+ /*lint -e{704} use shift for performance */
+ fraction = (EAS_I16)((indexDesired>>1) & 0x07FFF); //just use 15 bits of fractional part
+
+ //adjust whole part by indexReference
+ index = indexReference - index;
+ //make sure we stay within array bounds, this implements circular buffer
+ while (index < 0)
+ {
+ index += indexLimit;
+ }
+
+ //get two adjacent values from the array
+ val1 = array[index];
+
+ //handle special case when index == 0, else typical case
+ if (index == 0)
+ {
+ val2 = array[indexLimit-1]; //get last value from array
+ }
+ else
+ {
+ val2 = array[index-1]; //get previous value from array
+ }
+
+ //compute linear interpolation as (val1 + ((val2-val1)*fraction))
+ return(val1 + (EAS_I16)MULT_EG1_EG1(val2-val1,fraction));
+}
+
+/*----------------------------------------------------------------------------
+ * ChorusProcess()
+ *----------------------------------------------------------------------------
+ * Purpose: compute the chorus on the input buffer, and mix into output buffer
+ *
+ *
+ * Inputs:
+ * src: pointer to input buffer of PCM values to be processed
+ * dst: pointer to output buffer of PCM values we are to sume the result with
+ * bufSize: the number of sample frames (i.e. stereo samples) in the buffer
+ *
+ * Outputs:
+ * None
+ *
+ *----------------------------------------------------------------------------
+*/
+//compute the chorus, and mix into output buffer
+static void ChorusProcess (EAS_VOID_PTR pInstData, EAS_PCM *pSrc, EAS_PCM *pDst, EAS_I32 numSamples)
+{
+ EAS_I32 ix;
+ EAS_I32 nChannelNumber;
+ EAS_I16 lfoValueLeft;
+ EAS_I16 lfoValueRight;
+ EAS_I32 positionOffsetL;
+ EAS_I32 positionOffsetR;
+ EAS_PCM tapL;
+ EAS_PCM tapR;
+ EAS_I32 tempValue;
+ EAS_PCM nInputSample;
+ EAS_I32 nOutputSample;
+ EAS_PCM *pIn;
+ EAS_PCM *pOut;
+
+ S_CHORUS_OBJECT *pChorusData;
+
+ pChorusData = (S_CHORUS_OBJECT*) pInstData;
+
+ //if the chorus is disabled or turned all the way down
+ if (pChorusData->bypass == EAS_TRUE || pChorusData->m_nLevel == 0)
+ {
+ if (pSrc != pDst)
+ EAS_HWMemCpy(pSrc, pDst, numSamples * NUM_OUTPUT_CHANNELS * (EAS_I32) sizeof(EAS_PCM));
+ return;
+ }
+
+ if (pChorusData->m_nNextChorus != pChorusData->m_nCurrentChorus)
+ {
+ ChorusUpdate(pChorusData);
+ }
+
+ for (nChannelNumber = 0; nChannelNumber < NUM_OUTPUT_CHANNELS; nChannelNumber++)
+ {
+
+ pIn = pSrc + nChannelNumber;
+ pOut = pDst + nChannelNumber;
+
+ if(nChannelNumber==0)
+ {
+ for (ix = 0; ix < numSamples; ix++)
+ {
+ nInputSample = *pIn;
+ pIn += NUM_OUTPUT_CHANNELS;
+
+ //feed input into chorus delay line
+ pChorusData->chorusDelayL[pChorusData->chorusIndexL] = nInputSample;
+
+ //compute chorus lfo value using phase as fractional index into chorus shape table
+ //resulting value is between -1.0 and 1.0, expressed as signed 16 bit number
+ lfoValueLeft = WeightedTap(EAS_chorusShape, 0, pChorusData->lfoLPhase, CHORUS_SHAPE_SIZE);
+
+ //scale chorus depth by lfo value to get relative fractional sample index
+ //index is expressed as 32 bit number with 16 bit fractional part
+ /*lint -e{703} use shift for performance */
+ positionOffsetL = pChorusData->m_nDepth * (((EAS_I32)lfoValueLeft) << 1);
+
+ //add fixed chorus delay to get actual fractional sample index
+ positionOffsetL += ((EAS_I32)pChorusData->chorusTapPosition) << 16;
+
+ //get tap value from chorus delay using fractional sample index
+ tapL = WeightedTap(pChorusData->chorusDelayL, pChorusData->chorusIndexL, positionOffsetL, CHORUS_L_SIZE);
+
+ //scale by chorus level, then sum with input buffer contents and saturate
+ tempValue = MULT_EG1_EG1(tapL, pChorusData->m_nLevel);
+ nOutputSample = SATURATE(tempValue + nInputSample);
+
+ *pOut = (EAS_I16)SATURATE(nOutputSample);
+ pOut += NUM_OUTPUT_CHANNELS;
+
+
+ //increment chorus delay index and make it wrap as needed
+ //this implements circular buffer
+ if ((pChorusData->chorusIndexL+=1) >= CHORUS_L_SIZE)
+ pChorusData->chorusIndexL = 0;
+
+ //increment fractional lfo phase, and make it wrap as needed
+ pChorusData->lfoLPhase += pChorusData->m_nRate;
+ while (pChorusData->lfoLPhase >= (CHORUS_SHAPE_SIZE<<16))
+ {
+ pChorusData->lfoLPhase -= (CHORUS_SHAPE_SIZE<<16);
+ }
+ }
+ }
+ else
+ {
+ for (ix = 0; ix < numSamples; ix++)
+ {
+ nInputSample = *pIn;
+ pIn += NUM_OUTPUT_CHANNELS;
+
+ //feed input into chorus delay line
+ pChorusData->chorusDelayR[pChorusData->chorusIndexR] = nInputSample;
+
+ //compute chorus lfo value using phase as fractional index into chorus shape table
+ //resulting value is between -1.0 and 1.0, expressed as signed 16 bit number
+ lfoValueRight = WeightedTap(EAS_chorusShape, 0, pChorusData->lfoRPhase, CHORUS_SHAPE_SIZE);
+
+ //scale chorus depth by lfo value to get relative fractional sample index
+ //index is expressed as 32 bit number with 16 bit fractional part
+ /*lint -e{703} use shift for performance */
+ positionOffsetR = pChorusData->m_nDepth * (((EAS_I32)lfoValueRight) << 1);
+
+ //add fixed chorus delay to get actual fractional sample index
+ positionOffsetR += ((EAS_I32)pChorusData->chorusTapPosition) << 16;
+
+ //get tap value from chorus delay using fractional sample index
+ tapR = WeightedTap(pChorusData->chorusDelayR, pChorusData->chorusIndexR, positionOffsetR, CHORUS_R_SIZE);
+
+ //scale by chorus level, then sum with output buffer contents and saturate
+ tempValue = MULT_EG1_EG1(tapR, pChorusData->m_nLevel);
+ nOutputSample = SATURATE(tempValue + nInputSample);
+
+ *pOut = (EAS_I16)SATURATE(nOutputSample);
+ pOut += NUM_OUTPUT_CHANNELS;
+
+ //increment chorus delay index and make it wrap as needed
+ //this implements circular buffer
+ if ((pChorusData->chorusIndexR+=1) >= CHORUS_R_SIZE)
+ pChorusData->chorusIndexR = 0;
+
+ //increment fractional lfo phase, and make it wrap as needed
+ pChorusData->lfoRPhase += pChorusData->m_nRate;
+ while (pChorusData->lfoRPhase >= (CHORUS_SHAPE_SIZE<<16))
+ {
+ pChorusData->lfoRPhase -= (CHORUS_SHAPE_SIZE<<16);
+ }
+ }
+ }
+
+ }
+} /* end ChorusProcess */
+
+
+
+/*----------------------------------------------------------------------------
+ * ChorusShutdown()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Initializes the Chorus effect.
+ *
+ * Inputs:
+ * pInstData - handle to instance data
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT ChorusShutdown (EAS_DATA_HANDLE pEASData, EAS_VOID_PTR pInstData)
+{
+ /* check Configuration Module for static memory allocation */
+ if (!pEASData->staticMemoryModel)
+ EAS_HWFree(pEASData->hwInstData, pInstData);
+ return EAS_SUCCESS;
+} /* end ChorusShutdown */
+
+/*----------------------------------------------------------------------------
+ * ChorusGetParam()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Get a Chorus parameter
+ *
+ * Inputs:
+ * pInstData - handle to instance data
+ * param - parameter index
+ * *pValue - pointer to variable to hold retrieved value
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT ChorusGetParam (EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue)
+{
+ S_CHORUS_OBJECT *p;
+
+ p = (S_CHORUS_OBJECT*) pInstData;
+
+ switch (param)
+ {
+ case EAS_PARAM_CHORUS_BYPASS:
+ *pValue = (EAS_I32) p->bypass;
+ break;
+ case EAS_PARAM_CHORUS_PRESET:
+ *pValue = (EAS_I8) p->m_nCurrentChorus;
+ break;
+ case EAS_PARAM_CHORUS_RATE:
+ *pValue = (EAS_I32) p->m_nRate;
+ break;
+ case EAS_PARAM_CHORUS_DEPTH:
+ *pValue = (EAS_I32) p->m_nDepth;
+ break;
+ case EAS_PARAM_CHORUS_LEVEL:
+ *pValue = (EAS_I32) p->m_nLevel;
+ break;
+ default:
+ return EAS_ERROR_INVALID_PARAMETER;
+ }
+ return EAS_SUCCESS;
+} /* end ChorusGetParam */
+
+
+/*----------------------------------------------------------------------------
+ * ChorusSetParam()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Set a Chorus parameter
+ *
+ * Inputs:
+ * pInstData - handle to instance data
+ * param - parameter index
+ * *pValue - new paramter value
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT ChorusSetParam (EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value)
+{
+ S_CHORUS_OBJECT *p;
+
+ p = (S_CHORUS_OBJECT*) pInstData;
+
+ switch (param)
+ {
+ case EAS_PARAM_CHORUS_BYPASS:
+ p->bypass = (EAS_BOOL) value;
+ break;
+ case EAS_PARAM_CHORUS_PRESET:
+ if(value!=EAS_PARAM_CHORUS_PRESET1 && value!=EAS_PARAM_CHORUS_PRESET2 &&
+ value!=EAS_PARAM_CHORUS_PRESET3 && value!=EAS_PARAM_CHORUS_PRESET4)
+ return EAS_ERROR_INVALID_PARAMETER;
+ p->m_nNextChorus = (EAS_I8)value;
+ break;
+ case EAS_PARAM_CHORUS_RATE:
+ if(value<EAS_CHORUS_RATE_MIN || value>EAS_CHORUS_RATE_MAX)
+ return EAS_ERROR_INVALID_PARAMETER;
+ p->m_nRate = (EAS_I16) value;
+ break;
+ case EAS_PARAM_CHORUS_DEPTH:
+ if(value<EAS_CHORUS_DEPTH_MIN || value>EAS_CHORUS_DEPTH_MAX)
+ return EAS_ERROR_INVALID_PARAMETER;
+ p->m_nDepth = (EAS_I16) value;
+ break;
+ case EAS_PARAM_CHORUS_LEVEL:
+ if(value<EAS_CHORUS_LEVEL_MIN || value>EAS_CHORUS_LEVEL_MAX)
+ return EAS_ERROR_INVALID_PARAMETER;
+ p->m_nLevel = (EAS_I16) value;
+ break;
+
+ default:
+ return EAS_ERROR_INVALID_PARAMETER;
+ }
+ return EAS_SUCCESS;
+} /* end ChorusSetParam */
+
+
+/*----------------------------------------------------------------------------
+ * ChorusReadInPresets()
+ *----------------------------------------------------------------------------
+ * Purpose: sets global Chorus preset bank to defaults
+ *
+ * Inputs:
+ *
+ * Outputs:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT ChorusReadInPresets(S_CHORUS_OBJECT *pChorusData)
+{
+
+ int preset = 0;
+ int defaultPreset = 0;
+
+ //now init any remaining presets to defaults
+ for (defaultPreset = preset; defaultPreset < CHORUS_MAX_TYPE; defaultPreset++)
+ {
+ S_CHORUS_PRESET *pPreset = &pChorusData->m_sPreset.m_sPreset[defaultPreset];
+ if (defaultPreset == 0 || defaultPreset > CHORUS_MAX_TYPE-1)
+ {
+ pPreset->m_nDepth = 39;
+ pPreset->m_nRate = 30;
+ pPreset->m_nLevel = 32767;
+ }
+ else if (defaultPreset == 1)
+ {
+ pPreset->m_nDepth = 21;
+ pPreset->m_nRate = 45;
+ pPreset->m_nLevel = 25000;
+ }
+ else if (defaultPreset == 2)
+ {
+ pPreset->m_nDepth = 53;
+ pPreset->m_nRate = 25;
+ pPreset->m_nLevel = 32000;
+ }
+ else if (defaultPreset == 3)
+ {
+ pPreset->m_nDepth = 32;
+ pPreset->m_nRate = 37;
+ pPreset->m_nLevel = 29000;
+ }
+ }
+
+ return EAS_SUCCESS;
+}
+
+
+/*----------------------------------------------------------------------------
+ * ChorusUpdate
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Update the Chorus preset parameters as required
+ *
+ * Inputs:
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ * - chorus paramters will be changed
+ * - m_nCurrentRoom := m_nNextRoom
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT ChorusUpdate(S_CHORUS_OBJECT *pChorusData)
+{
+ S_CHORUS_PRESET *pPreset = &pChorusData->m_sPreset.m_sPreset[pChorusData->m_nNextChorus];
+
+ pChorusData->m_nLevel = pPreset->m_nLevel;
+ pChorusData->m_nRate = pPreset->m_nRate;
+ pChorusData->m_nDepth = pPreset->m_nDepth;
+
+ pChorusData->m_nRate = (EAS_I16)
+ ((((EAS_I32)CHORUS_SHAPE_SIZE<<16)/(20*(EAS_I32)_OUTPUT_SAMPLE_RATE)) * pChorusData->m_nRate);
+
+ /*lint -e{704} use shift for performance */
+ pChorusData->m_nDepth = (EAS_I16)
+ (((((EAS_I32)pChorusData->m_nDepth * _OUTPUT_SAMPLE_RATE)>>5) * 105) >> 16);
+
+ pChorusData->m_nCurrentChorus = pChorusData->m_nNextChorus;
+
+ return EAS_SUCCESS;
+
+} /* end ChorusUpdate */
diff --git a/arm-hybrid-22k/lib_src/eas_chorusdata.c b/arm-hybrid-22k/lib_src/eas_chorusdata.c
index caee1ed..ec71ff8 100644
--- a/arm-hybrid-22k/lib_src/eas_chorusdata.c
+++ b/arm-hybrid-22k/lib_src/eas_chorusdata.c
@@ -1,13 +1,13 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_chorusdata.c
- *
- * Contents and purpose:
- * Contains the static data allocation for the Chorus effect
- *
- *
- * Copyright Sonic Network Inc. 2006
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_chorusdata.c
+ *
+ * Contents and purpose:
+ * Contains the static data allocation for the Chorus effect
+ *
+ *
+ * Copyright Sonic Network Inc. 2006
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,15 +20,15 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 550 $
- * $Date: 2007-02-02 09:37:03 -0800 (Fri, 02 Feb 2007) $
- *----------------------------------------------------------------------------
-*/
-
-#include "eas_chorusdata.h"
-
-S_CHORUS_OBJECT eas_ChorusData;
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 550 $
+ * $Date: 2007-02-02 09:37:03 -0800 (Fri, 02 Feb 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+#include "eas_chorusdata.h"
+
+S_CHORUS_OBJECT eas_ChorusData;
+
diff --git a/arm-hybrid-22k/lib_src/eas_chorusdata.h b/arm-hybrid-22k/lib_src/eas_chorusdata.h
index 4420ddd..ec8daa4 100644
--- a/arm-hybrid-22k/lib_src/eas_chorusdata.h
+++ b/arm-hybrid-22k/lib_src/eas_chorusdata.h
@@ -1,13 +1,13 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_chorusdata.h
- *
- * Contents and purpose:
- * Contains the prototypes for the Chorus effect.
- *
- *
- * Copyright Sonic Network Inc. 2006
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_chorusdata.h
+ *
+ * Contents and purpose:
+ * Contains the prototypes for the Chorus effect.
+ *
+ *
+ * Copyright Sonic Network Inc. 2006
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,141 +20,141 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 309 $
- * $Date: 2006-09-12 18:52:45 -0700 (Tue, 12 Sep 2006) $
- *----------------------------------------------------------------------------
-*/
-
-#ifndef _EAS_CHORUS_H
-#define _EAS_CHORUS_H
-
-#include "eas_types.h"
-#include "eas_audioconst.h"
-
-//defines for chorus
-
-#define EAS_CHORUS_BYPASS_DEFAULT 1
-#define EAS_CHORUS_PRESET_DEFAULT 0
-#define EAS_CHORUS_RATE_DEFAULT 30
-#define EAS_CHORUS_DEPTH_DEFAULT 39
-#define EAS_CHORUS_LEVEL_DEFAULT 32767
-
-#define EAS_CHORUS_LEVEL_MIN 0
-#define EAS_CHORUS_LEVEL_MAX 32767
-
-#define EAS_CHORUS_RATE_MIN 10
-#define EAS_CHORUS_RATE_MAX 50
-
-#define EAS_CHORUS_DEPTH_MIN 15
-#define EAS_CHORUS_DEPTH_MAX 60
-
-#define CHORUS_SIZE_MS 20
-#define CHORUS_L_SIZE ((CHORUS_SIZE_MS*_OUTPUT_SAMPLE_RATE)/1000)
-#define CHORUS_R_SIZE CHORUS_L_SIZE
-#define CHORUS_SHAPE_SIZE 128
-#define CHORUS_DELAY_MS 10
-
-#define CHORUS_MAX_TYPE 4 // any Chorus numbers larger than this are invalid
-
-typedef struct
-{
- EAS_I16 m_nRate;
- EAS_I16 m_nDepth;
- EAS_I16 m_nLevel;
-
-} S_CHORUS_PRESET;
-
-typedef struct
-{
- S_CHORUS_PRESET m_sPreset[CHORUS_MAX_TYPE]; //array of presets
-
-} S_CHORUS_PRESET_BANK;
-
-/* parameters for each Chorus */
-typedef struct
-{
- EAS_I32 lfoLPhase;
- EAS_I32 lfoRPhase;
- EAS_I16 chorusIndexL;
- EAS_I16 chorusIndexR;
- EAS_U16 chorusTapPosition;
-
- EAS_I16 m_nRate;
- EAS_I16 m_nDepth;
- EAS_I16 m_nLevel;
-
- //delay lines used by the chorus, longer would sound better
- EAS_PCM chorusDelayL[CHORUS_L_SIZE];
- EAS_PCM chorusDelayR[CHORUS_R_SIZE];
-
- EAS_BOOL bypass;
- EAS_I8 preset;
-
- EAS_I16 m_nCurrentChorus; // preset number for current Chorus
- EAS_I16 m_nNextChorus; // preset number for next Chorus
-
- S_CHORUS_PRESET pPreset;
-
- S_CHORUS_PRESET_BANK m_sPreset;
-
-} S_CHORUS_OBJECT;
-
-
-/*----------------------------------------------------------------------------
- * WeightedTap()
- *----------------------------------------------------------------------------
- * Purpose: Does fractional array look-up using linear interpolation
- *
- * first convert indexDesired to actual desired index by taking into account indexReference
- * then do linear interpolation between two actual samples using fractional part
- *
- * Inputs:
- * array: pointer to array of signed 16 bit values, typically either PCM data or control data
- * indexReference: the circular buffer relative offset
- * indexDesired: the fractional index we are looking up (16 bits index + 16 bits fraction)
- * indexLimit: the total size of the array, used to compute buffer wrap
- *
- * Outputs:
- * Value from the input array, linearly interpolated between two actual data values
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_I16 WeightedTap(const EAS_I16 *array, EAS_I16 indexReference, EAS_I32 indexDesired, EAS_I16 indexLimit);
-
-/*----------------------------------------------------------------------------
- * ChorusReadInPresets()
- *----------------------------------------------------------------------------
- * Purpose: sets global Chorus preset bank to defaults
- *
- * Inputs:
- *
- * Outputs:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT ChorusReadInPresets(S_CHORUS_OBJECT *pChorusData);
-
-/*----------------------------------------------------------------------------
- * ChorusUpdate
- *----------------------------------------------------------------------------
- * Purpose:
- * Update the Chorus preset parameters as required
- *
- * Inputs:
- *
- * Outputs:
- *
- *
- * Side Effects:
- * - chorus paramters will be changed
- * - m_nCurrentChorus := m_nNextChorus
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT ChorusUpdate(S_CHORUS_OBJECT* pChorusData);
-
-#endif /* #ifndef _EAS_CHORUSDATA_H */
-
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 309 $
+ * $Date: 2006-09-12 18:52:45 -0700 (Tue, 12 Sep 2006) $
+ *----------------------------------------------------------------------------
+*/
+
+#ifndef _EAS_CHORUS_H
+#define _EAS_CHORUS_H
+
+#include "eas_types.h"
+#include "eas_audioconst.h"
+
+//defines for chorus
+
+#define EAS_CHORUS_BYPASS_DEFAULT 1
+#define EAS_CHORUS_PRESET_DEFAULT 0
+#define EAS_CHORUS_RATE_DEFAULT 30
+#define EAS_CHORUS_DEPTH_DEFAULT 39
+#define EAS_CHORUS_LEVEL_DEFAULT 32767
+
+#define EAS_CHORUS_LEVEL_MIN 0
+#define EAS_CHORUS_LEVEL_MAX 32767
+
+#define EAS_CHORUS_RATE_MIN 10
+#define EAS_CHORUS_RATE_MAX 50
+
+#define EAS_CHORUS_DEPTH_MIN 15
+#define EAS_CHORUS_DEPTH_MAX 60
+
+#define CHORUS_SIZE_MS 20
+#define CHORUS_L_SIZE ((CHORUS_SIZE_MS*_OUTPUT_SAMPLE_RATE)/1000)
+#define CHORUS_R_SIZE CHORUS_L_SIZE
+#define CHORUS_SHAPE_SIZE 128
+#define CHORUS_DELAY_MS 10
+
+#define CHORUS_MAX_TYPE 4 // any Chorus numbers larger than this are invalid
+
+typedef struct
+{
+ EAS_I16 m_nRate;
+ EAS_I16 m_nDepth;
+ EAS_I16 m_nLevel;
+
+} S_CHORUS_PRESET;
+
+typedef struct
+{
+ S_CHORUS_PRESET m_sPreset[CHORUS_MAX_TYPE]; //array of presets
+
+} S_CHORUS_PRESET_BANK;
+
+/* parameters for each Chorus */
+typedef struct
+{
+ EAS_I32 lfoLPhase;
+ EAS_I32 lfoRPhase;
+ EAS_I16 chorusIndexL;
+ EAS_I16 chorusIndexR;
+ EAS_U16 chorusTapPosition;
+
+ EAS_I16 m_nRate;
+ EAS_I16 m_nDepth;
+ EAS_I16 m_nLevel;
+
+ //delay lines used by the chorus, longer would sound better
+ EAS_PCM chorusDelayL[CHORUS_L_SIZE];
+ EAS_PCM chorusDelayR[CHORUS_R_SIZE];
+
+ EAS_BOOL bypass;
+ EAS_I8 preset;
+
+ EAS_I16 m_nCurrentChorus; // preset number for current Chorus
+ EAS_I16 m_nNextChorus; // preset number for next Chorus
+
+ S_CHORUS_PRESET pPreset;
+
+ S_CHORUS_PRESET_BANK m_sPreset;
+
+} S_CHORUS_OBJECT;
+
+
+/*----------------------------------------------------------------------------
+ * WeightedTap()
+ *----------------------------------------------------------------------------
+ * Purpose: Does fractional array look-up using linear interpolation
+ *
+ * first convert indexDesired to actual desired index by taking into account indexReference
+ * then do linear interpolation between two actual samples using fractional part
+ *
+ * Inputs:
+ * array: pointer to array of signed 16 bit values, typically either PCM data or control data
+ * indexReference: the circular buffer relative offset
+ * indexDesired: the fractional index we are looking up (16 bits index + 16 bits fraction)
+ * indexLimit: the total size of the array, used to compute buffer wrap
+ *
+ * Outputs:
+ * Value from the input array, linearly interpolated between two actual data values
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_I16 WeightedTap(const EAS_I16 *array, EAS_I16 indexReference, EAS_I32 indexDesired, EAS_I16 indexLimit);
+
+/*----------------------------------------------------------------------------
+ * ChorusReadInPresets()
+ *----------------------------------------------------------------------------
+ * Purpose: sets global Chorus preset bank to defaults
+ *
+ * Inputs:
+ *
+ * Outputs:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT ChorusReadInPresets(S_CHORUS_OBJECT *pChorusData);
+
+/*----------------------------------------------------------------------------
+ * ChorusUpdate
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Update the Chorus preset parameters as required
+ *
+ * Inputs:
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ * - chorus paramters will be changed
+ * - m_nCurrentChorus := m_nNextChorus
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT ChorusUpdate(S_CHORUS_OBJECT* pChorusData);
+
+#endif /* #ifndef _EAS_CHORUSDATA_H */
+
+
diff --git a/arm-hybrid-22k/lib_src/eas_ctype.h b/arm-hybrid-22k/lib_src/eas_ctype.h
index 8503870..14fa96f 100644
--- a/arm-hybrid-22k/lib_src/eas_ctype.h
+++ b/arm-hybrid-22k/lib_src/eas_ctype.h
@@ -1,14 +1,14 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_ctype.h
- *
- * Contents and purpose:
- * This is a replacement for the CRT ctype.h functions. These
- * functions are currently ASCII only, but eventually, we will want
- * to support wide-characters for localization.
- *
- * Copyright (c) 2005 Sonic Network Inc.
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_ctype.h
+ *
+ * Contents and purpose:
+ * This is a replacement for the CRT ctype.h functions. These
+ * functions are currently ASCII only, but eventually, we will want
+ * to support wide-characters for localization.
+ *
+ * Copyright (c) 2005 Sonic Network Inc.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,21 +21,21 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 429 $
- * $Date: 2006-10-19 23:50:15 -0700 (Thu, 19 Oct 2006) $
- *----------------------------------------------------------------------------
-*/
-
-#ifndef _EAS_CTYPE_H
-#define _EAS_CTYPE_H
-
-EAS_INLINE EAS_I8 IsDigit (EAS_I8 c) { return ((c >= '0') && (c <= '9')); }
-EAS_INLINE EAS_I8 IsSpace (EAS_I8 c) { return (((c >= 9) && (c <= 13)) || (c == ' ')); }
-EAS_INLINE EAS_I8 ToUpper (EAS_I8 c) { if ((c >= 'a') && (c <= 'z')) return c & ~0x20; else return c; }
-EAS_INLINE EAS_I8 ToLower (EAS_I8 c) { if ((c >= 'A') && (c <= 'Z')) return c |= 0x20; else return c; }
-
-#endif
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 429 $
+ * $Date: 2006-10-19 23:50:15 -0700 (Thu, 19 Oct 2006) $
+ *----------------------------------------------------------------------------
+*/
+
+#ifndef _EAS_CTYPE_H
+#define _EAS_CTYPE_H
+
+EAS_INLINE EAS_I8 IsDigit (EAS_I8 c) { return ((c >= '0') && (c <= '9')); }
+EAS_INLINE EAS_I8 IsSpace (EAS_I8 c) { return (((c >= 9) && (c <= 13)) || (c == ' ')); }
+EAS_INLINE EAS_I8 ToUpper (EAS_I8 c) { if ((c >= 'a') && (c <= 'z')) return c & ~0x20; else return c; }
+EAS_INLINE EAS_I8 ToLower (EAS_I8 c) { if ((c >= 'A') && (c <= 'Z')) return c |= 0x20; else return c; }
+
+#endif
+
diff --git a/arm-hybrid-22k/lib_src/eas_data.c b/arm-hybrid-22k/lib_src/eas_data.c
index bb60ef2..31a4e6a 100644
--- a/arm-hybrid-22k/lib_src/eas_data.c
+++ b/arm-hybrid-22k/lib_src/eas_data.c
@@ -1,12 +1,12 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_data.c
- *
- * Contents and purpose:
- * Contains a data allocation for synthesizer
- *
- * Copyright Sonic Network Inc. 2004
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_data.c
+ *
+ * Contents and purpose:
+ * Contains a data allocation for synthesizer
+ *
+ * Copyright Sonic Network Inc. 2004
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,19 +19,19 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 547 $
- * $Date: 2007-01-31 16:30:17 -0800 (Wed, 31 Jan 2007) $
- *----------------------------------------------------------------------------
-*/
-
-// includes
-#include "eas_data.h"
-
-// globals
-S_EAS_DATA eas_Data;
-S_VOICE_MGR eas_Synth;
-S_SYNTH eas_MIDI;
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 547 $
+ * $Date: 2007-01-31 16:30:17 -0800 (Wed, 31 Jan 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+// includes
+#include "eas_data.h"
+
+// globals
+S_EAS_DATA eas_Data;
+S_VOICE_MGR eas_Synth;
+S_SYNTH eas_MIDI;
+
diff --git a/arm-hybrid-22k/lib_src/eas_data.h b/arm-hybrid-22k/lib_src/eas_data.h
index 0a47d04..e2fcb1a 100644
--- a/arm-hybrid-22k/lib_src/eas_data.h
+++ b/arm-hybrid-22k/lib_src/eas_data.h
@@ -1,13 +1,13 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_data.h
- *
- * Contents and purpose:
- * This header defines all types, to support dynamic allocation of the
- * memory resources needed for persistent EAS data.
- *
- * Copyright 2004 Sonic Network Inc.
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_data.h
+ *
+ * Contents and purpose:
+ * This header defines all types, to support dynamic allocation of the
+ * memory resources needed for persistent EAS data.
+ *
+ * Copyright 2004 Sonic Network Inc.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,112 +20,112 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 842 $
- * $Date: 2007-08-23 14:32:31 -0700 (Thu, 23 Aug 2007) $
- *----------------------------------------------------------------------------
-*/
-
-#ifndef _EAS_DATA_H
-#define _EAS_DATA_H
-
-#include "eas_types.h"
-#include "eas_synthcfg.h"
-#include "eas.h"
-#include "eas_audioconst.h"
-#include "eas_sndlib.h"
-#include "eas_pcm.h"
-#include "eas_pcmdata.h"
-#include "eas_synth.h"
-#include "eas_miditypes.h"
-#include "eas_effects.h"
-
-#ifdef AUX_MIXER
-#include "eas_auxmixdata.h"
-#endif
-
-#ifdef JET_INTERFACE
-#include "jet.h"
-#endif
-
-#ifdef _METRICS_ENABLED
-#include "eas_perf.h"
-#endif
-
-#ifndef MAX_NUMBER_STREAMS
-#define MAX_NUMBER_STREAMS 4
-#endif
-
-/* flags for S_EAS_STREAM */
-#define STREAM_FLAGS_PARSED 1
-#define STREAM_FLAGS_PAUSE 2
-#define STREAM_FLAGS_LOCATE 4
-#define STREAM_FLAGS_RESUME 8
-
-/* structure for parsing a stream */
-typedef struct s_eas_stream_tag
-{
- void *pParserModule;
- EAS_U32 time;
- EAS_U32 frameLength;
- EAS_I32 repeatCount;
- EAS_VOID_PTR handle;
- EAS_U8 volume;
- EAS_BOOL8 streamFlags;
-} S_EAS_STREAM;
-
-/* default master volume is -10dB */
-#define DEFAULT_VOLUME 90
-#define DEFAULT_STREAM_VOLUME 100
-#define DEFAULT_STREAM_GAIN 14622
-
-/* 10 dB of boost available for individual parsers */
-#define STREAM_VOLUME_HEADROOM 10
-
-/* amalgamated persistent data type */
-typedef struct s_eas_data_tag
-{
-#ifdef _CHECKED_BUILD
- EAS_U32 handleCheck;
-#endif
- EAS_HW_DATA_HANDLE hwInstData;
-
- S_EFFECTS_MODULE effectsModules[NUM_EFFECTS_MODULES];
-
-#ifdef _METRICS_ENABLED
- S_METRICS_INTERFACE *pMetricsModule;
- EAS_VOID_PTR pMetricsData;
-#endif
-
- EAS_I32 *pMixBuffer;
- EAS_PCM *pOutputAudioBuffer;
-
-#ifdef AUX_MIXER
- S_EAS_AUX_MIXER auxMixer;
-#endif
-
-#ifdef _MAXIMIZER_ENABLED
- EAS_VOID_PTR pMaximizerData;
-#endif
-
- S_EAS_STREAM streams[MAX_NUMBER_STREAMS];
-
- S_PCM_STATE *pPCMStreams;
-
- S_VOICE_MGR *pVoiceMgr;
-
-#ifdef JET_INTERFACE
- JET_DATA_HANDLE jetHandle;
-#endif
-
- EAS_U32 renderTime;
- EAS_I16 masterGain;
- EAS_U8 masterVolume;
- EAS_BOOL8 staticMemoryModel;
- EAS_BOOL8 searchHeaderFlag;
-} S_EAS_DATA;
-
-#endif
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 842 $
+ * $Date: 2007-08-23 14:32:31 -0700 (Thu, 23 Aug 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+#ifndef _EAS_DATA_H
+#define _EAS_DATA_H
+
+#include "eas_types.h"
+#include "eas_synthcfg.h"
+#include "eas.h"
+#include "eas_audioconst.h"
+#include "eas_sndlib.h"
+#include "eas_pcm.h"
+#include "eas_pcmdata.h"
+#include "eas_synth.h"
+#include "eas_miditypes.h"
+#include "eas_effects.h"
+
+#ifdef AUX_MIXER
+#include "eas_auxmixdata.h"
+#endif
+
+#ifdef JET_INTERFACE
+#include "jet.h"
+#endif
+
+#ifdef _METRICS_ENABLED
+#include "eas_perf.h"
+#endif
+
+#ifndef MAX_NUMBER_STREAMS
+#define MAX_NUMBER_STREAMS 4
+#endif
+
+/* flags for S_EAS_STREAM */
+#define STREAM_FLAGS_PARSED 1
+#define STREAM_FLAGS_PAUSE 2
+#define STREAM_FLAGS_LOCATE 4
+#define STREAM_FLAGS_RESUME 8
+
+/* structure for parsing a stream */
+typedef struct s_eas_stream_tag
+{
+ void *pParserModule;
+ EAS_U32 time;
+ EAS_U32 frameLength;
+ EAS_I32 repeatCount;
+ EAS_VOID_PTR handle;
+ EAS_U8 volume;
+ EAS_BOOL8 streamFlags;
+} S_EAS_STREAM;
+
+/* default master volume is -10dB */
+#define DEFAULT_VOLUME 90
+#define DEFAULT_STREAM_VOLUME 100
+#define DEFAULT_STREAM_GAIN 14622
+
+/* 10 dB of boost available for individual parsers */
+#define STREAM_VOLUME_HEADROOM 10
+
+/* amalgamated persistent data type */
+typedef struct s_eas_data_tag
+{
+#ifdef _CHECKED_BUILD
+ EAS_U32 handleCheck;
+#endif
+ EAS_HW_DATA_HANDLE hwInstData;
+
+ S_EFFECTS_MODULE effectsModules[NUM_EFFECTS_MODULES];
+
+#ifdef _METRICS_ENABLED
+ S_METRICS_INTERFACE *pMetricsModule;
+ EAS_VOID_PTR pMetricsData;
+#endif
+
+ EAS_I32 *pMixBuffer;
+ EAS_PCM *pOutputAudioBuffer;
+
+#ifdef AUX_MIXER
+ S_EAS_AUX_MIXER auxMixer;
+#endif
+
+#ifdef _MAXIMIZER_ENABLED
+ EAS_VOID_PTR pMaximizerData;
+#endif
+
+ S_EAS_STREAM streams[MAX_NUMBER_STREAMS];
+
+ S_PCM_STATE *pPCMStreams;
+
+ S_VOICE_MGR *pVoiceMgr;
+
+#ifdef JET_INTERFACE
+ JET_DATA_HANDLE jetHandle;
+#endif
+
+ EAS_U32 renderTime;
+ EAS_I16 masterGain;
+ EAS_U8 masterVolume;
+ EAS_BOOL8 staticMemoryModel;
+ EAS_BOOL8 searchHeaderFlag;
+} S_EAS_DATA;
+
+#endif
+
diff --git a/arm-hybrid-22k/lib_src/eas_effects.h b/arm-hybrid-22k/lib_src/eas_effects.h
index 01e64c0..86dedac 100644
--- a/arm-hybrid-22k/lib_src/eas_effects.h
+++ b/arm-hybrid-22k/lib_src/eas_effects.h
@@ -1,12 +1,12 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_effects.h
- *
- * Contents and purpose:
- * Defines a generic effects interface.
- *
- * Copyright Sonic Network Inc. 2005
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_effects.h
+ *
+ * Contents and purpose:
+ * Defines a generic effects interface.
+ *
+ * Copyright Sonic Network Inc. 2005
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,43 +19,43 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 82 $
- * $Date: 2006-07-10 11:45:19 -0700 (Mon, 10 Jul 2006) $
- *----------------------------------------------------------------------------
-*/
-
-#ifndef _EAS_EFFECTS_H
-#define _EAS_EFFECTS_H
-
-#include "eas_types.h"
-
-typedef struct
-{
- EAS_RESULT (*pfInit)(EAS_DATA_HANDLE pEASData, EAS_VOID_PTR *pInstData);
- void (*pfProcess)(EAS_VOID_PTR pInstData, EAS_PCM *in, EAS_PCM *out, EAS_I32 numSamples);
- EAS_RESULT (*pfShutdown)(EAS_DATA_HANDLE pEASData, EAS_VOID_PTR pInstData);
- EAS_RESULT (*pFGetParam)(EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue);
- EAS_RESULT (*pFSetParam)(EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value);
-} S_EFFECTS_INTERFACE;
-
-typedef struct
-{
- EAS_RESULT (*pfInit)(EAS_DATA_HANDLE pEASData, EAS_VOID_PTR *pInstData);
- void (*pfProcess)(EAS_VOID_PTR pInstData, EAS_I32 *in, EAS_I32 *out, EAS_I32 numSamples);
- EAS_RESULT (*pfShutdown)(EAS_DATA_HANDLE pEASData, EAS_VOID_PTR pInstData);
- EAS_RESULT (*pFGetParam)(EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue);
- EAS_RESULT (*pFSetParam)(EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value);
-} S_EFFECTS32_INTERFACE;
-
-/* mixer instance data */
-typedef struct
-{
- S_EFFECTS_INTERFACE *effect;
- EAS_VOID_PTR effectData;
-} S_EFFECTS_MODULE;
-
-#endif /* end _EAS_EFFECTS_H */
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 82 $
+ * $Date: 2006-07-10 11:45:19 -0700 (Mon, 10 Jul 2006) $
+ *----------------------------------------------------------------------------
+*/
+
+#ifndef _EAS_EFFECTS_H
+#define _EAS_EFFECTS_H
+
+#include "eas_types.h"
+
+typedef struct
+{
+ EAS_RESULT (*pfInit)(EAS_DATA_HANDLE pEASData, EAS_VOID_PTR *pInstData);
+ void (*pfProcess)(EAS_VOID_PTR pInstData, EAS_PCM *in, EAS_PCM *out, EAS_I32 numSamples);
+ EAS_RESULT (*pfShutdown)(EAS_DATA_HANDLE pEASData, EAS_VOID_PTR pInstData);
+ EAS_RESULT (*pFGetParam)(EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue);
+ EAS_RESULT (*pFSetParam)(EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value);
+} S_EFFECTS_INTERFACE;
+
+typedef struct
+{
+ EAS_RESULT (*pfInit)(EAS_DATA_HANDLE pEASData, EAS_VOID_PTR *pInstData);
+ void (*pfProcess)(EAS_VOID_PTR pInstData, EAS_I32 *in, EAS_I32 *out, EAS_I32 numSamples);
+ EAS_RESULT (*pfShutdown)(EAS_DATA_HANDLE pEASData, EAS_VOID_PTR pInstData);
+ EAS_RESULT (*pFGetParam)(EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue);
+ EAS_RESULT (*pFSetParam)(EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value);
+} S_EFFECTS32_INTERFACE;
+
+/* mixer instance data */
+typedef struct
+{
+ S_EFFECTS_INTERFACE *effect;
+ EAS_VOID_PTR effectData;
+} S_EFFECTS_MODULE;
+
+#endif /* end _EAS_EFFECTS_H */
+
diff --git a/arm-hybrid-22k/lib_src/eas_fmengine.c b/arm-hybrid-22k/lib_src/eas_fmengine.c
index 9c3da66..ea7f69c 100644
--- a/arm-hybrid-22k/lib_src/eas_fmengine.c
+++ b/arm-hybrid-22k/lib_src/eas_fmengine.c
@@ -1,12 +1,12 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_fmengine.c
- *
- * Contents and purpose:
- * Implements the low-level FM synthesizer functions.
- *
- * Copyright Sonic Network Inc. 2004, 2005
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_fmengine.c
+ *
+ * Contents and purpose:
+ * Implements the low-level FM synthesizer functions.
+ *
+ * Copyright Sonic Network Inc. 2004, 2005
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,767 +19,767 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 795 $
- * $Date: 2007-08-01 00:14:45 -0700 (Wed, 01 Aug 2007) $
- *----------------------------------------------------------------------------
-*/
-
-/* includes */
-#include "eas_types.h"
-#include "eas_math.h"
-#include "eas_audioconst.h"
-#include "eas_fmengine.h"
-
-#if defined(EAS_FM_SYNTH) || defined(EAS_HYBRID_SYNTH) || defined(EAS_SPLIT_HYBRID_SYNTH) || defined(EAS_SPLIT_FM_SYNTH)
-#include "eas_data.h"
-#endif
-
-/* externals */
-extern const EAS_I16 sineTable[];
-extern const EAS_U8 fmScaleTable[16];
-
-// saturation constants for 32-bit to 16-bit conversion
-#define _EAS_MAX_OUTPUT 32767
-#define _EAS_MIN_OUTPUT -32767
-
-static S_FM_ENG_VOICE voices[NUM_FM_VOICES];
-
-/* local prototypes */
-void FM_SynthMixVoice (S_FM_ENG_VOICE *p, EAS_U16 gainTarget, EAS_I32 numSamplesToAdd, EAS_PCM *pInputBuffer, EAS_I32 *pBuffer);
-
-/* used in development environment */
-#if defined(_SATURATION_MONITOR)
-static EAS_BOOL bSaturated = EAS_FALSE;
-
-/*----------------------------------------------------------------------------
- * FM_CheckSaturation()
- *----------------------------------------------------------------------------
- * Purpose:
- * Allows the sound development tool to check for saturation at the voice
- * level. Useful for tuning the level controls.
- *
- * Inputs:
- *
- * Outputs:
- * Returns true if saturation has occurred since the last time the function
- * was called.
- *
- * Side Effects:
- * Resets the saturation flag
- *----------------------------------------------------------------------------
-*/
-EAS_BOOL FM_CheckSaturation ()
-{
- EAS_BOOL bTemp;
- bTemp = bSaturated;
- bSaturated = EAS_FALSE;
- return bTemp;
-}
-#endif
-
-/*----------------------------------------------------------------------------
- * FM_Saturate()
- *----------------------------------------------------------------------------
- * Purpose:
- * This inline function saturates a 32-bit number to 16-bits
- *
- * Inputs:
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- * Returns a 16-bit integer
- *----------------------------------------------------------------------------
-*/
-EAS_INLINE EAS_I16 FM_Saturate (EAS_I32 nValue)
-{
- if (nValue > _EAS_MAX_OUTPUT)
- {
-#if defined(_SATURATION_MONITOR)
- bSaturated = EAS_TRUE;
-#endif
- return _EAS_MAX_OUTPUT;
- }
- if (nValue < _EAS_MIN_OUTPUT)
- {
-#if defined(_SATURATION_MONITOR)
- bSaturated = EAS_TRUE;
-#endif
- return _EAS_MIN_OUTPUT;
- }
- return (EAS_I16) nValue;
-}
-
-/*----------------------------------------------------------------------------
- * FM_Noise()
- *----------------------------------------------------------------------------
- * Purpose:
- * A 31-bit low-cost linear congruential PRNG algorithm used to
- * generate noise.
- *
- * Inputs:
- * pnSeed - pointer to 32-bit PRNG seed
- *
- * Outputs:
- * Returns a 16-bit integer
- *----------------------------------------------------------------------------
-*/
-EAS_INLINE EAS_I16 FM_Noise (EAS_U32 *pnSeed)
-{
- *pnSeed = *pnSeed * 214013L + 2531011L;
- return (EAS_I16) ((*pnSeed >> 15) & 0xffff);
-}
-
-/*----------------------------------------------------------------------------
- * FM_PhaseInc()
- *----------------------------------------------------------------------------
- * Purpose:
- * Transform pitch cents to linear phase increment
- *
- * Inputs:
- * nCents - measured in cents
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- * nResult - int.frac result (where frac has NUM_DENTS_FRAC_BITS)
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_I32 FM_PhaseInc (EAS_I32 nCents)
-{
- EAS_I32 nDents;
- EAS_I32 nExponentInt, nExponentFrac;
- EAS_I32 nTemp1, nTemp2;
- EAS_I32 nResult;
-
- /* convert cents to dents */
- nDents = FMUL_15x15(nCents, CENTS_TO_DENTS);
- nExponentInt = GET_DENTS_INT_PART(nDents) + (32 - SINE_TABLE_SIZE_IN_BITS - NUM_EG1_FRAC_BITS);
- nExponentFrac = GET_DENTS_FRAC_PART(nDents);
-
- /* implement 2^(fracPart) as a power series */
- nTemp1 = GN2_TO_X2 + MULT_DENTS_COEF(nExponentFrac, GN2_TO_X3);
- nTemp2 = GN2_TO_X1 + MULT_DENTS_COEF(nExponentFrac, nTemp1);
- nTemp1 = GN2_TO_X0 + MULT_DENTS_COEF(nExponentFrac, nTemp2);
-
- /*
- implement 2^(intPart) as
- a left shift for intPart >= 0 or
- a left shift for intPart < 0
- */
- if (nExponentInt >= 0)
- {
- /* left shift for positive exponents */
- /*lint -e{703} <avoid multiply for performance>*/
- nResult = nTemp1 << nExponentInt;
- }
- else
- {
- /* right shift for negative exponents */
- nExponentInt = -nExponentInt;
- nResult = nTemp1 >> nExponentInt;
- }
-
- return nResult;
-}
-
-#if (NUM_OUTPUT_CHANNELS == 2)
-/*----------------------------------------------------------------------------
- * FM_CalculatePan()
- *----------------------------------------------------------------------------
- * Purpose:
- * Assign the left and right gain values corresponding to the given pan value.
- *
- * Inputs:
- * psVoice - ptr to the voice we have assigned for this channel
- * psArticulation - ptr to this voice's articulation
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- *
- * Side Effects:
- * the given voice's m_nGainLeft and m_nGainRight are assigned
- *----------------------------------------------------------------------------
-*/
-static void FM_CalculatePan (EAS_I16 pan, EAS_U16 *pGainLeft, EAS_U16 *pGainRight)
-{
- EAS_I32 nTemp;
- EAS_INT nNetAngle;
-
- /*
- Implement the following
- sin(x) = (2-4*c)*x^2 + c + x
- cos(x) = (2-4*c)*x^2 + c - x
-
- where c = 1/sqrt(2)
- using the a0 + x*(a1 + x*a2) approach
- */
-
- /*
- Get the Midi CC10 pan value for this voice's channel
- convert the pan value to an "angle" representation suitable for
- our sin, cos calculator. This representation is NOT necessarily the same
- as the transform in the GM manuals because of our sin, cos calculator.
- "angle" = (CC10 - 64)/128
- */
- /*lint -e{703} <avoid multiply for performance reasons>*/
- nNetAngle = ((EAS_I32) pan) << (NUM_EG1_FRAC_BITS -7);
-
- /* calculate sin */
- nTemp = EG1_ONE + FMUL_15x15(COEFF_PAN_G2, nNetAngle);
- nTemp = COEFF_PAN_G0 + FMUL_15x15(nTemp, nNetAngle);
-
- if (nTemp > SYNTH_FULL_SCALE_EG1_GAIN)
- nTemp = SYNTH_FULL_SCALE_EG1_GAIN;
- else if (nTemp < 0)
- nTemp = 0;
-
- *pGainRight = (EAS_U16) nTemp;
-
- /* calculate cos */
- nTemp = -EG1_ONE + FMUL_15x15(COEFF_PAN_G2, nNetAngle);
- nTemp = COEFF_PAN_G0 + FMUL_15x15(nTemp, nNetAngle);
-
- if (nTemp > SYNTH_FULL_SCALE_EG1_GAIN)
- nTemp = SYNTH_FULL_SCALE_EG1_GAIN;
- else if (nTemp < 0)
- nTemp = 0;
-
- *pGainLeft = (EAS_U16) nTemp;
-}
-#endif /* #if (NUM_OUTPUT_CHANNELS == 2) */
-
-/*----------------------------------------------------------------------------
- * FM_Operator()
- *----------------------------------------------------------------------------
- * Purpose:
- * Synthesizes a buffer of samples based on passed parameters.
- *
- * Inputs:
- * nNumSamplesToAdd - number of samples to synthesize
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-void FM_Operator (
- S_FM_ENG_OPER *p,
- EAS_I32 numSamplesToAdd,
- EAS_PCM *pBuffer,
- EAS_PCM *pModBuffer,
- EAS_BOOL mix,
- EAS_U16 gainTarget,
- EAS_I16 pitch,
- EAS_U8 feedback,
- EAS_I16 *pLastOutput)
-{
- EAS_I32 gain;
- EAS_I32 gainInc;
- EAS_U32 phase;
- EAS_U32 phaseInc;
- EAS_U32 phaseTemp;
- EAS_I32 temp;
- EAS_I32 temp2;
-
- /* establish local gain variable */
- gain = (EAS_I32) p->gain << 16;
-
- /* calculate gain increment */
- /*lint -e{703} use shift for performance */
- gainInc = ((EAS_I32) gainTarget - (EAS_I32) p->gain) << (16 - SYNTH_UPDATE_PERIOD_IN_BITS);
-
- /* establish local phase variables */
- phase = p->phase;
-
- /* calculate the new phase increment */
- phaseInc = (EAS_U32) FM_PhaseInc(pitch);
-
- /* restore final output from previous frame for feedback loop */
- if (pLastOutput)
- temp = *pLastOutput;
- else
- temp = 0;
-
- /* generate a buffer of samples */
- while (numSamplesToAdd--)
- {
-
- /* incorporate modulation */
- if (pModBuffer)
- {
- /*lint -e{701} use shift for performance */
- temp = *pModBuffer++ << FM_MODULATOR_INPUT_SHIFT;
- }
-
- /* incorporate feedback */
- else
- {
- /*lint -e{703} use shift for performance */
- temp = (temp * (EAS_I32) feedback) << FM_FEEDBACK_SHIFT;
- }
-
- /*lint -e{737} <use this behavior to avoid extra mask step> */
- phaseTemp = phase + temp;
-
- /* fetch sample from wavetable */
- temp = sineTable[phaseTemp >> (32 - SINE_TABLE_SIZE_IN_BITS)];
-
- /* increment operator phase */
- phase += phaseInc;
-
- /* internal gain for modulation effects */
- temp = FMUL_15x15(temp, (gain >> 16));
-
- /* output gain calculation */
- temp2 = FMUL_15x15(temp, p->outputGain);
-
- /* saturating add to buffer */
- if (mix)
- {
- temp2 += *pBuffer;
- *pBuffer++ = FM_Saturate(temp2);
- }
-
- /* output to buffer */
- else
- *pBuffer++ = (EAS_I16) temp2;
-
- /* increment gain */
- gain += gainInc;
-
- }
-
- /* save phase and gain */
- p->phase = phase;
- p->gain = gainTarget;
-
- /* save last output for feedback in next frame */
- if (pLastOutput)
- *pLastOutput = (EAS_I16) temp;
-}
-
-/*----------------------------------------------------------------------------
- * FM_NoiseOperator()
- *----------------------------------------------------------------------------
- * Purpose:
- * Synthesizes a buffer of samples based on passed parameters.
- *
- * Inputs:
- * nNumSamplesToAdd - number of samples to synthesize
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-void FM_NoiseOperator (
- S_FM_ENG_OPER *p,
- EAS_I32 numSamplesToAdd,
- EAS_PCM *pBuffer,
- EAS_BOOL mix,
- EAS_U16 gainTarget,
- EAS_U8 feedback,
- EAS_I16 *pLastOutput)
-{
- EAS_I32 gain;
- EAS_I32 gainInc;
- EAS_U32 phase;
- EAS_I32 temp;
- EAS_I32 temp2;
-
- /* establish local gain variable */
- gain = (EAS_I32) p->gain << 16;
-
- /* calculate gain increment */
- /*lint -e{703} use shift for performance */
- gainInc = ((EAS_I32) gainTarget - (EAS_I32) p->gain) << (16 - SYNTH_UPDATE_PERIOD_IN_BITS);
-
- /* establish local phase variables */
- phase = p->phase;
-
- /* establish local phase variables */
- phase = p->phase;
-
- /* recall last sample for filter Z-1 term */
- temp = 0;
- if (pLastOutput)
- temp = *pLastOutput;
-
- /* generate a buffer of samples */
- while (numSamplesToAdd--)
- {
-
- /* if using filter */
- if (pLastOutput)
- {
- /* use PRNG for noise */
- temp2 = FM_Noise(&phase);
-
- /*lint -e{704} use shift for performance */
- temp += ((temp2 -temp) * feedback) >> 8;
- }
- else
- {
- temp = FM_Noise(&phase);
- }
-
- /* internal gain for modulation effects */
- temp2 = FMUL_15x15(temp, (gain >> 16));
-
- /* output gain calculation */
- temp2 = FMUL_15x15(temp2, p->outputGain);
-
- /* saturating add to buffer */
- if (mix)
- {
- temp2 += *pBuffer;
- *pBuffer++ = FM_Saturate(temp2);
- }
-
- /* output to buffer */
- else
- *pBuffer++ = (EAS_I16) temp2;
-
- /* increment gain */
- gain += gainInc;
-
- }
-
- /* save phase and gain */
- p->phase = phase;
- p->gain = gainTarget;
-
- /* save last output for feedback in next frame */
- if (pLastOutput)
- *pLastOutput = (EAS_I16) temp;
-}
-
-/*----------------------------------------------------------------------------
- * FM_ConfigVoice()
- *----------------------------------------------------------------------------
- * Purpose:
- * Receives parameters to start a new voice.
- *
- * Inputs:
- * voiceNum - voice number to start
- * vCfg - configuration data
- * pMixBuffer - pointer to host supplied buffer
- *
- * Outputs:
- *
- * Side Effects:
- *
- * Notes:
- * pFrameBuffer is not used in the test version, but is passed as a
- * courtesy to split architecture implementations. It can be used as
- * as pointer to the interprocessor communications buffer when the
- * synthesis parameters are passed off to a DSP for synthesis.
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, pFrameBuffer) pFrameBuffer not used in test version - see above */
-void FM_ConfigVoice (EAS_I32 voiceNum, S_FM_VOICE_CONFIG *vCfg, EAS_FRAME_BUFFER_HANDLE pFrameBuffer)
-{
- S_FM_ENG_VOICE *pVoice;
- EAS_INT i;
-
- /* establish pointer to voice data */
- pVoice = &voices[voiceNum];
-
- /* save data */
- pVoice->feedback = vCfg->feedback;
- pVoice->flags = vCfg->flags;
- pVoice->voiceGain = vCfg->voiceGain;
-
- /* initialize Z-1 terms */
- pVoice->op1Out = 0;
- pVoice->op3Out = 0;
-
- /* initialize operators */
- for (i = 0; i < 4; i++)
- {
- /* save operator data */
- pVoice->oper[i].gain = vCfg->gain[i];
- pVoice->oper[i].outputGain = vCfg->outputGain[i];
- pVoice->oper[i].outputGain = vCfg->outputGain[i];
-
- /* initalize operator */
- pVoice->oper[i].phase = 0;
- }
-
- /* calculate pan */
-#if NUM_OUTPUT_CHANNELS == 2
- FM_CalculatePan(vCfg->pan, &pVoice->gainLeft, &pVoice->gainRight);
-#endif
-}
-
-/*----------------------------------------------------------------------------
- * FM_ProcessVoice()
- *----------------------------------------------------------------------------
- * Purpose:
- * Synthesizes a buffer of samples based on calculated parameters.
- *
- * Inputs:
- * nNumSamplesToAdd - number of samples to synthesize
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- *
- * Side Effects:
- *
- * Notes:
- * pOut is not used in the test version, but is passed as a
- * courtesy to split architecture implementations. It can be used as
- * as pointer to the interprocessor communications buffer when the
- * synthesis parameters are passed off to a DSP for synthesis.
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, pOut) pOut not used in test version - see above */
-void FM_ProcessVoice (
- EAS_I32 voiceNum,
- S_FM_VOICE_FRAME *pFrame,
- EAS_I32 numSamplesToAdd,
- EAS_PCM *pTempBuffer,
- EAS_PCM *pBuffer,
- EAS_I32 *pMixBuffer,
- EAS_FRAME_BUFFER_HANDLE pFrameBuffer)
-{
- S_FM_ENG_VOICE *p;
- EAS_PCM *pOutBuf;
- EAS_PCM *pMod;
- EAS_BOOL mix;
- EAS_U8 feedback1;
- EAS_U8 feedback3;
- EAS_U8 mode;
-
- /* establish pointer to voice data */
- p = &voices[voiceNum];
- mode = p->flags & 0x07;
-
- /* lookup feedback values */
- feedback1 = fmScaleTable[p->feedback >> 4];
- feedback3 = fmScaleTable[p->feedback & 0x0f];
-
- /* operator 3 is on output bus in modes 0, 1, and 3 */
- if ((mode == 0) || (mode == 1) || (mode == 3))
- pOutBuf = pBuffer;
- else
- pOutBuf = pTempBuffer;
-
- if (p->flags & FLAG_FM_ENG_VOICE_OP3_NOISE)
- {
- FM_NoiseOperator(
- p->oper + 2,
- numSamplesToAdd,
- pOutBuf,
- EAS_FALSE,
- pFrame->gain[2],
- feedback3,
- &p->op3Out);
- }
- else
- {
- FM_Operator(
- p->oper + 2,
- numSamplesToAdd,
- pOutBuf,
- 0,
- EAS_FALSE,
- pFrame->gain[2],
- pFrame->pitch[2],
- feedback3,
- &p->op3Out);
- }
-
- /* operator 4 is on output bus in modes 0, 1, and 2 */
- if (mode < 3)
- pOutBuf = pBuffer;
- else
- pOutBuf = pTempBuffer;
-
- /* operator 4 is modulated in modes 2, 4, and 5 */
- if ((mode == 2) || (mode == 4) || (mode == 5))
- pMod = pTempBuffer;
- else
- pMod = 0;
-
- /* operator 4 is in mix mode in modes 0 and 1 */
- mix = (mode < 2);
-
- if (p->flags & FLAG_FM_ENG_VOICE_OP4_NOISE)
- {
- FM_NoiseOperator(
- p->oper + 3,
- numSamplesToAdd,
- pOutBuf,
- mix,
- pFrame->gain[3],
- 0,
- 0);
- }
- else
- {
- FM_Operator(
- p->oper + 3,
- numSamplesToAdd,
- pOutBuf,
- pMod,
- mix,
- pFrame->gain[3],
- pFrame->pitch[3],
- 0,
- 0);
- }
-
- /* operator 1 is on output bus in mode 0 */
- if (mode == 0)
- pOutBuf = pBuffer;
- else
- pOutBuf = pTempBuffer;
-
- /* operator 1 is modulated in modes 3 and 4 */
- if ((mode == 3) || (mode == 4))
- pMod = pTempBuffer;
- else
- pMod = 0;
-
- /* operator 1 is in mix mode in modes 0 and 5 */
- mix = ((mode == 0) || (mode == 5));
-
- if (p->flags & FLAG_FM_ENG_VOICE_OP1_NOISE)
- {
- FM_NoiseOperator(
- p->oper,
- numSamplesToAdd,
- pOutBuf,
- mix,
- pFrame->gain[0],
- feedback1,
- &p->op1Out);
- }
- else
- {
- FM_Operator(
- p->oper,
- numSamplesToAdd,
- pOutBuf,
- pMod,
- mix,
- pFrame->gain[0],
- pFrame->pitch[0],
- feedback1,
- &p->op1Out);
- }
-
- /* operator 2 is modulated in all modes except 0 */
- if (mode != 0)
- pMod = pTempBuffer;
- else
- pMod = 0;
-
- /* operator 1 is in mix mode in modes 0 -3 */
- mix = (mode < 4);
-
- if (p->flags & FLAG_FM_ENG_VOICE_OP2_NOISE)
- {
- FM_NoiseOperator(
- p->oper + 1,
- numSamplesToAdd,
- pBuffer,
- mix,
- pFrame->gain[1],
- 0,
- 0);
- }
- else
- {
- FM_Operator(
- p->oper + 1,
- numSamplesToAdd,
- pBuffer,
- pMod,
- mix,
- pFrame->gain[1],
- pFrame->pitch[1],
- 0,
- 0);
- }
-
- /* mix voice output to synthesizer output buffer */
- FM_SynthMixVoice(p, pFrame->voiceGain, numSamplesToAdd, pBuffer, pMixBuffer);
-}
-
-/*----------------------------------------------------------------------------
- * FM_SynthMixVoice()
- *----------------------------------------------------------------------------
- * Purpose:
- * Mixes the voice output buffer into the final mix using an anti-zipper
- * filter.
- *
- * Inputs:
- * nNumSamplesToAdd - number of samples to synthesize
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-void FM_SynthMixVoice(S_FM_ENG_VOICE *p, EAS_U16 nGainTarget, EAS_I32 numSamplesToAdd, EAS_PCM *pInputBuffer, EAS_I32 *pBuffer)
-{
- EAS_I32 nGain;
- EAS_I32 nGainInc;
- EAS_I32 nTemp;
-
- /* restore previous gain */
- /*lint -e{703} <use shift for performance> */
- nGain = (EAS_I32) p->voiceGain << 16;
-
- /* calculate gain increment */
- /*lint -e{703} <use shift for performance> */
- nGainInc = ((EAS_I32) nGainTarget - (EAS_I32) p->voiceGain) << (16 - SYNTH_UPDATE_PERIOD_IN_BITS);
-
- /* mix the output buffer */
- while (numSamplesToAdd--)
- {
- /* output gain calculation */
- nTemp = *pInputBuffer++;
-
- /* sum to output buffer */
-#if (NUM_OUTPUT_CHANNELS == 2)
-
- /*lint -e{704} <use shift for performance> */
- nTemp = ((EAS_I32) nTemp * (nGain >> 16)) >> FM_GAIN_SHIFT;
-
- /*lint -e{704} <use shift for performance> */
- {
- EAS_I32 nTemp2;
- nTemp = nTemp >> FM_STEREO_PRE_GAIN_SHIFT;
- nTemp2 = (nTemp * p->gainLeft) >> FM_STEREO_POST_GAIN_SHIFT;
- *pBuffer++ += nTemp2;
- nTemp2 = (nTemp * p->gainRight) >> FM_STEREO_POST_GAIN_SHIFT;
- *pBuffer++ += nTemp2;
- }
-#else
- /*lint -e{704} <use shift for performance> */
- nTemp = ((EAS_I32) nTemp * (nGain >> 16)) >> FM_MONO_GAIN_SHIFT;
- *pBuffer++ += nTemp;
-#endif
-
- /* increment gain for anti-zipper filter */
- nGain += nGainInc;
- }
-
- /* save gain */
- p->voiceGain = nGainTarget;
-}
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 795 $
+ * $Date: 2007-08-01 00:14:45 -0700 (Wed, 01 Aug 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+/* includes */
+#include "eas_types.h"
+#include "eas_math.h"
+#include "eas_audioconst.h"
+#include "eas_fmengine.h"
+
+#if defined(EAS_FM_SYNTH) || defined(EAS_HYBRID_SYNTH) || defined(EAS_SPLIT_HYBRID_SYNTH) || defined(EAS_SPLIT_FM_SYNTH)
+#include "eas_data.h"
+#endif
+
+/* externals */
+extern const EAS_I16 sineTable[];
+extern const EAS_U8 fmScaleTable[16];
+
+// saturation constants for 32-bit to 16-bit conversion
+#define _EAS_MAX_OUTPUT 32767
+#define _EAS_MIN_OUTPUT -32767
+
+static S_FM_ENG_VOICE voices[NUM_FM_VOICES];
+
+/* local prototypes */
+void FM_SynthMixVoice (S_FM_ENG_VOICE *p, EAS_U16 gainTarget, EAS_I32 numSamplesToAdd, EAS_PCM *pInputBuffer, EAS_I32 *pBuffer);
+
+/* used in development environment */
+#if defined(_SATURATION_MONITOR)
+static EAS_BOOL bSaturated = EAS_FALSE;
+
+/*----------------------------------------------------------------------------
+ * FM_CheckSaturation()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Allows the sound development tool to check for saturation at the voice
+ * level. Useful for tuning the level controls.
+ *
+ * Inputs:
+ *
+ * Outputs:
+ * Returns true if saturation has occurred since the last time the function
+ * was called.
+ *
+ * Side Effects:
+ * Resets the saturation flag
+ *----------------------------------------------------------------------------
+*/
+EAS_BOOL FM_CheckSaturation ()
+{
+ EAS_BOOL bTemp;
+ bTemp = bSaturated;
+ bSaturated = EAS_FALSE;
+ return bTemp;
+}
+#endif
+
+/*----------------------------------------------------------------------------
+ * FM_Saturate()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * This inline function saturates a 32-bit number to 16-bits
+ *
+ * Inputs:
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ * Returns a 16-bit integer
+ *----------------------------------------------------------------------------
+*/
+EAS_INLINE EAS_I16 FM_Saturate (EAS_I32 nValue)
+{
+ if (nValue > _EAS_MAX_OUTPUT)
+ {
+#if defined(_SATURATION_MONITOR)
+ bSaturated = EAS_TRUE;
+#endif
+ return _EAS_MAX_OUTPUT;
+ }
+ if (nValue < _EAS_MIN_OUTPUT)
+ {
+#if defined(_SATURATION_MONITOR)
+ bSaturated = EAS_TRUE;
+#endif
+ return _EAS_MIN_OUTPUT;
+ }
+ return (EAS_I16) nValue;
+}
+
+/*----------------------------------------------------------------------------
+ * FM_Noise()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * A 31-bit low-cost linear congruential PRNG algorithm used to
+ * generate noise.
+ *
+ * Inputs:
+ * pnSeed - pointer to 32-bit PRNG seed
+ *
+ * Outputs:
+ * Returns a 16-bit integer
+ *----------------------------------------------------------------------------
+*/
+EAS_INLINE EAS_I16 FM_Noise (EAS_U32 *pnSeed)
+{
+ *pnSeed = *pnSeed * 214013L + 2531011L;
+ return (EAS_I16) ((*pnSeed >> 15) & 0xffff);
+}
+
+/*----------------------------------------------------------------------------
+ * FM_PhaseInc()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Transform pitch cents to linear phase increment
+ *
+ * Inputs:
+ * nCents - measured in cents
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ * nResult - int.frac result (where frac has NUM_DENTS_FRAC_BITS)
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_I32 FM_PhaseInc (EAS_I32 nCents)
+{
+ EAS_I32 nDents;
+ EAS_I32 nExponentInt, nExponentFrac;
+ EAS_I32 nTemp1, nTemp2;
+ EAS_I32 nResult;
+
+ /* convert cents to dents */
+ nDents = FMUL_15x15(nCents, CENTS_TO_DENTS);
+ nExponentInt = GET_DENTS_INT_PART(nDents) + (32 - SINE_TABLE_SIZE_IN_BITS - NUM_EG1_FRAC_BITS);
+ nExponentFrac = GET_DENTS_FRAC_PART(nDents);
+
+ /* implement 2^(fracPart) as a power series */
+ nTemp1 = GN2_TO_X2 + MULT_DENTS_COEF(nExponentFrac, GN2_TO_X3);
+ nTemp2 = GN2_TO_X1 + MULT_DENTS_COEF(nExponentFrac, nTemp1);
+ nTemp1 = GN2_TO_X0 + MULT_DENTS_COEF(nExponentFrac, nTemp2);
+
+ /*
+ implement 2^(intPart) as
+ a left shift for intPart >= 0 or
+ a left shift for intPart < 0
+ */
+ if (nExponentInt >= 0)
+ {
+ /* left shift for positive exponents */
+ /*lint -e{703} <avoid multiply for performance>*/
+ nResult = nTemp1 << nExponentInt;
+ }
+ else
+ {
+ /* right shift for negative exponents */
+ nExponentInt = -nExponentInt;
+ nResult = nTemp1 >> nExponentInt;
+ }
+
+ return nResult;
+}
+
+#if (NUM_OUTPUT_CHANNELS == 2)
+/*----------------------------------------------------------------------------
+ * FM_CalculatePan()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Assign the left and right gain values corresponding to the given pan value.
+ *
+ * Inputs:
+ * psVoice - ptr to the voice we have assigned for this channel
+ * psArticulation - ptr to this voice's articulation
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ * the given voice's m_nGainLeft and m_nGainRight are assigned
+ *----------------------------------------------------------------------------
+*/
+static void FM_CalculatePan (EAS_I16 pan, EAS_U16 *pGainLeft, EAS_U16 *pGainRight)
+{
+ EAS_I32 nTemp;
+ EAS_INT nNetAngle;
+
+ /*
+ Implement the following
+ sin(x) = (2-4*c)*x^2 + c + x
+ cos(x) = (2-4*c)*x^2 + c - x
+
+ where c = 1/sqrt(2)
+ using the a0 + x*(a1 + x*a2) approach
+ */
+
+ /*
+ Get the Midi CC10 pan value for this voice's channel
+ convert the pan value to an "angle" representation suitable for
+ our sin, cos calculator. This representation is NOT necessarily the same
+ as the transform in the GM manuals because of our sin, cos calculator.
+ "angle" = (CC10 - 64)/128
+ */
+ /*lint -e{703} <avoid multiply for performance reasons>*/
+ nNetAngle = ((EAS_I32) pan) << (NUM_EG1_FRAC_BITS -7);
+
+ /* calculate sin */
+ nTemp = EG1_ONE + FMUL_15x15(COEFF_PAN_G2, nNetAngle);
+ nTemp = COEFF_PAN_G0 + FMUL_15x15(nTemp, nNetAngle);
+
+ if (nTemp > SYNTH_FULL_SCALE_EG1_GAIN)
+ nTemp = SYNTH_FULL_SCALE_EG1_GAIN;
+ else if (nTemp < 0)
+ nTemp = 0;
+
+ *pGainRight = (EAS_U16) nTemp;
+
+ /* calculate cos */
+ nTemp = -EG1_ONE + FMUL_15x15(COEFF_PAN_G2, nNetAngle);
+ nTemp = COEFF_PAN_G0 + FMUL_15x15(nTemp, nNetAngle);
+
+ if (nTemp > SYNTH_FULL_SCALE_EG1_GAIN)
+ nTemp = SYNTH_FULL_SCALE_EG1_GAIN;
+ else if (nTemp < 0)
+ nTemp = 0;
+
+ *pGainLeft = (EAS_U16) nTemp;
+}
+#endif /* #if (NUM_OUTPUT_CHANNELS == 2) */
+
+/*----------------------------------------------------------------------------
+ * FM_Operator()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Synthesizes a buffer of samples based on passed parameters.
+ *
+ * Inputs:
+ * nNumSamplesToAdd - number of samples to synthesize
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+void FM_Operator (
+ S_FM_ENG_OPER *p,
+ EAS_I32 numSamplesToAdd,
+ EAS_PCM *pBuffer,
+ EAS_PCM *pModBuffer,
+ EAS_BOOL mix,
+ EAS_U16 gainTarget,
+ EAS_I16 pitch,
+ EAS_U8 feedback,
+ EAS_I16 *pLastOutput)
+{
+ EAS_I32 gain;
+ EAS_I32 gainInc;
+ EAS_U32 phase;
+ EAS_U32 phaseInc;
+ EAS_U32 phaseTemp;
+ EAS_I32 temp;
+ EAS_I32 temp2;
+
+ /* establish local gain variable */
+ gain = (EAS_I32) p->gain << 16;
+
+ /* calculate gain increment */
+ /*lint -e{703} use shift for performance */
+ gainInc = ((EAS_I32) gainTarget - (EAS_I32) p->gain) << (16 - SYNTH_UPDATE_PERIOD_IN_BITS);
+
+ /* establish local phase variables */
+ phase = p->phase;
+
+ /* calculate the new phase increment */
+ phaseInc = (EAS_U32) FM_PhaseInc(pitch);
+
+ /* restore final output from previous frame for feedback loop */
+ if (pLastOutput)
+ temp = *pLastOutput;
+ else
+ temp = 0;
+
+ /* generate a buffer of samples */
+ while (numSamplesToAdd--)
+ {
+
+ /* incorporate modulation */
+ if (pModBuffer)
+ {
+ /*lint -e{701} use shift for performance */
+ temp = *pModBuffer++ << FM_MODULATOR_INPUT_SHIFT;
+ }
+
+ /* incorporate feedback */
+ else
+ {
+ /*lint -e{703} use shift for performance */
+ temp = (temp * (EAS_I32) feedback) << FM_FEEDBACK_SHIFT;
+ }
+
+ /*lint -e{737} <use this behavior to avoid extra mask step> */
+ phaseTemp = phase + temp;
+
+ /* fetch sample from wavetable */
+ temp = sineTable[phaseTemp >> (32 - SINE_TABLE_SIZE_IN_BITS)];
+
+ /* increment operator phase */
+ phase += phaseInc;
+
+ /* internal gain for modulation effects */
+ temp = FMUL_15x15(temp, (gain >> 16));
+
+ /* output gain calculation */
+ temp2 = FMUL_15x15(temp, p->outputGain);
+
+ /* saturating add to buffer */
+ if (mix)
+ {
+ temp2 += *pBuffer;
+ *pBuffer++ = FM_Saturate(temp2);
+ }
+
+ /* output to buffer */
+ else
+ *pBuffer++ = (EAS_I16) temp2;
+
+ /* increment gain */
+ gain += gainInc;
+
+ }
+
+ /* save phase and gain */
+ p->phase = phase;
+ p->gain = gainTarget;
+
+ /* save last output for feedback in next frame */
+ if (pLastOutput)
+ *pLastOutput = (EAS_I16) temp;
+}
+
+/*----------------------------------------------------------------------------
+ * FM_NoiseOperator()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Synthesizes a buffer of samples based on passed parameters.
+ *
+ * Inputs:
+ * nNumSamplesToAdd - number of samples to synthesize
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+void FM_NoiseOperator (
+ S_FM_ENG_OPER *p,
+ EAS_I32 numSamplesToAdd,
+ EAS_PCM *pBuffer,
+ EAS_BOOL mix,
+ EAS_U16 gainTarget,
+ EAS_U8 feedback,
+ EAS_I16 *pLastOutput)
+{
+ EAS_I32 gain;
+ EAS_I32 gainInc;
+ EAS_U32 phase;
+ EAS_I32 temp;
+ EAS_I32 temp2;
+
+ /* establish local gain variable */
+ gain = (EAS_I32) p->gain << 16;
+
+ /* calculate gain increment */
+ /*lint -e{703} use shift for performance */
+ gainInc = ((EAS_I32) gainTarget - (EAS_I32) p->gain) << (16 - SYNTH_UPDATE_PERIOD_IN_BITS);
+
+ /* establish local phase variables */
+ phase = p->phase;
+
+ /* establish local phase variables */
+ phase = p->phase;
+
+ /* recall last sample for filter Z-1 term */
+ temp = 0;
+ if (pLastOutput)
+ temp = *pLastOutput;
+
+ /* generate a buffer of samples */
+ while (numSamplesToAdd--)
+ {
+
+ /* if using filter */
+ if (pLastOutput)
+ {
+ /* use PRNG for noise */
+ temp2 = FM_Noise(&phase);
+
+ /*lint -e{704} use shift for performance */
+ temp += ((temp2 -temp) * feedback) >> 8;
+ }
+ else
+ {
+ temp = FM_Noise(&phase);
+ }
+
+ /* internal gain for modulation effects */
+ temp2 = FMUL_15x15(temp, (gain >> 16));
+
+ /* output gain calculation */
+ temp2 = FMUL_15x15(temp2, p->outputGain);
+
+ /* saturating add to buffer */
+ if (mix)
+ {
+ temp2 += *pBuffer;
+ *pBuffer++ = FM_Saturate(temp2);
+ }
+
+ /* output to buffer */
+ else
+ *pBuffer++ = (EAS_I16) temp2;
+
+ /* increment gain */
+ gain += gainInc;
+
+ }
+
+ /* save phase and gain */
+ p->phase = phase;
+ p->gain = gainTarget;
+
+ /* save last output for feedback in next frame */
+ if (pLastOutput)
+ *pLastOutput = (EAS_I16) temp;
+}
+
+/*----------------------------------------------------------------------------
+ * FM_ConfigVoice()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Receives parameters to start a new voice.
+ *
+ * Inputs:
+ * voiceNum - voice number to start
+ * vCfg - configuration data
+ * pMixBuffer - pointer to host supplied buffer
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ *
+ * Notes:
+ * pFrameBuffer is not used in the test version, but is passed as a
+ * courtesy to split architecture implementations. It can be used as
+ * as pointer to the interprocessor communications buffer when the
+ * synthesis parameters are passed off to a DSP for synthesis.
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pFrameBuffer) pFrameBuffer not used in test version - see above */
+void FM_ConfigVoice (EAS_I32 voiceNum, S_FM_VOICE_CONFIG *vCfg, EAS_FRAME_BUFFER_HANDLE pFrameBuffer)
+{
+ S_FM_ENG_VOICE *pVoice;
+ EAS_INT i;
+
+ /* establish pointer to voice data */
+ pVoice = &voices[voiceNum];
+
+ /* save data */
+ pVoice->feedback = vCfg->feedback;
+ pVoice->flags = vCfg->flags;
+ pVoice->voiceGain = vCfg->voiceGain;
+
+ /* initialize Z-1 terms */
+ pVoice->op1Out = 0;
+ pVoice->op3Out = 0;
+
+ /* initialize operators */
+ for (i = 0; i < 4; i++)
+ {
+ /* save operator data */
+ pVoice->oper[i].gain = vCfg->gain[i];
+ pVoice->oper[i].outputGain = vCfg->outputGain[i];
+ pVoice->oper[i].outputGain = vCfg->outputGain[i];
+
+ /* initalize operator */
+ pVoice->oper[i].phase = 0;
+ }
+
+ /* calculate pan */
+#if NUM_OUTPUT_CHANNELS == 2
+ FM_CalculatePan(vCfg->pan, &pVoice->gainLeft, &pVoice->gainRight);
+#endif
+}
+
+/*----------------------------------------------------------------------------
+ * FM_ProcessVoice()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Synthesizes a buffer of samples based on calculated parameters.
+ *
+ * Inputs:
+ * nNumSamplesToAdd - number of samples to synthesize
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ *
+ * Notes:
+ * pOut is not used in the test version, but is passed as a
+ * courtesy to split architecture implementations. It can be used as
+ * as pointer to the interprocessor communications buffer when the
+ * synthesis parameters are passed off to a DSP for synthesis.
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pOut) pOut not used in test version - see above */
+void FM_ProcessVoice (
+ EAS_I32 voiceNum,
+ S_FM_VOICE_FRAME *pFrame,
+ EAS_I32 numSamplesToAdd,
+ EAS_PCM *pTempBuffer,
+ EAS_PCM *pBuffer,
+ EAS_I32 *pMixBuffer,
+ EAS_FRAME_BUFFER_HANDLE pFrameBuffer)
+{
+ S_FM_ENG_VOICE *p;
+ EAS_PCM *pOutBuf;
+ EAS_PCM *pMod;
+ EAS_BOOL mix;
+ EAS_U8 feedback1;
+ EAS_U8 feedback3;
+ EAS_U8 mode;
+
+ /* establish pointer to voice data */
+ p = &voices[voiceNum];
+ mode = p->flags & 0x07;
+
+ /* lookup feedback values */
+ feedback1 = fmScaleTable[p->feedback >> 4];
+ feedback3 = fmScaleTable[p->feedback & 0x0f];
+
+ /* operator 3 is on output bus in modes 0, 1, and 3 */
+ if ((mode == 0) || (mode == 1) || (mode == 3))
+ pOutBuf = pBuffer;
+ else
+ pOutBuf = pTempBuffer;
+
+ if (p->flags & FLAG_FM_ENG_VOICE_OP3_NOISE)
+ {
+ FM_NoiseOperator(
+ p->oper + 2,
+ numSamplesToAdd,
+ pOutBuf,
+ EAS_FALSE,
+ pFrame->gain[2],
+ feedback3,
+ &p->op3Out);
+ }
+ else
+ {
+ FM_Operator(
+ p->oper + 2,
+ numSamplesToAdd,
+ pOutBuf,
+ 0,
+ EAS_FALSE,
+ pFrame->gain[2],
+ pFrame->pitch[2],
+ feedback3,
+ &p->op3Out);
+ }
+
+ /* operator 4 is on output bus in modes 0, 1, and 2 */
+ if (mode < 3)
+ pOutBuf = pBuffer;
+ else
+ pOutBuf = pTempBuffer;
+
+ /* operator 4 is modulated in modes 2, 4, and 5 */
+ if ((mode == 2) || (mode == 4) || (mode == 5))
+ pMod = pTempBuffer;
+ else
+ pMod = 0;
+
+ /* operator 4 is in mix mode in modes 0 and 1 */
+ mix = (mode < 2);
+
+ if (p->flags & FLAG_FM_ENG_VOICE_OP4_NOISE)
+ {
+ FM_NoiseOperator(
+ p->oper + 3,
+ numSamplesToAdd,
+ pOutBuf,
+ mix,
+ pFrame->gain[3],
+ 0,
+ 0);
+ }
+ else
+ {
+ FM_Operator(
+ p->oper + 3,
+ numSamplesToAdd,
+ pOutBuf,
+ pMod,
+ mix,
+ pFrame->gain[3],
+ pFrame->pitch[3],
+ 0,
+ 0);
+ }
+
+ /* operator 1 is on output bus in mode 0 */
+ if (mode == 0)
+ pOutBuf = pBuffer;
+ else
+ pOutBuf = pTempBuffer;
+
+ /* operator 1 is modulated in modes 3 and 4 */
+ if ((mode == 3) || (mode == 4))
+ pMod = pTempBuffer;
+ else
+ pMod = 0;
+
+ /* operator 1 is in mix mode in modes 0 and 5 */
+ mix = ((mode == 0) || (mode == 5));
+
+ if (p->flags & FLAG_FM_ENG_VOICE_OP1_NOISE)
+ {
+ FM_NoiseOperator(
+ p->oper,
+ numSamplesToAdd,
+ pOutBuf,
+ mix,
+ pFrame->gain[0],
+ feedback1,
+ &p->op1Out);
+ }
+ else
+ {
+ FM_Operator(
+ p->oper,
+ numSamplesToAdd,
+ pOutBuf,
+ pMod,
+ mix,
+ pFrame->gain[0],
+ pFrame->pitch[0],
+ feedback1,
+ &p->op1Out);
+ }
+
+ /* operator 2 is modulated in all modes except 0 */
+ if (mode != 0)
+ pMod = pTempBuffer;
+ else
+ pMod = 0;
+
+ /* operator 1 is in mix mode in modes 0 -3 */
+ mix = (mode < 4);
+
+ if (p->flags & FLAG_FM_ENG_VOICE_OP2_NOISE)
+ {
+ FM_NoiseOperator(
+ p->oper + 1,
+ numSamplesToAdd,
+ pBuffer,
+ mix,
+ pFrame->gain[1],
+ 0,
+ 0);
+ }
+ else
+ {
+ FM_Operator(
+ p->oper + 1,
+ numSamplesToAdd,
+ pBuffer,
+ pMod,
+ mix,
+ pFrame->gain[1],
+ pFrame->pitch[1],
+ 0,
+ 0);
+ }
+
+ /* mix voice output to synthesizer output buffer */
+ FM_SynthMixVoice(p, pFrame->voiceGain, numSamplesToAdd, pBuffer, pMixBuffer);
+}
+
+/*----------------------------------------------------------------------------
+ * FM_SynthMixVoice()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Mixes the voice output buffer into the final mix using an anti-zipper
+ * filter.
+ *
+ * Inputs:
+ * nNumSamplesToAdd - number of samples to synthesize
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+void FM_SynthMixVoice(S_FM_ENG_VOICE *p, EAS_U16 nGainTarget, EAS_I32 numSamplesToAdd, EAS_PCM *pInputBuffer, EAS_I32 *pBuffer)
+{
+ EAS_I32 nGain;
+ EAS_I32 nGainInc;
+ EAS_I32 nTemp;
+
+ /* restore previous gain */
+ /*lint -e{703} <use shift for performance> */
+ nGain = (EAS_I32) p->voiceGain << 16;
+
+ /* calculate gain increment */
+ /*lint -e{703} <use shift for performance> */
+ nGainInc = ((EAS_I32) nGainTarget - (EAS_I32) p->voiceGain) << (16 - SYNTH_UPDATE_PERIOD_IN_BITS);
+
+ /* mix the output buffer */
+ while (numSamplesToAdd--)
+ {
+ /* output gain calculation */
+ nTemp = *pInputBuffer++;
+
+ /* sum to output buffer */
+#if (NUM_OUTPUT_CHANNELS == 2)
+
+ /*lint -e{704} <use shift for performance> */
+ nTemp = ((EAS_I32) nTemp * (nGain >> 16)) >> FM_GAIN_SHIFT;
+
+ /*lint -e{704} <use shift for performance> */
+ {
+ EAS_I32 nTemp2;
+ nTemp = nTemp >> FM_STEREO_PRE_GAIN_SHIFT;
+ nTemp2 = (nTemp * p->gainLeft) >> FM_STEREO_POST_GAIN_SHIFT;
+ *pBuffer++ += nTemp2;
+ nTemp2 = (nTemp * p->gainRight) >> FM_STEREO_POST_GAIN_SHIFT;
+ *pBuffer++ += nTemp2;
+ }
+#else
+ /*lint -e{704} <use shift for performance> */
+ nTemp = ((EAS_I32) nTemp * (nGain >> 16)) >> FM_MONO_GAIN_SHIFT;
+ *pBuffer++ += nTemp;
+#endif
+
+ /* increment gain for anti-zipper filter */
+ nGain += nGainInc;
+ }
+
+ /* save gain */
+ p->voiceGain = nGainTarget;
+}
+
diff --git a/arm-hybrid-22k/lib_src/eas_fmengine.h b/arm-hybrid-22k/lib_src/eas_fmengine.h
index 4ddc12b..dd248f8 100644
--- a/arm-hybrid-22k/lib_src/eas_fmengine.h
+++ b/arm-hybrid-22k/lib_src/eas_fmengine.h
@@ -1,12 +1,12 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_fmengine.h
- *
- * Contents and purpose:
- * Declarations, interfaces, and prototypes for FM synthesize low-level.
- *
- * Copyright Sonic Network Inc. 2004
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_fmengine.h
+ *
+ * Contents and purpose:
+ * Declarations, interfaces, and prototypes for FM synthesize low-level.
+ *
+ * Copyright Sonic Network Inc. 2004
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,103 +19,103 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 664 $
- * $Date: 2007-04-25 13:11:22 -0700 (Wed, 25 Apr 2007) $
- *----------------------------------------------------------------------------
-*/
-
-/* sentinel */
-#ifndef _FMENGINE_H
-#define _FMENGINE_H
-
-/* check for split architecture */
-#if defined (EAS_SPLIT_HYBRID_SYNTH) || defined(EAS_SPLIT_FM_SYNTH)
-#define FM_OFFBOARD
-#endif
-
-/* output level to mix buffer (3 = -24dB) */
-#define FM_GAIN_SHIFT 3
-#define FM_MONO_GAIN_SHIFT 9
-
-/* voice output level for stereo 15 = +6dB */
-#define FM_STEREO_PRE_GAIN_SHIFT 11
-#define FM_STEREO_POST_GAIN_SHIFT 10
-
-/* modulator input level shift (21 = -30dB) */
-#define FM_MODULATOR_INPUT_SHIFT 21
-
-/* feedback control level shift (7 = 0dB) */
-#define FM_FEEDBACK_SHIFT 7
-
-/* synth final output level */
-#define SYNTH_POST_GAIN_SHIFT 14
-
-/* LFO modulation to gain control */
-#define FM_LFO_GAIN_SHIFT 12
-
-/* sine table is always a power of 2 - saves cycles in inner loop */
-#define SINE_TABLE_SIZE_IN_BITS 11
-#define SINE_TABLE_SIZE 2048
-
-/* operator structure for FM engine */
-typedef struct
-{
- EAS_U32 phase; /* current waveform phase */
- EAS_U16 gain; /* current internal gain */
- EAS_U16 outputGain; /* current output gain */
-} S_FM_ENG_OPER;
-
-typedef struct
-{
- S_FM_ENG_OPER oper[4]; /* operator data */
- EAS_I16 op1Out; /* op1 output for feedback loop */
- EAS_I16 op3Out; /* op3 output for feedback loop */
- EAS_U16 voiceGain; /* LFO + channel parameters */
-#if (NUM_OUTPUT_CHANNELS == 2)
- EAS_U16 gainLeft; /* left gain multiplier */
- EAS_U16 gainRight; /* right gain multiplier */
-#endif
- EAS_U8 flags; /* mode bits and noise waveform flags */
- EAS_U8 feedback; /* feedback for Op1 and Op3 */
-} S_FM_ENG_VOICE;
-
-typedef struct
-{
- EAS_U16 gain[4]; /* initial operator gain value */
- EAS_U16 outputGain[4]; /* initial operator output gain value */
- EAS_U16 voiceGain; /* initial voice gain */
- EAS_U8 flags; /* mode bits and noise waveform flags */
- EAS_U8 feedback; /* feedback for Op1 and Op3 */
-#if (NUM_OUTPUT_CHANNELS == 2)
- EAS_I8 pan; /* pan value +/-64 */
-#endif
-} S_FM_VOICE_CONFIG;
-
-typedef struct
-{
- EAS_U16 gain[4]; /* new operator gain value */
- EAS_I16 pitch[4]; /* new pitch value */
- EAS_U16 voiceGain; /* new voice gain */
-} S_FM_VOICE_FRAME;
-
-/* bit definitions for S_FM_ENG_VOICE.flags */
-#define FLAG_FM_ENG_VOICE_OP1_NOISE 0x10 /* operator 1 source is PRNG */
-#define FLAG_FM_ENG_VOICE_OP2_NOISE 0x20 /* operator 2 source is PRNG */
-#define FLAG_FM_ENG_VOICE_OP3_NOISE 0x40 /* operator 3 source is PRNG */
-#define FLAG_FM_ENG_VOICE_OP4_NOISE 0x80 /* operator 4 source is PRNG */
-
-#ifdef FM_OFFBOARD
-extern EAS_BOOL FM_StartFrame (EAS_FRAME_BUFFER_HANDLE pFrameBuffer);
-extern EAS_BOOL FM_EndFrame (EAS_FRAME_BUFFER_HANDLE pFrameBuffe, EAS_I32 *pMixBuffer, EAS_I16 masterGain);
-#endif
-
-/* FM engine prototypes */
-extern void FM_ConfigVoice (EAS_I32 voiceNum, S_FM_VOICE_CONFIG *vCfg, EAS_FRAME_BUFFER_HANDLE pFrameBuffer);
-extern void FM_ProcessVoice (EAS_I32 voiceNum, S_FM_VOICE_FRAME *pFrame, EAS_I32 numSamplesToAdd, EAS_PCM *pTempBuffer, EAS_PCM *pBuffer, EAS_I32 *pMixBuffer, EAS_FRAME_BUFFER_HANDLE pFrameBuffer);
-
-#endif
-/* #ifndef _FMENGINE_H */
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 664 $
+ * $Date: 2007-04-25 13:11:22 -0700 (Wed, 25 Apr 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+/* sentinel */
+#ifndef _FMENGINE_H
+#define _FMENGINE_H
+
+/* check for split architecture */
+#if defined (EAS_SPLIT_HYBRID_SYNTH) || defined(EAS_SPLIT_FM_SYNTH)
+#define FM_OFFBOARD
+#endif
+
+/* output level to mix buffer (3 = -24dB) */
+#define FM_GAIN_SHIFT 3
+#define FM_MONO_GAIN_SHIFT 9
+
+/* voice output level for stereo 15 = +6dB */
+#define FM_STEREO_PRE_GAIN_SHIFT 11
+#define FM_STEREO_POST_GAIN_SHIFT 10
+
+/* modulator input level shift (21 = -30dB) */
+#define FM_MODULATOR_INPUT_SHIFT 21
+
+/* feedback control level shift (7 = 0dB) */
+#define FM_FEEDBACK_SHIFT 7
+
+/* synth final output level */
+#define SYNTH_POST_GAIN_SHIFT 14
+
+/* LFO modulation to gain control */
+#define FM_LFO_GAIN_SHIFT 12
+
+/* sine table is always a power of 2 - saves cycles in inner loop */
+#define SINE_TABLE_SIZE_IN_BITS 11
+#define SINE_TABLE_SIZE 2048
+
+/* operator structure for FM engine */
+typedef struct
+{
+ EAS_U32 phase; /* current waveform phase */
+ EAS_U16 gain; /* current internal gain */
+ EAS_U16 outputGain; /* current output gain */
+} S_FM_ENG_OPER;
+
+typedef struct
+{
+ S_FM_ENG_OPER oper[4]; /* operator data */
+ EAS_I16 op1Out; /* op1 output for feedback loop */
+ EAS_I16 op3Out; /* op3 output for feedback loop */
+ EAS_U16 voiceGain; /* LFO + channel parameters */
+#if (NUM_OUTPUT_CHANNELS == 2)
+ EAS_U16 gainLeft; /* left gain multiplier */
+ EAS_U16 gainRight; /* right gain multiplier */
+#endif
+ EAS_U8 flags; /* mode bits and noise waveform flags */
+ EAS_U8 feedback; /* feedback for Op1 and Op3 */
+} S_FM_ENG_VOICE;
+
+typedef struct
+{
+ EAS_U16 gain[4]; /* initial operator gain value */
+ EAS_U16 outputGain[4]; /* initial operator output gain value */
+ EAS_U16 voiceGain; /* initial voice gain */
+ EAS_U8 flags; /* mode bits and noise waveform flags */
+ EAS_U8 feedback; /* feedback for Op1 and Op3 */
+#if (NUM_OUTPUT_CHANNELS == 2)
+ EAS_I8 pan; /* pan value +/-64 */
+#endif
+} S_FM_VOICE_CONFIG;
+
+typedef struct
+{
+ EAS_U16 gain[4]; /* new operator gain value */
+ EAS_I16 pitch[4]; /* new pitch value */
+ EAS_U16 voiceGain; /* new voice gain */
+} S_FM_VOICE_FRAME;
+
+/* bit definitions for S_FM_ENG_VOICE.flags */
+#define FLAG_FM_ENG_VOICE_OP1_NOISE 0x10 /* operator 1 source is PRNG */
+#define FLAG_FM_ENG_VOICE_OP2_NOISE 0x20 /* operator 2 source is PRNG */
+#define FLAG_FM_ENG_VOICE_OP3_NOISE 0x40 /* operator 3 source is PRNG */
+#define FLAG_FM_ENG_VOICE_OP4_NOISE 0x80 /* operator 4 source is PRNG */
+
+#ifdef FM_OFFBOARD
+extern EAS_BOOL FM_StartFrame (EAS_FRAME_BUFFER_HANDLE pFrameBuffer);
+extern EAS_BOOL FM_EndFrame (EAS_FRAME_BUFFER_HANDLE pFrameBuffe, EAS_I32 *pMixBuffer, EAS_I16 masterGain);
+#endif
+
+/* FM engine prototypes */
+extern void FM_ConfigVoice (EAS_I32 voiceNum, S_FM_VOICE_CONFIG *vCfg, EAS_FRAME_BUFFER_HANDLE pFrameBuffer);
+extern void FM_ProcessVoice (EAS_I32 voiceNum, S_FM_VOICE_FRAME *pFrame, EAS_I32 numSamplesToAdd, EAS_PCM *pTempBuffer, EAS_PCM *pBuffer, EAS_I32 *pMixBuffer, EAS_FRAME_BUFFER_HANDLE pFrameBuffer);
+
+#endif
+/* #ifndef _FMENGINE_H */
+
diff --git a/arm-hybrid-22k/lib_src/eas_fmsynth.c b/arm-hybrid-22k/lib_src/eas_fmsynth.c
index 83f0087..629506a 100644
--- a/arm-hybrid-22k/lib_src/eas_fmsynth.c
+++ b/arm-hybrid-22k/lib_src/eas_fmsynth.c
@@ -1,12 +1,12 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * fmsynth.c
- *
- * Contents and purpose:
- * Implements the high-level FM synthesizer functions.
- *
- * Copyright Sonic Network Inc. 2004
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * fmsynth.c
+ *
+ * Contents and purpose:
+ * Implements the high-level FM synthesizer functions.
+ *
+ * Copyright Sonic Network Inc. 2004
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,892 +19,892 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 795 $
- * $Date: 2007-08-01 00:14:45 -0700 (Wed, 01 Aug 2007) $
- *----------------------------------------------------------------------------
-*/
-
-// includes
-#include "eas_host.h"
-#include "eas_report.h"
-
-#include "eas_data.h"
-#include "eas_synth_protos.h"
-#include "eas_audioconst.h"
-#include "eas_fmengine.h"
-#include "eas_math.h"
-
-/* option sanity check */
-#ifdef _REVERB
-#error "No reverb for FM synthesizer"
-#endif
-#ifdef _CHORUS
-#error "No chorus for FM synthesizer"
-#endif
-
-/*
- * WARNING: These macros can cause unwanted side effects. Use them
- * with care. For example, min(x++,y++) will cause either x or y to be
- * incremented twice.
- */
-#define min(a,b) ((a) < (b) ? (a) : (b))
-#define max(a,b) ((a) > (b) ? (a) : (b))
-
-/* pivot point for keyboard scalars */
-#define EG_SCALE_PIVOT_POINT 64
-#define KEY_SCALE_PIVOT_POINT 36
-
-/* This number is the negative of the frequency of the note (in cents) of
- * the sine wave played at unity. The number can be calculated as follows:
- *
- * MAGIC_NUMBER = 1200 * log(base2) (SINE_TABLE_SIZE * 8.175798916 / SAMPLE_RATE)
- *
- * 8.17578 is a reference to the frequency of MIDI note 0
- */
-#if defined (_SAMPLE_RATE_8000)
-#define MAGIC_NUMBER 1279
-#elif defined (_SAMPLE_RATE_16000)
-#define MAGIC_NUMBER 79
-#elif defined (_SAMPLE_RATE_20000)
-#define MAGIC_NUMBER -308
-#elif defined (_SAMPLE_RATE_22050)
-#define MAGIC_NUMBER -477
-#elif defined (_SAMPLE_RATE_24000)
-#define MAGIC_NUMBER -623
-#elif defined (_SAMPLE_RATE_32000)
-#define MAGIC_NUMBER -1121
-#elif defined (_SAMPLE_RATE_44100)
-#define MAGIC_NUMBER -1677
-#elif defined (_SAMPLE_RATE_48000)
-#define MAGIC_NUMBER -1823
-#endif
-
-/* externs */
-extern const EAS_I16 fmControlTable[128];
-extern const EAS_U16 fmRateTable[256];
-extern const EAS_U16 fmAttackTable[16];
-extern const EAS_U8 fmDecayTable[16];
-extern const EAS_U8 fmReleaseTable[16];
-extern const EAS_U8 fmScaleTable[16];
-
-/* local prototypes */
-/*lint -esym(715, pVoiceMgr) standard synthesizer interface - pVoiceMgr not used */
-static EAS_RESULT FM_Initialize (S_VOICE_MGR *pVoiceMgr) { return EAS_SUCCESS; }
-static EAS_RESULT FM_StartVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, EAS_I32 voiceNum, EAS_U16 regionIndex);
-static EAS_BOOL FM_UpdateVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, EAS_I32 voiceNum, EAS_I32 *pMixBuffer, EAS_I32 numSamples);
-static void FM_ReleaseVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, EAS_I32 voiceNum);
-static void FM_MuteVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, EAS_I32 voiceNum);
-static void FM_SustainPedal (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, S_SYNTH_CHANNEL *pChannel, EAS_I32 voiceNum);
-static void FM_UpdateChannel (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel);
-
-
-/*----------------------------------------------------------------------------
- * Synthesizer interface
- *----------------------------------------------------------------------------
-*/
-const S_SYNTH_INTERFACE fmSynth =
-{
- FM_Initialize,
- FM_StartVoice,
- FM_UpdateVoice,
- FM_ReleaseVoice,
- FM_MuteVoice,
- FM_SustainPedal,
- FM_UpdateChannel
-};
-
-#ifdef FM_OFFBOARD
-const S_FRAME_INTERFACE fmFrameInterface =
-{
- FM_StartFrame,
- FM_EndFrame
-};
-#endif
-
-/*----------------------------------------------------------------------------
- * inline functions
- *----------------------------------------------------------------------------
- */
-EAS_INLINE S_FM_VOICE *GetFMVoicePtr (S_VOICE_MGR *pVoiceMgr, EAS_INT voiceNum)
-{
- return &pVoiceMgr->fmVoices[voiceNum];
-}
-EAS_INLINE S_SYNTH_CHANNEL *GetChannelPtr (S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice)
-{
- return &pSynth->channels[pVoice->channel & 15];
-}
-EAS_INLINE const S_FM_REGION *GetFMRegionPtr (S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice)
-{
-#ifdef _SECONDARY_SYNTH
- return &pSynth->pEAS->pFMRegions[pVoice->regionIndex & REGION_INDEX_MASK];
-#else
- return &pSynth->pEAS->pFMRegions[pVoice->regionIndex];
-#endif
-}
-
-/*----------------------------------------------------------------------------
- * FM_SynthIsOutputOperator
- *----------------------------------------------------------------------------
- * Purpose:
- * Returns true if the operator is a direct output and not muted
- *
- * Inputs:
- *
- * Outputs:
- * Returns boolean
- *----------------------------------------------------------------------------
-*/
-static EAS_BOOL FM_SynthIsOutputOperator (const S_FM_REGION *pRegion, EAS_INT operIndex)
-{
-
- /* see if voice is muted */
- if ((pRegion->oper[operIndex].gain & 0xfc) == 0)
- return 0;
-
- /* check based on mode */
- switch (pRegion->region.keyGroupAndFlags & 7)
- {
-
- /* mode 0 - all operators are external */
- case 0:
- return EAS_TRUE;
-
- /* mode 1 - operators 1-3 are external */
- case 1:
- if (operIndex != 0)
- return EAS_TRUE;
- break;
-
- /* mode 2 - operators 1 & 3 are external */
- case 2:
- if ((operIndex == 1) || (operIndex == 3))
- return EAS_TRUE;
- break;
-
- /* mode 2 - operators 1 & 2 are external */
- case 3:
- if ((operIndex == 1) || (operIndex == 2))
- return EAS_TRUE;
- break;
-
- /* modes 4 & 5 - operator 1 is external */
- case 4:
- case 5:
- if (operIndex == 1)
- return EAS_TRUE;
- break;
-
- default:
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_FATAL,"Invalid voice mode: %d",
- pRegion->region.keyGroupAndFlags & 7); */ }
- }
-
- return EAS_FALSE;
-}
-
-/*----------------------------------------------------------------------------
- * FM_CalcEGRate()
- *----------------------------------------------------------------------------
- * Purpose:
- *
- * Inputs:
- * nKeyNumber - MIDI note
- * nLogRate - logarithmic scale rate from patch data
- * nKeyScale - key scaling factor for this EG
- *
- * Outputs:
- * 16-bit linear multiplier
- *----------------------------------------------------------------------------
-*/
-
-static EAS_U16 FM_CalcEGRate (EAS_U8 nKeyNumber, EAS_U8 nLogRate, EAS_U8 nEGScale)
-{
- EAS_I32 temp;
-
- /* incorporate key scaling on release rate */
- temp = (EAS_I32) nLogRate << 7;
- temp += ((EAS_I32) nKeyNumber - EG_SCALE_PIVOT_POINT) * (EAS_I32) nEGScale;
-
- /* saturate */
- temp = max(temp, 0);
- temp = min(temp, 32767);
-
- /* look up in rate table */
- /*lint -e{704} use shift for performance */
- return fmRateTable[temp >> 8];
-}
-
-/*----------------------------------------------------------------------------
- * FM_ReleaseVoice()
- *----------------------------------------------------------------------------
- * Purpose:
- * The selected voice is being released.
- *
- * Inputs:
- * psEASData - pointer to S_EAS_DATA
- * pVoice - pointer to voice to release
- *
- * Outputs:
- * None
- *----------------------------------------------------------------------------
-*/
-static void FM_ReleaseVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, EAS_I32 voiceNum)
-{
- EAS_INT operIndex;
- const S_FM_REGION *pRegion;
- S_FM_VOICE *pFMVoice;
-
- /* check to see if voice responds to NOTE-OFF's */
- pRegion = GetFMRegionPtr(pSynth, pVoice);
- if (pRegion->region.keyGroupAndFlags & REGION_FLAG_ONE_SHOT)
- return;
-
- /* set all envelopes to release state */
- pFMVoice = GetFMVoicePtr(pVoiceMgr, voiceNum);
- for (operIndex = 0; operIndex < 4; operIndex++)
- {
- pFMVoice->oper[operIndex].envState = eFMEnvelopeStateRelease;
-
- /* incorporate key scaling on release rate */
- pFMVoice->oper[operIndex].envRate = FM_CalcEGRate(
- pVoice->note,
- fmReleaseTable[pRegion->oper[operIndex].velocityRelease & 0x0f],
- fmScaleTable[pRegion->oper[operIndex].egKeyScale >> 4]);
- } /* end for (operIndex = 0; operIndex < 4; operIndex++) */
-}
-
-/*----------------------------------------------------------------------------
- * FM_MuteVoice()
- *----------------------------------------------------------------------------
- * Purpose:
- * The selected voice is being muted.
- *
- * Inputs:
- * pVoice - pointer to voice to release
- *
- * Outputs:
- * None
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, pSynth) standard interface, pVoiceMgr not used */
-static void FM_MuteVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, EAS_I32 voiceNum)
-{
- S_FM_VOICE *pFMVoice;
-
- /* clear deferred action flags */
- pVoice->voiceFlags &=
- ~(VOICE_FLAG_DEFER_MIDI_NOTE_OFF |
- VOICE_FLAG_SUSTAIN_PEDAL_DEFER_NOTE_OFF |
- VOICE_FLAG_DEFER_MUTE);
-
- /* set all envelopes to muted state */
- pFMVoice = GetFMVoicePtr(pVoiceMgr, voiceNum);
- pFMVoice->oper[0].envState = eFMEnvelopeStateMuted;
- pFMVoice->oper[1].envState = eFMEnvelopeStateMuted;
- pFMVoice->oper[2].envState = eFMEnvelopeStateMuted;
- pFMVoice->oper[3].envState = eFMEnvelopeStateMuted;
-}
-
-/*----------------------------------------------------------------------------
- * FM_SustainPedal()
- *----------------------------------------------------------------------------
- * Purpose:
- * The selected voice is held due to sustain pedal
- *
- * Inputs:
- * pVoice - pointer to voice to sustain
- *
- * Outputs:
- * None
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, pChannel) standard interface, pVoiceMgr not used */
-static void FM_SustainPedal (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, S_SYNTH_CHANNEL *pChannel, EAS_I32 voiceNum)
-{
- const S_FM_REGION *pRegion;
- S_FM_VOICE *pFMVoice;
- EAS_INT operIndex;
-
- pRegion = GetFMRegionPtr(pSynth, pVoice);
- pFMVoice = GetFMVoicePtr(pVoiceMgr, voiceNum);
-
- /* check to see if any envelopes are above the sustain level */
- for (operIndex = 0; operIndex < 4; operIndex++)
- {
-
- /* if level control or envelope gain is zero, skip this envelope */
- if (((pRegion->oper[operIndex].gain & 0xfc) == 0) ||
- (pFMVoice->oper[operIndex].envGain == 0))
- {
- continue;
- }
-
- /* if the envelope gain is above the sustain level, we need to catch this voice */
- if (pFMVoice->oper[operIndex].envGain >= ((EAS_U16) (pRegion->oper[operIndex].sustain & 0xfc) << 7))
- {
-
- /* reset envelope to decay state */
- pFMVoice->oper[operIndex].envState = eFMEnvelopeStateDecay;
-
- pFMVoice->oper[operIndex].envRate = FM_CalcEGRate(
- pVoice->note,
- fmDecayTable[pRegion->oper[operIndex].attackDecay & 0x0f],
- fmScaleTable[pRegion->oper[operIndex].egKeyScale >> 4]);
-
- /* set voice to decay state */
- pVoice->voiceState = eVoiceStatePlay;
-
- /* set sustain flag */
- pVoice->voiceFlags |= VOICE_FLAG_SUSTAIN_PEDAL_DEFER_NOTE_OFF;
- }
- } /* end for (operIndex = 0; operIndex < 4; operIndex++) */
-}
-
-/*----------------------------------------------------------------------------
- * FM_StartVoice()
- *----------------------------------------------------------------------------
- * Purpose:
- * Assign the region for the given instrument using the midi key number
- * and the RPN2 (coarse tuning) value. By using RPN2 as part of the
- * region selection process, we reduce the amount a given sample has
- * to be transposed by selecting the closest recorded root instead.
- *
- * This routine is the second half of SynthAssignRegion().
- * If the region was successfully found by SynthFindRegionIndex(),
- * then assign the region's parameters to the voice.
- *
- * Setup and initialize the following voice parameters:
- * m_nRegionIndex
- *
- * Inputs:
- * pVoice - ptr to the voice we have assigned for this channel
- * nRegionIndex - index of the region
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- * success - could find and assign the region for this voice's note otherwise
- * failure - could not find nor assign the region for this voice's note
- *
- * Side Effects:
- * psSynthObject->m_sVoice[].m_nRegionIndex is assigned
- * psSynthObject->m_sVoice[] parameters are assigned
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT FM_StartVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, EAS_I32 voiceNum, EAS_U16 regionIndex)
-{
- S_FM_VOICE *pFMVoice;
- S_SYNTH_CHANNEL *pChannel;
- const S_FM_REGION *pRegion;
- EAS_I32 temp;
- EAS_INT operIndex;
-
- /* establish pointers to data */
- pVoice->regionIndex = regionIndex;
- pFMVoice = GetFMVoicePtr(pVoiceMgr, voiceNum);
- pChannel = GetChannelPtr(pSynth, pVoice);
- pRegion = GetFMRegionPtr(pSynth, pVoice);
-
- /* update static channel parameters */
- if (pChannel->channelFlags & CHANNEL_FLAG_UPDATE_CHANNEL_PARAMETERS)
- FM_UpdateChannel(pVoiceMgr, pSynth, pVoice->channel & 15);
-
- /* init the LFO */
- pFMVoice->lfoValue = 0;
- pFMVoice->lfoPhase = 0;
- pFMVoice->lfoDelay = (EAS_U16) (fmScaleTable[pRegion->lfoFreqDelay & 0x0f] >> 1);
-
-#if (NUM_OUTPUT_CHANNELS == 2)
- /* calculate pan gain values only if stereo output */
- /* set up panning only at note start */
- temp = (EAS_I32) pChannel->pan - 64;
- temp += (EAS_I32) pRegion->pan;
- if (temp < -64)
- temp = -64;
- if (temp > 64)
- temp = 64;
- pFMVoice->pan = (EAS_I8) temp;
-#endif /* #if (NUM_OUTPUT_CHANNELS == 2) */
-
- /* no samples have been synthesized for this note yet */
- pVoice->voiceFlags = VOICE_FLAG_NO_SAMPLES_SYNTHESIZED_YET;
-
- /* initialize gain value for anti-zipper filter */
- pFMVoice->voiceGain = (EAS_I16) EAS_LogToLinear16(pChannel->staticGain);
- pFMVoice->voiceGain = (EAS_I16) FMUL_15x15(pFMVoice->voiceGain, pSynth->masterVolume);
-
- /* initialize the operators */
- for (operIndex = 0; operIndex < 4; operIndex++)
- {
-
- /* establish operator output gain level */
- /*lint -e{701} <use shift for performance> */
- pFMVoice->oper[operIndex].outputGain = EAS_LogToLinear16(((EAS_I16) (pRegion->oper[operIndex].gain & 0xfc) - 0xfc) << 7);
-
- /* check for linear velocity flag */
- /*lint -e{703} <use shift for performance> */
- if (pRegion->oper[operIndex].flags & FM_OPER_FLAG_LINEAR_VELOCITY)
- temp = (EAS_I32) (pVoice->velocity - 127) << 5;
- else
- temp = (EAS_I32) fmControlTable[pVoice->velocity];
-
- /* scale velocity */
- /*lint -e{704} use shift for performance */
- temp = (temp * (EAS_I32)(pRegion->oper[operIndex].velocityRelease & 0xf0)) >> 7;
-
- /* include key scalar */
- temp -= ((EAS_I32) pVoice->note - KEY_SCALE_PIVOT_POINT) * (EAS_I32) fmScaleTable[pRegion->oper[operIndex].egKeyScale & 0x0f];
-
- /* saturate */
- temp = min(temp, 0);
- temp = max(temp, -32768);
-
- /* save static gain parameters */
- pFMVoice->oper[operIndex].baseGain = (EAS_I16) EAS_LogToLinear16(temp);
-
- /* incorporate key scaling on decay rate */
- pFMVoice->oper[operIndex].envRate = FM_CalcEGRate(
- pVoice->note,
- fmDecayTable[pRegion->oper[operIndex].attackDecay & 0x0f],
- fmScaleTable[pRegion->oper[operIndex].egKeyScale >> 4]);
-
- /* if zero attack time, max out envelope and jump to decay state */
- if ((pRegion->oper[operIndex].attackDecay & 0xf0) == 0xf0)
- {
-
- /* start out envelope at max */
- pFMVoice->oper[operIndex].envGain = 0x7fff;
-
- /* set envelope to decay state */
- pFMVoice->oper[operIndex].envState = eFMEnvelopeStateDecay;
- }
-
- /* start envelope at zero and start in attack state */
- else
- {
- pFMVoice->oper[operIndex].envGain = 0;
- pFMVoice->oper[operIndex].envState = eFMEnvelopeStateAttack;
- }
- }
-
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * FM_UpdateChannel()
- *----------------------------------------------------------------------------
- * Purpose:
- * Calculate and assign static channel parameters
- * These values only need to be updated if one of the controller values
- * for this channel changes.
- * Called when CHANNEL_FLAG_UPDATE_CHANNEL_PARAMETERS flag is set.
- *
- * Inputs:
- * nChannel - channel to update
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- *
- * Side Effects:
- * - the given channel's static gain and static pitch are updated
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, pVoiceMgr) standard interface, pVoiceMgr not used */
-static void FM_UpdateChannel (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel)
-{
- S_SYNTH_CHANNEL *pChannel;
- EAS_I32 temp;
-
- pChannel = &pSynth->channels[channel];
-
- /* convert CC7 volume controller to log scale */
- temp = fmControlTable[pChannel->volume];
-
- /* incorporate CC11 expression controller */
- temp += fmControlTable[pChannel->expression];
-
- /* saturate */
- pChannel->staticGain = (EAS_I16) max(temp,-32768);
-
- /* calculate pitch bend */
- /*lint -e{703} <avoid multiply for performance>*/
- temp = (((EAS_I32)(pChannel->pitchBend) << 2) - 32768);
-
- temp = FMUL_15x15(temp, pChannel->pitchBendSensitivity);
-
- /* include "magic number" compensation for sample rate and lookup table size */
- temp += MAGIC_NUMBER;
-
- /* if this is not a drum channel, then add in the per-channel tuning */
- if (!(pChannel->channelFlags & CHANNEL_FLAG_RHYTHM_CHANNEL))
- temp += (pChannel->finePitch + (pChannel->coarsePitch * 100));
-
- /* save static pitch */
- pChannel->staticPitch = temp;
-
- /* Calculate LFO modulation depth */
- /* mod wheel to LFO depth */
- temp = FMUL_15x15(DEFAULT_LFO_MOD_WHEEL_TO_PITCH_CENTS,
- pChannel->modWheel << (NUM_EG1_FRAC_BITS -7));
-
- /* channel pressure to LFO depth */
- pChannel->lfoAmt = (EAS_I16) (temp +
- FMUL_15x15(DEFAULT_LFO_CHANNEL_PRESSURE_TO_PITCH_CENTS,
- pChannel->channelPressure << (NUM_EG1_FRAC_BITS -7)));
-
- /* clear update flag */
- pChannel->channelFlags &= ~CHANNEL_FLAG_UPDATE_CHANNEL_PARAMETERS;
- return;
-}
-
-/*----------------------------------------------------------------------------
- * FM_UpdateLFO()
- *----------------------------------------------------------------------------
- * Purpose:
- * Calculate the LFO for the given voice
- *
- * Inputs:
- * pVoice - ptr to the voice whose LFO we want to update
- * psEASData - pointer to overall EAS data structure - used for debug only
- *
- * Outputs:
- *
- * Side Effects:
- * - updates LFO values for the given voice
- *----------------------------------------------------------------------------
-*/
-static void FM_UpdateLFO (S_FM_VOICE *pFMVoice, const S_FM_REGION *pRegion)
-{
-
- /* increment the LFO phase if the delay time has elapsed */
- if (!pFMVoice->lfoDelay)
- {
- /*lint -e{701} <use shift for performance> */
- pFMVoice->lfoPhase = pFMVoice->lfoPhase + (EAS_U16) (-fmControlTable[((15 - (pRegion->lfoFreqDelay >> 4)) << 3) + 4]);
-
- /* square wave LFO? */
- if (pRegion->region.keyGroupAndFlags & REGION_FLAG_SQUARE_WAVE)
- pFMVoice->lfoValue = (EAS_I16)(pFMVoice->lfoPhase & 0x8000 ? -32767 : 32767);
-
- /* trick to get a triangle wave out of a sawtooth */
- else
- {
- pFMVoice->lfoValue = (EAS_I16) (pFMVoice->lfoPhase << 1);
- /*lint -e{502} <shortcut to turn sawtooth into sine wave> */
- if ((pFMVoice->lfoPhase > 0x3fff) && (pFMVoice->lfoPhase < 0xC000))
- pFMVoice->lfoValue = ~pFMVoice->lfoValue;
- }
- }
-
- /* still in delay */
- else
- pFMVoice->lfoDelay--;
-
- return;
-}
-
-/*----------------------------------------------------------------------------
- * FM_UpdateEG()
- *----------------------------------------------------------------------------
- * Purpose:
- * Calculate the synthesis parameters for an operator to be used during
- * the next buffer
- *
- * Inputs:
- * pVoice - pointer to the voice being updated
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_BOOL FM_UpdateEG (S_SYNTH_VOICE *pVoice, S_OPERATOR *pOper, const S_FM_OPER *pOperData, EAS_BOOL oneShot)
-{
- EAS_U32 temp;
- EAS_BOOL done;
-
- /* set flag assuming the envelope is not done */
- done = EAS_FALSE;
-
- /* take appropriate action based on state */
- switch (pOper->envState)
- {
-
- case eFMEnvelopeStateAttack:
-
- /* the envelope is linear during the attack, so add the value */
- temp = pOper->envGain + fmAttackTable[pOperData->attackDecay >> 4];
-
- /* check for end of attack */
- if (temp >= 0x7fff)
- {
- pOper->envGain = 0x7fff;
- pOper->envState = eFMEnvelopeStateDecay;
- }
- else
- pOper->envGain = (EAS_U16) temp;
- break;
-
- case eFMEnvelopeStateDecay:
-
- /* decay is exponential, multiply by decay rate */
- pOper->envGain = (EAS_U16) FMUL_15x15(pOper->envGain, pOper->envRate);
-
- /* check for sustain level reached */
- temp = (EAS_U32) (pOperData->sustain & 0xfc) << 7;
- if (pOper->envGain <= (EAS_U16) temp)
- {
- /* if this is a one-shot patch, go directly to release phase */
- if (oneShot)
- {
- pOper->envRate = FM_CalcEGRate(
- pVoice->note,
- fmReleaseTable[pOperData->velocityRelease & 0x0f],
- fmScaleTable[pOperData->egKeyScale >> 4]);
- pOper->envState = eFMEnvelopeStateRelease;
- }
-
- /* normal sustaining type */
- else
- {
- pOper->envGain = (EAS_U16) temp;
- pOper->envState = eFMEnvelopeStateSustain;
- }
- }
- break;
-
- case eFMEnvelopeStateSustain:
- pOper->envGain = (EAS_U16)((EAS_U16)(pOperData->sustain & 0xfc) << 7);
- break;
-
- case eFMEnvelopeStateRelease:
-
- /* release is exponential, multiply by release rate */
- pOper->envGain = (EAS_U16) FMUL_15x15(pOper->envGain, pOper->envRate);
-
- /* fully released */
- if (pOper->envGain == 0)
- {
- pOper->envGain = 0;
- pOper->envState = eFMEnvelopeStateMuted;
- done = EAS_TRUE;
- }
- break;
-
- case eFMEnvelopeStateMuted:
- pOper->envGain = 0;
- done = EAS_TRUE;
- break;
- default:
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_FATAL,"Invalid operator state: %d", pOper->envState); */ }
- } /* end switch (pOper->m_eState) */
-
- return done;
-}
-
-/*----------------------------------------------------------------------------
- * FM_UpdateDynamic()
- *----------------------------------------------------------------------------
- * Purpose:
- * Calculate the synthesis parameters for this voice that will be used to
- * synthesize the next buffer
- *
- * Inputs:
- * pVoice - pointer to the voice being updated
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- * Returns EAS_TRUE if voice will be fully ramped to zero at the end of
- * the next synthesized buffer.
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_BOOL FM_UpdateDynamic (S_SYNTH_VOICE *pVoice, S_FM_VOICE *pFMVoice, const S_FM_REGION *pRegion, S_SYNTH_CHANNEL *pChannel)
-{
- EAS_I32 temp;
- EAS_I32 pitch;
- EAS_I32 lfoPitch;
- EAS_INT operIndex;
- EAS_BOOL done;
-
- /* increment LFO phase */
- FM_UpdateLFO(pFMVoice, pRegion);
-
- /* base pitch in cents */
- pitch = pVoice->note * 100;
-
- /* LFO amount includes LFO depth from programming + channel dynamics */
- temp = (fmScaleTable[pRegion->vibTrem >> 4] >> 1) + pChannel->lfoAmt;
-
- /* multiply by LFO output to get final pitch modulation */
- lfoPitch = FMUL_15x15(pFMVoice->lfoValue, temp);
-
- /* flag to indicate this voice is done */
- done = EAS_TRUE;
-
- /* iterate through operators to establish parameters */
- for (operIndex = 0; operIndex < 4; operIndex++)
- {
- EAS_BOOL bTemp;
-
- /* set base phase increment for each operator */
- temp = pRegion->oper[operIndex].tuning +
- pChannel->staticPitch;
-
- /* add vibrato effect unless it is disabled for this operator */
- if ((pRegion->oper[operIndex].flags & FM_OPER_FLAG_NO_VIBRATO) == 0)
- temp += lfoPitch;
-
- /* if note is monotonic, bias to MIDI note 60 */
- if (pRegion->oper[operIndex].flags & FM_OPER_FLAG_MONOTONE)
- temp += 6000;
- else
- temp += pitch;
- pFMVoice->oper[operIndex].pitch = (EAS_I16) temp;
-
- /* calculate envelope, returns true if done */
- bTemp = FM_UpdateEG(pVoice, &pFMVoice->oper[operIndex], &pRegion->oper[operIndex], pRegion->region.keyGroupAndFlags & REGION_FLAG_ONE_SHOT);
-
- /* check if all output envelopes have completed */
- if (FM_SynthIsOutputOperator(pRegion, operIndex))
- done = done && bTemp;
- }
-
- return done;
-}
-
-/*----------------------------------------------------------------------------
- * FM_UpdateVoice()
- *----------------------------------------------------------------------------
- * Purpose:
- * Synthesize a block of samples for the given voice.
- *
- * Inputs:
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- * number of samples actually written to buffer
- *
- * Side Effects:
- * - samples are added to the presently free buffer
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_BOOL FM_UpdateVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, EAS_I32 voiceNum, EAS_I32 *pMixBuffer, EAS_I32 numSamples)
-{
- S_SYNTH_CHANNEL *pChannel;
- const S_FM_REGION *pRegion;
- S_FM_VOICE *pFMVoice;
- S_FM_VOICE_CONFIG vCfg;
- S_FM_VOICE_FRAME vFrame;
- EAS_I32 temp;
- EAS_INT oper;
- EAS_U16 voiceGainTarget;
- EAS_BOOL done;
-
- /* setup some pointers */
- pChannel = GetChannelPtr(pSynth, pVoice);
- pRegion = GetFMRegionPtr(pSynth, pVoice);
- pFMVoice = GetFMVoicePtr(pVoiceMgr, voiceNum);
-
- /* if the voice is just starting, get the voice configuration data */
- if (pVoice->voiceFlags & VOICE_FLAG_NO_SAMPLES_SYNTHESIZED_YET)
- {
-
- /* split architecture may limit the number of voice starts */
-#ifdef MAX_VOICE_STARTS
- if (pVoiceMgr->numVoiceStarts == MAX_VOICE_STARTS)
- return EAS_FALSE;
- pVoiceMgr->numVoiceStarts++;
-#endif
-
- /* get initial parameters */
- vCfg.feedback = pRegion->feedback;
- vCfg.voiceGain = (EAS_U16) pFMVoice->voiceGain;
-
-#if (NUM_OUTPUT_CHANNELS == 2)
- vCfg.pan = pFMVoice->pan;
-#endif
-
- /* get voice mode */
- vCfg.flags = pRegion->region.keyGroupAndFlags & 7;
-
- /* get operator parameters */
- for (oper = 0; oper < 4; oper++)
- {
- /* calculate initial gain */
- vCfg.gain[oper] = (EAS_U16) FMUL_15x15(pFMVoice->oper[oper].baseGain, pFMVoice->oper[oper].envGain);
- vCfg.outputGain[oper] = pFMVoice->oper[oper].outputGain;
-
- /* copy noise waveform flag */
- if (pRegion->oper[oper].flags & FM_OPER_FLAG_NOISE)
- vCfg.flags |= (EAS_U8) (FLAG_FM_ENG_VOICE_OP1_NOISE << oper);
- }
-
-#ifdef FM_OFFBOARD
- FM_ConfigVoice(voiceNum, &vCfg, pVoiceMgr->pFrameBuffer);
-#else
- FM_ConfigVoice(voiceNum, &vCfg, NULL);
-#endif
-
- /* clear startup flag */
- pVoice->voiceFlags &= ~VOICE_FLAG_NO_SAMPLES_SYNTHESIZED_YET;
- }
-
- /* calculate new synthesis parameters */
- done = FM_UpdateDynamic(pVoice, pFMVoice, pRegion, pChannel);
-
- /* calculate LFO gain modulation */
- /*lint -e{702} <use shift for performance> */
- temp = ((fmScaleTable[pRegion->vibTrem & 0x0f] >> 1) * pFMVoice->lfoValue) >> FM_LFO_GAIN_SHIFT;
-
- /* include channel gain */
- temp += pChannel->staticGain;
-
- /* -32768 or lower is infinite attenuation */
- if (temp < -32767)
- voiceGainTarget = 0;
-
- /* translate to linear gain multiplier */
- else
- voiceGainTarget = EAS_LogToLinear16(temp);
-
- /* include synth master volume */
- voiceGainTarget = (EAS_U16) FMUL_15x15(voiceGainTarget, pSynth->masterVolume);
-
- /* save target values for this frame */
- vFrame.voiceGain = voiceGainTarget;
-
- /* assume voice output is zero */
- pVoice->gain = 0;
-
- /* save operator targets for this frame */
- for (oper = 0; oper < 4; oper++)
- {
- vFrame.gain[oper] = (EAS_U16) FMUL_15x15(pFMVoice->oper[oper].baseGain, pFMVoice->oper[oper].envGain);
- vFrame.pitch[oper] = pFMVoice->oper[oper].pitch;
-
- /* use the highest output envelope level as the gain for the voice stealing algorithm */
- if (FM_SynthIsOutputOperator(pRegion, oper))
- pVoice->gain = max(pVoice->gain, (EAS_I16) vFrame.gain[oper]);
- }
-
- /* consider voice gain multiplier in calculating gain for stealing algorithm */
- pVoice->gain = (EAS_I16) FMUL_15x15(voiceGainTarget, pVoice->gain);
-
- /* synthesize samples */
-#ifdef FM_OFFBOARD
- FM_ProcessVoice(voiceNum, &vFrame, numSamples, pVoiceMgr->operMixBuffer, pVoiceMgr->voiceBuffer, pMixBuffer, pVoiceMgr->pFrameBuffer);
-#else
- FM_ProcessVoice(voiceNum, &vFrame, numSamples, pVoiceMgr->operMixBuffer, pVoiceMgr->voiceBuffer, pMixBuffer, NULL);
-#endif
-
- return done;
-}
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 795 $
+ * $Date: 2007-08-01 00:14:45 -0700 (Wed, 01 Aug 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+// includes
+#include "eas_host.h"
+#include "eas_report.h"
+
+#include "eas_data.h"
+#include "eas_synth_protos.h"
+#include "eas_audioconst.h"
+#include "eas_fmengine.h"
+#include "eas_math.h"
+
+/* option sanity check */
+#ifdef _REVERB
+#error "No reverb for FM synthesizer"
+#endif
+#ifdef _CHORUS
+#error "No chorus for FM synthesizer"
+#endif
+
+/*
+ * WARNING: These macros can cause unwanted side effects. Use them
+ * with care. For example, min(x++,y++) will cause either x or y to be
+ * incremented twice.
+ */
+#define min(a,b) ((a) < (b) ? (a) : (b))
+#define max(a,b) ((a) > (b) ? (a) : (b))
+
+/* pivot point for keyboard scalars */
+#define EG_SCALE_PIVOT_POINT 64
+#define KEY_SCALE_PIVOT_POINT 36
+
+/* This number is the negative of the frequency of the note (in cents) of
+ * the sine wave played at unity. The number can be calculated as follows:
+ *
+ * MAGIC_NUMBER = 1200 * log(base2) (SINE_TABLE_SIZE * 8.175798916 / SAMPLE_RATE)
+ *
+ * 8.17578 is a reference to the frequency of MIDI note 0
+ */
+#if defined (_SAMPLE_RATE_8000)
+#define MAGIC_NUMBER 1279
+#elif defined (_SAMPLE_RATE_16000)
+#define MAGIC_NUMBER 79
+#elif defined (_SAMPLE_RATE_20000)
+#define MAGIC_NUMBER -308
+#elif defined (_SAMPLE_RATE_22050)
+#define MAGIC_NUMBER -477
+#elif defined (_SAMPLE_RATE_24000)
+#define MAGIC_NUMBER -623
+#elif defined (_SAMPLE_RATE_32000)
+#define MAGIC_NUMBER -1121
+#elif defined (_SAMPLE_RATE_44100)
+#define MAGIC_NUMBER -1677
+#elif defined (_SAMPLE_RATE_48000)
+#define MAGIC_NUMBER -1823
+#endif
+
+/* externs */
+extern const EAS_I16 fmControlTable[128];
+extern const EAS_U16 fmRateTable[256];
+extern const EAS_U16 fmAttackTable[16];
+extern const EAS_U8 fmDecayTable[16];
+extern const EAS_U8 fmReleaseTable[16];
+extern const EAS_U8 fmScaleTable[16];
+
+/* local prototypes */
+/*lint -esym(715, pVoiceMgr) standard synthesizer interface - pVoiceMgr not used */
+static EAS_RESULT FM_Initialize (S_VOICE_MGR *pVoiceMgr) { return EAS_SUCCESS; }
+static EAS_RESULT FM_StartVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, EAS_I32 voiceNum, EAS_U16 regionIndex);
+static EAS_BOOL FM_UpdateVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, EAS_I32 voiceNum, EAS_I32 *pMixBuffer, EAS_I32 numSamples);
+static void FM_ReleaseVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, EAS_I32 voiceNum);
+static void FM_MuteVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, EAS_I32 voiceNum);
+static void FM_SustainPedal (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, S_SYNTH_CHANNEL *pChannel, EAS_I32 voiceNum);
+static void FM_UpdateChannel (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel);
+
+
+/*----------------------------------------------------------------------------
+ * Synthesizer interface
+ *----------------------------------------------------------------------------
+*/
+const S_SYNTH_INTERFACE fmSynth =
+{
+ FM_Initialize,
+ FM_StartVoice,
+ FM_UpdateVoice,
+ FM_ReleaseVoice,
+ FM_MuteVoice,
+ FM_SustainPedal,
+ FM_UpdateChannel
+};
+
+#ifdef FM_OFFBOARD
+const S_FRAME_INTERFACE fmFrameInterface =
+{
+ FM_StartFrame,
+ FM_EndFrame
+};
+#endif
+
+/*----------------------------------------------------------------------------
+ * inline functions
+ *----------------------------------------------------------------------------
+ */
+EAS_INLINE S_FM_VOICE *GetFMVoicePtr (S_VOICE_MGR *pVoiceMgr, EAS_INT voiceNum)
+{
+ return &pVoiceMgr->fmVoices[voiceNum];
+}
+EAS_INLINE S_SYNTH_CHANNEL *GetChannelPtr (S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice)
+{
+ return &pSynth->channels[pVoice->channel & 15];
+}
+EAS_INLINE const S_FM_REGION *GetFMRegionPtr (S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice)
+{
+#ifdef _SECONDARY_SYNTH
+ return &pSynth->pEAS->pFMRegions[pVoice->regionIndex & REGION_INDEX_MASK];
+#else
+ return &pSynth->pEAS->pFMRegions[pVoice->regionIndex];
+#endif
+}
+
+/*----------------------------------------------------------------------------
+ * FM_SynthIsOutputOperator
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Returns true if the operator is a direct output and not muted
+ *
+ * Inputs:
+ *
+ * Outputs:
+ * Returns boolean
+ *----------------------------------------------------------------------------
+*/
+static EAS_BOOL FM_SynthIsOutputOperator (const S_FM_REGION *pRegion, EAS_INT operIndex)
+{
+
+ /* see if voice is muted */
+ if ((pRegion->oper[operIndex].gain & 0xfc) == 0)
+ return 0;
+
+ /* check based on mode */
+ switch (pRegion->region.keyGroupAndFlags & 7)
+ {
+
+ /* mode 0 - all operators are external */
+ case 0:
+ return EAS_TRUE;
+
+ /* mode 1 - operators 1-3 are external */
+ case 1:
+ if (operIndex != 0)
+ return EAS_TRUE;
+ break;
+
+ /* mode 2 - operators 1 & 3 are external */
+ case 2:
+ if ((operIndex == 1) || (operIndex == 3))
+ return EAS_TRUE;
+ break;
+
+ /* mode 2 - operators 1 & 2 are external */
+ case 3:
+ if ((operIndex == 1) || (operIndex == 2))
+ return EAS_TRUE;
+ break;
+
+ /* modes 4 & 5 - operator 1 is external */
+ case 4:
+ case 5:
+ if (operIndex == 1)
+ return EAS_TRUE;
+ break;
+
+ default:
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_FATAL,"Invalid voice mode: %d",
+ pRegion->region.keyGroupAndFlags & 7); */ }
+ }
+
+ return EAS_FALSE;
+}
+
+/*----------------------------------------------------------------------------
+ * FM_CalcEGRate()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ *
+ * Inputs:
+ * nKeyNumber - MIDI note
+ * nLogRate - logarithmic scale rate from patch data
+ * nKeyScale - key scaling factor for this EG
+ *
+ * Outputs:
+ * 16-bit linear multiplier
+ *----------------------------------------------------------------------------
+*/
+
+static EAS_U16 FM_CalcEGRate (EAS_U8 nKeyNumber, EAS_U8 nLogRate, EAS_U8 nEGScale)
+{
+ EAS_I32 temp;
+
+ /* incorporate key scaling on release rate */
+ temp = (EAS_I32) nLogRate << 7;
+ temp += ((EAS_I32) nKeyNumber - EG_SCALE_PIVOT_POINT) * (EAS_I32) nEGScale;
+
+ /* saturate */
+ temp = max(temp, 0);
+ temp = min(temp, 32767);
+
+ /* look up in rate table */
+ /*lint -e{704} use shift for performance */
+ return fmRateTable[temp >> 8];
+}
+
+/*----------------------------------------------------------------------------
+ * FM_ReleaseVoice()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * The selected voice is being released.
+ *
+ * Inputs:
+ * psEASData - pointer to S_EAS_DATA
+ * pVoice - pointer to voice to release
+ *
+ * Outputs:
+ * None
+ *----------------------------------------------------------------------------
+*/
+static void FM_ReleaseVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, EAS_I32 voiceNum)
+{
+ EAS_INT operIndex;
+ const S_FM_REGION *pRegion;
+ S_FM_VOICE *pFMVoice;
+
+ /* check to see if voice responds to NOTE-OFF's */
+ pRegion = GetFMRegionPtr(pSynth, pVoice);
+ if (pRegion->region.keyGroupAndFlags & REGION_FLAG_ONE_SHOT)
+ return;
+
+ /* set all envelopes to release state */
+ pFMVoice = GetFMVoicePtr(pVoiceMgr, voiceNum);
+ for (operIndex = 0; operIndex < 4; operIndex++)
+ {
+ pFMVoice->oper[operIndex].envState = eFMEnvelopeStateRelease;
+
+ /* incorporate key scaling on release rate */
+ pFMVoice->oper[operIndex].envRate = FM_CalcEGRate(
+ pVoice->note,
+ fmReleaseTable[pRegion->oper[operIndex].velocityRelease & 0x0f],
+ fmScaleTable[pRegion->oper[operIndex].egKeyScale >> 4]);
+ } /* end for (operIndex = 0; operIndex < 4; operIndex++) */
+}
+
+/*----------------------------------------------------------------------------
+ * FM_MuteVoice()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * The selected voice is being muted.
+ *
+ * Inputs:
+ * pVoice - pointer to voice to release
+ *
+ * Outputs:
+ * None
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pSynth) standard interface, pVoiceMgr not used */
+static void FM_MuteVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, EAS_I32 voiceNum)
+{
+ S_FM_VOICE *pFMVoice;
+
+ /* clear deferred action flags */
+ pVoice->voiceFlags &=
+ ~(VOICE_FLAG_DEFER_MIDI_NOTE_OFF |
+ VOICE_FLAG_SUSTAIN_PEDAL_DEFER_NOTE_OFF |
+ VOICE_FLAG_DEFER_MUTE);
+
+ /* set all envelopes to muted state */
+ pFMVoice = GetFMVoicePtr(pVoiceMgr, voiceNum);
+ pFMVoice->oper[0].envState = eFMEnvelopeStateMuted;
+ pFMVoice->oper[1].envState = eFMEnvelopeStateMuted;
+ pFMVoice->oper[2].envState = eFMEnvelopeStateMuted;
+ pFMVoice->oper[3].envState = eFMEnvelopeStateMuted;
+}
+
+/*----------------------------------------------------------------------------
+ * FM_SustainPedal()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * The selected voice is held due to sustain pedal
+ *
+ * Inputs:
+ * pVoice - pointer to voice to sustain
+ *
+ * Outputs:
+ * None
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pChannel) standard interface, pVoiceMgr not used */
+static void FM_SustainPedal (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, S_SYNTH_CHANNEL *pChannel, EAS_I32 voiceNum)
+{
+ const S_FM_REGION *pRegion;
+ S_FM_VOICE *pFMVoice;
+ EAS_INT operIndex;
+
+ pRegion = GetFMRegionPtr(pSynth, pVoice);
+ pFMVoice = GetFMVoicePtr(pVoiceMgr, voiceNum);
+
+ /* check to see if any envelopes are above the sustain level */
+ for (operIndex = 0; operIndex < 4; operIndex++)
+ {
+
+ /* if level control or envelope gain is zero, skip this envelope */
+ if (((pRegion->oper[operIndex].gain & 0xfc) == 0) ||
+ (pFMVoice->oper[operIndex].envGain == 0))
+ {
+ continue;
+ }
+
+ /* if the envelope gain is above the sustain level, we need to catch this voice */
+ if (pFMVoice->oper[operIndex].envGain >= ((EAS_U16) (pRegion->oper[operIndex].sustain & 0xfc) << 7))
+ {
+
+ /* reset envelope to decay state */
+ pFMVoice->oper[operIndex].envState = eFMEnvelopeStateDecay;
+
+ pFMVoice->oper[operIndex].envRate = FM_CalcEGRate(
+ pVoice->note,
+ fmDecayTable[pRegion->oper[operIndex].attackDecay & 0x0f],
+ fmScaleTable[pRegion->oper[operIndex].egKeyScale >> 4]);
+
+ /* set voice to decay state */
+ pVoice->voiceState = eVoiceStatePlay;
+
+ /* set sustain flag */
+ pVoice->voiceFlags |= VOICE_FLAG_SUSTAIN_PEDAL_DEFER_NOTE_OFF;
+ }
+ } /* end for (operIndex = 0; operIndex < 4; operIndex++) */
+}
+
+/*----------------------------------------------------------------------------
+ * FM_StartVoice()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Assign the region for the given instrument using the midi key number
+ * and the RPN2 (coarse tuning) value. By using RPN2 as part of the
+ * region selection process, we reduce the amount a given sample has
+ * to be transposed by selecting the closest recorded root instead.
+ *
+ * This routine is the second half of SynthAssignRegion().
+ * If the region was successfully found by SynthFindRegionIndex(),
+ * then assign the region's parameters to the voice.
+ *
+ * Setup and initialize the following voice parameters:
+ * m_nRegionIndex
+ *
+ * Inputs:
+ * pVoice - ptr to the voice we have assigned for this channel
+ * nRegionIndex - index of the region
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ * success - could find and assign the region for this voice's note otherwise
+ * failure - could not find nor assign the region for this voice's note
+ *
+ * Side Effects:
+ * psSynthObject->m_sVoice[].m_nRegionIndex is assigned
+ * psSynthObject->m_sVoice[] parameters are assigned
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT FM_StartVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, EAS_I32 voiceNum, EAS_U16 regionIndex)
+{
+ S_FM_VOICE *pFMVoice;
+ S_SYNTH_CHANNEL *pChannel;
+ const S_FM_REGION *pRegion;
+ EAS_I32 temp;
+ EAS_INT operIndex;
+
+ /* establish pointers to data */
+ pVoice->regionIndex = regionIndex;
+ pFMVoice = GetFMVoicePtr(pVoiceMgr, voiceNum);
+ pChannel = GetChannelPtr(pSynth, pVoice);
+ pRegion = GetFMRegionPtr(pSynth, pVoice);
+
+ /* update static channel parameters */
+ if (pChannel->channelFlags & CHANNEL_FLAG_UPDATE_CHANNEL_PARAMETERS)
+ FM_UpdateChannel(pVoiceMgr, pSynth, pVoice->channel & 15);
+
+ /* init the LFO */
+ pFMVoice->lfoValue = 0;
+ pFMVoice->lfoPhase = 0;
+ pFMVoice->lfoDelay = (EAS_U16) (fmScaleTable[pRegion->lfoFreqDelay & 0x0f] >> 1);
+
+#if (NUM_OUTPUT_CHANNELS == 2)
+ /* calculate pan gain values only if stereo output */
+ /* set up panning only at note start */
+ temp = (EAS_I32) pChannel->pan - 64;
+ temp += (EAS_I32) pRegion->pan;
+ if (temp < -64)
+ temp = -64;
+ if (temp > 64)
+ temp = 64;
+ pFMVoice->pan = (EAS_I8) temp;
+#endif /* #if (NUM_OUTPUT_CHANNELS == 2) */
+
+ /* no samples have been synthesized for this note yet */
+ pVoice->voiceFlags = VOICE_FLAG_NO_SAMPLES_SYNTHESIZED_YET;
+
+ /* initialize gain value for anti-zipper filter */
+ pFMVoice->voiceGain = (EAS_I16) EAS_LogToLinear16(pChannel->staticGain);
+ pFMVoice->voiceGain = (EAS_I16) FMUL_15x15(pFMVoice->voiceGain, pSynth->masterVolume);
+
+ /* initialize the operators */
+ for (operIndex = 0; operIndex < 4; operIndex++)
+ {
+
+ /* establish operator output gain level */
+ /*lint -e{701} <use shift for performance> */
+ pFMVoice->oper[operIndex].outputGain = EAS_LogToLinear16(((EAS_I16) (pRegion->oper[operIndex].gain & 0xfc) - 0xfc) << 7);
+
+ /* check for linear velocity flag */
+ /*lint -e{703} <use shift for performance> */
+ if (pRegion->oper[operIndex].flags & FM_OPER_FLAG_LINEAR_VELOCITY)
+ temp = (EAS_I32) (pVoice->velocity - 127) << 5;
+ else
+ temp = (EAS_I32) fmControlTable[pVoice->velocity];
+
+ /* scale velocity */
+ /*lint -e{704} use shift for performance */
+ temp = (temp * (EAS_I32)(pRegion->oper[operIndex].velocityRelease & 0xf0)) >> 7;
+
+ /* include key scalar */
+ temp -= ((EAS_I32) pVoice->note - KEY_SCALE_PIVOT_POINT) * (EAS_I32) fmScaleTable[pRegion->oper[operIndex].egKeyScale & 0x0f];
+
+ /* saturate */
+ temp = min(temp, 0);
+ temp = max(temp, -32768);
+
+ /* save static gain parameters */
+ pFMVoice->oper[operIndex].baseGain = (EAS_I16) EAS_LogToLinear16(temp);
+
+ /* incorporate key scaling on decay rate */
+ pFMVoice->oper[operIndex].envRate = FM_CalcEGRate(
+ pVoice->note,
+ fmDecayTable[pRegion->oper[operIndex].attackDecay & 0x0f],
+ fmScaleTable[pRegion->oper[operIndex].egKeyScale >> 4]);
+
+ /* if zero attack time, max out envelope and jump to decay state */
+ if ((pRegion->oper[operIndex].attackDecay & 0xf0) == 0xf0)
+ {
+
+ /* start out envelope at max */
+ pFMVoice->oper[operIndex].envGain = 0x7fff;
+
+ /* set envelope to decay state */
+ pFMVoice->oper[operIndex].envState = eFMEnvelopeStateDecay;
+ }
+
+ /* start envelope at zero and start in attack state */
+ else
+ {
+ pFMVoice->oper[operIndex].envGain = 0;
+ pFMVoice->oper[operIndex].envState = eFMEnvelopeStateAttack;
+ }
+ }
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * FM_UpdateChannel()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Calculate and assign static channel parameters
+ * These values only need to be updated if one of the controller values
+ * for this channel changes.
+ * Called when CHANNEL_FLAG_UPDATE_CHANNEL_PARAMETERS flag is set.
+ *
+ * Inputs:
+ * nChannel - channel to update
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ * - the given channel's static gain and static pitch are updated
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pVoiceMgr) standard interface, pVoiceMgr not used */
+static void FM_UpdateChannel (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel)
+{
+ S_SYNTH_CHANNEL *pChannel;
+ EAS_I32 temp;
+
+ pChannel = &pSynth->channels[channel];
+
+ /* convert CC7 volume controller to log scale */
+ temp = fmControlTable[pChannel->volume];
+
+ /* incorporate CC11 expression controller */
+ temp += fmControlTable[pChannel->expression];
+
+ /* saturate */
+ pChannel->staticGain = (EAS_I16) max(temp,-32768);
+
+ /* calculate pitch bend */
+ /*lint -e{703} <avoid multiply for performance>*/
+ temp = (((EAS_I32)(pChannel->pitchBend) << 2) - 32768);
+
+ temp = FMUL_15x15(temp, pChannel->pitchBendSensitivity);
+
+ /* include "magic number" compensation for sample rate and lookup table size */
+ temp += MAGIC_NUMBER;
+
+ /* if this is not a drum channel, then add in the per-channel tuning */
+ if (!(pChannel->channelFlags & CHANNEL_FLAG_RHYTHM_CHANNEL))
+ temp += (pChannel->finePitch + (pChannel->coarsePitch * 100));
+
+ /* save static pitch */
+ pChannel->staticPitch = temp;
+
+ /* Calculate LFO modulation depth */
+ /* mod wheel to LFO depth */
+ temp = FMUL_15x15(DEFAULT_LFO_MOD_WHEEL_TO_PITCH_CENTS,
+ pChannel->modWheel << (NUM_EG1_FRAC_BITS -7));
+
+ /* channel pressure to LFO depth */
+ pChannel->lfoAmt = (EAS_I16) (temp +
+ FMUL_15x15(DEFAULT_LFO_CHANNEL_PRESSURE_TO_PITCH_CENTS,
+ pChannel->channelPressure << (NUM_EG1_FRAC_BITS -7)));
+
+ /* clear update flag */
+ pChannel->channelFlags &= ~CHANNEL_FLAG_UPDATE_CHANNEL_PARAMETERS;
+ return;
+}
+
+/*----------------------------------------------------------------------------
+ * FM_UpdateLFO()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Calculate the LFO for the given voice
+ *
+ * Inputs:
+ * pVoice - ptr to the voice whose LFO we want to update
+ * psEASData - pointer to overall EAS data structure - used for debug only
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ * - updates LFO values for the given voice
+ *----------------------------------------------------------------------------
+*/
+static void FM_UpdateLFO (S_FM_VOICE *pFMVoice, const S_FM_REGION *pRegion)
+{
+
+ /* increment the LFO phase if the delay time has elapsed */
+ if (!pFMVoice->lfoDelay)
+ {
+ /*lint -e{701} <use shift for performance> */
+ pFMVoice->lfoPhase = pFMVoice->lfoPhase + (EAS_U16) (-fmControlTable[((15 - (pRegion->lfoFreqDelay >> 4)) << 3) + 4]);
+
+ /* square wave LFO? */
+ if (pRegion->region.keyGroupAndFlags & REGION_FLAG_SQUARE_WAVE)
+ pFMVoice->lfoValue = (EAS_I16)(pFMVoice->lfoPhase & 0x8000 ? -32767 : 32767);
+
+ /* trick to get a triangle wave out of a sawtooth */
+ else
+ {
+ pFMVoice->lfoValue = (EAS_I16) (pFMVoice->lfoPhase << 1);
+ /*lint -e{502} <shortcut to turn sawtooth into sine wave> */
+ if ((pFMVoice->lfoPhase > 0x3fff) && (pFMVoice->lfoPhase < 0xC000))
+ pFMVoice->lfoValue = ~pFMVoice->lfoValue;
+ }
+ }
+
+ /* still in delay */
+ else
+ pFMVoice->lfoDelay--;
+
+ return;
+}
+
+/*----------------------------------------------------------------------------
+ * FM_UpdateEG()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Calculate the synthesis parameters for an operator to be used during
+ * the next buffer
+ *
+ * Inputs:
+ * pVoice - pointer to the voice being updated
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_BOOL FM_UpdateEG (S_SYNTH_VOICE *pVoice, S_OPERATOR *pOper, const S_FM_OPER *pOperData, EAS_BOOL oneShot)
+{
+ EAS_U32 temp;
+ EAS_BOOL done;
+
+ /* set flag assuming the envelope is not done */
+ done = EAS_FALSE;
+
+ /* take appropriate action based on state */
+ switch (pOper->envState)
+ {
+
+ case eFMEnvelopeStateAttack:
+
+ /* the envelope is linear during the attack, so add the value */
+ temp = pOper->envGain + fmAttackTable[pOperData->attackDecay >> 4];
+
+ /* check for end of attack */
+ if (temp >= 0x7fff)
+ {
+ pOper->envGain = 0x7fff;
+ pOper->envState = eFMEnvelopeStateDecay;
+ }
+ else
+ pOper->envGain = (EAS_U16) temp;
+ break;
+
+ case eFMEnvelopeStateDecay:
+
+ /* decay is exponential, multiply by decay rate */
+ pOper->envGain = (EAS_U16) FMUL_15x15(pOper->envGain, pOper->envRate);
+
+ /* check for sustain level reached */
+ temp = (EAS_U32) (pOperData->sustain & 0xfc) << 7;
+ if (pOper->envGain <= (EAS_U16) temp)
+ {
+ /* if this is a one-shot patch, go directly to release phase */
+ if (oneShot)
+ {
+ pOper->envRate = FM_CalcEGRate(
+ pVoice->note,
+ fmReleaseTable[pOperData->velocityRelease & 0x0f],
+ fmScaleTable[pOperData->egKeyScale >> 4]);
+ pOper->envState = eFMEnvelopeStateRelease;
+ }
+
+ /* normal sustaining type */
+ else
+ {
+ pOper->envGain = (EAS_U16) temp;
+ pOper->envState = eFMEnvelopeStateSustain;
+ }
+ }
+ break;
+
+ case eFMEnvelopeStateSustain:
+ pOper->envGain = (EAS_U16)((EAS_U16)(pOperData->sustain & 0xfc) << 7);
+ break;
+
+ case eFMEnvelopeStateRelease:
+
+ /* release is exponential, multiply by release rate */
+ pOper->envGain = (EAS_U16) FMUL_15x15(pOper->envGain, pOper->envRate);
+
+ /* fully released */
+ if (pOper->envGain == 0)
+ {
+ pOper->envGain = 0;
+ pOper->envState = eFMEnvelopeStateMuted;
+ done = EAS_TRUE;
+ }
+ break;
+
+ case eFMEnvelopeStateMuted:
+ pOper->envGain = 0;
+ done = EAS_TRUE;
+ break;
+ default:
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_FATAL,"Invalid operator state: %d", pOper->envState); */ }
+ } /* end switch (pOper->m_eState) */
+
+ return done;
+}
+
+/*----------------------------------------------------------------------------
+ * FM_UpdateDynamic()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Calculate the synthesis parameters for this voice that will be used to
+ * synthesize the next buffer
+ *
+ * Inputs:
+ * pVoice - pointer to the voice being updated
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ * Returns EAS_TRUE if voice will be fully ramped to zero at the end of
+ * the next synthesized buffer.
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_BOOL FM_UpdateDynamic (S_SYNTH_VOICE *pVoice, S_FM_VOICE *pFMVoice, const S_FM_REGION *pRegion, S_SYNTH_CHANNEL *pChannel)
+{
+ EAS_I32 temp;
+ EAS_I32 pitch;
+ EAS_I32 lfoPitch;
+ EAS_INT operIndex;
+ EAS_BOOL done;
+
+ /* increment LFO phase */
+ FM_UpdateLFO(pFMVoice, pRegion);
+
+ /* base pitch in cents */
+ pitch = pVoice->note * 100;
+
+ /* LFO amount includes LFO depth from programming + channel dynamics */
+ temp = (fmScaleTable[pRegion->vibTrem >> 4] >> 1) + pChannel->lfoAmt;
+
+ /* multiply by LFO output to get final pitch modulation */
+ lfoPitch = FMUL_15x15(pFMVoice->lfoValue, temp);
+
+ /* flag to indicate this voice is done */
+ done = EAS_TRUE;
+
+ /* iterate through operators to establish parameters */
+ for (operIndex = 0; operIndex < 4; operIndex++)
+ {
+ EAS_BOOL bTemp;
+
+ /* set base phase increment for each operator */
+ temp = pRegion->oper[operIndex].tuning +
+ pChannel->staticPitch;
+
+ /* add vibrato effect unless it is disabled for this operator */
+ if ((pRegion->oper[operIndex].flags & FM_OPER_FLAG_NO_VIBRATO) == 0)
+ temp += lfoPitch;
+
+ /* if note is monotonic, bias to MIDI note 60 */
+ if (pRegion->oper[operIndex].flags & FM_OPER_FLAG_MONOTONE)
+ temp += 6000;
+ else
+ temp += pitch;
+ pFMVoice->oper[operIndex].pitch = (EAS_I16) temp;
+
+ /* calculate envelope, returns true if done */
+ bTemp = FM_UpdateEG(pVoice, &pFMVoice->oper[operIndex], &pRegion->oper[operIndex], pRegion->region.keyGroupAndFlags & REGION_FLAG_ONE_SHOT);
+
+ /* check if all output envelopes have completed */
+ if (FM_SynthIsOutputOperator(pRegion, operIndex))
+ done = done && bTemp;
+ }
+
+ return done;
+}
+
+/*----------------------------------------------------------------------------
+ * FM_UpdateVoice()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Synthesize a block of samples for the given voice.
+ *
+ * Inputs:
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ * number of samples actually written to buffer
+ *
+ * Side Effects:
+ * - samples are added to the presently free buffer
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_BOOL FM_UpdateVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, EAS_I32 voiceNum, EAS_I32 *pMixBuffer, EAS_I32 numSamples)
+{
+ S_SYNTH_CHANNEL *pChannel;
+ const S_FM_REGION *pRegion;
+ S_FM_VOICE *pFMVoice;
+ S_FM_VOICE_CONFIG vCfg;
+ S_FM_VOICE_FRAME vFrame;
+ EAS_I32 temp;
+ EAS_INT oper;
+ EAS_U16 voiceGainTarget;
+ EAS_BOOL done;
+
+ /* setup some pointers */
+ pChannel = GetChannelPtr(pSynth, pVoice);
+ pRegion = GetFMRegionPtr(pSynth, pVoice);
+ pFMVoice = GetFMVoicePtr(pVoiceMgr, voiceNum);
+
+ /* if the voice is just starting, get the voice configuration data */
+ if (pVoice->voiceFlags & VOICE_FLAG_NO_SAMPLES_SYNTHESIZED_YET)
+ {
+
+ /* split architecture may limit the number of voice starts */
+#ifdef MAX_VOICE_STARTS
+ if (pVoiceMgr->numVoiceStarts == MAX_VOICE_STARTS)
+ return EAS_FALSE;
+ pVoiceMgr->numVoiceStarts++;
+#endif
+
+ /* get initial parameters */
+ vCfg.feedback = pRegion->feedback;
+ vCfg.voiceGain = (EAS_U16) pFMVoice->voiceGain;
+
+#if (NUM_OUTPUT_CHANNELS == 2)
+ vCfg.pan = pFMVoice->pan;
+#endif
+
+ /* get voice mode */
+ vCfg.flags = pRegion->region.keyGroupAndFlags & 7;
+
+ /* get operator parameters */
+ for (oper = 0; oper < 4; oper++)
+ {
+ /* calculate initial gain */
+ vCfg.gain[oper] = (EAS_U16) FMUL_15x15(pFMVoice->oper[oper].baseGain, pFMVoice->oper[oper].envGain);
+ vCfg.outputGain[oper] = pFMVoice->oper[oper].outputGain;
+
+ /* copy noise waveform flag */
+ if (pRegion->oper[oper].flags & FM_OPER_FLAG_NOISE)
+ vCfg.flags |= (EAS_U8) (FLAG_FM_ENG_VOICE_OP1_NOISE << oper);
+ }
+
+#ifdef FM_OFFBOARD
+ FM_ConfigVoice(voiceNum, &vCfg, pVoiceMgr->pFrameBuffer);
+#else
+ FM_ConfigVoice(voiceNum, &vCfg, NULL);
+#endif
+
+ /* clear startup flag */
+ pVoice->voiceFlags &= ~VOICE_FLAG_NO_SAMPLES_SYNTHESIZED_YET;
+ }
+
+ /* calculate new synthesis parameters */
+ done = FM_UpdateDynamic(pVoice, pFMVoice, pRegion, pChannel);
+
+ /* calculate LFO gain modulation */
+ /*lint -e{702} <use shift for performance> */
+ temp = ((fmScaleTable[pRegion->vibTrem & 0x0f] >> 1) * pFMVoice->lfoValue) >> FM_LFO_GAIN_SHIFT;
+
+ /* include channel gain */
+ temp += pChannel->staticGain;
+
+ /* -32768 or lower is infinite attenuation */
+ if (temp < -32767)
+ voiceGainTarget = 0;
+
+ /* translate to linear gain multiplier */
+ else
+ voiceGainTarget = EAS_LogToLinear16(temp);
+
+ /* include synth master volume */
+ voiceGainTarget = (EAS_U16) FMUL_15x15(voiceGainTarget, pSynth->masterVolume);
+
+ /* save target values for this frame */
+ vFrame.voiceGain = voiceGainTarget;
+
+ /* assume voice output is zero */
+ pVoice->gain = 0;
+
+ /* save operator targets for this frame */
+ for (oper = 0; oper < 4; oper++)
+ {
+ vFrame.gain[oper] = (EAS_U16) FMUL_15x15(pFMVoice->oper[oper].baseGain, pFMVoice->oper[oper].envGain);
+ vFrame.pitch[oper] = pFMVoice->oper[oper].pitch;
+
+ /* use the highest output envelope level as the gain for the voice stealing algorithm */
+ if (FM_SynthIsOutputOperator(pRegion, oper))
+ pVoice->gain = max(pVoice->gain, (EAS_I16) vFrame.gain[oper]);
+ }
+
+ /* consider voice gain multiplier in calculating gain for stealing algorithm */
+ pVoice->gain = (EAS_I16) FMUL_15x15(voiceGainTarget, pVoice->gain);
+
+ /* synthesize samples */
+#ifdef FM_OFFBOARD
+ FM_ProcessVoice(voiceNum, &vFrame, numSamples, pVoiceMgr->operMixBuffer, pVoiceMgr->voiceBuffer, pMixBuffer, pVoiceMgr->pFrameBuffer);
+#else
+ FM_ProcessVoice(voiceNum, &vFrame, numSamples, pVoiceMgr->operMixBuffer, pVoiceMgr->voiceBuffer, pMixBuffer, NULL);
+#endif
+
+ return done;
+}
+
diff --git a/arm-hybrid-22k/lib_src/eas_fmsynth.h b/arm-hybrid-22k/lib_src/eas_fmsynth.h
index 76f8adc..8ceda46 100644
--- a/arm-hybrid-22k/lib_src/eas_fmsynth.h
+++ b/arm-hybrid-22k/lib_src/eas_fmsynth.h
@@ -1,12 +1,12 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_fmsynth.h
- *
- * Contents and purpose:
- * Implements the FM synthesizer functions.
- *
- * Copyright Sonic Network Inc. 2004
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_fmsynth.h
+ *
+ * Contents and purpose:
+ * Implements the FM synthesizer functions.
+ *
+ * Copyright Sonic Network Inc. 2004
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,63 +19,63 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 90 $
- * $Date: 2006-07-11 20:18:13 -0700 (Tue, 11 Jul 2006) $
- *----------------------------------------------------------------------------
-*/
-
-#ifndef fmsynthH
-#define fmsynthH
-
-#include "eas_data.h"
-
-#if defined (_FM_SYNTH)
-
-/* FM envelope state */
-typedef enum {
- eFMEnvelopeStateAttack = 0,
- eFMEnvelopeStateDecay,
- eFMEnvelopeStateSustain,
- eFMEnvelopeStateRelease,
- eFMEnvelopeStateMuted,
- eFMEnvelopeStateInvalid /* should never be in this state! */
-} E_FM_ENVELOPE_STATE;
-
-/*------------------------------------
- * S_OPERATOR data structure
- *------------------------------------
-*/
-typedef struct s_operator_tag
-{
- EAS_I16 pitch; /* operator pitch in cents */
- EAS_U16 envGain; /* envelope target */
- EAS_I16 baseGain; /* patch gain (inc. vel & key scale) */
- EAS_U16 outputGain; /* current output gain */
- EAS_U16 envRate; /* calculated envelope rate */
- EAS_U8 envState; /* envelope state */
- EAS_U8 pad; /* pad to 16-bits */
-} S_OPERATOR;
-#endif
-
-typedef struct s_fm_voice_tag
-{
- S_OPERATOR oper[4]; /* operator data */
- EAS_I16 voiceGain; /* LFO + channel parameters */
- EAS_U16 lfoPhase; /* LFO current phase */
- EAS_I16 lfoValue; /* LFO current value */
- EAS_U16 lfoDelay; /* keeps track of elapsed delay time */
- EAS_I8 pan; /* stereo pan value (-64 to +64) */
- EAS_I8 pad; /* reserved to maintain alignment */
-} S_FM_VOICE;
-
-#ifdef _FM_EDITOR
-extern S_FM_REGION newPatch;
-extern S_FM_REGION OriginalPatch;
-#endif
-
-extern EAS_U32 freqTable[];
-
-#endif
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 90 $
+ * $Date: 2006-07-11 20:18:13 -0700 (Tue, 11 Jul 2006) $
+ *----------------------------------------------------------------------------
+*/
+
+#ifndef fmsynthH
+#define fmsynthH
+
+#include "eas_data.h"
+
+#if defined (_FM_SYNTH)
+
+/* FM envelope state */
+typedef enum {
+ eFMEnvelopeStateAttack = 0,
+ eFMEnvelopeStateDecay,
+ eFMEnvelopeStateSustain,
+ eFMEnvelopeStateRelease,
+ eFMEnvelopeStateMuted,
+ eFMEnvelopeStateInvalid /* should never be in this state! */
+} E_FM_ENVELOPE_STATE;
+
+/*------------------------------------
+ * S_OPERATOR data structure
+ *------------------------------------
+*/
+typedef struct s_operator_tag
+{
+ EAS_I16 pitch; /* operator pitch in cents */
+ EAS_U16 envGain; /* envelope target */
+ EAS_I16 baseGain; /* patch gain (inc. vel & key scale) */
+ EAS_U16 outputGain; /* current output gain */
+ EAS_U16 envRate; /* calculated envelope rate */
+ EAS_U8 envState; /* envelope state */
+ EAS_U8 pad; /* pad to 16-bits */
+} S_OPERATOR;
+#endif
+
+typedef struct s_fm_voice_tag
+{
+ S_OPERATOR oper[4]; /* operator data */
+ EAS_I16 voiceGain; /* LFO + channel parameters */
+ EAS_U16 lfoPhase; /* LFO current phase */
+ EAS_I16 lfoValue; /* LFO current value */
+ EAS_U16 lfoDelay; /* keeps track of elapsed delay time */
+ EAS_I8 pan; /* stereo pan value (-64 to +64) */
+ EAS_I8 pad; /* reserved to maintain alignment */
+} S_FM_VOICE;
+
+#ifdef _FM_EDITOR
+extern S_FM_REGION newPatch;
+extern S_FM_REGION OriginalPatch;
+#endif
+
+extern EAS_U32 freqTable[];
+
+#endif
diff --git a/arm-hybrid-22k/lib_src/eas_fmtables.c b/arm-hybrid-22k/lib_src/eas_fmtables.c
index 25c6961..a8ff0a2 100644
--- a/arm-hybrid-22k/lib_src/eas_fmtables.c
+++ b/arm-hybrid-22k/lib_src/eas_fmtables.c
@@ -1,13 +1,13 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_fmtables.c
- *
- * Contents and purpose:
- * Contains lookup tables for the FM synthesizer
- *
- *
- * Copyright Sonic Network Inc. 2005
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_fmtables.c
+ *
+ * Contents and purpose:
+ * Contains lookup tables for the FM synthesizer
+ *
+ *
+ * Copyright Sonic Network Inc. 2005
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,349 +20,349 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 82 $
- * $Date: 2006-07-10 11:45:19 -0700 (Mon, 10 Jul 2006) $
- *
- *----------------------------------------------------------------------------
-*/
-
-
-#include "eas_types.h"
-
-/* this table is needed by the DSP and the main processor */
-const EAS_U8 fmScaleTable[16] =
-{
- 0,8,16,24,32,40,48,56,64,72,80,96,128,160,192,255
-};
-
-/* these tables are needed on the main processor */
-#ifndef _DSP_CODE
-const EAS_I16 fmControlTable[128] =
-{
- -32768,-14313,-12265,-11067,-10217,-9558,-9019,-8563,
- -8169,-7821,-7510,-7228,-6971,-6734,-6515,-6312,
- -6121,-5942,-5773,-5613,-5462,-5317,-5180,-5049,
- -4923,-4802,-4686,-4575,-4467,-4364,-4264,-4167,
- -4073,-3982,-3894,-3808,-3725,-3644,-3565,-3488,
- -3414,-3341,-3269,-3200,-3132,-3066,-3001,-2937,
- -2875,-2814,-2754,-2696,-2638,-2582,-2527,-2473,
- -2419,-2367,-2316,-2265,-2216,-2167,-2119,-2071,
- -2025,-1979,-1934,-1889,-1846,-1803,-1760,-1718,
- -1677,-1636,-1596,-1556,-1517,-1478,-1440,-1403,
- -1366,-1329,-1293,-1257,-1221,-1186,-1152,-1118,
- -1084,-1051,-1018,-985,-953,-921,-889,-858,
- -827,-796,-766,-736,-706,-677,-648,-619,
- -590,-562,-534,-506,-479,-452,-425,-398,
- -371,-345,-319,-293,-268,-242,-217,-192,
- -168,-143,-119,-95,-71,-47,-23,0
-};
-
-const EAS_U16 fmRateTable[128] =
-{
- 32767,32764,32758,32747,32731,32712,32688,32659,
- 32627,32590,32548,32503,32453,32398,32340,32277,
- 32211,32140,32065,31985,31902,31815,31724,31628,
- 31529,31426,31319,31208,31094,30976,30854,30728,
- 30599,30466,30330,30191,30048,29902,29752,29599,
- 29443,29285,29123,28958,28790,28619,28445,28269,
- 28090,27909,27725,27538,27349,27158,26964,26769,
- 26571,26371,26169,25965,25760,25552,25343,25132,
- 24920,24706,24490,24274,24056,23836,23616,23394,
- 23172,22948,22724,22499,22273,22046,21819,21591,
- 21363,21135,20906,20676,20447,20217,19987,19758,
- 19528,19298,19069,18840,18610,18382,18153,17926,
- 17698,17471,17245,17020,16795,16571,16347,16125,
- 15903,15683,15463,15245,15027,14811,14596,14382,
- 14169,13957,13747,13538,13331,13125,12920,12717,
- 12516,12316,12117,11921,11725,11532,11340,0
-};
-
-const EAS_U16 fmAttackTable[15] =
-{
- 27,54,109,327,655,1310,2730,4095,
- 4681,5461,6553,8191,10922,16383,32767
-};
-
-const EAS_U8 fmDecayTable[16] =
-{
- 4,7,10,15,20,25,30,35,40,50,60,70,80,90,100,127
-};
-
-const EAS_U8 fmReleaseTable[16] =
-{
- 10,15,20,25,30,35,40,45,50,60,70,80,90,100,113,127
-};
-#endif
-
-/* this table is needed only on the DSP */
-#if defined(_DSP_CODE) || !defined(_SPLIT_ARCHITECTURE)
-//---------------------------------------------------------------------
-// sineTable
-//
-// Contains sine lookup table
-//---------------------------------------------------------------------
-
-const EAS_I16 sineTable[2048] =
-{
- 0,101,201,302,402,503,603,704,
- 804,905,1005,1106,1206,1307,1407,1507,
- 1608,1708,1809,1909,2009,2110,2210,2310,
- 2410,2511,2611,2711,2811,2911,3012,3112,
- 3212,3312,3412,3512,3612,3712,3811,3911,
- 4011,4111,4210,4310,4410,4509,4609,4708,
- 4808,4907,5007,5106,5205,5305,5404,5503,
- 5602,5701,5800,5899,5998,6096,6195,6294,
- 6393,6491,6590,6688,6786,6885,6983,7081,
- 7179,7277,7375,7473,7571,7669,7767,7864,
- 7962,8059,8157,8254,8351,8448,8545,8642,
- 8739,8836,8933,9030,9126,9223,9319,9416,
- 9512,9608,9704,9800,9896,9992,10087,10183,
- 10278,10374,10469,10564,10659,10754,10849,10944,
- 11039,11133,11228,11322,11417,11511,11605,11699,
- 11793,11886,11980,12074,12167,12260,12353,12446,
- 12539,12632,12725,12817,12910,13002,13094,13187,
- 13279,13370,13462,13554,13645,13736,13828,13919,
- 14010,14101,14191,14282,14372,14462,14553,14643,
- 14732,14822,14912,15001,15090,15180,15269,15358,
- 15446,15535,15623,15712,15800,15888,15976,16063,
- 16151,16238,16325,16413,16499,16586,16673,16759,
- 16846,16932,17018,17104,17189,17275,17360,17445,
- 17530,17615,17700,17784,17869,17953,18037,18121,
- 18204,18288,18371,18454,18537,18620,18703,18785,
- 18868,18950,19032,19113,19195,19276,19357,19438,
- 19519,19600,19680,19761,19841,19921,20000,20080,
- 20159,20238,20317,20396,20475,20553,20631,20709,
- 20787,20865,20942,21019,21096,21173,21250,21326,
- 21403,21479,21554,21630,21705,21781,21856,21930,
- 22005,22079,22154,22227,22301,22375,22448,22521,
- 22594,22667,22739,22812,22884,22956,23027,23099,
- 23170,23241,23311,23382,23452,23522,23592,23662,
- 23731,23801,23870,23938,24007,24075,24143,24211,
- 24279,24346,24413,24480,24547,24613,24680,24746,
- 24811,24877,24942,25007,25072,25137,25201,25265,
- 25329,25393,25456,25519,25582,25645,25708,25770,
- 25832,25893,25955,26016,26077,26138,26198,26259,
- 26319,26378,26438,26497,26556,26615,26674,26732,
- 26790,26848,26905,26962,27019,27076,27133,27189,
- 27245,27300,27356,27411,27466,27521,27575,27629,
- 27683,27737,27790,27843,27896,27949,28001,28053,
- 28105,28157,28208,28259,28310,28360,28411,28460,
- 28510,28560,28609,28658,28706,28755,28803,28850,
- 28898,28945,28992,29039,29085,29131,29177,29223,
- 29268,29313,29358,29403,29447,29491,29534,29578,
- 29621,29664,29706,29749,29791,29832,29874,29915,
- 29956,29997,30037,30077,30117,30156,30195,30234,
- 30273,30311,30349,30387,30424,30462,30498,30535,
- 30571,30607,30643,30679,30714,30749,30783,30818,
- 30852,30885,30919,30952,30985,31017,31050,31082,
- 31113,31145,31176,31206,31237,31267,31297,31327,
- 31356,31385,31414,31442,31470,31498,31526,31553,
- 31580,31607,31633,31659,31685,31710,31736,31760,
- 31785,31809,31833,31857,31880,31903,31926,31949,
- 31971,31993,32014,32036,32057,32077,32098,32118,
- 32137,32157,32176,32195,32213,32232,32250,32267,
- 32285,32302,32318,32335,32351,32367,32382,32397,
- 32412,32427,32441,32455,32469,32482,32495,32508,
- 32521,32533,32545,32556,32567,32578,32589,32599,
- 32609,32619,32628,32637,32646,32655,32663,32671,
- 32678,32685,32692,32699,32705,32711,32717,32722,
- 32728,32732,32737,32741,32745,32748,32752,32755,
- 32757,32759,32761,32763,32765,32766,32766,32767,
- 32767,32767,32766,32766,32765,32763,32761,32759,
- 32757,32755,32752,32748,32745,32741,32737,32732,
- 32728,32722,32717,32711,32705,32699,32692,32685,
- 32678,32671,32663,32655,32646,32637,32628,32619,
- 32609,32599,32589,32578,32567,32556,32545,32533,
- 32521,32508,32495,32482,32469,32455,32441,32427,
- 32412,32397,32382,32367,32351,32335,32318,32302,
- 32285,32267,32250,32232,32213,32195,32176,32157,
- 32137,32118,32098,32077,32057,32036,32014,31993,
- 31971,31949,31926,31903,31880,31857,31833,31809,
- 31785,31760,31736,31710,31685,31659,31633,31607,
- 31580,31553,31526,31498,31470,31442,31414,31385,
- 31356,31327,31297,31267,31237,31206,31176,31145,
- 31113,31082,31050,31017,30985,30952,30919,30885,
- 30852,30818,30783,30749,30714,30679,30643,30607,
- 30571,30535,30498,30462,30424,30387,30349,30311,
- 30273,30234,30195,30156,30117,30077,30037,29997,
- 29956,29915,29874,29832,29791,29749,29706,29664,
- 29621,29578,29534,29491,29447,29403,29358,29313,
- 29268,29223,29177,29131,29085,29039,28992,28945,
- 28898,28850,28803,28755,28706,28658,28609,28560,
- 28510,28460,28411,28360,28310,28259,28208,28157,
- 28105,28053,28001,27949,27896,27843,27790,27737,
- 27683,27629,27575,27521,27466,27411,27356,27300,
- 27245,27189,27133,27076,27019,26962,26905,26848,
- 26790,26732,26674,26615,26556,26497,26438,26378,
- 26319,26259,26198,26138,26077,26016,25955,25893,
- 25832,25770,25708,25645,25582,25519,25456,25393,
- 25329,25265,25201,25137,25072,25007,24942,24877,
- 24811,24746,24680,24613,24547,24480,24413,24346,
- 24279,24211,24143,24075,24007,23938,23870,23801,
- 23731,23662,23592,23522,23452,23382,23311,23241,
- 23170,23099,23027,22956,22884,22812,22739,22667,
- 22594,22521,22448,22375,22301,22227,22154,22079,
- 22005,21930,21856,21781,21705,21630,21554,21479,
- 21403,21326,21250,21173,21096,21019,20942,20865,
- 20787,20709,20631,20553,20475,20396,20317,20238,
- 20159,20080,20000,19921,19841,19761,19680,19600,
- 19519,19438,19357,19276,19195,19113,19032,18950,
- 18868,18785,18703,18620,18537,18454,18371,18288,
- 18204,18121,18037,17953,17869,17784,17700,17615,
- 17530,17445,17360,17275,17189,17104,17018,16932,
- 16846,16759,16673,16586,16499,16413,16325,16238,
- 16151,16063,15976,15888,15800,15712,15623,15535,
- 15446,15358,15269,15180,15090,15001,14912,14822,
- 14732,14643,14553,14462,14372,14282,14191,14101,
- 14010,13919,13828,13736,13645,13554,13462,13370,
- 13279,13187,13094,13002,12910,12817,12725,12632,
- 12539,12446,12353,12260,12167,12074,11980,11886,
- 11793,11699,11605,11511,11417,11322,11228,11133,
- 11039,10944,10849,10754,10659,10564,10469,10374,
- 10278,10183,10087,9992,9896,9800,9704,9608,
- 9512,9416,9319,9223,9126,9030,8933,8836,
- 8739,8642,8545,8448,8351,8254,8157,8059,
- 7962,7864,7767,7669,7571,7473,7375,7277,
- 7179,7081,6983,6885,6786,6688,6590,6491,
- 6393,6294,6195,6096,5998,5899,5800,5701,
- 5602,5503,5404,5305,5205,5106,5007,4907,
- 4808,4708,4609,4509,4410,4310,4210,4111,
- 4011,3911,3811,3712,3612,3512,3412,3312,
- 3212,3112,3012,2911,2811,2711,2611,2511,
- 2410,2310,2210,2110,2009,1909,1809,1708,
- 1608,1507,1407,1307,1206,1106,1005,905,
- 804,704,603,503,402,302,201,101,
- 0,-101,-201,-302,-402,-503,-603,-704,
- -804,-905,-1005,-1106,-1206,-1307,-1407,-1507,
- -1608,-1708,-1809,-1909,-2009,-2110,-2210,-2310,
- -2410,-2511,-2611,-2711,-2811,-2911,-3012,-3112,
- -3212,-3312,-3412,-3512,-3612,-3712,-3811,-3911,
- -4011,-4111,-4210,-4310,-4410,-4509,-4609,-4708,
- -4808,-4907,-5007,-5106,-5205,-5305,-5404,-5503,
- -5602,-5701,-5800,-5899,-5998,-6096,-6195,-6294,
- -6393,-6491,-6590,-6688,-6786,-6885,-6983,-7081,
- -7179,-7277,-7375,-7473,-7571,-7669,-7767,-7864,
- -7962,-8059,-8157,-8254,-8351,-8448,-8545,-8642,
- -8739,-8836,-8933,-9030,-9126,-9223,-9319,-9416,
- -9512,-9608,-9704,-9800,-9896,-9992,-10087,-10183,
- -10278,-10374,-10469,-10564,-10659,-10754,-10849,-10944,
- -11039,-11133,-11228,-11322,-11417,-11511,-11605,-11699,
- -11793,-11886,-11980,-12074,-12167,-12260,-12353,-12446,
- -12539,-12632,-12725,-12817,-12910,-13002,-13094,-13187,
- -13279,-13370,-13462,-13554,-13645,-13736,-13828,-13919,
- -14010,-14101,-14191,-14282,-14372,-14462,-14553,-14643,
- -14732,-14822,-14912,-15001,-15090,-15180,-15269,-15358,
- -15446,-15535,-15623,-15712,-15800,-15888,-15976,-16063,
- -16151,-16238,-16325,-16413,-16499,-16586,-16673,-16759,
- -16846,-16932,-17018,-17104,-17189,-17275,-17360,-17445,
- -17530,-17615,-17700,-17784,-17869,-17953,-18037,-18121,
- -18204,-18288,-18371,-18454,-18537,-18620,-18703,-18785,
- -18868,-18950,-19032,-19113,-19195,-19276,-19357,-19438,
- -19519,-19600,-19680,-19761,-19841,-19921,-20000,-20080,
- -20159,-20238,-20317,-20396,-20475,-20553,-20631,-20709,
- -20787,-20865,-20942,-21019,-21096,-21173,-21250,-21326,
- -21403,-21479,-21554,-21630,-21705,-21781,-21856,-21930,
- -22005,-22079,-22154,-22227,-22301,-22375,-22448,-22521,
- -22594,-22667,-22739,-22812,-22884,-22956,-23027,-23099,
- -23170,-23241,-23311,-23382,-23452,-23522,-23592,-23662,
- -23731,-23801,-23870,-23938,-24007,-24075,-24143,-24211,
- -24279,-24346,-24413,-24480,-24547,-24613,-24680,-24746,
- -24811,-24877,-24942,-25007,-25072,-25137,-25201,-25265,
- -25329,-25393,-25456,-25519,-25582,-25645,-25708,-25770,
- -25832,-25893,-25955,-26016,-26077,-26138,-26198,-26259,
- -26319,-26378,-26438,-26497,-26556,-26615,-26674,-26732,
- -26790,-26848,-26905,-26962,-27019,-27076,-27133,-27189,
- -27245,-27300,-27356,-27411,-27466,-27521,-27575,-27629,
- -27683,-27737,-27790,-27843,-27896,-27949,-28001,-28053,
- -28105,-28157,-28208,-28259,-28310,-28360,-28411,-28460,
- -28510,-28560,-28609,-28658,-28706,-28755,-28803,-28850,
- -28898,-28945,-28992,-29039,-29085,-29131,-29177,-29223,
- -29268,-29313,-29358,-29403,-29447,-29491,-29534,-29578,
- -29621,-29664,-29706,-29749,-29791,-29832,-29874,-29915,
- -29956,-29997,-30037,-30077,-30117,-30156,-30195,-30234,
- -30273,-30311,-30349,-30387,-30424,-30462,-30498,-30535,
- -30571,-30607,-30643,-30679,-30714,-30749,-30783,-30818,
- -30852,-30885,-30919,-30952,-30985,-31017,-31050,-31082,
- -31113,-31145,-31176,-31206,-31237,-31267,-31297,-31327,
- -31356,-31385,-31414,-31442,-31470,-31498,-31526,-31553,
- -31580,-31607,-31633,-31659,-31685,-31710,-31736,-31760,
- -31785,-31809,-31833,-31857,-31880,-31903,-31926,-31949,
- -31971,-31993,-32014,-32036,-32057,-32077,-32098,-32118,
- -32137,-32157,-32176,-32195,-32213,-32232,-32250,-32267,
- -32285,-32302,-32318,-32335,-32351,-32367,-32382,-32397,
- -32412,-32427,-32441,-32455,-32469,-32482,-32495,-32508,
- -32521,-32533,-32545,-32556,-32567,-32578,-32589,-32599,
- -32609,-32619,-32628,-32637,-32646,-32655,-32663,-32671,
- -32678,-32685,-32692,-32699,-32705,-32711,-32717,-32722,
- -32728,-32732,-32737,-32741,-32745,-32748,-32752,-32755,
- -32757,-32759,-32761,-32763,-32765,-32766,-32766,-32767,
- -32767,-32767,-32766,-32766,-32765,-32763,-32761,-32759,
- -32757,-32755,-32752,-32748,-32745,-32741,-32737,-32732,
- -32728,-32722,-32717,-32711,-32705,-32699,-32692,-32685,
- -32678,-32671,-32663,-32655,-32646,-32637,-32628,-32619,
- -32609,-32599,-32589,-32578,-32567,-32556,-32545,-32533,
- -32521,-32508,-32495,-32482,-32469,-32455,-32441,-32427,
- -32412,-32397,-32382,-32367,-32351,-32335,-32318,-32302,
- -32285,-32267,-32250,-32232,-32213,-32195,-32176,-32157,
- -32137,-32118,-32098,-32077,-32057,-32036,-32014,-31993,
- -31971,-31949,-31926,-31903,-31880,-31857,-31833,-31809,
- -31785,-31760,-31736,-31710,-31685,-31659,-31633,-31607,
- -31580,-31553,-31526,-31498,-31470,-31442,-31414,-31385,
- -31356,-31327,-31297,-31267,-31237,-31206,-31176,-31145,
- -31113,-31082,-31050,-31017,-30985,-30952,-30919,-30885,
- -30852,-30818,-30783,-30749,-30714,-30679,-30643,-30607,
- -30571,-30535,-30498,-30462,-30424,-30387,-30349,-30311,
- -30273,-30234,-30195,-30156,-30117,-30077,-30037,-29997,
- -29956,-29915,-29874,-29832,-29791,-29749,-29706,-29664,
- -29621,-29578,-29534,-29491,-29447,-29403,-29358,-29313,
- -29268,-29223,-29177,-29131,-29085,-29039,-28992,-28945,
- -28898,-28850,-28803,-28755,-28706,-28658,-28609,-28560,
- -28510,-28460,-28411,-28360,-28310,-28259,-28208,-28157,
- -28105,-28053,-28001,-27949,-27896,-27843,-27790,-27737,
- -27683,-27629,-27575,-27521,-27466,-27411,-27356,-27300,
- -27245,-27189,-27133,-27076,-27019,-26962,-26905,-26848,
- -26790,-26732,-26674,-26615,-26556,-26497,-26438,-26378,
- -26319,-26259,-26198,-26138,-26077,-26016,-25955,-25893,
- -25832,-25770,-25708,-25645,-25582,-25519,-25456,-25393,
- -25329,-25265,-25201,-25137,-25072,-25007,-24942,-24877,
- -24811,-24746,-24680,-24613,-24547,-24480,-24413,-24346,
- -24279,-24211,-24143,-24075,-24007,-23938,-23870,-23801,
- -23731,-23662,-23592,-23522,-23452,-23382,-23311,-23241,
- -23170,-23099,-23027,-22956,-22884,-22812,-22739,-22667,
- -22594,-22521,-22448,-22375,-22301,-22227,-22154,-22079,
- -22005,-21930,-21856,-21781,-21705,-21630,-21554,-21479,
- -21403,-21326,-21250,-21173,-21096,-21019,-20942,-20865,
- -20787,-20709,-20631,-20553,-20475,-20396,-20317,-20238,
- -20159,-20080,-20000,-19921,-19841,-19761,-19680,-19600,
- -19519,-19438,-19357,-19276,-19195,-19113,-19032,-18950,
- -18868,-18785,-18703,-18620,-18537,-18454,-18371,-18288,
- -18204,-18121,-18037,-17953,-17869,-17784,-17700,-17615,
- -17530,-17445,-17360,-17275,-17189,-17104,-17018,-16932,
- -16846,-16759,-16673,-16586,-16499,-16413,-16325,-16238,
- -16151,-16063,-15976,-15888,-15800,-15712,-15623,-15535,
- -15446,-15358,-15269,-15180,-15090,-15001,-14912,-14822,
- -14732,-14643,-14553,-14462,-14372,-14282,-14191,-14101,
- -14010,-13919,-13828,-13736,-13645,-13554,-13462,-13370,
- -13279,-13187,-13094,-13002,-12910,-12817,-12725,-12632,
- -12539,-12446,-12353,-12260,-12167,-12074,-11980,-11886,
- -11793,-11699,-11605,-11511,-11417,-11322,-11228,-11133,
- -11039,-10944,-10849,-10754,-10659,-10564,-10469,-10374,
- -10278,-10183,-10087,-9992,-9896,-9800,-9704,-9608,
- -9512,-9416,-9319,-9223,-9126,-9030,-8933,-8836,
- -8739,-8642,-8545,-8448,-8351,-8254,-8157,-8059,
- -7962,-7864,-7767,-7669,-7571,-7473,-7375,-7277,
- -7179,-7081,-6983,-6885,-6786,-6688,-6590,-6491,
- -6393,-6294,-6195,-6096,-5998,-5899,-5800,-5701,
- -5602,-5503,-5404,-5305,-5205,-5106,-5007,-4907,
- -4808,-4708,-4609,-4509,-4410,-4310,-4210,-4111,
- -4011,-3911,-3811,-3712,-3612,-3512,-3412,-3312,
- -3212,-3112,-3012,-2911,-2811,-2711,-2611,-2511,
- -2410,-2310,-2210,-2110,-2009,-1909,-1809,-1708,
- -1608,-1507,-1407,-1307,-1206,-1106,-1005,-905,
- -804,-704,-603,-503,-402,-302,-201,-101
-};
-#endif
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 82 $
+ * $Date: 2006-07-10 11:45:19 -0700 (Mon, 10 Jul 2006) $
+ *
+ *----------------------------------------------------------------------------
+*/
+
+
+#include "eas_types.h"
+
+/* this table is needed by the DSP and the main processor */
+const EAS_U8 fmScaleTable[16] =
+{
+ 0,8,16,24,32,40,48,56,64,72,80,96,128,160,192,255
+};
+
+/* these tables are needed on the main processor */
+#ifndef _DSP_CODE
+const EAS_I16 fmControlTable[128] =
+{
+ -32768,-14313,-12265,-11067,-10217,-9558,-9019,-8563,
+ -8169,-7821,-7510,-7228,-6971,-6734,-6515,-6312,
+ -6121,-5942,-5773,-5613,-5462,-5317,-5180,-5049,
+ -4923,-4802,-4686,-4575,-4467,-4364,-4264,-4167,
+ -4073,-3982,-3894,-3808,-3725,-3644,-3565,-3488,
+ -3414,-3341,-3269,-3200,-3132,-3066,-3001,-2937,
+ -2875,-2814,-2754,-2696,-2638,-2582,-2527,-2473,
+ -2419,-2367,-2316,-2265,-2216,-2167,-2119,-2071,
+ -2025,-1979,-1934,-1889,-1846,-1803,-1760,-1718,
+ -1677,-1636,-1596,-1556,-1517,-1478,-1440,-1403,
+ -1366,-1329,-1293,-1257,-1221,-1186,-1152,-1118,
+ -1084,-1051,-1018,-985,-953,-921,-889,-858,
+ -827,-796,-766,-736,-706,-677,-648,-619,
+ -590,-562,-534,-506,-479,-452,-425,-398,
+ -371,-345,-319,-293,-268,-242,-217,-192,
+ -168,-143,-119,-95,-71,-47,-23,0
+};
+
+const EAS_U16 fmRateTable[128] =
+{
+ 32767,32764,32758,32747,32731,32712,32688,32659,
+ 32627,32590,32548,32503,32453,32398,32340,32277,
+ 32211,32140,32065,31985,31902,31815,31724,31628,
+ 31529,31426,31319,31208,31094,30976,30854,30728,
+ 30599,30466,30330,30191,30048,29902,29752,29599,
+ 29443,29285,29123,28958,28790,28619,28445,28269,
+ 28090,27909,27725,27538,27349,27158,26964,26769,
+ 26571,26371,26169,25965,25760,25552,25343,25132,
+ 24920,24706,24490,24274,24056,23836,23616,23394,
+ 23172,22948,22724,22499,22273,22046,21819,21591,
+ 21363,21135,20906,20676,20447,20217,19987,19758,
+ 19528,19298,19069,18840,18610,18382,18153,17926,
+ 17698,17471,17245,17020,16795,16571,16347,16125,
+ 15903,15683,15463,15245,15027,14811,14596,14382,
+ 14169,13957,13747,13538,13331,13125,12920,12717,
+ 12516,12316,12117,11921,11725,11532,11340,0
+};
+
+const EAS_U16 fmAttackTable[15] =
+{
+ 27,54,109,327,655,1310,2730,4095,
+ 4681,5461,6553,8191,10922,16383,32767
+};
+
+const EAS_U8 fmDecayTable[16] =
+{
+ 4,7,10,15,20,25,30,35,40,50,60,70,80,90,100,127
+};
+
+const EAS_U8 fmReleaseTable[16] =
+{
+ 10,15,20,25,30,35,40,45,50,60,70,80,90,100,113,127
+};
+#endif
+
+/* this table is needed only on the DSP */
+#if defined(_DSP_CODE) || !defined(_SPLIT_ARCHITECTURE)
+//---------------------------------------------------------------------
+// sineTable
+//
+// Contains sine lookup table
+//---------------------------------------------------------------------
+
+const EAS_I16 sineTable[2048] =
+{
+ 0,101,201,302,402,503,603,704,
+ 804,905,1005,1106,1206,1307,1407,1507,
+ 1608,1708,1809,1909,2009,2110,2210,2310,
+ 2410,2511,2611,2711,2811,2911,3012,3112,
+ 3212,3312,3412,3512,3612,3712,3811,3911,
+ 4011,4111,4210,4310,4410,4509,4609,4708,
+ 4808,4907,5007,5106,5205,5305,5404,5503,
+ 5602,5701,5800,5899,5998,6096,6195,6294,
+ 6393,6491,6590,6688,6786,6885,6983,7081,
+ 7179,7277,7375,7473,7571,7669,7767,7864,
+ 7962,8059,8157,8254,8351,8448,8545,8642,
+ 8739,8836,8933,9030,9126,9223,9319,9416,
+ 9512,9608,9704,9800,9896,9992,10087,10183,
+ 10278,10374,10469,10564,10659,10754,10849,10944,
+ 11039,11133,11228,11322,11417,11511,11605,11699,
+ 11793,11886,11980,12074,12167,12260,12353,12446,
+ 12539,12632,12725,12817,12910,13002,13094,13187,
+ 13279,13370,13462,13554,13645,13736,13828,13919,
+ 14010,14101,14191,14282,14372,14462,14553,14643,
+ 14732,14822,14912,15001,15090,15180,15269,15358,
+ 15446,15535,15623,15712,15800,15888,15976,16063,
+ 16151,16238,16325,16413,16499,16586,16673,16759,
+ 16846,16932,17018,17104,17189,17275,17360,17445,
+ 17530,17615,17700,17784,17869,17953,18037,18121,
+ 18204,18288,18371,18454,18537,18620,18703,18785,
+ 18868,18950,19032,19113,19195,19276,19357,19438,
+ 19519,19600,19680,19761,19841,19921,20000,20080,
+ 20159,20238,20317,20396,20475,20553,20631,20709,
+ 20787,20865,20942,21019,21096,21173,21250,21326,
+ 21403,21479,21554,21630,21705,21781,21856,21930,
+ 22005,22079,22154,22227,22301,22375,22448,22521,
+ 22594,22667,22739,22812,22884,22956,23027,23099,
+ 23170,23241,23311,23382,23452,23522,23592,23662,
+ 23731,23801,23870,23938,24007,24075,24143,24211,
+ 24279,24346,24413,24480,24547,24613,24680,24746,
+ 24811,24877,24942,25007,25072,25137,25201,25265,
+ 25329,25393,25456,25519,25582,25645,25708,25770,
+ 25832,25893,25955,26016,26077,26138,26198,26259,
+ 26319,26378,26438,26497,26556,26615,26674,26732,
+ 26790,26848,26905,26962,27019,27076,27133,27189,
+ 27245,27300,27356,27411,27466,27521,27575,27629,
+ 27683,27737,27790,27843,27896,27949,28001,28053,
+ 28105,28157,28208,28259,28310,28360,28411,28460,
+ 28510,28560,28609,28658,28706,28755,28803,28850,
+ 28898,28945,28992,29039,29085,29131,29177,29223,
+ 29268,29313,29358,29403,29447,29491,29534,29578,
+ 29621,29664,29706,29749,29791,29832,29874,29915,
+ 29956,29997,30037,30077,30117,30156,30195,30234,
+ 30273,30311,30349,30387,30424,30462,30498,30535,
+ 30571,30607,30643,30679,30714,30749,30783,30818,
+ 30852,30885,30919,30952,30985,31017,31050,31082,
+ 31113,31145,31176,31206,31237,31267,31297,31327,
+ 31356,31385,31414,31442,31470,31498,31526,31553,
+ 31580,31607,31633,31659,31685,31710,31736,31760,
+ 31785,31809,31833,31857,31880,31903,31926,31949,
+ 31971,31993,32014,32036,32057,32077,32098,32118,
+ 32137,32157,32176,32195,32213,32232,32250,32267,
+ 32285,32302,32318,32335,32351,32367,32382,32397,
+ 32412,32427,32441,32455,32469,32482,32495,32508,
+ 32521,32533,32545,32556,32567,32578,32589,32599,
+ 32609,32619,32628,32637,32646,32655,32663,32671,
+ 32678,32685,32692,32699,32705,32711,32717,32722,
+ 32728,32732,32737,32741,32745,32748,32752,32755,
+ 32757,32759,32761,32763,32765,32766,32766,32767,
+ 32767,32767,32766,32766,32765,32763,32761,32759,
+ 32757,32755,32752,32748,32745,32741,32737,32732,
+ 32728,32722,32717,32711,32705,32699,32692,32685,
+ 32678,32671,32663,32655,32646,32637,32628,32619,
+ 32609,32599,32589,32578,32567,32556,32545,32533,
+ 32521,32508,32495,32482,32469,32455,32441,32427,
+ 32412,32397,32382,32367,32351,32335,32318,32302,
+ 32285,32267,32250,32232,32213,32195,32176,32157,
+ 32137,32118,32098,32077,32057,32036,32014,31993,
+ 31971,31949,31926,31903,31880,31857,31833,31809,
+ 31785,31760,31736,31710,31685,31659,31633,31607,
+ 31580,31553,31526,31498,31470,31442,31414,31385,
+ 31356,31327,31297,31267,31237,31206,31176,31145,
+ 31113,31082,31050,31017,30985,30952,30919,30885,
+ 30852,30818,30783,30749,30714,30679,30643,30607,
+ 30571,30535,30498,30462,30424,30387,30349,30311,
+ 30273,30234,30195,30156,30117,30077,30037,29997,
+ 29956,29915,29874,29832,29791,29749,29706,29664,
+ 29621,29578,29534,29491,29447,29403,29358,29313,
+ 29268,29223,29177,29131,29085,29039,28992,28945,
+ 28898,28850,28803,28755,28706,28658,28609,28560,
+ 28510,28460,28411,28360,28310,28259,28208,28157,
+ 28105,28053,28001,27949,27896,27843,27790,27737,
+ 27683,27629,27575,27521,27466,27411,27356,27300,
+ 27245,27189,27133,27076,27019,26962,26905,26848,
+ 26790,26732,26674,26615,26556,26497,26438,26378,
+ 26319,26259,26198,26138,26077,26016,25955,25893,
+ 25832,25770,25708,25645,25582,25519,25456,25393,
+ 25329,25265,25201,25137,25072,25007,24942,24877,
+ 24811,24746,24680,24613,24547,24480,24413,24346,
+ 24279,24211,24143,24075,24007,23938,23870,23801,
+ 23731,23662,23592,23522,23452,23382,23311,23241,
+ 23170,23099,23027,22956,22884,22812,22739,22667,
+ 22594,22521,22448,22375,22301,22227,22154,22079,
+ 22005,21930,21856,21781,21705,21630,21554,21479,
+ 21403,21326,21250,21173,21096,21019,20942,20865,
+ 20787,20709,20631,20553,20475,20396,20317,20238,
+ 20159,20080,20000,19921,19841,19761,19680,19600,
+ 19519,19438,19357,19276,19195,19113,19032,18950,
+ 18868,18785,18703,18620,18537,18454,18371,18288,
+ 18204,18121,18037,17953,17869,17784,17700,17615,
+ 17530,17445,17360,17275,17189,17104,17018,16932,
+ 16846,16759,16673,16586,16499,16413,16325,16238,
+ 16151,16063,15976,15888,15800,15712,15623,15535,
+ 15446,15358,15269,15180,15090,15001,14912,14822,
+ 14732,14643,14553,14462,14372,14282,14191,14101,
+ 14010,13919,13828,13736,13645,13554,13462,13370,
+ 13279,13187,13094,13002,12910,12817,12725,12632,
+ 12539,12446,12353,12260,12167,12074,11980,11886,
+ 11793,11699,11605,11511,11417,11322,11228,11133,
+ 11039,10944,10849,10754,10659,10564,10469,10374,
+ 10278,10183,10087,9992,9896,9800,9704,9608,
+ 9512,9416,9319,9223,9126,9030,8933,8836,
+ 8739,8642,8545,8448,8351,8254,8157,8059,
+ 7962,7864,7767,7669,7571,7473,7375,7277,
+ 7179,7081,6983,6885,6786,6688,6590,6491,
+ 6393,6294,6195,6096,5998,5899,5800,5701,
+ 5602,5503,5404,5305,5205,5106,5007,4907,
+ 4808,4708,4609,4509,4410,4310,4210,4111,
+ 4011,3911,3811,3712,3612,3512,3412,3312,
+ 3212,3112,3012,2911,2811,2711,2611,2511,
+ 2410,2310,2210,2110,2009,1909,1809,1708,
+ 1608,1507,1407,1307,1206,1106,1005,905,
+ 804,704,603,503,402,302,201,101,
+ 0,-101,-201,-302,-402,-503,-603,-704,
+ -804,-905,-1005,-1106,-1206,-1307,-1407,-1507,
+ -1608,-1708,-1809,-1909,-2009,-2110,-2210,-2310,
+ -2410,-2511,-2611,-2711,-2811,-2911,-3012,-3112,
+ -3212,-3312,-3412,-3512,-3612,-3712,-3811,-3911,
+ -4011,-4111,-4210,-4310,-4410,-4509,-4609,-4708,
+ -4808,-4907,-5007,-5106,-5205,-5305,-5404,-5503,
+ -5602,-5701,-5800,-5899,-5998,-6096,-6195,-6294,
+ -6393,-6491,-6590,-6688,-6786,-6885,-6983,-7081,
+ -7179,-7277,-7375,-7473,-7571,-7669,-7767,-7864,
+ -7962,-8059,-8157,-8254,-8351,-8448,-8545,-8642,
+ -8739,-8836,-8933,-9030,-9126,-9223,-9319,-9416,
+ -9512,-9608,-9704,-9800,-9896,-9992,-10087,-10183,
+ -10278,-10374,-10469,-10564,-10659,-10754,-10849,-10944,
+ -11039,-11133,-11228,-11322,-11417,-11511,-11605,-11699,
+ -11793,-11886,-11980,-12074,-12167,-12260,-12353,-12446,
+ -12539,-12632,-12725,-12817,-12910,-13002,-13094,-13187,
+ -13279,-13370,-13462,-13554,-13645,-13736,-13828,-13919,
+ -14010,-14101,-14191,-14282,-14372,-14462,-14553,-14643,
+ -14732,-14822,-14912,-15001,-15090,-15180,-15269,-15358,
+ -15446,-15535,-15623,-15712,-15800,-15888,-15976,-16063,
+ -16151,-16238,-16325,-16413,-16499,-16586,-16673,-16759,
+ -16846,-16932,-17018,-17104,-17189,-17275,-17360,-17445,
+ -17530,-17615,-17700,-17784,-17869,-17953,-18037,-18121,
+ -18204,-18288,-18371,-18454,-18537,-18620,-18703,-18785,
+ -18868,-18950,-19032,-19113,-19195,-19276,-19357,-19438,
+ -19519,-19600,-19680,-19761,-19841,-19921,-20000,-20080,
+ -20159,-20238,-20317,-20396,-20475,-20553,-20631,-20709,
+ -20787,-20865,-20942,-21019,-21096,-21173,-21250,-21326,
+ -21403,-21479,-21554,-21630,-21705,-21781,-21856,-21930,
+ -22005,-22079,-22154,-22227,-22301,-22375,-22448,-22521,
+ -22594,-22667,-22739,-22812,-22884,-22956,-23027,-23099,
+ -23170,-23241,-23311,-23382,-23452,-23522,-23592,-23662,
+ -23731,-23801,-23870,-23938,-24007,-24075,-24143,-24211,
+ -24279,-24346,-24413,-24480,-24547,-24613,-24680,-24746,
+ -24811,-24877,-24942,-25007,-25072,-25137,-25201,-25265,
+ -25329,-25393,-25456,-25519,-25582,-25645,-25708,-25770,
+ -25832,-25893,-25955,-26016,-26077,-26138,-26198,-26259,
+ -26319,-26378,-26438,-26497,-26556,-26615,-26674,-26732,
+ -26790,-26848,-26905,-26962,-27019,-27076,-27133,-27189,
+ -27245,-27300,-27356,-27411,-27466,-27521,-27575,-27629,
+ -27683,-27737,-27790,-27843,-27896,-27949,-28001,-28053,
+ -28105,-28157,-28208,-28259,-28310,-28360,-28411,-28460,
+ -28510,-28560,-28609,-28658,-28706,-28755,-28803,-28850,
+ -28898,-28945,-28992,-29039,-29085,-29131,-29177,-29223,
+ -29268,-29313,-29358,-29403,-29447,-29491,-29534,-29578,
+ -29621,-29664,-29706,-29749,-29791,-29832,-29874,-29915,
+ -29956,-29997,-30037,-30077,-30117,-30156,-30195,-30234,
+ -30273,-30311,-30349,-30387,-30424,-30462,-30498,-30535,
+ -30571,-30607,-30643,-30679,-30714,-30749,-30783,-30818,
+ -30852,-30885,-30919,-30952,-30985,-31017,-31050,-31082,
+ -31113,-31145,-31176,-31206,-31237,-31267,-31297,-31327,
+ -31356,-31385,-31414,-31442,-31470,-31498,-31526,-31553,
+ -31580,-31607,-31633,-31659,-31685,-31710,-31736,-31760,
+ -31785,-31809,-31833,-31857,-31880,-31903,-31926,-31949,
+ -31971,-31993,-32014,-32036,-32057,-32077,-32098,-32118,
+ -32137,-32157,-32176,-32195,-32213,-32232,-32250,-32267,
+ -32285,-32302,-32318,-32335,-32351,-32367,-32382,-32397,
+ -32412,-32427,-32441,-32455,-32469,-32482,-32495,-32508,
+ -32521,-32533,-32545,-32556,-32567,-32578,-32589,-32599,
+ -32609,-32619,-32628,-32637,-32646,-32655,-32663,-32671,
+ -32678,-32685,-32692,-32699,-32705,-32711,-32717,-32722,
+ -32728,-32732,-32737,-32741,-32745,-32748,-32752,-32755,
+ -32757,-32759,-32761,-32763,-32765,-32766,-32766,-32767,
+ -32767,-32767,-32766,-32766,-32765,-32763,-32761,-32759,
+ -32757,-32755,-32752,-32748,-32745,-32741,-32737,-32732,
+ -32728,-32722,-32717,-32711,-32705,-32699,-32692,-32685,
+ -32678,-32671,-32663,-32655,-32646,-32637,-32628,-32619,
+ -32609,-32599,-32589,-32578,-32567,-32556,-32545,-32533,
+ -32521,-32508,-32495,-32482,-32469,-32455,-32441,-32427,
+ -32412,-32397,-32382,-32367,-32351,-32335,-32318,-32302,
+ -32285,-32267,-32250,-32232,-32213,-32195,-32176,-32157,
+ -32137,-32118,-32098,-32077,-32057,-32036,-32014,-31993,
+ -31971,-31949,-31926,-31903,-31880,-31857,-31833,-31809,
+ -31785,-31760,-31736,-31710,-31685,-31659,-31633,-31607,
+ -31580,-31553,-31526,-31498,-31470,-31442,-31414,-31385,
+ -31356,-31327,-31297,-31267,-31237,-31206,-31176,-31145,
+ -31113,-31082,-31050,-31017,-30985,-30952,-30919,-30885,
+ -30852,-30818,-30783,-30749,-30714,-30679,-30643,-30607,
+ -30571,-30535,-30498,-30462,-30424,-30387,-30349,-30311,
+ -30273,-30234,-30195,-30156,-30117,-30077,-30037,-29997,
+ -29956,-29915,-29874,-29832,-29791,-29749,-29706,-29664,
+ -29621,-29578,-29534,-29491,-29447,-29403,-29358,-29313,
+ -29268,-29223,-29177,-29131,-29085,-29039,-28992,-28945,
+ -28898,-28850,-28803,-28755,-28706,-28658,-28609,-28560,
+ -28510,-28460,-28411,-28360,-28310,-28259,-28208,-28157,
+ -28105,-28053,-28001,-27949,-27896,-27843,-27790,-27737,
+ -27683,-27629,-27575,-27521,-27466,-27411,-27356,-27300,
+ -27245,-27189,-27133,-27076,-27019,-26962,-26905,-26848,
+ -26790,-26732,-26674,-26615,-26556,-26497,-26438,-26378,
+ -26319,-26259,-26198,-26138,-26077,-26016,-25955,-25893,
+ -25832,-25770,-25708,-25645,-25582,-25519,-25456,-25393,
+ -25329,-25265,-25201,-25137,-25072,-25007,-24942,-24877,
+ -24811,-24746,-24680,-24613,-24547,-24480,-24413,-24346,
+ -24279,-24211,-24143,-24075,-24007,-23938,-23870,-23801,
+ -23731,-23662,-23592,-23522,-23452,-23382,-23311,-23241,
+ -23170,-23099,-23027,-22956,-22884,-22812,-22739,-22667,
+ -22594,-22521,-22448,-22375,-22301,-22227,-22154,-22079,
+ -22005,-21930,-21856,-21781,-21705,-21630,-21554,-21479,
+ -21403,-21326,-21250,-21173,-21096,-21019,-20942,-20865,
+ -20787,-20709,-20631,-20553,-20475,-20396,-20317,-20238,
+ -20159,-20080,-20000,-19921,-19841,-19761,-19680,-19600,
+ -19519,-19438,-19357,-19276,-19195,-19113,-19032,-18950,
+ -18868,-18785,-18703,-18620,-18537,-18454,-18371,-18288,
+ -18204,-18121,-18037,-17953,-17869,-17784,-17700,-17615,
+ -17530,-17445,-17360,-17275,-17189,-17104,-17018,-16932,
+ -16846,-16759,-16673,-16586,-16499,-16413,-16325,-16238,
+ -16151,-16063,-15976,-15888,-15800,-15712,-15623,-15535,
+ -15446,-15358,-15269,-15180,-15090,-15001,-14912,-14822,
+ -14732,-14643,-14553,-14462,-14372,-14282,-14191,-14101,
+ -14010,-13919,-13828,-13736,-13645,-13554,-13462,-13370,
+ -13279,-13187,-13094,-13002,-12910,-12817,-12725,-12632,
+ -12539,-12446,-12353,-12260,-12167,-12074,-11980,-11886,
+ -11793,-11699,-11605,-11511,-11417,-11322,-11228,-11133,
+ -11039,-10944,-10849,-10754,-10659,-10564,-10469,-10374,
+ -10278,-10183,-10087,-9992,-9896,-9800,-9704,-9608,
+ -9512,-9416,-9319,-9223,-9126,-9030,-8933,-8836,
+ -8739,-8642,-8545,-8448,-8351,-8254,-8157,-8059,
+ -7962,-7864,-7767,-7669,-7571,-7473,-7375,-7277,
+ -7179,-7081,-6983,-6885,-6786,-6688,-6590,-6491,
+ -6393,-6294,-6195,-6096,-5998,-5899,-5800,-5701,
+ -5602,-5503,-5404,-5305,-5205,-5106,-5007,-4907,
+ -4808,-4708,-4609,-4509,-4410,-4310,-4210,-4111,
+ -4011,-3911,-3811,-3712,-3612,-3512,-3412,-3312,
+ -3212,-3112,-3012,-2911,-2811,-2711,-2611,-2511,
+ -2410,-2310,-2210,-2110,-2009,-1909,-1809,-1708,
+ -1608,-1507,-1407,-1307,-1206,-1106,-1005,-905,
+ -804,-704,-603,-503,-402,-302,-201,-101
+};
+#endif
+
diff --git a/arm-hybrid-22k/lib_src/eas_ima_tables.c b/arm-hybrid-22k/lib_src/eas_ima_tables.c
index 56bd1eb..b03b4d4 100644
--- a/arm-hybrid-22k/lib_src/eas_ima_tables.c
+++ b/arm-hybrid-22k/lib_src/eas_ima_tables.c
@@ -1,12 +1,12 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_ima_tables.c
- *
- * Contents and purpose:
- * Contains the constant tables for IMA encode/decode
- *
- * Copyright (c) 2005 Sonic Network Inc.
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_ima_tables.c
+ *
+ * Contents and purpose:
+ * Contains the constant tables for IMA encode/decode
+ *
+ * Copyright (c) 2005 Sonic Network Inc.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,36 +19,36 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 760 $
- * $Date: 2007-07-17 23:09:36 -0700 (Tue, 17 Jul 2007) $
- *----------------------------------------------------------------------------
-*/
-
-#include "eas_types.h"
-
-/*----------------------------------------------------------------------------
- * ADPCM decode tables
- *----------------------------------------------------------------------------
-*/
-const EAS_I16 imaIndexTable[16] =
-{
- -1, -1, -1, -1, 2, 4, 6, 8,
- -1, -1, -1, -1, 2, 4, 6, 8
-};
-
-const EAS_I16 imaStepSizeTable[89] =
-{
- 7, 8, 9, 10, 11, 12, 13, 14, 16, 17,
- 19, 21, 23, 25, 28, 31, 34, 37, 41, 45,
- 50, 55, 60, 66, 73, 80, 88, 97, 107, 118,
- 130, 143, 157, 173, 190, 209, 230, 253, 279, 307,
- 337, 371, 408, 449, 494, 544, 598, 658, 724, 796,
- 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066,
- 2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358,
- 5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,
- 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767
-};
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 760 $
+ * $Date: 2007-07-17 23:09:36 -0700 (Tue, 17 Jul 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+#include "eas_types.h"
+
+/*----------------------------------------------------------------------------
+ * ADPCM decode tables
+ *----------------------------------------------------------------------------
+*/
+const EAS_I16 imaIndexTable[16] =
+{
+ -1, -1, -1, -1, 2, 4, 6, 8,
+ -1, -1, -1, -1, 2, 4, 6, 8
+};
+
+const EAS_I16 imaStepSizeTable[89] =
+{
+ 7, 8, 9, 10, 11, 12, 13, 14, 16, 17,
+ 19, 21, 23, 25, 28, 31, 34, 37, 41, 45,
+ 50, 55, 60, 66, 73, 80, 88, 97, 107, 118,
+ 130, 143, 157, 173, 190, 209, 230, 253, 279, 307,
+ 337, 371, 408, 449, 494, 544, 598, 658, 724, 796,
+ 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066,
+ 2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358,
+ 5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,
+ 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767
+};
+
diff --git a/arm-hybrid-22k/lib_src/eas_imaadpcm.c b/arm-hybrid-22k/lib_src/eas_imaadpcm.c
index 68bf257..41280b5 100644
--- a/arm-hybrid-22k/lib_src/eas_imaadpcm.c
+++ b/arm-hybrid-22k/lib_src/eas_imaadpcm.c
@@ -1,12 +1,12 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_imaadpcm.c
- *
- * Contents and purpose:
- * Implements the IMA ADPCM decoder
- *
- * Copyright Sonic Network Inc. 2005
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_imaadpcm.c
+ *
+ * Contents and purpose:
+ * Implements the IMA ADPCM decoder
+ *
+ * Copyright Sonic Network Inc. 2005
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,350 +19,350 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 847 $
- * $Date: 2007-08-27 21:30:08 -0700 (Mon, 27 Aug 2007) $
- *----------------------------------------------------------------------------
-*/
-
-#include "eas_data.h"
-#include "eas_host.h"
-#include "eas_pcm.h"
-#include "eas_math.h"
-#include "eas_report.h"
-
-// #define _DEBUG_IMA_ADPCM_LOCATE
-
-/*----------------------------------------------------------------------------
- * externs
- *----------------------------------------------------------------------------
-*/
-extern const EAS_I16 imaIndexTable[];
-extern const EAS_I16 imaStepSizeTable[];
-
-/*----------------------------------------------------------------------------
- * prototypes
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT IMADecoderInit (EAS_DATA_HANDLE pEASData, S_PCM_STATE *pState);
-static EAS_RESULT IMADecoderSample (EAS_DATA_HANDLE pEASData, S_PCM_STATE *pState);
-static void IMADecoderADPCM (S_DECODER_STATE *pState, EAS_U8 nibble);
-static EAS_RESULT IMADecoderLocate (EAS_DATA_HANDLE pEASData, S_PCM_STATE *pState, EAS_I32 time);
-
-/*----------------------------------------------------------------------------
- * IMA ADPCM Decoder interface
- *----------------------------------------------------------------------------
-*/
-const S_DECODER_INTERFACE IMADecoder =
-{
- IMADecoderInit,
- IMADecoderSample,
- IMADecoderLocate
-};
-
-/*----------------------------------------------------------------------------
- * IMADecoderInit()
- *----------------------------------------------------------------------------
- * Purpose:
- * Initializes the IMA ADPCM decoder
- *
- * Inputs:
- *
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, pEASData) common decoder interface - pEASData not used */
-static EAS_RESULT IMADecoderInit (EAS_DATA_HANDLE pEASData, S_PCM_STATE *pState)
-{
- pState->decoderL.step = 0;
- pState->decoderR.step = 0;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * IMADecoderSample()
- *----------------------------------------------------------------------------
- * Purpose:
- * Decodes an IMA ADPCM sample
- *
- * Inputs:
- *
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT IMADecoderSample (EAS_DATA_HANDLE pEASData, S_PCM_STATE *pState)
-{
- EAS_RESULT result;
- EAS_I16 sTemp;
-
- /* if high nibble, decode */
- if (pState->hiNibble)
- {
- IMADecoderADPCM(&pState->decoderL, (EAS_U8)(pState->srcByte >> 4));
- pState->hiNibble = EAS_FALSE;
- }
-
- /* low nibble, need to fetch another byte */
- else
- {
- /* check for loop */
- if ((pState->bytesLeft == 0) && (pState->loopSamples != 0))
- {
- /* seek to start of loop */
- if ((result = EAS_HWFileSeek(pEASData->hwInstData, pState->fileHandle, (EAS_I32) (pState->startPos + pState->loopLocation))) != EAS_SUCCESS)
- return result;
- pState->bytesLeft = pState->byteCount = (EAS_I32) pState->bytesLeftLoop;
- pState->blockCount = 0;
- pState->flags &= ~PCM_FLAGS_EMPTY;
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMADecoderSample: Rewind file to %d, bytesLeft = %d\n", pState->startPos, pState->bytesLeft); */ }
- }
-
- /* if start of block, fetch new predictor and step index */
- if ((pState->blockSize != 0) && (pState->blockCount == 0) && (pState->bytesLeft != 0))
- {
-
- /* get predicted sample for left channel */
- if ((result = EAS_HWGetWord(pEASData->hwInstData, pState->fileHandle, &sTemp, EAS_FALSE)) != EAS_SUCCESS)
- return result;
-#ifdef _DEBUG_IMA_ADPCM
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Predictor: Was %d, now %d\n", pState->decoderL.acc, sTemp); */ }
-#endif
- pState->decoderL.acc = pState->decoderL.x1 = sTemp;
-
- /* get step index for left channel - upper 8 bits are reserved */
- if ((result = EAS_HWGetWord(pEASData->hwInstData, pState->fileHandle, &sTemp, EAS_FALSE)) != EAS_SUCCESS)
- return result;
-#ifdef _DEBUG_IMA_ADPCM
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Step: Was %d, now %d\n", pState->decoderL.step, sTemp); */ }
-#endif
- pState->decoderL.step = sTemp & 0xff;
-
- if (pState->flags & PCM_FLAGS_STEREO)
- {
- /* get predicted sample for right channel */
- if ((result = EAS_HWGetWord(pEASData->hwInstData, pState->fileHandle, &sTemp, EAS_FALSE)) != EAS_SUCCESS)
- return result;
- pState->decoderR.acc = pState->decoderR.x1 = sTemp;
-
- /* get step index for right channel - upper 8 bits are reserved */
- if ((result = EAS_HWGetWord(pEASData->hwInstData, pState->fileHandle, &sTemp, EAS_FALSE)) != EAS_SUCCESS)
- return result;
-#ifdef _DEBUG_IMA_ADPCM
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Step: Was %d, now %d\n", pState->decoderR.step, sTemp); */ }
-#endif
- pState->decoderR.step = sTemp & 0xff;
-
- pState->blockCount = pState->blockSize - 8;
- pState->bytesLeft -= 8;
- }
- else
- {
- pState->blockCount = pState->blockSize - 4;
- pState->bytesLeft -= 4;
- }
- }
- else
- {
-
- /* get another ADPCM data pair */
- if (pState->bytesLeft)
- {
-
- if ((result = EAS_HWGetByte(pEASData->hwInstData, pState->fileHandle, &pState->srcByte)) != EAS_SUCCESS)
- return result;
-
- /* decode the low nibble */
- pState->bytesLeft--;
- pState->blockCount--;
- IMADecoderADPCM(&pState->decoderL, (EAS_U8)(pState->srcByte & 0x0f));
-
- if (pState->flags & PCM_FLAGS_STEREO)
- IMADecoderADPCM(&pState->decoderR, (EAS_U8)(pState->srcByte >> 4));
- else
- pState->hiNibble = EAS_TRUE;
- }
-
- /* out of ADPCM data, generate enough samples to fill buffer */
- else
- {
- pState->decoderL.x1 = pState->decoderL.x0;
- pState->decoderR.x1 = pState->decoderR.x0;
- }
- }
- }
-
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * IMADecoderADPCM()
- *----------------------------------------------------------------------------
- * Purpose:
- * Decodes an IMA ADPCM sample
- *
- * Inputs:
- *
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static void IMADecoderADPCM (S_DECODER_STATE *pState, EAS_U8 nibble)
-{
- EAS_INT delta;
- EAS_INT stepSize;
-
- /* get stepsize from table */
- stepSize = imaStepSizeTable[pState->step];
-
- /* delta = (abs(delta) + 0.5) * step / 4 */
- delta = 0;
- if (nibble & 4)
- delta += stepSize;
-
- if (nibble & 2)
- /*lint -e{702} use shift for performance */
- delta += stepSize >> 1;
-
- if (nibble & 1)
- /*lint -e{702} use shift for performance */
- delta += stepSize >> 2;
-
- /*lint -e{702} use shift for performance */
- delta += stepSize >> 3;
-
- /* integrate the delta */
- if (nibble & 8)
- pState->acc -= delta;
- else
- pState->acc += delta;
-
- /* saturate */
- if (pState->acc > 32767)
- pState->acc = 32767;
- if (pState->acc < -32768)
- pState->acc = -32768;
- pState->x1 = (EAS_PCM) pState->acc;
-
- /* compute new step size */
- pState->step += imaIndexTable[nibble];
- if (pState->step < 0)
- pState->step = 0;
- if (pState->step > 88)
- pState->step = 88;
-
-#ifdef _DEBUG_IMA_ADPCM
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "In=%u, Pred=%d, Step=%d\n", nibble, pState->acc, imaStepSizeTable[pState->step]); */ }
-#endif
-}
-
-/*----------------------------------------------------------------------------
- * IMADecoderLocate()
- *----------------------------------------------------------------------------
- * Locate in an IMA ADPCM stream
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT IMADecoderLocate (EAS_DATA_HANDLE pEASData, S_PCM_STATE *pState, EAS_I32 time)
-{
- EAS_RESULT result;
- EAS_I32 temp;
- EAS_I32 samplesPerBlock;
- EAS_I32 secs, msecs;
-
- /* no need to calculate if time is zero */
- if (time == 0)
- temp = 0;
-
- /* not zero */
- else
- {
-
- /* can't seek if not a blocked file */
- if (pState->blockSize == 0)
- return EAS_ERROR_FEATURE_NOT_AVAILABLE;
-
- /* calculate number of samples per block */
- if (pState->flags & PCM_FLAGS_STEREO)
- samplesPerBlock = pState->blockSize - 7;
- else
- samplesPerBlock = (pState->blockSize << 1) - 7;
-
- /* break down into secs and msecs */
- secs = time / 1000;
- msecs = time - (secs * 1000);
-
- /* calculate sample number fraction from msecs */
- temp = (msecs * pState->sampleRate);
- temp = (temp >> 10) + ((temp * 49) >> 21);
-
- /* add integer sample count */
- temp += secs * pState->sampleRate;
-
-#ifdef _DEBUG_IMA_ADPCM_LOCATE
- EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x2380b977, 0x00000006 , time, temp);
-#endif
-
- /* for looped samples, calculate position in the loop */
- if ((temp > pState->byteCount) && (pState->loopSamples != 0))
- {
- EAS_I32 numBlocks;
- EAS_I32 samplesPerLoop;
- EAS_I32 samplesInLastBlock;
-
- numBlocks = (EAS_I32) (pState->loopStart / pState->blockSize);
- samplesInLastBlock = (EAS_I32) pState->loopStart - (numBlocks * pState->blockSize);
- if (samplesInLastBlock)
- {
- if (pState->flags & PCM_FLAGS_STEREO)
- samplesInLastBlock = samplesInLastBlock - 7;
- else
- /*lint -e{703} use shift for performance */
- samplesInLastBlock = (samplesInLastBlock << 1) - 7;
- }
- samplesPerLoop = numBlocks * samplesPerBlock + samplesInLastBlock;
- temp = temp % samplesPerLoop;
-#ifdef _DEBUG_IMA_ADPCM_LOCATE
- EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x2380b977, 0x00000007 , numBlocks, samplesPerLoop, samplesInLastBlock, temp);
-#endif
- }
-
- /* find start of block for requested sample */
- temp = (temp / samplesPerBlock) * pState->blockSize;
-#ifdef _DEBUG_IMA_ADPCM_LOCATE
- EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x2380b977, 0x00000008 , temp);
-#endif
-
- }
-
- /* seek to new location */
- if ((result = EAS_PESeek(pEASData, pState, &temp)) != EAS_SUCCESS)
- return result;
-
-#ifdef _DEBUG_IMA_ADPCM_LOCATE
- EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x2380b977, 0x00000009 , pState->bytesLeft);
-#endif
-
- /* reset state */
- pState->blockCount = 0;
- pState->hiNibble = EAS_FALSE;
- if ((pState->state != EAS_STATE_PAUSING) && (pState->state != EAS_STATE_PAUSED))
- pState->state = EAS_STATE_READY;
-
- return EAS_SUCCESS;
-}
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 847 $
+ * $Date: 2007-08-27 21:30:08 -0700 (Mon, 27 Aug 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+#include "eas_data.h"
+#include "eas_host.h"
+#include "eas_pcm.h"
+#include "eas_math.h"
+#include "eas_report.h"
+
+// #define _DEBUG_IMA_ADPCM_LOCATE
+
+/*----------------------------------------------------------------------------
+ * externs
+ *----------------------------------------------------------------------------
+*/
+extern const EAS_I16 imaIndexTable[];
+extern const EAS_I16 imaStepSizeTable[];
+
+/*----------------------------------------------------------------------------
+ * prototypes
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT IMADecoderInit (EAS_DATA_HANDLE pEASData, S_PCM_STATE *pState);
+static EAS_RESULT IMADecoderSample (EAS_DATA_HANDLE pEASData, S_PCM_STATE *pState);
+static void IMADecoderADPCM (S_DECODER_STATE *pState, EAS_U8 nibble);
+static EAS_RESULT IMADecoderLocate (EAS_DATA_HANDLE pEASData, S_PCM_STATE *pState, EAS_I32 time);
+
+/*----------------------------------------------------------------------------
+ * IMA ADPCM Decoder interface
+ *----------------------------------------------------------------------------
+*/
+const S_DECODER_INTERFACE IMADecoder =
+{
+ IMADecoderInit,
+ IMADecoderSample,
+ IMADecoderLocate
+};
+
+/*----------------------------------------------------------------------------
+ * IMADecoderInit()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Initializes the IMA ADPCM decoder
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pEASData) common decoder interface - pEASData not used */
+static EAS_RESULT IMADecoderInit (EAS_DATA_HANDLE pEASData, S_PCM_STATE *pState)
+{
+ pState->decoderL.step = 0;
+ pState->decoderR.step = 0;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * IMADecoderSample()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Decodes an IMA ADPCM sample
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT IMADecoderSample (EAS_DATA_HANDLE pEASData, S_PCM_STATE *pState)
+{
+ EAS_RESULT result;
+ EAS_I16 sTemp;
+
+ /* if high nibble, decode */
+ if (pState->hiNibble)
+ {
+ IMADecoderADPCM(&pState->decoderL, (EAS_U8)(pState->srcByte >> 4));
+ pState->hiNibble = EAS_FALSE;
+ }
+
+ /* low nibble, need to fetch another byte */
+ else
+ {
+ /* check for loop */
+ if ((pState->bytesLeft == 0) && (pState->loopSamples != 0))
+ {
+ /* seek to start of loop */
+ if ((result = EAS_HWFileSeek(pEASData->hwInstData, pState->fileHandle, (EAS_I32) (pState->startPos + pState->loopLocation))) != EAS_SUCCESS)
+ return result;
+ pState->bytesLeft = pState->byteCount = (EAS_I32) pState->bytesLeftLoop;
+ pState->blockCount = 0;
+ pState->flags &= ~PCM_FLAGS_EMPTY;
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMADecoderSample: Rewind file to %d, bytesLeft = %d\n", pState->startPos, pState->bytesLeft); */ }
+ }
+
+ /* if start of block, fetch new predictor and step index */
+ if ((pState->blockSize != 0) && (pState->blockCount == 0) && (pState->bytesLeft != 0))
+ {
+
+ /* get predicted sample for left channel */
+ if ((result = EAS_HWGetWord(pEASData->hwInstData, pState->fileHandle, &sTemp, EAS_FALSE)) != EAS_SUCCESS)
+ return result;
+#ifdef _DEBUG_IMA_ADPCM
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Predictor: Was %d, now %d\n", pState->decoderL.acc, sTemp); */ }
+#endif
+ pState->decoderL.acc = pState->decoderL.x1 = sTemp;
+
+ /* get step index for left channel - upper 8 bits are reserved */
+ if ((result = EAS_HWGetWord(pEASData->hwInstData, pState->fileHandle, &sTemp, EAS_FALSE)) != EAS_SUCCESS)
+ return result;
+#ifdef _DEBUG_IMA_ADPCM
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Step: Was %d, now %d\n", pState->decoderL.step, sTemp); */ }
+#endif
+ pState->decoderL.step = sTemp & 0xff;
+
+ if (pState->flags & PCM_FLAGS_STEREO)
+ {
+ /* get predicted sample for right channel */
+ if ((result = EAS_HWGetWord(pEASData->hwInstData, pState->fileHandle, &sTemp, EAS_FALSE)) != EAS_SUCCESS)
+ return result;
+ pState->decoderR.acc = pState->decoderR.x1 = sTemp;
+
+ /* get step index for right channel - upper 8 bits are reserved */
+ if ((result = EAS_HWGetWord(pEASData->hwInstData, pState->fileHandle, &sTemp, EAS_FALSE)) != EAS_SUCCESS)
+ return result;
+#ifdef _DEBUG_IMA_ADPCM
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Step: Was %d, now %d\n", pState->decoderR.step, sTemp); */ }
+#endif
+ pState->decoderR.step = sTemp & 0xff;
+
+ pState->blockCount = pState->blockSize - 8;
+ pState->bytesLeft -= 8;
+ }
+ else
+ {
+ pState->blockCount = pState->blockSize - 4;
+ pState->bytesLeft -= 4;
+ }
+ }
+ else
+ {
+
+ /* get another ADPCM data pair */
+ if (pState->bytesLeft)
+ {
+
+ if ((result = EAS_HWGetByte(pEASData->hwInstData, pState->fileHandle, &pState->srcByte)) != EAS_SUCCESS)
+ return result;
+
+ /* decode the low nibble */
+ pState->bytesLeft--;
+ pState->blockCount--;
+ IMADecoderADPCM(&pState->decoderL, (EAS_U8)(pState->srcByte & 0x0f));
+
+ if (pState->flags & PCM_FLAGS_STEREO)
+ IMADecoderADPCM(&pState->decoderR, (EAS_U8)(pState->srcByte >> 4));
+ else
+ pState->hiNibble = EAS_TRUE;
+ }
+
+ /* out of ADPCM data, generate enough samples to fill buffer */
+ else
+ {
+ pState->decoderL.x1 = pState->decoderL.x0;
+ pState->decoderR.x1 = pState->decoderR.x0;
+ }
+ }
+ }
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * IMADecoderADPCM()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Decodes an IMA ADPCM sample
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static void IMADecoderADPCM (S_DECODER_STATE *pState, EAS_U8 nibble)
+{
+ EAS_INT delta;
+ EAS_INT stepSize;
+
+ /* get stepsize from table */
+ stepSize = imaStepSizeTable[pState->step];
+
+ /* delta = (abs(delta) + 0.5) * step / 4 */
+ delta = 0;
+ if (nibble & 4)
+ delta += stepSize;
+
+ if (nibble & 2)
+ /*lint -e{702} use shift for performance */
+ delta += stepSize >> 1;
+
+ if (nibble & 1)
+ /*lint -e{702} use shift for performance */
+ delta += stepSize >> 2;
+
+ /*lint -e{702} use shift for performance */
+ delta += stepSize >> 3;
+
+ /* integrate the delta */
+ if (nibble & 8)
+ pState->acc -= delta;
+ else
+ pState->acc += delta;
+
+ /* saturate */
+ if (pState->acc > 32767)
+ pState->acc = 32767;
+ if (pState->acc < -32768)
+ pState->acc = -32768;
+ pState->x1 = (EAS_PCM) pState->acc;
+
+ /* compute new step size */
+ pState->step += imaIndexTable[nibble];
+ if (pState->step < 0)
+ pState->step = 0;
+ if (pState->step > 88)
+ pState->step = 88;
+
+#ifdef _DEBUG_IMA_ADPCM
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "In=%u, Pred=%d, Step=%d\n", nibble, pState->acc, imaStepSizeTable[pState->step]); */ }
+#endif
+}
+
+/*----------------------------------------------------------------------------
+ * IMADecoderLocate()
+ *----------------------------------------------------------------------------
+ * Locate in an IMA ADPCM stream
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT IMADecoderLocate (EAS_DATA_HANDLE pEASData, S_PCM_STATE *pState, EAS_I32 time)
+{
+ EAS_RESULT result;
+ EAS_I32 temp;
+ EAS_I32 samplesPerBlock;
+ EAS_I32 secs, msecs;
+
+ /* no need to calculate if time is zero */
+ if (time == 0)
+ temp = 0;
+
+ /* not zero */
+ else
+ {
+
+ /* can't seek if not a blocked file */
+ if (pState->blockSize == 0)
+ return EAS_ERROR_FEATURE_NOT_AVAILABLE;
+
+ /* calculate number of samples per block */
+ if (pState->flags & PCM_FLAGS_STEREO)
+ samplesPerBlock = pState->blockSize - 7;
+ else
+ samplesPerBlock = (pState->blockSize << 1) - 7;
+
+ /* break down into secs and msecs */
+ secs = time / 1000;
+ msecs = time - (secs * 1000);
+
+ /* calculate sample number fraction from msecs */
+ temp = (msecs * pState->sampleRate);
+ temp = (temp >> 10) + ((temp * 49) >> 21);
+
+ /* add integer sample count */
+ temp += secs * pState->sampleRate;
+
+#ifdef _DEBUG_IMA_ADPCM_LOCATE
+ EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x2380b977, 0x00000006 , time, temp);
+#endif
+
+ /* for looped samples, calculate position in the loop */
+ if ((temp > pState->byteCount) && (pState->loopSamples != 0))
+ {
+ EAS_I32 numBlocks;
+ EAS_I32 samplesPerLoop;
+ EAS_I32 samplesInLastBlock;
+
+ numBlocks = (EAS_I32) (pState->loopStart / pState->blockSize);
+ samplesInLastBlock = (EAS_I32) pState->loopStart - (numBlocks * pState->blockSize);
+ if (samplesInLastBlock)
+ {
+ if (pState->flags & PCM_FLAGS_STEREO)
+ samplesInLastBlock = samplesInLastBlock - 7;
+ else
+ /*lint -e{703} use shift for performance */
+ samplesInLastBlock = (samplesInLastBlock << 1) - 7;
+ }
+ samplesPerLoop = numBlocks * samplesPerBlock + samplesInLastBlock;
+ temp = temp % samplesPerLoop;
+#ifdef _DEBUG_IMA_ADPCM_LOCATE
+ EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x2380b977, 0x00000007 , numBlocks, samplesPerLoop, samplesInLastBlock, temp);
+#endif
+ }
+
+ /* find start of block for requested sample */
+ temp = (temp / samplesPerBlock) * pState->blockSize;
+#ifdef _DEBUG_IMA_ADPCM_LOCATE
+ EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x2380b977, 0x00000008 , temp);
+#endif
+
+ }
+
+ /* seek to new location */
+ if ((result = EAS_PESeek(pEASData, pState, &temp)) != EAS_SUCCESS)
+ return result;
+
+#ifdef _DEBUG_IMA_ADPCM_LOCATE
+ EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x2380b977, 0x00000009 , pState->bytesLeft);
+#endif
+
+ /* reset state */
+ pState->blockCount = 0;
+ pState->hiNibble = EAS_FALSE;
+ if ((pState->state != EAS_STATE_PAUSING) && (pState->state != EAS_STATE_PAUSED))
+ pState->state = EAS_STATE_READY;
+
+ return EAS_SUCCESS;
+}
+
diff --git a/arm-hybrid-22k/lib_src/eas_imelody.c b/arm-hybrid-22k/lib_src/eas_imelody.c
index 9f4d541..698c7df 100644
--- a/arm-hybrid-22k/lib_src/eas_imelody.c
+++ b/arm-hybrid-22k/lib_src/eas_imelody.c
@@ -1,12 +1,12 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_imelody.c
- *
- * Contents and purpose:
- * iMelody parser
- *
- * Copyright Sonic Network Inc. 2005
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_imelody.c
+ *
+ * Contents and purpose:
+ * iMelody parser
+ *
+ * Copyright Sonic Network Inc. 2005
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,1720 +19,1720 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 797 $
- * $Date: 2007-08-01 00:15:56 -0700 (Wed, 01 Aug 2007) $
- *----------------------------------------------------------------------------
-*/
-
-/* lint doesn't like the way some string.h files look */
-#ifdef _lint
-#include "lint_stdlib.h"
-#else
-#include <string.h>
-#endif
-
-#include "eas_data.h"
-#include "eas_miditypes.h"
-#include "eas_parser.h"
-#include "eas_report.h"
-#include "eas_host.h"
-#include "eas_midi.h"
-#include "eas_config.h"
-#include "eas_vm_protos.h"
-#include "eas_imelodydata.h"
-#include "eas_ctype.h"
-
-// #define _DEBUG_IMELODY
-
-/* increase gain for mono ringtones */
-#define IMELODY_GAIN_OFFSET 8
-
-/* length of 32nd note in 1/256ths of a msec for 120 BPM tempo */
-#define DEFAULT_TICK_CONV 16000
-#define TICK_CONVERT 1920000
-
-/* default channel and program for iMelody playback */
-#define IMELODY_CHANNEL 0
-#define IMELODY_PROGRAM 80
-#define IMELODY_VEL_MUL 4
-#define IMELODY_VEL_OFS 67
-
-/* multiplier for fixed point triplet conversion */
-#define TRIPLET_MULTIPLIER 683
-#define TRIPLET_SHIFT 10
-
-static const char* const tokens[] =
-{
- "BEGIN:IMELODY",
- "VERSION:",
- "FORMAT:CLASS",
- "NAME:",
- "COMPOSER:",
- "BEAT:",
- "STYLE:",
- "VOLUME:",
- "MELODY:",
- "END:IMELODY"
-};
-
-/* ledon or ledoff */
-static const char ledStr[] = "edo";
-
-/* vibeon or vibeoff */
-static const char vibeStr[] = "ibeo";
-
-/* backon or backoff */
-static const char backStr[] = "cko";
-
-typedef enum
-{
- TOKEN_BEGIN,
- TOKEN_VERSION,
- TOKEN_FORMAT,
- TOKEN_NAME,
- TOKEN_COMPOSER,
- TOKEN_BEAT,
- TOKEN_STYLE,
- TOKEN_VOLUME,
- TOKEN_MELODY,
- TOKEN_END,
- TOKEN_INVALID
-} ENUM_IMELODY_TOKENS;
-
-/* lookup table for note values */
-static const EAS_I8 noteTable[] = { 9, 11, 0, 2, 4, 5, 7 };
-
-/* inline functions */
-#ifdef _DEBUG_IMELODY
-static void PutBackChar (S_IMELODY_DATA *pData)
-{
- if (pData->index)
- pData->index--;
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "PutBackChar '%c'\n", pData->buffer[pData->index]); */ }
-}
-#else
-EAS_INLINE void PutBackChar (S_IMELODY_DATA *pData) { if (pData->index) pData->index--; }
-#endif
-
-
-/* local prototypes */
-static EAS_RESULT IMY_CheckFileType (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle, EAS_VOID_PTR *ppHandle, EAS_I32 offset);
-static EAS_RESULT IMY_Prepare (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
-static EAS_RESULT IMY_Time (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_U32 *pTime);
-static EAS_RESULT IMY_Event (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_INT parserMode);
-static EAS_RESULT IMY_State (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_STATE *pState);
-static EAS_RESULT IMY_Close (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
-static EAS_RESULT IMY_Reset (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
-static EAS_RESULT IMY_Pause (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
-static EAS_RESULT IMY_Resume (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
-static EAS_RESULT IMY_SetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value);
-static EAS_RESULT IMY_GetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue);
-static EAS_BOOL IMY_PlayNote (S_EAS_DATA *pEASData, S_IMELODY_DATA *pData, EAS_I8 note, EAS_INT parserMode);
-static EAS_BOOL IMY_PlayRest (S_EAS_DATA *pEASData, S_IMELODY_DATA *pData);
-static EAS_BOOL IMY_GetDuration (EAS_HW_DATA_HANDLE hwInstData, S_IMELODY_DATA *pData, EAS_I32 *pDuration);
-static EAS_BOOL IMY_GetLEDState (S_EAS_DATA *pEASData, S_IMELODY_DATA *pData);
-static EAS_BOOL IMY_GetVibeState (S_EAS_DATA *pEASData, S_IMELODY_DATA *pData);
-static EAS_BOOL IMY_GetBackState (S_EAS_DATA *pEASData, S_IMELODY_DATA *pData);
-static EAS_BOOL IMY_GetVolume (EAS_HW_DATA_HANDLE hwInstData, S_IMELODY_DATA *pData, EAS_BOOL inHeader);
-static EAS_BOOL IMY_GetNumber (EAS_HW_DATA_HANDLE hwInstData, S_IMELODY_DATA *pData, EAS_INT *temp, EAS_BOOL inHeader);
-static EAS_RESULT IMY_ParseHeader (S_EAS_DATA *pEASData, S_IMELODY_DATA* pData);
-static EAS_I8 IMY_GetNextChar (EAS_HW_DATA_HANDLE hwInstData, S_IMELODY_DATA *pData, EAS_BOOL inHeader);
-static EAS_RESULT IMY_ReadLine (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE fileHandle, EAS_I8 *buffer, EAS_I32 *pStartLine);
-static EAS_INT IMY_ParseLine (EAS_I8 *buffer, EAS_U8 *pIndex);
-
-
-/*----------------------------------------------------------------------------
- *
- * EAS_iMelody_Parser
- *
- * This structure contains the functional interface for the iMelody parser
- *----------------------------------------------------------------------------
-*/
-const S_FILE_PARSER_INTERFACE EAS_iMelody_Parser =
-{
- IMY_CheckFileType,
- IMY_Prepare,
- IMY_Time,
- IMY_Event,
- IMY_State,
- IMY_Close,
- IMY_Reset,
- IMY_Pause,
- IMY_Resume,
- NULL,
- IMY_SetData,
- IMY_GetData,
- NULL
-};
-
-/*----------------------------------------------------------------------------
- * IMY_CheckFileType()
- *----------------------------------------------------------------------------
- * Purpose:
- * Check the file type to see if we can parse it
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT IMY_CheckFileType (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle, EAS_VOID_PTR *ppHandle, EAS_I32 offset)
-{
- S_IMELODY_DATA* pData;
- EAS_I8 buffer[MAX_LINE_SIZE+1];
- EAS_U8 index;
-
-#ifdef _DEBUG_IMELODY
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Enter IMY_CheckFileType\n"); */ }
-#endif
-
- /* read the first line of the file */
- *ppHandle = NULL;
- if (IMY_ReadLine(pEASData->hwInstData, fileHandle, buffer, NULL) != EAS_SUCCESS)
- return EAS_SUCCESS;
-
- /* check for header string */
- if (IMY_ParseLine(buffer, &index) == TOKEN_BEGIN)
- {
-
- /* check for static memory allocation */
- if (pEASData->staticMemoryModel)
- pData = EAS_CMEnumData(EAS_CM_IMELODY_DATA);
- else
- pData = EAS_HWMalloc(pEASData->hwInstData, sizeof(S_IMELODY_DATA));
- if (!pData)
- return EAS_ERROR_MALLOC_FAILED;
- EAS_HWMemSet(pData, 0, sizeof(S_IMELODY_DATA));
-
- /* initialize */
- pData->fileHandle = fileHandle;
- pData->fileOffset = offset;
- pData->state = EAS_STATE_ERROR;
- pData->state = EAS_STATE_OPEN;
-
- /* return a pointer to the instance data */
- *ppHandle = pData;
- }
-
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * IMY_Prepare()
- *----------------------------------------------------------------------------
- * Purpose:
- * Prepare to parse the file. Allocates instance data (or uses static allocation for
- * static memory model).
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT IMY_Prepare (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
-{
- S_IMELODY_DATA* pData;
- EAS_RESULT result;
-
-#ifdef _DEBUG_IMELODY
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Enter IMY_Prepare\n"); */ }
-#endif
-
- /* check for valid state */
- pData = (S_IMELODY_DATA*) pInstData;
- if (pData->state != EAS_STATE_OPEN)
- return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
-
- /* instantiate a synthesizer */
- if ((result = VMInitMIDI(pEASData, &pData->pSynth)) != EAS_SUCCESS)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "VMInitMIDI returned %d\n", result); */ }
- return result;
- }
-
- /* parse the header */
- if ((result = IMY_ParseHeader(pEASData, pData)) != EAS_SUCCESS)
- return result;
-
-#ifdef _DEBUG_IMELODY
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_Prepare: state set to EAS_STATE_READY\n"); */ }
-#endif
-
- pData ->state = EAS_STATE_READY;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * IMY_Time()
- *----------------------------------------------------------------------------
- * Purpose:
- * Returns the time of the next event in msecs
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- * pTime - pointer to variable to hold time of next event (in msecs)
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, pEASData) common decoder interface - pEASData not used */
-static EAS_RESULT IMY_Time (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_U32 *pTime)
-{
- S_IMELODY_DATA *pData;
-
- pData = (S_IMELODY_DATA*) pInstData;
-
- /* return time in milliseconds */
- /*lint -e{704} use shift instead of division */
- *pTime = pData->time >> 8;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * IMY_Event()
- *----------------------------------------------------------------------------
- * Purpose:
- * Parse the next event in the file
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT IMY_Event (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_INT parserMode)
-{
- S_IMELODY_DATA* pData;
- EAS_RESULT result;
- EAS_I8 c;
- EAS_BOOL eof;
- EAS_INT temp;
-
- pData = (S_IMELODY_DATA*) pInstData;
- if (pData->state >= EAS_STATE_OPEN)
- return EAS_SUCCESS;
-
- /* initialize MIDI channel when the track starts playing */
- if (pData->time == 0)
- {
-
-#ifdef _DEBUG_IMELODY
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_Event: Reset\n"); */ }
-#endif
- /* set program to square lead */
- VMProgramChange(pEASData->pVoiceMgr, pData->pSynth, IMELODY_CHANNEL, IMELODY_PROGRAM);
-
- /* set channel volume to max */
- VMControlChange(pEASData->pVoiceMgr, pData->pSynth, IMELODY_CHANNEL, 7, 127);
- }
-
- /* check for end of note */
- if (pData->note)
- {
-
-#ifdef _DEBUG_IMELODY
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Stopping note %d\n", pData->note); */ }
-#endif
- /* stop the note */
- VMStopNote(pEASData->pVoiceMgr, pData->pSynth, IMELODY_CHANNEL, pData->note, 0);
- pData->note = 0;
-
- /* check for rest between notes */
- if (pData->restTicks)
- {
- pData->time += pData->restTicks;
- pData->restTicks = 0;
- return EAS_SUCCESS;
- }
- }
-
- /* parse the next event */
- eof = EAS_FALSE;
- while (!eof)
- {
-
- /* get next character */
- c = IMY_GetNextChar(pEASData->hwInstData, pData, EAS_FALSE);
-
- switch (c)
- {
- /* start repeat */
- case '(':
-
-#ifdef _DEBUG_IMELODY
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Enter repeat section\n", c); */ }
-#endif
-
- if (pData->repeatOffset < 0)
- {
- pData->repeatOffset = pData->startLine + (EAS_I32) pData->index;
-
-#ifdef _DEBUG_IMELODY
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Repeat offset = %d\n", pData->repeatOffset); */ }
-#endif
- }
- else
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Ignoring nested repeat section\n"); */ }
- break;
-
- /* end repeat */
- case ')':
-
-#ifdef _DEBUG_IMELODY
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "End repeat section, repeat offset = %d\n", pData->repeatOffset); */ }
-#endif
- /* ignore invalid repeats */
- if (pData->repeatCount >= 0)
- {
-
- /* decrement repeat count (repeatCount == 0 means infinite loop) */
- if (pData->repeatCount > 0)
- {
- if (--pData->repeatCount == 0)
- {
- pData->repeatCount = -1;
-#ifdef _DEBUG_IMELODY
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Repeat loop complete\n"); */ }
-#endif
- }
- }
-
-//2 TEMPORARY FIX: If locating, don't do infinite loops.
-//3 We need a different mode for metadata parsing where we don't loop at all
- if ((parserMode == eParserModePlay) || (pData->repeatCount != 0))
- {
-
-#ifdef _DEBUG_IMELODY
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Rewinding file for repeat\n"); */ }
-#endif
- /* rewind to start of loop */
- if ((result = EAS_HWFileSeek(pEASData->hwInstData, pData->fileHandle, pData->repeatOffset)) != EAS_SUCCESS)
- return result;
- IMY_ReadLine(pEASData->hwInstData, pData->fileHandle, pData->buffer, &pData->startLine);
- pData->index = 0;
-
- /* if last loop, prevent future loops */
- if (pData->repeatCount == -1)
- pData->repeatOffset = -1;
- }
- }
- break;
-
- /* repeat count */
- case '@':
- if (!IMY_GetNumber(pEASData->hwInstData, pData, &temp, EAS_FALSE))
- eof = EAS_TRUE;
- else if (pData->repeatOffset > 0)
- {
-
-#ifdef _DEBUG_IMELODY
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Repeat count = %dt", pData->repeatCount); */ }
-#endif
- if (pData->repeatCount < 0)
- pData->repeatCount = (EAS_I16) temp;
- }
- break;
-
- /* volume */
- case 'V':
- if (!IMY_GetVolume(pEASData->hwInstData, pData, EAS_FALSE))
- eof = EAS_TRUE;
- break;
-
- /* flat */
- case '&':
- pData->noteModifier = -1;
- break;
-
- /* sharp */
- case '#':
- pData->noteModifier = +1;
- break;
-
- /* octave */
- case '*':
- c = IMY_GetNextChar(pEASData->hwInstData, pData, EAS_FALSE);
- if (IsDigit(c))
- pData->octave = (EAS_U8) ((c - '0' + 1) * 12);
- else if (!c)
- eof = EAS_TRUE;
- break;
-
- /* ledon or ledoff */
- case 'l':
- if (!IMY_GetLEDState(pEASData, pData))
- eof = EAS_TRUE;
- break;
-
- /* vibeon or vibeoff */
- case 'v':
- if (!IMY_GetVibeState(pEASData, pData))
- eof = EAS_TRUE;
- break;
-
- /* either a B note or backon or backoff */
- case 'b':
- if (IMY_GetNextChar(pEASData->hwInstData, pData, EAS_FALSE) == 'a')
- {
- if (!IMY_GetBackState(pEASData, pData))
- eof = EAS_TRUE;
- }
- else
- {
- PutBackChar(pData);
- if (IMY_PlayNote(pEASData, pData, c, parserMode))
- return EAS_SUCCESS;
- eof = EAS_TRUE;
- }
- break;
-
- /* rest */
- case 'r':
- case 'R':
- if (IMY_PlayRest(pEASData, pData))
- return EAS_SUCCESS;
- eof = EAS_TRUE;
- break;
-
- /* EOF */
- case 0:
-#ifdef _DEBUG_IMELODY
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_Event: end of iMelody file detected\n"); */ }
-#endif
- eof = EAS_TRUE;
- break;
-
- /* must be a note */
- default:
- c = ToLower(c);
- if ((c >= 'a') && (c <= 'g'))
- {
- if (IMY_PlayNote(pEASData, pData, c, parserMode))
- return EAS_SUCCESS;
- eof = EAS_TRUE;
- }
- else
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Ignoring unexpected character '%c' [0x%02x]\n", c, c); */ }
- break;
- }
- }
-
- /* handle EOF */
-#ifdef _DEBUG_IMELODY
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_Event: state set to EAS_STATE_STOPPING\n"); */ }
-#endif
- pData->state = EAS_STATE_STOPPING;
- VMReleaseAllVoices(pEASData->pVoiceMgr, pData->pSynth);
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * IMY_State()
- *----------------------------------------------------------------------------
- * Purpose:
- * Returns the current state of the stream
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- * pState - pointer to variable to store state
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, pEASData) common decoder interface - pEASData not used */
-static EAS_RESULT IMY_State (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 *pState)
-{
- S_IMELODY_DATA* pData;
-
- /* establish pointer to instance data */
- pData = (S_IMELODY_DATA*) pInstData;
-
- /* if stopping, check to see if synth voices are active */
- if (pData->state == EAS_STATE_STOPPING)
- {
- if (VMActiveVoices(pData->pSynth) == 0)
- {
- pData->state = EAS_STATE_STOPPED;
-#ifdef _DEBUG_IMELODY
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_State: state set to EAS_STATE_STOPPED\n"); */ }
-#endif
- }
- }
-
- if (pData->state == EAS_STATE_PAUSING)
- {
- if (VMActiveVoices(pData->pSynth) == 0)
- {
-#ifdef _DEBUG_IMELODY
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_State: state set to EAS_STATE_PAUSED\n"); */ }
-#endif
- pData->state = EAS_STATE_PAUSED;
- }
- }
-
- /* return current state */
- *pState = pData->state;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * IMY_Close()
- *----------------------------------------------------------------------------
- * Purpose:
- * Close the file and clean up
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT IMY_Close (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
-{
- S_IMELODY_DATA* pData;
- EAS_RESULT result;
-
-#ifdef _DEBUG_IMELODY
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_Close: close file\n"); */ }
-#endif
-
- pData = (S_IMELODY_DATA*) pInstData;
-
- /* close the file */
- if ((result = EAS_HWCloseFile(pEASData->hwInstData, pData->fileHandle)) != EAS_SUCCESS)
- return result;
-
- /* free the synth */
- if (pData->pSynth != NULL)
- VMMIDIShutdown(pEASData, pData->pSynth);
-
- /* if using dynamic memory, free it */
- if (!pEASData->staticMemoryModel)
- EAS_HWFree(pEASData->hwInstData, pData);
-
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * IMY_Reset()
- *----------------------------------------------------------------------------
- * Purpose:
- * Reset the sequencer. Used for locating backwards in the file.
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT IMY_Reset (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
-{
- S_IMELODY_DATA* pData;
- EAS_RESULT result;
-
-#ifdef _DEBUG_IMELODY
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_Reset: reset file\n"); */ }
-#endif
- pData = (S_IMELODY_DATA*) pInstData;
-
- /* reset the synth */
- VMReset(pEASData->pVoiceMgr, pData->pSynth, EAS_TRUE);
-
- /* reset time to zero */
- pData->time = 0;
- pData->note = 0;
-
- /* reset file position and re-parse header */
- pData->state = EAS_STATE_ERROR;
- if ((result = EAS_HWFileSeek(pEASData->hwInstData, pData->fileHandle, pData->fileOffset)) != EAS_SUCCESS)
- return result;
- if ((result = IMY_ParseHeader (pEASData, pData)) != EAS_SUCCESS)
- return result;
-
-#ifdef _DEBUG_IMELODY
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_Reset: state set to EAS_STATE_ERROR\n"); */ }
-#endif
-
- pData->state = EAS_STATE_READY;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * IMY_Pause()
- *----------------------------------------------------------------------------
- * Purpose:
- * Pauses the sequencer. Mutes all voices and sets state to pause.
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT IMY_Pause (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
-{
- S_IMELODY_DATA *pData;
-
-#ifdef _DEBUG_IMELODY
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_Pause: pause file\n"); */ }
-#endif
-
- /* can't pause a stopped stream */
- pData = (S_IMELODY_DATA*) pInstData;
- if (pData->state == EAS_STATE_STOPPED)
- return EAS_ERROR_ALREADY_STOPPED;
-
- /* mute the synthesizer */
- VMMuteAllVoices(pEASData->pVoiceMgr, pData->pSynth);
- pData->state = EAS_STATE_PAUSING;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * IMY_Resume()
- *----------------------------------------------------------------------------
- * Purpose:
- * Resume playing after a pause, sets state back to playing.
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, pEASData) common decoder interface - pEASData not used */
-static EAS_RESULT IMY_Resume (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
-{
- S_IMELODY_DATA *pData;
-
-#ifdef _DEBUG_IMELODY
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_Resume: resume file\n"); */ }
-#endif
-
- /* can't resume a stopped stream */
- pData = (S_IMELODY_DATA*) pInstData;
- if (pData->state == EAS_STATE_STOPPED)
- return EAS_ERROR_ALREADY_STOPPED;
-
- /* nothing to do but resume playback */
- pData->state = EAS_STATE_PLAY;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * IMY_SetData()
- *----------------------------------------------------------------------------
- * Purpose:
- * Adjust tempo relative to song tempo
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * pInstData - pointer to iMelody instance data
- * rate - rate (28-bit fractional amount)
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, pEASData) common decoder interface - pEASData not used */
-static EAS_RESULT IMY_SetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value)
-{
- S_IMELODY_DATA *pData;
-
- pData = (S_IMELODY_DATA*) pInstData;
- switch (param)
- {
-
- /* set metadata callback */
- case PARSER_DATA_METADATA_CB:
- EAS_HWMemCpy(&pData->metadata, (void*) value, sizeof(S_METADATA_CB));
- break;
-
- default:
- return EAS_ERROR_INVALID_PARAMETER;
- }
-
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * IMY_GetData()
- *----------------------------------------------------------------------------
- * Purpose:
- * Return the file type
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * pInstData - pointer to iMelody instance data
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, pEASData) common decoder interface - pEASData not used */
-static EAS_RESULT IMY_GetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue)
-{
- S_IMELODY_DATA *pData;
-
- pData = (S_IMELODY_DATA*) pInstData;
-
- switch (param)
- {
- /* return file type as iMelody */
- case PARSER_DATA_FILE_TYPE:
- *pValue = EAS_FILE_IMELODY;
- break;
-
- case PARSER_DATA_SYNTH_HANDLE:
- *pValue = (EAS_I32) pData->pSynth;
- break;
-
- case PARSER_DATA_GAIN_OFFSET:
- *pValue = IMELODY_GAIN_OFFSET;
- break;
-
- default:
- return EAS_ERROR_INVALID_PARAMETER;
- }
-
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * IMY_PlayNote()
- *----------------------------------------------------------------------------
- * Purpose:
- *
- *
- * Inputs:
- *
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_BOOL IMY_PlayNote (S_EAS_DATA *pEASData, S_IMELODY_DATA *pData, EAS_I8 note, EAS_INT parserMode)
-{
- EAS_I32 duration;
- EAS_U8 velocity;
-
-
-#ifdef _DEBUG_IMELODY
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_PlayNote: start note %d\n", note); */ }
-#endif
-
- /* get the duration */
- if (!IMY_GetDuration(pEASData->hwInstData, pData, &duration))
- return EAS_FALSE;
-
- /* save note value */
- pData->note = (EAS_U8) (pData->octave + noteTable[note - 'a'] + pData->noteModifier);
- velocity = (EAS_U8) (pData->volume ? pData->volume * IMELODY_VEL_MUL + IMELODY_VEL_OFS : 0);
-
- /* start note only if in play mode */
- if (parserMode == eParserModePlay)
- VMStartNote(pEASData->pVoiceMgr, pData->pSynth, IMELODY_CHANNEL, pData->note, velocity);
-
-#ifdef _DEBUG_IMELODY
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_PlayNote: Start note %d, duration %d\n", pData->note, duration); */ }
-#endif
-
- /* determine note length */
- switch (pData->style)
- {
- case 0:
- /*lint -e{704} shift for performance */
- pData->restTicks = duration >> 4;
- break;
- case 1:
- pData->restTicks = 0;
- break;
- case 2:
- /*lint -e{704} shift for performance */
- pData->restTicks = duration >> 1;
- break;
- default:
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "IMY_PlayNote: Note style out of range: %d\n", pData->style); */ }
- /*lint -e{704} shift for performance */
- pData->restTicks = duration >> 4;
- break;
- }
-
- /* next event is at end of this note */
- pData->time += duration - pData->restTicks;
-
- /* reset the flat/sharp modifier */
- pData->noteModifier = 0;
-
- return EAS_TRUE;
-}
-
-/*----------------------------------------------------------------------------
- * IMY_PlayRest()
- *----------------------------------------------------------------------------
- * Purpose:
- *
- *
- * Inputs:
- *
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_BOOL IMY_PlayRest (S_EAS_DATA *pEASData, S_IMELODY_DATA *pData)
-{
- EAS_I32 duration;
-
-#ifdef _DEBUG_IMELODY
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Enter IMY_PlayRest]n"); */ }
-#endif
-
- /* get the duration */
- if (!IMY_GetDuration(pEASData->hwInstData, pData, &duration))
- return EAS_FALSE;
-
-#ifdef _DEBUG_IMELODY
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_PlayRest: note duration %d\n", duration); */ }
-#endif
-
- /* next event is at end of this note */
- pData->time += duration;
- return EAS_TRUE;
-}
-
-/*----------------------------------------------------------------------------
- * IMY_GetDuration()
- *----------------------------------------------------------------------------
- * Purpose:
- *
- *
- * Inputs:
- *
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-
-static EAS_BOOL IMY_GetDuration (EAS_HW_DATA_HANDLE hwInstData, S_IMELODY_DATA *pData, EAS_I32 *pDuration)
-{
- EAS_I32 duration;
- EAS_I8 c;
-
- /* get the duration */
- *pDuration = 0;
- c = IMY_GetNextChar(hwInstData, pData, EAS_FALSE);
- if (!c)
- return EAS_FALSE;
- if ((c < '0') || (c > '5'))
- {
-#ifdef _DEBUG_IMELODY
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_GetDuration: error in duration '%c'\n", c); */ }
-#endif
- return EAS_FALSE;
- }
-
- /* calculate total length of note */
- duration = pData->tick * (1 << ('5' - c));
-
- /* check for duration modifier */
- c = IMY_GetNextChar(hwInstData, pData, EAS_FALSE);
- if (c)
- {
- if (c == '.')
- /*lint -e{704} shift for performance */
- duration += duration >> 1;
- else if (c == ':')
- /*lint -e{704} shift for performance */
- duration += (duration >> 1) + (duration >> 2);
- else if (c == ';')
- /*lint -e{704} shift for performance */
- duration = (duration * TRIPLET_MULTIPLIER) >> TRIPLET_SHIFT;
- else
- PutBackChar(pData);
- }
-
- *pDuration = duration;
- return EAS_TRUE;
-}
-
-/*----------------------------------------------------------------------------
- * IMY_GetLEDState()
- *----------------------------------------------------------------------------
- * Purpose:
- *
- *
- * Inputs:
- *
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_BOOL IMY_GetLEDState (S_EAS_DATA *pEASData, S_IMELODY_DATA *pData)
-{
- EAS_I8 c;
- EAS_INT i;
-
-#ifdef _DEBUG_IMELODY
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Enter IMY_GetLEDState\n"); */ }
-#endif
-
- for (i = 0; i < 5; i++)
- {
- c = IMY_GetNextChar(pEASData->hwInstData, pData, EAS_FALSE);
- if (!c)
- return EAS_FALSE;
- switch (i)
- {
- case 3:
- if (c == 'n')
- {
-#ifdef _DEBUG_IMELODY
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_GetLEDState: LED on\n"); */ }
-#endif
- EAS_HWLED(pEASData->hwInstData, EAS_TRUE);
- return EAS_TRUE;
- }
- else if (c != 'f')
- return EAS_FALSE;
- break;
-
- case 4:
- if (c == 'f')
- {
-#ifdef _DEBUG_IMELODY
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_GetLEDState: LED off\n"); */ }
-#endif
- EAS_HWLED(pEASData->hwInstData, EAS_FALSE);
- return EAS_TRUE;
- }
- return EAS_FALSE;
-
- default:
- if (c != ledStr[i])
- return EAS_FALSE;
- break;
- }
- }
- return EAS_FALSE;
-}
-
-/*----------------------------------------------------------------------------
- * IMY_GetVibeState()
- *----------------------------------------------------------------------------
- * Purpose:
- *
- *
- * Inputs:
- *
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_BOOL IMY_GetVibeState (S_EAS_DATA *pEASData, S_IMELODY_DATA *pData)
-{
- EAS_I8 c;
- EAS_INT i;
-
-#ifdef _DEBUG_IMELODY
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Enter IMY_GetVibeState\n"); */ }
-#endif
-
- for (i = 0; i < 6; i++)
- {
- c = IMY_GetNextChar(pEASData->hwInstData, pData, EAS_FALSE);
- if (!c)
- return EAS_FALSE;
- switch (i)
- {
- case 4:
- if (c == 'n')
- {
-#ifdef _DEBUG_IMELODY
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_GetVibeState: vibrate on\n"); */ }
-#endif
- EAS_HWVibrate(pEASData->hwInstData, EAS_TRUE);
- return EAS_TRUE;
- }
- else if (c != 'f')
- return EAS_FALSE;
- break;
-
- case 5:
- if (c == 'f')
- {
-#ifdef _DEBUG_IMELODY
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_GetVibeState: vibrate off\n"); */ }
-#endif
- EAS_HWVibrate(pEASData->hwInstData, EAS_FALSE);
- return EAS_TRUE;
- }
- return EAS_FALSE;
-
- default:
- if (c != vibeStr[i])
- return EAS_FALSE;
- break;
- }
- }
- return EAS_FALSE;
-}
-
-/*----------------------------------------------------------------------------
- * IMY_GetBackState()
- *----------------------------------------------------------------------------
- * Purpose:
- *
- *
- * Inputs:
- *
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_BOOL IMY_GetBackState (S_EAS_DATA *pEASData, S_IMELODY_DATA *pData)
-{
- EAS_I8 c;
- EAS_INT i;
-
-#ifdef _DEBUG_IMELODY
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Enter IMY_GetBackState\n"); */ }
-#endif
-
- for (i = 0; i < 5; i++)
- {
- c = IMY_GetNextChar(pEASData->hwInstData, pData, EAS_FALSE);
- if (!c)
- return EAS_FALSE;
- switch (i)
- {
- case 3:
- if (c == 'n')
- {
-#ifdef _DEBUG_IMELODY
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_GetBackState: backlight on\n"); */ }
-#endif
- EAS_HWBackLight(pEASData->hwInstData, EAS_TRUE);
- return EAS_TRUE;
- }
- else if (c != 'f')
- return EAS_FALSE;
- break;
-
- case 4:
- if (c == 'f')
- {
-#ifdef _DEBUG_IMELODY
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_GetBackState: backlight off\n"); */ }
-#endif
- EAS_HWBackLight(pEASData->hwInstData, EAS_FALSE);
- return EAS_TRUE;
- }
- return EAS_FALSE;
-
- default:
- if (c != backStr[i])
- return EAS_FALSE;
- break;
- }
- }
- return EAS_FALSE;
-}
-
-/*----------------------------------------------------------------------------
- * IMY_GetVolume()
- *----------------------------------------------------------------------------
- * Purpose:
- *
- *
- * Inputs:
- *
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_BOOL IMY_GetVolume (EAS_HW_DATA_HANDLE hwInstData, S_IMELODY_DATA *pData, EAS_BOOL inHeader)
-{
- EAS_INT temp;
- EAS_I8 c;
-
-#ifdef _DEBUG_IMELODY
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Enter IMY_GetVolume\n"); */ }
-#endif
-
- c = IMY_GetNextChar(hwInstData, pData, inHeader);
- if (c == '+')
- {
- if (pData->volume < 15)
- pData->volume++;
- return EAS_TRUE;
- }
- else if (c == '-')
- {
- if (pData->volume > 0)
- pData->volume--;
- return EAS_TRUE;
- }
- else if (IsDigit(c))
- temp = c - '0';
- else
- return EAS_FALSE;
-
- c = IMY_GetNextChar(hwInstData, pData, inHeader);
- if (IsDigit(c))
- temp = temp * 10 + c - '0';
- else if (c)
- PutBackChar(pData);
- if ((temp >= 0) && (temp <= 15))
- {
- if (inHeader && (temp == 0))
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Ignoring V0 encountered in header\n"); */ }
- else
- pData->volume = (EAS_U8) temp;
- }
- return EAS_TRUE;
-}
-
-/*----------------------------------------------------------------------------
- * IMY_GetNumber()
- *----------------------------------------------------------------------------
- * Purpose:
- *
- *
- * Inputs:
- *
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_BOOL IMY_GetNumber (EAS_HW_DATA_HANDLE hwInstData, S_IMELODY_DATA *pData, EAS_INT *temp, EAS_BOOL inHeader)
-{
- EAS_BOOL ok;
- EAS_I8 c;
-
-#ifdef _DEBUG_IMELODY
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Enter IMY_GetNumber\n"); */ }
-#endif
-
- *temp = 0;
- ok = EAS_FALSE;
- for (;;)
- {
- c = IMY_GetNextChar(hwInstData, pData, inHeader);
- if (IsDigit(c))
- {
- *temp = *temp * 10 + c - '0';
- ok = EAS_TRUE;
- }
- else
- {
- if (c)
- PutBackChar(pData);
-
-#ifdef _DEBUG_IMELODY
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_GetNumber: value %d\n", *temp); */ }
-#endif
-
- return ok;
- }
- }
-}
-
-/*----------------------------------------------------------------------------
- * IMY_GetVersion()
- *----------------------------------------------------------------------------
- * Purpose:
- *
- *
- * Inputs:
- *
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_BOOL IMY_GetVersion (S_IMELODY_DATA *pData, EAS_INT *pVersion)
-{
- EAS_I8 c;
- EAS_INT temp;
- EAS_INT version;
-
- version = temp = 0;
- for (;;)
- {
- c = pData->buffer[pData->index++];
- if ((c == 0) || (c == '.'))
- {
- /*lint -e{701} use shift for performance */
- version = (version << 8) + temp;
- if (c == 0)
- {
-
-#ifdef _DEBUG_IMELODY
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_GetVersion: version 0x%04x\n", version); */ }
-#endif
-
- *pVersion = version;
- return EAS_TRUE;
- }
- temp = 0;
- }
- else if (IsDigit(c))
- temp = (temp * 10) + c - '0';
- }
-}
-
-/*----------------------------------------------------------------------------
- * IMY_MetaData()
- *----------------------------------------------------------------------------
- * Purpose:
- * Prepare to parse the file. Allocates instance data (or uses static allocation for
- * static memory model).
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static void IMY_MetaData (S_IMELODY_DATA *pData, E_EAS_METADATA_TYPE metaType, EAS_I8 *buffer)
-{
- EAS_I32 len;
-
- /* check for callback */
- if (!pData->metadata.callback)
- return;
-
- /* copy data to host buffer */
- len = (EAS_I32) strlen((char*) buffer);
- if (len >pData->metadata.bufferSize)
- len = pData->metadata.bufferSize;
- strncpy((char*) pData->metadata.buffer, (char*) buffer, (size_t) len);
- pData->metadata.buffer[len] = 0;
-
- /* callback to host */
- pData->metadata.callback(metaType, pData->metadata.buffer, pData->metadata.pUserData);
-}
-
-/*----------------------------------------------------------------------------
- * IMY_ParseHeader()
- *----------------------------------------------------------------------------
- * Purpose:
- * Prepare to parse the file. Allocates instance data (or uses static allocation for
- * static memory model).
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT IMY_ParseHeader (S_EAS_DATA *pEASData, S_IMELODY_DATA* pData)
-{
- EAS_RESULT result;
- EAS_INT token;
- EAS_INT temp;
- EAS_I8 c;
-
-#ifdef _DEBUG_IMELODY
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Enter IMY_ParseHeader\n"); */ }
-#endif
-
- /* initialize some defaults */
- pData->time = 0;
- pData->tick = DEFAULT_TICK_CONV;
- pData->note = 0;
- pData->noteModifier = 0;
- pData ->restTicks = 0;
- pData->volume = 7;
- pData->octave = 60;
- pData->repeatOffset = -1;
- pData->repeatCount = -1;
- pData->style = 0;
-
- /* force the read of the first line */
- pData->index = 1;
-
- /* read data until we get to melody */
- for (;;)
- {
- /* read a line from the file and parse the token */
- if (pData->index != 0)
- {
- if ((result = IMY_ReadLine(pEASData->hwInstData, pData->fileHandle, pData->buffer, &pData->startLine)) != EAS_SUCCESS)
- {
-#ifdef _DEBUG_IMELODY
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_ParseHeader: IMY_ReadLine returned %d\n", result); */ }
-#endif
- return result;
- }
- }
- token = IMY_ParseLine(pData->buffer, &pData->index);
-
- switch (token)
- {
- /* ignore these valid tokens */
- case TOKEN_BEGIN:
- break;
-
- case TOKEN_FORMAT:
- if (!IMY_GetVersion(pData, &temp))
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Invalid FORMAT field '%s'\n", pData->buffer); */ }
- return EAS_ERROR_FILE_FORMAT;
- }
- if ((temp != 0x0100) && (temp != 0x0200))
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Unsupported FORMAT %02x\n", temp); */ }
- return EAS_ERROR_UNRECOGNIZED_FORMAT;
- }
- break;
-
- case TOKEN_VERSION:
- if (!IMY_GetVersion(pData, &temp))
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Invalid VERSION field '%s'\n", pData->buffer); */ }
- return EAS_ERROR_FILE_FORMAT;
- }
- if ((temp != 0x0100) && (temp != 0x0102))
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Unsupported VERSION %02x\n", temp); */ }
- return EAS_ERROR_UNRECOGNIZED_FORMAT;
- }
- break;
-
- case TOKEN_NAME:
- IMY_MetaData(pData, EAS_METADATA_TITLE, pData->buffer + pData->index);
- break;
-
- case TOKEN_COMPOSER:
- IMY_MetaData(pData, EAS_METADATA_AUTHOR, pData->buffer + pData->index);
- break;
-
- /* handle beat */
- case TOKEN_BEAT:
- IMY_GetNumber(pEASData->hwInstData, pData, &temp, EAS_TRUE);
- if ((temp >= 25) && (temp <= 900))
- pData->tick = TICK_CONVERT / temp;
- break;
-
- /* handle style */
- case TOKEN_STYLE:
- c = IMY_GetNextChar(pEASData->hwInstData, pData, EAS_TRUE);
- if (c == 'S')
- c = IMY_GetNextChar(pEASData->hwInstData, pData, EAS_TRUE);
- if ((c >= '0') && (c <= '2'))
- pData->style = (EAS_U8) (c - '0');
- else
- {
- PutBackChar(pData);
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Error in style command: %s\n", pData->buffer); */ }
- }
- break;
-
- /* handle volume */
- case TOKEN_VOLUME:
- c = IMY_GetNextChar(pEASData->hwInstData, pData, EAS_TRUE);
- if (c != 'V')
- {
- PutBackChar(pData);
- if (!IsDigit(c))
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Error in volume command: %s\n", pData->buffer); */ }
- break;
- }
- }
- IMY_GetVolume(pEASData->hwInstData, pData, EAS_TRUE);
- break;
-
- case TOKEN_MELODY:
-#ifdef _DEBUG_IMELODY
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Header successfully parsed\n"); */ }
-#endif
- return EAS_SUCCESS;
-
- case TOKEN_END:
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Unexpected END:IMELODY encountered\n"); */ }
- return EAS_ERROR_FILE_FORMAT;
-
- default:
- /* force a read of the next line */
- pData->index = 1;
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Ignoring unrecognized token in iMelody file: %s\n", pData->buffer); */ }
- break;
- }
- }
-}
-
-/*----------------------------------------------------------------------------
- * IMY_GetNextChar()
- *----------------------------------------------------------------------------
- * Purpose:
- *
- *
- * Inputs:
- *
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_I8 IMY_GetNextChar (EAS_HW_DATA_HANDLE hwInstData, S_IMELODY_DATA *pData, EAS_BOOL inHeader)
-{
- EAS_I8 c;
- EAS_U8 index;
-
- for (;;)
- {
- /* get next character */
- c = pData->buffer[pData->index++];
-
- /* buffer empty, read more */
- if (!c)
- {
- /* don't read the next line in the header */
- if (inHeader)
- return 0;
-
- pData->index = 0;
- pData->buffer[0] = 0;
- if (IMY_ReadLine(hwInstData, pData->fileHandle, pData->buffer, &pData->startLine) != EAS_SUCCESS)
- {
-#ifdef _DEBUG_IMELODY
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_GetNextChar: EOF\n"); */ }
-#endif
- return 0;
- }
-
- /* check for END:IMELODY token */
- if (IMY_ParseLine(pData->buffer, &index) == TOKEN_END)
- {
-#ifdef _DEBUG_IMELODY
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_GetNextChar: found END:IMELODY\n"); */ }
-#endif
- pData->buffer[0] = 0;
- return 0;
- }
- continue;
- }
-
- /* ignore white space */
- if (!IsSpace(c))
- {
-
-#ifdef _DEBUG_IMELODY
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_GetNextChar returned '%c'\n", c); */ }
-#endif
- return c;
- }
- }
-}
-
-/*----------------------------------------------------------------------------
- * IMY_ReadLine()
- *----------------------------------------------------------------------------
- * Purpose:
- * Reads a line of input from the file, discarding the CR/LF
- *
- * Inputs:
- *
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT IMY_ReadLine (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE fileHandle, EAS_I8 *buffer, EAS_I32 *pStartLine)
-{
- EAS_RESULT result;
- EAS_INT i;
- EAS_I8 c;
-
- /* fetch current file position and save it */
- if (pStartLine != NULL)
- {
- if ((result = EAS_HWFilePos(hwInstData, fileHandle, pStartLine)) != EAS_SUCCESS)
- {
-#ifdef _DEBUG_IMELODY
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_ParseHeader: EAS_HWFilePos returned %d\n", result); */ }
-#endif
- return result;
- }
- }
-
- buffer[0] = 0;
- for (i = 0; i < MAX_LINE_SIZE; )
- {
- if ((result = EAS_HWGetByte(hwInstData, fileHandle, &c)) != EAS_SUCCESS)
- {
- if ((result == EAS_EOF) && (i > 0))
- break;
- return result;
- }
-
- /* return on LF or end of data */
- if (c == '\n')
- break;
-
- /* store characters in buffer */
- if (c != '\r')
- buffer[i++] = c;
- }
- buffer[i] = 0;
-
-#ifdef _DEBUG_IMELODY
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_ReadLine read %s\n", buffer); */ }
-#endif
-
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * IMY_ParseLine()
- *----------------------------------------------------------------------------
- * Purpose:
- *
- *
- * Inputs:
- *
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_INT IMY_ParseLine (EAS_I8 *buffer, EAS_U8 *pIndex)
-{
- EAS_INT i;
- EAS_INT j;
-
- /* there's no strnicmp() in stdlib, so we have to roll our own */
- for (i = 0; i < TOKEN_INVALID; i++)
- {
- for (j = 0; ; j++)
- {
- /* end of token, must be a match */
- if (tokens[i][j] == 0)
- {
-#ifdef _DEBUG_IMELODY
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_ParseLine found token %d\n", i); */ }
-#endif
- *pIndex = (EAS_U8) j;
- return i;
- }
- if (tokens[i][j] != ToUpper(buffer[j]))
- break;
- }
- }
-#ifdef _DEBUG_IMELODY
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_ParseLine: no token found\n"); */ }
-#endif
- return TOKEN_INVALID;
-}
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 797 $
+ * $Date: 2007-08-01 00:15:56 -0700 (Wed, 01 Aug 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+/* lint doesn't like the way some string.h files look */
+#ifdef _lint
+#include "lint_stdlib.h"
+#else
+#include <string.h>
+#endif
+
+#include "eas_data.h"
+#include "eas_miditypes.h"
+#include "eas_parser.h"
+#include "eas_report.h"
+#include "eas_host.h"
+#include "eas_midi.h"
+#include "eas_config.h"
+#include "eas_vm_protos.h"
+#include "eas_imelodydata.h"
+#include "eas_ctype.h"
+
+// #define _DEBUG_IMELODY
+
+/* increase gain for mono ringtones */
+#define IMELODY_GAIN_OFFSET 8
+
+/* length of 32nd note in 1/256ths of a msec for 120 BPM tempo */
+#define DEFAULT_TICK_CONV 16000
+#define TICK_CONVERT 1920000
+
+/* default channel and program for iMelody playback */
+#define IMELODY_CHANNEL 0
+#define IMELODY_PROGRAM 80
+#define IMELODY_VEL_MUL 4
+#define IMELODY_VEL_OFS 67
+
+/* multiplier for fixed point triplet conversion */
+#define TRIPLET_MULTIPLIER 683
+#define TRIPLET_SHIFT 10
+
+static const char* const tokens[] =
+{
+ "BEGIN:IMELODY",
+ "VERSION:",
+ "FORMAT:CLASS",
+ "NAME:",
+ "COMPOSER:",
+ "BEAT:",
+ "STYLE:",
+ "VOLUME:",
+ "MELODY:",
+ "END:IMELODY"
+};
+
+/* ledon or ledoff */
+static const char ledStr[] = "edo";
+
+/* vibeon or vibeoff */
+static const char vibeStr[] = "ibeo";
+
+/* backon or backoff */
+static const char backStr[] = "cko";
+
+typedef enum
+{
+ TOKEN_BEGIN,
+ TOKEN_VERSION,
+ TOKEN_FORMAT,
+ TOKEN_NAME,
+ TOKEN_COMPOSER,
+ TOKEN_BEAT,
+ TOKEN_STYLE,
+ TOKEN_VOLUME,
+ TOKEN_MELODY,
+ TOKEN_END,
+ TOKEN_INVALID
+} ENUM_IMELODY_TOKENS;
+
+/* lookup table for note values */
+static const EAS_I8 noteTable[] = { 9, 11, 0, 2, 4, 5, 7 };
+
+/* inline functions */
+#ifdef _DEBUG_IMELODY
+static void PutBackChar (S_IMELODY_DATA *pData)
+{
+ if (pData->index)
+ pData->index--;
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "PutBackChar '%c'\n", pData->buffer[pData->index]); */ }
+}
+#else
+EAS_INLINE void PutBackChar (S_IMELODY_DATA *pData) { if (pData->index) pData->index--; }
+#endif
+
+
+/* local prototypes */
+static EAS_RESULT IMY_CheckFileType (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle, EAS_VOID_PTR *ppHandle, EAS_I32 offset);
+static EAS_RESULT IMY_Prepare (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
+static EAS_RESULT IMY_Time (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_U32 *pTime);
+static EAS_RESULT IMY_Event (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_INT parserMode);
+static EAS_RESULT IMY_State (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_STATE *pState);
+static EAS_RESULT IMY_Close (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
+static EAS_RESULT IMY_Reset (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
+static EAS_RESULT IMY_Pause (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
+static EAS_RESULT IMY_Resume (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
+static EAS_RESULT IMY_SetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value);
+static EAS_RESULT IMY_GetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue);
+static EAS_BOOL IMY_PlayNote (S_EAS_DATA *pEASData, S_IMELODY_DATA *pData, EAS_I8 note, EAS_INT parserMode);
+static EAS_BOOL IMY_PlayRest (S_EAS_DATA *pEASData, S_IMELODY_DATA *pData);
+static EAS_BOOL IMY_GetDuration (EAS_HW_DATA_HANDLE hwInstData, S_IMELODY_DATA *pData, EAS_I32 *pDuration);
+static EAS_BOOL IMY_GetLEDState (S_EAS_DATA *pEASData, S_IMELODY_DATA *pData);
+static EAS_BOOL IMY_GetVibeState (S_EAS_DATA *pEASData, S_IMELODY_DATA *pData);
+static EAS_BOOL IMY_GetBackState (S_EAS_DATA *pEASData, S_IMELODY_DATA *pData);
+static EAS_BOOL IMY_GetVolume (EAS_HW_DATA_HANDLE hwInstData, S_IMELODY_DATA *pData, EAS_BOOL inHeader);
+static EAS_BOOL IMY_GetNumber (EAS_HW_DATA_HANDLE hwInstData, S_IMELODY_DATA *pData, EAS_INT *temp, EAS_BOOL inHeader);
+static EAS_RESULT IMY_ParseHeader (S_EAS_DATA *pEASData, S_IMELODY_DATA* pData);
+static EAS_I8 IMY_GetNextChar (EAS_HW_DATA_HANDLE hwInstData, S_IMELODY_DATA *pData, EAS_BOOL inHeader);
+static EAS_RESULT IMY_ReadLine (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE fileHandle, EAS_I8 *buffer, EAS_I32 *pStartLine);
+static EAS_INT IMY_ParseLine (EAS_I8 *buffer, EAS_U8 *pIndex);
+
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_iMelody_Parser
+ *
+ * This structure contains the functional interface for the iMelody parser
+ *----------------------------------------------------------------------------
+*/
+const S_FILE_PARSER_INTERFACE EAS_iMelody_Parser =
+{
+ IMY_CheckFileType,
+ IMY_Prepare,
+ IMY_Time,
+ IMY_Event,
+ IMY_State,
+ IMY_Close,
+ IMY_Reset,
+ IMY_Pause,
+ IMY_Resume,
+ NULL,
+ IMY_SetData,
+ IMY_GetData,
+ NULL
+};
+
+/*----------------------------------------------------------------------------
+ * IMY_CheckFileType()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Check the file type to see if we can parse it
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT IMY_CheckFileType (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle, EAS_VOID_PTR *ppHandle, EAS_I32 offset)
+{
+ S_IMELODY_DATA* pData;
+ EAS_I8 buffer[MAX_LINE_SIZE+1];
+ EAS_U8 index;
+
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Enter IMY_CheckFileType\n"); */ }
+#endif
+
+ /* read the first line of the file */
+ *ppHandle = NULL;
+ if (IMY_ReadLine(pEASData->hwInstData, fileHandle, buffer, NULL) != EAS_SUCCESS)
+ return EAS_SUCCESS;
+
+ /* check for header string */
+ if (IMY_ParseLine(buffer, &index) == TOKEN_BEGIN)
+ {
+
+ /* check for static memory allocation */
+ if (pEASData->staticMemoryModel)
+ pData = EAS_CMEnumData(EAS_CM_IMELODY_DATA);
+ else
+ pData = EAS_HWMalloc(pEASData->hwInstData, sizeof(S_IMELODY_DATA));
+ if (!pData)
+ return EAS_ERROR_MALLOC_FAILED;
+ EAS_HWMemSet(pData, 0, sizeof(S_IMELODY_DATA));
+
+ /* initialize */
+ pData->fileHandle = fileHandle;
+ pData->fileOffset = offset;
+ pData->state = EAS_STATE_ERROR;
+ pData->state = EAS_STATE_OPEN;
+
+ /* return a pointer to the instance data */
+ *ppHandle = pData;
+ }
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * IMY_Prepare()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Prepare to parse the file. Allocates instance data (or uses static allocation for
+ * static memory model).
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT IMY_Prepare (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
+{
+ S_IMELODY_DATA* pData;
+ EAS_RESULT result;
+
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Enter IMY_Prepare\n"); */ }
+#endif
+
+ /* check for valid state */
+ pData = (S_IMELODY_DATA*) pInstData;
+ if (pData->state != EAS_STATE_OPEN)
+ return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
+
+ /* instantiate a synthesizer */
+ if ((result = VMInitMIDI(pEASData, &pData->pSynth)) != EAS_SUCCESS)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "VMInitMIDI returned %d\n", result); */ }
+ return result;
+ }
+
+ /* parse the header */
+ if ((result = IMY_ParseHeader(pEASData, pData)) != EAS_SUCCESS)
+ return result;
+
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_Prepare: state set to EAS_STATE_READY\n"); */ }
+#endif
+
+ pData ->state = EAS_STATE_READY;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * IMY_Time()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Returns the time of the next event in msecs
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ * pTime - pointer to variable to hold time of next event (in msecs)
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pEASData) common decoder interface - pEASData not used */
+static EAS_RESULT IMY_Time (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_U32 *pTime)
+{
+ S_IMELODY_DATA *pData;
+
+ pData = (S_IMELODY_DATA*) pInstData;
+
+ /* return time in milliseconds */
+ /*lint -e{704} use shift instead of division */
+ *pTime = pData->time >> 8;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * IMY_Event()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Parse the next event in the file
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT IMY_Event (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_INT parserMode)
+{
+ S_IMELODY_DATA* pData;
+ EAS_RESULT result;
+ EAS_I8 c;
+ EAS_BOOL eof;
+ EAS_INT temp;
+
+ pData = (S_IMELODY_DATA*) pInstData;
+ if (pData->state >= EAS_STATE_OPEN)
+ return EAS_SUCCESS;
+
+ /* initialize MIDI channel when the track starts playing */
+ if (pData->time == 0)
+ {
+
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_Event: Reset\n"); */ }
+#endif
+ /* set program to square lead */
+ VMProgramChange(pEASData->pVoiceMgr, pData->pSynth, IMELODY_CHANNEL, IMELODY_PROGRAM);
+
+ /* set channel volume to max */
+ VMControlChange(pEASData->pVoiceMgr, pData->pSynth, IMELODY_CHANNEL, 7, 127);
+ }
+
+ /* check for end of note */
+ if (pData->note)
+ {
+
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Stopping note %d\n", pData->note); */ }
+#endif
+ /* stop the note */
+ VMStopNote(pEASData->pVoiceMgr, pData->pSynth, IMELODY_CHANNEL, pData->note, 0);
+ pData->note = 0;
+
+ /* check for rest between notes */
+ if (pData->restTicks)
+ {
+ pData->time += pData->restTicks;
+ pData->restTicks = 0;
+ return EAS_SUCCESS;
+ }
+ }
+
+ /* parse the next event */
+ eof = EAS_FALSE;
+ while (!eof)
+ {
+
+ /* get next character */
+ c = IMY_GetNextChar(pEASData->hwInstData, pData, EAS_FALSE);
+
+ switch (c)
+ {
+ /* start repeat */
+ case '(':
+
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Enter repeat section\n", c); */ }
+#endif
+
+ if (pData->repeatOffset < 0)
+ {
+ pData->repeatOffset = pData->startLine + (EAS_I32) pData->index;
+
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Repeat offset = %d\n", pData->repeatOffset); */ }
+#endif
+ }
+ else
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Ignoring nested repeat section\n"); */ }
+ break;
+
+ /* end repeat */
+ case ')':
+
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "End repeat section, repeat offset = %d\n", pData->repeatOffset); */ }
+#endif
+ /* ignore invalid repeats */
+ if (pData->repeatCount >= 0)
+ {
+
+ /* decrement repeat count (repeatCount == 0 means infinite loop) */
+ if (pData->repeatCount > 0)
+ {
+ if (--pData->repeatCount == 0)
+ {
+ pData->repeatCount = -1;
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Repeat loop complete\n"); */ }
+#endif
+ }
+ }
+
+//2 TEMPORARY FIX: If locating, don't do infinite loops.
+//3 We need a different mode for metadata parsing where we don't loop at all
+ if ((parserMode == eParserModePlay) || (pData->repeatCount != 0))
+ {
+
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Rewinding file for repeat\n"); */ }
+#endif
+ /* rewind to start of loop */
+ if ((result = EAS_HWFileSeek(pEASData->hwInstData, pData->fileHandle, pData->repeatOffset)) != EAS_SUCCESS)
+ return result;
+ IMY_ReadLine(pEASData->hwInstData, pData->fileHandle, pData->buffer, &pData->startLine);
+ pData->index = 0;
+
+ /* if last loop, prevent future loops */
+ if (pData->repeatCount == -1)
+ pData->repeatOffset = -1;
+ }
+ }
+ break;
+
+ /* repeat count */
+ case '@':
+ if (!IMY_GetNumber(pEASData->hwInstData, pData, &temp, EAS_FALSE))
+ eof = EAS_TRUE;
+ else if (pData->repeatOffset > 0)
+ {
+
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Repeat count = %dt", pData->repeatCount); */ }
+#endif
+ if (pData->repeatCount < 0)
+ pData->repeatCount = (EAS_I16) temp;
+ }
+ break;
+
+ /* volume */
+ case 'V':
+ if (!IMY_GetVolume(pEASData->hwInstData, pData, EAS_FALSE))
+ eof = EAS_TRUE;
+ break;
+
+ /* flat */
+ case '&':
+ pData->noteModifier = -1;
+ break;
+
+ /* sharp */
+ case '#':
+ pData->noteModifier = +1;
+ break;
+
+ /* octave */
+ case '*':
+ c = IMY_GetNextChar(pEASData->hwInstData, pData, EAS_FALSE);
+ if (IsDigit(c))
+ pData->octave = (EAS_U8) ((c - '0' + 1) * 12);
+ else if (!c)
+ eof = EAS_TRUE;
+ break;
+
+ /* ledon or ledoff */
+ case 'l':
+ if (!IMY_GetLEDState(pEASData, pData))
+ eof = EAS_TRUE;
+ break;
+
+ /* vibeon or vibeoff */
+ case 'v':
+ if (!IMY_GetVibeState(pEASData, pData))
+ eof = EAS_TRUE;
+ break;
+
+ /* either a B note or backon or backoff */
+ case 'b':
+ if (IMY_GetNextChar(pEASData->hwInstData, pData, EAS_FALSE) == 'a')
+ {
+ if (!IMY_GetBackState(pEASData, pData))
+ eof = EAS_TRUE;
+ }
+ else
+ {
+ PutBackChar(pData);
+ if (IMY_PlayNote(pEASData, pData, c, parserMode))
+ return EAS_SUCCESS;
+ eof = EAS_TRUE;
+ }
+ break;
+
+ /* rest */
+ case 'r':
+ case 'R':
+ if (IMY_PlayRest(pEASData, pData))
+ return EAS_SUCCESS;
+ eof = EAS_TRUE;
+ break;
+
+ /* EOF */
+ case 0:
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_Event: end of iMelody file detected\n"); */ }
+#endif
+ eof = EAS_TRUE;
+ break;
+
+ /* must be a note */
+ default:
+ c = ToLower(c);
+ if ((c >= 'a') && (c <= 'g'))
+ {
+ if (IMY_PlayNote(pEASData, pData, c, parserMode))
+ return EAS_SUCCESS;
+ eof = EAS_TRUE;
+ }
+ else
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Ignoring unexpected character '%c' [0x%02x]\n", c, c); */ }
+ break;
+ }
+ }
+
+ /* handle EOF */
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_Event: state set to EAS_STATE_STOPPING\n"); */ }
+#endif
+ pData->state = EAS_STATE_STOPPING;
+ VMReleaseAllVoices(pEASData->pVoiceMgr, pData->pSynth);
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * IMY_State()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Returns the current state of the stream
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ * pState - pointer to variable to store state
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pEASData) common decoder interface - pEASData not used */
+static EAS_RESULT IMY_State (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 *pState)
+{
+ S_IMELODY_DATA* pData;
+
+ /* establish pointer to instance data */
+ pData = (S_IMELODY_DATA*) pInstData;
+
+ /* if stopping, check to see if synth voices are active */
+ if (pData->state == EAS_STATE_STOPPING)
+ {
+ if (VMActiveVoices(pData->pSynth) == 0)
+ {
+ pData->state = EAS_STATE_STOPPED;
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_State: state set to EAS_STATE_STOPPED\n"); */ }
+#endif
+ }
+ }
+
+ if (pData->state == EAS_STATE_PAUSING)
+ {
+ if (VMActiveVoices(pData->pSynth) == 0)
+ {
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_State: state set to EAS_STATE_PAUSED\n"); */ }
+#endif
+ pData->state = EAS_STATE_PAUSED;
+ }
+ }
+
+ /* return current state */
+ *pState = pData->state;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * IMY_Close()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Close the file and clean up
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT IMY_Close (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
+{
+ S_IMELODY_DATA* pData;
+ EAS_RESULT result;
+
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_Close: close file\n"); */ }
+#endif
+
+ pData = (S_IMELODY_DATA*) pInstData;
+
+ /* close the file */
+ if ((result = EAS_HWCloseFile(pEASData->hwInstData, pData->fileHandle)) != EAS_SUCCESS)
+ return result;
+
+ /* free the synth */
+ if (pData->pSynth != NULL)
+ VMMIDIShutdown(pEASData, pData->pSynth);
+
+ /* if using dynamic memory, free it */
+ if (!pEASData->staticMemoryModel)
+ EAS_HWFree(pEASData->hwInstData, pData);
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * IMY_Reset()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Reset the sequencer. Used for locating backwards in the file.
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT IMY_Reset (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
+{
+ S_IMELODY_DATA* pData;
+ EAS_RESULT result;
+
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_Reset: reset file\n"); */ }
+#endif
+ pData = (S_IMELODY_DATA*) pInstData;
+
+ /* reset the synth */
+ VMReset(pEASData->pVoiceMgr, pData->pSynth, EAS_TRUE);
+
+ /* reset time to zero */
+ pData->time = 0;
+ pData->note = 0;
+
+ /* reset file position and re-parse header */
+ pData->state = EAS_STATE_ERROR;
+ if ((result = EAS_HWFileSeek(pEASData->hwInstData, pData->fileHandle, pData->fileOffset)) != EAS_SUCCESS)
+ return result;
+ if ((result = IMY_ParseHeader (pEASData, pData)) != EAS_SUCCESS)
+ return result;
+
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_Reset: state set to EAS_STATE_ERROR\n"); */ }
+#endif
+
+ pData->state = EAS_STATE_READY;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * IMY_Pause()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Pauses the sequencer. Mutes all voices and sets state to pause.
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT IMY_Pause (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
+{
+ S_IMELODY_DATA *pData;
+
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_Pause: pause file\n"); */ }
+#endif
+
+ /* can't pause a stopped stream */
+ pData = (S_IMELODY_DATA*) pInstData;
+ if (pData->state == EAS_STATE_STOPPED)
+ return EAS_ERROR_ALREADY_STOPPED;
+
+ /* mute the synthesizer */
+ VMMuteAllVoices(pEASData->pVoiceMgr, pData->pSynth);
+ pData->state = EAS_STATE_PAUSING;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * IMY_Resume()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Resume playing after a pause, sets state back to playing.
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pEASData) common decoder interface - pEASData not used */
+static EAS_RESULT IMY_Resume (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
+{
+ S_IMELODY_DATA *pData;
+
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_Resume: resume file\n"); */ }
+#endif
+
+ /* can't resume a stopped stream */
+ pData = (S_IMELODY_DATA*) pInstData;
+ if (pData->state == EAS_STATE_STOPPED)
+ return EAS_ERROR_ALREADY_STOPPED;
+
+ /* nothing to do but resume playback */
+ pData->state = EAS_STATE_PLAY;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * IMY_SetData()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Adjust tempo relative to song tempo
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * pInstData - pointer to iMelody instance data
+ * rate - rate (28-bit fractional amount)
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pEASData) common decoder interface - pEASData not used */
+static EAS_RESULT IMY_SetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value)
+{
+ S_IMELODY_DATA *pData;
+
+ pData = (S_IMELODY_DATA*) pInstData;
+ switch (param)
+ {
+
+ /* set metadata callback */
+ case PARSER_DATA_METADATA_CB:
+ EAS_HWMemCpy(&pData->metadata, (void*) value, sizeof(S_METADATA_CB));
+ break;
+
+ default:
+ return EAS_ERROR_INVALID_PARAMETER;
+ }
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * IMY_GetData()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Return the file type
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * pInstData - pointer to iMelody instance data
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pEASData) common decoder interface - pEASData not used */
+static EAS_RESULT IMY_GetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue)
+{
+ S_IMELODY_DATA *pData;
+
+ pData = (S_IMELODY_DATA*) pInstData;
+
+ switch (param)
+ {
+ /* return file type as iMelody */
+ case PARSER_DATA_FILE_TYPE:
+ *pValue = EAS_FILE_IMELODY;
+ break;
+
+ case PARSER_DATA_SYNTH_HANDLE:
+ *pValue = (EAS_I32) pData->pSynth;
+ break;
+
+ case PARSER_DATA_GAIN_OFFSET:
+ *pValue = IMELODY_GAIN_OFFSET;
+ break;
+
+ default:
+ return EAS_ERROR_INVALID_PARAMETER;
+ }
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * IMY_PlayNote()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ *
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_BOOL IMY_PlayNote (S_EAS_DATA *pEASData, S_IMELODY_DATA *pData, EAS_I8 note, EAS_INT parserMode)
+{
+ EAS_I32 duration;
+ EAS_U8 velocity;
+
+
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_PlayNote: start note %d\n", note); */ }
+#endif
+
+ /* get the duration */
+ if (!IMY_GetDuration(pEASData->hwInstData, pData, &duration))
+ return EAS_FALSE;
+
+ /* save note value */
+ pData->note = (EAS_U8) (pData->octave + noteTable[note - 'a'] + pData->noteModifier);
+ velocity = (EAS_U8) (pData->volume ? pData->volume * IMELODY_VEL_MUL + IMELODY_VEL_OFS : 0);
+
+ /* start note only if in play mode */
+ if (parserMode == eParserModePlay)
+ VMStartNote(pEASData->pVoiceMgr, pData->pSynth, IMELODY_CHANNEL, pData->note, velocity);
+
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_PlayNote: Start note %d, duration %d\n", pData->note, duration); */ }
+#endif
+
+ /* determine note length */
+ switch (pData->style)
+ {
+ case 0:
+ /*lint -e{704} shift for performance */
+ pData->restTicks = duration >> 4;
+ break;
+ case 1:
+ pData->restTicks = 0;
+ break;
+ case 2:
+ /*lint -e{704} shift for performance */
+ pData->restTicks = duration >> 1;
+ break;
+ default:
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "IMY_PlayNote: Note style out of range: %d\n", pData->style); */ }
+ /*lint -e{704} shift for performance */
+ pData->restTicks = duration >> 4;
+ break;
+ }
+
+ /* next event is at end of this note */
+ pData->time += duration - pData->restTicks;
+
+ /* reset the flat/sharp modifier */
+ pData->noteModifier = 0;
+
+ return EAS_TRUE;
+}
+
+/*----------------------------------------------------------------------------
+ * IMY_PlayRest()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ *
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_BOOL IMY_PlayRest (S_EAS_DATA *pEASData, S_IMELODY_DATA *pData)
+{
+ EAS_I32 duration;
+
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Enter IMY_PlayRest]n"); */ }
+#endif
+
+ /* get the duration */
+ if (!IMY_GetDuration(pEASData->hwInstData, pData, &duration))
+ return EAS_FALSE;
+
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_PlayRest: note duration %d\n", duration); */ }
+#endif
+
+ /* next event is at end of this note */
+ pData->time += duration;
+ return EAS_TRUE;
+}
+
+/*----------------------------------------------------------------------------
+ * IMY_GetDuration()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ *
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+
+static EAS_BOOL IMY_GetDuration (EAS_HW_DATA_HANDLE hwInstData, S_IMELODY_DATA *pData, EAS_I32 *pDuration)
+{
+ EAS_I32 duration;
+ EAS_I8 c;
+
+ /* get the duration */
+ *pDuration = 0;
+ c = IMY_GetNextChar(hwInstData, pData, EAS_FALSE);
+ if (!c)
+ return EAS_FALSE;
+ if ((c < '0') || (c > '5'))
+ {
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_GetDuration: error in duration '%c'\n", c); */ }
+#endif
+ return EAS_FALSE;
+ }
+
+ /* calculate total length of note */
+ duration = pData->tick * (1 << ('5' - c));
+
+ /* check for duration modifier */
+ c = IMY_GetNextChar(hwInstData, pData, EAS_FALSE);
+ if (c)
+ {
+ if (c == '.')
+ /*lint -e{704} shift for performance */
+ duration += duration >> 1;
+ else if (c == ':')
+ /*lint -e{704} shift for performance */
+ duration += (duration >> 1) + (duration >> 2);
+ else if (c == ';')
+ /*lint -e{704} shift for performance */
+ duration = (duration * TRIPLET_MULTIPLIER) >> TRIPLET_SHIFT;
+ else
+ PutBackChar(pData);
+ }
+
+ *pDuration = duration;
+ return EAS_TRUE;
+}
+
+/*----------------------------------------------------------------------------
+ * IMY_GetLEDState()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ *
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_BOOL IMY_GetLEDState (S_EAS_DATA *pEASData, S_IMELODY_DATA *pData)
+{
+ EAS_I8 c;
+ EAS_INT i;
+
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Enter IMY_GetLEDState\n"); */ }
+#endif
+
+ for (i = 0; i < 5; i++)
+ {
+ c = IMY_GetNextChar(pEASData->hwInstData, pData, EAS_FALSE);
+ if (!c)
+ return EAS_FALSE;
+ switch (i)
+ {
+ case 3:
+ if (c == 'n')
+ {
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_GetLEDState: LED on\n"); */ }
+#endif
+ EAS_HWLED(pEASData->hwInstData, EAS_TRUE);
+ return EAS_TRUE;
+ }
+ else if (c != 'f')
+ return EAS_FALSE;
+ break;
+
+ case 4:
+ if (c == 'f')
+ {
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_GetLEDState: LED off\n"); */ }
+#endif
+ EAS_HWLED(pEASData->hwInstData, EAS_FALSE);
+ return EAS_TRUE;
+ }
+ return EAS_FALSE;
+
+ default:
+ if (c != ledStr[i])
+ return EAS_FALSE;
+ break;
+ }
+ }
+ return EAS_FALSE;
+}
+
+/*----------------------------------------------------------------------------
+ * IMY_GetVibeState()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ *
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_BOOL IMY_GetVibeState (S_EAS_DATA *pEASData, S_IMELODY_DATA *pData)
+{
+ EAS_I8 c;
+ EAS_INT i;
+
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Enter IMY_GetVibeState\n"); */ }
+#endif
+
+ for (i = 0; i < 6; i++)
+ {
+ c = IMY_GetNextChar(pEASData->hwInstData, pData, EAS_FALSE);
+ if (!c)
+ return EAS_FALSE;
+ switch (i)
+ {
+ case 4:
+ if (c == 'n')
+ {
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_GetVibeState: vibrate on\n"); */ }
+#endif
+ EAS_HWVibrate(pEASData->hwInstData, EAS_TRUE);
+ return EAS_TRUE;
+ }
+ else if (c != 'f')
+ return EAS_FALSE;
+ break;
+
+ case 5:
+ if (c == 'f')
+ {
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_GetVibeState: vibrate off\n"); */ }
+#endif
+ EAS_HWVibrate(pEASData->hwInstData, EAS_FALSE);
+ return EAS_TRUE;
+ }
+ return EAS_FALSE;
+
+ default:
+ if (c != vibeStr[i])
+ return EAS_FALSE;
+ break;
+ }
+ }
+ return EAS_FALSE;
+}
+
+/*----------------------------------------------------------------------------
+ * IMY_GetBackState()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ *
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_BOOL IMY_GetBackState (S_EAS_DATA *pEASData, S_IMELODY_DATA *pData)
+{
+ EAS_I8 c;
+ EAS_INT i;
+
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Enter IMY_GetBackState\n"); */ }
+#endif
+
+ for (i = 0; i < 5; i++)
+ {
+ c = IMY_GetNextChar(pEASData->hwInstData, pData, EAS_FALSE);
+ if (!c)
+ return EAS_FALSE;
+ switch (i)
+ {
+ case 3:
+ if (c == 'n')
+ {
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_GetBackState: backlight on\n"); */ }
+#endif
+ EAS_HWBackLight(pEASData->hwInstData, EAS_TRUE);
+ return EAS_TRUE;
+ }
+ else if (c != 'f')
+ return EAS_FALSE;
+ break;
+
+ case 4:
+ if (c == 'f')
+ {
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_GetBackState: backlight off\n"); */ }
+#endif
+ EAS_HWBackLight(pEASData->hwInstData, EAS_FALSE);
+ return EAS_TRUE;
+ }
+ return EAS_FALSE;
+
+ default:
+ if (c != backStr[i])
+ return EAS_FALSE;
+ break;
+ }
+ }
+ return EAS_FALSE;
+}
+
+/*----------------------------------------------------------------------------
+ * IMY_GetVolume()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ *
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_BOOL IMY_GetVolume (EAS_HW_DATA_HANDLE hwInstData, S_IMELODY_DATA *pData, EAS_BOOL inHeader)
+{
+ EAS_INT temp;
+ EAS_I8 c;
+
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Enter IMY_GetVolume\n"); */ }
+#endif
+
+ c = IMY_GetNextChar(hwInstData, pData, inHeader);
+ if (c == '+')
+ {
+ if (pData->volume < 15)
+ pData->volume++;
+ return EAS_TRUE;
+ }
+ else if (c == '-')
+ {
+ if (pData->volume > 0)
+ pData->volume--;
+ return EAS_TRUE;
+ }
+ else if (IsDigit(c))
+ temp = c - '0';
+ else
+ return EAS_FALSE;
+
+ c = IMY_GetNextChar(hwInstData, pData, inHeader);
+ if (IsDigit(c))
+ temp = temp * 10 + c - '0';
+ else if (c)
+ PutBackChar(pData);
+ if ((temp >= 0) && (temp <= 15))
+ {
+ if (inHeader && (temp == 0))
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Ignoring V0 encountered in header\n"); */ }
+ else
+ pData->volume = (EAS_U8) temp;
+ }
+ return EAS_TRUE;
+}
+
+/*----------------------------------------------------------------------------
+ * IMY_GetNumber()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ *
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_BOOL IMY_GetNumber (EAS_HW_DATA_HANDLE hwInstData, S_IMELODY_DATA *pData, EAS_INT *temp, EAS_BOOL inHeader)
+{
+ EAS_BOOL ok;
+ EAS_I8 c;
+
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Enter IMY_GetNumber\n"); */ }
+#endif
+
+ *temp = 0;
+ ok = EAS_FALSE;
+ for (;;)
+ {
+ c = IMY_GetNextChar(hwInstData, pData, inHeader);
+ if (IsDigit(c))
+ {
+ *temp = *temp * 10 + c - '0';
+ ok = EAS_TRUE;
+ }
+ else
+ {
+ if (c)
+ PutBackChar(pData);
+
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_GetNumber: value %d\n", *temp); */ }
+#endif
+
+ return ok;
+ }
+ }
+}
+
+/*----------------------------------------------------------------------------
+ * IMY_GetVersion()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ *
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_BOOL IMY_GetVersion (S_IMELODY_DATA *pData, EAS_INT *pVersion)
+{
+ EAS_I8 c;
+ EAS_INT temp;
+ EAS_INT version;
+
+ version = temp = 0;
+ for (;;)
+ {
+ c = pData->buffer[pData->index++];
+ if ((c == 0) || (c == '.'))
+ {
+ /*lint -e{701} use shift for performance */
+ version = (version << 8) + temp;
+ if (c == 0)
+ {
+
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_GetVersion: version 0x%04x\n", version); */ }
+#endif
+
+ *pVersion = version;
+ return EAS_TRUE;
+ }
+ temp = 0;
+ }
+ else if (IsDigit(c))
+ temp = (temp * 10) + c - '0';
+ }
+}
+
+/*----------------------------------------------------------------------------
+ * IMY_MetaData()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Prepare to parse the file. Allocates instance data (or uses static allocation for
+ * static memory model).
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static void IMY_MetaData (S_IMELODY_DATA *pData, E_EAS_METADATA_TYPE metaType, EAS_I8 *buffer)
+{
+ EAS_I32 len;
+
+ /* check for callback */
+ if (!pData->metadata.callback)
+ return;
+
+ /* copy data to host buffer */
+ len = (EAS_I32) strlen((char*) buffer);
+ if (len >pData->metadata.bufferSize)
+ len = pData->metadata.bufferSize;
+ strncpy((char*) pData->metadata.buffer, (char*) buffer, (size_t) len);
+ pData->metadata.buffer[len] = 0;
+
+ /* callback to host */
+ pData->metadata.callback(metaType, pData->metadata.buffer, pData->metadata.pUserData);
+}
+
+/*----------------------------------------------------------------------------
+ * IMY_ParseHeader()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Prepare to parse the file. Allocates instance data (or uses static allocation for
+ * static memory model).
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT IMY_ParseHeader (S_EAS_DATA *pEASData, S_IMELODY_DATA* pData)
+{
+ EAS_RESULT result;
+ EAS_INT token;
+ EAS_INT temp;
+ EAS_I8 c;
+
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Enter IMY_ParseHeader\n"); */ }
+#endif
+
+ /* initialize some defaults */
+ pData->time = 0;
+ pData->tick = DEFAULT_TICK_CONV;
+ pData->note = 0;
+ pData->noteModifier = 0;
+ pData ->restTicks = 0;
+ pData->volume = 7;
+ pData->octave = 60;
+ pData->repeatOffset = -1;
+ pData->repeatCount = -1;
+ pData->style = 0;
+
+ /* force the read of the first line */
+ pData->index = 1;
+
+ /* read data until we get to melody */
+ for (;;)
+ {
+ /* read a line from the file and parse the token */
+ if (pData->index != 0)
+ {
+ if ((result = IMY_ReadLine(pEASData->hwInstData, pData->fileHandle, pData->buffer, &pData->startLine)) != EAS_SUCCESS)
+ {
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_ParseHeader: IMY_ReadLine returned %d\n", result); */ }
+#endif
+ return result;
+ }
+ }
+ token = IMY_ParseLine(pData->buffer, &pData->index);
+
+ switch (token)
+ {
+ /* ignore these valid tokens */
+ case TOKEN_BEGIN:
+ break;
+
+ case TOKEN_FORMAT:
+ if (!IMY_GetVersion(pData, &temp))
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Invalid FORMAT field '%s'\n", pData->buffer); */ }
+ return EAS_ERROR_FILE_FORMAT;
+ }
+ if ((temp != 0x0100) && (temp != 0x0200))
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Unsupported FORMAT %02x\n", temp); */ }
+ return EAS_ERROR_UNRECOGNIZED_FORMAT;
+ }
+ break;
+
+ case TOKEN_VERSION:
+ if (!IMY_GetVersion(pData, &temp))
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Invalid VERSION field '%s'\n", pData->buffer); */ }
+ return EAS_ERROR_FILE_FORMAT;
+ }
+ if ((temp != 0x0100) && (temp != 0x0102))
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Unsupported VERSION %02x\n", temp); */ }
+ return EAS_ERROR_UNRECOGNIZED_FORMAT;
+ }
+ break;
+
+ case TOKEN_NAME:
+ IMY_MetaData(pData, EAS_METADATA_TITLE, pData->buffer + pData->index);
+ break;
+
+ case TOKEN_COMPOSER:
+ IMY_MetaData(pData, EAS_METADATA_AUTHOR, pData->buffer + pData->index);
+ break;
+
+ /* handle beat */
+ case TOKEN_BEAT:
+ IMY_GetNumber(pEASData->hwInstData, pData, &temp, EAS_TRUE);
+ if ((temp >= 25) && (temp <= 900))
+ pData->tick = TICK_CONVERT / temp;
+ break;
+
+ /* handle style */
+ case TOKEN_STYLE:
+ c = IMY_GetNextChar(pEASData->hwInstData, pData, EAS_TRUE);
+ if (c == 'S')
+ c = IMY_GetNextChar(pEASData->hwInstData, pData, EAS_TRUE);
+ if ((c >= '0') && (c <= '2'))
+ pData->style = (EAS_U8) (c - '0');
+ else
+ {
+ PutBackChar(pData);
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Error in style command: %s\n", pData->buffer); */ }
+ }
+ break;
+
+ /* handle volume */
+ case TOKEN_VOLUME:
+ c = IMY_GetNextChar(pEASData->hwInstData, pData, EAS_TRUE);
+ if (c != 'V')
+ {
+ PutBackChar(pData);
+ if (!IsDigit(c))
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Error in volume command: %s\n", pData->buffer); */ }
+ break;
+ }
+ }
+ IMY_GetVolume(pEASData->hwInstData, pData, EAS_TRUE);
+ break;
+
+ case TOKEN_MELODY:
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Header successfully parsed\n"); */ }
+#endif
+ return EAS_SUCCESS;
+
+ case TOKEN_END:
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Unexpected END:IMELODY encountered\n"); */ }
+ return EAS_ERROR_FILE_FORMAT;
+
+ default:
+ /* force a read of the next line */
+ pData->index = 1;
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Ignoring unrecognized token in iMelody file: %s\n", pData->buffer); */ }
+ break;
+ }
+ }
+}
+
+/*----------------------------------------------------------------------------
+ * IMY_GetNextChar()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ *
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_I8 IMY_GetNextChar (EAS_HW_DATA_HANDLE hwInstData, S_IMELODY_DATA *pData, EAS_BOOL inHeader)
+{
+ EAS_I8 c;
+ EAS_U8 index;
+
+ for (;;)
+ {
+ /* get next character */
+ c = pData->buffer[pData->index++];
+
+ /* buffer empty, read more */
+ if (!c)
+ {
+ /* don't read the next line in the header */
+ if (inHeader)
+ return 0;
+
+ pData->index = 0;
+ pData->buffer[0] = 0;
+ if (IMY_ReadLine(hwInstData, pData->fileHandle, pData->buffer, &pData->startLine) != EAS_SUCCESS)
+ {
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_GetNextChar: EOF\n"); */ }
+#endif
+ return 0;
+ }
+
+ /* check for END:IMELODY token */
+ if (IMY_ParseLine(pData->buffer, &index) == TOKEN_END)
+ {
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_GetNextChar: found END:IMELODY\n"); */ }
+#endif
+ pData->buffer[0] = 0;
+ return 0;
+ }
+ continue;
+ }
+
+ /* ignore white space */
+ if (!IsSpace(c))
+ {
+
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_GetNextChar returned '%c'\n", c); */ }
+#endif
+ return c;
+ }
+ }
+}
+
+/*----------------------------------------------------------------------------
+ * IMY_ReadLine()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Reads a line of input from the file, discarding the CR/LF
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT IMY_ReadLine (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE fileHandle, EAS_I8 *buffer, EAS_I32 *pStartLine)
+{
+ EAS_RESULT result;
+ EAS_INT i;
+ EAS_I8 c;
+
+ /* fetch current file position and save it */
+ if (pStartLine != NULL)
+ {
+ if ((result = EAS_HWFilePos(hwInstData, fileHandle, pStartLine)) != EAS_SUCCESS)
+ {
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_ParseHeader: EAS_HWFilePos returned %d\n", result); */ }
+#endif
+ return result;
+ }
+ }
+
+ buffer[0] = 0;
+ for (i = 0; i < MAX_LINE_SIZE; )
+ {
+ if ((result = EAS_HWGetByte(hwInstData, fileHandle, &c)) != EAS_SUCCESS)
+ {
+ if ((result == EAS_EOF) && (i > 0))
+ break;
+ return result;
+ }
+
+ /* return on LF or end of data */
+ if (c == '\n')
+ break;
+
+ /* store characters in buffer */
+ if (c != '\r')
+ buffer[i++] = c;
+ }
+ buffer[i] = 0;
+
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_ReadLine read %s\n", buffer); */ }
+#endif
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * IMY_ParseLine()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ *
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_INT IMY_ParseLine (EAS_I8 *buffer, EAS_U8 *pIndex)
+{
+ EAS_INT i;
+ EAS_INT j;
+
+ /* there's no strnicmp() in stdlib, so we have to roll our own */
+ for (i = 0; i < TOKEN_INVALID; i++)
+ {
+ for (j = 0; ; j++)
+ {
+ /* end of token, must be a match */
+ if (tokens[i][j] == 0)
+ {
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_ParseLine found token %d\n", i); */ }
+#endif
+ *pIndex = (EAS_U8) j;
+ return i;
+ }
+ if (tokens[i][j] != ToUpper(buffer[j]))
+ break;
+ }
+ }
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_ParseLine: no token found\n"); */ }
+#endif
+ return TOKEN_INVALID;
+}
+
diff --git a/arm-hybrid-22k/lib_src/eas_imelodydata.c b/arm-hybrid-22k/lib_src/eas_imelodydata.c
index e72dc0b..9437e08 100644
--- a/arm-hybrid-22k/lib_src/eas_imelodydata.c
+++ b/arm-hybrid-22k/lib_src/eas_imelodydata.c
@@ -1,14 +1,14 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_imelodydata.c
- *
- * Contents and purpose:
- * SMF File Parser
- *
- * This file contains data definitions for the SMF parser.
- *
- * Copyright Sonic Network Inc. 2005
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_imelodydata.c
+ *
+ * Contents and purpose:
+ * SMF File Parser
+ *
+ * This file contains data definitions for the SMF parser.
+ *
+ * Copyright Sonic Network Inc. 2005
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,23 +21,23 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 547 $
- * $Date: 2007-01-31 16:30:17 -0800 (Wed, 31 Jan 2007) $
- *----------------------------------------------------------------------------
-*/
-
-#include "eas_types.h"
-#include "eas_imelodydata.h"
-
-/*----------------------------------------------------------------------------
- *
- * eas_iMelodyData
- *
- * Static memory allocation for iMelody parser
- *----------------------------------------------------------------------------
-*/
-S_IMELODY_DATA eas_iMelodyData;
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 547 $
+ * $Date: 2007-01-31 16:30:17 -0800 (Wed, 31 Jan 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+#include "eas_types.h"
+#include "eas_imelodydata.h"
+
+/*----------------------------------------------------------------------------
+ *
+ * eas_iMelodyData
+ *
+ * Static memory allocation for iMelody parser
+ *----------------------------------------------------------------------------
+*/
+S_IMELODY_DATA eas_iMelodyData;
+
diff --git a/arm-hybrid-22k/lib_src/eas_imelodydata.h b/arm-hybrid-22k/lib_src/eas_imelodydata.h
index 303b8f6..57c1ed0 100644
--- a/arm-hybrid-22k/lib_src/eas_imelodydata.h
+++ b/arm-hybrid-22k/lib_src/eas_imelodydata.h
@@ -1,14 +1,14 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_imelodydata.h
- *
- * Contents and purpose:
- * SMF File Parser
- *
- * This file contains data declarations for the iMelody parser.
- *
- * Copyright Sonic Network Inc. 2005
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_imelodydata.h
+ *
+ * Contents and purpose:
+ * SMF File Parser
+ *
+ * This file contains data declarations for the iMelody parser.
+ *
+ * Copyright Sonic Network Inc. 2005
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,53 +21,53 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 778 $
- * $Date: 2007-07-23 16:45:17 -0700 (Mon, 23 Jul 2007) $
- *----------------------------------------------------------------------------
-*/
-
-#ifndef EAS_IMELODYDATA_H
-#define EAS_IMELODYDATA_H
-
-#include "eas_data.h"
-
-/* maximum line size as specified in iMelody V1.2 spec */
-#define MAX_LINE_SIZE 75
-
-/*----------------------------------------------------------------------------
- *
- * S_IMELODY_DATA
- *
- * This structure contains the state data for the iMelody parser
- *----------------------------------------------------------------------------
-*/
-
-typedef struct
-{
- EAS_FILE_HANDLE fileHandle; /* file handle */
- S_SYNTH *pSynth; /* pointer to synth */
- EAS_I32 fileOffset; /* offset to start of data */
- EAS_I32 time; /* current time in 256ths of a msec */
- EAS_I32 tickBase; /* basline length of 32nd note in 256th of a msec */
- EAS_I32 tick; /* actual length of 32nd note in 256th of a msec */
- EAS_I32 restTicks; /* ticks to rest after current note */
- EAS_I32 startLine; /* file offset at start of line (for repeats) */
- EAS_I32 repeatOffset; /* file offset to start of repeat section */
- S_METADATA_CB metadata; /* metadata callback */
- EAS_I16 repeatCount; /* repeat counter */
- EAS_U8 state; /* current state EAS_STATE_XXXX */
- EAS_U8 style; /* from STYLE */
- EAS_U8 index; /* index into buffer */
- EAS_U8 octave; /* octave prefix */
- EAS_U8 volume; /* current volume */
- EAS_U8 note; /* MIDI note number */
- EAS_I8 noteModifier; /* sharp or flat */
- EAS_I8 buffer[MAX_LINE_SIZE+1]; /* buffer for ASCII data */
-} S_IMELODY_DATA;
-
-#endif
-
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 778 $
+ * $Date: 2007-07-23 16:45:17 -0700 (Mon, 23 Jul 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+#ifndef EAS_IMELODYDATA_H
+#define EAS_IMELODYDATA_H
+
+#include "eas_data.h"
+
+/* maximum line size as specified in iMelody V1.2 spec */
+#define MAX_LINE_SIZE 75
+
+/*----------------------------------------------------------------------------
+ *
+ * S_IMELODY_DATA
+ *
+ * This structure contains the state data for the iMelody parser
+ *----------------------------------------------------------------------------
+*/
+
+typedef struct
+{
+ EAS_FILE_HANDLE fileHandle; /* file handle */
+ S_SYNTH *pSynth; /* pointer to synth */
+ EAS_I32 fileOffset; /* offset to start of data */
+ EAS_I32 time; /* current time in 256ths of a msec */
+ EAS_I32 tickBase; /* basline length of 32nd note in 256th of a msec */
+ EAS_I32 tick; /* actual length of 32nd note in 256th of a msec */
+ EAS_I32 restTicks; /* ticks to rest after current note */
+ EAS_I32 startLine; /* file offset at start of line (for repeats) */
+ EAS_I32 repeatOffset; /* file offset to start of repeat section */
+ S_METADATA_CB metadata; /* metadata callback */
+ EAS_I16 repeatCount; /* repeat counter */
+ EAS_U8 state; /* current state EAS_STATE_XXXX */
+ EAS_U8 style; /* from STYLE */
+ EAS_U8 index; /* index into buffer */
+ EAS_U8 octave; /* octave prefix */
+ EAS_U8 volume; /* current volume */
+ EAS_U8 note; /* MIDI note number */
+ EAS_I8 noteModifier; /* sharp or flat */
+ EAS_I8 buffer[MAX_LINE_SIZE+1]; /* buffer for ASCII data */
+} S_IMELODY_DATA;
+
+#endif
+
+
diff --git a/arm-hybrid-22k/lib_src/eas_math.c b/arm-hybrid-22k/lib_src/eas_math.c
index 12d788e..dc85051 100644
--- a/arm-hybrid-22k/lib_src/eas_math.c
+++ b/arm-hybrid-22k/lib_src/eas_math.c
@@ -1,13 +1,13 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_math.c
- *
- * Contents and purpose:
- * Contains common math routines for the various audio engines.
- *
- *
- * Copyright Sonic Network Inc. 2005
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_math.c
+ *
+ * Contents and purpose:
+ * Contains common math routines for the various audio engines.
+ *
+ *
+ * Copyright Sonic Network Inc. 2005
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,149 +20,149 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 586 $
- * $Date: 2007-03-08 20:33:04 -0800 (Thu, 08 Mar 2007) $
- *----------------------------------------------------------------------------
-*/
-
-#include "eas.h"
-#include "eas_math.h"
-
-/* anything less than this converts to a fraction too small to represent in 32-bits */
-#define MIN_CENTS -18000
-
-/*----------------------------------------------------------------------------
- * EAS_Calculate2toX()
- *----------------------------------------------------------------------------
- * Purpose:
- * Calculate 2^x
- *
- * Inputs:
- * nCents - measured in cents
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- * nResult - int.frac result (where frac has NUM_DENTS_FRAC_BITS)
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_I32 EAS_Calculate2toX (EAS_I32 nCents)
-{
- EAS_I32 nDents;
- EAS_I32 nExponentInt, nExponentFrac;
- EAS_I32 nTemp1, nTemp2;
- EAS_I32 nResult;
-
- /* check for minimum value */
- if (nCents < MIN_CENTS)
- return 0;
-
- /* for the time being, convert cents to dents */
- nDents = FMUL_15x15(nCents, CENTS_TO_DENTS);
-
- nExponentInt = GET_DENTS_INT_PART(nDents);
- nExponentFrac = GET_DENTS_FRAC_PART(nDents);
-
- /*
- implement 2^(fracPart) as a power series
- */
- nTemp1 = GN2_TO_X2 + MULT_DENTS_COEF(nExponentFrac, GN2_TO_X3);
- nTemp2 = GN2_TO_X1 + MULT_DENTS_COEF(nExponentFrac, nTemp1);
- nTemp1 = GN2_TO_X0 + MULT_DENTS_COEF(nExponentFrac, nTemp2);
-
- /*
- implement 2^(intPart) as
- a left shift for intPart >= 0 or
- a left shift for intPart < 0
- */
- if (nExponentInt >= 0)
- {
- /* left shift for positive exponents */
- /*lint -e{703} <avoid multiply for performance>*/
- nResult = nTemp1 << nExponentInt;
- }
- else
- {
- /* right shift for negative exponents */
- nExponentInt = -nExponentInt;
- nResult = nTemp1 >> nExponentInt;
- }
-
- return nResult;
-}
-
-/*----------------------------------------------------------------------------
- * EAS_LogToLinear16()
- *----------------------------------------------------------------------------
- * Purpose:
- * Transform log value to linear gain multiplier using piece-wise linear
- * approximation
- *
- * Inputs:
- * nGain - log scale value in 20.10 format. Even though gain is normally
- * stored in 6.10 (16-bit) format we use 32-bit numbers here to eliminate
- * the need for saturation checking when combining gain values.
- *
- * Outputs:
- * Returns a 16-bit linear value approximately equal to 2^(nGain/1024)
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_U16 EAS_LogToLinear16 (EAS_I32 nGain)
-{
- EAS_INT nExp;
- EAS_U16 nTemp;
-
- /* bias to positive */
- nGain += 32767;
-
- /* check for infinite attenuation */
- if (nGain < 0)
- return 0;
-
- /* extract the exponent */
- nExp = 31 - (nGain >> 10);
-
- /* check for maximum output */
- if (nExp < 0)
- return 0x7fff;
-
- /* extract mantissa and restore implied 1 bit */
- nTemp = (EAS_U16)((((nGain & 0x3ff) << 4) | 0x4000) >> nExp);
-
- /* use shift to approximate power-of-2 operation */
- return nTemp;
-}
-
-/*----------------------------------------------------------------------------
- * EAS_VolumeToGain()
- *----------------------------------------------------------------------------
- * Purpose:
- * Transform volume control in 1dB increments to gain multiplier
- *
- * Inputs:
- * volume - 100 = 0dB, 99 = -1dB, 0 = -inf
- *
- * Outputs:
- * Returns a 16-bit linear value
- *----------------------------------------------------------------------------
-*/
-EAS_I16 EAS_VolumeToGain (EAS_INT volume)
-{
- /* check for limits */
- if (volume <= 0)
- return 0;
- if (volume >= 100)
- return 0x7fff;
-
- /*lint -e{702} use shift instead of division */
- return (EAS_I16) EAS_Calculate2toX((((volume - EAS_MAX_VOLUME) * 204099) >> 10) - 1);
-}
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 586 $
+ * $Date: 2007-03-08 20:33:04 -0800 (Thu, 08 Mar 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+#include "eas.h"
+#include "eas_math.h"
+
+/* anything less than this converts to a fraction too small to represent in 32-bits */
+#define MIN_CENTS -18000
+
+/*----------------------------------------------------------------------------
+ * EAS_Calculate2toX()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Calculate 2^x
+ *
+ * Inputs:
+ * nCents - measured in cents
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ * nResult - int.frac result (where frac has NUM_DENTS_FRAC_BITS)
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_I32 EAS_Calculate2toX (EAS_I32 nCents)
+{
+ EAS_I32 nDents;
+ EAS_I32 nExponentInt, nExponentFrac;
+ EAS_I32 nTemp1, nTemp2;
+ EAS_I32 nResult;
+
+ /* check for minimum value */
+ if (nCents < MIN_CENTS)
+ return 0;
+
+ /* for the time being, convert cents to dents */
+ nDents = FMUL_15x15(nCents, CENTS_TO_DENTS);
+
+ nExponentInt = GET_DENTS_INT_PART(nDents);
+ nExponentFrac = GET_DENTS_FRAC_PART(nDents);
+
+ /*
+ implement 2^(fracPart) as a power series
+ */
+ nTemp1 = GN2_TO_X2 + MULT_DENTS_COEF(nExponentFrac, GN2_TO_X3);
+ nTemp2 = GN2_TO_X1 + MULT_DENTS_COEF(nExponentFrac, nTemp1);
+ nTemp1 = GN2_TO_X0 + MULT_DENTS_COEF(nExponentFrac, nTemp2);
+
+ /*
+ implement 2^(intPart) as
+ a left shift for intPart >= 0 or
+ a left shift for intPart < 0
+ */
+ if (nExponentInt >= 0)
+ {
+ /* left shift for positive exponents */
+ /*lint -e{703} <avoid multiply for performance>*/
+ nResult = nTemp1 << nExponentInt;
+ }
+ else
+ {
+ /* right shift for negative exponents */
+ nExponentInt = -nExponentInt;
+ nResult = nTemp1 >> nExponentInt;
+ }
+
+ return nResult;
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_LogToLinear16()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Transform log value to linear gain multiplier using piece-wise linear
+ * approximation
+ *
+ * Inputs:
+ * nGain - log scale value in 20.10 format. Even though gain is normally
+ * stored in 6.10 (16-bit) format we use 32-bit numbers here to eliminate
+ * the need for saturation checking when combining gain values.
+ *
+ * Outputs:
+ * Returns a 16-bit linear value approximately equal to 2^(nGain/1024)
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_U16 EAS_LogToLinear16 (EAS_I32 nGain)
+{
+ EAS_INT nExp;
+ EAS_U16 nTemp;
+
+ /* bias to positive */
+ nGain += 32767;
+
+ /* check for infinite attenuation */
+ if (nGain < 0)
+ return 0;
+
+ /* extract the exponent */
+ nExp = 31 - (nGain >> 10);
+
+ /* check for maximum output */
+ if (nExp < 0)
+ return 0x7fff;
+
+ /* extract mantissa and restore implied 1 bit */
+ nTemp = (EAS_U16)((((nGain & 0x3ff) << 4) | 0x4000) >> nExp);
+
+ /* use shift to approximate power-of-2 operation */
+ return nTemp;
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_VolumeToGain()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Transform volume control in 1dB increments to gain multiplier
+ *
+ * Inputs:
+ * volume - 100 = 0dB, 99 = -1dB, 0 = -inf
+ *
+ * Outputs:
+ * Returns a 16-bit linear value
+ *----------------------------------------------------------------------------
+*/
+EAS_I16 EAS_VolumeToGain (EAS_INT volume)
+{
+ /* check for limits */
+ if (volume <= 0)
+ return 0;
+ if (volume >= 100)
+ return 0x7fff;
+
+ /*lint -e{702} use shift instead of division */
+ return (EAS_I16) EAS_Calculate2toX((((volume - EAS_MAX_VOLUME) * 204099) >> 10) - 1);
+}
+
diff --git a/arm-hybrid-22k/lib_src/eas_math.h b/arm-hybrid-22k/lib_src/eas_math.h
index 719270b..f240b51 100644
--- a/arm-hybrid-22k/lib_src/eas_math.h
+++ b/arm-hybrid-22k/lib_src/eas_math.h
@@ -1,13 +1,13 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_math.h
- *
- * Contents and purpose:
- * Contains common math routines for the various audio engines.
- *
- *
- * Copyright Sonic Network Inc. 2005
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_math.h
+ *
+ * Contents and purpose:
+ * Contains common math routines for the various audio engines.
+ *
+ *
+ * Copyright Sonic Network Inc. 2005
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,393 +20,393 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 584 $
- * $Date: 2007-03-08 09:49:24 -0800 (Thu, 08 Mar 2007) $
- *----------------------------------------------------------------------------
-*/
-
-#ifndef _EAS_MATH_H
-#define _EAS_MATH_H
-
-
-/** coefs for pan, generates sin, cos */
-#define COEFF_PAN_G2 -27146 /* -0.82842712474619 = 2 - 4/sqrt(2) */
-#define COEFF_PAN_G0 23170 /* 0.707106781186547 = 1/sqrt(2) */
-
-/*
-coefficients for approximating
-2^x = gn2toX0 + gn2toX1*x + gn2toX2*x^2 + gn2toX3*x^3
-where x is a int.frac number representing number of octaves.
-Actually, we approximate only the 2^(frac) using the power series
-and implement the 2^(int) as a shift, so that
-2^x == 2^(int.frac) == 2^(int) * 2^(fract)
- == (gn2toX0 + gn2toX1*x + gn2toX2*x^2 + gn2toX3*x^3) << (int)
-
-The gn2toX.. were generated using a best fit for a 3rd
-order polynomial, instead of taking the coefficients from
-a truncated Taylor (or Maclaurin?) series.
-*/
-
-#define GN2_TO_X0 32768 /* 1 */
-#define GN2_TO_X1 22833 /* 0.696807861328125 */
-#define GN2_TO_X2 7344 /* 0.22412109375 */
-#define GN2_TO_X3 2588 /* 0.0789794921875 */
-
-/*----------------------------------------------------------------------------
- * Fixed Point Math
- *----------------------------------------------------------------------------
- * These macros are used for fixed point multiplies. If the processor
- * supports fixed point multiplies, replace these macros with inline
- * assembly code to improve performance.
- *----------------------------------------------------------------------------
-*/
-
-/* Fixed point multiply 0.15 x 0.15 = 0.15 returned as 32-bits */
-#define FMUL_15x15(a,b) \
- /*lint -e(704) <avoid multiply for performance>*/ \
- (((EAS_I32)(a) * (EAS_I32)(b)) >> 15)
-
-/* Fixed point multiply 0.7 x 0.7 = 0.15 returned as 32-bits */
-#define FMUL_7x7(a,b) \
- /*lint -e(704) <avoid multiply for performance>*/ \
- (((EAS_I32)(a) * (EAS_I32)(b) ) << 1)
-
-/* Fixed point multiply 0.8 x 0.8 = 0.15 returned as 32-bits */
-#define FMUL_8x8(a,b) \
- /*lint -e(704) <avoid multiply for performance>*/ \
- (((EAS_I32)(a) * (EAS_I32)(b) ) >> 1)
-
-/* Fixed point multiply 0.8 x 1.15 = 0.15 returned as 32-bits */
-#define FMUL_8x15(a,b) \
- /*lint -e(704) <avoid divide for performance>*/ \
- (((EAS_I32)((a) << 7) * (EAS_I32)(b)) >> 15)
-
-/* macros for fractional phase accumulator */
-/*
-Note: changed the _U32 to _I32 on 03/14/02. This should not
-affect the phase calculations, and should allow us to reuse these
-macros for other audio sample related math.
-*/
-#define HARDWARE_BIT_WIDTH 32
-
-#define NUM_PHASE_INT_BITS 1
-#define NUM_PHASE_FRAC_BITS 15
-
-#define PHASE_FRAC_MASK (EAS_U32) ((0x1L << NUM_PHASE_FRAC_BITS) -1)
-
-#define GET_PHASE_INT_PART(x) (EAS_U32)((EAS_U32)(x) >> NUM_PHASE_FRAC_BITS)
-#define GET_PHASE_FRAC_PART(x) (EAS_U32)((EAS_U32)(x) & PHASE_FRAC_MASK)
-
-#define DEFAULT_PHASE_FRAC 0
-#define DEFAULT_PHASE_INT 0
-
-/*
-Linear interpolation calculates:
-output = (1-frac) * sample[n] + (frac) * sample[n+1]
-
-where conceptually 0 <= frac < 1
-
-For a fixed point implementation, frac is actually an integer value
-with an implied binary point one position to the left. The value of
-one (unity) is given by PHASE_ONE
-one half and one quarter are useful for 4-point linear interp.
-*/
-#define PHASE_ONE (EAS_I32) (0x1L << NUM_PHASE_FRAC_BITS)
-
-/*
- Multiply the signed audio sample by the unsigned fraction.
-- a is the signed audio sample
-- b is the unsigned fraction (cast to signed int as long as coef
- uses (n-1) or less bits, where n == hardware bit width)
-*/
-#define MULT_AUDIO_COEF(audio,coef) /*lint -e704 <avoid divide for performance>*/ \
- (EAS_I32)( \
- ( \
- ((EAS_I32)(audio)) * ((EAS_I32)(coef)) \
- ) \
- >> NUM_PHASE_FRAC_BITS \
- ) \
- /* lint +704 <restore checking>*/
-
-/* wet / dry calculation macros */
-#define NUM_WET_DRY_FRAC_BITS 7 // 15
-#define NUM_WET_DRY_INT_BITS 9 // 1
-
-/* define a 1.0 */
-#define WET_DRY_ONE (EAS_I32) ((0x1L << NUM_WET_DRY_FRAC_BITS))
-#define WET_DRY_MINUS_ONE (EAS_I32) (~WET_DRY_ONE)
-#define WET_DRY_FULL_SCALE (EAS_I32) (WET_DRY_ONE - 1)
-
-#define MULT_AUDIO_WET_DRY_COEF(audio,coef) /*lint -e(702) <avoid divide for performance>*/ \
- (EAS_I32)( \
- ( \
- ((EAS_I32)(audio)) * ((EAS_I32)(coef)) \
- ) \
- >> NUM_WET_DRY_FRAC_BITS \
- )
-
-/* Envelope 1 (EG1) calculation macros */
-#define NUM_EG1_INT_BITS 1
-#define NUM_EG1_FRAC_BITS 15
-
-/* the max positive gain used in the synth for EG1 */
-/* SYNTH_FULL_SCALE_EG1_GAIN must match the value in the dls2eas
-converter, otherwise, the values we read from the .eas file are bogus. */
-#define SYNTH_FULL_SCALE_EG1_GAIN (EAS_I32) ((0x1L << NUM_EG1_FRAC_BITS) -1)
-
-/* define a 1.0 */
-#define EG1_ONE (EAS_I32) ((0x1L << NUM_EG1_FRAC_BITS))
-#define EG1_MINUS_ONE (EAS_I32) (~SYNTH_FULL_SCALE_EG1_GAIN)
-
-#define EG1_HALF (EAS_I32) (EG1_ONE/2)
-#define EG1_MINUS_HALF (EAS_I32) (EG1_MINUS_ONE/2)
-
-/*
-We implement the EG1 using a linear gain value, which means that the
-attack segment is handled by incrementing (adding) the linear gain.
-However, EG1 treats the Decay, Sustain, and Release differently than
-the Attack portion. For Decay, Sustain, and Release, the gain is
-linear on dB scale, which is equivalent to exponential damping on
-a linear scale. Because we use a linear gain for EG1, we implement
-the Decay and Release as multiplication (instead of incrementing
-as we did for the attack segment).
-Therefore, we need the following macro to implement the multiplication
-(i.e., exponential damping) during the Decay and Release segments of
-the EG1
-*/
-#define MULT_EG1_EG1(gain,damping) /*lint -e(704) <avoid divide for performance>*/ \
- (EAS_I32)( \
- ( \
- ((EAS_I32)(gain)) * ((EAS_I32)(damping)) \
- ) \
- >> NUM_EG1_FRAC_BITS \
- )
-
-// Use the following macro specifically for the filter, when multiplying
-// the b1 coefficient. The 0 <= |b1| < 2, which therefore might overflow
-// in certain conditions because we store b1 as a 1.15 value.
-// Instead, we could store b1 as b1p (b1' == b1 "prime") where
-// b1p == b1/2, thus ensuring no potential overflow for b1p because
-// 0 <= |b1p| < 1
-// However, during the filter calculation, we must account for the fact
-// that we are using b1p instead of b1, and thereby multiply by
-// an extra factor of 2. Rather than multiply by an extra factor of 2,
-// we can instead shift the result right by one less, hence the
-// modified shift right value of (NUM_EG1_FRAC_BITS -1)
-#define MULT_EG1_EG1_X2(gain,damping) /*lint -e(702) <avoid divide for performance>*/ \
- (EAS_I32)( \
- ( \
- ((EAS_I32)(gain)) * ((EAS_I32)(damping)) \
- ) \
- >> (NUM_EG1_FRAC_BITS -1) \
- )
-
-#define SATURATE_EG1(x) /*lint -e{734} saturation operation */ \
- ((EAS_I32)(x) > SYNTH_FULL_SCALE_EG1_GAIN) ? (SYNTH_FULL_SCALE_EG1_GAIN) : \
- ((EAS_I32)(x) < EG1_MINUS_ONE) ? (EG1_MINUS_ONE) : (x);
-
-
-/* use "digital cents" == "dents" instead of cents */
-/* we coudl re-use the phase frac macros, but if we do,
-we must change the phase macros to cast to _I32 instead of _U32,
-because using a _U32 cast causes problems when shifting the exponent
-for the 2^x calculation, because right shift a negative values MUST
-be sign extended, or else the 2^x calculation is wrong */
-
-/* use "digital cents" == "dents" instead of cents */
-#define NUM_DENTS_FRAC_BITS 12
-#define NUM_DENTS_INT_BITS (HARDWARE_BIT_WIDTH - NUM_DENTS_FRAC_BITS)
-
-#define DENTS_FRAC_MASK (EAS_I32) ((0x1L << NUM_DENTS_FRAC_BITS) -1)
-
-#define GET_DENTS_INT_PART(x) /*lint -e(704) <avoid divide for performance>*/ \
- (EAS_I32)((EAS_I32)(x) >> NUM_DENTS_FRAC_BITS)
-
-#define GET_DENTS_FRAC_PART(x) (EAS_I32)((EAS_I32)(x) & DENTS_FRAC_MASK)
-
-#define DENTS_ONE (EAS_I32) (0x1L << NUM_DENTS_FRAC_BITS)
-
-/* use CENTS_TO_DENTS to convert a value in cents to dents */
-#define CENTS_TO_DENTS (EAS_I32) (DENTS_ONE * (0x1L << NUM_EG1_FRAC_BITS) / 1200L) \
-
-
-/*
-For gain, the LFO generates a value that modulates in terms
-of dB. However, we use a linear gain value, so we must convert
-the LFO value in dB to a linear gain. Normally, we would use
-linear gain = 10^x, where x = LFO value in dB / 20.
-Instead, we implement 10^x using our 2^x approximation.
-because
-
- 10^x = 2^(log2(10^x)) = 2^(x * log2(10))
-
-so we need to multiply by log2(10) which is just a constant.
-Ah, but just wait -- our 2^x actually doesn't exactly implement
-2^x, but it actually assumes that the input is in cents, and within
-the 2^x approximation converts its input from cents to octaves
-by dividing its input by 1200.
-
-So, in order to convert the LFO gain value in dB to something
-that our existing 2^x approximation can use, multiply the LFO gain
-by log2(10) * 1200 / 20
-
-The divide by 20 helps convert dB to linear gain, and we might
-as well incorporate that operation into this conversion.
-Of course, we need to keep some fractional bits, so multiply
-the constant by NUM_EG1_FRAC_BITS
-*/
-
-/* use LFO_GAIN_TO_CENTS to convert the LFO gain value to cents */
-#if 0
-#define DOUBLE_LOG2_10 (double) (3.32192809488736) /* log2(10) */
-
-#define DOUBLE_LFO_GAIN_TO_CENTS (double) \
- ( \
- (DOUBLE_LOG2_10) * \
- 1200.0 / \
- 20.0 \
- )
-
-#define LFO_GAIN_TO_CENTS (EAS_I32) \
- ( \
- DOUBLE_LFO_GAIN_TO_CENTS * \
- (0x1L << NUM_EG1_FRAC_BITS) \
- )
-#endif
-
-#define LFO_GAIN_TO_CENTS (EAS_I32) (1671981156L >> (23 - NUM_EG1_FRAC_BITS))
-
-
-#define MULT_DENTS_COEF(dents,coef) /*lint -e704 <avoid divide for performance>*/ \
- (EAS_I32)( \
- ( \
- ((EAS_I32)(dents)) * ((EAS_I32)(coef)) \
- ) \
- >> NUM_DENTS_FRAC_BITS \
- ) \
- /* lint +e704 <restore checking>*/
-
-/* we use 16-bits in the PC per audio sample */
-#define BITS_PER_AUDIO_SAMPLE 16
-
-/* we define 1 as 1.0 - 1 LSbit */
-#define DISTORTION_ONE (EAS_I32)((0x1L << (BITS_PER_AUDIO_SAMPLE-1)) -1)
-#define DISTORTION_MINUS_ONE (EAS_I32)(~DISTORTION_ONE)
-
-/* drive coef is given as int.frac */
-#define NUM_DRIVE_COEF_INT_BITS 1
-#define NUM_DRIVE_COEF_FRAC_BITS 4
-
-#define MULT_AUDIO_DRIVE(audio,drive) /*lint -e(702) <avoid divide for performance>*/ \
- (EAS_I32) ( \
- ( \
- ((EAS_I32)(audio)) * ((EAS_I32)(drive)) \
- ) \
- >> NUM_DRIVE_COEF_FRAC_BITS \
- )
-
-#define MULT_AUDIO_AUDIO(audio1,audio2) /*lint -e(702) <avoid divide for performance>*/ \
- (EAS_I32) ( \
- ( \
- ((EAS_I32)(audio1)) * ((EAS_I32)(audio2)) \
- ) \
- >> (BITS_PER_AUDIO_SAMPLE-1) \
- )
-
-#define SATURATE(x) \
- ((((EAS_I32)(x)) > DISTORTION_ONE) ? (DISTORTION_ONE) : \
- (((EAS_I32)(x)) < DISTORTION_MINUS_ONE) ? (DISTORTION_MINUS_ONE) : ((EAS_I32)(x)));
-
-
-
-/*----------------------------------------------------------------------------
- * EAS_Calculate2toX()
- *----------------------------------------------------------------------------
- * Purpose:
- * Calculate 2^x
- *
- * Inputs:
- * nCents - measured in cents
- *
- * Outputs:
- * nResult - int.frac result (where frac has NUM_DENTS_FRAC_BITS)
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_I32 EAS_Calculate2toX (EAS_I32 nCents);
-
-/*----------------------------------------------------------------------------
- * EAS_LogToLinear16()
- *----------------------------------------------------------------------------
- * Purpose:
- * Transform log value to linear gain multiplier using piece-wise linear
- * approximation
- *
- * Inputs:
- * nGain - log scale value in 20.10 format. Even though gain is normally
- * stored in 6.10 (16-bit) format we use 32-bit numbers here to eliminate
- * the need for saturation checking when combining gain values.
- *
- * Outputs:
- * Returns a 16-bit linear value approximately equal to 2^(nGain/1024)
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_U16 EAS_LogToLinear16 (EAS_I32 nGain);
-
-/*----------------------------------------------------------------------------
- * EAS_VolumeToGain()
- *----------------------------------------------------------------------------
- * Purpose:
- * Transform volume control in 1dB increments to gain multiplier
- *
- * Inputs:
- * volume - 100 = 0dB, 99 = -1dB, 0 = -inf
- *
- * Outputs:
- * Returns a 16-bit linear value
- *----------------------------------------------------------------------------
-*/
-EAS_I16 EAS_VolumeToGain (EAS_INT volume);
-
-/*----------------------------------------------------------------------------
- * EAS_fsqrt()
- *----------------------------------------------------------------------------
- * Purpose:
- * Calculates the square root of a 32-bit fixed point value
- *
- * Inputs:
- * n = value of interest
- *
- * Outputs:
- * returns the square root of n
- *
- *----------------------------------------------------------------------------
-*/
-EAS_U16 EAS_fsqrt (EAS_U32 n);
-
-/*----------------------------------------------------------------------------
- * EAS_flog2()
- *----------------------------------------------------------------------------
- * Purpose:
- * Calculates the log2 of a 32-bit fixed point value
- *
- * Inputs:
- * n = value of interest
- *
- * Outputs:
- * returns the log2 of n
- *
- *----------------------------------------------------------------------------
-*/
-EAS_I32 EAS_flog2 (EAS_U32 n);
-
-#endif
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 584 $
+ * $Date: 2007-03-08 09:49:24 -0800 (Thu, 08 Mar 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+#ifndef _EAS_MATH_H
+#define _EAS_MATH_H
+
+
+/** coefs for pan, generates sin, cos */
+#define COEFF_PAN_G2 -27146 /* -0.82842712474619 = 2 - 4/sqrt(2) */
+#define COEFF_PAN_G0 23170 /* 0.707106781186547 = 1/sqrt(2) */
+
+/*
+coefficients for approximating
+2^x = gn2toX0 + gn2toX1*x + gn2toX2*x^2 + gn2toX3*x^3
+where x is a int.frac number representing number of octaves.
+Actually, we approximate only the 2^(frac) using the power series
+and implement the 2^(int) as a shift, so that
+2^x == 2^(int.frac) == 2^(int) * 2^(fract)
+ == (gn2toX0 + gn2toX1*x + gn2toX2*x^2 + gn2toX3*x^3) << (int)
+
+The gn2toX.. were generated using a best fit for a 3rd
+order polynomial, instead of taking the coefficients from
+a truncated Taylor (or Maclaurin?) series.
+*/
+
+#define GN2_TO_X0 32768 /* 1 */
+#define GN2_TO_X1 22833 /* 0.696807861328125 */
+#define GN2_TO_X2 7344 /* 0.22412109375 */
+#define GN2_TO_X3 2588 /* 0.0789794921875 */
+
+/*----------------------------------------------------------------------------
+ * Fixed Point Math
+ *----------------------------------------------------------------------------
+ * These macros are used for fixed point multiplies. If the processor
+ * supports fixed point multiplies, replace these macros with inline
+ * assembly code to improve performance.
+ *----------------------------------------------------------------------------
+*/
+
+/* Fixed point multiply 0.15 x 0.15 = 0.15 returned as 32-bits */
+#define FMUL_15x15(a,b) \
+ /*lint -e(704) <avoid multiply for performance>*/ \
+ (((EAS_I32)(a) * (EAS_I32)(b)) >> 15)
+
+/* Fixed point multiply 0.7 x 0.7 = 0.15 returned as 32-bits */
+#define FMUL_7x7(a,b) \
+ /*lint -e(704) <avoid multiply for performance>*/ \
+ (((EAS_I32)(a) * (EAS_I32)(b) ) << 1)
+
+/* Fixed point multiply 0.8 x 0.8 = 0.15 returned as 32-bits */
+#define FMUL_8x8(a,b) \
+ /*lint -e(704) <avoid multiply for performance>*/ \
+ (((EAS_I32)(a) * (EAS_I32)(b) ) >> 1)
+
+/* Fixed point multiply 0.8 x 1.15 = 0.15 returned as 32-bits */
+#define FMUL_8x15(a,b) \
+ /*lint -e(704) <avoid divide for performance>*/ \
+ (((EAS_I32)((a) << 7) * (EAS_I32)(b)) >> 15)
+
+/* macros for fractional phase accumulator */
+/*
+Note: changed the _U32 to _I32 on 03/14/02. This should not
+affect the phase calculations, and should allow us to reuse these
+macros for other audio sample related math.
+*/
+#define HARDWARE_BIT_WIDTH 32
+
+#define NUM_PHASE_INT_BITS 1
+#define NUM_PHASE_FRAC_BITS 15
+
+#define PHASE_FRAC_MASK (EAS_U32) ((0x1L << NUM_PHASE_FRAC_BITS) -1)
+
+#define GET_PHASE_INT_PART(x) (EAS_U32)((EAS_U32)(x) >> NUM_PHASE_FRAC_BITS)
+#define GET_PHASE_FRAC_PART(x) (EAS_U32)((EAS_U32)(x) & PHASE_FRAC_MASK)
+
+#define DEFAULT_PHASE_FRAC 0
+#define DEFAULT_PHASE_INT 0
+
+/*
+Linear interpolation calculates:
+output = (1-frac) * sample[n] + (frac) * sample[n+1]
+
+where conceptually 0 <= frac < 1
+
+For a fixed point implementation, frac is actually an integer value
+with an implied binary point one position to the left. The value of
+one (unity) is given by PHASE_ONE
+one half and one quarter are useful for 4-point linear interp.
+*/
+#define PHASE_ONE (EAS_I32) (0x1L << NUM_PHASE_FRAC_BITS)
+
+/*
+ Multiply the signed audio sample by the unsigned fraction.
+- a is the signed audio sample
+- b is the unsigned fraction (cast to signed int as long as coef
+ uses (n-1) or less bits, where n == hardware bit width)
+*/
+#define MULT_AUDIO_COEF(audio,coef) /*lint -e704 <avoid divide for performance>*/ \
+ (EAS_I32)( \
+ ( \
+ ((EAS_I32)(audio)) * ((EAS_I32)(coef)) \
+ ) \
+ >> NUM_PHASE_FRAC_BITS \
+ ) \
+ /* lint +704 <restore checking>*/
+
+/* wet / dry calculation macros */
+#define NUM_WET_DRY_FRAC_BITS 7 // 15
+#define NUM_WET_DRY_INT_BITS 9 // 1
+
+/* define a 1.0 */
+#define WET_DRY_ONE (EAS_I32) ((0x1L << NUM_WET_DRY_FRAC_BITS))
+#define WET_DRY_MINUS_ONE (EAS_I32) (~WET_DRY_ONE)
+#define WET_DRY_FULL_SCALE (EAS_I32) (WET_DRY_ONE - 1)
+
+#define MULT_AUDIO_WET_DRY_COEF(audio,coef) /*lint -e(702) <avoid divide for performance>*/ \
+ (EAS_I32)( \
+ ( \
+ ((EAS_I32)(audio)) * ((EAS_I32)(coef)) \
+ ) \
+ >> NUM_WET_DRY_FRAC_BITS \
+ )
+
+/* Envelope 1 (EG1) calculation macros */
+#define NUM_EG1_INT_BITS 1
+#define NUM_EG1_FRAC_BITS 15
+
+/* the max positive gain used in the synth for EG1 */
+/* SYNTH_FULL_SCALE_EG1_GAIN must match the value in the dls2eas
+converter, otherwise, the values we read from the .eas file are bogus. */
+#define SYNTH_FULL_SCALE_EG1_GAIN (EAS_I32) ((0x1L << NUM_EG1_FRAC_BITS) -1)
+
+/* define a 1.0 */
+#define EG1_ONE (EAS_I32) ((0x1L << NUM_EG1_FRAC_BITS))
+#define EG1_MINUS_ONE (EAS_I32) (~SYNTH_FULL_SCALE_EG1_GAIN)
+
+#define EG1_HALF (EAS_I32) (EG1_ONE/2)
+#define EG1_MINUS_HALF (EAS_I32) (EG1_MINUS_ONE/2)
+
+/*
+We implement the EG1 using a linear gain value, which means that the
+attack segment is handled by incrementing (adding) the linear gain.
+However, EG1 treats the Decay, Sustain, and Release differently than
+the Attack portion. For Decay, Sustain, and Release, the gain is
+linear on dB scale, which is equivalent to exponential damping on
+a linear scale. Because we use a linear gain for EG1, we implement
+the Decay and Release as multiplication (instead of incrementing
+as we did for the attack segment).
+Therefore, we need the following macro to implement the multiplication
+(i.e., exponential damping) during the Decay and Release segments of
+the EG1
+*/
+#define MULT_EG1_EG1(gain,damping) /*lint -e(704) <avoid divide for performance>*/ \
+ (EAS_I32)( \
+ ( \
+ ((EAS_I32)(gain)) * ((EAS_I32)(damping)) \
+ ) \
+ >> NUM_EG1_FRAC_BITS \
+ )
+
+// Use the following macro specifically for the filter, when multiplying
+// the b1 coefficient. The 0 <= |b1| < 2, which therefore might overflow
+// in certain conditions because we store b1 as a 1.15 value.
+// Instead, we could store b1 as b1p (b1' == b1 "prime") where
+// b1p == b1/2, thus ensuring no potential overflow for b1p because
+// 0 <= |b1p| < 1
+// However, during the filter calculation, we must account for the fact
+// that we are using b1p instead of b1, and thereby multiply by
+// an extra factor of 2. Rather than multiply by an extra factor of 2,
+// we can instead shift the result right by one less, hence the
+// modified shift right value of (NUM_EG1_FRAC_BITS -1)
+#define MULT_EG1_EG1_X2(gain,damping) /*lint -e(702) <avoid divide for performance>*/ \
+ (EAS_I32)( \
+ ( \
+ ((EAS_I32)(gain)) * ((EAS_I32)(damping)) \
+ ) \
+ >> (NUM_EG1_FRAC_BITS -1) \
+ )
+
+#define SATURATE_EG1(x) /*lint -e{734} saturation operation */ \
+ ((EAS_I32)(x) > SYNTH_FULL_SCALE_EG1_GAIN) ? (SYNTH_FULL_SCALE_EG1_GAIN) : \
+ ((EAS_I32)(x) < EG1_MINUS_ONE) ? (EG1_MINUS_ONE) : (x);
+
+
+/* use "digital cents" == "dents" instead of cents */
+/* we coudl re-use the phase frac macros, but if we do,
+we must change the phase macros to cast to _I32 instead of _U32,
+because using a _U32 cast causes problems when shifting the exponent
+for the 2^x calculation, because right shift a negative values MUST
+be sign extended, or else the 2^x calculation is wrong */
+
+/* use "digital cents" == "dents" instead of cents */
+#define NUM_DENTS_FRAC_BITS 12
+#define NUM_DENTS_INT_BITS (HARDWARE_BIT_WIDTH - NUM_DENTS_FRAC_BITS)
+
+#define DENTS_FRAC_MASK (EAS_I32) ((0x1L << NUM_DENTS_FRAC_BITS) -1)
+
+#define GET_DENTS_INT_PART(x) /*lint -e(704) <avoid divide for performance>*/ \
+ (EAS_I32)((EAS_I32)(x) >> NUM_DENTS_FRAC_BITS)
+
+#define GET_DENTS_FRAC_PART(x) (EAS_I32)((EAS_I32)(x) & DENTS_FRAC_MASK)
+
+#define DENTS_ONE (EAS_I32) (0x1L << NUM_DENTS_FRAC_BITS)
+
+/* use CENTS_TO_DENTS to convert a value in cents to dents */
+#define CENTS_TO_DENTS (EAS_I32) (DENTS_ONE * (0x1L << NUM_EG1_FRAC_BITS) / 1200L) \
+
+
+/*
+For gain, the LFO generates a value that modulates in terms
+of dB. However, we use a linear gain value, so we must convert
+the LFO value in dB to a linear gain. Normally, we would use
+linear gain = 10^x, where x = LFO value in dB / 20.
+Instead, we implement 10^x using our 2^x approximation.
+because
+
+ 10^x = 2^(log2(10^x)) = 2^(x * log2(10))
+
+so we need to multiply by log2(10) which is just a constant.
+Ah, but just wait -- our 2^x actually doesn't exactly implement
+2^x, but it actually assumes that the input is in cents, and within
+the 2^x approximation converts its input from cents to octaves
+by dividing its input by 1200.
+
+So, in order to convert the LFO gain value in dB to something
+that our existing 2^x approximation can use, multiply the LFO gain
+by log2(10) * 1200 / 20
+
+The divide by 20 helps convert dB to linear gain, and we might
+as well incorporate that operation into this conversion.
+Of course, we need to keep some fractional bits, so multiply
+the constant by NUM_EG1_FRAC_BITS
+*/
+
+/* use LFO_GAIN_TO_CENTS to convert the LFO gain value to cents */
+#if 0
+#define DOUBLE_LOG2_10 (double) (3.32192809488736) /* log2(10) */
+
+#define DOUBLE_LFO_GAIN_TO_CENTS (double) \
+ ( \
+ (DOUBLE_LOG2_10) * \
+ 1200.0 / \
+ 20.0 \
+ )
+
+#define LFO_GAIN_TO_CENTS (EAS_I32) \
+ ( \
+ DOUBLE_LFO_GAIN_TO_CENTS * \
+ (0x1L << NUM_EG1_FRAC_BITS) \
+ )
+#endif
+
+#define LFO_GAIN_TO_CENTS (EAS_I32) (1671981156L >> (23 - NUM_EG1_FRAC_BITS))
+
+
+#define MULT_DENTS_COEF(dents,coef) /*lint -e704 <avoid divide for performance>*/ \
+ (EAS_I32)( \
+ ( \
+ ((EAS_I32)(dents)) * ((EAS_I32)(coef)) \
+ ) \
+ >> NUM_DENTS_FRAC_BITS \
+ ) \
+ /* lint +e704 <restore checking>*/
+
+/* we use 16-bits in the PC per audio sample */
+#define BITS_PER_AUDIO_SAMPLE 16
+
+/* we define 1 as 1.0 - 1 LSbit */
+#define DISTORTION_ONE (EAS_I32)((0x1L << (BITS_PER_AUDIO_SAMPLE-1)) -1)
+#define DISTORTION_MINUS_ONE (EAS_I32)(~DISTORTION_ONE)
+
+/* drive coef is given as int.frac */
+#define NUM_DRIVE_COEF_INT_BITS 1
+#define NUM_DRIVE_COEF_FRAC_BITS 4
+
+#define MULT_AUDIO_DRIVE(audio,drive) /*lint -e(702) <avoid divide for performance>*/ \
+ (EAS_I32) ( \
+ ( \
+ ((EAS_I32)(audio)) * ((EAS_I32)(drive)) \
+ ) \
+ >> NUM_DRIVE_COEF_FRAC_BITS \
+ )
+
+#define MULT_AUDIO_AUDIO(audio1,audio2) /*lint -e(702) <avoid divide for performance>*/ \
+ (EAS_I32) ( \
+ ( \
+ ((EAS_I32)(audio1)) * ((EAS_I32)(audio2)) \
+ ) \
+ >> (BITS_PER_AUDIO_SAMPLE-1) \
+ )
+
+#define SATURATE(x) \
+ ((((EAS_I32)(x)) > DISTORTION_ONE) ? (DISTORTION_ONE) : \
+ (((EAS_I32)(x)) < DISTORTION_MINUS_ONE) ? (DISTORTION_MINUS_ONE) : ((EAS_I32)(x)));
+
+
+
+/*----------------------------------------------------------------------------
+ * EAS_Calculate2toX()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Calculate 2^x
+ *
+ * Inputs:
+ * nCents - measured in cents
+ *
+ * Outputs:
+ * nResult - int.frac result (where frac has NUM_DENTS_FRAC_BITS)
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_I32 EAS_Calculate2toX (EAS_I32 nCents);
+
+/*----------------------------------------------------------------------------
+ * EAS_LogToLinear16()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Transform log value to linear gain multiplier using piece-wise linear
+ * approximation
+ *
+ * Inputs:
+ * nGain - log scale value in 20.10 format. Even though gain is normally
+ * stored in 6.10 (16-bit) format we use 32-bit numbers here to eliminate
+ * the need for saturation checking when combining gain values.
+ *
+ * Outputs:
+ * Returns a 16-bit linear value approximately equal to 2^(nGain/1024)
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_U16 EAS_LogToLinear16 (EAS_I32 nGain);
+
+/*----------------------------------------------------------------------------
+ * EAS_VolumeToGain()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Transform volume control in 1dB increments to gain multiplier
+ *
+ * Inputs:
+ * volume - 100 = 0dB, 99 = -1dB, 0 = -inf
+ *
+ * Outputs:
+ * Returns a 16-bit linear value
+ *----------------------------------------------------------------------------
+*/
+EAS_I16 EAS_VolumeToGain (EAS_INT volume);
+
+/*----------------------------------------------------------------------------
+ * EAS_fsqrt()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Calculates the square root of a 32-bit fixed point value
+ *
+ * Inputs:
+ * n = value of interest
+ *
+ * Outputs:
+ * returns the square root of n
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_U16 EAS_fsqrt (EAS_U32 n);
+
+/*----------------------------------------------------------------------------
+ * EAS_flog2()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Calculates the log2 of a 32-bit fixed point value
+ *
+ * Inputs:
+ * n = value of interest
+ *
+ * Outputs:
+ * returns the log2 of n
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_I32 EAS_flog2 (EAS_U32 n);
+
+#endif
+
diff --git a/arm-hybrid-22k/lib_src/eas_midi.c b/arm-hybrid-22k/lib_src/eas_midi.c
index 08aed72..2c0c793 100644
--- a/arm-hybrid-22k/lib_src/eas_midi.c
+++ b/arm-hybrid-22k/lib_src/eas_midi.c
@@ -1,13 +1,13 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_midi.c
- *
- * Contents and purpose:
- * This file implements the MIDI stream parser. It is called by eas_smf.c to parse MIDI messages
- * that are streamed out of the file. It can also parse live MIDI streams.
- *
- * Copyright Sonic Network Inc. 2005
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_midi.c
+ *
+ * Contents and purpose:
+ * This file implements the MIDI stream parser. It is called by eas_smf.c to parse MIDI messages
+ * that are streamed out of the file. It can also parse live MIDI streams.
+ *
+ * Copyright Sonic Network Inc. 2005
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,550 +20,550 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 794 $
- * $Date: 2007-08-01 00:08:48 -0700 (Wed, 01 Aug 2007) $
- *----------------------------------------------------------------------------
-*/
-
-#include "eas_data.h"
-#include "eas_report.h"
-#include "eas_miditypes.h"
-#include "eas_midi.h"
-#include "eas_vm_protos.h"
-#include "eas_parser.h"
-
-#ifdef JET_INTERFACE
-#include "jet_data.h"
-#endif
-
-
-/* state enumerations for ProcessSysExMessage */
-typedef enum
-{
- eSysEx,
- eSysExUnivNonRealTime,
- eSysExUnivNrtTargetID,
- eSysExGMControl,
- eSysExUnivRealTime,
- eSysExUnivRtTargetID,
- eSysExDeviceControl,
- eSysExMasterVolume,
- eSysExMasterVolLSB,
- eSysExSPMIDI,
- eSysExSPMIDIchan,
- eSysExSPMIDIMIP,
- eSysExMfgID1,
- eSysExMfgID2,
- eSysExMfgID3,
- eSysExEnhancer,
- eSysExEnhancerSubID,
- eSysExEnhancerFeedback1,
- eSysExEnhancerFeedback2,
- eSysExEnhancerDrive,
- eSysExEnhancerWet,
- eSysExEOX,
- eSysExIgnore
-} E_SYSEX_STATES;
-
-/* local prototypes */
-static EAS_RESULT ProcessMIDIMessage (S_EAS_DATA *pEASData, S_SYNTH *pSynth, S_MIDI_STREAM *pMIDIStream, EAS_INT parserMode);
-static EAS_RESULT ProcessSysExMessage (S_EAS_DATA *pEASData, S_SYNTH *pSynth, S_MIDI_STREAM *pMIDIStream, EAS_U8 c, EAS_INT parserMode);
-
-/*----------------------------------------------------------------------------
- * EAS_InitMIDIStream()
- *----------------------------------------------------------------------------
- * Purpose:
- * Initializes the MIDI stream state for parsing.
- *
- * Inputs:
- *
- * Outputs:
- * returns EAS_RESULT (EAS_SUCCESS is OK)
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-void EAS_InitMIDIStream (S_MIDI_STREAM *pMIDIStream)
-{
- pMIDIStream->byte3 = EAS_FALSE;
- pMIDIStream->pending = EAS_FALSE;
- pMIDIStream->runningStatus = 0;
- pMIDIStream->status = 0;
-}
-
-/*----------------------------------------------------------------------------
- * EAS_ParseMIDIStream()
- *----------------------------------------------------------------------------
- * Purpose:
- * Parses a MIDI input stream character by character. Characters are pushed (rather than pulled)
- * so the interface works equally well for both file and stream I/O.
- *
- * Inputs:
- * c - character from MIDI stream
- *
- * Outputs:
- * returns EAS_RESULT (EAS_SUCCESS is OK)
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT EAS_ParseMIDIStream (S_EAS_DATA *pEASData, S_SYNTH *pSynth, S_MIDI_STREAM *pMIDIStream, EAS_U8 c, EAS_INT parserMode)
-{
-
- /* check for new status byte */
- if (c & 0x80)
- {
- /* save new running status */
- if (c < 0xf8)
- {
- pMIDIStream->runningStatus = c;
- pMIDIStream->byte3 = EAS_FALSE;
-
- /* deal with SysEx */
- if ((c == 0xf7) || (c == 0xf0))
- {
- if (parserMode == eParserModeMetaData)
- return EAS_SUCCESS;
- return ProcessSysExMessage(pEASData, pSynth, pMIDIStream, c, parserMode);
- }
-
- /* inform the file parser that we're in the middle of a message */
- if ((c < 0xf4) || (c > 0xf6))
- pMIDIStream->pending = EAS_TRUE;
- }
-
- /* real-time message - ignore it */
- return EAS_SUCCESS;
- }
-
- /* 3rd byte of a 3-byte message? */
- if (pMIDIStream->byte3)
- {
- pMIDIStream->d2 = c;
- pMIDIStream->byte3 = EAS_FALSE;
- pMIDIStream->pending = EAS_FALSE;
- if (parserMode == eParserModeMetaData)
- return EAS_SUCCESS;
- return ProcessMIDIMessage(pEASData, pSynth, pMIDIStream, parserMode);
- }
-
- /* check for status received */
- if (pMIDIStream->runningStatus)
- {
-
- /* save new status and data byte */
- pMIDIStream->status = pMIDIStream->runningStatus;
-
- /* check for 3-byte messages */
- if (pMIDIStream->status < 0xc0)
- {
- pMIDIStream->d1 = c;
- pMIDIStream->pending = EAS_TRUE;
- pMIDIStream->byte3 = EAS_TRUE;
- return EAS_SUCCESS;
- }
-
- /* check for 2-byte messages */
- if (pMIDIStream->status < 0xe0)
- {
- pMIDIStream->d1 = c;
- pMIDIStream->pending = EAS_FALSE;
- if (parserMode == eParserModeMetaData)
- return EAS_SUCCESS;
- return ProcessMIDIMessage(pEASData, pSynth, pMIDIStream, parserMode);
- }
-
- /* check for more 3-bytes message */
- if (pMIDIStream->status < 0xf0)
- {
- pMIDIStream->d1 = c;
- pMIDIStream->pending = EAS_TRUE;
- pMIDIStream->byte3 = EAS_TRUE;
- return EAS_SUCCESS;
- }
-
- /* SysEx message? */
- if (pMIDIStream->status == 0xF0)
- {
- if (parserMode == eParserModeMetaData)
- return EAS_SUCCESS;
- return ProcessSysExMessage(pEASData, pSynth, pMIDIStream, c, parserMode);
- }
-
- /* remaining messages all clear running status */
- pMIDIStream->runningStatus = 0;
-
- /* F2 is 3-byte message */
- if (pMIDIStream->status == 0xf2)
- {
- pMIDIStream->byte3 = EAS_TRUE;
- return EAS_SUCCESS;
- }
- }
-
- /* no status byte received, provide a warning, but we should be able to recover */
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Received MIDI data without a valid status byte: %d\n",c); */ }
- pMIDIStream->pending = EAS_FALSE;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * ProcessMIDIMessage()
- *----------------------------------------------------------------------------
- * Purpose:
- * This function processes a typical MIDI message. All of the data has been received, just need
- * to take appropriate action.
- *
- * Inputs:
- *
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT ProcessMIDIMessage (S_EAS_DATA *pEASData, S_SYNTH *pSynth, S_MIDI_STREAM *pMIDIStream, EAS_INT parserMode)
-{
- EAS_U8 channel;
-
- channel = pMIDIStream->status & 0x0f;
- switch (pMIDIStream->status & 0xf0)
- {
- case 0x80:
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL,"NoteOff: %02x %02x %02x\n",
- pMIDIStream->status, pMIDIStream->d1, pMIDIStream->d2); */ }
- if (parserMode < eParserModeMute)
- VMStopNote(pEASData->pVoiceMgr, pSynth, channel, pMIDIStream->d1, pMIDIStream->d2);
- break;
-
- case 0x90:
- if (pMIDIStream->d2)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL,"NoteOn: %02x %02x %02x\n",
- pMIDIStream->status, pMIDIStream->d1, pMIDIStream->d2); */ }
- pMIDIStream->flags |= MIDI_FLAG_FIRST_NOTE;
- if (parserMode == eParserModePlay)
- VMStartNote(pEASData->pVoiceMgr, pSynth, channel, pMIDIStream->d1, pMIDIStream->d2);
- }
- else
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL,"NoteOff: %02x %02x %02x\n",
- pMIDIStream->status, pMIDIStream->d1, pMIDIStream->d2); */ }
- if (parserMode < eParserModeMute)
- VMStopNote(pEASData->pVoiceMgr, pSynth, channel, pMIDIStream->d1, pMIDIStream->d2);
- }
- break;
-
- case 0xa0:
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL,"PolyPres: %02x %02x %02x\n",
- pMIDIStream->status, pMIDIStream->d1, pMIDIStream->d2); */ }
- break;
-
- case 0xb0:
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL,"Control: %02x %02x %02x\n",
- pMIDIStream->status, pMIDIStream->d1, pMIDIStream->d2); */ }
- if (parserMode < eParserModeMute)
- VMControlChange(pEASData->pVoiceMgr, pSynth, channel, pMIDIStream->d1, pMIDIStream->d2);
-#ifdef JET_INTERFACE
- if (pMIDIStream->jetData & MIDI_FLAGS_JET_CB)
- {
- JET_Event(pEASData, pMIDIStream->jetData & (JET_EVENT_SEG_MASK | JET_EVENT_TRACK_MASK),
- channel, pMIDIStream->d1, pMIDIStream->d2);
- }
-#endif
- break;
-
- case 0xc0:
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL,"Program: %02x %02x\n",
- pMIDIStream->status, pMIDIStream->d1); */ }
- if (parserMode < eParserModeMute)
- VMProgramChange(pEASData->pVoiceMgr, pSynth, channel, pMIDIStream->d1);
- break;
-
- case 0xd0:
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL,"ChanPres: %02x %02x\n",
- pMIDIStream->status, pMIDIStream->d1); */ }
- if (parserMode < eParserModeMute)
- VMChannelPressure(pSynth, channel, pMIDIStream->d1);
- break;
-
- case 0xe0:
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL,"PBend: %02x %02x %02x\n",
- pMIDIStream->status, pMIDIStream->d1, pMIDIStream->d2); */ }
- if (parserMode < eParserModeMute)
- VMPitchBend(pSynth, channel, pMIDIStream->d1, pMIDIStream->d2);
- break;
-
- default:
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL,"Unknown: %02x %02x %02x\n",
- pMIDIStream->status, pMIDIStream->d1, pMIDIStream->d2); */ }
- }
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * ProcessSysExMessage()
- *----------------------------------------------------------------------------
- * Purpose:
- * Process a SysEx character byte from the MIDI stream. Since we cannot
- * simply wait for the next character to arrive, we are forced to save
- * state after each character. It would be easier to parse at the file
- * level, but then we lose the nice feature of being able to support
- * these messages in a real-time MIDI stream.
- *
- * Inputs:
- * pEASData - pointer to synthesizer instance data
- * c - character to be processed
- * locating - if true, the sequencer is relocating to a new position
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- * Notes:
- * These are the SysEx messages we can receive:
- *
- * SysEx messages
- * { f0 7e 7f 09 01 f7 } GM 1 On
- * { f0 7e 7f 09 02 f7 } GM 1/2 Off
- * { f0 7e 7f 09 03 f7 } GM 2 On
- * { f0 7f 7f 04 01 lsb msb } Master Volume
- * { f0 7f 7f 0b 01 ch mip [ch mip ...] f7 } SP-MIDI
- * { f0 00 01 3a 04 01 fdbk1 fdbk2 drive wet dry f7 } Enhancer
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT ProcessSysExMessage (S_EAS_DATA *pEASData, S_SYNTH *pSynth, S_MIDI_STREAM *pMIDIStream, EAS_U8 c, EAS_INT parserMode)
-{
-
- /* check for start byte */
- if (c == 0xf0)
- {
- pMIDIStream->sysExState = eSysEx;
- }
- /* check for end byte */
- else if (c == 0xf7)
- {
- /* if this was a MIP message, update the MIP table */
- if ((pMIDIStream->sysExState == eSysExSPMIDIchan) && (parserMode != eParserModeMetaData))
- VMUpdateMIPTable(pEASData->pVoiceMgr, pSynth);
- pMIDIStream->sysExState = eSysExIgnore;
- }
-
- /* process SysEx message */
- else
- {
- switch (pMIDIStream->sysExState)
- {
- case eSysEx:
-
- /* first byte, determine message class */
- switch (c)
- {
- case 0x7e:
- pMIDIStream->sysExState = eSysExUnivNonRealTime;
- break;
- case 0x7f:
- pMIDIStream->sysExState = eSysExUnivRealTime;
- break;
- case 0x00:
- pMIDIStream->sysExState = eSysExMfgID1;
- break;
- default:
- pMIDIStream->sysExState = eSysExIgnore;
- break;
- }
- break;
-
- /* process GM message */
- case eSysExUnivNonRealTime:
- if (c == 0x7f)
- pMIDIStream->sysExState = eSysExUnivNrtTargetID;
- else
- pMIDIStream->sysExState = eSysExIgnore;
- break;
-
- case eSysExUnivNrtTargetID:
- if (c == 0x09)
- pMIDIStream->sysExState = eSysExGMControl;
- else
- pMIDIStream->sysExState = eSysExIgnore;
- break;
-
- case eSysExGMControl:
- if ((c == 1) || (c == 3))
- {
- /* GM 1 or GM2 On, reset synth */
- if (parserMode != eParserModeMetaData)
- {
- pMIDIStream->flags |= MIDI_FLAG_GM_ON;
- VMReset(pEASData->pVoiceMgr, pSynth, EAS_FALSE);
- VMInitMIPTable(pSynth);
- }
- pMIDIStream->sysExState = eSysExEOX;
- }
- else
- pMIDIStream->sysExState = eSysExIgnore;
- break;
-
- /* Process Master Volume and SP-MIDI */
- case eSysExUnivRealTime:
- if (c == 0x7f)
- pMIDIStream->sysExState = eSysExUnivRtTargetID;
- else
- pMIDIStream->sysExState = eSysExIgnore;
- break;
-
- case eSysExUnivRtTargetID:
- if (c == 0x04)
- pMIDIStream->sysExState = eSysExDeviceControl;
- else if (c == 0x0b)
- pMIDIStream->sysExState = eSysExSPMIDI;
- else
- pMIDIStream->sysExState = eSysExIgnore;
- break;
-
- /* process master volume */
- case eSysExDeviceControl:
- if (c == 0x01)
- pMIDIStream->sysExState = eSysExMasterVolume;
- else
- pMIDIStream->sysExState = eSysExIgnore;
- break;
-
- case eSysExMasterVolume:
- /* save LSB */
- pMIDIStream->d1 = c;
- pMIDIStream->sysExState = eSysExMasterVolLSB;
- break;
-
- case eSysExMasterVolLSB:
- if (parserMode != eParserModeMetaData)
- {
- EAS_I32 gain = ((EAS_I32) c << 8) | ((EAS_I32) pMIDIStream->d1 << 1);
- gain = (gain * gain) >> 15;
- VMSetVolume(pSynth, (EAS_U16) gain);
- }
- pMIDIStream->sysExState = eSysExEOX;
- break;
-
- /* process SP-MIDI MIP message */
- case eSysExSPMIDI:
- if (c == 0x01)
- {
- /* assume all channels are muted */
- if (parserMode != eParserModeMetaData)
- VMInitMIPTable(pSynth);
- pMIDIStream->d1 = 0;
- pMIDIStream->sysExState = eSysExSPMIDIchan;
- }
- else
- pMIDIStream->sysExState = eSysExIgnore;
- break;
-
- case eSysExSPMIDIchan:
- if (c < NUM_SYNTH_CHANNELS)
- {
- pMIDIStream->d2 = c;
- pMIDIStream->sysExState = eSysExSPMIDIMIP;
- }
- else
- {
- /* bad MIP message - unmute channels */
- if (parserMode != eParserModeMetaData)
- VMInitMIPTable(pSynth);
- pMIDIStream->sysExState = eSysExIgnore;
- }
- break;
-
- case eSysExSPMIDIMIP:
- /* process MIP entry here */
- if (parserMode != eParserModeMetaData)
- VMSetMIPEntry(pEASData->pVoiceMgr, pSynth, pMIDIStream->d2, pMIDIStream->d1, c);
- pMIDIStream->sysExState = eSysExSPMIDIchan;
-
- /* if 16 channels received, update MIP table */
- if (++pMIDIStream->d1 == NUM_SYNTH_CHANNELS)
- {
- if (parserMode != eParserModeMetaData)
- VMUpdateMIPTable(pEASData->pVoiceMgr, pSynth);
- pMIDIStream->sysExState = eSysExEOX;
- }
- break;
-
- /* process Enhancer */
- case eSysExMfgID1:
- if (c == 0x01)
- pMIDIStream->sysExState = eSysExMfgID1;
- else
- pMIDIStream->sysExState = eSysExIgnore;
- break;
-
- case eSysExMfgID2:
- if (c == 0x3a)
- pMIDIStream->sysExState = eSysExMfgID1;
- else
- pMIDIStream->sysExState = eSysExIgnore;
- break;
-
- case eSysExMfgID3:
- if (c == 0x04)
- pMIDIStream->sysExState = eSysExEnhancer;
- else
- pMIDIStream->sysExState = eSysExIgnore;
- break;
-
- case eSysExEnhancer:
- if (c == 0x01)
- pMIDIStream->sysExState = eSysExEnhancerSubID;
- else
- pMIDIStream->sysExState = eSysExIgnore;
- break;
-
- case eSysExEnhancerSubID:
- pMIDIStream->sysExState = eSysExEnhancerFeedback1;
- break;
-
- case eSysExEnhancerFeedback1:
- pMIDIStream->sysExState = eSysExEnhancerFeedback2;
- break;
-
- case eSysExEnhancerFeedback2:
- pMIDIStream->sysExState = eSysExEnhancerDrive;
- break;
-
- case eSysExEnhancerDrive:
- pMIDIStream->sysExState = eSysExEnhancerWet;
- break;
-
- case eSysExEnhancerWet:
- pMIDIStream->sysExState = eSysExEOX;
- break;
-
- case eSysExEOX:
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Expected F7, received %02x\n", c); */ }
- pMIDIStream->sysExState = eSysExIgnore;
- break;
-
- case eSysExIgnore:
- break;
-
- default:
- pMIDIStream->sysExState = eSysExIgnore;
- break;
- }
- }
-
- if (pMIDIStream->sysExState == eSysExIgnore)
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Ignoring SysEx byte %02x\n", c); */ }
- return EAS_SUCCESS;
-} /* end ProcessSysExMessage */
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 794 $
+ * $Date: 2007-08-01 00:08:48 -0700 (Wed, 01 Aug 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+#include "eas_data.h"
+#include "eas_report.h"
+#include "eas_miditypes.h"
+#include "eas_midi.h"
+#include "eas_vm_protos.h"
+#include "eas_parser.h"
+
+#ifdef JET_INTERFACE
+#include "jet_data.h"
+#endif
+
+
+/* state enumerations for ProcessSysExMessage */
+typedef enum
+{
+ eSysEx,
+ eSysExUnivNonRealTime,
+ eSysExUnivNrtTargetID,
+ eSysExGMControl,
+ eSysExUnivRealTime,
+ eSysExUnivRtTargetID,
+ eSysExDeviceControl,
+ eSysExMasterVolume,
+ eSysExMasterVolLSB,
+ eSysExSPMIDI,
+ eSysExSPMIDIchan,
+ eSysExSPMIDIMIP,
+ eSysExMfgID1,
+ eSysExMfgID2,
+ eSysExMfgID3,
+ eSysExEnhancer,
+ eSysExEnhancerSubID,
+ eSysExEnhancerFeedback1,
+ eSysExEnhancerFeedback2,
+ eSysExEnhancerDrive,
+ eSysExEnhancerWet,
+ eSysExEOX,
+ eSysExIgnore
+} E_SYSEX_STATES;
+
+/* local prototypes */
+static EAS_RESULT ProcessMIDIMessage (S_EAS_DATA *pEASData, S_SYNTH *pSynth, S_MIDI_STREAM *pMIDIStream, EAS_INT parserMode);
+static EAS_RESULT ProcessSysExMessage (S_EAS_DATA *pEASData, S_SYNTH *pSynth, S_MIDI_STREAM *pMIDIStream, EAS_U8 c, EAS_INT parserMode);
+
+/*----------------------------------------------------------------------------
+ * EAS_InitMIDIStream()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Initializes the MIDI stream state for parsing.
+ *
+ * Inputs:
+ *
+ * Outputs:
+ * returns EAS_RESULT (EAS_SUCCESS is OK)
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+void EAS_InitMIDIStream (S_MIDI_STREAM *pMIDIStream)
+{
+ pMIDIStream->byte3 = EAS_FALSE;
+ pMIDIStream->pending = EAS_FALSE;
+ pMIDIStream->runningStatus = 0;
+ pMIDIStream->status = 0;
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_ParseMIDIStream()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Parses a MIDI input stream character by character. Characters are pushed (rather than pulled)
+ * so the interface works equally well for both file and stream I/O.
+ *
+ * Inputs:
+ * c - character from MIDI stream
+ *
+ * Outputs:
+ * returns EAS_RESULT (EAS_SUCCESS is OK)
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_ParseMIDIStream (S_EAS_DATA *pEASData, S_SYNTH *pSynth, S_MIDI_STREAM *pMIDIStream, EAS_U8 c, EAS_INT parserMode)
+{
+
+ /* check for new status byte */
+ if (c & 0x80)
+ {
+ /* save new running status */
+ if (c < 0xf8)
+ {
+ pMIDIStream->runningStatus = c;
+ pMIDIStream->byte3 = EAS_FALSE;
+
+ /* deal with SysEx */
+ if ((c == 0xf7) || (c == 0xf0))
+ {
+ if (parserMode == eParserModeMetaData)
+ return EAS_SUCCESS;
+ return ProcessSysExMessage(pEASData, pSynth, pMIDIStream, c, parserMode);
+ }
+
+ /* inform the file parser that we're in the middle of a message */
+ if ((c < 0xf4) || (c > 0xf6))
+ pMIDIStream->pending = EAS_TRUE;
+ }
+
+ /* real-time message - ignore it */
+ return EAS_SUCCESS;
+ }
+
+ /* 3rd byte of a 3-byte message? */
+ if (pMIDIStream->byte3)
+ {
+ pMIDIStream->d2 = c;
+ pMIDIStream->byte3 = EAS_FALSE;
+ pMIDIStream->pending = EAS_FALSE;
+ if (parserMode == eParserModeMetaData)
+ return EAS_SUCCESS;
+ return ProcessMIDIMessage(pEASData, pSynth, pMIDIStream, parserMode);
+ }
+
+ /* check for status received */
+ if (pMIDIStream->runningStatus)
+ {
+
+ /* save new status and data byte */
+ pMIDIStream->status = pMIDIStream->runningStatus;
+
+ /* check for 3-byte messages */
+ if (pMIDIStream->status < 0xc0)
+ {
+ pMIDIStream->d1 = c;
+ pMIDIStream->pending = EAS_TRUE;
+ pMIDIStream->byte3 = EAS_TRUE;
+ return EAS_SUCCESS;
+ }
+
+ /* check for 2-byte messages */
+ if (pMIDIStream->status < 0xe0)
+ {
+ pMIDIStream->d1 = c;
+ pMIDIStream->pending = EAS_FALSE;
+ if (parserMode == eParserModeMetaData)
+ return EAS_SUCCESS;
+ return ProcessMIDIMessage(pEASData, pSynth, pMIDIStream, parserMode);
+ }
+
+ /* check for more 3-bytes message */
+ if (pMIDIStream->status < 0xf0)
+ {
+ pMIDIStream->d1 = c;
+ pMIDIStream->pending = EAS_TRUE;
+ pMIDIStream->byte3 = EAS_TRUE;
+ return EAS_SUCCESS;
+ }
+
+ /* SysEx message? */
+ if (pMIDIStream->status == 0xF0)
+ {
+ if (parserMode == eParserModeMetaData)
+ return EAS_SUCCESS;
+ return ProcessSysExMessage(pEASData, pSynth, pMIDIStream, c, parserMode);
+ }
+
+ /* remaining messages all clear running status */
+ pMIDIStream->runningStatus = 0;
+
+ /* F2 is 3-byte message */
+ if (pMIDIStream->status == 0xf2)
+ {
+ pMIDIStream->byte3 = EAS_TRUE;
+ return EAS_SUCCESS;
+ }
+ }
+
+ /* no status byte received, provide a warning, but we should be able to recover */
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Received MIDI data without a valid status byte: %d\n",c); */ }
+ pMIDIStream->pending = EAS_FALSE;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * ProcessMIDIMessage()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * This function processes a typical MIDI message. All of the data has been received, just need
+ * to take appropriate action.
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT ProcessMIDIMessage (S_EAS_DATA *pEASData, S_SYNTH *pSynth, S_MIDI_STREAM *pMIDIStream, EAS_INT parserMode)
+{
+ EAS_U8 channel;
+
+ channel = pMIDIStream->status & 0x0f;
+ switch (pMIDIStream->status & 0xf0)
+ {
+ case 0x80:
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL,"NoteOff: %02x %02x %02x\n",
+ pMIDIStream->status, pMIDIStream->d1, pMIDIStream->d2); */ }
+ if (parserMode < eParserModeMute)
+ VMStopNote(pEASData->pVoiceMgr, pSynth, channel, pMIDIStream->d1, pMIDIStream->d2);
+ break;
+
+ case 0x90:
+ if (pMIDIStream->d2)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL,"NoteOn: %02x %02x %02x\n",
+ pMIDIStream->status, pMIDIStream->d1, pMIDIStream->d2); */ }
+ pMIDIStream->flags |= MIDI_FLAG_FIRST_NOTE;
+ if (parserMode == eParserModePlay)
+ VMStartNote(pEASData->pVoiceMgr, pSynth, channel, pMIDIStream->d1, pMIDIStream->d2);
+ }
+ else
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL,"NoteOff: %02x %02x %02x\n",
+ pMIDIStream->status, pMIDIStream->d1, pMIDIStream->d2); */ }
+ if (parserMode < eParserModeMute)
+ VMStopNote(pEASData->pVoiceMgr, pSynth, channel, pMIDIStream->d1, pMIDIStream->d2);
+ }
+ break;
+
+ case 0xa0:
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL,"PolyPres: %02x %02x %02x\n",
+ pMIDIStream->status, pMIDIStream->d1, pMIDIStream->d2); */ }
+ break;
+
+ case 0xb0:
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL,"Control: %02x %02x %02x\n",
+ pMIDIStream->status, pMIDIStream->d1, pMIDIStream->d2); */ }
+ if (parserMode < eParserModeMute)
+ VMControlChange(pEASData->pVoiceMgr, pSynth, channel, pMIDIStream->d1, pMIDIStream->d2);
+#ifdef JET_INTERFACE
+ if (pMIDIStream->jetData & MIDI_FLAGS_JET_CB)
+ {
+ JET_Event(pEASData, pMIDIStream->jetData & (JET_EVENT_SEG_MASK | JET_EVENT_TRACK_MASK),
+ channel, pMIDIStream->d1, pMIDIStream->d2);
+ }
+#endif
+ break;
+
+ case 0xc0:
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL,"Program: %02x %02x\n",
+ pMIDIStream->status, pMIDIStream->d1); */ }
+ if (parserMode < eParserModeMute)
+ VMProgramChange(pEASData->pVoiceMgr, pSynth, channel, pMIDIStream->d1);
+ break;
+
+ case 0xd0:
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL,"ChanPres: %02x %02x\n",
+ pMIDIStream->status, pMIDIStream->d1); */ }
+ if (parserMode < eParserModeMute)
+ VMChannelPressure(pSynth, channel, pMIDIStream->d1);
+ break;
+
+ case 0xe0:
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL,"PBend: %02x %02x %02x\n",
+ pMIDIStream->status, pMIDIStream->d1, pMIDIStream->d2); */ }
+ if (parserMode < eParserModeMute)
+ VMPitchBend(pSynth, channel, pMIDIStream->d1, pMIDIStream->d2);
+ break;
+
+ default:
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL,"Unknown: %02x %02x %02x\n",
+ pMIDIStream->status, pMIDIStream->d1, pMIDIStream->d2); */ }
+ }
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * ProcessSysExMessage()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Process a SysEx character byte from the MIDI stream. Since we cannot
+ * simply wait for the next character to arrive, we are forced to save
+ * state after each character. It would be easier to parse at the file
+ * level, but then we lose the nice feature of being able to support
+ * these messages in a real-time MIDI stream.
+ *
+ * Inputs:
+ * pEASData - pointer to synthesizer instance data
+ * c - character to be processed
+ * locating - if true, the sequencer is relocating to a new position
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ * Notes:
+ * These are the SysEx messages we can receive:
+ *
+ * SysEx messages
+ * { f0 7e 7f 09 01 f7 } GM 1 On
+ * { f0 7e 7f 09 02 f7 } GM 1/2 Off
+ * { f0 7e 7f 09 03 f7 } GM 2 On
+ * { f0 7f 7f 04 01 lsb msb } Master Volume
+ * { f0 7f 7f 0b 01 ch mip [ch mip ...] f7 } SP-MIDI
+ * { f0 00 01 3a 04 01 fdbk1 fdbk2 drive wet dry f7 } Enhancer
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT ProcessSysExMessage (S_EAS_DATA *pEASData, S_SYNTH *pSynth, S_MIDI_STREAM *pMIDIStream, EAS_U8 c, EAS_INT parserMode)
+{
+
+ /* check for start byte */
+ if (c == 0xf0)
+ {
+ pMIDIStream->sysExState = eSysEx;
+ }
+ /* check for end byte */
+ else if (c == 0xf7)
+ {
+ /* if this was a MIP message, update the MIP table */
+ if ((pMIDIStream->sysExState == eSysExSPMIDIchan) && (parserMode != eParserModeMetaData))
+ VMUpdateMIPTable(pEASData->pVoiceMgr, pSynth);
+ pMIDIStream->sysExState = eSysExIgnore;
+ }
+
+ /* process SysEx message */
+ else
+ {
+ switch (pMIDIStream->sysExState)
+ {
+ case eSysEx:
+
+ /* first byte, determine message class */
+ switch (c)
+ {
+ case 0x7e:
+ pMIDIStream->sysExState = eSysExUnivNonRealTime;
+ break;
+ case 0x7f:
+ pMIDIStream->sysExState = eSysExUnivRealTime;
+ break;
+ case 0x00:
+ pMIDIStream->sysExState = eSysExMfgID1;
+ break;
+ default:
+ pMIDIStream->sysExState = eSysExIgnore;
+ break;
+ }
+ break;
+
+ /* process GM message */
+ case eSysExUnivNonRealTime:
+ if (c == 0x7f)
+ pMIDIStream->sysExState = eSysExUnivNrtTargetID;
+ else
+ pMIDIStream->sysExState = eSysExIgnore;
+ break;
+
+ case eSysExUnivNrtTargetID:
+ if (c == 0x09)
+ pMIDIStream->sysExState = eSysExGMControl;
+ else
+ pMIDIStream->sysExState = eSysExIgnore;
+ break;
+
+ case eSysExGMControl:
+ if ((c == 1) || (c == 3))
+ {
+ /* GM 1 or GM2 On, reset synth */
+ if (parserMode != eParserModeMetaData)
+ {
+ pMIDIStream->flags |= MIDI_FLAG_GM_ON;
+ VMReset(pEASData->pVoiceMgr, pSynth, EAS_FALSE);
+ VMInitMIPTable(pSynth);
+ }
+ pMIDIStream->sysExState = eSysExEOX;
+ }
+ else
+ pMIDIStream->sysExState = eSysExIgnore;
+ break;
+
+ /* Process Master Volume and SP-MIDI */
+ case eSysExUnivRealTime:
+ if (c == 0x7f)
+ pMIDIStream->sysExState = eSysExUnivRtTargetID;
+ else
+ pMIDIStream->sysExState = eSysExIgnore;
+ break;
+
+ case eSysExUnivRtTargetID:
+ if (c == 0x04)
+ pMIDIStream->sysExState = eSysExDeviceControl;
+ else if (c == 0x0b)
+ pMIDIStream->sysExState = eSysExSPMIDI;
+ else
+ pMIDIStream->sysExState = eSysExIgnore;
+ break;
+
+ /* process master volume */
+ case eSysExDeviceControl:
+ if (c == 0x01)
+ pMIDIStream->sysExState = eSysExMasterVolume;
+ else
+ pMIDIStream->sysExState = eSysExIgnore;
+ break;
+
+ case eSysExMasterVolume:
+ /* save LSB */
+ pMIDIStream->d1 = c;
+ pMIDIStream->sysExState = eSysExMasterVolLSB;
+ break;
+
+ case eSysExMasterVolLSB:
+ if (parserMode != eParserModeMetaData)
+ {
+ EAS_I32 gain = ((EAS_I32) c << 8) | ((EAS_I32) pMIDIStream->d1 << 1);
+ gain = (gain * gain) >> 15;
+ VMSetVolume(pSynth, (EAS_U16) gain);
+ }
+ pMIDIStream->sysExState = eSysExEOX;
+ break;
+
+ /* process SP-MIDI MIP message */
+ case eSysExSPMIDI:
+ if (c == 0x01)
+ {
+ /* assume all channels are muted */
+ if (parserMode != eParserModeMetaData)
+ VMInitMIPTable(pSynth);
+ pMIDIStream->d1 = 0;
+ pMIDIStream->sysExState = eSysExSPMIDIchan;
+ }
+ else
+ pMIDIStream->sysExState = eSysExIgnore;
+ break;
+
+ case eSysExSPMIDIchan:
+ if (c < NUM_SYNTH_CHANNELS)
+ {
+ pMIDIStream->d2 = c;
+ pMIDIStream->sysExState = eSysExSPMIDIMIP;
+ }
+ else
+ {
+ /* bad MIP message - unmute channels */
+ if (parserMode != eParserModeMetaData)
+ VMInitMIPTable(pSynth);
+ pMIDIStream->sysExState = eSysExIgnore;
+ }
+ break;
+
+ case eSysExSPMIDIMIP:
+ /* process MIP entry here */
+ if (parserMode != eParserModeMetaData)
+ VMSetMIPEntry(pEASData->pVoiceMgr, pSynth, pMIDIStream->d2, pMIDIStream->d1, c);
+ pMIDIStream->sysExState = eSysExSPMIDIchan;
+
+ /* if 16 channels received, update MIP table */
+ if (++pMIDIStream->d1 == NUM_SYNTH_CHANNELS)
+ {
+ if (parserMode != eParserModeMetaData)
+ VMUpdateMIPTable(pEASData->pVoiceMgr, pSynth);
+ pMIDIStream->sysExState = eSysExEOX;
+ }
+ break;
+
+ /* process Enhancer */
+ case eSysExMfgID1:
+ if (c == 0x01)
+ pMIDIStream->sysExState = eSysExMfgID1;
+ else
+ pMIDIStream->sysExState = eSysExIgnore;
+ break;
+
+ case eSysExMfgID2:
+ if (c == 0x3a)
+ pMIDIStream->sysExState = eSysExMfgID1;
+ else
+ pMIDIStream->sysExState = eSysExIgnore;
+ break;
+
+ case eSysExMfgID3:
+ if (c == 0x04)
+ pMIDIStream->sysExState = eSysExEnhancer;
+ else
+ pMIDIStream->sysExState = eSysExIgnore;
+ break;
+
+ case eSysExEnhancer:
+ if (c == 0x01)
+ pMIDIStream->sysExState = eSysExEnhancerSubID;
+ else
+ pMIDIStream->sysExState = eSysExIgnore;
+ break;
+
+ case eSysExEnhancerSubID:
+ pMIDIStream->sysExState = eSysExEnhancerFeedback1;
+ break;
+
+ case eSysExEnhancerFeedback1:
+ pMIDIStream->sysExState = eSysExEnhancerFeedback2;
+ break;
+
+ case eSysExEnhancerFeedback2:
+ pMIDIStream->sysExState = eSysExEnhancerDrive;
+ break;
+
+ case eSysExEnhancerDrive:
+ pMIDIStream->sysExState = eSysExEnhancerWet;
+ break;
+
+ case eSysExEnhancerWet:
+ pMIDIStream->sysExState = eSysExEOX;
+ break;
+
+ case eSysExEOX:
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Expected F7, received %02x\n", c); */ }
+ pMIDIStream->sysExState = eSysExIgnore;
+ break;
+
+ case eSysExIgnore:
+ break;
+
+ default:
+ pMIDIStream->sysExState = eSysExIgnore;
+ break;
+ }
+ }
+
+ if (pMIDIStream->sysExState == eSysExIgnore)
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Ignoring SysEx byte %02x\n", c); */ }
+ return EAS_SUCCESS;
+} /* end ProcessSysExMessage */
+
diff --git a/arm-hybrid-22k/lib_src/eas_midi.h b/arm-hybrid-22k/lib_src/eas_midi.h
index 37a03ee..10649a0 100644
--- a/arm-hybrid-22k/lib_src/eas_midi.h
+++ b/arm-hybrid-22k/lib_src/eas_midi.h
@@ -1,13 +1,13 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_midi.h
- *
- * Contents and purpose:
- * Prototypes for MIDI stream parsing functions
- *
- *
- * Copyright Sonic Network Inc. 2005
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_midi.h
+ *
+ * Contents and purpose:
+ * Prototypes for MIDI stream parsing functions
+ *
+ *
+ * Copyright Sonic Network Inc. 2005
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,52 +20,52 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 82 $
- * $Date: 2006-07-10 11:45:19 -0700 (Mon, 10 Jul 2006) $
- *----------------------------------------------------------------------------
-*/
-
-#ifndef _EAS_MIDI_H
-#define _EAS_MIDI_H
-
-/*----------------------------------------------------------------------------
- * EAS_InitMIDIStream()
- *----------------------------------------------------------------------------
- * Purpose:
- * Initializes the MIDI stream state for parsing.
- *
- * Inputs:
- *
- * Outputs:
- * returns EAS_RESULT (EAS_SUCCESS is OK)
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-void EAS_InitMIDIStream (S_MIDI_STREAM *pMIDIStream);
-
-/*----------------------------------------------------------------------------
- * EAS_ParseMIDIStream()
- *----------------------------------------------------------------------------
- * Purpose:
- * Parses a MIDI input stream character by character. Characters are pushed (rather than pulled)
- * so the interface works equally well for both file and stream I/O.
- *
- * Inputs:
- * c - character from MIDI stream
- *
- * Outputs:
- * returns EAS_RESULT (EAS_SUCCESS is OK)
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT EAS_ParseMIDIStream (S_EAS_DATA *pEASData, S_SYNTH *pSynth, S_MIDI_STREAM *pMIDIStream, EAS_U8 c, EAS_INT parserMode);
-
-#endif /* #define _EAS_MIDI_H */
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 82 $
+ * $Date: 2006-07-10 11:45:19 -0700 (Mon, 10 Jul 2006) $
+ *----------------------------------------------------------------------------
+*/
+
+#ifndef _EAS_MIDI_H
+#define _EAS_MIDI_H
+
+/*----------------------------------------------------------------------------
+ * EAS_InitMIDIStream()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Initializes the MIDI stream state for parsing.
+ *
+ * Inputs:
+ *
+ * Outputs:
+ * returns EAS_RESULT (EAS_SUCCESS is OK)
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+void EAS_InitMIDIStream (S_MIDI_STREAM *pMIDIStream);
+
+/*----------------------------------------------------------------------------
+ * EAS_ParseMIDIStream()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Parses a MIDI input stream character by character. Characters are pushed (rather than pulled)
+ * so the interface works equally well for both file and stream I/O.
+ *
+ * Inputs:
+ * c - character from MIDI stream
+ *
+ * Outputs:
+ * returns EAS_RESULT (EAS_SUCCESS is OK)
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_ParseMIDIStream (S_EAS_DATA *pEASData, S_SYNTH *pSynth, S_MIDI_STREAM *pMIDIStream, EAS_U8 c, EAS_INT parserMode);
+
+#endif /* #define _EAS_MIDI_H */
+
diff --git a/arm-hybrid-22k/lib_src/eas_midictrl.h b/arm-hybrid-22k/lib_src/eas_midictrl.h
index 0c4217d..46fdc4f 100644
--- a/arm-hybrid-22k/lib_src/eas_midictrl.h
+++ b/arm-hybrid-22k/lib_src/eas_midictrl.h
@@ -1,15 +1,15 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_midictrl.h
- *
- * Contents and purpose:
- * MIDI controller definitions
- *
- * This header only contains declarations that are specific
- * to this implementation.
- *
- * Copyright Sonic Network Inc. 2005
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_midictrl.h
+ *
+ * Contents and purpose:
+ * MIDI controller definitions
+ *
+ * This header only contains declarations that are specific
+ * to this implementation.
+ *
+ * Copyright Sonic Network Inc. 2005
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -22,43 +22,43 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 82 $
- * $Date: 2006-07-10 11:45:19 -0700 (Mon, 10 Jul 2006) $
- *----------------------------------------------------------------------------
-*/
-
-#ifndef _EAS_MIDICTRL_H
-#define _EAS_MIDICTRL_H
-
-/* define controller types */
-/*
- Note that these controller types are specified in base 10 (decimal)
- and not in hexadecimal. The above midi messages are specified
- in hexadecimal.
-*/
-#define MIDI_CONTROLLER_BANK_SELECT 0
-#define MIDI_CONTROLLER_BANK_SELECT_MSB 0
-#define MIDI_CONTROLLER_MOD_WHEEL 1
-#define MIDI_CONTROLLER_ENTER_DATA_MSB 6
-#define MIDI_CONTROLLER_VOLUME 7
-#define MIDI_CONTROLLER_PAN 10
-#define MIDI_CONTROLLER_EXPRESSION 11
-#define MIDI_CONTROLLER_BANK_SELECT_LSB 32
-#define MIDI_CONTROLLER_ENTER_DATA_LSB 38 /* 0x26 */
-#define MIDI_CONTROLLER_SUSTAIN_PEDAL 64
-#define MIDI_CONTROLLER_SELECT_NRPN_LSB 98
-#define MIDI_CONTROLLER_SELECT_NRPN_MSB 99
-#define MIDI_CONTROLLER_SELECT_RPN_LSB 100 /* 0x64 */
-#define MIDI_CONTROLLER_SELECT_RPN_MSB 101 /* 0x65 */
-#define MIDI_CONTROLLER_ALL_SOUND_OFF 120
-#define MIDI_CONTROLLER_RESET_CONTROLLERS 121
-#define MIDI_CONTROLLER_ALL_NOTES_OFF 123
-#define MIDI_CONTROLLER_OMNI_OFF 124
-#define MIDI_CONTROLLER_OMNI_ON 125
-#define MIDI_CONTROLLER_MONO_ON_POLY_OFF 126
-#define MIDI_CONTROLLER_POLY_ON_MONO_OFF 127
-
-#endif /* #ifndef _EAS_MIDICTRL_H */
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 82 $
+ * $Date: 2006-07-10 11:45:19 -0700 (Mon, 10 Jul 2006) $
+ *----------------------------------------------------------------------------
+*/
+
+#ifndef _EAS_MIDICTRL_H
+#define _EAS_MIDICTRL_H
+
+/* define controller types */
+/*
+ Note that these controller types are specified in base 10 (decimal)
+ and not in hexadecimal. The above midi messages are specified
+ in hexadecimal.
+*/
+#define MIDI_CONTROLLER_BANK_SELECT 0
+#define MIDI_CONTROLLER_BANK_SELECT_MSB 0
+#define MIDI_CONTROLLER_MOD_WHEEL 1
+#define MIDI_CONTROLLER_ENTER_DATA_MSB 6
+#define MIDI_CONTROLLER_VOLUME 7
+#define MIDI_CONTROLLER_PAN 10
+#define MIDI_CONTROLLER_EXPRESSION 11
+#define MIDI_CONTROLLER_BANK_SELECT_LSB 32
+#define MIDI_CONTROLLER_ENTER_DATA_LSB 38 /* 0x26 */
+#define MIDI_CONTROLLER_SUSTAIN_PEDAL 64
+#define MIDI_CONTROLLER_SELECT_NRPN_LSB 98
+#define MIDI_CONTROLLER_SELECT_NRPN_MSB 99
+#define MIDI_CONTROLLER_SELECT_RPN_LSB 100 /* 0x64 */
+#define MIDI_CONTROLLER_SELECT_RPN_MSB 101 /* 0x65 */
+#define MIDI_CONTROLLER_ALL_SOUND_OFF 120
+#define MIDI_CONTROLLER_RESET_CONTROLLERS 121
+#define MIDI_CONTROLLER_ALL_NOTES_OFF 123
+#define MIDI_CONTROLLER_OMNI_OFF 124
+#define MIDI_CONTROLLER_OMNI_ON 125
+#define MIDI_CONTROLLER_MONO_ON_POLY_OFF 126
+#define MIDI_CONTROLLER_POLY_ON_MONO_OFF 127
+
+#endif /* #ifndef _EAS_MIDICTRL_H */
diff --git a/arm-hybrid-22k/lib_src/eas_mididata.c b/arm-hybrid-22k/lib_src/eas_mididata.c
index 2ee907e..4463b7e 100644
--- a/arm-hybrid-22k/lib_src/eas_mididata.c
+++ b/arm-hybrid-22k/lib_src/eas_mididata.c
@@ -1,13 +1,13 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_mididata.c
- *
- * Contents and purpose:
- * Data module for MIDI stream interface
- *
- *
- * Copyright Sonic Network Inc. 2005
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_mididata.c
+ *
+ * Contents and purpose:
+ * Data module for MIDI stream interface
+ *
+ *
+ * Copyright Sonic Network Inc. 2005
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,15 +20,15 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 547 $
- * $Date: 2007-01-31 16:30:17 -0800 (Wed, 31 Jan 2007) $
- *----------------------------------------------------------------------------
-*/
-
-#include "eas_miditypes.h"
-
-S_INTERACTIVE_MIDI eas_MIDIData;
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 547 $
+ * $Date: 2007-01-31 16:30:17 -0800 (Wed, 31 Jan 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+#include "eas_miditypes.h"
+
+S_INTERACTIVE_MIDI eas_MIDIData;
+
diff --git a/arm-hybrid-22k/lib_src/eas_miditypes.h b/arm-hybrid-22k/lib_src/eas_miditypes.h
index 0b7f96e..015f08b 100644
--- a/arm-hybrid-22k/lib_src/eas_miditypes.h
+++ b/arm-hybrid-22k/lib_src/eas_miditypes.h
@@ -1,13 +1,13 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_miditypes.h
- *
- * Contents and purpose:
- * Contains declarations for the MIDI stream parser.
- *
- *
- * Copyright Sonic Network Inc. 2005
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_miditypes.h
+ *
+ * Contents and purpose:
+ * Contains declarations for the MIDI stream parser.
+ *
+ *
+ * Copyright Sonic Network Inc. 2005
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,119 +20,119 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 778 $
- * $Date: 2007-07-23 16:45:17 -0700 (Mon, 23 Jul 2007) $
- *----------------------------------------------------------------------------
-*/
-
-#ifndef _EAS_MIDITYPES_H
-#define _EAS_MIDITYPES_H
-
-#include "eas_data.h"
-#include "eas_parser.h"
-
-/*----------------------------------------------------------------------------
- * S_MIDI_STREAM
- *
- * Maintains parser state for the MIDI stream parser
- *
- *----------------------------------------------------------------------------
-*/
-
-typedef struct s_midi_stream_tag
-{
- EAS_BOOL8 byte3; /* flag indicates 3rd byte expected */
- EAS_BOOL8 pending; /* flag indicates more data expected */
- EAS_U8 sysExState; /* maintains the SysEx state */
- EAS_U8 runningStatus; /* last running status received */
- EAS_U8 status; /* status byte */
- EAS_U8 d1; /* first data byte */
- EAS_U8 d2; /* second data byte */
- EAS_U8 flags; /* flags - see below for definition */
-#ifdef JET_INTERFACE
- EAS_U32 jetData; /* JET data */
-#endif
-} S_MIDI_STREAM;
-
-/* flags for S_MIDI_STREAM.flags */
-#define MIDI_FLAG_GM_ON 0x01 /* GM System On message received */
-#define MIDI_FLAG_FIRST_NOTE 0x02 /* first note received */
-
-/* flags for S_MIDI_STREAM.jetFlags */
-#define MIDI_FLAGS_JET_MUTE 0x00000001 /* track is muted */
-#define MIDI_FLAGS_JET_CB 0x00000002 /* JET callback enabled */
-
-/*----------------------------------------------------------------------------
- *
- * S_SMF_STREAM
- *
- * This structure contains data required to parse an SMF stream. For SMF0 files, there
- * will be a single instance of this per file. For SMF1 files, there will be multiple instance,
- * one for each separate stream in the file.
- *
- *----------------------------------------------------------------------------
-*/
-
-typedef struct s_smf_stream_tag
-{
- EAS_FILE_HANDLE fileHandle; /* host wrapper file handle */
- EAS_U32 ticks; /* time of next event in stream */
- EAS_I32 startFilePos; /* start location of track within file */
- S_MIDI_STREAM midiStream; /* MIDI stream state */
-} S_SMF_STREAM;
-
-/*----------------------------------------------------------------------------
- *
- * S_SMF_DATA
- *
- * This structure contains the instance data required to parse an SMF stream.
- *
- *----------------------------------------------------------------------------
-*/
-
-typedef struct s_smf_data_tag
-{
-#ifdef _CHECKED_BUILD
- EAS_U32 handleCheck; /* signature check for checked build */
-#endif
- S_SMF_STREAM *streams; /* pointer to individual streams in file */
- S_SMF_STREAM *nextStream; /* pointer to next stream with event */
- S_SYNTH *pSynth; /* pointer to synth */
- EAS_FILE_HANDLE fileHandle; /* file handle */
- S_METADATA_CB metadata; /* metadata callback */
- EAS_I32 fileOffset; /* for embedded files */
- EAS_I32 time; /* current time in milliseconds/256 */
- EAS_U16 numStreams; /* actual number of streams */
- EAS_U16 tickConv; /* current MIDI tick to msec conversion */
- EAS_U16 ppqn; /* ticks per quarter note */
- EAS_U8 state; /* current state EAS_STATE_XXXX */
- EAS_U8 flags; /* flags - see definitions below */
-} S_SMF_DATA;
-
-#define SMF_FLAGS_CHASE_MODE 0x01 /* chase mode - skip to first note */
-#define SMF_FLAGS_HAS_TIME_SIG 0x02 /* time signature encountered at time 0 */
-#define SMF_FLAGS_HAS_TEMPO 0x04 /* tempo encountered at time 0 */
-#define SMF_FLAGS_HAS_GM_ON 0x08 /* GM System On encountered at time 0 */
-#define SMF_FLAGS_JET_STREAM 0x80 /* JET in use - keep strict timing */
-
-/* combo flags indicate setup bar */
-#define SMF_FLAGS_SETUP_BAR (SMF_FLAGS_HAS_TIME_SIG | SMF_FLAGS_HAS_TEMPO | SMF_FLAGS_HAS_GM_ON)
-
-/*----------------------------------------------------------------------------
- * Interactive MIDI structure
- *----------------------------------------------------------------------------
-*/
-typedef struct s_interactive_midi_tag
-{
-#ifdef _CHECKED_BUILD
- EAS_U32 handleCheck; /* signature check for checked build */
-#endif
- S_SYNTH *pSynth; /* pointer to synth */
- S_MIDI_STREAM stream; /* stream data */
-} S_INTERACTIVE_MIDI;
-
-#endif /* #ifndef _EAS_MIDITYPES_H */
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 778 $
+ * $Date: 2007-07-23 16:45:17 -0700 (Mon, 23 Jul 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+#ifndef _EAS_MIDITYPES_H
+#define _EAS_MIDITYPES_H
+
+#include "eas_data.h"
+#include "eas_parser.h"
+
+/*----------------------------------------------------------------------------
+ * S_MIDI_STREAM
+ *
+ * Maintains parser state for the MIDI stream parser
+ *
+ *----------------------------------------------------------------------------
+*/
+
+typedef struct s_midi_stream_tag
+{
+ EAS_BOOL8 byte3; /* flag indicates 3rd byte expected */
+ EAS_BOOL8 pending; /* flag indicates more data expected */
+ EAS_U8 sysExState; /* maintains the SysEx state */
+ EAS_U8 runningStatus; /* last running status received */
+ EAS_U8 status; /* status byte */
+ EAS_U8 d1; /* first data byte */
+ EAS_U8 d2; /* second data byte */
+ EAS_U8 flags; /* flags - see below for definition */
+#ifdef JET_INTERFACE
+ EAS_U32 jetData; /* JET data */
+#endif
+} S_MIDI_STREAM;
+
+/* flags for S_MIDI_STREAM.flags */
+#define MIDI_FLAG_GM_ON 0x01 /* GM System On message received */
+#define MIDI_FLAG_FIRST_NOTE 0x02 /* first note received */
+
+/* flags for S_MIDI_STREAM.jetFlags */
+#define MIDI_FLAGS_JET_MUTE 0x00000001 /* track is muted */
+#define MIDI_FLAGS_JET_CB 0x00000002 /* JET callback enabled */
+
+/*----------------------------------------------------------------------------
+ *
+ * S_SMF_STREAM
+ *
+ * This structure contains data required to parse an SMF stream. For SMF0 files, there
+ * will be a single instance of this per file. For SMF1 files, there will be multiple instance,
+ * one for each separate stream in the file.
+ *
+ *----------------------------------------------------------------------------
+*/
+
+typedef struct s_smf_stream_tag
+{
+ EAS_FILE_HANDLE fileHandle; /* host wrapper file handle */
+ EAS_U32 ticks; /* time of next event in stream */
+ EAS_I32 startFilePos; /* start location of track within file */
+ S_MIDI_STREAM midiStream; /* MIDI stream state */
+} S_SMF_STREAM;
+
+/*----------------------------------------------------------------------------
+ *
+ * S_SMF_DATA
+ *
+ * This structure contains the instance data required to parse an SMF stream.
+ *
+ *----------------------------------------------------------------------------
+*/
+
+typedef struct s_smf_data_tag
+{
+#ifdef _CHECKED_BUILD
+ EAS_U32 handleCheck; /* signature check for checked build */
+#endif
+ S_SMF_STREAM *streams; /* pointer to individual streams in file */
+ S_SMF_STREAM *nextStream; /* pointer to next stream with event */
+ S_SYNTH *pSynth; /* pointer to synth */
+ EAS_FILE_HANDLE fileHandle; /* file handle */
+ S_METADATA_CB metadata; /* metadata callback */
+ EAS_I32 fileOffset; /* for embedded files */
+ EAS_I32 time; /* current time in milliseconds/256 */
+ EAS_U16 numStreams; /* actual number of streams */
+ EAS_U16 tickConv; /* current MIDI tick to msec conversion */
+ EAS_U16 ppqn; /* ticks per quarter note */
+ EAS_U8 state; /* current state EAS_STATE_XXXX */
+ EAS_U8 flags; /* flags - see definitions below */
+} S_SMF_DATA;
+
+#define SMF_FLAGS_CHASE_MODE 0x01 /* chase mode - skip to first note */
+#define SMF_FLAGS_HAS_TIME_SIG 0x02 /* time signature encountered at time 0 */
+#define SMF_FLAGS_HAS_TEMPO 0x04 /* tempo encountered at time 0 */
+#define SMF_FLAGS_HAS_GM_ON 0x08 /* GM System On encountered at time 0 */
+#define SMF_FLAGS_JET_STREAM 0x80 /* JET in use - keep strict timing */
+
+/* combo flags indicate setup bar */
+#define SMF_FLAGS_SETUP_BAR (SMF_FLAGS_HAS_TIME_SIG | SMF_FLAGS_HAS_TEMPO | SMF_FLAGS_HAS_GM_ON)
+
+/*----------------------------------------------------------------------------
+ * Interactive MIDI structure
+ *----------------------------------------------------------------------------
+*/
+typedef struct s_interactive_midi_tag
+{
+#ifdef _CHECKED_BUILD
+ EAS_U32 handleCheck; /* signature check for checked build */
+#endif
+ S_SYNTH *pSynth; /* pointer to synth */
+ S_MIDI_STREAM stream; /* stream data */
+} S_INTERACTIVE_MIDI;
+
+#endif /* #ifndef _EAS_MIDITYPES_H */
+
diff --git a/arm-hybrid-22k/lib_src/eas_mixbuf.c b/arm-hybrid-22k/lib_src/eas_mixbuf.c
index 73e969a..db5bd02 100644
--- a/arm-hybrid-22k/lib_src/eas_mixbuf.c
+++ b/arm-hybrid-22k/lib_src/eas_mixbuf.c
@@ -1,12 +1,12 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_mixbuf.c
- *
- * Contents and purpose:
- * Contains a data allocation for synthesizer
- *
- * Copyright Sonic Network Inc. 2004
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_mixbuf.c
+ *
+ * Contents and purpose:
+ * Contains a data allocation for synthesizer
+ *
+ * Copyright Sonic Network Inc. 2004
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,18 +19,18 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 82 $
- * $Date: 2006-07-10 11:45:19 -0700 (Mon, 10 Jul 2006) $
- *----------------------------------------------------------------------------
-*/
-
-// includes
-#include "eas_data.h"
-#include "eas_mixer.h"
-
-// globals
-EAS_I32 eas_MixBuffer[BUFFER_SIZE_IN_MONO_SAMPLES * NUM_OUTPUT_CHANNELS];
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 82 $
+ * $Date: 2006-07-10 11:45:19 -0700 (Mon, 10 Jul 2006) $
+ *----------------------------------------------------------------------------
+*/
+
+// includes
+#include "eas_data.h"
+#include "eas_mixer.h"
+
+// globals
+EAS_I32 eas_MixBuffer[BUFFER_SIZE_IN_MONO_SAMPLES * NUM_OUTPUT_CHANNELS];
+
diff --git a/arm-hybrid-22k/lib_src/eas_mixer.c b/arm-hybrid-22k/lib_src/eas_mixer.c
index c4a2f9f..0a839a8 100644
--- a/arm-hybrid-22k/lib_src/eas_mixer.c
+++ b/arm-hybrid-22k/lib_src/eas_mixer.c
@@ -1,13 +1,13 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_mixer.c
- *
- * Contents and purpose:
- * This file contains the critical components of the mix engine that
- * must be optimized for best performance.
- *
- * Copyright Sonic Network Inc. 2005
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_mixer.c
+ *
+ * Contents and purpose:
+ * This file contains the critical components of the mix engine that
+ * must be optimized for best performance.
+ *
+ * Copyright Sonic Network Inc. 2005
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,445 +20,445 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 706 $
- * $Date: 2007-05-31 17:22:51 -0700 (Thu, 31 May 2007) $
- *----------------------------------------------------------------------------
-*/
-
-//3 dls: This module is in the midst of being converted from a synth
-//3 specific module to a general purpose mix engine
-
-/*------------------------------------
- * includes
- *------------------------------------
-*/
-#include "eas_data.h"
-#include "eas_host.h"
-#include "eas_math.h"
-#include "eas_mixer.h"
-#include "eas_config.h"
-#include "eas_report.h"
-
-#ifdef _MAXIMIZER_ENABLED
-EAS_I32 MaximizerProcess (EAS_VOID_PTR pInstData, EAS_I32 *pSrc, EAS_I32 *pDst, EAS_I32 numSamples);
-#endif
-
-/*------------------------------------
- * defines
- *------------------------------------
-*/
-
-/* need to boost stereo by ~3dB to compensate for the panner */
-#define STEREO_3DB_GAIN_BOOST 512
-
-/*----------------------------------------------------------------------------
- * EAS_MixEngineInit()
- *----------------------------------------------------------------------------
- * Purpose:
- * Prepares the mix engine for work, allocates buffers, locates effects modules, etc.
- *
- * Inputs:
- * pEASData - instance data
- * pInstData - pointer to variable to receive instance data handle
- *
- * Outputs:
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT EAS_MixEngineInit (S_EAS_DATA *pEASData)
-{
-
- /* check Configuration Module for mix buffer allocation */
- if (pEASData->staticMemoryModel)
- pEASData->pMixBuffer = EAS_CMEnumData(EAS_CM_MIX_BUFFER);
- else
- pEASData->pMixBuffer = EAS_HWMalloc(pEASData->hwInstData, BUFFER_SIZE_IN_MONO_SAMPLES * NUM_OUTPUT_CHANNELS * sizeof(EAS_I32));
- if (pEASData->pMixBuffer == NULL)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_FATAL, "Failed to allocate mix buffer memory\n"); */ }
- return EAS_ERROR_MALLOC_FAILED;
- }
- EAS_HWMemSet((void *)(pEASData->pMixBuffer), 0, BUFFER_SIZE_IN_MONO_SAMPLES * NUM_OUTPUT_CHANNELS * sizeof(EAS_I32));
-
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * EAS_MixEnginePrep()
- *----------------------------------------------------------------------------
- * Purpose:
- * Performs prep before synthesize a buffer of audio, such as clearing
- * audio buffers, etc.
- *
- * Inputs:
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-void EAS_MixEnginePrep (S_EAS_DATA *pEASData, EAS_I32 numSamples)
-{
-
- /* clear the mix buffer */
-#if (NUM_OUTPUT_CHANNELS == 2)
- EAS_HWMemSet(pEASData->pMixBuffer, 0, numSamples * (EAS_I32) sizeof(long) * 2);
-#else
- EAS_HWMemSet(pEASData->pMixBuffer, 0, (EAS_I32) numSamples * (EAS_I32) sizeof(long));
-#endif
-
- /* need to clear other side-chain effect buffers (chorus & reverb) */
-}
-
-/*----------------------------------------------------------------------------
- * EAS_MixEnginePost
- *----------------------------------------------------------------------------
- * Purpose:
- * This routine does the post-processing after all voices have been
- * synthesized. It calls any sweeteners and does the final mixdown to
- * the output buffer.
- *
- * Inputs:
- *
- * Outputs:
- *
- * Notes:
- *----------------------------------------------------------------------------
-*/
-void EAS_MixEnginePost (S_EAS_DATA *pEASData, EAS_I32 numSamples)
-{
- EAS_U16 gain;
-
-//3 dls: Need to restore the mix engine metrics
-
- /* calculate the gain multiplier */
-#ifdef _MAXIMIZER_ENABLED
- if (pEASData->effectsModules[EAS_MODULE_MAXIMIZER].effect)
- {
- EAS_I32 temp;
- temp = MaximizerProcess(pEASData->effectsModules[EAS_MODULE_MAXIMIZER].effectData, pEASData->pMixBuffer, pEASData->pMixBuffer, numSamples);
- temp = (temp * pEASData->masterGain) >> 15;
- if (temp > 32767)
- gain = 32767;
- else
- gain = (EAS_U16) temp;
- }
- else
- gain = (EAS_U16) pEASData->masterGain;
-#else
- gain = (EAS_U16) pEASData->masterGain;
-#endif
-
- /* Not using all the gain bits for now
- * Reduce the input to the compressor by 6dB to prevent saturation
- */
-#ifdef _COMPRESSOR_ENABLED
- if (pEASData->effectsModules[EAS_MODULE_COMPRESSOR].effectData)
- gain = gain >> 5;
- else
- gain = gain >> 4;
-#else
- gain = gain >> 4;
-#endif
-
- /* convert 32-bit mix buffer to 16-bit output format */
-#if (NUM_OUTPUT_CHANNELS == 2)
- SynthMasterGain(pEASData->pMixBuffer, pEASData->pOutputAudioBuffer, gain, (EAS_U16) ((EAS_U16) numSamples * 2));
-#else
- SynthMasterGain(pEASData->pMixBuffer, pEASData->pOutputAudioBuffer, gain, (EAS_U16) numSamples);
-#endif
-
-#ifdef _ENHANCER_ENABLED
- /* enhancer effect */
- if (pEASData->effectsModules[EAS_MODULE_ENHANCER].effectData)
- (*pEASData->effectsModules[EAS_MODULE_ENHANCER].effect->pfProcess)
- (pEASData->effectsModules[EAS_MODULE_ENHANCER].effectData,
- pEASData->pOutputAudioBuffer,
- pEASData->pOutputAudioBuffer,
- numSamples);
-#endif
-
-#ifdef _GRAPHIC_EQ_ENABLED
- /* graphic EQ effect */
- if (pEASData->effectsModules[EAS_MODULE_GRAPHIC_EQ].effectData)
- (*pEASData->effectsModules[EAS_MODULE_GRAPHIC_EQ].effect->pfProcess)
- (pEASData->effectsModules[EAS_MODULE_GRAPHIC_EQ].effectData,
- pEASData->pOutputAudioBuffer,
- pEASData->pOutputAudioBuffer,
- numSamples);
-#endif
-
-#ifdef _COMPRESSOR_ENABLED
- /* compressor effect */
- if (pEASData->effectsModules[EAS_MODULE_COMPRESSOR].effectData)
- (*pEASData->effectsModules[EAS_MODULE_COMPRESSOR].effect->pfProcess)
- (pEASData->effectsModules[EAS_MODULE_COMPRESSOR].effectData,
- pEASData->pOutputAudioBuffer,
- pEASData->pOutputAudioBuffer,
- numSamples);
-#endif
-
-#ifdef _WOW_ENABLED
- /* WOW requires a 32-bit buffer, borrow the mix buffer and
- * pass it as the destination buffer
- */
- /*lint -e{740} temporarily passing a parameter through an existing I/F */
- if (pEASData->effectsModules[EAS_MODULE_WOW].effectData)
- (*pEASData->effectsModules[EAS_MODULE_WOW].effect->pfProcess)
- (pEASData->effectsModules[EAS_MODULE_WOW].effectData,
- pEASData->pOutputAudioBuffer,
- (EAS_PCM*) pEASData->pMixBuffer,
- numSamples);
-#endif
-
-#ifdef _TONECONTROLEQ_ENABLED
- /* ToneControlEQ effect */
- if (pEASData->effectsModules[EAS_MODULE_TONECONTROLEQ].effectData)
- (*pEASData->effectsModules[EAS_MODULE_TONECONTROLEQ].effect->pfProcess)
- (pEASData->effectsModules[EAS_MODULE_TONECONTROLEQ].effectData,
- pEASData->pOutputAudioBuffer,
- pEASData->pOutputAudioBuffer,
- numSamples);
-#endif
-
-#ifdef _REVERB_ENABLED
- /* Reverb effect */
- if (pEASData->effectsModules[EAS_MODULE_REVERB].effectData)
- (*pEASData->effectsModules[EAS_MODULE_REVERB].effect->pfProcess)
- (pEASData->effectsModules[EAS_MODULE_REVERB].effectData,
- pEASData->pOutputAudioBuffer,
- pEASData->pOutputAudioBuffer,
- numSamples);
-#endif
-
-#ifdef _CHORUS_ENABLED
- /* Chorus effect */
- if (pEASData->effectsModules[EAS_MODULE_CHORUS].effectData)
- (*pEASData->effectsModules[EAS_MODULE_CHORUS].effect->pfProcess)
- (pEASData->effectsModules[EAS_MODULE_CHORUS].effectData,
- pEASData->pOutputAudioBuffer,
- pEASData->pOutputAudioBuffer,
- numSamples);
-#endif
-
-}
-
-#ifndef NATIVE_EAS_KERNEL
-/*----------------------------------------------------------------------------
- * SynthMasterGain
- *----------------------------------------------------------------------------
- * Purpose:
- * Mixes down audio from 32-bit to 16-bit target buffer
- *
- * Inputs:
- *
- * Outputs:
- *
- *----------------------------------------------------------------------------
-*/
-void SynthMasterGain (long *pInputBuffer, EAS_PCM *pOutputBuffer, EAS_U16 nGain, EAS_U16 numSamples) {
-
- /* loop through the buffer */
- while (numSamples--) {
- long s;
-
- /* read a sample from the input buffer and add some guard bits */
- s = *pInputBuffer++;
-
- /* add some guard bits */
- /*lint -e{704} <avoid divide for performance>*/
- s = s >> 7;
-
- /* apply master gain */
- s *= (long) nGain;
-
- /* shift to lower 16-bits */
- /*lint -e{704} <avoid divide for performance>*/
- s = s >> 9;
-
- /* saturate */
- s = SATURATE(s);
-
- *pOutputBuffer++ = (EAS_PCM)s;
- }
-}
-#endif
-
-/*----------------------------------------------------------------------------
- * EAS_MixEngineShutdown()
- *----------------------------------------------------------------------------
- * Purpose:
- * Shuts down effects modules and deallocates memory
- *
- * Inputs:
- * pEASData - instance data
- * pInstData - instance data handle
- *
- * Outputs:
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT EAS_MixEngineShutdown (S_EAS_DATA *pEASData)
-{
-
- /* check Configuration Module for static memory allocation */
- if (!pEASData->staticMemoryModel && (pEASData->pMixBuffer != NULL))
- EAS_HWFree(pEASData->hwInstData, pEASData->pMixBuffer);
-
- return EAS_SUCCESS;
-}
-
-#ifdef UNIFIED_MIXER
-#ifndef NATIVE_MIX_STREAM
-/*----------------------------------------------------------------------------
- * EAS_MixStream
- *----------------------------------------------------------------------------
- * Mix a 16-bit stream into a 32-bit buffer
- *
- * pInputBuffer 16-bit input buffer
- * pMixBuffer 32-bit mix buffer
- * numSamples number of samples to mix
- * gainLeft initial gain left or mono
- * gainRight initial gain right
- * gainLeft left gain increment per sample
- * gainRight right gain increment per sample
- * flags bit 0 = stereo source
- * bit 1 = stereo output
- *----------------------------------------------------------------------------
-*/
-void EAS_MixStream (EAS_PCM *pInputBuffer, EAS_I32 *pMixBuffer, EAS_I32 numSamples, EAS_I32 gainLeft, EAS_I32 gainRight, EAS_I32 gainIncLeft, EAS_I32 gainIncRight, EAS_I32 flags)
-{
- EAS_I32 temp;
- EAS_INT src, dest;
-
- /* NOTE: There are a lot of optimizations that can be done
- * in the native implementations based on register
- * availability, etc. For example, it may make sense to
- * break this down into 8 separate routines:
- *
- * 1. Mono source to mono output
- * 2. Mono source to stereo output
- * 3. Stereo source to mono output
- * 4. Stereo source to stereo output
- * 5. Mono source to mono output - no gain change
- * 6. Mono source to stereo output - no gain change
- * 7. Stereo source to mono output - no gain change
- * 8. Stereo source to stereo output - no gain change
- *
- * Other possibilities include loop unrolling, skipping
- * a gain calculation every 2 or 4 samples, etc.
- */
-
- /* no gain change, use fast loops */
- if ((gainIncLeft == 0) && (gainIncRight == 0))
- {
- switch (flags & (MIX_FLAGS_STEREO_SOURCE | MIX_FLAGS_STEREO_OUTPUT))
- {
- /* mono to mono */
- case 0:
- gainLeft >>= 15;
- for (src = dest = 0; src < numSamples; src++, dest++)
- {
-
- pMixBuffer[dest] += (pInputBuffer[src] * gainLeft) >> NUM_MIXER_GUARD_BITS;
- }
- break;
-
- /* mono to stereo */
- case MIX_FLAGS_STEREO_OUTPUT:
- gainLeft >>= 15;
- gainRight >>= 15;
- for (src = dest = 0; src < numSamples; src++, dest+=2)
- {
- pMixBuffer[dest] += (pInputBuffer[src] * gainLeft) >> NUM_MIXER_GUARD_BITS;
- pMixBuffer[dest+1] += (pInputBuffer[src] * gainRight) >> NUM_MIXER_GUARD_BITS;
- }
- break;
-
- /* stereo to mono */
- case MIX_FLAGS_STEREO_SOURCE:
- gainLeft >>= 15;
- gainRight >>= 15;
- for (src = dest = 0; src < numSamples; src+=2, dest++)
- {
- temp = (pInputBuffer[src] * gainLeft) >> NUM_MIXER_GUARD_BITS;
- temp += ((pInputBuffer[src+1] * gainRight) >> NUM_MIXER_GUARD_BITS);
- pMixBuffer[dest] += temp;
- }
- break;
-
- /* stereo to stereo */
- case MIX_FLAGS_STEREO_SOURCE | MIX_FLAGS_STEREO_OUTPUT:
- gainLeft >>= 15;
- gainRight >>= 15;
- for (src = dest = 0; src < numSamples; src+=2, dest+=2)
- {
- pMixBuffer[dest] += (pInputBuffer[src] * gainLeft) >> NUM_MIXER_GUARD_BITS;
- pMixBuffer[dest+1] += (pInputBuffer[src+1] * gainRight) >> NUM_MIXER_GUARD_BITS;
- }
- break;
- }
- }
-
- /* gain change - do gain increment */
- else
- {
- switch (flags & (MIX_FLAGS_STEREO_SOURCE | MIX_FLAGS_STEREO_OUTPUT))
- {
- /* mono to mono */
- case 0:
- for (src = dest = 0; src < numSamples; src++, dest++)
- {
- gainLeft += gainIncLeft;
- pMixBuffer[dest] += (pInputBuffer[src] * (gainLeft >> 15)) >> NUM_MIXER_GUARD_BITS;
- }
- break;
-
- /* mono to stereo */
- case MIX_FLAGS_STEREO_OUTPUT:
- for (src = dest = 0; src < numSamples; src++, dest+=2)
- {
- gainLeft += gainIncLeft;
- gainRight += gainIncRight;
- pMixBuffer[dest] += (pInputBuffer[src] * (gainLeft >> 15)) >> NUM_MIXER_GUARD_BITS;
- pMixBuffer[dest+1] += (pInputBuffer[src] * (gainRight >> 15)) >> NUM_MIXER_GUARD_BITS;
- }
- break;
-
- /* stereo to mono */
- case MIX_FLAGS_STEREO_SOURCE:
- for (src = dest = 0; src < numSamples; src+=2, dest++)
- {
- gainLeft += gainIncLeft;
- gainRight += gainIncRight;
- temp = (pInputBuffer[src] * (gainLeft >> 15)) >> NUM_MIXER_GUARD_BITS;
- temp += ((pInputBuffer[src+1] * (gainRight >> 15)) >> NUM_MIXER_GUARD_BITS);
- pMixBuffer[dest] += temp;
- }
- break;
-
- /* stereo to stereo */
- case MIX_FLAGS_STEREO_SOURCE | MIX_FLAGS_STEREO_OUTPUT:
- for (src = dest = 0; src < numSamples; src+=2, dest+=2)
- {
- gainLeft += gainIncLeft;
- gainRight += gainIncRight;
- pMixBuffer[dest] += (pInputBuffer[src] * (gainLeft >> 15)) >> NUM_MIXER_GUARD_BITS;
- pMixBuffer[dest+1] += (pInputBuffer[src+1] * (gainRight >> 15)) >> NUM_MIXER_GUARD_BITS;
- }
- break;
- }
- }
-}
-#endif
-#endif
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 706 $
+ * $Date: 2007-05-31 17:22:51 -0700 (Thu, 31 May 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+//3 dls: This module is in the midst of being converted from a synth
+//3 specific module to a general purpose mix engine
+
+/*------------------------------------
+ * includes
+ *------------------------------------
+*/
+#include "eas_data.h"
+#include "eas_host.h"
+#include "eas_math.h"
+#include "eas_mixer.h"
+#include "eas_config.h"
+#include "eas_report.h"
+
+#ifdef _MAXIMIZER_ENABLED
+EAS_I32 MaximizerProcess (EAS_VOID_PTR pInstData, EAS_I32 *pSrc, EAS_I32 *pDst, EAS_I32 numSamples);
+#endif
+
+/*------------------------------------
+ * defines
+ *------------------------------------
+*/
+
+/* need to boost stereo by ~3dB to compensate for the panner */
+#define STEREO_3DB_GAIN_BOOST 512
+
+/*----------------------------------------------------------------------------
+ * EAS_MixEngineInit()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Prepares the mix engine for work, allocates buffers, locates effects modules, etc.
+ *
+ * Inputs:
+ * pEASData - instance data
+ * pInstData - pointer to variable to receive instance data handle
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_MixEngineInit (S_EAS_DATA *pEASData)
+{
+
+ /* check Configuration Module for mix buffer allocation */
+ if (pEASData->staticMemoryModel)
+ pEASData->pMixBuffer = EAS_CMEnumData(EAS_CM_MIX_BUFFER);
+ else
+ pEASData->pMixBuffer = EAS_HWMalloc(pEASData->hwInstData, BUFFER_SIZE_IN_MONO_SAMPLES * NUM_OUTPUT_CHANNELS * sizeof(EAS_I32));
+ if (pEASData->pMixBuffer == NULL)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_FATAL, "Failed to allocate mix buffer memory\n"); */ }
+ return EAS_ERROR_MALLOC_FAILED;
+ }
+ EAS_HWMemSet((void *)(pEASData->pMixBuffer), 0, BUFFER_SIZE_IN_MONO_SAMPLES * NUM_OUTPUT_CHANNELS * sizeof(EAS_I32));
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_MixEnginePrep()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Performs prep before synthesize a buffer of audio, such as clearing
+ * audio buffers, etc.
+ *
+ * Inputs:
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+void EAS_MixEnginePrep (S_EAS_DATA *pEASData, EAS_I32 numSamples)
+{
+
+ /* clear the mix buffer */
+#if (NUM_OUTPUT_CHANNELS == 2)
+ EAS_HWMemSet(pEASData->pMixBuffer, 0, numSamples * (EAS_I32) sizeof(long) * 2);
+#else
+ EAS_HWMemSet(pEASData->pMixBuffer, 0, (EAS_I32) numSamples * (EAS_I32) sizeof(long));
+#endif
+
+ /* need to clear other side-chain effect buffers (chorus & reverb) */
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_MixEnginePost
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * This routine does the post-processing after all voices have been
+ * synthesized. It calls any sweeteners and does the final mixdown to
+ * the output buffer.
+ *
+ * Inputs:
+ *
+ * Outputs:
+ *
+ * Notes:
+ *----------------------------------------------------------------------------
+*/
+void EAS_MixEnginePost (S_EAS_DATA *pEASData, EAS_I32 numSamples)
+{
+ EAS_U16 gain;
+
+//3 dls: Need to restore the mix engine metrics
+
+ /* calculate the gain multiplier */
+#ifdef _MAXIMIZER_ENABLED
+ if (pEASData->effectsModules[EAS_MODULE_MAXIMIZER].effect)
+ {
+ EAS_I32 temp;
+ temp = MaximizerProcess(pEASData->effectsModules[EAS_MODULE_MAXIMIZER].effectData, pEASData->pMixBuffer, pEASData->pMixBuffer, numSamples);
+ temp = (temp * pEASData->masterGain) >> 15;
+ if (temp > 32767)
+ gain = 32767;
+ else
+ gain = (EAS_U16) temp;
+ }
+ else
+ gain = (EAS_U16) pEASData->masterGain;
+#else
+ gain = (EAS_U16) pEASData->masterGain;
+#endif
+
+ /* Not using all the gain bits for now
+ * Reduce the input to the compressor by 6dB to prevent saturation
+ */
+#ifdef _COMPRESSOR_ENABLED
+ if (pEASData->effectsModules[EAS_MODULE_COMPRESSOR].effectData)
+ gain = gain >> 5;
+ else
+ gain = gain >> 4;
+#else
+ gain = gain >> 4;
+#endif
+
+ /* convert 32-bit mix buffer to 16-bit output format */
+#if (NUM_OUTPUT_CHANNELS == 2)
+ SynthMasterGain(pEASData->pMixBuffer, pEASData->pOutputAudioBuffer, gain, (EAS_U16) ((EAS_U16) numSamples * 2));
+#else
+ SynthMasterGain(pEASData->pMixBuffer, pEASData->pOutputAudioBuffer, gain, (EAS_U16) numSamples);
+#endif
+
+#ifdef _ENHANCER_ENABLED
+ /* enhancer effect */
+ if (pEASData->effectsModules[EAS_MODULE_ENHANCER].effectData)
+ (*pEASData->effectsModules[EAS_MODULE_ENHANCER].effect->pfProcess)
+ (pEASData->effectsModules[EAS_MODULE_ENHANCER].effectData,
+ pEASData->pOutputAudioBuffer,
+ pEASData->pOutputAudioBuffer,
+ numSamples);
+#endif
+
+#ifdef _GRAPHIC_EQ_ENABLED
+ /* graphic EQ effect */
+ if (pEASData->effectsModules[EAS_MODULE_GRAPHIC_EQ].effectData)
+ (*pEASData->effectsModules[EAS_MODULE_GRAPHIC_EQ].effect->pfProcess)
+ (pEASData->effectsModules[EAS_MODULE_GRAPHIC_EQ].effectData,
+ pEASData->pOutputAudioBuffer,
+ pEASData->pOutputAudioBuffer,
+ numSamples);
+#endif
+
+#ifdef _COMPRESSOR_ENABLED
+ /* compressor effect */
+ if (pEASData->effectsModules[EAS_MODULE_COMPRESSOR].effectData)
+ (*pEASData->effectsModules[EAS_MODULE_COMPRESSOR].effect->pfProcess)
+ (pEASData->effectsModules[EAS_MODULE_COMPRESSOR].effectData,
+ pEASData->pOutputAudioBuffer,
+ pEASData->pOutputAudioBuffer,
+ numSamples);
+#endif
+
+#ifdef _WOW_ENABLED
+ /* WOW requires a 32-bit buffer, borrow the mix buffer and
+ * pass it as the destination buffer
+ */
+ /*lint -e{740} temporarily passing a parameter through an existing I/F */
+ if (pEASData->effectsModules[EAS_MODULE_WOW].effectData)
+ (*pEASData->effectsModules[EAS_MODULE_WOW].effect->pfProcess)
+ (pEASData->effectsModules[EAS_MODULE_WOW].effectData,
+ pEASData->pOutputAudioBuffer,
+ (EAS_PCM*) pEASData->pMixBuffer,
+ numSamples);
+#endif
+
+#ifdef _TONECONTROLEQ_ENABLED
+ /* ToneControlEQ effect */
+ if (pEASData->effectsModules[EAS_MODULE_TONECONTROLEQ].effectData)
+ (*pEASData->effectsModules[EAS_MODULE_TONECONTROLEQ].effect->pfProcess)
+ (pEASData->effectsModules[EAS_MODULE_TONECONTROLEQ].effectData,
+ pEASData->pOutputAudioBuffer,
+ pEASData->pOutputAudioBuffer,
+ numSamples);
+#endif
+
+#ifdef _REVERB_ENABLED
+ /* Reverb effect */
+ if (pEASData->effectsModules[EAS_MODULE_REVERB].effectData)
+ (*pEASData->effectsModules[EAS_MODULE_REVERB].effect->pfProcess)
+ (pEASData->effectsModules[EAS_MODULE_REVERB].effectData,
+ pEASData->pOutputAudioBuffer,
+ pEASData->pOutputAudioBuffer,
+ numSamples);
+#endif
+
+#ifdef _CHORUS_ENABLED
+ /* Chorus effect */
+ if (pEASData->effectsModules[EAS_MODULE_CHORUS].effectData)
+ (*pEASData->effectsModules[EAS_MODULE_CHORUS].effect->pfProcess)
+ (pEASData->effectsModules[EAS_MODULE_CHORUS].effectData,
+ pEASData->pOutputAudioBuffer,
+ pEASData->pOutputAudioBuffer,
+ numSamples);
+#endif
+
+}
+
+#ifndef NATIVE_EAS_KERNEL
+/*----------------------------------------------------------------------------
+ * SynthMasterGain
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Mixes down audio from 32-bit to 16-bit target buffer
+ *
+ * Inputs:
+ *
+ * Outputs:
+ *
+ *----------------------------------------------------------------------------
+*/
+void SynthMasterGain (long *pInputBuffer, EAS_PCM *pOutputBuffer, EAS_U16 nGain, EAS_U16 numSamples) {
+
+ /* loop through the buffer */
+ while (numSamples--) {
+ long s;
+
+ /* read a sample from the input buffer and add some guard bits */
+ s = *pInputBuffer++;
+
+ /* add some guard bits */
+ /*lint -e{704} <avoid divide for performance>*/
+ s = s >> 7;
+
+ /* apply master gain */
+ s *= (long) nGain;
+
+ /* shift to lower 16-bits */
+ /*lint -e{704} <avoid divide for performance>*/
+ s = s >> 9;
+
+ /* saturate */
+ s = SATURATE(s);
+
+ *pOutputBuffer++ = (EAS_PCM)s;
+ }
+}
+#endif
+
+/*----------------------------------------------------------------------------
+ * EAS_MixEngineShutdown()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Shuts down effects modules and deallocates memory
+ *
+ * Inputs:
+ * pEASData - instance data
+ * pInstData - instance data handle
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_MixEngineShutdown (S_EAS_DATA *pEASData)
+{
+
+ /* check Configuration Module for static memory allocation */
+ if (!pEASData->staticMemoryModel && (pEASData->pMixBuffer != NULL))
+ EAS_HWFree(pEASData->hwInstData, pEASData->pMixBuffer);
+
+ return EAS_SUCCESS;
+}
+
+#ifdef UNIFIED_MIXER
+#ifndef NATIVE_MIX_STREAM
+/*----------------------------------------------------------------------------
+ * EAS_MixStream
+ *----------------------------------------------------------------------------
+ * Mix a 16-bit stream into a 32-bit buffer
+ *
+ * pInputBuffer 16-bit input buffer
+ * pMixBuffer 32-bit mix buffer
+ * numSamples number of samples to mix
+ * gainLeft initial gain left or mono
+ * gainRight initial gain right
+ * gainLeft left gain increment per sample
+ * gainRight right gain increment per sample
+ * flags bit 0 = stereo source
+ * bit 1 = stereo output
+ *----------------------------------------------------------------------------
+*/
+void EAS_MixStream (EAS_PCM *pInputBuffer, EAS_I32 *pMixBuffer, EAS_I32 numSamples, EAS_I32 gainLeft, EAS_I32 gainRight, EAS_I32 gainIncLeft, EAS_I32 gainIncRight, EAS_I32 flags)
+{
+ EAS_I32 temp;
+ EAS_INT src, dest;
+
+ /* NOTE: There are a lot of optimizations that can be done
+ * in the native implementations based on register
+ * availability, etc. For example, it may make sense to
+ * break this down into 8 separate routines:
+ *
+ * 1. Mono source to mono output
+ * 2. Mono source to stereo output
+ * 3. Stereo source to mono output
+ * 4. Stereo source to stereo output
+ * 5. Mono source to mono output - no gain change
+ * 6. Mono source to stereo output - no gain change
+ * 7. Stereo source to mono output - no gain change
+ * 8. Stereo source to stereo output - no gain change
+ *
+ * Other possibilities include loop unrolling, skipping
+ * a gain calculation every 2 or 4 samples, etc.
+ */
+
+ /* no gain change, use fast loops */
+ if ((gainIncLeft == 0) && (gainIncRight == 0))
+ {
+ switch (flags & (MIX_FLAGS_STEREO_SOURCE | MIX_FLAGS_STEREO_OUTPUT))
+ {
+ /* mono to mono */
+ case 0:
+ gainLeft >>= 15;
+ for (src = dest = 0; src < numSamples; src++, dest++)
+ {
+
+ pMixBuffer[dest] += (pInputBuffer[src] * gainLeft) >> NUM_MIXER_GUARD_BITS;
+ }
+ break;
+
+ /* mono to stereo */
+ case MIX_FLAGS_STEREO_OUTPUT:
+ gainLeft >>= 15;
+ gainRight >>= 15;
+ for (src = dest = 0; src < numSamples; src++, dest+=2)
+ {
+ pMixBuffer[dest] += (pInputBuffer[src] * gainLeft) >> NUM_MIXER_GUARD_BITS;
+ pMixBuffer[dest+1] += (pInputBuffer[src] * gainRight) >> NUM_MIXER_GUARD_BITS;
+ }
+ break;
+
+ /* stereo to mono */
+ case MIX_FLAGS_STEREO_SOURCE:
+ gainLeft >>= 15;
+ gainRight >>= 15;
+ for (src = dest = 0; src < numSamples; src+=2, dest++)
+ {
+ temp = (pInputBuffer[src] * gainLeft) >> NUM_MIXER_GUARD_BITS;
+ temp += ((pInputBuffer[src+1] * gainRight) >> NUM_MIXER_GUARD_BITS);
+ pMixBuffer[dest] += temp;
+ }
+ break;
+
+ /* stereo to stereo */
+ case MIX_FLAGS_STEREO_SOURCE | MIX_FLAGS_STEREO_OUTPUT:
+ gainLeft >>= 15;
+ gainRight >>= 15;
+ for (src = dest = 0; src < numSamples; src+=2, dest+=2)
+ {
+ pMixBuffer[dest] += (pInputBuffer[src] * gainLeft) >> NUM_MIXER_GUARD_BITS;
+ pMixBuffer[dest+1] += (pInputBuffer[src+1] * gainRight) >> NUM_MIXER_GUARD_BITS;
+ }
+ break;
+ }
+ }
+
+ /* gain change - do gain increment */
+ else
+ {
+ switch (flags & (MIX_FLAGS_STEREO_SOURCE | MIX_FLAGS_STEREO_OUTPUT))
+ {
+ /* mono to mono */
+ case 0:
+ for (src = dest = 0; src < numSamples; src++, dest++)
+ {
+ gainLeft += gainIncLeft;
+ pMixBuffer[dest] += (pInputBuffer[src] * (gainLeft >> 15)) >> NUM_MIXER_GUARD_BITS;
+ }
+ break;
+
+ /* mono to stereo */
+ case MIX_FLAGS_STEREO_OUTPUT:
+ for (src = dest = 0; src < numSamples; src++, dest+=2)
+ {
+ gainLeft += gainIncLeft;
+ gainRight += gainIncRight;
+ pMixBuffer[dest] += (pInputBuffer[src] * (gainLeft >> 15)) >> NUM_MIXER_GUARD_BITS;
+ pMixBuffer[dest+1] += (pInputBuffer[src] * (gainRight >> 15)) >> NUM_MIXER_GUARD_BITS;
+ }
+ break;
+
+ /* stereo to mono */
+ case MIX_FLAGS_STEREO_SOURCE:
+ for (src = dest = 0; src < numSamples; src+=2, dest++)
+ {
+ gainLeft += gainIncLeft;
+ gainRight += gainIncRight;
+ temp = (pInputBuffer[src] * (gainLeft >> 15)) >> NUM_MIXER_GUARD_BITS;
+ temp += ((pInputBuffer[src+1] * (gainRight >> 15)) >> NUM_MIXER_GUARD_BITS);
+ pMixBuffer[dest] += temp;
+ }
+ break;
+
+ /* stereo to stereo */
+ case MIX_FLAGS_STEREO_SOURCE | MIX_FLAGS_STEREO_OUTPUT:
+ for (src = dest = 0; src < numSamples; src+=2, dest+=2)
+ {
+ gainLeft += gainIncLeft;
+ gainRight += gainIncRight;
+ pMixBuffer[dest] += (pInputBuffer[src] * (gainLeft >> 15)) >> NUM_MIXER_GUARD_BITS;
+ pMixBuffer[dest+1] += (pInputBuffer[src+1] * (gainRight >> 15)) >> NUM_MIXER_GUARD_BITS;
+ }
+ break;
+ }
+ }
+}
+#endif
+#endif
+
diff --git a/arm-hybrid-22k/lib_src/eas_mixer.h b/arm-hybrid-22k/lib_src/eas_mixer.h
index 2ba2d3d..b2eb33b 100644
--- a/arm-hybrid-22k/lib_src/eas_mixer.h
+++ b/arm-hybrid-22k/lib_src/eas_mixer.h
@@ -1,13 +1,13 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_mixer.h
- *
- * Contents and purpose:
- * This file contains the critical components of the mix engine that
- * must be optimized for best performance.
- *
- * Copyright Sonic Network Inc. 2005
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_mixer.h
+ *
+ * Contents and purpose:
+ * This file contains the critical components of the mix engine that
+ * must be optimized for best performance.
+ *
+ * Copyright Sonic Network Inc. 2005
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,118 +20,118 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 706 $
- * $Date: 2007-05-31 17:22:51 -0700 (Thu, 31 May 2007) $
- *----------------------------------------------------------------------------
-*/
-
-#ifndef _EAS_MIXER_H
-#define _EAS_MIXER_H
-
-//3 dls: This module is in the midst of being converted from a synth
-//3 specific module to a general purpose mix engine
-
-#define MIX_FLAGS_STEREO_SOURCE 1
-#define MIX_FLAGS_STEREO_OUTPUT 2
-#define NUM_MIXER_GUARD_BITS 4
-
-#include "eas_effects.h"
-
-extern void SynthMasterGain( long *pInputBuffer, EAS_PCM *pOutputBuffer, EAS_U16 nGain, EAS_U16 nNumLoopSamples);
-
-/*----------------------------------------------------------------------------
- * EAS_MixEngineInit()
- *----------------------------------------------------------------------------
- * Purpose:
- * Prepares the mix engine for work, allocates buffers, locates effects modules, etc.
- *
- * Inputs:
- * pEASData - instance data
- * pInstData - pointer to variable to receive instance data handle
- *
- * Outputs:
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT EAS_MixEngineInit (EAS_DATA_HANDLE pEASData);
-
-/*----------------------------------------------------------------------------
- * EAS_MixEnginePrep()
- *----------------------------------------------------------------------------
- * Purpose:
- * Performs prep before synthesize a buffer of audio, such as clearing
- * audio buffers, etc.
- *
- * Inputs:
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-void EAS_MixEnginePrep (EAS_DATA_HANDLE pEASData, EAS_I32 nNumSamplesToAdd);
-
-/*----------------------------------------------------------------------------
- * EAS_MixEnginePost
- *----------------------------------------------------------------------------
- * Purpose:
- * This routine does the post-processing after all voices have been
- * synthesized. It calls any sweeteners and does the final mixdown to
- * the output buffer.
- *
- * Inputs:
- *
- * Outputs:
- *
- * Notes:
- *----------------------------------------------------------------------------
-*/
-void EAS_MixEnginePost (EAS_DATA_HANDLE pEASData, EAS_I32 nNumSamplesToAdd);
-
-/*----------------------------------------------------------------------------
- * EAS_MixEngineShutdown()
- *----------------------------------------------------------------------------
- * Purpose:
- * Shuts down effects modules and deallocates memory
- *
- * Inputs:
- * pEASData - instance data
- * pInstData - instance data handle
- *
- * Outputs:
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT EAS_MixEngineShutdown (EAS_DATA_HANDLE pEASData);
-
-#ifdef UNIFIED_MIXER
-/*----------------------------------------------------------------------------
- * EAS_MixStream
- *----------------------------------------------------------------------------
- * Mix a 16-bit stream into a 32-bit buffer
- *
- * pInputBuffer 16-bit input buffer
- * pMixBuffer 32-bit mix buffer
- * numSamples number of samples to mix
- * gainLeft initial gain left or mono
- * gainRight initial gain right
- * gainLeft left gain increment per sample
- * gainRight right gain increment per sample
- * flags bit 0 = stereo source
- * bit 1 = stereo output
- *----------------------------------------------------------------------------
-*/
-void EAS_MixStream (EAS_PCM *pInputBuffer, EAS_I32 *pMixBuffer, EAS_I32 numSamples, EAS_I32 gainLeft, EAS_I32 gainRight, EAS_I32 gainIncLeft, EAS_I32 gainIncRight, EAS_I32 flags);
-#endif
-
-#endif /* #ifndef _EAS_MIXER_H */
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 706 $
+ * $Date: 2007-05-31 17:22:51 -0700 (Thu, 31 May 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+#ifndef _EAS_MIXER_H
+#define _EAS_MIXER_H
+
+//3 dls: This module is in the midst of being converted from a synth
+//3 specific module to a general purpose mix engine
+
+#define MIX_FLAGS_STEREO_SOURCE 1
+#define MIX_FLAGS_STEREO_OUTPUT 2
+#define NUM_MIXER_GUARD_BITS 4
+
+#include "eas_effects.h"
+
+extern void SynthMasterGain( long *pInputBuffer, EAS_PCM *pOutputBuffer, EAS_U16 nGain, EAS_U16 nNumLoopSamples);
+
+/*----------------------------------------------------------------------------
+ * EAS_MixEngineInit()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Prepares the mix engine for work, allocates buffers, locates effects modules, etc.
+ *
+ * Inputs:
+ * pEASData - instance data
+ * pInstData - pointer to variable to receive instance data handle
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_MixEngineInit (EAS_DATA_HANDLE pEASData);
+
+/*----------------------------------------------------------------------------
+ * EAS_MixEnginePrep()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Performs prep before synthesize a buffer of audio, such as clearing
+ * audio buffers, etc.
+ *
+ * Inputs:
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+void EAS_MixEnginePrep (EAS_DATA_HANDLE pEASData, EAS_I32 nNumSamplesToAdd);
+
+/*----------------------------------------------------------------------------
+ * EAS_MixEnginePost
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * This routine does the post-processing after all voices have been
+ * synthesized. It calls any sweeteners and does the final mixdown to
+ * the output buffer.
+ *
+ * Inputs:
+ *
+ * Outputs:
+ *
+ * Notes:
+ *----------------------------------------------------------------------------
+*/
+void EAS_MixEnginePost (EAS_DATA_HANDLE pEASData, EAS_I32 nNumSamplesToAdd);
+
+/*----------------------------------------------------------------------------
+ * EAS_MixEngineShutdown()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Shuts down effects modules and deallocates memory
+ *
+ * Inputs:
+ * pEASData - instance data
+ * pInstData - instance data handle
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_MixEngineShutdown (EAS_DATA_HANDLE pEASData);
+
+#ifdef UNIFIED_MIXER
+/*----------------------------------------------------------------------------
+ * EAS_MixStream
+ *----------------------------------------------------------------------------
+ * Mix a 16-bit stream into a 32-bit buffer
+ *
+ * pInputBuffer 16-bit input buffer
+ * pMixBuffer 32-bit mix buffer
+ * numSamples number of samples to mix
+ * gainLeft initial gain left or mono
+ * gainRight initial gain right
+ * gainLeft left gain increment per sample
+ * gainRight right gain increment per sample
+ * flags bit 0 = stereo source
+ * bit 1 = stereo output
+ *----------------------------------------------------------------------------
+*/
+void EAS_MixStream (EAS_PCM *pInputBuffer, EAS_I32 *pMixBuffer, EAS_I32 numSamples, EAS_I32 gainLeft, EAS_I32 gainRight, EAS_I32 gainIncLeft, EAS_I32 gainIncRight, EAS_I32 flags);
+#endif
+
+#endif /* #ifndef _EAS_MIXER_H */
+
diff --git a/arm-hybrid-22k/lib_src/eas_ota.c b/arm-hybrid-22k/lib_src/eas_ota.c
index fb81d62..5bc9062 100644
--- a/arm-hybrid-22k/lib_src/eas_ota.c
+++ b/arm-hybrid-22k/lib_src/eas_ota.c
@@ -1,12 +1,12 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_ota.c
- *
- * Contents and purpose:
- * OTA parser
- *
- * Copyright Sonic Network Inc. 2005
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_ota.c
+ *
+ * Contents and purpose:
+ * OTA parser
+ *
+ * Copyright Sonic Network Inc. 2005
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,1059 +19,1059 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 795 $
- * $Date: 2007-08-01 00:14:45 -0700 (Wed, 01 Aug 2007) $
- *----------------------------------------------------------------------------
-*/
-
-#include "eas_data.h"
-#include "eas_miditypes.h"
-#include "eas_parser.h"
-#include "eas_report.h"
-#include "eas_host.h"
-#include "eas_midi.h"
-#include "eas_config.h"
-#include "eas_vm_protos.h"
-#include "eas_otadata.h"
-
-/* increase gain for mono ringtones */
-#define OTA_GAIN_OFFSET 8
-
-/* file definitions */
-#define OTA_RINGTONE 0x25
-#define OTA_SOUND 0x1d
-#define OTA_UNICODE 0x22
-
-/* song type definitions */
-#define OTA_BASIC_SONG_TYPE 0x01
-#define OTA_TEMPORARY_SONG_TYPE 0x02
-
-/* instruction ID coding */
-#define OTA_PATTERN_HEADER_ID 0x00
-#define OTA_NOTE_INST_ID 0x01
-#define OTA_SCALE_INST_ID 0x02
-#define OTA_STYLE_INST_ID 0x03
-#define OTA_TEMPO_INST_ID 0x04
-#define OTA_VOLUME_INST_ID 0x05
-
-/* note durations */
-#define OTA_NORMAL_DURATION 0x00
-#define OTA_DOTTED_NOTE 0x01
-#define OTA_DOUBLE_DOTTED_NOTE 0x02
-#define OTA_TRIPLET_NOTE 0x03
-
-/* loop count value for infinite loop */
-#define OTA_INFINITE_LOOP 0x0f
-
-/* length of 32nd note in 1/256ths of a msec for 63 BPM tempo */
-#define DEFAULT_TICK_CONV 30476
-
-/* default channel and program for OTA playback */
-#define OTA_CHANNEL 0
-#define OTA_PROGRAM 80
-#define OTA_VEL_MUL 4
-#define OTA_VEL_OFS 67
-#define OTA_VEL_DEFAULT 95
-
-/* multiplier for fixed point triplet conversion */
-#define TRIPLET_MULTIPLIER 683
-#define TRIPLET_SHIFT 10
-
-/* local prototypes */
-static EAS_RESULT OTA_CheckFileType (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle, EAS_VOID_PTR *ppHandle, EAS_I32 offset);
-static EAS_RESULT OTA_Prepare (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
-static EAS_RESULT OTA_Time (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_U32 *pTime);
-static EAS_RESULT OTA_Event (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_INT parserMode);
-static EAS_RESULT OTA_State (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_STATE *pState);
-static EAS_RESULT OTA_Close (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
-static EAS_RESULT OTA_Reset (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
-static EAS_RESULT OTA_Pause (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
-static EAS_RESULT OTA_Resume (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
-static EAS_RESULT OTA_SetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value);
-static EAS_RESULT OTA_GetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue);
-static EAS_RESULT OTA_ParseHeader (S_EAS_DATA *pEASData, S_OTA_DATA* pData);
-static EAS_RESULT OTA_FetchBitField (EAS_HW_DATA_HANDLE hwInstData, S_OTA_DATA *pData, EAS_I32 numBits, EAS_U8 *pValue);
-static EAS_RESULT OTA_SavePosition (EAS_HW_DATA_HANDLE hwInstData, S_OTA_DATA *pData, S_OTA_LOC *pLoc);
-static EAS_RESULT OTA_RestorePosition (EAS_HW_DATA_HANDLE hwInstData, S_OTA_DATA *pData, S_OTA_LOC *pLoc);
-
-
-/*----------------------------------------------------------------------------
- *
- * EAS_OTA_Parser
- *
- * This structure contains the functional interface for the OTA parser
- *----------------------------------------------------------------------------
-*/
-const S_FILE_PARSER_INTERFACE EAS_OTA_Parser =
-{
- OTA_CheckFileType,
- OTA_Prepare,
- OTA_Time,
- OTA_Event,
- OTA_State,
- OTA_Close,
- OTA_Reset,
- OTA_Pause,
- OTA_Resume,
- NULL,
- OTA_SetData,
- OTA_GetData,
- NULL
-};
-
-/*----------------------------------------------------------------------------
- *
- * bpmTable
- *
- * BPM conversion table. Converts bpm values to 256ths of a millisecond for a 32nd note
- *----------------------------------------------------------------------------
-*/
-static const EAS_U32 bpmTable[32] =
-{
- 76800, 68571, 61935, 54857,
- 48000, 42667, 38400, 34286,
- 30476, 27429, 24000, 21333,
- 19200, 17143, 15360, 13714,
- 12000, 10667, 9600, 8533,
- 7680, 6737, 6000, 5408,
- 4800, 4267, 3840, 3398,
- 3024, 2685, 2400, 2133
-};
-
-/*----------------------------------------------------------------------------
- * OTA_CheckFileType()
- *----------------------------------------------------------------------------
- * Purpose:
- * Check the file type to see if we can parse it
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT OTA_CheckFileType (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle, EAS_VOID_PTR *ppHandle, EAS_I32 offset)
-{
- S_OTA_DATA* pData;
- EAS_RESULT result;
- EAS_INT cmdLen;
- EAS_INT state;
- EAS_U8 temp;
-
- /* read the first byte, should be command length */
- *ppHandle = NULL;
- if ((result = EAS_HWGetByte(pEASData->hwInstData, fileHandle, &temp)) != EAS_SUCCESS)
- return result;
-
- /* read all the commands */
- cmdLen = temp;
- state = 0;
- while (cmdLen--)
- {
-
- /* read the command, upper 7 bits */
- if ((result = EAS_HWGetByte(pEASData->hwInstData, fileHandle, &temp)) != EAS_SUCCESS)
- return result;
- temp = temp >> 1;
-
- if (state == 0)
- {
- if (temp != OTA_RINGTONE)
- break;
- state++;
- }
- else
- {
-
- if (temp == OTA_SOUND)
- {
-
- /* check for static memory allocation */
- if (pEASData->staticMemoryModel)
- pData = EAS_CMEnumData(EAS_CM_OTA_DATA);
- else
- pData = EAS_HWMalloc(pEASData->hwInstData, sizeof(S_OTA_DATA));
- if (!pData)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Malloc failed in OTA_Prepare\n"); */ }
- return EAS_ERROR_MALLOC_FAILED;
- }
- EAS_HWMemSet(pData, 0, sizeof(S_OTA_DATA));
-
- /* return a pointer to the instance data */
- pData->fileHandle = fileHandle;
- pData->fileOffset = offset;
- pData->state = EAS_STATE_OPEN;
- *ppHandle = pData;
- break;
- }
-
- if (temp != OTA_UNICODE)
- break;
- }
- }
-
- /* not recognized */
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * OTA_Prepare()
- *----------------------------------------------------------------------------
- * Purpose:
- * Prepare to parse the file. Allocates instance data (or uses static allocation for
- * static memory model).
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT OTA_Prepare (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
-{
- S_OTA_DATA* pData;
- EAS_RESULT result;
-
- /* check for valid state */
- pData = (S_OTA_DATA*) pInstData;
- if (pData->state != EAS_STATE_OPEN)
- return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
-
- /* instantiate a synthesizer */
- if ((result = VMInitMIDI(pEASData, &pData->pSynth)) != EAS_SUCCESS)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "VMInitMIDI returned %d\n", result); */ }
- return result;
- }
-
- pData->state = EAS_STATE_ERROR;
- if ((result = OTA_ParseHeader(pEASData, pData)) != EAS_SUCCESS)
- return result;
-
- pData->state = EAS_STATE_READY;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * OTA_Time()
- *----------------------------------------------------------------------------
- * Purpose:
- * Returns the time of the next event in msecs
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- * pTime - pointer to variable to hold time of next event (in msecs)
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, pEASData) common decoder interface - pEASData not used */
-static EAS_RESULT OTA_Time (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_U32 *pTime)
-{
- S_OTA_DATA *pData;
-
- pData = (S_OTA_DATA*) pInstData;
-
- /* return time in milliseconds */
- /*lint -e{704} use shift instead of division */
- *pTime = pData->time >> 8;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * OTA_Event()
- *----------------------------------------------------------------------------
- * Purpose:
- * Parse the next event in the file
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT OTA_Event (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_INT parserMode)
-{
- S_OTA_DATA* pData;
- EAS_RESULT result;
- EAS_U32 duration;
- EAS_U8 temp;
-
- pData = (S_OTA_DATA*) pInstData;
- if (pData->state >= EAS_STATE_OPEN)
- return EAS_SUCCESS;
-
- /* initialize MIDI channel when the track starts playing */
- if (pData->time == 0)
- {
- /* set program to square lead */
- if (parserMode != eParserModeMetaData)
- VMProgramChange(pEASData->pVoiceMgr, pData->pSynth, OTA_CHANNEL, OTA_PROGRAM);
-
- /* set channel volume to max */
- if (parserMode != eParserModeMetaData)
- VMControlChange(pEASData->pVoiceMgr, pData->pSynth, OTA_CHANNEL, 7, 127);
- }
-
- /* check for end of note */
- if (pData->note)
- {
- /* stop the note */
- VMStopNote(pEASData->pVoiceMgr, pData->pSynth, OTA_CHANNEL, pData->note, 0);
- pData->note = 0;
-
- /* check for rest between notes */
- if (pData->restTicks)
- {
- pData->time += (EAS_I32) pData->restTicks;
- pData->restTicks = 0;
- return EAS_SUCCESS;
- }
- }
-
- /* if not in a pattern, read the pattern header */
- while (pData->current.patternLen == 0)
- {
-
- /* check for loop - don't do infinite loops when locating */
- if (pData->loopCount && ((parserMode == eParserModePlay) || (pData->loopCount != OTA_INFINITE_LOOP)))
- {
- /* if not infinite loop, decrement loop count */
- if (pData->loopCount != OTA_INFINITE_LOOP)
- pData->loopCount--;
-
- /* back to start of pattern*/
- if ((result = OTA_RestorePosition(pEASData->hwInstData, pData, &pData->patterns[pData->currentPattern])) != EAS_SUCCESS)
- return result;
- }
-
- /* if no previous position to restore, continue forward */
- else if (pData->restore.fileOffset < 0)
- {
-
- /* check for end of song */
- if (pData->numPatterns == 0)
- {
- pData->state = EAS_STATE_STOPPING;
- VMReleaseAllVoices(pEASData->pVoiceMgr, pData->pSynth);
- return EAS_SUCCESS;
- }
-
- /* read the next pattern header */
- if ((result = OTA_FetchBitField(pEASData->hwInstData, pData, 3, &temp)) != EAS_SUCCESS)
- return result;
- if (temp != OTA_PATTERN_HEADER_ID)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Expected OTA pattern header\n"); */ }
- return EAS_ERROR_FILE_FORMAT;
- }
-
- /* get the pattern ID */
- if ((result = OTA_FetchBitField(pEASData->hwInstData, pData, 2, &pData->currentPattern)) != EAS_SUCCESS)
- return result;
-
- /* get the loop count */
- if ((result = OTA_FetchBitField(pEASData->hwInstData, pData, 4, &pData->loopCount)) != EAS_SUCCESS)
- return result;
-
- /* get the pattern length */
- if ((result = OTA_FetchBitField(pEASData->hwInstData, pData, 8, &pData->current.patternLen)) != EAS_SUCCESS)
- return result;
-
- /* if pattern definition, save the current position */
- if (pData->current.patternLen)
- {
- if ((result = OTA_SavePosition(pEASData->hwInstData, pData, &pData->patterns[pData->currentPattern])) != EAS_SUCCESS)
- return result;
- }
-
- /* if pattern length is zero, repeat a previous pattern */
- else
- {
- /* make sure it's a valid pattern */
- if (pData->patterns[pData->currentPattern].fileOffset < 0)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "OTA pattern error, invalid pattern specified\n"); */ }
- return EAS_ERROR_FILE_FORMAT;
- }
-
- /* save current position and data */
- if ((result = OTA_SavePosition(pEASData->hwInstData, pData, &pData->restore)) != EAS_SUCCESS)
- return result;
-
- /* seek to the pattern in the file */
- if ((result = OTA_RestorePosition(pEASData->hwInstData, pData, &pData->patterns[pData->currentPattern])) != EAS_SUCCESS)
- return result;
- }
-
- /* decrement pattern count */
- pData->numPatterns--;
- }
-
- /* restore previous position */
- else
- {
- if ((result = OTA_RestorePosition(pEASData->hwInstData, pData, &pData->restore)) != EAS_SUCCESS)
- return result;
- }
- }
-
- /* get the next event */
- if ((result = OTA_FetchBitField(pEASData->hwInstData, pData, 3, &temp)) != EAS_SUCCESS)
- return result;
-
- switch (temp)
- {
- case OTA_NOTE_INST_ID:
- /* fetch note value */
- if ((result = OTA_FetchBitField(pEASData->hwInstData, pData, 4, &pData->note)) != EAS_SUCCESS)
- return result;
-
- /* fetch note duration */
- if ((result = OTA_FetchBitField(pEASData->hwInstData, pData, 3, &temp)) != EAS_SUCCESS)
- return result;
- duration = pData->tick * (0x20 >> temp);
-
- /* fetch note duration modifier */
- if ((result = OTA_FetchBitField(pEASData->hwInstData, pData, 2, &temp)) != EAS_SUCCESS)
- return result;
- switch (temp)
- {
- case OTA_NORMAL_DURATION:
- break;
-
- case OTA_DOTTED_NOTE:
- duration += duration >> 1;
- break;
-
- case OTA_DOUBLE_DOTTED_NOTE:
- duration += (duration >> 1) + (duration >> 2);
- break;
-
- case OTA_TRIPLET_NOTE:
- duration = (duration * TRIPLET_MULTIPLIER) >> TRIPLET_SHIFT;
- break;
-
- default:
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Unrecognized note duration ignored\n"); */ }
- break;
- }
-
- /* check for note */
- if (pData->note)
- {
-
- /* determine note length based on style */
- switch (pData->style)
- {
- case 0:
- pData->restTicks = duration >> 4;
- break;
- case 1:
- pData->restTicks = 0;
- break;
- case 2:
- pData->restTicks = duration >> 1;
- break;
- default:
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Unrecognized note style ignored\n"); */ }
- }
-
- /* add octave */
- pData->note += pData->octave;
- if (parserMode == eParserModePlay)
- VMStartNote(pEASData->pVoiceMgr, pData->pSynth, OTA_CHANNEL, pData->note, pData->velocity);
- pData->time += (EAS_I32) duration - (EAS_I32) pData->restTicks;
- }
-
- /* this is a rest */
- else
- pData->time += (EAS_I32) duration;
- break;
-
- case OTA_SCALE_INST_ID:
- /* fetch octave */
- if ((result = OTA_FetchBitField(pEASData->hwInstData, pData, 2, &temp)) != EAS_SUCCESS)
- return result;
- pData->octave = (EAS_U8) (temp * 12 + 59);
- break;
-
- case OTA_STYLE_INST_ID:
- /* fetch note style */
- if ((result = OTA_FetchBitField(pEASData->hwInstData, pData, 2, &pData->style)) != EAS_SUCCESS)
- return result;
- break;
-
- case OTA_TEMPO_INST_ID:
- /* fetch tempo */
- if ((result = OTA_FetchBitField(pEASData->hwInstData, pData, 5, &temp)) != EAS_SUCCESS)
- return result;
- pData->tick = bpmTable[temp];
- break;
-
- case OTA_VOLUME_INST_ID:
- /* fetch volume */
- if ((result = OTA_FetchBitField(pEASData->hwInstData, pData, 4, &temp)) != EAS_SUCCESS)
- return result;
- pData->velocity = temp ? (EAS_U8) (temp * OTA_VEL_MUL + OTA_VEL_OFS) : 0;
- break;
-
- default:
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Unexpected instruction ID in OTA stream\n"); */ }
- return EAS_ERROR_FILE_FORMAT;
- }
-
- /* decrement pattern length */
- pData->current.patternLen--;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * OTA_State()
- *----------------------------------------------------------------------------
- * Purpose:
- * Returns the current state of the stream
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- * pState - pointer to variable to store state
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, pEASData) common decoder interface - pEASData not used */
-static EAS_RESULT OTA_State (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 *pState)
-{
- S_OTA_DATA* pData;
-
- /* establish pointer to instance data */
- pData = (S_OTA_DATA*) pInstData;
-
- /* if stopping, check to see if synth voices are active */
- if (pData->state == EAS_STATE_STOPPING)
- {
- if (VMActiveVoices(pData->pSynth) == 0)
- pData->state = EAS_STATE_STOPPED;
- }
-
- if (pData->state == EAS_STATE_PAUSING)
- {
- if (VMActiveVoices(pData->pSynth) == 0)
- pData->state = EAS_STATE_PAUSED;
- }
-
- /* return current state */
- *pState = pData->state;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * OTA_Close()
- *----------------------------------------------------------------------------
- * Purpose:
- * Close the file and clean up
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT OTA_Close (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
-{
- S_OTA_DATA* pData;
- EAS_RESULT result;
-
- pData = (S_OTA_DATA*) pInstData;
-
- /* close the file */
- if ((result = EAS_HWCloseFile(pEASData->hwInstData, pData->fileHandle)) != EAS_SUCCESS)
- return result;
-
- /* free the synth */
- if (pData->pSynth != NULL)
- VMMIDIShutdown(pEASData, pData->pSynth);
-
- /* if using dynamic memory, free it */
- if (!pEASData->staticMemoryModel)
- EAS_HWFree(pEASData->hwInstData, pData);
-
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * OTA_Reset()
- *----------------------------------------------------------------------------
- * Purpose:
- * Reset the sequencer. Used for locating backwards in the file.
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT OTA_Reset (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
-{
- S_OTA_DATA* pData;
- EAS_RESULT result;
-
- pData = (S_OTA_DATA*) pInstData;
-
- /* reset the synth */
- VMReset(pEASData->pVoiceMgr, pData->pSynth, EAS_TRUE);
- pData->note = 0;
-
- /* reset file position and re-parse header */
- pData->state = EAS_STATE_ERROR;
- if ((result = OTA_ParseHeader (pEASData, pData)) != EAS_SUCCESS)
- return result;
-
- pData->state = EAS_STATE_READY;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * OTA_Pause()
- *----------------------------------------------------------------------------
- * Purpose:
- * Pauses the sequencer. Mutes all voices and sets state to pause.
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT OTA_Pause (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
-{
- S_OTA_DATA *pData;
-
- /* can't pause a stopped stream */
- pData = (S_OTA_DATA*) pInstData;
- if (pData->state == EAS_STATE_STOPPED)
- return EAS_ERROR_ALREADY_STOPPED;
-
- /* mute the synthesizer */
- VMMuteAllVoices(pEASData->pVoiceMgr, pData->pSynth);
- pData->state = EAS_STATE_PAUSING;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * OTA_Resume()
- *----------------------------------------------------------------------------
- * Purpose:
- * Resume playing after a pause, sets state back to playing.
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, pEASData) common decoder interface - pEASData not used */
-static EAS_RESULT OTA_Resume (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
-{
- S_OTA_DATA *pData;
-
- /* can't resume a stopped stream */
- pData = (S_OTA_DATA*) pInstData;
- if (pData->state == EAS_STATE_STOPPED)
- return EAS_ERROR_ALREADY_STOPPED;
-
- /* nothing to do but resume playback */
- pData->state = EAS_STATE_PLAY;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * OTA_SetData()
- *----------------------------------------------------------------------------
- * Purpose:
- * Return file type
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, pEASData) common decoder interface - pEASData not used */
-static EAS_RESULT OTA_SetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value)
-{
- S_OTA_DATA *pData;
-
- pData = (S_OTA_DATA *) pInstData;
- switch (param)
- {
-
- /* set metadata callback */
- case PARSER_DATA_METADATA_CB:
- EAS_HWMemCpy(&pData->metadata, (void*) value, sizeof(S_METADATA_CB));
- break;
-
- default:
- return EAS_ERROR_INVALID_PARAMETER;
- }
-
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * OTA_GetData()
- *----------------------------------------------------------------------------
- * Purpose:
- * Return file type
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, pEASData) common decoder interface - pEASData not used */
-static EAS_RESULT OTA_GetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue)
-{
- S_OTA_DATA *pData;
-
- pData = (S_OTA_DATA*) pInstData;
- switch (param)
- {
- /* return file type as OTA */
- case PARSER_DATA_FILE_TYPE:
- *pValue = EAS_FILE_OTA;
- break;
-
-#if 0
- /* set transposition */
- case PARSER_DATA_TRANSPOSITION:
- *pValue = pData->transposition;
- break;
-#endif
-
- case PARSER_DATA_SYNTH_HANDLE:
- *pValue = (EAS_I32) pData->pSynth;
- break;
-
- case PARSER_DATA_GAIN_OFFSET:
- *pValue = OTA_GAIN_OFFSET;
- break;
-
- default:
- return EAS_ERROR_INVALID_PARAMETER;
- }
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * OTA_ParseHeader()
- *----------------------------------------------------------------------------
- * Purpose:
- * Prepare to parse the file. Allocates instance data (or uses static allocation for
- * static memory model).
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT OTA_ParseHeader (S_EAS_DATA *pEASData, S_OTA_DATA* pData)
-{
- EAS_RESULT result;
- EAS_INT i;
- EAS_INT state;
- EAS_U8 temp;
- EAS_U8 titleLen;
-
- /* initialize some data */
- pData->flags = 0;
- pData->time = 0;
- pData->tick = DEFAULT_TICK_CONV;
- pData->patterns[0].fileOffset = pData->patterns[1].fileOffset =
- pData->patterns[2].fileOffset = pData->patterns[3].fileOffset = -1;
- pData->current.bitCount = 0;
- pData->current.patternLen = 0;
- pData->loopCount = 0;
- pData->restore.fileOffset = -1;
- pData->note = 0;
- pData->restTicks = 0;
- pData->velocity = OTA_VEL_DEFAULT;
- pData->style = 0;
- pData->octave = 59;
-
- /* seek to start of data */
- if ((result = EAS_HWFileSeek(pEASData->hwInstData, pData->fileHandle, pData->fileOffset)) != EAS_SUCCESS)
- return result;
-
- /* read the first byte, should be command length */
- if ((result = EAS_HWGetByte(pEASData->hwInstData, pData->fileHandle, &temp)) != EAS_SUCCESS)
- return result;
-
- /* read all the commands */
- i = temp;
- state = 0;
- while (i--)
- {
-
- /* fetch command, always starts on byte boundary */
- pData->current.bitCount = 0;
- if ((result = OTA_FetchBitField(pEASData->hwInstData, pData, 7, &temp)) != EAS_SUCCESS)
- return result;
-
- if (state == 0)
- {
- if (temp != OTA_RINGTONE)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Expected OTA Ring Tone Programming type\n"); */ }
- return EAS_ERROR_FILE_FORMAT;
- }
- state++;
- }
- else
- {
-
- if (temp == OTA_SOUND)
- break;
-
- if (temp == OTA_UNICODE)
- pData->flags |= OTA_FLAGS_UNICODE;
- else
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Expected OTA Sound or Unicode type\n"); */ }
- return EAS_ERROR_FILE_FORMAT;
- }
- }
- }
-
- /* get song type */
- if ((result = OTA_FetchBitField(pEASData->hwInstData, pData, 3, &temp)) != EAS_SUCCESS)
- return result;
-
- /* check for basic song type */
- if (temp == OTA_BASIC_SONG_TYPE)
- {
- /* fetch title length */
- if ((result = OTA_FetchBitField(pEASData->hwInstData, pData, 4, &titleLen)) != EAS_SUCCESS)
- return result;
-
- /* if unicode, double the length */
- if (pData->flags & OTA_FLAGS_UNICODE)
- titleLen = (EAS_U8) (titleLen << 1);
-
- /* zero the metadata buffer */
- if (pData->metadata.buffer)
- EAS_HWMemSet(pData->metadata.buffer, 0, pData->metadata.bufferSize);
-
- /* read the song title */
- for (i = 0; i < titleLen; i++)
- {
- /* fetch character */
- if ((result = OTA_FetchBitField(pEASData->hwInstData, pData, 8, &temp)) != EAS_SUCCESS)
- return result;
-
- /* check for metadata callback */
- if (pData->metadata.callback)
- {
- if (i < (pData->metadata.bufferSize - 1))
- pData->metadata.buffer[i] = (char) temp;
- }
- }
-
- /* if host has registered callback, call it now */
- if (pData->metadata.callback)
- (*pData->metadata.callback)(EAS_METADATA_TITLE, pData->metadata.buffer, pData->metadata.pUserData);
- }
-
- /* must be temporary song */
- else if (temp != OTA_TEMPORARY_SONG_TYPE)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Expected OTA basic or temporary song type\n"); */ }
- return EAS_ERROR_FILE_FORMAT;
- }
-
- /* get the song length */
- if ((result = OTA_FetchBitField(pEASData->hwInstData, pData, 8, &pData->numPatterns)) != EAS_SUCCESS)
- return result;
-
- /* sanity check */
- if (pData->numPatterns == 0)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "OTA number of patterns is zero\n"); */ }
- return EAS_ERROR_FILE_FORMAT;
- }
-
- /* at start of first pattern */
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * OTA_FetchBitField()
- *----------------------------------------------------------------------------
- * Purpose:
- * Fetch a specified number of bits from the input stream
- *
- * Inputs:
- *
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT OTA_FetchBitField (EAS_HW_DATA_HANDLE hwInstData, S_OTA_DATA *pData, EAS_I32 numBits, EAS_U8 *pValue)
-{
- EAS_RESULT result;
- EAS_I32 bitsLeft;
- EAS_U8 value;
-
- value = 0;
-
- /* do we have enough bits? */
- bitsLeft = pData->current.bitCount - numBits;
-
- /* not enough bits, assemble them from 2 characters */
- if (bitsLeft < 0)
- {
- /* grab the remaining bits from the previous byte */
- if (pData->current.bitCount)
- /*lint -e{504,734} this is a legitimate shift operation */
- value = pData->current.dataByte << -bitsLeft;
-
- /* read the next byte */
- if ((result = EAS_HWGetByte(hwInstData, pData->fileHandle, &pData->current.dataByte)) != EAS_SUCCESS)
- return result;
- bitsLeft += 8;
- }
-
- /* more bits than needed? */
- if (bitsLeft > 0)
- {
- value |= pData->current.dataByte >> bitsLeft;
- pData->current.bitCount = (EAS_U8) bitsLeft;
- pData->current.dataByte = pData->current.dataByte & (0xff >> (8 - bitsLeft));
- }
-
- /* exactly the right number of bits */
- else
- {
- value |= pData->current.dataByte;
- pData->current.bitCount = 0;
- }
-
- *pValue = value;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * OTA_SavePosition()
- *----------------------------------------------------------------------------
- * Purpose:
- *
- *
- * Inputs:
- *
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT OTA_SavePosition (EAS_HW_DATA_HANDLE hwInstData, S_OTA_DATA *pData, S_OTA_LOC *pLoc)
-{
- EAS_HWMemCpy(pLoc, &pData->current, sizeof(S_OTA_LOC));
- return EAS_HWFilePos(hwInstData, pData->fileHandle, &pLoc->fileOffset);
-}
-
-/*----------------------------------------------------------------------------
- * OTA_RestorePosition()
- *----------------------------------------------------------------------------
- * Purpose:
- *
- *
- * Inputs:
- *
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT OTA_RestorePosition (EAS_HW_DATA_HANDLE hwInstData, S_OTA_DATA *pData, S_OTA_LOC *pLoc)
-{
- EAS_HWMemCpy(&pData->current, pLoc, sizeof(S_OTA_LOC));
- pData->restore.fileOffset = -1;
- return EAS_HWFileSeek(hwInstData, pData->fileHandle, pLoc->fileOffset);
-}
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 795 $
+ * $Date: 2007-08-01 00:14:45 -0700 (Wed, 01 Aug 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+#include "eas_data.h"
+#include "eas_miditypes.h"
+#include "eas_parser.h"
+#include "eas_report.h"
+#include "eas_host.h"
+#include "eas_midi.h"
+#include "eas_config.h"
+#include "eas_vm_protos.h"
+#include "eas_otadata.h"
+
+/* increase gain for mono ringtones */
+#define OTA_GAIN_OFFSET 8
+
+/* file definitions */
+#define OTA_RINGTONE 0x25
+#define OTA_SOUND 0x1d
+#define OTA_UNICODE 0x22
+
+/* song type definitions */
+#define OTA_BASIC_SONG_TYPE 0x01
+#define OTA_TEMPORARY_SONG_TYPE 0x02
+
+/* instruction ID coding */
+#define OTA_PATTERN_HEADER_ID 0x00
+#define OTA_NOTE_INST_ID 0x01
+#define OTA_SCALE_INST_ID 0x02
+#define OTA_STYLE_INST_ID 0x03
+#define OTA_TEMPO_INST_ID 0x04
+#define OTA_VOLUME_INST_ID 0x05
+
+/* note durations */
+#define OTA_NORMAL_DURATION 0x00
+#define OTA_DOTTED_NOTE 0x01
+#define OTA_DOUBLE_DOTTED_NOTE 0x02
+#define OTA_TRIPLET_NOTE 0x03
+
+/* loop count value for infinite loop */
+#define OTA_INFINITE_LOOP 0x0f
+
+/* length of 32nd note in 1/256ths of a msec for 63 BPM tempo */
+#define DEFAULT_TICK_CONV 30476
+
+/* default channel and program for OTA playback */
+#define OTA_CHANNEL 0
+#define OTA_PROGRAM 80
+#define OTA_VEL_MUL 4
+#define OTA_VEL_OFS 67
+#define OTA_VEL_DEFAULT 95
+
+/* multiplier for fixed point triplet conversion */
+#define TRIPLET_MULTIPLIER 683
+#define TRIPLET_SHIFT 10
+
+/* local prototypes */
+static EAS_RESULT OTA_CheckFileType (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle, EAS_VOID_PTR *ppHandle, EAS_I32 offset);
+static EAS_RESULT OTA_Prepare (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
+static EAS_RESULT OTA_Time (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_U32 *pTime);
+static EAS_RESULT OTA_Event (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_INT parserMode);
+static EAS_RESULT OTA_State (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_STATE *pState);
+static EAS_RESULT OTA_Close (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
+static EAS_RESULT OTA_Reset (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
+static EAS_RESULT OTA_Pause (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
+static EAS_RESULT OTA_Resume (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
+static EAS_RESULT OTA_SetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value);
+static EAS_RESULT OTA_GetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue);
+static EAS_RESULT OTA_ParseHeader (S_EAS_DATA *pEASData, S_OTA_DATA* pData);
+static EAS_RESULT OTA_FetchBitField (EAS_HW_DATA_HANDLE hwInstData, S_OTA_DATA *pData, EAS_I32 numBits, EAS_U8 *pValue);
+static EAS_RESULT OTA_SavePosition (EAS_HW_DATA_HANDLE hwInstData, S_OTA_DATA *pData, S_OTA_LOC *pLoc);
+static EAS_RESULT OTA_RestorePosition (EAS_HW_DATA_HANDLE hwInstData, S_OTA_DATA *pData, S_OTA_LOC *pLoc);
+
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_OTA_Parser
+ *
+ * This structure contains the functional interface for the OTA parser
+ *----------------------------------------------------------------------------
+*/
+const S_FILE_PARSER_INTERFACE EAS_OTA_Parser =
+{
+ OTA_CheckFileType,
+ OTA_Prepare,
+ OTA_Time,
+ OTA_Event,
+ OTA_State,
+ OTA_Close,
+ OTA_Reset,
+ OTA_Pause,
+ OTA_Resume,
+ NULL,
+ OTA_SetData,
+ OTA_GetData,
+ NULL
+};
+
+/*----------------------------------------------------------------------------
+ *
+ * bpmTable
+ *
+ * BPM conversion table. Converts bpm values to 256ths of a millisecond for a 32nd note
+ *----------------------------------------------------------------------------
+*/
+static const EAS_U32 bpmTable[32] =
+{
+ 76800, 68571, 61935, 54857,
+ 48000, 42667, 38400, 34286,
+ 30476, 27429, 24000, 21333,
+ 19200, 17143, 15360, 13714,
+ 12000, 10667, 9600, 8533,
+ 7680, 6737, 6000, 5408,
+ 4800, 4267, 3840, 3398,
+ 3024, 2685, 2400, 2133
+};
+
+/*----------------------------------------------------------------------------
+ * OTA_CheckFileType()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Check the file type to see if we can parse it
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT OTA_CheckFileType (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle, EAS_VOID_PTR *ppHandle, EAS_I32 offset)
+{
+ S_OTA_DATA* pData;
+ EAS_RESULT result;
+ EAS_INT cmdLen;
+ EAS_INT state;
+ EAS_U8 temp;
+
+ /* read the first byte, should be command length */
+ *ppHandle = NULL;
+ if ((result = EAS_HWGetByte(pEASData->hwInstData, fileHandle, &temp)) != EAS_SUCCESS)
+ return result;
+
+ /* read all the commands */
+ cmdLen = temp;
+ state = 0;
+ while (cmdLen--)
+ {
+
+ /* read the command, upper 7 bits */
+ if ((result = EAS_HWGetByte(pEASData->hwInstData, fileHandle, &temp)) != EAS_SUCCESS)
+ return result;
+ temp = temp >> 1;
+
+ if (state == 0)
+ {
+ if (temp != OTA_RINGTONE)
+ break;
+ state++;
+ }
+ else
+ {
+
+ if (temp == OTA_SOUND)
+ {
+
+ /* check for static memory allocation */
+ if (pEASData->staticMemoryModel)
+ pData = EAS_CMEnumData(EAS_CM_OTA_DATA);
+ else
+ pData = EAS_HWMalloc(pEASData->hwInstData, sizeof(S_OTA_DATA));
+ if (!pData)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Malloc failed in OTA_Prepare\n"); */ }
+ return EAS_ERROR_MALLOC_FAILED;
+ }
+ EAS_HWMemSet(pData, 0, sizeof(S_OTA_DATA));
+
+ /* return a pointer to the instance data */
+ pData->fileHandle = fileHandle;
+ pData->fileOffset = offset;
+ pData->state = EAS_STATE_OPEN;
+ *ppHandle = pData;
+ break;
+ }
+
+ if (temp != OTA_UNICODE)
+ break;
+ }
+ }
+
+ /* not recognized */
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * OTA_Prepare()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Prepare to parse the file. Allocates instance data (or uses static allocation for
+ * static memory model).
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT OTA_Prepare (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
+{
+ S_OTA_DATA* pData;
+ EAS_RESULT result;
+
+ /* check for valid state */
+ pData = (S_OTA_DATA*) pInstData;
+ if (pData->state != EAS_STATE_OPEN)
+ return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
+
+ /* instantiate a synthesizer */
+ if ((result = VMInitMIDI(pEASData, &pData->pSynth)) != EAS_SUCCESS)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "VMInitMIDI returned %d\n", result); */ }
+ return result;
+ }
+
+ pData->state = EAS_STATE_ERROR;
+ if ((result = OTA_ParseHeader(pEASData, pData)) != EAS_SUCCESS)
+ return result;
+
+ pData->state = EAS_STATE_READY;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * OTA_Time()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Returns the time of the next event in msecs
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ * pTime - pointer to variable to hold time of next event (in msecs)
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pEASData) common decoder interface - pEASData not used */
+static EAS_RESULT OTA_Time (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_U32 *pTime)
+{
+ S_OTA_DATA *pData;
+
+ pData = (S_OTA_DATA*) pInstData;
+
+ /* return time in milliseconds */
+ /*lint -e{704} use shift instead of division */
+ *pTime = pData->time >> 8;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * OTA_Event()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Parse the next event in the file
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT OTA_Event (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_INT parserMode)
+{
+ S_OTA_DATA* pData;
+ EAS_RESULT result;
+ EAS_U32 duration;
+ EAS_U8 temp;
+
+ pData = (S_OTA_DATA*) pInstData;
+ if (pData->state >= EAS_STATE_OPEN)
+ return EAS_SUCCESS;
+
+ /* initialize MIDI channel when the track starts playing */
+ if (pData->time == 0)
+ {
+ /* set program to square lead */
+ if (parserMode != eParserModeMetaData)
+ VMProgramChange(pEASData->pVoiceMgr, pData->pSynth, OTA_CHANNEL, OTA_PROGRAM);
+
+ /* set channel volume to max */
+ if (parserMode != eParserModeMetaData)
+ VMControlChange(pEASData->pVoiceMgr, pData->pSynth, OTA_CHANNEL, 7, 127);
+ }
+
+ /* check for end of note */
+ if (pData->note)
+ {
+ /* stop the note */
+ VMStopNote(pEASData->pVoiceMgr, pData->pSynth, OTA_CHANNEL, pData->note, 0);
+ pData->note = 0;
+
+ /* check for rest between notes */
+ if (pData->restTicks)
+ {
+ pData->time += (EAS_I32) pData->restTicks;
+ pData->restTicks = 0;
+ return EAS_SUCCESS;
+ }
+ }
+
+ /* if not in a pattern, read the pattern header */
+ while (pData->current.patternLen == 0)
+ {
+
+ /* check for loop - don't do infinite loops when locating */
+ if (pData->loopCount && ((parserMode == eParserModePlay) || (pData->loopCount != OTA_INFINITE_LOOP)))
+ {
+ /* if not infinite loop, decrement loop count */
+ if (pData->loopCount != OTA_INFINITE_LOOP)
+ pData->loopCount--;
+
+ /* back to start of pattern*/
+ if ((result = OTA_RestorePosition(pEASData->hwInstData, pData, &pData->patterns[pData->currentPattern])) != EAS_SUCCESS)
+ return result;
+ }
+
+ /* if no previous position to restore, continue forward */
+ else if (pData->restore.fileOffset < 0)
+ {
+
+ /* check for end of song */
+ if (pData->numPatterns == 0)
+ {
+ pData->state = EAS_STATE_STOPPING;
+ VMReleaseAllVoices(pEASData->pVoiceMgr, pData->pSynth);
+ return EAS_SUCCESS;
+ }
+
+ /* read the next pattern header */
+ if ((result = OTA_FetchBitField(pEASData->hwInstData, pData, 3, &temp)) != EAS_SUCCESS)
+ return result;
+ if (temp != OTA_PATTERN_HEADER_ID)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Expected OTA pattern header\n"); */ }
+ return EAS_ERROR_FILE_FORMAT;
+ }
+
+ /* get the pattern ID */
+ if ((result = OTA_FetchBitField(pEASData->hwInstData, pData, 2, &pData->currentPattern)) != EAS_SUCCESS)
+ return result;
+
+ /* get the loop count */
+ if ((result = OTA_FetchBitField(pEASData->hwInstData, pData, 4, &pData->loopCount)) != EAS_SUCCESS)
+ return result;
+
+ /* get the pattern length */
+ if ((result = OTA_FetchBitField(pEASData->hwInstData, pData, 8, &pData->current.patternLen)) != EAS_SUCCESS)
+ return result;
+
+ /* if pattern definition, save the current position */
+ if (pData->current.patternLen)
+ {
+ if ((result = OTA_SavePosition(pEASData->hwInstData, pData, &pData->patterns[pData->currentPattern])) != EAS_SUCCESS)
+ return result;
+ }
+
+ /* if pattern length is zero, repeat a previous pattern */
+ else
+ {
+ /* make sure it's a valid pattern */
+ if (pData->patterns[pData->currentPattern].fileOffset < 0)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "OTA pattern error, invalid pattern specified\n"); */ }
+ return EAS_ERROR_FILE_FORMAT;
+ }
+
+ /* save current position and data */
+ if ((result = OTA_SavePosition(pEASData->hwInstData, pData, &pData->restore)) != EAS_SUCCESS)
+ return result;
+
+ /* seek to the pattern in the file */
+ if ((result = OTA_RestorePosition(pEASData->hwInstData, pData, &pData->patterns[pData->currentPattern])) != EAS_SUCCESS)
+ return result;
+ }
+
+ /* decrement pattern count */
+ pData->numPatterns--;
+ }
+
+ /* restore previous position */
+ else
+ {
+ if ((result = OTA_RestorePosition(pEASData->hwInstData, pData, &pData->restore)) != EAS_SUCCESS)
+ return result;
+ }
+ }
+
+ /* get the next event */
+ if ((result = OTA_FetchBitField(pEASData->hwInstData, pData, 3, &temp)) != EAS_SUCCESS)
+ return result;
+
+ switch (temp)
+ {
+ case OTA_NOTE_INST_ID:
+ /* fetch note value */
+ if ((result = OTA_FetchBitField(pEASData->hwInstData, pData, 4, &pData->note)) != EAS_SUCCESS)
+ return result;
+
+ /* fetch note duration */
+ if ((result = OTA_FetchBitField(pEASData->hwInstData, pData, 3, &temp)) != EAS_SUCCESS)
+ return result;
+ duration = pData->tick * (0x20 >> temp);
+
+ /* fetch note duration modifier */
+ if ((result = OTA_FetchBitField(pEASData->hwInstData, pData, 2, &temp)) != EAS_SUCCESS)
+ return result;
+ switch (temp)
+ {
+ case OTA_NORMAL_DURATION:
+ break;
+
+ case OTA_DOTTED_NOTE:
+ duration += duration >> 1;
+ break;
+
+ case OTA_DOUBLE_DOTTED_NOTE:
+ duration += (duration >> 1) + (duration >> 2);
+ break;
+
+ case OTA_TRIPLET_NOTE:
+ duration = (duration * TRIPLET_MULTIPLIER) >> TRIPLET_SHIFT;
+ break;
+
+ default:
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Unrecognized note duration ignored\n"); */ }
+ break;
+ }
+
+ /* check for note */
+ if (pData->note)
+ {
+
+ /* determine note length based on style */
+ switch (pData->style)
+ {
+ case 0:
+ pData->restTicks = duration >> 4;
+ break;
+ case 1:
+ pData->restTicks = 0;
+ break;
+ case 2:
+ pData->restTicks = duration >> 1;
+ break;
+ default:
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Unrecognized note style ignored\n"); */ }
+ }
+
+ /* add octave */
+ pData->note += pData->octave;
+ if (parserMode == eParserModePlay)
+ VMStartNote(pEASData->pVoiceMgr, pData->pSynth, OTA_CHANNEL, pData->note, pData->velocity);
+ pData->time += (EAS_I32) duration - (EAS_I32) pData->restTicks;
+ }
+
+ /* this is a rest */
+ else
+ pData->time += (EAS_I32) duration;
+ break;
+
+ case OTA_SCALE_INST_ID:
+ /* fetch octave */
+ if ((result = OTA_FetchBitField(pEASData->hwInstData, pData, 2, &temp)) != EAS_SUCCESS)
+ return result;
+ pData->octave = (EAS_U8) (temp * 12 + 59);
+ break;
+
+ case OTA_STYLE_INST_ID:
+ /* fetch note style */
+ if ((result = OTA_FetchBitField(pEASData->hwInstData, pData, 2, &pData->style)) != EAS_SUCCESS)
+ return result;
+ break;
+
+ case OTA_TEMPO_INST_ID:
+ /* fetch tempo */
+ if ((result = OTA_FetchBitField(pEASData->hwInstData, pData, 5, &temp)) != EAS_SUCCESS)
+ return result;
+ pData->tick = bpmTable[temp];
+ break;
+
+ case OTA_VOLUME_INST_ID:
+ /* fetch volume */
+ if ((result = OTA_FetchBitField(pEASData->hwInstData, pData, 4, &temp)) != EAS_SUCCESS)
+ return result;
+ pData->velocity = temp ? (EAS_U8) (temp * OTA_VEL_MUL + OTA_VEL_OFS) : 0;
+ break;
+
+ default:
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Unexpected instruction ID in OTA stream\n"); */ }
+ return EAS_ERROR_FILE_FORMAT;
+ }
+
+ /* decrement pattern length */
+ pData->current.patternLen--;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * OTA_State()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Returns the current state of the stream
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ * pState - pointer to variable to store state
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pEASData) common decoder interface - pEASData not used */
+static EAS_RESULT OTA_State (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 *pState)
+{
+ S_OTA_DATA* pData;
+
+ /* establish pointer to instance data */
+ pData = (S_OTA_DATA*) pInstData;
+
+ /* if stopping, check to see if synth voices are active */
+ if (pData->state == EAS_STATE_STOPPING)
+ {
+ if (VMActiveVoices(pData->pSynth) == 0)
+ pData->state = EAS_STATE_STOPPED;
+ }
+
+ if (pData->state == EAS_STATE_PAUSING)
+ {
+ if (VMActiveVoices(pData->pSynth) == 0)
+ pData->state = EAS_STATE_PAUSED;
+ }
+
+ /* return current state */
+ *pState = pData->state;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * OTA_Close()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Close the file and clean up
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT OTA_Close (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
+{
+ S_OTA_DATA* pData;
+ EAS_RESULT result;
+
+ pData = (S_OTA_DATA*) pInstData;
+
+ /* close the file */
+ if ((result = EAS_HWCloseFile(pEASData->hwInstData, pData->fileHandle)) != EAS_SUCCESS)
+ return result;
+
+ /* free the synth */
+ if (pData->pSynth != NULL)
+ VMMIDIShutdown(pEASData, pData->pSynth);
+
+ /* if using dynamic memory, free it */
+ if (!pEASData->staticMemoryModel)
+ EAS_HWFree(pEASData->hwInstData, pData);
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * OTA_Reset()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Reset the sequencer. Used for locating backwards in the file.
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT OTA_Reset (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
+{
+ S_OTA_DATA* pData;
+ EAS_RESULT result;
+
+ pData = (S_OTA_DATA*) pInstData;
+
+ /* reset the synth */
+ VMReset(pEASData->pVoiceMgr, pData->pSynth, EAS_TRUE);
+ pData->note = 0;
+
+ /* reset file position and re-parse header */
+ pData->state = EAS_STATE_ERROR;
+ if ((result = OTA_ParseHeader (pEASData, pData)) != EAS_SUCCESS)
+ return result;
+
+ pData->state = EAS_STATE_READY;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * OTA_Pause()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Pauses the sequencer. Mutes all voices and sets state to pause.
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT OTA_Pause (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
+{
+ S_OTA_DATA *pData;
+
+ /* can't pause a stopped stream */
+ pData = (S_OTA_DATA*) pInstData;
+ if (pData->state == EAS_STATE_STOPPED)
+ return EAS_ERROR_ALREADY_STOPPED;
+
+ /* mute the synthesizer */
+ VMMuteAllVoices(pEASData->pVoiceMgr, pData->pSynth);
+ pData->state = EAS_STATE_PAUSING;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * OTA_Resume()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Resume playing after a pause, sets state back to playing.
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pEASData) common decoder interface - pEASData not used */
+static EAS_RESULT OTA_Resume (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
+{
+ S_OTA_DATA *pData;
+
+ /* can't resume a stopped stream */
+ pData = (S_OTA_DATA*) pInstData;
+ if (pData->state == EAS_STATE_STOPPED)
+ return EAS_ERROR_ALREADY_STOPPED;
+
+ /* nothing to do but resume playback */
+ pData->state = EAS_STATE_PLAY;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * OTA_SetData()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Return file type
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pEASData) common decoder interface - pEASData not used */
+static EAS_RESULT OTA_SetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value)
+{
+ S_OTA_DATA *pData;
+
+ pData = (S_OTA_DATA *) pInstData;
+ switch (param)
+ {
+
+ /* set metadata callback */
+ case PARSER_DATA_METADATA_CB:
+ EAS_HWMemCpy(&pData->metadata, (void*) value, sizeof(S_METADATA_CB));
+ break;
+
+ default:
+ return EAS_ERROR_INVALID_PARAMETER;
+ }
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * OTA_GetData()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Return file type
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pEASData) common decoder interface - pEASData not used */
+static EAS_RESULT OTA_GetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue)
+{
+ S_OTA_DATA *pData;
+
+ pData = (S_OTA_DATA*) pInstData;
+ switch (param)
+ {
+ /* return file type as OTA */
+ case PARSER_DATA_FILE_TYPE:
+ *pValue = EAS_FILE_OTA;
+ break;
+
+#if 0
+ /* set transposition */
+ case PARSER_DATA_TRANSPOSITION:
+ *pValue = pData->transposition;
+ break;
+#endif
+
+ case PARSER_DATA_SYNTH_HANDLE:
+ *pValue = (EAS_I32) pData->pSynth;
+ break;
+
+ case PARSER_DATA_GAIN_OFFSET:
+ *pValue = OTA_GAIN_OFFSET;
+ break;
+
+ default:
+ return EAS_ERROR_INVALID_PARAMETER;
+ }
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * OTA_ParseHeader()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Prepare to parse the file. Allocates instance data (or uses static allocation for
+ * static memory model).
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT OTA_ParseHeader (S_EAS_DATA *pEASData, S_OTA_DATA* pData)
+{
+ EAS_RESULT result;
+ EAS_INT i;
+ EAS_INT state;
+ EAS_U8 temp;
+ EAS_U8 titleLen;
+
+ /* initialize some data */
+ pData->flags = 0;
+ pData->time = 0;
+ pData->tick = DEFAULT_TICK_CONV;
+ pData->patterns[0].fileOffset = pData->patterns[1].fileOffset =
+ pData->patterns[2].fileOffset = pData->patterns[3].fileOffset = -1;
+ pData->current.bitCount = 0;
+ pData->current.patternLen = 0;
+ pData->loopCount = 0;
+ pData->restore.fileOffset = -1;
+ pData->note = 0;
+ pData->restTicks = 0;
+ pData->velocity = OTA_VEL_DEFAULT;
+ pData->style = 0;
+ pData->octave = 59;
+
+ /* seek to start of data */
+ if ((result = EAS_HWFileSeek(pEASData->hwInstData, pData->fileHandle, pData->fileOffset)) != EAS_SUCCESS)
+ return result;
+
+ /* read the first byte, should be command length */
+ if ((result = EAS_HWGetByte(pEASData->hwInstData, pData->fileHandle, &temp)) != EAS_SUCCESS)
+ return result;
+
+ /* read all the commands */
+ i = temp;
+ state = 0;
+ while (i--)
+ {
+
+ /* fetch command, always starts on byte boundary */
+ pData->current.bitCount = 0;
+ if ((result = OTA_FetchBitField(pEASData->hwInstData, pData, 7, &temp)) != EAS_SUCCESS)
+ return result;
+
+ if (state == 0)
+ {
+ if (temp != OTA_RINGTONE)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Expected OTA Ring Tone Programming type\n"); */ }
+ return EAS_ERROR_FILE_FORMAT;
+ }
+ state++;
+ }
+ else
+ {
+
+ if (temp == OTA_SOUND)
+ break;
+
+ if (temp == OTA_UNICODE)
+ pData->flags |= OTA_FLAGS_UNICODE;
+ else
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Expected OTA Sound or Unicode type\n"); */ }
+ return EAS_ERROR_FILE_FORMAT;
+ }
+ }
+ }
+
+ /* get song type */
+ if ((result = OTA_FetchBitField(pEASData->hwInstData, pData, 3, &temp)) != EAS_SUCCESS)
+ return result;
+
+ /* check for basic song type */
+ if (temp == OTA_BASIC_SONG_TYPE)
+ {
+ /* fetch title length */
+ if ((result = OTA_FetchBitField(pEASData->hwInstData, pData, 4, &titleLen)) != EAS_SUCCESS)
+ return result;
+
+ /* if unicode, double the length */
+ if (pData->flags & OTA_FLAGS_UNICODE)
+ titleLen = (EAS_U8) (titleLen << 1);
+
+ /* zero the metadata buffer */
+ if (pData->metadata.buffer)
+ EAS_HWMemSet(pData->metadata.buffer, 0, pData->metadata.bufferSize);
+
+ /* read the song title */
+ for (i = 0; i < titleLen; i++)
+ {
+ /* fetch character */
+ if ((result = OTA_FetchBitField(pEASData->hwInstData, pData, 8, &temp)) != EAS_SUCCESS)
+ return result;
+
+ /* check for metadata callback */
+ if (pData->metadata.callback)
+ {
+ if (i < (pData->metadata.bufferSize - 1))
+ pData->metadata.buffer[i] = (char) temp;
+ }
+ }
+
+ /* if host has registered callback, call it now */
+ if (pData->metadata.callback)
+ (*pData->metadata.callback)(EAS_METADATA_TITLE, pData->metadata.buffer, pData->metadata.pUserData);
+ }
+
+ /* must be temporary song */
+ else if (temp != OTA_TEMPORARY_SONG_TYPE)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Expected OTA basic or temporary song type\n"); */ }
+ return EAS_ERROR_FILE_FORMAT;
+ }
+
+ /* get the song length */
+ if ((result = OTA_FetchBitField(pEASData->hwInstData, pData, 8, &pData->numPatterns)) != EAS_SUCCESS)
+ return result;
+
+ /* sanity check */
+ if (pData->numPatterns == 0)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "OTA number of patterns is zero\n"); */ }
+ return EAS_ERROR_FILE_FORMAT;
+ }
+
+ /* at start of first pattern */
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * OTA_FetchBitField()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Fetch a specified number of bits from the input stream
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT OTA_FetchBitField (EAS_HW_DATA_HANDLE hwInstData, S_OTA_DATA *pData, EAS_I32 numBits, EAS_U8 *pValue)
+{
+ EAS_RESULT result;
+ EAS_I32 bitsLeft;
+ EAS_U8 value;
+
+ value = 0;
+
+ /* do we have enough bits? */
+ bitsLeft = pData->current.bitCount - numBits;
+
+ /* not enough bits, assemble them from 2 characters */
+ if (bitsLeft < 0)
+ {
+ /* grab the remaining bits from the previous byte */
+ if (pData->current.bitCount)
+ /*lint -e{504,734} this is a legitimate shift operation */
+ value = pData->current.dataByte << -bitsLeft;
+
+ /* read the next byte */
+ if ((result = EAS_HWGetByte(hwInstData, pData->fileHandle, &pData->current.dataByte)) != EAS_SUCCESS)
+ return result;
+ bitsLeft += 8;
+ }
+
+ /* more bits than needed? */
+ if (bitsLeft > 0)
+ {
+ value |= pData->current.dataByte >> bitsLeft;
+ pData->current.bitCount = (EAS_U8) bitsLeft;
+ pData->current.dataByte = pData->current.dataByte & (0xff >> (8 - bitsLeft));
+ }
+
+ /* exactly the right number of bits */
+ else
+ {
+ value |= pData->current.dataByte;
+ pData->current.bitCount = 0;
+ }
+
+ *pValue = value;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * OTA_SavePosition()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ *
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT OTA_SavePosition (EAS_HW_DATA_HANDLE hwInstData, S_OTA_DATA *pData, S_OTA_LOC *pLoc)
+{
+ EAS_HWMemCpy(pLoc, &pData->current, sizeof(S_OTA_LOC));
+ return EAS_HWFilePos(hwInstData, pData->fileHandle, &pLoc->fileOffset);
+}
+
+/*----------------------------------------------------------------------------
+ * OTA_RestorePosition()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ *
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT OTA_RestorePosition (EAS_HW_DATA_HANDLE hwInstData, S_OTA_DATA *pData, S_OTA_LOC *pLoc)
+{
+ EAS_HWMemCpy(&pData->current, pLoc, sizeof(S_OTA_LOC));
+ pData->restore.fileOffset = -1;
+ return EAS_HWFileSeek(hwInstData, pData->fileHandle, pLoc->fileOffset);
+}
+
diff --git a/arm-hybrid-22k/lib_src/eas_otadata.c b/arm-hybrid-22k/lib_src/eas_otadata.c
index 237f832..7463a0c 100644
--- a/arm-hybrid-22k/lib_src/eas_otadata.c
+++ b/arm-hybrid-22k/lib_src/eas_otadata.c
@@ -1,12 +1,12 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_otadata..c
- *
- * Contents and purpose:
- * OTA Stream Parser data module for static memory model
- *
- * Copyright Sonic Network Inc. 2005
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_otadata..c
+ *
+ * Contents and purpose:
+ * OTA Stream Parser data module for static memory model
+ *
+ * Copyright Sonic Network Inc. 2005
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,23 +19,23 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 547 $
- * $Date: 2007-01-31 16:30:17 -0800 (Wed, 31 Jan 2007) $
- *----------------------------------------------------------------------------
-*/
-
-#include "eas_types.h"
-#include "eas_otadata.h"
-
-/*----------------------------------------------------------------------------
- *
- * eas_OTAData
- *
- * Static memory allocation for OTA parser
- *----------------------------------------------------------------------------
-*/
-S_OTA_DATA eas_OTAData;
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 547 $
+ * $Date: 2007-01-31 16:30:17 -0800 (Wed, 31 Jan 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+#include "eas_types.h"
+#include "eas_otadata.h"
+
+/*----------------------------------------------------------------------------
+ *
+ * eas_OTAData
+ *
+ * Static memory allocation for OTA parser
+ *----------------------------------------------------------------------------
+*/
+S_OTA_DATA eas_OTAData;
+
diff --git a/arm-hybrid-22k/lib_src/eas_otadata.h b/arm-hybrid-22k/lib_src/eas_otadata.h
index 63e963f..c06e3d3 100644
--- a/arm-hybrid-22k/lib_src/eas_otadata.h
+++ b/arm-hybrid-22k/lib_src/eas_otadata.h
@@ -1,14 +1,14 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_otadata.h
- *
- * Contents and purpose:
- * OTA File Parser
- *
- * This file contains data declarations for the OTA parser.
- *
- * Copyright Sonic Network Inc. 2005
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_otadata.h
+ *
+ * Contents and purpose:
+ * OTA File Parser
+ *
+ * This file contains data declarations for the OTA parser.
+ *
+ * Copyright Sonic Network Inc. 2005
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,61 +21,61 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 82 $
- * $Date: 2006-07-10 11:45:19 -0700 (Mon, 10 Jul 2006) $
- *----------------------------------------------------------------------------
-*/
-
-#ifndef EAS_OTADATA_H
-#define EAS_OTADATA_H
-
-#include "eas_data.h"
-
-/* definition for state flags */
-#define OTA_FLAGS_UNICODE 0x01 /* unicode text */
-
-/*----------------------------------------------------------------------------
- *
- * S_OTA_DATA
- *
- * This structure contains the state data for the OTA parser
- *----------------------------------------------------------------------------
-*/
-
-typedef struct
-{
- EAS_I32 fileOffset; /* offset to location in file */
- EAS_U8 patternLen; /* length of current pattern */
- EAS_U8 dataByte; /* previous char from file */
- EAS_U8 bitCount; /* bit count in char */
-} S_OTA_LOC;
-
-typedef struct
-{
- EAS_FILE_HANDLE fileHandle; /* file handle */
- S_SYNTH *pSynth; /* synth handle */
- EAS_I32 fileOffset; /* offset to start of data */
- EAS_I32 time; /* current time in 256ths of a msec */
- EAS_U32 tick; /* length of 32nd note in 256th of a msec */
- EAS_U32 restTicks; /* ticks to rest after current note */
- S_OTA_LOC patterns[4]; /* pattern locations */
- S_OTA_LOC current; /* current location */
- S_OTA_LOC restore; /* previous location */
- S_METADATA_CB metadata; /* metadata callback */
- EAS_U8 flags; /* bit flags */
- EAS_U8 numPatterns; /* number of patterns left in song */
- EAS_U8 currentPattern; /* current pattern for loop */
- EAS_U8 note; /* MIDI note number */
- EAS_U8 octave; /* octave modifier */
- EAS_U8 style; /* from STYLE */
- EAS_U8 velocity; /* current volume */
- EAS_U8 state; /* current state EAS_STATE_XXXX */
- EAS_U8 loopCount; /* loop count for pattern */
-} S_OTA_DATA;
-
-#endif
-
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 82 $
+ * $Date: 2006-07-10 11:45:19 -0700 (Mon, 10 Jul 2006) $
+ *----------------------------------------------------------------------------
+*/
+
+#ifndef EAS_OTADATA_H
+#define EAS_OTADATA_H
+
+#include "eas_data.h"
+
+/* definition for state flags */
+#define OTA_FLAGS_UNICODE 0x01 /* unicode text */
+
+/*----------------------------------------------------------------------------
+ *
+ * S_OTA_DATA
+ *
+ * This structure contains the state data for the OTA parser
+ *----------------------------------------------------------------------------
+*/
+
+typedef struct
+{
+ EAS_I32 fileOffset; /* offset to location in file */
+ EAS_U8 patternLen; /* length of current pattern */
+ EAS_U8 dataByte; /* previous char from file */
+ EAS_U8 bitCount; /* bit count in char */
+} S_OTA_LOC;
+
+typedef struct
+{
+ EAS_FILE_HANDLE fileHandle; /* file handle */
+ S_SYNTH *pSynth; /* synth handle */
+ EAS_I32 fileOffset; /* offset to start of data */
+ EAS_I32 time; /* current time in 256ths of a msec */
+ EAS_U32 tick; /* length of 32nd note in 256th of a msec */
+ EAS_U32 restTicks; /* ticks to rest after current note */
+ S_OTA_LOC patterns[4]; /* pattern locations */
+ S_OTA_LOC current; /* current location */
+ S_OTA_LOC restore; /* previous location */
+ S_METADATA_CB metadata; /* metadata callback */
+ EAS_U8 flags; /* bit flags */
+ EAS_U8 numPatterns; /* number of patterns left in song */
+ EAS_U8 currentPattern; /* current pattern for loop */
+ EAS_U8 note; /* MIDI note number */
+ EAS_U8 octave; /* octave modifier */
+ EAS_U8 style; /* from STYLE */
+ EAS_U8 velocity; /* current volume */
+ EAS_U8 state; /* current state EAS_STATE_XXXX */
+ EAS_U8 loopCount; /* loop count for pattern */
+} S_OTA_DATA;
+
+#endif
+
+
diff --git a/arm-hybrid-22k/lib_src/eas_pan.c b/arm-hybrid-22k/lib_src/eas_pan.c
index 373d90e..ae4c69d 100644
--- a/arm-hybrid-22k/lib_src/eas_pan.c
+++ b/arm-hybrid-22k/lib_src/eas_pan.c
@@ -1,16 +1,16 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_pan.c
- *
- * Contents and purpose:
- * Calculates left and right gain multipliers based on a pan value from -63 to +63
- *
- * NOTES:
- * The _CMX_PARSER and _MFI_PARSER preprocessor symbols determine
- * whether the parser works for those particular file formats.
- *
- * Copyright Sonic Network Inc. 2005
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_pan.c
+ *
+ * Contents and purpose:
+ * Calculates left and right gain multipliers based on a pan value from -63 to +63
+ *
+ * NOTES:
+ * The _CMX_PARSER and _MFI_PARSER preprocessor symbols determine
+ * whether the parser works for those particular file formats.
+ *
+ * Copyright Sonic Network Inc. 2005
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -23,76 +23,76 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 82 $
- * $Date: 2006-07-10 11:45:19 -0700 (Mon, 10 Jul 2006) $
- *----------------------------------------------------------------------------
-*/
-
-#include "eas_pan.h"
-#include "eas_math.h"
-
-/*----------------------------------------------------------------------------
- * EAS_CalcPanControl()
- *----------------------------------------------------------------------------
- * Purpose:
- * Assign the left and right gain values corresponding to the given pan value.
- *
- * This routine uses sin/cos approximations for an equal power curve:
- *
- * sin(x) = (2-4*c)*x^2 + c + x
- * cos(x) = (2-4*c)*x^2 + c - x
- *
- * where c = 1/sqrt(2)
- * using the a0 + x*(a1 + x*a2) approach
- *
- * Inputs:
- * pan - pan value (-63 to + 63)
- *
- * Outputs:
- * pGainLeft linear gain multiplier for left channel (15-bit fraction)
- * pGainRight linear gain multiplier for left channel (15-bit fraction)
- *
- * Side Effects:
- *----------------------------------------------------------------------------
-*/
-void EAS_CalcPanControl (EAS_INT pan, EAS_I16 *pGainLeft, EAS_I16 *pGainRight)
-{
- EAS_INT temp;
- EAS_INT netAngle;
-
- /* impose hard limit */
- if (pan < -63)
- netAngle = -63;
- else if (pan > 63)
- netAngle = 63;
- else
- netAngle = pan;
-
- /*lint -e{701} <avoid multiply for performance reasons>*/
- netAngle = netAngle << 8;
-
- /* calculate sin */
- temp = EG1_ONE + FMUL_15x15(COEFF_PAN_G2, netAngle);
- temp = COEFF_PAN_G0 + FMUL_15x15(temp, netAngle);
-
- if (temp > SYNTH_FULL_SCALE_EG1_GAIN)
- temp = SYNTH_FULL_SCALE_EG1_GAIN;
- else if (temp < 0)
- temp = 0;
-
- *pGainRight = (EAS_I16) temp;
-
- /* calculate cos */
- temp = -EG1_ONE + FMUL_15x15(COEFF_PAN_G2, netAngle);
- temp = COEFF_PAN_G0 + FMUL_15x15(temp, netAngle);
- if (temp > SYNTH_FULL_SCALE_EG1_GAIN)
- temp = SYNTH_FULL_SCALE_EG1_GAIN;
- else if (temp < 0)
- temp = 0;
-
- *pGainLeft = (EAS_I16) temp;
-}
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 82 $
+ * $Date: 2006-07-10 11:45:19 -0700 (Mon, 10 Jul 2006) $
+ *----------------------------------------------------------------------------
+*/
+
+#include "eas_pan.h"
+#include "eas_math.h"
+
+/*----------------------------------------------------------------------------
+ * EAS_CalcPanControl()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Assign the left and right gain values corresponding to the given pan value.
+ *
+ * This routine uses sin/cos approximations for an equal power curve:
+ *
+ * sin(x) = (2-4*c)*x^2 + c + x
+ * cos(x) = (2-4*c)*x^2 + c - x
+ *
+ * where c = 1/sqrt(2)
+ * using the a0 + x*(a1 + x*a2) approach
+ *
+ * Inputs:
+ * pan - pan value (-63 to + 63)
+ *
+ * Outputs:
+ * pGainLeft linear gain multiplier for left channel (15-bit fraction)
+ * pGainRight linear gain multiplier for left channel (15-bit fraction)
+ *
+ * Side Effects:
+ *----------------------------------------------------------------------------
+*/
+void EAS_CalcPanControl (EAS_INT pan, EAS_I16 *pGainLeft, EAS_I16 *pGainRight)
+{
+ EAS_INT temp;
+ EAS_INT netAngle;
+
+ /* impose hard limit */
+ if (pan < -63)
+ netAngle = -63;
+ else if (pan > 63)
+ netAngle = 63;
+ else
+ netAngle = pan;
+
+ /*lint -e{701} <avoid multiply for performance reasons>*/
+ netAngle = netAngle << 8;
+
+ /* calculate sin */
+ temp = EG1_ONE + FMUL_15x15(COEFF_PAN_G2, netAngle);
+ temp = COEFF_PAN_G0 + FMUL_15x15(temp, netAngle);
+
+ if (temp > SYNTH_FULL_SCALE_EG1_GAIN)
+ temp = SYNTH_FULL_SCALE_EG1_GAIN;
+ else if (temp < 0)
+ temp = 0;
+
+ *pGainRight = (EAS_I16) temp;
+
+ /* calculate cos */
+ temp = -EG1_ONE + FMUL_15x15(COEFF_PAN_G2, netAngle);
+ temp = COEFF_PAN_G0 + FMUL_15x15(temp, netAngle);
+ if (temp > SYNTH_FULL_SCALE_EG1_GAIN)
+ temp = SYNTH_FULL_SCALE_EG1_GAIN;
+ else if (temp < 0)
+ temp = 0;
+
+ *pGainLeft = (EAS_I16) temp;
+}
+
diff --git a/arm-hybrid-22k/lib_src/eas_pan.h b/arm-hybrid-22k/lib_src/eas_pan.h
index cefa650..cb0a90d 100644
--- a/arm-hybrid-22k/lib_src/eas_pan.h
+++ b/arm-hybrid-22k/lib_src/eas_pan.h
@@ -1,16 +1,16 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_pan.h
- *
- * Contents and purpose:
- * Calculates left and right gain multipliers based on a pan value from -63 to +63
- *
- * NOTES:
- * The _CMX_PARSER and _MFI_PARSER preprocessor symbols determine
- * whether the parser works for those particular file formats.
- *
- * Copyright Sonic Network Inc. 2005
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_pan.h
+ *
+ * Contents and purpose:
+ * Calculates left and right gain multipliers based on a pan value from -63 to +63
+ *
+ * NOTES:
+ * The _CMX_PARSER and _MFI_PARSER preprocessor symbols determine
+ * whether the parser works for those particular file formats.
+ *
+ * Copyright Sonic Network Inc. 2005
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -23,44 +23,44 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 82 $
- * $Date: 2006-07-10 11:45:19 -0700 (Mon, 10 Jul 2006) $
- *----------------------------------------------------------------------------
-*/
-
-#ifndef EAS_PAN_H
-#define _EAS_PAN_H
-
-#include "eas_types.h"
-
-/*----------------------------------------------------------------------------
- * EAS_CalcPanControl()
- *----------------------------------------------------------------------------
- * Purpose:
- * Assign the left and right gain values corresponding to the given pan value.
- *
- * This routine uses sin/cos approximations for an equal power curve:
- *
- * sin(x) = (2-4*c)*x^2 + c + x
- * cos(x) = (2-4*c)*x^2 + c - x
- *
- * where c = 1/sqrt(2)
- * using the a0 + x*(a1 + x*a2) approach
- *
- * Inputs:
- * pan - pan value (-63 to + 63)
- *
- * Outputs:
- * pGainLeft linear gain multiplier for left channel (15-bit fraction)
- * pGainRight linear gain multiplier for left channel (15-bit fraction)
- *
- * Side Effects:
- *----------------------------------------------------------------------------
-*/
-void EAS_CalcPanControl (EAS_INT pan, EAS_I16 *pGainLeft, EAS_I16 *pGainRight);
-
-#endif
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 82 $
+ * $Date: 2006-07-10 11:45:19 -0700 (Mon, 10 Jul 2006) $
+ *----------------------------------------------------------------------------
+*/
+
+#ifndef EAS_PAN_H
+#define _EAS_PAN_H
+
+#include "eas_types.h"
+
+/*----------------------------------------------------------------------------
+ * EAS_CalcPanControl()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Assign the left and right gain values corresponding to the given pan value.
+ *
+ * This routine uses sin/cos approximations for an equal power curve:
+ *
+ * sin(x) = (2-4*c)*x^2 + c + x
+ * cos(x) = (2-4*c)*x^2 + c - x
+ *
+ * where c = 1/sqrt(2)
+ * using the a0 + x*(a1 + x*a2) approach
+ *
+ * Inputs:
+ * pan - pan value (-63 to + 63)
+ *
+ * Outputs:
+ * pGainLeft linear gain multiplier for left channel (15-bit fraction)
+ * pGainRight linear gain multiplier for left channel (15-bit fraction)
+ *
+ * Side Effects:
+ *----------------------------------------------------------------------------
+*/
+void EAS_CalcPanControl (EAS_INT pan, EAS_I16 *pGainLeft, EAS_I16 *pGainRight);
+
+#endif
+
diff --git a/arm-hybrid-22k/lib_src/eas_parser.h b/arm-hybrid-22k/lib_src/eas_parser.h
index 5512c82..96ec35b 100644
--- a/arm-hybrid-22k/lib_src/eas_parser.h
+++ b/arm-hybrid-22k/lib_src/eas_parser.h
@@ -1,15 +1,15 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_parser.h
- *
- * Contents and purpose:
- * Interface declarations for the generic parser interface
- *
- * This header only contains declarations that are specific
- * to this implementation.
- *
- * Copyright Sonic Network Inc. 2005
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_parser.h
+ *
+ * Contents and purpose:
+ * Interface declarations for the generic parser interface
+ *
+ * This header only contains declarations that are specific
+ * to this implementation.
+ *
+ * Copyright Sonic Network Inc. 2005
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -22,77 +22,77 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 767 $
- * $Date: 2007-07-19 13:47:31 -0700 (Thu, 19 Jul 2007) $
- *----------------------------------------------------------------------------
-*/
-
-#ifndef _EAS_PARSER_H
-#define _EAS_PARSER_H
-
-#include "eas_types.h"
-
-
-/* metadata callback */
-typedef struct s_metadata_cb_tag
-{
- EAS_METADATA_CBFUNC callback;
- char *buffer;
- EAS_VOID_PTR pUserData;
- EAS_I32 bufferSize;
-} S_METADATA_CB;
-
-/* generic parser interface */
-typedef struct
-{
- EAS_RESULT (* EAS_CONST pfCheckFileType)(struct s_eas_data_tag *pEASData, EAS_FILE_HANDLE fileHandle, EAS_VOID_PTR *ppHandle, EAS_I32 offset);
- EAS_RESULT (* EAS_CONST pfPrepare)(struct s_eas_data_tag *pEASData, EAS_VOID_PTR pInstData);
- EAS_RESULT (* EAS_CONST pfTime)(struct s_eas_data_tag *pEASData, EAS_VOID_PTR pInstData, EAS_U32 *pTime);
- EAS_RESULT (* EAS_CONST pfEvent)(struct s_eas_data_tag *pEASData, EAS_VOID_PTR pInstData, EAS_INT parseMode);
- EAS_RESULT (* EAS_CONST pfState)(struct s_eas_data_tag *pEASData, EAS_VOID_PTR pInstData, EAS_STATE *pState);
- EAS_RESULT (* EAS_CONST pfClose)(struct s_eas_data_tag *pEASData, EAS_VOID_PTR pInstData);
- EAS_RESULT (* EAS_CONST pfReset)(struct s_eas_data_tag *pEASData, EAS_VOID_PTR pInstData);
- EAS_RESULT (* EAS_CONST pfPause)(struct s_eas_data_tag *pEASData, EAS_VOID_PTR pInstData);
- EAS_RESULT (* EAS_CONST pfResume)(struct s_eas_data_tag *pEASData, EAS_VOID_PTR pInstData);
- EAS_RESULT (* EAS_CONST pfLocate)(struct s_eas_data_tag *pEASData, EAS_VOID_PTR pInstData, EAS_I32 time, EAS_BOOL *pParserLocate);
- EAS_RESULT (* EAS_CONST pfSetData)(struct s_eas_data_tag *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value);
- EAS_RESULT (* EAS_CONST pfGetData)(struct s_eas_data_tag *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue);
- EAS_RESULT (* EAS_CONST pfGetMetaData)(struct s_eas_data_tag *pEASData, EAS_VOID_PTR pInstData, EAS_I32 *pMediaLength);
-} S_FILE_PARSER_INTERFACE;
-
-typedef enum
-{
- eParserModePlay,
- eParserModeLocate,
- eParserModeMute,
- eParserModeMetaData
-} E_PARSE_MODE;
-
-typedef enum
-{
- PARSER_DATA_FILE_TYPE,
- PARSER_DATA_PLAYBACK_RATE,
- PARSER_DATA_TRANSPOSITION,
- PARSER_DATA_VOLUME,
- PARSER_DATA_SYNTH_HANDLE,
- PARSER_DATA_METADATA_CB,
- PARSER_DATA_DLS_COLLECTION,
- PARSER_DATA_EAS_LIBRARY,
- PARSER_DATA_POLYPHONY,
- PARSER_DATA_PRIORITY,
- PARSER_DATA_FORMAT,
- PARSER_DATA_MEDIA_LENGTH,
- PARSER_DATA_JET_CB,
- PARSER_DATA_MUTE_FLAGS,
- PARSER_DATA_SET_MUTE,
- PARSER_DATA_CLEAR_MUTE,
- PARSER_DATA_NOTE_COUNT,
- PARSER_DATA_MAX_PCM_STREAMS,
- PARSER_DATA_GAIN_OFFSET,
- PARSER_DATA_PLAY_MODE
-} E_PARSER_DATA;
-
-#endif /* #ifndef _EAS_PARSER_H */
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 767 $
+ * $Date: 2007-07-19 13:47:31 -0700 (Thu, 19 Jul 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+#ifndef _EAS_PARSER_H
+#define _EAS_PARSER_H
+
+#include "eas_types.h"
+
+
+/* metadata callback */
+typedef struct s_metadata_cb_tag
+{
+ EAS_METADATA_CBFUNC callback;
+ char *buffer;
+ EAS_VOID_PTR pUserData;
+ EAS_I32 bufferSize;
+} S_METADATA_CB;
+
+/* generic parser interface */
+typedef struct
+{
+ EAS_RESULT (* EAS_CONST pfCheckFileType)(struct s_eas_data_tag *pEASData, EAS_FILE_HANDLE fileHandle, EAS_VOID_PTR *ppHandle, EAS_I32 offset);
+ EAS_RESULT (* EAS_CONST pfPrepare)(struct s_eas_data_tag *pEASData, EAS_VOID_PTR pInstData);
+ EAS_RESULT (* EAS_CONST pfTime)(struct s_eas_data_tag *pEASData, EAS_VOID_PTR pInstData, EAS_U32 *pTime);
+ EAS_RESULT (* EAS_CONST pfEvent)(struct s_eas_data_tag *pEASData, EAS_VOID_PTR pInstData, EAS_INT parseMode);
+ EAS_RESULT (* EAS_CONST pfState)(struct s_eas_data_tag *pEASData, EAS_VOID_PTR pInstData, EAS_STATE *pState);
+ EAS_RESULT (* EAS_CONST pfClose)(struct s_eas_data_tag *pEASData, EAS_VOID_PTR pInstData);
+ EAS_RESULT (* EAS_CONST pfReset)(struct s_eas_data_tag *pEASData, EAS_VOID_PTR pInstData);
+ EAS_RESULT (* EAS_CONST pfPause)(struct s_eas_data_tag *pEASData, EAS_VOID_PTR pInstData);
+ EAS_RESULT (* EAS_CONST pfResume)(struct s_eas_data_tag *pEASData, EAS_VOID_PTR pInstData);
+ EAS_RESULT (* EAS_CONST pfLocate)(struct s_eas_data_tag *pEASData, EAS_VOID_PTR pInstData, EAS_I32 time, EAS_BOOL *pParserLocate);
+ EAS_RESULT (* EAS_CONST pfSetData)(struct s_eas_data_tag *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value);
+ EAS_RESULT (* EAS_CONST pfGetData)(struct s_eas_data_tag *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue);
+ EAS_RESULT (* EAS_CONST pfGetMetaData)(struct s_eas_data_tag *pEASData, EAS_VOID_PTR pInstData, EAS_I32 *pMediaLength);
+} S_FILE_PARSER_INTERFACE;
+
+typedef enum
+{
+ eParserModePlay,
+ eParserModeLocate,
+ eParserModeMute,
+ eParserModeMetaData
+} E_PARSE_MODE;
+
+typedef enum
+{
+ PARSER_DATA_FILE_TYPE,
+ PARSER_DATA_PLAYBACK_RATE,
+ PARSER_DATA_TRANSPOSITION,
+ PARSER_DATA_VOLUME,
+ PARSER_DATA_SYNTH_HANDLE,
+ PARSER_DATA_METADATA_CB,
+ PARSER_DATA_DLS_COLLECTION,
+ PARSER_DATA_EAS_LIBRARY,
+ PARSER_DATA_POLYPHONY,
+ PARSER_DATA_PRIORITY,
+ PARSER_DATA_FORMAT,
+ PARSER_DATA_MEDIA_LENGTH,
+ PARSER_DATA_JET_CB,
+ PARSER_DATA_MUTE_FLAGS,
+ PARSER_DATA_SET_MUTE,
+ PARSER_DATA_CLEAR_MUTE,
+ PARSER_DATA_NOTE_COUNT,
+ PARSER_DATA_MAX_PCM_STREAMS,
+ PARSER_DATA_GAIN_OFFSET,
+ PARSER_DATA_PLAY_MODE
+} E_PARSER_DATA;
+
+#endif /* #ifndef _EAS_PARSER_H */
diff --git a/arm-hybrid-22k/lib_src/eas_pcm.c b/arm-hybrid-22k/lib_src/eas_pcm.c
index 64b8f71..ff3f6f9 100644
--- a/arm-hybrid-22k/lib_src/eas_pcm.c
+++ b/arm-hybrid-22k/lib_src/eas_pcm.c
@@ -1,12 +1,12 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_pcm.c
- *
- * Contents and purpose:
- * Implements the PCM engine including ADPCM decode for SMAF and CMX audio playback.
- *
- * Copyright Sonic Network Inc. 2005
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_pcm.c
+ *
+ * Contents and purpose:
+ * Implements the PCM engine including ADPCM decode for SMAF and CMX audio playback.
+ *
+ * Copyright Sonic Network Inc. 2005
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,1464 +19,1464 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 849 $
- * $Date: 2007-08-28 08:59:11 -0700 (Tue, 28 Aug 2007) $
- *----------------------------------------------------------------------------
-*/
-
-#include "eas_data.h"
-#include "eas_report.h"
-#include "eas_host.h"
-#include "eas_config.h"
-#include "eas_parser.h"
-#include "eas_pcm.h"
-#include "eas_math.h"
-#include "eas_mixer.h"
-
-#define PCM_MIXER_GUARD_BITS (NUM_MIXER_GUARD_BITS + 1)
-
-/*----------------------------------------------------------------------------
- * Decoder interfaces
- *----------------------------------------------------------------------------
-*/
-
-static EAS_RESULT LinearPCMDecode (EAS_DATA_HANDLE pEASData, S_PCM_STATE *pState);
-static EAS_RESULT LinearPCMLocate (EAS_DATA_HANDLE pEASData, S_PCM_STATE *pState, EAS_I32 time);
-
-static const S_DECODER_INTERFACE PCMDecoder =
-{
- NULL,
- LinearPCMDecode,
- LinearPCMLocate,
-};
-
-/* SMAF ADPCM decoder */
-#ifdef _SMAF_PARSER
-extern S_DECODER_INTERFACE SmafDecoder;
-#define SMAF_DECODER &SmafDecoder
-extern S_DECODER_INTERFACE Smaf7BitDecoder;
-#define SMAF_7BIT_DECODER &Smaf7BitDecoder
-#else
-#define SMAF_DECODER NULL
-#define SMAF_7BIT_DECODER NULL
-#endif
-
-/* IMA ADPCM decoder */
-#ifdef _IMA_DECODER
-extern S_DECODER_INTERFACE IMADecoder;
-#define IMA_DECODER &IMADecoder
-#else
-#define IMA_DECODER NULL
-#endif
-
-static const S_DECODER_INTERFACE * const decoders[] =
-{
- &PCMDecoder,
- SMAF_DECODER,
- IMA_DECODER,
- SMAF_7BIT_DECODER
-};
-
-/*----------------------------------------------------------------------------
- * Sample rate conversion
- *----------------------------------------------------------------------------
-*/
-
-#define SRC_RATE_MULTIPLER (0x40000000 / _OUTPUT_SAMPLE_RATE)
-
-#ifdef _LOOKUP_SAMPLE_RATE
-static const EAS_U32 srcConvRate[][2] =
-{
- 4000L, (4000L << 15) / _OUTPUT_SAMPLE_RATE,
- 8000L, (8000L << 15) / _OUTPUT_SAMPLE_RATE,
- 11025L, (11025L << 15) / _OUTPUT_SAMPLE_RATE,
- 12000L, (12000L << 15) / _OUTPUT_SAMPLE_RATE,
- 16000L, (16000L << 15) / _OUTPUT_SAMPLE_RATE,
- 22050L, (22050L << 15) / _OUTPUT_SAMPLE_RATE,
- 24000L, (24000L << 15) / _OUTPUT_SAMPLE_RATE,
- 32000L, (32000L << 15) / _OUTPUT_SAMPLE_RATE
-};
-static EAS_U32 CalcBaseFreq (EAS_U32 sampleRate);
-#define SRC_CONV_RATE_ENTRIES (sizeof(srcConvRate)/sizeof(EAS_U32)/2)
-#endif
-
-
-/* interface prototypes */
-static EAS_RESULT RenderPCMStream (S_EAS_DATA *pEASData, S_PCM_STATE *pState, EAS_I32 numSamples);
-
-
-/* local prototypes */
-static S_PCM_STATE *FindSlot (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle, EAS_PCM_CALLBACK pCallbackFunc, EAS_VOID_PTR cbInstData);
-static EAS_RESULT InitPCMStream (S_EAS_DATA *pEASData, S_PCM_STATE *pState);
-
-/*----------------------------------------------------------------------------
- * EAS_PEInit()
- *----------------------------------------------------------------------------
- * Purpose:
- * Initializes the PCM engine
- *
- * Inputs:
- *
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT EAS_PEInit (S_EAS_DATA *pEASData)
-{
- S_PCM_STATE *pState;
- EAS_INT i;
-
- /* check for static memory allocation */
- if (pEASData->staticMemoryModel)
- pEASData->pPCMStreams = EAS_CMEnumData(EAS_CM_PCM_DATA);
- /* allocate dynamic memory */
- else
- pEASData->pPCMStreams = EAS_HWMalloc(pEASData->hwInstData, sizeof(S_PCM_STATE) * MAX_PCM_STREAMS);
-
- if (!pEASData->pPCMStreams)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_FATAL, "Failed to allocate memory for PCM streams\n"); */ }
- return EAS_ERROR_MALLOC_FAILED;
- }
-
- //zero the memory to insure complete initialization
- EAS_HWMemSet((void *)(pEASData->pPCMStreams),0, sizeof(S_PCM_STATE) * MAX_PCM_STREAMS);
-
- /* initialize the state data */
- for (i = 0, pState = pEASData->pPCMStreams; i < MAX_PCM_STREAMS; i++, pState++)
- pState->fileHandle = NULL;
-
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * EAS_PEShutdown()
- *----------------------------------------------------------------------------
- * Purpose:
- * Shuts down the PCM engine
- *
- * Inputs:
- *
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT EAS_PEShutdown (S_EAS_DATA *pEASData)
-{
-
- /* free any dynamic memory */
- if (!pEASData->staticMemoryModel)
- {
- if (pEASData->pPCMStreams)
- {
- EAS_HWFree(pEASData->hwInstData, pEASData->pPCMStreams);
- pEASData->pPCMStreams = NULL;
- }
- }
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * EAS_PERender()
- *----------------------------------------------------------------------------
- * Purpose:
- * Render a buffer of PCM audio
- *
- * Inputs:
- *
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT EAS_PERender (S_EAS_DATA* pEASData, EAS_I32 numSamples)
-{
- S_PCM_STATE *pState;
- EAS_RESULT result;
- EAS_INT i;
-
- /* render all the active streams */
- for (i = 0, pState = pEASData->pPCMStreams; i < MAX_PCM_STREAMS; i++, pState++)
- {
- if ((pState->fileHandle) && (pState->state != EAS_STATE_STOPPED) && (pState->state != EAS_STATE_PAUSED))
- if ((result = RenderPCMStream(pEASData, pState, numSamples)) != EAS_SUCCESS)
- return result;
- }
- return EAS_SUCCESS;
-}
-
-
-/*----------------------------------------------------------------------------
- * EAS_PEState()
- *----------------------------------------------------------------------------
- * Purpose:
- * Returns the current state of the stream
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- * pState - pointer to variable to store state
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- * Notes:
- * This interface is also exposed in the internal library for use by the other modules.
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, pEASData) reserved for future use */
-EAS_RESULT EAS_PEState (S_EAS_DATA *pEASData, EAS_PCM_HANDLE pInstData, EAS_STATE *pState)
-{
- /* return current state */
- *pState = pInstData->state;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * EAS_PEClose()
- *----------------------------------------------------------------------------
- * Purpose:
- * Close the file and clean up
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT EAS_PEClose (S_EAS_DATA *pEASData, EAS_PCM_HANDLE pState)
-{
- EAS_RESULT result;
-
- if ((result = EAS_HWCloseFile(pEASData->hwInstData, pState->fileHandle)) != EAS_SUCCESS)
- return result;
-
- pState->fileHandle = NULL;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * PCM_Reset()
- *----------------------------------------------------------------------------
- * Purpose:
- * Reset the sequencer. Used for locating backwards in the file.
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT EAS_PEReset (S_EAS_DATA *pEASData, EAS_PCM_HANDLE pState)
-{
- EAS_RESULT result;
-
- /* reset file position to first byte of data in the stream */
- if ((result = EAS_HWFileSeek(pEASData->hwInstData, pState->fileHandle, pState->startPos)) != EAS_SUCCESS)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Error %d seeking to start of PCM file\n", result); */ }
- return result;
- }
-
- /* re-initialize stream */
- return InitPCMStream(pEASData, pState);
-}
-
-/*----------------------------------------------------------------------------
- * EAS_PEOpenStream()
- *----------------------------------------------------------------------------
- * Purpose:
- * Starts up a PCM playback
- *
- * Inputs:
- *
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT EAS_PEOpenStream (S_EAS_DATA *pEASData, S_PCM_OPEN_PARAMS *pParams, EAS_PCM_HANDLE *pHandle)
-{
- EAS_RESULT result;
- S_PCM_STATE *pState;
- EAS_I32 filePos;
-
- /* make sure we support this decoder */
- if (pParams->decoder >= NUM_DECODER_MODULES)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Decoder selector out of range\n"); */ }
- return EAS_ERROR_PARAMETER_RANGE;
- }
- if (decoders[pParams->decoder] == NULL)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Decoder module not available\n"); */ }
- return EAS_ERROR_FEATURE_NOT_AVAILABLE;
- }
-
- /* find a slot for the new stream */
- if ((pState = FindSlot(pEASData, pParams->fileHandle, pParams->pCallbackFunc, pParams->cbInstData)) == NULL)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Unable to open ADPCM stream, too many streams open\n"); */ }
- return EAS_ERROR_MAX_PCM_STREAMS;
- }
-
- /* get the current file position */
- if ((result = EAS_HWFilePos(pEASData->hwInstData, pState->fileHandle, &filePos)) != EAS_SUCCESS)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "EAS_HWFilePos returned %ld\n",result); */ }
- pState->fileHandle = NULL;
- return result;
- }
-
- pState->pDecoder = decoders[pParams->decoder];
- pState->startPos = filePos;
- pState->bytesLeftLoop = pState->byteCount = pParams->size;
- pState->loopStart = pParams->loopStart;
- pState->samplesTilLoop = (EAS_I32) pState->loopStart;
- pState->loopSamples = pParams->loopSamples;
- pState->samplesInLoop = 0;
- pState->blockSize = (EAS_U16) pParams->blockSize;
- pState->flags = pParams->flags;
- pState->envData = pParams->envData;
- pState->volume = pParams->volume;
- pState->sampleRate = (EAS_U16) pParams->sampleRate;
-
- /* set the base frequency */
- pState->basefreq = (SRC_RATE_MULTIPLER * (EAS_U32) pParams->sampleRate) >> 15;
-
- /* calculate shift for frequencies > 1.0 */
- pState->rateShift = 0;
- while (pState->basefreq > 32767)
- {
- pState->basefreq = pState->basefreq >> 1;
- pState->rateShift++;
- }
-
- /* initialize */
- if ((result = InitPCMStream(pEASData, pState)) != EAS_SUCCESS)
- return result;
-
- *pHandle = pState;
-
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "EAS_PEOpenStream: StartPos=%d, byteCount = %d, loopSamples=%d\n",
- pState->startPos, pState->byteCount, pState->loopSamples); */ }
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * EAS_PEContinueStream()
- *----------------------------------------------------------------------------
- * Purpose:
- * Continues a PCM stream
- *
- * Inputs:
- *
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -e{715} reserved for future use */
-EAS_RESULT EAS_PEContinueStream (S_EAS_DATA *pEASData, EAS_PCM_HANDLE pState, EAS_I32 size)
-{
-
- /* add new samples to count */
- pState->bytesLeft += size;
- if (pState->bytesLeft > 0)
- pState->flags &= ~PCM_FLAGS_EMPTY;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * EAS_PEGetFileHandle()
- *----------------------------------------------------------------------------
- * Purpose:
- * Returns the file handle of a stream
- *
- * Inputs:
- *
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, pEASData) reserved for future use */
-EAS_RESULT EAS_PEGetFileHandle (S_EAS_DATA *pEASData, EAS_PCM_HANDLE pState, EAS_FILE_HANDLE *pFileHandle)
-{
- *pFileHandle = pState->fileHandle;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * EAS_PEUpdateParams()
- *----------------------------------------------------------------------------
- * Purpose:
- * Update the pitch and volume parameters for a PCM stream
- *
- * Inputs:
- * pEASData - pointer to EAS library instance data
- * handle - pointer to S_PCM_STATE for this stream
- * gainLeft - linear gain multipler in 1.15 fraction format
- * gainRight - linear gain multipler in 1.15 fraction format
- * pitch - pitch shift in cents
- * initial - initial settings, set current gain
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- * Notes
- * In mono mode, leftGain controls the output gain and rightGain is ignored
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, pEASData) reserved for future use */
-/*lint -esym(715, gainRight) used only in 2-channel version */
-EAS_RESULT EAS_PEUpdateParams (S_EAS_DATA* pEASData, EAS_PCM_HANDLE pState, EAS_I16 pitch, EAS_I16 gainLeft, EAS_I16 gainRight)
-{
-
- pState->gainLeft = gainLeft;
-
-#if (NUM_OUTPUT_CHANNELS == 2)
- pState->gainRight = gainRight;
-#endif
-
- pState->pitch = pitch;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * EAS_PELocate()
- *----------------------------------------------------------------------------
- * Purpose:
- * This function seeks to the requested place in the file. Accuracy
- * is dependent on the sample rate and block size.
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * pState - stream handle
- * time - media time in milliseconds
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT EAS_PELocate (S_EAS_DATA *pEASData, EAS_PCM_HANDLE pState, EAS_I32 time)
-{
- if (pState->pDecoder->pfLocate == NULL)
- return EAS_ERROR_FEATURE_NOT_AVAILABLE;
-
- return pState->pDecoder->pfLocate(pEASData, pState, time);
-}
-
-/*----------------------------------------------------------------------------
- * EAS_PEUpdateVolume()
- *----------------------------------------------------------------------------
- * Purpose:
- * Update the volume parameters for a PCM stream
- *
- * Inputs:
- * pEASData - pointer to EAS library instance data
- * handle - pointer to S_PCM_STATE for this stream
- * gainLeft - linear gain multipler in 1.15 fraction format
- * gainRight - linear gain multipler in 1.15 fraction format
- * initial - initial settings, set current gain
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- * Notes
- * In mono mode, leftGain controls the output gain and rightGain is ignored
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, pEASData) reserved for future use */
-EAS_RESULT EAS_PEUpdateVolume (S_EAS_DATA* pEASData, EAS_PCM_HANDLE pState, EAS_I16 volume)
-{
- pState->volume = volume;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * EAS_PEUpdatePitch()
- *----------------------------------------------------------------------------
- * Purpose:
- * Update the pitch parameter for a PCM stream
- *
- * Inputs:
- * pEASData - pointer to EAS library instance data
- * pState - pointer to S_PCM_STATE for this stream
- * pitch - new pitch value in pitch cents
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, pEASData) reserved for future use */
-EAS_RESULT EAS_PEUpdatePitch (S_EAS_DATA* pEASData, EAS_PCM_HANDLE pState, EAS_I16 pitch)
-{
- pState->pitch = pitch;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * EAS_PEPause()
- *----------------------------------------------------------------------------
- * Purpose:
- * Mute and stop rendering a PCM stream. Sets the gain target to zero and stops the playback
- * at the end of the next audio frame.
- *
- * Inputs:
- * pEASData - pointer to EAS library instance data
- * handle - pointer to S_PCM_STATE for this stream
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, pEASData) reserved for future use */
-EAS_RESULT EAS_PEPause (S_EAS_DATA *pEASData, EAS_PCM_HANDLE pState)
-{
- /* set state to stopping */
- pState->state = EAS_STATE_PAUSING;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * EAS_PEResume()
- *----------------------------------------------------------------------------
- * Purpose:
- * Resume rendering a PCM stream. Sets the gain target back to its
- * previous setting and restarts playback at the end of the next audio
- * frame.
- *
- * Inputs:
- * pEASData - pointer to EAS library instance data
- * handle - pointer to S_PCM_STATE for this stream
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, pEASData) reserved for future use */
-EAS_RESULT EAS_PEResume (S_EAS_DATA *pEASData, EAS_PCM_HANDLE pState)
-{
- /* set state to stopping */
- pState->state = EAS_STATE_PLAY;
- return EAS_SUCCESS;
-}
-
-EAS_U32 getDecayScale(EAS_U32 index)
-{
- EAS_U32 utemp;
-
- //envelope decay segment
- switch (index)
- {
- case 0: //no decay
- utemp = 512;//32768;
- break;
- case 1: //.0156 dB per update
- utemp = 511;//32709;
- break;
- case 2: //.03125
- utemp = 510;//32649;
- break;
- case 3: //.0625
- utemp = 508;//32532;
- break;
- case 4: //.125
- utemp = 505;//32298;
- break;
- case 5: //.25
- utemp = 497;//31835;
- break;
- case 6: //.5
- utemp = 483;//30929;
- break;
- case 7: //1.0
- utemp = 456;//29193;
- break;
- case 8: //2.0
- utemp = 406;//26008;
- break;
- case 9: //4.0
- utemp = 323;//20642;
- break;
- case 10: //8.0
- utemp = 203;//13004;
- break;
- case 11: //16.0
- utemp = 81;//5160;
- break;
- case 12: //32.0
- utemp = 13;//813;
- break;
- case 13: //64.0
- utemp = 0;//20;
- break;
- case 14: //128.0
- utemp = 0;
- break;
- case 15: //256.0
- default:
- utemp = 0;
- break;
- }
- //printf("getdecayscale returned %d\n",utemp);
- return utemp;
-}
-
-EAS_U32 getAttackIncrement(EAS_U32 index)
-{
- EAS_U32 utemp;
-
- //envelope decay segment
- switch (index)
- {
- case 0:
- utemp = 32;
- break;
- case 1:
- utemp = 64;
- break;
- case 2:
- utemp = 128;
- break;
- case 3:
- utemp = 256;
- break;
- case 4:
- utemp = 512;
- break;
- case 5:
- utemp = 1024;
- break;
- case 6:
- utemp = 2048;
- break;
- case 7:
- utemp = 4096;
- break;
- case 8:
- utemp = 8192;
- break;
- case 9:
- utemp = 16384;
- break;
- case 10:
- utemp = 32768;
- break;
- case 11:
- utemp = 65536;
- break;
- case 12:
- utemp = 65536;
- break;
- case 13:
- utemp = 65536;
- break;
- case 14:
- utemp = 65535;
- break;
- case 15:
- default:
- utemp = 0;
- break;
- }
- //printf("getattackincrement returned %d\n",utemp);
- return utemp;
-}
-
-/*----------------------------------------------------------------------------
- * EAS_PERelease()
- *----------------------------------------------------------------------------
- * Purpose:
- * Put the PCM stream envelope into release.
- *
- * Inputs:
- * pEASData - pointer to EAS library instance data
- * handle - pointer to S_PCM_STATE for this stream
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, pEASData) reserved for future use */
-EAS_RESULT EAS_PERelease (S_EAS_DATA *pEASData, EAS_PCM_HANDLE pState)
-{
- EAS_U32 utemp;
-
- //printf("handling note-off part of envelope\n");
- /*if the note is not ignore release or sustained*/
- if (((pState->envData >> 24) & 0x0F)==0)
- {
- /* set envelope state to release */
- pState->envState = PCM_ENV_RELEASE;
- utemp = ((pState->envData >> 20) & 0x0F);
- pState->envScale = getDecayScale(utemp); //getReleaseScale(utemp);
- }
- else
- {
- /*else change envelope state to sustain */
- pState->envState = PCM_ENV_SUSTAIN;
- utemp = ((pState->envData >> 28) & 0x0F);
- pState->envScale = getDecayScale(utemp); //getSustainScale(utemp);
- }
- //since we are in release, don't let anything hang around too long
- //printf("checking env scale, val = %d\n",((S_PCM_STATE*) handle)->envScale);
- if (pState->envScale > 505)
- pState->envScale = 505;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * FindSlot()
- *----------------------------------------------------------------------------
- * Purpose:
- * Locates an empty stream slot and assigns the file handle
- *
- * Inputs:
- * pEASData - pointer to EAS library instance data
- * fileHandle - file handle
- * pCallbackFunc - function to be called back upon EAS_STATE_STOPPED
- *
- * Outputs:
- * returns handle to slot or NULL if all slots are used
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static S_PCM_STATE *FindSlot (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle, EAS_PCM_CALLBACK pCallbackFunc, EAS_VOID_PTR cbInstData)
-{
- EAS_INT i;
- S_PCM_STATE *pState;
-
-#ifndef NO_PCM_STEAL
- S_PCM_STATE *foundState = NULL;
- EAS_INT count = 0;
- EAS_U32 startOrder = 0xFFFFFFFF;
- S_PCM_STATE *stealState = NULL;
- EAS_U32 youngest = 0;
-
- /* find an empty slot, count total in use, and find oldest in use (lowest start order) */
- for (i = 0, pState = pEASData->pPCMStreams; i < MAX_PCM_STREAMS; i++, pState++)
- {
- /* if this one is available */
- if (pState->fileHandle == NULL)
- {
- foundState = pState;
- }
- /* else this one is in use, so see if it is the oldest, and count total in use */
- /* also find youngest */
- else
- {
- /*one more voice in use*/
- count++;
- /* is this the oldest? (lowest start order) */
- if ((pState->state != EAS_STATE_STOPPING) && (pState->startOrder < startOrder))
- {
- /* remember this one */
- stealState = pState;
- /* remember the oldest so far */
- startOrder = pState->startOrder;
- }
- /* is this the youngest? (highest start order) */
- if (pState->startOrder >= youngest)
- {
- youngest = pState->startOrder;
- }
- }
- }
-
- /* if there are too many voices active, stop the oldest one */
- if (count > PCM_STREAM_THRESHOLD)
- {
- //printf("stealing!!!\n");
- /* make sure we got one, although we should always have one at this point */
- if (stealState != NULL)
- {
- //flag this as stopping, so it will get shut off
- stealState->state = EAS_STATE_STOPPING;
- }
- }
-
- /* if there are no available open streams (we won't likely see this, due to stealing) */
- if (foundState == NULL)
- return NULL;
-
- /* save info */
- foundState->startOrder = youngest + 1;
- foundState->fileHandle = fileHandle;
- foundState->pCallback = pCallbackFunc;
- foundState->cbInstData = cbInstData;
- return foundState;
-#else
- /* find an empty slot*/
- for (i = 0; i < MAX_PCM_STREAMS; i++)
- {
- pState = &pEASData->pPCMStreams[i];
- if (pState->fileHandle != NULL)
- continue;
-
- pState->fileHandle = fileHandle;
- pState->pCallback = pCallbackFunc;
- pState->cbInstData = cbInstData;
- return pState;
- }
- return NULL;
-#endif
-}
-
-#ifdef _LOOKUP_SAMPLE_RATE
-/*----------------------------------------------------------------------------
- * CalcBaseFreq()
- *----------------------------------------------------------------------------
- * Purpose:
- * Calculates the fractional phase increment for the sample rate converter
- *
- * Inputs:
- * sampleRate - sample rate in samples/sec
- *
- * Outputs:
- * Returns fractional sample rate with a 15-bit fraction
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_U32 CalcBaseFreq (EAS_U32 sampleRate)
-{
- EAS_INT i;
-
- /* look up the conversion rate */
- for (i = 0; i < (EAS_INT)(SRC_CONV_RATE_ENTRIES); i ++)
- {
- if (srcConvRate[i][0] == sampleRate)
- return srcConvRate[i][1];
- }
-
- /* if not found in table, do it the long way */
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Sample rate %u not in table, calculating by division\n", sampleRate); */ }
-
- return (SRC_RATE_MULTIPLER * (EAS_U32) sampleRate) >> 15;
-}
-#endif
-
-/*----------------------------------------------------------------------------
- * InitPCMStream()
- *----------------------------------------------------------------------------
- * Purpose:
- * Start an ADPCM stream playback. Decodes the header, preps the engine.
- *
- * Inputs:
- *
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT InitPCMStream (S_EAS_DATA *pEASData, S_PCM_STATE *pState)
-{
-
- /* initialize the data structure */
- pState->bytesLeft = pState->byteCount;
- pState->phase = 0;
- pState->srcByte = 0;
- pState->decoderL.acc = 0;
- pState->decoderL.output = 0;
- pState->decoderL.x0 = pState->decoderL.x1 = 0;
- pState->decoderL.step = 0;
- pState->decoderR.acc = 0;
- pState->decoderR.output = 0;
- pState->decoderR.x0 = pState->decoderR.x1 = 0;
- pState->decoderR.step = 0;
- pState->hiNibble = EAS_FALSE;
- pState->pitch = 0;
- pState->blockCount = 0;
- pState->gainLeft = PCM_DEFAULT_GAIN_SETTING;
-// pState->currentGainLeft = PCM_DEFAULT_GAIN_SETTING;
- pState->envValue = 0;
- pState->envState = PCM_ENV_START;
-
-#if (NUM_OUTPUT_CHANNELS == 2)
- pState->gainRight = PCM_DEFAULT_GAIN_SETTING;
-// pState->currentGainRight = PCM_DEFAULT_GAIN_SETTING;
-#endif
- pState->state = EAS_STATE_READY;
-
- /* initialize the decoder */
- if (pState->pDecoder->pfInit)
- return (*pState->pDecoder->pfInit)(pEASData, pState);
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * RenderPCMStream()
- *----------------------------------------------------------------------------
- * Purpose:
- * Decodes a buffer of ADPCM data.
- *
- * Inputs:
- *
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT RenderPCMStream (S_EAS_DATA *pEASData, S_PCM_STATE *pState, EAS_I32 numSamples)
-{
- EAS_RESULT result;
- EAS_U32 phaseInc;
- EAS_I32 gainLeft, gainIncLeft;
- EAS_I32 *pOut;
- EAS_I32 temp;
- EAS_U32 utemp;
-
-#if (NUM_OUTPUT_CHANNELS == 2)
- EAS_I32 gainRight, gainIncRight;
-#endif
-
-#if 0
- printf("env data: AR = %d, DR = %d, SL = %d, SR = %d, RR = %d\n",
- ((pState->envData >> 12) & 0x0F),
- ((pState->envData >> 16) & 0x0F),
- ((pState->envData >> 8) & 0x0F),
- ((pState->envData >> 28) & 0x0F),
- ((pState->envData >> 20) & 0x0F));
-#endif
-
- if (pState->envState == PCM_ENV_START)
- {
- //printf("env start\n");
- utemp = ((pState->envData >> 12) & 0x0F);
- //if fastest rate, attack is already completed
- //do the same for slowest rate, since that allows zero to be passed for default envelope
- if (utemp == 0x0F || utemp == 0x00)
- {
- //start envelope at full
- pState->envValue = (32768<<7);
- //jump right into decay
- utemp = ((pState->envData >> 16) & 0x0F);
- pState->envScale = getDecayScale(utemp);
- pState->envState = PCM_ENV_DECAY;
- pState->currentGainLeft = (EAS_I16) FMUL_15x15(pState->gainLeft, pState->volume);
- pState->currentGainRight = (EAS_I16) FMUL_15x15(pState->gainRight, pState->volume);
- }
- //else attack has a ramp
- else
- {
- //start the envelope very low
- pState->envValue = (2<<7);
- pState->currentGainLeft = 0;
- pState->currentGainRight = 0;
- //get envelope attack scaling value
- pState->envScale = getAttackIncrement(utemp);
- //go to attack state
- pState->envState = PCM_ENV_ATTACK;
- }
- }
- if (pState->envState == PCM_ENV_ATTACK)
- {
- //printf("env attack, env value = %d, env scale = %d\n",pState->envValue>>7,pState->envScale);
- //update envelope value
- pState->envValue = pState->envValue + (pState->envScale << 7);
- //check envelope level and update state if needed
- if (pState->envValue >= (32768<<7))
- {
- pState->envValue = (32768<<7);
- utemp = ((pState->envData >> 16) & 0x0F);
- pState->envScale = getDecayScale(utemp);
- pState->envState = PCM_ENV_DECAY;
- }
- }
- else if (pState->envState == PCM_ENV_DECAY)
- {
- //printf("env decay, env value = %d, env scale = %d\n",pState->envValue>>7,pState->envScale);
- //update envelope value
- pState->envValue = (pState->envValue * pState->envScale)>>9;
- //check envelope level against sustain level and update state if needed
- utemp = ((pState->envData >> 8) & 0x0F);
- if (utemp == (EAS_U32)0x0F)
- utemp = (2<<7);
- else
- {
- utemp = ((32769<<7) >> (utemp>>1));
- }
- if (pState->envValue <= utemp)
- {
- utemp = ((pState->envData >> 28) & 0x0F);
- pState->envScale = getDecayScale(utemp); //getSustainScale(utemp);
- pState->envState = PCM_ENV_SUSTAIN;
- }
- }
- else if (pState->envState == PCM_ENV_SUSTAIN)
- {
- //printf("env sustain, env value = %d, env scale = %d\n",pState->envValue>>7,pState->envScale);
- //update envelope value
- pState->envValue = (pState->envValue * pState->envScale)>>9;
- //check envelope level against bottom level and update state if needed
- if (pState->envValue <= (2<<7))
- {
- //no more decay
- pState->envScale = 512;
- pState->envState = PCM_ENV_END;
- }
- }
- else if (pState->envState == PCM_ENV_RELEASE)
- {
- //printf("env release, env value = %d, env scale = %d\n",pState->envValue>>7,pState->envScale);
- //update envelope value
- pState->envValue = (pState->envValue * pState->envScale)>>9;
- //check envelope level against bottom level and update state if needed
- if (pState->envValue <= (2<<7))
- {
- //no more decay
- pState->envScale = 512;
- pState->envState = PCM_ENV_END;
- }
- }
- else if (pState->envState == PCM_ENV_END)
- {
- //printf("env end\n");
- /* set state to stopping, already ramped down */
- pState->state = EAS_STATE_STOPPING;
- }
-
- //pState->gainLeft = (EAS_U16)((pState->gainLeft * (pState->envValue>>7))>>15);
- //pState->gainRight = (EAS_U16)((pState->gainRight * (pState->envValue>>7))>>15);
-
- /* gain to 32-bits to increase resolution on anti-zipper filter */
- /*lint -e{703} use shift for performance */
- gainLeft = (EAS_I32) pState->currentGainLeft << SYNTH_UPDATE_PERIOD_IN_BITS;
-#if (NUM_OUTPUT_CHANNELS == 2)
- /*lint -e{703} use shift for performance */
- gainRight = (EAS_I32) pState->currentGainRight << SYNTH_UPDATE_PERIOD_IN_BITS;
-#endif
-
- /* calculate a new gain increment, gain target is zero if pausing */
- if ((pState->state == EAS_STATE_PAUSING) || (pState->state == EAS_STATE_PAUSED))
- {
- gainIncLeft = -pState->currentGainLeft;
-#if (NUM_OUTPUT_CHANNELS == 2)
- gainIncRight= -pState->currentGainRight;
-#endif
- }
- else
- {
- EAS_I32 gain = FMUL_15x15(pState->envValue >> 7, pState->volume);
- gainIncLeft = FMUL_15x15(pState->gainLeft, gain) - pState->currentGainLeft;
-#if (NUM_OUTPUT_CHANNELS == 2)
- gainIncRight = FMUL_15x15(pState->gainRight, gain) - pState->currentGainRight;
-#endif
- }
-
- /* calculate phase increment */
- phaseInc = pState->basefreq;
-
- /* convert pitch cents to linear multiplier */
- if (pState->pitch)
- {
- temp = EAS_Calculate2toX(pState->pitch);
- phaseInc = FMUL_15x15(phaseInc, temp);
- }
- phaseInc = phaseInc << pState->rateShift;
-
- /* pointer to mix buffer */
- pOut = pEASData->pMixBuffer;
-
- /* render a buffer of samples */
- while (numSamples--)
- {
-
- /* interpolate an output sample */
- pState->decoderL.output = pState->decoderL.x0 + FMUL_15x15((pState->decoderL.x1 - pState->decoderL.x0), pState->phase & PHASE_FRAC_MASK);
-
- /* stereo output */
-#if (NUM_OUTPUT_CHANNELS == 2)
-
- /* stereo stream? */
- if (pState->flags & PCM_FLAGS_STEREO)
- pState->decoderR.output = pState->decoderR.x0 + FMUL_15x15((pState->decoderR.x1 - pState->decoderR.x0), pState->phase & PHASE_FRAC_MASK);
-
- /* gain scale and mix */
- /*lint -e{704} use shift instead of division */
- *pOut++ += (pState->decoderL.output * (gainLeft >> SYNTH_UPDATE_PERIOD_IN_BITS)) >> PCM_MIXER_GUARD_BITS;
- gainLeft += gainIncLeft;
-
- /*lint -e{704} use shift instead of division */
- if (pState->flags & PCM_FLAGS_STEREO)
- *pOut++ += (pState->decoderR.output * (gainRight >> SYNTH_UPDATE_PERIOD_IN_BITS)) >> PCM_MIXER_GUARD_BITS;
- else
- *pOut++ += (pState->decoderL.output * (gainRight >> SYNTH_UPDATE_PERIOD_IN_BITS)) >> PCM_MIXER_GUARD_BITS;
-
- gainRight += gainIncRight;
-
- /* mono output */
-#else
- /* if stereo stream, decode right channel and mix to mono */
- if (pState->flags & PCM_FLAGS_STEREO)
- {
- pState->decoderR.output= pState->decoderR.x0 + FMUL_15x15((pState->decoderR.x1 - pState->decoderR.x0), pState->phase & PHASE_FRAC_MASK);
-
- /* for mono, sum stereo ADPCM to mono */
- /*lint -e{704} use shift instead of division */
- *pOut++ += ((pState->decoderL.output + pState->decoderR.output) * (gainLeft >> SYNTH_UPDATE_PERIOD_IN_BITS)) >> PCM_MIXER_GUARD_BITS;
- }
- else
- /*lint -e{704} use shift instead of division */
- *pOut++ += (pState->decoderL.output * (gainLeft >> SYNTH_UPDATE_PERIOD_IN_BITS)) >> PCM_MIXER_GUARD_BITS;
-
- gainLeft += gainIncLeft;
-#endif
-
- /* advance phase accumulator */
- pState->phase += phaseInc;
-
- /* if integer part of phase accumulator is non-zero, advance to next sample */
- while (pState->phase & ~PHASE_FRAC_MASK)
- {
- pState->decoderL.x0 = pState->decoderL.x1;
- pState->decoderR.x0 = pState->decoderR.x1;
-
- /* give the source a chance to continue the stream */
- if (!pState->bytesLeft && pState->pCallback && ((pState->flags & PCM_FLAGS_EMPTY) == 0))
- {
- pState->flags |= PCM_FLAGS_EMPTY;
- (*pState->pCallback)(pEASData, pState->cbInstData, pState, EAS_STATE_EMPTY);
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "RenderPCMStream: After empty callback, bytesLeft = %d\n", pState->bytesLeft); */ }
- }
-
- /* decode the next sample */
- if ((result = (*pState->pDecoder->pfDecodeSample)(pEASData, pState)) != EAS_SUCCESS)
- return result;
-
- /* adjust phase by one sample */
- pState->phase -= (1L << NUM_PHASE_FRAC_BITS);
- }
-
- }
-
- /* save new gain */
- /*lint -e{704} use shift instead of division */
- pState->currentGainLeft = (EAS_I16) (gainLeft >> SYNTH_UPDATE_PERIOD_IN_BITS);
-
-#if (NUM_OUTPUT_CHANNELS == 2)
- /*lint -e{704} use shift instead of division */
- pState->currentGainRight = (EAS_I16) (gainRight >> SYNTH_UPDATE_PERIOD_IN_BITS);
-#endif
-
- /* if pausing, set new state and notify */
- if (pState->state == EAS_STATE_PAUSING)
- {
- pState->state = EAS_STATE_PAUSED;
- if (pState->pCallback)
- (*pState->pCallback)(pEASData, pState->cbInstData, pState, pState->state);
- }
-
- /* if out of data, set stopped state and notify */
- if (pState->bytesLeft == 0 || pState->state == EAS_STATE_STOPPING)
- {
- pState->state = EAS_STATE_STOPPED;
-
- /* do callback unless the file has already been closed */
- if (pState->pCallback && pState->fileHandle)
- (*pState->pCallback)(pEASData, pState->cbInstData, pState, pState->state);
- }
-
- if (pState->state == EAS_STATE_READY)
- pState->state = EAS_STATE_PLAY;
-
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * LinearPCMDecode()
- *----------------------------------------------------------------------------
- * Purpose:
- * Decodes a PCM sample
- *
- * Inputs:
- *
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT LinearPCMDecode (EAS_DATA_HANDLE pEASData, S_PCM_STATE *pState)
-{
- EAS_RESULT result;
- EAS_HW_DATA_HANDLE hwInstData;
-
- hwInstData = ((S_EAS_DATA*) pEASData)->hwInstData;
-
- /* if out of data, check for loop */
- if ((pState->bytesLeft == 0) && (pState->loopSamples != 0))
- {
- if ((result = EAS_HWFileSeek(pEASData->hwInstData, pState->fileHandle, (EAS_I32) (pState->startPos + pState->loopLocation))) != EAS_SUCCESS)
- return result;
- pState->bytesLeft = pState->byteCount = (EAS_I32) pState->bytesLeftLoop;
- pState->flags &= ~PCM_FLAGS_EMPTY;
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "LinearPCMDecode: Rewind file to %d, bytesLeft = %d\n", pState->startPos, pState->bytesLeft); */ }
- }
-
- if (pState->bytesLeft)
- {
-
- /* check format byte for 8-bit samples */
- if (pState->flags & PCM_FLAGS_8_BIT)
- {
- /* fetch left or mono sample */
- if ((result = EAS_HWGetByte(hwInstData, pState->fileHandle, &pState->srcByte)) != EAS_SUCCESS)
- return result;
-
- /* if unsigned */
- if (pState->flags & PCM_FLAGS_UNSIGNED)
- {
- /*lint -e{734} converting unsigned 8-bit to signed 16-bit */
- pState->decoderL.x1 = (EAS_PCM)(((EAS_PCM) pState->srcByte << 8) ^ 0x8000);
- }
- else
- {
- /*lint -e{734} converting signed 8-bit to signed 16-bit */
- pState->decoderL.x1 = (EAS_PCM)((EAS_PCM) pState->srcByte << 8);
- }
- pState->bytesLeft--;
-
- /* fetch right sample */
- if(pState->flags & PCM_FLAGS_STEREO)
- {
- if ((result = EAS_HWGetByte(hwInstData, pState->fileHandle, &pState->srcByte)) != EAS_SUCCESS)
- return result;
-
- /* if unsigned */
- if (pState->flags & PCM_FLAGS_UNSIGNED)
- {
- /*lint -e{734} converting unsigned 8-bit to signed 16-bit */
- pState->decoderR.x1 = (EAS_PCM)(((EAS_PCM) pState->srcByte << 8) ^ 0x8000);
- }
- else
- {
- /*lint -e{734} converting signed 8-bit to signed 16-bit */
- pState->decoderR.x1 = (EAS_PCM)((EAS_PCM) pState->srcByte << 8);
- }
- pState->bytesLeft--;
- }
- }
-
- /* must be 16-bit samples */
- else
- {
- //unsigned 16 bit currently not supported
- if (pState->flags & PCM_FLAGS_UNSIGNED)
- {
- return EAS_ERROR_INVALID_PCM_TYPE;
- }
-
- /* fetch left or mono sample */
- if ((result = EAS_HWGetWord(hwInstData, pState->fileHandle, &pState->decoderL.x1, EAS_FALSE)) != EAS_SUCCESS)
- return result;
- pState->bytesLeft -= 2;
-
- /* fetch right sample */
- if(pState->flags & PCM_FLAGS_STEREO)
- {
- if ((result = EAS_HWGetWord(hwInstData, pState->fileHandle, &pState->decoderR.x1, EAS_FALSE)) != EAS_SUCCESS)
- return result;
- pState->bytesLeft -= 2;
- }
- }
- }
-
- /* no more data, force zero samples */
- else
- pState->decoderL.x1 = pState->decoderR.x1 = 0;
-
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * LinearPCMLocate()
- *----------------------------------------------------------------------------
- * Purpose:
- * Locate in a linear PCM stream
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT LinearPCMLocate (EAS_DATA_HANDLE pEASData, S_PCM_STATE *pState, EAS_I32 time)
-{
- EAS_RESULT result;
- EAS_I32 temp;
- EAS_I32 secs, msecs;
- EAS_INT shift;
-
- /* calculate size of sample frame */
- if (pState->flags & PCM_FLAGS_8_BIT)
- shift = 0;
- else
- shift = 1;
- if (pState->flags & PCM_FLAGS_STEREO)
- shift++;
-
- /* break down into secs and msecs */
- secs = time / 1000;
- msecs = time - (secs * 1000);
-
- /* calculate sample number fraction from msecs */
- temp = (msecs * pState->sampleRate);
- temp = (temp >> 10) + ((temp * 49) >> 21);
-
- /* add integer sample count */
- temp += secs * pState->sampleRate;
-
- /* calculate the position based on sample frame size */
- /*lint -e{703} use shift for performance */
- temp <<= shift;
-
- /* past end of sample? */
- if (temp > (EAS_I32) pState->loopStart)
- {
- /* if not looped, flag error */
- if (pState->loopSamples == 0)
- {
- pState->bytesLeft = 0;
- pState->flags |= PCM_FLAGS_EMPTY;
- return EAS_ERROR_LOCATE_BEYOND_END;
- }
-
- /* looped sample - calculate position in loop */
- while (temp > (EAS_I32) pState->loopStart)
- temp -= (EAS_I32) pState->loopStart;
- }
-
- /* seek to new position */
- if ((result = EAS_PESeek(pEASData, pState, &temp)) != EAS_SUCCESS)
- return result;
-
- /* reset state */
- if ((pState->state != EAS_STATE_PAUSING) && (pState->state != EAS_STATE_PAUSED))
- pState->state = EAS_STATE_READY;
-
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * EAS_PESeek
- *----------------------------------------------------------------------------
- * Purpose:
- * Locate to a particular byte in a PCM stream
- *----------------------------------------------------------------------------
- * This bit is tricky because the chunks may not be contiguous,
- * so we have to rely on the parser to position in the file. We
- * do this by seeking to the end of each chunk and simulating an
- * empty buffer condition until we get to where we want to go.
- *
- * A better solution would be a parser API for re-positioning,
- * but there isn't time at the moment to re-factor all the
- * parsers to support a new API.
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT EAS_PESeek (S_EAS_DATA *pEASData, S_PCM_STATE *pState, EAS_I32 *pLocation)
-{
- EAS_RESULT result;
-
- /* seek to start of audio */
- if ((result = EAS_HWFileSeek(pEASData->hwInstData, pState->fileHandle, pState->startPos)) != EAS_SUCCESS)
- {
- pState->state = EAS_STATE_ERROR;
- return result;
- }
- pState->bytesLeft = pState->bytesLeftLoop;
-
- /* skip through chunks until we find the right chunk */
- while (*pLocation > (EAS_I32) pState->bytesLeft)
- {
- /* seek to end of audio chunk */
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "EAS_PESeek: Seek to offset = %d\n", pState->bytesLeft); */ }
- if ((result = EAS_HWFileSeekOfs(pEASData->hwInstData, pState->fileHandle, pState->bytesLeft)) != EAS_SUCCESS)
- {
- pState->state = EAS_STATE_ERROR;
- return result;
- }
- *pLocation -= pState->bytesLeft;
- pState->bytesLeft = 0;
- pState->flags |= PCM_FLAGS_EMPTY;
-
- /* retrieve more data */
- if (pState->pCallback)
- (*pState->pCallback)(pEASData, pState->cbInstData, pState, EAS_STATE_EMPTY);
-
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "EAS_PESeek: bytesLeft=%d, byte location = %d\n", pState->bytesLeft, *pLocation); */ }
-
- /* no more samples */
- if (pState->bytesLeft == 0)
- return EAS_ERROR_LOCATE_BEYOND_END;
- }
-
- /* seek to new offset in current chunk */
- if (*pLocation > 0)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "EAS_PESeek: Seek to offset = %d\n", *pLocation); */ }
- if ((result = EAS_HWFileSeekOfs(pEASData->hwInstData, pState->fileHandle, *pLocation)) != EAS_SUCCESS)
- {
- pState->state = EAS_STATE_ERROR;
- return result;
- }
-
- /* if not streamed, calculate number of bytes left */
- if (pState->flags & PCM_FLAGS_STREAMING)
- pState->bytesLeft = 0x7fffffff;
- else
- pState->bytesLeft -= *pLocation;
- }
- return EAS_SUCCESS;
-}
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 849 $
+ * $Date: 2007-08-28 08:59:11 -0700 (Tue, 28 Aug 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+#include "eas_data.h"
+#include "eas_report.h"
+#include "eas_host.h"
+#include "eas_config.h"
+#include "eas_parser.h"
+#include "eas_pcm.h"
+#include "eas_math.h"
+#include "eas_mixer.h"
+
+#define PCM_MIXER_GUARD_BITS (NUM_MIXER_GUARD_BITS + 1)
+
+/*----------------------------------------------------------------------------
+ * Decoder interfaces
+ *----------------------------------------------------------------------------
+*/
+
+static EAS_RESULT LinearPCMDecode (EAS_DATA_HANDLE pEASData, S_PCM_STATE *pState);
+static EAS_RESULT LinearPCMLocate (EAS_DATA_HANDLE pEASData, S_PCM_STATE *pState, EAS_I32 time);
+
+static const S_DECODER_INTERFACE PCMDecoder =
+{
+ NULL,
+ LinearPCMDecode,
+ LinearPCMLocate,
+};
+
+/* SMAF ADPCM decoder */
+#ifdef _SMAF_PARSER
+extern S_DECODER_INTERFACE SmafDecoder;
+#define SMAF_DECODER &SmafDecoder
+extern S_DECODER_INTERFACE Smaf7BitDecoder;
+#define SMAF_7BIT_DECODER &Smaf7BitDecoder
+#else
+#define SMAF_DECODER NULL
+#define SMAF_7BIT_DECODER NULL
+#endif
+
+/* IMA ADPCM decoder */
+#ifdef _IMA_DECODER
+extern S_DECODER_INTERFACE IMADecoder;
+#define IMA_DECODER &IMADecoder
+#else
+#define IMA_DECODER NULL
+#endif
+
+static const S_DECODER_INTERFACE * const decoders[] =
+{
+ &PCMDecoder,
+ SMAF_DECODER,
+ IMA_DECODER,
+ SMAF_7BIT_DECODER
+};
+
+/*----------------------------------------------------------------------------
+ * Sample rate conversion
+ *----------------------------------------------------------------------------
+*/
+
+#define SRC_RATE_MULTIPLER (0x40000000 / _OUTPUT_SAMPLE_RATE)
+
+#ifdef _LOOKUP_SAMPLE_RATE
+static const EAS_U32 srcConvRate[][2] =
+{
+ 4000L, (4000L << 15) / _OUTPUT_SAMPLE_RATE,
+ 8000L, (8000L << 15) / _OUTPUT_SAMPLE_RATE,
+ 11025L, (11025L << 15) / _OUTPUT_SAMPLE_RATE,
+ 12000L, (12000L << 15) / _OUTPUT_SAMPLE_RATE,
+ 16000L, (16000L << 15) / _OUTPUT_SAMPLE_RATE,
+ 22050L, (22050L << 15) / _OUTPUT_SAMPLE_RATE,
+ 24000L, (24000L << 15) / _OUTPUT_SAMPLE_RATE,
+ 32000L, (32000L << 15) / _OUTPUT_SAMPLE_RATE
+};
+static EAS_U32 CalcBaseFreq (EAS_U32 sampleRate);
+#define SRC_CONV_RATE_ENTRIES (sizeof(srcConvRate)/sizeof(EAS_U32)/2)
+#endif
+
+
+/* interface prototypes */
+static EAS_RESULT RenderPCMStream (S_EAS_DATA *pEASData, S_PCM_STATE *pState, EAS_I32 numSamples);
+
+
+/* local prototypes */
+static S_PCM_STATE *FindSlot (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle, EAS_PCM_CALLBACK pCallbackFunc, EAS_VOID_PTR cbInstData);
+static EAS_RESULT InitPCMStream (S_EAS_DATA *pEASData, S_PCM_STATE *pState);
+
+/*----------------------------------------------------------------------------
+ * EAS_PEInit()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Initializes the PCM engine
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_PEInit (S_EAS_DATA *pEASData)
+{
+ S_PCM_STATE *pState;
+ EAS_INT i;
+
+ /* check for static memory allocation */
+ if (pEASData->staticMemoryModel)
+ pEASData->pPCMStreams = EAS_CMEnumData(EAS_CM_PCM_DATA);
+ /* allocate dynamic memory */
+ else
+ pEASData->pPCMStreams = EAS_HWMalloc(pEASData->hwInstData, sizeof(S_PCM_STATE) * MAX_PCM_STREAMS);
+
+ if (!pEASData->pPCMStreams)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_FATAL, "Failed to allocate memory for PCM streams\n"); */ }
+ return EAS_ERROR_MALLOC_FAILED;
+ }
+
+ //zero the memory to insure complete initialization
+ EAS_HWMemSet((void *)(pEASData->pPCMStreams),0, sizeof(S_PCM_STATE) * MAX_PCM_STREAMS);
+
+ /* initialize the state data */
+ for (i = 0, pState = pEASData->pPCMStreams; i < MAX_PCM_STREAMS; i++, pState++)
+ pState->fileHandle = NULL;
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_PEShutdown()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Shuts down the PCM engine
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_PEShutdown (S_EAS_DATA *pEASData)
+{
+
+ /* free any dynamic memory */
+ if (!pEASData->staticMemoryModel)
+ {
+ if (pEASData->pPCMStreams)
+ {
+ EAS_HWFree(pEASData->hwInstData, pEASData->pPCMStreams);
+ pEASData->pPCMStreams = NULL;
+ }
+ }
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_PERender()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Render a buffer of PCM audio
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_PERender (S_EAS_DATA* pEASData, EAS_I32 numSamples)
+{
+ S_PCM_STATE *pState;
+ EAS_RESULT result;
+ EAS_INT i;
+
+ /* render all the active streams */
+ for (i = 0, pState = pEASData->pPCMStreams; i < MAX_PCM_STREAMS; i++, pState++)
+ {
+ if ((pState->fileHandle) && (pState->state != EAS_STATE_STOPPED) && (pState->state != EAS_STATE_PAUSED))
+ if ((result = RenderPCMStream(pEASData, pState, numSamples)) != EAS_SUCCESS)
+ return result;
+ }
+ return EAS_SUCCESS;
+}
+
+
+/*----------------------------------------------------------------------------
+ * EAS_PEState()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Returns the current state of the stream
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ * pState - pointer to variable to store state
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ * Notes:
+ * This interface is also exposed in the internal library for use by the other modules.
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pEASData) reserved for future use */
+EAS_RESULT EAS_PEState (S_EAS_DATA *pEASData, EAS_PCM_HANDLE pInstData, EAS_STATE *pState)
+{
+ /* return current state */
+ *pState = pInstData->state;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_PEClose()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Close the file and clean up
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_PEClose (S_EAS_DATA *pEASData, EAS_PCM_HANDLE pState)
+{
+ EAS_RESULT result;
+
+ if ((result = EAS_HWCloseFile(pEASData->hwInstData, pState->fileHandle)) != EAS_SUCCESS)
+ return result;
+
+ pState->fileHandle = NULL;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * PCM_Reset()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Reset the sequencer. Used for locating backwards in the file.
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_PEReset (S_EAS_DATA *pEASData, EAS_PCM_HANDLE pState)
+{
+ EAS_RESULT result;
+
+ /* reset file position to first byte of data in the stream */
+ if ((result = EAS_HWFileSeek(pEASData->hwInstData, pState->fileHandle, pState->startPos)) != EAS_SUCCESS)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Error %d seeking to start of PCM file\n", result); */ }
+ return result;
+ }
+
+ /* re-initialize stream */
+ return InitPCMStream(pEASData, pState);
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_PEOpenStream()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Starts up a PCM playback
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_PEOpenStream (S_EAS_DATA *pEASData, S_PCM_OPEN_PARAMS *pParams, EAS_PCM_HANDLE *pHandle)
+{
+ EAS_RESULT result;
+ S_PCM_STATE *pState;
+ EAS_I32 filePos;
+
+ /* make sure we support this decoder */
+ if (pParams->decoder >= NUM_DECODER_MODULES)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Decoder selector out of range\n"); */ }
+ return EAS_ERROR_PARAMETER_RANGE;
+ }
+ if (decoders[pParams->decoder] == NULL)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Decoder module not available\n"); */ }
+ return EAS_ERROR_FEATURE_NOT_AVAILABLE;
+ }
+
+ /* find a slot for the new stream */
+ if ((pState = FindSlot(pEASData, pParams->fileHandle, pParams->pCallbackFunc, pParams->cbInstData)) == NULL)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Unable to open ADPCM stream, too many streams open\n"); */ }
+ return EAS_ERROR_MAX_PCM_STREAMS;
+ }
+
+ /* get the current file position */
+ if ((result = EAS_HWFilePos(pEASData->hwInstData, pState->fileHandle, &filePos)) != EAS_SUCCESS)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "EAS_HWFilePos returned %ld\n",result); */ }
+ pState->fileHandle = NULL;
+ return result;
+ }
+
+ pState->pDecoder = decoders[pParams->decoder];
+ pState->startPos = filePos;
+ pState->bytesLeftLoop = pState->byteCount = pParams->size;
+ pState->loopStart = pParams->loopStart;
+ pState->samplesTilLoop = (EAS_I32) pState->loopStart;
+ pState->loopSamples = pParams->loopSamples;
+ pState->samplesInLoop = 0;
+ pState->blockSize = (EAS_U16) pParams->blockSize;
+ pState->flags = pParams->flags;
+ pState->envData = pParams->envData;
+ pState->volume = pParams->volume;
+ pState->sampleRate = (EAS_U16) pParams->sampleRate;
+
+ /* set the base frequency */
+ pState->basefreq = (SRC_RATE_MULTIPLER * (EAS_U32) pParams->sampleRate) >> 15;
+
+ /* calculate shift for frequencies > 1.0 */
+ pState->rateShift = 0;
+ while (pState->basefreq > 32767)
+ {
+ pState->basefreq = pState->basefreq >> 1;
+ pState->rateShift++;
+ }
+
+ /* initialize */
+ if ((result = InitPCMStream(pEASData, pState)) != EAS_SUCCESS)
+ return result;
+
+ *pHandle = pState;
+
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "EAS_PEOpenStream: StartPos=%d, byteCount = %d, loopSamples=%d\n",
+ pState->startPos, pState->byteCount, pState->loopSamples); */ }
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_PEContinueStream()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Continues a PCM stream
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -e{715} reserved for future use */
+EAS_RESULT EAS_PEContinueStream (S_EAS_DATA *pEASData, EAS_PCM_HANDLE pState, EAS_I32 size)
+{
+
+ /* add new samples to count */
+ pState->bytesLeft += size;
+ if (pState->bytesLeft > 0)
+ pState->flags &= ~PCM_FLAGS_EMPTY;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_PEGetFileHandle()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Returns the file handle of a stream
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pEASData) reserved for future use */
+EAS_RESULT EAS_PEGetFileHandle (S_EAS_DATA *pEASData, EAS_PCM_HANDLE pState, EAS_FILE_HANDLE *pFileHandle)
+{
+ *pFileHandle = pState->fileHandle;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_PEUpdateParams()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Update the pitch and volume parameters for a PCM stream
+ *
+ * Inputs:
+ * pEASData - pointer to EAS library instance data
+ * handle - pointer to S_PCM_STATE for this stream
+ * gainLeft - linear gain multipler in 1.15 fraction format
+ * gainRight - linear gain multipler in 1.15 fraction format
+ * pitch - pitch shift in cents
+ * initial - initial settings, set current gain
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ * Notes
+ * In mono mode, leftGain controls the output gain and rightGain is ignored
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pEASData) reserved for future use */
+/*lint -esym(715, gainRight) used only in 2-channel version */
+EAS_RESULT EAS_PEUpdateParams (S_EAS_DATA* pEASData, EAS_PCM_HANDLE pState, EAS_I16 pitch, EAS_I16 gainLeft, EAS_I16 gainRight)
+{
+
+ pState->gainLeft = gainLeft;
+
+#if (NUM_OUTPUT_CHANNELS == 2)
+ pState->gainRight = gainRight;
+#endif
+
+ pState->pitch = pitch;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_PELocate()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * This function seeks to the requested place in the file. Accuracy
+ * is dependent on the sample rate and block size.
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * pState - stream handle
+ * time - media time in milliseconds
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_PELocate (S_EAS_DATA *pEASData, EAS_PCM_HANDLE pState, EAS_I32 time)
+{
+ if (pState->pDecoder->pfLocate == NULL)
+ return EAS_ERROR_FEATURE_NOT_AVAILABLE;
+
+ return pState->pDecoder->pfLocate(pEASData, pState, time);
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_PEUpdateVolume()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Update the volume parameters for a PCM stream
+ *
+ * Inputs:
+ * pEASData - pointer to EAS library instance data
+ * handle - pointer to S_PCM_STATE for this stream
+ * gainLeft - linear gain multipler in 1.15 fraction format
+ * gainRight - linear gain multipler in 1.15 fraction format
+ * initial - initial settings, set current gain
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ * Notes
+ * In mono mode, leftGain controls the output gain and rightGain is ignored
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pEASData) reserved for future use */
+EAS_RESULT EAS_PEUpdateVolume (S_EAS_DATA* pEASData, EAS_PCM_HANDLE pState, EAS_I16 volume)
+{
+ pState->volume = volume;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_PEUpdatePitch()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Update the pitch parameter for a PCM stream
+ *
+ * Inputs:
+ * pEASData - pointer to EAS library instance data
+ * pState - pointer to S_PCM_STATE for this stream
+ * pitch - new pitch value in pitch cents
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pEASData) reserved for future use */
+EAS_RESULT EAS_PEUpdatePitch (S_EAS_DATA* pEASData, EAS_PCM_HANDLE pState, EAS_I16 pitch)
+{
+ pState->pitch = pitch;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_PEPause()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Mute and stop rendering a PCM stream. Sets the gain target to zero and stops the playback
+ * at the end of the next audio frame.
+ *
+ * Inputs:
+ * pEASData - pointer to EAS library instance data
+ * handle - pointer to S_PCM_STATE for this stream
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pEASData) reserved for future use */
+EAS_RESULT EAS_PEPause (S_EAS_DATA *pEASData, EAS_PCM_HANDLE pState)
+{
+ /* set state to stopping */
+ pState->state = EAS_STATE_PAUSING;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_PEResume()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Resume rendering a PCM stream. Sets the gain target back to its
+ * previous setting and restarts playback at the end of the next audio
+ * frame.
+ *
+ * Inputs:
+ * pEASData - pointer to EAS library instance data
+ * handle - pointer to S_PCM_STATE for this stream
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pEASData) reserved for future use */
+EAS_RESULT EAS_PEResume (S_EAS_DATA *pEASData, EAS_PCM_HANDLE pState)
+{
+ /* set state to stopping */
+ pState->state = EAS_STATE_PLAY;
+ return EAS_SUCCESS;
+}
+
+EAS_U32 getDecayScale(EAS_U32 index)
+{
+ EAS_U32 utemp;
+
+ //envelope decay segment
+ switch (index)
+ {
+ case 0: //no decay
+ utemp = 512;//32768;
+ break;
+ case 1: //.0156 dB per update
+ utemp = 511;//32709;
+ break;
+ case 2: //.03125
+ utemp = 510;//32649;
+ break;
+ case 3: //.0625
+ utemp = 508;//32532;
+ break;
+ case 4: //.125
+ utemp = 505;//32298;
+ break;
+ case 5: //.25
+ utemp = 497;//31835;
+ break;
+ case 6: //.5
+ utemp = 483;//30929;
+ break;
+ case 7: //1.0
+ utemp = 456;//29193;
+ break;
+ case 8: //2.0
+ utemp = 406;//26008;
+ break;
+ case 9: //4.0
+ utemp = 323;//20642;
+ break;
+ case 10: //8.0
+ utemp = 203;//13004;
+ break;
+ case 11: //16.0
+ utemp = 81;//5160;
+ break;
+ case 12: //32.0
+ utemp = 13;//813;
+ break;
+ case 13: //64.0
+ utemp = 0;//20;
+ break;
+ case 14: //128.0
+ utemp = 0;
+ break;
+ case 15: //256.0
+ default:
+ utemp = 0;
+ break;
+ }
+ //printf("getdecayscale returned %d\n",utemp);
+ return utemp;
+}
+
+EAS_U32 getAttackIncrement(EAS_U32 index)
+{
+ EAS_U32 utemp;
+
+ //envelope decay segment
+ switch (index)
+ {
+ case 0:
+ utemp = 32;
+ break;
+ case 1:
+ utemp = 64;
+ break;
+ case 2:
+ utemp = 128;
+ break;
+ case 3:
+ utemp = 256;
+ break;
+ case 4:
+ utemp = 512;
+ break;
+ case 5:
+ utemp = 1024;
+ break;
+ case 6:
+ utemp = 2048;
+ break;
+ case 7:
+ utemp = 4096;
+ break;
+ case 8:
+ utemp = 8192;
+ break;
+ case 9:
+ utemp = 16384;
+ break;
+ case 10:
+ utemp = 32768;
+ break;
+ case 11:
+ utemp = 65536;
+ break;
+ case 12:
+ utemp = 65536;
+ break;
+ case 13:
+ utemp = 65536;
+ break;
+ case 14:
+ utemp = 65535;
+ break;
+ case 15:
+ default:
+ utemp = 0;
+ break;
+ }
+ //printf("getattackincrement returned %d\n",utemp);
+ return utemp;
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_PERelease()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Put the PCM stream envelope into release.
+ *
+ * Inputs:
+ * pEASData - pointer to EAS library instance data
+ * handle - pointer to S_PCM_STATE for this stream
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pEASData) reserved for future use */
+EAS_RESULT EAS_PERelease (S_EAS_DATA *pEASData, EAS_PCM_HANDLE pState)
+{
+ EAS_U32 utemp;
+
+ //printf("handling note-off part of envelope\n");
+ /*if the note is not ignore release or sustained*/
+ if (((pState->envData >> 24) & 0x0F)==0)
+ {
+ /* set envelope state to release */
+ pState->envState = PCM_ENV_RELEASE;
+ utemp = ((pState->envData >> 20) & 0x0F);
+ pState->envScale = getDecayScale(utemp); //getReleaseScale(utemp);
+ }
+ else
+ {
+ /*else change envelope state to sustain */
+ pState->envState = PCM_ENV_SUSTAIN;
+ utemp = ((pState->envData >> 28) & 0x0F);
+ pState->envScale = getDecayScale(utemp); //getSustainScale(utemp);
+ }
+ //since we are in release, don't let anything hang around too long
+ //printf("checking env scale, val = %d\n",((S_PCM_STATE*) handle)->envScale);
+ if (pState->envScale > 505)
+ pState->envScale = 505;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * FindSlot()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Locates an empty stream slot and assigns the file handle
+ *
+ * Inputs:
+ * pEASData - pointer to EAS library instance data
+ * fileHandle - file handle
+ * pCallbackFunc - function to be called back upon EAS_STATE_STOPPED
+ *
+ * Outputs:
+ * returns handle to slot or NULL if all slots are used
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static S_PCM_STATE *FindSlot (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle, EAS_PCM_CALLBACK pCallbackFunc, EAS_VOID_PTR cbInstData)
+{
+ EAS_INT i;
+ S_PCM_STATE *pState;
+
+#ifndef NO_PCM_STEAL
+ S_PCM_STATE *foundState = NULL;
+ EAS_INT count = 0;
+ EAS_U32 startOrder = 0xFFFFFFFF;
+ S_PCM_STATE *stealState = NULL;
+ EAS_U32 youngest = 0;
+
+ /* find an empty slot, count total in use, and find oldest in use (lowest start order) */
+ for (i = 0, pState = pEASData->pPCMStreams; i < MAX_PCM_STREAMS; i++, pState++)
+ {
+ /* if this one is available */
+ if (pState->fileHandle == NULL)
+ {
+ foundState = pState;
+ }
+ /* else this one is in use, so see if it is the oldest, and count total in use */
+ /* also find youngest */
+ else
+ {
+ /*one more voice in use*/
+ count++;
+ /* is this the oldest? (lowest start order) */
+ if ((pState->state != EAS_STATE_STOPPING) && (pState->startOrder < startOrder))
+ {
+ /* remember this one */
+ stealState = pState;
+ /* remember the oldest so far */
+ startOrder = pState->startOrder;
+ }
+ /* is this the youngest? (highest start order) */
+ if (pState->startOrder >= youngest)
+ {
+ youngest = pState->startOrder;
+ }
+ }
+ }
+
+ /* if there are too many voices active, stop the oldest one */
+ if (count > PCM_STREAM_THRESHOLD)
+ {
+ //printf("stealing!!!\n");
+ /* make sure we got one, although we should always have one at this point */
+ if (stealState != NULL)
+ {
+ //flag this as stopping, so it will get shut off
+ stealState->state = EAS_STATE_STOPPING;
+ }
+ }
+
+ /* if there are no available open streams (we won't likely see this, due to stealing) */
+ if (foundState == NULL)
+ return NULL;
+
+ /* save info */
+ foundState->startOrder = youngest + 1;
+ foundState->fileHandle = fileHandle;
+ foundState->pCallback = pCallbackFunc;
+ foundState->cbInstData = cbInstData;
+ return foundState;
+#else
+ /* find an empty slot*/
+ for (i = 0; i < MAX_PCM_STREAMS; i++)
+ {
+ pState = &pEASData->pPCMStreams[i];
+ if (pState->fileHandle != NULL)
+ continue;
+
+ pState->fileHandle = fileHandle;
+ pState->pCallback = pCallbackFunc;
+ pState->cbInstData = cbInstData;
+ return pState;
+ }
+ return NULL;
+#endif
+}
+
+#ifdef _LOOKUP_SAMPLE_RATE
+/*----------------------------------------------------------------------------
+ * CalcBaseFreq()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Calculates the fractional phase increment for the sample rate converter
+ *
+ * Inputs:
+ * sampleRate - sample rate in samples/sec
+ *
+ * Outputs:
+ * Returns fractional sample rate with a 15-bit fraction
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_U32 CalcBaseFreq (EAS_U32 sampleRate)
+{
+ EAS_INT i;
+
+ /* look up the conversion rate */
+ for (i = 0; i < (EAS_INT)(SRC_CONV_RATE_ENTRIES); i ++)
+ {
+ if (srcConvRate[i][0] == sampleRate)
+ return srcConvRate[i][1];
+ }
+
+ /* if not found in table, do it the long way */
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Sample rate %u not in table, calculating by division\n", sampleRate); */ }
+
+ return (SRC_RATE_MULTIPLER * (EAS_U32) sampleRate) >> 15;
+}
+#endif
+
+/*----------------------------------------------------------------------------
+ * InitPCMStream()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Start an ADPCM stream playback. Decodes the header, preps the engine.
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT InitPCMStream (S_EAS_DATA *pEASData, S_PCM_STATE *pState)
+{
+
+ /* initialize the data structure */
+ pState->bytesLeft = pState->byteCount;
+ pState->phase = 0;
+ pState->srcByte = 0;
+ pState->decoderL.acc = 0;
+ pState->decoderL.output = 0;
+ pState->decoderL.x0 = pState->decoderL.x1 = 0;
+ pState->decoderL.step = 0;
+ pState->decoderR.acc = 0;
+ pState->decoderR.output = 0;
+ pState->decoderR.x0 = pState->decoderR.x1 = 0;
+ pState->decoderR.step = 0;
+ pState->hiNibble = EAS_FALSE;
+ pState->pitch = 0;
+ pState->blockCount = 0;
+ pState->gainLeft = PCM_DEFAULT_GAIN_SETTING;
+// pState->currentGainLeft = PCM_DEFAULT_GAIN_SETTING;
+ pState->envValue = 0;
+ pState->envState = PCM_ENV_START;
+
+#if (NUM_OUTPUT_CHANNELS == 2)
+ pState->gainRight = PCM_DEFAULT_GAIN_SETTING;
+// pState->currentGainRight = PCM_DEFAULT_GAIN_SETTING;
+#endif
+ pState->state = EAS_STATE_READY;
+
+ /* initialize the decoder */
+ if (pState->pDecoder->pfInit)
+ return (*pState->pDecoder->pfInit)(pEASData, pState);
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * RenderPCMStream()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Decodes a buffer of ADPCM data.
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT RenderPCMStream (S_EAS_DATA *pEASData, S_PCM_STATE *pState, EAS_I32 numSamples)
+{
+ EAS_RESULT result;
+ EAS_U32 phaseInc;
+ EAS_I32 gainLeft, gainIncLeft;
+ EAS_I32 *pOut;
+ EAS_I32 temp;
+ EAS_U32 utemp;
+
+#if (NUM_OUTPUT_CHANNELS == 2)
+ EAS_I32 gainRight, gainIncRight;
+#endif
+
+#if 0
+ printf("env data: AR = %d, DR = %d, SL = %d, SR = %d, RR = %d\n",
+ ((pState->envData >> 12) & 0x0F),
+ ((pState->envData >> 16) & 0x0F),
+ ((pState->envData >> 8) & 0x0F),
+ ((pState->envData >> 28) & 0x0F),
+ ((pState->envData >> 20) & 0x0F));
+#endif
+
+ if (pState->envState == PCM_ENV_START)
+ {
+ //printf("env start\n");
+ utemp = ((pState->envData >> 12) & 0x0F);
+ //if fastest rate, attack is already completed
+ //do the same for slowest rate, since that allows zero to be passed for default envelope
+ if (utemp == 0x0F || utemp == 0x00)
+ {
+ //start envelope at full
+ pState->envValue = (32768<<7);
+ //jump right into decay
+ utemp = ((pState->envData >> 16) & 0x0F);
+ pState->envScale = getDecayScale(utemp);
+ pState->envState = PCM_ENV_DECAY;
+ pState->currentGainLeft = (EAS_I16) FMUL_15x15(pState->gainLeft, pState->volume);
+ pState->currentGainRight = (EAS_I16) FMUL_15x15(pState->gainRight, pState->volume);
+ }
+ //else attack has a ramp
+ else
+ {
+ //start the envelope very low
+ pState->envValue = (2<<7);
+ pState->currentGainLeft = 0;
+ pState->currentGainRight = 0;
+ //get envelope attack scaling value
+ pState->envScale = getAttackIncrement(utemp);
+ //go to attack state
+ pState->envState = PCM_ENV_ATTACK;
+ }
+ }
+ if (pState->envState == PCM_ENV_ATTACK)
+ {
+ //printf("env attack, env value = %d, env scale = %d\n",pState->envValue>>7,pState->envScale);
+ //update envelope value
+ pState->envValue = pState->envValue + (pState->envScale << 7);
+ //check envelope level and update state if needed
+ if (pState->envValue >= (32768<<7))
+ {
+ pState->envValue = (32768<<7);
+ utemp = ((pState->envData >> 16) & 0x0F);
+ pState->envScale = getDecayScale(utemp);
+ pState->envState = PCM_ENV_DECAY;
+ }
+ }
+ else if (pState->envState == PCM_ENV_DECAY)
+ {
+ //printf("env decay, env value = %d, env scale = %d\n",pState->envValue>>7,pState->envScale);
+ //update envelope value
+ pState->envValue = (pState->envValue * pState->envScale)>>9;
+ //check envelope level against sustain level and update state if needed
+ utemp = ((pState->envData >> 8) & 0x0F);
+ if (utemp == (EAS_U32)0x0F)
+ utemp = (2<<7);
+ else
+ {
+ utemp = ((32769<<7) >> (utemp>>1));
+ }
+ if (pState->envValue <= utemp)
+ {
+ utemp = ((pState->envData >> 28) & 0x0F);
+ pState->envScale = getDecayScale(utemp); //getSustainScale(utemp);
+ pState->envState = PCM_ENV_SUSTAIN;
+ }
+ }
+ else if (pState->envState == PCM_ENV_SUSTAIN)
+ {
+ //printf("env sustain, env value = %d, env scale = %d\n",pState->envValue>>7,pState->envScale);
+ //update envelope value
+ pState->envValue = (pState->envValue * pState->envScale)>>9;
+ //check envelope level against bottom level and update state if needed
+ if (pState->envValue <= (2<<7))
+ {
+ //no more decay
+ pState->envScale = 512;
+ pState->envState = PCM_ENV_END;
+ }
+ }
+ else if (pState->envState == PCM_ENV_RELEASE)
+ {
+ //printf("env release, env value = %d, env scale = %d\n",pState->envValue>>7,pState->envScale);
+ //update envelope value
+ pState->envValue = (pState->envValue * pState->envScale)>>9;
+ //check envelope level against bottom level and update state if needed
+ if (pState->envValue <= (2<<7))
+ {
+ //no more decay
+ pState->envScale = 512;
+ pState->envState = PCM_ENV_END;
+ }
+ }
+ else if (pState->envState == PCM_ENV_END)
+ {
+ //printf("env end\n");
+ /* set state to stopping, already ramped down */
+ pState->state = EAS_STATE_STOPPING;
+ }
+
+ //pState->gainLeft = (EAS_U16)((pState->gainLeft * (pState->envValue>>7))>>15);
+ //pState->gainRight = (EAS_U16)((pState->gainRight * (pState->envValue>>7))>>15);
+
+ /* gain to 32-bits to increase resolution on anti-zipper filter */
+ /*lint -e{703} use shift for performance */
+ gainLeft = (EAS_I32) pState->currentGainLeft << SYNTH_UPDATE_PERIOD_IN_BITS;
+#if (NUM_OUTPUT_CHANNELS == 2)
+ /*lint -e{703} use shift for performance */
+ gainRight = (EAS_I32) pState->currentGainRight << SYNTH_UPDATE_PERIOD_IN_BITS;
+#endif
+
+ /* calculate a new gain increment, gain target is zero if pausing */
+ if ((pState->state == EAS_STATE_PAUSING) || (pState->state == EAS_STATE_PAUSED))
+ {
+ gainIncLeft = -pState->currentGainLeft;
+#if (NUM_OUTPUT_CHANNELS == 2)
+ gainIncRight= -pState->currentGainRight;
+#endif
+ }
+ else
+ {
+ EAS_I32 gain = FMUL_15x15(pState->envValue >> 7, pState->volume);
+ gainIncLeft = FMUL_15x15(pState->gainLeft, gain) - pState->currentGainLeft;
+#if (NUM_OUTPUT_CHANNELS == 2)
+ gainIncRight = FMUL_15x15(pState->gainRight, gain) - pState->currentGainRight;
+#endif
+ }
+
+ /* calculate phase increment */
+ phaseInc = pState->basefreq;
+
+ /* convert pitch cents to linear multiplier */
+ if (pState->pitch)
+ {
+ temp = EAS_Calculate2toX(pState->pitch);
+ phaseInc = FMUL_15x15(phaseInc, temp);
+ }
+ phaseInc = phaseInc << pState->rateShift;
+
+ /* pointer to mix buffer */
+ pOut = pEASData->pMixBuffer;
+
+ /* render a buffer of samples */
+ while (numSamples--)
+ {
+
+ /* interpolate an output sample */
+ pState->decoderL.output = pState->decoderL.x0 + FMUL_15x15((pState->decoderL.x1 - pState->decoderL.x0), pState->phase & PHASE_FRAC_MASK);
+
+ /* stereo output */
+#if (NUM_OUTPUT_CHANNELS == 2)
+
+ /* stereo stream? */
+ if (pState->flags & PCM_FLAGS_STEREO)
+ pState->decoderR.output = pState->decoderR.x0 + FMUL_15x15((pState->decoderR.x1 - pState->decoderR.x0), pState->phase & PHASE_FRAC_MASK);
+
+ /* gain scale and mix */
+ /*lint -e{704} use shift instead of division */
+ *pOut++ += (pState->decoderL.output * (gainLeft >> SYNTH_UPDATE_PERIOD_IN_BITS)) >> PCM_MIXER_GUARD_BITS;
+ gainLeft += gainIncLeft;
+
+ /*lint -e{704} use shift instead of division */
+ if (pState->flags & PCM_FLAGS_STEREO)
+ *pOut++ += (pState->decoderR.output * (gainRight >> SYNTH_UPDATE_PERIOD_IN_BITS)) >> PCM_MIXER_GUARD_BITS;
+ else
+ *pOut++ += (pState->decoderL.output * (gainRight >> SYNTH_UPDATE_PERIOD_IN_BITS)) >> PCM_MIXER_GUARD_BITS;
+
+ gainRight += gainIncRight;
+
+ /* mono output */
+#else
+ /* if stereo stream, decode right channel and mix to mono */
+ if (pState->flags & PCM_FLAGS_STEREO)
+ {
+ pState->decoderR.output= pState->decoderR.x0 + FMUL_15x15((pState->decoderR.x1 - pState->decoderR.x0), pState->phase & PHASE_FRAC_MASK);
+
+ /* for mono, sum stereo ADPCM to mono */
+ /*lint -e{704} use shift instead of division */
+ *pOut++ += ((pState->decoderL.output + pState->decoderR.output) * (gainLeft >> SYNTH_UPDATE_PERIOD_IN_BITS)) >> PCM_MIXER_GUARD_BITS;
+ }
+ else
+ /*lint -e{704} use shift instead of division */
+ *pOut++ += (pState->decoderL.output * (gainLeft >> SYNTH_UPDATE_PERIOD_IN_BITS)) >> PCM_MIXER_GUARD_BITS;
+
+ gainLeft += gainIncLeft;
+#endif
+
+ /* advance phase accumulator */
+ pState->phase += phaseInc;
+
+ /* if integer part of phase accumulator is non-zero, advance to next sample */
+ while (pState->phase & ~PHASE_FRAC_MASK)
+ {
+ pState->decoderL.x0 = pState->decoderL.x1;
+ pState->decoderR.x0 = pState->decoderR.x1;
+
+ /* give the source a chance to continue the stream */
+ if (!pState->bytesLeft && pState->pCallback && ((pState->flags & PCM_FLAGS_EMPTY) == 0))
+ {
+ pState->flags |= PCM_FLAGS_EMPTY;
+ (*pState->pCallback)(pEASData, pState->cbInstData, pState, EAS_STATE_EMPTY);
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "RenderPCMStream: After empty callback, bytesLeft = %d\n", pState->bytesLeft); */ }
+ }
+
+ /* decode the next sample */
+ if ((result = (*pState->pDecoder->pfDecodeSample)(pEASData, pState)) != EAS_SUCCESS)
+ return result;
+
+ /* adjust phase by one sample */
+ pState->phase -= (1L << NUM_PHASE_FRAC_BITS);
+ }
+
+ }
+
+ /* save new gain */
+ /*lint -e{704} use shift instead of division */
+ pState->currentGainLeft = (EAS_I16) (gainLeft >> SYNTH_UPDATE_PERIOD_IN_BITS);
+
+#if (NUM_OUTPUT_CHANNELS == 2)
+ /*lint -e{704} use shift instead of division */
+ pState->currentGainRight = (EAS_I16) (gainRight >> SYNTH_UPDATE_PERIOD_IN_BITS);
+#endif
+
+ /* if pausing, set new state and notify */
+ if (pState->state == EAS_STATE_PAUSING)
+ {
+ pState->state = EAS_STATE_PAUSED;
+ if (pState->pCallback)
+ (*pState->pCallback)(pEASData, pState->cbInstData, pState, pState->state);
+ }
+
+ /* if out of data, set stopped state and notify */
+ if (pState->bytesLeft == 0 || pState->state == EAS_STATE_STOPPING)
+ {
+ pState->state = EAS_STATE_STOPPED;
+
+ /* do callback unless the file has already been closed */
+ if (pState->pCallback && pState->fileHandle)
+ (*pState->pCallback)(pEASData, pState->cbInstData, pState, pState->state);
+ }
+
+ if (pState->state == EAS_STATE_READY)
+ pState->state = EAS_STATE_PLAY;
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * LinearPCMDecode()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Decodes a PCM sample
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT LinearPCMDecode (EAS_DATA_HANDLE pEASData, S_PCM_STATE *pState)
+{
+ EAS_RESULT result;
+ EAS_HW_DATA_HANDLE hwInstData;
+
+ hwInstData = ((S_EAS_DATA*) pEASData)->hwInstData;
+
+ /* if out of data, check for loop */
+ if ((pState->bytesLeft == 0) && (pState->loopSamples != 0))
+ {
+ if ((result = EAS_HWFileSeek(pEASData->hwInstData, pState->fileHandle, (EAS_I32) (pState->startPos + pState->loopLocation))) != EAS_SUCCESS)
+ return result;
+ pState->bytesLeft = pState->byteCount = (EAS_I32) pState->bytesLeftLoop;
+ pState->flags &= ~PCM_FLAGS_EMPTY;
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "LinearPCMDecode: Rewind file to %d, bytesLeft = %d\n", pState->startPos, pState->bytesLeft); */ }
+ }
+
+ if (pState->bytesLeft)
+ {
+
+ /* check format byte for 8-bit samples */
+ if (pState->flags & PCM_FLAGS_8_BIT)
+ {
+ /* fetch left or mono sample */
+ if ((result = EAS_HWGetByte(hwInstData, pState->fileHandle, &pState->srcByte)) != EAS_SUCCESS)
+ return result;
+
+ /* if unsigned */
+ if (pState->flags & PCM_FLAGS_UNSIGNED)
+ {
+ /*lint -e{734} converting unsigned 8-bit to signed 16-bit */
+ pState->decoderL.x1 = (EAS_PCM)(((EAS_PCM) pState->srcByte << 8) ^ 0x8000);
+ }
+ else
+ {
+ /*lint -e{734} converting signed 8-bit to signed 16-bit */
+ pState->decoderL.x1 = (EAS_PCM)((EAS_PCM) pState->srcByte << 8);
+ }
+ pState->bytesLeft--;
+
+ /* fetch right sample */
+ if(pState->flags & PCM_FLAGS_STEREO)
+ {
+ if ((result = EAS_HWGetByte(hwInstData, pState->fileHandle, &pState->srcByte)) != EAS_SUCCESS)
+ return result;
+
+ /* if unsigned */
+ if (pState->flags & PCM_FLAGS_UNSIGNED)
+ {
+ /*lint -e{734} converting unsigned 8-bit to signed 16-bit */
+ pState->decoderR.x1 = (EAS_PCM)(((EAS_PCM) pState->srcByte << 8) ^ 0x8000);
+ }
+ else
+ {
+ /*lint -e{734} converting signed 8-bit to signed 16-bit */
+ pState->decoderR.x1 = (EAS_PCM)((EAS_PCM) pState->srcByte << 8);
+ }
+ pState->bytesLeft--;
+ }
+ }
+
+ /* must be 16-bit samples */
+ else
+ {
+ //unsigned 16 bit currently not supported
+ if (pState->flags & PCM_FLAGS_UNSIGNED)
+ {
+ return EAS_ERROR_INVALID_PCM_TYPE;
+ }
+
+ /* fetch left or mono sample */
+ if ((result = EAS_HWGetWord(hwInstData, pState->fileHandle, &pState->decoderL.x1, EAS_FALSE)) != EAS_SUCCESS)
+ return result;
+ pState->bytesLeft -= 2;
+
+ /* fetch right sample */
+ if(pState->flags & PCM_FLAGS_STEREO)
+ {
+ if ((result = EAS_HWGetWord(hwInstData, pState->fileHandle, &pState->decoderR.x1, EAS_FALSE)) != EAS_SUCCESS)
+ return result;
+ pState->bytesLeft -= 2;
+ }
+ }
+ }
+
+ /* no more data, force zero samples */
+ else
+ pState->decoderL.x1 = pState->decoderR.x1 = 0;
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * LinearPCMLocate()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Locate in a linear PCM stream
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT LinearPCMLocate (EAS_DATA_HANDLE pEASData, S_PCM_STATE *pState, EAS_I32 time)
+{
+ EAS_RESULT result;
+ EAS_I32 temp;
+ EAS_I32 secs, msecs;
+ EAS_INT shift;
+
+ /* calculate size of sample frame */
+ if (pState->flags & PCM_FLAGS_8_BIT)
+ shift = 0;
+ else
+ shift = 1;
+ if (pState->flags & PCM_FLAGS_STEREO)
+ shift++;
+
+ /* break down into secs and msecs */
+ secs = time / 1000;
+ msecs = time - (secs * 1000);
+
+ /* calculate sample number fraction from msecs */
+ temp = (msecs * pState->sampleRate);
+ temp = (temp >> 10) + ((temp * 49) >> 21);
+
+ /* add integer sample count */
+ temp += secs * pState->sampleRate;
+
+ /* calculate the position based on sample frame size */
+ /*lint -e{703} use shift for performance */
+ temp <<= shift;
+
+ /* past end of sample? */
+ if (temp > (EAS_I32) pState->loopStart)
+ {
+ /* if not looped, flag error */
+ if (pState->loopSamples == 0)
+ {
+ pState->bytesLeft = 0;
+ pState->flags |= PCM_FLAGS_EMPTY;
+ return EAS_ERROR_LOCATE_BEYOND_END;
+ }
+
+ /* looped sample - calculate position in loop */
+ while (temp > (EAS_I32) pState->loopStart)
+ temp -= (EAS_I32) pState->loopStart;
+ }
+
+ /* seek to new position */
+ if ((result = EAS_PESeek(pEASData, pState, &temp)) != EAS_SUCCESS)
+ return result;
+
+ /* reset state */
+ if ((pState->state != EAS_STATE_PAUSING) && (pState->state != EAS_STATE_PAUSED))
+ pState->state = EAS_STATE_READY;
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_PESeek
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Locate to a particular byte in a PCM stream
+ *----------------------------------------------------------------------------
+ * This bit is tricky because the chunks may not be contiguous,
+ * so we have to rely on the parser to position in the file. We
+ * do this by seeking to the end of each chunk and simulating an
+ * empty buffer condition until we get to where we want to go.
+ *
+ * A better solution would be a parser API for re-positioning,
+ * but there isn't time at the moment to re-factor all the
+ * parsers to support a new API.
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_PESeek (S_EAS_DATA *pEASData, S_PCM_STATE *pState, EAS_I32 *pLocation)
+{
+ EAS_RESULT result;
+
+ /* seek to start of audio */
+ if ((result = EAS_HWFileSeek(pEASData->hwInstData, pState->fileHandle, pState->startPos)) != EAS_SUCCESS)
+ {
+ pState->state = EAS_STATE_ERROR;
+ return result;
+ }
+ pState->bytesLeft = pState->bytesLeftLoop;
+
+ /* skip through chunks until we find the right chunk */
+ while (*pLocation > (EAS_I32) pState->bytesLeft)
+ {
+ /* seek to end of audio chunk */
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "EAS_PESeek: Seek to offset = %d\n", pState->bytesLeft); */ }
+ if ((result = EAS_HWFileSeekOfs(pEASData->hwInstData, pState->fileHandle, pState->bytesLeft)) != EAS_SUCCESS)
+ {
+ pState->state = EAS_STATE_ERROR;
+ return result;
+ }
+ *pLocation -= pState->bytesLeft;
+ pState->bytesLeft = 0;
+ pState->flags |= PCM_FLAGS_EMPTY;
+
+ /* retrieve more data */
+ if (pState->pCallback)
+ (*pState->pCallback)(pEASData, pState->cbInstData, pState, EAS_STATE_EMPTY);
+
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "EAS_PESeek: bytesLeft=%d, byte location = %d\n", pState->bytesLeft, *pLocation); */ }
+
+ /* no more samples */
+ if (pState->bytesLeft == 0)
+ return EAS_ERROR_LOCATE_BEYOND_END;
+ }
+
+ /* seek to new offset in current chunk */
+ if (*pLocation > 0)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "EAS_PESeek: Seek to offset = %d\n", *pLocation); */ }
+ if ((result = EAS_HWFileSeekOfs(pEASData->hwInstData, pState->fileHandle, *pLocation)) != EAS_SUCCESS)
+ {
+ pState->state = EAS_STATE_ERROR;
+ return result;
+ }
+
+ /* if not streamed, calculate number of bytes left */
+ if (pState->flags & PCM_FLAGS_STREAMING)
+ pState->bytesLeft = 0x7fffffff;
+ else
+ pState->bytesLeft -= *pLocation;
+ }
+ return EAS_SUCCESS;
+}
+
diff --git a/arm-hybrid-22k/lib_src/eas_pcm.h b/arm-hybrid-22k/lib_src/eas_pcm.h
index c161757..4fc77e9 100644
--- a/arm-hybrid-22k/lib_src/eas_pcm.h
+++ b/arm-hybrid-22k/lib_src/eas_pcm.h
@@ -1,13 +1,13 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_pcm.h
- *
- * Contents and purpose:
- * External function prototypes for eas_pcm.c module
- *
- *
- * Copyright Sonic Network Inc. 2005
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_pcm.h
+ *
+ * Contents and purpose:
+ * External function prototypes for eas_pcm.c module
+ *
+ *
+ * Copyright Sonic Network Inc. 2005
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,340 +20,340 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 847 $
- * $Date: 2007-08-27 21:30:08 -0700 (Mon, 27 Aug 2007) $
- *----------------------------------------------------------------------------
-*/
-
-#ifndef _EAS_PCM_H
-#define _EAS_PCM_H
-
-/* default gain setting - roughly unity gain */
-#define PCM_DEFAULT_GAIN_SETTING 0x6000
-
-typedef struct s_pcm_state_tag *EAS_PCM_HANDLE;
-typedef void (*EAS_PCM_CALLBACK) (EAS_DATA_HANDLE pEASData, EAS_VOID_PTR cbInstData, EAS_PCM_HANDLE pcmHandle, EAS_STATE state);
-
-/* parameters for EAS_PEOpenStream */
-typedef struct s_pcm_open_params_tag
-{
- EAS_FILE_HANDLE fileHandle;
- EAS_I32 decoder;
- EAS_U32 sampleRate;
- EAS_I32 size;
- EAS_U32 loopStart;
- EAS_U32 loopSamples;
- EAS_I32 blockSize;
- EAS_U32 flags;
- EAS_U32 envData;
- EAS_I16 volume;
- EAS_PCM_CALLBACK pCallbackFunc;
- EAS_VOID_PTR cbInstData;
- } S_PCM_OPEN_PARAMS;
-
-/*----------------------------------------------------------------------------
- * EAS_PEInit()
- *----------------------------------------------------------------------------
- * Purpose:
- * Initializes the PCM engine
- *
- * Inputs:
- *
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT EAS_PEInit (EAS_DATA_HANDLE pEASData);
-
-/*----------------------------------------------------------------------------
- * EAS_PEShutdown()
- *----------------------------------------------------------------------------
- * Purpose:
- * Shuts down the PCM engine
- *
- * Inputs:
- *
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT EAS_PEShutdown (EAS_DATA_HANDLE pEASData);
-
-/*----------------------------------------------------------------------------
- * EAS_PEOpenStream()
- *----------------------------------------------------------------------------
- * Purpose:
- * Starts up a PCM playback
- *
- * Inputs:
- *
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT EAS_PEOpenStream (EAS_DATA_HANDLE pEASData, S_PCM_OPEN_PARAMS *pParams, EAS_PCM_HANDLE *pHandle);
-
-/*----------------------------------------------------------------------------
- * EAS_PEContinueStream()
- *----------------------------------------------------------------------------
- * Purpose:
- * Continues a PCM stream
- *
- * Inputs:
- *
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT EAS_PEContinueStream (EAS_DATA_HANDLE pEASData, EAS_PCM_HANDLE handle, EAS_I32 size);
-
-/*----------------------------------------------------------------------------
- * EAS_PEGetFileHandle()
- *----------------------------------------------------------------------------
- * Purpose:
- * Returns the file handle of a stream
- *
- * Inputs:
- *
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT EAS_PEGetFileHandle (EAS_DATA_HANDLE pEASData, EAS_PCM_HANDLE handle, EAS_FILE_HANDLE *pFileHandle);
-
-/*----------------------------------------------------------------------------
- * EAS_PERender()
- *----------------------------------------------------------------------------
- * Purpose:
- * Render a buffer of PCM audio
- *
- * Inputs:
- *
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT EAS_PERender (EAS_DATA_HANDLE pEASData, EAS_I32 numSamples);
-
-/*----------------------------------------------------------------------------
- * EAS_PEUpdateParams()
- *----------------------------------------------------------------------------
- * Purpose:
- * Update the pitch and volume parameters using MIDI controls
- *
- * Inputs:
- *
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT EAS_PEUpdateParams (EAS_DATA_HANDLE pEASData, EAS_PCM_HANDLE pState, EAS_I16 pitch, EAS_I16 gainLeft, EAS_I16 gainRight);
-
-/*----------------------------------------------------------------------------
- * EAS_PELocate()
- *----------------------------------------------------------------------------
- * Purpose:
- * This function seeks to the requested place in the file. Accuracy
- * is dependent on the sample rate and block size.
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * pState - stream handle
- * time - media time in milliseconds
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT EAS_PELocate (EAS_DATA_HANDLE pEASData, EAS_PCM_HANDLE pState, EAS_I32 time);
-
-/*----------------------------------------------------------------------------
- * EAS_PEUpdateVolume()
- *----------------------------------------------------------------------------
- * Purpose:
- * Update the volume parameters for a PCM stream
- *
- * Inputs:
- * pEASData - pointer to EAS library instance data
- * handle - pointer to S_PCM_STATE for this stream
- * gainLeft - linear gain multipler in 1.15 fraction format
- * gainRight - linear gain multipler in 1.15 fraction format
- * initial - initial settings, set current gain
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- * Notes
- * In mono mode, leftGain controls the output gain and rightGain is ignored
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, pEASData) reserved for future use */
-EAS_RESULT EAS_PEUpdateVolume (EAS_DATA_HANDLE pEASData, EAS_PCM_HANDLE pState, EAS_I16 volume);
-
-/*----------------------------------------------------------------------------
- * EAS_PEUpdatePitch()
- *----------------------------------------------------------------------------
- * Purpose:
- * Update the pitch parameter for a PCM stream
- *
- * Inputs:
- * pEASData - pointer to EAS library instance data
- * pState - pointer to S_PCM_STATE for this stream
- * pitch - new pitch value in pitch cents
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, pEASData) reserved for future use */
-EAS_RESULT EAS_PEUpdatePitch (EAS_DATA_HANDLE pEASData, EAS_PCM_HANDLE pState, EAS_I16 pitch);
-
-/*----------------------------------------------------------------------------
- * EAS_PEState()
- *----------------------------------------------------------------------------
- * Purpose:
- * Returns the current state of the stream
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- * pState - pointer to variable to store state
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- * Notes:
- * This interface is also exposed in the internal library for use by the other modules.
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT EAS_PEState (EAS_DATA_HANDLE pEASData, EAS_PCM_HANDLE handle, EAS_STATE *pState);
-
-/*----------------------------------------------------------------------------
- * EAS_PEClose()
- *----------------------------------------------------------------------------
- * Purpose:
- * Close the file and clean up
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT EAS_PEClose (EAS_DATA_HANDLE pEASData, EAS_PCM_HANDLE handle);
-
-/*----------------------------------------------------------------------------
- * EAS_PEReset()
- *----------------------------------------------------------------------------
- * Purpose:
- * Reset the sequencer. Used for locating backwards in the file.
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT EAS_PEReset (EAS_DATA_HANDLE pEASData, EAS_PCM_HANDLE handle);
-
-/*----------------------------------------------------------------------------
- * EAS_PEPause()
- *----------------------------------------------------------------------------
- * Purpose:
- * Mute and pause rendering a PCM stream. Sets the gain target to zero and stops the playback
- * at the end of the next audio frame.
- *
- * Inputs:
- * pEASData - pointer to EAS library instance data
- * handle - pointer to S_PCM_STATE for this stream
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT EAS_PEPause (EAS_DATA_HANDLE pEASData, EAS_PCM_HANDLE handle);
-
-/*----------------------------------------------------------------------------
- * EAS_PEResume()
- *----------------------------------------------------------------------------
- * Purpose:
- * Resume rendering a PCM stream. Sets the gain target back to its
- * previous setting and restarts playback at the end of the next audio
- * frame.
- *
- * Inputs:
- * pEASData - pointer to EAS library instance data
- * handle - pointer to S_PCM_STATE for this stream
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT EAS_PEResume (EAS_DATA_HANDLE pEASData, EAS_PCM_HANDLE handle);
-
-/*----------------------------------------------------------------------------
- * EAS_PERelease()
- *----------------------------------------------------------------------------
- * Purpose:
- * Put the PCM stream envelope into release.
- *
- * Inputs:
- * pEASData - pointer to EAS library instance data
- * handle - pointer to S_PCM_STATE for this stream
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT EAS_PERelease (EAS_DATA_HANDLE pEASData, EAS_PCM_HANDLE handle);
-
-#endif /* end _EAS_PCM_H */
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 847 $
+ * $Date: 2007-08-27 21:30:08 -0700 (Mon, 27 Aug 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+#ifndef _EAS_PCM_H
+#define _EAS_PCM_H
+
+/* default gain setting - roughly unity gain */
+#define PCM_DEFAULT_GAIN_SETTING 0x6000
+
+typedef struct s_pcm_state_tag *EAS_PCM_HANDLE;
+typedef void (*EAS_PCM_CALLBACK) (EAS_DATA_HANDLE pEASData, EAS_VOID_PTR cbInstData, EAS_PCM_HANDLE pcmHandle, EAS_STATE state);
+
+/* parameters for EAS_PEOpenStream */
+typedef struct s_pcm_open_params_tag
+{
+ EAS_FILE_HANDLE fileHandle;
+ EAS_I32 decoder;
+ EAS_U32 sampleRate;
+ EAS_I32 size;
+ EAS_U32 loopStart;
+ EAS_U32 loopSamples;
+ EAS_I32 blockSize;
+ EAS_U32 flags;
+ EAS_U32 envData;
+ EAS_I16 volume;
+ EAS_PCM_CALLBACK pCallbackFunc;
+ EAS_VOID_PTR cbInstData;
+ } S_PCM_OPEN_PARAMS;
+
+/*----------------------------------------------------------------------------
+ * EAS_PEInit()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Initializes the PCM engine
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_PEInit (EAS_DATA_HANDLE pEASData);
+
+/*----------------------------------------------------------------------------
+ * EAS_PEShutdown()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Shuts down the PCM engine
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_PEShutdown (EAS_DATA_HANDLE pEASData);
+
+/*----------------------------------------------------------------------------
+ * EAS_PEOpenStream()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Starts up a PCM playback
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_PEOpenStream (EAS_DATA_HANDLE pEASData, S_PCM_OPEN_PARAMS *pParams, EAS_PCM_HANDLE *pHandle);
+
+/*----------------------------------------------------------------------------
+ * EAS_PEContinueStream()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Continues a PCM stream
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_PEContinueStream (EAS_DATA_HANDLE pEASData, EAS_PCM_HANDLE handle, EAS_I32 size);
+
+/*----------------------------------------------------------------------------
+ * EAS_PEGetFileHandle()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Returns the file handle of a stream
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_PEGetFileHandle (EAS_DATA_HANDLE pEASData, EAS_PCM_HANDLE handle, EAS_FILE_HANDLE *pFileHandle);
+
+/*----------------------------------------------------------------------------
+ * EAS_PERender()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Render a buffer of PCM audio
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_PERender (EAS_DATA_HANDLE pEASData, EAS_I32 numSamples);
+
+/*----------------------------------------------------------------------------
+ * EAS_PEUpdateParams()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Update the pitch and volume parameters using MIDI controls
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_PEUpdateParams (EAS_DATA_HANDLE pEASData, EAS_PCM_HANDLE pState, EAS_I16 pitch, EAS_I16 gainLeft, EAS_I16 gainRight);
+
+/*----------------------------------------------------------------------------
+ * EAS_PELocate()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * This function seeks to the requested place in the file. Accuracy
+ * is dependent on the sample rate and block size.
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * pState - stream handle
+ * time - media time in milliseconds
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_PELocate (EAS_DATA_HANDLE pEASData, EAS_PCM_HANDLE pState, EAS_I32 time);
+
+/*----------------------------------------------------------------------------
+ * EAS_PEUpdateVolume()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Update the volume parameters for a PCM stream
+ *
+ * Inputs:
+ * pEASData - pointer to EAS library instance data
+ * handle - pointer to S_PCM_STATE for this stream
+ * gainLeft - linear gain multipler in 1.15 fraction format
+ * gainRight - linear gain multipler in 1.15 fraction format
+ * initial - initial settings, set current gain
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ * Notes
+ * In mono mode, leftGain controls the output gain and rightGain is ignored
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pEASData) reserved for future use */
+EAS_RESULT EAS_PEUpdateVolume (EAS_DATA_HANDLE pEASData, EAS_PCM_HANDLE pState, EAS_I16 volume);
+
+/*----------------------------------------------------------------------------
+ * EAS_PEUpdatePitch()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Update the pitch parameter for a PCM stream
+ *
+ * Inputs:
+ * pEASData - pointer to EAS library instance data
+ * pState - pointer to S_PCM_STATE for this stream
+ * pitch - new pitch value in pitch cents
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pEASData) reserved for future use */
+EAS_RESULT EAS_PEUpdatePitch (EAS_DATA_HANDLE pEASData, EAS_PCM_HANDLE pState, EAS_I16 pitch);
+
+/*----------------------------------------------------------------------------
+ * EAS_PEState()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Returns the current state of the stream
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ * pState - pointer to variable to store state
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ * Notes:
+ * This interface is also exposed in the internal library for use by the other modules.
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_PEState (EAS_DATA_HANDLE pEASData, EAS_PCM_HANDLE handle, EAS_STATE *pState);
+
+/*----------------------------------------------------------------------------
+ * EAS_PEClose()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Close the file and clean up
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_PEClose (EAS_DATA_HANDLE pEASData, EAS_PCM_HANDLE handle);
+
+/*----------------------------------------------------------------------------
+ * EAS_PEReset()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Reset the sequencer. Used for locating backwards in the file.
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_PEReset (EAS_DATA_HANDLE pEASData, EAS_PCM_HANDLE handle);
+
+/*----------------------------------------------------------------------------
+ * EAS_PEPause()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Mute and pause rendering a PCM stream. Sets the gain target to zero and stops the playback
+ * at the end of the next audio frame.
+ *
+ * Inputs:
+ * pEASData - pointer to EAS library instance data
+ * handle - pointer to S_PCM_STATE for this stream
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_PEPause (EAS_DATA_HANDLE pEASData, EAS_PCM_HANDLE handle);
+
+/*----------------------------------------------------------------------------
+ * EAS_PEResume()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Resume rendering a PCM stream. Sets the gain target back to its
+ * previous setting and restarts playback at the end of the next audio
+ * frame.
+ *
+ * Inputs:
+ * pEASData - pointer to EAS library instance data
+ * handle - pointer to S_PCM_STATE for this stream
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_PEResume (EAS_DATA_HANDLE pEASData, EAS_PCM_HANDLE handle);
+
+/*----------------------------------------------------------------------------
+ * EAS_PERelease()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Put the PCM stream envelope into release.
+ *
+ * Inputs:
+ * pEASData - pointer to EAS library instance data
+ * handle - pointer to S_PCM_STATE for this stream
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_PERelease (EAS_DATA_HANDLE pEASData, EAS_PCM_HANDLE handle);
+
+#endif /* end _EAS_PCM_H */
+
diff --git a/arm-hybrid-22k/lib_src/eas_pcmdata.c b/arm-hybrid-22k/lib_src/eas_pcmdata.c
index 5649f07..2d85ac2 100644
--- a/arm-hybrid-22k/lib_src/eas_pcmdata.c
+++ b/arm-hybrid-22k/lib_src/eas_pcmdata.c
@@ -1,12 +1,12 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_pcmdata.c
- *
- * Contents and purpose:
- * Contains the static data for the PCM engine.
- *
- * Copyright Sonic Network Inc. 2005
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_pcmdata.c
+ *
+ * Contents and purpose:
+ * Contains the static data for the PCM engine.
+ *
+ * Copyright Sonic Network Inc. 2005
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,17 +19,17 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 547 $
- * $Date: 2007-01-31 16:30:17 -0800 (Wed, 31 Jan 2007) $
- *----------------------------------------------------------------------------
-*/
-
-#include "eas_data.h"
-
-/* static data allocation */
-S_PCM_STATE eas_PCMData[MAX_PCM_STREAMS];
-
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 547 $
+ * $Date: 2007-01-31 16:30:17 -0800 (Wed, 31 Jan 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+#include "eas_data.h"
+
+/* static data allocation */
+S_PCM_STATE eas_PCMData[MAX_PCM_STREAMS];
+
+
diff --git a/arm-hybrid-22k/lib_src/eas_pcmdata.h b/arm-hybrid-22k/lib_src/eas_pcmdata.h
index be2f8e5..ae18d6d 100644
--- a/arm-hybrid-22k/lib_src/eas_pcmdata.h
+++ b/arm-hybrid-22k/lib_src/eas_pcmdata.h
@@ -1,13 +1,13 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_pcmdata.h
- *
- * Contents and purpose:
- * Data declarations for the PCM engine
- *
- *
- * Copyright Sonic Network Inc. 2005
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_pcmdata.h
+ *
+ * Contents and purpose:
+ * Data declarations for the PCM engine
+ *
+ *
+ * Copyright Sonic Network Inc. 2005
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,138 +20,138 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 847 $
- * $Date: 2007-08-27 21:30:08 -0700 (Mon, 27 Aug 2007) $
- *----------------------------------------------------------------------------
-*/
-
-#ifndef _EAS_PCMDATA_H
-#define _EAS_PCMDATA_H
-
-/* sets the maximum number of simultaneous PCM streams */
-#ifndef MAX_PCM_STREAMS
-#define MAX_PCM_STREAMS 16
-#define PCM_STREAM_THRESHOLD (MAX_PCM_STREAMS - 4)
-#endif
-
-/* coefficents for high-pass filter in ADPCM */
-#define INTEGRATOR_COEFFICIENT 100 /* coefficient for leaky integrator */
-
-/* additional flags in S_PCM_STATE.flags used internal to module */
-#define PCM_FLAGS_EMPTY 0x01000000 /* unsigned format */
-
-/*----------------------------------------------------------------------------
- * S_PCM_STATE
- *
- * Retains state information for PCM streams.
- *----------------------------------------------------------------------------
-*/
-typedef struct s_decoder_state_tag
-{
- EAS_I32 output; /* last output for DC offset filter */
- EAS_I32 acc; /* accumulator for DC offset filter */
- EAS_I32 step; /* current ADPCM step size */
- EAS_PCM x1; /* current generated sample */
- EAS_PCM x0; /* previous generated sample */
-} S_DECODER_STATE;
-
-typedef enum
-{
- PCM_ENV_START = 0,
- PCM_ENV_ATTACK,
- PCM_ENV_DECAY,
- PCM_ENV_SUSTAIN,
- PCM_ENV_RELEASE,
- PCM_ENV_END
-} E_PCM_ENV_STATE;
-
-typedef struct s_pcm_state_tag
-{
-#ifdef _CHECKED_BUILD
- EAS_U32 handleCheck; /* signature check for checked build */
-#endif
- EAS_FILE_HANDLE fileHandle; /* pointer to input file */
- EAS_PCM_CALLBACK pCallback; /* pointer to callback function */
- EAS_VOID_PTR cbInstData; /* instance data for callback function */
- struct s_decoder_interface_tag EAS_CONST * pDecoder; /* pointer to decoder interface */
- EAS_STATE state; /* stream state */
- EAS_I32 time; /* media time */
- EAS_I32 startPos; /* start of PCM stream */
- EAS_I32 loopLocation; /* file location where loop starts */
- EAS_I32 byteCount; /* size of file */
- EAS_U32 loopStart; /* loop start, offset in samples from startPos */
- /* NOTE: For CMF, we use this to store total sample size */
- EAS_U32 loopSamples; /* total loop length, in samples, 0 means no loop */
- /* NOTE: For CMF, non-zero means looped */
- EAS_U32 samplesInLoop; /* samples left in the loop to play back */
- EAS_I32 samplesTilLoop; /* samples left to play until top of loop */
- EAS_I32 bytesLeft; /* count of bytes left in stream */
- EAS_I32 bytesLeftLoop; /* count of bytes left in stream, value at start of loop */
- EAS_U32 phase; /* current phase for interpolator */
- EAS_U32 basefreq; /* frequency multiplier */
- EAS_U32 flags; /* stream flags */
- EAS_U32 envData; /* envelope data (and LFO data) */
- EAS_U32 envValue; /* current envelope value */
- EAS_U32 envScale; /* current envelope scale */
- EAS_U32 startOrder; /* start order index, first is 0, next is 1, etc. */
- S_DECODER_STATE decoderL; /* left (mono) ADPCM state */
- S_DECODER_STATE decoderR; /* right ADPCM state */
- S_DECODER_STATE decoderLLoop; /* left (mono) ADPCM state, value at start of loop */
- S_DECODER_STATE decoderRLoop; /* right ADPCM state, value at start of loop */
- E_PCM_ENV_STATE envState; /* current envelope state */
- EAS_I16 volume; /* volume for stream */
- EAS_I16 pitch; /* relative pitch in cents - zero is unity playback */
- EAS_I16 gainLeft; /* requested gain */
- EAS_I16 gainRight; /* requested gain */
- EAS_I16 currentGainLeft; /* current gain for anti-zipper filter */
- EAS_I16 currentGainRight; /* current gain for anti-zipper filter */
- EAS_U16 blockSize; /* block size for ADPCM decoder */
- EAS_U16 blockCount; /* block counter for ADPCM decoder */
- EAS_U16 sampleRate; /* input sample rate */
- EAS_U8 srcByte; /* source byte */
- EAS_U8 msBitCount; /* count keeps track of MS bits */
- EAS_U8 msBitMask; /* mask keeps track of MS bits */
- EAS_U8 msBitValue; /* value keeps track of MS bits */
- EAS_U8 msBitCountLoop; /* count keeps track of MS bits, value at loop start */
- EAS_U8 msBitMaskLoop; /* mask keeps track of MS bits, value at loop start */
- EAS_U8 msBitValueLoop; /* value keeps track of MS bits, value at loop start */
- EAS_BOOL8 hiNibble; /* indicates high/low nibble is next */
- EAS_BOOL8 hiNibbleLoop; /* indicates high/low nibble is next, value loop start */
- EAS_U8 rateShift; /* for playback rate greater than 1.0 */
-} S_PCM_STATE;
-
-/*----------------------------------------------------------------------------
- * S_DECODER_INTERFACE
- *
- * Generic interface for audio decoders
- *----------------------------------------------------------------------------
-*/
-typedef struct s_decoder_interface_tag
-{
- EAS_RESULT (* EAS_CONST pfInit)(EAS_DATA_HANDLE pEASData, S_PCM_STATE *pState);
- EAS_RESULT (* EAS_CONST pfDecodeSample)(EAS_DATA_HANDLE pEASData, S_PCM_STATE *pState);
- EAS_RESULT (* EAS_CONST pfLocate)(EAS_DATA_HANDLE pEASData, S_PCM_STATE *pState, EAS_I32 time);
-} S_DECODER_INTERFACE;
-
-
-/* header chunk for SMAF ADPCM */
-#define TAG_YAMAHA_ADPCM 0x4d776100
-#define TAG_MASK 0xffffff00
-#define TAG_RIFF_FILE 0x52494646
-#define TAG_WAVE_CHUNK 0x57415645
-#define TAG_FMT_CHUNK 0x666d7420
-
-/*----------------------------------------------------------------------------
- * EAS_PESeek
- *----------------------------------------------------------------------------
- * Purpose:
- * Locate to a particular byte in a PCM stream
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT EAS_PESeek (EAS_DATA_HANDLE pEASData, S_PCM_STATE *pState, EAS_I32 *pLocation);
-
-#endif /* _EAS_PCMDATA_H */
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 847 $
+ * $Date: 2007-08-27 21:30:08 -0700 (Mon, 27 Aug 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+#ifndef _EAS_PCMDATA_H
+#define _EAS_PCMDATA_H
+
+/* sets the maximum number of simultaneous PCM streams */
+#ifndef MAX_PCM_STREAMS
+#define MAX_PCM_STREAMS 16
+#define PCM_STREAM_THRESHOLD (MAX_PCM_STREAMS - 4)
+#endif
+
+/* coefficents for high-pass filter in ADPCM */
+#define INTEGRATOR_COEFFICIENT 100 /* coefficient for leaky integrator */
+
+/* additional flags in S_PCM_STATE.flags used internal to module */
+#define PCM_FLAGS_EMPTY 0x01000000 /* unsigned format */
+
+/*----------------------------------------------------------------------------
+ * S_PCM_STATE
+ *
+ * Retains state information for PCM streams.
+ *----------------------------------------------------------------------------
+*/
+typedef struct s_decoder_state_tag
+{
+ EAS_I32 output; /* last output for DC offset filter */
+ EAS_I32 acc; /* accumulator for DC offset filter */
+ EAS_I32 step; /* current ADPCM step size */
+ EAS_PCM x1; /* current generated sample */
+ EAS_PCM x0; /* previous generated sample */
+} S_DECODER_STATE;
+
+typedef enum
+{
+ PCM_ENV_START = 0,
+ PCM_ENV_ATTACK,
+ PCM_ENV_DECAY,
+ PCM_ENV_SUSTAIN,
+ PCM_ENV_RELEASE,
+ PCM_ENV_END
+} E_PCM_ENV_STATE;
+
+typedef struct s_pcm_state_tag
+{
+#ifdef _CHECKED_BUILD
+ EAS_U32 handleCheck; /* signature check for checked build */
+#endif
+ EAS_FILE_HANDLE fileHandle; /* pointer to input file */
+ EAS_PCM_CALLBACK pCallback; /* pointer to callback function */
+ EAS_VOID_PTR cbInstData; /* instance data for callback function */
+ struct s_decoder_interface_tag EAS_CONST * pDecoder; /* pointer to decoder interface */
+ EAS_STATE state; /* stream state */
+ EAS_I32 time; /* media time */
+ EAS_I32 startPos; /* start of PCM stream */
+ EAS_I32 loopLocation; /* file location where loop starts */
+ EAS_I32 byteCount; /* size of file */
+ EAS_U32 loopStart; /* loop start, offset in samples from startPos */
+ /* NOTE: For CMF, we use this to store total sample size */
+ EAS_U32 loopSamples; /* total loop length, in samples, 0 means no loop */
+ /* NOTE: For CMF, non-zero means looped */
+ EAS_U32 samplesInLoop; /* samples left in the loop to play back */
+ EAS_I32 samplesTilLoop; /* samples left to play until top of loop */
+ EAS_I32 bytesLeft; /* count of bytes left in stream */
+ EAS_I32 bytesLeftLoop; /* count of bytes left in stream, value at start of loop */
+ EAS_U32 phase; /* current phase for interpolator */
+ EAS_U32 basefreq; /* frequency multiplier */
+ EAS_U32 flags; /* stream flags */
+ EAS_U32 envData; /* envelope data (and LFO data) */
+ EAS_U32 envValue; /* current envelope value */
+ EAS_U32 envScale; /* current envelope scale */
+ EAS_U32 startOrder; /* start order index, first is 0, next is 1, etc. */
+ S_DECODER_STATE decoderL; /* left (mono) ADPCM state */
+ S_DECODER_STATE decoderR; /* right ADPCM state */
+ S_DECODER_STATE decoderLLoop; /* left (mono) ADPCM state, value at start of loop */
+ S_DECODER_STATE decoderRLoop; /* right ADPCM state, value at start of loop */
+ E_PCM_ENV_STATE envState; /* current envelope state */
+ EAS_I16 volume; /* volume for stream */
+ EAS_I16 pitch; /* relative pitch in cents - zero is unity playback */
+ EAS_I16 gainLeft; /* requested gain */
+ EAS_I16 gainRight; /* requested gain */
+ EAS_I16 currentGainLeft; /* current gain for anti-zipper filter */
+ EAS_I16 currentGainRight; /* current gain for anti-zipper filter */
+ EAS_U16 blockSize; /* block size for ADPCM decoder */
+ EAS_U16 blockCount; /* block counter for ADPCM decoder */
+ EAS_U16 sampleRate; /* input sample rate */
+ EAS_U8 srcByte; /* source byte */
+ EAS_U8 msBitCount; /* count keeps track of MS bits */
+ EAS_U8 msBitMask; /* mask keeps track of MS bits */
+ EAS_U8 msBitValue; /* value keeps track of MS bits */
+ EAS_U8 msBitCountLoop; /* count keeps track of MS bits, value at loop start */
+ EAS_U8 msBitMaskLoop; /* mask keeps track of MS bits, value at loop start */
+ EAS_U8 msBitValueLoop; /* value keeps track of MS bits, value at loop start */
+ EAS_BOOL8 hiNibble; /* indicates high/low nibble is next */
+ EAS_BOOL8 hiNibbleLoop; /* indicates high/low nibble is next, value loop start */
+ EAS_U8 rateShift; /* for playback rate greater than 1.0 */
+} S_PCM_STATE;
+
+/*----------------------------------------------------------------------------
+ * S_DECODER_INTERFACE
+ *
+ * Generic interface for audio decoders
+ *----------------------------------------------------------------------------
+*/
+typedef struct s_decoder_interface_tag
+{
+ EAS_RESULT (* EAS_CONST pfInit)(EAS_DATA_HANDLE pEASData, S_PCM_STATE *pState);
+ EAS_RESULT (* EAS_CONST pfDecodeSample)(EAS_DATA_HANDLE pEASData, S_PCM_STATE *pState);
+ EAS_RESULT (* EAS_CONST pfLocate)(EAS_DATA_HANDLE pEASData, S_PCM_STATE *pState, EAS_I32 time);
+} S_DECODER_INTERFACE;
+
+
+/* header chunk for SMAF ADPCM */
+#define TAG_YAMAHA_ADPCM 0x4d776100
+#define TAG_MASK 0xffffff00
+#define TAG_RIFF_FILE 0x52494646
+#define TAG_WAVE_CHUNK 0x57415645
+#define TAG_FMT_CHUNK 0x666d7420
+
+/*----------------------------------------------------------------------------
+ * EAS_PESeek
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Locate to a particular byte in a PCM stream
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_PESeek (EAS_DATA_HANDLE pEASData, S_PCM_STATE *pState, EAS_I32 *pLocation);
+
+#endif /* _EAS_PCMDATA_H */
+
diff --git a/arm-hybrid-22k/lib_src/eas_public.c b/arm-hybrid-22k/lib_src/eas_public.c
index ac43261..394a9a1 100644
--- a/arm-hybrid-22k/lib_src/eas_public.c
+++ b/arm-hybrid-22k/lib_src/eas_public.c
@@ -1,12 +1,12 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_public.c
- *
- * Contents and purpose:
- * Contains EAS library public interface
- *
- * Copyright Sonic Network Inc. 2004
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_public.c
+ *
+ * Contents and purpose:
+ * Contains EAS library public interface
+ *
+ * Copyright Sonic Network Inc. 2004
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,2579 +19,2579 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 842 $
- * $Date: 2007-08-23 14:32:31 -0700 (Thu, 23 Aug 2007) $
- *----------------------------------------------------------------------------
-*/
-
-#include "eas_synthcfg.h"
-#include "eas.h"
-#include "eas_config.h"
-#include "eas_host.h"
-#include "eas_report.h"
-#include "eas_data.h"
-#include "eas_parser.h"
-#include "eas_pcm.h"
-#include "eas_midi.h"
-#include "eas_mixer.h"
-#include "eas_build.h"
-#include "eas_vm_protos.h"
-#include "eas_math.h"
-
-#ifdef JET_INTERFACE
-#include "jet_data.h"
-#endif
-
-#ifdef DLS_SYNTHESIZER
-#include "eas_mdls.h"
-#endif
-
-/* number of events to parse before calling EAS_HWYield function */
-#define YIELD_EVENT_COUNT 10
-
-/*----------------------------------------------------------------------------
- * easLibConfig
- *
- * This structure is available through the EAS public interface to allow
- * the user to check the configuration of the library.
- *----------------------------------------------------------------------------
-*/
-static const S_EAS_LIB_CONFIG easLibConfig =
-{
- LIB_VERSION,
-#ifdef _CHECKED_BUILD
- EAS_TRUE,
-#else
- EAS_FALSE,
-#endif
- MAX_SYNTH_VOICES,
- NUM_OUTPUT_CHANNELS,
- _OUTPUT_SAMPLE_RATE,
- BUFFER_SIZE_IN_MONO_SAMPLES,
-#ifdef _FILTER_ENABLED
- EAS_TRUE,
-#else
- EAS_FALSE,
-#endif
- _BUILD_TIME_,
- _BUILD_VERSION_
-};
-
-/* local prototypes */
-static EAS_RESULT EAS_ParseEvents (S_EAS_DATA *pEASData, S_EAS_STREAM *pStream, EAS_U32 endTime, EAS_INT parseMode);
-
-/*----------------------------------------------------------------------------
- * EAS_SetStreamParameter
- *----------------------------------------------------------------------------
- * Sets the specified parameter in the stream. Allows access to
- * customizable settings within the individual file parsers.
- *----------------------------------------------------------------------------
- * pEASData - pointer to EAS persistent data object
- * pStream - stream handle
- * param - enumerated parameter (see eas_parser.h)
- * value - new value
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT EAS_SetStreamParameter (S_EAS_DATA *pEASData, EAS_HANDLE pStream, EAS_I32 param, EAS_I32 value)
-{
- S_FILE_PARSER_INTERFACE *pParserModule;
-
- pParserModule = (S_FILE_PARSER_INTERFACE*) pStream->pParserModule;
- if (pParserModule->pfSetData)
- return (*pParserModule->pfSetData)(pEASData, pStream->handle, param, value);
- return EAS_ERROR_FEATURE_NOT_AVAILABLE;
-}
-
-/*----------------------------------------------------------------------------
- * EAS_GetStreamParameter
- *----------------------------------------------------------------------------
- * Sets the specified parameter in the stream. Allows access to
- * customizable settings within the individual file parsers.
- *----------------------------------------------------------------------------
- * pEASData - pointer to EAS persistent data object
- * pStream - stream handle
- * param - enumerated parameter (see eas_parser.h)
- * pValue - pointer to variable to receive current setting
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT EAS_GetStreamParameter (S_EAS_DATA *pEASData, EAS_HANDLE pStream, EAS_I32 param, EAS_I32 *pValue)
-{
- S_FILE_PARSER_INTERFACE *pParserModule;
-
- pParserModule = (S_FILE_PARSER_INTERFACE*) pStream->pParserModule;
- if (pParserModule->pfGetData)
- return (*pParserModule->pfGetData)(pEASData, pStream->handle, param, pValue);
- return EAS_ERROR_FEATURE_NOT_AVAILABLE;
-}
-
-/*----------------------------------------------------------------------------
- * EAS_StreamReady()
- *----------------------------------------------------------------------------
- * This routine sets common parameters like transpose, volume, etc.
- * First, it attempts to use the parser EAS_SetStreamParameter interface. If that
- * fails, it attempts to get the synth handle from the parser and
- * set the parameter directly on the synth. This eliminates duplicate
- * code in the parser.
- *----------------------------------------------------------------------------
-*/
-EAS_BOOL EAS_StreamReady (S_EAS_DATA *pEASData, EAS_HANDLE pStream)
-{
- S_FILE_PARSER_INTERFACE *pParserModule;
- EAS_STATE state;
-
- pParserModule = (S_FILE_PARSER_INTERFACE*) pStream->pParserModule;
- if (pParserModule->pfState(pEASData, pStream->handle, &state) != EAS_SUCCESS)
- return EAS_FALSE;
- return (state < EAS_STATE_OPEN);
-}
-
-/*----------------------------------------------------------------------------
- * EAS_IntSetStrmParam()
- *----------------------------------------------------------------------------
- * This routine sets common parameters like transpose, volume, etc.
- * First, it attempts to use the parser EAS_SetStreamParameter interface. If that
- * fails, it attempts to get the synth handle from the parser and
- * set the parameter directly on the synth. This eliminates duplicate
- * code in the parser.
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT EAS_IntSetStrmParam (S_EAS_DATA *pEASData, EAS_HANDLE pStream, EAS_INT param, EAS_I32 value)
-{
- S_SYNTH *pSynth;
-
- /* try to set the parameter using stream interface */
- if (EAS_SetStreamParameter(pEASData, pStream, param, value) == EAS_SUCCESS)
- return EAS_SUCCESS;
-
- /* get a pointer to the synth object and set it directly */
- /*lint -e{740} we are cheating by passing a pointer through this interface */
- if (EAS_GetStreamParameter(pEASData, pStream, PARSER_DATA_SYNTH_HANDLE, (EAS_I32*) &pSynth) != EAS_SUCCESS)
- return EAS_ERROR_INVALID_PARAMETER;
-
- if (pSynth == NULL)
- return EAS_ERROR_INVALID_PARAMETER;
-
- switch (param)
- {
-
-#ifdef DLS_SYNTHESIZER
- case PARSER_DATA_DLS_COLLECTION:
- {
- EAS_RESULT result = VMSetDLSLib(pSynth, (EAS_DLSLIB_HANDLE) value);
- if (result == EAS_SUCCESS)
- {
- DLSAddRef((S_DLS*) value);
- VMInitializeAllChannels(pEASData->pVoiceMgr, pSynth);
- }
- return result;
- }
-#endif
-
- case PARSER_DATA_EAS_LIBRARY:
- return VMSetEASLib(pSynth, (EAS_SNDLIB_HANDLE) value);
-
- case PARSER_DATA_POLYPHONY:
- return VMSetPolyphony(pEASData->pVoiceMgr, pSynth, value);
-
- case PARSER_DATA_PRIORITY:
- return VMSetPriority(pEASData->pVoiceMgr, pSynth, value);
-
- case PARSER_DATA_TRANSPOSITION:
- VMSetTranposition(pSynth, value);
- break;
-
- case PARSER_DATA_VOLUME:
- VMSetVolume(pSynth, (EAS_U16) value);
- break;
-
- default:
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Invalid paramter %d in call to EAS_IntSetStrmParam", param); */ }
- return EAS_ERROR_INVALID_PARAMETER;
- }
-
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * EAS_IntGetStrmParam()
- *----------------------------------------------------------------------------
- * This routine gets common parameters like transpose, volume, etc.
- * First, it attempts to use the parser EAS_GetStreamParameter interface. If that
- * fails, it attempts to get the synth handle from the parser and
- * get the parameter directly on the synth.
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT EAS_IntGetStrmParam (S_EAS_DATA *pEASData, EAS_HANDLE pStream, EAS_INT param, EAS_I32 *pValue)
-{
- S_SYNTH *pSynth;
-
- /* try to set the parameter */
- if (EAS_GetStreamParameter(pEASData, pStream, param, pValue) == EAS_SUCCESS)
- return EAS_SUCCESS;
-
- /* get a pointer to the synth object and retrieve data directly */
- /*lint -e{740} we are cheating by passing a pointer through this interface */
- if (EAS_GetStreamParameter(pEASData, pStream, PARSER_DATA_SYNTH_HANDLE, (EAS_I32*) &pSynth) != EAS_SUCCESS)
- return EAS_ERROR_INVALID_PARAMETER;
-
- if (pSynth == NULL)
- return EAS_ERROR_INVALID_PARAMETER;
-
- switch (param)
- {
- case PARSER_DATA_POLYPHONY:
- return VMGetPolyphony(pEASData->pVoiceMgr, pSynth, pValue);
-
- case PARSER_DATA_PRIORITY:
- return VMGetPriority(pEASData->pVoiceMgr, pSynth, pValue);
-
- case PARSER_DATA_TRANSPOSITION:
- VMGetTranposition(pSynth, pValue);
- break;
-
- case PARSER_DATA_NOTE_COUNT:
- *pValue = VMGetNoteCount(pSynth);
- break;
-
- default:
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Invalid paramter %d in call to EAS_IntSetStrmParam", param); */ }
- return EAS_ERROR_INVALID_PARAMETER;
- }
-
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * EAS_AllocateStream()
- *----------------------------------------------------------------------------
- * Purpose:
- * Allocates a stream handle
- *
- * Inputs:
- *
- * Outputs:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_INT EAS_AllocateStream (EAS_DATA_HANDLE pEASData)
-{
- EAS_INT streamNum;
-
- /* check for static allocation, only one stream allowed */
- if (pEASData->staticMemoryModel)
- {
- if (pEASData->streams[0].handle != NULL)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Attempt to open multiple streams in static model\n"); */ }
- return -1;
- }
- return 0;
- }
-
- /* dynamic model */
- for (streamNum = 0; streamNum < MAX_NUMBER_STREAMS; streamNum++)
- if (pEASData->streams[streamNum].handle == NULL)
- break;
- if (streamNum == MAX_NUMBER_STREAMS)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Exceeded maximum number of open streams\n"); */ }
- return -1;
- }
- return streamNum;
-}
-
-/*----------------------------------------------------------------------------
- * EAS_InitStream()
- *----------------------------------------------------------------------------
- * Purpose:
- * Initialize a stream
- *
- * Inputs:
- *
- * Outputs:
- *
- *----------------------------------------------------------------------------
-*/
-static void EAS_InitStream (S_EAS_STREAM *pStream, EAS_VOID_PTR pParserModule, EAS_VOID_PTR streamHandle)
-{
- pStream->pParserModule = pParserModule;
- pStream->handle = streamHandle;
- pStream->time = 0;
- pStream->frameLength = AUDIO_FRAME_LENGTH;
- pStream->repeatCount = 0;
- pStream->volume = DEFAULT_STREAM_VOLUME;
-}
-
-/*----------------------------------------------------------------------------
- * EAS_Config()
- *----------------------------------------------------------------------------
- * Purpose:
- * Returns a pointer to a structure containing the configuration options
- * in this library build.
- *
- * Inputs:
- *
- * Outputs:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC const S_EAS_LIB_CONFIG *EAS_Config (void)
-{
- return &easLibConfig;
-}
-
-/*----------------------------------------------------------------------------
- * EAS_Init()
- *----------------------------------------------------------------------------
- * Purpose:
- * Initialize the synthesizer library
- *
- * Inputs:
- * ppEASData - pointer to data handle variable for this instance
- *
- * Outputs:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_Init (EAS_DATA_HANDLE *ppEASData)
-{
- EAS_HW_DATA_HANDLE pHWInstData;
- EAS_RESULT result;
- S_EAS_DATA *pEASData;
- EAS_INT module;
- EAS_BOOL staticMemoryModel;
-
- /* get the memory model */
- staticMemoryModel = EAS_CMStaticMemoryModel();
-
- /* initialize the host wrapper interface */
- *ppEASData = NULL;
- if ((result = EAS_HWInit(&pHWInstData)) != EAS_SUCCESS)
- return result;
-
- /* check Configuration Module for S_EAS_DATA allocation */
- if (staticMemoryModel)
- pEASData = EAS_CMEnumData(EAS_CM_EAS_DATA);
- else
- pEASData = EAS_HWMalloc(pHWInstData, sizeof(S_EAS_DATA));
- if (!pEASData)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_FATAL, "Failed to allocate EAS library memory\n"); */ }
- return EAS_ERROR_MALLOC_FAILED;
- }
-
- /* initialize some data */
- EAS_HWMemSet(pEASData, 0, sizeof(S_EAS_DATA));
- pEASData->staticMemoryModel = (EAS_BOOL8) staticMemoryModel;
- pEASData->hwInstData = pHWInstData;
- pEASData->renderTime = 0;
-
- /* set header search flag */
-#ifdef FILE_HEADER_SEARCH
- pEASData->searchHeaderFlag = EAS_TRUE;
-#endif
-
- /* initalize parameters */
- EAS_SetVolume(pEASData, NULL, DEFAULT_VOLUME);
-
-#ifdef _METRICS_ENABLED
- /* initalize the metrics module */
- pEASData->pMetricsModule = EAS_CMEnumOptModules(EAS_MODULE_METRICS);
- if (pEASData->pMetricsModule != NULL)
- {
- if ((result = (*pEASData->pMetricsModule->pfInit)(pEASData, &pEASData->pMetricsData)) != EAS_SUCCESS)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Error %ld initializing metrics module\n", result); */ }
- return result;
- }
- }
-#endif
-
- /* initailize the voice manager & synthesizer */
- if ((result = VMInitialize(pEASData)) != EAS_SUCCESS)
- return result;
-
- /* initialize mix engine */
- if ((result = EAS_MixEngineInit(pEASData)) != EAS_SUCCESS)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Error %ld starting up mix engine\n", result); */ }
- return result;
- }
-
- /* initialize effects modules */
- for (module = 0; module < NUM_EFFECTS_MODULES; module++)
- {
- pEASData->effectsModules[module].effect = EAS_CMEnumFXModules(module);
- if (pEASData->effectsModules[module].effect != NULL)
- {
- if ((result = (*pEASData->effectsModules[module].effect->pfInit)(pEASData, &pEASData->effectsModules[module].effectData)) != EAS_SUCCESS)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_FATAL, "Initialization of effects module %d returned %d\n", module, result); */ }
- return result;
- }
- }
- }
-
- /* initialize PCM engine */
- if ((result = EAS_PEInit(pEASData)) != EAS_SUCCESS)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_FATAL, "EAS_PEInit failed with error code %ld\n", result); */ }
- return result;
- }
-
- /* return instance data pointer to host */
- *ppEASData = pEASData;
-
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * EAS_Shutdown()
- *----------------------------------------------------------------------------
- * Purpose:
- * Shuts down the library. Deallocates any memory associated with the
- * synthesizer (dynamic memory model only)
- *
- * Inputs:
- * pEASData - handle to data for this instance
- *
- * Outputs:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_Shutdown (EAS_DATA_HANDLE pEASData)
-{
- EAS_HW_DATA_HANDLE hwInstData;
- EAS_RESULT result, reportResult;
- EAS_INT i;
-
- /* establish pointers */
- hwInstData = pEASData->hwInstData;
-
- /* check for NULL handle */
- if (!pEASData)
- return EAS_ERROR_HANDLE_INTEGRITY;
-
- /* if there are streams open, close them */
- reportResult = EAS_SUCCESS;
- for (i = 0; i < MAX_NUMBER_STREAMS; i++)
- {
- if (pEASData->streams[i].pParserModule && pEASData->streams[i].handle)
- {
- if ((result = (*((S_FILE_PARSER_INTERFACE*)(pEASData->streams[i].pParserModule))->pfClose)(pEASData, pEASData->streams[i].handle)) != EAS_SUCCESS)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Error %ld shutting down parser module\n", result); */ }
- reportResult = result;
- }
- }
- }
-
- /* shutdown PCM engine */
- if ((result = EAS_PEShutdown(pEASData)) != EAS_SUCCESS)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Error %ld shutting down PCM engine\n", result); */ }
- if (reportResult == EAS_SUCCESS)
- reportResult = result;
- }
-
- /* shutdown mix engine */
- if ((result = EAS_MixEngineShutdown(pEASData)) != EAS_SUCCESS)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Error %ld shutting down mix engine\n", result); */ }
- if (reportResult == EAS_SUCCESS)
- reportResult = result;
- }
-
- /* shutdown effects modules */
- for (i = 0; i < NUM_EFFECTS_MODULES; i++)
- {
- if (pEASData->effectsModules[i].effect)
- {
- if ((result = (*pEASData->effectsModules[i].effect->pfShutdown)(pEASData, pEASData->effectsModules[i].effectData)) != EAS_SUCCESS)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_FATAL, "Shutdown of effects module %d returned %d\n", i, result); */ }
- if (reportResult == EAS_SUCCESS)
- reportResult = result;
- }
- }
- }
-
- /* shutdown the voice manager & synthesizer */
- VMShutdown(pEASData);
-
-#ifdef _METRICS_ENABLED
- /* shutdown the metrics module */
- if (pEASData->pMetricsModule != NULL)
- {
- if ((result = (*pEASData->pMetricsModule->pfShutdown)(pEASData, pEASData->pMetricsData)) != EAS_SUCCESS)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Error %ld shutting down metrics module\n", result); */ }
- if (reportResult == EAS_SUCCESS)
- reportResult = result;
- }
- }
-#endif
-
- /* release allocated memory */
- if (!pEASData->staticMemoryModel)
- EAS_HWFree(hwInstData, pEASData);
-
- /* shutdown host wrappers */
- if (hwInstData)
- {
- if ((result = EAS_HWShutdown(hwInstData)) != EAS_SUCCESS)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Error %ld shutting down host wrappers\n", result); */ }
- if (reportResult == EAS_SUCCESS)
- reportResult = result;
- }
- }
-
- return reportResult;
-}
-
-#ifdef JET_INTERFACE
-/*----------------------------------------------------------------------------
- * EAS_OpenJETStream()
- *----------------------------------------------------------------------------
- * Private interface for JET to open an SMF stream with an offset
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT EAS_OpenJETStream (EAS_DATA_HANDLE pEASData, EAS_FILE_HANDLE fileHandle, EAS_I32 offset, EAS_HANDLE *ppStream)
-{
- EAS_RESULT result;
- EAS_VOID_PTR streamHandle;
- S_FILE_PARSER_INTERFACE *pParserModule;
- EAS_INT streamNum;
-
- /* allocate a stream */
- if ((streamNum = EAS_AllocateStream(pEASData)) < 0)
- return EAS_ERROR_MAX_STREAMS_OPEN;
-
- /* check Configuration Module for SMF parser */
- *ppStream = NULL;
- streamHandle = NULL;
- pParserModule = (S_FILE_PARSER_INTERFACE *) EAS_CMEnumModules(0);
- if (pParserModule == NULL)
- return EAS_ERROR_UNRECOGNIZED_FORMAT;
-
- /* see if SMF parser recognizes the file */
- if ((result = (*pParserModule->pfCheckFileType)(pEASData, fileHandle, &streamHandle, offset)) != EAS_SUCCESS)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "CheckFileType returned error %ld\n", result); */ }
- return result;
- }
-
- /* parser recognized the file, return the handle */
- if (streamHandle)
- {
- EAS_InitStream(&pEASData->streams[streamNum], pParserModule, streamHandle);
- *ppStream = &pEASData->streams[streamNum];
- return EAS_SUCCESS;
- }
-
- return EAS_ERROR_UNRECOGNIZED_FORMAT;
-}
-#endif
-
-/*----------------------------------------------------------------------------
- * EAS_OpenFile()
- *----------------------------------------------------------------------------
- * Purpose:
- * Opens a file for audio playback.
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * pHandle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_OpenFile (EAS_DATA_HANDLE pEASData, EAS_FILE_LOCATOR locator, EAS_HANDLE *ppStream)
-{
- EAS_RESULT result;
- EAS_FILE_HANDLE fileHandle;
- EAS_VOID_PTR streamHandle;
- S_FILE_PARSER_INTERFACE *pParserModule;
- EAS_INT streamNum;
- EAS_INT moduleNum;
-
- /* open the file */
- if ((result = EAS_HWOpenFile(pEASData->hwInstData, locator, &fileHandle, EAS_FILE_READ)) != EAS_SUCCESS)
- return result;
-
- /* allocate a stream */
- if ((streamNum = EAS_AllocateStream(pEASData)) < 0)
- return EAS_ERROR_MAX_STREAMS_OPEN;
-
- /* check Configuration Module for file parsers */
- pParserModule = NULL;
- *ppStream = NULL;
- streamHandle = NULL;
- for (moduleNum = 0; ; moduleNum++)
- {
- pParserModule = (S_FILE_PARSER_INTERFACE *) EAS_CMEnumModules(moduleNum);
- if (pParserModule == NULL)
- break;
-
- /* see if this parser recognizes it */
- if ((result = (*pParserModule->pfCheckFileType)(pEASData, fileHandle, &streamHandle, 0L)) != EAS_SUCCESS)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "CheckFileType returned error %ld\n", result); */ }
- return result;
- }
-
- /* parser recognized the file, return the handle */
- if (streamHandle)
- {
-
- /* save the parser pointer and file handle */
- EAS_InitStream(&pEASData->streams[streamNum], pParserModule, streamHandle);
- *ppStream = &pEASData->streams[streamNum];
- return EAS_SUCCESS;
- }
-
- /* rewind the file for the next parser */
- if ((result = EAS_HWFileSeek(pEASData->hwInstData, fileHandle, 0L)) != EAS_SUCCESS)
- return result;
- }
-
- /* no parser was able to recognize the file, close it and return an error */
- EAS_HWCloseFile(pEASData->hwInstData, fileHandle);
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "No parser recognized the requested file\n"); */ }
- return EAS_ERROR_UNRECOGNIZED_FORMAT;
-}
-
-#ifdef MMAPI_SUPPORT
-/*----------------------------------------------------------------------------
- * EAS_MMAPIToneControl()
- *----------------------------------------------------------------------------
- * Purpose:
- * Opens a ToneControl file for audio playback.
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * pHandle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_MMAPIToneControl (EAS_DATA_HANDLE pEASData, EAS_FILE_LOCATOR locator, EAS_HANDLE *ppStream)
-{
- EAS_RESULT result;
- EAS_FILE_HANDLE fileHandle;
- EAS_VOID_PTR streamHandle;
- S_FILE_PARSER_INTERFACE *pParserModule;
- EAS_INT streamNum;
-
- /* check if the tone control parser is available */
- *ppStream = NULL;
- streamHandle = NULL;
- pParserModule = EAS_CMEnumOptModules(EAS_MODULE_MMAPI_TONE_CONTROL);
- if (pParserModule == NULL)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "EAS_MMAPIToneControl: ToneControl parser not available\n"); */ }
- return EAS_ERROR_FEATURE_NOT_AVAILABLE;
- }
-
- /* open the file */
- if ((result = EAS_HWOpenFile(pEASData->hwInstData, locator, &fileHandle, EAS_FILE_READ)) != EAS_SUCCESS)
- return result;
-
- /* allocate a stream */
- if ((streamNum = EAS_AllocateStream(pEASData)) < 0)
- return EAS_ERROR_MAX_STREAMS_OPEN;
-
- /* see if ToneControl parser recognizes it */
- if ((result = (*pParserModule->pfCheckFileType)(pEASData, fileHandle, &streamHandle, 0L)) != EAS_SUCCESS)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "CheckFileType returned error %ld\n", result); */ }
- return result;
- }
-
- /* parser accepted the file, return the handle */
- if (streamHandle)
- {
-
- /* save the parser pointer and file handle */
- EAS_InitStream(&pEASData->streams[streamNum], pParserModule, streamHandle);
- *ppStream = &pEASData->streams[streamNum];
- return EAS_SUCCESS;
- }
-
- /* parser did not recognize the file, close it and return an error */
- EAS_HWCloseFile(pEASData->hwInstData, fileHandle);
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "No parser recognized the requested file\n"); */ }
- return EAS_ERROR_UNRECOGNIZED_FORMAT;
-}
-
-/*----------------------------------------------------------------------------
- * EAS_GetWaveFmtChunk
- *----------------------------------------------------------------------------
- * Helper function to retrieve WAVE file fmt chunk for MMAPI
- *----------------------------------------------------------------------------
- * pEASData - pointer to EAS persistent data object
- * pStream - stream handle
- * pFmtChunk - pointer to variable to receive current setting
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_GetWaveFmtChunk (S_EAS_DATA *pEASData, EAS_HANDLE pStream, EAS_VOID_PTR *ppFmtChunk)
-{
- EAS_RESULT result;
- EAS_I32 value;
-
- if ((result = EAS_GetStreamParameter(pEASData, pStream, PARSER_DATA_FORMAT, &value)) != EAS_SUCCESS)
- return result;
- *ppFmtChunk = (EAS_VOID_PTR) value;
- return EAS_SUCCESS;
-}
-#endif
-
-/*----------------------------------------------------------------------------
- * EAS_GetFileType
- *----------------------------------------------------------------------------
- * Returns the file type (see eas_types.h for enumerations)
- *----------------------------------------------------------------------------
- * pEASData - pointer to EAS persistent data object
- * pStream - stream handle
- * pFileType - pointer to variable to receive file type
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_GetFileType (S_EAS_DATA *pEASData, EAS_HANDLE pStream, EAS_I32 *pFileType)
-{
- if (!EAS_StreamReady (pEASData, pStream))
- return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
- return EAS_GetStreamParameter(pEASData, pStream, PARSER_DATA_FILE_TYPE, pFileType);
-}
-
-/*----------------------------------------------------------------------------
- * EAS_Prepare()
- *----------------------------------------------------------------------------
- * Purpose:
- * Prepares the synthesizer to play the file or stream. Parses the first
- * frame of data from the file and arms the synthesizer.
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - file or stream handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_Prepare (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream)
-{
- S_FILE_PARSER_INTERFACE *pParserModule;
- EAS_STATE state;
- EAS_RESULT result;
-
- pParserModule = (S_FILE_PARSER_INTERFACE*) pStream->pParserModule;
- if (pParserModule == NULL)
- return EAS_ERROR_FEATURE_NOT_AVAILABLE;
-
- /* check for valid state */
- result = pParserModule->pfState(pEASData, pStream->handle, &state);
- if (result == EAS_SUCCESS)
- {
- /* prepare the stream */
- if (state == EAS_STATE_OPEN)
- {
- pParserModule = (S_FILE_PARSER_INTERFACE*) pStream->pParserModule;
- result = (*pParserModule->pfPrepare)(pEASData, pStream->handle);
-
- /* set volume */
- if (result == EAS_SUCCESS)
- result = EAS_SetVolume(pEASData, pStream, pStream->volume);
- }
- else
- result = EAS_ERROR_NOT_VALID_IN_THIS_STATE;
-
- }
-
- return result;
-}
-
-/*----------------------------------------------------------------------------
- * EAS_Render()
- *----------------------------------------------------------------------------
- * Purpose:
- * Parse the Midi data and render PCM audio data.
- *
- * Inputs:
- * pEASData - buffer for internal EAS data
- * pOut - output buffer pointer
- * nNumRequested - requested num samples to generate
- * pnNumGenerated - actual number of samples generated
- *
- * Outputs:
- * EAS_SUCCESS if PCM data was successfully rendered
- *
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_Render (EAS_DATA_HANDLE pEASData, EAS_PCM *pOut, EAS_I32 numRequested, EAS_I32 *pNumGenerated)
-{
- S_FILE_PARSER_INTERFACE *pParserModule;
- EAS_RESULT result;
- EAS_I32 voicesRendered;
- EAS_STATE parserState;
- EAS_INT streamNum;
-
- /* assume no samples generated and reset workload */
- *pNumGenerated = 0;
- VMInitWorkload(pEASData->pVoiceMgr);
-
- /* no support for other buffer sizes yet */
- if (numRequested != BUFFER_SIZE_IN_MONO_SAMPLES)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "This library supports only %ld samples in buffer, host requested %ld samples\n",
- (EAS_I32) BUFFER_SIZE_IN_MONO_SAMPLES, numRequested); */ }
- return EAS_BUFFER_SIZE_MISMATCH;
- }
-
-#ifdef _METRICS_ENABLED
- /* start performance counter */
- if (pEASData->pMetricsData)
- (*pEASData->pMetricsModule->pfStartTimer)(pEASData->pMetricsData, EAS_PM_TOTAL_TIME);
-#endif
-
- /* prep the frame buffer, do mix engine prep only if TRUE */
-#ifdef _SPLIT_ARCHITECTURE
- if (VMStartFrame(pEASData))
- EAS_MixEnginePrep(pEASData, numRequested);
-#else
- /* prep the mix engine */
- EAS_MixEnginePrep(pEASData, numRequested);
-#endif
-
- /* save the output buffer pointer */
- pEASData->pOutputAudioBuffer = pOut;
-
-
-#ifdef _METRICS_ENABLED
- /* start performance counter */
- if (pEASData->pMetricsData)
- (*pEASData->pMetricsModule->pfStartTimer)(pEASData->pMetricsData, EAS_PM_PARSE_TIME);
-#endif
-
- /* if we haven't finished parsing from last time, do it now */
- /* need to parse another frame of events before we render again */
- for (streamNum = 0; streamNum < MAX_NUMBER_STREAMS; streamNum++)
- {
- /* clear the locate flag */
- pEASData->streams[streamNum].streamFlags &= ~STREAM_FLAGS_LOCATE;
-
- if (pEASData->streams[streamNum].pParserModule)
- {
-
- /* establish pointer to parser module */
- pParserModule = pEASData->streams[streamNum].pParserModule;
-
- /* handle pause */
- if (pEASData->streams[streamNum].streamFlags & STREAM_FLAGS_PAUSE)
- {
- if (pParserModule->pfPause)
- result = pParserModule->pfPause(pEASData, pEASData->streams[streamNum].handle);
- pEASData->streams[streamNum].streamFlags &= ~STREAM_FLAGS_PAUSE;
- }
-
- /* get current state */
- if ((result = (*pParserModule->pfState)(pEASData, pEASData->streams[streamNum].handle, &parserState)) != EAS_SUCCESS)
- return result;
-
- /* handle resume */
- if (parserState == EAS_STATE_PAUSED)
- {
- if (pEASData->streams[streamNum].streamFlags & STREAM_FLAGS_RESUME)
- {
- if (pParserModule->pfResume)
- result = pParserModule->pfResume(pEASData, pEASData->streams[streamNum].handle);
- pEASData->streams[streamNum].streamFlags &= ~STREAM_FLAGS_RESUME;
- }
- }
-
- /* if necessary, parse stream */
- if ((pEASData->streams[streamNum].streamFlags & STREAM_FLAGS_PARSED) == 0)
- if ((result = EAS_ParseEvents(pEASData, &pEASData->streams[streamNum], pEASData->streams[streamNum].time + pEASData->streams[streamNum].frameLength, eParserModePlay)) != EAS_SUCCESS)
- return result;
-
- /* check for an early abort */
- if ((pEASData->streams[streamNum].streamFlags) == 0)
- {
-
-#ifdef _METRICS_ENABLED
- /* stop performance counter */
- if (pEASData->pMetricsData)
- (*pEASData->pMetricsModule->pfStartTimer)(pEASData->pMetricsData, EAS_PM_TOTAL_TIME);
-#endif
-
- return EAS_SUCCESS;
- }
-
- /* check for repeat */
- if (pEASData->streams[streamNum].repeatCount)
- {
-
- /* check for stopped state */
- if ((result = (*pParserModule->pfState)(pEASData, pEASData->streams[streamNum].handle, &parserState)) != EAS_SUCCESS)
- return result;
- if (parserState == EAS_STATE_STOPPED)
- {
-
- /* decrement repeat count, unless it is negative */
- if (pEASData->streams[streamNum].repeatCount > 0)
- pEASData->streams[streamNum].repeatCount--;
-
- /* reset the parser */
- if ((result = (*pParserModule->pfReset)(pEASData, pEASData->streams[streamNum].handle)) != EAS_SUCCESS)
- return result;
- pEASData->streams[streamNum].time = 0;
- }
- }
- }
- }
-
-#ifdef _METRICS_ENABLED
- /* stop performance counter */
- if (pEASData->pMetricsData)
- (void)(*pEASData->pMetricsModule->pfStopTimer)(pEASData->pMetricsData, EAS_PM_PARSE_TIME);
-#endif
-
-#ifdef _METRICS_ENABLED
- /* start the render timer */
- if (pEASData->pMetricsData)
- (*pEASData->pMetricsModule->pfStartTimer)(pEASData->pMetricsData, EAS_PM_RENDER_TIME);
-#endif
-
- /* render audio */
- if ((result = VMRender(pEASData->pVoiceMgr, BUFFER_SIZE_IN_MONO_SAMPLES, pEASData->pMixBuffer, &voicesRendered)) != EAS_SUCCESS)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "pfRender function returned error %ld\n", result); */ }
- return result;
- }
-
-#ifdef _METRICS_ENABLED
- /* stop the render timer */
- if (pEASData->pMetricsData) {
- (*pEASData->pMetricsModule->pfIncrementCounter)(pEASData->pMetricsData, EAS_PM_FRAME_COUNT, 1);
- (void)(*pEASData->pMetricsModule->pfStopTimer)(pEASData->pMetricsData, EAS_PM_RENDER_TIME);
- (*pEASData->pMetricsModule->pfIncrementCounter)(pEASData->pMetricsData, EAS_PM_TOTAL_VOICE_COUNT, (EAS_U32) voicesRendered);
- (void)(*pEASData->pMetricsModule->pfRecordMaxValue)(pEASData->pMetricsData, EAS_PM_MAX_VOICES, (EAS_U32) voicesRendered);
- }
-#endif
-
- //2 Do we really need frameParsed?
- /* need to parse another frame of events before we render again */
- for (streamNum = 0; streamNum < MAX_NUMBER_STREAMS; streamNum++)
- if (pEASData->streams[streamNum].pParserModule != NULL)
- pEASData->streams[streamNum].streamFlags &= ~STREAM_FLAGS_PARSED;
-
-#ifdef _METRICS_ENABLED
- /* start performance counter */
- if (pEASData->pMetricsData)
- (*pEASData->pMetricsModule->pfStartTimer)(pEASData->pMetricsData, EAS_PM_STREAM_TIME);
-#endif
-
- /* render PCM audio */
- if ((result = EAS_PERender(pEASData, numRequested)) != EAS_SUCCESS)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "EAS_PERender returned error %ld\n", result); */ }
- return result;
- }
-
-#ifdef _METRICS_ENABLED
- /* stop the stream timer */
- if (pEASData->pMetricsData)
- (void)(*pEASData->pMetricsModule->pfStopTimer)(pEASData->pMetricsData, EAS_PM_STREAM_TIME);
-#endif
-
-#ifdef _METRICS_ENABLED
- /* start the post timer */
- if (pEASData->pMetricsData)
- (*pEASData->pMetricsModule->pfStartTimer)(pEASData->pMetricsData, EAS_PM_POST_TIME);
-#endif
-
- /* for split architecture, send DSP vectors. Do post only if return is TRUE */
-#ifdef _SPLIT_ARCHITECTURE
- if (VMEndFrame(pEASData))
- {
- /* now do post-processing */
- EAS_MixEnginePost(pEASData, numRequested);
- *pNumGenerated = numRequested;
- }
-#else
- /* now do post-processing */
- EAS_MixEnginePost(pEASData, numRequested);
- *pNumGenerated = numRequested;
-#endif
-
-#ifdef _METRICS_ENABLED
- /* stop the post timer */
- if (pEASData->pMetricsData)
- (void)(*pEASData->pMetricsModule->pfStopTimer)(pEASData->pMetricsData, EAS_PM_POST_TIME);
-#endif
-
- /* advance render time */
- pEASData->renderTime += AUDIO_FRAME_LENGTH;
-
-#if 0
- /* dump workload for debug */
- if (pEASData->pVoiceMgr->workload)
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Workload = %d\n", pEASData->pVoiceMgr->workload); */ }
-#endif
-
-#ifdef _METRICS_ENABLED
- /* stop performance counter */
- if (pEASData->pMetricsData)
- {
- PERF_TIMER temp;
- temp = (*pEASData->pMetricsModule->pfStopTimer)(pEASData->pMetricsData, EAS_PM_TOTAL_TIME);
-
- /* if max render time, record the number of voices and time */
- if ((*pEASData->pMetricsModule->pfRecordMaxValue)
- (pEASData->pMetricsData, EAS_PM_MAX_CYCLES, (EAS_U32) temp))
- {
- (*pEASData->pMetricsModule->pfRecordValue)(pEASData->pMetricsData, EAS_PM_MAX_CYCLES_VOICES, (EAS_U32) voicesRendered);
- (*pEASData->pMetricsModule->pfRecordValue)(pEASData->pMetricsData, EAS_PM_MAX_CYCLES_TIME, (EAS_I32) (pEASData->renderTime >> 8));
- }
- }
-#endif
-
-#ifdef JET_INTERFACE
- /* let JET to do its thing */
- if (pEASData->jetHandle != NULL)
- {
- result = JET_Process(pEASData);
- if (result != EAS_SUCCESS)
- return result;
- }
-#endif
-
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * EAS_SetRepeat()
- *----------------------------------------------------------------------------
- * Purpose:
- * Set the selected stream to repeat.
- *
- * Inputs:
- * pEASData - handle to data for this instance
- * handle - handle to stream
- * repeatCount - repeat count
- *
- * Outputs:
- *
- * Side Effects:
- *
- * Notes:
- * 0 = no repeat
- * 1 = repeat once, i.e. play through twice
- * -1 = repeat forever
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, pEASData) reserved for future use */
-EAS_PUBLIC EAS_RESULT EAS_SetRepeat (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_I32 repeatCount)
-{
- pStream->repeatCount = repeatCount;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * EAS_GetRepeat()
- *----------------------------------------------------------------------------
- * Purpose:
- * Gets the current repeat count for the selected stream.
- *
- * Inputs:
- * pEASData - handle to data for this instance
- * handle - handle to stream
- * pRrepeatCount - pointer to variable to hold repeat count
- *
- * Outputs:
- *
- * Side Effects:
- *
- * Notes:
- * 0 = no repeat
- * 1 = repeat once, i.e. play through twice
- * -1 = repeat forever
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, pEASData) reserved for future use */
-EAS_PUBLIC EAS_RESULT EAS_GetRepeat (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_I32 *pRepeatCount)
-{
- *pRepeatCount = pStream->repeatCount;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * EAS_SetPlaybackRate()
- *----------------------------------------------------------------------------
- * Purpose:
- * Sets the playback rate.
- *
- * Inputs:
- * pEASData - handle to data for this instance
- * handle - handle to stream
- * rate - rate (28-bit fractional amount)
- *
- * Outputs:
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, pEASData) reserved for future use */
-EAS_PUBLIC EAS_RESULT EAS_SetPlaybackRate (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_U32 rate)
-{
-
- /* check range */
- if ((rate < (1 << 27)) || (rate > (1 << 29)))
- return EAS_ERROR_INVALID_PARAMETER;
-
- /* calculate new frame length
- *
- * NOTE: The maximum frame length we can accomodate based on a
- * maximum rate of 2.0 (2^28) is 2047 (2^13-1). To accomodate a
- * longer frame length or a higher maximum rate, the fixed point
- * divide below will need to be adjusted
- */
- pStream->frameLength = (AUDIO_FRAME_LENGTH * (rate >> 8)) >> 20;
-
- /* notify stream of new playback rate */
- EAS_SetStreamParameter(pEASData, pStream, PARSER_DATA_PLAYBACK_RATE, (EAS_I32) rate);
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * EAS_SetTransposition)
- *----------------------------------------------------------------------------
- * Purpose:
- * Sets the key tranposition for the synthesizer. Transposes all
- * melodic instruments by the specified amount. Range is limited
- * to +/-12 semitones.
- *
- * Inputs:
- * pEASData - handle to data for this instance
- * handle - handle to stream
- * transposition - +/-12 semitones
- *
- * Outputs:
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_SetTransposition (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_I32 transposition)
-{
-
- /* check range */
- if ((transposition < -12) || (transposition > 12))
- return EAS_ERROR_INVALID_PARAMETER;
-
- if (!EAS_StreamReady(pEASData, pStream))
- return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
- return EAS_IntSetStrmParam(pEASData, pStream, PARSER_DATA_TRANSPOSITION, transposition);
-}
-
-/*----------------------------------------------------------------------------
- * EAS_ParseEvents()
- *----------------------------------------------------------------------------
- * Purpose:
- * Parse events in the current streams until the desired time is reached.
- *
- * Inputs:
- * pEASData - buffer for internal EAS data
- * endTime - stop parsing if this time is reached
- * parseMode - play, locate, or metadata
- *
- * Outputs:
- * EAS_SUCCESS if PCM data was successfully rendered
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT EAS_ParseEvents (S_EAS_DATA *pEASData, EAS_HANDLE pStream, EAS_U32 endTime, EAS_INT parseMode)
-{
- S_FILE_PARSER_INTERFACE *pParserModule;
- EAS_RESULT result;
- EAS_I32 parserState;
- EAS_BOOL done;
- EAS_INT yieldCount = YIELD_EVENT_COUNT;
- EAS_U32 time = 0;
-
- /* does this parser have a time function? */
- pParserModule = pStream->pParserModule;
- if (pParserModule->pfTime == NULL)
- {
- /* check state */
- if ((result = (*pParserModule->pfState)(pEASData, pStream->handle, &parserState)) != EAS_SUCCESS)
- return result;
- /* if play state, advance time */
- if ((parserState >= EAS_STATE_READY) && (parserState <= EAS_STATE_PAUSING))
- pStream->time += pStream->frameLength;
- done = EAS_TRUE;
- }
-
- /* assume we're not done, in case we abort out */
- else
- {
- pStream->streamFlags &= ~STREAM_FLAGS_PARSED;
- done = EAS_FALSE;
- }
-
- while (!done)
- {
-
- /* check for stopped state */
- if ((result = (*pParserModule->pfState)(pEASData, pStream->handle, &parserState)) != EAS_SUCCESS)
- return result;
- if (parserState > EAS_STATE_PLAY)
- {
- /* save current time if we're not in play mode */
- if (parseMode != eParserModePlay)
- pStream->time = time << 8;
- done = EAS_TRUE;
- break;
- }
-
- /* get the next event time */
- if (pParserModule->pfTime)
- {
- if ((result = (*pParserModule->pfTime)(pEASData, pStream->handle, &time)) != EAS_SUCCESS)
- return result;
-
- /* if next event is within this frame, parse it */
- if (time < (endTime >> 8))
- {
-
- /* parse the next event */
- if (pParserModule->pfEvent)
- if ((result = (*pParserModule->pfEvent)(pEASData, pStream->handle, parseMode)) != EAS_SUCCESS)
- return result;
- }
-
- /* no more events in this frame, advance time */
- else
- {
- pStream->time = endTime;
- done = EAS_TRUE;
- }
- }
-
- /* check for max workload exceeded */
- if (VMCheckWorkload(pEASData->pVoiceMgr))
- {
- /* stop even though we may not have parsed
- * all the events in this frame. The parser will try to
- * catch up on the next frame.
- */
- break;
- }
-
- /* give host a chance for an early abort */
- if (--yieldCount == 0)
- {
- if (EAS_HWYield(pEASData->hwInstData))
- break;
- yieldCount = YIELD_EVENT_COUNT;
- }
- }
-
- /* if no early abort, parsing is complete for this frame */
- if (done)
- pStream->streamFlags |= STREAM_FLAGS_PARSED;
-
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * EAS_ParseMetaData()
- *----------------------------------------------------------------------------
- * Purpose:
- *
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - file or stream handle
- * playLength - pointer to variable to store the play length (in msecs)
- *
- * Outputs:
- *
- *
- * Side Effects:
- * - resets the parser to the start of the file
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_ParseMetaData (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_I32 *playLength)
-{
- S_FILE_PARSER_INTERFACE *pParserModule;
- EAS_RESULT result;
- EAS_STATE state;
-
- pParserModule = (S_FILE_PARSER_INTERFACE*) pStream->pParserModule;
- if (pParserModule == NULL)
- return EAS_ERROR_FEATURE_NOT_AVAILABLE;
-
- /* check parser state */
- if ((result = (*pParserModule->pfState)(pEASData, pStream->handle, &state)) != EAS_SUCCESS)
- return result;
- if (state >= EAS_STATE_OPEN)
- return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
-
- /* if parser has metadata function, use that */
- if (pParserModule->pfGetMetaData != NULL)
- return pParserModule->pfGetMetaData(pEASData, pStream->handle, playLength);
-
- /* reset the parser to the beginning */
- if ((result = (*pParserModule->pfReset)(pEASData, pStream->handle)) != EAS_SUCCESS)
- return result;
-
- /* parse the file to end */
- pStream->time = 0;
- VMInitWorkload(pEASData->pVoiceMgr);
- if ((result = EAS_ParseEvents(pEASData, pStream, 0x7fffffff, eParserModeMetaData)) != EAS_SUCCESS)
- return result;
-
- /* get the parser time */
- if ((result = EAS_GetLocation(pEASData, pStream, playLength)) != EAS_SUCCESS)
- return result;
-
- /* reset the parser to the beginning */
- pStream->time = 0;
- return (*pParserModule->pfReset)(pEASData, pStream->handle);
-}
-
-/*----------------------------------------------------------------------------
- * EAS_RegisterMetaDataCallback()
- *----------------------------------------------------------------------------
- * Purpose:
- * Registers a metadata callback function for parsed metadata.
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - file or stream handle
- * cbFunc - pointer to host callback function
- * metaDataBuffer - pointer to metadata buffer
- * metaDataBufSize - maximum size of the metadata buffer
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_RegisterMetaDataCallback (
- EAS_DATA_HANDLE pEASData,
- EAS_HANDLE pStream,
- EAS_METADATA_CBFUNC cbFunc,
- char *metaDataBuffer,
- EAS_I32 metaDataBufSize,
- EAS_VOID_PTR pUserData)
-{
- S_METADATA_CB metadata;
-
- if (!EAS_StreamReady(pEASData, pStream))
- return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
-
- /* register callback function */
- metadata.callback = cbFunc;
- metadata.buffer = metaDataBuffer;
- metadata.bufferSize = metaDataBufSize;
- metadata.pUserData = pUserData;
- return EAS_SetStreamParameter(pEASData, pStream, PARSER_DATA_METADATA_CB, (EAS_I32) &metadata);
-}
-
-/*----------------------------------------------------------------------------
- * EAS_GetNoteCount ()
- *----------------------------------------------------------------------------
- * Returns the total number of notes played in this stream
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_GetNoteCount (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_I32 *pNoteCount)
-{
- if (!EAS_StreamReady(pEASData, pStream))
- return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
- return EAS_IntGetStrmParam(pEASData, pStream, PARSER_DATA_NOTE_COUNT, pNoteCount);
-}
-
-/*----------------------------------------------------------------------------
- * EAS_CloseFile()
- *----------------------------------------------------------------------------
- * Purpose:
- * Closes an audio file or stream. Playback should have either paused or
- * completed (EAS_State returns EAS_PAUSED or EAS_STOPPED).
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - file or stream handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_CloseFile (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream)
-{
- S_FILE_PARSER_INTERFACE *pParserModule;
- EAS_RESULT result;
-
- /* call the close function */
- pParserModule = (S_FILE_PARSER_INTERFACE*) pStream->pParserModule;
- if (pParserModule == NULL)
- return EAS_ERROR_FEATURE_NOT_AVAILABLE;
-
- result = (*pParserModule->pfClose)(pEASData, pStream->handle);
-
- /* clear the handle and parser interface pointer */
- pStream->handle = NULL;
- pStream->pParserModule = NULL;
- return result;
-}
-
-/*----------------------------------------------------------------------------
- * EAS_OpenMIDIStream()
- *----------------------------------------------------------------------------
- * Purpose:
- * Opens a raw MIDI stream allowing the host to route MIDI cable data directly to the synthesizer
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * pHandle - pointer to variable to hold file or stream handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_OpenMIDIStream (EAS_DATA_HANDLE pEASData, EAS_HANDLE *ppStream, EAS_HANDLE streamHandle)
-{
- EAS_RESULT result;
- S_INTERACTIVE_MIDI *pMIDIStream;
- EAS_INT streamNum;
-
- /* initialize some pointers */
- *ppStream = NULL;
-
- /* allocate a stream */
- if ((streamNum = EAS_AllocateStream(pEASData)) < 0)
- return EAS_ERROR_MAX_STREAMS_OPEN;
-
- /* check Configuration Module for S_EAS_DATA allocation */
- if (pEASData->staticMemoryModel)
- pMIDIStream = EAS_CMEnumData(EAS_CM_MIDI_STREAM_DATA);
- else
- pMIDIStream = EAS_HWMalloc(pEASData->hwInstData, sizeof(S_INTERACTIVE_MIDI));
-
- /* allocate dynamic memory */
- if (!pMIDIStream)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_FATAL, "Failed to allocate MIDI stream data\n"); */ }
- return EAS_ERROR_MALLOC_FAILED;
- }
-
- /* zero the memory to insure complete initialization */
- EAS_HWMemSet(pMIDIStream, 0, sizeof(S_INTERACTIVE_MIDI));
- EAS_InitStream(&pEASData->streams[streamNum], NULL, pMIDIStream);
-
- /* instantiate a new synthesizer */
- if (streamHandle == NULL)
- {
- result = VMInitMIDI(pEASData, &pMIDIStream->pSynth);
- }
-
- /* use an existing synthesizer */
- else
- {
- EAS_I32 value;
- result = EAS_GetStreamParameter(pEASData, streamHandle, PARSER_DATA_SYNTH_HANDLE, &value);
- pMIDIStream->pSynth = (S_SYNTH*) value;
- VMIncRefCount(pMIDIStream->pSynth);
- }
- if (result != EAS_SUCCESS)
- {
- EAS_CloseMIDIStream(pEASData, &pEASData->streams[streamNum]);
- return result;
- }
-
- /* initialize the MIDI stream data */
- EAS_InitMIDIStream(&pMIDIStream->stream);
-
- *ppStream = (EAS_HANDLE) &pEASData->streams[streamNum];
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * EAS_WriteMIDIStream()
- *----------------------------------------------------------------------------
- * Purpose:
- * Send data to the MIDI stream device
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - stream handle
- * pBuffer - pointer to buffer
- * count - number of bytes to write
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_WriteMIDIStream (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_U8 *pBuffer, EAS_I32 count)
-{
- S_INTERACTIVE_MIDI *pMIDIStream;
- EAS_RESULT result;
-
- pMIDIStream = (S_INTERACTIVE_MIDI*) pStream->handle;
-
- /* send the entire buffer */
- while (count--)
- {
- if ((result = EAS_ParseMIDIStream(pEASData, pMIDIStream->pSynth, &pMIDIStream->stream, *pBuffer++, eParserModePlay)) != EAS_SUCCESS)
- return result;
- }
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * EAS_CloseMIDIStream()
- *----------------------------------------------------------------------------
- * Purpose:
- * Closes a raw MIDI stream
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - stream handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_CloseMIDIStream (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream)
-{
- S_INTERACTIVE_MIDI *pMIDIStream;
-
- pMIDIStream = (S_INTERACTIVE_MIDI*) pStream->handle;
-
- /* close synth */
- if (pMIDIStream->pSynth != NULL)
- {
- VMMIDIShutdown(pEASData, pMIDIStream->pSynth);
- pMIDIStream->pSynth = NULL;
- }
-
- /* release allocated memory */
- if (!pEASData->staticMemoryModel)
- EAS_HWFree(((S_EAS_DATA*) pEASData)->hwInstData, pMIDIStream);
-
- pStream->handle = NULL;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * EAS_State()
- *----------------------------------------------------------------------------
- * Purpose:
- * Returns the state of an audio file or stream.
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - file or stream handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_State (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_STATE *pState)
-{
- S_FILE_PARSER_INTERFACE *pParserModule;
- EAS_RESULT result;
-
- /* call the parser to return state */
- pParserModule = (S_FILE_PARSER_INTERFACE*) pStream->pParserModule;
- if (pParserModule == NULL)
- return EAS_ERROR_FEATURE_NOT_AVAILABLE;
-
- if ((result = (*pParserModule->pfState)(pEASData, pStream->handle, pState)) != EAS_SUCCESS)
- return result;
-
- /* if repeat count is set for this parser, mask the stopped state from the application */
- if (pStream->repeatCount && (*pState == EAS_STATE_STOPPED))
- *pState = EAS_STATE_PLAY;
-
- /* if we're not ready or playing, we don't need to hide state from host */
- if (*pState > EAS_STATE_PLAY)
- return EAS_SUCCESS;
-
- /* if stream is about to be paused, report it as paused */
- if (pStream->streamFlags & STREAM_FLAGS_PAUSE)
- {
- if (pStream->streamFlags & STREAM_FLAGS_LOCATE)
- *pState = EAS_STATE_PAUSED;
- else
- *pState = EAS_STATE_PAUSING;
- }
-
- /* if stream is about to resume, report it as playing */
- if (pStream->streamFlags & STREAM_FLAGS_RESUME)
- *pState = EAS_STATE_PLAY;
-
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * EAS_SetPolyphony()
- *----------------------------------------------------------------------------
- * Purpose:
- * Set the polyphony of the stream. A value of 0 allows the stream
- * to use all voices (set by EAS_SetSynthPolyphony).
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * streamHandle - handle returned by EAS_OpenFile
- * polyphonyCount - the desired polyphony count
- *
- * Outputs:
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_SetPolyphony (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_I32 polyphonyCount)
-{
- if (!EAS_StreamReady(pEASData, pStream))
- return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
- return EAS_IntSetStrmParam(pEASData, pStream, PARSER_DATA_POLYPHONY, polyphonyCount);
-}
-
-/*----------------------------------------------------------------------------
- * EAS_GetPolyphony()
- *----------------------------------------------------------------------------
- * Purpose:
- * Returns the current polyphony setting of the stream
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * streamHandle - handle returned by EAS_OpenFile
- * pPolyphonyCount - pointer to variable to receive polyphony count
- *
- * Outputs:
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_GetPolyphony (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_I32 *pPolyphonyCount)
-{
- if (!EAS_StreamReady(pEASData, pStream))
- return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
- return EAS_IntGetStrmParam(pEASData, pStream, PARSER_DATA_POLYPHONY, pPolyphonyCount);
-}
-
-/*----------------------------------------------------------------------------
- * EAS_SetSynthPolyphony()
- *----------------------------------------------------------------------------
- * Purpose:
- * Set the polyphony of the synth . Value must be >= 1 and <= the
- * maximum number of voices. This function will pin the polyphony
- * at those limits
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * synthNum - synthesizer number (0 = onboard, 1 = DSP)
- * polyphonyCount - the desired polyphony count
- *
- * Outputs:
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_SetSynthPolyphony (EAS_DATA_HANDLE pEASData, EAS_I32 synthNum, EAS_I32 polyphonyCount)
-{
- return VMSetSynthPolyphony(pEASData->pVoiceMgr, synthNum, polyphonyCount);
-}
-
-/*----------------------------------------------------------------------------
- * EAS_GetSynthPolyphony()
- *----------------------------------------------------------------------------
- * Purpose:
- * Returns the current polyphony setting of the synth
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * synthNum - synthesizer number (0 = onboard, 1 = DSP)
- * pPolyphonyCount - pointer to variable to receive polyphony count
- *
- * Outputs:
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_GetSynthPolyphony (EAS_DATA_HANDLE pEASData, EAS_I32 synthNum, EAS_I32 *pPolyphonyCount)
-{
- return VMGetSynthPolyphony(pEASData->pVoiceMgr, synthNum, pPolyphonyCount);
-}
-
-/*----------------------------------------------------------------------------
- * EAS_SetPriority()
- *----------------------------------------------------------------------------
- * Purpose:
- * Set the priority of the stream. Determines which stream's voices
- * are stolen when there are insufficient voices for all notes.
- * Value must be in the range of 1-15, lower values are higher
- * priority.
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * streamHandle - handle returned by EAS_OpenFile
- * polyphonyCount - the desired polyphony count
- *
- * Outputs:
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_SetPriority (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_I32 priority)
-{
- if (!EAS_StreamReady(pEASData, pStream))
- return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
- return EAS_IntSetStrmParam(pEASData, pStream, PARSER_DATA_PRIORITY, priority);
-}
-
-/*----------------------------------------------------------------------------
- * EAS_GetPriority()
- *----------------------------------------------------------------------------
- * Purpose:
- * Returns the current priority setting of the stream
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * streamHandle - handle returned by EAS_OpenFile
- * pPriority - pointer to variable to receive priority
- *
- * Outputs:
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_GetPriority (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_I32 *pPriority)
-{
- if (!EAS_StreamReady(pEASData, pStream))
- return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
- return EAS_IntGetStrmParam(pEASData, pStream, PARSER_DATA_PRIORITY, pPriority);
-}
-
-/*----------------------------------------------------------------------------
- * EAS_SetVolume()
- *----------------------------------------------------------------------------
- * Purpose:
- * Set the master gain for the mix engine in 1dB increments
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * volume - the desired master gain (100 is max)
- * handle - file or stream handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- * overrides any previously set master volume from sysex
- *
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_SetVolume (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_I32 volume)
-{
- EAS_I16 gain;
-
- /* check range */
- if ((volume < 0) || (volume > EAS_MAX_VOLUME))
- return EAS_ERROR_PARAMETER_RANGE;
-
- /* stream volume */
- if (pStream != NULL)
- {
- EAS_I32 gainOffset;
- EAS_RESULT result;
-
- if (!EAS_StreamReady(pEASData, pStream))
- return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
-
- /* get gain offset */
- pStream->volume = (EAS_U8) volume;
- result = EAS_GetStreamParameter(pEASData, pStream, PARSER_DATA_GAIN_OFFSET, &gainOffset);
- if (result == EAS_SUCCESS)
- volume += gainOffset;
-
- /* set stream volume */
- gain = EAS_VolumeToGain(volume - STREAM_VOLUME_HEADROOM);
-
- /* convert to linear scalar */
- return EAS_IntSetStrmParam(pEASData, pStream, PARSER_DATA_VOLUME, gain);
- }
-
- /* master volume */
- pEASData->masterVolume = (EAS_U8) volume;
-#if (NUM_OUTPUT_CHANNELS == 1)
- /* leave 3dB headroom for mono output */
- volume -= 3;
-#endif
-
- gain = EAS_VolumeToGain(volume - STREAM_VOLUME_HEADROOM);
- pEASData->masterGain = gain;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * EAS_GetVolume()
- *----------------------------------------------------------------------------
- * Purpose:
- * Returns the master volume for the synthesizer. The default volume setting is
- * 50. The volume range is 0 to 100;
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * volume - the desired master volume
- * handle - file or stream handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- * overrides any previously set master volume from sysex
- *
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_I32 EAS_GetVolume (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream)
-{
- if (pStream == NULL)
- return pEASData->masterVolume;
-
- if (!EAS_StreamReady(pEASData, pStream))
- return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
- return pStream->volume;
-}
-
-/*----------------------------------------------------------------------------
- * EAS_SetMaxLoad()
- *----------------------------------------------------------------------------
- * Purpose:
- * Sets the maximum workload the parsers will do in a single call to
- * EAS_Render. The units are currently arbitrary, but should correlate
- * well to the actual CPU cycles consumed. The primary effect is to
- * reduce the occasional peaks in CPU cycles consumed when parsing
- * dense parts of a MIDI score.
- *
- * Inputs:
- * pEASData - handle to data for this instance
- * maxLoad - the desired maximum workload
- *
- * Outputs:
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_SetMaxLoad (EAS_DATA_HANDLE pEASData, EAS_I32 maxLoad)
-{
- VMSetWorkload(pEASData->pVoiceMgr, maxLoad);
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * EAS_SetMaxPCMStreams()
- *----------------------------------------------------------------------------
- * Sets the maximum number of PCM streams allowed in parsers that
- * use PCM streaming.
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * streamHandle - handle returned by EAS_OpenFile
- * maxNumStreams - maximum number of PCM streams
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_SetMaxPCMStreams (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_I32 maxNumStreams)
-{
- if (!EAS_StreamReady(pEASData, pStream))
- return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
- return EAS_IntSetStrmParam(pEASData, pStream, PARSER_DATA_MAX_PCM_STREAMS, maxNumStreams);
-}
-
-/*----------------------------------------------------------------------------
- * EAS_Locate()
- *----------------------------------------------------------------------------
- * Purpose:
- * Locate into the file associated with the handle.
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - file handle
- * milliseconds - playback offset from start of file in milliseconds
- *
- * Outputs:
- *
- *
- * Side Effects:
- * the actual offset will be quantized to the closest update period, typically
- * a resolution of 5.9ms. Notes that are started prior to this time will not
- * sound. Any notes currently playing will be shut off.
- *
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_Locate (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_I32 milliseconds, EAS_BOOL offset)
-{
- S_FILE_PARSER_INTERFACE *pParserModule;
- EAS_RESULT result;
- EAS_U32 requestedTime;
- EAS_STATE state;
-
- /* get pointer to parser function table */
- pParserModule = (S_FILE_PARSER_INTERFACE*) pStream->pParserModule;
- if (pParserModule == NULL)
- return EAS_ERROR_FEATURE_NOT_AVAILABLE;
-
- if ((result = (*pParserModule->pfState)(pEASData, pStream->handle, &state)) != EAS_SUCCESS)
- return result;
- if (state >= EAS_STATE_OPEN)
- return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
-
- /* handle offset and limit to start of file */
- /*lint -e{704} use shift for performance*/
- if (offset)
- milliseconds += (EAS_I32) pStream->time >> 8;
- if (milliseconds < 0)
- milliseconds = 0;
-
- /* check to see if the request is different from the current time */
- requestedTime = (EAS_U32) milliseconds;
- if (requestedTime == (pStream->time >> 8))
- return EAS_SUCCESS;
-
- /* set the locate flag */
- pStream->streamFlags |= STREAM_FLAGS_LOCATE;
-
- /* use the parser locate function, if available */
- if (pParserModule->pfLocate != NULL)
- {
- EAS_BOOL parserLocate = EAS_FALSE;
- result = pParserModule->pfLocate(pEASData, pStream->handle, (EAS_I32) requestedTime, &parserLocate);
- if (!parserLocate)
- {
- if (result == EAS_SUCCESS)
- pStream->time = requestedTime << 8;
- return result;
- }
- }
-
- /* if we were paused and not going to resume, set pause request flag */
- if (((state == EAS_STATE_PAUSING) || (state == EAS_STATE_PAUSED)) && ((pStream->streamFlags & STREAM_FLAGS_RESUME) == 0))
- pStream->streamFlags |= STREAM_FLAGS_PAUSE;
-
- /* reset the synth and parser */
- if ((result = (*pParserModule->pfReset)(pEASData, pStream->handle)) != EAS_SUCCESS)
- return result;
- pStream->time = 0;
-
- /* locating forward, clear parsed flag and parse data until we get to the requested location */
- if ((result = EAS_ParseEvents(pEASData, pStream, requestedTime << 8, eParserModeLocate)) != EAS_SUCCESS)
- return result;
-
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * EAS_GetLocation()
- *----------------------------------------------------------------------------
- * Purpose:
- * Returns the current playback offset
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - file handle
- *
- * Outputs:
- * The offset in milliseconds from the start of the current sequence, quantized
- * to the nearest update period. Actual resolution is typically 5.9 ms.
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, pEASData) reserved for future use */
-EAS_PUBLIC EAS_RESULT EAS_GetLocation (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_I32 *pTime)
-{
- if (!EAS_StreamReady(pEASData, pStream))
- return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
-
- *pTime = pStream->time >> 8;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * EAS_GetRenderTime()
- *----------------------------------------------------------------------------
- * Purpose:
- * Returns the current playback offset
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- *
- * Outputs:
- * Gets the render time clock in msecs.
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_GetRenderTime (EAS_DATA_HANDLE pEASData, EAS_I32 *pTime)
-{
- *pTime = pEASData->renderTime >> 8;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * EAS_Pause()
- *----------------------------------------------------------------------------
- * Purpose:
- * Pauses the playback of the data associated with this handle. The audio
- * is gracefully ramped down to prevent clicks and pops. It may take several
- * buffers of audio before the audio is muted.
- *
- * Inputs:
- * psEASData - pointer to overall EAS data structure
- * handle - file or stream handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_Pause (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream)
-{
- S_FILE_PARSER_INTERFACE *pParserModule;
- EAS_STATE state;
- EAS_RESULT result;
-
- pParserModule = (S_FILE_PARSER_INTERFACE*) pStream->pParserModule;
- if (pParserModule == NULL)
- return EAS_ERROR_FEATURE_NOT_AVAILABLE;
-
- /* check for valid state */
- result = pParserModule->pfState(pEASData, pStream->handle, &state);
- if (result == EAS_SUCCESS)
- {
- if ((state != EAS_STATE_PLAY) && (state != EAS_STATE_READY) && ((pStream->streamFlags & STREAM_FLAGS_RESUME) == 0))
- return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
-
- /* make sure parser implements pause */
- if (pParserModule->pfPause == NULL)
- result = EAS_ERROR_NOT_IMPLEMENTED;
-
- /* clear resume flag */
- pStream->streamFlags &= ~STREAM_FLAGS_RESUME;
-
- /* set pause flag */
- pStream->streamFlags |= STREAM_FLAGS_PAUSE;
-
-#if 0
- /* pause the stream */
- if (pParserModule->pfPause)
- result = pParserModule->pfPause(pEASData, pStream->handle);
- else
- result = EAS_ERROR_NOT_IMPLEMENTED;
-#endif
- }
-
- return result;
-}
-
-/*----------------------------------------------------------------------------
- * EAS_Resume()
- *----------------------------------------------------------------------------
- * Purpose:
- * Resumes the playback of the data associated with this handle. The audio
- * is gracefully ramped up to prevent clicks and pops.
- *
- * Inputs:
- * psEASData - pointer to overall EAS data structure
- * handle - file or stream handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_Resume (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream)
-{
- S_FILE_PARSER_INTERFACE *pParserModule;
- EAS_STATE state;
- EAS_RESULT result;
-
- pParserModule = (S_FILE_PARSER_INTERFACE*) pStream->pParserModule;
- if (pParserModule == NULL)
- return EAS_ERROR_FEATURE_NOT_AVAILABLE;
-
- /* check for valid state */
- result = pParserModule->pfState(pEASData, pStream->handle, &state);
- if (result == EAS_SUCCESS)
- {
- if ((state != EAS_STATE_PAUSED) && (state != EAS_STATE_PAUSING) && ((pStream->streamFlags & STREAM_FLAGS_PAUSE) == 0))
- return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
-
- /* make sure parser implements this function */
- if (pParserModule->pfResume == NULL)
- result = EAS_ERROR_NOT_IMPLEMENTED;
-
- /* clear pause flag */
- pStream->streamFlags &= ~STREAM_FLAGS_PAUSE;
-
- /* set resume flag */
- pStream->streamFlags |= STREAM_FLAGS_RESUME;
-
-#if 0
- /* resume the stream */
- if (pParserModule->pfResume)
- result = pParserModule->pfResume(pEASData, pStream->handle);
- else
- result = EAS_ERROR_NOT_IMPLEMENTED;
-#endif
- }
-
- return result;
-}
-
-/*----------------------------------------------------------------------------
- * EAS_GetParameter()
- *----------------------------------------------------------------------------
- * Purpose:
- * Set the parameter of a module. See E_MODULES for a list of modules
- * and the header files of the modules for a list of parameters.
- *
- * Inputs:
- * psEASData - pointer to overall EAS data structure
- * handle - file or stream handle
- * module - enumerated module number
- * param - enumerated parameter number
- * pValue - pointer to variable to receive parameter value
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_GetParameter (EAS_DATA_HANDLE pEASData, EAS_I32 module, EAS_I32 param, EAS_I32 *pValue)
-{
-
- if (module >= NUM_EFFECTS_MODULES)
- return EAS_ERROR_INVALID_MODULE;
-
- if (pEASData->effectsModules[module].effectData == NULL)
- return EAS_ERROR_INVALID_MODULE;
-
- return (*pEASData->effectsModules[module].effect->pFGetParam)
- (pEASData->effectsModules[module].effectData, param, pValue);
-}
-
-/*----------------------------------------------------------------------------
- * EAS_SetParameter()
- *----------------------------------------------------------------------------
- * Purpose:
- * Set the parameter of a module. See E_MODULES for a list of modules
- * and the header files of the modules for a list of parameters.
- *
- * Inputs:
- * psEASData - pointer to overall EAS data structure
- * handle - file or stream handle
- * module - enumerated module number
- * param - enumerated parameter number
- * value - new parameter value
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_SetParameter (EAS_DATA_HANDLE pEASData, EAS_I32 module, EAS_I32 param, EAS_I32 value)
-{
-
- if (module >= NUM_EFFECTS_MODULES)
- return EAS_ERROR_INVALID_MODULE;
-
- if (pEASData->effectsModules[module].effectData == NULL)
- return EAS_ERROR_INVALID_MODULE;
-
- return (*pEASData->effectsModules[module].effect->pFSetParam)
- (pEASData->effectsModules[module].effectData, param, value);
-}
-
-#ifdef _METRICS_ENABLED
-/*----------------------------------------------------------------------------
- * EAS_MetricsReport()
- *----------------------------------------------------------------------------
- * Purpose:
- * Displays the current metrics through the metrics interface.
- *
- * Inputs:
- * p - instance data handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_MetricsReport (EAS_DATA_HANDLE pEASData)
-{
- if (!pEASData->pMetricsModule)
- return EAS_ERROR_INVALID_MODULE;
-
- return (*pEASData->pMetricsModule->pfReport)(pEASData->pMetricsData);
-}
-
-/*----------------------------------------------------------------------------
- * EAS_MetricsReset()
- *----------------------------------------------------------------------------
- * Purpose:
- * Resets the metrics.
- *
- * Inputs:
- * p - instance data handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_MetricsReset (EAS_DATA_HANDLE pEASData)
-{
-
- if (!pEASData->pMetricsModule)
- return EAS_ERROR_INVALID_MODULE;
-
- return (*pEASData->pMetricsModule->pfReset)(pEASData->pMetricsData);
-}
-#endif
-
-/*----------------------------------------------------------------------------
- * EAS_SetSoundLibrary()
- *----------------------------------------------------------------------------
- * Purpose:
- * Sets the location of the sound library.
- *
- * Inputs:
- * pEASData - instance data handle
- * pSoundLib - pointer to sound library
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_SetSoundLibrary (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_SNDLIB_HANDLE pSndLib)
-{
- if (pStream)
- {
- if (!EAS_StreamReady(pEASData, pStream))
- return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
- return EAS_IntSetStrmParam(pEASData, pStream, PARSER_DATA_EAS_LIBRARY, (EAS_I32) pSndLib);
- }
-
- return VMSetGlobalEASLib(pEASData->pVoiceMgr, pSndLib);
-}
-
-/*----------------------------------------------------------------------------
- * EAS_SetHeaderSearchFlag()
- *----------------------------------------------------------------------------
- * By default, when EAS_OpenFile is called, the parsers check the
- * first few bytes of the file looking for a specific header. Some
- * mobile devices may add a header to the start of a file, which
- * will prevent the parser from recognizing the file. If the
- * searchFlag is set to EAS_TRUE, the parser will search the entire
- * file looking for the header. This may enable EAS to recognize
- * some files that it would ordinarily reject. The negative is that
- * it make take slightly longer to process the EAS_OpenFile request.
- *
- * Inputs:
- * pEASData - instance data handle
- * searchFlag - search flag (EAS_TRUE or EAS_FALSE)
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_SetHeaderSearchFlag (EAS_DATA_HANDLE pEASData, EAS_BOOL searchFlag)
-{
- pEASData->searchHeaderFlag = (EAS_BOOL8) searchFlag;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * EAS_SetPlayMode()
- *----------------------------------------------------------------------------
- * Some file formats support special play modes, such as iMode partial
- * play mode. This call can be used to change the play mode. The
- * default play mode (usually straight playback) is always zero.
- *
- * Inputs:
- * pEASData - instance data handle
- * handle - file or stream handle
- * playMode - play mode (see file parser for specifics)
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_SetPlayMode (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_I32 playMode)
-{
- return EAS_IntSetStrmParam(pEASData, pStream, PARSER_DATA_PLAY_MODE, playMode);
-}
-
-#ifdef DLS_SYNTHESIZER
-/*----------------------------------------------------------------------------
- * EAS_LoadDLSCollection()
- *----------------------------------------------------------------------------
- * Purpose:
- * Sets the location of the sound library.
- *
- * Inputs:
- * pEASData - instance data handle
- * pSoundLib - pointer to sound library
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_LoadDLSCollection (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_FILE_LOCATOR locator)
-{
- EAS_FILE_HANDLE fileHandle;
- EAS_RESULT result;
- EAS_DLSLIB_HANDLE pDLS;
-
- if (pStream != NULL)
- {
- if (!EAS_StreamReady(pEASData, pStream))
- return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
- }
-
- /* open the file */
- if ((result = EAS_HWOpenFile(pEASData->hwInstData, locator, &fileHandle, EAS_FILE_READ)) != EAS_SUCCESS)
- return result;
-
- /* parse the file */
- result = DLSParser(pEASData->hwInstData, fileHandle, 0, &pDLS);
- EAS_HWCloseFile(pEASData->hwInstData, fileHandle);
-
- if (result == EAS_SUCCESS)
- {
-
- /* if a stream pStream is specified, point it to the DLS collection */
- if (pStream)
- result = EAS_IntSetStrmParam(pEASData, pStream, PARSER_DATA_DLS_COLLECTION, (EAS_I32) pDLS);
-
- /* global DLS load */
- else
- result = VMSetGlobalDLSLib(pEASData, pDLS);
- }
-
- return result;
-}
-#endif
-
-#ifdef EXTERNAL_AUDIO
-/*----------------------------------------------------------------------------
- * EAS_RegExtAudioCallback()
- *----------------------------------------------------------------------------
- * Purpose:
- * Registers callback functions for audio events.
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - file or stream handle
- * cbProgChgFunc - pointer to host callback function for program change
- * cbEventFunc - pointer to host callback functio for note events
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_RegExtAudioCallback (EAS_DATA_HANDLE pEASData,
- EAS_HANDLE pStream,
- EAS_VOID_PTR pInstData,
- EAS_EXT_PRG_CHG_FUNC cbProgChgFunc,
- EAS_EXT_EVENT_FUNC cbEventFunc)
-{
- S_SYNTH *pSynth;
-
- if (!EAS_StreamReady(pEASData, pStream))
- return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
-
- if (EAS_GetStreamParameter(pEASData, pStream, PARSER_DATA_SYNTH_HANDLE, (EAS_I32*) &pSynth) != EAS_SUCCESS)
- return EAS_ERROR_INVALID_PARAMETER;
-
- if (pSynth == NULL)
- return EAS_ERROR_INVALID_PARAMETER;
-
- VMRegExtAudioCallback(pSynth, pInstData, cbProgChgFunc, cbEventFunc);
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * EAS_GetMIDIControllers()
- *----------------------------------------------------------------------------
- * Purpose:
- * Returns the current state of MIDI controllers on the requested channel.
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - file or stream handle
- * pControl - pointer to structure to receive data
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_GetMIDIControllers (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_U8 channel, S_MIDI_CONTROLLERS *pControl)
-{
- S_SYNTH *pSynth;
-
- if (!EAS_StreamReady(pEASData, pStream))
- return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
-
- if (EAS_GetStreamParameter(pEASData, pStream, PARSER_DATA_SYNTH_HANDLE, (EAS_I32*) &pSynth) != EAS_SUCCESS)
- return EAS_ERROR_INVALID_PARAMETER;
-
- if (pSynth == NULL)
- return EAS_ERROR_INVALID_PARAMETER;
-
- VMGetMIDIControllers(pSynth, channel, pControl);
- return EAS_SUCCESS;
-}
-#endif
-
-#ifdef _SPLIT_ARCHITECTURE
-/*----------------------------------------------------------------------------
- * EAS_SetFrameBuffer()
- *----------------------------------------------------------------------------
- * Purpose:
- * Sets the frame buffer pointer passed to the IPC communications functions
- *
- * Inputs:
- * pEASData - instance data handle
- * locator - file locator
- *
- * Outputs:
- *
- *
- * Side Effects:
- * May overlay instruments in the GM sound set
- *
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT EAS_SetFrameBuffer (EAS_DATA_HANDLE pEASData, EAS_FRAME_BUFFER_HANDLE pFrameBuffer)
-{
- if (pEASData->pVoiceMgr)
- pEASData->pVoiceMgr->pFrameBuffer = pFrameBuffer;
- return EAS_SUCCESS;
-}
-#endif
-
-/*----------------------------------------------------------------------------
- * EAS_SearchFile
- *----------------------------------------------------------------------------
- * Search file for specific sequence starting at current file
- * position. Returns offset to start of sequence.
- *
- * Inputs:
- * pEASData - pointer to EAS persistent data object
- * fileHandle - file handle
- * searchString - pointer to search sequence
- * len - length of search sequence
- * pOffset - pointer to variable to store offset to sequence
- *
- * Returns EAS_EOF if end-of-file is reached
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT EAS_SearchFile (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle, const EAS_U8 *searchString, EAS_I32 len, EAS_I32 *pOffset)
-{
- EAS_RESULT result;
- EAS_INT index;
- EAS_U8 c;
-
- *pOffset = -1;
- index = 0;
- for (;;)
- {
- result = EAS_HWGetByte(pEASData->hwInstData, fileHandle, &c);
- if (result != EAS_SUCCESS)
- return result;
- if (c == searchString[index])
- {
- index++;
- if (index == 4)
- {
- result = EAS_HWFilePos(pEASData->hwInstData, fileHandle, pOffset);
- if (result != EAS_SUCCESS)
- return result;
- *pOffset -= len;
- break;
- }
- }
- else
- index = 0;
- }
- return EAS_SUCCESS;
-}
-
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 842 $
+ * $Date: 2007-08-23 14:32:31 -0700 (Thu, 23 Aug 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+#include "eas_synthcfg.h"
+#include "eas.h"
+#include "eas_config.h"
+#include "eas_host.h"
+#include "eas_report.h"
+#include "eas_data.h"
+#include "eas_parser.h"
+#include "eas_pcm.h"
+#include "eas_midi.h"
+#include "eas_mixer.h"
+#include "eas_build.h"
+#include "eas_vm_protos.h"
+#include "eas_math.h"
+
+#ifdef JET_INTERFACE
+#include "jet_data.h"
+#endif
+
+#ifdef DLS_SYNTHESIZER
+#include "eas_mdls.h"
+#endif
+
+/* number of events to parse before calling EAS_HWYield function */
+#define YIELD_EVENT_COUNT 10
+
+/*----------------------------------------------------------------------------
+ * easLibConfig
+ *
+ * This structure is available through the EAS public interface to allow
+ * the user to check the configuration of the library.
+ *----------------------------------------------------------------------------
+*/
+static const S_EAS_LIB_CONFIG easLibConfig =
+{
+ LIB_VERSION,
+#ifdef _CHECKED_BUILD
+ EAS_TRUE,
+#else
+ EAS_FALSE,
+#endif
+ MAX_SYNTH_VOICES,
+ NUM_OUTPUT_CHANNELS,
+ _OUTPUT_SAMPLE_RATE,
+ BUFFER_SIZE_IN_MONO_SAMPLES,
+#ifdef _FILTER_ENABLED
+ EAS_TRUE,
+#else
+ EAS_FALSE,
+#endif
+ _BUILD_TIME_,
+ _BUILD_VERSION_
+};
+
+/* local prototypes */
+static EAS_RESULT EAS_ParseEvents (S_EAS_DATA *pEASData, S_EAS_STREAM *pStream, EAS_U32 endTime, EAS_INT parseMode);
+
+/*----------------------------------------------------------------------------
+ * EAS_SetStreamParameter
+ *----------------------------------------------------------------------------
+ * Sets the specified parameter in the stream. Allows access to
+ * customizable settings within the individual file parsers.
+ *----------------------------------------------------------------------------
+ * pEASData - pointer to EAS persistent data object
+ * pStream - stream handle
+ * param - enumerated parameter (see eas_parser.h)
+ * value - new value
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_SetStreamParameter (S_EAS_DATA *pEASData, EAS_HANDLE pStream, EAS_I32 param, EAS_I32 value)
+{
+ S_FILE_PARSER_INTERFACE *pParserModule;
+
+ pParserModule = (S_FILE_PARSER_INTERFACE*) pStream->pParserModule;
+ if (pParserModule->pfSetData)
+ return (*pParserModule->pfSetData)(pEASData, pStream->handle, param, value);
+ return EAS_ERROR_FEATURE_NOT_AVAILABLE;
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_GetStreamParameter
+ *----------------------------------------------------------------------------
+ * Sets the specified parameter in the stream. Allows access to
+ * customizable settings within the individual file parsers.
+ *----------------------------------------------------------------------------
+ * pEASData - pointer to EAS persistent data object
+ * pStream - stream handle
+ * param - enumerated parameter (see eas_parser.h)
+ * pValue - pointer to variable to receive current setting
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_GetStreamParameter (S_EAS_DATA *pEASData, EAS_HANDLE pStream, EAS_I32 param, EAS_I32 *pValue)
+{
+ S_FILE_PARSER_INTERFACE *pParserModule;
+
+ pParserModule = (S_FILE_PARSER_INTERFACE*) pStream->pParserModule;
+ if (pParserModule->pfGetData)
+ return (*pParserModule->pfGetData)(pEASData, pStream->handle, param, pValue);
+ return EAS_ERROR_FEATURE_NOT_AVAILABLE;
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_StreamReady()
+ *----------------------------------------------------------------------------
+ * This routine sets common parameters like transpose, volume, etc.
+ * First, it attempts to use the parser EAS_SetStreamParameter interface. If that
+ * fails, it attempts to get the synth handle from the parser and
+ * set the parameter directly on the synth. This eliminates duplicate
+ * code in the parser.
+ *----------------------------------------------------------------------------
+*/
+EAS_BOOL EAS_StreamReady (S_EAS_DATA *pEASData, EAS_HANDLE pStream)
+{
+ S_FILE_PARSER_INTERFACE *pParserModule;
+ EAS_STATE state;
+
+ pParserModule = (S_FILE_PARSER_INTERFACE*) pStream->pParserModule;
+ if (pParserModule->pfState(pEASData, pStream->handle, &state) != EAS_SUCCESS)
+ return EAS_FALSE;
+ return (state < EAS_STATE_OPEN);
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_IntSetStrmParam()
+ *----------------------------------------------------------------------------
+ * This routine sets common parameters like transpose, volume, etc.
+ * First, it attempts to use the parser EAS_SetStreamParameter interface. If that
+ * fails, it attempts to get the synth handle from the parser and
+ * set the parameter directly on the synth. This eliminates duplicate
+ * code in the parser.
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_IntSetStrmParam (S_EAS_DATA *pEASData, EAS_HANDLE pStream, EAS_INT param, EAS_I32 value)
+{
+ S_SYNTH *pSynth;
+
+ /* try to set the parameter using stream interface */
+ if (EAS_SetStreamParameter(pEASData, pStream, param, value) == EAS_SUCCESS)
+ return EAS_SUCCESS;
+
+ /* get a pointer to the synth object and set it directly */
+ /*lint -e{740} we are cheating by passing a pointer through this interface */
+ if (EAS_GetStreamParameter(pEASData, pStream, PARSER_DATA_SYNTH_HANDLE, (EAS_I32*) &pSynth) != EAS_SUCCESS)
+ return EAS_ERROR_INVALID_PARAMETER;
+
+ if (pSynth == NULL)
+ return EAS_ERROR_INVALID_PARAMETER;
+
+ switch (param)
+ {
+
+#ifdef DLS_SYNTHESIZER
+ case PARSER_DATA_DLS_COLLECTION:
+ {
+ EAS_RESULT result = VMSetDLSLib(pSynth, (EAS_DLSLIB_HANDLE) value);
+ if (result == EAS_SUCCESS)
+ {
+ DLSAddRef((S_DLS*) value);
+ VMInitializeAllChannels(pEASData->pVoiceMgr, pSynth);
+ }
+ return result;
+ }
+#endif
+
+ case PARSER_DATA_EAS_LIBRARY:
+ return VMSetEASLib(pSynth, (EAS_SNDLIB_HANDLE) value);
+
+ case PARSER_DATA_POLYPHONY:
+ return VMSetPolyphony(pEASData->pVoiceMgr, pSynth, value);
+
+ case PARSER_DATA_PRIORITY:
+ return VMSetPriority(pEASData->pVoiceMgr, pSynth, value);
+
+ case PARSER_DATA_TRANSPOSITION:
+ VMSetTranposition(pSynth, value);
+ break;
+
+ case PARSER_DATA_VOLUME:
+ VMSetVolume(pSynth, (EAS_U16) value);
+ break;
+
+ default:
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Invalid paramter %d in call to EAS_IntSetStrmParam", param); */ }
+ return EAS_ERROR_INVALID_PARAMETER;
+ }
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_IntGetStrmParam()
+ *----------------------------------------------------------------------------
+ * This routine gets common parameters like transpose, volume, etc.
+ * First, it attempts to use the parser EAS_GetStreamParameter interface. If that
+ * fails, it attempts to get the synth handle from the parser and
+ * get the parameter directly on the synth.
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_IntGetStrmParam (S_EAS_DATA *pEASData, EAS_HANDLE pStream, EAS_INT param, EAS_I32 *pValue)
+{
+ S_SYNTH *pSynth;
+
+ /* try to set the parameter */
+ if (EAS_GetStreamParameter(pEASData, pStream, param, pValue) == EAS_SUCCESS)
+ return EAS_SUCCESS;
+
+ /* get a pointer to the synth object and retrieve data directly */
+ /*lint -e{740} we are cheating by passing a pointer through this interface */
+ if (EAS_GetStreamParameter(pEASData, pStream, PARSER_DATA_SYNTH_HANDLE, (EAS_I32*) &pSynth) != EAS_SUCCESS)
+ return EAS_ERROR_INVALID_PARAMETER;
+
+ if (pSynth == NULL)
+ return EAS_ERROR_INVALID_PARAMETER;
+
+ switch (param)
+ {
+ case PARSER_DATA_POLYPHONY:
+ return VMGetPolyphony(pEASData->pVoiceMgr, pSynth, pValue);
+
+ case PARSER_DATA_PRIORITY:
+ return VMGetPriority(pEASData->pVoiceMgr, pSynth, pValue);
+
+ case PARSER_DATA_TRANSPOSITION:
+ VMGetTranposition(pSynth, pValue);
+ break;
+
+ case PARSER_DATA_NOTE_COUNT:
+ *pValue = VMGetNoteCount(pSynth);
+ break;
+
+ default:
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Invalid paramter %d in call to EAS_IntSetStrmParam", param); */ }
+ return EAS_ERROR_INVALID_PARAMETER;
+ }
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_AllocateStream()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Allocates a stream handle
+ *
+ * Inputs:
+ *
+ * Outputs:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_INT EAS_AllocateStream (EAS_DATA_HANDLE pEASData)
+{
+ EAS_INT streamNum;
+
+ /* check for static allocation, only one stream allowed */
+ if (pEASData->staticMemoryModel)
+ {
+ if (pEASData->streams[0].handle != NULL)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Attempt to open multiple streams in static model\n"); */ }
+ return -1;
+ }
+ return 0;
+ }
+
+ /* dynamic model */
+ for (streamNum = 0; streamNum < MAX_NUMBER_STREAMS; streamNum++)
+ if (pEASData->streams[streamNum].handle == NULL)
+ break;
+ if (streamNum == MAX_NUMBER_STREAMS)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Exceeded maximum number of open streams\n"); */ }
+ return -1;
+ }
+ return streamNum;
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_InitStream()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Initialize a stream
+ *
+ * Inputs:
+ *
+ * Outputs:
+ *
+ *----------------------------------------------------------------------------
+*/
+static void EAS_InitStream (S_EAS_STREAM *pStream, EAS_VOID_PTR pParserModule, EAS_VOID_PTR streamHandle)
+{
+ pStream->pParserModule = pParserModule;
+ pStream->handle = streamHandle;
+ pStream->time = 0;
+ pStream->frameLength = AUDIO_FRAME_LENGTH;
+ pStream->repeatCount = 0;
+ pStream->volume = DEFAULT_STREAM_VOLUME;
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_Config()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Returns a pointer to a structure containing the configuration options
+ * in this library build.
+ *
+ * Inputs:
+ *
+ * Outputs:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC const S_EAS_LIB_CONFIG *EAS_Config (void)
+{
+ return &easLibConfig;
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_Init()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Initialize the synthesizer library
+ *
+ * Inputs:
+ * ppEASData - pointer to data handle variable for this instance
+ *
+ * Outputs:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_Init (EAS_DATA_HANDLE *ppEASData)
+{
+ EAS_HW_DATA_HANDLE pHWInstData;
+ EAS_RESULT result;
+ S_EAS_DATA *pEASData;
+ EAS_INT module;
+ EAS_BOOL staticMemoryModel;
+
+ /* get the memory model */
+ staticMemoryModel = EAS_CMStaticMemoryModel();
+
+ /* initialize the host wrapper interface */
+ *ppEASData = NULL;
+ if ((result = EAS_HWInit(&pHWInstData)) != EAS_SUCCESS)
+ return result;
+
+ /* check Configuration Module for S_EAS_DATA allocation */
+ if (staticMemoryModel)
+ pEASData = EAS_CMEnumData(EAS_CM_EAS_DATA);
+ else
+ pEASData = EAS_HWMalloc(pHWInstData, sizeof(S_EAS_DATA));
+ if (!pEASData)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_FATAL, "Failed to allocate EAS library memory\n"); */ }
+ return EAS_ERROR_MALLOC_FAILED;
+ }
+
+ /* initialize some data */
+ EAS_HWMemSet(pEASData, 0, sizeof(S_EAS_DATA));
+ pEASData->staticMemoryModel = (EAS_BOOL8) staticMemoryModel;
+ pEASData->hwInstData = pHWInstData;
+ pEASData->renderTime = 0;
+
+ /* set header search flag */
+#ifdef FILE_HEADER_SEARCH
+ pEASData->searchHeaderFlag = EAS_TRUE;
+#endif
+
+ /* initalize parameters */
+ EAS_SetVolume(pEASData, NULL, DEFAULT_VOLUME);
+
+#ifdef _METRICS_ENABLED
+ /* initalize the metrics module */
+ pEASData->pMetricsModule = EAS_CMEnumOptModules(EAS_MODULE_METRICS);
+ if (pEASData->pMetricsModule != NULL)
+ {
+ if ((result = (*pEASData->pMetricsModule->pfInit)(pEASData, &pEASData->pMetricsData)) != EAS_SUCCESS)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Error %ld initializing metrics module\n", result); */ }
+ return result;
+ }
+ }
+#endif
+
+ /* initailize the voice manager & synthesizer */
+ if ((result = VMInitialize(pEASData)) != EAS_SUCCESS)
+ return result;
+
+ /* initialize mix engine */
+ if ((result = EAS_MixEngineInit(pEASData)) != EAS_SUCCESS)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Error %ld starting up mix engine\n", result); */ }
+ return result;
+ }
+
+ /* initialize effects modules */
+ for (module = 0; module < NUM_EFFECTS_MODULES; module++)
+ {
+ pEASData->effectsModules[module].effect = EAS_CMEnumFXModules(module);
+ if (pEASData->effectsModules[module].effect != NULL)
+ {
+ if ((result = (*pEASData->effectsModules[module].effect->pfInit)(pEASData, &pEASData->effectsModules[module].effectData)) != EAS_SUCCESS)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_FATAL, "Initialization of effects module %d returned %d\n", module, result); */ }
+ return result;
+ }
+ }
+ }
+
+ /* initialize PCM engine */
+ if ((result = EAS_PEInit(pEASData)) != EAS_SUCCESS)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_FATAL, "EAS_PEInit failed with error code %ld\n", result); */ }
+ return result;
+ }
+
+ /* return instance data pointer to host */
+ *ppEASData = pEASData;
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_Shutdown()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Shuts down the library. Deallocates any memory associated with the
+ * synthesizer (dynamic memory model only)
+ *
+ * Inputs:
+ * pEASData - handle to data for this instance
+ *
+ * Outputs:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_Shutdown (EAS_DATA_HANDLE pEASData)
+{
+ EAS_HW_DATA_HANDLE hwInstData;
+ EAS_RESULT result, reportResult;
+ EAS_INT i;
+
+ /* establish pointers */
+ hwInstData = pEASData->hwInstData;
+
+ /* check for NULL handle */
+ if (!pEASData)
+ return EAS_ERROR_HANDLE_INTEGRITY;
+
+ /* if there are streams open, close them */
+ reportResult = EAS_SUCCESS;
+ for (i = 0; i < MAX_NUMBER_STREAMS; i++)
+ {
+ if (pEASData->streams[i].pParserModule && pEASData->streams[i].handle)
+ {
+ if ((result = (*((S_FILE_PARSER_INTERFACE*)(pEASData->streams[i].pParserModule))->pfClose)(pEASData, pEASData->streams[i].handle)) != EAS_SUCCESS)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Error %ld shutting down parser module\n", result); */ }
+ reportResult = result;
+ }
+ }
+ }
+
+ /* shutdown PCM engine */
+ if ((result = EAS_PEShutdown(pEASData)) != EAS_SUCCESS)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Error %ld shutting down PCM engine\n", result); */ }
+ if (reportResult == EAS_SUCCESS)
+ reportResult = result;
+ }
+
+ /* shutdown mix engine */
+ if ((result = EAS_MixEngineShutdown(pEASData)) != EAS_SUCCESS)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Error %ld shutting down mix engine\n", result); */ }
+ if (reportResult == EAS_SUCCESS)
+ reportResult = result;
+ }
+
+ /* shutdown effects modules */
+ for (i = 0; i < NUM_EFFECTS_MODULES; i++)
+ {
+ if (pEASData->effectsModules[i].effect)
+ {
+ if ((result = (*pEASData->effectsModules[i].effect->pfShutdown)(pEASData, pEASData->effectsModules[i].effectData)) != EAS_SUCCESS)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_FATAL, "Shutdown of effects module %d returned %d\n", i, result); */ }
+ if (reportResult == EAS_SUCCESS)
+ reportResult = result;
+ }
+ }
+ }
+
+ /* shutdown the voice manager & synthesizer */
+ VMShutdown(pEASData);
+
+#ifdef _METRICS_ENABLED
+ /* shutdown the metrics module */
+ if (pEASData->pMetricsModule != NULL)
+ {
+ if ((result = (*pEASData->pMetricsModule->pfShutdown)(pEASData, pEASData->pMetricsData)) != EAS_SUCCESS)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Error %ld shutting down metrics module\n", result); */ }
+ if (reportResult == EAS_SUCCESS)
+ reportResult = result;
+ }
+ }
+#endif
+
+ /* release allocated memory */
+ if (!pEASData->staticMemoryModel)
+ EAS_HWFree(hwInstData, pEASData);
+
+ /* shutdown host wrappers */
+ if (hwInstData)
+ {
+ if ((result = EAS_HWShutdown(hwInstData)) != EAS_SUCCESS)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Error %ld shutting down host wrappers\n", result); */ }
+ if (reportResult == EAS_SUCCESS)
+ reportResult = result;
+ }
+ }
+
+ return reportResult;
+}
+
+#ifdef JET_INTERFACE
+/*----------------------------------------------------------------------------
+ * EAS_OpenJETStream()
+ *----------------------------------------------------------------------------
+ * Private interface for JET to open an SMF stream with an offset
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_OpenJETStream (EAS_DATA_HANDLE pEASData, EAS_FILE_HANDLE fileHandle, EAS_I32 offset, EAS_HANDLE *ppStream)
+{
+ EAS_RESULT result;
+ EAS_VOID_PTR streamHandle;
+ S_FILE_PARSER_INTERFACE *pParserModule;
+ EAS_INT streamNum;
+
+ /* allocate a stream */
+ if ((streamNum = EAS_AllocateStream(pEASData)) < 0)
+ return EAS_ERROR_MAX_STREAMS_OPEN;
+
+ /* check Configuration Module for SMF parser */
+ *ppStream = NULL;
+ streamHandle = NULL;
+ pParserModule = (S_FILE_PARSER_INTERFACE *) EAS_CMEnumModules(0);
+ if (pParserModule == NULL)
+ return EAS_ERROR_UNRECOGNIZED_FORMAT;
+
+ /* see if SMF parser recognizes the file */
+ if ((result = (*pParserModule->pfCheckFileType)(pEASData, fileHandle, &streamHandle, offset)) != EAS_SUCCESS)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "CheckFileType returned error %ld\n", result); */ }
+ return result;
+ }
+
+ /* parser recognized the file, return the handle */
+ if (streamHandle)
+ {
+ EAS_InitStream(&pEASData->streams[streamNum], pParserModule, streamHandle);
+ *ppStream = &pEASData->streams[streamNum];
+ return EAS_SUCCESS;
+ }
+
+ return EAS_ERROR_UNRECOGNIZED_FORMAT;
+}
+#endif
+
+/*----------------------------------------------------------------------------
+ * EAS_OpenFile()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Opens a file for audio playback.
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * pHandle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_OpenFile (EAS_DATA_HANDLE pEASData, EAS_FILE_LOCATOR locator, EAS_HANDLE *ppStream)
+{
+ EAS_RESULT result;
+ EAS_FILE_HANDLE fileHandle;
+ EAS_VOID_PTR streamHandle;
+ S_FILE_PARSER_INTERFACE *pParserModule;
+ EAS_INT streamNum;
+ EAS_INT moduleNum;
+
+ /* open the file */
+ if ((result = EAS_HWOpenFile(pEASData->hwInstData, locator, &fileHandle, EAS_FILE_READ)) != EAS_SUCCESS)
+ return result;
+
+ /* allocate a stream */
+ if ((streamNum = EAS_AllocateStream(pEASData)) < 0)
+ return EAS_ERROR_MAX_STREAMS_OPEN;
+
+ /* check Configuration Module for file parsers */
+ pParserModule = NULL;
+ *ppStream = NULL;
+ streamHandle = NULL;
+ for (moduleNum = 0; ; moduleNum++)
+ {
+ pParserModule = (S_FILE_PARSER_INTERFACE *) EAS_CMEnumModules(moduleNum);
+ if (pParserModule == NULL)
+ break;
+
+ /* see if this parser recognizes it */
+ if ((result = (*pParserModule->pfCheckFileType)(pEASData, fileHandle, &streamHandle, 0L)) != EAS_SUCCESS)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "CheckFileType returned error %ld\n", result); */ }
+ return result;
+ }
+
+ /* parser recognized the file, return the handle */
+ if (streamHandle)
+ {
+
+ /* save the parser pointer and file handle */
+ EAS_InitStream(&pEASData->streams[streamNum], pParserModule, streamHandle);
+ *ppStream = &pEASData->streams[streamNum];
+ return EAS_SUCCESS;
+ }
+
+ /* rewind the file for the next parser */
+ if ((result = EAS_HWFileSeek(pEASData->hwInstData, fileHandle, 0L)) != EAS_SUCCESS)
+ return result;
+ }
+
+ /* no parser was able to recognize the file, close it and return an error */
+ EAS_HWCloseFile(pEASData->hwInstData, fileHandle);
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "No parser recognized the requested file\n"); */ }
+ return EAS_ERROR_UNRECOGNIZED_FORMAT;
+}
+
+#ifdef MMAPI_SUPPORT
+/*----------------------------------------------------------------------------
+ * EAS_MMAPIToneControl()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Opens a ToneControl file for audio playback.
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * pHandle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_MMAPIToneControl (EAS_DATA_HANDLE pEASData, EAS_FILE_LOCATOR locator, EAS_HANDLE *ppStream)
+{
+ EAS_RESULT result;
+ EAS_FILE_HANDLE fileHandle;
+ EAS_VOID_PTR streamHandle;
+ S_FILE_PARSER_INTERFACE *pParserModule;
+ EAS_INT streamNum;
+
+ /* check if the tone control parser is available */
+ *ppStream = NULL;
+ streamHandle = NULL;
+ pParserModule = EAS_CMEnumOptModules(EAS_MODULE_MMAPI_TONE_CONTROL);
+ if (pParserModule == NULL)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "EAS_MMAPIToneControl: ToneControl parser not available\n"); */ }
+ return EAS_ERROR_FEATURE_NOT_AVAILABLE;
+ }
+
+ /* open the file */
+ if ((result = EAS_HWOpenFile(pEASData->hwInstData, locator, &fileHandle, EAS_FILE_READ)) != EAS_SUCCESS)
+ return result;
+
+ /* allocate a stream */
+ if ((streamNum = EAS_AllocateStream(pEASData)) < 0)
+ return EAS_ERROR_MAX_STREAMS_OPEN;
+
+ /* see if ToneControl parser recognizes it */
+ if ((result = (*pParserModule->pfCheckFileType)(pEASData, fileHandle, &streamHandle, 0L)) != EAS_SUCCESS)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "CheckFileType returned error %ld\n", result); */ }
+ return result;
+ }
+
+ /* parser accepted the file, return the handle */
+ if (streamHandle)
+ {
+
+ /* save the parser pointer and file handle */
+ EAS_InitStream(&pEASData->streams[streamNum], pParserModule, streamHandle);
+ *ppStream = &pEASData->streams[streamNum];
+ return EAS_SUCCESS;
+ }
+
+ /* parser did not recognize the file, close it and return an error */
+ EAS_HWCloseFile(pEASData->hwInstData, fileHandle);
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "No parser recognized the requested file\n"); */ }
+ return EAS_ERROR_UNRECOGNIZED_FORMAT;
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_GetWaveFmtChunk
+ *----------------------------------------------------------------------------
+ * Helper function to retrieve WAVE file fmt chunk for MMAPI
+ *----------------------------------------------------------------------------
+ * pEASData - pointer to EAS persistent data object
+ * pStream - stream handle
+ * pFmtChunk - pointer to variable to receive current setting
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_GetWaveFmtChunk (S_EAS_DATA *pEASData, EAS_HANDLE pStream, EAS_VOID_PTR *ppFmtChunk)
+{
+ EAS_RESULT result;
+ EAS_I32 value;
+
+ if ((result = EAS_GetStreamParameter(pEASData, pStream, PARSER_DATA_FORMAT, &value)) != EAS_SUCCESS)
+ return result;
+ *ppFmtChunk = (EAS_VOID_PTR) value;
+ return EAS_SUCCESS;
+}
+#endif
+
+/*----------------------------------------------------------------------------
+ * EAS_GetFileType
+ *----------------------------------------------------------------------------
+ * Returns the file type (see eas_types.h for enumerations)
+ *----------------------------------------------------------------------------
+ * pEASData - pointer to EAS persistent data object
+ * pStream - stream handle
+ * pFileType - pointer to variable to receive file type
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_GetFileType (S_EAS_DATA *pEASData, EAS_HANDLE pStream, EAS_I32 *pFileType)
+{
+ if (!EAS_StreamReady (pEASData, pStream))
+ return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
+ return EAS_GetStreamParameter(pEASData, pStream, PARSER_DATA_FILE_TYPE, pFileType);
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_Prepare()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Prepares the synthesizer to play the file or stream. Parses the first
+ * frame of data from the file and arms the synthesizer.
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - file or stream handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_Prepare (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream)
+{
+ S_FILE_PARSER_INTERFACE *pParserModule;
+ EAS_STATE state;
+ EAS_RESULT result;
+
+ pParserModule = (S_FILE_PARSER_INTERFACE*) pStream->pParserModule;
+ if (pParserModule == NULL)
+ return EAS_ERROR_FEATURE_NOT_AVAILABLE;
+
+ /* check for valid state */
+ result = pParserModule->pfState(pEASData, pStream->handle, &state);
+ if (result == EAS_SUCCESS)
+ {
+ /* prepare the stream */
+ if (state == EAS_STATE_OPEN)
+ {
+ pParserModule = (S_FILE_PARSER_INTERFACE*) pStream->pParserModule;
+ result = (*pParserModule->pfPrepare)(pEASData, pStream->handle);
+
+ /* set volume */
+ if (result == EAS_SUCCESS)
+ result = EAS_SetVolume(pEASData, pStream, pStream->volume);
+ }
+ else
+ result = EAS_ERROR_NOT_VALID_IN_THIS_STATE;
+
+ }
+
+ return result;
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_Render()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Parse the Midi data and render PCM audio data.
+ *
+ * Inputs:
+ * pEASData - buffer for internal EAS data
+ * pOut - output buffer pointer
+ * nNumRequested - requested num samples to generate
+ * pnNumGenerated - actual number of samples generated
+ *
+ * Outputs:
+ * EAS_SUCCESS if PCM data was successfully rendered
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_Render (EAS_DATA_HANDLE pEASData, EAS_PCM *pOut, EAS_I32 numRequested, EAS_I32 *pNumGenerated)
+{
+ S_FILE_PARSER_INTERFACE *pParserModule;
+ EAS_RESULT result;
+ EAS_I32 voicesRendered;
+ EAS_STATE parserState;
+ EAS_INT streamNum;
+
+ /* assume no samples generated and reset workload */
+ *pNumGenerated = 0;
+ VMInitWorkload(pEASData->pVoiceMgr);
+
+ /* no support for other buffer sizes yet */
+ if (numRequested != BUFFER_SIZE_IN_MONO_SAMPLES)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "This library supports only %ld samples in buffer, host requested %ld samples\n",
+ (EAS_I32) BUFFER_SIZE_IN_MONO_SAMPLES, numRequested); */ }
+ return EAS_BUFFER_SIZE_MISMATCH;
+ }
+
+#ifdef _METRICS_ENABLED
+ /* start performance counter */
+ if (pEASData->pMetricsData)
+ (*pEASData->pMetricsModule->pfStartTimer)(pEASData->pMetricsData, EAS_PM_TOTAL_TIME);
+#endif
+
+ /* prep the frame buffer, do mix engine prep only if TRUE */
+#ifdef _SPLIT_ARCHITECTURE
+ if (VMStartFrame(pEASData))
+ EAS_MixEnginePrep(pEASData, numRequested);
+#else
+ /* prep the mix engine */
+ EAS_MixEnginePrep(pEASData, numRequested);
+#endif
+
+ /* save the output buffer pointer */
+ pEASData->pOutputAudioBuffer = pOut;
+
+
+#ifdef _METRICS_ENABLED
+ /* start performance counter */
+ if (pEASData->pMetricsData)
+ (*pEASData->pMetricsModule->pfStartTimer)(pEASData->pMetricsData, EAS_PM_PARSE_TIME);
+#endif
+
+ /* if we haven't finished parsing from last time, do it now */
+ /* need to parse another frame of events before we render again */
+ for (streamNum = 0; streamNum < MAX_NUMBER_STREAMS; streamNum++)
+ {
+ /* clear the locate flag */
+ pEASData->streams[streamNum].streamFlags &= ~STREAM_FLAGS_LOCATE;
+
+ if (pEASData->streams[streamNum].pParserModule)
+ {
+
+ /* establish pointer to parser module */
+ pParserModule = pEASData->streams[streamNum].pParserModule;
+
+ /* handle pause */
+ if (pEASData->streams[streamNum].streamFlags & STREAM_FLAGS_PAUSE)
+ {
+ if (pParserModule->pfPause)
+ result = pParserModule->pfPause(pEASData, pEASData->streams[streamNum].handle);
+ pEASData->streams[streamNum].streamFlags &= ~STREAM_FLAGS_PAUSE;
+ }
+
+ /* get current state */
+ if ((result = (*pParserModule->pfState)(pEASData, pEASData->streams[streamNum].handle, &parserState)) != EAS_SUCCESS)
+ return result;
+
+ /* handle resume */
+ if (parserState == EAS_STATE_PAUSED)
+ {
+ if (pEASData->streams[streamNum].streamFlags & STREAM_FLAGS_RESUME)
+ {
+ if (pParserModule->pfResume)
+ result = pParserModule->pfResume(pEASData, pEASData->streams[streamNum].handle);
+ pEASData->streams[streamNum].streamFlags &= ~STREAM_FLAGS_RESUME;
+ }
+ }
+
+ /* if necessary, parse stream */
+ if ((pEASData->streams[streamNum].streamFlags & STREAM_FLAGS_PARSED) == 0)
+ if ((result = EAS_ParseEvents(pEASData, &pEASData->streams[streamNum], pEASData->streams[streamNum].time + pEASData->streams[streamNum].frameLength, eParserModePlay)) != EAS_SUCCESS)
+ return result;
+
+ /* check for an early abort */
+ if ((pEASData->streams[streamNum].streamFlags) == 0)
+ {
+
+#ifdef _METRICS_ENABLED
+ /* stop performance counter */
+ if (pEASData->pMetricsData)
+ (*pEASData->pMetricsModule->pfStartTimer)(pEASData->pMetricsData, EAS_PM_TOTAL_TIME);
+#endif
+
+ return EAS_SUCCESS;
+ }
+
+ /* check for repeat */
+ if (pEASData->streams[streamNum].repeatCount)
+ {
+
+ /* check for stopped state */
+ if ((result = (*pParserModule->pfState)(pEASData, pEASData->streams[streamNum].handle, &parserState)) != EAS_SUCCESS)
+ return result;
+ if (parserState == EAS_STATE_STOPPED)
+ {
+
+ /* decrement repeat count, unless it is negative */
+ if (pEASData->streams[streamNum].repeatCount > 0)
+ pEASData->streams[streamNum].repeatCount--;
+
+ /* reset the parser */
+ if ((result = (*pParserModule->pfReset)(pEASData, pEASData->streams[streamNum].handle)) != EAS_SUCCESS)
+ return result;
+ pEASData->streams[streamNum].time = 0;
+ }
+ }
+ }
+ }
+
+#ifdef _METRICS_ENABLED
+ /* stop performance counter */
+ if (pEASData->pMetricsData)
+ (void)(*pEASData->pMetricsModule->pfStopTimer)(pEASData->pMetricsData, EAS_PM_PARSE_TIME);
+#endif
+
+#ifdef _METRICS_ENABLED
+ /* start the render timer */
+ if (pEASData->pMetricsData)
+ (*pEASData->pMetricsModule->pfStartTimer)(pEASData->pMetricsData, EAS_PM_RENDER_TIME);
+#endif
+
+ /* render audio */
+ if ((result = VMRender(pEASData->pVoiceMgr, BUFFER_SIZE_IN_MONO_SAMPLES, pEASData->pMixBuffer, &voicesRendered)) != EAS_SUCCESS)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "pfRender function returned error %ld\n", result); */ }
+ return result;
+ }
+
+#ifdef _METRICS_ENABLED
+ /* stop the render timer */
+ if (pEASData->pMetricsData) {
+ (*pEASData->pMetricsModule->pfIncrementCounter)(pEASData->pMetricsData, EAS_PM_FRAME_COUNT, 1);
+ (void)(*pEASData->pMetricsModule->pfStopTimer)(pEASData->pMetricsData, EAS_PM_RENDER_TIME);
+ (*pEASData->pMetricsModule->pfIncrementCounter)(pEASData->pMetricsData, EAS_PM_TOTAL_VOICE_COUNT, (EAS_U32) voicesRendered);
+ (void)(*pEASData->pMetricsModule->pfRecordMaxValue)(pEASData->pMetricsData, EAS_PM_MAX_VOICES, (EAS_U32) voicesRendered);
+ }
+#endif
+
+ //2 Do we really need frameParsed?
+ /* need to parse another frame of events before we render again */
+ for (streamNum = 0; streamNum < MAX_NUMBER_STREAMS; streamNum++)
+ if (pEASData->streams[streamNum].pParserModule != NULL)
+ pEASData->streams[streamNum].streamFlags &= ~STREAM_FLAGS_PARSED;
+
+#ifdef _METRICS_ENABLED
+ /* start performance counter */
+ if (pEASData->pMetricsData)
+ (*pEASData->pMetricsModule->pfStartTimer)(pEASData->pMetricsData, EAS_PM_STREAM_TIME);
+#endif
+
+ /* render PCM audio */
+ if ((result = EAS_PERender(pEASData, numRequested)) != EAS_SUCCESS)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "EAS_PERender returned error %ld\n", result); */ }
+ return result;
+ }
+
+#ifdef _METRICS_ENABLED
+ /* stop the stream timer */
+ if (pEASData->pMetricsData)
+ (void)(*pEASData->pMetricsModule->pfStopTimer)(pEASData->pMetricsData, EAS_PM_STREAM_TIME);
+#endif
+
+#ifdef _METRICS_ENABLED
+ /* start the post timer */
+ if (pEASData->pMetricsData)
+ (*pEASData->pMetricsModule->pfStartTimer)(pEASData->pMetricsData, EAS_PM_POST_TIME);
+#endif
+
+ /* for split architecture, send DSP vectors. Do post only if return is TRUE */
+#ifdef _SPLIT_ARCHITECTURE
+ if (VMEndFrame(pEASData))
+ {
+ /* now do post-processing */
+ EAS_MixEnginePost(pEASData, numRequested);
+ *pNumGenerated = numRequested;
+ }
+#else
+ /* now do post-processing */
+ EAS_MixEnginePost(pEASData, numRequested);
+ *pNumGenerated = numRequested;
+#endif
+
+#ifdef _METRICS_ENABLED
+ /* stop the post timer */
+ if (pEASData->pMetricsData)
+ (void)(*pEASData->pMetricsModule->pfStopTimer)(pEASData->pMetricsData, EAS_PM_POST_TIME);
+#endif
+
+ /* advance render time */
+ pEASData->renderTime += AUDIO_FRAME_LENGTH;
+
+#if 0
+ /* dump workload for debug */
+ if (pEASData->pVoiceMgr->workload)
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Workload = %d\n", pEASData->pVoiceMgr->workload); */ }
+#endif
+
+#ifdef _METRICS_ENABLED
+ /* stop performance counter */
+ if (pEASData->pMetricsData)
+ {
+ PERF_TIMER temp;
+ temp = (*pEASData->pMetricsModule->pfStopTimer)(pEASData->pMetricsData, EAS_PM_TOTAL_TIME);
+
+ /* if max render time, record the number of voices and time */
+ if ((*pEASData->pMetricsModule->pfRecordMaxValue)
+ (pEASData->pMetricsData, EAS_PM_MAX_CYCLES, (EAS_U32) temp))
+ {
+ (*pEASData->pMetricsModule->pfRecordValue)(pEASData->pMetricsData, EAS_PM_MAX_CYCLES_VOICES, (EAS_U32) voicesRendered);
+ (*pEASData->pMetricsModule->pfRecordValue)(pEASData->pMetricsData, EAS_PM_MAX_CYCLES_TIME, (EAS_I32) (pEASData->renderTime >> 8));
+ }
+ }
+#endif
+
+#ifdef JET_INTERFACE
+ /* let JET to do its thing */
+ if (pEASData->jetHandle != NULL)
+ {
+ result = JET_Process(pEASData);
+ if (result != EAS_SUCCESS)
+ return result;
+ }
+#endif
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_SetRepeat()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Set the selected stream to repeat.
+ *
+ * Inputs:
+ * pEASData - handle to data for this instance
+ * handle - handle to stream
+ * repeatCount - repeat count
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ *
+ * Notes:
+ * 0 = no repeat
+ * 1 = repeat once, i.e. play through twice
+ * -1 = repeat forever
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pEASData) reserved for future use */
+EAS_PUBLIC EAS_RESULT EAS_SetRepeat (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_I32 repeatCount)
+{
+ pStream->repeatCount = repeatCount;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_GetRepeat()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Gets the current repeat count for the selected stream.
+ *
+ * Inputs:
+ * pEASData - handle to data for this instance
+ * handle - handle to stream
+ * pRrepeatCount - pointer to variable to hold repeat count
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ *
+ * Notes:
+ * 0 = no repeat
+ * 1 = repeat once, i.e. play through twice
+ * -1 = repeat forever
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pEASData) reserved for future use */
+EAS_PUBLIC EAS_RESULT EAS_GetRepeat (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_I32 *pRepeatCount)
+{
+ *pRepeatCount = pStream->repeatCount;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_SetPlaybackRate()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Sets the playback rate.
+ *
+ * Inputs:
+ * pEASData - handle to data for this instance
+ * handle - handle to stream
+ * rate - rate (28-bit fractional amount)
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pEASData) reserved for future use */
+EAS_PUBLIC EAS_RESULT EAS_SetPlaybackRate (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_U32 rate)
+{
+
+ /* check range */
+ if ((rate < (1 << 27)) || (rate > (1 << 29)))
+ return EAS_ERROR_INVALID_PARAMETER;
+
+ /* calculate new frame length
+ *
+ * NOTE: The maximum frame length we can accomodate based on a
+ * maximum rate of 2.0 (2^28) is 2047 (2^13-1). To accomodate a
+ * longer frame length or a higher maximum rate, the fixed point
+ * divide below will need to be adjusted
+ */
+ pStream->frameLength = (AUDIO_FRAME_LENGTH * (rate >> 8)) >> 20;
+
+ /* notify stream of new playback rate */
+ EAS_SetStreamParameter(pEASData, pStream, PARSER_DATA_PLAYBACK_RATE, (EAS_I32) rate);
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_SetTransposition)
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Sets the key tranposition for the synthesizer. Transposes all
+ * melodic instruments by the specified amount. Range is limited
+ * to +/-12 semitones.
+ *
+ * Inputs:
+ * pEASData - handle to data for this instance
+ * handle - handle to stream
+ * transposition - +/-12 semitones
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_SetTransposition (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_I32 transposition)
+{
+
+ /* check range */
+ if ((transposition < -12) || (transposition > 12))
+ return EAS_ERROR_INVALID_PARAMETER;
+
+ if (!EAS_StreamReady(pEASData, pStream))
+ return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
+ return EAS_IntSetStrmParam(pEASData, pStream, PARSER_DATA_TRANSPOSITION, transposition);
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_ParseEvents()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Parse events in the current streams until the desired time is reached.
+ *
+ * Inputs:
+ * pEASData - buffer for internal EAS data
+ * endTime - stop parsing if this time is reached
+ * parseMode - play, locate, or metadata
+ *
+ * Outputs:
+ * EAS_SUCCESS if PCM data was successfully rendered
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT EAS_ParseEvents (S_EAS_DATA *pEASData, EAS_HANDLE pStream, EAS_U32 endTime, EAS_INT parseMode)
+{
+ S_FILE_PARSER_INTERFACE *pParserModule;
+ EAS_RESULT result;
+ EAS_I32 parserState;
+ EAS_BOOL done;
+ EAS_INT yieldCount = YIELD_EVENT_COUNT;
+ EAS_U32 time = 0;
+
+ /* does this parser have a time function? */
+ pParserModule = pStream->pParserModule;
+ if (pParserModule->pfTime == NULL)
+ {
+ /* check state */
+ if ((result = (*pParserModule->pfState)(pEASData, pStream->handle, &parserState)) != EAS_SUCCESS)
+ return result;
+ /* if play state, advance time */
+ if ((parserState >= EAS_STATE_READY) && (parserState <= EAS_STATE_PAUSING))
+ pStream->time += pStream->frameLength;
+ done = EAS_TRUE;
+ }
+
+ /* assume we're not done, in case we abort out */
+ else
+ {
+ pStream->streamFlags &= ~STREAM_FLAGS_PARSED;
+ done = EAS_FALSE;
+ }
+
+ while (!done)
+ {
+
+ /* check for stopped state */
+ if ((result = (*pParserModule->pfState)(pEASData, pStream->handle, &parserState)) != EAS_SUCCESS)
+ return result;
+ if (parserState > EAS_STATE_PLAY)
+ {
+ /* save current time if we're not in play mode */
+ if (parseMode != eParserModePlay)
+ pStream->time = time << 8;
+ done = EAS_TRUE;
+ break;
+ }
+
+ /* get the next event time */
+ if (pParserModule->pfTime)
+ {
+ if ((result = (*pParserModule->pfTime)(pEASData, pStream->handle, &time)) != EAS_SUCCESS)
+ return result;
+
+ /* if next event is within this frame, parse it */
+ if (time < (endTime >> 8))
+ {
+
+ /* parse the next event */
+ if (pParserModule->pfEvent)
+ if ((result = (*pParserModule->pfEvent)(pEASData, pStream->handle, parseMode)) != EAS_SUCCESS)
+ return result;
+ }
+
+ /* no more events in this frame, advance time */
+ else
+ {
+ pStream->time = endTime;
+ done = EAS_TRUE;
+ }
+ }
+
+ /* check for max workload exceeded */
+ if (VMCheckWorkload(pEASData->pVoiceMgr))
+ {
+ /* stop even though we may not have parsed
+ * all the events in this frame. The parser will try to
+ * catch up on the next frame.
+ */
+ break;
+ }
+
+ /* give host a chance for an early abort */
+ if (--yieldCount == 0)
+ {
+ if (EAS_HWYield(pEASData->hwInstData))
+ break;
+ yieldCount = YIELD_EVENT_COUNT;
+ }
+ }
+
+ /* if no early abort, parsing is complete for this frame */
+ if (done)
+ pStream->streamFlags |= STREAM_FLAGS_PARSED;
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_ParseMetaData()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ *
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - file or stream handle
+ * playLength - pointer to variable to store the play length (in msecs)
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ * - resets the parser to the start of the file
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_ParseMetaData (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_I32 *playLength)
+{
+ S_FILE_PARSER_INTERFACE *pParserModule;
+ EAS_RESULT result;
+ EAS_STATE state;
+
+ pParserModule = (S_FILE_PARSER_INTERFACE*) pStream->pParserModule;
+ if (pParserModule == NULL)
+ return EAS_ERROR_FEATURE_NOT_AVAILABLE;
+
+ /* check parser state */
+ if ((result = (*pParserModule->pfState)(pEASData, pStream->handle, &state)) != EAS_SUCCESS)
+ return result;
+ if (state >= EAS_STATE_OPEN)
+ return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
+
+ /* if parser has metadata function, use that */
+ if (pParserModule->pfGetMetaData != NULL)
+ return pParserModule->pfGetMetaData(pEASData, pStream->handle, playLength);
+
+ /* reset the parser to the beginning */
+ if ((result = (*pParserModule->pfReset)(pEASData, pStream->handle)) != EAS_SUCCESS)
+ return result;
+
+ /* parse the file to end */
+ pStream->time = 0;
+ VMInitWorkload(pEASData->pVoiceMgr);
+ if ((result = EAS_ParseEvents(pEASData, pStream, 0x7fffffff, eParserModeMetaData)) != EAS_SUCCESS)
+ return result;
+
+ /* get the parser time */
+ if ((result = EAS_GetLocation(pEASData, pStream, playLength)) != EAS_SUCCESS)
+ return result;
+
+ /* reset the parser to the beginning */
+ pStream->time = 0;
+ return (*pParserModule->pfReset)(pEASData, pStream->handle);
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_RegisterMetaDataCallback()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Registers a metadata callback function for parsed metadata.
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - file or stream handle
+ * cbFunc - pointer to host callback function
+ * metaDataBuffer - pointer to metadata buffer
+ * metaDataBufSize - maximum size of the metadata buffer
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_RegisterMetaDataCallback (
+ EAS_DATA_HANDLE pEASData,
+ EAS_HANDLE pStream,
+ EAS_METADATA_CBFUNC cbFunc,
+ char *metaDataBuffer,
+ EAS_I32 metaDataBufSize,
+ EAS_VOID_PTR pUserData)
+{
+ S_METADATA_CB metadata;
+
+ if (!EAS_StreamReady(pEASData, pStream))
+ return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
+
+ /* register callback function */
+ metadata.callback = cbFunc;
+ metadata.buffer = metaDataBuffer;
+ metadata.bufferSize = metaDataBufSize;
+ metadata.pUserData = pUserData;
+ return EAS_SetStreamParameter(pEASData, pStream, PARSER_DATA_METADATA_CB, (EAS_I32) &metadata);
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_GetNoteCount ()
+ *----------------------------------------------------------------------------
+ * Returns the total number of notes played in this stream
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_GetNoteCount (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_I32 *pNoteCount)
+{
+ if (!EAS_StreamReady(pEASData, pStream))
+ return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
+ return EAS_IntGetStrmParam(pEASData, pStream, PARSER_DATA_NOTE_COUNT, pNoteCount);
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_CloseFile()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Closes an audio file or stream. Playback should have either paused or
+ * completed (EAS_State returns EAS_PAUSED or EAS_STOPPED).
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - file or stream handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_CloseFile (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream)
+{
+ S_FILE_PARSER_INTERFACE *pParserModule;
+ EAS_RESULT result;
+
+ /* call the close function */
+ pParserModule = (S_FILE_PARSER_INTERFACE*) pStream->pParserModule;
+ if (pParserModule == NULL)
+ return EAS_ERROR_FEATURE_NOT_AVAILABLE;
+
+ result = (*pParserModule->pfClose)(pEASData, pStream->handle);
+
+ /* clear the handle and parser interface pointer */
+ pStream->handle = NULL;
+ pStream->pParserModule = NULL;
+ return result;
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_OpenMIDIStream()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Opens a raw MIDI stream allowing the host to route MIDI cable data directly to the synthesizer
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * pHandle - pointer to variable to hold file or stream handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_OpenMIDIStream (EAS_DATA_HANDLE pEASData, EAS_HANDLE *ppStream, EAS_HANDLE streamHandle)
+{
+ EAS_RESULT result;
+ S_INTERACTIVE_MIDI *pMIDIStream;
+ EAS_INT streamNum;
+
+ /* initialize some pointers */
+ *ppStream = NULL;
+
+ /* allocate a stream */
+ if ((streamNum = EAS_AllocateStream(pEASData)) < 0)
+ return EAS_ERROR_MAX_STREAMS_OPEN;
+
+ /* check Configuration Module for S_EAS_DATA allocation */
+ if (pEASData->staticMemoryModel)
+ pMIDIStream = EAS_CMEnumData(EAS_CM_MIDI_STREAM_DATA);
+ else
+ pMIDIStream = EAS_HWMalloc(pEASData->hwInstData, sizeof(S_INTERACTIVE_MIDI));
+
+ /* allocate dynamic memory */
+ if (!pMIDIStream)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_FATAL, "Failed to allocate MIDI stream data\n"); */ }
+ return EAS_ERROR_MALLOC_FAILED;
+ }
+
+ /* zero the memory to insure complete initialization */
+ EAS_HWMemSet(pMIDIStream, 0, sizeof(S_INTERACTIVE_MIDI));
+ EAS_InitStream(&pEASData->streams[streamNum], NULL, pMIDIStream);
+
+ /* instantiate a new synthesizer */
+ if (streamHandle == NULL)
+ {
+ result = VMInitMIDI(pEASData, &pMIDIStream->pSynth);
+ }
+
+ /* use an existing synthesizer */
+ else
+ {
+ EAS_I32 value;
+ result = EAS_GetStreamParameter(pEASData, streamHandle, PARSER_DATA_SYNTH_HANDLE, &value);
+ pMIDIStream->pSynth = (S_SYNTH*) value;
+ VMIncRefCount(pMIDIStream->pSynth);
+ }
+ if (result != EAS_SUCCESS)
+ {
+ EAS_CloseMIDIStream(pEASData, &pEASData->streams[streamNum]);
+ return result;
+ }
+
+ /* initialize the MIDI stream data */
+ EAS_InitMIDIStream(&pMIDIStream->stream);
+
+ *ppStream = (EAS_HANDLE) &pEASData->streams[streamNum];
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_WriteMIDIStream()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Send data to the MIDI stream device
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - stream handle
+ * pBuffer - pointer to buffer
+ * count - number of bytes to write
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_WriteMIDIStream (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_U8 *pBuffer, EAS_I32 count)
+{
+ S_INTERACTIVE_MIDI *pMIDIStream;
+ EAS_RESULT result;
+
+ pMIDIStream = (S_INTERACTIVE_MIDI*) pStream->handle;
+
+ /* send the entire buffer */
+ while (count--)
+ {
+ if ((result = EAS_ParseMIDIStream(pEASData, pMIDIStream->pSynth, &pMIDIStream->stream, *pBuffer++, eParserModePlay)) != EAS_SUCCESS)
+ return result;
+ }
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_CloseMIDIStream()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Closes a raw MIDI stream
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - stream handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_CloseMIDIStream (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream)
+{
+ S_INTERACTIVE_MIDI *pMIDIStream;
+
+ pMIDIStream = (S_INTERACTIVE_MIDI*) pStream->handle;
+
+ /* close synth */
+ if (pMIDIStream->pSynth != NULL)
+ {
+ VMMIDIShutdown(pEASData, pMIDIStream->pSynth);
+ pMIDIStream->pSynth = NULL;
+ }
+
+ /* release allocated memory */
+ if (!pEASData->staticMemoryModel)
+ EAS_HWFree(((S_EAS_DATA*) pEASData)->hwInstData, pMIDIStream);
+
+ pStream->handle = NULL;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_State()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Returns the state of an audio file or stream.
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - file or stream handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_State (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_STATE *pState)
+{
+ S_FILE_PARSER_INTERFACE *pParserModule;
+ EAS_RESULT result;
+
+ /* call the parser to return state */
+ pParserModule = (S_FILE_PARSER_INTERFACE*) pStream->pParserModule;
+ if (pParserModule == NULL)
+ return EAS_ERROR_FEATURE_NOT_AVAILABLE;
+
+ if ((result = (*pParserModule->pfState)(pEASData, pStream->handle, pState)) != EAS_SUCCESS)
+ return result;
+
+ /* if repeat count is set for this parser, mask the stopped state from the application */
+ if (pStream->repeatCount && (*pState == EAS_STATE_STOPPED))
+ *pState = EAS_STATE_PLAY;
+
+ /* if we're not ready or playing, we don't need to hide state from host */
+ if (*pState > EAS_STATE_PLAY)
+ return EAS_SUCCESS;
+
+ /* if stream is about to be paused, report it as paused */
+ if (pStream->streamFlags & STREAM_FLAGS_PAUSE)
+ {
+ if (pStream->streamFlags & STREAM_FLAGS_LOCATE)
+ *pState = EAS_STATE_PAUSED;
+ else
+ *pState = EAS_STATE_PAUSING;
+ }
+
+ /* if stream is about to resume, report it as playing */
+ if (pStream->streamFlags & STREAM_FLAGS_RESUME)
+ *pState = EAS_STATE_PLAY;
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_SetPolyphony()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Set the polyphony of the stream. A value of 0 allows the stream
+ * to use all voices (set by EAS_SetSynthPolyphony).
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * streamHandle - handle returned by EAS_OpenFile
+ * polyphonyCount - the desired polyphony count
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_SetPolyphony (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_I32 polyphonyCount)
+{
+ if (!EAS_StreamReady(pEASData, pStream))
+ return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
+ return EAS_IntSetStrmParam(pEASData, pStream, PARSER_DATA_POLYPHONY, polyphonyCount);
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_GetPolyphony()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Returns the current polyphony setting of the stream
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * streamHandle - handle returned by EAS_OpenFile
+ * pPolyphonyCount - pointer to variable to receive polyphony count
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_GetPolyphony (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_I32 *pPolyphonyCount)
+{
+ if (!EAS_StreamReady(pEASData, pStream))
+ return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
+ return EAS_IntGetStrmParam(pEASData, pStream, PARSER_DATA_POLYPHONY, pPolyphonyCount);
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_SetSynthPolyphony()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Set the polyphony of the synth . Value must be >= 1 and <= the
+ * maximum number of voices. This function will pin the polyphony
+ * at those limits
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * synthNum - synthesizer number (0 = onboard, 1 = DSP)
+ * polyphonyCount - the desired polyphony count
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_SetSynthPolyphony (EAS_DATA_HANDLE pEASData, EAS_I32 synthNum, EAS_I32 polyphonyCount)
+{
+ return VMSetSynthPolyphony(pEASData->pVoiceMgr, synthNum, polyphonyCount);
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_GetSynthPolyphony()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Returns the current polyphony setting of the synth
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * synthNum - synthesizer number (0 = onboard, 1 = DSP)
+ * pPolyphonyCount - pointer to variable to receive polyphony count
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_GetSynthPolyphony (EAS_DATA_HANDLE pEASData, EAS_I32 synthNum, EAS_I32 *pPolyphonyCount)
+{
+ return VMGetSynthPolyphony(pEASData->pVoiceMgr, synthNum, pPolyphonyCount);
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_SetPriority()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Set the priority of the stream. Determines which stream's voices
+ * are stolen when there are insufficient voices for all notes.
+ * Value must be in the range of 1-15, lower values are higher
+ * priority.
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * streamHandle - handle returned by EAS_OpenFile
+ * polyphonyCount - the desired polyphony count
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_SetPriority (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_I32 priority)
+{
+ if (!EAS_StreamReady(pEASData, pStream))
+ return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
+ return EAS_IntSetStrmParam(pEASData, pStream, PARSER_DATA_PRIORITY, priority);
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_GetPriority()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Returns the current priority setting of the stream
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * streamHandle - handle returned by EAS_OpenFile
+ * pPriority - pointer to variable to receive priority
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_GetPriority (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_I32 *pPriority)
+{
+ if (!EAS_StreamReady(pEASData, pStream))
+ return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
+ return EAS_IntGetStrmParam(pEASData, pStream, PARSER_DATA_PRIORITY, pPriority);
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_SetVolume()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Set the master gain for the mix engine in 1dB increments
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * volume - the desired master gain (100 is max)
+ * handle - file or stream handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ * overrides any previously set master volume from sysex
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_SetVolume (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_I32 volume)
+{
+ EAS_I16 gain;
+
+ /* check range */
+ if ((volume < 0) || (volume > EAS_MAX_VOLUME))
+ return EAS_ERROR_PARAMETER_RANGE;
+
+ /* stream volume */
+ if (pStream != NULL)
+ {
+ EAS_I32 gainOffset;
+ EAS_RESULT result;
+
+ if (!EAS_StreamReady(pEASData, pStream))
+ return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
+
+ /* get gain offset */
+ pStream->volume = (EAS_U8) volume;
+ result = EAS_GetStreamParameter(pEASData, pStream, PARSER_DATA_GAIN_OFFSET, &gainOffset);
+ if (result == EAS_SUCCESS)
+ volume += gainOffset;
+
+ /* set stream volume */
+ gain = EAS_VolumeToGain(volume - STREAM_VOLUME_HEADROOM);
+
+ /* convert to linear scalar */
+ return EAS_IntSetStrmParam(pEASData, pStream, PARSER_DATA_VOLUME, gain);
+ }
+
+ /* master volume */
+ pEASData->masterVolume = (EAS_U8) volume;
+#if (NUM_OUTPUT_CHANNELS == 1)
+ /* leave 3dB headroom for mono output */
+ volume -= 3;
+#endif
+
+ gain = EAS_VolumeToGain(volume - STREAM_VOLUME_HEADROOM);
+ pEASData->masterGain = gain;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_GetVolume()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Returns the master volume for the synthesizer. The default volume setting is
+ * 50. The volume range is 0 to 100;
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * volume - the desired master volume
+ * handle - file or stream handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ * overrides any previously set master volume from sysex
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_I32 EAS_GetVolume (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream)
+{
+ if (pStream == NULL)
+ return pEASData->masterVolume;
+
+ if (!EAS_StreamReady(pEASData, pStream))
+ return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
+ return pStream->volume;
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_SetMaxLoad()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Sets the maximum workload the parsers will do in a single call to
+ * EAS_Render. The units are currently arbitrary, but should correlate
+ * well to the actual CPU cycles consumed. The primary effect is to
+ * reduce the occasional peaks in CPU cycles consumed when parsing
+ * dense parts of a MIDI score.
+ *
+ * Inputs:
+ * pEASData - handle to data for this instance
+ * maxLoad - the desired maximum workload
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_SetMaxLoad (EAS_DATA_HANDLE pEASData, EAS_I32 maxLoad)
+{
+ VMSetWorkload(pEASData->pVoiceMgr, maxLoad);
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_SetMaxPCMStreams()
+ *----------------------------------------------------------------------------
+ * Sets the maximum number of PCM streams allowed in parsers that
+ * use PCM streaming.
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * streamHandle - handle returned by EAS_OpenFile
+ * maxNumStreams - maximum number of PCM streams
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_SetMaxPCMStreams (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_I32 maxNumStreams)
+{
+ if (!EAS_StreamReady(pEASData, pStream))
+ return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
+ return EAS_IntSetStrmParam(pEASData, pStream, PARSER_DATA_MAX_PCM_STREAMS, maxNumStreams);
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_Locate()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Locate into the file associated with the handle.
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - file handle
+ * milliseconds - playback offset from start of file in milliseconds
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ * the actual offset will be quantized to the closest update period, typically
+ * a resolution of 5.9ms. Notes that are started prior to this time will not
+ * sound. Any notes currently playing will be shut off.
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_Locate (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_I32 milliseconds, EAS_BOOL offset)
+{
+ S_FILE_PARSER_INTERFACE *pParserModule;
+ EAS_RESULT result;
+ EAS_U32 requestedTime;
+ EAS_STATE state;
+
+ /* get pointer to parser function table */
+ pParserModule = (S_FILE_PARSER_INTERFACE*) pStream->pParserModule;
+ if (pParserModule == NULL)
+ return EAS_ERROR_FEATURE_NOT_AVAILABLE;
+
+ if ((result = (*pParserModule->pfState)(pEASData, pStream->handle, &state)) != EAS_SUCCESS)
+ return result;
+ if (state >= EAS_STATE_OPEN)
+ return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
+
+ /* handle offset and limit to start of file */
+ /*lint -e{704} use shift for performance*/
+ if (offset)
+ milliseconds += (EAS_I32) pStream->time >> 8;
+ if (milliseconds < 0)
+ milliseconds = 0;
+
+ /* check to see if the request is different from the current time */
+ requestedTime = (EAS_U32) milliseconds;
+ if (requestedTime == (pStream->time >> 8))
+ return EAS_SUCCESS;
+
+ /* set the locate flag */
+ pStream->streamFlags |= STREAM_FLAGS_LOCATE;
+
+ /* use the parser locate function, if available */
+ if (pParserModule->pfLocate != NULL)
+ {
+ EAS_BOOL parserLocate = EAS_FALSE;
+ result = pParserModule->pfLocate(pEASData, pStream->handle, (EAS_I32) requestedTime, &parserLocate);
+ if (!parserLocate)
+ {
+ if (result == EAS_SUCCESS)
+ pStream->time = requestedTime << 8;
+ return result;
+ }
+ }
+
+ /* if we were paused and not going to resume, set pause request flag */
+ if (((state == EAS_STATE_PAUSING) || (state == EAS_STATE_PAUSED)) && ((pStream->streamFlags & STREAM_FLAGS_RESUME) == 0))
+ pStream->streamFlags |= STREAM_FLAGS_PAUSE;
+
+ /* reset the synth and parser */
+ if ((result = (*pParserModule->pfReset)(pEASData, pStream->handle)) != EAS_SUCCESS)
+ return result;
+ pStream->time = 0;
+
+ /* locating forward, clear parsed flag and parse data until we get to the requested location */
+ if ((result = EAS_ParseEvents(pEASData, pStream, requestedTime << 8, eParserModeLocate)) != EAS_SUCCESS)
+ return result;
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_GetLocation()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Returns the current playback offset
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - file handle
+ *
+ * Outputs:
+ * The offset in milliseconds from the start of the current sequence, quantized
+ * to the nearest update period. Actual resolution is typically 5.9 ms.
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pEASData) reserved for future use */
+EAS_PUBLIC EAS_RESULT EAS_GetLocation (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_I32 *pTime)
+{
+ if (!EAS_StreamReady(pEASData, pStream))
+ return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
+
+ *pTime = pStream->time >> 8;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_GetRenderTime()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Returns the current playback offset
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ * Gets the render time clock in msecs.
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_GetRenderTime (EAS_DATA_HANDLE pEASData, EAS_I32 *pTime)
+{
+ *pTime = pEASData->renderTime >> 8;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_Pause()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Pauses the playback of the data associated with this handle. The audio
+ * is gracefully ramped down to prevent clicks and pops. It may take several
+ * buffers of audio before the audio is muted.
+ *
+ * Inputs:
+ * psEASData - pointer to overall EAS data structure
+ * handle - file or stream handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_Pause (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream)
+{
+ S_FILE_PARSER_INTERFACE *pParserModule;
+ EAS_STATE state;
+ EAS_RESULT result;
+
+ pParserModule = (S_FILE_PARSER_INTERFACE*) pStream->pParserModule;
+ if (pParserModule == NULL)
+ return EAS_ERROR_FEATURE_NOT_AVAILABLE;
+
+ /* check for valid state */
+ result = pParserModule->pfState(pEASData, pStream->handle, &state);
+ if (result == EAS_SUCCESS)
+ {
+ if ((state != EAS_STATE_PLAY) && (state != EAS_STATE_READY) && ((pStream->streamFlags & STREAM_FLAGS_RESUME) == 0))
+ return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
+
+ /* make sure parser implements pause */
+ if (pParserModule->pfPause == NULL)
+ result = EAS_ERROR_NOT_IMPLEMENTED;
+
+ /* clear resume flag */
+ pStream->streamFlags &= ~STREAM_FLAGS_RESUME;
+
+ /* set pause flag */
+ pStream->streamFlags |= STREAM_FLAGS_PAUSE;
+
+#if 0
+ /* pause the stream */
+ if (pParserModule->pfPause)
+ result = pParserModule->pfPause(pEASData, pStream->handle);
+ else
+ result = EAS_ERROR_NOT_IMPLEMENTED;
+#endif
+ }
+
+ return result;
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_Resume()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Resumes the playback of the data associated with this handle. The audio
+ * is gracefully ramped up to prevent clicks and pops.
+ *
+ * Inputs:
+ * psEASData - pointer to overall EAS data structure
+ * handle - file or stream handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_Resume (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream)
+{
+ S_FILE_PARSER_INTERFACE *pParserModule;
+ EAS_STATE state;
+ EAS_RESULT result;
+
+ pParserModule = (S_FILE_PARSER_INTERFACE*) pStream->pParserModule;
+ if (pParserModule == NULL)
+ return EAS_ERROR_FEATURE_NOT_AVAILABLE;
+
+ /* check for valid state */
+ result = pParserModule->pfState(pEASData, pStream->handle, &state);
+ if (result == EAS_SUCCESS)
+ {
+ if ((state != EAS_STATE_PAUSED) && (state != EAS_STATE_PAUSING) && ((pStream->streamFlags & STREAM_FLAGS_PAUSE) == 0))
+ return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
+
+ /* make sure parser implements this function */
+ if (pParserModule->pfResume == NULL)
+ result = EAS_ERROR_NOT_IMPLEMENTED;
+
+ /* clear pause flag */
+ pStream->streamFlags &= ~STREAM_FLAGS_PAUSE;
+
+ /* set resume flag */
+ pStream->streamFlags |= STREAM_FLAGS_RESUME;
+
+#if 0
+ /* resume the stream */
+ if (pParserModule->pfResume)
+ result = pParserModule->pfResume(pEASData, pStream->handle);
+ else
+ result = EAS_ERROR_NOT_IMPLEMENTED;
+#endif
+ }
+
+ return result;
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_GetParameter()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Set the parameter of a module. See E_MODULES for a list of modules
+ * and the header files of the modules for a list of parameters.
+ *
+ * Inputs:
+ * psEASData - pointer to overall EAS data structure
+ * handle - file or stream handle
+ * module - enumerated module number
+ * param - enumerated parameter number
+ * pValue - pointer to variable to receive parameter value
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_GetParameter (EAS_DATA_HANDLE pEASData, EAS_I32 module, EAS_I32 param, EAS_I32 *pValue)
+{
+
+ if (module >= NUM_EFFECTS_MODULES)
+ return EAS_ERROR_INVALID_MODULE;
+
+ if (pEASData->effectsModules[module].effectData == NULL)
+ return EAS_ERROR_INVALID_MODULE;
+
+ return (*pEASData->effectsModules[module].effect->pFGetParam)
+ (pEASData->effectsModules[module].effectData, param, pValue);
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_SetParameter()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Set the parameter of a module. See E_MODULES for a list of modules
+ * and the header files of the modules for a list of parameters.
+ *
+ * Inputs:
+ * psEASData - pointer to overall EAS data structure
+ * handle - file or stream handle
+ * module - enumerated module number
+ * param - enumerated parameter number
+ * value - new parameter value
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_SetParameter (EAS_DATA_HANDLE pEASData, EAS_I32 module, EAS_I32 param, EAS_I32 value)
+{
+
+ if (module >= NUM_EFFECTS_MODULES)
+ return EAS_ERROR_INVALID_MODULE;
+
+ if (pEASData->effectsModules[module].effectData == NULL)
+ return EAS_ERROR_INVALID_MODULE;
+
+ return (*pEASData->effectsModules[module].effect->pFSetParam)
+ (pEASData->effectsModules[module].effectData, param, value);
+}
+
+#ifdef _METRICS_ENABLED
+/*----------------------------------------------------------------------------
+ * EAS_MetricsReport()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Displays the current metrics through the metrics interface.
+ *
+ * Inputs:
+ * p - instance data handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_MetricsReport (EAS_DATA_HANDLE pEASData)
+{
+ if (!pEASData->pMetricsModule)
+ return EAS_ERROR_INVALID_MODULE;
+
+ return (*pEASData->pMetricsModule->pfReport)(pEASData->pMetricsData);
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_MetricsReset()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Resets the metrics.
+ *
+ * Inputs:
+ * p - instance data handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_MetricsReset (EAS_DATA_HANDLE pEASData)
+{
+
+ if (!pEASData->pMetricsModule)
+ return EAS_ERROR_INVALID_MODULE;
+
+ return (*pEASData->pMetricsModule->pfReset)(pEASData->pMetricsData);
+}
+#endif
+
+/*----------------------------------------------------------------------------
+ * EAS_SetSoundLibrary()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Sets the location of the sound library.
+ *
+ * Inputs:
+ * pEASData - instance data handle
+ * pSoundLib - pointer to sound library
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_SetSoundLibrary (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_SNDLIB_HANDLE pSndLib)
+{
+ if (pStream)
+ {
+ if (!EAS_StreamReady(pEASData, pStream))
+ return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
+ return EAS_IntSetStrmParam(pEASData, pStream, PARSER_DATA_EAS_LIBRARY, (EAS_I32) pSndLib);
+ }
+
+ return VMSetGlobalEASLib(pEASData->pVoiceMgr, pSndLib);
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_SetHeaderSearchFlag()
+ *----------------------------------------------------------------------------
+ * By default, when EAS_OpenFile is called, the parsers check the
+ * first few bytes of the file looking for a specific header. Some
+ * mobile devices may add a header to the start of a file, which
+ * will prevent the parser from recognizing the file. If the
+ * searchFlag is set to EAS_TRUE, the parser will search the entire
+ * file looking for the header. This may enable EAS to recognize
+ * some files that it would ordinarily reject. The negative is that
+ * it make take slightly longer to process the EAS_OpenFile request.
+ *
+ * Inputs:
+ * pEASData - instance data handle
+ * searchFlag - search flag (EAS_TRUE or EAS_FALSE)
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_SetHeaderSearchFlag (EAS_DATA_HANDLE pEASData, EAS_BOOL searchFlag)
+{
+ pEASData->searchHeaderFlag = (EAS_BOOL8) searchFlag;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_SetPlayMode()
+ *----------------------------------------------------------------------------
+ * Some file formats support special play modes, such as iMode partial
+ * play mode. This call can be used to change the play mode. The
+ * default play mode (usually straight playback) is always zero.
+ *
+ * Inputs:
+ * pEASData - instance data handle
+ * handle - file or stream handle
+ * playMode - play mode (see file parser for specifics)
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_SetPlayMode (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_I32 playMode)
+{
+ return EAS_IntSetStrmParam(pEASData, pStream, PARSER_DATA_PLAY_MODE, playMode);
+}
+
+#ifdef DLS_SYNTHESIZER
+/*----------------------------------------------------------------------------
+ * EAS_LoadDLSCollection()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Sets the location of the sound library.
+ *
+ * Inputs:
+ * pEASData - instance data handle
+ * pSoundLib - pointer to sound library
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_LoadDLSCollection (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_FILE_LOCATOR locator)
+{
+ EAS_FILE_HANDLE fileHandle;
+ EAS_RESULT result;
+ EAS_DLSLIB_HANDLE pDLS;
+
+ if (pStream != NULL)
+ {
+ if (!EAS_StreamReady(pEASData, pStream))
+ return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
+ }
+
+ /* open the file */
+ if ((result = EAS_HWOpenFile(pEASData->hwInstData, locator, &fileHandle, EAS_FILE_READ)) != EAS_SUCCESS)
+ return result;
+
+ /* parse the file */
+ result = DLSParser(pEASData->hwInstData, fileHandle, 0, &pDLS);
+ EAS_HWCloseFile(pEASData->hwInstData, fileHandle);
+
+ if (result == EAS_SUCCESS)
+ {
+
+ /* if a stream pStream is specified, point it to the DLS collection */
+ if (pStream)
+ result = EAS_IntSetStrmParam(pEASData, pStream, PARSER_DATA_DLS_COLLECTION, (EAS_I32) pDLS);
+
+ /* global DLS load */
+ else
+ result = VMSetGlobalDLSLib(pEASData, pDLS);
+ }
+
+ return result;
+}
+#endif
+
+#ifdef EXTERNAL_AUDIO
+/*----------------------------------------------------------------------------
+ * EAS_RegExtAudioCallback()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Registers callback functions for audio events.
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - file or stream handle
+ * cbProgChgFunc - pointer to host callback function for program change
+ * cbEventFunc - pointer to host callback functio for note events
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_RegExtAudioCallback (EAS_DATA_HANDLE pEASData,
+ EAS_HANDLE pStream,
+ EAS_VOID_PTR pInstData,
+ EAS_EXT_PRG_CHG_FUNC cbProgChgFunc,
+ EAS_EXT_EVENT_FUNC cbEventFunc)
+{
+ S_SYNTH *pSynth;
+
+ if (!EAS_StreamReady(pEASData, pStream))
+ return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
+
+ if (EAS_GetStreamParameter(pEASData, pStream, PARSER_DATA_SYNTH_HANDLE, (EAS_I32*) &pSynth) != EAS_SUCCESS)
+ return EAS_ERROR_INVALID_PARAMETER;
+
+ if (pSynth == NULL)
+ return EAS_ERROR_INVALID_PARAMETER;
+
+ VMRegExtAudioCallback(pSynth, pInstData, cbProgChgFunc, cbEventFunc);
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_GetMIDIControllers()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Returns the current state of MIDI controllers on the requested channel.
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - file or stream handle
+ * pControl - pointer to structure to receive data
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_GetMIDIControllers (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_U8 channel, S_MIDI_CONTROLLERS *pControl)
+{
+ S_SYNTH *pSynth;
+
+ if (!EAS_StreamReady(pEASData, pStream))
+ return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
+
+ if (EAS_GetStreamParameter(pEASData, pStream, PARSER_DATA_SYNTH_HANDLE, (EAS_I32*) &pSynth) != EAS_SUCCESS)
+ return EAS_ERROR_INVALID_PARAMETER;
+
+ if (pSynth == NULL)
+ return EAS_ERROR_INVALID_PARAMETER;
+
+ VMGetMIDIControllers(pSynth, channel, pControl);
+ return EAS_SUCCESS;
+}
+#endif
+
+#ifdef _SPLIT_ARCHITECTURE
+/*----------------------------------------------------------------------------
+ * EAS_SetFrameBuffer()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Sets the frame buffer pointer passed to the IPC communications functions
+ *
+ * Inputs:
+ * pEASData - instance data handle
+ * locator - file locator
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ * May overlay instruments in the GM sound set
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_SetFrameBuffer (EAS_DATA_HANDLE pEASData, EAS_FRAME_BUFFER_HANDLE pFrameBuffer)
+{
+ if (pEASData->pVoiceMgr)
+ pEASData->pVoiceMgr->pFrameBuffer = pFrameBuffer;
+ return EAS_SUCCESS;
+}
+#endif
+
+/*----------------------------------------------------------------------------
+ * EAS_SearchFile
+ *----------------------------------------------------------------------------
+ * Search file for specific sequence starting at current file
+ * position. Returns offset to start of sequence.
+ *
+ * Inputs:
+ * pEASData - pointer to EAS persistent data object
+ * fileHandle - file handle
+ * searchString - pointer to search sequence
+ * len - length of search sequence
+ * pOffset - pointer to variable to store offset to sequence
+ *
+ * Returns EAS_EOF if end-of-file is reached
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_SearchFile (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle, const EAS_U8 *searchString, EAS_I32 len, EAS_I32 *pOffset)
+{
+ EAS_RESULT result;
+ EAS_INT index;
+ EAS_U8 c;
+
+ *pOffset = -1;
+ index = 0;
+ for (;;)
+ {
+ result = EAS_HWGetByte(pEASData->hwInstData, fileHandle, &c);
+ if (result != EAS_SUCCESS)
+ return result;
+ if (c == searchString[index])
+ {
+ index++;
+ if (index == 4)
+ {
+ result = EAS_HWFilePos(pEASData->hwInstData, fileHandle, pOffset);
+ if (result != EAS_SUCCESS)
+ return result;
+ *pOffset -= len;
+ break;
+ }
+ }
+ else
+ index = 0;
+ }
+ return EAS_SUCCESS;
+}
+
+
diff --git a/arm-hybrid-22k/lib_src/eas_reverb.c b/arm-hybrid-22k/lib_src/eas_reverb.c
index 6d99862..cd5befe 100644
--- a/arm-hybrid-22k/lib_src/eas_reverb.c
+++ b/arm-hybrid-22k/lib_src/eas_reverb.c
@@ -1,13 +1,13 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_reverb.c
- *
- * Contents and purpose:
- * Contains the implementation of the Reverb effect.
- *
- *
- * Copyright Sonic Network Inc. 2006
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_reverb.c
+ *
+ * Contents and purpose:
+ * Contains the implementation of the Reverb effect.
+ *
+ *
+ * Copyright Sonic Network Inc. 2006
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,1135 +20,1135 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 510 $
- * $Date: 2006-12-19 01:47:33 -0800 (Tue, 19 Dec 2006) $
- *----------------------------------------------------------------------------
-*/
-
-/*------------------------------------
- * includes
- *------------------------------------
-*/
-
-#include "eas_data.h"
-#include "eas_effects.h"
-#include "eas_math.h"
-#include "eas_reverbdata.h"
-#include "eas_reverb.h"
-#include "eas_config.h"
-#include "eas_host.h"
-#include "eas_report.h"
-
-/* prototypes for effects interface */
-static EAS_RESULT ReverbInit (EAS_DATA_HANDLE pEASData, EAS_VOID_PTR *pInstData);
-static void ReverbProcess (EAS_VOID_PTR pInstData, EAS_PCM *pSrc, EAS_PCM *pDst, EAS_I32 numSamples);
-static EAS_RESULT ReverbShutdown (EAS_DATA_HANDLE pEASData, EAS_VOID_PTR pInstData);
-static EAS_RESULT ReverbGetParam (EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue);
-static EAS_RESULT ReverbSetParam (EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value);
-
-/* common effects interface for configuration module */
-const S_EFFECTS_INTERFACE EAS_Reverb =
-{
- ReverbInit,
- ReverbProcess,
- ReverbShutdown,
- ReverbGetParam,
- ReverbSetParam
-};
-
-
-
-/*----------------------------------------------------------------------------
- * InitializeReverb()
- *----------------------------------------------------------------------------
- * Purpose:
- *
- * Inputs:
- *
- * Outputs:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT ReverbInit(EAS_DATA_HANDLE pEASData, EAS_VOID_PTR *pInstData)
-{
- EAS_I32 i;
- EAS_U16 nOffset;
- EAS_INT temp;
-
- S_REVERB_OBJECT *pReverbData;
- S_REVERB_PRESET *pPreset;
-
- /* check Configuration Module for data allocation */
- if (pEASData->staticMemoryModel)
- pReverbData = EAS_CMEnumFXData(EAS_MODULE_REVERB);
-
- /* allocate dynamic memory */
- else
- pReverbData = EAS_HWMalloc(pEASData->hwInstData, sizeof(S_REVERB_OBJECT));
-
- if (pReverbData == NULL)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_FATAL, "Failed to allocate Reverb memory\n"); */ }
- return EAS_ERROR_MALLOC_FAILED;
- }
-
- /* clear the structure */
- EAS_HWMemSet(pReverbData, 0, sizeof(S_REVERB_OBJECT));
-
- ReverbReadInPresets(pReverbData);
-
- pReverbData->m_nMinSamplesToAdd = REVERB_UPDATE_PERIOD_IN_SAMPLES;
-
- pReverbData->m_nRevOutFbkR = 0;
- pReverbData->m_nRevOutFbkL = 0;
-
- pReverbData->m_sAp0.m_zApIn = AP0_IN;
- pReverbData->m_sAp0.m_zApOut = AP0_IN + DEFAULT_AP0_LENGTH;
- pReverbData->m_sAp0.m_nApGain = DEFAULT_AP0_GAIN;
-
- pReverbData->m_zD0In = DELAY0_IN;
-
- pReverbData->m_sAp1.m_zApIn = AP1_IN;
- pReverbData->m_sAp1.m_zApOut = AP1_IN + DEFAULT_AP1_LENGTH;
- pReverbData->m_sAp1.m_nApGain = DEFAULT_AP1_GAIN;
-
- pReverbData->m_zD1In = DELAY1_IN;
-
- pReverbData->m_zLpf0 = 0;
- pReverbData->m_zLpf1 = 0;
- pReverbData->m_nLpfFwd = 8837;
- pReverbData->m_nLpfFbk = 6494;
-
- pReverbData->m_nSin = 0;
- pReverbData->m_nCos = 0;
- pReverbData->m_nSinIncrement = 0;
- pReverbData->m_nCosIncrement = 0;
-
- // set xfade parameters
- pReverbData->m_nXfadeInterval = (EAS_U16)REVERB_XFADE_PERIOD_IN_SAMPLES;
- pReverbData->m_nXfadeCounter = pReverbData->m_nXfadeInterval + 1; // force update on first iteration
- pReverbData->m_nPhase = -32768;
- pReverbData->m_nPhaseIncrement = REVERB_XFADE_PHASE_INCREMENT;
-
- pReverbData->m_nNoise = (EAS_I16)0xABCD;
-
- pReverbData->m_nMaxExcursion = 0x007F;
-
- // set delay tap lengths
- nOffset = ReverbCalculateNoise( pReverbData->m_nMaxExcursion,
- &pReverbData->m_nNoise );
-
- pReverbData->m_zD1Cross =
- DELAY1_OUT - pReverbData->m_nMaxExcursion + nOffset;
-
- nOffset = ReverbCalculateNoise( pReverbData->m_nMaxExcursion,
- &pReverbData->m_nNoise );
-
- pReverbData->m_zD0Cross =
- DELAY1_OUT - pReverbData->m_nMaxExcursion - nOffset;
-
- nOffset = ReverbCalculateNoise( pReverbData->m_nMaxExcursion,
- &pReverbData->m_nNoise );
-
- pReverbData->m_zD0Self =
- DELAY0_OUT - pReverbData->m_nMaxExcursion - nOffset;
-
- nOffset = ReverbCalculateNoise( pReverbData->m_nMaxExcursion,
- &pReverbData->m_nNoise );
-
- pReverbData->m_zD1Self =
- DELAY1_OUT - pReverbData->m_nMaxExcursion + nOffset;
-
- // for debugging purposes, allow noise generator
- pReverbData->m_bUseNoise = EAS_FALSE;
-
- // for debugging purposes, allow bypass
- pReverbData->m_bBypass = EAS_TRUE; //EAS_FALSE;
-
- pReverbData->m_nNextRoom = 1;
-
- pReverbData->m_nCurrentRoom = pReverbData->m_nNextRoom + 1; // force update on first iteration
-
- pReverbData->m_nWet = REVERB_DEFAULT_WET;
-
- pReverbData->m_nDry = REVERB_DEFAULT_DRY;
-
- // set base index into circular buffer
- pReverbData->m_nBaseIndex = 0;
-
- // set the early reflections, L
- pReverbData->m_sEarlyL.m_nLpfFbk = 4915;
- pReverbData->m_sEarlyL.m_nLpfFwd = 27852;
- pReverbData->m_sEarlyL.m_zLpf = 0;
-
- for (i=0; i < REVERB_MAX_NUM_REFLECTIONS; i++)
- {
- pReverbData->m_sEarlyL.m_nGain[i] = 0;
- pReverbData->m_sEarlyL.m_zDelay[i] = 0;
- }
-
- // set the early reflections, R
- pReverbData->m_sEarlyR.m_nLpfFbk = 4915;
- pReverbData->m_sEarlyR.m_nLpfFwd = 27852;
- pReverbData->m_sEarlyR.m_zLpf = 0;
-
- for (i=0; i < REVERB_MAX_NUM_REFLECTIONS; i++)
- {
- pReverbData->m_sEarlyR.m_nGain[i] = 0;
- pReverbData->m_sEarlyR.m_zDelay[i] = 0;
- }
-
- // clear the reverb delay line
- for (i=0; i < REVERB_BUFFER_SIZE_IN_SAMPLES; i++)
- {
- pReverbData->m_nDelayLine[i] = 0;
- }
-
- ////////////////////////////////
- ///code from the EAS DEMO Reverb
- //now copy from the new preset into the reverb
- pPreset = &pReverbData->m_sPreset.m_sPreset[pReverbData->m_nNextRoom];
-
- pReverbData->m_nLpfFbk = pPreset->m_nLpfFbk;
- pReverbData->m_nLpfFwd = pPreset->m_nLpfFwd;
-
- pReverbData->m_nEarly = pPreset->m_nEarly;
- pReverbData->m_nWet = pPreset->m_nWet;
- pReverbData->m_nDry = pPreset->m_nDry;
-
- pReverbData->m_nMaxExcursion = pPreset->m_nMaxExcursion;
- //stored as time based, convert to sample based
- temp = pPreset->m_nXfadeInterval;
- /*lint -e{702} shift for performance */
- temp = (temp * _OUTPUT_SAMPLE_RATE) >> 16;
- pReverbData->m_nXfadeInterval = (EAS_U16) temp;
- //gsReverbObject.m_nXfadeInterval = pPreset->m_nXfadeInterval;
-
- pReverbData->m_sAp0.m_nApGain = pPreset->m_nAp0_ApGain;
- //stored as time based, convert to absolute sample value
- temp = pPreset->m_nAp0_ApOut;
- /*lint -e{702} shift for performance */
- temp = (temp * _OUTPUT_SAMPLE_RATE) >> 16;
- pReverbData->m_sAp0.m_zApOut = (EAS_U16) (pReverbData->m_sAp0.m_zApIn + temp);
- //gsReverbObject.m_sAp0.m_zApOut = pPreset->m_nAp0_ApOut;
-
- pReverbData->m_sAp1.m_nApGain = pPreset->m_nAp1_ApGain;
- //stored as time based, convert to absolute sample value
- temp = pPreset->m_nAp1_ApOut;
- /*lint -e{702} shift for performance */
- temp = (temp * _OUTPUT_SAMPLE_RATE) >> 16;
- pReverbData->m_sAp1.m_zApOut = (EAS_U16) (pReverbData->m_sAp1.m_zApIn + temp);
- //gsReverbObject.m_sAp1.m_zApOut = pPreset->m_nAp1_ApOut;
- ///code from the EAS DEMO Reverb
- ////////////////////////////////
-
- *pInstData = pReverbData;
-
- return EAS_SUCCESS;
-
-} /* end InitializeReverb */
-
-
-
-/*----------------------------------------------------------------------------
- * ReverbProcess()
- *----------------------------------------------------------------------------
- * Purpose:
- * Reverberate the requested number of samples (block based processing)
- *
- * Inputs:
- * pInputBuffer - src buffer
- * pOutputBuffer - dst buffer
- * nNumSamplesToAdd - number of samples to write to buffer
- *
- * Outputs:
- * number of samples actually written to buffer
- *
- * Side Effects:
- * - samples are added to the presently free buffer
- *
- *----------------------------------------------------------------------------
-*/
-static void ReverbProcess(EAS_VOID_PTR pInstData, EAS_PCM *pSrc, EAS_PCM *pDst, EAS_I32 numSamples)
-{
- S_REVERB_OBJECT *pReverbData;
-
- pReverbData = (S_REVERB_OBJECT*) pInstData;
-
- //if bypassed or the preset forces the signal to be completely dry
- if (pReverbData->m_bBypass ||
- (pReverbData->m_nWet == 0 && pReverbData->m_nDry == 32767))
- {
- if (pSrc != pDst)
- EAS_HWMemCpy(pSrc, pDst, numSamples * NUM_OUTPUT_CHANNELS * (EAS_I32) sizeof(EAS_PCM));
- return;
- }
-
- if (pReverbData->m_nNextRoom != pReverbData->m_nCurrentRoom)
- {
- ReverbUpdateRoom(pReverbData);
- }
-
- ReverbUpdateXfade(pReverbData, numSamples);
-
- Reverb(pReverbData, numSamples, pDst, pSrc);
-
- /* check if update counter needs to be reset */
- if (pReverbData->m_nUpdateCounter >= REVERB_MODULO_UPDATE_PERIOD_IN_SAMPLES)
- {
- /* update interval has elapsed, so reset counter */
- pReverbData->m_nUpdateCounter = 0;
- } /* end if m_nUpdateCounter >= update interval */
-
- /* increment update counter */
- pReverbData->m_nUpdateCounter += (EAS_I16)numSamples;
-
-} /* end ComputeReverb */
-
-/*----------------------------------------------------------------------------
- * ReverbUpdateXfade
- *----------------------------------------------------------------------------
- * Purpose:
- * Update the xfade parameters as required
- *
- * Inputs:
- * nNumSamplesToAdd - number of samples to write to buffer
- *
- * Outputs:
- *
- *
- * Side Effects:
- * - xfade parameters will be changed
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT ReverbUpdateXfade(S_REVERB_OBJECT *pReverbData, EAS_INT nNumSamplesToAdd)
-{
- EAS_U16 nOffset;
- EAS_I16 tempCos;
- EAS_I16 tempSin;
-
- if (pReverbData->m_nXfadeCounter >= pReverbData->m_nXfadeInterval)
- {
- /* update interval has elapsed, so reset counter */
- pReverbData->m_nXfadeCounter = 0;
-
- // Pin the sin,cos values to min / max values to ensure that the
- // modulated taps' coefs are zero (thus no clicks)
- if (pReverbData->m_nPhaseIncrement > 0)
- {
- // if phase increment > 0, then sin -> 1, cos -> 0
- pReverbData->m_nSin = 32767;
- pReverbData->m_nCos = 0;
-
- // reset the phase to match the sin, cos values
- pReverbData->m_nPhase = 32767;
-
- // modulate the cross taps because their tap coefs are zero
- nOffset = ReverbCalculateNoise( pReverbData->m_nMaxExcursion, &pReverbData->m_nNoise );
-
- pReverbData->m_zD1Cross =
- DELAY1_OUT - pReverbData->m_nMaxExcursion + nOffset;
-
- nOffset = ReverbCalculateNoise( pReverbData->m_nMaxExcursion, &pReverbData->m_nNoise );
-
- pReverbData->m_zD0Cross =
- DELAY0_OUT - pReverbData->m_nMaxExcursion - nOffset;
- }
- else
- {
- // if phase increment < 0, then sin -> 0, cos -> 1
- pReverbData->m_nSin = 0;
- pReverbData->m_nCos = 32767;
-
- // reset the phase to match the sin, cos values
- pReverbData->m_nPhase = -32768;
-
- // modulate the self taps because their tap coefs are zero
- nOffset = ReverbCalculateNoise( pReverbData->m_nMaxExcursion, &pReverbData->m_nNoise );
-
- pReverbData->m_zD0Self =
- DELAY0_OUT - pReverbData->m_nMaxExcursion - nOffset;
-
- nOffset = ReverbCalculateNoise( pReverbData->m_nMaxExcursion, &pReverbData->m_nNoise );
-
- pReverbData->m_zD1Self =
- DELAY1_OUT - pReverbData->m_nMaxExcursion + nOffset;
-
- } // end if-else (pReverbData->m_nPhaseIncrement > 0)
-
- // Reverse the direction of the sin,cos so that the
- // tap whose coef was previously increasing now decreases
- // and vice versa
- pReverbData->m_nPhaseIncrement = -pReverbData->m_nPhaseIncrement;
-
- } // end if counter >= update interval
-
- //compute what phase will be next time
- pReverbData->m_nPhase += pReverbData->m_nPhaseIncrement;
-
- //calculate what the new sin and cos need to reach by the next update
- ReverbCalculateSinCos(pReverbData->m_nPhase, &tempSin, &tempCos);
-
- //calculate the per-sample increment required to get there by the next update
- /*lint -e{702} shift for performance */
- pReverbData->m_nSinIncrement =
- (tempSin - pReverbData->m_nSin) >> REVERB_UPDATE_PERIOD_IN_BITS;
-
- /*lint -e{702} shift for performance */
- pReverbData->m_nCosIncrement =
- (tempCos - pReverbData->m_nCos) >> REVERB_UPDATE_PERIOD_IN_BITS;
-
-
- /* increment update counter */
- pReverbData->m_nXfadeCounter += (EAS_U16) nNumSamplesToAdd;
-
- return EAS_SUCCESS;
-
-} /* end ReverbUpdateXfade */
-
-
-/*----------------------------------------------------------------------------
- * ReverbCalculateNoise
- *----------------------------------------------------------------------------
- * Purpose:
- * Calculate a noise sample and limit its value
- *
- * Inputs:
- * nMaxExcursion - noise value is limited to this value
- * pnNoise - return new noise sample in this (not limited)
- *
- * Outputs:
- * new limited noise value
- *
- * Side Effects:
- * - *pnNoise noise value is updated
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_U16 ReverbCalculateNoise(EAS_U16 nMaxExcursion, EAS_I16 *pnNoise)
-{
- // calculate new noise value
- *pnNoise = (EAS_I16) (*pnNoise * 5 + 1);
-
-#if 0 // 1xxx, test
- *pnNoise = 0;
-#endif // 1xxx, test
-
- // return the limited noise value
- return (nMaxExcursion & (*pnNoise));
-
-} /* end ReverbCalculateNoise */
-
-/*----------------------------------------------------------------------------
- * ReverbCalculateSinCos
- *----------------------------------------------------------------------------
- * Purpose:
- * Calculate a new sin and cosine value based on the given phase
- *
- * Inputs:
- * nPhase - phase angle
- * pnSin - input old value, output new value
- * pnCos - input old value, output new value
- *
- * Outputs:
- *
- * Side Effects:
- * - *pnSin, *pnCos are updated
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT ReverbCalculateSinCos(EAS_I16 nPhase, EAS_I16 *pnSin, EAS_I16 *pnCos)
-{
- EAS_I32 nTemp;
- EAS_I32 nNetAngle;
-
- // -1 <= nPhase < 1
- // However, for the calculation, we need a value
- // that ranges from -1/2 to +1/2, so divide the phase by 2
- /*lint -e{702} shift for performance */
- nNetAngle = nPhase >> 1;
-
- /*
- Implement the following
- sin(x) = (2-4*c)*x^2 + c + x
- cos(x) = (2-4*c)*x^2 + c - x
-
- where c = 1/sqrt(2)
- using the a0 + x*(a1 + x*a2) approach
- */
-
- /* limit the input "angle" to be between -0.5 and +0.5 */
- if (nNetAngle > EG1_HALF)
- {
- nNetAngle = EG1_HALF;
- }
- else if (nNetAngle < EG1_MINUS_HALF)
- {
- nNetAngle = EG1_MINUS_HALF;
- }
-
- /* calculate sin */
- nTemp = EG1_ONE + MULT_EG1_EG1(REVERB_PAN_G2, nNetAngle);
- nTemp = REVERB_PAN_G0 + MULT_EG1_EG1(nTemp, nNetAngle);
- *pnSin = (EAS_I16) SATURATE_EG1(nTemp);
-
- /* calculate cos */
- nTemp = -EG1_ONE + MULT_EG1_EG1(REVERB_PAN_G2, nNetAngle);
- nTemp = REVERB_PAN_G0 + MULT_EG1_EG1(nTemp, nNetAngle);
- *pnCos = (EAS_I16) SATURATE_EG1(nTemp);
-
- return EAS_SUCCESS;
-} /* end ReverbCalculateSinCos */
-
-/*----------------------------------------------------------------------------
- * Reverb
- *----------------------------------------------------------------------------
- * Purpose:
- * apply reverb to the given signal
- *
- * Inputs:
- * nNu
- * pnSin - input old value, output new value
- * pnCos - input old value, output new value
- *
- * Outputs:
- * number of samples actually reverberated
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT Reverb(S_REVERB_OBJECT *pReverbData, EAS_INT nNumSamplesToAdd, EAS_PCM *pOutputBuffer, EAS_PCM *pInputBuffer)
-{
- EAS_I32 i;
- EAS_I32 nDelayOut;
- EAS_U16 nBase;
-
- EAS_U32 nAddr;
- EAS_I32 nTemp1;
- EAS_I32 nTemp2;
- EAS_I32 nApIn;
- EAS_I32 nApOut;
-
- EAS_I32 j;
- EAS_I32 nEarlyOut;
-
- EAS_I32 tempValue;
-
-
- // get the base address
- nBase = pReverbData->m_nBaseIndex;
-
- for (i=0; i < nNumSamplesToAdd; i++)
- {
- // ********** Left Allpass - start
- // left input = (left dry/4) + right feedback from previous period
- /*lint -e{702} use shift for performance */
- nApIn = ((*pInputBuffer++)>>2) + pReverbData->m_nRevOutFbkR;
-// nApIn = *pInputBuffer++; // 1xxx test and debug ap
-
- // fetch allpass delay line out
- //nAddr = CIRCULAR(nBase, psAp0->m_zApOut, REVERB_BUFFER_MASK);
- nAddr = CIRCULAR(nBase, pReverbData->m_sAp0.m_zApOut, REVERB_BUFFER_MASK);
- nDelayOut = pReverbData->m_nDelayLine[nAddr];
-
- // calculate allpass feedforward; subtract the feedforward result
- nTemp1 = MULT_EG1_EG1(nApIn, pReverbData->m_sAp0.m_nApGain);
- nApOut = SATURATE(nDelayOut - nTemp1); // allpass output
-
- // calculate allpass feedback; add the feedback result
- nTemp1 = MULT_EG1_EG1(nApOut, pReverbData->m_sAp0.m_nApGain);
- nTemp1 = SATURATE(nApIn + nTemp1);
-
- // inject into allpass delay
- nAddr = CIRCULAR(nBase, pReverbData->m_sAp0.m_zApIn, REVERB_BUFFER_MASK);
- pReverbData->m_nDelayLine[nAddr] = (EAS_PCM) nTemp1;
-
- // inject allpass output into delay line
- nAddr = CIRCULAR(nBase, pReverbData->m_zD0In, REVERB_BUFFER_MASK);
- pReverbData->m_nDelayLine[nAddr] = (EAS_PCM) nApOut;
-
- // ********** Left Allpass - end
-
- // ********** Right Allpass - start
- // right input = (right dry/4) + left feedback from previous period
- /*lint -e{702} use shift for performance */
- nApIn = ((*pInputBuffer++)>>2) + pReverbData->m_nRevOutFbkL;
-// nApIn = *pInputBuffer++; // 1xxx test and debug ap
-
- // fetch allpass delay line out
- nAddr = CIRCULAR(nBase, pReverbData->m_sAp1.m_zApOut, REVERB_BUFFER_MASK);
- nDelayOut = pReverbData->m_nDelayLine[nAddr];
-
- // calculate allpass feedforward; subtract the feedforward result
- nTemp1 = MULT_EG1_EG1(nApIn, pReverbData->m_sAp1.m_nApGain);
- nApOut = SATURATE(nDelayOut - nTemp1); // allpass output
-
- // calculate allpass feedback; add the feedback result
- nTemp1 = MULT_EG1_EG1(nApOut, pReverbData->m_sAp1.m_nApGain);
- nTemp1 = SATURATE(nApIn + nTemp1);
-
- // inject into allpass delay
- nAddr = CIRCULAR(nBase, pReverbData->m_sAp1.m_zApIn, REVERB_BUFFER_MASK);
- pReverbData->m_nDelayLine[nAddr] = (EAS_PCM) nTemp1;
-
- // inject allpass output into delay line
- nAddr = CIRCULAR(nBase, pReverbData->m_zD1In, REVERB_BUFFER_MASK);
- pReverbData->m_nDelayLine[nAddr] = (EAS_PCM) nApOut;
-
- // ********** Right Allpass - end
-
- // ********** D0 output - start
- // fetch delay line self out
- nAddr = CIRCULAR(nBase, pReverbData->m_zD0Self, REVERB_BUFFER_MASK);
- nDelayOut = pReverbData->m_nDelayLine[nAddr];
-
- // calculate delay line self out
- nTemp1 = MULT_EG1_EG1(nDelayOut, pReverbData->m_nSin);
-
- // fetch delay line cross out
- nAddr = CIRCULAR(nBase, pReverbData->m_zD1Cross, REVERB_BUFFER_MASK);
- nDelayOut = pReverbData->m_nDelayLine[nAddr];
-
- // calculate delay line self out
- nTemp2 = MULT_EG1_EG1(nDelayOut, pReverbData->m_nCos);
-
- // calculate unfiltered delay out
- nDelayOut = SATURATE(nTemp1 + nTemp2);
-
- // calculate lowpass filter (mixer scale factor included in LPF feedforward)
- nTemp1 = MULT_EG1_EG1(nDelayOut, pReverbData->m_nLpfFwd);
-
- nTemp2 = MULT_EG1_EG1(pReverbData->m_zLpf0, pReverbData->m_nLpfFbk);
-
- // calculate filtered delay out and simultaneously update LPF state variable
- // filtered delay output is stored in m_zLpf0
- pReverbData->m_zLpf0 = (EAS_PCM) SATURATE(nTemp1 + nTemp2);
-
- // ********** D0 output - end
-
- // ********** D1 output - start
- // fetch delay line self out
- nAddr = CIRCULAR(nBase, pReverbData->m_zD1Self, REVERB_BUFFER_MASK);
- nDelayOut = pReverbData->m_nDelayLine[nAddr];
-
- // calculate delay line self out
- nTemp1 = MULT_EG1_EG1(nDelayOut, pReverbData->m_nSin);
-
- // fetch delay line cross out
- nAddr = CIRCULAR(nBase, pReverbData->m_zD0Cross, REVERB_BUFFER_MASK);
- nDelayOut = pReverbData->m_nDelayLine[nAddr];
-
- // calculate delay line self out
- nTemp2 = MULT_EG1_EG1(nDelayOut, pReverbData->m_nCos);
-
- // calculate unfiltered delay out
- nDelayOut = SATURATE(nTemp1 + nTemp2);
-
- // calculate lowpass filter (mixer scale factor included in LPF feedforward)
- nTemp1 = MULT_EG1_EG1(nDelayOut, pReverbData->m_nLpfFwd);
-
- nTemp2 = MULT_EG1_EG1(pReverbData->m_zLpf1, pReverbData->m_nLpfFbk);
-
- // calculate filtered delay out and simultaneously update LPF state variable
- // filtered delay output is stored in m_zLpf1
- pReverbData->m_zLpf1 = (EAS_PCM)SATURATE(nTemp1 + nTemp2);
-
- // ********** D1 output - end
-
- // ********** mixer and feedback - start
- // sum is fedback to right input (R + L)
- pReverbData->m_nRevOutFbkL =
- (EAS_PCM)SATURATE((EAS_I32)pReverbData->m_zLpf1 + (EAS_I32)pReverbData->m_zLpf0);
-
- // difference is feedback to left input (R - L)
- /*lint -e{685} lint complains that it can't saturate negative */
- pReverbData->m_nRevOutFbkR =
- (EAS_PCM)SATURATE((EAS_I32)pReverbData->m_zLpf1 - (EAS_I32)pReverbData->m_zLpf0);
-
- // ********** mixer and feedback - end
-
- // ********** start early reflection generator, left
- //psEarly = &(pReverbData->m_sEarlyL);
-
- nEarlyOut = 0;
-
- for (j=0; j < REVERB_MAX_NUM_REFLECTIONS; j++)
- {
- // fetch delay line out
- //nAddr = CIRCULAR(nBase, psEarly->m_zDelay[j], REVERB_BUFFER_MASK);
- nAddr = CIRCULAR(nBase, pReverbData->m_sEarlyL.m_zDelay[j], REVERB_BUFFER_MASK);
-
- nDelayOut = pReverbData->m_nDelayLine[nAddr];
-
- // calculate reflection
- //nTemp1 = MULT_EG1_EG1(nDelayOut, psEarly->m_nGain[j]);
- nTemp1 = MULT_EG1_EG1(nDelayOut, pReverbData->m_sEarlyL.m_nGain[j]);
-
- nEarlyOut = SATURATE(nEarlyOut + nTemp1);
-
- } // end for (j=0; j < REVERB_MAX_NUM_REFLECTIONS; j++)
-
- // apply lowpass to early reflections
- //nTemp1 = MULT_EG1_EG1(nEarlyOut, psEarly->m_nLpfFwd);
- nTemp1 = MULT_EG1_EG1(nEarlyOut, pReverbData->m_sEarlyL.m_nLpfFwd);
-
- //nTemp2 = MULT_EG1_EG1(psEarly->m_zLpf, psEarly->m_nLpfFbk);
- nTemp2 = MULT_EG1_EG1(pReverbData->m_sEarlyL.m_zLpf, pReverbData->m_sEarlyL.m_nLpfFbk);
-
-
- // calculate filtered out and simultaneously update LPF state variable
- // filtered output is stored in m_zLpf1
- //psEarly->m_zLpf = SATURATE(nTemp1 + nTemp2);
- pReverbData->m_sEarlyL.m_zLpf = (EAS_PCM) SATURATE(nTemp1 + nTemp2);
-
- // combine filtered early and late reflections for output
- //*pOutputBuffer++ = inL;
- //tempValue = SATURATE(psEarly->m_zLpf + pReverbData->m_nRevOutFbkL);
- tempValue = SATURATE((EAS_I32)pReverbData->m_sEarlyL.m_zLpf + (EAS_I32)pReverbData->m_nRevOutFbkL);
- //scale reverb output by wet level
- /*lint -e{701} use shift for performance */
- tempValue = MULT_EG1_EG1(tempValue, (pReverbData->m_nWet<<1));
- //sum with output buffer
- tempValue += *pOutputBuffer;
- *pOutputBuffer++ = (EAS_PCM)SATURATE(tempValue);
-
- // ********** end early reflection generator, left
-
- // ********** start early reflection generator, right
- //psEarly = &(pReverbData->m_sEarlyR);
-
- nEarlyOut = 0;
-
- for (j=0; j < REVERB_MAX_NUM_REFLECTIONS; j++)
- {
- // fetch delay line out
- nAddr = CIRCULAR(nBase, pReverbData->m_sEarlyR.m_zDelay[j], REVERB_BUFFER_MASK);
- nDelayOut = pReverbData->m_nDelayLine[nAddr];
-
- // calculate reflection
- nTemp1 = MULT_EG1_EG1(nDelayOut, pReverbData->m_sEarlyR.m_nGain[j]);
-
- nEarlyOut = SATURATE(nEarlyOut + nTemp1);
-
- } // end for (j=0; j < REVERB_MAX_NUM_REFLECTIONS; j++)
-
- // apply lowpass to early reflections
- nTemp1 = MULT_EG1_EG1(nEarlyOut, pReverbData->m_sEarlyR.m_nLpfFwd);
-
- nTemp2 = MULT_EG1_EG1(pReverbData->m_sEarlyR.m_zLpf, pReverbData->m_sEarlyR.m_nLpfFbk);
-
- // calculate filtered out and simultaneously update LPF state variable
- // filtered output is stored in m_zLpf1
- pReverbData->m_sEarlyR.m_zLpf = (EAS_PCM)SATURATE(nTemp1 + nTemp2);
-
- // combine filtered early and late reflections for output
- //*pOutputBuffer++ = inR;
- tempValue = SATURATE((EAS_I32)pReverbData->m_sEarlyR.m_zLpf + (EAS_I32)pReverbData->m_nRevOutFbkR);
- //scale reverb output by wet level
- /*lint -e{701} use shift for performance */
- tempValue = MULT_EG1_EG1(tempValue, (pReverbData->m_nWet << 1));
- //sum with output buffer
- tempValue = tempValue + *pOutputBuffer;
- *pOutputBuffer++ = (EAS_PCM)SATURATE(tempValue);
-
- // ********** end early reflection generator, right
-
- // decrement base addr for next sample period
- nBase--;
-
- pReverbData->m_nSin += pReverbData->m_nSinIncrement;
- pReverbData->m_nCos += pReverbData->m_nCosIncrement;
-
- } // end for (i=0; i < nNumSamplesToAdd; i++)
-
- // store the most up to date version
- pReverbData->m_nBaseIndex = nBase;
-
- return EAS_SUCCESS;
-} /* end Reverb */
-
-
-
-/*----------------------------------------------------------------------------
- * ReverbShutdown()
- *----------------------------------------------------------------------------
- * Purpose:
- * Initializes the Reverb effect.
- *
- * Inputs:
- * pInstData - handle to instance data
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT ReverbShutdown (EAS_DATA_HANDLE pEASData, EAS_VOID_PTR pInstData)
-{
- /* check Configuration Module for static memory allocation */
- if (!pEASData->staticMemoryModel)
- EAS_HWFree(pEASData->hwInstData, pInstData);
- return EAS_SUCCESS;
-} /* end ReverbShutdown */
-
-/*----------------------------------------------------------------------------
- * ReverbGetParam()
- *----------------------------------------------------------------------------
- * Purpose:
- * Get a Reverb parameter
- *
- * Inputs:
- * pInstData - handle to instance data
- * param - parameter index
- * *pValue - pointer to variable to hold retrieved value
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT ReverbGetParam (EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue)
-{
- S_REVERB_OBJECT *p;
-
- p = (S_REVERB_OBJECT*) pInstData;
-
- switch (param)
- {
- case EAS_PARAM_REVERB_BYPASS:
- *pValue = (EAS_I32) p->m_bBypass;
- break;
- case EAS_PARAM_REVERB_PRESET:
- *pValue = (EAS_I8) p->m_nCurrentRoom;
- break;
- case EAS_PARAM_REVERB_WET:
- *pValue = p->m_nWet;
- break;
- case EAS_PARAM_REVERB_DRY:
- *pValue = p->m_nDry;
- break;
- default:
- return EAS_ERROR_INVALID_PARAMETER;
- }
- return EAS_SUCCESS;
-} /* end ReverbGetParam */
-
-
-/*----------------------------------------------------------------------------
- * ReverbSetParam()
- *----------------------------------------------------------------------------
- * Purpose:
- * Set a Reverb parameter
- *
- * Inputs:
- * pInstData - handle to instance data
- * param - parameter index
- * *pValue - new paramter value
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT ReverbSetParam (EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value)
-{
- S_REVERB_OBJECT *p;
-
- p = (S_REVERB_OBJECT*) pInstData;
-
- switch (param)
- {
- case EAS_PARAM_REVERB_BYPASS:
- p->m_bBypass = (EAS_BOOL) value;
- break;
- case EAS_PARAM_REVERB_PRESET:
- if(value!=EAS_PARAM_REVERB_LARGE_HALL && value!=EAS_PARAM_REVERB_HALL &&
- value!=EAS_PARAM_REVERB_CHAMBER && value!=EAS_PARAM_REVERB_ROOM)
- return EAS_ERROR_INVALID_PARAMETER;
- p->m_nNextRoom = (EAS_I16)value;
- break;
- case EAS_PARAM_REVERB_WET:
- if(value>EAS_REVERB_WET_MAX || value<EAS_REVERB_WET_MIN)
- return EAS_ERROR_INVALID_PARAMETER;
- p->m_nWet = (EAS_I16)value;
- break;
- case EAS_PARAM_REVERB_DRY:
- if(value>EAS_REVERB_DRY_MAX || value<EAS_REVERB_DRY_MIN)
- return EAS_ERROR_INVALID_PARAMETER;
- p->m_nDry = (EAS_I16)value;
- break;
- default:
- return EAS_ERROR_INVALID_PARAMETER;
- }
- return EAS_SUCCESS;
-} /* end ReverbSetParam */
-
-
-/*----------------------------------------------------------------------------
- * ReverbUpdateRoom
- *----------------------------------------------------------------------------
- * Purpose:
- * Update the room's preset parameters as required
- *
- * Inputs:
- *
- * Outputs:
- *
- *
- * Side Effects:
- * - reverb paramters (fbk, fwd, etc) will be changed
- * - m_nCurrentRoom := m_nNextRoom
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT ReverbUpdateRoom(S_REVERB_OBJECT *pReverbData)
-{
- EAS_INT temp;
-
- S_REVERB_PRESET *pPreset = &pReverbData->m_sPreset.m_sPreset[pReverbData->m_nNextRoom];
-
- pReverbData->m_nLpfFwd = pPreset->m_nLpfFwd;
- pReverbData->m_nLpfFbk = pPreset->m_nLpfFbk;
-
- pReverbData->m_nEarly = pPreset->m_nEarly;
- pReverbData->m_nWet = pPreset->m_nWet;
- pReverbData->m_nDry = pPreset->m_nDry;
-
-
- pReverbData->m_nMaxExcursion = pPreset->m_nMaxExcursion;
- //stored as time based, convert to sample based
- temp = pPreset->m_nXfadeInterval;
- /*lint -e{702} shift for performance */
- temp = (temp * _OUTPUT_SAMPLE_RATE) >> 16;
- pReverbData->m_nXfadeInterval = (EAS_U16) temp;
- //gpsReverbObject->m_nXfadeInterval = pPreset->m_nXfadeInterval;
- pReverbData->m_sAp0.m_nApGain = pPreset->m_nAp0_ApGain;
- //stored as time based, convert to absolute sample value
- temp = pPreset->m_nAp0_ApOut;
- /*lint -e{702} shift for performance */
- temp = (temp * _OUTPUT_SAMPLE_RATE) >> 16;
- pReverbData->m_sAp0.m_zApOut = (EAS_U16) (pReverbData->m_sAp0.m_zApIn + temp);
- //gpsReverbObject->m_sAp0.m_zApOut = pPreset->m_nAp0_ApOut;
- pReverbData->m_sAp1.m_nApGain = pPreset->m_nAp1_ApGain;
- //stored as time based, convert to absolute sample value
- temp = pPreset->m_nAp1_ApOut;
- /*lint -e{702} shift for performance */
- temp = (temp * _OUTPUT_SAMPLE_RATE) >> 16;
- pReverbData->m_sAp1.m_zApOut = (EAS_U16) (pReverbData->m_sAp1.m_zApIn + temp);
- //gpsReverbObject->m_sAp1.m_zApOut = pPreset->m_nAp1_ApOut;
-
- pReverbData->m_nCurrentRoom = pReverbData->m_nNextRoom;
-
- return EAS_SUCCESS;
-
-} /* end ReverbUpdateRoom */
-
-
-/*----------------------------------------------------------------------------
- * ReverbReadInPresets()
- *----------------------------------------------------------------------------
- * Purpose: sets global reverb preset bank to defaults
- *
- * Inputs:
- *
- * Outputs:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT ReverbReadInPresets(S_REVERB_OBJECT *pReverbData)
-{
-
- int preset = 0;
- int defaultPreset = 0;
-
- //now init any remaining presets to defaults
- for (defaultPreset = preset; defaultPreset < REVERB_MAX_ROOM_TYPE; defaultPreset++)
- {
- S_REVERB_PRESET *pPreset = &pReverbData->m_sPreset.m_sPreset[defaultPreset];
- if (defaultPreset == 0 || defaultPreset > REVERB_MAX_ROOM_TYPE-1)
- {
- pPreset->m_nLpfFbk = 8307;
- pPreset->m_nLpfFwd = 14768;
- pPreset->m_nEarly = 0;
- pPreset->m_nWet = 27690;
- pPreset->m_nDry = 32767;
- pPreset->m_nEarlyL_LpfFbk = 3692;
- pPreset->m_nEarlyL_LpfFwd = 29075;
- pPreset->m_nEarlyL_Delay0 = 922;
- pPreset->m_nEarlyL_Gain0 = 22152;
- pPreset->m_nEarlyL_Delay1 = 1462;
- pPreset->m_nEarlyL_Gain1 = 17537;
- pPreset->m_nEarlyL_Delay2 = 0;
- pPreset->m_nEarlyL_Gain2 = 14768;
- pPreset->m_nEarlyL_Delay3 = 1221;
- pPreset->m_nEarlyL_Gain3 = 14307;
- pPreset->m_nEarlyL_Delay4 = 0;
- pPreset->m_nEarlyL_Gain4 = 13384;
- pPreset->m_nEarlyR_Delay0 = 502;
- pPreset->m_nEarlyR_Gain0 = 20306;
- pPreset->m_nEarlyR_Delay1 = 1762;
- pPreset->m_nEarlyR_Gain1 = 17537;
- pPreset->m_nEarlyR_Delay2 = 0;
- pPreset->m_nEarlyR_Gain2 = 14768;
- pPreset->m_nEarlyR_Delay3 = 0;
- pPreset->m_nEarlyR_Gain3 = 16153;
- pPreset->m_nEarlyR_Delay4 = 0;
- pPreset->m_nEarlyR_Gain4 = 13384;
- pPreset->m_nMaxExcursion = 127;
- pPreset->m_nXfadeInterval = 6388;
- pPreset->m_nAp0_ApGain = 15691;
- pPreset->m_nAp0_ApOut = 711;
- pPreset->m_nAp1_ApGain = 17999;
- pPreset->m_nAp1_ApOut = 1113;
- pPreset->m_rfu4 = 0;
- pPreset->m_rfu5 = 0;
- pPreset->m_rfu6 = 0;
- pPreset->m_rfu7 = 0;
- pPreset->m_rfu8 = 0;
- pPreset->m_rfu9 = 0;
- pPreset->m_rfu10 = 0;
- }
- else if (defaultPreset == 1)
- {
- pPreset->m_nLpfFbk = 6461;
- pPreset->m_nLpfFwd = 14307;
- pPreset->m_nEarly = 0;
- pPreset->m_nWet = 27690;
- pPreset->m_nDry = 32767;
- pPreset->m_nEarlyL_LpfFbk = 3692;
- pPreset->m_nEarlyL_LpfFwd = 29075;
- pPreset->m_nEarlyL_Delay0 = 922;
- pPreset->m_nEarlyL_Gain0 = 22152;
- pPreset->m_nEarlyL_Delay1 = 1462;
- pPreset->m_nEarlyL_Gain1 = 17537;
- pPreset->m_nEarlyL_Delay2 = 0;
- pPreset->m_nEarlyL_Gain2 = 14768;
- pPreset->m_nEarlyL_Delay3 = 1221;
- pPreset->m_nEarlyL_Gain3 = 14307;
- pPreset->m_nEarlyL_Delay4 = 0;
- pPreset->m_nEarlyL_Gain4 = 13384;
- pPreset->m_nEarlyR_Delay0 = 502;
- pPreset->m_nEarlyR_Gain0 = 20306;
- pPreset->m_nEarlyR_Delay1 = 1762;
- pPreset->m_nEarlyR_Gain1 = 17537;
- pPreset->m_nEarlyR_Delay2 = 0;
- pPreset->m_nEarlyR_Gain2 = 14768;
- pPreset->m_nEarlyR_Delay3 = 0;
- pPreset->m_nEarlyR_Gain3 = 16153;
- pPreset->m_nEarlyR_Delay4 = 0;
- pPreset->m_nEarlyR_Gain4 = 13384;
- pPreset->m_nMaxExcursion = 127;
- pPreset->m_nXfadeInterval = 6391;
- pPreset->m_nAp0_ApGain = 15230;
- pPreset->m_nAp0_ApOut = 708;
- pPreset->m_nAp1_ApGain = 9692;
- pPreset->m_nAp1_ApOut = 1113;
- pPreset->m_rfu4 = 0;
- pPreset->m_rfu5 = 0;
- pPreset->m_rfu6 = 0;
- pPreset->m_rfu7 = 0;
- pPreset->m_rfu8 = 0;
- pPreset->m_rfu9 = 0;
- pPreset->m_rfu10 = 0;
- }
- else if (defaultPreset == 2)
- {
- pPreset->m_nLpfFbk = 5077;
- pPreset->m_nLpfFwd = 12922;
- pPreset->m_nEarly = 0;
- pPreset->m_nWet = 24460;
- pPreset->m_nDry = 32767;
- pPreset->m_nEarlyL_LpfFbk = 3692;
- pPreset->m_nEarlyL_LpfFwd = 29075;
- pPreset->m_nEarlyL_Delay0 = 922;
- pPreset->m_nEarlyL_Gain0 = 22152;
- pPreset->m_nEarlyL_Delay1 = 1462;
- pPreset->m_nEarlyL_Gain1 = 17537;
- pPreset->m_nEarlyL_Delay2 = 0;
- pPreset->m_nEarlyL_Gain2 = 14768;
- pPreset->m_nEarlyL_Delay3 = 1221;
- pPreset->m_nEarlyL_Gain3 = 14307;
- pPreset->m_nEarlyL_Delay4 = 0;
- pPreset->m_nEarlyL_Gain4 = 13384;
- pPreset->m_nEarlyR_Delay0 = 502;
- pPreset->m_nEarlyR_Gain0 = 20306;
- pPreset->m_nEarlyR_Delay1 = 1762;
- pPreset->m_nEarlyR_Gain1 = 17537;
- pPreset->m_nEarlyR_Delay2 = 0;
- pPreset->m_nEarlyR_Gain2 = 14768;
- pPreset->m_nEarlyR_Delay3 = 0;
- pPreset->m_nEarlyR_Gain3 = 16153;
- pPreset->m_nEarlyR_Delay4 = 0;
- pPreset->m_nEarlyR_Gain4 = 13384;
- pPreset->m_nMaxExcursion = 127;
- pPreset->m_nXfadeInterval = 6449;
- pPreset->m_nAp0_ApGain = 15691;
- pPreset->m_nAp0_ApOut = 774;
- pPreset->m_nAp1_ApGain = 15691;
- pPreset->m_nAp1_ApOut = 1113;
- pPreset->m_rfu4 = 0;
- pPreset->m_rfu5 = 0;
- pPreset->m_rfu6 = 0;
- pPreset->m_rfu7 = 0;
- pPreset->m_rfu8 = 0;
- pPreset->m_rfu9 = 0;
- pPreset->m_rfu10 = 0;
- }
- else if (defaultPreset == 3)
- {
- pPreset->m_nLpfFbk = 5077;
- pPreset->m_nLpfFwd = 11076;
- pPreset->m_nEarly = 0;
- pPreset->m_nWet = 23075;
- pPreset->m_nDry = 32767;
- pPreset->m_nEarlyL_LpfFbk = 3692;
- pPreset->m_nEarlyL_LpfFwd = 29075;
- pPreset->m_nEarlyL_Delay0 = 922;
- pPreset->m_nEarlyL_Gain0 = 22152;
- pPreset->m_nEarlyL_Delay1 = 1462;
- pPreset->m_nEarlyL_Gain1 = 17537;
- pPreset->m_nEarlyL_Delay2 = 0;
- pPreset->m_nEarlyL_Gain2 = 14768;
- pPreset->m_nEarlyL_Delay3 = 1221;
- pPreset->m_nEarlyL_Gain3 = 14307;
- pPreset->m_nEarlyL_Delay4 = 0;
- pPreset->m_nEarlyL_Gain4 = 13384;
- pPreset->m_nEarlyR_Delay0 = 502;
- pPreset->m_nEarlyR_Gain0 = 20306;
- pPreset->m_nEarlyR_Delay1 = 1762;
- pPreset->m_nEarlyR_Gain1 = 17537;
- pPreset->m_nEarlyR_Delay2 = 0;
- pPreset->m_nEarlyR_Gain2 = 14768;
- pPreset->m_nEarlyR_Delay3 = 0;
- pPreset->m_nEarlyR_Gain3 = 16153;
- pPreset->m_nEarlyR_Delay4 = 0;
- pPreset->m_nEarlyR_Gain4 = 13384;
- pPreset->m_nMaxExcursion = 127;
- pPreset->m_nXfadeInterval = 6470; //6483;
- pPreset->m_nAp0_ApGain = 14768;
- pPreset->m_nAp0_ApOut = 792;
- pPreset->m_nAp1_ApGain = 15783;
- pPreset->m_nAp1_ApOut = 1113;
- pPreset->m_rfu4 = 0;
- pPreset->m_rfu5 = 0;
- pPreset->m_rfu6 = 0;
- pPreset->m_rfu7 = 0;
- pPreset->m_rfu8 = 0;
- pPreset->m_rfu9 = 0;
- pPreset->m_rfu10 = 0;
-
- }
- }
-
- return EAS_SUCCESS;
-}
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 510 $
+ * $Date: 2006-12-19 01:47:33 -0800 (Tue, 19 Dec 2006) $
+ *----------------------------------------------------------------------------
+*/
+
+/*------------------------------------
+ * includes
+ *------------------------------------
+*/
+
+#include "eas_data.h"
+#include "eas_effects.h"
+#include "eas_math.h"
+#include "eas_reverbdata.h"
+#include "eas_reverb.h"
+#include "eas_config.h"
+#include "eas_host.h"
+#include "eas_report.h"
+
+/* prototypes for effects interface */
+static EAS_RESULT ReverbInit (EAS_DATA_HANDLE pEASData, EAS_VOID_PTR *pInstData);
+static void ReverbProcess (EAS_VOID_PTR pInstData, EAS_PCM *pSrc, EAS_PCM *pDst, EAS_I32 numSamples);
+static EAS_RESULT ReverbShutdown (EAS_DATA_HANDLE pEASData, EAS_VOID_PTR pInstData);
+static EAS_RESULT ReverbGetParam (EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue);
+static EAS_RESULT ReverbSetParam (EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value);
+
+/* common effects interface for configuration module */
+const S_EFFECTS_INTERFACE EAS_Reverb =
+{
+ ReverbInit,
+ ReverbProcess,
+ ReverbShutdown,
+ ReverbGetParam,
+ ReverbSetParam
+};
+
+
+
+/*----------------------------------------------------------------------------
+ * InitializeReverb()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ *
+ * Inputs:
+ *
+ * Outputs:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT ReverbInit(EAS_DATA_HANDLE pEASData, EAS_VOID_PTR *pInstData)
+{
+ EAS_I32 i;
+ EAS_U16 nOffset;
+ EAS_INT temp;
+
+ S_REVERB_OBJECT *pReverbData;
+ S_REVERB_PRESET *pPreset;
+
+ /* check Configuration Module for data allocation */
+ if (pEASData->staticMemoryModel)
+ pReverbData = EAS_CMEnumFXData(EAS_MODULE_REVERB);
+
+ /* allocate dynamic memory */
+ else
+ pReverbData = EAS_HWMalloc(pEASData->hwInstData, sizeof(S_REVERB_OBJECT));
+
+ if (pReverbData == NULL)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_FATAL, "Failed to allocate Reverb memory\n"); */ }
+ return EAS_ERROR_MALLOC_FAILED;
+ }
+
+ /* clear the structure */
+ EAS_HWMemSet(pReverbData, 0, sizeof(S_REVERB_OBJECT));
+
+ ReverbReadInPresets(pReverbData);
+
+ pReverbData->m_nMinSamplesToAdd = REVERB_UPDATE_PERIOD_IN_SAMPLES;
+
+ pReverbData->m_nRevOutFbkR = 0;
+ pReverbData->m_nRevOutFbkL = 0;
+
+ pReverbData->m_sAp0.m_zApIn = AP0_IN;
+ pReverbData->m_sAp0.m_zApOut = AP0_IN + DEFAULT_AP0_LENGTH;
+ pReverbData->m_sAp0.m_nApGain = DEFAULT_AP0_GAIN;
+
+ pReverbData->m_zD0In = DELAY0_IN;
+
+ pReverbData->m_sAp1.m_zApIn = AP1_IN;
+ pReverbData->m_sAp1.m_zApOut = AP1_IN + DEFAULT_AP1_LENGTH;
+ pReverbData->m_sAp1.m_nApGain = DEFAULT_AP1_GAIN;
+
+ pReverbData->m_zD1In = DELAY1_IN;
+
+ pReverbData->m_zLpf0 = 0;
+ pReverbData->m_zLpf1 = 0;
+ pReverbData->m_nLpfFwd = 8837;
+ pReverbData->m_nLpfFbk = 6494;
+
+ pReverbData->m_nSin = 0;
+ pReverbData->m_nCos = 0;
+ pReverbData->m_nSinIncrement = 0;
+ pReverbData->m_nCosIncrement = 0;
+
+ // set xfade parameters
+ pReverbData->m_nXfadeInterval = (EAS_U16)REVERB_XFADE_PERIOD_IN_SAMPLES;
+ pReverbData->m_nXfadeCounter = pReverbData->m_nXfadeInterval + 1; // force update on first iteration
+ pReverbData->m_nPhase = -32768;
+ pReverbData->m_nPhaseIncrement = REVERB_XFADE_PHASE_INCREMENT;
+
+ pReverbData->m_nNoise = (EAS_I16)0xABCD;
+
+ pReverbData->m_nMaxExcursion = 0x007F;
+
+ // set delay tap lengths
+ nOffset = ReverbCalculateNoise( pReverbData->m_nMaxExcursion,
+ &pReverbData->m_nNoise );
+
+ pReverbData->m_zD1Cross =
+ DELAY1_OUT - pReverbData->m_nMaxExcursion + nOffset;
+
+ nOffset = ReverbCalculateNoise( pReverbData->m_nMaxExcursion,
+ &pReverbData->m_nNoise );
+
+ pReverbData->m_zD0Cross =
+ DELAY1_OUT - pReverbData->m_nMaxExcursion - nOffset;
+
+ nOffset = ReverbCalculateNoise( pReverbData->m_nMaxExcursion,
+ &pReverbData->m_nNoise );
+
+ pReverbData->m_zD0Self =
+ DELAY0_OUT - pReverbData->m_nMaxExcursion - nOffset;
+
+ nOffset = ReverbCalculateNoise( pReverbData->m_nMaxExcursion,
+ &pReverbData->m_nNoise );
+
+ pReverbData->m_zD1Self =
+ DELAY1_OUT - pReverbData->m_nMaxExcursion + nOffset;
+
+ // for debugging purposes, allow noise generator
+ pReverbData->m_bUseNoise = EAS_FALSE;
+
+ // for debugging purposes, allow bypass
+ pReverbData->m_bBypass = EAS_TRUE; //EAS_FALSE;
+
+ pReverbData->m_nNextRoom = 1;
+
+ pReverbData->m_nCurrentRoom = pReverbData->m_nNextRoom + 1; // force update on first iteration
+
+ pReverbData->m_nWet = REVERB_DEFAULT_WET;
+
+ pReverbData->m_nDry = REVERB_DEFAULT_DRY;
+
+ // set base index into circular buffer
+ pReverbData->m_nBaseIndex = 0;
+
+ // set the early reflections, L
+ pReverbData->m_sEarlyL.m_nLpfFbk = 4915;
+ pReverbData->m_sEarlyL.m_nLpfFwd = 27852;
+ pReverbData->m_sEarlyL.m_zLpf = 0;
+
+ for (i=0; i < REVERB_MAX_NUM_REFLECTIONS; i++)
+ {
+ pReverbData->m_sEarlyL.m_nGain[i] = 0;
+ pReverbData->m_sEarlyL.m_zDelay[i] = 0;
+ }
+
+ // set the early reflections, R
+ pReverbData->m_sEarlyR.m_nLpfFbk = 4915;
+ pReverbData->m_sEarlyR.m_nLpfFwd = 27852;
+ pReverbData->m_sEarlyR.m_zLpf = 0;
+
+ for (i=0; i < REVERB_MAX_NUM_REFLECTIONS; i++)
+ {
+ pReverbData->m_sEarlyR.m_nGain[i] = 0;
+ pReverbData->m_sEarlyR.m_zDelay[i] = 0;
+ }
+
+ // clear the reverb delay line
+ for (i=0; i < REVERB_BUFFER_SIZE_IN_SAMPLES; i++)
+ {
+ pReverbData->m_nDelayLine[i] = 0;
+ }
+
+ ////////////////////////////////
+ ///code from the EAS DEMO Reverb
+ //now copy from the new preset into the reverb
+ pPreset = &pReverbData->m_sPreset.m_sPreset[pReverbData->m_nNextRoom];
+
+ pReverbData->m_nLpfFbk = pPreset->m_nLpfFbk;
+ pReverbData->m_nLpfFwd = pPreset->m_nLpfFwd;
+
+ pReverbData->m_nEarly = pPreset->m_nEarly;
+ pReverbData->m_nWet = pPreset->m_nWet;
+ pReverbData->m_nDry = pPreset->m_nDry;
+
+ pReverbData->m_nMaxExcursion = pPreset->m_nMaxExcursion;
+ //stored as time based, convert to sample based
+ temp = pPreset->m_nXfadeInterval;
+ /*lint -e{702} shift for performance */
+ temp = (temp * _OUTPUT_SAMPLE_RATE) >> 16;
+ pReverbData->m_nXfadeInterval = (EAS_U16) temp;
+ //gsReverbObject.m_nXfadeInterval = pPreset->m_nXfadeInterval;
+
+ pReverbData->m_sAp0.m_nApGain = pPreset->m_nAp0_ApGain;
+ //stored as time based, convert to absolute sample value
+ temp = pPreset->m_nAp0_ApOut;
+ /*lint -e{702} shift for performance */
+ temp = (temp * _OUTPUT_SAMPLE_RATE) >> 16;
+ pReverbData->m_sAp0.m_zApOut = (EAS_U16) (pReverbData->m_sAp0.m_zApIn + temp);
+ //gsReverbObject.m_sAp0.m_zApOut = pPreset->m_nAp0_ApOut;
+
+ pReverbData->m_sAp1.m_nApGain = pPreset->m_nAp1_ApGain;
+ //stored as time based, convert to absolute sample value
+ temp = pPreset->m_nAp1_ApOut;
+ /*lint -e{702} shift for performance */
+ temp = (temp * _OUTPUT_SAMPLE_RATE) >> 16;
+ pReverbData->m_sAp1.m_zApOut = (EAS_U16) (pReverbData->m_sAp1.m_zApIn + temp);
+ //gsReverbObject.m_sAp1.m_zApOut = pPreset->m_nAp1_ApOut;
+ ///code from the EAS DEMO Reverb
+ ////////////////////////////////
+
+ *pInstData = pReverbData;
+
+ return EAS_SUCCESS;
+
+} /* end InitializeReverb */
+
+
+
+/*----------------------------------------------------------------------------
+ * ReverbProcess()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Reverberate the requested number of samples (block based processing)
+ *
+ * Inputs:
+ * pInputBuffer - src buffer
+ * pOutputBuffer - dst buffer
+ * nNumSamplesToAdd - number of samples to write to buffer
+ *
+ * Outputs:
+ * number of samples actually written to buffer
+ *
+ * Side Effects:
+ * - samples are added to the presently free buffer
+ *
+ *----------------------------------------------------------------------------
+*/
+static void ReverbProcess(EAS_VOID_PTR pInstData, EAS_PCM *pSrc, EAS_PCM *pDst, EAS_I32 numSamples)
+{
+ S_REVERB_OBJECT *pReverbData;
+
+ pReverbData = (S_REVERB_OBJECT*) pInstData;
+
+ //if bypassed or the preset forces the signal to be completely dry
+ if (pReverbData->m_bBypass ||
+ (pReverbData->m_nWet == 0 && pReverbData->m_nDry == 32767))
+ {
+ if (pSrc != pDst)
+ EAS_HWMemCpy(pSrc, pDst, numSamples * NUM_OUTPUT_CHANNELS * (EAS_I32) sizeof(EAS_PCM));
+ return;
+ }
+
+ if (pReverbData->m_nNextRoom != pReverbData->m_nCurrentRoom)
+ {
+ ReverbUpdateRoom(pReverbData);
+ }
+
+ ReverbUpdateXfade(pReverbData, numSamples);
+
+ Reverb(pReverbData, numSamples, pDst, pSrc);
+
+ /* check if update counter needs to be reset */
+ if (pReverbData->m_nUpdateCounter >= REVERB_MODULO_UPDATE_PERIOD_IN_SAMPLES)
+ {
+ /* update interval has elapsed, so reset counter */
+ pReverbData->m_nUpdateCounter = 0;
+ } /* end if m_nUpdateCounter >= update interval */
+
+ /* increment update counter */
+ pReverbData->m_nUpdateCounter += (EAS_I16)numSamples;
+
+} /* end ComputeReverb */
+
+/*----------------------------------------------------------------------------
+ * ReverbUpdateXfade
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Update the xfade parameters as required
+ *
+ * Inputs:
+ * nNumSamplesToAdd - number of samples to write to buffer
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ * - xfade parameters will be changed
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT ReverbUpdateXfade(S_REVERB_OBJECT *pReverbData, EAS_INT nNumSamplesToAdd)
+{
+ EAS_U16 nOffset;
+ EAS_I16 tempCos;
+ EAS_I16 tempSin;
+
+ if (pReverbData->m_nXfadeCounter >= pReverbData->m_nXfadeInterval)
+ {
+ /* update interval has elapsed, so reset counter */
+ pReverbData->m_nXfadeCounter = 0;
+
+ // Pin the sin,cos values to min / max values to ensure that the
+ // modulated taps' coefs are zero (thus no clicks)
+ if (pReverbData->m_nPhaseIncrement > 0)
+ {
+ // if phase increment > 0, then sin -> 1, cos -> 0
+ pReverbData->m_nSin = 32767;
+ pReverbData->m_nCos = 0;
+
+ // reset the phase to match the sin, cos values
+ pReverbData->m_nPhase = 32767;
+
+ // modulate the cross taps because their tap coefs are zero
+ nOffset = ReverbCalculateNoise( pReverbData->m_nMaxExcursion, &pReverbData->m_nNoise );
+
+ pReverbData->m_zD1Cross =
+ DELAY1_OUT - pReverbData->m_nMaxExcursion + nOffset;
+
+ nOffset = ReverbCalculateNoise( pReverbData->m_nMaxExcursion, &pReverbData->m_nNoise );
+
+ pReverbData->m_zD0Cross =
+ DELAY0_OUT - pReverbData->m_nMaxExcursion - nOffset;
+ }
+ else
+ {
+ // if phase increment < 0, then sin -> 0, cos -> 1
+ pReverbData->m_nSin = 0;
+ pReverbData->m_nCos = 32767;
+
+ // reset the phase to match the sin, cos values
+ pReverbData->m_nPhase = -32768;
+
+ // modulate the self taps because their tap coefs are zero
+ nOffset = ReverbCalculateNoise( pReverbData->m_nMaxExcursion, &pReverbData->m_nNoise );
+
+ pReverbData->m_zD0Self =
+ DELAY0_OUT - pReverbData->m_nMaxExcursion - nOffset;
+
+ nOffset = ReverbCalculateNoise( pReverbData->m_nMaxExcursion, &pReverbData->m_nNoise );
+
+ pReverbData->m_zD1Self =
+ DELAY1_OUT - pReverbData->m_nMaxExcursion + nOffset;
+
+ } // end if-else (pReverbData->m_nPhaseIncrement > 0)
+
+ // Reverse the direction of the sin,cos so that the
+ // tap whose coef was previously increasing now decreases
+ // and vice versa
+ pReverbData->m_nPhaseIncrement = -pReverbData->m_nPhaseIncrement;
+
+ } // end if counter >= update interval
+
+ //compute what phase will be next time
+ pReverbData->m_nPhase += pReverbData->m_nPhaseIncrement;
+
+ //calculate what the new sin and cos need to reach by the next update
+ ReverbCalculateSinCos(pReverbData->m_nPhase, &tempSin, &tempCos);
+
+ //calculate the per-sample increment required to get there by the next update
+ /*lint -e{702} shift for performance */
+ pReverbData->m_nSinIncrement =
+ (tempSin - pReverbData->m_nSin) >> REVERB_UPDATE_PERIOD_IN_BITS;
+
+ /*lint -e{702} shift for performance */
+ pReverbData->m_nCosIncrement =
+ (tempCos - pReverbData->m_nCos) >> REVERB_UPDATE_PERIOD_IN_BITS;
+
+
+ /* increment update counter */
+ pReverbData->m_nXfadeCounter += (EAS_U16) nNumSamplesToAdd;
+
+ return EAS_SUCCESS;
+
+} /* end ReverbUpdateXfade */
+
+
+/*----------------------------------------------------------------------------
+ * ReverbCalculateNoise
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Calculate a noise sample and limit its value
+ *
+ * Inputs:
+ * nMaxExcursion - noise value is limited to this value
+ * pnNoise - return new noise sample in this (not limited)
+ *
+ * Outputs:
+ * new limited noise value
+ *
+ * Side Effects:
+ * - *pnNoise noise value is updated
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_U16 ReverbCalculateNoise(EAS_U16 nMaxExcursion, EAS_I16 *pnNoise)
+{
+ // calculate new noise value
+ *pnNoise = (EAS_I16) (*pnNoise * 5 + 1);
+
+#if 0 // 1xxx, test
+ *pnNoise = 0;
+#endif // 1xxx, test
+
+ // return the limited noise value
+ return (nMaxExcursion & (*pnNoise));
+
+} /* end ReverbCalculateNoise */
+
+/*----------------------------------------------------------------------------
+ * ReverbCalculateSinCos
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Calculate a new sin and cosine value based on the given phase
+ *
+ * Inputs:
+ * nPhase - phase angle
+ * pnSin - input old value, output new value
+ * pnCos - input old value, output new value
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ * - *pnSin, *pnCos are updated
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT ReverbCalculateSinCos(EAS_I16 nPhase, EAS_I16 *pnSin, EAS_I16 *pnCos)
+{
+ EAS_I32 nTemp;
+ EAS_I32 nNetAngle;
+
+ // -1 <= nPhase < 1
+ // However, for the calculation, we need a value
+ // that ranges from -1/2 to +1/2, so divide the phase by 2
+ /*lint -e{702} shift for performance */
+ nNetAngle = nPhase >> 1;
+
+ /*
+ Implement the following
+ sin(x) = (2-4*c)*x^2 + c + x
+ cos(x) = (2-4*c)*x^2 + c - x
+
+ where c = 1/sqrt(2)
+ using the a0 + x*(a1 + x*a2) approach
+ */
+
+ /* limit the input "angle" to be between -0.5 and +0.5 */
+ if (nNetAngle > EG1_HALF)
+ {
+ nNetAngle = EG1_HALF;
+ }
+ else if (nNetAngle < EG1_MINUS_HALF)
+ {
+ nNetAngle = EG1_MINUS_HALF;
+ }
+
+ /* calculate sin */
+ nTemp = EG1_ONE + MULT_EG1_EG1(REVERB_PAN_G2, nNetAngle);
+ nTemp = REVERB_PAN_G0 + MULT_EG1_EG1(nTemp, nNetAngle);
+ *pnSin = (EAS_I16) SATURATE_EG1(nTemp);
+
+ /* calculate cos */
+ nTemp = -EG1_ONE + MULT_EG1_EG1(REVERB_PAN_G2, nNetAngle);
+ nTemp = REVERB_PAN_G0 + MULT_EG1_EG1(nTemp, nNetAngle);
+ *pnCos = (EAS_I16) SATURATE_EG1(nTemp);
+
+ return EAS_SUCCESS;
+} /* end ReverbCalculateSinCos */
+
+/*----------------------------------------------------------------------------
+ * Reverb
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * apply reverb to the given signal
+ *
+ * Inputs:
+ * nNu
+ * pnSin - input old value, output new value
+ * pnCos - input old value, output new value
+ *
+ * Outputs:
+ * number of samples actually reverberated
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT Reverb(S_REVERB_OBJECT *pReverbData, EAS_INT nNumSamplesToAdd, EAS_PCM *pOutputBuffer, EAS_PCM *pInputBuffer)
+{
+ EAS_I32 i;
+ EAS_I32 nDelayOut;
+ EAS_U16 nBase;
+
+ EAS_U32 nAddr;
+ EAS_I32 nTemp1;
+ EAS_I32 nTemp2;
+ EAS_I32 nApIn;
+ EAS_I32 nApOut;
+
+ EAS_I32 j;
+ EAS_I32 nEarlyOut;
+
+ EAS_I32 tempValue;
+
+
+ // get the base address
+ nBase = pReverbData->m_nBaseIndex;
+
+ for (i=0; i < nNumSamplesToAdd; i++)
+ {
+ // ********** Left Allpass - start
+ // left input = (left dry/4) + right feedback from previous period
+ /*lint -e{702} use shift for performance */
+ nApIn = ((*pInputBuffer++)>>2) + pReverbData->m_nRevOutFbkR;
+// nApIn = *pInputBuffer++; // 1xxx test and debug ap
+
+ // fetch allpass delay line out
+ //nAddr = CIRCULAR(nBase, psAp0->m_zApOut, REVERB_BUFFER_MASK);
+ nAddr = CIRCULAR(nBase, pReverbData->m_sAp0.m_zApOut, REVERB_BUFFER_MASK);
+ nDelayOut = pReverbData->m_nDelayLine[nAddr];
+
+ // calculate allpass feedforward; subtract the feedforward result
+ nTemp1 = MULT_EG1_EG1(nApIn, pReverbData->m_sAp0.m_nApGain);
+ nApOut = SATURATE(nDelayOut - nTemp1); // allpass output
+
+ // calculate allpass feedback; add the feedback result
+ nTemp1 = MULT_EG1_EG1(nApOut, pReverbData->m_sAp0.m_nApGain);
+ nTemp1 = SATURATE(nApIn + nTemp1);
+
+ // inject into allpass delay
+ nAddr = CIRCULAR(nBase, pReverbData->m_sAp0.m_zApIn, REVERB_BUFFER_MASK);
+ pReverbData->m_nDelayLine[nAddr] = (EAS_PCM) nTemp1;
+
+ // inject allpass output into delay line
+ nAddr = CIRCULAR(nBase, pReverbData->m_zD0In, REVERB_BUFFER_MASK);
+ pReverbData->m_nDelayLine[nAddr] = (EAS_PCM) nApOut;
+
+ // ********** Left Allpass - end
+
+ // ********** Right Allpass - start
+ // right input = (right dry/4) + left feedback from previous period
+ /*lint -e{702} use shift for performance */
+ nApIn = ((*pInputBuffer++)>>2) + pReverbData->m_nRevOutFbkL;
+// nApIn = *pInputBuffer++; // 1xxx test and debug ap
+
+ // fetch allpass delay line out
+ nAddr = CIRCULAR(nBase, pReverbData->m_sAp1.m_zApOut, REVERB_BUFFER_MASK);
+ nDelayOut = pReverbData->m_nDelayLine[nAddr];
+
+ // calculate allpass feedforward; subtract the feedforward result
+ nTemp1 = MULT_EG1_EG1(nApIn, pReverbData->m_sAp1.m_nApGain);
+ nApOut = SATURATE(nDelayOut - nTemp1); // allpass output
+
+ // calculate allpass feedback; add the feedback result
+ nTemp1 = MULT_EG1_EG1(nApOut, pReverbData->m_sAp1.m_nApGain);
+ nTemp1 = SATURATE(nApIn + nTemp1);
+
+ // inject into allpass delay
+ nAddr = CIRCULAR(nBase, pReverbData->m_sAp1.m_zApIn, REVERB_BUFFER_MASK);
+ pReverbData->m_nDelayLine[nAddr] = (EAS_PCM) nTemp1;
+
+ // inject allpass output into delay line
+ nAddr = CIRCULAR(nBase, pReverbData->m_zD1In, REVERB_BUFFER_MASK);
+ pReverbData->m_nDelayLine[nAddr] = (EAS_PCM) nApOut;
+
+ // ********** Right Allpass - end
+
+ // ********** D0 output - start
+ // fetch delay line self out
+ nAddr = CIRCULAR(nBase, pReverbData->m_zD0Self, REVERB_BUFFER_MASK);
+ nDelayOut = pReverbData->m_nDelayLine[nAddr];
+
+ // calculate delay line self out
+ nTemp1 = MULT_EG1_EG1(nDelayOut, pReverbData->m_nSin);
+
+ // fetch delay line cross out
+ nAddr = CIRCULAR(nBase, pReverbData->m_zD1Cross, REVERB_BUFFER_MASK);
+ nDelayOut = pReverbData->m_nDelayLine[nAddr];
+
+ // calculate delay line self out
+ nTemp2 = MULT_EG1_EG1(nDelayOut, pReverbData->m_nCos);
+
+ // calculate unfiltered delay out
+ nDelayOut = SATURATE(nTemp1 + nTemp2);
+
+ // calculate lowpass filter (mixer scale factor included in LPF feedforward)
+ nTemp1 = MULT_EG1_EG1(nDelayOut, pReverbData->m_nLpfFwd);
+
+ nTemp2 = MULT_EG1_EG1(pReverbData->m_zLpf0, pReverbData->m_nLpfFbk);
+
+ // calculate filtered delay out and simultaneously update LPF state variable
+ // filtered delay output is stored in m_zLpf0
+ pReverbData->m_zLpf0 = (EAS_PCM) SATURATE(nTemp1 + nTemp2);
+
+ // ********** D0 output - end
+
+ // ********** D1 output - start
+ // fetch delay line self out
+ nAddr = CIRCULAR(nBase, pReverbData->m_zD1Self, REVERB_BUFFER_MASK);
+ nDelayOut = pReverbData->m_nDelayLine[nAddr];
+
+ // calculate delay line self out
+ nTemp1 = MULT_EG1_EG1(nDelayOut, pReverbData->m_nSin);
+
+ // fetch delay line cross out
+ nAddr = CIRCULAR(nBase, pReverbData->m_zD0Cross, REVERB_BUFFER_MASK);
+ nDelayOut = pReverbData->m_nDelayLine[nAddr];
+
+ // calculate delay line self out
+ nTemp2 = MULT_EG1_EG1(nDelayOut, pReverbData->m_nCos);
+
+ // calculate unfiltered delay out
+ nDelayOut = SATURATE(nTemp1 + nTemp2);
+
+ // calculate lowpass filter (mixer scale factor included in LPF feedforward)
+ nTemp1 = MULT_EG1_EG1(nDelayOut, pReverbData->m_nLpfFwd);
+
+ nTemp2 = MULT_EG1_EG1(pReverbData->m_zLpf1, pReverbData->m_nLpfFbk);
+
+ // calculate filtered delay out and simultaneously update LPF state variable
+ // filtered delay output is stored in m_zLpf1
+ pReverbData->m_zLpf1 = (EAS_PCM)SATURATE(nTemp1 + nTemp2);
+
+ // ********** D1 output - end
+
+ // ********** mixer and feedback - start
+ // sum is fedback to right input (R + L)
+ pReverbData->m_nRevOutFbkL =
+ (EAS_PCM)SATURATE((EAS_I32)pReverbData->m_zLpf1 + (EAS_I32)pReverbData->m_zLpf0);
+
+ // difference is feedback to left input (R - L)
+ /*lint -e{685} lint complains that it can't saturate negative */
+ pReverbData->m_nRevOutFbkR =
+ (EAS_PCM)SATURATE((EAS_I32)pReverbData->m_zLpf1 - (EAS_I32)pReverbData->m_zLpf0);
+
+ // ********** mixer and feedback - end
+
+ // ********** start early reflection generator, left
+ //psEarly = &(pReverbData->m_sEarlyL);
+
+ nEarlyOut = 0;
+
+ for (j=0; j < REVERB_MAX_NUM_REFLECTIONS; j++)
+ {
+ // fetch delay line out
+ //nAddr = CIRCULAR(nBase, psEarly->m_zDelay[j], REVERB_BUFFER_MASK);
+ nAddr = CIRCULAR(nBase, pReverbData->m_sEarlyL.m_zDelay[j], REVERB_BUFFER_MASK);
+
+ nDelayOut = pReverbData->m_nDelayLine[nAddr];
+
+ // calculate reflection
+ //nTemp1 = MULT_EG1_EG1(nDelayOut, psEarly->m_nGain[j]);
+ nTemp1 = MULT_EG1_EG1(nDelayOut, pReverbData->m_sEarlyL.m_nGain[j]);
+
+ nEarlyOut = SATURATE(nEarlyOut + nTemp1);
+
+ } // end for (j=0; j < REVERB_MAX_NUM_REFLECTIONS; j++)
+
+ // apply lowpass to early reflections
+ //nTemp1 = MULT_EG1_EG1(nEarlyOut, psEarly->m_nLpfFwd);
+ nTemp1 = MULT_EG1_EG1(nEarlyOut, pReverbData->m_sEarlyL.m_nLpfFwd);
+
+ //nTemp2 = MULT_EG1_EG1(psEarly->m_zLpf, psEarly->m_nLpfFbk);
+ nTemp2 = MULT_EG1_EG1(pReverbData->m_sEarlyL.m_zLpf, pReverbData->m_sEarlyL.m_nLpfFbk);
+
+
+ // calculate filtered out and simultaneously update LPF state variable
+ // filtered output is stored in m_zLpf1
+ //psEarly->m_zLpf = SATURATE(nTemp1 + nTemp2);
+ pReverbData->m_sEarlyL.m_zLpf = (EAS_PCM) SATURATE(nTemp1 + nTemp2);
+
+ // combine filtered early and late reflections for output
+ //*pOutputBuffer++ = inL;
+ //tempValue = SATURATE(psEarly->m_zLpf + pReverbData->m_nRevOutFbkL);
+ tempValue = SATURATE((EAS_I32)pReverbData->m_sEarlyL.m_zLpf + (EAS_I32)pReverbData->m_nRevOutFbkL);
+ //scale reverb output by wet level
+ /*lint -e{701} use shift for performance */
+ tempValue = MULT_EG1_EG1(tempValue, (pReverbData->m_nWet<<1));
+ //sum with output buffer
+ tempValue += *pOutputBuffer;
+ *pOutputBuffer++ = (EAS_PCM)SATURATE(tempValue);
+
+ // ********** end early reflection generator, left
+
+ // ********** start early reflection generator, right
+ //psEarly = &(pReverbData->m_sEarlyR);
+
+ nEarlyOut = 0;
+
+ for (j=0; j < REVERB_MAX_NUM_REFLECTIONS; j++)
+ {
+ // fetch delay line out
+ nAddr = CIRCULAR(nBase, pReverbData->m_sEarlyR.m_zDelay[j], REVERB_BUFFER_MASK);
+ nDelayOut = pReverbData->m_nDelayLine[nAddr];
+
+ // calculate reflection
+ nTemp1 = MULT_EG1_EG1(nDelayOut, pReverbData->m_sEarlyR.m_nGain[j]);
+
+ nEarlyOut = SATURATE(nEarlyOut + nTemp1);
+
+ } // end for (j=0; j < REVERB_MAX_NUM_REFLECTIONS; j++)
+
+ // apply lowpass to early reflections
+ nTemp1 = MULT_EG1_EG1(nEarlyOut, pReverbData->m_sEarlyR.m_nLpfFwd);
+
+ nTemp2 = MULT_EG1_EG1(pReverbData->m_sEarlyR.m_zLpf, pReverbData->m_sEarlyR.m_nLpfFbk);
+
+ // calculate filtered out and simultaneously update LPF state variable
+ // filtered output is stored in m_zLpf1
+ pReverbData->m_sEarlyR.m_zLpf = (EAS_PCM)SATURATE(nTemp1 + nTemp2);
+
+ // combine filtered early and late reflections for output
+ //*pOutputBuffer++ = inR;
+ tempValue = SATURATE((EAS_I32)pReverbData->m_sEarlyR.m_zLpf + (EAS_I32)pReverbData->m_nRevOutFbkR);
+ //scale reverb output by wet level
+ /*lint -e{701} use shift for performance */
+ tempValue = MULT_EG1_EG1(tempValue, (pReverbData->m_nWet << 1));
+ //sum with output buffer
+ tempValue = tempValue + *pOutputBuffer;
+ *pOutputBuffer++ = (EAS_PCM)SATURATE(tempValue);
+
+ // ********** end early reflection generator, right
+
+ // decrement base addr for next sample period
+ nBase--;
+
+ pReverbData->m_nSin += pReverbData->m_nSinIncrement;
+ pReverbData->m_nCos += pReverbData->m_nCosIncrement;
+
+ } // end for (i=0; i < nNumSamplesToAdd; i++)
+
+ // store the most up to date version
+ pReverbData->m_nBaseIndex = nBase;
+
+ return EAS_SUCCESS;
+} /* end Reverb */
+
+
+
+/*----------------------------------------------------------------------------
+ * ReverbShutdown()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Initializes the Reverb effect.
+ *
+ * Inputs:
+ * pInstData - handle to instance data
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT ReverbShutdown (EAS_DATA_HANDLE pEASData, EAS_VOID_PTR pInstData)
+{
+ /* check Configuration Module for static memory allocation */
+ if (!pEASData->staticMemoryModel)
+ EAS_HWFree(pEASData->hwInstData, pInstData);
+ return EAS_SUCCESS;
+} /* end ReverbShutdown */
+
+/*----------------------------------------------------------------------------
+ * ReverbGetParam()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Get a Reverb parameter
+ *
+ * Inputs:
+ * pInstData - handle to instance data
+ * param - parameter index
+ * *pValue - pointer to variable to hold retrieved value
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT ReverbGetParam (EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue)
+{
+ S_REVERB_OBJECT *p;
+
+ p = (S_REVERB_OBJECT*) pInstData;
+
+ switch (param)
+ {
+ case EAS_PARAM_REVERB_BYPASS:
+ *pValue = (EAS_I32) p->m_bBypass;
+ break;
+ case EAS_PARAM_REVERB_PRESET:
+ *pValue = (EAS_I8) p->m_nCurrentRoom;
+ break;
+ case EAS_PARAM_REVERB_WET:
+ *pValue = p->m_nWet;
+ break;
+ case EAS_PARAM_REVERB_DRY:
+ *pValue = p->m_nDry;
+ break;
+ default:
+ return EAS_ERROR_INVALID_PARAMETER;
+ }
+ return EAS_SUCCESS;
+} /* end ReverbGetParam */
+
+
+/*----------------------------------------------------------------------------
+ * ReverbSetParam()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Set a Reverb parameter
+ *
+ * Inputs:
+ * pInstData - handle to instance data
+ * param - parameter index
+ * *pValue - new paramter value
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT ReverbSetParam (EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value)
+{
+ S_REVERB_OBJECT *p;
+
+ p = (S_REVERB_OBJECT*) pInstData;
+
+ switch (param)
+ {
+ case EAS_PARAM_REVERB_BYPASS:
+ p->m_bBypass = (EAS_BOOL) value;
+ break;
+ case EAS_PARAM_REVERB_PRESET:
+ if(value!=EAS_PARAM_REVERB_LARGE_HALL && value!=EAS_PARAM_REVERB_HALL &&
+ value!=EAS_PARAM_REVERB_CHAMBER && value!=EAS_PARAM_REVERB_ROOM)
+ return EAS_ERROR_INVALID_PARAMETER;
+ p->m_nNextRoom = (EAS_I16)value;
+ break;
+ case EAS_PARAM_REVERB_WET:
+ if(value>EAS_REVERB_WET_MAX || value<EAS_REVERB_WET_MIN)
+ return EAS_ERROR_INVALID_PARAMETER;
+ p->m_nWet = (EAS_I16)value;
+ break;
+ case EAS_PARAM_REVERB_DRY:
+ if(value>EAS_REVERB_DRY_MAX || value<EAS_REVERB_DRY_MIN)
+ return EAS_ERROR_INVALID_PARAMETER;
+ p->m_nDry = (EAS_I16)value;
+ break;
+ default:
+ return EAS_ERROR_INVALID_PARAMETER;
+ }
+ return EAS_SUCCESS;
+} /* end ReverbSetParam */
+
+
+/*----------------------------------------------------------------------------
+ * ReverbUpdateRoom
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Update the room's preset parameters as required
+ *
+ * Inputs:
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ * - reverb paramters (fbk, fwd, etc) will be changed
+ * - m_nCurrentRoom := m_nNextRoom
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT ReverbUpdateRoom(S_REVERB_OBJECT *pReverbData)
+{
+ EAS_INT temp;
+
+ S_REVERB_PRESET *pPreset = &pReverbData->m_sPreset.m_sPreset[pReverbData->m_nNextRoom];
+
+ pReverbData->m_nLpfFwd = pPreset->m_nLpfFwd;
+ pReverbData->m_nLpfFbk = pPreset->m_nLpfFbk;
+
+ pReverbData->m_nEarly = pPreset->m_nEarly;
+ pReverbData->m_nWet = pPreset->m_nWet;
+ pReverbData->m_nDry = pPreset->m_nDry;
+
+
+ pReverbData->m_nMaxExcursion = pPreset->m_nMaxExcursion;
+ //stored as time based, convert to sample based
+ temp = pPreset->m_nXfadeInterval;
+ /*lint -e{702} shift for performance */
+ temp = (temp * _OUTPUT_SAMPLE_RATE) >> 16;
+ pReverbData->m_nXfadeInterval = (EAS_U16) temp;
+ //gpsReverbObject->m_nXfadeInterval = pPreset->m_nXfadeInterval;
+ pReverbData->m_sAp0.m_nApGain = pPreset->m_nAp0_ApGain;
+ //stored as time based, convert to absolute sample value
+ temp = pPreset->m_nAp0_ApOut;
+ /*lint -e{702} shift for performance */
+ temp = (temp * _OUTPUT_SAMPLE_RATE) >> 16;
+ pReverbData->m_sAp0.m_zApOut = (EAS_U16) (pReverbData->m_sAp0.m_zApIn + temp);
+ //gpsReverbObject->m_sAp0.m_zApOut = pPreset->m_nAp0_ApOut;
+ pReverbData->m_sAp1.m_nApGain = pPreset->m_nAp1_ApGain;
+ //stored as time based, convert to absolute sample value
+ temp = pPreset->m_nAp1_ApOut;
+ /*lint -e{702} shift for performance */
+ temp = (temp * _OUTPUT_SAMPLE_RATE) >> 16;
+ pReverbData->m_sAp1.m_zApOut = (EAS_U16) (pReverbData->m_sAp1.m_zApIn + temp);
+ //gpsReverbObject->m_sAp1.m_zApOut = pPreset->m_nAp1_ApOut;
+
+ pReverbData->m_nCurrentRoom = pReverbData->m_nNextRoom;
+
+ return EAS_SUCCESS;
+
+} /* end ReverbUpdateRoom */
+
+
+/*----------------------------------------------------------------------------
+ * ReverbReadInPresets()
+ *----------------------------------------------------------------------------
+ * Purpose: sets global reverb preset bank to defaults
+ *
+ * Inputs:
+ *
+ * Outputs:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT ReverbReadInPresets(S_REVERB_OBJECT *pReverbData)
+{
+
+ int preset = 0;
+ int defaultPreset = 0;
+
+ //now init any remaining presets to defaults
+ for (defaultPreset = preset; defaultPreset < REVERB_MAX_ROOM_TYPE; defaultPreset++)
+ {
+ S_REVERB_PRESET *pPreset = &pReverbData->m_sPreset.m_sPreset[defaultPreset];
+ if (defaultPreset == 0 || defaultPreset > REVERB_MAX_ROOM_TYPE-1)
+ {
+ pPreset->m_nLpfFbk = 8307;
+ pPreset->m_nLpfFwd = 14768;
+ pPreset->m_nEarly = 0;
+ pPreset->m_nWet = 27690;
+ pPreset->m_nDry = 32767;
+ pPreset->m_nEarlyL_LpfFbk = 3692;
+ pPreset->m_nEarlyL_LpfFwd = 29075;
+ pPreset->m_nEarlyL_Delay0 = 922;
+ pPreset->m_nEarlyL_Gain0 = 22152;
+ pPreset->m_nEarlyL_Delay1 = 1462;
+ pPreset->m_nEarlyL_Gain1 = 17537;
+ pPreset->m_nEarlyL_Delay2 = 0;
+ pPreset->m_nEarlyL_Gain2 = 14768;
+ pPreset->m_nEarlyL_Delay3 = 1221;
+ pPreset->m_nEarlyL_Gain3 = 14307;
+ pPreset->m_nEarlyL_Delay4 = 0;
+ pPreset->m_nEarlyL_Gain4 = 13384;
+ pPreset->m_nEarlyR_Delay0 = 502;
+ pPreset->m_nEarlyR_Gain0 = 20306;
+ pPreset->m_nEarlyR_Delay1 = 1762;
+ pPreset->m_nEarlyR_Gain1 = 17537;
+ pPreset->m_nEarlyR_Delay2 = 0;
+ pPreset->m_nEarlyR_Gain2 = 14768;
+ pPreset->m_nEarlyR_Delay3 = 0;
+ pPreset->m_nEarlyR_Gain3 = 16153;
+ pPreset->m_nEarlyR_Delay4 = 0;
+ pPreset->m_nEarlyR_Gain4 = 13384;
+ pPreset->m_nMaxExcursion = 127;
+ pPreset->m_nXfadeInterval = 6388;
+ pPreset->m_nAp0_ApGain = 15691;
+ pPreset->m_nAp0_ApOut = 711;
+ pPreset->m_nAp1_ApGain = 17999;
+ pPreset->m_nAp1_ApOut = 1113;
+ pPreset->m_rfu4 = 0;
+ pPreset->m_rfu5 = 0;
+ pPreset->m_rfu6 = 0;
+ pPreset->m_rfu7 = 0;
+ pPreset->m_rfu8 = 0;
+ pPreset->m_rfu9 = 0;
+ pPreset->m_rfu10 = 0;
+ }
+ else if (defaultPreset == 1)
+ {
+ pPreset->m_nLpfFbk = 6461;
+ pPreset->m_nLpfFwd = 14307;
+ pPreset->m_nEarly = 0;
+ pPreset->m_nWet = 27690;
+ pPreset->m_nDry = 32767;
+ pPreset->m_nEarlyL_LpfFbk = 3692;
+ pPreset->m_nEarlyL_LpfFwd = 29075;
+ pPreset->m_nEarlyL_Delay0 = 922;
+ pPreset->m_nEarlyL_Gain0 = 22152;
+ pPreset->m_nEarlyL_Delay1 = 1462;
+ pPreset->m_nEarlyL_Gain1 = 17537;
+ pPreset->m_nEarlyL_Delay2 = 0;
+ pPreset->m_nEarlyL_Gain2 = 14768;
+ pPreset->m_nEarlyL_Delay3 = 1221;
+ pPreset->m_nEarlyL_Gain3 = 14307;
+ pPreset->m_nEarlyL_Delay4 = 0;
+ pPreset->m_nEarlyL_Gain4 = 13384;
+ pPreset->m_nEarlyR_Delay0 = 502;
+ pPreset->m_nEarlyR_Gain0 = 20306;
+ pPreset->m_nEarlyR_Delay1 = 1762;
+ pPreset->m_nEarlyR_Gain1 = 17537;
+ pPreset->m_nEarlyR_Delay2 = 0;
+ pPreset->m_nEarlyR_Gain2 = 14768;
+ pPreset->m_nEarlyR_Delay3 = 0;
+ pPreset->m_nEarlyR_Gain3 = 16153;
+ pPreset->m_nEarlyR_Delay4 = 0;
+ pPreset->m_nEarlyR_Gain4 = 13384;
+ pPreset->m_nMaxExcursion = 127;
+ pPreset->m_nXfadeInterval = 6391;
+ pPreset->m_nAp0_ApGain = 15230;
+ pPreset->m_nAp0_ApOut = 708;
+ pPreset->m_nAp1_ApGain = 9692;
+ pPreset->m_nAp1_ApOut = 1113;
+ pPreset->m_rfu4 = 0;
+ pPreset->m_rfu5 = 0;
+ pPreset->m_rfu6 = 0;
+ pPreset->m_rfu7 = 0;
+ pPreset->m_rfu8 = 0;
+ pPreset->m_rfu9 = 0;
+ pPreset->m_rfu10 = 0;
+ }
+ else if (defaultPreset == 2)
+ {
+ pPreset->m_nLpfFbk = 5077;
+ pPreset->m_nLpfFwd = 12922;
+ pPreset->m_nEarly = 0;
+ pPreset->m_nWet = 24460;
+ pPreset->m_nDry = 32767;
+ pPreset->m_nEarlyL_LpfFbk = 3692;
+ pPreset->m_nEarlyL_LpfFwd = 29075;
+ pPreset->m_nEarlyL_Delay0 = 922;
+ pPreset->m_nEarlyL_Gain0 = 22152;
+ pPreset->m_nEarlyL_Delay1 = 1462;
+ pPreset->m_nEarlyL_Gain1 = 17537;
+ pPreset->m_nEarlyL_Delay2 = 0;
+ pPreset->m_nEarlyL_Gain2 = 14768;
+ pPreset->m_nEarlyL_Delay3 = 1221;
+ pPreset->m_nEarlyL_Gain3 = 14307;
+ pPreset->m_nEarlyL_Delay4 = 0;
+ pPreset->m_nEarlyL_Gain4 = 13384;
+ pPreset->m_nEarlyR_Delay0 = 502;
+ pPreset->m_nEarlyR_Gain0 = 20306;
+ pPreset->m_nEarlyR_Delay1 = 1762;
+ pPreset->m_nEarlyR_Gain1 = 17537;
+ pPreset->m_nEarlyR_Delay2 = 0;
+ pPreset->m_nEarlyR_Gain2 = 14768;
+ pPreset->m_nEarlyR_Delay3 = 0;
+ pPreset->m_nEarlyR_Gain3 = 16153;
+ pPreset->m_nEarlyR_Delay4 = 0;
+ pPreset->m_nEarlyR_Gain4 = 13384;
+ pPreset->m_nMaxExcursion = 127;
+ pPreset->m_nXfadeInterval = 6449;
+ pPreset->m_nAp0_ApGain = 15691;
+ pPreset->m_nAp0_ApOut = 774;
+ pPreset->m_nAp1_ApGain = 15691;
+ pPreset->m_nAp1_ApOut = 1113;
+ pPreset->m_rfu4 = 0;
+ pPreset->m_rfu5 = 0;
+ pPreset->m_rfu6 = 0;
+ pPreset->m_rfu7 = 0;
+ pPreset->m_rfu8 = 0;
+ pPreset->m_rfu9 = 0;
+ pPreset->m_rfu10 = 0;
+ }
+ else if (defaultPreset == 3)
+ {
+ pPreset->m_nLpfFbk = 5077;
+ pPreset->m_nLpfFwd = 11076;
+ pPreset->m_nEarly = 0;
+ pPreset->m_nWet = 23075;
+ pPreset->m_nDry = 32767;
+ pPreset->m_nEarlyL_LpfFbk = 3692;
+ pPreset->m_nEarlyL_LpfFwd = 29075;
+ pPreset->m_nEarlyL_Delay0 = 922;
+ pPreset->m_nEarlyL_Gain0 = 22152;
+ pPreset->m_nEarlyL_Delay1 = 1462;
+ pPreset->m_nEarlyL_Gain1 = 17537;
+ pPreset->m_nEarlyL_Delay2 = 0;
+ pPreset->m_nEarlyL_Gain2 = 14768;
+ pPreset->m_nEarlyL_Delay3 = 1221;
+ pPreset->m_nEarlyL_Gain3 = 14307;
+ pPreset->m_nEarlyL_Delay4 = 0;
+ pPreset->m_nEarlyL_Gain4 = 13384;
+ pPreset->m_nEarlyR_Delay0 = 502;
+ pPreset->m_nEarlyR_Gain0 = 20306;
+ pPreset->m_nEarlyR_Delay1 = 1762;
+ pPreset->m_nEarlyR_Gain1 = 17537;
+ pPreset->m_nEarlyR_Delay2 = 0;
+ pPreset->m_nEarlyR_Gain2 = 14768;
+ pPreset->m_nEarlyR_Delay3 = 0;
+ pPreset->m_nEarlyR_Gain3 = 16153;
+ pPreset->m_nEarlyR_Delay4 = 0;
+ pPreset->m_nEarlyR_Gain4 = 13384;
+ pPreset->m_nMaxExcursion = 127;
+ pPreset->m_nXfadeInterval = 6470; //6483;
+ pPreset->m_nAp0_ApGain = 14768;
+ pPreset->m_nAp0_ApOut = 792;
+ pPreset->m_nAp1_ApGain = 15783;
+ pPreset->m_nAp1_ApOut = 1113;
+ pPreset->m_rfu4 = 0;
+ pPreset->m_rfu5 = 0;
+ pPreset->m_rfu6 = 0;
+ pPreset->m_rfu7 = 0;
+ pPreset->m_rfu8 = 0;
+ pPreset->m_rfu9 = 0;
+ pPreset->m_rfu10 = 0;
+
+ }
+ }
+
+ return EAS_SUCCESS;
+}
diff --git a/arm-hybrid-22k/lib_src/eas_reverbdata.c b/arm-hybrid-22k/lib_src/eas_reverbdata.c
index 5d48c1b..db34b48 100644
--- a/arm-hybrid-22k/lib_src/eas_reverbdata.c
+++ b/arm-hybrid-22k/lib_src/eas_reverbdata.c
@@ -1,13 +1,13 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_reverbdata.c
- *
- * Contents and purpose:
- * Contains the static data allocation for the Reverb effect
- *
- *
- * Copyright Sonic Network Inc. 2006
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_reverbdata.c
+ *
+ * Contents and purpose:
+ * Contains the static data allocation for the Reverb effect
+ *
+ *
+ * Copyright Sonic Network Inc. 2006
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,15 +20,15 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 550 $
- * $Date: 2007-02-02 09:37:03 -0800 (Fri, 02 Feb 2007) $
- *----------------------------------------------------------------------------
-*/
-
-#include "eas_reverbdata.h"
-
-S_REVERB_OBJECT eas_ReverbData;
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 550 $
+ * $Date: 2007-02-02 09:37:03 -0800 (Fri, 02 Feb 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+#include "eas_reverbdata.h"
+
+S_REVERB_OBJECT eas_ReverbData;
+
diff --git a/arm-hybrid-22k/lib_src/eas_reverbdata.h b/arm-hybrid-22k/lib_src/eas_reverbdata.h
index ef424da..926ea2e 100644
--- a/arm-hybrid-22k/lib_src/eas_reverbdata.h
+++ b/arm-hybrid-22k/lib_src/eas_reverbdata.h
@@ -1,13 +1,13 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_reverbdata.h
- *
- * Contents and purpose:
- * Contains the prototypes for the Reverb effect.
- *
- *
- * Copyright Sonic Network Inc. 2006
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_reverbdata.h
+ *
+ * Contents and purpose:
+ * Contains the prototypes for the Reverb effect.
+ *
+ *
+ * Copyright Sonic Network Inc. 2006
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,467 +20,467 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 499 $
- * $Date: 2006-12-11 16:07:20 -0800 (Mon, 11 Dec 2006) $
- *----------------------------------------------------------------------------
-*/
-
-#ifndef _EAS_REVERBDATA_H
-#define _EAS_REVERBDATA_H
-
-#include "eas_types.h"
-#include "eas_audioconst.h"
-
-/*------------------------------------
- * defines
- *------------------------------------
-*/
-
-/*
-CIRCULAR() calculates the array index using modulo arithmetic.
-The "trick" is that modulo arithmetic is simplified by masking
-the effective address where the mask is (2^n)-1. This only works
-if the buffer size is a power of two.
-*/
-#define CIRCULAR(base,offset,size) (EAS_U32)( \
- ( \
- ((EAS_I32)(base)) + ((EAS_I32)(offset)) \
- ) \
- & size \
- )
-
-/* reverb parameters are updated every 2^(REVERB_UPDATE_PERIOD_IN_BITS) samples */
-#if defined (_SAMPLE_RATE_8000)
-
-#define REVERB_UPDATE_PERIOD_IN_BITS 5
-#define REVERB_BUFFER_SIZE_IN_SAMPLES 2048
-
-#elif defined (_SAMPLE_RATE_16000)
-
-#define REVERB_UPDATE_PERIOD_IN_BITS 6
-#define REVERB_BUFFER_SIZE_IN_SAMPLES 4096
-
-#elif defined (_SAMPLE_RATE_22050)
-
-#define REVERB_UPDATE_PERIOD_IN_BITS 7
-#define REVERB_BUFFER_SIZE_IN_SAMPLES 4096
-
-#elif defined (_SAMPLE_RATE_32000)
-
-#define REVERB_UPDATE_PERIOD_IN_BITS 7
-#define REVERB_BUFFER_SIZE_IN_SAMPLES 8192
-
-#elif defined (_SAMPLE_RATE_44100)
-
-#define REVERB_UPDATE_PERIOD_IN_BITS 8
-#define REVERB_BUFFER_SIZE_IN_SAMPLES 8192
-
-#elif defined (_SAMPLE_RATE_48000)
-
-#define REVERB_UPDATE_PERIOD_IN_BITS 8
-#define REVERB_BUFFER_SIZE_IN_SAMPLES 8192
-
-#endif
-
-// Define a mask for circular addressing, so that array index
-// can wraparound and stay in array boundary of 0, 1, ..., (buffer size -1)
-// The buffer size MUST be a power of two
-#define REVERB_BUFFER_MASK (REVERB_BUFFER_SIZE_IN_SAMPLES -1)
-
-#define REVERB_MAX_ROOM_TYPE 4 // any room numbers larger than this are invalid
-#define REVERB_MAX_NUM_REFLECTIONS 5 // max num reflections per channel
-
-/* synth parameters are updated every SYNTH_UPDATE_PERIOD_IN_SAMPLES */
-#define REVERB_UPDATE_PERIOD_IN_SAMPLES (EAS_I32)(0x1L << REVERB_UPDATE_PERIOD_IN_BITS)
-
-/*
-calculate the update counter by bitwise ANDING with this value to
-generate a 2^n modulo value
-*/
-#define REVERB_MODULO_UPDATE_PERIOD_IN_SAMPLES (EAS_I32)(REVERB_UPDATE_PERIOD_IN_SAMPLES -1)
-
-/* synth parameters are updated every SYNTH_UPDATE_PERIOD_IN_SECONDS seconds */
-#define REVERB_UPDATE_PERIOD_IN_SECONDS (REVERB_UPDATE_PERIOD_IN_SAMPLES / _OUTPUT_SAMPLE_RATE)
-
-// xfade parameters
-#define REVERB_XFADE_PERIOD_IN_SECONDS (100.0 / 1000.0) // xfade once every this many seconds
-
-#define REVERB_XFADE_PERIOD_IN_SAMPLES (REVERB_XFADE_PERIOD_IN_SECONDS * _OUTPUT_SAMPLE_RATE)
-
-#define REVERB_XFADE_PHASE_INCREMENT (EAS_I16)(65536 / ((EAS_I16)REVERB_XFADE_PERIOD_IN_SAMPLES/(EAS_I16)REVERB_UPDATE_PERIOD_IN_SAMPLES))
-
-/**********/
-/* the entire synth uses various flags in a bit field */
-
-/* if flag is set, synth reset has been requested */
-#define REVERB_FLAG_RESET_IS_REQUESTED 0x01 /* bit 0 */
-#define MASK_REVERB_RESET_IS_REQUESTED 0x01
-#define MASK_REVERB_RESET_IS_NOT_REQUESTED (EAS_U32)(~MASK_REVERB_RESET_IS_REQUESTED)
-
-/*
-by default, we always want to update ALL channel parameters
-when we reset the synth (e.g., during GM ON)
-*/
-#define DEFAULT_REVERB_FLAGS 0x0
-
-/* coefficients for generating sin, cos */
-#define REVERB_PAN_G2 4294940151 /* -0.82842712474619 = 2 - 4/sqrt(2) */
-/*
-EAS_I32 nPanG1 = +1.0 for sin
-EAS_I32 nPanG1 = -1.0 for cos
-*/
-#define REVERB_PAN_G0 23170 /* 0.707106781186547 = 1/sqrt(2) */
-
-/*************************************************************/
-// define the input injection points
-#define GUARD 5 // safety guard of this many samples
-
-#define MAX_AP_TIME (double) (20.0/1000.0) // delay time in milliseconds
-#define MAX_DELAY_TIME (double) (65.0/1000.0) // delay time in milliseconds
-
-#define MAX_AP_SAMPLES (int)(((double) MAX_AP_TIME) * ((double) _OUTPUT_SAMPLE_RATE))
-#define MAX_DELAY_SAMPLES (int)(((double) MAX_DELAY_TIME) * ((double) _OUTPUT_SAMPLE_RATE))
-
-#define AP0_IN 0
-#define AP1_IN (AP0_IN + MAX_AP_SAMPLES + GUARD)
-#define DELAY0_IN (AP1_IN + MAX_AP_SAMPLES + GUARD)
-#define DELAY1_IN (DELAY0_IN + MAX_DELAY_SAMPLES + GUARD)
-
-// Define the max offsets for the end points of each section
-// i.e., we don't expect a given section's taps to go beyond
-// the following limits
-#define AP0_OUT (AP0_IN + MAX_AP_SAMPLES -1)
-#define AP1_OUT (AP1_IN + MAX_AP_SAMPLES -1)
-#define DELAY0_OUT (DELAY0_IN + MAX_DELAY_SAMPLES -1)
-#define DELAY1_OUT (DELAY1_IN + MAX_DELAY_SAMPLES -1)
-
-#define REVERB_DEFAULT_ROOM_NUMBER 1 // default preset number
-#define DEFAULT_AP0_LENGTH (int)(((double) (17.0/1000.0)) * ((double) _OUTPUT_SAMPLE_RATE))
-#define DEFAULT_AP0_GAIN 19400
-#define DEFAULT_AP1_LENGTH (int)(((double) (16.5/1000.0)) * ((double) _OUTPUT_SAMPLE_RATE))
-#define DEFAULT_AP1_GAIN -19400
-
-#define REVERB_DEFAULT_WET 32767
-#define REVERB_DEFAULT_DRY 0
-
-#define EAS_REVERB_WET_MAX 32767
-#define EAS_REVERB_WET_MIN 0
-#define EAS_REVERB_DRY_MAX 32767
-#define EAS_REVERB_DRY_MIN 0
-
-/* parameters for each allpass */
-typedef struct
-{
- EAS_U16 m_zApOut; // delay offset for ap out
-
- EAS_I16 m_nApGain; // gain for ap
-
- EAS_U16 m_zApIn; // delay offset for ap in
-
-} S_ALLPASS_OBJECT;
-
-
-/* parameters for each allpass */
-typedef struct
-{
- EAS_PCM m_zLpf; // actual state variable, not a length
-
- EAS_I16 m_nLpfFwd; // lpf forward gain
-
- EAS_I16 m_nLpfFbk; // lpf feedback gain
-
- EAS_U16 m_zDelay[REVERB_MAX_NUM_REFLECTIONS]; // delay offset for ap out
-
- EAS_I16 m_nGain[REVERB_MAX_NUM_REFLECTIONS]; // gain for ap
-
-} S_EARLY_REFLECTION_OBJECT;
-
-//demo
-typedef struct
-{
- EAS_I16 m_nLpfFbk;
- EAS_I16 m_nLpfFwd;
-
- EAS_I16 m_nEarly;
- EAS_I16 m_nWet;
- EAS_I16 m_nDry;
-
- EAS_I16 m_nEarlyL_LpfFbk;
- EAS_I16 m_nEarlyL_LpfFwd;
-
- EAS_I16 m_nEarlyL_Delay0; //8
- EAS_I16 m_nEarlyL_Gain0;
- EAS_I16 m_nEarlyL_Delay1;
- EAS_I16 m_nEarlyL_Gain1;
- EAS_I16 m_nEarlyL_Delay2;
- EAS_I16 m_nEarlyL_Gain2;
- EAS_I16 m_nEarlyL_Delay3;
- EAS_I16 m_nEarlyL_Gain3;
- EAS_I16 m_nEarlyL_Delay4;
- EAS_I16 m_nEarlyL_Gain4;
-
- EAS_I16 m_nEarlyR_Delay0; //18
- EAS_I16 m_nEarlyR_Gain0;
- EAS_I16 m_nEarlyR_Delay1;
- EAS_I16 m_nEarlyR_Gain1;
- EAS_I16 m_nEarlyR_Delay2;
- EAS_I16 m_nEarlyR_Gain2;
- EAS_I16 m_nEarlyR_Delay3;
- EAS_I16 m_nEarlyR_Gain3;
- EAS_I16 m_nEarlyR_Delay4;
- EAS_I16 m_nEarlyR_Gain4;
-
- EAS_U16 m_nMaxExcursion; //28
- EAS_I16 m_nXfadeInterval;
-
- EAS_I16 m_nAp0_ApGain; //30
- EAS_I16 m_nAp0_ApOut;
- EAS_I16 m_nAp1_ApGain;
- EAS_I16 m_nAp1_ApOut;
-
- EAS_I16 m_rfu4;
- EAS_I16 m_rfu5;
- EAS_I16 m_rfu6;
- EAS_I16 m_rfu7;
- EAS_I16 m_rfu8;
- EAS_I16 m_rfu9;
- EAS_I16 m_rfu10; //43
-
-} S_REVERB_PRESET;
-
-typedef struct
-{
- S_REVERB_PRESET m_sPreset[REVERB_MAX_ROOM_TYPE]; //array of presets
-
-} S_REVERB_PRESET_BANK;
-
-/* parameters for each reverb */
-typedef struct
-{
- /* controls entire reverb playback volume */
- /* to conserve memory, use the MSB and ignore the LSB */
- EAS_U8 m_nMasterVolume;
-
- /* update counter keeps track of when synth params need updating */
- /* only needs to be as large as REVERB_UPDATE_PERIOD_IN_SAMPLES */
- EAS_I16 m_nUpdateCounter;
-
- EAS_U16 m_nMinSamplesToAdd; /* ComputeReverb() generates this many samples */
-
- EAS_U8 m_nFlags; /* misc flags/bit fields */
-
- EAS_PCM *m_pOutputBuffer;
- EAS_PCM *m_pInputBuffer;
-
- EAS_U16 m_nNumSamplesInOutputBuffer;
- EAS_U16 m_nNumSamplesInInputBuffer;
-
- EAS_U16 m_nNumInputSamplesRead; // if m_nNumInputSamplesRead >= NumSamplesInInputBuffer
- // then get a new input buffer
- EAS_PCM *m_pNextInputSample;
-
- EAS_U16 m_nBaseIndex; // base index for circular buffer
-
- // reverb delay line offsets, allpass parameters, etc:
-
- EAS_PCM m_nRevOutFbkR; // combine feedback reverb right out with dry left in
-
- S_ALLPASS_OBJECT m_sAp0; // allpass 0 (left channel)
-
- EAS_U16 m_zD0In; // delay offset for delay line D0 in
-
- EAS_PCM m_nRevOutFbkL; // combine feedback reverb left out with dry right in
-
- S_ALLPASS_OBJECT m_sAp1; // allpass 1 (right channel)
-
- EAS_U16 m_zD1In; // delay offset for delay line D1 in
-
- // delay output taps, notice criss cross order
- EAS_U16 m_zD0Self; // self feeds forward d0 --> d0
-
- EAS_U16 m_zD1Cross; // cross feeds across d1 --> d0
-
- EAS_PCM m_zLpf0; // actual state variable, not a length
-
- EAS_U16 m_zD1Self; // self feeds forward d1 --> d1
-
- EAS_U16 m_zD0Cross; // cross feeds across d0 --> d1
-
- EAS_PCM m_zLpf1; // actual state variable, not a length
-
- EAS_I16 m_nSin; // gain for self taps
-
- EAS_I16 m_nCos; // gain for cross taps
-
- EAS_I16 m_nSinIncrement; // increment for gain
-
- EAS_I16 m_nCosIncrement; // increment for gain
-
- EAS_I16 m_nLpfFwd; // lpf forward gain (includes scaling for mixer)
-
- EAS_I16 m_nLpfFbk; // lpf feedback gain
-
- EAS_U16 m_nXfadeInterval; // update/xfade after this many samples
-
- EAS_U16 m_nXfadeCounter; // keep track of when to xfade
-
- EAS_I16 m_nPhase; // -1 <= m_nPhase < 1
- // but during sin,cos calculations
- // use m_nPhase/2
-
- EAS_I16 m_nPhaseIncrement; // add this to m_nPhase each frame
-
- EAS_I16 m_nNoise; // random noise sample
-
- EAS_U16 m_nMaxExcursion; // the taps can excurse +/- this amount
-
- EAS_BOOL m_bUseNoise; // if EAS_TRUE, use noise as input signal
-
- EAS_BOOL m_bBypass; // if EAS_TRUE, then bypass reverb and copy input to output
-
- EAS_I16 m_nCurrentRoom; // preset number for current room
-
- EAS_I16 m_nNextRoom; // preset number for next room
-
- EAS_I16 m_nWet; // gain for wet (processed) signal
-
- EAS_I16 m_nDry; // gain for dry (unprocessed) signal
-
- EAS_I16 m_nEarly; // gain for early (widen) signal
-
- S_EARLY_REFLECTION_OBJECT m_sEarlyL; // left channel early reflections
- S_EARLY_REFLECTION_OBJECT m_sEarlyR; // right channel early reflections
-
- EAS_PCM m_nDelayLine[REVERB_BUFFER_SIZE_IN_SAMPLES]; // one large delay line for all reverb elements
-
- S_REVERB_PRESET pPreset;
-
- S_REVERB_PRESET_BANK m_sPreset;
-
- //EAS_I8 preset;
-
-} S_REVERB_OBJECT;
-
-
-/*------------------------------------
- * prototypes
- *------------------------------------
-*/
-
-/*----------------------------------------------------------------------------
- * ReverbUpdateXfade
- *----------------------------------------------------------------------------
- * Purpose:
- * Update the xfade parameters as required
- *
- * Inputs:
- * nNumSamplesToAdd - number of samples to write to buffer
- *
- * Outputs:
- *
- *
- * Side Effects:
- * - xfade parameters will be changed
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT ReverbUpdateXfade(S_REVERB_OBJECT* pReverbData, EAS_INT nNumSamplesToAdd);
-
-/*----------------------------------------------------------------------------
- * ReverbCalculateNoise
- *----------------------------------------------------------------------------
- * Purpose:
- * Calculate a noise sample and limit its value
- *
- * Inputs:
- * nMaxExcursion - noise value is limited to this value
- * pnNoise - return new noise sample in this (not limited)
- *
- * Outputs:
- * new limited noise value
- *
- * Side Effects:
- * - *pnNoise noise value is updated
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_U16 ReverbCalculateNoise(EAS_U16 nMaxExcursion, EAS_I16 *pnNoise);
-
-/*----------------------------------------------------------------------------
- * ReverbCalculateSinCos
- *----------------------------------------------------------------------------
- * Purpose:
- * Calculate a new sin and cosine value based on the given phase
- *
- * Inputs:
- * nPhase - phase angle
- * pnSin - input old value, output new value
- * pnCos - input old value, output new value
- *
- * Outputs:
- *
- * Side Effects:
- * - *pnSin, *pnCos are updated
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT ReverbCalculateSinCos(EAS_I16 nPhase, EAS_I16 *pnSin, EAS_I16 *pnCos);
-
-/*----------------------------------------------------------------------------
- * Reverb
- *----------------------------------------------------------------------------
- * Purpose:
- * apply reverb to the given signal
- *
- * Inputs:
- * nNu
- * pnSin - input old value, output new value
- * pnCos - input old value, output new value
- *
- * Outputs:
- * number of samples actually reverberated
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT Reverb(S_REVERB_OBJECT* pReverbData, EAS_INT nNumSamplesToAdd, EAS_PCM *pOutputBuffer, EAS_PCM *pInputBuffer);
-
-/*----------------------------------------------------------------------------
- * ReverbReadInPresets()
- *----------------------------------------------------------------------------
- * Purpose: sets global reverb preset bank to defaults
- *
- * Inputs:
- *
- * Outputs:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT ReverbReadInPresets(S_REVERB_OBJECT* pReverbData);
-
-
-/*----------------------------------------------------------------------------
- * ReverbUpdateRoom
- *----------------------------------------------------------------------------
- * Purpose:
- * Update the room's preset parameters as required
- *
- * Inputs:
- *
- * Outputs:
- *
- *
- * Side Effects:
- * - reverb paramters (fbk, fwd, etc) will be changed
- * - m_nCurrentRoom := m_nNextRoom
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT ReverbUpdateRoom(S_REVERB_OBJECT* pReverbData);
-
-#endif /* #ifndef _EAS_REVERBDATA_H */
-
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 499 $
+ * $Date: 2006-12-11 16:07:20 -0800 (Mon, 11 Dec 2006) $
+ *----------------------------------------------------------------------------
+*/
+
+#ifndef _EAS_REVERBDATA_H
+#define _EAS_REVERBDATA_H
+
+#include "eas_types.h"
+#include "eas_audioconst.h"
+
+/*------------------------------------
+ * defines
+ *------------------------------------
+*/
+
+/*
+CIRCULAR() calculates the array index using modulo arithmetic.
+The "trick" is that modulo arithmetic is simplified by masking
+the effective address where the mask is (2^n)-1. This only works
+if the buffer size is a power of two.
+*/
+#define CIRCULAR(base,offset,size) (EAS_U32)( \
+ ( \
+ ((EAS_I32)(base)) + ((EAS_I32)(offset)) \
+ ) \
+ & size \
+ )
+
+/* reverb parameters are updated every 2^(REVERB_UPDATE_PERIOD_IN_BITS) samples */
+#if defined (_SAMPLE_RATE_8000)
+
+#define REVERB_UPDATE_PERIOD_IN_BITS 5
+#define REVERB_BUFFER_SIZE_IN_SAMPLES 2048
+
+#elif defined (_SAMPLE_RATE_16000)
+
+#define REVERB_UPDATE_PERIOD_IN_BITS 6
+#define REVERB_BUFFER_SIZE_IN_SAMPLES 4096
+
+#elif defined (_SAMPLE_RATE_22050)
+
+#define REVERB_UPDATE_PERIOD_IN_BITS 7
+#define REVERB_BUFFER_SIZE_IN_SAMPLES 4096
+
+#elif defined (_SAMPLE_RATE_32000)
+
+#define REVERB_UPDATE_PERIOD_IN_BITS 7
+#define REVERB_BUFFER_SIZE_IN_SAMPLES 8192
+
+#elif defined (_SAMPLE_RATE_44100)
+
+#define REVERB_UPDATE_PERIOD_IN_BITS 8
+#define REVERB_BUFFER_SIZE_IN_SAMPLES 8192
+
+#elif defined (_SAMPLE_RATE_48000)
+
+#define REVERB_UPDATE_PERIOD_IN_BITS 8
+#define REVERB_BUFFER_SIZE_IN_SAMPLES 8192
+
+#endif
+
+// Define a mask for circular addressing, so that array index
+// can wraparound and stay in array boundary of 0, 1, ..., (buffer size -1)
+// The buffer size MUST be a power of two
+#define REVERB_BUFFER_MASK (REVERB_BUFFER_SIZE_IN_SAMPLES -1)
+
+#define REVERB_MAX_ROOM_TYPE 4 // any room numbers larger than this are invalid
+#define REVERB_MAX_NUM_REFLECTIONS 5 // max num reflections per channel
+
+/* synth parameters are updated every SYNTH_UPDATE_PERIOD_IN_SAMPLES */
+#define REVERB_UPDATE_PERIOD_IN_SAMPLES (EAS_I32)(0x1L << REVERB_UPDATE_PERIOD_IN_BITS)
+
+/*
+calculate the update counter by bitwise ANDING with this value to
+generate a 2^n modulo value
+*/
+#define REVERB_MODULO_UPDATE_PERIOD_IN_SAMPLES (EAS_I32)(REVERB_UPDATE_PERIOD_IN_SAMPLES -1)
+
+/* synth parameters are updated every SYNTH_UPDATE_PERIOD_IN_SECONDS seconds */
+#define REVERB_UPDATE_PERIOD_IN_SECONDS (REVERB_UPDATE_PERIOD_IN_SAMPLES / _OUTPUT_SAMPLE_RATE)
+
+// xfade parameters
+#define REVERB_XFADE_PERIOD_IN_SECONDS (100.0 / 1000.0) // xfade once every this many seconds
+
+#define REVERB_XFADE_PERIOD_IN_SAMPLES (REVERB_XFADE_PERIOD_IN_SECONDS * _OUTPUT_SAMPLE_RATE)
+
+#define REVERB_XFADE_PHASE_INCREMENT (EAS_I16)(65536 / ((EAS_I16)REVERB_XFADE_PERIOD_IN_SAMPLES/(EAS_I16)REVERB_UPDATE_PERIOD_IN_SAMPLES))
+
+/**********/
+/* the entire synth uses various flags in a bit field */
+
+/* if flag is set, synth reset has been requested */
+#define REVERB_FLAG_RESET_IS_REQUESTED 0x01 /* bit 0 */
+#define MASK_REVERB_RESET_IS_REQUESTED 0x01
+#define MASK_REVERB_RESET_IS_NOT_REQUESTED (EAS_U32)(~MASK_REVERB_RESET_IS_REQUESTED)
+
+/*
+by default, we always want to update ALL channel parameters
+when we reset the synth (e.g., during GM ON)
+*/
+#define DEFAULT_REVERB_FLAGS 0x0
+
+/* coefficients for generating sin, cos */
+#define REVERB_PAN_G2 4294940151 /* -0.82842712474619 = 2 - 4/sqrt(2) */
+/*
+EAS_I32 nPanG1 = +1.0 for sin
+EAS_I32 nPanG1 = -1.0 for cos
+*/
+#define REVERB_PAN_G0 23170 /* 0.707106781186547 = 1/sqrt(2) */
+
+/*************************************************************/
+// define the input injection points
+#define GUARD 5 // safety guard of this many samples
+
+#define MAX_AP_TIME (double) (20.0/1000.0) // delay time in milliseconds
+#define MAX_DELAY_TIME (double) (65.0/1000.0) // delay time in milliseconds
+
+#define MAX_AP_SAMPLES (int)(((double) MAX_AP_TIME) * ((double) _OUTPUT_SAMPLE_RATE))
+#define MAX_DELAY_SAMPLES (int)(((double) MAX_DELAY_TIME) * ((double) _OUTPUT_SAMPLE_RATE))
+
+#define AP0_IN 0
+#define AP1_IN (AP0_IN + MAX_AP_SAMPLES + GUARD)
+#define DELAY0_IN (AP1_IN + MAX_AP_SAMPLES + GUARD)
+#define DELAY1_IN (DELAY0_IN + MAX_DELAY_SAMPLES + GUARD)
+
+// Define the max offsets for the end points of each section
+// i.e., we don't expect a given section's taps to go beyond
+// the following limits
+#define AP0_OUT (AP0_IN + MAX_AP_SAMPLES -1)
+#define AP1_OUT (AP1_IN + MAX_AP_SAMPLES -1)
+#define DELAY0_OUT (DELAY0_IN + MAX_DELAY_SAMPLES -1)
+#define DELAY1_OUT (DELAY1_IN + MAX_DELAY_SAMPLES -1)
+
+#define REVERB_DEFAULT_ROOM_NUMBER 1 // default preset number
+#define DEFAULT_AP0_LENGTH (int)(((double) (17.0/1000.0)) * ((double) _OUTPUT_SAMPLE_RATE))
+#define DEFAULT_AP0_GAIN 19400
+#define DEFAULT_AP1_LENGTH (int)(((double) (16.5/1000.0)) * ((double) _OUTPUT_SAMPLE_RATE))
+#define DEFAULT_AP1_GAIN -19400
+
+#define REVERB_DEFAULT_WET 32767
+#define REVERB_DEFAULT_DRY 0
+
+#define EAS_REVERB_WET_MAX 32767
+#define EAS_REVERB_WET_MIN 0
+#define EAS_REVERB_DRY_MAX 32767
+#define EAS_REVERB_DRY_MIN 0
+
+/* parameters for each allpass */
+typedef struct
+{
+ EAS_U16 m_zApOut; // delay offset for ap out
+
+ EAS_I16 m_nApGain; // gain for ap
+
+ EAS_U16 m_zApIn; // delay offset for ap in
+
+} S_ALLPASS_OBJECT;
+
+
+/* parameters for each allpass */
+typedef struct
+{
+ EAS_PCM m_zLpf; // actual state variable, not a length
+
+ EAS_I16 m_nLpfFwd; // lpf forward gain
+
+ EAS_I16 m_nLpfFbk; // lpf feedback gain
+
+ EAS_U16 m_zDelay[REVERB_MAX_NUM_REFLECTIONS]; // delay offset for ap out
+
+ EAS_I16 m_nGain[REVERB_MAX_NUM_REFLECTIONS]; // gain for ap
+
+} S_EARLY_REFLECTION_OBJECT;
+
+//demo
+typedef struct
+{
+ EAS_I16 m_nLpfFbk;
+ EAS_I16 m_nLpfFwd;
+
+ EAS_I16 m_nEarly;
+ EAS_I16 m_nWet;
+ EAS_I16 m_nDry;
+
+ EAS_I16 m_nEarlyL_LpfFbk;
+ EAS_I16 m_nEarlyL_LpfFwd;
+
+ EAS_I16 m_nEarlyL_Delay0; //8
+ EAS_I16 m_nEarlyL_Gain0;
+ EAS_I16 m_nEarlyL_Delay1;
+ EAS_I16 m_nEarlyL_Gain1;
+ EAS_I16 m_nEarlyL_Delay2;
+ EAS_I16 m_nEarlyL_Gain2;
+ EAS_I16 m_nEarlyL_Delay3;
+ EAS_I16 m_nEarlyL_Gain3;
+ EAS_I16 m_nEarlyL_Delay4;
+ EAS_I16 m_nEarlyL_Gain4;
+
+ EAS_I16 m_nEarlyR_Delay0; //18
+ EAS_I16 m_nEarlyR_Gain0;
+ EAS_I16 m_nEarlyR_Delay1;
+ EAS_I16 m_nEarlyR_Gain1;
+ EAS_I16 m_nEarlyR_Delay2;
+ EAS_I16 m_nEarlyR_Gain2;
+ EAS_I16 m_nEarlyR_Delay3;
+ EAS_I16 m_nEarlyR_Gain3;
+ EAS_I16 m_nEarlyR_Delay4;
+ EAS_I16 m_nEarlyR_Gain4;
+
+ EAS_U16 m_nMaxExcursion; //28
+ EAS_I16 m_nXfadeInterval;
+
+ EAS_I16 m_nAp0_ApGain; //30
+ EAS_I16 m_nAp0_ApOut;
+ EAS_I16 m_nAp1_ApGain;
+ EAS_I16 m_nAp1_ApOut;
+
+ EAS_I16 m_rfu4;
+ EAS_I16 m_rfu5;
+ EAS_I16 m_rfu6;
+ EAS_I16 m_rfu7;
+ EAS_I16 m_rfu8;
+ EAS_I16 m_rfu9;
+ EAS_I16 m_rfu10; //43
+
+} S_REVERB_PRESET;
+
+typedef struct
+{
+ S_REVERB_PRESET m_sPreset[REVERB_MAX_ROOM_TYPE]; //array of presets
+
+} S_REVERB_PRESET_BANK;
+
+/* parameters for each reverb */
+typedef struct
+{
+ /* controls entire reverb playback volume */
+ /* to conserve memory, use the MSB and ignore the LSB */
+ EAS_U8 m_nMasterVolume;
+
+ /* update counter keeps track of when synth params need updating */
+ /* only needs to be as large as REVERB_UPDATE_PERIOD_IN_SAMPLES */
+ EAS_I16 m_nUpdateCounter;
+
+ EAS_U16 m_nMinSamplesToAdd; /* ComputeReverb() generates this many samples */
+
+ EAS_U8 m_nFlags; /* misc flags/bit fields */
+
+ EAS_PCM *m_pOutputBuffer;
+ EAS_PCM *m_pInputBuffer;
+
+ EAS_U16 m_nNumSamplesInOutputBuffer;
+ EAS_U16 m_nNumSamplesInInputBuffer;
+
+ EAS_U16 m_nNumInputSamplesRead; // if m_nNumInputSamplesRead >= NumSamplesInInputBuffer
+ // then get a new input buffer
+ EAS_PCM *m_pNextInputSample;
+
+ EAS_U16 m_nBaseIndex; // base index for circular buffer
+
+ // reverb delay line offsets, allpass parameters, etc:
+
+ EAS_PCM m_nRevOutFbkR; // combine feedback reverb right out with dry left in
+
+ S_ALLPASS_OBJECT m_sAp0; // allpass 0 (left channel)
+
+ EAS_U16 m_zD0In; // delay offset for delay line D0 in
+
+ EAS_PCM m_nRevOutFbkL; // combine feedback reverb left out with dry right in
+
+ S_ALLPASS_OBJECT m_sAp1; // allpass 1 (right channel)
+
+ EAS_U16 m_zD1In; // delay offset for delay line D1 in
+
+ // delay output taps, notice criss cross order
+ EAS_U16 m_zD0Self; // self feeds forward d0 --> d0
+
+ EAS_U16 m_zD1Cross; // cross feeds across d1 --> d0
+
+ EAS_PCM m_zLpf0; // actual state variable, not a length
+
+ EAS_U16 m_zD1Self; // self feeds forward d1 --> d1
+
+ EAS_U16 m_zD0Cross; // cross feeds across d0 --> d1
+
+ EAS_PCM m_zLpf1; // actual state variable, not a length
+
+ EAS_I16 m_nSin; // gain for self taps
+
+ EAS_I16 m_nCos; // gain for cross taps
+
+ EAS_I16 m_nSinIncrement; // increment for gain
+
+ EAS_I16 m_nCosIncrement; // increment for gain
+
+ EAS_I16 m_nLpfFwd; // lpf forward gain (includes scaling for mixer)
+
+ EAS_I16 m_nLpfFbk; // lpf feedback gain
+
+ EAS_U16 m_nXfadeInterval; // update/xfade after this many samples
+
+ EAS_U16 m_nXfadeCounter; // keep track of when to xfade
+
+ EAS_I16 m_nPhase; // -1 <= m_nPhase < 1
+ // but during sin,cos calculations
+ // use m_nPhase/2
+
+ EAS_I16 m_nPhaseIncrement; // add this to m_nPhase each frame
+
+ EAS_I16 m_nNoise; // random noise sample
+
+ EAS_U16 m_nMaxExcursion; // the taps can excurse +/- this amount
+
+ EAS_BOOL m_bUseNoise; // if EAS_TRUE, use noise as input signal
+
+ EAS_BOOL m_bBypass; // if EAS_TRUE, then bypass reverb and copy input to output
+
+ EAS_I16 m_nCurrentRoom; // preset number for current room
+
+ EAS_I16 m_nNextRoom; // preset number for next room
+
+ EAS_I16 m_nWet; // gain for wet (processed) signal
+
+ EAS_I16 m_nDry; // gain for dry (unprocessed) signal
+
+ EAS_I16 m_nEarly; // gain for early (widen) signal
+
+ S_EARLY_REFLECTION_OBJECT m_sEarlyL; // left channel early reflections
+ S_EARLY_REFLECTION_OBJECT m_sEarlyR; // right channel early reflections
+
+ EAS_PCM m_nDelayLine[REVERB_BUFFER_SIZE_IN_SAMPLES]; // one large delay line for all reverb elements
+
+ S_REVERB_PRESET pPreset;
+
+ S_REVERB_PRESET_BANK m_sPreset;
+
+ //EAS_I8 preset;
+
+} S_REVERB_OBJECT;
+
+
+/*------------------------------------
+ * prototypes
+ *------------------------------------
+*/
+
+/*----------------------------------------------------------------------------
+ * ReverbUpdateXfade
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Update the xfade parameters as required
+ *
+ * Inputs:
+ * nNumSamplesToAdd - number of samples to write to buffer
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ * - xfade parameters will be changed
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT ReverbUpdateXfade(S_REVERB_OBJECT* pReverbData, EAS_INT nNumSamplesToAdd);
+
+/*----------------------------------------------------------------------------
+ * ReverbCalculateNoise
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Calculate a noise sample and limit its value
+ *
+ * Inputs:
+ * nMaxExcursion - noise value is limited to this value
+ * pnNoise - return new noise sample in this (not limited)
+ *
+ * Outputs:
+ * new limited noise value
+ *
+ * Side Effects:
+ * - *pnNoise noise value is updated
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_U16 ReverbCalculateNoise(EAS_U16 nMaxExcursion, EAS_I16 *pnNoise);
+
+/*----------------------------------------------------------------------------
+ * ReverbCalculateSinCos
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Calculate a new sin and cosine value based on the given phase
+ *
+ * Inputs:
+ * nPhase - phase angle
+ * pnSin - input old value, output new value
+ * pnCos - input old value, output new value
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ * - *pnSin, *pnCos are updated
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT ReverbCalculateSinCos(EAS_I16 nPhase, EAS_I16 *pnSin, EAS_I16 *pnCos);
+
+/*----------------------------------------------------------------------------
+ * Reverb
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * apply reverb to the given signal
+ *
+ * Inputs:
+ * nNu
+ * pnSin - input old value, output new value
+ * pnCos - input old value, output new value
+ *
+ * Outputs:
+ * number of samples actually reverberated
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT Reverb(S_REVERB_OBJECT* pReverbData, EAS_INT nNumSamplesToAdd, EAS_PCM *pOutputBuffer, EAS_PCM *pInputBuffer);
+
+/*----------------------------------------------------------------------------
+ * ReverbReadInPresets()
+ *----------------------------------------------------------------------------
+ * Purpose: sets global reverb preset bank to defaults
+ *
+ * Inputs:
+ *
+ * Outputs:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT ReverbReadInPresets(S_REVERB_OBJECT* pReverbData);
+
+
+/*----------------------------------------------------------------------------
+ * ReverbUpdateRoom
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Update the room's preset parameters as required
+ *
+ * Inputs:
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ * - reverb paramters (fbk, fwd, etc) will be changed
+ * - m_nCurrentRoom := m_nNextRoom
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT ReverbUpdateRoom(S_REVERB_OBJECT* pReverbData);
+
+#endif /* #ifndef _EAS_REVERBDATA_H */
+
+
diff --git a/arm-hybrid-22k/lib_src/eas_rtttl.c b/arm-hybrid-22k/lib_src/eas_rtttl.c
index 486ad60..d8253fb 100644
--- a/arm-hybrid-22k/lib_src/eas_rtttl.c
+++ b/arm-hybrid-22k/lib_src/eas_rtttl.c
@@ -1,12 +1,12 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_rtttl.c
- *
- * Contents and purpose:
- * RTTTL parser
- *
- * Copyright Sonic Network Inc. 2005
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_rtttl.c
+ *
+ * Contents and purpose:
+ * RTTTL parser
+ *
+ * Copyright Sonic Network Inc. 2005
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,1179 +19,1179 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 795 $
- * $Date: 2007-08-01 00:14:45 -0700 (Wed, 01 Aug 2007) $
- *----------------------------------------------------------------------------
-*/
-
-#include "eas_data.h"
-#include "eas_miditypes.h"
-#include "eas_parser.h"
-#include "eas_report.h"
-#include "eas_host.h"
-#include "eas_midi.h"
-#include "eas_config.h"
-#include "eas_vm_protos.h"
-#include "eas_rtttldata.h"
-#include "eas_ctype.h"
-
-/* increase gain for mono ringtones */
-#define RTTTL_GAIN_OFFSET 8
-
-/* maximum title length including colon separator */
-#define RTTTL_MAX_TITLE_LEN 32
-#define RTTTL_INFINITE_LOOP 15
-
-/* length of 32nd note in 1/256ths of a msec for 63 BPM tempo */
-#define DEFAULT_TICK_CONV 30476
-#define TICK_CONVERT 1920000
-
-/* default channel and program for RTTTL playback */
-#define RTTTL_CHANNEL 0
-#define RTTTL_PROGRAM 80
-#define RTTTL_VELOCITY 127
-
-/* note used for rest */
-#define RTTTL_REST 1
-
-/* multiplier for fixed point triplet conversion */
-#define TRIPLET_MULTIPLIER 683
-#define TRIPLET_SHIFT 10
-
-/* local prototypes */
-static EAS_RESULT RTTTL_CheckFileType (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle, EAS_VOID_PTR *ppHandle, EAS_I32 offset);
-static EAS_RESULT RTTTL_Prepare (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
-static EAS_RESULT RTTTL_Time (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_U32 *pTime);
-static EAS_RESULT RTTTL_Event (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_INT parserMode);
-static EAS_RESULT RTTTL_State (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_STATE *pState);
-static EAS_RESULT RTTTL_Close (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
-static EAS_RESULT RTTTL_Reset (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
-static EAS_RESULT RTTTL_Pause (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
-static EAS_RESULT RTTTL_Resume (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
-static EAS_RESULT RTTTL_SetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value);
-static EAS_RESULT RTTTL_GetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue);
-static EAS_RESULT RTTTL_GetStyle (EAS_HW_DATA_HANDLE hwInstData, S_RTTTL_DATA *pData);
-static EAS_RESULT RTTTL_GetDuration (EAS_HW_DATA_HANDLE hwInstData, S_RTTTL_DATA *pData, EAS_I8 *pDuration);
-static EAS_RESULT RTTTL_GetOctave (EAS_HW_DATA_HANDLE hwInstData, S_RTTTL_DATA *pData, EAS_U8 *pOctave);
-static EAS_RESULT RTTTL_GetTempo (EAS_HW_DATA_HANDLE hwInstData, S_RTTTL_DATA *pData);
-static EAS_RESULT RTTTL_GetNumber (EAS_HW_DATA_HANDLE hwInstData, S_RTTTL_DATA *pData, EAS_I32 *pValue);
-static EAS_RESULT RTTTL_ParseHeader (S_EAS_DATA *pEASData, S_RTTTL_DATA* pData, EAS_BOOL metaData);
-static EAS_RESULT RTTTL_GetNextChar (EAS_HW_DATA_HANDLE hwInstData, S_RTTTL_DATA *pData, EAS_I8 *pValue);
-static EAS_RESULT RTTTL_PeekNextChar (EAS_HW_DATA_HANDLE hwInstData, S_RTTTL_DATA *pData, EAS_I8 *pValue);
-
-/* inline functions */
-EAS_INLINE void RTTTL_PutBackChar (S_RTTTL_DATA *pData, EAS_I8 value) { pData->dataByte = value; }
-
-
-/* lookup table for note values */
-static const EAS_U8 noteTable[] = { 21, 23, 12, 14, 16, 17, 19, 23 };
-
-/*----------------------------------------------------------------------------
- *
- * EAS_RTTTL_Parser
- *
- * This structure contains the functional interface for the iMelody parser
- *----------------------------------------------------------------------------
-*/
-const S_FILE_PARSER_INTERFACE EAS_RTTTL_Parser =
-{
- RTTTL_CheckFileType,
- RTTTL_Prepare,
- RTTTL_Time,
- RTTTL_Event,
- RTTTL_State,
- RTTTL_Close,
- RTTTL_Reset,
- RTTTL_Pause,
- RTTTL_Resume,
- NULL,
- RTTTL_SetData,
- RTTTL_GetData,
- NULL
-};
-
-/*----------------------------------------------------------------------------
- * RTTTL_CheckFileType()
- *----------------------------------------------------------------------------
- * Purpose:
- * Check the file type to see if we can parse it
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT RTTTL_CheckFileType (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle, EAS_VOID_PTR *ppHandle, EAS_I32 offset)
-{
- S_RTTTL_DATA data;
- S_RTTTL_DATA *pData;
-
- /* see if we can parse the header */
- data.fileHandle = fileHandle;
- data.fileOffset = offset;
- *ppHandle= NULL;
- if (RTTTL_ParseHeader (pEASData, &data, EAS_FALSE) == EAS_SUCCESS)
- {
-
- /* check for static memory allocation */
- if (pEASData->staticMemoryModel)
- pData = EAS_CMEnumData(EAS_CM_RTTTL_DATA);
- else
- pData = EAS_HWMalloc(pEASData->hwInstData, sizeof(S_RTTTL_DATA));
- if (!pData)
- return EAS_ERROR_MALLOC_FAILED;
- EAS_HWMemSet(pData, 0, sizeof(S_RTTTL_DATA));
-
- /* return a pointer to the instance data */
- pData->fileHandle = fileHandle;
- pData->fileOffset = offset;
- pData->state = EAS_STATE_OPEN;
- *ppHandle = pData;
- }
-
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * RTTTL_Prepare()
- *----------------------------------------------------------------------------
- * Purpose:
- * Prepare to parse the file. Allocates instance data (or uses static allocation for
- * static memory model).
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT RTTTL_Prepare (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
-{
- S_RTTTL_DATA* pData;
- EAS_RESULT result;
-
- /* check for valid state */
- pData = (S_RTTTL_DATA*) pInstData;
- if (pData->state != EAS_STATE_OPEN)
- return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
-
- /* instantiate a synthesizer */
- if ((result = VMInitMIDI(pEASData, &pData->pSynth)) != EAS_SUCCESS)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "VMInitMIDI returned %d\n", result); */ }
- return result;
- }
-
- pData->state = EAS_STATE_ERROR;
- if ((result = RTTTL_ParseHeader (pEASData, pData, (EAS_BOOL) (pData->metadata.callback != NULL))) != EAS_SUCCESS)
- {
- /* if using dynamic memory, free it */
- if (!pEASData->staticMemoryModel)
- EAS_HWFree(pEASData->hwInstData, pData);
- return result;
- }
-
- pData->state = EAS_STATE_READY;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * RTTTL_Time()
- *----------------------------------------------------------------------------
- * Purpose:
- * Returns the time of the next event in msecs
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- * pTime - pointer to variable to hold time of next event (in msecs)
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, pEASData) reserved for future use */
-static EAS_RESULT RTTTL_Time (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_U32 *pTime)
-{
- S_RTTTL_DATA *pData;
-
- pData = (S_RTTTL_DATA*) pInstData;
-
- /* return time in milliseconds */
- /*lint -e{704} use shift instead of division */
- *pTime = pData->time >> 8;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * RTTTL_Event()
- *----------------------------------------------------------------------------
- * Purpose:
- * Parse the next event in the file
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT RTTTL_Event (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_INT parserMode)
-{
- S_RTTTL_DATA* pData;
- EAS_RESULT result;
- EAS_I32 ticks;
- EAS_I32 temp;
- EAS_I8 c;
- EAS_U8 note;
- EAS_U8 octave;
-
- pData = (S_RTTTL_DATA*) pInstData;
- if (pData->state >= EAS_STATE_OPEN)
- return EAS_SUCCESS;
-
- /* initialize MIDI channel when the track starts playing */
- if (pData->time == 0)
- {
- /* set program to square lead */
- VMProgramChange(pEASData->pVoiceMgr, pData->pSynth, RTTTL_CHANNEL, RTTTL_PROGRAM);
-
- /* set channel volume to max */
- VMControlChange(pEASData->pVoiceMgr, pData->pSynth, RTTTL_CHANNEL, 7, 127);
- }
-
- /* check for end of note */
- if (pData->note)
- {
- /* stop the note */
- VMStopNote(pEASData->pVoiceMgr, pData->pSynth, RTTTL_CHANNEL, pData->note, 0);
- pData->note = 0;
-
- /* check for rest between notes */
- if (pData->restTicks)
- {
- pData->time += pData->restTicks;
- pData->restTicks = 0;
- return EAS_SUCCESS;
- }
- }
-
- /* parse the next event */
- octave = pData->octave;
- note = 0;
- ticks = pData->duration * pData->tick;
- for (;;)
- {
-
- /* get next character */
- if ((result = RTTTL_GetNextChar(pEASData->hwInstData, pData, &c)) != EAS_SUCCESS)
- {
- if (result != EAS_EOF)
- return result;
-
- /* end of file, if no notes to process, check for looping */
- if (!note)
- {
- /* if no loop set state to stopping */
- if (pData->repeatCount == 0)
- {
- pData->state = EAS_STATE_STOPPING;
- VMReleaseAllVoices(pEASData->pVoiceMgr, pData->pSynth);
- return EAS_SUCCESS;
- }
-
- /* decrement loop count */
- if (pData->repeatCount != RTTTL_INFINITE_LOOP)
- pData->repeatCount--;
-
- /* if locating, ignore infinite loops */
- else if (parserMode != eParserModePlay)
- {
- pData->state = EAS_STATE_STOPPING;
- VMReleaseAllVoices(pEASData->pVoiceMgr, pData->pSynth);
- return EAS_SUCCESS;
- }
-
- /* loop back to start of notes */
- if ((result = EAS_HWFileSeek(pEASData->hwInstData, pData->fileHandle, pData->repeatOffset)) != EAS_SUCCESS)
- return result;
- continue;
- }
-
- /* still have a note to process */
- else
- c = ',';
- }
-
- /* bpm */
- if (c == 'b')
- {
- /* peek at next character */
- if ((result = RTTTL_PeekNextChar(pEASData->hwInstData, pData, &c)) != EAS_SUCCESS)
- return result;
-
- /* if a number, must be octave or tempo */
- if (IsDigit(c))
- {
- if ((result = RTTTL_GetNumber(pEASData->hwInstData, pData, &temp)) != EAS_SUCCESS)
- return result;
-
- /* check for octave first */
- if ((temp >= 4) && (temp <= 7))
- {
- octave = (EAS_U8) temp;
- }
-
- /* check for tempo */
- else if ((temp >= 25) && (temp <= 900))
- {
- pData->tick = TICK_CONVERT / (EAS_U32) temp;
- }
-
- /* don't know what it was */
- else
- return EAS_ERROR_FILE_FORMAT;
- }
-
- /* must be a note */
- else
- {
- note = noteTable[1];
- }
- }
-
- /* octave */
- else if (c == 'o')
- {
- if ((result = RTTTL_GetOctave(pEASData->hwInstData, pData, &pData->octave)) != EAS_SUCCESS)
- return result;
- }
-
- /* style */
- else if (c == 's')
- {
- if ((result = RTTTL_GetStyle(pEASData->hwInstData, pData)) != EAS_SUCCESS)
- return result;
- }
-
- /* duration or octave */
- else if (IsDigit(c))
- {
- RTTTL_PutBackChar(pData, c);
-
- /* duration comes before note */
- if (!note)
- {
- if ((result = RTTTL_GetDuration(pEASData->hwInstData, pData, &c)) != EAS_SUCCESS)
- return result;
- ticks = c * pData->tick;
- }
-
- /* octave comes after note */
- else
- {
- if ((result = RTTTL_GetOctave(pEASData->hwInstData, pData, &octave)) != EAS_SUCCESS)
- return result;
- }
- }
-
- /* note or rest */
- else if ((c >= 'a') && (c <= 'h'))
- {
- note = noteTable[c - 'a'];
- }
-
- else if (c == 'p')
- {
- note = RTTTL_REST;
- }
-
- /* dotted note */
- else if (c == '.')
- {
- /*lint -e{704} shift for performance */
- ticks += ticks >> 1;
- }
-
- /* accidental */
- else if (c == '#')
- {
- if (note)
- note++;
- }
-
- /* end of event */
- else if ((c == ',') && note)
- {
-
- /* handle note events */
- if (note != RTTTL_REST)
- {
-
- /* save note and start it */
- pData->note = note + octave;
- if (parserMode == eParserModePlay)
- VMStartNote(pEASData->pVoiceMgr, pData->pSynth, RTTTL_CHANNEL, pData->note, RTTTL_VELOCITY);
-
- /* determine note length */
- switch (pData->style)
- {
- /* natural */
- case 'n':
- /*lint -e{704} shift for performance */
- pData->restTicks = ticks >> 4;
- break;
- /* continuous */
-
- case 'c':
- pData->restTicks = 0;
- break;
-
- /* staccato */
- case 's':
- /*lint -e{704} shift for performance */
- pData->restTicks = ticks >> 1;
- break;
-
- default:
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "RTTTL_Event: Unexpected style type %c\n", pData->style); */ }
- break;
- }
-
- /* next event is at end of this note */
- pData->time += ticks - pData->restTicks;
- }
-
- /* rest */
- else
- pData->time += ticks;
-
- /* event found, return to caller */
- break;
- }
- }
-
- pData->state = EAS_STATE_PLAY;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * RTTTL_State()
- *----------------------------------------------------------------------------
- * Purpose:
- * Returns the current state of the stream
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- * pState - pointer to variable to store state
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, pEASData) reserved for future use */
-static EAS_RESULT RTTTL_State (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 *pState)
-{
- S_RTTTL_DATA* pData;
-
- /* establish pointer to instance data */
- pData = (S_RTTTL_DATA*) pInstData;
-
- /* if stopping, check to see if synth voices are active */
- if (pData->state == EAS_STATE_STOPPING)
- {
- if (VMActiveVoices(pData->pSynth) == 0)
- pData->state = EAS_STATE_STOPPED;
- }
-
- if (pData->state == EAS_STATE_PAUSING)
- {
- if (VMActiveVoices(pData->pSynth) == 0)
- pData->state = EAS_STATE_PAUSED;
- }
-
- /* return current state */
- *pState = pData->state;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * RTTTL_Close()
- *----------------------------------------------------------------------------
- * Purpose:
- * Close the file and clean up
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT RTTTL_Close (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
-{
- S_RTTTL_DATA* pData;
- EAS_RESULT result;
-
- pData = (S_RTTTL_DATA*) pInstData;
-
- /* close the file */
- if ((result = EAS_HWCloseFile(pEASData->hwInstData, pData->fileHandle)) != EAS_SUCCESS)
- return result;
-
- /* free the synth */
- if (pData->pSynth != NULL)
- VMMIDIShutdown(pEASData, pData->pSynth);
-
- /* if using dynamic memory, free it */
- if (!pEASData->staticMemoryModel)
- EAS_HWFree(pEASData->hwInstData, pData);
-
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * RTTTL_Reset()
- *----------------------------------------------------------------------------
- * Purpose:
- * Reset the sequencer. Used for locating backwards in the file.
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT RTTTL_Reset (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
-{
- S_RTTTL_DATA* pData;
- EAS_RESULT result;
-
- pData = (S_RTTTL_DATA*) pInstData;
-
- /* reset the synth */
- VMReset(pEASData->pVoiceMgr, pData->pSynth, EAS_TRUE);
-
- /* reset time to zero */
- pData->time = 0;
- pData->note = 0;
-
- /* reset file position and re-parse header */
- pData->state = EAS_STATE_ERROR;
- if ((result = EAS_HWFileSeek(pEASData->hwInstData, pData->fileHandle, pData->fileOffset)) != EAS_SUCCESS)
- return result;
- if ((result = RTTTL_ParseHeader (pEASData, pData, EAS_TRUE)) != EAS_SUCCESS)
- return result;
-
- pData->state = EAS_STATE_READY;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * RTTTL_Pause()
- *----------------------------------------------------------------------------
- * Purpose:
- * Pauses the sequencer. Mutes all voices and sets state to pause.
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT RTTTL_Pause (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
-{
- S_RTTTL_DATA *pData;
-
- /* can't pause a stopped stream */
- pData = (S_RTTTL_DATA*) pInstData;
- if (pData->state == EAS_STATE_STOPPED)
- return EAS_ERROR_ALREADY_STOPPED;
-
- /* mute the synthesizer */
- VMMuteAllVoices(pEASData->pVoiceMgr, pData->pSynth);
- pData->state = EAS_STATE_PAUSING;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * RTTTL_Resume()
- *----------------------------------------------------------------------------
- * Purpose:
- * Resume playing after a pause, sets state back to playing.
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, pEASData) reserved for future use */
-static EAS_RESULT RTTTL_Resume (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
-{
- S_RTTTL_DATA *pData;
-
- /* can't resume a stopped stream */
- pData = (S_RTTTL_DATA*) pInstData;
- if (pData->state == EAS_STATE_STOPPED)
- return EAS_ERROR_ALREADY_STOPPED;
-
- /* nothing to do but resume playback */
- pData->state = EAS_STATE_PLAY;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * RTTTL_SetData()
- *----------------------------------------------------------------------------
- * Purpose:
- * Return file type
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, pEASData) reserved for future use */
-static EAS_RESULT RTTTL_SetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value)
-{
- S_RTTTL_DATA *pData;
-
- pData = (S_RTTTL_DATA *) pInstData;
- switch (param)
- {
-
- /* set metadata callback */
- case PARSER_DATA_METADATA_CB:
- EAS_HWMemCpy(&pData->metadata, (void*) value, sizeof(S_METADATA_CB));
- break;
-
- default:
- return EAS_ERROR_INVALID_PARAMETER;
- }
-
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * RTTTL_GetData()
- *----------------------------------------------------------------------------
- * Purpose:
- * Return file type
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, pEASData) reserved for future use */
-static EAS_RESULT RTTTL_GetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue)
-{
- S_RTTTL_DATA *pData;
-
- pData = (S_RTTTL_DATA *) pInstData;
- switch (param)
- {
- /* return file type as RTTTL */
- case PARSER_DATA_FILE_TYPE:
- *pValue = EAS_FILE_RTTTL;
- break;
-
-#if 0
- /* set transposition */
- case PARSER_DATA_TRANSPOSITION:
- *pValue = pData->transposition;
- break;
-#endif
-
- case PARSER_DATA_SYNTH_HANDLE:
- *pValue = (EAS_I32) pData->pSynth;
- break;
-
- case PARSER_DATA_GAIN_OFFSET:
- *pValue = RTTTL_GAIN_OFFSET;
- break;
-
- default:
- return EAS_ERROR_INVALID_PARAMETER;
- }
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * RTTTL_GetStyle()
- *----------------------------------------------------------------------------
- * Purpose:
- *
- *
- * Inputs:
- *
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT RTTTL_GetStyle (EAS_HW_DATA_HANDLE hwInstData, S_RTTTL_DATA *pData)
-{
- EAS_RESULT result;
- EAS_I8 style;
-
- /* get style */
- if ((result = RTTTL_GetNextChar(hwInstData, pData, &style)) != EAS_SUCCESS)
- return result;
-
- if ((style != 's') && (style != 'n') && (style != 'c'))
- return EAS_ERROR_FILE_FORMAT;
-
- pData->style = style;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * RTTTL_GetDuration()
- *----------------------------------------------------------------------------
- * Purpose:
- *
- *
- * Inputs:
- *
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT RTTTL_GetDuration (EAS_HW_DATA_HANDLE hwInstData, S_RTTTL_DATA *pData, EAS_I8 *pDuration)
-{
- EAS_RESULT result;
- EAS_I32 duration;
- EAS_I8 temp;
-
- /* get the duration */
- if ((result = RTTTL_GetNumber(hwInstData, pData, &duration)) != EAS_SUCCESS)
- return result;
-
- if ((duration != 1) && (duration != 2) && (duration != 4) && (duration != 8) && (duration != 16) && (duration != 32))
- return EAS_ERROR_FILE_FORMAT;
-
- temp = 64;
- while (duration)
- {
- /*lint -e{704} shift for performance */
- duration = duration >> 1;
- /*lint -e{702} use shift for performance */
- temp = temp >> 1;
- }
-
- *pDuration = temp;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * RTTTL_GetOctave()
- *----------------------------------------------------------------------------
- * Purpose:
- *
- *
- * Inputs:
- *
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT RTTTL_GetOctave (EAS_HW_DATA_HANDLE hwInstData, S_RTTTL_DATA *pData, EAS_U8 *pOctave)
-{
- EAS_RESULT result;
- EAS_I32 octave;
-
- /* get the tempo */
- if ((result = RTTTL_GetNumber(hwInstData, pData, &octave)) != EAS_SUCCESS)
- return result;
-
- if ((octave < 4) || (octave > 7))
- return EAS_ERROR_FILE_FORMAT;
-
- *pOctave = (EAS_U8) (octave * 12);
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * RTTTL_GetTempo()
- *----------------------------------------------------------------------------
- * Purpose:
- *
- *
- * Inputs:
- *
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT RTTTL_GetTempo (EAS_HW_DATA_HANDLE hwInstData, S_RTTTL_DATA *pData)
-{
- EAS_RESULT result;
- EAS_I32 tempo;
-
- /* get the tempo */
- if ((result = RTTTL_GetNumber(hwInstData, pData, &tempo)) != EAS_SUCCESS)
- return result;
-
- if ((tempo < 25) || (tempo > 900))
- return EAS_ERROR_FILE_FORMAT;
-
- pData->tick = TICK_CONVERT / (EAS_U32) tempo;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * RTTTL_GetNumber()
- *----------------------------------------------------------------------------
- * Purpose:
- *
- *
- * Inputs:
- *
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT RTTTL_GetNumber (EAS_HW_DATA_HANDLE hwInstData, S_RTTTL_DATA *pData, EAS_I32 *pValue)
-{
- EAS_RESULT result;
- EAS_INT temp;
- EAS_I8 c;
-
- *pValue = -1;
- temp = 0;
- for (;;)
- {
- if ((result = RTTTL_PeekNextChar(hwInstData, pData, &c)) != EAS_SUCCESS)
- {
- if ((result == EAS_EOF) && (*pValue != -1))
- return EAS_SUCCESS;
- return result;
- }
-
- if (IsDigit(c))
- {
- pData->dataByte = 0;
- temp = temp * 10 + c - '0';
- *pValue = temp;
- }
- else
- return EAS_SUCCESS;
- }
-}
-
-/*----------------------------------------------------------------------------
- * RTTTL_ParseHeader()
- *----------------------------------------------------------------------------
- * Purpose:
- * Prepare to parse the file. Allocates instance data (or uses static allocation for
- * static memory model).
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT RTTTL_ParseHeader (S_EAS_DATA *pEASData, S_RTTTL_DATA* pData, EAS_BOOL metaData)
-{
- EAS_RESULT result;
- EAS_I32 i;
- EAS_I8 temp;
- EAS_I8 control;
-
- /* initialize some defaults */
- pData->time = 0;
- pData->tick = DEFAULT_TICK_CONV;
- pData->note = 0;
- pData->duration = 4;
- pData ->restTicks = 0;
- pData->octave = 60;
- pData->repeatOffset = -1;
- pData->repeatCount = 0;
- pData->style = 'n';
- pData->dataByte = 0;
-
- metaData = metaData && (pData->metadata.buffer != NULL) && (pData->metadata.callback != NULL);
-
- /* seek to start of data */
- if ((result = EAS_HWFileSeek(pEASData->hwInstData, pData->fileHandle, pData->fileOffset)) != EAS_SUCCESS)
- return result;
-
- /* zero the metadata buffer */
- if (metaData)
- EAS_HWMemSet(pData->metadata.buffer, 0, pData->metadata.bufferSize);
-
- /* read the title */
- for (i = 0; i < RTTTL_MAX_TITLE_LEN; i++)
- {
- if ((result = EAS_HWGetByte(pEASData->hwInstData, pData->fileHandle, &temp)) != EAS_SUCCESS)
- return result;
-
- if (temp == ':')
- break;
-
- /* pass along metadata */
- if (metaData)
- {
- if (i < (pData->metadata.bufferSize- 1))
- pData->metadata.buffer[i] = (char) temp;
- }
- }
-
- /* check for error in title */
- if (i == RTTTL_MAX_TITLE_LEN)
- return EAS_ERROR_FILE_FORMAT;
-
- /* pass along metadata */
- if (metaData)
- (*pData->metadata.callback)(EAS_METADATA_TITLE, pData->metadata.buffer, pData->metadata.pUserData);
-
- /* control fields */
- for (;;)
- {
-
- /* get control type */
- if ((result = RTTTL_GetNextChar(pEASData->hwInstData, pData, &control)) != EAS_SUCCESS)
- return result;
-
- /* next char should be equal sign */
- if ((result = RTTTL_GetNextChar(pEASData->hwInstData, pData, &temp)) != EAS_SUCCESS)
- return result;
- if (temp != '=')
- return EAS_ERROR_FILE_FORMAT;
-
- /* get the control value */
- switch (control)
- {
-
- /* bpm */
- case 'b':
- if ((result = RTTTL_GetTempo(pEASData->hwInstData, pData)) != EAS_SUCCESS)
- return result;
- break;
-
- /* duration */
- case 'd':
- if ((result = RTTTL_GetDuration(pEASData->hwInstData, pData, &temp)) != EAS_SUCCESS)
- return result;
- pData->duration = temp;
- break;
-
- /* loop */
- case 'l':
- if ((result = RTTTL_GetNumber(pEASData->hwInstData, pData, &i)) != EAS_SUCCESS)
- return result;
- if ((i < 0) || (i > 15))
- return EAS_ERROR_FILE_FORMAT;
- pData->repeatCount = (EAS_U8) i;
- break;
-
- /* octave */
- case 'o':
- if ((result = RTTTL_GetOctave(pEASData->hwInstData, pData, &pData->octave)) != EAS_SUCCESS)
- return result;
- break;
-
- /* get style */
- case 's':
- if ((result = RTTTL_GetStyle(pEASData->hwInstData, pData)) != EAS_SUCCESS)
- return result;
- break;
-
- /* unrecognized control */
- default:
- return EAS_ERROR_FILE_FORMAT;
- }
-
- /* next character should be comma or colon */
- if ((result = RTTTL_GetNextChar(pEASData->hwInstData, pData, &temp)) != EAS_SUCCESS)
- return result;
-
- /* check for end of control field */
- if (temp == ':')
- break;
-
- /* must be a comma */
- if (temp != ',')
- return EAS_ERROR_FILE_FORMAT;
- }
-
- /* should be at the start of the music block */
- if ((result = EAS_HWFilePos(pEASData->hwInstData, pData->fileHandle, &pData->repeatOffset)) != EAS_SUCCESS)
- return result;
-
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * RTTTL_GetNextChar()
- *----------------------------------------------------------------------------
- * Purpose:
- *
- *
- * Inputs:
- *
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT RTTTL_GetNextChar (EAS_HW_DATA_HANDLE hwInstData, S_RTTTL_DATA *pData, EAS_I8 *pValue)
-{
- EAS_RESULT result;
- EAS_I8 temp;
-
- *pValue = 0;
- for(;;)
- {
-
- /* check for character that has been put back */
- if (pData->dataByte)
- {
- temp = pData->dataByte;
- pData->dataByte = 0;
- }
- else
- {
- if ((result = EAS_HWGetByte(hwInstData, pData->fileHandle, &temp)) != EAS_SUCCESS)
- return result;
- }
-
- /* ignore white space */
- if (!IsSpace(temp))
- {
- *pValue = ToLower(temp);
- return EAS_SUCCESS;
- }
- }
-}
-
-/*----------------------------------------------------------------------------
- * RTTTL_PeekNextChar()
- *----------------------------------------------------------------------------
- * Purpose:
- *
- *
- * Inputs:
- *
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT RTTTL_PeekNextChar (EAS_HW_DATA_HANDLE hwInstData, S_RTTTL_DATA *pData, EAS_I8 *pValue)
-{
- EAS_RESULT result;
- EAS_I8 temp;
-
- *pValue = 0;
- for(;;)
- {
-
- /* read a character from the file, if necessary */
- if (!pData->dataByte)
- {
- if ((result = EAS_HWGetByte(hwInstData, pData->fileHandle, &pData->dataByte)) != EAS_SUCCESS)
- return result;
-
- }
- temp = pData->dataByte;
-
- /* ignore white space */
- if (!IsSpace(temp))
- {
- *pValue = ToLower(temp);
- return EAS_SUCCESS;
- }
- pData->dataByte = 0;
- }
-}
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 795 $
+ * $Date: 2007-08-01 00:14:45 -0700 (Wed, 01 Aug 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+#include "eas_data.h"
+#include "eas_miditypes.h"
+#include "eas_parser.h"
+#include "eas_report.h"
+#include "eas_host.h"
+#include "eas_midi.h"
+#include "eas_config.h"
+#include "eas_vm_protos.h"
+#include "eas_rtttldata.h"
+#include "eas_ctype.h"
+
+/* increase gain for mono ringtones */
+#define RTTTL_GAIN_OFFSET 8
+
+/* maximum title length including colon separator */
+#define RTTTL_MAX_TITLE_LEN 32
+#define RTTTL_INFINITE_LOOP 15
+
+/* length of 32nd note in 1/256ths of a msec for 63 BPM tempo */
+#define DEFAULT_TICK_CONV 30476
+#define TICK_CONVERT 1920000
+
+/* default channel and program for RTTTL playback */
+#define RTTTL_CHANNEL 0
+#define RTTTL_PROGRAM 80
+#define RTTTL_VELOCITY 127
+
+/* note used for rest */
+#define RTTTL_REST 1
+
+/* multiplier for fixed point triplet conversion */
+#define TRIPLET_MULTIPLIER 683
+#define TRIPLET_SHIFT 10
+
+/* local prototypes */
+static EAS_RESULT RTTTL_CheckFileType (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle, EAS_VOID_PTR *ppHandle, EAS_I32 offset);
+static EAS_RESULT RTTTL_Prepare (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
+static EAS_RESULT RTTTL_Time (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_U32 *pTime);
+static EAS_RESULT RTTTL_Event (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_INT parserMode);
+static EAS_RESULT RTTTL_State (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_STATE *pState);
+static EAS_RESULT RTTTL_Close (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
+static EAS_RESULT RTTTL_Reset (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
+static EAS_RESULT RTTTL_Pause (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
+static EAS_RESULT RTTTL_Resume (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
+static EAS_RESULT RTTTL_SetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value);
+static EAS_RESULT RTTTL_GetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue);
+static EAS_RESULT RTTTL_GetStyle (EAS_HW_DATA_HANDLE hwInstData, S_RTTTL_DATA *pData);
+static EAS_RESULT RTTTL_GetDuration (EAS_HW_DATA_HANDLE hwInstData, S_RTTTL_DATA *pData, EAS_I8 *pDuration);
+static EAS_RESULT RTTTL_GetOctave (EAS_HW_DATA_HANDLE hwInstData, S_RTTTL_DATA *pData, EAS_U8 *pOctave);
+static EAS_RESULT RTTTL_GetTempo (EAS_HW_DATA_HANDLE hwInstData, S_RTTTL_DATA *pData);
+static EAS_RESULT RTTTL_GetNumber (EAS_HW_DATA_HANDLE hwInstData, S_RTTTL_DATA *pData, EAS_I32 *pValue);
+static EAS_RESULT RTTTL_ParseHeader (S_EAS_DATA *pEASData, S_RTTTL_DATA* pData, EAS_BOOL metaData);
+static EAS_RESULT RTTTL_GetNextChar (EAS_HW_DATA_HANDLE hwInstData, S_RTTTL_DATA *pData, EAS_I8 *pValue);
+static EAS_RESULT RTTTL_PeekNextChar (EAS_HW_DATA_HANDLE hwInstData, S_RTTTL_DATA *pData, EAS_I8 *pValue);
+
+/* inline functions */
+EAS_INLINE void RTTTL_PutBackChar (S_RTTTL_DATA *pData, EAS_I8 value) { pData->dataByte = value; }
+
+
+/* lookup table for note values */
+static const EAS_U8 noteTable[] = { 21, 23, 12, 14, 16, 17, 19, 23 };
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_RTTTL_Parser
+ *
+ * This structure contains the functional interface for the iMelody parser
+ *----------------------------------------------------------------------------
+*/
+const S_FILE_PARSER_INTERFACE EAS_RTTTL_Parser =
+{
+ RTTTL_CheckFileType,
+ RTTTL_Prepare,
+ RTTTL_Time,
+ RTTTL_Event,
+ RTTTL_State,
+ RTTTL_Close,
+ RTTTL_Reset,
+ RTTTL_Pause,
+ RTTTL_Resume,
+ NULL,
+ RTTTL_SetData,
+ RTTTL_GetData,
+ NULL
+};
+
+/*----------------------------------------------------------------------------
+ * RTTTL_CheckFileType()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Check the file type to see if we can parse it
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT RTTTL_CheckFileType (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle, EAS_VOID_PTR *ppHandle, EAS_I32 offset)
+{
+ S_RTTTL_DATA data;
+ S_RTTTL_DATA *pData;
+
+ /* see if we can parse the header */
+ data.fileHandle = fileHandle;
+ data.fileOffset = offset;
+ *ppHandle= NULL;
+ if (RTTTL_ParseHeader (pEASData, &data, EAS_FALSE) == EAS_SUCCESS)
+ {
+
+ /* check for static memory allocation */
+ if (pEASData->staticMemoryModel)
+ pData = EAS_CMEnumData(EAS_CM_RTTTL_DATA);
+ else
+ pData = EAS_HWMalloc(pEASData->hwInstData, sizeof(S_RTTTL_DATA));
+ if (!pData)
+ return EAS_ERROR_MALLOC_FAILED;
+ EAS_HWMemSet(pData, 0, sizeof(S_RTTTL_DATA));
+
+ /* return a pointer to the instance data */
+ pData->fileHandle = fileHandle;
+ pData->fileOffset = offset;
+ pData->state = EAS_STATE_OPEN;
+ *ppHandle = pData;
+ }
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * RTTTL_Prepare()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Prepare to parse the file. Allocates instance data (or uses static allocation for
+ * static memory model).
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT RTTTL_Prepare (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
+{
+ S_RTTTL_DATA* pData;
+ EAS_RESULT result;
+
+ /* check for valid state */
+ pData = (S_RTTTL_DATA*) pInstData;
+ if (pData->state != EAS_STATE_OPEN)
+ return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
+
+ /* instantiate a synthesizer */
+ if ((result = VMInitMIDI(pEASData, &pData->pSynth)) != EAS_SUCCESS)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "VMInitMIDI returned %d\n", result); */ }
+ return result;
+ }
+
+ pData->state = EAS_STATE_ERROR;
+ if ((result = RTTTL_ParseHeader (pEASData, pData, (EAS_BOOL) (pData->metadata.callback != NULL))) != EAS_SUCCESS)
+ {
+ /* if using dynamic memory, free it */
+ if (!pEASData->staticMemoryModel)
+ EAS_HWFree(pEASData->hwInstData, pData);
+ return result;
+ }
+
+ pData->state = EAS_STATE_READY;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * RTTTL_Time()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Returns the time of the next event in msecs
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ * pTime - pointer to variable to hold time of next event (in msecs)
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pEASData) reserved for future use */
+static EAS_RESULT RTTTL_Time (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_U32 *pTime)
+{
+ S_RTTTL_DATA *pData;
+
+ pData = (S_RTTTL_DATA*) pInstData;
+
+ /* return time in milliseconds */
+ /*lint -e{704} use shift instead of division */
+ *pTime = pData->time >> 8;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * RTTTL_Event()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Parse the next event in the file
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT RTTTL_Event (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_INT parserMode)
+{
+ S_RTTTL_DATA* pData;
+ EAS_RESULT result;
+ EAS_I32 ticks;
+ EAS_I32 temp;
+ EAS_I8 c;
+ EAS_U8 note;
+ EAS_U8 octave;
+
+ pData = (S_RTTTL_DATA*) pInstData;
+ if (pData->state >= EAS_STATE_OPEN)
+ return EAS_SUCCESS;
+
+ /* initialize MIDI channel when the track starts playing */
+ if (pData->time == 0)
+ {
+ /* set program to square lead */
+ VMProgramChange(pEASData->pVoiceMgr, pData->pSynth, RTTTL_CHANNEL, RTTTL_PROGRAM);
+
+ /* set channel volume to max */
+ VMControlChange(pEASData->pVoiceMgr, pData->pSynth, RTTTL_CHANNEL, 7, 127);
+ }
+
+ /* check for end of note */
+ if (pData->note)
+ {
+ /* stop the note */
+ VMStopNote(pEASData->pVoiceMgr, pData->pSynth, RTTTL_CHANNEL, pData->note, 0);
+ pData->note = 0;
+
+ /* check for rest between notes */
+ if (pData->restTicks)
+ {
+ pData->time += pData->restTicks;
+ pData->restTicks = 0;
+ return EAS_SUCCESS;
+ }
+ }
+
+ /* parse the next event */
+ octave = pData->octave;
+ note = 0;
+ ticks = pData->duration * pData->tick;
+ for (;;)
+ {
+
+ /* get next character */
+ if ((result = RTTTL_GetNextChar(pEASData->hwInstData, pData, &c)) != EAS_SUCCESS)
+ {
+ if (result != EAS_EOF)
+ return result;
+
+ /* end of file, if no notes to process, check for looping */
+ if (!note)
+ {
+ /* if no loop set state to stopping */
+ if (pData->repeatCount == 0)
+ {
+ pData->state = EAS_STATE_STOPPING;
+ VMReleaseAllVoices(pEASData->pVoiceMgr, pData->pSynth);
+ return EAS_SUCCESS;
+ }
+
+ /* decrement loop count */
+ if (pData->repeatCount != RTTTL_INFINITE_LOOP)
+ pData->repeatCount--;
+
+ /* if locating, ignore infinite loops */
+ else if (parserMode != eParserModePlay)
+ {
+ pData->state = EAS_STATE_STOPPING;
+ VMReleaseAllVoices(pEASData->pVoiceMgr, pData->pSynth);
+ return EAS_SUCCESS;
+ }
+
+ /* loop back to start of notes */
+ if ((result = EAS_HWFileSeek(pEASData->hwInstData, pData->fileHandle, pData->repeatOffset)) != EAS_SUCCESS)
+ return result;
+ continue;
+ }
+
+ /* still have a note to process */
+ else
+ c = ',';
+ }
+
+ /* bpm */
+ if (c == 'b')
+ {
+ /* peek at next character */
+ if ((result = RTTTL_PeekNextChar(pEASData->hwInstData, pData, &c)) != EAS_SUCCESS)
+ return result;
+
+ /* if a number, must be octave or tempo */
+ if (IsDigit(c))
+ {
+ if ((result = RTTTL_GetNumber(pEASData->hwInstData, pData, &temp)) != EAS_SUCCESS)
+ return result;
+
+ /* check for octave first */
+ if ((temp >= 4) && (temp <= 7))
+ {
+ octave = (EAS_U8) temp;
+ }
+
+ /* check for tempo */
+ else if ((temp >= 25) && (temp <= 900))
+ {
+ pData->tick = TICK_CONVERT / (EAS_U32) temp;
+ }
+
+ /* don't know what it was */
+ else
+ return EAS_ERROR_FILE_FORMAT;
+ }
+
+ /* must be a note */
+ else
+ {
+ note = noteTable[1];
+ }
+ }
+
+ /* octave */
+ else if (c == 'o')
+ {
+ if ((result = RTTTL_GetOctave(pEASData->hwInstData, pData, &pData->octave)) != EAS_SUCCESS)
+ return result;
+ }
+
+ /* style */
+ else if (c == 's')
+ {
+ if ((result = RTTTL_GetStyle(pEASData->hwInstData, pData)) != EAS_SUCCESS)
+ return result;
+ }
+
+ /* duration or octave */
+ else if (IsDigit(c))
+ {
+ RTTTL_PutBackChar(pData, c);
+
+ /* duration comes before note */
+ if (!note)
+ {
+ if ((result = RTTTL_GetDuration(pEASData->hwInstData, pData, &c)) != EAS_SUCCESS)
+ return result;
+ ticks = c * pData->tick;
+ }
+
+ /* octave comes after note */
+ else
+ {
+ if ((result = RTTTL_GetOctave(pEASData->hwInstData, pData, &octave)) != EAS_SUCCESS)
+ return result;
+ }
+ }
+
+ /* note or rest */
+ else if ((c >= 'a') && (c <= 'h'))
+ {
+ note = noteTable[c - 'a'];
+ }
+
+ else if (c == 'p')
+ {
+ note = RTTTL_REST;
+ }
+
+ /* dotted note */
+ else if (c == '.')
+ {
+ /*lint -e{704} shift for performance */
+ ticks += ticks >> 1;
+ }
+
+ /* accidental */
+ else if (c == '#')
+ {
+ if (note)
+ note++;
+ }
+
+ /* end of event */
+ else if ((c == ',') && note)
+ {
+
+ /* handle note events */
+ if (note != RTTTL_REST)
+ {
+
+ /* save note and start it */
+ pData->note = note + octave;
+ if (parserMode == eParserModePlay)
+ VMStartNote(pEASData->pVoiceMgr, pData->pSynth, RTTTL_CHANNEL, pData->note, RTTTL_VELOCITY);
+
+ /* determine note length */
+ switch (pData->style)
+ {
+ /* natural */
+ case 'n':
+ /*lint -e{704} shift for performance */
+ pData->restTicks = ticks >> 4;
+ break;
+ /* continuous */
+
+ case 'c':
+ pData->restTicks = 0;
+ break;
+
+ /* staccato */
+ case 's':
+ /*lint -e{704} shift for performance */
+ pData->restTicks = ticks >> 1;
+ break;
+
+ default:
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "RTTTL_Event: Unexpected style type %c\n", pData->style); */ }
+ break;
+ }
+
+ /* next event is at end of this note */
+ pData->time += ticks - pData->restTicks;
+ }
+
+ /* rest */
+ else
+ pData->time += ticks;
+
+ /* event found, return to caller */
+ break;
+ }
+ }
+
+ pData->state = EAS_STATE_PLAY;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * RTTTL_State()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Returns the current state of the stream
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ * pState - pointer to variable to store state
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pEASData) reserved for future use */
+static EAS_RESULT RTTTL_State (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 *pState)
+{
+ S_RTTTL_DATA* pData;
+
+ /* establish pointer to instance data */
+ pData = (S_RTTTL_DATA*) pInstData;
+
+ /* if stopping, check to see if synth voices are active */
+ if (pData->state == EAS_STATE_STOPPING)
+ {
+ if (VMActiveVoices(pData->pSynth) == 0)
+ pData->state = EAS_STATE_STOPPED;
+ }
+
+ if (pData->state == EAS_STATE_PAUSING)
+ {
+ if (VMActiveVoices(pData->pSynth) == 0)
+ pData->state = EAS_STATE_PAUSED;
+ }
+
+ /* return current state */
+ *pState = pData->state;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * RTTTL_Close()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Close the file and clean up
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT RTTTL_Close (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
+{
+ S_RTTTL_DATA* pData;
+ EAS_RESULT result;
+
+ pData = (S_RTTTL_DATA*) pInstData;
+
+ /* close the file */
+ if ((result = EAS_HWCloseFile(pEASData->hwInstData, pData->fileHandle)) != EAS_SUCCESS)
+ return result;
+
+ /* free the synth */
+ if (pData->pSynth != NULL)
+ VMMIDIShutdown(pEASData, pData->pSynth);
+
+ /* if using dynamic memory, free it */
+ if (!pEASData->staticMemoryModel)
+ EAS_HWFree(pEASData->hwInstData, pData);
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * RTTTL_Reset()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Reset the sequencer. Used for locating backwards in the file.
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT RTTTL_Reset (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
+{
+ S_RTTTL_DATA* pData;
+ EAS_RESULT result;
+
+ pData = (S_RTTTL_DATA*) pInstData;
+
+ /* reset the synth */
+ VMReset(pEASData->pVoiceMgr, pData->pSynth, EAS_TRUE);
+
+ /* reset time to zero */
+ pData->time = 0;
+ pData->note = 0;
+
+ /* reset file position and re-parse header */
+ pData->state = EAS_STATE_ERROR;
+ if ((result = EAS_HWFileSeek(pEASData->hwInstData, pData->fileHandle, pData->fileOffset)) != EAS_SUCCESS)
+ return result;
+ if ((result = RTTTL_ParseHeader (pEASData, pData, EAS_TRUE)) != EAS_SUCCESS)
+ return result;
+
+ pData->state = EAS_STATE_READY;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * RTTTL_Pause()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Pauses the sequencer. Mutes all voices and sets state to pause.
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT RTTTL_Pause (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
+{
+ S_RTTTL_DATA *pData;
+
+ /* can't pause a stopped stream */
+ pData = (S_RTTTL_DATA*) pInstData;
+ if (pData->state == EAS_STATE_STOPPED)
+ return EAS_ERROR_ALREADY_STOPPED;
+
+ /* mute the synthesizer */
+ VMMuteAllVoices(pEASData->pVoiceMgr, pData->pSynth);
+ pData->state = EAS_STATE_PAUSING;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * RTTTL_Resume()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Resume playing after a pause, sets state back to playing.
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pEASData) reserved for future use */
+static EAS_RESULT RTTTL_Resume (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
+{
+ S_RTTTL_DATA *pData;
+
+ /* can't resume a stopped stream */
+ pData = (S_RTTTL_DATA*) pInstData;
+ if (pData->state == EAS_STATE_STOPPED)
+ return EAS_ERROR_ALREADY_STOPPED;
+
+ /* nothing to do but resume playback */
+ pData->state = EAS_STATE_PLAY;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * RTTTL_SetData()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Return file type
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pEASData) reserved for future use */
+static EAS_RESULT RTTTL_SetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value)
+{
+ S_RTTTL_DATA *pData;
+
+ pData = (S_RTTTL_DATA *) pInstData;
+ switch (param)
+ {
+
+ /* set metadata callback */
+ case PARSER_DATA_METADATA_CB:
+ EAS_HWMemCpy(&pData->metadata, (void*) value, sizeof(S_METADATA_CB));
+ break;
+
+ default:
+ return EAS_ERROR_INVALID_PARAMETER;
+ }
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * RTTTL_GetData()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Return file type
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pEASData) reserved for future use */
+static EAS_RESULT RTTTL_GetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue)
+{
+ S_RTTTL_DATA *pData;
+
+ pData = (S_RTTTL_DATA *) pInstData;
+ switch (param)
+ {
+ /* return file type as RTTTL */
+ case PARSER_DATA_FILE_TYPE:
+ *pValue = EAS_FILE_RTTTL;
+ break;
+
+#if 0
+ /* set transposition */
+ case PARSER_DATA_TRANSPOSITION:
+ *pValue = pData->transposition;
+ break;
+#endif
+
+ case PARSER_DATA_SYNTH_HANDLE:
+ *pValue = (EAS_I32) pData->pSynth;
+ break;
+
+ case PARSER_DATA_GAIN_OFFSET:
+ *pValue = RTTTL_GAIN_OFFSET;
+ break;
+
+ default:
+ return EAS_ERROR_INVALID_PARAMETER;
+ }
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * RTTTL_GetStyle()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ *
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT RTTTL_GetStyle (EAS_HW_DATA_HANDLE hwInstData, S_RTTTL_DATA *pData)
+{
+ EAS_RESULT result;
+ EAS_I8 style;
+
+ /* get style */
+ if ((result = RTTTL_GetNextChar(hwInstData, pData, &style)) != EAS_SUCCESS)
+ return result;
+
+ if ((style != 's') && (style != 'n') && (style != 'c'))
+ return EAS_ERROR_FILE_FORMAT;
+
+ pData->style = style;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * RTTTL_GetDuration()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ *
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT RTTTL_GetDuration (EAS_HW_DATA_HANDLE hwInstData, S_RTTTL_DATA *pData, EAS_I8 *pDuration)
+{
+ EAS_RESULT result;
+ EAS_I32 duration;
+ EAS_I8 temp;
+
+ /* get the duration */
+ if ((result = RTTTL_GetNumber(hwInstData, pData, &duration)) != EAS_SUCCESS)
+ return result;
+
+ if ((duration != 1) && (duration != 2) && (duration != 4) && (duration != 8) && (duration != 16) && (duration != 32))
+ return EAS_ERROR_FILE_FORMAT;
+
+ temp = 64;
+ while (duration)
+ {
+ /*lint -e{704} shift for performance */
+ duration = duration >> 1;
+ /*lint -e{702} use shift for performance */
+ temp = temp >> 1;
+ }
+
+ *pDuration = temp;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * RTTTL_GetOctave()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ *
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT RTTTL_GetOctave (EAS_HW_DATA_HANDLE hwInstData, S_RTTTL_DATA *pData, EAS_U8 *pOctave)
+{
+ EAS_RESULT result;
+ EAS_I32 octave;
+
+ /* get the tempo */
+ if ((result = RTTTL_GetNumber(hwInstData, pData, &octave)) != EAS_SUCCESS)
+ return result;
+
+ if ((octave < 4) || (octave > 7))
+ return EAS_ERROR_FILE_FORMAT;
+
+ *pOctave = (EAS_U8) (octave * 12);
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * RTTTL_GetTempo()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ *
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT RTTTL_GetTempo (EAS_HW_DATA_HANDLE hwInstData, S_RTTTL_DATA *pData)
+{
+ EAS_RESULT result;
+ EAS_I32 tempo;
+
+ /* get the tempo */
+ if ((result = RTTTL_GetNumber(hwInstData, pData, &tempo)) != EAS_SUCCESS)
+ return result;
+
+ if ((tempo < 25) || (tempo > 900))
+ return EAS_ERROR_FILE_FORMAT;
+
+ pData->tick = TICK_CONVERT / (EAS_U32) tempo;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * RTTTL_GetNumber()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ *
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT RTTTL_GetNumber (EAS_HW_DATA_HANDLE hwInstData, S_RTTTL_DATA *pData, EAS_I32 *pValue)
+{
+ EAS_RESULT result;
+ EAS_INT temp;
+ EAS_I8 c;
+
+ *pValue = -1;
+ temp = 0;
+ for (;;)
+ {
+ if ((result = RTTTL_PeekNextChar(hwInstData, pData, &c)) != EAS_SUCCESS)
+ {
+ if ((result == EAS_EOF) && (*pValue != -1))
+ return EAS_SUCCESS;
+ return result;
+ }
+
+ if (IsDigit(c))
+ {
+ pData->dataByte = 0;
+ temp = temp * 10 + c - '0';
+ *pValue = temp;
+ }
+ else
+ return EAS_SUCCESS;
+ }
+}
+
+/*----------------------------------------------------------------------------
+ * RTTTL_ParseHeader()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Prepare to parse the file. Allocates instance data (or uses static allocation for
+ * static memory model).
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT RTTTL_ParseHeader (S_EAS_DATA *pEASData, S_RTTTL_DATA* pData, EAS_BOOL metaData)
+{
+ EAS_RESULT result;
+ EAS_I32 i;
+ EAS_I8 temp;
+ EAS_I8 control;
+
+ /* initialize some defaults */
+ pData->time = 0;
+ pData->tick = DEFAULT_TICK_CONV;
+ pData->note = 0;
+ pData->duration = 4;
+ pData ->restTicks = 0;
+ pData->octave = 60;
+ pData->repeatOffset = -1;
+ pData->repeatCount = 0;
+ pData->style = 'n';
+ pData->dataByte = 0;
+
+ metaData = metaData && (pData->metadata.buffer != NULL) && (pData->metadata.callback != NULL);
+
+ /* seek to start of data */
+ if ((result = EAS_HWFileSeek(pEASData->hwInstData, pData->fileHandle, pData->fileOffset)) != EAS_SUCCESS)
+ return result;
+
+ /* zero the metadata buffer */
+ if (metaData)
+ EAS_HWMemSet(pData->metadata.buffer, 0, pData->metadata.bufferSize);
+
+ /* read the title */
+ for (i = 0; i < RTTTL_MAX_TITLE_LEN; i++)
+ {
+ if ((result = EAS_HWGetByte(pEASData->hwInstData, pData->fileHandle, &temp)) != EAS_SUCCESS)
+ return result;
+
+ if (temp == ':')
+ break;
+
+ /* pass along metadata */
+ if (metaData)
+ {
+ if (i < (pData->metadata.bufferSize- 1))
+ pData->metadata.buffer[i] = (char) temp;
+ }
+ }
+
+ /* check for error in title */
+ if (i == RTTTL_MAX_TITLE_LEN)
+ return EAS_ERROR_FILE_FORMAT;
+
+ /* pass along metadata */
+ if (metaData)
+ (*pData->metadata.callback)(EAS_METADATA_TITLE, pData->metadata.buffer, pData->metadata.pUserData);
+
+ /* control fields */
+ for (;;)
+ {
+
+ /* get control type */
+ if ((result = RTTTL_GetNextChar(pEASData->hwInstData, pData, &control)) != EAS_SUCCESS)
+ return result;
+
+ /* next char should be equal sign */
+ if ((result = RTTTL_GetNextChar(pEASData->hwInstData, pData, &temp)) != EAS_SUCCESS)
+ return result;
+ if (temp != '=')
+ return EAS_ERROR_FILE_FORMAT;
+
+ /* get the control value */
+ switch (control)
+ {
+
+ /* bpm */
+ case 'b':
+ if ((result = RTTTL_GetTempo(pEASData->hwInstData, pData)) != EAS_SUCCESS)
+ return result;
+ break;
+
+ /* duration */
+ case 'd':
+ if ((result = RTTTL_GetDuration(pEASData->hwInstData, pData, &temp)) != EAS_SUCCESS)
+ return result;
+ pData->duration = temp;
+ break;
+
+ /* loop */
+ case 'l':
+ if ((result = RTTTL_GetNumber(pEASData->hwInstData, pData, &i)) != EAS_SUCCESS)
+ return result;
+ if ((i < 0) || (i > 15))
+ return EAS_ERROR_FILE_FORMAT;
+ pData->repeatCount = (EAS_U8) i;
+ break;
+
+ /* octave */
+ case 'o':
+ if ((result = RTTTL_GetOctave(pEASData->hwInstData, pData, &pData->octave)) != EAS_SUCCESS)
+ return result;
+ break;
+
+ /* get style */
+ case 's':
+ if ((result = RTTTL_GetStyle(pEASData->hwInstData, pData)) != EAS_SUCCESS)
+ return result;
+ break;
+
+ /* unrecognized control */
+ default:
+ return EAS_ERROR_FILE_FORMAT;
+ }
+
+ /* next character should be comma or colon */
+ if ((result = RTTTL_GetNextChar(pEASData->hwInstData, pData, &temp)) != EAS_SUCCESS)
+ return result;
+
+ /* check for end of control field */
+ if (temp == ':')
+ break;
+
+ /* must be a comma */
+ if (temp != ',')
+ return EAS_ERROR_FILE_FORMAT;
+ }
+
+ /* should be at the start of the music block */
+ if ((result = EAS_HWFilePos(pEASData->hwInstData, pData->fileHandle, &pData->repeatOffset)) != EAS_SUCCESS)
+ return result;
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * RTTTL_GetNextChar()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ *
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT RTTTL_GetNextChar (EAS_HW_DATA_HANDLE hwInstData, S_RTTTL_DATA *pData, EAS_I8 *pValue)
+{
+ EAS_RESULT result;
+ EAS_I8 temp;
+
+ *pValue = 0;
+ for(;;)
+ {
+
+ /* check for character that has been put back */
+ if (pData->dataByte)
+ {
+ temp = pData->dataByte;
+ pData->dataByte = 0;
+ }
+ else
+ {
+ if ((result = EAS_HWGetByte(hwInstData, pData->fileHandle, &temp)) != EAS_SUCCESS)
+ return result;
+ }
+
+ /* ignore white space */
+ if (!IsSpace(temp))
+ {
+ *pValue = ToLower(temp);
+ return EAS_SUCCESS;
+ }
+ }
+}
+
+/*----------------------------------------------------------------------------
+ * RTTTL_PeekNextChar()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ *
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT RTTTL_PeekNextChar (EAS_HW_DATA_HANDLE hwInstData, S_RTTTL_DATA *pData, EAS_I8 *pValue)
+{
+ EAS_RESULT result;
+ EAS_I8 temp;
+
+ *pValue = 0;
+ for(;;)
+ {
+
+ /* read a character from the file, if necessary */
+ if (!pData->dataByte)
+ {
+ if ((result = EAS_HWGetByte(hwInstData, pData->fileHandle, &pData->dataByte)) != EAS_SUCCESS)
+ return result;
+
+ }
+ temp = pData->dataByte;
+
+ /* ignore white space */
+ if (!IsSpace(temp))
+ {
+ *pValue = ToLower(temp);
+ return EAS_SUCCESS;
+ }
+ pData->dataByte = 0;
+ }
+}
+
diff --git a/arm-hybrid-22k/lib_src/eas_rtttldata.c b/arm-hybrid-22k/lib_src/eas_rtttldata.c
index 7a500bd..708a1d9 100644
--- a/arm-hybrid-22k/lib_src/eas_rtttldata.c
+++ b/arm-hybrid-22k/lib_src/eas_rtttldata.c
@@ -1,12 +1,12 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_rtttldata.c
- *
- * Contents and purpose:
- * RTTTL File Parser data module for static memory models
- *
- * Copyright Sonic Network Inc. 2005
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_rtttldata.c
+ *
+ * Contents and purpose:
+ * RTTTL File Parser data module for static memory models
+ *
+ * Copyright Sonic Network Inc. 2005
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,23 +19,23 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 547 $
- * $Date: 2007-01-31 16:30:17 -0800 (Wed, 31 Jan 2007) $
- *----------------------------------------------------------------------------
-*/
-
-#include "eas_types.h"
-#include "eas_rtttldata.h"
-
-/*----------------------------------------------------------------------------
- *
- * eas_RTTTLData
- *
- * Static memory allocation for RTTTL parser
- *----------------------------------------------------------------------------
-*/
-S_RTTTL_DATA eas_RTTTLData;
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 547 $
+ * $Date: 2007-01-31 16:30:17 -0800 (Wed, 31 Jan 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+#include "eas_types.h"
+#include "eas_rtttldata.h"
+
+/*----------------------------------------------------------------------------
+ *
+ * eas_RTTTLData
+ *
+ * Static memory allocation for RTTTL parser
+ *----------------------------------------------------------------------------
+*/
+S_RTTTL_DATA eas_RTTTLData;
+
diff --git a/arm-hybrid-22k/lib_src/eas_rtttldata.h b/arm-hybrid-22k/lib_src/eas_rtttldata.h
index bf4c38b..31dd522 100644
--- a/arm-hybrid-22k/lib_src/eas_rtttldata.h
+++ b/arm-hybrid-22k/lib_src/eas_rtttldata.h
@@ -1,14 +1,14 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_rtttldata.h
- *
- * Contents and purpose:
- * SMF File Parser
- *
- * This file contains data declarations for the RTTTL parser.
- *
- * Copyright Sonic Network Inc. 2005
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_rtttldata.h
+ *
+ * Contents and purpose:
+ * SMF File Parser
+ *
+ * This file contains data declarations for the RTTTL parser.
+ *
+ * Copyright Sonic Network Inc. 2005
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,50 +21,50 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 82 $
- * $Date: 2006-07-10 11:45:19 -0700 (Mon, 10 Jul 2006) $
- *----------------------------------------------------------------------------
-*/
-
-#ifndef EAS_RTTTLDATA_H
-#define EAS_RTTTLDATA_H
-
-#include "eas_data.h"
-
-
-/* maximum line size as specified in iMelody V1.2 spec */
-#define MAX_LINE_SIZE 75
-
-/*----------------------------------------------------------------------------
- *
- * S_RTTTL_DATA
- *
- * This structure contains the state data for the iMelody parser
- *----------------------------------------------------------------------------
-*/
-
-typedef struct
-{
- EAS_FILE_HANDLE fileHandle; /* file handle */
- S_SYNTH *pSynth; /* synthesizer handle */
- S_METADATA_CB metadata; /* metadata callback */
- EAS_I32 fileOffset; /* offset to start of data */
- EAS_I32 time; /* current time in 256ths of a msec */
- EAS_I32 tick; /* length of 32nd note in 256th of a msec */
- EAS_I32 restTicks; /* ticks to rest after current note */
- EAS_I32 repeatOffset; /* file offset to start of repeat section */
- EAS_U8 repeatCount; /* repeat counter */
- EAS_I8 dataByte; /* storage for characters that are "put back" */
- EAS_U8 state; /* current state EAS_STATE_XXXX */
- EAS_I8 style; /* from STYLE */
- EAS_U8 note; /* MIDI note number */
- EAS_U8 octave; /* decault octave prefix */
- EAS_I8 duration; /* default note duration */
-} S_RTTTL_DATA;
-
-#endif
-
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 82 $
+ * $Date: 2006-07-10 11:45:19 -0700 (Mon, 10 Jul 2006) $
+ *----------------------------------------------------------------------------
+*/
+
+#ifndef EAS_RTTTLDATA_H
+#define EAS_RTTTLDATA_H
+
+#include "eas_data.h"
+
+
+/* maximum line size as specified in iMelody V1.2 spec */
+#define MAX_LINE_SIZE 75
+
+/*----------------------------------------------------------------------------
+ *
+ * S_RTTTL_DATA
+ *
+ * This structure contains the state data for the iMelody parser
+ *----------------------------------------------------------------------------
+*/
+
+typedef struct
+{
+ EAS_FILE_HANDLE fileHandle; /* file handle */
+ S_SYNTH *pSynth; /* synthesizer handle */
+ S_METADATA_CB metadata; /* metadata callback */
+ EAS_I32 fileOffset; /* offset to start of data */
+ EAS_I32 time; /* current time in 256ths of a msec */
+ EAS_I32 tick; /* length of 32nd note in 256th of a msec */
+ EAS_I32 restTicks; /* ticks to rest after current note */
+ EAS_I32 repeatOffset; /* file offset to start of repeat section */
+ EAS_U8 repeatCount; /* repeat counter */
+ EAS_I8 dataByte; /* storage for characters that are "put back" */
+ EAS_U8 state; /* current state EAS_STATE_XXXX */
+ EAS_I8 style; /* from STYLE */
+ EAS_U8 note; /* MIDI note number */
+ EAS_U8 octave; /* decault octave prefix */
+ EAS_I8 duration; /* default note duration */
+} S_RTTTL_DATA;
+
+#endif
+
+
diff --git a/arm-hybrid-22k/lib_src/eas_smf.c b/arm-hybrid-22k/lib_src/eas_smf.c
index 7b56e97..e609583 100644
--- a/arm-hybrid-22k/lib_src/eas_smf.c
+++ b/arm-hybrid-22k/lib_src/eas_smf.c
@@ -1,14 +1,14 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_smf.c
- *
- * Contents and purpose:
- * SMF Type 0 and 1 File Parser
- *
- * For SMF timebase analysis, see "MIDI Sequencer Analysis.xls".
- *
- * Copyright Sonic Network Inc. 2005
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_smf.c
+ *
+ * Contents and purpose:
+ * SMF Type 0 and 1 File Parser
+ *
+ * For SMF timebase analysis, see "MIDI Sequencer Analysis.xls".
+ *
+ * Copyright Sonic Network Inc. 2005
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,1183 +21,1183 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 803 $
- * $Date: 2007-08-01 09:57:00 -0700 (Wed, 01 Aug 2007) $
- *----------------------------------------------------------------------------
-*/
-
-#include "eas_data.h"
-#include "eas_miditypes.h"
-#include "eas_parser.h"
-#include "eas_report.h"
-#include "eas_host.h"
-#include "eas_midi.h"
-#include "eas_config.h"
-#include "eas_vm_protos.h"
-#include "eas_smfdata.h"
-#include "eas_smf.h"
-
-#ifdef JET_INTERFACE
-#include "jet_data.h"
-#endif
-
-//3 dls: The timebase for this module is adequate to keep MIDI and
-//3 digital audio synchronized for only a few minutes. It should be
-//3 sufficient for most mobile applications. If better accuracy is
-//3 required, more fractional bits should be added to the timebase.
-
-static const EAS_U8 smfHeader[] = { 'M', 'T', 'h', 'd' };
-
-/* local prototypes */
-static EAS_RESULT SMF_GetVarLenData (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE fileHandle, EAS_U32 *pData);
-static EAS_RESULT SMF_ParseMetaEvent (S_EAS_DATA *pEASData, S_SMF_DATA *pSMFData, S_SMF_STREAM *pSMFStream);
-static EAS_RESULT SMF_ParseSysEx (S_EAS_DATA *pEASData, S_SMF_DATA *pSMFData, S_SMF_STREAM *pSMFStream, EAS_U8 f0, EAS_INT parserMode);
-static EAS_RESULT SMF_ParseEvent (S_EAS_DATA *pEASData, S_SMF_DATA *pSMFData, S_SMF_STREAM *pSMFStream, EAS_INT parserMode);
-static EAS_RESULT SMF_GetDeltaTime (EAS_HW_DATA_HANDLE hwInstData, S_SMF_STREAM *pSMFStream);
-static void SMF_UpdateTime (S_SMF_DATA *pSMFData, EAS_U32 ticks);
-
-
-/*----------------------------------------------------------------------------
- *
- * SMF_Parser
- *
- * This structure contains the functional interface for the SMF parser
- *----------------------------------------------------------------------------
-*/
-const S_FILE_PARSER_INTERFACE EAS_SMF_Parser =
-{
- SMF_CheckFileType,
- SMF_Prepare,
- SMF_Time,
- SMF_Event,
- SMF_State,
- SMF_Close,
- SMF_Reset,
- SMF_Pause,
- SMF_Resume,
- NULL,
- SMF_SetData,
- SMF_GetData,
- NULL
-};
-
-/*----------------------------------------------------------------------------
- * SMF_CheckFileType()
- *----------------------------------------------------------------------------
- * Purpose:
- * Check the file type to see if we can parse it
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT SMF_CheckFileType (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle, EAS_VOID_PTR *ppHandle, EAS_I32 offset)
-{
- S_SMF_DATA* pSMFData;
- EAS_RESULT result;
-
- /* seek to starting offset - usually 0 */
- *ppHandle = NULL;
- if ((result = EAS_HWFileSeek(pEASData->hwInstData, fileHandle, offset)) != EAS_SUCCESS)
- return result;
-
- /* search through file for header - slow method */
- if (pEASData->searchHeaderFlag)
- {
- result = EAS_SearchFile(pEASData, fileHandle, smfHeader, sizeof(smfHeader), &offset);
- if (result != EAS_SUCCESS)
- return (result == EAS_EOF) ? EAS_SUCCESS : result;
- }
-
- /* read the first 4 bytes of the file - quick method */
- else {
- EAS_U8 header[4];
- EAS_I32 count;
- if ((result = EAS_HWReadFile(pEASData->hwInstData, fileHandle, header, sizeof(header), &count)) != EAS_SUCCESS)
- return result;
-
- /* check for 'MTrk' - return if no match */
- if ((header[0] != 'M') || (header[1] != 'T') || (header[2] != 'h') || (header[3] != 'd'))
- return EAS_SUCCESS;
- }
-
- /* check for static memory allocation */
- if (pEASData->staticMemoryModel)
- pSMFData = EAS_CMEnumData(EAS_CM_SMF_DATA);
- else
- {
- pSMFData = EAS_HWMalloc(pEASData->hwInstData, sizeof(S_SMF_DATA));
- EAS_HWMemSet((void *)pSMFData,0, sizeof(S_SMF_DATA));
- }
- if (!pSMFData)
- return EAS_ERROR_MALLOC_FAILED;
-
- /* initialize some critical data */
- pSMFData->fileHandle = fileHandle;
- pSMFData->fileOffset = offset;
- pSMFData->pSynth = NULL;
- pSMFData->time = 0;
- pSMFData->state = EAS_STATE_OPEN;
- *ppHandle = pSMFData;
-
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * SMF_Prepare()
- *----------------------------------------------------------------------------
- * Purpose:
- * Prepare to parse the file. Allocates instance data (or uses static allocation for
- * static memory model).
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT SMF_Prepare (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
-{
- S_SMF_DATA* pSMFData;
- EAS_RESULT result;
-
- /* check for valid state */
- pSMFData = (S_SMF_DATA *) pInstData;
- if (pSMFData->state != EAS_STATE_OPEN)
- return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
-
- /* instantiate a synthesizer */
- if ((result = VMInitMIDI(pEASData, &pSMFData->pSynth)) != EAS_SUCCESS)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "VMInitMIDI returned %d\n", result); */ }
- return result;
- }
-
- /* parse the file header and setup the individual stream parsers */
- if ((result = SMF_ParseHeader(pEASData->hwInstData, pSMFData)) != EAS_SUCCESS)
- return result;
-
- /* ready to play */
- pSMFData->state = EAS_STATE_READY;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * SMF_Time()
- *----------------------------------------------------------------------------
- * Purpose:
- * Returns the time of the next event in msecs
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- * pTime - pointer to variable to hold time of next event (in msecs)
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, pEASData) reserved for future use */
-EAS_RESULT SMF_Time (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_U32 *pTime)
-{
- S_SMF_DATA *pSMFData;
-
- pSMFData = (S_SMF_DATA*) pInstData;
-
- /* sanity check */
-#ifdef _CHECKED_BUILD
- if (pSMFData->state == EAS_STATE_STOPPED)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Can't ask for time on a stopped stream\n"); */ }
- }
-
- if (pSMFData->nextStream == NULL)
- {
- { /* dpp: EAS_ReportEx( _EAS_SEVERITY_ERROR, "no is NULL\n"); */ }
- }
-#endif
-
-#if 0
- /* return time in milliseconds */
- /* if chase mode, lie about time */
- if (pSMFData->flags & SMF_FLAGS_CHASE_MODE)
- *pTime = 0;
-
- else
-#endif
-
- /*lint -e{704} use shift instead of division */
- *pTime = pSMFData->time >> 8;
-
- *pTime = pSMFData->time >> 8;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * SMF_Event()
- *----------------------------------------------------------------------------
- * Purpose:
- * Parse the next event in the file
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT SMF_Event (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_INT parserMode)
-{
- S_SMF_DATA* pSMFData;
- EAS_RESULT result;
- EAS_I32 i;
- EAS_U32 ticks;
- EAS_U32 temp;
-
- /* establish pointer to instance data */
- pSMFData = (S_SMF_DATA*) pInstData;
- if (pSMFData->state >= EAS_STATE_OPEN)
- return EAS_SUCCESS;
-
- /* get current ticks */
- ticks = pSMFData->nextStream->ticks;
-
- /* assume that an error occurred */
- pSMFData->state = EAS_STATE_ERROR;
-
-#ifdef JET_INTERFACE
- /* if JET has track muted, set parser mode to mute */
- if (pSMFData->nextStream->midiStream.jetData & MIDI_FLAGS_JET_MUTE)
- parserMode = eParserModeMute;
-#endif
-
- /* parse the next event from all the streams */
- if ((result = SMF_ParseEvent(pEASData, pSMFData, pSMFData->nextStream, parserMode)) != EAS_SUCCESS)
- {
- /* check for unexpected end-of-file */
- if (result != EAS_EOF)
- return result;
-
- /* indicate end of track for this stream */
- pSMFData->nextStream->ticks = SMF_END_OF_TRACK;
- }
-
- /* get next delta time, unless already at end of track */
- else if (pSMFData->nextStream->ticks != SMF_END_OF_TRACK)
- {
- if ((result = SMF_GetDeltaTime(pEASData->hwInstData, pSMFData->nextStream)) != EAS_SUCCESS)
- {
- /* check for unexpected end-of-file */
- if (result != EAS_EOF)
- return result;
-
- /* indicate end of track for this stream */
- pSMFData->nextStream->ticks = SMF_END_OF_TRACK;
- }
-
- /* if zero delta to next event, stay with this stream */
- else if (pSMFData->nextStream->ticks == ticks)
- {
- pSMFData->state = EAS_STATE_PLAY;
- return EAS_SUCCESS;
- }
- }
-
- /* find next event in all streams */
- temp = 0x7ffffff;
- pSMFData->nextStream = NULL;
- for (i = 0; i < pSMFData->numStreams; i++)
- {
- if (pSMFData->streams[i].ticks < temp)
- {
- temp = pSMFData->streams[i].ticks;
- pSMFData->nextStream = &pSMFData->streams[i];
- }
- }
-
- /* are there any more events to parse? */
- if (pSMFData->nextStream)
- {
- pSMFData->state = EAS_STATE_PLAY;
-
- /* update the time of the next event */
- SMF_UpdateTime(pSMFData, pSMFData->nextStream->ticks - ticks);
- }
- else
- {
- pSMFData->state = EAS_STATE_STOPPING;
- VMReleaseAllVoices(pEASData->pVoiceMgr, pSMFData->pSynth);
- }
-
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * SMF_State()
- *----------------------------------------------------------------------------
- * Purpose:
- * Returns the current state of the stream
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- * pState - pointer to variable to store state
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, pEASData) reserved for future use */
-EAS_RESULT SMF_State (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 *pState)
-{
- S_SMF_DATA* pSMFData;
-
- /* establish pointer to instance data */
- pSMFData = (S_SMF_DATA*) pInstData;
-
- /* if stopping, check to see if synth voices are active */
- if (pSMFData->state == EAS_STATE_STOPPING)
- {
- if (VMActiveVoices(pSMFData->pSynth) == 0)
- pSMFData->state = EAS_STATE_STOPPED;
- }
-
- if (pSMFData->state == EAS_STATE_PAUSING)
- {
- if (VMActiveVoices(pSMFData->pSynth) == 0)
- pSMFData->state = EAS_STATE_PAUSED;
- }
-
- /* return current state */
- *pState = pSMFData->state;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * SMF_Close()
- *----------------------------------------------------------------------------
- * Purpose:
- * Close the file and clean up
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT SMF_Close (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
-{
- S_SMF_DATA* pSMFData;
- EAS_I32 i;
- EAS_RESULT result;
-
- pSMFData = (S_SMF_DATA*) pInstData;
-
- /* close all the streams */
- for (i = 0; i < pSMFData->numStreams; i++)
- {
- if (pSMFData->streams[i].fileHandle != NULL)
- {
- if ((result = EAS_HWCloseFile(pEASData->hwInstData, pSMFData->streams[i].fileHandle)) != EAS_SUCCESS)
- return result;
- }
- }
- if (pSMFData->fileHandle != NULL)
- if ((result = EAS_HWCloseFile(pEASData->hwInstData, pSMFData->fileHandle)) != EAS_SUCCESS)
- return result;
-
- /* free the synth */
- if (pSMFData->pSynth != NULL)
- VMMIDIShutdown(pEASData, pSMFData->pSynth);
-
- /* if using dynamic memory, free it */
- if (!pEASData->staticMemoryModel)
- {
- if (pSMFData->streams)
- EAS_HWFree(pEASData->hwInstData, pSMFData->streams);
-
- /* free the instance data */
- EAS_HWFree(pEASData->hwInstData, pSMFData);
- }
-
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * SMF_Reset()
- *----------------------------------------------------------------------------
- * Purpose:
- * Reset the sequencer. Used for locating backwards in the file.
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT SMF_Reset (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
-{
- S_SMF_DATA* pSMFData;
- EAS_I32 i;
- EAS_RESULT result;
- EAS_U32 ticks;
-
- pSMFData = (S_SMF_DATA*) pInstData;
-
- /* reset time to zero */
- pSMFData->time = 0;
-
- /* reset the synth */
- VMReset(pEASData->pVoiceMgr, pSMFData->pSynth, EAS_TRUE);
-
- /* find the start of each track */
- ticks = 0x7fffffffL;
- pSMFData->nextStream = NULL;
- for (i = 0; i < pSMFData->numStreams; i++)
- {
-
- /* reset file position to first byte of data in track */
- if ((result = EAS_HWFileSeek(pEASData->hwInstData, pSMFData->streams[i].fileHandle, pSMFData->streams[i].startFilePos)) != EAS_SUCCESS)
- return result;
-
- /* initalize some data */
- pSMFData->streams[i].ticks = 0;
-
- /* initalize the MIDI parser data */
- EAS_InitMIDIStream(&pSMFData->streams[i].midiStream);
-
- /* parse the first delta time in each stream */
- if ((result = SMF_GetDeltaTime(pEASData->hwInstData,&pSMFData->streams[i])) != EAS_SUCCESS)
- return result;
- if (pSMFData->streams[i].ticks < ticks)
- {
- ticks = pSMFData->streams[i].ticks;
- pSMFData->nextStream = &pSMFData->streams[i];
- }
- }
-
-
- pSMFData->state = EAS_STATE_READY;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * SMF_Pause()
- *----------------------------------------------------------------------------
- * Purpose:
- * Pauses the sequencer. Mutes all voices and sets state to pause.
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT SMF_Pause (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
-{
- S_SMF_DATA *pSMFData;
-
- /* can't pause a stopped stream */
- pSMFData = (S_SMF_DATA*) pInstData;
- if (pSMFData->state == EAS_STATE_STOPPED)
- return EAS_ERROR_ALREADY_STOPPED;
-
- /* mute the synthesizer */
- VMMuteAllVoices(pEASData->pVoiceMgr, pSMFData->pSynth);
- pSMFData->state = EAS_STATE_PAUSING;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * SMF_Resume()
- *----------------------------------------------------------------------------
- * Purpose:
- * Resume playing after a pause, sets state back to playing.
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, pEASData) reserved for future use */
-EAS_RESULT SMF_Resume (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
-{
- S_SMF_DATA *pSMFData;
-
- /* can't resume a stopped stream */
- pSMFData = (S_SMF_DATA*) pInstData;
- if (pSMFData->state == EAS_STATE_STOPPED)
- return EAS_ERROR_ALREADY_STOPPED;
-
- /* nothing to do but resume playback */
- pSMFData->state = EAS_STATE_PLAY;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * SMF_SetData()
- *----------------------------------------------------------------------------
- * Purpose:
- * Sets parser parameters
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, pEASData) reserved for future use */
-EAS_RESULT SMF_SetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value)
-{
- S_SMF_DATA *pSMFData;
-
- pSMFData = (S_SMF_DATA*) pInstData;
- switch (param)
- {
-
- /* set metadata callback */
- case PARSER_DATA_METADATA_CB:
- EAS_HWMemCpy(&pSMFData->metadata, (void*) value, sizeof(S_METADATA_CB));
- break;
-
-#ifdef JET_INTERFACE
- /* set jet segment and track ID of all tracks for callback function */
- case PARSER_DATA_JET_CB:
- {
- EAS_U32 i;
- EAS_U32 bit = (EAS_U32) value;
- bit = (bit << JET_EVENT_SEG_SHIFT) & JET_EVENT_SEG_MASK;
- for (i = 0; i < pSMFData->numStreams; i++)
- pSMFData->streams[i].midiStream.jetData =
- (pSMFData->streams[i].midiStream.jetData &
- ~(JET_EVENT_TRACK_MASK | JET_EVENT_SEG_MASK)) |
- i << JET_EVENT_TRACK_SHIFT | bit | MIDI_FLAGS_JET_CB;
- pSMFData->flags |= SMF_FLAGS_JET_STREAM;
- }
- break;
-
- /* set state of all mute flags at once */
- case PARSER_DATA_MUTE_FLAGS:
- {
- EAS_INT i;
- EAS_U32 bit = (EAS_U32) value;
- for (i = 0; i < pSMFData->numStreams; i++)
- {
- if (bit & 1)
- pSMFData->streams[i].midiStream.jetData |= MIDI_FLAGS_JET_MUTE;
- else
- pSMFData->streams[i].midiStream.jetData &= ~MIDI_FLAGS_JET_MUTE;
- bit >>= 1;
- }
- }
- break;
-
- /* set track mute */
- case PARSER_DATA_SET_MUTE:
- if (value < pSMFData->numStreams)
- pSMFData->streams[value].midiStream.jetData |= MIDI_FLAGS_JET_MUTE;
- else
- return EAS_ERROR_PARAMETER_RANGE;
- break;
-
- /* clear track mute */
- case PARSER_DATA_CLEAR_MUTE:
- if (value < pSMFData->numStreams)
- pSMFData->streams[value].midiStream.jetData &= ~MIDI_FLAGS_JET_MUTE;
- else
- return EAS_ERROR_PARAMETER_RANGE;
- break;
-#endif
-
- default:
- return EAS_ERROR_INVALID_PARAMETER;
- }
-
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * SMF_GetData()
- *----------------------------------------------------------------------------
- * Purpose:
- * Retrieves parser parameters
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, pEASData) reserved for future use */
-EAS_RESULT SMF_GetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue)
-{
- S_SMF_DATA *pSMFData;
-
- pSMFData = (S_SMF_DATA*) pInstData;
- switch (param)
- {
- /* return file type */
- case PARSER_DATA_FILE_TYPE:
- if (pSMFData->numStreams == 1)
- *pValue = EAS_FILE_SMF0;
- else
- *pValue = EAS_FILE_SMF1;
- break;
-
-/* now handled in eas_public.c */
-#if 0
- case PARSER_DATA_POLYPHONY:
- if (pSMFData->pSynth)
- VMGetPolyphony(pEASData->pVoiceMgr, pSMFData->pSynth, pValue);
- else
- return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
- break;
-
- case PARSER_DATA_PRIORITY:
- if (pSMFData->pSynth)
- VMGetPriority(pEASData->pVoiceMgr, pSMFData->pSynth, pValue);
- break;
-
- /* set transposition */
- case PARSER_DATA_TRANSPOSITION:
- *pValue = pSMFData->transposition;
- break;
-#endif
-
- case PARSER_DATA_SYNTH_HANDLE:
- *pValue = (EAS_I32) pSMFData->pSynth;
- break;
-
- default:
- return EAS_ERROR_INVALID_PARAMETER;
- }
-
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * SMF_GetVarLenData()
- *----------------------------------------------------------------------------
- * Purpose:
- * Reads a varible length quantity from an SMF file
- *
- * Inputs:
- *
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT SMF_GetVarLenData (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE fileHandle, EAS_U32 *pData)
-{
- EAS_RESULT result;
- EAS_U32 data;
- EAS_U8 c;
-
- /* read until bit 7 is zero */
- data = 0;
- do
- {
- if ((result = EAS_HWGetByte(hwInstData, fileHandle,&c)) != EAS_SUCCESS)
- return result;
- data = (data << 7) | (c & 0x7f);
- } while (c & 0x80);
- *pData = data;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * SMF_GetDeltaTime()
- *----------------------------------------------------------------------------
- * Purpose:
- * Reads a varible length quantity from an SMF file
- *
- * Inputs:
- *
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT SMF_GetDeltaTime (EAS_HW_DATA_HANDLE hwInstData, S_SMF_STREAM *pSMFStream)
-{
- EAS_RESULT result;
- EAS_U32 ticks;
-
- if ((result = SMF_GetVarLenData(hwInstData, pSMFStream->fileHandle, &ticks)) != EAS_SUCCESS)
- return result;
-
- pSMFStream->ticks += ticks;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * SMF_ParseMetaEvent()
- *----------------------------------------------------------------------------
- * Purpose:
- * Reads a varible length quantity from an SMF file
- *
- * Inputs:
- *
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT SMF_ParseMetaEvent (S_EAS_DATA *pEASData, S_SMF_DATA *pSMFData, S_SMF_STREAM *pSMFStream)
-{
- EAS_RESULT result;
- EAS_U32 len;
- EAS_I32 pos;
- EAS_U32 temp;
- EAS_U8 c;
-
- /* get the meta-event type */
- if ((result = EAS_HWGetByte(pEASData->hwInstData, pSMFStream->fileHandle, &c)) != EAS_SUCCESS)
- return result;
-
- /* get the length */
- if ((result = SMF_GetVarLenData(pEASData->hwInstData, pSMFStream->fileHandle, &len)) != EAS_SUCCESS)
- return result;
-
- /* get the current file position so we can skip the event */
- if ((result = EAS_HWFilePos(pEASData->hwInstData, pSMFStream->fileHandle, &pos)) != EAS_SUCCESS)
- return result;
- pos += (EAS_I32) len;
-
- /* end of track? */
- if (c == SMF_META_END_OF_TRACK)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Meta-event: end of track\n", c, len); */ }
- pSMFStream->ticks = SMF_END_OF_TRACK;
- }
-
- /* tempo event? */
- else if (c == SMF_META_TEMPO)
- {
- /* read the 3-byte timebase value */
- temp = 0;
- while (len--)
- {
- if ((result = EAS_HWGetByte(pEASData->hwInstData, pSMFStream->fileHandle, &c)) != EAS_SUCCESS)
- return result;
- temp = (temp << 8) | c;
- }
-
- pSMFData->tickConv = (EAS_U16) (((temp * 1024) / pSMFData->ppqn + 500) / 1000);
- pSMFData->flags |= SMF_FLAGS_HAS_TEMPO;
- }
-
- /* check for time signature - see iMelody spec V1.4 section 4.1.2.2.3.6 */
- else if (c == SMF_META_TIME_SIGNATURE)
- {
- pSMFData->flags |= SMF_FLAGS_HAS_TIME_SIG;
- }
-
- /* if the host has registered a metadata callback return the metadata */
- else if (pSMFData->metadata.callback)
- {
- EAS_I32 readLen;
- E_EAS_METADATA_TYPE metaType;
-
- metaType = EAS_METADATA_UNKNOWN;
-
- /* only process title on the first track */
- if (c == SMF_META_SEQTRK_NAME)
- metaType = EAS_METADATA_TITLE;
- else if (c == SMF_META_TEXT)
- metaType = EAS_METADATA_TEXT;
- else if (c == SMF_META_COPYRIGHT)
- metaType = EAS_METADATA_COPYRIGHT;
- else if (c == SMF_META_LYRIC)
- metaType = EAS_METADATA_LYRIC;
-
- if (metaType != EAS_METADATA_UNKNOWN)
- {
- readLen = pSMFData->metadata.bufferSize - 1;
- if ((EAS_I32) len < readLen)
- readLen = (EAS_I32) len;
- if ((result = EAS_HWReadFile(pEASData->hwInstData, pSMFStream->fileHandle, pSMFData->metadata.buffer, readLen, &readLen)) != EAS_SUCCESS)
- return result;
- pSMFData->metadata.buffer[readLen] = 0;
- pSMFData->metadata.callback(metaType, pSMFData->metadata.buffer, pSMFData->metadata.pUserData);
- }
- }
-
- /* position file to next event - in case we ignored all or part of the meta-event */
- if ((result = EAS_HWFileSeek(pEASData->hwInstData, pSMFStream->fileHandle, pos)) != EAS_SUCCESS)
- return result;
-
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Meta-event: type=%02x, len=%d\n", c, len); */ }
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * SMF_ParseSysEx()
- *----------------------------------------------------------------------------
- * Purpose:
- * Reads a varible length quantity from an SMF file
- *
- * Inputs:
- *
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT SMF_ParseSysEx (S_EAS_DATA *pEASData, S_SMF_DATA *pSMFData, S_SMF_STREAM *pSMFStream, EAS_U8 f0, EAS_INT parserMode)
-{
- EAS_RESULT result;
- EAS_U32 len;
- EAS_U8 c;
-
- /* get the length */
- if ((result = SMF_GetVarLenData(pEASData->hwInstData, pSMFStream->fileHandle, &len)) != EAS_SUCCESS)
- return result;
-
- /* start of SysEx message? */
- if (f0 == 0xf0)
- {
- if ((result = EAS_ParseMIDIStream(pEASData, pSMFData->pSynth, &pSMFStream->midiStream, f0, parserMode)) != EAS_SUCCESS)
- return result;
- }
-
- /* feed the SysEx to the stream parser */
- while (len--)
- {
- if ((result = EAS_HWGetByte(pEASData->hwInstData, pSMFStream->fileHandle, &c)) != EAS_SUCCESS)
- return result;
- if ((result = EAS_ParseMIDIStream(pEASData, pSMFData->pSynth, &pSMFStream->midiStream, c, parserMode)) != EAS_SUCCESS)
- return result;
-
- /* check for GM system ON */
- if (pSMFStream->midiStream.flags & MIDI_FLAG_GM_ON)
- pSMFData->flags |= SMF_FLAGS_HAS_GM_ON;
- }
-
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * SMF_ParseEvent()
- *----------------------------------------------------------------------------
- * Purpose:
- * Reads a varible length quantity from an SMF file
- *
- * Inputs:
- *
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT SMF_ParseEvent (S_EAS_DATA *pEASData, S_SMF_DATA *pSMFData, S_SMF_STREAM *pSMFStream, EAS_INT parserMode)
-{
- EAS_RESULT result;
- EAS_U8 c;
-
- /* get the event type */
- if ((result = EAS_HWGetByte(pEASData->hwInstData, pSMFStream->fileHandle, &c)) != EAS_SUCCESS)
- return result;
-
- /* parse meta-event */
- if (c == 0xff)
- {
- if ((result = SMF_ParseMetaEvent(pEASData, pSMFData, pSMFStream)) != EAS_SUCCESS)
- return result;
- }
-
- /* parse SysEx */
- else if ((c == 0xf0) || (c == 0xf7))
- {
- if ((result = SMF_ParseSysEx(pEASData, pSMFData, pSMFStream, c, parserMode)) != EAS_SUCCESS)
- return result;
- }
-
- /* parse MIDI message */
- else
- {
- if ((result = EAS_ParseMIDIStream(pEASData, pSMFData->pSynth, &pSMFStream->midiStream, c, parserMode)) != EAS_SUCCESS)
- return result;
-
- /* keep streaming data to the MIDI parser until the message is complete */
- while (pSMFStream->midiStream.pending)
- {
- if ((result = EAS_HWGetByte(pEASData->hwInstData, pSMFStream->fileHandle, &c)) != EAS_SUCCESS)
- return result;
- if ((result = EAS_ParseMIDIStream(pEASData, pSMFData->pSynth, &pSMFStream->midiStream, c, parserMode)) != EAS_SUCCESS)
- return result;
- }
-
- }
-
- /* chase mode logic */
- if (pSMFData->time == 0)
- {
- if (pSMFData->flags & SMF_FLAGS_CHASE_MODE)
- {
- if (pSMFStream->midiStream.flags & MIDI_FLAG_FIRST_NOTE)
- pSMFData->flags &= ~SMF_FLAGS_CHASE_MODE;
- }
- else if ((pSMFData->flags & SMF_FLAGS_SETUP_BAR) == SMF_FLAGS_SETUP_BAR)
- pSMFData->flags = (pSMFData->flags & ~SMF_FLAGS_SETUP_BAR) | SMF_FLAGS_CHASE_MODE;
- }
-
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * SMF_ParseHeader()
- *----------------------------------------------------------------------------
- * Purpose:
- * Parses the header of an SMF file, allocates memory the stream parsers and initializes the
- * stream parsers.
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * pSMFData - pointer to parser instance data
- * fileHandle - file handle
- * fileOffset - offset in the file where the header data starts, usually 0
- *
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -e{801} we know that 'goto' is deprecated - but it's cleaner in this case */
-EAS_RESULT SMF_ParseHeader (EAS_HW_DATA_HANDLE hwInstData, S_SMF_DATA *pSMFData)
-{
- EAS_RESULT result;
- EAS_I32 i;
- EAS_U16 division;
- EAS_U32 chunkSize;
- EAS_U32 chunkStart;
- EAS_U32 temp;
- EAS_U32 ticks;
-
- /* rewind the file and find the end of the header chunk */
- if ((result = EAS_HWFileSeek(hwInstData, pSMFData->fileHandle, pSMFData->fileOffset + SMF_OFS_HEADER_SIZE)) != EAS_SUCCESS)
- goto ReadError;
- if ((result = EAS_HWGetDWord(hwInstData, pSMFData->fileHandle, &chunkSize, EAS_TRUE)) != EAS_SUCCESS)
- goto ReadError;
-
- /* determine the number of tracks */
- if ((result = EAS_HWFileSeek(hwInstData, pSMFData->fileHandle, pSMFData->fileOffset + SMF_OFS_NUM_TRACKS)) != EAS_SUCCESS)
- goto ReadError;
- if ((result = EAS_HWGetWord(hwInstData, pSMFData->fileHandle, &pSMFData->numStreams, EAS_TRUE)) != EAS_SUCCESS)
- goto ReadError;
-
- /* limit the number of tracks */
- if (pSMFData->numStreams > MAX_SMF_STREAMS)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "SMF file contains %u tracks, playing %d tracks\n", pSMFData->numStreams, MAX_SMF_STREAMS); */ }
- pSMFData->numStreams = MAX_SMF_STREAMS;
- }
-
- /* get the time division */
- if ((result = EAS_HWGetWord(hwInstData, pSMFData->fileHandle, &division, EAS_TRUE)) != EAS_SUCCESS)
- goto ReadError;
-
- /* setup default timebase for 120 bpm */
- pSMFData->ppqn = 192;
- if (division & 0x8000)
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING,"No support for SMPTE code timebase\n"); */ }
- else
- pSMFData->ppqn = (division & 0x7fff);
- pSMFData->tickConv = (EAS_U16) (((SMF_DEFAULT_TIMEBASE * 1024) / pSMFData->ppqn + 500) / 1000);
-
- /* dynamic memory allocation, allocate memory for streams */
- if (pSMFData->streams == NULL)
- {
- pSMFData->streams = EAS_HWMalloc(hwInstData,sizeof(S_SMF_STREAM) * pSMFData->numStreams);
- if (pSMFData->streams == NULL)
- return EAS_ERROR_MALLOC_FAILED;
-
- /* zero the memory to insure complete initialization */
- EAS_HWMemSet((void *)(pSMFData->streams), 0, sizeof(S_SMF_STREAM) * pSMFData->numStreams);
- }
-
- /* find the start of each track */
- chunkStart = (EAS_U32) pSMFData->fileOffset;
- ticks = 0x7fffffffL;
- pSMFData->nextStream = NULL;
- for (i = 0; i < pSMFData->numStreams; i++)
- {
-
- for (;;)
- {
-
- /* calculate start of next chunk - checking for errors */
- temp = chunkStart + SMF_CHUNK_INFO_SIZE + chunkSize;
- if (temp <= chunkStart)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING,"Error in chunk size at offset %d\n", chunkStart); */ }
- return EAS_ERROR_FILE_FORMAT;
- }
- chunkStart = temp;
-
- /* seek to the start of the next chunk */
- if ((result = EAS_HWFileSeek(hwInstData, pSMFData->fileHandle, (EAS_I32) chunkStart)) != EAS_SUCCESS)
- goto ReadError;
-
- /* read the chunk identifier */
- if ((result = EAS_HWGetDWord(hwInstData, pSMFData->fileHandle, &temp, EAS_TRUE)) != EAS_SUCCESS)
- goto ReadError;
-
- /* read the chunk size */
- if ((result = EAS_HWGetDWord(hwInstData, pSMFData->fileHandle, &chunkSize, EAS_TRUE)) != EAS_SUCCESS)
- goto ReadError;
-
- /* make sure this is an 'MTrk' chunk */
- if (temp == SMF_CHUNK_TYPE_TRACK)
- break;
-
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING,"Unexpected chunk type: 0x%08x\n", temp); */ }
- }
-
- /* initalize some data */
- pSMFData->streams[i].ticks = 0;
- pSMFData->streams[i].fileHandle = pSMFData->fileHandle;
-
- /* NULL the file handle so we don't try to close it twice */
- pSMFData->fileHandle = NULL;
-
- /* save this file position as the start of the track */
- pSMFData->streams[i].startFilePos = (EAS_I32) chunkStart + SMF_CHUNK_INFO_SIZE;
-
- /* initalize the MIDI parser data */
- EAS_InitMIDIStream(&pSMFData->streams[i].midiStream);
-
- /* parse the first delta time in each stream */
- if ((result = SMF_GetDeltaTime(hwInstData, &pSMFData->streams[i])) != EAS_SUCCESS)
- goto ReadError;
-
- if (pSMFData->streams[i].ticks < ticks)
- {
- ticks = pSMFData->streams[i].ticks;
- pSMFData->nextStream = &pSMFData->streams[i];
- }
-
- /* more tracks to do, create a duplicate file handle */
- if (i < (pSMFData->numStreams - 1))
- {
- if ((result = EAS_HWDupHandle(hwInstData, pSMFData->streams[i].fileHandle, &pSMFData->fileHandle)) != EAS_SUCCESS)
- goto ReadError;
- }
- }
-
- /* update the time of the next event */
- if (pSMFData->nextStream)
- SMF_UpdateTime(pSMFData, pSMFData->nextStream->ticks);
-
- return EAS_SUCCESS;
-
- /* ugly goto: but simpler than structured */
- ReadError:
- if (result == EAS_EOF)
- return EAS_ERROR_FILE_FORMAT;
- return result;
-}
-
-/*----------------------------------------------------------------------------
- * SMF_UpdateTime()
- *----------------------------------------------------------------------------
- * Purpose:
- * Update the millisecond time base by converting the ticks into millieconds
- *
- * Inputs:
- *
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static void SMF_UpdateTime (S_SMF_DATA *pSMFData, EAS_U32 ticks)
-{
- EAS_U32 temp1, temp2;
-
- if (pSMFData->flags & SMF_FLAGS_CHASE_MODE)
- return;
-
- temp1 = (ticks >> 10) * pSMFData->tickConv;
- temp2 = (ticks & 0x3ff) * pSMFData->tickConv;
- pSMFData->time += (EAS_I32)((temp1 << 8) + (temp2 >> 2));
-}
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 803 $
+ * $Date: 2007-08-01 09:57:00 -0700 (Wed, 01 Aug 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+#include "eas_data.h"
+#include "eas_miditypes.h"
+#include "eas_parser.h"
+#include "eas_report.h"
+#include "eas_host.h"
+#include "eas_midi.h"
+#include "eas_config.h"
+#include "eas_vm_protos.h"
+#include "eas_smfdata.h"
+#include "eas_smf.h"
+
+#ifdef JET_INTERFACE
+#include "jet_data.h"
+#endif
+
+//3 dls: The timebase for this module is adequate to keep MIDI and
+//3 digital audio synchronized for only a few minutes. It should be
+//3 sufficient for most mobile applications. If better accuracy is
+//3 required, more fractional bits should be added to the timebase.
+
+static const EAS_U8 smfHeader[] = { 'M', 'T', 'h', 'd' };
+
+/* local prototypes */
+static EAS_RESULT SMF_GetVarLenData (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE fileHandle, EAS_U32 *pData);
+static EAS_RESULT SMF_ParseMetaEvent (S_EAS_DATA *pEASData, S_SMF_DATA *pSMFData, S_SMF_STREAM *pSMFStream);
+static EAS_RESULT SMF_ParseSysEx (S_EAS_DATA *pEASData, S_SMF_DATA *pSMFData, S_SMF_STREAM *pSMFStream, EAS_U8 f0, EAS_INT parserMode);
+static EAS_RESULT SMF_ParseEvent (S_EAS_DATA *pEASData, S_SMF_DATA *pSMFData, S_SMF_STREAM *pSMFStream, EAS_INT parserMode);
+static EAS_RESULT SMF_GetDeltaTime (EAS_HW_DATA_HANDLE hwInstData, S_SMF_STREAM *pSMFStream);
+static void SMF_UpdateTime (S_SMF_DATA *pSMFData, EAS_U32 ticks);
+
+
+/*----------------------------------------------------------------------------
+ *
+ * SMF_Parser
+ *
+ * This structure contains the functional interface for the SMF parser
+ *----------------------------------------------------------------------------
+*/
+const S_FILE_PARSER_INTERFACE EAS_SMF_Parser =
+{
+ SMF_CheckFileType,
+ SMF_Prepare,
+ SMF_Time,
+ SMF_Event,
+ SMF_State,
+ SMF_Close,
+ SMF_Reset,
+ SMF_Pause,
+ SMF_Resume,
+ NULL,
+ SMF_SetData,
+ SMF_GetData,
+ NULL
+};
+
+/*----------------------------------------------------------------------------
+ * SMF_CheckFileType()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Check the file type to see if we can parse it
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT SMF_CheckFileType (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle, EAS_VOID_PTR *ppHandle, EAS_I32 offset)
+{
+ S_SMF_DATA* pSMFData;
+ EAS_RESULT result;
+
+ /* seek to starting offset - usually 0 */
+ *ppHandle = NULL;
+ if ((result = EAS_HWFileSeek(pEASData->hwInstData, fileHandle, offset)) != EAS_SUCCESS)
+ return result;
+
+ /* search through file for header - slow method */
+ if (pEASData->searchHeaderFlag)
+ {
+ result = EAS_SearchFile(pEASData, fileHandle, smfHeader, sizeof(smfHeader), &offset);
+ if (result != EAS_SUCCESS)
+ return (result == EAS_EOF) ? EAS_SUCCESS : result;
+ }
+
+ /* read the first 4 bytes of the file - quick method */
+ else {
+ EAS_U8 header[4];
+ EAS_I32 count;
+ if ((result = EAS_HWReadFile(pEASData->hwInstData, fileHandle, header, sizeof(header), &count)) != EAS_SUCCESS)
+ return result;
+
+ /* check for 'MTrk' - return if no match */
+ if ((header[0] != 'M') || (header[1] != 'T') || (header[2] != 'h') || (header[3] != 'd'))
+ return EAS_SUCCESS;
+ }
+
+ /* check for static memory allocation */
+ if (pEASData->staticMemoryModel)
+ pSMFData = EAS_CMEnumData(EAS_CM_SMF_DATA);
+ else
+ {
+ pSMFData = EAS_HWMalloc(pEASData->hwInstData, sizeof(S_SMF_DATA));
+ EAS_HWMemSet((void *)pSMFData,0, sizeof(S_SMF_DATA));
+ }
+ if (!pSMFData)
+ return EAS_ERROR_MALLOC_FAILED;
+
+ /* initialize some critical data */
+ pSMFData->fileHandle = fileHandle;
+ pSMFData->fileOffset = offset;
+ pSMFData->pSynth = NULL;
+ pSMFData->time = 0;
+ pSMFData->state = EAS_STATE_OPEN;
+ *ppHandle = pSMFData;
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * SMF_Prepare()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Prepare to parse the file. Allocates instance data (or uses static allocation for
+ * static memory model).
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT SMF_Prepare (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
+{
+ S_SMF_DATA* pSMFData;
+ EAS_RESULT result;
+
+ /* check for valid state */
+ pSMFData = (S_SMF_DATA *) pInstData;
+ if (pSMFData->state != EAS_STATE_OPEN)
+ return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
+
+ /* instantiate a synthesizer */
+ if ((result = VMInitMIDI(pEASData, &pSMFData->pSynth)) != EAS_SUCCESS)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "VMInitMIDI returned %d\n", result); */ }
+ return result;
+ }
+
+ /* parse the file header and setup the individual stream parsers */
+ if ((result = SMF_ParseHeader(pEASData->hwInstData, pSMFData)) != EAS_SUCCESS)
+ return result;
+
+ /* ready to play */
+ pSMFData->state = EAS_STATE_READY;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * SMF_Time()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Returns the time of the next event in msecs
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ * pTime - pointer to variable to hold time of next event (in msecs)
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pEASData) reserved for future use */
+EAS_RESULT SMF_Time (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_U32 *pTime)
+{
+ S_SMF_DATA *pSMFData;
+
+ pSMFData = (S_SMF_DATA*) pInstData;
+
+ /* sanity check */
+#ifdef _CHECKED_BUILD
+ if (pSMFData->state == EAS_STATE_STOPPED)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Can't ask for time on a stopped stream\n"); */ }
+ }
+
+ if (pSMFData->nextStream == NULL)
+ {
+ { /* dpp: EAS_ReportEx( _EAS_SEVERITY_ERROR, "no is NULL\n"); */ }
+ }
+#endif
+
+#if 0
+ /* return time in milliseconds */
+ /* if chase mode, lie about time */
+ if (pSMFData->flags & SMF_FLAGS_CHASE_MODE)
+ *pTime = 0;
+
+ else
+#endif
+
+ /*lint -e{704} use shift instead of division */
+ *pTime = pSMFData->time >> 8;
+
+ *pTime = pSMFData->time >> 8;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * SMF_Event()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Parse the next event in the file
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT SMF_Event (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_INT parserMode)
+{
+ S_SMF_DATA* pSMFData;
+ EAS_RESULT result;
+ EAS_I32 i;
+ EAS_U32 ticks;
+ EAS_U32 temp;
+
+ /* establish pointer to instance data */
+ pSMFData = (S_SMF_DATA*) pInstData;
+ if (pSMFData->state >= EAS_STATE_OPEN)
+ return EAS_SUCCESS;
+
+ /* get current ticks */
+ ticks = pSMFData->nextStream->ticks;
+
+ /* assume that an error occurred */
+ pSMFData->state = EAS_STATE_ERROR;
+
+#ifdef JET_INTERFACE
+ /* if JET has track muted, set parser mode to mute */
+ if (pSMFData->nextStream->midiStream.jetData & MIDI_FLAGS_JET_MUTE)
+ parserMode = eParserModeMute;
+#endif
+
+ /* parse the next event from all the streams */
+ if ((result = SMF_ParseEvent(pEASData, pSMFData, pSMFData->nextStream, parserMode)) != EAS_SUCCESS)
+ {
+ /* check for unexpected end-of-file */
+ if (result != EAS_EOF)
+ return result;
+
+ /* indicate end of track for this stream */
+ pSMFData->nextStream->ticks = SMF_END_OF_TRACK;
+ }
+
+ /* get next delta time, unless already at end of track */
+ else if (pSMFData->nextStream->ticks != SMF_END_OF_TRACK)
+ {
+ if ((result = SMF_GetDeltaTime(pEASData->hwInstData, pSMFData->nextStream)) != EAS_SUCCESS)
+ {
+ /* check for unexpected end-of-file */
+ if (result != EAS_EOF)
+ return result;
+
+ /* indicate end of track for this stream */
+ pSMFData->nextStream->ticks = SMF_END_OF_TRACK;
+ }
+
+ /* if zero delta to next event, stay with this stream */
+ else if (pSMFData->nextStream->ticks == ticks)
+ {
+ pSMFData->state = EAS_STATE_PLAY;
+ return EAS_SUCCESS;
+ }
+ }
+
+ /* find next event in all streams */
+ temp = 0x7ffffff;
+ pSMFData->nextStream = NULL;
+ for (i = 0; i < pSMFData->numStreams; i++)
+ {
+ if (pSMFData->streams[i].ticks < temp)
+ {
+ temp = pSMFData->streams[i].ticks;
+ pSMFData->nextStream = &pSMFData->streams[i];
+ }
+ }
+
+ /* are there any more events to parse? */
+ if (pSMFData->nextStream)
+ {
+ pSMFData->state = EAS_STATE_PLAY;
+
+ /* update the time of the next event */
+ SMF_UpdateTime(pSMFData, pSMFData->nextStream->ticks - ticks);
+ }
+ else
+ {
+ pSMFData->state = EAS_STATE_STOPPING;
+ VMReleaseAllVoices(pEASData->pVoiceMgr, pSMFData->pSynth);
+ }
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * SMF_State()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Returns the current state of the stream
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ * pState - pointer to variable to store state
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pEASData) reserved for future use */
+EAS_RESULT SMF_State (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 *pState)
+{
+ S_SMF_DATA* pSMFData;
+
+ /* establish pointer to instance data */
+ pSMFData = (S_SMF_DATA*) pInstData;
+
+ /* if stopping, check to see if synth voices are active */
+ if (pSMFData->state == EAS_STATE_STOPPING)
+ {
+ if (VMActiveVoices(pSMFData->pSynth) == 0)
+ pSMFData->state = EAS_STATE_STOPPED;
+ }
+
+ if (pSMFData->state == EAS_STATE_PAUSING)
+ {
+ if (VMActiveVoices(pSMFData->pSynth) == 0)
+ pSMFData->state = EAS_STATE_PAUSED;
+ }
+
+ /* return current state */
+ *pState = pSMFData->state;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * SMF_Close()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Close the file and clean up
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT SMF_Close (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
+{
+ S_SMF_DATA* pSMFData;
+ EAS_I32 i;
+ EAS_RESULT result;
+
+ pSMFData = (S_SMF_DATA*) pInstData;
+
+ /* close all the streams */
+ for (i = 0; i < pSMFData->numStreams; i++)
+ {
+ if (pSMFData->streams[i].fileHandle != NULL)
+ {
+ if ((result = EAS_HWCloseFile(pEASData->hwInstData, pSMFData->streams[i].fileHandle)) != EAS_SUCCESS)
+ return result;
+ }
+ }
+ if (pSMFData->fileHandle != NULL)
+ if ((result = EAS_HWCloseFile(pEASData->hwInstData, pSMFData->fileHandle)) != EAS_SUCCESS)
+ return result;
+
+ /* free the synth */
+ if (pSMFData->pSynth != NULL)
+ VMMIDIShutdown(pEASData, pSMFData->pSynth);
+
+ /* if using dynamic memory, free it */
+ if (!pEASData->staticMemoryModel)
+ {
+ if (pSMFData->streams)
+ EAS_HWFree(pEASData->hwInstData, pSMFData->streams);
+
+ /* free the instance data */
+ EAS_HWFree(pEASData->hwInstData, pSMFData);
+ }
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * SMF_Reset()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Reset the sequencer. Used for locating backwards in the file.
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT SMF_Reset (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
+{
+ S_SMF_DATA* pSMFData;
+ EAS_I32 i;
+ EAS_RESULT result;
+ EAS_U32 ticks;
+
+ pSMFData = (S_SMF_DATA*) pInstData;
+
+ /* reset time to zero */
+ pSMFData->time = 0;
+
+ /* reset the synth */
+ VMReset(pEASData->pVoiceMgr, pSMFData->pSynth, EAS_TRUE);
+
+ /* find the start of each track */
+ ticks = 0x7fffffffL;
+ pSMFData->nextStream = NULL;
+ for (i = 0; i < pSMFData->numStreams; i++)
+ {
+
+ /* reset file position to first byte of data in track */
+ if ((result = EAS_HWFileSeek(pEASData->hwInstData, pSMFData->streams[i].fileHandle, pSMFData->streams[i].startFilePos)) != EAS_SUCCESS)
+ return result;
+
+ /* initalize some data */
+ pSMFData->streams[i].ticks = 0;
+
+ /* initalize the MIDI parser data */
+ EAS_InitMIDIStream(&pSMFData->streams[i].midiStream);
+
+ /* parse the first delta time in each stream */
+ if ((result = SMF_GetDeltaTime(pEASData->hwInstData,&pSMFData->streams[i])) != EAS_SUCCESS)
+ return result;
+ if (pSMFData->streams[i].ticks < ticks)
+ {
+ ticks = pSMFData->streams[i].ticks;
+ pSMFData->nextStream = &pSMFData->streams[i];
+ }
+ }
+
+
+ pSMFData->state = EAS_STATE_READY;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * SMF_Pause()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Pauses the sequencer. Mutes all voices and sets state to pause.
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT SMF_Pause (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
+{
+ S_SMF_DATA *pSMFData;
+
+ /* can't pause a stopped stream */
+ pSMFData = (S_SMF_DATA*) pInstData;
+ if (pSMFData->state == EAS_STATE_STOPPED)
+ return EAS_ERROR_ALREADY_STOPPED;
+
+ /* mute the synthesizer */
+ VMMuteAllVoices(pEASData->pVoiceMgr, pSMFData->pSynth);
+ pSMFData->state = EAS_STATE_PAUSING;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * SMF_Resume()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Resume playing after a pause, sets state back to playing.
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pEASData) reserved for future use */
+EAS_RESULT SMF_Resume (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
+{
+ S_SMF_DATA *pSMFData;
+
+ /* can't resume a stopped stream */
+ pSMFData = (S_SMF_DATA*) pInstData;
+ if (pSMFData->state == EAS_STATE_STOPPED)
+ return EAS_ERROR_ALREADY_STOPPED;
+
+ /* nothing to do but resume playback */
+ pSMFData->state = EAS_STATE_PLAY;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * SMF_SetData()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Sets parser parameters
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pEASData) reserved for future use */
+EAS_RESULT SMF_SetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value)
+{
+ S_SMF_DATA *pSMFData;
+
+ pSMFData = (S_SMF_DATA*) pInstData;
+ switch (param)
+ {
+
+ /* set metadata callback */
+ case PARSER_DATA_METADATA_CB:
+ EAS_HWMemCpy(&pSMFData->metadata, (void*) value, sizeof(S_METADATA_CB));
+ break;
+
+#ifdef JET_INTERFACE
+ /* set jet segment and track ID of all tracks for callback function */
+ case PARSER_DATA_JET_CB:
+ {
+ EAS_U32 i;
+ EAS_U32 bit = (EAS_U32) value;
+ bit = (bit << JET_EVENT_SEG_SHIFT) & JET_EVENT_SEG_MASK;
+ for (i = 0; i < pSMFData->numStreams; i++)
+ pSMFData->streams[i].midiStream.jetData =
+ (pSMFData->streams[i].midiStream.jetData &
+ ~(JET_EVENT_TRACK_MASK | JET_EVENT_SEG_MASK)) |
+ i << JET_EVENT_TRACK_SHIFT | bit | MIDI_FLAGS_JET_CB;
+ pSMFData->flags |= SMF_FLAGS_JET_STREAM;
+ }
+ break;
+
+ /* set state of all mute flags at once */
+ case PARSER_DATA_MUTE_FLAGS:
+ {
+ EAS_INT i;
+ EAS_U32 bit = (EAS_U32) value;
+ for (i = 0; i < pSMFData->numStreams; i++)
+ {
+ if (bit & 1)
+ pSMFData->streams[i].midiStream.jetData |= MIDI_FLAGS_JET_MUTE;
+ else
+ pSMFData->streams[i].midiStream.jetData &= ~MIDI_FLAGS_JET_MUTE;
+ bit >>= 1;
+ }
+ }
+ break;
+
+ /* set track mute */
+ case PARSER_DATA_SET_MUTE:
+ if (value < pSMFData->numStreams)
+ pSMFData->streams[value].midiStream.jetData |= MIDI_FLAGS_JET_MUTE;
+ else
+ return EAS_ERROR_PARAMETER_RANGE;
+ break;
+
+ /* clear track mute */
+ case PARSER_DATA_CLEAR_MUTE:
+ if (value < pSMFData->numStreams)
+ pSMFData->streams[value].midiStream.jetData &= ~MIDI_FLAGS_JET_MUTE;
+ else
+ return EAS_ERROR_PARAMETER_RANGE;
+ break;
+#endif
+
+ default:
+ return EAS_ERROR_INVALID_PARAMETER;
+ }
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * SMF_GetData()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Retrieves parser parameters
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pEASData) reserved for future use */
+EAS_RESULT SMF_GetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue)
+{
+ S_SMF_DATA *pSMFData;
+
+ pSMFData = (S_SMF_DATA*) pInstData;
+ switch (param)
+ {
+ /* return file type */
+ case PARSER_DATA_FILE_TYPE:
+ if (pSMFData->numStreams == 1)
+ *pValue = EAS_FILE_SMF0;
+ else
+ *pValue = EAS_FILE_SMF1;
+ break;
+
+/* now handled in eas_public.c */
+#if 0
+ case PARSER_DATA_POLYPHONY:
+ if (pSMFData->pSynth)
+ VMGetPolyphony(pEASData->pVoiceMgr, pSMFData->pSynth, pValue);
+ else
+ return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
+ break;
+
+ case PARSER_DATA_PRIORITY:
+ if (pSMFData->pSynth)
+ VMGetPriority(pEASData->pVoiceMgr, pSMFData->pSynth, pValue);
+ break;
+
+ /* set transposition */
+ case PARSER_DATA_TRANSPOSITION:
+ *pValue = pSMFData->transposition;
+ break;
+#endif
+
+ case PARSER_DATA_SYNTH_HANDLE:
+ *pValue = (EAS_I32) pSMFData->pSynth;
+ break;
+
+ default:
+ return EAS_ERROR_INVALID_PARAMETER;
+ }
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * SMF_GetVarLenData()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Reads a varible length quantity from an SMF file
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT SMF_GetVarLenData (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE fileHandle, EAS_U32 *pData)
+{
+ EAS_RESULT result;
+ EAS_U32 data;
+ EAS_U8 c;
+
+ /* read until bit 7 is zero */
+ data = 0;
+ do
+ {
+ if ((result = EAS_HWGetByte(hwInstData, fileHandle,&c)) != EAS_SUCCESS)
+ return result;
+ data = (data << 7) | (c & 0x7f);
+ } while (c & 0x80);
+ *pData = data;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * SMF_GetDeltaTime()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Reads a varible length quantity from an SMF file
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT SMF_GetDeltaTime (EAS_HW_DATA_HANDLE hwInstData, S_SMF_STREAM *pSMFStream)
+{
+ EAS_RESULT result;
+ EAS_U32 ticks;
+
+ if ((result = SMF_GetVarLenData(hwInstData, pSMFStream->fileHandle, &ticks)) != EAS_SUCCESS)
+ return result;
+
+ pSMFStream->ticks += ticks;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * SMF_ParseMetaEvent()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Reads a varible length quantity from an SMF file
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT SMF_ParseMetaEvent (S_EAS_DATA *pEASData, S_SMF_DATA *pSMFData, S_SMF_STREAM *pSMFStream)
+{
+ EAS_RESULT result;
+ EAS_U32 len;
+ EAS_I32 pos;
+ EAS_U32 temp;
+ EAS_U8 c;
+
+ /* get the meta-event type */
+ if ((result = EAS_HWGetByte(pEASData->hwInstData, pSMFStream->fileHandle, &c)) != EAS_SUCCESS)
+ return result;
+
+ /* get the length */
+ if ((result = SMF_GetVarLenData(pEASData->hwInstData, pSMFStream->fileHandle, &len)) != EAS_SUCCESS)
+ return result;
+
+ /* get the current file position so we can skip the event */
+ if ((result = EAS_HWFilePos(pEASData->hwInstData, pSMFStream->fileHandle, &pos)) != EAS_SUCCESS)
+ return result;
+ pos += (EAS_I32) len;
+
+ /* end of track? */
+ if (c == SMF_META_END_OF_TRACK)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Meta-event: end of track\n", c, len); */ }
+ pSMFStream->ticks = SMF_END_OF_TRACK;
+ }
+
+ /* tempo event? */
+ else if (c == SMF_META_TEMPO)
+ {
+ /* read the 3-byte timebase value */
+ temp = 0;
+ while (len--)
+ {
+ if ((result = EAS_HWGetByte(pEASData->hwInstData, pSMFStream->fileHandle, &c)) != EAS_SUCCESS)
+ return result;
+ temp = (temp << 8) | c;
+ }
+
+ pSMFData->tickConv = (EAS_U16) (((temp * 1024) / pSMFData->ppqn + 500) / 1000);
+ pSMFData->flags |= SMF_FLAGS_HAS_TEMPO;
+ }
+
+ /* check for time signature - see iMelody spec V1.4 section 4.1.2.2.3.6 */
+ else if (c == SMF_META_TIME_SIGNATURE)
+ {
+ pSMFData->flags |= SMF_FLAGS_HAS_TIME_SIG;
+ }
+
+ /* if the host has registered a metadata callback return the metadata */
+ else if (pSMFData->metadata.callback)
+ {
+ EAS_I32 readLen;
+ E_EAS_METADATA_TYPE metaType;
+
+ metaType = EAS_METADATA_UNKNOWN;
+
+ /* only process title on the first track */
+ if (c == SMF_META_SEQTRK_NAME)
+ metaType = EAS_METADATA_TITLE;
+ else if (c == SMF_META_TEXT)
+ metaType = EAS_METADATA_TEXT;
+ else if (c == SMF_META_COPYRIGHT)
+ metaType = EAS_METADATA_COPYRIGHT;
+ else if (c == SMF_META_LYRIC)
+ metaType = EAS_METADATA_LYRIC;
+
+ if (metaType != EAS_METADATA_UNKNOWN)
+ {
+ readLen = pSMFData->metadata.bufferSize - 1;
+ if ((EAS_I32) len < readLen)
+ readLen = (EAS_I32) len;
+ if ((result = EAS_HWReadFile(pEASData->hwInstData, pSMFStream->fileHandle, pSMFData->metadata.buffer, readLen, &readLen)) != EAS_SUCCESS)
+ return result;
+ pSMFData->metadata.buffer[readLen] = 0;
+ pSMFData->metadata.callback(metaType, pSMFData->metadata.buffer, pSMFData->metadata.pUserData);
+ }
+ }
+
+ /* position file to next event - in case we ignored all or part of the meta-event */
+ if ((result = EAS_HWFileSeek(pEASData->hwInstData, pSMFStream->fileHandle, pos)) != EAS_SUCCESS)
+ return result;
+
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Meta-event: type=%02x, len=%d\n", c, len); */ }
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * SMF_ParseSysEx()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Reads a varible length quantity from an SMF file
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT SMF_ParseSysEx (S_EAS_DATA *pEASData, S_SMF_DATA *pSMFData, S_SMF_STREAM *pSMFStream, EAS_U8 f0, EAS_INT parserMode)
+{
+ EAS_RESULT result;
+ EAS_U32 len;
+ EAS_U8 c;
+
+ /* get the length */
+ if ((result = SMF_GetVarLenData(pEASData->hwInstData, pSMFStream->fileHandle, &len)) != EAS_SUCCESS)
+ return result;
+
+ /* start of SysEx message? */
+ if (f0 == 0xf0)
+ {
+ if ((result = EAS_ParseMIDIStream(pEASData, pSMFData->pSynth, &pSMFStream->midiStream, f0, parserMode)) != EAS_SUCCESS)
+ return result;
+ }
+
+ /* feed the SysEx to the stream parser */
+ while (len--)
+ {
+ if ((result = EAS_HWGetByte(pEASData->hwInstData, pSMFStream->fileHandle, &c)) != EAS_SUCCESS)
+ return result;
+ if ((result = EAS_ParseMIDIStream(pEASData, pSMFData->pSynth, &pSMFStream->midiStream, c, parserMode)) != EAS_SUCCESS)
+ return result;
+
+ /* check for GM system ON */
+ if (pSMFStream->midiStream.flags & MIDI_FLAG_GM_ON)
+ pSMFData->flags |= SMF_FLAGS_HAS_GM_ON;
+ }
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * SMF_ParseEvent()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Reads a varible length quantity from an SMF file
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT SMF_ParseEvent (S_EAS_DATA *pEASData, S_SMF_DATA *pSMFData, S_SMF_STREAM *pSMFStream, EAS_INT parserMode)
+{
+ EAS_RESULT result;
+ EAS_U8 c;
+
+ /* get the event type */
+ if ((result = EAS_HWGetByte(pEASData->hwInstData, pSMFStream->fileHandle, &c)) != EAS_SUCCESS)
+ return result;
+
+ /* parse meta-event */
+ if (c == 0xff)
+ {
+ if ((result = SMF_ParseMetaEvent(pEASData, pSMFData, pSMFStream)) != EAS_SUCCESS)
+ return result;
+ }
+
+ /* parse SysEx */
+ else if ((c == 0xf0) || (c == 0xf7))
+ {
+ if ((result = SMF_ParseSysEx(pEASData, pSMFData, pSMFStream, c, parserMode)) != EAS_SUCCESS)
+ return result;
+ }
+
+ /* parse MIDI message */
+ else
+ {
+ if ((result = EAS_ParseMIDIStream(pEASData, pSMFData->pSynth, &pSMFStream->midiStream, c, parserMode)) != EAS_SUCCESS)
+ return result;
+
+ /* keep streaming data to the MIDI parser until the message is complete */
+ while (pSMFStream->midiStream.pending)
+ {
+ if ((result = EAS_HWGetByte(pEASData->hwInstData, pSMFStream->fileHandle, &c)) != EAS_SUCCESS)
+ return result;
+ if ((result = EAS_ParseMIDIStream(pEASData, pSMFData->pSynth, &pSMFStream->midiStream, c, parserMode)) != EAS_SUCCESS)
+ return result;
+ }
+
+ }
+
+ /* chase mode logic */
+ if (pSMFData->time == 0)
+ {
+ if (pSMFData->flags & SMF_FLAGS_CHASE_MODE)
+ {
+ if (pSMFStream->midiStream.flags & MIDI_FLAG_FIRST_NOTE)
+ pSMFData->flags &= ~SMF_FLAGS_CHASE_MODE;
+ }
+ else if ((pSMFData->flags & SMF_FLAGS_SETUP_BAR) == SMF_FLAGS_SETUP_BAR)
+ pSMFData->flags = (pSMFData->flags & ~SMF_FLAGS_SETUP_BAR) | SMF_FLAGS_CHASE_MODE;
+ }
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * SMF_ParseHeader()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Parses the header of an SMF file, allocates memory the stream parsers and initializes the
+ * stream parsers.
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * pSMFData - pointer to parser instance data
+ * fileHandle - file handle
+ * fileOffset - offset in the file where the header data starts, usually 0
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -e{801} we know that 'goto' is deprecated - but it's cleaner in this case */
+EAS_RESULT SMF_ParseHeader (EAS_HW_DATA_HANDLE hwInstData, S_SMF_DATA *pSMFData)
+{
+ EAS_RESULT result;
+ EAS_I32 i;
+ EAS_U16 division;
+ EAS_U32 chunkSize;
+ EAS_U32 chunkStart;
+ EAS_U32 temp;
+ EAS_U32 ticks;
+
+ /* rewind the file and find the end of the header chunk */
+ if ((result = EAS_HWFileSeek(hwInstData, pSMFData->fileHandle, pSMFData->fileOffset + SMF_OFS_HEADER_SIZE)) != EAS_SUCCESS)
+ goto ReadError;
+ if ((result = EAS_HWGetDWord(hwInstData, pSMFData->fileHandle, &chunkSize, EAS_TRUE)) != EAS_SUCCESS)
+ goto ReadError;
+
+ /* determine the number of tracks */
+ if ((result = EAS_HWFileSeek(hwInstData, pSMFData->fileHandle, pSMFData->fileOffset + SMF_OFS_NUM_TRACKS)) != EAS_SUCCESS)
+ goto ReadError;
+ if ((result = EAS_HWGetWord(hwInstData, pSMFData->fileHandle, &pSMFData->numStreams, EAS_TRUE)) != EAS_SUCCESS)
+ goto ReadError;
+
+ /* limit the number of tracks */
+ if (pSMFData->numStreams > MAX_SMF_STREAMS)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "SMF file contains %u tracks, playing %d tracks\n", pSMFData->numStreams, MAX_SMF_STREAMS); */ }
+ pSMFData->numStreams = MAX_SMF_STREAMS;
+ }
+
+ /* get the time division */
+ if ((result = EAS_HWGetWord(hwInstData, pSMFData->fileHandle, &division, EAS_TRUE)) != EAS_SUCCESS)
+ goto ReadError;
+
+ /* setup default timebase for 120 bpm */
+ pSMFData->ppqn = 192;
+ if (division & 0x8000)
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING,"No support for SMPTE code timebase\n"); */ }
+ else
+ pSMFData->ppqn = (division & 0x7fff);
+ pSMFData->tickConv = (EAS_U16) (((SMF_DEFAULT_TIMEBASE * 1024) / pSMFData->ppqn + 500) / 1000);
+
+ /* dynamic memory allocation, allocate memory for streams */
+ if (pSMFData->streams == NULL)
+ {
+ pSMFData->streams = EAS_HWMalloc(hwInstData,sizeof(S_SMF_STREAM) * pSMFData->numStreams);
+ if (pSMFData->streams == NULL)
+ return EAS_ERROR_MALLOC_FAILED;
+
+ /* zero the memory to insure complete initialization */
+ EAS_HWMemSet((void *)(pSMFData->streams), 0, sizeof(S_SMF_STREAM) * pSMFData->numStreams);
+ }
+
+ /* find the start of each track */
+ chunkStart = (EAS_U32) pSMFData->fileOffset;
+ ticks = 0x7fffffffL;
+ pSMFData->nextStream = NULL;
+ for (i = 0; i < pSMFData->numStreams; i++)
+ {
+
+ for (;;)
+ {
+
+ /* calculate start of next chunk - checking for errors */
+ temp = chunkStart + SMF_CHUNK_INFO_SIZE + chunkSize;
+ if (temp <= chunkStart)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING,"Error in chunk size at offset %d\n", chunkStart); */ }
+ return EAS_ERROR_FILE_FORMAT;
+ }
+ chunkStart = temp;
+
+ /* seek to the start of the next chunk */
+ if ((result = EAS_HWFileSeek(hwInstData, pSMFData->fileHandle, (EAS_I32) chunkStart)) != EAS_SUCCESS)
+ goto ReadError;
+
+ /* read the chunk identifier */
+ if ((result = EAS_HWGetDWord(hwInstData, pSMFData->fileHandle, &temp, EAS_TRUE)) != EAS_SUCCESS)
+ goto ReadError;
+
+ /* read the chunk size */
+ if ((result = EAS_HWGetDWord(hwInstData, pSMFData->fileHandle, &chunkSize, EAS_TRUE)) != EAS_SUCCESS)
+ goto ReadError;
+
+ /* make sure this is an 'MTrk' chunk */
+ if (temp == SMF_CHUNK_TYPE_TRACK)
+ break;
+
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING,"Unexpected chunk type: 0x%08x\n", temp); */ }
+ }
+
+ /* initalize some data */
+ pSMFData->streams[i].ticks = 0;
+ pSMFData->streams[i].fileHandle = pSMFData->fileHandle;
+
+ /* NULL the file handle so we don't try to close it twice */
+ pSMFData->fileHandle = NULL;
+
+ /* save this file position as the start of the track */
+ pSMFData->streams[i].startFilePos = (EAS_I32) chunkStart + SMF_CHUNK_INFO_SIZE;
+
+ /* initalize the MIDI parser data */
+ EAS_InitMIDIStream(&pSMFData->streams[i].midiStream);
+
+ /* parse the first delta time in each stream */
+ if ((result = SMF_GetDeltaTime(hwInstData, &pSMFData->streams[i])) != EAS_SUCCESS)
+ goto ReadError;
+
+ if (pSMFData->streams[i].ticks < ticks)
+ {
+ ticks = pSMFData->streams[i].ticks;
+ pSMFData->nextStream = &pSMFData->streams[i];
+ }
+
+ /* more tracks to do, create a duplicate file handle */
+ if (i < (pSMFData->numStreams - 1))
+ {
+ if ((result = EAS_HWDupHandle(hwInstData, pSMFData->streams[i].fileHandle, &pSMFData->fileHandle)) != EAS_SUCCESS)
+ goto ReadError;
+ }
+ }
+
+ /* update the time of the next event */
+ if (pSMFData->nextStream)
+ SMF_UpdateTime(pSMFData, pSMFData->nextStream->ticks);
+
+ return EAS_SUCCESS;
+
+ /* ugly goto: but simpler than structured */
+ ReadError:
+ if (result == EAS_EOF)
+ return EAS_ERROR_FILE_FORMAT;
+ return result;
+}
+
+/*----------------------------------------------------------------------------
+ * SMF_UpdateTime()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Update the millisecond time base by converting the ticks into millieconds
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static void SMF_UpdateTime (S_SMF_DATA *pSMFData, EAS_U32 ticks)
+{
+ EAS_U32 temp1, temp2;
+
+ if (pSMFData->flags & SMF_FLAGS_CHASE_MODE)
+ return;
+
+ temp1 = (ticks >> 10) * pSMFData->tickConv;
+ temp2 = (ticks & 0x3ff) * pSMFData->tickConv;
+ pSMFData->time += (EAS_I32)((temp1 << 8) + (temp2 >> 2));
+}
+
diff --git a/arm-hybrid-22k/lib_src/eas_smf.h b/arm-hybrid-22k/lib_src/eas_smf.h
index 9f66ab9..37c0790 100644
--- a/arm-hybrid-22k/lib_src/eas_smf.h
+++ b/arm-hybrid-22k/lib_src/eas_smf.h
@@ -1,12 +1,12 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_smf.h
- *
- * Contents and purpose:
- * SMF Type 0 and 1 File Parser
- *
- * Copyright Sonic Network Inc. 2005
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_smf.h
+ *
+ * Contents and purpose:
+ * SMF Type 0 and 1 File Parser
+ *
+ * Copyright Sonic Network Inc. 2005
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,31 +19,31 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 82 $
- * $Date: 2006-07-10 11:45:19 -0700 (Mon, 10 Jul 2006) $
- *----------------------------------------------------------------------------
-*/
-
-#ifndef _EAS_SMF_H
-#define _EAS_SMF_H
-
-/* prototypes for private interface to SMF parser */
-EAS_RESULT SMF_CheckFileType (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle, EAS_VOID_PTR *ppHandle, EAS_I32 offset);
-EAS_RESULT SMF_Prepare (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
-EAS_RESULT SMF_Time (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_U32 *pTime);
-EAS_RESULT SMF_Event (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_INT parserMode);
-EAS_RESULT SMF_State (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_STATE *pState);
-EAS_RESULT SMF_Close (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
-EAS_RESULT SMF_Reset (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
-EAS_RESULT SMF_Pause (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
-EAS_RESULT SMF_Resume (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
-EAS_RESULT SMF_SetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value);
-EAS_RESULT SMF_GetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue);
-EAS_RESULT SMF_ParseHeader (EAS_HW_DATA_HANDLE hwInstData, S_SMF_DATA *pSMFData);
-
-#endif /* end _EAS_SMF_H */
-
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 82 $
+ * $Date: 2006-07-10 11:45:19 -0700 (Mon, 10 Jul 2006) $
+ *----------------------------------------------------------------------------
+*/
+
+#ifndef _EAS_SMF_H
+#define _EAS_SMF_H
+
+/* prototypes for private interface to SMF parser */
+EAS_RESULT SMF_CheckFileType (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle, EAS_VOID_PTR *ppHandle, EAS_I32 offset);
+EAS_RESULT SMF_Prepare (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
+EAS_RESULT SMF_Time (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_U32 *pTime);
+EAS_RESULT SMF_Event (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_INT parserMode);
+EAS_RESULT SMF_State (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_STATE *pState);
+EAS_RESULT SMF_Close (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
+EAS_RESULT SMF_Reset (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
+EAS_RESULT SMF_Pause (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
+EAS_RESULT SMF_Resume (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
+EAS_RESULT SMF_SetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value);
+EAS_RESULT SMF_GetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue);
+EAS_RESULT SMF_ParseHeader (EAS_HW_DATA_HANDLE hwInstData, S_SMF_DATA *pSMFData);
+
+#endif /* end _EAS_SMF_H */
+
+
diff --git a/arm-hybrid-22k/lib_src/eas_smfdata.c b/arm-hybrid-22k/lib_src/eas_smfdata.c
index 5c27551..383d7f3 100644
--- a/arm-hybrid-22k/lib_src/eas_smfdata.c
+++ b/arm-hybrid-22k/lib_src/eas_smfdata.c
@@ -1,14 +1,14 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_smfdata.c
- *
- * Contents and purpose:
- * SMF File Parser
- *
- * This file contains data definitions for the SMF parser.
- *
- * Copyright Sonic Network Inc. 2005
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_smfdata.c
+ *
+ * Contents and purpose:
+ * SMF File Parser
+ *
+ * This file contains data definitions for the SMF parser.
+ *
+ * Copyright Sonic Network Inc. 2005
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,46 +21,46 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 778 $
- * $Date: 2007-07-23 16:45:17 -0700 (Mon, 23 Jul 2007) $
- *----------------------------------------------------------------------------
-*/
-
-#include "eas_miditypes.h"
-#include "eas_smfdata.h"
-
-/*----------------------------------------------------------------------------
- *
- * S_SMF_STREAM
- *
- * Static memory allocation for SMF parser
- *----------------------------------------------------------------------------
-*/
-static S_SMF_STREAM eas_SMFStreams[MAX_SMF_STREAMS];
-
-/*----------------------------------------------------------------------------
- *
- * eas_SMFData
- *
- * Static memory allocation for SMF parser
- *----------------------------------------------------------------------------
-*/
-S_SMF_DATA eas_SMFData =
-{
- eas_SMFStreams, /* pointer to individual streams in file */
- 0, /* pointer to next stream with event */
- 0, /* pointer to synth */
- 0, /* file handle */
- { 0, 0, 0, 0}, /* metadata callback */
- 0, /* file offset */
- 0, /* current time in milliseconds/256 */
- 0, /* actual number of streams */
- 0, /* current MIDI tick to msec conversion */
- 0, /* ticks per quarter note */
- 0, /* current state EAS_STATE_XXXX */
- 0 /* flags */
-};
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 778 $
+ * $Date: 2007-07-23 16:45:17 -0700 (Mon, 23 Jul 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+#include "eas_miditypes.h"
+#include "eas_smfdata.h"
+
+/*----------------------------------------------------------------------------
+ *
+ * S_SMF_STREAM
+ *
+ * Static memory allocation for SMF parser
+ *----------------------------------------------------------------------------
+*/
+static S_SMF_STREAM eas_SMFStreams[MAX_SMF_STREAMS];
+
+/*----------------------------------------------------------------------------
+ *
+ * eas_SMFData
+ *
+ * Static memory allocation for SMF parser
+ *----------------------------------------------------------------------------
+*/
+S_SMF_DATA eas_SMFData =
+{
+ eas_SMFStreams, /* pointer to individual streams in file */
+ 0, /* pointer to next stream with event */
+ 0, /* pointer to synth */
+ 0, /* file handle */
+ { 0, 0, 0, 0}, /* metadata callback */
+ 0, /* file offset */
+ 0, /* current time in milliseconds/256 */
+ 0, /* actual number of streams */
+ 0, /* current MIDI tick to msec conversion */
+ 0, /* ticks per quarter note */
+ 0, /* current state EAS_STATE_XXXX */
+ 0 /* flags */
+};
+
diff --git a/arm-hybrid-22k/lib_src/eas_smfdata.h b/arm-hybrid-22k/lib_src/eas_smfdata.h
index cf59cdc..8861d90 100644
--- a/arm-hybrid-22k/lib_src/eas_smfdata.h
+++ b/arm-hybrid-22k/lib_src/eas_smfdata.h
@@ -1,14 +1,14 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_smfdata.h
- *
- * Contents and purpose:
- * SMF File Parser
- *
- * This file contains data definitions for the SMF parser.
- *
- * Copyright Sonic Network Inc. 2005
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_smfdata.h
+ *
+ * Contents and purpose:
+ * SMF File Parser
+ *
+ * This file contains data definitions for the SMF parser.
+ *
+ * Copyright Sonic Network Inc. 2005
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,46 +21,46 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 686 $
- * $Date: 2007-05-03 14:10:54 -0700 (Thu, 03 May 2007) $
- *----------------------------------------------------------------------------
-*/
-
-#ifndef _EAS_SMF_DATA_H
-#define _EAS_SMF_DATA_H
-
-#ifndef MAX_SMF_STREAMS
-#define MAX_SMF_STREAMS 17
-#endif
-
-/* offsets in to the SMF file */
-#define SMF_OFS_HEADER_SIZE 4
-#define SMF_OFS_FILE_TYPE 8
-#define SMF_OFS_NUM_TRACKS 10
-
-/* size of chunk info (chunk ID + chunk size) */
-#define SMF_CHUNK_INFO_SIZE 8
-
-/* 'MTrk' track chunk ID */
-#define SMF_CHUNK_TYPE_TRACK 0x4d54726bL
-
-/* some useful meta-events */
-#define SMF_META_TEXT 0x01
-#define SMF_META_COPYRIGHT 0x02
-#define SMF_META_SEQTRK_NAME 0x03
-#define SMF_META_LYRIC 0x05
-#define SMF_META_END_OF_TRACK 0x2f
-#define SMF_META_TEMPO 0x51
-#define SMF_META_TIME_SIGNATURE 0x58
-
-/* default timebase (120BPM) */
-#define SMF_DEFAULT_TIMEBASE 500000L
-
-/* value for pSMFStream->ticks to signify end of track */
-#define SMF_END_OF_TRACK 0xffffffff
-
-#endif
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 686 $
+ * $Date: 2007-05-03 14:10:54 -0700 (Thu, 03 May 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+#ifndef _EAS_SMF_DATA_H
+#define _EAS_SMF_DATA_H
+
+#ifndef MAX_SMF_STREAMS
+#define MAX_SMF_STREAMS 17
+#endif
+
+/* offsets in to the SMF file */
+#define SMF_OFS_HEADER_SIZE 4
+#define SMF_OFS_FILE_TYPE 8
+#define SMF_OFS_NUM_TRACKS 10
+
+/* size of chunk info (chunk ID + chunk size) */
+#define SMF_CHUNK_INFO_SIZE 8
+
+/* 'MTrk' track chunk ID */
+#define SMF_CHUNK_TYPE_TRACK 0x4d54726bL
+
+/* some useful meta-events */
+#define SMF_META_TEXT 0x01
+#define SMF_META_COPYRIGHT 0x02
+#define SMF_META_SEQTRK_NAME 0x03
+#define SMF_META_LYRIC 0x05
+#define SMF_META_END_OF_TRACK 0x2f
+#define SMF_META_TEMPO 0x51
+#define SMF_META_TIME_SIGNATURE 0x58
+
+/* default timebase (120BPM) */
+#define SMF_DEFAULT_TIMEBASE 500000L
+
+/* value for pSMFStream->ticks to signify end of track */
+#define SMF_END_OF_TRACK 0xffffffff
+
+#endif
+
diff --git a/arm-hybrid-22k/lib_src/eas_sndlib.h b/arm-hybrid-22k/lib_src/eas_sndlib.h
index e05bee0..416be6e 100644
--- a/arm-hybrid-22k/lib_src/eas_sndlib.h
+++ b/arm-hybrid-22k/lib_src/eas_sndlib.h
@@ -1,12 +1,12 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_sndlib.h
- *
- * Contents and purpose:
- * Declarations for the sound library
- *
- * Copyright Sonic Network Inc. 2005
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_sndlib.h
+ *
+ * Contents and purpose:
+ * Declarations for the sound library
+ *
+ * Copyright Sonic Network Inc. 2005
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,388 +19,388 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 550 $
- * $Date: 2007-02-02 09:37:03 -0800 (Fri, 02 Feb 2007) $
- *----------------------------------------------------------------------------
-*/
-
-#ifndef _EAS_SNDLIB_H
-#define _EAS_SNDLIB_H
-
-#include "eas_types.h"
-#include "eas_synthcfg.h"
-
-#ifdef _WT_SYNTH
-#include "eas_wtengine.h"
-#endif
-
-/*----------------------------------------------------------------------------
- * This is bit of a hack to allow us to keep the same structure
- * declarations for the DLS parser. Normally, the data is located
- * in read-only memory, but for DLS, we store the data in RW
- * memory.
- *----------------------------------------------------------------------------
-*/
-#ifndef SCNST
-#define SCNST const
-#endif
-
-/*----------------------------------------------------------------------------
- * sample size
- *----------------------------------------------------------------------------
-*/
-#ifdef _16_BIT_SAMPLES
-typedef EAS_I16 EAS_SAMPLE;
-#else
-typedef EAS_I8 EAS_SAMPLE;
-#endif
-
-/*----------------------------------------------------------------------------
- * EAS Library ID - quick check for valid library and version
- *----------------------------------------------------------------------------
-*/
-#define _EAS_LIBRARY_VERSION 0x01534145
-
-#define NUM_PROGRAMS_IN_BANK 128
-#define INVALID_REGION_INDEX 0xffff
-
-/* this bit in region index indicates that region is for secondary synth */
-#define FLAG_RGN_IDX_FM_SYNTH 0x8000
-#define FLAG_RGN_IDX_DLS_SYNTH 0x4000
-#define REGION_INDEX_MASK 0x3fff
-
-/*----------------------------------------------------------------------------
- * Generic region data structure
- *
- * This must be the first element in each region structure
- *----------------------------------------------------------------------------
-*/
-typedef struct s_region_tag
-{
- EAS_U16 keyGroupAndFlags;
- EAS_U8 rangeLow;
- EAS_U8 rangeHigh;
-} S_REGION;
-
-/*
- * Bit fields for m_nKeyGroupAndFlags
- * Bits 0-2 are mode bits in FM synth
- * Bits 8-11 are the key group
- */
-#define REGION_FLAG_IS_LOOPED 0x01
-#define REGION_FLAG_USE_WAVE_GENERATOR 0x02
-#define REGION_FLAG_USE_ADPCM 0x04
-#define REGION_FLAG_ONE_SHOT 0x08
-#define REGION_FLAG_SQUARE_WAVE 0x10
-#define REGION_FLAG_OFF_CHIP 0x20
-#define REGION_FLAG_NON_SELF_EXCLUSIVE 0x40
-#define REGION_FLAG_LAST_REGION 0x8000
-
-/*----------------------------------------------------------------------------
- * Envelope data structure
- *----------------------------------------------------------------------------
-*/
-typedef struct s_envelope_tag
-{
- EAS_I16 attackTime;
- EAS_I16 decayTime;
- EAS_I16 sustainLevel;
- EAS_I16 releaseTime;
-} S_ENVELOPE;
-
-/*----------------------------------------------------------------------------
- * DLS envelope data structure
- *----------------------------------------------------------------------------
-*/
-typedef struct s_dls_envelope_tag
-{
- EAS_I16 delayTime;
- EAS_I16 attackTime;
- EAS_I16 holdTime;
- EAS_I16 decayTime;
- EAS_I16 sustainLevel;
- EAS_I16 releaseTime;
- EAS_I16 velToAttack;
- EAS_I16 keyNumToDecay;
- EAS_I16 keyNumToHold;
-} S_DLS_ENVELOPE;
-
-/*----------------------------------------------------------------------------
- * LFO data structure
- *----------------------------------------------------------------------------
-*/
-typedef struct s_lfo_params_tag
-{
- EAS_I16 lfoFreq;
- EAS_I16 lfoDelay;
-} S_LFO_PARAMS;
-
-/*----------------------------------------------------------------------------
- * Articulation data structure
- *----------------------------------------------------------------------------
-*/
-typedef struct s_articulation_tag
-{
- S_ENVELOPE eg1;
- S_ENVELOPE eg2;
- EAS_I16 lfoToPitch;
- EAS_I16 lfoDelay;
- EAS_I16 lfoFreq;
- EAS_I16 eg2ToPitch;
- EAS_I16 eg2ToFc;
- EAS_I16 filterCutoff;
- EAS_I8 lfoToGain;
- EAS_U8 filterQ;
- EAS_I8 pan;
-} S_ARTICULATION;
-
-/*----------------------------------------------------------------------------
- * DLS articulation data structure
- *----------------------------------------------------------------------------
-*/
-
-typedef struct s_dls_articulation_tag
-{
- S_LFO_PARAMS modLFO;
- S_LFO_PARAMS vibLFO;
-
- S_DLS_ENVELOPE eg1;
- S_DLS_ENVELOPE eg2;
-
- EAS_I16 eg1ShutdownTime;
-
- EAS_I16 filterCutoff;
- EAS_I16 modLFOToFc;
- EAS_I16 modLFOCC1ToFc;
- EAS_I16 modLFOChanPressToFc;
- EAS_I16 eg2ToFc;
- EAS_I16 velToFc;
- EAS_I16 keyNumToFc;
-
- EAS_I16 modLFOToGain;
- EAS_I16 modLFOCC1ToGain;
- EAS_I16 modLFOChanPressToGain;
-
- EAS_I16 tuning;
- EAS_I16 keyNumToPitch;
- EAS_I16 vibLFOToPitch;
- EAS_I16 vibLFOCC1ToPitch;
- EAS_I16 vibLFOChanPressToPitch;
- EAS_I16 modLFOToPitch;
- EAS_I16 modLFOCC1ToPitch;
- EAS_I16 modLFOChanPressToPitch;
- EAS_I16 eg2ToPitch;
-
- /* pad to 4-byte boundary */
- EAS_U16 pad;
-
- EAS_I8 pan;
- EAS_U8 filterQandFlags;
-
-#ifdef _REVERB
- EAS_I16 reverbSend;
- EAS_I16 cc91ToReverbSend;
-#endif
-
-#ifdef _CHORUS
- EAS_I16 chorusSend;
- EAS_I16 cc93ToChorusSend;
-#endif
-} S_DLS_ARTICULATION;
-
-/* flags in filterQandFlags
- * NOTE: Q is stored in bottom 5 bits
- */
-#define FLAG_DLS_VELOCITY_SENSITIVE 0x80
-#define FILTER_Q_MASK 0x1f
-
-/*----------------------------------------------------------------------------
- * Wavetable region data structure
- *----------------------------------------------------------------------------
-*/
-typedef struct s_wt_region_tag
-{
- S_REGION region;
- EAS_I16 tuning;
- EAS_I16 gain;
- EAS_U32 loopStart;
- EAS_U32 loopEnd;
- EAS_U16 waveIndex;
- EAS_U16 artIndex;
-} S_WT_REGION;
-
-/*----------------------------------------------------------------------------
- * DLS region data structure
- *----------------------------------------------------------------------------
-*/
-typedef struct s_dls_region_tag
-{
- S_WT_REGION wtRegion;
- EAS_U8 velLow;
- EAS_U8 velHigh;
-} S_DLS_REGION;
-
-/*----------------------------------------------------------------------------
- * FM synthesizer data structures
- *----------------------------------------------------------------------------
-*/
-typedef struct s_fm_oper_tag
-{
- EAS_I16 tuning;
- EAS_U8 attackDecay;
- EAS_U8 velocityRelease;
- EAS_U8 egKeyScale;
- EAS_U8 sustain;
- EAS_U8 gain;
- EAS_U8 flags;
-} S_FM_OPER;
-
-/* defines for S_FM_OPER.m_nFlags */
-#define FM_OPER_FLAG_MONOTONE 0x01
-#define FM_OPER_FLAG_NO_VIBRATO 0x02
-#define FM_OPER_FLAG_NOISE 0x04
-#define FM_OPER_FLAG_LINEAR_VELOCITY 0x08
-
-/* NOTE: The first two structure elements are common with S_WT_REGION
- * and we will rely on that in the voice management code and must
- * remain there unless the voice management code is revisited.
- */
-typedef struct s_fm_region_tag
-{
- S_REGION region;
- EAS_U8 vibTrem;
- EAS_U8 lfoFreqDelay;
- EAS_U8 feedback;
- EAS_I8 pan;
- S_FM_OPER oper[4];
-} S_FM_REGION;
-
-/*----------------------------------------------------------------------------
- * Common data structures
- *----------------------------------------------------------------------------
-*/
-
-/*----------------------------------------------------------------------------
- * Program data structure
- * Used for individual programs not stored as a complete bank.
- *----------------------------------------------------------------------------
-*/
-typedef struct s_program_tag
-{
- EAS_U32 locale;
- EAS_U16 regionIndex;
-} S_PROGRAM;
-
-/*----------------------------------------------------------------------------
- * Bank data structure
- *
- * A bank always consists of 128 programs. If a bank is less than 128
- * programs, it should be stored as a spare matrix in the pPrograms
- * array.
- *
- * bankNum: MSB/LSB of MIDI bank select controller
- * regionIndex: Index of first region in program
- *----------------------------------------------------------------------------
-*/
-typedef struct s_bank_tag
-{
- EAS_U16 locale;
- EAS_U16 regionIndex[NUM_PROGRAMS_IN_BANK];
-} S_BANK;
-
-
-/* defines for libFormat field
- * bits 0-17 are the sample rate
- * bit 18 is true if wavetable is present
- * bit 19 is true if FM is present
- * bit 20 is true if filter is enabled
- * bit 21 is sample depth (0 = 8-bits, 1 = 16-bits)
- * bits 22-31 are reserved
- */
-#define LIBFORMAT_SAMPLE_RATE_MASK 0x0003ffff
-#define LIB_FORMAT_TYPE_MASK 0x000c0000
-#define LIB_FORMAT_WAVETABLE 0x00000000
-#define LIB_FORMAT_FM 0x00040000
-#define LIB_FORMAT_HYBRID 0x00080000
-#define LIB_FORMAT_FILTER_ENABLED 0x00100000
-#define LIB_FORMAT_16_BIT_SAMPLES 0x00200000
-
-#ifdef DLS_SYNTHESIZER
-/*----------------------------------------------------------------------------
- * DLS data structure
- *
- * pDLSPrograms pointer to array of DLS programs
- * pDLSRegions pointer to array of DLS regions
- * pDLSArticulations pointer to array of DLS articulations
- * pSampleLen pointer to array of sample lengths
- * ppSamples pointer to array of sample pointers
- * numDLSPrograms number of DLS programs
- * numDLSRegions number of DLS regions
- * numDLSArticulations number of DLS articulations
- * numDLSSamples number of DLS samples
- *----------------------------------------------------------------------------
-*/
-typedef struct s_eas_dls_tag
-{
- S_PROGRAM *pDLSPrograms;
- S_DLS_REGION *pDLSRegions;
- S_DLS_ARTICULATION *pDLSArticulations;
- EAS_U32 *pDLSSampleLen;
- EAS_U32 *pDLSSampleOffsets;
- EAS_SAMPLE *pDLSSamples;
- EAS_U16 numDLSPrograms;
- EAS_U16 numDLSRegions;
- EAS_U16 numDLSArticulations;
- EAS_U16 numDLSSamples;
- EAS_U8 refCount;
-} S_DLS;
-#endif
-
-/*----------------------------------------------------------------------------
- * Sound library data structure
- *
- * pBanks pointer to array of banks
- * pPrograms pointer to array of programs
- * pWTRegions pointer to array of wavetable regions
- * pFMRegions pointer to array of FM regions
- * pArticulations pointer to array of articulations
- * pSampleLen pointer to array of sample lengths
- * ppSamples pointer to array of sample pointers
- * numBanks number of banks
- * numPrograms number of individual program
- * numRegions number of regions
- * numArticulations number of articulations
- * numSamples number of samples
- *----------------------------------------------------------------------------
-*/
-typedef struct s_eas_sndlib_tag
-{
- SCNST EAS_U32 identifier;
- SCNST EAS_U32 libAttr;
-
- SCNST S_BANK *pBanks;
- SCNST S_PROGRAM *pPrograms;
-
- SCNST S_WT_REGION *pWTRegions;
- SCNST S_ARTICULATION *pArticulations;
- SCNST EAS_U32 *pSampleLen;
- SCNST EAS_U32 *pSampleOffsets;
- SCNST EAS_SAMPLE *pSamples;
-
- SCNST S_FM_REGION *pFMRegions;
-
- SCNST EAS_U16 numBanks;
- SCNST EAS_U16 numPrograms;
-
- SCNST EAS_U16 numWTRegions;
- SCNST EAS_U16 numArticulations;
- SCNST EAS_U16 numSamples;
-
- SCNST EAS_U16 numFMRegions;
-} S_EAS;
-
-#endif
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 550 $
+ * $Date: 2007-02-02 09:37:03 -0800 (Fri, 02 Feb 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+#ifndef _EAS_SNDLIB_H
+#define _EAS_SNDLIB_H
+
+#include "eas_types.h"
+#include "eas_synthcfg.h"
+
+#ifdef _WT_SYNTH
+#include "eas_wtengine.h"
+#endif
+
+/*----------------------------------------------------------------------------
+ * This is bit of a hack to allow us to keep the same structure
+ * declarations for the DLS parser. Normally, the data is located
+ * in read-only memory, but for DLS, we store the data in RW
+ * memory.
+ *----------------------------------------------------------------------------
+*/
+#ifndef SCNST
+#define SCNST const
+#endif
+
+/*----------------------------------------------------------------------------
+ * sample size
+ *----------------------------------------------------------------------------
+*/
+#ifdef _16_BIT_SAMPLES
+typedef EAS_I16 EAS_SAMPLE;
+#else
+typedef EAS_I8 EAS_SAMPLE;
+#endif
+
+/*----------------------------------------------------------------------------
+ * EAS Library ID - quick check for valid library and version
+ *----------------------------------------------------------------------------
+*/
+#define _EAS_LIBRARY_VERSION 0x01534145
+
+#define NUM_PROGRAMS_IN_BANK 128
+#define INVALID_REGION_INDEX 0xffff
+
+/* this bit in region index indicates that region is for secondary synth */
+#define FLAG_RGN_IDX_FM_SYNTH 0x8000
+#define FLAG_RGN_IDX_DLS_SYNTH 0x4000
+#define REGION_INDEX_MASK 0x3fff
+
+/*----------------------------------------------------------------------------
+ * Generic region data structure
+ *
+ * This must be the first element in each region structure
+ *----------------------------------------------------------------------------
+*/
+typedef struct s_region_tag
+{
+ EAS_U16 keyGroupAndFlags;
+ EAS_U8 rangeLow;
+ EAS_U8 rangeHigh;
+} S_REGION;
+
+/*
+ * Bit fields for m_nKeyGroupAndFlags
+ * Bits 0-2 are mode bits in FM synth
+ * Bits 8-11 are the key group
+ */
+#define REGION_FLAG_IS_LOOPED 0x01
+#define REGION_FLAG_USE_WAVE_GENERATOR 0x02
+#define REGION_FLAG_USE_ADPCM 0x04
+#define REGION_FLAG_ONE_SHOT 0x08
+#define REGION_FLAG_SQUARE_WAVE 0x10
+#define REGION_FLAG_OFF_CHIP 0x20
+#define REGION_FLAG_NON_SELF_EXCLUSIVE 0x40
+#define REGION_FLAG_LAST_REGION 0x8000
+
+/*----------------------------------------------------------------------------
+ * Envelope data structure
+ *----------------------------------------------------------------------------
+*/
+typedef struct s_envelope_tag
+{
+ EAS_I16 attackTime;
+ EAS_I16 decayTime;
+ EAS_I16 sustainLevel;
+ EAS_I16 releaseTime;
+} S_ENVELOPE;
+
+/*----------------------------------------------------------------------------
+ * DLS envelope data structure
+ *----------------------------------------------------------------------------
+*/
+typedef struct s_dls_envelope_tag
+{
+ EAS_I16 delayTime;
+ EAS_I16 attackTime;
+ EAS_I16 holdTime;
+ EAS_I16 decayTime;
+ EAS_I16 sustainLevel;
+ EAS_I16 releaseTime;
+ EAS_I16 velToAttack;
+ EAS_I16 keyNumToDecay;
+ EAS_I16 keyNumToHold;
+} S_DLS_ENVELOPE;
+
+/*----------------------------------------------------------------------------
+ * LFO data structure
+ *----------------------------------------------------------------------------
+*/
+typedef struct s_lfo_params_tag
+{
+ EAS_I16 lfoFreq;
+ EAS_I16 lfoDelay;
+} S_LFO_PARAMS;
+
+/*----------------------------------------------------------------------------
+ * Articulation data structure
+ *----------------------------------------------------------------------------
+*/
+typedef struct s_articulation_tag
+{
+ S_ENVELOPE eg1;
+ S_ENVELOPE eg2;
+ EAS_I16 lfoToPitch;
+ EAS_I16 lfoDelay;
+ EAS_I16 lfoFreq;
+ EAS_I16 eg2ToPitch;
+ EAS_I16 eg2ToFc;
+ EAS_I16 filterCutoff;
+ EAS_I8 lfoToGain;
+ EAS_U8 filterQ;
+ EAS_I8 pan;
+} S_ARTICULATION;
+
+/*----------------------------------------------------------------------------
+ * DLS articulation data structure
+ *----------------------------------------------------------------------------
+*/
+
+typedef struct s_dls_articulation_tag
+{
+ S_LFO_PARAMS modLFO;
+ S_LFO_PARAMS vibLFO;
+
+ S_DLS_ENVELOPE eg1;
+ S_DLS_ENVELOPE eg2;
+
+ EAS_I16 eg1ShutdownTime;
+
+ EAS_I16 filterCutoff;
+ EAS_I16 modLFOToFc;
+ EAS_I16 modLFOCC1ToFc;
+ EAS_I16 modLFOChanPressToFc;
+ EAS_I16 eg2ToFc;
+ EAS_I16 velToFc;
+ EAS_I16 keyNumToFc;
+
+ EAS_I16 modLFOToGain;
+ EAS_I16 modLFOCC1ToGain;
+ EAS_I16 modLFOChanPressToGain;
+
+ EAS_I16 tuning;
+ EAS_I16 keyNumToPitch;
+ EAS_I16 vibLFOToPitch;
+ EAS_I16 vibLFOCC1ToPitch;
+ EAS_I16 vibLFOChanPressToPitch;
+ EAS_I16 modLFOToPitch;
+ EAS_I16 modLFOCC1ToPitch;
+ EAS_I16 modLFOChanPressToPitch;
+ EAS_I16 eg2ToPitch;
+
+ /* pad to 4-byte boundary */
+ EAS_U16 pad;
+
+ EAS_I8 pan;
+ EAS_U8 filterQandFlags;
+
+#ifdef _REVERB
+ EAS_I16 reverbSend;
+ EAS_I16 cc91ToReverbSend;
+#endif
+
+#ifdef _CHORUS
+ EAS_I16 chorusSend;
+ EAS_I16 cc93ToChorusSend;
+#endif
+} S_DLS_ARTICULATION;
+
+/* flags in filterQandFlags
+ * NOTE: Q is stored in bottom 5 bits
+ */
+#define FLAG_DLS_VELOCITY_SENSITIVE 0x80
+#define FILTER_Q_MASK 0x1f
+
+/*----------------------------------------------------------------------------
+ * Wavetable region data structure
+ *----------------------------------------------------------------------------
+*/
+typedef struct s_wt_region_tag
+{
+ S_REGION region;
+ EAS_I16 tuning;
+ EAS_I16 gain;
+ EAS_U32 loopStart;
+ EAS_U32 loopEnd;
+ EAS_U16 waveIndex;
+ EAS_U16 artIndex;
+} S_WT_REGION;
+
+/*----------------------------------------------------------------------------
+ * DLS region data structure
+ *----------------------------------------------------------------------------
+*/
+typedef struct s_dls_region_tag
+{
+ S_WT_REGION wtRegion;
+ EAS_U8 velLow;
+ EAS_U8 velHigh;
+} S_DLS_REGION;
+
+/*----------------------------------------------------------------------------
+ * FM synthesizer data structures
+ *----------------------------------------------------------------------------
+*/
+typedef struct s_fm_oper_tag
+{
+ EAS_I16 tuning;
+ EAS_U8 attackDecay;
+ EAS_U8 velocityRelease;
+ EAS_U8 egKeyScale;
+ EAS_U8 sustain;
+ EAS_U8 gain;
+ EAS_U8 flags;
+} S_FM_OPER;
+
+/* defines for S_FM_OPER.m_nFlags */
+#define FM_OPER_FLAG_MONOTONE 0x01
+#define FM_OPER_FLAG_NO_VIBRATO 0x02
+#define FM_OPER_FLAG_NOISE 0x04
+#define FM_OPER_FLAG_LINEAR_VELOCITY 0x08
+
+/* NOTE: The first two structure elements are common with S_WT_REGION
+ * and we will rely on that in the voice management code and must
+ * remain there unless the voice management code is revisited.
+ */
+typedef struct s_fm_region_tag
+{
+ S_REGION region;
+ EAS_U8 vibTrem;
+ EAS_U8 lfoFreqDelay;
+ EAS_U8 feedback;
+ EAS_I8 pan;
+ S_FM_OPER oper[4];
+} S_FM_REGION;
+
+/*----------------------------------------------------------------------------
+ * Common data structures
+ *----------------------------------------------------------------------------
+*/
+
+/*----------------------------------------------------------------------------
+ * Program data structure
+ * Used for individual programs not stored as a complete bank.
+ *----------------------------------------------------------------------------
+*/
+typedef struct s_program_tag
+{
+ EAS_U32 locale;
+ EAS_U16 regionIndex;
+} S_PROGRAM;
+
+/*----------------------------------------------------------------------------
+ * Bank data structure
+ *
+ * A bank always consists of 128 programs. If a bank is less than 128
+ * programs, it should be stored as a spare matrix in the pPrograms
+ * array.
+ *
+ * bankNum: MSB/LSB of MIDI bank select controller
+ * regionIndex: Index of first region in program
+ *----------------------------------------------------------------------------
+*/
+typedef struct s_bank_tag
+{
+ EAS_U16 locale;
+ EAS_U16 regionIndex[NUM_PROGRAMS_IN_BANK];
+} S_BANK;
+
+
+/* defines for libFormat field
+ * bits 0-17 are the sample rate
+ * bit 18 is true if wavetable is present
+ * bit 19 is true if FM is present
+ * bit 20 is true if filter is enabled
+ * bit 21 is sample depth (0 = 8-bits, 1 = 16-bits)
+ * bits 22-31 are reserved
+ */
+#define LIBFORMAT_SAMPLE_RATE_MASK 0x0003ffff
+#define LIB_FORMAT_TYPE_MASK 0x000c0000
+#define LIB_FORMAT_WAVETABLE 0x00000000
+#define LIB_FORMAT_FM 0x00040000
+#define LIB_FORMAT_HYBRID 0x00080000
+#define LIB_FORMAT_FILTER_ENABLED 0x00100000
+#define LIB_FORMAT_16_BIT_SAMPLES 0x00200000
+
+#ifdef DLS_SYNTHESIZER
+/*----------------------------------------------------------------------------
+ * DLS data structure
+ *
+ * pDLSPrograms pointer to array of DLS programs
+ * pDLSRegions pointer to array of DLS regions
+ * pDLSArticulations pointer to array of DLS articulations
+ * pSampleLen pointer to array of sample lengths
+ * ppSamples pointer to array of sample pointers
+ * numDLSPrograms number of DLS programs
+ * numDLSRegions number of DLS regions
+ * numDLSArticulations number of DLS articulations
+ * numDLSSamples number of DLS samples
+ *----------------------------------------------------------------------------
+*/
+typedef struct s_eas_dls_tag
+{
+ S_PROGRAM *pDLSPrograms;
+ S_DLS_REGION *pDLSRegions;
+ S_DLS_ARTICULATION *pDLSArticulations;
+ EAS_U32 *pDLSSampleLen;
+ EAS_U32 *pDLSSampleOffsets;
+ EAS_SAMPLE *pDLSSamples;
+ EAS_U16 numDLSPrograms;
+ EAS_U16 numDLSRegions;
+ EAS_U16 numDLSArticulations;
+ EAS_U16 numDLSSamples;
+ EAS_U8 refCount;
+} S_DLS;
+#endif
+
+/*----------------------------------------------------------------------------
+ * Sound library data structure
+ *
+ * pBanks pointer to array of banks
+ * pPrograms pointer to array of programs
+ * pWTRegions pointer to array of wavetable regions
+ * pFMRegions pointer to array of FM regions
+ * pArticulations pointer to array of articulations
+ * pSampleLen pointer to array of sample lengths
+ * ppSamples pointer to array of sample pointers
+ * numBanks number of banks
+ * numPrograms number of individual program
+ * numRegions number of regions
+ * numArticulations number of articulations
+ * numSamples number of samples
+ *----------------------------------------------------------------------------
+*/
+typedef struct s_eas_sndlib_tag
+{
+ SCNST EAS_U32 identifier;
+ SCNST EAS_U32 libAttr;
+
+ SCNST S_BANK *pBanks;
+ SCNST S_PROGRAM *pPrograms;
+
+ SCNST S_WT_REGION *pWTRegions;
+ SCNST S_ARTICULATION *pArticulations;
+ SCNST EAS_U32 *pSampleLen;
+ SCNST EAS_U32 *pSampleOffsets;
+ SCNST EAS_SAMPLE *pSamples;
+
+ SCNST S_FM_REGION *pFMRegions;
+
+ SCNST EAS_U16 numBanks;
+ SCNST EAS_U16 numPrograms;
+
+ SCNST EAS_U16 numWTRegions;
+ SCNST EAS_U16 numArticulations;
+ SCNST EAS_U16 numSamples;
+
+ SCNST EAS_U16 numFMRegions;
+} S_EAS;
+
+#endif
+
diff --git a/arm-hybrid-22k/lib_src/eas_synth.h b/arm-hybrid-22k/lib_src/eas_synth.h
index b242b03..6274b7d 100644
--- a/arm-hybrid-22k/lib_src/eas_synth.h
+++ b/arm-hybrid-22k/lib_src/eas_synth.h
@@ -1,12 +1,12 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_synth.h
- *
- * Contents and purpose:
- * Declarations, interfaces, and prototypes for synth.
- *
- * Copyright Sonic Network Inc. 2004, 2005
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_synth.h
+ *
+ * Contents and purpose:
+ * Declarations, interfaces, and prototypes for synth.
+ *
+ * Copyright Sonic Network Inc. 2004, 2005
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,377 +19,377 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 718 $
- * $Date: 2007-06-08 16:43:16 -0700 (Fri, 08 Jun 2007) $
- *----------------------------------------------------------------------------
-*/
-
-#ifndef _EAS_SYNTH_H
-#define _EAS_SYNTH_H
-
-#include "eas_types.h"
-#include "eas_sndlib.h"
-
-#ifdef _WT_SYNTH
-#include "eas_wtsynth.h"
-#endif
-
-#ifdef _FM_SYNTH
-#include "eas_fmsynth.h"
-#endif
-
-#ifndef NUM_OUTPUT_CHANNELS
-#define NUM_OUTPUT_CHANNELS 2
-#endif
-
-#ifndef MAX_SYNTH_VOICES
-#define MAX_SYNTH_VOICES 64
-#endif
-
-#ifndef MAX_VIRTUAL_SYNTHESIZERS
-#define MAX_VIRTUAL_SYNTHESIZERS 4
-#endif
-
-/* defines */
-#ifndef NUM_PRIMARY_VOICES
-#define NUM_PRIMARY_VOICES MAX_SYNTH_VOICES
-#elif !defined(NUM_SECONDARY_VOICES)
-#define NUM_SECONDARY_VOICES (MAX_SYNTH_VOICES - NUM_PRIMARY_VOICES)
-#endif
-
-#if defined(EAS_WT_SYNTH)
-#define NUM_WT_VOICES MAX_SYNTH_VOICES
-
-/* FM on MCU */
-#elif defined(EAS_FM_SYNTH)
-#define NUM_FM_VOICES MAX_SYNTH_VOICES
-
-/* wavetable drums on MCU, wavetable melodic on DSP */
-#elif defined(EAS_SPLIT_WT_SYNTH)
-#define NUM_WT_VOICES MAX_SYNTH_VOICES
-
-/* wavetable drums and FM melodic on MCU */
-#elif defined(EAS_HYBRID_SYNTH)
-#define NUM_WT_VOICES NUM_PRIMARY_VOICES
-#define NUM_FM_VOICES NUM_SECONDARY_VOICES
-
-/* wavetable drums on MCU, FM melodic on DSP */
-#elif defined(EAS_SPLIT_HYBRID_SYNTH)
-#define NUM_WT_VOICES NUM_PRIMARY_VOICES
-#define NUM_FM_VOICES NUM_SECONDARY_VOICES
-
-/* FM synth on DSP */
-#elif defined(EAS_SPLIT_FM_SYNTH)
-#define NUM_FM_VOICES MAX_SYNTH_VOICES
-
-#else
-#error "Unrecognized architecture option"
-#endif
-
-#define NUM_SYNTH_CHANNELS 16
-
-#define DEFAULT_SYNTH_VOICES MAX_SYNTH_VOICES
-
-/* use the following values to specify unassigned channels or voices */
-#define UNASSIGNED_SYNTH_CHANNEL NUM_SYNTH_CHANNELS
-#define UNASSIGNED_SYNTH_VOICE MAX_SYNTH_VOICES
-
-
-/* synth parameters are updated every SYNTH_UPDATE_PERIOD_IN_SAMPLES */
-#define SYNTH_UPDATE_PERIOD_IN_SAMPLES (EAS_I32)(0x1L << SYNTH_UPDATE_PERIOD_IN_BITS)
-
-/* stealing weighting factors */
-#define NOTE_AGE_STEAL_WEIGHT 1
-#define NOTE_GAIN_STEAL_WEIGHT 4
-#define CHANNEL_POLY_STEAL_WEIGHT 12
-#define CHANNEL_PRIORITY_STEAL_WEIGHT 2
-#define NOTE_MATCH_PENALTY 128
-#define SYNTH_PRIORITY_WEIGHT 8
-
-/* default synth master volume */
-#define DEFAULT_SYNTH_MASTER_VOLUME 0x7fff
-
-#define DEFAULT_SYNTH_PRIORITY 5
-
-/* default tuning values */
-#define DEFAULT_PITCH_BEND_SENSITIVITY 200 /* 2 semitones */
-#define DEFAULT_FINE_PITCH 0 /* 0 cents */
-#define DEFAULT_COARSE_PITCH 0 /* 0 semitones */
-
-/* default drum channel is 10, but is internally 9 due to unit offset */
-#define DEFAULT_DRUM_CHANNEL 9
-
-/* drum channel can simultaneously play this many voices at most */
-#define DEFAULT_CHANNEL_POLYPHONY_LIMIT 2
-
-/* default instrument is acoustic piano */
-#define DEFAULT_MELODY_BANK_MSB 0x79
-#define DEFAULT_RHYTHM_BANK_MSB 0x78
-#define DEFAULT_MELODY_BANK_NUMBER (DEFAULT_MELODY_BANK_MSB << 8)
-#define DEFAULT_RHYTHM_BANK_NUMBER (DEFAULT_RHYTHM_BANK_MSB << 8)
-#define DEFAULT_SYNTH_PROGRAM_NUMBER 0
-
-#define DEFAULT_PITCH_BEND 0x2000 /* 0x2000 == (0x40 << 7) | 0x00 */
-#define DEFAULT_MOD_WHEEL 0
-#define DEFAULT_CHANNEL_VOLUME 0x64
-#define DEFAULT_PAN 0x40 /* decimal 64, center */
-
-#ifdef _REVERB
-#define DEFAULT_REVERB_SEND 40 /* some reverb */
-#endif
-
-#ifdef _CHORUS
-#define DEFAULT_CHORUS_SEND 0 /* no chorus */
-#endif
-
-#define DEFAULT_EAS_FILTER_CUTOFF_FREQUENCY 0 /* EAS synth uses a different default */
-#define DEFAULT_FILTER_RESONANCE 0
-#define DEFAULT_EXPRESSION 0x7F
-
-#define DEFAULT_CHANNEL_PRESSURE 0
-
-#define DEFAULT_REGISTERED_PARAM 0x3FFF
-
-#define DEFAULT_CHANNEL_STATIC_GAIN 0
-#define DEFAULT_CHANNEL_STATIC_PITCH 0
-
-#define DEFAULT_LFO_MOD_WHEEL_TO_PITCH_CENTS 50
-#define DEFAULT_LFO_CHANNEL_PRESSURE_TO_PITCH_CENTS 50
-
-#define DEFAULT_KEY_NUMBER 0x69
-#define DEFAULT_VELOCITY 0x64
-#define DEFAULT_REGION_INDEX 0
-#define DEFAULT_ARTICULATION_INDEX 0
-#define DEFAULT_VOICE_GAIN 0
-#define DEFAULT_AGE 0
-#define DEFAULT_SP_MIDI_PRIORITY 16
-
-
-/* filter defines */
-#define DEFAULT_FILTER_ZERO 0
-#define FILTER_CUTOFF_MAX_PITCH_CENTS 1919
-#define FILTER_CUTOFF_MIN_PITCH_CENTS -4467
-#define A5_PITCH_OFFSET_IN_CENTS 6900
-
-/*------------------------------------
- * S_SYNTH_CHANNEL data structure
- *------------------------------------
-*/
-
-/* S_SYNTH_CHANNEL.m_nFlags */
-#define CHANNEL_FLAG_SUSTAIN_PEDAL 0x01
-#define CHANNEL_FLAG_MUTE 0x02
-#define CHANNEL_FLAG_UPDATE_CHANNEL_PARAMETERS 0x04
-#define CHANNEL_FLAG_RHYTHM_CHANNEL 0x08
-#define CHANNEL_FLAG_EXTERNAL_AUDIO 0x10
-#define DEFAULT_CHANNEL_FLAGS 0
-
-/* macros for extracting virtual synth and channel numbers */
-#define GET_VSYNTH(a) ((a) >> 4)
-#define GET_CHANNEL(a) ((a) & 15)
-
-typedef struct s_synth_channel_tag
-{
- /* use static channel parameters to reduce MIPs */
- /* parameters shared by multiple voices assigned to same channel */
- EAS_I32 staticPitch; /* (pitch bend * pitch sens) + fine pitch */
- EAS_I16 staticGain; /* (CC7 * CC11 * master vol)^2 */
-
- EAS_U16 regionIndex; /* index of first region in program */
-
- EAS_U16 bankNum; /* play programs from this bank */
- EAS_I16 pitchBend; /* pitch wheel value */
- EAS_I16 pitchBendSensitivity;
- EAS_I16 registeredParam; /* currently selected registered param */
-
-
-#if defined(_FM_SYNTH)
- EAS_I16 lfoAmt; /* amount of LFO to apply to voice */
-#endif
-
- EAS_U8 programNum; /* play this instrument number */
- EAS_U8 modWheel; /* CC1 */
- EAS_U8 volume; /* CC7 */
- EAS_U8 pan; /* CC10 */
-
- EAS_U8 expression; /* CC11 */
-
- /* the following parameters are controlled by RPNs */
- EAS_I8 finePitch;
- EAS_I8 coarsePitch;
-
- EAS_U8 channelPressure; /* applied to all voices on a given channel */
-
- EAS_U8 channelFlags; /* bit field channelFlags for */
- /* CC64, SP-MIDI channel masking */
-
- EAS_U8 pool; /* SPMIDI channel voice pool */
- EAS_U8 mip; /* SPMIDI MIP setting */
-
-#ifdef _REVERB
- EAS_U8 reverbSend; /* CC91 */
-#endif
-
-#ifdef _CHORUS
- EAS_U8 chorusSend; /* CC93 */
-#endif
-} S_SYNTH_CHANNEL;
-
-/*------------------------------------
- * S_SYNTH_VOICE data structure
- *------------------------------------
-*/
-
-/* S_SYNTH_VOICE.m_nFlags */
-#define VOICE_FLAG_UPDATE_VOICE_PARAMETERS 0x01
-#define VOICE_FLAG_SUSTAIN_PEDAL_DEFER_NOTE_OFF 0x02
-#define VOICE_FLAG_DEFER_MIDI_NOTE_OFF 0x04
-#define VOICE_FLAG_NO_SAMPLES_SYNTHESIZED_YET 0x08
-#define VOICE_FLAG_DEFER_MUTE 0x40
-#define DEFAULT_VOICE_FLAGS 0
-
-/* S_SYNTH_VOICE.m_eState */
-typedef enum {
-
- eVoiceStateFree = 0,
- eVoiceStateStart,
- eVoiceStatePlay,
- eVoiceStateRelease,
- eVoiceStateMuting,
- eVoiceStateStolen,
- eVoiceStateInvalid /* should never be in this state! */
-
-} E_VOICE_STATE;
-#define DEFAULT_VOICE_STATE eVoiceStateFree
-
-typedef struct s_synth_voice_tag
-{
-
-/* These parameters are common to both wavetable and FM
- * synthesizers. The voice manager should only access this data.
- * Any other data should be manipulated by the code that is
- * specific to that synthesizer and reflected back through the
- * common state data available here.
- */
- EAS_U16 regionIndex; /* index to wave and playback params */
- EAS_I16 gain; /* current gain */
- EAS_U16 age; /* large value means old note */
- EAS_U16 nextRegionIndex; /* index to wave and playback params */
- EAS_U8 voiceState; /* current voice state */
- EAS_U8 voiceFlags; /* misc flags/bit fields */
- EAS_U8 channel; /* this voice plays on this synth channel */
- EAS_U8 note; /* 12 <= key number <= 108 */
- EAS_U8 velocity; /* 0 <= velocity <= 127 */
- EAS_U8 nextChannel; /* play stolen voice on this channel */
- EAS_U8 nextNote; /* 12 <= key number <= 108 */
- EAS_U8 nextVelocity; /* 0 <= velocity <= 127 */
-} S_SYNTH_VOICE;
-
-/*------------------------------------
- * S_SYNTH data structure
- *
- * One instance for each MIDI stream
- *------------------------------------
-*/
-
-/* S_SYNTH.m_nFlags */
-#define SYNTH_FLAG_RESET_IS_REQUESTED 0x01
-#define SYNTH_FLAG_SP_MIDI_ON 0x02
-#define SYNTH_FLAG_UPDATE_ALL_CHANNEL_PARAMETERS 0x04
-#define SYNTH_FLAG_DEFERRED_MIDI_NOTE_OFF_PENDING 0x08
-#define DEFAULT_SYNTH_FLAGS SYNTH_FLAG_UPDATE_ALL_CHANNEL_PARAMETERS
-
-typedef struct s_synth_tag
-{
- struct s_eas_data_tag *pEASData;
- const S_EAS *pEAS;
-
-#ifdef DLS_SYNTHESIZER
- S_DLS *pDLS;
-#endif
-
-#ifdef EXTERNAL_AUDIO
- EAS_EXT_PRG_CHG_FUNC cbProgChgFunc;
- EAS_EXT_EVENT_FUNC cbEventFunc;
- EAS_VOID_PTR *pExtAudioInstData;
-#endif
-
- S_SYNTH_CHANNEL channels[NUM_SYNTH_CHANNELS];
- EAS_I32 totalNoteCount;
- EAS_U16 maxPolyphony;
- EAS_U16 numActiveVoices;
- EAS_U16 masterVolume;
- EAS_U8 channelsByPriority[NUM_SYNTH_CHANNELS];
- EAS_U8 poolCount[NUM_SYNTH_CHANNELS];
- EAS_U8 poolAlloc[NUM_SYNTH_CHANNELS];
- EAS_U8 synthFlags;
- EAS_I8 globalTranspose;
- EAS_U8 vSynthNum;
- EAS_U8 refCount;
- EAS_U8 priority;
-} S_SYNTH;
-
-/*------------------------------------
- * S_VOICE_MGR data structure
- *
- * One instance for each EAS library instance
- *------------------------------------
-*/
-typedef struct s_voice_mgr_tag
-{
- S_SYNTH *pSynth[MAX_VIRTUAL_SYNTHESIZERS];
- EAS_PCM voiceBuffer[SYNTH_UPDATE_PERIOD_IN_SAMPLES];
-
-#ifdef _FM_SYNTH
- EAS_PCM operMixBuffer[SYNTH_UPDATE_PERIOD_IN_SAMPLES];
- S_FM_VOICE fmVoices[NUM_FM_VOICES];
-#endif
-
-#ifdef _WT_SYNTH
- S_WT_VOICE wtVoices[NUM_WT_VOICES];
-#endif
-
-#ifdef _REVERB
- EAS_PCM reverbSendBuffer[NUM_OUTPUT_CHANNELS * SYNTH_UPDATE_PERIOD_IN_SAMPLES];
-#endif
-
-#ifdef _CHORUS
- EAS_PCM chorusSendBuffer[NUM_OUTPUT_CHANNELS * SYNTH_UPDATE_PERIOD_IN_SAMPLES];
-#endif
- S_SYNTH_VOICE voices[MAX_SYNTH_VOICES];
-
- EAS_SNDLIB_HANDLE pGlobalEAS;
-
-#ifdef DLS_SYNTHESIZER
- S_DLS *pGlobalDLS;
-#endif
-
-#ifdef _SPLIT_ARCHITECTURE
- EAS_FRAME_BUFFER_HANDLE pFrameBuffer;
-#endif
-
-#if defined(_SECONDARY_SYNTH) || defined(EAS_SPLIT_WT_SYNTH)
- EAS_U16 maxPolyphonyPrimary;
- EAS_U16 maxPolyphonySecondary;
-#endif
-
- EAS_I32 workload;
- EAS_I32 maxWorkLoad;
-
- EAS_U16 activeVoices;
- EAS_U16 maxPolyphony;
-
- EAS_U16 age;
-
-/* limits the number of voice starts in a frame for split architecture */
-#ifdef MAX_VOICE_STARTS
- EAS_U16 numVoiceStarts;
-#endif
-} S_VOICE_MGR;
-
-#endif /* #ifdef _EAS_SYNTH_H */
-
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 718 $
+ * $Date: 2007-06-08 16:43:16 -0700 (Fri, 08 Jun 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+#ifndef _EAS_SYNTH_H
+#define _EAS_SYNTH_H
+
+#include "eas_types.h"
+#include "eas_sndlib.h"
+
+#ifdef _WT_SYNTH
+#include "eas_wtsynth.h"
+#endif
+
+#ifdef _FM_SYNTH
+#include "eas_fmsynth.h"
+#endif
+
+#ifndef NUM_OUTPUT_CHANNELS
+#define NUM_OUTPUT_CHANNELS 2
+#endif
+
+#ifndef MAX_SYNTH_VOICES
+#define MAX_SYNTH_VOICES 64
+#endif
+
+#ifndef MAX_VIRTUAL_SYNTHESIZERS
+#define MAX_VIRTUAL_SYNTHESIZERS 4
+#endif
+
+/* defines */
+#ifndef NUM_PRIMARY_VOICES
+#define NUM_PRIMARY_VOICES MAX_SYNTH_VOICES
+#elif !defined(NUM_SECONDARY_VOICES)
+#define NUM_SECONDARY_VOICES (MAX_SYNTH_VOICES - NUM_PRIMARY_VOICES)
+#endif
+
+#if defined(EAS_WT_SYNTH)
+#define NUM_WT_VOICES MAX_SYNTH_VOICES
+
+/* FM on MCU */
+#elif defined(EAS_FM_SYNTH)
+#define NUM_FM_VOICES MAX_SYNTH_VOICES
+
+/* wavetable drums on MCU, wavetable melodic on DSP */
+#elif defined(EAS_SPLIT_WT_SYNTH)
+#define NUM_WT_VOICES MAX_SYNTH_VOICES
+
+/* wavetable drums and FM melodic on MCU */
+#elif defined(EAS_HYBRID_SYNTH)
+#define NUM_WT_VOICES NUM_PRIMARY_VOICES
+#define NUM_FM_VOICES NUM_SECONDARY_VOICES
+
+/* wavetable drums on MCU, FM melodic on DSP */
+#elif defined(EAS_SPLIT_HYBRID_SYNTH)
+#define NUM_WT_VOICES NUM_PRIMARY_VOICES
+#define NUM_FM_VOICES NUM_SECONDARY_VOICES
+
+/* FM synth on DSP */
+#elif defined(EAS_SPLIT_FM_SYNTH)
+#define NUM_FM_VOICES MAX_SYNTH_VOICES
+
+#else
+#error "Unrecognized architecture option"
+#endif
+
+#define NUM_SYNTH_CHANNELS 16
+
+#define DEFAULT_SYNTH_VOICES MAX_SYNTH_VOICES
+
+/* use the following values to specify unassigned channels or voices */
+#define UNASSIGNED_SYNTH_CHANNEL NUM_SYNTH_CHANNELS
+#define UNASSIGNED_SYNTH_VOICE MAX_SYNTH_VOICES
+
+
+/* synth parameters are updated every SYNTH_UPDATE_PERIOD_IN_SAMPLES */
+#define SYNTH_UPDATE_PERIOD_IN_SAMPLES (EAS_I32)(0x1L << SYNTH_UPDATE_PERIOD_IN_BITS)
+
+/* stealing weighting factors */
+#define NOTE_AGE_STEAL_WEIGHT 1
+#define NOTE_GAIN_STEAL_WEIGHT 4
+#define CHANNEL_POLY_STEAL_WEIGHT 12
+#define CHANNEL_PRIORITY_STEAL_WEIGHT 2
+#define NOTE_MATCH_PENALTY 128
+#define SYNTH_PRIORITY_WEIGHT 8
+
+/* default synth master volume */
+#define DEFAULT_SYNTH_MASTER_VOLUME 0x7fff
+
+#define DEFAULT_SYNTH_PRIORITY 5
+
+/* default tuning values */
+#define DEFAULT_PITCH_BEND_SENSITIVITY 200 /* 2 semitones */
+#define DEFAULT_FINE_PITCH 0 /* 0 cents */
+#define DEFAULT_COARSE_PITCH 0 /* 0 semitones */
+
+/* default drum channel is 10, but is internally 9 due to unit offset */
+#define DEFAULT_DRUM_CHANNEL 9
+
+/* drum channel can simultaneously play this many voices at most */
+#define DEFAULT_CHANNEL_POLYPHONY_LIMIT 2
+
+/* default instrument is acoustic piano */
+#define DEFAULT_MELODY_BANK_MSB 0x79
+#define DEFAULT_RHYTHM_BANK_MSB 0x78
+#define DEFAULT_MELODY_BANK_NUMBER (DEFAULT_MELODY_BANK_MSB << 8)
+#define DEFAULT_RHYTHM_BANK_NUMBER (DEFAULT_RHYTHM_BANK_MSB << 8)
+#define DEFAULT_SYNTH_PROGRAM_NUMBER 0
+
+#define DEFAULT_PITCH_BEND 0x2000 /* 0x2000 == (0x40 << 7) | 0x00 */
+#define DEFAULT_MOD_WHEEL 0
+#define DEFAULT_CHANNEL_VOLUME 0x64
+#define DEFAULT_PAN 0x40 /* decimal 64, center */
+
+#ifdef _REVERB
+#define DEFAULT_REVERB_SEND 40 /* some reverb */
+#endif
+
+#ifdef _CHORUS
+#define DEFAULT_CHORUS_SEND 0 /* no chorus */
+#endif
+
+#define DEFAULT_EAS_FILTER_CUTOFF_FREQUENCY 0 /* EAS synth uses a different default */
+#define DEFAULT_FILTER_RESONANCE 0
+#define DEFAULT_EXPRESSION 0x7F
+
+#define DEFAULT_CHANNEL_PRESSURE 0
+
+#define DEFAULT_REGISTERED_PARAM 0x3FFF
+
+#define DEFAULT_CHANNEL_STATIC_GAIN 0
+#define DEFAULT_CHANNEL_STATIC_PITCH 0
+
+#define DEFAULT_LFO_MOD_WHEEL_TO_PITCH_CENTS 50
+#define DEFAULT_LFO_CHANNEL_PRESSURE_TO_PITCH_CENTS 50
+
+#define DEFAULT_KEY_NUMBER 0x69
+#define DEFAULT_VELOCITY 0x64
+#define DEFAULT_REGION_INDEX 0
+#define DEFAULT_ARTICULATION_INDEX 0
+#define DEFAULT_VOICE_GAIN 0
+#define DEFAULT_AGE 0
+#define DEFAULT_SP_MIDI_PRIORITY 16
+
+
+/* filter defines */
+#define DEFAULT_FILTER_ZERO 0
+#define FILTER_CUTOFF_MAX_PITCH_CENTS 1919
+#define FILTER_CUTOFF_MIN_PITCH_CENTS -4467
+#define A5_PITCH_OFFSET_IN_CENTS 6900
+
+/*------------------------------------
+ * S_SYNTH_CHANNEL data structure
+ *------------------------------------
+*/
+
+/* S_SYNTH_CHANNEL.m_nFlags */
+#define CHANNEL_FLAG_SUSTAIN_PEDAL 0x01
+#define CHANNEL_FLAG_MUTE 0x02
+#define CHANNEL_FLAG_UPDATE_CHANNEL_PARAMETERS 0x04
+#define CHANNEL_FLAG_RHYTHM_CHANNEL 0x08
+#define CHANNEL_FLAG_EXTERNAL_AUDIO 0x10
+#define DEFAULT_CHANNEL_FLAGS 0
+
+/* macros for extracting virtual synth and channel numbers */
+#define GET_VSYNTH(a) ((a) >> 4)
+#define GET_CHANNEL(a) ((a) & 15)
+
+typedef struct s_synth_channel_tag
+{
+ /* use static channel parameters to reduce MIPs */
+ /* parameters shared by multiple voices assigned to same channel */
+ EAS_I32 staticPitch; /* (pitch bend * pitch sens) + fine pitch */
+ EAS_I16 staticGain; /* (CC7 * CC11 * master vol)^2 */
+
+ EAS_U16 regionIndex; /* index of first region in program */
+
+ EAS_U16 bankNum; /* play programs from this bank */
+ EAS_I16 pitchBend; /* pitch wheel value */
+ EAS_I16 pitchBendSensitivity;
+ EAS_I16 registeredParam; /* currently selected registered param */
+
+
+#if defined(_FM_SYNTH)
+ EAS_I16 lfoAmt; /* amount of LFO to apply to voice */
+#endif
+
+ EAS_U8 programNum; /* play this instrument number */
+ EAS_U8 modWheel; /* CC1 */
+ EAS_U8 volume; /* CC7 */
+ EAS_U8 pan; /* CC10 */
+
+ EAS_U8 expression; /* CC11 */
+
+ /* the following parameters are controlled by RPNs */
+ EAS_I8 finePitch;
+ EAS_I8 coarsePitch;
+
+ EAS_U8 channelPressure; /* applied to all voices on a given channel */
+
+ EAS_U8 channelFlags; /* bit field channelFlags for */
+ /* CC64, SP-MIDI channel masking */
+
+ EAS_U8 pool; /* SPMIDI channel voice pool */
+ EAS_U8 mip; /* SPMIDI MIP setting */
+
+#ifdef _REVERB
+ EAS_U8 reverbSend; /* CC91 */
+#endif
+
+#ifdef _CHORUS
+ EAS_U8 chorusSend; /* CC93 */
+#endif
+} S_SYNTH_CHANNEL;
+
+/*------------------------------------
+ * S_SYNTH_VOICE data structure
+ *------------------------------------
+*/
+
+/* S_SYNTH_VOICE.m_nFlags */
+#define VOICE_FLAG_UPDATE_VOICE_PARAMETERS 0x01
+#define VOICE_FLAG_SUSTAIN_PEDAL_DEFER_NOTE_OFF 0x02
+#define VOICE_FLAG_DEFER_MIDI_NOTE_OFF 0x04
+#define VOICE_FLAG_NO_SAMPLES_SYNTHESIZED_YET 0x08
+#define VOICE_FLAG_DEFER_MUTE 0x40
+#define DEFAULT_VOICE_FLAGS 0
+
+/* S_SYNTH_VOICE.m_eState */
+typedef enum {
+
+ eVoiceStateFree = 0,
+ eVoiceStateStart,
+ eVoiceStatePlay,
+ eVoiceStateRelease,
+ eVoiceStateMuting,
+ eVoiceStateStolen,
+ eVoiceStateInvalid /* should never be in this state! */
+
+} E_VOICE_STATE;
+#define DEFAULT_VOICE_STATE eVoiceStateFree
+
+typedef struct s_synth_voice_tag
+{
+
+/* These parameters are common to both wavetable and FM
+ * synthesizers. The voice manager should only access this data.
+ * Any other data should be manipulated by the code that is
+ * specific to that synthesizer and reflected back through the
+ * common state data available here.
+ */
+ EAS_U16 regionIndex; /* index to wave and playback params */
+ EAS_I16 gain; /* current gain */
+ EAS_U16 age; /* large value means old note */
+ EAS_U16 nextRegionIndex; /* index to wave and playback params */
+ EAS_U8 voiceState; /* current voice state */
+ EAS_U8 voiceFlags; /* misc flags/bit fields */
+ EAS_U8 channel; /* this voice plays on this synth channel */
+ EAS_U8 note; /* 12 <= key number <= 108 */
+ EAS_U8 velocity; /* 0 <= velocity <= 127 */
+ EAS_U8 nextChannel; /* play stolen voice on this channel */
+ EAS_U8 nextNote; /* 12 <= key number <= 108 */
+ EAS_U8 nextVelocity; /* 0 <= velocity <= 127 */
+} S_SYNTH_VOICE;
+
+/*------------------------------------
+ * S_SYNTH data structure
+ *
+ * One instance for each MIDI stream
+ *------------------------------------
+*/
+
+/* S_SYNTH.m_nFlags */
+#define SYNTH_FLAG_RESET_IS_REQUESTED 0x01
+#define SYNTH_FLAG_SP_MIDI_ON 0x02
+#define SYNTH_FLAG_UPDATE_ALL_CHANNEL_PARAMETERS 0x04
+#define SYNTH_FLAG_DEFERRED_MIDI_NOTE_OFF_PENDING 0x08
+#define DEFAULT_SYNTH_FLAGS SYNTH_FLAG_UPDATE_ALL_CHANNEL_PARAMETERS
+
+typedef struct s_synth_tag
+{
+ struct s_eas_data_tag *pEASData;
+ const S_EAS *pEAS;
+
+#ifdef DLS_SYNTHESIZER
+ S_DLS *pDLS;
+#endif
+
+#ifdef EXTERNAL_AUDIO
+ EAS_EXT_PRG_CHG_FUNC cbProgChgFunc;
+ EAS_EXT_EVENT_FUNC cbEventFunc;
+ EAS_VOID_PTR *pExtAudioInstData;
+#endif
+
+ S_SYNTH_CHANNEL channels[NUM_SYNTH_CHANNELS];
+ EAS_I32 totalNoteCount;
+ EAS_U16 maxPolyphony;
+ EAS_U16 numActiveVoices;
+ EAS_U16 masterVolume;
+ EAS_U8 channelsByPriority[NUM_SYNTH_CHANNELS];
+ EAS_U8 poolCount[NUM_SYNTH_CHANNELS];
+ EAS_U8 poolAlloc[NUM_SYNTH_CHANNELS];
+ EAS_U8 synthFlags;
+ EAS_I8 globalTranspose;
+ EAS_U8 vSynthNum;
+ EAS_U8 refCount;
+ EAS_U8 priority;
+} S_SYNTH;
+
+/*------------------------------------
+ * S_VOICE_MGR data structure
+ *
+ * One instance for each EAS library instance
+ *------------------------------------
+*/
+typedef struct s_voice_mgr_tag
+{
+ S_SYNTH *pSynth[MAX_VIRTUAL_SYNTHESIZERS];
+ EAS_PCM voiceBuffer[SYNTH_UPDATE_PERIOD_IN_SAMPLES];
+
+#ifdef _FM_SYNTH
+ EAS_PCM operMixBuffer[SYNTH_UPDATE_PERIOD_IN_SAMPLES];
+ S_FM_VOICE fmVoices[NUM_FM_VOICES];
+#endif
+
+#ifdef _WT_SYNTH
+ S_WT_VOICE wtVoices[NUM_WT_VOICES];
+#endif
+
+#ifdef _REVERB
+ EAS_PCM reverbSendBuffer[NUM_OUTPUT_CHANNELS * SYNTH_UPDATE_PERIOD_IN_SAMPLES];
+#endif
+
+#ifdef _CHORUS
+ EAS_PCM chorusSendBuffer[NUM_OUTPUT_CHANNELS * SYNTH_UPDATE_PERIOD_IN_SAMPLES];
+#endif
+ S_SYNTH_VOICE voices[MAX_SYNTH_VOICES];
+
+ EAS_SNDLIB_HANDLE pGlobalEAS;
+
+#ifdef DLS_SYNTHESIZER
+ S_DLS *pGlobalDLS;
+#endif
+
+#ifdef _SPLIT_ARCHITECTURE
+ EAS_FRAME_BUFFER_HANDLE pFrameBuffer;
+#endif
+
+#if defined(_SECONDARY_SYNTH) || defined(EAS_SPLIT_WT_SYNTH)
+ EAS_U16 maxPolyphonyPrimary;
+ EAS_U16 maxPolyphonySecondary;
+#endif
+
+ EAS_I32 workload;
+ EAS_I32 maxWorkLoad;
+
+ EAS_U16 activeVoices;
+ EAS_U16 maxPolyphony;
+
+ EAS_U16 age;
+
+/* limits the number of voice starts in a frame for split architecture */
+#ifdef MAX_VOICE_STARTS
+ EAS_U16 numVoiceStarts;
+#endif
+} S_VOICE_MGR;
+
+#endif /* #ifdef _EAS_SYNTH_H */
+
+
diff --git a/arm-hybrid-22k/lib_src/eas_synth_protos.h b/arm-hybrid-22k/lib_src/eas_synth_protos.h
index a2ef10d..b03af0f 100644
--- a/arm-hybrid-22k/lib_src/eas_synth_protos.h
+++ b/arm-hybrid-22k/lib_src/eas_synth_protos.h
@@ -1,12 +1,12 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_synth_protos.h
- *
- * Contents and purpose:
- * Declarations, interfaces, and prototypes for synth.
- *
- * Copyright Sonic Network Inc. 2004
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_synth_protos.h
+ *
+ * Contents and purpose:
+ * Declarations, interfaces, and prototypes for synth.
+ *
+ * Copyright Sonic Network Inc. 2004
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,42 +19,42 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 82 $
- * $Date: 2006-07-10 11:45:19 -0700 (Mon, 10 Jul 2006) $
- *----------------------------------------------------------------------------
-*/
-
-#ifndef _EAS_SYNTH_PROTOS_H
-#define _EAS_SYNTH_PROTOS_H
-
-/* includes */
-#include "eas_data.h"
-#include "eas_sndlib.h"
-
-#ifdef _SPLIT_ARCHITECTURE
-typedef struct s_frame_interface_tag
-{
- EAS_BOOL (* EAS_CONST pfStartFrame)(EAS_FRAME_BUFFER_HANDLE pFrameBuffer);
- EAS_BOOL (* EAS_CONST pfEndFrame)(EAS_FRAME_BUFFER_HANDLE pFrameBuffer, EAS_I32 *pMixBuffer, EAS_I16 masterGain);
-} S_FRAME_INTERFACE;
-#endif
-
-/* generic synthesizer interface */
-typedef struct
-{
- EAS_RESULT (* EAS_CONST pfInitialize)(S_VOICE_MGR *pVoiceMgr);
- EAS_RESULT (* EAS_CONST pfStartVoice)(S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, EAS_I32 voiceNum, EAS_U16 regionIndex);
- EAS_BOOL (* EAS_CONST pfUpdateVoice)(S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, EAS_I32 voiceNum, EAS_I32 *pMixBuffer, EAS_I32 numSamples);
- void (* EAS_CONST pfReleaseVoice)(S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, EAS_I32 voiceNum);
- void (* EAS_CONST pfMuteVoice)(S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, EAS_I32 voiceNum);
- void (* EAS_CONST pfSustainPedal)(S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, S_SYNTH_CHANNEL *pChannel, EAS_I32 voiceNum);
- void (* EAS_CONST pfUpdateChannel)(S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel);
-} S_SYNTH_INTERFACE;
-
-#endif
-
-
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 82 $
+ * $Date: 2006-07-10 11:45:19 -0700 (Mon, 10 Jul 2006) $
+ *----------------------------------------------------------------------------
+*/
+
+#ifndef _EAS_SYNTH_PROTOS_H
+#define _EAS_SYNTH_PROTOS_H
+
+/* includes */
+#include "eas_data.h"
+#include "eas_sndlib.h"
+
+#ifdef _SPLIT_ARCHITECTURE
+typedef struct s_frame_interface_tag
+{
+ EAS_BOOL (* EAS_CONST pfStartFrame)(EAS_FRAME_BUFFER_HANDLE pFrameBuffer);
+ EAS_BOOL (* EAS_CONST pfEndFrame)(EAS_FRAME_BUFFER_HANDLE pFrameBuffer, EAS_I32 *pMixBuffer, EAS_I16 masterGain);
+} S_FRAME_INTERFACE;
+#endif
+
+/* generic synthesizer interface */
+typedef struct
+{
+ EAS_RESULT (* EAS_CONST pfInitialize)(S_VOICE_MGR *pVoiceMgr);
+ EAS_RESULT (* EAS_CONST pfStartVoice)(S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, EAS_I32 voiceNum, EAS_U16 regionIndex);
+ EAS_BOOL (* EAS_CONST pfUpdateVoice)(S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, EAS_I32 voiceNum, EAS_I32 *pMixBuffer, EAS_I32 numSamples);
+ void (* EAS_CONST pfReleaseVoice)(S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, EAS_I32 voiceNum);
+ void (* EAS_CONST pfMuteVoice)(S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, EAS_I32 voiceNum);
+ void (* EAS_CONST pfSustainPedal)(S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, S_SYNTH_CHANNEL *pChannel, EAS_I32 voiceNum);
+ void (* EAS_CONST pfUpdateChannel)(S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel);
+} S_SYNTH_INTERFACE;
+
+#endif
+
+
+
diff --git a/arm-hybrid-22k/lib_src/eas_synthcfg.h b/arm-hybrid-22k/lib_src/eas_synthcfg.h
index 2491e6d..78a4178 100644
--- a/arm-hybrid-22k/lib_src/eas_synthcfg.h
+++ b/arm-hybrid-22k/lib_src/eas_synthcfg.h
@@ -1,12 +1,12 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_synthcfg.h
- *
- * Contents and purpose:
- * Defines for various synth configurations
- *
- * Copyright Sonic Network Inc. 2004, 2005
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_synthcfg.h
+ *
+ * Contents and purpose:
+ * Defines for various synth configurations
+ *
+ * Copyright Sonic Network Inc. 2004, 2005
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,52 +19,52 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 664 $
- * $Date: 2007-04-25 13:11:22 -0700 (Wed, 25 Apr 2007) $
- *----------------------------------------------------------------------------
-*/
-
-#ifndef _EAS_SYNTHCFG_H
-#define _EAS_SYNTHCFG_H
-
-#if defined(EAS_WT_SYNTH)
-#define _WT_SYNTH
-
-/* FM on MCU */
-#elif defined(EAS_FM_SYNTH)
-#define _FM_SYNTH
-
-/* wavetable drums and FM melodic on MCU */
-#elif defined(EAS_HYBRID_SYNTH)
-#define _WT_SYNTH
-#define _FM_SYNTH
-#define _SECONDARY_SYNTH
-#define _HYBRID_SYNTH
-
-/* wavetable drums on MCU, wavetable melodic on DSP */
-#elif defined(EAS_SPLIT_WT_SYNTH)
-#define _WT_SYNTH
-#define _SPLIT_ARCHITECTURE
-
-/* wavetable drums on MCU, FM melodic on DSP */
-#elif defined(EAS_SPLIT_HYBRID_SYNTH)
-#define _WT_SYNTH
-#define _FM_SYNTH
-#define _SECONDARY_SYNTH
-#define _SPLIT_ARCHITECTURE
-#define _HYBRID_SYNTH
-
-/* FM synth on DSP */
-#elif defined(EAS_SPLIT_FM_SYNTH)
-#define _FM_SYNTH
-#define _SPLIT_ARCHITECTURE
-
-#else
-#error "Unrecognized architecture option"
-#endif
-
-#endif
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 664 $
+ * $Date: 2007-04-25 13:11:22 -0700 (Wed, 25 Apr 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+#ifndef _EAS_SYNTHCFG_H
+#define _EAS_SYNTHCFG_H
+
+#if defined(EAS_WT_SYNTH)
+#define _WT_SYNTH
+
+/* FM on MCU */
+#elif defined(EAS_FM_SYNTH)
+#define _FM_SYNTH
+
+/* wavetable drums and FM melodic on MCU */
+#elif defined(EAS_HYBRID_SYNTH)
+#define _WT_SYNTH
+#define _FM_SYNTH
+#define _SECONDARY_SYNTH
+#define _HYBRID_SYNTH
+
+/* wavetable drums on MCU, wavetable melodic on DSP */
+#elif defined(EAS_SPLIT_WT_SYNTH)
+#define _WT_SYNTH
+#define _SPLIT_ARCHITECTURE
+
+/* wavetable drums on MCU, FM melodic on DSP */
+#elif defined(EAS_SPLIT_HYBRID_SYNTH)
+#define _WT_SYNTH
+#define _FM_SYNTH
+#define _SECONDARY_SYNTH
+#define _SPLIT_ARCHITECTURE
+#define _HYBRID_SYNTH
+
+/* FM synth on DSP */
+#elif defined(EAS_SPLIT_FM_SYNTH)
+#define _FM_SYNTH
+#define _SPLIT_ARCHITECTURE
+
+#else
+#error "Unrecognized architecture option"
+#endif
+
+#endif
+
diff --git a/arm-hybrid-22k/lib_src/eas_vm_protos.h b/arm-hybrid-22k/lib_src/eas_vm_protos.h
index eb49ba8..20f7c09 100644
--- a/arm-hybrid-22k/lib_src/eas_vm_protos.h
+++ b/arm-hybrid-22k/lib_src/eas_vm_protos.h
@@ -1,12 +1,12 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_vm_protos.h
- *
- * Contents and purpose:
- * Declarations, interfaces, and prototypes for voice manager.
- *
- * Copyright Sonic Network Inc. 2004
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_vm_protos.h
+ *
+ * Contents and purpose:
+ * Declarations, interfaces, and prototypes for voice manager.
+ *
+ * Copyright Sonic Network Inc. 2004
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,1068 +19,1068 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 736 $
- * $Date: 2007-06-22 13:51:24 -0700 (Fri, 22 Jun 2007) $
- *----------------------------------------------------------------------------
-*/
-
-#ifndef _EAS_VM_PROTOS_H
-#define _EAS_VM_PROTOS_H
-
-// includes
-#include "eas_data.h"
-#include "eas_sndlib.h"
-
-/*----------------------------------------------------------------------------
- * VMInitialize()
- *----------------------------------------------------------------------------
- * Purpose:
- *
- * Inputs:
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT VMInitialize (S_EAS_DATA *pEASData);
-
-/*----------------------------------------------------------------------------
- * VMInitMIDI()
- *----------------------------------------------------------------------------
- * Purpose:
- *
- * Inputs:
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT VMInitMIDI (S_EAS_DATA *pEASData, S_SYNTH **ppSynth);
-
-/*----------------------------------------------------------------------------
- * VMInitializeAllChannels()
- *----------------------------------------------------------------------------
- * Purpose:
- *
- * Inputs:
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- *
- *----------------------------------------------------------------------------
-*/
-void VMInitializeAllChannels (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth);
-
-/*----------------------------------------------------------------------------
- * VMResetControllers()
- *----------------------------------------------------------------------------
- * Purpose:
- *
- * Inputs:
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- *
- *----------------------------------------------------------------------------
-*/
-void VMResetControllers (S_SYNTH *pSynth);
-
-/*----------------------------------------------------------------------------
- * VMInitMIPTable()
- *----------------------------------------------------------------------------
- * Purpose:
- * Initialize the SP-MIDI MIP table
- *
- * Inputs:
- * pEASData - pointer to synthesizer instance data
- * mute - EAS_FALSE to unmute channels, EAS_TRUE to mute
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-void VMInitMIPTable (S_SYNTH *pSynth);
-
-/*----------------------------------------------------------------------------
- * VMSetMIPEntry()
- *----------------------------------------------------------------------------
- * Purpose:
- * Sets the priority and MIP level for a MIDI channel
- *
- * Inputs:
- * pEASData - pointer to synthesizer instance data
- * channel - MIDI channel number
- * priority - priority (0-15 with 0 = highest priority)
- * mip - maximum instantaneous polyphony
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-void VMSetMIPEntry (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel, EAS_U8 priority, EAS_U8 mip);
-
-/*----------------------------------------------------------------------------
- * VMUpdateMIPTable()
- *----------------------------------------------------------------------------
- * Purpose:
- * This routine is called when the polyphony count in the synthesizer changes
- *
- * Inputs:
- * pEASData - pointer to synthesizer instance data
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-void VMUpdateMIPTable (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth);
-
-/*----------------------------------------------------------------------------
- * VMInitializeAllVoices()
- *----------------------------------------------------------------------------
- * Purpose:
- *
- * Inputs:
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- *
- *----------------------------------------------------------------------------
-*/
-void VMInitializeAllVoices (S_VOICE_MGR *pVoiceMgr, EAS_INT vSynthNum);
-
-/*----------------------------------------------------------------------------
- * VMStartNote()
- *----------------------------------------------------------------------------
- * Purpose:
- * Update the synth's state to play the requested note on the requested
- * channel if possible.
- *
- * Inputs:
- * nChannel - the MIDI channel
- * nKeyNumber - the MIDI key number for this note
- * nNoteVelocity - the key velocity for this note
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- *
- *----------------------------------------------------------------------------
-*/
-void VMStartNote (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel, EAS_U8 note, EAS_U8 velocity);
-
-/*----------------------------------------------------------------------------
- * VMCheckKeyGroup()
- *----------------------------------------------------------------------------
- * Purpose:
- * If the note that we've been asked to start is in the same key group as
- * any currently playing notes, then we must shut down the currently playing
- * note in the same key group and then start the newly requested note.
- *
- * Inputs:
- * nChannel - synth channel that wants to start a new note
- * nKeyNumber - new note's midi note number
- * nRegionIndex - calling routine finds this index and gives to us
- * nNoteVelocity - new note's velocity
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- * pbVoiceStealingRequired - flag: this routine sets true if we needed to
- * steal a voice
- *
- * Side Effects:
- * gsSynthObject.m_sVoice[free voice num].m_nKeyNumber may be assigned
- * gsSynthObject.m_sVoice[free voice num].m_nVelocity may be assigned
- *----------------------------------------------------------------------------
-*/
-void VMCheckKeyGroup (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U16 keyGroup, EAS_U8 channel);
-
-/*----------------------------------------------------------------------------
- * VMCheckPolyphonyLimiting()
- *----------------------------------------------------------------------------
- * Purpose:
- * We only play at most 2 of the same note on a MIDI channel.
- * E.g., if we are asked to start note 36, and there are already two voices
- * that are playing note 36, then we must steal the voice playing
- * the oldest note 36 and use that stolen voice to play the new note 36.
- *
- * Inputs:
- * nChannel - synth channel that wants to start a new note
- * nKeyNumber - new note's midi note number
- * nNoteVelocity - new note's velocity
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- * pbVoiceStealingRequired - flag: this routine sets true if we needed to
- * steal a voice
- * *
- * Side Effects:
- * psSynthObject->m_sVoice[free voice num].m_nKeyNumber may be assigned
- * psSynthObject->m_sVoice[free voice num].m_nVelocity may be assigned
- *----------------------------------------------------------------------------
-*/
-EAS_BOOL VMCheckPolyphonyLimiting (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel, EAS_U8 note, EAS_U8 velocity, EAS_U16 regionIndex, EAS_I32 lowVoice, EAS_I32 highVoice);
-
-/*----------------------------------------------------------------------------
- * VMStopNote()
- *----------------------------------------------------------------------------
- * Purpose:
- * Update the synth's state to end the requested note on the requested
- * channel.
- *
- * Inputs:
- * nChannel - the MIDI channel
- * nKeyNumber - the key number of the note to stop
- * nNoteVelocity - the note-off velocity
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- * Side Effects:
- * gsSynthObject.m_sVoice[free voice num].m_nSynthChannel may be assigned
- * gsSynthObject.m_sVoice[free voice num].m_nKeyNumber is assigned
- * gsSynthObject.m_sVoice[free voice num].m_nVelocity is assigned
- *----------------------------------------------------------------------------
-*/
-void VMStopNote (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel, EAS_U8 key, EAS_U8 velocity);
-
-/*----------------------------------------------------------------------------
- * VMFindAvailableVoice()
- *----------------------------------------------------------------------------
- * Purpose:
- * Find an available voice and return the voice number if available.
- *
- * Inputs:
- * pnVoiceNumber - really an output, see below
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- * pnVoiceNumber - returns the voice number of available voice if found
- * success - if there is an available voice
- * failure - otherwise
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT VMFindAvailableVoice (S_VOICE_MGR *pVoiceMgr, EAS_INT *pVoiceNumber, EAS_I32 lowVoice, EAS_I32 highVoice);
-
-/*----------------------------------------------------------------------------
- * VMStealVoice()
- *----------------------------------------------------------------------------
- * Purpose:
- * Steal a voice and return the voice number
- *
- * Stealing algorithm: steal the best choice with minimal work, taking into
- * account SP-Midi channel priorities and polyphony allocation.
- *
- * In one pass through all the voices, figure out which voice to steal
- * taking into account a number of different factors:
- * Priority of the voice's MIDI channel
- * Number of voices over the polyphony allocation for voice's MIDI channel
- * Amplitude of the voice
- * Note age
- * Key velocity (for voices that haven't been started yet)
- * If any matching notes are found
- *
- * Inputs:
- * nChannel - the channel that this voice wants to be started on
- * nKeyNumber - the key number for this new voice
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- * pnVoiceNumber - voice stolen
- * EAS_RESULT EAS_SUCCESS - always successful
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT VMStealVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_INT *pVoiceNumber, EAS_U8 channel, EAS_U8 note, EAS_I32 lowVoice, EAS_I32 highVoice);
-
-/*----------------------------------------------------------------------------
- * VMAddSamples()
- *----------------------------------------------------------------------------
- * Purpose:
- * Synthesize the requested number of samples.
- *
- * Inputs:
- * nNumSamplesToAdd - number of samples to write to buffer
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- * number of samples actually written to buffer
- *
- * Side Effects:
- * - samples are added to the presently free buffer
- *
- *----------------------------------------------------------------------------
-*/
-EAS_I32 VMAddSamples (S_VOICE_MGR *pVoiceMgr, EAS_I32 *pMixBuffer, EAS_I32 numSamplesToAdd);
-
-/*----------------------------------------------------------------------------
- * VMProgramChange()
- *----------------------------------------------------------------------------
- * Purpose:
- * Change the instrument (program) for the given channel.
- *
- * Depending on the program number, and the bank selected for this channel, the
- * program may be in ROM, RAM (from SMAF or CMX related RAM wavetable), or
- * Alternate wavetable (from mobile DLS or other DLS file)
- *
- * This function figures out what wavetable should be used, and sets it up as the
- * wavetable to use for this channel. Also the channel may switch from a melodic
- * channel to a rhythm channel, or vice versa.
- *
- * Inputs:
- *
- * Outputs:
- * Side Effects:
- * gsSynthObject.m_sChannel[nChannel].m_nProgramNumber is likely changed
- * gsSynthObject.m_sChannel[nChannel].m_psEAS may be changed
- * gsSynthObject.m_sChannel[nChannel].m_bRhythmChannel may be changed
- *
- *----------------------------------------------------------------------------
-*/
-void VMProgramChange (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel, EAS_U8 program);
-
-/*----------------------------------------------------------------------------
- * VMChannelPressure()
- *----------------------------------------------------------------------------
- * Purpose:
- * Change the channel pressure for the given channel
- *
- * Inputs:
- * nChannel - the MIDI channel
- * nVelocity - the channel pressure value
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- * Side Effects:
- * gsSynthObject.m_sChannel[nChannel].m_nChannelPressure is updated
- *----------------------------------------------------------------------------
-*/
-void VMChannelPressure (S_SYNTH *pSynth, EAS_U8 channel, EAS_U8 value);
-
-/*----------------------------------------------------------------------------
- * VMPitchBend()
- *----------------------------------------------------------------------------
- * Purpose:
- * Change the pitch wheel value for the given channel.
- * This routine constructs the proper 14-bit argument when the calling routine
- * passes the pitch LSB and MSB.
- *
- * Note: some midi disassemblers display a bipolar pitch bend value.
- * We can display the bipolar value using
- * if m_nPitchBend >= 0x2000
- * bipolar pitch bend = postive (m_nPitchBend - 0x2000)
- * else
- * bipolar pitch bend = negative (0x2000 - m_nPitchBend)
- *
- * Inputs:
- * nChannel - the MIDI channel
- * nPitchLSB - the LSB byte from the pitch bend message
- * nPitchMSB - the MSB byte from the message
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- *
- * Side Effects:
- * gsSynthObject.m_sChannel[nChannel].m_nPitchBend is changed
- *
- *----------------------------------------------------------------------------
-*/
-void VMPitchBend (S_SYNTH *pSynth, EAS_U8 channel, EAS_U8 pitchLSB, EAS_U8 pitchMSB);
-
-/*----------------------------------------------------------------------------
- * VMControlChange()
- *----------------------------------------------------------------------------
- * Purpose:
- * Change the controller (or mode) for the given channel.
- *
- * Inputs:
- * nChannel - the MIDI channel
- * nControllerNumber - the controller number
- * nControlValue - the controller number for this control change
- * nControlValue - the value for this control change
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- * Side Effects:
- * gsSynthObject.m_sChannel[nChannel] controller is changed
- *
- *----------------------------------------------------------------------------
-*/
-void VMControlChange (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel, EAS_U8 controller, EAS_U8 value);
-
-/*----------------------------------------------------------------------------
- * VMUpdateRPNStateMachine()
- *----------------------------------------------------------------------------
- * Purpose:
- * Call this function when we want to parse a stream of RPN messages.
- * NOTE: The synth has only one set of global RPN data instead of RPN data
- * per channel.
- * So actually, we don't really need to look at the nChannel parameter,
- * but we pass it to facilitate future upgrades. Furthermore, we only
- * support RPN0 (pitch bend sensitivity), RPN1 (fine tuning) and
- * RPN2 (coarse tuning). Any other RPNs are rejected.
- *
- * Inputs:
- * nChannel - the MIDI channel
- * nControllerNumber - the RPN controller number
- * nControlValue - the value for this control change
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- *
- * Side Effects:
- * gsSynthObject.m_RPN0 (or m_RPN1 or m_RPN2) may be updated if the
- * proper RPN message sequence is parsed.
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT VMUpdateRPNStateMachine (S_SYNTH *pSynth, EAS_U8 channel, EAS_U8 controller, EAS_U8 value);
-
-/*----------------------------------------------------------------------------
- * VMUpdateStaticChannelParameters()
- *----------------------------------------------------------------------------
- * Purpose:
- * Update all of the static channel parameters for channels that have had
- * a controller change values
- * Or if the synth has signalled that all channels must forcibly
- * be updated
- *
- * Inputs:
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- * none
- *
- * Side Effects:
- * - psSynthObject->m_sChannel[].m_nStaticGain and m_nStaticPitch
- * are updated for channels whose controller values have changed
- * or if the synth has signalled that all channels must forcibly
- * be updated
- *----------------------------------------------------------------------------
-*/
-void VMUpdateStaticChannelParameters (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth);
-
-/*----------------------------------------------------------------------------
- * VMReleaseAllDeferredNoteOffs()
- *----------------------------------------------------------------------------
- * Purpose:
- * Call this functin when the sustain flag is presently set but
- * we are now transitioning from damper pedal on to
- * damper pedal off. This means all notes in this channel
- * that received a note off while the damper pedal was on, and
- * had their note-off requests deferred, should now proceed to
- * the release state.
- *
- * Inputs:
- * nChannel - this channel has its sustain pedal transitioning from on to off
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- * Side Effects:
- * any voice with deferred note offs on this channel are updated such that
- *
- *
- *----------------------------------------------------------------------------
-*/
-void VMReleaseAllDeferredNoteOffs (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel);
-
-/*----------------------------------------------------------------------------
- * VMCatchNotesForSustainPedal()
- *----------------------------------------------------------------------------
- * Purpose:
- * Call this function when the sustain flag is presently clear and
- * the damper pedal is off and we are transitioning from damper pedal OFF to
- * damper pedal ON. Currently sounding notes should be left
- * unchanged. However, we should try to "catch" notes if possible.
- * If any notes have levels >= sustain level, catch them,
- * otherwise, let them continue to release.
- *
- * Inputs:
- * nChannel - this channel has its sustain pedal transitioning from on to off
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- * Side Effects:
- * any voice with deferred note offs on this channel are updated such that
- * psVoice->m_sEG1.m_eState = eEnvelopeStateSustainPedal
- *----------------------------------------------------------------------------
-*/
-void VMCatchNotesForSustainPedal (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel);
-
-/*----------------------------------------------------------------------------
- * VMUpdateAllNotesAge()
- *----------------------------------------------------------------------------
- * Purpose:
- * Increment the note age for all voices older than the age of the voice
- * that is stopping, effectively making the voices "younger".
- *
- * Inputs:
- * nAge - age of voice that is going away
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- *
- * Side Effects:
- * m_nAge for some voices is incremented
- *----------------------------------------------------------------------------
-*/
-void VMUpdateAllNotesAge (S_VOICE_MGR *pVoiceMgr, EAS_U16 nAge);
-
-/*----------------------------------------------------------------------------
- * VMFindRegionIndex()
- *----------------------------------------------------------------------------
- * Purpose:
- * Find the region index for the given instrument using the midi key number
- * and the RPN2 (coarse tuning) value. By using RPN2 as part of the
- * region selection process, we reduce the amount a given sample has
- * to be transposed by selecting the closest recorded root instead.
- *
- * Inputs:
- * nChannel - current channel for this note
- * nKeyNumber - current midi note number
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- * pnRegionIndex - valid only if we returned success
- * success if we found the region index number, otherwise
- * failure
- *
- * Side Effects:
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT VMFindRegionIndex (S_VOICE_MGR *pVoiceMgr, EAS_U8 channel, EAS_U8 note, EAS_U16 *pRegionIndex);
-
-/*----------------------------------------------------------------------------
- * VMIncRefCount()
- *----------------------------------------------------------------------------
- * Increment reference count for virtual synth
- *----------------------------------------------------------------------------
-*/
-void VMIncRefCount (S_SYNTH *pSynth);
-
-/*----------------------------------------------------------------------------
- * VMReset()
- *----------------------------------------------------------------------------
- * Purpose:
- * We call this routine to start the process of reseting the synth.
- * This routine sets a flag for the entire synth indicating that we want
- * to reset.
- * We also force all voices to mute quickly.
- * However, we do not actually perform any synthesis in this routine. That
- * is, we do not ramp the voices down from this routine, but instead, we
- * let the "regular" synth processing steps take care of adding the ramp
- * down samples to the output buffer. After we are sure that all voices
- * have completed ramping down, we continue the process of resetting the
- * synth (from another routine).
- *
- * Inputs:
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- *
- * Side Effects:
- * - set a flag (in gsSynthObject.m_nFlags) indicating synth reset requested.
- * - force all voices to update their envelope states to mute
- *
- *----------------------------------------------------------------------------
-*/
-void VMReset (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_BOOL force);
-
-/*----------------------------------------------------------------------------
- * VMMuteAllVoices()
- *----------------------------------------------------------------------------
- * Purpose:
- * We call this in an emergency reset situation.
- * This forces all voices to mute quickly.
- *
- * Inputs:
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- *
- * Side Effects:
- * - forces all voices to update their envelope states to mute
- *
- *----------------------------------------------------------------------------
-*/
-void VMMuteVoice (S_VOICE_MGR *pVoiceMgr, EAS_I32 voiceNum);
-void VMMuteAllVoices (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth);
-
-/*----------------------------------------------------------------------------
- * VMReleaseAllVoices()
- *----------------------------------------------------------------------------
- * Purpose:
- * We call this after we've encountered the end of the Midi file.
- * This ensures all voice are either in release (because we received their
- * note off already) or forces them to mute quickly.
- * We use this as a safety to prevent bad midi files from playing forever.
- *
- * Inputs:
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- *
- * Side Effects:
- * - forces all voices to update their envelope states to release or mute
- *
- *----------------------------------------------------------------------------
-*/
-void VMReleaseAllVoices (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth);
-
-/*----------------------------------------------------------------------------
- * VMAllNotesOff()
- *----------------------------------------------------------------------------
- * Purpose:
- * Quickly mute all notes on the given channel.
- *
- * Inputs:
- * nChannel - quickly turn off all notes on this channel
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- *
- * Side Effects:
- * - forces all voices on this channel to update their envelope states to mute
- *
- *----------------------------------------------------------------------------
-*/
-void VMAllNotesOff (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel);
-
-/*----------------------------------------------------------------------------
- * VMDeferredStopNote()
- *----------------------------------------------------------------------------
- * Purpose:
- * Stop the notes that had deferred note-off requests.
- *
- * Inputs:
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- * None.
- *
- * Side Effects:
- * voices that have had deferred note-off requests are now put into release
- * gsSynthObject.m_sVoice[i].m_nFlags has the VOICE_FLAG_DEFER_MIDI_NOTE_OFF
- * cleared
- *----------------------------------------------------------------------------
-*/
-void VMDeferredStopNote (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth);
-
-/*----------------------------------------------------------------------------
- * VMSetSynthPolyphony()
- *----------------------------------------------------------------------------
- * Purpose:
- * Set the synth to a new polyphony value. Value must be >= 1 and
- * <= MAX_SYNTH_VOICES. This function will pin the polyphony at those limits
- *
- * Inputs:
- * pVoiceMgr pointer to synthesizer data
- * synth synthesizer number (0 = onboard, 1 = DSP)
- * polyphonyCount desired polyphony count
- *
- * Outputs:
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT VMSetSynthPolyphony (S_VOICE_MGR *pVoiceMgr, EAS_I32 synth, EAS_I32 polyphonyCount);
-
-/*----------------------------------------------------------------------------
- * VMGetSynthPolyphony()
- *----------------------------------------------------------------------------
- * Purpose:
- * Set the synth to a new polyphony value. Value must be >= 1 and
- * <= MAX_SYNTH_VOICES. This function will pin the polyphony at those limits
- *
- * Inputs:
- * pVoiceMgr pointer to synthesizer data
- * synth synthesizer number (0 = onboard, 1 = DSP)
- * polyphonyCount desired polyphony count
- *
- * Outputs:
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT VMGetSynthPolyphony (S_VOICE_MGR *pVoiceMgr, EAS_I32 synth, EAS_I32 *pPolyphonyCount);
-
-/*----------------------------------------------------------------------------
- * VMSetPolyphony()
- *----------------------------------------------------------------------------
- * Purpose:
- * Set the virtual synth polyphony. 0 = no limit (i.e. can use
- * all available voices).
- *
- * Inputs:
- * pVoiceMgr pointer to synthesizer data
- * polyphonyCount desired polyphony count
- * pSynth pointer to virtual synth
- *
- * Outputs:
- * Returns error code
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT VMSetPolyphony (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_I32 polyphonyCount);
-
-/*----------------------------------------------------------------------------
- * VMGetPolyphony()
- *----------------------------------------------------------------------------
- * Purpose:
- * Returns the current polyphony setting
- *
- * Inputs:
- * pVoiceMgr pointer to synthesizer data
- * pSynth pointer to virtual synth
- * pPolyphonyCount pointer to variable to receive data
- *
- * Outputs:
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT VMGetPolyphony (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_I32 *pPolyphonyCount);
-
-/*----------------------------------------------------------------------------
- * VMSetPriority()
- *----------------------------------------------------------------------------
- * Purpose:
- * Set the virtual synth priority
- *
- * Inputs:
- * pVoiceMgr pointer to synthesizer data
- * priority new priority
- * pSynth pointer to virtual synth
- *
- * Outputs:
- * Returns error code
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT VMSetPriority (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_I32 priority);
-
-/*----------------------------------------------------------------------------
- * VMGetPriority()
- *----------------------------------------------------------------------------
- * Purpose:
- * Get the virtual synth priority
- *
- * Inputs:
- * pVoiceMgr pointer to synthesizer data
- * pPriority pointer to variable to hold priority
- * pSynth pointer to virtual synth
- *
- * Outputs:
- * Returns error code
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT VMGetPriority (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_I32 *pPriority);
-
-/*----------------------------------------------------------------------------
- * VMSetVolume()
- *----------------------------------------------------------------------------
- * Purpose:
- * Set the master volume for this sequence
- *
- * Inputs:
- * nSynthVolume - the desired master volume
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- *
- *
- * Side Effects:
- * overrides any previously set master volume from sysex
- *
- *----------------------------------------------------------------------------
-*/
-void VMSetVolume (S_SYNTH *pSynth, EAS_U16 masterVolume);
-
-/*----------------------------------------------------------------------------
- * VMSetPitchBendRange()
- *----------------------------------------------------------------------------
- * Set the pitch bend range for the given channel.
- *----------------------------------------------------------------------------
-*/
-void VMSetPitchBendRange (S_SYNTH *pSynth, EAS_INT channel, EAS_I16 pitchBendRange);
-
-/*----------------------------------------------------------------------------
- * VMSetEASLib()
- *----------------------------------------------------------------------------
- * Purpose:
- * Sets the pointer to the sound library
- *
- * Inputs:
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT VMSetGlobalEASLib (S_VOICE_MGR *pVoiceMgr, EAS_SNDLIB_HANDLE pEAS);
-EAS_RESULT VMSetEASLib (S_SYNTH *pSynth, EAS_SNDLIB_HANDLE pEAS);
-
-#ifdef DLS_SYNTHESIZER
-/*----------------------------------------------------------------------------
- * VMSetDLSLib()
- *----------------------------------------------------------------------------
- * Purpose:
- * Sets the pointer to the sound library
- *
- * Inputs:
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT VMSetGlobalDLSLib (EAS_DATA_HANDLE pEASData, EAS_DLSLIB_HANDLE pDLS);
-EAS_RESULT VMSetDLSLib (S_SYNTH *pSynth, EAS_DLSLIB_HANDLE pDLS);
-#endif
-
-/*----------------------------------------------------------------------------
- * VMSetTranposition()
- *----------------------------------------------------------------------------
- * Purpose:
- * Sets the global key transposition used by the synthesizer.
- * Transposes all melodic instruments up or down by the specified
- * amount. Range is limited to +/-12 semitones.
- *
- * Inputs:
- * psEASData - pointer to overall EAS data structure
- * transposition - transpose amount (+/-12)
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-void VMSetTranposition (S_SYNTH *pSynth, EAS_I32 transposition);
-
-/*----------------------------------------------------------------------------
- * VMGetTranposition()
- *----------------------------------------------------------------------------
- * Purpose:
- * Gets the global key transposition used by the synthesizer.
- * Transposes all melodic instruments up or down by the specified
- * amount. Range is limited to +/-12 semitones.
- *
- * Inputs:
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-void VMGetTranposition (S_SYNTH *pSynth, EAS_I32 *pTransposition);
-
-/*----------------------------------------------------------------------------
- * VMGetNoteCount()
- *----------------------------------------------------------------------------
-* Returns the total note count
-*----------------------------------------------------------------------------
-*/
-EAS_I32 VMGetNoteCount (S_SYNTH *pSynth);
-
-/*----------------------------------------------------------------------------
- * VMRender()
- *----------------------------------------------------------------------------
- * Purpose:
- * This routine renders a frame of audio
- *
- * Inputs:
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- * pVoicesRendered - number of voices rendered this frame
- *
- * Side Effects:
- * sets psMidiObject->m_nMaxWorkloadPerFrame
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT VMRender (S_VOICE_MGR *pVoiceMgr, EAS_I32 numSamples, EAS_I32 *pMixBuffer, EAS_I32 *pVoicesRendered);
-
-/*----------------------------------------------------------------------------
- * VMInitWorkload()
- *----------------------------------------------------------------------------
- * Purpose:
- * Clears the workload counter
- *
- * Inputs:
- * pVoiceMgr - pointer to instance data
- *
- * Outputs:
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-void VMInitWorkload (S_VOICE_MGR *pVoiceMgr);
-
-/*----------------------------------------------------------------------------
- * VMSetWorkload()
- *----------------------------------------------------------------------------
- * Purpose:
- * Sets the max workload for a single frame.
- *
- * Inputs:
- * pVoiceMgr - pointer to instance data
- *
- * Outputs:
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-void VMSetWorkload (S_VOICE_MGR *pVoiceMgr, EAS_I32 maxWorkLoad);
-
-/*----------------------------------------------------------------------------
- * VMCheckWorkload()
- *----------------------------------------------------------------------------
- * Purpose:
- * Checks to see if work load has been exceeded on this frame.
- *
- * Inputs:
- * pVoiceMgr - pointer to instance data
- *
- * Outputs:
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_BOOL VMCheckWorkload (S_VOICE_MGR *pVoiceMgr);
-
-/*----------------------------------------------------------------------------
- * VMActiveVoices()
- *----------------------------------------------------------------------------
- * Purpose:
- * Returns the number of active voices in the synthesizer.
- *
- * Inputs:
- * pEASData - pointer to instance data
- *
- * Outputs:
- * Returns the number of active voices
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_I32 VMActiveVoices (S_SYNTH *pSynth);
-
-/*----------------------------------------------------------------------------
- * VMMIDIShutdown()
- *----------------------------------------------------------------------------
- * Purpose:
- * Clean up any Synth related system issues.
- *
- * Inputs:
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- * None
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-void VMMIDIShutdown (S_EAS_DATA *pEASData, S_SYNTH *pSynth);
-
-/*----------------------------------------------------------------------------
- * VMShutdown()
- *----------------------------------------------------------------------------
- * Purpose:
- * Clean up any Synth related system issues.
- *
- * Inputs:
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- * None
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-void VMShutdown (S_EAS_DATA *pEASData);
-
-#ifdef EXTERNAL_AUDIO
-/*----------------------------------------------------------------------------
- * EAS_RegExtAudioCallback()
- *----------------------------------------------------------------------------
- * Register a callback for external audio processing
- *----------------------------------------------------------------------------
-*/
-void VMRegExtAudioCallback (S_SYNTH *pSynth, EAS_VOID_PTR pInstData, EAS_EXT_PRG_CHG_FUNC cbProgChgFunc, EAS_EXT_EVENT_FUNC cbEventFunc);
-
-/*----------------------------------------------------------------------------
- * VMGetMIDIControllers()
- *----------------------------------------------------------------------------
- * Returns the MIDI controller values on the specified channel
- *----------------------------------------------------------------------------
-*/
-void VMGetMIDIControllers (S_SYNTH *pSynth, EAS_U8 channel, S_MIDI_CONTROLLERS *pControl);
-#endif
-
-#ifdef _SPLIT_ARCHITECTURE
-/*----------------------------------------------------------------------------
- * VMStartFrame()
- *----------------------------------------------------------------------------
- * Purpose:
- * Starts an audio frame
- *
- * Inputs:
- *
- * Outputs:
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_BOOL VMStartFrame (S_EAS_DATA *pEASData);
-
-/*----------------------------------------------------------------------------
- * VMEndFrame()
- *----------------------------------------------------------------------------
- * Purpose:
- * Stops an audio frame
- *
- * Inputs:
- *
- * Outputs:
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_BOOL VMEndFrame (S_EAS_DATA *pEASData);
-#endif
-
-#endif /* #ifdef _EAS_VM_PROTOS_H */
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 736 $
+ * $Date: 2007-06-22 13:51:24 -0700 (Fri, 22 Jun 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+#ifndef _EAS_VM_PROTOS_H
+#define _EAS_VM_PROTOS_H
+
+// includes
+#include "eas_data.h"
+#include "eas_sndlib.h"
+
+/*----------------------------------------------------------------------------
+ * VMInitialize()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ *
+ * Inputs:
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT VMInitialize (S_EAS_DATA *pEASData);
+
+/*----------------------------------------------------------------------------
+ * VMInitMIDI()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ *
+ * Inputs:
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT VMInitMIDI (S_EAS_DATA *pEASData, S_SYNTH **ppSynth);
+
+/*----------------------------------------------------------------------------
+ * VMInitializeAllChannels()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ *
+ * Inputs:
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ *
+ *----------------------------------------------------------------------------
+*/
+void VMInitializeAllChannels (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth);
+
+/*----------------------------------------------------------------------------
+ * VMResetControllers()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ *
+ * Inputs:
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ *
+ *----------------------------------------------------------------------------
+*/
+void VMResetControllers (S_SYNTH *pSynth);
+
+/*----------------------------------------------------------------------------
+ * VMInitMIPTable()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Initialize the SP-MIDI MIP table
+ *
+ * Inputs:
+ * pEASData - pointer to synthesizer instance data
+ * mute - EAS_FALSE to unmute channels, EAS_TRUE to mute
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+void VMInitMIPTable (S_SYNTH *pSynth);
+
+/*----------------------------------------------------------------------------
+ * VMSetMIPEntry()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Sets the priority and MIP level for a MIDI channel
+ *
+ * Inputs:
+ * pEASData - pointer to synthesizer instance data
+ * channel - MIDI channel number
+ * priority - priority (0-15 with 0 = highest priority)
+ * mip - maximum instantaneous polyphony
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+void VMSetMIPEntry (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel, EAS_U8 priority, EAS_U8 mip);
+
+/*----------------------------------------------------------------------------
+ * VMUpdateMIPTable()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * This routine is called when the polyphony count in the synthesizer changes
+ *
+ * Inputs:
+ * pEASData - pointer to synthesizer instance data
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+void VMUpdateMIPTable (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth);
+
+/*----------------------------------------------------------------------------
+ * VMInitializeAllVoices()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ *
+ * Inputs:
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ *
+ *----------------------------------------------------------------------------
+*/
+void VMInitializeAllVoices (S_VOICE_MGR *pVoiceMgr, EAS_INT vSynthNum);
+
+/*----------------------------------------------------------------------------
+ * VMStartNote()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Update the synth's state to play the requested note on the requested
+ * channel if possible.
+ *
+ * Inputs:
+ * nChannel - the MIDI channel
+ * nKeyNumber - the MIDI key number for this note
+ * nNoteVelocity - the key velocity for this note
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ *
+ *----------------------------------------------------------------------------
+*/
+void VMStartNote (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel, EAS_U8 note, EAS_U8 velocity);
+
+/*----------------------------------------------------------------------------
+ * VMCheckKeyGroup()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * If the note that we've been asked to start is in the same key group as
+ * any currently playing notes, then we must shut down the currently playing
+ * note in the same key group and then start the newly requested note.
+ *
+ * Inputs:
+ * nChannel - synth channel that wants to start a new note
+ * nKeyNumber - new note's midi note number
+ * nRegionIndex - calling routine finds this index and gives to us
+ * nNoteVelocity - new note's velocity
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ * pbVoiceStealingRequired - flag: this routine sets true if we needed to
+ * steal a voice
+ *
+ * Side Effects:
+ * gsSynthObject.m_sVoice[free voice num].m_nKeyNumber may be assigned
+ * gsSynthObject.m_sVoice[free voice num].m_nVelocity may be assigned
+ *----------------------------------------------------------------------------
+*/
+void VMCheckKeyGroup (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U16 keyGroup, EAS_U8 channel);
+
+/*----------------------------------------------------------------------------
+ * VMCheckPolyphonyLimiting()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * We only play at most 2 of the same note on a MIDI channel.
+ * E.g., if we are asked to start note 36, and there are already two voices
+ * that are playing note 36, then we must steal the voice playing
+ * the oldest note 36 and use that stolen voice to play the new note 36.
+ *
+ * Inputs:
+ * nChannel - synth channel that wants to start a new note
+ * nKeyNumber - new note's midi note number
+ * nNoteVelocity - new note's velocity
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ * pbVoiceStealingRequired - flag: this routine sets true if we needed to
+ * steal a voice
+ * *
+ * Side Effects:
+ * psSynthObject->m_sVoice[free voice num].m_nKeyNumber may be assigned
+ * psSynthObject->m_sVoice[free voice num].m_nVelocity may be assigned
+ *----------------------------------------------------------------------------
+*/
+EAS_BOOL VMCheckPolyphonyLimiting (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel, EAS_U8 note, EAS_U8 velocity, EAS_U16 regionIndex, EAS_I32 lowVoice, EAS_I32 highVoice);
+
+/*----------------------------------------------------------------------------
+ * VMStopNote()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Update the synth's state to end the requested note on the requested
+ * channel.
+ *
+ * Inputs:
+ * nChannel - the MIDI channel
+ * nKeyNumber - the key number of the note to stop
+ * nNoteVelocity - the note-off velocity
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ * Side Effects:
+ * gsSynthObject.m_sVoice[free voice num].m_nSynthChannel may be assigned
+ * gsSynthObject.m_sVoice[free voice num].m_nKeyNumber is assigned
+ * gsSynthObject.m_sVoice[free voice num].m_nVelocity is assigned
+ *----------------------------------------------------------------------------
+*/
+void VMStopNote (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel, EAS_U8 key, EAS_U8 velocity);
+
+/*----------------------------------------------------------------------------
+ * VMFindAvailableVoice()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Find an available voice and return the voice number if available.
+ *
+ * Inputs:
+ * pnVoiceNumber - really an output, see below
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ * pnVoiceNumber - returns the voice number of available voice if found
+ * success - if there is an available voice
+ * failure - otherwise
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT VMFindAvailableVoice (S_VOICE_MGR *pVoiceMgr, EAS_INT *pVoiceNumber, EAS_I32 lowVoice, EAS_I32 highVoice);
+
+/*----------------------------------------------------------------------------
+ * VMStealVoice()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Steal a voice and return the voice number
+ *
+ * Stealing algorithm: steal the best choice with minimal work, taking into
+ * account SP-Midi channel priorities and polyphony allocation.
+ *
+ * In one pass through all the voices, figure out which voice to steal
+ * taking into account a number of different factors:
+ * Priority of the voice's MIDI channel
+ * Number of voices over the polyphony allocation for voice's MIDI channel
+ * Amplitude of the voice
+ * Note age
+ * Key velocity (for voices that haven't been started yet)
+ * If any matching notes are found
+ *
+ * Inputs:
+ * nChannel - the channel that this voice wants to be started on
+ * nKeyNumber - the key number for this new voice
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ * pnVoiceNumber - voice stolen
+ * EAS_RESULT EAS_SUCCESS - always successful
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT VMStealVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_INT *pVoiceNumber, EAS_U8 channel, EAS_U8 note, EAS_I32 lowVoice, EAS_I32 highVoice);
+
+/*----------------------------------------------------------------------------
+ * VMAddSamples()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Synthesize the requested number of samples.
+ *
+ * Inputs:
+ * nNumSamplesToAdd - number of samples to write to buffer
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ * number of samples actually written to buffer
+ *
+ * Side Effects:
+ * - samples are added to the presently free buffer
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_I32 VMAddSamples (S_VOICE_MGR *pVoiceMgr, EAS_I32 *pMixBuffer, EAS_I32 numSamplesToAdd);
+
+/*----------------------------------------------------------------------------
+ * VMProgramChange()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Change the instrument (program) for the given channel.
+ *
+ * Depending on the program number, and the bank selected for this channel, the
+ * program may be in ROM, RAM (from SMAF or CMX related RAM wavetable), or
+ * Alternate wavetable (from mobile DLS or other DLS file)
+ *
+ * This function figures out what wavetable should be used, and sets it up as the
+ * wavetable to use for this channel. Also the channel may switch from a melodic
+ * channel to a rhythm channel, or vice versa.
+ *
+ * Inputs:
+ *
+ * Outputs:
+ * Side Effects:
+ * gsSynthObject.m_sChannel[nChannel].m_nProgramNumber is likely changed
+ * gsSynthObject.m_sChannel[nChannel].m_psEAS may be changed
+ * gsSynthObject.m_sChannel[nChannel].m_bRhythmChannel may be changed
+ *
+ *----------------------------------------------------------------------------
+*/
+void VMProgramChange (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel, EAS_U8 program);
+
+/*----------------------------------------------------------------------------
+ * VMChannelPressure()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Change the channel pressure for the given channel
+ *
+ * Inputs:
+ * nChannel - the MIDI channel
+ * nVelocity - the channel pressure value
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ * Side Effects:
+ * gsSynthObject.m_sChannel[nChannel].m_nChannelPressure is updated
+ *----------------------------------------------------------------------------
+*/
+void VMChannelPressure (S_SYNTH *pSynth, EAS_U8 channel, EAS_U8 value);
+
+/*----------------------------------------------------------------------------
+ * VMPitchBend()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Change the pitch wheel value for the given channel.
+ * This routine constructs the proper 14-bit argument when the calling routine
+ * passes the pitch LSB and MSB.
+ *
+ * Note: some midi disassemblers display a bipolar pitch bend value.
+ * We can display the bipolar value using
+ * if m_nPitchBend >= 0x2000
+ * bipolar pitch bend = postive (m_nPitchBend - 0x2000)
+ * else
+ * bipolar pitch bend = negative (0x2000 - m_nPitchBend)
+ *
+ * Inputs:
+ * nChannel - the MIDI channel
+ * nPitchLSB - the LSB byte from the pitch bend message
+ * nPitchMSB - the MSB byte from the message
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ * gsSynthObject.m_sChannel[nChannel].m_nPitchBend is changed
+ *
+ *----------------------------------------------------------------------------
+*/
+void VMPitchBend (S_SYNTH *pSynth, EAS_U8 channel, EAS_U8 pitchLSB, EAS_U8 pitchMSB);
+
+/*----------------------------------------------------------------------------
+ * VMControlChange()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Change the controller (or mode) for the given channel.
+ *
+ * Inputs:
+ * nChannel - the MIDI channel
+ * nControllerNumber - the controller number
+ * nControlValue - the controller number for this control change
+ * nControlValue - the value for this control change
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ * Side Effects:
+ * gsSynthObject.m_sChannel[nChannel] controller is changed
+ *
+ *----------------------------------------------------------------------------
+*/
+void VMControlChange (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel, EAS_U8 controller, EAS_U8 value);
+
+/*----------------------------------------------------------------------------
+ * VMUpdateRPNStateMachine()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Call this function when we want to parse a stream of RPN messages.
+ * NOTE: The synth has only one set of global RPN data instead of RPN data
+ * per channel.
+ * So actually, we don't really need to look at the nChannel parameter,
+ * but we pass it to facilitate future upgrades. Furthermore, we only
+ * support RPN0 (pitch bend sensitivity), RPN1 (fine tuning) and
+ * RPN2 (coarse tuning). Any other RPNs are rejected.
+ *
+ * Inputs:
+ * nChannel - the MIDI channel
+ * nControllerNumber - the RPN controller number
+ * nControlValue - the value for this control change
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ * gsSynthObject.m_RPN0 (or m_RPN1 or m_RPN2) may be updated if the
+ * proper RPN message sequence is parsed.
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT VMUpdateRPNStateMachine (S_SYNTH *pSynth, EAS_U8 channel, EAS_U8 controller, EAS_U8 value);
+
+/*----------------------------------------------------------------------------
+ * VMUpdateStaticChannelParameters()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Update all of the static channel parameters for channels that have had
+ * a controller change values
+ * Or if the synth has signalled that all channels must forcibly
+ * be updated
+ *
+ * Inputs:
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ * none
+ *
+ * Side Effects:
+ * - psSynthObject->m_sChannel[].m_nStaticGain and m_nStaticPitch
+ * are updated for channels whose controller values have changed
+ * or if the synth has signalled that all channels must forcibly
+ * be updated
+ *----------------------------------------------------------------------------
+*/
+void VMUpdateStaticChannelParameters (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth);
+
+/*----------------------------------------------------------------------------
+ * VMReleaseAllDeferredNoteOffs()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Call this functin when the sustain flag is presently set but
+ * we are now transitioning from damper pedal on to
+ * damper pedal off. This means all notes in this channel
+ * that received a note off while the damper pedal was on, and
+ * had their note-off requests deferred, should now proceed to
+ * the release state.
+ *
+ * Inputs:
+ * nChannel - this channel has its sustain pedal transitioning from on to off
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ * Side Effects:
+ * any voice with deferred note offs on this channel are updated such that
+ *
+ *
+ *----------------------------------------------------------------------------
+*/
+void VMReleaseAllDeferredNoteOffs (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel);
+
+/*----------------------------------------------------------------------------
+ * VMCatchNotesForSustainPedal()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Call this function when the sustain flag is presently clear and
+ * the damper pedal is off and we are transitioning from damper pedal OFF to
+ * damper pedal ON. Currently sounding notes should be left
+ * unchanged. However, we should try to "catch" notes if possible.
+ * If any notes have levels >= sustain level, catch them,
+ * otherwise, let them continue to release.
+ *
+ * Inputs:
+ * nChannel - this channel has its sustain pedal transitioning from on to off
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ * Side Effects:
+ * any voice with deferred note offs on this channel are updated such that
+ * psVoice->m_sEG1.m_eState = eEnvelopeStateSustainPedal
+ *----------------------------------------------------------------------------
+*/
+void VMCatchNotesForSustainPedal (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel);
+
+/*----------------------------------------------------------------------------
+ * VMUpdateAllNotesAge()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Increment the note age for all voices older than the age of the voice
+ * that is stopping, effectively making the voices "younger".
+ *
+ * Inputs:
+ * nAge - age of voice that is going away
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ * m_nAge for some voices is incremented
+ *----------------------------------------------------------------------------
+*/
+void VMUpdateAllNotesAge (S_VOICE_MGR *pVoiceMgr, EAS_U16 nAge);
+
+/*----------------------------------------------------------------------------
+ * VMFindRegionIndex()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Find the region index for the given instrument using the midi key number
+ * and the RPN2 (coarse tuning) value. By using RPN2 as part of the
+ * region selection process, we reduce the amount a given sample has
+ * to be transposed by selecting the closest recorded root instead.
+ *
+ * Inputs:
+ * nChannel - current channel for this note
+ * nKeyNumber - current midi note number
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ * pnRegionIndex - valid only if we returned success
+ * success if we found the region index number, otherwise
+ * failure
+ *
+ * Side Effects:
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT VMFindRegionIndex (S_VOICE_MGR *pVoiceMgr, EAS_U8 channel, EAS_U8 note, EAS_U16 *pRegionIndex);
+
+/*----------------------------------------------------------------------------
+ * VMIncRefCount()
+ *----------------------------------------------------------------------------
+ * Increment reference count for virtual synth
+ *----------------------------------------------------------------------------
+*/
+void VMIncRefCount (S_SYNTH *pSynth);
+
+/*----------------------------------------------------------------------------
+ * VMReset()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * We call this routine to start the process of reseting the synth.
+ * This routine sets a flag for the entire synth indicating that we want
+ * to reset.
+ * We also force all voices to mute quickly.
+ * However, we do not actually perform any synthesis in this routine. That
+ * is, we do not ramp the voices down from this routine, but instead, we
+ * let the "regular" synth processing steps take care of adding the ramp
+ * down samples to the output buffer. After we are sure that all voices
+ * have completed ramping down, we continue the process of resetting the
+ * synth (from another routine).
+ *
+ * Inputs:
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ * - set a flag (in gsSynthObject.m_nFlags) indicating synth reset requested.
+ * - force all voices to update their envelope states to mute
+ *
+ *----------------------------------------------------------------------------
+*/
+void VMReset (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_BOOL force);
+
+/*----------------------------------------------------------------------------
+ * VMMuteAllVoices()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * We call this in an emergency reset situation.
+ * This forces all voices to mute quickly.
+ *
+ * Inputs:
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ * - forces all voices to update their envelope states to mute
+ *
+ *----------------------------------------------------------------------------
+*/
+void VMMuteVoice (S_VOICE_MGR *pVoiceMgr, EAS_I32 voiceNum);
+void VMMuteAllVoices (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth);
+
+/*----------------------------------------------------------------------------
+ * VMReleaseAllVoices()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * We call this after we've encountered the end of the Midi file.
+ * This ensures all voice are either in release (because we received their
+ * note off already) or forces them to mute quickly.
+ * We use this as a safety to prevent bad midi files from playing forever.
+ *
+ * Inputs:
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ * - forces all voices to update their envelope states to release or mute
+ *
+ *----------------------------------------------------------------------------
+*/
+void VMReleaseAllVoices (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth);
+
+/*----------------------------------------------------------------------------
+ * VMAllNotesOff()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Quickly mute all notes on the given channel.
+ *
+ * Inputs:
+ * nChannel - quickly turn off all notes on this channel
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ * - forces all voices on this channel to update their envelope states to mute
+ *
+ *----------------------------------------------------------------------------
+*/
+void VMAllNotesOff (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel);
+
+/*----------------------------------------------------------------------------
+ * VMDeferredStopNote()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Stop the notes that had deferred note-off requests.
+ *
+ * Inputs:
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ * None.
+ *
+ * Side Effects:
+ * voices that have had deferred note-off requests are now put into release
+ * gsSynthObject.m_sVoice[i].m_nFlags has the VOICE_FLAG_DEFER_MIDI_NOTE_OFF
+ * cleared
+ *----------------------------------------------------------------------------
+*/
+void VMDeferredStopNote (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth);
+
+/*----------------------------------------------------------------------------
+ * VMSetSynthPolyphony()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Set the synth to a new polyphony value. Value must be >= 1 and
+ * <= MAX_SYNTH_VOICES. This function will pin the polyphony at those limits
+ *
+ * Inputs:
+ * pVoiceMgr pointer to synthesizer data
+ * synth synthesizer number (0 = onboard, 1 = DSP)
+ * polyphonyCount desired polyphony count
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT VMSetSynthPolyphony (S_VOICE_MGR *pVoiceMgr, EAS_I32 synth, EAS_I32 polyphonyCount);
+
+/*----------------------------------------------------------------------------
+ * VMGetSynthPolyphony()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Set the synth to a new polyphony value. Value must be >= 1 and
+ * <= MAX_SYNTH_VOICES. This function will pin the polyphony at those limits
+ *
+ * Inputs:
+ * pVoiceMgr pointer to synthesizer data
+ * synth synthesizer number (0 = onboard, 1 = DSP)
+ * polyphonyCount desired polyphony count
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT VMGetSynthPolyphony (S_VOICE_MGR *pVoiceMgr, EAS_I32 synth, EAS_I32 *pPolyphonyCount);
+
+/*----------------------------------------------------------------------------
+ * VMSetPolyphony()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Set the virtual synth polyphony. 0 = no limit (i.e. can use
+ * all available voices).
+ *
+ * Inputs:
+ * pVoiceMgr pointer to synthesizer data
+ * polyphonyCount desired polyphony count
+ * pSynth pointer to virtual synth
+ *
+ * Outputs:
+ * Returns error code
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT VMSetPolyphony (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_I32 polyphonyCount);
+
+/*----------------------------------------------------------------------------
+ * VMGetPolyphony()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Returns the current polyphony setting
+ *
+ * Inputs:
+ * pVoiceMgr pointer to synthesizer data
+ * pSynth pointer to virtual synth
+ * pPolyphonyCount pointer to variable to receive data
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT VMGetPolyphony (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_I32 *pPolyphonyCount);
+
+/*----------------------------------------------------------------------------
+ * VMSetPriority()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Set the virtual synth priority
+ *
+ * Inputs:
+ * pVoiceMgr pointer to synthesizer data
+ * priority new priority
+ * pSynth pointer to virtual synth
+ *
+ * Outputs:
+ * Returns error code
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT VMSetPriority (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_I32 priority);
+
+/*----------------------------------------------------------------------------
+ * VMGetPriority()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Get the virtual synth priority
+ *
+ * Inputs:
+ * pVoiceMgr pointer to synthesizer data
+ * pPriority pointer to variable to hold priority
+ * pSynth pointer to virtual synth
+ *
+ * Outputs:
+ * Returns error code
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT VMGetPriority (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_I32 *pPriority);
+
+/*----------------------------------------------------------------------------
+ * VMSetVolume()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Set the master volume for this sequence
+ *
+ * Inputs:
+ * nSynthVolume - the desired master volume
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ * overrides any previously set master volume from sysex
+ *
+ *----------------------------------------------------------------------------
+*/
+void VMSetVolume (S_SYNTH *pSynth, EAS_U16 masterVolume);
+
+/*----------------------------------------------------------------------------
+ * VMSetPitchBendRange()
+ *----------------------------------------------------------------------------
+ * Set the pitch bend range for the given channel.
+ *----------------------------------------------------------------------------
+*/
+void VMSetPitchBendRange (S_SYNTH *pSynth, EAS_INT channel, EAS_I16 pitchBendRange);
+
+/*----------------------------------------------------------------------------
+ * VMSetEASLib()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Sets the pointer to the sound library
+ *
+ * Inputs:
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT VMSetGlobalEASLib (S_VOICE_MGR *pVoiceMgr, EAS_SNDLIB_HANDLE pEAS);
+EAS_RESULT VMSetEASLib (S_SYNTH *pSynth, EAS_SNDLIB_HANDLE pEAS);
+
+#ifdef DLS_SYNTHESIZER
+/*----------------------------------------------------------------------------
+ * VMSetDLSLib()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Sets the pointer to the sound library
+ *
+ * Inputs:
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT VMSetGlobalDLSLib (EAS_DATA_HANDLE pEASData, EAS_DLSLIB_HANDLE pDLS);
+EAS_RESULT VMSetDLSLib (S_SYNTH *pSynth, EAS_DLSLIB_HANDLE pDLS);
+#endif
+
+/*----------------------------------------------------------------------------
+ * VMSetTranposition()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Sets the global key transposition used by the synthesizer.
+ * Transposes all melodic instruments up or down by the specified
+ * amount. Range is limited to +/-12 semitones.
+ *
+ * Inputs:
+ * psEASData - pointer to overall EAS data structure
+ * transposition - transpose amount (+/-12)
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+void VMSetTranposition (S_SYNTH *pSynth, EAS_I32 transposition);
+
+/*----------------------------------------------------------------------------
+ * VMGetTranposition()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Gets the global key transposition used by the synthesizer.
+ * Transposes all melodic instruments up or down by the specified
+ * amount. Range is limited to +/-12 semitones.
+ *
+ * Inputs:
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+void VMGetTranposition (S_SYNTH *pSynth, EAS_I32 *pTransposition);
+
+/*----------------------------------------------------------------------------
+ * VMGetNoteCount()
+ *----------------------------------------------------------------------------
+* Returns the total note count
+*----------------------------------------------------------------------------
+*/
+EAS_I32 VMGetNoteCount (S_SYNTH *pSynth);
+
+/*----------------------------------------------------------------------------
+ * VMRender()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * This routine renders a frame of audio
+ *
+ * Inputs:
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ * pVoicesRendered - number of voices rendered this frame
+ *
+ * Side Effects:
+ * sets psMidiObject->m_nMaxWorkloadPerFrame
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT VMRender (S_VOICE_MGR *pVoiceMgr, EAS_I32 numSamples, EAS_I32 *pMixBuffer, EAS_I32 *pVoicesRendered);
+
+/*----------------------------------------------------------------------------
+ * VMInitWorkload()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Clears the workload counter
+ *
+ * Inputs:
+ * pVoiceMgr - pointer to instance data
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+void VMInitWorkload (S_VOICE_MGR *pVoiceMgr);
+
+/*----------------------------------------------------------------------------
+ * VMSetWorkload()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Sets the max workload for a single frame.
+ *
+ * Inputs:
+ * pVoiceMgr - pointer to instance data
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+void VMSetWorkload (S_VOICE_MGR *pVoiceMgr, EAS_I32 maxWorkLoad);
+
+/*----------------------------------------------------------------------------
+ * VMCheckWorkload()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Checks to see if work load has been exceeded on this frame.
+ *
+ * Inputs:
+ * pVoiceMgr - pointer to instance data
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_BOOL VMCheckWorkload (S_VOICE_MGR *pVoiceMgr);
+
+/*----------------------------------------------------------------------------
+ * VMActiveVoices()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Returns the number of active voices in the synthesizer.
+ *
+ * Inputs:
+ * pEASData - pointer to instance data
+ *
+ * Outputs:
+ * Returns the number of active voices
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_I32 VMActiveVoices (S_SYNTH *pSynth);
+
+/*----------------------------------------------------------------------------
+ * VMMIDIShutdown()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Clean up any Synth related system issues.
+ *
+ * Inputs:
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ * None
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+void VMMIDIShutdown (S_EAS_DATA *pEASData, S_SYNTH *pSynth);
+
+/*----------------------------------------------------------------------------
+ * VMShutdown()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Clean up any Synth related system issues.
+ *
+ * Inputs:
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ * None
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+void VMShutdown (S_EAS_DATA *pEASData);
+
+#ifdef EXTERNAL_AUDIO
+/*----------------------------------------------------------------------------
+ * EAS_RegExtAudioCallback()
+ *----------------------------------------------------------------------------
+ * Register a callback for external audio processing
+ *----------------------------------------------------------------------------
+*/
+void VMRegExtAudioCallback (S_SYNTH *pSynth, EAS_VOID_PTR pInstData, EAS_EXT_PRG_CHG_FUNC cbProgChgFunc, EAS_EXT_EVENT_FUNC cbEventFunc);
+
+/*----------------------------------------------------------------------------
+ * VMGetMIDIControllers()
+ *----------------------------------------------------------------------------
+ * Returns the MIDI controller values on the specified channel
+ *----------------------------------------------------------------------------
+*/
+void VMGetMIDIControllers (S_SYNTH *pSynth, EAS_U8 channel, S_MIDI_CONTROLLERS *pControl);
+#endif
+
+#ifdef _SPLIT_ARCHITECTURE
+/*----------------------------------------------------------------------------
+ * VMStartFrame()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Starts an audio frame
+ *
+ * Inputs:
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_BOOL VMStartFrame (S_EAS_DATA *pEASData);
+
+/*----------------------------------------------------------------------------
+ * VMEndFrame()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Stops an audio frame
+ *
+ * Inputs:
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_BOOL VMEndFrame (S_EAS_DATA *pEASData);
+#endif
+
+#endif /* #ifdef _EAS_VM_PROTOS_H */
+
diff --git a/arm-hybrid-22k/lib_src/eas_voicemgt.c b/arm-hybrid-22k/lib_src/eas_voicemgt.c
index 873f29d..ab0b776 100644
--- a/arm-hybrid-22k/lib_src/eas_voicemgt.c
+++ b/arm-hybrid-22k/lib_src/eas_voicemgt.c
@@ -1,12 +1,12 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_voicemgt.c
- *
- * Contents and purpose:
- * Implements the synthesizer functions.
- *
- * Copyright Sonic Network Inc. 2004
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_voicemgt.c
+ *
+ * Contents and purpose:
+ * Implements the synthesizer functions.
+ *
+ * Copyright Sonic Network Inc. 2004
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,3953 +19,3953 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 794 $
- * $Date: 2007-08-01 00:08:48 -0700 (Wed, 01 Aug 2007) $
- *----------------------------------------------------------------------------
-*/
-
-/* includes */
-#include "eas.h"
-#include "eas_data.h"
-#include "eas_config.h"
-#include "eas_report.h"
-#include "eas_midictrl.h"
-#include "eas_host.h"
-#include "eas_synth_protos.h"
-#include "eas_vm_protos.h"
-
-#ifdef DLS_SYNTHESIZER
-#include "eas_mdls.h"
-#endif
-
-// #define _DEBUG_VM
-
-/* some defines for workload */
-#define WORKLOAD_AMOUNT_SMALL_INCREMENT 5
-#define WORKLOAD_AMOUNT_START_NOTE 10
-#define WORKLOAD_AMOUNT_STOP_NOTE 10
-#define WORKLOAD_AMOUNT_KEY_GROUP 10
-#define WORKLOAD_AMOUNT_POLY_LIMIT 10
-
-/* pointer to base sound library */
-extern S_EAS easSoundLib;
-
-#ifdef TEST_HARNESS
-extern S_EAS easTestLib;
-EAS_SNDLIB_HANDLE VMGetLibHandle(EAS_INT libNum)
-{
- switch (libNum)
- {
- case 0:
- return &easSoundLib;
-#ifdef _WT_SYNTH
- case 1:
- return &easTestLib;
-#endif
- default:
- return NULL;
- }
-}
-#endif
-
-/* pointer to synthesizer interface(s) */
-#ifdef _WT_SYNTH
-extern const S_SYNTH_INTERFACE wtSynth;
-#endif
-
-#ifdef _FM_SYNTH
-extern const S_SYNTH_INTERFACE fmSynth;
-#endif
-
-typedef S_SYNTH_INTERFACE *S_SYNTH_INTERFACE_HANDLE;
-
-/* wavetable on MCU */
-#if defined(EAS_WT_SYNTH)
-const S_SYNTH_INTERFACE *const pPrimarySynth = &wtSynth;
-
-/* FM on MCU */
-#elif defined(EAS_FM_SYNTH)
-const S_SYNTH_INTERFACE *const pPrimarySynth = &fmSynth;
-
-/* wavetable drums on MCU, FM melodic on DSP */
-#elif defined(EAS_HYBRID_SYNTH)
-const S_SYNTH_INTERFACE *const pPrimarySynth = &wtSynth;
-const S_SYNTH_INTERFACE *const pSecondarySynth = &fmSynth;
-
-/* wavetable drums on MCU, wavetable melodic on DSP */
-#elif defined(EAS_SPLIT_WT_SYNTH)
-const S_SYNTH_INTERFACE *const pPrimarySynth = &wtSynth;
-extern const S_FRAME_INTERFACE wtFrameInterface;
-const S_FRAME_INTERFACE *const pFrameInterface = &wtFrameInterface;
-
-/* wavetable drums on MCU, FM melodic on DSP */
-#elif defined(EAS_SPLIT_HYBRID_SYNTH)
-const S_SYNTH_INTERFACE *const pPrimarySynth = &wtSynth;
-const S_SYNTH_INTERFACE *const pSecondarySynth = &fmSynth;
-extern const S_FRAME_INTERFACE fmFrameInterface;
-const S_FRAME_INTERFACE *const pFrameInterface = &fmFrameInterface;
-
-/* FM on DSP */
-#elif defined(EAS_SPLIT_FM_SYNTH)
-const S_SYNTH_INTERFACE *const pPrimarySynth = &fmSynth;
-extern const S_FRAME_INTERFACE fmFrameInterface;
-const S_FRAME_INTERFACE *const pFrameInterface = &fmFrameInterface;
-
-#else
-#error "Undefined architecture option"
-#endif
-
-/*----------------------------------------------------------------------------
- * inline functions
- *----------------------------------------------------------------------------
-*/
-EAS_INLINE const S_REGION* GetRegionPtr (S_SYNTH *pSynth, EAS_U16 regionIndex)
-{
-#if defined(DLS_SYNTHESIZER)
- if (regionIndex & FLAG_RGN_IDX_DLS_SYNTH)
- return &pSynth->pDLS->pDLSRegions[regionIndex & REGION_INDEX_MASK].wtRegion.region;
-#endif
-#if defined(_HYBRID_SYNTH)
- if (regionIndex & FLAG_RGN_IDX_FM_SYNTH)
- return &pSynth->pEAS->pFMRegions[regionIndex & REGION_INDEX_MASK].region;
- else
- return &pSynth->pEAS->pWTRegions[regionIndex].region;
-#elif defined(_WT_SYNTH)
- return &pSynth->pEAS->pWTRegions[regionIndex].region;
-#elif defined(_FM_SYNTH)
- return &pSynth->pEAS->pFMRegions[regionIndex].region;
-#endif
-}
-
-/*lint -esym(715, voiceNum) used in some implementation */
-EAS_INLINE const S_SYNTH_INTERFACE* GetSynthPtr (EAS_INT voiceNum)
-{
-#if defined(_HYBRID_SYNTH)
- if (voiceNum < NUM_PRIMARY_VOICES)
- return pPrimarySynth;
- else
- return pSecondarySynth;
-#else
- return pPrimarySynth;
-#endif
-}
-
-EAS_INLINE EAS_INT GetAdjustedVoiceNum (EAS_INT voiceNum)
-{
-#if defined(_HYBRID_SYNTH)
- if (voiceNum >= NUM_PRIMARY_VOICES)
- return voiceNum - NUM_PRIMARY_VOICES;
-#endif
- return voiceNum;
-}
-
-EAS_INLINE EAS_U8 VSynthToChannel (S_SYNTH *pSynth, EAS_U8 channel)
-{
- /*lint -e{734} synthNum is always 0-15 */
- return channel | (pSynth->vSynthNum << 4);
-}
-
-/*----------------------------------------------------------------------------
- * InitVoice()
- *----------------------------------------------------------------------------
- * Initialize a synthesizer voice
- *----------------------------------------------------------------------------
-*/
-void InitVoice (S_SYNTH_VOICE *pVoice)
-{
- pVoice->channel = UNASSIGNED_SYNTH_CHANNEL;
- pVoice->nextChannel = UNASSIGNED_SYNTH_CHANNEL;
- pVoice->note = pVoice->nextNote = DEFAULT_KEY_NUMBER;
- pVoice->velocity = pVoice->nextVelocity = DEFAULT_VELOCITY;
- pVoice->regionIndex = DEFAULT_REGION_INDEX;
- pVoice->age = DEFAULT_AGE;
- pVoice->voiceFlags = DEFAULT_VOICE_FLAGS;
- pVoice->voiceState = DEFAULT_VOICE_STATE;
-}
-
-/*----------------------------------------------------------------------------
- * IncVoicePoolCount()
- *----------------------------------------------------------------------------
- * Updates the voice pool count when a voice changes state
- *----------------------------------------------------------------------------
-*/
-static void IncVoicePoolCount (S_VOICE_MGR *pVoiceMgr, S_SYNTH_VOICE *pVoice)
-{
- S_SYNTH *pSynth;
- EAS_INT pool;
-
- /* ignore muting voices */
- if (pVoice->voiceState == eVoiceStateMuting)
- return;
-
- if (pVoice->voiceState == eVoiceStateStolen)
- {
- pSynth = pVoiceMgr->pSynth[GET_VSYNTH(pVoice->nextChannel)];
- pool = pSynth->channels[GET_CHANNEL(pVoice->nextChannel)].pool;
- }
- else
- {
- pSynth = pVoiceMgr->pSynth[GET_VSYNTH(pVoice->channel)];
- pool = pSynth->channels[GET_CHANNEL(pVoice->channel)].pool;
- }
-
- pSynth->poolCount[pool]++;
-
-#ifdef _DEBUG_VM
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IncVoicePoolCount: Synth=%d pool=%d\n", pSynth->vSynthNum, pool); */ }
-#endif
-}
-
-/*----------------------------------------------------------------------------
- * DecVoicePoolCount()
- *----------------------------------------------------------------------------
- * Updates the voice pool count when a voice changes state
- *----------------------------------------------------------------------------
-*/
-static void DecVoicePoolCount (S_VOICE_MGR *pVoiceMgr, S_SYNTH_VOICE *pVoice)
-{
- S_SYNTH *pSynth;
- EAS_INT pool;
-
- /* ignore muting voices */
- if (pVoice->voiceState == eVoiceStateMuting)
- return;
-
- if (pVoice->voiceState == eVoiceStateStolen)
- {
- pSynth = pVoiceMgr->pSynth[GET_VSYNTH(pVoice->nextChannel)];
- pool = pSynth->channels[GET_CHANNEL(pVoice->nextChannel)].pool;
- }
- else
- {
- pSynth = pVoiceMgr->pSynth[GET_VSYNTH(pVoice->channel)];
- pool = pSynth->channels[GET_CHANNEL(pVoice->channel)].pool;
- }
-
- pSynth->poolCount[pool]--;
-
-#ifdef _DEBUG_VM
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "DecVoicePoolCount: Synth=%d pool=%d\n", pSynth->vSynthNum, pool); */ }
-#endif
-}
-
-/*----------------------------------------------------------------------------
- * VMInitialize()
- *----------------------------------------------------------------------------
- * Purpose:
- *
- * Inputs:
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT VMInitialize (S_EAS_DATA *pEASData)
-{
- S_VOICE_MGR *pVoiceMgr;
- EAS_INT i;
-
- /* check Configuration Module for data allocation */
- if (pEASData->staticMemoryModel)
- pVoiceMgr = EAS_CMEnumData(EAS_CM_SYNTH_DATA);
- else
- pVoiceMgr = EAS_HWMalloc(pEASData->hwInstData, sizeof(S_VOICE_MGR));
- if (!pVoiceMgr)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "VMInitialize: Failed to allocate synthesizer memory\n"); */ }
- return EAS_ERROR_MALLOC_FAILED;
- }
- EAS_HWMemSet(pVoiceMgr, 0, sizeof(S_VOICE_MGR));
-
- /* initialize non-zero variables */
- pVoiceMgr->pGlobalEAS = (S_EAS*) &easSoundLib;
- pVoiceMgr->maxPolyphony = (EAS_U16) MAX_SYNTH_VOICES;
-
-#if defined(_SECONDARY_SYNTH) || defined(EAS_SPLIT_WT_SYNTH)
- pVoiceMgr->maxPolyphonyPrimary = NUM_PRIMARY_VOICES;
- pVoiceMgr->maxPolyphonySecondary = NUM_SECONDARY_VOICES;
-#endif
-
- /* set max workload to zero */
- pVoiceMgr->maxWorkLoad = 0;
-
- /* initialize the voice manager parameters */
- for (i = 0; i < MAX_SYNTH_VOICES; i++)
- InitVoice(&pVoiceMgr->voices[i]);
-
- /* initialize the synth */
- /*lint -e{522} return unused at this time */
- pPrimarySynth->pfInitialize(pVoiceMgr);
-
- /* initialize the off-chip synth */
-#ifdef _HYBRID_SYNTH
- /*lint -e{522} return unused at this time */
- pSecondarySynth->pfInitialize(pVoiceMgr);
-#endif
-
- pEASData->pVoiceMgr = pVoiceMgr;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * VMInitMIDI()
- *----------------------------------------------------------------------------
- * Purpose:
- *
- * Inputs:
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT VMInitMIDI (S_EAS_DATA *pEASData, S_SYNTH **ppSynth)
-{
- EAS_RESULT result;
- S_SYNTH *pSynth;
- EAS_INT virtualSynthNum;
-
- *ppSynth = NULL;
-
- /* static memory model only allows one synth */
- if (pEASData->staticMemoryModel)
- {
- if (pEASData->pVoiceMgr->pSynth[0] != NULL)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "VMInitMIDI: No virtual synthesizer support for static memory model\n"); */ }
- return EAS_ERROR_NO_VIRTUAL_SYNTHESIZER;
- }
-
- /* check Configuration Module for data allocation */
- pSynth = EAS_CMEnumData(EAS_CM_MIDI_DATA);
- virtualSynthNum = 0;
- }
-
- /* dynamic memory model */
- else
- {
- for (virtualSynthNum = 0; virtualSynthNum < MAX_VIRTUAL_SYNTHESIZERS; virtualSynthNum++)
- if (pEASData->pVoiceMgr->pSynth[virtualSynthNum] == NULL)
- break;
- if (virtualSynthNum == MAX_VIRTUAL_SYNTHESIZERS)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "VMInitMIDI: Exceeded number of active virtual synthesizers"); */ }
- return EAS_ERROR_NO_VIRTUAL_SYNTHESIZER;
- }
- pSynth = EAS_HWMalloc(pEASData->hwInstData, sizeof(S_SYNTH));
- }
-
- /* make sure we have a valid memory pointer */
- if (pSynth == NULL)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "VMInitMIDI: Failed to allocate synthesizer memory\n"); */ }
- return EAS_ERROR_MALLOC_FAILED;
- }
- EAS_HWMemSet(pSynth, 0, sizeof(S_SYNTH));
-
- /* set the sound library pointer */
- if ((result = VMSetEASLib(pSynth, pEASData->pVoiceMgr->pGlobalEAS)) != EAS_SUCCESS)
- {
- VMMIDIShutdown(pEASData, pSynth);
- return result;
- }
-
- /* link in DLS bank if downloaded */
-#ifdef DLS_SYNTHESIZER
- if (pEASData->pVoiceMgr->pGlobalDLS)
- {
- pSynth->pDLS = pEASData->pVoiceMgr->pGlobalDLS;
- DLSAddRef(pSynth->pDLS);
- }
-#endif
-
- /* initialize MIDI state variables */
- pSynth->synthFlags = DEFAULT_SYNTH_FLAGS;
- pSynth->masterVolume = DEFAULT_SYNTH_MASTER_VOLUME;
- pSynth->refCount = 1;
- pSynth->priority = DEFAULT_SYNTH_PRIORITY;
- pSynth->poolAlloc[0] = (EAS_U8) pEASData->pVoiceMgr->maxPolyphony;
-
- VMInitializeAllChannels(pEASData->pVoiceMgr, pSynth);
-
- pSynth->vSynthNum = (EAS_U8) virtualSynthNum;
- pEASData->pVoiceMgr->pSynth[virtualSynthNum] = pSynth;
-
- *ppSynth = pSynth;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * VMIncRefCount()
- *----------------------------------------------------------------------------
- * Increment reference count for virtual synth
- *----------------------------------------------------------------------------
-*/
-void VMIncRefCount (S_SYNTH *pSynth)
-{
- pSynth->refCount++;
-}
-
-/*----------------------------------------------------------------------------
- * VMReset()
- *----------------------------------------------------------------------------
- * Purpose:
- * We call this routine to start the process of reseting the synth.
- * This routine sets a flag for the entire synth indicating that we want
- * to reset.
- * We also force all voices to mute quickly.
- * However, we do not actually perform any synthesis in this routine. That
- * is, we do not ramp the voices down from this routine, but instead, we
- * let the "regular" synth processing steps take care of adding the ramp
- * down samples to the output buffer. After we are sure that all voices
- * have completed ramping down, we continue the process of resetting the
- * synth (from another routine).
- *
- * Inputs:
- * psEASData - pointer to overall EAS data structure
- * force - force reset even if voices are active
- *
- * Outputs:
- *
- * Side Effects:
- * - set a flag (in psSynthObject->m_nFlags) indicating synth reset requested.
- * - force all voices to update their envelope states to mute
- *
- *----------------------------------------------------------------------------
-*/
-void VMReset (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_BOOL force)
-{
-
-#ifdef _DEBUG_VM
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMReset: request to reset synth. Force = %d\n", force); */ }
-#endif
-
- /* force voices to off state - may cause audio artifacts */
- if (force)
- {
- pVoiceMgr->activeVoices -= pSynth->numActiveVoices;
- pSynth->numActiveVoices = 0;
- VMInitializeAllVoices(pVoiceMgr, pSynth->vSynthNum);
- }
- else
- VMMuteAllVoices(pVoiceMgr, pSynth);
-
- /* don't reset if voices are still playing */
- if (pSynth->numActiveVoices == 0)
- {
- EAS_INT i;
-
-#ifdef _DEBUG_VM
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMReset: complete the reset process\n"); */ }
-#endif
-
- VMInitializeAllChannels(pVoiceMgr, pSynth);
- for (i = 0; i < NUM_SYNTH_CHANNELS; i++)
- pSynth->poolCount[i] = 0;
-
- /* set polyphony */
- if (pSynth->maxPolyphony < pVoiceMgr->maxPolyphony)
- pSynth->poolAlloc[0] = (EAS_U8) pVoiceMgr->maxPolyphony;
- else
- pSynth->poolAlloc[0] = (EAS_U8) pSynth->maxPolyphony;
-
- /* clear reset flag */
- pSynth->synthFlags &= ~SYNTH_FLAG_RESET_IS_REQUESTED;
- }
-
- /* handle reset after voices are muted */
- else
- pSynth->synthFlags |= SYNTH_FLAG_RESET_IS_REQUESTED;
-}
-
-/*----------------------------------------------------------------------------
- * VMInitializeAllChannels()
- *----------------------------------------------------------------------------
- * Purpose:
- *
- * Inputs:
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- *
- *----------------------------------------------------------------------------
-*/
-void VMInitializeAllChannels (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth)
-{
- S_SYNTH_CHANNEL *pChannel;
- EAS_INT i;
-
- VMResetControllers(pSynth);
-
- /* init each channel */
- pChannel = pSynth->channels;
-
- for (i = 0; i < NUM_SYNTH_CHANNELS; i++, pChannel++)
- {
- pChannel->channelFlags = DEFAULT_CHANNEL_FLAGS;
- pChannel->staticGain = DEFAULT_CHANNEL_STATIC_GAIN;
- pChannel->staticPitch = DEFAULT_CHANNEL_STATIC_PITCH;
- pChannel->pool = 0;
-
- /* the drum channel needs a different init */
- if (i == DEFAULT_DRUM_CHANNEL)
- {
- pChannel->bankNum = DEFAULT_RHYTHM_BANK_NUMBER;
- pChannel->channelFlags |= CHANNEL_FLAG_RHYTHM_CHANNEL;
- }
- else
- pChannel->bankNum = DEFAULT_MELODY_BANK_NUMBER;
-
- VMProgramChange(pVoiceMgr, pSynth, (EAS_U8) i, DEFAULT_SYNTH_PROGRAM_NUMBER);
- }
-
-}
-
-/*----------------------------------------------------------------------------
- * VMResetControllers()
- *----------------------------------------------------------------------------
- * Purpose:
- *
- * Inputs:
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- *
- *----------------------------------------------------------------------------
-*/
-void VMResetControllers (S_SYNTH *pSynth)
-{
- S_SYNTH_CHANNEL *pChannel;
- EAS_INT i;
-
- pChannel = pSynth->channels;
-
- for (i = 0; i < NUM_SYNTH_CHANNELS; i++, pChannel++)
- {
- pChannel->pitchBend = DEFAULT_PITCH_BEND;
- pChannel->modWheel = DEFAULT_MOD_WHEEL;
- pChannel->volume = DEFAULT_CHANNEL_VOLUME;
- pChannel->pan = DEFAULT_PAN;
- pChannel->expression = DEFAULT_EXPRESSION;
-
-#ifdef _REVERB
- pSynth->channels[i].reverbSend = DEFAULT_REVERB_SEND;
-#endif
-
-#ifdef _CHORUS
- pSynth->channels[i].chorusSend = DEFAULT_CHORUS_SEND;
-#endif
-
- pChannel->channelPressure = DEFAULT_CHANNEL_PRESSURE;
- pChannel->registeredParam = DEFAULT_REGISTERED_PARAM;
- pChannel->pitchBendSensitivity = DEFAULT_PITCH_BEND_SENSITIVITY;
- pChannel->finePitch = DEFAULT_FINE_PITCH;
- pChannel->coarsePitch = DEFAULT_COARSE_PITCH;
-
- /* update all voices on this channel */
- pChannel->channelFlags |= CHANNEL_FLAG_UPDATE_CHANNEL_PARAMETERS;
- }
-}
-
-/*----------------------------------------------------------------------------
- * VMInitializeAllVoices()
- *----------------------------------------------------------------------------
- * Purpose:
- *
- * Inputs:
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- *
- *----------------------------------------------------------------------------
-*/
-void VMInitializeAllVoices (S_VOICE_MGR *pVoiceMgr, EAS_INT vSynthNum)
-{
- EAS_INT i;
-
- /* initialize the voice manager parameters */
- for (i = 0; i < MAX_SYNTH_VOICES; i++)
- {
- if (pVoiceMgr->voices[i].voiceState != eVoiceStateStolen)
- {
- if (GET_VSYNTH(pVoiceMgr->voices[i].channel) == vSynthNum)
- InitVoice(&pVoiceMgr->voices[i]);
- }
- else
- {
- if (GET_VSYNTH(pVoiceMgr->voices[i].nextChannel) == vSynthNum)
- InitVoice(&pVoiceMgr->voices[i]);
- }
- }
-}
-
-/*----------------------------------------------------------------------------
- * VMMuteVoice()
- *----------------------------------------------------------------------------
- * Mute the selected voice
- *----------------------------------------------------------------------------
-*/
-void VMMuteVoice (S_VOICE_MGR *pVoiceMgr, EAS_I32 voiceNum)
-{
- S_SYNTH *pSynth;
- S_SYNTH_VOICE *pVoice;
-
- /* take no action if voice is already muted */
- pVoice = &pVoiceMgr->voices[voiceNum];
- if ((pVoice->voiceState == eVoiceStateMuting) || (pVoice->voiceState == eVoiceStateFree))
- return;
-
- /* one less voice in pool */
- DecVoicePoolCount(pVoiceMgr, pVoice);
-
- pSynth = pVoiceMgr->pSynth[GET_VSYNTH(pVoice->channel)];
- GetSynthPtr(voiceNum)->pfMuteVoice(pVoiceMgr, pSynth, pVoice, GetAdjustedVoiceNum(voiceNum));
- pVoice->voiceState = eVoiceStateMuting;
-
-}
-
-/*----------------------------------------------------------------------------
- * VMReleaseVoice()
- *----------------------------------------------------------------------------
- * Release the selected voice
- *----------------------------------------------------------------------------
-*/
-void VMReleaseVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_I32 voiceNum)
-{
- S_SYNTH_VOICE *pVoice = &pVoiceMgr->voices[voiceNum];
-
- /* take no action if voice is already free, muting, or releasing */
- if (( pVoice->voiceState == eVoiceStateMuting) ||
- (pVoice->voiceState == eVoiceStateFree) ||
- (pVoice->voiceState == eVoiceStateRelease))
- return;
-
- /* stolen voices should just be muted */
- if (pVoice->voiceState == eVoiceStateStolen)
- VMMuteVoice(pVoiceMgr, voiceNum);
-
- /* release this voice */
- GetSynthPtr(voiceNum)->pfReleaseVoice(pVoiceMgr, pSynth, &pVoiceMgr->voices[voiceNum], GetAdjustedVoiceNum(voiceNum));
- pVoice->voiceState = eVoiceStateRelease;
-}
-
-/*----------------------------------------------------------------------------
- * VMInitMIPTable()
- *----------------------------------------------------------------------------
- * Initialize the SP-MIDI MIP table in preparation for receiving MIP message
- *----------------------------------------------------------------------------
-*/
-void VMInitMIPTable (S_SYNTH *pSynth)
-{
- EAS_INT i;
-
-#ifdef _DEBUG_VM
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMInitMIPTable\n"); */ }
-#endif
-
- /* clear SP-MIDI flag */
- pSynth->synthFlags &= ~SYNTH_FLAG_SP_MIDI_ON;
- for (i = 0; i < NUM_SYNTH_CHANNELS; i++)
- {
- pSynth->channels[i].pool = 0;
- pSynth->channels[i].mip = 0;
- }
-}
-
-/*----------------------------------------------------------------------------
- * VMSetMIPEntry()
- *----------------------------------------------------------------------------
- * Sets the priority and MIP level for a MIDI channel
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, pVoiceMgr) reserved for future use */
-void VMSetMIPEntry (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel, EAS_U8 priority, EAS_U8 mip)
-{
-
-#ifdef _DEBUG_VM
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMSetMIPEntry: channel=%d, priority=%d, MIP=%d\n", channel, priority, mip); */ }
-#endif
-
- /* save data for use by MIP message processing */
- if (priority < NUM_SYNTH_CHANNELS)
- {
- pSynth->channels[channel].pool = priority;
- pSynth->channels[channel].mip = mip;
- }
-}
-
-/*----------------------------------------------------------------------------
- * VMMIPUpdateChannelMuting()
- *----------------------------------------------------------------------------
- * This routine is called after an SP-MIDI message is received and
- * any time the allocated polyphony changes. It mutes or unmutes
- * channels based on polyphony.
- *----------------------------------------------------------------------------
-*/
-void VMMIPUpdateChannelMuting (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth)
-{
- EAS_INT i;
- EAS_INT maxPolyphony;
- EAS_INT channel;
- EAS_INT vSynthNum;
- EAS_INT pool;
-
-#ifdef _DEBUG_VM
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMUpdateMIPTable\n"); */ }
-#endif
-
- /* determine max polyphony */
- if (pSynth->maxPolyphony)
- maxPolyphony = pSynth->maxPolyphony;
- else
- maxPolyphony = pVoiceMgr->maxPolyphony;
-
- /* process channels */
- for (i = 0; i < NUM_SYNTH_CHANNELS; i++)
- {
-
- /* channel must be in MIP message and must meet allocation target */
- if ((pSynth->channels[i].mip != 0) && (pSynth->channels[i].mip <= maxPolyphony))
- pSynth->channels[i].channelFlags &= ~CHANNEL_FLAG_MUTE;
- else
- pSynth->channels[i].channelFlags |= CHANNEL_FLAG_MUTE;
-
- /* reset voice pool count */
- pSynth->poolCount[i] = 0;
- }
-
- /* mute any voices on muted channels, and count unmuted voices */
- for (i = 0; i < MAX_SYNTH_VOICES; i++)
- {
-
- /* ignore free voices */
- if (pVoiceMgr->voices[i].voiceState == eVoiceStateFree)
- continue;
-
- /* get channel and virtual synth */
- if (pVoiceMgr->voices[i].voiceState != eVoiceStateStolen)
- {
- vSynthNum = GET_VSYNTH(pVoiceMgr->voices[i].channel);
- channel = GET_CHANNEL(pVoiceMgr->voices[i].channel);
- }
- else
- {
- vSynthNum = GET_VSYNTH(pVoiceMgr->voices[i].nextChannel);
- channel = GET_CHANNEL(pVoiceMgr->voices[i].nextChannel);
- }
-
- /* ignore voices on other synths */
- if (vSynthNum != pSynth->vSynthNum)
- continue;
-
- /* count voices */
- pool = pSynth->channels[channel].pool;
-
- /* deal with muted channels */
- if (pSynth->channels[channel].channelFlags & CHANNEL_FLAG_MUTE)
- {
- /* mute stolen voices scheduled to play on this channel */
- if (pVoiceMgr->voices[i].voiceState == eVoiceStateStolen)
- pVoiceMgr->voices[i].voiceState = eVoiceStateMuting;
-
- /* release voices that aren't already muting */
- else if (pVoiceMgr->voices[i].voiceState != eVoiceStateMuting)
- {
- VMReleaseVoice(pVoiceMgr, pSynth, i);
- pSynth->poolCount[pool]++;
- }
- }
-
- /* not muted, count this voice */
- else
- pSynth->poolCount[pool]++;
- }
-}
-
-/*----------------------------------------------------------------------------
- * VMUpdateMIPTable()
- *----------------------------------------------------------------------------
- * This routine is called at the end of the SysEx message to allow
- * the Voice Manager to complete the initialization of the MIP
- * table. It assigns channels to the appropriate voice pool based
- * on the MIP setting and calculates the voices allocated for each
- * pool.
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, pVoiceMgr) reserved for future use */
-void VMUpdateMIPTable (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth)
-{
- S_SYNTH_CHANNEL *pChannel;
- EAS_INT i;
- EAS_INT currentMIP;
- EAS_INT currentPool;
- EAS_INT priority[NUM_SYNTH_CHANNELS];
-
-#ifdef _DEBUG_VM
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMUpdateMIPTable\n"); */ }
-#endif
-
- /* set SP-MIDI flag */
- pSynth->synthFlags |= SYNTH_FLAG_SP_MIDI_ON;
-
- /* sort channels into priority order */
- for (i = 0; i < NUM_SYNTH_CHANNELS; i++)
- priority[i] = -1;
- for (i = 0; i < NUM_SYNTH_CHANNELS; i++)
- {
- if (pSynth->channels[i].pool != DEFAULT_SP_MIDI_PRIORITY)
- priority[pSynth->channels[i].pool] = i;
- }
-
- /* process channels in priority order */
- currentMIP = 0;
- currentPool = -1;
- for (i = 0; i < NUM_SYNTH_CHANNELS; i++)
- {
- /* stop when we run out of channels */
- if (priority[i] == -1)
- break;
-
- pChannel = &pSynth->channels[priority[i]];
-
- /* when 2 or more channels have the same MIP setting, they
- * share a common voice pool
- */
- if (pChannel->mip == currentMIP)
- pChannel->pool = (EAS_U8) currentPool;
-
- /* new voice pool */
- else
- {
- currentPool++;
- pSynth->poolAlloc[currentPool] = (EAS_U8) (pChannel->mip - currentMIP);
- currentMIP = pChannel->mip;
- }
- }
-
- /* set SP-MIDI flag */
- pSynth->synthFlags |= SYNTH_FLAG_SP_MIDI_ON;
-
- /* update channel muting */
- VMMIPUpdateChannelMuting (pVoiceMgr, pSynth);
-}
-
-/*----------------------------------------------------------------------------
- * VMMuteAllVoices()
- *----------------------------------------------------------------------------
- * Purpose:
- * We call this in an emergency reset situation.
- * This forces all voices to mute quickly.
- *
- * Inputs:
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- *
- * Side Effects:
- * - forces all voices to update their envelope states to mute
- *
- *----------------------------------------------------------------------------
-*/
-void VMMuteAllVoices (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth)
-{
- EAS_INT i;
-
-#ifdef _DEBUG_VM
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMMuteAllVoices: about to mute all voices!!\n"); */ }
-#endif
-
- for (i = 0; i < MAX_SYNTH_VOICES; i++)
- {
- /* for stolen voices, check new channel */
- if (pVoiceMgr->voices[i].voiceState == eVoiceStateStolen)
- {
- if (GET_VSYNTH(pVoiceMgr->voices[i].nextChannel) == pSynth->vSynthNum)
- VMMuteVoice(pVoiceMgr, i);
- }
-
- else if (pSynth->vSynthNum == GET_VSYNTH(pVoiceMgr->voices[i].channel))
- VMMuteVoice(pVoiceMgr, i);
- }
-}
-
-/*----------------------------------------------------------------------------
- * VMReleaseAllVoices()
- *----------------------------------------------------------------------------
- * Purpose:
- * We call this after we've encountered the end of the Midi file.
- * This ensures all voices are either in release (because we received their
- * note off already) or forces them to mute quickly.
- * We use this as a safety to prevent bad midi files from playing forever.
- *
- * Inputs:
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- *
- * Side Effects:
- * - forces all voices to update their envelope states to release or mute
- *
- *----------------------------------------------------------------------------
-*/
-void VMReleaseAllVoices (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth)
-{
- EAS_INT i;
-
- /* release sustain pedal on all channels */
- for (i = 0; i < NUM_SYNTH_CHANNELS; i++)
- {
- if (pSynth->channels[ i ].channelFlags & CHANNEL_FLAG_SUSTAIN_PEDAL)
- {
- VMReleaseAllDeferredNoteOffs(pVoiceMgr, pSynth, (EAS_U8) i);
- pSynth->channels[i].channelFlags &= ~CHANNEL_FLAG_SUSTAIN_PEDAL;
- }
- }
-
- /* release all voices */
- for (i = 0; i < MAX_SYNTH_VOICES; i++)
- {
-
- switch (pVoiceMgr->voices[i].voiceState)
- {
- case eVoiceStateStart:
- case eVoiceStatePlay:
- /* only release voices on this synth */
- if (GET_VSYNTH(pVoiceMgr->voices[i].channel) == pSynth->vSynthNum)
- VMReleaseVoice(pVoiceMgr, pSynth, i);
- break;
-
- case eVoiceStateStolen:
- if (GET_VSYNTH(pVoiceMgr->voices[i].nextChannel) == pSynth->vSynthNum)
- VMMuteVoice(pVoiceMgr, i);
- break;
-
- case eVoiceStateFree:
- case eVoiceStateRelease:
- case eVoiceStateMuting:
- break;
-
- case eVoiceStateInvalid:
- default:
-#ifdef _DEBUG_VM
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMReleaseAllVoices: error, %d is an unrecognized state\n",
- pVoiceMgr->voices[i].voiceState); */ }
-#endif
- break;
- }
- }
-}
-
-/*----------------------------------------------------------------------------
- * VMAllNotesOff()
- *----------------------------------------------------------------------------
- * Purpose:
- * Quickly mute all notes on the given channel.
- *
- * Inputs:
- * nChannel - quickly turn off all notes on this channel
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- *
- * Side Effects:
- * - forces all voices on this channel to update their envelope states to mute
- *
- *----------------------------------------------------------------------------
-*/
-void VMAllNotesOff (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel)
-{
- EAS_INT voiceNum;
- S_SYNTH_VOICE *pVoice;
-
-#ifdef _DEBUG_VM
- if (channel >= NUM_SYNTH_CHANNELS)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMAllNotesOff: error, %d invalid channel number\n",
- channel); */ }
- return;
- }
-#endif
-
- /* increment workload */
- pVoiceMgr->workload += WORKLOAD_AMOUNT_SMALL_INCREMENT;
-
- /* check each voice */
- channel = VSynthToChannel(pSynth, channel);
- for (voiceNum = 0; voiceNum < MAX_SYNTH_VOICES; voiceNum++)
- {
- pVoice = &pVoiceMgr->voices[voiceNum];
- if (pVoice->voiceState != eVoiceStateFree)
- {
- if (((pVoice->voiceState != eVoiceStateStolen) && (channel == pVoice->channel)) ||
- ((pVoice->voiceState == eVoiceStateStolen) && (channel == pVoice->nextChannel)))
- {
- /* this voice is assigned to the requested channel */
- GetSynthPtr(voiceNum)->pfMuteVoice(pVoiceMgr, pSynth, pVoice, GetAdjustedVoiceNum(voiceNum));
- pVoice->voiceState = eVoiceStateMuting;
- }
- }
- }
-}
-
-/*----------------------------------------------------------------------------
- * VMDeferredStopNote()
- *----------------------------------------------------------------------------
- * Purpose:
- * Stop the notes that had deferred note-off requests.
- *
- * Inputs:
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- * None.
- *
- * Side Effects:
- * voices that have had deferred note-off requests are now put into release
- * psSynthObject->m_sVoice[i].m_nFlags has the VOICE_FLAG_DEFER_MIDI_NOTE_OFF
- * cleared
- *----------------------------------------------------------------------------
-*/
-void VMDeferredStopNote (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth)
-{
- EAS_INT voiceNum;
- EAS_INT channel;
- EAS_BOOL deferredNoteOff;
-
- deferredNoteOff = EAS_FALSE;
-
- /* check each voice to see if it requires a deferred note off */
- for (voiceNum=0; voiceNum < MAX_SYNTH_VOICES; voiceNum++)
- {
- if (pVoiceMgr->voices[voiceNum].voiceFlags & VOICE_FLAG_DEFER_MIDI_NOTE_OFF)
- {
- /* check if this voice was stolen */
- if (pVoiceMgr->voices[voiceNum].voiceState == eVoiceStateStolen)
- {
- /*
- This voice was stolen, AND it also has a deferred note-off.
- The stolen note must be completely ramped down at this point.
- The note that caused the stealing to occur, however, must
- have received a note-off request before the note that caused
- stealing ever had a chance to even start. We want to give
- the note that caused the stealing a chance to play, so we
- start it on the next update interval, and we defer sending
- the note-off request until the subsequent update interval.
- So do not send the note-off request for this voice because
- this voice was stolen and should have completed ramping down,
- Also, do not clear the global flag nor this voice's flag
- because we must indicate that the subsequent update interval,
- after the note that caused stealing has started, should
- then send the deferred note-off request.
- */
- deferredNoteOff = EAS_TRUE;
-
-#ifdef _DEBUG_VM
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMDeferredStopNote: defer request to stop voice %d (channel=%d note=%d) - voice not started\n",
- voiceNum,
- pVoiceMgr->voices[voiceNum].nextChannel,
- pVoiceMgr->voices[voiceNum].note); */ }
-
- /* sanity check: this stolen voice better be ramped to zero */
- if (0 != pVoiceMgr->voices[voiceNum].gain)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMDeferredStopNote: warning, this voice did not complete its ramp to zero\n"); */ }
- }
-#endif // #ifdef _DEBUG_VM
-
- }
- else
- {
- /* clear the flag using exor */
- pVoiceMgr->voices[voiceNum].voiceFlags ^=
- VOICE_FLAG_DEFER_MIDI_NOTE_OFF;
-
-#ifdef _DEBUG_VM
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMDeferredStopNote: Stop voice %d (channel=%d note=%d)\n",
- voiceNum,
- pVoiceMgr->voices[voiceNum].nextChannel,
- pVoiceMgr->voices[voiceNum].note); */ }
-#endif
-
- channel = pVoiceMgr->voices[voiceNum].channel & 15;
-
- /* check if sustain pedal is on */
- if (pSynth->channels[channel].channelFlags & CHANNEL_FLAG_SUSTAIN_PEDAL)
- {
- GetSynthPtr(voiceNum)->pfSustainPedal(pVoiceMgr, pSynth, &pVoiceMgr->voices[voiceNum], &pSynth->channels[channel], GetAdjustedVoiceNum(voiceNum));
- }
-
- /* release this voice */
- else
- VMReleaseVoice(pVoiceMgr, pSynth, voiceNum);
-
- }
-
- }
-
- }
-
- /* clear the deferred note-off flag, unless there's another one pending */
- if (deferredNoteOff == EAS_FALSE)
- pSynth->synthFlags ^= SYNTH_FLAG_DEFERRED_MIDI_NOTE_OFF_PENDING;
-}
-
-/*----------------------------------------------------------------------------
- * VMReleaseAllDeferredNoteOffs()
- *----------------------------------------------------------------------------
- * Purpose:
- * Call this functin when the sustain flag is presently set but
- * we are now transitioning from damper pedal on to
- * damper pedal off. This means all notes in this channel
- * that received a note off while the damper pedal was on, and
- * had their note-off requests deferred, should now proceed to
- * the release state.
- *
- * Inputs:
- * nChannel - this channel has its sustain pedal transitioning from on to off
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- * Side Effects:
- * any voice with deferred note offs on this channel are updated such that
- * pVoice->m_sEG1.m_eState = eEnvelopeStateRelease
- * pVoice->m_sEG1.m_nIncrement = release increment
- * pVoice->m_nFlags = clear the deferred note off flag
- *----------------------------------------------------------------------------
-*/
-void VMReleaseAllDeferredNoteOffs (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel)
-{
- S_SYNTH_VOICE *pVoice;
- EAS_INT voiceNum;
-
-#ifdef _DEBUG_VM
- if (channel >= NUM_SYNTH_CHANNELS)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMReleaseAllDeferredNoteOffs: error, %d invalid channel number\n",
- channel); */ }
- return;
- }
-#endif /* #ifdef _DEBUG_VM */
-
- /* increment workload */
- pVoiceMgr->workload += WORKLOAD_AMOUNT_SMALL_INCREMENT;
-
- /* find all the voices assigned to this channel */
- channel = VSynthToChannel(pSynth, channel);
- for (voiceNum = 0; voiceNum < MAX_SYNTH_VOICES; voiceNum++)
- {
-
- pVoice = &pVoiceMgr->voices[voiceNum];
- if (channel == pVoice->channel)
- {
-
- /* does this voice have a deferred note off? */
- if (pVoice->voiceFlags & VOICE_FLAG_SUSTAIN_PEDAL_DEFER_NOTE_OFF)
- {
- /* release voice */
- VMReleaseVoice(pVoiceMgr, pSynth, voiceNum);
-
- /* use exor to flip bit, clear the flag */
- pVoice->voiceFlags &= ~VOICE_FLAG_SUSTAIN_PEDAL_DEFER_NOTE_OFF;
-
- }
-
- }
- }
-
- return;
-}
-
-/*----------------------------------------------------------------------------
- * VMCatchNotesForSustainPedal()
- *----------------------------------------------------------------------------
- * Purpose:
- * Call this function when the sustain flag is presently clear and
- * the damper pedal is off and we are transitioning from damper pedal OFF to
- * damper pedal ON. Currently sounding notes should be left
- * unchanged. However, we should try to "catch" notes if possible.
- * If any notes are in release and have levels >= sustain level, catch them,
- * otherwise, let them continue to release.
- *
- * Inputs:
- * nChannel - this channel has its sustain pedal transitioning from on to off
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- *----------------------------------------------------------------------------
-*/
-void VMCatchNotesForSustainPedal (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel)
-{
- EAS_INT voiceNum;
-
-#ifdef _DEBUG_VM
- if (channel >= NUM_SYNTH_CHANNELS)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMCatchNotesForSustainPedal: error, %d invalid channel number\n",
- channel); */ }
- return;
- }
-#endif
-
- pVoiceMgr->workload += WORKLOAD_AMOUNT_SMALL_INCREMENT;
- channel = VSynthToChannel(pSynth, channel);
-
- /* find all the voices assigned to this channel */
- for (voiceNum = 0; voiceNum < MAX_SYNTH_VOICES; voiceNum++)
- {
- if (channel == pVoiceMgr->voices[voiceNum].channel)
- {
- if (eVoiceStateRelease == pVoiceMgr->voices[voiceNum].voiceState)
- GetSynthPtr(voiceNum)->pfSustainPedal(pVoiceMgr, pSynth, &pVoiceMgr->voices[voiceNum], &pSynth->channels[channel], GetAdjustedVoiceNum(voiceNum));
- }
- }
-}
-
-/*----------------------------------------------------------------------------
- * VMUpdateAllNotesAge()
- *----------------------------------------------------------------------------
- * Purpose:
- * Increment the note age for all of the active voices.
- *
- * Inputs:
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- *
- * Side Effects:
- * m_nAge for all voices is incremented
- *----------------------------------------------------------------------------
-*/
-void VMUpdateAllNotesAge (S_VOICE_MGR *pVoiceMgr, EAS_U16 age)
-{
- EAS_INT i;
-
- for (i = 0; i < MAX_SYNTH_VOICES; i++)
- {
- if (age - pVoiceMgr->voices[i].age > 0)
- pVoiceMgr->voices[i].age++;
- }
-}
-
-/*----------------------------------------------------------------------------
- * VMStolenVoice()
- *----------------------------------------------------------------------------
- * Purpose:
- * The selected voice is being stolen. Sets the parameters so that the
- * voice will begin playing the new sound on the next buffer.
- *
- * Inputs:
- * pVoice - pointer to voice to steal
- * nChannel - the channel to start a note on
- * nKeyNumber - the key number to start a note for
- * nNoteVelocity - the key velocity from this note
- *
- * Outputs:
- * None
- *----------------------------------------------------------------------------
-*/
-static void VMStolenVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_I32 voiceNum, EAS_U8 channel, EAS_U8 note, EAS_U8 velocity, EAS_U16 regionIndex)
-{
- S_SYNTH_VOICE *pVoice = &pVoiceMgr->voices[voiceNum];
-
- /* one less voice in old pool */
- DecVoicePoolCount(pVoiceMgr, pVoice);
-
- /* mute the sound that is currently playing */
- GetSynthPtr(voiceNum)->pfMuteVoice(pVoiceMgr, pVoiceMgr->pSynth[GET_VSYNTH(pVoice->channel)], &pVoiceMgr->voices[voiceNum], GetAdjustedVoiceNum(voiceNum));
- pVoice->voiceState = eVoiceStateStolen;
-
- /* set new note data */
- pVoice->nextChannel = VSynthToChannel(pSynth, channel);
- pVoice->nextNote = note;
- pVoice->nextVelocity = velocity;
- pVoice->nextRegionIndex = regionIndex;
-
- /* one more voice in new pool */
- IncVoicePoolCount(pVoiceMgr, pVoice);
-
- /* clear the deferred flags */
- pVoice->voiceFlags &=
- ~(VOICE_FLAG_DEFER_MIDI_NOTE_OFF |
- VOICE_FLAG_DEFER_MUTE |
- VOICE_FLAG_SUSTAIN_PEDAL_DEFER_NOTE_OFF);
-
- /* all notes older than this one get "younger" */
- VMUpdateAllNotesAge(pVoiceMgr, pVoice->age);
-
- /* assign current age to this note and increment for the next note */
- pVoice->age = pVoiceMgr->age++;
-}
-
-/*----------------------------------------------------------------------------
- * VMFreeVoice()
- *----------------------------------------------------------------------------
- * Purpose:
- * The selected voice is done playing and being returned to the
- * pool of free voices
- *
- * Inputs:
- * pVoice - pointer to voice to free
- *
- * Outputs:
- * None
- *----------------------------------------------------------------------------
-*/
-static void VMFreeVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice)
-{
-
- /* do nothing if voice is already free */
- if (pVoice->voiceState == eVoiceStateFree)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "VMFreeVoice: Attempt to free voice that is already free\n"); */ }
- return;
- }
-
- /* if we jump directly to free without passing muting stage,
- * we need to adjust the voice count */
- DecVoicePoolCount(pVoiceMgr, pVoice);
-
-
-#ifdef _DEBUG_VM
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "VMFreeVoice: Synth=%d\n", pSynth->vSynthNum); */ }
-#endif
-
- /* return to free voice pool */
- pVoiceMgr->activeVoices--;
- pSynth->numActiveVoices--;
- InitVoice(pVoice);
-
-#ifdef _DEBUG_VM
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMFreeVoice: free voice %d\n", pVoice - pVoiceMgr->voices); */ }
-#endif
-
- /* all notes older than this one get "younger" */
- VMUpdateAllNotesAge(pVoiceMgr, pVoice->age);
- }
-
-/*----------------------------------------------------------------------------
- * VMRetargetStolenVoice()
- *----------------------------------------------------------------------------
- * Purpose:
- * The selected voice has been stolen and needs to be initalized with
- * the paramters of its new note.
- *
- * Inputs:
- * pVoice - pointer to voice to retarget
- *
- * Outputs:
- * None
- *----------------------------------------------------------------------------
-*/
-static EAS_BOOL VMRetargetStolenVoice (S_VOICE_MGR *pVoiceMgr, EAS_I32 voiceNum)
-{
- EAS_U8 flags;
- S_SYNTH_CHANNEL *pMIDIChannel;
- S_SYNTH_VOICE *pVoice;
- S_SYNTH *pSynth;
- S_SYNTH *pNextSynth;
-
- /* establish some pointers */
- pVoice = &pVoiceMgr->voices[voiceNum];
- pSynth = pVoiceMgr->pSynth[GET_VSYNTH(pVoice->channel)];
- pMIDIChannel = &pSynth->channels[pVoice->channel & 15];
- pNextSynth = pVoiceMgr->pSynth[GET_VSYNTH(pVoice->nextChannel)];
-
-#ifdef _DEBUG_VM
-{ /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMRetargetStolenVoice: retargeting stolen voice %d on channel %d\n",
- voiceNum, pVoice->channel); */ }
-
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "\to channel %d note: %d velocity: %d\n",
- pVoice->nextChannel, pVoice->nextNote, pVoice->nextVelocity); */ }
-#endif
-
- /* make sure new channel hasn't been muted by SP-MIDI since the voice was stolen */
- if ((pSynth->synthFlags & SYNTH_FLAG_SP_MIDI_ON) &&
- (pMIDIChannel->channelFlags & CHANNEL_FLAG_MUTE))
- {
- VMFreeVoice(pVoiceMgr, pSynth, &pVoiceMgr->voices[voiceNum]);
- return EAS_FALSE;
- }
-
- /* if assigned to a new synth, correct the active voice count */
- if (pVoice->channel != pVoice->nextChannel)
- {
-#ifdef _DEBUG_VM
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMRetargetStolenVoice: Note assigned to different virtual synth, adjusting numActiveVoices\n"); */ }
-#endif
- pSynth->numActiveVoices--;
- pNextSynth->numActiveVoices++;
- }
-
- /* assign new channel number, and increase channel voice count */
- pVoice->channel = pVoice->nextChannel;
- pMIDIChannel = &pNextSynth->channels[pVoice->channel & 15];
-
- /* assign other data */
- pVoice->note = pVoice->nextNote;
- pVoice->velocity = pVoice->nextVelocity;
- pVoice->nextChannel = UNASSIGNED_SYNTH_CHANNEL;
- pVoice->regionIndex = pVoice->nextRegionIndex;
-
- /* save the flags, pfStartVoice() will clear them */
- flags = pVoice->voiceFlags;
-
- /* keep track of the note-start related workload */
- pVoiceMgr->workload += WORKLOAD_AMOUNT_START_NOTE;
-
- /* setup the voice parameters */
- pVoice->voiceState = eVoiceStateStart;
-
- /*lint -e{522} return not used at this time */
- GetSynthPtr(voiceNum)->pfStartVoice(pVoiceMgr, pNextSynth, &pVoiceMgr->voices[voiceNum], GetAdjustedVoiceNum(voiceNum), pVoice->regionIndex);
-
- /* did the new note already receive a MIDI note-off request? */
- if (flags & VOICE_FLAG_DEFER_MIDI_NOTE_OFF)
- {
-#ifdef _DEBUG_VM
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMRetargetVoice: stolen note note-off request deferred\n"); */ }
-#endif
- pVoice->voiceFlags |= VOICE_FLAG_DEFER_MIDI_NOTE_OFF;
- pNextSynth->synthFlags |= SYNTH_FLAG_DEFERRED_MIDI_NOTE_OFF_PENDING;
- }
-
- return EAS_TRUE;
-}
-
-/*----------------------------------------------------------------------------
- * VMCheckKeyGroup()
- *----------------------------------------------------------------------------
- * If the note that we've been asked to start is in the same key group as
- * any currently playing notes, then we must shut down the currently playing
- * note in the same key group
- *----------------------------------------------------------------------------
-*/
-void VMCheckKeyGroup (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U16 keyGroup, EAS_U8 channel)
-{
- const S_REGION *pRegion;
- EAS_INT voiceNum;
-
- /* increment frame workload */
- pVoiceMgr->workload += WORKLOAD_AMOUNT_KEY_GROUP;
-
- /* need to check all voices in case this is a layered sound */
- channel = VSynthToChannel(pSynth, channel);
- for (voiceNum = 0; voiceNum < MAX_SYNTH_VOICES; voiceNum++)
- {
- if (pVoiceMgr->voices[voiceNum].voiceState != eVoiceStateStolen)
- {
- /* voice must be on the same channel */
- if (channel == pVoiceMgr->voices[voiceNum].channel)
- {
- /* check key group */
- pRegion = GetRegionPtr(pSynth, pVoiceMgr->voices[voiceNum].regionIndex);
- if (keyGroup == (pRegion->keyGroupAndFlags & 0x0f00))
- {
-#ifdef _DEBUG_VM
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMCheckKeyGroup: voice %d matches key group %d\n", voiceNum, keyGroup >> 8); */ }
-#endif
-
- /* if this voice was just started, set it to mute on the next buffer */
- if (pVoiceMgr->voices[voiceNum].voiceFlags & VOICE_FLAG_NO_SAMPLES_SYNTHESIZED_YET)
- pVoiceMgr->voices[voiceNum].voiceFlags |= VOICE_FLAG_DEFER_MUTE;
-
- /* mute immediately */
- else
- VMMuteVoice(pVoiceMgr, voiceNum);
- }
- }
- }
-
- /* for stolen voice, check new values */
- else
- {
- /* voice must be on the same channel */
- if (channel == pVoiceMgr->voices[voiceNum].nextChannel)
- {
- /* check key group */
- pRegion = GetRegionPtr(pSynth, pVoiceMgr->voices[voiceNum].nextRegionIndex);
- if (keyGroup == (pRegion->keyGroupAndFlags & 0x0f00))
- {
-#ifdef _DEBUG_VM
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMCheckKeyGroup: voice %d matches key group %d\n", voiceNum, keyGroup >> 8); */ }
-#endif
-
- /* if this voice was just started, set it to mute on the next buffer */
- if (pVoiceMgr->voices[voiceNum].voiceFlags & VOICE_FLAG_NO_SAMPLES_SYNTHESIZED_YET)
- pVoiceMgr->voices[voiceNum].voiceFlags |= VOICE_FLAG_DEFER_MUTE;
-
- /* mute immediately */
- else
- VMMuteVoice(pVoiceMgr, voiceNum);
- }
- }
-
- }
- }
-}
-
-/*----------------------------------------------------------------------------
- * VMCheckPolyphonyLimiting()
- *----------------------------------------------------------------------------
- * Purpose:
- * We only play at most 2 of the same note on a MIDI channel.
- * E.g., if we are asked to start note 36, and there are already two voices
- * that are playing note 36, then we must steal the voice playing
- * the oldest note 36 and use that stolen voice to play the new note 36.
- *
- * Inputs:
- * nChannel - synth channel that wants to start a new note
- * nKeyNumber - new note's midi note number
- * nNoteVelocity - new note's velocity
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- * pbVoiceStealingRequired - flag: this routine sets true if we needed to
- * steal a voice
- * *
- * Side Effects:
- * psSynthObject->m_sVoice[free voice num].m_nKeyNumber may be assigned
- * psSynthObject->m_sVoice[free voice num].m_nVelocity may be assigned
- *----------------------------------------------------------------------------
-*/
-EAS_BOOL VMCheckPolyphonyLimiting (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel, EAS_U8 note, EAS_U8 velocity, EAS_U16 regionIndex, EAS_I32 lowVoice, EAS_I32 highVoice)
-{
- EAS_INT voiceNum;
- EAS_INT oldestVoiceNum;
- EAS_INT numVoicesPlayingNote;
- EAS_U16 age;
- EAS_U16 oldestNoteAge;
-
- pVoiceMgr->workload += WORKLOAD_AMOUNT_POLY_LIMIT;
-
- numVoicesPlayingNote = 0;
- oldestVoiceNum = MAX_SYNTH_VOICES;
- oldestNoteAge = 0;
- channel = VSynthToChannel(pSynth, channel);
-
- /* examine each voice on this channel playing this note */
- for (voiceNum = lowVoice; voiceNum <= highVoice; voiceNum++)
- {
- /* check stolen notes separately */
- if (pVoiceMgr->voices[voiceNum].voiceState != eVoiceStateStolen)
- {
-
- /* same channel and note ? */
- if ((channel == pVoiceMgr->voices[voiceNum].channel) && (note == pVoiceMgr->voices[voiceNum].note))
- {
- numVoicesPlayingNote++;
- age = pVoiceMgr->age - pVoiceMgr->voices[voiceNum].age;
-
- /* is this the oldest voice for this note? */
- if (age >= oldestNoteAge)
- {
- oldestNoteAge = age;
- oldestVoiceNum = voiceNum;
- }
- }
- }
-
- /* handle stolen voices */
- else
- {
- /* same channel and note ? */
- if ((channel == pVoiceMgr->voices[voiceNum].nextChannel) && (note == pVoiceMgr->voices[voiceNum].nextNote))
- {
- numVoicesPlayingNote++;
- }
- }
- }
-
- /* check to see if we exceeded poly limit */
- if (numVoicesPlayingNote < DEFAULT_CHANNEL_POLYPHONY_LIMIT)
- return EAS_FALSE;
-
- /* make sure we have a voice to steal */
- if (oldestVoiceNum != MAX_SYNTH_VOICES)
- {
-#ifdef _DEBUG_VM
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMCheckPolyphonyLimiting: voice %d has the oldest note\n", oldestVoiceNum); */ }
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "VMCheckPolyphonyLimiting: polyphony limiting requires shutting down note %d \n", pVoiceMgr->voices[oldestVoiceNum].note); */ }
-#endif
- VMStolenVoice(pVoiceMgr, pSynth, oldestVoiceNum, channel, note, velocity, regionIndex);
- return EAS_TRUE;
- }
-
-#ifdef _DEBUG_VM
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "VMCheckPolyphonyLimiting: No oldest voice to steal\n"); */ }
-#endif
- return EAS_FALSE;
-}
-
-/*----------------------------------------------------------------------------
- * VMStartVoice()
- *----------------------------------------------------------------------------
- * Starts a voice given a region index
- *----------------------------------------------------------------------------
-*/
-void VMStartVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel, EAS_U8 note, EAS_U8 velocity, EAS_U16 regionIndex)
-{
- const S_REGION *pRegion;
- S_SYNTH_CHANNEL *pChannel;
- EAS_INT voiceNum;
- EAS_INT maxSynthPoly;
- EAS_I32 lowVoice, highVoice;
- EAS_U16 keyGroup;
-
- pChannel = &pSynth->channels[channel];
- pRegion = GetRegionPtr(pSynth, regionIndex);
-
- /* select correct synth */
-#if defined(_SECONDARY_SYNTH) || defined(EAS_SPLIT_WT_SYNTH)
- {
-#ifdef EAS_SPLIT_WT_SYNTH
- if ((pRegion->keyGroupAndFlags & REGION_FLAG_OFF_CHIP) == 0)
-#else
- if ((regionIndex & FLAG_RGN_IDX_FM_SYNTH) == 0)
-#endif
- {
- lowVoice = 0;
- highVoice = NUM_PRIMARY_VOICES - 1;
- }
- else
- {
- lowVoice = NUM_PRIMARY_VOICES;
- highVoice = MAX_SYNTH_VOICES - 1;
- }
- }
-#else
- lowVoice = 0;
- highVoice = MAX_SYNTH_VOICES - 1;
-#endif
-
- /* keep track of the note-start related workload */
- pVoiceMgr->workload+= WORKLOAD_AMOUNT_START_NOTE;
-
- /* other voices in pool, check for key group and poly limiting */
- if (pSynth->poolCount[pChannel->pool] != 0)
- {
-
- /* check for key group exclusivity */
- keyGroup = pRegion->keyGroupAndFlags & 0x0f00;
- if (keyGroup!= 0)
- VMCheckKeyGroup(pVoiceMgr, pSynth, keyGroup, channel);
-
- /* check polyphony limit and steal a voice if necessary */
- if ((pRegion->keyGroupAndFlags & REGION_FLAG_NON_SELF_EXCLUSIVE) == 0)
- {
- if (VMCheckPolyphonyLimiting(pVoiceMgr, pSynth, channel, note, velocity, regionIndex, lowVoice, highVoice) == EAS_TRUE)
- return;
- }
- }
-
- /* check max poly allocation */
- if ((pSynth->maxPolyphony == 0) || (pVoiceMgr->maxPolyphony < pSynth->maxPolyphony))
- maxSynthPoly = pVoiceMgr->maxPolyphony;
- else
- maxSynthPoly = pSynth->maxPolyphony;
-
- /* any free voices? */
- if ((pVoiceMgr->activeVoices < pVoiceMgr->maxPolyphony) &&
- (pSynth->numActiveVoices < maxSynthPoly) &&
- (EAS_SUCCESS == VMFindAvailableVoice(pVoiceMgr, &voiceNum, lowVoice, highVoice)))
- {
- S_SYNTH_VOICE *pVoice = &pVoiceMgr->voices[voiceNum];
-
-#ifdef _DEBUG_VM
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "VMStartVoice: Synth=%d\n", pSynth->vSynthNum); */ }
-#endif
-
- /* bump voice counts */
- pVoiceMgr->activeVoices++;
- pSynth->numActiveVoices++;
-
-#ifdef _DEBUG_VM
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMStartVoice: voice %d assigned to channel %d note %d velocity %d\n",
- voiceNum, channel, note, velocity); */ }
-#endif
-
- /* save parameters */
- pVoiceMgr->voices[voiceNum].channel = VSynthToChannel(pSynth, channel);
- pVoiceMgr->voices[voiceNum].note = note;
- pVoiceMgr->voices[voiceNum].velocity = velocity;
-
- /* establish note age for voice stealing */
- pVoiceMgr->voices[voiceNum].age = pVoiceMgr->age++;
-
- /* setup the synthesis parameters */
- pVoiceMgr->voices[voiceNum].voiceState = eVoiceStateStart;
-
- /* increment voice pool count */
- IncVoicePoolCount(pVoiceMgr, pVoice);
-
- /* start voice on correct synth */
- /*lint -e{522} return not used at this time */
- GetSynthPtr(voiceNum)->pfStartVoice(pVoiceMgr, pSynth, &pVoiceMgr->voices[voiceNum], GetAdjustedVoiceNum(voiceNum), regionIndex);
- return;
- }
-
- /* no free voices, we have to steal one using appropriate algorithm */
- if (VMStealVoice(pVoiceMgr, pSynth, &voiceNum, channel, note, lowVoice, highVoice) == EAS_SUCCESS)
- VMStolenVoice(pVoiceMgr, pSynth, voiceNum, channel, note, velocity, regionIndex);
-
-#ifdef _DEBUG_VM
- else
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMStartVoice: Could not steal a voice for channel %d note %d velocity %d\n",
- channel, note, velocity); */ }
- }
-#endif
-
- return;
-}
-
-/*----------------------------------------------------------------------------
- * VMStartNote()
- *----------------------------------------------------------------------------
- * Purpose:
- * Update the synth's state to play the requested note on the requested
- * channel if possible.
- *
- * Inputs:
- * nChannel - the channel to start a note on
- * nKeyNumber - the key number to start a note for
- * nNoteVelocity - the key velocity from this note
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- * Side Effects:
- * psSynthObject->m_nNumActiveVoices may be incremented
- * psSynthObject->m_sVoice[free voice num].m_nSynthChannel may be assigned
- * psSynthObject->m_sVoice[free voice num].m_nKeyNumber is assigned
- * psSynthObject->m_sVoice[free voice num].m_nVelocity is assigned
- *----------------------------------------------------------------------------
-*/
-void VMStartNote (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel, EAS_U8 note, EAS_U8 velocity)
-{
- S_SYNTH_CHANNEL *pChannel;
- EAS_U16 regionIndex;
- EAS_I16 adjustedNote;
-
- /* bump note count */
- pSynth->totalNoteCount++;
-
- pChannel = &pSynth->channels[channel];
-
- /* check channel mute */
- if (pChannel->channelFlags & CHANNEL_FLAG_MUTE)
- return;
-
-#ifdef EXTERNAL_AUDIO
- /* pass event to external audio when requested */
- if ((pChannel->channelFlags & CHANNEL_FLAG_EXTERNAL_AUDIO) && (pSynth->cbEventFunc != NULL))
- {
- S_EXT_AUDIO_EVENT event;
- event.channel = channel;
- event.note = note;
- event.velocity = velocity;
- event.noteOn = EAS_TRUE;
- if (pSynth->cbEventFunc(pSynth->pExtAudioInstData, &event))
- return;
- }
-#endif
-
- /* start search at first region */
- regionIndex = pChannel->regionIndex;
-
- /* handle transposition */
- adjustedNote = note;
- if (pChannel->channelFlags & CHANNEL_FLAG_RHYTHM_CHANNEL)
- adjustedNote += pChannel->coarsePitch;
- else
- adjustedNote += pChannel->coarsePitch + pSynth->globalTranspose;
-
- /* limit adjusted key number so it does not wraparound, over/underflow */
- if (adjustedNote < 0)
- {
- adjustedNote = 0;
- }
- else if (adjustedNote > 127)
- {
- adjustedNote = 127;
- }
-
-#if defined(DLS_SYNTHESIZER)
- if (regionIndex & FLAG_RGN_IDX_DLS_SYNTH)
- {
- /* DLS voice */
- for (;;)
- {
- /*lint -e{740,826} cast OK, we know this is actually a DLS region */
- const S_DLS_REGION *pDLSRegion = (S_DLS_REGION*) GetRegionPtr(pSynth, regionIndex);
-
- /* check key against this region's key and velocity range */
- if (((adjustedNote >= pDLSRegion->wtRegion.region.rangeLow) && (adjustedNote <= pDLSRegion->wtRegion.region.rangeHigh)) &&
- ((velocity >= pDLSRegion->velLow) && (velocity <= pDLSRegion->velHigh)))
- {
- VMStartVoice(pVoiceMgr, pSynth, channel, note, velocity, regionIndex);
- }
-
- /* last region in program? */
- if (pDLSRegion->wtRegion.region.keyGroupAndFlags & REGION_FLAG_LAST_REGION)
- break;
-
- /* advance to next region */
- regionIndex++;
- }
- }
- else
-#endif
-
- /* braces here for #if clause */
- {
- /* EAS voice */
- for (;;)
- {
- const S_REGION *pRegion = GetRegionPtr(pSynth, regionIndex);
-
- /* check key against this region's keyrange */
- if ((adjustedNote >= pRegion->rangeLow) && (adjustedNote <= pRegion->rangeHigh))
- {
- VMStartVoice(pVoiceMgr, pSynth, channel, note, velocity, regionIndex);
- break;
- }
-
- /* last region in program? */
- if (pRegion->keyGroupAndFlags & REGION_FLAG_LAST_REGION)
- break;
-
- /* advance to next region */
- regionIndex++;
- }
- }
-}
-
-/*----------------------------------------------------------------------------
- * VMStopNote()
- *----------------------------------------------------------------------------
- * Purpose:
- * Update the synth's state to end the requested note on the requested
- * channel.
- *
- * Inputs:
- * nChannel - the channel to stop a note on
- * nKeyNumber - the key number for this note off
- * nNoteVelocity - the note-off velocity
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- * Side Effects:
- * psSynthObject->m_sVoice[free voice num].m_nSynthChannel may be assigned
- * psSynthObject->m_sVoice[free voice num].m_nKeyNumber is assigned
- * psSynthObject->m_sVoice[free voice num].m_nVelocity is assigned
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, velocity) reserved for future use */
-void VMStopNote (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel, EAS_U8 note, EAS_U8 velocity)
-{
- S_SYNTH_CHANNEL *pChannel;
- EAS_INT voiceNum;
-
- pChannel = &(pSynth->channels[channel]);
-
-#ifdef EXTERNAL_AUDIO
- if ((pChannel->channelFlags & CHANNEL_FLAG_EXTERNAL_AUDIO) && (pSynth->cbEventFunc != NULL))
- {
- S_EXT_AUDIO_EVENT event;
- event.channel = channel;
- event.note = note;
- event.velocity = velocity;
- event.noteOn = EAS_FALSE;
- if (pSynth->cbEventFunc(pSynth->pExtAudioInstData, &event))
- return;
- }
-#endif
-
- /* keep track of the note-start workload */
- pVoiceMgr->workload += WORKLOAD_AMOUNT_STOP_NOTE;
-
- channel = VSynthToChannel(pSynth, channel);
-
- for (voiceNum=0; voiceNum < MAX_SYNTH_VOICES; voiceNum++)
- {
-
- /* stolen notes are handled separately */
- if (eVoiceStateStolen != pVoiceMgr->voices[voiceNum].voiceState)
- {
-
- /* channel and key number must match */
- if ((channel == pVoiceMgr->voices[voiceNum].channel) && (note == pVoiceMgr->voices[voiceNum].note))
- {
-#ifdef _DEBUG_VM
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMStopNote: voice %d channel %d note %d\n",
- voiceNum, channel, note); */ }
-#endif
-
- /* if sustain pedal is down, set deferred note-off flag */
- if (pChannel->channelFlags & CHANNEL_FLAG_SUSTAIN_PEDAL)
- {
- pVoiceMgr->voices[voiceNum].voiceFlags |= VOICE_FLAG_SUSTAIN_PEDAL_DEFER_NOTE_OFF;
- continue;
- }
-
- /* if this note just started, wait before we stop it */
- if (pVoiceMgr->voices[voiceNum].voiceFlags & VOICE_FLAG_NO_SAMPLES_SYNTHESIZED_YET)
- {
-#ifdef _DEBUG_VM
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "\tDeferred: Not started yet\n"); */ }
-#endif
- pVoiceMgr->voices[voiceNum].voiceFlags |= VOICE_FLAG_DEFER_MIDI_NOTE_OFF;
- pSynth->synthFlags |= SYNTH_FLAG_DEFERRED_MIDI_NOTE_OFF_PENDING;
- }
-
- /* release voice */
- else
- VMReleaseVoice(pVoiceMgr, pSynth, voiceNum);
-
- }
- }
-
- /* process stolen notes, new channel and key number must match */
- else if ((channel == pVoiceMgr->voices[voiceNum].nextChannel) && (note == pVoiceMgr->voices[voiceNum].nextNote))
- {
-
-#ifdef _DEBUG_VM
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMStopNote: voice %d channel %d note %d\n\tDeferred: Stolen voice\n",
- voiceNum, channel, note); */ }
-#endif
- pVoiceMgr->voices[voiceNum].voiceFlags |= VOICE_FLAG_DEFER_MIDI_NOTE_OFF;
- }
- }
-}
-
-/*----------------------------------------------------------------------------
- * VMFindAvailableVoice()
- *----------------------------------------------------------------------------
- * Purpose:
- * Find an available voice and return the voice number if available.
- *
- * Inputs:
- * pnVoiceNumber - really an output, returns the voice number found
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- * success - if there is an available voice
- * failure - otherwise
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT VMFindAvailableVoice (S_VOICE_MGR *pVoiceMgr, EAS_INT *pVoiceNumber, EAS_I32 lowVoice, EAS_I32 highVoice)
-{
- EAS_INT voiceNum;
-
- /* Check each voice to see if it has been assigned to a synth channel */
- for (voiceNum = lowVoice; voiceNum <= highVoice; voiceNum++)
- {
- /* check if this voice has been assigned to a synth channel */
- if ( pVoiceMgr->voices[voiceNum].voiceState == eVoiceStateFree)
- {
- *pVoiceNumber = voiceNum; /* this voice is available */
- return EAS_SUCCESS;
- }
- }
-
- /* if we reach here, we have not found a free voice */
- *pVoiceNumber = UNASSIGNED_SYNTH_VOICE;
-
-#ifdef _DEBUG_VM
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMFindAvailableVoice: error, could not find an available voice\n"); */ }
-#endif
- return EAS_FAILURE;
-}
-
-/*----------------------------------------------------------------------------
- * VMStealVoice()
- *----------------------------------------------------------------------------
- * Purpose:
- * Steal a voice and return the voice number
- *
- * Stealing algorithm: steal the best choice with minimal work, taking into
- * account SP-Midi channel priorities and polyphony allocation.
- *
- * In one pass through all the voices, figure out which voice to steal
- * taking into account a number of different factors:
- * Priority of the voice's MIDI channel
- * Number of voices over the polyphony allocation for voice's MIDI channel
- * Amplitude of the voice
- * Note age
- * Key velocity (for voices that haven't been started yet)
- * If any matching notes are found
- *
- * Inputs:
- * pnVoiceNumber - really an output, see below
- * nChannel - the channel that this voice wants to be started on
- * nKeyNumber - the key number for this new voice
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- * pnVoiceNumber - voice number of the voice that was stolen
- * EAS_RESULT EAS_SUCCESS - always successful
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT VMStealVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_INT *pVoiceNumber, EAS_U8 channel, EAS_U8 note, EAS_I32 lowVoice, EAS_I32 highVoice)
-{
- S_SYNTH_VOICE *pCurrVoice;
- S_SYNTH *pCurrSynth;
- EAS_INT voiceNum;
- EAS_INT bestCandidate;
- EAS_U8 currChannel;
- EAS_U8 currNote;
- EAS_I32 bestPriority;
- EAS_I32 currentPriority;
-
- /* determine which voice to steal */
- bestPriority = 0;
- bestCandidate = MAX_SYNTH_VOICES;
-
- for (voiceNum = lowVoice; voiceNum <= highVoice; voiceNum++)
- {
- pCurrVoice = &pVoiceMgr->voices[voiceNum];
-
- /* ignore free voices */
- if (pCurrVoice->voiceState == eVoiceStateFree)
- continue;
-
- /* for stolen voices, use the new parameters, not the old */
- if (pCurrVoice->voiceState == eVoiceStateStolen)
- {
- pCurrSynth = pVoiceMgr->pSynth[GET_VSYNTH(pCurrVoice->nextChannel)];
- currChannel = pCurrVoice->nextChannel;
- currNote = pCurrVoice->nextNote;
- }
- else
- {
- pCurrSynth = pVoiceMgr->pSynth[GET_VSYNTH(pCurrVoice->channel)];
- currChannel = pCurrVoice->channel;
- currNote = pCurrVoice->note;
- }
-
- /* ignore voices that are higher priority */
- if (pSynth->priority > pCurrSynth->priority)
- continue;
-#ifdef _DEBUG_VM
-// { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMStealVoice: New priority = %d exceeds old priority = %d\n", pSynth->priority, pCurrSynth->priority); */ }
-#endif
-
- /* if voice is stolen or just started, reduce the likelihood it will be stolen */
- if (( pCurrVoice->voiceState == eVoiceStateStolen) || (pCurrVoice->voiceFlags & VOICE_FLAG_NO_SAMPLES_SYNTHESIZED_YET))
- {
- currentPriority = 128 - pCurrVoice->nextVelocity;
- }
- else
- {
- /* compute the priority of this voice, higher means better for stealing */
- /* use not age */
- currentPriority = (EAS_I32) pCurrVoice->age << NOTE_AGE_STEAL_WEIGHT;
-
- /* include note gain -higher gain is lower steal value */
- /*lint -e{704} use shift for performance */
- currentPriority += ((32768 >> (12 - NOTE_GAIN_STEAL_WEIGHT)) + 256) -
- ((EAS_I32) pCurrVoice->gain >> (12 - NOTE_GAIN_STEAL_WEIGHT));
- }
-
- /* in SP-MIDI mode, include over poly allocation and channel priority */
- if (pSynth->synthFlags & SYNTH_FLAG_SP_MIDI_ON)
- {
- S_SYNTH_CHANNEL *pChannel = &pCurrSynth->channels[GET_CHANNEL(currChannel)];
- /*lint -e{701} use shift for performance */
- if (pSynth->poolCount[pChannel->pool] >= pSynth->poolAlloc[pChannel->pool])
- currentPriority += (pSynth->poolCount[pChannel->pool] -pSynth->poolAlloc[pChannel->pool] + 1) << CHANNEL_POLY_STEAL_WEIGHT;
-
- /* include channel priority */
- currentPriority += (EAS_I32)(pChannel->pool << CHANNEL_PRIORITY_STEAL_WEIGHT);
- }
-
- /* if a note is already playing that matches this note, consider stealing it more readily */
- if ((note == currNote) && (channel == currChannel))
- currentPriority += NOTE_MATCH_PENALTY;
-
- /* is this the best choice so far? */
- if (currentPriority >= bestPriority)
- {
- bestPriority = currentPriority;
- bestCandidate = voiceNum;
- }
- }
-
- /* may happen if all voices are allocated to a higher priority virtual synth */
- if (bestCandidate == MAX_SYNTH_VOICES)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMStealVoice: Unable to allocate a voice\n"); */ }
- return EAS_ERROR_NO_VOICE_ALLOCATED;
- }
-
-#ifdef _DEBUG_VM
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMStealVoice: Voice %d stolen\n", bestCandidate); */ }
-
- /* are we stealing a stolen voice? */
- if (pVoiceMgr->voices[bestCandidate].voiceState == eVoiceStateStolen)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "VMStealVoice: Voice %d is already marked as stolen and was scheduled to play ch: %d note: %d vel: %d\n",
- bestCandidate,
- pVoiceMgr->voices[bestCandidate].nextChannel,
- pVoiceMgr->voices[bestCandidate].nextNote,
- pVoiceMgr->voices[bestCandidate].nextVelocity); */ }
- }
-#endif
-
- *pVoiceNumber = (EAS_U16) bestCandidate;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * VMChannelPressure()
- *----------------------------------------------------------------------------
- * Purpose:
- * Change the channel pressure for the given channel
- *
- * Inputs:
- * nChannel - the MIDI channel
- * nVelocity - the channel pressure value
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- * Side Effects:
- * psSynthObject->m_sChannel[nChannel].m_nChannelPressure is updated
- *----------------------------------------------------------------------------
-*/
-void VMChannelPressure (S_SYNTH *pSynth, EAS_U8 channel, EAS_U8 value)
-{
- S_SYNTH_CHANNEL *pChannel;
-
- pChannel = &(pSynth->channels[channel]);
- pChannel->channelPressure = value;
-
- /*
- set a channel flag to request parameter updates
- for all the voices associated with this channel
- */
- pChannel->channelFlags |= CHANNEL_FLAG_UPDATE_CHANNEL_PARAMETERS;
-}
-
-/*----------------------------------------------------------------------------
- * VMPitchBend()
- *----------------------------------------------------------------------------
- * Purpose:
- * Change the pitch wheel value for the given channel.
- * This routine constructs the proper 14-bit argument when the calling routine
- * passes the pitch LSB and MSB.
- *
- * Note: some midi disassemblers display a bipolar pitch bend value.
- * We can display the bipolar value using
- * if m_nPitchBend >= 0x2000
- * bipolar pitch bend = postive (m_nPitchBend - 0x2000)
- * else
- * bipolar pitch bend = negative (0x2000 - m_nPitchBend)
- *
- * Inputs:
- * nChannel - the MIDI channel
- * nPitchLSB - the LSB byte of the pitch bend message
- * nPitchMSB - the MSB byte of the pitch bend message
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- *
- * Side Effects:
- * psSynthObject->m_sChannel[nChannel].m_nPitchBend is changed
- *
- *----------------------------------------------------------------------------
-*/
-void VMPitchBend (S_SYNTH *pSynth, EAS_U8 channel, EAS_U8 nPitchLSB, EAS_U8 nPitchMSB)
-{
- S_SYNTH_CHANNEL *pChannel;
-
- pChannel = &(pSynth->channels[channel]);
- pChannel->pitchBend = (EAS_I16) ((nPitchMSB << 7) | nPitchLSB);
-
- /*
- set a channel flag to request parameter updates
- for all the voices associated with this channel
- */
- pChannel->channelFlags |= CHANNEL_FLAG_UPDATE_CHANNEL_PARAMETERS;
-}
-
-/*----------------------------------------------------------------------------
- * VMControlChange()
- *----------------------------------------------------------------------------
- * Purpose:
- * Change the controller (or mode) for the given channel.
- *
- * Inputs:
- * nChannel - the MIDI channel
- * nControllerNumber - the MIDI controller number
- * nControlValue - the value for this controller message
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- * Side Effects:
- * psSynthObject->m_sChannel[nChannel] controller is changed
- *
- *----------------------------------------------------------------------------
-*/
-void VMControlChange (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel, EAS_U8 controller, EAS_U8 value)
-{
- S_SYNTH_CHANNEL *pChannel;
-
- pChannel = &(pSynth->channels[channel]);
-
- /*
- set a channel flag to request parameter updates
- for all the voices associated with this channel
- */
- pChannel->channelFlags |= CHANNEL_FLAG_UPDATE_CHANNEL_PARAMETERS;
-
- switch ( controller )
- {
- case MIDI_CONTROLLER_BANK_SELECT_MSB:
-#ifdef _DEBUG_VM
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMControlChange: Bank Select MSB: msb 0x%X\n", value); */ }
-#endif
- /* use this MSB with a zero LSB, until we get an LSB message */
- pChannel->bankNum = value << 8;
- break;
-
- case MIDI_CONTROLLER_MOD_WHEEL:
- /* we treat mod wheel as a 7-bit controller and only use the MSB */
- pChannel->modWheel = value;
- break;
-
- case MIDI_CONTROLLER_VOLUME:
- /* we treat volume as a 7-bit controller and only use the MSB */
- pChannel->volume = value;
- break;
-
- case MIDI_CONTROLLER_PAN:
- /* we treat pan as a 7-bit controller and only use the MSB */
- pChannel->pan = value;
- break;
-
- case MIDI_CONTROLLER_EXPRESSION:
- /* we treat expression as a 7-bit controller and only use the MSB */
- pChannel->expression = value;
- break;
-
- case MIDI_CONTROLLER_BANK_SELECT_LSB:
-#ifdef _DEBUG_VM
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMControlChange: Bank Select LSB: lsb 0x%X\n", value); */ }
-#endif
- /*
- construct bank number as 7-bits (stored as 8) of existing MSB
- and 7-bits of new LSB (also stored as 8(
- */
- pChannel->bankNum =
- (pChannel->bankNum & 0xFF00) | value;
-
- break;
-
- case MIDI_CONTROLLER_SUSTAIN_PEDAL:
- /* we treat sustain pedal as a boolean on/off bit flag */
- if (value < 64)
- {
- /*
- we are requested to turn the pedal off, but first check
- if the pedal is already on
- */
- if (0 !=
- (pChannel->channelFlags & CHANNEL_FLAG_SUSTAIN_PEDAL)
- )
- {
- /*
- The sustain flag is presently set and the damper pedal is on.
- We are therefore transitioning from damper pedal ON to
- damper pedal OFF. This means all notes in this channel
- that received a note off while the damper pedal was on, and
- had their note-off requests deferred, should now proceed to
- the release state.
- */
- VMReleaseAllDeferredNoteOffs(pVoiceMgr, pSynth, channel);
- } /* end if sustain pedal is already on */
-
- /* turn the sustain pedal off */
- pChannel->channelFlags &= ~CHANNEL_FLAG_SUSTAIN_PEDAL;
- }
- else
- {
- /*
- we are requested to turn the pedal on, but first check
- if the pedal is already off
- */
- if (0 ==
- (pChannel->channelFlags & CHANNEL_FLAG_SUSTAIN_PEDAL)
- )
- {
- /*
- The sustain flag is presently clear and the damper pedal is off.
- We are therefore transitioning from damper pedal OFF to
- damper pedal ON. Currently sounding notes should be left
- unchanged. However, we should try to "catch" notes if possible.
- If any notes have levels >= sustain level, catch them,
- otherwise, let them continue to release.
- */
- VMCatchNotesForSustainPedal(pVoiceMgr, pSynth, channel);
- }
-
- /* turn the sustain pedal on */
- pChannel->channelFlags |= CHANNEL_FLAG_SUSTAIN_PEDAL;
- }
-
- break;
-#ifdef _REVERB
- case MIDI_CONTROLLER_REVERB_SEND:
- /* we treat send as a 7-bit controller and only use the MSB */
- pSynth->channels[channel].reverbSend = value;
- break;
-#endif
-#ifdef _CHORUS
- case MIDI_CONTROLLER_CHORUS_SEND:
- /* we treat send as a 7-bit controller and only use the MSB */
- pSynth->channels[channel].chorusSend = value;
- break;
-#endif
- case MIDI_CONTROLLER_RESET_CONTROLLERS:
- /* despite the Midi message name, not ALL controllers are reset */
- pChannel->modWheel = DEFAULT_MOD_WHEEL;
- pChannel->expression = DEFAULT_EXPRESSION;
-
- /* turn the sustain pedal off as default/reset */
- pChannel->channelFlags &= ~CHANNEL_FLAG_SUSTAIN_PEDAL;
- pChannel->pitchBend = DEFAULT_PITCH_BEND;
-
- /* reset channel pressure */
- pChannel->channelPressure = DEFAULT_CHANNEL_PRESSURE;
-
- /* reset RPN values */
- pChannel->registeredParam = DEFAULT_REGISTERED_PARAM;
- pChannel->pitchBendSensitivity = DEFAULT_PITCH_BEND_SENSITIVITY;
- pChannel->finePitch = DEFAULT_FINE_PITCH;
- pChannel->coarsePitch = DEFAULT_COARSE_PITCH;
-
- /*
- program change, bank select, channel volume CC7, pan CC10
- are NOT reset
- */
- break;
-
- /*
- For logical reasons, the RPN data entry are grouped together.
- However, keep in mind that these cases are not necessarily in
- ascending order.
- e.g., MIDI_CONTROLLER_DATA_ENTRY_MSB == 6,
- whereas MIDI_CONTROLLER_SUSTAIN_PEDAL == 64.
- So arrange these case statements in whatever manner is more efficient for
- the processor / compiler.
- */
- case MIDI_CONTROLLER_ENTER_DATA_MSB:
- case MIDI_CONTROLLER_ENTER_DATA_LSB:
- case MIDI_CONTROLLER_SELECT_RPN_LSB:
- case MIDI_CONTROLLER_SELECT_RPN_MSB:
- case MIDI_CONTROLLER_SELECT_NRPN_MSB:
- case MIDI_CONTROLLER_SELECT_NRPN_LSB:
- VMUpdateRPNStateMachine(pSynth, channel, controller, value);
- break;
-
- case MIDI_CONTROLLER_ALL_SOUND_OFF:
- case MIDI_CONTROLLER_ALL_NOTES_OFF:
- case MIDI_CONTROLLER_OMNI_OFF:
- case MIDI_CONTROLLER_OMNI_ON:
- case MIDI_CONTROLLER_MONO_ON_POLY_OFF:
- case MIDI_CONTROLLER_POLY_ON_MONO_OFF:
- /* NOTE: we treat all sounds off the same as all notes off */
- VMAllNotesOff(pVoiceMgr, pSynth, channel);
- break;
-
- default:
-#ifdef _DEBUG_VM
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMControlChange: controller %d not yet implemented\n", controller); */ }
-#endif
- break;
-
- }
-
- return;
-}
-
-/*----------------------------------------------------------------------------
- * VMUpdateRPNStateMachine()
- *----------------------------------------------------------------------------
- * Purpose:
- * Call this function when we want to parse RPN related controller messages.
- * We only support RPN0 (pitch bend sensitivity), RPN1 (fine tuning) and
- * RPN2 (coarse tuning). Any other RPNs or NRPNs are ignored for now.
- *.
- * Supports any order, so not a state machine anymore. This function was
- * rewritten to work correctly regardless of order.
- *
- * Inputs:
- * nChannel - the channel this controller message is coming from
- * nControllerNumber - which RPN related controller
- * nControlValue - the value of the RPN related controller
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- * returns EAS_RESULT, which is typically EAS_SUCCESS, since there are
- * few possible errors
- *
- * Side Effects:
- * gsSynthObject.m_sChannel[nChannel].m_nPitchBendSensitivity
- * (or m_nFinePitch or m_nCoarsePitch)
- * will be updated if the proper RPN message is received.
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT VMUpdateRPNStateMachine (S_SYNTH *pSynth, EAS_U8 channel, EAS_U8 controller, EAS_U8 value)
-{
- S_SYNTH_CHANNEL *pChannel;
-
-#ifdef _DEBUG_VM
- if (channel >= NUM_SYNTH_CHANNELS)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMUpdateRPNStateMachines: error, %d invalid channel number\n",
- channel); */ }
- return EAS_FAILURE;
- }
-#endif
-
- pChannel = &(pSynth->channels[channel]);
-
- switch (controller)
- {
- case MIDI_CONTROLLER_SELECT_NRPN_MSB:
- case MIDI_CONTROLLER_SELECT_NRPN_LSB:
- pChannel->registeredParam = DEFAULT_REGISTERED_PARAM;
- break;
- case MIDI_CONTROLLER_SELECT_RPN_MSB:
- pChannel->registeredParam =
- (pChannel->registeredParam & 0x7F) | (value<<7);
- break;
- case MIDI_CONTROLLER_SELECT_RPN_LSB:
- pChannel->registeredParam =
- (pChannel->registeredParam & 0x7F00) | value;
- break;
- case MIDI_CONTROLLER_ENTER_DATA_MSB:
- switch (pChannel->registeredParam)
- {
- case 0:
- pChannel->pitchBendSensitivity = value * 100;
- break;
- case 1:
- /*lint -e{702} <avoid division for performance reasons>*/
- pChannel->finePitch = (EAS_I8)((((value << 7) - 8192) * 100) >> 13);
- break;
- case 2:
- pChannel->coarsePitch = (EAS_I8)(value - 64);
- break;
- default:
- break;
- }
- break;
- case MIDI_CONTROLLER_ENTER_DATA_LSB:
- switch (pChannel->registeredParam)
- {
- case 0:
- //ignore lsb
- break;
- case 1:
- //ignore lsb
- break;
- case 2:
- //ignore lsb
- break;
- default:
- break;
- }
- break;
- default:
- return EAS_FAILURE; //not a RPN related controller
- }
-
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * VMUpdateStaticChannelParameters()
- *----------------------------------------------------------------------------
- * Purpose:
- * Update all of the static channel parameters for channels that have had
- * a controller change values
- * Or if the synth has signalled that all channels must forcibly
- * be updated
- *
- * Inputs:
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- * none
- *
- * Side Effects:
- * - psSynthObject->m_sChannel[].m_nStaticGain and m_nStaticPitch
- * are updated for channels whose controller values have changed
- * or if the synth has signalled that all channels must forcibly
- * be updated
- *----------------------------------------------------------------------------
-*/
-void VMUpdateStaticChannelParameters (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth)
-{
- EAS_INT channel;
-
- if (pSynth->synthFlags & SYNTH_FLAG_UPDATE_ALL_CHANNEL_PARAMETERS)
- {
- /*
- the synth wants us to forcibly update all channel
- parameters. This event occurs when we are about to
- finish resetting the synth
- */
- for (channel = 0; channel < NUM_SYNTH_CHANNELS; channel++)
- {
-#ifdef _HYBRID_SYNTH
- if (pSynth->channels[channel].regionIndex & FLAG_RGN_IDX_FM_SYNTH)
- pSecondarySynth->pfUpdateChannel(pVoiceMgr, pSynth, (EAS_U8) channel);
- else
- pPrimarySynth->pfUpdateChannel(pVoiceMgr, pSynth, (EAS_U8) channel);
-#else
- pPrimarySynth->pfUpdateChannel(pVoiceMgr, pSynth, (EAS_U8) channel);
-#endif
- }
-
- /*
- clear the flag to indicates we have now forcibly
- updated all channel parameters
- */
- pSynth->synthFlags &= ~SYNTH_FLAG_UPDATE_ALL_CHANNEL_PARAMETERS;
- }
- else
- {
-
- /* only update channel params if signalled by a channel flag */
- for (channel = 0; channel < NUM_SYNTH_CHANNELS; channel++)
- {
- if ( 0 != (pSynth->channels[channel].channelFlags & CHANNEL_FLAG_UPDATE_CHANNEL_PARAMETERS))
- {
-#ifdef _HYBRID_SYNTH
- if (pSynth->channels[channel].regionIndex & FLAG_RGN_IDX_FM_SYNTH)
- pSecondarySynth->pfUpdateChannel(pVoiceMgr, pSynth, (EAS_U8) channel);
- else
- pPrimarySynth->pfUpdateChannel(pVoiceMgr, pSynth, (EAS_U8) channel);
-#else
- pPrimarySynth->pfUpdateChannel(pVoiceMgr, pSynth, (EAS_U8) channel);
-#endif
- }
- }
-
- }
-
- return;
-}
-
-/*----------------------------------------------------------------------------
- * VMFindProgram()
- *----------------------------------------------------------------------------
- * Purpose:
- * Look up an individual program in sound library. This function
- * searches the bank list for a program, then the individual program
- * list.
- *
- * Inputs:
- *
- * Outputs:
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT VMFindProgram (const S_EAS *pEAS, EAS_U32 bank, EAS_U8 programNum, EAS_U16 *pRegionIndex)
-{
- EAS_U32 locale;
- const S_PROGRAM *p;
- EAS_U16 i;
- EAS_U16 regionIndex;
-
- /* make sure we have a valid sound library */
- if (pEAS == NULL)
- return EAS_FAILURE;
-
- /* search the banks */
- for (i = 0; i < pEAS->numBanks; i++)
- {
- if (bank == (EAS_U32) pEAS->pBanks[i].locale)
- {
- regionIndex = pEAS->pBanks[i].regionIndex[programNum];
- if (regionIndex != INVALID_REGION_INDEX)
- {
- *pRegionIndex = regionIndex;
- return EAS_SUCCESS;
- }
- break;
- }
- }
-
- /* establish locale */
- locale = ( bank << 8) | programNum;
-
- /* search for program */
- for (i = 0, p = pEAS->pPrograms; i < pEAS->numPrograms; i++, p++)
- {
- if (p->locale == locale)
- {
- *pRegionIndex = p->regionIndex;
- return EAS_SUCCESS;
- }
- }
-
- return EAS_FAILURE;
-}
-
-#ifdef DLS_SYNTHESIZER
-/*----------------------------------------------------------------------------
- * VMFindDLSProgram()
- *----------------------------------------------------------------------------
- * Purpose:
- * Look up an individual program in sound library. This function
- * searches the bank list for a program, then the individual program
- * list.
- *
- * Inputs:
- *
- * Outputs:
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT VMFindDLSProgram (const S_DLS *pDLS, EAS_U32 bank, EAS_U8 programNum, EAS_U16 *pRegionIndex)
-{
- EAS_U32 locale;
- const S_PROGRAM *p;
- EAS_U16 i;
-
- /* make sure we have a valid sound library */
- if (pDLS == NULL)
- return EAS_FAILURE;
-
- /* establish locale */
- locale = (bank << 8) | programNum;
-
- /* search for program */
- for (i = 0, p = pDLS->pDLSPrograms; i < pDLS->numDLSPrograms; i++, p++)
- {
- if (p->locale == locale)
- {
- *pRegionIndex = p->regionIndex;
- return EAS_SUCCESS;
- }
- }
-
- return EAS_FAILURE;
-}
-#endif
-
-/*----------------------------------------------------------------------------
- * VMProgramChange()
- *----------------------------------------------------------------------------
- * Purpose:
- * Change the instrument (program) for the given channel.
- *
- * Depending on the program number, and the bank selected for this channel, the
- * program may be in ROM, RAM (from SMAF or CMX related RAM wavetable), or
- * Alternate wavetable (from mobile DLS or other DLS file)
- *
- * This function figures out what wavetable should be used, and sets it up as the
- * wavetable to use for this channel. Also the channel may switch from a melodic
- * channel to a rhythm channel, or vice versa.
- *
- * Inputs:
- *
- * Outputs:
- * Side Effects:
- * gsSynthObject.m_sChannel[nChannel].m_nProgramNumber is likely changed
- * gsSynthObject.m_sChannel[nChannel].m_psEAS may be changed
- * gsSynthObject.m_sChannel[nChannel].m_bRhythmChannel may be changed
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, pVoiceMgr) reserved for future use */
-void VMProgramChange (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel, EAS_U8 program)
-{
- S_SYNTH_CHANNEL *pChannel;
- EAS_U32 bank;
- EAS_U16 regionIndex;
-
-#ifdef _DEBUG_VM
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "VMProgramChange: vSynthNum=%d, channel=%d, program=%d\n", pSynth->vSynthNum, channel, program); */ }
-#endif
-
- /* setup pointer to MIDI channel data */
- pChannel = &pSynth->channels[channel];
- bank = pChannel->bankNum;
-
- /* allow channels to switch between being melodic or rhythm channels, using GM2 CC values */
- if ((bank & 0xFF00) == DEFAULT_RHYTHM_BANK_NUMBER)
- {
- /* make it a rhythm channel */
- pChannel->channelFlags |= CHANNEL_FLAG_RHYTHM_CHANNEL;
- }
- else if ((bank & 0xFF00) == DEFAULT_MELODY_BANK_NUMBER)
- {
- /* make it a melody channel */
- pChannel->channelFlags &= ~CHANNEL_FLAG_RHYTHM_CHANNEL;
- }
-
- regionIndex = DEFAULT_REGION_INDEX;
-
-#ifdef EXTERNAL_AUDIO
- /* give the external audio interface a chance to handle it */
- if (pSynth->cbProgChgFunc != NULL)
- {
- S_EXT_AUDIO_PRG_CHG prgChg;
- prgChg.channel = channel;
- prgChg.bank = (EAS_U16) bank;
- prgChg.program = program;
- if (pSynth->cbProgChgFunc(pSynth->pExtAudioInstData, &prgChg))
- pChannel->channelFlags |= CHANNEL_FLAG_EXTERNAL_AUDIO;
- }
-
-#endif
-
-
-#ifdef DLS_SYNTHESIZER
- /* first check for DLS program that may overlay the internal instrument */
- if (VMFindDLSProgram(pSynth->pDLS, bank, program, &regionIndex) != EAS_SUCCESS)
-#endif
-
- /* braces to support 'if' clause above */
- {
-
- /* look in the internal banks */
- if (VMFindProgram(pSynth->pEAS, bank, program, &regionIndex) != EAS_SUCCESS)
-
- /* fall back to default bank */
- {
- if (pSynth->channels[channel].channelFlags & CHANNEL_FLAG_RHYTHM_CHANNEL)
- bank = DEFAULT_RHYTHM_BANK_NUMBER;
- else
- bank = DEFAULT_MELODY_BANK_NUMBER;
-
- if (VMFindProgram(pSynth->pEAS, bank, program, &regionIndex) != EAS_SUCCESS)
-
- /* switch to program 0 in the default bank */
- {
- if (VMFindProgram(pSynth->pEAS, bank, 0, &regionIndex) != EAS_SUCCESS)
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "VMProgramChange: No program @ %03d:%03d:%03d\n",
- (bank >> 8) & 0x7f, bank & 0x7f, program); */ }
- }
- }
- }
-
- /* we have our new program change for this channel */
- pChannel->programNum = program;
- pChannel->regionIndex = regionIndex;
-
- /*
- set a channel flag to request parameter updates
- for all the voices associated with this channel
- */
- pChannel->channelFlags |= CHANNEL_FLAG_UPDATE_CHANNEL_PARAMETERS;
-
- return;
-}
-
-/*----------------------------------------------------------------------------
- * VMAddSamples()
- *----------------------------------------------------------------------------
- * Purpose:
- * Synthesize the requested number of samples (block based processing)
- *
- * Inputs:
- * nNumSamplesToAdd - number of samples to write to buffer
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- * number of voices rendered
- *
- * Side Effects:
- * - samples are added to the presently free buffer
- *
- *----------------------------------------------------------------------------
-*/
-EAS_I32 VMAddSamples (S_VOICE_MGR *pVoiceMgr, EAS_I32 *pMixBuffer, EAS_I32 numSamples)
-{
- S_SYNTH *pSynth;
- EAS_INT voicesRendered;
- EAS_INT voiceNum;
- EAS_BOOL done;
-
-#ifdef _REVERB
- EAS_PCM *pReverbSendBuffer;
-#endif // ifdef _REVERB
-
-#ifdef _CHORUS
- EAS_PCM *pChorusSendBuffer;
-#endif // ifdef _CHORUS
-
- voicesRendered = 0;
- for (voiceNum = 0; voiceNum < MAX_SYNTH_VOICES; voiceNum++)
- {
-
- /* retarget stolen voices */
- if ((pVoiceMgr->voices[voiceNum].voiceState == eVoiceStateStolen) && (pVoiceMgr->voices[voiceNum].gain <= 0))
- VMRetargetStolenVoice(pVoiceMgr, voiceNum);
-
- /* get pointer to virtual synth */
- pSynth = pVoiceMgr->pSynth[pVoiceMgr->voices[voiceNum].channel >> 4];
-
- /* synthesize active voices */
- if (pVoiceMgr->voices[voiceNum].voiceState != eVoiceStateFree)
- {
- done = GetSynthPtr(voiceNum)->pfUpdateVoice(pVoiceMgr, pSynth, &pVoiceMgr->voices[voiceNum], GetAdjustedVoiceNum(voiceNum), pMixBuffer, numSamples);
- voicesRendered++;
-
- /* voice is finished */
- if (done == EAS_TRUE)
- {
- /* set gain of stolen voice to zero so it will be restarted */
- if (pVoiceMgr->voices[voiceNum].voiceState == eVoiceStateStolen)
- pVoiceMgr->voices[voiceNum].gain = 0;
-
- /* or return it to the free voice pool */
- else
- VMFreeVoice(pVoiceMgr, pSynth, &pVoiceMgr->voices[voiceNum]);
- }
-
- /* if this voice is scheduled to be muted, set the mute flag */
- if (pVoiceMgr->voices[voiceNum].voiceFlags & VOICE_FLAG_DEFER_MUTE)
- {
- pVoiceMgr->voices[voiceNum].voiceFlags &= ~(VOICE_FLAG_DEFER_MUTE | VOICE_FLAG_DEFER_MIDI_NOTE_OFF);
- VMMuteVoice(pVoiceMgr, voiceNum);
- }
-
- /* if voice just started, advance state to play */
- if (pVoiceMgr->voices[voiceNum].voiceState == eVoiceStateStart)
- pVoiceMgr->voices[voiceNum].voiceState = eVoiceStatePlay;
- }
- }
-
- return voicesRendered;
-}
-
-/*----------------------------------------------------------------------------
- * VMRender()
- *----------------------------------------------------------------------------
- * Purpose:
- * This routine renders a frame of audio
- *
- * Inputs:
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- * pVoicesRendered - number of voices rendered this frame
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT VMRender (S_VOICE_MGR *pVoiceMgr, EAS_I32 numSamples, EAS_I32 *pMixBuffer, EAS_I32 *pVoicesRendered)
-{
- S_SYNTH *pSynth;
- EAS_INT i;
- EAS_INT channel;
-
-#ifdef _CHECKED_BUILD
- SanityCheck(pVoiceMgr);
-#endif
-
- /* update MIDI channel parameters */
- *pVoicesRendered = 0;
- for (i = 0; i < MAX_VIRTUAL_SYNTHESIZERS; i++)
- {
- if (pVoiceMgr->pSynth[i] != NULL)
- VMUpdateStaticChannelParameters(pVoiceMgr, pVoiceMgr->pSynth[i]);
- }
-
- /* synthesize a buffer of audio */
- *pVoicesRendered = VMAddSamples(pVoiceMgr, pMixBuffer, numSamples);
-
- /*
- * check for deferred note-off messages
- * If flag is set, that means one or more voices are expecting deferred
- * midi note-off messages because the midi note-on and corresponding midi
- * note-off requests occurred during the same update interval. The goal
- * is the defer the note-off request so that the note can at least start.
- */
- for (i = 0; i < MAX_VIRTUAL_SYNTHESIZERS; i++)
- {
- pSynth = pVoiceMgr->pSynth[i];
-
- if (pSynth== NULL)
- continue;
-
- if (pSynth->synthFlags & SYNTH_FLAG_DEFERRED_MIDI_NOTE_OFF_PENDING)
- VMDeferredStopNote(pVoiceMgr, pSynth);
-
- /* check if we need to reset the synth */
- if ((pSynth->synthFlags & SYNTH_FLAG_RESET_IS_REQUESTED) &&
- (pSynth->numActiveVoices == 0))
- {
- /*
- complete the process of resetting the synth now that
- all voices have muted
- */
-#ifdef _DEBUG_VM
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMAddSamples: complete the reset process\n"); */ }
-#endif
-
- VMInitializeAllChannels(pVoiceMgr, pSynth);
- VMInitializeAllVoices(pVoiceMgr, pSynth->vSynthNum);
-
- /* clear the reset flag */
- pSynth->synthFlags &= ~SYNTH_FLAG_RESET_IS_REQUESTED;
- }
-
- /* clear channel update flags */
- for (channel = 0; channel < NUM_SYNTH_CHANNELS; channel++)
- pSynth->channels[channel].channelFlags &= ~CHANNEL_FLAG_UPDATE_CHANNEL_PARAMETERS;
-
- }
-
-#ifdef _CHECKED_BUILD
- SanityCheck(pVoiceMgr);
-#endif
-
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * VMInitWorkload()
- *----------------------------------------------------------------------------
- * Purpose:
- * Clears the workload counter
- *
- * Inputs:
- * pVoiceMgr - pointer to instance data
- *
- * Outputs:
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-void VMInitWorkload (S_VOICE_MGR *pVoiceMgr)
-{
- pVoiceMgr->workload = 0;
-}
-
-/*----------------------------------------------------------------------------
- * VMSetWorkload()
- *----------------------------------------------------------------------------
- * Purpose:
- * Sets the max workload for a single frame.
- *
- * Inputs:
- * pVoiceMgr - pointer to instance data
- *
- * Outputs:
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-void VMSetWorkload (S_VOICE_MGR *pVoiceMgr, EAS_I32 maxWorkLoad)
-{
- pVoiceMgr->maxWorkLoad = maxWorkLoad;
-}
-
-/*----------------------------------------------------------------------------
- * VMCheckWorkload()
- *----------------------------------------------------------------------------
- * Purpose:
- * Checks to see if work load has been exceeded on this frame.
- *
- * Inputs:
- * pVoiceMgr - pointer to instance data
- *
- * Outputs:
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_BOOL VMCheckWorkload (S_VOICE_MGR *pVoiceMgr)
-{
- if (pVoiceMgr->maxWorkLoad > 0)
- return (EAS_BOOL) (pVoiceMgr->workload >= pVoiceMgr->maxWorkLoad);
- return EAS_FALSE;
-}
-
-/*----------------------------------------------------------------------------
- * VMActiveVoices()
- *----------------------------------------------------------------------------
- * Purpose:
- * Returns the number of active voices in the synthesizer.
- *
- * Inputs:
- * pEASData - pointer to instance data
- *
- * Outputs:
- * Returns the number of active voices
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_I32 VMActiveVoices (S_SYNTH *pSynth)
-{
- return pSynth->numActiveVoices;
-}
-
-/*----------------------------------------------------------------------------
- * VMSetSynthPolyphony()
- *----------------------------------------------------------------------------
- * Purpose:
- * Set the synth to a new polyphony value. Value must be >= 1 and
- * <= MAX_SYNTH_VOICES. This function will pin the polyphony at those limits
- *
- * Inputs:
- * pVoiceMgr pointer to synthesizer data
- * polyphonyCount desired polyphony count
- * synth synthesizer number (0 = onboard, 1 = DSP)
- *
- * Outputs:
- * Returns error code
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT VMSetSynthPolyphony (S_VOICE_MGR *pVoiceMgr, EAS_I32 synth, EAS_I32 polyphonyCount)
-{
- EAS_INT i;
- EAS_INT activeVoices;
-
- /* lower limit */
- if (polyphonyCount < 1)
- polyphonyCount = 1;
-
- /* split architecture */
-#if defined(_SECONDARY_SYNTH) || defined(EAS_SPLIT_WT_SYNTH)
- if (synth == EAS_MCU_SYNTH)
- {
- if (polyphonyCount > NUM_PRIMARY_VOICES)
- polyphonyCount = NUM_PRIMARY_VOICES;
- if (pVoiceMgr->maxPolyphonyPrimary == polyphonyCount)
- return EAS_SUCCESS;
- pVoiceMgr->maxPolyphonyPrimary = (EAS_U16) polyphonyCount;
- }
- else if (synth == EAS_DSP_SYNTH)
- {
- if (polyphonyCount > NUM_SECONDARY_VOICES)
- polyphonyCount = NUM_SECONDARY_VOICES;
- if (pVoiceMgr->maxPolyphonySecondary == polyphonyCount)
- return EAS_SUCCESS;
- pVoiceMgr->maxPolyphonySecondary = (EAS_U16) polyphonyCount;
- }
- else
- return EAS_ERROR_PARAMETER_RANGE;
-
- /* setting for SP-MIDI */
- pVoiceMgr->maxPolyphony = pVoiceMgr->maxPolyphonyPrimary + pVoiceMgr->maxPolyphonySecondary;
-
- /* standard architecture */
-#else
- if (synth != EAS_MCU_SYNTH)
- return EAS_ERROR_PARAMETER_RANGE;
-
- /* pin desired value to possible limits */
- if (polyphonyCount > MAX_SYNTH_VOICES)
- polyphonyCount = MAX_SYNTH_VOICES;
-
- /* set polyphony, if value is different than current value */
- if (pVoiceMgr->maxPolyphony == polyphonyCount)
- return EAS_SUCCESS;
-
- pVoiceMgr->maxPolyphony = (EAS_U16) polyphonyCount;
-#endif
-
- /* if SPMIDI enabled, update channel masking based on new polyphony */
- for (i = 0; i < MAX_VIRTUAL_SYNTHESIZERS; i++)
- {
- if (pVoiceMgr->pSynth[i])
- {
- if (pVoiceMgr->pSynth[i]->synthFlags & SYNTH_FLAG_SP_MIDI_ON)
- VMMIPUpdateChannelMuting(pVoiceMgr, pVoiceMgr->pSynth[i]);
- else
- pVoiceMgr->pSynth[i]->poolAlloc[0] = (EAS_U8) polyphonyCount;
- }
- }
-
- /* are we under polyphony limit? */
- if (pVoiceMgr->activeVoices <= polyphonyCount)
- return EAS_SUCCESS;
-
- /* count the number of active voices */
- activeVoices = 0;
- for (i = 0; i < MAX_SYNTH_VOICES; i++)
- {
-
- /* is voice active? */
- if ((pVoiceMgr->voices[i].voiceState != eVoiceStateFree) && (pVoiceMgr->voices[i].voiceState != eVoiceStateMuting))
- activeVoices++;
- }
-
- /* we may have to mute voices to reach new target */
- while (activeVoices > polyphonyCount)
- {
- S_SYNTH *pSynth;
- S_SYNTH_VOICE *pVoice;
- EAS_I32 currentPriority, bestPriority;
- EAS_INT bestCandidate;
-
- /* find the lowest priority voice */
- bestPriority = bestCandidate = -1;
- for (i = 0; i < MAX_SYNTH_VOICES; i++)
- {
-
- pVoice = &pVoiceMgr->voices[i];
-
- /* ignore free and muting voices */
- if ((pVoice->voiceState == eVoiceStateFree) || (pVoice->voiceState == eVoiceStateMuting))
- continue;
-
- pSynth = pVoiceMgr->pSynth[GET_VSYNTH(pVoice->channel)];
-
- /* if voice is stolen or just started, reduce the likelihood it will be stolen */
- if (( pVoice->voiceState == eVoiceStateStolen) || (pVoice->voiceFlags & VOICE_FLAG_NO_SAMPLES_SYNTHESIZED_YET))
- {
- /* include velocity */
- currentPriority = 128 - pVoice->nextVelocity;
-
- /* include channel priority */
- currentPriority += pSynth->channels[GET_CHANNEL(pVoice->nextChannel)].pool << CHANNEL_PRIORITY_STEAL_WEIGHT;
- }
- else
- {
- /* include age */
- currentPriority = (EAS_I32) pVoice->age << NOTE_AGE_STEAL_WEIGHT;
-
- /* include note gain -higher gain is lower steal value */
- /*lint -e{704} use shift for performance */
- currentPriority += ((32768 >> (12 - NOTE_GAIN_STEAL_WEIGHT)) + 256) -
- ((EAS_I32) pVoice->gain >> (12 - NOTE_GAIN_STEAL_WEIGHT));
-
- /* include channel priority */
- currentPriority += pSynth->channels[GET_CHANNEL(pVoice->channel)].pool << CHANNEL_PRIORITY_STEAL_WEIGHT;
- }
-
- /* include synth priority */
- currentPriority += pSynth->priority << SYNTH_PRIORITY_WEIGHT;
-
- /* is this the best choice so far? */
- if (currentPriority > bestPriority)
- {
- bestPriority = currentPriority;
- bestCandidate = i;
- }
- }
-
- /* shutdown best candidate */
- if (bestCandidate < 0)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "VMSetPolyphony: Unable to reduce polyphony\n"); */ }
- break;
- }
-
- /* shut down this voice */
- /*lint -e{771} pSynth is initialized if bestCandidate >= 0 */
- VMMuteVoice(pVoiceMgr, bestCandidate);
- activeVoices--;
- }
-
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * VMGetSynthPolyphony()
- *----------------------------------------------------------------------------
- * Purpose:
- * Returns the current polyphony setting
- *
- * Inputs:
- * pVoiceMgr pointer to synthesizer data
- * synth synthesizer number (0 = onboard, 1 = DSP)
- *
- * Outputs:
- * Returns actual polyphony value set, as pinned by limits
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT VMGetSynthPolyphony (S_VOICE_MGR *pVoiceMgr, EAS_I32 synth, EAS_I32 *pPolyphonyCount)
-{
-
-#if defined(_SECONDARY_SYNTH) || defined(EAS_SPLIT_WT_SYNTH)
- if (synth == EAS_MCU_SYNTH)
- *pPolyphonyCount = pVoiceMgr->maxPolyphonyPrimary;
- else if (synth == EAS_DSP_SYNTH)
- *pPolyphonyCount = pVoiceMgr->maxPolyphonySecondary;
- else
- return EAS_ERROR_PARAMETER_RANGE;
-#else
- if (synth != EAS_MCU_SYNTH)
- return EAS_ERROR_PARAMETER_RANGE;
- *pPolyphonyCount = pVoiceMgr->maxPolyphony;
-#endif
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * VMSetPolyphony()
- *----------------------------------------------------------------------------
- * Purpose:
- * Set the virtual synth polyphony. 0 = no limit (i.e. can use
- * all available voices).
- *
- * Inputs:
- * pVoiceMgr pointer to synthesizer data
- * polyphonyCount desired polyphony count
- * pSynth pointer to virtual synth
- *
- * Outputs:
- * Returns error code
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT VMSetPolyphony (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_I32 polyphonyCount)
-{
- EAS_INT i;
- EAS_INT activeVoices;
-
- /* check limits */
- if (polyphonyCount < 0)
- return EAS_ERROR_PARAMETER_RANGE;
-
- /* zero is max polyphony */
- if ((polyphonyCount == 0) || (polyphonyCount > MAX_SYNTH_VOICES))
- {
- pSynth->maxPolyphony = 0;
- return EAS_SUCCESS;
- }
-
- /* set new polyphony */
- pSynth->maxPolyphony = (EAS_U16) polyphonyCount;
-
- /* max polyphony is minimum of virtual synth and actual synth */
- if (polyphonyCount > pVoiceMgr->maxPolyphony)
- polyphonyCount = pVoiceMgr->maxPolyphony;
-
- /* if SP-MIDI mode, update the channel muting */
- if (pSynth->synthFlags & SYNTH_FLAG_SP_MIDI_ON)
- VMMIPUpdateChannelMuting(pVoiceMgr, pSynth);
- else
- pSynth->poolAlloc[0] = (EAS_U8) polyphonyCount;
-
- /* are we under polyphony limit? */
- if (pSynth->numActiveVoices <= polyphonyCount)
- return EAS_SUCCESS;
-
- /* count the number of active voices */
- activeVoices = 0;
- for (i = 0; i < MAX_SYNTH_VOICES; i++)
- {
- /* this synth? */
- if (GET_VSYNTH(pVoiceMgr->voices[i].nextChannel) != pSynth->vSynthNum)
- continue;
-
- /* is voice active? */
- if ((pVoiceMgr->voices[i].voiceState != eVoiceStateFree) && (pVoiceMgr->voices[i].voiceState != eVoiceStateMuting))
- activeVoices++;
- }
-
- /* we may have to mute voices to reach new target */
- while (activeVoices > polyphonyCount)
- {
- S_SYNTH_VOICE *pVoice;
- EAS_I32 currentPriority, bestPriority;
- EAS_INT bestCandidate;
-
- /* find the lowest priority voice */
- bestPriority = bestCandidate = -1;
- for (i = 0; i < MAX_SYNTH_VOICES; i++)
- {
- pVoice = &pVoiceMgr->voices[i];
-
- /* this synth? */
- if (GET_VSYNTH(pVoice->nextChannel) != pSynth->vSynthNum)
- continue;
-
- /* if voice is stolen or just started, reduce the likelihood it will be stolen */
- if (( pVoice->voiceState == eVoiceStateStolen) || (pVoice->voiceFlags & VOICE_FLAG_NO_SAMPLES_SYNTHESIZED_YET))
- {
- /* include velocity */
- currentPriority = 128 - pVoice->nextVelocity;
-
- /* include channel priority */
- currentPriority += pSynth->channels[GET_CHANNEL(pVoice->nextChannel)].pool << CHANNEL_PRIORITY_STEAL_WEIGHT;
- }
- else
- {
- /* include age */
- currentPriority = (EAS_I32) pVoice->age << NOTE_AGE_STEAL_WEIGHT;
-
- /* include note gain -higher gain is lower steal value */
- /*lint -e{704} use shift for performance */
- currentPriority += ((32768 >> (12 - NOTE_GAIN_STEAL_WEIGHT)) + 256) -
- ((EAS_I32) pVoice->gain >> (12 - NOTE_GAIN_STEAL_WEIGHT));
-
- /* include channel priority */
- currentPriority += pSynth->channels[GET_CHANNEL(pVoice->nextChannel)].pool << CHANNEL_PRIORITY_STEAL_WEIGHT;
- }
-
- /* is this the best choice so far? */
- if (currentPriority > bestPriority)
- {
- bestPriority = currentPriority;
- bestCandidate = i;
- }
- }
-
- /* shutdown best candidate */
- if (bestCandidate < 0)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "VMSetPolyphony: Unable to reduce polyphony\n"); */ }
- break;
- }
-
- /* shut down this voice */
- VMMuteVoice(pVoiceMgr, bestCandidate);
- activeVoices--;
- }
-
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * VMGetPolyphony()
- *----------------------------------------------------------------------------
- * Purpose:
- * Get the virtual synth polyphony
- *
- * Inputs:
- * pVoiceMgr pointer to synthesizer data
- * pPolyphonyCount pointer to variable to hold polyphony count
- * pSynth pointer to virtual synth
- *
- * Outputs:
- * Returns error code
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, pVoiceMgr) reserved for future use */
-EAS_RESULT VMGetPolyphony (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_I32 *pPolyphonyCount)
-{
- *pPolyphonyCount = (EAS_U16) pSynth->maxPolyphony;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * VMSetPriority()
- *----------------------------------------------------------------------------
- * Purpose:
- * Set the virtual synth priority
- *
- * Inputs:
- * pVoiceMgr pointer to synthesizer data
- * priority new priority
- * pSynth pointer to virtual synth
- *
- * Outputs:
- * Returns error code
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, pVoiceMgr) reserved for future use */
-EAS_RESULT VMSetPriority (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_I32 priority)
-{
- pSynth->priority = (EAS_U8) priority ;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * VMGetPriority()
- *----------------------------------------------------------------------------
- * Purpose:
- * Get the virtual synth priority
- *
- * Inputs:
- * pVoiceMgr pointer to synthesizer data
- * pPriority pointer to variable to hold priority
- * pSynth pointer to virtual synth
- *
- * Outputs:
- * Returns error code
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, pVoiceMgr) reserved for future use */
-EAS_RESULT VMGetPriority (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_I32 *pPriority)
-{
- *pPriority = pSynth->priority;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * VMSetVolume()
- *----------------------------------------------------------------------------
- * Purpose:
- * Set the master volume for this synthesizer for this sequence.
- *
- * Inputs:
- * nSynthVolume - the desired master volume
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- *
- *
- * Side Effects:
- * overrides any previously set master volume from sysex
- *
- *----------------------------------------------------------------------------
-*/
-void VMSetVolume (S_SYNTH *pSynth, EAS_U16 masterVolume)
-{
- pSynth->masterVolume = masterVolume;
- pSynth->synthFlags |= SYNTH_FLAG_UPDATE_ALL_CHANNEL_PARAMETERS;
-}
-
-/*----------------------------------------------------------------------------
- * VMSetPitchBendRange()
- *----------------------------------------------------------------------------
- * Set the pitch bend range for the given channel.
- *----------------------------------------------------------------------------
-*/
-void VMSetPitchBendRange (S_SYNTH *pSynth, EAS_INT channel, EAS_I16 pitchBendRange)
-{
- pSynth->channels[channel].pitchBendSensitivity = pitchBendRange;
-}
-
-/*----------------------------------------------------------------------------
- * VMValidateEASLib()
- *----------------------------------------------------------------------------
- * Validates an EAS library
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT VMValidateEASLib (EAS_SNDLIB_HANDLE pEAS)
-{
- /* validate the sound library */
- if (pEAS)
- {
- if (pEAS->identifier != _EAS_LIBRARY_VERSION)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "VMValidateEASLib: Sound library mismatch in sound library: Read 0x%08x, expected 0x%08x\n",
- pEAS->identifier, _EAS_LIBRARY_VERSION); */ }
- return EAS_ERROR_SOUND_LIBRARY;
- }
-
- /* check sample rate */
- if ((pEAS->libAttr & LIBFORMAT_SAMPLE_RATE_MASK) != _OUTPUT_SAMPLE_RATE)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "VMValidateEASLib: Sample rate mismatch in sound library: Read %lu, expected %lu\n",
- pEAS->libAttr & LIBFORMAT_SAMPLE_RATE_MASK, _OUTPUT_SAMPLE_RATE); */ }
- return EAS_ERROR_SOUND_LIBRARY;
- }
-
-#ifdef _WT_SYNTH
- /* check sample bit depth */
-#ifdef _8_BIT_SAMPLES
- if (pEAS->libAttr & LIB_FORMAT_16_BIT_SAMPLES)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "VMValidateEASLib: Expected 8-bit samples and found 16-bit\n",
- pEAS->libAttr & LIBFORMAT_SAMPLE_RATE_MASK, _OUTPUT_SAMPLE_RATE); */ }
- return EAS_ERROR_SOUND_LIBRARY;
- }
-#endif
-#ifdef _16_BIT_SAMPLES
- if ((pEAS->libAttr & LIB_FORMAT_16_BIT_SAMPLES) == 0)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "VMValidateEASLib: Expected 16-bit samples and found 8-bit\n",
- pEAS->libAttr & LIBFORMAT_SAMPLE_RATE_MASK, _OUTPUT_SAMPLE_RATE); */ }
- return EAS_ERROR_SOUND_LIBRARY;
- }
-#endif
-#endif
- }
-
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * VMSetGlobalEASLib()
- *----------------------------------------------------------------------------
- * Purpose:
- * Sets the EAS library to be used by the synthesizer
- *
- * Inputs:
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT VMSetGlobalEASLib (S_VOICE_MGR *pVoiceMgr, EAS_SNDLIB_HANDLE pEAS)
-{
- EAS_RESULT result;
-
- result = VMValidateEASLib(pEAS);
- if (result != EAS_SUCCESS)
- return result;
-
- pVoiceMgr->pGlobalEAS = pEAS;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * VMSetEASLib()
- *----------------------------------------------------------------------------
- * Purpose:
- * Sets the EAS library to be used by the synthesizer
- *
- * Inputs:
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT VMSetEASLib (S_SYNTH *pSynth, EAS_SNDLIB_HANDLE pEAS)
-{
- EAS_RESULT result;
-
- result = VMValidateEASLib(pEAS);
- if (result != EAS_SUCCESS)
- return result;
-
- pSynth->pEAS = pEAS;
- return EAS_SUCCESS;
-}
-
-#ifdef DLS_SYNTHESIZER
-/*----------------------------------------------------------------------------
- * VMSetGlobalDLSLib()
- *----------------------------------------------------------------------------
- * Purpose:
- * Sets the DLS library to be used by the synthesizer
- *
- * Inputs:
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT VMSetGlobalDLSLib (EAS_DATA_HANDLE pEASData, EAS_DLSLIB_HANDLE pDLS)
-{
-
- if (pEASData->pVoiceMgr->pGlobalDLS)
- DLSCleanup(pEASData->hwInstData, pEASData->pVoiceMgr->pGlobalDLS);
-
- pEASData->pVoiceMgr->pGlobalDLS = pDLS;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * VMSetDLSLib()
- *----------------------------------------------------------------------------
- * Purpose:
- * Sets the DLS library to be used by the synthesizer
- *
- * Inputs:
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT VMSetDLSLib (S_SYNTH *pSynth, EAS_DLSLIB_HANDLE pDLS)
-{
- pSynth->pDLS = pDLS;
- return EAS_SUCCESS;
-}
-#endif
-
-/*----------------------------------------------------------------------------
- * VMSetTranposition()
- *----------------------------------------------------------------------------
- * Purpose:
- * Sets the global key transposition used by the synthesizer.
- * Transposes all melodic instruments up or down by the specified
- * amount. Range is limited to +/-12 semitones.
- *
- * Inputs:
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-void VMSetTranposition (S_SYNTH *pSynth, EAS_I32 transposition)
-{
- pSynth->globalTranspose = (EAS_I8) transposition;
-}
-
-/*----------------------------------------------------------------------------
- * VMGetTranposition()
- *----------------------------------------------------------------------------
- * Purpose:
- * Gets the global key transposition used by the synthesizer.
- * Transposes all melodic instruments up or down by the specified
- * amount. Range is limited to +/-12 semitones.
- *
- * Inputs:
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-void VMGetTranposition (S_SYNTH *pSynth, EAS_I32 *pTransposition)
-{
- *pTransposition = pSynth->globalTranspose;
-}
-
-/*----------------------------------------------------------------------------
- * VMGetNoteCount()
- *----------------------------------------------------------------------------
-* Returns the total note count
-*----------------------------------------------------------------------------
-*/
-EAS_I32 VMGetNoteCount (S_SYNTH *pSynth)
-{
- return pSynth->totalNoteCount;
-}
-
-/*----------------------------------------------------------------------------
- * VMMIDIShutdown()
- *----------------------------------------------------------------------------
- * Purpose:
- * Clean up any Synth related system issues.
- *
- * Inputs:
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- * None
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-void VMMIDIShutdown (S_EAS_DATA *pEASData, S_SYNTH *pSynth)
-{
- EAS_INT vSynthNum;
-
- /* decrement reference count, free if all references are gone */
- if (--pSynth->refCount > 0)
- return;
-
- vSynthNum = pSynth->vSynthNum;
-
- /* cleanup DLS load */
-#ifdef DLS_SYNTHESIZER
- /*lint -e{550} result used only in debugging code */
- if (pSynth->pDLS != NULL)
- {
- EAS_RESULT result;
- if ((result = DLSCleanup(pEASData->hwInstData, pSynth->pDLS)) != EAS_SUCCESS)
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "VMMIDIShutdown: Error %ld cleaning up DLS collection\n", result); */ }
- pSynth->pDLS = NULL;
- }
-#endif
-
- VMReset(pEASData->pVoiceMgr, pSynth, EAS_TRUE);
-
- /* check Configuration Module for static memory allocation */
- if (!pEASData->staticMemoryModel)
- EAS_HWFree(pEASData->hwInstData, pSynth);
-
- /* clear pointer to MIDI state */
- pEASData->pVoiceMgr->pSynth[vSynthNum] = NULL;
-}
-
-/*----------------------------------------------------------------------------
- * VMShutdown()
- *----------------------------------------------------------------------------
- * Purpose:
- * Clean up any Synth related system issues.
- *
- * Inputs:
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- * None
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-void VMShutdown (S_EAS_DATA *pEASData)
-{
-
- /* don't free a NULL pointer */
- if (pEASData->pVoiceMgr == NULL)
- return;
-
-#ifdef DLS_SYNTHESIZER
- /* if we have a global DLS collection, clean it up */
- if (pEASData->pVoiceMgr->pGlobalDLS)
- {
- DLSCleanup(pEASData->hwInstData, pEASData->pVoiceMgr->pGlobalDLS);
- pEASData->pVoiceMgr->pGlobalDLS = NULL;
- }
-#endif
-
- /* check Configuration Module for static memory allocation */
- if (!pEASData->staticMemoryModel)
- EAS_HWFree(pEASData->hwInstData, pEASData->pVoiceMgr);
- pEASData->pVoiceMgr = NULL;
-}
-
-#ifdef EXTERNAL_AUDIO
-/*----------------------------------------------------------------------------
- * EAS_RegExtAudioCallback()
- *----------------------------------------------------------------------------
- * Register a callback for external audio processing
- *----------------------------------------------------------------------------
-*/
-void VMRegExtAudioCallback (S_SYNTH *pSynth, EAS_VOID_PTR pInstData, EAS_EXT_PRG_CHG_FUNC cbProgChgFunc, EAS_EXT_EVENT_FUNC cbEventFunc)
-{
- pSynth->pExtAudioInstData = pInstData;
- pSynth->cbProgChgFunc = cbProgChgFunc;
- pSynth->cbEventFunc = cbEventFunc;
-}
-
-/*----------------------------------------------------------------------------
- * VMGetMIDIControllers()
- *----------------------------------------------------------------------------
- * Returns the MIDI controller values on the specified channel
- *----------------------------------------------------------------------------
-*/
-void VMGetMIDIControllers (S_SYNTH *pSynth, EAS_U8 channel, S_MIDI_CONTROLLERS *pControl)
-{
- pControl->modWheel = pSynth->channels[channel].modWheel;
- pControl->volume = pSynth->channels[channel].volume;
- pControl->pan = pSynth->channels[channel].pan;
- pControl->expression = pSynth->channels[channel].expression;
- pControl->channelPressure = pSynth->channels[channel].channelPressure;
-
-#ifdef _REVERB
- pControl->reverbSend = pSynth->channels[channel].reverbSend;
-#endif
-
-#ifdef _CHORUSE
- pControl->chorusSend = pSynth->channels[channel].chorusSend;
-#endif
-}
-#endif
-
-#ifdef _SPLIT_ARCHITECTURE
-/*----------------------------------------------------------------------------
- * VMStartFrame()
- *----------------------------------------------------------------------------
- * Purpose:
- * Starts an audio frame
- *
- * Inputs:
- *
- * Outputs:
- * Returns true if EAS_MixEnginePrep should be called (onboard mixing)
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_BOOL VMStartFrame (S_EAS_DATA *pEASData)
-{
-
- /* init counter for voices starts in split architecture */
-#ifdef MAX_VOICE_STARTS
- pVoiceMgr->numVoiceStarts = 0;
-#endif
-
- return pFrameInterface->pfStartFrame(pEASData->pVoiceMgr->pFrameBuffer);
-}
-
-/*----------------------------------------------------------------------------
- * VMEndFrame()
- *----------------------------------------------------------------------------
- * Purpose:
- * Stops an audio frame
- *
- * Inputs:
- *
- * Outputs:
- * Returns true if EAS_MixEnginePost should be called (onboard mixing)
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_BOOL VMEndFrame (S_EAS_DATA *pEASData)
-{
-
- return pFrameInterface->pfEndFrame(pEASData->pVoiceMgr->pFrameBuffer, pEASData->pMixBuffer, pEASData->masterGain);
-}
-#endif
-
-#ifdef TEST_HARNESS
-/*----------------------------------------------------------------------------
- * SanityCheck()
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT VMSanityCheck (EAS_DATA_HANDLE pEASData)
-{
- S_SYNTH_VOICE *pVoice;
- S_SYNTH *pSynth;
- EAS_INT i;
- EAS_INT j;
- EAS_INT freeVoices;
- EAS_INT activeVoices;
- EAS_INT playingVoices;
- EAS_INT stolenVoices;
- EAS_INT releasingVoices;
- EAS_INT mutingVoices;
- EAS_INT poolCount[MAX_VIRTUAL_SYNTHESIZERS][NUM_SYNTH_CHANNELS];
- EAS_INT vSynthNum;
- EAS_RESULT result = EAS_SUCCESS;
-
- /* initialize counts */
- EAS_HWMemSet(poolCount, 0, sizeof(poolCount));
- freeVoices = activeVoices = playingVoices = stolenVoices = releasingVoices = mutingVoices = 0;
-
- /* iterate through all voices */
- for (i = 0; i < MAX_SYNTH_VOICES; i++)
- {
- pVoice = &pEASData->pVoiceMgr->voices[i];
- if (pVoice->voiceState != eVoiceStateFree)
- {
- vSynthNum = GET_VSYNTH(pVoice->channel);
- if (vSynthNum >= MAX_VIRTUAL_SYNTHESIZERS)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "VMSanityCheck: Voice %d has invalid virtual synth number %d\n", i, vSynthNum); */ }
- result = EAS_FAILURE;
- continue;
- }
- pSynth = pEASData->pVoiceMgr->pSynth[vSynthNum];
-
- switch (pVoice->voiceState)
- {
- case eVoiceStateMuting:
- activeVoices++;
- mutingVoices++;
- break;
-
- case eVoiceStateStolen:
- vSynthNum = GET_VSYNTH(pVoice->nextChannel);
- if (vSynthNum >= MAX_VIRTUAL_SYNTHESIZERS)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "VMSanityCheck: Voice %d has invalid virtual synth number %d\n", i, vSynthNum); */ }
- result = EAS_FAILURE;
- continue;
- }
- pSynth = pEASData->pVoiceMgr->pSynth[vSynthNum];
- activeVoices++;
- stolenVoices++;
- poolCount[vSynthNum][pSynth->channels[GET_CHANNEL(pVoice->nextChannel)].pool]++;
- break;
-
- case eVoiceStateStart:
- case eVoiceStatePlay:
- activeVoices++;
- playingVoices++;
- poolCount[vSynthNum][pSynth->channels[GET_CHANNEL(pVoice->channel)].pool]++;
- break;
-
- case eVoiceStateRelease:
- activeVoices++;
- releasingVoices++;
- poolCount[vSynthNum][pSynth->channels[GET_CHANNEL(pVoice->channel)].pool]++;
- break;
-
- default:
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "VMSanityCheck : voice %d in invalid state\n", i); */ }
- result = EAS_FAILURE;
- break;
- }
- }
-
- /* count free voices */
- else
- freeVoices++;
- }
-
- /* dump state info */
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "%d free\n", freeVoices); */ }
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "%d active\n", activeVoices); */ }
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "%d playing\n", playingVoices); */ }
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "%d releasing\n", releasingVoices); */ }
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "%d muting\n", mutingVoices); */ }
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "%d stolen\n", stolenVoices); */ }
-
- if (pEASData->pVoiceMgr->activeVoices != activeVoices)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Active voice mismatch was %d should be %d\n",
- pEASData->pVoiceMgr->activeVoices, activeVoices); */ }
- result = EAS_FAILURE;
- }
-
- /* check virtual synth status */
- for (i = 0; i < MAX_VIRTUAL_SYNTHESIZERS; i++)
- {
- if (pEASData->pVoiceMgr->pSynth[i] == NULL)
- continue;
-
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Synth %d numActiveVoices: %d\n", i, pEASData->pVoiceMgr->pSynth[i]->numActiveVoices); */ }
- if (pEASData->pVoiceMgr->pSynth[i]->numActiveVoices > MAX_SYNTH_VOICES)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "VMSanityCheck: Synth %d illegal count for numActiveVoices: %d\n", i, pEASData->pVoiceMgr->pSynth[i]->numActiveVoices); */ }
- result = EAS_FAILURE;
- }
- for (j = 0; j < NUM_SYNTH_CHANNELS; j++)
- {
- if (poolCount[i][j] != pEASData->pVoiceMgr->pSynth[i]->poolCount[j])
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Pool count mismatch synth %d pool %d, was %d, should be %d\n",
- i, j, pEASData->pVoiceMgr->pSynth[i]->poolCount[j], poolCount[i][j]); */ }
- result = EAS_FAILURE;
- }
- }
- }
-
- return result;
-}
-#endif
-
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 794 $
+ * $Date: 2007-08-01 00:08:48 -0700 (Wed, 01 Aug 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+/* includes */
+#include "eas.h"
+#include "eas_data.h"
+#include "eas_config.h"
+#include "eas_report.h"
+#include "eas_midictrl.h"
+#include "eas_host.h"
+#include "eas_synth_protos.h"
+#include "eas_vm_protos.h"
+
+#ifdef DLS_SYNTHESIZER
+#include "eas_mdls.h"
+#endif
+
+// #define _DEBUG_VM
+
+/* some defines for workload */
+#define WORKLOAD_AMOUNT_SMALL_INCREMENT 5
+#define WORKLOAD_AMOUNT_START_NOTE 10
+#define WORKLOAD_AMOUNT_STOP_NOTE 10
+#define WORKLOAD_AMOUNT_KEY_GROUP 10
+#define WORKLOAD_AMOUNT_POLY_LIMIT 10
+
+/* pointer to base sound library */
+extern S_EAS easSoundLib;
+
+#ifdef TEST_HARNESS
+extern S_EAS easTestLib;
+EAS_SNDLIB_HANDLE VMGetLibHandle(EAS_INT libNum)
+{
+ switch (libNum)
+ {
+ case 0:
+ return &easSoundLib;
+#ifdef _WT_SYNTH
+ case 1:
+ return &easTestLib;
+#endif
+ default:
+ return NULL;
+ }
+}
+#endif
+
+/* pointer to synthesizer interface(s) */
+#ifdef _WT_SYNTH
+extern const S_SYNTH_INTERFACE wtSynth;
+#endif
+
+#ifdef _FM_SYNTH
+extern const S_SYNTH_INTERFACE fmSynth;
+#endif
+
+typedef S_SYNTH_INTERFACE *S_SYNTH_INTERFACE_HANDLE;
+
+/* wavetable on MCU */
+#if defined(EAS_WT_SYNTH)
+const S_SYNTH_INTERFACE *const pPrimarySynth = &wtSynth;
+
+/* FM on MCU */
+#elif defined(EAS_FM_SYNTH)
+const S_SYNTH_INTERFACE *const pPrimarySynth = &fmSynth;
+
+/* wavetable drums on MCU, FM melodic on DSP */
+#elif defined(EAS_HYBRID_SYNTH)
+const S_SYNTH_INTERFACE *const pPrimarySynth = &wtSynth;
+const S_SYNTH_INTERFACE *const pSecondarySynth = &fmSynth;
+
+/* wavetable drums on MCU, wavetable melodic on DSP */
+#elif defined(EAS_SPLIT_WT_SYNTH)
+const S_SYNTH_INTERFACE *const pPrimarySynth = &wtSynth;
+extern const S_FRAME_INTERFACE wtFrameInterface;
+const S_FRAME_INTERFACE *const pFrameInterface = &wtFrameInterface;
+
+/* wavetable drums on MCU, FM melodic on DSP */
+#elif defined(EAS_SPLIT_HYBRID_SYNTH)
+const S_SYNTH_INTERFACE *const pPrimarySynth = &wtSynth;
+const S_SYNTH_INTERFACE *const pSecondarySynth = &fmSynth;
+extern const S_FRAME_INTERFACE fmFrameInterface;
+const S_FRAME_INTERFACE *const pFrameInterface = &fmFrameInterface;
+
+/* FM on DSP */
+#elif defined(EAS_SPLIT_FM_SYNTH)
+const S_SYNTH_INTERFACE *const pPrimarySynth = &fmSynth;
+extern const S_FRAME_INTERFACE fmFrameInterface;
+const S_FRAME_INTERFACE *const pFrameInterface = &fmFrameInterface;
+
+#else
+#error "Undefined architecture option"
+#endif
+
+/*----------------------------------------------------------------------------
+ * inline functions
+ *----------------------------------------------------------------------------
+*/
+EAS_INLINE const S_REGION* GetRegionPtr (S_SYNTH *pSynth, EAS_U16 regionIndex)
+{
+#if defined(DLS_SYNTHESIZER)
+ if (regionIndex & FLAG_RGN_IDX_DLS_SYNTH)
+ return &pSynth->pDLS->pDLSRegions[regionIndex & REGION_INDEX_MASK].wtRegion.region;
+#endif
+#if defined(_HYBRID_SYNTH)
+ if (regionIndex & FLAG_RGN_IDX_FM_SYNTH)
+ return &pSynth->pEAS->pFMRegions[regionIndex & REGION_INDEX_MASK].region;
+ else
+ return &pSynth->pEAS->pWTRegions[regionIndex].region;
+#elif defined(_WT_SYNTH)
+ return &pSynth->pEAS->pWTRegions[regionIndex].region;
+#elif defined(_FM_SYNTH)
+ return &pSynth->pEAS->pFMRegions[regionIndex].region;
+#endif
+}
+
+/*lint -esym(715, voiceNum) used in some implementation */
+EAS_INLINE const S_SYNTH_INTERFACE* GetSynthPtr (EAS_INT voiceNum)
+{
+#if defined(_HYBRID_SYNTH)
+ if (voiceNum < NUM_PRIMARY_VOICES)
+ return pPrimarySynth;
+ else
+ return pSecondarySynth;
+#else
+ return pPrimarySynth;
+#endif
+}
+
+EAS_INLINE EAS_INT GetAdjustedVoiceNum (EAS_INT voiceNum)
+{
+#if defined(_HYBRID_SYNTH)
+ if (voiceNum >= NUM_PRIMARY_VOICES)
+ return voiceNum - NUM_PRIMARY_VOICES;
+#endif
+ return voiceNum;
+}
+
+EAS_INLINE EAS_U8 VSynthToChannel (S_SYNTH *pSynth, EAS_U8 channel)
+{
+ /*lint -e{734} synthNum is always 0-15 */
+ return channel | (pSynth->vSynthNum << 4);
+}
+
+/*----------------------------------------------------------------------------
+ * InitVoice()
+ *----------------------------------------------------------------------------
+ * Initialize a synthesizer voice
+ *----------------------------------------------------------------------------
+*/
+void InitVoice (S_SYNTH_VOICE *pVoice)
+{
+ pVoice->channel = UNASSIGNED_SYNTH_CHANNEL;
+ pVoice->nextChannel = UNASSIGNED_SYNTH_CHANNEL;
+ pVoice->note = pVoice->nextNote = DEFAULT_KEY_NUMBER;
+ pVoice->velocity = pVoice->nextVelocity = DEFAULT_VELOCITY;
+ pVoice->regionIndex = DEFAULT_REGION_INDEX;
+ pVoice->age = DEFAULT_AGE;
+ pVoice->voiceFlags = DEFAULT_VOICE_FLAGS;
+ pVoice->voiceState = DEFAULT_VOICE_STATE;
+}
+
+/*----------------------------------------------------------------------------
+ * IncVoicePoolCount()
+ *----------------------------------------------------------------------------
+ * Updates the voice pool count when a voice changes state
+ *----------------------------------------------------------------------------
+*/
+static void IncVoicePoolCount (S_VOICE_MGR *pVoiceMgr, S_SYNTH_VOICE *pVoice)
+{
+ S_SYNTH *pSynth;
+ EAS_INT pool;
+
+ /* ignore muting voices */
+ if (pVoice->voiceState == eVoiceStateMuting)
+ return;
+
+ if (pVoice->voiceState == eVoiceStateStolen)
+ {
+ pSynth = pVoiceMgr->pSynth[GET_VSYNTH(pVoice->nextChannel)];
+ pool = pSynth->channels[GET_CHANNEL(pVoice->nextChannel)].pool;
+ }
+ else
+ {
+ pSynth = pVoiceMgr->pSynth[GET_VSYNTH(pVoice->channel)];
+ pool = pSynth->channels[GET_CHANNEL(pVoice->channel)].pool;
+ }
+
+ pSynth->poolCount[pool]++;
+
+#ifdef _DEBUG_VM
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IncVoicePoolCount: Synth=%d pool=%d\n", pSynth->vSynthNum, pool); */ }
+#endif
+}
+
+/*----------------------------------------------------------------------------
+ * DecVoicePoolCount()
+ *----------------------------------------------------------------------------
+ * Updates the voice pool count when a voice changes state
+ *----------------------------------------------------------------------------
+*/
+static void DecVoicePoolCount (S_VOICE_MGR *pVoiceMgr, S_SYNTH_VOICE *pVoice)
+{
+ S_SYNTH *pSynth;
+ EAS_INT pool;
+
+ /* ignore muting voices */
+ if (pVoice->voiceState == eVoiceStateMuting)
+ return;
+
+ if (pVoice->voiceState == eVoiceStateStolen)
+ {
+ pSynth = pVoiceMgr->pSynth[GET_VSYNTH(pVoice->nextChannel)];
+ pool = pSynth->channels[GET_CHANNEL(pVoice->nextChannel)].pool;
+ }
+ else
+ {
+ pSynth = pVoiceMgr->pSynth[GET_VSYNTH(pVoice->channel)];
+ pool = pSynth->channels[GET_CHANNEL(pVoice->channel)].pool;
+ }
+
+ pSynth->poolCount[pool]--;
+
+#ifdef _DEBUG_VM
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "DecVoicePoolCount: Synth=%d pool=%d\n", pSynth->vSynthNum, pool); */ }
+#endif
+}
+
+/*----------------------------------------------------------------------------
+ * VMInitialize()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ *
+ * Inputs:
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT VMInitialize (S_EAS_DATA *pEASData)
+{
+ S_VOICE_MGR *pVoiceMgr;
+ EAS_INT i;
+
+ /* check Configuration Module for data allocation */
+ if (pEASData->staticMemoryModel)
+ pVoiceMgr = EAS_CMEnumData(EAS_CM_SYNTH_DATA);
+ else
+ pVoiceMgr = EAS_HWMalloc(pEASData->hwInstData, sizeof(S_VOICE_MGR));
+ if (!pVoiceMgr)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "VMInitialize: Failed to allocate synthesizer memory\n"); */ }
+ return EAS_ERROR_MALLOC_FAILED;
+ }
+ EAS_HWMemSet(pVoiceMgr, 0, sizeof(S_VOICE_MGR));
+
+ /* initialize non-zero variables */
+ pVoiceMgr->pGlobalEAS = (S_EAS*) &easSoundLib;
+ pVoiceMgr->maxPolyphony = (EAS_U16) MAX_SYNTH_VOICES;
+
+#if defined(_SECONDARY_SYNTH) || defined(EAS_SPLIT_WT_SYNTH)
+ pVoiceMgr->maxPolyphonyPrimary = NUM_PRIMARY_VOICES;
+ pVoiceMgr->maxPolyphonySecondary = NUM_SECONDARY_VOICES;
+#endif
+
+ /* set max workload to zero */
+ pVoiceMgr->maxWorkLoad = 0;
+
+ /* initialize the voice manager parameters */
+ for (i = 0; i < MAX_SYNTH_VOICES; i++)
+ InitVoice(&pVoiceMgr->voices[i]);
+
+ /* initialize the synth */
+ /*lint -e{522} return unused at this time */
+ pPrimarySynth->pfInitialize(pVoiceMgr);
+
+ /* initialize the off-chip synth */
+#ifdef _HYBRID_SYNTH
+ /*lint -e{522} return unused at this time */
+ pSecondarySynth->pfInitialize(pVoiceMgr);
+#endif
+
+ pEASData->pVoiceMgr = pVoiceMgr;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * VMInitMIDI()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ *
+ * Inputs:
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT VMInitMIDI (S_EAS_DATA *pEASData, S_SYNTH **ppSynth)
+{
+ EAS_RESULT result;
+ S_SYNTH *pSynth;
+ EAS_INT virtualSynthNum;
+
+ *ppSynth = NULL;
+
+ /* static memory model only allows one synth */
+ if (pEASData->staticMemoryModel)
+ {
+ if (pEASData->pVoiceMgr->pSynth[0] != NULL)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "VMInitMIDI: No virtual synthesizer support for static memory model\n"); */ }
+ return EAS_ERROR_NO_VIRTUAL_SYNTHESIZER;
+ }
+
+ /* check Configuration Module for data allocation */
+ pSynth = EAS_CMEnumData(EAS_CM_MIDI_DATA);
+ virtualSynthNum = 0;
+ }
+
+ /* dynamic memory model */
+ else
+ {
+ for (virtualSynthNum = 0; virtualSynthNum < MAX_VIRTUAL_SYNTHESIZERS; virtualSynthNum++)
+ if (pEASData->pVoiceMgr->pSynth[virtualSynthNum] == NULL)
+ break;
+ if (virtualSynthNum == MAX_VIRTUAL_SYNTHESIZERS)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "VMInitMIDI: Exceeded number of active virtual synthesizers"); */ }
+ return EAS_ERROR_NO_VIRTUAL_SYNTHESIZER;
+ }
+ pSynth = EAS_HWMalloc(pEASData->hwInstData, sizeof(S_SYNTH));
+ }
+
+ /* make sure we have a valid memory pointer */
+ if (pSynth == NULL)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "VMInitMIDI: Failed to allocate synthesizer memory\n"); */ }
+ return EAS_ERROR_MALLOC_FAILED;
+ }
+ EAS_HWMemSet(pSynth, 0, sizeof(S_SYNTH));
+
+ /* set the sound library pointer */
+ if ((result = VMSetEASLib(pSynth, pEASData->pVoiceMgr->pGlobalEAS)) != EAS_SUCCESS)
+ {
+ VMMIDIShutdown(pEASData, pSynth);
+ return result;
+ }
+
+ /* link in DLS bank if downloaded */
+#ifdef DLS_SYNTHESIZER
+ if (pEASData->pVoiceMgr->pGlobalDLS)
+ {
+ pSynth->pDLS = pEASData->pVoiceMgr->pGlobalDLS;
+ DLSAddRef(pSynth->pDLS);
+ }
+#endif
+
+ /* initialize MIDI state variables */
+ pSynth->synthFlags = DEFAULT_SYNTH_FLAGS;
+ pSynth->masterVolume = DEFAULT_SYNTH_MASTER_VOLUME;
+ pSynth->refCount = 1;
+ pSynth->priority = DEFAULT_SYNTH_PRIORITY;
+ pSynth->poolAlloc[0] = (EAS_U8) pEASData->pVoiceMgr->maxPolyphony;
+
+ VMInitializeAllChannels(pEASData->pVoiceMgr, pSynth);
+
+ pSynth->vSynthNum = (EAS_U8) virtualSynthNum;
+ pEASData->pVoiceMgr->pSynth[virtualSynthNum] = pSynth;
+
+ *ppSynth = pSynth;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * VMIncRefCount()
+ *----------------------------------------------------------------------------
+ * Increment reference count for virtual synth
+ *----------------------------------------------------------------------------
+*/
+void VMIncRefCount (S_SYNTH *pSynth)
+{
+ pSynth->refCount++;
+}
+
+/*----------------------------------------------------------------------------
+ * VMReset()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * We call this routine to start the process of reseting the synth.
+ * This routine sets a flag for the entire synth indicating that we want
+ * to reset.
+ * We also force all voices to mute quickly.
+ * However, we do not actually perform any synthesis in this routine. That
+ * is, we do not ramp the voices down from this routine, but instead, we
+ * let the "regular" synth processing steps take care of adding the ramp
+ * down samples to the output buffer. After we are sure that all voices
+ * have completed ramping down, we continue the process of resetting the
+ * synth (from another routine).
+ *
+ * Inputs:
+ * psEASData - pointer to overall EAS data structure
+ * force - force reset even if voices are active
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ * - set a flag (in psSynthObject->m_nFlags) indicating synth reset requested.
+ * - force all voices to update their envelope states to mute
+ *
+ *----------------------------------------------------------------------------
+*/
+void VMReset (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_BOOL force)
+{
+
+#ifdef _DEBUG_VM
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMReset: request to reset synth. Force = %d\n", force); */ }
+#endif
+
+ /* force voices to off state - may cause audio artifacts */
+ if (force)
+ {
+ pVoiceMgr->activeVoices -= pSynth->numActiveVoices;
+ pSynth->numActiveVoices = 0;
+ VMInitializeAllVoices(pVoiceMgr, pSynth->vSynthNum);
+ }
+ else
+ VMMuteAllVoices(pVoiceMgr, pSynth);
+
+ /* don't reset if voices are still playing */
+ if (pSynth->numActiveVoices == 0)
+ {
+ EAS_INT i;
+
+#ifdef _DEBUG_VM
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMReset: complete the reset process\n"); */ }
+#endif
+
+ VMInitializeAllChannels(pVoiceMgr, pSynth);
+ for (i = 0; i < NUM_SYNTH_CHANNELS; i++)
+ pSynth->poolCount[i] = 0;
+
+ /* set polyphony */
+ if (pSynth->maxPolyphony < pVoiceMgr->maxPolyphony)
+ pSynth->poolAlloc[0] = (EAS_U8) pVoiceMgr->maxPolyphony;
+ else
+ pSynth->poolAlloc[0] = (EAS_U8) pSynth->maxPolyphony;
+
+ /* clear reset flag */
+ pSynth->synthFlags &= ~SYNTH_FLAG_RESET_IS_REQUESTED;
+ }
+
+ /* handle reset after voices are muted */
+ else
+ pSynth->synthFlags |= SYNTH_FLAG_RESET_IS_REQUESTED;
+}
+
+/*----------------------------------------------------------------------------
+ * VMInitializeAllChannels()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ *
+ * Inputs:
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ *
+ *----------------------------------------------------------------------------
+*/
+void VMInitializeAllChannels (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth)
+{
+ S_SYNTH_CHANNEL *pChannel;
+ EAS_INT i;
+
+ VMResetControllers(pSynth);
+
+ /* init each channel */
+ pChannel = pSynth->channels;
+
+ for (i = 0; i < NUM_SYNTH_CHANNELS; i++, pChannel++)
+ {
+ pChannel->channelFlags = DEFAULT_CHANNEL_FLAGS;
+ pChannel->staticGain = DEFAULT_CHANNEL_STATIC_GAIN;
+ pChannel->staticPitch = DEFAULT_CHANNEL_STATIC_PITCH;
+ pChannel->pool = 0;
+
+ /* the drum channel needs a different init */
+ if (i == DEFAULT_DRUM_CHANNEL)
+ {
+ pChannel->bankNum = DEFAULT_RHYTHM_BANK_NUMBER;
+ pChannel->channelFlags |= CHANNEL_FLAG_RHYTHM_CHANNEL;
+ }
+ else
+ pChannel->bankNum = DEFAULT_MELODY_BANK_NUMBER;
+
+ VMProgramChange(pVoiceMgr, pSynth, (EAS_U8) i, DEFAULT_SYNTH_PROGRAM_NUMBER);
+ }
+
+}
+
+/*----------------------------------------------------------------------------
+ * VMResetControllers()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ *
+ * Inputs:
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ *
+ *----------------------------------------------------------------------------
+*/
+void VMResetControllers (S_SYNTH *pSynth)
+{
+ S_SYNTH_CHANNEL *pChannel;
+ EAS_INT i;
+
+ pChannel = pSynth->channels;
+
+ for (i = 0; i < NUM_SYNTH_CHANNELS; i++, pChannel++)
+ {
+ pChannel->pitchBend = DEFAULT_PITCH_BEND;
+ pChannel->modWheel = DEFAULT_MOD_WHEEL;
+ pChannel->volume = DEFAULT_CHANNEL_VOLUME;
+ pChannel->pan = DEFAULT_PAN;
+ pChannel->expression = DEFAULT_EXPRESSION;
+
+#ifdef _REVERB
+ pSynth->channels[i].reverbSend = DEFAULT_REVERB_SEND;
+#endif
+
+#ifdef _CHORUS
+ pSynth->channels[i].chorusSend = DEFAULT_CHORUS_SEND;
+#endif
+
+ pChannel->channelPressure = DEFAULT_CHANNEL_PRESSURE;
+ pChannel->registeredParam = DEFAULT_REGISTERED_PARAM;
+ pChannel->pitchBendSensitivity = DEFAULT_PITCH_BEND_SENSITIVITY;
+ pChannel->finePitch = DEFAULT_FINE_PITCH;
+ pChannel->coarsePitch = DEFAULT_COARSE_PITCH;
+
+ /* update all voices on this channel */
+ pChannel->channelFlags |= CHANNEL_FLAG_UPDATE_CHANNEL_PARAMETERS;
+ }
+}
+
+/*----------------------------------------------------------------------------
+ * VMInitializeAllVoices()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ *
+ * Inputs:
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ *
+ *----------------------------------------------------------------------------
+*/
+void VMInitializeAllVoices (S_VOICE_MGR *pVoiceMgr, EAS_INT vSynthNum)
+{
+ EAS_INT i;
+
+ /* initialize the voice manager parameters */
+ for (i = 0; i < MAX_SYNTH_VOICES; i++)
+ {
+ if (pVoiceMgr->voices[i].voiceState != eVoiceStateStolen)
+ {
+ if (GET_VSYNTH(pVoiceMgr->voices[i].channel) == vSynthNum)
+ InitVoice(&pVoiceMgr->voices[i]);
+ }
+ else
+ {
+ if (GET_VSYNTH(pVoiceMgr->voices[i].nextChannel) == vSynthNum)
+ InitVoice(&pVoiceMgr->voices[i]);
+ }
+ }
+}
+
+/*----------------------------------------------------------------------------
+ * VMMuteVoice()
+ *----------------------------------------------------------------------------
+ * Mute the selected voice
+ *----------------------------------------------------------------------------
+*/
+void VMMuteVoice (S_VOICE_MGR *pVoiceMgr, EAS_I32 voiceNum)
+{
+ S_SYNTH *pSynth;
+ S_SYNTH_VOICE *pVoice;
+
+ /* take no action if voice is already muted */
+ pVoice = &pVoiceMgr->voices[voiceNum];
+ if ((pVoice->voiceState == eVoiceStateMuting) || (pVoice->voiceState == eVoiceStateFree))
+ return;
+
+ /* one less voice in pool */
+ DecVoicePoolCount(pVoiceMgr, pVoice);
+
+ pSynth = pVoiceMgr->pSynth[GET_VSYNTH(pVoice->channel)];
+ GetSynthPtr(voiceNum)->pfMuteVoice(pVoiceMgr, pSynth, pVoice, GetAdjustedVoiceNum(voiceNum));
+ pVoice->voiceState = eVoiceStateMuting;
+
+}
+
+/*----------------------------------------------------------------------------
+ * VMReleaseVoice()
+ *----------------------------------------------------------------------------
+ * Release the selected voice
+ *----------------------------------------------------------------------------
+*/
+void VMReleaseVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_I32 voiceNum)
+{
+ S_SYNTH_VOICE *pVoice = &pVoiceMgr->voices[voiceNum];
+
+ /* take no action if voice is already free, muting, or releasing */
+ if (( pVoice->voiceState == eVoiceStateMuting) ||
+ (pVoice->voiceState == eVoiceStateFree) ||
+ (pVoice->voiceState == eVoiceStateRelease))
+ return;
+
+ /* stolen voices should just be muted */
+ if (pVoice->voiceState == eVoiceStateStolen)
+ VMMuteVoice(pVoiceMgr, voiceNum);
+
+ /* release this voice */
+ GetSynthPtr(voiceNum)->pfReleaseVoice(pVoiceMgr, pSynth, &pVoiceMgr->voices[voiceNum], GetAdjustedVoiceNum(voiceNum));
+ pVoice->voiceState = eVoiceStateRelease;
+}
+
+/*----------------------------------------------------------------------------
+ * VMInitMIPTable()
+ *----------------------------------------------------------------------------
+ * Initialize the SP-MIDI MIP table in preparation for receiving MIP message
+ *----------------------------------------------------------------------------
+*/
+void VMInitMIPTable (S_SYNTH *pSynth)
+{
+ EAS_INT i;
+
+#ifdef _DEBUG_VM
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMInitMIPTable\n"); */ }
+#endif
+
+ /* clear SP-MIDI flag */
+ pSynth->synthFlags &= ~SYNTH_FLAG_SP_MIDI_ON;
+ for (i = 0; i < NUM_SYNTH_CHANNELS; i++)
+ {
+ pSynth->channels[i].pool = 0;
+ pSynth->channels[i].mip = 0;
+ }
+}
+
+/*----------------------------------------------------------------------------
+ * VMSetMIPEntry()
+ *----------------------------------------------------------------------------
+ * Sets the priority and MIP level for a MIDI channel
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pVoiceMgr) reserved for future use */
+void VMSetMIPEntry (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel, EAS_U8 priority, EAS_U8 mip)
+{
+
+#ifdef _DEBUG_VM
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMSetMIPEntry: channel=%d, priority=%d, MIP=%d\n", channel, priority, mip); */ }
+#endif
+
+ /* save data for use by MIP message processing */
+ if (priority < NUM_SYNTH_CHANNELS)
+ {
+ pSynth->channels[channel].pool = priority;
+ pSynth->channels[channel].mip = mip;
+ }
+}
+
+/*----------------------------------------------------------------------------
+ * VMMIPUpdateChannelMuting()
+ *----------------------------------------------------------------------------
+ * This routine is called after an SP-MIDI message is received and
+ * any time the allocated polyphony changes. It mutes or unmutes
+ * channels based on polyphony.
+ *----------------------------------------------------------------------------
+*/
+void VMMIPUpdateChannelMuting (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth)
+{
+ EAS_INT i;
+ EAS_INT maxPolyphony;
+ EAS_INT channel;
+ EAS_INT vSynthNum;
+ EAS_INT pool;
+
+#ifdef _DEBUG_VM
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMUpdateMIPTable\n"); */ }
+#endif
+
+ /* determine max polyphony */
+ if (pSynth->maxPolyphony)
+ maxPolyphony = pSynth->maxPolyphony;
+ else
+ maxPolyphony = pVoiceMgr->maxPolyphony;
+
+ /* process channels */
+ for (i = 0; i < NUM_SYNTH_CHANNELS; i++)
+ {
+
+ /* channel must be in MIP message and must meet allocation target */
+ if ((pSynth->channels[i].mip != 0) && (pSynth->channels[i].mip <= maxPolyphony))
+ pSynth->channels[i].channelFlags &= ~CHANNEL_FLAG_MUTE;
+ else
+ pSynth->channels[i].channelFlags |= CHANNEL_FLAG_MUTE;
+
+ /* reset voice pool count */
+ pSynth->poolCount[i] = 0;
+ }
+
+ /* mute any voices on muted channels, and count unmuted voices */
+ for (i = 0; i < MAX_SYNTH_VOICES; i++)
+ {
+
+ /* ignore free voices */
+ if (pVoiceMgr->voices[i].voiceState == eVoiceStateFree)
+ continue;
+
+ /* get channel and virtual synth */
+ if (pVoiceMgr->voices[i].voiceState != eVoiceStateStolen)
+ {
+ vSynthNum = GET_VSYNTH(pVoiceMgr->voices[i].channel);
+ channel = GET_CHANNEL(pVoiceMgr->voices[i].channel);
+ }
+ else
+ {
+ vSynthNum = GET_VSYNTH(pVoiceMgr->voices[i].nextChannel);
+ channel = GET_CHANNEL(pVoiceMgr->voices[i].nextChannel);
+ }
+
+ /* ignore voices on other synths */
+ if (vSynthNum != pSynth->vSynthNum)
+ continue;
+
+ /* count voices */
+ pool = pSynth->channels[channel].pool;
+
+ /* deal with muted channels */
+ if (pSynth->channels[channel].channelFlags & CHANNEL_FLAG_MUTE)
+ {
+ /* mute stolen voices scheduled to play on this channel */
+ if (pVoiceMgr->voices[i].voiceState == eVoiceStateStolen)
+ pVoiceMgr->voices[i].voiceState = eVoiceStateMuting;
+
+ /* release voices that aren't already muting */
+ else if (pVoiceMgr->voices[i].voiceState != eVoiceStateMuting)
+ {
+ VMReleaseVoice(pVoiceMgr, pSynth, i);
+ pSynth->poolCount[pool]++;
+ }
+ }
+
+ /* not muted, count this voice */
+ else
+ pSynth->poolCount[pool]++;
+ }
+}
+
+/*----------------------------------------------------------------------------
+ * VMUpdateMIPTable()
+ *----------------------------------------------------------------------------
+ * This routine is called at the end of the SysEx message to allow
+ * the Voice Manager to complete the initialization of the MIP
+ * table. It assigns channels to the appropriate voice pool based
+ * on the MIP setting and calculates the voices allocated for each
+ * pool.
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pVoiceMgr) reserved for future use */
+void VMUpdateMIPTable (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth)
+{
+ S_SYNTH_CHANNEL *pChannel;
+ EAS_INT i;
+ EAS_INT currentMIP;
+ EAS_INT currentPool;
+ EAS_INT priority[NUM_SYNTH_CHANNELS];
+
+#ifdef _DEBUG_VM
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMUpdateMIPTable\n"); */ }
+#endif
+
+ /* set SP-MIDI flag */
+ pSynth->synthFlags |= SYNTH_FLAG_SP_MIDI_ON;
+
+ /* sort channels into priority order */
+ for (i = 0; i < NUM_SYNTH_CHANNELS; i++)
+ priority[i] = -1;
+ for (i = 0; i < NUM_SYNTH_CHANNELS; i++)
+ {
+ if (pSynth->channels[i].pool != DEFAULT_SP_MIDI_PRIORITY)
+ priority[pSynth->channels[i].pool] = i;
+ }
+
+ /* process channels in priority order */
+ currentMIP = 0;
+ currentPool = -1;
+ for (i = 0; i < NUM_SYNTH_CHANNELS; i++)
+ {
+ /* stop when we run out of channels */
+ if (priority[i] == -1)
+ break;
+
+ pChannel = &pSynth->channels[priority[i]];
+
+ /* when 2 or more channels have the same MIP setting, they
+ * share a common voice pool
+ */
+ if (pChannel->mip == currentMIP)
+ pChannel->pool = (EAS_U8) currentPool;
+
+ /* new voice pool */
+ else
+ {
+ currentPool++;
+ pSynth->poolAlloc[currentPool] = (EAS_U8) (pChannel->mip - currentMIP);
+ currentMIP = pChannel->mip;
+ }
+ }
+
+ /* set SP-MIDI flag */
+ pSynth->synthFlags |= SYNTH_FLAG_SP_MIDI_ON;
+
+ /* update channel muting */
+ VMMIPUpdateChannelMuting (pVoiceMgr, pSynth);
+}
+
+/*----------------------------------------------------------------------------
+ * VMMuteAllVoices()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * We call this in an emergency reset situation.
+ * This forces all voices to mute quickly.
+ *
+ * Inputs:
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ * - forces all voices to update their envelope states to mute
+ *
+ *----------------------------------------------------------------------------
+*/
+void VMMuteAllVoices (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth)
+{
+ EAS_INT i;
+
+#ifdef _DEBUG_VM
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMMuteAllVoices: about to mute all voices!!\n"); */ }
+#endif
+
+ for (i = 0; i < MAX_SYNTH_VOICES; i++)
+ {
+ /* for stolen voices, check new channel */
+ if (pVoiceMgr->voices[i].voiceState == eVoiceStateStolen)
+ {
+ if (GET_VSYNTH(pVoiceMgr->voices[i].nextChannel) == pSynth->vSynthNum)
+ VMMuteVoice(pVoiceMgr, i);
+ }
+
+ else if (pSynth->vSynthNum == GET_VSYNTH(pVoiceMgr->voices[i].channel))
+ VMMuteVoice(pVoiceMgr, i);
+ }
+}
+
+/*----------------------------------------------------------------------------
+ * VMReleaseAllVoices()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * We call this after we've encountered the end of the Midi file.
+ * This ensures all voices are either in release (because we received their
+ * note off already) or forces them to mute quickly.
+ * We use this as a safety to prevent bad midi files from playing forever.
+ *
+ * Inputs:
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ * - forces all voices to update their envelope states to release or mute
+ *
+ *----------------------------------------------------------------------------
+*/
+void VMReleaseAllVoices (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth)
+{
+ EAS_INT i;
+
+ /* release sustain pedal on all channels */
+ for (i = 0; i < NUM_SYNTH_CHANNELS; i++)
+ {
+ if (pSynth->channels[ i ].channelFlags & CHANNEL_FLAG_SUSTAIN_PEDAL)
+ {
+ VMReleaseAllDeferredNoteOffs(pVoiceMgr, pSynth, (EAS_U8) i);
+ pSynth->channels[i].channelFlags &= ~CHANNEL_FLAG_SUSTAIN_PEDAL;
+ }
+ }
+
+ /* release all voices */
+ for (i = 0; i < MAX_SYNTH_VOICES; i++)
+ {
+
+ switch (pVoiceMgr->voices[i].voiceState)
+ {
+ case eVoiceStateStart:
+ case eVoiceStatePlay:
+ /* only release voices on this synth */
+ if (GET_VSYNTH(pVoiceMgr->voices[i].channel) == pSynth->vSynthNum)
+ VMReleaseVoice(pVoiceMgr, pSynth, i);
+ break;
+
+ case eVoiceStateStolen:
+ if (GET_VSYNTH(pVoiceMgr->voices[i].nextChannel) == pSynth->vSynthNum)
+ VMMuteVoice(pVoiceMgr, i);
+ break;
+
+ case eVoiceStateFree:
+ case eVoiceStateRelease:
+ case eVoiceStateMuting:
+ break;
+
+ case eVoiceStateInvalid:
+ default:
+#ifdef _DEBUG_VM
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMReleaseAllVoices: error, %d is an unrecognized state\n",
+ pVoiceMgr->voices[i].voiceState); */ }
+#endif
+ break;
+ }
+ }
+}
+
+/*----------------------------------------------------------------------------
+ * VMAllNotesOff()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Quickly mute all notes on the given channel.
+ *
+ * Inputs:
+ * nChannel - quickly turn off all notes on this channel
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ * - forces all voices on this channel to update their envelope states to mute
+ *
+ *----------------------------------------------------------------------------
+*/
+void VMAllNotesOff (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel)
+{
+ EAS_INT voiceNum;
+ S_SYNTH_VOICE *pVoice;
+
+#ifdef _DEBUG_VM
+ if (channel >= NUM_SYNTH_CHANNELS)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMAllNotesOff: error, %d invalid channel number\n",
+ channel); */ }
+ return;
+ }
+#endif
+
+ /* increment workload */
+ pVoiceMgr->workload += WORKLOAD_AMOUNT_SMALL_INCREMENT;
+
+ /* check each voice */
+ channel = VSynthToChannel(pSynth, channel);
+ for (voiceNum = 0; voiceNum < MAX_SYNTH_VOICES; voiceNum++)
+ {
+ pVoice = &pVoiceMgr->voices[voiceNum];
+ if (pVoice->voiceState != eVoiceStateFree)
+ {
+ if (((pVoice->voiceState != eVoiceStateStolen) && (channel == pVoice->channel)) ||
+ ((pVoice->voiceState == eVoiceStateStolen) && (channel == pVoice->nextChannel)))
+ {
+ /* this voice is assigned to the requested channel */
+ GetSynthPtr(voiceNum)->pfMuteVoice(pVoiceMgr, pSynth, pVoice, GetAdjustedVoiceNum(voiceNum));
+ pVoice->voiceState = eVoiceStateMuting;
+ }
+ }
+ }
+}
+
+/*----------------------------------------------------------------------------
+ * VMDeferredStopNote()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Stop the notes that had deferred note-off requests.
+ *
+ * Inputs:
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ * None.
+ *
+ * Side Effects:
+ * voices that have had deferred note-off requests are now put into release
+ * psSynthObject->m_sVoice[i].m_nFlags has the VOICE_FLAG_DEFER_MIDI_NOTE_OFF
+ * cleared
+ *----------------------------------------------------------------------------
+*/
+void VMDeferredStopNote (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth)
+{
+ EAS_INT voiceNum;
+ EAS_INT channel;
+ EAS_BOOL deferredNoteOff;
+
+ deferredNoteOff = EAS_FALSE;
+
+ /* check each voice to see if it requires a deferred note off */
+ for (voiceNum=0; voiceNum < MAX_SYNTH_VOICES; voiceNum++)
+ {
+ if (pVoiceMgr->voices[voiceNum].voiceFlags & VOICE_FLAG_DEFER_MIDI_NOTE_OFF)
+ {
+ /* check if this voice was stolen */
+ if (pVoiceMgr->voices[voiceNum].voiceState == eVoiceStateStolen)
+ {
+ /*
+ This voice was stolen, AND it also has a deferred note-off.
+ The stolen note must be completely ramped down at this point.
+ The note that caused the stealing to occur, however, must
+ have received a note-off request before the note that caused
+ stealing ever had a chance to even start. We want to give
+ the note that caused the stealing a chance to play, so we
+ start it on the next update interval, and we defer sending
+ the note-off request until the subsequent update interval.
+ So do not send the note-off request for this voice because
+ this voice was stolen and should have completed ramping down,
+ Also, do not clear the global flag nor this voice's flag
+ because we must indicate that the subsequent update interval,
+ after the note that caused stealing has started, should
+ then send the deferred note-off request.
+ */
+ deferredNoteOff = EAS_TRUE;
+
+#ifdef _DEBUG_VM
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMDeferredStopNote: defer request to stop voice %d (channel=%d note=%d) - voice not started\n",
+ voiceNum,
+ pVoiceMgr->voices[voiceNum].nextChannel,
+ pVoiceMgr->voices[voiceNum].note); */ }
+
+ /* sanity check: this stolen voice better be ramped to zero */
+ if (0 != pVoiceMgr->voices[voiceNum].gain)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMDeferredStopNote: warning, this voice did not complete its ramp to zero\n"); */ }
+ }
+#endif // #ifdef _DEBUG_VM
+
+ }
+ else
+ {
+ /* clear the flag using exor */
+ pVoiceMgr->voices[voiceNum].voiceFlags ^=
+ VOICE_FLAG_DEFER_MIDI_NOTE_OFF;
+
+#ifdef _DEBUG_VM
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMDeferredStopNote: Stop voice %d (channel=%d note=%d)\n",
+ voiceNum,
+ pVoiceMgr->voices[voiceNum].nextChannel,
+ pVoiceMgr->voices[voiceNum].note); */ }
+#endif
+
+ channel = pVoiceMgr->voices[voiceNum].channel & 15;
+
+ /* check if sustain pedal is on */
+ if (pSynth->channels[channel].channelFlags & CHANNEL_FLAG_SUSTAIN_PEDAL)
+ {
+ GetSynthPtr(voiceNum)->pfSustainPedal(pVoiceMgr, pSynth, &pVoiceMgr->voices[voiceNum], &pSynth->channels[channel], GetAdjustedVoiceNum(voiceNum));
+ }
+
+ /* release this voice */
+ else
+ VMReleaseVoice(pVoiceMgr, pSynth, voiceNum);
+
+ }
+
+ }
+
+ }
+
+ /* clear the deferred note-off flag, unless there's another one pending */
+ if (deferredNoteOff == EAS_FALSE)
+ pSynth->synthFlags ^= SYNTH_FLAG_DEFERRED_MIDI_NOTE_OFF_PENDING;
+}
+
+/*----------------------------------------------------------------------------
+ * VMReleaseAllDeferredNoteOffs()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Call this functin when the sustain flag is presently set but
+ * we are now transitioning from damper pedal on to
+ * damper pedal off. This means all notes in this channel
+ * that received a note off while the damper pedal was on, and
+ * had their note-off requests deferred, should now proceed to
+ * the release state.
+ *
+ * Inputs:
+ * nChannel - this channel has its sustain pedal transitioning from on to off
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ * Side Effects:
+ * any voice with deferred note offs on this channel are updated such that
+ * pVoice->m_sEG1.m_eState = eEnvelopeStateRelease
+ * pVoice->m_sEG1.m_nIncrement = release increment
+ * pVoice->m_nFlags = clear the deferred note off flag
+ *----------------------------------------------------------------------------
+*/
+void VMReleaseAllDeferredNoteOffs (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel)
+{
+ S_SYNTH_VOICE *pVoice;
+ EAS_INT voiceNum;
+
+#ifdef _DEBUG_VM
+ if (channel >= NUM_SYNTH_CHANNELS)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMReleaseAllDeferredNoteOffs: error, %d invalid channel number\n",
+ channel); */ }
+ return;
+ }
+#endif /* #ifdef _DEBUG_VM */
+
+ /* increment workload */
+ pVoiceMgr->workload += WORKLOAD_AMOUNT_SMALL_INCREMENT;
+
+ /* find all the voices assigned to this channel */
+ channel = VSynthToChannel(pSynth, channel);
+ for (voiceNum = 0; voiceNum < MAX_SYNTH_VOICES; voiceNum++)
+ {
+
+ pVoice = &pVoiceMgr->voices[voiceNum];
+ if (channel == pVoice->channel)
+ {
+
+ /* does this voice have a deferred note off? */
+ if (pVoice->voiceFlags & VOICE_FLAG_SUSTAIN_PEDAL_DEFER_NOTE_OFF)
+ {
+ /* release voice */
+ VMReleaseVoice(pVoiceMgr, pSynth, voiceNum);
+
+ /* use exor to flip bit, clear the flag */
+ pVoice->voiceFlags &= ~VOICE_FLAG_SUSTAIN_PEDAL_DEFER_NOTE_OFF;
+
+ }
+
+ }
+ }
+
+ return;
+}
+
+/*----------------------------------------------------------------------------
+ * VMCatchNotesForSustainPedal()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Call this function when the sustain flag is presently clear and
+ * the damper pedal is off and we are transitioning from damper pedal OFF to
+ * damper pedal ON. Currently sounding notes should be left
+ * unchanged. However, we should try to "catch" notes if possible.
+ * If any notes are in release and have levels >= sustain level, catch them,
+ * otherwise, let them continue to release.
+ *
+ * Inputs:
+ * nChannel - this channel has its sustain pedal transitioning from on to off
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ *----------------------------------------------------------------------------
+*/
+void VMCatchNotesForSustainPedal (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel)
+{
+ EAS_INT voiceNum;
+
+#ifdef _DEBUG_VM
+ if (channel >= NUM_SYNTH_CHANNELS)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMCatchNotesForSustainPedal: error, %d invalid channel number\n",
+ channel); */ }
+ return;
+ }
+#endif
+
+ pVoiceMgr->workload += WORKLOAD_AMOUNT_SMALL_INCREMENT;
+ channel = VSynthToChannel(pSynth, channel);
+
+ /* find all the voices assigned to this channel */
+ for (voiceNum = 0; voiceNum < MAX_SYNTH_VOICES; voiceNum++)
+ {
+ if (channel == pVoiceMgr->voices[voiceNum].channel)
+ {
+ if (eVoiceStateRelease == pVoiceMgr->voices[voiceNum].voiceState)
+ GetSynthPtr(voiceNum)->pfSustainPedal(pVoiceMgr, pSynth, &pVoiceMgr->voices[voiceNum], &pSynth->channels[channel], GetAdjustedVoiceNum(voiceNum));
+ }
+ }
+}
+
+/*----------------------------------------------------------------------------
+ * VMUpdateAllNotesAge()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Increment the note age for all of the active voices.
+ *
+ * Inputs:
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ * m_nAge for all voices is incremented
+ *----------------------------------------------------------------------------
+*/
+void VMUpdateAllNotesAge (S_VOICE_MGR *pVoiceMgr, EAS_U16 age)
+{
+ EAS_INT i;
+
+ for (i = 0; i < MAX_SYNTH_VOICES; i++)
+ {
+ if (age - pVoiceMgr->voices[i].age > 0)
+ pVoiceMgr->voices[i].age++;
+ }
+}
+
+/*----------------------------------------------------------------------------
+ * VMStolenVoice()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * The selected voice is being stolen. Sets the parameters so that the
+ * voice will begin playing the new sound on the next buffer.
+ *
+ * Inputs:
+ * pVoice - pointer to voice to steal
+ * nChannel - the channel to start a note on
+ * nKeyNumber - the key number to start a note for
+ * nNoteVelocity - the key velocity from this note
+ *
+ * Outputs:
+ * None
+ *----------------------------------------------------------------------------
+*/
+static void VMStolenVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_I32 voiceNum, EAS_U8 channel, EAS_U8 note, EAS_U8 velocity, EAS_U16 regionIndex)
+{
+ S_SYNTH_VOICE *pVoice = &pVoiceMgr->voices[voiceNum];
+
+ /* one less voice in old pool */
+ DecVoicePoolCount(pVoiceMgr, pVoice);
+
+ /* mute the sound that is currently playing */
+ GetSynthPtr(voiceNum)->pfMuteVoice(pVoiceMgr, pVoiceMgr->pSynth[GET_VSYNTH(pVoice->channel)], &pVoiceMgr->voices[voiceNum], GetAdjustedVoiceNum(voiceNum));
+ pVoice->voiceState = eVoiceStateStolen;
+
+ /* set new note data */
+ pVoice->nextChannel = VSynthToChannel(pSynth, channel);
+ pVoice->nextNote = note;
+ pVoice->nextVelocity = velocity;
+ pVoice->nextRegionIndex = regionIndex;
+
+ /* one more voice in new pool */
+ IncVoicePoolCount(pVoiceMgr, pVoice);
+
+ /* clear the deferred flags */
+ pVoice->voiceFlags &=
+ ~(VOICE_FLAG_DEFER_MIDI_NOTE_OFF |
+ VOICE_FLAG_DEFER_MUTE |
+ VOICE_FLAG_SUSTAIN_PEDAL_DEFER_NOTE_OFF);
+
+ /* all notes older than this one get "younger" */
+ VMUpdateAllNotesAge(pVoiceMgr, pVoice->age);
+
+ /* assign current age to this note and increment for the next note */
+ pVoice->age = pVoiceMgr->age++;
+}
+
+/*----------------------------------------------------------------------------
+ * VMFreeVoice()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * The selected voice is done playing and being returned to the
+ * pool of free voices
+ *
+ * Inputs:
+ * pVoice - pointer to voice to free
+ *
+ * Outputs:
+ * None
+ *----------------------------------------------------------------------------
+*/
+static void VMFreeVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice)
+{
+
+ /* do nothing if voice is already free */
+ if (pVoice->voiceState == eVoiceStateFree)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "VMFreeVoice: Attempt to free voice that is already free\n"); */ }
+ return;
+ }
+
+ /* if we jump directly to free without passing muting stage,
+ * we need to adjust the voice count */
+ DecVoicePoolCount(pVoiceMgr, pVoice);
+
+
+#ifdef _DEBUG_VM
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "VMFreeVoice: Synth=%d\n", pSynth->vSynthNum); */ }
+#endif
+
+ /* return to free voice pool */
+ pVoiceMgr->activeVoices--;
+ pSynth->numActiveVoices--;
+ InitVoice(pVoice);
+
+#ifdef _DEBUG_VM
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMFreeVoice: free voice %d\n", pVoice - pVoiceMgr->voices); */ }
+#endif
+
+ /* all notes older than this one get "younger" */
+ VMUpdateAllNotesAge(pVoiceMgr, pVoice->age);
+ }
+
+/*----------------------------------------------------------------------------
+ * VMRetargetStolenVoice()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * The selected voice has been stolen and needs to be initalized with
+ * the paramters of its new note.
+ *
+ * Inputs:
+ * pVoice - pointer to voice to retarget
+ *
+ * Outputs:
+ * None
+ *----------------------------------------------------------------------------
+*/
+static EAS_BOOL VMRetargetStolenVoice (S_VOICE_MGR *pVoiceMgr, EAS_I32 voiceNum)
+{
+ EAS_U8 flags;
+ S_SYNTH_CHANNEL *pMIDIChannel;
+ S_SYNTH_VOICE *pVoice;
+ S_SYNTH *pSynth;
+ S_SYNTH *pNextSynth;
+
+ /* establish some pointers */
+ pVoice = &pVoiceMgr->voices[voiceNum];
+ pSynth = pVoiceMgr->pSynth[GET_VSYNTH(pVoice->channel)];
+ pMIDIChannel = &pSynth->channels[pVoice->channel & 15];
+ pNextSynth = pVoiceMgr->pSynth[GET_VSYNTH(pVoice->nextChannel)];
+
+#ifdef _DEBUG_VM
+{ /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMRetargetStolenVoice: retargeting stolen voice %d on channel %d\n",
+ voiceNum, pVoice->channel); */ }
+
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "\to channel %d note: %d velocity: %d\n",
+ pVoice->nextChannel, pVoice->nextNote, pVoice->nextVelocity); */ }
+#endif
+
+ /* make sure new channel hasn't been muted by SP-MIDI since the voice was stolen */
+ if ((pSynth->synthFlags & SYNTH_FLAG_SP_MIDI_ON) &&
+ (pMIDIChannel->channelFlags & CHANNEL_FLAG_MUTE))
+ {
+ VMFreeVoice(pVoiceMgr, pSynth, &pVoiceMgr->voices[voiceNum]);
+ return EAS_FALSE;
+ }
+
+ /* if assigned to a new synth, correct the active voice count */
+ if (pVoice->channel != pVoice->nextChannel)
+ {
+#ifdef _DEBUG_VM
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMRetargetStolenVoice: Note assigned to different virtual synth, adjusting numActiveVoices\n"); */ }
+#endif
+ pSynth->numActiveVoices--;
+ pNextSynth->numActiveVoices++;
+ }
+
+ /* assign new channel number, and increase channel voice count */
+ pVoice->channel = pVoice->nextChannel;
+ pMIDIChannel = &pNextSynth->channels[pVoice->channel & 15];
+
+ /* assign other data */
+ pVoice->note = pVoice->nextNote;
+ pVoice->velocity = pVoice->nextVelocity;
+ pVoice->nextChannel = UNASSIGNED_SYNTH_CHANNEL;
+ pVoice->regionIndex = pVoice->nextRegionIndex;
+
+ /* save the flags, pfStartVoice() will clear them */
+ flags = pVoice->voiceFlags;
+
+ /* keep track of the note-start related workload */
+ pVoiceMgr->workload += WORKLOAD_AMOUNT_START_NOTE;
+
+ /* setup the voice parameters */
+ pVoice->voiceState = eVoiceStateStart;
+
+ /*lint -e{522} return not used at this time */
+ GetSynthPtr(voiceNum)->pfStartVoice(pVoiceMgr, pNextSynth, &pVoiceMgr->voices[voiceNum], GetAdjustedVoiceNum(voiceNum), pVoice->regionIndex);
+
+ /* did the new note already receive a MIDI note-off request? */
+ if (flags & VOICE_FLAG_DEFER_MIDI_NOTE_OFF)
+ {
+#ifdef _DEBUG_VM
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMRetargetVoice: stolen note note-off request deferred\n"); */ }
+#endif
+ pVoice->voiceFlags |= VOICE_FLAG_DEFER_MIDI_NOTE_OFF;
+ pNextSynth->synthFlags |= SYNTH_FLAG_DEFERRED_MIDI_NOTE_OFF_PENDING;
+ }
+
+ return EAS_TRUE;
+}
+
+/*----------------------------------------------------------------------------
+ * VMCheckKeyGroup()
+ *----------------------------------------------------------------------------
+ * If the note that we've been asked to start is in the same key group as
+ * any currently playing notes, then we must shut down the currently playing
+ * note in the same key group
+ *----------------------------------------------------------------------------
+*/
+void VMCheckKeyGroup (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U16 keyGroup, EAS_U8 channel)
+{
+ const S_REGION *pRegion;
+ EAS_INT voiceNum;
+
+ /* increment frame workload */
+ pVoiceMgr->workload += WORKLOAD_AMOUNT_KEY_GROUP;
+
+ /* need to check all voices in case this is a layered sound */
+ channel = VSynthToChannel(pSynth, channel);
+ for (voiceNum = 0; voiceNum < MAX_SYNTH_VOICES; voiceNum++)
+ {
+ if (pVoiceMgr->voices[voiceNum].voiceState != eVoiceStateStolen)
+ {
+ /* voice must be on the same channel */
+ if (channel == pVoiceMgr->voices[voiceNum].channel)
+ {
+ /* check key group */
+ pRegion = GetRegionPtr(pSynth, pVoiceMgr->voices[voiceNum].regionIndex);
+ if (keyGroup == (pRegion->keyGroupAndFlags & 0x0f00))
+ {
+#ifdef _DEBUG_VM
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMCheckKeyGroup: voice %d matches key group %d\n", voiceNum, keyGroup >> 8); */ }
+#endif
+
+ /* if this voice was just started, set it to mute on the next buffer */
+ if (pVoiceMgr->voices[voiceNum].voiceFlags & VOICE_FLAG_NO_SAMPLES_SYNTHESIZED_YET)
+ pVoiceMgr->voices[voiceNum].voiceFlags |= VOICE_FLAG_DEFER_MUTE;
+
+ /* mute immediately */
+ else
+ VMMuteVoice(pVoiceMgr, voiceNum);
+ }
+ }
+ }
+
+ /* for stolen voice, check new values */
+ else
+ {
+ /* voice must be on the same channel */
+ if (channel == pVoiceMgr->voices[voiceNum].nextChannel)
+ {
+ /* check key group */
+ pRegion = GetRegionPtr(pSynth, pVoiceMgr->voices[voiceNum].nextRegionIndex);
+ if (keyGroup == (pRegion->keyGroupAndFlags & 0x0f00))
+ {
+#ifdef _DEBUG_VM
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMCheckKeyGroup: voice %d matches key group %d\n", voiceNum, keyGroup >> 8); */ }
+#endif
+
+ /* if this voice was just started, set it to mute on the next buffer */
+ if (pVoiceMgr->voices[voiceNum].voiceFlags & VOICE_FLAG_NO_SAMPLES_SYNTHESIZED_YET)
+ pVoiceMgr->voices[voiceNum].voiceFlags |= VOICE_FLAG_DEFER_MUTE;
+
+ /* mute immediately */
+ else
+ VMMuteVoice(pVoiceMgr, voiceNum);
+ }
+ }
+
+ }
+ }
+}
+
+/*----------------------------------------------------------------------------
+ * VMCheckPolyphonyLimiting()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * We only play at most 2 of the same note on a MIDI channel.
+ * E.g., if we are asked to start note 36, and there are already two voices
+ * that are playing note 36, then we must steal the voice playing
+ * the oldest note 36 and use that stolen voice to play the new note 36.
+ *
+ * Inputs:
+ * nChannel - synth channel that wants to start a new note
+ * nKeyNumber - new note's midi note number
+ * nNoteVelocity - new note's velocity
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ * pbVoiceStealingRequired - flag: this routine sets true if we needed to
+ * steal a voice
+ * *
+ * Side Effects:
+ * psSynthObject->m_sVoice[free voice num].m_nKeyNumber may be assigned
+ * psSynthObject->m_sVoice[free voice num].m_nVelocity may be assigned
+ *----------------------------------------------------------------------------
+*/
+EAS_BOOL VMCheckPolyphonyLimiting (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel, EAS_U8 note, EAS_U8 velocity, EAS_U16 regionIndex, EAS_I32 lowVoice, EAS_I32 highVoice)
+{
+ EAS_INT voiceNum;
+ EAS_INT oldestVoiceNum;
+ EAS_INT numVoicesPlayingNote;
+ EAS_U16 age;
+ EAS_U16 oldestNoteAge;
+
+ pVoiceMgr->workload += WORKLOAD_AMOUNT_POLY_LIMIT;
+
+ numVoicesPlayingNote = 0;
+ oldestVoiceNum = MAX_SYNTH_VOICES;
+ oldestNoteAge = 0;
+ channel = VSynthToChannel(pSynth, channel);
+
+ /* examine each voice on this channel playing this note */
+ for (voiceNum = lowVoice; voiceNum <= highVoice; voiceNum++)
+ {
+ /* check stolen notes separately */
+ if (pVoiceMgr->voices[voiceNum].voiceState != eVoiceStateStolen)
+ {
+
+ /* same channel and note ? */
+ if ((channel == pVoiceMgr->voices[voiceNum].channel) && (note == pVoiceMgr->voices[voiceNum].note))
+ {
+ numVoicesPlayingNote++;
+ age = pVoiceMgr->age - pVoiceMgr->voices[voiceNum].age;
+
+ /* is this the oldest voice for this note? */
+ if (age >= oldestNoteAge)
+ {
+ oldestNoteAge = age;
+ oldestVoiceNum = voiceNum;
+ }
+ }
+ }
+
+ /* handle stolen voices */
+ else
+ {
+ /* same channel and note ? */
+ if ((channel == pVoiceMgr->voices[voiceNum].nextChannel) && (note == pVoiceMgr->voices[voiceNum].nextNote))
+ {
+ numVoicesPlayingNote++;
+ }
+ }
+ }
+
+ /* check to see if we exceeded poly limit */
+ if (numVoicesPlayingNote < DEFAULT_CHANNEL_POLYPHONY_LIMIT)
+ return EAS_FALSE;
+
+ /* make sure we have a voice to steal */
+ if (oldestVoiceNum != MAX_SYNTH_VOICES)
+ {
+#ifdef _DEBUG_VM
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMCheckPolyphonyLimiting: voice %d has the oldest note\n", oldestVoiceNum); */ }
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "VMCheckPolyphonyLimiting: polyphony limiting requires shutting down note %d \n", pVoiceMgr->voices[oldestVoiceNum].note); */ }
+#endif
+ VMStolenVoice(pVoiceMgr, pSynth, oldestVoiceNum, channel, note, velocity, regionIndex);
+ return EAS_TRUE;
+ }
+
+#ifdef _DEBUG_VM
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "VMCheckPolyphonyLimiting: No oldest voice to steal\n"); */ }
+#endif
+ return EAS_FALSE;
+}
+
+/*----------------------------------------------------------------------------
+ * VMStartVoice()
+ *----------------------------------------------------------------------------
+ * Starts a voice given a region index
+ *----------------------------------------------------------------------------
+*/
+void VMStartVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel, EAS_U8 note, EAS_U8 velocity, EAS_U16 regionIndex)
+{
+ const S_REGION *pRegion;
+ S_SYNTH_CHANNEL *pChannel;
+ EAS_INT voiceNum;
+ EAS_INT maxSynthPoly;
+ EAS_I32 lowVoice, highVoice;
+ EAS_U16 keyGroup;
+
+ pChannel = &pSynth->channels[channel];
+ pRegion = GetRegionPtr(pSynth, regionIndex);
+
+ /* select correct synth */
+#if defined(_SECONDARY_SYNTH) || defined(EAS_SPLIT_WT_SYNTH)
+ {
+#ifdef EAS_SPLIT_WT_SYNTH
+ if ((pRegion->keyGroupAndFlags & REGION_FLAG_OFF_CHIP) == 0)
+#else
+ if ((regionIndex & FLAG_RGN_IDX_FM_SYNTH) == 0)
+#endif
+ {
+ lowVoice = 0;
+ highVoice = NUM_PRIMARY_VOICES - 1;
+ }
+ else
+ {
+ lowVoice = NUM_PRIMARY_VOICES;
+ highVoice = MAX_SYNTH_VOICES - 1;
+ }
+ }
+#else
+ lowVoice = 0;
+ highVoice = MAX_SYNTH_VOICES - 1;
+#endif
+
+ /* keep track of the note-start related workload */
+ pVoiceMgr->workload+= WORKLOAD_AMOUNT_START_NOTE;
+
+ /* other voices in pool, check for key group and poly limiting */
+ if (pSynth->poolCount[pChannel->pool] != 0)
+ {
+
+ /* check for key group exclusivity */
+ keyGroup = pRegion->keyGroupAndFlags & 0x0f00;
+ if (keyGroup!= 0)
+ VMCheckKeyGroup(pVoiceMgr, pSynth, keyGroup, channel);
+
+ /* check polyphony limit and steal a voice if necessary */
+ if ((pRegion->keyGroupAndFlags & REGION_FLAG_NON_SELF_EXCLUSIVE) == 0)
+ {
+ if (VMCheckPolyphonyLimiting(pVoiceMgr, pSynth, channel, note, velocity, regionIndex, lowVoice, highVoice) == EAS_TRUE)
+ return;
+ }
+ }
+
+ /* check max poly allocation */
+ if ((pSynth->maxPolyphony == 0) || (pVoiceMgr->maxPolyphony < pSynth->maxPolyphony))
+ maxSynthPoly = pVoiceMgr->maxPolyphony;
+ else
+ maxSynthPoly = pSynth->maxPolyphony;
+
+ /* any free voices? */
+ if ((pVoiceMgr->activeVoices < pVoiceMgr->maxPolyphony) &&
+ (pSynth->numActiveVoices < maxSynthPoly) &&
+ (EAS_SUCCESS == VMFindAvailableVoice(pVoiceMgr, &voiceNum, lowVoice, highVoice)))
+ {
+ S_SYNTH_VOICE *pVoice = &pVoiceMgr->voices[voiceNum];
+
+#ifdef _DEBUG_VM
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "VMStartVoice: Synth=%d\n", pSynth->vSynthNum); */ }
+#endif
+
+ /* bump voice counts */
+ pVoiceMgr->activeVoices++;
+ pSynth->numActiveVoices++;
+
+#ifdef _DEBUG_VM
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMStartVoice: voice %d assigned to channel %d note %d velocity %d\n",
+ voiceNum, channel, note, velocity); */ }
+#endif
+
+ /* save parameters */
+ pVoiceMgr->voices[voiceNum].channel = VSynthToChannel(pSynth, channel);
+ pVoiceMgr->voices[voiceNum].note = note;
+ pVoiceMgr->voices[voiceNum].velocity = velocity;
+
+ /* establish note age for voice stealing */
+ pVoiceMgr->voices[voiceNum].age = pVoiceMgr->age++;
+
+ /* setup the synthesis parameters */
+ pVoiceMgr->voices[voiceNum].voiceState = eVoiceStateStart;
+
+ /* increment voice pool count */
+ IncVoicePoolCount(pVoiceMgr, pVoice);
+
+ /* start voice on correct synth */
+ /*lint -e{522} return not used at this time */
+ GetSynthPtr(voiceNum)->pfStartVoice(pVoiceMgr, pSynth, &pVoiceMgr->voices[voiceNum], GetAdjustedVoiceNum(voiceNum), regionIndex);
+ return;
+ }
+
+ /* no free voices, we have to steal one using appropriate algorithm */
+ if (VMStealVoice(pVoiceMgr, pSynth, &voiceNum, channel, note, lowVoice, highVoice) == EAS_SUCCESS)
+ VMStolenVoice(pVoiceMgr, pSynth, voiceNum, channel, note, velocity, regionIndex);
+
+#ifdef _DEBUG_VM
+ else
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMStartVoice: Could not steal a voice for channel %d note %d velocity %d\n",
+ channel, note, velocity); */ }
+ }
+#endif
+
+ return;
+}
+
+/*----------------------------------------------------------------------------
+ * VMStartNote()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Update the synth's state to play the requested note on the requested
+ * channel if possible.
+ *
+ * Inputs:
+ * nChannel - the channel to start a note on
+ * nKeyNumber - the key number to start a note for
+ * nNoteVelocity - the key velocity from this note
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ * Side Effects:
+ * psSynthObject->m_nNumActiveVoices may be incremented
+ * psSynthObject->m_sVoice[free voice num].m_nSynthChannel may be assigned
+ * psSynthObject->m_sVoice[free voice num].m_nKeyNumber is assigned
+ * psSynthObject->m_sVoice[free voice num].m_nVelocity is assigned
+ *----------------------------------------------------------------------------
+*/
+void VMStartNote (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel, EAS_U8 note, EAS_U8 velocity)
+{
+ S_SYNTH_CHANNEL *pChannel;
+ EAS_U16 regionIndex;
+ EAS_I16 adjustedNote;
+
+ /* bump note count */
+ pSynth->totalNoteCount++;
+
+ pChannel = &pSynth->channels[channel];
+
+ /* check channel mute */
+ if (pChannel->channelFlags & CHANNEL_FLAG_MUTE)
+ return;
+
+#ifdef EXTERNAL_AUDIO
+ /* pass event to external audio when requested */
+ if ((pChannel->channelFlags & CHANNEL_FLAG_EXTERNAL_AUDIO) && (pSynth->cbEventFunc != NULL))
+ {
+ S_EXT_AUDIO_EVENT event;
+ event.channel = channel;
+ event.note = note;
+ event.velocity = velocity;
+ event.noteOn = EAS_TRUE;
+ if (pSynth->cbEventFunc(pSynth->pExtAudioInstData, &event))
+ return;
+ }
+#endif
+
+ /* start search at first region */
+ regionIndex = pChannel->regionIndex;
+
+ /* handle transposition */
+ adjustedNote = note;
+ if (pChannel->channelFlags & CHANNEL_FLAG_RHYTHM_CHANNEL)
+ adjustedNote += pChannel->coarsePitch;
+ else
+ adjustedNote += pChannel->coarsePitch + pSynth->globalTranspose;
+
+ /* limit adjusted key number so it does not wraparound, over/underflow */
+ if (adjustedNote < 0)
+ {
+ adjustedNote = 0;
+ }
+ else if (adjustedNote > 127)
+ {
+ adjustedNote = 127;
+ }
+
+#if defined(DLS_SYNTHESIZER)
+ if (regionIndex & FLAG_RGN_IDX_DLS_SYNTH)
+ {
+ /* DLS voice */
+ for (;;)
+ {
+ /*lint -e{740,826} cast OK, we know this is actually a DLS region */
+ const S_DLS_REGION *pDLSRegion = (S_DLS_REGION*) GetRegionPtr(pSynth, regionIndex);
+
+ /* check key against this region's key and velocity range */
+ if (((adjustedNote >= pDLSRegion->wtRegion.region.rangeLow) && (adjustedNote <= pDLSRegion->wtRegion.region.rangeHigh)) &&
+ ((velocity >= pDLSRegion->velLow) && (velocity <= pDLSRegion->velHigh)))
+ {
+ VMStartVoice(pVoiceMgr, pSynth, channel, note, velocity, regionIndex);
+ }
+
+ /* last region in program? */
+ if (pDLSRegion->wtRegion.region.keyGroupAndFlags & REGION_FLAG_LAST_REGION)
+ break;
+
+ /* advance to next region */
+ regionIndex++;
+ }
+ }
+ else
+#endif
+
+ /* braces here for #if clause */
+ {
+ /* EAS voice */
+ for (;;)
+ {
+ const S_REGION *pRegion = GetRegionPtr(pSynth, regionIndex);
+
+ /* check key against this region's keyrange */
+ if ((adjustedNote >= pRegion->rangeLow) && (adjustedNote <= pRegion->rangeHigh))
+ {
+ VMStartVoice(pVoiceMgr, pSynth, channel, note, velocity, regionIndex);
+ break;
+ }
+
+ /* last region in program? */
+ if (pRegion->keyGroupAndFlags & REGION_FLAG_LAST_REGION)
+ break;
+
+ /* advance to next region */
+ regionIndex++;
+ }
+ }
+}
+
+/*----------------------------------------------------------------------------
+ * VMStopNote()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Update the synth's state to end the requested note on the requested
+ * channel.
+ *
+ * Inputs:
+ * nChannel - the channel to stop a note on
+ * nKeyNumber - the key number for this note off
+ * nNoteVelocity - the note-off velocity
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ * Side Effects:
+ * psSynthObject->m_sVoice[free voice num].m_nSynthChannel may be assigned
+ * psSynthObject->m_sVoice[free voice num].m_nKeyNumber is assigned
+ * psSynthObject->m_sVoice[free voice num].m_nVelocity is assigned
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, velocity) reserved for future use */
+void VMStopNote (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel, EAS_U8 note, EAS_U8 velocity)
+{
+ S_SYNTH_CHANNEL *pChannel;
+ EAS_INT voiceNum;
+
+ pChannel = &(pSynth->channels[channel]);
+
+#ifdef EXTERNAL_AUDIO
+ if ((pChannel->channelFlags & CHANNEL_FLAG_EXTERNAL_AUDIO) && (pSynth->cbEventFunc != NULL))
+ {
+ S_EXT_AUDIO_EVENT event;
+ event.channel = channel;
+ event.note = note;
+ event.velocity = velocity;
+ event.noteOn = EAS_FALSE;
+ if (pSynth->cbEventFunc(pSynth->pExtAudioInstData, &event))
+ return;
+ }
+#endif
+
+ /* keep track of the note-start workload */
+ pVoiceMgr->workload += WORKLOAD_AMOUNT_STOP_NOTE;
+
+ channel = VSynthToChannel(pSynth, channel);
+
+ for (voiceNum=0; voiceNum < MAX_SYNTH_VOICES; voiceNum++)
+ {
+
+ /* stolen notes are handled separately */
+ if (eVoiceStateStolen != pVoiceMgr->voices[voiceNum].voiceState)
+ {
+
+ /* channel and key number must match */
+ if ((channel == pVoiceMgr->voices[voiceNum].channel) && (note == pVoiceMgr->voices[voiceNum].note))
+ {
+#ifdef _DEBUG_VM
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMStopNote: voice %d channel %d note %d\n",
+ voiceNum, channel, note); */ }
+#endif
+
+ /* if sustain pedal is down, set deferred note-off flag */
+ if (pChannel->channelFlags & CHANNEL_FLAG_SUSTAIN_PEDAL)
+ {
+ pVoiceMgr->voices[voiceNum].voiceFlags |= VOICE_FLAG_SUSTAIN_PEDAL_DEFER_NOTE_OFF;
+ continue;
+ }
+
+ /* if this note just started, wait before we stop it */
+ if (pVoiceMgr->voices[voiceNum].voiceFlags & VOICE_FLAG_NO_SAMPLES_SYNTHESIZED_YET)
+ {
+#ifdef _DEBUG_VM
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "\tDeferred: Not started yet\n"); */ }
+#endif
+ pVoiceMgr->voices[voiceNum].voiceFlags |= VOICE_FLAG_DEFER_MIDI_NOTE_OFF;
+ pSynth->synthFlags |= SYNTH_FLAG_DEFERRED_MIDI_NOTE_OFF_PENDING;
+ }
+
+ /* release voice */
+ else
+ VMReleaseVoice(pVoiceMgr, pSynth, voiceNum);
+
+ }
+ }
+
+ /* process stolen notes, new channel and key number must match */
+ else if ((channel == pVoiceMgr->voices[voiceNum].nextChannel) && (note == pVoiceMgr->voices[voiceNum].nextNote))
+ {
+
+#ifdef _DEBUG_VM
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMStopNote: voice %d channel %d note %d\n\tDeferred: Stolen voice\n",
+ voiceNum, channel, note); */ }
+#endif
+ pVoiceMgr->voices[voiceNum].voiceFlags |= VOICE_FLAG_DEFER_MIDI_NOTE_OFF;
+ }
+ }
+}
+
+/*----------------------------------------------------------------------------
+ * VMFindAvailableVoice()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Find an available voice and return the voice number if available.
+ *
+ * Inputs:
+ * pnVoiceNumber - really an output, returns the voice number found
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ * success - if there is an available voice
+ * failure - otherwise
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT VMFindAvailableVoice (S_VOICE_MGR *pVoiceMgr, EAS_INT *pVoiceNumber, EAS_I32 lowVoice, EAS_I32 highVoice)
+{
+ EAS_INT voiceNum;
+
+ /* Check each voice to see if it has been assigned to a synth channel */
+ for (voiceNum = lowVoice; voiceNum <= highVoice; voiceNum++)
+ {
+ /* check if this voice has been assigned to a synth channel */
+ if ( pVoiceMgr->voices[voiceNum].voiceState == eVoiceStateFree)
+ {
+ *pVoiceNumber = voiceNum; /* this voice is available */
+ return EAS_SUCCESS;
+ }
+ }
+
+ /* if we reach here, we have not found a free voice */
+ *pVoiceNumber = UNASSIGNED_SYNTH_VOICE;
+
+#ifdef _DEBUG_VM
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMFindAvailableVoice: error, could not find an available voice\n"); */ }
+#endif
+ return EAS_FAILURE;
+}
+
+/*----------------------------------------------------------------------------
+ * VMStealVoice()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Steal a voice and return the voice number
+ *
+ * Stealing algorithm: steal the best choice with minimal work, taking into
+ * account SP-Midi channel priorities and polyphony allocation.
+ *
+ * In one pass through all the voices, figure out which voice to steal
+ * taking into account a number of different factors:
+ * Priority of the voice's MIDI channel
+ * Number of voices over the polyphony allocation for voice's MIDI channel
+ * Amplitude of the voice
+ * Note age
+ * Key velocity (for voices that haven't been started yet)
+ * If any matching notes are found
+ *
+ * Inputs:
+ * pnVoiceNumber - really an output, see below
+ * nChannel - the channel that this voice wants to be started on
+ * nKeyNumber - the key number for this new voice
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ * pnVoiceNumber - voice number of the voice that was stolen
+ * EAS_RESULT EAS_SUCCESS - always successful
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT VMStealVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_INT *pVoiceNumber, EAS_U8 channel, EAS_U8 note, EAS_I32 lowVoice, EAS_I32 highVoice)
+{
+ S_SYNTH_VOICE *pCurrVoice;
+ S_SYNTH *pCurrSynth;
+ EAS_INT voiceNum;
+ EAS_INT bestCandidate;
+ EAS_U8 currChannel;
+ EAS_U8 currNote;
+ EAS_I32 bestPriority;
+ EAS_I32 currentPriority;
+
+ /* determine which voice to steal */
+ bestPriority = 0;
+ bestCandidate = MAX_SYNTH_VOICES;
+
+ for (voiceNum = lowVoice; voiceNum <= highVoice; voiceNum++)
+ {
+ pCurrVoice = &pVoiceMgr->voices[voiceNum];
+
+ /* ignore free voices */
+ if (pCurrVoice->voiceState == eVoiceStateFree)
+ continue;
+
+ /* for stolen voices, use the new parameters, not the old */
+ if (pCurrVoice->voiceState == eVoiceStateStolen)
+ {
+ pCurrSynth = pVoiceMgr->pSynth[GET_VSYNTH(pCurrVoice->nextChannel)];
+ currChannel = pCurrVoice->nextChannel;
+ currNote = pCurrVoice->nextNote;
+ }
+ else
+ {
+ pCurrSynth = pVoiceMgr->pSynth[GET_VSYNTH(pCurrVoice->channel)];
+ currChannel = pCurrVoice->channel;
+ currNote = pCurrVoice->note;
+ }
+
+ /* ignore voices that are higher priority */
+ if (pSynth->priority > pCurrSynth->priority)
+ continue;
+#ifdef _DEBUG_VM
+// { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMStealVoice: New priority = %d exceeds old priority = %d\n", pSynth->priority, pCurrSynth->priority); */ }
+#endif
+
+ /* if voice is stolen or just started, reduce the likelihood it will be stolen */
+ if (( pCurrVoice->voiceState == eVoiceStateStolen) || (pCurrVoice->voiceFlags & VOICE_FLAG_NO_SAMPLES_SYNTHESIZED_YET))
+ {
+ currentPriority = 128 - pCurrVoice->nextVelocity;
+ }
+ else
+ {
+ /* compute the priority of this voice, higher means better for stealing */
+ /* use not age */
+ currentPriority = (EAS_I32) pCurrVoice->age << NOTE_AGE_STEAL_WEIGHT;
+
+ /* include note gain -higher gain is lower steal value */
+ /*lint -e{704} use shift for performance */
+ currentPriority += ((32768 >> (12 - NOTE_GAIN_STEAL_WEIGHT)) + 256) -
+ ((EAS_I32) pCurrVoice->gain >> (12 - NOTE_GAIN_STEAL_WEIGHT));
+ }
+
+ /* in SP-MIDI mode, include over poly allocation and channel priority */
+ if (pSynth->synthFlags & SYNTH_FLAG_SP_MIDI_ON)
+ {
+ S_SYNTH_CHANNEL *pChannel = &pCurrSynth->channels[GET_CHANNEL(currChannel)];
+ /*lint -e{701} use shift for performance */
+ if (pSynth->poolCount[pChannel->pool] >= pSynth->poolAlloc[pChannel->pool])
+ currentPriority += (pSynth->poolCount[pChannel->pool] -pSynth->poolAlloc[pChannel->pool] + 1) << CHANNEL_POLY_STEAL_WEIGHT;
+
+ /* include channel priority */
+ currentPriority += (EAS_I32)(pChannel->pool << CHANNEL_PRIORITY_STEAL_WEIGHT);
+ }
+
+ /* if a note is already playing that matches this note, consider stealing it more readily */
+ if ((note == currNote) && (channel == currChannel))
+ currentPriority += NOTE_MATCH_PENALTY;
+
+ /* is this the best choice so far? */
+ if (currentPriority >= bestPriority)
+ {
+ bestPriority = currentPriority;
+ bestCandidate = voiceNum;
+ }
+ }
+
+ /* may happen if all voices are allocated to a higher priority virtual synth */
+ if (bestCandidate == MAX_SYNTH_VOICES)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMStealVoice: Unable to allocate a voice\n"); */ }
+ return EAS_ERROR_NO_VOICE_ALLOCATED;
+ }
+
+#ifdef _DEBUG_VM
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMStealVoice: Voice %d stolen\n", bestCandidate); */ }
+
+ /* are we stealing a stolen voice? */
+ if (pVoiceMgr->voices[bestCandidate].voiceState == eVoiceStateStolen)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "VMStealVoice: Voice %d is already marked as stolen and was scheduled to play ch: %d note: %d vel: %d\n",
+ bestCandidate,
+ pVoiceMgr->voices[bestCandidate].nextChannel,
+ pVoiceMgr->voices[bestCandidate].nextNote,
+ pVoiceMgr->voices[bestCandidate].nextVelocity); */ }
+ }
+#endif
+
+ *pVoiceNumber = (EAS_U16) bestCandidate;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * VMChannelPressure()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Change the channel pressure for the given channel
+ *
+ * Inputs:
+ * nChannel - the MIDI channel
+ * nVelocity - the channel pressure value
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ * Side Effects:
+ * psSynthObject->m_sChannel[nChannel].m_nChannelPressure is updated
+ *----------------------------------------------------------------------------
+*/
+void VMChannelPressure (S_SYNTH *pSynth, EAS_U8 channel, EAS_U8 value)
+{
+ S_SYNTH_CHANNEL *pChannel;
+
+ pChannel = &(pSynth->channels[channel]);
+ pChannel->channelPressure = value;
+
+ /*
+ set a channel flag to request parameter updates
+ for all the voices associated with this channel
+ */
+ pChannel->channelFlags |= CHANNEL_FLAG_UPDATE_CHANNEL_PARAMETERS;
+}
+
+/*----------------------------------------------------------------------------
+ * VMPitchBend()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Change the pitch wheel value for the given channel.
+ * This routine constructs the proper 14-bit argument when the calling routine
+ * passes the pitch LSB and MSB.
+ *
+ * Note: some midi disassemblers display a bipolar pitch bend value.
+ * We can display the bipolar value using
+ * if m_nPitchBend >= 0x2000
+ * bipolar pitch bend = postive (m_nPitchBend - 0x2000)
+ * else
+ * bipolar pitch bend = negative (0x2000 - m_nPitchBend)
+ *
+ * Inputs:
+ * nChannel - the MIDI channel
+ * nPitchLSB - the LSB byte of the pitch bend message
+ * nPitchMSB - the MSB byte of the pitch bend message
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ * psSynthObject->m_sChannel[nChannel].m_nPitchBend is changed
+ *
+ *----------------------------------------------------------------------------
+*/
+void VMPitchBend (S_SYNTH *pSynth, EAS_U8 channel, EAS_U8 nPitchLSB, EAS_U8 nPitchMSB)
+{
+ S_SYNTH_CHANNEL *pChannel;
+
+ pChannel = &(pSynth->channels[channel]);
+ pChannel->pitchBend = (EAS_I16) ((nPitchMSB << 7) | nPitchLSB);
+
+ /*
+ set a channel flag to request parameter updates
+ for all the voices associated with this channel
+ */
+ pChannel->channelFlags |= CHANNEL_FLAG_UPDATE_CHANNEL_PARAMETERS;
+}
+
+/*----------------------------------------------------------------------------
+ * VMControlChange()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Change the controller (or mode) for the given channel.
+ *
+ * Inputs:
+ * nChannel - the MIDI channel
+ * nControllerNumber - the MIDI controller number
+ * nControlValue - the value for this controller message
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ * Side Effects:
+ * psSynthObject->m_sChannel[nChannel] controller is changed
+ *
+ *----------------------------------------------------------------------------
+*/
+void VMControlChange (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel, EAS_U8 controller, EAS_U8 value)
+{
+ S_SYNTH_CHANNEL *pChannel;
+
+ pChannel = &(pSynth->channels[channel]);
+
+ /*
+ set a channel flag to request parameter updates
+ for all the voices associated with this channel
+ */
+ pChannel->channelFlags |= CHANNEL_FLAG_UPDATE_CHANNEL_PARAMETERS;
+
+ switch ( controller )
+ {
+ case MIDI_CONTROLLER_BANK_SELECT_MSB:
+#ifdef _DEBUG_VM
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMControlChange: Bank Select MSB: msb 0x%X\n", value); */ }
+#endif
+ /* use this MSB with a zero LSB, until we get an LSB message */
+ pChannel->bankNum = value << 8;
+ break;
+
+ case MIDI_CONTROLLER_MOD_WHEEL:
+ /* we treat mod wheel as a 7-bit controller and only use the MSB */
+ pChannel->modWheel = value;
+ break;
+
+ case MIDI_CONTROLLER_VOLUME:
+ /* we treat volume as a 7-bit controller and only use the MSB */
+ pChannel->volume = value;
+ break;
+
+ case MIDI_CONTROLLER_PAN:
+ /* we treat pan as a 7-bit controller and only use the MSB */
+ pChannel->pan = value;
+ break;
+
+ case MIDI_CONTROLLER_EXPRESSION:
+ /* we treat expression as a 7-bit controller and only use the MSB */
+ pChannel->expression = value;
+ break;
+
+ case MIDI_CONTROLLER_BANK_SELECT_LSB:
+#ifdef _DEBUG_VM
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMControlChange: Bank Select LSB: lsb 0x%X\n", value); */ }
+#endif
+ /*
+ construct bank number as 7-bits (stored as 8) of existing MSB
+ and 7-bits of new LSB (also stored as 8(
+ */
+ pChannel->bankNum =
+ (pChannel->bankNum & 0xFF00) | value;
+
+ break;
+
+ case MIDI_CONTROLLER_SUSTAIN_PEDAL:
+ /* we treat sustain pedal as a boolean on/off bit flag */
+ if (value < 64)
+ {
+ /*
+ we are requested to turn the pedal off, but first check
+ if the pedal is already on
+ */
+ if (0 !=
+ (pChannel->channelFlags & CHANNEL_FLAG_SUSTAIN_PEDAL)
+ )
+ {
+ /*
+ The sustain flag is presently set and the damper pedal is on.
+ We are therefore transitioning from damper pedal ON to
+ damper pedal OFF. This means all notes in this channel
+ that received a note off while the damper pedal was on, and
+ had their note-off requests deferred, should now proceed to
+ the release state.
+ */
+ VMReleaseAllDeferredNoteOffs(pVoiceMgr, pSynth, channel);
+ } /* end if sustain pedal is already on */
+
+ /* turn the sustain pedal off */
+ pChannel->channelFlags &= ~CHANNEL_FLAG_SUSTAIN_PEDAL;
+ }
+ else
+ {
+ /*
+ we are requested to turn the pedal on, but first check
+ if the pedal is already off
+ */
+ if (0 ==
+ (pChannel->channelFlags & CHANNEL_FLAG_SUSTAIN_PEDAL)
+ )
+ {
+ /*
+ The sustain flag is presently clear and the damper pedal is off.
+ We are therefore transitioning from damper pedal OFF to
+ damper pedal ON. Currently sounding notes should be left
+ unchanged. However, we should try to "catch" notes if possible.
+ If any notes have levels >= sustain level, catch them,
+ otherwise, let them continue to release.
+ */
+ VMCatchNotesForSustainPedal(pVoiceMgr, pSynth, channel);
+ }
+
+ /* turn the sustain pedal on */
+ pChannel->channelFlags |= CHANNEL_FLAG_SUSTAIN_PEDAL;
+ }
+
+ break;
+#ifdef _REVERB
+ case MIDI_CONTROLLER_REVERB_SEND:
+ /* we treat send as a 7-bit controller and only use the MSB */
+ pSynth->channels[channel].reverbSend = value;
+ break;
+#endif
+#ifdef _CHORUS
+ case MIDI_CONTROLLER_CHORUS_SEND:
+ /* we treat send as a 7-bit controller and only use the MSB */
+ pSynth->channels[channel].chorusSend = value;
+ break;
+#endif
+ case MIDI_CONTROLLER_RESET_CONTROLLERS:
+ /* despite the Midi message name, not ALL controllers are reset */
+ pChannel->modWheel = DEFAULT_MOD_WHEEL;
+ pChannel->expression = DEFAULT_EXPRESSION;
+
+ /* turn the sustain pedal off as default/reset */
+ pChannel->channelFlags &= ~CHANNEL_FLAG_SUSTAIN_PEDAL;
+ pChannel->pitchBend = DEFAULT_PITCH_BEND;
+
+ /* reset channel pressure */
+ pChannel->channelPressure = DEFAULT_CHANNEL_PRESSURE;
+
+ /* reset RPN values */
+ pChannel->registeredParam = DEFAULT_REGISTERED_PARAM;
+ pChannel->pitchBendSensitivity = DEFAULT_PITCH_BEND_SENSITIVITY;
+ pChannel->finePitch = DEFAULT_FINE_PITCH;
+ pChannel->coarsePitch = DEFAULT_COARSE_PITCH;
+
+ /*
+ program change, bank select, channel volume CC7, pan CC10
+ are NOT reset
+ */
+ break;
+
+ /*
+ For logical reasons, the RPN data entry are grouped together.
+ However, keep in mind that these cases are not necessarily in
+ ascending order.
+ e.g., MIDI_CONTROLLER_DATA_ENTRY_MSB == 6,
+ whereas MIDI_CONTROLLER_SUSTAIN_PEDAL == 64.
+ So arrange these case statements in whatever manner is more efficient for
+ the processor / compiler.
+ */
+ case MIDI_CONTROLLER_ENTER_DATA_MSB:
+ case MIDI_CONTROLLER_ENTER_DATA_LSB:
+ case MIDI_CONTROLLER_SELECT_RPN_LSB:
+ case MIDI_CONTROLLER_SELECT_RPN_MSB:
+ case MIDI_CONTROLLER_SELECT_NRPN_MSB:
+ case MIDI_CONTROLLER_SELECT_NRPN_LSB:
+ VMUpdateRPNStateMachine(pSynth, channel, controller, value);
+ break;
+
+ case MIDI_CONTROLLER_ALL_SOUND_OFF:
+ case MIDI_CONTROLLER_ALL_NOTES_OFF:
+ case MIDI_CONTROLLER_OMNI_OFF:
+ case MIDI_CONTROLLER_OMNI_ON:
+ case MIDI_CONTROLLER_MONO_ON_POLY_OFF:
+ case MIDI_CONTROLLER_POLY_ON_MONO_OFF:
+ /* NOTE: we treat all sounds off the same as all notes off */
+ VMAllNotesOff(pVoiceMgr, pSynth, channel);
+ break;
+
+ default:
+#ifdef _DEBUG_VM
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMControlChange: controller %d not yet implemented\n", controller); */ }
+#endif
+ break;
+
+ }
+
+ return;
+}
+
+/*----------------------------------------------------------------------------
+ * VMUpdateRPNStateMachine()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Call this function when we want to parse RPN related controller messages.
+ * We only support RPN0 (pitch bend sensitivity), RPN1 (fine tuning) and
+ * RPN2 (coarse tuning). Any other RPNs or NRPNs are ignored for now.
+ *.
+ * Supports any order, so not a state machine anymore. This function was
+ * rewritten to work correctly regardless of order.
+ *
+ * Inputs:
+ * nChannel - the channel this controller message is coming from
+ * nControllerNumber - which RPN related controller
+ * nControlValue - the value of the RPN related controller
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ * returns EAS_RESULT, which is typically EAS_SUCCESS, since there are
+ * few possible errors
+ *
+ * Side Effects:
+ * gsSynthObject.m_sChannel[nChannel].m_nPitchBendSensitivity
+ * (or m_nFinePitch or m_nCoarsePitch)
+ * will be updated if the proper RPN message is received.
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT VMUpdateRPNStateMachine (S_SYNTH *pSynth, EAS_U8 channel, EAS_U8 controller, EAS_U8 value)
+{
+ S_SYNTH_CHANNEL *pChannel;
+
+#ifdef _DEBUG_VM
+ if (channel >= NUM_SYNTH_CHANNELS)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMUpdateRPNStateMachines: error, %d invalid channel number\n",
+ channel); */ }
+ return EAS_FAILURE;
+ }
+#endif
+
+ pChannel = &(pSynth->channels[channel]);
+
+ switch (controller)
+ {
+ case MIDI_CONTROLLER_SELECT_NRPN_MSB:
+ case MIDI_CONTROLLER_SELECT_NRPN_LSB:
+ pChannel->registeredParam = DEFAULT_REGISTERED_PARAM;
+ break;
+ case MIDI_CONTROLLER_SELECT_RPN_MSB:
+ pChannel->registeredParam =
+ (pChannel->registeredParam & 0x7F) | (value<<7);
+ break;
+ case MIDI_CONTROLLER_SELECT_RPN_LSB:
+ pChannel->registeredParam =
+ (pChannel->registeredParam & 0x7F00) | value;
+ break;
+ case MIDI_CONTROLLER_ENTER_DATA_MSB:
+ switch (pChannel->registeredParam)
+ {
+ case 0:
+ pChannel->pitchBendSensitivity = value * 100;
+ break;
+ case 1:
+ /*lint -e{702} <avoid division for performance reasons>*/
+ pChannel->finePitch = (EAS_I8)((((value << 7) - 8192) * 100) >> 13);
+ break;
+ case 2:
+ pChannel->coarsePitch = (EAS_I8)(value - 64);
+ break;
+ default:
+ break;
+ }
+ break;
+ case MIDI_CONTROLLER_ENTER_DATA_LSB:
+ switch (pChannel->registeredParam)
+ {
+ case 0:
+ //ignore lsb
+ break;
+ case 1:
+ //ignore lsb
+ break;
+ case 2:
+ //ignore lsb
+ break;
+ default:
+ break;
+ }
+ break;
+ default:
+ return EAS_FAILURE; //not a RPN related controller
+ }
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * VMUpdateStaticChannelParameters()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Update all of the static channel parameters for channels that have had
+ * a controller change values
+ * Or if the synth has signalled that all channels must forcibly
+ * be updated
+ *
+ * Inputs:
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ * none
+ *
+ * Side Effects:
+ * - psSynthObject->m_sChannel[].m_nStaticGain and m_nStaticPitch
+ * are updated for channels whose controller values have changed
+ * or if the synth has signalled that all channels must forcibly
+ * be updated
+ *----------------------------------------------------------------------------
+*/
+void VMUpdateStaticChannelParameters (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth)
+{
+ EAS_INT channel;
+
+ if (pSynth->synthFlags & SYNTH_FLAG_UPDATE_ALL_CHANNEL_PARAMETERS)
+ {
+ /*
+ the synth wants us to forcibly update all channel
+ parameters. This event occurs when we are about to
+ finish resetting the synth
+ */
+ for (channel = 0; channel < NUM_SYNTH_CHANNELS; channel++)
+ {
+#ifdef _HYBRID_SYNTH
+ if (pSynth->channels[channel].regionIndex & FLAG_RGN_IDX_FM_SYNTH)
+ pSecondarySynth->pfUpdateChannel(pVoiceMgr, pSynth, (EAS_U8) channel);
+ else
+ pPrimarySynth->pfUpdateChannel(pVoiceMgr, pSynth, (EAS_U8) channel);
+#else
+ pPrimarySynth->pfUpdateChannel(pVoiceMgr, pSynth, (EAS_U8) channel);
+#endif
+ }
+
+ /*
+ clear the flag to indicates we have now forcibly
+ updated all channel parameters
+ */
+ pSynth->synthFlags &= ~SYNTH_FLAG_UPDATE_ALL_CHANNEL_PARAMETERS;
+ }
+ else
+ {
+
+ /* only update channel params if signalled by a channel flag */
+ for (channel = 0; channel < NUM_SYNTH_CHANNELS; channel++)
+ {
+ if ( 0 != (pSynth->channels[channel].channelFlags & CHANNEL_FLAG_UPDATE_CHANNEL_PARAMETERS))
+ {
+#ifdef _HYBRID_SYNTH
+ if (pSynth->channels[channel].regionIndex & FLAG_RGN_IDX_FM_SYNTH)
+ pSecondarySynth->pfUpdateChannel(pVoiceMgr, pSynth, (EAS_U8) channel);
+ else
+ pPrimarySynth->pfUpdateChannel(pVoiceMgr, pSynth, (EAS_U8) channel);
+#else
+ pPrimarySynth->pfUpdateChannel(pVoiceMgr, pSynth, (EAS_U8) channel);
+#endif
+ }
+ }
+
+ }
+
+ return;
+}
+
+/*----------------------------------------------------------------------------
+ * VMFindProgram()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Look up an individual program in sound library. This function
+ * searches the bank list for a program, then the individual program
+ * list.
+ *
+ * Inputs:
+ *
+ * Outputs:
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT VMFindProgram (const S_EAS *pEAS, EAS_U32 bank, EAS_U8 programNum, EAS_U16 *pRegionIndex)
+{
+ EAS_U32 locale;
+ const S_PROGRAM *p;
+ EAS_U16 i;
+ EAS_U16 regionIndex;
+
+ /* make sure we have a valid sound library */
+ if (pEAS == NULL)
+ return EAS_FAILURE;
+
+ /* search the banks */
+ for (i = 0; i < pEAS->numBanks; i++)
+ {
+ if (bank == (EAS_U32) pEAS->pBanks[i].locale)
+ {
+ regionIndex = pEAS->pBanks[i].regionIndex[programNum];
+ if (regionIndex != INVALID_REGION_INDEX)
+ {
+ *pRegionIndex = regionIndex;
+ return EAS_SUCCESS;
+ }
+ break;
+ }
+ }
+
+ /* establish locale */
+ locale = ( bank << 8) | programNum;
+
+ /* search for program */
+ for (i = 0, p = pEAS->pPrograms; i < pEAS->numPrograms; i++, p++)
+ {
+ if (p->locale == locale)
+ {
+ *pRegionIndex = p->regionIndex;
+ return EAS_SUCCESS;
+ }
+ }
+
+ return EAS_FAILURE;
+}
+
+#ifdef DLS_SYNTHESIZER
+/*----------------------------------------------------------------------------
+ * VMFindDLSProgram()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Look up an individual program in sound library. This function
+ * searches the bank list for a program, then the individual program
+ * list.
+ *
+ * Inputs:
+ *
+ * Outputs:
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT VMFindDLSProgram (const S_DLS *pDLS, EAS_U32 bank, EAS_U8 programNum, EAS_U16 *pRegionIndex)
+{
+ EAS_U32 locale;
+ const S_PROGRAM *p;
+ EAS_U16 i;
+
+ /* make sure we have a valid sound library */
+ if (pDLS == NULL)
+ return EAS_FAILURE;
+
+ /* establish locale */
+ locale = (bank << 8) | programNum;
+
+ /* search for program */
+ for (i = 0, p = pDLS->pDLSPrograms; i < pDLS->numDLSPrograms; i++, p++)
+ {
+ if (p->locale == locale)
+ {
+ *pRegionIndex = p->regionIndex;
+ return EAS_SUCCESS;
+ }
+ }
+
+ return EAS_FAILURE;
+}
+#endif
+
+/*----------------------------------------------------------------------------
+ * VMProgramChange()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Change the instrument (program) for the given channel.
+ *
+ * Depending on the program number, and the bank selected for this channel, the
+ * program may be in ROM, RAM (from SMAF or CMX related RAM wavetable), or
+ * Alternate wavetable (from mobile DLS or other DLS file)
+ *
+ * This function figures out what wavetable should be used, and sets it up as the
+ * wavetable to use for this channel. Also the channel may switch from a melodic
+ * channel to a rhythm channel, or vice versa.
+ *
+ * Inputs:
+ *
+ * Outputs:
+ * Side Effects:
+ * gsSynthObject.m_sChannel[nChannel].m_nProgramNumber is likely changed
+ * gsSynthObject.m_sChannel[nChannel].m_psEAS may be changed
+ * gsSynthObject.m_sChannel[nChannel].m_bRhythmChannel may be changed
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pVoiceMgr) reserved for future use */
+void VMProgramChange (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel, EAS_U8 program)
+{
+ S_SYNTH_CHANNEL *pChannel;
+ EAS_U32 bank;
+ EAS_U16 regionIndex;
+
+#ifdef _DEBUG_VM
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "VMProgramChange: vSynthNum=%d, channel=%d, program=%d\n", pSynth->vSynthNum, channel, program); */ }
+#endif
+
+ /* setup pointer to MIDI channel data */
+ pChannel = &pSynth->channels[channel];
+ bank = pChannel->bankNum;
+
+ /* allow channels to switch between being melodic or rhythm channels, using GM2 CC values */
+ if ((bank & 0xFF00) == DEFAULT_RHYTHM_BANK_NUMBER)
+ {
+ /* make it a rhythm channel */
+ pChannel->channelFlags |= CHANNEL_FLAG_RHYTHM_CHANNEL;
+ }
+ else if ((bank & 0xFF00) == DEFAULT_MELODY_BANK_NUMBER)
+ {
+ /* make it a melody channel */
+ pChannel->channelFlags &= ~CHANNEL_FLAG_RHYTHM_CHANNEL;
+ }
+
+ regionIndex = DEFAULT_REGION_INDEX;
+
+#ifdef EXTERNAL_AUDIO
+ /* give the external audio interface a chance to handle it */
+ if (pSynth->cbProgChgFunc != NULL)
+ {
+ S_EXT_AUDIO_PRG_CHG prgChg;
+ prgChg.channel = channel;
+ prgChg.bank = (EAS_U16) bank;
+ prgChg.program = program;
+ if (pSynth->cbProgChgFunc(pSynth->pExtAudioInstData, &prgChg))
+ pChannel->channelFlags |= CHANNEL_FLAG_EXTERNAL_AUDIO;
+ }
+
+#endif
+
+
+#ifdef DLS_SYNTHESIZER
+ /* first check for DLS program that may overlay the internal instrument */
+ if (VMFindDLSProgram(pSynth->pDLS, bank, program, &regionIndex) != EAS_SUCCESS)
+#endif
+
+ /* braces to support 'if' clause above */
+ {
+
+ /* look in the internal banks */
+ if (VMFindProgram(pSynth->pEAS, bank, program, &regionIndex) != EAS_SUCCESS)
+
+ /* fall back to default bank */
+ {
+ if (pSynth->channels[channel].channelFlags & CHANNEL_FLAG_RHYTHM_CHANNEL)
+ bank = DEFAULT_RHYTHM_BANK_NUMBER;
+ else
+ bank = DEFAULT_MELODY_BANK_NUMBER;
+
+ if (VMFindProgram(pSynth->pEAS, bank, program, &regionIndex) != EAS_SUCCESS)
+
+ /* switch to program 0 in the default bank */
+ {
+ if (VMFindProgram(pSynth->pEAS, bank, 0, &regionIndex) != EAS_SUCCESS)
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "VMProgramChange: No program @ %03d:%03d:%03d\n",
+ (bank >> 8) & 0x7f, bank & 0x7f, program); */ }
+ }
+ }
+ }
+
+ /* we have our new program change for this channel */
+ pChannel->programNum = program;
+ pChannel->regionIndex = regionIndex;
+
+ /*
+ set a channel flag to request parameter updates
+ for all the voices associated with this channel
+ */
+ pChannel->channelFlags |= CHANNEL_FLAG_UPDATE_CHANNEL_PARAMETERS;
+
+ return;
+}
+
+/*----------------------------------------------------------------------------
+ * VMAddSamples()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Synthesize the requested number of samples (block based processing)
+ *
+ * Inputs:
+ * nNumSamplesToAdd - number of samples to write to buffer
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ * number of voices rendered
+ *
+ * Side Effects:
+ * - samples are added to the presently free buffer
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_I32 VMAddSamples (S_VOICE_MGR *pVoiceMgr, EAS_I32 *pMixBuffer, EAS_I32 numSamples)
+{
+ S_SYNTH *pSynth;
+ EAS_INT voicesRendered;
+ EAS_INT voiceNum;
+ EAS_BOOL done;
+
+#ifdef _REVERB
+ EAS_PCM *pReverbSendBuffer;
+#endif // ifdef _REVERB
+
+#ifdef _CHORUS
+ EAS_PCM *pChorusSendBuffer;
+#endif // ifdef _CHORUS
+
+ voicesRendered = 0;
+ for (voiceNum = 0; voiceNum < MAX_SYNTH_VOICES; voiceNum++)
+ {
+
+ /* retarget stolen voices */
+ if ((pVoiceMgr->voices[voiceNum].voiceState == eVoiceStateStolen) && (pVoiceMgr->voices[voiceNum].gain <= 0))
+ VMRetargetStolenVoice(pVoiceMgr, voiceNum);
+
+ /* get pointer to virtual synth */
+ pSynth = pVoiceMgr->pSynth[pVoiceMgr->voices[voiceNum].channel >> 4];
+
+ /* synthesize active voices */
+ if (pVoiceMgr->voices[voiceNum].voiceState != eVoiceStateFree)
+ {
+ done = GetSynthPtr(voiceNum)->pfUpdateVoice(pVoiceMgr, pSynth, &pVoiceMgr->voices[voiceNum], GetAdjustedVoiceNum(voiceNum), pMixBuffer, numSamples);
+ voicesRendered++;
+
+ /* voice is finished */
+ if (done == EAS_TRUE)
+ {
+ /* set gain of stolen voice to zero so it will be restarted */
+ if (pVoiceMgr->voices[voiceNum].voiceState == eVoiceStateStolen)
+ pVoiceMgr->voices[voiceNum].gain = 0;
+
+ /* or return it to the free voice pool */
+ else
+ VMFreeVoice(pVoiceMgr, pSynth, &pVoiceMgr->voices[voiceNum]);
+ }
+
+ /* if this voice is scheduled to be muted, set the mute flag */
+ if (pVoiceMgr->voices[voiceNum].voiceFlags & VOICE_FLAG_DEFER_MUTE)
+ {
+ pVoiceMgr->voices[voiceNum].voiceFlags &= ~(VOICE_FLAG_DEFER_MUTE | VOICE_FLAG_DEFER_MIDI_NOTE_OFF);
+ VMMuteVoice(pVoiceMgr, voiceNum);
+ }
+
+ /* if voice just started, advance state to play */
+ if (pVoiceMgr->voices[voiceNum].voiceState == eVoiceStateStart)
+ pVoiceMgr->voices[voiceNum].voiceState = eVoiceStatePlay;
+ }
+ }
+
+ return voicesRendered;
+}
+
+/*----------------------------------------------------------------------------
+ * VMRender()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * This routine renders a frame of audio
+ *
+ * Inputs:
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ * pVoicesRendered - number of voices rendered this frame
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT VMRender (S_VOICE_MGR *pVoiceMgr, EAS_I32 numSamples, EAS_I32 *pMixBuffer, EAS_I32 *pVoicesRendered)
+{
+ S_SYNTH *pSynth;
+ EAS_INT i;
+ EAS_INT channel;
+
+#ifdef _CHECKED_BUILD
+ SanityCheck(pVoiceMgr);
+#endif
+
+ /* update MIDI channel parameters */
+ *pVoicesRendered = 0;
+ for (i = 0; i < MAX_VIRTUAL_SYNTHESIZERS; i++)
+ {
+ if (pVoiceMgr->pSynth[i] != NULL)
+ VMUpdateStaticChannelParameters(pVoiceMgr, pVoiceMgr->pSynth[i]);
+ }
+
+ /* synthesize a buffer of audio */
+ *pVoicesRendered = VMAddSamples(pVoiceMgr, pMixBuffer, numSamples);
+
+ /*
+ * check for deferred note-off messages
+ * If flag is set, that means one or more voices are expecting deferred
+ * midi note-off messages because the midi note-on and corresponding midi
+ * note-off requests occurred during the same update interval. The goal
+ * is the defer the note-off request so that the note can at least start.
+ */
+ for (i = 0; i < MAX_VIRTUAL_SYNTHESIZERS; i++)
+ {
+ pSynth = pVoiceMgr->pSynth[i];
+
+ if (pSynth== NULL)
+ continue;
+
+ if (pSynth->synthFlags & SYNTH_FLAG_DEFERRED_MIDI_NOTE_OFF_PENDING)
+ VMDeferredStopNote(pVoiceMgr, pSynth);
+
+ /* check if we need to reset the synth */
+ if ((pSynth->synthFlags & SYNTH_FLAG_RESET_IS_REQUESTED) &&
+ (pSynth->numActiveVoices == 0))
+ {
+ /*
+ complete the process of resetting the synth now that
+ all voices have muted
+ */
+#ifdef _DEBUG_VM
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMAddSamples: complete the reset process\n"); */ }
+#endif
+
+ VMInitializeAllChannels(pVoiceMgr, pSynth);
+ VMInitializeAllVoices(pVoiceMgr, pSynth->vSynthNum);
+
+ /* clear the reset flag */
+ pSynth->synthFlags &= ~SYNTH_FLAG_RESET_IS_REQUESTED;
+ }
+
+ /* clear channel update flags */
+ for (channel = 0; channel < NUM_SYNTH_CHANNELS; channel++)
+ pSynth->channels[channel].channelFlags &= ~CHANNEL_FLAG_UPDATE_CHANNEL_PARAMETERS;
+
+ }
+
+#ifdef _CHECKED_BUILD
+ SanityCheck(pVoiceMgr);
+#endif
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * VMInitWorkload()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Clears the workload counter
+ *
+ * Inputs:
+ * pVoiceMgr - pointer to instance data
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+void VMInitWorkload (S_VOICE_MGR *pVoiceMgr)
+{
+ pVoiceMgr->workload = 0;
+}
+
+/*----------------------------------------------------------------------------
+ * VMSetWorkload()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Sets the max workload for a single frame.
+ *
+ * Inputs:
+ * pVoiceMgr - pointer to instance data
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+void VMSetWorkload (S_VOICE_MGR *pVoiceMgr, EAS_I32 maxWorkLoad)
+{
+ pVoiceMgr->maxWorkLoad = maxWorkLoad;
+}
+
+/*----------------------------------------------------------------------------
+ * VMCheckWorkload()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Checks to see if work load has been exceeded on this frame.
+ *
+ * Inputs:
+ * pVoiceMgr - pointer to instance data
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_BOOL VMCheckWorkload (S_VOICE_MGR *pVoiceMgr)
+{
+ if (pVoiceMgr->maxWorkLoad > 0)
+ return (EAS_BOOL) (pVoiceMgr->workload >= pVoiceMgr->maxWorkLoad);
+ return EAS_FALSE;
+}
+
+/*----------------------------------------------------------------------------
+ * VMActiveVoices()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Returns the number of active voices in the synthesizer.
+ *
+ * Inputs:
+ * pEASData - pointer to instance data
+ *
+ * Outputs:
+ * Returns the number of active voices
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_I32 VMActiveVoices (S_SYNTH *pSynth)
+{
+ return pSynth->numActiveVoices;
+}
+
+/*----------------------------------------------------------------------------
+ * VMSetSynthPolyphony()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Set the synth to a new polyphony value. Value must be >= 1 and
+ * <= MAX_SYNTH_VOICES. This function will pin the polyphony at those limits
+ *
+ * Inputs:
+ * pVoiceMgr pointer to synthesizer data
+ * polyphonyCount desired polyphony count
+ * synth synthesizer number (0 = onboard, 1 = DSP)
+ *
+ * Outputs:
+ * Returns error code
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT VMSetSynthPolyphony (S_VOICE_MGR *pVoiceMgr, EAS_I32 synth, EAS_I32 polyphonyCount)
+{
+ EAS_INT i;
+ EAS_INT activeVoices;
+
+ /* lower limit */
+ if (polyphonyCount < 1)
+ polyphonyCount = 1;
+
+ /* split architecture */
+#if defined(_SECONDARY_SYNTH) || defined(EAS_SPLIT_WT_SYNTH)
+ if (synth == EAS_MCU_SYNTH)
+ {
+ if (polyphonyCount > NUM_PRIMARY_VOICES)
+ polyphonyCount = NUM_PRIMARY_VOICES;
+ if (pVoiceMgr->maxPolyphonyPrimary == polyphonyCount)
+ return EAS_SUCCESS;
+ pVoiceMgr->maxPolyphonyPrimary = (EAS_U16) polyphonyCount;
+ }
+ else if (synth == EAS_DSP_SYNTH)
+ {
+ if (polyphonyCount > NUM_SECONDARY_VOICES)
+ polyphonyCount = NUM_SECONDARY_VOICES;
+ if (pVoiceMgr->maxPolyphonySecondary == polyphonyCount)
+ return EAS_SUCCESS;
+ pVoiceMgr->maxPolyphonySecondary = (EAS_U16) polyphonyCount;
+ }
+ else
+ return EAS_ERROR_PARAMETER_RANGE;
+
+ /* setting for SP-MIDI */
+ pVoiceMgr->maxPolyphony = pVoiceMgr->maxPolyphonyPrimary + pVoiceMgr->maxPolyphonySecondary;
+
+ /* standard architecture */
+#else
+ if (synth != EAS_MCU_SYNTH)
+ return EAS_ERROR_PARAMETER_RANGE;
+
+ /* pin desired value to possible limits */
+ if (polyphonyCount > MAX_SYNTH_VOICES)
+ polyphonyCount = MAX_SYNTH_VOICES;
+
+ /* set polyphony, if value is different than current value */
+ if (pVoiceMgr->maxPolyphony == polyphonyCount)
+ return EAS_SUCCESS;
+
+ pVoiceMgr->maxPolyphony = (EAS_U16) polyphonyCount;
+#endif
+
+ /* if SPMIDI enabled, update channel masking based on new polyphony */
+ for (i = 0; i < MAX_VIRTUAL_SYNTHESIZERS; i++)
+ {
+ if (pVoiceMgr->pSynth[i])
+ {
+ if (pVoiceMgr->pSynth[i]->synthFlags & SYNTH_FLAG_SP_MIDI_ON)
+ VMMIPUpdateChannelMuting(pVoiceMgr, pVoiceMgr->pSynth[i]);
+ else
+ pVoiceMgr->pSynth[i]->poolAlloc[0] = (EAS_U8) polyphonyCount;
+ }
+ }
+
+ /* are we under polyphony limit? */
+ if (pVoiceMgr->activeVoices <= polyphonyCount)
+ return EAS_SUCCESS;
+
+ /* count the number of active voices */
+ activeVoices = 0;
+ for (i = 0; i < MAX_SYNTH_VOICES; i++)
+ {
+
+ /* is voice active? */
+ if ((pVoiceMgr->voices[i].voiceState != eVoiceStateFree) && (pVoiceMgr->voices[i].voiceState != eVoiceStateMuting))
+ activeVoices++;
+ }
+
+ /* we may have to mute voices to reach new target */
+ while (activeVoices > polyphonyCount)
+ {
+ S_SYNTH *pSynth;
+ S_SYNTH_VOICE *pVoice;
+ EAS_I32 currentPriority, bestPriority;
+ EAS_INT bestCandidate;
+
+ /* find the lowest priority voice */
+ bestPriority = bestCandidate = -1;
+ for (i = 0; i < MAX_SYNTH_VOICES; i++)
+ {
+
+ pVoice = &pVoiceMgr->voices[i];
+
+ /* ignore free and muting voices */
+ if ((pVoice->voiceState == eVoiceStateFree) || (pVoice->voiceState == eVoiceStateMuting))
+ continue;
+
+ pSynth = pVoiceMgr->pSynth[GET_VSYNTH(pVoice->channel)];
+
+ /* if voice is stolen or just started, reduce the likelihood it will be stolen */
+ if (( pVoice->voiceState == eVoiceStateStolen) || (pVoice->voiceFlags & VOICE_FLAG_NO_SAMPLES_SYNTHESIZED_YET))
+ {
+ /* include velocity */
+ currentPriority = 128 - pVoice->nextVelocity;
+
+ /* include channel priority */
+ currentPriority += pSynth->channels[GET_CHANNEL(pVoice->nextChannel)].pool << CHANNEL_PRIORITY_STEAL_WEIGHT;
+ }
+ else
+ {
+ /* include age */
+ currentPriority = (EAS_I32) pVoice->age << NOTE_AGE_STEAL_WEIGHT;
+
+ /* include note gain -higher gain is lower steal value */
+ /*lint -e{704} use shift for performance */
+ currentPriority += ((32768 >> (12 - NOTE_GAIN_STEAL_WEIGHT)) + 256) -
+ ((EAS_I32) pVoice->gain >> (12 - NOTE_GAIN_STEAL_WEIGHT));
+
+ /* include channel priority */
+ currentPriority += pSynth->channels[GET_CHANNEL(pVoice->channel)].pool << CHANNEL_PRIORITY_STEAL_WEIGHT;
+ }
+
+ /* include synth priority */
+ currentPriority += pSynth->priority << SYNTH_PRIORITY_WEIGHT;
+
+ /* is this the best choice so far? */
+ if (currentPriority > bestPriority)
+ {
+ bestPriority = currentPriority;
+ bestCandidate = i;
+ }
+ }
+
+ /* shutdown best candidate */
+ if (bestCandidate < 0)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "VMSetPolyphony: Unable to reduce polyphony\n"); */ }
+ break;
+ }
+
+ /* shut down this voice */
+ /*lint -e{771} pSynth is initialized if bestCandidate >= 0 */
+ VMMuteVoice(pVoiceMgr, bestCandidate);
+ activeVoices--;
+ }
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * VMGetSynthPolyphony()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Returns the current polyphony setting
+ *
+ * Inputs:
+ * pVoiceMgr pointer to synthesizer data
+ * synth synthesizer number (0 = onboard, 1 = DSP)
+ *
+ * Outputs:
+ * Returns actual polyphony value set, as pinned by limits
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT VMGetSynthPolyphony (S_VOICE_MGR *pVoiceMgr, EAS_I32 synth, EAS_I32 *pPolyphonyCount)
+{
+
+#if defined(_SECONDARY_SYNTH) || defined(EAS_SPLIT_WT_SYNTH)
+ if (synth == EAS_MCU_SYNTH)
+ *pPolyphonyCount = pVoiceMgr->maxPolyphonyPrimary;
+ else if (synth == EAS_DSP_SYNTH)
+ *pPolyphonyCount = pVoiceMgr->maxPolyphonySecondary;
+ else
+ return EAS_ERROR_PARAMETER_RANGE;
+#else
+ if (synth != EAS_MCU_SYNTH)
+ return EAS_ERROR_PARAMETER_RANGE;
+ *pPolyphonyCount = pVoiceMgr->maxPolyphony;
+#endif
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * VMSetPolyphony()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Set the virtual synth polyphony. 0 = no limit (i.e. can use
+ * all available voices).
+ *
+ * Inputs:
+ * pVoiceMgr pointer to synthesizer data
+ * polyphonyCount desired polyphony count
+ * pSynth pointer to virtual synth
+ *
+ * Outputs:
+ * Returns error code
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT VMSetPolyphony (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_I32 polyphonyCount)
+{
+ EAS_INT i;
+ EAS_INT activeVoices;
+
+ /* check limits */
+ if (polyphonyCount < 0)
+ return EAS_ERROR_PARAMETER_RANGE;
+
+ /* zero is max polyphony */
+ if ((polyphonyCount == 0) || (polyphonyCount > MAX_SYNTH_VOICES))
+ {
+ pSynth->maxPolyphony = 0;
+ return EAS_SUCCESS;
+ }
+
+ /* set new polyphony */
+ pSynth->maxPolyphony = (EAS_U16) polyphonyCount;
+
+ /* max polyphony is minimum of virtual synth and actual synth */
+ if (polyphonyCount > pVoiceMgr->maxPolyphony)
+ polyphonyCount = pVoiceMgr->maxPolyphony;
+
+ /* if SP-MIDI mode, update the channel muting */
+ if (pSynth->synthFlags & SYNTH_FLAG_SP_MIDI_ON)
+ VMMIPUpdateChannelMuting(pVoiceMgr, pSynth);
+ else
+ pSynth->poolAlloc[0] = (EAS_U8) polyphonyCount;
+
+ /* are we under polyphony limit? */
+ if (pSynth->numActiveVoices <= polyphonyCount)
+ return EAS_SUCCESS;
+
+ /* count the number of active voices */
+ activeVoices = 0;
+ for (i = 0; i < MAX_SYNTH_VOICES; i++)
+ {
+ /* this synth? */
+ if (GET_VSYNTH(pVoiceMgr->voices[i].nextChannel) != pSynth->vSynthNum)
+ continue;
+
+ /* is voice active? */
+ if ((pVoiceMgr->voices[i].voiceState != eVoiceStateFree) && (pVoiceMgr->voices[i].voiceState != eVoiceStateMuting))
+ activeVoices++;
+ }
+
+ /* we may have to mute voices to reach new target */
+ while (activeVoices > polyphonyCount)
+ {
+ S_SYNTH_VOICE *pVoice;
+ EAS_I32 currentPriority, bestPriority;
+ EAS_INT bestCandidate;
+
+ /* find the lowest priority voice */
+ bestPriority = bestCandidate = -1;
+ for (i = 0; i < MAX_SYNTH_VOICES; i++)
+ {
+ pVoice = &pVoiceMgr->voices[i];
+
+ /* this synth? */
+ if (GET_VSYNTH(pVoice->nextChannel) != pSynth->vSynthNum)
+ continue;
+
+ /* if voice is stolen or just started, reduce the likelihood it will be stolen */
+ if (( pVoice->voiceState == eVoiceStateStolen) || (pVoice->voiceFlags & VOICE_FLAG_NO_SAMPLES_SYNTHESIZED_YET))
+ {
+ /* include velocity */
+ currentPriority = 128 - pVoice->nextVelocity;
+
+ /* include channel priority */
+ currentPriority += pSynth->channels[GET_CHANNEL(pVoice->nextChannel)].pool << CHANNEL_PRIORITY_STEAL_WEIGHT;
+ }
+ else
+ {
+ /* include age */
+ currentPriority = (EAS_I32) pVoice->age << NOTE_AGE_STEAL_WEIGHT;
+
+ /* include note gain -higher gain is lower steal value */
+ /*lint -e{704} use shift for performance */
+ currentPriority += ((32768 >> (12 - NOTE_GAIN_STEAL_WEIGHT)) + 256) -
+ ((EAS_I32) pVoice->gain >> (12 - NOTE_GAIN_STEAL_WEIGHT));
+
+ /* include channel priority */
+ currentPriority += pSynth->channels[GET_CHANNEL(pVoice->nextChannel)].pool << CHANNEL_PRIORITY_STEAL_WEIGHT;
+ }
+
+ /* is this the best choice so far? */
+ if (currentPriority > bestPriority)
+ {
+ bestPriority = currentPriority;
+ bestCandidate = i;
+ }
+ }
+
+ /* shutdown best candidate */
+ if (bestCandidate < 0)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "VMSetPolyphony: Unable to reduce polyphony\n"); */ }
+ break;
+ }
+
+ /* shut down this voice */
+ VMMuteVoice(pVoiceMgr, bestCandidate);
+ activeVoices--;
+ }
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * VMGetPolyphony()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Get the virtual synth polyphony
+ *
+ * Inputs:
+ * pVoiceMgr pointer to synthesizer data
+ * pPolyphonyCount pointer to variable to hold polyphony count
+ * pSynth pointer to virtual synth
+ *
+ * Outputs:
+ * Returns error code
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pVoiceMgr) reserved for future use */
+EAS_RESULT VMGetPolyphony (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_I32 *pPolyphonyCount)
+{
+ *pPolyphonyCount = (EAS_U16) pSynth->maxPolyphony;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * VMSetPriority()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Set the virtual synth priority
+ *
+ * Inputs:
+ * pVoiceMgr pointer to synthesizer data
+ * priority new priority
+ * pSynth pointer to virtual synth
+ *
+ * Outputs:
+ * Returns error code
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pVoiceMgr) reserved for future use */
+EAS_RESULT VMSetPriority (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_I32 priority)
+{
+ pSynth->priority = (EAS_U8) priority ;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * VMGetPriority()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Get the virtual synth priority
+ *
+ * Inputs:
+ * pVoiceMgr pointer to synthesizer data
+ * pPriority pointer to variable to hold priority
+ * pSynth pointer to virtual synth
+ *
+ * Outputs:
+ * Returns error code
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pVoiceMgr) reserved for future use */
+EAS_RESULT VMGetPriority (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_I32 *pPriority)
+{
+ *pPriority = pSynth->priority;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * VMSetVolume()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Set the master volume for this synthesizer for this sequence.
+ *
+ * Inputs:
+ * nSynthVolume - the desired master volume
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ * overrides any previously set master volume from sysex
+ *
+ *----------------------------------------------------------------------------
+*/
+void VMSetVolume (S_SYNTH *pSynth, EAS_U16 masterVolume)
+{
+ pSynth->masterVolume = masterVolume;
+ pSynth->synthFlags |= SYNTH_FLAG_UPDATE_ALL_CHANNEL_PARAMETERS;
+}
+
+/*----------------------------------------------------------------------------
+ * VMSetPitchBendRange()
+ *----------------------------------------------------------------------------
+ * Set the pitch bend range for the given channel.
+ *----------------------------------------------------------------------------
+*/
+void VMSetPitchBendRange (S_SYNTH *pSynth, EAS_INT channel, EAS_I16 pitchBendRange)
+{
+ pSynth->channels[channel].pitchBendSensitivity = pitchBendRange;
+}
+
+/*----------------------------------------------------------------------------
+ * VMValidateEASLib()
+ *----------------------------------------------------------------------------
+ * Validates an EAS library
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT VMValidateEASLib (EAS_SNDLIB_HANDLE pEAS)
+{
+ /* validate the sound library */
+ if (pEAS)
+ {
+ if (pEAS->identifier != _EAS_LIBRARY_VERSION)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "VMValidateEASLib: Sound library mismatch in sound library: Read 0x%08x, expected 0x%08x\n",
+ pEAS->identifier, _EAS_LIBRARY_VERSION); */ }
+ return EAS_ERROR_SOUND_LIBRARY;
+ }
+
+ /* check sample rate */
+ if ((pEAS->libAttr & LIBFORMAT_SAMPLE_RATE_MASK) != _OUTPUT_SAMPLE_RATE)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "VMValidateEASLib: Sample rate mismatch in sound library: Read %lu, expected %lu\n",
+ pEAS->libAttr & LIBFORMAT_SAMPLE_RATE_MASK, _OUTPUT_SAMPLE_RATE); */ }
+ return EAS_ERROR_SOUND_LIBRARY;
+ }
+
+#ifdef _WT_SYNTH
+ /* check sample bit depth */
+#ifdef _8_BIT_SAMPLES
+ if (pEAS->libAttr & LIB_FORMAT_16_BIT_SAMPLES)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "VMValidateEASLib: Expected 8-bit samples and found 16-bit\n",
+ pEAS->libAttr & LIBFORMAT_SAMPLE_RATE_MASK, _OUTPUT_SAMPLE_RATE); */ }
+ return EAS_ERROR_SOUND_LIBRARY;
+ }
+#endif
+#ifdef _16_BIT_SAMPLES
+ if ((pEAS->libAttr & LIB_FORMAT_16_BIT_SAMPLES) == 0)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "VMValidateEASLib: Expected 16-bit samples and found 8-bit\n",
+ pEAS->libAttr & LIBFORMAT_SAMPLE_RATE_MASK, _OUTPUT_SAMPLE_RATE); */ }
+ return EAS_ERROR_SOUND_LIBRARY;
+ }
+#endif
+#endif
+ }
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * VMSetGlobalEASLib()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Sets the EAS library to be used by the synthesizer
+ *
+ * Inputs:
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT VMSetGlobalEASLib (S_VOICE_MGR *pVoiceMgr, EAS_SNDLIB_HANDLE pEAS)
+{
+ EAS_RESULT result;
+
+ result = VMValidateEASLib(pEAS);
+ if (result != EAS_SUCCESS)
+ return result;
+
+ pVoiceMgr->pGlobalEAS = pEAS;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * VMSetEASLib()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Sets the EAS library to be used by the synthesizer
+ *
+ * Inputs:
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT VMSetEASLib (S_SYNTH *pSynth, EAS_SNDLIB_HANDLE pEAS)
+{
+ EAS_RESULT result;
+
+ result = VMValidateEASLib(pEAS);
+ if (result != EAS_SUCCESS)
+ return result;
+
+ pSynth->pEAS = pEAS;
+ return EAS_SUCCESS;
+}
+
+#ifdef DLS_SYNTHESIZER
+/*----------------------------------------------------------------------------
+ * VMSetGlobalDLSLib()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Sets the DLS library to be used by the synthesizer
+ *
+ * Inputs:
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT VMSetGlobalDLSLib (EAS_DATA_HANDLE pEASData, EAS_DLSLIB_HANDLE pDLS)
+{
+
+ if (pEASData->pVoiceMgr->pGlobalDLS)
+ DLSCleanup(pEASData->hwInstData, pEASData->pVoiceMgr->pGlobalDLS);
+
+ pEASData->pVoiceMgr->pGlobalDLS = pDLS;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * VMSetDLSLib()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Sets the DLS library to be used by the synthesizer
+ *
+ * Inputs:
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT VMSetDLSLib (S_SYNTH *pSynth, EAS_DLSLIB_HANDLE pDLS)
+{
+ pSynth->pDLS = pDLS;
+ return EAS_SUCCESS;
+}
+#endif
+
+/*----------------------------------------------------------------------------
+ * VMSetTranposition()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Sets the global key transposition used by the synthesizer.
+ * Transposes all melodic instruments up or down by the specified
+ * amount. Range is limited to +/-12 semitones.
+ *
+ * Inputs:
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+void VMSetTranposition (S_SYNTH *pSynth, EAS_I32 transposition)
+{
+ pSynth->globalTranspose = (EAS_I8) transposition;
+}
+
+/*----------------------------------------------------------------------------
+ * VMGetTranposition()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Gets the global key transposition used by the synthesizer.
+ * Transposes all melodic instruments up or down by the specified
+ * amount. Range is limited to +/-12 semitones.
+ *
+ * Inputs:
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+void VMGetTranposition (S_SYNTH *pSynth, EAS_I32 *pTransposition)
+{
+ *pTransposition = pSynth->globalTranspose;
+}
+
+/*----------------------------------------------------------------------------
+ * VMGetNoteCount()
+ *----------------------------------------------------------------------------
+* Returns the total note count
+*----------------------------------------------------------------------------
+*/
+EAS_I32 VMGetNoteCount (S_SYNTH *pSynth)
+{
+ return pSynth->totalNoteCount;
+}
+
+/*----------------------------------------------------------------------------
+ * VMMIDIShutdown()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Clean up any Synth related system issues.
+ *
+ * Inputs:
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ * None
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+void VMMIDIShutdown (S_EAS_DATA *pEASData, S_SYNTH *pSynth)
+{
+ EAS_INT vSynthNum;
+
+ /* decrement reference count, free if all references are gone */
+ if (--pSynth->refCount > 0)
+ return;
+
+ vSynthNum = pSynth->vSynthNum;
+
+ /* cleanup DLS load */
+#ifdef DLS_SYNTHESIZER
+ /*lint -e{550} result used only in debugging code */
+ if (pSynth->pDLS != NULL)
+ {
+ EAS_RESULT result;
+ if ((result = DLSCleanup(pEASData->hwInstData, pSynth->pDLS)) != EAS_SUCCESS)
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "VMMIDIShutdown: Error %ld cleaning up DLS collection\n", result); */ }
+ pSynth->pDLS = NULL;
+ }
+#endif
+
+ VMReset(pEASData->pVoiceMgr, pSynth, EAS_TRUE);
+
+ /* check Configuration Module for static memory allocation */
+ if (!pEASData->staticMemoryModel)
+ EAS_HWFree(pEASData->hwInstData, pSynth);
+
+ /* clear pointer to MIDI state */
+ pEASData->pVoiceMgr->pSynth[vSynthNum] = NULL;
+}
+
+/*----------------------------------------------------------------------------
+ * VMShutdown()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Clean up any Synth related system issues.
+ *
+ * Inputs:
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ * None
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+void VMShutdown (S_EAS_DATA *pEASData)
+{
+
+ /* don't free a NULL pointer */
+ if (pEASData->pVoiceMgr == NULL)
+ return;
+
+#ifdef DLS_SYNTHESIZER
+ /* if we have a global DLS collection, clean it up */
+ if (pEASData->pVoiceMgr->pGlobalDLS)
+ {
+ DLSCleanup(pEASData->hwInstData, pEASData->pVoiceMgr->pGlobalDLS);
+ pEASData->pVoiceMgr->pGlobalDLS = NULL;
+ }
+#endif
+
+ /* check Configuration Module for static memory allocation */
+ if (!pEASData->staticMemoryModel)
+ EAS_HWFree(pEASData->hwInstData, pEASData->pVoiceMgr);
+ pEASData->pVoiceMgr = NULL;
+}
+
+#ifdef EXTERNAL_AUDIO
+/*----------------------------------------------------------------------------
+ * EAS_RegExtAudioCallback()
+ *----------------------------------------------------------------------------
+ * Register a callback for external audio processing
+ *----------------------------------------------------------------------------
+*/
+void VMRegExtAudioCallback (S_SYNTH *pSynth, EAS_VOID_PTR pInstData, EAS_EXT_PRG_CHG_FUNC cbProgChgFunc, EAS_EXT_EVENT_FUNC cbEventFunc)
+{
+ pSynth->pExtAudioInstData = pInstData;
+ pSynth->cbProgChgFunc = cbProgChgFunc;
+ pSynth->cbEventFunc = cbEventFunc;
+}
+
+/*----------------------------------------------------------------------------
+ * VMGetMIDIControllers()
+ *----------------------------------------------------------------------------
+ * Returns the MIDI controller values on the specified channel
+ *----------------------------------------------------------------------------
+*/
+void VMGetMIDIControllers (S_SYNTH *pSynth, EAS_U8 channel, S_MIDI_CONTROLLERS *pControl)
+{
+ pControl->modWheel = pSynth->channels[channel].modWheel;
+ pControl->volume = pSynth->channels[channel].volume;
+ pControl->pan = pSynth->channels[channel].pan;
+ pControl->expression = pSynth->channels[channel].expression;
+ pControl->channelPressure = pSynth->channels[channel].channelPressure;
+
+#ifdef _REVERB
+ pControl->reverbSend = pSynth->channels[channel].reverbSend;
+#endif
+
+#ifdef _CHORUSE
+ pControl->chorusSend = pSynth->channels[channel].chorusSend;
+#endif
+}
+#endif
+
+#ifdef _SPLIT_ARCHITECTURE
+/*----------------------------------------------------------------------------
+ * VMStartFrame()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Starts an audio frame
+ *
+ * Inputs:
+ *
+ * Outputs:
+ * Returns true if EAS_MixEnginePrep should be called (onboard mixing)
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_BOOL VMStartFrame (S_EAS_DATA *pEASData)
+{
+
+ /* init counter for voices starts in split architecture */
+#ifdef MAX_VOICE_STARTS
+ pVoiceMgr->numVoiceStarts = 0;
+#endif
+
+ return pFrameInterface->pfStartFrame(pEASData->pVoiceMgr->pFrameBuffer);
+}
+
+/*----------------------------------------------------------------------------
+ * VMEndFrame()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Stops an audio frame
+ *
+ * Inputs:
+ *
+ * Outputs:
+ * Returns true if EAS_MixEnginePost should be called (onboard mixing)
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_BOOL VMEndFrame (S_EAS_DATA *pEASData)
+{
+
+ return pFrameInterface->pfEndFrame(pEASData->pVoiceMgr->pFrameBuffer, pEASData->pMixBuffer, pEASData->masterGain);
+}
+#endif
+
+#ifdef TEST_HARNESS
+/*----------------------------------------------------------------------------
+ * SanityCheck()
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT VMSanityCheck (EAS_DATA_HANDLE pEASData)
+{
+ S_SYNTH_VOICE *pVoice;
+ S_SYNTH *pSynth;
+ EAS_INT i;
+ EAS_INT j;
+ EAS_INT freeVoices;
+ EAS_INT activeVoices;
+ EAS_INT playingVoices;
+ EAS_INT stolenVoices;
+ EAS_INT releasingVoices;
+ EAS_INT mutingVoices;
+ EAS_INT poolCount[MAX_VIRTUAL_SYNTHESIZERS][NUM_SYNTH_CHANNELS];
+ EAS_INT vSynthNum;
+ EAS_RESULT result = EAS_SUCCESS;
+
+ /* initialize counts */
+ EAS_HWMemSet(poolCount, 0, sizeof(poolCount));
+ freeVoices = activeVoices = playingVoices = stolenVoices = releasingVoices = mutingVoices = 0;
+
+ /* iterate through all voices */
+ for (i = 0; i < MAX_SYNTH_VOICES; i++)
+ {
+ pVoice = &pEASData->pVoiceMgr->voices[i];
+ if (pVoice->voiceState != eVoiceStateFree)
+ {
+ vSynthNum = GET_VSYNTH(pVoice->channel);
+ if (vSynthNum >= MAX_VIRTUAL_SYNTHESIZERS)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "VMSanityCheck: Voice %d has invalid virtual synth number %d\n", i, vSynthNum); */ }
+ result = EAS_FAILURE;
+ continue;
+ }
+ pSynth = pEASData->pVoiceMgr->pSynth[vSynthNum];
+
+ switch (pVoice->voiceState)
+ {
+ case eVoiceStateMuting:
+ activeVoices++;
+ mutingVoices++;
+ break;
+
+ case eVoiceStateStolen:
+ vSynthNum = GET_VSYNTH(pVoice->nextChannel);
+ if (vSynthNum >= MAX_VIRTUAL_SYNTHESIZERS)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "VMSanityCheck: Voice %d has invalid virtual synth number %d\n", i, vSynthNum); */ }
+ result = EAS_FAILURE;
+ continue;
+ }
+ pSynth = pEASData->pVoiceMgr->pSynth[vSynthNum];
+ activeVoices++;
+ stolenVoices++;
+ poolCount[vSynthNum][pSynth->channels[GET_CHANNEL(pVoice->nextChannel)].pool]++;
+ break;
+
+ case eVoiceStateStart:
+ case eVoiceStatePlay:
+ activeVoices++;
+ playingVoices++;
+ poolCount[vSynthNum][pSynth->channels[GET_CHANNEL(pVoice->channel)].pool]++;
+ break;
+
+ case eVoiceStateRelease:
+ activeVoices++;
+ releasingVoices++;
+ poolCount[vSynthNum][pSynth->channels[GET_CHANNEL(pVoice->channel)].pool]++;
+ break;
+
+ default:
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "VMSanityCheck : voice %d in invalid state\n", i); */ }
+ result = EAS_FAILURE;
+ break;
+ }
+ }
+
+ /* count free voices */
+ else
+ freeVoices++;
+ }
+
+ /* dump state info */
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "%d free\n", freeVoices); */ }
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "%d active\n", activeVoices); */ }
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "%d playing\n", playingVoices); */ }
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "%d releasing\n", releasingVoices); */ }
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "%d muting\n", mutingVoices); */ }
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "%d stolen\n", stolenVoices); */ }
+
+ if (pEASData->pVoiceMgr->activeVoices != activeVoices)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Active voice mismatch was %d should be %d\n",
+ pEASData->pVoiceMgr->activeVoices, activeVoices); */ }
+ result = EAS_FAILURE;
+ }
+
+ /* check virtual synth status */
+ for (i = 0; i < MAX_VIRTUAL_SYNTHESIZERS; i++)
+ {
+ if (pEASData->pVoiceMgr->pSynth[i] == NULL)
+ continue;
+
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Synth %d numActiveVoices: %d\n", i, pEASData->pVoiceMgr->pSynth[i]->numActiveVoices); */ }
+ if (pEASData->pVoiceMgr->pSynth[i]->numActiveVoices > MAX_SYNTH_VOICES)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "VMSanityCheck: Synth %d illegal count for numActiveVoices: %d\n", i, pEASData->pVoiceMgr->pSynth[i]->numActiveVoices); */ }
+ result = EAS_FAILURE;
+ }
+ for (j = 0; j < NUM_SYNTH_CHANNELS; j++)
+ {
+ if (poolCount[i][j] != pEASData->pVoiceMgr->pSynth[i]->poolCount[j])
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Pool count mismatch synth %d pool %d, was %d, should be %d\n",
+ i, j, pEASData->pVoiceMgr->pSynth[i]->poolCount[j], poolCount[i][j]); */ }
+ result = EAS_FAILURE;
+ }
+ }
+ }
+
+ return result;
+}
+#endif
+
+
diff --git a/arm-hybrid-22k/lib_src/eas_wavefile.c b/arm-hybrid-22k/lib_src/eas_wavefile.c
index d3f3ba0..f24bde2 100644
--- a/arm-hybrid-22k/lib_src/eas_wavefile.c
+++ b/arm-hybrid-22k/lib_src/eas_wavefile.c
@@ -1,12 +1,12 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_wavefile.c
- *
- * Contents and purpose:
- * This file implements the wave file parser.
- *
- * Copyright Sonic Network Inc. 2005
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_wavefile.c
+ *
+ * Contents and purpose:
+ * This file implements the wave file parser.
+ *
+ * Copyright Sonic Network Inc. 2005
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,849 +19,849 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 852 $
- * $Date: 2007-09-04 11:43:49 -0700 (Tue, 04 Sep 2007) $
- *----------------------------------------------------------------------------
-*/
-
-#include "eas_data.h"
-#include "eas_report.h"
-#include "eas_host.h"
-#include "eas_config.h"
-#include "eas_parser.h"
-#include "eas_pcm.h"
-#include "eas_wavefile.h"
-
-/* lint is choking on the ARM math.h file, so we declare the log10 function here */
-extern double log10(double x);
-
-/* increase gain to compensate for loss in mixer */
-#define WAVE_GAIN_OFFSET 6
-
-/* constant for 1200 / log10(2.0) */
-#define PITCH_CENTS_CONVERSION 3986.313714
-
-/*----------------------------------------------------------------------------
- * WAVE file defines
- *----------------------------------------------------------------------------
-*/
-/* RIFF chunks */
-#define CHUNK_TYPE(a,b,c,d) ( \
- ( ((EAS_U32)(a) & 0xFF) << 24 ) \
- + ( ((EAS_U32)(b) & 0xFF) << 16 ) \
- + ( ((EAS_U32)(c) & 0xFF) << 8 ) \
- + ( ((EAS_U32)(d) & 0xFF) ) )
-
-#define CHUNK_RIFF CHUNK_TYPE('R','I','F','F')
-#define CHUNK_WAVE CHUNK_TYPE('W','A','V','E')
-#define CHUNK_FMT CHUNK_TYPE('f','m','t',' ')
-#define CHUNK_DATA CHUNK_TYPE('d','a','t','a')
-#define CHUNK_LIST CHUNK_TYPE('L','I','S','T')
-#define CHUNK_INFO CHUNK_TYPE('I','N','F','O')
-#define CHUNK_INAM CHUNK_TYPE('I','N','A','M')
-#define CHUNK_ICOP CHUNK_TYPE('I','C','O','P')
-#define CHUNK_IART CHUNK_TYPE('I','A','R','T')
-
-/* wave file format identifiers */
-#define WAVE_FORMAT_PCM 0x0001
-#define WAVE_FORMAT_IMA_ADPCM 0x0011
-
-/* file size for streamed file */
-#define FILE_SIZE_STREAMING 0x80000000
-
-/*----------------------------------------------------------------------------
- * prototypes
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT WaveCheckFileType (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle, EAS_VOID_PTR *pHandle, EAS_I32 offset);
-static EAS_RESULT WavePrepare (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
-static EAS_RESULT WaveState (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_STATE *pState);
-static EAS_RESULT WaveClose (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
-static EAS_RESULT WaveReset (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
-static EAS_RESULT WaveLocate (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 time, EAS_BOOL *pParserLocate);
-static EAS_RESULT WavePause (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
-static EAS_RESULT WaveResume (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
-static EAS_RESULT WaveSetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value);
-static EAS_RESULT WaveGetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue);
-static EAS_RESULT WaveParseHeader (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle, S_WAVE_STATE *pWaveData);
-static EAS_RESULT WaveGetMetaData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 *pMediaLength);
-
-#ifdef MMAPI_SUPPORT
-static EAS_RESULT SaveFmtChunk (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle, S_WAVE_STATE *pWaveData, EAS_I32 size);
-#endif
-
-/*----------------------------------------------------------------------------
- *
- * EAS_Wave_Parser
- *
- * This structure contains the functional interface for the Wave file parser
- *----------------------------------------------------------------------------
-*/
-const S_FILE_PARSER_INTERFACE EAS_Wave_Parser =
-{
- WaveCheckFileType,
- WavePrepare,
- NULL,
- NULL,
- WaveState,
- WaveClose,
- WaveReset,
- WavePause,
- WaveResume,
- WaveLocate,
- WaveSetData,
- WaveGetData,
- WaveGetMetaData
-};
-
-/*----------------------------------------------------------------------------
- * WaveCheckFileType()
- *----------------------------------------------------------------------------
- * Purpose:
- * Check the file type to see if we can parse it
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT WaveCheckFileType (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle, EAS_VOID_PTR *pHandle, EAS_I32 offset)
-{
- S_WAVE_STATE *pWaveData;
-
- /* zero the memory to insure complete initialization */
- *pHandle = NULL;
-
- /* read the file header */
- if (WaveParseHeader(pEASData, fileHandle, NULL) == EAS_SUCCESS)
- {
-
- /* check for static memory allocation */
- if (pEASData->staticMemoryModel)
- pWaveData = EAS_CMEnumData(EAS_CM_WAVE_DATA);
- else
- pWaveData = EAS_HWMalloc(pEASData->hwInstData, sizeof(S_WAVE_STATE));
- if (!pWaveData)
- return EAS_ERROR_MALLOC_FAILED;
- EAS_HWMemSet(pWaveData, 0, sizeof(S_WAVE_STATE));
-
- /* return a pointer to the instance data */
- pWaveData->fileHandle = fileHandle;
- pWaveData->fileOffset = offset;
- *pHandle = pWaveData;
- }
-
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * WavePrepare()
- *----------------------------------------------------------------------------
- * Purpose:
- * Prepare to parse the file.
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT WavePrepare (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
-{
- S_WAVE_STATE *pWaveData;
- EAS_RESULT result;
-
- /* validate parser state */
- pWaveData = (S_WAVE_STATE*) pInstData;
- if (pWaveData->streamHandle != NULL)
- return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
-
- /* back to start of file */
- pWaveData->time = 0;
- if ((result = EAS_HWFileSeek(pEASData->hwInstData, pWaveData->fileHandle, pWaveData->fileOffset)) != EAS_SUCCESS)
- return result;
-
- /* parse the file header */
- if ((result = WaveParseHeader(pEASData, pWaveData->fileHandle, pWaveData)) != EAS_SUCCESS)
- return result;
-
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * WaveState()
- *----------------------------------------------------------------------------
- * Purpose:
- * Returns the current state of the stream
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- * pState - pointer to variable to store state
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- * Notes:
- * This interface is also exposed in the internal library for use by the other modules.
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT WaveState (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_STATE *pState)
-{
- S_WAVE_STATE *pWaveData;
-
- /* return current state */
- pWaveData = (S_WAVE_STATE*) pInstData;
- if (pWaveData->streamHandle)
- return EAS_PEState(pEASData, pWaveData->streamHandle, pState);
-
- /* if no stream handle, and time is not zero, we are done */
- if (pWaveData->time > 0)
- *pState = EAS_STATE_STOPPED;
- else
- *pState = EAS_STATE_OPEN;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * WaveClose()
- *----------------------------------------------------------------------------
- * Purpose:
- * Close the file and clean up
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT WaveClose (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
-{
- S_WAVE_STATE *pWaveData;
- EAS_RESULT result;
-
- pWaveData = (S_WAVE_STATE*) pInstData;
-
- /* close the stream */
- if (pWaveData->streamHandle)
- {
- if ((result = EAS_PEClose(pEASData, pWaveData->streamHandle)) != EAS_SUCCESS)
- return result;
- pWaveData->streamHandle = NULL;
- }
-
- /* if using dynamic memory, free it */
- if (!pEASData->staticMemoryModel)
- {
-
-#ifdef MMAPI_SUPPORT
- /* need to free the fmt chunk */
- if (pWaveData->fmtChunk != NULL)
- EAS_HWFree(pEASData->hwInstData, pWaveData->fmtChunk);
-#endif
-
- /* free the instance data */
- EAS_HWFree(pEASData->hwInstData, pWaveData);
-
- }
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * WaveReset()
- *----------------------------------------------------------------------------
- * Purpose:
- * Reset the sequencer. Used for locating backwards in the file.
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT WaveReset (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
-{
- EAS_PCM_HANDLE streamHandle;
-
- /* reset to first byte of data in the stream */
- streamHandle = ((S_WAVE_STATE*)pInstData)->streamHandle;
- if (streamHandle)
- return EAS_PEReset(pEASData, streamHandle);
- return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
-}
-
-/*----------------------------------------------------------------------------
- * WaveLocate()
- *----------------------------------------------------------------------------
- * Purpose:
- * Rewind/fast-forward in file.
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- * time - time (in msecs)
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, pParserLocate) reserved for future use */
-static EAS_RESULT WaveLocate (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 time, EAS_BOOL *pParserLocate)
-{
- EAS_PCM_HANDLE streamHandle;
-
- /* reset to first byte of data in the stream */
- streamHandle = ((S_WAVE_STATE*)pInstData)->streamHandle;
- if (streamHandle)
- return EAS_PELocate(pEASData, streamHandle, time);
- return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
-}
-
-/*----------------------------------------------------------------------------
- * WavePause()
- *----------------------------------------------------------------------------
- * Purpose:
- * Mute and stop rendering a PCM stream. Sets the gain target to zero and stops the playback
- * at the end of the next audio frame.
- *
- * Inputs:
- * pEASData - pointer to EAS library instance data
- * handle - pointer to S_WAVE_STATE for this stream
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, pEASData) reserved for future use */
-static EAS_RESULT WavePause (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
-{
- EAS_PCM_HANDLE streamHandle;
-
- /* pause the stream */
- streamHandle = ((S_WAVE_STATE*)pInstData)->streamHandle;
- if (streamHandle)
- return EAS_PEPause(pEASData, streamHandle);
- return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
-}
-
-/*----------------------------------------------------------------------------
- * WaveResume()
- *----------------------------------------------------------------------------
- * Purpose:
- * Resume rendering a PCM stream. Sets the gain target back to its
- * previous setting and restarts playback at the end of the next audio
- * frame.
- *
- * Inputs:
- * pEASData - pointer to EAS library instance data
- * handle - pointer to S_WAVE_STATE for this stream
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, pEASData) reserved for future use */
-static EAS_RESULT WaveResume (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
-{
- EAS_PCM_HANDLE streamHandle;
-
- /* resume the stream */
- streamHandle = ((S_WAVE_STATE*)pInstData)->streamHandle;
- if (streamHandle)
- return EAS_PEResume(pEASData, streamHandle);
- return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
-}
-
-/*----------------------------------------------------------------------------
- * WaveSetData()
- *----------------------------------------------------------------------------
- * Purpose:
- *
- * Inputs:
- * pEASData - pointer to EAS library instance data
- * handle - pointer to S_WAVE_STATE for this stream
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT WaveSetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value)
-{
- S_WAVE_STATE *pWaveData = (S_WAVE_STATE*) pInstData;
-
- switch (param)
- {
- /* set metadata callback */
- case PARSER_DATA_METADATA_CB:
- EAS_HWMemCpy(&pWaveData->metadata, (void*) value, sizeof(S_METADATA_CB));
- return EAS_SUCCESS;
-
- case PARSER_DATA_PLAYBACK_RATE:
- value = (EAS_I32) (PITCH_CENTS_CONVERSION * log10((double) value / (double) (1 << 28)));
- return EAS_PEUpdatePitch(pEASData, pWaveData->streamHandle, (EAS_I16) value);
-
- case PARSER_DATA_VOLUME:
- return EAS_PEUpdateVolume(pEASData, pWaveData->streamHandle, (EAS_I16) value);
-
- default:
- return EAS_ERROR_INVALID_PARAMETER;
- }
-}
-
-/*----------------------------------------------------------------------------
- * WaveGetData()
- *----------------------------------------------------------------------------
- * Purpose:
- *
- * Inputs:
- * pEASData - pointer to EAS library instance data
- * handle - pointer to S_WAVE_STATE for this stream
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, pEASData) reserved for future use */
-static EAS_RESULT WaveGetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue)
-{
- S_WAVE_STATE *pWaveData;
-
- pWaveData = (S_WAVE_STATE*) pInstData;
- switch (param)
- {
- /* return file type as WAVE */
- case PARSER_DATA_FILE_TYPE:
- *pValue = pWaveData->fileType;
- break;
-
-#ifdef MMAPI_SUPPORT
- /* return pointer to 'fmt' chunk */
- case PARSER_DATA_FORMAT:
- *pValue = (EAS_I32) pWaveData->fmtChunk;
- break;
-#endif
-
- case PARSER_DATA_GAIN_OFFSET:
- *pValue = WAVE_GAIN_OFFSET;
- break;
-
- default:
- return EAS_ERROR_INVALID_PARAMETER;
- }
-
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * WaveParseHeader()
- *----------------------------------------------------------------------------
- * Purpose:
- * Parse the WAVE file header.
- *
- * Inputs:
- * pEASData - pointer to EAS library instance data
- * handle - pointer to S_WAVE_STATE for this stream
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT WaveParseHeader (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle, S_WAVE_STATE *pWaveData)
-{
- S_PCM_OPEN_PARAMS params;
- EAS_RESULT result;
- EAS_U32 tag;
- EAS_U32 fileSize;
- EAS_U32 size;
- EAS_I32 pos;
- EAS_I32 audioOffset;
- EAS_U16 usTemp;
- EAS_BOOL parseDone;
- EAS_U32 avgBytesPerSec;
-
- /* init some data (and keep lint happy) */
- params.sampleRate = 0;
- params.size = 0;
- audioOffset = 0;
- params.decoder = 0;
- params.blockSize = 0;
- params.pCallbackFunc = NULL;
- params.cbInstData = NULL;
- params.loopSamples = 0;
- params.fileHandle = fileHandle;
- params.volume = 0x7fff;
- params.envData = 0;
- avgBytesPerSec = 8000;
-
- /* check for 'RIFF' tag */
- if ((result = EAS_HWGetDWord(pEASData->hwInstData, fileHandle, &tag, EAS_TRUE)) != EAS_FALSE)
- return result;
- if (tag != CHUNK_RIFF)
- return EAS_ERROR_UNRECOGNIZED_FORMAT;
-
- /* get size */
- if ((result = EAS_HWGetDWord(pEASData->hwInstData, fileHandle, &fileSize, EAS_FALSE)) != EAS_FALSE)
- return result;
-
- /* check for 'WAVE' tag */
- if ((result = EAS_HWGetDWord(pEASData->hwInstData, fileHandle, &tag, EAS_TRUE)) != EAS_FALSE)
- return result;
- if (tag != CHUNK_WAVE)
- return EAS_ERROR_UNRECOGNIZED_FORMAT;
-
- /* this is enough to say we recognize the file */
- if (pWaveData == NULL)
- return EAS_SUCCESS;
-
- /* check for streaming mode */
- pWaveData->flags = 0;
- pWaveData->mediaLength = -1;
- pWaveData->infoChunkPos = -1;
- pWaveData->infoChunkSize = -1;
- if (fileSize== FILE_SIZE_STREAMING)
- {
- pWaveData->flags |= PCM_FLAGS_STREAMING;
- fileSize = 0x7fffffff;
- }
-
- /* find out where we're at */
- if ((result = EAS_HWFilePos(pEASData->hwInstData, fileHandle, &pos)) != EAS_SUCCESS)
- return result;
- fileSize -= 4;
-
- parseDone = EAS_FALSE;
- for (;;)
- {
- /* get tag and size for next chunk */
- if ((result = EAS_HWGetDWord(pEASData->hwInstData, fileHandle, &tag, EAS_TRUE)) != EAS_FALSE)
- return result;
- if ((result = EAS_HWGetDWord(pEASData->hwInstData, fileHandle, &size, EAS_FALSE)) != EAS_FALSE)
- return result;
-
- /* process chunk */
- pos += 8;
- switch (tag)
- {
- case CHUNK_FMT:
-
-#ifdef MMAPI_SUPPORT
- if ((result = SaveFmtChunk(pEASData, fileHandle, pWaveData, (EAS_I32) size)) != EAS_SUCCESS)
- return result;
-#endif
-
- /* get audio format */
- if ((result = EAS_HWGetWord(pEASData->hwInstData, fileHandle, &usTemp, EAS_FALSE)) != EAS_FALSE)
- return result;
- if (usTemp == WAVE_FORMAT_PCM)
- {
- params.decoder = EAS_DECODER_PCM;
- pWaveData->fileType = EAS_FILE_WAVE_PCM;
- }
- else if (usTemp == WAVE_FORMAT_IMA_ADPCM)
- {
- params.decoder = EAS_DECODER_IMA_ADPCM;
- pWaveData->fileType = EAS_FILE_WAVE_IMA_ADPCM;
- }
- else
- return EAS_ERROR_UNRECOGNIZED_FORMAT;
-
- /* get number of channels */
- if ((result = EAS_HWGetWord(pEASData->hwInstData, fileHandle, &usTemp, EAS_FALSE)) != EAS_FALSE)
- return result;
- if (usTemp == 2)
- pWaveData->flags |= PCM_FLAGS_STEREO;
- else if (usTemp != 1)
- return EAS_ERROR_UNRECOGNIZED_FORMAT;
-
- /* get sample rate */
- if ((result = EAS_HWGetDWord(pEASData->hwInstData, fileHandle, &params.sampleRate, EAS_FALSE)) != EAS_FALSE)
- return result;
-
- /* get stream rate */
- if ((result = EAS_HWGetDWord(pEASData->hwInstData, fileHandle, &avgBytesPerSec, EAS_FALSE)) != EAS_FALSE)
- return result;
-
- /* get block alignment */
- if ((result = EAS_HWGetWord(pEASData->hwInstData, fileHandle, &usTemp, EAS_FALSE)) != EAS_FALSE)
- return result;
- params.blockSize = usTemp;
-
- /* get bits per sample */
- if ((result = EAS_HWGetWord(pEASData->hwInstData, fileHandle, &usTemp, EAS_FALSE)) != EAS_FALSE)
- return result;
-
- /* PCM, must be 8 or 16 bit samples */
- if (params.decoder == EAS_DECODER_PCM)
- {
- if (usTemp == 8)
- pWaveData->flags |= PCM_FLAGS_8_BIT | PCM_FLAGS_UNSIGNED;
- else if (usTemp != 16)
- return EAS_ERROR_UNRECOGNIZED_FORMAT;
- }
-
- /* for IMA ADPCM, we only support mono 4-bit ADPCM */
- else
- {
- if ((usTemp != 4) || (pWaveData->flags & PCM_FLAGS_STEREO))
- return EAS_ERROR_UNRECOGNIZED_FORMAT;
- }
-
- break;
-
- case CHUNK_DATA:
- audioOffset = pos;
- if (pWaveData->flags & PCM_FLAGS_STREAMING)
- {
- params.size = 0x7fffffff;
- parseDone = EAS_TRUE;
- }
- else
- {
- params.size = (EAS_I32) size;
- params.loopStart = size;
- /* use more accurate method if possible */
- if (size <= (0x7fffffff / 1000))
- pWaveData->mediaLength = (EAS_I32) ((size * 1000) / avgBytesPerSec);
- else
- pWaveData->mediaLength = (EAS_I32) (size / (avgBytesPerSec / 1000));
- }
- break;
-
- case CHUNK_LIST:
- /* get the list type */
- if ((result = EAS_HWGetDWord(pEASData->hwInstData, fileHandle, &tag, EAS_TRUE)) != EAS_FALSE)
- return result;
- if (tag == CHUNK_INFO)
- {
- pWaveData->infoChunkPos = pos + 4;
- pWaveData->infoChunkSize = (EAS_I32) size - 4;
- }
- break;
-
- default:
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "WaveParseHeader: %c%c%c%c chunk - %d byte(s) ignored\n",
- (char) (tag >> 24), (char) (tag >> 16), (char) (tag >> 8), (char) tag, size); */ }
- break;
- }
-
- if (parseDone)
- break;
-
- /* subtract header size */
- fileSize -= 8;
-
- /* account for zero-padding on odd length chunks */
- if (size & 1)
- size++;
-
- /* this check works for files with odd length last chunk and no zero-pad */
- if (size >= fileSize)
- {
- if (size > fileSize)
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "WaveParseHeader: '%c%c%c%c' chunk size exceeds length of file or is not zero-padded\n",
- (char) (tag >> 24), (char) (tag >> 16), (char) (tag >> 8), (char) tag, size); */ }
- break;
- }
-
- /* subtract size of data chunk (including any zero-pad) */
- fileSize -= size;
-
- /* seek to next chunk */
- pos += (EAS_I32) size;
- if ((result = EAS_HWFileSeek(pEASData->hwInstData, fileHandle, pos)) != EAS_SUCCESS)
- return result;
- }
-
- /* check for valid header */
- if ((params.sampleRate == 0) || (params.size == 0))
- return EAS_ERROR_UNRECOGNIZED_FORMAT;
-
- /* save the pertinent information */
- pWaveData->audioOffset = audioOffset;
- params.flags = pWaveData->flags;
-
- /* seek to data */
- if ((result = EAS_HWFileSeek(pEASData->hwInstData, fileHandle, audioOffset)) != EAS_SUCCESS)
- return result;
-
- /* open a stream in the PCM engine */
- return EAS_PEOpenStream(pEASData, &params, &pWaveData->streamHandle);
-}
-
-/*----------------------------------------------------------------------------
- * WaveGetMetaData()
- *----------------------------------------------------------------------------
- * Purpose:
- * Process the INFO chunk and return metadata to host
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT WaveGetMetaData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 *pMediaLength)
-{
- S_WAVE_STATE *pWaveData;
- EAS_RESULT result;
- EAS_I32 pos;
- EAS_U32 size;
- EAS_I32 infoSize;
- EAS_U32 tag;
- EAS_I32 restorePos;
- E_EAS_METADATA_TYPE metaType;
- EAS_I32 metaLen;
-
- /* get current position so we can restore it */
- pWaveData = (S_WAVE_STATE*) pInstData;
-
- /* return media length */
- *pMediaLength = pWaveData->mediaLength;
-
- /* did we encounter an INFO chunk? */
- if (pWaveData->infoChunkPos < 0)
- return EAS_SUCCESS;
-
- if ((result = EAS_HWFilePos(pEASData->hwInstData, pWaveData->fileHandle, &restorePos)) != EAS_SUCCESS)
- return result;
-
- /* offset to start of first chunk in INFO chunk */
- pos = pWaveData->infoChunkPos;
- infoSize = pWaveData->infoChunkSize;
-
- /* read all the chunks in the INFO chunk */
- for (;;)
- {
-
- /* seek to next chunk */
- if ((result = EAS_HWFileSeek(pEASData->hwInstData, pWaveData->fileHandle, pos)) != EAS_SUCCESS)
- return result;
-
- /* get tag and size for next chunk */
- if ((result = EAS_HWGetDWord(pEASData->hwInstData, pWaveData->fileHandle, &tag, EAS_TRUE)) != EAS_FALSE)
- return result;
- if ((result = EAS_HWGetDWord(pEASData->hwInstData, pWaveData->fileHandle, &size, EAS_FALSE)) != EAS_FALSE)
- return result;
-
- /* process chunk */
- pos += 8;
- metaType = EAS_METADATA_UNKNOWN;
- switch (tag)
- {
- case CHUNK_INAM:
- metaType = EAS_METADATA_TITLE;
- break;
-
- case CHUNK_IART:
- metaType = EAS_METADATA_AUTHOR;
- break;
-
- case CHUNK_ICOP:
- metaType = EAS_METADATA_COPYRIGHT;
- break;
-
- default:
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "WaveParseHeader: %c%c%c%c chunk - %d byte(s) ignored\n",
- (char) (tag >> 24), (char) (tag >> 16), (char) (tag >> 8), (char) tag, size); */ }
- break;
- }
-
- /* process known metadata */
- if (metaType != EAS_METADATA_UNKNOWN)
- {
- metaLen = pWaveData->metadata.bufferSize - 1;
- if (metaLen > (EAS_I32) size)
- metaLen = (EAS_I32) size;
- if ((result = EAS_HWReadFile(pEASData->hwInstData, pWaveData->fileHandle, pWaveData->metadata.buffer, metaLen, &metaLen)) != EAS_SUCCESS)
- return result;
- pWaveData->metadata.buffer[metaLen] = 0;
- pWaveData->metadata.callback(metaType, pWaveData->metadata.buffer, pWaveData->metadata.pUserData);
- }
-
- /* subtract this block */
- if (size & 1)
- size++;
- infoSize -= (EAS_I32) size + 8;
- if (infoSize == 0)
- break;
- pos += (EAS_I32) size;
- }
-
-
- /* restore original position */
- return EAS_HWFileSeek(pEASData->hwInstData, pWaveData->fileHandle, restorePos);
-}
-
-#ifdef MMAPI_SUPPORT
-/*----------------------------------------------------------------------------
- * SaveFmtChunk()
- *----------------------------------------------------------------------------
- * Purpose:
- * Save the fmt chunk for the MMAPI library
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT SaveFmtChunk (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle, S_WAVE_STATE *pWaveData, EAS_I32 fmtSize)
-{
- EAS_RESULT result;
- EAS_I32 pos;
- EAS_I32 count;
-
- /* save current file position */
- if ((result = EAS_HWFilePos(pEASData->hwInstData, fileHandle, &pos)) != EAS_SUCCESS)
- return result;
-
- /* allocate a chunk of memory */
- pWaveData->fmtChunk = EAS_HWMalloc(pEASData->hwInstData, fmtSize);
- if (!pWaveData->fmtChunk)
- return EAS_ERROR_MALLOC_FAILED;
-
- /* read the fmt chunk into memory */
- if ((result = EAS_HWReadFile(pEASData->hwInstData, fileHandle, pWaveData->fmtChunk, fmtSize, &count)) != EAS_SUCCESS)
- return result;
- if (count != fmtSize)
- return EAS_ERROR_FILE_READ_FAILED;
-
- /* restore file position */
- return EAS_HWFileSeek(pEASData->hwInstData, fileHandle, pos);
-}
-#endif
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 852 $
+ * $Date: 2007-09-04 11:43:49 -0700 (Tue, 04 Sep 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+#include "eas_data.h"
+#include "eas_report.h"
+#include "eas_host.h"
+#include "eas_config.h"
+#include "eas_parser.h"
+#include "eas_pcm.h"
+#include "eas_wavefile.h"
+
+/* lint is choking on the ARM math.h file, so we declare the log10 function here */
+extern double log10(double x);
+
+/* increase gain to compensate for loss in mixer */
+#define WAVE_GAIN_OFFSET 6
+
+/* constant for 1200 / log10(2.0) */
+#define PITCH_CENTS_CONVERSION 3986.313714
+
+/*----------------------------------------------------------------------------
+ * WAVE file defines
+ *----------------------------------------------------------------------------
+*/
+/* RIFF chunks */
+#define CHUNK_TYPE(a,b,c,d) ( \
+ ( ((EAS_U32)(a) & 0xFF) << 24 ) \
+ + ( ((EAS_U32)(b) & 0xFF) << 16 ) \
+ + ( ((EAS_U32)(c) & 0xFF) << 8 ) \
+ + ( ((EAS_U32)(d) & 0xFF) ) )
+
+#define CHUNK_RIFF CHUNK_TYPE('R','I','F','F')
+#define CHUNK_WAVE CHUNK_TYPE('W','A','V','E')
+#define CHUNK_FMT CHUNK_TYPE('f','m','t',' ')
+#define CHUNK_DATA CHUNK_TYPE('d','a','t','a')
+#define CHUNK_LIST CHUNK_TYPE('L','I','S','T')
+#define CHUNK_INFO CHUNK_TYPE('I','N','F','O')
+#define CHUNK_INAM CHUNK_TYPE('I','N','A','M')
+#define CHUNK_ICOP CHUNK_TYPE('I','C','O','P')
+#define CHUNK_IART CHUNK_TYPE('I','A','R','T')
+
+/* wave file format identifiers */
+#define WAVE_FORMAT_PCM 0x0001
+#define WAVE_FORMAT_IMA_ADPCM 0x0011
+
+/* file size for streamed file */
+#define FILE_SIZE_STREAMING 0x80000000
+
+/*----------------------------------------------------------------------------
+ * prototypes
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT WaveCheckFileType (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle, EAS_VOID_PTR *pHandle, EAS_I32 offset);
+static EAS_RESULT WavePrepare (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
+static EAS_RESULT WaveState (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_STATE *pState);
+static EAS_RESULT WaveClose (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
+static EAS_RESULT WaveReset (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
+static EAS_RESULT WaveLocate (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 time, EAS_BOOL *pParserLocate);
+static EAS_RESULT WavePause (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
+static EAS_RESULT WaveResume (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
+static EAS_RESULT WaveSetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value);
+static EAS_RESULT WaveGetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue);
+static EAS_RESULT WaveParseHeader (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle, S_WAVE_STATE *pWaveData);
+static EAS_RESULT WaveGetMetaData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 *pMediaLength);
+
+#ifdef MMAPI_SUPPORT
+static EAS_RESULT SaveFmtChunk (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle, S_WAVE_STATE *pWaveData, EAS_I32 size);
+#endif
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_Wave_Parser
+ *
+ * This structure contains the functional interface for the Wave file parser
+ *----------------------------------------------------------------------------
+*/
+const S_FILE_PARSER_INTERFACE EAS_Wave_Parser =
+{
+ WaveCheckFileType,
+ WavePrepare,
+ NULL,
+ NULL,
+ WaveState,
+ WaveClose,
+ WaveReset,
+ WavePause,
+ WaveResume,
+ WaveLocate,
+ WaveSetData,
+ WaveGetData,
+ WaveGetMetaData
+};
+
+/*----------------------------------------------------------------------------
+ * WaveCheckFileType()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Check the file type to see if we can parse it
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT WaveCheckFileType (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle, EAS_VOID_PTR *pHandle, EAS_I32 offset)
+{
+ S_WAVE_STATE *pWaveData;
+
+ /* zero the memory to insure complete initialization */
+ *pHandle = NULL;
+
+ /* read the file header */
+ if (WaveParseHeader(pEASData, fileHandle, NULL) == EAS_SUCCESS)
+ {
+
+ /* check for static memory allocation */
+ if (pEASData->staticMemoryModel)
+ pWaveData = EAS_CMEnumData(EAS_CM_WAVE_DATA);
+ else
+ pWaveData = EAS_HWMalloc(pEASData->hwInstData, sizeof(S_WAVE_STATE));
+ if (!pWaveData)
+ return EAS_ERROR_MALLOC_FAILED;
+ EAS_HWMemSet(pWaveData, 0, sizeof(S_WAVE_STATE));
+
+ /* return a pointer to the instance data */
+ pWaveData->fileHandle = fileHandle;
+ pWaveData->fileOffset = offset;
+ *pHandle = pWaveData;
+ }
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * WavePrepare()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Prepare to parse the file.
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT WavePrepare (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
+{
+ S_WAVE_STATE *pWaveData;
+ EAS_RESULT result;
+
+ /* validate parser state */
+ pWaveData = (S_WAVE_STATE*) pInstData;
+ if (pWaveData->streamHandle != NULL)
+ return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
+
+ /* back to start of file */
+ pWaveData->time = 0;
+ if ((result = EAS_HWFileSeek(pEASData->hwInstData, pWaveData->fileHandle, pWaveData->fileOffset)) != EAS_SUCCESS)
+ return result;
+
+ /* parse the file header */
+ if ((result = WaveParseHeader(pEASData, pWaveData->fileHandle, pWaveData)) != EAS_SUCCESS)
+ return result;
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * WaveState()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Returns the current state of the stream
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ * pState - pointer to variable to store state
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ * Notes:
+ * This interface is also exposed in the internal library for use by the other modules.
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT WaveState (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_STATE *pState)
+{
+ S_WAVE_STATE *pWaveData;
+
+ /* return current state */
+ pWaveData = (S_WAVE_STATE*) pInstData;
+ if (pWaveData->streamHandle)
+ return EAS_PEState(pEASData, pWaveData->streamHandle, pState);
+
+ /* if no stream handle, and time is not zero, we are done */
+ if (pWaveData->time > 0)
+ *pState = EAS_STATE_STOPPED;
+ else
+ *pState = EAS_STATE_OPEN;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * WaveClose()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Close the file and clean up
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT WaveClose (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
+{
+ S_WAVE_STATE *pWaveData;
+ EAS_RESULT result;
+
+ pWaveData = (S_WAVE_STATE*) pInstData;
+
+ /* close the stream */
+ if (pWaveData->streamHandle)
+ {
+ if ((result = EAS_PEClose(pEASData, pWaveData->streamHandle)) != EAS_SUCCESS)
+ return result;
+ pWaveData->streamHandle = NULL;
+ }
+
+ /* if using dynamic memory, free it */
+ if (!pEASData->staticMemoryModel)
+ {
+
+#ifdef MMAPI_SUPPORT
+ /* need to free the fmt chunk */
+ if (pWaveData->fmtChunk != NULL)
+ EAS_HWFree(pEASData->hwInstData, pWaveData->fmtChunk);
+#endif
+
+ /* free the instance data */
+ EAS_HWFree(pEASData->hwInstData, pWaveData);
+
+ }
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * WaveReset()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Reset the sequencer. Used for locating backwards in the file.
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT WaveReset (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
+{
+ EAS_PCM_HANDLE streamHandle;
+
+ /* reset to first byte of data in the stream */
+ streamHandle = ((S_WAVE_STATE*)pInstData)->streamHandle;
+ if (streamHandle)
+ return EAS_PEReset(pEASData, streamHandle);
+ return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
+}
+
+/*----------------------------------------------------------------------------
+ * WaveLocate()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Rewind/fast-forward in file.
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ * time - time (in msecs)
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pParserLocate) reserved for future use */
+static EAS_RESULT WaveLocate (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 time, EAS_BOOL *pParserLocate)
+{
+ EAS_PCM_HANDLE streamHandle;
+
+ /* reset to first byte of data in the stream */
+ streamHandle = ((S_WAVE_STATE*)pInstData)->streamHandle;
+ if (streamHandle)
+ return EAS_PELocate(pEASData, streamHandle, time);
+ return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
+}
+
+/*----------------------------------------------------------------------------
+ * WavePause()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Mute and stop rendering a PCM stream. Sets the gain target to zero and stops the playback
+ * at the end of the next audio frame.
+ *
+ * Inputs:
+ * pEASData - pointer to EAS library instance data
+ * handle - pointer to S_WAVE_STATE for this stream
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pEASData) reserved for future use */
+static EAS_RESULT WavePause (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
+{
+ EAS_PCM_HANDLE streamHandle;
+
+ /* pause the stream */
+ streamHandle = ((S_WAVE_STATE*)pInstData)->streamHandle;
+ if (streamHandle)
+ return EAS_PEPause(pEASData, streamHandle);
+ return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
+}
+
+/*----------------------------------------------------------------------------
+ * WaveResume()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Resume rendering a PCM stream. Sets the gain target back to its
+ * previous setting and restarts playback at the end of the next audio
+ * frame.
+ *
+ * Inputs:
+ * pEASData - pointer to EAS library instance data
+ * handle - pointer to S_WAVE_STATE for this stream
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pEASData) reserved for future use */
+static EAS_RESULT WaveResume (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
+{
+ EAS_PCM_HANDLE streamHandle;
+
+ /* resume the stream */
+ streamHandle = ((S_WAVE_STATE*)pInstData)->streamHandle;
+ if (streamHandle)
+ return EAS_PEResume(pEASData, streamHandle);
+ return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
+}
+
+/*----------------------------------------------------------------------------
+ * WaveSetData()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ *
+ * Inputs:
+ * pEASData - pointer to EAS library instance data
+ * handle - pointer to S_WAVE_STATE for this stream
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT WaveSetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value)
+{
+ S_WAVE_STATE *pWaveData = (S_WAVE_STATE*) pInstData;
+
+ switch (param)
+ {
+ /* set metadata callback */
+ case PARSER_DATA_METADATA_CB:
+ EAS_HWMemCpy(&pWaveData->metadata, (void*) value, sizeof(S_METADATA_CB));
+ return EAS_SUCCESS;
+
+ case PARSER_DATA_PLAYBACK_RATE:
+ value = (EAS_I32) (PITCH_CENTS_CONVERSION * log10((double) value / (double) (1 << 28)));
+ return EAS_PEUpdatePitch(pEASData, pWaveData->streamHandle, (EAS_I16) value);
+
+ case PARSER_DATA_VOLUME:
+ return EAS_PEUpdateVolume(pEASData, pWaveData->streamHandle, (EAS_I16) value);
+
+ default:
+ return EAS_ERROR_INVALID_PARAMETER;
+ }
+}
+
+/*----------------------------------------------------------------------------
+ * WaveGetData()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ *
+ * Inputs:
+ * pEASData - pointer to EAS library instance data
+ * handle - pointer to S_WAVE_STATE for this stream
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pEASData) reserved for future use */
+static EAS_RESULT WaveGetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue)
+{
+ S_WAVE_STATE *pWaveData;
+
+ pWaveData = (S_WAVE_STATE*) pInstData;
+ switch (param)
+ {
+ /* return file type as WAVE */
+ case PARSER_DATA_FILE_TYPE:
+ *pValue = pWaveData->fileType;
+ break;
+
+#ifdef MMAPI_SUPPORT
+ /* return pointer to 'fmt' chunk */
+ case PARSER_DATA_FORMAT:
+ *pValue = (EAS_I32) pWaveData->fmtChunk;
+ break;
+#endif
+
+ case PARSER_DATA_GAIN_OFFSET:
+ *pValue = WAVE_GAIN_OFFSET;
+ break;
+
+ default:
+ return EAS_ERROR_INVALID_PARAMETER;
+ }
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * WaveParseHeader()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Parse the WAVE file header.
+ *
+ * Inputs:
+ * pEASData - pointer to EAS library instance data
+ * handle - pointer to S_WAVE_STATE for this stream
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT WaveParseHeader (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle, S_WAVE_STATE *pWaveData)
+{
+ S_PCM_OPEN_PARAMS params;
+ EAS_RESULT result;
+ EAS_U32 tag;
+ EAS_U32 fileSize;
+ EAS_U32 size;
+ EAS_I32 pos;
+ EAS_I32 audioOffset;
+ EAS_U16 usTemp;
+ EAS_BOOL parseDone;
+ EAS_U32 avgBytesPerSec;
+
+ /* init some data (and keep lint happy) */
+ params.sampleRate = 0;
+ params.size = 0;
+ audioOffset = 0;
+ params.decoder = 0;
+ params.blockSize = 0;
+ params.pCallbackFunc = NULL;
+ params.cbInstData = NULL;
+ params.loopSamples = 0;
+ params.fileHandle = fileHandle;
+ params.volume = 0x7fff;
+ params.envData = 0;
+ avgBytesPerSec = 8000;
+
+ /* check for 'RIFF' tag */
+ if ((result = EAS_HWGetDWord(pEASData->hwInstData, fileHandle, &tag, EAS_TRUE)) != EAS_FALSE)
+ return result;
+ if (tag != CHUNK_RIFF)
+ return EAS_ERROR_UNRECOGNIZED_FORMAT;
+
+ /* get size */
+ if ((result = EAS_HWGetDWord(pEASData->hwInstData, fileHandle, &fileSize, EAS_FALSE)) != EAS_FALSE)
+ return result;
+
+ /* check for 'WAVE' tag */
+ if ((result = EAS_HWGetDWord(pEASData->hwInstData, fileHandle, &tag, EAS_TRUE)) != EAS_FALSE)
+ return result;
+ if (tag != CHUNK_WAVE)
+ return EAS_ERROR_UNRECOGNIZED_FORMAT;
+
+ /* this is enough to say we recognize the file */
+ if (pWaveData == NULL)
+ return EAS_SUCCESS;
+
+ /* check for streaming mode */
+ pWaveData->flags = 0;
+ pWaveData->mediaLength = -1;
+ pWaveData->infoChunkPos = -1;
+ pWaveData->infoChunkSize = -1;
+ if (fileSize== FILE_SIZE_STREAMING)
+ {
+ pWaveData->flags |= PCM_FLAGS_STREAMING;
+ fileSize = 0x7fffffff;
+ }
+
+ /* find out where we're at */
+ if ((result = EAS_HWFilePos(pEASData->hwInstData, fileHandle, &pos)) != EAS_SUCCESS)
+ return result;
+ fileSize -= 4;
+
+ parseDone = EAS_FALSE;
+ for (;;)
+ {
+ /* get tag and size for next chunk */
+ if ((result = EAS_HWGetDWord(pEASData->hwInstData, fileHandle, &tag, EAS_TRUE)) != EAS_FALSE)
+ return result;
+ if ((result = EAS_HWGetDWord(pEASData->hwInstData, fileHandle, &size, EAS_FALSE)) != EAS_FALSE)
+ return result;
+
+ /* process chunk */
+ pos += 8;
+ switch (tag)
+ {
+ case CHUNK_FMT:
+
+#ifdef MMAPI_SUPPORT
+ if ((result = SaveFmtChunk(pEASData, fileHandle, pWaveData, (EAS_I32) size)) != EAS_SUCCESS)
+ return result;
+#endif
+
+ /* get audio format */
+ if ((result = EAS_HWGetWord(pEASData->hwInstData, fileHandle, &usTemp, EAS_FALSE)) != EAS_FALSE)
+ return result;
+ if (usTemp == WAVE_FORMAT_PCM)
+ {
+ params.decoder = EAS_DECODER_PCM;
+ pWaveData->fileType = EAS_FILE_WAVE_PCM;
+ }
+ else if (usTemp == WAVE_FORMAT_IMA_ADPCM)
+ {
+ params.decoder = EAS_DECODER_IMA_ADPCM;
+ pWaveData->fileType = EAS_FILE_WAVE_IMA_ADPCM;
+ }
+ else
+ return EAS_ERROR_UNRECOGNIZED_FORMAT;
+
+ /* get number of channels */
+ if ((result = EAS_HWGetWord(pEASData->hwInstData, fileHandle, &usTemp, EAS_FALSE)) != EAS_FALSE)
+ return result;
+ if (usTemp == 2)
+ pWaveData->flags |= PCM_FLAGS_STEREO;
+ else if (usTemp != 1)
+ return EAS_ERROR_UNRECOGNIZED_FORMAT;
+
+ /* get sample rate */
+ if ((result = EAS_HWGetDWord(pEASData->hwInstData, fileHandle, &params.sampleRate, EAS_FALSE)) != EAS_FALSE)
+ return result;
+
+ /* get stream rate */
+ if ((result = EAS_HWGetDWord(pEASData->hwInstData, fileHandle, &avgBytesPerSec, EAS_FALSE)) != EAS_FALSE)
+ return result;
+
+ /* get block alignment */
+ if ((result = EAS_HWGetWord(pEASData->hwInstData, fileHandle, &usTemp, EAS_FALSE)) != EAS_FALSE)
+ return result;
+ params.blockSize = usTemp;
+
+ /* get bits per sample */
+ if ((result = EAS_HWGetWord(pEASData->hwInstData, fileHandle, &usTemp, EAS_FALSE)) != EAS_FALSE)
+ return result;
+
+ /* PCM, must be 8 or 16 bit samples */
+ if (params.decoder == EAS_DECODER_PCM)
+ {
+ if (usTemp == 8)
+ pWaveData->flags |= PCM_FLAGS_8_BIT | PCM_FLAGS_UNSIGNED;
+ else if (usTemp != 16)
+ return EAS_ERROR_UNRECOGNIZED_FORMAT;
+ }
+
+ /* for IMA ADPCM, we only support mono 4-bit ADPCM */
+ else
+ {
+ if ((usTemp != 4) || (pWaveData->flags & PCM_FLAGS_STEREO))
+ return EAS_ERROR_UNRECOGNIZED_FORMAT;
+ }
+
+ break;
+
+ case CHUNK_DATA:
+ audioOffset = pos;
+ if (pWaveData->flags & PCM_FLAGS_STREAMING)
+ {
+ params.size = 0x7fffffff;
+ parseDone = EAS_TRUE;
+ }
+ else
+ {
+ params.size = (EAS_I32) size;
+ params.loopStart = size;
+ /* use more accurate method if possible */
+ if (size <= (0x7fffffff / 1000))
+ pWaveData->mediaLength = (EAS_I32) ((size * 1000) / avgBytesPerSec);
+ else
+ pWaveData->mediaLength = (EAS_I32) (size / (avgBytesPerSec / 1000));
+ }
+ break;
+
+ case CHUNK_LIST:
+ /* get the list type */
+ if ((result = EAS_HWGetDWord(pEASData->hwInstData, fileHandle, &tag, EAS_TRUE)) != EAS_FALSE)
+ return result;
+ if (tag == CHUNK_INFO)
+ {
+ pWaveData->infoChunkPos = pos + 4;
+ pWaveData->infoChunkSize = (EAS_I32) size - 4;
+ }
+ break;
+
+ default:
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "WaveParseHeader: %c%c%c%c chunk - %d byte(s) ignored\n",
+ (char) (tag >> 24), (char) (tag >> 16), (char) (tag >> 8), (char) tag, size); */ }
+ break;
+ }
+
+ if (parseDone)
+ break;
+
+ /* subtract header size */
+ fileSize -= 8;
+
+ /* account for zero-padding on odd length chunks */
+ if (size & 1)
+ size++;
+
+ /* this check works for files with odd length last chunk and no zero-pad */
+ if (size >= fileSize)
+ {
+ if (size > fileSize)
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "WaveParseHeader: '%c%c%c%c' chunk size exceeds length of file or is not zero-padded\n",
+ (char) (tag >> 24), (char) (tag >> 16), (char) (tag >> 8), (char) tag, size); */ }
+ break;
+ }
+
+ /* subtract size of data chunk (including any zero-pad) */
+ fileSize -= size;
+
+ /* seek to next chunk */
+ pos += (EAS_I32) size;
+ if ((result = EAS_HWFileSeek(pEASData->hwInstData, fileHandle, pos)) != EAS_SUCCESS)
+ return result;
+ }
+
+ /* check for valid header */
+ if ((params.sampleRate == 0) || (params.size == 0))
+ return EAS_ERROR_UNRECOGNIZED_FORMAT;
+
+ /* save the pertinent information */
+ pWaveData->audioOffset = audioOffset;
+ params.flags = pWaveData->flags;
+
+ /* seek to data */
+ if ((result = EAS_HWFileSeek(pEASData->hwInstData, fileHandle, audioOffset)) != EAS_SUCCESS)
+ return result;
+
+ /* open a stream in the PCM engine */
+ return EAS_PEOpenStream(pEASData, &params, &pWaveData->streamHandle);
+}
+
+/*----------------------------------------------------------------------------
+ * WaveGetMetaData()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Process the INFO chunk and return metadata to host
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT WaveGetMetaData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 *pMediaLength)
+{
+ S_WAVE_STATE *pWaveData;
+ EAS_RESULT result;
+ EAS_I32 pos;
+ EAS_U32 size;
+ EAS_I32 infoSize;
+ EAS_U32 tag;
+ EAS_I32 restorePos;
+ E_EAS_METADATA_TYPE metaType;
+ EAS_I32 metaLen;
+
+ /* get current position so we can restore it */
+ pWaveData = (S_WAVE_STATE*) pInstData;
+
+ /* return media length */
+ *pMediaLength = pWaveData->mediaLength;
+
+ /* did we encounter an INFO chunk? */
+ if (pWaveData->infoChunkPos < 0)
+ return EAS_SUCCESS;
+
+ if ((result = EAS_HWFilePos(pEASData->hwInstData, pWaveData->fileHandle, &restorePos)) != EAS_SUCCESS)
+ return result;
+
+ /* offset to start of first chunk in INFO chunk */
+ pos = pWaveData->infoChunkPos;
+ infoSize = pWaveData->infoChunkSize;
+
+ /* read all the chunks in the INFO chunk */
+ for (;;)
+ {
+
+ /* seek to next chunk */
+ if ((result = EAS_HWFileSeek(pEASData->hwInstData, pWaveData->fileHandle, pos)) != EAS_SUCCESS)
+ return result;
+
+ /* get tag and size for next chunk */
+ if ((result = EAS_HWGetDWord(pEASData->hwInstData, pWaveData->fileHandle, &tag, EAS_TRUE)) != EAS_FALSE)
+ return result;
+ if ((result = EAS_HWGetDWord(pEASData->hwInstData, pWaveData->fileHandle, &size, EAS_FALSE)) != EAS_FALSE)
+ return result;
+
+ /* process chunk */
+ pos += 8;
+ metaType = EAS_METADATA_UNKNOWN;
+ switch (tag)
+ {
+ case CHUNK_INAM:
+ metaType = EAS_METADATA_TITLE;
+ break;
+
+ case CHUNK_IART:
+ metaType = EAS_METADATA_AUTHOR;
+ break;
+
+ case CHUNK_ICOP:
+ metaType = EAS_METADATA_COPYRIGHT;
+ break;
+
+ default:
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "WaveParseHeader: %c%c%c%c chunk - %d byte(s) ignored\n",
+ (char) (tag >> 24), (char) (tag >> 16), (char) (tag >> 8), (char) tag, size); */ }
+ break;
+ }
+
+ /* process known metadata */
+ if (metaType != EAS_METADATA_UNKNOWN)
+ {
+ metaLen = pWaveData->metadata.bufferSize - 1;
+ if (metaLen > (EAS_I32) size)
+ metaLen = (EAS_I32) size;
+ if ((result = EAS_HWReadFile(pEASData->hwInstData, pWaveData->fileHandle, pWaveData->metadata.buffer, metaLen, &metaLen)) != EAS_SUCCESS)
+ return result;
+ pWaveData->metadata.buffer[metaLen] = 0;
+ pWaveData->metadata.callback(metaType, pWaveData->metadata.buffer, pWaveData->metadata.pUserData);
+ }
+
+ /* subtract this block */
+ if (size & 1)
+ size++;
+ infoSize -= (EAS_I32) size + 8;
+ if (infoSize == 0)
+ break;
+ pos += (EAS_I32) size;
+ }
+
+
+ /* restore original position */
+ return EAS_HWFileSeek(pEASData->hwInstData, pWaveData->fileHandle, restorePos);
+}
+
+#ifdef MMAPI_SUPPORT
+/*----------------------------------------------------------------------------
+ * SaveFmtChunk()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Save the fmt chunk for the MMAPI library
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT SaveFmtChunk (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle, S_WAVE_STATE *pWaveData, EAS_I32 fmtSize)
+{
+ EAS_RESULT result;
+ EAS_I32 pos;
+ EAS_I32 count;
+
+ /* save current file position */
+ if ((result = EAS_HWFilePos(pEASData->hwInstData, fileHandle, &pos)) != EAS_SUCCESS)
+ return result;
+
+ /* allocate a chunk of memory */
+ pWaveData->fmtChunk = EAS_HWMalloc(pEASData->hwInstData, fmtSize);
+ if (!pWaveData->fmtChunk)
+ return EAS_ERROR_MALLOC_FAILED;
+
+ /* read the fmt chunk into memory */
+ if ((result = EAS_HWReadFile(pEASData->hwInstData, fileHandle, pWaveData->fmtChunk, fmtSize, &count)) != EAS_SUCCESS)
+ return result;
+ if (count != fmtSize)
+ return EAS_ERROR_FILE_READ_FAILED;
+
+ /* restore file position */
+ return EAS_HWFileSeek(pEASData->hwInstData, fileHandle, pos);
+}
+#endif
+
diff --git a/arm-hybrid-22k/lib_src/eas_wavefile.h b/arm-hybrid-22k/lib_src/eas_wavefile.h
index b8b76df..f8814a8 100644
--- a/arm-hybrid-22k/lib_src/eas_wavefile.h
+++ b/arm-hybrid-22k/lib_src/eas_wavefile.h
@@ -1,12 +1,12 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_wavefile.h
- *
- * Contents and purpose:
- * Static data block for wave file parser.
- *
- * Copyright Sonic Network Inc. 2005
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_wavefile.h
+ *
+ * Contents and purpose:
+ * Static data block for wave file parser.
+ *
+ * Copyright Sonic Network Inc. 2005
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,45 +19,45 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 439 $
- * $Date: 2006-10-26 11:53:18 -0700 (Thu, 26 Oct 2006) $
- *----------------------------------------------------------------------------
-*/
-
-#ifndef _EAS_WAVEFILE_H
-#define _EAS_WAVEFILE_H
-
-#include "eas_data.h"
-#include "eas_pcm.h"
-
-/*----------------------------------------------------------------------------
- *
- * S_WAVE_STATE
- *
- * This structure contains the WAVE file parser state information
- *----------------------------------------------------------------------------
-*/
-typedef struct s_wave_state_tag
-{
- EAS_FILE_HANDLE fileHandle;
- EAS_PCM_HANDLE streamHandle;
- S_METADATA_CB metadata;
- EAS_U32 time;
- EAS_I32 fileOffset;
- EAS_I32 audioOffset;
- EAS_I32 mediaLength;
- EAS_U32 audioSize;
- EAS_U32 flags;
- EAS_I16 fileType;
-#ifdef MMAPI_SUPPORT
- EAS_VOID_PTR fmtChunk;
-#endif
- EAS_I32 infoChunkPos;
- EAS_I32 infoChunkSize;
-} S_WAVE_STATE;
-
-#endif
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 439 $
+ * $Date: 2006-10-26 11:53:18 -0700 (Thu, 26 Oct 2006) $
+ *----------------------------------------------------------------------------
+*/
+
+#ifndef _EAS_WAVEFILE_H
+#define _EAS_WAVEFILE_H
+
+#include "eas_data.h"
+#include "eas_pcm.h"
+
+/*----------------------------------------------------------------------------
+ *
+ * S_WAVE_STATE
+ *
+ * This structure contains the WAVE file parser state information
+ *----------------------------------------------------------------------------
+*/
+typedef struct s_wave_state_tag
+{
+ EAS_FILE_HANDLE fileHandle;
+ EAS_PCM_HANDLE streamHandle;
+ S_METADATA_CB metadata;
+ EAS_U32 time;
+ EAS_I32 fileOffset;
+ EAS_I32 audioOffset;
+ EAS_I32 mediaLength;
+ EAS_U32 audioSize;
+ EAS_U32 flags;
+ EAS_I16 fileType;
+#ifdef MMAPI_SUPPORT
+ EAS_VOID_PTR fmtChunk;
+#endif
+ EAS_I32 infoChunkPos;
+ EAS_I32 infoChunkSize;
+} S_WAVE_STATE;
+
+#endif
+
diff --git a/arm-hybrid-22k/lib_src/eas_wavefiledata.c b/arm-hybrid-22k/lib_src/eas_wavefiledata.c
index 3742aa6..c224a6c 100644
--- a/arm-hybrid-22k/lib_src/eas_wavefiledata.c
+++ b/arm-hybrid-22k/lib_src/eas_wavefiledata.c
@@ -1,12 +1,12 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_wavefiledata.c
- *
- * Contents and purpose:
- * Static data block for wave file parser.
- *
- * Copyright Sonic Network Inc. 2005
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_wavefiledata.c
+ *
+ * Contents and purpose:
+ * Static data block for wave file parser.
+ *
+ * Copyright Sonic Network Inc. 2005
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,15 +19,15 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 547 $
- * $Date: 2007-01-31 16:30:17 -0800 (Wed, 31 Jan 2007) $
- *----------------------------------------------------------------------------
-*/
-
-#include "eas_wavefile.h"
-
-S_WAVE_STATE eas_WaveData;
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 547 $
+ * $Date: 2007-01-31 16:30:17 -0800 (Wed, 31 Jan 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+#include "eas_wavefile.h"
+
+S_WAVE_STATE eas_WaveData;
+
diff --git a/arm-hybrid-22k/lib_src/eas_wt_IPC_frame.h b/arm-hybrid-22k/lib_src/eas_wt_IPC_frame.h
index 376fd3a..29d77aa 100644
--- a/arm-hybrid-22k/lib_src/eas_wt_IPC_frame.h
+++ b/arm-hybrid-22k/lib_src/eas_wt_IPC_frame.h
@@ -1,21 +1,21 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_wt_IPC_frame.h
- *
- * Contents and purpose:
- * This module contains data definitions for the interprocessor
- * communications framework for a split-architecture synthesizer.
- *
- * This sample version writes IPC data to a file that can be used
- * as a test vector for the DSP simulator. For a real-time system
- * the file I/O is replaced with an IPC protocol in the hardware.
- *
- * Synchronization with the DSP is accomplished at the API level,
- * i.e. the host code should call EAS_Render when it is ready to
- * buffer another block of data for transmission to the DSP.
- *
- * Copyright Sonic Network Inc. 2005
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_wt_IPC_frame.h
+ *
+ * Contents and purpose:
+ * This module contains data definitions for the interprocessor
+ * communications framework for a split-architecture synthesizer.
+ *
+ * This sample version writes IPC data to a file that can be used
+ * as a test vector for the DSP simulator. For a real-time system
+ * the file I/O is replaced with an IPC protocol in the hardware.
+ *
+ * Synchronization with the DSP is accomplished at the API level,
+ * i.e. the host code should call EAS_Render when it is ready to
+ * buffer another block of data for transmission to the DSP.
+ *
+ * Copyright Sonic Network Inc. 2005
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -28,55 +28,55 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 818 $
- * $Date: 2007-08-02 15:19:41 -0700 (Thu, 02 Aug 2007) $
- *----------------------------------------------------------------------------
-*/
-
-#ifndef _EAS_WT_IPC_FRAME_H
-#define _EAS_WT_IPC_FRAME_H
-
-/*----------------------------------------------------------------------------
- * S_WT_FRAME
- *
- * This structure contains the common parameters that are updated
- *for each frame of audio.
- *----------------------------------------------------------------------------
-*/
-typedef struct s_wt_frame_tag
-{
- EAS_I32 gainTarget;
- EAS_I32 phaseIncrement;
-
-#if defined(_FILTER_ENABLED)
- EAS_I32 k;
- EAS_I32 b1;
- EAS_I32 b2;
-#endif
-} S_WT_FRAME;
-
-/*----------------------------------------------------------------------------
- * S_WT_CONFIG
- *
- * This structure contains state data for the wavetable engine
- *----------------------------------------------------------------------------
-*/
-typedef struct s_wt_config_tag
-{
- EAS_U32 loopEnd; /* points to last PCM sample (not 1 beyond last) */
- EAS_U32 loopStart; /* points to first sample at start of loop */
- EAS_U32 phaseAccum; /* current sample, integer portion of phase */
-
-#if (NUM_OUTPUT_CHANNELS == 2)
- EAS_I16 gainLeft; /* left channel gain */
- EAS_I16 gainRight; /* right channel gain */
-#endif
-
- EAS_I16 gain; /* current voice gain */
-} S_WT_CONFIG;
-
-#endif
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 818 $
+ * $Date: 2007-08-02 15:19:41 -0700 (Thu, 02 Aug 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+#ifndef _EAS_WT_IPC_FRAME_H
+#define _EAS_WT_IPC_FRAME_H
+
+/*----------------------------------------------------------------------------
+ * S_WT_FRAME
+ *
+ * This structure contains the common parameters that are updated
+ *for each frame of audio.
+ *----------------------------------------------------------------------------
+*/
+typedef struct s_wt_frame_tag
+{
+ EAS_I32 gainTarget;
+ EAS_I32 phaseIncrement;
+
+#if defined(_FILTER_ENABLED)
+ EAS_I32 k;
+ EAS_I32 b1;
+ EAS_I32 b2;
+#endif
+} S_WT_FRAME;
+
+/*----------------------------------------------------------------------------
+ * S_WT_CONFIG
+ *
+ * This structure contains state data for the wavetable engine
+ *----------------------------------------------------------------------------
+*/
+typedef struct s_wt_config_tag
+{
+ EAS_U32 loopEnd; /* points to last PCM sample (not 1 beyond last) */
+ EAS_U32 loopStart; /* points to first sample at start of loop */
+ EAS_U32 phaseAccum; /* current sample, integer portion of phase */
+
+#if (NUM_OUTPUT_CHANNELS == 2)
+ EAS_I16 gainLeft; /* left channel gain */
+ EAS_I16 gainRight; /* right channel gain */
+#endif
+
+ EAS_I16 gain; /* current voice gain */
+} S_WT_CONFIG;
+
+#endif
+
diff --git a/arm-hybrid-22k/lib_src/eas_wtengine.c b/arm-hybrid-22k/lib_src/eas_wtengine.c
index 4215924..8407634 100644
--- a/arm-hybrid-22k/lib_src/eas_wtengine.c
+++ b/arm-hybrid-22k/lib_src/eas_wtengine.c
@@ -1,13 +1,13 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_wtengine.c
- *
- * Contents and purpose:
- * This file contains the critical synthesizer components that need to
- * be optimized for best performance.
- *
- * Copyright Sonic Network Inc. 2004-2005
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_wtengine.c
+ *
+ * Contents and purpose:
+ * This file contains the critical synthesizer components that need to
+ * be optimized for best performance.
+ *
+ * Copyright Sonic Network Inc. 2004-2005
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,642 +20,642 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 844 $
- * $Date: 2007-08-23 14:33:32 -0700 (Thu, 23 Aug 2007) $
- *----------------------------------------------------------------------------
-*/
-
-/*------------------------------------
- * includes
- *------------------------------------
-*/
-#include "eas_types.h"
-#include "eas_math.h"
-#include "eas_audioconst.h"
-#include "eas_sndlib.h"
-#include "eas_wtengine.h"
-#include "eas_mixer.h"
-
-/*----------------------------------------------------------------------------
- * prototypes
- *----------------------------------------------------------------------------
-*/
-extern void WT_NoiseGenerator (S_WT_VOICE *pWTVoice, S_WT_INT_FRAME *pWTIntFrame);
-extern void WT_VoiceGain (S_WT_VOICE *pWTVoice, S_WT_INT_FRAME *pWTIntFrame);
-
-#if defined(_OPTIMIZED_MONO)
-extern void WT_InterpolateMono (S_WT_VOICE *pWTVoice, S_WT_INT_FRAME *pWTIntFrame);
-#else
-extern void WT_InterpolateNoLoop (S_WT_VOICE *pWTVoice, S_WT_INT_FRAME *pWTIntFrame);
-extern void WT_Interpolate (S_WT_VOICE *pWTVoice, S_WT_INT_FRAME *pWTIntFrame);
-#endif
-
-#if defined(_FILTER_ENABLED)
-extern void WT_VoiceFilter (S_FILTER_CONTROL*pFilter, S_WT_INT_FRAME *pWTIntFrame);
-#endif
-
-#if defined(_OPTIMIZED_MONO) || !defined(NATIVE_EAS_KERNEL)
-/*----------------------------------------------------------------------------
- * WT_VoiceGain
- *----------------------------------------------------------------------------
- * Purpose:
- * Output gain for individual voice
- *
- * Inputs:
- *
- * Outputs:
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, pWTVoice) reserved for future use */
-void WT_VoiceGain (S_WT_VOICE *pWTVoice, S_WT_INT_FRAME *pWTIntFrame)
-{
- EAS_I32 *pMixBuffer;
- EAS_PCM *pInputBuffer;
- EAS_I32 gain;
- EAS_I32 gainIncrement;
- EAS_I32 tmp0;
- EAS_I32 tmp1;
- EAS_I32 tmp2;
- EAS_I32 numSamples;
-
-#if (NUM_OUTPUT_CHANNELS == 2)
- EAS_I32 gainLeft, gainRight;
-#endif
-
- /* initialize some local variables */
- numSamples = pWTIntFrame->numSamples;
- pMixBuffer = pWTIntFrame->pMixBuffer;
- pInputBuffer = pWTIntFrame->pAudioBuffer;
-
- /*lint -e{703} <avoid multiply for performance>*/
- gainIncrement = (pWTIntFrame->frame.gainTarget - pWTIntFrame->prevGain) << (16 - SYNTH_UPDATE_PERIOD_IN_BITS);
- if (gainIncrement < 0)
- gainIncrement++;
- /*lint -e{703} <avoid multiply for performance>*/
- gain = pWTIntFrame->prevGain << 16;
-
-#if (NUM_OUTPUT_CHANNELS == 2)
- gainLeft = pWTVoice->gainLeft;
- gainRight = pWTVoice->gainRight;
-#endif
-
- while (numSamples--) {
-
- /* incremental gain step to prevent zipper noise */
- tmp0 = *pInputBuffer++;
- gain += gainIncrement;
- /*lint -e{704} <avoid divide>*/
- tmp2 = gain >> 16;
-
- /* scale sample by gain */
- tmp2 *= tmp0;
-
-
- /* stereo output */
-#if (NUM_OUTPUT_CHANNELS == 2)
- /*lint -e{704} <avoid divide>*/
- tmp2 = tmp2 >> 14;
-
- /* get the current sample in the final mix buffer */
- tmp1 = *pMixBuffer;
-
- /* left channel */
- tmp0 = tmp2 * gainLeft;
- /*lint -e{704} <avoid divide>*/
- tmp0 = tmp0 >> NUM_MIXER_GUARD_BITS;
- tmp1 += tmp0;
- *pMixBuffer++ = tmp1;
-
- /* get the current sample in the final mix buffer */
- tmp1 = *pMixBuffer;
-
- /* right channel */
- tmp0 = tmp2 * gainRight;
- /*lint -e{704} <avoid divide>*/
- tmp0 = tmp0 >> NUM_MIXER_GUARD_BITS;
- tmp1 += tmp0;
- *pMixBuffer++ = tmp1;
-
- /* mono output */
-#else
-
- /* get the current sample in the final mix buffer */
- tmp1 = *pMixBuffer;
- /*lint -e{704} <avoid divide>*/
- tmp2 = tmp2 >> (NUM_MIXER_GUARD_BITS - 1);
- tmp1 += tmp2;
- *pMixBuffer++ = tmp1;
-#endif
-
- }
-}
-#endif
-
-#ifndef NATIVE_EAS_KERNEL
-/*----------------------------------------------------------------------------
- * WT_Interpolate
- *----------------------------------------------------------------------------
- * Purpose:
- * Interpolation engine for wavetable synth
- *
- * Inputs:
- *
- * Outputs:
- *
- *----------------------------------------------------------------------------
-*/
-void WT_Interpolate (S_WT_VOICE *pWTVoice, S_WT_INT_FRAME *pWTIntFrame)
-{
- EAS_PCM *pOutputBuffer;
- EAS_I32 phaseInc;
- EAS_I32 phaseFrac;
- EAS_I32 acc0;
- const EAS_SAMPLE *pSamples;
- const EAS_SAMPLE *loopEnd;
- EAS_I32 samp1;
- EAS_I32 samp2;
- EAS_I32 numSamples;
-
- /* initialize some local variables */
- numSamples = pWTIntFrame->numSamples;
- pOutputBuffer = pWTIntFrame->pAudioBuffer;
-
- loopEnd = (const EAS_SAMPLE*) pWTVoice->loopEnd + 1;
- pSamples = (const EAS_SAMPLE*) pWTVoice->phaseAccum;
- /*lint -e{713} truncation is OK */
- phaseFrac = pWTVoice->phaseFrac;
- phaseInc = pWTIntFrame->frame.phaseIncrement;
-
- /* fetch adjacent samples */
-#if defined(_8_BIT_SAMPLES)
- /*lint -e{701} <avoid multiply for performance>*/
- samp1 = pSamples[0] << 8;
- /*lint -e{701} <avoid multiply for performance>*/
- samp2 = pSamples[1] << 8;
-#else
- samp1 = pSamples[0];
- samp2 = pSamples[1];
-#endif
-
- while (numSamples--) {
-
- /* linear interpolation */
- acc0 = samp2 - samp1;
- acc0 = acc0 * phaseFrac;
- /*lint -e{704} <avoid divide>*/
- acc0 = samp1 + (acc0 >> NUM_PHASE_FRAC_BITS);
-
- /* save new output sample in buffer */
- /*lint -e{704} <avoid divide>*/
- *pOutputBuffer++ = (EAS_I16)(acc0 >> 2);
-
- /* increment phase */
- phaseFrac += phaseInc;
- /*lint -e{704} <avoid divide>*/
- acc0 = phaseFrac >> NUM_PHASE_FRAC_BITS;
-
- /* next sample */
- if (acc0 > 0) {
-
- /* advance sample pointer */
- pSamples += acc0;
- phaseFrac = (EAS_I32)((EAS_U32)phaseFrac & PHASE_FRAC_MASK);
-
- /* check for loop end */
- acc0 = (EAS_I32) (pSamples - loopEnd);
- if (acc0 >= 0)
- pSamples = (const EAS_SAMPLE*) pWTVoice->loopStart + acc0;
-
- /* fetch new samples */
-#if defined(_8_BIT_SAMPLES)
- /*lint -e{701} <avoid multiply for performance>*/
- samp1 = pSamples[0] << 8;
- /*lint -e{701} <avoid multiply for performance>*/
- samp2 = pSamples[1] << 8;
-#else
- samp1 = pSamples[0];
- samp2 = pSamples[1];
-#endif
- }
- }
-
- /* save pointer and phase */
- pWTVoice->phaseAccum = (EAS_U32) pSamples;
- pWTVoice->phaseFrac = (EAS_U32) phaseFrac;
-}
-#endif
-
-#ifndef NATIVE_EAS_KERNEL
-/*----------------------------------------------------------------------------
- * WT_InterpolateNoLoop
- *----------------------------------------------------------------------------
- * Purpose:
- * Interpolation engine for wavetable synth
- *
- * Inputs:
- *
- * Outputs:
- *
- *----------------------------------------------------------------------------
-*/
-void WT_InterpolateNoLoop (S_WT_VOICE *pWTVoice, S_WT_INT_FRAME *pWTIntFrame)
-{
- EAS_PCM *pOutputBuffer;
- EAS_I32 phaseInc;
- EAS_I32 phaseFrac;
- EAS_I32 acc0;
- const EAS_SAMPLE *pSamples;
- EAS_I32 samp1;
- EAS_I32 samp2;
- EAS_I32 numSamples;
-
- /* initialize some local variables */
- numSamples = pWTIntFrame->numSamples;
- pOutputBuffer = pWTIntFrame->pAudioBuffer;
-
- phaseInc = pWTIntFrame->frame.phaseIncrement;
- pSamples = (const EAS_SAMPLE*) pWTVoice->phaseAccum;
- phaseFrac = (EAS_I32)pWTVoice->phaseFrac;
-
- /* fetch adjacent samples */
-#if defined(_8_BIT_SAMPLES)
- /*lint -e{701} <avoid multiply for performance>*/
- samp1 = pSamples[0] << 8;
- /*lint -e{701} <avoid multiply for performance>*/
- samp2 = pSamples[1] << 8;
-#else
- samp1 = pSamples[0];
- samp2 = pSamples[1];
-#endif
-
- while (numSamples--) {
-
-
- /* linear interpolation */
- acc0 = samp2 - samp1;
- acc0 = acc0 * phaseFrac;
- /*lint -e{704} <avoid divide>*/
- acc0 = samp1 + (acc0 >> NUM_PHASE_FRAC_BITS);
-
- /* save new output sample in buffer */
- /*lint -e{704} <avoid divide>*/
- *pOutputBuffer++ = (EAS_I16)(acc0 >> 2);
-
- /* increment phase */
- phaseFrac += phaseInc;
- /*lint -e{704} <avoid divide>*/
- acc0 = phaseFrac >> NUM_PHASE_FRAC_BITS;
-
- /* next sample */
- if (acc0 > 0) {
-
- /* advance sample pointer */
- pSamples += acc0;
- phaseFrac = (EAS_I32)((EAS_U32)phaseFrac & PHASE_FRAC_MASK);
-
- /* fetch new samples */
-#if defined(_8_BIT_SAMPLES)
- /*lint -e{701} <avoid multiply for performance>*/
- samp1 = pSamples[0] << 8;
- /*lint -e{701} <avoid multiply for performance>*/
- samp2 = pSamples[1] << 8;
-#else
- samp1 = pSamples[0];
- samp2 = pSamples[1];
-#endif
- }
- }
-
- /* save pointer and phase */
- pWTVoice->phaseAccum = (EAS_U32) pSamples;
- pWTVoice->phaseFrac = (EAS_U32) phaseFrac;
-}
-#endif
-
-#if defined(_FILTER_ENABLED) && !defined(NATIVE_EAS_KERNEL)
-/*----------------------------------------------------------------------------
- * WT_VoiceFilter
- *----------------------------------------------------------------------------
- * Purpose:
- * Implements a 2-pole filter
- *
- * Inputs:
- *
- * Outputs:
- *
- *----------------------------------------------------------------------------
-*/
-void WT_VoiceFilter (S_FILTER_CONTROL *pFilter, S_WT_INT_FRAME *pWTIntFrame)
-{
- EAS_PCM *pAudioBuffer;
- EAS_I32 k;
- EAS_I32 b1;
- EAS_I32 b2;
- EAS_I32 z1;
- EAS_I32 z2;
- EAS_I32 acc0;
- EAS_I32 acc1;
- EAS_I32 numSamples;
-
- /* initialize some local variables */
- numSamples = pWTIntFrame->numSamples;
- pAudioBuffer = pWTIntFrame->pAudioBuffer;
-
- z1 = pFilter->z1;
- z2 = pFilter->z2;
- b1 = -pWTIntFrame->frame.b1;
-
- /*lint -e{702} <avoid divide> */
- b2 = -pWTIntFrame->frame.b2 >> 1;
-
- /*lint -e{702} <avoid divide> */
- k = pWTIntFrame->frame.k >> 1;
-
- while (numSamples--)
- {
-
- /* do filter calculations */
- acc0 = *pAudioBuffer;
- acc1 = z1 * b1;
- acc1 += z2 * b2;
- acc0 = acc1 + k * acc0;
- z2 = z1;
-
- /*lint -e{702} <avoid divide> */
- z1 = acc0 >> 14;
- *pAudioBuffer++ = (EAS_I16) z1;
- }
-
- /* save delay values */
- pFilter->z1 = (EAS_I16) z1;
- pFilter->z2 = (EAS_I16) z2;
-}
-#endif
-
-/*----------------------------------------------------------------------------
- * WT_NoiseGenerator
- *----------------------------------------------------------------------------
- * Purpose:
- * Generate pseudo-white noise using PRNG and interpolation engine
- *
- * Inputs:
- *
- * Outputs:
- *
- * Notes:
- * This output is scaled -12dB to prevent saturation in the filter. For a
- * high quality synthesizer, the output can be set to full scale, however
- * if the filter is used, it can overflow with certain coefficients. In this
- * case, either a saturation operation should take in the filter before
- * scaling back to 16 bits or the signal path should be increased to 18 bits
- * or more.
- *----------------------------------------------------------------------------
-*/
- void WT_NoiseGenerator (S_WT_VOICE *pWTVoice, S_WT_INT_FRAME *pWTIntFrame)
- {
- EAS_PCM *pOutputBuffer;
- EAS_I32 phaseInc;
- EAS_I32 tmp0;
- EAS_I32 tmp1;
- EAS_I32 nInterpolatedSample;
- EAS_I32 numSamples;
-
- /* initialize some local variables */
- numSamples = pWTIntFrame->numSamples;
- pOutputBuffer = pWTIntFrame->pAudioBuffer;
- phaseInc = pWTIntFrame->frame.phaseIncrement;
-
- /* get last two samples generated */
- /*lint -e{704} <avoid divide for performance>*/
- tmp0 = (EAS_I32) (pWTVoice->phaseAccum) >> 18;
- /*lint -e{704} <avoid divide for performance>*/
- tmp1 = (EAS_I32) (pWTVoice->loopEnd) >> 18;
-
- /* generate a buffer of noise */
- while (numSamples--) {
- nInterpolatedSample = MULT_AUDIO_COEF( tmp0, (PHASE_ONE - pWTVoice->phaseFrac));
- nInterpolatedSample += MULT_AUDIO_COEF( tmp1, pWTVoice->phaseFrac);
- *pOutputBuffer++ = (EAS_PCM) nInterpolatedSample;
-
- /* update PRNG */
- pWTVoice->phaseFrac += (EAS_U32) phaseInc;
- if (GET_PHASE_INT_PART(pWTVoice->phaseFrac)) {
- tmp0 = tmp1;
- pWTVoice->phaseAccum = pWTVoice->loopEnd;
- pWTVoice->loopEnd = (5 * pWTVoice->loopEnd + 1);
- tmp1 = (EAS_I32) (pWTVoice->loopEnd) >> 18;
- pWTVoice->phaseFrac = GET_PHASE_FRAC_PART(pWTVoice->phaseFrac);
- }
-
- }
-}
-
-#ifndef _OPTIMIZED_MONO
-/*----------------------------------------------------------------------------
- * WT_ProcessVoice
- *----------------------------------------------------------------------------
- * Purpose:
- * This routine does the block processing for one voice. It is isolated
- * from the main synth code to allow for various implementation-specific
- * optimizations. It calls the interpolator, filter, and gain routines
- * appropriate for a particular configuration.
- *
- * Inputs:
- *
- * Outputs:
- *
- * Notes:
- *----------------------------------------------------------------------------
-*/
-void WT_ProcessVoice (S_WT_VOICE *pWTVoice, S_WT_INT_FRAME *pWTIntFrame)
-{
-
- /* use noise generator */
- if (pWTVoice->loopStart == WT_NOISE_GENERATOR)
- WT_NoiseGenerator(pWTVoice, pWTIntFrame);
-
- /* generate interpolated samples for looped waves */
- else if (pWTVoice->loopStart != pWTVoice->loopEnd)
- WT_Interpolate(pWTVoice, pWTIntFrame);
-
- /* generate interpolated samples for unlooped waves */
- else
- {
- WT_InterpolateNoLoop(pWTVoice, pWTIntFrame);
- }
-
-#ifdef _FILTER_ENABLED
- if (pWTIntFrame->frame.k != 0)
- WT_VoiceFilter(&pWTVoice->filter, pWTIntFrame);
-#endif
-
-//2 TEST NEW MIXER FUNCTION
-#ifdef UNIFIED_MIXER
- {
- EAS_I32 gainLeft, gainIncLeft;
-
-#if (NUM_OUTPUT_CHANNELS == 2)
- EAS_I32 gainRight, gainIncRight;
-#endif
-
- gainLeft = (pWTIntFrame->prevGain * pWTVoice->gainLeft) << 1;
- gainIncLeft = (((pWTIntFrame->frame.gainTarget * pWTVoice->gainLeft) << 1) - gainLeft) >> SYNTH_UPDATE_PERIOD_IN_BITS;
-
-#if (NUM_OUTPUT_CHANNELS == 2)
- gainRight = (pWTIntFrame->prevGain * pWTVoice->gainRight) << 1;
- gainIncRight = (((pWTIntFrame->frame.gainTarget * pWTVoice->gainRight) << 1) - gainRight) >> SYNTH_UPDATE_PERIOD_IN_BITS;
- EAS_MixStream(
- pWTIntFrame->pAudioBuffer,
- pWTIntFrame->pMixBuffer,
- pWTIntFrame->numSamples,
- gainLeft,
- gainRight,
- gainIncLeft,
- gainIncRight,
- MIX_FLAGS_STEREO_OUTPUT);
-
-#else
- EAS_MixStream(
- pWTIntFrame->pAudioBuffer,
- pWTIntFrame->pMixBuffer,
- pWTIntFrame->numSamples,
- gainLeft,
- 0,
- gainIncLeft,
- 0,
- 0);
-#endif
- }
-
-#else
- /* apply gain, and left and right gain */
- WT_VoiceGain(pWTVoice, pWTIntFrame);
-#endif
-}
-#endif
-
-#if defined(_OPTIMIZED_MONO) && !defined(NATIVE_EAS_KERNEL)
-/*----------------------------------------------------------------------------
- * WT_InterpolateMono
- *----------------------------------------------------------------------------
- * Purpose:
- * A C version of the sample interpolation + gain routine, optimized for mono.
- * It's not pretty, but it matches the assembly code exactly.
- *
- * Inputs:
- *
- * Outputs:
- *
- * Notes:
- *----------------------------------------------------------------------------
-*/
-void WT_InterpolateMono (S_WT_VOICE *pWTVoice, S_WT_INT_FRAME *pWTIntFrame)
-{
- EAS_I32 *pMixBuffer;
- const EAS_I8 *pLoopEnd;
- const EAS_I8 *pCurrentPhaseInt;
- EAS_I32 numSamples;
- EAS_I32 gain;
- EAS_I32 gainIncrement;
- EAS_I32 currentPhaseFrac;
- EAS_I32 phaseInc;
- EAS_I32 tmp0;
- EAS_I32 tmp1;
- EAS_I32 tmp2;
- EAS_I8 *pLoopStart;
-
- numSamples = pWTIntFrame->numSamples;
- pMixBuffer = pWTIntFrame->pMixBuffer;
-
- /* calculate gain increment */
- gainIncrement = (pWTIntFrame->gainTarget - pWTIntFrame->prevGain) << (16 - SYNTH_UPDATE_PERIOD_IN_BITS);
- if (gainIncrement < 0)
- gainIncrement++;
- gain = pWTIntFrame->prevGain << 16;
-
- pCurrentPhaseInt = pWTVoice->pPhaseAccum;
- currentPhaseFrac = pWTVoice->phaseFrac;
- phaseInc = pWTIntFrame->phaseIncrement;
-
- pLoopStart = pWTVoice->pLoopStart;
- pLoopEnd = pWTVoice->pLoopEnd + 1;
-
-InterpolationLoop:
- tmp0 = (EAS_I32)(pCurrentPhaseInt - pLoopEnd);
- if (tmp0 >= 0)
- pCurrentPhaseInt = pLoopStart + tmp0;
-
- tmp0 = *pCurrentPhaseInt;
- tmp1 = *(pCurrentPhaseInt + 1);
-
- tmp2 = phaseInc + currentPhaseFrac;
-
- tmp1 = tmp1 - tmp0;
- tmp1 = tmp1 * currentPhaseFrac;
-
- tmp1 = tmp0 + (tmp1 >> NUM_EG1_FRAC_BITS);
-
- pCurrentPhaseInt += (tmp2 >> NUM_PHASE_FRAC_BITS);
- currentPhaseFrac = tmp2 & PHASE_FRAC_MASK;
-
- gain += gainIncrement;
- tmp2 = (gain >> SYNTH_UPDATE_PERIOD_IN_BITS);
-
- tmp0 = *pMixBuffer;
- tmp2 = tmp1 * tmp2;
- tmp2 = (tmp2 >> 9);
- tmp0 = tmp2 + tmp0;
- *pMixBuffer++ = tmp0;
-
- numSamples--;
- if (numSamples)
- goto InterpolationLoop;
-
- pWTVoice->pPhaseAccum = pCurrentPhaseInt;
- pWTVoice->phaseFrac = currentPhaseFrac;
- /*lint -e{702} <avoid divide>*/
- pWTVoice->gain = (EAS_I16)(gain >> SYNTH_UPDATE_PERIOD_IN_BITS);
-}
-#endif
-
-#ifdef _OPTIMIZED_MONO
-/*----------------------------------------------------------------------------
- * WT_ProcessVoice
- *----------------------------------------------------------------------------
- * Purpose:
- * This routine does the block processing for one voice. It is isolated
- * from the main synth code to allow for various implementation-specific
- * optimizations. It calls the interpolator, filter, and gain routines
- * appropriate for a particular configuration.
- *
- * Inputs:
- *
- * Outputs:
- *
- * Notes:
- * This special version works handles an optimized mono-only signal
- * without filters
- *----------------------------------------------------------------------------
-*/
-void WT_ProcessVoice (S_WT_VOICE *pWTVoice, S_WT_INT_FRAME *pWTIntFrame)
-{
-
- /* use noise generator */
- if (pWTVoice->loopStart== WT_NOISE_GENERATOR)
- {
- WT_NoiseGenerator(pWTVoice, pWTIntFrame);
- WT_VoiceGain(pWTVoice, pWTIntFrame);
- }
-
- /* or generate interpolated samples */
- else
- {
- WT_InterpolateMono(pWTVoice, pWTIntFrame);
- }
-}
-#endif
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 844 $
+ * $Date: 2007-08-23 14:33:32 -0700 (Thu, 23 Aug 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+/*------------------------------------
+ * includes
+ *------------------------------------
+*/
+#include "eas_types.h"
+#include "eas_math.h"
+#include "eas_audioconst.h"
+#include "eas_sndlib.h"
+#include "eas_wtengine.h"
+#include "eas_mixer.h"
+
+/*----------------------------------------------------------------------------
+ * prototypes
+ *----------------------------------------------------------------------------
+*/
+extern void WT_NoiseGenerator (S_WT_VOICE *pWTVoice, S_WT_INT_FRAME *pWTIntFrame);
+extern void WT_VoiceGain (S_WT_VOICE *pWTVoice, S_WT_INT_FRAME *pWTIntFrame);
+
+#if defined(_OPTIMIZED_MONO)
+extern void WT_InterpolateMono (S_WT_VOICE *pWTVoice, S_WT_INT_FRAME *pWTIntFrame);
+#else
+extern void WT_InterpolateNoLoop (S_WT_VOICE *pWTVoice, S_WT_INT_FRAME *pWTIntFrame);
+extern void WT_Interpolate (S_WT_VOICE *pWTVoice, S_WT_INT_FRAME *pWTIntFrame);
+#endif
+
+#if defined(_FILTER_ENABLED)
+extern void WT_VoiceFilter (S_FILTER_CONTROL*pFilter, S_WT_INT_FRAME *pWTIntFrame);
+#endif
+
+#if defined(_OPTIMIZED_MONO) || !defined(NATIVE_EAS_KERNEL)
+/*----------------------------------------------------------------------------
+ * WT_VoiceGain
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Output gain for individual voice
+ *
+ * Inputs:
+ *
+ * Outputs:
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pWTVoice) reserved for future use */
+void WT_VoiceGain (S_WT_VOICE *pWTVoice, S_WT_INT_FRAME *pWTIntFrame)
+{
+ EAS_I32 *pMixBuffer;
+ EAS_PCM *pInputBuffer;
+ EAS_I32 gain;
+ EAS_I32 gainIncrement;
+ EAS_I32 tmp0;
+ EAS_I32 tmp1;
+ EAS_I32 tmp2;
+ EAS_I32 numSamples;
+
+#if (NUM_OUTPUT_CHANNELS == 2)
+ EAS_I32 gainLeft, gainRight;
+#endif
+
+ /* initialize some local variables */
+ numSamples = pWTIntFrame->numSamples;
+ pMixBuffer = pWTIntFrame->pMixBuffer;
+ pInputBuffer = pWTIntFrame->pAudioBuffer;
+
+ /*lint -e{703} <avoid multiply for performance>*/
+ gainIncrement = (pWTIntFrame->frame.gainTarget - pWTIntFrame->prevGain) << (16 - SYNTH_UPDATE_PERIOD_IN_BITS);
+ if (gainIncrement < 0)
+ gainIncrement++;
+ /*lint -e{703} <avoid multiply for performance>*/
+ gain = pWTIntFrame->prevGain << 16;
+
+#if (NUM_OUTPUT_CHANNELS == 2)
+ gainLeft = pWTVoice->gainLeft;
+ gainRight = pWTVoice->gainRight;
+#endif
+
+ while (numSamples--) {
+
+ /* incremental gain step to prevent zipper noise */
+ tmp0 = *pInputBuffer++;
+ gain += gainIncrement;
+ /*lint -e{704} <avoid divide>*/
+ tmp2 = gain >> 16;
+
+ /* scale sample by gain */
+ tmp2 *= tmp0;
+
+
+ /* stereo output */
+#if (NUM_OUTPUT_CHANNELS == 2)
+ /*lint -e{704} <avoid divide>*/
+ tmp2 = tmp2 >> 14;
+
+ /* get the current sample in the final mix buffer */
+ tmp1 = *pMixBuffer;
+
+ /* left channel */
+ tmp0 = tmp2 * gainLeft;
+ /*lint -e{704} <avoid divide>*/
+ tmp0 = tmp0 >> NUM_MIXER_GUARD_BITS;
+ tmp1 += tmp0;
+ *pMixBuffer++ = tmp1;
+
+ /* get the current sample in the final mix buffer */
+ tmp1 = *pMixBuffer;
+
+ /* right channel */
+ tmp0 = tmp2 * gainRight;
+ /*lint -e{704} <avoid divide>*/
+ tmp0 = tmp0 >> NUM_MIXER_GUARD_BITS;
+ tmp1 += tmp0;
+ *pMixBuffer++ = tmp1;
+
+ /* mono output */
+#else
+
+ /* get the current sample in the final mix buffer */
+ tmp1 = *pMixBuffer;
+ /*lint -e{704} <avoid divide>*/
+ tmp2 = tmp2 >> (NUM_MIXER_GUARD_BITS - 1);
+ tmp1 += tmp2;
+ *pMixBuffer++ = tmp1;
+#endif
+
+ }
+}
+#endif
+
+#ifndef NATIVE_EAS_KERNEL
+/*----------------------------------------------------------------------------
+ * WT_Interpolate
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Interpolation engine for wavetable synth
+ *
+ * Inputs:
+ *
+ * Outputs:
+ *
+ *----------------------------------------------------------------------------
+*/
+void WT_Interpolate (S_WT_VOICE *pWTVoice, S_WT_INT_FRAME *pWTIntFrame)
+{
+ EAS_PCM *pOutputBuffer;
+ EAS_I32 phaseInc;
+ EAS_I32 phaseFrac;
+ EAS_I32 acc0;
+ const EAS_SAMPLE *pSamples;
+ const EAS_SAMPLE *loopEnd;
+ EAS_I32 samp1;
+ EAS_I32 samp2;
+ EAS_I32 numSamples;
+
+ /* initialize some local variables */
+ numSamples = pWTIntFrame->numSamples;
+ pOutputBuffer = pWTIntFrame->pAudioBuffer;
+
+ loopEnd = (const EAS_SAMPLE*) pWTVoice->loopEnd + 1;
+ pSamples = (const EAS_SAMPLE*) pWTVoice->phaseAccum;
+ /*lint -e{713} truncation is OK */
+ phaseFrac = pWTVoice->phaseFrac;
+ phaseInc = pWTIntFrame->frame.phaseIncrement;
+
+ /* fetch adjacent samples */
+#if defined(_8_BIT_SAMPLES)
+ /*lint -e{701} <avoid multiply for performance>*/
+ samp1 = pSamples[0] << 8;
+ /*lint -e{701} <avoid multiply for performance>*/
+ samp2 = pSamples[1] << 8;
+#else
+ samp1 = pSamples[0];
+ samp2 = pSamples[1];
+#endif
+
+ while (numSamples--) {
+
+ /* linear interpolation */
+ acc0 = samp2 - samp1;
+ acc0 = acc0 * phaseFrac;
+ /*lint -e{704} <avoid divide>*/
+ acc0 = samp1 + (acc0 >> NUM_PHASE_FRAC_BITS);
+
+ /* save new output sample in buffer */
+ /*lint -e{704} <avoid divide>*/
+ *pOutputBuffer++ = (EAS_I16)(acc0 >> 2);
+
+ /* increment phase */
+ phaseFrac += phaseInc;
+ /*lint -e{704} <avoid divide>*/
+ acc0 = phaseFrac >> NUM_PHASE_FRAC_BITS;
+
+ /* next sample */
+ if (acc0 > 0) {
+
+ /* advance sample pointer */
+ pSamples += acc0;
+ phaseFrac = (EAS_I32)((EAS_U32)phaseFrac & PHASE_FRAC_MASK);
+
+ /* check for loop end */
+ acc0 = (EAS_I32) (pSamples - loopEnd);
+ if (acc0 >= 0)
+ pSamples = (const EAS_SAMPLE*) pWTVoice->loopStart + acc0;
+
+ /* fetch new samples */
+#if defined(_8_BIT_SAMPLES)
+ /*lint -e{701} <avoid multiply for performance>*/
+ samp1 = pSamples[0] << 8;
+ /*lint -e{701} <avoid multiply for performance>*/
+ samp2 = pSamples[1] << 8;
+#else
+ samp1 = pSamples[0];
+ samp2 = pSamples[1];
+#endif
+ }
+ }
+
+ /* save pointer and phase */
+ pWTVoice->phaseAccum = (EAS_U32) pSamples;
+ pWTVoice->phaseFrac = (EAS_U32) phaseFrac;
+}
+#endif
+
+#ifndef NATIVE_EAS_KERNEL
+/*----------------------------------------------------------------------------
+ * WT_InterpolateNoLoop
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Interpolation engine for wavetable synth
+ *
+ * Inputs:
+ *
+ * Outputs:
+ *
+ *----------------------------------------------------------------------------
+*/
+void WT_InterpolateNoLoop (S_WT_VOICE *pWTVoice, S_WT_INT_FRAME *pWTIntFrame)
+{
+ EAS_PCM *pOutputBuffer;
+ EAS_I32 phaseInc;
+ EAS_I32 phaseFrac;
+ EAS_I32 acc0;
+ const EAS_SAMPLE *pSamples;
+ EAS_I32 samp1;
+ EAS_I32 samp2;
+ EAS_I32 numSamples;
+
+ /* initialize some local variables */
+ numSamples = pWTIntFrame->numSamples;
+ pOutputBuffer = pWTIntFrame->pAudioBuffer;
+
+ phaseInc = pWTIntFrame->frame.phaseIncrement;
+ pSamples = (const EAS_SAMPLE*) pWTVoice->phaseAccum;
+ phaseFrac = (EAS_I32)pWTVoice->phaseFrac;
+
+ /* fetch adjacent samples */
+#if defined(_8_BIT_SAMPLES)
+ /*lint -e{701} <avoid multiply for performance>*/
+ samp1 = pSamples[0] << 8;
+ /*lint -e{701} <avoid multiply for performance>*/
+ samp2 = pSamples[1] << 8;
+#else
+ samp1 = pSamples[0];
+ samp2 = pSamples[1];
+#endif
+
+ while (numSamples--) {
+
+
+ /* linear interpolation */
+ acc0 = samp2 - samp1;
+ acc0 = acc0 * phaseFrac;
+ /*lint -e{704} <avoid divide>*/
+ acc0 = samp1 + (acc0 >> NUM_PHASE_FRAC_BITS);
+
+ /* save new output sample in buffer */
+ /*lint -e{704} <avoid divide>*/
+ *pOutputBuffer++ = (EAS_I16)(acc0 >> 2);
+
+ /* increment phase */
+ phaseFrac += phaseInc;
+ /*lint -e{704} <avoid divide>*/
+ acc0 = phaseFrac >> NUM_PHASE_FRAC_BITS;
+
+ /* next sample */
+ if (acc0 > 0) {
+
+ /* advance sample pointer */
+ pSamples += acc0;
+ phaseFrac = (EAS_I32)((EAS_U32)phaseFrac & PHASE_FRAC_MASK);
+
+ /* fetch new samples */
+#if defined(_8_BIT_SAMPLES)
+ /*lint -e{701} <avoid multiply for performance>*/
+ samp1 = pSamples[0] << 8;
+ /*lint -e{701} <avoid multiply for performance>*/
+ samp2 = pSamples[1] << 8;
+#else
+ samp1 = pSamples[0];
+ samp2 = pSamples[1];
+#endif
+ }
+ }
+
+ /* save pointer and phase */
+ pWTVoice->phaseAccum = (EAS_U32) pSamples;
+ pWTVoice->phaseFrac = (EAS_U32) phaseFrac;
+}
+#endif
+
+#if defined(_FILTER_ENABLED) && !defined(NATIVE_EAS_KERNEL)
+/*----------------------------------------------------------------------------
+ * WT_VoiceFilter
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Implements a 2-pole filter
+ *
+ * Inputs:
+ *
+ * Outputs:
+ *
+ *----------------------------------------------------------------------------
+*/
+void WT_VoiceFilter (S_FILTER_CONTROL *pFilter, S_WT_INT_FRAME *pWTIntFrame)
+{
+ EAS_PCM *pAudioBuffer;
+ EAS_I32 k;
+ EAS_I32 b1;
+ EAS_I32 b2;
+ EAS_I32 z1;
+ EAS_I32 z2;
+ EAS_I32 acc0;
+ EAS_I32 acc1;
+ EAS_I32 numSamples;
+
+ /* initialize some local variables */
+ numSamples = pWTIntFrame->numSamples;
+ pAudioBuffer = pWTIntFrame->pAudioBuffer;
+
+ z1 = pFilter->z1;
+ z2 = pFilter->z2;
+ b1 = -pWTIntFrame->frame.b1;
+
+ /*lint -e{702} <avoid divide> */
+ b2 = -pWTIntFrame->frame.b2 >> 1;
+
+ /*lint -e{702} <avoid divide> */
+ k = pWTIntFrame->frame.k >> 1;
+
+ while (numSamples--)
+ {
+
+ /* do filter calculations */
+ acc0 = *pAudioBuffer;
+ acc1 = z1 * b1;
+ acc1 += z2 * b2;
+ acc0 = acc1 + k * acc0;
+ z2 = z1;
+
+ /*lint -e{702} <avoid divide> */
+ z1 = acc0 >> 14;
+ *pAudioBuffer++ = (EAS_I16) z1;
+ }
+
+ /* save delay values */
+ pFilter->z1 = (EAS_I16) z1;
+ pFilter->z2 = (EAS_I16) z2;
+}
+#endif
+
+/*----------------------------------------------------------------------------
+ * WT_NoiseGenerator
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Generate pseudo-white noise using PRNG and interpolation engine
+ *
+ * Inputs:
+ *
+ * Outputs:
+ *
+ * Notes:
+ * This output is scaled -12dB to prevent saturation in the filter. For a
+ * high quality synthesizer, the output can be set to full scale, however
+ * if the filter is used, it can overflow with certain coefficients. In this
+ * case, either a saturation operation should take in the filter before
+ * scaling back to 16 bits or the signal path should be increased to 18 bits
+ * or more.
+ *----------------------------------------------------------------------------
+*/
+ void WT_NoiseGenerator (S_WT_VOICE *pWTVoice, S_WT_INT_FRAME *pWTIntFrame)
+ {
+ EAS_PCM *pOutputBuffer;
+ EAS_I32 phaseInc;
+ EAS_I32 tmp0;
+ EAS_I32 tmp1;
+ EAS_I32 nInterpolatedSample;
+ EAS_I32 numSamples;
+
+ /* initialize some local variables */
+ numSamples = pWTIntFrame->numSamples;
+ pOutputBuffer = pWTIntFrame->pAudioBuffer;
+ phaseInc = pWTIntFrame->frame.phaseIncrement;
+
+ /* get last two samples generated */
+ /*lint -e{704} <avoid divide for performance>*/
+ tmp0 = (EAS_I32) (pWTVoice->phaseAccum) >> 18;
+ /*lint -e{704} <avoid divide for performance>*/
+ tmp1 = (EAS_I32) (pWTVoice->loopEnd) >> 18;
+
+ /* generate a buffer of noise */
+ while (numSamples--) {
+ nInterpolatedSample = MULT_AUDIO_COEF( tmp0, (PHASE_ONE - pWTVoice->phaseFrac));
+ nInterpolatedSample += MULT_AUDIO_COEF( tmp1, pWTVoice->phaseFrac);
+ *pOutputBuffer++ = (EAS_PCM) nInterpolatedSample;
+
+ /* update PRNG */
+ pWTVoice->phaseFrac += (EAS_U32) phaseInc;
+ if (GET_PHASE_INT_PART(pWTVoice->phaseFrac)) {
+ tmp0 = tmp1;
+ pWTVoice->phaseAccum = pWTVoice->loopEnd;
+ pWTVoice->loopEnd = (5 * pWTVoice->loopEnd + 1);
+ tmp1 = (EAS_I32) (pWTVoice->loopEnd) >> 18;
+ pWTVoice->phaseFrac = GET_PHASE_FRAC_PART(pWTVoice->phaseFrac);
+ }
+
+ }
+}
+
+#ifndef _OPTIMIZED_MONO
+/*----------------------------------------------------------------------------
+ * WT_ProcessVoice
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * This routine does the block processing for one voice. It is isolated
+ * from the main synth code to allow for various implementation-specific
+ * optimizations. It calls the interpolator, filter, and gain routines
+ * appropriate for a particular configuration.
+ *
+ * Inputs:
+ *
+ * Outputs:
+ *
+ * Notes:
+ *----------------------------------------------------------------------------
+*/
+void WT_ProcessVoice (S_WT_VOICE *pWTVoice, S_WT_INT_FRAME *pWTIntFrame)
+{
+
+ /* use noise generator */
+ if (pWTVoice->loopStart == WT_NOISE_GENERATOR)
+ WT_NoiseGenerator(pWTVoice, pWTIntFrame);
+
+ /* generate interpolated samples for looped waves */
+ else if (pWTVoice->loopStart != pWTVoice->loopEnd)
+ WT_Interpolate(pWTVoice, pWTIntFrame);
+
+ /* generate interpolated samples for unlooped waves */
+ else
+ {
+ WT_InterpolateNoLoop(pWTVoice, pWTIntFrame);
+ }
+
+#ifdef _FILTER_ENABLED
+ if (pWTIntFrame->frame.k != 0)
+ WT_VoiceFilter(&pWTVoice->filter, pWTIntFrame);
+#endif
+
+//2 TEST NEW MIXER FUNCTION
+#ifdef UNIFIED_MIXER
+ {
+ EAS_I32 gainLeft, gainIncLeft;
+
+#if (NUM_OUTPUT_CHANNELS == 2)
+ EAS_I32 gainRight, gainIncRight;
+#endif
+
+ gainLeft = (pWTIntFrame->prevGain * pWTVoice->gainLeft) << 1;
+ gainIncLeft = (((pWTIntFrame->frame.gainTarget * pWTVoice->gainLeft) << 1) - gainLeft) >> SYNTH_UPDATE_PERIOD_IN_BITS;
+
+#if (NUM_OUTPUT_CHANNELS == 2)
+ gainRight = (pWTIntFrame->prevGain * pWTVoice->gainRight) << 1;
+ gainIncRight = (((pWTIntFrame->frame.gainTarget * pWTVoice->gainRight) << 1) - gainRight) >> SYNTH_UPDATE_PERIOD_IN_BITS;
+ EAS_MixStream(
+ pWTIntFrame->pAudioBuffer,
+ pWTIntFrame->pMixBuffer,
+ pWTIntFrame->numSamples,
+ gainLeft,
+ gainRight,
+ gainIncLeft,
+ gainIncRight,
+ MIX_FLAGS_STEREO_OUTPUT);
+
+#else
+ EAS_MixStream(
+ pWTIntFrame->pAudioBuffer,
+ pWTIntFrame->pMixBuffer,
+ pWTIntFrame->numSamples,
+ gainLeft,
+ 0,
+ gainIncLeft,
+ 0,
+ 0);
+#endif
+ }
+
+#else
+ /* apply gain, and left and right gain */
+ WT_VoiceGain(pWTVoice, pWTIntFrame);
+#endif
+}
+#endif
+
+#if defined(_OPTIMIZED_MONO) && !defined(NATIVE_EAS_KERNEL)
+/*----------------------------------------------------------------------------
+ * WT_InterpolateMono
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * A C version of the sample interpolation + gain routine, optimized for mono.
+ * It's not pretty, but it matches the assembly code exactly.
+ *
+ * Inputs:
+ *
+ * Outputs:
+ *
+ * Notes:
+ *----------------------------------------------------------------------------
+*/
+void WT_InterpolateMono (S_WT_VOICE *pWTVoice, S_WT_INT_FRAME *pWTIntFrame)
+{
+ EAS_I32 *pMixBuffer;
+ const EAS_I8 *pLoopEnd;
+ const EAS_I8 *pCurrentPhaseInt;
+ EAS_I32 numSamples;
+ EAS_I32 gain;
+ EAS_I32 gainIncrement;
+ EAS_I32 currentPhaseFrac;
+ EAS_I32 phaseInc;
+ EAS_I32 tmp0;
+ EAS_I32 tmp1;
+ EAS_I32 tmp2;
+ EAS_I8 *pLoopStart;
+
+ numSamples = pWTIntFrame->numSamples;
+ pMixBuffer = pWTIntFrame->pMixBuffer;
+
+ /* calculate gain increment */
+ gainIncrement = (pWTIntFrame->gainTarget - pWTIntFrame->prevGain) << (16 - SYNTH_UPDATE_PERIOD_IN_BITS);
+ if (gainIncrement < 0)
+ gainIncrement++;
+ gain = pWTIntFrame->prevGain << 16;
+
+ pCurrentPhaseInt = pWTVoice->pPhaseAccum;
+ currentPhaseFrac = pWTVoice->phaseFrac;
+ phaseInc = pWTIntFrame->phaseIncrement;
+
+ pLoopStart = pWTVoice->pLoopStart;
+ pLoopEnd = pWTVoice->pLoopEnd + 1;
+
+InterpolationLoop:
+ tmp0 = (EAS_I32)(pCurrentPhaseInt - pLoopEnd);
+ if (tmp0 >= 0)
+ pCurrentPhaseInt = pLoopStart + tmp0;
+
+ tmp0 = *pCurrentPhaseInt;
+ tmp1 = *(pCurrentPhaseInt + 1);
+
+ tmp2 = phaseInc + currentPhaseFrac;
+
+ tmp1 = tmp1 - tmp0;
+ tmp1 = tmp1 * currentPhaseFrac;
+
+ tmp1 = tmp0 + (tmp1 >> NUM_EG1_FRAC_BITS);
+
+ pCurrentPhaseInt += (tmp2 >> NUM_PHASE_FRAC_BITS);
+ currentPhaseFrac = tmp2 & PHASE_FRAC_MASK;
+
+ gain += gainIncrement;
+ tmp2 = (gain >> SYNTH_UPDATE_PERIOD_IN_BITS);
+
+ tmp0 = *pMixBuffer;
+ tmp2 = tmp1 * tmp2;
+ tmp2 = (tmp2 >> 9);
+ tmp0 = tmp2 + tmp0;
+ *pMixBuffer++ = tmp0;
+
+ numSamples--;
+ if (numSamples)
+ goto InterpolationLoop;
+
+ pWTVoice->pPhaseAccum = pCurrentPhaseInt;
+ pWTVoice->phaseFrac = currentPhaseFrac;
+ /*lint -e{702} <avoid divide>*/
+ pWTVoice->gain = (EAS_I16)(gain >> SYNTH_UPDATE_PERIOD_IN_BITS);
+}
+#endif
+
+#ifdef _OPTIMIZED_MONO
+/*----------------------------------------------------------------------------
+ * WT_ProcessVoice
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * This routine does the block processing for one voice. It is isolated
+ * from the main synth code to allow for various implementation-specific
+ * optimizations. It calls the interpolator, filter, and gain routines
+ * appropriate for a particular configuration.
+ *
+ * Inputs:
+ *
+ * Outputs:
+ *
+ * Notes:
+ * This special version works handles an optimized mono-only signal
+ * without filters
+ *----------------------------------------------------------------------------
+*/
+void WT_ProcessVoice (S_WT_VOICE *pWTVoice, S_WT_INT_FRAME *pWTIntFrame)
+{
+
+ /* use noise generator */
+ if (pWTVoice->loopStart== WT_NOISE_GENERATOR)
+ {
+ WT_NoiseGenerator(pWTVoice, pWTIntFrame);
+ WT_VoiceGain(pWTVoice, pWTIntFrame);
+ }
+
+ /* or generate interpolated samples */
+ else
+ {
+ WT_InterpolateMono(pWTVoice, pWTIntFrame);
+ }
+}
+#endif
+
diff --git a/arm-hybrid-22k/lib_src/eas_wtengine.h b/arm-hybrid-22k/lib_src/eas_wtengine.h
index 6401322..bba7a5e 100644
--- a/arm-hybrid-22k/lib_src/eas_wtengine.h
+++ b/arm-hybrid-22k/lib_src/eas_wtengine.h
@@ -1,12 +1,12 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_wtengine.h
- *
- * Contents and purpose:
- * This file defines the interface for wavetable synthesis engine
- *
- * Copyright Sonic Network Inc. 2004
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_wtengine.h
+ *
+ * Contents and purpose:
+ * This file defines the interface for wavetable synthesis engine
+ *
+ * Copyright Sonic Network Inc. 2004
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,153 +19,153 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 818 $
- * $Date: 2007-08-02 15:19:41 -0700 (Thu, 02 Aug 2007) $
- *----------------------------------------------------------------------------
-*/
-
-#ifndef _EAS_WTENGINE_H
-#define _EAS_WTENGINE_H
-
-/* option sanity check */
-#if defined(_OPTIMIZED_MONO) && defined(_FILTER_ENABLED)
-#error "Incompatible build settings: _OPTIMIZED_MONO cannot be used with _FILTER_ENABLED"
-#endif
-
-#if defined(_OPTIMIZED_MONO) && (NUM_OUTPUT_CHANNELS != 1)
-#error "Incompatible build settings: _OPTIMIZED_MONO can only be used with NUM_OUTPUT_CHANNELS = 1"
-#endif
-
-#include "eas_wt_IPC_frame.h"
-
-/*----------------------------------------------------------------------------
- * defines
- *----------------------------------------------------------------------------
-*/
-#define WT_NOISE_GENERATOR 0xffffffff
-
-/*----------------------------------------------------------------------------
- * typedefs
- *----------------------------------------------------------------------------
-*/
-
-/*----------------------------------------------------------------------------
- * S_WT_INT_FRAME
- *
- * This structure includes S_WT_FRAME plus the bus mixing
- * parameters for the internal voices.
- *----------------------------------------------------------------------------
-*/
-typedef struct s_wt_int_frame_tag
-{
- S_WT_FRAME frame;
- EAS_PCM *pAudioBuffer;
- EAS_I32 *pMixBuffer;
- EAS_I32 numSamples;
- EAS_I32 prevGain;
-} S_WT_INT_FRAME;
-
-#if defined(_FILTER_ENABLED)
-/*----------------------------------------------------------------------------
- * S_FILTER_CONTROL data structure
- *----------------------------------------------------------------------------
-*/
-typedef struct s_filter_control_tag
-{
- EAS_I16 z1; /* 1 sample delay state variable */
- EAS_I16 z2; /* 2 sample delay state variable */
-} S_FILTER_CONTROL;
-#endif
-
-/*------------------------------------
- * S_LFO_CONTROL data structure
- *------------------------------------
-*/
-typedef struct s_lfo_control_tag
-{
- EAS_I16 lfoValue; /* LFO current output value */
- EAS_I16 lfoPhase; /* LFO current phase */
-} S_LFO_CONTROL;
-
-/* bit definitions for S_WT_VOICE:flags */
-#define WT_FLAGS_ADPCM_NIBBLE 1 /* high/low nibble flag */
-#define WT_FLAGS_ADPCM_READY 2 /* first 2 samples are decoded */
-#define WT_FLAGS_USE_ADPCM 4 /* sample is ADPCM encoded */
-
-/* eg1State and eg2State */
-typedef enum {
- eEnvelopeStateInit = 0,
- eEnvelopeStateDelay,
- eEnvelopeStateAttack,
- eEnvelopeStateHold,
- eEnvelopeStateDecay,
- eEnvelopeStateSustain,
- eEnvelopeStateRelease,
- eEnvelopeStateMuting,
- eEnvelopeStateMuted,
- eEnvelopeStateInvalid /* should never be in this state! */
-} E_ENVELOPE_STATE;
-
-#define DEFAULT_EG1_STATE eEnvelopeStateAttack
-#define DEFAULT_EG1_VALUE 0
-#define DEFAULT_EG1_INCREMENT 0
-#define DEFAULT_EG2_STATE eEnvelopeStateAttack
-#define DEFAULT_EG2_VALUE 0
-#define DEFAULT_EG2_INCREMENT 0
-
-/*----------------------------------------------------------------------------
- * S_WT_VOICE
- *
- * This structure contains state data for the wavetable engine
- *----------------------------------------------------------------------------
-*/
-typedef struct s_wt_voice_tag
-{
- EAS_U32 loopEnd; /* points to last PCM sample (not 1 beyond last) */
- EAS_U32 loopStart; /* points to first sample at start of loop */
- EAS_U32 phaseAccum; /* current sample, integer portion of phase */
- EAS_U32 phaseFrac; /* fractional portion of phase */
-
-#if (NUM_OUTPUT_CHANNELS == 2)
- EAS_I16 gainLeft; /* current gain, left ch */
- EAS_I16 gainRight; /* current gain, right ch */
-#endif
-
-#if defined(_FILTER_ENABLED)
- S_FILTER_CONTROL filter; /* low pass filter */
-#endif
-
- S_LFO_CONTROL modLFO; /* modulator LFO */
-
-#ifdef DLS_SYNTHESIZER
- S_LFO_CONTROL vibLFO; /* vibrato LFO */
-#endif
-
- /* envelope control */
- EAS_I16 eg1Value;
- EAS_I16 eg2Value;
- EAS_I16 eg1Increment;
- EAS_I16 eg2Increment;
- EAS_U8 eg1State;
- EAS_U8 eg2State;
-
- EAS_U16 artIndex; /* index to articulation params */
-
-} S_WT_VOICE;
-
-/*----------------------------------------------------------------------------
- * prototypes
- *----------------------------------------------------------------------------
-*/
-EAS_BOOL WT_CheckSampleEnd (S_WT_VOICE *pWTVoice, S_WT_INT_FRAME *pWTIntFrame, EAS_BOOL update);
-void WT_ProcessVoice (S_WT_VOICE *pWTVoice, S_WT_INT_FRAME *pWTIntFrame);
-
-#ifdef EAS_SPLIT_WT_SYNTH
-void WTE_ConfigVoice (EAS_I32 voiceNum, S_WT_CONFIG *pWTConfig, EAS_FRAME_BUFFER_HANDLE pFrameBuffer);
-void WTE_ProcessVoice (EAS_I32 voiceNum, S_WT_FRAME *pWTParams, EAS_FRAME_BUFFER_HANDLE pFrameBuffer);
-#endif
-
-#endif
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 818 $
+ * $Date: 2007-08-02 15:19:41 -0700 (Thu, 02 Aug 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+#ifndef _EAS_WTENGINE_H
+#define _EAS_WTENGINE_H
+
+/* option sanity check */
+#if defined(_OPTIMIZED_MONO) && defined(_FILTER_ENABLED)
+#error "Incompatible build settings: _OPTIMIZED_MONO cannot be used with _FILTER_ENABLED"
+#endif
+
+#if defined(_OPTIMIZED_MONO) && (NUM_OUTPUT_CHANNELS != 1)
+#error "Incompatible build settings: _OPTIMIZED_MONO can only be used with NUM_OUTPUT_CHANNELS = 1"
+#endif
+
+#include "eas_wt_IPC_frame.h"
+
+/*----------------------------------------------------------------------------
+ * defines
+ *----------------------------------------------------------------------------
+*/
+#define WT_NOISE_GENERATOR 0xffffffff
+
+/*----------------------------------------------------------------------------
+ * typedefs
+ *----------------------------------------------------------------------------
+*/
+
+/*----------------------------------------------------------------------------
+ * S_WT_INT_FRAME
+ *
+ * This structure includes S_WT_FRAME plus the bus mixing
+ * parameters for the internal voices.
+ *----------------------------------------------------------------------------
+*/
+typedef struct s_wt_int_frame_tag
+{
+ S_WT_FRAME frame;
+ EAS_PCM *pAudioBuffer;
+ EAS_I32 *pMixBuffer;
+ EAS_I32 numSamples;
+ EAS_I32 prevGain;
+} S_WT_INT_FRAME;
+
+#if defined(_FILTER_ENABLED)
+/*----------------------------------------------------------------------------
+ * S_FILTER_CONTROL data structure
+ *----------------------------------------------------------------------------
+*/
+typedef struct s_filter_control_tag
+{
+ EAS_I16 z1; /* 1 sample delay state variable */
+ EAS_I16 z2; /* 2 sample delay state variable */
+} S_FILTER_CONTROL;
+#endif
+
+/*------------------------------------
+ * S_LFO_CONTROL data structure
+ *------------------------------------
+*/
+typedef struct s_lfo_control_tag
+{
+ EAS_I16 lfoValue; /* LFO current output value */
+ EAS_I16 lfoPhase; /* LFO current phase */
+} S_LFO_CONTROL;
+
+/* bit definitions for S_WT_VOICE:flags */
+#define WT_FLAGS_ADPCM_NIBBLE 1 /* high/low nibble flag */
+#define WT_FLAGS_ADPCM_READY 2 /* first 2 samples are decoded */
+#define WT_FLAGS_USE_ADPCM 4 /* sample is ADPCM encoded */
+
+/* eg1State and eg2State */
+typedef enum {
+ eEnvelopeStateInit = 0,
+ eEnvelopeStateDelay,
+ eEnvelopeStateAttack,
+ eEnvelopeStateHold,
+ eEnvelopeStateDecay,
+ eEnvelopeStateSustain,
+ eEnvelopeStateRelease,
+ eEnvelopeStateMuting,
+ eEnvelopeStateMuted,
+ eEnvelopeStateInvalid /* should never be in this state! */
+} E_ENVELOPE_STATE;
+
+#define DEFAULT_EG1_STATE eEnvelopeStateAttack
+#define DEFAULT_EG1_VALUE 0
+#define DEFAULT_EG1_INCREMENT 0
+#define DEFAULT_EG2_STATE eEnvelopeStateAttack
+#define DEFAULT_EG2_VALUE 0
+#define DEFAULT_EG2_INCREMENT 0
+
+/*----------------------------------------------------------------------------
+ * S_WT_VOICE
+ *
+ * This structure contains state data for the wavetable engine
+ *----------------------------------------------------------------------------
+*/
+typedef struct s_wt_voice_tag
+{
+ EAS_U32 loopEnd; /* points to last PCM sample (not 1 beyond last) */
+ EAS_U32 loopStart; /* points to first sample at start of loop */
+ EAS_U32 phaseAccum; /* current sample, integer portion of phase */
+ EAS_U32 phaseFrac; /* fractional portion of phase */
+
+#if (NUM_OUTPUT_CHANNELS == 2)
+ EAS_I16 gainLeft; /* current gain, left ch */
+ EAS_I16 gainRight; /* current gain, right ch */
+#endif
+
+#if defined(_FILTER_ENABLED)
+ S_FILTER_CONTROL filter; /* low pass filter */
+#endif
+
+ S_LFO_CONTROL modLFO; /* modulator LFO */
+
+#ifdef DLS_SYNTHESIZER
+ S_LFO_CONTROL vibLFO; /* vibrato LFO */
+#endif
+
+ /* envelope control */
+ EAS_I16 eg1Value;
+ EAS_I16 eg2Value;
+ EAS_I16 eg1Increment;
+ EAS_I16 eg2Increment;
+ EAS_U8 eg1State;
+ EAS_U8 eg2State;
+
+ EAS_U16 artIndex; /* index to articulation params */
+
+} S_WT_VOICE;
+
+/*----------------------------------------------------------------------------
+ * prototypes
+ *----------------------------------------------------------------------------
+*/
+EAS_BOOL WT_CheckSampleEnd (S_WT_VOICE *pWTVoice, S_WT_INT_FRAME *pWTIntFrame, EAS_BOOL update);
+void WT_ProcessVoice (S_WT_VOICE *pWTVoice, S_WT_INT_FRAME *pWTIntFrame);
+
+#ifdef EAS_SPLIT_WT_SYNTH
+void WTE_ConfigVoice (EAS_I32 voiceNum, S_WT_CONFIG *pWTConfig, EAS_FRAME_BUFFER_HANDLE pFrameBuffer);
+void WTE_ProcessVoice (EAS_I32 voiceNum, S_WT_FRAME *pWTParams, EAS_FRAME_BUFFER_HANDLE pFrameBuffer);
+#endif
+
+#endif
diff --git a/arm-hybrid-22k/lib_src/eas_wtsynth.c b/arm-hybrid-22k/lib_src/eas_wtsynth.c
index 8098e09..788b34f 100644
--- a/arm-hybrid-22k/lib_src/eas_wtsynth.c
+++ b/arm-hybrid-22k/lib_src/eas_wtsynth.c
@@ -1,12 +1,12 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_wtsynth.c
- *
- * Contents and purpose:
- * Implements the synthesizer functions.
- *
- * Copyright Sonic Network Inc. 2004
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_wtsynth.c
+ *
+ * Contents and purpose:
+ * Implements the synthesizer functions.
+ *
+ * Copyright Sonic Network Inc. 2004
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,1233 +19,1233 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 795 $
- * $Date: 2007-08-01 00:14:45 -0700 (Wed, 01 Aug 2007) $
- *----------------------------------------------------------------------------
-*/
-
-// includes
-#include "eas_data.h"
-#include "eas_report.h"
-#include "eas_host.h"
-#include "eas_math.h"
-#include "eas_synth_protos.h"
-#include "eas_wtsynth.h"
-#include "eas_pan.h"
-
-#ifdef DLS_SYNTHESIZER
-#include "eas_dlssynth.h"
-#endif
-
-#ifdef _METRICS_ENABLED
-#include "eas_perf.h"
-#endif
-
-/* local prototypes */
-static EAS_RESULT WT_Initialize(S_VOICE_MGR *pVoiceMgr);
-static void WT_ReleaseVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, EAS_I32 voiceNum);
-static void WT_MuteVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, EAS_I32 voiceNum);
-static void WT_SustainPedal (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, S_SYNTH_CHANNEL *pChannel, EAS_I32 voiceNum);
-static EAS_RESULT WT_StartVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, EAS_I32 voiceNum, EAS_U16 regionIndex);
-static EAS_BOOL WT_UpdateVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, EAS_I32 voiceNum, EAS_I32 *pMixBuffer, EAS_I32 numSamples);
-static void WT_UpdateChannel (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel);
-static EAS_I32 WT_UpdatePhaseInc (S_WT_VOICE *pWTVoice, const S_ARTICULATION *pArt, S_SYNTH_CHANNEL *pChannel, EAS_I32 pitchCents);
-static EAS_I32 WT_UpdateGain (S_SYNTH_VOICE *pVoice, S_WT_VOICE *pWTVoice, const S_ARTICULATION *pArt, S_SYNTH_CHANNEL *pChannel, EAS_I32 gain);
-static void WT_UpdateEG1 (S_WT_VOICE *pWTVoice, const S_ENVELOPE *pEnv);
-static void WT_UpdateEG2 (S_WT_VOICE *pWTVoice, const S_ENVELOPE *pEnv);
-
-#ifdef EAS_SPLIT_WT_SYNTH
-extern EAS_BOOL WTE_StartFrame (EAS_FRAME_BUFFER_HANDLE pFrameBuffer);
-extern EAS_BOOL WTE_EndFrame (EAS_FRAME_BUFFER_HANDLE pFrameBuffer, EAS_I32 *pMixBuffer, EAS_I16 masterGain);
-#endif
-
-#ifdef _FILTER_ENABLED
-static void WT_UpdateFilter (S_WT_VOICE *pWTVoice, S_WT_INT_FRAME *pIntFrame, const S_ARTICULATION *pArt);
-#endif
-
-#ifdef _STATS
-extern double statsPhaseIncrement;
-extern double statsMaxPhaseIncrement;
-extern long statsPhaseSampleCount;
-extern double statsSampleSize;
-extern long statsSampleCount;
-#endif
-
-/*----------------------------------------------------------------------------
- * Synthesizer interface
- *----------------------------------------------------------------------------
-*/
-
-const S_SYNTH_INTERFACE wtSynth =
-{
- WT_Initialize,
- WT_StartVoice,
- WT_UpdateVoice,
- WT_ReleaseVoice,
- WT_MuteVoice,
- WT_SustainPedal,
- WT_UpdateChannel
-};
-
-#ifdef EAS_SPLIT_WT_SYNTH
-const S_FRAME_INTERFACE wtFrameInterface =
-{
- WTE_StartFrame,
- WTE_EndFrame
-};
-#endif
-
-/*----------------------------------------------------------------------------
- * WT_Initialize()
- *----------------------------------------------------------------------------
- * Purpose:
- *
- * Inputs:
- * pVoice - pointer to voice to initialize
- *
- * Outputs:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT WT_Initialize (S_VOICE_MGR *pVoiceMgr)
-{
- EAS_INT i;
-
- for (i = 0; i < NUM_WT_VOICES; i++)
- {
-
- pVoiceMgr->wtVoices[i].artIndex = DEFAULT_ARTICULATION_INDEX;
-
- pVoiceMgr->wtVoices[i].eg1State = DEFAULT_EG1_STATE;
- pVoiceMgr->wtVoices[i].eg1Value = DEFAULT_EG1_VALUE;
- pVoiceMgr->wtVoices[i].eg1Increment = DEFAULT_EG1_INCREMENT;
-
- pVoiceMgr->wtVoices[i].eg2State = DEFAULT_EG2_STATE;
- pVoiceMgr->wtVoices[i].eg2Value = DEFAULT_EG2_VALUE;
- pVoiceMgr->wtVoices[i].eg2Increment = DEFAULT_EG2_INCREMENT;
-
- /* left and right gain values are needed only if stereo output */
-#if (NUM_OUTPUT_CHANNELS == 2)
- pVoiceMgr->wtVoices[i].gainLeft = DEFAULT_VOICE_GAIN;
- pVoiceMgr->wtVoices[i].gainRight = DEFAULT_VOICE_GAIN;
-#endif
-
- pVoiceMgr->wtVoices[i].phaseFrac = DEFAULT_PHASE_FRAC;
- pVoiceMgr->wtVoices[i].phaseAccum = DEFAULT_PHASE_INT;
-
-#ifdef _FILTER_ENABLED
- pVoiceMgr->wtVoices[i].filter.z1 = DEFAULT_FILTER_ZERO;
- pVoiceMgr->wtVoices[i].filter.z2 = DEFAULT_FILTER_ZERO;
-#endif
- }
-
- return EAS_TRUE;
-}
-
-/*----------------------------------------------------------------------------
- * WT_ReleaseVoice()
- *----------------------------------------------------------------------------
- * Purpose:
- * The selected voice is being released.
- *
- * Inputs:
- * pEASData - pointer to S_EAS_DATA
- * pVoice - pointer to voice to release
- *
- * Outputs:
- * None
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, pVoice) used in some implementations */
-static void WT_ReleaseVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, EAS_I32 voiceNum)
-{
- S_WT_VOICE *pWTVoice;
- const S_ARTICULATION *pArticulation;
-
-#ifdef DLS_SYNTHESIZER
- if (pVoice->regionIndex & FLAG_RGN_IDX_DLS_SYNTH)
- {
- DLS_ReleaseVoice(pVoiceMgr, pSynth, pVoice, voiceNum);
- return;
- }
-#endif
-
- pWTVoice = &pVoiceMgr->wtVoices[voiceNum];
- pArticulation = &pSynth->pEAS->pArticulations[pWTVoice->artIndex];
-
- /* release EG1 */
- pWTVoice->eg1State = eEnvelopeStateRelease;
- pWTVoice->eg1Increment = pArticulation->eg1.releaseTime;
-
- /*
- The spec says we should release EG2, but doing so with the current
- voicing is causing clicks. This fix will need to be coordinated with
- a new sound library release
- */
-
- /* release EG2 */
- pWTVoice->eg2State = eEnvelopeStateRelease;
- pWTVoice->eg2Increment = pArticulation->eg2.releaseTime;
-}
-
-/*----------------------------------------------------------------------------
- * WT_MuteVoice()
- *----------------------------------------------------------------------------
- * Purpose:
- * The selected voice is being muted.
- *
- * Inputs:
- * pVoice - pointer to voice to release
- *
- * Outputs:
- * None
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, pSynth) used in some implementations */
-static void WT_MuteVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, EAS_I32 voiceNum)
-{
-
-#ifdef DLS_SYNTHESIZER
- if (pVoice->regionIndex & FLAG_RGN_IDX_DLS_SYNTH)
- {
- DLS_MuteVoice(pVoiceMgr, pSynth, pVoice, voiceNum);
- return;
- }
-#endif
-
- /* clear deferred action flags */
- pVoice->voiceFlags &=
- ~(VOICE_FLAG_DEFER_MIDI_NOTE_OFF |
- VOICE_FLAG_SUSTAIN_PEDAL_DEFER_NOTE_OFF |
- VOICE_FLAG_DEFER_MUTE);
-
- /* set the envelope state */
- pVoiceMgr->wtVoices[voiceNum].eg1State = eEnvelopeStateMuted;
- pVoiceMgr->wtVoices[voiceNum].eg2State = eEnvelopeStateMuted;
-}
-
-/*----------------------------------------------------------------------------
- * WT_SustainPedal()
- *----------------------------------------------------------------------------
- * Purpose:
- * The selected voice is held due to sustain pedal
- *
- * Inputs:
- * pVoice - pointer to voice to sustain
- *
- * Outputs:
- * None
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, pChannel) used in some implementations */
-static void WT_SustainPedal (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, S_SYNTH_CHANNEL *pChannel, EAS_I32 voiceNum)
-{
- S_WT_VOICE *pWTVoice;
-
-#ifdef DLS_SYNTHESIZER
- if (pVoice->regionIndex & FLAG_RGN_IDX_DLS_SYNTH)
- {
- DLS_SustainPedal(pVoiceMgr, pSynth, pVoice, pChannel, voiceNum);
- return;
- }
-#endif
-
- /* don't catch the voice if below the sustain level */
- pWTVoice = &pVoiceMgr->wtVoices[voiceNum];
- if (pWTVoice->eg1Value < pSynth->pEAS->pArticulations[pWTVoice->artIndex].eg1.sustainLevel)
- return;
-
- /* sustain flag is set, damper pedal is on */
- /* defer releasing this note until the damper pedal is off */
- pWTVoice->eg1State = eEnvelopeStateDecay;
- pVoice->voiceState = eVoiceStatePlay;
-
- /*
- because sustain pedal is on, this voice
- should defer releasing its note
- */
- pVoice->voiceFlags |= VOICE_FLAG_SUSTAIN_PEDAL_DEFER_NOTE_OFF;
-
-#ifdef _DEBUG_SYNTH
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "WT_SustainPedal: defer note off because sustain pedal is on\n"); */ }
-#endif
-}
-
-/*----------------------------------------------------------------------------
- * WT_StartVoice()
- *----------------------------------------------------------------------------
- * Purpose:
- * Assign the region for the given instrument using the midi key number
- * and the RPN2 (coarse tuning) value. By using RPN2 as part of the
- * region selection process, we reduce the amount a given sample has
- * to be transposed by selecting the closest recorded root instead.
- *
- * This routine is the second half of SynthAssignRegion().
- * If the region was successfully found by SynthFindRegionIndex(),
- * then assign the region's parameters to the voice.
- *
- * Setup and initialize the following voice parameters:
- * m_nRegionIndex
- *
- * Inputs:
- * pVoice - ptr to the voice we have assigned for this channel
- * nRegionIndex - index of the region
- * pEASData - pointer to overall EAS data structure
- *
- * Outputs:
- * success - could find and assign the region for this voice's note otherwise
- * failure - could not find nor assign the region for this voice's note
- *
- * Side Effects:
- * psSynthObject->m_sVoice[].m_nRegionIndex is assigned
- * psSynthObject->m_sVoice[] parameters are assigned
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT WT_StartVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, EAS_I32 voiceNum, EAS_U16 regionIndex)
-{
- S_WT_VOICE *pWTVoice;
- const S_WT_REGION *pRegion;
- const S_ARTICULATION *pArt;
- S_SYNTH_CHANNEL *pChannel;
-
-#if (NUM_OUTPUT_CHANNELS == 2)
- EAS_INT pan;
-#endif
-
-#ifdef EAS_SPLIT_WT_SYNTH
- S_WT_CONFIG wtConfig;
-#endif
-
- /* no samples have been synthesized for this note yet */
- pVoice->regionIndex = regionIndex;
- pVoice->voiceFlags = VOICE_FLAG_NO_SAMPLES_SYNTHESIZED_YET;
-
- /* get the articulation index for this region */
- pWTVoice = &pVoiceMgr->wtVoices[voiceNum];
- pChannel = &pSynth->channels[pVoice->channel & 15];
-
- /* update static channel parameters */
- if (pChannel->channelFlags & CHANNEL_FLAG_UPDATE_CHANNEL_PARAMETERS)
- WT_UpdateChannel(pVoiceMgr, pSynth, pVoice->channel & 15);
-
-#ifdef DLS_SYNTHESIZER
- if (pVoice->regionIndex & FLAG_RGN_IDX_DLS_SYNTH)
- return DLS_StartVoice(pVoiceMgr, pSynth, pVoice, voiceNum, regionIndex);
-#endif
-
- pRegion = &(pSynth->pEAS->pWTRegions[regionIndex]);
- pWTVoice->artIndex = pRegion->artIndex;
-
-#ifdef _DEBUG_SYNTH
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "WT_StartVoice: Voice %ld; Region %d\n", (EAS_I32) (pVoice - pVoiceMgr->voices), regionIndex); */ }
-#endif
-
- pArt = &pSynth->pEAS->pArticulations[pWTVoice->artIndex];
-
- /* MIDI note on puts this voice into attack state */
- pWTVoice->eg1State = eEnvelopeStateAttack;
- pWTVoice->eg1Value = 0;
- pWTVoice->eg1Increment = pArt->eg1.attackTime;
- pWTVoice->eg2State = eEnvelopeStateAttack;
- pWTVoice->eg2Value = 0;
- pWTVoice->eg2Increment = pArt->eg2.attackTime;
-
- /* init the LFO */
- pWTVoice->modLFO.lfoValue = 0;
- pWTVoice->modLFO.lfoPhase = -pArt->lfoDelay;
-
- pVoice->gain = 0;
-
-#if (NUM_OUTPUT_CHANNELS == 2)
- /*
- Get the Midi CC10 pan value for this voice's channel
- convert the pan value to an "angle" representation suitable for
- our sin, cos calculator. This representation is NOT necessarily the same
- as the transform in the GM manuals because of our sin, cos calculator.
- "angle" = (CC10 - 64)/128
- */
- pan = (EAS_INT) pSynth->channels[pVoice->channel & 15].pan - 64;
- pan += pArt->pan;
- EAS_CalcPanControl(pan, &pWTVoice->gainLeft, &pWTVoice->gainRight);
-#endif
-
-#ifdef _FILTER_ENABLED
- /* clear out the filter states */
- pWTVoice->filter.z1 = 0;
- pWTVoice->filter.z2 = 0;
-#endif
-
- /* if this wave is to be generated using noise generator */
- if (pRegion->region.keyGroupAndFlags & REGION_FLAG_USE_WAVE_GENERATOR)
- {
- pWTVoice->phaseAccum = 4574296;
- pWTVoice->loopStart = WT_NOISE_GENERATOR;
- pWTVoice->loopEnd = 4574295;
- }
-
- /* normal sample */
- else
- {
-
-#ifdef EAS_SPLIT_WT_SYNTH
- if (voiceNum < NUM_PRIMARY_VOICES)
- pWTVoice->phaseAccum = (EAS_U32) pSynth->pEAS->pSamples + pSynth->pEAS->pSampleOffsets[pRegion->waveIndex];
- else
- pWTVoice->phaseAccum = pSynth->pEAS->pSampleOffsets[pRegion->waveIndex];
-#else
- pWTVoice->phaseAccum = (EAS_U32) pSynth->pEAS->pSamples + pSynth->pEAS->pSampleOffsets[pRegion->waveIndex];
-#endif
-
- if (pRegion->region.keyGroupAndFlags & REGION_FLAG_IS_LOOPED)
- {
- pWTVoice->loopStart = pWTVoice->phaseAccum + pRegion->loopStart;
- pWTVoice->loopEnd = pWTVoice->phaseAccum + pRegion->loopEnd - 1;
- }
- else
- pWTVoice->loopStart = pWTVoice->loopEnd = pWTVoice->phaseAccum + pSynth->pEAS->pSampleLen[pRegion->waveIndex] - 1;
- }
-
-#ifdef EAS_SPLIT_WT_SYNTH
- /* configure off-chip voices */
- if (voiceNum >= NUM_PRIMARY_VOICES)
- {
- wtConfig.phaseAccum = pWTVoice->phaseAccum;
- wtConfig.loopStart = pWTVoice->loopStart;
- wtConfig.loopEnd = pWTVoice->loopEnd;
- wtConfig.gain = pVoice->gain;
-
-#if (NUM_OUTPUT_CHANNELS == 2)
- wtConfig.gainLeft = pWTVoice->gainLeft;
- wtConfig.gainRight = pWTVoice->gainRight;
-#endif
-
- WTE_ConfigVoice(voiceNum - NUM_PRIMARY_VOICES, &wtConfig, pVoiceMgr->pFrameBuffer);
- }
-#endif
-
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * WT_CheckSampleEnd
- *----------------------------------------------------------------------------
- * Purpose:
- * Check for end of sample and calculate number of samples to synthesize
- *
- * Inputs:
- *
- * Outputs:
- *
- * Notes:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_BOOL WT_CheckSampleEnd (S_WT_VOICE *pWTVoice, S_WT_INT_FRAME *pWTIntFrame, EAS_BOOL update)
-{
- EAS_U32 endPhaseAccum;
- EAS_U32 endPhaseFrac;
- EAS_I32 numSamples;
- EAS_BOOL done = EAS_FALSE;
-
- /* check to see if we hit the end of the waveform this time */
- /*lint -e{703} use shift for performance */
- endPhaseFrac = pWTVoice->phaseFrac + (pWTIntFrame->frame.phaseIncrement << SYNTH_UPDATE_PERIOD_IN_BITS);
- endPhaseAccum = pWTVoice->phaseAccum + GET_PHASE_INT_PART(endPhaseFrac);
- if (endPhaseAccum >= pWTVoice->loopEnd)
- {
- /* calculate how far current ptr is from end */
- numSamples = (EAS_I32) (pWTVoice->loopEnd - pWTVoice->phaseAccum);
-
- /* now account for the fractional portion */
- /*lint -e{703} use shift for performance */
- numSamples = (EAS_I32) ((numSamples << NUM_PHASE_FRAC_BITS) - pWTVoice->phaseFrac);
- pWTIntFrame->numSamples = 1 + (numSamples / pWTIntFrame->frame.phaseIncrement);
-
- /* sound will be done this frame */
- done = EAS_TRUE;
- }
-
- /* update data for off-chip synth */
- if (update)
- {
- pWTVoice->phaseFrac = endPhaseFrac;
- pWTVoice->phaseAccum = endPhaseAccum;
- }
-
- return done;
-}
-
-/*----------------------------------------------------------------------------
- * WT_UpdateVoice()
- *----------------------------------------------------------------------------
- * Purpose:
- * Synthesize a block of samples for the given voice.
- * Use linear interpolation.
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- *
- * Outputs:
- * number of samples actually written to buffer
- *
- * Side Effects:
- * - samples are added to the presently free buffer
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_BOOL WT_UpdateVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, EAS_I32 voiceNum, EAS_I32 *pMixBuffer, EAS_I32 numSamples)
-{
- S_WT_VOICE *pWTVoice;
- S_WT_INT_FRAME intFrame;
- S_SYNTH_CHANNEL *pChannel;
- const S_WT_REGION *pWTRegion;
- const S_ARTICULATION *pArt;
- EAS_I32 temp;
- EAS_BOOL done;
-
-#ifdef DLS_SYNTHESIZER
- if (pVoice->regionIndex & FLAG_RGN_IDX_DLS_SYNTH)
- return DLS_UpdateVoice(pVoiceMgr, pSynth, pVoice, voiceNum, pMixBuffer, numSamples);
-#endif
-
- /* establish pointers to critical data */
- pWTVoice = &pVoiceMgr->wtVoices[voiceNum];
- pWTRegion = &pSynth->pEAS->pWTRegions[pVoice->regionIndex & REGION_INDEX_MASK];
- pArt = &pSynth->pEAS->pArticulations[pWTVoice->artIndex];
- pChannel = &pSynth->channels[pVoice->channel & 15];
- intFrame.prevGain = pVoice->gain;
-
- /* update the envelopes */
- WT_UpdateEG1(pWTVoice, &pArt->eg1);
- WT_UpdateEG2(pWTVoice, &pArt->eg2);
-
- /* update the LFO */
- WT_UpdateLFO(&pWTVoice->modLFO, pArt->lfoFreq);
-
-#ifdef _FILTER_ENABLED
- /* calculate filter if library uses filter */
- if (pSynth->pEAS->libAttr & LIB_FORMAT_FILTER_ENABLED)
- WT_UpdateFilter(pWTVoice, &intFrame, pArt);
- else
- intFrame.frame.k = 0;
-#endif
-
- /* update the gain */
- intFrame.frame.gainTarget = WT_UpdateGain(pVoice, pWTVoice, pArt, pChannel, pWTRegion->gain);
-
- /* calculate base pitch*/
- temp = pChannel->staticPitch + pWTRegion->tuning;
-
- /* include global transpose */
- if (pChannel->channelFlags & CHANNEL_FLAG_RHYTHM_CHANNEL)
- temp += pVoice->note * 100;
- else
- temp += (pVoice->note + pSynth->globalTranspose) * 100;
- intFrame.frame.phaseIncrement = WT_UpdatePhaseInc(pWTVoice, pArt, pChannel, temp);
-
- /* call into engine to generate samples */
- intFrame.pAudioBuffer = pVoiceMgr->voiceBuffer;
- intFrame.pMixBuffer = pMixBuffer;
- intFrame.numSamples = numSamples;
-
- /* check for end of sample */
- if ((pWTVoice->loopStart != WT_NOISE_GENERATOR) && (pWTVoice->loopStart == pWTVoice->loopEnd))
- done = WT_CheckSampleEnd(pWTVoice, &intFrame, (EAS_BOOL) (voiceNum >= NUM_PRIMARY_VOICES));
- else
- done = EAS_FALSE;
-
-#ifdef EAS_SPLIT_WT_SYNTH
- if (voiceNum < NUM_PRIMARY_VOICES)
- {
-#ifndef _SPLIT_WT_TEST_HARNESS
- WT_ProcessVoice(pWTVoice, &intFrame);
-#endif
- }
- else
- WTE_ProcessVoice(voiceNum - NUM_PRIMARY_VOICES, &intFrame.frame, pVoiceMgr->pFrameBuffer);
-#else
- WT_ProcessVoice(pWTVoice, &intFrame);
-#endif
-
- /* clear flag */
- pVoice->voiceFlags &= ~VOICE_FLAG_NO_SAMPLES_SYNTHESIZED_YET;
-
- /* if voice has finished, set flag for voice manager */
- if ((pVoice->voiceState != eVoiceStateStolen) && (pWTVoice->eg1State == eEnvelopeStateMuted))
- done = EAS_TRUE;
-
- /* if the update interval has elapsed, then force the current gain to the next
- * gain since we never actually reach the next gain when ramping -- we just get
- * very close to the target gain.
- */
- pVoice->gain = (EAS_I16) intFrame.frame.gainTarget;
-
- return done;
-}
-
-/*----------------------------------------------------------------------------
- * WT_UpdatePhaseInc()
- *----------------------------------------------------------------------------
- * Purpose:
- * Calculate the phase increment
- *
- * Inputs:
- * pVoice - pointer to the voice being updated
- * psRegion - pointer to the region
- * psArticulation - pointer to the articulation
- * nChannelPitchForThisVoice - the portion of the pitch that is fixed for this
- * voice during the duration of this synthesis
- * pEASData - pointer to overall EAS data structure
- *
- * Outputs:
- *
- * Side Effects:
- * set the phase increment for this voice
- *----------------------------------------------------------------------------
-*/
-static EAS_I32 WT_UpdatePhaseInc (S_WT_VOICE *pWTVoice, const S_ARTICULATION *pArt, S_SYNTH_CHANNEL *pChannel, EAS_I32 pitchCents)
-{
- EAS_I32 temp;
-
- /*pitchCents due to CC1 = LFO * (CC1 / 128) * DEFAULT_LFO_MOD_WHEEL_TO_PITCH_CENTS */
- temp = MULT_EG1_EG1(DEFAULT_LFO_MOD_WHEEL_TO_PITCH_CENTS,
- ((pChannel->modWheel) << (NUM_EG1_FRAC_BITS -7)));
-
- /* pitchCents due to channel pressure = LFO * (channel pressure / 128) * DEFAULT_LFO_CHANNEL_PRESSURE_TO_PITCH_CENTS */
- temp += MULT_EG1_EG1(DEFAULT_LFO_CHANNEL_PRESSURE_TO_PITCH_CENTS,
- ((pChannel->channelPressure) << (NUM_EG1_FRAC_BITS -7)));
-
- /* now multiply the (channel pressure + CC1) pitch values by the LFO value */
- temp = MULT_EG1_EG1(pWTVoice->modLFO.lfoValue, temp);
-
- /*
- add in the LFO pitch due to
- channel pressure and CC1 along with
- the LFO pitch, the EG2 pitch, and the
- "static" pitch for this voice on this channel
- */
- temp += pitchCents +
- (MULT_EG1_EG1(pWTVoice->eg2Value, pArt->eg2ToPitch)) +
- (MULT_EG1_EG1(pWTVoice->modLFO.lfoValue, pArt->lfoToPitch));
-
- /* convert from cents to linear phase increment */
- return EAS_Calculate2toX(temp);
-}
-
-/*----------------------------------------------------------------------------
- * WT_UpdateChannel()
- *----------------------------------------------------------------------------
- * Purpose:
- * Calculate and assign static channel parameters
- * These values only need to be updated if one of the controller values
- * for this channel changes
- *
- * Inputs:
- * nChannel - channel to update
- * pEASData - pointer to overall EAS data structure
- *
- * Outputs:
- *
- * Side Effects:
- * - the given channel's static gain and static pitch are updated
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, pVoiceMgr) reserved for future use */
-static void WT_UpdateChannel (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel)
-{
- EAS_I32 staticGain;
- EAS_I32 pitchBend;
- S_SYNTH_CHANNEL *pChannel;
-
- pChannel = &pSynth->channels[channel];
-
- /*
- nChannelGain = (CC7 * CC11)^2 * master volume
- where CC7 == 100 by default, CC11 == 127, master volume == 32767
- */
- staticGain = MULT_EG1_EG1((pChannel->volume) << (NUM_EG1_FRAC_BITS - 7),
- (pChannel->expression) << (NUM_EG1_FRAC_BITS - 7));
-
- /* staticGain has to be squared */
- staticGain = MULT_EG1_EG1(staticGain, staticGain);
-
- pChannel->staticGain = (EAS_I16) MULT_EG1_EG1(staticGain, pSynth->masterVolume);
-
- /*
- calculate pitch bend: RPN0 * ((2*pitch wheel)/16384 -1)
- However, if we use the EG1 macros, remember that EG1 has a full
- scale value of 32768 (instead of 16384). So instead of multiplying
- by 2, multiply by 4 (left shift by 2), and subtract by 32768 instead
- of 16384. This utilizes the fact that the EG1 macro places a binary
- point 15 places to the left instead of 14 places.
- */
- /*lint -e{703} <avoid multiply for performance>*/
- pitchBend =
- (((EAS_I32)(pChannel->pitchBend) << 2)
- - 32768);
-
- pChannel->staticPitch =
- MULT_EG1_EG1(pitchBend, pChannel->pitchBendSensitivity);
-
- /* if this is not a drum channel, then add in the per-channel tuning */
- if (!(pChannel->channelFlags & CHANNEL_FLAG_RHYTHM_CHANNEL))
- pChannel->staticPitch += pChannel->finePitch + (pChannel->coarsePitch * 100);
-
- /* clear update flag */
- pChannel->channelFlags &= ~CHANNEL_FLAG_UPDATE_CHANNEL_PARAMETERS;
- return;
-}
-
-/*----------------------------------------------------------------------------
- * WT_UpdateGain()
- *----------------------------------------------------------------------------
- * Purpose:
- * Calculate and assign static voice parameters as part of WT_UpdateVoice()
- *
- * Inputs:
- * pVoice - ptr to the synth voice that we want to synthesize
- * pEASData - pointer to overall EAS data structure
- *
- * Outputs:
- *
- * Side Effects:
- * - various voice parameters are calculated and assigned
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_I32 WT_UpdateGain (S_SYNTH_VOICE *pVoice, S_WT_VOICE *pWTVoice, const S_ARTICULATION *pArt, S_SYNTH_CHANNEL *pChannel, EAS_I32 gain)
-{
- EAS_I32 lfoGain;
- EAS_I32 temp;
-
- /*
- If this voice was stolen, then the velocity is actually
- for the new note, not the note that we are currently ramping down.
- So we really shouldn't use this velocity. However, that would require
- more memory to store the velocity value, and the improvement may
- not be sufficient to warrant the added memory.
- */
- /* velocity is fixed at note start for a given voice and must be squared */
- temp = (pVoice->velocity) << (NUM_EG1_FRAC_BITS - 7);
- temp = MULT_EG1_EG1(temp, temp);
-
- /* region gain is fixed as part of the articulation */
- temp = MULT_EG1_EG1(temp, gain);
-
- /* include the channel gain */
- temp = MULT_EG1_EG1(temp, pChannel->staticGain);
-
- /* calculate LFO gain using an approximation for 10^x */
- lfoGain = MULT_EG1_EG1(pWTVoice->modLFO.lfoValue, pArt->lfoToGain);
- lfoGain = MULT_EG1_EG1(lfoGain, LFO_GAIN_TO_CENTS);
-
- /* convert from a dB-like value to linear gain */
- lfoGain = EAS_Calculate2toX(lfoGain);
- temp = MULT_EG1_EG1(temp, lfoGain);
-
- /* calculate the voice's gain */
- temp = (EAS_I16)MULT_EG1_EG1(temp, pWTVoice->eg1Value);
-
- return temp;
-}
-
-/*----------------------------------------------------------------------------
- * WT_UpdateEG1()
- *----------------------------------------------------------------------------
- * Purpose:
- * Calculate the EG1 envelope for the given voice (but do not update any
- * state)
- *
- * Inputs:
- * pVoice - ptr to the voice whose envelope we want to update
- * nVoice - this voice's number - used only for debug
- * pEASData - pointer to overall EAS data structure
- *
- * Outputs:
- * nValue - the envelope value
- *
- * Side Effects:
- * - updates EG1 state value for the given voice
- *----------------------------------------------------------------------------
-*/
-static void WT_UpdateEG1 (S_WT_VOICE *pWTVoice, const S_ENVELOPE *pEnv)
-{
- EAS_I32 temp;
-
- switch (pWTVoice->eg1State)
- {
- case eEnvelopeStateAttack:
- temp = pWTVoice->eg1Value + pWTVoice->eg1Increment;
-
- /* check if we have reached peak amplitude */
- if (temp >= SYNTH_FULL_SCALE_EG1_GAIN)
- {
- /* limit the volume */
- temp = SYNTH_FULL_SCALE_EG1_GAIN;
-
- /* prepare to move to decay state */
- pWTVoice->eg1State = eEnvelopeStateDecay;
- pWTVoice->eg1Increment = pEnv->decayTime;
- }
-
- break;
-
- /* exponential decay */
- case eEnvelopeStateDecay:
- temp = MULT_EG1_EG1(pWTVoice->eg1Value, pWTVoice->eg1Increment);
-
- /* check if we have reached sustain level */
- if (temp <= pEnv->sustainLevel)
- {
- /* enforce the sustain level */
- temp = pEnv->sustainLevel;
-
- /* if sustain level is zero, skip sustain & release the voice */
- if (temp > 0)
- pWTVoice->eg1State = eEnvelopeStateSustain;
-
- /* move to sustain state */
- else
- pWTVoice->eg1State = eEnvelopeStateMuted;
- }
-
- break;
-
- case eEnvelopeStateSustain:
- return;
-
- case eEnvelopeStateRelease:
- temp = MULT_EG1_EG1(pWTVoice->eg1Value, pWTVoice->eg1Increment);
-
- /* if we hit zero, this voice isn't contributing any audio */
- if (temp <= 0)
- {
- temp = 0;
- pWTVoice->eg1State = eEnvelopeStateMuted;
- }
- break;
-
- /* voice is muted, set target to zero */
- case eEnvelopeStateMuted:
- temp = 0;
- break;
-
- case eEnvelopeStateInvalid:
- default:
- temp = 0;
-#ifdef _DEBUG_SYNTH
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "WT_UpdateEG1: error, %d is an unrecognized state\n",
- pWTVoice->eg1State); */ }
-#endif
- break;
-
- }
-
- pWTVoice->eg1Value = (EAS_I16) temp;
-}
-
-/*----------------------------------------------------------------------------
- * WT_UpdateEG2()
- *----------------------------------------------------------------------------
- * Purpose:
- * Update the EG2 envelope for the given voice
- *
- * Inputs:
- * pVoice - ptr to the voice whose envelope we want to update
- * pEASData - pointer to overall EAS data structure
- *
- * Outputs:
- *
- * Side Effects:
- * - updates EG2 values for the given voice
- *----------------------------------------------------------------------------
-*/
-
-static void WT_UpdateEG2 (S_WT_VOICE *pWTVoice, const S_ENVELOPE *pEnv)
-{
- EAS_I32 temp;
-
- switch (pWTVoice->eg2State)
- {
- case eEnvelopeStateAttack:
- temp = pWTVoice->eg2Value + pWTVoice->eg2Increment;
-
- /* check if we have reached peak amplitude */
- if (temp >= SYNTH_FULL_SCALE_EG1_GAIN)
- {
- /* limit the volume */
- temp = SYNTH_FULL_SCALE_EG1_GAIN;
-
- /* prepare to move to decay state */
- pWTVoice->eg2State = eEnvelopeStateDecay;
-
- pWTVoice->eg2Increment = pEnv->decayTime;
- }
-
- break;
-
- /* implement linear pitch decay in cents */
- case eEnvelopeStateDecay:
- temp = pWTVoice->eg2Value -pWTVoice->eg2Increment;
-
- /* check if we have reached sustain level */
- if (temp <= pEnv->sustainLevel)
- {
- /* enforce the sustain level */
- temp = pEnv->sustainLevel;
-
- /* prepare to move to sustain state */
- pWTVoice->eg2State = eEnvelopeStateSustain;
- }
- break;
-
- case eEnvelopeStateSustain:
- return;
-
- case eEnvelopeStateRelease:
- temp = pWTVoice->eg2Value - pWTVoice->eg2Increment;
-
- if (temp <= 0)
- {
- temp = 0;
- pWTVoice->eg2State = eEnvelopeStateMuted;
- }
-
- break;
-
- /* voice is muted, set target to zero */
- case eEnvelopeStateMuted:
- temp = 0;
- break;
-
- case eEnvelopeStateInvalid:
- default:
- temp = 0;
-#ifdef _DEBUG_SYNTH
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "WT_UpdateEG2: error, %d is an unrecognized state\n",
- pWTVoice->eg2State); */ }
-#endif
- break;
- }
-
- pWTVoice->eg2Value = (EAS_I16) temp;
-}
-
-/*----------------------------------------------------------------------------
- * WT_UpdateLFO ()
- *----------------------------------------------------------------------------
- * Purpose:
- * Calculate the LFO for the given voice
- *
- * Inputs:
- * pLFO - ptr to the LFO data
- * phaseInc - phase increment
- *
- * Outputs:
- *
- * Side Effects:
- * - updates LFO values for the given voice
- *----------------------------------------------------------------------------
-*/
-void WT_UpdateLFO (S_LFO_CONTROL *pLFO, EAS_I16 phaseInc)
-{
-
- /* To save memory, if m_nPhaseValue is negative, we are in the
- * delay phase, and m_nPhaseValue represents the time left
- * in the delay.
- */
- if (pLFO->lfoPhase < 0)
- {
- pLFO->lfoPhase++;
- return;
- }
-
- /* calculate LFO output from phase value */
- /*lint -e{701} Use shift for performance */
- pLFO->lfoValue = (EAS_I16) (pLFO->lfoPhase << 2);
- /*lint -e{502} <shortcut to turn sawtooth into triangle wave> */
- if ((pLFO->lfoPhase > 0x1fff) && (pLFO->lfoPhase < 0x6000))
- pLFO->lfoValue = ~pLFO->lfoValue;
-
- /* update LFO phase */
- pLFO->lfoPhase = (pLFO->lfoPhase + phaseInc) & 0x7fff;
-}
-
-#ifdef _FILTER_ENABLED
-/*----------------------------------------------------------------------------
- * WT_UpdateFilter()
- *----------------------------------------------------------------------------
- * Purpose:
- * Update the Filter parameters
- *
- * Inputs:
- * pVoice - ptr to the voice whose filter we want to update
- * pEASData - pointer to overall EAS data structure
- *
- * Outputs:
- *
- * Side Effects:
- * - updates Filter values for the given voice
- *----------------------------------------------------------------------------
-*/
-static void WT_UpdateFilter (S_WT_VOICE *pWTVoice, S_WT_INT_FRAME *pIntFrame, const S_ARTICULATION *pArt)
-{
- EAS_I32 cutoff;
-
- /* no need to calculate filter coefficients if it is bypassed */
- if (pArt->filterCutoff == DEFAULT_EAS_FILTER_CUTOFF_FREQUENCY)
- {
- pIntFrame->frame.k = 0;
- return;
- }
-
- /* determine the dynamic cutoff frequency */
- cutoff = MULT_EG1_EG1(pWTVoice->eg2Value, pArt->eg2ToFc);
- cutoff += pArt->filterCutoff;
-
- /* subtract the A5 offset and the sampling frequency */
- cutoff -= FILTER_CUTOFF_FREQ_ADJUST + A5_PITCH_OFFSET_IN_CENTS;
-
- /* limit the cutoff frequency */
- if (cutoff > FILTER_CUTOFF_MAX_PITCH_CENTS)
- cutoff = FILTER_CUTOFF_MAX_PITCH_CENTS;
- else if (cutoff < FILTER_CUTOFF_MIN_PITCH_CENTS)
- cutoff = FILTER_CUTOFF_MIN_PITCH_CENTS;
-
- WT_SetFilterCoeffs(pIntFrame, cutoff, pArt->filterQ);
-}
-#endif
-
-#if defined(_FILTER_ENABLED) || defined(DLS_SYNTHESIZER)
-/*----------------------------------------------------------------------------
- * coef
- *----------------------------------------------------------------------------
- * Table of filter coefficients for low-pass filter
- *----------------------------------------------------------------------------
- *
- * polynomial coefficients are based on 8kHz sampling frequency
- * filter coef b2 = k2 = k2g0*k^0 + k2g1*k^1*(2^x) + k2g2*k^2*(2^x)
- *
- *where k2g0, k2g1, k2g2 are from the truncated power series expansion on theta
- *(k*2^x = theta, but we incorporate the k along with the k2g0, k2g1, k2g2)
- *note: this is a power series in 2^x, not k*2^x
- *where k = (2*pi*440)/8kHz == convert octaves to radians
- *
- * so actually, the following coefs listed as k2g0, k2g1, k2g2 are really
- * k2g0*k^0 = k2g0
- * k2g1*k^1
- * k2g2*k^2
- *
- *
- * filter coef n1 = numerator = n1g0*k^0 + n1g1*k^1*(2^x) + n1g2*k^2*(2^x) + n1g3*k^3*(2^x)
- *
- *where n1g0, n1g1, n1g2, n1g3 are from the truncated power series expansion on theta
- *(k*2^x = theta, but we incorporate the k along with the n1g0, n1g1, n1g2, n2g3)
- *note: this is a power series in 2^x, not k*2^x
- *where k = (2*pi*440)/8kHz == convert octaves to radians
- *we also include the optimization factor of 0.81
- *
- * so actually, the following coefs listed as n1g0, n1g1, n1g2, n2g3 are really
- * n1g0*k^0 = n1g0
- * n1g1*k^1
- * n1g2*k^2
- * n1g3*k^3
- *
- * NOTE that n1g0 == n1g1 == 0, always, so we only need to store n1g2 and n1g3
- *----------------------------------------------------------------------------
-*/
-
-static const EAS_I16 nk1g0 = -32768;
-static const EAS_I16 nk1g2 = 1580;
-static const EAS_I16 k2g0 = 32767;
-
-static const EAS_I16 k2g1[] =
-{
- -11324, /* k2g1[0] = -0.3455751918948761 */
- -10387, /* k2g1[1] = -0.3169878073928751 */
- -9528, /* k2g1[2] = -0.29076528753345476 */
- -8740, /* k2g1[3] = -0.2667120011011279 */
- -8017, /* k2g1[4] = -0.24464850028971705 */
- -7353, /* k2g1[5] = -0.22441018194495696 */
- -6745, /* k2g1[6] = -0.20584605955455101 */
- -6187, /* k2g1[7] = -0.18881763682420102 */
- -5675, /* k2g1[8] = -0.1731978744360067 */
- -5206, /* k2g1[9] = -0.15887024228080968 */
- -4775, /* k2g1[10] = -0.14572785009373057 */
- -4380, /* k2g1[11] = -0.13367265000706827 */
- -4018, /* k2g1[12] = -0.1226147050712642 */
- -3685, /* k2g1[13] = -0.11247151828678581 */
- -3381, /* k2g1[14] = -0.10316741714122014 */
- -3101, /* k2g1[15] = -0.0946329890599603 */
- -2844, /* k2g1[16] = -0.08680456355870586 */
- -2609, /* k2g1[17] = -0.07962373723441349 */
- -2393, /* k2g1[18] = -0.07303693805092666 */
- -2195, /* k2g1[19] = -0.06699502566866912 */
- -2014, /* k2g1[20] = -0.06145292483669077 */
- -1847, /* k2g1[21] = -0.056369289112013346 */
- -1694, /* k2g1[22] = -0.05170619239747895 */
- -1554, /* k2g1[23] = -0.04742884599684141 */
- -1426, /* k2g1[24] = -0.043505339076210514 */
- -1308, /* k2g1[25] = -0.03990640059558053 */
- -1199, /* k2g1[26] = -0.03660518093435039 */
- -1100, /* k2g1[27] = -0.03357705158166837 */
- -1009, /* k2g1[28] = -0.030799421397205727 */
- -926, /* k2g1[29] = -0.028251568071585884 */
- -849 /* k2g1[30] = -0.025914483529091967 */
-};
-
-static const EAS_I16 k2g2[] =
-{
- 1957, /* k2g2[0] = 0.059711106626580836 */
- 1646, /* k2g2[1] = 0.05024063501786333 */
- 1385, /* k2g2[2] = 0.042272226217199664 */
- 1165, /* k2g2[3] = 0.03556764576567844 */
- 981, /* k2g2[4] = 0.029926444346999134 */
- 825, /* k2g2[5] = 0.025179964880280382 */
- 694, /* k2g2[6] = 0.02118630011706455 */
- 584, /* k2g2[7] = 0.01782604998793514 */
- 491, /* k2g2[8] = 0.014998751854573014 */
- 414, /* k2g2[9] = 0.012619876941179595 */
- 348, /* k2g2[10] = 0.010618303146468736 */
- 293, /* k2g2[11] = 0.008934188679954682 */
- 246, /* k2g2[12] = 0.007517182949855368 */
- 207, /* k2g2[13] = 0.006324921212866403 */
- 174, /* k2g2[14] = 0.005321757979794424 */
- 147, /* k2g2[15] = 0.004477701309210577 */
- 123, /* k2g2[16] = 0.00376751612730811 */
- 104, /* k2g2[17] = 0.0031699697655869644 */
- 87, /* k2g2[18] = 0.00266719715992703 */
- 74, /* k2g2[19] = 0.0022441667321724647 */
- 62, /* k2g2[20] = 0.0018882309854916855 */
- 52, /* k2g2[21] = 0.0015887483774966232 */
- 44, /* k2g2[22] = 0.0013367651661223448 */
- 37, /* k2g2[23] = 0.0011247477162958733 */
- 31, /* k2g2[24] = 0.0009463572640678758 */
- 26, /* k2g2[25] = 0.0007962604042473498 */
- 22, /* k2g2[26] = 0.0006699696356181593 */
- 18, /* k2g2[27] = 0.0005637091964589207 */
- 16, /* k2g2[28] = 0.00047430217920125243 */
- 13, /* k2g2[29] = 0.00039907554925166274 */
- 11 /* k2g2[30] = 0.00033578022828973666 */
-};
-
-static const EAS_I16 n1g2[] =
-{
- 3170, /* n1g2[0] = 0.0967319927350769 */
- 3036, /* n1g2[1] = 0.0926446051254155 */
- 2908, /* n1g2[2] = 0.08872992911818503 */
- 2785, /* n1g2[3] = 0.08498066682523227 */
- 2667, /* n1g2[4] = 0.08138982872895201 */
- 2554, /* n1g2[5] = 0.07795072065216213 */
- 2446, /* n1g2[6] = 0.0746569312785634 */
- 2343, /* n1g2[7] = 0.07150232020051943 */
- 2244, /* n1g2[8] = 0.06848100647187474 */
- 2149, /* n1g2[9] = 0.06558735764447099 */
- 2058, /* n1g2[10] = 0.06281597926792246 */
- 1971, /* n1g2[11] = 0.06016170483307614 */
- 1888, /* n1g2[12] = 0.05761958614040857 */
- 1808, /* n1g2[13] = 0.05518488407540374 */
- 1732, /* n1g2[14] = 0.052853059773715245 */
- 1659, /* n1g2[15] = 0.05061976615964251 */
- 1589, /* n1g2[16] = 0.04848083984214659 */
- 1521, /* n1g2[17] = 0.046432293353298 */
- 1457, /* n1g2[18] = 0.04447030771468711 */
- 1396, /* n1g2[19] = 0.04259122531793907 */
- 1337, /* n1g2[20] = 0.040791543106060944 */
- 1280, /* n1g2[21] = 0.03906790604290942 */
- 1226, /* n1g2[22] = 0.037417100858604564 */
- 1174, /* n1g2[23] = 0.035836050059229754 */
- 1125, /* n1g2[24] = 0.03432180618965023 */
- 1077, /* n1g2[25] = 0.03287154633875494 */
- 1032, /* n1g2[26] = 0.03148256687687814 */
- 988, /* n1g2[27] = 0.030152278415589925 */
- 946, /* n1g2[28] = 0.028878200980459685 */
- 906, /* n1g2[29] = 0.02765795938779331 */
- 868 /* n1g2[30] = 0.02648927881672521 */
-};
-
-static const EAS_I16 n1g3[] =
-{
- -548, /* n1g3[0] = -0.016714088475899017 */
- -481, /* n1g3[1] = -0.014683605122742116 */
- -423, /* n1g3[2] = -0.012899791676436092 */
- -371, /* n1g3[3] = -0.01133268185193299 */
- -326, /* n1g3[4] = -0.00995594976868754 */
- -287, /* n1g3[5] = -0.008746467702146129 */
- -252, /* n1g3[6] = -0.00768391756106361 */
- -221, /* n1g3[7] = -0.006750449563854721 */
- -194, /* n1g3[8] = -0.005930382380083576 */
- -171, /* n1g3[9] = -0.005209939699767622 */
- -150, /* n1g3[10] = -0.004577018805123356 */
- -132, /* n1g3[11] = -0.004020987256990177 */
- -116, /* n1g3[12] = -0.003532504280467257 */
- -102, /* n1g3[13] = -0.00310336384922047 */
- -89, /* n1g3[14] = -0.002726356832432369 */
- -78, /* n1g3[15] = -0.002395149888601605 */
- -69, /* n1g3[16] = -0.0021041790717285314 */
- -61, /* n1g3[17] = -0.0018485563625771063 */
- -53, /* n1g3[18] = -0.001623987554831628 */
- -47, /* n1g3[19] = -0.0014267001167177025 */
- -41, /* n1g3[20] = -0.0012533798162347005 */
- -36, /* n1g3[21] = -0.0011011150453668693 */
- -32, /* n1g3[22] = -0.0009673479079754438 */
- -28, /* n1g3[23] = -0.0008498312496971563 */
- -24, /* n1g3[24] = -0.0007465909079943587 */
- -21, /* n1g3[25] = -0.0006558925481952733 */
- -19, /* n1g3[26] = -0.0005762125284029567 */
- -17, /* n1g3[27] = -0.0005062123038325457 */
- -15, /* n1g3[28] = -0.0004447159405951901 */
- -13, /* n1g3[29] = -0.00039069036118270117 */
- -11 /* n1g3[30] = -0.00034322798979677605 */
-};
-
-/*----------------------------------------------------------------------------
- * WT_SetFilterCoeffs()
- *----------------------------------------------------------------------------
- * Purpose:
- * Update the Filter parameters
- *
- * Inputs:
- * pVoice - ptr to the voice whose filter we want to update
- * pEASData - pointer to overall EAS data structure
- *
- * Outputs:
- *
- * Side Effects:
- * - updates Filter values for the given voice
- *----------------------------------------------------------------------------
-*/
-void WT_SetFilterCoeffs (S_WT_INT_FRAME *pIntFrame, EAS_I32 cutoff, EAS_I32 resonance)
-{
- EAS_I32 temp;
-
- /*
- Convert the cutoff, which has had A5 subtracted, using the 2^x approx
- Note, this cutoff is related to theta cutoff by
- theta = k * 2^x
- We use 2^x and incorporate k in the power series coefs instead
- */
- cutoff = EAS_Calculate2toX(cutoff);
-
- /* calculate b2 coef */
- temp = k2g1[resonance] + MULT_AUDIO_COEF(cutoff, k2g2[resonance]);
- temp = k2g0 + MULT_AUDIO_COEF(cutoff, temp);
- pIntFrame->frame.b2 = temp;
-
- /* calculate b1 coef */
- temp = MULT_AUDIO_COEF(cutoff, nk1g2);
- temp = nk1g0 + MULT_AUDIO_COEF(cutoff, temp);
- temp += MULT_AUDIO_COEF(temp, pIntFrame->frame.b2);
- pIntFrame->frame.b1 = temp >> 1;
-
- /* calculate K coef */
- temp = n1g2[resonance] + MULT_AUDIO_COEF(cutoff, n1g3[resonance]);
- temp = MULT_AUDIO_COEF(cutoff, temp);
- temp = MULT_AUDIO_COEF(cutoff, temp);
- pIntFrame->frame.k = temp;
-}
-#endif
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 795 $
+ * $Date: 2007-08-01 00:14:45 -0700 (Wed, 01 Aug 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+// includes
+#include "eas_data.h"
+#include "eas_report.h"
+#include "eas_host.h"
+#include "eas_math.h"
+#include "eas_synth_protos.h"
+#include "eas_wtsynth.h"
+#include "eas_pan.h"
+
+#ifdef DLS_SYNTHESIZER
+#include "eas_dlssynth.h"
+#endif
+
+#ifdef _METRICS_ENABLED
+#include "eas_perf.h"
+#endif
+
+/* local prototypes */
+static EAS_RESULT WT_Initialize(S_VOICE_MGR *pVoiceMgr);
+static void WT_ReleaseVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, EAS_I32 voiceNum);
+static void WT_MuteVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, EAS_I32 voiceNum);
+static void WT_SustainPedal (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, S_SYNTH_CHANNEL *pChannel, EAS_I32 voiceNum);
+static EAS_RESULT WT_StartVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, EAS_I32 voiceNum, EAS_U16 regionIndex);
+static EAS_BOOL WT_UpdateVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, EAS_I32 voiceNum, EAS_I32 *pMixBuffer, EAS_I32 numSamples);
+static void WT_UpdateChannel (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel);
+static EAS_I32 WT_UpdatePhaseInc (S_WT_VOICE *pWTVoice, const S_ARTICULATION *pArt, S_SYNTH_CHANNEL *pChannel, EAS_I32 pitchCents);
+static EAS_I32 WT_UpdateGain (S_SYNTH_VOICE *pVoice, S_WT_VOICE *pWTVoice, const S_ARTICULATION *pArt, S_SYNTH_CHANNEL *pChannel, EAS_I32 gain);
+static void WT_UpdateEG1 (S_WT_VOICE *pWTVoice, const S_ENVELOPE *pEnv);
+static void WT_UpdateEG2 (S_WT_VOICE *pWTVoice, const S_ENVELOPE *pEnv);
+
+#ifdef EAS_SPLIT_WT_SYNTH
+extern EAS_BOOL WTE_StartFrame (EAS_FRAME_BUFFER_HANDLE pFrameBuffer);
+extern EAS_BOOL WTE_EndFrame (EAS_FRAME_BUFFER_HANDLE pFrameBuffer, EAS_I32 *pMixBuffer, EAS_I16 masterGain);
+#endif
+
+#ifdef _FILTER_ENABLED
+static void WT_UpdateFilter (S_WT_VOICE *pWTVoice, S_WT_INT_FRAME *pIntFrame, const S_ARTICULATION *pArt);
+#endif
+
+#ifdef _STATS
+extern double statsPhaseIncrement;
+extern double statsMaxPhaseIncrement;
+extern long statsPhaseSampleCount;
+extern double statsSampleSize;
+extern long statsSampleCount;
+#endif
+
+/*----------------------------------------------------------------------------
+ * Synthesizer interface
+ *----------------------------------------------------------------------------
+*/
+
+const S_SYNTH_INTERFACE wtSynth =
+{
+ WT_Initialize,
+ WT_StartVoice,
+ WT_UpdateVoice,
+ WT_ReleaseVoice,
+ WT_MuteVoice,
+ WT_SustainPedal,
+ WT_UpdateChannel
+};
+
+#ifdef EAS_SPLIT_WT_SYNTH
+const S_FRAME_INTERFACE wtFrameInterface =
+{
+ WTE_StartFrame,
+ WTE_EndFrame
+};
+#endif
+
+/*----------------------------------------------------------------------------
+ * WT_Initialize()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ *
+ * Inputs:
+ * pVoice - pointer to voice to initialize
+ *
+ * Outputs:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT WT_Initialize (S_VOICE_MGR *pVoiceMgr)
+{
+ EAS_INT i;
+
+ for (i = 0; i < NUM_WT_VOICES; i++)
+ {
+
+ pVoiceMgr->wtVoices[i].artIndex = DEFAULT_ARTICULATION_INDEX;
+
+ pVoiceMgr->wtVoices[i].eg1State = DEFAULT_EG1_STATE;
+ pVoiceMgr->wtVoices[i].eg1Value = DEFAULT_EG1_VALUE;
+ pVoiceMgr->wtVoices[i].eg1Increment = DEFAULT_EG1_INCREMENT;
+
+ pVoiceMgr->wtVoices[i].eg2State = DEFAULT_EG2_STATE;
+ pVoiceMgr->wtVoices[i].eg2Value = DEFAULT_EG2_VALUE;
+ pVoiceMgr->wtVoices[i].eg2Increment = DEFAULT_EG2_INCREMENT;
+
+ /* left and right gain values are needed only if stereo output */
+#if (NUM_OUTPUT_CHANNELS == 2)
+ pVoiceMgr->wtVoices[i].gainLeft = DEFAULT_VOICE_GAIN;
+ pVoiceMgr->wtVoices[i].gainRight = DEFAULT_VOICE_GAIN;
+#endif
+
+ pVoiceMgr->wtVoices[i].phaseFrac = DEFAULT_PHASE_FRAC;
+ pVoiceMgr->wtVoices[i].phaseAccum = DEFAULT_PHASE_INT;
+
+#ifdef _FILTER_ENABLED
+ pVoiceMgr->wtVoices[i].filter.z1 = DEFAULT_FILTER_ZERO;
+ pVoiceMgr->wtVoices[i].filter.z2 = DEFAULT_FILTER_ZERO;
+#endif
+ }
+
+ return EAS_TRUE;
+}
+
+/*----------------------------------------------------------------------------
+ * WT_ReleaseVoice()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * The selected voice is being released.
+ *
+ * Inputs:
+ * pEASData - pointer to S_EAS_DATA
+ * pVoice - pointer to voice to release
+ *
+ * Outputs:
+ * None
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pVoice) used in some implementations */
+static void WT_ReleaseVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, EAS_I32 voiceNum)
+{
+ S_WT_VOICE *pWTVoice;
+ const S_ARTICULATION *pArticulation;
+
+#ifdef DLS_SYNTHESIZER
+ if (pVoice->regionIndex & FLAG_RGN_IDX_DLS_SYNTH)
+ {
+ DLS_ReleaseVoice(pVoiceMgr, pSynth, pVoice, voiceNum);
+ return;
+ }
+#endif
+
+ pWTVoice = &pVoiceMgr->wtVoices[voiceNum];
+ pArticulation = &pSynth->pEAS->pArticulations[pWTVoice->artIndex];
+
+ /* release EG1 */
+ pWTVoice->eg1State = eEnvelopeStateRelease;
+ pWTVoice->eg1Increment = pArticulation->eg1.releaseTime;
+
+ /*
+ The spec says we should release EG2, but doing so with the current
+ voicing is causing clicks. This fix will need to be coordinated with
+ a new sound library release
+ */
+
+ /* release EG2 */
+ pWTVoice->eg2State = eEnvelopeStateRelease;
+ pWTVoice->eg2Increment = pArticulation->eg2.releaseTime;
+}
+
+/*----------------------------------------------------------------------------
+ * WT_MuteVoice()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * The selected voice is being muted.
+ *
+ * Inputs:
+ * pVoice - pointer to voice to release
+ *
+ * Outputs:
+ * None
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pSynth) used in some implementations */
+static void WT_MuteVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, EAS_I32 voiceNum)
+{
+
+#ifdef DLS_SYNTHESIZER
+ if (pVoice->regionIndex & FLAG_RGN_IDX_DLS_SYNTH)
+ {
+ DLS_MuteVoice(pVoiceMgr, pSynth, pVoice, voiceNum);
+ return;
+ }
+#endif
+
+ /* clear deferred action flags */
+ pVoice->voiceFlags &=
+ ~(VOICE_FLAG_DEFER_MIDI_NOTE_OFF |
+ VOICE_FLAG_SUSTAIN_PEDAL_DEFER_NOTE_OFF |
+ VOICE_FLAG_DEFER_MUTE);
+
+ /* set the envelope state */
+ pVoiceMgr->wtVoices[voiceNum].eg1State = eEnvelopeStateMuted;
+ pVoiceMgr->wtVoices[voiceNum].eg2State = eEnvelopeStateMuted;
+}
+
+/*----------------------------------------------------------------------------
+ * WT_SustainPedal()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * The selected voice is held due to sustain pedal
+ *
+ * Inputs:
+ * pVoice - pointer to voice to sustain
+ *
+ * Outputs:
+ * None
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pChannel) used in some implementations */
+static void WT_SustainPedal (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, S_SYNTH_CHANNEL *pChannel, EAS_I32 voiceNum)
+{
+ S_WT_VOICE *pWTVoice;
+
+#ifdef DLS_SYNTHESIZER
+ if (pVoice->regionIndex & FLAG_RGN_IDX_DLS_SYNTH)
+ {
+ DLS_SustainPedal(pVoiceMgr, pSynth, pVoice, pChannel, voiceNum);
+ return;
+ }
+#endif
+
+ /* don't catch the voice if below the sustain level */
+ pWTVoice = &pVoiceMgr->wtVoices[voiceNum];
+ if (pWTVoice->eg1Value < pSynth->pEAS->pArticulations[pWTVoice->artIndex].eg1.sustainLevel)
+ return;
+
+ /* sustain flag is set, damper pedal is on */
+ /* defer releasing this note until the damper pedal is off */
+ pWTVoice->eg1State = eEnvelopeStateDecay;
+ pVoice->voiceState = eVoiceStatePlay;
+
+ /*
+ because sustain pedal is on, this voice
+ should defer releasing its note
+ */
+ pVoice->voiceFlags |= VOICE_FLAG_SUSTAIN_PEDAL_DEFER_NOTE_OFF;
+
+#ifdef _DEBUG_SYNTH
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "WT_SustainPedal: defer note off because sustain pedal is on\n"); */ }
+#endif
+}
+
+/*----------------------------------------------------------------------------
+ * WT_StartVoice()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Assign the region for the given instrument using the midi key number
+ * and the RPN2 (coarse tuning) value. By using RPN2 as part of the
+ * region selection process, we reduce the amount a given sample has
+ * to be transposed by selecting the closest recorded root instead.
+ *
+ * This routine is the second half of SynthAssignRegion().
+ * If the region was successfully found by SynthFindRegionIndex(),
+ * then assign the region's parameters to the voice.
+ *
+ * Setup and initialize the following voice parameters:
+ * m_nRegionIndex
+ *
+ * Inputs:
+ * pVoice - ptr to the voice we have assigned for this channel
+ * nRegionIndex - index of the region
+ * pEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ * success - could find and assign the region for this voice's note otherwise
+ * failure - could not find nor assign the region for this voice's note
+ *
+ * Side Effects:
+ * psSynthObject->m_sVoice[].m_nRegionIndex is assigned
+ * psSynthObject->m_sVoice[] parameters are assigned
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT WT_StartVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, EAS_I32 voiceNum, EAS_U16 regionIndex)
+{
+ S_WT_VOICE *pWTVoice;
+ const S_WT_REGION *pRegion;
+ const S_ARTICULATION *pArt;
+ S_SYNTH_CHANNEL *pChannel;
+
+#if (NUM_OUTPUT_CHANNELS == 2)
+ EAS_INT pan;
+#endif
+
+#ifdef EAS_SPLIT_WT_SYNTH
+ S_WT_CONFIG wtConfig;
+#endif
+
+ /* no samples have been synthesized for this note yet */
+ pVoice->regionIndex = regionIndex;
+ pVoice->voiceFlags = VOICE_FLAG_NO_SAMPLES_SYNTHESIZED_YET;
+
+ /* get the articulation index for this region */
+ pWTVoice = &pVoiceMgr->wtVoices[voiceNum];
+ pChannel = &pSynth->channels[pVoice->channel & 15];
+
+ /* update static channel parameters */
+ if (pChannel->channelFlags & CHANNEL_FLAG_UPDATE_CHANNEL_PARAMETERS)
+ WT_UpdateChannel(pVoiceMgr, pSynth, pVoice->channel & 15);
+
+#ifdef DLS_SYNTHESIZER
+ if (pVoice->regionIndex & FLAG_RGN_IDX_DLS_SYNTH)
+ return DLS_StartVoice(pVoiceMgr, pSynth, pVoice, voiceNum, regionIndex);
+#endif
+
+ pRegion = &(pSynth->pEAS->pWTRegions[regionIndex]);
+ pWTVoice->artIndex = pRegion->artIndex;
+
+#ifdef _DEBUG_SYNTH
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "WT_StartVoice: Voice %ld; Region %d\n", (EAS_I32) (pVoice - pVoiceMgr->voices), regionIndex); */ }
+#endif
+
+ pArt = &pSynth->pEAS->pArticulations[pWTVoice->artIndex];
+
+ /* MIDI note on puts this voice into attack state */
+ pWTVoice->eg1State = eEnvelopeStateAttack;
+ pWTVoice->eg1Value = 0;
+ pWTVoice->eg1Increment = pArt->eg1.attackTime;
+ pWTVoice->eg2State = eEnvelopeStateAttack;
+ pWTVoice->eg2Value = 0;
+ pWTVoice->eg2Increment = pArt->eg2.attackTime;
+
+ /* init the LFO */
+ pWTVoice->modLFO.lfoValue = 0;
+ pWTVoice->modLFO.lfoPhase = -pArt->lfoDelay;
+
+ pVoice->gain = 0;
+
+#if (NUM_OUTPUT_CHANNELS == 2)
+ /*
+ Get the Midi CC10 pan value for this voice's channel
+ convert the pan value to an "angle" representation suitable for
+ our sin, cos calculator. This representation is NOT necessarily the same
+ as the transform in the GM manuals because of our sin, cos calculator.
+ "angle" = (CC10 - 64)/128
+ */
+ pan = (EAS_INT) pSynth->channels[pVoice->channel & 15].pan - 64;
+ pan += pArt->pan;
+ EAS_CalcPanControl(pan, &pWTVoice->gainLeft, &pWTVoice->gainRight);
+#endif
+
+#ifdef _FILTER_ENABLED
+ /* clear out the filter states */
+ pWTVoice->filter.z1 = 0;
+ pWTVoice->filter.z2 = 0;
+#endif
+
+ /* if this wave is to be generated using noise generator */
+ if (pRegion->region.keyGroupAndFlags & REGION_FLAG_USE_WAVE_GENERATOR)
+ {
+ pWTVoice->phaseAccum = 4574296;
+ pWTVoice->loopStart = WT_NOISE_GENERATOR;
+ pWTVoice->loopEnd = 4574295;
+ }
+
+ /* normal sample */
+ else
+ {
+
+#ifdef EAS_SPLIT_WT_SYNTH
+ if (voiceNum < NUM_PRIMARY_VOICES)
+ pWTVoice->phaseAccum = (EAS_U32) pSynth->pEAS->pSamples + pSynth->pEAS->pSampleOffsets[pRegion->waveIndex];
+ else
+ pWTVoice->phaseAccum = pSynth->pEAS->pSampleOffsets[pRegion->waveIndex];
+#else
+ pWTVoice->phaseAccum = (EAS_U32) pSynth->pEAS->pSamples + pSynth->pEAS->pSampleOffsets[pRegion->waveIndex];
+#endif
+
+ if (pRegion->region.keyGroupAndFlags & REGION_FLAG_IS_LOOPED)
+ {
+ pWTVoice->loopStart = pWTVoice->phaseAccum + pRegion->loopStart;
+ pWTVoice->loopEnd = pWTVoice->phaseAccum + pRegion->loopEnd - 1;
+ }
+ else
+ pWTVoice->loopStart = pWTVoice->loopEnd = pWTVoice->phaseAccum + pSynth->pEAS->pSampleLen[pRegion->waveIndex] - 1;
+ }
+
+#ifdef EAS_SPLIT_WT_SYNTH
+ /* configure off-chip voices */
+ if (voiceNum >= NUM_PRIMARY_VOICES)
+ {
+ wtConfig.phaseAccum = pWTVoice->phaseAccum;
+ wtConfig.loopStart = pWTVoice->loopStart;
+ wtConfig.loopEnd = pWTVoice->loopEnd;
+ wtConfig.gain = pVoice->gain;
+
+#if (NUM_OUTPUT_CHANNELS == 2)
+ wtConfig.gainLeft = pWTVoice->gainLeft;
+ wtConfig.gainRight = pWTVoice->gainRight;
+#endif
+
+ WTE_ConfigVoice(voiceNum - NUM_PRIMARY_VOICES, &wtConfig, pVoiceMgr->pFrameBuffer);
+ }
+#endif
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * WT_CheckSampleEnd
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Check for end of sample and calculate number of samples to synthesize
+ *
+ * Inputs:
+ *
+ * Outputs:
+ *
+ * Notes:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_BOOL WT_CheckSampleEnd (S_WT_VOICE *pWTVoice, S_WT_INT_FRAME *pWTIntFrame, EAS_BOOL update)
+{
+ EAS_U32 endPhaseAccum;
+ EAS_U32 endPhaseFrac;
+ EAS_I32 numSamples;
+ EAS_BOOL done = EAS_FALSE;
+
+ /* check to see if we hit the end of the waveform this time */
+ /*lint -e{703} use shift for performance */
+ endPhaseFrac = pWTVoice->phaseFrac + (pWTIntFrame->frame.phaseIncrement << SYNTH_UPDATE_PERIOD_IN_BITS);
+ endPhaseAccum = pWTVoice->phaseAccum + GET_PHASE_INT_PART(endPhaseFrac);
+ if (endPhaseAccum >= pWTVoice->loopEnd)
+ {
+ /* calculate how far current ptr is from end */
+ numSamples = (EAS_I32) (pWTVoice->loopEnd - pWTVoice->phaseAccum);
+
+ /* now account for the fractional portion */
+ /*lint -e{703} use shift for performance */
+ numSamples = (EAS_I32) ((numSamples << NUM_PHASE_FRAC_BITS) - pWTVoice->phaseFrac);
+ pWTIntFrame->numSamples = 1 + (numSamples / pWTIntFrame->frame.phaseIncrement);
+
+ /* sound will be done this frame */
+ done = EAS_TRUE;
+ }
+
+ /* update data for off-chip synth */
+ if (update)
+ {
+ pWTVoice->phaseFrac = endPhaseFrac;
+ pWTVoice->phaseAccum = endPhaseAccum;
+ }
+
+ return done;
+}
+
+/*----------------------------------------------------------------------------
+ * WT_UpdateVoice()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Synthesize a block of samples for the given voice.
+ * Use linear interpolation.
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ * number of samples actually written to buffer
+ *
+ * Side Effects:
+ * - samples are added to the presently free buffer
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_BOOL WT_UpdateVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, EAS_I32 voiceNum, EAS_I32 *pMixBuffer, EAS_I32 numSamples)
+{
+ S_WT_VOICE *pWTVoice;
+ S_WT_INT_FRAME intFrame;
+ S_SYNTH_CHANNEL *pChannel;
+ const S_WT_REGION *pWTRegion;
+ const S_ARTICULATION *pArt;
+ EAS_I32 temp;
+ EAS_BOOL done;
+
+#ifdef DLS_SYNTHESIZER
+ if (pVoice->regionIndex & FLAG_RGN_IDX_DLS_SYNTH)
+ return DLS_UpdateVoice(pVoiceMgr, pSynth, pVoice, voiceNum, pMixBuffer, numSamples);
+#endif
+
+ /* establish pointers to critical data */
+ pWTVoice = &pVoiceMgr->wtVoices[voiceNum];
+ pWTRegion = &pSynth->pEAS->pWTRegions[pVoice->regionIndex & REGION_INDEX_MASK];
+ pArt = &pSynth->pEAS->pArticulations[pWTVoice->artIndex];
+ pChannel = &pSynth->channels[pVoice->channel & 15];
+ intFrame.prevGain = pVoice->gain;
+
+ /* update the envelopes */
+ WT_UpdateEG1(pWTVoice, &pArt->eg1);
+ WT_UpdateEG2(pWTVoice, &pArt->eg2);
+
+ /* update the LFO */
+ WT_UpdateLFO(&pWTVoice->modLFO, pArt->lfoFreq);
+
+#ifdef _FILTER_ENABLED
+ /* calculate filter if library uses filter */
+ if (pSynth->pEAS->libAttr & LIB_FORMAT_FILTER_ENABLED)
+ WT_UpdateFilter(pWTVoice, &intFrame, pArt);
+ else
+ intFrame.frame.k = 0;
+#endif
+
+ /* update the gain */
+ intFrame.frame.gainTarget = WT_UpdateGain(pVoice, pWTVoice, pArt, pChannel, pWTRegion->gain);
+
+ /* calculate base pitch*/
+ temp = pChannel->staticPitch + pWTRegion->tuning;
+
+ /* include global transpose */
+ if (pChannel->channelFlags & CHANNEL_FLAG_RHYTHM_CHANNEL)
+ temp += pVoice->note * 100;
+ else
+ temp += (pVoice->note + pSynth->globalTranspose) * 100;
+ intFrame.frame.phaseIncrement = WT_UpdatePhaseInc(pWTVoice, pArt, pChannel, temp);
+
+ /* call into engine to generate samples */
+ intFrame.pAudioBuffer = pVoiceMgr->voiceBuffer;
+ intFrame.pMixBuffer = pMixBuffer;
+ intFrame.numSamples = numSamples;
+
+ /* check for end of sample */
+ if ((pWTVoice->loopStart != WT_NOISE_GENERATOR) && (pWTVoice->loopStart == pWTVoice->loopEnd))
+ done = WT_CheckSampleEnd(pWTVoice, &intFrame, (EAS_BOOL) (voiceNum >= NUM_PRIMARY_VOICES));
+ else
+ done = EAS_FALSE;
+
+#ifdef EAS_SPLIT_WT_SYNTH
+ if (voiceNum < NUM_PRIMARY_VOICES)
+ {
+#ifndef _SPLIT_WT_TEST_HARNESS
+ WT_ProcessVoice(pWTVoice, &intFrame);
+#endif
+ }
+ else
+ WTE_ProcessVoice(voiceNum - NUM_PRIMARY_VOICES, &intFrame.frame, pVoiceMgr->pFrameBuffer);
+#else
+ WT_ProcessVoice(pWTVoice, &intFrame);
+#endif
+
+ /* clear flag */
+ pVoice->voiceFlags &= ~VOICE_FLAG_NO_SAMPLES_SYNTHESIZED_YET;
+
+ /* if voice has finished, set flag for voice manager */
+ if ((pVoice->voiceState != eVoiceStateStolen) && (pWTVoice->eg1State == eEnvelopeStateMuted))
+ done = EAS_TRUE;
+
+ /* if the update interval has elapsed, then force the current gain to the next
+ * gain since we never actually reach the next gain when ramping -- we just get
+ * very close to the target gain.
+ */
+ pVoice->gain = (EAS_I16) intFrame.frame.gainTarget;
+
+ return done;
+}
+
+/*----------------------------------------------------------------------------
+ * WT_UpdatePhaseInc()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Calculate the phase increment
+ *
+ * Inputs:
+ * pVoice - pointer to the voice being updated
+ * psRegion - pointer to the region
+ * psArticulation - pointer to the articulation
+ * nChannelPitchForThisVoice - the portion of the pitch that is fixed for this
+ * voice during the duration of this synthesis
+ * pEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ * set the phase increment for this voice
+ *----------------------------------------------------------------------------
+*/
+static EAS_I32 WT_UpdatePhaseInc (S_WT_VOICE *pWTVoice, const S_ARTICULATION *pArt, S_SYNTH_CHANNEL *pChannel, EAS_I32 pitchCents)
+{
+ EAS_I32 temp;
+
+ /*pitchCents due to CC1 = LFO * (CC1 / 128) * DEFAULT_LFO_MOD_WHEEL_TO_PITCH_CENTS */
+ temp = MULT_EG1_EG1(DEFAULT_LFO_MOD_WHEEL_TO_PITCH_CENTS,
+ ((pChannel->modWheel) << (NUM_EG1_FRAC_BITS -7)));
+
+ /* pitchCents due to channel pressure = LFO * (channel pressure / 128) * DEFAULT_LFO_CHANNEL_PRESSURE_TO_PITCH_CENTS */
+ temp += MULT_EG1_EG1(DEFAULT_LFO_CHANNEL_PRESSURE_TO_PITCH_CENTS,
+ ((pChannel->channelPressure) << (NUM_EG1_FRAC_BITS -7)));
+
+ /* now multiply the (channel pressure + CC1) pitch values by the LFO value */
+ temp = MULT_EG1_EG1(pWTVoice->modLFO.lfoValue, temp);
+
+ /*
+ add in the LFO pitch due to
+ channel pressure and CC1 along with
+ the LFO pitch, the EG2 pitch, and the
+ "static" pitch for this voice on this channel
+ */
+ temp += pitchCents +
+ (MULT_EG1_EG1(pWTVoice->eg2Value, pArt->eg2ToPitch)) +
+ (MULT_EG1_EG1(pWTVoice->modLFO.lfoValue, pArt->lfoToPitch));
+
+ /* convert from cents to linear phase increment */
+ return EAS_Calculate2toX(temp);
+}
+
+/*----------------------------------------------------------------------------
+ * WT_UpdateChannel()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Calculate and assign static channel parameters
+ * These values only need to be updated if one of the controller values
+ * for this channel changes
+ *
+ * Inputs:
+ * nChannel - channel to update
+ * pEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ * - the given channel's static gain and static pitch are updated
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pVoiceMgr) reserved for future use */
+static void WT_UpdateChannel (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel)
+{
+ EAS_I32 staticGain;
+ EAS_I32 pitchBend;
+ S_SYNTH_CHANNEL *pChannel;
+
+ pChannel = &pSynth->channels[channel];
+
+ /*
+ nChannelGain = (CC7 * CC11)^2 * master volume
+ where CC7 == 100 by default, CC11 == 127, master volume == 32767
+ */
+ staticGain = MULT_EG1_EG1((pChannel->volume) << (NUM_EG1_FRAC_BITS - 7),
+ (pChannel->expression) << (NUM_EG1_FRAC_BITS - 7));
+
+ /* staticGain has to be squared */
+ staticGain = MULT_EG1_EG1(staticGain, staticGain);
+
+ pChannel->staticGain = (EAS_I16) MULT_EG1_EG1(staticGain, pSynth->masterVolume);
+
+ /*
+ calculate pitch bend: RPN0 * ((2*pitch wheel)/16384 -1)
+ However, if we use the EG1 macros, remember that EG1 has a full
+ scale value of 32768 (instead of 16384). So instead of multiplying
+ by 2, multiply by 4 (left shift by 2), and subtract by 32768 instead
+ of 16384. This utilizes the fact that the EG1 macro places a binary
+ point 15 places to the left instead of 14 places.
+ */
+ /*lint -e{703} <avoid multiply for performance>*/
+ pitchBend =
+ (((EAS_I32)(pChannel->pitchBend) << 2)
+ - 32768);
+
+ pChannel->staticPitch =
+ MULT_EG1_EG1(pitchBend, pChannel->pitchBendSensitivity);
+
+ /* if this is not a drum channel, then add in the per-channel tuning */
+ if (!(pChannel->channelFlags & CHANNEL_FLAG_RHYTHM_CHANNEL))
+ pChannel->staticPitch += pChannel->finePitch + (pChannel->coarsePitch * 100);
+
+ /* clear update flag */
+ pChannel->channelFlags &= ~CHANNEL_FLAG_UPDATE_CHANNEL_PARAMETERS;
+ return;
+}
+
+/*----------------------------------------------------------------------------
+ * WT_UpdateGain()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Calculate and assign static voice parameters as part of WT_UpdateVoice()
+ *
+ * Inputs:
+ * pVoice - ptr to the synth voice that we want to synthesize
+ * pEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ * - various voice parameters are calculated and assigned
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_I32 WT_UpdateGain (S_SYNTH_VOICE *pVoice, S_WT_VOICE *pWTVoice, const S_ARTICULATION *pArt, S_SYNTH_CHANNEL *pChannel, EAS_I32 gain)
+{
+ EAS_I32 lfoGain;
+ EAS_I32 temp;
+
+ /*
+ If this voice was stolen, then the velocity is actually
+ for the new note, not the note that we are currently ramping down.
+ So we really shouldn't use this velocity. However, that would require
+ more memory to store the velocity value, and the improvement may
+ not be sufficient to warrant the added memory.
+ */
+ /* velocity is fixed at note start for a given voice and must be squared */
+ temp = (pVoice->velocity) << (NUM_EG1_FRAC_BITS - 7);
+ temp = MULT_EG1_EG1(temp, temp);
+
+ /* region gain is fixed as part of the articulation */
+ temp = MULT_EG1_EG1(temp, gain);
+
+ /* include the channel gain */
+ temp = MULT_EG1_EG1(temp, pChannel->staticGain);
+
+ /* calculate LFO gain using an approximation for 10^x */
+ lfoGain = MULT_EG1_EG1(pWTVoice->modLFO.lfoValue, pArt->lfoToGain);
+ lfoGain = MULT_EG1_EG1(lfoGain, LFO_GAIN_TO_CENTS);
+
+ /* convert from a dB-like value to linear gain */
+ lfoGain = EAS_Calculate2toX(lfoGain);
+ temp = MULT_EG1_EG1(temp, lfoGain);
+
+ /* calculate the voice's gain */
+ temp = (EAS_I16)MULT_EG1_EG1(temp, pWTVoice->eg1Value);
+
+ return temp;
+}
+
+/*----------------------------------------------------------------------------
+ * WT_UpdateEG1()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Calculate the EG1 envelope for the given voice (but do not update any
+ * state)
+ *
+ * Inputs:
+ * pVoice - ptr to the voice whose envelope we want to update
+ * nVoice - this voice's number - used only for debug
+ * pEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ * nValue - the envelope value
+ *
+ * Side Effects:
+ * - updates EG1 state value for the given voice
+ *----------------------------------------------------------------------------
+*/
+static void WT_UpdateEG1 (S_WT_VOICE *pWTVoice, const S_ENVELOPE *pEnv)
+{
+ EAS_I32 temp;
+
+ switch (pWTVoice->eg1State)
+ {
+ case eEnvelopeStateAttack:
+ temp = pWTVoice->eg1Value + pWTVoice->eg1Increment;
+
+ /* check if we have reached peak amplitude */
+ if (temp >= SYNTH_FULL_SCALE_EG1_GAIN)
+ {
+ /* limit the volume */
+ temp = SYNTH_FULL_SCALE_EG1_GAIN;
+
+ /* prepare to move to decay state */
+ pWTVoice->eg1State = eEnvelopeStateDecay;
+ pWTVoice->eg1Increment = pEnv->decayTime;
+ }
+
+ break;
+
+ /* exponential decay */
+ case eEnvelopeStateDecay:
+ temp = MULT_EG1_EG1(pWTVoice->eg1Value, pWTVoice->eg1Increment);
+
+ /* check if we have reached sustain level */
+ if (temp <= pEnv->sustainLevel)
+ {
+ /* enforce the sustain level */
+ temp = pEnv->sustainLevel;
+
+ /* if sustain level is zero, skip sustain & release the voice */
+ if (temp > 0)
+ pWTVoice->eg1State = eEnvelopeStateSustain;
+
+ /* move to sustain state */
+ else
+ pWTVoice->eg1State = eEnvelopeStateMuted;
+ }
+
+ break;
+
+ case eEnvelopeStateSustain:
+ return;
+
+ case eEnvelopeStateRelease:
+ temp = MULT_EG1_EG1(pWTVoice->eg1Value, pWTVoice->eg1Increment);
+
+ /* if we hit zero, this voice isn't contributing any audio */
+ if (temp <= 0)
+ {
+ temp = 0;
+ pWTVoice->eg1State = eEnvelopeStateMuted;
+ }
+ break;
+
+ /* voice is muted, set target to zero */
+ case eEnvelopeStateMuted:
+ temp = 0;
+ break;
+
+ case eEnvelopeStateInvalid:
+ default:
+ temp = 0;
+#ifdef _DEBUG_SYNTH
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "WT_UpdateEG1: error, %d is an unrecognized state\n",
+ pWTVoice->eg1State); */ }
+#endif
+ break;
+
+ }
+
+ pWTVoice->eg1Value = (EAS_I16) temp;
+}
+
+/*----------------------------------------------------------------------------
+ * WT_UpdateEG2()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Update the EG2 envelope for the given voice
+ *
+ * Inputs:
+ * pVoice - ptr to the voice whose envelope we want to update
+ * pEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ * - updates EG2 values for the given voice
+ *----------------------------------------------------------------------------
+*/
+
+static void WT_UpdateEG2 (S_WT_VOICE *pWTVoice, const S_ENVELOPE *pEnv)
+{
+ EAS_I32 temp;
+
+ switch (pWTVoice->eg2State)
+ {
+ case eEnvelopeStateAttack:
+ temp = pWTVoice->eg2Value + pWTVoice->eg2Increment;
+
+ /* check if we have reached peak amplitude */
+ if (temp >= SYNTH_FULL_SCALE_EG1_GAIN)
+ {
+ /* limit the volume */
+ temp = SYNTH_FULL_SCALE_EG1_GAIN;
+
+ /* prepare to move to decay state */
+ pWTVoice->eg2State = eEnvelopeStateDecay;
+
+ pWTVoice->eg2Increment = pEnv->decayTime;
+ }
+
+ break;
+
+ /* implement linear pitch decay in cents */
+ case eEnvelopeStateDecay:
+ temp = pWTVoice->eg2Value -pWTVoice->eg2Increment;
+
+ /* check if we have reached sustain level */
+ if (temp <= pEnv->sustainLevel)
+ {
+ /* enforce the sustain level */
+ temp = pEnv->sustainLevel;
+
+ /* prepare to move to sustain state */
+ pWTVoice->eg2State = eEnvelopeStateSustain;
+ }
+ break;
+
+ case eEnvelopeStateSustain:
+ return;
+
+ case eEnvelopeStateRelease:
+ temp = pWTVoice->eg2Value - pWTVoice->eg2Increment;
+
+ if (temp <= 0)
+ {
+ temp = 0;
+ pWTVoice->eg2State = eEnvelopeStateMuted;
+ }
+
+ break;
+
+ /* voice is muted, set target to zero */
+ case eEnvelopeStateMuted:
+ temp = 0;
+ break;
+
+ case eEnvelopeStateInvalid:
+ default:
+ temp = 0;
+#ifdef _DEBUG_SYNTH
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "WT_UpdateEG2: error, %d is an unrecognized state\n",
+ pWTVoice->eg2State); */ }
+#endif
+ break;
+ }
+
+ pWTVoice->eg2Value = (EAS_I16) temp;
+}
+
+/*----------------------------------------------------------------------------
+ * WT_UpdateLFO ()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Calculate the LFO for the given voice
+ *
+ * Inputs:
+ * pLFO - ptr to the LFO data
+ * phaseInc - phase increment
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ * - updates LFO values for the given voice
+ *----------------------------------------------------------------------------
+*/
+void WT_UpdateLFO (S_LFO_CONTROL *pLFO, EAS_I16 phaseInc)
+{
+
+ /* To save memory, if m_nPhaseValue is negative, we are in the
+ * delay phase, and m_nPhaseValue represents the time left
+ * in the delay.
+ */
+ if (pLFO->lfoPhase < 0)
+ {
+ pLFO->lfoPhase++;
+ return;
+ }
+
+ /* calculate LFO output from phase value */
+ /*lint -e{701} Use shift for performance */
+ pLFO->lfoValue = (EAS_I16) (pLFO->lfoPhase << 2);
+ /*lint -e{502} <shortcut to turn sawtooth into triangle wave> */
+ if ((pLFO->lfoPhase > 0x1fff) && (pLFO->lfoPhase < 0x6000))
+ pLFO->lfoValue = ~pLFO->lfoValue;
+
+ /* update LFO phase */
+ pLFO->lfoPhase = (pLFO->lfoPhase + phaseInc) & 0x7fff;
+}
+
+#ifdef _FILTER_ENABLED
+/*----------------------------------------------------------------------------
+ * WT_UpdateFilter()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Update the Filter parameters
+ *
+ * Inputs:
+ * pVoice - ptr to the voice whose filter we want to update
+ * pEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ * - updates Filter values for the given voice
+ *----------------------------------------------------------------------------
+*/
+static void WT_UpdateFilter (S_WT_VOICE *pWTVoice, S_WT_INT_FRAME *pIntFrame, const S_ARTICULATION *pArt)
+{
+ EAS_I32 cutoff;
+
+ /* no need to calculate filter coefficients if it is bypassed */
+ if (pArt->filterCutoff == DEFAULT_EAS_FILTER_CUTOFF_FREQUENCY)
+ {
+ pIntFrame->frame.k = 0;
+ return;
+ }
+
+ /* determine the dynamic cutoff frequency */
+ cutoff = MULT_EG1_EG1(pWTVoice->eg2Value, pArt->eg2ToFc);
+ cutoff += pArt->filterCutoff;
+
+ /* subtract the A5 offset and the sampling frequency */
+ cutoff -= FILTER_CUTOFF_FREQ_ADJUST + A5_PITCH_OFFSET_IN_CENTS;
+
+ /* limit the cutoff frequency */
+ if (cutoff > FILTER_CUTOFF_MAX_PITCH_CENTS)
+ cutoff = FILTER_CUTOFF_MAX_PITCH_CENTS;
+ else if (cutoff < FILTER_CUTOFF_MIN_PITCH_CENTS)
+ cutoff = FILTER_CUTOFF_MIN_PITCH_CENTS;
+
+ WT_SetFilterCoeffs(pIntFrame, cutoff, pArt->filterQ);
+}
+#endif
+
+#if defined(_FILTER_ENABLED) || defined(DLS_SYNTHESIZER)
+/*----------------------------------------------------------------------------
+ * coef
+ *----------------------------------------------------------------------------
+ * Table of filter coefficients for low-pass filter
+ *----------------------------------------------------------------------------
+ *
+ * polynomial coefficients are based on 8kHz sampling frequency
+ * filter coef b2 = k2 = k2g0*k^0 + k2g1*k^1*(2^x) + k2g2*k^2*(2^x)
+ *
+ *where k2g0, k2g1, k2g2 are from the truncated power series expansion on theta
+ *(k*2^x = theta, but we incorporate the k along with the k2g0, k2g1, k2g2)
+ *note: this is a power series in 2^x, not k*2^x
+ *where k = (2*pi*440)/8kHz == convert octaves to radians
+ *
+ * so actually, the following coefs listed as k2g0, k2g1, k2g2 are really
+ * k2g0*k^0 = k2g0
+ * k2g1*k^1
+ * k2g2*k^2
+ *
+ *
+ * filter coef n1 = numerator = n1g0*k^0 + n1g1*k^1*(2^x) + n1g2*k^2*(2^x) + n1g3*k^3*(2^x)
+ *
+ *where n1g0, n1g1, n1g2, n1g3 are from the truncated power series expansion on theta
+ *(k*2^x = theta, but we incorporate the k along with the n1g0, n1g1, n1g2, n2g3)
+ *note: this is a power series in 2^x, not k*2^x
+ *where k = (2*pi*440)/8kHz == convert octaves to radians
+ *we also include the optimization factor of 0.81
+ *
+ * so actually, the following coefs listed as n1g0, n1g1, n1g2, n2g3 are really
+ * n1g0*k^0 = n1g0
+ * n1g1*k^1
+ * n1g2*k^2
+ * n1g3*k^3
+ *
+ * NOTE that n1g0 == n1g1 == 0, always, so we only need to store n1g2 and n1g3
+ *----------------------------------------------------------------------------
+*/
+
+static const EAS_I16 nk1g0 = -32768;
+static const EAS_I16 nk1g2 = 1580;
+static const EAS_I16 k2g0 = 32767;
+
+static const EAS_I16 k2g1[] =
+{
+ -11324, /* k2g1[0] = -0.3455751918948761 */
+ -10387, /* k2g1[1] = -0.3169878073928751 */
+ -9528, /* k2g1[2] = -0.29076528753345476 */
+ -8740, /* k2g1[3] = -0.2667120011011279 */
+ -8017, /* k2g1[4] = -0.24464850028971705 */
+ -7353, /* k2g1[5] = -0.22441018194495696 */
+ -6745, /* k2g1[6] = -0.20584605955455101 */
+ -6187, /* k2g1[7] = -0.18881763682420102 */
+ -5675, /* k2g1[8] = -0.1731978744360067 */
+ -5206, /* k2g1[9] = -0.15887024228080968 */
+ -4775, /* k2g1[10] = -0.14572785009373057 */
+ -4380, /* k2g1[11] = -0.13367265000706827 */
+ -4018, /* k2g1[12] = -0.1226147050712642 */
+ -3685, /* k2g1[13] = -0.11247151828678581 */
+ -3381, /* k2g1[14] = -0.10316741714122014 */
+ -3101, /* k2g1[15] = -0.0946329890599603 */
+ -2844, /* k2g1[16] = -0.08680456355870586 */
+ -2609, /* k2g1[17] = -0.07962373723441349 */
+ -2393, /* k2g1[18] = -0.07303693805092666 */
+ -2195, /* k2g1[19] = -0.06699502566866912 */
+ -2014, /* k2g1[20] = -0.06145292483669077 */
+ -1847, /* k2g1[21] = -0.056369289112013346 */
+ -1694, /* k2g1[22] = -0.05170619239747895 */
+ -1554, /* k2g1[23] = -0.04742884599684141 */
+ -1426, /* k2g1[24] = -0.043505339076210514 */
+ -1308, /* k2g1[25] = -0.03990640059558053 */
+ -1199, /* k2g1[26] = -0.03660518093435039 */
+ -1100, /* k2g1[27] = -0.03357705158166837 */
+ -1009, /* k2g1[28] = -0.030799421397205727 */
+ -926, /* k2g1[29] = -0.028251568071585884 */
+ -849 /* k2g1[30] = -0.025914483529091967 */
+};
+
+static const EAS_I16 k2g2[] =
+{
+ 1957, /* k2g2[0] = 0.059711106626580836 */
+ 1646, /* k2g2[1] = 0.05024063501786333 */
+ 1385, /* k2g2[2] = 0.042272226217199664 */
+ 1165, /* k2g2[3] = 0.03556764576567844 */
+ 981, /* k2g2[4] = 0.029926444346999134 */
+ 825, /* k2g2[5] = 0.025179964880280382 */
+ 694, /* k2g2[6] = 0.02118630011706455 */
+ 584, /* k2g2[7] = 0.01782604998793514 */
+ 491, /* k2g2[8] = 0.014998751854573014 */
+ 414, /* k2g2[9] = 0.012619876941179595 */
+ 348, /* k2g2[10] = 0.010618303146468736 */
+ 293, /* k2g2[11] = 0.008934188679954682 */
+ 246, /* k2g2[12] = 0.007517182949855368 */
+ 207, /* k2g2[13] = 0.006324921212866403 */
+ 174, /* k2g2[14] = 0.005321757979794424 */
+ 147, /* k2g2[15] = 0.004477701309210577 */
+ 123, /* k2g2[16] = 0.00376751612730811 */
+ 104, /* k2g2[17] = 0.0031699697655869644 */
+ 87, /* k2g2[18] = 0.00266719715992703 */
+ 74, /* k2g2[19] = 0.0022441667321724647 */
+ 62, /* k2g2[20] = 0.0018882309854916855 */
+ 52, /* k2g2[21] = 0.0015887483774966232 */
+ 44, /* k2g2[22] = 0.0013367651661223448 */
+ 37, /* k2g2[23] = 0.0011247477162958733 */
+ 31, /* k2g2[24] = 0.0009463572640678758 */
+ 26, /* k2g2[25] = 0.0007962604042473498 */
+ 22, /* k2g2[26] = 0.0006699696356181593 */
+ 18, /* k2g2[27] = 0.0005637091964589207 */
+ 16, /* k2g2[28] = 0.00047430217920125243 */
+ 13, /* k2g2[29] = 0.00039907554925166274 */
+ 11 /* k2g2[30] = 0.00033578022828973666 */
+};
+
+static const EAS_I16 n1g2[] =
+{
+ 3170, /* n1g2[0] = 0.0967319927350769 */
+ 3036, /* n1g2[1] = 0.0926446051254155 */
+ 2908, /* n1g2[2] = 0.08872992911818503 */
+ 2785, /* n1g2[3] = 0.08498066682523227 */
+ 2667, /* n1g2[4] = 0.08138982872895201 */
+ 2554, /* n1g2[5] = 0.07795072065216213 */
+ 2446, /* n1g2[6] = 0.0746569312785634 */
+ 2343, /* n1g2[7] = 0.07150232020051943 */
+ 2244, /* n1g2[8] = 0.06848100647187474 */
+ 2149, /* n1g2[9] = 0.06558735764447099 */
+ 2058, /* n1g2[10] = 0.06281597926792246 */
+ 1971, /* n1g2[11] = 0.06016170483307614 */
+ 1888, /* n1g2[12] = 0.05761958614040857 */
+ 1808, /* n1g2[13] = 0.05518488407540374 */
+ 1732, /* n1g2[14] = 0.052853059773715245 */
+ 1659, /* n1g2[15] = 0.05061976615964251 */
+ 1589, /* n1g2[16] = 0.04848083984214659 */
+ 1521, /* n1g2[17] = 0.046432293353298 */
+ 1457, /* n1g2[18] = 0.04447030771468711 */
+ 1396, /* n1g2[19] = 0.04259122531793907 */
+ 1337, /* n1g2[20] = 0.040791543106060944 */
+ 1280, /* n1g2[21] = 0.03906790604290942 */
+ 1226, /* n1g2[22] = 0.037417100858604564 */
+ 1174, /* n1g2[23] = 0.035836050059229754 */
+ 1125, /* n1g2[24] = 0.03432180618965023 */
+ 1077, /* n1g2[25] = 0.03287154633875494 */
+ 1032, /* n1g2[26] = 0.03148256687687814 */
+ 988, /* n1g2[27] = 0.030152278415589925 */
+ 946, /* n1g2[28] = 0.028878200980459685 */
+ 906, /* n1g2[29] = 0.02765795938779331 */
+ 868 /* n1g2[30] = 0.02648927881672521 */
+};
+
+static const EAS_I16 n1g3[] =
+{
+ -548, /* n1g3[0] = -0.016714088475899017 */
+ -481, /* n1g3[1] = -0.014683605122742116 */
+ -423, /* n1g3[2] = -0.012899791676436092 */
+ -371, /* n1g3[3] = -0.01133268185193299 */
+ -326, /* n1g3[4] = -0.00995594976868754 */
+ -287, /* n1g3[5] = -0.008746467702146129 */
+ -252, /* n1g3[6] = -0.00768391756106361 */
+ -221, /* n1g3[7] = -0.006750449563854721 */
+ -194, /* n1g3[8] = -0.005930382380083576 */
+ -171, /* n1g3[9] = -0.005209939699767622 */
+ -150, /* n1g3[10] = -0.004577018805123356 */
+ -132, /* n1g3[11] = -0.004020987256990177 */
+ -116, /* n1g3[12] = -0.003532504280467257 */
+ -102, /* n1g3[13] = -0.00310336384922047 */
+ -89, /* n1g3[14] = -0.002726356832432369 */
+ -78, /* n1g3[15] = -0.002395149888601605 */
+ -69, /* n1g3[16] = -0.0021041790717285314 */
+ -61, /* n1g3[17] = -0.0018485563625771063 */
+ -53, /* n1g3[18] = -0.001623987554831628 */
+ -47, /* n1g3[19] = -0.0014267001167177025 */
+ -41, /* n1g3[20] = -0.0012533798162347005 */
+ -36, /* n1g3[21] = -0.0011011150453668693 */
+ -32, /* n1g3[22] = -0.0009673479079754438 */
+ -28, /* n1g3[23] = -0.0008498312496971563 */
+ -24, /* n1g3[24] = -0.0007465909079943587 */
+ -21, /* n1g3[25] = -0.0006558925481952733 */
+ -19, /* n1g3[26] = -0.0005762125284029567 */
+ -17, /* n1g3[27] = -0.0005062123038325457 */
+ -15, /* n1g3[28] = -0.0004447159405951901 */
+ -13, /* n1g3[29] = -0.00039069036118270117 */
+ -11 /* n1g3[30] = -0.00034322798979677605 */
+};
+
+/*----------------------------------------------------------------------------
+ * WT_SetFilterCoeffs()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Update the Filter parameters
+ *
+ * Inputs:
+ * pVoice - ptr to the voice whose filter we want to update
+ * pEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ * - updates Filter values for the given voice
+ *----------------------------------------------------------------------------
+*/
+void WT_SetFilterCoeffs (S_WT_INT_FRAME *pIntFrame, EAS_I32 cutoff, EAS_I32 resonance)
+{
+ EAS_I32 temp;
+
+ /*
+ Convert the cutoff, which has had A5 subtracted, using the 2^x approx
+ Note, this cutoff is related to theta cutoff by
+ theta = k * 2^x
+ We use 2^x and incorporate k in the power series coefs instead
+ */
+ cutoff = EAS_Calculate2toX(cutoff);
+
+ /* calculate b2 coef */
+ temp = k2g1[resonance] + MULT_AUDIO_COEF(cutoff, k2g2[resonance]);
+ temp = k2g0 + MULT_AUDIO_COEF(cutoff, temp);
+ pIntFrame->frame.b2 = temp;
+
+ /* calculate b1 coef */
+ temp = MULT_AUDIO_COEF(cutoff, nk1g2);
+ temp = nk1g0 + MULT_AUDIO_COEF(cutoff, temp);
+ temp += MULT_AUDIO_COEF(temp, pIntFrame->frame.b2);
+ pIntFrame->frame.b1 = temp >> 1;
+
+ /* calculate K coef */
+ temp = n1g2[resonance] + MULT_AUDIO_COEF(cutoff, n1g3[resonance]);
+ temp = MULT_AUDIO_COEF(cutoff, temp);
+ temp = MULT_AUDIO_COEF(cutoff, temp);
+ pIntFrame->frame.k = temp;
+}
+#endif
+
diff --git a/arm-hybrid-22k/lib_src/eas_wtsynth.h b/arm-hybrid-22k/lib_src/eas_wtsynth.h
index 106ab40..90a7ad8 100644
--- a/arm-hybrid-22k/lib_src/eas_wtsynth.h
+++ b/arm-hybrid-22k/lib_src/eas_wtsynth.h
@@ -1,12 +1,12 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_wtsynth.h
- *
- * Contents and purpose:
- * This file defines the interface for synthesizer engine
- *
- * Copyright Sonic Network Inc. 2004
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_wtsynth.h
+ *
+ * Contents and purpose:
+ * This file defines the interface for synthesizer engine
+ *
+ * Copyright Sonic Network Inc. 2004
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,48 +19,48 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 82 $
- * $Date: 2006-07-10 11:45:19 -0700 (Mon, 10 Jul 2006) $
- *----------------------------------------------------------------------------
-*/
-
-#ifndef _EAS_WTSYNTH_H
-#define _EAS_WTSYNTH_H
-
-#include "eas_sndlib.h"
-#include "eas_wtengine.h"
-
-/* adjust the filter cutoff frequency to the sample rate */
-#if defined (_SAMPLE_RATE_8000)
-#define FILTER_CUTOFF_FREQ_ADJUST 0
-#elif defined (_SAMPLE_RATE_16000)
-#define FILTER_CUTOFF_FREQ_ADJUST 1200
-#elif defined (_SAMPLE_RATE_20000)
-#define FILTER_CUTOFF_FREQ_ADJUST 1586
-#elif defined (_SAMPLE_RATE_22050)
-#define FILTER_CUTOFF_FREQ_ADJUST 1756
-#elif defined (_SAMPLE_RATE_24000)
-#define FILTER_CUTOFF_FREQ_ADJUST 1902
-#elif defined (_SAMPLE_RATE_32000)
-#define FILTER_CUTOFF_FREQ_ADJUST 2400
-#elif defined (_SAMPLE_RATE_44100)
-#define FILTER_CUTOFF_FREQ_ADJUST 2956
-#elif defined (_SAMPLE_RATE_48000)
-#define FILTER_CUTOFF_FREQ_ADJUST 3102
-#else
-#error "_SAMPLE_RATE_XXXXX must be defined to valid rate"
-#endif
-
-/* function prototypes */
-void WT_UpdateLFO (S_LFO_CONTROL *pLFO, EAS_I16 phaseInc);
-
-#if defined(_FILTER_ENABLED) || defined(DLS_SYNTHESIZER)
-void WT_SetFilterCoeffs (S_WT_INT_FRAME *pIntFrame, EAS_I32 cutoff, EAS_I32 resonance);
-#endif
-
-#endif
-
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 82 $
+ * $Date: 2006-07-10 11:45:19 -0700 (Mon, 10 Jul 2006) $
+ *----------------------------------------------------------------------------
+*/
+
+#ifndef _EAS_WTSYNTH_H
+#define _EAS_WTSYNTH_H
+
+#include "eas_sndlib.h"
+#include "eas_wtengine.h"
+
+/* adjust the filter cutoff frequency to the sample rate */
+#if defined (_SAMPLE_RATE_8000)
+#define FILTER_CUTOFF_FREQ_ADJUST 0
+#elif defined (_SAMPLE_RATE_16000)
+#define FILTER_CUTOFF_FREQ_ADJUST 1200
+#elif defined (_SAMPLE_RATE_20000)
+#define FILTER_CUTOFF_FREQ_ADJUST 1586
+#elif defined (_SAMPLE_RATE_22050)
+#define FILTER_CUTOFF_FREQ_ADJUST 1756
+#elif defined (_SAMPLE_RATE_24000)
+#define FILTER_CUTOFF_FREQ_ADJUST 1902
+#elif defined (_SAMPLE_RATE_32000)
+#define FILTER_CUTOFF_FREQ_ADJUST 2400
+#elif defined (_SAMPLE_RATE_44100)
+#define FILTER_CUTOFF_FREQ_ADJUST 2956
+#elif defined (_SAMPLE_RATE_48000)
+#define FILTER_CUTOFF_FREQ_ADJUST 3102
+#else
+#error "_SAMPLE_RATE_XXXXX must be defined to valid rate"
+#endif
+
+/* function prototypes */
+void WT_UpdateLFO (S_LFO_CONTROL *pLFO, EAS_I16 phaseInc);
+
+#if defined(_FILTER_ENABLED) || defined(DLS_SYNTHESIZER)
+void WT_SetFilterCoeffs (S_WT_INT_FRAME *pIntFrame, EAS_I32 cutoff, EAS_I32 resonance);
+#endif
+
+#endif
+
+
diff --git a/arm-hybrid-22k/lib_src/hybrid_22khz_mcu.c b/arm-hybrid-22k/lib_src/hybrid_22khz_mcu.c
index 880819c..1d6816b 100644
--- a/arm-hybrid-22k/lib_src/hybrid_22khz_mcu.c
+++ b/arm-hybrid-22k/lib_src/hybrid_22khz_mcu.c
@@ -1,11 +1,11 @@
-/*----------------------------------------------------------------------------
- *
- * Filename: C:\Sonic\Trunk\EASLib\WTLibrary\hybrid_22khz_mcu.c
- * Source: C:\Sonic\Trunk\Wavetables\Sonic_20Khz_Drums.dls
- * CmdLine: -w C:\Sonic\Trunk\EASLib\WTLibrary\hybrid_22khz_mcu.c -l C:\Sonic\Trunk\EASLib\WTLibrary\hybrid_22khz.log -d 0 -c -f C:\Sonic\Release3-5\EASLib\FMSynth\GMdblib-3.fml C:\Sonic\Trunk\Wavetables\Sonic_20Khz_Drums.dls -w -l -d -c -f C:\Sonic\Trunk\Wavetables\Sonic_20Khz_Drums.dls
- * Purpose: Wavetable sound libary
- *
- * Copyright (c) 2006 Sonic Network Inc.
+/*----------------------------------------------------------------------------
+ *
+ * Filename: C:\Sonic\Trunk\EASLib\WTLibrary\hybrid_22khz_mcu.c
+ * Source: C:\Sonic\Trunk\Wavetables\Sonic_20Khz_Drums.dls
+ * CmdLine: -w C:\Sonic\Trunk\EASLib\WTLibrary\hybrid_22khz_mcu.c -l C:\Sonic\Trunk\EASLib\WTLibrary\hybrid_22khz.log -d 0 -c -f C:\Sonic\Release3-5\EASLib\FMSynth\GMdblib-3.fml C:\Sonic\Trunk\Wavetables\Sonic_20Khz_Drums.dls -w -l -d -c -f C:\Sonic\Trunk\Wavetables\Sonic_20Khz_Drums.dls
+ * Purpose: Wavetable sound libary
+ *
+ * Copyright (c) 2006 Sonic Network Inc.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,5132 +18,5132 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision:$
- * $Date:$
- *----------------------------------------------------------------------------
-*/
-
-#include "eas_sndlib.h"
-
-/*----------------------------------------------------------------------------
- * Articulations
- *----------------------------------------------------------------------------
-*/
-const S_ARTICULATION eas_articulations[] =
-{
- { /* articulation 0 */
- { 32767, 30725, 0, 30725 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 951, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 1 */
- { 32767, 26863, 0, 26863 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 951, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 2 */
- { 32767, 30484, 0, 30668 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 951, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 3 */
- { 32767, 26439, 0, 26439 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 951, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 4 */
- { 32767, 0, 32767, 32715 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 951, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 5 */
- { 32767, 21333, 0, 21333 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 951, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 6 */
- { 32767, 31882, 0, 31938 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 951, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 7 */
- { 32767, 32663, 32767, 32663 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 951, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 8 */
- { 32767, 0, 32767, 0 },
- { 32767, 1902, 0, 0 },
- 0, 0, 951, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 9 */
- { 32767, 32349, 0, 32349 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 951, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 10 */
- { 32767, 0, 32767, 17213 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 951, 0, 0, 0, 0, 0, -1
- },
- { /* articulation 11 */
- { 32767, 32072, 0, 32072 },
- { 32767, 761, 0, 0 },
- 0, 0, 951, 0, 0, 0, 0, 0, -56
- },
- { /* articulation 12 */
- { 32767, 23749, 0, 23749 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 951, 0, 0, 0, 0, 0, 56
- },
- { /* articulation 13 */
- { 32767, 32010, 0, 32010 },
- { 32767, 761, 0, 0 },
- 0, 0, 951, 0, 0, 0, 0, 0, -31
- },
- { /* articulation 14 */
- { 9511, 21333, 0, 21333 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 951, 0, 0, 0, 0, 0, 56
- },
- { /* articulation 15 */
- { 32767, 31844, 0, 31844 },
- { 32767, 761, 0, 0 },
- 0, 0, 951, 0, 0, 0, 0, 0, -6
- },
- { /* articulation 16 */
- { 32767, 32123, 0, 32194 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 951, 0, 0, 0, 0, 0, 56
- },
- { /* articulation 17 */
- { 32767, 31730, 0, 31730 },
- { 32767, 761, 0, 0 },
- 0, 0, 951, 0, 0, 0, 0, 0, 6
- },
- { /* articulation 18 */
- { 32767, 31391, 0, 31391 },
- { 32767, 951, 0, 0 },
- 0, 0, 951, 0, 0, 0, 0, 0, 31
- },
- { /* articulation 19 */
- { 32767, 31964, 0, 31964 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 951, 0, 0, 0, 0, 0, 25
- },
- { /* articulation 20 */
- { 32767, 31056, 0, 31056 },
- { 32767, 951, 0, 0 },
- 0, 0, 951, 0, 0, 0, 0, 0, 63
- },
- { /* articulation 21 */
- { 32767, 32289, 0, 32271 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 951, 0, 0, 0, 0, 0, -37
- },
- { /* articulation 22 */
- { 19021, 31882, 0, 31911 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 951, 0, 0, 0, 0, 0, -37
- },
- { /* articulation 23 */
- { 32767, 31988, 0, 32032 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 951, 0, 0, 0, 0, 0, -37
- },
- { /* articulation 24 */
- { 32767, 0, 32767, 32663 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 951, 0, 0, 0, 0, 0, 12
- },
- { /* articulation 25 */
- { 32767, 31352, 0, 31352 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 951, 0, 0, 0, 0, 0, -25
- },
- { /* articulation 26 */
- { 32767, 0, 32767, 32663 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 951, 0, 0, 0, 0, 0, 25
- },
- { /* articulation 27 */
- { 32767, 31817, 0, 31781 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 951, 0, 0, 0, 0, 0, -25
- },
- { /* articulation 28 */
- { 32767, 30725, 0, 30725 },
- { 32767, 95, 0, 0 },
- 0, 0, 951, 240, 0, 0, 0, 0, -56
- },
- { /* articulation 29 */
- { 32767, 32230, 0, 32218 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 951, 0, 0, 0, 0, 0, -37
- },
- { /* articulation 30 */
- { 32767, 26439, 0, 26439 },
- { 32767, 3804, 0, 0 },
- 0, 0, 951, 0, 0, 0, 0, 0, 50
- },
- { /* articulation 31 */
- { 32767, 23749, 0, 23749 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 951, 0, 0, 0, 0, 0, -50
- },
- { /* articulation 32 */
- { 32767, 29434, 0, 29434 },
- { 32767, 3804, 0, 0 },
- 0, 0, 951, 0, 0, 0, 0, 0, -50
- },
- { /* articulation 33 */
- { 32767, 30240, 0, 30234 },
- { 32767, 3804, 0, 0 },
- 0, 0, 951, 0, 0, 0, 0, 0, -44
- },
- { /* articulation 34 */
- { 32767, 32558, 0, 32558 },
- { 32767, 254, 0, 0 },
- 0, 0, 951, 0, 0, 0, 0, 0, 25
- },
- { /* articulation 35 */
- { 32767, 0, 32767, 32663 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 951, 0, 0, 0, 0, 0, -63
- },
- { /* articulation 36 */
- { 3804, 23749, 0, 23749 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 951, 0, 0, 0, 0, 0, -63
- },
- { /* articulation 37 */
- { 32767, 23749, 0, 23749 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 951, 0, 0, 0, 0, 0, -59
- },
- { /* articulation 38 */
- { 32767, 30725, 0, 30725 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 951, 0, 0, 0, 0, 0, 50
- },
- { /* articulation 39 */
- { 32767, 28809, 0, 28809 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 951, 0, 0, 0, 0, 0, 44
- },
- { /* articulation 40 */
- { 1902, 30725, 0, 30725 },
- { 32767, 380, 0, 0 },
- 0, 0, 951, -100, 0, 0, 0, 0, 44
- },
- { /* articulation 41 */
- { 32767, 9042, 0, 9042 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 951, 0, 0, 0, 0, 0, 25
- },
- { /* articulation 42 */
- { 32767, 29889, 0, 29889 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 951, 0, 0, 0, 0, 0, 63
- },
- { /* articulation 43 */
- { 32767, 30240, 0, 30234 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 951, 0, 0, 0, 0, 0, 63
- },
- { /* articulation 44 */
- { 19021, 19970, 0, 19970 },
- { 951, 32767, 32767, 0 },
- 0, 0, 951, 100, 0, 0, 0, 0, -25
- },
- { /* articulation 45 */
- { 3804, 17213, 0, 17213 },
- { 951, 32767, 32767, 0 },
- 0, 0, 951, 500, 0, 0, 0, 0, -25
- },
- { /* articulation 46 */
- { 32767, 17213, 0, 17213 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 951, 0, 0, 0, 0, 0, -56
- },
- { /* articulation 47 */
- { 32767, 30725, 0, 30725 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 951, 0, 0, 0, 0, 0, -56
- },
- { /* articulation 48 */
- { 32767, 0, 32767, 0 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 951, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 49 */
- { 32767, 31180, 0, 31180 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 951, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 50 */
- { 19021, 31964, 0, 32071 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 951, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 51 */
- { 32767, 29669, 0, 29669 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 951, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 52 */
- { 32767, 31742, 0, 31352 },
- { 32767, 294, 0, 0 },
- 0, 0, 951, 0, 10000, 7121, 0, 0, 0
- }
-}; /*end Articulations */
-
-/*----------------------------------------------------------------------------
- * Regions
- *----------------------------------------------------------------------------
-*/
-const S_WT_REGION eas_regions[] =
-{
- { { 0, 27, 27 }, -2868, 16422, 0, 0, 19, 0 }, /* region 0 */
- { { 0, 28, 28 }, -3568, 32767, 0, 0, 13, 0 }, /* region 1 */
- { { 0, 29, 29 }, -4553, 32767, 0, 0, 9, 1 }, /* region 2 */
- { { 0, 30, 30 }, -4853, 32767, 0, 0, 9, 2 }, /* region 3 */
- { { 0, 31, 31 }, -3868, 23197, 0, 0, 15, 3 }, /* region 4 */
- { { 1536, 32, 32 }, -3368, 20675, 0, 0, 29, 4 }, /* region 5 */
- { { 1537, 33, 33 }, -3868, 20675, 792, 800, 17, 5 }, /* region 6 */
- { { 1537, 34, 34 }, -3968, 16422, 792, 800, 17, 6 }, /* region 7 */
- { { 0, 35, 35 }, -4968, 32767, 0, 0, 20, 7 }, /* region 8 */
- { { 0, 36, 36 }, -4968, 32767, 0, 0, 20, 7 }, /* region 9 */
- { { 0, 37, 37 }, -4051, 18426, 0, 0, 16, 8 }, /* region 10 */
- { { 0, 38, 38 }, -4151, 23197, 0, 0, 5, 9 }, /* region 11 */
- { { 0, 39, 39 }, -4668, 23197, 0, 0, 12, 10 }, /* region 12 */
- { { 0, 40, 40 }, -4151, 23197, 0, 0, 5, 4 }, /* region 13 */
- { { 1, 41, 41 }, -5855, 26028, 798, 993, 14, 11 }, /* region 14 */
- { { 257, 42, 42 }, -4368, 26028, 4288, 6792, 2, 12 }, /* region 15 */
- { { 1, 43, 43 }, -5755, 26028, 798, 993, 14, 13 }, /* region 16 */
- { { 257, 44, 44 }, -4568, 26028, 4288, 6792, 2, 14 }, /* region 17 */
- { { 1, 45, 45 }, -5755, 26028, 798, 993, 14, 15 }, /* region 18 */
- { { 257, 46, 46 }, -4768, 26028, 4288, 6792, 2, 16 }, /* region 19 */
- { { 1, 47, 47 }, -5455, 26028, 798, 993, 14, 17 }, /* region 20 */
- { { 1, 48, 48 }, -5355, 26028, 798, 993, 14, 18 }, /* region 21 */
- { { 1, 49, 49 }, -5368, 16422, 1294, 5241, 3, 19 }, /* region 22 */
- { { 1, 50, 50 }, -5255, 26028, 798, 993, 14, 20 }, /* region 23 */
- { { 1, 51, 51 }, -5268, 16422, 6592, 9921, 0, 21 }, /* region 24 */
- { { 1, 52, 52 }, -5768, 32767, 1294, 5241, 3, 22 }, /* region 25 */
- { { 1, 53, 53 }, -5418, 14636, 6592, 9921, 0, 23 }, /* region 26 */
- { { 0, 54, 54 }, -5751, 26028, 0, 0, 11, 24 }, /* region 27 */
- { { 1, 55, 55 }, -5468, 32767, 1294, 5241, 3, 25 }, /* region 28 */
- { { 0, 56, 56 }, -7255, 32767, 0, 0, 24, 26 }, /* region 29 */
- { { 1, 57, 57 }, -5868, 32767, 1294, 5241, 3, 27 }, /* region 30 */
- { { 1, 58, 58 }, -7053, 23197, 0, 166, 26, 28 }, /* region 31 */
- { { 1, 59, 59 }, -5968, 16422, 6592, 9921, 0, 29 }, /* region 32 */
- { { 1, 60, 60 }, -6453, 23197, 432, 582, 18, 30 }, /* region 33 */
- { { 1, 61, 61 }, -6853, 16422, 432, 582, 18, 30 }, /* region 34 */
- { { 1, 62, 62 }, -7253, 20675, 432, 582, 18, 31 }, /* region 35 */
- { { 1, 63, 63 }, -7353, 23197, 432, 582, 18, 32 }, /* region 36 */
- { { 1, 64, 64 }, -7953, 23197, 432, 582, 18, 33 }, /* region 37 */
- { { 0, 65, 65 }, -7555, 32767, 0, 0, 4, 34 }, /* region 38 */
- { { 0, 66, 66 }, -7955, 20675, 0, 0, 4, 34 }, /* region 39 */
- { { 512, 67, 67 }, -7155, 18426, 0, 0, 24, 35 }, /* region 40 */
- { { 512, 68, 68 }, -7755, 18426, 0, 0, 24, 35 }, /* region 41 */
- { { 0, 69, 69 }, -7755, 32767, 0, 0, 21, 36 }, /* region 42 */
- { { 0, 70, 70 }, -6855, 21900, 0, 0, 21, 37 }, /* region 43 */
- { { 769, 71, 71 }, -6355, 23197, 0, 1226, 10, 38 }, /* region 44 */
- { { 769, 72, 72 }, -6955, 26028, 0, 1226, 10, 38 }, /* region 45 */
- { { 1024, 73, 73 }, -7955, 32767, 0, 0, 7, 39 }, /* region 46 */
- { { 1024, 74, 74 }, -8455, 32767, 0, 0, 7, 40 }, /* region 47 */
- { { 1, 75, 75 }, -8068, 23197, 0, 29, 30, 41 }, /* region 48 */
- { { 0, 76, 76 }, -10455, 23197, 0, 0, 28, 42 }, /* region 49 */
- { { 0, 77, 77 }, -10055, 23197, 0, 0, 28, 43 }, /* region 50 */
- { { 0, 78, 78 }, -8853, 16422, 0, 0, 23, 44 }, /* region 51 */
- { { 0, 79, 79 }, -10253, 16422, 0, 0, 23, 45 }, /* region 52 */
- { { 1280, 80, 80 }, -6468, 13045, 0, 0, 25, 46 }, /* region 53 */
- { { 1280, 81, 81 }, -6568, 16422, 0, 0, 25, 47 }, /* region 54 */
- { { 0, 82, 82 }, -8455, 20675, 0, 0, 22, 48 }, /* region 55 */
- { { 0, 83, 83 }, -9068, 32767, 0, 0, 6, 49 }, /* region 56 */
- { { 1, 84, 84 }, -8568, 23197, 0, 9337, 1, 50 }, /* region 57 */
- { { 0, 85, 85 }, -9655, 32767, 0, 0, 27, 0 }, /* region 58 */
- { { 0, 86, 86 }, -9068, 16422, 0, 0, 8, 51 }, /* region 59 */
- { { 32769, 87, 87 }, -9168, 32767, 1335, 1603, 8, 52 } /* region 60 */
-}; /* end Regions */
-
-/*----------------------------------------------------------------------------
- * FM Regions
- *----------------------------------------------------------------------------
-*/
-const S_FM_REGION eas_fmRegions[] =
-{
-
- { /* FM region 0 */
- { 37, 0, 127 }, 0, 255, 8, 0,
- {
- { 514, 239, 47, 97, 0, 184, 3 },
- { 1, 244, 89, 114, 0, 248, 2 },
- { 3370, 244, 49, 76, 40, 192, 2 },
- { -1, 227, 97, 51, 160, 212, 2 }
- }
- },
- { /* FM region 1 */
- { 37, 0, 127 }, 160, 255, 8, 0,
- {
- { 2514, 223, 95, 72, 0, 176, 3 },
- { 1, 244, 73, 145, 0, 244, 2 },
- { 3600, 245, 81, 198, 40, 192, 2 },
- { 3, 246, 81, 163, 108, 212, 2 }
- }
- },
- { /* FM region 2 */
- { 37, 0, 127 }, 160, 255, 119, 0,
- {
- { 0, 216, 79, 72, 0, 216, 2 },
- { 2, 244, 73, 145, 0, 244, 2 },
- { 3370, 247, 33, 182, 60, 204, 2 },
- { 1200, 246, 65, 163, 108, 204, 2 }
- }
- },
- { /* FM region 3 */
- { 37, 0, 127 }, 160, 255, 1, 0,
- {
- { 3369, 248, 65, 71, 40, 208, 2 },
- { -3, 245, 88, 113, 0, 244, 2 },
- { 2784, 225, 65, 133, 80, 192, 2 },
- { 3, 241, 81, 113, 80, 216, 2 }
- }
- },
- { /* FM region 4 */
- { 34, 0, 127 }, 0, 255, 128, 0,
- {
- { 0, 229, 155, 183, 0, 228, 2 },
- { -3, 243, 90, 81, 0, 244, 2 },
- { 4800, 248, 109, 180, 36, 192, 2 },
- { 3, 245, 90, 85, 16, 244, 2 }
- }
- },
- { /* FM region 5 */
- { 34, 0, 127 }, 9, 96, 192, 0,
- {
- { 1200, 229, 157, 180, 0, 216, 2 },
- { -3, 244, 90, 81, 0, 244, 2 },
- { 1902, 255, 111, 182, 80, 208, 2 },
- { 3, 246, 92, 83, 0, 244, 2 }
- }
- },
- { /* FM region 6 */
- { 34, 0, 127 }, 0, 255, 154, 0,
- {
- { 3102, 244, 63, 102, 228, 228, 2 },
- { 1200, 247, 93, 97, 0, 236, 2 },
- { 1902, 255, 63, 98, 156, 220, 2 },
- { 1200, 244, 92, 98, 0, 236, 2 }
- }
- },
- { /* FM region 7 */
- { 37, 0, 127 }, 0, 255, 202, 0,
- {
- { 0, 251, 131, 19, 216, 220, 2 },
- { 1201, 247, 62, 113, 0, 240, 2 },
- { 0, 243, 154, 36, 240, 224, 2 },
- { 2784, 250, 61, 36, 240, 208, 2 }
- }
- },
- { /* FM region 8 */
- { 33, 0, 127 }, 0, 255, 80, 0,
- {
- { -1, 213, 191, 183, 0, 204, 2 },
- { 1, 245, 154, 129, 0, 244, 2 },
- { 3831, 252, 159, 100, 0, 200, 2 },
- { 1197, 246, 91, 182, 0, 244, 2 }
- }
- },
- { /* FM region 9 */
- { 34, 0, 127 }, 48, 80, 21, 0,
- {
- { 2982, 255, 43, 96, 0, 196, 3 },
- { 3, 247, 71, 130, 0, 244, 2 },
- { 3358, 253, 40, 98, 144, 208, 2 },
- { -2, 246, 70, 130, 0, 236, 2 }
- }
- },
- { /* FM region 10 */
- { 34, 0, 127 }, 48, 80, 26, 0,
- {
- { 3096, 249, 72, 100, 0, 208, 2 },
- { 2185, 249, 102, 130, 0, 240, 2 },
- { 3386, 247, 66, 100, 144, 212, 2 },
- { -2, 247, 102, 130, 0, 240, 2 }
- }
- },
- { /* FM region 11 */
- { 34, 0, 127 }, 92, 67, 21, 0,
- {
- { 2982, 255, 27, 146, 0, 200, 3 },
- { 3, 246, 68, 146, 0, 240, 2 },
- { 3358, 250, 149, 116, 144, 208, 2 },
- { -3, 245, 68, 146, 0, 240, 0 }
- }
- },
- { /* FM region 12 */
- { 34, 0, 127 }, 0, 67, 0, 0,
- {
- { 1500, 239, 60, 151, 0, 220, 2 },
- { 0, 247, 76, 146, 0, 240, 2 },
- { 2398, 234, 156, 151, 0, 212, 2 },
- { 0, 246, 105, 146, 0, 244, 2 }
- }
- },
- { /* FM region 13 */
- { 34, 0, 127 }, 0, 67, 0, 0,
- {
- { 2500, 255, 60, 151, 0, 220, 2 },
- { 0, 249, 92, 146, 0, 244, 2 },
- { 3369, 250, 156, 151, 0, 196, 2 },
- { 0, 248, 89, 146, 0, 244, 2 }
- }
- },
- { /* FM region 14 */
- { 37, 0, 127 }, 160, 255, 0, 0,
- {
- { 2300, 229, 112, 49, 0, 208, 2 },
- { -3, 247, 67, 50, 0, 248, 2 },
- { 1074, 255, 41, 49, 0, 196, 2 },
- { 686, 240, 97, 18, 0, 196, 2 }
- }
- },
- { /* FM region 15 */
- { 37, 0, 127 }, 160, 255, 219, 0,
- {
- { 3369, 255, 65, 70, 40, 216, 2 },
- { 1, 246, 72, 113, 0, 240, 2 },
- { 1902, 225, 33, 129, 80, 204, 2 },
- { 2400, 225, 97, 113, 80, 200, 2 }
- }
- },
- { /* FM region 16 */
- { 35, 0, 127 }, 32, 48, 151, 0,
- {
- { 1201, 215, 35, 66, 252, 208, 0 },
- { -9581, 254, 63, 177, 240, 240, 3 },
- { 1902, 248, 47, 64, 112, 244, 2 },
- { 0, 247, 35, 66, 208, 212, 2 }
- }
- },
- { /* FM region 17 */
- { 33, 0, 127 }, 0, 255, 153, 0,
- {
- { 1, 252, 31, 3, 244, 196, 2 },
- { -1, 208, 31, 4, 248, 244, 2 },
- { 1205, 209, 31, 4, 248, 236, 2 },
- { 1899, 250, 31, 32, 0, 240, 2 }
- }
- },
- { /* FM region 18 */
- { 34, 0, 127 }, 32, 49, 201, 0,
- {
- { 1, 220, 47, 3, 244, 220, 0 },
- { -10000, 208, 63, 1, 248, 240, 3 },
- { 1586, 255, 47, 3, 188, 216, 2 },
- { -1, 202, 63, 32, 80, 232, 2 }
- }
- },
- { /* FM region 19 */
- { 33, 0, 127 }, 0, 143, 29, 0,
- {
- { -1200, 223, 64, 0, 252, 216, 2 },
- { 1200, 96, 41, 35, 248, 240, 2 },
- { 1200, 143, 41, 64, 252, 224, 2 },
- { 3102, 161, 41, 96, 248, 216, 2 }
- }
- },
- { /* FM region 20 */
- { 34, 0, 127 }, 0, 143, 34, 0,
- {
- { -1200, 133, 79, 1, 252, 212, 2 },
- { 1201, 112, 46, 34, 248, 232, 2 },
- { 0, 116, 79, 65, 252, 200, 2 },
- { 1900, 161, 46, 98, 248, 232, 2 }
- }
- },
- { /* FM region 21 */
- { 34, 0, 127 }, 0, 143, 187, 0,
- {
- { 1202, 80, 74, 1, 252, 216, 2 },
- { 2402, 112, 46, 34, 248, 232, 2 },
- { 0, 99, 78, 97, 184, 216, 2 },
- { 1899, 81, 46, 98, 236, 232, 2 }
- }
- },
- { /* FM region 22 */
- { 37, 0, 127 }, 22, 141, 34, 0,
- {
- { 2787, 176, 79, 4, 252, 208, 2 },
- { 2785, 144, 45, 34, 248, 236, 2 },
- { 3369, 83, 77, 100, 184, 172, 2 },
- { 1902, 102, 45, 100, 172, 212, 0 }
- }
- },
- { /* FM region 23 */
- { 34, 0, 127 }, 0, 143, 135, 0,
- {
- { 1900, 112, 79, 3, 252, 220, 2 },
- { 2400, 128, 45, 34, 248, 232, 2 },
- { 1200, 115, 77, 98, 184, 220, 2 },
- { 1904, 97, 45, 98, 236, 232, 2 }
- }
- },
- { /* FM region 24 */
- { 37, 0, 127 }, 0, 255, 157, 0,
- {
- { 1200, 244, 54, 4, 20, 200, 2 },
- { 0, 245, 92, 130, 0, 244, 2 },
- { 3802, 247, 68, 21, 0, 196, 2 },
- { 1, 245, 43, 114, 0, 204, 2 }
- }
- },
- { /* FM region 25 */
- { 37, 0, 127 }, 0, 128, 83, 0,
- {
- { 0, 244, 51, 4, 200, 204, 0 },
- { 0, 247, 108, 129, 0, 248, 0 },
- { 2786, 243, 31, 70, 200, 220, 0 },
- { 1902, 246, 44, 113, 12, 188, 0 }
- }
- },
- { /* FM region 26 */
- { 37, 0, 127 }, 0, 128, 61, 0,
- {
- { 0, 246, 51, 97, 76, 204, 0 },
- { 0, 244, 60, 97, 0, 240, 0 },
- { 1786, 255, 31, 64, 0, 180, 0 },
- { 1200, 247, 60, 97, 12, 204, 0 }
- }
- },
- { /* FM region 27 */
- { 37, 0, 127 }, 0, 128, 153, 0,
- {
- { -2, 243, 53, 99, 96, 200, 0 },
- { 0, 243, 60, 97, 0, 240, 0 },
- { 3983, 247, 63, 100, 24, 204, 0 },
- { 2, 242, 53, 99, 52, 212, 0 }
- }
- },
- { /* FM region 28 */
- { 37, 0, 127 }, 0, 128, 205, 0,
- {
- { -2, 244, 47, 97, 20, 208, 0 },
- { 0, 252, 75, 193, 0, 248, 0 },
- { 0, 254, 63, 98, 132, 224, 0 },
- { 2786, 251, 63, 98, 52, 192, 0 }
- }
- },
- { /* FM region 29 */
- { 37, 0, 127 }, 0, 128, 221, 0,
- {
- { -1, 208, 191, 99, 220, 224, 0 },
- { 1200, 243, 92, 97, 0, 244, 0 },
- { 3984, 212, 11, 96, 168, 196, 0 },
- { 1, 242, 127, 98, 108, 204, 0 }
- }
- },
- { /* FM region 30 */
- { 37, 0, 127 }, 0, 128, 174, 0,
- {
- { -3, 212, 207, 99, 0, 228, 0 },
- { 1902, 241, 108, 97, 0, 248, 0 },
- { 3805, 212, 59, 98, 0, 220, 0 },
- { 1902, 146, 107, 98, 144, 196, 0 }
- }
- },
- { /* FM region 31 */
- { 41, 0, 127 }, 0, 255, 128, 0,
- {
- { 1206, 239, 43, 69, 0, 216, 2 },
- { 4, 254, 42, 66, 0, 244, 2 },
- { 702, 88, 55, 66, 0, 204, 2 },
- { -4, 71, 55, 66, 0, 240, 2 }
- }
- },
- { /* FM region 32 */
- { 37, 0, 127 }, 0, 255, 85, 0,
- {
- { 500, 239, 95, 82, 0, 184, 3 },
- { 0, 248, 73, 132, 0, 252, 2 },
- { 2786, 203, 59, 130, 0, 176, 2 },
- { 0, 216, 42, 100, 0, 208, 2 }
- }
- },
- { /* FM region 33 */
- { 37, 0, 127 }, 0, 128, 73, 0,
- {
- { 1, 229, 54, 131, 160, 208, 0 },
- { -1, 244, 62, 97, 0, 248, 0 },
- { 3986, 227, 127, 69, 140, 184, 0 },
- { 1201, 249, 92, 114, 0, 204, 0 }
- }
- },
- { /* FM region 34 */
- { 37, 0, 127 }, 0, 128, 73, 0,
- {
- { 1, 225, 54, 100, 200, 212, 0 },
- { -1, 244, 94, 97, 0, 248, 0 },
- { 3986, 249, 127, 88, 112, 188, 0 },
- { 1201, 249, 92, 85, 52, 208, 0 }
- }
- },
- { /* FM region 35 */
- { 37, 0, 127 }, 0, 128, 188, 0,
- {
- { -3, 198, 92, 179, 28, 212, 0 },
- { 0, 243, 90, 145, 0, 248, 0 },
- { 1901, 215, 95, 69, 28, 196, 0 },
- { 3, 84, 108, 196, 32, 208, 0 }
- }
- },
- { /* FM region 36 */
- { 37, 0, 127 }, 0, 136, 6, 0,
- {
- { 0, 226, 99, 36, 224, 216, 0 },
- { 1902, 248, 78, 33, 0, 252, 0 },
- { 3369, 239, 250, 33, 0, 204, 0 },
- { 0, 230, 253, 33, 0, 208, 0 }
- }
- },
- { /* FM region 37 */
- { 37, 0, 127 }, 0, 136, 195, 0,
- {
- { 0, 245, 99, 36, 152, 208, 0 },
- { 1200, 248, 78, 33, 0, 252, 0 },
- { 3369, 246, 250, 33, 0, 216, 0 },
- { 0, 246, 61, 33, 0, 180, 0 }
- }
- },
- { /* FM region 38 */
- { 34, 0, 127 }, 0, 133, 221, 0,
- {
- { 1, 244, 67, 35, 80, 220, 0 },
- { 3, 246, 94, 33, 0, 244, 0 },
- { -1, 245, 70, 35, 80, 236, 2 },
- { -3, 246, 63, 33, 0, 236, 2 }
- }
- },
- { /* FM region 39 */
- { 34, 0, 127 }, 0, 133, 220, 0,
- {
- { 0, 114, 51, 34, 132, 208, 0 },
- { 3, 214, 62, 33, 0, 248, 0 },
- { 0, 85, 54, 34, 44, 224, 2 },
- { -3, 214, 63, 33, 0, 236, 2 }
- }
- },
- { /* FM region 40 */
- { 37, 0, 127 }, 48, 142, 187, 0,
- {
- { -1, 33, 22, 33, 200, 208, 0 },
- { 0, 81, 105, 33, 220, 240, 0 },
- { 2786, 245, 19, 50, 208, 192, 0 },
- { 1, 245, 21, 82, 200, 220, 0 }
- }
- },
- { /* FM region 41 */
- { 37, 0, 127 }, 48, 126, 103, 0,
- {
- { -1, 193, 22, 33, 228, 212, 0 },
- { 0, 81, 105, 33, 220, 244, 0 },
- { 0, 245, 19, 50, 216, 228, 0 },
- { 1200, 245, 19, 82, 200, 188, 0 }
- }
- },
- { /* FM region 42 */
- { 37, 0, 127 }, 16, 126, 202, 0,
- {
- { -1, 49, 24, 41, 200, 212, 0 },
- { 0, 81, 71, 49, 220, 244, 0 },
- { 3371, 243, 19, 36, 232, 192, 0 },
- { 1, 242, 24, 36, 220, 212, 0 }
- }
- },
- { /* FM region 43 */
- { 37, 0, 127 }, 16, 124, 205, 0,
- {
- { 0, 129, 24, 49, 208, 200, 0 },
- { 0, 67, 102, 81, 224, 244, 0 },
- { 3804, 246, 23, 36, 160, 196, 0 },
- { 1200, 244, 24, 35, 208, 200, 0 }
- }
- },
- { /* FM region 44 */
- { 37, 0, 127 }, 48, 144, 208, 0,
- {
- { -3, 209, 22, 33, 200, 204, 2 },
- { 0, 81, 89, 33, 220, 240, 2 },
- { -5000, 208, 6, 33, 244, 188, 3 },
- { 3, 97, 89, 33, 224, 200, 0 }
- }
- },
- { /* FM region 45 */
- { 37, 0, 127 }, 0, 255, 186, 0,
- {
- { 500, 223, 95, 0, 0, 192, 3 },
- { 0, 247, 89, 100, 0, 248, 2 },
- { 3369, 255, 59, 168, 0, 212, 2 },
- { 0, 216, 42, 97, 0, 212, 2 }
- }
- },
- { /* FM region 46 */
- { 34, 0, 127 }, 0, 255, 221, 0,
- {
- { 1206, 235, 70, 69, 0, 216, 2 },
- { 4, 248, 84, 66, 0, 244, 2 },
- { 1902, 247, 52, 137, 80, 216, 2 },
- { -4, 245, 84, 131, 0, 240, 2 }
- }
- },
- { /* FM region 47 */
- { 37, 0, 127 }, 0, 255, 105, 0,
- {
- { 387, 231, 115, 34, 4, 216, 2 },
- { 0, 248, 37, 65, 0, 252, 2 },
- { 3308, 248, 117, 34, 8, 200, 2 },
- { 1900, 213, 82, 50, 0, 192, 2 }
- }
- },
- { /* FM region 48 */
- { 34, 0, 127 }, 32, 160, 221, 0,
- {
- { -7, 209, 22, 33, 200, 204, 2 },
- { -7, 81, 73, 33, 220, 244, 0 },
- { 7, 209, 22, 33, 200, 208, 0 },
- { 7, 97, 73, 33, 224, 244, 2 }
- }
- },
- { /* FM region 49 */
- { 34, 0, 127 }, 64, 128, 189, 0,
- {
- { -2, 209, 54, 32, 224, 216, 2 },
- { -7726, 97, 105, 33, 220, 240, 3 },
- { 1902, 209, 54, 34, 216, 208, 0 },
- { 2, 81, 105, 33, 224, 236, 0 }
- }
- },
- { /* FM region 50 */
- { 34, 0, 127 }, 80, 144, 206, 0,
- {
- { -3, 179, 38, 33, 160, 220, 2 },
- { -7726, 81, 69, 34, 220, 244, 3 },
- { 3, 193, 38, 33, 240, 212, 0 },
- { -8000, 65, 69, 34, 224, 236, 3 }
- }
- },
- { /* FM region 51 */
- { 37, 0, 127 }, 96, 128, 204, 0,
- {
- { -3, 97, 38, 33, 180, 216, 0 },
- { 0, 81, 69, 34, 220, 240, 2 },
- { 3369, 145, 38, 33, 240, 196, 2 },
- { -13190, 65, 69, 34, 240, 200, 3 }
- }
- },
- { /* FM region 52 */
- { 34, 0, 127 }, 64, 128, 108, 0,
- {
- { -3, 193, 37, 35, 236, 208, 0 },
- { 2394, 97, 90, 36, 224, 232, 2 },
- { 3, 65, 40, 35, 236, 204, 2 },
- { 1203, 97, 89, 33, 224, 240, 0 }
- }
- },
- { /* FM region 53 */
- { 37, 0, 127 }, 128, 128, 122, 0,
- {
- { 0, 193, 21, 34, 236, 188, 0 },
- { 3, 97, 74, 36, 224, 248, 2 },
- { 1906, 251, 24, 32, 96, 192, 3 },
- { 1200, 97, 73, 32, 224, 184, 0 }
- }
- },
- { /* FM region 54 */
- { 34, 0, 127 }, 64, 133, 135, 0,
- {
- { 0, 194, 25, 35, 120, 200, 2 },
- { 0, 97, 75, 36, 224, 240, 0 },
- { 2906, 254, 28, 48, 0, 184, 3 },
- { 0, 216, 75, 80, 204, 240, 2 }
- }
- },
- { /* FM region 55 */
- { 41, 0, 127 }, 208, 64, 255, 0,
- {
- { 475, 249, 16, 32, 252, 240, 2 },
- { 702, 248, 71, 32, 0, 244, 2 },
- { 1136, 232, 27, 32, 216, 248, 0 },
- { 0, 249, 23, 48, 0, 248, 2 }
- }
- },
- { /* FM region 56 */
- { 37, 0, 127 }, 0, 132, 233, 0,
- {
- { 0, 195, 95, 64, 240, 208, 0 },
- { 0, 225, 94, 64, 248, 240, 0 },
- { 0, 254, 127, 0, 4, 196, 4 },
- { 1902, 228, 95, 1, 248, 200, 0 }
- }
- },
- { /* FM region 57 */
- { 37, 0, 127 }, 16, 140, 238, 0,
- {
- { 0, 163, 90, 67, 228, 208, 0 },
- { 0, 209, 77, 65, 248, 240, 0 },
- { 1969, 173, 58, 65, 0, 176, 0 },
- { 0, 210, 61, 52, 204, 220, 0 }
- }
- },
- { /* FM region 58 */
- { 37, 0, 127 }, 16, 140, 222, 0,
- {
- { 0, 119, 74, 67, 160, 212, 0 },
- { 0, 146, 61, 65, 248, 244, 0 },
- { 1900, 137, 58, 65, 100, 196, 0 },
- { 0, 119, 61, 52, 120, 200, 0 }
- }
- },
- { /* FM region 59 */
- { 37, 0, 127 }, 16, 135, 219, 0,
- {
- { 0, 176, 79, 69, 240, 216, 0 },
- { 0, 193, 79, 64, 248, 236, 0 },
- { 0, 178, 123, 54, 92, 228, 0 },
- { 3369, 212, 95, 38, 144, 212, 0 }
- }
- },
- { /* FM region 60 */
- { 34, 0, 127 }, 0, 119, 203, 0,
- {
- { 2, 65, 77, 66, 228, 204, 0 },
- { 2, 161, 74, 64, 240, 240, 0 },
- { -2, 85, 60, 66, 180, 216, 2 },
- { -2, 162, 74, 64, 220, 240, 2 }
- }
- },
- { /* FM region 61 */
- { 34, 0, 127 }, 16, 154, 237, 0,
- {
- { 0, 179, 42, 64, 216, 208, 0 },
- { 0, 209, 61, 64, 248, 244, 0 },
- { -1200, 226, 55, 65, 244, 220, 2 },
- { 1902, 162, 62, 52, 204, 236, 2 }
- }
- },
- { /* FM region 62 */
- { 34, 0, 127 }, 48, 119, 221, 0,
- {
- { 2, 119, 79, 64, 208, 212, 0 },
- { 2, 209, 110, 64, 248, 236, 0 },
- { -2, 84, 79, 64, 136, 212, 2 },
- { -2, 209, 110, 64, 240, 240, 2 }
- }
- },
- { /* FM region 63 */
- { 34, 0, 127 }, 32, 135, 221, 0,
- {
- { 2, 165, 79, 64, 152, 216, 0 },
- { 2, 225, 110, 64, 248, 236, 0 },
- { -2, 132, 79, 64, 72, 224, 2 },
- { -2, 241, 110, 64, 252, 236, 2 }
- }
- },
- { /* FM region 64 */
- { 37, 0, 127 }, 17, 127, 190, 0,
- {
- { 0, 209, 60, 67, 244, 208, 0 },
- { 1200, 145, 94, 65, 248, 244, 2 },
- { 3369, 197, 47, 4, 128, 192, 0 },
- { 1902, 167, 94, 6, 200, 200, 0 }
- }
- },
- { /* FM region 65 */
- { 37, 0, 127 }, 17, 143, 190, 0,
- {
- { 0, 209, 60, 67, 244, 216, 0 },
- { 1902, 145, 62, 65, 248, 240, 2 },
- { 3369, 197, 47, 4, 128, 196, 0 },
- { 2400, 167, 94, 6, 200, 212, 2 }
- }
- },
- { /* FM region 66 */
- { 37, 0, 127 }, 17, 143, 190, 0,
- {
- { 0, 209, 60, 67, 244, 208, 0 },
- { 1902, 145, 62, 65, 248, 240, 2 },
- { 3369, 197, 47, 4, 128, 192, 0 },
- { 1902, 167, 94, 6, 200, 216, 2 }
- }
- },
- { /* FM region 67 */
- { 37, 0, 127 }, 17, 125, 190, 0,
- {
- { 0, 114, 109, 67, 244, 224, 0 },
- { 1902, 166, 93, 97, 200, 240, 0 },
- { 2786, 165, 95, 52, 160, 200, 0 },
- { 2400, 173, 78, 54, 240, 212, 2 }
- }
- },
- { /* FM region 68 */
- { 34, 0, 127 }, 16, 140, 205, 0,
- {
- { 0, 211, 55, 66, 244, 208, 0 },
- { 1902, 193, 93, 65, 248, 240, 0 },
- { 0, 204, 47, 4, 244, 216, 0 },
- { 3600, 183, 95, 6, 160, 232, 0 }
- }
- },
- { /* FM region 69 */
- { 34, 0, 127 }, 16, 126, 222, 0,
- {
- { 0, 243, 36, 66, 172, 200, 0 },
- { 1200, 193, 110, 67, 248, 244, 0 },
- { 0, 215, 33, 2, 232, 212, 0 },
- { 3369, 178, 63, 6, 184, 240, 0 }
- }
- },
- { /* FM region 70 */
- { 34, 0, 127 }, 16, 140, 221, 0,
- {
- { 1200, 213, 61, 66, 136, 200, 0 },
- { 1902, 193, 93, 68, 248, 240, 0 },
- { 0, 197, 47, 2, 228, 216, 0 },
- { 3369, 183, 95, 2, 160, 236, 0 }
- }
- },
- { /* FM region 71 */
- { 34, 0, 127 }, 16, 124, 201, 0,
- {
- { 1200, 195, 55, 68, 240, 208, 0 },
- { 0, 209, 76, 65, 248, 236, 0 },
- { 1902, 147, 47, 19, 208, 212, 0 },
- { 0, 183, 79, 22, 156, 228, 0 }
- }
- },
- { /* FM region 72 */
- { 37, 0, 127 }, 32, 110, 234, 0,
- {
- { 500, 237, 60, 68, 0, 192, 1 },
- { 1, 161, 93, 65, 248, 240, 2 },
- { 3365, 154, 47, 16, 48, 180, 6 },
- { 1200, 165, 92, 52, 160, 212, 2 }
- }
- },
- { /* FM region 73 */
- { 37, 0, 127 }, 32, 142, 200, 0,
- {
- { 0, 193, 60, 68, 248, 200, 0 },
- { 1, 129, 61, 65, 248, 240, 2 },
- { 3365, 154, 47, 16, 68, 184, 6 },
- { 1200, 169, 92, 52, 160, 204, 2 }
- }
- },
- { /* FM region 74 */
- { 35, 0, 127 }, 32, 135, 36, 0,
- {
- { 1199, 165, 79, 66, 152, 192, 2 },
- { -3, 145, 110, 64, 248, 240, 2 },
- { 0, 199, 79, 66, 44, 236, 2 },
- { 2986, 136, 110, 67, 100, 196, 2 }
- }
- },
- { /* FM region 75 */
- { 37, 0, 127 }, 32, 190, 71, 0,
- {
- { 868, 202, 140, 16, 24, 188, 2 },
- { 0, 176, 77, 65, 248, 240, 2 },
- { 3750, 169, 127, 16, 36, 228, 6 },
- { 2400, 195, 60, 17, 232, 172, 2 }
- }
- },
- { /* FM region 76 */
- { 37, 0, 127 }, 224, 16, 123, 0,
- {
- { 275, 202, 14, 2, 44, 196, 2 },
- { 0, 165, 89, 65, 56, 244, 2 },
- { 0, 255, 12, 2, 64, 216, 6 },
- { 963, 169, 14, 4, 40, 196, 2 }
- }
- },
- { /* FM region 77 */
- { 50, 0, 127 }, 192, 128, 100, 0,
- {
- { 1500, 202, 79, 68, 76, 204, 2 },
- { -2, 97, 26, 64, 248, 232, 2 },
- { 1588, 202, 223, 69, 4, 220, 0 },
- { 3, 188, 121, 67, 48, 252, 2 }
- }
- },
- { /* FM region 78 */
- { 34, 0, 127 }, 112, 140, 205, 0,
- {
- { 0, 68, 47, 66, 60, 176, 2 },
- { -2, 113, 94, 64, 248, 236, 0 },
- { 5000, 121, 47, 64, 32, 168, 7 },
- { 3, 136, 94, 64, 0, 236, 0 }
- }
- },
- { /* FM region 79 */
- { 35, 0, 127 }, 32, 135, 33, 0,
- {
- { 1199, 197, 79, 66, 152, 184, 2 },
- { 0, 161, 110, 64, 248, 240, 2 },
- { 0, 199, 79, 66, 44, 236, 2 },
- { 2400, 255, 110, 65, 36, 208, 6 }
- }
- },
- { /* FM region 80 */
- { 34, 0, 127 }, 0, 192, 170, 0,
- {
- { 1199, 192, 77, 33, 200, 212, 0 },
- { 0, 209, 107, 33, 232, 240, 0 },
- { 1201, 80, 77, 33, 200, 212, 0 },
- { 0, 241, 107, 33, 232, 240, 0 }
- }
- },
- { /* FM region 81 */
- { 34, 0, 127 }, 0, 192, 221, 0,
- {
- { -1, 192, 45, 33, 200, 212, 0 },
- { -1, 209, 107, 33, 232, 244, 0 },
- { 1, 80, 45, 33, 200, 212, 0 },
- { 1, 241, 107, 33, 232, 244, 0 }
- }
- },
- { /* FM region 82 */
- { 37, 0, 127 }, 0, 112, 255, 0,
- {
- { 4750, 221, 45, 34, 48, 172, 4 },
- { -10000, 161, 107, 33, 200, 244, 3 },
- { 2204, 137, 45, 37, 64, 184, 0 },
- { -2, 211, 107, 33, 160, 208, 0 }
- }
- },
- { /* FM region 83 */
- { 37, 0, 127 }, 16, 127, 238, 0,
- {
- { 2, 248, 45, 32, 204, 208, 0 },
- { -9500, 241, 107, 33, 200, 240, 3 },
- { 3369, 186, 45, 38, 24, 208, 0 },
- { -2, 211, 107, 32, 220, 212, 0 }
- }
- },
- { /* FM region 84 */
- { 37, 0, 127 }, 0, 128, 221, 0,
- {
- { -1, 192, 191, 99, 220, 216, 0 },
- { 1200, 243, 92, 97, 0, 244, 0 },
- { 3984, 200, 11, 96, 168, 192, 0 },
- { 1, 194, 127, 98, 108, 200, 0 }
- }
- },
- { /* FM region 85 */
- { 34, 0, 127 }, 128, 128, 111, 0,
- {
- { 1, 194, 25, 35, 120, 204, 2 },
- { -9750, 193, 107, 36, 224, 244, 3 },
- { 3906, 255, 28, 50, 12, 188, 3 },
- { -1, 216, 107, 80, 204, 240, 2 }
- }
- },
- { /* FM region 86 */
- { 34, 0, 127 }, 32, 134, 222, 0,
- {
- { 0, 195, 52, 33, 200, 208, 0 },
- { 0, 177, 90, 33, 232, 240, 2 },
- { 702, 195, 52, 33, 200, 208, 2 },
- { 702, 177, 90, 34, 232, 240, 2 }
- }
- },
- { /* FM region 87 */
- { 34, 0, 127 }, 32, 134, 205, 0,
- {
- { 0, 198, 75, 36, 120, 220, 2 },
- { 0, 225, 78, 52, 40, 244, 2 },
- { 0, 246, 47, 32, 220, 208, 2 },
- { 1902, 241, 124, 32, 240, 236, 2 }
- }
- },
- { /* FM region 88 */
- { 35, 0, 127 }, 32, 120, 14, 0,
- {
- { 3600, 244, 67, 34, 88, 208, 0 },
- { 3, 194, 84, 33, 84, 240, 2 },
- { -3, 194, 84, 33, 172, 236, 2 },
- { 902, 254, 114, 34, 0, 224, 3 }
- }
- },
- { /* FM region 89 */
- { 34, 0, 127 }, 64, 169, 170, 0,
- {
- { -3, 83, 69, 34, 184, 212, 0 },
- { -7500, 50, 69, 33, 176, 244, 3 },
- { 3, 81, 69, 34, 212, 212, 2 },
- { -8500, 66, 69, 33, 176, 244, 3 }
- }
- },
- { /* FM region 90 */
- { 34, 0, 127 }, 64, 120, 221, 0,
- {
- { -2, 82, 69, 34, 244, 216, 0 },
- { 0, 145, 102, 33, 228, 240, 0 },
- { 2, 81, 69, 34, 244, 208, 2 },
- { 0, 145, 102, 33, 224, 240, 2 }
- }
- },
- { /* FM region 91 */
- { 35, 0, 127 }, 32, 138, 14, 0,
- {
- { 2400, 148, 67, 34, 176, 200, 0 },
- { 3, 194, 85, 33, 220, 236, 2 },
- { -3, 194, 69, 33, 220, 236, 2 },
- { 1905, 254, 114, 34, 48, 224, 2 }
- }
- },
- { /* FM region 92 */
- { 34, 0, 127 }, 82, 67, 71, 0,
- {
- { 2982, 228, 22, 146, 88, 192, 3 },
- { 3, 102, 84, 146, 196, 240, 2 },
- { 3358, 50, 149, 116, 144, 208, 2 },
- { -3, 85, 84, 146, 120, 240, 0 }
- }
- },
- { /* FM region 93 */
- { 37, 0, 127 }, 48, 126, 219, 0,
- {
- { -3, 49, 19, 33, 120, 200, 0 },
- { 0, 81, 70, 33, 220, 240, 0 },
- { 3804, 242, 18, 50, 200, 200, 0 },
- { 1203, 82, 19, 82, 200, 176, 0 }
- }
- },
- { /* FM region 94 */
- { 35, 0, 127 }, 32, 138, 13, 0,
- {
- { 2786, 116, 67, 34, 204, 184, 0 },
- { 1902, 114, 69, 33, 192, 232, 2 },
- { -3, 178, 69, 33, 188, 232, 2 },
- { 3804, 254, 82, 34, 164, 228, 2 }
- }
- },
- { /* FM region 95 */
- { 34, 0, 127 }, 48, 135, 238, 0,
- {
- { -2, 34, 85, 34, 184, 224, 0 },
- { 1, 113, 70, 33, 228, 236, 0 },
- { 2, 19, 85, 34, 156, 224, 2 },
- { -1, 129, 70, 33, 224, 236, 2 }
- }
- },
- { /* FM region 96 */
- { 50, 0, 127 }, 240, 112, 221, 0,
- {
- { 3369, 213, 69, 32, 0, 204, 0 },
- { 0, 193, 70, 33, 112, 232, 2 },
- { 0, 145, 69, 34, 244, 208, 2 },
- { -9000, 145, 70, 33, 224, 236, 3 }
- }
- },
- { /* FM region 97 */
- { 34, 0, 127 }, 96, 122, 168, 0,
- {
- { -1, 99, 51, 33, 200, 208, 0 },
- { -8500, 81, 83, 33, 232, 240, 3 },
- { 702, 99, 52, 33, 200, 208, 2 },
- { -9500, 65, 83, 34, 224, 240, 3 }
- }
- },
- { /* FM region 98 */
- { 34, 0, 127 }, 0, 67, 0, 0,
- {
- { 1500, 217, 55, 151, 20, 224, 2 },
- { 3, 231, 70, 146, 88, 220, 2 },
- { 2369, 115, 148, 151, 32, 196, 2 },
- { -3, 118, 36, 146, 64, 244, 2 }
- }
- },
- { /* FM region 99 */
- { 34, 0, 127 }, 64, 169, 204, 0,
- {
- { -3, 228, 69, 34, 148, 220, 0 },
- { -7448, 243, 69, 33, 200, 240, 3 },
- { 3, 81, 68, 34, 212, 212, 2 },
- { -8526, 65, 68, 33, 196, 240, 3 }
- }
- },
- { /* FM region 100 */
- { 34, 0, 127 }, 64, 119, 187, 0,
- {
- { 2786, 228, 22, 146, 176, 192, 0 },
- { 3, 102, 68, 146, 196, 236, 2 },
- { 3369, 178, 149, 116, 176, 208, 2 },
- { -3, 231, 68, 146, 120, 240, 0 }
- }
- },
- { /* FM region 101 */
- { 34, 0, 127 }, 240, 144, 239, 0,
- {
- { -2, 49, 69, 34, 236, 208, 2 },
- { -9000, 113, 102, 33, 228, 236, 3 },
- { 2400, 149, 69, 34, 12, 216, 1 },
- { 0, 145, 102, 33, 224, 236, 2 }
- }
- },
- { /* FM region 102 */
- { 50, 0, 127 }, 241, 176, 6, 0,
- {
- { 1200, 247, 49, 64, 252, 204, 0 },
- { 3804, 246, 101, 32, 0, 232, 2 },
- { 1902, 247, 32, 32, 112, 188, 2 },
- { 0, 228, 84, 32, 0, 240, 2 }
- }
- },
- { /* FM region 103 */
- { 37, 0, 127 }, 64, 101, 221, 0,
- {
- { 1, 194, 68, 97, 196, 200, 2 },
- { -10001, 247, 100, 114, 176, 240, 3 },
- { 3370, 213, 33, 70, 52, 200, 2 },
- { -1, 178, 68, 49, 208, 212, 0 }
- }
- },
- { /* FM region 104 */
- { 34, 0, 127 }, 0, 255, 203, 0,
- {
- { -3, 245, 82, 99, 200, 232, 2 },
- { 2787, 244, 84, 96, 0, 236, 2 },
- { 1198, 133, 81, 100, 196, 220, 2 },
- { 1902, 147, 67, 80, 0, 232, 2 }
- }
- },
- { /* FM region 105 */
- { 37, 0, 127 }, 0, 255, 140, 0,
- {
- { 500, 255, 137, 179, 0, 200, 3 },
- { 1902, 248, 90, 160, 0, 244, 2 },
- { 3804, 245, 57, 35, 164, 204, 2 },
- { 0, 245, 38, 51, 196, 208, 2 }
- }
- },
- { /* FM region 106 */
- { 37, 0, 127 }, 0, 255, 72, 0,
- {
- { 1000, 238, 57, 65, 0, 188, 3 },
- { 1902, 247, 103, 112, 0, 244, 2 },
- { 2786, 250, 36, 81, 68, 212, 2 },
- { 0, 249, 50, 49, 172, 204, 2 }
- }
- },
- { /* FM region 107 */
- { 37, 0, 127 }, 16, 119, 72, 0,
- {
- { 1500, 255, 89, 65, 0, 196, 3 },
- { 2790, 246, 39, 112, 0, 240, 0 },
- { 1905, 246, 36, 81, 168, 208, 0 },
- { 0, 249, 114, 49, 172, 212, 0 }
- }
- },
- { /* FM region 108 */
- { 37, 0, 127 }, 0, 255, 237, 0,
- {
- { 1902, 254, 89, 65, 0, 212, 2 },
- { 0, 248, 87, 112, 0, 240, 2 },
- { 3369, 231, 62, 81, 0, 208, 2 },
- { 3, 245, 118, 49, 96, 196, 2 }
- }
- },
- { /* FM region 109 */
- { 34, 0, 127 }, 16, 188, 205, 0,
- {
- { -2, 179, 47, 50, 244, 224, 2 },
- { 1900, 145, 94, 49, 248, 232, 2 },
- { 3, 210, 46, 2, 244, 208, 2 },
- { 2789, 133, 93, 4, 180, 244, 2 }
- }
- },
- { /* FM region 110 */
- { 37, 0, 127 }, 48, 135, 220, 0,
- {
- { 1901, 162, 25, 35, 144, 208, 0 },
- { 0, 113, 105, 65, 220, 240, 0 },
- { 3369, 233, 88, 51, 120, 212, 0 },
- { 0, 229, 24, 84, 200, 208, 0 }
- }
- },
- { /* FM region 111 */
- { 34, 0, 127 }, 112, 32, 190, 0,
- {
- { 0, 53, 79, 66, 152, 212, 2 },
- { 1200, 53, 75, 64, 136, 244, 2 },
- { 500, 149, 60, 66, 16, 208, 2 },
- { 1902, 200, 78, 64, 0, 248, 0 }
- }
- },
- { /* FM region 112 */
- { 37, 0, 127 }, 0, 144, 130, 0,
- {
- { 2514, 255, 68, 53, 0, 204, 2 },
- { 2400, 247, 133, 48, 0, 240, 2 },
- { 4151, 243, 67, 50, 0, 212, 2 },
- { 3369, 243, 66, 56, 0, 204, 2 }
- }
- },
- { /* FM region 113 */
- { 37, 0, 127 }, 0, 255, 0, 0,
- {
- { 514, 253, 79, 51, 0, 196, 3 },
- { 1905, 252, 89, 51, 0, 244, 2 },
- { 4349, 245, 35, 51, 0, 208, 2 },
- { 1205, 247, 34, 51, 0, 208, 2 }
- }
- },
- { /* FM region 114 */
- { 37, 0, 127 }, 0, 255, 0, 0,
- {
- { 514, 221, 69, 35, 0, 204, 3 },
- { 0, 250, 86, 115, 0, 252, 2 },
- { 1884, 244, 116, 51, 0, 200, 2 },
- { 1208, 210, 35, 51, 0, 208, 2 }
- }
- },
- { /* FM region 115 */
- { 37, 0, 127 }, 0, 255, 16, 0,
- {
- { 514, 222, 85, 163, 0, 192, 3 },
- { 0, 254, 108, 163, 0, 252, 2 },
- { 3800, 255, 143, 160, 0, 176, 2 },
- { 1200, 250, 105, 163, 0, 212, 2 }
- }
- },
- { /* FM region 116 */
- { 37, 0, 127 }, 0, 255, 16, 0,
- {
- { 1514, 249, 101, 163, 0, 204, 3 },
- { -1200, 249, 87, 160, 0, 252, 2 },
- { 0, 235, 143, 160, 0, 204, 2 },
- { 1200, 234, 73, 163, 0, 204, 2 }
- }
- },
- { /* FM region 117 */
- { 37, 0, 127 }, 0, 255, 16, 0,
- {
- { 500, 239, 101, 160, 0, 204, 3 },
- { -1195, 248, 104, 160, 0, 252, 2 },
- { 1898, 252, 72, 163, 0, 216, 2 },
- { 1239, 248, 87, 163, 0, 196, 2 }
- }
- },
- { /* FM region 118 */
- { 37, 0, 127 }, 0, 255, 255, 0,
- {
- { 500, 255, 98, 160, 0, 196, 3 },
- { -1, 249, 105, 160, 0, 252, 2 },
- { 1907, 250, 71, 160, 0, 252, 2 },
- { 1182, 249, 87, 161, 0, 192, 2 }
- }
- },
- { /* FM region 119 */
- { 37, 0, 127 }, 0, 0, 100, 0,
- {
- { 600, 32, 15, 0, 252, 224, 6 },
- { 0, 47, 111, 65, 0, 244, 2 },
- { 1826, 16, 47, 0, 252, 216, 2 },
- { 3551, 240, 47, 0, 252, 212, 2 }
- }
- },
- { /* FM region 120 */
- { 52, 0, 127 }, 240, 128, 235, 0,
- {
- { 1228, 161, 47, 17, 196, 200, 3 },
- { 3000, 123, 75, 17, 0, 240, 2 },
- { 7022, 72, 43, 17, 0, 216, 0 },
- { 4000, 150, 79, 17, 48, 196, 3 }
- }
- },
- { /* FM region 121 */
- { 37, 0, 127 }, 224, 16, 86, 0,
- {
- { 275, 251, 6, 0, 36, 200, 2 },
- { 0, 101, 104, 65, 56, 240, 2 },
- { 0, 240, 6, 0, 252, 208, 6 },
- { 1000, 195, 8, 0, 248, 200, 2 }
- }
- },
- { /* FM region 122 */
- { 34, 0, 127 }, 0, 0, 185, 0,
- {
- { 600, 35, 66, 17, 72, 224, 4 },
- { -13000, 81, 67, 17, 228, 244, 2 },
- { 702, 97, 38, 17, 212, 196, 6 },
- { -14000, 81, 65, 17, 224, 244, 3 }
- }
- },
- { /* FM region 123 */
- { 50, 0, 127 }, 240, 112, 237, 0,
- {
- { -6528, 153, 127, 16, 0, 252, 3 },
- { 1200, 105, 109, 16, 0, 216, 2 },
- { -6022, 179, 139, 17, 0, 248, 3 },
- { 2000, 104, 79, 17, 0, 240, 0 }
- }
- },
- { /* FM region 124 */
- { 50, 0, 127 }, 240, 240, 16, 0,
- {
- { 1914, 240, 64, 160, 240, 208, 2 },
- { 1200, 240, 73, 163, 240, 244, 0 },
- { 1900, 240, 64, 160, 240, 148, 2 },
- { 4151, 240, 73, 163, 240, 244, 0 }
- }
- },
- { /* FM region 125 */
- { 34, 0, 127 }, 240, 56, 235, 0,
- {
- { -5522, 97, 32, 17, 196, 240, 3 },
- { 0, 84, 75, 17, 180, 248, 3 },
- { 702, 65, 38, 17, 224, 212, 6 },
- { -4000, 161, 73, 17, 224, 252, 1 }
- }
- },
- { /* FM region 126 */
- { 53, 0, 127 }, 240, 248, 37, 0,
- {
- { 1050, 243, 0, 0, 252, 224, 7 },
- { 2000, 49, 68, 0, 224, 236, 3 },
- { 350, 240, 0, 0, 252, 216, 1 },
- { 700, 240, 0, 0, 252, 212, 3 }
- }
- },
- { /* FM region 127 */
- { 53, 0, 127 }, 240, 248, 37, 0,
- {
- { 1050, 245, 85, 0, 0, 244, 7 },
- { -5000, 247, 71, 0, 0, 252, 3 },
- { 350, 240, 0, 0, 0, 164, 0 },
- { 700, 32, 0, 0, 0, 252, 2 }
- }
- }}; /* end FM Regions */
-
-/*----------------------------------------------------------------------------
- * Programs
- *----------------------------------------------------------------------------
-*/
-const S_PROGRAM eas_programs[] =
-{
- { 7864320, 0 } /* program 0 */
-}; /* end Programs */
-
-/*----------------------------------------------------------------------------
- * Banks
- *----------------------------------------------------------------------------
-*/
-const S_BANK eas_banks[] =
-{
- { /* bank 0 */
- 30976,
- {
- 32768, 32769, 32770, 32771, 32772, 32773, 32774, 32775,
- 32776, 32777, 32778, 32779, 32780, 32781, 32782, 32783,
- 32784, 32785, 32786, 32787, 32788, 32789, 32790, 32791,
- 32792, 32793, 32794, 32795, 32796, 32797, 32798, 32799,
- 32800, 32801, 32802, 32803, 32804, 32805, 32806, 32807,
- 32808, 32809, 32810, 32811, 32812, 32813, 32814, 32815,
- 32816, 32817, 32818, 32819, 32820, 32821, 32822, 32823,
- 32824, 32825, 32826, 32827, 32828, 32829, 32830, 32831,
- 32832, 32833, 32834, 32835, 32836, 32837, 32838, 32839,
- 32840, 32841, 32842, 32843, 32844, 32845, 32846, 32847,
- 32848, 32849, 32850, 32851, 32852, 32853, 32854, 32855,
- 32856, 32857, 32858, 32859, 32860, 32861, 32862, 32863,
- 32864, 32865, 32866, 32867, 32868, 32869, 32870, 32871,
- 32872, 32873, 32874, 32875, 32876, 32877, 32878, 32879,
- 32880, 32881, 32882, 32883, 32884, 32885, 32886, 32887,
- 32888, 32889, 32890, 32891, 32892, 32893, 32894, 32895
- }
- }
-}; /* end Banks */
-
-/*----------------------------------------------------------------------------
- * Samples
- *----------------------------------------------------------------------------
-*/
-
-const EAS_SAMPLE eas_samples[] =
-{
- 13, -24, 28, -32, 33, -37, 39, -61, 119, -76, 120, -70, 99, -122, 89, -113,
- 91, -123, 122, -123, 77, 86, -116, 6, -118, 123, -23, 64, -93, 17, 24, -125,
- 124, -125, 124, -24, -12, 56, 87, -54, 38, -91, 64, -2, -41, 126, -127, 20,
- 8, -48, -62, 127, -128, 88, -43, -18, 86, -100, 44, -32, -26, 71, -13, 6,
- 51, -33, -50, 106, -59, 33, 5, -20, 69, -56, 54, -48, -6, 38, -5, -38,
- 35, -1, 12, -1, 4, 23, -56, 19, -7, 5, -4, 31, -38, 3, -12, -9,
- -25, -7, 24, -32, 17, -21, -22, 24, -20, 6, -18, 0, -15, 5, -16, 15,
- 3, 2, -10, 3, 27, -31, 37, -12, 32, -5, 2, -21, 27, -14, 20, -8,
- 5, 15, -7, -11, 20, -37, 7, -23, 17, -22, 11, -14, 8, -44, 39, -52,
- 26, 3, 14, -10, 51, -45, 29, -19, 19, -3, 41, -21, 46, -23, 10, 16,
- -25, 3, 7, -30, 19, -9, -5, -1, 1, -19, 1, -24, -23, 51, -48, -10,
- 17, -34, -38, 60, -71, 26, -43, 65, -59, 70, -26, 61, -51, 63, -51, 42,
- -25, 58, -36, 31, 10, -14, -9, 8, -18, 8, 4, 8, 7, 31, -52, 39,
- -53, 53, -56, 24, 11, 1, -20, -8, -32, -18, -10, -25, 4, 1, 37, -37,
- 42, -42, 53, -57, 52, -18, 30, 11, 20, -52, 55, -61, 56, -50, 24, -26,
- 38, -42, 36, -1, -43, 58, -46, 6, 18, -35, 31, -36, 28, -55, 55, -98,
- 52, -41, 26, -24, 48, -31, 48, -26, 30, 19, -17, 23, -8, 13, 15, 19,
- -7, -23, 41, -36, 20, -39, 65, -64, 66, -38, -9, 7, -14, -10, -3, 6,
- 15, -19, -40, 53, -67, -11, -12, -25, 23, -11, -12, 46, -48, 39, -20, 20,
- -14, 31, -54, 71, -25, 2, -8, -5, -9, 1, 7, 27, 17, -14, 43, -31,
- 27, 11, -33, 20, -2, -33, 45, -38, 17, -9, -11, -17, -22, -19, 20, -25,
- 4, 29, -35, 14, -17, 1, -7, 19, 2, 16, 32, -3, -17, 4, 0, -9,
- 17, 5, -8, 52, -32, 40, -39, -5, -18, 14, -21, 31, 10, -17, 8, -34,
- -7, 1, -44, 7, 10, -8, -6, -18, -25, -1, -19, 16, -29, 62, 6, 9,
- 21, 0, -14, 4, 5, 20, 13, 27, -1, 18, -5, 21, -31, 11, 2, -9,
- -4, 21, -27, 8, -21, -28, -19, 14, -12, 5, -20, 20, -36, 4, -18, -27,
- -4, -4, 15, 4, 48, -7, -11, 20, -6, 7, 20, 1, 20, 0, 35, -35,
- 28, -37, 7, -43, 21, -22, 23, -18, 12, -22, -13, -20, -11, 7, 23, -10,
- 19, -18, 17, -41, 4, -16, -8, 21, 11, -4, 10, 30, -24, 32, -15, 15,
- -13, 28, -5, 38, -10, 0, -22, -13, -12, 24, -18, 30, -7, 4, -16, 27,
- -28, -3, -1, 18, -14, 31, -24, -3, -13, -19, -36, -2, -31, 9, -2, -12,
- 17, 12, -50, 46, -49, 43, -15, 13, 22, 15, -25, 10, -8, -6, 14, -2,
- 24, 15, 9, 17, -13, 5, 14, -15, 7, 20, 4, 4, 18, -16, 3, -47,
- 31, -46, 19, -24, 5, -19, -1, -42, 14, -44, 18, -7, -1, 15, 9, -35,
- 32, -44, 39, -46, 23, -16, 36, -25, 45, -34, 32, -8, 10, 5, 28, 0,
- 12, 11, 3, 20, -23, 6, -8, 16, 7, 17, -19, 32, -44, 3, -8, -21,
- -8, -5, 2, -29, 2, -3, -19, -14, 3, 7, -23, 10, 1, 3, 8, 13,
- -44, 20, 21, -16, 23, 3, 5, 10, -11, 32, -11, 13, -7, 30, 4, 16,
- -7, -6, -7, 14, -40, 4, -16, -26, 3, -1, 0, -6, 5, -50, 37, -27,
- 18, -16, -14, 6, -1, -4, -15, 8, -12, 14, 9, -22, 42, -10, 23, -11,
- 36, -15, 13, 30, 1, 47, -20, 33, -14, -12, 1, -20, -9, -9, -11, -13,
- 7, -37, 25, -47, 14, -13, 4, -12, 9, -32, 18, -48, -1, -35, -1, -7,
- 35, -20, 53, -4, 34, -7, 13, 19, 9, 30, 6, 45, -22, 23, -18, -6,
- -1, 3, -30, 14, -15, 9, -39, 10, -33, -13, -24, 10, 14, 14, -10, 2,
- -34, -4, -20, -21, -14, 40, -10, 17, -14, 28, -17, 37, -26, 69, -15, 38,
- 2, 21, -25, 37, -61, 13, -9, 5, -17, 18, -41, 22, -57, -1, -9, -13,
- 24, -10, 38, -5, 8, -16, -2, 1, 12, -25, -2, -13, 2, 2, -16, -19,
- 32, -30, 22, 20, -4, 12, 11, -17, 19, -17, -3, 20, -33, 65, -27, 32,
- -14, 8, -8, 13, -19, 9, -2, 7, 33, -40, 18, -18, -18, 6, -23, -11,
- -11, -28, 4, -11, -15, -14, -8, -5, 34, -6, 19, 1, -3, 9, -1, 5,
- 5, 14, -11, 40, -3, 18, -20, 16, -7, 2, -5, 9, -16, 9, -17, 0,
- -17, 4, -17, -3, 3, 8, -14, -19, 12, -21, -7, 1, -2, -8, 16, 3,
- -6, 35, -23, 33, -13, 11, 12, 3, -7, 26, -11, 19, -18, 23, -22, 39,
- -49, 39, -50, 11, -38, 26, -29, 10, -6, -22, 15, -8, 15, -37, 36, -43,
- 39, -43, 18, -26, 1, 11, 4, -2, 9, 7, 2, 7, 19, 1, 1, -4,
- 16, -5, 16, -9, -3, 4, -4, -1, -17, 0, 11, 16, -27, 12, -15, 15,
- -3, 0, 10, -3, -5, 12, -13, -7, -13, -31, -1, -3, -17, 15, -31, 25,
- -10, 15, -1, 2, 4, 10, 7, 32, -13, 7, -22, 2, -10, 16, 1, -15,
- 19, -24, 16, -18, -12, 18, -9, 9, 24, -8, 8, 11, 0, -31, 17, -55,
- 21, -43, 40, -40, 29, -54, 44, -34, 22, 11, 16, 7, 19, 21, -6, 2,
- -7, -16, 22, 0, -1, -4, 5, -8, 26, -42, 4, -6, -21, 35, -16, 8,
- 0, -22, -13, 11, -31, 7, -28, 4, 17, -12, -18, -2, -23, 23, -1, 19,
- 34, 7, 7, 35, -19, 11, -8, -17, 8, 4, 16, -16, -13, 9, -15, -5,
- -1, -6, 7, 3, 11, 1, -7, -24, 21, -31, 36, -3, -10, 8, 2, -17,
- 12, -24, 6, -3, 9, 15, 3, 13, -8, -13, -3, 6, -19, 14, -33, 16,
- -17, -5, -31, 3, -29, 24, -7, -6, 35, -20, -5, 34, -20, 25, -3, 10,
- 25, 8, 14, -13, 0, 1, 17, -33, 51, -38, 45, -32, 39, -3, -2, -24,
- 3, -18, 14, -4, -44, 2, -25, -15, -2, -23, 3, -2, -2, 20, -14, 8,
- -10, -4, 21, 11, -13, 32, -4, 8, 19, -16, -2, -2, -2, 14, -2, -1,
- 27, -26, 20, 11, -13, 10, -3, -7, 12, -13, -3, -30, -16, 10, -26, -3,
- -10, -2, -9, 15, -17, 1, -2, -7, 14, -8, 12, -3, -1, 2, 47, -26,
- 22, -19, 16, 2, 13, -3, 21, -10, 22, -32, 43, -24, 16, 0, 5, -2,
- 12, -44, -12, 1, -26, 1, -36, 5, 2, 9, -17, 20, -37, 14, -9, -5,
- 6, -3, -13, 23, -19, 25, -33, 6, 17, 10, 19, 15, -4, 12, 5, -9,
- 33, -20, 26, -9, 11, -2, 11, -21, -7, -13, -4, -8, -12, 0, -10, -9,
- 8, -33, 9, -26, 8, 6, -8, 12, 7, -8, 0, 7, -16, 25, -8, 27,
- 12, 0, 9, -9, 4, -17, 14, -16, 11, -8, 18, -2, 4, 2, -20, -18,
- 22, -16, -5, 3, -24, 13, -10, -12, -10, 2, -16, 33, -15, 21, -15, -4,
- -19, 29, -22, 18, 2, 20, 12, 18, -22, -7, -16, 7, -19, 14, 1, -17,
- 33, -22, 38, -8, 3, -3, 21, -17, 51, -43, 15, -22, -23, -6, -12, -14,
- 14, 9, 6, 4, -31, 3, -16, -14, 22, -22, 5, 13, -25, 17, -2, -18,
- 7, 1, 5, 36, -16, 23, 4, -15, 29, -20, 10, 1, 24, 17, 16, -4,
- -16, -37, -11, 1, -33, 27, -36, 17, -22, 2, -33, 16, -29, 32, -7, 24,
- -12, 14, -12, 22, -16, 15, -20, 19, 9, 14, 12, -1, -24, 13, -6, -1,
- 32, -19, 24, 12, -26, 4, -31, -38, 18, -16, -13, 3, -14, -1, 11, -15,
- 15, 0, -2, 30, -6, 35, -23, 10, -35, 5, -14, 17, -21, 20, 4, 7,
- 8, -5, -15, 20, -25, 26, 6, -3, 3, 5, -24, 26, -35, 4, 0, -6,
- 13, -23, 8, -25, 1, -2, 9, 3, 17, 4, 0, 13, -15, 3, -21, -16,
- 4, -5, -10, 11, -2, 7, 23, -22, 25, -19, 18, 25, -9, 14, -21, -7,
- 11, -24, 22, -12, -7, 6, 9, -33, 11, -20, 2, -9, 2, 3, -13, 12,
- -15, 23, -21, 16, -16, -2, 8, 13, -12, 18, -10, 16, -12, 20, -18, 18,
- -1, 21, -21, 20, -30, -6, 10, -2, 13, -6, -15, 6, 2, -1, 1, -19,
- 9, -15, -3, -11, 0, -5, 1, 5, 1, -4, -8, 1, -16, 23, 0, -23,
- 2, 8, -6, 38, -4, 2, 13, -17, 31, -4, -8, 22, -14, 0, 12, -22,
- 7, -7, 11, 4, -4, -12, -9, -22, 2, -17, -17, -11, 7, -17, 19, -24,
- 9, -8, -6, 29, -4, 10, 4, 4, 23, -1, 9, -6, -12, 23, 16, -6,
- 33, -29, 12, -7, -10, 17, -4, -18, 21, 0, -14, -2, -20, -21, 10, -28,
- 5, -18, -4, 0, -11, 1, 5, -17, 3, 9, 20, 6, 1, -7, 2, -7,
- 3, 9, -22, 29, 6, -1, 25, -10, 6, -1, 4, 12, 18, -13, 28, -11,
- 6, -15, -14, -22, -7, 5, -14, 1, -16, -12, -5, 5, -9, 4, -1, -14,
- 21, -10, -5, 0, -17, -7, 2, -10, 6, 11, 1, 37, -17, 6, 21, -24,
- 41, 2, 23, 0, 10, -18, 16, -26, 14, -21, -19, 18, -9, -14, -1, -9,
- -14, -3, -7, -10, 7, -7, 19, -11, 15, -25, -3, -6, 2, 8, -10, 4,
- 12, -3, 11, -2, -2, 5, 31, -9, 39, -21, 14, -23, 18, -16, -1, -3,
- -6, 0, 22, -9, -5, -17, -4, -12, 2, -3, -7, 10, -10, 7, -20, -19,
- -10, 0, -14, 32, -15, -18, 13, -9, 2, 17, -14, 6, 36, -9, 28, 1,
- 0, 17, -10, 5, 17, -8, 12, -2, 3, 2, -22, -6, -14, 6, 8, -11,
- -14, 2, -23, 25, -35, 3, -18, 1, -14, 22, -1, -12, -7, -9, 13, -4,
- 12, 4, -3, 18, 0, 1, 8, -14, 14, -2, 1, 17, -3, -14, 35, -17,
- 19, -14, -6, 1, -9, 18, -17, -4, -13, -2, -14, 10, -10, -6, 0, 3,
- 5, -12, -13, -3, -6, -6, 11, -13, -7, 13, -2, 6, 13, -7, 11, -5,
- 23, 1, 29, -17, 23, -10, 18, -16, 12, -20, 10, 7, -9, -5, -21, -9,
- 5, -13, -2, 0, -15, -11, 3, 0, -18, 5, -25, -2, 3, -2, -3, 4,
- 8, 14, -7, 15, 4, 8, 19, 9, 11, 7, -3, 14, -11, 1, 15, -35,
- 3, 3, -10, -16, 0, -15, 2, 3, -12, 27, -23, 32, -15, 10, -14, 3,
- -27, 10, -15, 12, -24, 7, 2, 9, -2, -2, -1, 3, 1, 1, 8, -4,
- 0, 6, -6, 1, 1, -1, 8, -11, 31, -27, 13, 4, -3, 5, -1, 0,
- 2, 9, 0, 12, -31, 4, -27, 1, -25, 20, -21, -14, 12, -14, 0, -5,
- -23, 18, -1, 15, 19, -5, 20, -8, 14, -7, 16, 3, 0, 8, 10, 0,
- -8, -10, 3, -8, 9, -12, 4, 15, -6, 2, -12, -29, -3, -16, -11, 35,
- -18, -1, -28, 7, -12, 0, 7, -5, 22, 10, 10, -4, 6, -13, 21, -23,
- 20, 8, -13, 11, 15, -6, -6, -22, -1, 3, 14, 7, 11, -27, 12, -17,
- -12, 8, -15, 3, -8, 12, -12, 5, -30, 12, -18, 9, -2, 3, 4, 15,
- 1, 5, -9, 0, -8, 24, -2, 21, 5, -4, -4, 14, -15, 0, -1, 3,
- 17, -5, 13, -19, -10, -4, -6, -4, -7, 18, -27, 8, 1, -12, -21, -13,
- 1, -9, 11, 1, -3, -1, 22, -21, 9, 6, -3, 20, -2, 17, 7, -12,
- 1, 4, 4, -9, 9, -20, 24, 7, -9, -3, -7, -6, 10, 7, 3, 9,
- -2, -3, -4, 1, -19, -8, -16, 0, -12, 0, -25, 4, -22, 10, -9, 0,
- -3, 15, -1, 8, 11, -15, 10, 13, 1, 22, -5, 15, 1, 24, 6, 0,
- -6, 5, 5, 10, 8, -1, -11, -14, 3, -31, 2, -22, -4, -8, -15, -2,
- -31, -12, 6, -7, 5, 2, 3, -4, 19, 3, 4, 7, 7, -8, 31, -6,
- 26, 1, -2, 2, -3, -10, -4, -4, 9, 3, 12, -16, 16, -9, -1, 5,
- 4, -7, 13, -17, 0, -11, -13, -22, 1, -9, 4, -7, 7, -10, 5, -1,
- -6, -3, -21, 7, -10, 18, -3, 1, -7, -11, 11, -8, 12, 20, 3, 13,
- 16, -1, 3, 13, -3, 23, 16, -3, 15, -14, 12, -6, -8, -28, 0, -33,
- 4, -11, -12, -13, -21, -17, -16, -5, -12, 16, -7, 15, -6, -5, 3, -9,
- 21, 17, 13, 14, 11, 21, -12, 31, -18, 7, 12, 8, 9, 7, 1, -3,
- -7, -14, 17, -35, -10, -2, -18, -8, -10, -20, -22, 2, -10, -3, 1, -1,
- 4, -5, 11, -20, 11, -6, 27, 7, 18, 8, -1, 2, 3, 11, -9, 5,
- 5, -7, 29, -6, 20, -21, 23, -15, 19, -19, 2, -22, 11, -26, -7, -10,
- -30, -1, -3, -6, 15, -22, 16, -7, -9, -2, -7, -5, 11, 17, -13, 2,
- 8, -5, 6, 27, -6, 12, -6, 4, 15, 3, 14, -3, -12, 11, -2, 6,
- 5, 4, -6, -12, 0, -32, 2, -22, 22, -12, -5, -7, -11, -7, 6, -1,
- -3, -3, -16, 2, -1, 0, 0, -7, -2, 1, 12, -4, 5, 20, 1, 16,
- -2, 14, -1, 19, 8, 29, -8, 7, -14, -2, 3, -13, 8, -40, 22, -18,
- 2, -14, -8, -11, -8, 12, -21, -1, -10, -12, -6, -4, -14, 6, -19, 7,
- 14, 1, 11, 11, -11, 25, 1, 14, -5, 31, 0, 22, 4, 1, 3, 6,
- -3, 4, -2, -20, -7, -26, 1, -12, -7, -10, 2, -1, -5, -7, -8, -10,
- 6, -7, -6, 10, -17, 6, 3, 15, -8, 15, -7, 12, 1, 9, -4, -2,
- 10, 9, -1, 10, -4, 9, -8, 17, 0, -13, -7, -2, -11, 3, -2, -15,
- -4, -11, -5, -9, 1, 8, -10, 8, -8, -6, -18, 21, -19, 26, -19, -1,
- -11, 10, 4, 12, -10, 16, -10, 17, 8, 13, -1, 17, 1, 5, -1, 11,
- -8, 9, 16, -17, 3, -26, -17, -14, 6, -17, 4, -20, 0, -1, -6, -4,
- 2, -15, 13, -3, -1, 0, -2, -8, 11, 7, -3, -8, 5, 14, -1, 28,
- -19, 13, -4, 8, 1, 11, 7, 6, -8, -2, -13, -10, -22, 6, 11, -1,
- -1, -5, -13, 18, 3, -10, 9, -17, -8, 9, -9, 1, -17, -4, -16, 18,
- -6, 15, -10, 17, 5, 0, -5, 0, -11, 12, 15, 4, 8, 5, -4, 0,
- -2, 3, -17, -2, -1, 11, -6, -7, 2, -33, 23, -6, -1, -2, -2, -1,
- -8, 3, -29, -2, -34, 16, -3, 16, 1, 10, -12, 23, 0, -3, 16, 12,
- 19, 23, -1, 8, -26, 16, -32, 26, -13, 2, -11, 5, -1, -15, -9, -16,
- 7, -6, 14, -15, 5, -10, -7, -9, -9, 6, -17, 13, 18, -5, -3, -4,
- -4, -18, 28, -6, 13, 17, 24, -2, 9, -14, 1, -11, 7, 17, 1, -15,
- 10, -23, -4, -12, 5, -20, 17, -10, 6, 0, -9, 4, -8, -15, 6, -16,
- 7, 9, 3, 6, -12, -17, 0, 4, 13, 22, -4, 10, -8, 7, -12, 5,
- 5, 1, 11, 2, 10, -3, -2, 3, -10, -5, -7, -4, -18, 17, -2, -14,
- -16, -7, -10, -3, 6, -1, 14, -11, 15, -18, 2, -6, 0, -1, 0, 20,
- -17, 1, 6, 2, 6, 12, -3, 7, 25, -5, 17, -14, 0, -6, 0, -2,
- -5, -1, -10, 8, 2, -9, -19, -7, -17, 5, 3, -7, 4, -15, -5, 9,
- -12, -1, -5, 3, -5, 26, -2, 3, -4, 5, 3, 7, 10, 5, 6, 6,
- 26, -17, 0, -1, 3, -3, 10, -7, -7, -9, 11, -18, 0, -16, -6, -5,
- 3, 7, -14, -14, 0, -21, 14, -8, -1, -12, 2, 1, 2, -3, -1, -3,
- 18, 5, 5, 9, 12, 7, 18, 8, 5, -25, 16, -15, 16, -7, 9, -22,
- 1, 14, -13, -5, 2, -6, -8, 13, -17, 6, -16, 1, -5, -14, -6, -6,
- -15, -2, 9, -9, -18, 15, -19, 12, 7, 4, 8, 14, 15, 6, 10, -3,
- 9, -7, 23, -17, 21, -20, 7, 0, -9, 8, -10, 1, 4, 2, 3, -9,
- -9, -15, -6, -21, -16, -6, 0, -11, 19, -8, -9, 5, -6, 0, 5, 14,
- 7, 1, 12, 8, 7, -5, 12, 8, -4, 19, 4, -7, 2, 3, -12, -8,
- -1, 0, 5, 7, -5, -8, -22, -8, -21, -2, -9, 10, -20, 13, -6, 8,
- -17, -9, -6, 2, 5, 8, 6, -3, 10, -9, -2, 15, -6, 20, 7, 11,
- 10, -3, -4, -8, 25, -25, 18, -12, 17, -6, 20, -22, -1, -17, -10, 5,
- -10, 9, -13, -9, -6, 10, -25, -5, -2, -5, 13, 2, -5, -8, -10, 11,
- -27, 10, -4, 11, 0, 33, -4, 10, -14, 1, 12, -2, 27, -8, 6, 11,
- 9, -12, -4, -10, -13, 12, 5, 1, -10, -14, -15, -8, -7, -9, 3, -5,
- 10, 3, -11, -12, -13, -3, -3, 3, 2, 9, 17, -6, 25, -3, -3, -8,
- 19, 3, 30, -10, 12, -22, 7, -5, -10, -3, 21, -8, 12, 6, -5, -13,
- -13, -9, -9, -1, -23, 13, -17, 15, -22, -11, -18, 8, -14, 20, 1, 4,
- -5, 3, 3, 5, 11, 1, 2, 27, 1, 10, -7, -8, -2, -2, 7, -1,
- 17, -5, 24, -7, 5, -10, -20, -6, 5, -4, -5, -1, -18, -5, -14, -1,
- -20, 1, 7, -7, 12, -4, -2, -4, 2, 8, 0, 7, 1, 6, -2, 18,
- -5, -7, 4, 3, -2, 13, 4, 0, 2, -3, 2, -10, -6, 1, -6, 6,
- -7, -3, -21, -2, -12, 5, -1, -9, 7, -3, 13, 5, 5, -8, 0, -8,
- 19, -5, 13, 13, -7, 3, 0, -10, 0, -8, 20, -8, 13, -20, -5, -7,
- 3, 5, -7, 2, -5, -4, -14, 11, -23, -13, 2, -1, 12, 13, 5, -6,
- 23, -9, 9, -6, -9, 18, -13, 16, -3, -7, -17, 3, -13, 12, -9, 4,
- 0, 0, 13, -18, -1, 3, -13, 20, -5, 1, -20, 15, -23, 18, -4, -8,
- 5, -7, 16, 4, 6, -3, 7, -21, 19, -17, -7, 9, 5, 3, -5, -3,
- -16, -9, 25, -9, 12, -5, 10, -5, 9, -4, -6, -3, 4, 10, -2, 11,
- -12, -2, -14, 8, -23, -5, 0, -8, 9, -2, -11, -3, -9, 9, 2, 2,
- 4, -5, 7, 11, -16, 0, -6, 7, 6, 25, 5, 6, -4, 3, 4, 3,
- 2, -8, -3, 5, -1, -11, -4, -9, -3, -15, 10, -12, -5, 11, -4, -7,
- 6, -29, -5, 6, 11, 3, 9, -18, 13, -14, 19, -1, -2, 4, 5, 12,
- 1, 5, -8, 3, 1, 20, -6, 2, 3, -16, 10, -10, -18, -11, -7, -7,
- 9, -4, -8, 9, -15, 13, -13, -3, -7, 3, 8, 11, -6, -16, 1, -8,
- 20, 4, 15, -5, -3, 11, -5, 6, 0, -5, 10, 13, 0, -6, -11, 0,
- 11, -11, 10, -7, -8, 1, 16, -9, 2, -22, -9, 0, 4, 5, -12, -22,
- 2, -8, -8, 14, -16, 0, 13, 0, 9, -7, 2, -1, 7, 8, -3, -3,
- 2, 15, 5, 10, -7, 12, -4, 22, -4, -3, -12, -2, -15, 8, -2, -22,
- 7, -10, 5, 12, -20, -9, -11, -2, -12, 2, -9, 5, -3, 11, 7, -9,
- 4, -4, 24, -7, 21, -15, -3, 2, 14, -1, 5, 18, -12, 13, 3, 5,
- -10, -11, 0, -8, -2, -4, 2, -15, 9, -10, -16, -9, -7, 0, -1, 3,
- -8, -10, 5, -8, 4, -3, 8, -2, 20, 1, 6, -4, -9, 4, 14, 7,
- -1, 3, -5, 18, -7, 20, -6, -10, 8, 1, -2, 3, -4, -5, -3, -6,
- 0, -16, -7, 12, 0, -17, 4, -31, -7, 1, 1, -4, 8, -11, 6, -1,
- 11, -5, -7, -4, 2, 4, 15, -3, 21, -5, 20, 3, -12, 21, -1, 10,
- 5, 6, -20, -1, -18, 2, 3, -4, -5, -1, 6, -2, -11, -17, -15, -13,
- 0, 6, -18, 7, -18, 7, -7, 6, 7, -10, 18, 16, 2, -1, 3, -11,
- 6, 14, 1, 15, -2, 29, -8, 17, -14, 2, -19, 12, 8, -6, -1, -23,
- 6, -11, 7, -19, -18, 0, 1, -8, -8, -4, -20, 8, -8, 4, 10, -12,
- 13, 0, 18, -10, -3, -4, 6, 4, 17, 7, -2, 18, -9, 14, -10, -4,
- -11, 4, 3, 23, -17, -6, -2, -7, -7, 9, -10, 1, 2, -4, -14, -7,
- -6, -8, -4, 7, 2, -3, 3, 0, 13, -10, -4, -9, -6, 18, 11, -4,
- 16, -8, -4, 1, -1, 7, 3, 3, 3, 10, -15, -2, -9, 9, 0, 2,
- 2, -9, 12, -7, 0, -23, -7, -19, 2, -1, 0, 4, -15, 7, 3, -3,
- 0, 9, -12, 19, 4, 8, -13, -6, 5, -1, 14, 10, 9, 13, -3, 16,
- -18, 13, -18, 7, -10, 13, -6, -11, -3, 7, -23, -6, -11, -21, 9, -1,
- 4, -3, -16, 0, -12, 7, 14, -5, 15, 0, 6, -5, -3, -9, 9, 4,
- 10, 4, -2, -7, 10, -1, 10, -6, -14, 15, -4, 13, -4, -4, -14, 5,
- -2, 4, -9, 3, -14, 2, 3, -10, -1, -9, 0, 3, -6, 12, -16, 0,
- 4, 10, -25, 6, -5, 2, 8, 3, -2, -4, 15, 4, 7, 2, -1, -6,
- 10, 11, 2, -2, -14, 6, -3, 0, -3, -9, -10, 1, -1, -15, 9, -29,
- 9, -10, 7, -3, -3, -10, -2, 14, 4, -6, 0, 1, 12, 4, 18, -15,
- 19, 1, 15, 1, 1, 3, -10, 8, -1, 7, -30, 8, -19, -2, -5, -9,
- -10, 0, -1, 6, -4, -12, 1, -18, 10, -1, -12, 2, 7, 12, 11, 0,
- -4, -1, 6, 10, 17, -8, 1, -12, 5, -2, 1, -7, -1, 4, 3, -3,
- -1, -18, 8, -9, 0, -2, 8, -12, 12, 7, -5, -2, -16, -7, 9, -5,
- 11, -9, -4, 3, 1, -9, -1, -2, -6, 7, 12, 0, -8, 9, -10, 3,
- 0, 2, -3, 11, 14, 4, 3, -12, 3, -3, 2, 12, -4, -2, -2, 9,
- -21, -5, -28, -6, -10, 6, 7, -6, -3, -24, 7, -11, 10, 0, 8, 13,
- 10, 6, -7, -2, -5, 7, -1, 9, 18, -2, 12, -4, 7, -26, 13, -6,
- 19, 6, 6, -5, -16, -6, -8, -18, -2, 1, -11, 3, 4, -16, -8, -10,
- -3, 2, -3, 5, 5, 0, 11, 0, -14, 0, 1, 14, 11, 13, 0, -2,
- 5, -1, -4, -2, -4, 5, 21, 3, 14, -5, -22, 5, -11, -3, -6, -3,
- -11, 0, -5, -13, -10, -18, 3, 9, -10, 2, 3, -11, 11, -11, 5, -19,
- 23, -1, 20, 18, 4, -3, -6, 9, 4, -3, 8, 4, 6, 2, 5, -14,
- -6, -3, 2, -6, -4, -3, -11, 0, -5, 0, -21, -2, -10, 11, 5, -4,
- -5, -5, -8, 10, -10, 4, -1, 6, 12, 9, 2, 8, -20, 8, -2, 11,
- -11, 1, -4, 5, 6, -6, 6, -14, 14, 4, -2, 12, -3, -10, 8, -5,
- -15, -9, -1, 5, 8, -3, 0, -23, -9, -11, 4, -12, 3, -4, 4, 1,
- 15, -12, 3, 13, 2, 5, 8, -8, 7, 11, -3, 17, -11, 5, 3, 19,
- 13, 3, -11, -11, -2, -9, -7, -4, -24, -1, -17, -3, -17, 0, -15, 2,
- -1, -5, -4, 3, 2, 2, 11, -4, 3, -6, 11, 8, 3, 6, 3, 7,
- 7, 6, -6, 2, 0, 14, 14, 3, 8, -6, 4, -3, 6, -13, -2, -9,
- -4, 5, -13, -5, -21, -1, -6, -1, -5, -14, 8, -7, 5, -7, -17, -11,
- 7, 3, 20, 7, 1, -3, 4, 5, 14, -3, 5, 3, 10, 8, 6, -6,
- -2, 6, 3, 7, -6, -3, -3, -6, -1, -27, -11, -17, 0, 11, 7, 1,
- -7, -9, -13, 5, -11, 0, -10, 15, 2, 5, -2, -5, 1, 6, 6, -6,
- -5, 6, 2, 5, 3, 10, -16, 11, 8, 18, 3, 13, -11, 7, 5, -7,
- -6, -20, 15, -1, 10, -1, -13, -17, -11, -3, -13, -4, -14, -3, -2, -6,
- 6, -28, 9, -8, 10, 0, 12, -2, 10, 9, 1, 3, -6, 5, 17, 24,
- 18, 3, 4, -9, -4, 2, -8, -4, -2, -11, 1, -8, -12, -9, -10, 5,
- 0, -7, -9, 7, -18, 6, -10, -12, -1, -1, 13, 1, 18, 2, -3, 4,
- 3, 3, -3, 3, 10, 9, 7, 5, -8, -7, 0, 3, -7, 7, -2, -2,
- 5, -10, 2, -5, -3, -1, 4, 1, -2, -10, 4, -9, -5, -12, -18, 3,
- 6, -3, 3, -15, -1, -13, 6, -2, 8, 0, 8, 16, -2, 17, -4, 8,
- 3, 23, -1, 11, -8, 10, -4, -5, -3, -13, -2, -1, -2, 2, -9, -13,
- -13, -2, -11, -2, -20, -5, 0, 3, 2, -1, -10, 1, 8, 3, 9, 6,
- 4, -3, 13, 3, 4, 11, 2, 11, 8, -2, -1, -2, -2, -2, -1, -21,
- -1, -14, 8, 6, -8, -10, 2, -16, 4, -3, -1, -10, 7, -1, 4, -4,
- -12, 3, -2, 13, 2, -3, -9, -2, 6, -7, 8, -8, -5, 12, 7, 8,
- -3, 6, -1, 16, 0, 7, -8, 3, -7, -1, 0, -6, -4, -8, 6, -1,
- 4, -19, 2, -3, -8, -3, -12, 4, -6, 2, -7, 1, -13, 2, 9, -1,
- 17, -19, 3, -3, 23, 9, 6, 3, 6, 6, -5, 11, -11, 1, 0, -5,
- 6, -6, -4, -5, -7, 3, -4, -14, -9, -7, -1, 5, -11, 4, -19, 14,
- -4, 3, 4, 2, 0, 9, -2, -3, 2, -2, 10, 15, -3, 14, -6, -4,
- 6, 1, -8, 11, -9, 4, 3, -9, 2, 2, -2, 2, -2, -9, -2, -2,
- 1, -6, -6, -22, -16, -10, 12, 0, 5, -8, -2, -4, -2, 5, -1, 7,
- 7, 9, 1, 7, 6, -1, 10, 11, 5, -3, 8, 1, -1, 8, -15, -6,
- -10, 12, 0, 2, -5, -9, -12, -7, -4, -14, -4, 0, -1, 5, -7, -8,
- -12, 0, 2, 16, -3, 11, -4, 16, 11, 2, -3, 2, 8, -1, 7, -13,
- 4, -3, -1, 3, -10, -2, -11, 3, 2, 3, -7, -10, -5, -10, 12, -8,
- 5, -7, 15, 1, -10, 7, -16, 1, 3, 4, -5, 7, -7, 4, -2, -1,
- -8, 0, -2, 17, 10, -2, 6, -5, 3, 10, -7, 2, -3, 4, 5, 5,
- -3, -8, -8, -1, 1, 7, -5, -11, -2, -10, -4, -15, -7, -10, -2, 2,
- -4, -10, -8, 0, 2, 6, 3, 2, 3, 10, 14, 8, 7, 3, 5, -5,
- 20, -6, -1, -2, 0, 1, -2, -2, -8, 3, -3, 10, -14, 3, -3, -2,
- 0, -5, 0, -15, 4, -2, 0, 4, -7, 3, -8, 7, -14, -2, -6, 4,
- 2, 3, -10, -2, 5, -3, 12, -2, -5, -9, 1, 4, 1, 11, -12, 15,
- 5, 20, 10, -5, 1, 5, 3, -13, 6, -16, 5, 1, -5, -8, -3, -14,
- -6, -2, -5, -8, -17, -9, 3, -6, -2, -3, -3, 1, 14, 2, 4, 5,
- 3, 8, 7, 12, 0, 11, 4, 16, 2, -3, -9, -1, 1, -1, -3, -6,
- -14, 4, -6, 2, -14, -9, -11, -1, 0, 0, -5, -6, -10, 5, -5, 2,
- -3, 2, 2, 17, -2, -1, -3, 3, 11, 1, 10, 2, 7, 6, 5, -5,
- -3, -3, -2, 7, 2, 1, -18, -5, -2, -3, -5, 0, -2, 0, 8, -9,
- -10, -15, -7, -2, -1, 6, -8, 16, -10, 13, -4, 2, -4, 4, 7, 9,
- 6, -5, -2, 8, -1, 11, -6, -1, 5, 8, 0, 9, -20, 0, -9, 4,
- -3, 1, -4, -11, 2, -6, 0, -12, 0, 1, 5, -2, 1, -7, -4, 3,
- -1, -10, 3, -3, 7, 4, 8, -9, -6, -10, 0, 0, 2, -4, 6, 9,
- 10, 2, 0, -1, 2, 14, 3, 7, -7, 2, -2, -2, -6, -9, 2, -3,
- 6, -3, -7, -9, -10, -2, 2, -1, -11, 2, 1, 7, -4, -7, -19, 3,
- -1, 6, 6, 6, 6, 0, 6, 7, 3, -1, 3, 8, 3, 4, -10, -5,
- -7, 5, -4, -14, 2, -8, 5, -2, 2, -16, -4, -11, 2, 4, -1, 2,
- -1, 0, 5, 4, -12, 3, 9, 7, 13, -3, -7, 2, 6, -1, 7, -1,
- -1, 5, -5, 7, -11, -9, -13, 2, 5, 2, -2, -7, 5, 4, -4, -2,
- -15, -4, 3, 0, 0, -5, 2, -7, -1, 9, -2, -1, 5, 1, 1, -4,
- -5, -4, 6, 8, 7, -5, 4, -7, 4, 0, 1, -6, -5, -2, 5, -1,
- 0, 1, 1, 3, 9, -4, -2, -4, -9, -1, 4, -17, 1, -13, 11, -1,
- 6, -9, -1, 5, 1, 8, -3, 4, -5, 1, 7, -5, 1, -3, 5, 3,
- 4, -7, -11, -7, 1, 5, -13, 11, -11, 1, 3, 6, -9, 6, -5, -7,
- 4, -13, 5, -7, 10, 5, 6, -15, -1, 6, 4, 18, -7, -7, -3, -4,
- 2, -5, 3, -4, 9, -4, 3, 3, -3, -10, 0, -1, 2, 5, -3, 7,
- 3, 2, -6, -11, -2, -1, 4, -5, 4, -5, 0, -5, 5, -5, -4, 2,
- 4, 2, 5, -8, -13, -3, 0, -1, -2, 4, 6, 9, 1, 3, -7, -1,
- 1, 12, 1, 1, -1, -5, -1, 2, -8, -9, -7, -2, 3, 10, -6, -7,
- -12, -7, -4, -5, 6, 0, 10, 5, 7, -4, -2, -8, 10, 5, 9, 4,
- -1, -1, -1, -1, -1, -2, -3, 3, 9, -2, 9, -14, -13, -8, -10, 1,
- 1, 3, 3, 1, -3, -12, -5, -7, 1, 6, 6, -2, -7, -3, -3, 2,
- 2, 4, -9, 14, 8, 11, -3, 5, -11, 1, -1, 5, 3, 8, 2, 8,
- -2, -6, -13, -10, 0, 4, 3, 4, -3, -9, 1, -5, -5, -6, 1, -2,
- 2, -10, -6, -15, 1, -5, 4, -1, 2, 2, 4, 10, 4, 2, -13, 0,
- 4, 8, 17, 2, 5, 4, 2, -6, 5, -5, 0, 8, -2, -1, -5, -4,
- -5, -1, -5, -4, -5, 0, 0, 1, -9, -15, -3, -12, 1, -1, -7, 10,
- 2, 5, -1, 2, -6, 2, 2, 10, 10, -1, 2, -2, 4, 5, 0, -6,
- 12, 5, 3, -1, -8, -8, -4, -4, 3, -11, 0, -1, -1, 0, -2, -14,
- -6, -9, 2, 1, 7, -4, 3, -1, 0, -3, 1, 2, 7, 5, 4, 3,
- -2, -3, 1, 6, -1, 6, -11, 7, 2, -6, 2, -4, 0, 2, 3, -7,
- -9, 3, 0, 4, -6, 0, -21, 0, -5, -1, 0, -1, 1, -6, -1, -1,
- 0, -7, 5, 7, -2, 8, -4, -1, 3, 9, -6, 10, -6, 7, 9, 10,
- 9, -6, 5, -14, 6, -5, 1, 2, -3, 0, -9, -10, -14, -2, -3, 6,
- -8, -15, 3, -9, 0, -3, 0, -6, -1, 3, 9, 10, 3, 3, -10, 6,
- 1, 3, -1, 9, 12, 4, 4, -9, -7, -5, 8, 6, 1, 1, -4, -5,
- -5, -1, -11, -3, -4, 1, -1, 1, -10, -7, -2, -3, -4, -3, -6, 11,
- 5, 3, 2, -8, -5, -2, 3, 9, 13, 5, 4, 4, 0, -5, -1, -5,
- 9, 2, 3, -9, -4, 3, -6, 2, 1, -9, 5, -2, 3, -2, -9, -8,
- -15, -5, -3, 3, -13, 11, 6, -3, 1, -6, -6, -1, 6, 4, 6, 7,
- 1, 5, 0, 8, -6, 7, 2, 6, 2, -5, 0, -3, -1, 3, -7, -1,
- -3, 5, 7, 6, -18, -10, -11, -7, -3, 10, -4, 3, -4, -8, -5, -12,
- -3, -4, 12, 10, 2, -4, 6, 3, 1, 2, 0, -3, 3, 7, 7, -5,
- 2, -4, 1, 3, 11, 2, 3, 4, -2, -7, -5, -17, -11, 4, -3, 5,
- -7, -7, -6, -1, -8, -5, -5, 1, 7, 1, 2, -1, -9, 7, 1, 7,
- 3, 3, 6, 9, 6, 1, -6, -4, 2, 5, 7, 4, -2, 1, 3, -11,
- -1, -16, -2, -6, 1, 3, -8, -15, -11, 4, -1, 9, -2, -5, 0, 6,
- 0, -7, 0, -8, 4, 2, 6, 2, 0, 2, 6, 2, -2, 4, -2, 4,
- 14, 2, 2, -6, -6, -3, 4, -4, -1, -4, 1, -3, -6, -1, -13, -1,
- -2, 7, -8, -7, -10, 0, 4, 3, -8, -3, 1, 4, 6, 4, 6, -3,
- 5, 3, 4, 0, 6, 1, 4, 7, -3, -10, 8, -1, 9, -1, 1, -11,
- -7, -3, -3, -6, -8, -9, -6, 1, -3, -6, -6, -5, 0, 0, 2, -3,
- 0, 6, 4, 3, 2, 7, 4, 11, 14, 5, -1, -5, 1, -2, 7, 3,
- 0, 1, 2, -5, -7, -10, -12, -10, -5, -5, -6, -6, -9, 1, -8, -2,
- -1, -9, 1, 8, 2, -5, -2, -5, 0, 5, 6, 6, 7, 8, 10, 2,
- 0, -3, -1, 2, 13, 3, 0, -6, 0, 1, -3, 0, -12, -2, 4, -4,
- 4, -8, -11, -1, -2, 1, -1, 2, -12, 3, -6, 1, -12, -7, -7, 3,
- 0, 9, 0, 1, 6, 1, -1, 2, 1, 2, 8, 9, -3, -1, 0, 7,
- 3, 8, -1, -4, -1, 1, 3, -9, -1, -17, -3, -2, -4, -4, -3, -4,
- -6, -11, -15, -2, -5, 6, 10, 1, 3, -1, -3, 13, 7, 1, 6, 4,
- 4, 9, 5, -3, -5, 9, 3, 5, -3, 1, -3, 3, 0, -7, -5, -7,
- 0, -5, 0, -1, -15, -11, -4, -5, -10, 2, -7, 5, -4, 1, -9, 2,
- 1, 8, 7, 10, 2, 2, 0, 4, 3, -2, 0, 4, 2, 6, 8, -2,
- 4, 4, -2, 5, -3, -6, 3, -3, -5, -9, -8, -11, -5, -1, -1, -5,
- -7, -5, -8, 0, -3, 5, -7, 11, 1, 0, 2, -3, -1, 3, 9, 6,
- -3, 8, 1, 11, 2, 8, -3, -3, 6, 2, 1, 2, -7, -3, -2, -4,
- -8, -3, -3, 5, -10, -10, -4, -12, -2, 3, -5, 3, -6, -8, -2, 5,
- -3, 0, 1, 4, 8, 4, 5, 0, 4, 8, 1, 7, -3, 0, 3, 4,
- 4, -5, -2, -7, -3, 0, 5, -5, -9, 3, -2, -1, -2, -5, -1, -4,
- -3, -11, -4, -5, -6, 0, 5, 0, -5, 5, 3, 8, -1, 3, 3, 2,
- 5, 7, -4, 3, 1, 3, 10, 2, -7, 1, 0, 6, -4, -3, -5, -7,
- -2, -4, -3, -6, 0, -10, 4, -6, -4, -7, -2, 1, -4, -1, -3, -1,
- 2, 6, 2, 4, -2, 2, 4, 2, 5, -3, 4, 2, 1, 0, 8, -3,
- 2, 5, -5, 3, -5, -2, 5, -5, 3, -1, -4, -3, 4, -10, -5, -7,
- -4, -4, 0, 0, -7, -1, -1, 2, 1, -2, -12, -4, -1, 0, 4, -5,
- 2, 0, 3, 12, 11, 3, 11, -1, -3, 6, -6, 1, 1, 7, 6, -7,
- -1, -7, -4, -4, -7, -8, -1, -6, -6, -2, -3, -5, 0, -4, 8, -7,
- 1, 4, -3, 6, 1, -7, 3, 5, 6, 5, 13, 2, 2, -4, 4, -3,
- 1, 4, -4, 2, -3, -10, -10, -7, -2, -2, -2, 0, -6, -2, 1, -3,
- -4, -2, -5, -2, 7, 1, 6, -5, 6, -1, -1, 2, -3, 4, 11, 2,
- -1, 2, -7, -5, 8, 0, 3, -3, -5, -1, -2, 3, 1, -4, 4, 7,
- 0, 2, 3, -3, 0, 1, -5, -15, -5, -3, 1, 3, -3, -11, -4, -7,
- 1, -2, -1, -1, 0, 1, 1, -5, -1, 3, -2, 7, 1, -4, -1, 0,
- 4, 5, 3, 3, -1, 8, 11, 1, 4, 1, -5, 7, -6, -4, -2, -4,
- -2, 3, -8, -3, -13, -6, 3, -3, -7, -4, -7, 3, 3, -3, 2, -1,
- 1, -4, -2, -2, -5, 1, 11, 9, -2, 6, -3, 7, 7, 1, 1, -7,
- 2, -3, 1, 4, -4, -4, 5, 1, 0, -3, -6, 2, -3, 0, -8, -12,
- -6, -2, -3, 6, -1, -9, 0, -1, 1, 3, -2, -1, 0, 1, 6, 0,
- -3, 5, 1, 6, 1, -1, 4, 1, 7, -3, -1, -1, -4, 4, 14, -1,
- -1, 2, -4, -1, -6, -8, -8, -3, -2, 2, -9, -5, -7, -12, 5, 0,
- -3, -4, -3, 5, 4, 3, -2, -6, 4, 7, 3, 5, 7, -3, 8, 0,
- -5, -1, -1, 11, 10, 3, 4, -8, -3, -3, 1, -3, 0, -4, -3, 1,
- -7, -8, -16, -7, -6, -2, 3, -7, -2, 1, -4, 0, -5, -5, 1, 5,
- 10, 5, 0, 3, 0, 1, 13, 0, 5, 9, 6, 8, -1, -4, 0, -3,
- 6, 4, -4, 0, -3, -15, -2, -12, -15, -3, -6, 2, 1, -3, -4, -9,
- -9, -3, -3, -2, 3, 4, 9, 0, 2, 1, 2, 14, 5, 3, 8, 2,
- 7, 4, -4, -4, -1, -9, 9, -5, -1, -7, -10, -2, -7, -4, 0, -5,
- 2, 5, 1, 0, -5, -5, -1, -1, -3, 4, -8, 5, 3, -4, 4, -5,
- -3, 9, 4, 8, 0, 0, 2, 0, -2, 0, -2, -7, 12, -1, 5, -4,
- 2, -3, 0, 2, -2, -4, -2, 2, -5, 3, -7, -9, -4, -3, -2, -6,
- -6, -2, -6, -1, -7, -8, 1, 3, 6, 10, 4, 5, 0, 5, 8, 1,
- 3, 8, 5, 11, 12, -7, 4, 0, -3, 2, -1, -8, -7, -4, -2, -6,
- -9, -6, -13, -4, -1, 0, -9, -5, -3, -4, -2, 3, 1, 1, 9, 4,
- 2, 6, -1, 3, 6, 2, 0, -3, 3, 2, 6, 3, -1, -4, 4, 1,
- 2, 2, -5, -8, -1, -3, -1, -9, -4, 1, -5, 5, -7, -4, 0, 3,
- -10, 3, -3, -5, 1, 5, 4, 1, -5, 1, -5, 4, 1, -6, 0, 5,
- 8, 8, 1, 6, 0, 3, 4, 2, -3, 1, -3, -3, 3, -10, -6, -8,
- -2, -1, -3, -6, -6, -5, -6, -6, -5, 5, -3, 5, 6, -2, -1, -1,
- -4, 6, -2, 6, 6, 2, 12, 8, -2, 3, -6, -2, 5, 4, -3, -2,
- -5, -4, -7, -6, 1, -5, 2, 2, 0, 1, -7, 0, -4, -2, -1, -2,
- -5, 7, -5, -2, -3, -2, -3, 4, 4, 9, 0, 1, 1, -5, -3, -4,
- -4, 4, 3, 6, 1, -2, -2, -7, 4, 1, 1, -3, 3, -1, 2, 0,
- -7, 0, 0, -1, -3, -2, -1, -5, -2, -3, -8, -5, -5, -1, 5, 5,
- 2, 2, -3, 4, 3, 4, 6, 3, -1, 10, -4, -3, -2, -3, 0, -4,
- 0, -2, -2, 0, 2, -5, -2, -5, -9, 8, -2, -1, -1, -3, -3, -2,
- -6, 2, 1, 2, 9, 0, 1, 4, -5, 2, 4, -6, -1, 2, -1, 6,
- 3, 0, -5, -3, -1, 0, 3, -3, 0, -6, -2, -3, -4, -2, 0, 3,
- 2, 2, 0, -10, 1, -6, -5, -1, -2, 5, 3, 6, -2, -6, -1, -3,
- 2, 4, 1, -1, 0, 1, 1, 3, -1, 5, -1, 7, 6, 1, -2, 0,
- -6, -2, -2, -8, -2, -2, -3, -5, -5, -8, -3, -1, 5, -3, 1, 2,
- 1, 2, -3, -2, -3, 2, 6, 2, 6, 0, 0, -2, 9, -1, 3, -2,
- 3, 0, 0, 0, -6, -6, -1, -5, -7, 1, -3, -6, 2, -2, -1, -5,
- -2, 1, 4, 2, 2, -3, -1, 6, -2, 2, 4, -3, 2, 2, 2, -3,
- 1, 0, -4, 2, -1, -2, 3, 1, 1, -1, -5, -8, -2, -5, 0, 1,
- -6, 3, -4, 2, 3, -6, 3, 0, 2, -2, -1, -4, -2, -4, 4, 0,
- -3, 0, -6, -3, 10, -3, 3, 0, 4, 7, 3, 0, 5, 1, 5, 1,
- -3, -2, 0, -6, 3, -1, -7, -5, -7, -1, -2, -2, -2, -3, -2, 2,
- -2, -1, -3, -3, 2, -2, -6, -3, -3, 4, 3, 2, 0, -1, 5, 5,
- 8, 2, 2, -2, 4, 0, 5, -5, -3, -1, -3, -3, -6, -4, -2, 3,
- 0, -2, -2, -5, 5, -1, 3, -1, -1, -3, 0, 0, -5, -4, -3, -2,
- 5, 0, -4, -4, 1, 2, 6, 0, -3, -1, 2, 3, 7, -3, 0, -4,
- -2, 4, 3, 0, 1, 3, -3, 1, -7, -4, 0, 1, 1, -4, -4, -4,
- -9, -1, -2, -3, -2, -3, -3, 4, 3, -1, -4, 2, 4, 4, 3, 2,
- -1, 0, 9, -1, 4, 2, 7, -1, 6, -2, -2, -5, -1, -9, -2, -2,
- -6, -1, -1, 1, -8, -6, -5, -1, -1, 1, -4, -5, 3, 1, 5, 3,
- -3, 0, -2, 7, 0, 1, -2, 3, -1, 5, -1, -5, 7, -1, 3, 2,
- -5, -6, -2, 4, 2, -1, -3, -1, -1, -1, -1, -2, -4, 1, -5, 3,
- -1, -3, -5, 2, 6, -6, -1, -5, -4, 4, -1, -1, -2, -1, 2, 0,
- 3, 1, 4, 2, 7, -1, 2, 0, -2, 1, 4, -5, -3, -7, -2, 0,
- -1, -1, -3, 0, 0, -2, -6, 2, -4, 2, -4, 1, -7, -2, -1, 5,
- 3, -2, -7, -4, 1, 6, 4, 5, 1, 4, 0, 5, 1, -1, 2, 0,
- -3, -3, -5, -6, 3, -1, 5, -1, -2, 1, 1, 4, 2, -6, -3, -4,
- -3, 2, -2, -8, -3, -6, -4, -2, -11, 0, 0, 1, 6, -3, -2, 1,
- 2, 10, 8, 4, -2, -1, 2, 2, 1, -2, 3, 1, 5, 3, -1, 0,
- -4, 4, -7, -2, -7, -8, -4, -3, -2, -7, -7, -3, -1, 5, -2, 0,
- -7, 2, -1, 3, 1, 4, 6, 5, 8, 3, 2, -1, 3, -3, 0, 0,
- -5, -1, 1, 1, -5, -3, -2, 6, 4, 5, -4, -8, -4, -3, -2, -5,
- -4, -4, -4, 2, -3, -2, -4, -4, -4, 6, 1, 0, 1, 3, 3, 5,
- 2, 1, 0, 6, 2, -1, 1, -3, -3, 2, -1, 0, 1, 3, 1, 4,
- -4, -5, -10, -8, 1, -6, -3, -4, -6, -3, 0, 2, -3, -1, 2, 0,
- 8, 1, 4, 4, 3, 6, 3, 1, 3, 5, 1, 2, -4, -7, -3, -3,
- 3, 0, -7, -5, 0, -3, -1, -2, -4, 0, -5, 1, -6, -1, -5, -3,
- 1, 4, -1, -3, 3, 3, 5, -1, -2, 2, -1, 2, 1, -1, -5, 5,
- 1, 2, 2, -4, 0, -1, 3, 0, -2, -1, 2, 1, 5, 4, -3, -5,
- 0, -2, -2, -6, -3, -3, -4, -1, -5, -4, -1, -2, 0, 2, -2, -6,
- -3, 1, 1, 1, -1, 3, 4, 7, 2, 3, 4, -1, 7, 2, 3, 1,
- -1, 1, -2, 0, -4, -5, -6, 0, -2, -7, -2, -5, -5, 1, -4, -5,
- -5, 3, -1, 1, 2, -2, 0, 1, 4, 1, -4, 2, 2, 0, 9, 2,
- 0, 4, 3, 1, 2, -4, -2, -4, 3, -4, -2, -6, 0, -1, 5, 2,
- -4, 0, -4, -4, -1, -5, -4, -7, -3, 1, 0, -2, -1, -5, 1, 0,
- -1, 0, 2, 4, 0, 3, -2, 1, 2, 6, 0, 1, 5, 0, 3, 3,
- 2, -5, -2, 1, 5, 2, -2, -5, -9, 0, -6, -1, -6, -7, -5, -4,
- 0, -2, -5, -3, 2, -2, 3, 2, 0, 9, 2, 0, 4, -3, 4, 5,
- 8, 6, -2, -4, -1, 0, -2, -2, 1, -5, 2, -5, -1, -4, -3, -4,
- 0, -2, -7, -3, -1, 0, -1, 0, -6, 3, -2, 5, 2, -1, -2, 1,
- 0, 1, -1, -3, 2, 3, 1, 2, -4, -3, -1, 5, 5, 3, -4, 0,
- 1, 2, 5, -5, 1, -5, 2, -2, 2, -4, -3, 0, -4, -3, -9, -7,
- -4, 2, -2, 1, -6, -3, 0, 1, 5, 1, -5, 0, 0, 2, 1, 2,
- 0, 6, 4, 6, 3, 2, 3, 1, -2, -2, -9, -4, -1, 4, 0, -1,
- -5, -8, -5, -4, 0, -4, -1, -3, 0, 0, -4, -3, -1, 1, 2, 0,
- -2, -3, 1, 3, 2, 3, 3, 0, 8, 2, 7, -1, 3, -2, 4, 0,
- 0, 1, -4, 5, -1, -3, -3, -6, -4, 2, 1, -5, -4, -7, -4, -4,
- -7, -2, -10, 1, 0, 1, -3, 4, -2, 5, 2, 1, -3, -1, 2, 8,
- 4, 5, 0, 1, 4, 5, 2, 2, -2, 1, -4, 0, -3, -3, -1, 0,
- 2, -4, -4, -5, -1, -7, 0, -4, -5, -1, -3, 2, -2, 0, 3, 0,
- 2, 0, 1, -2, 2, 4, -1, 0, -3, -1, 1, 3, 2, -3, 2, 0,
- 2, 2, -1, 2, -2, -3, 0, 0, -2, 2, -2, 4, -3, -6, -7, -6,
- 2, -1, -4, -1, -7, -1, -3, 3, -1, 0, -2, 2, 2, -3, 3, -4,
- 5, 7, 6, 3, 1, -1, 6, 2, 1, 0, -1, -1, 1, -3, 1, -3,
- -5, -5, -3, -8, -3, -11, -1, -1, 0, -8, -2, -5, 3, 4, 0, 1,
- -2, 2, 0, 6, 4, 1, 4, 1, 5, 0, 0, 1, 2, 5, 0, 1,
- -10, 0, -5, 2, 0, -6, -6, -2, -2, 2, -3, 0, -4, 2, -4, 1,
- -3, -4, 1, -2, 2, 1, -2, 0, 3, 2, -3, -1, -5, -3, 4, 2,
- 3, -1, 4, 1, 5, -1, 2, -3, 2, -3, 0, -3, -2, 1, 1, 5,
- 1, -2, -5, 1, -1, -4, -3, -7, 0, -5, -4, -4, 0, -4, 4, 0,
- -1, 1, -8, 1, 0, 9, 1, 2, -2, 5, 5, 1, 6, -1, 6, 3,
- 1, 1, -2, -2, -4, -3, -2, -3, -7, -4, -4, -1, -3, -8, -1, -8,
- 4, -5, 0, -3, 1, 0, 4, -1, 0, 1, 3, 3, 4, -4, 6, -2,
- 2, 5, 4, -3, 4, -3, 5, 0, -4, 0, 0, -1, 0, -4, -4, 3,
- -1, -2, -4, -8, -9, -5, -4, 4, -4, 1, -4, 1, 1, -1, -1, -1,
- 3, 2, 3, 0, 1, 2, 1, 5, 3, 1, 0, 5, 3, 3, 0, -5,
- -4, -2, 5, 0, -2, -5, -2, -6, -2, -5, -8, -2, 1, -1, -3, -7,
- -8, -6, 0, 4, 7, -2, 7, -1, 7, 3, 2, -5, 0, 2, 0, 1,
- -3, 2, 2, 3, 3, -3, 0, -2, 3, -1, -1, -4, -6, -2, -3, 4,
- -4, 0, -4, 6, -2, -6, -2, -7, 1, 2, -1, -3, -2, -2, 3, -1,
- 0, -3, -1, 4, 7, 4, 0, 2, -1, 0, 6, -2, 1, 1, 5, 4,
- 1, -3, -3, -2, 2, 2, 1, -6, -6, -3, -4, -2, -6, -5, -4, -5,
- -2, -8, -8, -3, 0, 4, 0, 1, -1, 2, 5, 4, 2, 2, 3, 3,
- 4, 10, 0, 2, 0, 3, 1, 1, 0, -3, 1, -3, 1, -7, 0, 1,
- -2, 1, -6, -4, -10, -1, -4, -2, -2, -3, 2, -4, 1, -5, -4, -4,
- 2, 1, 1, -4, -1, 3, 1, 6, 2, -2, -2, 3, 3, 2, 7, -5,
- 5, 0, 8, 1, -1, 2, 3, -1, -6, 0, -10, 3, -1, -1, -5, -6,
- -8, -2, 0, -3, -5, -8, -4, 2, -3, -1, -2, 0, -1, 7, -1, 3,
- 2, 4, 7, 3, 4, -1, 5, 1, 9, 1, -2, -1, -1, 1, -3, -2,
- -6, -7, 1, -3, -1, -9, -4, -6, 0, 2, -3, -2, -4, -3, 0, -4,
- -1, -4, 0, 1, 6, -1, 1, -1, 3, 5, -1, 3, 4, 5, 7, 4,
- -2, 0, -2, 0, 3, 1, -1, -8, -2, -1, -2, -5, -1, -2, -2, 2,
- -5, -7, -9, -2, -3, -2, 1, -5, 4, -4, 5, -1, -1, -3, 2, 3,
- 7, 3, -1, 3, 4, -1, 5, -4, 0, 4, 4, 3, 4, -9, 1, -5,
- 2, -2, -2, -3, -7, -1, -2, -2, -5, -3, -1, 1, -2, -1, -4, -4,
- 1, -1, -7, 0, -1, 2, 5, 4, -4, -5, -4, 0, 2, 1, -1, 3,
- 5, 4, 0, 0, -1, 3, 8, 3, 3, -4, 0, 1, 0, -2, -6, -2,
- -4, 3, -2, -3, -5, -6, -3, -1, -1, -7, 0, 0, 3, -5, -4, -11,
- 0, 0, 3, 3, 1, 1, 1, 4, 6, 1, 1, 2, 9, 3, 3, -4,
- -4, -3, 2, -1, -6, 1, -5, 2, 0, -1, -8, -5, -6, 1, 0, -2,
- -1, -2, -1, 2, 0, -9, 0, 5, 4, 7, -3, -3, 3, 4, 2, 4,
- 0, -1, 3, 1, 5, -5, -6, -7, 0, 3, 0, -2, -4, 3, 3, -3,
- -4, -7, -2, 4, 1, -1, -4, -1, -6, -2, 3, -2, -3, 1, 4, 1,
- -1, -4, -3, 3, 4, 5, -2, 2, -3, 4, 0, 3, -3, -3, 0, 3,
- 1, -2, -1, -3, 2, 4, -2, -2, -3, -1, -1, 3, -11, -2, -8, 5,
- -1, 3, -5, -2, 2, -1, 3, -3, 0, -1, -1, 5, -2, 0, -2, 3,
- 2, 3, -2, -6, -3, 2, 4, -6, 5, -6, 1, 2, 3, -6, 2, -3,
- -4, 3, -9, 2, -6, 3, 4, 2, -9, -1, 1, 2, 8, -3, -4, -1,
- -2, 2, -2, 2, -3, 3, -1, 1, 2, -1, -6, 1, 2, 2, 1, -2,
- 2, 3, 1, -3, -6, -3, 0, 1, -3, 0, -3, -1, -4, 2, -4, -3,
- -1, 4, 0, 5, -6, -7, -1, 0, 0, -3, -1, 2, 4, 0, 3, -4,
- -1, 1, 7, 4, 2, -1, -4, 0, 2, -4, -5, -5, -1, 1, 4, -5,
- -4, -6, -3, -2, -3, 2, -2, 5, 2, 3, -4, -2, -5, 6, 3, 4,
- 2, -3, 1, 0, 0, 1, -3, -1, 1, 7, 0, 6, -6, -7, -2, -7,
- 0, -1, 0, 2, 1, -2, -7, -2, -5, 0, 2, 0, -3, -5, -1, -3,
- 0, -1, 0, -6, 8, 4, 5, -1, 1, -4, 1, 1, 4, 2, 5, 3,
- 6, 0, -2, -9, -4, -1, 0, 0, 1, -1, -4, -1, -5, -5, -5, 0,
- 0, 1, -6, -5, -9, 0, -3, 0, -2, 0, 0, 3, 4, 2, 1, -7,
- 1, 3, 4, 9, 1, 4, 4, 2, -4, 2, -2, 1, 5, -2, 0, -3,
- -4, -3, -2, -4, -4, -4, 1, -1, 2, -6, -8, -3, -8, -1, -2, -4,
- 5, 2, 3, -1, 0, -4, 2, -1, 5, 5, -1, 3, 0, 3, 3, 0,
- -4, 9, 4, 2, -1, -6, -4, -2, -2, 2, -7, 0, 0, -2, -2, -2,
- -10, -4, -7, 0, -2, 2, -2, 2, 1, 0, -3, 0, 1, 6, 3, 2,
- 0, 0, -1, 2, 3, -1, 4, -5, 6, 2, -3, 0, -3, 0, 1, 0,
- -5, -6, 1, 0, 1, -5, -2, -14, 0, -4, -1, -1, -1, 1, -3, 0,
- -2, -1, -4, 4, 5, -1, 5, -1, 3, 3, 5, -3, 5, -3, 5, 5,
- 6, 4, -6, 2, -9, 4, -4, 0, 1, -2, -1, -8, -6, -11, -2, -3,
- 3, -6, -8, 3, -5, 1, -3, 1, -3, 1, 3, 5, 6, 2, 1, -6,
- 4, -1, 1, 0, 7, 7, 2, 3, -6, -4, -4, 3, 3, 0, 1, -1,
- -2, -4, 0, -8, -2, -3, 1, -2, 1, -5, -2, -1, -3, -3, -4, -3,
- 7, 4, 1, -1, -6, -5, -3, 2, 5, 8, 3, 3, 2, 1, -4, -1,
- -2, 6, 3, 2, -4, -1, 1, -5, -1, -1, -5, 2, -2, 1, -2, -7,
- -5, -11, -4, -3, 3, -8, 8, 4, -2, -2, -4, -4, -1, 4, 3, 5,
- 5, 2, 4, -1, 6, -3, 6, 2, 3, 0, -4, 0, -2, -2, 0, -5,
- -2, -1, 4, 3, 1, -13, -8, -8, -5, -3, 7, -2, 3, -2, -5, -3,
- -8, -2, -3, 8, 6, 1, -2, 5, 3, 1, 2, 0, -1, 2, 4, 3,
- -5, 1, -3, 0, 1, 7, 1, 2, 3, -1, -4, -4, -10, -7, 3, 0,
- 2, -5, -5, -4, -1, -7, -3, -3, 1, 3, 0, 0, -1, -6, 6, 1,
- 4, 1, 2, 5, 6, 4, -1, -4, -3, 1, 2, 5, 2, -1, 1, 3,
- -8, -1, -10, -2, -5, 0, -1, -6, -10, -7, 2, -2, 6, -1, -2, 1,
- 4, -1, -5, -1, -5, 4, 1, 4, 2, 1, 3, 4, 0, -2, 1, -1,
- 3, 8, 2, 1, -4, -3, -3, 3, -3, -1, -4, 0, -4, -6, -2, -8,
- 1, -2, 5, -6, -5, -6, 0, 3, 1, -6, -3, 1, 2, 4, 2, 4,
- -2, 3, 3, 3, 1, 5, 1, 2, 3, -2, -6, 6, -1, 6, -2, 1,
- -7, -5, -2, -3, -6, -6, -6, -4, 0, -2, -4, -4, -3, 0, -1, 1,
- -3, -1, 3, 1, 1, 0, 6, 4, 8, 10, 5, 0, -3, 1, -2, 5,
- 2, 1, 1, 1, -4, -6, -8, -8, -8, -5, -4, -5, -4, -5, 0, -5,
- -3, 0, -7, 0, 4, 1, -4, -1, -4, -2, 4, 4, 5, 6, 6, 7,
- 0, 0, -1, 0, 2, 9, 2, 1, -3, 0, 1, -3, 1, -9, -1, 3,
- -4, 3, -6, -7, -2, -1, -1, -1, 1, -9, 2, -5, 1, -8, -6, -6,
- 1, -1, 6, 0, 2, 5, 2, 0, 2, 1, 2, 6, 5, -2, -1, 0,
- 4, 1, 6, 0, -2, 1, 0, 3, -7, -1, -13, -4, -3, -3, -3, -2,
- -3, -5, -9, -11, -2, -3, 4, 7, -1, 2, 0, -2, 8, 5, 1, 4,
- 3, 2, 7, 3, -2, -4, 7, 2, 3, -2, 1, -1, 2, 0, -5, -4,
- -4, 0, -4, 0, -1, -10, -9, -3, -5, -8, 1, -5, 3, -3, 0, -7,
- 1, 0, 5, 4, 7, 1, 1, 0, 2, 2, -2, -1, 2, 1, 4, 6,
- -1, 4, 3, -1, 4, -2, -3, 3, -1, -2, -6, -6, -7, -3, -1, 0,
- -4, -6, -5, -6, 0, -3, 3, -5, 7, 0, -1, 1, -3, -1, 1, 6,
- 3, -3, 7, 1, 10, 1, 6, -1, -2, 5, 2, 1, 1, -4, -2, 0,
- -3, -7, -2, -4, 4, -8, -8, -4, -10, -2, 2, -4, 1, -5, -7, -1,
- 3, -1, 1, 1, 4, 6, 2, 2, 0, 4, 7, 0, 5, -2, 0, 3,
- 3, 3, -3, -1, -5, -2, 0, 3, -4, -6, 2, -1, 0, -2, -4, 0,
- -4, -3, -9, -3, -4, -4, 0, 3, -1, -4, 3, 1, 5, -2, 1, 2,
- 2, 4, 5, -3, 2, 1, 3, 7, 1, -5, 1, 0, 5, -3, -2, -3,
- -4, 0, -3, -2, -5, 0, -8, 3, -6, -4, -6, -2, 2, -4, -2, -3,
- -2, 1, 4, 2, 3, -2, 2, 4, 1, 4, -2, 3, 2, 1, 1, 7,
- -1, 2, 4, -4, 2, -4, -2, 5, -4, 3, -1, -3, -2, 3, -8, -4,
- -6, -3, -3, -1, 0, -6, -1, 0, 1, 1, -2, -10, -3, -1, 0, 2,
- -5, 1, 1, 2, 10, 8, 2, 8, -1, -2, 4, -5, 2, 2, 7, 6,
- -6, -1, -5, -4, -3, -6, -7, 0, -5, -5, -1, -2, -5, 0, -4, 6,
- -6, 0, 3, -3, 4, 0, -6, 2, 5, 5, 4, 10, 0, 2, -3, 3,
- -2, 0, 3, -3, 2, -3, -8, -8, -5, -1, -1, -1, 0, -5, -2, 0,
- -3, -4, -1, -5, -2, 5, 0, 5, -4, 4, -1, -1, 1, -3, 3, 9,
- 2, -1, 1, -6, -3, 7, 1, 3, -2, -4, 0, -1, 3, 1, -3, 4,
- 6, 0, 1, 2, -3, 0, 0, -5, -13, -4, -2, 1, 2, -3, -10, -4,
- -7, 1, -2, -2, -1, 0, 1, 1, -4, -1, 2, -2, 7, 1, -3, 0,
- 0, 4, 5, 2, 2, -1, 6, 9, 1, 3, 1, -5, 5, -6, -5, -2,
- -4, -2, 2, -7, -4, -11, -5, 3, -3, -6, -4, -6, 3, 3, -3, 2,
- 0, 1, -3, -1, -2, -4, 1, 10, 8, -2, 4, -3, 6, 6, 1, 0,
- -7, 2, -2, 1, 3, -4, -4, 4, 1, 0, -2, -5, 2, -2, 0, -7,
- -11, -5, -2, -2, 5, -1, -8, -1, -1, 1, 2, -2, -1, 1, 1, 5,
- 0, -3, 5, 1, 6, 1, -1, 3, 1, 6, -3, -1, -1, -3, 4, 12,
- -1, -1, 2, -4, -1, -6, -8, -7, -3, -2, 1, -9, -5, -6, -10, 5,
- 1, -2, -3, -2, 5, 4, 3, -1, -5, 4, 6, 3, 4, 6, -2, 7,
- 0, -4, -1, -1, 9, 8, 2, 2, -8, -3, -3, 0, -2, 0, -4, -2,
- 0, -6, -7, -14, -6, -5, -1, 3, -6, -2, 1, -3, 0, -4, -5, 1,
- 5, 9, 4, 0, 3, 0, 1, 12, 0, 4, 8, 5, 7, -1, -4, 0,
- -3, 5, 4, -4, 0, -3, -13, -2, -10, -14, -3, -5, 2, 1, -3, -4,
- -8, -8, -3, -2, -2, 3, 4, 8, 0, 2, 1, 2, 12, 5, 3, 8,
- 2, 6, 3, -4, -4, -2, -8, 8, -5, -2, -6, -10, -2, -6, -4, 0,
- -4, 2, 5, 1, 0, -4, -4, -1, -1, -3, 4, -7, 4, 3, -3, 4,
- -4, -3, 8, 4, 7, 0, 0, 2, -1, -2, -1, -2, -7, 11, -1, 5,
- -4, 2, -2, 0, 2, -2, -4, -2, 1, -5, 3, -6, -9, -3, -3, -2,
- -5, -5, -2, -6, -2, -7, -8, 1, 3, 5, 9, 4, 4, 0, 5, 8,
- 1, 3, 7, 5, 10, 11, -7, 3, 0, -3, 1, -1, -7, -7, -3, -2,
- -6, -9, -6, -12, -4, -1, 0, -8, -5, -3, -3, -2, 3, 1, 1, 9,
- 4, 2, 5, -1, 2, 6, 2, 0, -3, 2, 2, 5, 2, -1, -4, 4,
- 1, 1, 2, -5, -8, -1, -3, -1, -9, -4, 1, -4, 5, -6, -4, 0,
- 3, -9, 3, -3, -5, 1, 4, 4, 1, -4, 1, -4, 4, 1, -6, 0,
- 5, 7, 8, 1, 6, 0, 3, 4, 2, -3, 1, -3, -3, 3, -9, -6,
- -7, -2, -1, -3, -5, -6, -5, -5, -6, -5, 4, -3, 5, 5, -2, -1,
- -1, -3, 6, -2, 5, 6, 2, 11, 8, -1, 3, -6, -2, 5, 4, -3,
- -3, -5, -3, -7, -5, 0, -5, 2, 1, 0, 1, -7, 0, -3, -2, -1,
- -2, -5, 7, -4, -2, -3, -2, -3, 4, 4, 9, 0, 1, 1, -5, -3,
- -4, -4, 4, 3, 6, 0, -2, -2, -6, 4, 1, 1, -3, 3, -1, 2,
- 0, -7, 0, 0, -1, -3, -2, -1, -5, -2, -3, -8, -5, -5, -1, 5,
- 5, 2, 2, -3, 4, 3, 3, 6, 3, -1, 10, -4, -3, -2, -3, 0,
- -4, 0, -2, -2, 0, 1, -4, -2, -5, -9, 8, -2, -1, -1, -3, -3,
- -2, -6, 2, 1, 2, 9, 0, 1, 3, -4, 2, 4, -6, -1, 2, -1,
- 6, 3, 0, -5, -3, -1, 0, 3, -3, 0, -6, -2, -3, -4, -2, 0,
- 3, 2, 2, 0, -10, 1, -6, -5, -1, -2, 5, 3, 6, -2, -6, -1,
- -3, 2, 11, 11, -28, -10, 54, -53, 2, 43, -37, 0, 43, -48, 7, 11,
- -18, 19, -33, 32, -1, -7, -6, 19, -21, 23, -38, 0, 54, -49, 0, 15,
- 20, -28, -20, 53, -28, -48, 70, -6, -60, 51, 5, -32, 1, 31, -10, -33,
- 24, 33, -68, 21, 50, -67, -1, 57, -28, -21, 26, 15, -48, 9, 33, -32,
- -3, 23, -10, 5, -4, -10, 24, -42, 29, -13, 0, 26, -15, -26, 46, -17,
- -38, 45, -26, 8, -1, 4, -5, -3, 15, -27, -2, 39, -37, -25, 74, -33,
- -25, 16, 24, -26, -25, 46, 10, -74, 50, 33, -80, 37, 32, -51, 13, 26,
- -21, -5, 0, 18, -33, -1, 49, -29, -29, 38, 7, -26, -20, 45, -21, -18,
- 26, -6, -6, 17, -29, -5, 41, -38, 10, 19, -18, -7, 15, 2, -24, 1,
- 21, -6, -28, 51, -30, -7, 10, 6, -22, -3, 37, -32, -24, 63, -16, -60,
- 65, -10, -35, 15, 17, -15, -8, -1, 33, -37, -10, 55, -44, -5, 41, -35,
- -9, 20, -5, -18, 13, 19, -27, 2, 34, -34, -7, 21, -27, 27, -25, 26,
- 5, -30, 32, -45, 38, -3, -41, 24, 25, -31, 5, 9, 9, -37, 13, 31,
- -36, 7, 20, -18, -25, 56, -50, 13, 17, -17, 19, -40, 46, -3, -82, 88,
- -1, -73, 66, -10, -4, -18, 13, 5, -27, 14, 7, -7, -10, 37, -39, 11,
- 14, -38, 35, -21, 5, 11, -27, 45, -37, -6, 34, -39, 23, 16, -51, 51,
- -11, -28, 19, -6, 12, -29, 12, 26, -21, -25, 48, -35, -6, 24, -9, 0,
- -31, 54, -19, -47, 73, -33, -43, 81, -59, 12, 15, -28, 22, -26, 33, -2,
- -29, 14, 34, -63, 28, 16, -40, 31, -22, 18, 8, -22, 25, -31, 6, 26,
- -54, 33, 19, -53, 56, -25, -9, 24, -39, 34, -18, -15, 35, -18, -16, 43,
- -41, -3, 47, -54, 9, 33, -13, -24, -2, 41, -26, -35, 73, -49, 1, 32,
- -34, 20, -28, 22, -5, -16, 23, 18, -62, 47, 5, -57, 51, -15, -5, 0,
- 4, 12, -11, -15, 29, -28, 4, 26, -44, 43, -19, -14, 35, -37, 23, -15,
- -11, 45, -54, 17, 42, -67, 18, 47, -58, 17, 25, -35, 14, -6, 11, -3,
- -42, 73, -50, -12, 67, -68, 28, -6, -4, 16, -44, 47, 8, -64, 80, -39,
- -31, 54, -43, 14, -2, 11, -14, 4, -3, 19, -34, 0, 61, -98, 69, 12,
- -61, 48, -35, 28, -12, -38, 85, -86, 42, 25, -76, 77, -31, -37, 39, -2,
- -12, 7, -10, 16, -1, -33, 60, -48, -16, 70, -69, 13, 38, -43, 15, 0,
- 0, 22, -65, 75, -28, -60, 96, -58, -8, 32, -6, 1, -11, 4, 17, -46,
- 17, 46, -86, 66, 9, -69, 67, -21, -30, 33, -32, 42, -34, 1, 50, -74,
- 40, 5, -34, 21, 7, -23, 21, -14, 10, -1, -33, 58, -48, -3, 65, -77,
- 14, 51, -65, 32, -10, 0, 24, -58, 71, -27, -54, 86, -56, -12, 45, -17,
- -18, 21, -1, -5, -14, 12, 19, -75, 78, 1, -80, 84, -25, -33, 48, -50,
- 45, -30, -15, 69, -86, 46, 22, -56, 14, 36, -35, 2, 16, -11, 4, -24,
- 41, -27, -19, 53, -42, -4, 49, -67, 36, 2, -26, 37, -46, 58, -40, -26,
- 82, -70, -7, 55, -30, -20, 36, -1, -32, 11, 7, 7, -41, 39, 18, -68,
- 65, -11, -39, 40, -34, 30, -20, -12, 70, -98, 53, 27, -74, 40, 10, -31,
- 11, 20, -19, 6, -6, 12, -19, -9, 46, -36, -31, 83, -65, 8, 32, -48,
- 42, -45, 49, -23, -32, 68, -59, 5, 39, -31, -1, 23, -20, -8, 17, -7,
- -15, -1, 16, 25, -63, 51, 14, -66, 47, -10, -15, 5, -1, 36, -72, 54,
- 22, -86, 64, -3, -31, 13, 11, -8, -12, 14, 15, -34, 6, 29, -24, -25,
- 62, -49, -9, 49, -56, 45, -31, 18, 4, -37, 57, -41, -11, 38, -38, 7,
- 24, -20, 10, -13, 20, -17, -8, 18, -4, -30, 35, 14, -63, 56, -7, -52,
- 50, -5, -4, -19, 17, 36, -83, 51, 14, -52, 30, 4, 0, -15, 14, 8,
- -43, 32, 3, -20, 2, 19, -11, -20, 45, -42, 14, 3, -5, 9, -31, 43,
- -20, -30, 51, -24, -19, 47, -42, 21, -17, 25, -24, -20, 52, -37, 1, 20,
- -6, -21, 25, -2, -33, 30, -9, -15, 23, -13, 26, -49, 29, 22, -76, 71,
- -12, -37, 27, 4, 7, -41, 30, 10, -45, 28, 13, -13, -21, 31, -1, -33,
- 27, 6, -18, -10, 24, -6, -26, 33, -10, -37, 72, -60, 24, 1, -13, 15,
- -36, 52, -44, 18, 14, -31, 23, 2, -16, -8, 10, 23, -47, 19, 17, -10,
- -17, 10, 29, -69, 56, -5, -38, 47, -28, 14, -21, 6, 32, -55, 33, 12,
- -39, 24, 5, -11, -25, 31, 12, -47, 35, 9, -25, 1, 7, 5, -36, 57,
- -52, 18, 29, -45, 37, -45, 35, -13, -17, 41, -31, 7, 8, -18, 15, -19,
- 19, -22, 2, 33, -37, 20, -4, 2, -25, 27, 0, -34, 37, -13, -6, 3,
- 1, 17, -46, 28, 32, -78, 60, -7, -25, 18, -6, 12, -35, 31, 4, -38,
- 37, -11, -8, -13, 37, -22, -17, 32, -27, 25, -34, 24, 9, -43, 41, -19,
- -1, 29, -48, 29, -6, -8, 10, -11, 27, -35, 18, 9, -19, -7, 12, 4,
- -27, 30, 2, -24, 13, 7, -18, -1, 16, 11, -68, 77, -15, -45, 43, -24,
- 29, -38, 16, 21, -43, 27, -7, -10, 11, 1, -4, -13, 26, -17, -1, 1,
- -1, 3, -19, 34, -24, -13, 49, -51, 22, 3, -23, 29, -33, 28, -7, -15,
- 31, -35, 2, 29, -28, -11, 27, -4, -18, 19, 2, -31, 26, -16, 17, -28,
- 34, -3, -49, 64, -39, 6, 1, -8, 25, -38, 32, 4, -53, 47, 0, -32,
- 16, 14, -1, -37, 31, -4, -7, -8, 9, 7, -20, 36, -34, 4, 25, -39,
- 25, -13, 4, 12, -36, 51, -38, 0, 34, -51, 27, 13, -34, 14, 12, -9,
- -23, 41, -21, -1, -16, 28, 10, -62, 66, -23, -26, 26, -9, 13, -29, 13,
- 31, -62, 49, 1, -49, 49, -18, -7, 2, 14, -10, -19, 20, 5, -8, -17,
- 37, -27, -5, 23, -35, 17, 15, -30, 30, -20, 28, -32, -5, 48, -64, 29,
- 13, -37, 35, -10, -1, -7, -3, 14, -16, -9, 26, -5, -35, 48, -21, -21,
- 40, -26, -11, 21, 3, 0, -42, 47, 8, -71, 72, -21, -21, 25, -15, 7,
- -16, 14, -1, -24, 18, 32, -48, 12, 30, -46, 12, 26, -45, 36, -20, 18,
- -3, -34, 52, -40, -2, 25, -29, 32, -11, -18, 18, -3, 3, -24, 7, 36,
- -40, -10, 50, -35, -19, 47, -30, -4, 22, -17, 8, -22, 29, 4, -72, 85,
- -21, -48, 57, -19, -8, -10, 17, 5, -31, 16, 24, -47, 29, 12, -31, 14,
- 2, -27, 43, -26, 5, 13, -33, 48, -46, -6, 58, -67, 13, 45, -50, 26,
- -6, -6, -2, -9, 24, -20, -7, 40, -37, -5, 36, -29, -17, 38, -21, 2,
- -5, 6, 14, -52, 59, -11, -59, 82, -38, -22, 32, -11, -6, -4, 11, 14,
- -38, 30, 5, -44, 24, 25, -37, 0, 21, 1, -9, -24, 49, -36, -12, 47,
- -49, 20, 34, -70, 43, 6, -31, 21, -20, 24, -13, -10, 37, -35, -8, 37,
- -26, -22, 44, -20, -13, 20, -7, 8, -28, 36, -15, -42, 79, -41, -28, 46,
- -17, -8, -5, 5, 29, -44, 17, 24, -43, 20, 13, -42, 16, 37, -43, 5,
- 22, 4, -31, 6, 26, -40, 11, 31, -45, 24, 9, -27, 26, -29, 26, -13,
- -16, 38, -40, 19, 21, -37, -9, 51, -32, -18, 34, -11, -7, -11, 22, 0,
- -40, 49, -20, -23, 44, -22, -9, 3, -2, 19, -44, 42, 6, -52, 41, 6,
- -43, 20, 28, -48, 31, 8, -23, 10, -7, 7, -19, 4, 31, -41, 15, 28,
- -40, 16, -8, 16, -25, -4, 51, -55, 19, 0, 8, -29, 29, -16, -11, 37,
- -39, 18, 4, -6, -5, -14, 35, -6, -52, 72, -37, -9, 13, 11, -17, -22,
- 53, -32, -20, 42, -19, -18, 12, 19, -29, 12, 12, -24, 15, -6, 6, -12,
- -15, 54, -44, -2, 41, -48, 32, -20, -4, 9, 1, 5, -35, 48, -11, -17,
- -9, 24, 1, -37, 38, -9, -16, 16, -2, -11, -1, 13, 11, -55, 67, -31,
- -19, 37, -26, -4, 12, 16, -34, 11, 21, -22, -10, 12, 0, 0, -21, 37,
- -16, -11, 29, -37, 15, -3, 17, -37, 13, 38, -54, 30, -2, -19, 11, -11,
- 20, -20, 15, 4, -22, 13, 2, -8, -13, 20, 4, -28, 33, -9, -34, 38,
- -13, -6, -14, 46, -33, -9, 36, -34, 4, 8, -9, 11, -9, 5, 1, -17,
- 23, -16, -3, 4, 18, -26, -11, 54, -53, 5, 18, -5, -11, 8, 11, -20,
- 12, -10, 1, 2, 5, -4, -5, -1, 23, -35, 22, -1, -25, 19, 3, -7,
- -11, 22, 1, -37, 45, -26, -12, 20, 2, -23, 17, 13, -23, -4, 18, 1,
- -15, -15, 33, 4, -49, 46, -25, 3, 5, 2, -11, 7, 13, -33, 13, 10,
- -24, 12, 6, -3, -4, 12, -9, -10, -3, 20, -19, -3, 19, -2, -21, 16,
- 5, -33, 35, -17, -3, 2, 17, -12, -21, 27, -17, -6, 19, -8, -6, 14,
- -12, 10, -16, 13, 0, -19, 11, 20, -23, -9, 38, -50, 22, 17, -24, -5,
- 17, 7, -24, 0, 23, -18, -14, 27, -15, 5, 6, -9, 1, -2, 7, -24,
- 16, 10, -12, -9, 26, -19, -14, 30, -18, -13, 19, -10, 10, -8, 6, 1,
- -27, 35, -13, -20, 26, -5, -11, -10, 28, -9, -32, 36, -3, -25, 12, 28,
- -51, 36, -6, -20, 18, -2, -3, -1, -11, 28, -31, -4, 48, -56, 16, 19,
- -18, 6, -4, 1, -10, 11, 0, -4, -6, 25, -26, -9, 30, -26, -6, 23,
- -13, 10, -7, -3, 19, -56, 64, -30, -31, 50, -4, -31, 15, 15, -27, 6,
- 13, -6, -14, 20, -2, -27, 23, 7, -30, 10, 19, -10, -1, -13, 27, -31,
- 3, 38, -56, 29, 20, -45, 24, 5, -17, 0, 5, 3, -9, 2, 24, -25,
- -14, 31, -13, -22, 28, -6, -8, 1, 3, 13, -41, 51, -39, -20, 60, -30,
- -28, 48, -14, -26, 25, -10, 7, -17, 16, 5, -25, 13, 10, -32, 11, 35,
- -46, 17, 10, 5, -32, 10, 21, -44, 19, 30, -39, 15, 7, -18, 11, -11,
- 10, -13, 1, 19, -14, -12, 30, -25, -18, 43, -23, -15, 30, -13, -6, -14,
- 43, -42, -9, 55, -36, -17, 43, -21, -11, 12, -13, 16, -28, 23, 10, -38,
- 27, 17, -47, 22, 20, -46, 30, -7, 6, -10, -6, 26, -34, 15, 22, -39,
- 15, 21, -43, 26, -6, 1, -14, 12, 20, -26, -12, 41, -29, -29, 57, -40,
- 2, 27, -22, 8, -10, 10, -10, -10, 30, -14, -29, 47, -17, -24, 25, -11,
- 3, -17, 30, -3, -32, 28, 7, -44, 35, 12, -46, 39, -6, -10, -2, -3,
- 23, -31, -4, 49, -48, 6, 39, -55, 32, -8, -9, 0, 8, 7, -15, -3,
- 29, -26, -16, 43, -44, 13, 26, -30, 9, 6, -5, 4, -28, 30, 9, -56,
- 64, -19, -33, 43, -25, -8, 14, 8, -14, -8, 18, 11, -44, 23, 17, -39,
- 20, 19, -24, -1, 12, 7, -27, -2, 47, -51, 3, 47, -55, 28, 1, -23,
- 17, 4, -12, 5, -9, 18, -9, -21, 30, -24, 6, 12, -11, -2, 14, -13,
- -3, -10, 26, -10, -45, 74, -31, -31, 51, -26, -14, 19, -8, 2, -4, 3,
- 23, -43, 20, 15, -31, 13, 20, -36, 18, 9, -17, -3, 0, 21, -32, 12,
- 32, -50, 21, 12, -26, 16, -6, 5, 1, -16, 21, -5, -27, 28, -11, -11,
- 19, -2, -20, 28, -17, -2, 4, -5, 9, -26, 43, -31, -11, 47, -42, 1,
- 19, -16, 5, -8, 12, 9, -41, 41, -7, -32, 22, 25, -51, 23, 14, -18,
- 7, -21, 31, -22, -2, 24, -24, 6, 18, -39, 25, -9, 3, 5, -17, 28,
- -13, -17, 27, -21, -12, 25, -12, -12, 32, -19, -6, 11, -24, 29, -21, 11,
- -2, -17, 36, -29, -9, 24, -16, -2, 7, -6, 17, -27, 27, -20, -11, 23,
- -1, -31, 25, 15, -32, 12, -8, 21, -22, -8, 26, -16, -15, 47, -45, 8,
- 12, -12, 14, -28, 33, -10, -15, 15, -11, 6, 2, -17, 5, 23, -20, -5,
- 19, -21, 12, -8, -8, 31, -38, 31, -17, -14, 31, -27, -1, 19, -20, 19,
- -10, 4, -2, -7, 2, 1, -6, 6, 12, -27, 12, 8, -10, -7, 8, -1,
- -3, -15, 47, -53, 15, 25, -40, 24, -7, 12, -13, -11, 22, -7, -22, 14,
- 7, -5, -11, 13, 5, -8, -9, 4, 7, -22, 22, -12, 16, -9, -16, 29,
- -32, 8, 23, -36, 14, 7, -3, 5, -27, 24, -1, -20, 14, 7, -7, -4,
- 9, -21, 6, 23, -27, 7, -1, 23, -30, -3, 31, -39, 26, -17, -3, 30,
- -24, 9, -7, -13, 30, -24, 3, 2, 9, -6, -15, 24, -18, 9, -20, 16,
- 2, -8, 11, -11, 6, -10, 6, 11, -38, 27, 20, -42, 28, -26, 35, -21,
- -29, 51, -32, 8, -3, 15, -19, 3, 14, -33, 24, 4, -9, -9, 4, 23,
- -29, 0, 21, -32, 39, -38, 20, 8, -34, 38, -27, 8, 12, -12, 3, -8,
- 11, -11, 1, 3, -9, 18, -18, 10, 0, -7, 4, -13, 17, -13, 0, 33,
- -56, 42, -11, -7, 7, -17, 36, -50, 24, 21, -25, -7, 14, 9, -27, 8,
- 23, -28, 3, 8, 2, -12, -10, 39, -43, 24, -4, -5, 18, -38, 39, -26,
- -8, 26, -24, 14, 10, -20, 5, -9, 15, -19, 13, -12, 5, 24, -39, 24,
- -8, 8, -16, -14, 53, -49, 16, 5, -22, 26, -28, 18, -13, 7, 18, -31,
- 6, 17, -12, -13, 3, 26, -35, 16, 18, -36, 21, -12, 28, -49, 27, 22,
- -38, 13, -1, 17, -28, -5, 30, -22, 2, 25, -42, 32, -19, 18, -23, -1,
- 21, -20, 22, -31, 25, 3, -25, 9, -6, 27, -29, -3, 32, -35, 19, -7,
- -8, 11, -12, 28, -35, 1, 39, -33, -6, 2, 30, -35, -1, 41, -42, 18,
- -9, 6, -8, -2, 26, -46, 24, 24, -41, 11, 11, -2, -12, -9, 48, -59,
- 31, -10, 6, -12, -5, 34, -43, 33, -12, -7, 11, -11, 1, 7, -12, 17,
- -23, 32, -24, -5, 19, -26, 27, -28, 24, -15, -5, 31, -41, 11, 11, -4,
- -19, 10, 37, -53, 2, 43, -35, 2, -3, 20, -20, 3, 32, -53, 30, 5,
- -24, 10, -7, 41, -53, 10, 33, -31, -8, 11, 12, -30, 28, 4, -37, 28,
- 8, -30, 12, -17, 42, -38, 5, 24, -33, 35, -41, 23, -1, -4, 5, -20,
- 32, -18, -10, 25, -22, -4, 14, 6, -24, -5, 62, -80, 28, 19, -20, 4,
- -14, 41, -49, 14, 34, -45, 3, 13, 17, -37, -4, 66, -61, -5, 35, -15,
- -5, -2, 14, -24, 21, 5, -41, 41, -22, 18, -24, 5, 44, -66, 34, -3,
- -17, 24, -26, 20, -13, 14, -1, -31, 39, -19, -20, 31, -14, 0, -12, 46,
- -61, 29, 19, -44, 36, -26, 30, -31, -7, 49, -41, -15, 54, -42, -1, 12,
- 24, -48, 8, 44, -57, 17, 13, 7, -34, 13, 33, -55, 28, 4, -14, 4,
- -9, 32, -42, 15, 28, -58, 40, -12, 0, 7, -8, 8, -24, 29, -9, -29,
- 38, -23, 9, -8, 13, -7, -14, 24, -37, 32, -7, 3, -17, 1, 39, -46,
- -20, 78, -68, 15, 17, -6, -4, -15, 37, -47, 15, 20, -17, -12, 28, 9,
- -52, 25, 31, -54, 24, 4, -1, -11, -5, 51, -74, 36, 9, -27, 17, -6,
- 8, -12, 3, 6, -16, 14, 0, -15, 10, 3, 7, -31, 34, -22, -2, 17,
- -20, 9, 10, -7, -13, -5, 45, -52, 8, 30, -33, 15, -11, 28, -32, -5,
- 44, -42, -4, 42, -25, -29, 29, 14, -36, 12, 19, -20, 8, -14, 33, -42,
- 16, 23, -48, 32, 2, -14, 2, -1, 14, -21, -9, 42, -47, 24, 0, -10,
- 0, 15, -19, -1, 21, -31, 13, 15, -23, 10, -14, 20, -7, -27, 50, -32,
- -5, 18, -10, -1, -8, 25, -36, 12, 34, -45, 6, 27, -20, -16, 12, 19,
- -22, 0, 12, 0, -13, -8, 31, -41, 17, 16, -29, 17, 11, -19, -4, -2,
- 36, -55, 30, 13, -35, 25, -7, -8, 10, -4, -8, 13, -7, 0, 4, -16,
- 8, 13, -35, 40, -25, -6, 44, -51, 17, 15, -18, -3, 1, 14, -18, -1,
- 24, -23, -9, 20, -6, -9, 1, 24, -30, 6, 6, 10, -29, 8, 31, -48,
- 21, 27, -43, 13, 4, -4, -5, -2, 19, -18, 12, -15, 4, 16, -25, 9,
- 1, 2, 0, -13, 12, 3, -16, -3, 18, -10, -6, 25, -41, 21, 11, -30,
- 20, -3, 0, 1, -14, 27, -19, -21, 38, -28, 9, -3, 14, -22, 13, -4,
- -2, -6, 12, 2, -26, 30, -1, -38, 31, 7, -32, 25, -16, 14, -4, -9,
- 15, -19, 6, 4, -11, 2, 11, -8, -4, 10, -7, -4, 6, -10, 2, 11,
- -9, 0, -5, 15, -16, 0, 9, -2, -7, 0, 11, -11, -12, 35, -44, 20,
- 13, -19, 2, 13, -11, -14, 12, 10, -22, -2, 27, -24, -2, 15, 5, -29,
- 22, -10, 6, -2, -3, 16, -31, 20, 11, -39, 29, 9, -34, 25, -10, 5,
- -2, -15, 14, 0, -5, -6, 19, -18, 13, -22, 5, 24, -30, -1, 35, -23,
- -12, 12, 12, -26, 5, 22, -32, 16, 16, -27, 2, 10, -4, -12, 2, 23,
- -19, -1, 1, 11, -17, 4, 8, -18, 12, 12, -24, 1, 24, -20, -15, 29,
- -5, -31, 42, -23, -8, 20, -18, 19, -33, 24, 8, -22, 0, 32, -38, 9,
- 21, -25, 2, 23, -30, 7, 16, -20, 12, -10, 8, -14, 12, 16, -41, 24,
- 14, -30, 6, 2, 19, -22, -6, 25, -8, -24, 23, -1, -29, 32, 9, -53,
- 50, 4, -42, 12, 12, 3, -24, 15, 14, -25, 5, 4, 7, -25, 26, -5,
- -23, 28, 0, -32, 23, -1, -21, 14, 10, -7, -13, 21, -25, 16, -8, 1,
- -1, -1, 13, -22, 12, 12, -28, 3, 13, 1, -15, -3, 38, -41, -5, 45,
- -37, -9, 30, -4, -35, 42, -10, -25, 19, -4, 3, -18, 12, 22, -43, 25,
- 14, -37, 21, 4, -19, 5, 17, -12, -17, 26, -4, -22, 11, 7, 6, -31,
- 35, -15, -14, 22, -14, 0, 0, 14, -16, -12, 31, -17, -19, 25, -10, 0,
- 2, 12, -23, 8, 16, -44, 37, 0, -19, -2, 21, -5, -25, 22, 12, -38,
- 3, 37, -11, -38, 36, 11, -54, 40, -9, -11, 14, -11, 11, -19, 17, 17,
- -47, 16, 25, -17, -23, 34, -3, -29, 25, -17, 5, 14, -17, 3, -4, 21,
- -23, -11, 35, -31, 7, 13, -17, 13, -6, 6, -22, 13, 5, -8, -8, 16,
- 8, -34, 18, 21, -49, 32, 12, -45, 32, 0, 1, -32, 27, 2, -20, 10,
- 6, 3, -26, 18, 19, -50, 31, 13, -40, 20, 12, -7, -19, 21, -9, -12,
- 24, -21, 6, 7, -6, -2, -9, 23, -19, -8, 15, -7, 18, -26, 13, 5,
- -21, 21, -19, 4, 25, -26, -14, 32, -2, -33, 21, 8, -29, 38, -35, 17,
- 8, -19, 15, -29, 24, 15, -40, 10, 28, -21, -26, 34, 7, -42, 35, -3,
- -14, -1, 18, -6, -30, 29, -1, -11, 8, -8, 16, -22, -2, 25, -27, 14,
- 0, -9, 1, 9, 1, -25, 22, -16, 12, 8, -33, 32, 2, -35, 19, 4,
- 0, -17, 15, 1, -6, 9, -15, 16, -30, 25, 8, -46, 40, 11, -39, 8,
- 11, 2, -21, 10, 11, -17, 15, -6, -4, -10, 18, -6, -23, 29, -2, -7,
- -13, 9, 24, -48, 23, 17, -30, 27, -22, 9, 4, -16, 8, 4, -9, -2,
- 19, -12, -12, 21, -22, 15, -8, -2, 20, -39, 32, -5, -16, 11, 5, -15,
- -8, 30, -5, -36, 34, -5, -13, 1, 3, 22, -37, 14, 6, -8, 0, -6,
- 11, -17, 23, -6, -18, 19, -7, -4, -14, 11, 17, -32, 24, -6, -2, 9,
- -26, 30, -24, 2, 18, -19, 7, 4, -6, -3, -1, 3, 1, 0, -21, 39,
- -20, -33, 51, -27, -6, 24, -18, 8, -10, 12, -3, -23, 25, -11, 5, -19,
- 25, 2, -34, 29, -5, -9, -7, 18, -12, -18, 30, -4, -26, 20, -9, 22,
- -32, 7, 26, -28, 6, -9, 19, -20, 5, 2, -9, 26, -15, -13, 18, -19,
- 15, -3, -26, 34, 2, -33, 6, 36, -36, -12, 36, -32, 29, -24, 10, 13,
- -39, 30, -6, -17, 12, 9, -9, -17, 28, -6, -27, 21, 4, -15, 6, 13,
- -13, -16, 30, -21, 1, -4, 4, 28, -60, 46, -3, -21, 3, 5, -8, 17,
- -17, 3, 11, -6, -9, 11, -8, -17, 44, -36, 0, 20, -9, -4, -13, 29,
- -24, 5, -3, 6, 14, -36, 26, -3, -23, 30, -3, -30, 25, 3, -12, -22,
- 42, -13, -27, 19, 9, -3, -20, 16, -7, -3, 7, -5, 6, -13, 22, -21,
- -15, 39, -17, -21, 30, -23, 19, -6, -20, 31, -24, 0, 8, 12, -31, 20,
- 8, -27, 20, -14, 20, -22, -2, 17, 0, -18, 11, 0, 7, -28, 22, -2,
- -19, 31, -17, -8, -2, 28, -24, -16, 34, -4, -28, 9, 26, -12, -30, 29,
- -7, -6, 10, -1, -10, 5, -3, 6, -23, 29, -18, 10, -16, 7, 28, -48,
- 21, 4, -12, 9, 4, -12, 5, -1, -7, 2, 0, -3, 11, -15, -3, 26,
- -19, -4, 3, 1, 10, -37, 49, -26, -9, 6, 18, -23, 0, 17, -3, -27,
- 25, 3, -22, 10, 6, -3, -19, 32, -23, 9, -3, -3, 11, -31, 27, 12,
- -42, 23, 13, -12, -18, 30, -10, -19, 13, -4, 0, 17, -25, 12, -2, -2,
- 4, -8, 9, -12, 8, -17, 24, -2, -19, 14, -16, 18, -6, -12, 22, -12,
- -17, 20, 0, -4, -13, 19, -5, -18, 30, -19, 8, -17, 19, -9, -6, 8,
- 1, 1, -36, 48, -9, -40, 46, 1, -50, 44, -5, -14, -3, 10, 4, -17,
- 11, -1, 11, -25, 9, 10, -24, 19, 2, -9, -4, 4, 10, -26, 20, -8,
- 6, -3, -12, 17, 7, -31, 18, -14, 17, -7, 0, 2, -8, 9, -15, 19,
- -16, 8, 2, -22, 21, 15, -33, 4, 24, -20, -13, 36, -18, -24, 33, -16,
- -8, 20, -19, 22, -32, 21, 0, -5, -7, 18, -17, -11, 26, -5, -25, 25,
- 3, -17, -3, 15, 7, -35, 22, -3, 2, -2, -6, 7, -3, -4, 4, -13,
- 25, -17, 1, -4, 7, -12, 13, -2, -11, 12, 2, -25, 24, 0, -25, 17,
- -4, 6, -9, 14, -11, -8, 5, 0, 10, -25, 23, 1, -28, 27, 5, -26,
- 0, 23, -11, -20, 21, 10, -30, 12, 9, -5, -16, 25, -12, -19, 26, -3,
- -12, 1, 9, -1, -15, 11, 3, -12, 6, -5, 11, -7, -8, 6, 3, -11,
- 4, 5, 0, -11, 7, -1, 6, -17, 1, 26, -35, 14, 6, -6, -8, 15,
- -7, -9, 13, -2, -20, 19, 6, -11, -14, 24, 7, -36, 19, 11, -24, 1,
- 23, -18, -4, 18, -10, -19, 29, -10, -9, -1, 6, 10, -23, 10, 19, -32,
- 11, 11, -4, -13, 5, 12, -17, 3, 13, -20, 11, 0, -8, 5, 14, -32,
- 19, 1, -22, 28, -16, -8, 13, 3, 0, -11, -10, 38, -40, 3, 22, -9,
- -16, 19, -4, -13, 13, 9, -29, 9, 16, -9, -20, 25, -2, -22, 11, 6,
- 4, -22, 12, 16, -35, 15, 26, -42, 13, 12, -5, -20, 24, -4, -18, 20,
- -7, -11, 9, 5, -7, 1, -2, -2, 10, -18, 9, 11, -17, -2, 7, -5,
- 28, -48, 12, 31, -36, 12, 8, -2, -14, 8, 2, -5, -1, 11, -17, -4,
- 21, -1, -27, 19, 3, -13, 0, 8, 15, -39, 19, 17, -43, 34, 4, -32,
- 16, 8, -10, -8, 21, -10, -12, 6, 9, -4, -10, 3, 9, -13, 8, 2,
- -7, 1, 1, 2, -18, 22, -10, 2, 5, -19, 19, -4, -11, 11, -5, 2,
- -13, 7, 15, -24, 9, 11, -20, -2, 21, 1, -38, 21, 9, -2, -22, 23,
- 6, -41, 34, -2, -19, 27, -10, -23, 20, -3, 13, -34, 20, 10, -15, -3,
- 14, -1, -19, 3, 4, 5, 8, -14, 9, -18, 18, -1, -22, 24, -8, -8,
- 10, -10, 14, -12, -4, 6, -14, 30, -38, 28, -5, -23, 19, 4, -10, -9,
- 22, -7, -22, 17, 8, -5, -19, 25, -9, -23, 31, -6, -26, 31, -20, 18,
- -29, 22, 20, -54, 33, -4, 1, -3, 4, -8, 0, -5, 13, -6, -6, 9,
- -1, -24, 36, -9, -26, 30, -24, 11, 8, -23, 22, -16, 5, -11, 20, -2,
- -26, 23, -9, -3, 0, 9, -10, -6, 13, -3, -17, 25, -12, -2, -8, 16,
- 4, -35, 39, -14, -9, -2, 23, -6, -37, 40, -12, -11, 4, 8, 1, -13,
- 1, 17, -26, 12, 10, -27, 17, 4, -6, -18, 42, -32, 2, 4, -16, 36,
- -31, 0, 10, 0, -1, -12, 15, 0, -28, 22, -3, -1, 6, -6, -9, -3,
- 25, -18, -8, 7, 6, 5, -39, 48, -16, -23, 22, -2, -8, 1, 18, -25,
- -9, 25, 1, -28, 16, 9, 0, -34, 37, -4, -27, 27, -18, -1, 6, 4,
- -5, -8, 16, -9, 10, -21, 6, 12, -14, -4, 6, 9, 3, -31, 33, -14,
- -12, 23, -28, 25, -10, 2, -11, 1, 11, 6, -30, 3, 40, -21, -34, 46,
- -12, -22, 11, 6, -2, -10, 14, -10, -21, 49, -29, -16, 17, 9, -15, -13,
- 32, -19, 0, 0, 8, 0, -14, 8, -4, -16, 30, -17, 2, -1, 0, 9,
- -15, 6, -4, 11, -15, -6, 28, -28, 17, -18, 7, 11, -19, 12, 3, -24,
- 21, 3, -29, 15, 26, -25, -27, 51, -18, -19, 7, 20, -21, -11, 36, -32,
- -3, 35, -27, -4, 6, 8, 2, -31, 18, 18, -29, 1, 25, -16, -8, 19,
- -30, 13, 16, -20, 8, -12, 19, -3, -21, 15, 0, -6, -3, 4, 6, 1,
- -20, 2, 20, -5, -27, 31, -7, -21, 19, 6, -19, -10, 40, -28, -17, 40,
- -15, -22, 12, 13, -23, 6, 14, -12, -7, 10, 11, -11, -30, 45, -9, -44,
- 48, -5, -14, -5, 20, -22, 9, 3, -10, 0, 4, 4, -7, -9, 24, -23,
- 3, 8, -15, 15, -2, -19, 21, -8, -6, -1, 14, -7, -12, 18, -10, -3,
- 3, 21, -37, 2, 29, -23, -7, 22, -10, -2, -7, 20, -10, -20, 15, 5,
- -25, 17, 23, -29, -16, 50, -35, -9, 19, 4, -22, 2, 24, -19, -10, 25,
- -9, -22, 23, 3, -15, -6, 10, -4, 13, -29, 17, 13, -26, -2, 25, -23,
- 14, -16, 12, -2, -2, 4, -11, 1, 11, 0, -22, 14, 18, -28, -6, 11,
- 22, -29, -10, 42, -30, -12, 26, -12, -15, 19, 15, -41, 10, 33, -16, -32,
- 20, 29, -47, 10, 36, -35, -1, 20, -19, 1, 9, 5, -14, -16, 15, 29,
- -38, -6, 35, -16, -20, 18, 6, -9, -7, 1, 4, 6, -4, 0, -9, 2,
- 8, 2, -14, -4, 24, -12, -32, 41, -1, -26, 1, 23, -22, 4, 11, -10,
- -6, 8, 16, -28, -12, 52, -28, -40, 53, 2, -29, 2, 17, -10, -5, -2,
- 8, -1, -13, 25, -10, -33, 51, -16, -32, 12, 29, -27, -11, 25, 7, -27,
- 4, 12, 0, -15, 5, -2, 4, -11, 11, 21, -51, 15, 37, -46, 7, 24,
- -9, -20, 2, 27, -11, -17, 4, 22, -40, 26, 16, -36, 2, 35, -32, -2,
- 12, 14, -23, -17, 26, 10, -26, 3, 20, -20, -9, 28, -16, -9, 19, -4,
- -21, 15, 12, -17, -15, 24, -7, -6, 5, -2, 10, -21, 4, 12, -9, -11,
- 30, -12, -32, 38, 3, -33, 11, 11, 0, -24, 4, 44, -37, -18, 36, -8,
- -25, 21, 5, -24, 10, -1, 18, -22, -2, 30, -38, -8, 41, -24, -3, 4,
- 8, -6, -11, 20, -11, -20, 22, -2, 2, -8, 8, -12, 8, -17, 11, 18,
- -34, 19, -4, 5, -3, -9, 5, -6, 6, -4, -6, 17, -5, -11, 2, 12,
- -8, -16, 15, 3, -21, 13, 8, -7, -8, 12, -5, -5, -17, 33, -1, -44,
- 35, 15, -42, 18, 15, -21, 4, -4, 10, -5, -14, 27, -21, -7, 19, 1,
- -3, -8, -6, 9, -1, -23, 29, -13, -1, -2, 4, 8, -6, -20, 26, -22,
- 5, 21, -25, 9, 3, -11, 16, -12, -4, 20, -20, -8, 25, -13, -5, 6,
- -11, 13, 6, -30, 13, 24, -31, -11, 27, 9, -43, 28, 2, -3, -5, -4,
- 13, -16, -1, 10, -8, -4, 11, 8, -23, 14, 0, -4, -10, 1, 14, -14,
- 3, 2, -3, 20, -35, 26, -6, -25, 38, -32, 12, -10, 16, -10, 14, -24,
- 9, 33, -83, 72, -13, -27, 28, -26, 25, -13, 8, -25, 18, 15, -29, 17,
- -3, 9, -25, 2, 19, -20, 18, -20, 13, 4, -18, 32, -32, -10, 35, -18,
- -12, 16, 10, -15, -5, 4, 13, -21, 1, 0, 14, -18, 9, 12, -26, 27,
- -27, 9, 1, -4, -1, 1, 14, -33, 52, -49, -1, 46, -50, 21, -5, 12,
- -9, -7, 6, 1, -2, -10, 14, -2, -10, 13, -19, 23, -26, 18, -2, -22,
- 34, -30, 8, 20, -38, 14, 18, -18, -5, 9, 3, -6, -13, 24, -1, -28,
- 12, 11, -14, -1, 21, -37, 31, -16, 5, 6, -26, 32, -23, 4, 2, 9,
- 2, -40, 40, -7, -10, 2, 0, 9, -16, -1, 16, -3, -10, -3, 19, -22,
- 6, 7, -9, -4, -10, 39, -38, 5, 27, -28, 0, 13, -8, 1, -3, 5,
- -3, -9, 13, -8, -4, 13, -14, -6, 22, -14, -13, 31, -30, 22, -15, -15,
- 55, -56, 6, 26, -23, 8, 1, 4, -17, 8, 6, -9, 9, -11, 15, -18,
- 5, 14, -18, 9, -22, 26, -2, -23, 25, -11, 1, -16, 15, 12, -28, -4,
- 35, -31, -3, 28, -8, -12, -8, 26, -21, -1, 3, -2, 12, -18, 18, -3,
- -6, -9, 14, -23, 9, 36, -57, 29, 21, -50, 29, -2, -13, 7, 0, -5,
- 6, -1, -4, 10, -25, 23, -3, -19, 28, -20, 11, -17, -5, 37, -39, 19,
- -7, 1, 7, -17, 12, 14, -36, 6, 23, -23, 9, 12, -19, 4, 2, 2,
- 6, -27, 14, 17, -39, 14, 34, -22, -31, 34, 6, -36, 28, -1, -28, 24,
- 1, -18, 24, -20, 9, -2, -15, 21, -4, -23, 23, -10, -4, 15, -12, 3,
- -6, 2, 10, -28, 28, -6, -15, 14, -14, 10, 1, -18, 14, 5, -19, 15,
- 2, -18, 22, -17, -7, 29, -43, 45, -15, -40, 62, -27, -23, 23, 10, -20,
- -20, 41, -7, -20, 9, 10, -22, 8, 5, 9, -21, 0, 22, -11, -18, 27,
- -4, -34, 30, 3, -9, -2, 1, 4, -13, 6, 16, -25, 11, -11, 8, 1,
- -11, 14, -4, -6, 4, 1, -2, -7, 1, -3, 11, -31, 57, -36, -10, 37,
- -44, 22, -2, -10, 4, -1, 7, -2, -7, 7, 14, -33, 5, 24, -29, 7,
- 10, -1, -13, 0, 26, -23, -16, 43, -32, -14, 23, 11, -23, -5, 13, 13,
- -44, 44, -7, -18, 7, -7, 12, -12, -1, -1, 7, 0, -6, 26, -37, 17,
- -6, 4, -19, 18, 13, -37, 24, 4, -7, 0, -13, 15, 3, -28, 22, 14,
- -41, 27, 5, -28, 38, -30, 9, -6, -1, 18, -28, 8, 26, -36, 4, 21,
- -3, -30, 28, -6, 1, -26, 45, -28, -15, 34, -15, -12, 6, 8, 1, -9,
- -16, 26, 1, -50, 65, -34, -12, 25, -9, 4, -14, 21, -17, -2, -6, 10,
- 17, -29, -6, 40, -23, -20, 27, 0, -40, 44, -27, 16, -6, 2, 3, -20,
- 15, 15, -32, -1, 28, -9, -29, 38, -22, 14, -21, 16, -5, -6, 17, -35,
- 20, 13, -19, 0, 2, 2, 16, -32, 0, 47, -61, 16, 31, -37, 21, -8,
- 6, -7, 3, -6, 8, -9, -12, 29, -13, -20, 33, -16, 0, -21, 46, -39,
- 2, 17, -3, -11, -6, 18, 2, -35, 29, 17, -37, 0, 42, -42, 9, -3,
- 16, -19, -2, 24, -17, -2, 0, -1, 6, -12, 19, -12, -16, 27, -2, -27,
- 16, 17, -42, 38, -22, 8, 2, -12, -1, 15, -18, 13, -6, -11, 7, 21,
- -36, 26, -23, 38, -48, 15, 26, -20, -18, 24, -1, -4, -20, 34, -16, -17,
- 18, 11, -30, 15, 7, -10, -10, 12, 15, -31, -1, 28, -6, -32, 30, 4,
- -24, 1, 28, -28, 7, -11, 33, -39, 23, -15, 19, -12, -12, 11, 4, -25,
- 33, -22, 14, -4, -3, -6, 10, -21, 31, -40, 19, 13, -10, -1, 14, -18,
- -3, 10, -4, -5, -2, 10, -6, -14, 21, 14, -40, 15, 6, 3, -31, 28,
- 12, -42, 11, 43, -44, 2, 27, -17, -18, 22, -16, 33, -59, 37, 15, -35,
- 11, 20, -22, 1, -7, 22, -22, 7, -1, 9, -16, -4, 20, 3, -38, 31,
- 9, -31, -3, 39, -34, 8, 4, -19, 41, -41, 11, 21, -40, 19, 18, -47,
- 45, -14, -5, -13, 26, -4, -28, 19, 15, -45, 38, -4, -9, -4, 17, -29,
- 28, -27, 34, -25, -20, 39, 5, -52, 49, -15, -13, 5, -3, 14, -2, -20,
- 17, -3, -12, 18, -7, -9, 1, 10, 7, -31, 19, 13, -29, 12, -22, 52,
- -30, -28, 40, 7, -60, 56, -19, -5, -5, 22, -26, 13, 1, 5, -28, 30,
- -12, 3, -17, 25, -26, 16, -16, 20, -5, -14, 26, -19, -33, 67, -47, 2,
- 20, -19, 21, -22, 12, 12, -25, 0, 17, -26, 24, -4, -15, 6, 9, -8,
- 13, -28, 24, -15, 13, -27, 26, 3, -11, -31, 61, -31, -19, 24, 5, -33,
- 22, -3, 14, -35, 22, 10, -28, 8, 23, -24, -2, 1, 18, -18, -8, 26,
- -15, -12, 26, -31, 15, 10, -24, 18, -19, 35, -32, -1, 15, 7, -40, 36,
- -14, -4, 16, -12, -22, 51, -54, 41, -31, 14, 4, -17, 5, 13, -24, 29,
- -31, 12, 25, -34, -2, 30, -36, 21, -16, 22, -4, -36, 42, -11, -6, -12,
- 31, -16, -29, 34, 6, -29, -4, 37, -23, -25, 51, -34, 9, -11, 23, -25,
- 14, -8, 5, -20, 32, -22, 6, 14, -16, -3, 24, -49, 51, -46, 31, -4,
- -21, 26, -13, 0, 7, -9, -2, -1, 8, -21, 22, -21, 29, -29, 10, 22,
- -41, 37, -24, -7, 15, 3, -25, 26, 1, -15, 5, 2, 14, -33, -3, 54,
- -69, 27, 13, 5, -37, 27, 4, -6, -19, 19, -3, -9, 2, 10, -11, 15,
- -30, 38, -35, 20, 0, -29, 37, -16, 1, -14, 21, -12, -7, 22, -33, 30,
- -19, 4, -7, -1, 31, -57, 46, -15, -8, 20, -21, -1, 18, -21, 17, -12,
- 6, 7, -20, 2, 32, -57, 46, -7, -25, 12, 25, -32, -3, 18, 1, -12,
- -15, 31, 4, -56, 52, -11, -6, -20, 23, 19, -50, 37, -7, -9, -1, 14,
- -22, 10, 14, -36, 37, -18, -8, 25, -31, 20, -16, 21, -26, 10, 7, -15,
- 9, 3, -14, 19, -25, 24, -15, -4, -4, 27, -37, 21, 7, -12, 1, -5,
- 4, 5, -12, -4, 10, -12, 17, -10, -16, 52, -56, 5, 29, -12, -5, -28,
- 56, -30, -19, 34, -3, -30, 20, 4, -21, 12, 9, -17, 21, -35, 43, -19,
- -20, 21, -4, -13, 12, -10, 9, 0, -6, -4, 10, -19, 25, -23, 6, -3,
- 10, -5, -15, 31, -12, -14, -4, 22, -15, -5, 1, 17, -17, -8, 28, -15,
- -8, 6, -10, 2, 7, 8, -31, 25, 3, -20, -2, 26, -10, -22, 12, 20,
- -25, 6, -11, 33, -36, -2, 43, -36, -8, 20, -9, -7, 2, 4, 5, -7,
- -5, 24, -28, 11, 6, -24, 20, -7, -2, 6, -9, -1, 20, -35, 13, 27,
- -31, -7, 31, -13, -12, -6, 27, -14, -24, 33, -6, -10, 15, -14, 6, -13,
- 9, 0, -8, -1, 19, -20, 6, 10, -9, -15, 23, -20, -4, 31, -24, 2,
- -13, 23, 1, -25, 14, 12, -16, -18, 25, 4, -25, 15, -3, 2, 6, -16,
- 21, -12, -19, 19, 1, -18, 21, 1, -30, 25, 3, -15, -5, 6, 18, -34,
- 4, 32, -13, -18, 1, 28, -21, -30, 44, -1, -41, 28, 16, -32, 9, 14,
- -17, 6, -11, 5, 21, -43, 38, -11, -24, 39, -15, -18, 18, -3, -15, 0,
- 20, -15, 2, -1, -6, 32, -43, 13, 19, -26, -3, 17, 10, -29, 19, 1,
- -19, 22, -13, 7, -16, 10, 8, -17, -1, 12, 1, -18, 1, 40, -49, 6,
- 34, -35, -8, 30, -2, -23, 4, 15, 12, -39, 2, 55, -57, -8, 47, -27,
- -7, 18, -7, 2, -11, 0, 19, -21, 4, 2, 10, -32, 34, -16, -12, 20,
- -12, 2, -4, 20, -12, -22, 22, -14, 9, -12, 6, 21, -24, -7, 27, -13,
- -22, 13, 16, -38, 37, -2, -21, 19, -14, 2, -6, 6, 7, -16, -11, 44,
- -22, -35, 52, -10, -41, 24, 16, -13, -19, 14, 21, -20, -29, 55, -20, -21,
- 5, 28, -30, -3, 22, -6, -10, 5, 11, -11, -7, 15, -11, -4, -10, 18,
- 1, -23, 24, 3, -24, 10, 5, 0, -32, 35, -7, -12, 1, 11, 18, -53,
- 36, 7, -26, 0, 24, -27, 0, 26, -24, 6, 6, -13, 16, -21, 13, 1,
- -25, 20, 26, -61, 40, 21, -41, -6, 28, 1, -24, -7, 38, -14, -25, 20,
- 5, -16, -1, 6, 13, -20, -7, 39, -33, -8, 25, -14, 5, -20, 26, 2,
- -28, 14, 14, -18, -23, 64, -60, 11, 24, -9, -13, -2, 17, -5, -25, 16,
- 22, -13, -44, 61, -14, -38, 35, -7, -18, 28, -16, -10, 25, -9, -20, 8,
- 6, 8, -23, 11, 19, -27, -1, 15, 0, -25, 18, 8, 2, -34, 38, 1,
- -41, 23, -7, 13, -6, -19, 45, -20, -27, 24, 14, -61, 53, -13, -13, 21,
- -21, 36, -25, -33, 58, -33, -26, 35, 19, -50, 7, 50, -35, -20, 28, 5,
- -29, -1, 28, -20, 3, -10, 20, -8, -16, 35, -22, -13, 17, -10, -3, 15,
- -25, 24, -7, 0, -8, -3, 29, -32, -7, 30, -16, 9, -29, 24, 10, -27,
- -9, 49, -40, 4, 14, -28, 37, -29, -18, 68, -67, 12, 45, -48, 3, 31,
- -21, -16, 9, 20, -3, -40, 38, 17, -65, 41, 8, -15, -9, -2, 46, -51,
- -7, 64, -51, -31, 57, -21, 5, -10, -7, 35, -36, 0, 20, -20, 14, -16,
- 10, 9, -1, -26, 26, -18, -3, 5, 14, -8, -17, 32, -25, 1, 17, -29,
- 17, 17, -47, 50, -19, -12, 9, -1, -11, 17, -29, 44, -25, -36, 63, -32,
- -18, 29, -7, 9, -38, 32, 14, -50, 21, 37, -57, 13, 37, -17, -16, -9,
- 28, -6, -60, 76, -13, -34, 29, 1, -5, 9, -41, 35, -2, -48, 52, -5,
- -3, -17, 14, 5, -12, -13, 24, -20, 7, -4, 10, 2, -13, 10, -2, -18,
- 20, 2, -33, 37, -18, -9, 25, -21, 14, -15, 9, -2, -14, 15, 10, -44,
- 37, 7, -36, 15, 18, -9, -21, 2, 45, -53, 3, 47, -48, 3, 25, -17,
- 14, -24, -2, 53, -72, 22, 38, -32, -13, 22, -15, 30, -36, 6, 27, -30,
- -4, 21, -3, -20, 8, 13, -3, -29, 43, -10, -41, 33, -14, 20, -22, 9,
- 13, -14, -10, 25, -30, 14, 6, -29, 29, 2, -23, 4, 14, -15, -3, 13,
- 11, -29, 21, -1, -25, 13, 5, 1, -9, -18, 58, -31, -44, 56, 7, -69,
- 46, -10, 11, -3, -27, 41, 1, -58, 46, 7, -33, 14, -14, 30, -22, -24,
- 77, -66, 6, 6, 27, -36, -2, 21, 10, -62, 57, 11, -46, 23, 7, -8,
- -18, 24, -21, 17, -35, 40, -4, -31, 36, -13, -10, 0, -2, 2, 0, 2,
- -14, 18, 22, -53, 11, 43, -45, -13, 39, -7, -12, -6, 22, -8, -27, 19,
- 15, -35, 13, 21, -30, 26, -35, 40, -17, -11, -5, 33, -25, -4, -9, 32,
- -10, -44, 65, -23, -18, 0, 28, -31, 17, -23, 45, -50, 11, 52, -68, 13,
- 23, -10, -32, 41, -13, 4, -13, 5, 9, -11, 4, -8, 6, 12, -25, 4,
- 24, -20, -15, 11, 30, -42, 5, 30, -7, -40, 27, 17, -27, -5, 14, 16,
- -26, -9, 39, -23, -11, 17, -16, 30, -52, 43, -9, -4, -28, 31, 4, -15,
- -15, 34, 6, -69, 65, -3, -40, 6, 42, -40, 8, 11, 18, -29, -28, 62,
- -40, -17, 31, 2, -22, 20, -13, 16, -18, 0, -6, 12, -4, -10, 17, 0,
- -6, -25, 44, -25, -6, 0, 24, -13, -33, 43, 1, -46, 36, 3, 0, -34,
- 38, -11, -14, 5, -11, 30, -19, 3, -12, 45, -56, -3, 41, -20, -21, 17,
- 22, -18, -15, 14, 37, -92, 53, 25, -48, -2, 57, -44, -4, 3, 35, -31,
- -32, 59, -24, -17, 9, 28, -39, 22, -10, 9, -7, 0, 7, -29, 33, -16,
- -17, 37, -24, -17, 43, -14, -28, 18, 18, -33, 5, 4, 21, -34, 13, 4,
- -6, 7, -15, 14, -8, 11, -17, -1, 15, 0, -42, 58, -18, -35, 37, 14,
- -47, 9, 27, -14, -33, 20, 58, -79, 11, 49, -18, -55, 58, -6, -29, 6,
- 12, 16, -55, 61, -29, -20, 37, -15, -1, 9, -26, 22, 3, -25, 0, 31,
- -18, -1, -12, 40, -11, -64, 62, -11, -23, 3, 32, -11, -18, 19, 5, -36,
- 15, 11, -21, 6, 18, -16, 5, 16, -35, 14, -2, 19, -53, 45, 31, -81,
- 31, 46, -51, -14, 44, -13, -23, -11, 67, -62, -3, 50, -23, -26, 24, 16,
- -34, -2, 3, 27, -33, 1, 38, -35, 13, 0, -24, 50, -59, 11, 31, -20,
- -6, 10, 20, -28, -15, 38, -2, -60, 43, 32, -68, 24, 47, -54, 9, 3,
- 23, -46, 11, 36, -56, 34, -2, -20, 12, 24, -36, 9, 7, 18, -45, 11,
- 45, -50, -10, 42, 4, -63, 62, -10, -22, -9, 26, 8, -52, 41, 14, -54,
- 41, -9, -8, 12, -26, 33, -25, 6, 3, -14, 20, -28, -2, 50, -23, -51,
- 64, 11, -86, 57, 17, -39, -5, 19, 41, -79, 33, 43, -64, 2, 40, -21,
- -7, -6, 38, -37, -8, 43, -39, 5, 16, 3, -49, 67, -38, -20, 39, -20,
- 10, -24, 43, -15, -47, 57, -13, -53, 59, -16, 8, -27, 35, -4, -36, 35,
- -29, 13, -5, 5, -13, 32, -5, -48, 57, -29, -15, 30, -26, 23, -34, 33,
- 25, -79, 54, 25, -70, 16, 33, -1, -60, 37, 52, -76, 7, 54, -22, -61,
- 76, -23, -30, 30, -15, 14, -21, 24, -4, -20, 23, 0, -49, 63, -31, -12,
- 28, -15, 9, -17, 26, -25, -1, 4, 15, -31, 22, 8, -23, 18, -8, -7,
- 6, -1, 7, -12, -1, 32, -62, 42, 14, -59, 41, 13, -31, -5, 40, -14,
- -49, 36, 38, -64, 1, 68, -54, -29, 61, -16, -29, 8, 37, -22, -33, 42,
- 18, -75, 47, 6, -25, 26, -33, 42, -32, 1, 4, 3, -2, 5, -20, 27,
- 4, -43, 33, 2, -27, 6, 26, -25, 8, 2, 19, -46, 26, 15, -56, 44,
- 12, -34, -4, 43, -34, -1, 2, 27, -40, -3, 52, -64, 26, 21, -30, -3,
- 30, 1, -37, 13, 27, -28, -31, 49, 4, -63, 61, 2, -23, -10, 22, 7,
- -53, 17, 43, -51, 21, 15, -26, 37, -31, -4, 9, 0, -28, 28, 4, -10,
- -5, 21, 2, -40, 32, 9, -50, 20, 43, -63, 32, -6, 13, -24, -4, 62,
- -87, 46, 12, -27, -14, 25, 13, -44, 25, 24, -29, -8, 13, 18, -56, 46,
- 6, -51, 55, -19, -10, -4, 17, 3, -52, 60, -3, -49, 41, -14, 0, -4,
- -3, 17, -9, -9, 1, 18, -11, -17, 3, 17, -5, -23, 15, 42, -83, 51,
- -1, -17, 6, -16, 57, -83, 48, 16, -46, 10, 24, -8, -32, 32, 15, -49,
- 26, 19, -24, -22, 40, 20, -80, 64, -11, -24, 14, -11, 17, -18, 18, -5,
- -21, 45, -36, -11, 24, -16, 5, -10, 32, -13, -17, 24, -15, -4, -8, 9,
- 0, -16, 33, -36, 36, -7, -39, 46, -35, 33, -61, 51, 10, -63, 50, 11,
- -34, -5, 39, -8, -46, 41, 6, -45, 22, 14, -4, -41, 74, -33, -44, 57,
- -19, -20, -12, 42, -4, -37, 30, 18, -31, 0, -1, 10, -16, 3, 8, 1,
- 9, -31, 21, -2, -11, -1, 3, 24, -40, 15, 31, -52, 20, -1, 13, -32,
- 31, 6, -44, 41, -17, -18, 21, 18, -32, -10, 41, -2, -60, 42, 9, -25,
- -9, 38, -10, -29, 40, -27, -7, 14, 8, -20, -2, 26, -11, -35, 42, -2,
- -36, 28, -1, 3, -33, 39, -7, -24, 9, 4, 4, -10, 7, -2, 0, 15,
- -52, 45, 4, -38, 14, 29, -20, -23, 39, -1, -38, 13, 23, -26, -1, 12,
- 2, -30, 41, -10, -30, 36, -3, -22, -6, 35, -20, -32, 27, 22, -41, 19,
- 23, -18, -18, 22, -5, -34, 39, -19, 5, -3, 29, -26, -21, 47, -38, -23,
- 38, -4, -15, 6, 19, -12, -4, 6, -14, 17, -14, -11, 22, 3, -20, -13,
- 38, -2, -52, 43, 16, -30, -19, 37, 1, -51, 47, 2, -23, -1, 22, -10,
- -24, 17, 21, -62, 51, 11, -38, 19, 8, -3, -50, 61, -18, -15, 4, 16,
- -9, -15, 29, -32, -2, 37, -43, 9, 35, -36, 13, -16, 28, -28, -5, 41,
- -35, -3, 12, 15, -29, 2, 19, -20, 19, -21, 7, 18, -20, 1, -24, 47,
- -17, -45, 54, 10, -43, 0, 37, -3, -63, 58, 4, -55, 43, -2, -6, -31,
- 50, -35, -10, 37, -12, -17, 1, 29, -34, -5, 31, -19, -10, 29, -26, 32,
- -44, 25, -5, -27, 43, -45, 33, 12, -29, -6, 38, -18, -34, 23, 18, -21,
- -12, 17, 27, -52, 18, 32, -49, 42, -19, -24, 40, -26, -7, 0, 32, -12,
- -44, 69, -18, -46, 21, 26, -41, -5, 49, -24, -8, 22, 0, -23, -17, 32,
- -6, -42, 64, -40, 17, 0, 3, -11, -28, 63, -61, 13, 26, -12, -7, 4,
- -5, 8, -2, -5, -14, 18, 13, -38, 6, 36, -7, -71, 86, -10, -56, 45,
- -11, -2, -18, 9, 26, -38, 24, 1, -24, 41, -35, -10, 24, -1, -24, 10,
- 25, -15, -20, 10, 36, -44, -32, 96, -69, -8, 44, -32, 12, -20, 33, -33,
- 11, 24, -24, -15, 40, -23, -27, 20, 18, -19, -4, 28, -23, 9, -9, 4,
- -19, 32, -27, -15, 59, -37, -17, 28, 2, -20, -12, 28, 20, -68, 46, 2,
- -24, 3, 6, 16, -28, 17, 8, -21, 1, 6, -21, 15, 34, -68, 43, 41,
- -81, 31, 10, -5, -28, 1, 51, -37, -21, 64, -40, -23, 44, -25, -12, 15,
- 7, -21, 14, 0, 6, -29, 29, 7, -39, 30, -10, 0, -4, -5, 13, 8,
- -24, 23, -28, 38, -27, -34, 50, -5, -33, 10, 55, -47, -22, 43, -3, -45,
- 11, 38, -37, 15, 16, -25, 24, -22, -4, 0, 4, 14, -41, 33, 35, -67,
- 13, 52, -57, 0, 25, -4, -7, -11, 18, 5, -37, 32, 2, -39, 54, -24,
- -18, 13, 16, -27, -2, 7, 31, -52, 29, 17, -41, 38, -23, -15, 28, -4,
- -28, 40, -13, -20, 8, 13, 0, -40, 37, 20, -53, 14, 39, -34, -21, 27,
- 14, -28, 12, 14, -23, 7, 3, -28, 24, 6, -23, 10, 9, 20, -39, -12,
- 61, -39, -44, 74, -24, -25, 21, 13, -31, 10, 11, -3, -21, 19, 7, -43,
- 46, -26, -2, 22, -16, 0, 13, -16, 10, -9, -20, 33, -30, 29, -2, -29,
- 44, -8, -62, 54, 13, -50, 8, 34, 7, -43, 9, 41, -34, -39, 54, -6,
- -28, 9, 20, -16, -6, 25, -30, -6, 45, -51, 4, 36, -21, -22, 28, 4,
- -25, 18, 6, -5, -33, 37, -9, -19, 14, 8, -5, -4, 5, -1, -13, 0,
- 16, -46, 49, -5, -25, 30, -8, -16, 15, -17, -4, 24, -26, 14, -8, 16,
- 3, -40, 16, 47, -78, 21, 65, -53, -20, 24, 26, -55, 6, 55, -47, -6,
- 35, -4, -28, 14, 1, -19, 15, -9, 20, -22, 19, -6, -31, 32, 7, -36,
- 14, 20, -18, -7, 9, 9, -27, 22, -15, 8, 9, -15, 2, -2, 9, -19,
- 11, 5, 11, -38, 38, -4, -35, 23, 17, -48, 34, 15, -51, 41, -2, -11,
- -30, 35, 20, -65, 33, 34, -37, -23, 48, -2, -48, 21, 19, -12, -34, 42,
- 8, -49, 33, 10, -27, 25, -15, -6, 9, -11, 7, -14, 22, -7, -11, 18,
- 4, -18, -12, 30, -40, 14, 16, -11, -2, 30, -36, 4, 20, -19, -25, 21,
- 17, -39, 38, -11, 13, -32, 19, 13, -49, 41, -2, -25, 8, 24, -23, -16,
- 41, -9, -44, 34, 28, -48, -15, 59, -22, -54, 64, -6, -10, -20, 29, 4,
- -56, 42, 7, -31, 20, 0, -5, 9, -3, -27, 33, -15, -18, 25, 5, -21,
- 10, -6, -4, 1, 5, 14, -42, 47, -10, -14, -15, 30, -6, -53, 64, -4,
- -33, 13, 27, -34, -16, 37, -4, -42, 38, 11, -35, 11, 17, -10, -33, 55,
- -35, -6, 14, 20, -35, -11, 63, -52, -17, 55, -22, -23, 19, -2, 0, -5,
- -10, 21, -5, -14, 12, 1, -10, 6, -15, 11, 13, -37, 43, -14, -17, 11,
- 10, -13, -28, 43, -15, -25, 35, 11, -45, 20, 25, -34, -21, 51, -16, -42,
- 35, 18, -23, -32, 75, -47, -18, 34, -1, -28, 1, 34, -40, 16, 23, -26,
- 4, 18, -22, -4, -7, 18, -8, -25, 41, 0, -24, 13, 9, -30, 14, -4,
- -14, 30, -18, 5, 9, -12, -3, -8, 25, -22, -18, 50, -18, -43, 48, 0,
- -39, 11, 27, -14, -26, 42, -10, -33, 4, 61, -72, 7, 58, -40, -22, 28,
- 24, -62, 19, 31, -22, -23, 41, -13, -16, 5, 11, -13, -4, 23, -21, 4,
- 7, -8, -20, 33, -19, -10, 26, -7, -13, 2, 18, -21, -10, 28, -20, -15,
- 54, -36, -26, 56, -30, -32, 42, -5, -21, 1, 40, -26, -19, 29, 7, -59,
- 34, 24, -43, 20, 3, 12, -36, 23, 23, -48, -1, 61, -49, -25, 62, -27,
- -23, 19, 13, -17, 4, 0, 9, -29, 19, -5, -7, 13, -9, 17, -7, 0,
- -14, 11, -5, -17, 2, 35, -29, -10, 45, -27, -21, 31, -9, -17, 12, 5,
- -10, -12, 26, 0, -37, 34, 6, -36, 18, 8, -2, -42, 39, 16, -47, 25,
- 37, -57, 1, 51, -59, 13, 19, -10, -10, 11, 11, -8, -32, 42, -19, -36,
- 59, -26, 1, -7, 17, -14, -2, -1, -2, 5, -5, 4, 0, 15, -25, -3,
- 30, -28, -15, 36, -13, -5, -13, 26, 2, -45, 41, 2, -38, 21, 20, -29,
- -11, 46, -27, -35, 46, 3, -38, 20, 25, -48, 19, 18, -26, 5, 3, 10,
- -17, -13, 46, -29, -27, 52, -40, 18, -6, 9, -14, -8, 21, -11, -11, 16,
- 14, -42, 33, 5, -31, 14, 0, -14, 19, -9, 11, -5, 2, 2, -39, 58,
- -35, -26, 47, -1, -40, 19, 32, -36, -14, 37, -2, -40, 18, 32, -47, -6,
- 49, -34, -7, 36, -16, -15, 2, 22, -36, -5, 53, -56, 27, 6, 2, -13,
- -8, 28, -40, 4, 22, -2, -33, 46, -14, -36, 51, -10, -47, 40, -2, -18,
- 3, 11, 13, -50, 57, -33, -5, 30, -31, -4, 19, -3, -17, 20, -2, -8,
- -16, 34, -6, -45, 30, 35, -73, 21, 55, -52, 3, 11, 19, -42, -2, 55,
- -57, 13, 23, -11, -16, 12, 16, -45, 25, 9, -22, -2, 37, -23, -29, 49,
- -24, -27, 46, -23, -8, 22, -14, 6, -26, 45, -42, -9, 41, -15, -12, 11,
- 13, -25, -1, 10, 9, -42, 37, -2, -20, 17, 14, -41, 25, 17, -52, 45,
- -14, 1, -23, 21, 30, -74, 44, 35, -53, -4, 42, -18, -36, 30, 9, -26,
- 17, 15, -18, -12, 37, -32, -25, 48, -27, -6, 20, -8, 12, -32, 38, -22,
- -17, 36, -18, -13, 15, 7, -22, 14, -3, 5, -21, 33, -18, -18, 17, 12,
- -31, 10, 34, -51, 33, -12, 15, -23, 1, 19, -50, 51, -7, -41, 47, 11,
- -56, 20, 30, -23, -34, 37, 17, -29, -14, 54, -25, -45, 50, -16, -17, 11,
- 14, -2, -30, 44, -16, -32, 39, -18, -16, 26, -5, -22, 25, -7, 1, -18,
- 27, -8, -21, 23, 0, -30, 16, 27, -54, 46, -1, -24, -9, 28, 8, -62,
- 48, 6, -31, 13, 17, -25, 17, -16, -1, 9, 2, 0, -15, 12, 19, -42,
- -2, 57, -56, -2, 47, -11, -40, 21, 38, -56, -22, 71, -26, -41, 52, 3,
- -29, 14, -1, -7, -20, 29, -3, -34, 41, -1, -35, 26, 12, -38, 25, -6,
- -4, 7, -9, 6, -14, 31, -24, -7, 24, 3, -47, 33, 9, -28, -7, 23,
- 18, -44, 22, 29, -48, 1, 46, -52, 14, 21, -21, -9, 26, 3, -41, 20,
- 34, -52, -14, 75, -39, -40, 53, 0, -35, 6, 29, -15, -36, 44, 0, -39,
- 36, -15, -11, 25, -9, -8, 6, 0, 1, -30, 29, -1, -17, 12, 20, -34,
- 17, 4, -35, 29, -4, -10, -8, 35, 0, -45, 34, 18, -77, 45, 22, -29,
- -9, 24, 14, -50, 29, 15, -34, -1, 47, -52, 3, 58, -54, -12, 40, -7,
- -28, 10, 33, -22, -50, 79, -24, -38, 25, 10, -5, -30, 27, 16, -42, 15,
- 14, -19, 11, 6, -33, 35, 2, -46, 49, -20, -7, 13, -4, 0, -12, 14,
- 3, -50, 58, -8, -44, 40, 17, -22, -41, 60, -13, -48, 25, 50, -62, -3,
- 71, -55, -12, 23, 3, -20, -1, 13, 20, -50, 48, -27, -23, 57, -43, -5,
- 8, 30, -34, -16, 51, -18, -42, 35, 19, -40, 23, 0, -35, 39, -23, 0,
- 21, -24, 16, -6, 2, 14, -53, 43, 1, -46, 51, -2, -19, 3, 25, -32,
- -11, 24, -1, -34, 25, 42, -74, 29, 42, -41, -34, 56, -3, -32, -26, 84,
- -35, -72, 101, -39, -13, 5, 24, -31, -2, 21, -25, 2, 22, 0, -37, 43,
- 2, -41, 23, -6, -9, 9, -7, 24, -19, -8, 24, -33, 31, -11, -37, 57,
- -25, -22, 35, -2, -29, 2, 26, -1, -39, 20, 51, -72, 14, 45, -45, -17,
- 49, -30, -12, 24, 25, -48, -23, 107, -96, -10, 61, -7, -47, 22, 34, -35,
- -13, 21, 17, -55, 40, 12, -43, 23, 6, -21, 19, -10, -4, 10, 3, -2,
- -35, 38, -7, -29, 31, 1, -15, 15, -11, 5, -8, -3, 10, -30, 40, 10,
- -62, 43, 30, -80, 22, 59, -63, -6, 42, 4, -35, -2, 67, -87, 21, 44,
- -44, -6, 34, -6, -39, 26, 28, -26, -47, 87, -25, -74, 69, 15, -63, 22,
- 19, 3, -13, -14, 36, -30, 1, 5, -9, 9, 3, -14, 29, -9, -25, 14,
- 6, -6, -38, 54, -12, -38, 46, 14, -70, 48, 19, -68, 37, 25, -27, -25,
- 29, 39, -81, 27, 50, -53, -12, 44, -4, -46, 23, 27, -32, -24, 67, -34,
- -36, 65, -33, -31, 52, -22, -23, 21, 8, 18, -61, 46, 14, -59, 26, 31,
- -49, 24, 11, -27, 30, -29, 8, -7, 20, -20, -4, 11, 0, -1, 0, -1,
- 0, -1, 1, -2, 2, -1, -4, -2, 1, 19, -2, -20, 3, -10, -11, 12,
- 3, -10, -3, 25, -4, 1, 6, 4, -12, 10, 2, -4, -28, -11, 9, 2,
- 1, 18, -9, -20, 12, 11, 10, 1, -5, 5, -15, 4, 7, -27, -3, 4,
- -8, 38, -31, -15, 7, 13, -34, 37, -6, -19, -6, 20, 41, -31, -20, 28,
- -13, 30, -4, 0, -23, -1, 0, -13, 21, 3, -32, 19, 30, -52, 18, -24,
- -27, 31, -14, 4, 1, -16, 14, 12, -20, 32, 14, -41, 37, -6, -5, 1,
- 27, -34, 42, 9, 2, -34, 20, -25, 11, 15, -10, -14, -19, -24, 5, -12,
- 3, -17, 2, 46, -13, -15, 31, -23, -16, 21, 25, -6, -36, 10, 1, 26,
- -18, -12, 1, 21, -8, 17, -16, -29, -39, 17, -5, -1, -4, -6, -18, 33,
- -21, 24, -17, 31, 0, 4, 0, 6, -26, 18, 24, 46, 5, 19, -10, 11,
- 25, -13, 10, 50, -50, -52, 21, -23, -29, -8, 34, -35, -39, 15, -16, -43,
- -5, -29, 29, -1, -8, -30, 18, 5, -14, 52, 12, -4, -28, 19, 25, 25,
- 16, -44, 53, -20, 49, -23, 25, -32, 1, -63, 50, 37, -52, -13, 13, 4,
- -18, 22, -56, 7, 23, -46, -7, 39, -69, -15, 26, 28, 21, 9, -64, 55,
- 23, -34, 46, -26, -9, 36, -31, 4, 5, 37, -58, 28, 49, -25, 20, -1,
- -12, -25, -6, 12, 9, -23, -34, 0, -2, 14, 3, -4, -13, 25, 23, -11,
- 1, -34, 6, 9, 30, -36, -19, 11, -16, 14, 76, -97, 33, 25, -50, 8,
- 25, -35, 20, -20, 4, -27, 63, -73, 25, 35, -22, 7, -33, 13, 2, 6,
- -3, 5, 1, 17, 1, -36, 40, -4, 10, -28, -9, 14, -16, 5, 20, -32,
- -45, 59, -10, 26, -29, -10, -13, -32, 44, -74, 81, -51, -12, 66, -11, -33,
- 17, 38, 12, 57, -39, 5, 39, 9, -4, 4, 0, 25, -50, 24, -19, -1,
- -30, -21, 24, -46, -20, -35, 19, -10, 1, -45, -7, 29, -8, -70, 51, -4,
- -51, 42, 20, 21, 21, -24, 7, 69, 1, 17, 10, 9, 8, 16, -8, 66,
- -32, -13, -24, 30, 50, -86, -15, 34, -23, -56, -26, 7, 22, -45, 23, -41,
- 50, -84, -19, 50, 0, 2, -20, -31, 49, -12, -8, 12, 63, -20, -23, 57,
- -37, 85, -57, -29, 83, -11, -15, -29, 25, -44, 33, -51, 74, -56, 63, -99,
- 72, 15, -40, -41, -29, 68, -66, 46, 12, 21, -65, 5, 62, -24, -24, -15,
- 7, -25, 7, -4, -16, 47, 13, -38, 3, 55, -31, -40, 31, -1, -35, 22,
- 4, 34, -6, -1, -12, 6, 75, -51, 12, 57, -19, -24, -5, 12, -10, 26,
- -13, 10, -44, 25, -13, -26, 39, -42, -25, -65, 36, -55, -41, -12, 2, 8,
- 22, 22, -24, -27, 51, -38, 36, 1, -14, -8, 88, 2, 15, 28, 6, 46,
- 8, 32, -22, 37, -29, 10, 3, -36, 9, -9, 2, 6, -15, -79, 32, -15,
- -26, -4, -29, -28, 7, 16, -29, -27, 3, 8, 2, 9, 5, 1, -13, 38,
- 16, 26, -16, 0, 19, -14, 20, -29, -3, 43, 17, -14, 39, -34, -15, 24,
- 36, -27, -1, 7, -55, 24, 50, -43, 21, 5, -5, -122, 78, -43, -33, 12,
- -12, 9, -45, -3, -1, -22, 37, -3, 17, -35, -11, 32, 5, 62, 0, -4,
- 20, 18, -33, 93, 2, -77, 45, 33, -29, -35, 45, -55, 48, -12, 15, -54,
- 16, -3, -50, 1, -21, -39, 16, -1, -33, -38, 19, -45, 9, 34, 26, -15,
- 21, 60, -32, 7, -2, 24, 21, 28, -19, -12, 7, 60, 23, -23, 7, -44,
- -54, 54, -17, -42, 38, -24, -23, 18, 9, -31, 4, 24, -26, -27, 33, -53,
- 15, 26, -38, 11, 13, -39, 24, 32, 19, 14, 16, -27, -24, 14, 14, 9,
- 6, -48, -8, -8, 60, -39, 1, -32, 51, -34, 0, 33, -16, -33, -10, 60,
- -40, -1, 3, 31, 50, -16, -32, -40, 45, -34, -8, 54, -80, 0, 19, 21,
- -21, 87, -70, -19, 23, 25, -56, 40, -33, 19, -44, -8, 7, -12, 18, -20,
- 22, -10, 18, 5, -7, 26, 33, -65, 49, -9, -9, 27, 22, 22, -37, 18,
- -19, -1, 61, -23, -39, 4, 4, -32, -3, 27, -39, -3, 38, -19, -12, -8,
- -37, 3, -10, -14, -37, 0, 4, 24, 1, 33, -35, 29, -2, 24, 24, -21,
- 23, -3, -31, 47, 12, -26, 35, -19, -17, 22, 20, -27, 1, -16, -18, 17,
- -2, -19, -22, 25, -2, -11, -3, -60, -2, 30, 64, -76, -7, -29, 45, 1,
- 46, -23, -43, 2, 43, 68, -38, -8, 45, -7, -8, 15, -47, -27, 71, -12,
- -3, -17, -54, -29, 75, -51, 8, -27, 12, -18, 60, -29, -42, 22, 51, -32,
- -27, 28, -11, 48, -34, 30, 26, -19, 20, 14, -16, 2, 7, -36, 70, -14,
- -21, -39, 82, -50, -49, 33, -28, 9, -17, -15, -51, 5, 7, -17, 58, -29,
- -33, 2, 29, 14, -46, 3, 28, 2, 28, -22, 7, -3, 28, 2, 40, -71,
- 2, 23, 24, 19, 11, -62, 56, 1, -24, -7, -10, -26, 30, -49, 18, -40,
- 52, -51, 46, -3, -28, -26, 40, 11, -5, 8, -46, 25, -10, 34, -25, 44,
- -17, -7, 12, 12, -28, -19, 30, -26, 6, -38, 13, 45, -43, 24, 24, -49,
- -13, 19, 3, 27, -5, -8, 5, -6, -4, 39, 7, 1, -38, 22, 20, -20,
- 19, -24, -50, 47, -11, -25, 32, -59, 17, 12, 35, -50, -14, -7, 15, 33,
- -15, 11, -45, 10, 14, 50, -68, -4, 11, -35, 20, 88, -72, 40, 16, -9,
- 3, 55, -44, 25, -24, 6, 14, -66, 9, 7, -10, 9, -7, 1, -42, -24,
- -26, 74, -5, -23, -44, 12, 11, 12, 57, -60, -19, 7, -2, 40, 3, -26,
- -14, 44, 29, 7, -23, 21, -32, 42, 13, -30, -16, 36, -9, 3, -21, 17,
- -67, 30, -4, 23, -19, 8, -32, 5, 31, -4, -26, 18, -24, 6, 39, -7,
- -24, -2, -5, 6, -3, 11, -10, -6, 16, -15, -15, 5, -19, -17, 38, -27,
- 35, -48, 7, -20, 4, 12, 1, -33, 28, -24, -2, 28, -10, -11, 23, -2,
- 5, 21, -5, 8, 0, 21, 12, -24, 36, -40, 36, 29, -2, -19, 1, 3,
- -8, 9, -11, -13, -31, 26, -5, 23, -26, -30, 1, 30, -19, -2, -15, 3,
- 5, 5, -3, 3, -43, 38, 16, -30, 18, 12, -1, -4, 20, -47, 11, 1,
- 21, -15, 1, 0, -43, -5, 37, -28, 11, -51, 21, 2, 20, -24, 22, -46,
- 34, -1, 7, 27, -12, -24, 28, 39, -4, 10, -19, 8, 6, 37, -26, 2,
- -12, -32, 36, 17, -11, -14, -26, -1, 17, 17, -53, -10, -11, 23, -16, -26,
- 10, -33, 1, 61, -5, -21, -14, -28, 50, 13, -41, 17, -12, 38, -19, 24,
- 36, -75, 16, 1, 58, -15, -19, -33, 56, -40, 39, -18, 1, 0, -34, 11,
- 32, -6, -52, 32, 2, 39, -31, -23, 0, -11, 10, -26, 55, -6, -51, 0,
- 36, -33, -14, -9, 30, -11, -5, 14, -17, 6, -34, 28, 16, -3, -21, 7,
- 25, 13, -30, 14, 12, 33, 3, -16, 9, -12, -17, 15, 2, 23, 14, -46,
- 1, 13, -4, -19, 6, 30, -53, -13, 1, -17, 13, -38, 11, 20, 1, -24,
- 19, -10, 7, -28, 48, 25, -59, -33, 51, 12, -4, -3, 13, -23, 64, 0,
- -5, -24, -6, 21, -27, 28, -19, -29, 51, -24, -9, -12, 3, -3, 35, 6,
- -33, -37, -5, 45, -47, 30, -16, -9, -10, 51, -31, 32, 10, -22, -10, 8,
- -13, -28, 8, 15, -25, 39, -36, 2, 50, -30, 36, -40, -14, 35, -9, -3,
- 12, -25, 36, -7, -20, -6, 48, -5, 31, -4, -18, -48, 67, -47, 26, -30,
- 6, 9, -14, -29, 3, 23, -12, -27, 29, -22, -36, -9, 51, -30, -18, -16,
- 47, -4, -25, 18, 16, 13, -11, 15, 10, 2, -36, 42, 3, -9, -21, 52,
- -19, 18, -34, -3, -11, 23, 19, -13, -17, -19, 16, -1, 0, -32, -1, -4,
- 25, 9, -37, -3, -9, 45, -15, -29, 36, 4, -29, -9, 35, 16, -36, -21,
- 25, -12, 10, -21, 25, 5, -17, -8, 12, 35, -56, 4, -15, 47, -32, -5,
- 18, 3, 11, 2, 7, 1, 1, -24, 23, 6, 7, -46, -37, 73, 12, -2,
- -20, 34, -45, 32, -23, 15, -40, -34, 12, 4, 13, -39, 3, 23, 17, -24,
- -15, 16, 19, -30, -9, 12, 53, -64, 1, 23, 40, -11, 8, 33, -36, 42,
- -68, 71, -16, -10, -41, 22, 16, -19, -18, 26, -2, 1, 4, -21, -3, -16,
- -4, 16, -31, 1, -26, -5, -8, 43, -69, 28, 14, 10, -16, 21, -18, -2,
- -14, 0, 32, 23, -28, -21, 68, 0, -40, 24, 32, 1, -10, 8, -20, 32,
- -37, 16, -3, 24, -10, -5, -30, 35, -39, 12, 6, -26, -2, -58, 65, -66,
- 13, -10, -6, -15, 28, -27, -39, 51, -28, 16, -10, 60, -51, 30, 51, -24,
- 11, -9, -7, 14, 39, -33, 4, -14, 25, -13, -8, 35, -40, -1, 27, -9,
- 11, -9, -13, 5, 19, -37, -12, 23, 1, -2, -31, 37, -7, -41, 35, 16,
- -6, -28, -8, 9, -23, 22, -8, 27, -17, -27, -10, 10, 12, -6, 11, -51,
- 21, -19, -29, 23, -10, -4, 32, 3, 25, 7, -25, 23, 35, -21, -2, -3,
- 23, -4, 14, 6, -8, -5, -6, 10, 10, 5, -38, -7, 16, -38, -2, 12,
- 8, -54, 5, 18, -12, -18, 23, 17, -52, 50, -78, 11, 4, 5, 19, 7,
- 27, -24, 5, 3, 35, -20, 34, -15, -10, 4, 21, 16, -14, 12, -8, -2,
- 42, -30, -22, 28, -9, -34, -11, 23, -36, 0, 15, -10, 14, -37, -7, -19,
- 30, -18, 15, -17, -14, -14, 51, -20, -8, 13, -12, 7, 35, 9, -12, -13,
- 48, 1, -2, -32, 13, -5, 1, 15, 40, -66, 18, 1, 49, -45, -38, -8,
- 14, -16, -2, 24, -13, -62, 15, 54, -28, -18, -3, 10, 13, -21, -18, -9,
- 44, -13, 8, 37, 6, -18, 4, 27, -18, 21, 3, -8, 13, 27, -19, 14,
- 2, -27, -11, -8, 17, -38, -26, 29, -31, 5, -7, -5, -9, -4, -11, 9,
- -3, -5, -18, 16, 3, 0, -8, -2, -6, -1, 58, -11, 12, 2, 31, -21,
- 13, 27, -17, -23, 54, 18, -33, -7, -7, 3, -2, -25, 15, -1, -25, -41,
- -13, 46, -71, -15, 40, 10, -14, 0, -10, 18, 0, -31, 25, -8, -10, -13,
- 24, 30, -9, 6, 4, 26, -3, 5, 31, -25, 0, -7, 16, 20, -1, -12,
- -22, 11, -10, -3, -26, 12, 3, 2, -17, -31, 4, -26, 15, 13, 6, -22,
- -5, 5, 8, 11, -23, 17, 17, -33, 0, 12, 21, -20, -3, 20, 21, -7,
- -20, 38, 20, -27, -16, 3, 7, -8, -3, 0, 22, -38, -37, 26, 23, -26,
- -8, -5, 0, -12, -2, 30, -8, -4, -2, -13, 15, -24, -4, 29, 10, 32,
- -7, -57, 48, -13, 41, -13, 16, -20, -20, 33, -13, 26, -17, -18, 20, 10,
- -44, 18, 2, -18, 3, -13, -5, -25, -16, 7, 30, -32, 8, -34, 19, -5,
- 23, -28, 12, -4, -14, 30, 1, -2, 15, -20, -16, 44, -2, 34, -31, 36,
- -25, 15, -3, 13, -10, -36, 39, -5, 0, -16, 1, 27, -28, 24, -26, -8,
- -12, -16, 25, -2, -12, -28, 16, -17, 7, -24, 31, -15, -8, 31, -22, -7,
- 0, 14, 16, -17, 8, -15, 24, -3, 17, -14, 6, -4, -22, 22, 9, 1,
- 3, -21, 18, -8, 11, 0, 10, -3, -12, 3, 15, -15, 1, 2, -13, 3,
- -23, -3, 15, -11, -5, 9, -30, -6, -10, 27, -2, -9, -12, 10, 4, 0,
- -16, 16, -10, -27, 51, -5, -4, -1, -4, 5, 38, -18, -11, 17, 1, -2,
- 8, 0, -7, 6, -6, -4, 9, -12, -11, 11, 1, -14, 1, -31, 13, 3,
- -28, 12, 24, -30, 7, -6, 5, -4, -6, 8, 1, 14, -19, -1, 32, -22,
- -9, 34, 6, -9, -9, -5, 15, 6, -25, 14, 6, -41, 0, 10, 2, 12,
- -18, 6, 5, -1, -16, 4, 26, -33, 5, 4, -4, -9, 5, -2, 14, -10,
- -11, 16, -6, 11, -5, -15, 14, 18, -19, 21, -24, 13, 6, -13, 21, -12,
- -11, -2, 10, -6, -7, -13, 12, -13, 1, 10, -7, 2, -2, -21, 24, 5,
- 2, 5, -24, 17, -17, -15, 9, 20, -12, -9, -15, 14, -1, -2, 14, -13,
- 5, -32, 21, 10, 7, -11, 24, -1, -23, 24, -25, 31, 7, -16, -2, -4,
- 9, -19, 17, 4, -27, 22, 21, -28, -6, 32, -48, 6, -4, 20, -6, -41,
- 11, 31, -16, -14, 2, -8, -13, -13, 35, -15, 15, -20, 1, 26, 7, -13,
- 18, 5, -19, 11, -7, 20, 22, -35, -11, 20, -24, 21, -20, 34, -15, -17,
- -8, -2, 16, -9, -12, 2, 20, -31, 24, -21, 2, 12, -27, 28, -10, -5,
- 24, 7, -29, 4, 6, -24, 33, -4, -8, -16, 1, 32, -28, 13, 7, 2,
- -10, -38, 30, 2, -18, -2, 17, 13, -6, -46, -1, 61, -48, 18, 10, 2,
- -17, -13, 8, 27, -8, 0, 11, -5, 20, -39, 4, 19, -8, -13, -15, 29,
- -36, 29, -16, 14, -25, 17, -14, -15, 18, 5, 3, -5, -2, -19, 31, -12,
- 14, -23, 31, -24, -4, 0, 4, 2, 11, -15, 22, -27, -4, 9, -8, 22,
- -2, 7, -33, -12, -3, 30, -3, -10, 12, -19, 2, -9, 16, -4, -15, 5,
- 32, -13, -13, 22, -11, 1, 3, 18, -12, 3, -17, 16, 15, -36, -2, 10,
- -12, 9, -29, 14, 12, -23, 5, 39, -20, -39, 13, 14, -13, 2, -16, 43,
- -25, -1, -12, 19, 11, -27, 0, 28, 3, -3, -15, -1, 10, -31, 43, -6,
- 5, -10, 4, -18, 24, -6, -14, -8, -5, 4, 1, -5, -20, 21, 5, -19,
- 22, -8, -13, -3, 20, -10, 20, -12, -7, 11, -11, -15, 6, 3, 24, -9,
- -4, -3, -4, -20, 44, -12, -15, 4, -3, -6, 2, 9, 3, -17, -7, 9,
- -2, 2, -22, 18, -8, -2, -10, 4, 6, -1, -4, 9, -1, 6, -9, 8,
- 2, 4, 4, -6, 17, -32, 11, -1, 21, -7, -29, 12, 2, -35, 28, 12,
- -15, 15, -43, 37, -30, -4, 2, 27, 8, -22, -1, -13, 20, -28, 36, -6,
- -12, -4, -8, 14, 2, -12, 5, 12, -3, -11, 3, -1, 2, 18, 12, -11,
- 4, -31, 13, 10, -10, 12, 7, -35, 10, -17, -3, 12, -5, 2, 0, -23,
- 7, 5, -4, 23, -30, 2, 4, -3, 18, -16, 17, 16, -12, -3, -14, 17,
- -1, -5, 9, 19, -23, 11, -8, -19, 34, -7, -13, 1, 3, 19, -23, -15,
- 19, -17, 5, -24, 16, 4, -5, -7, 7, -2, -20, 4, 15, 21, -29, -7,
- 16, -3, -17, 9, 3, 15, -15, -5, 12, -14, 8, 21, -15, 12, -18, -1,
- 17, -19, 2, 16, 16, -11, -30, 22, -12, -12, -1, 21, -28, 29, -30, -6,
- 19, -14, -5, 0, 10, 18, -8, -15, -1, 7, -15, 28, -3, -3, -9, -8,
- 0, 6, 18, -32, 7, -3, -11, 6, 30, -42, 32, -13, -8, 5, 8, 8,
- -15, 3, 4, -22, 27, -6, 6, -11, 1, -6, 13, -5, 2, -12, 29, -30,
- 10, -15, 18, -19, 8, 21, 1, -28, 15, -20, 25, -25, -1, 11, -2, 1,
- -22, -3, 15, 1, -22, 18, 16, -24, 1, 19, 6, 9, -7, -22, 8, -6,
- 2, 14, -9, -4, -13, 10, -12, 13, 0, -11, -12, -2, -6, 20, -9, 4,
- 5, -14, 3, 9, -2, 13, -5, 0, 14, -17, -1, -3, 8, -6, 7, 29,
- -19, -13, 3, 27, -17, -8, 11, -2, -14, -9, 7, -3, -9, -14, 24, -12,
- -35, -13, 40, -10, 1, -7, 1, 2, -1, 1, 16, 3, -13, -11, 30, 2,
- -9, 0, -9, 2, 15, -9, 8, 3, -19, 12, 5, -21, 5, -6, 16, -4,
- 7, -4, -2, 9, -35, 27, -6, 0, -12, 15, -29, 8, 2, -7, 4, 1,
- -15, 28, -15, -13, 18, 4, -1, 1, -4, -7, -16, 21, -11, 25, -19, 2,
- -10, 20, -32, 11, 6, 6, -15, 22, 8, -25, -13, 5, 20, 13, 7, -23,
- -6, 7, -4, 4, 0, -7, 3, -10, -4, 9, 1, 3, -8, 2, 16, -22,
- -7, -3, 12, -4, -4, 8, -10, 6, -13, -5, 3, 3, 6, 4, 4, -9,
- -27, 1, 16, 17, -15, 0, -12, 15, -2, -6, 10, 3, -16, -16, 22, 13,
- -12, 4, -4, 7, 11, -12, -14, 15, -1, 3, -12, 7, -7, 12, -14, 9,
- -9, 2, 2, 9, -12, -17, 12, -17, 14, -2, -18, 2, 16, -5, 1, 8,
- -5, -12, 0, -3, 21, -2, -17, 10, 10, -4, -16, 6, 15, -1, -25, -11,
- 18, 0, -11, 8, 15, -16, -18, -4, 39, 3, -30, -6, 22, 2, -22, 2,
- 21, -9, -9, 12, -3, 19, -24, -12, 20, -8, 4, 3, -3, 15, -20, -3,
- 14, -7, -4, -14, 9, -8, 0, 7, -6, -8, -4, -3, 4, 13, -18, 0,
- 9, -2, 5, -4, 10, 3, -9, -6, 9, -3, 1, 4, -3, 4, -11, 2,
- -3, 5, 11, -13, -1, 4, -7, 1, -11, 1, 17, -17, 2, 13, 1, -21,
- -2, 7, -5, -4, -5, 16, -5, -7, 4, 8, 8, -14, 4, 8, -7, -1,
- 5, 2, -11, -9, 9, 6, -10, -2, 6, -7, -2, -1, 15, -17, -4, 5,
- -2, 2, -3, -5, 11, -3, 1, 16, -12, -3, -7, 6, 5, -4, 5, 0,
- -3, -15, 5, 3, -8, 9, 3, -8, 1, -6, -4, 0, -7, 21, -18, 9,
- -8, 11, -2, -10, 10, 1, 14, -19, -11, -7, 18, -7, 4, 6, 2, -15,
- 2, 4, 5, -3, 0, 0, 12, -2, -15, -4, 18, -7, -9, 18, -7, -6,
- -9, 4, 7, -21, 11, -18, 14, -5, -4, 8, 5, 4, -3, -4, -11, 11,
- -15, 19, 2, -18, 8, -4, -13, 18, 3, -14, -3, 9, -11, 2, 10, -9,
- -5, -1, -15, 13, 16, -9, -4, 29, -15, -14, 6, 9, -1, -15, 12, 12,
- -6, -6, 13, -10, 18, -14, 7, -12, 5, -9, -12, 16, -6, -16, 7, -1,
- -22, 8, 2, -1, 9, 4, -31, -9, 12, 14, -9, -5, 17, -25, 7, 0,
- 13, 4, -1, -17, 10, 13, -7, -11, 17, 2, -23, 27, 5, -10, -3, 13,
- 5, -5, -5, -4, 0, -3, -5, 3, 4, -9, -7, 5, 4, -13, -10, 1,
- 7, -4, -2, -3, -5, 15, -9, 0, 1, 12, -17, -6, 32, -15, -16, -11,
- 20, 0, 2, -11, -5, 25, -21, 3, 10, 15, -24, -4, 8, -5, 0, 15,
- -1, -7, 1, -18, 21, -7, 3, -12, 0, 12, -10, 6, -3, -2, 2, -1,
- 9, 1, -9, 7, -9, -4, 9, -16, -4, 8, -10, 4, -3, -2, 13, -9,
- 4, -16, 4, -3, -5, 14, 7, -8, 2, 9, 0, -2, -12, 7, -3, 2,
- -4, -15, 11, -8, -11, -4, 23, -5, -1, 4, -9, 7, -4, 7, 8, -13,
- -6, -4, 16, 10, -11, 8, -1, -1, 2, -5, 0, -3, -6, 2, 3, -6,
- 13, -19, -9, 19, -11, 6, -12, 12, -10, -3, -11, -10, 14, 2, -19, 14,
- 4, -6, 4, 11, -7, 3, -3, -8, 24, -18, 6, -8, 15, -14, -7, 19,
- 0, -11, -3, 2, 2, 0, 2, 6, -7, -22, 16, 0, 11, -12, 7, -12,
- 10, -16, 4, 8, -11, -11, 4, 16, -19, 13, 1, -19, 12, 19, -15, -4,
- 9, -8, -13, 5, 14, -12, 5, -21, 7, 4, 11, -19, -1, 15, -16, -3,
- -12, 14, 1, 1, 15, -6, -13, 7, 0, 6, 4, -11, -3, 10, 14, -20,
- 7, 3, 1, 5, 17, -17, -5, 3, -4, 6, -1, 3, -18, 10, -10, 0,
- 0, 14, -18, -19, 17, -23, -5, -1, 4, -4, -2, 1, -13, 26, -15, 2,
- -10, 3, 13, 0, -6, 3, -4, 3, 0, -2, 9, 2, 9, -14, 23, -4,
- -10, 15, 7, -16, 0, 9, 3, 0, 14, -12, 0, 4, -10, 1, -11, -13,
- -6, 15, -14, -7, 2, -20, 4, -7, 9, -3, 2, -14, -1, 1, -1, 9,
- -18, 10, -1, 1, -3, 22, 1, -1, 5, -4, 10, 2, 5, 0, 3, -2,
- -1, 5, -2, -3, -5, 10, 2, -16, 2, 3, -1, -1, -11, 7, 6, 0,
- -10, 10, -7, -2, -15, 15, 4, -25, 0, 4, 4, -12, 0, 5, -7, -6,
- 6, 6, -8, 1, -1, -7, 17, -9, 2, 8, 4, -6, -6, 19, -5, -11,
- 12, -12, 3, 3, -5, 9, 11, -26, 0, 0, 7, 5, -8, 11, -5, -6,
- -16, 7, 12, -10, 0, -6, 7, -8, 3, -4, 11, -9, -16, 13, 18, -18,
- 2, -5, 7, 5, 0, -1, 4, -9, -13, 18, 5, -4, -14, 1, 7, -5,
- 4, -9, 15, 3, -10, -4, 5, 3, -11, -17, 18, 4, -9, -3, 3, -5,
- -11, -3, 0, 7, -1, -8, -2, 6, -7, 7, -3, 6, 3, -12, 15, -5,
- 23, -12, 8, -12, -4, 10, 1, 4, -3, 0, 0, 8, 0, 1, 11, -27,
- -9, 9, -4, -3, 12, -19, -2, -8, -6, 1, -1, 2, -12, 5, -11, 3,
- -1, -1, -10, 18, 0, 3, 2, 4, -5, 11, -3, 9, -2, -5, 7, -6,
- 8, 10, 2, -1, -8, 1, -16, 2, 9, 1, -4, 0, -15, -5, 6, -14,
- -9, 14, -22, 3, 7, -1, -2, -2, 0, 1, -2, 1, 9, 0, 7, -1,
- 6, 4, 0, -6, -2, 2, 4, -9, 11, 1, -25, 9, -6, 5, 0, -7,
- -8, 3, 5, 1, -2, 3, -9, -5, 7, 14, -12, 3, -10, 10, 3, -16,
- -3, 26, -8, -9, -2, 15, 0, -21, 8, 11, -17, 3, 8, -8, 10, -19,
- -3, 8, -4, 6, -10, 3, 4, -6, -4, 6, 0, 4, -19, 9, 3, -7,
- 17, -7, 2, 3, -27, 12, 5, -14, 5, -6, -6, 6, 11, -11, 6, -12,
- -2, 9, 8, 1, -18, 18, -9, 0, 13, -8, -10, 24, -11, 4, 13, -4,
- -18, -3, 2, 9, -7, -1, 4, -6, 0, -11, 5, -1, -1, -8, -10, -6,
- 6, -15, 20, 6, -25, 11, -5, -7, 12, 4, 0, -6, 6, 2, -1, 5,
- 1, -11, 9, 20, -11, 14, -6, -15, 11, -11, 7, 1, -5, 2, -8, -2,
- 12, -5, -16, 8, -4, -10, 2, 2, -6, -8, 5, 0, 3, 4, -17, 13,
- 4, -9, 1, 5, 4, 8, -7, -3, 3, -2, 4, 14, -9, -6, -7, -3,
- 11, -17, 0, 9, -10, 0, 1, 0, -9, -7, 8, 7, -3, 15, -22, 2,
- 7, 0, 2, 4, -2, -6, -3, -1, 9, 2, -2, 1, -4, -1, -6, 2,
- 4, -8, 3, -2, 1, 0, -9, 14, -6, -5, 3, -1, -6, 5, -5, -6,
- 5, -5, -1, 12, -10, -6, -3, 9, -7, -8, 14, -5, -11, 9, -1, 5,
- -5, 3, 1, 0, 1, 3, -7, 7, -1, 1, 4, 5, -16, 7, 6, -6,
- -2, 11, -8, -9, 3, -9, -2, 15, -11, -11, 6, -1, -7, -4, 4, 2,
- -9, 1, 1, -2, 0, 6, -3, -3, 6, -7, 6, 11, -11, -9, 0, 15,
- -8, 14, -2, -13, 1, 4, 0, 7, -2, -10, -1, 8, -6, -4, 5, 1,
- -6, 1, -8, 0, -4, 7, 4, -3, -8, -4, -3, 8, 3, -8, -3, 16,
- -7, -1, 0, -1, -4, -2, 2, 6, -1, -2, -4, 5, 5, -4, -2, -8,
- -6, 10, 4, -5, -2, -2, -2, 0, -4, 0, 2, 0, -12, 6, 2, 0,
- 3, 2, -11, 2, 1, -2, 10, 1, -6, 9, -8, -3, 5, -1, 5, -2,
- 0, -5, -7, 8, 5, -4, -9, -1, 1, -2, -7, 4, -12, -4, 5, 0,
- -4, 5, -13, 8, 2, 4, 1, -10, -6, -3, 17, 4, 1, -7, 6, 2,
- 1, -3, -1, 0, 7, -8, -2, 6, 2, -8, 0, 21, -16, -5, -1, -2,
- 4, 0, -18, 11, -10, -4, 11, -4, -1, -2, 2, -3, 2, -2, -8, -1,
- 1, -3, 8, 2, 0, 1, 5, -7, 2, -4, -1, 4, 5, 0, 1, -6,
- -11, -6, 7, 8, 5, -7, -12, 7, 2, -6, -3, 7, -4, -3, -1, 2,
- 9, 0, -7, 9, 5, -15, -3, -7, 2, 3, -2, 0, -3, 6, -13, -2,
- 0, -5, 3, 9, -5, 9, -12, -9, 12, 4, 1, 5, 3, -4, -2, 3,
- 11, -16, 2, 0, 10, -9, -4, 8, -4, -7, 2, 2, -6, 3, -22, 8,
- 11, -7, -6, -2, -5, -5, -8, 3, 7, 12, -8, -1, 4, 8, -14, 4,
- 13, -6, -8, 2, 17, -1, -3, 12, -10, -2, -7, 0, -6, 16, -17, -4,
- 10, -9, -2, 1, 0, -1, -7, 7, -10, -3, 3, -1, -7, 11, -11, 3,
- 3, 8, -6, -2, 1, 0, -15, 15, 5, 0, 7, -5, 4, -3, -2, 2,
- -4, 10, -9, -9, 15, -6, -12, 14, 3, -7, 0, -9, -1, -5, 3, -4,
- 3, 4, -14, -2, -1, 8, -3, 13, -5, -18, 12, -1, -7, 0, 5, -2,
- -6, 14, 3, -9, 3, 1, -10, 0, 7, 3, -7, 4, 2, -14, 4, 4,
- -6, 14, -4, -12, 6, 2, -10, 1, 5, -6, -10, 3, 8, -11, 9, -1,
- -3, 2, -6, -8, 4, 2, -10, 6, 11, -7, 0, 2, 1, -10, 8, 6,
- -5, 2, -2, 3, -4, 1, 4, -11, 6, 4, -8, 4, 4, -13, -4, 2,
- 6, -3, 2, -4, -11, 11, 2, -13, 9, 3, -21, -2, 17, -4, -1, 6,
- -11, -2, 1, -4, 4, 5, 0, 0, 1, 13, -8, 0, -3, 2, -6, 1,
- 7, -4, 2, 2, -5, -5, 8, -14, -4, 8, -10, -1, 3, -4, -6, 6,
- 5, -12, -6, 5, 1, -4, 2, -4, -1, 8, -8, 1, 8, -4, 6, -1,
- 17, -8, -7, -1, 4, -1, 14, -5, 0, -6, -1, 0, -1, 2, -10, -7,
- 0, 6, -6, 4, -12, -1, 7, -5, -2, 0, 3, 0, -9, 10, -8, -1,
- -5, 11, -15, 6, 6, -1, 1, 1, -4, 4, -7, 12, -11, 10, 2, -15,
- 5, 11, 5, -7, -7, 0, 0, -5, 11, 0, -5, -10, -12, 15, 1, -2,
- -4, 2, 6, -9, -8, -3, -1, -5, 5, -4, 1, 5, -13, -1, 10, 0,
- 0, -2, 1, 9, 0, 3, -7, 14, -2, 0, -2, 3, -12, 9, 4, 0,
- -4, -7, 0, -6, -5, 5, -3, -5, -5, 4, 7, -13, -7, -6, 3, 1,
- 0, 6, -3, -5, -4, 7, 1, 3, 1, -3, 5, 3, 3, 2, -1, 2,
- 4, -9, 8, 2, -5, 6, -12, 7, -5, -8, -6, 9, -14, 4, -7, 4,
- -6, 1, -2, -11, 4, -4, 2, 7, -4, 4, 5, -2, -4, -5, 6, 2,
- 0, 5, 9, 3, -4, -7, 1, 6, 3, -2, -7, 1, 1, -6, 0, 8,
- -12, -11, 7, -12, 0, 2, -5, 4, -1, -9, -2, 7, -8, 1, 1, 5,
- 1, -4, 5, -8, 4, 2, -5, 7, 6, -6, -3, -8, 13, -2, -3, 2,
- 0, 0, -5, 6, 5, -6, -3, -3, 2, 8, -12, 4, 7, -12, -10, 13,
- -3, -2, 1, -5, 1, 1, -2, 5, -5, -6, -12, 4, 0, 4, 3, 3,
- -10, -8, -3, 10, -5, 7, -8, 3, -1, 6, 0, 3, 6, 4, -6, 2,
- 5, 5, -6, -4, -2, 4, -2, -9, -4, 7, -1, -12, 10, -5, -9, -11,
- 1, 4, -8, 1, 7, -3, 4, -7, -1, 8, -5, -6, 9, -1, 0, 8,
- 3, 7, -9, 6, -1, 9, -7, 2, 3, -4, -5, 6, -6, 8, -10, -12,
- 4, 3, 1, -1, -9, -1, -4, -5, -3, 6, 7, -11, -4, 6, 0, -3,
- 3, 4, -5, -4, 1, -3, 3, -2, 0, 1, -1, 3, -9, 7, 3, -7,
- -2, 5, 5, -9, 7, 0, -8, 8, 1, -5, 6, -4, -6, 2, 6, -3,
- 0, 0, -3, -9, -6, -2, 9, 2, -2, -11, 7, 9, -9, -7, 8, 0,
- -7, 1, 4, -5, -3, -3, 5, 5, -3, -13, 7, 5, -6, 5, -2, 7,
- -9, -8, 6, 2, -5, 3, 7, -4, -6, -7, 1, 7, 6, -5, -5, 6,
- -10, 10, 1, -4, 4, -4, -2, 1, 9, -10, 0, 4, -8, -1, -5, -1,
- 3, -2, 6, 1, -5, -5, -5, 2, -3, 3, 3, -1, 0, -4, 0, 9,
- -1, -6, -6, 4, -1, 2, 5, 0, -2, -2, -4, 2, 4, -1, -4, 4,
- 0, -3, -9, -2, 6, 0, -7, -1, 3, -2, -1, 2, 2, -7, -2, 0,
- 2, 4, -6, 3, -3, 6, 0, 0, -2, -6, 1, 11, -2, -1, -8, 3,
- -7, 1, -2, 6, -9, 6, 0, -1, 1, -6, -7, 5, -1, 2, -2, -1,
- -1, 0, -3, 1, 2, -1, -3, -5, 3, 7, -9, 5, 3, -5, -5, 5,
- -1, 0, 4, 4, -11, 8, -3, -10, 9, -7, -1, 1, -2, 1, -3, 6,
- -3, -5, 2, 4, -7, 5, 2, -2, -3, 1, -2, -4, 2, 0, -4, 8,
- 2, -12, 0, 6, -10, -2, 8, -6, -3, 6, -4, 2, 9, -4, -7, 2,
- 5, -1, 1, 4, 0, -5, 2, -7, 2, 4, 1, -5, -1, 7, -5, -5,
- 12, -7, -12, 6, -4, -3, 3, 4, -3, -5, -1, -3, -10, 9, -8, -2,
- 6, -3, -4, 6, -1, 0, 3, 2, 1, -3, -5, 2, 0, 4, -3, -3,
- 1, 4, -8, 0, 7, 4, -9, 0, 3, 1, 1, -5, -4, 3, -1, -4,
- 4, 3, -8, -2, -2, -3, -1, 0, -3, -2, 3, -2, 1, 0, -1, 0,
- -6, 8, -5, 5, -5, 5, -3, 5, -7, 1, -3, -1, -1, 2, 8, -2,
- -5, 1, -3, -1, -4, -4, 9, -1, 1, -3, -2, 1, -14, 8, 3, -14,
- 4, 1, 2, 2, 0, -5, 3, -1, 2, -2, 8, -8, -3, -3, 7, -1,
- -3, -1, -3, 1, 5, -7, 7, -12, -1, 1, 4, 3, -7, 5, 6, -2,
- 2, -6, -3, 0, -5, 2, 1, -1, 2, -7, 1, 8, -5, -4, -3, 2,
- -2, -5, 3, 2, -3, -6, -1, 1, -4, 4, 5, 2, -14, -1, 3, -4,
- 3, 10, 2, 2, -4, -1, 4, 3, -6, 2, 1, -2, -9, 7, -2, 1,
- -4, -5, 1, -7, -1, 1, 2, 2, -1, -6, 5, -1, -12, -4, 11, -2,
- -3, 6, -4, 2, 0, 0, -2, 0, 3, 2, 4, 2, -3, -6, 9, -10,
- -4, 2, 4, -1, -5, -1, 2, 1, 2, -7, -2, -4, -4, -2, 7, 5,
- -6, 0, 1, -1, -4, 2, -6, 3, 9, -11, -2, 8, 0, -5, 6, -1,
- 3, -5, 6, 1, -10, -4, -3, 4, 10, -8, -2, 1, 4, -8, 4, 3,
- -8, -5, 2, 4, -5, 6, -2, 2, 2, -3, -10, 0, -6, 2, 4, 12,
- -4, -10, 6, 2, -5, 2, -3, 6, -4, 0, -6, -4, 7, 0, -4, 12,
- 0, -14, 3, 2, 1, 1, 2, -7, -1, 3, -1, -4, 10, -9, -11, 6,
- 4, -9, -5, -1, 5, 0, 6, -5, -5, -4, 3, -7, 9, 0, -1, 0,
- 4, -3, -2, -1, -4, 0, 10, 3, -5, 4, -4, -6, 8, 0, -7, -3,
- 17, -9, -8, -1, 3, -3, -3, 0, -4, -3, -5, -4, 8, 8, -9, -5,
- 4, 0, -7, 6, 7, 3, -6, 3, -3, 1, -4, -4, 4, 10, 1, -5,
- -2, 0, -9, 4, 1, 1, -4, -2, 6, -3, -5, 0, -6, 3, 0, -2,
- 4, 1, 0, -4, 3, -1, -10, -2, -2, 2, 9, -11, 8, 3, -2, -1,
- -1, -3, -1, -8, 4, 6, 2, -7, 2, -1, 3, -6, 0, 1, -1, 2,
- 2, 3, -1, -13, 2, 9, 3, -5, -3, 2, -3, 5, -4, -2, 0, -4,
- -1, 1, -4, 0, -4, 0, -2, -2, -5, 1, 4, -1, 1, -4, 1, 2,
- 0, -2, 2, 1, 1, 0, 7, 0, -3, -4, -2, 5, 0, -3, -2, 3,
- 2, -9, -1, -1, -1, -4, 1, 5, -6, 1, -4, 8, -12, 1, -5, 3,
- 3, -1, -6, 9, -3, -2, 0, 4, 0, -3, 4, 10, -5, -4, -2, 0,
- 2, -3, -2, -2, 0, 0, -3, 0, 3, -8, 0, -5, 1, 0, 5, 1,
- 4, -14, -2, 1, 3, 1, 0, -1, 6, -2, 2, -5, 4, 1, -2, -3,
- 1, 3, 5, -5, 3, -1, -8, 0, -3, 5, -7, 2, -4, 2, -4, 2,
- -3, -2, -7, 4, 2, -2, -4, 5, -5, -3, 0, -4, 3, 5, -6, 5,
- 8, -5, 0, 2, 1, -6, 0, 5, 1, -2, 6, -10, 7, -9, 3, -5,
- 4, -1, -1, -4, 5, -6, 5, -1, -9, -1, 2, 4, -2, 0, 5, -9,
- 1, 0, -2, 1, -1, -3, -1, 9, -1, -9, -2, 2, 1, 2, -2, 3,
- -7, 3, -1, 3, -1, -5, -5, 9, 1, -1, -3, 2, -7, 1, 3, -4,
- -2, 5, 3, -2, 0, -5, -1, -1, -3, 1, -2, 0, -1, -2, 7, -3,
- -12, -1, -2, 0, 5, 4, -4, -2, 6, -3, -5, 8, -5, -4, 2, 6,
- 1, -1, -1, -4, 4, 3, -6, -4, 6, -1, -4, 2, 2, -10, -4, 3,
- 0, -3, 5, -4, -5, -1, 2, -5, -1, 2, -2, 1, 6, -2, -4, 5,
- -2, 1, 4, 0, -2, 0, 3, 0, -2, -4, -6, 6, 3, -2, -1, -1,
- 1, -1, 0, 0, -14, -1, 3, 0, 0, 4, -6, -2, 0, -2, -3, -3,
- 3, -4, 7, 4, -4, -3, -2, 3, 1, 0, 1, 2, 5, -2, -6, -1,
- 1, 1, -4, 3, 0, -2, -3, 2, -8, 1, -2, -5, 0, 2, -2, 6,
- 2, -1, -7, 4, -5, 2, -4, -6, 5, 5, 2, -1, -3, -4, -7, 0,
- 6, -3, 0, -4, 8, 1, -6, -1, 2, 0, -2, -1, 7, -5, -4, 0,
- 7, 0, -5, -4, 3, -2, 3, -3, 1, 3, -1, -6, 2, 3, -7, 3,
- 0, -3, -3, -2, -4, 2, -2, -1, -3, 2, -4, 0, 4, 2, -6, 1,
- -1, 1, 1, 4, 1, 2, -4, 0, 0, 5, 0, -5, -5, 7, 0, -4,
- -4, 2, -6, -4, 5, -1, -1, -4, -3, 3, -1, -6, 1, 4, -1, -3,
- -3, 3, 4, -1, 3, 2, 0, -3, -3, 5, 2, -3, -1, 1, -1, -2,
- -1, 2, 1, -5, -1, 1, -3, -3, -4, 0, 2, -3, -2, 0, 4, -1,
- -2, 0, 3, -6, 0, 3, 5, -1, -2, 3, 0, -3, 0, -3, 8, -4,
- -6, 4, 2, -5, 0, -1, 2, -5, -7, -2, 1, 2, 1, 0, -2, -1,
- -2, 0, 4, 0, -5, 2, 7, 5, -5, 3, -3, 0, 1, 0, -2, 5,
- -10, 0, 1, 3, -12, 1, -2, -1, 1, -2, -4, 3, -6, -2, 3, 0,
- -6, 0, 2, 4, 2, -3, 6, 2, -7, 2, 1, -4, 9, 3, -1, 0,
- -2, -7, 0, 5, 3, -6, 4, -8, -3, -3, -1, -3, 3, -3, -5, 3,
- -3, 3, -1, 2, -7, -2, -1, -4, 2, 2, 4, 3, 0, 0, -1, -2,
- 1, 4, -2, 2, -1, 2, -2, -1, -8, 2, 2, -3, -1, 2, -2, -5,
- 0, -1, -4, -1, 5, 1, 3, -2, -1, 0, 2, 6, -4, -1, -6, -2,
- 2, 4, 1, -2, -5, -4, 0, 3, -4, 1, 4, -1, -9, -1, 1, -1,
- -2, -2, 2, 1, -5, 6, -1, 5, -4, -3, -2, 8, -2, 1, 5, 2,
- -8, 0, 2, 0, 3, -3, -4, 3, -7, -6, 4, 1, -6, 0, 2, -2,
- -4, -2, 2, 4, -5, -2, 3, 0, -5, 1, 7, 6, -4, -7, 4, 3,
- -6, -3, 12, -3, -3, -5, -2, 2, -2, -7, -2, 10, -4, -5, 2, 0,
- -3, -5, 3, -1, 3, -2, -3, 3, 6, -8, 2, 5, -3, -3, -5, 13,
- -3, -1, 1, 1, -4, -3, 0, 3, -3, -2, -1, 1, 2, -7, -6, 3,
- -7, -3, 3, 1, 2, 1, -7, 3, -3, -1, -5, 6, 3, -1, -6, 6,
- 3, -2, -3, -1, 1, -3, 3, -5, 4, 0, -6, -3, 5, -1, -5, 8,
- -2, -1, 0, -4, 5, -4, -5, -1, 1, 4, -1, 1, 5, -5, 3, -2,
- -2, -5, -2, 2, 4, -2, 2, 1, -16, 5, 1, -1, -2, -2, 1, -4,
- 0, -8, 2, 4, -5, 0, 6, -2, 0, 0, 0, -1, 2, -5, 6, -1,
- -1, 2, -1, 4, -5, 1, 0, -4, -2, -3, 2, 2, 4, -3, 1, -9,
- -1, 2, 0, 1, -1, -1, -4, 3, -7, 6, -4, 2, -4, 7, -3, -1,
- 3, -7, 0, 10, -1, -8, 2, 2, -5, -5, 4, -2, -2, -7, -5, 4,
- 2, 3, -11, 10, -6, -5, -4, 0, 9, -1, 0, 4, -6, -1, 3, -1,
- 6, -6, -1, -1, 9, -5, -3, 7, -1, -1, 4, 2, -7, 3, -2, 0,
- -2, 2, -9, 0, 4, -6, 0, 2, 3, -14, 4, -3, -12, 3, -1, 3,
- -4, 4, -8, 6, 5, -3, -2, -4, 8, 0, -3, -1, 1, -4, 4, -3,
- 7, 0, 1, -5, 1, 6, -10, 1, 8, -5, -8, 6, 4, -2, 5, 2,
- -9, 4, -1, -1, 0, -4, -5, 3, 4, -11, 3, -7, -4, 1, 2, 0,
- -3, -2, -7, 4, -9, 4, -6, -1, 2, -2, -1, 3, 9, -6, 2, -1,
- 3, 4, 2, 3, -1, 0, -1, 1, 4, 0, -3, 3, 6, -7, -4, 4,
- -3, 0, -5, -2, 2, 4, -1, -1, 0, -9, -4, -6, 14, -11, -5, -1,
- 5, -6, -3, 3, -2, -6, 3, 5, -1, -4, 5, -7, 7, 4, -7, 6,
- 4, -2, -4, 5, 8, -12, 3, -1, -5, 3, -3, 2, 10, -7, -12, 3,
- -2, 5, -4, 4, 3, -6, -4, -6, 10, -4, 2, -3, 2, 0, -2, 0,
- 2, 2, -12, -2, 13, -2, -6, 0, -5, 10, 1, -1, -2, 0, -12, 3,
- 11, 0, -5, -9, 7, -4, 2, -3, 0, 9, -2, -6, 0, 3, -2, -13,
- 1, 12, -7, -3, 0, -1, -4, -4, -5, 1, 5, -4, -7, 2, 0, -3,
- 5, -2, 10, -12, 5, 1, 10, 8, -6, 4, -12, 7, -1, 5, 0, -1,
- -2, 7, 4, -4, 5, -4, -20, 6, 1, -6, 5, 0, -14, 3, -12, 3,
- -8, 6, -10, 2, -4, -3, 1, 4, -7, 4, 8, 2, 1, 2, 2, 3,
- 3, 0, 7, -7, 3, -1, -1, 11, 3, 1, -6, 0, -8, -10, 8, 6,
- -4, -1, -5, -11, 3, -1, -14, 6, -4, -13, 10, 0, 1, -5, 0, 0,
- 1, -3, 7, 4, 3, 3, -1, 6, 1, -1, -6, 2, 2, -3, -4, 15,
- -17, -4, 1, -3, 4, -4, -6, -2, 4, 4, -4, 3, -4, -7, -2, 13,
- -1, -4, -2, -3, 9, -7, -12, 13, 10, -12, -3, 4, 13, -14, -6, 12,
- -4, -10, 11, -5, 4, -1, -17, 9, -1, 4, -3, -5, 6, 0, -7, 3,
- 2, 4, -9, -9, 13, -8, 7, 6, -8, 11, -15, -11, 16, -10, -2, 1,
- -8, -1, 11, -1, -4, 2, -13, 9, 3, 11, -16, 4, 7, -9, 9, 4,
- -16, 11, 9, -10, 13, 4, -10, -12, 2, 4, 4, -10, 7, -6, 0, -8,
- -3, 3, -1, -4, -9, -9, 3, -5, -3, 24, -19, -5, 7, -11, 4, 9,
- 1, -3, -1, 7, -4, 4, 4, -4, -7, 22, 0, -1, 10, -19, 3, 1,
- -6, 9, -7, 3, -5, -5, 5, 9, -17, -2, 4, -9, -4, 5, -3, -7,
- -3, 6, -4, 10, -12, -3, 13, -6, -5, 5, 3, 8, 0, -7, 0, 2,
- -3, 12, 3, -10, -4, -8, 8, -1, -16, 13, -5, -5, 0, 3, -6, -8,
- -2, 13, -5, 12, -4, -17, 11, 0, 2, 2, 3, -6, -3, -3, 4, 7,
- -3, 1, -2, -2, -3, -4, 7, -3, -4, 4, -5, 6, -11, 5, 7, -10,
- 0, 2, -6, -1, 5, -3, 3, -5, 5, -8, 4, 10, -8, 3, -4, 7,
- -5, 3, -3, -2, 4, 2, -4, -7, 2, -3, -5, 6, -2, 5, -4, 6,
- -10, -5, 5, 0, -8, 6, -6, -1, -3, 5, 2, 0, -4, 10, -12, -5,
- -21, -1, -4, 5, 3, 2, 18, -14, 8, 5, 1, -4, -5, -2, -9, 0,
- -12, 20, -4, 7, 1, 6, 7, -1, -5, 13, -1, -7, 6, -2, -5, 2,
- 1, 4, 6, -7, 6, -9, -3, 6, -3, 8, -10, 8, -6, 0, -20, 1,
- -5, 5, -4, -8, -12, -13, 8, -2, 17, 3, -5, -20, -1, -7, 3, 22,
- 22, 12, -11, -13, -15, -9, 21, -3, 25, 43, -4, -3, -6, -21, -30, -37,
- -9, 8, -5, 8, 53, 50, 1, -5, -13, -15, -41, -23, 6, -34, -47, -17,
- -2, 2, -13, 22, 29, 32, 44, 51, 55, 10, 15, 7, 0, -31, -48, -38,
- -48, -43, -13, 7, 4, -46, -23, -6, 6, 4, 12, 50, 26, 4, 24, 40,
- 33, 20, 17, 17, -7, -30, 10, -2, -17, 5, -36, -7, -38, -30, -13, 1,
- 9, -1, -6, -29, -15, -11, 7, 3, 6, 16, 27, -22, -8, 5, 24, 27,
- 0, 4, -5, -5, -2, 15, 12, 12, 2, 13, 0, -19, -26, 4, -19, -24,
- -33, -21, -28, 0, 6, 18, 20, 15, 40, 2, -8, 17, 21, 47, -2, -12,
- 11, -9, 22, -19, 3, -27, -29, -10, -38, -36, -42, 33, 12, -29, 10, -15,
- 0, -1, -22, 24, 27, 8, 15, 7, 16, -13, 9, 33, 8, -4, 33, 70,
- 21, -26, -18, -15, -22, -76, -2, 15, -35, -4, 8, 5, -3, -45, 6, 24,
- -20, 6, -15, 8, -1, 2, 7, -4, 39, 4, 22, 34, -25, 26, -1, -31,
- -4, 10, 2, 22, -25, -19, -2, -2, -44, -29, -17, 10, -6, 29, -8, 12,
- 18, -9, -6, -36, 4, -14, -8, 10, -12, 28, 9, 16, 17, -29, 26, 0,
- 1, 11, -13, 11, 1, 7, -7, -3, -5, 22, -10, 10, -29, 22, -29, -30,
- 29, -30, 3, -43, 21, 5, -18, 6, -5, 23, 18, -31, 35, 28, -19, 9,
- 13, 10, -3, -10, 37, -69, 7, 11, -16, 8, -76, 11, 58, -57, 18, -7,
- -11, 26, -40, 100, -53, -1, 14, 3, -26, -35, 21, 20, -30, 10, -26, 37,
- 25, -97, 118, -72, 37, 11, -15, 52, -22, 6, 85, -32, 24, -63, 48, -60,
- -19, 3, -28, -19, 7, -28, 15, -22, 7, 20, -7, 16, -13, 8, 25, -27,
- 2, 7, -18, 15, -30, 23, -3, 28, -31, 34, 22, -23, -6, -6, 28, -68,
- -10, -3, -22, 12, -43, 70, -52, 32, 8, -4, 55, -14, 19, 21, 45, -13,
- -33, -9, 20, -22, -14, 9, -21, -2, 6, -56, 17, -26, 23, -13, -8, -1,
- 3, 31, 16, 20, -12, -10, 50, -27, -17, -13, -26, 29, -23, -7, 58, -40,
- -20, 16, 16, -13, -65, 63, 18, -25, 23, -3, 6, 11, -11, -24, -19, 8,
- 32, -44, 47, -50, 26, 6, 43, -58, 15, -21, 46, -81, 60, -28, 65, -37,
- 42, 42, -55, -6, -23, -9, -52, -25, -5, 7, -67, 26, 59, -62, 31, 63,
- -23, 52, -16, 27, 14, -13, 19, -41, -8, 37, -7, 9, -33, 16, 7, 36,
- -40, -26, -26, 49, -3, 3, -50, 33, 23, -10, -13, -14, -19, -13, 1, 2,
- -41, -19, 32, -3, -29, 9, 58, 1, 9, 15, 19, -19, 59, 2, 6, -6,
- -24, 52, -67, 3, 5, -37, 3, 31, -42, 45, -1, -31, -6, 19, 11, -17,
- -5, -2, -22, 3, -35, 35, -39, 8, 17, 6, 7, -32, 2, -1, 40, -32,
- -2, 26, -5, 2, -5, -12, 18, 21, -15, 29, -28, 13, -23, 36, 28, -75,
- 55, -53, 50, -45, 9, -3, 42, -10, -33, 8, -9, -17, 8, 13, -13, 34,
- -48, 39, -5, -26, 24, 19, -34, 29, -41, 22, -42, -11, -15, 37, 0, -31,
- 15, 4, 11, 18, -28, 23, -3, -52, 33, -1, -8, 19, -39, 44, -3, -16,
- 31, 7, -17, 38, -44, 62, -21, 0, -7, -13, 25, 12, -50, -13, 2, 9,
- -47, 43, -29, -12, -3, -3, -37, -22, 0, -6, 60, -69, 27, 9, 12, 13,
- -7, 46, 43, -2, 3, -5, -5, 17, 13, -37, 35, -39, -38, 33, -44, -10,
- 11, -9, 50, -68, 26, -22, 10, -20, 34, -13, -17, 21, -34, -1, 42, -23,
- -7, 9, 3, 1, -1, -9, 36, -15, 5, -21, 40, -47, 25, -11, 20, 24,
- -19, 16, -13, 6, -25, -2, 19, -17, 7, -36, 28, -8, -28, -11, 9, 25,
- -55, 7, 39, -36, -3, 8, 28, 25, -33, 29, 1, -28, -1, -7, 40, -50,
- 22, 15, 21, -2, -1, 18, 8, 46, -52, -1, 14, -39, -10, 18, -10, -27,
- -15, -9, 2, -7, -47, 23, 17, -40, 12, 37, -24, 22, 9, 5, 27, -14,
- -17, -17, 23, 16, -18, 19, 32, -19, -10, 13, 12, -33, 31, -4, 12, -17,
- 22, -3, -8, -33, 16, -45, -17, -13, -24, 23, 19, -22, 52, -63, 23, 26,
- 8, -11, 30, 40, -35, 28, -5, 11, -10, -16, 18, -35, -21, -6, 9, 0,
- -33, 9, -15, -24, 15, -23, -19, 30, 13, -20, 37, 24, -48, 47, 21, -31,
- 51, -22, 40, -24, 47, -55, 31, -21, -57, 15, -7, -28, 5, 25, -12, -42,
- 46, -43, -21, 6, 4, 14, -15, 11, 51, -27, 6, 21, -27, 42, 17, -35,
- 3, 3, -15, 11, 17, -26, 0, 6, 11, 18, -37, 4, 28, -14, -14, -30,
- 43, -50, -17, 55, -50, 16, -32, 51, -35, -13, -4, 54, -22, 23, -48, 51,
- 2, 10, -16, 7, -10, 15, -48, 25, -5, -4, 6, 21, -17, -2, 30, -23,
- 16, -3, -12, -11, 21, -57, 3, 10, -3, 0, -19, 36, -42, 50, 0, -30,
- 55, -15, 12, -10, 28, -47, 29, -16, 6, -37, -1, -6, 3, -45, 35, -30,
- 8, -4, -12, 32, 42, -23, 3, 5, 30, -38, 15, 16, -36, 60, -1, -53,
- 28, -25, -10, 45, -20, 2, -22, 24, -6, -19, -31, 18, 6, -56, -15, -3,
- -5, 1, 12, 5, -7, 70, -9, -7, 49, -31, 48, 36, -15, 5, -23, 35,
- -51, 4, -32, -40, 7, -20, -15, -7, 17, -32, -2, 17, 1, -8, 46, -4,
- 12, 15, 41, -50, 29, -21, -13, 10, -20, 12, 2, -24, 12, -1, 6, 8,
- -29, 19, -27, 51, -67, 83, -44, -22, 21, -2, -14, 13, -52, 72, -37, 19,
- -25, 43, -37, -22, 19, -12, -36, 14, 17, -3, 27, -39, 58, -23, 1, 14,
- 52, -25, 15, -1, 1, -23, -11, -9, 4, 14, -83, 23, 4, -38, -21, 2,
- -1, 17, 2, 48, -30, 24, 29, 9, 19, -44, 46, 22, 5, -32, 39, 0,
- -28, -27, 16, -32, -31, 7, -17, -13, -9, -6, 14, -33, -18, 35, -39, 52,
- -40, 31, 12, 14, -24, 52, -35, 11, 1, 26, 10, -18, 20, 7, -7, -5,
- 7, 5, -15, -10, -7, 8, -10, -26, 21, -16, -14, 13, -27, 27, -44, 6,
- 18, 6, -12, -4, -11, 12, -1, 7, 6, 3, 20, -5, 11, 15, 9, -10,
- 37, -37, -3, 11, -23, 9, -35, 19, -32, 4, 14, -28, 41, -42, 43, -5,
- 11, -20, -16, 20, -10, 6, 6, -4, 1, -6, 7, 20, -42, 25, -29, 34,
- -31, -10, 14, -4, -9, -4, 13, 7, -7, -2, -19, 25, -10, 0, 16, -1,
- -9, -6, 53, -52, 10, -7, 5, -10, 1, 4, 9, -24, 10, -21, 61, -40,
- 3, 3, 12, -38, 31, -3, -7, 8, -13, 8, -15, 4, -33, 44, -29, 5,
- 5, 37, -52, 16, -13, 25, 7, -34, 17, -7, 14, -11, 24, -32, 22, -23,
- 42, 5, -30, 21, 19, -21, 2, -11, 14, -18, -16, -34, 41, -30, 7, 2,
- -23, 20, -37, 26, -17, 18, -37, 64, 0, 14, -19, 5, 12, -8, -13, 22,
- -9, -26, 24, 17, -8, 3, -5, -14, -14, 17, -30, 14, 26, -67, 38, -9,
- -20, 11, 11, -22, 11, 15, 1, 11, -22, 0, 1, 38, -43, 2, 15, -31,
- 2, -5, 29, -18, -27, 21, -8, 15, -20, 46, -24, 20, 16, -7, 24, -63,
- 40, -8, 9, -8, 14, -10, -11, -28, 4, 10, 8, -26, 13, 11, -35, -1,
- 40, -36, -5, -3, 38, -7, -23, 3, 4, 17, 3, -15, 11, 24, -67, 26,
- 2, 21, -54, 30, 14, -34, 12, 25, -16, 12, -13, -7, 47, -24, -23, 7,
- 18, -4, -19, 31, -18, -14, -11, 21, -15, 5, -31, 40, -53, 21, -4, 30,
- -32, -3, 14, -5, 30, -17, 3, 13, 8, -4, -5, -11, -12, 8, -7, 16,
- 10, -21, 35, -59, 13, 10, -3, -7, 1, 2, -16, -4, 27, -43, 35, -16,
- -14, 36, 0, -51, 13, 31, -19, 14, 21, -19, 14, -3, -27, 29, -10, 34,
- -46, 30, -12, -17, 11, -34, 23, -23, 10, -3, 4, -8, -14, 25, -16, 35,
- -12, 22, -7, 3, 9, 0, 11, -5, -10, -16, 9, -21, 7, -36, -4, -13,
- 4, -6, -7, -2, -1, 0, 14, 16, -15, 7, 27, -28, 43, -32, 17, 7,
- -25, 33, -7, 6, -10, 11, -20, 1, 5, 28, -11, -26, 20, -17, 29, -40,
- 1, -6, 13, -23, 23, -23, -28, 18, 5, -22, 16, -19, 41, -9, -16, -11,
- 45, -17, 6, -51, 34, 36, -44, 29, -33, 22, -13, 3, 5, -26, 2, 11,
- 23, -17, 0, -7, 12, 3, -27, 18, 13, -2, -30, 22, -6, 7, 1, -4,
- 5, -1, 12, -14, 1, -15, -5, 12, 6, 3, -13, 15, -14, 14, -1, -12,
- 3, 3, -4, -18, 7, 2, -7, -5, 9, -15, 7, 17, -27, 45, -52, 60,
- -15, -12, -9, -11, -14, 27, -18, -9, 21, -10, 10, 3, -23, -4, 8, -23,
- 19, -31, 12, 18, 12, -7, 1, 15, 3, 27, -38, -7, 42, -9, 1, -7,
- -22, 5, -10, 0, -28, 5, 12, -6, 0, -12, -15, 18, 19, -14, -27, 47,
- -6, -1, -21, 32, -31, 52, -41, 3, -39, 34, -29, 16, 8, -6, 33, 16,
- -23, -10, 16, 9, 2, -33, 40, 0, -21, -2, -18, 1, 13, -32, 24, -11,
- -14, 24, -20, 0, -19, 11, 23, 1, -30, 4, 38, -23, 11, 0, 9, 18,
- -36, 10, -21, -1, -5, -1, 23, -24, 9, 27, -13, 4, -39, 60, -17, -11,
- -12, 25, -9, -36, 26, -7, -3, 28, -27, 26, -12, -20, 8, 13, -40, 7,
- -23, 38, -33, 14, 8, -1, -23, 36, -19, 15, 13, -36, 4, 17, -32, 31,
- -23, 20, 0, 23, -3, 5, -17, -11, 12, -24, 21, -29, 34, -26, -1, 4,
- -14, 21, 9, -1, -1, 21, -33, 29, 1, -28, 28, -20, 22, -24, -13, -13,
- -6, 10, -22, 33, -49, 17, -24, 1, 22, -11, 43, -27, 28, 28, -33, 36,
- 5, -5, 2, 22, -28, 16, -24, -16, 4, -69, 66, -47, -12, 19, -17, -1,
- 24, -32, 46, -36, -3, 50, -26, 24, -22, 9, 39, -53, 0, 32, -1, -21,
- 29, -26, -4, 29, -45, 12, -10, 11, -12, 20, -23, -11, 20, 10, -1, -24,
- 33, -16, 12, 2, 4, 14, -17, -17, 20, -42, 6, -18, 0, -4, -10, 11,
- 2, -10, 4, 7, 2, 27, -35, 11, 12, 4, -11, 19, -19, 40, -6, -16,
- 44, 2, -10, 32, -37, 1, -23, -8, 23, -59, 11, -5, -9, -9, -1, -8,
- 5, -18, 26, -14, 27, -10, 9, 30, 23, -31, 30, -1, -1, -14, -13, 35,
- -76, 42, -79, 43, -29, 1, 2, -5, -6, 5, 30, 15, -20, 23, 25, -37,
- 39, -5, -20, 24, -7, 2, 20, -38, 20, -31, -12, -2, -12, 13, -31, 10,
- -9, 0, -11, 27, -16, 10, -2, 44, -46, 18, 33, -16, -12, 3, 11, 15,
- -26, 8, -22, 19, -3, -11, 5, -48, 31, 16, -15, -5, -2, 17, 6, -9,
- -8, 9, 25, -7, 0, 7, -8, -5, 10, -11, -26, 26, -15, 17, -31, -11,
- 15, -1, -16, 1, 10, 4, -7, 18, -6, 2, 11, -2, 11, -26, -4, 25,
- -27, -19, 7, 29, -29, 13, -10, 3, -27, 31, -55, 38, -13, 17, -9, 32,
- -27, 17, 18, -3, -10, 17, -45, 58, -12, -18, 25, 4, -40, 35, -61, 10,
- -3, 2, -15, -14, 33, -20, -2, -4, -19, 31, -29, 25, 8, -11, -3, 32,
- 1, -26, 12, 25, -42, 5, 27, 1, 2, 17, -25, -2, 6, 9, -17, 9,
- -11, 9, 9, -21, 11, 15, -55, 34, -24, -6, -1, -9, 17, -13, 1, -11,
- 31, -24, -15, 38, -21, 27, -30, 30, -35, 28, 15, -30, 56, -40, -17, 39,
- -9, -7, 4, -18, 7, 13, -25, 3, -9, -13, -13, 27, -35, 13, 0, 6,
- -3, 26, -20, 27, -23, 25, -25, 38, -2, -3, 8, -11, 0, 0, 0, -28,
- 28, -27, -6, 23, -33, -8, -1, -29, 0, 2, 26, -40, 15, 2, 23, 28,
- -32, 17, 26, -17, 10, 1, -14, 17, 1, 14, -9, -10, -15, 12, -3, -19,
- 2, 20, -19, -19, -14, 4, -2, -8, 13, -16, 22, -9, 28, 7, -9, -22,
- 49, -28, 3, -5, 9, -2, 5, -26, 39, -12, -29, 19, -11, 7, -33, 27,
- -32, 15, -9, -9, 16, -7, -3, 27, -4, -18, 19, 23, -20, 3, 2, 11,
- -21, 14, 4, -13, 8, -15, 9, 4, -37, 9, -11, 22, -20, -12, 17, 12,
- -20, -2, 13, 18, -19, -1, 19, -28, 12, 2, 12, 2, -37, 12, 21, -19,
- -23, 17, 21, -35, 9, 26, -20, -15, 12, 14, 23, -20, 17, 9, -16, -4,
- 5, 3, -8, -24, 13, -5, 5, -7, -11, 31, -24, -34, 28, -8, -26, 16,
- -7, 2, -2, 9, -21, 42, -54, 34, 42, -22, 16, -1, 14, -15, -12, 21,
- -16, -3, -18, 55, -46, 11, 6, -19, 18, -36, -9, 12, -21, 23, -41, 37,
- -12, -10, 1, 13, -5, -7, 42, 2, 1, -2, 4, -3, 15, -53, 27, -3,
- -26, -14, 32, -30, -5, 11, 12, -3, -4, -24, 35, -37, 12, 4, 5, -17,
- 32, 0, -18, 41, -41, 43, -2, 22, -36, 7, -5, 11, -25, 7, -29, 9,
- 2, -4, -11, 5, -2, 15, -31, -11, 24, 3, -15, 26, 11, -10, 18, 5,
- -8, -2, -43, 43, 2, -43, -20, 25, 4, -3, 39, -11, -6, -3, -1, -12,
- 22, -21, 6, 22, -7, -17, -5, 18, -4, -14, 3, 18, -11, -18, -3, -2,
- 2, -5, 1, 10, -28, 17, 8, -8, -12, 23, -13, 10, 0, -12, 14, 11,
- -11, 34, -21, 3, 1, -9, -17, 1, 9, -28, 5, -34, 21, -8, 8, 8,
- -13, 18, 2, -15, 5, -3, 11, -2, 11, -2, 15, -10, 14, 5, -1, 18,
- -6, 1, -26, 13, -25, 2, 6, -39, -14, 0, -5, 13, -22, -14, 34, -22,
- -1, 16, -13, 11, 32, -10, 31, -5, 18, -21, 34, -47, 32, -9, 10, 8,
- -31, 5, 4, -9, 5, -52, 16, -14, 4, 20, -11, -13, 13, -10, -12, 11,
- 16, -20, 13, -12, 14, 10, 1, -15, 32, -24, 18, 0, 5, -26, 6, 16,
- -23, -10, 12, -40, 17, -14, -13, 38, -5, 5, -19, -3, 17, 14, -8, 8,
- -15, 21, -6, 10, -12, -16, 27, 6, -35, 16, -26, 45, -25, -1, -9, 29,
- -25, 8, -31, 9, 25, -10, 4, 11, -22, -5, 1, -12, 6, -10, -11, 17,
- -31, 5, 21, -6, 33, -55, 47, 6, -6, 2, 11, 14, -11, 10, -14, -26,
- 8, -18, 4, 11, 6, -4, -2, -20, -2, -26, 38, 4, -24, -6, 7, 22,
- -15, 30, 0, 13, 3, -11, 4, -10, -28, 38, -14, -9, -5, -45, 40, -21,
- -28, 31, 0, -9, 18, -45, 20, 12, -20, 39, -25, 14, 1, 17, -4, 29,
- -12, 26, -8, -21, -19, 10, 3, -31, 34, -16, -12, 5, -14, -4, -13, 13,
- -7, 13, -15, -23, 40, -27, 15, 4, -11, 23, -20, -2, 7, 8, 3, 2,
- -4, 1, 7, -22, 42, -37, 24, 1, -9, 16, -31, 9, 6, -3, -25, 40,
- -41, 0, 2, -7, 18, 0, -10, 21, -5, -17, 29, -37, 27, 3, -22, 10,
- 11, -5, 13, -17, 15, -19, -23, 17, -10, -35, 20, 4, -4, 3, -10, 7,
- 15, -14, 10, -3, 10, -25, 13, 1, 20, -13, 13, 19, -38, 18, -4, 19,
- -10, 9, -27, 19, -35, -8, -10, 39, -14, 2, 14, 36, -16, -8, -8, -7,
- -2, -11, 4, 1, -42, 51, -17, 10, -15, -33, 29, -25, -7, 6, 2, 11,
- 3, -20, 37, -28, 6, 34, -22, 5, 28, -4, 17, 5, -47, 28, 1, -3,
- -21, 8, -6, -7, 10, -15, 6, -30, 6, -19, 1, -4, 30, -22, 29, -13,
- -4, -2, 11, -1, -15, 38, -4, -9, 25, -29, -17, 10, -2, -3, 7, -15,
- 24, -26, 21, 2, 6, -20, 10, -26, 41, -33, 19, -11, 6, -3, -9, 5,
- 3, -21, 8, -5, -7, 10, 13, -10, -3, -4, -10, 26, -1, 1, 5, 11,
- -3, 2, 23, -35, 21, -43, 17, -4, 2, -24, 14, -22, -3, 3, -5, -2,
- 12, -13, 16, -5, 7, 17, 4, -44, 26, 17, -4, 36, -58, 43, -20, 8,
- 3, -23, -18, -17, 16, 4, 3, -33, 15, -4, -10, 19, -20, 23, 13, -6,
- -4, 25, -12, 21, -9, -4, 6, -1, 23, -7, -15, 3, -15, 3, -13, -23,
- -3, -32, 4, 6, -18, 0, 11, -14, 42, -37, 26, -20, 50, -18, 18, 11,
- 4, 18, -5, 8, -22, 30, 5, -20, 16, -20, -28, 2, 4, -10, -10, -10,
- -27, 38, -38, 14, -17, -20, 34, -11, -5, -5, 10, 5, 25, -20, -2, 28,
- -8, 26, -39, 68, -50, 53, -35, -5, 3, -23, 24, 8, -21, -28, 19, 6,
- -18, -13, -7, 26, -7, 0, -4, 7, -7, -15, 29, -10, -12, 13, 9, -4,
- -34, 39, -49, 38, -31, 29, -26, 2, -18, 45, 3, -16, -2, 29, 4, -27,
- 2, 17, 6, -12, -3, 12, -12, -14, -22, 11, -13, 6, -2, 30, -39, 12,
- 5, 10, -18, 3, -5, 24, -39, 15, 49, -42, 19, 9, -25, 5, -60, 31,
- -19, -8, 9, 28, 28, -34, 21, -4, 25, 24, -18, 17, -35, 1, 7, -28,
- 32, -29, 6, 7, 4, -23, 21, -17, -14, 16, -29, 21, -43, -24, 2, 58,
- -33, 60, -20, 24, -29, 18, -24, 29, -14, -6, 10, -19, 15, 38, -38, 35,
- -15, -11, 20, 9, -57, -4, 0, -8, 15, -8, -20, -6, 9, 21, 8, -21,
- 12, 1, 6, -29, 24, 17, 6, -33, 26, 20, -12, 14, -17, 3, -2, -19,
- -6, 13, -55, -5, 5, 8, 21, -12, 11, -13, 15, -34, 45, -47, 43, -6,
- 5, 34, -32, 28, -15, 12, -38, 30, -16, 1, -4, -2, 6, 4, -26, 2,
- 21, -42, 5, 19, -20, 44, -70, 38, -5, -4, -8, 20, -16, 22, -25, 46,
- -21, 1, -31, 48, -32, 7, -23, 62, -48, 38, -2, -30, 41, -57, 41, -41,
- 9, -5, 16, 9, 1, -50, 80, -48, 5, -20, 11, -9, -19, -8, 1, 20,
- -24, 4, 36, -42, 42, -32, 39, 6, -12, 1, 12, 3, -17, 2, -13, 57,
- -70, 26, 6, 0, -23, 8, 4, -17, -10, -41, 34, -10, -46, 51, 23, -10,
- -4, -10, 16, -9, 4, 32, -14, 6, -7, 23, -18, -9, 5, -14, 4, 15,
- -29, 10, 15, -14, 19, -28, 40, -30, -20, 17, 3, 5, 37, -32, 12, 0,
- -18, 1, -7, -23, 4, -51, 69, -22, -43, 30, -39, 54, -64, 29, 21, -2,
- 2, -22, 29, 2, 14, 5, 8, -7, 7, 34, 2, -25, 10, -7, -5, 24,
- -64, -1, -18, -7, 23, -24, 26, -23, -35, -17, 51, -60, 53, -2, 14, 17,
- 6, 5, 11, -9, 15, 21, -1, 21, -49, 45, -34, -16, 12, 0, -34, 2,
- -67, 50, -48, 23, -20, -12, 20, -22, 32, -15, 15, -23, 65, -9, 33, 26,
- -3, 4, 14, 8, -17, -17, -47, 57, -63, 13, 8, -30, -8, -31, -12, 28,
- -45, 9, -3, 19, -31, 31, -2, 41, -46, 38, 38, -23, 21, -13, 9, 35,
- -2, 5, 13, -36, -2, -10, 15, -16, -48, 22, 29, -49, -21, 15, -10, -15,
- -23, 26, 40, -39, 26, -10, 13, 21, -46, 35, -20, 8, -1, 30, 17, -64,
- 22, 2, 22, -30, 6, 19, -18, -34, 38, -4, 13, 0, -11, 50, -51, 21,
- -10, 13, -42, -9, 45, 4, -82, 12, 37, -11, -12, -8, 21, 6, -33, 32,
- -14, 6, 13, -44, 37, -22, 20, 2, 12, -15, 26, 30, -17, -11, -30, 18,
- -4, -5, 11, -2, -22, -15, 25, -16, 11, -15, 21, -8, -17, -9, 27, 11,
- -43, 2, 4, 31, -59, -5, 44, -16, 26, -13, 3, 1, -1, -40, 70, -44,
- 43, -15, 2, 22, -36, 13, 41, -43, -12, 4, 12, -34, -22, 9, 22, -23,
- -22, 27, -24, 22, -18, 45, 12, -32, 7, 17, -24, -15, 4, 20, 6, -40,
- 29, 48, -64, 28, -3, -6, 43, -22, -34, 36, -41, 13, -2, -59, 72, -53,
- 39, -30, -3, 16, 29, -40, 5, 30, -21, 15, -35, 9, 14, 2, 4, -16,
- 4, 8, 14, 1, 30, -32, 5, -14, 28, -26, -1, -12, -16, -4, -22, -5,
- 28, -8, -24, 7, 42, -22, -3, -9, 16, 38, -42, 25, 8, 10, -9, 38,
- -28, 31, -8, -34, 22, -70, 21, 15, -36, -10, -15, -1, 49, -37, -17, 51,
- -24, 11, 30, -27, 33, -39, -12, 36, -4, -49, 38, 12, 10, -17, -11, 59,
- -26, -59, 33, 28, -37, 17, -39, 40, -16, -29, 28, 14, -19, -14, 18, 23,
- -17, -16, 15, -11, 9, -16, 45, -25, -27, -1, 40, -36, 1, 19, -1, -14,
- -3, 1, 29, -9, -58, 54, -12, -19, 16, 13, 29, -74, 48, -20, 22, -66,
- 3, 23, 2, -31, 11, 41, -41, 2, 25, 4, 8, -3, 8, 23, -10, -6,
- 27, -1, -67, 31, -29, 29, -29, 0, 17, -20, -18, -10, 29, -45, 43, -35,
- 61, 4, -49, 31, -10, 53, -60, 19, 11, 15, -22, -3, -20, 26, 3, -60,
- 59, -41, -26, 17, 22, 12, -6, -12, 30, -14, -8, -7, 16, 54, -34, -18,
- 26, -15, -11, 7, -44, 39, -52, 48, -53, 18, -38, 3, 13, -11, 37, -12,
- 11, 9, 14, -7, 40, -19, -6, 6, -15, 29, -34, 1, 18, -18, -9, -24,
- -30, 17, -50, 31, 4, 8, 17, -7, -5, 0, 17, 25, 16, 15, 43, -54,
- 39, -10, 2, -40, -23, 26, 3, -61, -2, 15, -6, -56, 46, -2, 16, -80,
- 43, 52, -9, -30, 41, 17, 2, -33, -7, 52, -7, -29, 31, 0, -23, 10,
- -24, 44, -82, 18, 45, -14, -40, -40, 40, 12, -66, 0, 74, -35, -5, 17,
- 67, -59, 32, -4, 29, -1, -48, 39, 1, 8, -63, 43, -12, -37, -5, -12,
- 25, 2, -21, 7, 24, -34, -11, 19, 28, 6, -34, 44, 13, -35, -19, 28,
- -50, -13, 56, 7, -32, -12, 19, 6, -1, -6, 6, 0, 17, -26, 41, -20,
- -5, -6, 43, -58, 10, -12, -14, 74, -84, 74, -28, -15, -27, 19, -15, -3,
- 17, 24, 10, -60, 64, 0, -9, -39, 1, 25, -12, -25, 22, 8, -21, -40,
- 73, -32, -18, -11, 6, 57, -52, 36, -19, 37, -40, 9, 2, 14, -15, 27,
- -33, 35, 7, -37, 24, 10, -66, 17, 1, -10, 13, -38, 15, -9, 43, -30,
- 19, -15, 17, -8, 7, 8, -38, 66, -55, 10, 9, -37, 37, -32, -11, 47,
- -14, 11, 37, -41, -33, 12, 3, 34, -59, 35, 14, -4, -7, -2, -21, 48,
- -52, 49, -8, -44, 0, 11, -6, -2, 11, -35, 64, -38, -35, 64, 7, -32,
- 15, 15, 19, -39, 18, -31, 25, 6, -28, 25, 17, -34, -26, 21, -18, 15,
- -15, -31, 24, -4, -26, 41, -2, -18, -24, 75, -21, 1, -6, -2, 16, 12,
- -24, 15, 8, -14, 7, 7, -4, -37, 45, -67, 39, -41, 9, 19, 13, -60,
- 44, -22, 23, 2, -35, 14, 35, -25, 7, 21, -39, 15, 1, 39, -43, 26,
- -18, -14, 36, -10, -16, -15, 29, -34, 16, -1, -13, 24, 0, -43, 55, -18,
- -31, 22, -15, -15, 43, -33, 50, -10, -43, 22, -27, 60, -30, 14, 0, 10,
- -3, 10, -20, 11, -34, -7, 70, -59, -26, 25, -23, 7, -29, 8, 11, -13,
- -8, 3, 13, -13, 35, -8, 34, -33, 9, 30, -5, 33, -37, -10, 56, -38,
- -5, 14, -50, -24, 39, -11, -11, -27, -22, 46, -13, -6, -1, -6, 37, -56,
- 48, -11, 24, -14, 32, -13, -1, 5, 8, 37, -86, 36, -1, -6, -12, 13,
- -40, 3, 9, 15, -13, -23, 3, -15, 61, -50, -12, 29, -14, -2, 25, -31,
- 52, -41, 31, 31, -27, -10, 9, 22, -15, 3, -11, 22, -25, 8, -40, 0,
- -5, 2, -9, 40, -62, 5, 16, -6, -7, -21, 31, 29, -28, -3, 47, -31,
- 51, -34, 59, -32, -8, 44, -7, -2, -20, 3, 64, -51, -58, -3, 0, -39,
- 26, -22, 14, -39, 8, 20, -30, -2, 7, 8, 37, 15, -9, 43, -5, 2,
- 11, -5, 10, 2, -37, 56, -59, -11, 8, -14, -30, -29, -3, 29, -1, -33,
- 42, -44, 53, -58, 85, -28, -5, -2, 41, 5, 15, -49, 30, 26, -46, 17,
- 9, -55, 0, 38, -46, 32, -32, 10, 15, -60, 8, 23, -1, 7, -35, 71,
- -11, -39, 39, -22, -8, -3, 10, 36, 13, -73, 53, -15, 7, -7, -15, 25,
- -7, -24, 21, 9, -51, -11, 27, -15, 11, -6, 26, -26, 27, 16, -33, 47,
- -29, -18, 53, -53, -2, 38, -29, 12, -37, 18, 10, -10, -20, -8, 12, 15,
- -43, 32, 3, -44, 35, 29, -38, 17, -16, 13, 45, -37, 21, 18, -7, -38,
- 32, -21, -6, -4, 20, -14, -9, -16, 14, 1, -19, -13, 22, -4, -39, 58,
- -34, 3, 17, -10, 50, -3, -47, 36, 29, -27, -13, 39, -20, -8, 12, -40,
- -20, 1, 0, -24, 23, -40, 38, 4, -1, -19, 16, 10, -4, 28, -25, 44,
- -17, 19, -21, 50, -10, -16, -13, 7, -28, 11, -9, -17, 13, -52, 22, -3,
- -21, -49, 75, -42, 34, -3, 18, 1, 10, -20, 13, 13, 22, -11, -35, 46,
- -29, 44, -39, -31, 37, -22, -27, 42, -57, 40, -34, 4, 12, 9, -29, 13,
- 6, -10, 4, 21, 7, -17, 3, 25, -18, 44, -26, -1, 20, -38, 19, 24,
- -35, -18, -6, -14, 23, -32, -15, 24, -6, -50, 62, -39, -3, 0, -23, 87,
- -44, 37, -9, -4, 67, -73, 46, 45, -32, -14, 8, -4, -22, -5, -22, -20,
- 36, -34, 6, 26, -35, -18, 15, 0, -12, 0, 12, -10, 28, -15, 24, 13,
- -21, 19, 15, -17, 20, -7, 0, -21, 7, -16, 5, -12, -1, -11, 7, 32,
- -68, 69, -55, 24, 2, -3, 21, -47, 28, 20, -15, -29, -2, 23, 4, -18,
- 15, -22, 36, -38, 17, -23, 14, -18, 17, 31, -37, 30, 8, -1, -3, -5,
- -12, 22, -18, -28, 33, 0, -9, -16, 20, 9, -26, -20, 21, 2, -4, 14,
- -24, 16, -11, 12, -1, -39, 7, 51, -2, 1, -12, -30, 63, -43, -19, -2,
- -6, 20, 10, -18, -2, 23, 15, -3, -34, 1, 9, 10, -22, -29, 28, 28,
- -32, -2, 23, -26, 2, 11, 25, -35, -14, 15, 23, -48, 12, 7, 22, -52,
- 25, 17, 16, -47, 29, 13, -19, 12, -67, 65, -6, -30, 32, 7, -12, 14,
- -19, 27, -52, -2, 15, 40, -69, -5, 33, 15, 6, -51, 36, 21, -2, -24,
- 15, -3, -9, -4, 30, -34, -2, -19, 27, -23, 3, -12, 2, 18, -15, -6,
- -3, 22, -30, 55, -21, 26, -35, 44, -27, 25, -21, 4, 14, -20, -1, 10,
- -42, 12, 7, -12, 5, -37, 13, 1, 3, -33, 24, 15, 0, -4, 10, -14,
- -6, 35, -6, -4, -8, 13, 26, -7, -32, 36, -9, 5, -15, 14, -15, -36,
- 8, 2, -15, -22, -7, 28, -4, -25, 17, 39, -16, 4, 20, 8, 4, -2,
- 4, 31, -46, -12, 15, 0, -9, -36, 18, -10, -12, 7, -17, 3, -13, -4,
- 37, -27, 6, -16, 76, -41, 13, -14, 25, 28, -21, -10, 31, -4, -39, 21,
- -9, -35, 12, 3, -16, 7, -54, 51, -34, 44, -45, 30, -7, -30, 49, -21,
- -1, 27, 12, -8, 9, 8, 5, -27, 42, -30, 32, -28, -27, 19, -18, -36,
- 10, -25, 19, -9, -14, -5, 13, 31, -21, 22, -28, 15, 13, 10, -12, 6,
- 32, 1, 24, -47, 36, -4, -23, 0, -16, 6, -41, 1, 17, -33, -9, 5,
- 34, -5, -15, -1, 30, 13, -30, 20, 7, -12, -16, 11, 20, -4, -19, 21,
- 26, -25, -17, -5, 23, -32, -3, -12, 18, -5, -28, 8, 15, -14, -10, 31,
- 11, -43, 12, 35, -5, 3, -33, 48, -1, -11, -6, 28, -23, -13, 13, 9,
- -7, -22, 2, -25, 32, -38, 17, -16, 10, -54, 69, -62, 61, -30, 4, 24,
- 3, -12, 4, 27, -22, 22, 0, 4, -15, 4, -46, 20, -16, 29, -30, 14,
- -25, 30, -18, 16, -12, -7, 21, -10, 16, -23, 15, 9, -12, 12, 13, -21,
- 19, -28, -2, 5, -15, 0, 3, -17, 6, -6, 18, -11, 6, 13, -1, 15,
- -23, 14, 5, -17, -14, 5, 24, -23, 15, -26, 9, -10, 15, -29, 2, -12,
- 23, 8, 10, -37, 26, 7, -5, -25, 3, 16, 14, -10, -5, -16, 22, -7,
- -8, 18, -58, 86, -15, -5, 4, -30, 40, -7, -21, -12, 9, -10, 16, -48,
- 40, -29, -6, -5, -22, 21, 3, -20, 39, -36, 29, -5, 2, 3, 15, 2,
- 6, 21, -11, 28, -13, 2, -33, 24, 1, -28, 12, -33, 12, 11, 0, -41,
- 11, -5, -9, 26, -34, 15, 2, 18, -7, -25, 5, 11, -4, -7, 35, -6,
- 23, 12, -42, 33, -32, 26, -41, 25, -23, 15, -13, 11, -5, -4, 0, -8,
- -4, 1, 10, 6, -8, -7, 18, 8, -11, -19, 9, 17, -2, -13, 8, -21,
- 31, -16, -24, 3, -12, 10, 23, -8, 12, 8, 23, -7, -22, -8, 5, -5,
- -14, -33, 4, 7, -11, -11, 15, -22, 38, -2, -11, 24, -16, 38, 14, -6,
- 7, -14, 18, -13, 2, -8, -14, 13, -19, -13, 2, 2, -23, -9, 11, 1,
- -12, 16, 1, 2, 18, 1, -20, 9, -5, -14, 16, -11, 2, 8, -2, -9,
- 0, 11, 13, -22, 18, -16, 35, -39, 45, -22, -18, 12, 1, -19, 21, -48,
- 42, -20, 9, -23, 20, -11, -27, 21, -13, -14, -11, 29, -13, 25, -25, 36,
- -13, 8, 17, 34, -14, 11, 4, -4, -15, -9, -12, 1, 19, -69, 7, 10,
- -34, -20, 1, -5, 13, 6, 34, -17, 5, 40, -1, 21, -38, 35, 22, 11,
- -28, 28, 11, -25, -26, 12, -20, -38, 10, -16, -11, -11, -6, 13, -22, -31,
- 43, -42, 49, -33, 20, 17, 13, -22, 44, -21, -4, 14, 9, 33, 10, 0,
- -1, 0, 0, -2, 11, 23, 22, 24, 25, 20, 21, 15, 40, -1, -24, -42,
- -5, -19, -11, -8, 4, -46, -31, -14, -33, -40, -44, -48, -89, -63, -47, -33,
- -27, -10, -6, 22, 25, 26, 28, 37, 11, 15, 51, 44, 54, 66, 66, 71,
- 111, 84, 70, 63, 47, 39, 22, 47, -28, -79, -111, -90, -91, -112, -81, -87,
- -49, -46, -5, -24, 26, 24, 47, 29, 23, 30, 30, 13, -1, 4, -14, 17,
- 35, 62, 31, 53, 59, 72, 64, 27, 26, 9, 9, -61, -44, -88, -74, -81,
- -83, -124, -96, -37, -78, -48, -56, -68, -60, 7, 44, 39, 54, 77, 102, 110,
- 108, 89, 101, 100, 105, 64, 22, -1, 44, 40, -19, -29, -35, -16, -27, -40,
- -77, -82, -113, -104, -93, -57, -72, -56, -3, 1, 7, -1, 49, 39, 30, 31,
- 23, 10, 31, 11, 7, -19, -2, -2, 28, 62, 92, 75, 33, 34, -20, -47,
- -61, -85, -105, -93, -119, -112, -54, -70, -67, -32, -1, 4, 4, 20, 29, 62,
- 70, 54, 62, 78, 115, 92, 85, 78, 52, 21, 19, 27, 2, -8, 13, 0,
- 5, 3, 9, 18, 0, -59, -61, -45, -57, -65, -76, -89, -102, -48, -24, 17,
- 6, 26, 33, 35, 26, 41, 63, 20, 12, 29, 34, 8, 7, 31, 21, 31,
- 39, 33, -5, -8, -55, -57, -98, -94, -88, -64, -82, -74, -39, -14, 3, 16,
- 22, 8, 2, 17, 5, 36, 76, 74, 71, 57, 73, 62, 47, 30, 32, 19,
- 4, 7, -14, -18, -2, 17, -5, 13, 22, 31, 10, 8, -13, -47, -80, -85,
- -86, -71, -73, -60, -35, -10, 9, 19, 49, 53, 47, 60, 73, 43, 33, 20,
- 13, -1, -7, -7, 7, 9, -2, 5, -14, -40, -69, -61, -66, -67, -84, -58,
- -58, -33, 2, -7, -5, 12, 32, 18, 25, 19, 24, 65, 59, 62, 64, 63,
- 55, 60, 52, 31, 19, -12, -26, -4, -7, -10, -3, 6, -22, -14, 12, 19,
- 4, -26, -38, -40, -56, -61, -66, -59, -65, -51, -20, 29, 40, 51, 52, 62,
- 61, 53, 26, 20, 6, 8, 6, 9, -14, -14, -15, -2, -11, -23, -36, -38,
- -60, -77, -69, -60, -51, -56, -44, -27, 10, -2, 14, 10, 22, 16, 41, 60,
- 39, 35, 60, 62, 43, 45, 63, 52, 17, 12, 15, -1, -2, 0, -38, -48,
- -32, -22, -7, 3, 13, 10, -2, -1, -8, -12, -25, -48, -46, -52, -49, -36,
- -17, 9, 17, 26, 48, 57, 55, 69, 60, 32, 6, 4, -6, -20, -24, -9,
- -21, -25, -14, -18, -38, -38, -32, -51, -52, -60, -34, -6, -6, -16, -11, -2,
- -1, 17, 19, 3, 11, 25, 31, 41, 39, 33, 33, 41, 34, 34, 23, 21,
- 15, 6, -13, -24, -28, -20, -8, -12, -19, -12, -5, 9, 14, 2, -12, -25,
- -28, -21, -28, -23, -22, -18, -26, -5, 24, 45, 46, 47, 39, 33, 36, 42,
- 29, 7, -5, -10, -21, -29, -39, -39, -31, -24, -29, -39, -51, -43, -27, -22,
- -18, -25, -26, -20, 9, 19, 18, 4, -2, 19, 30, 38, 25, 24, 28, 33,
- 41, 38, 34, 32, 38, 24, 8, 4, -8, -11, -15, -25, -31, -25, -20, -22,
- -15, -11, -9, -12, -17, -20, -20, -15, -6, -11, -8, 0, 11, 29, 19, 17,
- 17, 18, 28, 31, 25, 18, 23, 18, 10, 1, -7, -18, -26, -24, -30, -41,
- -38, -44, -32, -31, -31, -35, -25, -12, -2, -8, -11, -13, -13, -2, 8, 15,
- 19, 29, 35, 37, 39, 43, 42, 40, 35, 27, 25, 18, 15, 9, 4, -4,
- -15, -28, -28, -26, -28, -18, -15, -25, -23, -12, -11, -14, -10, -2, -4, -1,
- 8, 15, 19, 22, 25, 16, 16, 17, 5, 7, 13, 18, 13, 9, 6, 6,
- 4, -4, -21, -31, -28, -37, -39, -34, -38, -38, -32, -17, -6, -4, -14, -19,
- -9, 3, -2, 3, 4, 7, 8, 13, 23, 35, 38, 43, 42, 31, 25, 23,
- 17, 8, 3, 4, -7, -7, -10, -13, -20, -19, -28, -33, -30, -23, -18, -13,
- -17, -12, 3, 14, 23, 31, 27, 23, 21, 22, 19, 12, 4, 2, 2, -2,
- 0, 4, 11, 11, 6, 4, -2, -5, -14, -17, -30, -38, -44, -42, -28, -21,
- -23, -21, -15, -15, -4, 8, 11, 4, -7, -15, -7, 5, 10, 21, 26, 28,
- 27, 34, 37, 36, 28, 19, 10, 11, 8, -2, -18, -17, -19, -19, -22, -24,
- -21, -24, -18, -17, -13, -19, -13, -1, 12, 19, 22, 21, 19, 19, 30, 34,
- 24, 13, 7, 2, 1, 1, 2, -1, -2, -6, 0, 0, -2, -15, -21, -17,
- -21, -28, -32, -31, -31, -32, -27, -24, -17, -4, 1, -3, -1, 1, 4, 7,
- 8, 15, 16, 15, 15, 20, 32, 36, 38, 32, 19, 12, 3, 2, -2, -4,
- -11, -19, -17, -15, -11, -16, -20, -27, -30, -28, -22, -13, -6, -2, 2, 12,
- 23, 29, 45, 44, 36, 32, 21, 16, 14, 10, 1, -9, -8, -2, -1, -7,
- -13, -13, -12, -9, -11, -18, -24, -26, -28, -30, -24, -21, -21, -21, -11, -11,
- -10, 0, -2, 0, 4, 12, 13, 14, 12, 17, 22, 28, 30, 28, 20, 16,
- 13, 8, 2, -2, -6, -15, -14, -18, -15, -15, -16, -18, -18, -16, -19, -18,
- -17, -10, 0, -1, 4, 13, 22, 37, 39, 36, 27, 27, 32, 26, 15, 6,
- -1, -4, -5, -7, -11, -11, -9, -15, -15, -14, -18, -21, -19, -17, -21, -19,
- -15, -15, -10, -15, -14, -12, -11, -6, -2, 1, -2, 1, 5, 14, 22, 33,
- 35, 23, 18, 16, 13, 11, 6, 1, -9, -18, -11, -6, -7, -8, -9, -11,
- -11, -12, -13, -17, -21, -24, -24, -15, -4, 7, 12, 17, 25, 30, 28, 31,
- 32, 31, 27, 22, 15, 12, 3, -2, -8, -6, -3, -9, -13, -22, -24, -20,
- -18, -22, -24, -18, -14, -13, -10, -11, -9, -3, -2, -3, -5, -10, -10, -5,
- -1, 4, 11, 15, 19, 22, 27, 23, 20, 16, 14, 5, -3, -11, -15, -16,
- -12, -12, -11, -5, 1, -3, -10, -13, -15, -11, -10, -10, -11, -8, -3, 2,
- 7, 9, 15, 25, 30, 33, 31, 25, 21, 20, 16, 13, 7, -2, -8, -5,
- -4, -11, -20, -21, -22, -21, -17, -20, -21, -22, -19, -19, -11, -4, -2, -2,
- -2, 2, 5, 2, 0, 0, -3, 1, 8, 16, 13, 14, 17, 15, 13, 8,
- 5, -1, -6, -10, -13, -14, -14, -13, -10, -7, -8, -8, -6, -6, -3, -1,
- -1, -9, -12, -7, 3, 13, 17, 14, 13, 17, 22, 23, 24, 18, 15, 18,
- 18, 18, 15, 8, 0, -5, -8, -11, -15, -17, -21, -26, -26, -24, -26, -24,
- -13, -9, -6, -3, -2, 3, 4, 6, 7, 5, 2, 4, 2, -2, -4, -3,
- 5, 13, 17, 10, 3, -1, -2, -4, -5, -11, -14, -13, -11, -8, -8, -8,
- -6, -3, 0, -1, -5, -5, 0, 4, 3, 1, 2, 0, 0, 6, 13, 20,
- 17, 17, 18, 21, 18, 14, 13, 11, 11, 7, 9, 3, -5, -12, -14, -18,
- -21, -23, -26, -26, -13, -3, -6, -13, -14, -5, 5, 8, 3, 0, 1, 3,
- 6, 4, -1, -1, 1, 3, 7, 5, 3, 0, 1, -1, 3, 0, -3, -11,
- -11, -9, -10, -9, -8, -5, -7, -7, -10, -9, -6, -1, 4, 6, 4, 2,
- 5, 10, 13, 9, 12, 13, 14, 15, 16, 13, 12, 10, 13, 14, 13, 8,
- 2, -1, -4, -6, -9, -15, -20, -21, -19, -14, -16, -22, -21, -13, -5, -3,
- -3, -1, 3, 5, 10, 9, 9, 6, 8, 7, 7, 7, 3, -4, -6, -4,
- -1, -4, -8, -10, -11, -8, -4, -6, -10, -7, -8, -11, -11, -8, -5, -4,
- 0, 3, 3, 8, 10, 10, 12, 12, 11, 10, 13, 12, 10, 6, 8, 9,
- 9, 11, 13, 11, 9, 10, 7, 2, -3, -8, -9, -14, -16, -16, -19, -18,
- -14, -13, -11, -11, -10, -5, -1, 3, 5, 2, 2, 9, 14, 11, 9, 10,
- 7, 2, 0, 2, -2, -9, -13, -15, -18, -17, -15, -13, -10, -5, -5, -7,
- -7, -4, -1, 0, -2, -4, -2, 1, 4, 9, 10, 10, 11, 11, 13, 14,
- 10, 11, 9, 9, 4, 6, 5, 4, 5, 7, 8, 10, 9, 4, -4, -8,
- -9, -10, -11, -12, -14, -15, -17, -15, -9, -4, -1, -6, -5, 2, 8, 8,
- 6, 5, 3, 4, 5, 9, 10, 10, 5, -1, -5, -10, -12, -14, -16, -18,
- -17, -11, -10, -11, -8, -5, -2, -2, 0, 3, 4, 5, 3, 2, 3, 5,
- 9, 12, 12, 11, 10, 12, 14, 12, 8, 5, 0, -1, 1, 3, 0, 1,
- 3, 5, 6, 5, 0, -5, -11, -10, -13, -12, -13, -15, -14, -8, -4, -3,
- -3, -4, 0, 4, 5, 3, 6, 4, 4, 7, 10, 9, 9, 8, 5, 5,
- 2, -4, -10, -15, -17, -20, -22, -22, -19, -14, -11, -10, -8, -6, 0, 3,
- 5, 3, 4, 8, 11, 11, 12, 13, 12, 12, 15, 15, 16, 16, 13, 11,
- 6, 3, -2, -5, -5, -3, -2, -1, 2, 0, -3, -4, -5, -7, -10, -12,
- -11, -12, -11, -8, -4, -2, 0, 1, 2, 2, 2, 4, 3, 3, 4, 5,
- 9, 10, 6, 2, 1, 2, 0, -3, -7, -13, -18, -19, -18, -16, -18, -20,
- -19, -14, -8, -4, -1, 3, 3, 5, 7, 9, 9, 10, 12, 13, 13, 13,
- 13, 16, 15, 13, 9, 6, 3, 2, 1, 0, -3, -5, -6, -4, -2, -2,
- -4, -4, -5, -5, -3, -3, -4, -6, -6, -7, -4, 0, 2, 3, 2, 2,
- 1, 2, 2, 1, 4, 5, 4, 1, 0, 2, 2, 0, -2, -6, -8, -6,
- -7, -9, -11, -15, -18, -19, -18, -18, -17, -13, -9, -2, 2, 3, 5, 10,
- 12, 13, 14, 14, 15, 17, 17, 16, 16, 15, 13, 11, 7, 2, -6, -10,
- -8, -6, -8, -8, -7, -6, -6, -3, -4, -6, -5, -3, -2, -2, 0, 1,
- 0, 2, 2, 3, 2, 3, 2, 3, 3, 5, 2, 0, 4, 6, 5, -1,
- -4, -2, -1, -2, -6, -8, -9, -10, -12, -10, -14, -17, -22, -22, -21, -19,
- -15, -8, -3, 1, 7, 12, 12, 15, 19, 22, 21, 18, 16, 16, 16, 13,
- 12, 6, 3, 3, 2, -3, -6, -7, -12, -12, -11, -8, -9, -8, -7, -3,
- 0, 0, 0, 0, -2, -2, 0, 1, 2, 2, 4, 6, 6, 7, 5, 4,
- 3, 4, 5, 3, 0, -2, -2, -4, -6, -10, -8, -8, -10, -11, -12, -12,
- -12, -13, -16, -16, -16, -14, -11, -8, -4, -2, 1, 6, 12, 17, 19, 20,
- 20, 21, 21, 19, 13, 10, 9, 5, 0, -3, -4, -4, -5, -6, -6, -4,
- -7, -10, -12, -12, -12, -10, -7, -4, -2, 4, 6, 8, 7, 7, 7, 7,
- 8, 8, 7, 5, 6, 6, 4, 1, -1, -1, 0, -3, -7, -10, -10, -8,
- -11, -14, -14, -12, -11, -9, -6, -8, -8, -8, -11, -13, -12, -9, -8, -5,
- 0, 4, 8, 11, 14, 18, 18, 20, 23, 23, 20, 14, 9, 4, 0, -3,
- -6, -8, -8, -8, -8, -9, -10, -11, -10, -9, -8, -8, -7, -6, -3, 0,
- 3, 6, 12, 16, 16, 14, 10, 8, 9, 7, 4, 1, 0, 0, -2, -1,
- 0, 0, -3, -7, -10, -13, -13, -12, -13, -15, -14, -13, -9, -6, -5, -5,
- -7, -8, -9, -7, -6, -5, -7, -5, 1, 8, 13, 17, 19, 20, 21, 22,
- 22, 18, 12, 9, 5, -1, -5, -9, -11, -13, -12, -12, -11, -10, -8, -7,
- -7, -6, -7, -6, -3, 0, 1, 3, 7, 10, 11, 12, 15, 15, 14, 9,
- 6, 3, 1, 0, -2, -2, -2, -3, -6, -8, -10, -11, -13, -15, -15, -15,
- -13, -12, -12, -7, -5, -5, -5, -4, -3, -3, -4, -4, -1, -1, 1, 4,
- 7, 10, 12, 14, 17, 20, 22, 19, 14, 8, 5, 2, -2, -5, -10, -14,
- -13, -11, -10, -10, -10, -10, -8, -6, -3, -3, -3, -1, -1, 2, 6, 10,
- 13, 14, 15, 15, 15, 13, 11, 8, 5, 1, -1, -3, -3, -6, -10, -12,
- -12, -12, -12, -13, -15, -18, -19, -15, -11, -6, -4, -3, -4, -4, -2, 1,
- 4, 2, -1, -2, 1, 4, 6, 8, 7, 7, 11, 14, 15, 15, 15, 13,
- 10, 6, 1, -3, -6, -9, -13, -15, -15, -13, -11, -9, -9, -9, -7, -3,
- 0, 2, 2, 4, 7, 11, 15, 16, 14, 11, 12, 13, 15, 13, 9, 4,
- 1, -1, -4, -6, -8, -11, -15, -17, -17, -17, -17, -15, -13, -13, -12, -10,
- -7, -6, -4, 1, 2, 2, 3, 4, 5, 4, 4, 3, 5, 6, 6, 8,
- 7, 7, 9, 11, 10, 9, 8, 5, 2, 0, -2, -6, -10, -13, -13, -14,
- -14, -13, -11, -9, -4, -1, -1, -1, 2, 6, 8, 10, 11, 12, 14, 14,
- 14, 13, 11, 10, 7, 4, 2, 3, 1, -3, -6, -10, -14, -17, -18, -18,
- -19, -19, -17, -15, -13, -9, -5, -1, 1, 0, 1, 3, 5, 6, 6, 6,
- 7, 8, 9, 8, 4, 1, 0, 2, 4, 5, 6, 5, 4, 4, 4, 3,
- 1, -3, -7, -9, -11, -12, -12, -12, -11, -10, -7, -4, -2, 1, 4, 5,
- 8, 11, 13, 14, 14, 11, 11, 11, 10, 10, 9, 6, 5, 3, 1, -2,
- -5, -10, -14, -16, -17, -18, -19, -20, -19, -17, -14, -10, -5, -1, 1, 3,
- 5, 6, 6, 6, 6, 6, 6, 6, 6, 8, 7, 6, 4, 2, 0, -1,
- 0, 0, 1, 2, 1, 1, 2, 1, -2, -5, -8, -9, -10, -11, -12, -12,
- -10, -7, -4, -1, 2, 8, 11, 13, 15, 15, 13, 12, 11, 10, 9, 8,
- 6, 5, 4, 4, 3, 0, -3, -6, -10, -14, -18, -21, -22, -21, -18, -16,
- -13, -10, -6, -3, 0, 3, 5, 5, 5, 6, 7, 8, 8, 8, 7, 8,
- 7, 6, 5, 4, 1, 0, -2, -4, -4, -5, -4, -4, -3, -2, -1, -2,
- -3, -4, -7, -8, -9, -9, -9, -8, -5, -2, 2, 4, 8, 11, 14, 15,
- 15, 14, 12, 10, 7, 5, 4, 4, 2, 1, 1, 2, -1, -3, -7, -10,
- -15, -18, -18, -18, -18, -17, -15, -11, -7, -3, 1, 3, 4, 5, 6, 7,
- 7, 8, 8, 9, 10, 10, 9, 6, 4, 2, 0, -3, -4, -6, -7, -7,
- -6, -5, -3, -2, -2, -2, -2, -3, -4, -5, -6, -6, -6, -6, -5, -4,
- -1, 4, 7, 9, 11, 12, 12, 11, 10, 9, 8, 7, 5, 3, 3, 2,
- 1, 0, -1, -4, -7, -8, -10, -13, -14, -15, -15, -15, -14, -11, -9, -6,
- -3, 0, 2, 4, 5, 6, 7, 8, 9, 10, 10, 9, 8, 6, 5, 3,
- 1, -3, -6, -8, -8, -7, -7, -7, -6, -4, -2, 0, -1, -2, -3, -3,
- -3, -3, -4, -3, -3, -1, 1, 3, 4, 6, 7, 8, 9, 10, 10, 9,
- 7, 6, 6, 4, 3, 2, 1, -1, -2, -4, -6, -9, -11, -12, -12, -12,
- -11, -11, -10, -9, -8, -7, -5, -4, -1, 1, 3, 5, 7, 9, 10, 11,
- 10, 9, 8, 7, 6, 2, -1, -3, -4, -6, -7, -7, -7, -7, -6, -5,
- -5, -4, -3, -3, -4, -4, -4, -3, -2, 0, 0, 1, 1, 2, 4, 6,
- 6, 7, 7, 8, 7, 7, 7, 7, 7, 6, 5, 2, 0, -2, -4, -5,
- -7, -8, -8, -8, -9, -10, -10, -9, -8, -7, -7, -7, -5, -3, -2, 0,
- 1, 2, 4, 6, 9, 10, 11, 12, 10, 8, 6, 3, 1, -2, -4, -6,
- -7, -7, -7, -7, -8, -7, -7, -6, -6, -5, -4, -3, -3, -2, -1, 1,
- 2, 2, 3, 4, 5, 5, 5, 6, 6, 6, 5, 5, 6, 6, 6, 4,
- 3, 2, 1, -1, -3, -4, -6, -8, -9, -9, -8, -8, -6, -5, -5, -5,
- -6, -6, -6, -5, -4, -2, 0, 2, 4, 6, 7, 8, 9, 9, 9, 9,
- 6, 4, 1, -1, -3, -5, -6, -7, -7, -7, -6, -6, -6, -6, -6, -5,
- -4, -3, -3, -2, -1, 1, 3, 4, 5, 5, 5, 5, 5, 5, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 2, 1, -1, -3, -4, -5, -6, -7, -7,
- -7, -7, -7, -6, -5, -4, -4, -3, -3, -3, -3, -2, -1, 0, 1, 3,
- 5, 7, 8, 8, 8, 7, 6, 4, 2, 0, -2, -3, -4, -5, -6, -7,
- -7, -7, -7, -6, -6, -5, -5, -5, -3, -2, 0, 1, 2, 3, 4, 5,
- 6, 6, 6, 5, 5, 4, 3, 3, 3, 3, 3, 3, 2, 1, 1, -1,
- -2, -3, -4, -5, -6, -6, -7, -6, -5, -4, -3, -3, -3, -3, -3, -2,
- -1, -1, 0, 1, 1, 1, 2, 3, 5, 6, 6, 6, 5, 4, 2, 1,
- 0, -2, -4, -5, -5, -6, -6, -6, -7, -7, -7, -6, -5, -4, -3, -2,
- -1, 0, 2, 3, 3, 4, 4, 5, 5, 5, 4, 4, 4, 4, 3, 3,
- 2, 1, 1, 0, 0, -1, -1, -2, -3, -4, -5, -5, -5, -5, -5, -4,
- -4, -3, -3, -2, -1, -1, -1, -1, 0, 0, 0, 1, 2, 3, 3, 4,
- 4, 4, 4, 4, 3, 1, 0, 0, -2, -3, -4, -5, -5, -6, -6, -6,
- -5, -4, -4, -4, -3, -2, -2, -1, 0, 2, 3, 3, 4, 4, 4, 4,
- 3, 3, 3, 3, 2, 2, 1, 1, 1, 0, -1, -1, -2, -3, -3, -3,
- -3, -3, -3, -3, -3, -3, -3, -2, -2, -2, -1, -1, -1, 0, 0, 0,
- 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 1, 1, 0, 0, -1, -1,
- -2, -3, -3, -3, -4, -4, -4, -4, -3, -3, -2, -1, -1, -1, 0, 1,
- 1, 1, 2, 2, 2, 3, 3, 2, 2, 1, 1, 1, 0, 0, 0, 0,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- 0, 0, -8, -33, -24, -25, -25, -26, -27, -32, -28, -36, -31, -36, -22, -34,
- 11, -74, -14, 94, 41, 28, 33, 30, 40, 34, 23, 41, 40, 60, 56, 59,
- 60, 44, 39, 54, 45, 52, 17, 44, 62, 34, 33, 19, 18, 43, 35, 22,
- 36, -15, -10, 32, -7, -12, -6, -8, -50, -47, -44, -4, -25, -48, -76, -58,
- -75, -96, -85, -118, -114, -63, -106, -103, -83, -110, -99, -84, -76, -58, -63, -61,
- -51, -53, -36, -32, -41, -27, -11, 11, 8, 27, 19, 30, 35, 28, 57, 53,
- 38, 71, 51, 68, 110, 78, 89, 109, 97, 82, 94, 115, 114, 79, 70, 79,
- 94, 85, 76, 84, 95, 83, 82, 55, 54, 54, 41, 41, 27, 20, 6, -11,
- -21, -16, -14, -33, -33, -52, -54, -59, -62, -71, -79, -88, -88, -78, -78, -72,
- -71, -94, -99, -93, -90, -78, -87, -105, -103, -79, -62, -71, -78, -63, -61, -66,
- -49, -23, -10, -11, -24, -20, -4, -22, 9, 8, 27, 43, 34, 38, 51, 83,
- 65, 58, 74, 75, 70, 73, 71, 65, 100, 89, 94, 65, 84, 49, 49, 61,
- 54, 43, 51, 58, 53, 35, 40, 36, 38, 34, 23, 14, -12, -10, -1, -1,
- -11, -12, -19, -33, -66, -52, -42, -37, -55, -42, -28, -32, -29, -35, -41, -28,
- -25, -46, -85, -64, -62, -55, -49, -68, -55, -53, -52, -47, -43, -26, -32, -41,
- -34, -35, -40, -26, -8, -1, -6, -11, 5, -2, 8, 3, 8, 6, 4, 20,
- 29, 43, 24, 33, 20, 30, 24, 39, 38, 40, 29, 37, 36, 39, 61, 58,
- 41, 51, 59, 51, 55, 58, 48, 32, 45, 40, 27, 30, 41, 44, 26, 19,
- 23, -3, 7, 0, -3, 2, 3, -6, -5, -14, -6, -10, -27, -45, -47, -41,
- -38, -50, -51, -46, -43, -45, -65, -65, -80, -95, -82, -74, -66, -69, -67, -33,
- -31, -53, -48, -51, -43, -18, -24, -24, -33, -26, -10, 0, -17, -6, 17, 31,
- 2, 23, 45, 46, 12, 75, 38, 63, 69, 31, 38, 80, 57, 48, 59, 81,
- 74, 32, 52, 72, 24, 60, 44, 55, 40, 28, 48, 33, 24, 10, -2, 21,
- 34, 13, 18, 7, -1, -12, -20, -18, -30, -9, -7, -30, -27, -26, -38, -20,
- -54, -55, -64, -53, -36, -62, -37, -71, -47, -42, -71, -45, -55, -50, -54, -56,
- -36, -37, -54, -36, -12, -38, -33, -26, -7, -22, -44, -10, 2, 3, 15, 8,
- 18, 6, 12, 8, 15, 28, 22, 50, 35, 55, 42, 36, 49, 52, 64, 48,
- 60, 49, 60, 62, 40, 47, 68, 52, 59, 61, 44, 53, 44, 35, 31, 31,
- 47, 22, 6, 4, -7, 5, -4, -21, -13, -9, -10, -27, -46, -32, -44, -46,
- -62, -44, -51, -67, -53, -59, -63, -74, -67, -61, -61, -65, -47, -58, -57, -45,
- -41, -46, -41, -38, -22, -25, -34, -16, -10, -18, 0, 1, -6, 5, 17, 15,
- 10, 23, 38, 28, 28, 54, 40, 19, 55, 55, 41, 46, 53, 40, 49, 51,
- 52, 41, 56, 39, 53, 38, 33, 35, 18, 15, 38, 30, 23, 27, 13, 11,
- 7, 16, -1, 0, 0, 13, -6, -10, -15, -10, -10, -24, -20, -16, -38, -36,
- -21, -40, -32, -42, -38, -52, -53, -41, -48, -58, -50, -47, -37, -41, -45, -29,
- -41, -6, -48, -24, -25, -15, -9, -10, -10, -10, -1, -17, 4, 3, 10, -4,
- 9, 15, 25, 24, 19, 23, 34, 28, 33, 37, 38, 26, 36, 47, 35, 46,
- 45, 28, 35, 32, 32, 24, 21, 26, 23, 19, 37, 20, 9, 29, -2, 26,
- 24, 8, 4, 14, 21, 11, -9, -8, 4, -9, -31, -11, -15, -21, -24, -29,
- -22, -33, -26, -29, -48, -32, -44, -28, -22, -35, -30, -38, -31, -46, -44, -36,
- -27, -23, -29, -24, -11, -20, -28, -13, -34, -19, -1, 7, -3, -1, 6, -3,
- 5, 4, 8, 17, 26, 19, 33, 27, 16, 35, 14, 36, 39, 22, 32, 31,
- 19, 32, 23, 29, 21, 30, 29, 23, 31, 13, 24, 17, 11, 26, 18, 12,
- 5, 23, 16, 9, 15, -10, 3, 18, -15, -4, -4, 6, -14, -15, -5, -34,
- -11, -20, -18, -8, -17, -29, -30, -29, -19, -34, -35, -20, -36, -20, -16, -21,
- -38, -16, -30, -24, -25, -19, -18, -15, -7, -5, -5, -10, -23, -3, -14, 0,
- -1, -12, -9, 7, 7, 2, 12, 5, 7, 19, 10, 21, 21, 27, 30, 22,
- 18, 34, 22, 11, 26, 24, 20, 21, 25, 29, 22, 27, 27, 20, 10, 20,
- 16, 22, 15, 16, 16, 5, 19, 10, 3, 22, -5, -5, -7, -16, -4, -11,
- -22, -7, -16, -11, -23, -16, -30, -24, -28, -20, -29, -24, -32, -22, -22, -30,
- -17, -23, -28, -22, -20, -21, -21, -17, -30, -15, -14, -20, -9, 3, 6, 5,
- -20, 10, 13, -2, 11, 8, -1, 7, 16, 5, 22, 23, 13, 22, 13, 22,
- 25, 15, 16, 11, 15, 13, 7, 12, 19, 18, 20, 12, 23, 11, 6, 10,
- 1, 11, 19, 5, 20, 0, 11, 11, 1, 14, 15, -3, -1, -7, 6, -6,
- -9, -9, 4, -3, -10, -20, -14, -9, -14, -7, -10, -5, -4, -29, -14, -12,
- -26, -21, -27, -18, -10, -19, -27, -18, -8, -25, -8, -13, -15, -14, -15, 5,
- -13, -7, -11, -4, -12, 0, 15, 5, 4, 1, 11, 6, 4, 3, 6, 21,
- 19, 8, 15, 13, 6, 14, 16, 18, 17, 20, 15, 11, 15, 24, 13, 11,
- 19, 7, 17, 14, 6, 17, 7, 7, 6, 6, 5, 11, 0, 6, 0, -6,
- 5, 1, -11, -6, -1, -8, -9, -15, -7, -4, -16, -17, -13, -13, -17, -14,
- -12, -12, -28, -13, -19, -25, -31, -24, -17, -17, -16, -7, -15, -12, -8, -15,
- -8, -16, -10, -4, -1, -2, 3, 5, 2, -2, 5, 3, 6, 10, 8, 11,
- 14, 14, 13, 15, 22, 16, 14, 18, 13, 17, 19, 16, 10, 17, 8, 17,
- 14, 3, 14, 7, 10, 10, 7, 6, 6, -1, 6, 1, 0, 12, -6, 6,
- 12, -4, -5, -4, -2, -2, -1, -2, -8, -11, -9, -11, -11, -18, -6, -5,
- -16, -9, -14, -10, -13, -10, -11, -15, -14, -14, -12, -17, -17, -17, -7, -11,
- -14, -15, -12, -6, -15, -5, -13, -9, 0, 12, -2, -2, 6, 2, -7, 4,
- 10, 2, 9, 8, 7, 4, 5, 11, 15, 11, 10, 18, 9, 13, 13, 13,
- 21, 11, 18, 19, 13, 14, 16, 6, 8, 1, 19, 11, 10, 11, 1, 3,
- -1, -1, 5, -11, 5, -1, -5, -3, -13, -10, -6, -7, -5, -15, -10, -11,
- -18, -8, -16, -20, -18, -9, -12, -17, -21, -21, -13, -21, -8, -10, -10, -5,
- -16, -7, 2, -6, -6, -9, -7, -2, -9, -5, 6, -7, 1, 3, -1, 2,
- 1, 2, 9, 8, 5, 15, 12, 1, 11, 9, 8, 10, 15, 14, 5, 13,
- 17, 14, 15, 10, 7, 16, 5, 5, 5, 8, 9, 10, 10, 7, 0, 4,
- 6, 9, -10, -4, 5, 2, -1, 0, -3, -4, -5, -10, -5, -8, -9, -10,
- -3, -13, -6, -9, -20, -15, -11, -18, -14, -10, -12, -20, -14, -14, -7, -12,
- -21, -14, -9, -8, -11, -5, -2, -7, -4, 4, -2, -3, -1, 0, -1, 8,
- 6, 9, 7, 10, 6, 3, 4, 7, 10, 11, 6, 9, 17, 11, 9, 7,
- -2, 16, 13, 12, 18, 5, 16, 9, 4, 9, 6, 8, 9, 4, 4, 3,
- -2, -3, 2, -6, -3, 1, -7, -6, -3, -6, -14, -8, -9, -4, -13, -9,
- -8, -16, -10, -12, -13, -11, -7, -8, -12, -9, -8, -7, -11, -4, -8, -7,
- -8, -3, -13, -10, -3, 6, -5, -5, 0, -5, -3, 6, -2, -2, 4, -2,
- 6, 2, -2, 5, 5, -2, 5, 15, 13, 4, 6, 6, 14, 9, 4, 8,
- 7, 3, 11, 12, 2, 10, 7, 10, 8, 4, 6, 2, 0, 3, 2, 4,
- 2, -6, -2, 2, -4, 3, -5, -6, -5, -5, -5, -4, -8, -7, -4, -4,
- -7, -8, -7, -13, -10, -10, -11, -9, -8, -8, -7, -11, -7, -3, -9, -6,
- -7, -3, -4, -5, 3, -3, -1, -2, -4, 1, 4, 0, 3, 0, 5, 2,
- 0, 5, 4, 1, 3, 1, 0, 1, 7, 3, 0, 4, 3, 6, 5, 0,
- 9, 5, 7, 6, 3, 6, 2, 3, 5, -4, 9, 0, 4, 10, 0, 5,
- 1, -2, 4, -3, -3, -2, 0, 2, -7, 3, -10, -1, -6, -9, -2, -4,
- -10, -3, -7, -6, -4, -10, -6, -6, -11, -6, 0, -6, -8, -4, -1, -9,
- -10, 0, -6, -7, -2, -7, 1, -5, -5, -1, 1, -6, 2, 0, -3, -1,
- 7, -4, 0, 7, 0, 8, 2, 3, 4, 4, 2, 5, -1, 6, 7, 5,
- 6, 4, 2, 4, 6, 8, 6, 3, 1, 8, 9, 2, -1, 4, 3, 4,
- 3, -3, 7, 4, 3, -2, 2, -4, -6, -2, -5, -2, -3, 0, -5, -6,
- -13, -5, -6, -11, -9, -10, -5, -4, -9, -9, -7, -7, -8, -8, -6, -5,
- -7, -5, -1, -3, -4, -2, -2, 2, -3, 1, 2, -3, 1, 2, 1, 0,
- 1, 5, 0, 2, 5, 2, 0, 4, 1, 7, 3, 2, 6, 0, 5, 7,
- 5, 5, 1, 3, 3, 5, 10, 3, 4, 8, 2, 7, 3, -2, 3, 0,
- -1, -1, 1, 0, 1, -3, -2, -5, -4, -3, -1, -7, -8, -4, -4, -10,
- -2, -8, -8, -8, -8, -9, -6, -8, -9, -4, -2, -7, -5, -2, -7, -6,
- -9, -2, 0, -4, 4, -6, -3, -4, -1, 2, 1, 2, 9, 0, 3, 0,
- 6, 4, 0, 5, 6, 2, 7, 7, 5, 7, 6, 8, 6, 6, 5, 5,
- 1, 6, 5, -1, 3, 4, -1, 4, 1, 4, 3, -5, 0, 4, 1, 4,
- -2, -3, -4, 0, -4, -8, -2, -5, -4, -8, -6, -5, -3, -3, -7, -9,
- -6, -10, -10, -6, -6, -5, -4, -7, -6, -4, -10, -3, -10, 0, -2, -2,
- -6, -1, 3, -3, -3, 1, 2, 1, 4, 3, 4, 3, 4, 1, 2, 6,
- 5, 5, 5, 7, 9, 1, 5, 4, 4, 7, 2, 9, 2, 4, 8, 2,
- 5, 6, 3, -2, -2, -1, -2, -1, 1, -2, -4, 1, -6, -2, -5, -3,
- -5, -5, -6, -4, -3, -4, -10, -4, -3, -8, -4, 0, -3, -5, -6, -6,
- -3, -1, -7, -3, 1, -1, -4, -2, 1, -2, 0, -1, -2, 0, 0, 5,
- -2, 0, 3, 3, 1, 5, 2, 4, 1, 4, 1, 2, 3, 3, 3, 4,
- 3, 3, 5, 1, 4, 2, 3, 1, 2, 0, 2, 1, -2, -2, -1, 0,
- -2, -1, -1, -3, -5, -2, 0, -5, -1, 0, -5, -2, -2, -2, -3, -3,
- -1, -4, -1, -2, -4, -2, -1, -2, -1, 0, -3, -1, -1, 0, 1, -1,
- -1, 3, -4, -2, -2, 4, -2, -1, -1, -1, 0, 0, -1, -1, -1, -1,
- 2, 0, -1, 2, -1, 0, -1, 2, 0, 3, 5, -2, 1, 2, 0, 5,
- 0, -3, 4, -3, 1, 2, 0, 4, -1, -2, 1, 0, 0, 0, -1, 1,
- -2, 0, 1, 1, 0, -5, 1, -2, -1, 0, -2, -3, -1, -3, 0, -2,
- -3, -4, 1, -2, -3, -2, -2, -1, -1, -2, -1, -4, -5, 2, -4, 0,
- 1, -1, 2, -2, -1, 0, 0, 1, -3, 3, 2, 0, -2, 2, 1, 2,
- -2, 5, 3, -2, -2, -1, 1, 0, 0, 1, 3, 2, 0, 0, -1, -2,
- 1, 1, 2, 1, 1, -1, 0, -1, -1, -1, -3, 1, 1, 2, -2, -1,
- 0, 0, -2, 0, -1, -1, 2, -2, 1, -1, 0, 0, -1, -1, -2, 0,
- -1, 1, -1, -1, 2, -2, 0, -1, -1, 2, -1, 0, -3, -1, 0, 0,
- 0, -3, -3, -2, 0, 0, -1, -1, 0, -4, 2, 0, -2, 0, 1, -3,
- -1, 2, 1, 0, -1, 0, 0, -1, 0, 2, -1, -1, 0, 0, -2, 1,
- 1, 0, 1, 0, 2, -3, -2, 2, -1, -1, 2, -2, 1, 1, 0, 0,
- 1, 1, 0, -4, 3, -1, 2, 0, 2, -1, -2, 0, 1, 1, -1, -1,
- -1, -1, -1, -2, -2, -2, -2, -2, -1, -1, 1, 0, -5, 0, -1, -1,
- -1, 1, -1, 1, -1, 1, 0, -2, 0, -2, 1, -1, 1, 0, -1, -2,
- 0, -1, 0, 0, 2, 0, 0, 0, 1, 0, 0, 2, 0, -1, 0, 0,
- 0, 2, -1, 1, 1, -1, -1, 0, 0, 1, 1, 0, 0, 0, 0, -1,
- 0, 0, -2, 0, 0, -1, 1, -2, -1, -1, -1, -2, -1, -2, 1, -1,
- 0, -2, -2, 1, -2, -1, 1, 0, 1, 1, -1, -1, 0, -1, 0, 0,
- 0, -2, 0, -1, 0, 0, -1, -2, -2, -2, 1, -1, 0, 0, -1, 1,
- 1, -2, -1, -2, -1, 1, -1, -1, -2, -2, 0, 0, 1, -1, -1, -1,
- -1, -2, 2, 0, 0, 1, 1, 1, -2, 0, -1, 0, -1, -1, 2, 0,
- -1, -1, -1, 1, -1, 2, 0, -1, 1, 1, 0, 1, 0, -1, -1, -1,
- -1, -3, 0, 0, -1, 1, 0, 0, -2, -2, -2, 0, -1, 0, 0, -1,
- 0, -1, -2, -1, -2, 0, -2, 0, 0, -1, -2, 1, -2, 0, -1, -2,
- 2, 0, -1, 2, -1, 1, -1, 0, 0, -1, 0, 0, 0, -1, 0, 1,
- 0, 0, 1, 0, -1, -1, 0, -2, -1, 0, 0, 1, 0, 0, 0, 0,
- -1, -1, 1, -1, -2, -1, 0, 0, -2, 0, -1, 0, 0, 0, 1, 0,
- 0, -1, 1, 0, -1, 0, 1, -1, 0, -1, -2, 0, -1, 0, -1, -1,
- -1, 0, -1, 0, 0, 0, -1, -1, 0, -2, 0, 0, 0, -2, -2, 0,
- -2, -1, -1, -1, -2, 0, -1, -1, -1, 0, 0, -1, -1, 0, 1, -1,
- -1, 0, -1, 0, 0, 1, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1,
- -1, 0, 0, 0, 1, 0, 0, -1, 0, 0, -1, -1, 0, -1, -1, 0,
- -1, 0, -1, -1, 0, -2, -1, 0, -1, -1, -1, -1, 0, -1, 0, 0,
- 0, 0, -1, 1, 0, 0, 0, -1, -1, 0, -1, -1, 0, 0, 0, 0,
- 0, -1, -1, 0, -1, -1, 0, 0, -1, 0, -2, 0, -1, -1, -1, 0,
- -1, -1, 0, -1, 0, 0, 0, -2, -1, 0, -1, -1, 0, 1, -1, -1,
- 0, 0, 0, 0, -1, -1, -1, -1, 0, 1, 0, 0, 0, 0, 0, -1,
- 0, 0, 0, 0, 0, 0, -1, 0, 0, -1, 0, 0, -1, -1, -1, 0,
- 0, -1, -1, 0, -1, 0, 0, 0, -1, 0, -1, -1, 0, -2, -1, -1,
- -1, 0, -1, 0, -1, -1, 0, 0, -1, 0, -1, 0, -1, -1, -1, 0,
- -1, 0, -1, 0, 0, -1, 0, -1, 0, 0, -1, -1, 0, 0, 0, -1,
- 0, -1, 0, 1, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, -1, 0,
- 0, -1, -1, 0, 0, 0, -1, 0, 1, -1, -1, -1, 0, 0, -1, -1,
- -1, -1, 0, -1, 0, 0, 0, 0, 0, 0, -1, -1, 0, -1, -1, 0,
- -1, 0, -1, -1, -1, -1, 0, -1, -1, -1, -1, -1, -1, -1, 0, -1,
- 0, -1, 0, 0, -1, -1, 0, -1, 0, -1, 0, 0, -1, 0, -1, -1,
- -1, 0, -1, 0, 0, 0, 0, 0, -1, -1, 0, 0, 0, 0, 0, 0,
- 0, 0, -1, 0, 0, -1, 0, 0, 0, 0, -1, 0, -1, 0, 0, 0,
- -1, -1, 0, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, -1,
- -1, -1, 0, 0, 0, -1, 0, -1, -1, 0, -1, 0, 0, -1, -1, -1,
- -1, -1, 0, 0, -1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, -1,
- 0, 0, 0, 0, -1, 0, 0, 0, 0, -1, 0, 0, 0, 0, -1, 0,
- 0, -1, 0, -1, 0, 0, -1, -1, -1, 0, -1, -1, 0, -1, -1, 0,
- 0, -1, -1, -1, -1, 0, -1, -1, 0, 0, -1, 0, 0, 0, -1, -1,
- 0, -1, -1, -1, 0, 0, -1, -1, -1, -1, -1, 0, -1, 0, 0, -1,
- -1, 0, 0, -1, 0, 0, -1, -1, -1, 0, -1, 0, 0, -1, -1, 0,
- 0, -1, -1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, -1, -1, 0, 0, 0, -1, 0, -1, 0,
- -1, -1, -1, -1, -1, -1, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, 0, 11, -3, 47, -12, -15, -34, 3, 12, 38, 5, -24, -26, -9, -12,
- 63, -18, 12, -17, -50, 34, -6, 40, -2, -8, -37, -6, 9, 12, 32, -4,
- -33, 2, -33, 35, 20, 6, -11, -33, -11, 12, 23, 30, -21, -13, -28, -6,
- 33, 14, 7, -18, -22, -11, 18, 23, 5, -4, -22, -30, 29, -11, 40, -12,
- -15, -5, -11, 16, 13, -9, 5, -19, 3, 4, 2, 19, -28, 24, -41, 40,
- -9, -8, 4, -29, 28, -1, 22, -16, -32, 16, -22, 45, 19, -45, 17, -54,
- 25, 28, 33, -19, -30, -21, -25, 83, -20, 15, -3, -74, 12, 33, 4, 53,
- -26, -57, -9, 0, 36, 33, 8, -67, -2, -17, 27, 55, -17, -11, -31, -23,
- 24, 22, 6, 19, -55, 27, -48, 55, -8, 14, 7, -61, 26, -25, 34, 32,
- -26, 11, -50, 5, 14, -1, 67, -75, 47, -79, 29, 15, 8, 42, -49, 2,
- -34, -3, 51, -23, 52, -33, -32, -7, -14, 52, 6, 29, -73, 5, -9, -2,
- 64, -39, -6, 25, -60, 30, 5, 16, -13, 40, -61, 7, 20, -50, 75, -36,
- 10, -12, -4, -17, 23, 16, -18, 31, -38, -21, 33, -37, 56, -11, -5, -1,
- -43, 43, -56, 93, -67, 40, -17, -46, 60, -56, 62, -24, 14, -18, -23, 9,
- -16, 44, 19, -53, 58, -124, 81, -18, 32, 26, -43, -23, -28, 42, 1, 60,
- -27, -61, 14, -37, 42, 64, -32, -2, -43, -31, 25, 59, -7, -1, -19, -73,
- 51, 23, 18, 7, -24, -65, 29, 18, -2, 57, -47, -27, 4, -2, 16, 41,
- -25, -47, 36, -51, 49, 24, -37, 13, -15, -11, 12, 26, -58, 52, -20, -16,
- 31, -24, -20, 52, -16, -9, 32, -69, 5, 48, -34, 52, -12, -59, 20, -10,
- 30, 16, 21, -75, 1, 8, -33, 126, -57, 9, -37, -49, 32, 24, 62, -59,
- 19, -85, -2, 91, -23, 65, -49, -75, 19, -16, 68, 9, 16, -77, -3, 3,
- -13, 111, -69, 17, -30, -59, 56, 1, 19, 23, -26, -21, -24, 25, -31, 97,
- -59, 4, -16, -34, 40, 17, 16, -24, -6, -40, 26, 17, 3, 4, -23, -3,
- -1, 23, -8, 6, -29, -2, 21, -13, 22, -11, -31, 40, -35, 48, -27, 7,
- -39, 4, 28, -12, 55, -68, 9, -9, 2, 51, -21, -20, -18, -15, 33, 20,
- 15, -57, 41, -78, 72, -2, -7, 13, -60, 11, 13, 49, -19, 10, -55, -23,
- 59, -6, 22, 2, -79, 40, -11, 46, -11, 11, -66, 13, 24, -24, 80, -65,
- 5, -22, 1, 19, 23, -8, -27, -11, 2, 0, 64, -61, 21, -52, 34, 23,
- 7, -1, -51, 21, -41, 86, -45, 49, -62, -6, 0, 11, 51, -33, 16, -62,
- -1, 23, 8, 62, -45, -35, 7, -39, 88, -54, 70, -86, 33, -27, -1, 61,
- -60, 58, -62, 10, 15, -28, 65, -48, 11, -2, -44, 78, -64, 75, -78, 26,
- -29, 22, 40, -30, 16, -53, -12, 56, -15, 48, -51, -22, -10, 9, 52, -20,
- 40, -92, 16, -3, 26, 43, -19, -35, -31, 15, 13, 49, -11, -34, -24, -1,
- 9, 50, -12, -25, -17, -10, 15, 44, -20, 0, -28, -22, 32, 5, 27, -33,
- 15, -67, 61, -19, 19, 18, -46, -1, -1, 7, 18, 14, -27, -21, 18, -27,
- 42, 22, -56, 38, -56, 21, 17, 2, 5, -3, -11, -38, 48, -27, 32, 8,
- -50, 1, 10, -3, 38, -10, -16, -36, 34, -45, 74, -12, -30, 16, -52, 22,
- 24, 17, -1, -13, -41, -10, 50, -5, 41, -32, -62, 25, -5, 48, 24, -26,
- -61, 4, -2, 44, 62, -59, -23, -38, -4, 61, 34, 0, -57, -18, -41, 63,
- 36, 6, -1, -69, -11, 10, 19, 60, -31, 3, -64, 18, -19, 61, 10, -17,
- 10, -73, 13, 30, -7, 64, -39, -27, -34, 8, 20, 46, 24, -87, 29, -70,
- 51, 51, -12, 6, -44, -30, 10, 52, -7, 2, -6, -72, 63, -9, 17, 15,
- -37, -24, 14, 24, -11, 43, -55, -29, 42, -19, 47, 1, -49, -13, 13, 6,
- 38, 4, -59, -2, 7, 5, 61, -31, -42, 11, -32, 54, 14, -11, -23, -10,
- -20, 40, 19, -18, 0, -19, -28, 52, -14, -5, 29, -70, 53, -17, 19, -18,
- 15, -30, -2, 37, -41, 38, 7, -61, 67, -67, 35, 11, -12, 11, -34, 38,
- -61, 89, -59, 10, 28, -60, 52, -19, -22, 34, -30, 42, -42, 45, -68, 35,
- 19, -45, 80, -81, 26, -16, 4, 30, 0, -13, -19, -14, 23, -22, 75, -77,
- 47, -45, -5, 48, -36, 48, -50, 18, -35, 25, 5, 4, 14, -16, -33, 40,
- -49, 71, -38, 17, -30, -6, 12, 4, 31, -27, -6, -12, -11, 27, 15, -13,
- 12, -54, 32, -19, 53, -17, -1, -16, -39, 39, -5, 30, -3, -29, -13, -2,
- 23, 16, 4, -18, -41, 26, -11, 35, 18, -48, 13, -33, 28, 1, 38, -45,
- 5, -13, -18, 49, 1, -21, 16, -44, 14, 16, 7, -6, -5, -10, -18, 52,
- -33, 25, -11, -36, 31, -15, 14, 11, -22, 9, -27, 41, -42, 56, -50, 15,
- 10, -28, 30, -18, 3, 7, -7, 7, -16, 13, -27, 29, 5, -25, 42, -71,
- 44, -18, 21, 8, -7, -21, -15, 21, -9, 36, -2, -43, 17, -26, 14, 45,
- -33, 19, -40, 1, -3, 37, -5, -5, -2, -46, 38, 0, 7, 18, -33, -12,
- 11, -11, 33, 2, -16, -15, -3, 1, 18, 26, -32, -4, -14, -17, 54, -1,
- -1, -17, -35, 10, 12, 40, -12, -10, -30, -31, 51, -12, 65, -35, -34, -12,
- -32, 60, 22, 19, -33, -39, -20, 2, 75, 2, 9, -42, -72, 35, 13, 65,
- 5, -28, -60, -15, 23, 40, 44, -33, -34, -34, -5, 48, 33, 2, -21, -47,
- -15, 25, 33, 12, 7, -55, -12, 7, 19, 28, 9, -34, -28, 5, 7, 32,
- 15, -41, 8, -32, 10, 36, -4, 14, -40, 16, -45, 56, -15, 17, 0, -33,
- 2, 0, 7, 23, -12, -1, -26, 3, 6, 10, 24, -32, 21, -50, 33, -9,
- 15, 11, -24, 1, -12, 12, 4, 13, -10, -11, -2, -5, 7, 17, -23, 25,
- -27, 12, -6, 0, 8, -16, 18, -24, 31, -27, 9, -3, -2, 18, -4, -7,
- -11, -12, 10, 12, 15, -17, 7, -34, 18, 8, 4, 9, -18, -14, -3, 15,
- 9, 7, 0, -37, 21, -13, 16, 18, -32, 12, -23, 21, 3, 12, -14, -14,
- 3, -5, 24, 4, -21, 9, -32, 26, 14, -1, 12, -40, 0, -6, 24, 11,
- 3, -11, -34, 17, -8, 28, 18, -36, 9, -38, 13, 26, 11, 7, -20, -13,
- -34, 49, -24, 41, -8, -36, 4, -8, 3, 47, -11, -5, -24, -15, -9, 44,
- 8, -5, 8, -61, 17, 14, 14, 23, -15, -43, 1, -1, 28, 27, 1, -40,
- -6, -20, 18, 45, -22, 4, -20, -34, 39, 12, 3, 9, -31, -23, 15, 17,
- -7, 36, -36, -19, 30, -30, 36, 1, -16, -8, 5, -14, 20, 10, -13, 0,
- 6, -30, 37, -22, 3, 14, -27, 24, -15, 14, -15, 19, -22, 4, 17, -31,
- 29, -14, -10, 27, -26, 22, -14, 8, -17, 9, -2, -11, 33, -27, 14, 0,
- -29, 31, -21, 21, -7, -2, -14, -4, 20, -15, 37, -27, -9, 7, -24, 24,
- 8, -9, 12, -23, 7, -14, 30, -22, 25, -16, -20, 24, -27, 23, 8, -9,
- 6, -11, -18, 12, -3, 22, -14, 28, -61, 41, -32, 21, 29, -26, 8, -31,
- 2, 5, 28, 3, -9, -14, -21, -3, 48, -33, 49, -62, 9, -1, 6, 33,
- -24, 11, -44, 24, -2, 6, 25, -40, 8, 1, -16, 49, -41, 27, -41, 18,
- 0, 3, 31, -50, 36, -42, 22, 15, -18, 24, -34, 5, 12, -21, 52, -56,
- 52, -58, 29, -8, -8, 39, -51, 48, -47, 24, 4, -16, 22, -28, 6, 7,
- -22, 48, -55, 51, -44, 31, -10, -5, 8, -36, 41, -31, 35, -9, -16, 10,
- -17, 6, 21, -13, 10, -26, 5, -17, 39, -3, 3, 1, -43, 12, 1, 17,
- 15, -7, -24, -9, 5, 15, 17, 8, -38, 2, -25, 25, 15, 12, -13, -16,
- -11, 3, 19, 9, -9, -9, -15, 1, 19, -1, 14, -20, -1, -12, 15, -7,
- 11, -10, -2, -3, 10, -9, 18, -17, 2, -4, -3, 4, 3, -2, -5, 9,
- -9, 4, 5, -13, 5, 5, -21, 22, -16, 11, -4, 13, -22, 5, 3, -23,
- 35, -14, -6, 13, -24, 4, 17, -6, 6, -7, -6, -27, 43, -28, 25, 9,
- -45, 28, -23, 8, 25, -14, 0, -15, -4, -3, 27, 3, -15, 18, -59, 34,
- 3, -3, 38, -39, -11, 4, -9, 27, 9, -2, -38, 21, -31, 19, 47, -53,
- 43, -47, -11, 29, -2, 19, -7, -9, -36, 19, 12, -8, 53, -58, 1, 2,
- -33, 67, -23, 25, -44, 5, -25, 28, 32, -29, 32, -60, 0, 25, -7, 39,
- -14, -29, -12, 2, 11, 20, 23, -54, 18, -25, 1, 45, -10, -10, -4, -29,
- 7, 28, 7, -11, 9, -46, 16, 11, 8, 8, -7, -25, -3, 16, -3, 32,
- -25, -7, -20, 12, 0, 30, -14, -4, -15, -6, 6, 24, -9, 3, -16, -24,
- 23, -3, 27, -20, 15, -56, 42, -17, 21, 13, -27, -8, -2, 5, 8, 21,
- -21, -12, 4, -14, 15, 24, -39, 31, -38, 19, -2, 16, -16, 3, -6, -21,
- 30, -14, 16, 4, -30, 11, -7, 7, 12, -5, -10, -9, 9, -17, 37, -15,
- -5, 6, -26, 12, 13, -8, 7, -2, -18, 1, 17, -13, 15, 4, -37, 25,
- -18, 8, 13, 1, -23, 21, -25, 10, 7, -1, -6, 10, -15, -7, 21, -26,
- 29, -12, -3, -3, 0, -16, 29, -18, 21, -15, 1, -23, 22, -4, 3, 21,
- -43, 22, -19, 4, 21, -8, 4, -11, -7, -5, 7, 19, -20, 31, -47, 11,
- 2, -9, 44, -28, 8, -31, 5, -1, 20, 24, -38, 14, -32, -4, 47, -30,
- 38, -41, -1, -12, 12, 27, -16, 29, -57, 12, -1, 3, 38, -29, 3, -25,
- -1, 28, -10, 36, -52, 20, -33, 27, 14, -11, 18, -42, 13, 3, 3, 20,
- -21, 0, -20, 15, 4, 0, 23, -49, 28, -24, 18, 16, -15, -2, -26, 22,
- -10, 33, -7, -26, 11, -25, 19, 21, -14, 8, -33, 6, -2, 30, 2, -12,
- -6, -37, 34, -4, 22, 1, -33, -3, -4, 15, 20, 3, -20, -16, 2, -14,
- 38, -3, -7, 2, -24, -4, 22, -4, 11, -2, -15, -19, 21, -15, 24, 8,
- -21, 1, -12, -3, 9, 21, -22, 17, -26, -2, 6, 14, -8, 19, -24, -10,
- 8, -10, 17, 9, -7, -12, 8, -27, 29, -3, 4, -4, -3, -26, 25, -9,
- 13, 9, -19, -7, 2, -4, 10, 19, -29, 13, -16, -3, 18, 4, -12, 10,
- -24, 1, 6, 10, -9, 19, -26, -3, 16, -15, 20, -4, -16, 1, 3, -4,
- 9, 6, -19, 7, 3, -18, 26, -13, -7, 12, -13, 2, 9, -5, -7, 15,
- -18, 6, 8, -18, 13, -2, -12, 15, -12, 9, -6, -2, -16, 25, -14, 18,
- 1, -29, 11, -4, 14, 2, 3, -26, 6, -3, 1, 19, -3, -15, 12, -29,
- 17, -2, 12, -2, -4, -3, -28, 34, -21, 31, -7, -17, -3, -13, 20, 1,
- 14, -14, -22, 11, -13, 33, -2, -11, -4, -30, 33, -12, 30, -17, -17, -4,
- -4, 25, 2, 3, -20, -22, 20, -13, 42, -15, -11, -9, -16, 23, 8, 16,
- -28, -3, -11, 4, 27, -8, 5, -17, -9, 8, -2, 25, -27, 17, -32, 19,
- -4, 16, -8, -16, 6, -20, 32, 0, -14, 8, -34, 18, 12, 3, 13, -36,
- 11, -34, 49, -14, 22, -12, -38, 17, -21, 42, 5, -10, -12, -34, 8, 18,
- 18, 26, -50, 9, -50, 42, 16, 10, 10, -51, 2, -21, 38, 16, 7, -17,
- -29, -12, 13, 19, 25, -16, -7, -40, 14, 5, 23, 6, -11, -23, -3, 11,
- 2, 25, -26, 0, -12, 5, 4, 9, 2, -18, 10, -15, 5, 20, -26, 23,
- -28, 6, 8, 1, 12, -26, 10, -19, 20, 7, -14, 17, -37, 18, 1, -1,
- 23, -28, 9, -25, 20, 1, 6, 6, -23, 9, -15, 12, 10, -11, 5, -5,
- -12, 15, -8, 4, 4, -4, -6, 8, -11, 3, 6, -6, 0, 6, -12, 1,
- 14, -26, 27, -17, -3, 15, -18, 15, -10, 1, -6, 4, 9, -17, 28, -42,
- 18, 3, -17, 45, -38, 9, -12, -7, 19, 8, 7, -31, 8, -18, 6, 53,
- -51, 34, -41, -13, 32, -4, 17, -10, -6, -28, 25, 0, -2, 23, -32, -7,
- 21, -28, 36, -7, -14, 7, -10, -4, 13, -3, -7, 7, -5, -6, 14, -10,
- -10, 22, -29, 22, 0, -23, 24, -25, 15, 3, 3, -4, -9, 5, -23, 33,
- -10, -6, 22, -48, 31, -8, 7, 10, -15, -5, -14, 20, -7, 16, 3, -32,
- 20, -21, 13, 18, -20, 9, -25, 13, -3, 21, -4, -10, -4, -18, 18, 6,
- 2, 6, -32, 8, -4, 18, 10, -3, -21, -12, 3, 3, 28, -3, -18, -4,
- -14, 10, 19, 5, -9, -10, -21, 8, 21, 2, 11, -23, -12, -8, 14, 12,
- -1, 5, -31, 14, -9, 15, 7, -14, 5, -19, 11, -3, 5, 1, -11, 12,
- -13, 14, -6, -10, 5, -9, 16, -4, 3, -15, -5, 9, 2, 14, -11, -9,
- -7, -7, 22, -2, 12, -14, -15, -2, 2, 19, 0, 6, -28, -3, 0, 5,
- 27, -10, -8, -15, -9, 12, 10, 20, -25, 5, -23, 0, 27, -10, 21, -27,
- -3, -14, 17, 8, 1, 6, -28, 2, 7, -2, 21, -14, -6, -9, 3, 6,
- 2, 16, -33, 19, -17, 7, 10, -6, -3, -4, 0, 0, 11, -1, -13, 5,
- -9, -1, 25, -27, 19, -20, 3, 9, 1, 2, -11, 5, -19, 26, -4, -6,
- 13, -28, 10, 13, -11, 17, -19, -1, -10, 22, -4, -1, 13, -43, 29, -8,
- 3, 18, -25, 5, -13, 16, -5, 12, 0, -29, 25, -23, 14, 17, -29, 23,
- -23, 8, 2, 0, 4, -8, 11, -25, 22, -8, -6, 28, -35, 19, -6, -17,
- 25, -15, 9, -5, 1, -12, 10, 5, -14, 22, -24, 0, 18, -23, 23, -9,
- -10, 8, -1, -1, 4, -4, -13, 8, 6, -7, 22, -27, -8, 10, -6, 23,
- 1, -17, -10, -9, 15, 14, 15, -17, -24, -1, -11, 41, 4, -4, -12, -35,
- 12, 13, 19, 12, -22, -25, -6, 8, 22, 17, -3, -36, 7, -21, 21, 32,
- -22, 8, -23, -17, 17, 15, 1, 10, -19, -20, 2, 10, 3, 23, -13, -21,
- 7, -19, 26, 12, -10, 4, -35, 4, 7, 12, 19, -17, -3, -24, 14, 7,
- 7, 15, -43, 12, -13, 8, 37, -29, 13, -34, 11, 2, 11, 14, -34, 22,
- -31, 20, 14, -14, 18, -29, 5, -4, 3, 13, -11, 13, -23, 9, -3, -5,
- 22, -22, 12, -10, -11, 15, -2, 6, 4, -10, -15, 11, -5, 10, 8, -14,
- -12, 12, -10, 16, 17, -37, 16, -18, -3, 31, -11, -1, -9, -8, 0, 22,
- 6, -21, 9, -32, 14, 26, -19, 27, -40, 6, -4, 13, 14, -14, 3, -34,
- 21, 1, 10, 15, -32, 5, -10, 5, 19, -10, 3, -21, 10, -7, 14, 9,
- -23, 18, -25, 9, 7, -5, 4, -1, -8, -2, 15, -17, 16, -5, -17, 16,
- -13, 9, 3, 2, -17, 13, -10, -2, 29, -33, 17, -15, -10, 23, -6, 12,
- -14, -3, -9, 2, 26, -23, 28, -45, 14, -1, 1, 33, -35, 17, -34, 15,
- 10, 3, 12, -31, 7, -15, 18, 19, -19, 12, -39, 16, 5, 8, 17, -37,
- 16, -35, 39, -3, 8, -5, -31, 9, -4, 26, 0, -3, -18, -15, 19, -2,
- 25, -12, -21, 1, -16, 26, 4, 6, -20, -1, -14, 11, 21, -20, 22, -32,
- 0, 14, -9, 19, -10, -2, -13, 14, -9, 4, 17, -36, 30, -20, -2, 22,
- -21, 13, -11, 7, -12, 15, -6, -15, 25, -29, 20, 3, -18, 17, -17, 7,
- -3, 11, -9, -4, 13, -33, 34, -10, -5, 22, -34, 11, -4, 8, -1, 11,
- -14, -16, 24, -27, 31, 3, -29, 19, -23, 2, 26, -11, 1, -3, -14, -4,
- 27, -14, 3, 9, -38, 26, -1, -7, 20, -15, -12, 14, -8, 4, 7, -11,
- -10, 12, -3, 0, 16, -28, 7, 1, -2, 14, -7, -10, -5, 4, 5, 9,
- 3, -22, 4, -5, 0, 27, -18, 1, -9, -10, 13, 10, 1, -9, -1, -21,
- 15, 11, -8, 15, -21, -8, 12, -4, 13, 0, -12, -5, 2, -1, 9, 2,
- -8, 0, -4, 1, 4, -1, -1, -1, -1, -2, -15, 21, -17, 23, -30, 1,
- 34, -34, 6, 5, -15, 19, 1, -25, 6, 20, -2, -28, 15, 10, -15, 0,
- -7, 10, 7, -5, -9, -6, 19, -3, -21, 3, 20, -4, -20, 1, 16, -3,
- -8, -2, 5, 1, -8, -6, 3, 9, 2, -13, -4, 15, -7, -9, 0, 3,
- 6, -7, -7, 5, 8, -8, -4, 0, 1, 1, -6, -4, 7, 2, -2, -7,
- 0, 4, -3, -4, 0, 2, 0, -2, -4, 1, 4, -2, -4, -3, 1, 3,
- -5, -4, 4, 3, -6, -5, 4, -1, -2, -3, 0, 3, -3, -1, -4, 3,
- 3, -5, -3, 1, 1, -2, -3, 1, 2, -2, -4, 0, 0, 0, -1, -3,
- 1, 1, -3, -2, 1, 0, -2, -2, 0, 0, -2, -1, 0, -1, 1, -2,
- -2, 1, 0, -2, 0, -1, 0, -1, -1, -1, 0, 0, -1, -3, 1, 1,
- -2, -2, 0, 1, -1, -2, -1, 0, 0, 0, -2, -1, 1, 0, -3, 0,
- 2, -1, -2, 0, 0, 0, -2, 0, -1, 0, -1, -1, 1, 0, -1, 0,
- -1, 1, 0, -13, 5, 7, -11, 24, -50, 41, 4, -29, 14, -11, 8, 11,
- -15, -12, 15, 18, -21, -14, 22, -2, -11, -3, -3, 18, -3, -5, -14, 9,
- 22, -24, -16, 23, 12, -23, -8, 9, 10, -4, -8, -3, 11, -4, -14, 0,
- 8, 8, -5, -14, 8, 10, -12, -4, -2, 10, 0, -11, -3, 11, 0, -7,
- -2, -1, 7, -6, -8, 3, 6, 0, -3, -8, 7, 2, -7, -2, 2, 1,
- -2, -4, -1, 3, 3, -4, -5, 1, 3, -3, -6, 2, 5, -1, -7, -1,
- 3, -1, -4, -3, 5, 0, -3, -2, -1, 4, -1, -5, -1, 3, -1, -4,
- -1, 3, 1, -4, -2, 1, 0, -2, -3, 0, 2, -1, -4, 1, 1, -1,
- -2, -2, 1, -1, -3, 0, 0, 0, -1, -2, 0, 0, -2, -1, 0, -1,
- 0, -2, -1, 0, -1, 0, -1, -2, 2, -1, -2, -1, 0, 1, -2, 0,
- -1, -1, 0, -1, -2, 0, 1, -1, -3, 0, 1, -1, -3, 0, 1, -2,
- -1, 0, 0, -1, -1, 0, -1, -1, -1, -1, 0, 0, -1, -1, 0, 0,
- -2, 0, 0, 0, 0, -2, 1, -1, 0, -1, 0, 0, 0, -1, 0, 0,
- 0, 0, -1, 0, 0, -1, 0, -1, 1, 0, 0, 0, 1, -1, -1, 0,
- 0, 0, 1, -2, 4, -3, 3, -40, 71, -73, 67, -27, -68, 127, -80, 3,
- 5, 1, 17, -14, 1, -30, 53, -3, -42, 15, 19, -9, -17, -1, 13, 16,
- -17, 4, -32, 43, 15, -68, 18, 54, -38, -7, -1, 11, 7, -3, -18, 5,
- 25, -27, -9, 9, 19, -6, -12, -8, 20, -1, -15, -1, 1, 17, -10, -16,
- 12, 12, -13, 0, -6, 10, 2, -16, -1, 14, -4, 4, -11, -2, 12, -6,
- -8, 4, 4, -2, -4, 1, -2, 4, 3, -7, -5, 8, 0, -10, 1, 4,
- 2, -4, -6, 4, 1, -1, -7, 1, 8, -9, 2, -5, 3, 3, -4, -3,
- 0, 3, -3, -5, 4, 3, -3, -4, 0, 2, 0, -3, -4, 5, 0, -5,
- -1, 2, 0, -3, 0, -1, 2, -2, -4, 3, 0, -1, -2, -1, 2, -2,
- -2, 1, -1, 0, -1, -3, 1, 1, -2, 1, -3, 1, 1, -3, -1, 1,
- 0, -1, -2, 1, -1, -1, 1, -2, 1, -1, -1, -1, -1, 0, 1, -3,
- 0, 0, 1, -4, 0, 1, -2, 0, -2, 0, 0, 0, -2, 1, -1, 0,
- -2, 0, 2, -2, -1, 0, -1, 2, -2, -1, 1, -2, 0, -1, 1, -1,
- -1, -1, 1, -2, 1, -1, -1, 2, -3, 0, 0, -1, 1, -1, 0, 1,
- 0, -2, 0, -1, 1, -2, 0, 0, -1, 1, 0, -2, 0, 1, -2, 1,
- 0, 0, -1, 0, 1, -1, -1, -1, 1, 1, -1, 0, 0, 0, -1, 1,
- 0, -1, 1, 0, 0, 1, 0, -1, 1, 0, 3, -40, 58, -39, 12, 42,
- -117, 108, 1, -66, 22, 17, 0, -9, 10, -39, 42, 4, -23, -12, 28, 3,
- -34, 9, 17, 3, -9, 10, -29, 13, 53, -79, 3, 64, -26, -24, 16, -9,
- 14, 2, -8, -15, 31, -9, -30, 11, 29, -15, -7, 0, 3, 6, -4, -9,
- -6, 22, 1, -24, 9, 11, -8, 0, -2, 2, 8, -12, -6, 10, 2, 2,
- -9, -4, 11, -2, -10, 3, 2, 3, -5, -1, 1, -1, 6, -4, -8, 9,
- 2, -8, -3, 6, 3, -4, -3, -1, 6, -2, -8, 0, 9, -4, -3, -2,
- 2, 4, -4, -1, -1, 4, -2, -6, 4, 2, -1, -4, 0, 1, 2, -3,
- -5, 3, 3, -3, -4, 3, 0, -1, 0, -2, 2, 0, -3, 0, 3, 0,
- -3, -1, 2, 0, -3, 1, 0, -1, 2, -2, -2, 2, -1, 0, -1, -1,
- 1, -1, -2, 0, 0, 1, -3, 1, 0, -1, 1, -2, -1, 2, -2, -1,
- 0, -1, 2, -3, -1, 1, 1, -2, -2, 2, 1, -2, -1, 0, 0, 1,
- -3, 1, 0, 0, 0, -2, 3, 0, -2, 0, 0, 1, 0, -1, 1, -2,
- 0, 0, 0, -1, 1, 0, 0, 0, -1, 1, -1, 1, 0, -1, 1, -2,
- 0, 1, 1, 0, 1, -2, 1, 0, 1, 0, 0, 3, -1, 0, 1, 0,
- 0, 3, -29, 35, -12, -16, 56, -88, 39, 62, -79, 5, 29, 1, -13, 12,
- -29, 26, 17, -28, -3, 12, 5, -11, -19, 28, 1, -5, 9, -21, -7, 60,
- -56, -20, 57, -10, -27, 21, -21, 16, 12, -12, -21, 24, 6, -29, 4, 19,
- 2, -7, -5, -3, 7, 6, -11, -9, 11, 13, -18, -4, 13, 1, -3, -6,
- -1, 10, -8, -6, 5, 3, 5, -3, -11, 4, 9, -11, 0, 4, 3, -4,
- -1, 0, 0, 7, 0, -14, 7, 5, -7, -4, 4, 5, -1, -4, -4, 4,
- 1, -4, -4, 7, -1, -1, -3, 0, 5, -1, -4, -1, 2, 0, -3, 1,
- 1, 2, -2, -4, 1, 2, 0, -5, 2, 3, -2, -2, 1, 1, -2, 2,
- -3, 0, 0, -1, -1, 0, 1, 0, -3, 0, 0, -1, 1, -1, -2, 1,
- -1, 0, -2, 2, 1, -2, -1, 1, 0, -1, -1, 0, 1, -1, 0, -2,
- 1, 1, -1, 0, -1, -1, 0, 0, -1, -1, 0, -1, -1, 2, -2, -1,
- 1, 0, 0, -1, -1, 1, 0, -1, 1, -1, 0, 1, -3, 1, 1, -1,
- -1, 0, 1, 0, 0, 0, -1, 0, 0, -1, 0, 1, 0, 0, 2, -2,
- 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, -1, -1, -7, -9,
- 35, -52, 59, -33, -32, 64, -15, -41, 19, 22, -20, 9, -11, -3, 33, -27,
- 2, 7, -9, 19, -37, 24, 7, -11, 11, -1, -30, 37, 8, -57, 36, 19,
- -33, 14, 0, -17, 26, 1, -20, -5, 26, -18, -13, 14, 7, -6, 4, -9,
- -4, 11, 3, -14, -7, 20, 0, -18, 10, 1, 4, -5, -7, 6, 0, -3,
- -2, -2, 8, 5, -11, -6, 10, -1, -10, 6, -2, -1, 1, -3, 0, 3,
- 5, -9, -5, 9, -3, -4, 1, 1, 3, -1, -4, -1, 2, -2, -5, 5,
- -3, 0, 1, -5, 4, 2, -3, -3, 0, 0, -2, 1, 0, -2, 3, -2,
- -5, 2, 2, -2, -4, 3, 0, -2, 1, -2, -2, 5, -2, -6, 1, 2,
- -1, -1, 0, 1, -1, -2, -1, -1, 2, 0, -4, 0, 1, 0, -3, 0,
- 2, 0, -3, 0, 0, 1, -1, -1, 1, 0, -1, -2, 1, 0, 0, -1,
- 0, -2, 1, 0, -1, 1, -1, 0, -2, 1, 1, -2, -1, 2, -2, 1,
- -3, 1, 1, -1, 0, 0, -1, 1, 0, -2, 2, -1, -1, 0, 0, 1,
- 0, 1, 0, -2, 1, 0, 0, -1, 1, 0, 0, 0, 0, -3, -20, 45,
- -56, 40, -5, -34, 27, 24, -42, -1, 29, -14, -4, 2, -7, 24, -20, -1,
- 18, -25, 25, -29, 9, 21, -26, 14, 4, -20, 7, 27, -42, 5, 31, -24,
- -2, 19, -30, 21, 8, -11, -17, 20, 1, -22, 11, 7, -7, 6, -5, -7,
- 3, 11, -6, -18, 11, 16, -20, 1, 5, 2, -3, -3, 0, -3, 4, -1,
- -7, 2, 10, -9, -8, 7, 2, -9, 5, -1, -5, 2, 1, -3, -2, 9,
- -5, -8, 4, 1, -5, 0, 1, 2, -1, 0, -5, 4, -1, -5, 4, -3,
- 1, 1, -5, 3, 0, 0, -3, 0, -1, -2, 1, 2, -5, 2, 1, -5,
- -2, 3, -1, -5, 2, 1, -4, 2, -1, -4, 2, 3, -7, -1, 2, 0,
- -2, 1, 0, -2, -1, 0, -3, 1, 2, -3, -2, 3, 0, -3, -1, 1,
- 0, -1, -2, -1, 1, 0, 0, -1, 0, 0, -2, 0, 0, 1, -2, 2,
- -3, 1, 0, 0, -2, 1, 0, -1, 0, 0, -1, -1, 2, -3, 0, 0,
- -1, 0, 0, -1, 1, 0, -4, -13, 32, -41, 31, -10, -10, 4, 22, -25,
- -8, 21, -3, -14, 5, 1, 12, -23, 8, 18, -31, 25, -26, 10, 17, -23,
- 8, 5, -9, 0, 16, -25, 2, 23, -22, -2, 22, -30, 15, 7, -6, -13,
- 12, 1, -17, 9, 5, -6, 4, -3, -7, 5, 7, -6, -13, 7, 10, -11,
- 0, 0, 4, -3, -3, 2, -7, 4, 2, -5, 0, 6, -3, -8, 4, 2,
- -8, 7, 0, -8, -1, 6, 0, -8, 6, 0, -5, 1, 0, -5, 3, 2,
- -3, -2, 4, -5, -1, -1, -2, 3, -4, 1, -1, -3, 3, -1, -2, -2,
- 1, -2, -2, 1, 1, -4, 1, 2, -5, -3, 5, -3, -4, 4, -1, -4,
- 2, -1, -4, 3, 1, -5, -2, 2, 0, -2, 2, -1, -4, 3, -1, -3,
- 0, 1, -2, -2, 1, -1, -1, -1, 0, 0, -1, -1, -1, 0, -1, 1,
- -1, -1, 0, -2, 1, 0, -1, -1, 0, -1, -1, -1, 2, -2, -1, 1,
- -1, -2, 1, -1, -1, 1, -2, 1, -7, -3, 15, -23, 20, -16, 9, -12,
- 16, -12, -8, 11, 5, -18, 6, 8, 0, -18, 16, 4, -19, 16, -17, 10,
- 5, -8, -2, 9, -5, -4, 10, -17, 5, 13, -18, 2, 12, -17, 10, 0,
- -2, -8, 7, -4, -7, 6, 1, -3, 1, 3, -9, -2, 10, -7, -8, 4,
- 6, -6, 1, 0, 0, -2, 1, -1, -8, 6, 1, -5, 2, 4, -2, -4,
- 1, 1, -7, 5, -1, -4, -2, 4, 0, -4, 4, -3, -4, 1, 0, -3,
- 0, 2, -1, -2, 2, -2, -1, -3, 0, 3, -4, 3, -3, 0, 2, 0,
- -3, -1, 1, -3, -1, 2, 0, -1, 0, 0, -3, 0, 1, -4, -1, 2,
- 0, -2, 0, 1, -3, 1, 1, -3, -2, 2, -1, -1, 2, -1, -2, 1,
- 0, -1, -1, 0, 2, 33, 42, 58, 71, 79, 85, 88, 91, 94, 79, 95,
- 82, 106, 86, 105, 47, 16, -6, 13, 44, 31, -15, -38, -36, 20, 70, 41,
- 48, 58, 24, -57, -127, -119, -102, -126, -128, -111, -78, -82, -88, -87, -60, -66,
- -98, -104, -99, -97, -99, -104, -101, -88, -87, -91, -61, -27, -34, -54, -55, -45,
- -24, -10, -5, -4, 5, 34, 63, 101, 94, 78, 52, 51, 52, 74, 81, 77,
- 59, 46, 17, 7, 39, 53, 47, 42, 66, 83, 73, 52, 28, 22, 11, 8,
- 11, 0, -15, -23, -15, -14, -6, 16, 46, 62, 71, 76, 90, 102, 103, 103,
- 101, 100, 90, 75, 63, 67, 49, 37, 28, 12, 5, 6, 15, 15, 8, -7,
- -12, -4, -10, -28, -24, -17, -25, -50, -64, -81, -103, -116, -116, -113, -95, -72,
- -54, -41, -47, -65, -65, -50, -33, -24, -7, 11, 8, -4, -13, -28, -51, -75,
- -90, -91, -90, -90, -87, -88, -83, -84, -82, -81, -81, -76, -65, -71, -85, -84,
- -79, -83, -81, -77, -72, -70, -65, -66, -66, -65, -66, -68, -61, -56, -51, -36,
- -13, -3, -5, -8, -12, -12, 3, 16, 21, 31, 50, 69, 77, 82, 90, 102,
- 110, 114, 116, 117, 118, 119, 116, 112, 109, 105, 98, 99, 103, 102, 91, 73,
- 64, 63, 61, 57, 51, 40, 24, 35, 57, 75, 84, 79, 65, 37, 4, -26,
- -45, -57, -54, -46, -45, -54, -67, -67, -48, -16, 15, 35, 44, 45, 44, 45,
- 46, 38, 23, 2, -15, -34, -52, -60, -70, -77, -80, -79, -74, -77, -84, -86,
- -80, -72, -68, -72, -80, -87, -92, -96, -101, -104, -104, -101, -93, -90, -89, -86,
- -85, -84, -83, -82, -81, -79, -77, -76, -73, -71, -66, -62, -55, -39, -31, -27,
- -25, -31, -37, -46, -51, -53, -54, -48, -45, -38, -20, 3, 24, 35, 39, 32,
- 16, 5, 3, 0, -6, -13, -13, -11, -2, 14, 28, 40, 50, 53, 50, 55,
- 64, 74, 90, 105, 108, 112, 106, 104, 109, 112, 123, 127, 127, 127, 127, 127,
- 127, 118, 113, 107, 110, 114, 111, 104, 101, 101, 102, 103, 99, 99, 89, 73,
- 53, 35, 20, 0, -22, -43, -63, -77, -82, -76, -65, -48, -36, -29, -24, -25,
- -29, -37, -40, -49, -59, -67, -73, -76, -78, -79, -75, -73, -74, -75, -68, -52,
- -44, -30, -19, -9, -6, -9, -13, -24, -33, -35, -31, -30, -35, -40, -44, -45,
- -51, -53, -54, -50, -50, -47, -42, -50, -55, -54, -56, -56, -54, -54, -49, -48,
- -41, -32, -28, -18, -13, -5, 6, 18, 33, 49, 60, 71, 78, 88, 95, 97,
- 93, 88, 91, 93, 97, 98, 97, 94, 91, 85, 81, 72, 70, 66, 61, 60,
- 64, 66, 74, 83, 92, 102, 108, 109, 107, 102, 97, 95, 91, 87, 80, 74,
- 67, 62, 61, 58, 61, 61, 57, 53, 43, 35, 27, 25, 24, 20, 20, 22,
- 27, 34, 36, 32, 21, 8, -3, -10, -16, -18, -16, -16, -19, -15, -11, -11,
- -12, -20, -34, -45, -59, -72, -80, -89, -94, -95, -102, -111, -114, -111, -111, -108,
- -106, -104, -101, -98, -93, -90, -86, -86, -83, -82, -81, -79, -76, -73, -70, -72,
- -78, -81, -79, -79, -72, -60, -43, -31, -25, -27, -34, -37, -40, -42, -41, -39,
- -36, -34, -25, -12, -4, 5, 12, 16, 17, 15, 13, 6, -4, -7, -8, -6,
- -1, 4, 7, 9, 12, 16, 19, 19, 22, 28, 29, 28, 29, 30, 34, 40,
- 49, 57, 71, 78, 85, 92, 96, 95, 89, 85, 86, 93, 99, 104, 102, 100,
- 94, 85, 77, 73, 69, 66, 63, 60, 60, 59, 57, 52, 47, 41, 31, 18,
- 6, -3, -7, -11, -12, -14, -18, -22, -23, -22, -24, -30, -37, -41, -44, -50,
- -56, -64, -67, -65, -62, -58, -58, -58, -59, -61, -62, -66, -72, -78, -79, -77,
- -73, -68, -64, -61, -56, -53, -54, -52, -52, -57, -63, -69, -70, -68, -65, -62,
- -59, -57, -56, -58, -60, -61, -63, -64, -62, -61, -60, -58, -54, -49, -45, -42,
- -39, -36, -32, -28, -22, -13, -7, -3, 2, 13, 28, 41, 52, 64, 71, 73,
- 73, 70, 64, 61, 60, 64, 66, 65, 66, 64, 61, 60, 62, 65, 64, 66,
- 67, 67, 68, 66, 64, 66, 68, 73, 76, 74, 72, 66, 58, 52, 46, 42,
- 38, 38, 41, 47, 52, 52, 48, 45, 42, 40, 38, 34, 29, 27, 26, 28,
- 29, 28, 29, 30, 31, 28, 24, 21, 19, 17, 14, 10, 6, 3, -4, -9,
- -15, -19, -26, -33, -40, -49, -55, -60, -65, -70, -73, -72, -72, -71, -70, -71,
- -75, -78, -81, -83, -86, -86, -85, -84, -82, -80, -77, -72, -69, -66, -63, -61,
- -61, -61, -61, -61, -60, -58, -53, -48, -42, -36, -30, -28, -30, -32, -33, -32,
- -31, -28, -22, -18, -10, -5, 0, 3, 6, 11, 16, 19, 22, 24, 26, 27,
- 29, 34, 40, 46, 48, 48, 48, 45, 40, 36, 33, 31, 33, 35, 40, 48,
- 55, 62, 68, 73, 76, 78, 78, 77, 79, 82, 85, 87, 87, 87, 86, 86,
- 86, 83, 78, 71, 63, 55, 48, 44, 39, 36, 36, 36, 35, 32, 28, 24,
- 18, 13, 9, 6, 4, 1, -2, -5, -11, -17, -20, -21, -20, -21, -24, -28,
- -32, -34, -33, -33, -35, -37, -40, -43, -47, -52, -58, -63, -69, -74, -77, -80,
- -81, -82, -81, -80, -77, -74, -69, -62, -54, -48, -48, -51, -54, -57, -57, -57,
- -56, -55, -55, -56, -57, -56, -55, -54, -54, -54, -54, -52, -49, -45, -41, -38,
- -34, -31, -29, -27, -24, -20, -17, -11, -7, -3, 0, 5, 10, 16, 22, 27,
- 31, 34, 38, 42, 44, 45, 48, 50, 52, 57, 61, 64, 64, 65, 65, 63,
- 60, 57, 55, 55, 58, 61, 63, 65, 67, 69, 71, 74, 77, 79, 79, 77,
- 74, 71, 68, 66, 63, 60, 57, 55, 51, 46, 40, 36, 30, 25, 20, 17,
- 16, 17, 16, 14, 12, 10, 7, 3, -1, -5, -11, -15, -17, -18, -18, -19,
- -21, -25, -29, -32, -33, -33, -36, -39, -43, -46, -50, -53, -56, -58, -59, -60,
- -61, -62, -63, -65, -66, -67, -68, -70, -72, -72, -70, -67, -63, -61, -60, -60,
- -58, -56, -54, -53, -52, -52, -52, -51, -50, -49, -47, -45, -43, -40, -37, -35,
- -34, -32, -29, -25, -21, -18, -14, -9, -4, 0, 4, 7, 11, 15, 18, 21,
- 25, 28, 33, 37, 41, 44, 46, 47, 47, 46, 46, 45, 43, 42, 42, 43,
- 46, 48, 49, 50, 52, 55, 59, 62, 65, 66, 67, 68, 69, 69, 70, 72,
- 74, 74, 73, 72, 71, 69, 65, 61, 57, 53, 50, 46, 43, 38, 35, 32,
- 28, 23, 19, 17, 17, 15, 13, 11, 9, 5, 1, -3, -6, -9, -12, -14,
- -17, -19, -23, -27, -31, -35, -38, -40, -43, -46, -48, -52, -55, -57, -61, -64,
- -66, -67, -68, -69, -70, -70, -70, -69, -69, -70, -71, -70, -66, -62, -59, -55,
- -52, -50, -46, -43, -41, -38, -36, -35, -35, -34, -33, -33, -33, -33, -31, -30,
- -28, -26, -25, -24, -21, -20, -20, -19, -19, -18, -17, -16, -15, -13, -11, -8,
- -3, 2, 9, 15, 21, 27, 33, 38, 41, 45, 48, 51, 53, 55, 56, 56,
- 56, 56, 56, 56, 56, 55, 57, 58, 60, 61, 62, 62, 64, 66, 68, 69,
- 71, 72, 73, 74, 72, 70, 67, 63, 60, 57, 54, 50, 46, 41, 36, 31,
- 27, 23, 19, 16, 14, 12, 11, 9, 8, 5, 2, -1, -4, -8, -10, -15,
- -18, -19, -20, -22, -22, -23, -23, -24, -26, -29, -31, -33, -35, -36, -37, -38,
- -41, -44, -46, -48, -50, -52, -54, -56, -59, -61, -63, -63, -64, -65, -64, -63,
- -62, -61, -60, -59, -58, -57, -58, -57, -57, -55, -53, -50, -49, -47, -46, -43,
- -40, -37, -33, -31, -28, -26, -23, -20, -16, -14, -12, -9, -5, -2, 1, 5,
- 9, 13, 17, 21, 24, 26, 29, 32, 35, 37, 37, 38, 39, 41, 43, 44,
- 45, 46, 48, 50, 51, 53, 52, 52, 50, 48, 47, 46, 46, 46, 46, 47,
- 48, 49, 51, 54, 56, 58, 60, 61, 62, 62, 62, 61, 59, 57, 55, 54,
- 53, 52, 51, 49, 46, 41, 36, 31, 27, 22, 18, 14, 11, 9, 6, 3,
- 0, -2, -5, -8, -11, -16, -20, -25, -28, -31, -34, -37, -39, -41, -41, -42,
- -42, -42, -43, -45, -46, -47, -49, -50, -52, -54, -56, -57, -58, -60, -61, -63,
- -64, -64, -64, -63, -63, -61, -59, -58, -57, -55, -54, -53, -52, -52, -51, -50,
- -49, -47, -46, -45, -44, -42, -40, -38, -35, -32, -30, -28, -25, -22, -19, -17,
- -15, -12, -9, -5, -1, 3, 7, 11, 15, 19, 23, 25, 27, 30, 34, 36,
- 37, 38, 39, 40, 42, 44, 45, 46, 47, 49, 50, 52, 53, 52, 51, 49,
- 47, 47, 46, 46, 46, 47, 47, 48, 50, 52, 55, 57, 59, 61, 62, 62,
- 62, 61, 60, 58, 56, 54, 54, 53, 51, 50, 47, 44, 39, 34, 29, 25,
- 20, 16, 13, 10, 7, 4, 2, -1, -3, -6, -9, -14, -18, -22, -26, -30,
- -33, -35, -38, -40, -41, -41, -42, -42, -43, -44, -46, -47, -48, -49, -51, -53,
- -55, -56, -57, -59, -60, -62, -63, -64, -64, -63, -63, -62, -60, -59, -57, -56,
- -55, -53, -52, -52, -51, -51, -50, -48, -46, -45, -44, -43, -41, -39, -36, -34,
- -31, -29, -26, -24, -21, -16, 1, -2, -1, -9, -9, -6, 5, 6, -1, -10,
- 8, 24, 11, -2, -14, -9, -15, -13, 5, 14, 12, -6, -1, -12, 1, -9,
- 12, 12, 10, 5, -19, -11, -13, -2, 8, 5, 1, -2, -3, 9, -6, 6,
- 5, 6, -3, -17, -7, 3, 2, -1, 0, 7, -7, 5, 4, 6, -18, -24,
- 6, 20, -1, -4, -1, 10, 3, -10, 8, 7, -11, -17, -15, 5, 18, 4,
- 1, 8, -16, -4, 0, 11, 9, -10, -15, 0, -22, -12, 19, 34, 16, -9,
- -16, -7, -12, -10, 13, 23, -1, -10, -2, -3, -11, 13, 7, -6, -9, 3,
- 11, -10, -18, 12, 22, 7, -27, -29, -4, 20, 20, 10, 8, -16, -26, -6,
- 22, 21, 7, 15, 8, -50, -50, -7, 35, 22, -13, 32, 41, -33, -46, -10,
- 23, -7, -25, 23, 21, -38, -36, 14, 44, 2, 2, 34, -14, -51, -29, 11,
- 19, 7, 22, 13, -23, -21, -8, -9, 1, 14, 26, 26, -8, -34, -33, 4,
- 1, -6, -2, 16, -7, -23, 12, 27, 5, 6, 6, 0, -8, 0, -1, -17,
- -13, -12, 3, 9, 4, 11, 23, 36, 0, -43, -16, 4, -21, -26, 27, 16,
- -25, 3, 65, 4, -34, 24, -10, -38, -14, 13, 4, -15, 36, 44, -42, -51,
- 20, -5, -6, 68, 20, -18, -39, -11, 9, 17, 6, -33, -20, -13, 48, 30,
- 22, -4, -9, -53, -20, 32, 32, -16, 17, -11, -36, -8, -5, 39, 28, 33,
- 21, -64, -48, 3, -22, 15, 62, -26, 0, 3, 5, 73, -14, -48, -20, -59,
- 4, 70, 60, -7, -2, -88, -22, -17, 39, 17, 33, -3, 15, 28, -47, -80,
- -37, 5, 7, 104, 16, -99, -92, -36, 109, 78, 26, -15, -92, -21, 62, 48,
- -51, -81, -25, 55, 63, 35, 21, -115, -54, 101, 73, -41, -110, -66, 50, 107,
- 45, -8, -109, -38, 12, 102, 3, 17, -45, -2, -36, 39, 46, -12, -28, -27,
- -17, 17, -18, 82, -5, -3, -25, -5, -14, 15, 9, -3, -17, -6, 2, 7,
- -36, -13, 6, 21, -23, -20, 16, -18, 3, -2, 26, 0, 13, -23, -2, -19,
- -28, -18, 15, 12, 22, -4, 23, -17, -22, -9, -18, -4, 11, 13, 0, 34,
- -16, -20, 26, 23, 15, -4, -25, 7, 8, -9, 8, 44, 1, -40, 17, -32,
- 9, -30, -52, 52, 3, 2, -21, 83, 58, -14, -46, -61, -12, -67, -20, 64,
- 72, 57, -10, 5, 1, -77, 31, -47, -39, 12, 22, 57, 28, 0, 9, -76,
- 15, -74, 33, -12, 39, 114, -35, -36, -38, -23, 27, -21, 14, 56, 47, 6,
- -72, -61, -4, 18, -4, 19, 13, 45, 71, 48, -1, -125, -52, -56, -20, -18,
- -12, 51, 78, 68, -46, 32, -40, -29, -28, -81, -25, 75, 42, 58, -38, 1,
- -29, -34, 31, -36, -14, 10, 64, 37, 2, -31, -72, -17, -33, 30, -52, -54,
- 25, 43, 70, 81, -9, -73, 4, -65, 15, -28, 25, 0, 28, 19, 51, -26,
- 6, 0, -37, -15, -22, -20, -16, -5, 50, 56, 67, 25, 16, -35, -29, -14,
- -39, 19, -24, -52, -13, -32, -10, 39, 33, 59, 6, 37, 55, 11, -9, -35,
- -15, -57, -56, -36, -34, 19, 19, 6, 20, 17, -11, 5, 26, 19, 16, 7,
- -20, -26, -55, -62, -36, -18, 19, 37, 47, 25, -6, -14, 1, -4, -13, 12,
- 23, 34, 38, 41, 33, 31, -10, -56, -52, -49, -31, -40, -21, -12, 0, 5,
- 12, 22, 22, 21, 31, 12, 2, -8, -4, -18, -7, 3, 1, -1, 11, 12,
- 18, 17, 9, -2, -12, -13, -11, -1, 8, 3, 3, 2, 5, -5, -16, -15,
- -13, -8, -12, -9, -2, -1, 2, 7, 10, 7, 11, 14, 7, -1, -4, 5,
- -3, -2, 0, -6, -10, -1, -5, 3, 9, 0, -8, -9, -6, -6, 0, 6,
- 3, 6, 7, 10, 0, -8, -3, -5, -1, -8, -7, -4, -3, -3, 0, -1,
- -6, 2, 7, 7, 5, 4, 10, 5, 8, -1, -11, -15, -11, -15, -10, -1,
- -8, -12, -5, 1, 3, 6, 8, 11, 18, 22, 26, 10, -10, -1, -15, -3,
- -21, -16, -14, -12, -7, -8, -18, -20, -11, 9, 20, 27, 26, 11, 1, 21,
- 6, 3, -9, -15, -9, -20, 3, 5, 21, 14, 6, 11, -21, -22, -6, -21,
- -23, -18, 11, 6, 5, 21, 9, 23, 16, -3, -30, -7, -27, -4, 5, 18,
- 22, 16, 2, 7, -1, -2, -10, -14, -10, -17, -10, -15, -16, 3, 12, 30,
- 18, -1, -6, -15, -3, 5, 11, -18, -2, 8, 21, 11, -13, -4, -30, -7,
- 0, 12, 25, -3, 17, 14, -20, -6, -27, -41, -11, -12, 23, -8, 13, 24,
- 18, 27, -11, -8, -12, -2, 17, 23, 13, -20, -21, -2, -21, -34, -46, -23,
- 28, 48, 9, -10, 8, 29, 27, 5, -29, -12, 13, -5, -2, -35, 1, 3,
- 24, 13, 17, -18, -30, -21, 14, -1, 6, -8, 48, 45, -7, -34, -49, -32,
- -6, -26, 20, 29, 76, 30, -21, -66, -36, -15, 40, -5, 29, 3, 10, -39,
- -25, -2, 24, 19, 19, -4, -8, 3, -22, -23, -18, 13, 17, -3, -25, 23,
- 66, 26, -18, -27, -34, -30, -30, 36, 25, 28, -22, -17, -7, -22, 21, 18,
- 42, 8, -25, -28, -31, -10, 15, 18, 0, -1, -5, 16, -12, 13, 13, 12,
- -8, -37, -9, 13, -5, 8, -3, 13, -8, 4, 24, -16, -43, -18, 26, 26,
- -11, -9, 19, 9, -15, 9, 15, -12, -31, -27, 8, 29, 5, 7, 17, -33,
- -14, 14, 23, -1, -18, -18, -4, -35, -17, 47, 71, -16, -20, -11, -16, -25,
- 6, 37, 14, -18, 1, -8, -14, 10, 14, 2, -20, 0, 20, -10, -25, 14,
- 32, 7, -39, -38, -3, 34, 25, 13, 3, -24, -34, 5, 38, 18, 7, 29,
- -30, -74, -41, 36, 40, -12, 26, 55, -17, -59, -26, 28, -2, -31, 24, 25,
- -44, -39, 21, 44, -1, 10, 33, -34, -50, -12, 18, 13, 20, 17, -6, -31,
- -10, -6, -1, 7, 12, 14, 6, -16, -24, 6, 9, -16, -16, 6, 2, -10,
- 13, 12, -10, 0, 11, 11, 10, -3, -22, -22, -12, -7, 19, 17, -2, -12,
- 6, 16, 7, -11, -1, -20, -22, -8, 26, 16, -3, 12, 1, -33, 2, 30,
- -23, -5, 28, -17, -19, 21, 9, -28, -14, 25, -1, 4, 24, 0, -26, -9,
- 7, 2, -2, 20, -10, -11, 5, -3, -4, 8, -9, 14, 18, 25, -22, -15,
- -22, -3, -12, 27, 30, 15, -11, -26, -4, 15, -7, -14, 23, -23, -4, 34,
- -2, -38, 14, -11, -24, 16, 34, 11, -13, 3, -3, -19, -34, 0, -3, 24,
- 43, 1, -12, -38, -25, -11, 23, 35, 12, -28, -25, -16, 7, 22, 1, -10,
- 8, 8, -3, 6, -24, -20, -13, 9, 31, 12, -16, 7, -29, 5, 8, -28,
- 3, 4, 12, 26, -9, -15, -5, -20, 9, 21, 0, 1, -9, 0, 8, -3,
- -7, -9, -3, 22, 8, 3, -11, -9, -11, 3, 15, 9, -10, 1, -3, -3,
- -2, -5, 9, 0, 12, 7, -15, -7, 0, -8, 5, 9, -5, 7, -7, 10,
- 4, -11, -2, -8, -4, 9, 9, 0, -2, -11, -3, -4, 3, 4, 3, -2,
- 3, 3, -8, -9, -2, 0, 3, 5, -1, -10, -7, 2, 8, 3, 0, -5,
- -5, 2, 4, -2, -5, -3, 2, 3, 0, 2, -5, -3, 3, 2, -2, -4,
- -2, 1, 2, 1, 0, -1, 1, -2, -5, 0, 0, 2, 0, -3, -2, 0,
- 1, 0, -2, -2, -2, 0, 3, 3, -2, -5, -1, -1, -1, -4, 3, 9,
- 1, -1, -2, -11, -7, 1, 9, 11, 8, -4, -11, -12, -9, -4, 18, 15,
- 14, 1, -22, -29, -14, 3, 30, 29, 14, -2, -35, -43, -11, 13, 36, 42,
- 15, -16, -49, -44, -10, 28, 47, 38, 11, -25, -66, -39, 4, 36, 58, 33,
- -3, -44, -65, -29, 19, 52, 54, 23, -13, -59, -65, -15, 32, 69, 49, 8,
- -30, -74, -51, 3, 43, 71, 40, -5, -48, -77, -31, 16, 57, 67, 24, -15,
- -67, -72, -12, 36, 66, 59, 5, -31, -80, -51, 3, 49, 75, 37, -2, -59,
- -81, -28, 20, 67, 66, 22, -23, -76, -65, -10, 41, 78, 48, 4, -36, -85,
- -47, 6, 59, 80, 31, -8, -69, -82, -22, 29, 73, 63, 17, -31, -81, -63,
- -1, 47, 79, 47, 3, -56, -90, -40, 19, 75, 73, 28, -25, -86, -74, -10,
- 48, 85, 56, 6, -51, -93, -48, 11, 67, 86, 33, -11, -78, -87, -29, 36,
- 89, 66, 13, -38, -91, -60, 2, 50, 83, 48, 0, -56, -90, -41, 16, 71,
- 78, 30, -17, -80, -75, -20, 31, 82, 62, 15, -32, -85, -66, -7, 48, 84,
- 50, 4, -53, -87, -44, 8, 62, 78, 35, -8, -65, -83, -30, 23, 70, 71,
- 24, -20, -76, -75, -12, 32, 73, 62, 15, -30, -85, -62, -2, 41, 76, 51,
- 9, -39, -86, -52, 1, 45, 79, 46, 8, -49, -89, -46, 3, 54, 80, 43,
- 7, -55, -83, -50, 0, 53, 76, 54, 11, -52, -83, -55, 0, 40, 67, 58,
- 22, -32, -79, -67, -11, 28, 63, 52, 37, -9, -70, -63, -28, 10, 42, 49,
- 53, 8, -46, -64, -41, 1, 22, 38, 51, 39, -16, -63, -46, -23, 5, 33,
- 38, 48, 14, -42, -57, -29, -5, 22, 37, 40, 28, -23, -53, -39, -10, 14,
- 30, 40, 31, -1, -48, -40, -18, 11, 19, 31, 26, 14, -20, -50, -25, -5,
- 11, 31, 30, 14, 0, -35, -39, -4, -1, 19, 27, 17, 9, -10, -39, -21,
- -8, 9, 24, 26, 13, -5, -19, -30, -12, -1, 17, 25, 16, 3, -19, -26,
- -13, -6, 17, 22, 20, 5, -16, -32, -19, -1, 23, 27, 23, 4, -30, -33,
- -23, -1, 35, 35, 24, -2, -41, -45, -21, 9, 45, 41, 22, -12, -50, -46,
- -18, 28, 55, 45, 10, -27, -78, -42, 0, 53, 66, 32, -1, -61, -74, -28,
- 27, 64, 64, 24, -28, -80, -66, -15, 53, 84, 48, 5, -59, -94, -41, 17,
- 75, 80, 26, -21, -91, -79, -12, 48, 87, 55, 10, -58, -96, -46, 9, 80,
- 81, 30, -23, -84, -80, -15, 49, 90, 49, 9, -57, -95, -45, 17, 76, 79,
- 26, -20, -91, -75, -18, 52, 90, 52, 6, -59, -92, -41, 15, 68, 80, 31,
- -21, -87, -76, -13, 45, 87, 49, 11, -60, -94, -35, 14, 80, 68, 22, -23,
- -89, -66, -7, 47, 93, 44, -8, -61, -95, -31, 24, 86, 75, 10, -35, -96,
- -66, -1, 61, 100, 44, -12, -77, -105, -33, 32, 97, 92, 16, -44, -111, -90,
- -5, 65, 121, 65, -3, -80, -123, -59, 17, 98, 111, 46, -25, -112, -109, -33,
- 42, 112, 90, 30, -55, -115, -84, -17, 66, 105, 71, 13, -73, -113, -61, 0,
- 77, 96, 56, 4, -80, -108, -50, 8, 78, 93, 47, 3, -88, -98, -40, 7,
- 65, 76, 53, 18, -71, -90, -44, 0, 39, 57, 43, 34, -19, -69, -54, -19,
- 18, 32, 31, 34, 7, -40, -36, -21, -1, 12, 12, 25, 27, -9, -32, -14,
- -14, 2, 0, 1, 20, 19, -2, -13, -11, -18, -12, -2, 18, 24, 12, -2,
- -14, -19, -19, -12, 18, 24, 22, -2, -15, -32, -20, 3, 22, 26, 17, -13,
- -31, -27, -13, 17, 33, 32, 5, -29, -47, -29, 2, 33, 42, 32, -6, -53,
- -52, -24, 22, 51, 41, 27, -32, -74, -45, 0, 45, 59, 33, -1, -62, -66,
- -31, 26, 73, 49, 17, -42, -80, -42, -8, 63, 72, 28, -10, -75, -72, -23,
- 32, 88, 47, 13, -56, -93, -38, 10, 76, 69, 26, -20, -96, -66, -10, 48,
- 90, 47, 0, -69, -103, -29, 25, 87, 73, 18, -35, -104, -68, -2, 61, 93,
- 47, -5, -83, -98, -31, 30, 92, 68, 17, -39, -97, -63, -5, 64, 88, 35,
- -9, -74, -86, -22, 31, 85, 54, 13, -44, -93, -46, 9, 65, 75, 23, -17,
- -75, -78, -15, 39, 84, 54, 3, -52, -96, -46, 12, 71, 90, 29, -18, -89,
- -87, -26, 36, 86, 72, 26, -37, -106, -77, -12, 45, 99, 68, 22, -46, -108,
- -73, -10, 43, 87, 69, 19, -27, -92, -79, -12, 27, 63, 57, 26, 4, -53,
- -75, -35, 12, 33, 37, 31, 26, -9, -53, -39, -16, 6, 20, 23, 22, 13,
- -8, -22, -23, -18, -3, 9, 25, 19, 4, -8, -20, -17, -10, 6, 16, 17,
- 13, -8, -34, -21, -6, 17, 33, 23, 6, -32, -51, -23, 11, 36, 46, 31,
- -11, -46, -65, -31, 15, 59, 55, 28, -20, -73, -64, -26, 42, 78, 51, 14,
- -53, -85, -48, -4, 70, 80, 38, -16, -80, -76, -32, 39, 90, 58, 19, -59,
- -99, -50, 14, 71, 75, 36, -21, -94, -70, -23, 51, 88, 53, 9, -68, -97,
- -40, 16, 83, 73, 29, -33, -100, -61, -13, 58, 87, 41, 0, -74, -81, -35,
- 24, 87, 55, 20, -41, -88, -58, 0, 69, 73, 34, -5, -86, -75, -20, 38,
- 79, 49, 13, -48, -90, -39, 2, 71, 68, 31, -16, -84, -67, -15, 38, 79,
- 42, 12, -50, -85, -37, 2, 62, 71, 34, -5, -83, -75, -24, 27, 82, 51,
- 27, -30, -88, -54, -15, 44, 73, 50, 16, -49, -81, -47, -6, 38, 58, 50,
- 27, -31, -69, -52, -13, 15, 36, 45, 33, -5, -41, -44, -23, 2, 14, 27,
- 33, 10, -25, -20, -18, -6, 1, -1, 17, 22, 3, -13, -10, -17, -13, -6,
- 13, 24, 15, 1, -11, -19, -19, -16, 12, 24, 24, 3, -12, -29, -26, -1,
- 18, 27, 19, -4, -31, -28, -19, 11, 30, 35, 12, -21, -46, -35, -6, 28,
- 42, 36, 5, -46, -57, -31, 10, 50, 43, 33, -16, -71, -55, -9, 35, 62,
- 38, 10, -51, -71, -40, 11, 69, 58, 24, -26, -81, -50, -18, 48, 79, 37,
- 1, -62, -81, -32, 16, 84, 59, 20, -37, -96, -50, -2, 63, 78, 33, -4,
- -85, -80, -20, 33, 88, 59, 10, -50, -107, -47, 14, 75, 85, 27, -19, -95,
- -83, -15, 47, 94, 60, 8, -66, -105, -46, 15, 83, 81, 26, -23, -91, -76,
- -18, 48, 92, 47, 1, -59, -94, -36, 18, 78, 66, 19, -27, -91, -60, -3,
- 53, 80, 35, -8, -62, -86, -28, 27, 79, 66, 13, -38, -94, -62, 1, 56,
- 95, 42, -6, -75, -96, -39, 22, 80, 80, 36, -20, -97, -92, -24, 30, 93,
- 79, 32, -27, -102, -87, -22, 31, 81, 79, 29, -14, -81, -91, -25, 19, 56,
- 63, 31, 11, -39, -77, -47, 3, 31, 37, 33, 27, 3, -48, -46, -20, 0,
- 18, 22, 23, 16, -3, -20, -19, -15, -4, 2, 8, 5, 0, 0, 0, 1,
- -1, -1, 3, -4, -2, 1, -1, -2, 2, 3, -6, 1, 2, -6, 2, 2,
- -4, -1, 2, -5, 1, 4, -4, 0, -1, 0, -1, -2, 2, 2, -6, 0,
- 4, -3, -3, 4, -2, -3, -2, 0, 1, 1, -2, -2, 3, -8, 27, -42,
- 11, 21, -35, 34, -25, 12, 9, -24, 14, 13, -38, 53, -42, -3, 46, -73,
- 55, -16, -9, 28, -49, 38, -12, -21, 49, -51, 20, 32, -73, 64, -28, -7,
- 32, -50, 42, -11, -30, 49, -21, -31, 46, -25, -7, 20, -22, 18, -16, -10,
- 21, -23, 5, 28, -35, 8, 0, 8, -26, 19, 6, -11, -20, 64, -46, -18,
- 51, -73, 119, -117, 46, 36, -80, 67, -46, 22, 0, -24, 56, -59, 14, 26,
- -40, 24, -9, 20, -20, -15, 43, -26, -11, 9, 14, -3, -31, 6, 54, -62,
- 3, 67, -78, 20, 21, -25, 31, -41, 18, 27, -53, 32, 15, -48, 37, -11,
- 4, -12, -3, 31, -24, -21, 42, -10, -45, 55, -32, 34, -43, -14, 86, -78,
- 8, 39, -35, -2, 13, 2, 5, -11, -4, 7, 5, -31, 37, -4, -28, 28,
- -9, -11, 10, -1, 4, -18, 17, -9, -13, 24, -18, 20, -18, -30, 59, -25,
- -29, 48, -15, -29, 23, 4, -3, -18, 14, 6, -8, -19, 19, 8, -13, 0,
- 13, -18, 4, 1, 0, 0, 10, -14, -12, 39, -46, 23, 9, -22, 23, -20,
- -22, 63, -42, -28, 77, -66, 12, 38, -56, 31, 27, -77, 66, -11, -39, 59,
- -33, -41, 92, -54, -50, 96, -36, -46, 46, -17, 31, -43, -28, 98, -57, -50,
- 84, -22, -44, 39, -8, 17, -28, -13, 63, -67, 16, 10, 3, -15, -4, 36,
- -34, -1, 26, -27, -2, 13, 7, -22, 0, 27, -11, -19, 6, 26, -42, 14,
- 18, -7, -14, -10, 37, -14, -24, 25, -4, -5, -10, 3, 35, -39, -7, 31,
- -8, -23, 15, 4, -1, -25, 28, 7, -35, 34, -16, -1, 9, -35, 45, -22,
- -17, 48, -52, 24, 22, -65, 48, 7, -45, 47, -19, -33, 71, -70, 46, -7,
- -52, 68, -25, -35, 48, -13, -17, 14, 2, -12, 8, -10, 1, 22, -32, 4,
- 34, -26, -18, 29, -7, -19, 15, -7, 15, -8, -29, 50, -22, -35, 53, -19,
- -37, 47, -9, -40, 41, 1, -27, 7, 3, 0, 0, -7, 13, -7, -21, 26,
- 14, -44, 11, 40, -51, 10, 26, -28, 16, -13, -3, 31, -42, 11, 34, -52,
- 11, 34, -43, 10, 29, -19, -21, 27, -10, -5, 10, -14, 11, 3, -35, 43,
- 3, -52, 37, 22, -66, 49, -12, -19, 50, -58, 16, 42, -70, 50, -2, -42,
- 60, -69, 43, 11, -57, 54, -8, -31, 23, -8, -7, 24, -32, 11, 21, -51,
- 60, -44, -6, 68, -87, 33, 45, -79, 50, -7, -13, 21, -40, 31, 12, -41,
- 18, 24, -39, 15, 7, -17, 25, -20, -12, 43, -47, 17, 6, -16, 10, 4,
- -11, -1, 14, -10, -7, 6, 9, -23, 9, 3, 13, -30, 16, 16, -33, 17,
- 4, -17, 23, -29, 3, 54, -86, 50, 11, -41, 30, -23, 15, 18, -60, 56,
- 7, -65, 49, -4, -12, 1, -6, 19, -4, -33, 35, -10, -12, 13, -2, -2,
- -2, 2, -10, 16, -8, -11, 19, -6, -19, 24, -14, 9, 3, -24, 24, -6,
- -13, 19, -11, -6, 6, -9, 16, -8, -10, 14, -10, -1, -5, 16, -8, -25,
- 37, -11, -27, 37, -14, -13, 19, -17, 14, -5, -15, 26, -27, 10, 11, -23,
- 22, -5, -19, 25, -7, -28, 44, -35, 0, 25, -31, 31, -10, -26, 46, -41,
- 2, 33, -40, 24, 8, -43, 44, -12, -25, 37, -25, -6, 29, -27, 5, 24,
- -40, 24, -1, -25, 23, -1, -6, -2, -1, 14, -24, 8, 13, -11, 0, -13,
- 16, 15, -56, 43, 12, -35, 14, -9, 18, -10, -19, 28, -3, -27, 23, -2,
- -14, 27, -35, 10, 35, -68, 44, 7, -43, 46, -21, -25, 56, -35, -21, 51,
- -33, -8, 28, -27, 19, -2, -26, 36, -26, 3, 13, -12, 6, -10, 8, -14,
- 15, -12, 0, 13, -9, -16, 32, -27, 3, 23, -49, 49, -17, -31, 63, -64,
- 25, 36, -76, 61, -11, -47, 75, -54, -9, 69, -81, 32, 29, -63, 46, -7,
- -26, 39, -31, 6, 18, -26, 13, -5, 5, -5, -2, 5, -12, 17, -17, -2,
- 22, -25, 1, 20, -19, 3, 6, -6, 3, -9, 10, -6, -3, 7, -7, -3,
- 12, -5, -5, -11, 24, -7, -23, 24, 0, -14, 0, 12, -10, -2, 5, 0,
- 1, -10, 10, -2, -17, 26, -11, -16, 28, -22, 6, 4, -17, 30, -27, -7,
- 46, -54, 15, 29, -42, 25, -4, -15, 26, -29, 11, 15, -28, 19, -7, 1,
- 8, -20, 14, 1, -15, 11, -2, -2, 0, -10, 15, -5, -12, 15, -1, -15,
- 12, 4, -15, 9, -1, -9, 9, -5, -6, 13, -12, 1, 6, -6, -3, 6,
- -4, 0, -6, 11, -9, -2, 13, -12, -2, -1, 8, -11, 4, 2, -6, 4,
- -4, 4, 0, -13, 15, 0, -21, 23, -5, -15, 15, -2, -9, 6, -2, -4,
- 2, 3, -1, -7, 7, -2, -9, 6, 2, -9, 4, 5, -12, 10, -9, 4,
- 5, -16, 12, -2, -13, 20, -13, -4, 17, -23, 14, 2, -20, 22, -13, -3,
- 15, -22, 12, 4, -18, 17, -7, -7, 13, -14, 6, 4, -10, 9, -5, -6,
- 7, 0, -7, 8, -4, -1, 0, -6, 4, 7, -14, 2, 13, -16, 3, 10,
- -15, 7, -1, -10, 14, -10, -2, 11, -9, -4, 7, -6, 3, -3, -5, 9,
- -6, -3, 5, 1, -7, 3, -2, 0, -2, 0, 4, -3, -2, 4, -6, 4,
- -2, -2, 0, 1, 0, -7, 7, -2, -7, 9, -7, -4, 11, -15, 11, -2,
- -9, 9, -4, -3, 2, 3, -7, 5, 0, -5, 6, -7, 1, 7, -10, -2,
- 13, -9, -4, 8, -4, -2, -1, 1, 1, -7, 4, 5, -8, 0, 6, -6,
- 0, 3, -4, 0, 1, -2, 2, -4, -4, 8, -7, -1, 6, -9, 8, -3,
- -6, 12, -12, 1, 10, -11, 1, 5, -6, 3, -2, -3, 7, -10, 2, 7,
- -12, 5, 2, -5, 3, -5, 0, 6, -10, 3, 4, -8, 2, 2, -3, 3,
- -8, 8, 2, -14, 10, 3, -12, 8, 2, -11, 8, -2, -6, 9, -7, -4,
- 10, -9, -1, 7, -7, 1, 3, -8, 8, -2, -8, 10, -3, -5, 5, -6,
- 3, 1, -8, 10, -5, -5, 7, -4, -2, 2, -3, 1, -1, -3, 4, -3,
- 0, 0, 0, 0, -4, 3, -2, -3, 3, -5, 3, 0, -7, 5, 1, -8,
- 5, 1, -6, 6, -5, 0, 3, -7, 3, 2, -6, 3, 2, -6, 3, 1,
- -3, -2, 5, -4, -1, 3, -4, 0, 0, -3, 5, -5, -3, 7, -5, -3,
- 6, -4, 0, -1, -3, 3, -2, -1, 2, -1, -2, 1, -2, 1, -1, -7,
- 8, -1, 5, -7, 13, -22, 8, -7, 8, -110, -28, 24, 54, 36, 2, 60,
- -45, 57, 42, -43, 20, 41, -66, 24, -11, 18, -18, -38, -63, -36, 30, -11,
- 33, 25, 30, 18, 11, -18, -5, 5, -46, 40, 1, -13, -18, -20, -31, 20,
- 10, 29, -7, -18, 40, -29, -17, 42, -19, 6, -4, 6, -8, 10, -26, -5,
- 3, 1, -17, 6, 0, 19, -1, 8, 0, -6, -10, -1, -12, -1, 1, -3,
- 8, -7, 4, 11, 4, 14, -13, 16, -19, -4, -13, -13, -14, 6, 4, -1,
- 4, 11, -1, 11, -1, 1, -4, -1, -15, 6, -9, 1, -1, 0, 3, 1,
- -8, 3, -1, -1, 2, -2, 2, -2, 1, -5, -7, 3, -3, 6, -3, 4,
- -1, 0, -4, 2, -7, 3, -6, -1, -1, 4, 0, 3, -2, 2, -5, 5,
- -8, -3, -3, 2, -5, 7, -1, 4, -2, 4, -10, 6, -6, -1, -4, 5,
- -13, 7, -6, 5, -8, 17, -20, 14, -6, 9, -40, 71, -127, 9, -73, 127,
- 76, -28, 74, -32, 8, -62, -49, -38, 40, -68, 22, -12, 68, 10, 39, -10,
- 0, 35, -23, 0, -59, -15, -7, -3, -23, 1, -20, 37, 27, 2, 30, -2,
- 17, 2, -5, -7, -27, -29, 16, -3, -11, 1, -16, -5, -8, -10, 7, 32,
- 9, 5, -4, 16, 5, -8, -17, -16, 5, -13, 8, 11, 15, -10, -9, 0,
- -1, 2, 7, -3, -23, 9, 2, 3, 1, -13, -1, -6, 11, -6, 8, 1,
- 12, -12, 9, -14, 8, -1, 0, -3, -13, 4, -7, -4, 8, 5, -5, -7,
- 4, -2, -3, 2, 3, -6, 8, -3, 1, -3, -2, 2, -6, 2, -4, -3,
- -4, 3, 1, 0, 0, 1, -1, -1, 2, -2, 0, -4, -2, 1, 2, 0,
- -3, 1, -3, 0, -1, -3, -6, 2, -2, 3, -4, 10, -8, 9, -5, 12,
- -19, 46, 37, -128, 60, -90, 102, -65, 40, -57, 39, -6, 23, -8, 19, 24,
- 15, -17, -47, -27, -36, -16, 21, 3, 23, 14, 50, -8, 19, 25, 7, -9,
- -28, -63, -37, 0, -42, 54, -17, 68, -3, 30, -12, -4, 11, -15, 9, -25,
- -15, -2, -27, -25, 38, -8, -13, 33, 24, 12, -38, 39, -12, -3, -17, -44,
- 38, 2, 27, 3, -5, -4, -13, -30, -56, -4, 11, 1, 9, 17, 46, 25,
- -14, 6, -3, -7, -21, 2, 16, -5, -22, 2, -2, 6, -12, -25, -15, 10,
- 9, 8, 11, 43, 8, -5, -22, -16, 14, -31, 16, 7, -7, -26, -20, -2,
- 9, 11, 26, 7, 6, -20, -13, 0, 4, 17, -17, -18, 10, 2, -10, 27,
- -8, 24, -23, -14, 1, 0, 13, -19, 14, 10, -16, 16, -4, -20, 20, -33,
- 2, 2, 24, 21, -3, -26, -24, -18, -18, 10, 10, 24, 18, 2, 9, -24,
- 16, -14, -8, 9, -5, -14, 8, -5, 30, -11, 11, -13, -15, -12, 7, 4,
- -13, -13, 13, -13, 12, 23, 9, 0, 14, -10, -9, -35, -2, -21, 12, -1,
- 17, 19, 11, -4, 0, -18, -24, 11, -10, 1, 11, 12, -13, -16, 10, -23,
- 21, 9, -9, 3, 12, -6, 3, -5, 12, 0, -2, 0, -19, -9, 5, -11,
- -7, 10, 1, -3, 9, 18, -6, 0, -1, 1, -13, 2, 1, -3, -8, 17,
- -4, -9, 18, -15, 8, -1, -11, -5, -14, 11, -5, -7, 12, 16, -7, 7,
- -3, -11, -5, -6, 1, 4, -3, -3, 15, 5, 0, 3, 6, -16, 4, -14,
- -6, -9, -4, 2, 11, 11, 7, -2, 4, -12, -7, -14, -6, -7, 9, 4,
- 7, -2, 6, 5, 6, -4, -3, -4, 7, -7, -11, -9, 0, -3, 7, -2,
- -2, 3, 13, -4, -6, -15, 9, -7, -1, 4, 6, 5, 8, -6, -8, 0,
- -11, -4, 6, -8, 4, 3, 5, 13, -4, -9, -3, 4, -3, -3, 4, -1,
- -12, 6, -14, 2, 3, 15, 2, 6, -7, -8, 3, 1, -2, 3, -3, -12,
- -6, -14, 7, -2, 13, 6, 10, 6, 0, -2, -10, -12, -8, -6, -7, -6,
- 6, 4, -2, 5, 2, 0, -1, 3, -11, 4, 0, 20, -8, -2, 0, -1,
- -3, 7, -3, -4, -2, -6, -10, -10, -8, 1, 2, 5, 8, 2, 5, 8,
- 3, 4, 3, -2, -15, 0, -1, -7, -2, -5, -10, 10, -1, 5, 3, 5,
- -1, -2, -8, -5, -9, 1, -8, 6, 5, 4, 1, 1, 2, 3, -2, 4,
- -7, 1, -7, -9, -2, 0, 2, 3, 6, -8, 8, 3, 0, -2, -9, -3,
- -2, 0, 3, -1, -2, -3, 7, -3, 10, -8, 1, -12, 3, -7, 2, -3,
- 7, 4, 4, 0, 0, -6, -1, -5, -3, -4, -7, 0, 5, 7, 0, 2,
- -3, 10, -1, 3, -7, -5, -4, -9, -3, -7, 5, -4, 9, 2, 1, 4,
- 5, 0, -5, 1, -8, 4, -9, 5, -5, 0, 3, -2, -1, 1, 1, -7,
- 7, 0, 3, -5, 0, -3, -1, -1, -5, -1, 1, -1, 1, -1, 0, 2,
- 0, 2, -7, -7, 4, -1, 0, 3, 4, -1, -3, -4, -6, 3, -2, 4,
- -1, 5, -2, -1, -5, -2, -4, 1, 3, 2, 2, 0, -3, 1, 1, -3,
- -3, -1, 1, -3, -2, -1, -2, -3, -1, 0, 4, 3, 5, 2, 1, -4,
- -9, -3, -7, 1, -2, 7, -2, 3, 3, 3, 1, 0, -1, -6, -7, -6,
- -4, -1, 1, 0, 5, 2, -2, 2, -3, -1, 3, -1, 1, -4, -4, -5,
- 0, -7, 2, -4, 3, 4, 1, 2, -1, -1, -2, -2, 0, -1, 1, -1,
- -1, -3, 1, 1, 3, -3, -1, 1, 1, -2, -3, -8, -5, 0, -1, 5,
- 2, 3, 1, -2, -1, -1, -3, 1, 1, -2, -3, -3, -1, 0, -1, 1,
- 2, 2, 5, 0, -1, -2, -1, -2, 0, -4, 0, -5, -1, -1, 0, 1,
- 5, 4, -2, -1, -2, 0, -6, -1, 0, 1, -1, -2, 1, 0, 0, 3,
- 1, -2, 1, -2, -4, -1, 0, -1, -1, -4, -2, -4, 2, -1, 1, 0,
- 3, 2, 0, 4, -1, 4, -6, 2, -4, -3, -5, -4, -3, 0, 2, 0,
- 1, 4, 2, 2, -2, -2, -5, -6, -5, -3, -2, 1, -1, 0, 0, 2,
- 2, 2, 0, 4, -2, 3, 2, -1, -2, -3, -3, -3, -5, -5, -5, -1,
- -1, 0, 2, 2, 4, 1, 2, 1, 2, -1, -1, -3, -4, -5, -3, -2,
- -2, -1, 1, 4, 2, 2, 2, 1, -1, -2, -6, -2, -3, 2, -1, 1,
- -2, 0, 2, 1, 2, -2, 1, 0, -2, -2, -3, 0, -2, -1, -1, 0,
- -2, -2, 1, 0, 2, -1, 1, -1, 0, -1, -1, -7, 8, -1, 5, -7,
- 13, -22, 8, -7, 8, -110, -28, 24, 54, 36, 2, 60, -45, 57, 42, -43,
- 20, 41, -66, 24, -11, 18, -18, -38, -63, -36, 30, -11, 33, 25, 30, 18,
- 11, -18, -5, 5, -46, 40, 1, -13, -18, -20, -31, 20, 10, 29, -7, -18,
- 40, -29, -17, 42, -19, 6, -4, 6, -8, 10, -26, -5, 3, 1, -17, 6,
- 0, 19, -1, 8, 0, -6, -10, -1, -12, -1, 1, -3, 8, -7, 4, 11,
- 4, 14, -13, 16, -19, -4, -13, -13, -14, 6, 4, -1, 4, 11, -1, 11,
- -1, 1, -4, -1, -15, 6, -9, 1, -1, 0, 3, 1, -8, 3, -1, -1,
- 2, -2, 2, -2, 1, -5, -7, 3, -3, 6, -3, 4, -1, 0, -4, 2,
- -7, 3, -6, -1, -1, 4, 0, 3, -2, 2, -5, 5, -8, -3, -3, 2,
- -5, 7, -1, 4, -2, 4, -10, 6, -6, -1, -4, 5, -13, 7, -6, 5,
- -8, 17, -20, 14, -6, 9, -40, 71, -127, 9, -73, 127, 76, -28, 74, -32,
- 8, -62, -49, -38, 40, -68, 22, -12, 68, 10, 39, -10, 0, 35, -23, 0,
- -59, -15, -7, -3, -23, 1, -20, 37, 27, 2, 30, -2, 17, 2, -5, -7,
- -27, -29, 16, -3, -11, 1, -16, -5, -8, -10, 7, 32, 9, 5, -4, 16,
- 5, -8, -17, -16, 5, -13, 8, 11, 15, -10, -9, 0, -1, 2, 7, -3,
- -23, 9, 2, 3, 1, -13, -1, -6, 11, -6, 8, 1, 12, -12, 9, -14,
- 8, -1, 0, -3, -13, 4, -7, -4, 8, 5, -5, -7, 4, -2, -3, 2,
- 3, -6, 8, -3, 1, -3, -2, 2, -6, 2, -4, -3, -4, 3, 1, 0,
- 0, 1, -1, -1, 2, -2, 0, -4, -2, 1, 2, 0, -3, 1, -3, 0,
- -1, -3, -6, 2, -2, 3, -4, 10, -8, 9, -5, 12, -19, 46, 37, -128,
- 60, -90, 102, -65, 40, -57, 39, -6, 23, -8, 19, 24, 15, -17, -47, -27,
- -36, -16, 21, 3, 23, 14, 50, -8, 19, 25, 7, -9, -28, -63, -37, 0,
- -42, 54, -17, 68, -3, 30, -12, -4, 11, -15, 9, -25, -15, -2, -27, -25,
- 38, -8, -13, 33, 24, 12, -38, 39, -12, -3, -17, -44, 38, 2, 27, 3,
- -5, -4, -13, -30, -56, -4, 11, 1, 9, 17, 46, 25, -14, 6, -3, -7,
- -21, 2, 16, -5, -22, 2, -2, 6, -12, -25, -15, 10, 9, 8, 11, 43,
- 8, -5, -22, -16, 14, -31, 16, 7, -7, -26, -20, -2, 9, 11, 26, 7,
- 6, -20, -13, 0, 4, 17, -17, -18, 10, 2, -10, 27, -8, 24, -23, -14,
- 1, 0, 13, -19, 14, 10, -16, 16, -4, -20, 20, -33, 2, 2, 24, 21,
- -3, -26, -24, -18, -18, 10, 10, 24, 18, 2, 9, -24, 16, -14, -8, 9,
- -5, -14, 8, -5, 30, -11, 11, -13, -15, -12, 7, 4, -13, -13, 13, -13,
- 12, 23, 9, 0, 14, -10, -9, -35, -2, -21, 12, -1, 17, 19, 11, -4,
- 0, -18, -24, 11, -10, 1, 11, 12, -13, -16, 10, -23, 21, 9, -9, 3,
- 12, -6, 3, -5, 12, 0, -2, 0, -19, -9, 5, -11, -7, 10, 1, -3,
- 9, 18, -6, 0, -1, 1, -13, 2, 1, -3, -8, 17, -4, -9, 18, -15,
- 8, -1, -11, -5, -14, 11, -5, -7, 12, 16, -7, 7, -3, -11, -5, -6,
- 1, 4, -3, -3, 15, 5, 0, 3, 6, -16, 4, -14, -6, -9, -4, 2,
- 11, 11, 7, -2, 4, -12, -7, -14, -6, -7, 9, 4, 7, -2, 6, 5,
- 6, -4, -3, -4, 7, -7, -11, -9, 0, -3, 7, -2, -2, 3, 13, -4,
- -6, -15, 9, -7, -1, 4, 6, 5, 8, -6, -8, 0, -11, -4, 6, -8,
- 4, 3, 5, 13, -4, -9, -3, 4, -3, -3, 4, -1, -12, 6, -14, 2,
- 3, 15, 2, 6, -7, -8, 3, 1, -2, 3, -3, -12, -6, -14, 7, -2,
- 13, 6, 10, 6, 0, -2, -10, -12, -8, -6, -7, -6, 6, 4, -2, 5,
- 2, 0, -1, 3, -11, 4, 0, 20, -8, -2, 0, -1, -3, 7, -3, -4,
- -2, -6, -10, -10, -8, 1, 2, 5, 8, 2, 5, 8, 3, 4, 3, -2,
- -15, 0, -1, -7, -2, -5, -10, 10, -1, 5, 3, 5, -1, -2, -8, -5,
- -9, 1, -8, 6, 5, 4, 1, 1, 2, 3, -2, 4, -7, 1, -7, -9,
- -2, 0, 2, 3, 6, -8, 8, 3, 0, -2, -9, -3, -2, 0, 3, -1,
- -2, -3, 7, -3, 10, -8, 1, -12, 3, -7, 2, -3, 7, 4, 4, 0,
- 0, -6, -1, -5, -3, -4, -7, 0, 5, 7, 0, 2, -3, 10, -1, 3,
- -7, -5, -4, -9, -3, -7, 5, -4, 9, 2, 1, 4, 5, 0, -5, 1,
- -8, 4, -9, 5, -5, 0, 3, -2, -1, 1, 1, -7, 7, 0, 3, -5,
- 0, -3, -1, -1, -5, -1, 1, -1, 1, -1, 0, 2, 0, 2, -7, -7,
- 4, -1, 0, 3, 4, -1, -3, -4, -6, 3, -2, 4, -1, 5, -2, -1,
- -5, -2, -4, 1, 3, 2, 2, 0, -3, 1, 1, -3, -3, -1, 1, -3,
- -2, -1, -2, -3, -1, 0, 4, 3, 5, 2, 1, -4, -9, -3, -7, 1,
- -2, 7, -2, 3, 3, 3, 1, 0, -1, -6, -7, -6, -4, -1, 1, 0,
- 5, 2, -2, 2, -3, -1, 3, -1, 1, -4, -4, -5, 0, -7, 2, -4,
- 3, 4, 1, 2, -1, -1, -2, -2, 0, -1, 1, -1, -1, -3, 1, 1,
- 3, -3, -1, 1, 1, -2, -3, -8, -5, 0, -1, 5, 2, 3, 1, -2,
- -1, -1, -3, 1, 1, -2, -3, -3, -1, 0, -1, 1, 2, 2, 5, 0,
- -1, -2, -1, -2, 0, -4, 0, -5, -1, -1, 0, 1, 5, 4, -2, -1,
- -2, 0, -6, -1, 0, 1, -1, -2, 1, 0, 0, 3, 1, -2, 1, -2,
- -4, -1, 0, -1, -1, -4, -2, -4, 2, -1, 1, 0, 3, 2, 0, 4,
- -1, 4, -6, 2, -4, -3, -5, -4, -3, 0, 2, 0, 1, 4, 2, 2,
- -2, -2, -5, -6, -5, -3, -2, 1, -1, 0, 0, 2, 2, 2, 0, 4,
- -2, 3, 2, -1, -2, -3, -3, -3, -5, -5, -5, -1, -1, 0, 2, 2,
- 4, 1, 2, 1, 2, -1, -1, -3, -4, -5, -3, -2, -2, -1, 1, 4,
- 2, 2, 2, 1, -1, -2, -6, -2, -3, 2, -1, 1, -2, 0, 2, 1,
- 2, -2, 1, 0, -2, -2, -3, 0, -2, -1, -1, 0, -2, -2, 1, 0,
- 2, -1, 1, -1, 0, -1, -1, 1, -7, 5, -22, -32, -35, -32, -43, -35,
- -55, -42, -66, -48, -80, -57, -17, -128, -59, -76, 0, -26, 1, -33, 21, 3,
- 16, 15, 26, 43, 28, 66, 6, 97, 40, 103, 67, 101, 102, 98, 94, 21,
- 98, 90, 57, 78, 89, 81, 61, -6, 54, 4, 62, 19, 27, 34, 12, 16,
- 14, -17, 19, -5, -2, -13, -38, -24, -3, -33, -14, -11, -16, 0, -13, 7,
- -26, -13, -16, 6, -57, -23, -28, -13, -9, -34, -32, -20, -87, -62, -28, -38,
- -75, -37, -27, -41, -71, -48, -30, -44, -83, -67, -52, -48, -45, -46, -45, -63,
- -47, -40, -32, -45, -24, -32, -43, -21, -17, 0, 21, 26, 43, 51, 62, 47,
- 41, 55, 57, 68, 34, 53, 63, 62, 71, 60, 61, 56, 53, 56, 54, 38,
- 50, 58, 50, 40, 28, 54, 39, 41, 38, 22, 32, 20, -3, 19, -1, -7,
- -6, -16, -16, -14, -27, -29, -46, -66, -61, -51, -54, -61, -41, -50, -47, -52,
- -55, -45, -44, -28, -58, -56, -31, -37, -36, -32, -18, -16, -34, -29, -9, -21,
- -20, -30, -22, -17, -19, -8, -12, -14, -6, -14, -6, -11, -2, 4, -6, 9,
- 8, 17, 23, 13, 31, 13, 24, 30, 28, 29, 30, 43, 34, 37, 52, 42,
- 44, 50, 67, 59, 49, 54, 48, 43, 51, 45, 42, 62, 47, 39, 37, 36,
- 24, 28, 13, 3, 9, -11, -3, -9, -14, -18, -34, -27, -29, -39, -42, -38,
- -46, -37, -46, -43, -41, -35, -38, -31, -38, -34, -39, -39, -34, -48, -44, -47,
- -49, -54, -52, -44, -53, -37, -47, -38, -31, -38, -27, -19, -19, -15, -16, 0,
- 0, 2, 7, 13, 29, 22, 32, 32, 39, 47, 41, 40, 55, 48, 41, 44,
- 57, 43, 36, 47, 43, 42, 37, 32, 32, 27, 33, 36, 30, 23, 25, 25,
- 22, 18, 22, 20, 16, 8, 6, 12, 7, 0, 1, 3, -5, -14, -9, -7,
- -8, -19, -15, -16, -23, -21, -21, -32, -31, -29, -26, -27, -29, -33, -26, -29,
- -30, -39, -28, -41, -43, -35, -34, -32, -29, -28, -28, -25, -27, -24, -27, -27,
- -27, -22, -23, -17, -9, -10, -14, -10, -8, -4, -2, -1, -3, 5, 4, 10,
- 11, 7, 13, 11, 14, 27, 22, 22, 22, 27, 36, 34, 36, 37, 45, 44,
- 47, 48, 51, 49, 52, 51, 52, 48, 50, 47, 48, 42, 40, 29, 33, 24,
- 22, 12, 5, 0, -3, -5, -9, -21, -21, -25, -19, -28, -28, -30, -33, -39,
- -42, -42, -46, -46, -45, -42, -43, -47, -47, -36, -32, -30, -34, -31, -22, -29,
- -29, -30, -26, -28, -30, -21, -26, -27, -21, -19, -16, -11, -12, -8, -2, 1,
- -4, 1, 0, 1, 9, 8, 7, 12, 10, 13, 20, 17, 18, 21, 26, 29,
- 30, 30, 29, 34, 33, 34, 33, 30, 32, 33, 28, 33, 29, 35, 32, 31,
- 30, 31, 30, 25, 27, 24, 21, 21, 20, 16, 17, 12, 6, 4, -3, 1,
- -6, -7, -11, -13, -11, -10, -8, -13, -12, -9, -17, -14, -19, -24, -22, -24,
- -30, -32, -30, -33, -37, -39, -40, -42, -39, -41, -39, -40, -41, -35, -35, -35,
- -37, -36, -33, -30, -25, -25, -19, -16, -16, -10, -6, -7, -4, -2, 1, 3,
- 6, 10, 9, 15, 17, 18, 17, 13, 19, 18, 17, 19, 20, 24, 24, 27,
- 27, 29, 30, 26, 28, 28, 27, 28, 26, 25, 24, 25, 20, 19, 17, 18,
- 15, 12, 13, 10, 6, 8, 6, 3, 4, 3, 0, -3, 0, -1, -2, -5,
- -4, -5, -4, -5, -6, -8, -9, -9, -12, -11, -16, -16, -15, -15, -13, -17,
- -16, -17, -17, -21, -20, -25, -24, -24, -24, -26, -30, -30, -27, -30, -26, -26,
- -27, -27, -25, -24, -19, -20, -17, -13, -12, -8, -8, -8, -6, -5, -2, -1,
- 0, 3, 8, 10, 12, 16, 18, 24, 25, 25, 28, 30, 28, 32, 33, 31,
- 32, 31, 35, 33, 31, 31, 27, 28, 26, 23, 23, 20, 22, 18, 16, 13,
- 11, 9, 5, 4, -2, -2, -3, -8, -9, -11, -12, -13, -15, -15, -15, -15,
- -15, -14, -12, -12, -13, -13, -8, -11, -10, -12, -10, -12, -12, -8, -8, -9,
- -9, -9, -8, -9, -10, -11, -11, -10, -13, -14, -13, -16, -16, -17, -17, -18,
- -19, -18, -17, -16, -16, -15, -15, -13, -12, -10, -12, -10, -9, -8, -6, -6,
- -3, 0, 0, 1, 2, 2, 3, 4, 4, 5, 6, 7, 8, 9, 10, 11,
- 12, 12, 13, 14, 14, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16,
- 16, 16, 15, 15, 14, 13, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4,
- 3, 2, 1, 0, -1, -1, -2, -3, -4, -5, -5, -6, -7, -7, -8, -9,
- -9, -10, -11, -11, -12, -12, -13, -13, -13, -13, -14, -14, -14, -15, -15, -15,
- -15, -15, -15, -16, -16, -16, -15, -15, -15, -14, -13, -13, -12, -11, -10, -9,
- -8, -7, -6, -5, -4, -2, -1, 0, 1, 2, 4, 5, 6, 7, 8, 9,
- 10, 11, 12, 12, 13, 13, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16,
- 17, 17, 17, 17, 17, 17, 16, 16, 15, 15, 14, 14, 13, 12, 11, 10,
- 9, 7, 6, 5, 3, 1, 0, -2, -4, -5, -7, -9, -10, -11, -13, -14,
- -15, -15, -16, -17, -17, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18,
- -18, -17, -17, -16, -16, -15, -14, -14, -13, -12, -11, -10, -9, -8, -7, -6,
- -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 9, 10,
- 11, 11, 12, 13, 13, 13, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15,
- 15, 15, 15, 15, 14, 14, 14, 13, 12, 12, 11, 10, 9, 8, 8, 7,
- 6, 5, 4, 3, 2, 1, 0, 0, -1, 10, -20, 30, 25, 21, 14, 4,
- 15, -48, -33, 11, -70, 54, -5, -21, -8, -3, 73, -52, 65, -55, 80, -28,
- -67, -3, -13, 21, -49, -2, 11, 36, 59, -60, 34, -28, 21, -25, -45, 54,
- 5, 0, -19, -12, 20, 54, -51, -23, 22, 36, -59, -20, 8, 28, -9, -54,
- 127, -44, 69, -128, 5, 69, -8, -98, 45, 69, 20, -97, 23, -7, 121, -81,
- -2, -21, 51, -67, -14, -24, 127, -60, 45, -116, 127, -29, -93, -23, 107, -5,
- -21, -62, 37, 41, 29, -74, -63, 103, 24, -59, -44, 62, 43, -28, -46, 7,
- 72, 19, -70, -47, 42, 53, -68, -13, 37, 59, -38, -60, 39, 66, 27, -128,
- 36, 77, 15, -74, -15, 75, 38, -49, -11, -39, 16, -8, -30, 35, 41, -1,
- -2, 17, -68, 99, -97, 60, -49, 32, -44, -29, 82, -26, 39, -35, 10, 38,
- -20, -21, -92, 83, -24, 13, 31, -33, 22, 45, -31, -24, 9, -24, -32, 42,
- -17, 34, 7, -27, 6, 61, -9, -34, -5, -8, -17, -6, -34, 17, 43, -9,
- 35, -34, 16, 27, -24, -17, -17, 5, -17, 42, -31, 22, 17, -26, -22, 32,
- 41, -27, -25, -10, -5, 16, -2, 13, -1, 48, -33, -27, 6, 16, 13, -37,
- -11, 18, 25, -42, -11, 46, -7, -15, 9, 15, 4, -3, -36, -24, 31, -8,
- 14, 12, 27, -19, -17, -14, -7, 42, -5, -15, 5, 1, -15, 14, 43, -19,
- 1, -25, -35, 16, 16, 29, -12, 8, -14, 1, 21, -8, -12, -22, -4, 24,
- 26, -16, -22, 37, 3, -41, 7, 4, 3, 30, 4, -27, 11, -6, -26, 33,
- 23, -23, -14, -20, -7, -4, 36, 0, 18, 10, -27, 1, 1, 16, -1, -4,
- -44, -5, 17, 9, 13, -4, -3, 31, 24, -14, -26, 9, -27, -28, 19, 22,
- 32, -11, -15, 5, 15, -23, -21, 16, 14, 18, -11, -26, 13, 10, -12, -12,
- 11, 14, -6, -13, -3, 6, -6, 3, 12, 32, 14, -22, -45, -10, 37, 11,
- -50, -11, 50, 22, -13, -4, -4, 15, -16, -33, 7, 34, -9, -14, -1, 21,
- 15, -14, -12, -6, 7, 8, 2, 0, -5, 6, 15, 4, -9, 13, 3, -51,
- -18, 27, 10, 5, -11, 6, -1, 5, 22, 2, -14, -39, -12, 19, 17, 4,
- 11, 5, -25, 2, 23, 8, 2, -3, -39, -22, 4, 18, 6, 14, 25, 20,
- -17, -20, 17, 7, -43, -38, -18, 17, 24, -6, 30, 44, 6, -36, -20, 7,
- 24, 1, -69, -25, 47, 15, -4, 35, 19, -18, -22, -12, 20, 39, -36, -49,
- 9, 28, -16, 9, 34, 36, -22, -69, -16, 39, 7, -28, -3, 33, -18, -7,
- 18, 53, 24, -37, -61, -10, 38, 2, -24, -11, 12, 17, 0, 28, 50, -5,
- -59, -57, 22, 14, -15, -5, 22, 9, -20, 19, 33, 31, -33, -62, -13, -2,
- 45, -9, -4, -3, 19, 8, -8, 40, 8, -16, -44, -19, 16, 3, 23, -32,
- 22, 5, -9, 5, 26, 21, -27, -18, -45, 3, 15, 0, 7, 7, 7, 13,
- 18, -10, 3, -5, -30, -30, -3, 9, 31, 17, -10, 19, 28, -33, -20, 31,
- 14, -67, -27, 13, 20, 29, 1, -2, 24, -3, -26, -12, 32, -7, -31, -17,
- 5, 22, 11, -6, 6, 7, 2, 7, 5, -12, -22, -17, -24, 22, 47, 1,
- 2, 10, 5, -29, -5, 13, 1, -30, -28, -5, 23, 25, 6, 5, 1, 7,
- 0, 5, 3, -33, -37, -6, 19, 20, 26, -1, -15, 21, 9, -14, -13, 0,
- -11, -24, -9, 9, 23, 1, 1, 32, 11, -25, -18, 5, -5, -6, -9, -10,
- 2, 18, 4, 12, 6, -2, -8, 2, 2, -7, 2, -22, -5, 17, 25, 15,
- -5, -1, -24, -8, -10, -5, 12, 7, -4, -10, 4, 8, 22, 11, -1, -12,
- -31, -17, 6, 12, 11, 5, -3, -1, 22, 0, -4, 3, -18, -17, -3, 16,
- 9, 2, -5, 0, 4, -9, 18, 17, -22, -19, -8, -6, 21, 11, -6, -16,
- 33, 13, -15, -3, -15, 1, -3, -10, -7, 8, 17, -11, 9, 19, 0, 5,
- 0, -18, -13, 2, -20, 10, 29, -11, -13, 5, 11, 16, 4, -25, -21, 13,
- -5, 1, 3, -1, 6, 13, -7, -1, 17, -6, -6, -9, -6, -3, -1, 1,
- 18, 11, -22, 2, 18, -2, -15, 1, 5, -12, -10, -7, 9, 26, 10, -11,
- 5, 0, -7, -3, -11, -9, -3, 2, -10, 19, 28, -3, -3, -4, 9, -14,
- -5, -7, 8, -3, -27, 5, 37, 11, -2, 3, -27, -15, 12, -2, 14, 2,
- -8, -16, 22, 11, -1, 10, -17, -8, -5, -23, 2, 29, 8, -21, 8, 12,
- 6, 8, -17, 3, -2, -12, -27, 16, 25, -5, -7, 2, 19, 1, -15, 7,
- 2, -5, -34, 2, 18, 17, -10, 2, 18, -1, -12, -10, 5, 1, -16, -9,
- 12, 21, 4, -10, 2, 12, 1, -19, -11, 20, 5, -14, -21, 5, 17, -5,
- 3, 17, 4, -25, -5, 5, 4, 0, -5, 2, 2, -1, 1, 13, 0, -11,
- -8, 3, 2, -1, -3, -3, 11, 8, -6, 2, 7, 4, -5, -23, -2, 14,
- -1, -15, -2, 15, 10, 1, -4, 16, 1, -24, -12, 8, 8, -20, -2, 14,
- 13, 10, 2, 2, -9, -6, -9, -3, 5, 7, -3, -9, 0, 2, 8, 3,
- -1, 2, -4, 0, -2, 0, -2, 3, 5, -4, -28, 22, -43, 36, -13, -127,
- -43, 2, -18, 126, 78, -127, -48, 68, -74, -67, 33, 62, 83, 42, -32, -46,
- -70, -26, 115, 21, -66, 72, 52, -27, 44, 50, 50, 61, 28, -12, 3, -59,
- 49, 3, -19, 39, 94, 16, 31, 6, 29, 3, -100, -1, -4, -60, 19, 7,
- -29, -28, -38, -3, -47, -20, -21, -1, 5, -55, -12, -55, -39, 26, 47, -22,
- -9, -41, -21, -19, -37, 0, 45, -56, 24, 75, -50, -9, 31, 28, 26, 13,
- -3, -15, -27, 1, 1, -31, -10, 38, -1, 7, 43, 19, 21, 41, 33, 9,
- -17, -3, -42, -76, -30, -8, -9, -1, 21, 22, 38, 32, 22, 0, -18, -32,
- -58, -12, 5, -48, -13, 64, 29, -2, 2, 19, 43, 25, -19, -39, -69, -92,
- -15, 23, 30, 30, 51, 37, 35, 37, 30, -27, -63, 5, -30, -56, -16, 26,
- 52, 20, 14, 59, 27, -9, 22, -4, -20, -37, -17, -34, -34, -1, 35, 26,
- 31, 5, -16, 4, 33, 22, 8, 5, -28, -41, -20, -10, -6, -2, -16, 12,
- 31, -23, 7, -2, -39, -28, -13, 8, 5, 16, -4, -6, -18, -24, -27, -50,
- -6, 5, 12, 0, -2, -14, -23, 5, -28, -10, 2, 28, 15, 2, 22, 27,
- 41, 31, 2, 12, 31, 5, 12, -6, 15, 40, 34, 18, 26, 26, 12, 34,
- 23, 34, 30, 22, 10, -26, -22, 1, 0, -1, 12, -4, -21, -5, -5, -20,
- -31, -25, -24, -42, -44, -41, -41, -37, -29, -28, -29, -40, -17, -21, -38, -42,
- -38, -40, -36, -13, -14, -8, -15, -7, -6, 5, 12, -1, -17, -1, 9, 2,
- 16, 30, 27, 37, 36, 38, 36, 36, 19, 45, 45, 33, 26, 33, 28, 36,
- 31, 17, 12, 22, 11, 11, 17, 5, -13, 6, 10, 2, -6, 2, 9, 15,
- -6, -8, -23, -44, -3, -11, -35, -25, -35, -23, -21, 0, -11, -21, -17, 11,
- -6, -11, -17, -33, -16, -16, -4, -7, -7, -9, -4, 1, 1, -3, 6, 7,
- 4, -17, -11, -6, -4, 1, 3, 6, 4, 5, -4, 17, 7, 3, 9, -20,
- 0, -7, -3, -5, 4, 9, 16, 2, 3, 8, 15, 15, 1, -3, 8, -1,
- 5, 14, 7, 4, 8, -8, 2, -3, 5, 11, 5, 3, -4, 10, 17, 13,
- -11, -5, 1, -3, 0, -6, -12, 2, -3, 13, -5, -25, -15, -7, 4, 1,
- -8, -4, -12, -16, 3, 9, -6, 3, -21, -4, 4, -14, 1, -1, -2, 3,
- -8, -5, 0, 7, -2, -3, -1, 3, -9, 5, -4, -17, -1, 9, 3, 7,
- 1, -4, -3, 5, 2, -7, -9, 12, -6, -14, -16, 2, -1, 16, 2, 2,
- 7, -6, -26, 3, -2, -4, -2, 10, 3, -7, 3, 8, 9, 5, 4, 1,
- -5, -5, 11, 8, 7, 11, 12, -1, -5, -16, 13, 7, 2, 11, 4, -4,
- 9, -8, -8, 14, 11, -8, 0, -1, -5, -2, -1, -10, -5, -9, -9, -16,
- -12, -8, -16, 5, -10, -4, -11, -3, 1, 0, -3, -5, -13, -9, -2, -8,
- 5, -9, -7, -2, 2, -11, -7, 13, 8, -3, 2, 7, -2, -1, 5, 0,
- 11, 6, 13, 15, 1, -4, 9, 5, 3, 8, -3, -4, 16, 4, 11, 9,
- 0, 8, 1, -6, -5, -18, 3, 7, -18, -4, 0, -3, -3, -6, -4, -5,
- -5, -10, -2, -9, -5, -2, -4, -11, -2, 1, -5, -2, 11, -6, -9, 1,
- 4, -6, -1, -5, 1, 2, 9, 5, 0, 4, 4, -2, 7, 0, -10, 5,
- 2, -3, 0, -6, 7, -4, -3, 6, -1, -6, -1, -1, 2, -2, -6, -3,
- 0, 8, -6, 4, -1, -5, -3, 3, 1, -5, -6, -2, -3, 5, 6, 0,
- 7, -3, 3, -1, 0, -2, 9, 1, 1, -3, 4, 5, -5, 2, -2, 2,
- -11, -2, -4, 11, 4, 5, 0, -5, -12, -6, -5, -5, 3, -2, -2, 2,
- 2, 1, 0, -1, -8, -5, -5, -3, 2, -1, 3, -1, 3, 0, -1, 0,
- -1, 1, 1, -4, -4, 2, -2, 1, -6, 1, 2, 4, 2, 2, -5, -1,
- 6, -3, -1, -4, 11, 3, -9, -2, -6, -3, 2, 4, 2, 1, 2, 4,
- 3, -6, -4, -3, -2, 0, 2, -2, 5, 2, -1, 3, -9, -3, -3, -4,
- -4, -1, 0, -2, 7, 3, 1, 1, -2, -4, -2, -3, -2, -4, 2, 4,
- -1, 2, 3, 0, 3, -1, 0, -2, -2, -3, 1, -1, -4, 5, -1, 5,
- 0, -3, -2, -1, -4, 3, -1, -3, -2, -2, -1, 0, 0, 1, -1, 0,
- -2, -2, 0, -3, -1, 0, 0, 1, 1, -2, -1, 1, -3, 1, 2, 0,
- -1, 0, -1, 1, 5, -2, 1, -3, -3, -1, -3, 0, 1, 3, 2, -1,
- -1, -2, -2, -1, 1, 30, -9, -44, 13, 26, -53, -41, 2, 76, 47, 40,
- -52, -53, -5, 12, -33, 15, 62, 53, -27, -98, -26, -42, 52, 75, 43, -32,
- -3, -83, -13, -36, 35, 39, 56, 25, -9, -122, -22, -3, 79, -6, 6, 25,
- -20, -12, -40, -19, 15, 74, 37, -14, -33, 6, 25, 7, -10, -4, 42, 4,
- -33, -87, -55, 29, 39, 21, -34, -27, 1, 26, 5, -22, -13, 10, 56, 0,
- -26, -40, 30, 42, 23, -7, -23, 28, 21, 9, -37, -25, 11, 25, 8, -48,
- -19, -15, 41, -2, -30, -28, 4, 30, -12, -23, -28, 17, 38, 3, -12, -8,
- 17, 26, 9, -32, 0, 12, 49, -3, -29, -17, 2, 41, -17, -24, -17, 9,
- 30, -23, -22, -21, 19, 17, -12, -35, -18, 12, 29, 2, -27, 7, 14, 42,
- -11, -24, -3, 15, 40, -23, -24, -17, 21, 22, -10, -23, -10, 23, 13, -4,
- -37, 0, 15, 19, -12, -40, -2, 13, 30, -16, -22, -3, 22, 22, -13, -16,
- -7, 34, 9, -5, -34, -5, 29, 10, -3, -39, 3, 17, 14, -13, -25, 5,
- 21, 12, -18, -22, -8, 31, 8, -5, -27, -9, 30, 1, -3, -30, 6, 27,
- 4, -14, -31, 8, 25, 10, -14, -21, -3, 24, 4, -11, -17, -1, 30, -1,
- -12, -26, 3, 32, 3, -13, -26, 5, 23, 3, -14, -17, 6, 22, 1, -17,
- -16, 4, 25, 4, -18, -19, 4, 23, 5, -17, -14, 5, 21, 1, -20, -11,
- 7, 23, 2, -19, -17, 8, 19, 6, -18, -15, 10, 14, 6, -26, -5, 11,
- 15, 4, -27, -5, 4, 22, 1, -17, -12, 6, 15, 1, -16, -13, 20, 8,
- 4, -28, -7, 17, 9, 10, -31, 3, 1, 13, 0, -18, 0, 6, 17, -10,
- -14, -15, 21, 10, 3, -19, -14, 22, -4, 11, -27, 8, 9, 7, -2, -26,
- 8, 2, 23, -13, -7, -13, 12, 11, -11, -2, -15, 27, -8, 2, -22, 0,
- 18, 0, 6, -27, 10, -4, 19, -13, -7, 1, 2, 19, -26, 7, -17, 28,
- -2, -8, -6, -11, 23, -9, 10, -24, 12, -2, 10, -8, -14, 13, -5, 25,
- -33, 7, -11, 17, 8, -19, 9, -18, 26, -17, 6, -12, 8, 8, -5, 0,
- -23, 20, -10, 25, -24, 2, 0, -2, 17, -30, 22, -16, 25, -15, -7, -2,
- -4, 21, -15, 13, -25, 19, -11, 9, -8, -7, 19, -15, 20, -34, 17, -9,
- 15, 0, -15, 11, -17, 24, -24, 16, -15, 15, 0, -11, 6, -21, 30, -18,
- 18, -22, 6, 3, -6, 10, -20, 23, -17, 20, -23, 7, -3, 2, 16, -24,
- 18, -26, 27, -15, 5, -2, -5, 19, -21, 12, -22, 22, -9, 9, -11, -5,
- 11, -13, 21, -27, 22, -17, 13, -5, -13, 14, -14, 28, -24, 9, -16, 12,
- 3, -7, 5, -14, 22, -20, 14, -21, 14, 3, -2, 6, -26, 20, -17, 23,
- -17, 3, 0, -2, 11, -23, 14, -14, 26, -14, 0, -10, -3, 18, -14, 15,
- -24, 19, -9, 4, -8, -9, 18, -6, 15, -29, 11, -10, 16, -1, -11, 9,
- -13, 23, -23, 8, -13, 12, 10, -11, 0, -20, 22, -7, 12, -19, 4, 4,
- 1, 4, -23, 18, -10, 22, -17, -7, 0, -1, 23, -20, 6, -18, 18, 0,
- -3, -8, -5, 20, -8, 6, -27, 14, 2, 11, -5, -20, 13, -10, 24, -22,
- 3, -5, 11, 8, -20, 1, -12, 28, -7, 0, -19, 2, 15, -5, 6, -25,
- 20, -4, 13, -19, -10, 10, 5, 17, -27, 1, -10, 22, -2, -10, -2, -7,
- 26, -18, 4, -24, 18, 10, 1, -8, -23, 16, 2, 15, -22, -1, 3, 10,
- 5, -27, 9, -8, 35, -19, -3, -18, 7, 19, -7, -3, -16, 14, 6, -5,
- -9, -12, 23, -5, 11, -33, 19, -10, 23, -22, 3, -5, 14, -2, -8, -8,
- 7, 7, 2, -14, 0, -2, 17, -14, 3, -17, 20, -5, 7, -19, 3, 3,
- 10, -5, -9, -4, 6, 6, -2, -10, 1, 2, 12, -13, 0, -11, 18, -3,
- 3, -16, 2, 4, 7, -5, -6, 0, 6, 1, -6, -6, 4, 6, 5, -11,
- -2, -4, 12, -6, 1, -9, 9, 0, 1, -11, 0, 6, 5, -2, -11, 1,
- 2, 7, -5, -7, 3, 1, 8, -13, 0, -6, 15, -3, -2, -11, 1, 9,
- 1, -2, -12, 6, 2, 5, -9, -5, 3, 6, 5, -12, -3, -3, 12, 0,
- -5, -7, 0, 8, -2, -2, -9, 7, 3, 5, -11, -4, 0, 9, 2, -7,
- -6, 0, 7, 1, -6, -3, 1, 8, -4, -5, -7, 7, 4, 4, -11, -1,
- -2, 10, -5, -1, -7, 8, 1, 1, -12, 1, 4, 7, -4, -8, -4, 8,
- 0, 3, -16, 11, -7, 1, 0, 0, -1, -1, -4, 1, -1, -3, -13, -8,
- -14, -3, -2, -2, 1, 8, 5, 7, -21, -13, -2, -6, -8, -22, -6, 5,
- 11, 34, 41, 33, 13, 28, 33, 48, 35, 21, -3, -26, -18, -10, 3, 7,
- 22, 21, 63, 40, 41, 43, 4, -8, -43, -63, -77, -77, -59, -18, 3, 2,
- -21, -46, -74, -90, -108, -101, -94, -89, -84, -85, -77, -59, -50, -33, -7, 18,
- 37, 47, 64, 101, 127, 125, 127, 126, 126, 126, 122, 100, 87, 62, 37, 28,
- 27, 25, 27, 34, 25, -4, -45, -85, -123, -128, -126, -128, -127, -123, -92, -73,
- -55, -45, -37, -33, -32, -33, -43, -53, -55, -43, -20, 3, 20, 34, 42, 49,
- 55, 63, 74, 84, 93, 101, 107, 112, 117, 109, 92, 63, 33, 8, -13, -25,
- -29, -30, -27, -27, -32, -46, -63, -82, -98, -109, -116, -121, -118, -104, -80, -49,
- -12, 21, 45, 58, 64, 66, 66, 61, 51, 44, 37, 32, 32, 33, 33, 28,
- 23, 15, 8, 3, 2, 9, 16, 20, 24, 23, 14, -1, -20, -37, -48, -53,
- -52, -47, -38, -26, -13, -5, -1, -4, -10, -22, -34, -43, -48, -46, -34, -16,
- 5, 25, 45, 65, 78, 84, 83, 71, 55, 39, 24, 9, -3, -12, -23, -34,
- -45, -57, -65, -71, -71, -63, -49, -34, -21, -11, -2, 2, 8, 11, 12, 14,
- 14, 20, 28, 38, 50, 58, 63, 61, 56, 46, 33, 17, -1, -19, -34, -45,
- -48, -44, -32, -19, -5, 5, 7, 4, -2, -7, -11, -15, -18, -21, -23, -26,
- -28, -30, -31, -29, -26, -20, -12, -1, 11, 21, 32, 42, 51, 55, 55, 52,
- 46, 41, 37, 32, 30, 28, 27, 24, 19, 12, -1, -21, -45, -67, -89, -103,
- -107, -101, -90, -70, -51, -33, -18, -2, 11, 23, 33, 39, 44, 49, 52, 57,
- 59, 59, 56, 52, 48, 41, 35, 28, 20, 15, 11, 4, 0, -5, -11, -18,
- -25, -34, -42, -47, -48, -46, -40, -33, -27, -24, -21, -24, -32, -42, -51, -56,
- -58, -56, -47, -35, -18, 2, 24, 48, 70, 88, 99, 104, 102, 97, 89, 79,
- 69, 59, 49, 37, 27, 14, 0, -14, -29, -44, -58, -71, -81, -87, -88, -88,
- -85, -81, -77, -72, -63, -51, -37, -21, -5, 12, 29, 43, 53, 59, 61, 57,
- 48, 36, 24, 13, 8, 8, 15, 25, 38, 48, 54, 54, 50, 43, 33, 22,
- 11, 3, -6, -15, -25, -35, -46, -54, -61, -65, -68, -69, -69, -68, -64, -59,
- -52, -43, -32, -20, -7, 6, 19, 31, 42, 51, 58, 62, 64, 62, 58, 52,
- 44, 35, 26, 17, 9, 1, -5, -10, -15, -18, -19, -20, -19, -18, -16, -15,
- -14, -14, -15, -16, -17, -18, -19, -19, -19, -19, -18, -16, -14, -11, -9, -6,
- -3, 0, 3, 6, 10, 14, 18, 22, 27, 32, 35, 37, 37, 35, 30, 23,
- 14, 4, -6, -15, -24, -31, -36, -39, -40, -39, -37, -32, -26, -19, -10, -1,
- 8, 17, 24, 29, 32, 33, 32, 29, 25, 20, 15, 11, 7, 3, -1, -5,
- -9, -14, -19, -24, -28, -31, -32, -31, -27, -23, -16, -10, -3, 2, 7, 10,
- 12, 13, 13, 13, 12, 10, 8, 7, 5, 5, 5, 5, 6, 8, 10, 13,
- 17, 20, 23, 25, 26, 25, 21, 16, 9, 1, -7, -16, -24, -31, -37, -42,
- -47, -49, -51, -52, -51, -48, -43, -37, -30, -20, -7, 6, 19, 0, -4, 10,
- 10, 11, -15, 4, -1, 3, -11, 11, 2, -12, 3, 18, -10, -62, 89, -16,
- -95, 118, -128, 122, -128, 112, -100, 109, -121, 120, -104, 58, 10, -88, 127, -102,
- 6, 98, -126, 35, 89, -111, -7, 112, -53, -94, 92, 64, -106, -53, 109, 52,
- -100, -75, 86, 95, -45, -119, -12, 111, 74, -58, -118, -27, 97, 100, -4, -107,
- -95, 17, 109, 92, -4, -99, -109, -26, 78, 115, 66, -27, -104, -109, -41, 55,
- 112, 98, 32, -53, -109, -105, -44, 41, 102, 109, 67, -4, -74, -112, -102, -47,
- 27, 88, 112, 93, 45, -19, -78, -110, -105, -65, -4, 59, 101, 110, 87, 43,
- -13, -67, -103, -111, -89, -44, 13, 65, 100, 109, 93, 59, 14, -36, -78, -104,
- -108, -90, -53, -6, 43, 83, 104, 106, 88, 57, 17, -27, -66, -95, -108, -102,
- -80, -44, -2, 41, 77, 99, 106, 98, 77, 46, 10, -29, -64, -91, -105, -105,
- -91, -64, -29, 10, 48, 78, 98, 105, 100, 84, 59, 30, -3, -36, -65, -88,
- -101, -105, -99, -83, -60, -32, -1, 30, 58, 80, 96, 103, 102, 94, 80, 62,
- 40, 16, -10, -35, -58, -78, -92, -101, -104, -100, -91, -77, -58, -36, -13, 12,
- 36, 57, 75, 89, 98, 102, 102, 97, 88, 76, 61, 44, 25, 5, -15, -35,
- -54, -70, -84, -94, -101, -104, -103, -98, -89, -77, -63, -46, -27, -8, 12, 31,
- 49, 65, 79, 90, 97, 102, 104, 102, 97, 90, 81, 70, 57, 42, 27, 10,
- -7, -24, -40, -56, -70, -81, -91, -99, -103, -105, -105, -101, -95, -87, -76, -63,
- -49, -34, -18, -1, 16, 32, 48, 62, 74, 85, 93, 100, 104, 105, 105, 102,
- 97, 90, 82, 72, 61, 48, 35, 21, 6, -9, -24, -38, -52, -65, -76, -86,
- -94, -101, -105, -108, -108, -106, -102, -96, -87, -78, -66, -54, -40, -26, -11, 4,
- 19, 34, 48, 61, 73, 83, 92, 99, 104, 107, 108, 108, 105, 101, 96, 89,
- 80, 70, 60, 48, 36, 22, 9, -5, -19, -33, -46, -58, -69, -80, -89, -96,
- -102, -107, -109, -110, -110, -107, -102, -97, -89, -80, -70, -59, -47, -33, -20, -6,
- 7, 19, 30, 41, 50, 58, 65, 71, 75, 78, 79, 80, 79, 77, 74, 70,
- 65, 60, 54, 48, 42, 36, 29, 22, 16, 10, 4, -2, -7, -12, -16, -19,
- -22, -24, -26, -27, -27, -27, -26, -25, -23, -22, -19, -17, -14, -12, -10, 0,
- -5, -2, -5, 2, -29, 22, 0, -27, 67, -59, 45, -13, -37, 28, 65, -4,
- 6, 60, 5, 58, 44, 60, 27, 43, 96, 71, 81, 48, 96, 70, 23, 90,
- 66, 80, 88, 40, 20, 61, 64, 12, 36, 24, 4, 7, 5, -27, -38, -26,
- -33, -49, -50, -70, -69, -93, -92, -94, -104, -104, -101, -110, -107, -111, -111, -126,
- -87, -119, -100, -94, -112, -93, -93, -80, -81, -76, -58, -56, -70, -30, -21, -42,
- -13, -3, 2, 8, 20, 28, 41, 45, 59, 62, 69, 84, 85, 90, 103, 109,
- 111, 118, 121, 121, 123, 121, 122, 121, 122, 121, 122, 121, 121, 120, 121, 120,
- 121, 120, 121, 120, 120, 119, 120, 119, 120, 118, 105, 106, 110, 83, 89, 92,
- 75, 67, 61, 57, 47, 40, 33, 24, 17, 10, 3, -2, -10, -20, -31, -31,
- -37, -49, -50, -63, -66, -69, -74, -79, -91, -89, -92, -95, -102, -106, -104, -107,
- -113, -113, -110, -113, -116, -114, -115, -114, -115, -114, -113, -114, -113, -114, -113, -112,
- -113, -109, -105, -111, -106, -107, -103, -100, -103, -99, -97, -98, -99, -92, -92, -93,
- -92, -92, -90, -88, -90, -88, -86, -89, -85, -85, -87, -85, -85, -82, -83, -82,
- -80, -78, -79, -76, -74, -73, -73, -69, -68, -66, -64, -65, -62, -58, -56, -56,
- -52, -50, -47, -43, -42, -39, -35, -33, -31, -27, -23, -21, -16, -16, -8, -7,
- -3, 1, 0, 10, 15, 15, 19, 26, 29, 30, 38, 41, 42, 47, 54, 54,
- 57, 63, 68, 69, 72, 77, 78, 80, 85, 84, 86, 87, 86, 87, 86, 85,
- 86, 85, 84, 85, 84, 83, 84, 83, 82, 82, 83, 82, 81, 82, 81, 80,
- 81, 80, 79, 80, 79, 79, 78, 79, 78, 78, 77, 74, 70, 66, 64, 61,
- 55, 52, 49, 45, 40, 35, 32, 29, 24, 19, 15, 12, 8, 4, 0, -4,
- -8, -11, -15, -17, -20, -25, -26, -29, -32, -34, -37, -39, -41, -43, -45, -46,
- -48, -49, -50, -50, -52, -52, -53, -52, -53, -54, -53, -53, -52, -52, -51, -50,
- -50, -49, -48, -48, -46, -45, -44, -42, -41, -40, -39, -37, -35, -34, -32, -30,
- -28, -27, -24, -23, -22, -20, -19, -17, -15, -14, -13, -12, -10, -9, -8, -8,
- -6, -6, -5, -4, -4, -3, -3, -2, -2, -1, -2, -1, -2, -1, -1, 0,
- -1, 0, 1, 6, -11, 19, -25, 24, -15, 11, -6, 1, 9, -6, -3, 11,
- -18, 28, -23, 8, 6, -2, -1, 0, -5, 18, -23, 24, -28, 27, -12, -1,
- -2, 6, 4, -14, 19, -29, 42, -40, 22, -6, -3, 14, -16, 4, 8, -9,
- 13, -22, 17, 5, -24, 37, -34, 20, -4, -11, 19, -20, 21, -16, 1, 17,
- -17, 5, -9, 25, -31, 31, -40, 32, -11, -7, 4, -4, 13, -23, 29, -40,
- 51, -49, 20, 3, -20, 38, -47, 34, -21, 14, -9, 4, -13, 20, -29, 37,
- -57, 59, -48, 23, -5, -7, 5, -6, -5, 13, -17, 9, -4, -12, 22, -19,
- -8, 10, -5, -7, 8, -18, 19, -13, 5, -12, 6, -10, 18, -40, 66, -91,
- 82, -56, 17, 19, -51, 56, -45, 30, -19, 5, -6, 7, -9, -4, -2, -5,
- 13, -19, 1, 20, -28, 13, -6, 0, -17, 33, -48, 38, -16, -20, 53, -75,
- 75, -61, 30, -12, -9, 2, 5, -9, -7, 15, -17, 9, 4, -46, 70, -85,
- 86, -67, 29, 18, -60, 76, -70, 29, -8, -1, 1, 14, -58, 93, -118, 127,
- -125, 85, -36, -2, 17, -39, 46, -61, 70, -99, 122, -120, 56, 15, -85, 116,
- -101, 30, 43, -108, 127, -122, 72, -38, -3, 20, -31, 29, -37, 42, -50, 63,
- -72, 40, -7, -46, 66, -82, 53, -25, 1, 1, -1, -3, 3, -24, 24, -34,
- 27, -24, 36, -49, 37, -38, 35, -42, 13, -4, -14, 14, -29, 42, -58, 58,
- -60, 41, -39, 27, -35, 27, -32, 25, -37, 43, -50, 32, -20, -4, 4, -14,
- 16, -43, 66, -93, 79, -58, 27, -11, -21, 34, -40, 24, -7, -25, 31, -29,
- 19, -18, -2, 1, -6, 4, -31, 47, -63, 62, -64, 32, 2, -29, 23, -21,
- 19, -41, 59, -76, 62, -52, 26, -11, -1, -10, 6, -10, -7, 17, -42, 34,
- -12, -34, 73, -106, 92, -61, 26, -24, 8, -7, -2, 3, -24, 31, -44, 27,
- -9, -22, 38, -43, 15, -4, -3, -2, -12, 5, 1, -7, 7, -25, 17, -17,
- 4, -15, 27, -40, 34, -18, 6, -13, 12, -3, -9, -6, 8, -18, 18, -36,
- 54, -55, 30, -25, 26, -41, 38, -49, 48, -38, 8, 16, -40, 47, -52, 34,
- -12, -4, 2, -13, 0, 1, 6, -11, 19, -25, 24, -15, 11, -6, 1, 9,
- -6, -3, 11, -18, 28, -23, 8, 6, -2, -1, 0, -5, 18, -23, 24, -28,
- 27, -12, -1, -2, 6, 4, -14, 19, -29, 42, -40, 22, -6, -3, 14, -16,
- 4, 8, -9, 13, -22, 17, 5, -24, 37, -34, 20, -4, -11, 19, -20, 21,
- -16, 1, 17, -17, 5, -9, 25, -31, 31, -40, 32, -11, -7, 4, -4, 13,
- -23, 29, -40, 51, -49, 20, 3, -20, 38, -47, 34, -21, 14, -9, 4, -13,
- 20, -29, 37, -57, 59, -48, 23, -5, -7, 5, -6, -5, 13, -17, 9, -4,
- -12, 22, -19, -8, 10, -5, -7, 8, -18, 19, -13, 5, -12, 6, -10, 18,
- -40, 66, -91, 82, -56, 17, 19, -51, 56, -45, 30, -19, 5, -6, 7, -9,
- -4, -2, -5, 13, -19, 1, 20, -28, 13, -6, 0, -17, 33, -48, 38, -16,
- -20, 53, -75, 75, -61, 30, -12, -9, 2, 5, -9, -7, 15, -17, 9, 4,
- -46, 70, -85, 86, -67, 29, 18, -60, 76, -70, 29, -8, -1, 1, 14, -58,
- 93, -118, 127, -125, 85, -36, -2, 17, -39, 46, -61, 70, -99, 122, -120, 56,
- 15, -85, 116, -101, 30, 43, -108, 127, -122, 72, -38, -3, 20, -31, 29, -37,
- 42, -50, 63, -72, 40, -7, -46, 66, -82, 53, -25, 1, 1, -1, -3, 3,
- -24, 24, -34, 27, -24, 36, -49, 37, -38, 35, -42, 13, -4, -14, 14, -29,
- 42, -58, 58, -60, 41, -39, 27, -35, 27, -32, 25, -37, 43, -50, 32, -20,
- -4, 4, -14, 16, -43, 66, -93, 79, -58, 27, -11, -21, 34, -40, 24, -7,
- -25, 31, -29, 19, -18, -2, 1, -6, 4, -31, 47, -63, 62, -64, 32, 2,
- -29, 23, -21, 19, -41, 59, -76, 62, -52, 26, -11, -1, -10, 6, -10, -7,
- 17, -42, 34, -12, -34, 73, -106, 92, -61, 26, -24, 8, -7, -2, 3, -24,
- 31, -44, 27, -9, -22, 38, -43, 15, -4, -3, -2, -12, 5, 1, -7, 7,
- -25, 17, -17, 4, -15, 27, -40, 34, -18, 6, -13, 12, -3, -9, -6, 8,
- -18, 18, -36, 54, -55, 30, -25, 26, -41, 38, -49, 48, -38, 8, 16, -40,
- 47, -52, 34, -12, -4, 2, -13, -1, -9, -21, -32, -43, -55, -58, -40, -8,
- 15, 29, 38, 44, 59, 63, 51, 20, -20, -47, -61, -58, -48, -42, -43, -35,
- -15, 15, 41, 55, 61, 62, 70, 67, 45, 11, -31, -62, -80, -78, -71, -62,
- -54, -39, -15, 18, 50, 68, 79, 83, 92, 88, 57, 16, -31, -71, -94, -95,
- -90, -83, -71, -55, -28, 7, 49, 77, 93, 100, 109, 107, 78, 36, -20, -71,
- -99, -104, -100, -92, -83, -69, -43, -5, 42, 79, 100, 108, 114, 112, 90, 51,
- -9, -65, -100, -110, -105, -95, -87, -76, -52, -11, 35, 75, 100, 107, 111, 106,
- 90, 52, -4, -60, -97, -109, -99, -87, -80, -65, -35, 5, 43, 75, 91, 95,
- 93, 87, 71, 31, -19, -64, -93, -99, -88, -76, -66, -44, -9, 28, 59, 79,
- 84, 80, 71, 59, 35, -5, -45, -76, -96, -95, -77, -59, -39, -9, 28, 61,
- 86, 98, 93, 74, 52, 28, -6, -43, -72, -94, -108, -99, -77, -52, -20, 19,
- 56, 84, 106, 115, 106, 79, 45, 3, -40, -74, -93, -108, -112, -100, -79, -46,
- -1, 45, 78, 100, 113, 118, 108, 81, 39, -19, -67, -93, -103, -108, -104, -94,
- -74, -32, 19, 61, 88, 102, 108, 109, 100, 73, 21, -44, -87, -102, -104, -97,
- -90, -78, -49, 0, 46, 78, 90, 92, 89, 87, 77, 43, -15, -72, -101, -104,
- -93, -79, -69, -47, -3, 47, 84, 96, 89, 74, 65, 58, 37, -7, -61, -99,
- -110, -101, -82, -62, -38, 2, 49, 92, 112, 106, 82, 59, 41, 18, -19, -61,
- -95, -111, -110, -98, -74, -39, 6, 54, 99, 122, 123, 104, 79, 50, 12, -32,
- -72, -100, -111, -110, -106, -90, -54, -4, 49, 99, 123, 126, 113, 95, 69, 24,
- -27, -72, -102, -114, -109, -104, -94, -64, -16, 36, 87, 116, 121, 111, 97, 76,
- 36, -15, -61, -94, -110, -108, -98, -86, -60, -19, 29, 77, 104, 109, 99, 86,
- 67, 35, -7, -47, -82, -98, -101, -92, -77, -48, -14, 25, 67, 92, 95, 83,
- 66, 45, 18, -9, -37, -62, -77, -81, -78, -54, -16, 0, 0, 0, 12, -10,
- 16, -14, -18, 17, -31, -2, 3, -19, -8, 17, 28, 37, 31, -1, -25, -16,
- -47, -13, -43, -22, 6, 34, 41, 49, 41, 27, 6, -33, -62, -54, -59, -32,
- -13, 29, 53, 73, 60, 54, 16, -19, -58, -77, -89, -42, -46, 17, 55, 78,
- 86, 81, 33, -3, -35, -84, -110, -75, -70, 0, 39, 78, 92, 105, 70, 13,
- -15, -82, -107, -103, -84, -41, 20, 81, 85, 127, 86, 39, -4, -63, -103, -99,
- -107, -69, 2, 68, 82, 127, 84, 58, 28, -44, -88, -104, -108, -83, -13, 29,
- 69, 116, 87, 77, 40, -16, -65, -89, -104, -89, -40, -1, 47, 96, 90, 85,
- 52, 9, -38, -62, -96, -95, -62, -22, 21, 73, 78, 86, 65, 35, -15, -41,
- -80, -92, -69, -48, 1, 43, 65, 80, 73, 49, 8, -23, -59, -75, -74, -60,
- -22, 17, 49, 69, 65, 60, 25, -1, -36, -59, -70, -61, -40, -9, 30, 52,
- 57, 63, 37, 17, -12, -41, -61, -57, -50, -30, 9, 30, 49, 60, 47, 28,
- 6, -20, -49, -51, -53, -42, -11, 13, 34, 53, 50, 34, 18, -3, -35, -39,
- -52, -49, -23, 0, 18, 41, 47, 36, 31, 10, -21, -28, -43, -49, -31, -13,
- 2, 28, 39, 35, 38, 19, -7, -18, -33, -42, -36, -26, -12, 19, 30, 34,
- 36, 22, 6, -5, -25, -38, -36, -29, -17, 8, 19, 26, 35, 28, 12, 3,
- -17, -30, -29, -29, -22, -3, 9, 19, 33, 26, 14, 8, -9, -18, -22, -28,
- -25, -9, 3, 15, 22, 20, 18, 12, 1, -11, -22, -24, -21, -13, -3, 8,
- 11, 20, 21, 12, 5, -6, -19, -16, -17, -17, -7, 3, 8, 20, 17, 7,
- 7, -2, -11, -13, -16, -17, -5, 2, 5, 12, 13, 8, 6, 3, -9, -11,
- -9, -14, -5, 1, -3, 6, 11, 6, 7, 2, -6, -4, -4, -10, -6, -3,
- -4, 5, 8, 2, 5, 4, -2, 0, -3, -9, -4, -3, -3, 2, 3, 0,
- 6, 4, 0, -1, -2, -2, 0, -4, 8, -1, 9, 14, 53, 57, 33, -4,
- -20, -14, -31, -71, -112, -43, 30, -22, -102, -74, 38, 90, 35, -22, 20, 99,
- 96, 22, -42, -5, 48, 16, -74, -97, -51, 10, -21, -80, -68, 24, 77, 43,
- -9, 20, 90, 99, 32, -28, -8, 41, 18, -63, -97, -55, -2, -18, -74, -67,
- 11, 69, 44, -1, 17, 83, 98, 40, -20, -8, 35, 20, -55, -95, -60, -8,
- -19, -69, -68, 3, 61, 45, 1, 15, 78, 99, 46, -14, -8, 33, 22, -48,
- -93, -62, -13, -19, -67, -70, -5, 56, 44, 3, 13, 73, 99, 51, -10, -7,
- 32, 25, -42, -91, -66, -15, -18, -65, -73, -11, 51, 44, 3, 9, 69, 100,
- 55, -6, -8, 32, 30, -36, -89, -68, -17, -17, -64, -77, -18, 47, 45, 3,
- 5, 64, 100, 60, -2, -8, 32, 34, -30, -87, -70, -19, -14, -63, -80, -25,
- 43, 45, 3, 1, 59, 100, 66, 1, -9, 31, 39, -23, -84, -74, -20, -12,
- -59, -84, -32, 38, 46, 3, -3, 53, 101, 71, 6, -10, 31, 43, -14, -81,
- -76, -24, -9, -57, -86, -41, 33, 46, 5, -9, 47, 99, 77, 9, -11, 28,
- 49, -6, -76, -79, -25, -9, -50, -91, -46, 9, -41, 2, 6, -33, 33, -4,
- -1, 34, -93, 60, -49, 68, -21, 41, -38, -38, 27, -87, 127, -34, 38, -3,
- -34, -2, -85, 79, -24, 4, 75, -23, 11, -70, 1, -6, -6, 63, -48, 76,
- -71, 2, -7, -15, 46, -32, 48, -25, -5, 10, -31, 18, -23, 5, 6, 17,
- 11, 3, 24, -46, -21, -1, -5, 31, 1, 36, -23, -11, -4, -29, 14, -5,
- 29, 9, -2, -2, -20, -2, -15, 13, 7, 4, 15, -11, 4, -13, -1, 1,
- -13, 15, -6, 9, 9, -2, -4, -11, -2, -11, 7, 12, 9, 5, -6, -6,
- -16, -2, 3, 6, 13, 1, 7, -14, -3, -11, -1, 8, 0, 18, -3, -3,
- -6, -13, 0, 4, 2, 9, 2, 2, -6, -4, -1, -8, 2, 4, 2, 7,
- -4, 2, 1, -7, -3, -2, 0, 2, 8, -2, 2, -1, -7, -3, -1, 3,
- 4, 3, 3, -3, -4, -4, 0, 2, 1, 5, -1, -2, 1, -4, -1, 1,
- 0, 2, 8, -22, 25, 30, 6, -19, -62, -19, 10, 83, 57, -67, -88, -52,
- 63, 127, 42, -63, -121, -70, 82, 111, 46, -43, -114, -35, 45, 73, 39, -19,
- -54, -41, 9, 49, 24, -16, -14, -9, -6, 10, 8, -22, 25, 30, 6, -19,
- -62, -19, 10, 83, 57, -67, -88, -52, 63, 127, 42, -63, -121, -70, 82, 111,
- 46, -43, -114, -35, 45, 73, 39, -19, -54, -41, 9, 49, 24, -16, -14, -9,
- -6, 10, 94, 127, 124, 127, 127, 114, 73, 35, -11, -52, -98, -118, -125, -128,
- -128, -128, -128, -128, -128, -128, -124, -86, -47, 0, 40, 87, 106, 116, 119, 125,
- 37, -7, 122, 72, -57, -71, -88, -28, 48, 127, 36, -30, -53, -126, -16, 71,
- 92, 51, -1, -83, -128, 14, 43, 83, 86, -14, -106, -87, -7, 28, 1, 122,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0
-};
-
-const EAS_U32 eas_sampleLengths[] =
-{
- 9922, 9338, 6793, 5242, 3057, 2818, 2806, 1835,
- 1603, 1262, 1227, 1168, 1132, 1132, 994, 907,
- 817, 801, 583, 418, 402, 387, 387, 357,
- 347, 212, 167, 40, 40, 32, 30
-};
-
-const EAS_U32 eas_sampleOffsets[] =
-{
- 0x00000000, 0x000026c2, 0x00004b3c, 0x000065c5, 0x00007a3f, 0x00008630, 0x00009132, 0x00009c28,
- 0x0000a353, 0x0000a996, 0x0000ae84, 0x0000b34f, 0x0000b7df, 0x0000bc4b, 0x0000c0b7, 0x0000c499,
- 0x0000c824, 0x0000cb55, 0x0000ce76, 0x0000d0bd, 0x0000d25f, 0x0000d3f1, 0x0000d574, 0x0000d6f7,
- 0x0000d85c, 0x0000d9b7, 0x0000da8b, 0x0000db32, 0x0000db5a, 0x0000db82, 0x0000dba2
-};
-
-/*----------------------------------------------------------------------------
- * S_EAS (hybrid)
- *----------------------------------------------------------------------------
-*/
-const S_EAS easSoundLib =
-{
- 0x01534145,
- 0x00105622,
- eas_banks,
- eas_programs,
- eas_regions,
- eas_articulations,
- eas_sampleLengths,
- eas_sampleOffsets,
- eas_samples,
- eas_fmRegions,
- 1,
- 1,
- 61,
- 53,
- 31,
- 128
-}; /* end S_EAS */
-
-/*----------------------------------------------------------------------------
- * Statistics
- *
- * Number of banks: 1
- * Number of programs: 1
- * Number of regions: 61
- * Number of articulations: 53
- * Number of samples: 31
- * Size of sample pool: 56276
- *----------------------------------------------------------------------------
-*/
-/* end C:\Sonic\Trunk\EASLib\WTLibrary\hybrid_22khz_mcu.c */
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision:$
+ * $Date:$
+ *----------------------------------------------------------------------------
+*/
+
+#include "eas_sndlib.h"
+
+/*----------------------------------------------------------------------------
+ * Articulations
+ *----------------------------------------------------------------------------
+*/
+const S_ARTICULATION eas_articulations[] =
+{
+ { /* articulation 0 */
+ { 32767, 30725, 0, 30725 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 951, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 1 */
+ { 32767, 26863, 0, 26863 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 951, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 2 */
+ { 32767, 30484, 0, 30668 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 951, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 3 */
+ { 32767, 26439, 0, 26439 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 951, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 4 */
+ { 32767, 0, 32767, 32715 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 951, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 5 */
+ { 32767, 21333, 0, 21333 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 951, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 6 */
+ { 32767, 31882, 0, 31938 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 951, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 7 */
+ { 32767, 32663, 32767, 32663 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 951, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 8 */
+ { 32767, 0, 32767, 0 },
+ { 32767, 1902, 0, 0 },
+ 0, 0, 951, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 9 */
+ { 32767, 32349, 0, 32349 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 951, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 10 */
+ { 32767, 0, 32767, 17213 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 951, 0, 0, 0, 0, 0, -1
+ },
+ { /* articulation 11 */
+ { 32767, 32072, 0, 32072 },
+ { 32767, 761, 0, 0 },
+ 0, 0, 951, 0, 0, 0, 0, 0, -56
+ },
+ { /* articulation 12 */
+ { 32767, 23749, 0, 23749 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 951, 0, 0, 0, 0, 0, 56
+ },
+ { /* articulation 13 */
+ { 32767, 32010, 0, 32010 },
+ { 32767, 761, 0, 0 },
+ 0, 0, 951, 0, 0, 0, 0, 0, -31
+ },
+ { /* articulation 14 */
+ { 9511, 21333, 0, 21333 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 951, 0, 0, 0, 0, 0, 56
+ },
+ { /* articulation 15 */
+ { 32767, 31844, 0, 31844 },
+ { 32767, 761, 0, 0 },
+ 0, 0, 951, 0, 0, 0, 0, 0, -6
+ },
+ { /* articulation 16 */
+ { 32767, 32123, 0, 32194 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 951, 0, 0, 0, 0, 0, 56
+ },
+ { /* articulation 17 */
+ { 32767, 31730, 0, 31730 },
+ { 32767, 761, 0, 0 },
+ 0, 0, 951, 0, 0, 0, 0, 0, 6
+ },
+ { /* articulation 18 */
+ { 32767, 31391, 0, 31391 },
+ { 32767, 951, 0, 0 },
+ 0, 0, 951, 0, 0, 0, 0, 0, 31
+ },
+ { /* articulation 19 */
+ { 32767, 31964, 0, 31964 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 951, 0, 0, 0, 0, 0, 25
+ },
+ { /* articulation 20 */
+ { 32767, 31056, 0, 31056 },
+ { 32767, 951, 0, 0 },
+ 0, 0, 951, 0, 0, 0, 0, 0, 63
+ },
+ { /* articulation 21 */
+ { 32767, 32289, 0, 32271 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 951, 0, 0, 0, 0, 0, -37
+ },
+ { /* articulation 22 */
+ { 19021, 31882, 0, 31911 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 951, 0, 0, 0, 0, 0, -37
+ },
+ { /* articulation 23 */
+ { 32767, 31988, 0, 32032 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 951, 0, 0, 0, 0, 0, -37
+ },
+ { /* articulation 24 */
+ { 32767, 0, 32767, 32663 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 951, 0, 0, 0, 0, 0, 12
+ },
+ { /* articulation 25 */
+ { 32767, 31352, 0, 31352 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 951, 0, 0, 0, 0, 0, -25
+ },
+ { /* articulation 26 */
+ { 32767, 0, 32767, 32663 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 951, 0, 0, 0, 0, 0, 25
+ },
+ { /* articulation 27 */
+ { 32767, 31817, 0, 31781 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 951, 0, 0, 0, 0, 0, -25
+ },
+ { /* articulation 28 */
+ { 32767, 30725, 0, 30725 },
+ { 32767, 95, 0, 0 },
+ 0, 0, 951, 240, 0, 0, 0, 0, -56
+ },
+ { /* articulation 29 */
+ { 32767, 32230, 0, 32218 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 951, 0, 0, 0, 0, 0, -37
+ },
+ { /* articulation 30 */
+ { 32767, 26439, 0, 26439 },
+ { 32767, 3804, 0, 0 },
+ 0, 0, 951, 0, 0, 0, 0, 0, 50
+ },
+ { /* articulation 31 */
+ { 32767, 23749, 0, 23749 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 951, 0, 0, 0, 0, 0, -50
+ },
+ { /* articulation 32 */
+ { 32767, 29434, 0, 29434 },
+ { 32767, 3804, 0, 0 },
+ 0, 0, 951, 0, 0, 0, 0, 0, -50
+ },
+ { /* articulation 33 */
+ { 32767, 30240, 0, 30234 },
+ { 32767, 3804, 0, 0 },
+ 0, 0, 951, 0, 0, 0, 0, 0, -44
+ },
+ { /* articulation 34 */
+ { 32767, 32558, 0, 32558 },
+ { 32767, 254, 0, 0 },
+ 0, 0, 951, 0, 0, 0, 0, 0, 25
+ },
+ { /* articulation 35 */
+ { 32767, 0, 32767, 32663 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 951, 0, 0, 0, 0, 0, -63
+ },
+ { /* articulation 36 */
+ { 3804, 23749, 0, 23749 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 951, 0, 0, 0, 0, 0, -63
+ },
+ { /* articulation 37 */
+ { 32767, 23749, 0, 23749 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 951, 0, 0, 0, 0, 0, -59
+ },
+ { /* articulation 38 */
+ { 32767, 30725, 0, 30725 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 951, 0, 0, 0, 0, 0, 50
+ },
+ { /* articulation 39 */
+ { 32767, 28809, 0, 28809 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 951, 0, 0, 0, 0, 0, 44
+ },
+ { /* articulation 40 */
+ { 1902, 30725, 0, 30725 },
+ { 32767, 380, 0, 0 },
+ 0, 0, 951, -100, 0, 0, 0, 0, 44
+ },
+ { /* articulation 41 */
+ { 32767, 9042, 0, 9042 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 951, 0, 0, 0, 0, 0, 25
+ },
+ { /* articulation 42 */
+ { 32767, 29889, 0, 29889 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 951, 0, 0, 0, 0, 0, 63
+ },
+ { /* articulation 43 */
+ { 32767, 30240, 0, 30234 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 951, 0, 0, 0, 0, 0, 63
+ },
+ { /* articulation 44 */
+ { 19021, 19970, 0, 19970 },
+ { 951, 32767, 32767, 0 },
+ 0, 0, 951, 100, 0, 0, 0, 0, -25
+ },
+ { /* articulation 45 */
+ { 3804, 17213, 0, 17213 },
+ { 951, 32767, 32767, 0 },
+ 0, 0, 951, 500, 0, 0, 0, 0, -25
+ },
+ { /* articulation 46 */
+ { 32767, 17213, 0, 17213 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 951, 0, 0, 0, 0, 0, -56
+ },
+ { /* articulation 47 */
+ { 32767, 30725, 0, 30725 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 951, 0, 0, 0, 0, 0, -56
+ },
+ { /* articulation 48 */
+ { 32767, 0, 32767, 0 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 951, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 49 */
+ { 32767, 31180, 0, 31180 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 951, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 50 */
+ { 19021, 31964, 0, 32071 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 951, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 51 */
+ { 32767, 29669, 0, 29669 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 951, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 52 */
+ { 32767, 31742, 0, 31352 },
+ { 32767, 294, 0, 0 },
+ 0, 0, 951, 0, 10000, 7121, 0, 0, 0
+ }
+}; /*end Articulations */
+
+/*----------------------------------------------------------------------------
+ * Regions
+ *----------------------------------------------------------------------------
+*/
+const S_WT_REGION eas_regions[] =
+{
+ { { 0, 27, 27 }, -2868, 16422, 0, 0, 19, 0 }, /* region 0 */
+ { { 0, 28, 28 }, -3568, 32767, 0, 0, 13, 0 }, /* region 1 */
+ { { 0, 29, 29 }, -4553, 32767, 0, 0, 9, 1 }, /* region 2 */
+ { { 0, 30, 30 }, -4853, 32767, 0, 0, 9, 2 }, /* region 3 */
+ { { 0, 31, 31 }, -3868, 23197, 0, 0, 15, 3 }, /* region 4 */
+ { { 1536, 32, 32 }, -3368, 20675, 0, 0, 29, 4 }, /* region 5 */
+ { { 1537, 33, 33 }, -3868, 20675, 792, 800, 17, 5 }, /* region 6 */
+ { { 1537, 34, 34 }, -3968, 16422, 792, 800, 17, 6 }, /* region 7 */
+ { { 0, 35, 35 }, -4968, 32767, 0, 0, 20, 7 }, /* region 8 */
+ { { 0, 36, 36 }, -4968, 32767, 0, 0, 20, 7 }, /* region 9 */
+ { { 0, 37, 37 }, -4051, 18426, 0, 0, 16, 8 }, /* region 10 */
+ { { 0, 38, 38 }, -4151, 23197, 0, 0, 5, 9 }, /* region 11 */
+ { { 0, 39, 39 }, -4668, 23197, 0, 0, 12, 10 }, /* region 12 */
+ { { 0, 40, 40 }, -4151, 23197, 0, 0, 5, 4 }, /* region 13 */
+ { { 1, 41, 41 }, -5855, 26028, 798, 993, 14, 11 }, /* region 14 */
+ { { 257, 42, 42 }, -4368, 26028, 4288, 6792, 2, 12 }, /* region 15 */
+ { { 1, 43, 43 }, -5755, 26028, 798, 993, 14, 13 }, /* region 16 */
+ { { 257, 44, 44 }, -4568, 26028, 4288, 6792, 2, 14 }, /* region 17 */
+ { { 1, 45, 45 }, -5755, 26028, 798, 993, 14, 15 }, /* region 18 */
+ { { 257, 46, 46 }, -4768, 26028, 4288, 6792, 2, 16 }, /* region 19 */
+ { { 1, 47, 47 }, -5455, 26028, 798, 993, 14, 17 }, /* region 20 */
+ { { 1, 48, 48 }, -5355, 26028, 798, 993, 14, 18 }, /* region 21 */
+ { { 1, 49, 49 }, -5368, 16422, 1294, 5241, 3, 19 }, /* region 22 */
+ { { 1, 50, 50 }, -5255, 26028, 798, 993, 14, 20 }, /* region 23 */
+ { { 1, 51, 51 }, -5268, 16422, 6592, 9921, 0, 21 }, /* region 24 */
+ { { 1, 52, 52 }, -5768, 32767, 1294, 5241, 3, 22 }, /* region 25 */
+ { { 1, 53, 53 }, -5418, 14636, 6592, 9921, 0, 23 }, /* region 26 */
+ { { 0, 54, 54 }, -5751, 26028, 0, 0, 11, 24 }, /* region 27 */
+ { { 1, 55, 55 }, -5468, 32767, 1294, 5241, 3, 25 }, /* region 28 */
+ { { 0, 56, 56 }, -7255, 32767, 0, 0, 24, 26 }, /* region 29 */
+ { { 1, 57, 57 }, -5868, 32767, 1294, 5241, 3, 27 }, /* region 30 */
+ { { 1, 58, 58 }, -7053, 23197, 0, 166, 26, 28 }, /* region 31 */
+ { { 1, 59, 59 }, -5968, 16422, 6592, 9921, 0, 29 }, /* region 32 */
+ { { 1, 60, 60 }, -6453, 23197, 432, 582, 18, 30 }, /* region 33 */
+ { { 1, 61, 61 }, -6853, 16422, 432, 582, 18, 30 }, /* region 34 */
+ { { 1, 62, 62 }, -7253, 20675, 432, 582, 18, 31 }, /* region 35 */
+ { { 1, 63, 63 }, -7353, 23197, 432, 582, 18, 32 }, /* region 36 */
+ { { 1, 64, 64 }, -7953, 23197, 432, 582, 18, 33 }, /* region 37 */
+ { { 0, 65, 65 }, -7555, 32767, 0, 0, 4, 34 }, /* region 38 */
+ { { 0, 66, 66 }, -7955, 20675, 0, 0, 4, 34 }, /* region 39 */
+ { { 512, 67, 67 }, -7155, 18426, 0, 0, 24, 35 }, /* region 40 */
+ { { 512, 68, 68 }, -7755, 18426, 0, 0, 24, 35 }, /* region 41 */
+ { { 0, 69, 69 }, -7755, 32767, 0, 0, 21, 36 }, /* region 42 */
+ { { 0, 70, 70 }, -6855, 21900, 0, 0, 21, 37 }, /* region 43 */
+ { { 769, 71, 71 }, -6355, 23197, 0, 1226, 10, 38 }, /* region 44 */
+ { { 769, 72, 72 }, -6955, 26028, 0, 1226, 10, 38 }, /* region 45 */
+ { { 1024, 73, 73 }, -7955, 32767, 0, 0, 7, 39 }, /* region 46 */
+ { { 1024, 74, 74 }, -8455, 32767, 0, 0, 7, 40 }, /* region 47 */
+ { { 1, 75, 75 }, -8068, 23197, 0, 29, 30, 41 }, /* region 48 */
+ { { 0, 76, 76 }, -10455, 23197, 0, 0, 28, 42 }, /* region 49 */
+ { { 0, 77, 77 }, -10055, 23197, 0, 0, 28, 43 }, /* region 50 */
+ { { 0, 78, 78 }, -8853, 16422, 0, 0, 23, 44 }, /* region 51 */
+ { { 0, 79, 79 }, -10253, 16422, 0, 0, 23, 45 }, /* region 52 */
+ { { 1280, 80, 80 }, -6468, 13045, 0, 0, 25, 46 }, /* region 53 */
+ { { 1280, 81, 81 }, -6568, 16422, 0, 0, 25, 47 }, /* region 54 */
+ { { 0, 82, 82 }, -8455, 20675, 0, 0, 22, 48 }, /* region 55 */
+ { { 0, 83, 83 }, -9068, 32767, 0, 0, 6, 49 }, /* region 56 */
+ { { 1, 84, 84 }, -8568, 23197, 0, 9337, 1, 50 }, /* region 57 */
+ { { 0, 85, 85 }, -9655, 32767, 0, 0, 27, 0 }, /* region 58 */
+ { { 0, 86, 86 }, -9068, 16422, 0, 0, 8, 51 }, /* region 59 */
+ { { 32769, 87, 87 }, -9168, 32767, 1335, 1603, 8, 52 } /* region 60 */
+}; /* end Regions */
+
+/*----------------------------------------------------------------------------
+ * FM Regions
+ *----------------------------------------------------------------------------
+*/
+const S_FM_REGION eas_fmRegions[] =
+{
+
+ { /* FM region 0 */
+ { 37, 0, 127 }, 0, 255, 8, 0,
+ {
+ { 514, 239, 47, 97, 0, 184, 3 },
+ { 1, 244, 89, 114, 0, 248, 2 },
+ { 3370, 244, 49, 76, 40, 192, 2 },
+ { -1, 227, 97, 51, 160, 212, 2 }
+ }
+ },
+ { /* FM region 1 */
+ { 37, 0, 127 }, 160, 255, 8, 0,
+ {
+ { 2514, 223, 95, 72, 0, 176, 3 },
+ { 1, 244, 73, 145, 0, 244, 2 },
+ { 3600, 245, 81, 198, 40, 192, 2 },
+ { 3, 246, 81, 163, 108, 212, 2 }
+ }
+ },
+ { /* FM region 2 */
+ { 37, 0, 127 }, 160, 255, 119, 0,
+ {
+ { 0, 216, 79, 72, 0, 216, 2 },
+ { 2, 244, 73, 145, 0, 244, 2 },
+ { 3370, 247, 33, 182, 60, 204, 2 },
+ { 1200, 246, 65, 163, 108, 204, 2 }
+ }
+ },
+ { /* FM region 3 */
+ { 37, 0, 127 }, 160, 255, 1, 0,
+ {
+ { 3369, 248, 65, 71, 40, 208, 2 },
+ { -3, 245, 88, 113, 0, 244, 2 },
+ { 2784, 225, 65, 133, 80, 192, 2 },
+ { 3, 241, 81, 113, 80, 216, 2 }
+ }
+ },
+ { /* FM region 4 */
+ { 34, 0, 127 }, 0, 255, 128, 0,
+ {
+ { 0, 229, 155, 183, 0, 228, 2 },
+ { -3, 243, 90, 81, 0, 244, 2 },
+ { 4800, 248, 109, 180, 36, 192, 2 },
+ { 3, 245, 90, 85, 16, 244, 2 }
+ }
+ },
+ { /* FM region 5 */
+ { 34, 0, 127 }, 9, 96, 192, 0,
+ {
+ { 1200, 229, 157, 180, 0, 216, 2 },
+ { -3, 244, 90, 81, 0, 244, 2 },
+ { 1902, 255, 111, 182, 80, 208, 2 },
+ { 3, 246, 92, 83, 0, 244, 2 }
+ }
+ },
+ { /* FM region 6 */
+ { 34, 0, 127 }, 0, 255, 154, 0,
+ {
+ { 3102, 244, 63, 102, 228, 228, 2 },
+ { 1200, 247, 93, 97, 0, 236, 2 },
+ { 1902, 255, 63, 98, 156, 220, 2 },
+ { 1200, 244, 92, 98, 0, 236, 2 }
+ }
+ },
+ { /* FM region 7 */
+ { 37, 0, 127 }, 0, 255, 202, 0,
+ {
+ { 0, 251, 131, 19, 216, 220, 2 },
+ { 1201, 247, 62, 113, 0, 240, 2 },
+ { 0, 243, 154, 36, 240, 224, 2 },
+ { 2784, 250, 61, 36, 240, 208, 2 }
+ }
+ },
+ { /* FM region 8 */
+ { 33, 0, 127 }, 0, 255, 80, 0,
+ {
+ { -1, 213, 191, 183, 0, 204, 2 },
+ { 1, 245, 154, 129, 0, 244, 2 },
+ { 3831, 252, 159, 100, 0, 200, 2 },
+ { 1197, 246, 91, 182, 0, 244, 2 }
+ }
+ },
+ { /* FM region 9 */
+ { 34, 0, 127 }, 48, 80, 21, 0,
+ {
+ { 2982, 255, 43, 96, 0, 196, 3 },
+ { 3, 247, 71, 130, 0, 244, 2 },
+ { 3358, 253, 40, 98, 144, 208, 2 },
+ { -2, 246, 70, 130, 0, 236, 2 }
+ }
+ },
+ { /* FM region 10 */
+ { 34, 0, 127 }, 48, 80, 26, 0,
+ {
+ { 3096, 249, 72, 100, 0, 208, 2 },
+ { 2185, 249, 102, 130, 0, 240, 2 },
+ { 3386, 247, 66, 100, 144, 212, 2 },
+ { -2, 247, 102, 130, 0, 240, 2 }
+ }
+ },
+ { /* FM region 11 */
+ { 34, 0, 127 }, 92, 67, 21, 0,
+ {
+ { 2982, 255, 27, 146, 0, 200, 3 },
+ { 3, 246, 68, 146, 0, 240, 2 },
+ { 3358, 250, 149, 116, 144, 208, 2 },
+ { -3, 245, 68, 146, 0, 240, 0 }
+ }
+ },
+ { /* FM region 12 */
+ { 34, 0, 127 }, 0, 67, 0, 0,
+ {
+ { 1500, 239, 60, 151, 0, 220, 2 },
+ { 0, 247, 76, 146, 0, 240, 2 },
+ { 2398, 234, 156, 151, 0, 212, 2 },
+ { 0, 246, 105, 146, 0, 244, 2 }
+ }
+ },
+ { /* FM region 13 */
+ { 34, 0, 127 }, 0, 67, 0, 0,
+ {
+ { 2500, 255, 60, 151, 0, 220, 2 },
+ { 0, 249, 92, 146, 0, 244, 2 },
+ { 3369, 250, 156, 151, 0, 196, 2 },
+ { 0, 248, 89, 146, 0, 244, 2 }
+ }
+ },
+ { /* FM region 14 */
+ { 37, 0, 127 }, 160, 255, 0, 0,
+ {
+ { 2300, 229, 112, 49, 0, 208, 2 },
+ { -3, 247, 67, 50, 0, 248, 2 },
+ { 1074, 255, 41, 49, 0, 196, 2 },
+ { 686, 240, 97, 18, 0, 196, 2 }
+ }
+ },
+ { /* FM region 15 */
+ { 37, 0, 127 }, 160, 255, 219, 0,
+ {
+ { 3369, 255, 65, 70, 40, 216, 2 },
+ { 1, 246, 72, 113, 0, 240, 2 },
+ { 1902, 225, 33, 129, 80, 204, 2 },
+ { 2400, 225, 97, 113, 80, 200, 2 }
+ }
+ },
+ { /* FM region 16 */
+ { 35, 0, 127 }, 32, 48, 151, 0,
+ {
+ { 1201, 215, 35, 66, 252, 208, 0 },
+ { -9581, 254, 63, 177, 240, 240, 3 },
+ { 1902, 248, 47, 64, 112, 244, 2 },
+ { 0, 247, 35, 66, 208, 212, 2 }
+ }
+ },
+ { /* FM region 17 */
+ { 33, 0, 127 }, 0, 255, 153, 0,
+ {
+ { 1, 252, 31, 3, 244, 196, 2 },
+ { -1, 208, 31, 4, 248, 244, 2 },
+ { 1205, 209, 31, 4, 248, 236, 2 },
+ { 1899, 250, 31, 32, 0, 240, 2 }
+ }
+ },
+ { /* FM region 18 */
+ { 34, 0, 127 }, 32, 49, 201, 0,
+ {
+ { 1, 220, 47, 3, 244, 220, 0 },
+ { -10000, 208, 63, 1, 248, 240, 3 },
+ { 1586, 255, 47, 3, 188, 216, 2 },
+ { -1, 202, 63, 32, 80, 232, 2 }
+ }
+ },
+ { /* FM region 19 */
+ { 33, 0, 127 }, 0, 143, 29, 0,
+ {
+ { -1200, 223, 64, 0, 252, 216, 2 },
+ { 1200, 96, 41, 35, 248, 240, 2 },
+ { 1200, 143, 41, 64, 252, 224, 2 },
+ { 3102, 161, 41, 96, 248, 216, 2 }
+ }
+ },
+ { /* FM region 20 */
+ { 34, 0, 127 }, 0, 143, 34, 0,
+ {
+ { -1200, 133, 79, 1, 252, 212, 2 },
+ { 1201, 112, 46, 34, 248, 232, 2 },
+ { 0, 116, 79, 65, 252, 200, 2 },
+ { 1900, 161, 46, 98, 248, 232, 2 }
+ }
+ },
+ { /* FM region 21 */
+ { 34, 0, 127 }, 0, 143, 187, 0,
+ {
+ { 1202, 80, 74, 1, 252, 216, 2 },
+ { 2402, 112, 46, 34, 248, 232, 2 },
+ { 0, 99, 78, 97, 184, 216, 2 },
+ { 1899, 81, 46, 98, 236, 232, 2 }
+ }
+ },
+ { /* FM region 22 */
+ { 37, 0, 127 }, 22, 141, 34, 0,
+ {
+ { 2787, 176, 79, 4, 252, 208, 2 },
+ { 2785, 144, 45, 34, 248, 236, 2 },
+ { 3369, 83, 77, 100, 184, 172, 2 },
+ { 1902, 102, 45, 100, 172, 212, 0 }
+ }
+ },
+ { /* FM region 23 */
+ { 34, 0, 127 }, 0, 143, 135, 0,
+ {
+ { 1900, 112, 79, 3, 252, 220, 2 },
+ { 2400, 128, 45, 34, 248, 232, 2 },
+ { 1200, 115, 77, 98, 184, 220, 2 },
+ { 1904, 97, 45, 98, 236, 232, 2 }
+ }
+ },
+ { /* FM region 24 */
+ { 37, 0, 127 }, 0, 255, 157, 0,
+ {
+ { 1200, 244, 54, 4, 20, 200, 2 },
+ { 0, 245, 92, 130, 0, 244, 2 },
+ { 3802, 247, 68, 21, 0, 196, 2 },
+ { 1, 245, 43, 114, 0, 204, 2 }
+ }
+ },
+ { /* FM region 25 */
+ { 37, 0, 127 }, 0, 128, 83, 0,
+ {
+ { 0, 244, 51, 4, 200, 204, 0 },
+ { 0, 247, 108, 129, 0, 248, 0 },
+ { 2786, 243, 31, 70, 200, 220, 0 },
+ { 1902, 246, 44, 113, 12, 188, 0 }
+ }
+ },
+ { /* FM region 26 */
+ { 37, 0, 127 }, 0, 128, 61, 0,
+ {
+ { 0, 246, 51, 97, 76, 204, 0 },
+ { 0, 244, 60, 97, 0, 240, 0 },
+ { 1786, 255, 31, 64, 0, 180, 0 },
+ { 1200, 247, 60, 97, 12, 204, 0 }
+ }
+ },
+ { /* FM region 27 */
+ { 37, 0, 127 }, 0, 128, 153, 0,
+ {
+ { -2, 243, 53, 99, 96, 200, 0 },
+ { 0, 243, 60, 97, 0, 240, 0 },
+ { 3983, 247, 63, 100, 24, 204, 0 },
+ { 2, 242, 53, 99, 52, 212, 0 }
+ }
+ },
+ { /* FM region 28 */
+ { 37, 0, 127 }, 0, 128, 205, 0,
+ {
+ { -2, 244, 47, 97, 20, 208, 0 },
+ { 0, 252, 75, 193, 0, 248, 0 },
+ { 0, 254, 63, 98, 132, 224, 0 },
+ { 2786, 251, 63, 98, 52, 192, 0 }
+ }
+ },
+ { /* FM region 29 */
+ { 37, 0, 127 }, 0, 128, 221, 0,
+ {
+ { -1, 208, 191, 99, 220, 224, 0 },
+ { 1200, 243, 92, 97, 0, 244, 0 },
+ { 3984, 212, 11, 96, 168, 196, 0 },
+ { 1, 242, 127, 98, 108, 204, 0 }
+ }
+ },
+ { /* FM region 30 */
+ { 37, 0, 127 }, 0, 128, 174, 0,
+ {
+ { -3, 212, 207, 99, 0, 228, 0 },
+ { 1902, 241, 108, 97, 0, 248, 0 },
+ { 3805, 212, 59, 98, 0, 220, 0 },
+ { 1902, 146, 107, 98, 144, 196, 0 }
+ }
+ },
+ { /* FM region 31 */
+ { 41, 0, 127 }, 0, 255, 128, 0,
+ {
+ { 1206, 239, 43, 69, 0, 216, 2 },
+ { 4, 254, 42, 66, 0, 244, 2 },
+ { 702, 88, 55, 66, 0, 204, 2 },
+ { -4, 71, 55, 66, 0, 240, 2 }
+ }
+ },
+ { /* FM region 32 */
+ { 37, 0, 127 }, 0, 255, 85, 0,
+ {
+ { 500, 239, 95, 82, 0, 184, 3 },
+ { 0, 248, 73, 132, 0, 252, 2 },
+ { 2786, 203, 59, 130, 0, 176, 2 },
+ { 0, 216, 42, 100, 0, 208, 2 }
+ }
+ },
+ { /* FM region 33 */
+ { 37, 0, 127 }, 0, 128, 73, 0,
+ {
+ { 1, 229, 54, 131, 160, 208, 0 },
+ { -1, 244, 62, 97, 0, 248, 0 },
+ { 3986, 227, 127, 69, 140, 184, 0 },
+ { 1201, 249, 92, 114, 0, 204, 0 }
+ }
+ },
+ { /* FM region 34 */
+ { 37, 0, 127 }, 0, 128, 73, 0,
+ {
+ { 1, 225, 54, 100, 200, 212, 0 },
+ { -1, 244, 94, 97, 0, 248, 0 },
+ { 3986, 249, 127, 88, 112, 188, 0 },
+ { 1201, 249, 92, 85, 52, 208, 0 }
+ }
+ },
+ { /* FM region 35 */
+ { 37, 0, 127 }, 0, 128, 188, 0,
+ {
+ { -3, 198, 92, 179, 28, 212, 0 },
+ { 0, 243, 90, 145, 0, 248, 0 },
+ { 1901, 215, 95, 69, 28, 196, 0 },
+ { 3, 84, 108, 196, 32, 208, 0 }
+ }
+ },
+ { /* FM region 36 */
+ { 37, 0, 127 }, 0, 136, 6, 0,
+ {
+ { 0, 226, 99, 36, 224, 216, 0 },
+ { 1902, 248, 78, 33, 0, 252, 0 },
+ { 3369, 239, 250, 33, 0, 204, 0 },
+ { 0, 230, 253, 33, 0, 208, 0 }
+ }
+ },
+ { /* FM region 37 */
+ { 37, 0, 127 }, 0, 136, 195, 0,
+ {
+ { 0, 245, 99, 36, 152, 208, 0 },
+ { 1200, 248, 78, 33, 0, 252, 0 },
+ { 3369, 246, 250, 33, 0, 216, 0 },
+ { 0, 246, 61, 33, 0, 180, 0 }
+ }
+ },
+ { /* FM region 38 */
+ { 34, 0, 127 }, 0, 133, 221, 0,
+ {
+ { 1, 244, 67, 35, 80, 220, 0 },
+ { 3, 246, 94, 33, 0, 244, 0 },
+ { -1, 245, 70, 35, 80, 236, 2 },
+ { -3, 246, 63, 33, 0, 236, 2 }
+ }
+ },
+ { /* FM region 39 */
+ { 34, 0, 127 }, 0, 133, 220, 0,
+ {
+ { 0, 114, 51, 34, 132, 208, 0 },
+ { 3, 214, 62, 33, 0, 248, 0 },
+ { 0, 85, 54, 34, 44, 224, 2 },
+ { -3, 214, 63, 33, 0, 236, 2 }
+ }
+ },
+ { /* FM region 40 */
+ { 37, 0, 127 }, 48, 142, 187, 0,
+ {
+ { -1, 33, 22, 33, 200, 208, 0 },
+ { 0, 81, 105, 33, 220, 240, 0 },
+ { 2786, 245, 19, 50, 208, 192, 0 },
+ { 1, 245, 21, 82, 200, 220, 0 }
+ }
+ },
+ { /* FM region 41 */
+ { 37, 0, 127 }, 48, 126, 103, 0,
+ {
+ { -1, 193, 22, 33, 228, 212, 0 },
+ { 0, 81, 105, 33, 220, 244, 0 },
+ { 0, 245, 19, 50, 216, 228, 0 },
+ { 1200, 245, 19, 82, 200, 188, 0 }
+ }
+ },
+ { /* FM region 42 */
+ { 37, 0, 127 }, 16, 126, 202, 0,
+ {
+ { -1, 49, 24, 41, 200, 212, 0 },
+ { 0, 81, 71, 49, 220, 244, 0 },
+ { 3371, 243, 19, 36, 232, 192, 0 },
+ { 1, 242, 24, 36, 220, 212, 0 }
+ }
+ },
+ { /* FM region 43 */
+ { 37, 0, 127 }, 16, 124, 205, 0,
+ {
+ { 0, 129, 24, 49, 208, 200, 0 },
+ { 0, 67, 102, 81, 224, 244, 0 },
+ { 3804, 246, 23, 36, 160, 196, 0 },
+ { 1200, 244, 24, 35, 208, 200, 0 }
+ }
+ },
+ { /* FM region 44 */
+ { 37, 0, 127 }, 48, 144, 208, 0,
+ {
+ { -3, 209, 22, 33, 200, 204, 2 },
+ { 0, 81, 89, 33, 220, 240, 2 },
+ { -5000, 208, 6, 33, 244, 188, 3 },
+ { 3, 97, 89, 33, 224, 200, 0 }
+ }
+ },
+ { /* FM region 45 */
+ { 37, 0, 127 }, 0, 255, 186, 0,
+ {
+ { 500, 223, 95, 0, 0, 192, 3 },
+ { 0, 247, 89, 100, 0, 248, 2 },
+ { 3369, 255, 59, 168, 0, 212, 2 },
+ { 0, 216, 42, 97, 0, 212, 2 }
+ }
+ },
+ { /* FM region 46 */
+ { 34, 0, 127 }, 0, 255, 221, 0,
+ {
+ { 1206, 235, 70, 69, 0, 216, 2 },
+ { 4, 248, 84, 66, 0, 244, 2 },
+ { 1902, 247, 52, 137, 80, 216, 2 },
+ { -4, 245, 84, 131, 0, 240, 2 }
+ }
+ },
+ { /* FM region 47 */
+ { 37, 0, 127 }, 0, 255, 105, 0,
+ {
+ { 387, 231, 115, 34, 4, 216, 2 },
+ { 0, 248, 37, 65, 0, 252, 2 },
+ { 3308, 248, 117, 34, 8, 200, 2 },
+ { 1900, 213, 82, 50, 0, 192, 2 }
+ }
+ },
+ { /* FM region 48 */
+ { 34, 0, 127 }, 32, 160, 221, 0,
+ {
+ { -7, 209, 22, 33, 200, 204, 2 },
+ { -7, 81, 73, 33, 220, 244, 0 },
+ { 7, 209, 22, 33, 200, 208, 0 },
+ { 7, 97, 73, 33, 224, 244, 2 }
+ }
+ },
+ { /* FM region 49 */
+ { 34, 0, 127 }, 64, 128, 189, 0,
+ {
+ { -2, 209, 54, 32, 224, 216, 2 },
+ { -7726, 97, 105, 33, 220, 240, 3 },
+ { 1902, 209, 54, 34, 216, 208, 0 },
+ { 2, 81, 105, 33, 224, 236, 0 }
+ }
+ },
+ { /* FM region 50 */
+ { 34, 0, 127 }, 80, 144, 206, 0,
+ {
+ { -3, 179, 38, 33, 160, 220, 2 },
+ { -7726, 81, 69, 34, 220, 244, 3 },
+ { 3, 193, 38, 33, 240, 212, 0 },
+ { -8000, 65, 69, 34, 224, 236, 3 }
+ }
+ },
+ { /* FM region 51 */
+ { 37, 0, 127 }, 96, 128, 204, 0,
+ {
+ { -3, 97, 38, 33, 180, 216, 0 },
+ { 0, 81, 69, 34, 220, 240, 2 },
+ { 3369, 145, 38, 33, 240, 196, 2 },
+ { -13190, 65, 69, 34, 240, 200, 3 }
+ }
+ },
+ { /* FM region 52 */
+ { 34, 0, 127 }, 64, 128, 108, 0,
+ {
+ { -3, 193, 37, 35, 236, 208, 0 },
+ { 2394, 97, 90, 36, 224, 232, 2 },
+ { 3, 65, 40, 35, 236, 204, 2 },
+ { 1203, 97, 89, 33, 224, 240, 0 }
+ }
+ },
+ { /* FM region 53 */
+ { 37, 0, 127 }, 128, 128, 122, 0,
+ {
+ { 0, 193, 21, 34, 236, 188, 0 },
+ { 3, 97, 74, 36, 224, 248, 2 },
+ { 1906, 251, 24, 32, 96, 192, 3 },
+ { 1200, 97, 73, 32, 224, 184, 0 }
+ }
+ },
+ { /* FM region 54 */
+ { 34, 0, 127 }, 64, 133, 135, 0,
+ {
+ { 0, 194, 25, 35, 120, 200, 2 },
+ { 0, 97, 75, 36, 224, 240, 0 },
+ { 2906, 254, 28, 48, 0, 184, 3 },
+ { 0, 216, 75, 80, 204, 240, 2 }
+ }
+ },
+ { /* FM region 55 */
+ { 41, 0, 127 }, 208, 64, 255, 0,
+ {
+ { 475, 249, 16, 32, 252, 240, 2 },
+ { 702, 248, 71, 32, 0, 244, 2 },
+ { 1136, 232, 27, 32, 216, 248, 0 },
+ { 0, 249, 23, 48, 0, 248, 2 }
+ }
+ },
+ { /* FM region 56 */
+ { 37, 0, 127 }, 0, 132, 233, 0,
+ {
+ { 0, 195, 95, 64, 240, 208, 0 },
+ { 0, 225, 94, 64, 248, 240, 0 },
+ { 0, 254, 127, 0, 4, 196, 4 },
+ { 1902, 228, 95, 1, 248, 200, 0 }
+ }
+ },
+ { /* FM region 57 */
+ { 37, 0, 127 }, 16, 140, 238, 0,
+ {
+ { 0, 163, 90, 67, 228, 208, 0 },
+ { 0, 209, 77, 65, 248, 240, 0 },
+ { 1969, 173, 58, 65, 0, 176, 0 },
+ { 0, 210, 61, 52, 204, 220, 0 }
+ }
+ },
+ { /* FM region 58 */
+ { 37, 0, 127 }, 16, 140, 222, 0,
+ {
+ { 0, 119, 74, 67, 160, 212, 0 },
+ { 0, 146, 61, 65, 248, 244, 0 },
+ { 1900, 137, 58, 65, 100, 196, 0 },
+ { 0, 119, 61, 52, 120, 200, 0 }
+ }
+ },
+ { /* FM region 59 */
+ { 37, 0, 127 }, 16, 135, 219, 0,
+ {
+ { 0, 176, 79, 69, 240, 216, 0 },
+ { 0, 193, 79, 64, 248, 236, 0 },
+ { 0, 178, 123, 54, 92, 228, 0 },
+ { 3369, 212, 95, 38, 144, 212, 0 }
+ }
+ },
+ { /* FM region 60 */
+ { 34, 0, 127 }, 0, 119, 203, 0,
+ {
+ { 2, 65, 77, 66, 228, 204, 0 },
+ { 2, 161, 74, 64, 240, 240, 0 },
+ { -2, 85, 60, 66, 180, 216, 2 },
+ { -2, 162, 74, 64, 220, 240, 2 }
+ }
+ },
+ { /* FM region 61 */
+ { 34, 0, 127 }, 16, 154, 237, 0,
+ {
+ { 0, 179, 42, 64, 216, 208, 0 },
+ { 0, 209, 61, 64, 248, 244, 0 },
+ { -1200, 226, 55, 65, 244, 220, 2 },
+ { 1902, 162, 62, 52, 204, 236, 2 }
+ }
+ },
+ { /* FM region 62 */
+ { 34, 0, 127 }, 48, 119, 221, 0,
+ {
+ { 2, 119, 79, 64, 208, 212, 0 },
+ { 2, 209, 110, 64, 248, 236, 0 },
+ { -2, 84, 79, 64, 136, 212, 2 },
+ { -2, 209, 110, 64, 240, 240, 2 }
+ }
+ },
+ { /* FM region 63 */
+ { 34, 0, 127 }, 32, 135, 221, 0,
+ {
+ { 2, 165, 79, 64, 152, 216, 0 },
+ { 2, 225, 110, 64, 248, 236, 0 },
+ { -2, 132, 79, 64, 72, 224, 2 },
+ { -2, 241, 110, 64, 252, 236, 2 }
+ }
+ },
+ { /* FM region 64 */
+ { 37, 0, 127 }, 17, 127, 190, 0,
+ {
+ { 0, 209, 60, 67, 244, 208, 0 },
+ { 1200, 145, 94, 65, 248, 244, 2 },
+ { 3369, 197, 47, 4, 128, 192, 0 },
+ { 1902, 167, 94, 6, 200, 200, 0 }
+ }
+ },
+ { /* FM region 65 */
+ { 37, 0, 127 }, 17, 143, 190, 0,
+ {
+ { 0, 209, 60, 67, 244, 216, 0 },
+ { 1902, 145, 62, 65, 248, 240, 2 },
+ { 3369, 197, 47, 4, 128, 196, 0 },
+ { 2400, 167, 94, 6, 200, 212, 2 }
+ }
+ },
+ { /* FM region 66 */
+ { 37, 0, 127 }, 17, 143, 190, 0,
+ {
+ { 0, 209, 60, 67, 244, 208, 0 },
+ { 1902, 145, 62, 65, 248, 240, 2 },
+ { 3369, 197, 47, 4, 128, 192, 0 },
+ { 1902, 167, 94, 6, 200, 216, 2 }
+ }
+ },
+ { /* FM region 67 */
+ { 37, 0, 127 }, 17, 125, 190, 0,
+ {
+ { 0, 114, 109, 67, 244, 224, 0 },
+ { 1902, 166, 93, 97, 200, 240, 0 },
+ { 2786, 165, 95, 52, 160, 200, 0 },
+ { 2400, 173, 78, 54, 240, 212, 2 }
+ }
+ },
+ { /* FM region 68 */
+ { 34, 0, 127 }, 16, 140, 205, 0,
+ {
+ { 0, 211, 55, 66, 244, 208, 0 },
+ { 1902, 193, 93, 65, 248, 240, 0 },
+ { 0, 204, 47, 4, 244, 216, 0 },
+ { 3600, 183, 95, 6, 160, 232, 0 }
+ }
+ },
+ { /* FM region 69 */
+ { 34, 0, 127 }, 16, 126, 222, 0,
+ {
+ { 0, 243, 36, 66, 172, 200, 0 },
+ { 1200, 193, 110, 67, 248, 244, 0 },
+ { 0, 215, 33, 2, 232, 212, 0 },
+ { 3369, 178, 63, 6, 184, 240, 0 }
+ }
+ },
+ { /* FM region 70 */
+ { 34, 0, 127 }, 16, 140, 221, 0,
+ {
+ { 1200, 213, 61, 66, 136, 200, 0 },
+ { 1902, 193, 93, 68, 248, 240, 0 },
+ { 0, 197, 47, 2, 228, 216, 0 },
+ { 3369, 183, 95, 2, 160, 236, 0 }
+ }
+ },
+ { /* FM region 71 */
+ { 34, 0, 127 }, 16, 124, 201, 0,
+ {
+ { 1200, 195, 55, 68, 240, 208, 0 },
+ { 0, 209, 76, 65, 248, 236, 0 },
+ { 1902, 147, 47, 19, 208, 212, 0 },
+ { 0, 183, 79, 22, 156, 228, 0 }
+ }
+ },
+ { /* FM region 72 */
+ { 37, 0, 127 }, 32, 110, 234, 0,
+ {
+ { 500, 237, 60, 68, 0, 192, 1 },
+ { 1, 161, 93, 65, 248, 240, 2 },
+ { 3365, 154, 47, 16, 48, 180, 6 },
+ { 1200, 165, 92, 52, 160, 212, 2 }
+ }
+ },
+ { /* FM region 73 */
+ { 37, 0, 127 }, 32, 142, 200, 0,
+ {
+ { 0, 193, 60, 68, 248, 200, 0 },
+ { 1, 129, 61, 65, 248, 240, 2 },
+ { 3365, 154, 47, 16, 68, 184, 6 },
+ { 1200, 169, 92, 52, 160, 204, 2 }
+ }
+ },
+ { /* FM region 74 */
+ { 35, 0, 127 }, 32, 135, 36, 0,
+ {
+ { 1199, 165, 79, 66, 152, 192, 2 },
+ { -3, 145, 110, 64, 248, 240, 2 },
+ { 0, 199, 79, 66, 44, 236, 2 },
+ { 2986, 136, 110, 67, 100, 196, 2 }
+ }
+ },
+ { /* FM region 75 */
+ { 37, 0, 127 }, 32, 190, 71, 0,
+ {
+ { 868, 202, 140, 16, 24, 188, 2 },
+ { 0, 176, 77, 65, 248, 240, 2 },
+ { 3750, 169, 127, 16, 36, 228, 6 },
+ { 2400, 195, 60, 17, 232, 172, 2 }
+ }
+ },
+ { /* FM region 76 */
+ { 37, 0, 127 }, 224, 16, 123, 0,
+ {
+ { 275, 202, 14, 2, 44, 196, 2 },
+ { 0, 165, 89, 65, 56, 244, 2 },
+ { 0, 255, 12, 2, 64, 216, 6 },
+ { 963, 169, 14, 4, 40, 196, 2 }
+ }
+ },
+ { /* FM region 77 */
+ { 50, 0, 127 }, 192, 128, 100, 0,
+ {
+ { 1500, 202, 79, 68, 76, 204, 2 },
+ { -2, 97, 26, 64, 248, 232, 2 },
+ { 1588, 202, 223, 69, 4, 220, 0 },
+ { 3, 188, 121, 67, 48, 252, 2 }
+ }
+ },
+ { /* FM region 78 */
+ { 34, 0, 127 }, 112, 140, 205, 0,
+ {
+ { 0, 68, 47, 66, 60, 176, 2 },
+ { -2, 113, 94, 64, 248, 236, 0 },
+ { 5000, 121, 47, 64, 32, 168, 7 },
+ { 3, 136, 94, 64, 0, 236, 0 }
+ }
+ },
+ { /* FM region 79 */
+ { 35, 0, 127 }, 32, 135, 33, 0,
+ {
+ { 1199, 197, 79, 66, 152, 184, 2 },
+ { 0, 161, 110, 64, 248, 240, 2 },
+ { 0, 199, 79, 66, 44, 236, 2 },
+ { 2400, 255, 110, 65, 36, 208, 6 }
+ }
+ },
+ { /* FM region 80 */
+ { 34, 0, 127 }, 0, 192, 170, 0,
+ {
+ { 1199, 192, 77, 33, 200, 212, 0 },
+ { 0, 209, 107, 33, 232, 240, 0 },
+ { 1201, 80, 77, 33, 200, 212, 0 },
+ { 0, 241, 107, 33, 232, 240, 0 }
+ }
+ },
+ { /* FM region 81 */
+ { 34, 0, 127 }, 0, 192, 221, 0,
+ {
+ { -1, 192, 45, 33, 200, 212, 0 },
+ { -1, 209, 107, 33, 232, 244, 0 },
+ { 1, 80, 45, 33, 200, 212, 0 },
+ { 1, 241, 107, 33, 232, 244, 0 }
+ }
+ },
+ { /* FM region 82 */
+ { 37, 0, 127 }, 0, 112, 255, 0,
+ {
+ { 4750, 221, 45, 34, 48, 172, 4 },
+ { -10000, 161, 107, 33, 200, 244, 3 },
+ { 2204, 137, 45, 37, 64, 184, 0 },
+ { -2, 211, 107, 33, 160, 208, 0 }
+ }
+ },
+ { /* FM region 83 */
+ { 37, 0, 127 }, 16, 127, 238, 0,
+ {
+ { 2, 248, 45, 32, 204, 208, 0 },
+ { -9500, 241, 107, 33, 200, 240, 3 },
+ { 3369, 186, 45, 38, 24, 208, 0 },
+ { -2, 211, 107, 32, 220, 212, 0 }
+ }
+ },
+ { /* FM region 84 */
+ { 37, 0, 127 }, 0, 128, 221, 0,
+ {
+ { -1, 192, 191, 99, 220, 216, 0 },
+ { 1200, 243, 92, 97, 0, 244, 0 },
+ { 3984, 200, 11, 96, 168, 192, 0 },
+ { 1, 194, 127, 98, 108, 200, 0 }
+ }
+ },
+ { /* FM region 85 */
+ { 34, 0, 127 }, 128, 128, 111, 0,
+ {
+ { 1, 194, 25, 35, 120, 204, 2 },
+ { -9750, 193, 107, 36, 224, 244, 3 },
+ { 3906, 255, 28, 50, 12, 188, 3 },
+ { -1, 216, 107, 80, 204, 240, 2 }
+ }
+ },
+ { /* FM region 86 */
+ { 34, 0, 127 }, 32, 134, 222, 0,
+ {
+ { 0, 195, 52, 33, 200, 208, 0 },
+ { 0, 177, 90, 33, 232, 240, 2 },
+ { 702, 195, 52, 33, 200, 208, 2 },
+ { 702, 177, 90, 34, 232, 240, 2 }
+ }
+ },
+ { /* FM region 87 */
+ { 34, 0, 127 }, 32, 134, 205, 0,
+ {
+ { 0, 198, 75, 36, 120, 220, 2 },
+ { 0, 225, 78, 52, 40, 244, 2 },
+ { 0, 246, 47, 32, 220, 208, 2 },
+ { 1902, 241, 124, 32, 240, 236, 2 }
+ }
+ },
+ { /* FM region 88 */
+ { 35, 0, 127 }, 32, 120, 14, 0,
+ {
+ { 3600, 244, 67, 34, 88, 208, 0 },
+ { 3, 194, 84, 33, 84, 240, 2 },
+ { -3, 194, 84, 33, 172, 236, 2 },
+ { 902, 254, 114, 34, 0, 224, 3 }
+ }
+ },
+ { /* FM region 89 */
+ { 34, 0, 127 }, 64, 169, 170, 0,
+ {
+ { -3, 83, 69, 34, 184, 212, 0 },
+ { -7500, 50, 69, 33, 176, 244, 3 },
+ { 3, 81, 69, 34, 212, 212, 2 },
+ { -8500, 66, 69, 33, 176, 244, 3 }
+ }
+ },
+ { /* FM region 90 */
+ { 34, 0, 127 }, 64, 120, 221, 0,
+ {
+ { -2, 82, 69, 34, 244, 216, 0 },
+ { 0, 145, 102, 33, 228, 240, 0 },
+ { 2, 81, 69, 34, 244, 208, 2 },
+ { 0, 145, 102, 33, 224, 240, 2 }
+ }
+ },
+ { /* FM region 91 */
+ { 35, 0, 127 }, 32, 138, 14, 0,
+ {
+ { 2400, 148, 67, 34, 176, 200, 0 },
+ { 3, 194, 85, 33, 220, 236, 2 },
+ { -3, 194, 69, 33, 220, 236, 2 },
+ { 1905, 254, 114, 34, 48, 224, 2 }
+ }
+ },
+ { /* FM region 92 */
+ { 34, 0, 127 }, 82, 67, 71, 0,
+ {
+ { 2982, 228, 22, 146, 88, 192, 3 },
+ { 3, 102, 84, 146, 196, 240, 2 },
+ { 3358, 50, 149, 116, 144, 208, 2 },
+ { -3, 85, 84, 146, 120, 240, 0 }
+ }
+ },
+ { /* FM region 93 */
+ { 37, 0, 127 }, 48, 126, 219, 0,
+ {
+ { -3, 49, 19, 33, 120, 200, 0 },
+ { 0, 81, 70, 33, 220, 240, 0 },
+ { 3804, 242, 18, 50, 200, 200, 0 },
+ { 1203, 82, 19, 82, 200, 176, 0 }
+ }
+ },
+ { /* FM region 94 */
+ { 35, 0, 127 }, 32, 138, 13, 0,
+ {
+ { 2786, 116, 67, 34, 204, 184, 0 },
+ { 1902, 114, 69, 33, 192, 232, 2 },
+ { -3, 178, 69, 33, 188, 232, 2 },
+ { 3804, 254, 82, 34, 164, 228, 2 }
+ }
+ },
+ { /* FM region 95 */
+ { 34, 0, 127 }, 48, 135, 238, 0,
+ {
+ { -2, 34, 85, 34, 184, 224, 0 },
+ { 1, 113, 70, 33, 228, 236, 0 },
+ { 2, 19, 85, 34, 156, 224, 2 },
+ { -1, 129, 70, 33, 224, 236, 2 }
+ }
+ },
+ { /* FM region 96 */
+ { 50, 0, 127 }, 240, 112, 221, 0,
+ {
+ { 3369, 213, 69, 32, 0, 204, 0 },
+ { 0, 193, 70, 33, 112, 232, 2 },
+ { 0, 145, 69, 34, 244, 208, 2 },
+ { -9000, 145, 70, 33, 224, 236, 3 }
+ }
+ },
+ { /* FM region 97 */
+ { 34, 0, 127 }, 96, 122, 168, 0,
+ {
+ { -1, 99, 51, 33, 200, 208, 0 },
+ { -8500, 81, 83, 33, 232, 240, 3 },
+ { 702, 99, 52, 33, 200, 208, 2 },
+ { -9500, 65, 83, 34, 224, 240, 3 }
+ }
+ },
+ { /* FM region 98 */
+ { 34, 0, 127 }, 0, 67, 0, 0,
+ {
+ { 1500, 217, 55, 151, 20, 224, 2 },
+ { 3, 231, 70, 146, 88, 220, 2 },
+ { 2369, 115, 148, 151, 32, 196, 2 },
+ { -3, 118, 36, 146, 64, 244, 2 }
+ }
+ },
+ { /* FM region 99 */
+ { 34, 0, 127 }, 64, 169, 204, 0,
+ {
+ { -3, 228, 69, 34, 148, 220, 0 },
+ { -7448, 243, 69, 33, 200, 240, 3 },
+ { 3, 81, 68, 34, 212, 212, 2 },
+ { -8526, 65, 68, 33, 196, 240, 3 }
+ }
+ },
+ { /* FM region 100 */
+ { 34, 0, 127 }, 64, 119, 187, 0,
+ {
+ { 2786, 228, 22, 146, 176, 192, 0 },
+ { 3, 102, 68, 146, 196, 236, 2 },
+ { 3369, 178, 149, 116, 176, 208, 2 },
+ { -3, 231, 68, 146, 120, 240, 0 }
+ }
+ },
+ { /* FM region 101 */
+ { 34, 0, 127 }, 240, 144, 239, 0,
+ {
+ { -2, 49, 69, 34, 236, 208, 2 },
+ { -9000, 113, 102, 33, 228, 236, 3 },
+ { 2400, 149, 69, 34, 12, 216, 1 },
+ { 0, 145, 102, 33, 224, 236, 2 }
+ }
+ },
+ { /* FM region 102 */
+ { 50, 0, 127 }, 241, 176, 6, 0,
+ {
+ { 1200, 247, 49, 64, 252, 204, 0 },
+ { 3804, 246, 101, 32, 0, 232, 2 },
+ { 1902, 247, 32, 32, 112, 188, 2 },
+ { 0, 228, 84, 32, 0, 240, 2 }
+ }
+ },
+ { /* FM region 103 */
+ { 37, 0, 127 }, 64, 101, 221, 0,
+ {
+ { 1, 194, 68, 97, 196, 200, 2 },
+ { -10001, 247, 100, 114, 176, 240, 3 },
+ { 3370, 213, 33, 70, 52, 200, 2 },
+ { -1, 178, 68, 49, 208, 212, 0 }
+ }
+ },
+ { /* FM region 104 */
+ { 34, 0, 127 }, 0, 255, 203, 0,
+ {
+ { -3, 245, 82, 99, 200, 232, 2 },
+ { 2787, 244, 84, 96, 0, 236, 2 },
+ { 1198, 133, 81, 100, 196, 220, 2 },
+ { 1902, 147, 67, 80, 0, 232, 2 }
+ }
+ },
+ { /* FM region 105 */
+ { 37, 0, 127 }, 0, 255, 140, 0,
+ {
+ { 500, 255, 137, 179, 0, 200, 3 },
+ { 1902, 248, 90, 160, 0, 244, 2 },
+ { 3804, 245, 57, 35, 164, 204, 2 },
+ { 0, 245, 38, 51, 196, 208, 2 }
+ }
+ },
+ { /* FM region 106 */
+ { 37, 0, 127 }, 0, 255, 72, 0,
+ {
+ { 1000, 238, 57, 65, 0, 188, 3 },
+ { 1902, 247, 103, 112, 0, 244, 2 },
+ { 2786, 250, 36, 81, 68, 212, 2 },
+ { 0, 249, 50, 49, 172, 204, 2 }
+ }
+ },
+ { /* FM region 107 */
+ { 37, 0, 127 }, 16, 119, 72, 0,
+ {
+ { 1500, 255, 89, 65, 0, 196, 3 },
+ { 2790, 246, 39, 112, 0, 240, 0 },
+ { 1905, 246, 36, 81, 168, 208, 0 },
+ { 0, 249, 114, 49, 172, 212, 0 }
+ }
+ },
+ { /* FM region 108 */
+ { 37, 0, 127 }, 0, 255, 237, 0,
+ {
+ { 1902, 254, 89, 65, 0, 212, 2 },
+ { 0, 248, 87, 112, 0, 240, 2 },
+ { 3369, 231, 62, 81, 0, 208, 2 },
+ { 3, 245, 118, 49, 96, 196, 2 }
+ }
+ },
+ { /* FM region 109 */
+ { 34, 0, 127 }, 16, 188, 205, 0,
+ {
+ { -2, 179, 47, 50, 244, 224, 2 },
+ { 1900, 145, 94, 49, 248, 232, 2 },
+ { 3, 210, 46, 2, 244, 208, 2 },
+ { 2789, 133, 93, 4, 180, 244, 2 }
+ }
+ },
+ { /* FM region 110 */
+ { 37, 0, 127 }, 48, 135, 220, 0,
+ {
+ { 1901, 162, 25, 35, 144, 208, 0 },
+ { 0, 113, 105, 65, 220, 240, 0 },
+ { 3369, 233, 88, 51, 120, 212, 0 },
+ { 0, 229, 24, 84, 200, 208, 0 }
+ }
+ },
+ { /* FM region 111 */
+ { 34, 0, 127 }, 112, 32, 190, 0,
+ {
+ { 0, 53, 79, 66, 152, 212, 2 },
+ { 1200, 53, 75, 64, 136, 244, 2 },
+ { 500, 149, 60, 66, 16, 208, 2 },
+ { 1902, 200, 78, 64, 0, 248, 0 }
+ }
+ },
+ { /* FM region 112 */
+ { 37, 0, 127 }, 0, 144, 130, 0,
+ {
+ { 2514, 255, 68, 53, 0, 204, 2 },
+ { 2400, 247, 133, 48, 0, 240, 2 },
+ { 4151, 243, 67, 50, 0, 212, 2 },
+ { 3369, 243, 66, 56, 0, 204, 2 }
+ }
+ },
+ { /* FM region 113 */
+ { 37, 0, 127 }, 0, 255, 0, 0,
+ {
+ { 514, 253, 79, 51, 0, 196, 3 },
+ { 1905, 252, 89, 51, 0, 244, 2 },
+ { 4349, 245, 35, 51, 0, 208, 2 },
+ { 1205, 247, 34, 51, 0, 208, 2 }
+ }
+ },
+ { /* FM region 114 */
+ { 37, 0, 127 }, 0, 255, 0, 0,
+ {
+ { 514, 221, 69, 35, 0, 204, 3 },
+ { 0, 250, 86, 115, 0, 252, 2 },
+ { 1884, 244, 116, 51, 0, 200, 2 },
+ { 1208, 210, 35, 51, 0, 208, 2 }
+ }
+ },
+ { /* FM region 115 */
+ { 37, 0, 127 }, 0, 255, 16, 0,
+ {
+ { 514, 222, 85, 163, 0, 192, 3 },
+ { 0, 254, 108, 163, 0, 252, 2 },
+ { 3800, 255, 143, 160, 0, 176, 2 },
+ { 1200, 250, 105, 163, 0, 212, 2 }
+ }
+ },
+ { /* FM region 116 */
+ { 37, 0, 127 }, 0, 255, 16, 0,
+ {
+ { 1514, 249, 101, 163, 0, 204, 3 },
+ { -1200, 249, 87, 160, 0, 252, 2 },
+ { 0, 235, 143, 160, 0, 204, 2 },
+ { 1200, 234, 73, 163, 0, 204, 2 }
+ }
+ },
+ { /* FM region 117 */
+ { 37, 0, 127 }, 0, 255, 16, 0,
+ {
+ { 500, 239, 101, 160, 0, 204, 3 },
+ { -1195, 248, 104, 160, 0, 252, 2 },
+ { 1898, 252, 72, 163, 0, 216, 2 },
+ { 1239, 248, 87, 163, 0, 196, 2 }
+ }
+ },
+ { /* FM region 118 */
+ { 37, 0, 127 }, 0, 255, 255, 0,
+ {
+ { 500, 255, 98, 160, 0, 196, 3 },
+ { -1, 249, 105, 160, 0, 252, 2 },
+ { 1907, 250, 71, 160, 0, 252, 2 },
+ { 1182, 249, 87, 161, 0, 192, 2 }
+ }
+ },
+ { /* FM region 119 */
+ { 37, 0, 127 }, 0, 0, 100, 0,
+ {
+ { 600, 32, 15, 0, 252, 224, 6 },
+ { 0, 47, 111, 65, 0, 244, 2 },
+ { 1826, 16, 47, 0, 252, 216, 2 },
+ { 3551, 240, 47, 0, 252, 212, 2 }
+ }
+ },
+ { /* FM region 120 */
+ { 52, 0, 127 }, 240, 128, 235, 0,
+ {
+ { 1228, 161, 47, 17, 196, 200, 3 },
+ { 3000, 123, 75, 17, 0, 240, 2 },
+ { 7022, 72, 43, 17, 0, 216, 0 },
+ { 4000, 150, 79, 17, 48, 196, 3 }
+ }
+ },
+ { /* FM region 121 */
+ { 37, 0, 127 }, 224, 16, 86, 0,
+ {
+ { 275, 251, 6, 0, 36, 200, 2 },
+ { 0, 101, 104, 65, 56, 240, 2 },
+ { 0, 240, 6, 0, 252, 208, 6 },
+ { 1000, 195, 8, 0, 248, 200, 2 }
+ }
+ },
+ { /* FM region 122 */
+ { 34, 0, 127 }, 0, 0, 185, 0,
+ {
+ { 600, 35, 66, 17, 72, 224, 4 },
+ { -13000, 81, 67, 17, 228, 244, 2 },
+ { 702, 97, 38, 17, 212, 196, 6 },
+ { -14000, 81, 65, 17, 224, 244, 3 }
+ }
+ },
+ { /* FM region 123 */
+ { 50, 0, 127 }, 240, 112, 237, 0,
+ {
+ { -6528, 153, 127, 16, 0, 252, 3 },
+ { 1200, 105, 109, 16, 0, 216, 2 },
+ { -6022, 179, 139, 17, 0, 248, 3 },
+ { 2000, 104, 79, 17, 0, 240, 0 }
+ }
+ },
+ { /* FM region 124 */
+ { 50, 0, 127 }, 240, 240, 16, 0,
+ {
+ { 1914, 240, 64, 160, 240, 208, 2 },
+ { 1200, 240, 73, 163, 240, 244, 0 },
+ { 1900, 240, 64, 160, 240, 148, 2 },
+ { 4151, 240, 73, 163, 240, 244, 0 }
+ }
+ },
+ { /* FM region 125 */
+ { 34, 0, 127 }, 240, 56, 235, 0,
+ {
+ { -5522, 97, 32, 17, 196, 240, 3 },
+ { 0, 84, 75, 17, 180, 248, 3 },
+ { 702, 65, 38, 17, 224, 212, 6 },
+ { -4000, 161, 73, 17, 224, 252, 1 }
+ }
+ },
+ { /* FM region 126 */
+ { 53, 0, 127 }, 240, 248, 37, 0,
+ {
+ { 1050, 243, 0, 0, 252, 224, 7 },
+ { 2000, 49, 68, 0, 224, 236, 3 },
+ { 350, 240, 0, 0, 252, 216, 1 },
+ { 700, 240, 0, 0, 252, 212, 3 }
+ }
+ },
+ { /* FM region 127 */
+ { 53, 0, 127 }, 240, 248, 37, 0,
+ {
+ { 1050, 245, 85, 0, 0, 244, 7 },
+ { -5000, 247, 71, 0, 0, 252, 3 },
+ { 350, 240, 0, 0, 0, 164, 0 },
+ { 700, 32, 0, 0, 0, 252, 2 }
+ }
+ }}; /* end FM Regions */
+
+/*----------------------------------------------------------------------------
+ * Programs
+ *----------------------------------------------------------------------------
+*/
+const S_PROGRAM eas_programs[] =
+{
+ { 7864320, 0 } /* program 0 */
+}; /* end Programs */
+
+/*----------------------------------------------------------------------------
+ * Banks
+ *----------------------------------------------------------------------------
+*/
+const S_BANK eas_banks[] =
+{
+ { /* bank 0 */
+ 30976,
+ {
+ 32768, 32769, 32770, 32771, 32772, 32773, 32774, 32775,
+ 32776, 32777, 32778, 32779, 32780, 32781, 32782, 32783,
+ 32784, 32785, 32786, 32787, 32788, 32789, 32790, 32791,
+ 32792, 32793, 32794, 32795, 32796, 32797, 32798, 32799,
+ 32800, 32801, 32802, 32803, 32804, 32805, 32806, 32807,
+ 32808, 32809, 32810, 32811, 32812, 32813, 32814, 32815,
+ 32816, 32817, 32818, 32819, 32820, 32821, 32822, 32823,
+ 32824, 32825, 32826, 32827, 32828, 32829, 32830, 32831,
+ 32832, 32833, 32834, 32835, 32836, 32837, 32838, 32839,
+ 32840, 32841, 32842, 32843, 32844, 32845, 32846, 32847,
+ 32848, 32849, 32850, 32851, 32852, 32853, 32854, 32855,
+ 32856, 32857, 32858, 32859, 32860, 32861, 32862, 32863,
+ 32864, 32865, 32866, 32867, 32868, 32869, 32870, 32871,
+ 32872, 32873, 32874, 32875, 32876, 32877, 32878, 32879,
+ 32880, 32881, 32882, 32883, 32884, 32885, 32886, 32887,
+ 32888, 32889, 32890, 32891, 32892, 32893, 32894, 32895
+ }
+ }
+}; /* end Banks */
+
+/*----------------------------------------------------------------------------
+ * Samples
+ *----------------------------------------------------------------------------
+*/
+
+const EAS_SAMPLE eas_samples[] =
+{
+ 13, -24, 28, -32, 33, -37, 39, -61, 119, -76, 120, -70, 99, -122, 89, -113,
+ 91, -123, 122, -123, 77, 86, -116, 6, -118, 123, -23, 64, -93, 17, 24, -125,
+ 124, -125, 124, -24, -12, 56, 87, -54, 38, -91, 64, -2, -41, 126, -127, 20,
+ 8, -48, -62, 127, -128, 88, -43, -18, 86, -100, 44, -32, -26, 71, -13, 6,
+ 51, -33, -50, 106, -59, 33, 5, -20, 69, -56, 54, -48, -6, 38, -5, -38,
+ 35, -1, 12, -1, 4, 23, -56, 19, -7, 5, -4, 31, -38, 3, -12, -9,
+ -25, -7, 24, -32, 17, -21, -22, 24, -20, 6, -18, 0, -15, 5, -16, 15,
+ 3, 2, -10, 3, 27, -31, 37, -12, 32, -5, 2, -21, 27, -14, 20, -8,
+ 5, 15, -7, -11, 20, -37, 7, -23, 17, -22, 11, -14, 8, -44, 39, -52,
+ 26, 3, 14, -10, 51, -45, 29, -19, 19, -3, 41, -21, 46, -23, 10, 16,
+ -25, 3, 7, -30, 19, -9, -5, -1, 1, -19, 1, -24, -23, 51, -48, -10,
+ 17, -34, -38, 60, -71, 26, -43, 65, -59, 70, -26, 61, -51, 63, -51, 42,
+ -25, 58, -36, 31, 10, -14, -9, 8, -18, 8, 4, 8, 7, 31, -52, 39,
+ -53, 53, -56, 24, 11, 1, -20, -8, -32, -18, -10, -25, 4, 1, 37, -37,
+ 42, -42, 53, -57, 52, -18, 30, 11, 20, -52, 55, -61, 56, -50, 24, -26,
+ 38, -42, 36, -1, -43, 58, -46, 6, 18, -35, 31, -36, 28, -55, 55, -98,
+ 52, -41, 26, -24, 48, -31, 48, -26, 30, 19, -17, 23, -8, 13, 15, 19,
+ -7, -23, 41, -36, 20, -39, 65, -64, 66, -38, -9, 7, -14, -10, -3, 6,
+ 15, -19, -40, 53, -67, -11, -12, -25, 23, -11, -12, 46, -48, 39, -20, 20,
+ -14, 31, -54, 71, -25, 2, -8, -5, -9, 1, 7, 27, 17, -14, 43, -31,
+ 27, 11, -33, 20, -2, -33, 45, -38, 17, -9, -11, -17, -22, -19, 20, -25,
+ 4, 29, -35, 14, -17, 1, -7, 19, 2, 16, 32, -3, -17, 4, 0, -9,
+ 17, 5, -8, 52, -32, 40, -39, -5, -18, 14, -21, 31, 10, -17, 8, -34,
+ -7, 1, -44, 7, 10, -8, -6, -18, -25, -1, -19, 16, -29, 62, 6, 9,
+ 21, 0, -14, 4, 5, 20, 13, 27, -1, 18, -5, 21, -31, 11, 2, -9,
+ -4, 21, -27, 8, -21, -28, -19, 14, -12, 5, -20, 20, -36, 4, -18, -27,
+ -4, -4, 15, 4, 48, -7, -11, 20, -6, 7, 20, 1, 20, 0, 35, -35,
+ 28, -37, 7, -43, 21, -22, 23, -18, 12, -22, -13, -20, -11, 7, 23, -10,
+ 19, -18, 17, -41, 4, -16, -8, 21, 11, -4, 10, 30, -24, 32, -15, 15,
+ -13, 28, -5, 38, -10, 0, -22, -13, -12, 24, -18, 30, -7, 4, -16, 27,
+ -28, -3, -1, 18, -14, 31, -24, -3, -13, -19, -36, -2, -31, 9, -2, -12,
+ 17, 12, -50, 46, -49, 43, -15, 13, 22, 15, -25, 10, -8, -6, 14, -2,
+ 24, 15, 9, 17, -13, 5, 14, -15, 7, 20, 4, 4, 18, -16, 3, -47,
+ 31, -46, 19, -24, 5, -19, -1, -42, 14, -44, 18, -7, -1, 15, 9, -35,
+ 32, -44, 39, -46, 23, -16, 36, -25, 45, -34, 32, -8, 10, 5, 28, 0,
+ 12, 11, 3, 20, -23, 6, -8, 16, 7, 17, -19, 32, -44, 3, -8, -21,
+ -8, -5, 2, -29, 2, -3, -19, -14, 3, 7, -23, 10, 1, 3, 8, 13,
+ -44, 20, 21, -16, 23, 3, 5, 10, -11, 32, -11, 13, -7, 30, 4, 16,
+ -7, -6, -7, 14, -40, 4, -16, -26, 3, -1, 0, -6, 5, -50, 37, -27,
+ 18, -16, -14, 6, -1, -4, -15, 8, -12, 14, 9, -22, 42, -10, 23, -11,
+ 36, -15, 13, 30, 1, 47, -20, 33, -14, -12, 1, -20, -9, -9, -11, -13,
+ 7, -37, 25, -47, 14, -13, 4, -12, 9, -32, 18, -48, -1, -35, -1, -7,
+ 35, -20, 53, -4, 34, -7, 13, 19, 9, 30, 6, 45, -22, 23, -18, -6,
+ -1, 3, -30, 14, -15, 9, -39, 10, -33, -13, -24, 10, 14, 14, -10, 2,
+ -34, -4, -20, -21, -14, 40, -10, 17, -14, 28, -17, 37, -26, 69, -15, 38,
+ 2, 21, -25, 37, -61, 13, -9, 5, -17, 18, -41, 22, -57, -1, -9, -13,
+ 24, -10, 38, -5, 8, -16, -2, 1, 12, -25, -2, -13, 2, 2, -16, -19,
+ 32, -30, 22, 20, -4, 12, 11, -17, 19, -17, -3, 20, -33, 65, -27, 32,
+ -14, 8, -8, 13, -19, 9, -2, 7, 33, -40, 18, -18, -18, 6, -23, -11,
+ -11, -28, 4, -11, -15, -14, -8, -5, 34, -6, 19, 1, -3, 9, -1, 5,
+ 5, 14, -11, 40, -3, 18, -20, 16, -7, 2, -5, 9, -16, 9, -17, 0,
+ -17, 4, -17, -3, 3, 8, -14, -19, 12, -21, -7, 1, -2, -8, 16, 3,
+ -6, 35, -23, 33, -13, 11, 12, 3, -7, 26, -11, 19, -18, 23, -22, 39,
+ -49, 39, -50, 11, -38, 26, -29, 10, -6, -22, 15, -8, 15, -37, 36, -43,
+ 39, -43, 18, -26, 1, 11, 4, -2, 9, 7, 2, 7, 19, 1, 1, -4,
+ 16, -5, 16, -9, -3, 4, -4, -1, -17, 0, 11, 16, -27, 12, -15, 15,
+ -3, 0, 10, -3, -5, 12, -13, -7, -13, -31, -1, -3, -17, 15, -31, 25,
+ -10, 15, -1, 2, 4, 10, 7, 32, -13, 7, -22, 2, -10, 16, 1, -15,
+ 19, -24, 16, -18, -12, 18, -9, 9, 24, -8, 8, 11, 0, -31, 17, -55,
+ 21, -43, 40, -40, 29, -54, 44, -34, 22, 11, 16, 7, 19, 21, -6, 2,
+ -7, -16, 22, 0, -1, -4, 5, -8, 26, -42, 4, -6, -21, 35, -16, 8,
+ 0, -22, -13, 11, -31, 7, -28, 4, 17, -12, -18, -2, -23, 23, -1, 19,
+ 34, 7, 7, 35, -19, 11, -8, -17, 8, 4, 16, -16, -13, 9, -15, -5,
+ -1, -6, 7, 3, 11, 1, -7, -24, 21, -31, 36, -3, -10, 8, 2, -17,
+ 12, -24, 6, -3, 9, 15, 3, 13, -8, -13, -3, 6, -19, 14, -33, 16,
+ -17, -5, -31, 3, -29, 24, -7, -6, 35, -20, -5, 34, -20, 25, -3, 10,
+ 25, 8, 14, -13, 0, 1, 17, -33, 51, -38, 45, -32, 39, -3, -2, -24,
+ 3, -18, 14, -4, -44, 2, -25, -15, -2, -23, 3, -2, -2, 20, -14, 8,
+ -10, -4, 21, 11, -13, 32, -4, 8, 19, -16, -2, -2, -2, 14, -2, -1,
+ 27, -26, 20, 11, -13, 10, -3, -7, 12, -13, -3, -30, -16, 10, -26, -3,
+ -10, -2, -9, 15, -17, 1, -2, -7, 14, -8, 12, -3, -1, 2, 47, -26,
+ 22, -19, 16, 2, 13, -3, 21, -10, 22, -32, 43, -24, 16, 0, 5, -2,
+ 12, -44, -12, 1, -26, 1, -36, 5, 2, 9, -17, 20, -37, 14, -9, -5,
+ 6, -3, -13, 23, -19, 25, -33, 6, 17, 10, 19, 15, -4, 12, 5, -9,
+ 33, -20, 26, -9, 11, -2, 11, -21, -7, -13, -4, -8, -12, 0, -10, -9,
+ 8, -33, 9, -26, 8, 6, -8, 12, 7, -8, 0, 7, -16, 25, -8, 27,
+ 12, 0, 9, -9, 4, -17, 14, -16, 11, -8, 18, -2, 4, 2, -20, -18,
+ 22, -16, -5, 3, -24, 13, -10, -12, -10, 2, -16, 33, -15, 21, -15, -4,
+ -19, 29, -22, 18, 2, 20, 12, 18, -22, -7, -16, 7, -19, 14, 1, -17,
+ 33, -22, 38, -8, 3, -3, 21, -17, 51, -43, 15, -22, -23, -6, -12, -14,
+ 14, 9, 6, 4, -31, 3, -16, -14, 22, -22, 5, 13, -25, 17, -2, -18,
+ 7, 1, 5, 36, -16, 23, 4, -15, 29, -20, 10, 1, 24, 17, 16, -4,
+ -16, -37, -11, 1, -33, 27, -36, 17, -22, 2, -33, 16, -29, 32, -7, 24,
+ -12, 14, -12, 22, -16, 15, -20, 19, 9, 14, 12, -1, -24, 13, -6, -1,
+ 32, -19, 24, 12, -26, 4, -31, -38, 18, -16, -13, 3, -14, -1, 11, -15,
+ 15, 0, -2, 30, -6, 35, -23, 10, -35, 5, -14, 17, -21, 20, 4, 7,
+ 8, -5, -15, 20, -25, 26, 6, -3, 3, 5, -24, 26, -35, 4, 0, -6,
+ 13, -23, 8, -25, 1, -2, 9, 3, 17, 4, 0, 13, -15, 3, -21, -16,
+ 4, -5, -10, 11, -2, 7, 23, -22, 25, -19, 18, 25, -9, 14, -21, -7,
+ 11, -24, 22, -12, -7, 6, 9, -33, 11, -20, 2, -9, 2, 3, -13, 12,
+ -15, 23, -21, 16, -16, -2, 8, 13, -12, 18, -10, 16, -12, 20, -18, 18,
+ -1, 21, -21, 20, -30, -6, 10, -2, 13, -6, -15, 6, 2, -1, 1, -19,
+ 9, -15, -3, -11, 0, -5, 1, 5, 1, -4, -8, 1, -16, 23, 0, -23,
+ 2, 8, -6, 38, -4, 2, 13, -17, 31, -4, -8, 22, -14, 0, 12, -22,
+ 7, -7, 11, 4, -4, -12, -9, -22, 2, -17, -17, -11, 7, -17, 19, -24,
+ 9, -8, -6, 29, -4, 10, 4, 4, 23, -1, 9, -6, -12, 23, 16, -6,
+ 33, -29, 12, -7, -10, 17, -4, -18, 21, 0, -14, -2, -20, -21, 10, -28,
+ 5, -18, -4, 0, -11, 1, 5, -17, 3, 9, 20, 6, 1, -7, 2, -7,
+ 3, 9, -22, 29, 6, -1, 25, -10, 6, -1, 4, 12, 18, -13, 28, -11,
+ 6, -15, -14, -22, -7, 5, -14, 1, -16, -12, -5, 5, -9, 4, -1, -14,
+ 21, -10, -5, 0, -17, -7, 2, -10, 6, 11, 1, 37, -17, 6, 21, -24,
+ 41, 2, 23, 0, 10, -18, 16, -26, 14, -21, -19, 18, -9, -14, -1, -9,
+ -14, -3, -7, -10, 7, -7, 19, -11, 15, -25, -3, -6, 2, 8, -10, 4,
+ 12, -3, 11, -2, -2, 5, 31, -9, 39, -21, 14, -23, 18, -16, -1, -3,
+ -6, 0, 22, -9, -5, -17, -4, -12, 2, -3, -7, 10, -10, 7, -20, -19,
+ -10, 0, -14, 32, -15, -18, 13, -9, 2, 17, -14, 6, 36, -9, 28, 1,
+ 0, 17, -10, 5, 17, -8, 12, -2, 3, 2, -22, -6, -14, 6, 8, -11,
+ -14, 2, -23, 25, -35, 3, -18, 1, -14, 22, -1, -12, -7, -9, 13, -4,
+ 12, 4, -3, 18, 0, 1, 8, -14, 14, -2, 1, 17, -3, -14, 35, -17,
+ 19, -14, -6, 1, -9, 18, -17, -4, -13, -2, -14, 10, -10, -6, 0, 3,
+ 5, -12, -13, -3, -6, -6, 11, -13, -7, 13, -2, 6, 13, -7, 11, -5,
+ 23, 1, 29, -17, 23, -10, 18, -16, 12, -20, 10, 7, -9, -5, -21, -9,
+ 5, -13, -2, 0, -15, -11, 3, 0, -18, 5, -25, -2, 3, -2, -3, 4,
+ 8, 14, -7, 15, 4, 8, 19, 9, 11, 7, -3, 14, -11, 1, 15, -35,
+ 3, 3, -10, -16, 0, -15, 2, 3, -12, 27, -23, 32, -15, 10, -14, 3,
+ -27, 10, -15, 12, -24, 7, 2, 9, -2, -2, -1, 3, 1, 1, 8, -4,
+ 0, 6, -6, 1, 1, -1, 8, -11, 31, -27, 13, 4, -3, 5, -1, 0,
+ 2, 9, 0, 12, -31, 4, -27, 1, -25, 20, -21, -14, 12, -14, 0, -5,
+ -23, 18, -1, 15, 19, -5, 20, -8, 14, -7, 16, 3, 0, 8, 10, 0,
+ -8, -10, 3, -8, 9, -12, 4, 15, -6, 2, -12, -29, -3, -16, -11, 35,
+ -18, -1, -28, 7, -12, 0, 7, -5, 22, 10, 10, -4, 6, -13, 21, -23,
+ 20, 8, -13, 11, 15, -6, -6, -22, -1, 3, 14, 7, 11, -27, 12, -17,
+ -12, 8, -15, 3, -8, 12, -12, 5, -30, 12, -18, 9, -2, 3, 4, 15,
+ 1, 5, -9, 0, -8, 24, -2, 21, 5, -4, -4, 14, -15, 0, -1, 3,
+ 17, -5, 13, -19, -10, -4, -6, -4, -7, 18, -27, 8, 1, -12, -21, -13,
+ 1, -9, 11, 1, -3, -1, 22, -21, 9, 6, -3, 20, -2, 17, 7, -12,
+ 1, 4, 4, -9, 9, -20, 24, 7, -9, -3, -7, -6, 10, 7, 3, 9,
+ -2, -3, -4, 1, -19, -8, -16, 0, -12, 0, -25, 4, -22, 10, -9, 0,
+ -3, 15, -1, 8, 11, -15, 10, 13, 1, 22, -5, 15, 1, 24, 6, 0,
+ -6, 5, 5, 10, 8, -1, -11, -14, 3, -31, 2, -22, -4, -8, -15, -2,
+ -31, -12, 6, -7, 5, 2, 3, -4, 19, 3, 4, 7, 7, -8, 31, -6,
+ 26, 1, -2, 2, -3, -10, -4, -4, 9, 3, 12, -16, 16, -9, -1, 5,
+ 4, -7, 13, -17, 0, -11, -13, -22, 1, -9, 4, -7, 7, -10, 5, -1,
+ -6, -3, -21, 7, -10, 18, -3, 1, -7, -11, 11, -8, 12, 20, 3, 13,
+ 16, -1, 3, 13, -3, 23, 16, -3, 15, -14, 12, -6, -8, -28, 0, -33,
+ 4, -11, -12, -13, -21, -17, -16, -5, -12, 16, -7, 15, -6, -5, 3, -9,
+ 21, 17, 13, 14, 11, 21, -12, 31, -18, 7, 12, 8, 9, 7, 1, -3,
+ -7, -14, 17, -35, -10, -2, -18, -8, -10, -20, -22, 2, -10, -3, 1, -1,
+ 4, -5, 11, -20, 11, -6, 27, 7, 18, 8, -1, 2, 3, 11, -9, 5,
+ 5, -7, 29, -6, 20, -21, 23, -15, 19, -19, 2, -22, 11, -26, -7, -10,
+ -30, -1, -3, -6, 15, -22, 16, -7, -9, -2, -7, -5, 11, 17, -13, 2,
+ 8, -5, 6, 27, -6, 12, -6, 4, 15, 3, 14, -3, -12, 11, -2, 6,
+ 5, 4, -6, -12, 0, -32, 2, -22, 22, -12, -5, -7, -11, -7, 6, -1,
+ -3, -3, -16, 2, -1, 0, 0, -7, -2, 1, 12, -4, 5, 20, 1, 16,
+ -2, 14, -1, 19, 8, 29, -8, 7, -14, -2, 3, -13, 8, -40, 22, -18,
+ 2, -14, -8, -11, -8, 12, -21, -1, -10, -12, -6, -4, -14, 6, -19, 7,
+ 14, 1, 11, 11, -11, 25, 1, 14, -5, 31, 0, 22, 4, 1, 3, 6,
+ -3, 4, -2, -20, -7, -26, 1, -12, -7, -10, 2, -1, -5, -7, -8, -10,
+ 6, -7, -6, 10, -17, 6, 3, 15, -8, 15, -7, 12, 1, 9, -4, -2,
+ 10, 9, -1, 10, -4, 9, -8, 17, 0, -13, -7, -2, -11, 3, -2, -15,
+ -4, -11, -5, -9, 1, 8, -10, 8, -8, -6, -18, 21, -19, 26, -19, -1,
+ -11, 10, 4, 12, -10, 16, -10, 17, 8, 13, -1, 17, 1, 5, -1, 11,
+ -8, 9, 16, -17, 3, -26, -17, -14, 6, -17, 4, -20, 0, -1, -6, -4,
+ 2, -15, 13, -3, -1, 0, -2, -8, 11, 7, -3, -8, 5, 14, -1, 28,
+ -19, 13, -4, 8, 1, 11, 7, 6, -8, -2, -13, -10, -22, 6, 11, -1,
+ -1, -5, -13, 18, 3, -10, 9, -17, -8, 9, -9, 1, -17, -4, -16, 18,
+ -6, 15, -10, 17, 5, 0, -5, 0, -11, 12, 15, 4, 8, 5, -4, 0,
+ -2, 3, -17, -2, -1, 11, -6, -7, 2, -33, 23, -6, -1, -2, -2, -1,
+ -8, 3, -29, -2, -34, 16, -3, 16, 1, 10, -12, 23, 0, -3, 16, 12,
+ 19, 23, -1, 8, -26, 16, -32, 26, -13, 2, -11, 5, -1, -15, -9, -16,
+ 7, -6, 14, -15, 5, -10, -7, -9, -9, 6, -17, 13, 18, -5, -3, -4,
+ -4, -18, 28, -6, 13, 17, 24, -2, 9, -14, 1, -11, 7, 17, 1, -15,
+ 10, -23, -4, -12, 5, -20, 17, -10, 6, 0, -9, 4, -8, -15, 6, -16,
+ 7, 9, 3, 6, -12, -17, 0, 4, 13, 22, -4, 10, -8, 7, -12, 5,
+ 5, 1, 11, 2, 10, -3, -2, 3, -10, -5, -7, -4, -18, 17, -2, -14,
+ -16, -7, -10, -3, 6, -1, 14, -11, 15, -18, 2, -6, 0, -1, 0, 20,
+ -17, 1, 6, 2, 6, 12, -3, 7, 25, -5, 17, -14, 0, -6, 0, -2,
+ -5, -1, -10, 8, 2, -9, -19, -7, -17, 5, 3, -7, 4, -15, -5, 9,
+ -12, -1, -5, 3, -5, 26, -2, 3, -4, 5, 3, 7, 10, 5, 6, 6,
+ 26, -17, 0, -1, 3, -3, 10, -7, -7, -9, 11, -18, 0, -16, -6, -5,
+ 3, 7, -14, -14, 0, -21, 14, -8, -1, -12, 2, 1, 2, -3, -1, -3,
+ 18, 5, 5, 9, 12, 7, 18, 8, 5, -25, 16, -15, 16, -7, 9, -22,
+ 1, 14, -13, -5, 2, -6, -8, 13, -17, 6, -16, 1, -5, -14, -6, -6,
+ -15, -2, 9, -9, -18, 15, -19, 12, 7, 4, 8, 14, 15, 6, 10, -3,
+ 9, -7, 23, -17, 21, -20, 7, 0, -9, 8, -10, 1, 4, 2, 3, -9,
+ -9, -15, -6, -21, -16, -6, 0, -11, 19, -8, -9, 5, -6, 0, 5, 14,
+ 7, 1, 12, 8, 7, -5, 12, 8, -4, 19, 4, -7, 2, 3, -12, -8,
+ -1, 0, 5, 7, -5, -8, -22, -8, -21, -2, -9, 10, -20, 13, -6, 8,
+ -17, -9, -6, 2, 5, 8, 6, -3, 10, -9, -2, 15, -6, 20, 7, 11,
+ 10, -3, -4, -8, 25, -25, 18, -12, 17, -6, 20, -22, -1, -17, -10, 5,
+ -10, 9, -13, -9, -6, 10, -25, -5, -2, -5, 13, 2, -5, -8, -10, 11,
+ -27, 10, -4, 11, 0, 33, -4, 10, -14, 1, 12, -2, 27, -8, 6, 11,
+ 9, -12, -4, -10, -13, 12, 5, 1, -10, -14, -15, -8, -7, -9, 3, -5,
+ 10, 3, -11, -12, -13, -3, -3, 3, 2, 9, 17, -6, 25, -3, -3, -8,
+ 19, 3, 30, -10, 12, -22, 7, -5, -10, -3, 21, -8, 12, 6, -5, -13,
+ -13, -9, -9, -1, -23, 13, -17, 15, -22, -11, -18, 8, -14, 20, 1, 4,
+ -5, 3, 3, 5, 11, 1, 2, 27, 1, 10, -7, -8, -2, -2, 7, -1,
+ 17, -5, 24, -7, 5, -10, -20, -6, 5, -4, -5, -1, -18, -5, -14, -1,
+ -20, 1, 7, -7, 12, -4, -2, -4, 2, 8, 0, 7, 1, 6, -2, 18,
+ -5, -7, 4, 3, -2, 13, 4, 0, 2, -3, 2, -10, -6, 1, -6, 6,
+ -7, -3, -21, -2, -12, 5, -1, -9, 7, -3, 13, 5, 5, -8, 0, -8,
+ 19, -5, 13, 13, -7, 3, 0, -10, 0, -8, 20, -8, 13, -20, -5, -7,
+ 3, 5, -7, 2, -5, -4, -14, 11, -23, -13, 2, -1, 12, 13, 5, -6,
+ 23, -9, 9, -6, -9, 18, -13, 16, -3, -7, -17, 3, -13, 12, -9, 4,
+ 0, 0, 13, -18, -1, 3, -13, 20, -5, 1, -20, 15, -23, 18, -4, -8,
+ 5, -7, 16, 4, 6, -3, 7, -21, 19, -17, -7, 9, 5, 3, -5, -3,
+ -16, -9, 25, -9, 12, -5, 10, -5, 9, -4, -6, -3, 4, 10, -2, 11,
+ -12, -2, -14, 8, -23, -5, 0, -8, 9, -2, -11, -3, -9, 9, 2, 2,
+ 4, -5, 7, 11, -16, 0, -6, 7, 6, 25, 5, 6, -4, 3, 4, 3,
+ 2, -8, -3, 5, -1, -11, -4, -9, -3, -15, 10, -12, -5, 11, -4, -7,
+ 6, -29, -5, 6, 11, 3, 9, -18, 13, -14, 19, -1, -2, 4, 5, 12,
+ 1, 5, -8, 3, 1, 20, -6, 2, 3, -16, 10, -10, -18, -11, -7, -7,
+ 9, -4, -8, 9, -15, 13, -13, -3, -7, 3, 8, 11, -6, -16, 1, -8,
+ 20, 4, 15, -5, -3, 11, -5, 6, 0, -5, 10, 13, 0, -6, -11, 0,
+ 11, -11, 10, -7, -8, 1, 16, -9, 2, -22, -9, 0, 4, 5, -12, -22,
+ 2, -8, -8, 14, -16, 0, 13, 0, 9, -7, 2, -1, 7, 8, -3, -3,
+ 2, 15, 5, 10, -7, 12, -4, 22, -4, -3, -12, -2, -15, 8, -2, -22,
+ 7, -10, 5, 12, -20, -9, -11, -2, -12, 2, -9, 5, -3, 11, 7, -9,
+ 4, -4, 24, -7, 21, -15, -3, 2, 14, -1, 5, 18, -12, 13, 3, 5,
+ -10, -11, 0, -8, -2, -4, 2, -15, 9, -10, -16, -9, -7, 0, -1, 3,
+ -8, -10, 5, -8, 4, -3, 8, -2, 20, 1, 6, -4, -9, 4, 14, 7,
+ -1, 3, -5, 18, -7, 20, -6, -10, 8, 1, -2, 3, -4, -5, -3, -6,
+ 0, -16, -7, 12, 0, -17, 4, -31, -7, 1, 1, -4, 8, -11, 6, -1,
+ 11, -5, -7, -4, 2, 4, 15, -3, 21, -5, 20, 3, -12, 21, -1, 10,
+ 5, 6, -20, -1, -18, 2, 3, -4, -5, -1, 6, -2, -11, -17, -15, -13,
+ 0, 6, -18, 7, -18, 7, -7, 6, 7, -10, 18, 16, 2, -1, 3, -11,
+ 6, 14, 1, 15, -2, 29, -8, 17, -14, 2, -19, 12, 8, -6, -1, -23,
+ 6, -11, 7, -19, -18, 0, 1, -8, -8, -4, -20, 8, -8, 4, 10, -12,
+ 13, 0, 18, -10, -3, -4, 6, 4, 17, 7, -2, 18, -9, 14, -10, -4,
+ -11, 4, 3, 23, -17, -6, -2, -7, -7, 9, -10, 1, 2, -4, -14, -7,
+ -6, -8, -4, 7, 2, -3, 3, 0, 13, -10, -4, -9, -6, 18, 11, -4,
+ 16, -8, -4, 1, -1, 7, 3, 3, 3, 10, -15, -2, -9, 9, 0, 2,
+ 2, -9, 12, -7, 0, -23, -7, -19, 2, -1, 0, 4, -15, 7, 3, -3,
+ 0, 9, -12, 19, 4, 8, -13, -6, 5, -1, 14, 10, 9, 13, -3, 16,
+ -18, 13, -18, 7, -10, 13, -6, -11, -3, 7, -23, -6, -11, -21, 9, -1,
+ 4, -3, -16, 0, -12, 7, 14, -5, 15, 0, 6, -5, -3, -9, 9, 4,
+ 10, 4, -2, -7, 10, -1, 10, -6, -14, 15, -4, 13, -4, -4, -14, 5,
+ -2, 4, -9, 3, -14, 2, 3, -10, -1, -9, 0, 3, -6, 12, -16, 0,
+ 4, 10, -25, 6, -5, 2, 8, 3, -2, -4, 15, 4, 7, 2, -1, -6,
+ 10, 11, 2, -2, -14, 6, -3, 0, -3, -9, -10, 1, -1, -15, 9, -29,
+ 9, -10, 7, -3, -3, -10, -2, 14, 4, -6, 0, 1, 12, 4, 18, -15,
+ 19, 1, 15, 1, 1, 3, -10, 8, -1, 7, -30, 8, -19, -2, -5, -9,
+ -10, 0, -1, 6, -4, -12, 1, -18, 10, -1, -12, 2, 7, 12, 11, 0,
+ -4, -1, 6, 10, 17, -8, 1, -12, 5, -2, 1, -7, -1, 4, 3, -3,
+ -1, -18, 8, -9, 0, -2, 8, -12, 12, 7, -5, -2, -16, -7, 9, -5,
+ 11, -9, -4, 3, 1, -9, -1, -2, -6, 7, 12, 0, -8, 9, -10, 3,
+ 0, 2, -3, 11, 14, 4, 3, -12, 3, -3, 2, 12, -4, -2, -2, 9,
+ -21, -5, -28, -6, -10, 6, 7, -6, -3, -24, 7, -11, 10, 0, 8, 13,
+ 10, 6, -7, -2, -5, 7, -1, 9, 18, -2, 12, -4, 7, -26, 13, -6,
+ 19, 6, 6, -5, -16, -6, -8, -18, -2, 1, -11, 3, 4, -16, -8, -10,
+ -3, 2, -3, 5, 5, 0, 11, 0, -14, 0, 1, 14, 11, 13, 0, -2,
+ 5, -1, -4, -2, -4, 5, 21, 3, 14, -5, -22, 5, -11, -3, -6, -3,
+ -11, 0, -5, -13, -10, -18, 3, 9, -10, 2, 3, -11, 11, -11, 5, -19,
+ 23, -1, 20, 18, 4, -3, -6, 9, 4, -3, 8, 4, 6, 2, 5, -14,
+ -6, -3, 2, -6, -4, -3, -11, 0, -5, 0, -21, -2, -10, 11, 5, -4,
+ -5, -5, -8, 10, -10, 4, -1, 6, 12, 9, 2, 8, -20, 8, -2, 11,
+ -11, 1, -4, 5, 6, -6, 6, -14, 14, 4, -2, 12, -3, -10, 8, -5,
+ -15, -9, -1, 5, 8, -3, 0, -23, -9, -11, 4, -12, 3, -4, 4, 1,
+ 15, -12, 3, 13, 2, 5, 8, -8, 7, 11, -3, 17, -11, 5, 3, 19,
+ 13, 3, -11, -11, -2, -9, -7, -4, -24, -1, -17, -3, -17, 0, -15, 2,
+ -1, -5, -4, 3, 2, 2, 11, -4, 3, -6, 11, 8, 3, 6, 3, 7,
+ 7, 6, -6, 2, 0, 14, 14, 3, 8, -6, 4, -3, 6, -13, -2, -9,
+ -4, 5, -13, -5, -21, -1, -6, -1, -5, -14, 8, -7, 5, -7, -17, -11,
+ 7, 3, 20, 7, 1, -3, 4, 5, 14, -3, 5, 3, 10, 8, 6, -6,
+ -2, 6, 3, 7, -6, -3, -3, -6, -1, -27, -11, -17, 0, 11, 7, 1,
+ -7, -9, -13, 5, -11, 0, -10, 15, 2, 5, -2, -5, 1, 6, 6, -6,
+ -5, 6, 2, 5, 3, 10, -16, 11, 8, 18, 3, 13, -11, 7, 5, -7,
+ -6, -20, 15, -1, 10, -1, -13, -17, -11, -3, -13, -4, -14, -3, -2, -6,
+ 6, -28, 9, -8, 10, 0, 12, -2, 10, 9, 1, 3, -6, 5, 17, 24,
+ 18, 3, 4, -9, -4, 2, -8, -4, -2, -11, 1, -8, -12, -9, -10, 5,
+ 0, -7, -9, 7, -18, 6, -10, -12, -1, -1, 13, 1, 18, 2, -3, 4,
+ 3, 3, -3, 3, 10, 9, 7, 5, -8, -7, 0, 3, -7, 7, -2, -2,
+ 5, -10, 2, -5, -3, -1, 4, 1, -2, -10, 4, -9, -5, -12, -18, 3,
+ 6, -3, 3, -15, -1, -13, 6, -2, 8, 0, 8, 16, -2, 17, -4, 8,
+ 3, 23, -1, 11, -8, 10, -4, -5, -3, -13, -2, -1, -2, 2, -9, -13,
+ -13, -2, -11, -2, -20, -5, 0, 3, 2, -1, -10, 1, 8, 3, 9, 6,
+ 4, -3, 13, 3, 4, 11, 2, 11, 8, -2, -1, -2, -2, -2, -1, -21,
+ -1, -14, 8, 6, -8, -10, 2, -16, 4, -3, -1, -10, 7, -1, 4, -4,
+ -12, 3, -2, 13, 2, -3, -9, -2, 6, -7, 8, -8, -5, 12, 7, 8,
+ -3, 6, -1, 16, 0, 7, -8, 3, -7, -1, 0, -6, -4, -8, 6, -1,
+ 4, -19, 2, -3, -8, -3, -12, 4, -6, 2, -7, 1, -13, 2, 9, -1,
+ 17, -19, 3, -3, 23, 9, 6, 3, 6, 6, -5, 11, -11, 1, 0, -5,
+ 6, -6, -4, -5, -7, 3, -4, -14, -9, -7, -1, 5, -11, 4, -19, 14,
+ -4, 3, 4, 2, 0, 9, -2, -3, 2, -2, 10, 15, -3, 14, -6, -4,
+ 6, 1, -8, 11, -9, 4, 3, -9, 2, 2, -2, 2, -2, -9, -2, -2,
+ 1, -6, -6, -22, -16, -10, 12, 0, 5, -8, -2, -4, -2, 5, -1, 7,
+ 7, 9, 1, 7, 6, -1, 10, 11, 5, -3, 8, 1, -1, 8, -15, -6,
+ -10, 12, 0, 2, -5, -9, -12, -7, -4, -14, -4, 0, -1, 5, -7, -8,
+ -12, 0, 2, 16, -3, 11, -4, 16, 11, 2, -3, 2, 8, -1, 7, -13,
+ 4, -3, -1, 3, -10, -2, -11, 3, 2, 3, -7, -10, -5, -10, 12, -8,
+ 5, -7, 15, 1, -10, 7, -16, 1, 3, 4, -5, 7, -7, 4, -2, -1,
+ -8, 0, -2, 17, 10, -2, 6, -5, 3, 10, -7, 2, -3, 4, 5, 5,
+ -3, -8, -8, -1, 1, 7, -5, -11, -2, -10, -4, -15, -7, -10, -2, 2,
+ -4, -10, -8, 0, 2, 6, 3, 2, 3, 10, 14, 8, 7, 3, 5, -5,
+ 20, -6, -1, -2, 0, 1, -2, -2, -8, 3, -3, 10, -14, 3, -3, -2,
+ 0, -5, 0, -15, 4, -2, 0, 4, -7, 3, -8, 7, -14, -2, -6, 4,
+ 2, 3, -10, -2, 5, -3, 12, -2, -5, -9, 1, 4, 1, 11, -12, 15,
+ 5, 20, 10, -5, 1, 5, 3, -13, 6, -16, 5, 1, -5, -8, -3, -14,
+ -6, -2, -5, -8, -17, -9, 3, -6, -2, -3, -3, 1, 14, 2, 4, 5,
+ 3, 8, 7, 12, 0, 11, 4, 16, 2, -3, -9, -1, 1, -1, -3, -6,
+ -14, 4, -6, 2, -14, -9, -11, -1, 0, 0, -5, -6, -10, 5, -5, 2,
+ -3, 2, 2, 17, -2, -1, -3, 3, 11, 1, 10, 2, 7, 6, 5, -5,
+ -3, -3, -2, 7, 2, 1, -18, -5, -2, -3, -5, 0, -2, 0, 8, -9,
+ -10, -15, -7, -2, -1, 6, -8, 16, -10, 13, -4, 2, -4, 4, 7, 9,
+ 6, -5, -2, 8, -1, 11, -6, -1, 5, 8, 0, 9, -20, 0, -9, 4,
+ -3, 1, -4, -11, 2, -6, 0, -12, 0, 1, 5, -2, 1, -7, -4, 3,
+ -1, -10, 3, -3, 7, 4, 8, -9, -6, -10, 0, 0, 2, -4, 6, 9,
+ 10, 2, 0, -1, 2, 14, 3, 7, -7, 2, -2, -2, -6, -9, 2, -3,
+ 6, -3, -7, -9, -10, -2, 2, -1, -11, 2, 1, 7, -4, -7, -19, 3,
+ -1, 6, 6, 6, 6, 0, 6, 7, 3, -1, 3, 8, 3, 4, -10, -5,
+ -7, 5, -4, -14, 2, -8, 5, -2, 2, -16, -4, -11, 2, 4, -1, 2,
+ -1, 0, 5, 4, -12, 3, 9, 7, 13, -3, -7, 2, 6, -1, 7, -1,
+ -1, 5, -5, 7, -11, -9, -13, 2, 5, 2, -2, -7, 5, 4, -4, -2,
+ -15, -4, 3, 0, 0, -5, 2, -7, -1, 9, -2, -1, 5, 1, 1, -4,
+ -5, -4, 6, 8, 7, -5, 4, -7, 4, 0, 1, -6, -5, -2, 5, -1,
+ 0, 1, 1, 3, 9, -4, -2, -4, -9, -1, 4, -17, 1, -13, 11, -1,
+ 6, -9, -1, 5, 1, 8, -3, 4, -5, 1, 7, -5, 1, -3, 5, 3,
+ 4, -7, -11, -7, 1, 5, -13, 11, -11, 1, 3, 6, -9, 6, -5, -7,
+ 4, -13, 5, -7, 10, 5, 6, -15, -1, 6, 4, 18, -7, -7, -3, -4,
+ 2, -5, 3, -4, 9, -4, 3, 3, -3, -10, 0, -1, 2, 5, -3, 7,
+ 3, 2, -6, -11, -2, -1, 4, -5, 4, -5, 0, -5, 5, -5, -4, 2,
+ 4, 2, 5, -8, -13, -3, 0, -1, -2, 4, 6, 9, 1, 3, -7, -1,
+ 1, 12, 1, 1, -1, -5, -1, 2, -8, -9, -7, -2, 3, 10, -6, -7,
+ -12, -7, -4, -5, 6, 0, 10, 5, 7, -4, -2, -8, 10, 5, 9, 4,
+ -1, -1, -1, -1, -1, -2, -3, 3, 9, -2, 9, -14, -13, -8, -10, 1,
+ 1, 3, 3, 1, -3, -12, -5, -7, 1, 6, 6, -2, -7, -3, -3, 2,
+ 2, 4, -9, 14, 8, 11, -3, 5, -11, 1, -1, 5, 3, 8, 2, 8,
+ -2, -6, -13, -10, 0, 4, 3, 4, -3, -9, 1, -5, -5, -6, 1, -2,
+ 2, -10, -6, -15, 1, -5, 4, -1, 2, 2, 4, 10, 4, 2, -13, 0,
+ 4, 8, 17, 2, 5, 4, 2, -6, 5, -5, 0, 8, -2, -1, -5, -4,
+ -5, -1, -5, -4, -5, 0, 0, 1, -9, -15, -3, -12, 1, -1, -7, 10,
+ 2, 5, -1, 2, -6, 2, 2, 10, 10, -1, 2, -2, 4, 5, 0, -6,
+ 12, 5, 3, -1, -8, -8, -4, -4, 3, -11, 0, -1, -1, 0, -2, -14,
+ -6, -9, 2, 1, 7, -4, 3, -1, 0, -3, 1, 2, 7, 5, 4, 3,
+ -2, -3, 1, 6, -1, 6, -11, 7, 2, -6, 2, -4, 0, 2, 3, -7,
+ -9, 3, 0, 4, -6, 0, -21, 0, -5, -1, 0, -1, 1, -6, -1, -1,
+ 0, -7, 5, 7, -2, 8, -4, -1, 3, 9, -6, 10, -6, 7, 9, 10,
+ 9, -6, 5, -14, 6, -5, 1, 2, -3, 0, -9, -10, -14, -2, -3, 6,
+ -8, -15, 3, -9, 0, -3, 0, -6, -1, 3, 9, 10, 3, 3, -10, 6,
+ 1, 3, -1, 9, 12, 4, 4, -9, -7, -5, 8, 6, 1, 1, -4, -5,
+ -5, -1, -11, -3, -4, 1, -1, 1, -10, -7, -2, -3, -4, -3, -6, 11,
+ 5, 3, 2, -8, -5, -2, 3, 9, 13, 5, 4, 4, 0, -5, -1, -5,
+ 9, 2, 3, -9, -4, 3, -6, 2, 1, -9, 5, -2, 3, -2, -9, -8,
+ -15, -5, -3, 3, -13, 11, 6, -3, 1, -6, -6, -1, 6, 4, 6, 7,
+ 1, 5, 0, 8, -6, 7, 2, 6, 2, -5, 0, -3, -1, 3, -7, -1,
+ -3, 5, 7, 6, -18, -10, -11, -7, -3, 10, -4, 3, -4, -8, -5, -12,
+ -3, -4, 12, 10, 2, -4, 6, 3, 1, 2, 0, -3, 3, 7, 7, -5,
+ 2, -4, 1, 3, 11, 2, 3, 4, -2, -7, -5, -17, -11, 4, -3, 5,
+ -7, -7, -6, -1, -8, -5, -5, 1, 7, 1, 2, -1, -9, 7, 1, 7,
+ 3, 3, 6, 9, 6, 1, -6, -4, 2, 5, 7, 4, -2, 1, 3, -11,
+ -1, -16, -2, -6, 1, 3, -8, -15, -11, 4, -1, 9, -2, -5, 0, 6,
+ 0, -7, 0, -8, 4, 2, 6, 2, 0, 2, 6, 2, -2, 4, -2, 4,
+ 14, 2, 2, -6, -6, -3, 4, -4, -1, -4, 1, -3, -6, -1, -13, -1,
+ -2, 7, -8, -7, -10, 0, 4, 3, -8, -3, 1, 4, 6, 4, 6, -3,
+ 5, 3, 4, 0, 6, 1, 4, 7, -3, -10, 8, -1, 9, -1, 1, -11,
+ -7, -3, -3, -6, -8, -9, -6, 1, -3, -6, -6, -5, 0, 0, 2, -3,
+ 0, 6, 4, 3, 2, 7, 4, 11, 14, 5, -1, -5, 1, -2, 7, 3,
+ 0, 1, 2, -5, -7, -10, -12, -10, -5, -5, -6, -6, -9, 1, -8, -2,
+ -1, -9, 1, 8, 2, -5, -2, -5, 0, 5, 6, 6, 7, 8, 10, 2,
+ 0, -3, -1, 2, 13, 3, 0, -6, 0, 1, -3, 0, -12, -2, 4, -4,
+ 4, -8, -11, -1, -2, 1, -1, 2, -12, 3, -6, 1, -12, -7, -7, 3,
+ 0, 9, 0, 1, 6, 1, -1, 2, 1, 2, 8, 9, -3, -1, 0, 7,
+ 3, 8, -1, -4, -1, 1, 3, -9, -1, -17, -3, -2, -4, -4, -3, -4,
+ -6, -11, -15, -2, -5, 6, 10, 1, 3, -1, -3, 13, 7, 1, 6, 4,
+ 4, 9, 5, -3, -5, 9, 3, 5, -3, 1, -3, 3, 0, -7, -5, -7,
+ 0, -5, 0, -1, -15, -11, -4, -5, -10, 2, -7, 5, -4, 1, -9, 2,
+ 1, 8, 7, 10, 2, 2, 0, 4, 3, -2, 0, 4, 2, 6, 8, -2,
+ 4, 4, -2, 5, -3, -6, 3, -3, -5, -9, -8, -11, -5, -1, -1, -5,
+ -7, -5, -8, 0, -3, 5, -7, 11, 1, 0, 2, -3, -1, 3, 9, 6,
+ -3, 8, 1, 11, 2, 8, -3, -3, 6, 2, 1, 2, -7, -3, -2, -4,
+ -8, -3, -3, 5, -10, -10, -4, -12, -2, 3, -5, 3, -6, -8, -2, 5,
+ -3, 0, 1, 4, 8, 4, 5, 0, 4, 8, 1, 7, -3, 0, 3, 4,
+ 4, -5, -2, -7, -3, 0, 5, -5, -9, 3, -2, -1, -2, -5, -1, -4,
+ -3, -11, -4, -5, -6, 0, 5, 0, -5, 5, 3, 8, -1, 3, 3, 2,
+ 5, 7, -4, 3, 1, 3, 10, 2, -7, 1, 0, 6, -4, -3, -5, -7,
+ -2, -4, -3, -6, 0, -10, 4, -6, -4, -7, -2, 1, -4, -1, -3, -1,
+ 2, 6, 2, 4, -2, 2, 4, 2, 5, -3, 4, 2, 1, 0, 8, -3,
+ 2, 5, -5, 3, -5, -2, 5, -5, 3, -1, -4, -3, 4, -10, -5, -7,
+ -4, -4, 0, 0, -7, -1, -1, 2, 1, -2, -12, -4, -1, 0, 4, -5,
+ 2, 0, 3, 12, 11, 3, 11, -1, -3, 6, -6, 1, 1, 7, 6, -7,
+ -1, -7, -4, -4, -7, -8, -1, -6, -6, -2, -3, -5, 0, -4, 8, -7,
+ 1, 4, -3, 6, 1, -7, 3, 5, 6, 5, 13, 2, 2, -4, 4, -3,
+ 1, 4, -4, 2, -3, -10, -10, -7, -2, -2, -2, 0, -6, -2, 1, -3,
+ -4, -2, -5, -2, 7, 1, 6, -5, 6, -1, -1, 2, -3, 4, 11, 2,
+ -1, 2, -7, -5, 8, 0, 3, -3, -5, -1, -2, 3, 1, -4, 4, 7,
+ 0, 2, 3, -3, 0, 1, -5, -15, -5, -3, 1, 3, -3, -11, -4, -7,
+ 1, -2, -1, -1, 0, 1, 1, -5, -1, 3, -2, 7, 1, -4, -1, 0,
+ 4, 5, 3, 3, -1, 8, 11, 1, 4, 1, -5, 7, -6, -4, -2, -4,
+ -2, 3, -8, -3, -13, -6, 3, -3, -7, -4, -7, 3, 3, -3, 2, -1,
+ 1, -4, -2, -2, -5, 1, 11, 9, -2, 6, -3, 7, 7, 1, 1, -7,
+ 2, -3, 1, 4, -4, -4, 5, 1, 0, -3, -6, 2, -3, 0, -8, -12,
+ -6, -2, -3, 6, -1, -9, 0, -1, 1, 3, -2, -1, 0, 1, 6, 0,
+ -3, 5, 1, 6, 1, -1, 4, 1, 7, -3, -1, -1, -4, 4, 14, -1,
+ -1, 2, -4, -1, -6, -8, -8, -3, -2, 2, -9, -5, -7, -12, 5, 0,
+ -3, -4, -3, 5, 4, 3, -2, -6, 4, 7, 3, 5, 7, -3, 8, 0,
+ -5, -1, -1, 11, 10, 3, 4, -8, -3, -3, 1, -3, 0, -4, -3, 1,
+ -7, -8, -16, -7, -6, -2, 3, -7, -2, 1, -4, 0, -5, -5, 1, 5,
+ 10, 5, 0, 3, 0, 1, 13, 0, 5, 9, 6, 8, -1, -4, 0, -3,
+ 6, 4, -4, 0, -3, -15, -2, -12, -15, -3, -6, 2, 1, -3, -4, -9,
+ -9, -3, -3, -2, 3, 4, 9, 0, 2, 1, 2, 14, 5, 3, 8, 2,
+ 7, 4, -4, -4, -1, -9, 9, -5, -1, -7, -10, -2, -7, -4, 0, -5,
+ 2, 5, 1, 0, -5, -5, -1, -1, -3, 4, -8, 5, 3, -4, 4, -5,
+ -3, 9, 4, 8, 0, 0, 2, 0, -2, 0, -2, -7, 12, -1, 5, -4,
+ 2, -3, 0, 2, -2, -4, -2, 2, -5, 3, -7, -9, -4, -3, -2, -6,
+ -6, -2, -6, -1, -7, -8, 1, 3, 6, 10, 4, 5, 0, 5, 8, 1,
+ 3, 8, 5, 11, 12, -7, 4, 0, -3, 2, -1, -8, -7, -4, -2, -6,
+ -9, -6, -13, -4, -1, 0, -9, -5, -3, -4, -2, 3, 1, 1, 9, 4,
+ 2, 6, -1, 3, 6, 2, 0, -3, 3, 2, 6, 3, -1, -4, 4, 1,
+ 2, 2, -5, -8, -1, -3, -1, -9, -4, 1, -5, 5, -7, -4, 0, 3,
+ -10, 3, -3, -5, 1, 5, 4, 1, -5, 1, -5, 4, 1, -6, 0, 5,
+ 8, 8, 1, 6, 0, 3, 4, 2, -3, 1, -3, -3, 3, -10, -6, -8,
+ -2, -1, -3, -6, -6, -5, -6, -6, -5, 5, -3, 5, 6, -2, -1, -1,
+ -4, 6, -2, 6, 6, 2, 12, 8, -2, 3, -6, -2, 5, 4, -3, -2,
+ -5, -4, -7, -6, 1, -5, 2, 2, 0, 1, -7, 0, -4, -2, -1, -2,
+ -5, 7, -5, -2, -3, -2, -3, 4, 4, 9, 0, 1, 1, -5, -3, -4,
+ -4, 4, 3, 6, 1, -2, -2, -7, 4, 1, 1, -3, 3, -1, 2, 0,
+ -7, 0, 0, -1, -3, -2, -1, -5, -2, -3, -8, -5, -5, -1, 5, 5,
+ 2, 2, -3, 4, 3, 4, 6, 3, -1, 10, -4, -3, -2, -3, 0, -4,
+ 0, -2, -2, 0, 2, -5, -2, -5, -9, 8, -2, -1, -1, -3, -3, -2,
+ -6, 2, 1, 2, 9, 0, 1, 4, -5, 2, 4, -6, -1, 2, -1, 6,
+ 3, 0, -5, -3, -1, 0, 3, -3, 0, -6, -2, -3, -4, -2, 0, 3,
+ 2, 2, 0, -10, 1, -6, -5, -1, -2, 5, 3, 6, -2, -6, -1, -3,
+ 2, 4, 1, -1, 0, 1, 1, 3, -1, 5, -1, 7, 6, 1, -2, 0,
+ -6, -2, -2, -8, -2, -2, -3, -5, -5, -8, -3, -1, 5, -3, 1, 2,
+ 1, 2, -3, -2, -3, 2, 6, 2, 6, 0, 0, -2, 9, -1, 3, -2,
+ 3, 0, 0, 0, -6, -6, -1, -5, -7, 1, -3, -6, 2, -2, -1, -5,
+ -2, 1, 4, 2, 2, -3, -1, 6, -2, 2, 4, -3, 2, 2, 2, -3,
+ 1, 0, -4, 2, -1, -2, 3, 1, 1, -1, -5, -8, -2, -5, 0, 1,
+ -6, 3, -4, 2, 3, -6, 3, 0, 2, -2, -1, -4, -2, -4, 4, 0,
+ -3, 0, -6, -3, 10, -3, 3, 0, 4, 7, 3, 0, 5, 1, 5, 1,
+ -3, -2, 0, -6, 3, -1, -7, -5, -7, -1, -2, -2, -2, -3, -2, 2,
+ -2, -1, -3, -3, 2, -2, -6, -3, -3, 4, 3, 2, 0, -1, 5, 5,
+ 8, 2, 2, -2, 4, 0, 5, -5, -3, -1, -3, -3, -6, -4, -2, 3,
+ 0, -2, -2, -5, 5, -1, 3, -1, -1, -3, 0, 0, -5, -4, -3, -2,
+ 5, 0, -4, -4, 1, 2, 6, 0, -3, -1, 2, 3, 7, -3, 0, -4,
+ -2, 4, 3, 0, 1, 3, -3, 1, -7, -4, 0, 1, 1, -4, -4, -4,
+ -9, -1, -2, -3, -2, -3, -3, 4, 3, -1, -4, 2, 4, 4, 3, 2,
+ -1, 0, 9, -1, 4, 2, 7, -1, 6, -2, -2, -5, -1, -9, -2, -2,
+ -6, -1, -1, 1, -8, -6, -5, -1, -1, 1, -4, -5, 3, 1, 5, 3,
+ -3, 0, -2, 7, 0, 1, -2, 3, -1, 5, -1, -5, 7, -1, 3, 2,
+ -5, -6, -2, 4, 2, -1, -3, -1, -1, -1, -1, -2, -4, 1, -5, 3,
+ -1, -3, -5, 2, 6, -6, -1, -5, -4, 4, -1, -1, -2, -1, 2, 0,
+ 3, 1, 4, 2, 7, -1, 2, 0, -2, 1, 4, -5, -3, -7, -2, 0,
+ -1, -1, -3, 0, 0, -2, -6, 2, -4, 2, -4, 1, -7, -2, -1, 5,
+ 3, -2, -7, -4, 1, 6, 4, 5, 1, 4, 0, 5, 1, -1, 2, 0,
+ -3, -3, -5, -6, 3, -1, 5, -1, -2, 1, 1, 4, 2, -6, -3, -4,
+ -3, 2, -2, -8, -3, -6, -4, -2, -11, 0, 0, 1, 6, -3, -2, 1,
+ 2, 10, 8, 4, -2, -1, 2, 2, 1, -2, 3, 1, 5, 3, -1, 0,
+ -4, 4, -7, -2, -7, -8, -4, -3, -2, -7, -7, -3, -1, 5, -2, 0,
+ -7, 2, -1, 3, 1, 4, 6, 5, 8, 3, 2, -1, 3, -3, 0, 0,
+ -5, -1, 1, 1, -5, -3, -2, 6, 4, 5, -4, -8, -4, -3, -2, -5,
+ -4, -4, -4, 2, -3, -2, -4, -4, -4, 6, 1, 0, 1, 3, 3, 5,
+ 2, 1, 0, 6, 2, -1, 1, -3, -3, 2, -1, 0, 1, 3, 1, 4,
+ -4, -5, -10, -8, 1, -6, -3, -4, -6, -3, 0, 2, -3, -1, 2, 0,
+ 8, 1, 4, 4, 3, 6, 3, 1, 3, 5, 1, 2, -4, -7, -3, -3,
+ 3, 0, -7, -5, 0, -3, -1, -2, -4, 0, -5, 1, -6, -1, -5, -3,
+ 1, 4, -1, -3, 3, 3, 5, -1, -2, 2, -1, 2, 1, -1, -5, 5,
+ 1, 2, 2, -4, 0, -1, 3, 0, -2, -1, 2, 1, 5, 4, -3, -5,
+ 0, -2, -2, -6, -3, -3, -4, -1, -5, -4, -1, -2, 0, 2, -2, -6,
+ -3, 1, 1, 1, -1, 3, 4, 7, 2, 3, 4, -1, 7, 2, 3, 1,
+ -1, 1, -2, 0, -4, -5, -6, 0, -2, -7, -2, -5, -5, 1, -4, -5,
+ -5, 3, -1, 1, 2, -2, 0, 1, 4, 1, -4, 2, 2, 0, 9, 2,
+ 0, 4, 3, 1, 2, -4, -2, -4, 3, -4, -2, -6, 0, -1, 5, 2,
+ -4, 0, -4, -4, -1, -5, -4, -7, -3, 1, 0, -2, -1, -5, 1, 0,
+ -1, 0, 2, 4, 0, 3, -2, 1, 2, 6, 0, 1, 5, 0, 3, 3,
+ 2, -5, -2, 1, 5, 2, -2, -5, -9, 0, -6, -1, -6, -7, -5, -4,
+ 0, -2, -5, -3, 2, -2, 3, 2, 0, 9, 2, 0, 4, -3, 4, 5,
+ 8, 6, -2, -4, -1, 0, -2, -2, 1, -5, 2, -5, -1, -4, -3, -4,
+ 0, -2, -7, -3, -1, 0, -1, 0, -6, 3, -2, 5, 2, -1, -2, 1,
+ 0, 1, -1, -3, 2, 3, 1, 2, -4, -3, -1, 5, 5, 3, -4, 0,
+ 1, 2, 5, -5, 1, -5, 2, -2, 2, -4, -3, 0, -4, -3, -9, -7,
+ -4, 2, -2, 1, -6, -3, 0, 1, 5, 1, -5, 0, 0, 2, 1, 2,
+ 0, 6, 4, 6, 3, 2, 3, 1, -2, -2, -9, -4, -1, 4, 0, -1,
+ -5, -8, -5, -4, 0, -4, -1, -3, 0, 0, -4, -3, -1, 1, 2, 0,
+ -2, -3, 1, 3, 2, 3, 3, 0, 8, 2, 7, -1, 3, -2, 4, 0,
+ 0, 1, -4, 5, -1, -3, -3, -6, -4, 2, 1, -5, -4, -7, -4, -4,
+ -7, -2, -10, 1, 0, 1, -3, 4, -2, 5, 2, 1, -3, -1, 2, 8,
+ 4, 5, 0, 1, 4, 5, 2, 2, -2, 1, -4, 0, -3, -3, -1, 0,
+ 2, -4, -4, -5, -1, -7, 0, -4, -5, -1, -3, 2, -2, 0, 3, 0,
+ 2, 0, 1, -2, 2, 4, -1, 0, -3, -1, 1, 3, 2, -3, 2, 0,
+ 2, 2, -1, 2, -2, -3, 0, 0, -2, 2, -2, 4, -3, -6, -7, -6,
+ 2, -1, -4, -1, -7, -1, -3, 3, -1, 0, -2, 2, 2, -3, 3, -4,
+ 5, 7, 6, 3, 1, -1, 6, 2, 1, 0, -1, -1, 1, -3, 1, -3,
+ -5, -5, -3, -8, -3, -11, -1, -1, 0, -8, -2, -5, 3, 4, 0, 1,
+ -2, 2, 0, 6, 4, 1, 4, 1, 5, 0, 0, 1, 2, 5, 0, 1,
+ -10, 0, -5, 2, 0, -6, -6, -2, -2, 2, -3, 0, -4, 2, -4, 1,
+ -3, -4, 1, -2, 2, 1, -2, 0, 3, 2, -3, -1, -5, -3, 4, 2,
+ 3, -1, 4, 1, 5, -1, 2, -3, 2, -3, 0, -3, -2, 1, 1, 5,
+ 1, -2, -5, 1, -1, -4, -3, -7, 0, -5, -4, -4, 0, -4, 4, 0,
+ -1, 1, -8, 1, 0, 9, 1, 2, -2, 5, 5, 1, 6, -1, 6, 3,
+ 1, 1, -2, -2, -4, -3, -2, -3, -7, -4, -4, -1, -3, -8, -1, -8,
+ 4, -5, 0, -3, 1, 0, 4, -1, 0, 1, 3, 3, 4, -4, 6, -2,
+ 2, 5, 4, -3, 4, -3, 5, 0, -4, 0, 0, -1, 0, -4, -4, 3,
+ -1, -2, -4, -8, -9, -5, -4, 4, -4, 1, -4, 1, 1, -1, -1, -1,
+ 3, 2, 3, 0, 1, 2, 1, 5, 3, 1, 0, 5, 3, 3, 0, -5,
+ -4, -2, 5, 0, -2, -5, -2, -6, -2, -5, -8, -2, 1, -1, -3, -7,
+ -8, -6, 0, 4, 7, -2, 7, -1, 7, 3, 2, -5, 0, 2, 0, 1,
+ -3, 2, 2, 3, 3, -3, 0, -2, 3, -1, -1, -4, -6, -2, -3, 4,
+ -4, 0, -4, 6, -2, -6, -2, -7, 1, 2, -1, -3, -2, -2, 3, -1,
+ 0, -3, -1, 4, 7, 4, 0, 2, -1, 0, 6, -2, 1, 1, 5, 4,
+ 1, -3, -3, -2, 2, 2, 1, -6, -6, -3, -4, -2, -6, -5, -4, -5,
+ -2, -8, -8, -3, 0, 4, 0, 1, -1, 2, 5, 4, 2, 2, 3, 3,
+ 4, 10, 0, 2, 0, 3, 1, 1, 0, -3, 1, -3, 1, -7, 0, 1,
+ -2, 1, -6, -4, -10, -1, -4, -2, -2, -3, 2, -4, 1, -5, -4, -4,
+ 2, 1, 1, -4, -1, 3, 1, 6, 2, -2, -2, 3, 3, 2, 7, -5,
+ 5, 0, 8, 1, -1, 2, 3, -1, -6, 0, -10, 3, -1, -1, -5, -6,
+ -8, -2, 0, -3, -5, -8, -4, 2, -3, -1, -2, 0, -1, 7, -1, 3,
+ 2, 4, 7, 3, 4, -1, 5, 1, 9, 1, -2, -1, -1, 1, -3, -2,
+ -6, -7, 1, -3, -1, -9, -4, -6, 0, 2, -3, -2, -4, -3, 0, -4,
+ -1, -4, 0, 1, 6, -1, 1, -1, 3, 5, -1, 3, 4, 5, 7, 4,
+ -2, 0, -2, 0, 3, 1, -1, -8, -2, -1, -2, -5, -1, -2, -2, 2,
+ -5, -7, -9, -2, -3, -2, 1, -5, 4, -4, 5, -1, -1, -3, 2, 3,
+ 7, 3, -1, 3, 4, -1, 5, -4, 0, 4, 4, 3, 4, -9, 1, -5,
+ 2, -2, -2, -3, -7, -1, -2, -2, -5, -3, -1, 1, -2, -1, -4, -4,
+ 1, -1, -7, 0, -1, 2, 5, 4, -4, -5, -4, 0, 2, 1, -1, 3,
+ 5, 4, 0, 0, -1, 3, 8, 3, 3, -4, 0, 1, 0, -2, -6, -2,
+ -4, 3, -2, -3, -5, -6, -3, -1, -1, -7, 0, 0, 3, -5, -4, -11,
+ 0, 0, 3, 3, 1, 1, 1, 4, 6, 1, 1, 2, 9, 3, 3, -4,
+ -4, -3, 2, -1, -6, 1, -5, 2, 0, -1, -8, -5, -6, 1, 0, -2,
+ -1, -2, -1, 2, 0, -9, 0, 5, 4, 7, -3, -3, 3, 4, 2, 4,
+ 0, -1, 3, 1, 5, -5, -6, -7, 0, 3, 0, -2, -4, 3, 3, -3,
+ -4, -7, -2, 4, 1, -1, -4, -1, -6, -2, 3, -2, -3, 1, 4, 1,
+ -1, -4, -3, 3, 4, 5, -2, 2, -3, 4, 0, 3, -3, -3, 0, 3,
+ 1, -2, -1, -3, 2, 4, -2, -2, -3, -1, -1, 3, -11, -2, -8, 5,
+ -1, 3, -5, -2, 2, -1, 3, -3, 0, -1, -1, 5, -2, 0, -2, 3,
+ 2, 3, -2, -6, -3, 2, 4, -6, 5, -6, 1, 2, 3, -6, 2, -3,
+ -4, 3, -9, 2, -6, 3, 4, 2, -9, -1, 1, 2, 8, -3, -4, -1,
+ -2, 2, -2, 2, -3, 3, -1, 1, 2, -1, -6, 1, 2, 2, 1, -2,
+ 2, 3, 1, -3, -6, -3, 0, 1, -3, 0, -3, -1, -4, 2, -4, -3,
+ -1, 4, 0, 5, -6, -7, -1, 0, 0, -3, -1, 2, 4, 0, 3, -4,
+ -1, 1, 7, 4, 2, -1, -4, 0, 2, -4, -5, -5, -1, 1, 4, -5,
+ -4, -6, -3, -2, -3, 2, -2, 5, 2, 3, -4, -2, -5, 6, 3, 4,
+ 2, -3, 1, 0, 0, 1, -3, -1, 1, 7, 0, 6, -6, -7, -2, -7,
+ 0, -1, 0, 2, 1, -2, -7, -2, -5, 0, 2, 0, -3, -5, -1, -3,
+ 0, -1, 0, -6, 8, 4, 5, -1, 1, -4, 1, 1, 4, 2, 5, 3,
+ 6, 0, -2, -9, -4, -1, 0, 0, 1, -1, -4, -1, -5, -5, -5, 0,
+ 0, 1, -6, -5, -9, 0, -3, 0, -2, 0, 0, 3, 4, 2, 1, -7,
+ 1, 3, 4, 9, 1, 4, 4, 2, -4, 2, -2, 1, 5, -2, 0, -3,
+ -4, -3, -2, -4, -4, -4, 1, -1, 2, -6, -8, -3, -8, -1, -2, -4,
+ 5, 2, 3, -1, 0, -4, 2, -1, 5, 5, -1, 3, 0, 3, 3, 0,
+ -4, 9, 4, 2, -1, -6, -4, -2, -2, 2, -7, 0, 0, -2, -2, -2,
+ -10, -4, -7, 0, -2, 2, -2, 2, 1, 0, -3, 0, 1, 6, 3, 2,
+ 0, 0, -1, 2, 3, -1, 4, -5, 6, 2, -3, 0, -3, 0, 1, 0,
+ -5, -6, 1, 0, 1, -5, -2, -14, 0, -4, -1, -1, -1, 1, -3, 0,
+ -2, -1, -4, 4, 5, -1, 5, -1, 3, 3, 5, -3, 5, -3, 5, 5,
+ 6, 4, -6, 2, -9, 4, -4, 0, 1, -2, -1, -8, -6, -11, -2, -3,
+ 3, -6, -8, 3, -5, 1, -3, 1, -3, 1, 3, 5, 6, 2, 1, -6,
+ 4, -1, 1, 0, 7, 7, 2, 3, -6, -4, -4, 3, 3, 0, 1, -1,
+ -2, -4, 0, -8, -2, -3, 1, -2, 1, -5, -2, -1, -3, -3, -4, -3,
+ 7, 4, 1, -1, -6, -5, -3, 2, 5, 8, 3, 3, 2, 1, -4, -1,
+ -2, 6, 3, 2, -4, -1, 1, -5, -1, -1, -5, 2, -2, 1, -2, -7,
+ -5, -11, -4, -3, 3, -8, 8, 4, -2, -2, -4, -4, -1, 4, 3, 5,
+ 5, 2, 4, -1, 6, -3, 6, 2, 3, 0, -4, 0, -2, -2, 0, -5,
+ -2, -1, 4, 3, 1, -13, -8, -8, -5, -3, 7, -2, 3, -2, -5, -3,
+ -8, -2, -3, 8, 6, 1, -2, 5, 3, 1, 2, 0, -1, 2, 4, 3,
+ -5, 1, -3, 0, 1, 7, 1, 2, 3, -1, -4, -4, -10, -7, 3, 0,
+ 2, -5, -5, -4, -1, -7, -3, -3, 1, 3, 0, 0, -1, -6, 6, 1,
+ 4, 1, 2, 5, 6, 4, -1, -4, -3, 1, 2, 5, 2, -1, 1, 3,
+ -8, -1, -10, -2, -5, 0, -1, -6, -10, -7, 2, -2, 6, -1, -2, 1,
+ 4, -1, -5, -1, -5, 4, 1, 4, 2, 1, 3, 4, 0, -2, 1, -1,
+ 3, 8, 2, 1, -4, -3, -3, 3, -3, -1, -4, 0, -4, -6, -2, -8,
+ 1, -2, 5, -6, -5, -6, 0, 3, 1, -6, -3, 1, 2, 4, 2, 4,
+ -2, 3, 3, 3, 1, 5, 1, 2, 3, -2, -6, 6, -1, 6, -2, 1,
+ -7, -5, -2, -3, -6, -6, -6, -4, 0, -2, -4, -4, -3, 0, -1, 1,
+ -3, -1, 3, 1, 1, 0, 6, 4, 8, 10, 5, 0, -3, 1, -2, 5,
+ 2, 1, 1, 1, -4, -6, -8, -8, -8, -5, -4, -5, -4, -5, 0, -5,
+ -3, 0, -7, 0, 4, 1, -4, -1, -4, -2, 4, 4, 5, 6, 6, 7,
+ 0, 0, -1, 0, 2, 9, 2, 1, -3, 0, 1, -3, 1, -9, -1, 3,
+ -4, 3, -6, -7, -2, -1, -1, -1, 1, -9, 2, -5, 1, -8, -6, -6,
+ 1, -1, 6, 0, 2, 5, 2, 0, 2, 1, 2, 6, 5, -2, -1, 0,
+ 4, 1, 6, 0, -2, 1, 0, 3, -7, -1, -13, -4, -3, -3, -3, -2,
+ -3, -5, -9, -11, -2, -3, 4, 7, -1, 2, 0, -2, 8, 5, 1, 4,
+ 3, 2, 7, 3, -2, -4, 7, 2, 3, -2, 1, -1, 2, 0, -5, -4,
+ -4, 0, -4, 0, -1, -10, -9, -3, -5, -8, 1, -5, 3, -3, 0, -7,
+ 1, 0, 5, 4, 7, 1, 1, 0, 2, 2, -2, -1, 2, 1, 4, 6,
+ -1, 4, 3, -1, 4, -2, -3, 3, -1, -2, -6, -6, -7, -3, -1, 0,
+ -4, -6, -5, -6, 0, -3, 3, -5, 7, 0, -1, 1, -3, -1, 1, 6,
+ 3, -3, 7, 1, 10, 1, 6, -1, -2, 5, 2, 1, 1, -4, -2, 0,
+ -3, -7, -2, -4, 4, -8, -8, -4, -10, -2, 2, -4, 1, -5, -7, -1,
+ 3, -1, 1, 1, 4, 6, 2, 2, 0, 4, 7, 0, 5, -2, 0, 3,
+ 3, 3, -3, -1, -5, -2, 0, 3, -4, -6, 2, -1, 0, -2, -4, 0,
+ -4, -3, -9, -3, -4, -4, 0, 3, -1, -4, 3, 1, 5, -2, 1, 2,
+ 2, 4, 5, -3, 2, 1, 3, 7, 1, -5, 1, 0, 5, -3, -2, -3,
+ -4, 0, -3, -2, -5, 0, -8, 3, -6, -4, -6, -2, 2, -4, -2, -3,
+ -2, 1, 4, 2, 3, -2, 2, 4, 1, 4, -2, 3, 2, 1, 1, 7,
+ -1, 2, 4, -4, 2, -4, -2, 5, -4, 3, -1, -3, -2, 3, -8, -4,
+ -6, -3, -3, -1, 0, -6, -1, 0, 1, 1, -2, -10, -3, -1, 0, 2,
+ -5, 1, 1, 2, 10, 8, 2, 8, -1, -2, 4, -5, 2, 2, 7, 6,
+ -6, -1, -5, -4, -3, -6, -7, 0, -5, -5, -1, -2, -5, 0, -4, 6,
+ -6, 0, 3, -3, 4, 0, -6, 2, 5, 5, 4, 10, 0, 2, -3, 3,
+ -2, 0, 3, -3, 2, -3, -8, -8, -5, -1, -1, -1, 0, -5, -2, 0,
+ -3, -4, -1, -5, -2, 5, 0, 5, -4, 4, -1, -1, 1, -3, 3, 9,
+ 2, -1, 1, -6, -3, 7, 1, 3, -2, -4, 0, -1, 3, 1, -3, 4,
+ 6, 0, 1, 2, -3, 0, 0, -5, -13, -4, -2, 1, 2, -3, -10, -4,
+ -7, 1, -2, -2, -1, 0, 1, 1, -4, -1, 2, -2, 7, 1, -3, 0,
+ 0, 4, 5, 2, 2, -1, 6, 9, 1, 3, 1, -5, 5, -6, -5, -2,
+ -4, -2, 2, -7, -4, -11, -5, 3, -3, -6, -4, -6, 3, 3, -3, 2,
+ 0, 1, -3, -1, -2, -4, 1, 10, 8, -2, 4, -3, 6, 6, 1, 0,
+ -7, 2, -2, 1, 3, -4, -4, 4, 1, 0, -2, -5, 2, -2, 0, -7,
+ -11, -5, -2, -2, 5, -1, -8, -1, -1, 1, 2, -2, -1, 1, 1, 5,
+ 0, -3, 5, 1, 6, 1, -1, 3, 1, 6, -3, -1, -1, -3, 4, 12,
+ -1, -1, 2, -4, -1, -6, -8, -7, -3, -2, 1, -9, -5, -6, -10, 5,
+ 1, -2, -3, -2, 5, 4, 3, -1, -5, 4, 6, 3, 4, 6, -2, 7,
+ 0, -4, -1, -1, 9, 8, 2, 2, -8, -3, -3, 0, -2, 0, -4, -2,
+ 0, -6, -7, -14, -6, -5, -1, 3, -6, -2, 1, -3, 0, -4, -5, 1,
+ 5, 9, 4, 0, 3, 0, 1, 12, 0, 4, 8, 5, 7, -1, -4, 0,
+ -3, 5, 4, -4, 0, -3, -13, -2, -10, -14, -3, -5, 2, 1, -3, -4,
+ -8, -8, -3, -2, -2, 3, 4, 8, 0, 2, 1, 2, 12, 5, 3, 8,
+ 2, 6, 3, -4, -4, -2, -8, 8, -5, -2, -6, -10, -2, -6, -4, 0,
+ -4, 2, 5, 1, 0, -4, -4, -1, -1, -3, 4, -7, 4, 3, -3, 4,
+ -4, -3, 8, 4, 7, 0, 0, 2, -1, -2, -1, -2, -7, 11, -1, 5,
+ -4, 2, -2, 0, 2, -2, -4, -2, 1, -5, 3, -6, -9, -3, -3, -2,
+ -5, -5, -2, -6, -2, -7, -8, 1, 3, 5, 9, 4, 4, 0, 5, 8,
+ 1, 3, 7, 5, 10, 11, -7, 3, 0, -3, 1, -1, -7, -7, -3, -2,
+ -6, -9, -6, -12, -4, -1, 0, -8, -5, -3, -3, -2, 3, 1, 1, 9,
+ 4, 2, 5, -1, 2, 6, 2, 0, -3, 2, 2, 5, 2, -1, -4, 4,
+ 1, 1, 2, -5, -8, -1, -3, -1, -9, -4, 1, -4, 5, -6, -4, 0,
+ 3, -9, 3, -3, -5, 1, 4, 4, 1, -4, 1, -4, 4, 1, -6, 0,
+ 5, 7, 8, 1, 6, 0, 3, 4, 2, -3, 1, -3, -3, 3, -9, -6,
+ -7, -2, -1, -3, -5, -6, -5, -5, -6, -5, 4, -3, 5, 5, -2, -1,
+ -1, -3, 6, -2, 5, 6, 2, 11, 8, -1, 3, -6, -2, 5, 4, -3,
+ -3, -5, -3, -7, -5, 0, -5, 2, 1, 0, 1, -7, 0, -3, -2, -1,
+ -2, -5, 7, -4, -2, -3, -2, -3, 4, 4, 9, 0, 1, 1, -5, -3,
+ -4, -4, 4, 3, 6, 0, -2, -2, -6, 4, 1, 1, -3, 3, -1, 2,
+ 0, -7, 0, 0, -1, -3, -2, -1, -5, -2, -3, -8, -5, -5, -1, 5,
+ 5, 2, 2, -3, 4, 3, 3, 6, 3, -1, 10, -4, -3, -2, -3, 0,
+ -4, 0, -2, -2, 0, 1, -4, -2, -5, -9, 8, -2, -1, -1, -3, -3,
+ -2, -6, 2, 1, 2, 9, 0, 1, 3, -4, 2, 4, -6, -1, 2, -1,
+ 6, 3, 0, -5, -3, -1, 0, 3, -3, 0, -6, -2, -3, -4, -2, 0,
+ 3, 2, 2, 0, -10, 1, -6, -5, -1, -2, 5, 3, 6, -2, -6, -1,
+ -3, 2, 11, 11, -28, -10, 54, -53, 2, 43, -37, 0, 43, -48, 7, 11,
+ -18, 19, -33, 32, -1, -7, -6, 19, -21, 23, -38, 0, 54, -49, 0, 15,
+ 20, -28, -20, 53, -28, -48, 70, -6, -60, 51, 5, -32, 1, 31, -10, -33,
+ 24, 33, -68, 21, 50, -67, -1, 57, -28, -21, 26, 15, -48, 9, 33, -32,
+ -3, 23, -10, 5, -4, -10, 24, -42, 29, -13, 0, 26, -15, -26, 46, -17,
+ -38, 45, -26, 8, -1, 4, -5, -3, 15, -27, -2, 39, -37, -25, 74, -33,
+ -25, 16, 24, -26, -25, 46, 10, -74, 50, 33, -80, 37, 32, -51, 13, 26,
+ -21, -5, 0, 18, -33, -1, 49, -29, -29, 38, 7, -26, -20, 45, -21, -18,
+ 26, -6, -6, 17, -29, -5, 41, -38, 10, 19, -18, -7, 15, 2, -24, 1,
+ 21, -6, -28, 51, -30, -7, 10, 6, -22, -3, 37, -32, -24, 63, -16, -60,
+ 65, -10, -35, 15, 17, -15, -8, -1, 33, -37, -10, 55, -44, -5, 41, -35,
+ -9, 20, -5, -18, 13, 19, -27, 2, 34, -34, -7, 21, -27, 27, -25, 26,
+ 5, -30, 32, -45, 38, -3, -41, 24, 25, -31, 5, 9, 9, -37, 13, 31,
+ -36, 7, 20, -18, -25, 56, -50, 13, 17, -17, 19, -40, 46, -3, -82, 88,
+ -1, -73, 66, -10, -4, -18, 13, 5, -27, 14, 7, -7, -10, 37, -39, 11,
+ 14, -38, 35, -21, 5, 11, -27, 45, -37, -6, 34, -39, 23, 16, -51, 51,
+ -11, -28, 19, -6, 12, -29, 12, 26, -21, -25, 48, -35, -6, 24, -9, 0,
+ -31, 54, -19, -47, 73, -33, -43, 81, -59, 12, 15, -28, 22, -26, 33, -2,
+ -29, 14, 34, -63, 28, 16, -40, 31, -22, 18, 8, -22, 25, -31, 6, 26,
+ -54, 33, 19, -53, 56, -25, -9, 24, -39, 34, -18, -15, 35, -18, -16, 43,
+ -41, -3, 47, -54, 9, 33, -13, -24, -2, 41, -26, -35, 73, -49, 1, 32,
+ -34, 20, -28, 22, -5, -16, 23, 18, -62, 47, 5, -57, 51, -15, -5, 0,
+ 4, 12, -11, -15, 29, -28, 4, 26, -44, 43, -19, -14, 35, -37, 23, -15,
+ -11, 45, -54, 17, 42, -67, 18, 47, -58, 17, 25, -35, 14, -6, 11, -3,
+ -42, 73, -50, -12, 67, -68, 28, -6, -4, 16, -44, 47, 8, -64, 80, -39,
+ -31, 54, -43, 14, -2, 11, -14, 4, -3, 19, -34, 0, 61, -98, 69, 12,
+ -61, 48, -35, 28, -12, -38, 85, -86, 42, 25, -76, 77, -31, -37, 39, -2,
+ -12, 7, -10, 16, -1, -33, 60, -48, -16, 70, -69, 13, 38, -43, 15, 0,
+ 0, 22, -65, 75, -28, -60, 96, -58, -8, 32, -6, 1, -11, 4, 17, -46,
+ 17, 46, -86, 66, 9, -69, 67, -21, -30, 33, -32, 42, -34, 1, 50, -74,
+ 40, 5, -34, 21, 7, -23, 21, -14, 10, -1, -33, 58, -48, -3, 65, -77,
+ 14, 51, -65, 32, -10, 0, 24, -58, 71, -27, -54, 86, -56, -12, 45, -17,
+ -18, 21, -1, -5, -14, 12, 19, -75, 78, 1, -80, 84, -25, -33, 48, -50,
+ 45, -30, -15, 69, -86, 46, 22, -56, 14, 36, -35, 2, 16, -11, 4, -24,
+ 41, -27, -19, 53, -42, -4, 49, -67, 36, 2, -26, 37, -46, 58, -40, -26,
+ 82, -70, -7, 55, -30, -20, 36, -1, -32, 11, 7, 7, -41, 39, 18, -68,
+ 65, -11, -39, 40, -34, 30, -20, -12, 70, -98, 53, 27, -74, 40, 10, -31,
+ 11, 20, -19, 6, -6, 12, -19, -9, 46, -36, -31, 83, -65, 8, 32, -48,
+ 42, -45, 49, -23, -32, 68, -59, 5, 39, -31, -1, 23, -20, -8, 17, -7,
+ -15, -1, 16, 25, -63, 51, 14, -66, 47, -10, -15, 5, -1, 36, -72, 54,
+ 22, -86, 64, -3, -31, 13, 11, -8, -12, 14, 15, -34, 6, 29, -24, -25,
+ 62, -49, -9, 49, -56, 45, -31, 18, 4, -37, 57, -41, -11, 38, -38, 7,
+ 24, -20, 10, -13, 20, -17, -8, 18, -4, -30, 35, 14, -63, 56, -7, -52,
+ 50, -5, -4, -19, 17, 36, -83, 51, 14, -52, 30, 4, 0, -15, 14, 8,
+ -43, 32, 3, -20, 2, 19, -11, -20, 45, -42, 14, 3, -5, 9, -31, 43,
+ -20, -30, 51, -24, -19, 47, -42, 21, -17, 25, -24, -20, 52, -37, 1, 20,
+ -6, -21, 25, -2, -33, 30, -9, -15, 23, -13, 26, -49, 29, 22, -76, 71,
+ -12, -37, 27, 4, 7, -41, 30, 10, -45, 28, 13, -13, -21, 31, -1, -33,
+ 27, 6, -18, -10, 24, -6, -26, 33, -10, -37, 72, -60, 24, 1, -13, 15,
+ -36, 52, -44, 18, 14, -31, 23, 2, -16, -8, 10, 23, -47, 19, 17, -10,
+ -17, 10, 29, -69, 56, -5, -38, 47, -28, 14, -21, 6, 32, -55, 33, 12,
+ -39, 24, 5, -11, -25, 31, 12, -47, 35, 9, -25, 1, 7, 5, -36, 57,
+ -52, 18, 29, -45, 37, -45, 35, -13, -17, 41, -31, 7, 8, -18, 15, -19,
+ 19, -22, 2, 33, -37, 20, -4, 2, -25, 27, 0, -34, 37, -13, -6, 3,
+ 1, 17, -46, 28, 32, -78, 60, -7, -25, 18, -6, 12, -35, 31, 4, -38,
+ 37, -11, -8, -13, 37, -22, -17, 32, -27, 25, -34, 24, 9, -43, 41, -19,
+ -1, 29, -48, 29, -6, -8, 10, -11, 27, -35, 18, 9, -19, -7, 12, 4,
+ -27, 30, 2, -24, 13, 7, -18, -1, 16, 11, -68, 77, -15, -45, 43, -24,
+ 29, -38, 16, 21, -43, 27, -7, -10, 11, 1, -4, -13, 26, -17, -1, 1,
+ -1, 3, -19, 34, -24, -13, 49, -51, 22, 3, -23, 29, -33, 28, -7, -15,
+ 31, -35, 2, 29, -28, -11, 27, -4, -18, 19, 2, -31, 26, -16, 17, -28,
+ 34, -3, -49, 64, -39, 6, 1, -8, 25, -38, 32, 4, -53, 47, 0, -32,
+ 16, 14, -1, -37, 31, -4, -7, -8, 9, 7, -20, 36, -34, 4, 25, -39,
+ 25, -13, 4, 12, -36, 51, -38, 0, 34, -51, 27, 13, -34, 14, 12, -9,
+ -23, 41, -21, -1, -16, 28, 10, -62, 66, -23, -26, 26, -9, 13, -29, 13,
+ 31, -62, 49, 1, -49, 49, -18, -7, 2, 14, -10, -19, 20, 5, -8, -17,
+ 37, -27, -5, 23, -35, 17, 15, -30, 30, -20, 28, -32, -5, 48, -64, 29,
+ 13, -37, 35, -10, -1, -7, -3, 14, -16, -9, 26, -5, -35, 48, -21, -21,
+ 40, -26, -11, 21, 3, 0, -42, 47, 8, -71, 72, -21, -21, 25, -15, 7,
+ -16, 14, -1, -24, 18, 32, -48, 12, 30, -46, 12, 26, -45, 36, -20, 18,
+ -3, -34, 52, -40, -2, 25, -29, 32, -11, -18, 18, -3, 3, -24, 7, 36,
+ -40, -10, 50, -35, -19, 47, -30, -4, 22, -17, 8, -22, 29, 4, -72, 85,
+ -21, -48, 57, -19, -8, -10, 17, 5, -31, 16, 24, -47, 29, 12, -31, 14,
+ 2, -27, 43, -26, 5, 13, -33, 48, -46, -6, 58, -67, 13, 45, -50, 26,
+ -6, -6, -2, -9, 24, -20, -7, 40, -37, -5, 36, -29, -17, 38, -21, 2,
+ -5, 6, 14, -52, 59, -11, -59, 82, -38, -22, 32, -11, -6, -4, 11, 14,
+ -38, 30, 5, -44, 24, 25, -37, 0, 21, 1, -9, -24, 49, -36, -12, 47,
+ -49, 20, 34, -70, 43, 6, -31, 21, -20, 24, -13, -10, 37, -35, -8, 37,
+ -26, -22, 44, -20, -13, 20, -7, 8, -28, 36, -15, -42, 79, -41, -28, 46,
+ -17, -8, -5, 5, 29, -44, 17, 24, -43, 20, 13, -42, 16, 37, -43, 5,
+ 22, 4, -31, 6, 26, -40, 11, 31, -45, 24, 9, -27, 26, -29, 26, -13,
+ -16, 38, -40, 19, 21, -37, -9, 51, -32, -18, 34, -11, -7, -11, 22, 0,
+ -40, 49, -20, -23, 44, -22, -9, 3, -2, 19, -44, 42, 6, -52, 41, 6,
+ -43, 20, 28, -48, 31, 8, -23, 10, -7, 7, -19, 4, 31, -41, 15, 28,
+ -40, 16, -8, 16, -25, -4, 51, -55, 19, 0, 8, -29, 29, -16, -11, 37,
+ -39, 18, 4, -6, -5, -14, 35, -6, -52, 72, -37, -9, 13, 11, -17, -22,
+ 53, -32, -20, 42, -19, -18, 12, 19, -29, 12, 12, -24, 15, -6, 6, -12,
+ -15, 54, -44, -2, 41, -48, 32, -20, -4, 9, 1, 5, -35, 48, -11, -17,
+ -9, 24, 1, -37, 38, -9, -16, 16, -2, -11, -1, 13, 11, -55, 67, -31,
+ -19, 37, -26, -4, 12, 16, -34, 11, 21, -22, -10, 12, 0, 0, -21, 37,
+ -16, -11, 29, -37, 15, -3, 17, -37, 13, 38, -54, 30, -2, -19, 11, -11,
+ 20, -20, 15, 4, -22, 13, 2, -8, -13, 20, 4, -28, 33, -9, -34, 38,
+ -13, -6, -14, 46, -33, -9, 36, -34, 4, 8, -9, 11, -9, 5, 1, -17,
+ 23, -16, -3, 4, 18, -26, -11, 54, -53, 5, 18, -5, -11, 8, 11, -20,
+ 12, -10, 1, 2, 5, -4, -5, -1, 23, -35, 22, -1, -25, 19, 3, -7,
+ -11, 22, 1, -37, 45, -26, -12, 20, 2, -23, 17, 13, -23, -4, 18, 1,
+ -15, -15, 33, 4, -49, 46, -25, 3, 5, 2, -11, 7, 13, -33, 13, 10,
+ -24, 12, 6, -3, -4, 12, -9, -10, -3, 20, -19, -3, 19, -2, -21, 16,
+ 5, -33, 35, -17, -3, 2, 17, -12, -21, 27, -17, -6, 19, -8, -6, 14,
+ -12, 10, -16, 13, 0, -19, 11, 20, -23, -9, 38, -50, 22, 17, -24, -5,
+ 17, 7, -24, 0, 23, -18, -14, 27, -15, 5, 6, -9, 1, -2, 7, -24,
+ 16, 10, -12, -9, 26, -19, -14, 30, -18, -13, 19, -10, 10, -8, 6, 1,
+ -27, 35, -13, -20, 26, -5, -11, -10, 28, -9, -32, 36, -3, -25, 12, 28,
+ -51, 36, -6, -20, 18, -2, -3, -1, -11, 28, -31, -4, 48, -56, 16, 19,
+ -18, 6, -4, 1, -10, 11, 0, -4, -6, 25, -26, -9, 30, -26, -6, 23,
+ -13, 10, -7, -3, 19, -56, 64, -30, -31, 50, -4, -31, 15, 15, -27, 6,
+ 13, -6, -14, 20, -2, -27, 23, 7, -30, 10, 19, -10, -1, -13, 27, -31,
+ 3, 38, -56, 29, 20, -45, 24, 5, -17, 0, 5, 3, -9, 2, 24, -25,
+ -14, 31, -13, -22, 28, -6, -8, 1, 3, 13, -41, 51, -39, -20, 60, -30,
+ -28, 48, -14, -26, 25, -10, 7, -17, 16, 5, -25, 13, 10, -32, 11, 35,
+ -46, 17, 10, 5, -32, 10, 21, -44, 19, 30, -39, 15, 7, -18, 11, -11,
+ 10, -13, 1, 19, -14, -12, 30, -25, -18, 43, -23, -15, 30, -13, -6, -14,
+ 43, -42, -9, 55, -36, -17, 43, -21, -11, 12, -13, 16, -28, 23, 10, -38,
+ 27, 17, -47, 22, 20, -46, 30, -7, 6, -10, -6, 26, -34, 15, 22, -39,
+ 15, 21, -43, 26, -6, 1, -14, 12, 20, -26, -12, 41, -29, -29, 57, -40,
+ 2, 27, -22, 8, -10, 10, -10, -10, 30, -14, -29, 47, -17, -24, 25, -11,
+ 3, -17, 30, -3, -32, 28, 7, -44, 35, 12, -46, 39, -6, -10, -2, -3,
+ 23, -31, -4, 49, -48, 6, 39, -55, 32, -8, -9, 0, 8, 7, -15, -3,
+ 29, -26, -16, 43, -44, 13, 26, -30, 9, 6, -5, 4, -28, 30, 9, -56,
+ 64, -19, -33, 43, -25, -8, 14, 8, -14, -8, 18, 11, -44, 23, 17, -39,
+ 20, 19, -24, -1, 12, 7, -27, -2, 47, -51, 3, 47, -55, 28, 1, -23,
+ 17, 4, -12, 5, -9, 18, -9, -21, 30, -24, 6, 12, -11, -2, 14, -13,
+ -3, -10, 26, -10, -45, 74, -31, -31, 51, -26, -14, 19, -8, 2, -4, 3,
+ 23, -43, 20, 15, -31, 13, 20, -36, 18, 9, -17, -3, 0, 21, -32, 12,
+ 32, -50, 21, 12, -26, 16, -6, 5, 1, -16, 21, -5, -27, 28, -11, -11,
+ 19, -2, -20, 28, -17, -2, 4, -5, 9, -26, 43, -31, -11, 47, -42, 1,
+ 19, -16, 5, -8, 12, 9, -41, 41, -7, -32, 22, 25, -51, 23, 14, -18,
+ 7, -21, 31, -22, -2, 24, -24, 6, 18, -39, 25, -9, 3, 5, -17, 28,
+ -13, -17, 27, -21, -12, 25, -12, -12, 32, -19, -6, 11, -24, 29, -21, 11,
+ -2, -17, 36, -29, -9, 24, -16, -2, 7, -6, 17, -27, 27, -20, -11, 23,
+ -1, -31, 25, 15, -32, 12, -8, 21, -22, -8, 26, -16, -15, 47, -45, 8,
+ 12, -12, 14, -28, 33, -10, -15, 15, -11, 6, 2, -17, 5, 23, -20, -5,
+ 19, -21, 12, -8, -8, 31, -38, 31, -17, -14, 31, -27, -1, 19, -20, 19,
+ -10, 4, -2, -7, 2, 1, -6, 6, 12, -27, 12, 8, -10, -7, 8, -1,
+ -3, -15, 47, -53, 15, 25, -40, 24, -7, 12, -13, -11, 22, -7, -22, 14,
+ 7, -5, -11, 13, 5, -8, -9, 4, 7, -22, 22, -12, 16, -9, -16, 29,
+ -32, 8, 23, -36, 14, 7, -3, 5, -27, 24, -1, -20, 14, 7, -7, -4,
+ 9, -21, 6, 23, -27, 7, -1, 23, -30, -3, 31, -39, 26, -17, -3, 30,
+ -24, 9, -7, -13, 30, -24, 3, 2, 9, -6, -15, 24, -18, 9, -20, 16,
+ 2, -8, 11, -11, 6, -10, 6, 11, -38, 27, 20, -42, 28, -26, 35, -21,
+ -29, 51, -32, 8, -3, 15, -19, 3, 14, -33, 24, 4, -9, -9, 4, 23,
+ -29, 0, 21, -32, 39, -38, 20, 8, -34, 38, -27, 8, 12, -12, 3, -8,
+ 11, -11, 1, 3, -9, 18, -18, 10, 0, -7, 4, -13, 17, -13, 0, 33,
+ -56, 42, -11, -7, 7, -17, 36, -50, 24, 21, -25, -7, 14, 9, -27, 8,
+ 23, -28, 3, 8, 2, -12, -10, 39, -43, 24, -4, -5, 18, -38, 39, -26,
+ -8, 26, -24, 14, 10, -20, 5, -9, 15, -19, 13, -12, 5, 24, -39, 24,
+ -8, 8, -16, -14, 53, -49, 16, 5, -22, 26, -28, 18, -13, 7, 18, -31,
+ 6, 17, -12, -13, 3, 26, -35, 16, 18, -36, 21, -12, 28, -49, 27, 22,
+ -38, 13, -1, 17, -28, -5, 30, -22, 2, 25, -42, 32, -19, 18, -23, -1,
+ 21, -20, 22, -31, 25, 3, -25, 9, -6, 27, -29, -3, 32, -35, 19, -7,
+ -8, 11, -12, 28, -35, 1, 39, -33, -6, 2, 30, -35, -1, 41, -42, 18,
+ -9, 6, -8, -2, 26, -46, 24, 24, -41, 11, 11, -2, -12, -9, 48, -59,
+ 31, -10, 6, -12, -5, 34, -43, 33, -12, -7, 11, -11, 1, 7, -12, 17,
+ -23, 32, -24, -5, 19, -26, 27, -28, 24, -15, -5, 31, -41, 11, 11, -4,
+ -19, 10, 37, -53, 2, 43, -35, 2, -3, 20, -20, 3, 32, -53, 30, 5,
+ -24, 10, -7, 41, -53, 10, 33, -31, -8, 11, 12, -30, 28, 4, -37, 28,
+ 8, -30, 12, -17, 42, -38, 5, 24, -33, 35, -41, 23, -1, -4, 5, -20,
+ 32, -18, -10, 25, -22, -4, 14, 6, -24, -5, 62, -80, 28, 19, -20, 4,
+ -14, 41, -49, 14, 34, -45, 3, 13, 17, -37, -4, 66, -61, -5, 35, -15,
+ -5, -2, 14, -24, 21, 5, -41, 41, -22, 18, -24, 5, 44, -66, 34, -3,
+ -17, 24, -26, 20, -13, 14, -1, -31, 39, -19, -20, 31, -14, 0, -12, 46,
+ -61, 29, 19, -44, 36, -26, 30, -31, -7, 49, -41, -15, 54, -42, -1, 12,
+ 24, -48, 8, 44, -57, 17, 13, 7, -34, 13, 33, -55, 28, 4, -14, 4,
+ -9, 32, -42, 15, 28, -58, 40, -12, 0, 7, -8, 8, -24, 29, -9, -29,
+ 38, -23, 9, -8, 13, -7, -14, 24, -37, 32, -7, 3, -17, 1, 39, -46,
+ -20, 78, -68, 15, 17, -6, -4, -15, 37, -47, 15, 20, -17, -12, 28, 9,
+ -52, 25, 31, -54, 24, 4, -1, -11, -5, 51, -74, 36, 9, -27, 17, -6,
+ 8, -12, 3, 6, -16, 14, 0, -15, 10, 3, 7, -31, 34, -22, -2, 17,
+ -20, 9, 10, -7, -13, -5, 45, -52, 8, 30, -33, 15, -11, 28, -32, -5,
+ 44, -42, -4, 42, -25, -29, 29, 14, -36, 12, 19, -20, 8, -14, 33, -42,
+ 16, 23, -48, 32, 2, -14, 2, -1, 14, -21, -9, 42, -47, 24, 0, -10,
+ 0, 15, -19, -1, 21, -31, 13, 15, -23, 10, -14, 20, -7, -27, 50, -32,
+ -5, 18, -10, -1, -8, 25, -36, 12, 34, -45, 6, 27, -20, -16, 12, 19,
+ -22, 0, 12, 0, -13, -8, 31, -41, 17, 16, -29, 17, 11, -19, -4, -2,
+ 36, -55, 30, 13, -35, 25, -7, -8, 10, -4, -8, 13, -7, 0, 4, -16,
+ 8, 13, -35, 40, -25, -6, 44, -51, 17, 15, -18, -3, 1, 14, -18, -1,
+ 24, -23, -9, 20, -6, -9, 1, 24, -30, 6, 6, 10, -29, 8, 31, -48,
+ 21, 27, -43, 13, 4, -4, -5, -2, 19, -18, 12, -15, 4, 16, -25, 9,
+ 1, 2, 0, -13, 12, 3, -16, -3, 18, -10, -6, 25, -41, 21, 11, -30,
+ 20, -3, 0, 1, -14, 27, -19, -21, 38, -28, 9, -3, 14, -22, 13, -4,
+ -2, -6, 12, 2, -26, 30, -1, -38, 31, 7, -32, 25, -16, 14, -4, -9,
+ 15, -19, 6, 4, -11, 2, 11, -8, -4, 10, -7, -4, 6, -10, 2, 11,
+ -9, 0, -5, 15, -16, 0, 9, -2, -7, 0, 11, -11, -12, 35, -44, 20,
+ 13, -19, 2, 13, -11, -14, 12, 10, -22, -2, 27, -24, -2, 15, 5, -29,
+ 22, -10, 6, -2, -3, 16, -31, 20, 11, -39, 29, 9, -34, 25, -10, 5,
+ -2, -15, 14, 0, -5, -6, 19, -18, 13, -22, 5, 24, -30, -1, 35, -23,
+ -12, 12, 12, -26, 5, 22, -32, 16, 16, -27, 2, 10, -4, -12, 2, 23,
+ -19, -1, 1, 11, -17, 4, 8, -18, 12, 12, -24, 1, 24, -20, -15, 29,
+ -5, -31, 42, -23, -8, 20, -18, 19, -33, 24, 8, -22, 0, 32, -38, 9,
+ 21, -25, 2, 23, -30, 7, 16, -20, 12, -10, 8, -14, 12, 16, -41, 24,
+ 14, -30, 6, 2, 19, -22, -6, 25, -8, -24, 23, -1, -29, 32, 9, -53,
+ 50, 4, -42, 12, 12, 3, -24, 15, 14, -25, 5, 4, 7, -25, 26, -5,
+ -23, 28, 0, -32, 23, -1, -21, 14, 10, -7, -13, 21, -25, 16, -8, 1,
+ -1, -1, 13, -22, 12, 12, -28, 3, 13, 1, -15, -3, 38, -41, -5, 45,
+ -37, -9, 30, -4, -35, 42, -10, -25, 19, -4, 3, -18, 12, 22, -43, 25,
+ 14, -37, 21, 4, -19, 5, 17, -12, -17, 26, -4, -22, 11, 7, 6, -31,
+ 35, -15, -14, 22, -14, 0, 0, 14, -16, -12, 31, -17, -19, 25, -10, 0,
+ 2, 12, -23, 8, 16, -44, 37, 0, -19, -2, 21, -5, -25, 22, 12, -38,
+ 3, 37, -11, -38, 36, 11, -54, 40, -9, -11, 14, -11, 11, -19, 17, 17,
+ -47, 16, 25, -17, -23, 34, -3, -29, 25, -17, 5, 14, -17, 3, -4, 21,
+ -23, -11, 35, -31, 7, 13, -17, 13, -6, 6, -22, 13, 5, -8, -8, 16,
+ 8, -34, 18, 21, -49, 32, 12, -45, 32, 0, 1, -32, 27, 2, -20, 10,
+ 6, 3, -26, 18, 19, -50, 31, 13, -40, 20, 12, -7, -19, 21, -9, -12,
+ 24, -21, 6, 7, -6, -2, -9, 23, -19, -8, 15, -7, 18, -26, 13, 5,
+ -21, 21, -19, 4, 25, -26, -14, 32, -2, -33, 21, 8, -29, 38, -35, 17,
+ 8, -19, 15, -29, 24, 15, -40, 10, 28, -21, -26, 34, 7, -42, 35, -3,
+ -14, -1, 18, -6, -30, 29, -1, -11, 8, -8, 16, -22, -2, 25, -27, 14,
+ 0, -9, 1, 9, 1, -25, 22, -16, 12, 8, -33, 32, 2, -35, 19, 4,
+ 0, -17, 15, 1, -6, 9, -15, 16, -30, 25, 8, -46, 40, 11, -39, 8,
+ 11, 2, -21, 10, 11, -17, 15, -6, -4, -10, 18, -6, -23, 29, -2, -7,
+ -13, 9, 24, -48, 23, 17, -30, 27, -22, 9, 4, -16, 8, 4, -9, -2,
+ 19, -12, -12, 21, -22, 15, -8, -2, 20, -39, 32, -5, -16, 11, 5, -15,
+ -8, 30, -5, -36, 34, -5, -13, 1, 3, 22, -37, 14, 6, -8, 0, -6,
+ 11, -17, 23, -6, -18, 19, -7, -4, -14, 11, 17, -32, 24, -6, -2, 9,
+ -26, 30, -24, 2, 18, -19, 7, 4, -6, -3, -1, 3, 1, 0, -21, 39,
+ -20, -33, 51, -27, -6, 24, -18, 8, -10, 12, -3, -23, 25, -11, 5, -19,
+ 25, 2, -34, 29, -5, -9, -7, 18, -12, -18, 30, -4, -26, 20, -9, 22,
+ -32, 7, 26, -28, 6, -9, 19, -20, 5, 2, -9, 26, -15, -13, 18, -19,
+ 15, -3, -26, 34, 2, -33, 6, 36, -36, -12, 36, -32, 29, -24, 10, 13,
+ -39, 30, -6, -17, 12, 9, -9, -17, 28, -6, -27, 21, 4, -15, 6, 13,
+ -13, -16, 30, -21, 1, -4, 4, 28, -60, 46, -3, -21, 3, 5, -8, 17,
+ -17, 3, 11, -6, -9, 11, -8, -17, 44, -36, 0, 20, -9, -4, -13, 29,
+ -24, 5, -3, 6, 14, -36, 26, -3, -23, 30, -3, -30, 25, 3, -12, -22,
+ 42, -13, -27, 19, 9, -3, -20, 16, -7, -3, 7, -5, 6, -13, 22, -21,
+ -15, 39, -17, -21, 30, -23, 19, -6, -20, 31, -24, 0, 8, 12, -31, 20,
+ 8, -27, 20, -14, 20, -22, -2, 17, 0, -18, 11, 0, 7, -28, 22, -2,
+ -19, 31, -17, -8, -2, 28, -24, -16, 34, -4, -28, 9, 26, -12, -30, 29,
+ -7, -6, 10, -1, -10, 5, -3, 6, -23, 29, -18, 10, -16, 7, 28, -48,
+ 21, 4, -12, 9, 4, -12, 5, -1, -7, 2, 0, -3, 11, -15, -3, 26,
+ -19, -4, 3, 1, 10, -37, 49, -26, -9, 6, 18, -23, 0, 17, -3, -27,
+ 25, 3, -22, 10, 6, -3, -19, 32, -23, 9, -3, -3, 11, -31, 27, 12,
+ -42, 23, 13, -12, -18, 30, -10, -19, 13, -4, 0, 17, -25, 12, -2, -2,
+ 4, -8, 9, -12, 8, -17, 24, -2, -19, 14, -16, 18, -6, -12, 22, -12,
+ -17, 20, 0, -4, -13, 19, -5, -18, 30, -19, 8, -17, 19, -9, -6, 8,
+ 1, 1, -36, 48, -9, -40, 46, 1, -50, 44, -5, -14, -3, 10, 4, -17,
+ 11, -1, 11, -25, 9, 10, -24, 19, 2, -9, -4, 4, 10, -26, 20, -8,
+ 6, -3, -12, 17, 7, -31, 18, -14, 17, -7, 0, 2, -8, 9, -15, 19,
+ -16, 8, 2, -22, 21, 15, -33, 4, 24, -20, -13, 36, -18, -24, 33, -16,
+ -8, 20, -19, 22, -32, 21, 0, -5, -7, 18, -17, -11, 26, -5, -25, 25,
+ 3, -17, -3, 15, 7, -35, 22, -3, 2, -2, -6, 7, -3, -4, 4, -13,
+ 25, -17, 1, -4, 7, -12, 13, -2, -11, 12, 2, -25, 24, 0, -25, 17,
+ -4, 6, -9, 14, -11, -8, 5, 0, 10, -25, 23, 1, -28, 27, 5, -26,
+ 0, 23, -11, -20, 21, 10, -30, 12, 9, -5, -16, 25, -12, -19, 26, -3,
+ -12, 1, 9, -1, -15, 11, 3, -12, 6, -5, 11, -7, -8, 6, 3, -11,
+ 4, 5, 0, -11, 7, -1, 6, -17, 1, 26, -35, 14, 6, -6, -8, 15,
+ -7, -9, 13, -2, -20, 19, 6, -11, -14, 24, 7, -36, 19, 11, -24, 1,
+ 23, -18, -4, 18, -10, -19, 29, -10, -9, -1, 6, 10, -23, 10, 19, -32,
+ 11, 11, -4, -13, 5, 12, -17, 3, 13, -20, 11, 0, -8, 5, 14, -32,
+ 19, 1, -22, 28, -16, -8, 13, 3, 0, -11, -10, 38, -40, 3, 22, -9,
+ -16, 19, -4, -13, 13, 9, -29, 9, 16, -9, -20, 25, -2, -22, 11, 6,
+ 4, -22, 12, 16, -35, 15, 26, -42, 13, 12, -5, -20, 24, -4, -18, 20,
+ -7, -11, 9, 5, -7, 1, -2, -2, 10, -18, 9, 11, -17, -2, 7, -5,
+ 28, -48, 12, 31, -36, 12, 8, -2, -14, 8, 2, -5, -1, 11, -17, -4,
+ 21, -1, -27, 19, 3, -13, 0, 8, 15, -39, 19, 17, -43, 34, 4, -32,
+ 16, 8, -10, -8, 21, -10, -12, 6, 9, -4, -10, 3, 9, -13, 8, 2,
+ -7, 1, 1, 2, -18, 22, -10, 2, 5, -19, 19, -4, -11, 11, -5, 2,
+ -13, 7, 15, -24, 9, 11, -20, -2, 21, 1, -38, 21, 9, -2, -22, 23,
+ 6, -41, 34, -2, -19, 27, -10, -23, 20, -3, 13, -34, 20, 10, -15, -3,
+ 14, -1, -19, 3, 4, 5, 8, -14, 9, -18, 18, -1, -22, 24, -8, -8,
+ 10, -10, 14, -12, -4, 6, -14, 30, -38, 28, -5, -23, 19, 4, -10, -9,
+ 22, -7, -22, 17, 8, -5, -19, 25, -9, -23, 31, -6, -26, 31, -20, 18,
+ -29, 22, 20, -54, 33, -4, 1, -3, 4, -8, 0, -5, 13, -6, -6, 9,
+ -1, -24, 36, -9, -26, 30, -24, 11, 8, -23, 22, -16, 5, -11, 20, -2,
+ -26, 23, -9, -3, 0, 9, -10, -6, 13, -3, -17, 25, -12, -2, -8, 16,
+ 4, -35, 39, -14, -9, -2, 23, -6, -37, 40, -12, -11, 4, 8, 1, -13,
+ 1, 17, -26, 12, 10, -27, 17, 4, -6, -18, 42, -32, 2, 4, -16, 36,
+ -31, 0, 10, 0, -1, -12, 15, 0, -28, 22, -3, -1, 6, -6, -9, -3,
+ 25, -18, -8, 7, 6, 5, -39, 48, -16, -23, 22, -2, -8, 1, 18, -25,
+ -9, 25, 1, -28, 16, 9, 0, -34, 37, -4, -27, 27, -18, -1, 6, 4,
+ -5, -8, 16, -9, 10, -21, 6, 12, -14, -4, 6, 9, 3, -31, 33, -14,
+ -12, 23, -28, 25, -10, 2, -11, 1, 11, 6, -30, 3, 40, -21, -34, 46,
+ -12, -22, 11, 6, -2, -10, 14, -10, -21, 49, -29, -16, 17, 9, -15, -13,
+ 32, -19, 0, 0, 8, 0, -14, 8, -4, -16, 30, -17, 2, -1, 0, 9,
+ -15, 6, -4, 11, -15, -6, 28, -28, 17, -18, 7, 11, -19, 12, 3, -24,
+ 21, 3, -29, 15, 26, -25, -27, 51, -18, -19, 7, 20, -21, -11, 36, -32,
+ -3, 35, -27, -4, 6, 8, 2, -31, 18, 18, -29, 1, 25, -16, -8, 19,
+ -30, 13, 16, -20, 8, -12, 19, -3, -21, 15, 0, -6, -3, 4, 6, 1,
+ -20, 2, 20, -5, -27, 31, -7, -21, 19, 6, -19, -10, 40, -28, -17, 40,
+ -15, -22, 12, 13, -23, 6, 14, -12, -7, 10, 11, -11, -30, 45, -9, -44,
+ 48, -5, -14, -5, 20, -22, 9, 3, -10, 0, 4, 4, -7, -9, 24, -23,
+ 3, 8, -15, 15, -2, -19, 21, -8, -6, -1, 14, -7, -12, 18, -10, -3,
+ 3, 21, -37, 2, 29, -23, -7, 22, -10, -2, -7, 20, -10, -20, 15, 5,
+ -25, 17, 23, -29, -16, 50, -35, -9, 19, 4, -22, 2, 24, -19, -10, 25,
+ -9, -22, 23, 3, -15, -6, 10, -4, 13, -29, 17, 13, -26, -2, 25, -23,
+ 14, -16, 12, -2, -2, 4, -11, 1, 11, 0, -22, 14, 18, -28, -6, 11,
+ 22, -29, -10, 42, -30, -12, 26, -12, -15, 19, 15, -41, 10, 33, -16, -32,
+ 20, 29, -47, 10, 36, -35, -1, 20, -19, 1, 9, 5, -14, -16, 15, 29,
+ -38, -6, 35, -16, -20, 18, 6, -9, -7, 1, 4, 6, -4, 0, -9, 2,
+ 8, 2, -14, -4, 24, -12, -32, 41, -1, -26, 1, 23, -22, 4, 11, -10,
+ -6, 8, 16, -28, -12, 52, -28, -40, 53, 2, -29, 2, 17, -10, -5, -2,
+ 8, -1, -13, 25, -10, -33, 51, -16, -32, 12, 29, -27, -11, 25, 7, -27,
+ 4, 12, 0, -15, 5, -2, 4, -11, 11, 21, -51, 15, 37, -46, 7, 24,
+ -9, -20, 2, 27, -11, -17, 4, 22, -40, 26, 16, -36, 2, 35, -32, -2,
+ 12, 14, -23, -17, 26, 10, -26, 3, 20, -20, -9, 28, -16, -9, 19, -4,
+ -21, 15, 12, -17, -15, 24, -7, -6, 5, -2, 10, -21, 4, 12, -9, -11,
+ 30, -12, -32, 38, 3, -33, 11, 11, 0, -24, 4, 44, -37, -18, 36, -8,
+ -25, 21, 5, -24, 10, -1, 18, -22, -2, 30, -38, -8, 41, -24, -3, 4,
+ 8, -6, -11, 20, -11, -20, 22, -2, 2, -8, 8, -12, 8, -17, 11, 18,
+ -34, 19, -4, 5, -3, -9, 5, -6, 6, -4, -6, 17, -5, -11, 2, 12,
+ -8, -16, 15, 3, -21, 13, 8, -7, -8, 12, -5, -5, -17, 33, -1, -44,
+ 35, 15, -42, 18, 15, -21, 4, -4, 10, -5, -14, 27, -21, -7, 19, 1,
+ -3, -8, -6, 9, -1, -23, 29, -13, -1, -2, 4, 8, -6, -20, 26, -22,
+ 5, 21, -25, 9, 3, -11, 16, -12, -4, 20, -20, -8, 25, -13, -5, 6,
+ -11, 13, 6, -30, 13, 24, -31, -11, 27, 9, -43, 28, 2, -3, -5, -4,
+ 13, -16, -1, 10, -8, -4, 11, 8, -23, 14, 0, -4, -10, 1, 14, -14,
+ 3, 2, -3, 20, -35, 26, -6, -25, 38, -32, 12, -10, 16, -10, 14, -24,
+ 9, 33, -83, 72, -13, -27, 28, -26, 25, -13, 8, -25, 18, 15, -29, 17,
+ -3, 9, -25, 2, 19, -20, 18, -20, 13, 4, -18, 32, -32, -10, 35, -18,
+ -12, 16, 10, -15, -5, 4, 13, -21, 1, 0, 14, -18, 9, 12, -26, 27,
+ -27, 9, 1, -4, -1, 1, 14, -33, 52, -49, -1, 46, -50, 21, -5, 12,
+ -9, -7, 6, 1, -2, -10, 14, -2, -10, 13, -19, 23, -26, 18, -2, -22,
+ 34, -30, 8, 20, -38, 14, 18, -18, -5, 9, 3, -6, -13, 24, -1, -28,
+ 12, 11, -14, -1, 21, -37, 31, -16, 5, 6, -26, 32, -23, 4, 2, 9,
+ 2, -40, 40, -7, -10, 2, 0, 9, -16, -1, 16, -3, -10, -3, 19, -22,
+ 6, 7, -9, -4, -10, 39, -38, 5, 27, -28, 0, 13, -8, 1, -3, 5,
+ -3, -9, 13, -8, -4, 13, -14, -6, 22, -14, -13, 31, -30, 22, -15, -15,
+ 55, -56, 6, 26, -23, 8, 1, 4, -17, 8, 6, -9, 9, -11, 15, -18,
+ 5, 14, -18, 9, -22, 26, -2, -23, 25, -11, 1, -16, 15, 12, -28, -4,
+ 35, -31, -3, 28, -8, -12, -8, 26, -21, -1, 3, -2, 12, -18, 18, -3,
+ -6, -9, 14, -23, 9, 36, -57, 29, 21, -50, 29, -2, -13, 7, 0, -5,
+ 6, -1, -4, 10, -25, 23, -3, -19, 28, -20, 11, -17, -5, 37, -39, 19,
+ -7, 1, 7, -17, 12, 14, -36, 6, 23, -23, 9, 12, -19, 4, 2, 2,
+ 6, -27, 14, 17, -39, 14, 34, -22, -31, 34, 6, -36, 28, -1, -28, 24,
+ 1, -18, 24, -20, 9, -2, -15, 21, -4, -23, 23, -10, -4, 15, -12, 3,
+ -6, 2, 10, -28, 28, -6, -15, 14, -14, 10, 1, -18, 14, 5, -19, 15,
+ 2, -18, 22, -17, -7, 29, -43, 45, -15, -40, 62, -27, -23, 23, 10, -20,
+ -20, 41, -7, -20, 9, 10, -22, 8, 5, 9, -21, 0, 22, -11, -18, 27,
+ -4, -34, 30, 3, -9, -2, 1, 4, -13, 6, 16, -25, 11, -11, 8, 1,
+ -11, 14, -4, -6, 4, 1, -2, -7, 1, -3, 11, -31, 57, -36, -10, 37,
+ -44, 22, -2, -10, 4, -1, 7, -2, -7, 7, 14, -33, 5, 24, -29, 7,
+ 10, -1, -13, 0, 26, -23, -16, 43, -32, -14, 23, 11, -23, -5, 13, 13,
+ -44, 44, -7, -18, 7, -7, 12, -12, -1, -1, 7, 0, -6, 26, -37, 17,
+ -6, 4, -19, 18, 13, -37, 24, 4, -7, 0, -13, 15, 3, -28, 22, 14,
+ -41, 27, 5, -28, 38, -30, 9, -6, -1, 18, -28, 8, 26, -36, 4, 21,
+ -3, -30, 28, -6, 1, -26, 45, -28, -15, 34, -15, -12, 6, 8, 1, -9,
+ -16, 26, 1, -50, 65, -34, -12, 25, -9, 4, -14, 21, -17, -2, -6, 10,
+ 17, -29, -6, 40, -23, -20, 27, 0, -40, 44, -27, 16, -6, 2, 3, -20,
+ 15, 15, -32, -1, 28, -9, -29, 38, -22, 14, -21, 16, -5, -6, 17, -35,
+ 20, 13, -19, 0, 2, 2, 16, -32, 0, 47, -61, 16, 31, -37, 21, -8,
+ 6, -7, 3, -6, 8, -9, -12, 29, -13, -20, 33, -16, 0, -21, 46, -39,
+ 2, 17, -3, -11, -6, 18, 2, -35, 29, 17, -37, 0, 42, -42, 9, -3,
+ 16, -19, -2, 24, -17, -2, 0, -1, 6, -12, 19, -12, -16, 27, -2, -27,
+ 16, 17, -42, 38, -22, 8, 2, -12, -1, 15, -18, 13, -6, -11, 7, 21,
+ -36, 26, -23, 38, -48, 15, 26, -20, -18, 24, -1, -4, -20, 34, -16, -17,
+ 18, 11, -30, 15, 7, -10, -10, 12, 15, -31, -1, 28, -6, -32, 30, 4,
+ -24, 1, 28, -28, 7, -11, 33, -39, 23, -15, 19, -12, -12, 11, 4, -25,
+ 33, -22, 14, -4, -3, -6, 10, -21, 31, -40, 19, 13, -10, -1, 14, -18,
+ -3, 10, -4, -5, -2, 10, -6, -14, 21, 14, -40, 15, 6, 3, -31, 28,
+ 12, -42, 11, 43, -44, 2, 27, -17, -18, 22, -16, 33, -59, 37, 15, -35,
+ 11, 20, -22, 1, -7, 22, -22, 7, -1, 9, -16, -4, 20, 3, -38, 31,
+ 9, -31, -3, 39, -34, 8, 4, -19, 41, -41, 11, 21, -40, 19, 18, -47,
+ 45, -14, -5, -13, 26, -4, -28, 19, 15, -45, 38, -4, -9, -4, 17, -29,
+ 28, -27, 34, -25, -20, 39, 5, -52, 49, -15, -13, 5, -3, 14, -2, -20,
+ 17, -3, -12, 18, -7, -9, 1, 10, 7, -31, 19, 13, -29, 12, -22, 52,
+ -30, -28, 40, 7, -60, 56, -19, -5, -5, 22, -26, 13, 1, 5, -28, 30,
+ -12, 3, -17, 25, -26, 16, -16, 20, -5, -14, 26, -19, -33, 67, -47, 2,
+ 20, -19, 21, -22, 12, 12, -25, 0, 17, -26, 24, -4, -15, 6, 9, -8,
+ 13, -28, 24, -15, 13, -27, 26, 3, -11, -31, 61, -31, -19, 24, 5, -33,
+ 22, -3, 14, -35, 22, 10, -28, 8, 23, -24, -2, 1, 18, -18, -8, 26,
+ -15, -12, 26, -31, 15, 10, -24, 18, -19, 35, -32, -1, 15, 7, -40, 36,
+ -14, -4, 16, -12, -22, 51, -54, 41, -31, 14, 4, -17, 5, 13, -24, 29,
+ -31, 12, 25, -34, -2, 30, -36, 21, -16, 22, -4, -36, 42, -11, -6, -12,
+ 31, -16, -29, 34, 6, -29, -4, 37, -23, -25, 51, -34, 9, -11, 23, -25,
+ 14, -8, 5, -20, 32, -22, 6, 14, -16, -3, 24, -49, 51, -46, 31, -4,
+ -21, 26, -13, 0, 7, -9, -2, -1, 8, -21, 22, -21, 29, -29, 10, 22,
+ -41, 37, -24, -7, 15, 3, -25, 26, 1, -15, 5, 2, 14, -33, -3, 54,
+ -69, 27, 13, 5, -37, 27, 4, -6, -19, 19, -3, -9, 2, 10, -11, 15,
+ -30, 38, -35, 20, 0, -29, 37, -16, 1, -14, 21, -12, -7, 22, -33, 30,
+ -19, 4, -7, -1, 31, -57, 46, -15, -8, 20, -21, -1, 18, -21, 17, -12,
+ 6, 7, -20, 2, 32, -57, 46, -7, -25, 12, 25, -32, -3, 18, 1, -12,
+ -15, 31, 4, -56, 52, -11, -6, -20, 23, 19, -50, 37, -7, -9, -1, 14,
+ -22, 10, 14, -36, 37, -18, -8, 25, -31, 20, -16, 21, -26, 10, 7, -15,
+ 9, 3, -14, 19, -25, 24, -15, -4, -4, 27, -37, 21, 7, -12, 1, -5,
+ 4, 5, -12, -4, 10, -12, 17, -10, -16, 52, -56, 5, 29, -12, -5, -28,
+ 56, -30, -19, 34, -3, -30, 20, 4, -21, 12, 9, -17, 21, -35, 43, -19,
+ -20, 21, -4, -13, 12, -10, 9, 0, -6, -4, 10, -19, 25, -23, 6, -3,
+ 10, -5, -15, 31, -12, -14, -4, 22, -15, -5, 1, 17, -17, -8, 28, -15,
+ -8, 6, -10, 2, 7, 8, -31, 25, 3, -20, -2, 26, -10, -22, 12, 20,
+ -25, 6, -11, 33, -36, -2, 43, -36, -8, 20, -9, -7, 2, 4, 5, -7,
+ -5, 24, -28, 11, 6, -24, 20, -7, -2, 6, -9, -1, 20, -35, 13, 27,
+ -31, -7, 31, -13, -12, -6, 27, -14, -24, 33, -6, -10, 15, -14, 6, -13,
+ 9, 0, -8, -1, 19, -20, 6, 10, -9, -15, 23, -20, -4, 31, -24, 2,
+ -13, 23, 1, -25, 14, 12, -16, -18, 25, 4, -25, 15, -3, 2, 6, -16,
+ 21, -12, -19, 19, 1, -18, 21, 1, -30, 25, 3, -15, -5, 6, 18, -34,
+ 4, 32, -13, -18, 1, 28, -21, -30, 44, -1, -41, 28, 16, -32, 9, 14,
+ -17, 6, -11, 5, 21, -43, 38, -11, -24, 39, -15, -18, 18, -3, -15, 0,
+ 20, -15, 2, -1, -6, 32, -43, 13, 19, -26, -3, 17, 10, -29, 19, 1,
+ -19, 22, -13, 7, -16, 10, 8, -17, -1, 12, 1, -18, 1, 40, -49, 6,
+ 34, -35, -8, 30, -2, -23, 4, 15, 12, -39, 2, 55, -57, -8, 47, -27,
+ -7, 18, -7, 2, -11, 0, 19, -21, 4, 2, 10, -32, 34, -16, -12, 20,
+ -12, 2, -4, 20, -12, -22, 22, -14, 9, -12, 6, 21, -24, -7, 27, -13,
+ -22, 13, 16, -38, 37, -2, -21, 19, -14, 2, -6, 6, 7, -16, -11, 44,
+ -22, -35, 52, -10, -41, 24, 16, -13, -19, 14, 21, -20, -29, 55, -20, -21,
+ 5, 28, -30, -3, 22, -6, -10, 5, 11, -11, -7, 15, -11, -4, -10, 18,
+ 1, -23, 24, 3, -24, 10, 5, 0, -32, 35, -7, -12, 1, 11, 18, -53,
+ 36, 7, -26, 0, 24, -27, 0, 26, -24, 6, 6, -13, 16, -21, 13, 1,
+ -25, 20, 26, -61, 40, 21, -41, -6, 28, 1, -24, -7, 38, -14, -25, 20,
+ 5, -16, -1, 6, 13, -20, -7, 39, -33, -8, 25, -14, 5, -20, 26, 2,
+ -28, 14, 14, -18, -23, 64, -60, 11, 24, -9, -13, -2, 17, -5, -25, 16,
+ 22, -13, -44, 61, -14, -38, 35, -7, -18, 28, -16, -10, 25, -9, -20, 8,
+ 6, 8, -23, 11, 19, -27, -1, 15, 0, -25, 18, 8, 2, -34, 38, 1,
+ -41, 23, -7, 13, -6, -19, 45, -20, -27, 24, 14, -61, 53, -13, -13, 21,
+ -21, 36, -25, -33, 58, -33, -26, 35, 19, -50, 7, 50, -35, -20, 28, 5,
+ -29, -1, 28, -20, 3, -10, 20, -8, -16, 35, -22, -13, 17, -10, -3, 15,
+ -25, 24, -7, 0, -8, -3, 29, -32, -7, 30, -16, 9, -29, 24, 10, -27,
+ -9, 49, -40, 4, 14, -28, 37, -29, -18, 68, -67, 12, 45, -48, 3, 31,
+ -21, -16, 9, 20, -3, -40, 38, 17, -65, 41, 8, -15, -9, -2, 46, -51,
+ -7, 64, -51, -31, 57, -21, 5, -10, -7, 35, -36, 0, 20, -20, 14, -16,
+ 10, 9, -1, -26, 26, -18, -3, 5, 14, -8, -17, 32, -25, 1, 17, -29,
+ 17, 17, -47, 50, -19, -12, 9, -1, -11, 17, -29, 44, -25, -36, 63, -32,
+ -18, 29, -7, 9, -38, 32, 14, -50, 21, 37, -57, 13, 37, -17, -16, -9,
+ 28, -6, -60, 76, -13, -34, 29, 1, -5, 9, -41, 35, -2, -48, 52, -5,
+ -3, -17, 14, 5, -12, -13, 24, -20, 7, -4, 10, 2, -13, 10, -2, -18,
+ 20, 2, -33, 37, -18, -9, 25, -21, 14, -15, 9, -2, -14, 15, 10, -44,
+ 37, 7, -36, 15, 18, -9, -21, 2, 45, -53, 3, 47, -48, 3, 25, -17,
+ 14, -24, -2, 53, -72, 22, 38, -32, -13, 22, -15, 30, -36, 6, 27, -30,
+ -4, 21, -3, -20, 8, 13, -3, -29, 43, -10, -41, 33, -14, 20, -22, 9,
+ 13, -14, -10, 25, -30, 14, 6, -29, 29, 2, -23, 4, 14, -15, -3, 13,
+ 11, -29, 21, -1, -25, 13, 5, 1, -9, -18, 58, -31, -44, 56, 7, -69,
+ 46, -10, 11, -3, -27, 41, 1, -58, 46, 7, -33, 14, -14, 30, -22, -24,
+ 77, -66, 6, 6, 27, -36, -2, 21, 10, -62, 57, 11, -46, 23, 7, -8,
+ -18, 24, -21, 17, -35, 40, -4, -31, 36, -13, -10, 0, -2, 2, 0, 2,
+ -14, 18, 22, -53, 11, 43, -45, -13, 39, -7, -12, -6, 22, -8, -27, 19,
+ 15, -35, 13, 21, -30, 26, -35, 40, -17, -11, -5, 33, -25, -4, -9, 32,
+ -10, -44, 65, -23, -18, 0, 28, -31, 17, -23, 45, -50, 11, 52, -68, 13,
+ 23, -10, -32, 41, -13, 4, -13, 5, 9, -11, 4, -8, 6, 12, -25, 4,
+ 24, -20, -15, 11, 30, -42, 5, 30, -7, -40, 27, 17, -27, -5, 14, 16,
+ -26, -9, 39, -23, -11, 17, -16, 30, -52, 43, -9, -4, -28, 31, 4, -15,
+ -15, 34, 6, -69, 65, -3, -40, 6, 42, -40, 8, 11, 18, -29, -28, 62,
+ -40, -17, 31, 2, -22, 20, -13, 16, -18, 0, -6, 12, -4, -10, 17, 0,
+ -6, -25, 44, -25, -6, 0, 24, -13, -33, 43, 1, -46, 36, 3, 0, -34,
+ 38, -11, -14, 5, -11, 30, -19, 3, -12, 45, -56, -3, 41, -20, -21, 17,
+ 22, -18, -15, 14, 37, -92, 53, 25, -48, -2, 57, -44, -4, 3, 35, -31,
+ -32, 59, -24, -17, 9, 28, -39, 22, -10, 9, -7, 0, 7, -29, 33, -16,
+ -17, 37, -24, -17, 43, -14, -28, 18, 18, -33, 5, 4, 21, -34, 13, 4,
+ -6, 7, -15, 14, -8, 11, -17, -1, 15, 0, -42, 58, -18, -35, 37, 14,
+ -47, 9, 27, -14, -33, 20, 58, -79, 11, 49, -18, -55, 58, -6, -29, 6,
+ 12, 16, -55, 61, -29, -20, 37, -15, -1, 9, -26, 22, 3, -25, 0, 31,
+ -18, -1, -12, 40, -11, -64, 62, -11, -23, 3, 32, -11, -18, 19, 5, -36,
+ 15, 11, -21, 6, 18, -16, 5, 16, -35, 14, -2, 19, -53, 45, 31, -81,
+ 31, 46, -51, -14, 44, -13, -23, -11, 67, -62, -3, 50, -23, -26, 24, 16,
+ -34, -2, 3, 27, -33, 1, 38, -35, 13, 0, -24, 50, -59, 11, 31, -20,
+ -6, 10, 20, -28, -15, 38, -2, -60, 43, 32, -68, 24, 47, -54, 9, 3,
+ 23, -46, 11, 36, -56, 34, -2, -20, 12, 24, -36, 9, 7, 18, -45, 11,
+ 45, -50, -10, 42, 4, -63, 62, -10, -22, -9, 26, 8, -52, 41, 14, -54,
+ 41, -9, -8, 12, -26, 33, -25, 6, 3, -14, 20, -28, -2, 50, -23, -51,
+ 64, 11, -86, 57, 17, -39, -5, 19, 41, -79, 33, 43, -64, 2, 40, -21,
+ -7, -6, 38, -37, -8, 43, -39, 5, 16, 3, -49, 67, -38, -20, 39, -20,
+ 10, -24, 43, -15, -47, 57, -13, -53, 59, -16, 8, -27, 35, -4, -36, 35,
+ -29, 13, -5, 5, -13, 32, -5, -48, 57, -29, -15, 30, -26, 23, -34, 33,
+ 25, -79, 54, 25, -70, 16, 33, -1, -60, 37, 52, -76, 7, 54, -22, -61,
+ 76, -23, -30, 30, -15, 14, -21, 24, -4, -20, 23, 0, -49, 63, -31, -12,
+ 28, -15, 9, -17, 26, -25, -1, 4, 15, -31, 22, 8, -23, 18, -8, -7,
+ 6, -1, 7, -12, -1, 32, -62, 42, 14, -59, 41, 13, -31, -5, 40, -14,
+ -49, 36, 38, -64, 1, 68, -54, -29, 61, -16, -29, 8, 37, -22, -33, 42,
+ 18, -75, 47, 6, -25, 26, -33, 42, -32, 1, 4, 3, -2, 5, -20, 27,
+ 4, -43, 33, 2, -27, 6, 26, -25, 8, 2, 19, -46, 26, 15, -56, 44,
+ 12, -34, -4, 43, -34, -1, 2, 27, -40, -3, 52, -64, 26, 21, -30, -3,
+ 30, 1, -37, 13, 27, -28, -31, 49, 4, -63, 61, 2, -23, -10, 22, 7,
+ -53, 17, 43, -51, 21, 15, -26, 37, -31, -4, 9, 0, -28, 28, 4, -10,
+ -5, 21, 2, -40, 32, 9, -50, 20, 43, -63, 32, -6, 13, -24, -4, 62,
+ -87, 46, 12, -27, -14, 25, 13, -44, 25, 24, -29, -8, 13, 18, -56, 46,
+ 6, -51, 55, -19, -10, -4, 17, 3, -52, 60, -3, -49, 41, -14, 0, -4,
+ -3, 17, -9, -9, 1, 18, -11, -17, 3, 17, -5, -23, 15, 42, -83, 51,
+ -1, -17, 6, -16, 57, -83, 48, 16, -46, 10, 24, -8, -32, 32, 15, -49,
+ 26, 19, -24, -22, 40, 20, -80, 64, -11, -24, 14, -11, 17, -18, 18, -5,
+ -21, 45, -36, -11, 24, -16, 5, -10, 32, -13, -17, 24, -15, -4, -8, 9,
+ 0, -16, 33, -36, 36, -7, -39, 46, -35, 33, -61, 51, 10, -63, 50, 11,
+ -34, -5, 39, -8, -46, 41, 6, -45, 22, 14, -4, -41, 74, -33, -44, 57,
+ -19, -20, -12, 42, -4, -37, 30, 18, -31, 0, -1, 10, -16, 3, 8, 1,
+ 9, -31, 21, -2, -11, -1, 3, 24, -40, 15, 31, -52, 20, -1, 13, -32,
+ 31, 6, -44, 41, -17, -18, 21, 18, -32, -10, 41, -2, -60, 42, 9, -25,
+ -9, 38, -10, -29, 40, -27, -7, 14, 8, -20, -2, 26, -11, -35, 42, -2,
+ -36, 28, -1, 3, -33, 39, -7, -24, 9, 4, 4, -10, 7, -2, 0, 15,
+ -52, 45, 4, -38, 14, 29, -20, -23, 39, -1, -38, 13, 23, -26, -1, 12,
+ 2, -30, 41, -10, -30, 36, -3, -22, -6, 35, -20, -32, 27, 22, -41, 19,
+ 23, -18, -18, 22, -5, -34, 39, -19, 5, -3, 29, -26, -21, 47, -38, -23,
+ 38, -4, -15, 6, 19, -12, -4, 6, -14, 17, -14, -11, 22, 3, -20, -13,
+ 38, -2, -52, 43, 16, -30, -19, 37, 1, -51, 47, 2, -23, -1, 22, -10,
+ -24, 17, 21, -62, 51, 11, -38, 19, 8, -3, -50, 61, -18, -15, 4, 16,
+ -9, -15, 29, -32, -2, 37, -43, 9, 35, -36, 13, -16, 28, -28, -5, 41,
+ -35, -3, 12, 15, -29, 2, 19, -20, 19, -21, 7, 18, -20, 1, -24, 47,
+ -17, -45, 54, 10, -43, 0, 37, -3, -63, 58, 4, -55, 43, -2, -6, -31,
+ 50, -35, -10, 37, -12, -17, 1, 29, -34, -5, 31, -19, -10, 29, -26, 32,
+ -44, 25, -5, -27, 43, -45, 33, 12, -29, -6, 38, -18, -34, 23, 18, -21,
+ -12, 17, 27, -52, 18, 32, -49, 42, -19, -24, 40, -26, -7, 0, 32, -12,
+ -44, 69, -18, -46, 21, 26, -41, -5, 49, -24, -8, 22, 0, -23, -17, 32,
+ -6, -42, 64, -40, 17, 0, 3, -11, -28, 63, -61, 13, 26, -12, -7, 4,
+ -5, 8, -2, -5, -14, 18, 13, -38, 6, 36, -7, -71, 86, -10, -56, 45,
+ -11, -2, -18, 9, 26, -38, 24, 1, -24, 41, -35, -10, 24, -1, -24, 10,
+ 25, -15, -20, 10, 36, -44, -32, 96, -69, -8, 44, -32, 12, -20, 33, -33,
+ 11, 24, -24, -15, 40, -23, -27, 20, 18, -19, -4, 28, -23, 9, -9, 4,
+ -19, 32, -27, -15, 59, -37, -17, 28, 2, -20, -12, 28, 20, -68, 46, 2,
+ -24, 3, 6, 16, -28, 17, 8, -21, 1, 6, -21, 15, 34, -68, 43, 41,
+ -81, 31, 10, -5, -28, 1, 51, -37, -21, 64, -40, -23, 44, -25, -12, 15,
+ 7, -21, 14, 0, 6, -29, 29, 7, -39, 30, -10, 0, -4, -5, 13, 8,
+ -24, 23, -28, 38, -27, -34, 50, -5, -33, 10, 55, -47, -22, 43, -3, -45,
+ 11, 38, -37, 15, 16, -25, 24, -22, -4, 0, 4, 14, -41, 33, 35, -67,
+ 13, 52, -57, 0, 25, -4, -7, -11, 18, 5, -37, 32, 2, -39, 54, -24,
+ -18, 13, 16, -27, -2, 7, 31, -52, 29, 17, -41, 38, -23, -15, 28, -4,
+ -28, 40, -13, -20, 8, 13, 0, -40, 37, 20, -53, 14, 39, -34, -21, 27,
+ 14, -28, 12, 14, -23, 7, 3, -28, 24, 6, -23, 10, 9, 20, -39, -12,
+ 61, -39, -44, 74, -24, -25, 21, 13, -31, 10, 11, -3, -21, 19, 7, -43,
+ 46, -26, -2, 22, -16, 0, 13, -16, 10, -9, -20, 33, -30, 29, -2, -29,
+ 44, -8, -62, 54, 13, -50, 8, 34, 7, -43, 9, 41, -34, -39, 54, -6,
+ -28, 9, 20, -16, -6, 25, -30, -6, 45, -51, 4, 36, -21, -22, 28, 4,
+ -25, 18, 6, -5, -33, 37, -9, -19, 14, 8, -5, -4, 5, -1, -13, 0,
+ 16, -46, 49, -5, -25, 30, -8, -16, 15, -17, -4, 24, -26, 14, -8, 16,
+ 3, -40, 16, 47, -78, 21, 65, -53, -20, 24, 26, -55, 6, 55, -47, -6,
+ 35, -4, -28, 14, 1, -19, 15, -9, 20, -22, 19, -6, -31, 32, 7, -36,
+ 14, 20, -18, -7, 9, 9, -27, 22, -15, 8, 9, -15, 2, -2, 9, -19,
+ 11, 5, 11, -38, 38, -4, -35, 23, 17, -48, 34, 15, -51, 41, -2, -11,
+ -30, 35, 20, -65, 33, 34, -37, -23, 48, -2, -48, 21, 19, -12, -34, 42,
+ 8, -49, 33, 10, -27, 25, -15, -6, 9, -11, 7, -14, 22, -7, -11, 18,
+ 4, -18, -12, 30, -40, 14, 16, -11, -2, 30, -36, 4, 20, -19, -25, 21,
+ 17, -39, 38, -11, 13, -32, 19, 13, -49, 41, -2, -25, 8, 24, -23, -16,
+ 41, -9, -44, 34, 28, -48, -15, 59, -22, -54, 64, -6, -10, -20, 29, 4,
+ -56, 42, 7, -31, 20, 0, -5, 9, -3, -27, 33, -15, -18, 25, 5, -21,
+ 10, -6, -4, 1, 5, 14, -42, 47, -10, -14, -15, 30, -6, -53, 64, -4,
+ -33, 13, 27, -34, -16, 37, -4, -42, 38, 11, -35, 11, 17, -10, -33, 55,
+ -35, -6, 14, 20, -35, -11, 63, -52, -17, 55, -22, -23, 19, -2, 0, -5,
+ -10, 21, -5, -14, 12, 1, -10, 6, -15, 11, 13, -37, 43, -14, -17, 11,
+ 10, -13, -28, 43, -15, -25, 35, 11, -45, 20, 25, -34, -21, 51, -16, -42,
+ 35, 18, -23, -32, 75, -47, -18, 34, -1, -28, 1, 34, -40, 16, 23, -26,
+ 4, 18, -22, -4, -7, 18, -8, -25, 41, 0, -24, 13, 9, -30, 14, -4,
+ -14, 30, -18, 5, 9, -12, -3, -8, 25, -22, -18, 50, -18, -43, 48, 0,
+ -39, 11, 27, -14, -26, 42, -10, -33, 4, 61, -72, 7, 58, -40, -22, 28,
+ 24, -62, 19, 31, -22, -23, 41, -13, -16, 5, 11, -13, -4, 23, -21, 4,
+ 7, -8, -20, 33, -19, -10, 26, -7, -13, 2, 18, -21, -10, 28, -20, -15,
+ 54, -36, -26, 56, -30, -32, 42, -5, -21, 1, 40, -26, -19, 29, 7, -59,
+ 34, 24, -43, 20, 3, 12, -36, 23, 23, -48, -1, 61, -49, -25, 62, -27,
+ -23, 19, 13, -17, 4, 0, 9, -29, 19, -5, -7, 13, -9, 17, -7, 0,
+ -14, 11, -5, -17, 2, 35, -29, -10, 45, -27, -21, 31, -9, -17, 12, 5,
+ -10, -12, 26, 0, -37, 34, 6, -36, 18, 8, -2, -42, 39, 16, -47, 25,
+ 37, -57, 1, 51, -59, 13, 19, -10, -10, 11, 11, -8, -32, 42, -19, -36,
+ 59, -26, 1, -7, 17, -14, -2, -1, -2, 5, -5, 4, 0, 15, -25, -3,
+ 30, -28, -15, 36, -13, -5, -13, 26, 2, -45, 41, 2, -38, 21, 20, -29,
+ -11, 46, -27, -35, 46, 3, -38, 20, 25, -48, 19, 18, -26, 5, 3, 10,
+ -17, -13, 46, -29, -27, 52, -40, 18, -6, 9, -14, -8, 21, -11, -11, 16,
+ 14, -42, 33, 5, -31, 14, 0, -14, 19, -9, 11, -5, 2, 2, -39, 58,
+ -35, -26, 47, -1, -40, 19, 32, -36, -14, 37, -2, -40, 18, 32, -47, -6,
+ 49, -34, -7, 36, -16, -15, 2, 22, -36, -5, 53, -56, 27, 6, 2, -13,
+ -8, 28, -40, 4, 22, -2, -33, 46, -14, -36, 51, -10, -47, 40, -2, -18,
+ 3, 11, 13, -50, 57, -33, -5, 30, -31, -4, 19, -3, -17, 20, -2, -8,
+ -16, 34, -6, -45, 30, 35, -73, 21, 55, -52, 3, 11, 19, -42, -2, 55,
+ -57, 13, 23, -11, -16, 12, 16, -45, 25, 9, -22, -2, 37, -23, -29, 49,
+ -24, -27, 46, -23, -8, 22, -14, 6, -26, 45, -42, -9, 41, -15, -12, 11,
+ 13, -25, -1, 10, 9, -42, 37, -2, -20, 17, 14, -41, 25, 17, -52, 45,
+ -14, 1, -23, 21, 30, -74, 44, 35, -53, -4, 42, -18, -36, 30, 9, -26,
+ 17, 15, -18, -12, 37, -32, -25, 48, -27, -6, 20, -8, 12, -32, 38, -22,
+ -17, 36, -18, -13, 15, 7, -22, 14, -3, 5, -21, 33, -18, -18, 17, 12,
+ -31, 10, 34, -51, 33, -12, 15, -23, 1, 19, -50, 51, -7, -41, 47, 11,
+ -56, 20, 30, -23, -34, 37, 17, -29, -14, 54, -25, -45, 50, -16, -17, 11,
+ 14, -2, -30, 44, -16, -32, 39, -18, -16, 26, -5, -22, 25, -7, 1, -18,
+ 27, -8, -21, 23, 0, -30, 16, 27, -54, 46, -1, -24, -9, 28, 8, -62,
+ 48, 6, -31, 13, 17, -25, 17, -16, -1, 9, 2, 0, -15, 12, 19, -42,
+ -2, 57, -56, -2, 47, -11, -40, 21, 38, -56, -22, 71, -26, -41, 52, 3,
+ -29, 14, -1, -7, -20, 29, -3, -34, 41, -1, -35, 26, 12, -38, 25, -6,
+ -4, 7, -9, 6, -14, 31, -24, -7, 24, 3, -47, 33, 9, -28, -7, 23,
+ 18, -44, 22, 29, -48, 1, 46, -52, 14, 21, -21, -9, 26, 3, -41, 20,
+ 34, -52, -14, 75, -39, -40, 53, 0, -35, 6, 29, -15, -36, 44, 0, -39,
+ 36, -15, -11, 25, -9, -8, 6, 0, 1, -30, 29, -1, -17, 12, 20, -34,
+ 17, 4, -35, 29, -4, -10, -8, 35, 0, -45, 34, 18, -77, 45, 22, -29,
+ -9, 24, 14, -50, 29, 15, -34, -1, 47, -52, 3, 58, -54, -12, 40, -7,
+ -28, 10, 33, -22, -50, 79, -24, -38, 25, 10, -5, -30, 27, 16, -42, 15,
+ 14, -19, 11, 6, -33, 35, 2, -46, 49, -20, -7, 13, -4, 0, -12, 14,
+ 3, -50, 58, -8, -44, 40, 17, -22, -41, 60, -13, -48, 25, 50, -62, -3,
+ 71, -55, -12, 23, 3, -20, -1, 13, 20, -50, 48, -27, -23, 57, -43, -5,
+ 8, 30, -34, -16, 51, -18, -42, 35, 19, -40, 23, 0, -35, 39, -23, 0,
+ 21, -24, 16, -6, 2, 14, -53, 43, 1, -46, 51, -2, -19, 3, 25, -32,
+ -11, 24, -1, -34, 25, 42, -74, 29, 42, -41, -34, 56, -3, -32, -26, 84,
+ -35, -72, 101, -39, -13, 5, 24, -31, -2, 21, -25, 2, 22, 0, -37, 43,
+ 2, -41, 23, -6, -9, 9, -7, 24, -19, -8, 24, -33, 31, -11, -37, 57,
+ -25, -22, 35, -2, -29, 2, 26, -1, -39, 20, 51, -72, 14, 45, -45, -17,
+ 49, -30, -12, 24, 25, -48, -23, 107, -96, -10, 61, -7, -47, 22, 34, -35,
+ -13, 21, 17, -55, 40, 12, -43, 23, 6, -21, 19, -10, -4, 10, 3, -2,
+ -35, 38, -7, -29, 31, 1, -15, 15, -11, 5, -8, -3, 10, -30, 40, 10,
+ -62, 43, 30, -80, 22, 59, -63, -6, 42, 4, -35, -2, 67, -87, 21, 44,
+ -44, -6, 34, -6, -39, 26, 28, -26, -47, 87, -25, -74, 69, 15, -63, 22,
+ 19, 3, -13, -14, 36, -30, 1, 5, -9, 9, 3, -14, 29, -9, -25, 14,
+ 6, -6, -38, 54, -12, -38, 46, 14, -70, 48, 19, -68, 37, 25, -27, -25,
+ 29, 39, -81, 27, 50, -53, -12, 44, -4, -46, 23, 27, -32, -24, 67, -34,
+ -36, 65, -33, -31, 52, -22, -23, 21, 8, 18, -61, 46, 14, -59, 26, 31,
+ -49, 24, 11, -27, 30, -29, 8, -7, 20, -20, -4, 11, 0, -1, 0, -1,
+ 0, -1, 1, -2, 2, -1, -4, -2, 1, 19, -2, -20, 3, -10, -11, 12,
+ 3, -10, -3, 25, -4, 1, 6, 4, -12, 10, 2, -4, -28, -11, 9, 2,
+ 1, 18, -9, -20, 12, 11, 10, 1, -5, 5, -15, 4, 7, -27, -3, 4,
+ -8, 38, -31, -15, 7, 13, -34, 37, -6, -19, -6, 20, 41, -31, -20, 28,
+ -13, 30, -4, 0, -23, -1, 0, -13, 21, 3, -32, 19, 30, -52, 18, -24,
+ -27, 31, -14, 4, 1, -16, 14, 12, -20, 32, 14, -41, 37, -6, -5, 1,
+ 27, -34, 42, 9, 2, -34, 20, -25, 11, 15, -10, -14, -19, -24, 5, -12,
+ 3, -17, 2, 46, -13, -15, 31, -23, -16, 21, 25, -6, -36, 10, 1, 26,
+ -18, -12, 1, 21, -8, 17, -16, -29, -39, 17, -5, -1, -4, -6, -18, 33,
+ -21, 24, -17, 31, 0, 4, 0, 6, -26, 18, 24, 46, 5, 19, -10, 11,
+ 25, -13, 10, 50, -50, -52, 21, -23, -29, -8, 34, -35, -39, 15, -16, -43,
+ -5, -29, 29, -1, -8, -30, 18, 5, -14, 52, 12, -4, -28, 19, 25, 25,
+ 16, -44, 53, -20, 49, -23, 25, -32, 1, -63, 50, 37, -52, -13, 13, 4,
+ -18, 22, -56, 7, 23, -46, -7, 39, -69, -15, 26, 28, 21, 9, -64, 55,
+ 23, -34, 46, -26, -9, 36, -31, 4, 5, 37, -58, 28, 49, -25, 20, -1,
+ -12, -25, -6, 12, 9, -23, -34, 0, -2, 14, 3, -4, -13, 25, 23, -11,
+ 1, -34, 6, 9, 30, -36, -19, 11, -16, 14, 76, -97, 33, 25, -50, 8,
+ 25, -35, 20, -20, 4, -27, 63, -73, 25, 35, -22, 7, -33, 13, 2, 6,
+ -3, 5, 1, 17, 1, -36, 40, -4, 10, -28, -9, 14, -16, 5, 20, -32,
+ -45, 59, -10, 26, -29, -10, -13, -32, 44, -74, 81, -51, -12, 66, -11, -33,
+ 17, 38, 12, 57, -39, 5, 39, 9, -4, 4, 0, 25, -50, 24, -19, -1,
+ -30, -21, 24, -46, -20, -35, 19, -10, 1, -45, -7, 29, -8, -70, 51, -4,
+ -51, 42, 20, 21, 21, -24, 7, 69, 1, 17, 10, 9, 8, 16, -8, 66,
+ -32, -13, -24, 30, 50, -86, -15, 34, -23, -56, -26, 7, 22, -45, 23, -41,
+ 50, -84, -19, 50, 0, 2, -20, -31, 49, -12, -8, 12, 63, -20, -23, 57,
+ -37, 85, -57, -29, 83, -11, -15, -29, 25, -44, 33, -51, 74, -56, 63, -99,
+ 72, 15, -40, -41, -29, 68, -66, 46, 12, 21, -65, 5, 62, -24, -24, -15,
+ 7, -25, 7, -4, -16, 47, 13, -38, 3, 55, -31, -40, 31, -1, -35, 22,
+ 4, 34, -6, -1, -12, 6, 75, -51, 12, 57, -19, -24, -5, 12, -10, 26,
+ -13, 10, -44, 25, -13, -26, 39, -42, -25, -65, 36, -55, -41, -12, 2, 8,
+ 22, 22, -24, -27, 51, -38, 36, 1, -14, -8, 88, 2, 15, 28, 6, 46,
+ 8, 32, -22, 37, -29, 10, 3, -36, 9, -9, 2, 6, -15, -79, 32, -15,
+ -26, -4, -29, -28, 7, 16, -29, -27, 3, 8, 2, 9, 5, 1, -13, 38,
+ 16, 26, -16, 0, 19, -14, 20, -29, -3, 43, 17, -14, 39, -34, -15, 24,
+ 36, -27, -1, 7, -55, 24, 50, -43, 21, 5, -5, -122, 78, -43, -33, 12,
+ -12, 9, -45, -3, -1, -22, 37, -3, 17, -35, -11, 32, 5, 62, 0, -4,
+ 20, 18, -33, 93, 2, -77, 45, 33, -29, -35, 45, -55, 48, -12, 15, -54,
+ 16, -3, -50, 1, -21, -39, 16, -1, -33, -38, 19, -45, 9, 34, 26, -15,
+ 21, 60, -32, 7, -2, 24, 21, 28, -19, -12, 7, 60, 23, -23, 7, -44,
+ -54, 54, -17, -42, 38, -24, -23, 18, 9, -31, 4, 24, -26, -27, 33, -53,
+ 15, 26, -38, 11, 13, -39, 24, 32, 19, 14, 16, -27, -24, 14, 14, 9,
+ 6, -48, -8, -8, 60, -39, 1, -32, 51, -34, 0, 33, -16, -33, -10, 60,
+ -40, -1, 3, 31, 50, -16, -32, -40, 45, -34, -8, 54, -80, 0, 19, 21,
+ -21, 87, -70, -19, 23, 25, -56, 40, -33, 19, -44, -8, 7, -12, 18, -20,
+ 22, -10, 18, 5, -7, 26, 33, -65, 49, -9, -9, 27, 22, 22, -37, 18,
+ -19, -1, 61, -23, -39, 4, 4, -32, -3, 27, -39, -3, 38, -19, -12, -8,
+ -37, 3, -10, -14, -37, 0, 4, 24, 1, 33, -35, 29, -2, 24, 24, -21,
+ 23, -3, -31, 47, 12, -26, 35, -19, -17, 22, 20, -27, 1, -16, -18, 17,
+ -2, -19, -22, 25, -2, -11, -3, -60, -2, 30, 64, -76, -7, -29, 45, 1,
+ 46, -23, -43, 2, 43, 68, -38, -8, 45, -7, -8, 15, -47, -27, 71, -12,
+ -3, -17, -54, -29, 75, -51, 8, -27, 12, -18, 60, -29, -42, 22, 51, -32,
+ -27, 28, -11, 48, -34, 30, 26, -19, 20, 14, -16, 2, 7, -36, 70, -14,
+ -21, -39, 82, -50, -49, 33, -28, 9, -17, -15, -51, 5, 7, -17, 58, -29,
+ -33, 2, 29, 14, -46, 3, 28, 2, 28, -22, 7, -3, 28, 2, 40, -71,
+ 2, 23, 24, 19, 11, -62, 56, 1, -24, -7, -10, -26, 30, -49, 18, -40,
+ 52, -51, 46, -3, -28, -26, 40, 11, -5, 8, -46, 25, -10, 34, -25, 44,
+ -17, -7, 12, 12, -28, -19, 30, -26, 6, -38, 13, 45, -43, 24, 24, -49,
+ -13, 19, 3, 27, -5, -8, 5, -6, -4, 39, 7, 1, -38, 22, 20, -20,
+ 19, -24, -50, 47, -11, -25, 32, -59, 17, 12, 35, -50, -14, -7, 15, 33,
+ -15, 11, -45, 10, 14, 50, -68, -4, 11, -35, 20, 88, -72, 40, 16, -9,
+ 3, 55, -44, 25, -24, 6, 14, -66, 9, 7, -10, 9, -7, 1, -42, -24,
+ -26, 74, -5, -23, -44, 12, 11, 12, 57, -60, -19, 7, -2, 40, 3, -26,
+ -14, 44, 29, 7, -23, 21, -32, 42, 13, -30, -16, 36, -9, 3, -21, 17,
+ -67, 30, -4, 23, -19, 8, -32, 5, 31, -4, -26, 18, -24, 6, 39, -7,
+ -24, -2, -5, 6, -3, 11, -10, -6, 16, -15, -15, 5, -19, -17, 38, -27,
+ 35, -48, 7, -20, 4, 12, 1, -33, 28, -24, -2, 28, -10, -11, 23, -2,
+ 5, 21, -5, 8, 0, 21, 12, -24, 36, -40, 36, 29, -2, -19, 1, 3,
+ -8, 9, -11, -13, -31, 26, -5, 23, -26, -30, 1, 30, -19, -2, -15, 3,
+ 5, 5, -3, 3, -43, 38, 16, -30, 18, 12, -1, -4, 20, -47, 11, 1,
+ 21, -15, 1, 0, -43, -5, 37, -28, 11, -51, 21, 2, 20, -24, 22, -46,
+ 34, -1, 7, 27, -12, -24, 28, 39, -4, 10, -19, 8, 6, 37, -26, 2,
+ -12, -32, 36, 17, -11, -14, -26, -1, 17, 17, -53, -10, -11, 23, -16, -26,
+ 10, -33, 1, 61, -5, -21, -14, -28, 50, 13, -41, 17, -12, 38, -19, 24,
+ 36, -75, 16, 1, 58, -15, -19, -33, 56, -40, 39, -18, 1, 0, -34, 11,
+ 32, -6, -52, 32, 2, 39, -31, -23, 0, -11, 10, -26, 55, -6, -51, 0,
+ 36, -33, -14, -9, 30, -11, -5, 14, -17, 6, -34, 28, 16, -3, -21, 7,
+ 25, 13, -30, 14, 12, 33, 3, -16, 9, -12, -17, 15, 2, 23, 14, -46,
+ 1, 13, -4, -19, 6, 30, -53, -13, 1, -17, 13, -38, 11, 20, 1, -24,
+ 19, -10, 7, -28, 48, 25, -59, -33, 51, 12, -4, -3, 13, -23, 64, 0,
+ -5, -24, -6, 21, -27, 28, -19, -29, 51, -24, -9, -12, 3, -3, 35, 6,
+ -33, -37, -5, 45, -47, 30, -16, -9, -10, 51, -31, 32, 10, -22, -10, 8,
+ -13, -28, 8, 15, -25, 39, -36, 2, 50, -30, 36, -40, -14, 35, -9, -3,
+ 12, -25, 36, -7, -20, -6, 48, -5, 31, -4, -18, -48, 67, -47, 26, -30,
+ 6, 9, -14, -29, 3, 23, -12, -27, 29, -22, -36, -9, 51, -30, -18, -16,
+ 47, -4, -25, 18, 16, 13, -11, 15, 10, 2, -36, 42, 3, -9, -21, 52,
+ -19, 18, -34, -3, -11, 23, 19, -13, -17, -19, 16, -1, 0, -32, -1, -4,
+ 25, 9, -37, -3, -9, 45, -15, -29, 36, 4, -29, -9, 35, 16, -36, -21,
+ 25, -12, 10, -21, 25, 5, -17, -8, 12, 35, -56, 4, -15, 47, -32, -5,
+ 18, 3, 11, 2, 7, 1, 1, -24, 23, 6, 7, -46, -37, 73, 12, -2,
+ -20, 34, -45, 32, -23, 15, -40, -34, 12, 4, 13, -39, 3, 23, 17, -24,
+ -15, 16, 19, -30, -9, 12, 53, -64, 1, 23, 40, -11, 8, 33, -36, 42,
+ -68, 71, -16, -10, -41, 22, 16, -19, -18, 26, -2, 1, 4, -21, -3, -16,
+ -4, 16, -31, 1, -26, -5, -8, 43, -69, 28, 14, 10, -16, 21, -18, -2,
+ -14, 0, 32, 23, -28, -21, 68, 0, -40, 24, 32, 1, -10, 8, -20, 32,
+ -37, 16, -3, 24, -10, -5, -30, 35, -39, 12, 6, -26, -2, -58, 65, -66,
+ 13, -10, -6, -15, 28, -27, -39, 51, -28, 16, -10, 60, -51, 30, 51, -24,
+ 11, -9, -7, 14, 39, -33, 4, -14, 25, -13, -8, 35, -40, -1, 27, -9,
+ 11, -9, -13, 5, 19, -37, -12, 23, 1, -2, -31, 37, -7, -41, 35, 16,
+ -6, -28, -8, 9, -23, 22, -8, 27, -17, -27, -10, 10, 12, -6, 11, -51,
+ 21, -19, -29, 23, -10, -4, 32, 3, 25, 7, -25, 23, 35, -21, -2, -3,
+ 23, -4, 14, 6, -8, -5, -6, 10, 10, 5, -38, -7, 16, -38, -2, 12,
+ 8, -54, 5, 18, -12, -18, 23, 17, -52, 50, -78, 11, 4, 5, 19, 7,
+ 27, -24, 5, 3, 35, -20, 34, -15, -10, 4, 21, 16, -14, 12, -8, -2,
+ 42, -30, -22, 28, -9, -34, -11, 23, -36, 0, 15, -10, 14, -37, -7, -19,
+ 30, -18, 15, -17, -14, -14, 51, -20, -8, 13, -12, 7, 35, 9, -12, -13,
+ 48, 1, -2, -32, 13, -5, 1, 15, 40, -66, 18, 1, 49, -45, -38, -8,
+ 14, -16, -2, 24, -13, -62, 15, 54, -28, -18, -3, 10, 13, -21, -18, -9,
+ 44, -13, 8, 37, 6, -18, 4, 27, -18, 21, 3, -8, 13, 27, -19, 14,
+ 2, -27, -11, -8, 17, -38, -26, 29, -31, 5, -7, -5, -9, -4, -11, 9,
+ -3, -5, -18, 16, 3, 0, -8, -2, -6, -1, 58, -11, 12, 2, 31, -21,
+ 13, 27, -17, -23, 54, 18, -33, -7, -7, 3, -2, -25, 15, -1, -25, -41,
+ -13, 46, -71, -15, 40, 10, -14, 0, -10, 18, 0, -31, 25, -8, -10, -13,
+ 24, 30, -9, 6, 4, 26, -3, 5, 31, -25, 0, -7, 16, 20, -1, -12,
+ -22, 11, -10, -3, -26, 12, 3, 2, -17, -31, 4, -26, 15, 13, 6, -22,
+ -5, 5, 8, 11, -23, 17, 17, -33, 0, 12, 21, -20, -3, 20, 21, -7,
+ -20, 38, 20, -27, -16, 3, 7, -8, -3, 0, 22, -38, -37, 26, 23, -26,
+ -8, -5, 0, -12, -2, 30, -8, -4, -2, -13, 15, -24, -4, 29, 10, 32,
+ -7, -57, 48, -13, 41, -13, 16, -20, -20, 33, -13, 26, -17, -18, 20, 10,
+ -44, 18, 2, -18, 3, -13, -5, -25, -16, 7, 30, -32, 8, -34, 19, -5,
+ 23, -28, 12, -4, -14, 30, 1, -2, 15, -20, -16, 44, -2, 34, -31, 36,
+ -25, 15, -3, 13, -10, -36, 39, -5, 0, -16, 1, 27, -28, 24, -26, -8,
+ -12, -16, 25, -2, -12, -28, 16, -17, 7, -24, 31, -15, -8, 31, -22, -7,
+ 0, 14, 16, -17, 8, -15, 24, -3, 17, -14, 6, -4, -22, 22, 9, 1,
+ 3, -21, 18, -8, 11, 0, 10, -3, -12, 3, 15, -15, 1, 2, -13, 3,
+ -23, -3, 15, -11, -5, 9, -30, -6, -10, 27, -2, -9, -12, 10, 4, 0,
+ -16, 16, -10, -27, 51, -5, -4, -1, -4, 5, 38, -18, -11, 17, 1, -2,
+ 8, 0, -7, 6, -6, -4, 9, -12, -11, 11, 1, -14, 1, -31, 13, 3,
+ -28, 12, 24, -30, 7, -6, 5, -4, -6, 8, 1, 14, -19, -1, 32, -22,
+ -9, 34, 6, -9, -9, -5, 15, 6, -25, 14, 6, -41, 0, 10, 2, 12,
+ -18, 6, 5, -1, -16, 4, 26, -33, 5, 4, -4, -9, 5, -2, 14, -10,
+ -11, 16, -6, 11, -5, -15, 14, 18, -19, 21, -24, 13, 6, -13, 21, -12,
+ -11, -2, 10, -6, -7, -13, 12, -13, 1, 10, -7, 2, -2, -21, 24, 5,
+ 2, 5, -24, 17, -17, -15, 9, 20, -12, -9, -15, 14, -1, -2, 14, -13,
+ 5, -32, 21, 10, 7, -11, 24, -1, -23, 24, -25, 31, 7, -16, -2, -4,
+ 9, -19, 17, 4, -27, 22, 21, -28, -6, 32, -48, 6, -4, 20, -6, -41,
+ 11, 31, -16, -14, 2, -8, -13, -13, 35, -15, 15, -20, 1, 26, 7, -13,
+ 18, 5, -19, 11, -7, 20, 22, -35, -11, 20, -24, 21, -20, 34, -15, -17,
+ -8, -2, 16, -9, -12, 2, 20, -31, 24, -21, 2, 12, -27, 28, -10, -5,
+ 24, 7, -29, 4, 6, -24, 33, -4, -8, -16, 1, 32, -28, 13, 7, 2,
+ -10, -38, 30, 2, -18, -2, 17, 13, -6, -46, -1, 61, -48, 18, 10, 2,
+ -17, -13, 8, 27, -8, 0, 11, -5, 20, -39, 4, 19, -8, -13, -15, 29,
+ -36, 29, -16, 14, -25, 17, -14, -15, 18, 5, 3, -5, -2, -19, 31, -12,
+ 14, -23, 31, -24, -4, 0, 4, 2, 11, -15, 22, -27, -4, 9, -8, 22,
+ -2, 7, -33, -12, -3, 30, -3, -10, 12, -19, 2, -9, 16, -4, -15, 5,
+ 32, -13, -13, 22, -11, 1, 3, 18, -12, 3, -17, 16, 15, -36, -2, 10,
+ -12, 9, -29, 14, 12, -23, 5, 39, -20, -39, 13, 14, -13, 2, -16, 43,
+ -25, -1, -12, 19, 11, -27, 0, 28, 3, -3, -15, -1, 10, -31, 43, -6,
+ 5, -10, 4, -18, 24, -6, -14, -8, -5, 4, 1, -5, -20, 21, 5, -19,
+ 22, -8, -13, -3, 20, -10, 20, -12, -7, 11, -11, -15, 6, 3, 24, -9,
+ -4, -3, -4, -20, 44, -12, -15, 4, -3, -6, 2, 9, 3, -17, -7, 9,
+ -2, 2, -22, 18, -8, -2, -10, 4, 6, -1, -4, 9, -1, 6, -9, 8,
+ 2, 4, 4, -6, 17, -32, 11, -1, 21, -7, -29, 12, 2, -35, 28, 12,
+ -15, 15, -43, 37, -30, -4, 2, 27, 8, -22, -1, -13, 20, -28, 36, -6,
+ -12, -4, -8, 14, 2, -12, 5, 12, -3, -11, 3, -1, 2, 18, 12, -11,
+ 4, -31, 13, 10, -10, 12, 7, -35, 10, -17, -3, 12, -5, 2, 0, -23,
+ 7, 5, -4, 23, -30, 2, 4, -3, 18, -16, 17, 16, -12, -3, -14, 17,
+ -1, -5, 9, 19, -23, 11, -8, -19, 34, -7, -13, 1, 3, 19, -23, -15,
+ 19, -17, 5, -24, 16, 4, -5, -7, 7, -2, -20, 4, 15, 21, -29, -7,
+ 16, -3, -17, 9, 3, 15, -15, -5, 12, -14, 8, 21, -15, 12, -18, -1,
+ 17, -19, 2, 16, 16, -11, -30, 22, -12, -12, -1, 21, -28, 29, -30, -6,
+ 19, -14, -5, 0, 10, 18, -8, -15, -1, 7, -15, 28, -3, -3, -9, -8,
+ 0, 6, 18, -32, 7, -3, -11, 6, 30, -42, 32, -13, -8, 5, 8, 8,
+ -15, 3, 4, -22, 27, -6, 6, -11, 1, -6, 13, -5, 2, -12, 29, -30,
+ 10, -15, 18, -19, 8, 21, 1, -28, 15, -20, 25, -25, -1, 11, -2, 1,
+ -22, -3, 15, 1, -22, 18, 16, -24, 1, 19, 6, 9, -7, -22, 8, -6,
+ 2, 14, -9, -4, -13, 10, -12, 13, 0, -11, -12, -2, -6, 20, -9, 4,
+ 5, -14, 3, 9, -2, 13, -5, 0, 14, -17, -1, -3, 8, -6, 7, 29,
+ -19, -13, 3, 27, -17, -8, 11, -2, -14, -9, 7, -3, -9, -14, 24, -12,
+ -35, -13, 40, -10, 1, -7, 1, 2, -1, 1, 16, 3, -13, -11, 30, 2,
+ -9, 0, -9, 2, 15, -9, 8, 3, -19, 12, 5, -21, 5, -6, 16, -4,
+ 7, -4, -2, 9, -35, 27, -6, 0, -12, 15, -29, 8, 2, -7, 4, 1,
+ -15, 28, -15, -13, 18, 4, -1, 1, -4, -7, -16, 21, -11, 25, -19, 2,
+ -10, 20, -32, 11, 6, 6, -15, 22, 8, -25, -13, 5, 20, 13, 7, -23,
+ -6, 7, -4, 4, 0, -7, 3, -10, -4, 9, 1, 3, -8, 2, 16, -22,
+ -7, -3, 12, -4, -4, 8, -10, 6, -13, -5, 3, 3, 6, 4, 4, -9,
+ -27, 1, 16, 17, -15, 0, -12, 15, -2, -6, 10, 3, -16, -16, 22, 13,
+ -12, 4, -4, 7, 11, -12, -14, 15, -1, 3, -12, 7, -7, 12, -14, 9,
+ -9, 2, 2, 9, -12, -17, 12, -17, 14, -2, -18, 2, 16, -5, 1, 8,
+ -5, -12, 0, -3, 21, -2, -17, 10, 10, -4, -16, 6, 15, -1, -25, -11,
+ 18, 0, -11, 8, 15, -16, -18, -4, 39, 3, -30, -6, 22, 2, -22, 2,
+ 21, -9, -9, 12, -3, 19, -24, -12, 20, -8, 4, 3, -3, 15, -20, -3,
+ 14, -7, -4, -14, 9, -8, 0, 7, -6, -8, -4, -3, 4, 13, -18, 0,
+ 9, -2, 5, -4, 10, 3, -9, -6, 9, -3, 1, 4, -3, 4, -11, 2,
+ -3, 5, 11, -13, -1, 4, -7, 1, -11, 1, 17, -17, 2, 13, 1, -21,
+ -2, 7, -5, -4, -5, 16, -5, -7, 4, 8, 8, -14, 4, 8, -7, -1,
+ 5, 2, -11, -9, 9, 6, -10, -2, 6, -7, -2, -1, 15, -17, -4, 5,
+ -2, 2, -3, -5, 11, -3, 1, 16, -12, -3, -7, 6, 5, -4, 5, 0,
+ -3, -15, 5, 3, -8, 9, 3, -8, 1, -6, -4, 0, -7, 21, -18, 9,
+ -8, 11, -2, -10, 10, 1, 14, -19, -11, -7, 18, -7, 4, 6, 2, -15,
+ 2, 4, 5, -3, 0, 0, 12, -2, -15, -4, 18, -7, -9, 18, -7, -6,
+ -9, 4, 7, -21, 11, -18, 14, -5, -4, 8, 5, 4, -3, -4, -11, 11,
+ -15, 19, 2, -18, 8, -4, -13, 18, 3, -14, -3, 9, -11, 2, 10, -9,
+ -5, -1, -15, 13, 16, -9, -4, 29, -15, -14, 6, 9, -1, -15, 12, 12,
+ -6, -6, 13, -10, 18, -14, 7, -12, 5, -9, -12, 16, -6, -16, 7, -1,
+ -22, 8, 2, -1, 9, 4, -31, -9, 12, 14, -9, -5, 17, -25, 7, 0,
+ 13, 4, -1, -17, 10, 13, -7, -11, 17, 2, -23, 27, 5, -10, -3, 13,
+ 5, -5, -5, -4, 0, -3, -5, 3, 4, -9, -7, 5, 4, -13, -10, 1,
+ 7, -4, -2, -3, -5, 15, -9, 0, 1, 12, -17, -6, 32, -15, -16, -11,
+ 20, 0, 2, -11, -5, 25, -21, 3, 10, 15, -24, -4, 8, -5, 0, 15,
+ -1, -7, 1, -18, 21, -7, 3, -12, 0, 12, -10, 6, -3, -2, 2, -1,
+ 9, 1, -9, 7, -9, -4, 9, -16, -4, 8, -10, 4, -3, -2, 13, -9,
+ 4, -16, 4, -3, -5, 14, 7, -8, 2, 9, 0, -2, -12, 7, -3, 2,
+ -4, -15, 11, -8, -11, -4, 23, -5, -1, 4, -9, 7, -4, 7, 8, -13,
+ -6, -4, 16, 10, -11, 8, -1, -1, 2, -5, 0, -3, -6, 2, 3, -6,
+ 13, -19, -9, 19, -11, 6, -12, 12, -10, -3, -11, -10, 14, 2, -19, 14,
+ 4, -6, 4, 11, -7, 3, -3, -8, 24, -18, 6, -8, 15, -14, -7, 19,
+ 0, -11, -3, 2, 2, 0, 2, 6, -7, -22, 16, 0, 11, -12, 7, -12,
+ 10, -16, 4, 8, -11, -11, 4, 16, -19, 13, 1, -19, 12, 19, -15, -4,
+ 9, -8, -13, 5, 14, -12, 5, -21, 7, 4, 11, -19, -1, 15, -16, -3,
+ -12, 14, 1, 1, 15, -6, -13, 7, 0, 6, 4, -11, -3, 10, 14, -20,
+ 7, 3, 1, 5, 17, -17, -5, 3, -4, 6, -1, 3, -18, 10, -10, 0,
+ 0, 14, -18, -19, 17, -23, -5, -1, 4, -4, -2, 1, -13, 26, -15, 2,
+ -10, 3, 13, 0, -6, 3, -4, 3, 0, -2, 9, 2, 9, -14, 23, -4,
+ -10, 15, 7, -16, 0, 9, 3, 0, 14, -12, 0, 4, -10, 1, -11, -13,
+ -6, 15, -14, -7, 2, -20, 4, -7, 9, -3, 2, -14, -1, 1, -1, 9,
+ -18, 10, -1, 1, -3, 22, 1, -1, 5, -4, 10, 2, 5, 0, 3, -2,
+ -1, 5, -2, -3, -5, 10, 2, -16, 2, 3, -1, -1, -11, 7, 6, 0,
+ -10, 10, -7, -2, -15, 15, 4, -25, 0, 4, 4, -12, 0, 5, -7, -6,
+ 6, 6, -8, 1, -1, -7, 17, -9, 2, 8, 4, -6, -6, 19, -5, -11,
+ 12, -12, 3, 3, -5, 9, 11, -26, 0, 0, 7, 5, -8, 11, -5, -6,
+ -16, 7, 12, -10, 0, -6, 7, -8, 3, -4, 11, -9, -16, 13, 18, -18,
+ 2, -5, 7, 5, 0, -1, 4, -9, -13, 18, 5, -4, -14, 1, 7, -5,
+ 4, -9, 15, 3, -10, -4, 5, 3, -11, -17, 18, 4, -9, -3, 3, -5,
+ -11, -3, 0, 7, -1, -8, -2, 6, -7, 7, -3, 6, 3, -12, 15, -5,
+ 23, -12, 8, -12, -4, 10, 1, 4, -3, 0, 0, 8, 0, 1, 11, -27,
+ -9, 9, -4, -3, 12, -19, -2, -8, -6, 1, -1, 2, -12, 5, -11, 3,
+ -1, -1, -10, 18, 0, 3, 2, 4, -5, 11, -3, 9, -2, -5, 7, -6,
+ 8, 10, 2, -1, -8, 1, -16, 2, 9, 1, -4, 0, -15, -5, 6, -14,
+ -9, 14, -22, 3, 7, -1, -2, -2, 0, 1, -2, 1, 9, 0, 7, -1,
+ 6, 4, 0, -6, -2, 2, 4, -9, 11, 1, -25, 9, -6, 5, 0, -7,
+ -8, 3, 5, 1, -2, 3, -9, -5, 7, 14, -12, 3, -10, 10, 3, -16,
+ -3, 26, -8, -9, -2, 15, 0, -21, 8, 11, -17, 3, 8, -8, 10, -19,
+ -3, 8, -4, 6, -10, 3, 4, -6, -4, 6, 0, 4, -19, 9, 3, -7,
+ 17, -7, 2, 3, -27, 12, 5, -14, 5, -6, -6, 6, 11, -11, 6, -12,
+ -2, 9, 8, 1, -18, 18, -9, 0, 13, -8, -10, 24, -11, 4, 13, -4,
+ -18, -3, 2, 9, -7, -1, 4, -6, 0, -11, 5, -1, -1, -8, -10, -6,
+ 6, -15, 20, 6, -25, 11, -5, -7, 12, 4, 0, -6, 6, 2, -1, 5,
+ 1, -11, 9, 20, -11, 14, -6, -15, 11, -11, 7, 1, -5, 2, -8, -2,
+ 12, -5, -16, 8, -4, -10, 2, 2, -6, -8, 5, 0, 3, 4, -17, 13,
+ 4, -9, 1, 5, 4, 8, -7, -3, 3, -2, 4, 14, -9, -6, -7, -3,
+ 11, -17, 0, 9, -10, 0, 1, 0, -9, -7, 8, 7, -3, 15, -22, 2,
+ 7, 0, 2, 4, -2, -6, -3, -1, 9, 2, -2, 1, -4, -1, -6, 2,
+ 4, -8, 3, -2, 1, 0, -9, 14, -6, -5, 3, -1, -6, 5, -5, -6,
+ 5, -5, -1, 12, -10, -6, -3, 9, -7, -8, 14, -5, -11, 9, -1, 5,
+ -5, 3, 1, 0, 1, 3, -7, 7, -1, 1, 4, 5, -16, 7, 6, -6,
+ -2, 11, -8, -9, 3, -9, -2, 15, -11, -11, 6, -1, -7, -4, 4, 2,
+ -9, 1, 1, -2, 0, 6, -3, -3, 6, -7, 6, 11, -11, -9, 0, 15,
+ -8, 14, -2, -13, 1, 4, 0, 7, -2, -10, -1, 8, -6, -4, 5, 1,
+ -6, 1, -8, 0, -4, 7, 4, -3, -8, -4, -3, 8, 3, -8, -3, 16,
+ -7, -1, 0, -1, -4, -2, 2, 6, -1, -2, -4, 5, 5, -4, -2, -8,
+ -6, 10, 4, -5, -2, -2, -2, 0, -4, 0, 2, 0, -12, 6, 2, 0,
+ 3, 2, -11, 2, 1, -2, 10, 1, -6, 9, -8, -3, 5, -1, 5, -2,
+ 0, -5, -7, 8, 5, -4, -9, -1, 1, -2, -7, 4, -12, -4, 5, 0,
+ -4, 5, -13, 8, 2, 4, 1, -10, -6, -3, 17, 4, 1, -7, 6, 2,
+ 1, -3, -1, 0, 7, -8, -2, 6, 2, -8, 0, 21, -16, -5, -1, -2,
+ 4, 0, -18, 11, -10, -4, 11, -4, -1, -2, 2, -3, 2, -2, -8, -1,
+ 1, -3, 8, 2, 0, 1, 5, -7, 2, -4, -1, 4, 5, 0, 1, -6,
+ -11, -6, 7, 8, 5, -7, -12, 7, 2, -6, -3, 7, -4, -3, -1, 2,
+ 9, 0, -7, 9, 5, -15, -3, -7, 2, 3, -2, 0, -3, 6, -13, -2,
+ 0, -5, 3, 9, -5, 9, -12, -9, 12, 4, 1, 5, 3, -4, -2, 3,
+ 11, -16, 2, 0, 10, -9, -4, 8, -4, -7, 2, 2, -6, 3, -22, 8,
+ 11, -7, -6, -2, -5, -5, -8, 3, 7, 12, -8, -1, 4, 8, -14, 4,
+ 13, -6, -8, 2, 17, -1, -3, 12, -10, -2, -7, 0, -6, 16, -17, -4,
+ 10, -9, -2, 1, 0, -1, -7, 7, -10, -3, 3, -1, -7, 11, -11, 3,
+ 3, 8, -6, -2, 1, 0, -15, 15, 5, 0, 7, -5, 4, -3, -2, 2,
+ -4, 10, -9, -9, 15, -6, -12, 14, 3, -7, 0, -9, -1, -5, 3, -4,
+ 3, 4, -14, -2, -1, 8, -3, 13, -5, -18, 12, -1, -7, 0, 5, -2,
+ -6, 14, 3, -9, 3, 1, -10, 0, 7, 3, -7, 4, 2, -14, 4, 4,
+ -6, 14, -4, -12, 6, 2, -10, 1, 5, -6, -10, 3, 8, -11, 9, -1,
+ -3, 2, -6, -8, 4, 2, -10, 6, 11, -7, 0, 2, 1, -10, 8, 6,
+ -5, 2, -2, 3, -4, 1, 4, -11, 6, 4, -8, 4, 4, -13, -4, 2,
+ 6, -3, 2, -4, -11, 11, 2, -13, 9, 3, -21, -2, 17, -4, -1, 6,
+ -11, -2, 1, -4, 4, 5, 0, 0, 1, 13, -8, 0, -3, 2, -6, 1,
+ 7, -4, 2, 2, -5, -5, 8, -14, -4, 8, -10, -1, 3, -4, -6, 6,
+ 5, -12, -6, 5, 1, -4, 2, -4, -1, 8, -8, 1, 8, -4, 6, -1,
+ 17, -8, -7, -1, 4, -1, 14, -5, 0, -6, -1, 0, -1, 2, -10, -7,
+ 0, 6, -6, 4, -12, -1, 7, -5, -2, 0, 3, 0, -9, 10, -8, -1,
+ -5, 11, -15, 6, 6, -1, 1, 1, -4, 4, -7, 12, -11, 10, 2, -15,
+ 5, 11, 5, -7, -7, 0, 0, -5, 11, 0, -5, -10, -12, 15, 1, -2,
+ -4, 2, 6, -9, -8, -3, -1, -5, 5, -4, 1, 5, -13, -1, 10, 0,
+ 0, -2, 1, 9, 0, 3, -7, 14, -2, 0, -2, 3, -12, 9, 4, 0,
+ -4, -7, 0, -6, -5, 5, -3, -5, -5, 4, 7, -13, -7, -6, 3, 1,
+ 0, 6, -3, -5, -4, 7, 1, 3, 1, -3, 5, 3, 3, 2, -1, 2,
+ 4, -9, 8, 2, -5, 6, -12, 7, -5, -8, -6, 9, -14, 4, -7, 4,
+ -6, 1, -2, -11, 4, -4, 2, 7, -4, 4, 5, -2, -4, -5, 6, 2,
+ 0, 5, 9, 3, -4, -7, 1, 6, 3, -2, -7, 1, 1, -6, 0, 8,
+ -12, -11, 7, -12, 0, 2, -5, 4, -1, -9, -2, 7, -8, 1, 1, 5,
+ 1, -4, 5, -8, 4, 2, -5, 7, 6, -6, -3, -8, 13, -2, -3, 2,
+ 0, 0, -5, 6, 5, -6, -3, -3, 2, 8, -12, 4, 7, -12, -10, 13,
+ -3, -2, 1, -5, 1, 1, -2, 5, -5, -6, -12, 4, 0, 4, 3, 3,
+ -10, -8, -3, 10, -5, 7, -8, 3, -1, 6, 0, 3, 6, 4, -6, 2,
+ 5, 5, -6, -4, -2, 4, -2, -9, -4, 7, -1, -12, 10, -5, -9, -11,
+ 1, 4, -8, 1, 7, -3, 4, -7, -1, 8, -5, -6, 9, -1, 0, 8,
+ 3, 7, -9, 6, -1, 9, -7, 2, 3, -4, -5, 6, -6, 8, -10, -12,
+ 4, 3, 1, -1, -9, -1, -4, -5, -3, 6, 7, -11, -4, 6, 0, -3,
+ 3, 4, -5, -4, 1, -3, 3, -2, 0, 1, -1, 3, -9, 7, 3, -7,
+ -2, 5, 5, -9, 7, 0, -8, 8, 1, -5, 6, -4, -6, 2, 6, -3,
+ 0, 0, -3, -9, -6, -2, 9, 2, -2, -11, 7, 9, -9, -7, 8, 0,
+ -7, 1, 4, -5, -3, -3, 5, 5, -3, -13, 7, 5, -6, 5, -2, 7,
+ -9, -8, 6, 2, -5, 3, 7, -4, -6, -7, 1, 7, 6, -5, -5, 6,
+ -10, 10, 1, -4, 4, -4, -2, 1, 9, -10, 0, 4, -8, -1, -5, -1,
+ 3, -2, 6, 1, -5, -5, -5, 2, -3, 3, 3, -1, 0, -4, 0, 9,
+ -1, -6, -6, 4, -1, 2, 5, 0, -2, -2, -4, 2, 4, -1, -4, 4,
+ 0, -3, -9, -2, 6, 0, -7, -1, 3, -2, -1, 2, 2, -7, -2, 0,
+ 2, 4, -6, 3, -3, 6, 0, 0, -2, -6, 1, 11, -2, -1, -8, 3,
+ -7, 1, -2, 6, -9, 6, 0, -1, 1, -6, -7, 5, -1, 2, -2, -1,
+ -1, 0, -3, 1, 2, -1, -3, -5, 3, 7, -9, 5, 3, -5, -5, 5,
+ -1, 0, 4, 4, -11, 8, -3, -10, 9, -7, -1, 1, -2, 1, -3, 6,
+ -3, -5, 2, 4, -7, 5, 2, -2, -3, 1, -2, -4, 2, 0, -4, 8,
+ 2, -12, 0, 6, -10, -2, 8, -6, -3, 6, -4, 2, 9, -4, -7, 2,
+ 5, -1, 1, 4, 0, -5, 2, -7, 2, 4, 1, -5, -1, 7, -5, -5,
+ 12, -7, -12, 6, -4, -3, 3, 4, -3, -5, -1, -3, -10, 9, -8, -2,
+ 6, -3, -4, 6, -1, 0, 3, 2, 1, -3, -5, 2, 0, 4, -3, -3,
+ 1, 4, -8, 0, 7, 4, -9, 0, 3, 1, 1, -5, -4, 3, -1, -4,
+ 4, 3, -8, -2, -2, -3, -1, 0, -3, -2, 3, -2, 1, 0, -1, 0,
+ -6, 8, -5, 5, -5, 5, -3, 5, -7, 1, -3, -1, -1, 2, 8, -2,
+ -5, 1, -3, -1, -4, -4, 9, -1, 1, -3, -2, 1, -14, 8, 3, -14,
+ 4, 1, 2, 2, 0, -5, 3, -1, 2, -2, 8, -8, -3, -3, 7, -1,
+ -3, -1, -3, 1, 5, -7, 7, -12, -1, 1, 4, 3, -7, 5, 6, -2,
+ 2, -6, -3, 0, -5, 2, 1, -1, 2, -7, 1, 8, -5, -4, -3, 2,
+ -2, -5, 3, 2, -3, -6, -1, 1, -4, 4, 5, 2, -14, -1, 3, -4,
+ 3, 10, 2, 2, -4, -1, 4, 3, -6, 2, 1, -2, -9, 7, -2, 1,
+ -4, -5, 1, -7, -1, 1, 2, 2, -1, -6, 5, -1, -12, -4, 11, -2,
+ -3, 6, -4, 2, 0, 0, -2, 0, 3, 2, 4, 2, -3, -6, 9, -10,
+ -4, 2, 4, -1, -5, -1, 2, 1, 2, -7, -2, -4, -4, -2, 7, 5,
+ -6, 0, 1, -1, -4, 2, -6, 3, 9, -11, -2, 8, 0, -5, 6, -1,
+ 3, -5, 6, 1, -10, -4, -3, 4, 10, -8, -2, 1, 4, -8, 4, 3,
+ -8, -5, 2, 4, -5, 6, -2, 2, 2, -3, -10, 0, -6, 2, 4, 12,
+ -4, -10, 6, 2, -5, 2, -3, 6, -4, 0, -6, -4, 7, 0, -4, 12,
+ 0, -14, 3, 2, 1, 1, 2, -7, -1, 3, -1, -4, 10, -9, -11, 6,
+ 4, -9, -5, -1, 5, 0, 6, -5, -5, -4, 3, -7, 9, 0, -1, 0,
+ 4, -3, -2, -1, -4, 0, 10, 3, -5, 4, -4, -6, 8, 0, -7, -3,
+ 17, -9, -8, -1, 3, -3, -3, 0, -4, -3, -5, -4, 8, 8, -9, -5,
+ 4, 0, -7, 6, 7, 3, -6, 3, -3, 1, -4, -4, 4, 10, 1, -5,
+ -2, 0, -9, 4, 1, 1, -4, -2, 6, -3, -5, 0, -6, 3, 0, -2,
+ 4, 1, 0, -4, 3, -1, -10, -2, -2, 2, 9, -11, 8, 3, -2, -1,
+ -1, -3, -1, -8, 4, 6, 2, -7, 2, -1, 3, -6, 0, 1, -1, 2,
+ 2, 3, -1, -13, 2, 9, 3, -5, -3, 2, -3, 5, -4, -2, 0, -4,
+ -1, 1, -4, 0, -4, 0, -2, -2, -5, 1, 4, -1, 1, -4, 1, 2,
+ 0, -2, 2, 1, 1, 0, 7, 0, -3, -4, -2, 5, 0, -3, -2, 3,
+ 2, -9, -1, -1, -1, -4, 1, 5, -6, 1, -4, 8, -12, 1, -5, 3,
+ 3, -1, -6, 9, -3, -2, 0, 4, 0, -3, 4, 10, -5, -4, -2, 0,
+ 2, -3, -2, -2, 0, 0, -3, 0, 3, -8, 0, -5, 1, 0, 5, 1,
+ 4, -14, -2, 1, 3, 1, 0, -1, 6, -2, 2, -5, 4, 1, -2, -3,
+ 1, 3, 5, -5, 3, -1, -8, 0, -3, 5, -7, 2, -4, 2, -4, 2,
+ -3, -2, -7, 4, 2, -2, -4, 5, -5, -3, 0, -4, 3, 5, -6, 5,
+ 8, -5, 0, 2, 1, -6, 0, 5, 1, -2, 6, -10, 7, -9, 3, -5,
+ 4, -1, -1, -4, 5, -6, 5, -1, -9, -1, 2, 4, -2, 0, 5, -9,
+ 1, 0, -2, 1, -1, -3, -1, 9, -1, -9, -2, 2, 1, 2, -2, 3,
+ -7, 3, -1, 3, -1, -5, -5, 9, 1, -1, -3, 2, -7, 1, 3, -4,
+ -2, 5, 3, -2, 0, -5, -1, -1, -3, 1, -2, 0, -1, -2, 7, -3,
+ -12, -1, -2, 0, 5, 4, -4, -2, 6, -3, -5, 8, -5, -4, 2, 6,
+ 1, -1, -1, -4, 4, 3, -6, -4, 6, -1, -4, 2, 2, -10, -4, 3,
+ 0, -3, 5, -4, -5, -1, 2, -5, -1, 2, -2, 1, 6, -2, -4, 5,
+ -2, 1, 4, 0, -2, 0, 3, 0, -2, -4, -6, 6, 3, -2, -1, -1,
+ 1, -1, 0, 0, -14, -1, 3, 0, 0, 4, -6, -2, 0, -2, -3, -3,
+ 3, -4, 7, 4, -4, -3, -2, 3, 1, 0, 1, 2, 5, -2, -6, -1,
+ 1, 1, -4, 3, 0, -2, -3, 2, -8, 1, -2, -5, 0, 2, -2, 6,
+ 2, -1, -7, 4, -5, 2, -4, -6, 5, 5, 2, -1, -3, -4, -7, 0,
+ 6, -3, 0, -4, 8, 1, -6, -1, 2, 0, -2, -1, 7, -5, -4, 0,
+ 7, 0, -5, -4, 3, -2, 3, -3, 1, 3, -1, -6, 2, 3, -7, 3,
+ 0, -3, -3, -2, -4, 2, -2, -1, -3, 2, -4, 0, 4, 2, -6, 1,
+ -1, 1, 1, 4, 1, 2, -4, 0, 0, 5, 0, -5, -5, 7, 0, -4,
+ -4, 2, -6, -4, 5, -1, -1, -4, -3, 3, -1, -6, 1, 4, -1, -3,
+ -3, 3, 4, -1, 3, 2, 0, -3, -3, 5, 2, -3, -1, 1, -1, -2,
+ -1, 2, 1, -5, -1, 1, -3, -3, -4, 0, 2, -3, -2, 0, 4, -1,
+ -2, 0, 3, -6, 0, 3, 5, -1, -2, 3, 0, -3, 0, -3, 8, -4,
+ -6, 4, 2, -5, 0, -1, 2, -5, -7, -2, 1, 2, 1, 0, -2, -1,
+ -2, 0, 4, 0, -5, 2, 7, 5, -5, 3, -3, 0, 1, 0, -2, 5,
+ -10, 0, 1, 3, -12, 1, -2, -1, 1, -2, -4, 3, -6, -2, 3, 0,
+ -6, 0, 2, 4, 2, -3, 6, 2, -7, 2, 1, -4, 9, 3, -1, 0,
+ -2, -7, 0, 5, 3, -6, 4, -8, -3, -3, -1, -3, 3, -3, -5, 3,
+ -3, 3, -1, 2, -7, -2, -1, -4, 2, 2, 4, 3, 0, 0, -1, -2,
+ 1, 4, -2, 2, -1, 2, -2, -1, -8, 2, 2, -3, -1, 2, -2, -5,
+ 0, -1, -4, -1, 5, 1, 3, -2, -1, 0, 2, 6, -4, -1, -6, -2,
+ 2, 4, 1, -2, -5, -4, 0, 3, -4, 1, 4, -1, -9, -1, 1, -1,
+ -2, -2, 2, 1, -5, 6, -1, 5, -4, -3, -2, 8, -2, 1, 5, 2,
+ -8, 0, 2, 0, 3, -3, -4, 3, -7, -6, 4, 1, -6, 0, 2, -2,
+ -4, -2, 2, 4, -5, -2, 3, 0, -5, 1, 7, 6, -4, -7, 4, 3,
+ -6, -3, 12, -3, -3, -5, -2, 2, -2, -7, -2, 10, -4, -5, 2, 0,
+ -3, -5, 3, -1, 3, -2, -3, 3, 6, -8, 2, 5, -3, -3, -5, 13,
+ -3, -1, 1, 1, -4, -3, 0, 3, -3, -2, -1, 1, 2, -7, -6, 3,
+ -7, -3, 3, 1, 2, 1, -7, 3, -3, -1, -5, 6, 3, -1, -6, 6,
+ 3, -2, -3, -1, 1, -3, 3, -5, 4, 0, -6, -3, 5, -1, -5, 8,
+ -2, -1, 0, -4, 5, -4, -5, -1, 1, 4, -1, 1, 5, -5, 3, -2,
+ -2, -5, -2, 2, 4, -2, 2, 1, -16, 5, 1, -1, -2, -2, 1, -4,
+ 0, -8, 2, 4, -5, 0, 6, -2, 0, 0, 0, -1, 2, -5, 6, -1,
+ -1, 2, -1, 4, -5, 1, 0, -4, -2, -3, 2, 2, 4, -3, 1, -9,
+ -1, 2, 0, 1, -1, -1, -4, 3, -7, 6, -4, 2, -4, 7, -3, -1,
+ 3, -7, 0, 10, -1, -8, 2, 2, -5, -5, 4, -2, -2, -7, -5, 4,
+ 2, 3, -11, 10, -6, -5, -4, 0, 9, -1, 0, 4, -6, -1, 3, -1,
+ 6, -6, -1, -1, 9, -5, -3, 7, -1, -1, 4, 2, -7, 3, -2, 0,
+ -2, 2, -9, 0, 4, -6, 0, 2, 3, -14, 4, -3, -12, 3, -1, 3,
+ -4, 4, -8, 6, 5, -3, -2, -4, 8, 0, -3, -1, 1, -4, 4, -3,
+ 7, 0, 1, -5, 1, 6, -10, 1, 8, -5, -8, 6, 4, -2, 5, 2,
+ -9, 4, -1, -1, 0, -4, -5, 3, 4, -11, 3, -7, -4, 1, 2, 0,
+ -3, -2, -7, 4, -9, 4, -6, -1, 2, -2, -1, 3, 9, -6, 2, -1,
+ 3, 4, 2, 3, -1, 0, -1, 1, 4, 0, -3, 3, 6, -7, -4, 4,
+ -3, 0, -5, -2, 2, 4, -1, -1, 0, -9, -4, -6, 14, -11, -5, -1,
+ 5, -6, -3, 3, -2, -6, 3, 5, -1, -4, 5, -7, 7, 4, -7, 6,
+ 4, -2, -4, 5, 8, -12, 3, -1, -5, 3, -3, 2, 10, -7, -12, 3,
+ -2, 5, -4, 4, 3, -6, -4, -6, 10, -4, 2, -3, 2, 0, -2, 0,
+ 2, 2, -12, -2, 13, -2, -6, 0, -5, 10, 1, -1, -2, 0, -12, 3,
+ 11, 0, -5, -9, 7, -4, 2, -3, 0, 9, -2, -6, 0, 3, -2, -13,
+ 1, 12, -7, -3, 0, -1, -4, -4, -5, 1, 5, -4, -7, 2, 0, -3,
+ 5, -2, 10, -12, 5, 1, 10, 8, -6, 4, -12, 7, -1, 5, 0, -1,
+ -2, 7, 4, -4, 5, -4, -20, 6, 1, -6, 5, 0, -14, 3, -12, 3,
+ -8, 6, -10, 2, -4, -3, 1, 4, -7, 4, 8, 2, 1, 2, 2, 3,
+ 3, 0, 7, -7, 3, -1, -1, 11, 3, 1, -6, 0, -8, -10, 8, 6,
+ -4, -1, -5, -11, 3, -1, -14, 6, -4, -13, 10, 0, 1, -5, 0, 0,
+ 1, -3, 7, 4, 3, 3, -1, 6, 1, -1, -6, 2, 2, -3, -4, 15,
+ -17, -4, 1, -3, 4, -4, -6, -2, 4, 4, -4, 3, -4, -7, -2, 13,
+ -1, -4, -2, -3, 9, -7, -12, 13, 10, -12, -3, 4, 13, -14, -6, 12,
+ -4, -10, 11, -5, 4, -1, -17, 9, -1, 4, -3, -5, 6, 0, -7, 3,
+ 2, 4, -9, -9, 13, -8, 7, 6, -8, 11, -15, -11, 16, -10, -2, 1,
+ -8, -1, 11, -1, -4, 2, -13, 9, 3, 11, -16, 4, 7, -9, 9, 4,
+ -16, 11, 9, -10, 13, 4, -10, -12, 2, 4, 4, -10, 7, -6, 0, -8,
+ -3, 3, -1, -4, -9, -9, 3, -5, -3, 24, -19, -5, 7, -11, 4, 9,
+ 1, -3, -1, 7, -4, 4, 4, -4, -7, 22, 0, -1, 10, -19, 3, 1,
+ -6, 9, -7, 3, -5, -5, 5, 9, -17, -2, 4, -9, -4, 5, -3, -7,
+ -3, 6, -4, 10, -12, -3, 13, -6, -5, 5, 3, 8, 0, -7, 0, 2,
+ -3, 12, 3, -10, -4, -8, 8, -1, -16, 13, -5, -5, 0, 3, -6, -8,
+ -2, 13, -5, 12, -4, -17, 11, 0, 2, 2, 3, -6, -3, -3, 4, 7,
+ -3, 1, -2, -2, -3, -4, 7, -3, -4, 4, -5, 6, -11, 5, 7, -10,
+ 0, 2, -6, -1, 5, -3, 3, -5, 5, -8, 4, 10, -8, 3, -4, 7,
+ -5, 3, -3, -2, 4, 2, -4, -7, 2, -3, -5, 6, -2, 5, -4, 6,
+ -10, -5, 5, 0, -8, 6, -6, -1, -3, 5, 2, 0, -4, 10, -12, -5,
+ -21, -1, -4, 5, 3, 2, 18, -14, 8, 5, 1, -4, -5, -2, -9, 0,
+ -12, 20, -4, 7, 1, 6, 7, -1, -5, 13, -1, -7, 6, -2, -5, 2,
+ 1, 4, 6, -7, 6, -9, -3, 6, -3, 8, -10, 8, -6, 0, -20, 1,
+ -5, 5, -4, -8, -12, -13, 8, -2, 17, 3, -5, -20, -1, -7, 3, 22,
+ 22, 12, -11, -13, -15, -9, 21, -3, 25, 43, -4, -3, -6, -21, -30, -37,
+ -9, 8, -5, 8, 53, 50, 1, -5, -13, -15, -41, -23, 6, -34, -47, -17,
+ -2, 2, -13, 22, 29, 32, 44, 51, 55, 10, 15, 7, 0, -31, -48, -38,
+ -48, -43, -13, 7, 4, -46, -23, -6, 6, 4, 12, 50, 26, 4, 24, 40,
+ 33, 20, 17, 17, -7, -30, 10, -2, -17, 5, -36, -7, -38, -30, -13, 1,
+ 9, -1, -6, -29, -15, -11, 7, 3, 6, 16, 27, -22, -8, 5, 24, 27,
+ 0, 4, -5, -5, -2, 15, 12, 12, 2, 13, 0, -19, -26, 4, -19, -24,
+ -33, -21, -28, 0, 6, 18, 20, 15, 40, 2, -8, 17, 21, 47, -2, -12,
+ 11, -9, 22, -19, 3, -27, -29, -10, -38, -36, -42, 33, 12, -29, 10, -15,
+ 0, -1, -22, 24, 27, 8, 15, 7, 16, -13, 9, 33, 8, -4, 33, 70,
+ 21, -26, -18, -15, -22, -76, -2, 15, -35, -4, 8, 5, -3, -45, 6, 24,
+ -20, 6, -15, 8, -1, 2, 7, -4, 39, 4, 22, 34, -25, 26, -1, -31,
+ -4, 10, 2, 22, -25, -19, -2, -2, -44, -29, -17, 10, -6, 29, -8, 12,
+ 18, -9, -6, -36, 4, -14, -8, 10, -12, 28, 9, 16, 17, -29, 26, 0,
+ 1, 11, -13, 11, 1, 7, -7, -3, -5, 22, -10, 10, -29, 22, -29, -30,
+ 29, -30, 3, -43, 21, 5, -18, 6, -5, 23, 18, -31, 35, 28, -19, 9,
+ 13, 10, -3, -10, 37, -69, 7, 11, -16, 8, -76, 11, 58, -57, 18, -7,
+ -11, 26, -40, 100, -53, -1, 14, 3, -26, -35, 21, 20, -30, 10, -26, 37,
+ 25, -97, 118, -72, 37, 11, -15, 52, -22, 6, 85, -32, 24, -63, 48, -60,
+ -19, 3, -28, -19, 7, -28, 15, -22, 7, 20, -7, 16, -13, 8, 25, -27,
+ 2, 7, -18, 15, -30, 23, -3, 28, -31, 34, 22, -23, -6, -6, 28, -68,
+ -10, -3, -22, 12, -43, 70, -52, 32, 8, -4, 55, -14, 19, 21, 45, -13,
+ -33, -9, 20, -22, -14, 9, -21, -2, 6, -56, 17, -26, 23, -13, -8, -1,
+ 3, 31, 16, 20, -12, -10, 50, -27, -17, -13, -26, 29, -23, -7, 58, -40,
+ -20, 16, 16, -13, -65, 63, 18, -25, 23, -3, 6, 11, -11, -24, -19, 8,
+ 32, -44, 47, -50, 26, 6, 43, -58, 15, -21, 46, -81, 60, -28, 65, -37,
+ 42, 42, -55, -6, -23, -9, -52, -25, -5, 7, -67, 26, 59, -62, 31, 63,
+ -23, 52, -16, 27, 14, -13, 19, -41, -8, 37, -7, 9, -33, 16, 7, 36,
+ -40, -26, -26, 49, -3, 3, -50, 33, 23, -10, -13, -14, -19, -13, 1, 2,
+ -41, -19, 32, -3, -29, 9, 58, 1, 9, 15, 19, -19, 59, 2, 6, -6,
+ -24, 52, -67, 3, 5, -37, 3, 31, -42, 45, -1, -31, -6, 19, 11, -17,
+ -5, -2, -22, 3, -35, 35, -39, 8, 17, 6, 7, -32, 2, -1, 40, -32,
+ -2, 26, -5, 2, -5, -12, 18, 21, -15, 29, -28, 13, -23, 36, 28, -75,
+ 55, -53, 50, -45, 9, -3, 42, -10, -33, 8, -9, -17, 8, 13, -13, 34,
+ -48, 39, -5, -26, 24, 19, -34, 29, -41, 22, -42, -11, -15, 37, 0, -31,
+ 15, 4, 11, 18, -28, 23, -3, -52, 33, -1, -8, 19, -39, 44, -3, -16,
+ 31, 7, -17, 38, -44, 62, -21, 0, -7, -13, 25, 12, -50, -13, 2, 9,
+ -47, 43, -29, -12, -3, -3, -37, -22, 0, -6, 60, -69, 27, 9, 12, 13,
+ -7, 46, 43, -2, 3, -5, -5, 17, 13, -37, 35, -39, -38, 33, -44, -10,
+ 11, -9, 50, -68, 26, -22, 10, -20, 34, -13, -17, 21, -34, -1, 42, -23,
+ -7, 9, 3, 1, -1, -9, 36, -15, 5, -21, 40, -47, 25, -11, 20, 24,
+ -19, 16, -13, 6, -25, -2, 19, -17, 7, -36, 28, -8, -28, -11, 9, 25,
+ -55, 7, 39, -36, -3, 8, 28, 25, -33, 29, 1, -28, -1, -7, 40, -50,
+ 22, 15, 21, -2, -1, 18, 8, 46, -52, -1, 14, -39, -10, 18, -10, -27,
+ -15, -9, 2, -7, -47, 23, 17, -40, 12, 37, -24, 22, 9, 5, 27, -14,
+ -17, -17, 23, 16, -18, 19, 32, -19, -10, 13, 12, -33, 31, -4, 12, -17,
+ 22, -3, -8, -33, 16, -45, -17, -13, -24, 23, 19, -22, 52, -63, 23, 26,
+ 8, -11, 30, 40, -35, 28, -5, 11, -10, -16, 18, -35, -21, -6, 9, 0,
+ -33, 9, -15, -24, 15, -23, -19, 30, 13, -20, 37, 24, -48, 47, 21, -31,
+ 51, -22, 40, -24, 47, -55, 31, -21, -57, 15, -7, -28, 5, 25, -12, -42,
+ 46, -43, -21, 6, 4, 14, -15, 11, 51, -27, 6, 21, -27, 42, 17, -35,
+ 3, 3, -15, 11, 17, -26, 0, 6, 11, 18, -37, 4, 28, -14, -14, -30,
+ 43, -50, -17, 55, -50, 16, -32, 51, -35, -13, -4, 54, -22, 23, -48, 51,
+ 2, 10, -16, 7, -10, 15, -48, 25, -5, -4, 6, 21, -17, -2, 30, -23,
+ 16, -3, -12, -11, 21, -57, 3, 10, -3, 0, -19, 36, -42, 50, 0, -30,
+ 55, -15, 12, -10, 28, -47, 29, -16, 6, -37, -1, -6, 3, -45, 35, -30,
+ 8, -4, -12, 32, 42, -23, 3, 5, 30, -38, 15, 16, -36, 60, -1, -53,
+ 28, -25, -10, 45, -20, 2, -22, 24, -6, -19, -31, 18, 6, -56, -15, -3,
+ -5, 1, 12, 5, -7, 70, -9, -7, 49, -31, 48, 36, -15, 5, -23, 35,
+ -51, 4, -32, -40, 7, -20, -15, -7, 17, -32, -2, 17, 1, -8, 46, -4,
+ 12, 15, 41, -50, 29, -21, -13, 10, -20, 12, 2, -24, 12, -1, 6, 8,
+ -29, 19, -27, 51, -67, 83, -44, -22, 21, -2, -14, 13, -52, 72, -37, 19,
+ -25, 43, -37, -22, 19, -12, -36, 14, 17, -3, 27, -39, 58, -23, 1, 14,
+ 52, -25, 15, -1, 1, -23, -11, -9, 4, 14, -83, 23, 4, -38, -21, 2,
+ -1, 17, 2, 48, -30, 24, 29, 9, 19, -44, 46, 22, 5, -32, 39, 0,
+ -28, -27, 16, -32, -31, 7, -17, -13, -9, -6, 14, -33, -18, 35, -39, 52,
+ -40, 31, 12, 14, -24, 52, -35, 11, 1, 26, 10, -18, 20, 7, -7, -5,
+ 7, 5, -15, -10, -7, 8, -10, -26, 21, -16, -14, 13, -27, 27, -44, 6,
+ 18, 6, -12, -4, -11, 12, -1, 7, 6, 3, 20, -5, 11, 15, 9, -10,
+ 37, -37, -3, 11, -23, 9, -35, 19, -32, 4, 14, -28, 41, -42, 43, -5,
+ 11, -20, -16, 20, -10, 6, 6, -4, 1, -6, 7, 20, -42, 25, -29, 34,
+ -31, -10, 14, -4, -9, -4, 13, 7, -7, -2, -19, 25, -10, 0, 16, -1,
+ -9, -6, 53, -52, 10, -7, 5, -10, 1, 4, 9, -24, 10, -21, 61, -40,
+ 3, 3, 12, -38, 31, -3, -7, 8, -13, 8, -15, 4, -33, 44, -29, 5,
+ 5, 37, -52, 16, -13, 25, 7, -34, 17, -7, 14, -11, 24, -32, 22, -23,
+ 42, 5, -30, 21, 19, -21, 2, -11, 14, -18, -16, -34, 41, -30, 7, 2,
+ -23, 20, -37, 26, -17, 18, -37, 64, 0, 14, -19, 5, 12, -8, -13, 22,
+ -9, -26, 24, 17, -8, 3, -5, -14, -14, 17, -30, 14, 26, -67, 38, -9,
+ -20, 11, 11, -22, 11, 15, 1, 11, -22, 0, 1, 38, -43, 2, 15, -31,
+ 2, -5, 29, -18, -27, 21, -8, 15, -20, 46, -24, 20, 16, -7, 24, -63,
+ 40, -8, 9, -8, 14, -10, -11, -28, 4, 10, 8, -26, 13, 11, -35, -1,
+ 40, -36, -5, -3, 38, -7, -23, 3, 4, 17, 3, -15, 11, 24, -67, 26,
+ 2, 21, -54, 30, 14, -34, 12, 25, -16, 12, -13, -7, 47, -24, -23, 7,
+ 18, -4, -19, 31, -18, -14, -11, 21, -15, 5, -31, 40, -53, 21, -4, 30,
+ -32, -3, 14, -5, 30, -17, 3, 13, 8, -4, -5, -11, -12, 8, -7, 16,
+ 10, -21, 35, -59, 13, 10, -3, -7, 1, 2, -16, -4, 27, -43, 35, -16,
+ -14, 36, 0, -51, 13, 31, -19, 14, 21, -19, 14, -3, -27, 29, -10, 34,
+ -46, 30, -12, -17, 11, -34, 23, -23, 10, -3, 4, -8, -14, 25, -16, 35,
+ -12, 22, -7, 3, 9, 0, 11, -5, -10, -16, 9, -21, 7, -36, -4, -13,
+ 4, -6, -7, -2, -1, 0, 14, 16, -15, 7, 27, -28, 43, -32, 17, 7,
+ -25, 33, -7, 6, -10, 11, -20, 1, 5, 28, -11, -26, 20, -17, 29, -40,
+ 1, -6, 13, -23, 23, -23, -28, 18, 5, -22, 16, -19, 41, -9, -16, -11,
+ 45, -17, 6, -51, 34, 36, -44, 29, -33, 22, -13, 3, 5, -26, 2, 11,
+ 23, -17, 0, -7, 12, 3, -27, 18, 13, -2, -30, 22, -6, 7, 1, -4,
+ 5, -1, 12, -14, 1, -15, -5, 12, 6, 3, -13, 15, -14, 14, -1, -12,
+ 3, 3, -4, -18, 7, 2, -7, -5, 9, -15, 7, 17, -27, 45, -52, 60,
+ -15, -12, -9, -11, -14, 27, -18, -9, 21, -10, 10, 3, -23, -4, 8, -23,
+ 19, -31, 12, 18, 12, -7, 1, 15, 3, 27, -38, -7, 42, -9, 1, -7,
+ -22, 5, -10, 0, -28, 5, 12, -6, 0, -12, -15, 18, 19, -14, -27, 47,
+ -6, -1, -21, 32, -31, 52, -41, 3, -39, 34, -29, 16, 8, -6, 33, 16,
+ -23, -10, 16, 9, 2, -33, 40, 0, -21, -2, -18, 1, 13, -32, 24, -11,
+ -14, 24, -20, 0, -19, 11, 23, 1, -30, 4, 38, -23, 11, 0, 9, 18,
+ -36, 10, -21, -1, -5, -1, 23, -24, 9, 27, -13, 4, -39, 60, -17, -11,
+ -12, 25, -9, -36, 26, -7, -3, 28, -27, 26, -12, -20, 8, 13, -40, 7,
+ -23, 38, -33, 14, 8, -1, -23, 36, -19, 15, 13, -36, 4, 17, -32, 31,
+ -23, 20, 0, 23, -3, 5, -17, -11, 12, -24, 21, -29, 34, -26, -1, 4,
+ -14, 21, 9, -1, -1, 21, -33, 29, 1, -28, 28, -20, 22, -24, -13, -13,
+ -6, 10, -22, 33, -49, 17, -24, 1, 22, -11, 43, -27, 28, 28, -33, 36,
+ 5, -5, 2, 22, -28, 16, -24, -16, 4, -69, 66, -47, -12, 19, -17, -1,
+ 24, -32, 46, -36, -3, 50, -26, 24, -22, 9, 39, -53, 0, 32, -1, -21,
+ 29, -26, -4, 29, -45, 12, -10, 11, -12, 20, -23, -11, 20, 10, -1, -24,
+ 33, -16, 12, 2, 4, 14, -17, -17, 20, -42, 6, -18, 0, -4, -10, 11,
+ 2, -10, 4, 7, 2, 27, -35, 11, 12, 4, -11, 19, -19, 40, -6, -16,
+ 44, 2, -10, 32, -37, 1, -23, -8, 23, -59, 11, -5, -9, -9, -1, -8,
+ 5, -18, 26, -14, 27, -10, 9, 30, 23, -31, 30, -1, -1, -14, -13, 35,
+ -76, 42, -79, 43, -29, 1, 2, -5, -6, 5, 30, 15, -20, 23, 25, -37,
+ 39, -5, -20, 24, -7, 2, 20, -38, 20, -31, -12, -2, -12, 13, -31, 10,
+ -9, 0, -11, 27, -16, 10, -2, 44, -46, 18, 33, -16, -12, 3, 11, 15,
+ -26, 8, -22, 19, -3, -11, 5, -48, 31, 16, -15, -5, -2, 17, 6, -9,
+ -8, 9, 25, -7, 0, 7, -8, -5, 10, -11, -26, 26, -15, 17, -31, -11,
+ 15, -1, -16, 1, 10, 4, -7, 18, -6, 2, 11, -2, 11, -26, -4, 25,
+ -27, -19, 7, 29, -29, 13, -10, 3, -27, 31, -55, 38, -13, 17, -9, 32,
+ -27, 17, 18, -3, -10, 17, -45, 58, -12, -18, 25, 4, -40, 35, -61, 10,
+ -3, 2, -15, -14, 33, -20, -2, -4, -19, 31, -29, 25, 8, -11, -3, 32,
+ 1, -26, 12, 25, -42, 5, 27, 1, 2, 17, -25, -2, 6, 9, -17, 9,
+ -11, 9, 9, -21, 11, 15, -55, 34, -24, -6, -1, -9, 17, -13, 1, -11,
+ 31, -24, -15, 38, -21, 27, -30, 30, -35, 28, 15, -30, 56, -40, -17, 39,
+ -9, -7, 4, -18, 7, 13, -25, 3, -9, -13, -13, 27, -35, 13, 0, 6,
+ -3, 26, -20, 27, -23, 25, -25, 38, -2, -3, 8, -11, 0, 0, 0, -28,
+ 28, -27, -6, 23, -33, -8, -1, -29, 0, 2, 26, -40, 15, 2, 23, 28,
+ -32, 17, 26, -17, 10, 1, -14, 17, 1, 14, -9, -10, -15, 12, -3, -19,
+ 2, 20, -19, -19, -14, 4, -2, -8, 13, -16, 22, -9, 28, 7, -9, -22,
+ 49, -28, 3, -5, 9, -2, 5, -26, 39, -12, -29, 19, -11, 7, -33, 27,
+ -32, 15, -9, -9, 16, -7, -3, 27, -4, -18, 19, 23, -20, 3, 2, 11,
+ -21, 14, 4, -13, 8, -15, 9, 4, -37, 9, -11, 22, -20, -12, 17, 12,
+ -20, -2, 13, 18, -19, -1, 19, -28, 12, 2, 12, 2, -37, 12, 21, -19,
+ -23, 17, 21, -35, 9, 26, -20, -15, 12, 14, 23, -20, 17, 9, -16, -4,
+ 5, 3, -8, -24, 13, -5, 5, -7, -11, 31, -24, -34, 28, -8, -26, 16,
+ -7, 2, -2, 9, -21, 42, -54, 34, 42, -22, 16, -1, 14, -15, -12, 21,
+ -16, -3, -18, 55, -46, 11, 6, -19, 18, -36, -9, 12, -21, 23, -41, 37,
+ -12, -10, 1, 13, -5, -7, 42, 2, 1, -2, 4, -3, 15, -53, 27, -3,
+ -26, -14, 32, -30, -5, 11, 12, -3, -4, -24, 35, -37, 12, 4, 5, -17,
+ 32, 0, -18, 41, -41, 43, -2, 22, -36, 7, -5, 11, -25, 7, -29, 9,
+ 2, -4, -11, 5, -2, 15, -31, -11, 24, 3, -15, 26, 11, -10, 18, 5,
+ -8, -2, -43, 43, 2, -43, -20, 25, 4, -3, 39, -11, -6, -3, -1, -12,
+ 22, -21, 6, 22, -7, -17, -5, 18, -4, -14, 3, 18, -11, -18, -3, -2,
+ 2, -5, 1, 10, -28, 17, 8, -8, -12, 23, -13, 10, 0, -12, 14, 11,
+ -11, 34, -21, 3, 1, -9, -17, 1, 9, -28, 5, -34, 21, -8, 8, 8,
+ -13, 18, 2, -15, 5, -3, 11, -2, 11, -2, 15, -10, 14, 5, -1, 18,
+ -6, 1, -26, 13, -25, 2, 6, -39, -14, 0, -5, 13, -22, -14, 34, -22,
+ -1, 16, -13, 11, 32, -10, 31, -5, 18, -21, 34, -47, 32, -9, 10, 8,
+ -31, 5, 4, -9, 5, -52, 16, -14, 4, 20, -11, -13, 13, -10, -12, 11,
+ 16, -20, 13, -12, 14, 10, 1, -15, 32, -24, 18, 0, 5, -26, 6, 16,
+ -23, -10, 12, -40, 17, -14, -13, 38, -5, 5, -19, -3, 17, 14, -8, 8,
+ -15, 21, -6, 10, -12, -16, 27, 6, -35, 16, -26, 45, -25, -1, -9, 29,
+ -25, 8, -31, 9, 25, -10, 4, 11, -22, -5, 1, -12, 6, -10, -11, 17,
+ -31, 5, 21, -6, 33, -55, 47, 6, -6, 2, 11, 14, -11, 10, -14, -26,
+ 8, -18, 4, 11, 6, -4, -2, -20, -2, -26, 38, 4, -24, -6, 7, 22,
+ -15, 30, 0, 13, 3, -11, 4, -10, -28, 38, -14, -9, -5, -45, 40, -21,
+ -28, 31, 0, -9, 18, -45, 20, 12, -20, 39, -25, 14, 1, 17, -4, 29,
+ -12, 26, -8, -21, -19, 10, 3, -31, 34, -16, -12, 5, -14, -4, -13, 13,
+ -7, 13, -15, -23, 40, -27, 15, 4, -11, 23, -20, -2, 7, 8, 3, 2,
+ -4, 1, 7, -22, 42, -37, 24, 1, -9, 16, -31, 9, 6, -3, -25, 40,
+ -41, 0, 2, -7, 18, 0, -10, 21, -5, -17, 29, -37, 27, 3, -22, 10,
+ 11, -5, 13, -17, 15, -19, -23, 17, -10, -35, 20, 4, -4, 3, -10, 7,
+ 15, -14, 10, -3, 10, -25, 13, 1, 20, -13, 13, 19, -38, 18, -4, 19,
+ -10, 9, -27, 19, -35, -8, -10, 39, -14, 2, 14, 36, -16, -8, -8, -7,
+ -2, -11, 4, 1, -42, 51, -17, 10, -15, -33, 29, -25, -7, 6, 2, 11,
+ 3, -20, 37, -28, 6, 34, -22, 5, 28, -4, 17, 5, -47, 28, 1, -3,
+ -21, 8, -6, -7, 10, -15, 6, -30, 6, -19, 1, -4, 30, -22, 29, -13,
+ -4, -2, 11, -1, -15, 38, -4, -9, 25, -29, -17, 10, -2, -3, 7, -15,
+ 24, -26, 21, 2, 6, -20, 10, -26, 41, -33, 19, -11, 6, -3, -9, 5,
+ 3, -21, 8, -5, -7, 10, 13, -10, -3, -4, -10, 26, -1, 1, 5, 11,
+ -3, 2, 23, -35, 21, -43, 17, -4, 2, -24, 14, -22, -3, 3, -5, -2,
+ 12, -13, 16, -5, 7, 17, 4, -44, 26, 17, -4, 36, -58, 43, -20, 8,
+ 3, -23, -18, -17, 16, 4, 3, -33, 15, -4, -10, 19, -20, 23, 13, -6,
+ -4, 25, -12, 21, -9, -4, 6, -1, 23, -7, -15, 3, -15, 3, -13, -23,
+ -3, -32, 4, 6, -18, 0, 11, -14, 42, -37, 26, -20, 50, -18, 18, 11,
+ 4, 18, -5, 8, -22, 30, 5, -20, 16, -20, -28, 2, 4, -10, -10, -10,
+ -27, 38, -38, 14, -17, -20, 34, -11, -5, -5, 10, 5, 25, -20, -2, 28,
+ -8, 26, -39, 68, -50, 53, -35, -5, 3, -23, 24, 8, -21, -28, 19, 6,
+ -18, -13, -7, 26, -7, 0, -4, 7, -7, -15, 29, -10, -12, 13, 9, -4,
+ -34, 39, -49, 38, -31, 29, -26, 2, -18, 45, 3, -16, -2, 29, 4, -27,
+ 2, 17, 6, -12, -3, 12, -12, -14, -22, 11, -13, 6, -2, 30, -39, 12,
+ 5, 10, -18, 3, -5, 24, -39, 15, 49, -42, 19, 9, -25, 5, -60, 31,
+ -19, -8, 9, 28, 28, -34, 21, -4, 25, 24, -18, 17, -35, 1, 7, -28,
+ 32, -29, 6, 7, 4, -23, 21, -17, -14, 16, -29, 21, -43, -24, 2, 58,
+ -33, 60, -20, 24, -29, 18, -24, 29, -14, -6, 10, -19, 15, 38, -38, 35,
+ -15, -11, 20, 9, -57, -4, 0, -8, 15, -8, -20, -6, 9, 21, 8, -21,
+ 12, 1, 6, -29, 24, 17, 6, -33, 26, 20, -12, 14, -17, 3, -2, -19,
+ -6, 13, -55, -5, 5, 8, 21, -12, 11, -13, 15, -34, 45, -47, 43, -6,
+ 5, 34, -32, 28, -15, 12, -38, 30, -16, 1, -4, -2, 6, 4, -26, 2,
+ 21, -42, 5, 19, -20, 44, -70, 38, -5, -4, -8, 20, -16, 22, -25, 46,
+ -21, 1, -31, 48, -32, 7, -23, 62, -48, 38, -2, -30, 41, -57, 41, -41,
+ 9, -5, 16, 9, 1, -50, 80, -48, 5, -20, 11, -9, -19, -8, 1, 20,
+ -24, 4, 36, -42, 42, -32, 39, 6, -12, 1, 12, 3, -17, 2, -13, 57,
+ -70, 26, 6, 0, -23, 8, 4, -17, -10, -41, 34, -10, -46, 51, 23, -10,
+ -4, -10, 16, -9, 4, 32, -14, 6, -7, 23, -18, -9, 5, -14, 4, 15,
+ -29, 10, 15, -14, 19, -28, 40, -30, -20, 17, 3, 5, 37, -32, 12, 0,
+ -18, 1, -7, -23, 4, -51, 69, -22, -43, 30, -39, 54, -64, 29, 21, -2,
+ 2, -22, 29, 2, 14, 5, 8, -7, 7, 34, 2, -25, 10, -7, -5, 24,
+ -64, -1, -18, -7, 23, -24, 26, -23, -35, -17, 51, -60, 53, -2, 14, 17,
+ 6, 5, 11, -9, 15, 21, -1, 21, -49, 45, -34, -16, 12, 0, -34, 2,
+ -67, 50, -48, 23, -20, -12, 20, -22, 32, -15, 15, -23, 65, -9, 33, 26,
+ -3, 4, 14, 8, -17, -17, -47, 57, -63, 13, 8, -30, -8, -31, -12, 28,
+ -45, 9, -3, 19, -31, 31, -2, 41, -46, 38, 38, -23, 21, -13, 9, 35,
+ -2, 5, 13, -36, -2, -10, 15, -16, -48, 22, 29, -49, -21, 15, -10, -15,
+ -23, 26, 40, -39, 26, -10, 13, 21, -46, 35, -20, 8, -1, 30, 17, -64,
+ 22, 2, 22, -30, 6, 19, -18, -34, 38, -4, 13, 0, -11, 50, -51, 21,
+ -10, 13, -42, -9, 45, 4, -82, 12, 37, -11, -12, -8, 21, 6, -33, 32,
+ -14, 6, 13, -44, 37, -22, 20, 2, 12, -15, 26, 30, -17, -11, -30, 18,
+ -4, -5, 11, -2, -22, -15, 25, -16, 11, -15, 21, -8, -17, -9, 27, 11,
+ -43, 2, 4, 31, -59, -5, 44, -16, 26, -13, 3, 1, -1, -40, 70, -44,
+ 43, -15, 2, 22, -36, 13, 41, -43, -12, 4, 12, -34, -22, 9, 22, -23,
+ -22, 27, -24, 22, -18, 45, 12, -32, 7, 17, -24, -15, 4, 20, 6, -40,
+ 29, 48, -64, 28, -3, -6, 43, -22, -34, 36, -41, 13, -2, -59, 72, -53,
+ 39, -30, -3, 16, 29, -40, 5, 30, -21, 15, -35, 9, 14, 2, 4, -16,
+ 4, 8, 14, 1, 30, -32, 5, -14, 28, -26, -1, -12, -16, -4, -22, -5,
+ 28, -8, -24, 7, 42, -22, -3, -9, 16, 38, -42, 25, 8, 10, -9, 38,
+ -28, 31, -8, -34, 22, -70, 21, 15, -36, -10, -15, -1, 49, -37, -17, 51,
+ -24, 11, 30, -27, 33, -39, -12, 36, -4, -49, 38, 12, 10, -17, -11, 59,
+ -26, -59, 33, 28, -37, 17, -39, 40, -16, -29, 28, 14, -19, -14, 18, 23,
+ -17, -16, 15, -11, 9, -16, 45, -25, -27, -1, 40, -36, 1, 19, -1, -14,
+ -3, 1, 29, -9, -58, 54, -12, -19, 16, 13, 29, -74, 48, -20, 22, -66,
+ 3, 23, 2, -31, 11, 41, -41, 2, 25, 4, 8, -3, 8, 23, -10, -6,
+ 27, -1, -67, 31, -29, 29, -29, 0, 17, -20, -18, -10, 29, -45, 43, -35,
+ 61, 4, -49, 31, -10, 53, -60, 19, 11, 15, -22, -3, -20, 26, 3, -60,
+ 59, -41, -26, 17, 22, 12, -6, -12, 30, -14, -8, -7, 16, 54, -34, -18,
+ 26, -15, -11, 7, -44, 39, -52, 48, -53, 18, -38, 3, 13, -11, 37, -12,
+ 11, 9, 14, -7, 40, -19, -6, 6, -15, 29, -34, 1, 18, -18, -9, -24,
+ -30, 17, -50, 31, 4, 8, 17, -7, -5, 0, 17, 25, 16, 15, 43, -54,
+ 39, -10, 2, -40, -23, 26, 3, -61, -2, 15, -6, -56, 46, -2, 16, -80,
+ 43, 52, -9, -30, 41, 17, 2, -33, -7, 52, -7, -29, 31, 0, -23, 10,
+ -24, 44, -82, 18, 45, -14, -40, -40, 40, 12, -66, 0, 74, -35, -5, 17,
+ 67, -59, 32, -4, 29, -1, -48, 39, 1, 8, -63, 43, -12, -37, -5, -12,
+ 25, 2, -21, 7, 24, -34, -11, 19, 28, 6, -34, 44, 13, -35, -19, 28,
+ -50, -13, 56, 7, -32, -12, 19, 6, -1, -6, 6, 0, 17, -26, 41, -20,
+ -5, -6, 43, -58, 10, -12, -14, 74, -84, 74, -28, -15, -27, 19, -15, -3,
+ 17, 24, 10, -60, 64, 0, -9, -39, 1, 25, -12, -25, 22, 8, -21, -40,
+ 73, -32, -18, -11, 6, 57, -52, 36, -19, 37, -40, 9, 2, 14, -15, 27,
+ -33, 35, 7, -37, 24, 10, -66, 17, 1, -10, 13, -38, 15, -9, 43, -30,
+ 19, -15, 17, -8, 7, 8, -38, 66, -55, 10, 9, -37, 37, -32, -11, 47,
+ -14, 11, 37, -41, -33, 12, 3, 34, -59, 35, 14, -4, -7, -2, -21, 48,
+ -52, 49, -8, -44, 0, 11, -6, -2, 11, -35, 64, -38, -35, 64, 7, -32,
+ 15, 15, 19, -39, 18, -31, 25, 6, -28, 25, 17, -34, -26, 21, -18, 15,
+ -15, -31, 24, -4, -26, 41, -2, -18, -24, 75, -21, 1, -6, -2, 16, 12,
+ -24, 15, 8, -14, 7, 7, -4, -37, 45, -67, 39, -41, 9, 19, 13, -60,
+ 44, -22, 23, 2, -35, 14, 35, -25, 7, 21, -39, 15, 1, 39, -43, 26,
+ -18, -14, 36, -10, -16, -15, 29, -34, 16, -1, -13, 24, 0, -43, 55, -18,
+ -31, 22, -15, -15, 43, -33, 50, -10, -43, 22, -27, 60, -30, 14, 0, 10,
+ -3, 10, -20, 11, -34, -7, 70, -59, -26, 25, -23, 7, -29, 8, 11, -13,
+ -8, 3, 13, -13, 35, -8, 34, -33, 9, 30, -5, 33, -37, -10, 56, -38,
+ -5, 14, -50, -24, 39, -11, -11, -27, -22, 46, -13, -6, -1, -6, 37, -56,
+ 48, -11, 24, -14, 32, -13, -1, 5, 8, 37, -86, 36, -1, -6, -12, 13,
+ -40, 3, 9, 15, -13, -23, 3, -15, 61, -50, -12, 29, -14, -2, 25, -31,
+ 52, -41, 31, 31, -27, -10, 9, 22, -15, 3, -11, 22, -25, 8, -40, 0,
+ -5, 2, -9, 40, -62, 5, 16, -6, -7, -21, 31, 29, -28, -3, 47, -31,
+ 51, -34, 59, -32, -8, 44, -7, -2, -20, 3, 64, -51, -58, -3, 0, -39,
+ 26, -22, 14, -39, 8, 20, -30, -2, 7, 8, 37, 15, -9, 43, -5, 2,
+ 11, -5, 10, 2, -37, 56, -59, -11, 8, -14, -30, -29, -3, 29, -1, -33,
+ 42, -44, 53, -58, 85, -28, -5, -2, 41, 5, 15, -49, 30, 26, -46, 17,
+ 9, -55, 0, 38, -46, 32, -32, 10, 15, -60, 8, 23, -1, 7, -35, 71,
+ -11, -39, 39, -22, -8, -3, 10, 36, 13, -73, 53, -15, 7, -7, -15, 25,
+ -7, -24, 21, 9, -51, -11, 27, -15, 11, -6, 26, -26, 27, 16, -33, 47,
+ -29, -18, 53, -53, -2, 38, -29, 12, -37, 18, 10, -10, -20, -8, 12, 15,
+ -43, 32, 3, -44, 35, 29, -38, 17, -16, 13, 45, -37, 21, 18, -7, -38,
+ 32, -21, -6, -4, 20, -14, -9, -16, 14, 1, -19, -13, 22, -4, -39, 58,
+ -34, 3, 17, -10, 50, -3, -47, 36, 29, -27, -13, 39, -20, -8, 12, -40,
+ -20, 1, 0, -24, 23, -40, 38, 4, -1, -19, 16, 10, -4, 28, -25, 44,
+ -17, 19, -21, 50, -10, -16, -13, 7, -28, 11, -9, -17, 13, -52, 22, -3,
+ -21, -49, 75, -42, 34, -3, 18, 1, 10, -20, 13, 13, 22, -11, -35, 46,
+ -29, 44, -39, -31, 37, -22, -27, 42, -57, 40, -34, 4, 12, 9, -29, 13,
+ 6, -10, 4, 21, 7, -17, 3, 25, -18, 44, -26, -1, 20, -38, 19, 24,
+ -35, -18, -6, -14, 23, -32, -15, 24, -6, -50, 62, -39, -3, 0, -23, 87,
+ -44, 37, -9, -4, 67, -73, 46, 45, -32, -14, 8, -4, -22, -5, -22, -20,
+ 36, -34, 6, 26, -35, -18, 15, 0, -12, 0, 12, -10, 28, -15, 24, 13,
+ -21, 19, 15, -17, 20, -7, 0, -21, 7, -16, 5, -12, -1, -11, 7, 32,
+ -68, 69, -55, 24, 2, -3, 21, -47, 28, 20, -15, -29, -2, 23, 4, -18,
+ 15, -22, 36, -38, 17, -23, 14, -18, 17, 31, -37, 30, 8, -1, -3, -5,
+ -12, 22, -18, -28, 33, 0, -9, -16, 20, 9, -26, -20, 21, 2, -4, 14,
+ -24, 16, -11, 12, -1, -39, 7, 51, -2, 1, -12, -30, 63, -43, -19, -2,
+ -6, 20, 10, -18, -2, 23, 15, -3, -34, 1, 9, 10, -22, -29, 28, 28,
+ -32, -2, 23, -26, 2, 11, 25, -35, -14, 15, 23, -48, 12, 7, 22, -52,
+ 25, 17, 16, -47, 29, 13, -19, 12, -67, 65, -6, -30, 32, 7, -12, 14,
+ -19, 27, -52, -2, 15, 40, -69, -5, 33, 15, 6, -51, 36, 21, -2, -24,
+ 15, -3, -9, -4, 30, -34, -2, -19, 27, -23, 3, -12, 2, 18, -15, -6,
+ -3, 22, -30, 55, -21, 26, -35, 44, -27, 25, -21, 4, 14, -20, -1, 10,
+ -42, 12, 7, -12, 5, -37, 13, 1, 3, -33, 24, 15, 0, -4, 10, -14,
+ -6, 35, -6, -4, -8, 13, 26, -7, -32, 36, -9, 5, -15, 14, -15, -36,
+ 8, 2, -15, -22, -7, 28, -4, -25, 17, 39, -16, 4, 20, 8, 4, -2,
+ 4, 31, -46, -12, 15, 0, -9, -36, 18, -10, -12, 7, -17, 3, -13, -4,
+ 37, -27, 6, -16, 76, -41, 13, -14, 25, 28, -21, -10, 31, -4, -39, 21,
+ -9, -35, 12, 3, -16, 7, -54, 51, -34, 44, -45, 30, -7, -30, 49, -21,
+ -1, 27, 12, -8, 9, 8, 5, -27, 42, -30, 32, -28, -27, 19, -18, -36,
+ 10, -25, 19, -9, -14, -5, 13, 31, -21, 22, -28, 15, 13, 10, -12, 6,
+ 32, 1, 24, -47, 36, -4, -23, 0, -16, 6, -41, 1, 17, -33, -9, 5,
+ 34, -5, -15, -1, 30, 13, -30, 20, 7, -12, -16, 11, 20, -4, -19, 21,
+ 26, -25, -17, -5, 23, -32, -3, -12, 18, -5, -28, 8, 15, -14, -10, 31,
+ 11, -43, 12, 35, -5, 3, -33, 48, -1, -11, -6, 28, -23, -13, 13, 9,
+ -7, -22, 2, -25, 32, -38, 17, -16, 10, -54, 69, -62, 61, -30, 4, 24,
+ 3, -12, 4, 27, -22, 22, 0, 4, -15, 4, -46, 20, -16, 29, -30, 14,
+ -25, 30, -18, 16, -12, -7, 21, -10, 16, -23, 15, 9, -12, 12, 13, -21,
+ 19, -28, -2, 5, -15, 0, 3, -17, 6, -6, 18, -11, 6, 13, -1, 15,
+ -23, 14, 5, -17, -14, 5, 24, -23, 15, -26, 9, -10, 15, -29, 2, -12,
+ 23, 8, 10, -37, 26, 7, -5, -25, 3, 16, 14, -10, -5, -16, 22, -7,
+ -8, 18, -58, 86, -15, -5, 4, -30, 40, -7, -21, -12, 9, -10, 16, -48,
+ 40, -29, -6, -5, -22, 21, 3, -20, 39, -36, 29, -5, 2, 3, 15, 2,
+ 6, 21, -11, 28, -13, 2, -33, 24, 1, -28, 12, -33, 12, 11, 0, -41,
+ 11, -5, -9, 26, -34, 15, 2, 18, -7, -25, 5, 11, -4, -7, 35, -6,
+ 23, 12, -42, 33, -32, 26, -41, 25, -23, 15, -13, 11, -5, -4, 0, -8,
+ -4, 1, 10, 6, -8, -7, 18, 8, -11, -19, 9, 17, -2, -13, 8, -21,
+ 31, -16, -24, 3, -12, 10, 23, -8, 12, 8, 23, -7, -22, -8, 5, -5,
+ -14, -33, 4, 7, -11, -11, 15, -22, 38, -2, -11, 24, -16, 38, 14, -6,
+ 7, -14, 18, -13, 2, -8, -14, 13, -19, -13, 2, 2, -23, -9, 11, 1,
+ -12, 16, 1, 2, 18, 1, -20, 9, -5, -14, 16, -11, 2, 8, -2, -9,
+ 0, 11, 13, -22, 18, -16, 35, -39, 45, -22, -18, 12, 1, -19, 21, -48,
+ 42, -20, 9, -23, 20, -11, -27, 21, -13, -14, -11, 29, -13, 25, -25, 36,
+ -13, 8, 17, 34, -14, 11, 4, -4, -15, -9, -12, 1, 19, -69, 7, 10,
+ -34, -20, 1, -5, 13, 6, 34, -17, 5, 40, -1, 21, -38, 35, 22, 11,
+ -28, 28, 11, -25, -26, 12, -20, -38, 10, -16, -11, -11, -6, 13, -22, -31,
+ 43, -42, 49, -33, 20, 17, 13, -22, 44, -21, -4, 14, 9, 33, 10, 0,
+ -1, 0, 0, -2, 11, 23, 22, 24, 25, 20, 21, 15, 40, -1, -24, -42,
+ -5, -19, -11, -8, 4, -46, -31, -14, -33, -40, -44, -48, -89, -63, -47, -33,
+ -27, -10, -6, 22, 25, 26, 28, 37, 11, 15, 51, 44, 54, 66, 66, 71,
+ 111, 84, 70, 63, 47, 39, 22, 47, -28, -79, -111, -90, -91, -112, -81, -87,
+ -49, -46, -5, -24, 26, 24, 47, 29, 23, 30, 30, 13, -1, 4, -14, 17,
+ 35, 62, 31, 53, 59, 72, 64, 27, 26, 9, 9, -61, -44, -88, -74, -81,
+ -83, -124, -96, -37, -78, -48, -56, -68, -60, 7, 44, 39, 54, 77, 102, 110,
+ 108, 89, 101, 100, 105, 64, 22, -1, 44, 40, -19, -29, -35, -16, -27, -40,
+ -77, -82, -113, -104, -93, -57, -72, -56, -3, 1, 7, -1, 49, 39, 30, 31,
+ 23, 10, 31, 11, 7, -19, -2, -2, 28, 62, 92, 75, 33, 34, -20, -47,
+ -61, -85, -105, -93, -119, -112, -54, -70, -67, -32, -1, 4, 4, 20, 29, 62,
+ 70, 54, 62, 78, 115, 92, 85, 78, 52, 21, 19, 27, 2, -8, 13, 0,
+ 5, 3, 9, 18, 0, -59, -61, -45, -57, -65, -76, -89, -102, -48, -24, 17,
+ 6, 26, 33, 35, 26, 41, 63, 20, 12, 29, 34, 8, 7, 31, 21, 31,
+ 39, 33, -5, -8, -55, -57, -98, -94, -88, -64, -82, -74, -39, -14, 3, 16,
+ 22, 8, 2, 17, 5, 36, 76, 74, 71, 57, 73, 62, 47, 30, 32, 19,
+ 4, 7, -14, -18, -2, 17, -5, 13, 22, 31, 10, 8, -13, -47, -80, -85,
+ -86, -71, -73, -60, -35, -10, 9, 19, 49, 53, 47, 60, 73, 43, 33, 20,
+ 13, -1, -7, -7, 7, 9, -2, 5, -14, -40, -69, -61, -66, -67, -84, -58,
+ -58, -33, 2, -7, -5, 12, 32, 18, 25, 19, 24, 65, 59, 62, 64, 63,
+ 55, 60, 52, 31, 19, -12, -26, -4, -7, -10, -3, 6, -22, -14, 12, 19,
+ 4, -26, -38, -40, -56, -61, -66, -59, -65, -51, -20, 29, 40, 51, 52, 62,
+ 61, 53, 26, 20, 6, 8, 6, 9, -14, -14, -15, -2, -11, -23, -36, -38,
+ -60, -77, -69, -60, -51, -56, -44, -27, 10, -2, 14, 10, 22, 16, 41, 60,
+ 39, 35, 60, 62, 43, 45, 63, 52, 17, 12, 15, -1, -2, 0, -38, -48,
+ -32, -22, -7, 3, 13, 10, -2, -1, -8, -12, -25, -48, -46, -52, -49, -36,
+ -17, 9, 17, 26, 48, 57, 55, 69, 60, 32, 6, 4, -6, -20, -24, -9,
+ -21, -25, -14, -18, -38, -38, -32, -51, -52, -60, -34, -6, -6, -16, -11, -2,
+ -1, 17, 19, 3, 11, 25, 31, 41, 39, 33, 33, 41, 34, 34, 23, 21,
+ 15, 6, -13, -24, -28, -20, -8, -12, -19, -12, -5, 9, 14, 2, -12, -25,
+ -28, -21, -28, -23, -22, -18, -26, -5, 24, 45, 46, 47, 39, 33, 36, 42,
+ 29, 7, -5, -10, -21, -29, -39, -39, -31, -24, -29, -39, -51, -43, -27, -22,
+ -18, -25, -26, -20, 9, 19, 18, 4, -2, 19, 30, 38, 25, 24, 28, 33,
+ 41, 38, 34, 32, 38, 24, 8, 4, -8, -11, -15, -25, -31, -25, -20, -22,
+ -15, -11, -9, -12, -17, -20, -20, -15, -6, -11, -8, 0, 11, 29, 19, 17,
+ 17, 18, 28, 31, 25, 18, 23, 18, 10, 1, -7, -18, -26, -24, -30, -41,
+ -38, -44, -32, -31, -31, -35, -25, -12, -2, -8, -11, -13, -13, -2, 8, 15,
+ 19, 29, 35, 37, 39, 43, 42, 40, 35, 27, 25, 18, 15, 9, 4, -4,
+ -15, -28, -28, -26, -28, -18, -15, -25, -23, -12, -11, -14, -10, -2, -4, -1,
+ 8, 15, 19, 22, 25, 16, 16, 17, 5, 7, 13, 18, 13, 9, 6, 6,
+ 4, -4, -21, -31, -28, -37, -39, -34, -38, -38, -32, -17, -6, -4, -14, -19,
+ -9, 3, -2, 3, 4, 7, 8, 13, 23, 35, 38, 43, 42, 31, 25, 23,
+ 17, 8, 3, 4, -7, -7, -10, -13, -20, -19, -28, -33, -30, -23, -18, -13,
+ -17, -12, 3, 14, 23, 31, 27, 23, 21, 22, 19, 12, 4, 2, 2, -2,
+ 0, 4, 11, 11, 6, 4, -2, -5, -14, -17, -30, -38, -44, -42, -28, -21,
+ -23, -21, -15, -15, -4, 8, 11, 4, -7, -15, -7, 5, 10, 21, 26, 28,
+ 27, 34, 37, 36, 28, 19, 10, 11, 8, -2, -18, -17, -19, -19, -22, -24,
+ -21, -24, -18, -17, -13, -19, -13, -1, 12, 19, 22, 21, 19, 19, 30, 34,
+ 24, 13, 7, 2, 1, 1, 2, -1, -2, -6, 0, 0, -2, -15, -21, -17,
+ -21, -28, -32, -31, -31, -32, -27, -24, -17, -4, 1, -3, -1, 1, 4, 7,
+ 8, 15, 16, 15, 15, 20, 32, 36, 38, 32, 19, 12, 3, 2, -2, -4,
+ -11, -19, -17, -15, -11, -16, -20, -27, -30, -28, -22, -13, -6, -2, 2, 12,
+ 23, 29, 45, 44, 36, 32, 21, 16, 14, 10, 1, -9, -8, -2, -1, -7,
+ -13, -13, -12, -9, -11, -18, -24, -26, -28, -30, -24, -21, -21, -21, -11, -11,
+ -10, 0, -2, 0, 4, 12, 13, 14, 12, 17, 22, 28, 30, 28, 20, 16,
+ 13, 8, 2, -2, -6, -15, -14, -18, -15, -15, -16, -18, -18, -16, -19, -18,
+ -17, -10, 0, -1, 4, 13, 22, 37, 39, 36, 27, 27, 32, 26, 15, 6,
+ -1, -4, -5, -7, -11, -11, -9, -15, -15, -14, -18, -21, -19, -17, -21, -19,
+ -15, -15, -10, -15, -14, -12, -11, -6, -2, 1, -2, 1, 5, 14, 22, 33,
+ 35, 23, 18, 16, 13, 11, 6, 1, -9, -18, -11, -6, -7, -8, -9, -11,
+ -11, -12, -13, -17, -21, -24, -24, -15, -4, 7, 12, 17, 25, 30, 28, 31,
+ 32, 31, 27, 22, 15, 12, 3, -2, -8, -6, -3, -9, -13, -22, -24, -20,
+ -18, -22, -24, -18, -14, -13, -10, -11, -9, -3, -2, -3, -5, -10, -10, -5,
+ -1, 4, 11, 15, 19, 22, 27, 23, 20, 16, 14, 5, -3, -11, -15, -16,
+ -12, -12, -11, -5, 1, -3, -10, -13, -15, -11, -10, -10, -11, -8, -3, 2,
+ 7, 9, 15, 25, 30, 33, 31, 25, 21, 20, 16, 13, 7, -2, -8, -5,
+ -4, -11, -20, -21, -22, -21, -17, -20, -21, -22, -19, -19, -11, -4, -2, -2,
+ -2, 2, 5, 2, 0, 0, -3, 1, 8, 16, 13, 14, 17, 15, 13, 8,
+ 5, -1, -6, -10, -13, -14, -14, -13, -10, -7, -8, -8, -6, -6, -3, -1,
+ -1, -9, -12, -7, 3, 13, 17, 14, 13, 17, 22, 23, 24, 18, 15, 18,
+ 18, 18, 15, 8, 0, -5, -8, -11, -15, -17, -21, -26, -26, -24, -26, -24,
+ -13, -9, -6, -3, -2, 3, 4, 6, 7, 5, 2, 4, 2, -2, -4, -3,
+ 5, 13, 17, 10, 3, -1, -2, -4, -5, -11, -14, -13, -11, -8, -8, -8,
+ -6, -3, 0, -1, -5, -5, 0, 4, 3, 1, 2, 0, 0, 6, 13, 20,
+ 17, 17, 18, 21, 18, 14, 13, 11, 11, 7, 9, 3, -5, -12, -14, -18,
+ -21, -23, -26, -26, -13, -3, -6, -13, -14, -5, 5, 8, 3, 0, 1, 3,
+ 6, 4, -1, -1, 1, 3, 7, 5, 3, 0, 1, -1, 3, 0, -3, -11,
+ -11, -9, -10, -9, -8, -5, -7, -7, -10, -9, -6, -1, 4, 6, 4, 2,
+ 5, 10, 13, 9, 12, 13, 14, 15, 16, 13, 12, 10, 13, 14, 13, 8,
+ 2, -1, -4, -6, -9, -15, -20, -21, -19, -14, -16, -22, -21, -13, -5, -3,
+ -3, -1, 3, 5, 10, 9, 9, 6, 8, 7, 7, 7, 3, -4, -6, -4,
+ -1, -4, -8, -10, -11, -8, -4, -6, -10, -7, -8, -11, -11, -8, -5, -4,
+ 0, 3, 3, 8, 10, 10, 12, 12, 11, 10, 13, 12, 10, 6, 8, 9,
+ 9, 11, 13, 11, 9, 10, 7, 2, -3, -8, -9, -14, -16, -16, -19, -18,
+ -14, -13, -11, -11, -10, -5, -1, 3, 5, 2, 2, 9, 14, 11, 9, 10,
+ 7, 2, 0, 2, -2, -9, -13, -15, -18, -17, -15, -13, -10, -5, -5, -7,
+ -7, -4, -1, 0, -2, -4, -2, 1, 4, 9, 10, 10, 11, 11, 13, 14,
+ 10, 11, 9, 9, 4, 6, 5, 4, 5, 7, 8, 10, 9, 4, -4, -8,
+ -9, -10, -11, -12, -14, -15, -17, -15, -9, -4, -1, -6, -5, 2, 8, 8,
+ 6, 5, 3, 4, 5, 9, 10, 10, 5, -1, -5, -10, -12, -14, -16, -18,
+ -17, -11, -10, -11, -8, -5, -2, -2, 0, 3, 4, 5, 3, 2, 3, 5,
+ 9, 12, 12, 11, 10, 12, 14, 12, 8, 5, 0, -1, 1, 3, 0, 1,
+ 3, 5, 6, 5, 0, -5, -11, -10, -13, -12, -13, -15, -14, -8, -4, -3,
+ -3, -4, 0, 4, 5, 3, 6, 4, 4, 7, 10, 9, 9, 8, 5, 5,
+ 2, -4, -10, -15, -17, -20, -22, -22, -19, -14, -11, -10, -8, -6, 0, 3,
+ 5, 3, 4, 8, 11, 11, 12, 13, 12, 12, 15, 15, 16, 16, 13, 11,
+ 6, 3, -2, -5, -5, -3, -2, -1, 2, 0, -3, -4, -5, -7, -10, -12,
+ -11, -12, -11, -8, -4, -2, 0, 1, 2, 2, 2, 4, 3, 3, 4, 5,
+ 9, 10, 6, 2, 1, 2, 0, -3, -7, -13, -18, -19, -18, -16, -18, -20,
+ -19, -14, -8, -4, -1, 3, 3, 5, 7, 9, 9, 10, 12, 13, 13, 13,
+ 13, 16, 15, 13, 9, 6, 3, 2, 1, 0, -3, -5, -6, -4, -2, -2,
+ -4, -4, -5, -5, -3, -3, -4, -6, -6, -7, -4, 0, 2, 3, 2, 2,
+ 1, 2, 2, 1, 4, 5, 4, 1, 0, 2, 2, 0, -2, -6, -8, -6,
+ -7, -9, -11, -15, -18, -19, -18, -18, -17, -13, -9, -2, 2, 3, 5, 10,
+ 12, 13, 14, 14, 15, 17, 17, 16, 16, 15, 13, 11, 7, 2, -6, -10,
+ -8, -6, -8, -8, -7, -6, -6, -3, -4, -6, -5, -3, -2, -2, 0, 1,
+ 0, 2, 2, 3, 2, 3, 2, 3, 3, 5, 2, 0, 4, 6, 5, -1,
+ -4, -2, -1, -2, -6, -8, -9, -10, -12, -10, -14, -17, -22, -22, -21, -19,
+ -15, -8, -3, 1, 7, 12, 12, 15, 19, 22, 21, 18, 16, 16, 16, 13,
+ 12, 6, 3, 3, 2, -3, -6, -7, -12, -12, -11, -8, -9, -8, -7, -3,
+ 0, 0, 0, 0, -2, -2, 0, 1, 2, 2, 4, 6, 6, 7, 5, 4,
+ 3, 4, 5, 3, 0, -2, -2, -4, -6, -10, -8, -8, -10, -11, -12, -12,
+ -12, -13, -16, -16, -16, -14, -11, -8, -4, -2, 1, 6, 12, 17, 19, 20,
+ 20, 21, 21, 19, 13, 10, 9, 5, 0, -3, -4, -4, -5, -6, -6, -4,
+ -7, -10, -12, -12, -12, -10, -7, -4, -2, 4, 6, 8, 7, 7, 7, 7,
+ 8, 8, 7, 5, 6, 6, 4, 1, -1, -1, 0, -3, -7, -10, -10, -8,
+ -11, -14, -14, -12, -11, -9, -6, -8, -8, -8, -11, -13, -12, -9, -8, -5,
+ 0, 4, 8, 11, 14, 18, 18, 20, 23, 23, 20, 14, 9, 4, 0, -3,
+ -6, -8, -8, -8, -8, -9, -10, -11, -10, -9, -8, -8, -7, -6, -3, 0,
+ 3, 6, 12, 16, 16, 14, 10, 8, 9, 7, 4, 1, 0, 0, -2, -1,
+ 0, 0, -3, -7, -10, -13, -13, -12, -13, -15, -14, -13, -9, -6, -5, -5,
+ -7, -8, -9, -7, -6, -5, -7, -5, 1, 8, 13, 17, 19, 20, 21, 22,
+ 22, 18, 12, 9, 5, -1, -5, -9, -11, -13, -12, -12, -11, -10, -8, -7,
+ -7, -6, -7, -6, -3, 0, 1, 3, 7, 10, 11, 12, 15, 15, 14, 9,
+ 6, 3, 1, 0, -2, -2, -2, -3, -6, -8, -10, -11, -13, -15, -15, -15,
+ -13, -12, -12, -7, -5, -5, -5, -4, -3, -3, -4, -4, -1, -1, 1, 4,
+ 7, 10, 12, 14, 17, 20, 22, 19, 14, 8, 5, 2, -2, -5, -10, -14,
+ -13, -11, -10, -10, -10, -10, -8, -6, -3, -3, -3, -1, -1, 2, 6, 10,
+ 13, 14, 15, 15, 15, 13, 11, 8, 5, 1, -1, -3, -3, -6, -10, -12,
+ -12, -12, -12, -13, -15, -18, -19, -15, -11, -6, -4, -3, -4, -4, -2, 1,
+ 4, 2, -1, -2, 1, 4, 6, 8, 7, 7, 11, 14, 15, 15, 15, 13,
+ 10, 6, 1, -3, -6, -9, -13, -15, -15, -13, -11, -9, -9, -9, -7, -3,
+ 0, 2, 2, 4, 7, 11, 15, 16, 14, 11, 12, 13, 15, 13, 9, 4,
+ 1, -1, -4, -6, -8, -11, -15, -17, -17, -17, -17, -15, -13, -13, -12, -10,
+ -7, -6, -4, 1, 2, 2, 3, 4, 5, 4, 4, 3, 5, 6, 6, 8,
+ 7, 7, 9, 11, 10, 9, 8, 5, 2, 0, -2, -6, -10, -13, -13, -14,
+ -14, -13, -11, -9, -4, -1, -1, -1, 2, 6, 8, 10, 11, 12, 14, 14,
+ 14, 13, 11, 10, 7, 4, 2, 3, 1, -3, -6, -10, -14, -17, -18, -18,
+ -19, -19, -17, -15, -13, -9, -5, -1, 1, 0, 1, 3, 5, 6, 6, 6,
+ 7, 8, 9, 8, 4, 1, 0, 2, 4, 5, 6, 5, 4, 4, 4, 3,
+ 1, -3, -7, -9, -11, -12, -12, -12, -11, -10, -7, -4, -2, 1, 4, 5,
+ 8, 11, 13, 14, 14, 11, 11, 11, 10, 10, 9, 6, 5, 3, 1, -2,
+ -5, -10, -14, -16, -17, -18, -19, -20, -19, -17, -14, -10, -5, -1, 1, 3,
+ 5, 6, 6, 6, 6, 6, 6, 6, 6, 8, 7, 6, 4, 2, 0, -1,
+ 0, 0, 1, 2, 1, 1, 2, 1, -2, -5, -8, -9, -10, -11, -12, -12,
+ -10, -7, -4, -1, 2, 8, 11, 13, 15, 15, 13, 12, 11, 10, 9, 8,
+ 6, 5, 4, 4, 3, 0, -3, -6, -10, -14, -18, -21, -22, -21, -18, -16,
+ -13, -10, -6, -3, 0, 3, 5, 5, 5, 6, 7, 8, 8, 8, 7, 8,
+ 7, 6, 5, 4, 1, 0, -2, -4, -4, -5, -4, -4, -3, -2, -1, -2,
+ -3, -4, -7, -8, -9, -9, -9, -8, -5, -2, 2, 4, 8, 11, 14, 15,
+ 15, 14, 12, 10, 7, 5, 4, 4, 2, 1, 1, 2, -1, -3, -7, -10,
+ -15, -18, -18, -18, -18, -17, -15, -11, -7, -3, 1, 3, 4, 5, 6, 7,
+ 7, 8, 8, 9, 10, 10, 9, 6, 4, 2, 0, -3, -4, -6, -7, -7,
+ -6, -5, -3, -2, -2, -2, -2, -3, -4, -5, -6, -6, -6, -6, -5, -4,
+ -1, 4, 7, 9, 11, 12, 12, 11, 10, 9, 8, 7, 5, 3, 3, 2,
+ 1, 0, -1, -4, -7, -8, -10, -13, -14, -15, -15, -15, -14, -11, -9, -6,
+ -3, 0, 2, 4, 5, 6, 7, 8, 9, 10, 10, 9, 8, 6, 5, 3,
+ 1, -3, -6, -8, -8, -7, -7, -7, -6, -4, -2, 0, -1, -2, -3, -3,
+ -3, -3, -4, -3, -3, -1, 1, 3, 4, 6, 7, 8, 9, 10, 10, 9,
+ 7, 6, 6, 4, 3, 2, 1, -1, -2, -4, -6, -9, -11, -12, -12, -12,
+ -11, -11, -10, -9, -8, -7, -5, -4, -1, 1, 3, 5, 7, 9, 10, 11,
+ 10, 9, 8, 7, 6, 2, -1, -3, -4, -6, -7, -7, -7, -7, -6, -5,
+ -5, -4, -3, -3, -4, -4, -4, -3, -2, 0, 0, 1, 1, 2, 4, 6,
+ 6, 7, 7, 8, 7, 7, 7, 7, 7, 6, 5, 2, 0, -2, -4, -5,
+ -7, -8, -8, -8, -9, -10, -10, -9, -8, -7, -7, -7, -5, -3, -2, 0,
+ 1, 2, 4, 6, 9, 10, 11, 12, 10, 8, 6, 3, 1, -2, -4, -6,
+ -7, -7, -7, -7, -8, -7, -7, -6, -6, -5, -4, -3, -3, -2, -1, 1,
+ 2, 2, 3, 4, 5, 5, 5, 6, 6, 6, 5, 5, 6, 6, 6, 4,
+ 3, 2, 1, -1, -3, -4, -6, -8, -9, -9, -8, -8, -6, -5, -5, -5,
+ -6, -6, -6, -5, -4, -2, 0, 2, 4, 6, 7, 8, 9, 9, 9, 9,
+ 6, 4, 1, -1, -3, -5, -6, -7, -7, -7, -6, -6, -6, -6, -6, -5,
+ -4, -3, -3, -2, -1, 1, 3, 4, 5, 5, 5, 5, 5, 5, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 2, 1, -1, -3, -4, -5, -6, -7, -7,
+ -7, -7, -7, -6, -5, -4, -4, -3, -3, -3, -3, -2, -1, 0, 1, 3,
+ 5, 7, 8, 8, 8, 7, 6, 4, 2, 0, -2, -3, -4, -5, -6, -7,
+ -7, -7, -7, -6, -6, -5, -5, -5, -3, -2, 0, 1, 2, 3, 4, 5,
+ 6, 6, 6, 5, 5, 4, 3, 3, 3, 3, 3, 3, 2, 1, 1, -1,
+ -2, -3, -4, -5, -6, -6, -7, -6, -5, -4, -3, -3, -3, -3, -3, -2,
+ -1, -1, 0, 1, 1, 1, 2, 3, 5, 6, 6, 6, 5, 4, 2, 1,
+ 0, -2, -4, -5, -5, -6, -6, -6, -7, -7, -7, -6, -5, -4, -3, -2,
+ -1, 0, 2, 3, 3, 4, 4, 5, 5, 5, 4, 4, 4, 4, 3, 3,
+ 2, 1, 1, 0, 0, -1, -1, -2, -3, -4, -5, -5, -5, -5, -5, -4,
+ -4, -3, -3, -2, -1, -1, -1, -1, 0, 0, 0, 1, 2, 3, 3, 4,
+ 4, 4, 4, 4, 3, 1, 0, 0, -2, -3, -4, -5, -5, -6, -6, -6,
+ -5, -4, -4, -4, -3, -2, -2, -1, 0, 2, 3, 3, 4, 4, 4, 4,
+ 3, 3, 3, 3, 2, 2, 1, 1, 1, 0, -1, -1, -2, -3, -3, -3,
+ -3, -3, -3, -3, -3, -3, -3, -2, -2, -2, -1, -1, -1, 0, 0, 0,
+ 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 1, 1, 0, 0, -1, -1,
+ -2, -3, -3, -3, -4, -4, -4, -4, -3, -3, -2, -1, -1, -1, 0, 1,
+ 1, 1, 2, 2, 2, 3, 3, 2, 2, 1, 1, 1, 0, 0, 0, 0,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ 0, 0, -8, -33, -24, -25, -25, -26, -27, -32, -28, -36, -31, -36, -22, -34,
+ 11, -74, -14, 94, 41, 28, 33, 30, 40, 34, 23, 41, 40, 60, 56, 59,
+ 60, 44, 39, 54, 45, 52, 17, 44, 62, 34, 33, 19, 18, 43, 35, 22,
+ 36, -15, -10, 32, -7, -12, -6, -8, -50, -47, -44, -4, -25, -48, -76, -58,
+ -75, -96, -85, -118, -114, -63, -106, -103, -83, -110, -99, -84, -76, -58, -63, -61,
+ -51, -53, -36, -32, -41, -27, -11, 11, 8, 27, 19, 30, 35, 28, 57, 53,
+ 38, 71, 51, 68, 110, 78, 89, 109, 97, 82, 94, 115, 114, 79, 70, 79,
+ 94, 85, 76, 84, 95, 83, 82, 55, 54, 54, 41, 41, 27, 20, 6, -11,
+ -21, -16, -14, -33, -33, -52, -54, -59, -62, -71, -79, -88, -88, -78, -78, -72,
+ -71, -94, -99, -93, -90, -78, -87, -105, -103, -79, -62, -71, -78, -63, -61, -66,
+ -49, -23, -10, -11, -24, -20, -4, -22, 9, 8, 27, 43, 34, 38, 51, 83,
+ 65, 58, 74, 75, 70, 73, 71, 65, 100, 89, 94, 65, 84, 49, 49, 61,
+ 54, 43, 51, 58, 53, 35, 40, 36, 38, 34, 23, 14, -12, -10, -1, -1,
+ -11, -12, -19, -33, -66, -52, -42, -37, -55, -42, -28, -32, -29, -35, -41, -28,
+ -25, -46, -85, -64, -62, -55, -49, -68, -55, -53, -52, -47, -43, -26, -32, -41,
+ -34, -35, -40, -26, -8, -1, -6, -11, 5, -2, 8, 3, 8, 6, 4, 20,
+ 29, 43, 24, 33, 20, 30, 24, 39, 38, 40, 29, 37, 36, 39, 61, 58,
+ 41, 51, 59, 51, 55, 58, 48, 32, 45, 40, 27, 30, 41, 44, 26, 19,
+ 23, -3, 7, 0, -3, 2, 3, -6, -5, -14, -6, -10, -27, -45, -47, -41,
+ -38, -50, -51, -46, -43, -45, -65, -65, -80, -95, -82, -74, -66, -69, -67, -33,
+ -31, -53, -48, -51, -43, -18, -24, -24, -33, -26, -10, 0, -17, -6, 17, 31,
+ 2, 23, 45, 46, 12, 75, 38, 63, 69, 31, 38, 80, 57, 48, 59, 81,
+ 74, 32, 52, 72, 24, 60, 44, 55, 40, 28, 48, 33, 24, 10, -2, 21,
+ 34, 13, 18, 7, -1, -12, -20, -18, -30, -9, -7, -30, -27, -26, -38, -20,
+ -54, -55, -64, -53, -36, -62, -37, -71, -47, -42, -71, -45, -55, -50, -54, -56,
+ -36, -37, -54, -36, -12, -38, -33, -26, -7, -22, -44, -10, 2, 3, 15, 8,
+ 18, 6, 12, 8, 15, 28, 22, 50, 35, 55, 42, 36, 49, 52, 64, 48,
+ 60, 49, 60, 62, 40, 47, 68, 52, 59, 61, 44, 53, 44, 35, 31, 31,
+ 47, 22, 6, 4, -7, 5, -4, -21, -13, -9, -10, -27, -46, -32, -44, -46,
+ -62, -44, -51, -67, -53, -59, -63, -74, -67, -61, -61, -65, -47, -58, -57, -45,
+ -41, -46, -41, -38, -22, -25, -34, -16, -10, -18, 0, 1, -6, 5, 17, 15,
+ 10, 23, 38, 28, 28, 54, 40, 19, 55, 55, 41, 46, 53, 40, 49, 51,
+ 52, 41, 56, 39, 53, 38, 33, 35, 18, 15, 38, 30, 23, 27, 13, 11,
+ 7, 16, -1, 0, 0, 13, -6, -10, -15, -10, -10, -24, -20, -16, -38, -36,
+ -21, -40, -32, -42, -38, -52, -53, -41, -48, -58, -50, -47, -37, -41, -45, -29,
+ -41, -6, -48, -24, -25, -15, -9, -10, -10, -10, -1, -17, 4, 3, 10, -4,
+ 9, 15, 25, 24, 19, 23, 34, 28, 33, 37, 38, 26, 36, 47, 35, 46,
+ 45, 28, 35, 32, 32, 24, 21, 26, 23, 19, 37, 20, 9, 29, -2, 26,
+ 24, 8, 4, 14, 21, 11, -9, -8, 4, -9, -31, -11, -15, -21, -24, -29,
+ -22, -33, -26, -29, -48, -32, -44, -28, -22, -35, -30, -38, -31, -46, -44, -36,
+ -27, -23, -29, -24, -11, -20, -28, -13, -34, -19, -1, 7, -3, -1, 6, -3,
+ 5, 4, 8, 17, 26, 19, 33, 27, 16, 35, 14, 36, 39, 22, 32, 31,
+ 19, 32, 23, 29, 21, 30, 29, 23, 31, 13, 24, 17, 11, 26, 18, 12,
+ 5, 23, 16, 9, 15, -10, 3, 18, -15, -4, -4, 6, -14, -15, -5, -34,
+ -11, -20, -18, -8, -17, -29, -30, -29, -19, -34, -35, -20, -36, -20, -16, -21,
+ -38, -16, -30, -24, -25, -19, -18, -15, -7, -5, -5, -10, -23, -3, -14, 0,
+ -1, -12, -9, 7, 7, 2, 12, 5, 7, 19, 10, 21, 21, 27, 30, 22,
+ 18, 34, 22, 11, 26, 24, 20, 21, 25, 29, 22, 27, 27, 20, 10, 20,
+ 16, 22, 15, 16, 16, 5, 19, 10, 3, 22, -5, -5, -7, -16, -4, -11,
+ -22, -7, -16, -11, -23, -16, -30, -24, -28, -20, -29, -24, -32, -22, -22, -30,
+ -17, -23, -28, -22, -20, -21, -21, -17, -30, -15, -14, -20, -9, 3, 6, 5,
+ -20, 10, 13, -2, 11, 8, -1, 7, 16, 5, 22, 23, 13, 22, 13, 22,
+ 25, 15, 16, 11, 15, 13, 7, 12, 19, 18, 20, 12, 23, 11, 6, 10,
+ 1, 11, 19, 5, 20, 0, 11, 11, 1, 14, 15, -3, -1, -7, 6, -6,
+ -9, -9, 4, -3, -10, -20, -14, -9, -14, -7, -10, -5, -4, -29, -14, -12,
+ -26, -21, -27, -18, -10, -19, -27, -18, -8, -25, -8, -13, -15, -14, -15, 5,
+ -13, -7, -11, -4, -12, 0, 15, 5, 4, 1, 11, 6, 4, 3, 6, 21,
+ 19, 8, 15, 13, 6, 14, 16, 18, 17, 20, 15, 11, 15, 24, 13, 11,
+ 19, 7, 17, 14, 6, 17, 7, 7, 6, 6, 5, 11, 0, 6, 0, -6,
+ 5, 1, -11, -6, -1, -8, -9, -15, -7, -4, -16, -17, -13, -13, -17, -14,
+ -12, -12, -28, -13, -19, -25, -31, -24, -17, -17, -16, -7, -15, -12, -8, -15,
+ -8, -16, -10, -4, -1, -2, 3, 5, 2, -2, 5, 3, 6, 10, 8, 11,
+ 14, 14, 13, 15, 22, 16, 14, 18, 13, 17, 19, 16, 10, 17, 8, 17,
+ 14, 3, 14, 7, 10, 10, 7, 6, 6, -1, 6, 1, 0, 12, -6, 6,
+ 12, -4, -5, -4, -2, -2, -1, -2, -8, -11, -9, -11, -11, -18, -6, -5,
+ -16, -9, -14, -10, -13, -10, -11, -15, -14, -14, -12, -17, -17, -17, -7, -11,
+ -14, -15, -12, -6, -15, -5, -13, -9, 0, 12, -2, -2, 6, 2, -7, 4,
+ 10, 2, 9, 8, 7, 4, 5, 11, 15, 11, 10, 18, 9, 13, 13, 13,
+ 21, 11, 18, 19, 13, 14, 16, 6, 8, 1, 19, 11, 10, 11, 1, 3,
+ -1, -1, 5, -11, 5, -1, -5, -3, -13, -10, -6, -7, -5, -15, -10, -11,
+ -18, -8, -16, -20, -18, -9, -12, -17, -21, -21, -13, -21, -8, -10, -10, -5,
+ -16, -7, 2, -6, -6, -9, -7, -2, -9, -5, 6, -7, 1, 3, -1, 2,
+ 1, 2, 9, 8, 5, 15, 12, 1, 11, 9, 8, 10, 15, 14, 5, 13,
+ 17, 14, 15, 10, 7, 16, 5, 5, 5, 8, 9, 10, 10, 7, 0, 4,
+ 6, 9, -10, -4, 5, 2, -1, 0, -3, -4, -5, -10, -5, -8, -9, -10,
+ -3, -13, -6, -9, -20, -15, -11, -18, -14, -10, -12, -20, -14, -14, -7, -12,
+ -21, -14, -9, -8, -11, -5, -2, -7, -4, 4, -2, -3, -1, 0, -1, 8,
+ 6, 9, 7, 10, 6, 3, 4, 7, 10, 11, 6, 9, 17, 11, 9, 7,
+ -2, 16, 13, 12, 18, 5, 16, 9, 4, 9, 6, 8, 9, 4, 4, 3,
+ -2, -3, 2, -6, -3, 1, -7, -6, -3, -6, -14, -8, -9, -4, -13, -9,
+ -8, -16, -10, -12, -13, -11, -7, -8, -12, -9, -8, -7, -11, -4, -8, -7,
+ -8, -3, -13, -10, -3, 6, -5, -5, 0, -5, -3, 6, -2, -2, 4, -2,
+ 6, 2, -2, 5, 5, -2, 5, 15, 13, 4, 6, 6, 14, 9, 4, 8,
+ 7, 3, 11, 12, 2, 10, 7, 10, 8, 4, 6, 2, 0, 3, 2, 4,
+ 2, -6, -2, 2, -4, 3, -5, -6, -5, -5, -5, -4, -8, -7, -4, -4,
+ -7, -8, -7, -13, -10, -10, -11, -9, -8, -8, -7, -11, -7, -3, -9, -6,
+ -7, -3, -4, -5, 3, -3, -1, -2, -4, 1, 4, 0, 3, 0, 5, 2,
+ 0, 5, 4, 1, 3, 1, 0, 1, 7, 3, 0, 4, 3, 6, 5, 0,
+ 9, 5, 7, 6, 3, 6, 2, 3, 5, -4, 9, 0, 4, 10, 0, 5,
+ 1, -2, 4, -3, -3, -2, 0, 2, -7, 3, -10, -1, -6, -9, -2, -4,
+ -10, -3, -7, -6, -4, -10, -6, -6, -11, -6, 0, -6, -8, -4, -1, -9,
+ -10, 0, -6, -7, -2, -7, 1, -5, -5, -1, 1, -6, 2, 0, -3, -1,
+ 7, -4, 0, 7, 0, 8, 2, 3, 4, 4, 2, 5, -1, 6, 7, 5,
+ 6, 4, 2, 4, 6, 8, 6, 3, 1, 8, 9, 2, -1, 4, 3, 4,
+ 3, -3, 7, 4, 3, -2, 2, -4, -6, -2, -5, -2, -3, 0, -5, -6,
+ -13, -5, -6, -11, -9, -10, -5, -4, -9, -9, -7, -7, -8, -8, -6, -5,
+ -7, -5, -1, -3, -4, -2, -2, 2, -3, 1, 2, -3, 1, 2, 1, 0,
+ 1, 5, 0, 2, 5, 2, 0, 4, 1, 7, 3, 2, 6, 0, 5, 7,
+ 5, 5, 1, 3, 3, 5, 10, 3, 4, 8, 2, 7, 3, -2, 3, 0,
+ -1, -1, 1, 0, 1, -3, -2, -5, -4, -3, -1, -7, -8, -4, -4, -10,
+ -2, -8, -8, -8, -8, -9, -6, -8, -9, -4, -2, -7, -5, -2, -7, -6,
+ -9, -2, 0, -4, 4, -6, -3, -4, -1, 2, 1, 2, 9, 0, 3, 0,
+ 6, 4, 0, 5, 6, 2, 7, 7, 5, 7, 6, 8, 6, 6, 5, 5,
+ 1, 6, 5, -1, 3, 4, -1, 4, 1, 4, 3, -5, 0, 4, 1, 4,
+ -2, -3, -4, 0, -4, -8, -2, -5, -4, -8, -6, -5, -3, -3, -7, -9,
+ -6, -10, -10, -6, -6, -5, -4, -7, -6, -4, -10, -3, -10, 0, -2, -2,
+ -6, -1, 3, -3, -3, 1, 2, 1, 4, 3, 4, 3, 4, 1, 2, 6,
+ 5, 5, 5, 7, 9, 1, 5, 4, 4, 7, 2, 9, 2, 4, 8, 2,
+ 5, 6, 3, -2, -2, -1, -2, -1, 1, -2, -4, 1, -6, -2, -5, -3,
+ -5, -5, -6, -4, -3, -4, -10, -4, -3, -8, -4, 0, -3, -5, -6, -6,
+ -3, -1, -7, -3, 1, -1, -4, -2, 1, -2, 0, -1, -2, 0, 0, 5,
+ -2, 0, 3, 3, 1, 5, 2, 4, 1, 4, 1, 2, 3, 3, 3, 4,
+ 3, 3, 5, 1, 4, 2, 3, 1, 2, 0, 2, 1, -2, -2, -1, 0,
+ -2, -1, -1, -3, -5, -2, 0, -5, -1, 0, -5, -2, -2, -2, -3, -3,
+ -1, -4, -1, -2, -4, -2, -1, -2, -1, 0, -3, -1, -1, 0, 1, -1,
+ -1, 3, -4, -2, -2, 4, -2, -1, -1, -1, 0, 0, -1, -1, -1, -1,
+ 2, 0, -1, 2, -1, 0, -1, 2, 0, 3, 5, -2, 1, 2, 0, 5,
+ 0, -3, 4, -3, 1, 2, 0, 4, -1, -2, 1, 0, 0, 0, -1, 1,
+ -2, 0, 1, 1, 0, -5, 1, -2, -1, 0, -2, -3, -1, -3, 0, -2,
+ -3, -4, 1, -2, -3, -2, -2, -1, -1, -2, -1, -4, -5, 2, -4, 0,
+ 1, -1, 2, -2, -1, 0, 0, 1, -3, 3, 2, 0, -2, 2, 1, 2,
+ -2, 5, 3, -2, -2, -1, 1, 0, 0, 1, 3, 2, 0, 0, -1, -2,
+ 1, 1, 2, 1, 1, -1, 0, -1, -1, -1, -3, 1, 1, 2, -2, -1,
+ 0, 0, -2, 0, -1, -1, 2, -2, 1, -1, 0, 0, -1, -1, -2, 0,
+ -1, 1, -1, -1, 2, -2, 0, -1, -1, 2, -1, 0, -3, -1, 0, 0,
+ 0, -3, -3, -2, 0, 0, -1, -1, 0, -4, 2, 0, -2, 0, 1, -3,
+ -1, 2, 1, 0, -1, 0, 0, -1, 0, 2, -1, -1, 0, 0, -2, 1,
+ 1, 0, 1, 0, 2, -3, -2, 2, -1, -1, 2, -2, 1, 1, 0, 0,
+ 1, 1, 0, -4, 3, -1, 2, 0, 2, -1, -2, 0, 1, 1, -1, -1,
+ -1, -1, -1, -2, -2, -2, -2, -2, -1, -1, 1, 0, -5, 0, -1, -1,
+ -1, 1, -1, 1, -1, 1, 0, -2, 0, -2, 1, -1, 1, 0, -1, -2,
+ 0, -1, 0, 0, 2, 0, 0, 0, 1, 0, 0, 2, 0, -1, 0, 0,
+ 0, 2, -1, 1, 1, -1, -1, 0, 0, 1, 1, 0, 0, 0, 0, -1,
+ 0, 0, -2, 0, 0, -1, 1, -2, -1, -1, -1, -2, -1, -2, 1, -1,
+ 0, -2, -2, 1, -2, -1, 1, 0, 1, 1, -1, -1, 0, -1, 0, 0,
+ 0, -2, 0, -1, 0, 0, -1, -2, -2, -2, 1, -1, 0, 0, -1, 1,
+ 1, -2, -1, -2, -1, 1, -1, -1, -2, -2, 0, 0, 1, -1, -1, -1,
+ -1, -2, 2, 0, 0, 1, 1, 1, -2, 0, -1, 0, -1, -1, 2, 0,
+ -1, -1, -1, 1, -1, 2, 0, -1, 1, 1, 0, 1, 0, -1, -1, -1,
+ -1, -3, 0, 0, -1, 1, 0, 0, -2, -2, -2, 0, -1, 0, 0, -1,
+ 0, -1, -2, -1, -2, 0, -2, 0, 0, -1, -2, 1, -2, 0, -1, -2,
+ 2, 0, -1, 2, -1, 1, -1, 0, 0, -1, 0, 0, 0, -1, 0, 1,
+ 0, 0, 1, 0, -1, -1, 0, -2, -1, 0, 0, 1, 0, 0, 0, 0,
+ -1, -1, 1, -1, -2, -1, 0, 0, -2, 0, -1, 0, 0, 0, 1, 0,
+ 0, -1, 1, 0, -1, 0, 1, -1, 0, -1, -2, 0, -1, 0, -1, -1,
+ -1, 0, -1, 0, 0, 0, -1, -1, 0, -2, 0, 0, 0, -2, -2, 0,
+ -2, -1, -1, -1, -2, 0, -1, -1, -1, 0, 0, -1, -1, 0, 1, -1,
+ -1, 0, -1, 0, 0, 1, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1,
+ -1, 0, 0, 0, 1, 0, 0, -1, 0, 0, -1, -1, 0, -1, -1, 0,
+ -1, 0, -1, -1, 0, -2, -1, 0, -1, -1, -1, -1, 0, -1, 0, 0,
+ 0, 0, -1, 1, 0, 0, 0, -1, -1, 0, -1, -1, 0, 0, 0, 0,
+ 0, -1, -1, 0, -1, -1, 0, 0, -1, 0, -2, 0, -1, -1, -1, 0,
+ -1, -1, 0, -1, 0, 0, 0, -2, -1, 0, -1, -1, 0, 1, -1, -1,
+ 0, 0, 0, 0, -1, -1, -1, -1, 0, 1, 0, 0, 0, 0, 0, -1,
+ 0, 0, 0, 0, 0, 0, -1, 0, 0, -1, 0, 0, -1, -1, -1, 0,
+ 0, -1, -1, 0, -1, 0, 0, 0, -1, 0, -1, -1, 0, -2, -1, -1,
+ -1, 0, -1, 0, -1, -1, 0, 0, -1, 0, -1, 0, -1, -1, -1, 0,
+ -1, 0, -1, 0, 0, -1, 0, -1, 0, 0, -1, -1, 0, 0, 0, -1,
+ 0, -1, 0, 1, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, -1, 0,
+ 0, -1, -1, 0, 0, 0, -1, 0, 1, -1, -1, -1, 0, 0, -1, -1,
+ -1, -1, 0, -1, 0, 0, 0, 0, 0, 0, -1, -1, 0, -1, -1, 0,
+ -1, 0, -1, -1, -1, -1, 0, -1, -1, -1, -1, -1, -1, -1, 0, -1,
+ 0, -1, 0, 0, -1, -1, 0, -1, 0, -1, 0, 0, -1, 0, -1, -1,
+ -1, 0, -1, 0, 0, 0, 0, 0, -1, -1, 0, 0, 0, 0, 0, 0,
+ 0, 0, -1, 0, 0, -1, 0, 0, 0, 0, -1, 0, -1, 0, 0, 0,
+ -1, -1, 0, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, -1,
+ -1, -1, 0, 0, 0, -1, 0, -1, -1, 0, -1, 0, 0, -1, -1, -1,
+ -1, -1, 0, 0, -1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, -1,
+ 0, 0, 0, 0, -1, 0, 0, 0, 0, -1, 0, 0, 0, 0, -1, 0,
+ 0, -1, 0, -1, 0, 0, -1, -1, -1, 0, -1, -1, 0, -1, -1, 0,
+ 0, -1, -1, -1, -1, 0, -1, -1, 0, 0, -1, 0, 0, 0, -1, -1,
+ 0, -1, -1, -1, 0, 0, -1, -1, -1, -1, -1, 0, -1, 0, 0, -1,
+ -1, 0, 0, -1, 0, 0, -1, -1, -1, 0, -1, 0, 0, -1, -1, 0,
+ 0, -1, -1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, -1, -1, 0, 0, 0, -1, 0, -1, 0,
+ -1, -1, -1, -1, -1, -1, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 0, 11, -3, 47, -12, -15, -34, 3, 12, 38, 5, -24, -26, -9, -12,
+ 63, -18, 12, -17, -50, 34, -6, 40, -2, -8, -37, -6, 9, 12, 32, -4,
+ -33, 2, -33, 35, 20, 6, -11, -33, -11, 12, 23, 30, -21, -13, -28, -6,
+ 33, 14, 7, -18, -22, -11, 18, 23, 5, -4, -22, -30, 29, -11, 40, -12,
+ -15, -5, -11, 16, 13, -9, 5, -19, 3, 4, 2, 19, -28, 24, -41, 40,
+ -9, -8, 4, -29, 28, -1, 22, -16, -32, 16, -22, 45, 19, -45, 17, -54,
+ 25, 28, 33, -19, -30, -21, -25, 83, -20, 15, -3, -74, 12, 33, 4, 53,
+ -26, -57, -9, 0, 36, 33, 8, -67, -2, -17, 27, 55, -17, -11, -31, -23,
+ 24, 22, 6, 19, -55, 27, -48, 55, -8, 14, 7, -61, 26, -25, 34, 32,
+ -26, 11, -50, 5, 14, -1, 67, -75, 47, -79, 29, 15, 8, 42, -49, 2,
+ -34, -3, 51, -23, 52, -33, -32, -7, -14, 52, 6, 29, -73, 5, -9, -2,
+ 64, -39, -6, 25, -60, 30, 5, 16, -13, 40, -61, 7, 20, -50, 75, -36,
+ 10, -12, -4, -17, 23, 16, -18, 31, -38, -21, 33, -37, 56, -11, -5, -1,
+ -43, 43, -56, 93, -67, 40, -17, -46, 60, -56, 62, -24, 14, -18, -23, 9,
+ -16, 44, 19, -53, 58, -124, 81, -18, 32, 26, -43, -23, -28, 42, 1, 60,
+ -27, -61, 14, -37, 42, 64, -32, -2, -43, -31, 25, 59, -7, -1, -19, -73,
+ 51, 23, 18, 7, -24, -65, 29, 18, -2, 57, -47, -27, 4, -2, 16, 41,
+ -25, -47, 36, -51, 49, 24, -37, 13, -15, -11, 12, 26, -58, 52, -20, -16,
+ 31, -24, -20, 52, -16, -9, 32, -69, 5, 48, -34, 52, -12, -59, 20, -10,
+ 30, 16, 21, -75, 1, 8, -33, 126, -57, 9, -37, -49, 32, 24, 62, -59,
+ 19, -85, -2, 91, -23, 65, -49, -75, 19, -16, 68, 9, 16, -77, -3, 3,
+ -13, 111, -69, 17, -30, -59, 56, 1, 19, 23, -26, -21, -24, 25, -31, 97,
+ -59, 4, -16, -34, 40, 17, 16, -24, -6, -40, 26, 17, 3, 4, -23, -3,
+ -1, 23, -8, 6, -29, -2, 21, -13, 22, -11, -31, 40, -35, 48, -27, 7,
+ -39, 4, 28, -12, 55, -68, 9, -9, 2, 51, -21, -20, -18, -15, 33, 20,
+ 15, -57, 41, -78, 72, -2, -7, 13, -60, 11, 13, 49, -19, 10, -55, -23,
+ 59, -6, 22, 2, -79, 40, -11, 46, -11, 11, -66, 13, 24, -24, 80, -65,
+ 5, -22, 1, 19, 23, -8, -27, -11, 2, 0, 64, -61, 21, -52, 34, 23,
+ 7, -1, -51, 21, -41, 86, -45, 49, -62, -6, 0, 11, 51, -33, 16, -62,
+ -1, 23, 8, 62, -45, -35, 7, -39, 88, -54, 70, -86, 33, -27, -1, 61,
+ -60, 58, -62, 10, 15, -28, 65, -48, 11, -2, -44, 78, -64, 75, -78, 26,
+ -29, 22, 40, -30, 16, -53, -12, 56, -15, 48, -51, -22, -10, 9, 52, -20,
+ 40, -92, 16, -3, 26, 43, -19, -35, -31, 15, 13, 49, -11, -34, -24, -1,
+ 9, 50, -12, -25, -17, -10, 15, 44, -20, 0, -28, -22, 32, 5, 27, -33,
+ 15, -67, 61, -19, 19, 18, -46, -1, -1, 7, 18, 14, -27, -21, 18, -27,
+ 42, 22, -56, 38, -56, 21, 17, 2, 5, -3, -11, -38, 48, -27, 32, 8,
+ -50, 1, 10, -3, 38, -10, -16, -36, 34, -45, 74, -12, -30, 16, -52, 22,
+ 24, 17, -1, -13, -41, -10, 50, -5, 41, -32, -62, 25, -5, 48, 24, -26,
+ -61, 4, -2, 44, 62, -59, -23, -38, -4, 61, 34, 0, -57, -18, -41, 63,
+ 36, 6, -1, -69, -11, 10, 19, 60, -31, 3, -64, 18, -19, 61, 10, -17,
+ 10, -73, 13, 30, -7, 64, -39, -27, -34, 8, 20, 46, 24, -87, 29, -70,
+ 51, 51, -12, 6, -44, -30, 10, 52, -7, 2, -6, -72, 63, -9, 17, 15,
+ -37, -24, 14, 24, -11, 43, -55, -29, 42, -19, 47, 1, -49, -13, 13, 6,
+ 38, 4, -59, -2, 7, 5, 61, -31, -42, 11, -32, 54, 14, -11, -23, -10,
+ -20, 40, 19, -18, 0, -19, -28, 52, -14, -5, 29, -70, 53, -17, 19, -18,
+ 15, -30, -2, 37, -41, 38, 7, -61, 67, -67, 35, 11, -12, 11, -34, 38,
+ -61, 89, -59, 10, 28, -60, 52, -19, -22, 34, -30, 42, -42, 45, -68, 35,
+ 19, -45, 80, -81, 26, -16, 4, 30, 0, -13, -19, -14, 23, -22, 75, -77,
+ 47, -45, -5, 48, -36, 48, -50, 18, -35, 25, 5, 4, 14, -16, -33, 40,
+ -49, 71, -38, 17, -30, -6, 12, 4, 31, -27, -6, -12, -11, 27, 15, -13,
+ 12, -54, 32, -19, 53, -17, -1, -16, -39, 39, -5, 30, -3, -29, -13, -2,
+ 23, 16, 4, -18, -41, 26, -11, 35, 18, -48, 13, -33, 28, 1, 38, -45,
+ 5, -13, -18, 49, 1, -21, 16, -44, 14, 16, 7, -6, -5, -10, -18, 52,
+ -33, 25, -11, -36, 31, -15, 14, 11, -22, 9, -27, 41, -42, 56, -50, 15,
+ 10, -28, 30, -18, 3, 7, -7, 7, -16, 13, -27, 29, 5, -25, 42, -71,
+ 44, -18, 21, 8, -7, -21, -15, 21, -9, 36, -2, -43, 17, -26, 14, 45,
+ -33, 19, -40, 1, -3, 37, -5, -5, -2, -46, 38, 0, 7, 18, -33, -12,
+ 11, -11, 33, 2, -16, -15, -3, 1, 18, 26, -32, -4, -14, -17, 54, -1,
+ -1, -17, -35, 10, 12, 40, -12, -10, -30, -31, 51, -12, 65, -35, -34, -12,
+ -32, 60, 22, 19, -33, -39, -20, 2, 75, 2, 9, -42, -72, 35, 13, 65,
+ 5, -28, -60, -15, 23, 40, 44, -33, -34, -34, -5, 48, 33, 2, -21, -47,
+ -15, 25, 33, 12, 7, -55, -12, 7, 19, 28, 9, -34, -28, 5, 7, 32,
+ 15, -41, 8, -32, 10, 36, -4, 14, -40, 16, -45, 56, -15, 17, 0, -33,
+ 2, 0, 7, 23, -12, -1, -26, 3, 6, 10, 24, -32, 21, -50, 33, -9,
+ 15, 11, -24, 1, -12, 12, 4, 13, -10, -11, -2, -5, 7, 17, -23, 25,
+ -27, 12, -6, 0, 8, -16, 18, -24, 31, -27, 9, -3, -2, 18, -4, -7,
+ -11, -12, 10, 12, 15, -17, 7, -34, 18, 8, 4, 9, -18, -14, -3, 15,
+ 9, 7, 0, -37, 21, -13, 16, 18, -32, 12, -23, 21, 3, 12, -14, -14,
+ 3, -5, 24, 4, -21, 9, -32, 26, 14, -1, 12, -40, 0, -6, 24, 11,
+ 3, -11, -34, 17, -8, 28, 18, -36, 9, -38, 13, 26, 11, 7, -20, -13,
+ -34, 49, -24, 41, -8, -36, 4, -8, 3, 47, -11, -5, -24, -15, -9, 44,
+ 8, -5, 8, -61, 17, 14, 14, 23, -15, -43, 1, -1, 28, 27, 1, -40,
+ -6, -20, 18, 45, -22, 4, -20, -34, 39, 12, 3, 9, -31, -23, 15, 17,
+ -7, 36, -36, -19, 30, -30, 36, 1, -16, -8, 5, -14, 20, 10, -13, 0,
+ 6, -30, 37, -22, 3, 14, -27, 24, -15, 14, -15, 19, -22, 4, 17, -31,
+ 29, -14, -10, 27, -26, 22, -14, 8, -17, 9, -2, -11, 33, -27, 14, 0,
+ -29, 31, -21, 21, -7, -2, -14, -4, 20, -15, 37, -27, -9, 7, -24, 24,
+ 8, -9, 12, -23, 7, -14, 30, -22, 25, -16, -20, 24, -27, 23, 8, -9,
+ 6, -11, -18, 12, -3, 22, -14, 28, -61, 41, -32, 21, 29, -26, 8, -31,
+ 2, 5, 28, 3, -9, -14, -21, -3, 48, -33, 49, -62, 9, -1, 6, 33,
+ -24, 11, -44, 24, -2, 6, 25, -40, 8, 1, -16, 49, -41, 27, -41, 18,
+ 0, 3, 31, -50, 36, -42, 22, 15, -18, 24, -34, 5, 12, -21, 52, -56,
+ 52, -58, 29, -8, -8, 39, -51, 48, -47, 24, 4, -16, 22, -28, 6, 7,
+ -22, 48, -55, 51, -44, 31, -10, -5, 8, -36, 41, -31, 35, -9, -16, 10,
+ -17, 6, 21, -13, 10, -26, 5, -17, 39, -3, 3, 1, -43, 12, 1, 17,
+ 15, -7, -24, -9, 5, 15, 17, 8, -38, 2, -25, 25, 15, 12, -13, -16,
+ -11, 3, 19, 9, -9, -9, -15, 1, 19, -1, 14, -20, -1, -12, 15, -7,
+ 11, -10, -2, -3, 10, -9, 18, -17, 2, -4, -3, 4, 3, -2, -5, 9,
+ -9, 4, 5, -13, 5, 5, -21, 22, -16, 11, -4, 13, -22, 5, 3, -23,
+ 35, -14, -6, 13, -24, 4, 17, -6, 6, -7, -6, -27, 43, -28, 25, 9,
+ -45, 28, -23, 8, 25, -14, 0, -15, -4, -3, 27, 3, -15, 18, -59, 34,
+ 3, -3, 38, -39, -11, 4, -9, 27, 9, -2, -38, 21, -31, 19, 47, -53,
+ 43, -47, -11, 29, -2, 19, -7, -9, -36, 19, 12, -8, 53, -58, 1, 2,
+ -33, 67, -23, 25, -44, 5, -25, 28, 32, -29, 32, -60, 0, 25, -7, 39,
+ -14, -29, -12, 2, 11, 20, 23, -54, 18, -25, 1, 45, -10, -10, -4, -29,
+ 7, 28, 7, -11, 9, -46, 16, 11, 8, 8, -7, -25, -3, 16, -3, 32,
+ -25, -7, -20, 12, 0, 30, -14, -4, -15, -6, 6, 24, -9, 3, -16, -24,
+ 23, -3, 27, -20, 15, -56, 42, -17, 21, 13, -27, -8, -2, 5, 8, 21,
+ -21, -12, 4, -14, 15, 24, -39, 31, -38, 19, -2, 16, -16, 3, -6, -21,
+ 30, -14, 16, 4, -30, 11, -7, 7, 12, -5, -10, -9, 9, -17, 37, -15,
+ -5, 6, -26, 12, 13, -8, 7, -2, -18, 1, 17, -13, 15, 4, -37, 25,
+ -18, 8, 13, 1, -23, 21, -25, 10, 7, -1, -6, 10, -15, -7, 21, -26,
+ 29, -12, -3, -3, 0, -16, 29, -18, 21, -15, 1, -23, 22, -4, 3, 21,
+ -43, 22, -19, 4, 21, -8, 4, -11, -7, -5, 7, 19, -20, 31, -47, 11,
+ 2, -9, 44, -28, 8, -31, 5, -1, 20, 24, -38, 14, -32, -4, 47, -30,
+ 38, -41, -1, -12, 12, 27, -16, 29, -57, 12, -1, 3, 38, -29, 3, -25,
+ -1, 28, -10, 36, -52, 20, -33, 27, 14, -11, 18, -42, 13, 3, 3, 20,
+ -21, 0, -20, 15, 4, 0, 23, -49, 28, -24, 18, 16, -15, -2, -26, 22,
+ -10, 33, -7, -26, 11, -25, 19, 21, -14, 8, -33, 6, -2, 30, 2, -12,
+ -6, -37, 34, -4, 22, 1, -33, -3, -4, 15, 20, 3, -20, -16, 2, -14,
+ 38, -3, -7, 2, -24, -4, 22, -4, 11, -2, -15, -19, 21, -15, 24, 8,
+ -21, 1, -12, -3, 9, 21, -22, 17, -26, -2, 6, 14, -8, 19, -24, -10,
+ 8, -10, 17, 9, -7, -12, 8, -27, 29, -3, 4, -4, -3, -26, 25, -9,
+ 13, 9, -19, -7, 2, -4, 10, 19, -29, 13, -16, -3, 18, 4, -12, 10,
+ -24, 1, 6, 10, -9, 19, -26, -3, 16, -15, 20, -4, -16, 1, 3, -4,
+ 9, 6, -19, 7, 3, -18, 26, -13, -7, 12, -13, 2, 9, -5, -7, 15,
+ -18, 6, 8, -18, 13, -2, -12, 15, -12, 9, -6, -2, -16, 25, -14, 18,
+ 1, -29, 11, -4, 14, 2, 3, -26, 6, -3, 1, 19, -3, -15, 12, -29,
+ 17, -2, 12, -2, -4, -3, -28, 34, -21, 31, -7, -17, -3, -13, 20, 1,
+ 14, -14, -22, 11, -13, 33, -2, -11, -4, -30, 33, -12, 30, -17, -17, -4,
+ -4, 25, 2, 3, -20, -22, 20, -13, 42, -15, -11, -9, -16, 23, 8, 16,
+ -28, -3, -11, 4, 27, -8, 5, -17, -9, 8, -2, 25, -27, 17, -32, 19,
+ -4, 16, -8, -16, 6, -20, 32, 0, -14, 8, -34, 18, 12, 3, 13, -36,
+ 11, -34, 49, -14, 22, -12, -38, 17, -21, 42, 5, -10, -12, -34, 8, 18,
+ 18, 26, -50, 9, -50, 42, 16, 10, 10, -51, 2, -21, 38, 16, 7, -17,
+ -29, -12, 13, 19, 25, -16, -7, -40, 14, 5, 23, 6, -11, -23, -3, 11,
+ 2, 25, -26, 0, -12, 5, 4, 9, 2, -18, 10, -15, 5, 20, -26, 23,
+ -28, 6, 8, 1, 12, -26, 10, -19, 20, 7, -14, 17, -37, 18, 1, -1,
+ 23, -28, 9, -25, 20, 1, 6, 6, -23, 9, -15, 12, 10, -11, 5, -5,
+ -12, 15, -8, 4, 4, -4, -6, 8, -11, 3, 6, -6, 0, 6, -12, 1,
+ 14, -26, 27, -17, -3, 15, -18, 15, -10, 1, -6, 4, 9, -17, 28, -42,
+ 18, 3, -17, 45, -38, 9, -12, -7, 19, 8, 7, -31, 8, -18, 6, 53,
+ -51, 34, -41, -13, 32, -4, 17, -10, -6, -28, 25, 0, -2, 23, -32, -7,
+ 21, -28, 36, -7, -14, 7, -10, -4, 13, -3, -7, 7, -5, -6, 14, -10,
+ -10, 22, -29, 22, 0, -23, 24, -25, 15, 3, 3, -4, -9, 5, -23, 33,
+ -10, -6, 22, -48, 31, -8, 7, 10, -15, -5, -14, 20, -7, 16, 3, -32,
+ 20, -21, 13, 18, -20, 9, -25, 13, -3, 21, -4, -10, -4, -18, 18, 6,
+ 2, 6, -32, 8, -4, 18, 10, -3, -21, -12, 3, 3, 28, -3, -18, -4,
+ -14, 10, 19, 5, -9, -10, -21, 8, 21, 2, 11, -23, -12, -8, 14, 12,
+ -1, 5, -31, 14, -9, 15, 7, -14, 5, -19, 11, -3, 5, 1, -11, 12,
+ -13, 14, -6, -10, 5, -9, 16, -4, 3, -15, -5, 9, 2, 14, -11, -9,
+ -7, -7, 22, -2, 12, -14, -15, -2, 2, 19, 0, 6, -28, -3, 0, 5,
+ 27, -10, -8, -15, -9, 12, 10, 20, -25, 5, -23, 0, 27, -10, 21, -27,
+ -3, -14, 17, 8, 1, 6, -28, 2, 7, -2, 21, -14, -6, -9, 3, 6,
+ 2, 16, -33, 19, -17, 7, 10, -6, -3, -4, 0, 0, 11, -1, -13, 5,
+ -9, -1, 25, -27, 19, -20, 3, 9, 1, 2, -11, 5, -19, 26, -4, -6,
+ 13, -28, 10, 13, -11, 17, -19, -1, -10, 22, -4, -1, 13, -43, 29, -8,
+ 3, 18, -25, 5, -13, 16, -5, 12, 0, -29, 25, -23, 14, 17, -29, 23,
+ -23, 8, 2, 0, 4, -8, 11, -25, 22, -8, -6, 28, -35, 19, -6, -17,
+ 25, -15, 9, -5, 1, -12, 10, 5, -14, 22, -24, 0, 18, -23, 23, -9,
+ -10, 8, -1, -1, 4, -4, -13, 8, 6, -7, 22, -27, -8, 10, -6, 23,
+ 1, -17, -10, -9, 15, 14, 15, -17, -24, -1, -11, 41, 4, -4, -12, -35,
+ 12, 13, 19, 12, -22, -25, -6, 8, 22, 17, -3, -36, 7, -21, 21, 32,
+ -22, 8, -23, -17, 17, 15, 1, 10, -19, -20, 2, 10, 3, 23, -13, -21,
+ 7, -19, 26, 12, -10, 4, -35, 4, 7, 12, 19, -17, -3, -24, 14, 7,
+ 7, 15, -43, 12, -13, 8, 37, -29, 13, -34, 11, 2, 11, 14, -34, 22,
+ -31, 20, 14, -14, 18, -29, 5, -4, 3, 13, -11, 13, -23, 9, -3, -5,
+ 22, -22, 12, -10, -11, 15, -2, 6, 4, -10, -15, 11, -5, 10, 8, -14,
+ -12, 12, -10, 16, 17, -37, 16, -18, -3, 31, -11, -1, -9, -8, 0, 22,
+ 6, -21, 9, -32, 14, 26, -19, 27, -40, 6, -4, 13, 14, -14, 3, -34,
+ 21, 1, 10, 15, -32, 5, -10, 5, 19, -10, 3, -21, 10, -7, 14, 9,
+ -23, 18, -25, 9, 7, -5, 4, -1, -8, -2, 15, -17, 16, -5, -17, 16,
+ -13, 9, 3, 2, -17, 13, -10, -2, 29, -33, 17, -15, -10, 23, -6, 12,
+ -14, -3, -9, 2, 26, -23, 28, -45, 14, -1, 1, 33, -35, 17, -34, 15,
+ 10, 3, 12, -31, 7, -15, 18, 19, -19, 12, -39, 16, 5, 8, 17, -37,
+ 16, -35, 39, -3, 8, -5, -31, 9, -4, 26, 0, -3, -18, -15, 19, -2,
+ 25, -12, -21, 1, -16, 26, 4, 6, -20, -1, -14, 11, 21, -20, 22, -32,
+ 0, 14, -9, 19, -10, -2, -13, 14, -9, 4, 17, -36, 30, -20, -2, 22,
+ -21, 13, -11, 7, -12, 15, -6, -15, 25, -29, 20, 3, -18, 17, -17, 7,
+ -3, 11, -9, -4, 13, -33, 34, -10, -5, 22, -34, 11, -4, 8, -1, 11,
+ -14, -16, 24, -27, 31, 3, -29, 19, -23, 2, 26, -11, 1, -3, -14, -4,
+ 27, -14, 3, 9, -38, 26, -1, -7, 20, -15, -12, 14, -8, 4, 7, -11,
+ -10, 12, -3, 0, 16, -28, 7, 1, -2, 14, -7, -10, -5, 4, 5, 9,
+ 3, -22, 4, -5, 0, 27, -18, 1, -9, -10, 13, 10, 1, -9, -1, -21,
+ 15, 11, -8, 15, -21, -8, 12, -4, 13, 0, -12, -5, 2, -1, 9, 2,
+ -8, 0, -4, 1, 4, -1, -1, -1, -1, -2, -15, 21, -17, 23, -30, 1,
+ 34, -34, 6, 5, -15, 19, 1, -25, 6, 20, -2, -28, 15, 10, -15, 0,
+ -7, 10, 7, -5, -9, -6, 19, -3, -21, 3, 20, -4, -20, 1, 16, -3,
+ -8, -2, 5, 1, -8, -6, 3, 9, 2, -13, -4, 15, -7, -9, 0, 3,
+ 6, -7, -7, 5, 8, -8, -4, 0, 1, 1, -6, -4, 7, 2, -2, -7,
+ 0, 4, -3, -4, 0, 2, 0, -2, -4, 1, 4, -2, -4, -3, 1, 3,
+ -5, -4, 4, 3, -6, -5, 4, -1, -2, -3, 0, 3, -3, -1, -4, 3,
+ 3, -5, -3, 1, 1, -2, -3, 1, 2, -2, -4, 0, 0, 0, -1, -3,
+ 1, 1, -3, -2, 1, 0, -2, -2, 0, 0, -2, -1, 0, -1, 1, -2,
+ -2, 1, 0, -2, 0, -1, 0, -1, -1, -1, 0, 0, -1, -3, 1, 1,
+ -2, -2, 0, 1, -1, -2, -1, 0, 0, 0, -2, -1, 1, 0, -3, 0,
+ 2, -1, -2, 0, 0, 0, -2, 0, -1, 0, -1, -1, 1, 0, -1, 0,
+ -1, 1, 0, -13, 5, 7, -11, 24, -50, 41, 4, -29, 14, -11, 8, 11,
+ -15, -12, 15, 18, -21, -14, 22, -2, -11, -3, -3, 18, -3, -5, -14, 9,
+ 22, -24, -16, 23, 12, -23, -8, 9, 10, -4, -8, -3, 11, -4, -14, 0,
+ 8, 8, -5, -14, 8, 10, -12, -4, -2, 10, 0, -11, -3, 11, 0, -7,
+ -2, -1, 7, -6, -8, 3, 6, 0, -3, -8, 7, 2, -7, -2, 2, 1,
+ -2, -4, -1, 3, 3, -4, -5, 1, 3, -3, -6, 2, 5, -1, -7, -1,
+ 3, -1, -4, -3, 5, 0, -3, -2, -1, 4, -1, -5, -1, 3, -1, -4,
+ -1, 3, 1, -4, -2, 1, 0, -2, -3, 0, 2, -1, -4, 1, 1, -1,
+ -2, -2, 1, -1, -3, 0, 0, 0, -1, -2, 0, 0, -2, -1, 0, -1,
+ 0, -2, -1, 0, -1, 0, -1, -2, 2, -1, -2, -1, 0, 1, -2, 0,
+ -1, -1, 0, -1, -2, 0, 1, -1, -3, 0, 1, -1, -3, 0, 1, -2,
+ -1, 0, 0, -1, -1, 0, -1, -1, -1, -1, 0, 0, -1, -1, 0, 0,
+ -2, 0, 0, 0, 0, -2, 1, -1, 0, -1, 0, 0, 0, -1, 0, 0,
+ 0, 0, -1, 0, 0, -1, 0, -1, 1, 0, 0, 0, 1, -1, -1, 0,
+ 0, 0, 1, -2, 4, -3, 3, -40, 71, -73, 67, -27, -68, 127, -80, 3,
+ 5, 1, 17, -14, 1, -30, 53, -3, -42, 15, 19, -9, -17, -1, 13, 16,
+ -17, 4, -32, 43, 15, -68, 18, 54, -38, -7, -1, 11, 7, -3, -18, 5,
+ 25, -27, -9, 9, 19, -6, -12, -8, 20, -1, -15, -1, 1, 17, -10, -16,
+ 12, 12, -13, 0, -6, 10, 2, -16, -1, 14, -4, 4, -11, -2, 12, -6,
+ -8, 4, 4, -2, -4, 1, -2, 4, 3, -7, -5, 8, 0, -10, 1, 4,
+ 2, -4, -6, 4, 1, -1, -7, 1, 8, -9, 2, -5, 3, 3, -4, -3,
+ 0, 3, -3, -5, 4, 3, -3, -4, 0, 2, 0, -3, -4, 5, 0, -5,
+ -1, 2, 0, -3, 0, -1, 2, -2, -4, 3, 0, -1, -2, -1, 2, -2,
+ -2, 1, -1, 0, -1, -3, 1, 1, -2, 1, -3, 1, 1, -3, -1, 1,
+ 0, -1, -2, 1, -1, -1, 1, -2, 1, -1, -1, -1, -1, 0, 1, -3,
+ 0, 0, 1, -4, 0, 1, -2, 0, -2, 0, 0, 0, -2, 1, -1, 0,
+ -2, 0, 2, -2, -1, 0, -1, 2, -2, -1, 1, -2, 0, -1, 1, -1,
+ -1, -1, 1, -2, 1, -1, -1, 2, -3, 0, 0, -1, 1, -1, 0, 1,
+ 0, -2, 0, -1, 1, -2, 0, 0, -1, 1, 0, -2, 0, 1, -2, 1,
+ 0, 0, -1, 0, 1, -1, -1, -1, 1, 1, -1, 0, 0, 0, -1, 1,
+ 0, -1, 1, 0, 0, 1, 0, -1, 1, 0, 3, -40, 58, -39, 12, 42,
+ -117, 108, 1, -66, 22, 17, 0, -9, 10, -39, 42, 4, -23, -12, 28, 3,
+ -34, 9, 17, 3, -9, 10, -29, 13, 53, -79, 3, 64, -26, -24, 16, -9,
+ 14, 2, -8, -15, 31, -9, -30, 11, 29, -15, -7, 0, 3, 6, -4, -9,
+ -6, 22, 1, -24, 9, 11, -8, 0, -2, 2, 8, -12, -6, 10, 2, 2,
+ -9, -4, 11, -2, -10, 3, 2, 3, -5, -1, 1, -1, 6, -4, -8, 9,
+ 2, -8, -3, 6, 3, -4, -3, -1, 6, -2, -8, 0, 9, -4, -3, -2,
+ 2, 4, -4, -1, -1, 4, -2, -6, 4, 2, -1, -4, 0, 1, 2, -3,
+ -5, 3, 3, -3, -4, 3, 0, -1, 0, -2, 2, 0, -3, 0, 3, 0,
+ -3, -1, 2, 0, -3, 1, 0, -1, 2, -2, -2, 2, -1, 0, -1, -1,
+ 1, -1, -2, 0, 0, 1, -3, 1, 0, -1, 1, -2, -1, 2, -2, -1,
+ 0, -1, 2, -3, -1, 1, 1, -2, -2, 2, 1, -2, -1, 0, 0, 1,
+ -3, 1, 0, 0, 0, -2, 3, 0, -2, 0, 0, 1, 0, -1, 1, -2,
+ 0, 0, 0, -1, 1, 0, 0, 0, -1, 1, -1, 1, 0, -1, 1, -2,
+ 0, 1, 1, 0, 1, -2, 1, 0, 1, 0, 0, 3, -1, 0, 1, 0,
+ 0, 3, -29, 35, -12, -16, 56, -88, 39, 62, -79, 5, 29, 1, -13, 12,
+ -29, 26, 17, -28, -3, 12, 5, -11, -19, 28, 1, -5, 9, -21, -7, 60,
+ -56, -20, 57, -10, -27, 21, -21, 16, 12, -12, -21, 24, 6, -29, 4, 19,
+ 2, -7, -5, -3, 7, 6, -11, -9, 11, 13, -18, -4, 13, 1, -3, -6,
+ -1, 10, -8, -6, 5, 3, 5, -3, -11, 4, 9, -11, 0, 4, 3, -4,
+ -1, 0, 0, 7, 0, -14, 7, 5, -7, -4, 4, 5, -1, -4, -4, 4,
+ 1, -4, -4, 7, -1, -1, -3, 0, 5, -1, -4, -1, 2, 0, -3, 1,
+ 1, 2, -2, -4, 1, 2, 0, -5, 2, 3, -2, -2, 1, 1, -2, 2,
+ -3, 0, 0, -1, -1, 0, 1, 0, -3, 0, 0, -1, 1, -1, -2, 1,
+ -1, 0, -2, 2, 1, -2, -1, 1, 0, -1, -1, 0, 1, -1, 0, -2,
+ 1, 1, -1, 0, -1, -1, 0, 0, -1, -1, 0, -1, -1, 2, -2, -1,
+ 1, 0, 0, -1, -1, 1, 0, -1, 1, -1, 0, 1, -3, 1, 1, -1,
+ -1, 0, 1, 0, 0, 0, -1, 0, 0, -1, 0, 1, 0, 0, 2, -2,
+ 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, -1, -1, -7, -9,
+ 35, -52, 59, -33, -32, 64, -15, -41, 19, 22, -20, 9, -11, -3, 33, -27,
+ 2, 7, -9, 19, -37, 24, 7, -11, 11, -1, -30, 37, 8, -57, 36, 19,
+ -33, 14, 0, -17, 26, 1, -20, -5, 26, -18, -13, 14, 7, -6, 4, -9,
+ -4, 11, 3, -14, -7, 20, 0, -18, 10, 1, 4, -5, -7, 6, 0, -3,
+ -2, -2, 8, 5, -11, -6, 10, -1, -10, 6, -2, -1, 1, -3, 0, 3,
+ 5, -9, -5, 9, -3, -4, 1, 1, 3, -1, -4, -1, 2, -2, -5, 5,
+ -3, 0, 1, -5, 4, 2, -3, -3, 0, 0, -2, 1, 0, -2, 3, -2,
+ -5, 2, 2, -2, -4, 3, 0, -2, 1, -2, -2, 5, -2, -6, 1, 2,
+ -1, -1, 0, 1, -1, -2, -1, -1, 2, 0, -4, 0, 1, 0, -3, 0,
+ 2, 0, -3, 0, 0, 1, -1, -1, 1, 0, -1, -2, 1, 0, 0, -1,
+ 0, -2, 1, 0, -1, 1, -1, 0, -2, 1, 1, -2, -1, 2, -2, 1,
+ -3, 1, 1, -1, 0, 0, -1, 1, 0, -2, 2, -1, -1, 0, 0, 1,
+ 0, 1, 0, -2, 1, 0, 0, -1, 1, 0, 0, 0, 0, -3, -20, 45,
+ -56, 40, -5, -34, 27, 24, -42, -1, 29, -14, -4, 2, -7, 24, -20, -1,
+ 18, -25, 25, -29, 9, 21, -26, 14, 4, -20, 7, 27, -42, 5, 31, -24,
+ -2, 19, -30, 21, 8, -11, -17, 20, 1, -22, 11, 7, -7, 6, -5, -7,
+ 3, 11, -6, -18, 11, 16, -20, 1, 5, 2, -3, -3, 0, -3, 4, -1,
+ -7, 2, 10, -9, -8, 7, 2, -9, 5, -1, -5, 2, 1, -3, -2, 9,
+ -5, -8, 4, 1, -5, 0, 1, 2, -1, 0, -5, 4, -1, -5, 4, -3,
+ 1, 1, -5, 3, 0, 0, -3, 0, -1, -2, 1, 2, -5, 2, 1, -5,
+ -2, 3, -1, -5, 2, 1, -4, 2, -1, -4, 2, 3, -7, -1, 2, 0,
+ -2, 1, 0, -2, -1, 0, -3, 1, 2, -3, -2, 3, 0, -3, -1, 1,
+ 0, -1, -2, -1, 1, 0, 0, -1, 0, 0, -2, 0, 0, 1, -2, 2,
+ -3, 1, 0, 0, -2, 1, 0, -1, 0, 0, -1, -1, 2, -3, 0, 0,
+ -1, 0, 0, -1, 1, 0, -4, -13, 32, -41, 31, -10, -10, 4, 22, -25,
+ -8, 21, -3, -14, 5, 1, 12, -23, 8, 18, -31, 25, -26, 10, 17, -23,
+ 8, 5, -9, 0, 16, -25, 2, 23, -22, -2, 22, -30, 15, 7, -6, -13,
+ 12, 1, -17, 9, 5, -6, 4, -3, -7, 5, 7, -6, -13, 7, 10, -11,
+ 0, 0, 4, -3, -3, 2, -7, 4, 2, -5, 0, 6, -3, -8, 4, 2,
+ -8, 7, 0, -8, -1, 6, 0, -8, 6, 0, -5, 1, 0, -5, 3, 2,
+ -3, -2, 4, -5, -1, -1, -2, 3, -4, 1, -1, -3, 3, -1, -2, -2,
+ 1, -2, -2, 1, 1, -4, 1, 2, -5, -3, 5, -3, -4, 4, -1, -4,
+ 2, -1, -4, 3, 1, -5, -2, 2, 0, -2, 2, -1, -4, 3, -1, -3,
+ 0, 1, -2, -2, 1, -1, -1, -1, 0, 0, -1, -1, -1, 0, -1, 1,
+ -1, -1, 0, -2, 1, 0, -1, -1, 0, -1, -1, -1, 2, -2, -1, 1,
+ -1, -2, 1, -1, -1, 1, -2, 1, -7, -3, 15, -23, 20, -16, 9, -12,
+ 16, -12, -8, 11, 5, -18, 6, 8, 0, -18, 16, 4, -19, 16, -17, 10,
+ 5, -8, -2, 9, -5, -4, 10, -17, 5, 13, -18, 2, 12, -17, 10, 0,
+ -2, -8, 7, -4, -7, 6, 1, -3, 1, 3, -9, -2, 10, -7, -8, 4,
+ 6, -6, 1, 0, 0, -2, 1, -1, -8, 6, 1, -5, 2, 4, -2, -4,
+ 1, 1, -7, 5, -1, -4, -2, 4, 0, -4, 4, -3, -4, 1, 0, -3,
+ 0, 2, -1, -2, 2, -2, -1, -3, 0, 3, -4, 3, -3, 0, 2, 0,
+ -3, -1, 1, -3, -1, 2, 0, -1, 0, 0, -3, 0, 1, -4, -1, 2,
+ 0, -2, 0, 1, -3, 1, 1, -3, -2, 2, -1, -1, 2, -1, -2, 1,
+ 0, -1, -1, 0, 2, 33, 42, 58, 71, 79, 85, 88, 91, 94, 79, 95,
+ 82, 106, 86, 105, 47, 16, -6, 13, 44, 31, -15, -38, -36, 20, 70, 41,
+ 48, 58, 24, -57, -127, -119, -102, -126, -128, -111, -78, -82, -88, -87, -60, -66,
+ -98, -104, -99, -97, -99, -104, -101, -88, -87, -91, -61, -27, -34, -54, -55, -45,
+ -24, -10, -5, -4, 5, 34, 63, 101, 94, 78, 52, 51, 52, 74, 81, 77,
+ 59, 46, 17, 7, 39, 53, 47, 42, 66, 83, 73, 52, 28, 22, 11, 8,
+ 11, 0, -15, -23, -15, -14, -6, 16, 46, 62, 71, 76, 90, 102, 103, 103,
+ 101, 100, 90, 75, 63, 67, 49, 37, 28, 12, 5, 6, 15, 15, 8, -7,
+ -12, -4, -10, -28, -24, -17, -25, -50, -64, -81, -103, -116, -116, -113, -95, -72,
+ -54, -41, -47, -65, -65, -50, -33, -24, -7, 11, 8, -4, -13, -28, -51, -75,
+ -90, -91, -90, -90, -87, -88, -83, -84, -82, -81, -81, -76, -65, -71, -85, -84,
+ -79, -83, -81, -77, -72, -70, -65, -66, -66, -65, -66, -68, -61, -56, -51, -36,
+ -13, -3, -5, -8, -12, -12, 3, 16, 21, 31, 50, 69, 77, 82, 90, 102,
+ 110, 114, 116, 117, 118, 119, 116, 112, 109, 105, 98, 99, 103, 102, 91, 73,
+ 64, 63, 61, 57, 51, 40, 24, 35, 57, 75, 84, 79, 65, 37, 4, -26,
+ -45, -57, -54, -46, -45, -54, -67, -67, -48, -16, 15, 35, 44, 45, 44, 45,
+ 46, 38, 23, 2, -15, -34, -52, -60, -70, -77, -80, -79, -74, -77, -84, -86,
+ -80, -72, -68, -72, -80, -87, -92, -96, -101, -104, -104, -101, -93, -90, -89, -86,
+ -85, -84, -83, -82, -81, -79, -77, -76, -73, -71, -66, -62, -55, -39, -31, -27,
+ -25, -31, -37, -46, -51, -53, -54, -48, -45, -38, -20, 3, 24, 35, 39, 32,
+ 16, 5, 3, 0, -6, -13, -13, -11, -2, 14, 28, 40, 50, 53, 50, 55,
+ 64, 74, 90, 105, 108, 112, 106, 104, 109, 112, 123, 127, 127, 127, 127, 127,
+ 127, 118, 113, 107, 110, 114, 111, 104, 101, 101, 102, 103, 99, 99, 89, 73,
+ 53, 35, 20, 0, -22, -43, -63, -77, -82, -76, -65, -48, -36, -29, -24, -25,
+ -29, -37, -40, -49, -59, -67, -73, -76, -78, -79, -75, -73, -74, -75, -68, -52,
+ -44, -30, -19, -9, -6, -9, -13, -24, -33, -35, -31, -30, -35, -40, -44, -45,
+ -51, -53, -54, -50, -50, -47, -42, -50, -55, -54, -56, -56, -54, -54, -49, -48,
+ -41, -32, -28, -18, -13, -5, 6, 18, 33, 49, 60, 71, 78, 88, 95, 97,
+ 93, 88, 91, 93, 97, 98, 97, 94, 91, 85, 81, 72, 70, 66, 61, 60,
+ 64, 66, 74, 83, 92, 102, 108, 109, 107, 102, 97, 95, 91, 87, 80, 74,
+ 67, 62, 61, 58, 61, 61, 57, 53, 43, 35, 27, 25, 24, 20, 20, 22,
+ 27, 34, 36, 32, 21, 8, -3, -10, -16, -18, -16, -16, -19, -15, -11, -11,
+ -12, -20, -34, -45, -59, -72, -80, -89, -94, -95, -102, -111, -114, -111, -111, -108,
+ -106, -104, -101, -98, -93, -90, -86, -86, -83, -82, -81, -79, -76, -73, -70, -72,
+ -78, -81, -79, -79, -72, -60, -43, -31, -25, -27, -34, -37, -40, -42, -41, -39,
+ -36, -34, -25, -12, -4, 5, 12, 16, 17, 15, 13, 6, -4, -7, -8, -6,
+ -1, 4, 7, 9, 12, 16, 19, 19, 22, 28, 29, 28, 29, 30, 34, 40,
+ 49, 57, 71, 78, 85, 92, 96, 95, 89, 85, 86, 93, 99, 104, 102, 100,
+ 94, 85, 77, 73, 69, 66, 63, 60, 60, 59, 57, 52, 47, 41, 31, 18,
+ 6, -3, -7, -11, -12, -14, -18, -22, -23, -22, -24, -30, -37, -41, -44, -50,
+ -56, -64, -67, -65, -62, -58, -58, -58, -59, -61, -62, -66, -72, -78, -79, -77,
+ -73, -68, -64, -61, -56, -53, -54, -52, -52, -57, -63, -69, -70, -68, -65, -62,
+ -59, -57, -56, -58, -60, -61, -63, -64, -62, -61, -60, -58, -54, -49, -45, -42,
+ -39, -36, -32, -28, -22, -13, -7, -3, 2, 13, 28, 41, 52, 64, 71, 73,
+ 73, 70, 64, 61, 60, 64, 66, 65, 66, 64, 61, 60, 62, 65, 64, 66,
+ 67, 67, 68, 66, 64, 66, 68, 73, 76, 74, 72, 66, 58, 52, 46, 42,
+ 38, 38, 41, 47, 52, 52, 48, 45, 42, 40, 38, 34, 29, 27, 26, 28,
+ 29, 28, 29, 30, 31, 28, 24, 21, 19, 17, 14, 10, 6, 3, -4, -9,
+ -15, -19, -26, -33, -40, -49, -55, -60, -65, -70, -73, -72, -72, -71, -70, -71,
+ -75, -78, -81, -83, -86, -86, -85, -84, -82, -80, -77, -72, -69, -66, -63, -61,
+ -61, -61, -61, -61, -60, -58, -53, -48, -42, -36, -30, -28, -30, -32, -33, -32,
+ -31, -28, -22, -18, -10, -5, 0, 3, 6, 11, 16, 19, 22, 24, 26, 27,
+ 29, 34, 40, 46, 48, 48, 48, 45, 40, 36, 33, 31, 33, 35, 40, 48,
+ 55, 62, 68, 73, 76, 78, 78, 77, 79, 82, 85, 87, 87, 87, 86, 86,
+ 86, 83, 78, 71, 63, 55, 48, 44, 39, 36, 36, 36, 35, 32, 28, 24,
+ 18, 13, 9, 6, 4, 1, -2, -5, -11, -17, -20, -21, -20, -21, -24, -28,
+ -32, -34, -33, -33, -35, -37, -40, -43, -47, -52, -58, -63, -69, -74, -77, -80,
+ -81, -82, -81, -80, -77, -74, -69, -62, -54, -48, -48, -51, -54, -57, -57, -57,
+ -56, -55, -55, -56, -57, -56, -55, -54, -54, -54, -54, -52, -49, -45, -41, -38,
+ -34, -31, -29, -27, -24, -20, -17, -11, -7, -3, 0, 5, 10, 16, 22, 27,
+ 31, 34, 38, 42, 44, 45, 48, 50, 52, 57, 61, 64, 64, 65, 65, 63,
+ 60, 57, 55, 55, 58, 61, 63, 65, 67, 69, 71, 74, 77, 79, 79, 77,
+ 74, 71, 68, 66, 63, 60, 57, 55, 51, 46, 40, 36, 30, 25, 20, 17,
+ 16, 17, 16, 14, 12, 10, 7, 3, -1, -5, -11, -15, -17, -18, -18, -19,
+ -21, -25, -29, -32, -33, -33, -36, -39, -43, -46, -50, -53, -56, -58, -59, -60,
+ -61, -62, -63, -65, -66, -67, -68, -70, -72, -72, -70, -67, -63, -61, -60, -60,
+ -58, -56, -54, -53, -52, -52, -52, -51, -50, -49, -47, -45, -43, -40, -37, -35,
+ -34, -32, -29, -25, -21, -18, -14, -9, -4, 0, 4, 7, 11, 15, 18, 21,
+ 25, 28, 33, 37, 41, 44, 46, 47, 47, 46, 46, 45, 43, 42, 42, 43,
+ 46, 48, 49, 50, 52, 55, 59, 62, 65, 66, 67, 68, 69, 69, 70, 72,
+ 74, 74, 73, 72, 71, 69, 65, 61, 57, 53, 50, 46, 43, 38, 35, 32,
+ 28, 23, 19, 17, 17, 15, 13, 11, 9, 5, 1, -3, -6, -9, -12, -14,
+ -17, -19, -23, -27, -31, -35, -38, -40, -43, -46, -48, -52, -55, -57, -61, -64,
+ -66, -67, -68, -69, -70, -70, -70, -69, -69, -70, -71, -70, -66, -62, -59, -55,
+ -52, -50, -46, -43, -41, -38, -36, -35, -35, -34, -33, -33, -33, -33, -31, -30,
+ -28, -26, -25, -24, -21, -20, -20, -19, -19, -18, -17, -16, -15, -13, -11, -8,
+ -3, 2, 9, 15, 21, 27, 33, 38, 41, 45, 48, 51, 53, 55, 56, 56,
+ 56, 56, 56, 56, 56, 55, 57, 58, 60, 61, 62, 62, 64, 66, 68, 69,
+ 71, 72, 73, 74, 72, 70, 67, 63, 60, 57, 54, 50, 46, 41, 36, 31,
+ 27, 23, 19, 16, 14, 12, 11, 9, 8, 5, 2, -1, -4, -8, -10, -15,
+ -18, -19, -20, -22, -22, -23, -23, -24, -26, -29, -31, -33, -35, -36, -37, -38,
+ -41, -44, -46, -48, -50, -52, -54, -56, -59, -61, -63, -63, -64, -65, -64, -63,
+ -62, -61, -60, -59, -58, -57, -58, -57, -57, -55, -53, -50, -49, -47, -46, -43,
+ -40, -37, -33, -31, -28, -26, -23, -20, -16, -14, -12, -9, -5, -2, 1, 5,
+ 9, 13, 17, 21, 24, 26, 29, 32, 35, 37, 37, 38, 39, 41, 43, 44,
+ 45, 46, 48, 50, 51, 53, 52, 52, 50, 48, 47, 46, 46, 46, 46, 47,
+ 48, 49, 51, 54, 56, 58, 60, 61, 62, 62, 62, 61, 59, 57, 55, 54,
+ 53, 52, 51, 49, 46, 41, 36, 31, 27, 22, 18, 14, 11, 9, 6, 3,
+ 0, -2, -5, -8, -11, -16, -20, -25, -28, -31, -34, -37, -39, -41, -41, -42,
+ -42, -42, -43, -45, -46, -47, -49, -50, -52, -54, -56, -57, -58, -60, -61, -63,
+ -64, -64, -64, -63, -63, -61, -59, -58, -57, -55, -54, -53, -52, -52, -51, -50,
+ -49, -47, -46, -45, -44, -42, -40, -38, -35, -32, -30, -28, -25, -22, -19, -17,
+ -15, -12, -9, -5, -1, 3, 7, 11, 15, 19, 23, 25, 27, 30, 34, 36,
+ 37, 38, 39, 40, 42, 44, 45, 46, 47, 49, 50, 52, 53, 52, 51, 49,
+ 47, 47, 46, 46, 46, 47, 47, 48, 50, 52, 55, 57, 59, 61, 62, 62,
+ 62, 61, 60, 58, 56, 54, 54, 53, 51, 50, 47, 44, 39, 34, 29, 25,
+ 20, 16, 13, 10, 7, 4, 2, -1, -3, -6, -9, -14, -18, -22, -26, -30,
+ -33, -35, -38, -40, -41, -41, -42, -42, -43, -44, -46, -47, -48, -49, -51, -53,
+ -55, -56, -57, -59, -60, -62, -63, -64, -64, -63, -63, -62, -60, -59, -57, -56,
+ -55, -53, -52, -52, -51, -51, -50, -48, -46, -45, -44, -43, -41, -39, -36, -34,
+ -31, -29, -26, -24, -21, -16, 1, -2, -1, -9, -9, -6, 5, 6, -1, -10,
+ 8, 24, 11, -2, -14, -9, -15, -13, 5, 14, 12, -6, -1, -12, 1, -9,
+ 12, 12, 10, 5, -19, -11, -13, -2, 8, 5, 1, -2, -3, 9, -6, 6,
+ 5, 6, -3, -17, -7, 3, 2, -1, 0, 7, -7, 5, 4, 6, -18, -24,
+ 6, 20, -1, -4, -1, 10, 3, -10, 8, 7, -11, -17, -15, 5, 18, 4,
+ 1, 8, -16, -4, 0, 11, 9, -10, -15, 0, -22, -12, 19, 34, 16, -9,
+ -16, -7, -12, -10, 13, 23, -1, -10, -2, -3, -11, 13, 7, -6, -9, 3,
+ 11, -10, -18, 12, 22, 7, -27, -29, -4, 20, 20, 10, 8, -16, -26, -6,
+ 22, 21, 7, 15, 8, -50, -50, -7, 35, 22, -13, 32, 41, -33, -46, -10,
+ 23, -7, -25, 23, 21, -38, -36, 14, 44, 2, 2, 34, -14, -51, -29, 11,
+ 19, 7, 22, 13, -23, -21, -8, -9, 1, 14, 26, 26, -8, -34, -33, 4,
+ 1, -6, -2, 16, -7, -23, 12, 27, 5, 6, 6, 0, -8, 0, -1, -17,
+ -13, -12, 3, 9, 4, 11, 23, 36, 0, -43, -16, 4, -21, -26, 27, 16,
+ -25, 3, 65, 4, -34, 24, -10, -38, -14, 13, 4, -15, 36, 44, -42, -51,
+ 20, -5, -6, 68, 20, -18, -39, -11, 9, 17, 6, -33, -20, -13, 48, 30,
+ 22, -4, -9, -53, -20, 32, 32, -16, 17, -11, -36, -8, -5, 39, 28, 33,
+ 21, -64, -48, 3, -22, 15, 62, -26, 0, 3, 5, 73, -14, -48, -20, -59,
+ 4, 70, 60, -7, -2, -88, -22, -17, 39, 17, 33, -3, 15, 28, -47, -80,
+ -37, 5, 7, 104, 16, -99, -92, -36, 109, 78, 26, -15, -92, -21, 62, 48,
+ -51, -81, -25, 55, 63, 35, 21, -115, -54, 101, 73, -41, -110, -66, 50, 107,
+ 45, -8, -109, -38, 12, 102, 3, 17, -45, -2, -36, 39, 46, -12, -28, -27,
+ -17, 17, -18, 82, -5, -3, -25, -5, -14, 15, 9, -3, -17, -6, 2, 7,
+ -36, -13, 6, 21, -23, -20, 16, -18, 3, -2, 26, 0, 13, -23, -2, -19,
+ -28, -18, 15, 12, 22, -4, 23, -17, -22, -9, -18, -4, 11, 13, 0, 34,
+ -16, -20, 26, 23, 15, -4, -25, 7, 8, -9, 8, 44, 1, -40, 17, -32,
+ 9, -30, -52, 52, 3, 2, -21, 83, 58, -14, -46, -61, -12, -67, -20, 64,
+ 72, 57, -10, 5, 1, -77, 31, -47, -39, 12, 22, 57, 28, 0, 9, -76,
+ 15, -74, 33, -12, 39, 114, -35, -36, -38, -23, 27, -21, 14, 56, 47, 6,
+ -72, -61, -4, 18, -4, 19, 13, 45, 71, 48, -1, -125, -52, -56, -20, -18,
+ -12, 51, 78, 68, -46, 32, -40, -29, -28, -81, -25, 75, 42, 58, -38, 1,
+ -29, -34, 31, -36, -14, 10, 64, 37, 2, -31, -72, -17, -33, 30, -52, -54,
+ 25, 43, 70, 81, -9, -73, 4, -65, 15, -28, 25, 0, 28, 19, 51, -26,
+ 6, 0, -37, -15, -22, -20, -16, -5, 50, 56, 67, 25, 16, -35, -29, -14,
+ -39, 19, -24, -52, -13, -32, -10, 39, 33, 59, 6, 37, 55, 11, -9, -35,
+ -15, -57, -56, -36, -34, 19, 19, 6, 20, 17, -11, 5, 26, 19, 16, 7,
+ -20, -26, -55, -62, -36, -18, 19, 37, 47, 25, -6, -14, 1, -4, -13, 12,
+ 23, 34, 38, 41, 33, 31, -10, -56, -52, -49, -31, -40, -21, -12, 0, 5,
+ 12, 22, 22, 21, 31, 12, 2, -8, -4, -18, -7, 3, 1, -1, 11, 12,
+ 18, 17, 9, -2, -12, -13, -11, -1, 8, 3, 3, 2, 5, -5, -16, -15,
+ -13, -8, -12, -9, -2, -1, 2, 7, 10, 7, 11, 14, 7, -1, -4, 5,
+ -3, -2, 0, -6, -10, -1, -5, 3, 9, 0, -8, -9, -6, -6, 0, 6,
+ 3, 6, 7, 10, 0, -8, -3, -5, -1, -8, -7, -4, -3, -3, 0, -1,
+ -6, 2, 7, 7, 5, 4, 10, 5, 8, -1, -11, -15, -11, -15, -10, -1,
+ -8, -12, -5, 1, 3, 6, 8, 11, 18, 22, 26, 10, -10, -1, -15, -3,
+ -21, -16, -14, -12, -7, -8, -18, -20, -11, 9, 20, 27, 26, 11, 1, 21,
+ 6, 3, -9, -15, -9, -20, 3, 5, 21, 14, 6, 11, -21, -22, -6, -21,
+ -23, -18, 11, 6, 5, 21, 9, 23, 16, -3, -30, -7, -27, -4, 5, 18,
+ 22, 16, 2, 7, -1, -2, -10, -14, -10, -17, -10, -15, -16, 3, 12, 30,
+ 18, -1, -6, -15, -3, 5, 11, -18, -2, 8, 21, 11, -13, -4, -30, -7,
+ 0, 12, 25, -3, 17, 14, -20, -6, -27, -41, -11, -12, 23, -8, 13, 24,
+ 18, 27, -11, -8, -12, -2, 17, 23, 13, -20, -21, -2, -21, -34, -46, -23,
+ 28, 48, 9, -10, 8, 29, 27, 5, -29, -12, 13, -5, -2, -35, 1, 3,
+ 24, 13, 17, -18, -30, -21, 14, -1, 6, -8, 48, 45, -7, -34, -49, -32,
+ -6, -26, 20, 29, 76, 30, -21, -66, -36, -15, 40, -5, 29, 3, 10, -39,
+ -25, -2, 24, 19, 19, -4, -8, 3, -22, -23, -18, 13, 17, -3, -25, 23,
+ 66, 26, -18, -27, -34, -30, -30, 36, 25, 28, -22, -17, -7, -22, 21, 18,
+ 42, 8, -25, -28, -31, -10, 15, 18, 0, -1, -5, 16, -12, 13, 13, 12,
+ -8, -37, -9, 13, -5, 8, -3, 13, -8, 4, 24, -16, -43, -18, 26, 26,
+ -11, -9, 19, 9, -15, 9, 15, -12, -31, -27, 8, 29, 5, 7, 17, -33,
+ -14, 14, 23, -1, -18, -18, -4, -35, -17, 47, 71, -16, -20, -11, -16, -25,
+ 6, 37, 14, -18, 1, -8, -14, 10, 14, 2, -20, 0, 20, -10, -25, 14,
+ 32, 7, -39, -38, -3, 34, 25, 13, 3, -24, -34, 5, 38, 18, 7, 29,
+ -30, -74, -41, 36, 40, -12, 26, 55, -17, -59, -26, 28, -2, -31, 24, 25,
+ -44, -39, 21, 44, -1, 10, 33, -34, -50, -12, 18, 13, 20, 17, -6, -31,
+ -10, -6, -1, 7, 12, 14, 6, -16, -24, 6, 9, -16, -16, 6, 2, -10,
+ 13, 12, -10, 0, 11, 11, 10, -3, -22, -22, -12, -7, 19, 17, -2, -12,
+ 6, 16, 7, -11, -1, -20, -22, -8, 26, 16, -3, 12, 1, -33, 2, 30,
+ -23, -5, 28, -17, -19, 21, 9, -28, -14, 25, -1, 4, 24, 0, -26, -9,
+ 7, 2, -2, 20, -10, -11, 5, -3, -4, 8, -9, 14, 18, 25, -22, -15,
+ -22, -3, -12, 27, 30, 15, -11, -26, -4, 15, -7, -14, 23, -23, -4, 34,
+ -2, -38, 14, -11, -24, 16, 34, 11, -13, 3, -3, -19, -34, 0, -3, 24,
+ 43, 1, -12, -38, -25, -11, 23, 35, 12, -28, -25, -16, 7, 22, 1, -10,
+ 8, 8, -3, 6, -24, -20, -13, 9, 31, 12, -16, 7, -29, 5, 8, -28,
+ 3, 4, 12, 26, -9, -15, -5, -20, 9, 21, 0, 1, -9, 0, 8, -3,
+ -7, -9, -3, 22, 8, 3, -11, -9, -11, 3, 15, 9, -10, 1, -3, -3,
+ -2, -5, 9, 0, 12, 7, -15, -7, 0, -8, 5, 9, -5, 7, -7, 10,
+ 4, -11, -2, -8, -4, 9, 9, 0, -2, -11, -3, -4, 3, 4, 3, -2,
+ 3, 3, -8, -9, -2, 0, 3, 5, -1, -10, -7, 2, 8, 3, 0, -5,
+ -5, 2, 4, -2, -5, -3, 2, 3, 0, 2, -5, -3, 3, 2, -2, -4,
+ -2, 1, 2, 1, 0, -1, 1, -2, -5, 0, 0, 2, 0, -3, -2, 0,
+ 1, 0, -2, -2, -2, 0, 3, 3, -2, -5, -1, -1, -1, -4, 3, 9,
+ 1, -1, -2, -11, -7, 1, 9, 11, 8, -4, -11, -12, -9, -4, 18, 15,
+ 14, 1, -22, -29, -14, 3, 30, 29, 14, -2, -35, -43, -11, 13, 36, 42,
+ 15, -16, -49, -44, -10, 28, 47, 38, 11, -25, -66, -39, 4, 36, 58, 33,
+ -3, -44, -65, -29, 19, 52, 54, 23, -13, -59, -65, -15, 32, 69, 49, 8,
+ -30, -74, -51, 3, 43, 71, 40, -5, -48, -77, -31, 16, 57, 67, 24, -15,
+ -67, -72, -12, 36, 66, 59, 5, -31, -80, -51, 3, 49, 75, 37, -2, -59,
+ -81, -28, 20, 67, 66, 22, -23, -76, -65, -10, 41, 78, 48, 4, -36, -85,
+ -47, 6, 59, 80, 31, -8, -69, -82, -22, 29, 73, 63, 17, -31, -81, -63,
+ -1, 47, 79, 47, 3, -56, -90, -40, 19, 75, 73, 28, -25, -86, -74, -10,
+ 48, 85, 56, 6, -51, -93, -48, 11, 67, 86, 33, -11, -78, -87, -29, 36,
+ 89, 66, 13, -38, -91, -60, 2, 50, 83, 48, 0, -56, -90, -41, 16, 71,
+ 78, 30, -17, -80, -75, -20, 31, 82, 62, 15, -32, -85, -66, -7, 48, 84,
+ 50, 4, -53, -87, -44, 8, 62, 78, 35, -8, -65, -83, -30, 23, 70, 71,
+ 24, -20, -76, -75, -12, 32, 73, 62, 15, -30, -85, -62, -2, 41, 76, 51,
+ 9, -39, -86, -52, 1, 45, 79, 46, 8, -49, -89, -46, 3, 54, 80, 43,
+ 7, -55, -83, -50, 0, 53, 76, 54, 11, -52, -83, -55, 0, 40, 67, 58,
+ 22, -32, -79, -67, -11, 28, 63, 52, 37, -9, -70, -63, -28, 10, 42, 49,
+ 53, 8, -46, -64, -41, 1, 22, 38, 51, 39, -16, -63, -46, -23, 5, 33,
+ 38, 48, 14, -42, -57, -29, -5, 22, 37, 40, 28, -23, -53, -39, -10, 14,
+ 30, 40, 31, -1, -48, -40, -18, 11, 19, 31, 26, 14, -20, -50, -25, -5,
+ 11, 31, 30, 14, 0, -35, -39, -4, -1, 19, 27, 17, 9, -10, -39, -21,
+ -8, 9, 24, 26, 13, -5, -19, -30, -12, -1, 17, 25, 16, 3, -19, -26,
+ -13, -6, 17, 22, 20, 5, -16, -32, -19, -1, 23, 27, 23, 4, -30, -33,
+ -23, -1, 35, 35, 24, -2, -41, -45, -21, 9, 45, 41, 22, -12, -50, -46,
+ -18, 28, 55, 45, 10, -27, -78, -42, 0, 53, 66, 32, -1, -61, -74, -28,
+ 27, 64, 64, 24, -28, -80, -66, -15, 53, 84, 48, 5, -59, -94, -41, 17,
+ 75, 80, 26, -21, -91, -79, -12, 48, 87, 55, 10, -58, -96, -46, 9, 80,
+ 81, 30, -23, -84, -80, -15, 49, 90, 49, 9, -57, -95, -45, 17, 76, 79,
+ 26, -20, -91, -75, -18, 52, 90, 52, 6, -59, -92, -41, 15, 68, 80, 31,
+ -21, -87, -76, -13, 45, 87, 49, 11, -60, -94, -35, 14, 80, 68, 22, -23,
+ -89, -66, -7, 47, 93, 44, -8, -61, -95, -31, 24, 86, 75, 10, -35, -96,
+ -66, -1, 61, 100, 44, -12, -77, -105, -33, 32, 97, 92, 16, -44, -111, -90,
+ -5, 65, 121, 65, -3, -80, -123, -59, 17, 98, 111, 46, -25, -112, -109, -33,
+ 42, 112, 90, 30, -55, -115, -84, -17, 66, 105, 71, 13, -73, -113, -61, 0,
+ 77, 96, 56, 4, -80, -108, -50, 8, 78, 93, 47, 3, -88, -98, -40, 7,
+ 65, 76, 53, 18, -71, -90, -44, 0, 39, 57, 43, 34, -19, -69, -54, -19,
+ 18, 32, 31, 34, 7, -40, -36, -21, -1, 12, 12, 25, 27, -9, -32, -14,
+ -14, 2, 0, 1, 20, 19, -2, -13, -11, -18, -12, -2, 18, 24, 12, -2,
+ -14, -19, -19, -12, 18, 24, 22, -2, -15, -32, -20, 3, 22, 26, 17, -13,
+ -31, -27, -13, 17, 33, 32, 5, -29, -47, -29, 2, 33, 42, 32, -6, -53,
+ -52, -24, 22, 51, 41, 27, -32, -74, -45, 0, 45, 59, 33, -1, -62, -66,
+ -31, 26, 73, 49, 17, -42, -80, -42, -8, 63, 72, 28, -10, -75, -72, -23,
+ 32, 88, 47, 13, -56, -93, -38, 10, 76, 69, 26, -20, -96, -66, -10, 48,
+ 90, 47, 0, -69, -103, -29, 25, 87, 73, 18, -35, -104, -68, -2, 61, 93,
+ 47, -5, -83, -98, -31, 30, 92, 68, 17, -39, -97, -63, -5, 64, 88, 35,
+ -9, -74, -86, -22, 31, 85, 54, 13, -44, -93, -46, 9, 65, 75, 23, -17,
+ -75, -78, -15, 39, 84, 54, 3, -52, -96, -46, 12, 71, 90, 29, -18, -89,
+ -87, -26, 36, 86, 72, 26, -37, -106, -77, -12, 45, 99, 68, 22, -46, -108,
+ -73, -10, 43, 87, 69, 19, -27, -92, -79, -12, 27, 63, 57, 26, 4, -53,
+ -75, -35, 12, 33, 37, 31, 26, -9, -53, -39, -16, 6, 20, 23, 22, 13,
+ -8, -22, -23, -18, -3, 9, 25, 19, 4, -8, -20, -17, -10, 6, 16, 17,
+ 13, -8, -34, -21, -6, 17, 33, 23, 6, -32, -51, -23, 11, 36, 46, 31,
+ -11, -46, -65, -31, 15, 59, 55, 28, -20, -73, -64, -26, 42, 78, 51, 14,
+ -53, -85, -48, -4, 70, 80, 38, -16, -80, -76, -32, 39, 90, 58, 19, -59,
+ -99, -50, 14, 71, 75, 36, -21, -94, -70, -23, 51, 88, 53, 9, -68, -97,
+ -40, 16, 83, 73, 29, -33, -100, -61, -13, 58, 87, 41, 0, -74, -81, -35,
+ 24, 87, 55, 20, -41, -88, -58, 0, 69, 73, 34, -5, -86, -75, -20, 38,
+ 79, 49, 13, -48, -90, -39, 2, 71, 68, 31, -16, -84, -67, -15, 38, 79,
+ 42, 12, -50, -85, -37, 2, 62, 71, 34, -5, -83, -75, -24, 27, 82, 51,
+ 27, -30, -88, -54, -15, 44, 73, 50, 16, -49, -81, -47, -6, 38, 58, 50,
+ 27, -31, -69, -52, -13, 15, 36, 45, 33, -5, -41, -44, -23, 2, 14, 27,
+ 33, 10, -25, -20, -18, -6, 1, -1, 17, 22, 3, -13, -10, -17, -13, -6,
+ 13, 24, 15, 1, -11, -19, -19, -16, 12, 24, 24, 3, -12, -29, -26, -1,
+ 18, 27, 19, -4, -31, -28, -19, 11, 30, 35, 12, -21, -46, -35, -6, 28,
+ 42, 36, 5, -46, -57, -31, 10, 50, 43, 33, -16, -71, -55, -9, 35, 62,
+ 38, 10, -51, -71, -40, 11, 69, 58, 24, -26, -81, -50, -18, 48, 79, 37,
+ 1, -62, -81, -32, 16, 84, 59, 20, -37, -96, -50, -2, 63, 78, 33, -4,
+ -85, -80, -20, 33, 88, 59, 10, -50, -107, -47, 14, 75, 85, 27, -19, -95,
+ -83, -15, 47, 94, 60, 8, -66, -105, -46, 15, 83, 81, 26, -23, -91, -76,
+ -18, 48, 92, 47, 1, -59, -94, -36, 18, 78, 66, 19, -27, -91, -60, -3,
+ 53, 80, 35, -8, -62, -86, -28, 27, 79, 66, 13, -38, -94, -62, 1, 56,
+ 95, 42, -6, -75, -96, -39, 22, 80, 80, 36, -20, -97, -92, -24, 30, 93,
+ 79, 32, -27, -102, -87, -22, 31, 81, 79, 29, -14, -81, -91, -25, 19, 56,
+ 63, 31, 11, -39, -77, -47, 3, 31, 37, 33, 27, 3, -48, -46, -20, 0,
+ 18, 22, 23, 16, -3, -20, -19, -15, -4, 2, 8, 5, 0, 0, 0, 1,
+ -1, -1, 3, -4, -2, 1, -1, -2, 2, 3, -6, 1, 2, -6, 2, 2,
+ -4, -1, 2, -5, 1, 4, -4, 0, -1, 0, -1, -2, 2, 2, -6, 0,
+ 4, -3, -3, 4, -2, -3, -2, 0, 1, 1, -2, -2, 3, -8, 27, -42,
+ 11, 21, -35, 34, -25, 12, 9, -24, 14, 13, -38, 53, -42, -3, 46, -73,
+ 55, -16, -9, 28, -49, 38, -12, -21, 49, -51, 20, 32, -73, 64, -28, -7,
+ 32, -50, 42, -11, -30, 49, -21, -31, 46, -25, -7, 20, -22, 18, -16, -10,
+ 21, -23, 5, 28, -35, 8, 0, 8, -26, 19, 6, -11, -20, 64, -46, -18,
+ 51, -73, 119, -117, 46, 36, -80, 67, -46, 22, 0, -24, 56, -59, 14, 26,
+ -40, 24, -9, 20, -20, -15, 43, -26, -11, 9, 14, -3, -31, 6, 54, -62,
+ 3, 67, -78, 20, 21, -25, 31, -41, 18, 27, -53, 32, 15, -48, 37, -11,
+ 4, -12, -3, 31, -24, -21, 42, -10, -45, 55, -32, 34, -43, -14, 86, -78,
+ 8, 39, -35, -2, 13, 2, 5, -11, -4, 7, 5, -31, 37, -4, -28, 28,
+ -9, -11, 10, -1, 4, -18, 17, -9, -13, 24, -18, 20, -18, -30, 59, -25,
+ -29, 48, -15, -29, 23, 4, -3, -18, 14, 6, -8, -19, 19, 8, -13, 0,
+ 13, -18, 4, 1, 0, 0, 10, -14, -12, 39, -46, 23, 9, -22, 23, -20,
+ -22, 63, -42, -28, 77, -66, 12, 38, -56, 31, 27, -77, 66, -11, -39, 59,
+ -33, -41, 92, -54, -50, 96, -36, -46, 46, -17, 31, -43, -28, 98, -57, -50,
+ 84, -22, -44, 39, -8, 17, -28, -13, 63, -67, 16, 10, 3, -15, -4, 36,
+ -34, -1, 26, -27, -2, 13, 7, -22, 0, 27, -11, -19, 6, 26, -42, 14,
+ 18, -7, -14, -10, 37, -14, -24, 25, -4, -5, -10, 3, 35, -39, -7, 31,
+ -8, -23, 15, 4, -1, -25, 28, 7, -35, 34, -16, -1, 9, -35, 45, -22,
+ -17, 48, -52, 24, 22, -65, 48, 7, -45, 47, -19, -33, 71, -70, 46, -7,
+ -52, 68, -25, -35, 48, -13, -17, 14, 2, -12, 8, -10, 1, 22, -32, 4,
+ 34, -26, -18, 29, -7, -19, 15, -7, 15, -8, -29, 50, -22, -35, 53, -19,
+ -37, 47, -9, -40, 41, 1, -27, 7, 3, 0, 0, -7, 13, -7, -21, 26,
+ 14, -44, 11, 40, -51, 10, 26, -28, 16, -13, -3, 31, -42, 11, 34, -52,
+ 11, 34, -43, 10, 29, -19, -21, 27, -10, -5, 10, -14, 11, 3, -35, 43,
+ 3, -52, 37, 22, -66, 49, -12, -19, 50, -58, 16, 42, -70, 50, -2, -42,
+ 60, -69, 43, 11, -57, 54, -8, -31, 23, -8, -7, 24, -32, 11, 21, -51,
+ 60, -44, -6, 68, -87, 33, 45, -79, 50, -7, -13, 21, -40, 31, 12, -41,
+ 18, 24, -39, 15, 7, -17, 25, -20, -12, 43, -47, 17, 6, -16, 10, 4,
+ -11, -1, 14, -10, -7, 6, 9, -23, 9, 3, 13, -30, 16, 16, -33, 17,
+ 4, -17, 23, -29, 3, 54, -86, 50, 11, -41, 30, -23, 15, 18, -60, 56,
+ 7, -65, 49, -4, -12, 1, -6, 19, -4, -33, 35, -10, -12, 13, -2, -2,
+ -2, 2, -10, 16, -8, -11, 19, -6, -19, 24, -14, 9, 3, -24, 24, -6,
+ -13, 19, -11, -6, 6, -9, 16, -8, -10, 14, -10, -1, -5, 16, -8, -25,
+ 37, -11, -27, 37, -14, -13, 19, -17, 14, -5, -15, 26, -27, 10, 11, -23,
+ 22, -5, -19, 25, -7, -28, 44, -35, 0, 25, -31, 31, -10, -26, 46, -41,
+ 2, 33, -40, 24, 8, -43, 44, -12, -25, 37, -25, -6, 29, -27, 5, 24,
+ -40, 24, -1, -25, 23, -1, -6, -2, -1, 14, -24, 8, 13, -11, 0, -13,
+ 16, 15, -56, 43, 12, -35, 14, -9, 18, -10, -19, 28, -3, -27, 23, -2,
+ -14, 27, -35, 10, 35, -68, 44, 7, -43, 46, -21, -25, 56, -35, -21, 51,
+ -33, -8, 28, -27, 19, -2, -26, 36, -26, 3, 13, -12, 6, -10, 8, -14,
+ 15, -12, 0, 13, -9, -16, 32, -27, 3, 23, -49, 49, -17, -31, 63, -64,
+ 25, 36, -76, 61, -11, -47, 75, -54, -9, 69, -81, 32, 29, -63, 46, -7,
+ -26, 39, -31, 6, 18, -26, 13, -5, 5, -5, -2, 5, -12, 17, -17, -2,
+ 22, -25, 1, 20, -19, 3, 6, -6, 3, -9, 10, -6, -3, 7, -7, -3,
+ 12, -5, -5, -11, 24, -7, -23, 24, 0, -14, 0, 12, -10, -2, 5, 0,
+ 1, -10, 10, -2, -17, 26, -11, -16, 28, -22, 6, 4, -17, 30, -27, -7,
+ 46, -54, 15, 29, -42, 25, -4, -15, 26, -29, 11, 15, -28, 19, -7, 1,
+ 8, -20, 14, 1, -15, 11, -2, -2, 0, -10, 15, -5, -12, 15, -1, -15,
+ 12, 4, -15, 9, -1, -9, 9, -5, -6, 13, -12, 1, 6, -6, -3, 6,
+ -4, 0, -6, 11, -9, -2, 13, -12, -2, -1, 8, -11, 4, 2, -6, 4,
+ -4, 4, 0, -13, 15, 0, -21, 23, -5, -15, 15, -2, -9, 6, -2, -4,
+ 2, 3, -1, -7, 7, -2, -9, 6, 2, -9, 4, 5, -12, 10, -9, 4,
+ 5, -16, 12, -2, -13, 20, -13, -4, 17, -23, 14, 2, -20, 22, -13, -3,
+ 15, -22, 12, 4, -18, 17, -7, -7, 13, -14, 6, 4, -10, 9, -5, -6,
+ 7, 0, -7, 8, -4, -1, 0, -6, 4, 7, -14, 2, 13, -16, 3, 10,
+ -15, 7, -1, -10, 14, -10, -2, 11, -9, -4, 7, -6, 3, -3, -5, 9,
+ -6, -3, 5, 1, -7, 3, -2, 0, -2, 0, 4, -3, -2, 4, -6, 4,
+ -2, -2, 0, 1, 0, -7, 7, -2, -7, 9, -7, -4, 11, -15, 11, -2,
+ -9, 9, -4, -3, 2, 3, -7, 5, 0, -5, 6, -7, 1, 7, -10, -2,
+ 13, -9, -4, 8, -4, -2, -1, 1, 1, -7, 4, 5, -8, 0, 6, -6,
+ 0, 3, -4, 0, 1, -2, 2, -4, -4, 8, -7, -1, 6, -9, 8, -3,
+ -6, 12, -12, 1, 10, -11, 1, 5, -6, 3, -2, -3, 7, -10, 2, 7,
+ -12, 5, 2, -5, 3, -5, 0, 6, -10, 3, 4, -8, 2, 2, -3, 3,
+ -8, 8, 2, -14, 10, 3, -12, 8, 2, -11, 8, -2, -6, 9, -7, -4,
+ 10, -9, -1, 7, -7, 1, 3, -8, 8, -2, -8, 10, -3, -5, 5, -6,
+ 3, 1, -8, 10, -5, -5, 7, -4, -2, 2, -3, 1, -1, -3, 4, -3,
+ 0, 0, 0, 0, -4, 3, -2, -3, 3, -5, 3, 0, -7, 5, 1, -8,
+ 5, 1, -6, 6, -5, 0, 3, -7, 3, 2, -6, 3, 2, -6, 3, 1,
+ -3, -2, 5, -4, -1, 3, -4, 0, 0, -3, 5, -5, -3, 7, -5, -3,
+ 6, -4, 0, -1, -3, 3, -2, -1, 2, -1, -2, 1, -2, 1, -1, -7,
+ 8, -1, 5, -7, 13, -22, 8, -7, 8, -110, -28, 24, 54, 36, 2, 60,
+ -45, 57, 42, -43, 20, 41, -66, 24, -11, 18, -18, -38, -63, -36, 30, -11,
+ 33, 25, 30, 18, 11, -18, -5, 5, -46, 40, 1, -13, -18, -20, -31, 20,
+ 10, 29, -7, -18, 40, -29, -17, 42, -19, 6, -4, 6, -8, 10, -26, -5,
+ 3, 1, -17, 6, 0, 19, -1, 8, 0, -6, -10, -1, -12, -1, 1, -3,
+ 8, -7, 4, 11, 4, 14, -13, 16, -19, -4, -13, -13, -14, 6, 4, -1,
+ 4, 11, -1, 11, -1, 1, -4, -1, -15, 6, -9, 1, -1, 0, 3, 1,
+ -8, 3, -1, -1, 2, -2, 2, -2, 1, -5, -7, 3, -3, 6, -3, 4,
+ -1, 0, -4, 2, -7, 3, -6, -1, -1, 4, 0, 3, -2, 2, -5, 5,
+ -8, -3, -3, 2, -5, 7, -1, 4, -2, 4, -10, 6, -6, -1, -4, 5,
+ -13, 7, -6, 5, -8, 17, -20, 14, -6, 9, -40, 71, -127, 9, -73, 127,
+ 76, -28, 74, -32, 8, -62, -49, -38, 40, -68, 22, -12, 68, 10, 39, -10,
+ 0, 35, -23, 0, -59, -15, -7, -3, -23, 1, -20, 37, 27, 2, 30, -2,
+ 17, 2, -5, -7, -27, -29, 16, -3, -11, 1, -16, -5, -8, -10, 7, 32,
+ 9, 5, -4, 16, 5, -8, -17, -16, 5, -13, 8, 11, 15, -10, -9, 0,
+ -1, 2, 7, -3, -23, 9, 2, 3, 1, -13, -1, -6, 11, -6, 8, 1,
+ 12, -12, 9, -14, 8, -1, 0, -3, -13, 4, -7, -4, 8, 5, -5, -7,
+ 4, -2, -3, 2, 3, -6, 8, -3, 1, -3, -2, 2, -6, 2, -4, -3,
+ -4, 3, 1, 0, 0, 1, -1, -1, 2, -2, 0, -4, -2, 1, 2, 0,
+ -3, 1, -3, 0, -1, -3, -6, 2, -2, 3, -4, 10, -8, 9, -5, 12,
+ -19, 46, 37, -128, 60, -90, 102, -65, 40, -57, 39, -6, 23, -8, 19, 24,
+ 15, -17, -47, -27, -36, -16, 21, 3, 23, 14, 50, -8, 19, 25, 7, -9,
+ -28, -63, -37, 0, -42, 54, -17, 68, -3, 30, -12, -4, 11, -15, 9, -25,
+ -15, -2, -27, -25, 38, -8, -13, 33, 24, 12, -38, 39, -12, -3, -17, -44,
+ 38, 2, 27, 3, -5, -4, -13, -30, -56, -4, 11, 1, 9, 17, 46, 25,
+ -14, 6, -3, -7, -21, 2, 16, -5, -22, 2, -2, 6, -12, -25, -15, 10,
+ 9, 8, 11, 43, 8, -5, -22, -16, 14, -31, 16, 7, -7, -26, -20, -2,
+ 9, 11, 26, 7, 6, -20, -13, 0, 4, 17, -17, -18, 10, 2, -10, 27,
+ -8, 24, -23, -14, 1, 0, 13, -19, 14, 10, -16, 16, -4, -20, 20, -33,
+ 2, 2, 24, 21, -3, -26, -24, -18, -18, 10, 10, 24, 18, 2, 9, -24,
+ 16, -14, -8, 9, -5, -14, 8, -5, 30, -11, 11, -13, -15, -12, 7, 4,
+ -13, -13, 13, -13, 12, 23, 9, 0, 14, -10, -9, -35, -2, -21, 12, -1,
+ 17, 19, 11, -4, 0, -18, -24, 11, -10, 1, 11, 12, -13, -16, 10, -23,
+ 21, 9, -9, 3, 12, -6, 3, -5, 12, 0, -2, 0, -19, -9, 5, -11,
+ -7, 10, 1, -3, 9, 18, -6, 0, -1, 1, -13, 2, 1, -3, -8, 17,
+ -4, -9, 18, -15, 8, -1, -11, -5, -14, 11, -5, -7, 12, 16, -7, 7,
+ -3, -11, -5, -6, 1, 4, -3, -3, 15, 5, 0, 3, 6, -16, 4, -14,
+ -6, -9, -4, 2, 11, 11, 7, -2, 4, -12, -7, -14, -6, -7, 9, 4,
+ 7, -2, 6, 5, 6, -4, -3, -4, 7, -7, -11, -9, 0, -3, 7, -2,
+ -2, 3, 13, -4, -6, -15, 9, -7, -1, 4, 6, 5, 8, -6, -8, 0,
+ -11, -4, 6, -8, 4, 3, 5, 13, -4, -9, -3, 4, -3, -3, 4, -1,
+ -12, 6, -14, 2, 3, 15, 2, 6, -7, -8, 3, 1, -2, 3, -3, -12,
+ -6, -14, 7, -2, 13, 6, 10, 6, 0, -2, -10, -12, -8, -6, -7, -6,
+ 6, 4, -2, 5, 2, 0, -1, 3, -11, 4, 0, 20, -8, -2, 0, -1,
+ -3, 7, -3, -4, -2, -6, -10, -10, -8, 1, 2, 5, 8, 2, 5, 8,
+ 3, 4, 3, -2, -15, 0, -1, -7, -2, -5, -10, 10, -1, 5, 3, 5,
+ -1, -2, -8, -5, -9, 1, -8, 6, 5, 4, 1, 1, 2, 3, -2, 4,
+ -7, 1, -7, -9, -2, 0, 2, 3, 6, -8, 8, 3, 0, -2, -9, -3,
+ -2, 0, 3, -1, -2, -3, 7, -3, 10, -8, 1, -12, 3, -7, 2, -3,
+ 7, 4, 4, 0, 0, -6, -1, -5, -3, -4, -7, 0, 5, 7, 0, 2,
+ -3, 10, -1, 3, -7, -5, -4, -9, -3, -7, 5, -4, 9, 2, 1, 4,
+ 5, 0, -5, 1, -8, 4, -9, 5, -5, 0, 3, -2, -1, 1, 1, -7,
+ 7, 0, 3, -5, 0, -3, -1, -1, -5, -1, 1, -1, 1, -1, 0, 2,
+ 0, 2, -7, -7, 4, -1, 0, 3, 4, -1, -3, -4, -6, 3, -2, 4,
+ -1, 5, -2, -1, -5, -2, -4, 1, 3, 2, 2, 0, -3, 1, 1, -3,
+ -3, -1, 1, -3, -2, -1, -2, -3, -1, 0, 4, 3, 5, 2, 1, -4,
+ -9, -3, -7, 1, -2, 7, -2, 3, 3, 3, 1, 0, -1, -6, -7, -6,
+ -4, -1, 1, 0, 5, 2, -2, 2, -3, -1, 3, -1, 1, -4, -4, -5,
+ 0, -7, 2, -4, 3, 4, 1, 2, -1, -1, -2, -2, 0, -1, 1, -1,
+ -1, -3, 1, 1, 3, -3, -1, 1, 1, -2, -3, -8, -5, 0, -1, 5,
+ 2, 3, 1, -2, -1, -1, -3, 1, 1, -2, -3, -3, -1, 0, -1, 1,
+ 2, 2, 5, 0, -1, -2, -1, -2, 0, -4, 0, -5, -1, -1, 0, 1,
+ 5, 4, -2, -1, -2, 0, -6, -1, 0, 1, -1, -2, 1, 0, 0, 3,
+ 1, -2, 1, -2, -4, -1, 0, -1, -1, -4, -2, -4, 2, -1, 1, 0,
+ 3, 2, 0, 4, -1, 4, -6, 2, -4, -3, -5, -4, -3, 0, 2, 0,
+ 1, 4, 2, 2, -2, -2, -5, -6, -5, -3, -2, 1, -1, 0, 0, 2,
+ 2, 2, 0, 4, -2, 3, 2, -1, -2, -3, -3, -3, -5, -5, -5, -1,
+ -1, 0, 2, 2, 4, 1, 2, 1, 2, -1, -1, -3, -4, -5, -3, -2,
+ -2, -1, 1, 4, 2, 2, 2, 1, -1, -2, -6, -2, -3, 2, -1, 1,
+ -2, 0, 2, 1, 2, -2, 1, 0, -2, -2, -3, 0, -2, -1, -1, 0,
+ -2, -2, 1, 0, 2, -1, 1, -1, 0, -1, -1, -7, 8, -1, 5, -7,
+ 13, -22, 8, -7, 8, -110, -28, 24, 54, 36, 2, 60, -45, 57, 42, -43,
+ 20, 41, -66, 24, -11, 18, -18, -38, -63, -36, 30, -11, 33, 25, 30, 18,
+ 11, -18, -5, 5, -46, 40, 1, -13, -18, -20, -31, 20, 10, 29, -7, -18,
+ 40, -29, -17, 42, -19, 6, -4, 6, -8, 10, -26, -5, 3, 1, -17, 6,
+ 0, 19, -1, 8, 0, -6, -10, -1, -12, -1, 1, -3, 8, -7, 4, 11,
+ 4, 14, -13, 16, -19, -4, -13, -13, -14, 6, 4, -1, 4, 11, -1, 11,
+ -1, 1, -4, -1, -15, 6, -9, 1, -1, 0, 3, 1, -8, 3, -1, -1,
+ 2, -2, 2, -2, 1, -5, -7, 3, -3, 6, -3, 4, -1, 0, -4, 2,
+ -7, 3, -6, -1, -1, 4, 0, 3, -2, 2, -5, 5, -8, -3, -3, 2,
+ -5, 7, -1, 4, -2, 4, -10, 6, -6, -1, -4, 5, -13, 7, -6, 5,
+ -8, 17, -20, 14, -6, 9, -40, 71, -127, 9, -73, 127, 76, -28, 74, -32,
+ 8, -62, -49, -38, 40, -68, 22, -12, 68, 10, 39, -10, 0, 35, -23, 0,
+ -59, -15, -7, -3, -23, 1, -20, 37, 27, 2, 30, -2, 17, 2, -5, -7,
+ -27, -29, 16, -3, -11, 1, -16, -5, -8, -10, 7, 32, 9, 5, -4, 16,
+ 5, -8, -17, -16, 5, -13, 8, 11, 15, -10, -9, 0, -1, 2, 7, -3,
+ -23, 9, 2, 3, 1, -13, -1, -6, 11, -6, 8, 1, 12, -12, 9, -14,
+ 8, -1, 0, -3, -13, 4, -7, -4, 8, 5, -5, -7, 4, -2, -3, 2,
+ 3, -6, 8, -3, 1, -3, -2, 2, -6, 2, -4, -3, -4, 3, 1, 0,
+ 0, 1, -1, -1, 2, -2, 0, -4, -2, 1, 2, 0, -3, 1, -3, 0,
+ -1, -3, -6, 2, -2, 3, -4, 10, -8, 9, -5, 12, -19, 46, 37, -128,
+ 60, -90, 102, -65, 40, -57, 39, -6, 23, -8, 19, 24, 15, -17, -47, -27,
+ -36, -16, 21, 3, 23, 14, 50, -8, 19, 25, 7, -9, -28, -63, -37, 0,
+ -42, 54, -17, 68, -3, 30, -12, -4, 11, -15, 9, -25, -15, -2, -27, -25,
+ 38, -8, -13, 33, 24, 12, -38, 39, -12, -3, -17, -44, 38, 2, 27, 3,
+ -5, -4, -13, -30, -56, -4, 11, 1, 9, 17, 46, 25, -14, 6, -3, -7,
+ -21, 2, 16, -5, -22, 2, -2, 6, -12, -25, -15, 10, 9, 8, 11, 43,
+ 8, -5, -22, -16, 14, -31, 16, 7, -7, -26, -20, -2, 9, 11, 26, 7,
+ 6, -20, -13, 0, 4, 17, -17, -18, 10, 2, -10, 27, -8, 24, -23, -14,
+ 1, 0, 13, -19, 14, 10, -16, 16, -4, -20, 20, -33, 2, 2, 24, 21,
+ -3, -26, -24, -18, -18, 10, 10, 24, 18, 2, 9, -24, 16, -14, -8, 9,
+ -5, -14, 8, -5, 30, -11, 11, -13, -15, -12, 7, 4, -13, -13, 13, -13,
+ 12, 23, 9, 0, 14, -10, -9, -35, -2, -21, 12, -1, 17, 19, 11, -4,
+ 0, -18, -24, 11, -10, 1, 11, 12, -13, -16, 10, -23, 21, 9, -9, 3,
+ 12, -6, 3, -5, 12, 0, -2, 0, -19, -9, 5, -11, -7, 10, 1, -3,
+ 9, 18, -6, 0, -1, 1, -13, 2, 1, -3, -8, 17, -4, -9, 18, -15,
+ 8, -1, -11, -5, -14, 11, -5, -7, 12, 16, -7, 7, -3, -11, -5, -6,
+ 1, 4, -3, -3, 15, 5, 0, 3, 6, -16, 4, -14, -6, -9, -4, 2,
+ 11, 11, 7, -2, 4, -12, -7, -14, -6, -7, 9, 4, 7, -2, 6, 5,
+ 6, -4, -3, -4, 7, -7, -11, -9, 0, -3, 7, -2, -2, 3, 13, -4,
+ -6, -15, 9, -7, -1, 4, 6, 5, 8, -6, -8, 0, -11, -4, 6, -8,
+ 4, 3, 5, 13, -4, -9, -3, 4, -3, -3, 4, -1, -12, 6, -14, 2,
+ 3, 15, 2, 6, -7, -8, 3, 1, -2, 3, -3, -12, -6, -14, 7, -2,
+ 13, 6, 10, 6, 0, -2, -10, -12, -8, -6, -7, -6, 6, 4, -2, 5,
+ 2, 0, -1, 3, -11, 4, 0, 20, -8, -2, 0, -1, -3, 7, -3, -4,
+ -2, -6, -10, -10, -8, 1, 2, 5, 8, 2, 5, 8, 3, 4, 3, -2,
+ -15, 0, -1, -7, -2, -5, -10, 10, -1, 5, 3, 5, -1, -2, -8, -5,
+ -9, 1, -8, 6, 5, 4, 1, 1, 2, 3, -2, 4, -7, 1, -7, -9,
+ -2, 0, 2, 3, 6, -8, 8, 3, 0, -2, -9, -3, -2, 0, 3, -1,
+ -2, -3, 7, -3, 10, -8, 1, -12, 3, -7, 2, -3, 7, 4, 4, 0,
+ 0, -6, -1, -5, -3, -4, -7, 0, 5, 7, 0, 2, -3, 10, -1, 3,
+ -7, -5, -4, -9, -3, -7, 5, -4, 9, 2, 1, 4, 5, 0, -5, 1,
+ -8, 4, -9, 5, -5, 0, 3, -2, -1, 1, 1, -7, 7, 0, 3, -5,
+ 0, -3, -1, -1, -5, -1, 1, -1, 1, -1, 0, 2, 0, 2, -7, -7,
+ 4, -1, 0, 3, 4, -1, -3, -4, -6, 3, -2, 4, -1, 5, -2, -1,
+ -5, -2, -4, 1, 3, 2, 2, 0, -3, 1, 1, -3, -3, -1, 1, -3,
+ -2, -1, -2, -3, -1, 0, 4, 3, 5, 2, 1, -4, -9, -3, -7, 1,
+ -2, 7, -2, 3, 3, 3, 1, 0, -1, -6, -7, -6, -4, -1, 1, 0,
+ 5, 2, -2, 2, -3, -1, 3, -1, 1, -4, -4, -5, 0, -7, 2, -4,
+ 3, 4, 1, 2, -1, -1, -2, -2, 0, -1, 1, -1, -1, -3, 1, 1,
+ 3, -3, -1, 1, 1, -2, -3, -8, -5, 0, -1, 5, 2, 3, 1, -2,
+ -1, -1, -3, 1, 1, -2, -3, -3, -1, 0, -1, 1, 2, 2, 5, 0,
+ -1, -2, -1, -2, 0, -4, 0, -5, -1, -1, 0, 1, 5, 4, -2, -1,
+ -2, 0, -6, -1, 0, 1, -1, -2, 1, 0, 0, 3, 1, -2, 1, -2,
+ -4, -1, 0, -1, -1, -4, -2, -4, 2, -1, 1, 0, 3, 2, 0, 4,
+ -1, 4, -6, 2, -4, -3, -5, -4, -3, 0, 2, 0, 1, 4, 2, 2,
+ -2, -2, -5, -6, -5, -3, -2, 1, -1, 0, 0, 2, 2, 2, 0, 4,
+ -2, 3, 2, -1, -2, -3, -3, -3, -5, -5, -5, -1, -1, 0, 2, 2,
+ 4, 1, 2, 1, 2, -1, -1, -3, -4, -5, -3, -2, -2, -1, 1, 4,
+ 2, 2, 2, 1, -1, -2, -6, -2, -3, 2, -1, 1, -2, 0, 2, 1,
+ 2, -2, 1, 0, -2, -2, -3, 0, -2, -1, -1, 0, -2, -2, 1, 0,
+ 2, -1, 1, -1, 0, -1, -1, 1, -7, 5, -22, -32, -35, -32, -43, -35,
+ -55, -42, -66, -48, -80, -57, -17, -128, -59, -76, 0, -26, 1, -33, 21, 3,
+ 16, 15, 26, 43, 28, 66, 6, 97, 40, 103, 67, 101, 102, 98, 94, 21,
+ 98, 90, 57, 78, 89, 81, 61, -6, 54, 4, 62, 19, 27, 34, 12, 16,
+ 14, -17, 19, -5, -2, -13, -38, -24, -3, -33, -14, -11, -16, 0, -13, 7,
+ -26, -13, -16, 6, -57, -23, -28, -13, -9, -34, -32, -20, -87, -62, -28, -38,
+ -75, -37, -27, -41, -71, -48, -30, -44, -83, -67, -52, -48, -45, -46, -45, -63,
+ -47, -40, -32, -45, -24, -32, -43, -21, -17, 0, 21, 26, 43, 51, 62, 47,
+ 41, 55, 57, 68, 34, 53, 63, 62, 71, 60, 61, 56, 53, 56, 54, 38,
+ 50, 58, 50, 40, 28, 54, 39, 41, 38, 22, 32, 20, -3, 19, -1, -7,
+ -6, -16, -16, -14, -27, -29, -46, -66, -61, -51, -54, -61, -41, -50, -47, -52,
+ -55, -45, -44, -28, -58, -56, -31, -37, -36, -32, -18, -16, -34, -29, -9, -21,
+ -20, -30, -22, -17, -19, -8, -12, -14, -6, -14, -6, -11, -2, 4, -6, 9,
+ 8, 17, 23, 13, 31, 13, 24, 30, 28, 29, 30, 43, 34, 37, 52, 42,
+ 44, 50, 67, 59, 49, 54, 48, 43, 51, 45, 42, 62, 47, 39, 37, 36,
+ 24, 28, 13, 3, 9, -11, -3, -9, -14, -18, -34, -27, -29, -39, -42, -38,
+ -46, -37, -46, -43, -41, -35, -38, -31, -38, -34, -39, -39, -34, -48, -44, -47,
+ -49, -54, -52, -44, -53, -37, -47, -38, -31, -38, -27, -19, -19, -15, -16, 0,
+ 0, 2, 7, 13, 29, 22, 32, 32, 39, 47, 41, 40, 55, 48, 41, 44,
+ 57, 43, 36, 47, 43, 42, 37, 32, 32, 27, 33, 36, 30, 23, 25, 25,
+ 22, 18, 22, 20, 16, 8, 6, 12, 7, 0, 1, 3, -5, -14, -9, -7,
+ -8, -19, -15, -16, -23, -21, -21, -32, -31, -29, -26, -27, -29, -33, -26, -29,
+ -30, -39, -28, -41, -43, -35, -34, -32, -29, -28, -28, -25, -27, -24, -27, -27,
+ -27, -22, -23, -17, -9, -10, -14, -10, -8, -4, -2, -1, -3, 5, 4, 10,
+ 11, 7, 13, 11, 14, 27, 22, 22, 22, 27, 36, 34, 36, 37, 45, 44,
+ 47, 48, 51, 49, 52, 51, 52, 48, 50, 47, 48, 42, 40, 29, 33, 24,
+ 22, 12, 5, 0, -3, -5, -9, -21, -21, -25, -19, -28, -28, -30, -33, -39,
+ -42, -42, -46, -46, -45, -42, -43, -47, -47, -36, -32, -30, -34, -31, -22, -29,
+ -29, -30, -26, -28, -30, -21, -26, -27, -21, -19, -16, -11, -12, -8, -2, 1,
+ -4, 1, 0, 1, 9, 8, 7, 12, 10, 13, 20, 17, 18, 21, 26, 29,
+ 30, 30, 29, 34, 33, 34, 33, 30, 32, 33, 28, 33, 29, 35, 32, 31,
+ 30, 31, 30, 25, 27, 24, 21, 21, 20, 16, 17, 12, 6, 4, -3, 1,
+ -6, -7, -11, -13, -11, -10, -8, -13, -12, -9, -17, -14, -19, -24, -22, -24,
+ -30, -32, -30, -33, -37, -39, -40, -42, -39, -41, -39, -40, -41, -35, -35, -35,
+ -37, -36, -33, -30, -25, -25, -19, -16, -16, -10, -6, -7, -4, -2, 1, 3,
+ 6, 10, 9, 15, 17, 18, 17, 13, 19, 18, 17, 19, 20, 24, 24, 27,
+ 27, 29, 30, 26, 28, 28, 27, 28, 26, 25, 24, 25, 20, 19, 17, 18,
+ 15, 12, 13, 10, 6, 8, 6, 3, 4, 3, 0, -3, 0, -1, -2, -5,
+ -4, -5, -4, -5, -6, -8, -9, -9, -12, -11, -16, -16, -15, -15, -13, -17,
+ -16, -17, -17, -21, -20, -25, -24, -24, -24, -26, -30, -30, -27, -30, -26, -26,
+ -27, -27, -25, -24, -19, -20, -17, -13, -12, -8, -8, -8, -6, -5, -2, -1,
+ 0, 3, 8, 10, 12, 16, 18, 24, 25, 25, 28, 30, 28, 32, 33, 31,
+ 32, 31, 35, 33, 31, 31, 27, 28, 26, 23, 23, 20, 22, 18, 16, 13,
+ 11, 9, 5, 4, -2, -2, -3, -8, -9, -11, -12, -13, -15, -15, -15, -15,
+ -15, -14, -12, -12, -13, -13, -8, -11, -10, -12, -10, -12, -12, -8, -8, -9,
+ -9, -9, -8, -9, -10, -11, -11, -10, -13, -14, -13, -16, -16, -17, -17, -18,
+ -19, -18, -17, -16, -16, -15, -15, -13, -12, -10, -12, -10, -9, -8, -6, -6,
+ -3, 0, 0, 1, 2, 2, 3, 4, 4, 5, 6, 7, 8, 9, 10, 11,
+ 12, 12, 13, 14, 14, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 15, 15, 14, 13, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4,
+ 3, 2, 1, 0, -1, -1, -2, -3, -4, -5, -5, -6, -7, -7, -8, -9,
+ -9, -10, -11, -11, -12, -12, -13, -13, -13, -13, -14, -14, -14, -15, -15, -15,
+ -15, -15, -15, -16, -16, -16, -15, -15, -15, -14, -13, -13, -12, -11, -10, -9,
+ -8, -7, -6, -5, -4, -2, -1, 0, 1, 2, 4, 5, 6, 7, 8, 9,
+ 10, 11, 12, 12, 13, 13, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16,
+ 17, 17, 17, 17, 17, 17, 16, 16, 15, 15, 14, 14, 13, 12, 11, 10,
+ 9, 7, 6, 5, 3, 1, 0, -2, -4, -5, -7, -9, -10, -11, -13, -14,
+ -15, -15, -16, -17, -17, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18,
+ -18, -17, -17, -16, -16, -15, -14, -14, -13, -12, -11, -10, -9, -8, -7, -6,
+ -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 9, 10,
+ 11, 11, 12, 13, 13, 13, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 14, 14, 14, 13, 12, 12, 11, 10, 9, 8, 8, 7,
+ 6, 5, 4, 3, 2, 1, 0, 0, -1, 10, -20, 30, 25, 21, 14, 4,
+ 15, -48, -33, 11, -70, 54, -5, -21, -8, -3, 73, -52, 65, -55, 80, -28,
+ -67, -3, -13, 21, -49, -2, 11, 36, 59, -60, 34, -28, 21, -25, -45, 54,
+ 5, 0, -19, -12, 20, 54, -51, -23, 22, 36, -59, -20, 8, 28, -9, -54,
+ 127, -44, 69, -128, 5, 69, -8, -98, 45, 69, 20, -97, 23, -7, 121, -81,
+ -2, -21, 51, -67, -14, -24, 127, -60, 45, -116, 127, -29, -93, -23, 107, -5,
+ -21, -62, 37, 41, 29, -74, -63, 103, 24, -59, -44, 62, 43, -28, -46, 7,
+ 72, 19, -70, -47, 42, 53, -68, -13, 37, 59, -38, -60, 39, 66, 27, -128,
+ 36, 77, 15, -74, -15, 75, 38, -49, -11, -39, 16, -8, -30, 35, 41, -1,
+ -2, 17, -68, 99, -97, 60, -49, 32, -44, -29, 82, -26, 39, -35, 10, 38,
+ -20, -21, -92, 83, -24, 13, 31, -33, 22, 45, -31, -24, 9, -24, -32, 42,
+ -17, 34, 7, -27, 6, 61, -9, -34, -5, -8, -17, -6, -34, 17, 43, -9,
+ 35, -34, 16, 27, -24, -17, -17, 5, -17, 42, -31, 22, 17, -26, -22, 32,
+ 41, -27, -25, -10, -5, 16, -2, 13, -1, 48, -33, -27, 6, 16, 13, -37,
+ -11, 18, 25, -42, -11, 46, -7, -15, 9, 15, 4, -3, -36, -24, 31, -8,
+ 14, 12, 27, -19, -17, -14, -7, 42, -5, -15, 5, 1, -15, 14, 43, -19,
+ 1, -25, -35, 16, 16, 29, -12, 8, -14, 1, 21, -8, -12, -22, -4, 24,
+ 26, -16, -22, 37, 3, -41, 7, 4, 3, 30, 4, -27, 11, -6, -26, 33,
+ 23, -23, -14, -20, -7, -4, 36, 0, 18, 10, -27, 1, 1, 16, -1, -4,
+ -44, -5, 17, 9, 13, -4, -3, 31, 24, -14, -26, 9, -27, -28, 19, 22,
+ 32, -11, -15, 5, 15, -23, -21, 16, 14, 18, -11, -26, 13, 10, -12, -12,
+ 11, 14, -6, -13, -3, 6, -6, 3, 12, 32, 14, -22, -45, -10, 37, 11,
+ -50, -11, 50, 22, -13, -4, -4, 15, -16, -33, 7, 34, -9, -14, -1, 21,
+ 15, -14, -12, -6, 7, 8, 2, 0, -5, 6, 15, 4, -9, 13, 3, -51,
+ -18, 27, 10, 5, -11, 6, -1, 5, 22, 2, -14, -39, -12, 19, 17, 4,
+ 11, 5, -25, 2, 23, 8, 2, -3, -39, -22, 4, 18, 6, 14, 25, 20,
+ -17, -20, 17, 7, -43, -38, -18, 17, 24, -6, 30, 44, 6, -36, -20, 7,
+ 24, 1, -69, -25, 47, 15, -4, 35, 19, -18, -22, -12, 20, 39, -36, -49,
+ 9, 28, -16, 9, 34, 36, -22, -69, -16, 39, 7, -28, -3, 33, -18, -7,
+ 18, 53, 24, -37, -61, -10, 38, 2, -24, -11, 12, 17, 0, 28, 50, -5,
+ -59, -57, 22, 14, -15, -5, 22, 9, -20, 19, 33, 31, -33, -62, -13, -2,
+ 45, -9, -4, -3, 19, 8, -8, 40, 8, -16, -44, -19, 16, 3, 23, -32,
+ 22, 5, -9, 5, 26, 21, -27, -18, -45, 3, 15, 0, 7, 7, 7, 13,
+ 18, -10, 3, -5, -30, -30, -3, 9, 31, 17, -10, 19, 28, -33, -20, 31,
+ 14, -67, -27, 13, 20, 29, 1, -2, 24, -3, -26, -12, 32, -7, -31, -17,
+ 5, 22, 11, -6, 6, 7, 2, 7, 5, -12, -22, -17, -24, 22, 47, 1,
+ 2, 10, 5, -29, -5, 13, 1, -30, -28, -5, 23, 25, 6, 5, 1, 7,
+ 0, 5, 3, -33, -37, -6, 19, 20, 26, -1, -15, 21, 9, -14, -13, 0,
+ -11, -24, -9, 9, 23, 1, 1, 32, 11, -25, -18, 5, -5, -6, -9, -10,
+ 2, 18, 4, 12, 6, -2, -8, 2, 2, -7, 2, -22, -5, 17, 25, 15,
+ -5, -1, -24, -8, -10, -5, 12, 7, -4, -10, 4, 8, 22, 11, -1, -12,
+ -31, -17, 6, 12, 11, 5, -3, -1, 22, 0, -4, 3, -18, -17, -3, 16,
+ 9, 2, -5, 0, 4, -9, 18, 17, -22, -19, -8, -6, 21, 11, -6, -16,
+ 33, 13, -15, -3, -15, 1, -3, -10, -7, 8, 17, -11, 9, 19, 0, 5,
+ 0, -18, -13, 2, -20, 10, 29, -11, -13, 5, 11, 16, 4, -25, -21, 13,
+ -5, 1, 3, -1, 6, 13, -7, -1, 17, -6, -6, -9, -6, -3, -1, 1,
+ 18, 11, -22, 2, 18, -2, -15, 1, 5, -12, -10, -7, 9, 26, 10, -11,
+ 5, 0, -7, -3, -11, -9, -3, 2, -10, 19, 28, -3, -3, -4, 9, -14,
+ -5, -7, 8, -3, -27, 5, 37, 11, -2, 3, -27, -15, 12, -2, 14, 2,
+ -8, -16, 22, 11, -1, 10, -17, -8, -5, -23, 2, 29, 8, -21, 8, 12,
+ 6, 8, -17, 3, -2, -12, -27, 16, 25, -5, -7, 2, 19, 1, -15, 7,
+ 2, -5, -34, 2, 18, 17, -10, 2, 18, -1, -12, -10, 5, 1, -16, -9,
+ 12, 21, 4, -10, 2, 12, 1, -19, -11, 20, 5, -14, -21, 5, 17, -5,
+ 3, 17, 4, -25, -5, 5, 4, 0, -5, 2, 2, -1, 1, 13, 0, -11,
+ -8, 3, 2, -1, -3, -3, 11, 8, -6, 2, 7, 4, -5, -23, -2, 14,
+ -1, -15, -2, 15, 10, 1, -4, 16, 1, -24, -12, 8, 8, -20, -2, 14,
+ 13, 10, 2, 2, -9, -6, -9, -3, 5, 7, -3, -9, 0, 2, 8, 3,
+ -1, 2, -4, 0, -2, 0, -2, 3, 5, -4, -28, 22, -43, 36, -13, -127,
+ -43, 2, -18, 126, 78, -127, -48, 68, -74, -67, 33, 62, 83, 42, -32, -46,
+ -70, -26, 115, 21, -66, 72, 52, -27, 44, 50, 50, 61, 28, -12, 3, -59,
+ 49, 3, -19, 39, 94, 16, 31, 6, 29, 3, -100, -1, -4, -60, 19, 7,
+ -29, -28, -38, -3, -47, -20, -21, -1, 5, -55, -12, -55, -39, 26, 47, -22,
+ -9, -41, -21, -19, -37, 0, 45, -56, 24, 75, -50, -9, 31, 28, 26, 13,
+ -3, -15, -27, 1, 1, -31, -10, 38, -1, 7, 43, 19, 21, 41, 33, 9,
+ -17, -3, -42, -76, -30, -8, -9, -1, 21, 22, 38, 32, 22, 0, -18, -32,
+ -58, -12, 5, -48, -13, 64, 29, -2, 2, 19, 43, 25, -19, -39, -69, -92,
+ -15, 23, 30, 30, 51, 37, 35, 37, 30, -27, -63, 5, -30, -56, -16, 26,
+ 52, 20, 14, 59, 27, -9, 22, -4, -20, -37, -17, -34, -34, -1, 35, 26,
+ 31, 5, -16, 4, 33, 22, 8, 5, -28, -41, -20, -10, -6, -2, -16, 12,
+ 31, -23, 7, -2, -39, -28, -13, 8, 5, 16, -4, -6, -18, -24, -27, -50,
+ -6, 5, 12, 0, -2, -14, -23, 5, -28, -10, 2, 28, 15, 2, 22, 27,
+ 41, 31, 2, 12, 31, 5, 12, -6, 15, 40, 34, 18, 26, 26, 12, 34,
+ 23, 34, 30, 22, 10, -26, -22, 1, 0, -1, 12, -4, -21, -5, -5, -20,
+ -31, -25, -24, -42, -44, -41, -41, -37, -29, -28, -29, -40, -17, -21, -38, -42,
+ -38, -40, -36, -13, -14, -8, -15, -7, -6, 5, 12, -1, -17, -1, 9, 2,
+ 16, 30, 27, 37, 36, 38, 36, 36, 19, 45, 45, 33, 26, 33, 28, 36,
+ 31, 17, 12, 22, 11, 11, 17, 5, -13, 6, 10, 2, -6, 2, 9, 15,
+ -6, -8, -23, -44, -3, -11, -35, -25, -35, -23, -21, 0, -11, -21, -17, 11,
+ -6, -11, -17, -33, -16, -16, -4, -7, -7, -9, -4, 1, 1, -3, 6, 7,
+ 4, -17, -11, -6, -4, 1, 3, 6, 4, 5, -4, 17, 7, 3, 9, -20,
+ 0, -7, -3, -5, 4, 9, 16, 2, 3, 8, 15, 15, 1, -3, 8, -1,
+ 5, 14, 7, 4, 8, -8, 2, -3, 5, 11, 5, 3, -4, 10, 17, 13,
+ -11, -5, 1, -3, 0, -6, -12, 2, -3, 13, -5, -25, -15, -7, 4, 1,
+ -8, -4, -12, -16, 3, 9, -6, 3, -21, -4, 4, -14, 1, -1, -2, 3,
+ -8, -5, 0, 7, -2, -3, -1, 3, -9, 5, -4, -17, -1, 9, 3, 7,
+ 1, -4, -3, 5, 2, -7, -9, 12, -6, -14, -16, 2, -1, 16, 2, 2,
+ 7, -6, -26, 3, -2, -4, -2, 10, 3, -7, 3, 8, 9, 5, 4, 1,
+ -5, -5, 11, 8, 7, 11, 12, -1, -5, -16, 13, 7, 2, 11, 4, -4,
+ 9, -8, -8, 14, 11, -8, 0, -1, -5, -2, -1, -10, -5, -9, -9, -16,
+ -12, -8, -16, 5, -10, -4, -11, -3, 1, 0, -3, -5, -13, -9, -2, -8,
+ 5, -9, -7, -2, 2, -11, -7, 13, 8, -3, 2, 7, -2, -1, 5, 0,
+ 11, 6, 13, 15, 1, -4, 9, 5, 3, 8, -3, -4, 16, 4, 11, 9,
+ 0, 8, 1, -6, -5, -18, 3, 7, -18, -4, 0, -3, -3, -6, -4, -5,
+ -5, -10, -2, -9, -5, -2, -4, -11, -2, 1, -5, -2, 11, -6, -9, 1,
+ 4, -6, -1, -5, 1, 2, 9, 5, 0, 4, 4, -2, 7, 0, -10, 5,
+ 2, -3, 0, -6, 7, -4, -3, 6, -1, -6, -1, -1, 2, -2, -6, -3,
+ 0, 8, -6, 4, -1, -5, -3, 3, 1, -5, -6, -2, -3, 5, 6, 0,
+ 7, -3, 3, -1, 0, -2, 9, 1, 1, -3, 4, 5, -5, 2, -2, 2,
+ -11, -2, -4, 11, 4, 5, 0, -5, -12, -6, -5, -5, 3, -2, -2, 2,
+ 2, 1, 0, -1, -8, -5, -5, -3, 2, -1, 3, -1, 3, 0, -1, 0,
+ -1, 1, 1, -4, -4, 2, -2, 1, -6, 1, 2, 4, 2, 2, -5, -1,
+ 6, -3, -1, -4, 11, 3, -9, -2, -6, -3, 2, 4, 2, 1, 2, 4,
+ 3, -6, -4, -3, -2, 0, 2, -2, 5, 2, -1, 3, -9, -3, -3, -4,
+ -4, -1, 0, -2, 7, 3, 1, 1, -2, -4, -2, -3, -2, -4, 2, 4,
+ -1, 2, 3, 0, 3, -1, 0, -2, -2, -3, 1, -1, -4, 5, -1, 5,
+ 0, -3, -2, -1, -4, 3, -1, -3, -2, -2, -1, 0, 0, 1, -1, 0,
+ -2, -2, 0, -3, -1, 0, 0, 1, 1, -2, -1, 1, -3, 1, 2, 0,
+ -1, 0, -1, 1, 5, -2, 1, -3, -3, -1, -3, 0, 1, 3, 2, -1,
+ -1, -2, -2, -1, 1, 30, -9, -44, 13, 26, -53, -41, 2, 76, 47, 40,
+ -52, -53, -5, 12, -33, 15, 62, 53, -27, -98, -26, -42, 52, 75, 43, -32,
+ -3, -83, -13, -36, 35, 39, 56, 25, -9, -122, -22, -3, 79, -6, 6, 25,
+ -20, -12, -40, -19, 15, 74, 37, -14, -33, 6, 25, 7, -10, -4, 42, 4,
+ -33, -87, -55, 29, 39, 21, -34, -27, 1, 26, 5, -22, -13, 10, 56, 0,
+ -26, -40, 30, 42, 23, -7, -23, 28, 21, 9, -37, -25, 11, 25, 8, -48,
+ -19, -15, 41, -2, -30, -28, 4, 30, -12, -23, -28, 17, 38, 3, -12, -8,
+ 17, 26, 9, -32, 0, 12, 49, -3, -29, -17, 2, 41, -17, -24, -17, 9,
+ 30, -23, -22, -21, 19, 17, -12, -35, -18, 12, 29, 2, -27, 7, 14, 42,
+ -11, -24, -3, 15, 40, -23, -24, -17, 21, 22, -10, -23, -10, 23, 13, -4,
+ -37, 0, 15, 19, -12, -40, -2, 13, 30, -16, -22, -3, 22, 22, -13, -16,
+ -7, 34, 9, -5, -34, -5, 29, 10, -3, -39, 3, 17, 14, -13, -25, 5,
+ 21, 12, -18, -22, -8, 31, 8, -5, -27, -9, 30, 1, -3, -30, 6, 27,
+ 4, -14, -31, 8, 25, 10, -14, -21, -3, 24, 4, -11, -17, -1, 30, -1,
+ -12, -26, 3, 32, 3, -13, -26, 5, 23, 3, -14, -17, 6, 22, 1, -17,
+ -16, 4, 25, 4, -18, -19, 4, 23, 5, -17, -14, 5, 21, 1, -20, -11,
+ 7, 23, 2, -19, -17, 8, 19, 6, -18, -15, 10, 14, 6, -26, -5, 11,
+ 15, 4, -27, -5, 4, 22, 1, -17, -12, 6, 15, 1, -16, -13, 20, 8,
+ 4, -28, -7, 17, 9, 10, -31, 3, 1, 13, 0, -18, 0, 6, 17, -10,
+ -14, -15, 21, 10, 3, -19, -14, 22, -4, 11, -27, 8, 9, 7, -2, -26,
+ 8, 2, 23, -13, -7, -13, 12, 11, -11, -2, -15, 27, -8, 2, -22, 0,
+ 18, 0, 6, -27, 10, -4, 19, -13, -7, 1, 2, 19, -26, 7, -17, 28,
+ -2, -8, -6, -11, 23, -9, 10, -24, 12, -2, 10, -8, -14, 13, -5, 25,
+ -33, 7, -11, 17, 8, -19, 9, -18, 26, -17, 6, -12, 8, 8, -5, 0,
+ -23, 20, -10, 25, -24, 2, 0, -2, 17, -30, 22, -16, 25, -15, -7, -2,
+ -4, 21, -15, 13, -25, 19, -11, 9, -8, -7, 19, -15, 20, -34, 17, -9,
+ 15, 0, -15, 11, -17, 24, -24, 16, -15, 15, 0, -11, 6, -21, 30, -18,
+ 18, -22, 6, 3, -6, 10, -20, 23, -17, 20, -23, 7, -3, 2, 16, -24,
+ 18, -26, 27, -15, 5, -2, -5, 19, -21, 12, -22, 22, -9, 9, -11, -5,
+ 11, -13, 21, -27, 22, -17, 13, -5, -13, 14, -14, 28, -24, 9, -16, 12,
+ 3, -7, 5, -14, 22, -20, 14, -21, 14, 3, -2, 6, -26, 20, -17, 23,
+ -17, 3, 0, -2, 11, -23, 14, -14, 26, -14, 0, -10, -3, 18, -14, 15,
+ -24, 19, -9, 4, -8, -9, 18, -6, 15, -29, 11, -10, 16, -1, -11, 9,
+ -13, 23, -23, 8, -13, 12, 10, -11, 0, -20, 22, -7, 12, -19, 4, 4,
+ 1, 4, -23, 18, -10, 22, -17, -7, 0, -1, 23, -20, 6, -18, 18, 0,
+ -3, -8, -5, 20, -8, 6, -27, 14, 2, 11, -5, -20, 13, -10, 24, -22,
+ 3, -5, 11, 8, -20, 1, -12, 28, -7, 0, -19, 2, 15, -5, 6, -25,
+ 20, -4, 13, -19, -10, 10, 5, 17, -27, 1, -10, 22, -2, -10, -2, -7,
+ 26, -18, 4, -24, 18, 10, 1, -8, -23, 16, 2, 15, -22, -1, 3, 10,
+ 5, -27, 9, -8, 35, -19, -3, -18, 7, 19, -7, -3, -16, 14, 6, -5,
+ -9, -12, 23, -5, 11, -33, 19, -10, 23, -22, 3, -5, 14, -2, -8, -8,
+ 7, 7, 2, -14, 0, -2, 17, -14, 3, -17, 20, -5, 7, -19, 3, 3,
+ 10, -5, -9, -4, 6, 6, -2, -10, 1, 2, 12, -13, 0, -11, 18, -3,
+ 3, -16, 2, 4, 7, -5, -6, 0, 6, 1, -6, -6, 4, 6, 5, -11,
+ -2, -4, 12, -6, 1, -9, 9, 0, 1, -11, 0, 6, 5, -2, -11, 1,
+ 2, 7, -5, -7, 3, 1, 8, -13, 0, -6, 15, -3, -2, -11, 1, 9,
+ 1, -2, -12, 6, 2, 5, -9, -5, 3, 6, 5, -12, -3, -3, 12, 0,
+ -5, -7, 0, 8, -2, -2, -9, 7, 3, 5, -11, -4, 0, 9, 2, -7,
+ -6, 0, 7, 1, -6, -3, 1, 8, -4, -5, -7, 7, 4, 4, -11, -1,
+ -2, 10, -5, -1, -7, 8, 1, 1, -12, 1, 4, 7, -4, -8, -4, 8,
+ 0, 3, -16, 11, -7, 1, 0, 0, -1, -1, -4, 1, -1, -3, -13, -8,
+ -14, -3, -2, -2, 1, 8, 5, 7, -21, -13, -2, -6, -8, -22, -6, 5,
+ 11, 34, 41, 33, 13, 28, 33, 48, 35, 21, -3, -26, -18, -10, 3, 7,
+ 22, 21, 63, 40, 41, 43, 4, -8, -43, -63, -77, -77, -59, -18, 3, 2,
+ -21, -46, -74, -90, -108, -101, -94, -89, -84, -85, -77, -59, -50, -33, -7, 18,
+ 37, 47, 64, 101, 127, 125, 127, 126, 126, 126, 122, 100, 87, 62, 37, 28,
+ 27, 25, 27, 34, 25, -4, -45, -85, -123, -128, -126, -128, -127, -123, -92, -73,
+ -55, -45, -37, -33, -32, -33, -43, -53, -55, -43, -20, 3, 20, 34, 42, 49,
+ 55, 63, 74, 84, 93, 101, 107, 112, 117, 109, 92, 63, 33, 8, -13, -25,
+ -29, -30, -27, -27, -32, -46, -63, -82, -98, -109, -116, -121, -118, -104, -80, -49,
+ -12, 21, 45, 58, 64, 66, 66, 61, 51, 44, 37, 32, 32, 33, 33, 28,
+ 23, 15, 8, 3, 2, 9, 16, 20, 24, 23, 14, -1, -20, -37, -48, -53,
+ -52, -47, -38, -26, -13, -5, -1, -4, -10, -22, -34, -43, -48, -46, -34, -16,
+ 5, 25, 45, 65, 78, 84, 83, 71, 55, 39, 24, 9, -3, -12, -23, -34,
+ -45, -57, -65, -71, -71, -63, -49, -34, -21, -11, -2, 2, 8, 11, 12, 14,
+ 14, 20, 28, 38, 50, 58, 63, 61, 56, 46, 33, 17, -1, -19, -34, -45,
+ -48, -44, -32, -19, -5, 5, 7, 4, -2, -7, -11, -15, -18, -21, -23, -26,
+ -28, -30, -31, -29, -26, -20, -12, -1, 11, 21, 32, 42, 51, 55, 55, 52,
+ 46, 41, 37, 32, 30, 28, 27, 24, 19, 12, -1, -21, -45, -67, -89, -103,
+ -107, -101, -90, -70, -51, -33, -18, -2, 11, 23, 33, 39, 44, 49, 52, 57,
+ 59, 59, 56, 52, 48, 41, 35, 28, 20, 15, 11, 4, 0, -5, -11, -18,
+ -25, -34, -42, -47, -48, -46, -40, -33, -27, -24, -21, -24, -32, -42, -51, -56,
+ -58, -56, -47, -35, -18, 2, 24, 48, 70, 88, 99, 104, 102, 97, 89, 79,
+ 69, 59, 49, 37, 27, 14, 0, -14, -29, -44, -58, -71, -81, -87, -88, -88,
+ -85, -81, -77, -72, -63, -51, -37, -21, -5, 12, 29, 43, 53, 59, 61, 57,
+ 48, 36, 24, 13, 8, 8, 15, 25, 38, 48, 54, 54, 50, 43, 33, 22,
+ 11, 3, -6, -15, -25, -35, -46, -54, -61, -65, -68, -69, -69, -68, -64, -59,
+ -52, -43, -32, -20, -7, 6, 19, 31, 42, 51, 58, 62, 64, 62, 58, 52,
+ 44, 35, 26, 17, 9, 1, -5, -10, -15, -18, -19, -20, -19, -18, -16, -15,
+ -14, -14, -15, -16, -17, -18, -19, -19, -19, -19, -18, -16, -14, -11, -9, -6,
+ -3, 0, 3, 6, 10, 14, 18, 22, 27, 32, 35, 37, 37, 35, 30, 23,
+ 14, 4, -6, -15, -24, -31, -36, -39, -40, -39, -37, -32, -26, -19, -10, -1,
+ 8, 17, 24, 29, 32, 33, 32, 29, 25, 20, 15, 11, 7, 3, -1, -5,
+ -9, -14, -19, -24, -28, -31, -32, -31, -27, -23, -16, -10, -3, 2, 7, 10,
+ 12, 13, 13, 13, 12, 10, 8, 7, 5, 5, 5, 5, 6, 8, 10, 13,
+ 17, 20, 23, 25, 26, 25, 21, 16, 9, 1, -7, -16, -24, -31, -37, -42,
+ -47, -49, -51, -52, -51, -48, -43, -37, -30, -20, -7, 6, 19, 0, -4, 10,
+ 10, 11, -15, 4, -1, 3, -11, 11, 2, -12, 3, 18, -10, -62, 89, -16,
+ -95, 118, -128, 122, -128, 112, -100, 109, -121, 120, -104, 58, 10, -88, 127, -102,
+ 6, 98, -126, 35, 89, -111, -7, 112, -53, -94, 92, 64, -106, -53, 109, 52,
+ -100, -75, 86, 95, -45, -119, -12, 111, 74, -58, -118, -27, 97, 100, -4, -107,
+ -95, 17, 109, 92, -4, -99, -109, -26, 78, 115, 66, -27, -104, -109, -41, 55,
+ 112, 98, 32, -53, -109, -105, -44, 41, 102, 109, 67, -4, -74, -112, -102, -47,
+ 27, 88, 112, 93, 45, -19, -78, -110, -105, -65, -4, 59, 101, 110, 87, 43,
+ -13, -67, -103, -111, -89, -44, 13, 65, 100, 109, 93, 59, 14, -36, -78, -104,
+ -108, -90, -53, -6, 43, 83, 104, 106, 88, 57, 17, -27, -66, -95, -108, -102,
+ -80, -44, -2, 41, 77, 99, 106, 98, 77, 46, 10, -29, -64, -91, -105, -105,
+ -91, -64, -29, 10, 48, 78, 98, 105, 100, 84, 59, 30, -3, -36, -65, -88,
+ -101, -105, -99, -83, -60, -32, -1, 30, 58, 80, 96, 103, 102, 94, 80, 62,
+ 40, 16, -10, -35, -58, -78, -92, -101, -104, -100, -91, -77, -58, -36, -13, 12,
+ 36, 57, 75, 89, 98, 102, 102, 97, 88, 76, 61, 44, 25, 5, -15, -35,
+ -54, -70, -84, -94, -101, -104, -103, -98, -89, -77, -63, -46, -27, -8, 12, 31,
+ 49, 65, 79, 90, 97, 102, 104, 102, 97, 90, 81, 70, 57, 42, 27, 10,
+ -7, -24, -40, -56, -70, -81, -91, -99, -103, -105, -105, -101, -95, -87, -76, -63,
+ -49, -34, -18, -1, 16, 32, 48, 62, 74, 85, 93, 100, 104, 105, 105, 102,
+ 97, 90, 82, 72, 61, 48, 35, 21, 6, -9, -24, -38, -52, -65, -76, -86,
+ -94, -101, -105, -108, -108, -106, -102, -96, -87, -78, -66, -54, -40, -26, -11, 4,
+ 19, 34, 48, 61, 73, 83, 92, 99, 104, 107, 108, 108, 105, 101, 96, 89,
+ 80, 70, 60, 48, 36, 22, 9, -5, -19, -33, -46, -58, -69, -80, -89, -96,
+ -102, -107, -109, -110, -110, -107, -102, -97, -89, -80, -70, -59, -47, -33, -20, -6,
+ 7, 19, 30, 41, 50, 58, 65, 71, 75, 78, 79, 80, 79, 77, 74, 70,
+ 65, 60, 54, 48, 42, 36, 29, 22, 16, 10, 4, -2, -7, -12, -16, -19,
+ -22, -24, -26, -27, -27, -27, -26, -25, -23, -22, -19, -17, -14, -12, -10, 0,
+ -5, -2, -5, 2, -29, 22, 0, -27, 67, -59, 45, -13, -37, 28, 65, -4,
+ 6, 60, 5, 58, 44, 60, 27, 43, 96, 71, 81, 48, 96, 70, 23, 90,
+ 66, 80, 88, 40, 20, 61, 64, 12, 36, 24, 4, 7, 5, -27, -38, -26,
+ -33, -49, -50, -70, -69, -93, -92, -94, -104, -104, -101, -110, -107, -111, -111, -126,
+ -87, -119, -100, -94, -112, -93, -93, -80, -81, -76, -58, -56, -70, -30, -21, -42,
+ -13, -3, 2, 8, 20, 28, 41, 45, 59, 62, 69, 84, 85, 90, 103, 109,
+ 111, 118, 121, 121, 123, 121, 122, 121, 122, 121, 122, 121, 121, 120, 121, 120,
+ 121, 120, 121, 120, 120, 119, 120, 119, 120, 118, 105, 106, 110, 83, 89, 92,
+ 75, 67, 61, 57, 47, 40, 33, 24, 17, 10, 3, -2, -10, -20, -31, -31,
+ -37, -49, -50, -63, -66, -69, -74, -79, -91, -89, -92, -95, -102, -106, -104, -107,
+ -113, -113, -110, -113, -116, -114, -115, -114, -115, -114, -113, -114, -113, -114, -113, -112,
+ -113, -109, -105, -111, -106, -107, -103, -100, -103, -99, -97, -98, -99, -92, -92, -93,
+ -92, -92, -90, -88, -90, -88, -86, -89, -85, -85, -87, -85, -85, -82, -83, -82,
+ -80, -78, -79, -76, -74, -73, -73, -69, -68, -66, -64, -65, -62, -58, -56, -56,
+ -52, -50, -47, -43, -42, -39, -35, -33, -31, -27, -23, -21, -16, -16, -8, -7,
+ -3, 1, 0, 10, 15, 15, 19, 26, 29, 30, 38, 41, 42, 47, 54, 54,
+ 57, 63, 68, 69, 72, 77, 78, 80, 85, 84, 86, 87, 86, 87, 86, 85,
+ 86, 85, 84, 85, 84, 83, 84, 83, 82, 82, 83, 82, 81, 82, 81, 80,
+ 81, 80, 79, 80, 79, 79, 78, 79, 78, 78, 77, 74, 70, 66, 64, 61,
+ 55, 52, 49, 45, 40, 35, 32, 29, 24, 19, 15, 12, 8, 4, 0, -4,
+ -8, -11, -15, -17, -20, -25, -26, -29, -32, -34, -37, -39, -41, -43, -45, -46,
+ -48, -49, -50, -50, -52, -52, -53, -52, -53, -54, -53, -53, -52, -52, -51, -50,
+ -50, -49, -48, -48, -46, -45, -44, -42, -41, -40, -39, -37, -35, -34, -32, -30,
+ -28, -27, -24, -23, -22, -20, -19, -17, -15, -14, -13, -12, -10, -9, -8, -8,
+ -6, -6, -5, -4, -4, -3, -3, -2, -2, -1, -2, -1, -2, -1, -1, 0,
+ -1, 0, 1, 6, -11, 19, -25, 24, -15, 11, -6, 1, 9, -6, -3, 11,
+ -18, 28, -23, 8, 6, -2, -1, 0, -5, 18, -23, 24, -28, 27, -12, -1,
+ -2, 6, 4, -14, 19, -29, 42, -40, 22, -6, -3, 14, -16, 4, 8, -9,
+ 13, -22, 17, 5, -24, 37, -34, 20, -4, -11, 19, -20, 21, -16, 1, 17,
+ -17, 5, -9, 25, -31, 31, -40, 32, -11, -7, 4, -4, 13, -23, 29, -40,
+ 51, -49, 20, 3, -20, 38, -47, 34, -21, 14, -9, 4, -13, 20, -29, 37,
+ -57, 59, -48, 23, -5, -7, 5, -6, -5, 13, -17, 9, -4, -12, 22, -19,
+ -8, 10, -5, -7, 8, -18, 19, -13, 5, -12, 6, -10, 18, -40, 66, -91,
+ 82, -56, 17, 19, -51, 56, -45, 30, -19, 5, -6, 7, -9, -4, -2, -5,
+ 13, -19, 1, 20, -28, 13, -6, 0, -17, 33, -48, 38, -16, -20, 53, -75,
+ 75, -61, 30, -12, -9, 2, 5, -9, -7, 15, -17, 9, 4, -46, 70, -85,
+ 86, -67, 29, 18, -60, 76, -70, 29, -8, -1, 1, 14, -58, 93, -118, 127,
+ -125, 85, -36, -2, 17, -39, 46, -61, 70, -99, 122, -120, 56, 15, -85, 116,
+ -101, 30, 43, -108, 127, -122, 72, -38, -3, 20, -31, 29, -37, 42, -50, 63,
+ -72, 40, -7, -46, 66, -82, 53, -25, 1, 1, -1, -3, 3, -24, 24, -34,
+ 27, -24, 36, -49, 37, -38, 35, -42, 13, -4, -14, 14, -29, 42, -58, 58,
+ -60, 41, -39, 27, -35, 27, -32, 25, -37, 43, -50, 32, -20, -4, 4, -14,
+ 16, -43, 66, -93, 79, -58, 27, -11, -21, 34, -40, 24, -7, -25, 31, -29,
+ 19, -18, -2, 1, -6, 4, -31, 47, -63, 62, -64, 32, 2, -29, 23, -21,
+ 19, -41, 59, -76, 62, -52, 26, -11, -1, -10, 6, -10, -7, 17, -42, 34,
+ -12, -34, 73, -106, 92, -61, 26, -24, 8, -7, -2, 3, -24, 31, -44, 27,
+ -9, -22, 38, -43, 15, -4, -3, -2, -12, 5, 1, -7, 7, -25, 17, -17,
+ 4, -15, 27, -40, 34, -18, 6, -13, 12, -3, -9, -6, 8, -18, 18, -36,
+ 54, -55, 30, -25, 26, -41, 38, -49, 48, -38, 8, 16, -40, 47, -52, 34,
+ -12, -4, 2, -13, 0, 1, 6, -11, 19, -25, 24, -15, 11, -6, 1, 9,
+ -6, -3, 11, -18, 28, -23, 8, 6, -2, -1, 0, -5, 18, -23, 24, -28,
+ 27, -12, -1, -2, 6, 4, -14, 19, -29, 42, -40, 22, -6, -3, 14, -16,
+ 4, 8, -9, 13, -22, 17, 5, -24, 37, -34, 20, -4, -11, 19, -20, 21,
+ -16, 1, 17, -17, 5, -9, 25, -31, 31, -40, 32, -11, -7, 4, -4, 13,
+ -23, 29, -40, 51, -49, 20, 3, -20, 38, -47, 34, -21, 14, -9, 4, -13,
+ 20, -29, 37, -57, 59, -48, 23, -5, -7, 5, -6, -5, 13, -17, 9, -4,
+ -12, 22, -19, -8, 10, -5, -7, 8, -18, 19, -13, 5, -12, 6, -10, 18,
+ -40, 66, -91, 82, -56, 17, 19, -51, 56, -45, 30, -19, 5, -6, 7, -9,
+ -4, -2, -5, 13, -19, 1, 20, -28, 13, -6, 0, -17, 33, -48, 38, -16,
+ -20, 53, -75, 75, -61, 30, -12, -9, 2, 5, -9, -7, 15, -17, 9, 4,
+ -46, 70, -85, 86, -67, 29, 18, -60, 76, -70, 29, -8, -1, 1, 14, -58,
+ 93, -118, 127, -125, 85, -36, -2, 17, -39, 46, -61, 70, -99, 122, -120, 56,
+ 15, -85, 116, -101, 30, 43, -108, 127, -122, 72, -38, -3, 20, -31, 29, -37,
+ 42, -50, 63, -72, 40, -7, -46, 66, -82, 53, -25, 1, 1, -1, -3, 3,
+ -24, 24, -34, 27, -24, 36, -49, 37, -38, 35, -42, 13, -4, -14, 14, -29,
+ 42, -58, 58, -60, 41, -39, 27, -35, 27, -32, 25, -37, 43, -50, 32, -20,
+ -4, 4, -14, 16, -43, 66, -93, 79, -58, 27, -11, -21, 34, -40, 24, -7,
+ -25, 31, -29, 19, -18, -2, 1, -6, 4, -31, 47, -63, 62, -64, 32, 2,
+ -29, 23, -21, 19, -41, 59, -76, 62, -52, 26, -11, -1, -10, 6, -10, -7,
+ 17, -42, 34, -12, -34, 73, -106, 92, -61, 26, -24, 8, -7, -2, 3, -24,
+ 31, -44, 27, -9, -22, 38, -43, 15, -4, -3, -2, -12, 5, 1, -7, 7,
+ -25, 17, -17, 4, -15, 27, -40, 34, -18, 6, -13, 12, -3, -9, -6, 8,
+ -18, 18, -36, 54, -55, 30, -25, 26, -41, 38, -49, 48, -38, 8, 16, -40,
+ 47, -52, 34, -12, -4, 2, -13, -1, -9, -21, -32, -43, -55, -58, -40, -8,
+ 15, 29, 38, 44, 59, 63, 51, 20, -20, -47, -61, -58, -48, -42, -43, -35,
+ -15, 15, 41, 55, 61, 62, 70, 67, 45, 11, -31, -62, -80, -78, -71, -62,
+ -54, -39, -15, 18, 50, 68, 79, 83, 92, 88, 57, 16, -31, -71, -94, -95,
+ -90, -83, -71, -55, -28, 7, 49, 77, 93, 100, 109, 107, 78, 36, -20, -71,
+ -99, -104, -100, -92, -83, -69, -43, -5, 42, 79, 100, 108, 114, 112, 90, 51,
+ -9, -65, -100, -110, -105, -95, -87, -76, -52, -11, 35, 75, 100, 107, 111, 106,
+ 90, 52, -4, -60, -97, -109, -99, -87, -80, -65, -35, 5, 43, 75, 91, 95,
+ 93, 87, 71, 31, -19, -64, -93, -99, -88, -76, -66, -44, -9, 28, 59, 79,
+ 84, 80, 71, 59, 35, -5, -45, -76, -96, -95, -77, -59, -39, -9, 28, 61,
+ 86, 98, 93, 74, 52, 28, -6, -43, -72, -94, -108, -99, -77, -52, -20, 19,
+ 56, 84, 106, 115, 106, 79, 45, 3, -40, -74, -93, -108, -112, -100, -79, -46,
+ -1, 45, 78, 100, 113, 118, 108, 81, 39, -19, -67, -93, -103, -108, -104, -94,
+ -74, -32, 19, 61, 88, 102, 108, 109, 100, 73, 21, -44, -87, -102, -104, -97,
+ -90, -78, -49, 0, 46, 78, 90, 92, 89, 87, 77, 43, -15, -72, -101, -104,
+ -93, -79, -69, -47, -3, 47, 84, 96, 89, 74, 65, 58, 37, -7, -61, -99,
+ -110, -101, -82, -62, -38, 2, 49, 92, 112, 106, 82, 59, 41, 18, -19, -61,
+ -95, -111, -110, -98, -74, -39, 6, 54, 99, 122, 123, 104, 79, 50, 12, -32,
+ -72, -100, -111, -110, -106, -90, -54, -4, 49, 99, 123, 126, 113, 95, 69, 24,
+ -27, -72, -102, -114, -109, -104, -94, -64, -16, 36, 87, 116, 121, 111, 97, 76,
+ 36, -15, -61, -94, -110, -108, -98, -86, -60, -19, 29, 77, 104, 109, 99, 86,
+ 67, 35, -7, -47, -82, -98, -101, -92, -77, -48, -14, 25, 67, 92, 95, 83,
+ 66, 45, 18, -9, -37, -62, -77, -81, -78, -54, -16, 0, 0, 0, 12, -10,
+ 16, -14, -18, 17, -31, -2, 3, -19, -8, 17, 28, 37, 31, -1, -25, -16,
+ -47, -13, -43, -22, 6, 34, 41, 49, 41, 27, 6, -33, -62, -54, -59, -32,
+ -13, 29, 53, 73, 60, 54, 16, -19, -58, -77, -89, -42, -46, 17, 55, 78,
+ 86, 81, 33, -3, -35, -84, -110, -75, -70, 0, 39, 78, 92, 105, 70, 13,
+ -15, -82, -107, -103, -84, -41, 20, 81, 85, 127, 86, 39, -4, -63, -103, -99,
+ -107, -69, 2, 68, 82, 127, 84, 58, 28, -44, -88, -104, -108, -83, -13, 29,
+ 69, 116, 87, 77, 40, -16, -65, -89, -104, -89, -40, -1, 47, 96, 90, 85,
+ 52, 9, -38, -62, -96, -95, -62, -22, 21, 73, 78, 86, 65, 35, -15, -41,
+ -80, -92, -69, -48, 1, 43, 65, 80, 73, 49, 8, -23, -59, -75, -74, -60,
+ -22, 17, 49, 69, 65, 60, 25, -1, -36, -59, -70, -61, -40, -9, 30, 52,
+ 57, 63, 37, 17, -12, -41, -61, -57, -50, -30, 9, 30, 49, 60, 47, 28,
+ 6, -20, -49, -51, -53, -42, -11, 13, 34, 53, 50, 34, 18, -3, -35, -39,
+ -52, -49, -23, 0, 18, 41, 47, 36, 31, 10, -21, -28, -43, -49, -31, -13,
+ 2, 28, 39, 35, 38, 19, -7, -18, -33, -42, -36, -26, -12, 19, 30, 34,
+ 36, 22, 6, -5, -25, -38, -36, -29, -17, 8, 19, 26, 35, 28, 12, 3,
+ -17, -30, -29, -29, -22, -3, 9, 19, 33, 26, 14, 8, -9, -18, -22, -28,
+ -25, -9, 3, 15, 22, 20, 18, 12, 1, -11, -22, -24, -21, -13, -3, 8,
+ 11, 20, 21, 12, 5, -6, -19, -16, -17, -17, -7, 3, 8, 20, 17, 7,
+ 7, -2, -11, -13, -16, -17, -5, 2, 5, 12, 13, 8, 6, 3, -9, -11,
+ -9, -14, -5, 1, -3, 6, 11, 6, 7, 2, -6, -4, -4, -10, -6, -3,
+ -4, 5, 8, 2, 5, 4, -2, 0, -3, -9, -4, -3, -3, 2, 3, 0,
+ 6, 4, 0, -1, -2, -2, 0, -4, 8, -1, 9, 14, 53, 57, 33, -4,
+ -20, -14, -31, -71, -112, -43, 30, -22, -102, -74, 38, 90, 35, -22, 20, 99,
+ 96, 22, -42, -5, 48, 16, -74, -97, -51, 10, -21, -80, -68, 24, 77, 43,
+ -9, 20, 90, 99, 32, -28, -8, 41, 18, -63, -97, -55, -2, -18, -74, -67,
+ 11, 69, 44, -1, 17, 83, 98, 40, -20, -8, 35, 20, -55, -95, -60, -8,
+ -19, -69, -68, 3, 61, 45, 1, 15, 78, 99, 46, -14, -8, 33, 22, -48,
+ -93, -62, -13, -19, -67, -70, -5, 56, 44, 3, 13, 73, 99, 51, -10, -7,
+ 32, 25, -42, -91, -66, -15, -18, -65, -73, -11, 51, 44, 3, 9, 69, 100,
+ 55, -6, -8, 32, 30, -36, -89, -68, -17, -17, -64, -77, -18, 47, 45, 3,
+ 5, 64, 100, 60, -2, -8, 32, 34, -30, -87, -70, -19, -14, -63, -80, -25,
+ 43, 45, 3, 1, 59, 100, 66, 1, -9, 31, 39, -23, -84, -74, -20, -12,
+ -59, -84, -32, 38, 46, 3, -3, 53, 101, 71, 6, -10, 31, 43, -14, -81,
+ -76, -24, -9, -57, -86, -41, 33, 46, 5, -9, 47, 99, 77, 9, -11, 28,
+ 49, -6, -76, -79, -25, -9, -50, -91, -46, 9, -41, 2, 6, -33, 33, -4,
+ -1, 34, -93, 60, -49, 68, -21, 41, -38, -38, 27, -87, 127, -34, 38, -3,
+ -34, -2, -85, 79, -24, 4, 75, -23, 11, -70, 1, -6, -6, 63, -48, 76,
+ -71, 2, -7, -15, 46, -32, 48, -25, -5, 10, -31, 18, -23, 5, 6, 17,
+ 11, 3, 24, -46, -21, -1, -5, 31, 1, 36, -23, -11, -4, -29, 14, -5,
+ 29, 9, -2, -2, -20, -2, -15, 13, 7, 4, 15, -11, 4, -13, -1, 1,
+ -13, 15, -6, 9, 9, -2, -4, -11, -2, -11, 7, 12, 9, 5, -6, -6,
+ -16, -2, 3, 6, 13, 1, 7, -14, -3, -11, -1, 8, 0, 18, -3, -3,
+ -6, -13, 0, 4, 2, 9, 2, 2, -6, -4, -1, -8, 2, 4, 2, 7,
+ -4, 2, 1, -7, -3, -2, 0, 2, 8, -2, 2, -1, -7, -3, -1, 3,
+ 4, 3, 3, -3, -4, -4, 0, 2, 1, 5, -1, -2, 1, -4, -1, 1,
+ 0, 2, 8, -22, 25, 30, 6, -19, -62, -19, 10, 83, 57, -67, -88, -52,
+ 63, 127, 42, -63, -121, -70, 82, 111, 46, -43, -114, -35, 45, 73, 39, -19,
+ -54, -41, 9, 49, 24, -16, -14, -9, -6, 10, 8, -22, 25, 30, 6, -19,
+ -62, -19, 10, 83, 57, -67, -88, -52, 63, 127, 42, -63, -121, -70, 82, 111,
+ 46, -43, -114, -35, 45, 73, 39, -19, -54, -41, 9, 49, 24, -16, -14, -9,
+ -6, 10, 94, 127, 124, 127, 127, 114, 73, 35, -11, -52, -98, -118, -125, -128,
+ -128, -128, -128, -128, -128, -128, -124, -86, -47, 0, 40, 87, 106, 116, 119, 125,
+ 37, -7, 122, 72, -57, -71, -88, -28, 48, 127, 36, -30, -53, -126, -16, 71,
+ 92, 51, -1, -83, -128, 14, 43, 83, 86, -14, -106, -87, -7, 28, 1, 122,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0
+};
+
+const EAS_U32 eas_sampleLengths[] =
+{
+ 9922, 9338, 6793, 5242, 3057, 2818, 2806, 1835,
+ 1603, 1262, 1227, 1168, 1132, 1132, 994, 907,
+ 817, 801, 583, 418, 402, 387, 387, 357,
+ 347, 212, 167, 40, 40, 32, 30
+};
+
+const EAS_U32 eas_sampleOffsets[] =
+{
+ 0x00000000, 0x000026c2, 0x00004b3c, 0x000065c5, 0x00007a3f, 0x00008630, 0x00009132, 0x00009c28,
+ 0x0000a353, 0x0000a996, 0x0000ae84, 0x0000b34f, 0x0000b7df, 0x0000bc4b, 0x0000c0b7, 0x0000c499,
+ 0x0000c824, 0x0000cb55, 0x0000ce76, 0x0000d0bd, 0x0000d25f, 0x0000d3f1, 0x0000d574, 0x0000d6f7,
+ 0x0000d85c, 0x0000d9b7, 0x0000da8b, 0x0000db32, 0x0000db5a, 0x0000db82, 0x0000dba2
+};
+
+/*----------------------------------------------------------------------------
+ * S_EAS (hybrid)
+ *----------------------------------------------------------------------------
+*/
+const S_EAS easSoundLib =
+{
+ 0x01534145,
+ 0x00105622,
+ eas_banks,
+ eas_programs,
+ eas_regions,
+ eas_articulations,
+ eas_sampleLengths,
+ eas_sampleOffsets,
+ eas_samples,
+ eas_fmRegions,
+ 1,
+ 1,
+ 61,
+ 53,
+ 31,
+ 128
+}; /* end S_EAS */
+
+/*----------------------------------------------------------------------------
+ * Statistics
+ *
+ * Number of banks: 1
+ * Number of programs: 1
+ * Number of regions: 61
+ * Number of articulations: 53
+ * Number of samples: 31
+ * Size of sample pool: 56276
+ *----------------------------------------------------------------------------
+*/
+/* end C:\Sonic\Trunk\EASLib\WTLibrary\hybrid_22khz_mcu.c */
diff --git a/arm-wt-22k/host_src/eas.h b/arm-wt-22k/host_src/eas.h
index 524601e..c64af49 100644
--- a/arm-wt-22k/host_src/eas.h
+++ b/arm-wt-22k/host_src/eas.h
@@ -1,16 +1,16 @@
/*----------------------------------------------------------------------------
*
- * File:
+ * File:
* eas.h
*
* Contents and purpose:
* The public interface header for the EAS synthesizer.
*
* This header only contains declarations that are specific
- * to this implementation.
+ * to this implementation.
*
* DO NOT MODIFY THIS FILE!
- *
+ *
* Copyright Sonic Network Inc. 2005, 2006
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -48,59 +48,59 @@ extern "C" {
typedef struct
{
- EAS_U32 libVersion;
- EAS_BOOL checkedVersion;
- EAS_I32 maxVoices;
- EAS_I32 numChannels;
- EAS_I32 sampleRate;
- EAS_I32 mixBufferSize;
- EAS_BOOL filterEnabled;
- EAS_U32 buildTimeStamp;
- EAS_CHAR *buildGUID;
+ EAS_U32 libVersion;
+ EAS_BOOL checkedVersion;
+ EAS_I32 maxVoices;
+ EAS_I32 numChannels;
+ EAS_I32 sampleRate;
+ EAS_I32 mixBufferSize;
+ EAS_BOOL filterEnabled;
+ EAS_U32 buildTimeStamp;
+ EAS_CHAR *buildGUID;
} S_EAS_LIB_CONFIG;
/* enumerated effects module numbers for configuration */
typedef enum
{
- EAS_MODULE_ENHANCER = 0,
- EAS_MODULE_COMPRESSOR,
- EAS_MODULE_REVERB,
- EAS_MODULE_CHORUS,
- EAS_MODULE_WIDENER,
- EAS_MODULE_GRAPHIC_EQ,
- EAS_MODULE_WOW,
- EAS_MODULE_MAXIMIZER,
- EAS_MODULE_TONECONTROLEQ,
- NUM_EFFECTS_MODULES
+ EAS_MODULE_ENHANCER = 0,
+ EAS_MODULE_COMPRESSOR,
+ EAS_MODULE_REVERB,
+ EAS_MODULE_CHORUS,
+ EAS_MODULE_WIDENER,
+ EAS_MODULE_GRAPHIC_EQ,
+ EAS_MODULE_WOW,
+ EAS_MODULE_MAXIMIZER,
+ EAS_MODULE_TONECONTROLEQ,
+ NUM_EFFECTS_MODULES
} E_FX_MODULES;
/* enumerated optional module numbers for configuration */
typedef enum
{
- EAS_MODULE_MMAPI_TONE_CONTROL = 0,
- EAS_MODULE_METRICS
+ EAS_MODULE_MMAPI_TONE_CONTROL = 0,
+ EAS_MODULE_METRICS
} E_OPT_MODULES;
-#define NUM_OPTIONAL_MODULES 2
+#define NUM_OPTIONAL_MODULES 2
/* enumerated audio decoders for configuration */
typedef enum
{
- EAS_DECODER_PCM = 0,
- EAS_DECODER_SMAF_ADPCM,
- EAS_DECODER_IMA_ADPCM,
- EAS_DECODER_7BIT_SMAF_ADPCM,
- EAS_DECODER_NOT_SUPPORTED
+ EAS_DECODER_PCM = 0,
+ EAS_DECODER_SMAF_ADPCM,
+ EAS_DECODER_IMA_ADPCM,
+ EAS_DECODER_7BIT_SMAF_ADPCM,
+ EAS_DECODER_NOT_SUPPORTED
} E_DECODER_MODULES;
-#define NUM_DECODER_MODULES 4
+#define NUM_DECODER_MODULES 4
/* defines for EAS_PEOpenStream flags parameter */
-#define PCM_FLAGS_STEREO 0x00000100 /* stream is stereo */
-#define PCM_FLAGS_8_BIT 0x00000001 /* 8-bit format */
-#define PCM_FLAGS_UNSIGNED 0x00000010 /* unsigned format */
-#define PCM_FLAGS_STREAMING 0x80000000 /* streaming mode */
+#define PCM_FLAGS_STEREO 0x00000100 /* stream is stereo */
+#define PCM_FLAGS_8_BIT 0x00000001 /* 8-bit format */
+#define PCM_FLAGS_UNSIGNED 0x00000010 /* unsigned format */
+#define PCM_FLAGS_STREAMING 0x80000000 /* streaming mode */
/* maximum volume setting */
-#define EAS_MAX_VOLUME 100
+#define EAS_MAX_VOLUME 100
/*----------------------------------------------------------------------------
* EAS_Init()
@@ -109,8 +109,8 @@ typedef enum
* Initialize the synthesizer library
*
* Inputs:
- * polyphony - number of voices to play (dynamic memory model only)
- * ppLibData - pointer to data handle variable for this instance
+ * polyphony - number of voices to play (dynamic memory model only)
+ * ppLibData - pointer to data handle variable for this instance
*
* Outputs:
*
@@ -141,7 +141,7 @@ EAS_PUBLIC const S_EAS_LIB_CONFIG *EAS_Config (void);
* synthesizer (dynamic memory model only)
*
* Inputs:
- * pEASData - handle to data for this instance
+ * pEASData - handle to data for this instance
*
* Outputs:
*
@@ -157,12 +157,12 @@ EAS_PUBLIC EAS_RESULT EAS_Shutdown (EAS_DATA_HANDLE pEASData);
*
* Inputs:
* pEASData - buffer for internal EAS data
- * pOut - output buffer pointer
- * nNumRequested - requested num samples to generate
- * pnNumGenerated - actual number of samples generated
+ * pOut - output buffer pointer
+ * nNumRequested - requested num samples to generate
+ * pnNumGenerated - actual number of samples generated
*
* Outputs:
- * EAS_SUCCESS if PCM data was successfully rendered
+ * EAS_SUCCESS if PCM data was successfully rendered
*
*----------------------------------------------------------------------------
*/
@@ -171,21 +171,21 @@ EAS_PUBLIC EAS_RESULT EAS_Render (EAS_DATA_HANDLE pEASData, EAS_PCM *pOut, EAS_I
/*----------------------------------------------------------------------------
* EAS_SetRepeat()
*----------------------------------------------------------------------------
- * Purpose:
+ * Purpose:
* Set the selected stream to repeat.
*
* Inputs:
- * pEASData - handle to data for this instance
- * streamHandle - handle to stream
- * repeatCount - repeat count (0 = no repeat, -1 = repeat forever)
- *
+ * pEASData - handle to data for this instance
+ * streamHandle - handle to stream
+ * repeatCount - repeat count (0 = no repeat, -1 = repeat forever)
+ *
* Outputs:
*
* Side Effects:
*
* Notes:
- * 0 = no repeat
- * 1 = repeat once, i.e. play through twice
+ * 0 = no repeat
+ * 1 = repeat once, i.e. play through twice
* -1 = repeat forever
*----------------------------------------------------------------------------
*/
@@ -194,21 +194,21 @@ EAS_PUBLIC EAS_RESULT EAS_SetRepeat (EAS_DATA_HANDLE pEASData, EAS_HANDLE stream
/*----------------------------------------------------------------------------
* EAS_GetRepeat()
*----------------------------------------------------------------------------
- * Purpose:
+ * Purpose:
* Gets the current repeat count for the selected stream.
*
* Inputs:
- * pEASData - handle to data for this instance
- * streamHandle - handle to stream
- * pRrepeatCount - pointer to variable to hold repeat count
- *
+ * pEASData - handle to data for this instance
+ * streamHandle - handle to stream
+ * pRrepeatCount - pointer to variable to hold repeat count
+ *
* Outputs:
*
* Side Effects:
*
* Notes:
- * 0 = no repeat
- * 1 = repeat once, i.e. play through twice
+ * 0 = no repeat
+ * 1 = repeat once, i.e. play through twice
* -1 = repeat forever
*----------------------------------------------------------------------------
*/
@@ -217,14 +217,14 @@ EAS_PUBLIC EAS_RESULT EAS_GetRepeat (EAS_DATA_HANDLE pEASData, EAS_HANDLE stream
/*----------------------------------------------------------------------------
* EAS_SetPlaybackRate()
*----------------------------------------------------------------------------
- * Purpose:
+ * Purpose:
* Set the playback rate.
*
* Inputs:
- * pEASData - handle to data for this instance
- * streamHandle - handle to stream
- * rate - rate (28-bit fractional amount)
- *
+ * pEASData - handle to data for this instance
+ * streamHandle - handle to stream
+ * rate - rate (28-bit fractional amount)
+ *
* Outputs:
*
* Side Effects:
@@ -232,22 +232,22 @@ EAS_PUBLIC EAS_RESULT EAS_GetRepeat (EAS_DATA_HANDLE pEASData, EAS_HANDLE stream
*----------------------------------------------------------------------------
*/
EAS_PUBLIC EAS_RESULT EAS_SetPlaybackRate (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle, EAS_U32 rate);
-#define MAX_PLAYBACK_RATE (EAS_U32)(1L << 29)
-#define MIN_PLAYBACK_RATE (EAS_U32)(1L << 27)
+#define MAX_PLAYBACK_RATE (EAS_U32)(1L << 29)
+#define MIN_PLAYBACK_RATE (EAS_U32)(1L << 27)
/*----------------------------------------------------------------------------
* EAS_SetTransposition)
*----------------------------------------------------------------------------
- * Purpose:
+ * Purpose:
* Sets the key tranposition for the synthesizer. Transposes all
* melodic instruments by the specified amount. Range is limited
* to +/-12 semitones.
*
* Inputs:
- * pEASData - handle to data for this instance
- * streamHandle - handle to stream
- * transposition - +/-12 semitones
- *
+ * pEASData - handle to data for this instance
+ * streamHandle - handle to stream
+ * transposition - +/-12 semitones
+ *
* Outputs:
*
* Side Effects:
@@ -255,21 +255,21 @@ EAS_PUBLIC EAS_RESULT EAS_SetPlaybackRate (EAS_DATA_HANDLE pEASData, EAS_HANDLE
*----------------------------------------------------------------------------
*/
EAS_PUBLIC EAS_RESULT EAS_SetTransposition (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle, EAS_I32 transposition);
-#define MAX_TRANSPOSE 12
+#define MAX_TRANSPOSE 12
/*----------------------------------------------------------------------------
* EAS_SetSynthPolyphony()
*----------------------------------------------------------------------------
- * Purpose:
+ * Purpose:
* Set the polyphony of the synthesizer. Value must be >= 1 and <= the
* maximum number of voices. This function will pin the polyphony
* at those limits
*
* Inputs:
- * pEASData - pointer to overall EAS data structure
- * synthNum - synthesizer number (0 = onboard, 1 = DSP)
- * polyphonyCount - the desired polyphony count
- *
+ * pEASData - pointer to overall EAS data structure
+ * synthNum - synthesizer number (0 = onboard, 1 = DSP)
+ * polyphonyCount - the desired polyphony count
+ *
* Outputs:
*
* Side Effects:
@@ -281,14 +281,14 @@ EAS_PUBLIC EAS_RESULT EAS_SetSynthPolyphony (EAS_DATA_HANDLE pEASData, EAS_I32 s
/*----------------------------------------------------------------------------
* EAS_GetSynthPolyphony()
*----------------------------------------------------------------------------
- * Purpose:
+ * Purpose:
* Returns the current polyphony setting of the synthesizer
*
* Inputs:
- * pEASData - pointer to overall EAS data structure
- * synthNum - synthesizer number (0 = onboard, 1 = DSP)
- * pPolyphonyCount - pointer to variable to receive polyphony count
- *
+ * pEASData - pointer to overall EAS data structure
+ * synthNum - synthesizer number (0 = onboard, 1 = DSP)
+ * pPolyphonyCount - pointer to variable to receive polyphony count
+ *
* Outputs:
*
* Side Effects:
@@ -300,16 +300,16 @@ EAS_PUBLIC EAS_RESULT EAS_GetSynthPolyphony (EAS_DATA_HANDLE pEASData, EAS_I32 s
/*----------------------------------------------------------------------------
* EAS_SetPolyphony()
*----------------------------------------------------------------------------
- * Purpose:
+ * Purpose:
* Set the polyphony of the stream. Value must be >= 1 and <= the
* maximum number of voices. This function will pin the polyphony
* at those limits
*
* Inputs:
- * pEASData - pointer to overall EAS data structure
- * streamHandle - handle returned by EAS_OpenFile
- * polyphonyCount - the desired polyphony count
- *
+ * pEASData - pointer to overall EAS data structure
+ * streamHandle - handle returned by EAS_OpenFile
+ * polyphonyCount - the desired polyphony count
+ *
* Outputs:
*
* Side Effects:
@@ -321,14 +321,14 @@ EAS_PUBLIC EAS_RESULT EAS_SetPolyphony (EAS_DATA_HANDLE pEASData, EAS_HANDLE str
/*----------------------------------------------------------------------------
* EAS_GetPolyphony()
*----------------------------------------------------------------------------
- * Purpose:
+ * Purpose:
* Returns the current polyphony setting of the stream
*
* Inputs:
- * pEASData - pointer to overall EAS data structure
- * streamHandle - handle returned by EAS_OpenFile
- * pPolyphonyCount - pointer to variable to receive polyphony count
- *
+ * pEASData - pointer to overall EAS data structure
+ * streamHandle - handle returned by EAS_OpenFile
+ * pPolyphonyCount - pointer to variable to receive polyphony count
+ *
* Outputs:
*
* Side Effects:
@@ -340,17 +340,17 @@ EAS_PUBLIC EAS_RESULT EAS_GetPolyphony (EAS_DATA_HANDLE pEASData, EAS_HANDLE str
/*----------------------------------------------------------------------------
* EAS_SetPriority()
*----------------------------------------------------------------------------
- * Purpose:
+ * Purpose:
* Set the priority of the stream. Determines which stream's voices
* are stolen when there are insufficient voices for all notes.
* Value must be in the range of 1-255, lower values are higher
* priority. The default priority is 50.
*
* Inputs:
- * pEASData - pointer to overall EAS data structure
- * streamHandle - handle returned by EAS_OpenFile
- * polyphonyCount - the desired polyphony count
- *
+ * pEASData - pointer to overall EAS data structure
+ * streamHandle - handle returned by EAS_OpenFile
+ * polyphonyCount - the desired polyphony count
+ *
* Outputs:
*
* Side Effects:
@@ -362,14 +362,14 @@ EAS_PUBLIC EAS_RESULT EAS_SetPriority (EAS_DATA_HANDLE pEASData, EAS_HANDLE stre
/*----------------------------------------------------------------------------
* EAS_GetPriority()
*----------------------------------------------------------------------------
- * Purpose:
+ * Purpose:
* Returns the current priority setting of the stream
*
* Inputs:
- * pEASData - pointer to overall EAS data structure
- * streamHandle - handle returned by EAS_OpenFile
- * pPriority - pointer to variable to receive priority
- *
+ * pEASData - pointer to overall EAS data structure
+ * streamHandle - handle returned by EAS_OpenFile
+ * pPriority - pointer to variable to receive priority
+ *
* Outputs:
*
* Side Effects:
@@ -381,14 +381,14 @@ EAS_PUBLIC EAS_RESULT EAS_GetPriority (EAS_DATA_HANDLE pEASData, EAS_HANDLE stre
/*----------------------------------------------------------------------------
* EAS_SetVolume()
*----------------------------------------------------------------------------
- * Purpose:
+ * Purpose:
* Set the master volume for the mixer. The default volume setting is
* 90 (-10 dB). The volume range is 0 to 100 in 1dB increments.
*
* Inputs:
- * pEASData - pointer to overall EAS data structure
- * volume - the desired master volume
- *
+ * pEASData - pointer to overall EAS data structure
+ * volume - the desired master volume
+ *
* Outputs:
*
*
@@ -402,13 +402,13 @@ EAS_PUBLIC EAS_RESULT EAS_SetVolume (EAS_DATA_HANDLE pEASData, EAS_HANDLE stream
/*----------------------------------------------------------------------------
* EAS_GetVolume()
*----------------------------------------------------------------------------
- * Purpose:
+ * Purpose:
* Returns the master volume for the mixer in 1dB increments.
*
* Inputs:
- * pEASData - pointer to overall EAS data structure
- * volume - the desired master volume
- *
+ * pEASData - pointer to overall EAS data structure
+ * volume - the desired master volume
+ *
* Outputs:
*
*
@@ -422,7 +422,7 @@ EAS_PUBLIC EAS_I32 EAS_GetVolume (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHan
/*----------------------------------------------------------------------------
* EAS_SetMaxLoad()
*----------------------------------------------------------------------------
- * Purpose:
+ * Purpose:
* Sets the maximum workload the parsers will do in a single call to
* EAS_Render. The units are currently arbitrary, but should correlate
* well to the actual CPU cycles consumed. The primary effect is to
@@ -431,9 +431,9 @@ EAS_PUBLIC EAS_I32 EAS_GetVolume (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHan
* the workload limiting function.
*
* Inputs:
- * pEASData - handle to data for this instance
- * maxLoad - the desired maximum workload
- *
+ * pEASData - handle to data for this instance
+ * maxLoad - the desired maximum workload
+ *
* Outputs:
*
* Side Effects:
@@ -449,9 +449,9 @@ EAS_PUBLIC EAS_RESULT EAS_SetMaxLoad (EAS_DATA_HANDLE pEASData, EAS_I32 maxLoad)
* use PCM streaming.
*
* Inputs:
- * pEASData - pointer to overall EAS data structure
- * streamHandle - handle returned by EAS_OpenFile
- * maxNumStreams - maximum number of PCM streams
+ * pEASData - pointer to overall EAS data structure
+ * streamHandle - handle returned by EAS_OpenFile
+ * maxNumStreams - maximum number of PCM streams
*----------------------------------------------------------------------------
*/
EAS_PUBLIC EAS_RESULT EAS_SetMaxPCMStreams (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_I32 maxNumStreams);
@@ -459,16 +459,16 @@ EAS_PUBLIC EAS_RESULT EAS_SetMaxPCMStreams (EAS_DATA_HANDLE pEASData, EAS_HANDLE
/*----------------------------------------------------------------------------
* EAS_OpenFile()
*----------------------------------------------------------------------------
- * Purpose:
+ * Purpose:
* Opens a file for audio playback.
*
* Inputs:
- * pEASData - pointer to overall EAS data structure
- * locator - pointer to filename or other locating information
- * pStreamHandle - pointer to stream handle variable
- *
+ * pEASData - pointer to overall EAS data structure
+ * locator - pointer to filename or other locating information
+ * pStreamHandle - pointer to stream handle variable
+ *
* Outputs:
- *
+ *
*
* Side Effects:
*
@@ -480,16 +480,16 @@ EAS_PUBLIC EAS_RESULT EAS_OpenFile (EAS_DATA_HANDLE pEASData, EAS_FILE_LOCATOR l
/*----------------------------------------------------------------------------
* EAS_MMAPIToneControl()
*----------------------------------------------------------------------------
- * Purpose:
+ * Purpose:
* Opens a ToneControl file for audio playback.
*
* Inputs:
- * pEASData - pointer to overall EAS data structure
- * locator - pointer to filename or other locating information
- * pStreamHandle - pointer to stream handle variable
- *
+ * pEASData - pointer to overall EAS data structure
+ * locator - pointer to filename or other locating information
+ * pStreamHandle - pointer to stream handle variable
+ *
* Outputs:
- *
+ *
*
* Side Effects:
*
@@ -502,9 +502,9 @@ EAS_PUBLIC EAS_RESULT EAS_MMAPIToneControl (EAS_DATA_HANDLE pEASData, EAS_FILE_L
*----------------------------------------------------------------------------
* Helper function to retrieve WAVE file fmt chunk for MMAPI
*----------------------------------------------------------------------------
- * pEASData - pointer to EAS persistent data object
- * streamHandle - stream handle
- * pFmtChunk - pointer to pointer to FMT chunk data
+ * pEASData - pointer to EAS persistent data object
+ * streamHandle - stream handle
+ * pFmtChunk - pointer to pointer to FMT chunk data
*----------------------------------------------------------------------------
*/
EAS_PUBLIC EAS_RESULT EAS_GetWaveFmtChunk (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle, EAS_VOID_PTR *ppFmtChunk);
@@ -515,9 +515,9 @@ EAS_PUBLIC EAS_RESULT EAS_GetWaveFmtChunk (EAS_DATA_HANDLE pEASData, EAS_HANDLE
*----------------------------------------------------------------------------
* Returns the file type (see eas_types.h for enumerations)
*----------------------------------------------------------------------------
- * pEASData - pointer to EAS persistent data object
- * streamHandle - stream handle
- * pFileType - pointer to variable to receive file type
+ * pEASData - pointer to EAS persistent data object
+ * streamHandle - stream handle
+ * pFileType - pointer to variable to receive file type
*----------------------------------------------------------------------------
*/
EAS_PUBLIC EAS_RESULT EAS_GetFileType (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle, EAS_I32 *pFileType);
@@ -525,19 +525,19 @@ EAS_PUBLIC EAS_RESULT EAS_GetFileType (EAS_DATA_HANDLE pEASData, EAS_HANDLE stre
/*----------------------------------------------------------------------------
* EAS_ParseMetaData()
*----------------------------------------------------------------------------
- * Purpose:
- *
+ * Purpose:
+ *
*
* Inputs:
- * pEASData - pointer to overall EAS data structure
- * streamHandle - file or stream handle
- * playLength - pointer to variable to store the play length (in msecs)
- *
+ * pEASData - pointer to overall EAS data structure
+ * streamHandle - file or stream handle
+ * playLength - pointer to variable to store the play length (in msecs)
+ *
* Outputs:
- *
+ *
*
* Side Effects:
- * - resets the parser to the start of the file
+ * - resets the parser to the start of the file
*----------------------------------------------------------------------------
*/
EAS_PUBLIC EAS_RESULT EAS_ParseMetaData (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle, EAS_I32 *pPlayLength);
@@ -545,16 +545,16 @@ EAS_PUBLIC EAS_RESULT EAS_ParseMetaData (EAS_DATA_HANDLE pEASData, EAS_HANDLE st
/*----------------------------------------------------------------------------
* EAS_Prepare()
*----------------------------------------------------------------------------
- * Purpose:
+ * Purpose:
* Prepares the synthesizer to play the file or stream. Parses the first
* frame of data from the file and arms the synthesizer.
*
* Inputs:
- * pEASData - pointer to overall EAS data structure
- * streamHandle - file or stream handle
- *
+ * pEASData - pointer to overall EAS data structure
+ * streamHandle - file or stream handle
+ *
* Outputs:
- *
+ *
*
* Side Effects:
*
@@ -565,15 +565,15 @@ EAS_PUBLIC EAS_RESULT EAS_Prepare (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHa
/*----------------------------------------------------------------------------
* EAS_State()
*----------------------------------------------------------------------------
- * Purpose:
- * Returns the state of an audio file or stream.
+ * Purpose:
+ * Returns the state of an audio file or stream.
*
* Inputs:
- * pEASData - pointer to overall EAS data structure
- * streamHandle - file or stream handle
- *
+ * pEASData - pointer to overall EAS data structure
+ * streamHandle - file or stream handle
+ *
* Outputs:
- *
+ *
*
* Side Effects:
*
@@ -584,32 +584,32 @@ EAS_PUBLIC EAS_RESULT EAS_State (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHand
/*----------------------------------------------------------------------------
* EAS_RegisterMetaDataCallback()
*----------------------------------------------------------------------------
- * Purpose:
+ * Purpose:
* Registers a metadata callback function for parsed metadata. To
* de-register the callback, call this function again with parameter
* cbFunc set to NULL.
*
* Inputs:
- * pEASData - pointer to overall EAS data structure
- * streamHandle - file or stream handle
- * cbFunc - pointer to host callback function
- * metaDataBuffer - pointer to metadata buffer
- * metaDataBufSize - maximum size of the metadata buffer
- *
+ * pEASData - pointer to overall EAS data structure
+ * streamHandle - file or stream handle
+ * cbFunc - pointer to host callback function
+ * metaDataBuffer - pointer to metadata buffer
+ * metaDataBufSize - maximum size of the metadata buffer
+ *
* Outputs:
- *
+ *
*
* Side Effects:
*
*----------------------------------------------------------------------------
*/
EAS_PUBLIC EAS_RESULT EAS_RegisterMetaDataCallback (
- EAS_DATA_HANDLE pEASData,
- EAS_HANDLE streamHandle,
- EAS_METADATA_CBFUNC cbFunc,
- char *metaDataBuffer,
- EAS_I32 metaDataBufSize,
- EAS_VOID_PTR pUserData);
+ EAS_DATA_HANDLE pEASData,
+ EAS_HANDLE streamHandle,
+ EAS_METADATA_CBFUNC cbFunc,
+ char *metaDataBuffer,
+ EAS_I32 metaDataBufSize,
+ EAS_VOID_PTR pUserData);
/*----------------------------------------------------------------------------
* EAS_GetNoteCount ()
@@ -617,9 +617,9 @@ EAS_PUBLIC EAS_RESULT EAS_RegisterMetaDataCallback (
* Returns the total number of notes played in this stream
*
* Inputs:
- * pEASData - pointer to overall EAS data structure
- * streamHandle - file or stream handle
- * pNoteCount - pointer to variable to receive note count
+ * pEASData - pointer to overall EAS data structure
+ * streamHandle - file or stream handle
+ * pNoteCount - pointer to variable to receive note count
*----------------------------------------------------------------------------
*/
EAS_PUBLIC EAS_RESULT EAS_GetNoteCount (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_I32 *pNoteCount);
@@ -627,16 +627,16 @@ EAS_PUBLIC EAS_RESULT EAS_GetNoteCount (EAS_DATA_HANDLE pEASData, EAS_HANDLE pSt
/*----------------------------------------------------------------------------
* EAS_CloseFile()
*----------------------------------------------------------------------------
- * Purpose:
+ * Purpose:
* Closes an audio file or stream. Playback should have either paused or
* completed (EAS_State returns EAS_PAUSED or EAS_STOPPED).
*
* Inputs:
- * pEASData - pointer to overall EAS data structure
- * streamHandle - file or stream handle
- *
+ * pEASData - pointer to overall EAS data structure
+ * streamHandle - file or stream handle
+ *
* Outputs:
- *
+ *
*
* Side Effects:
*
@@ -647,16 +647,16 @@ EAS_PUBLIC EAS_RESULT EAS_CloseFile (EAS_DATA_HANDLE pEASData, EAS_HANDLE stream
/*----------------------------------------------------------------------------
* EAS_OpenMIDIStream()
*----------------------------------------------------------------------------
- * Purpose:
+ * Purpose:
* Opens a raw MIDI stream allowing the host to route MIDI cable data directly to the synthesizer
*
* Inputs:
- * pEASData - pointer to overall EAS data structure
- * pStreamHandle - pointer to variable to hold file or stream handle
- * streamHandle - open stream or NULL for new synthesizer instance
- *
+ * pEASData - pointer to overall EAS data structure
+ * pStreamHandle - pointer to variable to hold file or stream handle
+ * streamHandle - open stream or NULL for new synthesizer instance
+ *
* Outputs:
- *
+ *
*
* Side Effects:
*
@@ -667,17 +667,17 @@ EAS_PUBLIC EAS_RESULT EAS_OpenMIDIStream (EAS_DATA_HANDLE pEASData, EAS_HANDLE *
/*----------------------------------------------------------------------------
* EAS_WriteMIDIStream()
*----------------------------------------------------------------------------
- * Purpose:
+ * Purpose:
* Send data to the MIDI stream device
*
* Inputs:
- * pEASData - pointer to overall EAS data structure
- * streamHandle - stream handle
- * pBuffer - pointer to buffer
- * count - number of bytes to write
- *
+ * pEASData - pointer to overall EAS data structure
+ * streamHandle - stream handle
+ * pBuffer - pointer to buffer
+ * count - number of bytes to write
+ *
* Outputs:
- *
+ *
*
* Side Effects:
*
@@ -688,15 +688,15 @@ EAS_PUBLIC EAS_RESULT EAS_WriteMIDIStream(EAS_DATA_HANDLE pEASData, EAS_HANDLE s
/*----------------------------------------------------------------------------
* EAS_CloseMIDIStream()
*----------------------------------------------------------------------------
- * Purpose:
+ * Purpose:
* Closes a raw MIDI stream
*
* Inputs:
- * pEASData - pointer to overall EAS data structure
- * streamHandle - stream handle
- *
+ * pEASData - pointer to overall EAS data structure
+ * streamHandle - stream handle
+ *
* Outputs:
- *
+ *
*
* Side Effects:
*
@@ -707,16 +707,16 @@ EAS_PUBLIC EAS_RESULT EAS_CloseMIDIStream (EAS_DATA_HANDLE pEASData, EAS_HANDLE
/*----------------------------------------------------------------------------
* EAS_Locate()
*----------------------------------------------------------------------------
- * Purpose:
+ * Purpose:
* Locate into the file associated with the handle.
*
* Inputs:
- * pEASData - pointer to overall EAS data structure
- * streamHandle - file handle
- * milliseconds - playback offset from start of file in milliseconds
- *
+ * pEASData - pointer to overall EAS data structure
+ * streamHandle - file handle
+ * milliseconds - playback offset from start of file in milliseconds
+ *
* Outputs:
- *
+ *
*
* Side Effects:
* the actual offset will be quantized to the closest update period, typically
@@ -730,12 +730,12 @@ EAS_PUBLIC EAS_RESULT EAS_Locate (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHan
/*----------------------------------------------------------------------------
* EAS_GetRenderTime()
*----------------------------------------------------------------------------
- * Purpose:
- * Returns the current playback offset
+ * Purpose:
+ * Returns the current playback offset
*
* Inputs:
- * pEASData - pointer to overall EAS data structure
- *
+ * pEASData - pointer to overall EAS data structure
+ *
* Outputs:
* Gets the render time clock in msecs.
*
@@ -748,13 +748,13 @@ EAS_PUBLIC EAS_RESULT EAS_GetRenderTime (EAS_DATA_HANDLE pEASData, EAS_I32 *pTim
/*----------------------------------------------------------------------------
* EAS_GetLocation()
*----------------------------------------------------------------------------
- * Purpose:
- * Returns the current playback offset
+ * Purpose:
+ * Returns the current playback offset
*
* Inputs:
- * pEASData - pointer to overall EAS data structure
- * streamHandle - file handle
- *
+ * pEASData - pointer to overall EAS data structure
+ * streamHandle - file handle
+ *
* Outputs:
* The offset in milliseconds from the start of the current sequence, quantized
* to the nearest update period. Actual resolution is typically 5.9 ms.
@@ -768,17 +768,17 @@ EAS_PUBLIC EAS_RESULT EAS_GetLocation (EAS_DATA_HANDLE pEASData, EAS_HANDLE stre
/*----------------------------------------------------------------------------
* EAS_Pause()
*----------------------------------------------------------------------------
- * Purpose:
+ * Purpose:
* Pauses the playback of the data associated with this handle. The audio
* is gracefully ramped down to prevent clicks and pops. It may take several
* buffers of audio before the audio is muted.
*
* Inputs:
- * psEASData - pointer to overall EAS data structure
- * streamHandle - file or stream handle
- *
+ * psEASData - pointer to overall EAS data structure
+ * streamHandle - file or stream handle
+ *
* Outputs:
- *
+ *
*
* Side Effects:
*
@@ -790,16 +790,16 @@ EAS_PUBLIC EAS_RESULT EAS_Pause (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHand
/*----------------------------------------------------------------------------
* EAS_Resume()
*----------------------------------------------------------------------------
- * Purpose:
+ * Purpose:
* Resumes the playback of the data associated with this handle. The audio
* is gracefully ramped up to prevent clicks and pops.
*
* Inputs:
- * psEASData - pointer to overall EAS data structure
- * streamHandle - file or stream handle
- *
+ * psEASData - pointer to overall EAS data structure
+ * streamHandle - file or stream handle
+ *
* Outputs:
- *
+ *
*
* Side Effects:
*
@@ -811,18 +811,18 @@ EAS_PUBLIC EAS_RESULT EAS_Resume (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHan
/*----------------------------------------------------------------------------
* EAS_GetParameter()
*----------------------------------------------------------------------------
- * Purpose:
+ * Purpose:
* Set the parameter of a module. See E_MODULES for a list of modules
* and the header files of the modules for a list of parameters.
*
* Inputs:
- * psEASData - pointer to overall EAS data structure
- * module - enumerated module number
- * param - enumerated parameter number
- * pValue - pointer to variable to receive parameter value
- *
+ * psEASData - pointer to overall EAS data structure
+ * module - enumerated module number
+ * param - enumerated parameter number
+ * pValue - pointer to variable to receive parameter value
+ *
* Outputs:
- *
+ *
*
* Side Effects:
*
@@ -834,19 +834,19 @@ EAS_PUBLIC EAS_RESULT EAS_GetParameter (EAS_DATA_HANDLE pEASData, EAS_I32 module
/*----------------------------------------------------------------------------
* EAS_SetParameter()
*----------------------------------------------------------------------------
- * Purpose:
+ * Purpose:
* Set the parameter of a module. See E_MODULES for a list of modules
* and the header files of the modules for a list of parameters.
*
* Inputs:
- * psEASData - pointer to overall EAS data structure
- * handle - file or stream handle
- * module - enumerated module number
- * param - enumerated parameter number
- * value - new parameter value
- *
+ * psEASData - pointer to overall EAS data structure
+ * handle - file or stream handle
+ * module - enumerated module number
+ * param - enumerated parameter number
+ * value - new parameter value
+ *
* Outputs:
- *
+ *
*
* Side Effects:
*
@@ -855,18 +855,18 @@ EAS_PUBLIC EAS_RESULT EAS_GetParameter (EAS_DATA_HANDLE pEASData, EAS_I32 module
*/
EAS_PUBLIC EAS_RESULT EAS_SetParameter (EAS_DATA_HANDLE pEASData, EAS_I32 module, EAS_I32 param, EAS_I32 value);
-#ifdef _METRICS_ENABLED
+#ifdef _METRICS_ENABLED
/*----------------------------------------------------------------------------
* EAS_MetricsReport()
*----------------------------------------------------------------------------
- * Purpose:
+ * Purpose:
* Displays the current metrics through the EAS_Report interface.
*
* Inputs:
- * pEASData - instance data handle
- *
+ * pEASData - instance data handle
+ *
* Outputs:
- *
+ *
*
* Side Effects:
*
@@ -877,14 +877,14 @@ EAS_PUBLIC EAS_RESULT EAS_MetricsReport (EAS_DATA_HANDLE pEASData);
/*----------------------------------------------------------------------------
* EAS_MetricsReset()
*----------------------------------------------------------------------------
- * Purpose:
+ * Purpose:
* Displays the current metrics through the EAS_Report interface.
*
* Inputs:
- * pEASData - instance data handle
- *
+ * pEASData - instance data handle
+ *
* Outputs:
- *
+ *
*
* Side Effects:
*
@@ -896,16 +896,16 @@ EAS_PUBLIC EAS_RESULT EAS_MetricsReset (EAS_DATA_HANDLE pEASData);
/*----------------------------------------------------------------------------
* EAS_SetSoundLibrary()
*----------------------------------------------------------------------------
- * Purpose:
+ * Purpose:
* Sets the location of the sound library.
*
* Inputs:
- * pEASData - instance data handle
- * streamHandle - file or stream handle
- * pSoundLib - pointer to sound library
- *
+ * pEASData - instance data handle
+ * streamHandle - file or stream handle
+ * pSoundLib - pointer to sound library
+ *
* Outputs:
- *
+ *
*
* Side Effects:
*
@@ -926,8 +926,8 @@ EAS_PUBLIC EAS_RESULT EAS_SetSoundLibrary (EAS_DATA_HANDLE pEASData, EAS_HANDLE
* it make take slightly longer to process the EAS_OpenFile request.
*
* Inputs:
- * pEASData - instance data handle
- * searchFlag - search flag (EAS_TRUE or EAS_FALSE)
+ * pEASData - instance data handle
+ * searchFlag - search flag (EAS_TRUE or EAS_FALSE)
*----------------------------------------------------------------------------
*/
EAS_PUBLIC EAS_RESULT EAS_SetHeaderSearchFlag (EAS_DATA_HANDLE pEASData, EAS_BOOL searchFlag);
@@ -940,9 +940,9 @@ EAS_PUBLIC EAS_RESULT EAS_SetHeaderSearchFlag (EAS_DATA_HANDLE pEASData, EAS_BOO
* default play mode (usually straight playback) is always zero.
*
* Inputs:
- * pEASData - instance data handle
- * handle - file or stream handle
- * playMode - play mode (see eas_types.h for enumerations)
+ * pEASData - instance data handle
+ * handle - file or stream handle
+ * playMode - play mode (see eas_types.h for enumerations)
*----------------------------------------------------------------------------
*/
EAS_PUBLIC EAS_RESULT EAS_SetPlayMode (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_I32 playMode);
@@ -951,16 +951,16 @@ EAS_PUBLIC EAS_RESULT EAS_SetPlayMode (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStr
/*----------------------------------------------------------------------------
* EAS_LoadDLSCollection()
*----------------------------------------------------------------------------
- * Purpose:
+ * Purpose:
* Downloads a DLS collection
*
* Inputs:
- * pEASData - instance data handle
- * streamHandle - file or stream handle
- * locator - file locator
- *
+ * pEASData - instance data handle
+ * streamHandle - file or stream handle
+ * locator - file locator
+ *
* Outputs:
- *
+ *
*
* Side Effects:
* May overlay instruments in the GM sound set
@@ -973,15 +973,15 @@ EAS_PUBLIC EAS_RESULT EAS_LoadDLSCollection (EAS_DATA_HANDLE pEASData, EAS_HANDL
/*----------------------------------------------------------------------------
* EAS_SetFrameBuffer()
*----------------------------------------------------------------------------
- * Purpose:
+ * Purpose:
* Sets the frame buffer pointer passed to the IPC communications functions
*
* Inputs:
- * pEASData - instance data handle
- * locator - file locator
- *
+ * pEASData - instance data handle
+ * locator - file locator
+ *
* Outputs:
- *
+ *
*
* Side Effects:
* May overlay instruments in the GM sound set
@@ -994,41 +994,41 @@ EAS_PUBLIC EAS_RESULT EAS_SetFrameBuffer (EAS_DATA_HANDLE pEASData, EAS_FRAME_BU
/*----------------------------------------------------------------------------
* EAS_RegExtAudioCallback()
*----------------------------------------------------------------------------
- * Purpose:
+ * Purpose:
* Registers callback functions for audio events.
*
* Inputs:
- * pEASData - pointer to overall EAS data structure
- * streamHandle - file or stream handle
- * cbProgChgFunc - pointer to host callback function for program change
- * cbEventFunc - pointer to host callback functio for note events
- *
+ * pEASData - pointer to overall EAS data structure
+ * streamHandle - file or stream handle
+ * cbProgChgFunc - pointer to host callback function for program change
+ * cbEventFunc - pointer to host callback functio for note events
+ *
* Outputs:
- *
+ *
*
* Side Effects:
*
*----------------------------------------------------------------------------
*/
EAS_PUBLIC EAS_RESULT EAS_RegExtAudioCallback (EAS_DATA_HANDLE pEASData,
- EAS_HANDLE streamHandle,
- EAS_VOID_PTR pInstData,
- EAS_EXT_PRG_CHG_FUNC cbProgChgFunc,
- EAS_EXT_EVENT_FUNC cbEventFunc);
+ EAS_HANDLE streamHandle,
+ EAS_VOID_PTR pInstData,
+ EAS_EXT_PRG_CHG_FUNC cbProgChgFunc,
+ EAS_EXT_EVENT_FUNC cbEventFunc);
/*----------------------------------------------------------------------------
* EAS_GetMIDIControllers()
*----------------------------------------------------------------------------
- * Purpose:
+ * Purpose:
* Returns the current state of MIDI controllers on the requested channel.
*
* Inputs:
- * pEASData - pointer to overall EAS data structure
- * streamHandle - file or stream handle
- * pControl - pointer to structure to receive data
- *
+ * pEASData - pointer to overall EAS data structure
+ * streamHandle - file or stream handle
+ * pControl - pointer to structure to receive data
+ *
* Outputs:
- *
+ *
*
* Side Effects:
*
@@ -1044,11 +1044,11 @@ EAS_PUBLIC EAS_RESULT EAS_GetMIDIControllers (EAS_DATA_HANDLE pEASData, EAS_HAND
* position. Returns offset to start of sequence.
*
* Inputs:
- * pEASData - pointer to EAS persistent data object
- * fileHandle - file handle
- * searchString - pointer to search sequence
- * len - length of search sequence
- * pOffset - pointer to variable to store offset to sequence
+ * pEASData - pointer to EAS persistent data object
+ * fileHandle - file handle
+ * searchString - pointer to search sequence
+ * len - length of search sequence
+ * pOffset - pointer to variable to store offset to sequence
*
* Returns EAS_EOF if end-of-file is reached
*----------------------------------------------------------------------------
diff --git a/arm-wt-22k/host_src/eas_build.h b/arm-wt-22k/host_src/eas_build.h
index 4ff15cc..a65f8a6 100644
--- a/arm-wt-22k/host_src/eas_build.h
+++ b/arm-wt-22k/host_src/eas_build.h
@@ -1,15 +1,15 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * host_src\eas_build.h
- *
- * Contents and purpose:
- * This file contains the build configuration for this
- * build. The buildGUIDStr is a GUID created during
- * the build process and is guaranteed to be unique
- * for each build.
- *
- * Copyright Sonic Network Inc. 2006
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * host_src\eas_build.h
+ *
+ * Contents and purpose:
+ * This file contains the build configuration for this
+ * build. The buildGUIDStr is a GUID created during
+ * the build process and is guaranteed to be unique
+ * for each build.
+ *
+ * Copyright Sonic Network Inc. 2006
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -22,15 +22,15 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * This file was autogenerated by buildid.exe
- *----------------------------------------------------------------------------
-*/
-
-#ifndef _GUID_1feda229b9a845e996f473c0a80e7220_
-#define _GUID_1feda229b9a845e996f473c0a80e7220_
-
-#define _BUILD_VERSION_ "1feda229-b9a8-45e9-96f4-73c0a80e7220"
-#define _BUILD_TIME_ 0x4743badd
-
-#endif /* _GUID_1feda229b9a845e996f473c0a80e7220_ */
+ *
+ * This file was autogenerated by buildid.exe
+ *----------------------------------------------------------------------------
+*/
+
+#ifndef _GUID_1feda229b9a845e996f473c0a80e7220_
+#define _GUID_1feda229b9a845e996f473c0a80e7220_
+
+#define _BUILD_VERSION_ "1feda229-b9a8-45e9-96f4-73c0a80e7220"
+#define _BUILD_TIME_ 0x4743badd
+
+#endif /* _GUID_1feda229b9a845e996f473c0a80e7220_ */
diff --git a/arm-wt-22k/host_src/eas_chorus.h b/arm-wt-22k/host_src/eas_chorus.h
index 0e9057f..998a828 100644
--- a/arm-wt-22k/host_src/eas_chorus.h
+++ b/arm-wt-22k/host_src/eas_chorus.h
@@ -1,13 +1,13 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_chorus.h
- *
- * Contents and purpose:
- * Contains parameter enumerations for the Chorus effect
- *
- *
- * Copyright Sonic Network Inc. 2006
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_chorus.h
+ *
+ * Contents and purpose:
+ * Contains parameter enumerations for the Chorus effect
+ *
+ *
+ * Copyright Sonic Network Inc. 2006
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,34 +20,34 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 309 $
- * $Date: 2006-09-12 18:52:45 -0700 (Tue, 12 Sep 2006) $
- *----------------------------------------------------------------------------
-*/
-
-#ifndef EAS_CHORUS_H
-#define EAS_CHORUS_H
-
-/* enumerated parameter settings for Chorus effect */
-typedef enum
-{
- EAS_PARAM_CHORUS_BYPASS,
- EAS_PARAM_CHORUS_PRESET,
- EAS_PARAM_CHORUS_RATE,
- EAS_PARAM_CHORUS_DEPTH,
- EAS_PARAM_CHORUS_LEVEL
-} E_CHORUS_PARAMS;
-
-typedef enum
-{
- EAS_PARAM_CHORUS_PRESET1,
- EAS_PARAM_CHORUS_PRESET2,
- EAS_PARAM_CHORUS_PRESET3,
- EAS_PARAM_CHORUS_PRESET4
-} E_CHORUS_PRESETS;
-
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 309 $
+ * $Date: 2006-09-12 18:52:45 -0700 (Tue, 12 Sep 2006) $
+ *----------------------------------------------------------------------------
+*/
+
+#ifndef EAS_CHORUS_H
+#define EAS_CHORUS_H
+
+/* enumerated parameter settings for Chorus effect */
+typedef enum
+{
+ EAS_PARAM_CHORUS_BYPASS,
+ EAS_PARAM_CHORUS_PRESET,
+ EAS_PARAM_CHORUS_RATE,
+ EAS_PARAM_CHORUS_DEPTH,
+ EAS_PARAM_CHORUS_LEVEL
+} E_CHORUS_PARAMS;
+
+typedef enum
+{
+ EAS_PARAM_CHORUS_PRESET1,
+ EAS_PARAM_CHORUS_PRESET2,
+ EAS_PARAM_CHORUS_PRESET3,
+ EAS_PARAM_CHORUS_PRESET4
+} E_CHORUS_PRESETS;
+
+
#endif \ No newline at end of file
diff --git a/arm-wt-22k/host_src/eas_config.c b/arm-wt-22k/host_src/eas_config.c
index c45fbb7..0b92357 100644
--- a/arm-wt-22k/host_src/eas_config.c
+++ b/arm-wt-22k/host_src/eas_config.c
@@ -1,22 +1,22 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_config.c
- *
- * Contents and purpose:
- * This file contains the Configuration Module interface (CM). The CM
- * is a module compiled external to the library that sets the configuration
- * for this build. It allows the library to find optional components and
- * links to static memory allocations (when used in a static configuration).
- *
- * DO NOT MODIFY THIS FILE!
- *
- * NOTE: This module is not intended to be modified by the customer. It
- * needs to be included in the build process with the correct configuration
- * defines (see the library documentation for information on how to configure
- * the library).
- *
- * Copyright Sonic Network Inc. 2004-2006
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_config.c
+ *
+ * Contents and purpose:
+ * This file contains the Configuration Module interface (CM). The CM
+ * is a module compiled external to the library that sets the configuration
+ * for this build. It allows the library to find optional components and
+ * links to static memory allocations (when used in a static configuration).
+ *
+ * DO NOT MODIFY THIS FILE!
+ *
+ * NOTE: This module is not intended to be modified by the customer. It
+ * needs to be included in the build process with the correct configuration
+ * defines (see the library documentation for information on how to configure
+ * the library).
+ *
+ * Copyright Sonic Network Inc. 2004-2006
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -29,591 +29,591 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 796 $
- * $Date: 2007-08-01 00:15:25 -0700 (Wed, 01 Aug 2007) $
- *----------------------------------------------------------------------------
-*/
-
-#include "eas.h"
-#include "eas_config.h"
-
-
-#ifdef _MFI_PARSER
-/*----------------------------------------------------------------------------
- * Vendor/Device ID for MFi Extensions
- *
- * Define the preprocessor symbols to establish the vendor ID and
- * device ID for the MFi PCM/ADPCM extensions.
- *----------------------------------------------------------------------------
-*/
-const EAS_U8 eas_MFIVendorIDMSB = (MFI_VENDOR_ID >> 8) & 0xff;
-const EAS_U8 eas_MFIVendorIDLSB = MFI_VENDOR_ID & 0xff;
-const EAS_U8 eas_MFIDeviceID = MFI_DEVICE_ID;
-#endif
-
-/*----------------------------------------------------------------------------
- *
- * parserModules
- *
- * This structure is used by the EAS library to locate file parsing
- * modules.
- *----------------------------------------------------------------------------
-*/
-
-/* define the external file parsers */
-extern EAS_VOID_PTR EAS_SMF_Parser;
-
-#ifdef _XMF_PARSER
-extern EAS_VOID_PTR EAS_XMF_Parser;
-#endif
-
-#ifdef _SMAF_PARSER
-extern EAS_VOID_PTR EAS_SMAF_Parser;
-#endif
-
-#ifdef _WAVE_PARSER
-extern EAS_VOID_PTR EAS_Wave_Parser;
-#endif
-
-#ifdef _OTA_PARSER
-extern EAS_VOID_PTR EAS_OTA_Parser;
-#endif
-
-#ifdef _IMELODY_PARSER
-extern EAS_VOID_PTR EAS_iMelody_Parser;
-#endif
-
-#ifdef _RTTTL_PARSER
-extern EAS_VOID_PTR EAS_RTTTL_Parser;
-#endif
-
-#if defined (_CMX_PARSER) || defined(_MFI_PARSER)
-extern EAS_VOID_PTR EAS_CMF_Parser;
-#endif
-
-/* initalize pointers to parser interfaces */
-/*lint -e{605} not pretty, but it works */
-EAS_VOID_PTR const parserModules[] =
-{
- &EAS_SMF_Parser,
-
-#ifdef _XMF_PARSER
- &EAS_XMF_Parser,
-#endif
-
-#ifdef _WAVE_PARSER
- &EAS_Wave_Parser,
-#endif
-
-#ifdef _SMAF_PARSER
- &EAS_SMAF_Parser,
-#endif
-
-#ifdef _OTA_PARSER
- &EAS_OTA_Parser,
-#endif
-
-#ifdef _IMELODY_PARSER
- &EAS_iMelody_Parser,
-#endif
-
-#ifdef _RTTTL_PARSER
- &EAS_RTTTL_Parser,
-#endif
-
-#if defined (_CMX_PARSER) || defined(_MFI_PARSER)
- &EAS_CMF_Parser
-#endif
-};
-#define NUM_PARSER_MODULES (sizeof(parserModules) / sizeof(EAS_VOID_PTR))
-
-/*----------------------------------------------------------------------------
- * Data Modules
- *----------------------------------------------------------------------------
-*/
-
-#ifdef _STATIC_MEMORY
-extern EAS_VOID_PTR eas_SMFData;
-extern EAS_VOID_PTR eas_Data;
-extern EAS_VOID_PTR eas_MixBuffer;
-extern EAS_VOID_PTR eas_Synth;
-extern EAS_VOID_PTR eas_MIDI;
-extern EAS_VOID_PTR eas_PCMData;
-extern EAS_VOID_PTR eas_MIDIData;
-
-#ifdef _XMF_PARSER
-extern EAS_VOID_PTR eas_XMFData;
-#endif
-
-#ifdef _SMAF_PARSER
-extern EAS_VOID_PTR eas_SMAFData;
-#endif
-
-#ifdef _OTA_PARSER
-extern EAS_VOID_PTR eas_OTAData;
-#endif
-
-#ifdef _IMELODY_PARSER
-extern EAS_VOID_PTR eas_iMelodyData;
-#endif
-
-#ifdef _RTTTL_PARSER
-extern EAS_VOID_PTR eas_RTTTLData;
-#endif
-
-#ifdef _WAVE_PARSER
-extern EAS_VOID_PTR eas_WaveData;
-#endif
-
-#if defined (_CMX_PARSER) || defined(_MFI_PARSER)
-extern EAS_VOID_PTR eas_CMFData;
-#endif
-#endif
-
-/*----------------------------------------------------------------------------
- *
- * Effects Modules
- *
- * These declarations are used by the EAS library to locate
- * effects modules.
- *----------------------------------------------------------------------------
-*/
-
-#ifdef _ENHANCER_ENABLED
-extern EAS_VOID_PTR EAS_Enhancer;
-#define EAS_ENHANCER_INTERFACE &EAS_Enhancer
-#ifdef _STATIC_MEMORY
-extern EAS_VOID_PTR eas_EnhancerData;
-#define EAS_ENHANCER_DATA &eas_EnhancerData
-#else
-#define EAS_ENHANCER_DATA NULL
-#endif
-#else
-#define EAS_ENHANCER_INTERFACE NULL
-#define EAS_ENHANCER_DATA NULL
-#endif
-
-#ifdef _COMPRESSOR_ENABLED
-extern EAS_VOID_PTR EAS_Compressor;
-#define EAS_COMPRESSOR_INTERFACE &EAS_Compressor
-#ifdef _STATIC_MEMORY
-extern EAS_VOID_PTR eas_CompressorData;
-#define EAS_COMPRESSOR_DATA &eas_CompressorData
-#else
-#define EAS_COMPRESSOR_DATA NULL
-#endif
-#else
-#define EAS_COMPRESSOR_INTERFACE NULL
-#define EAS_COMPRESSOR_DATA NULL
-#endif
-
-#ifdef _MAXIMIZER_ENABLED
-extern EAS_VOID_PTR EAS_Maximizer;
-#define EAS_MAXIMIZER_INTERFACE &EAS_Maximizer
-#ifdef _STATIC_MEMORY
-extern EAS_VOID_PTR eas_MaximizerData;
-#define EAS_MAXIMIZER_DATA &eas_MaximizerData
-#else
-#define EAS_MAXIMIZER_DATA NULL
-#endif
-#else
-#define EAS_MAXIMIZER_INTERFACE NULL
-#define EAS_MAXIMIZER_DATA NULL
-#endif
-
-
-#ifdef _REVERB_ENABLED
-extern EAS_VOID_PTR EAS_Reverb;
-#define EAS_REVERB_INTERFACE &EAS_Reverb
-#ifdef _STATIC_MEMORY
-extern EAS_VOID_PTR eas_ReverbData;
-#define EAS_REVERB_DATA &eas_ReverbData
-#else
-#define EAS_REVERB_DATA NULL
-#endif
-#else
-#define EAS_REVERB_INTERFACE NULL
-#define EAS_REVERB_DATA NULL
-#endif
-
-#ifdef _CHORUS_ENABLED
-extern EAS_VOID_PTR EAS_Chorus;
-#define EAS_CHORUS_INTERFACE &EAS_Chorus
-#ifdef _STATIC_MEMORY
-extern EAS_VOID_PTR eas_ChorusData;
-#define EAS_CHORUS_DATA &eas_ChorusData
-#else
-#define EAS_CHORUS_DATA NULL
-#endif
-#else
-#define EAS_CHORUS_INTERFACE NULL
-#define EAS_CHORUS_DATA NULL
-#endif
-
-#ifdef _WIDENER_ENABLED
-extern EAS_VOID_PTR EAS_Widener;
-#define EAS_WIDENER_INTERFACE &EAS_Widener
-#ifdef _STATIC_MEMORY
-extern EAS_VOID_PTR eas_WidenerData;
-#define EAS_WIDENER_DATA &eas_WidenerData
-#else
-#define EAS_WIDENER_DATA NULL
-#endif
-#else
-#define EAS_WIDENER_INTERFACE NULL
-#define EAS_WIDENER_DATA NULL
-#endif
-
-#ifdef _GRAPHIC_EQ_ENABLED
-extern EAS_VOID_PTR EAS_GraphicEQ;
-#define EAS_GRAPHIC_EQ_INTERFACE &EAS_GraphicEQ
-#ifdef _STATIC_MEMORY
-extern EAS_VOID_PTR eas_GraphicEQData;
-#define EAS_GRAPHIC_EQ_DATA &eas_GraphicEQData
-#else
-#define EAS_GRAPHIC_EQ_DATA NULL
-#endif
-#else
-#define EAS_GRAPHIC_EQ_INTERFACE NULL
-#define EAS_GRAPHIC_EQ_DATA NULL
-#endif
-
-#ifdef _WOW_ENABLED
-extern EAS_VOID_PTR EAS_Wow;
-#define EAS_WOW_INTERFACE &EAS_Wow
-#ifdef _STATIC_MEMORY
-#error "WOW module requires dynamic memory model"
-#else
-#define EAS_WOW_DATA NULL
-#endif
-#else
-#define EAS_WOW_INTERFACE NULL
-#define EAS_WOW_DATA NULL
-#endif
-
-#ifdef _TONECONTROLEQ_ENABLED
-extern EAS_VOID_PTR EAS_ToneControlEQ;
-#define EAS_TONECONTROLEQ_INTERFACE &EAS_ToneControlEQ
-#ifdef _STATIC_MEMORY
-extern EAS_VOID_PTR eas_ToneControlEQData;
-#define EAS_TONECONTROLEQ_DATA &eas_ToneControlEQData
-#else
-#define EAS_TONECONTROLEQ_DATA NULL
-#endif
-#else
-#define EAS_TONECONTROLEQ_INTERFACE NULL
-#define EAS_TONECONTROLEQ_DATA NULL
-#endif
-
-/*lint -e{605} not pretty, but it works */
-EAS_VOID_PTR const effectsModules[] =
-{
- EAS_ENHANCER_INTERFACE,
- EAS_COMPRESSOR_INTERFACE,
- EAS_REVERB_INTERFACE,
- EAS_CHORUS_INTERFACE,
- EAS_WIDENER_INTERFACE,
- EAS_GRAPHIC_EQ_INTERFACE,
- EAS_WOW_INTERFACE,
- EAS_MAXIMIZER_INTERFACE,
- EAS_TONECONTROLEQ_INTERFACE
-};
-
-EAS_VOID_PTR const effectsData[] =
-{
- EAS_ENHANCER_DATA,
- EAS_COMPRESSOR_DATA,
- EAS_REVERB_DATA,
- EAS_CHORUS_DATA,
- EAS_WIDENER_DATA,
- EAS_GRAPHIC_EQ_DATA,
- EAS_WOW_DATA,
- EAS_MAXIMIZER_DATA,
- EAS_TONECONTROLEQ_DATA
-};
-
-/*----------------------------------------------------------------------------
- *
- * Optional Modules
- *
- * These declarations are used by the EAS library to locate
- * effects modules.
- *----------------------------------------------------------------------------
-*/
-
-#ifdef _METRICS_ENABLED
-extern EAS_VOID_PTR EAS_Metrics;
-#define EAS_METRICS_INTERFACE &EAS_Metrics
-#ifdef _STATIC_MEMORY
-extern EAS_VOID_PTR eas_MetricsData;
-#define EAS_METRICS_DATA &eas_MetricsData
-#else
-#define EAS_METRICS_DATA NULL
-#endif
-#else
-#define EAS_METRICS_INTERFACE NULL
-#define EAS_METRICS_DATA NULL
-#endif
-
-#ifdef MMAPI_SUPPORT
-extern EAS_VOID_PTR EAS_TC_Parser;
-#define EAS_TONE_CONTROL_PARSER &EAS_TC_Parser
-#ifdef _STATIC_MEMORY
-extern EAS_VOID_PTR eas_TCData;
-#define EAS_TONE_CONTROL_DATA &eas_TCData
-#else
-#define EAS_TONE_CONTROL_DATA NULL
-#endif
-#else
-#define EAS_TONE_CONTROL_PARSER NULL
-#define EAS_TONE_CONTROL_DATA NULL
-#endif
-
-/*lint -e{605} not pretty, but it works */
-EAS_VOID_PTR const optionalModules[] =
-{
- EAS_TONE_CONTROL_PARSER,
- EAS_METRICS_INTERFACE
-};
-
-EAS_VOID_PTR const optionalData[] =
-{
- EAS_TONE_CONTROL_DATA,
- EAS_METRICS_DATA
-};
-
-/*----------------------------------------------------------------------------
- * EAS_CMStaticMemoryModel()
- *----------------------------------------------------------------------------
- * Purpose:
- * This function returns true if EAS has been configured for
- * a static memory model. There are some limitations in the
- * static memory model, see the documentation for more
- * information.
- *
- * Outputs:
- * returns EAS_TRUE if a module is found
- *----------------------------------------------------------------------------
-*/
-EAS_BOOL EAS_CMStaticMemoryModel (void)
-{
-#ifdef _STATIC_MEMORY
- return EAS_TRUE;
-#else
- return EAS_FALSE;
-#endif
-}
-
-/*----------------------------------------------------------------------------
- * EAS_CMEnumModules()
- *----------------------------------------------------------------------------
- * Purpose:
- * This function is used to find pointers to optional modules.
- *
- * Inputs:
- * module - module number
- *
- * Outputs:
- * returns a pointer to the module function table or NULL if no module
- *----------------------------------------------------------------------------
-*/
-EAS_VOID_PTR EAS_CMEnumModules (EAS_INT module)
-{
-
- if (module >= (EAS_INT) NUM_PARSER_MODULES)
- return NULL;
- return parserModules[module];
-}
-
-/*----------------------------------------------------------------------------
- * EAS_CMEnumData()
- *----------------------------------------------------------------------------
- * Purpose:
- * This function is used to find pointers to static memory allocations.
- *
- * Inputs:
- * dataModule - enumerated module number
- *
- * Outputs:
- * Returns handle to data or NULL if not found
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, dataModule) used only when _STATIC_MEMORY is defined */
-EAS_VOID_PTR EAS_CMEnumData (EAS_INT dataModule)
-{
-
-#ifdef _STATIC_MEMORY
- switch (dataModule)
- {
-
- /* main instance data for synthesizer */
- case EAS_CM_EAS_DATA:
- return &eas_Data;
-
- /* mix buffer for mix engine */
- case EAS_CM_MIX_BUFFER:
- /*lint -e{545} lint doesn't like this because it sees the underlying type */
- return &eas_MixBuffer;
-
- /* instance data for synth */
- case EAS_CM_SYNTH_DATA:
- return &eas_Synth;
-
- /* instance data for MIDI parser */
- case EAS_CM_MIDI_DATA:
- return &eas_MIDI;
-
- /* instance data for SMF parser */
- case EAS_CM_SMF_DATA:
- return &eas_SMFData;
-
-#ifdef _XMF_PARSER
- /* instance data for XMF parser */
- case EAS_CM_XMF_DATA:
- return &eas_XMFData;
-#endif
-
-#ifdef _SMAF_PARSER
- /* instance data for SMAF parser */
- case EAS_CM_SMAF_DATA:
- return &eas_SMAFData;
-#endif
-
- /* instance data for the PCM engine */
- case EAS_CM_PCM_DATA:
- /*lint -e{545} lint doesn't like this because it sees the underlying type */
- return &eas_PCMData;
-
- case EAS_CM_MIDI_STREAM_DATA:
- return &eas_MIDIData;
-
-#ifdef _OTA_PARSER
- /* instance data for OTA parser */
- case EAS_CM_OTA_DATA:
- return &eas_OTAData;
-#endif
-
-#ifdef _IMELODY_PARSER
- /* instance data for iMelody parser */
- case EAS_CM_IMELODY_DATA:
- return &eas_iMelodyData;
-#endif
-
-#ifdef _RTTTL_PARSER
- /* instance data for RTTTL parser */
- case EAS_CM_RTTTL_DATA:
- return &eas_RTTTLData;
-#endif
-
-#ifdef _WAVE_PARSER
- /* instance data for WAVE parser */
- case EAS_CM_WAVE_DATA:
- return &eas_WaveData;
-#endif
-
-#if defined (_CMX_PARSER) || defined(_MFI_PARSER)
- /* instance data for CMF parser */
- case EAS_CM_CMF_DATA:
- return &eas_CMFData;
-#endif
-
- default:
- return NULL;
- }
-
-#else
- return NULL;
-#endif
-}
-
-/*----------------------------------------------------------------------------
- * EAS_CMEnumFXModules()
- *----------------------------------------------------------------------------
- * Purpose:
- * This function is used to find pointers to optional effects modules.
- *
- * Inputs:
- * module - enumerated module number
- * pModule - pointer to module interface
- *
- * Outputs:
- * Returns pointer to function table or NULL if not found
- *----------------------------------------------------------------------------
-*/
-EAS_VOID_PTR EAS_CMEnumFXModules (EAS_INT module)
-{
-
- if (module >= NUM_EFFECTS_MODULES)
- return NULL;
- return effectsModules[module];
-}
-
-/*----------------------------------------------------------------------------
- * EAS_CMEnumFXData()
- *----------------------------------------------------------------------------
- * Purpose:
- * This function is used to find pointers to static memory allocations.
- *
- * Inputs:
- * dataModule - enumerated module number
- * pData - pointer to handle variable
- *
- * Outputs:
- * Returns handle to data or NULL if not found
- *----------------------------------------------------------------------------
-*/
-EAS_VOID_PTR EAS_CMEnumFXData (EAS_INT dataModule)
-{
-
- if (dataModule >= NUM_EFFECTS_MODULES)
- return NULL;
- return effectsData[dataModule];
-}
-
-/*----------------------------------------------------------------------------
- * EAS_CMEnumOptModules()
- *----------------------------------------------------------------------------
- * Purpose:
- * This function is used to find pointers to optional modules.
- *
- * Inputs:
- * module - enumerated module number
- *
- * Outputs:
- * returns pointer to function table or NULL if no module
- *----------------------------------------------------------------------------
-*/
-EAS_VOID_PTR EAS_CMEnumOptModules (EAS_INT module)
-{
-
- /* sanity check */
- if (module >= NUM_OPTIONAL_MODULES)
- return EAS_FALSE;
- return optionalModules[module];
-}
-
-/*----------------------------------------------------------------------------
- * EAS_CMEnumOptData()
- *----------------------------------------------------------------------------
- * Purpose:
- * This function is used to find pointers to static memory allocations.
- *
- * Inputs:
- * dataModule - enumerated module number
- *
- * Outputs:
- * Returns handle to data or NULL if not found
- *----------------------------------------------------------------------------
-*/
-EAS_VOID_PTR EAS_CMEnumOptData (EAS_INT dataModule)
-{
-
- if (dataModule >= NUM_OPTIONAL_MODULES)
- return NULL;
- return optionalData[dataModule];
-}
-
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 796 $
+ * $Date: 2007-08-01 00:15:25 -0700 (Wed, 01 Aug 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+#include "eas.h"
+#include "eas_config.h"
+
+
+#ifdef _MFI_PARSER
+/*----------------------------------------------------------------------------
+ * Vendor/Device ID for MFi Extensions
+ *
+ * Define the preprocessor symbols to establish the vendor ID and
+ * device ID for the MFi PCM/ADPCM extensions.
+ *----------------------------------------------------------------------------
+*/
+const EAS_U8 eas_MFIVendorIDMSB = (MFI_VENDOR_ID >> 8) & 0xff;
+const EAS_U8 eas_MFIVendorIDLSB = MFI_VENDOR_ID & 0xff;
+const EAS_U8 eas_MFIDeviceID = MFI_DEVICE_ID;
+#endif
+
+/*----------------------------------------------------------------------------
+ *
+ * parserModules
+ *
+ * This structure is used by the EAS library to locate file parsing
+ * modules.
+ *----------------------------------------------------------------------------
+*/
+
+/* define the external file parsers */
+extern EAS_VOID_PTR EAS_SMF_Parser;
+
+#ifdef _XMF_PARSER
+extern EAS_VOID_PTR EAS_XMF_Parser;
+#endif
+
+#ifdef _SMAF_PARSER
+extern EAS_VOID_PTR EAS_SMAF_Parser;
+#endif
+
+#ifdef _WAVE_PARSER
+extern EAS_VOID_PTR EAS_Wave_Parser;
+#endif
+
+#ifdef _OTA_PARSER
+extern EAS_VOID_PTR EAS_OTA_Parser;
+#endif
+
+#ifdef _IMELODY_PARSER
+extern EAS_VOID_PTR EAS_iMelody_Parser;
+#endif
+
+#ifdef _RTTTL_PARSER
+extern EAS_VOID_PTR EAS_RTTTL_Parser;
+#endif
+
+#if defined (_CMX_PARSER) || defined(_MFI_PARSER)
+extern EAS_VOID_PTR EAS_CMF_Parser;
+#endif
+
+/* initalize pointers to parser interfaces */
+/*lint -e{605} not pretty, but it works */
+EAS_VOID_PTR const parserModules[] =
+{
+ &EAS_SMF_Parser,
+
+#ifdef _XMF_PARSER
+ &EAS_XMF_Parser,
+#endif
+
+#ifdef _WAVE_PARSER
+ &EAS_Wave_Parser,
+#endif
+
+#ifdef _SMAF_PARSER
+ &EAS_SMAF_Parser,
+#endif
+
+#ifdef _OTA_PARSER
+ &EAS_OTA_Parser,
+#endif
+
+#ifdef _IMELODY_PARSER
+ &EAS_iMelody_Parser,
+#endif
+
+#ifdef _RTTTL_PARSER
+ &EAS_RTTTL_Parser,
+#endif
+
+#if defined (_CMX_PARSER) || defined(_MFI_PARSER)
+ &EAS_CMF_Parser
+#endif
+};
+#define NUM_PARSER_MODULES (sizeof(parserModules) / sizeof(EAS_VOID_PTR))
+
+/*----------------------------------------------------------------------------
+ * Data Modules
+ *----------------------------------------------------------------------------
+*/
+
+#ifdef _STATIC_MEMORY
+extern EAS_VOID_PTR eas_SMFData;
+extern EAS_VOID_PTR eas_Data;
+extern EAS_VOID_PTR eas_MixBuffer;
+extern EAS_VOID_PTR eas_Synth;
+extern EAS_VOID_PTR eas_MIDI;
+extern EAS_VOID_PTR eas_PCMData;
+extern EAS_VOID_PTR eas_MIDIData;
+
+#ifdef _XMF_PARSER
+extern EAS_VOID_PTR eas_XMFData;
+#endif
+
+#ifdef _SMAF_PARSER
+extern EAS_VOID_PTR eas_SMAFData;
+#endif
+
+#ifdef _OTA_PARSER
+extern EAS_VOID_PTR eas_OTAData;
+#endif
+
+#ifdef _IMELODY_PARSER
+extern EAS_VOID_PTR eas_iMelodyData;
+#endif
+
+#ifdef _RTTTL_PARSER
+extern EAS_VOID_PTR eas_RTTTLData;
+#endif
+
+#ifdef _WAVE_PARSER
+extern EAS_VOID_PTR eas_WaveData;
+#endif
+
+#if defined (_CMX_PARSER) || defined(_MFI_PARSER)
+extern EAS_VOID_PTR eas_CMFData;
+#endif
+#endif
+
+/*----------------------------------------------------------------------------
+ *
+ * Effects Modules
+ *
+ * These declarations are used by the EAS library to locate
+ * effects modules.
+ *----------------------------------------------------------------------------
+*/
+
+#ifdef _ENHANCER_ENABLED
+extern EAS_VOID_PTR EAS_Enhancer;
+#define EAS_ENHANCER_INTERFACE &EAS_Enhancer
+#ifdef _STATIC_MEMORY
+extern EAS_VOID_PTR eas_EnhancerData;
+#define EAS_ENHANCER_DATA &eas_EnhancerData
+#else
+#define EAS_ENHANCER_DATA NULL
+#endif
+#else
+#define EAS_ENHANCER_INTERFACE NULL
+#define EAS_ENHANCER_DATA NULL
+#endif
+
+#ifdef _COMPRESSOR_ENABLED
+extern EAS_VOID_PTR EAS_Compressor;
+#define EAS_COMPRESSOR_INTERFACE &EAS_Compressor
+#ifdef _STATIC_MEMORY
+extern EAS_VOID_PTR eas_CompressorData;
+#define EAS_COMPRESSOR_DATA &eas_CompressorData
+#else
+#define EAS_COMPRESSOR_DATA NULL
+#endif
+#else
+#define EAS_COMPRESSOR_INTERFACE NULL
+#define EAS_COMPRESSOR_DATA NULL
+#endif
+
+#ifdef _MAXIMIZER_ENABLED
+extern EAS_VOID_PTR EAS_Maximizer;
+#define EAS_MAXIMIZER_INTERFACE &EAS_Maximizer
+#ifdef _STATIC_MEMORY
+extern EAS_VOID_PTR eas_MaximizerData;
+#define EAS_MAXIMIZER_DATA &eas_MaximizerData
+#else
+#define EAS_MAXIMIZER_DATA NULL
+#endif
+#else
+#define EAS_MAXIMIZER_INTERFACE NULL
+#define EAS_MAXIMIZER_DATA NULL
+#endif
+
+
+#ifdef _REVERB_ENABLED
+extern EAS_VOID_PTR EAS_Reverb;
+#define EAS_REVERB_INTERFACE &EAS_Reverb
+#ifdef _STATIC_MEMORY
+extern EAS_VOID_PTR eas_ReverbData;
+#define EAS_REVERB_DATA &eas_ReverbData
+#else
+#define EAS_REVERB_DATA NULL
+#endif
+#else
+#define EAS_REVERB_INTERFACE NULL
+#define EAS_REVERB_DATA NULL
+#endif
+
+#ifdef _CHORUS_ENABLED
+extern EAS_VOID_PTR EAS_Chorus;
+#define EAS_CHORUS_INTERFACE &EAS_Chorus
+#ifdef _STATIC_MEMORY
+extern EAS_VOID_PTR eas_ChorusData;
+#define EAS_CHORUS_DATA &eas_ChorusData
+#else
+#define EAS_CHORUS_DATA NULL
+#endif
+#else
+#define EAS_CHORUS_INTERFACE NULL
+#define EAS_CHORUS_DATA NULL
+#endif
+
+#ifdef _WIDENER_ENABLED
+extern EAS_VOID_PTR EAS_Widener;
+#define EAS_WIDENER_INTERFACE &EAS_Widener
+#ifdef _STATIC_MEMORY
+extern EAS_VOID_PTR eas_WidenerData;
+#define EAS_WIDENER_DATA &eas_WidenerData
+#else
+#define EAS_WIDENER_DATA NULL
+#endif
+#else
+#define EAS_WIDENER_INTERFACE NULL
+#define EAS_WIDENER_DATA NULL
+#endif
+
+#ifdef _GRAPHIC_EQ_ENABLED
+extern EAS_VOID_PTR EAS_GraphicEQ;
+#define EAS_GRAPHIC_EQ_INTERFACE &EAS_GraphicEQ
+#ifdef _STATIC_MEMORY
+extern EAS_VOID_PTR eas_GraphicEQData;
+#define EAS_GRAPHIC_EQ_DATA &eas_GraphicEQData
+#else
+#define EAS_GRAPHIC_EQ_DATA NULL
+#endif
+#else
+#define EAS_GRAPHIC_EQ_INTERFACE NULL
+#define EAS_GRAPHIC_EQ_DATA NULL
+#endif
+
+#ifdef _WOW_ENABLED
+extern EAS_VOID_PTR EAS_Wow;
+#define EAS_WOW_INTERFACE &EAS_Wow
+#ifdef _STATIC_MEMORY
+#error "WOW module requires dynamic memory model"
+#else
+#define EAS_WOW_DATA NULL
+#endif
+#else
+#define EAS_WOW_INTERFACE NULL
+#define EAS_WOW_DATA NULL
+#endif
+
+#ifdef _TONECONTROLEQ_ENABLED
+extern EAS_VOID_PTR EAS_ToneControlEQ;
+#define EAS_TONECONTROLEQ_INTERFACE &EAS_ToneControlEQ
+#ifdef _STATIC_MEMORY
+extern EAS_VOID_PTR eas_ToneControlEQData;
+#define EAS_TONECONTROLEQ_DATA &eas_ToneControlEQData
+#else
+#define EAS_TONECONTROLEQ_DATA NULL
+#endif
+#else
+#define EAS_TONECONTROLEQ_INTERFACE NULL
+#define EAS_TONECONTROLEQ_DATA NULL
+#endif
+
+/*lint -e{605} not pretty, but it works */
+EAS_VOID_PTR const effectsModules[] =
+{
+ EAS_ENHANCER_INTERFACE,
+ EAS_COMPRESSOR_INTERFACE,
+ EAS_REVERB_INTERFACE,
+ EAS_CHORUS_INTERFACE,
+ EAS_WIDENER_INTERFACE,
+ EAS_GRAPHIC_EQ_INTERFACE,
+ EAS_WOW_INTERFACE,
+ EAS_MAXIMIZER_INTERFACE,
+ EAS_TONECONTROLEQ_INTERFACE
+};
+
+EAS_VOID_PTR const effectsData[] =
+{
+ EAS_ENHANCER_DATA,
+ EAS_COMPRESSOR_DATA,
+ EAS_REVERB_DATA,
+ EAS_CHORUS_DATA,
+ EAS_WIDENER_DATA,
+ EAS_GRAPHIC_EQ_DATA,
+ EAS_WOW_DATA,
+ EAS_MAXIMIZER_DATA,
+ EAS_TONECONTROLEQ_DATA
+};
+
+/*----------------------------------------------------------------------------
+ *
+ * Optional Modules
+ *
+ * These declarations are used by the EAS library to locate
+ * effects modules.
+ *----------------------------------------------------------------------------
+*/
+
+#ifdef _METRICS_ENABLED
+extern EAS_VOID_PTR EAS_Metrics;
+#define EAS_METRICS_INTERFACE &EAS_Metrics
+#ifdef _STATIC_MEMORY
+extern EAS_VOID_PTR eas_MetricsData;
+#define EAS_METRICS_DATA &eas_MetricsData
+#else
+#define EAS_METRICS_DATA NULL
+#endif
+#else
+#define EAS_METRICS_INTERFACE NULL
+#define EAS_METRICS_DATA NULL
+#endif
+
+#ifdef MMAPI_SUPPORT
+extern EAS_VOID_PTR EAS_TC_Parser;
+#define EAS_TONE_CONTROL_PARSER &EAS_TC_Parser
+#ifdef _STATIC_MEMORY
+extern EAS_VOID_PTR eas_TCData;
+#define EAS_TONE_CONTROL_DATA &eas_TCData
+#else
+#define EAS_TONE_CONTROL_DATA NULL
+#endif
+#else
+#define EAS_TONE_CONTROL_PARSER NULL
+#define EAS_TONE_CONTROL_DATA NULL
+#endif
+
+/*lint -e{605} not pretty, but it works */
+EAS_VOID_PTR const optionalModules[] =
+{
+ EAS_TONE_CONTROL_PARSER,
+ EAS_METRICS_INTERFACE
+};
+
+EAS_VOID_PTR const optionalData[] =
+{
+ EAS_TONE_CONTROL_DATA,
+ EAS_METRICS_DATA
+};
+
+/*----------------------------------------------------------------------------
+ * EAS_CMStaticMemoryModel()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * This function returns true if EAS has been configured for
+ * a static memory model. There are some limitations in the
+ * static memory model, see the documentation for more
+ * information.
+ *
+ * Outputs:
+ * returns EAS_TRUE if a module is found
+ *----------------------------------------------------------------------------
+*/
+EAS_BOOL EAS_CMStaticMemoryModel (void)
+{
+#ifdef _STATIC_MEMORY
+ return EAS_TRUE;
+#else
+ return EAS_FALSE;
+#endif
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_CMEnumModules()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * This function is used to find pointers to optional modules.
+ *
+ * Inputs:
+ * module - module number
+ *
+ * Outputs:
+ * returns a pointer to the module function table or NULL if no module
+ *----------------------------------------------------------------------------
+*/
+EAS_VOID_PTR EAS_CMEnumModules (EAS_INT module)
+{
+
+ if (module >= (EAS_INT) NUM_PARSER_MODULES)
+ return NULL;
+ return parserModules[module];
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_CMEnumData()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * This function is used to find pointers to static memory allocations.
+ *
+ * Inputs:
+ * dataModule - enumerated module number
+ *
+ * Outputs:
+ * Returns handle to data or NULL if not found
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, dataModule) used only when _STATIC_MEMORY is defined */
+EAS_VOID_PTR EAS_CMEnumData (EAS_INT dataModule)
+{
+
+#ifdef _STATIC_MEMORY
+ switch (dataModule)
+ {
+
+ /* main instance data for synthesizer */
+ case EAS_CM_EAS_DATA:
+ return &eas_Data;
+
+ /* mix buffer for mix engine */
+ case EAS_CM_MIX_BUFFER:
+ /*lint -e{545} lint doesn't like this because it sees the underlying type */
+ return &eas_MixBuffer;
+
+ /* instance data for synth */
+ case EAS_CM_SYNTH_DATA:
+ return &eas_Synth;
+
+ /* instance data for MIDI parser */
+ case EAS_CM_MIDI_DATA:
+ return &eas_MIDI;
+
+ /* instance data for SMF parser */
+ case EAS_CM_SMF_DATA:
+ return &eas_SMFData;
+
+#ifdef _XMF_PARSER
+ /* instance data for XMF parser */
+ case EAS_CM_XMF_DATA:
+ return &eas_XMFData;
+#endif
+
+#ifdef _SMAF_PARSER
+ /* instance data for SMAF parser */
+ case EAS_CM_SMAF_DATA:
+ return &eas_SMAFData;
+#endif
+
+ /* instance data for the PCM engine */
+ case EAS_CM_PCM_DATA:
+ /*lint -e{545} lint doesn't like this because it sees the underlying type */
+ return &eas_PCMData;
+
+ case EAS_CM_MIDI_STREAM_DATA:
+ return &eas_MIDIData;
+
+#ifdef _OTA_PARSER
+ /* instance data for OTA parser */
+ case EAS_CM_OTA_DATA:
+ return &eas_OTAData;
+#endif
+
+#ifdef _IMELODY_PARSER
+ /* instance data for iMelody parser */
+ case EAS_CM_IMELODY_DATA:
+ return &eas_iMelodyData;
+#endif
+
+#ifdef _RTTTL_PARSER
+ /* instance data for RTTTL parser */
+ case EAS_CM_RTTTL_DATA:
+ return &eas_RTTTLData;
+#endif
+
+#ifdef _WAVE_PARSER
+ /* instance data for WAVE parser */
+ case EAS_CM_WAVE_DATA:
+ return &eas_WaveData;
+#endif
+
+#if defined (_CMX_PARSER) || defined(_MFI_PARSER)
+ /* instance data for CMF parser */
+ case EAS_CM_CMF_DATA:
+ return &eas_CMFData;
+#endif
+
+ default:
+ return NULL;
+ }
+
+#else
+ return NULL;
+#endif
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_CMEnumFXModules()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * This function is used to find pointers to optional effects modules.
+ *
+ * Inputs:
+ * module - enumerated module number
+ * pModule - pointer to module interface
+ *
+ * Outputs:
+ * Returns pointer to function table or NULL if not found
+ *----------------------------------------------------------------------------
+*/
+EAS_VOID_PTR EAS_CMEnumFXModules (EAS_INT module)
+{
+
+ if (module >= NUM_EFFECTS_MODULES)
+ return NULL;
+ return effectsModules[module];
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_CMEnumFXData()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * This function is used to find pointers to static memory allocations.
+ *
+ * Inputs:
+ * dataModule - enumerated module number
+ * pData - pointer to handle variable
+ *
+ * Outputs:
+ * Returns handle to data or NULL if not found
+ *----------------------------------------------------------------------------
+*/
+EAS_VOID_PTR EAS_CMEnumFXData (EAS_INT dataModule)
+{
+
+ if (dataModule >= NUM_EFFECTS_MODULES)
+ return NULL;
+ return effectsData[dataModule];
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_CMEnumOptModules()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * This function is used to find pointers to optional modules.
+ *
+ * Inputs:
+ * module - enumerated module number
+ *
+ * Outputs:
+ * returns pointer to function table or NULL if no module
+ *----------------------------------------------------------------------------
+*/
+EAS_VOID_PTR EAS_CMEnumOptModules (EAS_INT module)
+{
+
+ /* sanity check */
+ if (module >= NUM_OPTIONAL_MODULES)
+ return EAS_FALSE;
+ return optionalModules[module];
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_CMEnumOptData()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * This function is used to find pointers to static memory allocations.
+ *
+ * Inputs:
+ * dataModule - enumerated module number
+ *
+ * Outputs:
+ * Returns handle to data or NULL if not found
+ *----------------------------------------------------------------------------
+*/
+EAS_VOID_PTR EAS_CMEnumOptData (EAS_INT dataModule)
+{
+
+ if (dataModule >= NUM_OPTIONAL_MODULES)
+ return NULL;
+ return optionalData[dataModule];
+}
+
+
diff --git a/arm-wt-22k/host_src/eas_config.h b/arm-wt-22k/host_src/eas_config.h
index d16be4a..49c2ef2 100644
--- a/arm-wt-22k/host_src/eas_config.h
+++ b/arm-wt-22k/host_src/eas_config.h
@@ -1,22 +1,22 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_config.h
- *
- * Contents and purpose:
- * This header declares the Configuration Module interface (CM). The CM
- * is a module compiled external to the library that sets the configuration
- * for this build. It allows the library to find optional components and
- * links to static memory allocations (when used in a static configuration).
- *
- * NOTE: This module is not intended to be modified by the customer. It
- * needs to be included in the build process with the correct configuration
- * defines (see the library documentation for information on how to configure
- * the library).
- *
- * DO NOT MODIFY THIS FILE!
- *
- * Copyright 2005 Sonic Network Inc.
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_config.h
+ *
+ * Contents and purpose:
+ * This header declares the Configuration Module interface (CM). The CM
+ * is a module compiled external to the library that sets the configuration
+ * for this build. It allows the library to find optional components and
+ * links to static memory allocations (when used in a static configuration).
+ *
+ * NOTE: This module is not intended to be modified by the customer. It
+ * needs to be included in the build process with the correct configuration
+ * defines (see the library documentation for information on how to configure
+ * the library).
+ *
+ * DO NOT MODIFY THIS FILE!
+ *
+ * Copyright 2005 Sonic Network Inc.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -29,163 +29,163 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 82 $
- * $Date: 2006-07-10 11:45:19 -0700 (Mon, 10 Jul 2006) $
- *----------------------------------------------------------------------------
-*/
-
-// sentinel
-#ifndef _EAS_CONFIG_H
-#define _EAS_CONFIG_H
-
-#include "eas_types.h"
-
-/* list of enumerators for optional modules */
-typedef enum {
- EAS_CM_FILE_PARSERS = 1
-} E_CM_ENUM_MODULES;
-
-/* list of enumerators for module and memory pointers */
-typedef enum {
- EAS_CM_EAS_DATA = 1,
- EAS_CM_MIX_BUFFER,
- EAS_CM_SYNTH_DATA,
- EAS_CM_MIDI_DATA,
- EAS_CM_SMF_DATA,
- EAS_CM_XMF_DATA,
- EAS_CM_SMAF_DATA,
- EAS_CM_PCM_DATA,
- EAS_CM_MIDI_STREAM_DATA,
- EAS_CM_METRICS_DATA,
- EAS_CM_OTA_DATA,
- EAS_CM_IMELODY_DATA,
- EAS_CM_RTTTL_DATA,
- EAS_CM_WAVE_DATA,
- EAS_CM_CMF_DATA
-} E_CM_DATA_MODULES;
-
-typedef struct
-{
- int maxSMFStreams;
- void *pSMFData;
- void *pSMFStream;
-} S_EAS_SMF_PTRS;
-
-typedef struct
-{
- int maxSMAFStreams;
- void *pSMAFData;
- void *pSMAFStream;
-} S_EAS_SMAF_PTRS;
-
-/*----------------------------------------------------------------------------
- * EAS_CMStaticMemoryModel()
- *----------------------------------------------------------------------------
- * Purpose:
- * This function returns true if EAS has been configured for
- * a static memory model. There are some limitations in the
- * static memory model, see the documentation for more
- * information.
- *
- * Outputs:
- * returns EAS_TRUE if a module is found
- *----------------------------------------------------------------------------
-*/
-EAS_BOOL EAS_CMStaticMemoryModel (void);
-
-/*----------------------------------------------------------------------------
- * EAS_CMEnumModules()
- *----------------------------------------------------------------------------
- * Purpose:
- * This function is used to find pointers to optional modules.
- *
- * Inputs:
- * module - module number
- *
- * Outputs:
- * returns a pointer to the module function table or NULL if no module
- *----------------------------------------------------------------------------
-*/
-EAS_VOID_PTR EAS_CMEnumModules (EAS_INT module);
-
-/*----------------------------------------------------------------------------
- * EAS_CMEnumData()
- *----------------------------------------------------------------------------
- * Purpose:
- * This function is used to find pointers to static memory allocations.
- *
- * Inputs:
- * dataModule - enumerated module number
- *
- * Outputs:
- * Returns handle to data or NULL if not found
- *----------------------------------------------------------------------------
-*/
-EAS_VOID_PTR EAS_CMEnumData (EAS_INT dataModule);
-
-/*----------------------------------------------------------------------------
- * EAS_CMEnumFXModules()
- *----------------------------------------------------------------------------
- * Purpose:
- * This function is used to find pointers to optional effects modules.
- *
- * Inputs:
- * module - enumerated module number
- * pModule - pointer to module interface
- *
- * Outputs:
- * Returns pointer to function table or NULL if not found
- *----------------------------------------------------------------------------
-*/
-EAS_VOID_PTR EAS_CMEnumFXModules (EAS_INT module);
-
-/*----------------------------------------------------------------------------
- * EAS_CMEnumFXData()
- *----------------------------------------------------------------------------
- * Purpose:
- * This function is used to find pointers to static memory allocations.
- *
- * Inputs:
- * dataModule - enumerated module number
- * pData - pointer to handle variable
- *
- * Outputs:
- * Returns handle to data or NULL if not found
- *----------------------------------------------------------------------------
-*/
-EAS_VOID_PTR EAS_CMEnumFXData (EAS_INT dataModule);
-
-/*----------------------------------------------------------------------------
- * EAS_CMEnumOptModules()
- *----------------------------------------------------------------------------
- * Purpose:
- * This function is used to find pointers to optional modules.
- *
- * Inputs:
- * module - enumerated module number
- *
- * Outputs:
- * returns pointer to function table or NULL if no module
- *----------------------------------------------------------------------------
-*/
-EAS_VOID_PTR EAS_CMEnumOptModules (EAS_INT module);
-
-/*----------------------------------------------------------------------------
- * EAS_CMEnumOptData()
- *----------------------------------------------------------------------------
- * Purpose:
- * This function is used to find pointers to static memory allocations.
- *
- * Inputs:
- * dataModule - enumerated module number
- *
- * Outputs:
- * Returns handle to data or NULL if not found
- *----------------------------------------------------------------------------
-*/
-EAS_VOID_PTR EAS_CMEnumOptData (EAS_INT dataModule);
-
-#endif /* end _EAS_CONFIG_H */
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 82 $
+ * $Date: 2006-07-10 11:45:19 -0700 (Mon, 10 Jul 2006) $
+ *----------------------------------------------------------------------------
+*/
+
+// sentinel
+#ifndef _EAS_CONFIG_H
+#define _EAS_CONFIG_H
+
+#include "eas_types.h"
+
+/* list of enumerators for optional modules */
+typedef enum {
+ EAS_CM_FILE_PARSERS = 1
+} E_CM_ENUM_MODULES;
+
+/* list of enumerators for module and memory pointers */
+typedef enum {
+ EAS_CM_EAS_DATA = 1,
+ EAS_CM_MIX_BUFFER,
+ EAS_CM_SYNTH_DATA,
+ EAS_CM_MIDI_DATA,
+ EAS_CM_SMF_DATA,
+ EAS_CM_XMF_DATA,
+ EAS_CM_SMAF_DATA,
+ EAS_CM_PCM_DATA,
+ EAS_CM_MIDI_STREAM_DATA,
+ EAS_CM_METRICS_DATA,
+ EAS_CM_OTA_DATA,
+ EAS_CM_IMELODY_DATA,
+ EAS_CM_RTTTL_DATA,
+ EAS_CM_WAVE_DATA,
+ EAS_CM_CMF_DATA
+} E_CM_DATA_MODULES;
+
+typedef struct
+{
+ int maxSMFStreams;
+ void *pSMFData;
+ void *pSMFStream;
+} S_EAS_SMF_PTRS;
+
+typedef struct
+{
+ int maxSMAFStreams;
+ void *pSMAFData;
+ void *pSMAFStream;
+} S_EAS_SMAF_PTRS;
+
+/*----------------------------------------------------------------------------
+ * EAS_CMStaticMemoryModel()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * This function returns true if EAS has been configured for
+ * a static memory model. There are some limitations in the
+ * static memory model, see the documentation for more
+ * information.
+ *
+ * Outputs:
+ * returns EAS_TRUE if a module is found
+ *----------------------------------------------------------------------------
+*/
+EAS_BOOL EAS_CMStaticMemoryModel (void);
+
+/*----------------------------------------------------------------------------
+ * EAS_CMEnumModules()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * This function is used to find pointers to optional modules.
+ *
+ * Inputs:
+ * module - module number
+ *
+ * Outputs:
+ * returns a pointer to the module function table or NULL if no module
+ *----------------------------------------------------------------------------
+*/
+EAS_VOID_PTR EAS_CMEnumModules (EAS_INT module);
+
+/*----------------------------------------------------------------------------
+ * EAS_CMEnumData()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * This function is used to find pointers to static memory allocations.
+ *
+ * Inputs:
+ * dataModule - enumerated module number
+ *
+ * Outputs:
+ * Returns handle to data or NULL if not found
+ *----------------------------------------------------------------------------
+*/
+EAS_VOID_PTR EAS_CMEnumData (EAS_INT dataModule);
+
+/*----------------------------------------------------------------------------
+ * EAS_CMEnumFXModules()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * This function is used to find pointers to optional effects modules.
+ *
+ * Inputs:
+ * module - enumerated module number
+ * pModule - pointer to module interface
+ *
+ * Outputs:
+ * Returns pointer to function table or NULL if not found
+ *----------------------------------------------------------------------------
+*/
+EAS_VOID_PTR EAS_CMEnumFXModules (EAS_INT module);
+
+/*----------------------------------------------------------------------------
+ * EAS_CMEnumFXData()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * This function is used to find pointers to static memory allocations.
+ *
+ * Inputs:
+ * dataModule - enumerated module number
+ * pData - pointer to handle variable
+ *
+ * Outputs:
+ * Returns handle to data or NULL if not found
+ *----------------------------------------------------------------------------
+*/
+EAS_VOID_PTR EAS_CMEnumFXData (EAS_INT dataModule);
+
+/*----------------------------------------------------------------------------
+ * EAS_CMEnumOptModules()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * This function is used to find pointers to optional modules.
+ *
+ * Inputs:
+ * module - enumerated module number
+ *
+ * Outputs:
+ * returns pointer to function table or NULL if no module
+ *----------------------------------------------------------------------------
+*/
+EAS_VOID_PTR EAS_CMEnumOptModules (EAS_INT module);
+
+/*----------------------------------------------------------------------------
+ * EAS_CMEnumOptData()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * This function is used to find pointers to static memory allocations.
+ *
+ * Inputs:
+ * dataModule - enumerated module number
+ *
+ * Outputs:
+ * Returns handle to data or NULL if not found
+ *----------------------------------------------------------------------------
+*/
+EAS_VOID_PTR EAS_CMEnumOptData (EAS_INT dataModule);
+
+#endif /* end _EAS_CONFIG_H */
diff --git a/arm-wt-22k/host_src/eas_host.h b/arm-wt-22k/host_src/eas_host.h
index 270e68c..8567432 100644
--- a/arm-wt-22k/host_src/eas_host.h
+++ b/arm-wt-22k/host_src/eas_host.h
@@ -1,16 +1,16 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_host.h
- *
- * Contents and purpose:
- * This header defines the host wrapper functions for stdio, stdlib, etc.
- * The host application must provide an abstraction layer for these functions
- * to support certain features, such as SMAF and SMF-1 conversion.
- *
- * DO NOT MODIFY THIS FILE!
- *
- * Copyright 2005 Sonic Network Inc.
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_host.h
+ *
+ * Contents and purpose:
+ * This header defines the host wrapper functions for stdio, stdlib, etc.
+ * The host application must provide an abstraction layer for these functions
+ * to support certain features, such as SMAF and SMF-1 conversion.
+ *
+ * DO NOT MODIFY THIS FILE!
+ *
+ * Copyright 2005 Sonic Network Inc.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -23,65 +23,65 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 82 $
- * $Date: 2006-07-10 11:45:19 -0700 (Mon, 10 Jul 2006) $
- *----------------------------------------------------------------------------
-*/
-
-// sentinel
-#ifndef _EAS_HOST_H
-#define _EAS_HOST_H
-
-#include "eas_types.h"
-
-/* for C++ linkage */
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* initialization and shutdown routines */
-extern EAS_RESULT EAS_HWInit(EAS_HW_DATA_HANDLE *hwInstData);
-extern EAS_RESULT EAS_HWShutdown(EAS_HW_DATA_HANDLE hwInstData);
-
-/* threading */
-extern void* EAS_HWRegisterSignalHandler();
-extern EAS_RESULT EAS_HWUnRegisterSignalHandler(void *cookie);
-
-/* memory functions */
-extern void *EAS_HWMemSet(void *s, int c, EAS_I32 n);
-extern void *EAS_HWMemCpy(void *s1, const void *s2, EAS_I32 n);
-extern EAS_I32 EAS_HWMemCmp(const void *s1, const void *s2, EAS_I32 n);
-
-/* memory allocation */
-extern void *EAS_HWMalloc(EAS_HW_DATA_HANDLE hwInstData, EAS_I32 size);
-extern void EAS_HWFree(EAS_HW_DATA_HANDLE hwInstData, void *p);
-
-/* file I/O */
-extern EAS_RESULT EAS_HWOpenFile(EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_LOCATOR locator, EAS_FILE_HANDLE *pFile, EAS_FILE_MODE mode);
-extern EAS_RESULT EAS_HWReadFile(EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, void *pBuffer, EAS_I32 n, EAS_I32 *pBytesRead);
-extern EAS_RESULT EAS_HWGetByte(EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, void *p);
-extern EAS_RESULT EAS_HWGetWord (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, void *p, EAS_BOOL msbFirst);
-extern EAS_RESULT EAS_HWGetDWord (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, void *p, EAS_BOOL msbFirst);
-extern EAS_RESULT EAS_HWFilePos (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, EAS_I32 *pPosition);
-extern EAS_RESULT EAS_HWFileSeek (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, EAS_I32 position);
-extern EAS_RESULT EAS_HWFileSeekOfs (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, EAS_I32 position);
-extern EAS_RESULT EAS_HWFileLength (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, EAS_I32 *pLength);
-extern EAS_RESULT EAS_HWDupHandle (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, EAS_FILE_HANDLE* pFile);
-extern EAS_RESULT EAS_HWCloseFile (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file);
-
-/* vibrate, LED, and backlight functions */
-extern EAS_RESULT EAS_HWVibrate(EAS_HW_DATA_HANDLE hwInstData, EAS_BOOL state);
-extern EAS_RESULT EAS_HWLED(EAS_HW_DATA_HANDLE hwInstData, EAS_BOOL state);
-extern EAS_RESULT EAS_HWBackLight(EAS_HW_DATA_HANDLE hwInstData, EAS_BOOL state);
-
-#ifdef __cplusplus
-} /* end extern "C" */
-#endif
-
-
-/* host yield function */
-extern EAS_BOOL EAS_HWYield(EAS_HW_DATA_HANDLE hwInstData);
-#endif /* end _EAS_HOST_H */
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 82 $
+ * $Date: 2006-07-10 11:45:19 -0700 (Mon, 10 Jul 2006) $
+ *----------------------------------------------------------------------------
+*/
+
+// sentinel
+#ifndef _EAS_HOST_H
+#define _EAS_HOST_H
+
+#include "eas_types.h"
+
+/* for C++ linkage */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* initialization and shutdown routines */
+extern EAS_RESULT EAS_HWInit(EAS_HW_DATA_HANDLE *hwInstData);
+extern EAS_RESULT EAS_HWShutdown(EAS_HW_DATA_HANDLE hwInstData);
+
+/* threading */
+extern void* EAS_HWRegisterSignalHandler();
+extern EAS_RESULT EAS_HWUnRegisterSignalHandler(void *cookie);
+
+/* memory functions */
+extern void *EAS_HWMemSet(void *s, int c, EAS_I32 n);
+extern void *EAS_HWMemCpy(void *s1, const void *s2, EAS_I32 n);
+extern EAS_I32 EAS_HWMemCmp(const void *s1, const void *s2, EAS_I32 n);
+
+/* memory allocation */
+extern void *EAS_HWMalloc(EAS_HW_DATA_HANDLE hwInstData, EAS_I32 size);
+extern void EAS_HWFree(EAS_HW_DATA_HANDLE hwInstData, void *p);
+
+/* file I/O */
+extern EAS_RESULT EAS_HWOpenFile(EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_LOCATOR locator, EAS_FILE_HANDLE *pFile, EAS_FILE_MODE mode);
+extern EAS_RESULT EAS_HWReadFile(EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, void *pBuffer, EAS_I32 n, EAS_I32 *pBytesRead);
+extern EAS_RESULT EAS_HWGetByte(EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, void *p);
+extern EAS_RESULT EAS_HWGetWord (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, void *p, EAS_BOOL msbFirst);
+extern EAS_RESULT EAS_HWGetDWord (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, void *p, EAS_BOOL msbFirst);
+extern EAS_RESULT EAS_HWFilePos (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, EAS_I32 *pPosition);
+extern EAS_RESULT EAS_HWFileSeek (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, EAS_I32 position);
+extern EAS_RESULT EAS_HWFileSeekOfs (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, EAS_I32 position);
+extern EAS_RESULT EAS_HWFileLength (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, EAS_I32 *pLength);
+extern EAS_RESULT EAS_HWDupHandle (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, EAS_FILE_HANDLE* pFile);
+extern EAS_RESULT EAS_HWCloseFile (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file);
+
+/* vibrate, LED, and backlight functions */
+extern EAS_RESULT EAS_HWVibrate(EAS_HW_DATA_HANDLE hwInstData, EAS_BOOL state);
+extern EAS_RESULT EAS_HWLED(EAS_HW_DATA_HANDLE hwInstData, EAS_BOOL state);
+extern EAS_RESULT EAS_HWBackLight(EAS_HW_DATA_HANDLE hwInstData, EAS_BOOL state);
+
+#ifdef __cplusplus
+} /* end extern "C" */
+#endif
+
+
+/* host yield function */
+extern EAS_BOOL EAS_HWYield(EAS_HW_DATA_HANDLE hwInstData);
+#endif /* end _EAS_HOST_H */
diff --git a/arm-wt-22k/host_src/eas_hostmm.c b/arm-wt-22k/host_src/eas_hostmm.c
index d8eed8e..6732928 100644
--- a/arm-wt-22k/host_src/eas_hostmm.c
+++ b/arm-wt-22k/host_src/eas_hostmm.c
@@ -8,11 +8,11 @@
* This is a sample version that reads from a filedescriptor.
* The file locator (EAS_FILE_LOCATOR) handle passed to
* HWOpenFile is the same one that is passed to EAS_OpenFile.
- *
+ *
* Modify this file to suit the needs of your particular system.
*
* EAS_MAX_FILE_HANDLES sets the maximum number of MIDI streams within
- * a MIDI type 1 file that can be played.
+ * a MIDI type 1 file that can be played.
*
* EAS_HW_FILE is a structure to support the file I/O functions. It
* comprises the file descriptor, the file read pointer, and
@@ -73,8 +73,8 @@
// 100 max file handles == 3 * (nb tracks(32) + 1 for the segment) + 1 for jet file
// 3 == 1(playing segment) + 1(prepared segment)
// + 1(after end of playing segment, before files closed)
-#define EAS_MAX_FILE_HANDLES 100
-#endif
+#define EAS_MAX_FILE_HANDLES 100
+#endif
/*
* this structure and the related function are here
@@ -118,7 +118,7 @@ EAS_RESULT EAS_HWInit (EAS_HW_DATA_HANDLE *pHWInstData)
return EAS_ERROR_MALLOC_FAILED;
EAS_HWMemSet(*pHWInstData, 0, sizeof(EAS_HW_INST_DATA));
-
+
file = (*pHWInstData)->files;
for (i = 0; i < EAS_MAX_FILE_HANDLES; i++)
{
@@ -184,7 +184,7 @@ void EAS_HWFree (EAS_HW_DATA_HANDLE hwInstData, void *p)
*
*----------------------------------------------------------------------------
*/
-void *EAS_HWMemCpy (void *dest, const void *src, EAS_I32 amount)
+void *EAS_HWMemCpy (void *dest, const void *src, EAS_I32 amount)
{
if (amount < 0) {
EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x1a54b6e8, 0x00000004 , amount);
@@ -201,7 +201,7 @@ void *EAS_HWMemCpy (void *dest, const void *src, EAS_I32 amount)
*
*----------------------------------------------------------------------------
*/
-void *EAS_HWMemSet (void *dest, int val, EAS_I32 amount)
+void *EAS_HWMemSet (void *dest, int val, EAS_I32 amount)
{
if (amount < 0) {
EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x1a54b6e8, 0x00000005 , amount);
@@ -218,7 +218,7 @@ void *EAS_HWMemSet (void *dest, int val, EAS_I32 amount)
*
*----------------------------------------------------------------------------
*/
-EAS_I32 EAS_HWMemCmp (const void *s1, const void *s2, EAS_I32 amount)
+EAS_I32 EAS_HWMemCmp (const void *s1, const void *s2, EAS_I32 amount)
{
if (amount < 0) {
EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x1a54b6e8, 0x00000006 , amount);
@@ -389,7 +389,7 @@ EAS_RESULT EAS_HWGetWord (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, v
*
* EAS_HWGetDWord
*
- * Returns the current location in the file
+ * Returns the current location in the file
*
*----------------------------------------------------------------------------
*/
@@ -422,7 +422,7 @@ EAS_RESULT EAS_HWGetDWord (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file,
*
* EAS_HWFilePos
*
- * Returns the current location in the file
+ * Returns the current location in the file
*
*----------------------------------------------------------------------------
*/
@@ -454,7 +454,7 @@ EAS_RESULT EAS_HWFileSeek (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file,
if (file->fd < 0)
return EAS_ERROR_INVALID_HANDLE;
- /* validate new position */
+ /* validate new position */
if ((position < 0) || (position > file->fileSize))
return EAS_ERROR_FILE_SEEK;
@@ -479,7 +479,7 @@ EAS_RESULT EAS_HWFileSeekOfs (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE fil
if (file->fd < 0)
return EAS_ERROR_INVALID_HANDLE;
- /* determine the file position */
+ /* determine the file position */
position += file->filePos;
if ((position < 0) || (position > file->fileSize))
return EAS_ERROR_FILE_SEEK;
diff --git a/arm-wt-22k/host_src/eas_main.c b/arm-wt-22k/host_src/eas_main.c
index fed600e..5cbf064 100644
--- a/arm-wt-22k/host_src/eas_main.c
+++ b/arm-wt-22k/host_src/eas_main.c
@@ -1,12 +1,12 @@
/*----------------------------------------------------------------------------
*
- * File:
+ * File:
* eas_main.c
*
* Contents and purpose:
* The entry point and high-level functions for the EAS Synthesizer test
* harness.
- *
+ *
* Copyright Sonic Network Inc. 2004
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -42,7 +42,7 @@
#include "eas_report.h"
/* determines how many EAS buffers to fill a host buffer */
-#define NUM_BUFFERS 8
+#define NUM_BUFFERS 8
/* default file to play if no filename is specified on the command line */
static const char defaultTestFile[] = "test.mid";
@@ -60,11 +60,11 @@ static EAS_BOOL EASLibraryCheck (const S_EAS_LIB_CONFIG *pLibConfig);
/*----------------------------------------------------------------------------
* PlayFile()
*----------------------------------------------------------------------------
- * Purpose:
+ * Purpose:
* This function plays the file requested by filename
- *
- * Inputs:
- *
+ *
+ * Inputs:
+ *
* Outputs:
*
*----------------------------------------------------------------------------
@@ -72,351 +72,351 @@ static EAS_BOOL EASLibraryCheck (const S_EAS_LIB_CONFIG *pLibConfig);
static EAS_RESULT PlayFile (EAS_DATA_HANDLE easData, const char* filename, const char* outputFile, const S_EAS_LIB_CONFIG *pLibConfig, void *buffer, EAS_I32 bufferSize)
{
- EAS_HANDLE handle;
- EAS_RESULT result, reportResult;
- EAS_I32 count;
- EAS_STATE state;
- EAS_I32 playTime;
- char waveFilename[256];
- WAVE_FILE *wFile;
- EAS_INT i;
- EAS_PCM *p;
- EAS_FILE file;
-
- /* determine the name of the output file */
- wFile = NULL;
- if (outputFile == NULL)
- {
- StrCopy(waveFilename, filename, sizeof(waveFilename));
- if (!ChangeFileExt(waveFilename, "wav", sizeof(waveFilename)))
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Error in output filename %s\n", waveFilename); */ }
- return EAS_FAILURE;
- }
- outputFile = waveFilename;
- }
-
- /* call EAS library to open file */
- file.path = filename;
- file.fd = 0;
- if ((reportResult = EAS_OpenFile(easData, &file, &handle)) != EAS_SUCCESS)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "EAS_OpenFile returned %ld\n", reportResult); */ }
- return reportResult;
- }
-
- /* prepare to play the file */
- if ((result = EAS_Prepare(easData, handle)) != EAS_SUCCESS)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "EAS_Prepare returned %ld\n", result); */ }
- reportResult = result;
- }
-
- /* get play length */
- if ((result = EAS_ParseMetaData(easData, handle, &playTime)) != EAS_SUCCESS)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "EAS_ParseMetaData returned %ld\n", result); */ }
- return result;
- }
- EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0xe624f4d9, 0x00000005 , playTime / 1000, playTime % 1000);
-
- if (reportResult == EAS_SUCCESS)
- {
- /* create the output file */
- wFile = WaveFileCreate(outputFile, pLibConfig->numChannels, pLibConfig->sampleRate, sizeof(EAS_PCM) * 8);
- if (!wFile)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Unable to create output file %s\n", waveFilename); */ }
- reportResult = EAS_FAILURE;
- }
- }
-
- /* rendering loop */
- while (reportResult == EAS_SUCCESS)
- {
-
- /* we may render several buffers here to fill one host buffer */
- for (i = 0, p = buffer; i < NUM_BUFFERS; i++, p+= pLibConfig->mixBufferSize * pLibConfig->numChannels)
- {
-
- /* get the current time */
- if ((result = EAS_GetLocation(easData, handle, &playTime)) != EAS_SUCCESS)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "EAS_GetLocation returned %d\n",result); */ }
- if (reportResult == EAS_SUCCESS)
- reportResult = result;
- break;
- }
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Parser time: %d.%03d\n", playTime / 1000, playTime % 1000); */ }
-
- /* render a buffer of audio */
- if ((result = EAS_Render(easData, p, pLibConfig->mixBufferSize, &count)) != EAS_SUCCESS)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "EAS_Render returned %d\n",result); */ }
- if (reportResult == EAS_SUCCESS)
- reportResult = result;
- }
- }
-
- if (result == EAS_SUCCESS)
- {
- /* write it to the wave file */
- if (WaveFileWrite(wFile, buffer, bufferSize) != bufferSize)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "WaveFileWrite failed\n"); */ }
- reportResult = EAS_FAILURE;
- }
- }
-
- if (reportResult == EAS_SUCCESS)
- {
- /* check stream state */
- if ((result = EAS_State(easData, handle, &state)) != EAS_SUCCESS)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "EAS_State returned %d\n", result); */ }
- reportResult = result;
- }
-
- /* is playback complete */
- if ((state == EAS_STATE_STOPPED) || (state == EAS_STATE_ERROR))
- break;
- }
- }
-
- /* close the output file */
- if (wFile)
- {
- if (!WaveFileClose(wFile))
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Error closing wave file %s\n", waveFilename); */ }
- if (reportResult == EAS_SUCCESS)
- result = EAS_FAILURE;
- }
- }
-
- /* close the input file */
- if ((result = EAS_CloseFile(easData,handle)) != EAS_SUCCESS)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "EAS_Close returned %ld\n", result); */ }
- if (reportResult == EAS_SUCCESS)
- result = EAS_FAILURE;
- }
-
- return reportResult;
+ EAS_HANDLE handle;
+ EAS_RESULT result, reportResult;
+ EAS_I32 count;
+ EAS_STATE state;
+ EAS_I32 playTime;
+ char waveFilename[256];
+ WAVE_FILE *wFile;
+ EAS_INT i;
+ EAS_PCM *p;
+ EAS_FILE file;
+
+ /* determine the name of the output file */
+ wFile = NULL;
+ if (outputFile == NULL)
+ {
+ StrCopy(waveFilename, filename, sizeof(waveFilename));
+ if (!ChangeFileExt(waveFilename, "wav", sizeof(waveFilename)))
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Error in output filename %s\n", waveFilename); */ }
+ return EAS_FAILURE;
+ }
+ outputFile = waveFilename;
+ }
+
+ /* call EAS library to open file */
+ file.path = filename;
+ file.fd = 0;
+ if ((reportResult = EAS_OpenFile(easData, &file, &handle)) != EAS_SUCCESS)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "EAS_OpenFile returned %ld\n", reportResult); */ }
+ return reportResult;
+ }
+
+ /* prepare to play the file */
+ if ((result = EAS_Prepare(easData, handle)) != EAS_SUCCESS)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "EAS_Prepare returned %ld\n", result); */ }
+ reportResult = result;
+ }
+
+ /* get play length */
+ if ((result = EAS_ParseMetaData(easData, handle, &playTime)) != EAS_SUCCESS)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "EAS_ParseMetaData returned %ld\n", result); */ }
+ return result;
+ }
+ EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0xe624f4d9, 0x00000005 , playTime / 1000, playTime % 1000);
+
+ if (reportResult == EAS_SUCCESS)
+ {
+ /* create the output file */
+ wFile = WaveFileCreate(outputFile, pLibConfig->numChannels, pLibConfig->sampleRate, sizeof(EAS_PCM) * 8);
+ if (!wFile)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Unable to create output file %s\n", waveFilename); */ }
+ reportResult = EAS_FAILURE;
+ }
+ }
+
+ /* rendering loop */
+ while (reportResult == EAS_SUCCESS)
+ {
+
+ /* we may render several buffers here to fill one host buffer */
+ for (i = 0, p = buffer; i < NUM_BUFFERS; i++, p+= pLibConfig->mixBufferSize * pLibConfig->numChannels)
+ {
+
+ /* get the current time */
+ if ((result = EAS_GetLocation(easData, handle, &playTime)) != EAS_SUCCESS)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "EAS_GetLocation returned %d\n",result); */ }
+ if (reportResult == EAS_SUCCESS)
+ reportResult = result;
+ break;
+ }
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Parser time: %d.%03d\n", playTime / 1000, playTime % 1000); */ }
+
+ /* render a buffer of audio */
+ if ((result = EAS_Render(easData, p, pLibConfig->mixBufferSize, &count)) != EAS_SUCCESS)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "EAS_Render returned %d\n",result); */ }
+ if (reportResult == EAS_SUCCESS)
+ reportResult = result;
+ }
+ }
+
+ if (result == EAS_SUCCESS)
+ {
+ /* write it to the wave file */
+ if (WaveFileWrite(wFile, buffer, bufferSize) != bufferSize)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "WaveFileWrite failed\n"); */ }
+ reportResult = EAS_FAILURE;
+ }
+ }
+
+ if (reportResult == EAS_SUCCESS)
+ {
+ /* check stream state */
+ if ((result = EAS_State(easData, handle, &state)) != EAS_SUCCESS)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "EAS_State returned %d\n", result); */ }
+ reportResult = result;
+ }
+
+ /* is playback complete */
+ if ((state == EAS_STATE_STOPPED) || (state == EAS_STATE_ERROR))
+ break;
+ }
+ }
+
+ /* close the output file */
+ if (wFile)
+ {
+ if (!WaveFileClose(wFile))
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Error closing wave file %s\n", waveFilename); */ }
+ if (reportResult == EAS_SUCCESS)
+ result = EAS_FAILURE;
+ }
+ }
+
+ /* close the input file */
+ if ((result = EAS_CloseFile(easData,handle)) != EAS_SUCCESS)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "EAS_Close returned %ld\n", result); */ }
+ if (reportResult == EAS_SUCCESS)
+ result = EAS_FAILURE;
+ }
+
+ return reportResult;
} /* end PlayFile */
/*----------------------------------------------------------------------------
* main()
*----------------------------------------------------------------------------
* Purpose: The entry point for the EAS sample application
- *
- * Inputs:
- *
+ *
+ * Inputs:
+ *
* Outputs:
*
*----------------------------------------------------------------------------
*/
int main( int argc, char **argv )
{
- EAS_DATA_HANDLE easData;
- const S_EAS_LIB_CONFIG *pLibConfig;
- void *buffer;
- EAS_RESULT result, playResult;
- EAS_I32 bufferSize;
- int i;
- int temp;
- FILE *debugFile;
- char *outputFile = NULL;
-
- /* set the error reporting level */
- EAS_SetDebugLevel(_EAS_SEVERITY_INFO);
- debugFile = NULL;
-
- /* process command-line arguments */
- for (i = 1; i < argc; i++)
- {
- /* check for switch */
- if (argv[i][0] == '-')
- {
- switch (argv[i][1])
- {
- case 'd':
- temp = argv[i][2];
- if ((temp >= '0') || (temp <= '9'))
- EAS_SetDebugLevel(temp);
- else
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Invalid debug level %d\n", temp); */ }
- break;
- case 'f':
- if ((debugFile = fopen(&argv[i][2],"w")) == NULL)
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Unable to create debug file %s\n", &argv[i][2]); */ }
- else
- EAS_SetDebugFile(debugFile, EAS_TRUE);
- break;
- case 'o':
- outputFile = &argv[i][2];
- break;
- case 'p':
- polyphony = atoi(&argv[i][2]);
- if (polyphony < 1)
- polyphony = 1;
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "Polyphony set to %d\n", polyphony); */ }
- break;
- default:
- break;
- }
- continue;
- }
- }
-
- /* assume success */
- playResult = EAS_SUCCESS;
-
- /* get the library configuration */
- pLibConfig = EAS_Config();
- if (!EASLibraryCheck(pLibConfig))
- return -1;
- if (polyphony > pLibConfig->maxVoices)
- polyphony = pLibConfig->maxVoices;
-
- /* calculate buffer size */
- bufferSize = pLibConfig->mixBufferSize * pLibConfig->numChannels * (EAS_I32)sizeof(EAS_PCM) * NUM_BUFFERS;
-
- /* allocate output buffer memory */
- buffer = malloc((EAS_U32)bufferSize);
- if (!buffer)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_FATAL, "Error allocating memory for audio buffer\n"); */ }
- return EAS_FAILURE;
- }
-
- /* initialize the EAS library */
- polyphony = pLibConfig->maxVoices;
- if ((result = EAS_Init(&easData)) != EAS_SUCCESS)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_FATAL, "EAS_Init returned %ld - aborting!\n", result); */ }
- free(buffer);
- return result;
- }
-
- /*
- * Some debugging environments don't allow for passed parameters.
- * In this case, just play the default MIDI file "test.mid"
- */
- if (argc < 2)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "Playing '%s'\n", defaultTestFile); */ }
- if ((playResult = PlayFile(easData, defaultTestFile, NULL, pLibConfig, buffer, bufferSize)) != EAS_SUCCESS)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Error %d playing file %s\n", playResult, defaultTestFile); */ }
- }
- }
- /* iterate through the list of files to be played */
- else
- {
- for (i = 1; i < argc; i++)
- {
- /* check for switch */
- if (argv[i][0] != '-')
- {
-
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "Playing '%s'\n", argv[i]); */ }
- if ((playResult = PlayFile(easData, argv[i], outputFile, pLibConfig, buffer, bufferSize)) != EAS_SUCCESS)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Error %d playing file %s\n", playResult, argv[i]); */ }
- break;
- }
- }
- }
- }
-
- /* shutdown the EAS library */
- if ((result = EAS_Shutdown(easData)) != EAS_SUCCESS)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_FATAL, "EAS_Shutdown returned %ld\n", result); */ }
- }
-
- /* free the output buffer */
- free(buffer);
-
- /* close the debug file */
- if (debugFile)
- fclose(debugFile);
-
- /* play errors take precedence over shutdown errors */
- if (playResult != EAS_SUCCESS)
- return playResult;
- return result;
+ EAS_DATA_HANDLE easData;
+ const S_EAS_LIB_CONFIG *pLibConfig;
+ void *buffer;
+ EAS_RESULT result, playResult;
+ EAS_I32 bufferSize;
+ int i;
+ int temp;
+ FILE *debugFile;
+ char *outputFile = NULL;
+
+ /* set the error reporting level */
+ EAS_SetDebugLevel(_EAS_SEVERITY_INFO);
+ debugFile = NULL;
+
+ /* process command-line arguments */
+ for (i = 1; i < argc; i++)
+ {
+ /* check for switch */
+ if (argv[i][0] == '-')
+ {
+ switch (argv[i][1])
+ {
+ case 'd':
+ temp = argv[i][2];
+ if ((temp >= '0') || (temp <= '9'))
+ EAS_SetDebugLevel(temp);
+ else
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Invalid debug level %d\n", temp); */ }
+ break;
+ case 'f':
+ if ((debugFile = fopen(&argv[i][2],"w")) == NULL)
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Unable to create debug file %s\n", &argv[i][2]); */ }
+ else
+ EAS_SetDebugFile(debugFile, EAS_TRUE);
+ break;
+ case 'o':
+ outputFile = &argv[i][2];
+ break;
+ case 'p':
+ polyphony = atoi(&argv[i][2]);
+ if (polyphony < 1)
+ polyphony = 1;
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "Polyphony set to %d\n", polyphony); */ }
+ break;
+ default:
+ break;
+ }
+ continue;
+ }
+ }
+
+ /* assume success */
+ playResult = EAS_SUCCESS;
+
+ /* get the library configuration */
+ pLibConfig = EAS_Config();
+ if (!EASLibraryCheck(pLibConfig))
+ return -1;
+ if (polyphony > pLibConfig->maxVoices)
+ polyphony = pLibConfig->maxVoices;
+
+ /* calculate buffer size */
+ bufferSize = pLibConfig->mixBufferSize * pLibConfig->numChannels * (EAS_I32)sizeof(EAS_PCM) * NUM_BUFFERS;
+
+ /* allocate output buffer memory */
+ buffer = malloc((EAS_U32)bufferSize);
+ if (!buffer)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_FATAL, "Error allocating memory for audio buffer\n"); */ }
+ return EAS_FAILURE;
+ }
+
+ /* initialize the EAS library */
+ polyphony = pLibConfig->maxVoices;
+ if ((result = EAS_Init(&easData)) != EAS_SUCCESS)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_FATAL, "EAS_Init returned %ld - aborting!\n", result); */ }
+ free(buffer);
+ return result;
+ }
+
+ /*
+ * Some debugging environments don't allow for passed parameters.
+ * In this case, just play the default MIDI file "test.mid"
+ */
+ if (argc < 2)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "Playing '%s'\n", defaultTestFile); */ }
+ if ((playResult = PlayFile(easData, defaultTestFile, NULL, pLibConfig, buffer, bufferSize)) != EAS_SUCCESS)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Error %d playing file %s\n", playResult, defaultTestFile); */ }
+ }
+ }
+ /* iterate through the list of files to be played */
+ else
+ {
+ for (i = 1; i < argc; i++)
+ {
+ /* check for switch */
+ if (argv[i][0] != '-')
+ {
+
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "Playing '%s'\n", argv[i]); */ }
+ if ((playResult = PlayFile(easData, argv[i], outputFile, pLibConfig, buffer, bufferSize)) != EAS_SUCCESS)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Error %d playing file %s\n", playResult, argv[i]); */ }
+ break;
+ }
+ }
+ }
+ }
+
+ /* shutdown the EAS library */
+ if ((result = EAS_Shutdown(easData)) != EAS_SUCCESS)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_FATAL, "EAS_Shutdown returned %ld\n", result); */ }
+ }
+
+ /* free the output buffer */
+ free(buffer);
+
+ /* close the debug file */
+ if (debugFile)
+ fclose(debugFile);
+
+ /* play errors take precedence over shutdown errors */
+ if (playResult != EAS_SUCCESS)
+ return playResult;
+ return result;
} /* end main */
/*----------------------------------------------------------------------------
* StrCopy()
*----------------------------------------------------------------------------
- * Purpose:
+ * Purpose:
* Safe string copy
- *
- * Inputs:
- *
+ *
+ * Inputs:
+ *
* Outputs:
*
*----------------------------------------------------------------------------
*/
static void StrCopy(char *dest, const char *src, EAS_I32 size)
{
- int len;
+ int len;
- strncpy(dest, src, (size_t) size-1);
- len = (int) strlen(src);
- if (len < size)
- dest[len] = 0;
+ strncpy(dest, src, (size_t) size-1);
+ len = (int) strlen(src);
+ if (len < size)
+ dest[len] = 0;
} /* end StrCopy */
/*----------------------------------------------------------------------------
* ChangeFileExt()
*----------------------------------------------------------------------------
- * Purpose:
+ * Purpose:
* Changes the file extension of a filename
- *
- * Inputs:
- *
+ *
+ * Inputs:
+ *
* Outputs:
*
*----------------------------------------------------------------------------
*/
static EAS_BOOL ChangeFileExt(char *str, const char *ext, EAS_I32 size)
{
- char *p;
-
- /* find the extension, if any */
- p = strrchr(str,'.');
- if (!p)
- {
- if ((EAS_I32)(strlen(str) + 5) > size)
- return EAS_FALSE;
- strcat(str,".");
- strcat(str,ext);
- return EAS_TRUE;
- }
-
- /* make sure there's room for the extension */
- p++;
- *p = 0;
- if ((EAS_I32)(strlen(str) + 4) > size)
- return EAS_FALSE;
- strcat(str,ext);
- return EAS_TRUE;
+ char *p;
+
+ /* find the extension, if any */
+ p = strrchr(str,'.');
+ if (!p)
+ {
+ if ((EAS_I32)(strlen(str) + 5) > size)
+ return EAS_FALSE;
+ strcat(str,".");
+ strcat(str,ext);
+ return EAS_TRUE;
+ }
+
+ /* make sure there's room for the extension */
+ p++;
+ *p = 0;
+ if ((EAS_I32)(strlen(str) + 4) > size)
+ return EAS_FALSE;
+ strcat(str,ext);
+ return EAS_TRUE;
} /* end ChangeFileExt */
/*----------------------------------------------------------------------------
* EASLibraryCheck()
*----------------------------------------------------------------------------
- * Purpose:
+ * Purpose:
* Displays the library version and checks it against the header
* file used to build this code.
*
* Inputs:
- * pLibConfig - library configuration retrieved from the library
- *
+ * pLibConfig - library configuration retrieved from the library
+ *
* Outputs:
* returns EAS_TRUE if matched
*
@@ -427,38 +427,38 @@ static EAS_BOOL ChangeFileExt(char *str, const char *ext, EAS_I32 size)
static EAS_BOOL EASLibraryCheck (const S_EAS_LIB_CONFIG *pLibConfig)
{
- /* display the library version */
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "EAS Library Version %d.%d.%d.%d\n",
- pLibConfig->libVersion >> 24,
- (pLibConfig->libVersion >> 16) & 0x0f,
- (pLibConfig->libVersion >> 8) & 0x0f,
- pLibConfig->libVersion & 0x0f); */ }
-
- /* display some info about the library build */
- if (pLibConfig->checkedVersion)
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "\tChecked library\n"); */ }
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "\tMaximum polyphony: %d\n", pLibConfig->maxVoices); */ }
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "\tNumber of channels: %d\n", pLibConfig->numChannels); */ }
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "\tSample rate: %d\n", pLibConfig->sampleRate); */ }
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "\tMix buffer size: %d\n", pLibConfig->mixBufferSize); */ }
- if (pLibConfig->filterEnabled)
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "\tFilter enabled\n"); */ }
+ /* display the library version */
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "EAS Library Version %d.%d.%d.%d\n",
+ pLibConfig->libVersion >> 24,
+ (pLibConfig->libVersion >> 16) & 0x0f,
+ (pLibConfig->libVersion >> 8) & 0x0f,
+ pLibConfig->libVersion & 0x0f); */ }
+
+ /* display some info about the library build */
+ if (pLibConfig->checkedVersion)
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "\tChecked library\n"); */ }
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "\tMaximum polyphony: %d\n", pLibConfig->maxVoices); */ }
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "\tNumber of channels: %d\n", pLibConfig->numChannels); */ }
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "\tSample rate: %d\n", pLibConfig->sampleRate); */ }
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "\tMix buffer size: %d\n", pLibConfig->mixBufferSize); */ }
+ if (pLibConfig->filterEnabled)
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "\tFilter enabled\n"); */ }
#ifndef _WIN32_WCE
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "\tLibrary Build Timestamp: %s", ctime((time_t*)&pLibConfig->buildTimeStamp)); */ }
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "\tLibrary Build Timestamp: %s", ctime((time_t*)&pLibConfig->buildTimeStamp)); */ }
#endif
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "\tLibrary Build ID: %s\n", pLibConfig->buildGUID); */ }
-
- /* check it against the header file used to build this code */
- /*lint -e{778} constant expression used for display purposes may evaluate to zero */
- if (LIB_VERSION != pLibConfig->libVersion)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_FATAL, "Library version does not match header files. EAS Header Version %d.%d.%d.%d\n",
- LIB_VERSION >> 24,
- (LIB_VERSION >> 16) & 0x0f,
- (LIB_VERSION >> 8) & 0x0f,
- LIB_VERSION & 0x0f); */ }
- return EAS_FALSE;
- }
- return EAS_TRUE;
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "\tLibrary Build ID: %s\n", pLibConfig->buildGUID); */ }
+
+ /* check it against the header file used to build this code */
+ /*lint -e{778} constant expression used for display purposes may evaluate to zero */
+ if (LIB_VERSION != pLibConfig->libVersion)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_FATAL, "Library version does not match header files. EAS Header Version %d.%d.%d.%d\n",
+ LIB_VERSION >> 24,
+ (LIB_VERSION >> 16) & 0x0f,
+ (LIB_VERSION >> 8) & 0x0f,
+ LIB_VERSION & 0x0f); */ }
+ return EAS_FALSE;
+ }
+ return EAS_TRUE;
} /* end EASLibraryCheck */
diff --git a/arm-wt-22k/host_src/eas_report.c b/arm-wt-22k/host_src/eas_report.c
index d4dd22c..04a828c 100644
--- a/arm-wt-22k/host_src/eas_report.c
+++ b/arm-wt-22k/host_src/eas_report.c
@@ -1,13 +1,13 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_report.c
- *
- * Contents and purpose:
- * This file contains the debug message handling routines for the EAS library.
- * These routines should be modified as needed for your system.
- *
- * Copyright 2005 Sonic Network Inc.
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_report.c
+ *
+ * Contents and purpose:
+ * This file contains the debug message handling routines for the EAS library.
+ * These routines should be modified as needed for your system.
+ *
+ * Copyright 2005 Sonic Network Inc.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,245 +20,245 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 659 $
- * $Date: 2007-04-24 13:36:35 -0700 (Tue, 24 Apr 2007) $
- *----------------------------------------------------------------------------
-*/
-
-#ifdef _lint
-#include "lint_stdlib.h"
-#else
-#include <stdlib.h>
-#include <stdio.h>
-#include <stdarg.h>
-#endif
-
-#include "eas_report.h"
-
-static int severityLevel = 9999;
-
-/* debug file */
-static FILE *debugFile = NULL;
-int flush = 0;
-
-#ifndef _NO_DEBUG_PREPROCESSOR
-
-/* structure should have an #include for each error message header file */
-S_DEBUG_MESSAGES debugMessages[] =
-{
-#ifndef UNIFIED_DEBUG_MESSAGES
-#include "eas_config_msgs.h"
-
-
-#include "eas_host_msgs.h"
-#include "eas_hostmm_msgs.h"
-#include "eas_math_msgs.h"
-#include "eas_midi_msgs.h"
-#include "eas_mixer_msgs.h"
-#include "eas_pcm_msgs.h"
-#include "eas_public_msgs.h"
-#include "eas_smf_msgs.h"
-#include "eas_wave_msgs.h"
-#include "eas_voicemgt_msgs.h"
-
-#ifdef _FM_SYNTH
-#include "eas_fmsynth_msgs.h"
-#include "eas_fmengine_msgs.h"
-#endif
-
-#ifdef _WT_SYNTH
-#include "eas_wtsynth_msgs.h"
-#include "eas_wtengine_msgs.h"
-#endif
-
-#ifdef _ARM_TEST_MAIN
-#include "arm_main_msgs.h"
-#endif
-
-#ifdef _EAS_MAIN
-#include "eas_main_msgs.h"
-#endif
-
-#ifdef _EAS_MAIN_IPC
-#include "eas_main_ipc_msgs.h"
-#endif
-
-#ifdef _METRICS_ENABLED
-#include "eas_perf_msgs.h"
-#endif
-
-#ifdef _COMPRESSOR_ENABLED
-#include "eas_compressor_msgs.h"
-#endif
-
-#ifdef _ENHANCER_ENABLED
-#include "eas_enhancer_msgs.h"
-#endif
-
-#ifdef _WOW_ENABLED
-#include "eas_wow_msgs.h"
-#endif
-
-#ifdef _SMAF_PARSER
-#include "eas_smaf_msgs.h"
-#endif
-
-#ifdef _OTA_PARSER
-#include "eas_ota_msgs.h"
-#endif
-
-#ifdef _IMELODY_PARSER
-#include "eas_imelody_msgs.h"
-#endif
-
-#ifdef _WAVE_PARSER
-#include "eas_wavefile_msgs.h"
-#endif
-
-#if defined(_CMX_PARSER) || defined(_MFI_PARSER)
-#include "eas_cmf_msgs.h"
-#endif
-
-#if defined(_CMX_PARSER) || defined(_MFI_PARSER) || defined(_WAVE_PARSER)
-#include "eas_imaadpcm_msgs.h"
-#endif
-
-#else
-#include "eas_debugmsgs.h"
-#endif
-
-/* denotes end of error messages */
-{ 0,0,0 }
-};
-
-/*----------------------------------------------------------------------------
- * EAS_ReportEx()
- *
- * This is the error message handler. The default handler outputs error
- * messages to stdout. Modify this as needed for your system.
- *----------------------------------------------------------------------------
-*/
-void EAS_ReportEx (int severity, unsigned long hashCode, int serialNum, ...)
-{
- va_list vargs;
- int i;
-
- /* check severity level */
- if (severity > severityLevel)
- return;
-
- /* find the error message and output to stdout */
- /*lint -e{661} we check for NULL pointer - no fence post error here */
- for (i = 0; debugMessages[i].m_pDebugMsg; i++)
- {
- if ((debugMessages[i].m_nHashCode == hashCode) &&
- (debugMessages[i].m_nSerialNum == serialNum))
- {
- /*lint -e{826} <allow variable args> */
- va_start(vargs, serialNum);
- if (debugFile)
- {
- vfprintf(debugFile, debugMessages[i].m_pDebugMsg, vargs);
- if (flush)
- fflush(debugFile);
- }
- else
- {
- vprintf(debugMessages[i].m_pDebugMsg, vargs);
- }
- va_end(vargs);
- return;
- }
- }
- printf("Unrecognized error: Severity=%d; HashCode=%lu; SerialNum=%d\n", severity, hashCode, serialNum);
-} /* end EAS_ReportEx */
-
-#else
-/*----------------------------------------------------------------------------
- * EAS_Report()
- *
- * This is the error message handler. The default handler outputs error
- * messages to stdout. Modify this as needed for your system.
- *----------------------------------------------------------------------------
-*/
-void EAS_Report (int severity, const char *fmt, ...)
-{
- va_list vargs;
-
- /* check severity level */
- if (severity > severityLevel)
- return;
-
- /*lint -e{826} <allow variable args> */
- va_start(vargs, fmt);
- if (debugFile)
- {
- vfprintf(debugFile, fmt, vargs);
- if (flush)
- fflush(debugFile);
- }
- else
- {
- vprintf(fmt, vargs);
- }
- va_end(vargs);
-} /* end EAS_Report */
-
-/*----------------------------------------------------------------------------
- * EAS_ReportX()
- *
- * This is the error message handler. The default handler outputs error
- * messages to stdout. Modify this as needed for your system.
- *----------------------------------------------------------------------------
-*/
-void EAS_ReportX (int severity, const char *fmt, ...)
-{
- va_list vargs;
-
- /* check severity level */
- if (severity > severityLevel)
- return;
-
- /*lint -e{826} <allow variable args> */
- va_start(vargs, fmt);
- if (debugFile)
- {
- vfprintf(debugFile, fmt, vargs);
- if (flush)
- fflush(debugFile);
- }
- else
- {
- vprintf(fmt, vargs);
- }
- va_end(vargs);
-} /* end EAS_ReportX */
-#endif
-
-/*----------------------------------------------------------------------------
- * EAS_SetDebugLevel()
- *
- * Sets the level for debug message output
- *----------------------------------------------------------------------------
-*/
-
-void EAS_SetDebugLevel (int severity)
-{
- severityLevel = severity;
-} /* end EAS_SetDebugLevel */
-
-/*----------------------------------------------------------------------------
- * EAS_SetDebugFile()
- *
- * Redirect debugger output to the specified file.
- *----------------------------------------------------------------------------
-*/
-void EAS_SetDebugFile (void *file, int flushAfterWrite)
-{
- debugFile = (FILE*) file;
- flush = flushAfterWrite;
-} /* end EAS_SetDebugFile */
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 659 $
+ * $Date: 2007-04-24 13:36:35 -0700 (Tue, 24 Apr 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+#ifdef _lint
+#include "lint_stdlib.h"
+#else
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdarg.h>
+#endif
+
+#include "eas_report.h"
+
+static int severityLevel = 9999;
+
+/* debug file */
+static FILE *debugFile = NULL;
+int flush = 0;
+
+#ifndef _NO_DEBUG_PREPROCESSOR
+
+/* structure should have an #include for each error message header file */
+S_DEBUG_MESSAGES debugMessages[] =
+{
+#ifndef UNIFIED_DEBUG_MESSAGES
+#include "eas_config_msgs.h"
+
+
+#include "eas_host_msgs.h"
+#include "eas_hostmm_msgs.h"
+#include "eas_math_msgs.h"
+#include "eas_midi_msgs.h"
+#include "eas_mixer_msgs.h"
+#include "eas_pcm_msgs.h"
+#include "eas_public_msgs.h"
+#include "eas_smf_msgs.h"
+#include "eas_wave_msgs.h"
+#include "eas_voicemgt_msgs.h"
+
+#ifdef _FM_SYNTH
+#include "eas_fmsynth_msgs.h"
+#include "eas_fmengine_msgs.h"
+#endif
+
+#ifdef _WT_SYNTH
+#include "eas_wtsynth_msgs.h"
+#include "eas_wtengine_msgs.h"
+#endif
+
+#ifdef _ARM_TEST_MAIN
+#include "arm_main_msgs.h"
+#endif
+
+#ifdef _EAS_MAIN
+#include "eas_main_msgs.h"
+#endif
+
+#ifdef _EAS_MAIN_IPC
+#include "eas_main_ipc_msgs.h"
+#endif
+
+#ifdef _METRICS_ENABLED
+#include "eas_perf_msgs.h"
+#endif
+
+#ifdef _COMPRESSOR_ENABLED
+#include "eas_compressor_msgs.h"
+#endif
+
+#ifdef _ENHANCER_ENABLED
+#include "eas_enhancer_msgs.h"
+#endif
+
+#ifdef _WOW_ENABLED
+#include "eas_wow_msgs.h"
+#endif
+
+#ifdef _SMAF_PARSER
+#include "eas_smaf_msgs.h"
+#endif
+
+#ifdef _OTA_PARSER
+#include "eas_ota_msgs.h"
+#endif
+
+#ifdef _IMELODY_PARSER
+#include "eas_imelody_msgs.h"
+#endif
+
+#ifdef _WAVE_PARSER
+#include "eas_wavefile_msgs.h"
+#endif
+
+#if defined(_CMX_PARSER) || defined(_MFI_PARSER)
+#include "eas_cmf_msgs.h"
+#endif
+
+#if defined(_CMX_PARSER) || defined(_MFI_PARSER) || defined(_WAVE_PARSER)
+#include "eas_imaadpcm_msgs.h"
+#endif
+
+#else
+#include "eas_debugmsgs.h"
+#endif
+
+/* denotes end of error messages */
+{ 0,0,0 }
+};
+
+/*----------------------------------------------------------------------------
+ * EAS_ReportEx()
+ *
+ * This is the error message handler. The default handler outputs error
+ * messages to stdout. Modify this as needed for your system.
+ *----------------------------------------------------------------------------
+*/
+void EAS_ReportEx (int severity, unsigned long hashCode, int serialNum, ...)
+{
+ va_list vargs;
+ int i;
+
+ /* check severity level */
+ if (severity > severityLevel)
+ return;
+
+ /* find the error message and output to stdout */
+ /*lint -e{661} we check for NULL pointer - no fence post error here */
+ for (i = 0; debugMessages[i].m_pDebugMsg; i++)
+ {
+ if ((debugMessages[i].m_nHashCode == hashCode) &&
+ (debugMessages[i].m_nSerialNum == serialNum))
+ {
+ /*lint -e{826} <allow variable args> */
+ va_start(vargs, serialNum);
+ if (debugFile)
+ {
+ vfprintf(debugFile, debugMessages[i].m_pDebugMsg, vargs);
+ if (flush)
+ fflush(debugFile);
+ }
+ else
+ {
+ vprintf(debugMessages[i].m_pDebugMsg, vargs);
+ }
+ va_end(vargs);
+ return;
+ }
+ }
+ printf("Unrecognized error: Severity=%d; HashCode=%lu; SerialNum=%d\n", severity, hashCode, serialNum);
+} /* end EAS_ReportEx */
+
+#else
+/*----------------------------------------------------------------------------
+ * EAS_Report()
+ *
+ * This is the error message handler. The default handler outputs error
+ * messages to stdout. Modify this as needed for your system.
+ *----------------------------------------------------------------------------
+*/
+void EAS_Report (int severity, const char *fmt, ...)
+{
+ va_list vargs;
+
+ /* check severity level */
+ if (severity > severityLevel)
+ return;
+
+ /*lint -e{826} <allow variable args> */
+ va_start(vargs, fmt);
+ if (debugFile)
+ {
+ vfprintf(debugFile, fmt, vargs);
+ if (flush)
+ fflush(debugFile);
+ }
+ else
+ {
+ vprintf(fmt, vargs);
+ }
+ va_end(vargs);
+} /* end EAS_Report */
+
+/*----------------------------------------------------------------------------
+ * EAS_ReportX()
+ *
+ * This is the error message handler. The default handler outputs error
+ * messages to stdout. Modify this as needed for your system.
+ *----------------------------------------------------------------------------
+*/
+void EAS_ReportX (int severity, const char *fmt, ...)
+{
+ va_list vargs;
+
+ /* check severity level */
+ if (severity > severityLevel)
+ return;
+
+ /*lint -e{826} <allow variable args> */
+ va_start(vargs, fmt);
+ if (debugFile)
+ {
+ vfprintf(debugFile, fmt, vargs);
+ if (flush)
+ fflush(debugFile);
+ }
+ else
+ {
+ vprintf(fmt, vargs);
+ }
+ va_end(vargs);
+} /* end EAS_ReportX */
+#endif
+
+/*----------------------------------------------------------------------------
+ * EAS_SetDebugLevel()
+ *
+ * Sets the level for debug message output
+ *----------------------------------------------------------------------------
+*/
+
+void EAS_SetDebugLevel (int severity)
+{
+ severityLevel = severity;
+} /* end EAS_SetDebugLevel */
+
+/*----------------------------------------------------------------------------
+ * EAS_SetDebugFile()
+ *
+ * Redirect debugger output to the specified file.
+ *----------------------------------------------------------------------------
+*/
+void EAS_SetDebugFile (void *file, int flushAfterWrite)
+{
+ debugFile = (FILE*) file;
+ flush = flushAfterWrite;
+} /* end EAS_SetDebugFile */
+
diff --git a/arm-wt-22k/host_src/eas_report.h b/arm-wt-22k/host_src/eas_report.h
index 9d7c8e8..b603b12 100644
--- a/arm-wt-22k/host_src/eas_report.h
+++ b/arm-wt-22k/host_src/eas_report.h
@@ -1,15 +1,15 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_report.h
- *
- * Contents and purpose:
- * This file contains the debug message handling routines for the EAS library.
- * These routines should be modified as needed for your system.
- *
- * DO NOT MODIFY THIS FILE!
- *
- * Copyright 2005 Sonic Network Inc.
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_report.h
+ *
+ * Contents and purpose:
+ * This file contains the debug message handling routines for the EAS library.
+ * These routines should be modified as needed for your system.
+ *
+ * DO NOT MODIFY THIS FILE!
+ *
+ * Copyright 2005 Sonic Network Inc.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -22,56 +22,56 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 82 $
- * $Date: 2006-07-10 11:45:19 -0700 (Mon, 10 Jul 2006) $
- *----------------------------------------------------------------------------
-*/
-
-/* sentinel */
-#ifndef _EAS_REPORT_H
-#define _EAS_REPORT_H
-
-#define _EAS_SEVERITY_NOFILTER 0
-#define _EAS_SEVERITY_FATAL 1
-#define _EAS_SEVERITY_ERROR 2
-#define _EAS_SEVERITY_WARNING 3
-#define _EAS_SEVERITY_INFO 4
-#define _EAS_SEVERITY_DETAIL 5
-
-/* for C++ linkage */
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifndef _NO_DEBUG_PREPROCESSOR
-
-/* structure for included debug message header files */
-typedef struct
-{
- unsigned long m_nHashCode;
- int m_nSerialNum;
- char *m_pDebugMsg;
-} S_DEBUG_MESSAGES;
-
-/* debug message handling prototypes */
-extern void EAS_ReportEx (int severity, unsigned long hashCode, int serialNum, ...);
-
-#else
-
-/* these prototypes are used if the debug preprocessor is not used */
-extern void EAS_Report (int severity, const char* fmt, ...);
-extern void EAS_ReportX (int severity, const char* fmt, ...);
-
-#endif
-
-extern void EAS_SetDebugLevel (int severity);
-extern void EAS_SetDebugFile (void *file, int flushAfterWrite);
-
-#ifdef __cplusplus
-} /* end extern "C" */
-#endif
-
-#endif
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 82 $
+ * $Date: 2006-07-10 11:45:19 -0700 (Mon, 10 Jul 2006) $
+ *----------------------------------------------------------------------------
+*/
+
+/* sentinel */
+#ifndef _EAS_REPORT_H
+#define _EAS_REPORT_H
+
+#define _EAS_SEVERITY_NOFILTER 0
+#define _EAS_SEVERITY_FATAL 1
+#define _EAS_SEVERITY_ERROR 2
+#define _EAS_SEVERITY_WARNING 3
+#define _EAS_SEVERITY_INFO 4
+#define _EAS_SEVERITY_DETAIL 5
+
+/* for C++ linkage */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef _NO_DEBUG_PREPROCESSOR
+
+/* structure for included debug message header files */
+typedef struct
+{
+ unsigned long m_nHashCode;
+ int m_nSerialNum;
+ char *m_pDebugMsg;
+} S_DEBUG_MESSAGES;
+
+/* debug message handling prototypes */
+extern void EAS_ReportEx (int severity, unsigned long hashCode, int serialNum, ...);
+
+#else
+
+/* these prototypes are used if the debug preprocessor is not used */
+extern void EAS_Report (int severity, const char* fmt, ...);
+extern void EAS_ReportX (int severity, const char* fmt, ...);
+
+#endif
+
+extern void EAS_SetDebugLevel (int severity);
+extern void EAS_SetDebugFile (void *file, int flushAfterWrite);
+
+#ifdef __cplusplus
+} /* end extern "C" */
+#endif
+
+#endif
diff --git a/arm-wt-22k/host_src/eas_reverb.h b/arm-wt-22k/host_src/eas_reverb.h
index a2535fb..559abed 100644
--- a/arm-wt-22k/host_src/eas_reverb.h
+++ b/arm-wt-22k/host_src/eas_reverb.h
@@ -1,13 +1,13 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_reverb.h
- *
- * Contents and purpose:
- * Contains parameter enumerations for the Reverb effect
- *
- *
- * Copyright Sonic Network Inc. 2006
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_reverb.h
+ *
+ * Contents and purpose:
+ * Contains parameter enumerations for the Reverb effect
+ *
+ *
+ * Copyright Sonic Network Inc. 2006
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,35 +20,35 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 300 $
- * $Date: 2006-09-11 17:37:20 -0700 (Mon, 11 Sep 2006) $
- *----------------------------------------------------------------------------
-*/
-
-#ifndef _EAS_REVERB_H
-#define _EAS_REVERB_H
-
-
-/* enumerated parameter settings for Reverb effect */
-typedef enum
-{
- EAS_PARAM_REVERB_BYPASS,
- EAS_PARAM_REVERB_PRESET,
- EAS_PARAM_REVERB_WET,
- EAS_PARAM_REVERB_DRY
-} E_REVERB_PARAMS;
-
-
-typedef enum
-{
- EAS_PARAM_REVERB_LARGE_HALL,
- EAS_PARAM_REVERB_HALL,
- EAS_PARAM_REVERB_CHAMBER,
- EAS_PARAM_REVERB_ROOM,
-} E_REVERB_PRESETS;
-
-
-#endif /* _REVERB_H */
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 300 $
+ * $Date: 2006-09-11 17:37:20 -0700 (Mon, 11 Sep 2006) $
+ *----------------------------------------------------------------------------
+*/
+
+#ifndef _EAS_REVERB_H
+#define _EAS_REVERB_H
+
+
+/* enumerated parameter settings for Reverb effect */
+typedef enum
+{
+ EAS_PARAM_REVERB_BYPASS,
+ EAS_PARAM_REVERB_PRESET,
+ EAS_PARAM_REVERB_WET,
+ EAS_PARAM_REVERB_DRY
+} E_REVERB_PARAMS;
+
+
+typedef enum
+{
+ EAS_PARAM_REVERB_LARGE_HALL,
+ EAS_PARAM_REVERB_HALL,
+ EAS_PARAM_REVERB_CHAMBER,
+ EAS_PARAM_REVERB_ROOM,
+} E_REVERB_PRESETS;
+
+
+#endif /* _REVERB_H */
diff --git a/arm-wt-22k/host_src/eas_types.h b/arm-wt-22k/host_src/eas_types.h
index 5ba1e4e..d66a2b7 100644
--- a/arm-wt-22k/host_src/eas_types.h
+++ b/arm-wt-22k/host_src/eas_types.h
@@ -1,17 +1,17 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_types.h
- *
- * Contents and purpose:
- * The public interface header for the EAS synthesizer.
- *
- * This header only contains declarations that are specific
- * to this implementation.
- *
- * DO NOT MODIFY THIS FILE!
- *
- * Copyright Sonic Network Inc. 2004
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_types.h
+ *
+ * Contents and purpose:
+ * The public interface header for the EAS synthesizer.
+ *
+ * This header only contains declarations that are specific
+ * to this implementation.
+ *
+ * DO NOT MODIFY THIS FILE!
+ *
+ * Copyright Sonic Network Inc. 2004
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -24,250 +24,250 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 726 $
- * $Date: 2007-06-14 23:10:46 -0700 (Thu, 14 Jun 2007) $
- *----------------------------------------------------------------------------
-*/
-
-#ifndef _EAS_TYPES_H
-#define _EAS_TYPES_H
-
-/* EAS_RESULT return codes */
-typedef long EAS_RESULT;
-#define EAS_SUCCESS 0
-#define EAS_FAILURE -1
-#define EAS_ERROR_INVALID_MODULE -2
-#define EAS_ERROR_MALLOC_FAILED -3
-#define EAS_ERROR_FILE_POS -4
-#define EAS_ERROR_INVALID_FILE_MODE -5
-#define EAS_ERROR_FILE_SEEK -6
-#define EAS_ERROR_FILE_LENGTH -7
-#define EAS_ERROR_NOT_IMPLEMENTED -8
-#define EAS_ERROR_CLOSE_FAILED -9
-#define EAS_ERROR_FILE_OPEN_FAILED -10
-#define EAS_ERROR_INVALID_HANDLE -11
-#define EAS_ERROR_NO_MIX_BUFFER -12
-#define EAS_ERROR_PARAMETER_RANGE -13
-#define EAS_ERROR_MAX_FILES_OPEN -14
-#define EAS_ERROR_UNRECOGNIZED_FORMAT -15
-#define EAS_BUFFER_SIZE_MISMATCH -16
-#define EAS_ERROR_FILE_FORMAT -17
-#define EAS_ERROR_SMF_NOT_INITIALIZED -18
-#define EAS_ERROR_LOCATE_BEYOND_END -19
-#define EAS_ERROR_INVALID_PCM_TYPE -20
-#define EAS_ERROR_MAX_PCM_STREAMS -21
-#define EAS_ERROR_NO_VOICE_ALLOCATED -22
-#define EAS_ERROR_INVALID_CHANNEL -23
-#define EAS_ERROR_ALREADY_STOPPED -24
-#define EAS_ERROR_FILE_READ_FAILED -25
-#define EAS_ERROR_HANDLE_INTEGRITY -26
-#define EAS_ERROR_MAX_STREAMS_OPEN -27
-#define EAS_ERROR_INVALID_PARAMETER -28
-#define EAS_ERROR_FEATURE_NOT_AVAILABLE -29
-#define EAS_ERROR_SOUND_LIBRARY -30
-#define EAS_ERROR_NOT_VALID_IN_THIS_STATE -31
-#define EAS_ERROR_NO_VIRTUAL_SYNTHESIZER -32
-#define EAS_ERROR_FILE_ALREADY_OPEN -33
-#define EAS_ERROR_FILE_ALREADY_CLOSED -34
-#define EAS_ERROR_INCOMPATIBLE_VERSION -35
-#define EAS_ERROR_QUEUE_IS_FULL -36
-#define EAS_ERROR_QUEUE_IS_EMPTY -37
-#define EAS_ERROR_FEATURE_ALREADY_ACTIVE -38
-
-/* special return codes */
-#define EAS_EOF 3
-#define EAS_STREAM_BUFFERING 4
-#define EAS_BUFFER_FULL 5
-
-/* EAS_STATE return codes */
-typedef long EAS_STATE;
-typedef enum
-{
- EAS_STATE_READY = 0,
- EAS_STATE_PLAY,
- EAS_STATE_STOPPING,
- EAS_STATE_PAUSING,
- EAS_STATE_STOPPED,
- EAS_STATE_PAUSED,
- EAS_STATE_OPEN,
- EAS_STATE_ERROR,
- EAS_STATE_EMPTY
-} E_EAS_STATE;
-
-/* constants */
-#ifndef EAS_CONST
-#define EAS_CONST const
-#endif
-
-/* definition for public interface functions */
-#ifndef EAS_PUBLIC
-#define EAS_PUBLIC
-#endif
-
-/* boolean values */
-typedef unsigned EAS_BOOL;
-typedef unsigned char EAS_BOOL8;
-
-#define EAS_FALSE 0
-#define EAS_TRUE 1
-
-/* scalar variable definitions */
-typedef unsigned char EAS_U8;
-typedef signed char EAS_I8;
-typedef char EAS_CHAR;
-
-typedef unsigned short EAS_U16;
-typedef short EAS_I16;
-
-typedef unsigned long EAS_U32;
-typedef long EAS_I32;
-
-typedef unsigned EAS_UINT;
-typedef int EAS_INT;
-typedef long EAS_LONG;
-
-/* audio output type */
-typedef short EAS_PCM;
-
-/* file open modes */
-typedef EAS_I32 EAS_FILE_MODE;
-#define EAS_FILE_READ 1
-#define EAS_FILE_WRITE 2
-
-/* file locator e.g. filename or memory pointer */
-typedef struct s_eas_file_tag {
- const char* path;
- int fd;
- long long offset;
- long long length;
-} EAS_FILE, *EAS_FILE_LOCATOR;
-
-/* handle to stream */
-typedef struct s_eas_stream_tag *EAS_HANDLE;
-
-/* handle to file */
-typedef struct eas_hw_file_tag *EAS_FILE_HANDLE;
-
-/* handle for synthesizer data */
-typedef struct s_eas_data_tag *EAS_DATA_HANDLE;
-
-/* handle to persistent data for host wrapper interface */
-typedef struct eas_hw_inst_data_tag *EAS_HW_DATA_HANDLE;
-
-/* handle to sound library */
-typedef struct s_eas_sndlib_tag *EAS_SNDLIB_HANDLE;
-typedef struct s_eas_dls_tag *EAS_DLSLIB_HANDLE;
-
-/* pointer to frame buffer - used in split architecture only */
-typedef struct s_eas_frame_buffer_tag *EAS_FRAME_BUFFER_HANDLE;
-
-/* untyped pointer for instance data */
-typedef void *EAS_VOID_PTR;
-
-/* inline functions */
-#ifndef EAS_INLINE
-#if defined (__XCC__)
-#define EAS_INLINE __inline__
-#elif defined (__GNUC__)
-#define EAS_INLINE inline static
-#else
-#define EAS_INLINE __inline
-#endif
-#endif
-
-/* define NULL value */
-#ifndef NULL
-#define NULL 0
-#endif
-
-/* metadata types for metadata return codes */
-typedef enum
-{
- EAS_METADATA_UNKNOWN = 0,
- EAS_METADATA_TITLE,
- EAS_METADATA_AUTHOR,
- EAS_METADATA_COPYRIGHT,
- EAS_METADATA_LYRIC,
- EAS_METADATA_TEXT
-} E_EAS_METADATA_TYPE;
-
-/* metadata callback function */
-typedef void (*EAS_METADATA_CBFUNC) (E_EAS_METADATA_TYPE metaDataType, char *metaDataBuf, EAS_VOID_PTR pUserData);
-
-/* file types for metadata return codes */
-typedef enum
-{
- EAS_FILE_UNKNOWN = 0,
- EAS_FILE_SMF0,
- EAS_FILE_SMF1,
- EAS_FILE_SMAF_UNKNOWN,
- EAS_FILE_SMAF_MA2,
- EAS_FILE_SMAF_MA3,
- EAS_FILE_SMAF_MA5,
- EAS_FILE_CMX,
- EAS_FILE_MFI,
- EAS_FILE_OTA,
- EAS_FILE_IMELODY,
- EAS_FILE_RTTTL,
- EAS_FILE_XMF0,
- EAS_FILE_XMF1,
- EAS_FILE_WAVE_PCM,
- EAS_FILE_WAVE_IMA_ADPCM,
- EAS_FILE_MMAPI_TONE_CONTROL
-} E_EAS_FILE_TYPE;
-
-/* enumeration for synthesizers */
-typedef enum
-{
- EAS_MCU_SYNTH = 0,
- EAS_DSP_SYNTH
-} E_SYNTHESIZER;
-
-/* external audio callback program change */
-typedef struct s_ext_audio_prg_chg_tag
-{
- EAS_U16 bank;
- EAS_U8 program;
- EAS_U8 channel;
-} S_EXT_AUDIO_PRG_CHG;
-
-/* external audio callback event */
-typedef struct s_ext_audio_event_tag
-{
- EAS_U8 channel;
- EAS_U8 note;
- EAS_U8 velocity;
- EAS_BOOL8 noteOn;
-} S_EXT_AUDIO_EVENT;
-
-typedef struct s_midi_controllers_tag
-{
- EAS_U8 modWheel; /* CC1 */
- EAS_U8 volume; /* CC7 */
- EAS_U8 pan; /* CC10 */
- EAS_U8 expression; /* CC11 */
- EAS_U8 channelPressure; /* MIDI channel pressure */
-
-#ifdef _REVERB
- EAS_U8 reverbSend; /* CC91 */
-#endif
-
-#ifdef _CHORUS
- EAS_U8 chorusSend; /* CC93 */
-#endif
-} S_MIDI_CONTROLLERS;
-
-/* iMode play modes enumeration for EAS_SetPlayMode */
-typedef enum
-{
- IMODE_PLAY_ALL = 0,
- IMODE_PLAY_PARTIAL
-} E_I_MODE_PLAY_MODE;
-
-typedef EAS_BOOL (*EAS_EXT_PRG_CHG_FUNC) (EAS_VOID_PTR pInstData, S_EXT_AUDIO_PRG_CHG *pPrgChg);
-typedef EAS_BOOL (*EAS_EXT_EVENT_FUNC) (EAS_VOID_PTR pInstData, S_EXT_AUDIO_EVENT *pEvent);
-
-#endif /* #ifndef _EAS_TYPES_H */
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 726 $
+ * $Date: 2007-06-14 23:10:46 -0700 (Thu, 14 Jun 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+#ifndef _EAS_TYPES_H
+#define _EAS_TYPES_H
+
+/* EAS_RESULT return codes */
+typedef long EAS_RESULT;
+#define EAS_SUCCESS 0
+#define EAS_FAILURE -1
+#define EAS_ERROR_INVALID_MODULE -2
+#define EAS_ERROR_MALLOC_FAILED -3
+#define EAS_ERROR_FILE_POS -4
+#define EAS_ERROR_INVALID_FILE_MODE -5
+#define EAS_ERROR_FILE_SEEK -6
+#define EAS_ERROR_FILE_LENGTH -7
+#define EAS_ERROR_NOT_IMPLEMENTED -8
+#define EAS_ERROR_CLOSE_FAILED -9
+#define EAS_ERROR_FILE_OPEN_FAILED -10
+#define EAS_ERROR_INVALID_HANDLE -11
+#define EAS_ERROR_NO_MIX_BUFFER -12
+#define EAS_ERROR_PARAMETER_RANGE -13
+#define EAS_ERROR_MAX_FILES_OPEN -14
+#define EAS_ERROR_UNRECOGNIZED_FORMAT -15
+#define EAS_BUFFER_SIZE_MISMATCH -16
+#define EAS_ERROR_FILE_FORMAT -17
+#define EAS_ERROR_SMF_NOT_INITIALIZED -18
+#define EAS_ERROR_LOCATE_BEYOND_END -19
+#define EAS_ERROR_INVALID_PCM_TYPE -20
+#define EAS_ERROR_MAX_PCM_STREAMS -21
+#define EAS_ERROR_NO_VOICE_ALLOCATED -22
+#define EAS_ERROR_INVALID_CHANNEL -23
+#define EAS_ERROR_ALREADY_STOPPED -24
+#define EAS_ERROR_FILE_READ_FAILED -25
+#define EAS_ERROR_HANDLE_INTEGRITY -26
+#define EAS_ERROR_MAX_STREAMS_OPEN -27
+#define EAS_ERROR_INVALID_PARAMETER -28
+#define EAS_ERROR_FEATURE_NOT_AVAILABLE -29
+#define EAS_ERROR_SOUND_LIBRARY -30
+#define EAS_ERROR_NOT_VALID_IN_THIS_STATE -31
+#define EAS_ERROR_NO_VIRTUAL_SYNTHESIZER -32
+#define EAS_ERROR_FILE_ALREADY_OPEN -33
+#define EAS_ERROR_FILE_ALREADY_CLOSED -34
+#define EAS_ERROR_INCOMPATIBLE_VERSION -35
+#define EAS_ERROR_QUEUE_IS_FULL -36
+#define EAS_ERROR_QUEUE_IS_EMPTY -37
+#define EAS_ERROR_FEATURE_ALREADY_ACTIVE -38
+
+/* special return codes */
+#define EAS_EOF 3
+#define EAS_STREAM_BUFFERING 4
+#define EAS_BUFFER_FULL 5
+
+/* EAS_STATE return codes */
+typedef long EAS_STATE;
+typedef enum
+{
+ EAS_STATE_READY = 0,
+ EAS_STATE_PLAY,
+ EAS_STATE_STOPPING,
+ EAS_STATE_PAUSING,
+ EAS_STATE_STOPPED,
+ EAS_STATE_PAUSED,
+ EAS_STATE_OPEN,
+ EAS_STATE_ERROR,
+ EAS_STATE_EMPTY
+} E_EAS_STATE;
+
+/* constants */
+#ifndef EAS_CONST
+#define EAS_CONST const
+#endif
+
+/* definition for public interface functions */
+#ifndef EAS_PUBLIC
+#define EAS_PUBLIC
+#endif
+
+/* boolean values */
+typedef unsigned EAS_BOOL;
+typedef unsigned char EAS_BOOL8;
+
+#define EAS_FALSE 0
+#define EAS_TRUE 1
+
+/* scalar variable definitions */
+typedef unsigned char EAS_U8;
+typedef signed char EAS_I8;
+typedef char EAS_CHAR;
+
+typedef unsigned short EAS_U16;
+typedef short EAS_I16;
+
+typedef unsigned long EAS_U32;
+typedef long EAS_I32;
+
+typedef unsigned EAS_UINT;
+typedef int EAS_INT;
+typedef long EAS_LONG;
+
+/* audio output type */
+typedef short EAS_PCM;
+
+/* file open modes */
+typedef EAS_I32 EAS_FILE_MODE;
+#define EAS_FILE_READ 1
+#define EAS_FILE_WRITE 2
+
+/* file locator e.g. filename or memory pointer */
+typedef struct s_eas_file_tag {
+ const char* path;
+ int fd;
+ long long offset;
+ long long length;
+} EAS_FILE, *EAS_FILE_LOCATOR;
+
+/* handle to stream */
+typedef struct s_eas_stream_tag *EAS_HANDLE;
+
+/* handle to file */
+typedef struct eas_hw_file_tag *EAS_FILE_HANDLE;
+
+/* handle for synthesizer data */
+typedef struct s_eas_data_tag *EAS_DATA_HANDLE;
+
+/* handle to persistent data for host wrapper interface */
+typedef struct eas_hw_inst_data_tag *EAS_HW_DATA_HANDLE;
+
+/* handle to sound library */
+typedef struct s_eas_sndlib_tag *EAS_SNDLIB_HANDLE;
+typedef struct s_eas_dls_tag *EAS_DLSLIB_HANDLE;
+
+/* pointer to frame buffer - used in split architecture only */
+typedef struct s_eas_frame_buffer_tag *EAS_FRAME_BUFFER_HANDLE;
+
+/* untyped pointer for instance data */
+typedef void *EAS_VOID_PTR;
+
+/* inline functions */
+#ifndef EAS_INLINE
+#if defined (__XCC__)
+#define EAS_INLINE __inline__
+#elif defined (__GNUC__)
+#define EAS_INLINE inline static
+#else
+#define EAS_INLINE __inline
+#endif
+#endif
+
+/* define NULL value */
+#ifndef NULL
+#define NULL 0
+#endif
+
+/* metadata types for metadata return codes */
+typedef enum
+{
+ EAS_METADATA_UNKNOWN = 0,
+ EAS_METADATA_TITLE,
+ EAS_METADATA_AUTHOR,
+ EAS_METADATA_COPYRIGHT,
+ EAS_METADATA_LYRIC,
+ EAS_METADATA_TEXT
+} E_EAS_METADATA_TYPE;
+
+/* metadata callback function */
+typedef void (*EAS_METADATA_CBFUNC) (E_EAS_METADATA_TYPE metaDataType, char *metaDataBuf, EAS_VOID_PTR pUserData);
+
+/* file types for metadata return codes */
+typedef enum
+{
+ EAS_FILE_UNKNOWN = 0,
+ EAS_FILE_SMF0,
+ EAS_FILE_SMF1,
+ EAS_FILE_SMAF_UNKNOWN,
+ EAS_FILE_SMAF_MA2,
+ EAS_FILE_SMAF_MA3,
+ EAS_FILE_SMAF_MA5,
+ EAS_FILE_CMX,
+ EAS_FILE_MFI,
+ EAS_FILE_OTA,
+ EAS_FILE_IMELODY,
+ EAS_FILE_RTTTL,
+ EAS_FILE_XMF0,
+ EAS_FILE_XMF1,
+ EAS_FILE_WAVE_PCM,
+ EAS_FILE_WAVE_IMA_ADPCM,
+ EAS_FILE_MMAPI_TONE_CONTROL
+} E_EAS_FILE_TYPE;
+
+/* enumeration for synthesizers */
+typedef enum
+{
+ EAS_MCU_SYNTH = 0,
+ EAS_DSP_SYNTH
+} E_SYNTHESIZER;
+
+/* external audio callback program change */
+typedef struct s_ext_audio_prg_chg_tag
+{
+ EAS_U16 bank;
+ EAS_U8 program;
+ EAS_U8 channel;
+} S_EXT_AUDIO_PRG_CHG;
+
+/* external audio callback event */
+typedef struct s_ext_audio_event_tag
+{
+ EAS_U8 channel;
+ EAS_U8 note;
+ EAS_U8 velocity;
+ EAS_BOOL8 noteOn;
+} S_EXT_AUDIO_EVENT;
+
+typedef struct s_midi_controllers_tag
+{
+ EAS_U8 modWheel; /* CC1 */
+ EAS_U8 volume; /* CC7 */
+ EAS_U8 pan; /* CC10 */
+ EAS_U8 expression; /* CC11 */
+ EAS_U8 channelPressure; /* MIDI channel pressure */
+
+#ifdef _REVERB
+ EAS_U8 reverbSend; /* CC91 */
+#endif
+
+#ifdef _CHORUS
+ EAS_U8 chorusSend; /* CC93 */
+#endif
+} S_MIDI_CONTROLLERS;
+
+/* iMode play modes enumeration for EAS_SetPlayMode */
+typedef enum
+{
+ IMODE_PLAY_ALL = 0,
+ IMODE_PLAY_PARTIAL
+} E_I_MODE_PLAY_MODE;
+
+typedef EAS_BOOL (*EAS_EXT_PRG_CHG_FUNC) (EAS_VOID_PTR pInstData, S_EXT_AUDIO_PRG_CHG *pPrgChg);
+typedef EAS_BOOL (*EAS_EXT_EVENT_FUNC) (EAS_VOID_PTR pInstData, S_EXT_AUDIO_EVENT *pEvent);
+
+#endif /* #ifndef _EAS_TYPES_H */
diff --git a/arm-wt-22k/host_src/eas_wave.c b/arm-wt-22k/host_src/eas_wave.c
index 02fed6e..4f6ffbd 100644
--- a/arm-wt-22k/host_src/eas_wave.c
+++ b/arm-wt-22k/host_src/eas_wave.c
@@ -1,13 +1,13 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_wave.c
- *
- * Contents and purpose:
- * This module contains .WAV file functions for the EAS synthesizer
- * test harness.
- *
- * Copyright Sonic Network Inc. 2005
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_wave.c
+ *
+ * Contents and purpose:
+ * This module contains .WAV file functions for the EAS synthesizer
+ * test harness.
+ *
+ * Copyright Sonic Network Inc. 2005
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,404 +20,404 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 658 $
- * $Date: 2007-04-24 13:35:49 -0700 (Tue, 24 Apr 2007) $
- *----------------------------------------------------------------------------
-*/
-
-/* lint complaints about most C library headers, so we use our own during lint step */
-#ifdef _lint
-#include "lint_stdlib.h"
-#else
-#include <stdio.h>
-#include <stdlib.h>
-#endif
-
-#include "eas_wave.h"
-
-/* .WAV file format tags */
-const EAS_U32 riffTag = 0x46464952;
-const EAS_U32 waveTag = 0x45564157;
-const EAS_U32 fmtTag = 0x20746d66;
-const EAS_U32 dataTag = 0x61746164;
-
-#ifdef _BIG_ENDIAN
-/*----------------------------------------------------------------------------
- * FlipDWord()
- *----------------------------------------------------------------------------
- * Purpose: Endian flip a DWORD for big-endian processors
- *
- * Inputs:
- *
- * Outputs:
- *
- *----------------------------------------------------------------------------
-*/
-static void FlipDWord (EAS_U32 *pValue)
-{
- EAS_U8 *p;
- EAS_U32 temp;
-
- p = (EAS_U8*) pValue;
- temp = (((((p[3] << 8) | p[2]) << 8) | p[1]) << 8) | p[0];
- *pValue = temp;
-}
-
-/*----------------------------------------------------------------------------
- * FlipWord()
- *----------------------------------------------------------------------------
- * Purpose: Endian flip a WORD for big-endian processors
- *
- * Inputs:
- *
- * Outputs:
- *
- *----------------------------------------------------------------------------
-*/
-static void FlipWord (EAS_U16 *pValue)
-{
- EAS_U8 *p;
- EAS_U16 temp;
-
- p = (EAS_U8*) pValue;
- temp = (p[1] << 8) | p[0];
- *pValue = temp;
-}
-
-/*----------------------------------------------------------------------------
- * FlipWaveHeader()
- *----------------------------------------------------------------------------
- * Purpose: Endian flip the wave header for big-endian processors
- *
- * Inputs:
- *
- * Outputs:
- *
- *----------------------------------------------------------------------------
-*/
-static void FlipWaveHeader (WAVE_HEADER *p)
-{
-
- FlipDWord(&p->nRiffTag);
- FlipDWord(&p->nRiffSize);
- FlipDWord(&p->nWaveTag);
- FlipDWord(&p->nFmtTag);
- FlipDWord(&p->nFmtSize);
- FlipDWord(&p->nDataTag);
- FlipDWord(&p->nDataSize);
- FlipWord(&p->fc.wFormatTag);
- FlipWord(&p->fc.nChannels);
- FlipDWord(&p->fc.nSamplesPerSec);
- FlipDWord(&p->fc.nAvgBytesPerSec);
- FlipWord(&p->fc.nBlockAlign);
- FlipWord(&p->fc.wBitsPerSample);
-
-}
-#endif
-
-/*----------------------------------------------------------------------------
- * WaveFileCreate()
- *----------------------------------------------------------------------------
- * Purpose: Opens a wave file for writing and writes the header
- *
- * Inputs:
- *
- * Outputs:
- *
- *----------------------------------------------------------------------------
-*/
-
-WAVE_FILE *WaveFileCreate (const char *filename, EAS_I32 nChannels, EAS_I32 nSamplesPerSec, EAS_I32 wBitsPerSample)
-{
- WAVE_FILE *wFile;
-
- /* allocate memory */
- wFile = malloc(sizeof(WAVE_FILE));
- if (!wFile)
- return NULL;
- wFile->write = EAS_TRUE;
-
- /* create the file */
- wFile->file = fopen(filename,"wb");
- if (!wFile->file)
- {
- free(wFile);
- return NULL;
- }
-
- /* initialize PCM format .WAV file header */
- wFile->wh.nRiffTag = riffTag;
- wFile->wh.nRiffSize = sizeof(WAVE_HEADER) - 8;
- wFile->wh.nWaveTag = waveTag;
- wFile->wh.nFmtTag = fmtTag;
- wFile->wh.nFmtSize = sizeof(FMT_CHUNK);
-
- /* initalize 'fmt' chunk */
- wFile->wh.fc.wFormatTag = 1;
- wFile->wh.fc.nChannels = (EAS_U16) nChannels;
- wFile->wh.fc.nSamplesPerSec = (EAS_U32) nSamplesPerSec;
- wFile->wh.fc.wBitsPerSample = (EAS_U16) wBitsPerSample;
- wFile->wh.fc.nBlockAlign = (EAS_U16) (nChannels * (EAS_U16) (wBitsPerSample / 8));
- wFile->wh.fc.nAvgBytesPerSec = wFile->wh.fc.nBlockAlign * (EAS_U32) nSamplesPerSec;
-
- /* initialize 'data' chunk */
- wFile->wh.nDataTag = dataTag;
- wFile->wh.nDataSize = 0;
-
-#ifdef _BIG_ENDIAN
- FlipWaveHeader(&wFile->wh);
-#endif
-
- /* write the header */
- if (fwrite(&wFile->wh, sizeof(WAVE_HEADER), 1, wFile->file) != 1)
- {
- fclose(wFile->file);
- free(wFile);
- return NULL;
- }
-
-#ifdef _BIG_ENDIAN
- FlipWaveHeader(&wFile->wh);
-#endif
-
- /* return the file handle */
- return wFile;
-} /* end WaveFileCreate */
-
-/*----------------------------------------------------------------------------
- * WaveFileWrite()
- *----------------------------------------------------------------------------
- * Purpose: Writes data to the wave file
- *
- * Inputs:
- *
- * Outputs:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_I32 WaveFileWrite (WAVE_FILE *wFile, void *buffer, EAS_I32 n)
-{
- EAS_I32 count;
-
- /* make sure we have an open file */
- if (wFile == NULL)
- {
- return 0;
- }
-
-#ifdef _BIG_ENDIAN
- {
- EAS_I32 i;
- EAS_U16 *p;
- p = buffer;
- i = n >> 1;
- while (i--)
- FlipWord(p++);
- }
-#endif
-
- /* write the data */
- count = (EAS_I32) fwrite(buffer, 1, (size_t) n, wFile->file);
-
- /* add the number of bytes written */
- wFile->wh.nRiffSize += (EAS_U32) count;
- wFile->wh.nDataSize += (EAS_U32) count;
-
- /* return the count of bytes written */
- return count;
-} /* end WriteWaveHeader */
-
-/*----------------------------------------------------------------------------
- * WaveFileClose()
- *----------------------------------------------------------------------------
- * Purpose: Opens a wave file for writing and writes the header
- *
- * Inputs:
- *
- * Outputs:
- *
- *----------------------------------------------------------------------------
-*/
-
-EAS_BOOL WaveFileClose (WAVE_FILE *wFile)
-{
- EAS_I32 count = 1;
-
- /* return to beginning of file and write the header */
- if (wFile->write)
- {
- if (fseek(wFile->file, 0L, SEEK_SET) == 0)
- {
-
-#ifdef _BIG_ENDIAN
- FlipWaveHeader(&wFile->wh);
-#endif
- count = (EAS_I32) fwrite(&wFile->wh, sizeof(WAVE_HEADER), 1, wFile->file);
-#ifdef _BIG_ENDIAN
- FlipWaveHeader(&wFile->wh);
-#endif
- }
- }
-
- /* close the file */
- if (fclose(wFile->file) != 0)
- count = 0;
-
- /* free the memory */
- free(wFile);
-
- /* return the file handle */
- return (count == 1 ? EAS_TRUE : EAS_FALSE);
-} /* end WaveFileClose */
-
-#ifdef _WAVE_FILE_READ
-#ifdef _BIG_ENDIAN
-#error "WaveFileOpen not currently supported on big-endian processors"
-#endif
-/*----------------------------------------------------------------------------
- * WaveFileOpen()
- *----------------------------------------------------------------------------
- * Purpose: Opens a wave file for reading and reads the header
- *
- * Inputs:
- *
- * Outputs:
- *
- *----------------------------------------------------------------------------
-*/
-
-WAVE_FILE *WaveFileOpen (const char *filename)
-{
- WAVE_FILE *wFile;
- struct
- {
- EAS_U32 tag;
- EAS_U32 size;
- } chunk;
- EAS_U32 tag;
- EAS_I32 startChunkPos;
- EAS_INT state;
- EAS_BOOL done;
-
- /* allocate memory */
- wFile = malloc(sizeof(WAVE_FILE));
- if (!wFile)
- return NULL;
-
- /* open the file */
- wFile->write = EAS_FALSE;
- wFile->file = fopen(filename,"rb");
- if (!wFile->file)
- {
- free(wFile);
- return NULL;
- }
-
- /* make lint happy */
- chunk.tag = chunk.size = 0;
- startChunkPos = 0;
-
- /* read the RIFF tag and file size */
- state = 0;
- done = EAS_FALSE;
- while (!done)
- {
-
- switch(state)
- {
- /* read the RIFF tag */
- case 0:
- if (fread(&chunk, sizeof(chunk), 1, wFile->file) != 1)
- done = EAS_TRUE;
- else
- {
- if (chunk.tag != riffTag)
- done = EAS_TRUE;
- else
- state++;
- }
- break;
-
- /* read the WAVE tag */
- case 1:
- if (fread(&tag, sizeof(tag), 1, wFile->file) != 1)
- done = EAS_TRUE;
- else
- {
- if (tag != waveTag)
- done = EAS_TRUE;
- else
- state++;
- }
- break;
-
- /* looking for fmt chunk */
- case 2:
- if (fread(&chunk, sizeof(chunk), 1, wFile->file) != 1)
- done = EAS_TRUE;
- else
- {
- startChunkPos = ftell(wFile->file);
-
- /* not fmt tag, skip it */
- if (chunk.tag != fmtTag)
- fseek(wFile->file, startChunkPos + (EAS_I32) chunk.size, SEEK_SET);
- else
- state++;
- }
- break;
-
- /* read fmt chunk */
- case 3:
- if (fread(&wFile->wh.fc, sizeof(FMT_CHUNK), 1, wFile->file) != 1)
- done = EAS_TRUE;
- else
- {
- fseek(wFile->file, startChunkPos + (EAS_I32) chunk.size, SEEK_SET);
- state++;
- }
- break;
-
- /* looking for data chunk */
- case 4:
- if (fread(&chunk, sizeof(chunk), 1, wFile->file) != 1)
- done = EAS_TRUE;
- else
- {
- startChunkPos = ftell(wFile->file);
-
- /* not data tag, skip it */
- if (chunk.tag != dataTag)
- fseek(wFile->file, startChunkPos + (EAS_I32) chunk.size, SEEK_SET);
- else
- {
- wFile->dataSize = chunk.size;
- state++;
- done = EAS_TRUE;
- }
- }
- break;
-
- default:
- done = EAS_TRUE;
- break;
- }
- }
-
- /* if not final state, an error occurred */
- if (state != 5)
- {
- fclose(wFile->file);
- free(wFile);
- return NULL;
- }
-
- /* return the file handle */
- return wFile;
-} /* end WaveFileOpen */
-#endif
-
-
-
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 658 $
+ * $Date: 2007-04-24 13:35:49 -0700 (Tue, 24 Apr 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+/* lint complaints about most C library headers, so we use our own during lint step */
+#ifdef _lint
+#include "lint_stdlib.h"
+#else
+#include <stdio.h>
+#include <stdlib.h>
+#endif
+
+#include "eas_wave.h"
+
+/* .WAV file format tags */
+const EAS_U32 riffTag = 0x46464952;
+const EAS_U32 waveTag = 0x45564157;
+const EAS_U32 fmtTag = 0x20746d66;
+const EAS_U32 dataTag = 0x61746164;
+
+#ifdef _BIG_ENDIAN
+/*----------------------------------------------------------------------------
+ * FlipDWord()
+ *----------------------------------------------------------------------------
+ * Purpose: Endian flip a DWORD for big-endian processors
+ *
+ * Inputs:
+ *
+ * Outputs:
+ *
+ *----------------------------------------------------------------------------
+*/
+static void FlipDWord (EAS_U32 *pValue)
+{
+ EAS_U8 *p;
+ EAS_U32 temp;
+
+ p = (EAS_U8*) pValue;
+ temp = (((((p[3] << 8) | p[2]) << 8) | p[1]) << 8) | p[0];
+ *pValue = temp;
+}
+
+/*----------------------------------------------------------------------------
+ * FlipWord()
+ *----------------------------------------------------------------------------
+ * Purpose: Endian flip a WORD for big-endian processors
+ *
+ * Inputs:
+ *
+ * Outputs:
+ *
+ *----------------------------------------------------------------------------
+*/
+static void FlipWord (EAS_U16 *pValue)
+{
+ EAS_U8 *p;
+ EAS_U16 temp;
+
+ p = (EAS_U8*) pValue;
+ temp = (p[1] << 8) | p[0];
+ *pValue = temp;
+}
+
+/*----------------------------------------------------------------------------
+ * FlipWaveHeader()
+ *----------------------------------------------------------------------------
+ * Purpose: Endian flip the wave header for big-endian processors
+ *
+ * Inputs:
+ *
+ * Outputs:
+ *
+ *----------------------------------------------------------------------------
+*/
+static void FlipWaveHeader (WAVE_HEADER *p)
+{
+
+ FlipDWord(&p->nRiffTag);
+ FlipDWord(&p->nRiffSize);
+ FlipDWord(&p->nWaveTag);
+ FlipDWord(&p->nFmtTag);
+ FlipDWord(&p->nFmtSize);
+ FlipDWord(&p->nDataTag);
+ FlipDWord(&p->nDataSize);
+ FlipWord(&p->fc.wFormatTag);
+ FlipWord(&p->fc.nChannels);
+ FlipDWord(&p->fc.nSamplesPerSec);
+ FlipDWord(&p->fc.nAvgBytesPerSec);
+ FlipWord(&p->fc.nBlockAlign);
+ FlipWord(&p->fc.wBitsPerSample);
+
+}
+#endif
+
+/*----------------------------------------------------------------------------
+ * WaveFileCreate()
+ *----------------------------------------------------------------------------
+ * Purpose: Opens a wave file for writing and writes the header
+ *
+ * Inputs:
+ *
+ * Outputs:
+ *
+ *----------------------------------------------------------------------------
+*/
+
+WAVE_FILE *WaveFileCreate (const char *filename, EAS_I32 nChannels, EAS_I32 nSamplesPerSec, EAS_I32 wBitsPerSample)
+{
+ WAVE_FILE *wFile;
+
+ /* allocate memory */
+ wFile = malloc(sizeof(WAVE_FILE));
+ if (!wFile)
+ return NULL;
+ wFile->write = EAS_TRUE;
+
+ /* create the file */
+ wFile->file = fopen(filename,"wb");
+ if (!wFile->file)
+ {
+ free(wFile);
+ return NULL;
+ }
+
+ /* initialize PCM format .WAV file header */
+ wFile->wh.nRiffTag = riffTag;
+ wFile->wh.nRiffSize = sizeof(WAVE_HEADER) - 8;
+ wFile->wh.nWaveTag = waveTag;
+ wFile->wh.nFmtTag = fmtTag;
+ wFile->wh.nFmtSize = sizeof(FMT_CHUNK);
+
+ /* initalize 'fmt' chunk */
+ wFile->wh.fc.wFormatTag = 1;
+ wFile->wh.fc.nChannels = (EAS_U16) nChannels;
+ wFile->wh.fc.nSamplesPerSec = (EAS_U32) nSamplesPerSec;
+ wFile->wh.fc.wBitsPerSample = (EAS_U16) wBitsPerSample;
+ wFile->wh.fc.nBlockAlign = (EAS_U16) (nChannels * (EAS_U16) (wBitsPerSample / 8));
+ wFile->wh.fc.nAvgBytesPerSec = wFile->wh.fc.nBlockAlign * (EAS_U32) nSamplesPerSec;
+
+ /* initialize 'data' chunk */
+ wFile->wh.nDataTag = dataTag;
+ wFile->wh.nDataSize = 0;
+
+#ifdef _BIG_ENDIAN
+ FlipWaveHeader(&wFile->wh);
+#endif
+
+ /* write the header */
+ if (fwrite(&wFile->wh, sizeof(WAVE_HEADER), 1, wFile->file) != 1)
+ {
+ fclose(wFile->file);
+ free(wFile);
+ return NULL;
+ }
+
+#ifdef _BIG_ENDIAN
+ FlipWaveHeader(&wFile->wh);
+#endif
+
+ /* return the file handle */
+ return wFile;
+} /* end WaveFileCreate */
+
+/*----------------------------------------------------------------------------
+ * WaveFileWrite()
+ *----------------------------------------------------------------------------
+ * Purpose: Writes data to the wave file
+ *
+ * Inputs:
+ *
+ * Outputs:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_I32 WaveFileWrite (WAVE_FILE *wFile, void *buffer, EAS_I32 n)
+{
+ EAS_I32 count;
+
+ /* make sure we have an open file */
+ if (wFile == NULL)
+ {
+ return 0;
+ }
+
+#ifdef _BIG_ENDIAN
+ {
+ EAS_I32 i;
+ EAS_U16 *p;
+ p = buffer;
+ i = n >> 1;
+ while (i--)
+ FlipWord(p++);
+ }
+#endif
+
+ /* write the data */
+ count = (EAS_I32) fwrite(buffer, 1, (size_t) n, wFile->file);
+
+ /* add the number of bytes written */
+ wFile->wh.nRiffSize += (EAS_U32) count;
+ wFile->wh.nDataSize += (EAS_U32) count;
+
+ /* return the count of bytes written */
+ return count;
+} /* end WriteWaveHeader */
+
+/*----------------------------------------------------------------------------
+ * WaveFileClose()
+ *----------------------------------------------------------------------------
+ * Purpose: Opens a wave file for writing and writes the header
+ *
+ * Inputs:
+ *
+ * Outputs:
+ *
+ *----------------------------------------------------------------------------
+*/
+
+EAS_BOOL WaveFileClose (WAVE_FILE *wFile)
+{
+ EAS_I32 count = 1;
+
+ /* return to beginning of file and write the header */
+ if (wFile->write)
+ {
+ if (fseek(wFile->file, 0L, SEEK_SET) == 0)
+ {
+
+#ifdef _BIG_ENDIAN
+ FlipWaveHeader(&wFile->wh);
+#endif
+ count = (EAS_I32) fwrite(&wFile->wh, sizeof(WAVE_HEADER), 1, wFile->file);
+#ifdef _BIG_ENDIAN
+ FlipWaveHeader(&wFile->wh);
+#endif
+ }
+ }
+
+ /* close the file */
+ if (fclose(wFile->file) != 0)
+ count = 0;
+
+ /* free the memory */
+ free(wFile);
+
+ /* return the file handle */
+ return (count == 1 ? EAS_TRUE : EAS_FALSE);
+} /* end WaveFileClose */
+
+#ifdef _WAVE_FILE_READ
+#ifdef _BIG_ENDIAN
+#error "WaveFileOpen not currently supported on big-endian processors"
+#endif
+/*----------------------------------------------------------------------------
+ * WaveFileOpen()
+ *----------------------------------------------------------------------------
+ * Purpose: Opens a wave file for reading and reads the header
+ *
+ * Inputs:
+ *
+ * Outputs:
+ *
+ *----------------------------------------------------------------------------
+*/
+
+WAVE_FILE *WaveFileOpen (const char *filename)
+{
+ WAVE_FILE *wFile;
+ struct
+ {
+ EAS_U32 tag;
+ EAS_U32 size;
+ } chunk;
+ EAS_U32 tag;
+ EAS_I32 startChunkPos;
+ EAS_INT state;
+ EAS_BOOL done;
+
+ /* allocate memory */
+ wFile = malloc(sizeof(WAVE_FILE));
+ if (!wFile)
+ return NULL;
+
+ /* open the file */
+ wFile->write = EAS_FALSE;
+ wFile->file = fopen(filename,"rb");
+ if (!wFile->file)
+ {
+ free(wFile);
+ return NULL;
+ }
+
+ /* make lint happy */
+ chunk.tag = chunk.size = 0;
+ startChunkPos = 0;
+
+ /* read the RIFF tag and file size */
+ state = 0;
+ done = EAS_FALSE;
+ while (!done)
+ {
+
+ switch(state)
+ {
+ /* read the RIFF tag */
+ case 0:
+ if (fread(&chunk, sizeof(chunk), 1, wFile->file) != 1)
+ done = EAS_TRUE;
+ else
+ {
+ if (chunk.tag != riffTag)
+ done = EAS_TRUE;
+ else
+ state++;
+ }
+ break;
+
+ /* read the WAVE tag */
+ case 1:
+ if (fread(&tag, sizeof(tag), 1, wFile->file) != 1)
+ done = EAS_TRUE;
+ else
+ {
+ if (tag != waveTag)
+ done = EAS_TRUE;
+ else
+ state++;
+ }
+ break;
+
+ /* looking for fmt chunk */
+ case 2:
+ if (fread(&chunk, sizeof(chunk), 1, wFile->file) != 1)
+ done = EAS_TRUE;
+ else
+ {
+ startChunkPos = ftell(wFile->file);
+
+ /* not fmt tag, skip it */
+ if (chunk.tag != fmtTag)
+ fseek(wFile->file, startChunkPos + (EAS_I32) chunk.size, SEEK_SET);
+ else
+ state++;
+ }
+ break;
+
+ /* read fmt chunk */
+ case 3:
+ if (fread(&wFile->wh.fc, sizeof(FMT_CHUNK), 1, wFile->file) != 1)
+ done = EAS_TRUE;
+ else
+ {
+ fseek(wFile->file, startChunkPos + (EAS_I32) chunk.size, SEEK_SET);
+ state++;
+ }
+ break;
+
+ /* looking for data chunk */
+ case 4:
+ if (fread(&chunk, sizeof(chunk), 1, wFile->file) != 1)
+ done = EAS_TRUE;
+ else
+ {
+ startChunkPos = ftell(wFile->file);
+
+ /* not data tag, skip it */
+ if (chunk.tag != dataTag)
+ fseek(wFile->file, startChunkPos + (EAS_I32) chunk.size, SEEK_SET);
+ else
+ {
+ wFile->dataSize = chunk.size;
+ state++;
+ done = EAS_TRUE;
+ }
+ }
+ break;
+
+ default:
+ done = EAS_TRUE;
+ break;
+ }
+ }
+
+ /* if not final state, an error occurred */
+ if (state != 5)
+ {
+ fclose(wFile->file);
+ free(wFile);
+ return NULL;
+ }
+
+ /* return the file handle */
+ return wFile;
+} /* end WaveFileOpen */
+#endif
+
+
+
diff --git a/arm-wt-22k/host_src/eas_wave.h b/arm-wt-22k/host_src/eas_wave.h
index ca388f5..968782f 100644
--- a/arm-wt-22k/host_src/eas_wave.h
+++ b/arm-wt-22k/host_src/eas_wave.h
@@ -1,14 +1,14 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_wave.h
- *
- * Contents and purpose:
- * Writes output to a .WAV file
- *
- * DO NOT MODIFY THIS FILE!
- *
- * Copyright Sonic Network Inc. 2005
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_wave.h
+ *
+ * Contents and purpose:
+ * Writes output to a .WAV file
+ *
+ * DO NOT MODIFY THIS FILE!
+ *
+ * Copyright Sonic Network Inc. 2005
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,54 +21,54 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 82 $
- * $Date: 2006-07-10 11:45:19 -0700 (Mon, 10 Jul 2006) $
- *----------------------------------------------------------------------------
-*/
-
-#include "eas_types.h"
-
-/* sentinel */
-#ifndef _EAS_WAVE_H
-#define _EAS_WAVE_H
-
-/* .WAV file format chunk */
-typedef struct {
- EAS_U16 wFormatTag;
- EAS_U16 nChannels;
- EAS_U32 nSamplesPerSec;
- EAS_U32 nAvgBytesPerSec;
- EAS_U16 nBlockAlign;
- EAS_U16 wBitsPerSample;
-} FMT_CHUNK;
-
-/* .WAV file header */
-typedef struct {
- EAS_U32 nRiffTag;
- EAS_U32 nRiffSize;
- EAS_U32 nWaveTag;
- EAS_U32 nFmtTag;
- EAS_U32 nFmtSize;
- FMT_CHUNK fc;
- EAS_U32 nDataTag;
- EAS_U32 nDataSize;
-} WAVE_HEADER;
-
-typedef struct {
- WAVE_HEADER wh;
- FILE *file;
- EAS_BOOL write;
- EAS_U32 dataSize;
-} WAVE_FILE;
-
-WAVE_FILE *WaveFileCreate (const char *filename, EAS_I32 nChannels, EAS_I32 nSamplesPerSec, EAS_I32 wBitsPerSample);
-EAS_I32 WaveFileWrite (WAVE_FILE *wFile, void *buffer, EAS_I32 n);
-EAS_BOOL WaveFileClose (WAVE_FILE *wFile);
-WAVE_FILE *WaveFileOpen (const char *filename);
-
-#endif /* end #ifndef _EAS_WAVE_H */
-
-
-
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 82 $
+ * $Date: 2006-07-10 11:45:19 -0700 (Mon, 10 Jul 2006) $
+ *----------------------------------------------------------------------------
+*/
+
+#include "eas_types.h"
+
+/* sentinel */
+#ifndef _EAS_WAVE_H
+#define _EAS_WAVE_H
+
+/* .WAV file format chunk */
+typedef struct {
+ EAS_U16 wFormatTag;
+ EAS_U16 nChannels;
+ EAS_U32 nSamplesPerSec;
+ EAS_U32 nAvgBytesPerSec;
+ EAS_U16 nBlockAlign;
+ EAS_U16 wBitsPerSample;
+} FMT_CHUNK;
+
+/* .WAV file header */
+typedef struct {
+ EAS_U32 nRiffTag;
+ EAS_U32 nRiffSize;
+ EAS_U32 nWaveTag;
+ EAS_U32 nFmtTag;
+ EAS_U32 nFmtSize;
+ FMT_CHUNK fc;
+ EAS_U32 nDataTag;
+ EAS_U32 nDataSize;
+} WAVE_HEADER;
+
+typedef struct {
+ WAVE_HEADER wh;
+ FILE *file;
+ EAS_BOOL write;
+ EAS_U32 dataSize;
+} WAVE_FILE;
+
+WAVE_FILE *WaveFileCreate (const char *filename, EAS_I32 nChannels, EAS_I32 nSamplesPerSec, EAS_I32 wBitsPerSample);
+EAS_I32 WaveFileWrite (WAVE_FILE *wFile, void *buffer, EAS_I32 n);
+EAS_BOOL WaveFileClose (WAVE_FILE *wFile);
+WAVE_FILE *WaveFileOpen (const char *filename);
+
+#endif /* end #ifndef _EAS_WAVE_H */
+
+
+
diff --git a/arm-wt-22k/host_src/jet.h b/arm-wt-22k/host_src/jet.h
index 35bdb6d..2e97a13 100644
--- a/arm-wt-22k/host_src/jet.h
+++ b/arm-wt-22k/host_src/jet.h
@@ -1,199 +1,199 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * jet.h
- *
- * Contents and purpose:
- * Public interface for JET sound engine
- *
- * Copyright (c) 2006 Sonic Network Inc.
-
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 554 $
- * $Date: 2007-02-02 11:06:10 -0800 (Fri, 02 Feb 2007) $
- *----------------------------------------------------------------------------
-*/
-
-#ifndef _JET_H
-#define _JET_H
-
-#include "eas_types.h"
-#include "eas.h"
-
-/* for C++ linkage */
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* opaque handle types for JET interface */
-typedef struct s_jet_data_tag *JET_DATA_HANDLE;
-
-typedef struct s_jet_config_tag
-{
- EAS_U8 appEventRangeLow;
- EAS_U8 appEventRangeHigh;
-} S_JET_CONFIG;
-
-typedef struct s_jet_status_tag
-{
- EAS_INT currentUserID;
- EAS_INT segmentRepeatCount;
- EAS_INT numQueuedSegments;
- EAS_BOOL paused;
- EAS_I32 location;
- EAS_U8 currentPlayingSegment;
- EAS_U8 currentQueuedSegment;
-} S_JET_STATUS;
-
-typedef struct s_jet_event_tag
-{
- EAS_U8 segment;
- EAS_U8 channel;
- EAS_U8 track;
- EAS_U8 controller;
- EAS_U8 value;
-} S_JET_EVENT;
-
-/*----------------------------------------------------------------------------
- * JET_Init()
- *----------------------------------------------------------------------------
- * Initializes the JET library, allocates memory, etc. Call
- * JET_Shutdown to de-allocate memory. Pass NULL for pConfig
- * to use defaults. If passing config data, configSize should be
- * sizeof(S_JET_CONFIG). This allows for future expansion of the
- * config structure while maintaining compatibility.
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT JET_Init (EAS_DATA_HANDLE easHandle, const S_JET_CONFIG *pConfig, EAS_INT configSize);
-
-/*----------------------------------------------------------------------------
- * JET_Shutdown()
- *----------------------------------------------------------------------------
- * Frees any memory used by the JET library
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT JET_Shutdown (EAS_DATA_HANDLE easHandle);
-
-/*----------------------------------------------------------------------------
- * JET_OpenFile()
- *----------------------------------------------------------------------------
- * Opens a JET content file for playback
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT JET_OpenFile (EAS_DATA_HANDLE easHandle, EAS_FILE_LOCATOR locator);
-
-/*----------------------------------------------------------------------------
- * JET_GetAppData()
- *----------------------------------------------------------------------------
- * Returns location and size of application data in the JET file
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT JET_GetAppData (EAS_DATA_HANDLE easHandle, EAS_I32 *pAppDataOffset, EAS_I32 *pAppDataSize);
-
-/*----------------------------------------------------------------------------
- * JET_CloseFile()
- *----------------------------------------------------------------------------
- * Closes a JET content file and releases associated resources
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT JET_CloseFile (EAS_DATA_HANDLE easHandle);
-
-/*----------------------------------------------------------------------------
- * JET_Status()
- *----------------------------------------------------------------------------
- * Returns current status
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT JET_Status (EAS_DATA_HANDLE easHandle, S_JET_STATUS *pStatus);
-
-/*----------------------------------------------------------------------------
- * JET_GetEvent()
- *----------------------------------------------------------------------------
- * Checks for application events
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_BOOL JET_GetEvent (EAS_DATA_HANDLE easHandle, EAS_U32 *pEventRaw, S_JET_EVENT *pEvent);
-
-/*----------------------------------------------------------------------------
- * JET_ParseEvent()
- *----------------------------------------------------------------------------
- * Returns current status
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC void JET_ParseEvent (EAS_U32 event, S_JET_EVENT *pEvent);
-
-/*----------------------------------------------------------------------------
- * JET_QueueSegment()
- *----------------------------------------------------------------------------
- * Queue a segment for playback
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT JET_QueueSegment (EAS_DATA_HANDLE easHandle, EAS_INT segmentNum, EAS_INT libNum, EAS_INT repeatCount, EAS_INT transpose, EAS_U32 muteFlags, EAS_U8 userID);
-
-/*----------------------------------------------------------------------------
- * JET_Play()
- *----------------------------------------------------------------------------
- * Starts playback of the file
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT JET_Play (EAS_DATA_HANDLE easHandle);
-
-/*----------------------------------------------------------------------------
- * JET_Pause()
- *----------------------------------------------------------------------------
- * Pauses playback of the file
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT JET_Pause (EAS_DATA_HANDLE easHandle);
-
-/*----------------------------------------------------------------------------
- * JET_SetMuteFlags()
- *----------------------------------------------------------------------------
- * Change the state of the mute flags
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT JET_SetMuteFlags (EAS_DATA_HANDLE easHandle, EAS_U32 muteFlags, EAS_BOOL sync);
-
-/*----------------------------------------------------------------------------
- * JET_SetMuteFlag()
- *----------------------------------------------------------------------------
- * Change the state of a single mute flag
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT JET_SetMuteFlag (EAS_DATA_HANDLE easHandle, EAS_INT trackNum, EAS_BOOL muteFlag, EAS_BOOL sync);
-
-/*----------------------------------------------------------------------------
- * JET_TriggerClip()
- *----------------------------------------------------------------------------
- * Unmute a track and then mute it when it is complete
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT JET_TriggerClip (EAS_DATA_HANDLE easHandle, EAS_INT clipID);
-
-/*----------------------------------------------------------------------------
- * JET_Clear_Queue()
- *----------------------------------------------------------------------------
- * Clears all segments in the queue
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT JET_Clear_Queue (EAS_DATA_HANDLE easHandle);
-
-#ifdef __cplusplus
-} /* end extern "C" */
-#endif
-
-
-#endif
-
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * jet.h
+ *
+ * Contents and purpose:
+ * Public interface for JET sound engine
+ *
+ * Copyright (c) 2006 Sonic Network Inc.
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 554 $
+ * $Date: 2007-02-02 11:06:10 -0800 (Fri, 02 Feb 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+#ifndef _JET_H
+#define _JET_H
+
+#include "eas_types.h"
+#include "eas.h"
+
+/* for C++ linkage */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* opaque handle types for JET interface */
+typedef struct s_jet_data_tag *JET_DATA_HANDLE;
+
+typedef struct s_jet_config_tag
+{
+ EAS_U8 appEventRangeLow;
+ EAS_U8 appEventRangeHigh;
+} S_JET_CONFIG;
+
+typedef struct s_jet_status_tag
+{
+ EAS_INT currentUserID;
+ EAS_INT segmentRepeatCount;
+ EAS_INT numQueuedSegments;
+ EAS_BOOL paused;
+ EAS_I32 location;
+ EAS_U8 currentPlayingSegment;
+ EAS_U8 currentQueuedSegment;
+} S_JET_STATUS;
+
+typedef struct s_jet_event_tag
+{
+ EAS_U8 segment;
+ EAS_U8 channel;
+ EAS_U8 track;
+ EAS_U8 controller;
+ EAS_U8 value;
+} S_JET_EVENT;
+
+/*----------------------------------------------------------------------------
+ * JET_Init()
+ *----------------------------------------------------------------------------
+ * Initializes the JET library, allocates memory, etc. Call
+ * JET_Shutdown to de-allocate memory. Pass NULL for pConfig
+ * to use defaults. If passing config data, configSize should be
+ * sizeof(S_JET_CONFIG). This allows for future expansion of the
+ * config structure while maintaining compatibility.
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT JET_Init (EAS_DATA_HANDLE easHandle, const S_JET_CONFIG *pConfig, EAS_INT configSize);
+
+/*----------------------------------------------------------------------------
+ * JET_Shutdown()
+ *----------------------------------------------------------------------------
+ * Frees any memory used by the JET library
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT JET_Shutdown (EAS_DATA_HANDLE easHandle);
+
+/*----------------------------------------------------------------------------
+ * JET_OpenFile()
+ *----------------------------------------------------------------------------
+ * Opens a JET content file for playback
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT JET_OpenFile (EAS_DATA_HANDLE easHandle, EAS_FILE_LOCATOR locator);
+
+/*----------------------------------------------------------------------------
+ * JET_GetAppData()
+ *----------------------------------------------------------------------------
+ * Returns location and size of application data in the JET file
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT JET_GetAppData (EAS_DATA_HANDLE easHandle, EAS_I32 *pAppDataOffset, EAS_I32 *pAppDataSize);
+
+/*----------------------------------------------------------------------------
+ * JET_CloseFile()
+ *----------------------------------------------------------------------------
+ * Closes a JET content file and releases associated resources
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT JET_CloseFile (EAS_DATA_HANDLE easHandle);
+
+/*----------------------------------------------------------------------------
+ * JET_Status()
+ *----------------------------------------------------------------------------
+ * Returns current status
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT JET_Status (EAS_DATA_HANDLE easHandle, S_JET_STATUS *pStatus);
+
+/*----------------------------------------------------------------------------
+ * JET_GetEvent()
+ *----------------------------------------------------------------------------
+ * Checks for application events
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_BOOL JET_GetEvent (EAS_DATA_HANDLE easHandle, EAS_U32 *pEventRaw, S_JET_EVENT *pEvent);
+
+/*----------------------------------------------------------------------------
+ * JET_ParseEvent()
+ *----------------------------------------------------------------------------
+ * Returns current status
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC void JET_ParseEvent (EAS_U32 event, S_JET_EVENT *pEvent);
+
+/*----------------------------------------------------------------------------
+ * JET_QueueSegment()
+ *----------------------------------------------------------------------------
+ * Queue a segment for playback
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT JET_QueueSegment (EAS_DATA_HANDLE easHandle, EAS_INT segmentNum, EAS_INT libNum, EAS_INT repeatCount, EAS_INT transpose, EAS_U32 muteFlags, EAS_U8 userID);
+
+/*----------------------------------------------------------------------------
+ * JET_Play()
+ *----------------------------------------------------------------------------
+ * Starts playback of the file
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT JET_Play (EAS_DATA_HANDLE easHandle);
+
+/*----------------------------------------------------------------------------
+ * JET_Pause()
+ *----------------------------------------------------------------------------
+ * Pauses playback of the file
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT JET_Pause (EAS_DATA_HANDLE easHandle);
+
+/*----------------------------------------------------------------------------
+ * JET_SetMuteFlags()
+ *----------------------------------------------------------------------------
+ * Change the state of the mute flags
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT JET_SetMuteFlags (EAS_DATA_HANDLE easHandle, EAS_U32 muteFlags, EAS_BOOL sync);
+
+/*----------------------------------------------------------------------------
+ * JET_SetMuteFlag()
+ *----------------------------------------------------------------------------
+ * Change the state of a single mute flag
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT JET_SetMuteFlag (EAS_DATA_HANDLE easHandle, EAS_INT trackNum, EAS_BOOL muteFlag, EAS_BOOL sync);
+
+/*----------------------------------------------------------------------------
+ * JET_TriggerClip()
+ *----------------------------------------------------------------------------
+ * Unmute a track and then mute it when it is complete
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT JET_TriggerClip (EAS_DATA_HANDLE easHandle, EAS_INT clipID);
+
+/*----------------------------------------------------------------------------
+ * JET_Clear_Queue()
+ *----------------------------------------------------------------------------
+ * Clears all segments in the queue
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT JET_Clear_Queue (EAS_DATA_HANDLE easHandle);
+
+#ifdef __cplusplus
+} /* end extern "C" */
+#endif
+
+
+#endif
+
diff --git a/arm-wt-22k/jetcreator_lib_src/darwin-x86/EASLib.c b/arm-wt-22k/jetcreator_lib_src/darwin-x86/EASLib.c
index 6f98bc1..ca19247 100755..100644
--- a/arm-wt-22k/jetcreator_lib_src/darwin-x86/EASLib.c
+++ b/arm-wt-22k/jetcreator_lib_src/darwin-x86/EASLib.c
@@ -1,1809 +1,1809 @@
-/*
- * EASLib.c
- * EASLIb
- *
- *
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <stdarg.h>
-#include <string.h>
-
-#include "eas.h"
-#include "eas_report.h"
-#include "eas_host.h"
-#include <AudioUnit/AudioUnit.h>
-#include <CoreServices/CoreServices.h>
-
-#ifdef JET_INTERFACE
-#include "jet.h"
-#endif
-
-
-#define EAS_EXPORT __attribute__((visibility("default")))
-
-// #define DEBUG_FILE_IO
-
-/* include debug interface */
-#include "eas_host_debug.h"
-
-#ifdef AUX_MIXER
-#include "eas_auxmix.h"
-#endif
-
-/* this module requires dynamic memory support */
-#ifdef _STATIC_MEMORY
-#error "eas_hostmm.c requires the dynamic memory model!\n"
-#endif
-
-#ifndef EAS_MAX_FILE_HANDLES
-#define EAS_MAX_FILE_HANDLES 32
-#endif
-
-#ifndef EAS_FILE_BUFFER_SIZE
-#define EAS_FILE_BUFFER_SIZE 32
-#endif
-
-/*
- * this structure and the related function are here
- * to support the ability to create duplicate handles
- * and buffering it in memory. If your system uses
- * in-memory resources, you can eliminate the calls
- * to malloc and free, the dup flag, and simply track
- * the file size and read position.
- */
- #ifdef BUFFERED_FILE_ACCESS
-typedef struct eas_hw_file_tag
-{
- FILE *pFile;
- EAS_I32 bytesInBuffer;
- EAS_I32 readIndex;
- EAS_I32 filePos;
- EAS_I32 fileSize;
- EAS_BOOL dup;
- EAS_U8 buffer[EAS_FILE_BUFFER_SIZE];
-} EAS_HW_FILE;
-#else
-typedef struct eas_hw_file_tag
-{
- EAS_I32 fileSize;
- EAS_I32 filePos;
- EAS_BOOL dup;
- EAS_U8 *buffer;
-} EAS_HW_FILE;
-#endif
-
-typedef struct eas_hw_inst_data_tag
-{
- EAS_HW_FILE files[EAS_MAX_FILE_HANDLES];
-} EAS_HW_INST_DATA;
-
-EAS_BOOL errorConditions[eNumErrorConditions];
-EAS_BOOL ledState;
-EAS_BOOL vibState;
-EAS_BOOL backlightState;
-
-#define MAX_DEBUG_MSG_LEN 1024
-
-typedef void (*EAS_LOG_FUNC)(EAS_INT severity, char *msg);
-
-static EAS_LOG_FUNC logCallback = NULL;
-static char messageBuffer[MAX_DEBUG_MSG_LEN];
-
-/* error counts */
-static EAS_INT eas_fatalErrors;
-static EAS_INT eas_errors;
-static EAS_INT eas_warnings;
-static int severityLevel = 9999;
-
-
-#define MAX_BUFFERS 8
-
-// The output unit
-AudioUnit OutputUnit;
-AudioStreamBasicDescription streamFormat;
-
-// sync stuf
-pthread_mutex_t mtx;
-pthread_cond_t cond;
-bool bStopped = true;
-
-// buffer to hold the data
-typedef struct
-{
- UInt32 uOutBufferLength;
- UInt32 uOutFrames;
- int ix;
- short* pData[8];
- unsigned int uLength;
-} S_BUFFER_INFO;
-
-static S_BUFFER_INFO *pBuf = NULL;
-const S_EAS_LIB_CONFIG *pConfig = NULL;
-
-/*----------------------------------------------------------------------------
- * ResetErrorCounters()
- *----------------------------------------------------------------------------
-*/
-EAS_EXPORT void ResetErrorCounters()
-{
- eas_fatalErrors = 0;
- eas_errors = 0;
- eas_warnings = 0;
-}
-
-/*----------------------------------------------------------------------------
- * SetLogCallback()
- *----------------------------------------------------------------------------
-*/
-EAS_EXPORT void SetLogCallback (EAS_LOG_FUNC callback)
-{
- logCallback = callback;
-}
-
-#ifndef _NO_DEBUG_PREPROCESSOR
-static S_DEBUG_MESSAGES debugMessages[] =
-{
-#ifdef UNIFIED_DEBUG_MESSAGES
-#include "eas_debugmsgs.h"
-#endif
- { 0,0,0 }
-};
-
-/*----------------------------------------------------------------------------
- * EAS_ReportEx()
- *----------------------------------------------------------------------------
-*/
-void EAS_ReportEx (int severity, unsigned long hashCode, int serialNum, ...)
-{
- va_list vargs;
- int i;
-
- switch (severity)
- {
- case _EAS_SEVERITY_FATAL:
- eas_fatalErrors++;
- break;
-
- case _EAS_SEVERITY_ERROR:
- eas_errors++;
- break;
-
- case _EAS_SEVERITY_WARNING:
- eas_warnings++;
- break;
-
- default:
- break;
- }
-
- /* check severity level */
- if (severity > severityLevel)
- return;
-
- /* check for callback */
- if (logCallback == NULL)
- return;
-
- /* find the error message and output to stdout */
- for (i = 0; debugMessages[i].m_pDebugMsg; i++)
- {
- if ((debugMessages[i].m_nHashCode == hashCode) &&
- (debugMessages[i].m_nSerialNum == serialNum))
- {
- va_start(vargs, serialNum);
-#ifdef WIN32
- vsprintf_s(messageBuffer, sizeof(messageBuffer), fmt, vargs);
-#else
- vsprintf(messageBuffer, debugMessages[i].m_pDebugMsg, vargs);
-#endif
- logCallback(severity, messageBuffer);
- va_end(vargs);
- return;
- }
- }
- printf("Unrecognized error: Severity=%d; HashCode=%lu; SerialNum=%d\n", severity, hashCode, serialNum);
-} /* end EAS_ReportEx */
-
-#else
-/*----------------------------------------------------------------------------
- * EAS_Report()
- *----------------------------------------------------------------------------
-*/
-void EAS_Report (int severity, const char *fmt, ...)
-{
- va_list vargs;
-
- switch (severity)
- {
- case _EAS_SEVERITY_FATAL:
- eas_fatalErrors++;
- break;
-
- case _EAS_SEVERITY_ERROR:
- eas_errors++;
- break;
-
- case _EAS_SEVERITY_WARNING:
- eas_warnings++;
- break;
-
- default:
- break;
- }
-
- /* check severity level */
- if (severity > severityLevel)
- return;
-
- /* check for callback */
- if (logCallback == NULL)
- return;
-
- va_start(vargs, fmt);
-#ifdef _WIN32
- vsprintf_s(messageBuffer, sizeof(messageBuffer), fmt, vargs);
-#else
- vsprintf(messageBuffer, fmt, vargs);
-#endif
- logCallback(severity, messageBuffer);
- va_end(vargs);
-} /* end EAS_Report */
-
-/*----------------------------------------------------------------------------
- * EAS_ReportX()
- *----------------------------------------------------------------------------
-*/
-void EAS_ReportX (int severity, const char *fmt, ...)
-{
- va_list vargs;
-
- switch (severity)
- {
- case _EAS_SEVERITY_FATAL:
- eas_fatalErrors++;
- break;
-
- case _EAS_SEVERITY_ERROR:
- eas_errors++;
- break;
-
- case _EAS_SEVERITY_WARNING:
- eas_warnings++;
- break;
-
- default:
- break;
- }
-
- /* check severity level */
- if (severity > severityLevel)
- return;
-
- /* check for callback */
- if (logCallback == NULL)
- return;
-
- va_start(vargs, fmt);
-#ifdef _WIN32
- vsprintf_s(messageBuffer, sizeof(messageBuffer), fmt, vargs);
-#else
- vsprintf(messageBuffer, fmt, vargs);
-#endif
- logCallback(severity, messageBuffer);
- va_end(vargs);
-}
-#endif
-
-/*----------------------------------------------------------------------------
- * EAS_DLLSetDebugLevel()
- *----------------------------------------------------------------------------
-*/
-EAS_EXPORT void EAS_DLLSetDebugLevel (int severity)
-{
- severityLevel = severity;
-}
-
-/*----------------------------------------------------------------------------
- * EAS_ExSetDebugLevel()
- *----------------------------------------------------------------------------
-*/
-void EAS_SetDebugLevel (int severity)
-{
- severityLevel = severity;
-}
-
-/*----------------------------------------------------------------------------
- * EAS_SelectLibrary()
- *----------------------------------------------------------------------------
-*/
-EAS_EXPORT EAS_RESULT EAS_SelectLib (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle, EAS_BOOL testLib)
-{
- extern EAS_SNDLIB_HANDLE VMGetLibHandle(EAS_INT libNum);
- return EAS_SetSoundLibrary(pEASData, streamHandle, VMGetLibHandle(testLib ? 1 : 0));
-}
-
-// Callback proc
-static OSStatus RenderProc( void *inRefCon,
- AudioUnitRenderActionFlags *ioActionFlags,
- const AudioTimeStamp *inTimeStamp,
- UInt32 inBusNumber,
- UInt32 inNumberFrames,
- AudioBufferList *ioData)
-{
- // Get the mutex
- pthread_mutex_lock(&mtx);
-
- short* ptrOutL = (short *)ioData->mBuffers[0].mData;
- short* ptrOutR = (short *)ioData->mBuffers[1].mData;
-
- memset(ptrOutL, 0, pBuf->uOutFrames);
- memset(ptrOutR, 0, pBuf->uOutFrames);
-
- // check if there is any data in the buffer
- if (pBuf->ix == 0 )
- {
- // Release the mutex and signal the python thread
- pthread_mutex_unlock(&mtx);
- pthread_cond_signal(&cond);
- return 0;
- }
-
- // Get a ptr to the data
- short* pData = pBuf->pData[--(pBuf->ix)];
-
- // Now copy the data
- int i;
- for (i = 0; i < pBuf->uOutFrames; i+=2 )
- {
- *ptrOutL++ = pData[i];
- *ptrOutR++ = pData[i+1];
- }
-
- // Release the mutex
- pthread_mutex_unlock(&mtx);
- pthread_cond_signal(&cond);
-
- return 0;
-}
-
-EAS_RESULT addData(EAS_PCM *pAudioBuffer)
-{
- // Copy the data we got from the synth
- memcpy(pBuf->pData[(pBuf->ix)++], pAudioBuffer, 2048);
-
- // Start the output Audio Unit only the first time
- if ( bStopped == true )
- {
- bStopped = false;
- OSStatus err = AudioOutputUnitStart (OutputUnit);
- if (err)
- {
- printf ("AudioDeviceStart=%ld\n", err);
- return EAS_FAILURE;
- }
- }
-
- return EAS_SUCCESS;
-}
-
-
-EAS_EXPORT EAS_RESULT EAS_RenderWaveOut(EAS_DATA_HANDLE easHandle, EAS_PCM *pAudioBuffer, EAS_I32 numRequested, EAS_I32 *pNumGenerated)
-{
- // Get the mutex
- pthread_mutex_lock(&mtx);
-
- // Check if our buffer is full
- while(pBuf->ix == MAX_BUFFERS - 1)
- pthread_cond_wait(&cond, &mtx);
-
- // Call the synth the render a buffer
- EAS_RESULT result = EAS_Render(easHandle, pAudioBuffer, numRequested, pNumGenerated);
- addData( pAudioBuffer );
-
- // Release the mutex
- pthread_mutex_unlock(&mtx);
-
- //Done
- return result;
-}
-
-#ifdef AUX_MIXER
-EAS_EXPORT EAS_RESULT EAS_RenderAuxMixerWaveOut (EAS_DATA_HANDLE easHandle, EAS_PCM *pAudioBuffer, EAS_I32 *pNumGenerated)
-{
- // Get the mutex
- pthread_mutex_lock(&mtx);
-
- // Check if our buffer is full
- while(pBuf->ix == MAX_BUFFERS - 1)
- pthread_cond_wait(&cond, &mtx);
-
- EAS_RESULT result = EAS_RenderAuxMixer(easHandle, pAudioBuffer, pNumGenerated);
- addData( pAudioBuffer );
-
- // Release the mutex
- pthread_mutex_unlock(&mtx);
-
- return result;
-}
-#endif
-
-EAS_EXPORT EAS_RESULT OpenWaveOutDevice(EAS_INT devNum, EAS_INT sampleRate, EAS_INT maxBufSize)
-{
- // Open the default output unit
- ComponentDescription desc;
- desc.componentType = kAudioUnitType_Output;
- desc.componentSubType = kAudioUnitSubType_DefaultOutput;
- desc.componentManufacturer = kAudioUnitManufacturer_Apple;
- desc.componentFlags = 0;
- desc.componentFlagsMask = 0;
-
- Component comp = FindNextComponent(NULL, &desc);
- if (comp == NULL)
- {
- printf ("Could find the default output unit!!!\n");
- return EAS_FAILURE;
- }
-
- OSStatus err = OpenAComponent(comp, &OutputUnit);
- if (comp == NULL)
- {
- printf ("OpenAComponent=%ld\n", err);
- return EAS_FAILURE;
- }
-
- // Set up a callback function to generate output to the output unit
- AURenderCallbackStruct auRenderCallback;
- auRenderCallback.inputProc = RenderProc;
- auRenderCallback.inputProcRefCon = NULL;
-
- err = AudioUnitSetProperty (OutputUnit,
- kAudioUnitProperty_SetRenderCallback,
- kAudioUnitScope_Input,
- 0,
- &auRenderCallback,
- sizeof(auRenderCallback));
- if (err)
- {
- printf ("AudioUnitSetProperty-CB=%ld\n", err);
- return EAS_FAILURE;;
- }
-
- pConfig = EAS_Config();
-
- // The synth engine already uses short* for the buffers so let CoreAudio do any conversions if needed
- if (sampleRate != 0)
- streamFormat.mSampleRate = sampleRate;
- else
- streamFormat.mSampleRate = pConfig->sampleRate;
-
- streamFormat.mFormatID = kAudioFormatLinearPCM;
- streamFormat.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger
- | kAudioFormatFlagsNativeEndian
- | kLinearPCMFormatFlagIsPacked
- | kAudioFormatFlagIsNonInterleaved;
-
- streamFormat.mBytesPerPacket = 2;
- streamFormat.mFramesPerPacket = 1;
- streamFormat.mBytesPerFrame = 2;
- streamFormat.mChannelsPerFrame = 2;
- streamFormat.mBitsPerChannel = 16;
-
- err = AudioUnitSetProperty (OutputUnit,
- kAudioUnitProperty_StreamFormat,
- kAudioUnitScope_Input,
- 0,
- &streamFormat,
- sizeof(AudioStreamBasicDescription));
- if (err)
- {
- printf ("AudioUnitSetProperty-SF= %4.4s, %ld\n", (char*)&err, err);
- return EAS_FAILURE;
- }
-
- // Initialize
- err = AudioUnitInitialize(OutputUnit);
- if (err)
- {
- printf ("AudioUnitInitialize = %ld\n", err);
- return EAS_FAILURE;
- }
-
- pBuf = (S_BUFFER_INFO *) malloc(sizeof(S_BUFFER_INFO));
- if( !pBuf )
- return EAS_FAILURE;
-
- pBuf->uOutBufferLength = pConfig->mixBufferSize * streamFormat.mBitsPerChannel / 2;
- UInt32 uDataSize = sizeof(pBuf->uOutBufferLength);
-
- err = AudioUnitSetProperty(OutputUnit, kAudioDevicePropertyBufferSize, kAudioUnitScope_Output, 0, &pBuf->uOutBufferLength, uDataSize);
- if (err)
- {
- printf ("AudioUnitSetProperty = %ld\n", err);
- return EAS_FAILURE;
- }
-
- err = AudioUnitGetProperty(OutputUnit, kAudioDevicePropertyBufferSize, kAudioUnitScope_Output, 0, &pBuf->uOutBufferLength, &uDataSize);
- if (err)
- {
- printf ("AudioUnitGetProperty = %ld\n", err);
- return EAS_FAILURE;
- }
-
- pBuf->uLength = pBuf->uOutBufferLength;
- int i;
- for ( i = 0; i < MAX_BUFFERS; i++)
- pBuf->pData[i] = malloc(pBuf->uLength);
-
- pBuf->uOutBufferLength /= pConfig->numChannels;
- pBuf->uOutFrames = pBuf->uOutBufferLength / sizeof(short);
-
- pBuf->ix = 0;
-
- // Init the stop flag
- bStopped = true;
-
- int result = pthread_mutex_init(&mtx, NULL);
- if (result)
- {
- printf("pthread_mutex_init failed\n");
- return EAS_FAILURE;
- }
-
- result = pthread_cond_init(&cond, NULL);
- if (result)
- {
- printf("pthread_cond_init failed\n");
- return EAS_FAILURE;
- }
-
- // Done
- return EAS_SUCCESS;
-}
-
-
-EAS_EXPORT EAS_RESULT StartStream()
-{
- OSStatus err = noErr;
- pthread_mutex_lock(&mtx);
- if ( bStopped == true )
- {
- err = AudioOutputUnitStart (OutputUnit);
- if (err)
- {
- printf ("AudioOutputUnitStart=%ld\n", err);
- return EAS_FAILURE;
- }
- bStopped = false;
- }
-
- return EAS_SUCCESS;
-}
-
-
-EAS_EXPORT EAS_RESULT CloseWaveOutDevice()
-{
- OSStatus err;
-
- pthread_mutex_lock(&mtx);
- if( false == bStopped )
- {
- AudioOutputUnitStop (OutputUnit);
- bStopped = true;
-
- err = AudioUnitUninitialize (OutputUnit);
- if (err)
- {
- printf ("AudioUnitUninitialize=%ld\n", err);
- return EAS_FAILURE;
- }
-
- CloseComponent (OutputUnit);
- int i = 0;
- for(i; i < MAX_BUFFERS; i++)
- free(pBuf->pData[i]);
-
- free(pBuf);
- }
-
- pthread_mutex_unlock(&mtx);
- return EAS_SUCCESS;
-}
-
-
-#if defined(_DEBUG) && !defined(MSC)
-#include <crtdbg.h>
-/*----------------------------------------------------------------------------
- * EnableHeapDebug()
- *----------------------------------------------------------------------------
-*/
-static void EnableHeapDebug (void)
-{
- int temp;
- temp = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
- temp |= _CRTDBG_ALLOC_MEM_DF;
- temp |= _CRTDBG_CHECK_ALWAYS_DF;
- temp |= _CRTDBG_LEAK_CHECK_DF;
-// temp |= _CRTDBG_DELAY_FREE_MEM_DF;
- _CrtSetDbgFlag(temp);
-}
-
-/*----------------------------------------------------------------------------
- * HeapCheck()
- *----------------------------------------------------------------------------
- * Check heap status
- *----------------------------------------------------------------------------
-*/
-void HeapCheck (void)
-{
- int heapStatus;
-
- /* Check heap status */
- heapStatus = _heapchk();
- if ((heapStatus == _HEAPOK) || (heapStatus == _HEAPEMPTY))
- return;
-
- EAS_ReportX(_EAS_SEVERITY_FATAL, "Heap corrupt\n" );
-}
-#endif
-
-
-/*----------------------------------------------------------------------------
- * EAS_HWInit
- *
- * Initialize host wrapper interface
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT EAS_HWInit (EAS_HW_DATA_HANDLE *pHWInstData)
-{
-
-#if defined(_DEBUG) && !defined(MSC)
- EnableHeapDebug();
-#endif
-
- #ifdef BUFFERED_FILE_ACCESS
- EAS_ReportX(_EAS_SEVERITY_INFO, "EAS_HWInit: Buffered file access\n");
- #else
- EAS_ReportX(_EAS_SEVERITY_INFO, "EAS_HWInit: Memory mapped file access\n");
- #endif
-
- /* simulate failure */
- if (errorConditions[eInitError])
- return EAS_FAILURE;
-
- /* need to track file opens for duplicate handles */
- *pHWInstData = malloc(sizeof(EAS_HW_INST_DATA));
- if (!(*pHWInstData))
- return EAS_ERROR_MALLOC_FAILED;
-
- EAS_HWMemSet(*pHWInstData, 0, sizeof(EAS_HW_INST_DATA));
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * EAS_HWShutdown
- *
- * Shut down host wrapper interface
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT EAS_HWShutdown (EAS_HW_DATA_HANDLE hwInstData)
-{
-
- /* simulate failure */
- if (errorConditions[eShutdownError])
- return EAS_FAILURE;
-
- free(hwInstData);
-
-#if defined(_DEBUG) && !defined(MSC)
- HeapCheck();
-#endif
-
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- *
- * EAS_HWMalloc
- *
- * Allocates dynamic memory
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, hwInstData) available for customer use */
-void *EAS_HWMalloc (EAS_HW_DATA_HANDLE hwInstData, EAS_I32 size)
-{
- /* simulate failure */
- if (errorConditions[eMallocError])
- return NULL;
-
- return malloc((size_t) size);
-}
-
-/*----------------------------------------------------------------------------
- *
- * EAS_HWFree
- *
- * Frees dynamic memory
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, hwInstData) available for customer use */
-void EAS_HWFree (EAS_HW_DATA_HANDLE hwInstData, void *p)
-{
- free(p);
-}
-
-/*----------------------------------------------------------------------------
- *
- * EAS_HWMemCpy
- *
- * Copy memory wrapper
- *
- *----------------------------------------------------------------------------
-*/
-void *EAS_HWMemCpy (void *dest, const void *src, EAS_I32 amount)
-{
- return memcpy(dest, src, (size_t) amount);
-}
-
-/*----------------------------------------------------------------------------
- *
- * EAS_HWMemSet
- *
- * Set memory wrapper
- *
- *----------------------------------------------------------------------------
-*/
-void *EAS_HWMemSet (void *dest, int val, EAS_I32 amount)
-{
- return memset(dest, val, (size_t) amount);
-}
-
-/*----------------------------------------------------------------------------
- *
- * EAS_HWMemCmp
- *
- * Compare memory wrapper
- *
- *----------------------------------------------------------------------------
-*/
-EAS_I32 EAS_HWMemCmp (const void *s1, const void *s2, EAS_I32 amount)
-{
- return (EAS_I32) memcmp(s1, s2, (size_t) amount);
-}
-
-#ifdef BUFFERED_FILE_ACCESS
-/*----------------------------------------------------------------------------
- *
- * EAS_HWOpenFile
- *
- * Open a file for read or write
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT EAS_HWOpenFile (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_LOCATOR locator, EAS_FILE_HANDLE *pFile, EAS_FILE_MODE mode)
-{
- EAS_HW_FILE *file;
- int i;
-
- /* set return value to NULL */
- *pFile = NULL;
-
- /* only support read mode at this time */
- if (mode != EAS_FILE_READ)
- return EAS_ERROR_INVALID_FILE_MODE;
-
- /* find an empty entry in the file table */
- file = hwInstData->files;
- for (i = 0; i < EAS_MAX_FILE_HANDLES; i++)
- {
- /* is this slot being used? */
- if (file->pFile == NULL)
- {
- EAS_RESULT result;
-
- /* open the file */
- file->pFile = fopen((const char*) locator, "rb");
- if (file->pFile == NULL)
- return EAS_ERROR_FILE_OPEN_FAILED;
-
- /* get file length */
- if ((result = EAS_HWFileLength(hwInstData, file, &file->fileSize)) != EAS_SUCCESS)
- {
- EAS_HWCloseFile(hwInstData, file);
- return result;
- }
-
-#ifdef DEBUG_FILE_IO
- EAS_ReportX(_EAS_SEVERITY_NOFILTER, "EAS_HWOpenFile: Open file %d\n", i);
-#endif
-
- /* initialize some values */
- file->bytesInBuffer = 0;
- file->readIndex = 0;
- file->filePos = 0;
- file->dup = EAS_FALSE;
-
- *pFile = file;
- return EAS_SUCCESS;
- }
- file++;
- }
-
- /* too many open files */
- return EAS_ERROR_MAX_FILES_OPEN;
-}
-
-/*----------------------------------------------------------------------------
- *
- * EAS_HWFillBuffer
- *
- * Fill buffer from file
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, hwInstData) hwInstData available for customer use */
-EAS_RESULT EAS_HWFillBuffer (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file)
-{
- /* reposition the file pointer */
- if (fseek(file->pFile, file->filePos, SEEK_SET) != 0)
- return EAS_ERROR_FILE_SEEK;
-
- /* read some data from the file */
- file->bytesInBuffer = (EAS_I32) fread(file->buffer, 1, EAS_FILE_BUFFER_SIZE, file->pFile);
- file->readIndex = 0;
- if (file->bytesInBuffer == 0)
- return EAS_EOF;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- *
- * EAS_HWReadFile
- *
- * Read data from a file
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, hwInstData) hwInstData available for customer use */
-EAS_RESULT EAS_HWReadFile (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, void *pBuffer, EAS_I32 n, EAS_I32 *pBytesRead)
-{
- EAS_RESULT result;
- EAS_I32 temp;
- EAS_U8 *p = pBuffer;
- EAS_I32 bytesLeft = n;
-
- *pBytesRead = 0;
-
- /* check handle integrity */
- if (file->pFile == NULL)
- return EAS_ERROR_INVALID_HANDLE;
-
-#ifdef DEBUG_FILE_IO
- EAS_ReportX(_EAS_SEVERITY_NOFILTER, "EAS_HWReadFile: Reading %d bytes from position %d\n", n, file->filePos);
-#endif
-
- /* try to fulfill request from buffer */
- for (;bytesLeft > 0;)
- {
- /* how many bytes can we get from buffer? */
- temp = file->bytesInBuffer - file->readIndex;
- if (temp > bytesLeft)
- temp = bytesLeft;
-
- /* copy data from buffer */
- EAS_HWMemCpy(p, &file->buffer[file->readIndex], temp);
- *pBytesRead += temp;
- file->readIndex += temp;
- file->filePos += temp;
- p += temp;
- bytesLeft -= temp;
-
- /* don't refill buffer if request is bigger than buffer */
- if ((bytesLeft == 0) || (bytesLeft >= EAS_FILE_BUFFER_SIZE))
- break;
-
- /* refill buffer */
- if ((result = EAS_HWFillBuffer(hwInstData, file)) != EAS_SUCCESS)
- return result;
- }
-
- /* more to read? do unbuffered read directly to target memory */
- if (bytesLeft)
- {
-
- /* position the file pointer */
- if (fseek(file->pFile, file->filePos, SEEK_SET) != 0)
- return EAS_ERROR_FILE_SEEK;
-
- /* read data in the buffer */
- temp = (EAS_I32) fread(p, 1, (size_t) bytesLeft, file->pFile);
- *pBytesRead += temp;
- file->filePos += temp;
-
- /* reset buffer info */
- file->bytesInBuffer = 0;
- file->readIndex = 0;
- }
-
-#ifdef DEBUG_FILE_IO
- {
-#define BYTES_PER_LINE 16
- char str[BYTES_PER_LINE * 3 + 1];
- EAS_INT i;
- for (i = 0; i < (n > BYTES_PER_LINE ? BYTES_PER_LINE : n) ; i ++)
- sprintf(&str[i*3], "%02x ", ((EAS_U8*)pBuffer)[i]);
- if (i)
- EAS_ReportX(_EAS_SEVERITY_NOFILTER, "%s\n", str);
- }
-#endif
-
- /* were n bytes read? */
- if (*pBytesRead != n)
- return EAS_EOF;
-
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- *
- * EAS_HWGetByte
- *
- * Read a byte from a file
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, hwInstData) hwInstData available for customer use */
-EAS_RESULT EAS_HWGetByte (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, void *p)
-{
- EAS_RESULT result;
-
- /* check handle integrity */
- if (file->pFile == NULL)
- return EAS_ERROR_INVALID_HANDLE;
-
- /* use local buffer - do we have any data? */
- if (file->readIndex >= file->bytesInBuffer)
- {
- if ((result = EAS_HWFillBuffer(hwInstData, file)) != EAS_SUCCESS)
- return result;
-
- /* if nothing to read, return EOF */
- if (file->bytesInBuffer == 0)
- return EAS_EOF;
- }
-
- /* get a character from the buffer */
- *((EAS_U8*) p) = file->buffer[file->readIndex++];
-
-#ifdef DEBUG_FILE_IO
- EAS_ReportX(_EAS_SEVERITY_NOFILTER, "EAS_HWGetByte: Reading from position %d, byte = 0x%02x\n", file->filePos, *(EAS_U8*)p);
-#endif
-
- file->filePos++;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- *
- * EAS_HWGetWord
- *
- * Read a 16-bit value from the file
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT EAS_HWGetWord (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, void *p, EAS_BOOL msbFirst)
-{
- EAS_RESULT result;
- EAS_I32 count;
- EAS_U8 c[2];
-
-#ifdef DEBUG_FILE_IO
- EAS_ReportX(_EAS_SEVERITY_NOFILTER, "EAS_HWGetWord: Reading 2 bytes from position %d\n", file->filePos);
-#endif
-
- /* read 2 bytes from the file */
- if ((result = EAS_HWReadFile(hwInstData, file, c, 2, &count)) != EAS_SUCCESS)
- return result;
-
- /* order them as requested */
- if (msbFirst)
- *((EAS_U16*) p) = ((EAS_U16) c[0] << 8) | c[1];
- else
- *((EAS_U16*) p) = ((EAS_U16) c[1] << 8) | c[0];
-
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- *
- * EAS_HWGetDWord
- *
- * Read a 16-bit value from the file
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT EAS_HWGetDWord (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, void *p, EAS_BOOL msbFirst)
-{
- EAS_RESULT result;
- EAS_I32 count;
- EAS_U8 c[4];
-
-#ifdef DEBUG_FILE_IO
- EAS_ReportX(_EAS_SEVERITY_NOFILTER, "EAS_HWGetDWord: Reading 4 bytes from position %d\n", file->filePos);
-#endif
-
- /* read 4 bytes from the file */
- if ((result = EAS_HWReadFile(hwInstData, file, c, 4, &count)) != EAS_SUCCESS)
- return result;
-
- /* order them as requested */
- if (msbFirst)
- *((EAS_U32*) p) = ((EAS_U32) c[0] << 24) | ((EAS_U32) c[1] << 16) | ((EAS_U32) c[2] << 8) | c[3];
- else
- *((EAS_U32*) p) = ((EAS_U32) c[3] << 24) | ((EAS_U32) c[2] << 16) | ((EAS_U32) c[1] << 8) | c[0];
-
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- *
- * EAS_HWFilePos
- *
- * Returns the current location in the file
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, hwInstData) hwInstData available for customer use */
-EAS_RESULT EAS_HWFilePos (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, EAS_I32 *pPosition)
-{
-
- /* check handle integrity */
- if (file->pFile == NULL)
- return EAS_ERROR_INVALID_HANDLE;
-
- *pPosition = file->filePos;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- *
- * EAS_HWFileSeek
- *
- * Seek to a specific location in the file
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, hwInstData) hwInstData available for customer use */
-EAS_RESULT EAS_HWFileSeek (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, EAS_I32 position)
-{
- EAS_I32 newIndex;
-
- /* check handle integrity */
- if (file->pFile == NULL)
- return EAS_ERROR_INVALID_HANDLE;
-
- /* check for seek past end */
- if ((position < 0) || (position > file->fileSize))
- return EAS_ERROR_FILE_SEEK;
-
-#ifdef DEBUG_FILE_IO
- EAS_ReportX(_EAS_SEVERITY_NOFILTER, "EAS_HWFileSeek: Seeking to new position %d\n", file->filePos);
-#endif
-
- /* is new position in current buffer? */
- newIndex = position - file->filePos + file->readIndex;
- if ((newIndex >= 0) && (newIndex < file->bytesInBuffer))
- {
- file->readIndex = newIndex;
- file->filePos = position;
- return EAS_SUCCESS;
- }
-
- /* save new position and reset buffer info so EAS_HWGetByte doesn't fail */
- file->filePos = position;
- file->bytesInBuffer = 0;
- file->readIndex = 0;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- *
- * EAS_HWFileSeekOfs
- *
- * Seek forward or back relative to the current position
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, hwInstData) hwInstData available for customer use */
-EAS_RESULT EAS_HWFileSeekOfs (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, EAS_I32 position)
-{
- EAS_I32 temp;
-
-#ifdef DEBUG_FILE_IO
- EAS_ReportX(_EAS_SEVERITY_NOFILTER, "EAS_HWFileSeekOfs: Seeking to new position %d\n", file->filePos + position);
-#endif
-
- /* check handle integrity */
- if (file->pFile == NULL)
- return EAS_ERROR_INVALID_HANDLE;
-
- /* check for seek past end */
- temp = file->filePos + position;
- if ((temp < 0) || (temp > file->fileSize))
- return EAS_ERROR_FILE_SEEK;
-
- /* is new position in current buffer? */
- temp = position + file->readIndex;
- if ((temp >= 0) && (temp < file->bytesInBuffer))
- {
- file->readIndex = temp;
- file->filePos += position;
- return EAS_SUCCESS;
- }
-
- /* save new position and reset buffer info so EAS_HWGetByte doesn't fail */
- file->filePos += position;
- file->bytesInBuffer = 0;
- file->readIndex = 0;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- *
- * EAS_HWFileLength
- *
- * Return the file length
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, hwInstData) hwInstData available for customer use */
-EAS_RESULT EAS_HWFileLength (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, EAS_I32 *pLength)
-{
- long pos;
-
- /* check handle integrity */
- if (file->pFile == NULL)
- return EAS_ERROR_INVALID_HANDLE;
-
- if ((pos = ftell(file->pFile)) == -1L)
- return EAS_ERROR_FILE_LENGTH;
- if (fseek(file->pFile, 0L, SEEK_END) != 0)
- return EAS_ERROR_FILE_LENGTH;
- if ((*pLength = ftell(file->pFile)) == -1L)
- return EAS_ERROR_FILE_LENGTH;
- if (fseek(file->pFile, pos, SEEK_SET) != 0)
- return EAS_ERROR_FILE_LENGTH;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- *
- * EAS_HWDupHandle
- *
- * Duplicate a file handle
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT EAS_HWDupHandle (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, EAS_FILE_HANDLE* pDupFile)
-{
- EAS_HW_FILE *dupfile;
- int i;
-
- /* check handle integrity */
- *pDupFile = NULL;
- if (file->pFile == NULL)
- return EAS_ERROR_INVALID_HANDLE;
-
- /* find an empty entry in the file table */
- dupfile = hwInstData->files;
- for (i = 0; i < EAS_MAX_FILE_HANDLES; i++)
- {
- /* is this slot being used? */
- if (dupfile->pFile == NULL)
- {
-
- /* copy info from the handle to be duplicated */
- dupfile->filePos = file->filePos;
- dupfile->pFile = file->pFile;
- dupfile->fileSize = file->fileSize;
-
- /* set the duplicate handle flag */
- dupfile->dup = file->dup = EAS_TRUE;
-
- /* initialize some values */
- dupfile->bytesInBuffer = 0;
- dupfile->readIndex = 0;
-
- *pDupFile = dupfile;
- return EAS_SUCCESS;
- }
- dupfile++;
- }
-
- /* too many open files */
- return EAS_ERROR_MAX_FILES_OPEN;
-}
-
-/*----------------------------------------------------------------------------
- *
- * EAS_HWClose
- *
- * Wrapper for fclose function
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT EAS_HWCloseFile (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file1)
-{
- EAS_HW_FILE *file2,*dupFile;
- int i;
-
- /* check handle integrity */
- if (file1->pFile == NULL)
- return EAS_ERROR_INVALID_HANDLE;
-
- /* check for duplicate handle */
- if (file1->dup)
- {
- dupFile = NULL;
- file2 = hwInstData->files;
- for (i = 0; i < EAS_MAX_FILE_HANDLES; i++)
- {
- /* check for duplicate */
- if ((file1 != file2) && (file2->pFile == file1->pFile))
- {
- /* is there more than one duplicate? */
- if (dupFile != NULL)
- {
- /* clear this entry and return */
- file1->pFile = NULL;
- return EAS_SUCCESS;
- }
-
- /* this is the first duplicate found */
- dupFile = file2;
- }
- file2++;
- }
-
- /* there is only one duplicate, clear the dup flag */
- if (dupFile)
- dupFile->dup = EAS_FALSE;
- else
- /* if we get here, there's a serious problem */
- return EAS_ERROR_HANDLE_INTEGRITY;
-
- /* clear this entry and return */
- file1->pFile = NULL;
- return EAS_SUCCESS;
- }
-
- /* no duplicates - close the file */
- if (fclose(file1->pFile) != 0)
- return EAS_ERROR_CLOSE_FAILED;
-
- /* clear this entry and return */
- file1->pFile = NULL;
- return EAS_SUCCESS;
-}
-#else
-/*----------------------------------------------------------------------------
- *
- * EAS_HWOpenFile
- *
- * Open a file for read or write
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT EAS_HWOpenFile (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_LOCATOR locator, EAS_FILE_HANDLE *pFile, EAS_FILE_MODE mode)
-{
- EAS_HW_FILE *file;
- FILE *ioFile;
- int i, temp;
-
- /* set return value to NULL */
- *pFile = NULL;
-
- /* simulate failure */
- if (errorConditions[eOpenError])
- return EAS_FAILURE;
-
- /* only support read mode at this time */
- if (mode != EAS_FILE_READ)
- return EAS_ERROR_INVALID_FILE_MODE;
-
- /* find an empty entry in the file table */
- file = hwInstData->files;
- for (i = 0; i < EAS_MAX_FILE_HANDLES; i++)
- {
- /* is this slot being used? */
- if (file->buffer == NULL)
- {
- /* open the file */
- if ((ioFile = fopen(locator,"rb")) == NULL)
- return EAS_ERROR_FILE_OPEN_FAILED;
-
- /* determine the file size */
- if (fseek(ioFile, 0L, SEEK_END) != 0)
- return EAS_ERROR_FILE_LENGTH;
- if ((file->fileSize = ftell(ioFile)) == -1L)
- return EAS_ERROR_FILE_LENGTH;
- if (fseek(ioFile, 0L, SEEK_SET) != 0)
- return EAS_ERROR_FILE_LENGTH;
-
- /* allocate a buffer */
- file->buffer = EAS_HWMalloc(hwInstData, file->fileSize);
- if (file->buffer == NULL)
- {
- fclose(ioFile);
- return EAS_ERROR_MALLOC_FAILED;
- }
-
- /* read the file into memory */
- temp = (int) fread(file->buffer, (size_t) file->fileSize, 1, ioFile);
-
- /* close the file - don't need it any more */
- fclose(ioFile);
-
- /* check for error reading file */
- if (temp != 1)
- return EAS_ERROR_FILE_READ_FAILED;
-
- /* initialize some values */
- file->filePos = 0;
- file->dup = EAS_FALSE;
-
- *pFile = file;
- return EAS_SUCCESS;
- }
- file++;
- }
-
- /* too many open files */
- return EAS_ERROR_MAX_FILES_OPEN;
-}
-
-/*----------------------------------------------------------------------------
- *
- * EAS_HWReadFile
- *
- * Read data from a file
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, hwInstData) available for customer use */
-EAS_RESULT EAS_HWReadFile (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, void *pBuffer, EAS_I32 n, EAS_I32 *pBytesRead)
-{
- EAS_I32 count;
-
- /* simulate failure */
- if (errorConditions[eReadError])
- return EAS_FAILURE;
-
- /* make sure we have a valid handle */
- if (file->buffer == NULL)
- return EAS_ERROR_INVALID_HANDLE;
-
- /* calculate the bytes to read */
- count = file->fileSize - file->filePos;
- if (n < count)
- count = n;
-
- /* copy the data to the requested location, and advance the pointer */
- if (count)
- EAS_HWMemCpy(pBuffer, &file->buffer[file->filePos], count);
- file->filePos += count;
- *pBytesRead = count;
-
- /* were n bytes read? */
- if (count!= n)
- return EAS_EOF;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- *
- * EAS_HWGetByte
- *
- * Read a byte from a file
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -e{715} hwInstData available for customer use */
-EAS_RESULT EAS_HWGetByte (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, void *p)
-{
-
- /* simulate failure */
- if (errorConditions[eReadError])
- return EAS_FAILURE;
-
- /* make sure we have a valid handle */
- if (file->buffer == NULL)
- return EAS_ERROR_INVALID_HANDLE;
-
- /* check for end of file */
- if (file->filePos >= file->fileSize)
- {
- *((EAS_U8*) p) = 0;
- return EAS_EOF;
- }
-
- /* get a character from the buffer */
- *((EAS_U8*) p) = file->buffer[file->filePos++];
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- *
- * EAS_HWGetWord
- *
- * Returns the current location in the file
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, hwInstData) available for customer use */
-EAS_RESULT EAS_HWGetWord (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, void *p, EAS_BOOL msbFirst)
-{
- EAS_RESULT result;
- EAS_U8 c1, c2;
-
- /* read 2 bytes from the file */
- if ((result = EAS_HWGetByte(hwInstData, file, &c1)) != EAS_SUCCESS)
- return result;
- if ((result = EAS_HWGetByte(hwInstData, file, &c2)) != EAS_SUCCESS)
- return result;
-
- /* order them as requested */
- if (msbFirst)
- *((EAS_U16*) p) = ((EAS_U16) c1 << 8) | c2;
- else
- *((EAS_U16*) p) = ((EAS_U16) c2 << 8) | c1;
-
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- *
- * EAS_HWGetDWord
- *
- * Returns the current location in the file
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, hwInstData) available for customer use */
-EAS_RESULT EAS_HWGetDWord (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, void *p, EAS_BOOL msbFirst)
-{
- EAS_RESULT result;
- EAS_U8 c1, c2,c3,c4;
-
- /* read 4 bytes from the file */
- if ((result = EAS_HWGetByte(hwInstData, file, &c1)) != EAS_SUCCESS)
- return result;
- if ((result = EAS_HWGetByte(hwInstData, file, &c2)) != EAS_SUCCESS)
- return result;
- if ((result = EAS_HWGetByte(hwInstData, file, &c3)) != EAS_SUCCESS)
- return result;
- if ((result = EAS_HWGetByte(hwInstData, file, &c4)) != EAS_SUCCESS)
- return result;
-
- /* order them as requested */
- if (msbFirst)
- *((EAS_U32*) p) = ((EAS_U32) c1 << 24) | ((EAS_U32) c2 << 16) | ((EAS_U32) c3 << 8) | c4;
- else
- *((EAS_U32*) p)= ((EAS_U32) c4 << 24) | ((EAS_U32) c3 << 16) | ((EAS_U32) c2 << 8) | c1;
-
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- *
- * EAS_HWFilePos
- *
- * Returns the current location in the file
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, hwInstData) available for customer use */
-EAS_RESULT EAS_HWFilePos (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, EAS_I32 *pPosition)
-{
-
- /* simulate failure */
- if (errorConditions[ePosError])
- return EAS_FAILURE;
-
- /* make sure we have a valid handle */
- if (file->buffer == NULL)
- return EAS_ERROR_INVALID_HANDLE;
-
- *pPosition = file->filePos;
- return EAS_SUCCESS;
-} /* end EAS_HWFilePos */
-
-/*----------------------------------------------------------------------------
- *
- * EAS_HWFileSeek
- *
- * Seek to a specific location in the file
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, hwInstData) available for customer use */
-EAS_RESULT EAS_HWFileSeek (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, EAS_I32 position)
-{
-
- /* simulate failure */
- if (errorConditions[eSeekError])
- return EAS_FAILURE;
-
- /* make sure we have a valid handle */
- if (file->buffer == NULL)
- return EAS_ERROR_INVALID_HANDLE;
-
- /* validate new position */
- if ((position < 0) || (position > file->fileSize))
- return EAS_ERROR_FILE_SEEK;
-
- /* save new position */
- file->filePos = position;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- *
- * EAS_HWFileSeekOfs
- *
- * Seek forward or back relative to the current position
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, hwInstData) available for customer use */
-EAS_RESULT EAS_HWFileSeekOfs (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, EAS_I32 position)
-{
-
- /* simulate failure */
- if (errorConditions[eSeekError])
- return EAS_FAILURE;
-
- /* make sure we have a valid handle */
- if (file->buffer == NULL)
- return EAS_ERROR_INVALID_HANDLE;
-
- /* determine the file position */
- position += file->filePos;
- if ((position < 0) || (position > file->fileSize))
- return EAS_ERROR_FILE_SEEK;
-
- /* save new position */
- file->filePos = position;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- *
- * EAS_HWFileLength
- *
- * Return the file length
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, hwInstData) available for customer use */
-EAS_RESULT EAS_HWFileLength (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, EAS_I32 *pLength)
-{
-
- /* simulate failure */
- if (errorConditions[eLengthError])
- return EAS_FAILURE;
-
- /* make sure we have a valid handle */
- if (file->buffer == NULL)
- return EAS_ERROR_INVALID_HANDLE;
-
- *pLength = file->fileSize;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- *
- * EAS_HWDupHandle
- *
- * Duplicate a file handle
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT EAS_HWDupHandle (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, EAS_FILE_HANDLE *pDupFile)
-{
- EAS_HW_FILE *dupFile;
- int i;
-
- /* simulate failure */
- if (errorConditions[eDupError])
- return EAS_FAILURE;
-
- /* make sure we have a valid handle */
- if (file->buffer == NULL)
- return EAS_ERROR_INVALID_HANDLE;
-
- /* find an empty entry in the file table */
- dupFile = hwInstData->files;
- for (i = 0; i < EAS_MAX_FILE_HANDLES; i++)
- {
- /* is this slot being used? */
- if (dupFile->buffer == NULL)
- {
-
- /* copy info from the handle to be duplicated */
- dupFile->filePos = file->filePos;
- dupFile->fileSize = file->fileSize;
- dupFile->buffer = file->buffer;
-
- /* set the duplicate handle flag */
- dupFile->dup = file->dup = EAS_TRUE;
-
- *pDupFile = dupFile;
- return EAS_SUCCESS;
- }
- dupFile++;
- }
-
- /* too many open files */
- return EAS_ERROR_MAX_FILES_OPEN;
-}
-
-/*----------------------------------------------------------------------------
- *
- * EAS_HWClose
- *
- * Wrapper for fclose function
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT EAS_HWCloseFile (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file1)
-{
- EAS_HW_FILE *file2,*dupFile;
- int i;
-
- /* simulate failure */
- if (errorConditions[eCloseError])
- return EAS_FAILURE;
-
- /* make sure we have a valid handle */
- if (file1->buffer == NULL)
- return EAS_ERROR_INVALID_HANDLE;
-
- /* check for duplicate handle */
- if (file1->dup)
- {
- dupFile = NULL;
- file2 = hwInstData->files;
- for (i = 0; i < EAS_MAX_FILE_HANDLES; i++)
- {
- /* check for duplicate */
- if ((file1 != file2) && (file2->buffer == file1->buffer))
- {
- /* is there more than one duplicate? */
- if (dupFile != NULL)
- {
- /* clear this entry and return */
- file1->buffer = NULL;
- return EAS_SUCCESS;
- }
-
- /* this is the first duplicate found */
- else
- dupFile = file2;
- }
- file2++;
- }
-
- /* there is only one duplicate, clear the dup flag */
- if (dupFile)
- dupFile->dup = EAS_FALSE;
- else
- /* if we get here, there's a serious problem */
- return EAS_ERROR_HANDLE_INTEGRITY;
-
- /* clear this entry and return */
- file1->buffer = NULL;
- return EAS_SUCCESS;
- }
-
- /* no duplicates -free the buffer */
- EAS_HWFree(hwInstData, file1->buffer);
-
- /* clear this entry and return */
- file1->buffer = NULL;
- return EAS_SUCCESS;
-}
-#endif
-
-/*----------------------------------------------------------------------------
- *
- * EAS_HWVibrate
- *
- * Turn on/off vibrate function
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, hwInstData) available for customer use */
-EAS_RESULT EAS_HWVibrate (EAS_HW_DATA_HANDLE hwInstData, EAS_BOOL state)
-{
- vibState = state;
-// EAS_ReportX(_EAS_SEVERITY_NOFILTER, "Vibrate state: %d\n", state);
- return EAS_SUCCESS;
-} /* end EAS_HWVibrate */
-
-/*----------------------------------------------------------------------------
- *
- * EAS_HWLED
- *
- * Turn on/off LED
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, hwInstData) available for customer use */
-EAS_RESULT EAS_HWLED (EAS_HW_DATA_HANDLE hwInstData, EAS_BOOL state)
-{
- ledState = state;
-// EAS_ReportX(_EAS_SEVERITY_NOFILTER, "LED state: %d\n", state);
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- *
- * EAS_HWBackLight
- *
- * Turn on/off backlight
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, hwInstData) available for customer use */
-EAS_RESULT EAS_HWBackLight (EAS_HW_DATA_HANDLE hwInstData, EAS_BOOL state)
-{
- backlightState = state;
-// EAS_ReportX(_EAS_SEVERITY_NOFILTER, "Backlight state: %d\n", state);
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- *
- * EAS_HWYield
- *
- * This function is called periodically by the EAS library to give the
- * host an opportunity to allow other tasks to run. There are two ways to
- * use this call:
- *
- * If you have a multi-tasking OS, you can call the yield function in the
- * OS to allow other tasks to run. In this case, return EAS_FALSE to tell
- * the EAS library to continue processing when control returns from this
- * function.
- *
- * If tasks run in a single thread by sequential function calls (sometimes
- * call a "commutator loop"), return EAS_TRUE to cause the EAS Library to
- * return to the caller. Be sure to check the number of bytes rendered
- * before passing the audio buffer to the codec - it may not be filled.
- * The next call to EAS_Render will continue processing until the buffer
- * has been filled.
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, hwInstData) available for customer use */
-EAS_BOOL EAS_HWYield (EAS_HW_DATA_HANDLE hwInstData)
-{
- /* put your code here */
- return EAS_FALSE;
-}
-
-
+/*
+ * EASLib.c
+ * EASLIb
+ *
+ *
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <string.h>
+
+#include "eas.h"
+#include "eas_report.h"
+#include "eas_host.h"
+#include <AudioUnit/AudioUnit.h>
+#include <CoreServices/CoreServices.h>
+
+#ifdef JET_INTERFACE
+#include "jet.h"
+#endif
+
+
+#define EAS_EXPORT __attribute__((visibility("default")))
+
+// #define DEBUG_FILE_IO
+
+/* include debug interface */
+#include "eas_host_debug.h"
+
+#ifdef AUX_MIXER
+#include "eas_auxmix.h"
+#endif
+
+/* this module requires dynamic memory support */
+#ifdef _STATIC_MEMORY
+#error "eas_hostmm.c requires the dynamic memory model!\n"
+#endif
+
+#ifndef EAS_MAX_FILE_HANDLES
+#define EAS_MAX_FILE_HANDLES 32
+#endif
+
+#ifndef EAS_FILE_BUFFER_SIZE
+#define EAS_FILE_BUFFER_SIZE 32
+#endif
+
+/*
+ * this structure and the related function are here
+ * to support the ability to create duplicate handles
+ * and buffering it in memory. If your system uses
+ * in-memory resources, you can eliminate the calls
+ * to malloc and free, the dup flag, and simply track
+ * the file size and read position.
+ */
+ #ifdef BUFFERED_FILE_ACCESS
+typedef struct eas_hw_file_tag
+{
+ FILE *pFile;
+ EAS_I32 bytesInBuffer;
+ EAS_I32 readIndex;
+ EAS_I32 filePos;
+ EAS_I32 fileSize;
+ EAS_BOOL dup;
+ EAS_U8 buffer[EAS_FILE_BUFFER_SIZE];
+} EAS_HW_FILE;
+#else
+typedef struct eas_hw_file_tag
+{
+ EAS_I32 fileSize;
+ EAS_I32 filePos;
+ EAS_BOOL dup;
+ EAS_U8 *buffer;
+} EAS_HW_FILE;
+#endif
+
+typedef struct eas_hw_inst_data_tag
+{
+ EAS_HW_FILE files[EAS_MAX_FILE_HANDLES];
+} EAS_HW_INST_DATA;
+
+EAS_BOOL errorConditions[eNumErrorConditions];
+EAS_BOOL ledState;
+EAS_BOOL vibState;
+EAS_BOOL backlightState;
+
+#define MAX_DEBUG_MSG_LEN 1024
+
+typedef void (*EAS_LOG_FUNC)(EAS_INT severity, char *msg);
+
+static EAS_LOG_FUNC logCallback = NULL;
+static char messageBuffer[MAX_DEBUG_MSG_LEN];
+
+/* error counts */
+static EAS_INT eas_fatalErrors;
+static EAS_INT eas_errors;
+static EAS_INT eas_warnings;
+static int severityLevel = 9999;
+
+
+#define MAX_BUFFERS 8
+
+// The output unit
+AudioUnit OutputUnit;
+AudioStreamBasicDescription streamFormat;
+
+// sync stuf
+pthread_mutex_t mtx;
+pthread_cond_t cond;
+bool bStopped = true;
+
+// buffer to hold the data
+typedef struct
+{
+ UInt32 uOutBufferLength;
+ UInt32 uOutFrames;
+ int ix;
+ short* pData[8];
+ unsigned int uLength;
+} S_BUFFER_INFO;
+
+static S_BUFFER_INFO *pBuf = NULL;
+const S_EAS_LIB_CONFIG *pConfig = NULL;
+
+/*----------------------------------------------------------------------------
+ * ResetErrorCounters()
+ *----------------------------------------------------------------------------
+*/
+EAS_EXPORT void ResetErrorCounters()
+{
+ eas_fatalErrors = 0;
+ eas_errors = 0;
+ eas_warnings = 0;
+}
+
+/*----------------------------------------------------------------------------
+ * SetLogCallback()
+ *----------------------------------------------------------------------------
+*/
+EAS_EXPORT void SetLogCallback (EAS_LOG_FUNC callback)
+{
+ logCallback = callback;
+}
+
+#ifndef _NO_DEBUG_PREPROCESSOR
+static S_DEBUG_MESSAGES debugMessages[] =
+{
+#ifdef UNIFIED_DEBUG_MESSAGES
+#include "eas_debugmsgs.h"
+#endif
+ { 0,0,0 }
+};
+
+/*----------------------------------------------------------------------------
+ * EAS_ReportEx()
+ *----------------------------------------------------------------------------
+*/
+void EAS_ReportEx (int severity, unsigned long hashCode, int serialNum, ...)
+{
+ va_list vargs;
+ int i;
+
+ switch (severity)
+ {
+ case _EAS_SEVERITY_FATAL:
+ eas_fatalErrors++;
+ break;
+
+ case _EAS_SEVERITY_ERROR:
+ eas_errors++;
+ break;
+
+ case _EAS_SEVERITY_WARNING:
+ eas_warnings++;
+ break;
+
+ default:
+ break;
+ }
+
+ /* check severity level */
+ if (severity > severityLevel)
+ return;
+
+ /* check for callback */
+ if (logCallback == NULL)
+ return;
+
+ /* find the error message and output to stdout */
+ for (i = 0; debugMessages[i].m_pDebugMsg; i++)
+ {
+ if ((debugMessages[i].m_nHashCode == hashCode) &&
+ (debugMessages[i].m_nSerialNum == serialNum))
+ {
+ va_start(vargs, serialNum);
+#ifdef WIN32
+ vsprintf_s(messageBuffer, sizeof(messageBuffer), fmt, vargs);
+#else
+ vsprintf(messageBuffer, debugMessages[i].m_pDebugMsg, vargs);
+#endif
+ logCallback(severity, messageBuffer);
+ va_end(vargs);
+ return;
+ }
+ }
+ printf("Unrecognized error: Severity=%d; HashCode=%lu; SerialNum=%d\n", severity, hashCode, serialNum);
+} /* end EAS_ReportEx */
+
+#else
+/*----------------------------------------------------------------------------
+ * EAS_Report()
+ *----------------------------------------------------------------------------
+*/
+void EAS_Report (int severity, const char *fmt, ...)
+{
+ va_list vargs;
+
+ switch (severity)
+ {
+ case _EAS_SEVERITY_FATAL:
+ eas_fatalErrors++;
+ break;
+
+ case _EAS_SEVERITY_ERROR:
+ eas_errors++;
+ break;
+
+ case _EAS_SEVERITY_WARNING:
+ eas_warnings++;
+ break;
+
+ default:
+ break;
+ }
+
+ /* check severity level */
+ if (severity > severityLevel)
+ return;
+
+ /* check for callback */
+ if (logCallback == NULL)
+ return;
+
+ va_start(vargs, fmt);
+#ifdef _WIN32
+ vsprintf_s(messageBuffer, sizeof(messageBuffer), fmt, vargs);
+#else
+ vsprintf(messageBuffer, fmt, vargs);
+#endif
+ logCallback(severity, messageBuffer);
+ va_end(vargs);
+} /* end EAS_Report */
+
+/*----------------------------------------------------------------------------
+ * EAS_ReportX()
+ *----------------------------------------------------------------------------
+*/
+void EAS_ReportX (int severity, const char *fmt, ...)
+{
+ va_list vargs;
+
+ switch (severity)
+ {
+ case _EAS_SEVERITY_FATAL:
+ eas_fatalErrors++;
+ break;
+
+ case _EAS_SEVERITY_ERROR:
+ eas_errors++;
+ break;
+
+ case _EAS_SEVERITY_WARNING:
+ eas_warnings++;
+ break;
+
+ default:
+ break;
+ }
+
+ /* check severity level */
+ if (severity > severityLevel)
+ return;
+
+ /* check for callback */
+ if (logCallback == NULL)
+ return;
+
+ va_start(vargs, fmt);
+#ifdef _WIN32
+ vsprintf_s(messageBuffer, sizeof(messageBuffer), fmt, vargs);
+#else
+ vsprintf(messageBuffer, fmt, vargs);
+#endif
+ logCallback(severity, messageBuffer);
+ va_end(vargs);
+}
+#endif
+
+/*----------------------------------------------------------------------------
+ * EAS_DLLSetDebugLevel()
+ *----------------------------------------------------------------------------
+*/
+EAS_EXPORT void EAS_DLLSetDebugLevel (int severity)
+{
+ severityLevel = severity;
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_ExSetDebugLevel()
+ *----------------------------------------------------------------------------
+*/
+void EAS_SetDebugLevel (int severity)
+{
+ severityLevel = severity;
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_SelectLibrary()
+ *----------------------------------------------------------------------------
+*/
+EAS_EXPORT EAS_RESULT EAS_SelectLib (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle, EAS_BOOL testLib)
+{
+ extern EAS_SNDLIB_HANDLE VMGetLibHandle(EAS_INT libNum);
+ return EAS_SetSoundLibrary(pEASData, streamHandle, VMGetLibHandle(testLib ? 1 : 0));
+}
+
+// Callback proc
+static OSStatus RenderProc( void *inRefCon,
+ AudioUnitRenderActionFlags *ioActionFlags,
+ const AudioTimeStamp *inTimeStamp,
+ UInt32 inBusNumber,
+ UInt32 inNumberFrames,
+ AudioBufferList *ioData)
+{
+ // Get the mutex
+ pthread_mutex_lock(&mtx);
+
+ short* ptrOutL = (short *)ioData->mBuffers[0].mData;
+ short* ptrOutR = (short *)ioData->mBuffers[1].mData;
+
+ memset(ptrOutL, 0, pBuf->uOutFrames);
+ memset(ptrOutR, 0, pBuf->uOutFrames);
+
+ // check if there is any data in the buffer
+ if (pBuf->ix == 0 )
+ {
+ // Release the mutex and signal the python thread
+ pthread_mutex_unlock(&mtx);
+ pthread_cond_signal(&cond);
+ return 0;
+ }
+
+ // Get a ptr to the data
+ short* pData = pBuf->pData[--(pBuf->ix)];
+
+ // Now copy the data
+ int i;
+ for (i = 0; i < pBuf->uOutFrames; i+=2 )
+ {
+ *ptrOutL++ = pData[i];
+ *ptrOutR++ = pData[i+1];
+ }
+
+ // Release the mutex
+ pthread_mutex_unlock(&mtx);
+ pthread_cond_signal(&cond);
+
+ return 0;
+}
+
+EAS_RESULT addData(EAS_PCM *pAudioBuffer)
+{
+ // Copy the data we got from the synth
+ memcpy(pBuf->pData[(pBuf->ix)++], pAudioBuffer, 2048);
+
+ // Start the output Audio Unit only the first time
+ if ( bStopped == true )
+ {
+ bStopped = false;
+ OSStatus err = AudioOutputUnitStart (OutputUnit);
+ if (err)
+ {
+ printf ("AudioDeviceStart=%ld\n", err);
+ return EAS_FAILURE;
+ }
+ }
+
+ return EAS_SUCCESS;
+}
+
+
+EAS_EXPORT EAS_RESULT EAS_RenderWaveOut(EAS_DATA_HANDLE easHandle, EAS_PCM *pAudioBuffer, EAS_I32 numRequested, EAS_I32 *pNumGenerated)
+{
+ // Get the mutex
+ pthread_mutex_lock(&mtx);
+
+ // Check if our buffer is full
+ while(pBuf->ix == MAX_BUFFERS - 1)
+ pthread_cond_wait(&cond, &mtx);
+
+ // Call the synth the render a buffer
+ EAS_RESULT result = EAS_Render(easHandle, pAudioBuffer, numRequested, pNumGenerated);
+ addData( pAudioBuffer );
+
+ // Release the mutex
+ pthread_mutex_unlock(&mtx);
+
+ //Done
+ return result;
+}
+
+#ifdef AUX_MIXER
+EAS_EXPORT EAS_RESULT EAS_RenderAuxMixerWaveOut (EAS_DATA_HANDLE easHandle, EAS_PCM *pAudioBuffer, EAS_I32 *pNumGenerated)
+{
+ // Get the mutex
+ pthread_mutex_lock(&mtx);
+
+ // Check if our buffer is full
+ while(pBuf->ix == MAX_BUFFERS - 1)
+ pthread_cond_wait(&cond, &mtx);
+
+ EAS_RESULT result = EAS_RenderAuxMixer(easHandle, pAudioBuffer, pNumGenerated);
+ addData( pAudioBuffer );
+
+ // Release the mutex
+ pthread_mutex_unlock(&mtx);
+
+ return result;
+}
+#endif
+
+EAS_EXPORT EAS_RESULT OpenWaveOutDevice(EAS_INT devNum, EAS_INT sampleRate, EAS_INT maxBufSize)
+{
+ // Open the default output unit
+ ComponentDescription desc;
+ desc.componentType = kAudioUnitType_Output;
+ desc.componentSubType = kAudioUnitSubType_DefaultOutput;
+ desc.componentManufacturer = kAudioUnitManufacturer_Apple;
+ desc.componentFlags = 0;
+ desc.componentFlagsMask = 0;
+
+ Component comp = FindNextComponent(NULL, &desc);
+ if (comp == NULL)
+ {
+ printf ("Could find the default output unit!!!\n");
+ return EAS_FAILURE;
+ }
+
+ OSStatus err = OpenAComponent(comp, &OutputUnit);
+ if (comp == NULL)
+ {
+ printf ("OpenAComponent=%ld\n", err);
+ return EAS_FAILURE;
+ }
+
+ // Set up a callback function to generate output to the output unit
+ AURenderCallbackStruct auRenderCallback;
+ auRenderCallback.inputProc = RenderProc;
+ auRenderCallback.inputProcRefCon = NULL;
+
+ err = AudioUnitSetProperty (OutputUnit,
+ kAudioUnitProperty_SetRenderCallback,
+ kAudioUnitScope_Input,
+ 0,
+ &auRenderCallback,
+ sizeof(auRenderCallback));
+ if (err)
+ {
+ printf ("AudioUnitSetProperty-CB=%ld\n", err);
+ return EAS_FAILURE;;
+ }
+
+ pConfig = EAS_Config();
+
+ // The synth engine already uses short* for the buffers so let CoreAudio do any conversions if needed
+ if (sampleRate != 0)
+ streamFormat.mSampleRate = sampleRate;
+ else
+ streamFormat.mSampleRate = pConfig->sampleRate;
+
+ streamFormat.mFormatID = kAudioFormatLinearPCM;
+ streamFormat.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger
+ | kAudioFormatFlagsNativeEndian
+ | kLinearPCMFormatFlagIsPacked
+ | kAudioFormatFlagIsNonInterleaved;
+
+ streamFormat.mBytesPerPacket = 2;
+ streamFormat.mFramesPerPacket = 1;
+ streamFormat.mBytesPerFrame = 2;
+ streamFormat.mChannelsPerFrame = 2;
+ streamFormat.mBitsPerChannel = 16;
+
+ err = AudioUnitSetProperty (OutputUnit,
+ kAudioUnitProperty_StreamFormat,
+ kAudioUnitScope_Input,
+ 0,
+ &streamFormat,
+ sizeof(AudioStreamBasicDescription));
+ if (err)
+ {
+ printf ("AudioUnitSetProperty-SF= %4.4s, %ld\n", (char*)&err, err);
+ return EAS_FAILURE;
+ }
+
+ // Initialize
+ err = AudioUnitInitialize(OutputUnit);
+ if (err)
+ {
+ printf ("AudioUnitInitialize = %ld\n", err);
+ return EAS_FAILURE;
+ }
+
+ pBuf = (S_BUFFER_INFO *) malloc(sizeof(S_BUFFER_INFO));
+ if( !pBuf )
+ return EAS_FAILURE;
+
+ pBuf->uOutBufferLength = pConfig->mixBufferSize * streamFormat.mBitsPerChannel / 2;
+ UInt32 uDataSize = sizeof(pBuf->uOutBufferLength);
+
+ err = AudioUnitSetProperty(OutputUnit, kAudioDevicePropertyBufferSize, kAudioUnitScope_Output, 0, &pBuf->uOutBufferLength, uDataSize);
+ if (err)
+ {
+ printf ("AudioUnitSetProperty = %ld\n", err);
+ return EAS_FAILURE;
+ }
+
+ err = AudioUnitGetProperty(OutputUnit, kAudioDevicePropertyBufferSize, kAudioUnitScope_Output, 0, &pBuf->uOutBufferLength, &uDataSize);
+ if (err)
+ {
+ printf ("AudioUnitGetProperty = %ld\n", err);
+ return EAS_FAILURE;
+ }
+
+ pBuf->uLength = pBuf->uOutBufferLength;
+ int i;
+ for ( i = 0; i < MAX_BUFFERS; i++)
+ pBuf->pData[i] = malloc(pBuf->uLength);
+
+ pBuf->uOutBufferLength /= pConfig->numChannels;
+ pBuf->uOutFrames = pBuf->uOutBufferLength / sizeof(short);
+
+ pBuf->ix = 0;
+
+ // Init the stop flag
+ bStopped = true;
+
+ int result = pthread_mutex_init(&mtx, NULL);
+ if (result)
+ {
+ printf("pthread_mutex_init failed\n");
+ return EAS_FAILURE;
+ }
+
+ result = pthread_cond_init(&cond, NULL);
+ if (result)
+ {
+ printf("pthread_cond_init failed\n");
+ return EAS_FAILURE;
+ }
+
+ // Done
+ return EAS_SUCCESS;
+}
+
+
+EAS_EXPORT EAS_RESULT StartStream()
+{
+ OSStatus err = noErr;
+ pthread_mutex_lock(&mtx);
+ if ( bStopped == true )
+ {
+ err = AudioOutputUnitStart (OutputUnit);
+ if (err)
+ {
+ printf ("AudioOutputUnitStart=%ld\n", err);
+ return EAS_FAILURE;
+ }
+ bStopped = false;
+ }
+
+ return EAS_SUCCESS;
+}
+
+
+EAS_EXPORT EAS_RESULT CloseWaveOutDevice()
+{
+ OSStatus err;
+
+ pthread_mutex_lock(&mtx);
+ if( false == bStopped )
+ {
+ AudioOutputUnitStop (OutputUnit);
+ bStopped = true;
+
+ err = AudioUnitUninitialize (OutputUnit);
+ if (err)
+ {
+ printf ("AudioUnitUninitialize=%ld\n", err);
+ return EAS_FAILURE;
+ }
+
+ CloseComponent (OutputUnit);
+ int i = 0;
+ for(i; i < MAX_BUFFERS; i++)
+ free(pBuf->pData[i]);
+
+ free(pBuf);
+ }
+
+ pthread_mutex_unlock(&mtx);
+ return EAS_SUCCESS;
+}
+
+
+#if defined(_DEBUG) && !defined(MSC)
+#include <crtdbg.h>
+/*----------------------------------------------------------------------------
+ * EnableHeapDebug()
+ *----------------------------------------------------------------------------
+*/
+static void EnableHeapDebug (void)
+{
+ int temp;
+ temp = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
+ temp |= _CRTDBG_ALLOC_MEM_DF;
+ temp |= _CRTDBG_CHECK_ALWAYS_DF;
+ temp |= _CRTDBG_LEAK_CHECK_DF;
+// temp |= _CRTDBG_DELAY_FREE_MEM_DF;
+ _CrtSetDbgFlag(temp);
+}
+
+/*----------------------------------------------------------------------------
+ * HeapCheck()
+ *----------------------------------------------------------------------------
+ * Check heap status
+ *----------------------------------------------------------------------------
+*/
+void HeapCheck (void)
+{
+ int heapStatus;
+
+ /* Check heap status */
+ heapStatus = _heapchk();
+ if ((heapStatus == _HEAPOK) || (heapStatus == _HEAPEMPTY))
+ return;
+
+ EAS_ReportX(_EAS_SEVERITY_FATAL, "Heap corrupt\n" );
+}
+#endif
+
+
+/*----------------------------------------------------------------------------
+ * EAS_HWInit
+ *
+ * Initialize host wrapper interface
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_HWInit (EAS_HW_DATA_HANDLE *pHWInstData)
+{
+
+#if defined(_DEBUG) && !defined(MSC)
+ EnableHeapDebug();
+#endif
+
+ #ifdef BUFFERED_FILE_ACCESS
+ EAS_ReportX(_EAS_SEVERITY_INFO, "EAS_HWInit: Buffered file access\n");
+ #else
+ EAS_ReportX(_EAS_SEVERITY_INFO, "EAS_HWInit: Memory mapped file access\n");
+ #endif
+
+ /* simulate failure */
+ if (errorConditions[eInitError])
+ return EAS_FAILURE;
+
+ /* need to track file opens for duplicate handles */
+ *pHWInstData = malloc(sizeof(EAS_HW_INST_DATA));
+ if (!(*pHWInstData))
+ return EAS_ERROR_MALLOC_FAILED;
+
+ EAS_HWMemSet(*pHWInstData, 0, sizeof(EAS_HW_INST_DATA));
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_HWShutdown
+ *
+ * Shut down host wrapper interface
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_HWShutdown (EAS_HW_DATA_HANDLE hwInstData)
+{
+
+ /* simulate failure */
+ if (errorConditions[eShutdownError])
+ return EAS_FAILURE;
+
+ free(hwInstData);
+
+#if defined(_DEBUG) && !defined(MSC)
+ HeapCheck();
+#endif
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_HWMalloc
+ *
+ * Allocates dynamic memory
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, hwInstData) available for customer use */
+void *EAS_HWMalloc (EAS_HW_DATA_HANDLE hwInstData, EAS_I32 size)
+{
+ /* simulate failure */
+ if (errorConditions[eMallocError])
+ return NULL;
+
+ return malloc((size_t) size);
+}
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_HWFree
+ *
+ * Frees dynamic memory
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, hwInstData) available for customer use */
+void EAS_HWFree (EAS_HW_DATA_HANDLE hwInstData, void *p)
+{
+ free(p);
+}
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_HWMemCpy
+ *
+ * Copy memory wrapper
+ *
+ *----------------------------------------------------------------------------
+*/
+void *EAS_HWMemCpy (void *dest, const void *src, EAS_I32 amount)
+{
+ return memcpy(dest, src, (size_t) amount);
+}
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_HWMemSet
+ *
+ * Set memory wrapper
+ *
+ *----------------------------------------------------------------------------
+*/
+void *EAS_HWMemSet (void *dest, int val, EAS_I32 amount)
+{
+ return memset(dest, val, (size_t) amount);
+}
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_HWMemCmp
+ *
+ * Compare memory wrapper
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_I32 EAS_HWMemCmp (const void *s1, const void *s2, EAS_I32 amount)
+{
+ return (EAS_I32) memcmp(s1, s2, (size_t) amount);
+}
+
+#ifdef BUFFERED_FILE_ACCESS
+/*----------------------------------------------------------------------------
+ *
+ * EAS_HWOpenFile
+ *
+ * Open a file for read or write
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_HWOpenFile (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_LOCATOR locator, EAS_FILE_HANDLE *pFile, EAS_FILE_MODE mode)
+{
+ EAS_HW_FILE *file;
+ int i;
+
+ /* set return value to NULL */
+ *pFile = NULL;
+
+ /* only support read mode at this time */
+ if (mode != EAS_FILE_READ)
+ return EAS_ERROR_INVALID_FILE_MODE;
+
+ /* find an empty entry in the file table */
+ file = hwInstData->files;
+ for (i = 0; i < EAS_MAX_FILE_HANDLES; i++)
+ {
+ /* is this slot being used? */
+ if (file->pFile == NULL)
+ {
+ EAS_RESULT result;
+
+ /* open the file */
+ file->pFile = fopen((const char*) locator, "rb");
+ if (file->pFile == NULL)
+ return EAS_ERROR_FILE_OPEN_FAILED;
+
+ /* get file length */
+ if ((result = EAS_HWFileLength(hwInstData, file, &file->fileSize)) != EAS_SUCCESS)
+ {
+ EAS_HWCloseFile(hwInstData, file);
+ return result;
+ }
+
+#ifdef DEBUG_FILE_IO
+ EAS_ReportX(_EAS_SEVERITY_NOFILTER, "EAS_HWOpenFile: Open file %d\n", i);
+#endif
+
+ /* initialize some values */
+ file->bytesInBuffer = 0;
+ file->readIndex = 0;
+ file->filePos = 0;
+ file->dup = EAS_FALSE;
+
+ *pFile = file;
+ return EAS_SUCCESS;
+ }
+ file++;
+ }
+
+ /* too many open files */
+ return EAS_ERROR_MAX_FILES_OPEN;
+}
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_HWFillBuffer
+ *
+ * Fill buffer from file
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, hwInstData) hwInstData available for customer use */
+EAS_RESULT EAS_HWFillBuffer (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file)
+{
+ /* reposition the file pointer */
+ if (fseek(file->pFile, file->filePos, SEEK_SET) != 0)
+ return EAS_ERROR_FILE_SEEK;
+
+ /* read some data from the file */
+ file->bytesInBuffer = (EAS_I32) fread(file->buffer, 1, EAS_FILE_BUFFER_SIZE, file->pFile);
+ file->readIndex = 0;
+ if (file->bytesInBuffer == 0)
+ return EAS_EOF;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_HWReadFile
+ *
+ * Read data from a file
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, hwInstData) hwInstData available for customer use */
+EAS_RESULT EAS_HWReadFile (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, void *pBuffer, EAS_I32 n, EAS_I32 *pBytesRead)
+{
+ EAS_RESULT result;
+ EAS_I32 temp;
+ EAS_U8 *p = pBuffer;
+ EAS_I32 bytesLeft = n;
+
+ *pBytesRead = 0;
+
+ /* check handle integrity */
+ if (file->pFile == NULL)
+ return EAS_ERROR_INVALID_HANDLE;
+
+#ifdef DEBUG_FILE_IO
+ EAS_ReportX(_EAS_SEVERITY_NOFILTER, "EAS_HWReadFile: Reading %d bytes from position %d\n", n, file->filePos);
+#endif
+
+ /* try to fulfill request from buffer */
+ for (;bytesLeft > 0;)
+ {
+ /* how many bytes can we get from buffer? */
+ temp = file->bytesInBuffer - file->readIndex;
+ if (temp > bytesLeft)
+ temp = bytesLeft;
+
+ /* copy data from buffer */
+ EAS_HWMemCpy(p, &file->buffer[file->readIndex], temp);
+ *pBytesRead += temp;
+ file->readIndex += temp;
+ file->filePos += temp;
+ p += temp;
+ bytesLeft -= temp;
+
+ /* don't refill buffer if request is bigger than buffer */
+ if ((bytesLeft == 0) || (bytesLeft >= EAS_FILE_BUFFER_SIZE))
+ break;
+
+ /* refill buffer */
+ if ((result = EAS_HWFillBuffer(hwInstData, file)) != EAS_SUCCESS)
+ return result;
+ }
+
+ /* more to read? do unbuffered read directly to target memory */
+ if (bytesLeft)
+ {
+
+ /* position the file pointer */
+ if (fseek(file->pFile, file->filePos, SEEK_SET) != 0)
+ return EAS_ERROR_FILE_SEEK;
+
+ /* read data in the buffer */
+ temp = (EAS_I32) fread(p, 1, (size_t) bytesLeft, file->pFile);
+ *pBytesRead += temp;
+ file->filePos += temp;
+
+ /* reset buffer info */
+ file->bytesInBuffer = 0;
+ file->readIndex = 0;
+ }
+
+#ifdef DEBUG_FILE_IO
+ {
+#define BYTES_PER_LINE 16
+ char str[BYTES_PER_LINE * 3 + 1];
+ EAS_INT i;
+ for (i = 0; i < (n > BYTES_PER_LINE ? BYTES_PER_LINE : n) ; i ++)
+ sprintf(&str[i*3], "%02x ", ((EAS_U8*)pBuffer)[i]);
+ if (i)
+ EAS_ReportX(_EAS_SEVERITY_NOFILTER, "%s\n", str);
+ }
+#endif
+
+ /* were n bytes read? */
+ if (*pBytesRead != n)
+ return EAS_EOF;
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_HWGetByte
+ *
+ * Read a byte from a file
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, hwInstData) hwInstData available for customer use */
+EAS_RESULT EAS_HWGetByte (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, void *p)
+{
+ EAS_RESULT result;
+
+ /* check handle integrity */
+ if (file->pFile == NULL)
+ return EAS_ERROR_INVALID_HANDLE;
+
+ /* use local buffer - do we have any data? */
+ if (file->readIndex >= file->bytesInBuffer)
+ {
+ if ((result = EAS_HWFillBuffer(hwInstData, file)) != EAS_SUCCESS)
+ return result;
+
+ /* if nothing to read, return EOF */
+ if (file->bytesInBuffer == 0)
+ return EAS_EOF;
+ }
+
+ /* get a character from the buffer */
+ *((EAS_U8*) p) = file->buffer[file->readIndex++];
+
+#ifdef DEBUG_FILE_IO
+ EAS_ReportX(_EAS_SEVERITY_NOFILTER, "EAS_HWGetByte: Reading from position %d, byte = 0x%02x\n", file->filePos, *(EAS_U8*)p);
+#endif
+
+ file->filePos++;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_HWGetWord
+ *
+ * Read a 16-bit value from the file
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_HWGetWord (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, void *p, EAS_BOOL msbFirst)
+{
+ EAS_RESULT result;
+ EAS_I32 count;
+ EAS_U8 c[2];
+
+#ifdef DEBUG_FILE_IO
+ EAS_ReportX(_EAS_SEVERITY_NOFILTER, "EAS_HWGetWord: Reading 2 bytes from position %d\n", file->filePos);
+#endif
+
+ /* read 2 bytes from the file */
+ if ((result = EAS_HWReadFile(hwInstData, file, c, 2, &count)) != EAS_SUCCESS)
+ return result;
+
+ /* order them as requested */
+ if (msbFirst)
+ *((EAS_U16*) p) = ((EAS_U16) c[0] << 8) | c[1];
+ else
+ *((EAS_U16*) p) = ((EAS_U16) c[1] << 8) | c[0];
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_HWGetDWord
+ *
+ * Read a 16-bit value from the file
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_HWGetDWord (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, void *p, EAS_BOOL msbFirst)
+{
+ EAS_RESULT result;
+ EAS_I32 count;
+ EAS_U8 c[4];
+
+#ifdef DEBUG_FILE_IO
+ EAS_ReportX(_EAS_SEVERITY_NOFILTER, "EAS_HWGetDWord: Reading 4 bytes from position %d\n", file->filePos);
+#endif
+
+ /* read 4 bytes from the file */
+ if ((result = EAS_HWReadFile(hwInstData, file, c, 4, &count)) != EAS_SUCCESS)
+ return result;
+
+ /* order them as requested */
+ if (msbFirst)
+ *((EAS_U32*) p) = ((EAS_U32) c[0] << 24) | ((EAS_U32) c[1] << 16) | ((EAS_U32) c[2] << 8) | c[3];
+ else
+ *((EAS_U32*) p) = ((EAS_U32) c[3] << 24) | ((EAS_U32) c[2] << 16) | ((EAS_U32) c[1] << 8) | c[0];
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_HWFilePos
+ *
+ * Returns the current location in the file
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, hwInstData) hwInstData available for customer use */
+EAS_RESULT EAS_HWFilePos (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, EAS_I32 *pPosition)
+{
+
+ /* check handle integrity */
+ if (file->pFile == NULL)
+ return EAS_ERROR_INVALID_HANDLE;
+
+ *pPosition = file->filePos;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_HWFileSeek
+ *
+ * Seek to a specific location in the file
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, hwInstData) hwInstData available for customer use */
+EAS_RESULT EAS_HWFileSeek (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, EAS_I32 position)
+{
+ EAS_I32 newIndex;
+
+ /* check handle integrity */
+ if (file->pFile == NULL)
+ return EAS_ERROR_INVALID_HANDLE;
+
+ /* check for seek past end */
+ if ((position < 0) || (position > file->fileSize))
+ return EAS_ERROR_FILE_SEEK;
+
+#ifdef DEBUG_FILE_IO
+ EAS_ReportX(_EAS_SEVERITY_NOFILTER, "EAS_HWFileSeek: Seeking to new position %d\n", file->filePos);
+#endif
+
+ /* is new position in current buffer? */
+ newIndex = position - file->filePos + file->readIndex;
+ if ((newIndex >= 0) && (newIndex < file->bytesInBuffer))
+ {
+ file->readIndex = newIndex;
+ file->filePos = position;
+ return EAS_SUCCESS;
+ }
+
+ /* save new position and reset buffer info so EAS_HWGetByte doesn't fail */
+ file->filePos = position;
+ file->bytesInBuffer = 0;
+ file->readIndex = 0;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_HWFileSeekOfs
+ *
+ * Seek forward or back relative to the current position
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, hwInstData) hwInstData available for customer use */
+EAS_RESULT EAS_HWFileSeekOfs (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, EAS_I32 position)
+{
+ EAS_I32 temp;
+
+#ifdef DEBUG_FILE_IO
+ EAS_ReportX(_EAS_SEVERITY_NOFILTER, "EAS_HWFileSeekOfs: Seeking to new position %d\n", file->filePos + position);
+#endif
+
+ /* check handle integrity */
+ if (file->pFile == NULL)
+ return EAS_ERROR_INVALID_HANDLE;
+
+ /* check for seek past end */
+ temp = file->filePos + position;
+ if ((temp < 0) || (temp > file->fileSize))
+ return EAS_ERROR_FILE_SEEK;
+
+ /* is new position in current buffer? */
+ temp = position + file->readIndex;
+ if ((temp >= 0) && (temp < file->bytesInBuffer))
+ {
+ file->readIndex = temp;
+ file->filePos += position;
+ return EAS_SUCCESS;
+ }
+
+ /* save new position and reset buffer info so EAS_HWGetByte doesn't fail */
+ file->filePos += position;
+ file->bytesInBuffer = 0;
+ file->readIndex = 0;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_HWFileLength
+ *
+ * Return the file length
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, hwInstData) hwInstData available for customer use */
+EAS_RESULT EAS_HWFileLength (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, EAS_I32 *pLength)
+{
+ long pos;
+
+ /* check handle integrity */
+ if (file->pFile == NULL)
+ return EAS_ERROR_INVALID_HANDLE;
+
+ if ((pos = ftell(file->pFile)) == -1L)
+ return EAS_ERROR_FILE_LENGTH;
+ if (fseek(file->pFile, 0L, SEEK_END) != 0)
+ return EAS_ERROR_FILE_LENGTH;
+ if ((*pLength = ftell(file->pFile)) == -1L)
+ return EAS_ERROR_FILE_LENGTH;
+ if (fseek(file->pFile, pos, SEEK_SET) != 0)
+ return EAS_ERROR_FILE_LENGTH;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_HWDupHandle
+ *
+ * Duplicate a file handle
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_HWDupHandle (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, EAS_FILE_HANDLE* pDupFile)
+{
+ EAS_HW_FILE *dupfile;
+ int i;
+
+ /* check handle integrity */
+ *pDupFile = NULL;
+ if (file->pFile == NULL)
+ return EAS_ERROR_INVALID_HANDLE;
+
+ /* find an empty entry in the file table */
+ dupfile = hwInstData->files;
+ for (i = 0; i < EAS_MAX_FILE_HANDLES; i++)
+ {
+ /* is this slot being used? */
+ if (dupfile->pFile == NULL)
+ {
+
+ /* copy info from the handle to be duplicated */
+ dupfile->filePos = file->filePos;
+ dupfile->pFile = file->pFile;
+ dupfile->fileSize = file->fileSize;
+
+ /* set the duplicate handle flag */
+ dupfile->dup = file->dup = EAS_TRUE;
+
+ /* initialize some values */
+ dupfile->bytesInBuffer = 0;
+ dupfile->readIndex = 0;
+
+ *pDupFile = dupfile;
+ return EAS_SUCCESS;
+ }
+ dupfile++;
+ }
+
+ /* too many open files */
+ return EAS_ERROR_MAX_FILES_OPEN;
+}
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_HWClose
+ *
+ * Wrapper for fclose function
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_HWCloseFile (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file1)
+{
+ EAS_HW_FILE *file2,*dupFile;
+ int i;
+
+ /* check handle integrity */
+ if (file1->pFile == NULL)
+ return EAS_ERROR_INVALID_HANDLE;
+
+ /* check for duplicate handle */
+ if (file1->dup)
+ {
+ dupFile = NULL;
+ file2 = hwInstData->files;
+ for (i = 0; i < EAS_MAX_FILE_HANDLES; i++)
+ {
+ /* check for duplicate */
+ if ((file1 != file2) && (file2->pFile == file1->pFile))
+ {
+ /* is there more than one duplicate? */
+ if (dupFile != NULL)
+ {
+ /* clear this entry and return */
+ file1->pFile = NULL;
+ return EAS_SUCCESS;
+ }
+
+ /* this is the first duplicate found */
+ dupFile = file2;
+ }
+ file2++;
+ }
+
+ /* there is only one duplicate, clear the dup flag */
+ if (dupFile)
+ dupFile->dup = EAS_FALSE;
+ else
+ /* if we get here, there's a serious problem */
+ return EAS_ERROR_HANDLE_INTEGRITY;
+
+ /* clear this entry and return */
+ file1->pFile = NULL;
+ return EAS_SUCCESS;
+ }
+
+ /* no duplicates - close the file */
+ if (fclose(file1->pFile) != 0)
+ return EAS_ERROR_CLOSE_FAILED;
+
+ /* clear this entry and return */
+ file1->pFile = NULL;
+ return EAS_SUCCESS;
+}
+#else
+/*----------------------------------------------------------------------------
+ *
+ * EAS_HWOpenFile
+ *
+ * Open a file for read or write
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_HWOpenFile (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_LOCATOR locator, EAS_FILE_HANDLE *pFile, EAS_FILE_MODE mode)
+{
+ EAS_HW_FILE *file;
+ FILE *ioFile;
+ int i, temp;
+
+ /* set return value to NULL */
+ *pFile = NULL;
+
+ /* simulate failure */
+ if (errorConditions[eOpenError])
+ return EAS_FAILURE;
+
+ /* only support read mode at this time */
+ if (mode != EAS_FILE_READ)
+ return EAS_ERROR_INVALID_FILE_MODE;
+
+ /* find an empty entry in the file table */
+ file = hwInstData->files;
+ for (i = 0; i < EAS_MAX_FILE_HANDLES; i++)
+ {
+ /* is this slot being used? */
+ if (file->buffer == NULL)
+ {
+ /* open the file */
+ if ((ioFile = fopen(locator,"rb")) == NULL)
+ return EAS_ERROR_FILE_OPEN_FAILED;
+
+ /* determine the file size */
+ if (fseek(ioFile, 0L, SEEK_END) != 0)
+ return EAS_ERROR_FILE_LENGTH;
+ if ((file->fileSize = ftell(ioFile)) == -1L)
+ return EAS_ERROR_FILE_LENGTH;
+ if (fseek(ioFile, 0L, SEEK_SET) != 0)
+ return EAS_ERROR_FILE_LENGTH;
+
+ /* allocate a buffer */
+ file->buffer = EAS_HWMalloc(hwInstData, file->fileSize);
+ if (file->buffer == NULL)
+ {
+ fclose(ioFile);
+ return EAS_ERROR_MALLOC_FAILED;
+ }
+
+ /* read the file into memory */
+ temp = (int) fread(file->buffer, (size_t) file->fileSize, 1, ioFile);
+
+ /* close the file - don't need it any more */
+ fclose(ioFile);
+
+ /* check for error reading file */
+ if (temp != 1)
+ return EAS_ERROR_FILE_READ_FAILED;
+
+ /* initialize some values */
+ file->filePos = 0;
+ file->dup = EAS_FALSE;
+
+ *pFile = file;
+ return EAS_SUCCESS;
+ }
+ file++;
+ }
+
+ /* too many open files */
+ return EAS_ERROR_MAX_FILES_OPEN;
+}
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_HWReadFile
+ *
+ * Read data from a file
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, hwInstData) available for customer use */
+EAS_RESULT EAS_HWReadFile (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, void *pBuffer, EAS_I32 n, EAS_I32 *pBytesRead)
+{
+ EAS_I32 count;
+
+ /* simulate failure */
+ if (errorConditions[eReadError])
+ return EAS_FAILURE;
+
+ /* make sure we have a valid handle */
+ if (file->buffer == NULL)
+ return EAS_ERROR_INVALID_HANDLE;
+
+ /* calculate the bytes to read */
+ count = file->fileSize - file->filePos;
+ if (n < count)
+ count = n;
+
+ /* copy the data to the requested location, and advance the pointer */
+ if (count)
+ EAS_HWMemCpy(pBuffer, &file->buffer[file->filePos], count);
+ file->filePos += count;
+ *pBytesRead = count;
+
+ /* were n bytes read? */
+ if (count!= n)
+ return EAS_EOF;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_HWGetByte
+ *
+ * Read a byte from a file
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -e{715} hwInstData available for customer use */
+EAS_RESULT EAS_HWGetByte (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, void *p)
+{
+
+ /* simulate failure */
+ if (errorConditions[eReadError])
+ return EAS_FAILURE;
+
+ /* make sure we have a valid handle */
+ if (file->buffer == NULL)
+ return EAS_ERROR_INVALID_HANDLE;
+
+ /* check for end of file */
+ if (file->filePos >= file->fileSize)
+ {
+ *((EAS_U8*) p) = 0;
+ return EAS_EOF;
+ }
+
+ /* get a character from the buffer */
+ *((EAS_U8*) p) = file->buffer[file->filePos++];
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_HWGetWord
+ *
+ * Returns the current location in the file
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, hwInstData) available for customer use */
+EAS_RESULT EAS_HWGetWord (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, void *p, EAS_BOOL msbFirst)
+{
+ EAS_RESULT result;
+ EAS_U8 c1, c2;
+
+ /* read 2 bytes from the file */
+ if ((result = EAS_HWGetByte(hwInstData, file, &c1)) != EAS_SUCCESS)
+ return result;
+ if ((result = EAS_HWGetByte(hwInstData, file, &c2)) != EAS_SUCCESS)
+ return result;
+
+ /* order them as requested */
+ if (msbFirst)
+ *((EAS_U16*) p) = ((EAS_U16) c1 << 8) | c2;
+ else
+ *((EAS_U16*) p) = ((EAS_U16) c2 << 8) | c1;
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_HWGetDWord
+ *
+ * Returns the current location in the file
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, hwInstData) available for customer use */
+EAS_RESULT EAS_HWGetDWord (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, void *p, EAS_BOOL msbFirst)
+{
+ EAS_RESULT result;
+ EAS_U8 c1, c2,c3,c4;
+
+ /* read 4 bytes from the file */
+ if ((result = EAS_HWGetByte(hwInstData, file, &c1)) != EAS_SUCCESS)
+ return result;
+ if ((result = EAS_HWGetByte(hwInstData, file, &c2)) != EAS_SUCCESS)
+ return result;
+ if ((result = EAS_HWGetByte(hwInstData, file, &c3)) != EAS_SUCCESS)
+ return result;
+ if ((result = EAS_HWGetByte(hwInstData, file, &c4)) != EAS_SUCCESS)
+ return result;
+
+ /* order them as requested */
+ if (msbFirst)
+ *((EAS_U32*) p) = ((EAS_U32) c1 << 24) | ((EAS_U32) c2 << 16) | ((EAS_U32) c3 << 8) | c4;
+ else
+ *((EAS_U32*) p)= ((EAS_U32) c4 << 24) | ((EAS_U32) c3 << 16) | ((EAS_U32) c2 << 8) | c1;
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_HWFilePos
+ *
+ * Returns the current location in the file
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, hwInstData) available for customer use */
+EAS_RESULT EAS_HWFilePos (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, EAS_I32 *pPosition)
+{
+
+ /* simulate failure */
+ if (errorConditions[ePosError])
+ return EAS_FAILURE;
+
+ /* make sure we have a valid handle */
+ if (file->buffer == NULL)
+ return EAS_ERROR_INVALID_HANDLE;
+
+ *pPosition = file->filePos;
+ return EAS_SUCCESS;
+} /* end EAS_HWFilePos */
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_HWFileSeek
+ *
+ * Seek to a specific location in the file
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, hwInstData) available for customer use */
+EAS_RESULT EAS_HWFileSeek (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, EAS_I32 position)
+{
+
+ /* simulate failure */
+ if (errorConditions[eSeekError])
+ return EAS_FAILURE;
+
+ /* make sure we have a valid handle */
+ if (file->buffer == NULL)
+ return EAS_ERROR_INVALID_HANDLE;
+
+ /* validate new position */
+ if ((position < 0) || (position > file->fileSize))
+ return EAS_ERROR_FILE_SEEK;
+
+ /* save new position */
+ file->filePos = position;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_HWFileSeekOfs
+ *
+ * Seek forward or back relative to the current position
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, hwInstData) available for customer use */
+EAS_RESULT EAS_HWFileSeekOfs (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, EAS_I32 position)
+{
+
+ /* simulate failure */
+ if (errorConditions[eSeekError])
+ return EAS_FAILURE;
+
+ /* make sure we have a valid handle */
+ if (file->buffer == NULL)
+ return EAS_ERROR_INVALID_HANDLE;
+
+ /* determine the file position */
+ position += file->filePos;
+ if ((position < 0) || (position > file->fileSize))
+ return EAS_ERROR_FILE_SEEK;
+
+ /* save new position */
+ file->filePos = position;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_HWFileLength
+ *
+ * Return the file length
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, hwInstData) available for customer use */
+EAS_RESULT EAS_HWFileLength (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, EAS_I32 *pLength)
+{
+
+ /* simulate failure */
+ if (errorConditions[eLengthError])
+ return EAS_FAILURE;
+
+ /* make sure we have a valid handle */
+ if (file->buffer == NULL)
+ return EAS_ERROR_INVALID_HANDLE;
+
+ *pLength = file->fileSize;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_HWDupHandle
+ *
+ * Duplicate a file handle
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_HWDupHandle (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, EAS_FILE_HANDLE *pDupFile)
+{
+ EAS_HW_FILE *dupFile;
+ int i;
+
+ /* simulate failure */
+ if (errorConditions[eDupError])
+ return EAS_FAILURE;
+
+ /* make sure we have a valid handle */
+ if (file->buffer == NULL)
+ return EAS_ERROR_INVALID_HANDLE;
+
+ /* find an empty entry in the file table */
+ dupFile = hwInstData->files;
+ for (i = 0; i < EAS_MAX_FILE_HANDLES; i++)
+ {
+ /* is this slot being used? */
+ if (dupFile->buffer == NULL)
+ {
+
+ /* copy info from the handle to be duplicated */
+ dupFile->filePos = file->filePos;
+ dupFile->fileSize = file->fileSize;
+ dupFile->buffer = file->buffer;
+
+ /* set the duplicate handle flag */
+ dupFile->dup = file->dup = EAS_TRUE;
+
+ *pDupFile = dupFile;
+ return EAS_SUCCESS;
+ }
+ dupFile++;
+ }
+
+ /* too many open files */
+ return EAS_ERROR_MAX_FILES_OPEN;
+}
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_HWClose
+ *
+ * Wrapper for fclose function
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_HWCloseFile (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file1)
+{
+ EAS_HW_FILE *file2,*dupFile;
+ int i;
+
+ /* simulate failure */
+ if (errorConditions[eCloseError])
+ return EAS_FAILURE;
+
+ /* make sure we have a valid handle */
+ if (file1->buffer == NULL)
+ return EAS_ERROR_INVALID_HANDLE;
+
+ /* check for duplicate handle */
+ if (file1->dup)
+ {
+ dupFile = NULL;
+ file2 = hwInstData->files;
+ for (i = 0; i < EAS_MAX_FILE_HANDLES; i++)
+ {
+ /* check for duplicate */
+ if ((file1 != file2) && (file2->buffer == file1->buffer))
+ {
+ /* is there more than one duplicate? */
+ if (dupFile != NULL)
+ {
+ /* clear this entry and return */
+ file1->buffer = NULL;
+ return EAS_SUCCESS;
+ }
+
+ /* this is the first duplicate found */
+ else
+ dupFile = file2;
+ }
+ file2++;
+ }
+
+ /* there is only one duplicate, clear the dup flag */
+ if (dupFile)
+ dupFile->dup = EAS_FALSE;
+ else
+ /* if we get here, there's a serious problem */
+ return EAS_ERROR_HANDLE_INTEGRITY;
+
+ /* clear this entry and return */
+ file1->buffer = NULL;
+ return EAS_SUCCESS;
+ }
+
+ /* no duplicates -free the buffer */
+ EAS_HWFree(hwInstData, file1->buffer);
+
+ /* clear this entry and return */
+ file1->buffer = NULL;
+ return EAS_SUCCESS;
+}
+#endif
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_HWVibrate
+ *
+ * Turn on/off vibrate function
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, hwInstData) available for customer use */
+EAS_RESULT EAS_HWVibrate (EAS_HW_DATA_HANDLE hwInstData, EAS_BOOL state)
+{
+ vibState = state;
+// EAS_ReportX(_EAS_SEVERITY_NOFILTER, "Vibrate state: %d\n", state);
+ return EAS_SUCCESS;
+} /* end EAS_HWVibrate */
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_HWLED
+ *
+ * Turn on/off LED
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, hwInstData) available for customer use */
+EAS_RESULT EAS_HWLED (EAS_HW_DATA_HANDLE hwInstData, EAS_BOOL state)
+{
+ ledState = state;
+// EAS_ReportX(_EAS_SEVERITY_NOFILTER, "LED state: %d\n", state);
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_HWBackLight
+ *
+ * Turn on/off backlight
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, hwInstData) available for customer use */
+EAS_RESULT EAS_HWBackLight (EAS_HW_DATA_HANDLE hwInstData, EAS_BOOL state)
+{
+ backlightState = state;
+// EAS_ReportX(_EAS_SEVERITY_NOFILTER, "Backlight state: %d\n", state);
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_HWYield
+ *
+ * This function is called periodically by the EAS library to give the
+ * host an opportunity to allow other tasks to run. There are two ways to
+ * use this call:
+ *
+ * If you have a multi-tasking OS, you can call the yield function in the
+ * OS to allow other tasks to run. In this case, return EAS_FALSE to tell
+ * the EAS library to continue processing when control returns from this
+ * function.
+ *
+ * If tasks run in a single thread by sequential function calls (sometimes
+ * call a "commutator loop"), return EAS_TRUE to cause the EAS Library to
+ * return to the caller. Be sure to check the number of bytes rendered
+ * before passing the audio buffer to the codec - it may not be filled.
+ * The next call to EAS_Render will continue processing until the buffer
+ * has been filled.
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, hwInstData) available for customer use */
+EAS_BOOL EAS_HWYield (EAS_HW_DATA_HANDLE hwInstData)
+{
+ /* put your code here */
+ return EAS_FALSE;
+}
+
+
diff --git a/arm-wt-22k/jetcreator_lib_src/darwin-x86/EASLib.h b/arm-wt-22k/jetcreator_lib_src/darwin-x86/EASLib.h
index 0c0a89d..adaaa70 100755..100644
--- a/arm-wt-22k/jetcreator_lib_src/darwin-x86/EASLib.h
+++ b/arm-wt-22k/jetcreator_lib_src/darwin-x86/EASLib.h
@@ -1,31 +1,31 @@
-/*
- * EASLib.h
- * EASLIb
- *
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-#include "eas_types.h"
-
-extern EAS_RESULT EAS_LibInit (EAS_DATA_HANDLE *pHandle)
-{
- return EAS_Init(pEASData);
-}
-
-EAS_EXPORT EAS_LibShutdown (EAS_DATA_HANDLE handle)
-{
- EAS_Shutdown(handle);
-}
+/*
+ * EASLib.h
+ * EASLIb
+ *
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include "eas_types.h"
+
+extern EAS_RESULT EAS_LibInit (EAS_DATA_HANDLE *pHandle)
+{
+ return EAS_Init(pEASData);
+}
+
+EAS_EXPORT EAS_LibShutdown (EAS_DATA_HANDLE handle)
+{
+ EAS_Shutdown(handle);
+}
diff --git a/arm-wt-22k/jetcreator_lib_src/darwin-x86/EASLibVst.c b/arm-wt-22k/jetcreator_lib_src/darwin-x86/EASLibVst.c
index 58c8770..5bfe774 100755..100644
--- a/arm-wt-22k/jetcreator_lib_src/darwin-x86/EASLibVst.c
+++ b/arm-wt-22k/jetcreator_lib_src/darwin-x86/EASLibVst.c
@@ -1,1504 +1,1504 @@
-/*
- * EASLib.c
- * EASLIb
- *
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- *
- */
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <stdarg.h>
-#include <string.h>
-
-#include "eas.h"
-#include "eas_report.h"
-#include "eas_host.h"
-
-#ifdef JET_INTERFACE
-#include "jet.h"
-#endif
-
-
-#define EAS_EXPORT __attribute__((visibility("default")))
-
-// #define DEBUG_FILE_IO
-
-/* include debug interface */
-#include "eas_host_debug.h"
-
-#ifdef AUX_MIXER
-#include "eas_auxmix.h"
-#endif
-
-/* this module requires dynamic memory support */
-#ifdef _STATIC_MEMORY
-#error "eas_hostmm.c requires the dynamic memory model!\n"
-#endif
-
-#ifndef EAS_MAX_FILE_HANDLES
-#define EAS_MAX_FILE_HANDLES 32
-#endif
-
-#ifndef EAS_FILE_BUFFER_SIZE
-#define EAS_FILE_BUFFER_SIZE 32
-#endif
-
-/*
- * this structure and the related function are here
- * to support the ability to create duplicate handles
- * and buffering it in memory. If your system uses
- * in-memory resources, you can eliminate the calls
- * to malloc and free, the dup flag, and simply track
- * the file size and read position.
- */
- #ifdef BUFFERED_FILE_ACCESS
-typedef struct eas_hw_file_tag
-{
- FILE *pFile;
- EAS_I32 bytesInBuffer;
- EAS_I32 readIndex;
- EAS_I32 filePos;
- EAS_I32 fileSize;
- EAS_BOOL dup;
- EAS_U8 buffer[EAS_FILE_BUFFER_SIZE];
-} EAS_HW_FILE;
-#else
-typedef struct eas_hw_file_tag
-{
- EAS_I32 fileSize;
- EAS_I32 filePos;
- EAS_BOOL dup;
- EAS_U8 *buffer;
-} EAS_HW_FILE;
-#endif
-
-typedef struct eas_hw_inst_data_tag
-{
- EAS_HW_FILE files[EAS_MAX_FILE_HANDLES];
-} EAS_HW_INST_DATA;
-
-EAS_BOOL errorConditions[eNumErrorConditions];
-EAS_BOOL ledState;
-EAS_BOOL vibState;
-EAS_BOOL backlightState;
-
-#define MAX_DEBUG_MSG_LEN 1024
-
-typedef void (*EAS_LOG_FUNC)(EAS_INT severity, char *msg);
-
-static EAS_LOG_FUNC logCallback = NULL;
-static char messageBuffer[MAX_DEBUG_MSG_LEN];
-
-/* error counts */
-static EAS_INT eas_fatalErrors;
-static EAS_INT eas_errors;
-static EAS_INT eas_warnings;
-static int severityLevel = 9999;
-
-/* wave out device */
-#ifndef MAX_WAVE_OUT_BUFFERS
-#define MAX_WAVE_OUT_BUFFERS 8
-#endif
-
-#ifndef EAS_BUFFERS_PER_WAVE_BUFFER
-#define EAS_BUFFERS_PER_WAVE_BUFFER 8
-#endif
-
-/*----------------------------------------------------------------------------
- * ResetErrorCounters()
- *----------------------------------------------------------------------------
-*/
-EAS_EXPORT void ResetErrorCounters()
-{
- eas_fatalErrors = 0;
- eas_errors = 0;
- eas_warnings = 0;
-}
-
-/*----------------------------------------------------------------------------
- * SetLogCallback()
- *----------------------------------------------------------------------------
-*/
-EAS_EXPORT void SetLogCallback (EAS_LOG_FUNC callback)
-{
- logCallback = callback;
-}
-
-#ifndef _NO_DEBUG_PREPROCESSOR
-static S_DEBUG_MESSAGES debugMessages[] =
-{
-#ifdef UNIFIED_DEBUG_MESSAGES
-#include "eas_debugmsgs.h"
-#endif
- { 0,0,0 }
-};
-
-/*----------------------------------------------------------------------------
- * EAS_ReportEx()
- *----------------------------------------------------------------------------
-*/
-void EAS_ReportEx (int severity, unsigned long hashCode, int serialNum, ...)
-{
- va_list vargs;
- int i;
-
- switch (severity)
- {
- case _EAS_SEVERITY_FATAL:
- eas_fatalErrors++;
- break;
-
- case _EAS_SEVERITY_ERROR:
- eas_errors++;
- break;
-
- case _EAS_SEVERITY_WARNING:
- eas_warnings++;
- break;
-
- default:
- break;
- }
-
- /* check severity level */
- if (severity > severityLevel)
- return;
-
- /* check for callback */
- if (logCallback == NULL)
- return;
-
- /* find the error message and output to stdout */
- for (i = 0; debugMessages[i].m_pDebugMsg; i++)
- {
- if ((debugMessages[i].m_nHashCode == hashCode) &&
- (debugMessages[i].m_nSerialNum == serialNum))
- {
- va_start(vargs, serialNum);
-#ifdef WIN32
- vsprintf_s(messageBuffer, sizeof(messageBuffer), fmt, vargs);
-#else
- vsprintf(messageBuffer, debugMessages[i].m_pDebugMsg, vargs);
-#endif
- logCallback(severity, messageBuffer);
- va_end(vargs);
- return;
- }
- }
- printf("Unrecognized error: Severity=%d; HashCode=%lu; SerialNum=%d\n", severity, hashCode, serialNum);
-} /* end EAS_ReportEx */
-
-#else
-/*----------------------------------------------------------------------------
- * EAS_Report()
- *----------------------------------------------------------------------------
-*/
-void EAS_Report (int severity, const char *fmt, ...)
-{
- va_list vargs;
-
- switch (severity)
- {
- case _EAS_SEVERITY_FATAL:
- eas_fatalErrors++;
- break;
-
- case _EAS_SEVERITY_ERROR:
- eas_errors++;
- break;
-
- case _EAS_SEVERITY_WARNING:
- eas_warnings++;
- break;
-
- default:
- break;
- }
-
- /* check severity level */
- if (severity > severityLevel)
- return;
-
- /* check for callback */
- if (logCallback == NULL)
- return;
-
- va_start(vargs, fmt);
-#ifdef _WIN32
- vsprintf_s(messageBuffer, sizeof(messageBuffer), fmt, vargs);
-#else
- vsprintf(messageBuffer, fmt, vargs);
-#endif
- logCallback(severity, messageBuffer);
- va_end(vargs);
-} /* end EAS_Report */
-
-/*----------------------------------------------------------------------------
- * EAS_ReportX()
- *----------------------------------------------------------------------------
-*/
-void EAS_ReportX (int severity, const char *fmt, ...)
-{
- va_list vargs;
-
- switch (severity)
- {
- case _EAS_SEVERITY_FATAL:
- eas_fatalErrors++;
- break;
-
- case _EAS_SEVERITY_ERROR:
- eas_errors++;
- break;
-
- case _EAS_SEVERITY_WARNING:
- eas_warnings++;
- break;
-
- default:
- break;
- }
-
- /* check severity level */
- if (severity > severityLevel)
- return;
-
- /* check for callback */
- if (logCallback == NULL)
- return;
-
- va_start(vargs, fmt);
-#ifdef _WIN32
- vsprintf_s(messageBuffer, sizeof(messageBuffer), fmt, vargs);
-#else
- vsprintf(messageBuffer, fmt, vargs);
-#endif
- logCallback(severity, messageBuffer);
- va_end(vargs);
-}
-#endif
-
-/*----------------------------------------------------------------------------
- * EAS_DLLSetDebugLevel()
- *----------------------------------------------------------------------------
-*/
-EAS_EXPORT void EAS_DLLSetDebugLevel (int severity)
-{
- severityLevel = severity;
-}
-
-/*----------------------------------------------------------------------------
- * EAS_ExSetDebugLevel()
- *----------------------------------------------------------------------------
-*/
-void EAS_SetDebugLevel (int severity)
-{
- severityLevel = severity;
-}
-
-/*----------------------------------------------------------------------------
- * EAS_SelectLibrary()
- *----------------------------------------------------------------------------
-*/
-EAS_EXPORT EAS_RESULT EAS_SelectLib (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle, EAS_BOOL testLib)
-{
- extern EAS_SNDLIB_HANDLE VMGetLibHandle(EAS_INT libNum);
- return EAS_SetSoundLibrary(pEASData, streamHandle, VMGetLibHandle(testLib ? 1 : 0));
-}
-
-
-#if defined(_DEBUG) && !defined(MSC)
-#include <crtdbg.h>
-/*----------------------------------------------------------------------------
- * EnableHeapDebug()
- *----------------------------------------------------------------------------
-*/
-static void EnableHeapDebug (void)
-{
- int temp;
- temp = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
- temp |= _CRTDBG_ALLOC_MEM_DF;
- temp |= _CRTDBG_CHECK_ALWAYS_DF;
- temp |= _CRTDBG_LEAK_CHECK_DF;
-// temp |= _CRTDBG_DELAY_FREE_MEM_DF;
- _CrtSetDbgFlag(temp);
-}
-
-/*----------------------------------------------------------------------------
- * HeapCheck()
- *----------------------------------------------------------------------------
- * Check heap status
- *----------------------------------------------------------------------------
-*/
-void HeapCheck (void)
-{
- int heapStatus;
-
- /* Check heap status */
- heapStatus = _heapchk();
- if ((heapStatus == _HEAPOK) || (heapStatus == _HEAPEMPTY))
- return;
-
- EAS_ReportX(_EAS_SEVERITY_FATAL, "Heap corrupt\n" );
-}
-#endif
-
-
-/*----------------------------------------------------------------------------
- * EAS_HWInit
- *
- * Initialize host wrapper interface
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT EAS_HWInit (EAS_HW_DATA_HANDLE *pHWInstData)
-{
-
-#if defined(_DEBUG) && !defined(MSC)
- EnableHeapDebug();
-#endif
-
- #ifdef BUFFERED_FILE_ACCESS
- EAS_ReportX(_EAS_SEVERITY_INFO, "EAS_HWInit: Buffered file access\n");
- #else
- EAS_ReportX(_EAS_SEVERITY_INFO, "EAS_HWInit: Memory mapped file access\n");
- #endif
-
- /* simulate failure */
- if (errorConditions[eInitError])
- return EAS_FAILURE;
-
- /* need to track file opens for duplicate handles */
- *pHWInstData = malloc(sizeof(EAS_HW_INST_DATA));
- if (!(*pHWInstData))
- return EAS_ERROR_MALLOC_FAILED;
-
- EAS_HWMemSet(*pHWInstData, 0, sizeof(EAS_HW_INST_DATA));
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * EAS_HWShutdown
- *
- * Shut down host wrapper interface
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT EAS_HWShutdown (EAS_HW_DATA_HANDLE hwInstData)
-{
-
- /* simulate failure */
- if (errorConditions[eShutdownError])
- return EAS_FAILURE;
-
- free(hwInstData);
-
-#if defined(_DEBUG) && !defined(MSC)
- HeapCheck();
-#endif
-
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- *
- * EAS_HWMalloc
- *
- * Allocates dynamic memory
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, hwInstData) available for customer use */
-void *EAS_HWMalloc (EAS_HW_DATA_HANDLE hwInstData, EAS_I32 size)
-{
- /* simulate failure */
- if (errorConditions[eMallocError])
- return NULL;
-
- return malloc((size_t) size);
-}
-
-/*----------------------------------------------------------------------------
- *
- * EAS_HWFree
- *
- * Frees dynamic memory
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, hwInstData) available for customer use */
-void EAS_HWFree (EAS_HW_DATA_HANDLE hwInstData, void *p)
-{
- free(p);
-}
-
-/*----------------------------------------------------------------------------
- *
- * EAS_HWMemCpy
- *
- * Copy memory wrapper
- *
- *----------------------------------------------------------------------------
-*/
-void *EAS_HWMemCpy (void *dest, const void *src, EAS_I32 amount)
-{
- return memcpy(dest, src, (size_t) amount);
-}
-
-/*----------------------------------------------------------------------------
- *
- * EAS_HWMemSet
- *
- * Set memory wrapper
- *
- *----------------------------------------------------------------------------
-*/
-void *EAS_HWMemSet (void *dest, int val, EAS_I32 amount)
-{
- return memset(dest, val, (size_t) amount);
-}
-
-/*----------------------------------------------------------------------------
- *
- * EAS_HWMemCmp
- *
- * Compare memory wrapper
- *
- *----------------------------------------------------------------------------
-*/
-EAS_I32 EAS_HWMemCmp (const void *s1, const void *s2, EAS_I32 amount)
-{
- return (EAS_I32) memcmp(s1, s2, (size_t) amount);
-}
-
-#ifdef BUFFERED_FILE_ACCESS
-/*----------------------------------------------------------------------------
- *
- * EAS_HWOpenFile
- *
- * Open a file for read or write
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT EAS_HWOpenFile (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_LOCATOR locator, EAS_FILE_HANDLE *pFile, EAS_FILE_MODE mode)
-{
- EAS_HW_FILE *file;
- int i;
-
- /* set return value to NULL */
- *pFile = NULL;
-
- /* only support read mode at this time */
- if (mode != EAS_FILE_READ)
- return EAS_ERROR_INVALID_FILE_MODE;
-
- /* find an empty entry in the file table */
- file = hwInstData->files;
- for (i = 0; i < EAS_MAX_FILE_HANDLES; i++)
- {
- /* is this slot being used? */
- if (file->pFile == NULL)
- {
- EAS_RESULT result;
-
- /* open the file */
- file->pFile = fopen((const char*) locator, "rb");
- if (file->pFile == NULL)
- return EAS_ERROR_FILE_OPEN_FAILED;
-
- /* get file length */
- if ((result = EAS_HWFileLength(hwInstData, file, &file->fileSize)) != EAS_SUCCESS)
- {
- EAS_HWCloseFile(hwInstData, file);
- return result;
- }
-
-#ifdef DEBUG_FILE_IO
- EAS_ReportX(_EAS_SEVERITY_NOFILTER, "EAS_HWOpenFile: Open file %d\n", i);
-#endif
-
- /* initialize some values */
- file->bytesInBuffer = 0;
- file->readIndex = 0;
- file->filePos = 0;
- file->dup = EAS_FALSE;
-
- *pFile = file;
- return EAS_SUCCESS;
- }
- file++;
- }
-
- /* too many open files */
- return EAS_ERROR_MAX_FILES_OPEN;
-}
-
-/*----------------------------------------------------------------------------
- *
- * EAS_HWFillBuffer
- *
- * Fill buffer from file
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, hwInstData) hwInstData available for customer use */
-EAS_RESULT EAS_HWFillBuffer (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file)
-{
- /* reposition the file pointer */
- if (fseek(file->pFile, file->filePos, SEEK_SET) != 0)
- return EAS_ERROR_FILE_SEEK;
-
- /* read some data from the file */
- file->bytesInBuffer = (EAS_I32) fread(file->buffer, 1, EAS_FILE_BUFFER_SIZE, file->pFile);
- file->readIndex = 0;
- if (file->bytesInBuffer == 0)
- return EAS_EOF;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- *
- * EAS_HWReadFile
- *
- * Read data from a file
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, hwInstData) hwInstData available for customer use */
-EAS_RESULT EAS_HWReadFile (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, void *pBuffer, EAS_I32 n, EAS_I32 *pBytesRead)
-{
- EAS_RESULT result;
- EAS_I32 temp;
- EAS_U8 *p = pBuffer;
- EAS_I32 bytesLeft = n;
-
- *pBytesRead = 0;
-
- /* check handle integrity */
- if (file->pFile == NULL)
- return EAS_ERROR_INVALID_HANDLE;
-
-#ifdef DEBUG_FILE_IO
- EAS_ReportX(_EAS_SEVERITY_NOFILTER, "EAS_HWReadFile: Reading %d bytes from position %d\n", n, file->filePos);
-#endif
-
- /* try to fulfill request from buffer */
- for (;bytesLeft > 0;)
- {
- /* how many bytes can we get from buffer? */
- temp = file->bytesInBuffer - file->readIndex;
- if (temp > bytesLeft)
- temp = bytesLeft;
-
- /* copy data from buffer */
- EAS_HWMemCpy(p, &file->buffer[file->readIndex], temp);
- *pBytesRead += temp;
- file->readIndex += temp;
- file->filePos += temp;
- p += temp;
- bytesLeft -= temp;
-
- /* don't refill buffer if request is bigger than buffer */
- if ((bytesLeft == 0) || (bytesLeft >= EAS_FILE_BUFFER_SIZE))
- break;
-
- /* refill buffer */
- if ((result = EAS_HWFillBuffer(hwInstData, file)) != EAS_SUCCESS)
- return result;
- }
-
- /* more to read? do unbuffered read directly to target memory */
- if (bytesLeft)
- {
-
- /* position the file pointer */
- if (fseek(file->pFile, file->filePos, SEEK_SET) != 0)
- return EAS_ERROR_FILE_SEEK;
-
- /* read data in the buffer */
- temp = (EAS_I32) fread(p, 1, (size_t) bytesLeft, file->pFile);
- *pBytesRead += temp;
- file->filePos += temp;
-
- /* reset buffer info */
- file->bytesInBuffer = 0;
- file->readIndex = 0;
- }
-
-#ifdef DEBUG_FILE_IO
- {
-#define BYTES_PER_LINE 16
- char str[BYTES_PER_LINE * 3 + 1];
- EAS_INT i;
- for (i = 0; i < (n > BYTES_PER_LINE ? BYTES_PER_LINE : n) ; i ++)
- sprintf(&str[i*3], "%02x ", ((EAS_U8*)pBuffer)[i]);
- if (i)
- EAS_ReportX(_EAS_SEVERITY_NOFILTER, "%s\n", str);
- }
-#endif
-
- /* were n bytes read? */
- if (*pBytesRead != n)
- return EAS_EOF;
-
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- *
- * EAS_HWGetByte
- *
- * Read a byte from a file
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, hwInstData) hwInstData available for customer use */
-EAS_RESULT EAS_HWGetByte (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, void *p)
-{
- EAS_RESULT result;
-
- /* check handle integrity */
- if (file->pFile == NULL)
- return EAS_ERROR_INVALID_HANDLE;
-
- /* use local buffer - do we have any data? */
- if (file->readIndex >= file->bytesInBuffer)
- {
- if ((result = EAS_HWFillBuffer(hwInstData, file)) != EAS_SUCCESS)
- return result;
-
- /* if nothing to read, return EOF */
- if (file->bytesInBuffer == 0)
- return EAS_EOF;
- }
-
- /* get a character from the buffer */
- *((EAS_U8*) p) = file->buffer[file->readIndex++];
-
-#ifdef DEBUG_FILE_IO
- EAS_ReportX(_EAS_SEVERITY_NOFILTER, "EAS_HWGetByte: Reading from position %d, byte = 0x%02x\n", file->filePos, *(EAS_U8*)p);
-#endif
-
- file->filePos++;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- *
- * EAS_HWGetWord
- *
- * Read a 16-bit value from the file
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT EAS_HWGetWord (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, void *p, EAS_BOOL msbFirst)
-{
- EAS_RESULT result;
- EAS_I32 count;
- EAS_U8 c[2];
-
-#ifdef DEBUG_FILE_IO
- EAS_ReportX(_EAS_SEVERITY_NOFILTER, "EAS_HWGetWord: Reading 2 bytes from position %d\n", file->filePos);
-#endif
-
- /* read 2 bytes from the file */
- if ((result = EAS_HWReadFile(hwInstData, file, c, 2, &count)) != EAS_SUCCESS)
- return result;
-
- /* order them as requested */
- if (msbFirst)
- *((EAS_U16*) p) = ((EAS_U16) c[0] << 8) | c[1];
- else
- *((EAS_U16*) p) = ((EAS_U16) c[1] << 8) | c[0];
-
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- *
- * EAS_HWGetDWord
- *
- * Read a 16-bit value from the file
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT EAS_HWGetDWord (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, void *p, EAS_BOOL msbFirst)
-{
- EAS_RESULT result;
- EAS_I32 count;
- EAS_U8 c[4];
-
-#ifdef DEBUG_FILE_IO
- EAS_ReportX(_EAS_SEVERITY_NOFILTER, "EAS_HWGetDWord: Reading 4 bytes from position %d\n", file->filePos);
-#endif
-
- /* read 4 bytes from the file */
- if ((result = EAS_HWReadFile(hwInstData, file, c, 4, &count)) != EAS_SUCCESS)
- return result;
-
- /* order them as requested */
- if (msbFirst)
- *((EAS_U32*) p) = ((EAS_U32) c[0] << 24) | ((EAS_U32) c[1] << 16) | ((EAS_U32) c[2] << 8) | c[3];
- else
- *((EAS_U32*) p) = ((EAS_U32) c[3] << 24) | ((EAS_U32) c[2] << 16) | ((EAS_U32) c[1] << 8) | c[0];
-
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- *
- * EAS_HWFilePos
- *
- * Returns the current location in the file
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, hwInstData) hwInstData available for customer use */
-EAS_RESULT EAS_HWFilePos (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, EAS_I32 *pPosition)
-{
-
- /* check handle integrity */
- if (file->pFile == NULL)
- return EAS_ERROR_INVALID_HANDLE;
-
- *pPosition = file->filePos;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- *
- * EAS_HWFileSeek
- *
- * Seek to a specific location in the file
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, hwInstData) hwInstData available for customer use */
-EAS_RESULT EAS_HWFileSeek (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, EAS_I32 position)
-{
- EAS_I32 newIndex;
-
- /* check handle integrity */
- if (file->pFile == NULL)
- return EAS_ERROR_INVALID_HANDLE;
-
- /* check for seek past end */
- if ((position < 0) || (position > file->fileSize))
- return EAS_ERROR_FILE_SEEK;
-
-#ifdef DEBUG_FILE_IO
- EAS_ReportX(_EAS_SEVERITY_NOFILTER, "EAS_HWFileSeek: Seeking to new position %d\n", file->filePos);
-#endif
-
- /* is new position in current buffer? */
- newIndex = position - file->filePos + file->readIndex;
- if ((newIndex >= 0) && (newIndex < file->bytesInBuffer))
- {
- file->readIndex = newIndex;
- file->filePos = position;
- return EAS_SUCCESS;
- }
-
- /* save new position and reset buffer info so EAS_HWGetByte doesn't fail */
- file->filePos = position;
- file->bytesInBuffer = 0;
- file->readIndex = 0;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- *
- * EAS_HWFileSeekOfs
- *
- * Seek forward or back relative to the current position
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, hwInstData) hwInstData available for customer use */
-EAS_RESULT EAS_HWFileSeekOfs (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, EAS_I32 position)
-{
- EAS_I32 temp;
-
-#ifdef DEBUG_FILE_IO
- EAS_ReportX(_EAS_SEVERITY_NOFILTER, "EAS_HWFileSeekOfs: Seeking to new position %d\n", file->filePos + position);
-#endif
-
- /* check handle integrity */
- if (file->pFile == NULL)
- return EAS_ERROR_INVALID_HANDLE;
-
- /* check for seek past end */
- temp = file->filePos + position;
- if ((temp < 0) || (temp > file->fileSize))
- return EAS_ERROR_FILE_SEEK;
-
- /* is new position in current buffer? */
- temp = position + file->readIndex;
- if ((temp >= 0) && (temp < file->bytesInBuffer))
- {
- file->readIndex = temp;
- file->filePos += position;
- return EAS_SUCCESS;
- }
-
- /* save new position and reset buffer info so EAS_HWGetByte doesn't fail */
- file->filePos += position;
- file->bytesInBuffer = 0;
- file->readIndex = 0;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- *
- * EAS_HWFileLength
- *
- * Return the file length
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, hwInstData) hwInstData available for customer use */
-EAS_RESULT EAS_HWFileLength (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, EAS_I32 *pLength)
-{
- long pos;
-
- /* check handle integrity */
- if (file->pFile == NULL)
- return EAS_ERROR_INVALID_HANDLE;
-
- if ((pos = ftell(file->pFile)) == -1L)
- return EAS_ERROR_FILE_LENGTH;
- if (fseek(file->pFile, 0L, SEEK_END) != 0)
- return EAS_ERROR_FILE_LENGTH;
- if ((*pLength = ftell(file->pFile)) == -1L)
- return EAS_ERROR_FILE_LENGTH;
- if (fseek(file->pFile, pos, SEEK_SET) != 0)
- return EAS_ERROR_FILE_LENGTH;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- *
- * EAS_HWDupHandle
- *
- * Duplicate a file handle
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT EAS_HWDupHandle (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, EAS_FILE_HANDLE* pDupFile)
-{
- EAS_HW_FILE *dupfile;
- int i;
-
- /* check handle integrity */
- *pDupFile = NULL;
- if (file->pFile == NULL)
- return EAS_ERROR_INVALID_HANDLE;
-
- /* find an empty entry in the file table */
- dupfile = hwInstData->files;
- for (i = 0; i < EAS_MAX_FILE_HANDLES; i++)
- {
- /* is this slot being used? */
- if (dupfile->pFile == NULL)
- {
-
- /* copy info from the handle to be duplicated */
- dupfile->filePos = file->filePos;
- dupfile->pFile = file->pFile;
- dupfile->fileSize = file->fileSize;
-
- /* set the duplicate handle flag */
- dupfile->dup = file->dup = EAS_TRUE;
-
- /* initialize some values */
- dupfile->bytesInBuffer = 0;
- dupfile->readIndex = 0;
-
- *pDupFile = dupfile;
- return EAS_SUCCESS;
- }
- dupfile++;
- }
-
- /* too many open files */
- return EAS_ERROR_MAX_FILES_OPEN;
-}
-
-/*----------------------------------------------------------------------------
- *
- * EAS_HWClose
- *
- * Wrapper for fclose function
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT EAS_HWCloseFile (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file1)
-{
- EAS_HW_FILE *file2,*dupFile;
- int i;
-
- /* check handle integrity */
- if (file1->pFile == NULL)
- return EAS_ERROR_INVALID_HANDLE;
-
- /* check for duplicate handle */
- if (file1->dup)
- {
- dupFile = NULL;
- file2 = hwInstData->files;
- for (i = 0; i < EAS_MAX_FILE_HANDLES; i++)
- {
- /* check for duplicate */
- if ((file1 != file2) && (file2->pFile == file1->pFile))
- {
- /* is there more than one duplicate? */
- if (dupFile != NULL)
- {
- /* clear this entry and return */
- file1->pFile = NULL;
- return EAS_SUCCESS;
- }
-
- /* this is the first duplicate found */
- dupFile = file2;
- }
- file2++;
- }
-
- /* there is only one duplicate, clear the dup flag */
- if (dupFile)
- dupFile->dup = EAS_FALSE;
- else
- /* if we get here, there's a serious problem */
- return EAS_ERROR_HANDLE_INTEGRITY;
-
- /* clear this entry and return */
- file1->pFile = NULL;
- return EAS_SUCCESS;
- }
-
- /* no duplicates - close the file */
- if (fclose(file1->pFile) != 0)
- return EAS_ERROR_CLOSE_FAILED;
-
- /* clear this entry and return */
- file1->pFile = NULL;
- return EAS_SUCCESS;
-}
-#else
-/*----------------------------------------------------------------------------
- *
- * EAS_HWOpenFile
- *
- * Open a file for read or write
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT EAS_HWOpenFile (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_LOCATOR locator, EAS_FILE_HANDLE *pFile, EAS_FILE_MODE mode)
-{
- EAS_HW_FILE *file;
- FILE *ioFile;
- int i, temp;
-
- /* set return value to NULL */
- *pFile = NULL;
-
- /* simulate failure */
- if (errorConditions[eOpenError])
- return EAS_FAILURE;
-
- /* only support read mode at this time */
- if (mode != EAS_FILE_READ)
- return EAS_ERROR_INVALID_FILE_MODE;
-
- /* find an empty entry in the file table */
- file = hwInstData->files;
- for (i = 0; i < EAS_MAX_FILE_HANDLES; i++)
- {
- /* is this slot being used? */
- if (file->buffer == NULL)
- {
- /* open the file */
- if ((ioFile = fopen(locator,"rb")) == NULL)
- return EAS_ERROR_FILE_OPEN_FAILED;
-
- /* determine the file size */
- if (fseek(ioFile, 0L, SEEK_END) != 0)
- return EAS_ERROR_FILE_LENGTH;
- if ((file->fileSize = ftell(ioFile)) == -1L)
- return EAS_ERROR_FILE_LENGTH;
- if (fseek(ioFile, 0L, SEEK_SET) != 0)
- return EAS_ERROR_FILE_LENGTH;
-
- /* allocate a buffer */
- file->buffer = EAS_HWMalloc(hwInstData, file->fileSize);
- if (file->buffer == NULL)
- {
- fclose(ioFile);
- return EAS_ERROR_MALLOC_FAILED;
- }
-
- /* read the file into memory */
- temp = (int) fread(file->buffer, (size_t) file->fileSize, 1, ioFile);
-
- /* close the file - don't need it any more */
- fclose(ioFile);
-
- /* check for error reading file */
- if (temp != 1)
- return EAS_ERROR_FILE_READ_FAILED;
-
- /* initialize some values */
- file->filePos = 0;
- file->dup = EAS_FALSE;
-
- *pFile = file;
- return EAS_SUCCESS;
- }
- file++;
- }
-
- /* too many open files */
- return EAS_ERROR_MAX_FILES_OPEN;
-}
-
-/*----------------------------------------------------------------------------
- *
- * EAS_HWReadFile
- *
- * Read data from a file
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, hwInstData) available for customer use */
-EAS_RESULT EAS_HWReadFile (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, void *pBuffer, EAS_I32 n, EAS_I32 *pBytesRead)
-{
- EAS_I32 count;
-
- /* simulate failure */
- if (errorConditions[eReadError])
- return EAS_FAILURE;
-
- /* make sure we have a valid handle */
- if (file->buffer == NULL)
- return EAS_ERROR_INVALID_HANDLE;
-
- /* calculate the bytes to read */
- count = file->fileSize - file->filePos;
- if (n < count)
- count = n;
-
- /* copy the data to the requested location, and advance the pointer */
- if (count)
- EAS_HWMemCpy(pBuffer, &file->buffer[file->filePos], count);
- file->filePos += count;
- *pBytesRead = count;
-
- /* were n bytes read? */
- if (count!= n)
- return EAS_EOF;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- *
- * EAS_HWGetByte
- *
- * Read a byte from a file
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -e{715} hwInstData available for customer use */
-EAS_RESULT EAS_HWGetByte (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, void *p)
-{
-
- /* simulate failure */
- if (errorConditions[eReadError])
- return EAS_FAILURE;
-
- /* make sure we have a valid handle */
- if (file->buffer == NULL)
- return EAS_ERROR_INVALID_HANDLE;
-
- /* check for end of file */
- if (file->filePos >= file->fileSize)
- {
- *((EAS_U8*) p) = 0;
- return EAS_EOF;
- }
-
- /* get a character from the buffer */
- *((EAS_U8*) p) = file->buffer[file->filePos++];
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- *
- * EAS_HWGetWord
- *
- * Returns the current location in the file
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, hwInstData) available for customer use */
-EAS_RESULT EAS_HWGetWord (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, void *p, EAS_BOOL msbFirst)
-{
- EAS_RESULT result;
- EAS_U8 c1, c2;
-
- /* read 2 bytes from the file */
- if ((result = EAS_HWGetByte(hwInstData, file, &c1)) != EAS_SUCCESS)
- return result;
- if ((result = EAS_HWGetByte(hwInstData, file, &c2)) != EAS_SUCCESS)
- return result;
-
- /* order them as requested */
- if (msbFirst)
- *((EAS_U16*) p) = ((EAS_U16) c1 << 8) | c2;
- else
- *((EAS_U16*) p) = ((EAS_U16) c2 << 8) | c1;
-
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- *
- * EAS_HWGetDWord
- *
- * Returns the current location in the file
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, hwInstData) available for customer use */
-EAS_RESULT EAS_HWGetDWord (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, void *p, EAS_BOOL msbFirst)
-{
- EAS_RESULT result;
- EAS_U8 c1, c2,c3,c4;
-
- /* read 4 bytes from the file */
- if ((result = EAS_HWGetByte(hwInstData, file, &c1)) != EAS_SUCCESS)
- return result;
- if ((result = EAS_HWGetByte(hwInstData, file, &c2)) != EAS_SUCCESS)
- return result;
- if ((result = EAS_HWGetByte(hwInstData, file, &c3)) != EAS_SUCCESS)
- return result;
- if ((result = EAS_HWGetByte(hwInstData, file, &c4)) != EAS_SUCCESS)
- return result;
-
- /* order them as requested */
- if (msbFirst)
- *((EAS_U32*) p) = ((EAS_U32) c1 << 24) | ((EAS_U32) c2 << 16) | ((EAS_U32) c3 << 8) | c4;
- else
- *((EAS_U32*) p)= ((EAS_U32) c4 << 24) | ((EAS_U32) c3 << 16) | ((EAS_U32) c2 << 8) | c1;
-
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- *
- * EAS_HWFilePos
- *
- * Returns the current location in the file
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, hwInstData) available for customer use */
-EAS_RESULT EAS_HWFilePos (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, EAS_I32 *pPosition)
-{
-
- /* simulate failure */
- if (errorConditions[ePosError])
- return EAS_FAILURE;
-
- /* make sure we have a valid handle */
- if (file->buffer == NULL)
- return EAS_ERROR_INVALID_HANDLE;
-
- *pPosition = file->filePos;
- return EAS_SUCCESS;
-} /* end EAS_HWFilePos */
-
-/*----------------------------------------------------------------------------
- *
- * EAS_HWFileSeek
- *
- * Seek to a specific location in the file
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, hwInstData) available for customer use */
-EAS_RESULT EAS_HWFileSeek (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, EAS_I32 position)
-{
-
- /* simulate failure */
- if (errorConditions[eSeekError])
- return EAS_FAILURE;
-
- /* make sure we have a valid handle */
- if (file->buffer == NULL)
- return EAS_ERROR_INVALID_HANDLE;
-
- /* validate new position */
- if ((position < 0) || (position > file->fileSize))
- return EAS_ERROR_FILE_SEEK;
-
- /* save new position */
- file->filePos = position;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- *
- * EAS_HWFileSeekOfs
- *
- * Seek forward or back relative to the current position
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, hwInstData) available for customer use */
-EAS_RESULT EAS_HWFileSeekOfs (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, EAS_I32 position)
-{
-
- /* simulate failure */
- if (errorConditions[eSeekError])
- return EAS_FAILURE;
-
- /* make sure we have a valid handle */
- if (file->buffer == NULL)
- return EAS_ERROR_INVALID_HANDLE;
-
- /* determine the file position */
- position += file->filePos;
- if ((position < 0) || (position > file->fileSize))
- return EAS_ERROR_FILE_SEEK;
-
- /* save new position */
- file->filePos = position;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- *
- * EAS_HWFileLength
- *
- * Return the file length
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, hwInstData) available for customer use */
-EAS_RESULT EAS_HWFileLength (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, EAS_I32 *pLength)
-{
-
- /* simulate failure */
- if (errorConditions[eLengthError])
- return EAS_FAILURE;
-
- /* make sure we have a valid handle */
- if (file->buffer == NULL)
- return EAS_ERROR_INVALID_HANDLE;
-
- *pLength = file->fileSize;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- *
- * EAS_HWDupHandle
- *
- * Duplicate a file handle
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT EAS_HWDupHandle (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, EAS_FILE_HANDLE *pDupFile)
-{
- EAS_HW_FILE *dupFile;
- int i;
-
- /* simulate failure */
- if (errorConditions[eDupError])
- return EAS_FAILURE;
-
- /* make sure we have a valid handle */
- if (file->buffer == NULL)
- return EAS_ERROR_INVALID_HANDLE;
-
- /* find an empty entry in the file table */
- dupFile = hwInstData->files;
- for (i = 0; i < EAS_MAX_FILE_HANDLES; i++)
- {
- /* is this slot being used? */
- if (dupFile->buffer == NULL)
- {
-
- /* copy info from the handle to be duplicated */
- dupFile->filePos = file->filePos;
- dupFile->fileSize = file->fileSize;
- dupFile->buffer = file->buffer;
-
- /* set the duplicate handle flag */
- dupFile->dup = file->dup = EAS_TRUE;
-
- *pDupFile = dupFile;
- return EAS_SUCCESS;
- }
- dupFile++;
- }
-
- /* too many open files */
- return EAS_ERROR_MAX_FILES_OPEN;
-}
-
-/*----------------------------------------------------------------------------
- *
- * EAS_HWClose
- *
- * Wrapper for fclose function
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT EAS_HWCloseFile (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file1)
-{
- EAS_HW_FILE *file2,*dupFile;
- int i;
-
- /* simulate failure */
- if (errorConditions[eCloseError])
- return EAS_FAILURE;
-
- /* make sure we have a valid handle */
- if (file1->buffer == NULL)
- return EAS_ERROR_INVALID_HANDLE;
-
- /* check for duplicate handle */
- if (file1->dup)
- {
- dupFile = NULL;
- file2 = hwInstData->files;
- for (i = 0; i < EAS_MAX_FILE_HANDLES; i++)
- {
- /* check for duplicate */
- if ((file1 != file2) && (file2->buffer == file1->buffer))
- {
- /* is there more than one duplicate? */
- if (dupFile != NULL)
- {
- /* clear this entry and return */
- file1->buffer = NULL;
- return EAS_SUCCESS;
- }
-
- /* this is the first duplicate found */
- else
- dupFile = file2;
- }
- file2++;
- }
-
- /* there is only one duplicate, clear the dup flag */
- if (dupFile)
- dupFile->dup = EAS_FALSE;
- else
- /* if we get here, there's a serious problem */
- return EAS_ERROR_HANDLE_INTEGRITY;
-
- /* clear this entry and return */
- file1->buffer = NULL;
- return EAS_SUCCESS;
- }
-
- /* no duplicates -free the buffer */
- EAS_HWFree(hwInstData, file1->buffer);
-
- /* clear this entry and return */
- file1->buffer = NULL;
- return EAS_SUCCESS;
-}
-#endif
-
-/*----------------------------------------------------------------------------
- *
- * EAS_HWVibrate
- *
- * Turn on/off vibrate function
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, hwInstData) available for customer use */
-EAS_RESULT EAS_HWVibrate (EAS_HW_DATA_HANDLE hwInstData, EAS_BOOL state)
-{
- vibState = state;
-// EAS_ReportX(_EAS_SEVERITY_NOFILTER, "Vibrate state: %d\n", state);
- return EAS_SUCCESS;
-} /* end EAS_HWVibrate */
-
-/*----------------------------------------------------------------------------
- *
- * EAS_HWLED
- *
- * Turn on/off LED
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, hwInstData) available for customer use */
-EAS_RESULT EAS_HWLED (EAS_HW_DATA_HANDLE hwInstData, EAS_BOOL state)
-{
- ledState = state;
-// EAS_ReportX(_EAS_SEVERITY_NOFILTER, "LED state: %d\n", state);
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- *
- * EAS_HWBackLight
- *
- * Turn on/off backlight
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, hwInstData) available for customer use */
-EAS_RESULT EAS_HWBackLight (EAS_HW_DATA_HANDLE hwInstData, EAS_BOOL state)
-{
- backlightState = state;
-// EAS_ReportX(_EAS_SEVERITY_NOFILTER, "Backlight state: %d\n", state);
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- *
- * EAS_HWYield
- *
- * This function is called periodically by the EAS library to give the
- * host an opportunity to allow other tasks to run. There are two ways to
- * use this call:
- *
- * If you have a multi-tasking OS, you can call the yield function in the
- * OS to allow other tasks to run. In this case, return EAS_FALSE to tell
- * the EAS library to continue processing when control returns from this
- * function.
- *
- * If tasks run in a single thread by sequential function calls (sometimes
- * call a "commutator loop"), return EAS_TRUE to cause the EAS Library to
- * return to the caller. Be sure to check the number of bytes rendered
- * before passing the audio buffer to the codec - it may not be filled.
- * The next call to EAS_Render will continue processing until the buffer
- * has been filled.
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, hwInstData) available for customer use */
-EAS_BOOL EAS_HWYield (EAS_HW_DATA_HANDLE hwInstData)
-{
- /* put your code here */
- return EAS_FALSE;
-}
-
-
+/*
+ * EASLib.c
+ * EASLIb
+ *
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <string.h>
+
+#include "eas.h"
+#include "eas_report.h"
+#include "eas_host.h"
+
+#ifdef JET_INTERFACE
+#include "jet.h"
+#endif
+
+
+#define EAS_EXPORT __attribute__((visibility("default")))
+
+// #define DEBUG_FILE_IO
+
+/* include debug interface */
+#include "eas_host_debug.h"
+
+#ifdef AUX_MIXER
+#include "eas_auxmix.h"
+#endif
+
+/* this module requires dynamic memory support */
+#ifdef _STATIC_MEMORY
+#error "eas_hostmm.c requires the dynamic memory model!\n"
+#endif
+
+#ifndef EAS_MAX_FILE_HANDLES
+#define EAS_MAX_FILE_HANDLES 32
+#endif
+
+#ifndef EAS_FILE_BUFFER_SIZE
+#define EAS_FILE_BUFFER_SIZE 32
+#endif
+
+/*
+ * this structure and the related function are here
+ * to support the ability to create duplicate handles
+ * and buffering it in memory. If your system uses
+ * in-memory resources, you can eliminate the calls
+ * to malloc and free, the dup flag, and simply track
+ * the file size and read position.
+ */
+ #ifdef BUFFERED_FILE_ACCESS
+typedef struct eas_hw_file_tag
+{
+ FILE *pFile;
+ EAS_I32 bytesInBuffer;
+ EAS_I32 readIndex;
+ EAS_I32 filePos;
+ EAS_I32 fileSize;
+ EAS_BOOL dup;
+ EAS_U8 buffer[EAS_FILE_BUFFER_SIZE];
+} EAS_HW_FILE;
+#else
+typedef struct eas_hw_file_tag
+{
+ EAS_I32 fileSize;
+ EAS_I32 filePos;
+ EAS_BOOL dup;
+ EAS_U8 *buffer;
+} EAS_HW_FILE;
+#endif
+
+typedef struct eas_hw_inst_data_tag
+{
+ EAS_HW_FILE files[EAS_MAX_FILE_HANDLES];
+} EAS_HW_INST_DATA;
+
+EAS_BOOL errorConditions[eNumErrorConditions];
+EAS_BOOL ledState;
+EAS_BOOL vibState;
+EAS_BOOL backlightState;
+
+#define MAX_DEBUG_MSG_LEN 1024
+
+typedef void (*EAS_LOG_FUNC)(EAS_INT severity, char *msg);
+
+static EAS_LOG_FUNC logCallback = NULL;
+static char messageBuffer[MAX_DEBUG_MSG_LEN];
+
+/* error counts */
+static EAS_INT eas_fatalErrors;
+static EAS_INT eas_errors;
+static EAS_INT eas_warnings;
+static int severityLevel = 9999;
+
+/* wave out device */
+#ifndef MAX_WAVE_OUT_BUFFERS
+#define MAX_WAVE_OUT_BUFFERS 8
+#endif
+
+#ifndef EAS_BUFFERS_PER_WAVE_BUFFER
+#define EAS_BUFFERS_PER_WAVE_BUFFER 8
+#endif
+
+/*----------------------------------------------------------------------------
+ * ResetErrorCounters()
+ *----------------------------------------------------------------------------
+*/
+EAS_EXPORT void ResetErrorCounters()
+{
+ eas_fatalErrors = 0;
+ eas_errors = 0;
+ eas_warnings = 0;
+}
+
+/*----------------------------------------------------------------------------
+ * SetLogCallback()
+ *----------------------------------------------------------------------------
+*/
+EAS_EXPORT void SetLogCallback (EAS_LOG_FUNC callback)
+{
+ logCallback = callback;
+}
+
+#ifndef _NO_DEBUG_PREPROCESSOR
+static S_DEBUG_MESSAGES debugMessages[] =
+{
+#ifdef UNIFIED_DEBUG_MESSAGES
+#include "eas_debugmsgs.h"
+#endif
+ { 0,0,0 }
+};
+
+/*----------------------------------------------------------------------------
+ * EAS_ReportEx()
+ *----------------------------------------------------------------------------
+*/
+void EAS_ReportEx (int severity, unsigned long hashCode, int serialNum, ...)
+{
+ va_list vargs;
+ int i;
+
+ switch (severity)
+ {
+ case _EAS_SEVERITY_FATAL:
+ eas_fatalErrors++;
+ break;
+
+ case _EAS_SEVERITY_ERROR:
+ eas_errors++;
+ break;
+
+ case _EAS_SEVERITY_WARNING:
+ eas_warnings++;
+ break;
+
+ default:
+ break;
+ }
+
+ /* check severity level */
+ if (severity > severityLevel)
+ return;
+
+ /* check for callback */
+ if (logCallback == NULL)
+ return;
+
+ /* find the error message and output to stdout */
+ for (i = 0; debugMessages[i].m_pDebugMsg; i++)
+ {
+ if ((debugMessages[i].m_nHashCode == hashCode) &&
+ (debugMessages[i].m_nSerialNum == serialNum))
+ {
+ va_start(vargs, serialNum);
+#ifdef WIN32
+ vsprintf_s(messageBuffer, sizeof(messageBuffer), fmt, vargs);
+#else
+ vsprintf(messageBuffer, debugMessages[i].m_pDebugMsg, vargs);
+#endif
+ logCallback(severity, messageBuffer);
+ va_end(vargs);
+ return;
+ }
+ }
+ printf("Unrecognized error: Severity=%d; HashCode=%lu; SerialNum=%d\n", severity, hashCode, serialNum);
+} /* end EAS_ReportEx */
+
+#else
+/*----------------------------------------------------------------------------
+ * EAS_Report()
+ *----------------------------------------------------------------------------
+*/
+void EAS_Report (int severity, const char *fmt, ...)
+{
+ va_list vargs;
+
+ switch (severity)
+ {
+ case _EAS_SEVERITY_FATAL:
+ eas_fatalErrors++;
+ break;
+
+ case _EAS_SEVERITY_ERROR:
+ eas_errors++;
+ break;
+
+ case _EAS_SEVERITY_WARNING:
+ eas_warnings++;
+ break;
+
+ default:
+ break;
+ }
+
+ /* check severity level */
+ if (severity > severityLevel)
+ return;
+
+ /* check for callback */
+ if (logCallback == NULL)
+ return;
+
+ va_start(vargs, fmt);
+#ifdef _WIN32
+ vsprintf_s(messageBuffer, sizeof(messageBuffer), fmt, vargs);
+#else
+ vsprintf(messageBuffer, fmt, vargs);
+#endif
+ logCallback(severity, messageBuffer);
+ va_end(vargs);
+} /* end EAS_Report */
+
+/*----------------------------------------------------------------------------
+ * EAS_ReportX()
+ *----------------------------------------------------------------------------
+*/
+void EAS_ReportX (int severity, const char *fmt, ...)
+{
+ va_list vargs;
+
+ switch (severity)
+ {
+ case _EAS_SEVERITY_FATAL:
+ eas_fatalErrors++;
+ break;
+
+ case _EAS_SEVERITY_ERROR:
+ eas_errors++;
+ break;
+
+ case _EAS_SEVERITY_WARNING:
+ eas_warnings++;
+ break;
+
+ default:
+ break;
+ }
+
+ /* check severity level */
+ if (severity > severityLevel)
+ return;
+
+ /* check for callback */
+ if (logCallback == NULL)
+ return;
+
+ va_start(vargs, fmt);
+#ifdef _WIN32
+ vsprintf_s(messageBuffer, sizeof(messageBuffer), fmt, vargs);
+#else
+ vsprintf(messageBuffer, fmt, vargs);
+#endif
+ logCallback(severity, messageBuffer);
+ va_end(vargs);
+}
+#endif
+
+/*----------------------------------------------------------------------------
+ * EAS_DLLSetDebugLevel()
+ *----------------------------------------------------------------------------
+*/
+EAS_EXPORT void EAS_DLLSetDebugLevel (int severity)
+{
+ severityLevel = severity;
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_ExSetDebugLevel()
+ *----------------------------------------------------------------------------
+*/
+void EAS_SetDebugLevel (int severity)
+{
+ severityLevel = severity;
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_SelectLibrary()
+ *----------------------------------------------------------------------------
+*/
+EAS_EXPORT EAS_RESULT EAS_SelectLib (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle, EAS_BOOL testLib)
+{
+ extern EAS_SNDLIB_HANDLE VMGetLibHandle(EAS_INT libNum);
+ return EAS_SetSoundLibrary(pEASData, streamHandle, VMGetLibHandle(testLib ? 1 : 0));
+}
+
+
+#if defined(_DEBUG) && !defined(MSC)
+#include <crtdbg.h>
+/*----------------------------------------------------------------------------
+ * EnableHeapDebug()
+ *----------------------------------------------------------------------------
+*/
+static void EnableHeapDebug (void)
+{
+ int temp;
+ temp = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
+ temp |= _CRTDBG_ALLOC_MEM_DF;
+ temp |= _CRTDBG_CHECK_ALWAYS_DF;
+ temp |= _CRTDBG_LEAK_CHECK_DF;
+// temp |= _CRTDBG_DELAY_FREE_MEM_DF;
+ _CrtSetDbgFlag(temp);
+}
+
+/*----------------------------------------------------------------------------
+ * HeapCheck()
+ *----------------------------------------------------------------------------
+ * Check heap status
+ *----------------------------------------------------------------------------
+*/
+void HeapCheck (void)
+{
+ int heapStatus;
+
+ /* Check heap status */
+ heapStatus = _heapchk();
+ if ((heapStatus == _HEAPOK) || (heapStatus == _HEAPEMPTY))
+ return;
+
+ EAS_ReportX(_EAS_SEVERITY_FATAL, "Heap corrupt\n" );
+}
+#endif
+
+
+/*----------------------------------------------------------------------------
+ * EAS_HWInit
+ *
+ * Initialize host wrapper interface
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_HWInit (EAS_HW_DATA_HANDLE *pHWInstData)
+{
+
+#if defined(_DEBUG) && !defined(MSC)
+ EnableHeapDebug();
+#endif
+
+ #ifdef BUFFERED_FILE_ACCESS
+ EAS_ReportX(_EAS_SEVERITY_INFO, "EAS_HWInit: Buffered file access\n");
+ #else
+ EAS_ReportX(_EAS_SEVERITY_INFO, "EAS_HWInit: Memory mapped file access\n");
+ #endif
+
+ /* simulate failure */
+ if (errorConditions[eInitError])
+ return EAS_FAILURE;
+
+ /* need to track file opens for duplicate handles */
+ *pHWInstData = malloc(sizeof(EAS_HW_INST_DATA));
+ if (!(*pHWInstData))
+ return EAS_ERROR_MALLOC_FAILED;
+
+ EAS_HWMemSet(*pHWInstData, 0, sizeof(EAS_HW_INST_DATA));
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_HWShutdown
+ *
+ * Shut down host wrapper interface
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_HWShutdown (EAS_HW_DATA_HANDLE hwInstData)
+{
+
+ /* simulate failure */
+ if (errorConditions[eShutdownError])
+ return EAS_FAILURE;
+
+ free(hwInstData);
+
+#if defined(_DEBUG) && !defined(MSC)
+ HeapCheck();
+#endif
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_HWMalloc
+ *
+ * Allocates dynamic memory
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, hwInstData) available for customer use */
+void *EAS_HWMalloc (EAS_HW_DATA_HANDLE hwInstData, EAS_I32 size)
+{
+ /* simulate failure */
+ if (errorConditions[eMallocError])
+ return NULL;
+
+ return malloc((size_t) size);
+}
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_HWFree
+ *
+ * Frees dynamic memory
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, hwInstData) available for customer use */
+void EAS_HWFree (EAS_HW_DATA_HANDLE hwInstData, void *p)
+{
+ free(p);
+}
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_HWMemCpy
+ *
+ * Copy memory wrapper
+ *
+ *----------------------------------------------------------------------------
+*/
+void *EAS_HWMemCpy (void *dest, const void *src, EAS_I32 amount)
+{
+ return memcpy(dest, src, (size_t) amount);
+}
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_HWMemSet
+ *
+ * Set memory wrapper
+ *
+ *----------------------------------------------------------------------------
+*/
+void *EAS_HWMemSet (void *dest, int val, EAS_I32 amount)
+{
+ return memset(dest, val, (size_t) amount);
+}
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_HWMemCmp
+ *
+ * Compare memory wrapper
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_I32 EAS_HWMemCmp (const void *s1, const void *s2, EAS_I32 amount)
+{
+ return (EAS_I32) memcmp(s1, s2, (size_t) amount);
+}
+
+#ifdef BUFFERED_FILE_ACCESS
+/*----------------------------------------------------------------------------
+ *
+ * EAS_HWOpenFile
+ *
+ * Open a file for read or write
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_HWOpenFile (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_LOCATOR locator, EAS_FILE_HANDLE *pFile, EAS_FILE_MODE mode)
+{
+ EAS_HW_FILE *file;
+ int i;
+
+ /* set return value to NULL */
+ *pFile = NULL;
+
+ /* only support read mode at this time */
+ if (mode != EAS_FILE_READ)
+ return EAS_ERROR_INVALID_FILE_MODE;
+
+ /* find an empty entry in the file table */
+ file = hwInstData->files;
+ for (i = 0; i < EAS_MAX_FILE_HANDLES; i++)
+ {
+ /* is this slot being used? */
+ if (file->pFile == NULL)
+ {
+ EAS_RESULT result;
+
+ /* open the file */
+ file->pFile = fopen((const char*) locator, "rb");
+ if (file->pFile == NULL)
+ return EAS_ERROR_FILE_OPEN_FAILED;
+
+ /* get file length */
+ if ((result = EAS_HWFileLength(hwInstData, file, &file->fileSize)) != EAS_SUCCESS)
+ {
+ EAS_HWCloseFile(hwInstData, file);
+ return result;
+ }
+
+#ifdef DEBUG_FILE_IO
+ EAS_ReportX(_EAS_SEVERITY_NOFILTER, "EAS_HWOpenFile: Open file %d\n", i);
+#endif
+
+ /* initialize some values */
+ file->bytesInBuffer = 0;
+ file->readIndex = 0;
+ file->filePos = 0;
+ file->dup = EAS_FALSE;
+
+ *pFile = file;
+ return EAS_SUCCESS;
+ }
+ file++;
+ }
+
+ /* too many open files */
+ return EAS_ERROR_MAX_FILES_OPEN;
+}
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_HWFillBuffer
+ *
+ * Fill buffer from file
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, hwInstData) hwInstData available for customer use */
+EAS_RESULT EAS_HWFillBuffer (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file)
+{
+ /* reposition the file pointer */
+ if (fseek(file->pFile, file->filePos, SEEK_SET) != 0)
+ return EAS_ERROR_FILE_SEEK;
+
+ /* read some data from the file */
+ file->bytesInBuffer = (EAS_I32) fread(file->buffer, 1, EAS_FILE_BUFFER_SIZE, file->pFile);
+ file->readIndex = 0;
+ if (file->bytesInBuffer == 0)
+ return EAS_EOF;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_HWReadFile
+ *
+ * Read data from a file
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, hwInstData) hwInstData available for customer use */
+EAS_RESULT EAS_HWReadFile (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, void *pBuffer, EAS_I32 n, EAS_I32 *pBytesRead)
+{
+ EAS_RESULT result;
+ EAS_I32 temp;
+ EAS_U8 *p = pBuffer;
+ EAS_I32 bytesLeft = n;
+
+ *pBytesRead = 0;
+
+ /* check handle integrity */
+ if (file->pFile == NULL)
+ return EAS_ERROR_INVALID_HANDLE;
+
+#ifdef DEBUG_FILE_IO
+ EAS_ReportX(_EAS_SEVERITY_NOFILTER, "EAS_HWReadFile: Reading %d bytes from position %d\n", n, file->filePos);
+#endif
+
+ /* try to fulfill request from buffer */
+ for (;bytesLeft > 0;)
+ {
+ /* how many bytes can we get from buffer? */
+ temp = file->bytesInBuffer - file->readIndex;
+ if (temp > bytesLeft)
+ temp = bytesLeft;
+
+ /* copy data from buffer */
+ EAS_HWMemCpy(p, &file->buffer[file->readIndex], temp);
+ *pBytesRead += temp;
+ file->readIndex += temp;
+ file->filePos += temp;
+ p += temp;
+ bytesLeft -= temp;
+
+ /* don't refill buffer if request is bigger than buffer */
+ if ((bytesLeft == 0) || (bytesLeft >= EAS_FILE_BUFFER_SIZE))
+ break;
+
+ /* refill buffer */
+ if ((result = EAS_HWFillBuffer(hwInstData, file)) != EAS_SUCCESS)
+ return result;
+ }
+
+ /* more to read? do unbuffered read directly to target memory */
+ if (bytesLeft)
+ {
+
+ /* position the file pointer */
+ if (fseek(file->pFile, file->filePos, SEEK_SET) != 0)
+ return EAS_ERROR_FILE_SEEK;
+
+ /* read data in the buffer */
+ temp = (EAS_I32) fread(p, 1, (size_t) bytesLeft, file->pFile);
+ *pBytesRead += temp;
+ file->filePos += temp;
+
+ /* reset buffer info */
+ file->bytesInBuffer = 0;
+ file->readIndex = 0;
+ }
+
+#ifdef DEBUG_FILE_IO
+ {
+#define BYTES_PER_LINE 16
+ char str[BYTES_PER_LINE * 3 + 1];
+ EAS_INT i;
+ for (i = 0; i < (n > BYTES_PER_LINE ? BYTES_PER_LINE : n) ; i ++)
+ sprintf(&str[i*3], "%02x ", ((EAS_U8*)pBuffer)[i]);
+ if (i)
+ EAS_ReportX(_EAS_SEVERITY_NOFILTER, "%s\n", str);
+ }
+#endif
+
+ /* were n bytes read? */
+ if (*pBytesRead != n)
+ return EAS_EOF;
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_HWGetByte
+ *
+ * Read a byte from a file
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, hwInstData) hwInstData available for customer use */
+EAS_RESULT EAS_HWGetByte (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, void *p)
+{
+ EAS_RESULT result;
+
+ /* check handle integrity */
+ if (file->pFile == NULL)
+ return EAS_ERROR_INVALID_HANDLE;
+
+ /* use local buffer - do we have any data? */
+ if (file->readIndex >= file->bytesInBuffer)
+ {
+ if ((result = EAS_HWFillBuffer(hwInstData, file)) != EAS_SUCCESS)
+ return result;
+
+ /* if nothing to read, return EOF */
+ if (file->bytesInBuffer == 0)
+ return EAS_EOF;
+ }
+
+ /* get a character from the buffer */
+ *((EAS_U8*) p) = file->buffer[file->readIndex++];
+
+#ifdef DEBUG_FILE_IO
+ EAS_ReportX(_EAS_SEVERITY_NOFILTER, "EAS_HWGetByte: Reading from position %d, byte = 0x%02x\n", file->filePos, *(EAS_U8*)p);
+#endif
+
+ file->filePos++;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_HWGetWord
+ *
+ * Read a 16-bit value from the file
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_HWGetWord (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, void *p, EAS_BOOL msbFirst)
+{
+ EAS_RESULT result;
+ EAS_I32 count;
+ EAS_U8 c[2];
+
+#ifdef DEBUG_FILE_IO
+ EAS_ReportX(_EAS_SEVERITY_NOFILTER, "EAS_HWGetWord: Reading 2 bytes from position %d\n", file->filePos);
+#endif
+
+ /* read 2 bytes from the file */
+ if ((result = EAS_HWReadFile(hwInstData, file, c, 2, &count)) != EAS_SUCCESS)
+ return result;
+
+ /* order them as requested */
+ if (msbFirst)
+ *((EAS_U16*) p) = ((EAS_U16) c[0] << 8) | c[1];
+ else
+ *((EAS_U16*) p) = ((EAS_U16) c[1] << 8) | c[0];
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_HWGetDWord
+ *
+ * Read a 16-bit value from the file
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_HWGetDWord (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, void *p, EAS_BOOL msbFirst)
+{
+ EAS_RESULT result;
+ EAS_I32 count;
+ EAS_U8 c[4];
+
+#ifdef DEBUG_FILE_IO
+ EAS_ReportX(_EAS_SEVERITY_NOFILTER, "EAS_HWGetDWord: Reading 4 bytes from position %d\n", file->filePos);
+#endif
+
+ /* read 4 bytes from the file */
+ if ((result = EAS_HWReadFile(hwInstData, file, c, 4, &count)) != EAS_SUCCESS)
+ return result;
+
+ /* order them as requested */
+ if (msbFirst)
+ *((EAS_U32*) p) = ((EAS_U32) c[0] << 24) | ((EAS_U32) c[1] << 16) | ((EAS_U32) c[2] << 8) | c[3];
+ else
+ *((EAS_U32*) p) = ((EAS_U32) c[3] << 24) | ((EAS_U32) c[2] << 16) | ((EAS_U32) c[1] << 8) | c[0];
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_HWFilePos
+ *
+ * Returns the current location in the file
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, hwInstData) hwInstData available for customer use */
+EAS_RESULT EAS_HWFilePos (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, EAS_I32 *pPosition)
+{
+
+ /* check handle integrity */
+ if (file->pFile == NULL)
+ return EAS_ERROR_INVALID_HANDLE;
+
+ *pPosition = file->filePos;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_HWFileSeek
+ *
+ * Seek to a specific location in the file
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, hwInstData) hwInstData available for customer use */
+EAS_RESULT EAS_HWFileSeek (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, EAS_I32 position)
+{
+ EAS_I32 newIndex;
+
+ /* check handle integrity */
+ if (file->pFile == NULL)
+ return EAS_ERROR_INVALID_HANDLE;
+
+ /* check for seek past end */
+ if ((position < 0) || (position > file->fileSize))
+ return EAS_ERROR_FILE_SEEK;
+
+#ifdef DEBUG_FILE_IO
+ EAS_ReportX(_EAS_SEVERITY_NOFILTER, "EAS_HWFileSeek: Seeking to new position %d\n", file->filePos);
+#endif
+
+ /* is new position in current buffer? */
+ newIndex = position - file->filePos + file->readIndex;
+ if ((newIndex >= 0) && (newIndex < file->bytesInBuffer))
+ {
+ file->readIndex = newIndex;
+ file->filePos = position;
+ return EAS_SUCCESS;
+ }
+
+ /* save new position and reset buffer info so EAS_HWGetByte doesn't fail */
+ file->filePos = position;
+ file->bytesInBuffer = 0;
+ file->readIndex = 0;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_HWFileSeekOfs
+ *
+ * Seek forward or back relative to the current position
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, hwInstData) hwInstData available for customer use */
+EAS_RESULT EAS_HWFileSeekOfs (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, EAS_I32 position)
+{
+ EAS_I32 temp;
+
+#ifdef DEBUG_FILE_IO
+ EAS_ReportX(_EAS_SEVERITY_NOFILTER, "EAS_HWFileSeekOfs: Seeking to new position %d\n", file->filePos + position);
+#endif
+
+ /* check handle integrity */
+ if (file->pFile == NULL)
+ return EAS_ERROR_INVALID_HANDLE;
+
+ /* check for seek past end */
+ temp = file->filePos + position;
+ if ((temp < 0) || (temp > file->fileSize))
+ return EAS_ERROR_FILE_SEEK;
+
+ /* is new position in current buffer? */
+ temp = position + file->readIndex;
+ if ((temp >= 0) && (temp < file->bytesInBuffer))
+ {
+ file->readIndex = temp;
+ file->filePos += position;
+ return EAS_SUCCESS;
+ }
+
+ /* save new position and reset buffer info so EAS_HWGetByte doesn't fail */
+ file->filePos += position;
+ file->bytesInBuffer = 0;
+ file->readIndex = 0;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_HWFileLength
+ *
+ * Return the file length
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, hwInstData) hwInstData available for customer use */
+EAS_RESULT EAS_HWFileLength (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, EAS_I32 *pLength)
+{
+ long pos;
+
+ /* check handle integrity */
+ if (file->pFile == NULL)
+ return EAS_ERROR_INVALID_HANDLE;
+
+ if ((pos = ftell(file->pFile)) == -1L)
+ return EAS_ERROR_FILE_LENGTH;
+ if (fseek(file->pFile, 0L, SEEK_END) != 0)
+ return EAS_ERROR_FILE_LENGTH;
+ if ((*pLength = ftell(file->pFile)) == -1L)
+ return EAS_ERROR_FILE_LENGTH;
+ if (fseek(file->pFile, pos, SEEK_SET) != 0)
+ return EAS_ERROR_FILE_LENGTH;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_HWDupHandle
+ *
+ * Duplicate a file handle
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_HWDupHandle (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, EAS_FILE_HANDLE* pDupFile)
+{
+ EAS_HW_FILE *dupfile;
+ int i;
+
+ /* check handle integrity */
+ *pDupFile = NULL;
+ if (file->pFile == NULL)
+ return EAS_ERROR_INVALID_HANDLE;
+
+ /* find an empty entry in the file table */
+ dupfile = hwInstData->files;
+ for (i = 0; i < EAS_MAX_FILE_HANDLES; i++)
+ {
+ /* is this slot being used? */
+ if (dupfile->pFile == NULL)
+ {
+
+ /* copy info from the handle to be duplicated */
+ dupfile->filePos = file->filePos;
+ dupfile->pFile = file->pFile;
+ dupfile->fileSize = file->fileSize;
+
+ /* set the duplicate handle flag */
+ dupfile->dup = file->dup = EAS_TRUE;
+
+ /* initialize some values */
+ dupfile->bytesInBuffer = 0;
+ dupfile->readIndex = 0;
+
+ *pDupFile = dupfile;
+ return EAS_SUCCESS;
+ }
+ dupfile++;
+ }
+
+ /* too many open files */
+ return EAS_ERROR_MAX_FILES_OPEN;
+}
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_HWClose
+ *
+ * Wrapper for fclose function
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_HWCloseFile (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file1)
+{
+ EAS_HW_FILE *file2,*dupFile;
+ int i;
+
+ /* check handle integrity */
+ if (file1->pFile == NULL)
+ return EAS_ERROR_INVALID_HANDLE;
+
+ /* check for duplicate handle */
+ if (file1->dup)
+ {
+ dupFile = NULL;
+ file2 = hwInstData->files;
+ for (i = 0; i < EAS_MAX_FILE_HANDLES; i++)
+ {
+ /* check for duplicate */
+ if ((file1 != file2) && (file2->pFile == file1->pFile))
+ {
+ /* is there more than one duplicate? */
+ if (dupFile != NULL)
+ {
+ /* clear this entry and return */
+ file1->pFile = NULL;
+ return EAS_SUCCESS;
+ }
+
+ /* this is the first duplicate found */
+ dupFile = file2;
+ }
+ file2++;
+ }
+
+ /* there is only one duplicate, clear the dup flag */
+ if (dupFile)
+ dupFile->dup = EAS_FALSE;
+ else
+ /* if we get here, there's a serious problem */
+ return EAS_ERROR_HANDLE_INTEGRITY;
+
+ /* clear this entry and return */
+ file1->pFile = NULL;
+ return EAS_SUCCESS;
+ }
+
+ /* no duplicates - close the file */
+ if (fclose(file1->pFile) != 0)
+ return EAS_ERROR_CLOSE_FAILED;
+
+ /* clear this entry and return */
+ file1->pFile = NULL;
+ return EAS_SUCCESS;
+}
+#else
+/*----------------------------------------------------------------------------
+ *
+ * EAS_HWOpenFile
+ *
+ * Open a file for read or write
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_HWOpenFile (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_LOCATOR locator, EAS_FILE_HANDLE *pFile, EAS_FILE_MODE mode)
+{
+ EAS_HW_FILE *file;
+ FILE *ioFile;
+ int i, temp;
+
+ /* set return value to NULL */
+ *pFile = NULL;
+
+ /* simulate failure */
+ if (errorConditions[eOpenError])
+ return EAS_FAILURE;
+
+ /* only support read mode at this time */
+ if (mode != EAS_FILE_READ)
+ return EAS_ERROR_INVALID_FILE_MODE;
+
+ /* find an empty entry in the file table */
+ file = hwInstData->files;
+ for (i = 0; i < EAS_MAX_FILE_HANDLES; i++)
+ {
+ /* is this slot being used? */
+ if (file->buffer == NULL)
+ {
+ /* open the file */
+ if ((ioFile = fopen(locator,"rb")) == NULL)
+ return EAS_ERROR_FILE_OPEN_FAILED;
+
+ /* determine the file size */
+ if (fseek(ioFile, 0L, SEEK_END) != 0)
+ return EAS_ERROR_FILE_LENGTH;
+ if ((file->fileSize = ftell(ioFile)) == -1L)
+ return EAS_ERROR_FILE_LENGTH;
+ if (fseek(ioFile, 0L, SEEK_SET) != 0)
+ return EAS_ERROR_FILE_LENGTH;
+
+ /* allocate a buffer */
+ file->buffer = EAS_HWMalloc(hwInstData, file->fileSize);
+ if (file->buffer == NULL)
+ {
+ fclose(ioFile);
+ return EAS_ERROR_MALLOC_FAILED;
+ }
+
+ /* read the file into memory */
+ temp = (int) fread(file->buffer, (size_t) file->fileSize, 1, ioFile);
+
+ /* close the file - don't need it any more */
+ fclose(ioFile);
+
+ /* check for error reading file */
+ if (temp != 1)
+ return EAS_ERROR_FILE_READ_FAILED;
+
+ /* initialize some values */
+ file->filePos = 0;
+ file->dup = EAS_FALSE;
+
+ *pFile = file;
+ return EAS_SUCCESS;
+ }
+ file++;
+ }
+
+ /* too many open files */
+ return EAS_ERROR_MAX_FILES_OPEN;
+}
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_HWReadFile
+ *
+ * Read data from a file
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, hwInstData) available for customer use */
+EAS_RESULT EAS_HWReadFile (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, void *pBuffer, EAS_I32 n, EAS_I32 *pBytesRead)
+{
+ EAS_I32 count;
+
+ /* simulate failure */
+ if (errorConditions[eReadError])
+ return EAS_FAILURE;
+
+ /* make sure we have a valid handle */
+ if (file->buffer == NULL)
+ return EAS_ERROR_INVALID_HANDLE;
+
+ /* calculate the bytes to read */
+ count = file->fileSize - file->filePos;
+ if (n < count)
+ count = n;
+
+ /* copy the data to the requested location, and advance the pointer */
+ if (count)
+ EAS_HWMemCpy(pBuffer, &file->buffer[file->filePos], count);
+ file->filePos += count;
+ *pBytesRead = count;
+
+ /* were n bytes read? */
+ if (count!= n)
+ return EAS_EOF;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_HWGetByte
+ *
+ * Read a byte from a file
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -e{715} hwInstData available for customer use */
+EAS_RESULT EAS_HWGetByte (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, void *p)
+{
+
+ /* simulate failure */
+ if (errorConditions[eReadError])
+ return EAS_FAILURE;
+
+ /* make sure we have a valid handle */
+ if (file->buffer == NULL)
+ return EAS_ERROR_INVALID_HANDLE;
+
+ /* check for end of file */
+ if (file->filePos >= file->fileSize)
+ {
+ *((EAS_U8*) p) = 0;
+ return EAS_EOF;
+ }
+
+ /* get a character from the buffer */
+ *((EAS_U8*) p) = file->buffer[file->filePos++];
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_HWGetWord
+ *
+ * Returns the current location in the file
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, hwInstData) available for customer use */
+EAS_RESULT EAS_HWGetWord (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, void *p, EAS_BOOL msbFirst)
+{
+ EAS_RESULT result;
+ EAS_U8 c1, c2;
+
+ /* read 2 bytes from the file */
+ if ((result = EAS_HWGetByte(hwInstData, file, &c1)) != EAS_SUCCESS)
+ return result;
+ if ((result = EAS_HWGetByte(hwInstData, file, &c2)) != EAS_SUCCESS)
+ return result;
+
+ /* order them as requested */
+ if (msbFirst)
+ *((EAS_U16*) p) = ((EAS_U16) c1 << 8) | c2;
+ else
+ *((EAS_U16*) p) = ((EAS_U16) c2 << 8) | c1;
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_HWGetDWord
+ *
+ * Returns the current location in the file
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, hwInstData) available for customer use */
+EAS_RESULT EAS_HWGetDWord (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, void *p, EAS_BOOL msbFirst)
+{
+ EAS_RESULT result;
+ EAS_U8 c1, c2,c3,c4;
+
+ /* read 4 bytes from the file */
+ if ((result = EAS_HWGetByte(hwInstData, file, &c1)) != EAS_SUCCESS)
+ return result;
+ if ((result = EAS_HWGetByte(hwInstData, file, &c2)) != EAS_SUCCESS)
+ return result;
+ if ((result = EAS_HWGetByte(hwInstData, file, &c3)) != EAS_SUCCESS)
+ return result;
+ if ((result = EAS_HWGetByte(hwInstData, file, &c4)) != EAS_SUCCESS)
+ return result;
+
+ /* order them as requested */
+ if (msbFirst)
+ *((EAS_U32*) p) = ((EAS_U32) c1 << 24) | ((EAS_U32) c2 << 16) | ((EAS_U32) c3 << 8) | c4;
+ else
+ *((EAS_U32*) p)= ((EAS_U32) c4 << 24) | ((EAS_U32) c3 << 16) | ((EAS_U32) c2 << 8) | c1;
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_HWFilePos
+ *
+ * Returns the current location in the file
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, hwInstData) available for customer use */
+EAS_RESULT EAS_HWFilePos (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, EAS_I32 *pPosition)
+{
+
+ /* simulate failure */
+ if (errorConditions[ePosError])
+ return EAS_FAILURE;
+
+ /* make sure we have a valid handle */
+ if (file->buffer == NULL)
+ return EAS_ERROR_INVALID_HANDLE;
+
+ *pPosition = file->filePos;
+ return EAS_SUCCESS;
+} /* end EAS_HWFilePos */
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_HWFileSeek
+ *
+ * Seek to a specific location in the file
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, hwInstData) available for customer use */
+EAS_RESULT EAS_HWFileSeek (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, EAS_I32 position)
+{
+
+ /* simulate failure */
+ if (errorConditions[eSeekError])
+ return EAS_FAILURE;
+
+ /* make sure we have a valid handle */
+ if (file->buffer == NULL)
+ return EAS_ERROR_INVALID_HANDLE;
+
+ /* validate new position */
+ if ((position < 0) || (position > file->fileSize))
+ return EAS_ERROR_FILE_SEEK;
+
+ /* save new position */
+ file->filePos = position;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_HWFileSeekOfs
+ *
+ * Seek forward or back relative to the current position
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, hwInstData) available for customer use */
+EAS_RESULT EAS_HWFileSeekOfs (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, EAS_I32 position)
+{
+
+ /* simulate failure */
+ if (errorConditions[eSeekError])
+ return EAS_FAILURE;
+
+ /* make sure we have a valid handle */
+ if (file->buffer == NULL)
+ return EAS_ERROR_INVALID_HANDLE;
+
+ /* determine the file position */
+ position += file->filePos;
+ if ((position < 0) || (position > file->fileSize))
+ return EAS_ERROR_FILE_SEEK;
+
+ /* save new position */
+ file->filePos = position;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_HWFileLength
+ *
+ * Return the file length
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, hwInstData) available for customer use */
+EAS_RESULT EAS_HWFileLength (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, EAS_I32 *pLength)
+{
+
+ /* simulate failure */
+ if (errorConditions[eLengthError])
+ return EAS_FAILURE;
+
+ /* make sure we have a valid handle */
+ if (file->buffer == NULL)
+ return EAS_ERROR_INVALID_HANDLE;
+
+ *pLength = file->fileSize;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_HWDupHandle
+ *
+ * Duplicate a file handle
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_HWDupHandle (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, EAS_FILE_HANDLE *pDupFile)
+{
+ EAS_HW_FILE *dupFile;
+ int i;
+
+ /* simulate failure */
+ if (errorConditions[eDupError])
+ return EAS_FAILURE;
+
+ /* make sure we have a valid handle */
+ if (file->buffer == NULL)
+ return EAS_ERROR_INVALID_HANDLE;
+
+ /* find an empty entry in the file table */
+ dupFile = hwInstData->files;
+ for (i = 0; i < EAS_MAX_FILE_HANDLES; i++)
+ {
+ /* is this slot being used? */
+ if (dupFile->buffer == NULL)
+ {
+
+ /* copy info from the handle to be duplicated */
+ dupFile->filePos = file->filePos;
+ dupFile->fileSize = file->fileSize;
+ dupFile->buffer = file->buffer;
+
+ /* set the duplicate handle flag */
+ dupFile->dup = file->dup = EAS_TRUE;
+
+ *pDupFile = dupFile;
+ return EAS_SUCCESS;
+ }
+ dupFile++;
+ }
+
+ /* too many open files */
+ return EAS_ERROR_MAX_FILES_OPEN;
+}
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_HWClose
+ *
+ * Wrapper for fclose function
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_HWCloseFile (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file1)
+{
+ EAS_HW_FILE *file2,*dupFile;
+ int i;
+
+ /* simulate failure */
+ if (errorConditions[eCloseError])
+ return EAS_FAILURE;
+
+ /* make sure we have a valid handle */
+ if (file1->buffer == NULL)
+ return EAS_ERROR_INVALID_HANDLE;
+
+ /* check for duplicate handle */
+ if (file1->dup)
+ {
+ dupFile = NULL;
+ file2 = hwInstData->files;
+ for (i = 0; i < EAS_MAX_FILE_HANDLES; i++)
+ {
+ /* check for duplicate */
+ if ((file1 != file2) && (file2->buffer == file1->buffer))
+ {
+ /* is there more than one duplicate? */
+ if (dupFile != NULL)
+ {
+ /* clear this entry and return */
+ file1->buffer = NULL;
+ return EAS_SUCCESS;
+ }
+
+ /* this is the first duplicate found */
+ else
+ dupFile = file2;
+ }
+ file2++;
+ }
+
+ /* there is only one duplicate, clear the dup flag */
+ if (dupFile)
+ dupFile->dup = EAS_FALSE;
+ else
+ /* if we get here, there's a serious problem */
+ return EAS_ERROR_HANDLE_INTEGRITY;
+
+ /* clear this entry and return */
+ file1->buffer = NULL;
+ return EAS_SUCCESS;
+ }
+
+ /* no duplicates -free the buffer */
+ EAS_HWFree(hwInstData, file1->buffer);
+
+ /* clear this entry and return */
+ file1->buffer = NULL;
+ return EAS_SUCCESS;
+}
+#endif
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_HWVibrate
+ *
+ * Turn on/off vibrate function
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, hwInstData) available for customer use */
+EAS_RESULT EAS_HWVibrate (EAS_HW_DATA_HANDLE hwInstData, EAS_BOOL state)
+{
+ vibState = state;
+// EAS_ReportX(_EAS_SEVERITY_NOFILTER, "Vibrate state: %d\n", state);
+ return EAS_SUCCESS;
+} /* end EAS_HWVibrate */
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_HWLED
+ *
+ * Turn on/off LED
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, hwInstData) available for customer use */
+EAS_RESULT EAS_HWLED (EAS_HW_DATA_HANDLE hwInstData, EAS_BOOL state)
+{
+ ledState = state;
+// EAS_ReportX(_EAS_SEVERITY_NOFILTER, "LED state: %d\n", state);
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_HWBackLight
+ *
+ * Turn on/off backlight
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, hwInstData) available for customer use */
+EAS_RESULT EAS_HWBackLight (EAS_HW_DATA_HANDLE hwInstData, EAS_BOOL state)
+{
+ backlightState = state;
+// EAS_ReportX(_EAS_SEVERITY_NOFILTER, "Backlight state: %d\n", state);
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_HWYield
+ *
+ * This function is called periodically by the EAS library to give the
+ * host an opportunity to allow other tasks to run. There are two ways to
+ * use this call:
+ *
+ * If you have a multi-tasking OS, you can call the yield function in the
+ * OS to allow other tasks to run. In this case, return EAS_FALSE to tell
+ * the EAS library to continue processing when control returns from this
+ * function.
+ *
+ * If tasks run in a single thread by sequential function calls (sometimes
+ * call a "commutator loop"), return EAS_TRUE to cause the EAS Library to
+ * return to the caller. Be sure to check the number of bytes rendered
+ * before passing the audio buffer to the codec - it may not be filled.
+ * The next call to EAS_Render will continue processing until the buffer
+ * has been filled.
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, hwInstData) available for customer use */
+EAS_BOOL EAS_HWYield (EAS_HW_DATA_HANDLE hwInstData)
+{
+ /* put your code here */
+ return EAS_FALSE;
+}
+
+
diff --git a/arm-wt-22k/jetcreator_lib_src/darwin-x86/eas_host_debug.h b/arm-wt-22k/jetcreator_lib_src/darwin-x86/eas_host_debug.h
index 8a01922..fb40923 100755..100644
--- a/arm-wt-22k/jetcreator_lib_src/darwin-x86/eas_host_debug.h
+++ b/arm-wt-22k/jetcreator_lib_src/darwin-x86/eas_host_debug.h
@@ -1,47 +1,47 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_host_debug.h
- *
- * Contents and purpose:
- * This header defines the host wrapper functions for simulating
- * error conditions.
- *
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
-*/
-
-// sentinel
-#ifndef _EAS_HOST_DEBUG_H
-#define _EAS_HOST_DEBUG_H
-
-#include "eas_types.h"
-
-typedef enum
-{
- eInitError,
- eShutdownError,
- eMallocError,
- eOpenError,
- eReadError,
- ePosError,
- eSeekError,
- eLengthError,
- eDupError,
- eCloseError,
- eNumErrorConditions,
-} E_ERROR_CONDITIONS;
-
-#endif
-
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_host_debug.h
+ *
+ * Contents and purpose:
+ * This header defines the host wrapper functions for simulating
+ * error conditions.
+ *
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+*/
+
+// sentinel
+#ifndef _EAS_HOST_DEBUG_H
+#define _EAS_HOST_DEBUG_H
+
+#include "eas_types.h"
+
+typedef enum
+{
+ eInitError,
+ eShutdownError,
+ eMallocError,
+ eOpenError,
+ eReadError,
+ ePosError,
+ eSeekError,
+ eLengthError,
+ eDupError,
+ eCloseError,
+ eNumErrorConditions,
+} E_ERROR_CONDITIONS;
+
+#endif
+
diff --git a/arm-wt-22k/jetcreator_lib_src/darwin-x86/eastestv37.c b/arm-wt-22k/jetcreator_lib_src/darwin-x86/eastestv37.c
index e4e9c48..f325c04 100755..100644
--- a/arm-wt-22k/jetcreator_lib_src/darwin-x86/eastestv37.c
+++ b/arm-wt-22k/jetcreator_lib_src/darwin-x86/eastestv37.c
@@ -1,999 +1,999 @@
-/*----------------------------------------------------------------------------
- *
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
-*/
-
-#include "eas_sndlib.h"
-
-/*----------------------------------------------------------------------------
- * Articulations
- *----------------------------------------------------------------------------
-*/
-const S_ARTICULATION testArticulations[] =
-{
- { /* articulation 0 */
- { 32767, 0, 32767, 0 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 951, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 1 */
- { 32767, 0, 32767, 0 },
- { 32767, 32767, 32767, 0 },
- 100, 0, 19, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 2 */
- { 32767, 0, 32767, 0 },
- { 32767, 32767, 32767, 0 },
- 100, 34, 951, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 3 */
- { 32767, 0, 32767, 0 },
- { 32767, 32767, 32767, 0 },
- 100, 86, 951, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 4 */
- { 32767, 0, 32767, 0 },
- { 32767, 32767, 32767, 0 },
- 100, 172, 951, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 5 */
- { 32767, 0, 32767, 0 },
- { 32767, 32767, 32767, 0 },
- 100, 345, 951, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 6 */
- { 32767, 0, 32767, 0 },
- { 32767, 32767, 32767, 0 },
- 100, 517, 951, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 7 */
- { 32767, 0, 32767, 0 },
- { 32767, 32767, 32767, 0 },
- 100, 689, 951, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 8 */
- { 32767, 0, 32767, 0 },
- { 32767, 32767, 32767, 0 },
- 100, 861, 951, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 9 */
- { 32767, 0, 32767, 0 },
- { 32767, 32767, 32767, 0 },
- 100, 1723, 951, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 10 */
- { 32767, 0, 32767, 0 },
- { 32767, 32767, 32767, 0 },
- 100, 0, 191, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 11 */
- { 32767, 0, 32767, 0 },
- { 32767, 32767, 32767, 0 },
- 100, 0, 382, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 12 */
- { 32767, 0, 32767, 0 },
- { 32767, 32767, 32767, 0 },
- 100, 0, 951, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 13 */
- { 32767, 0, 32767, 0 },
- { 32767, 32767, 32767, 0 },
- 100, 0, 1903, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 14 */
- { 32767, 0, 32767, 0 },
- { 32767, 32767, 32767, 0 },
- 100, 0, 3804, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 15 */
- { 1902, 0, 32767, 0 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 951, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 16 */
- { 380, 0, 32767, 0 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 951, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 17 */
- { 190, 0, 32767, 0 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 951, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 18 */
- { 38, 0, 32767, 0 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 951, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 19 */
- { 19, 0, 32767, 0 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 951, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 20 */
- { 10, 0, 32767, 0 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 951, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 21 */
- { 5, 0, 32767, 0 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 951, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 22 */
- { 32767, 17213, 0, 0 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 951, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 23 */
- { 32767, 28809, 0, 0 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 951, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 24 */
- { 32767, 30725, 0, 0 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 951, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 25 */
- { 32767, 32349, 0, 0 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 951, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 26 */
- { 32767, 32558, 0, 0 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 951, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 27 */
- { 32767, 32663, 0, 0 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 951, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 28 */
- { 32767, 32715, 0, 0 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 951, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 29 */
- { 32767, 30725, 32767, 0 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 951, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 30 */
- { 32767, 30725, 3566, 0 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 951, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 31 */
- { 32767, 30725, 42, 0 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 951, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 32 */
- { 32767, 30725, 5, 0 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 951, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 33 */
- { 32767, 30725, 2, 0 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 951, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 34 */
- { 32767, 0, 32767, 17213 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 951, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 35 */
- { 32767, 0, 32767, 28809 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 951, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 36 */
- { 32767, 0, 32767, 30725 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 951, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 37 */
- { 32767, 0, 32767, 32349 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 951, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 38 */
- { 32767, 0, 32767, 32558 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 951, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 39 */
- { 32767, 0, 32767, 32663 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 951, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 40 */
- { 32767, 0, 32767, 32715 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 951, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 41 */
- { 32767, 0, 32767, 0 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 190, 0, 0, 0, 1, 0, 0
- },
- { /* articulation 42 */
- { 32767, 0, 32767, 0 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 189, 0, 0, 0, 3, 0, 0
- },
- { /* articulation 43 */
- { 32767, 0, 32767, 0 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 190, 0, 0, 0, 4, 0, 0
- },
- { /* articulation 44 */
- { 32767, 0, 32767, 0 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 190, 0, 0, 0, 6, 0, 0
- },
- { /* articulation 45 */
- { 32767, 0, 32767, 0 },
- { 32767, 32767, 32767, 0 },
- -1200, 0, 190, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 46 */
- { 32767, 0, 32767, 0 },
- { 32767, 32767, 32767, 0 },
- -600, 0, 190, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 47 */
- { 32767, 0, 32767, 0 },
- { 32767, 32767, 32767, 0 },
- -100, 0, 190, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 48 */
- { 32767, 0, 32767, 0 },
- { 32767, 32767, 32767, 0 },
- -50, 0, 190, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 49 */
- { 32767, 0, 32767, 0 },
- { 32767, 32767, 32767, 0 },
- 50, 0, 190, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 50 */
- { 32767, 0, 32767, 0 },
- { 32767, 32767, 32767, 0 },
- 100, 0, 190, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 51 */
- { 32767, 0, 32767, 0 },
- { 32767, 32767, 32767, 0 },
- 600, 0, 190, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 52 */
- { 32767, 0, 32767, 0 },
- { 32767, 32767, 32767, 0 },
- 1200, 0, 190, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 53 */
- { 32767, 0, 32767, 0 },
- { 190, 190, 0, 0 },
- 0, 0, 951, -1200, 0, 0, 0, 0, 0
- },
- { /* articulation 54 */
- { 32767, 0, 32767, 0 },
- { 190, 190, 0, 0 },
- 0, 0, 951, -600, 0, 0, 0, 0, 0
- },
- { /* articulation 55 */
- { 32767, 0, 32767, 0 },
- { 190, 190, 0, 0 },
- 0, 0, 951, -100, 0, 0, 0, 0, 0
- },
- { /* articulation 56 */
- { 32767, 0, 32767, 0 },
- { 190, 190, 0, 0 },
- 0, 0, 951, -50, 0, 0, 0, 0, 0
- },
- { /* articulation 57 */
- { 32767, 0, 32767, 0 },
- { 190, 190, 0, 0 },
- 0, 0, 951, 50, 0, 0, 0, 0, 0
- },
- { /* articulation 58 */
- { 32767, 0, 32767, 0 },
- { 190, 190, 0, 0 },
- 0, 0, 951, 100, 0, 0, 0, 0, 0
- },
- { /* articulation 59 */
- { 32767, 0, 32767, 0 },
- { 190, 190, 0, 0 },
- 0, 0, 951, 600, 0, 0, 0, 0, 0
- },
- { /* articulation 60 */
- { 32767, 0, 32767, 0 },
- { 190, 190, 0, 0 },
- 0, 0, 951, 1200, 0, 0, 0, 0, 0
- },
- { /* articulation 61 */
- { 32767, 0, 32767, 0 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 951, 0, 0, 5535, 0, 0, 0
- },
- { /* articulation 62 */
- { 32767, 0, 32767, 0 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 951, 0, 0, 7121, 0, 0, 0
- },
- { /* articulation 63 */
- { 32767, 0, 32767, 0 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 951, 0, 0, 8321, 0, 0, 0
- },
- { /* articulation 64 */
- { 32767, 0, 32767, 0 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 951, 0, 0, 9906, 0, 0, 0
- },
- { /* articulation 65 */
- { 32767, 0, 32767, 0 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 951, 0, 0, 11106, 0, 0, 0
- },
- { /* articulation 66 */
- { 32767, 0, 32767, 0 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 951, 0, 0, 9521, 0, 0, 0
- },
- { /* articulation 67 */
- { 32767, 0, 32767, 0 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 951, 0, 0, 9521, 0, 8, 0
- },
- { /* articulation 68 */
- { 32767, 0, 32767, 0 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 951, 0, 0, 9521, 0, 16, 0
- },
- { /* articulation 69 */
- { 32767, 0, 32767, 0 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 951, 0, 0, 9521, 0, 24, 0
- },
- { /* articulation 70 */
- { 32767, 0, 32767, 0 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 951, 0, 0, 9521, 0, 30, 0
- },
- { /* articulation 71 */
- { 32767, 0, 32767, 0 },
- { 190, 190, 0, 0 },
- 0, 0, 951, 0, -6400, 9521, 0, 0, 0
- },
- { /* articulation 72 */
- { 32767, 0, 32767, 0 },
- { 190, 190, 0, 0 },
- 0, 0, 951, 0, -3200, 9521, 0, 0, 0
- },
- { /* articulation 73 */
- { 32767, 0, 32767, 0 },
- { 190, 190, 0, 0 },
- 0, 0, 951, 0, -1600, 9521, 0, 0, 0
- },
- { /* articulation 74 */
- { 32767, 0, 32767, 0 },
- { 190, 190, 0, 0 },
- 0, 0, 951, 0, -800, 9521, 0, 0, 0
- },
- { /* articulation 75 */
- { 32767, 0, 32767, 0 },
- { 190, 190, 0, 0 },
- 0, 0, 951, 0, 800, 7121, 0, 0, 0
- },
- { /* articulation 76 */
- { 190, 30725, 32767, 0 },
- { 190, 190, 0, 0 },
- 0, 0, 951, 0, 1600, 7121, 0, 0, 0
- },
- { /* articulation 77 */
- { 32767, 0, 32767, 0 },
- { 190, 190, 0, 0 },
- 0, 0, 951, 0, 3200, 7121, 0, 0, 0
- },
- { /* articulation 78 */
- { 32767, 0, 32767, 0 },
- { 190, 190, 0, 0 },
- 0, 0, 951, 0, 6400, 7121, 0, 0, 0
- },
- { /* articulation 79 */
- { 32767, 0, 32767, 0 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 190, 0, 0, 11106, 0, 0, 0
- },
- { /* articulation 80 */
- { 32767, 0, 32767, 0 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 191, 0, 0, 11106, 0, 0, 0
- },
- { /* articulation 81 */
- { 32767, 0, 32767, 0 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 190, 0, 0, 7121, 0, 0, 0
- },
- { /* articulation 82 */
- { 32767, 0, 32767, 0 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 951, 0, 0, 0, 0, 0, -63
- },
- { /* articulation 83 */
- { 32767, 0, 32767, 0 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 951, 0, 0, 0, 0, 0, -50
- },
- { /* articulation 84 */
- { 32767, 0, 32767, 0 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 951, 0, 0, 0, 0, 0, -37
- },
- { /* articulation 85 */
- { 32767, 0, 32767, 0 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 951, 0, 0, 0, 0, 0, -25
- },
- { /* articulation 86 */
- { 32767, 0, 32767, 0 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 951, 0, 0, 0, 0, 0, -12
- },
- { /* articulation 87 */
- { 32767, 0, 32767, 0 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 951, 0, 0, 0, 0, 0, 12
- },
- { /* articulation 88 */
- { 32767, 0, 32767, 0 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 951, 0, 0, 0, 0, 0, 25
- },
- { /* articulation 89 */
- { 32767, 0, 32767, 0 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 951, 0, 0, 0, 0, 0, 37
- },
- { /* articulation 90 */
- { 32767, 0, 32767, 0 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 951, 0, 0, 0, 0, 0, 50
- },
- { /* articulation 91 */
- { 32767, 0, 32767, 0 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 951, 0, 0, 0, 0, 0, 63
- },
- { /* articulation 92 */
- { 32767, 0, 32767, 0 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 951, 0, 0, 9907, 0, 0, 0
- },
- { /* articulation 93 */
- { 32767, 0, 32767, 0 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 951, 0, 0, 10574, 0, 0, 0
- },
- { /* articulation 94 */
- { 32767, 0, 32767, 0 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 951, 0, 0, 11373, 0, 0, 0
- },
- { /* articulation 95 */
- { 32767, 0, 32767, 0 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 951, 0, 0, 11376, 0, 0, 0
- },
- { /* articulation 96 */
- { 32767, 0, 32767, 0 },
- { 32767, 32767, 32767, 0 },
- 100, 0, 949, 0, 0, 0, 0, 0, 0
- }
-}; /*end Articulations */
-
-/*----------------------------------------------------------------------------
- * Regions
- *----------------------------------------------------------------------------
-*/
-const S_WT_REGION testRegions[] =
-{
- { { 32769, 0, 127 }, -6000, 32767, 101, 301, 4, 0 }, /* region 0 */
- { { 1, 0, 60 }, -6000, 32767, 101, 301, 4, 2 }, /* region 1 */
- { { 1, 61, 61 }, -6000, 32767, 101, 301, 4, 3 }, /* region 2 */
- { { 1, 62, 62 }, -6000, 32767, 101, 301, 4, 4 }, /* region 3 */
- { { 1, 63, 63 }, -6000, 32767, 101, 301, 4, 5 }, /* region 4 */
- { { 1, 64, 64 }, -6000, 32767, 101, 301, 4, 6 }, /* region 5 */
- { { 1, 65, 65 }, -6000, 32767, 101, 301, 4, 7 }, /* region 6 */
- { { 1, 66, 66 }, -6000, 32767, 101, 301, 4, 8 }, /* region 7 */
- { { 32769, 67, 127 }, -6000, 32767, 101, 301, 4, 9 }, /* region 8 */
- { { 32769, 0, 127 }, -6005, 32767, 3, 171, 5, 0 }, /* region 9 */
- { { 32768, 0, 127 }, -6555, 32767, 0, 0, 2, 0 }, /* region 10 */
- { { 32770, 0, 127 }, -6000, 32767, 0, 0, 0, 0 }, /* region 11 */
- { { 1, 60, 60 }, -6000, 32767, 101, 301, 4, 0 }, /* region 12 */
- { { 1, 61, 61 }, -6100, 16422, 101, 151, 4, 0 }, /* region 13 */
- { { 1, 62, 62 }, -6200, 8231, 101, 151, 4, 0 }, /* region 14 */
- { { 1, 63, 63 }, -6300, 2067, 101, 151, 4, 0 }, /* region 15 */
- { { 1, 64, 64 }, -6400, 130, 101, 151, 4, 0 }, /* region 16 */
- { { 32769, 65, 65 }, -6500, 1, 101, 151, 4, 0 }, /* region 17 */
- { { 1, 60, 60 }, -6000, 32767, 101, 301, 4, 0 }, /* region 18 */
- { { 1, 61, 61 }, -6200, 32767, 101, 151, 4, 0 }, /* region 19 */
- { { 1, 62, 62 }, -6400, 32767, 101, 151, 4, 0 }, /* region 20 */
- { { 1, 63, 63 }, -6600, 32767, 101, 151, 4, 0 }, /* region 21 */
- { { 1, 64, 64 }, -6800, 32767, 101, 151, 4, 0 }, /* region 22 */
- { { 1, 65, 65 }, -7000, 32767, 101, 151, 4, 0 }, /* region 23 */
- { { 1, 66, 66 }, -7200, 32767, 101, 151, 4, 0 }, /* region 24 */
- { { 1, 67, 67 }, -7400, 32767, 101, 151, 4, 0 }, /* region 25 */
- { { 1, 68, 68 }, -7600, 32767, 101, 151, 4, 0 }, /* region 26 */
- { { 1, 69, 69 }, -7800, 32767, 101, 151, 4, 0 }, /* region 27 */
- { { 1, 70, 70 }, -8000, 32767, 101, 151, 4, 0 }, /* region 28 */
- { { 1, 71, 71 }, -8200, 32767, 101, 151, 4, 0 }, /* region 29 */
- { { 32769, 72, 72 }, -8400, 32767, 101, 151, 4, 0 }, /* region 30 */
- { { 1, 60, 60 }, -6000, 32767, 101, 301, 4, 0 }, /* region 31 */
- { { 1, 61, 61 }, -6099, 32767, 101, 151, 4, 0 }, /* region 32 */
- { { 1, 62, 62 }, -6190, 32767, 101, 151, 4, 0 }, /* region 33 */
- { { 1, 63, 63 }, -6250, 32767, 101, 151, 4, 0 }, /* region 34 */
- { { 1, 64, 64 }, -6300, 32767, 101, 151, 4, 0 }, /* region 35 */
- { { 1, 65, 65 }, -6500, 32767, 101, 151, 4, 0 }, /* region 36 */
- { { 1, 66, 66 }, -6601, 32767, 101, 151, 4, 0 }, /* region 37 */
- { { 1, 67, 67 }, -6710, 32767, 101, 151, 4, 0 }, /* region 38 */
- { { 1, 68, 68 }, -6850, 32767, 101, 151, 4, 0 }, /* region 39 */
- { { 32769, 69, 69 }, -7000, 32767, 101, 151, 4, 0 }, /* region 40 */
- { { 1, 0, 0 }, 0, 32767, 101, 151, 4, 1 }, /* region 41 */
- { { 1, 1, 1 }, -100, 32767, 101, 151, 4, 10 }, /* region 42 */
- { { 1, 2, 2 }, -200, 32767, 101, 151, 4, 11 }, /* region 43 */
- { { 1, 3, 3 }, -300, 32767, 101, 151, 4, 12 }, /* region 44 */
- { { 1, 4, 4 }, -400, 32767, 101, 151, 4, 13 }, /* region 45 */
- { { 1, 5, 5 }, -500, 32767, 101, 151, 4, 14 }, /* region 46 */
- { { 1, 6, 6 }, -600, 32767, 101, 151, 4, 0 }, /* region 47 */
- { { 1, 7, 7 }, -700, 32767, 101, 151, 4, 15 }, /* region 48 */
- { { 1, 8, 8 }, -800, 32767, 101, 151, 4, 16 }, /* region 49 */
- { { 1, 9, 9 }, -900, 32767, 101, 151, 4, 17 }, /* region 50 */
- { { 1, 10, 10 }, -1000, 32767, 101, 151, 4, 18 }, /* region 51 */
- { { 1, 11, 11 }, -1100, 32767, 101, 151, 4, 19 }, /* region 52 */
- { { 1, 12, 12 }, -1200, 32767, 101, 151, 4, 20 }, /* region 53 */
- { { 1, 13, 13 }, -1300, 32767, 101, 151, 4, 21 }, /* region 54 */
- { { 1, 14, 14 }, -1400, 32767, 101, 151, 4, 22 }, /* region 55 */
- { { 1, 15, 15 }, -1500, 32767, 101, 151, 4, 23 }, /* region 56 */
- { { 1, 16, 16 }, -1600, 32767, 101, 151, 4, 24 }, /* region 57 */
- { { 1, 17, 17 }, -1700, 32767, 101, 151, 4, 25 }, /* region 58 */
- { { 1, 18, 18 }, -1800, 32767, 101, 151, 4, 26 }, /* region 59 */
- { { 1, 19, 19 }, -1900, 32767, 101, 151, 4, 27 }, /* region 60 */
- { { 1, 20, 20 }, -2000, 32767, 101, 151, 4, 28 }, /* region 61 */
- { { 1, 21, 21 }, -2100, 32767, 101, 151, 4, 29 }, /* region 62 */
- { { 1, 22, 22 }, -2200, 32767, 101, 151, 4, 30 }, /* region 63 */
- { { 1, 23, 23 }, -2300, 32767, 101, 151, 4, 31 }, /* region 64 */
- { { 1, 24, 24 }, -2400, 32767, 101, 151, 4, 32 }, /* region 65 */
- { { 1, 25, 25 }, -2500, 32767, 101, 151, 4, 33 }, /* region 66 */
- { { 1, 26, 26 }, -2600, 32767, 101, 151, 4, 24 }, /* region 67 */
- { { 1, 27, 27 }, -2700, 32767, 101, 151, 4, 0 }, /* region 68 */
- { { 1, 28, 28 }, -2800, 32767, 101, 151, 4, 34 }, /* region 69 */
- { { 1, 29, 29 }, -2900, 32767, 101, 151, 4, 35 }, /* region 70 */
- { { 1, 30, 30 }, -3000, 32767, 101, 151, 4, 36 }, /* region 71 */
- { { 1, 31, 31 }, -3100, 32767, 101, 151, 4, 37 }, /* region 72 */
- { { 1, 32, 32 }, -3200, 32767, 101, 151, 4, 38 }, /* region 73 */
- { { 1, 33, 33 }, -3300, 32767, 101, 151, 4, 39 }, /* region 74 */
- { { 1, 34, 34 }, -3400, 32767, 101, 151, 4, 40 }, /* region 75 */
- { { 1, 35, 35 }, -3500, 32767, 101, 151, 4, 41 }, /* region 76 */
- { { 1, 36, 36 }, -3600, 32767, 101, 151, 4, 42 }, /* region 77 */
- { { 1, 37, 37 }, -3700, 32767, 101, 151, 4, 43 }, /* region 78 */
- { { 1, 38, 38 }, -3800, 32767, 101, 151, 4, 44 }, /* region 79 */
- { { 1, 39, 39 }, -3900, 32767, 101, 151, 4, 45 }, /* region 80 */
- { { 1, 40, 40 }, -4000, 32767, 101, 151, 4, 46 }, /* region 81 */
- { { 1, 41, 41 }, -4100, 32767, 101, 151, 4, 47 }, /* region 82 */
- { { 1, 42, 42 }, -4200, 32767, 101, 151, 4, 48 }, /* region 83 */
- { { 1, 43, 43 }, -4300, 32767, 101, 151, 4, 49 }, /* region 84 */
- { { 1, 44, 44 }, -4400, 32767, 101, 151, 4, 50 }, /* region 85 */
- { { 1, 45, 45 }, -4500, 32767, 101, 151, 4, 51 }, /* region 86 */
- { { 1, 46, 46 }, -4600, 32767, 101, 151, 4, 52 }, /* region 87 */
- { { 1, 47, 47 }, -4700, 32767, 101, 151, 4, 53 }, /* region 88 */
- { { 1, 48, 48 }, -4800, 32767, 101, 151, 4, 54 }, /* region 89 */
- { { 1, 49, 49 }, -4900, 32767, 101, 151, 4, 55 }, /* region 90 */
- { { 1, 50, 50 }, -5000, 32767, 101, 151, 4, 56 }, /* region 91 */
- { { 1, 51, 51 }, -5100, 32767, 101, 151, 4, 57 }, /* region 92 */
- { { 1, 52, 52 }, -5200, 32767, 101, 151, 4, 58 }, /* region 93 */
- { { 1, 53, 53 }, -5300, 32767, 101, 151, 4, 59 }, /* region 94 */
- { { 1, 54, 54 }, -5400, 32767, 101, 151, 4, 60 }, /* region 95 */
- { { 2, 55, 55 }, -5500, 32767, 0, 0, 0, 61 }, /* region 96 */
- { { 2, 56, 56 }, -5600, 32767, 0, 0, 0, 62 }, /* region 97 */
- { { 2, 57, 57 }, -5700, 32767, 0, 0, 0, 63 }, /* region 98 */
- { { 2, 58, 58 }, -5800, 32767, 0, 0, 0, 64 }, /* region 99 */
- { { 2, 59, 59 }, -5900, 32767, 0, 0, 0, 65 }, /* region 100 */
- { { 2, 60, 60 }, -6000, 32767, 0, 0, 0, 0 }, /* region 101 */
- { { 2, 61, 61 }, -6100, 32767, 0, 0, 0, 66 }, /* region 102 */
- { { 2, 62, 62 }, -6200, 32767, 0, 0, 0, 67 }, /* region 103 */
- { { 2, 63, 63 }, -6300, 32767, 0, 0, 0, 68 }, /* region 104 */
- { { 2, 64, 64 }, -6400, 32767, 0, 0, 0, 69 }, /* region 105 */
- { { 2, 65, 65 }, -6500, 32767, 0, 0, 0, 70 }, /* region 106 */
- { { 2, 66, 66 }, -6600, 32767, 0, 0, 0, 71 }, /* region 107 */
- { { 2, 67, 67 }, -6700, 32767, 0, 0, 0, 72 }, /* region 108 */
- { { 2, 68, 68 }, -6800, 32767, 0, 0, 0, 73 }, /* region 109 */
- { { 2, 69, 69 }, -6900, 32767, 0, 0, 0, 74 }, /* region 110 */
- { { 2, 70, 70 }, -7000, 32767, 0, 0, 0, 75 }, /* region 111 */
- { { 2, 71, 71 }, -7100, 32767, 0, 0, 0, 76 }, /* region 112 */
- { { 2, 72, 72 }, -7200, 32767, 0, 0, 0, 77 }, /* region 113 */
- { { 2, 73, 73 }, -7300, 32767, 0, 0, 0, 78 }, /* region 114 */
- { { 2, 74, 74 }, -7400, 32767, 0, 0, 0, 79 }, /* region 115 */
- { { 2, 75, 75 }, -7500, 32767, 0, 0, 0, 79 }, /* region 116 */
- { { 2, 76, 76 }, -7600, 32767, 0, 0, 0, 79 }, /* region 117 */
- { { 2, 77, 77 }, -7700, 32767, 0, 0, 0, 80 }, /* region 118 */
- { { 2, 78, 78 }, -7800, 32767, 0, 0, 0, 81 }, /* region 119 */
- { { 2, 79, 79 }, -7900, 32767, 0, 0, 0, 81 }, /* region 120 */
- { { 2, 80, 80 }, -8000, 32767, 0, 0, 0, 81 }, /* region 121 */
- { { 2, 81, 81 }, -8100, 32767, 0, 0, 0, 81 }, /* region 122 */
- { { 2, 82, 82 }, -8200, 32767, 0, 0, 0, 0 }, /* region 123 */
- { { 257, 83, 83 }, -8300, 32767, 101, 151, 4, 0 }, /* region 124 */
- { { 257, 84, 84 }, -8405, 32767, 0, 171, 5, 0 }, /* region 125 */
- { { 0, 85, 85 }, -9055, 32767, 0, 0, 2, 82 }, /* region 126 */
- { { 0, 86, 86 }, -9155, 32767, 0, 0, 2, 83 }, /* region 127 */
- { { 0, 87, 87 }, -9255, 32767, 0, 0, 2, 84 }, /* region 128 */
- { { 0, 88, 88 }, -9355, 32767, 0, 0, 2, 85 }, /* region 129 */
- { { 0, 89, 89 }, -9455, 32767, 0, 0, 2, 86 }, /* region 130 */
- { { 0, 90, 90 }, -9555, 32767, 0, 0, 2, 0 }, /* region 131 */
- { { 0, 91, 91 }, -9655, 32767, 0, 0, 2, 87 }, /* region 132 */
- { { 0, 92, 92 }, -9755, 32767, 0, 0, 2, 88 }, /* region 133 */
- { { 0, 93, 93 }, -9855, 32767, 0, 0, 2, 89 }, /* region 134 */
- { { 0, 94, 94 }, -9955, 32767, 0, 0, 2, 90 }, /* region 135 */
- { { 0, 95, 95 }, -10055, 32767, 0, 0, 2, 91 }, /* region 136 */
- { { 2, 96, 96 }, -9600, 32767, 0, 0, 0, 63 }, /* region 137 */
- { { 2, 97, 97 }, -9700, 32767, 0, 0, 0, 92 }, /* region 138 */
- { { 2, 98, 98 }, -9800, 32767, 0, 0, 0, 93 }, /* region 139 */
- { { 2, 99, 99 }, -9900, 32767, 0, 0, 0, 94 }, /* region 140 */
- { { 2, 100, 100 }, -10000, 32767, 0, 0, 0, 95 }, /* region 141 */
- { { 32770, 101, 101 }, -10100, 32767, 0, 0, 0, 0 }, /* region 142 */
- { { 1, 36, 60 }, -6000, 32767, 1481, 1565, 0, 0 }, /* region 143 */
- { { 1, 61, 61 }, -7300, 32767, 740, 782, 1, 0 }, /* region 144 */
- { { 32769, 62, 62 }, -8599, 32767, 370, 391, 3, 0 }, /* region 145 */
- { { 32769, 60, 60 }, -6000, 32767, 101, 301, 4, 1 }, /* region 146 */
- { { 32769, 60, 60 }, -6000, 32767, 101, 301, 4, 50 }, /* region 147 */
- { { 32769, 60, 60 }, -6000, 32767, 101, 301, 4, 11 }, /* region 148 */
- { { 32769, 60, 60 }, -6000, 32767, 101, 301, 4, 96 }, /* region 149 */
- { { 32769, 60, 60 }, -6000, 32767, 101, 301, 4, 13 }, /* region 150 */
- { { 32769, 60, 60 }, -6000, 32767, 101, 301, 4, 14 } /* region 151 */
-}; /* end Regions */
-
-/*----------------------------------------------------------------------------
- * Programs
- *----------------------------------------------------------------------------
-*/
-const S_PROGRAM testPrograms[] =
-{
- { 0, 41 } /* program 0 */,
- { 1, 10 } /* program 1 */,
- { 2, 11 } /* program 2 */,
- { 3, 12 } /* program 3 */,
- { 4, 18 } /* program 4 */,
- { 5, 31 } /* program 5 */,
- { 6, 143 } /* program 6 */,
- { 7, 146 } /* program 7 */,
- { 8, 147 } /* program 8 */,
- { 9, 148 } /* program 9 */,
- { 10, 149 } /* program 10 */,
- { 11, 150 } /* program 11 */,
- { 12, 151 } /* program 12 */,
- { 13, 0 } /* program 13 */,
- { 14, 9 } /* program 14 */,
- { 15, 1 } /* program 15 */
-}; /* end Programs */
-
-/*----------------------------------------------------------------------------
- * Banks
- *----------------------------------------------------------------------------
-*/
-#define testBanks NULL
-
-/*----------------------------------------------------------------------------
- * Samples
- *----------------------------------------------------------------------------
-*/
-
-const EAS_SAMPLE testSamples[] =
-{
- -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 9, 10, 11, 12,
- 13, 13, 14, 13, 13, 13, 12, 12, 10, 9, 8, 6, 5, 3, 2, 0,
- -1, -3, -5, -8, -10, -12, -14, -15, -16, -17, -17, -17, -17, -16, -14, -13,
- -11, -10, -8, -6, -5, -4, -4, -3, -3, -2, -1, -1, -1, -1, -1, -1,
- -1, -2, -3, -3, -3, -3, -3, -2, -2, -2, -1, -1, -1, -1, 0, 0,
- 0, 0, 0, 0, 0, 1, 2, 4, 6, 9, 11, 12, 13, 15, 16, 17,
- 19, 20, 22, 23, 25, 28, 32, 34, 36, 36, 35, 31, 25, 18, 11, 3,
- -5, -13, -20, -26, -31, -34, -35, -36, -36, -35, -34, -32, -29, -26, -23, -19,
- -16, -12, -8, -5, -4, -4, -4, -6, -8, -9, -11, -11, -12, -13, -13, -13,
- -12, -11, -10, -9, -7, -5, -4, -3, -2, -1, -1, 0, 0, 2, 4, 5,
- 7, 7, 7, 7, 6, 6, 6, 6, 6, 6, 7, 9, 12, 14, 17, 20,
- 24, 27, 30, 33, 36, 39, 41, 43, 46, 49, 51, 51, 50, 48, 43, 35,
- 25, 14, 1, -12, -25, -37, -48, -56, -61, -63, -62, -60, -57, -53, -48, -42,
- -35, -29, -23, -17, -12, -8, -5, -3, -3, -4, -5, -7, -9, -11, -12, -14,
- -14, -14, -14, -13, -11, -9, -7, -5, -3, -1, 0, 1, 1, 1, 2, 3,
- 4, 5, 6, 6, 7, 8, 9, 10, 11, 11, 11, 11, 10, 9, 9, 10,
- 12, 14, 17, 20, 23, 26, 30, 34, 38, 40, 43, 46, 49, 52, 55, 57,
- 58, 56, 50, 42, 30, 16, 1, -15, -29, -43, -54, -63, -68, -69, -68, -65,
- -60, -55, -49, -42, -35, -29, -22, -16, -10, -6, -2, -1, 0, -1, -3, -6,
- -9, -12, -16, -18, -20, -21, -21, -21, -19, -17, -14, -11, -8, -5, -2, 1,
- 3, 5, 7, 9, 11, 12, 12, 12, 11, 10, 9, 8, 7, 7, 7, 7,
- 8, 9, 10, 12, 15, 17, 19, 22, 24, 26, 28, 30, 32, 34, 36, 38,
- 42, 44, 47, 49, 53, 56, 55, 52, 45, 35, 22, 8, -8, -23, -37, -50,
- -60, -67, -71, -71, -69, -63, -56, -48, -40, -33, -27, -21, -16, -12, -8, -6,
- -5, -5, -6, -8, -11, -14, -17, -19, -21, -22, -22, -22, -20, -18, -16, -13,
- -9, -6, -2, 1, 5, 7, 8, 9, 10, 11, 11, 11, 10, 10, 9, 9,
- 9, 8, 8, 9, 9, 10, 10, 12, 13, 14, 16, 18, 19, 21, 24, 26,
- 29, 32, 35, 39, 42, 46, 49, 51, 53, 56, 59, 59, 55, 48, 37, 22,
- 5, -12, -29, -45, -58, -68, -74, -77, -77, -75, -69, -62, -53, -44, -35, -28,
- -21, -15, -11, -8, -5, -4, -4, -4, -6, -8, -10, -13, -15, -17, -19, -19,
- -19, -18, -16, -13, -10, -8, -4, -1, 1, 4, 5, 7, 8, 10, 11, 12,
- 13, 14, 14, 13, 12, 12, 11, 9, 8, 7, 6, 6, 7, 8, 10, 12,
- 15, 18, 21, 25, 29, 34, 39, 45, 51, 57, 61, 67, 73, 77, 82, 84,
- 81, 70, 52, 29, 3, -24, -49, -72, -90, -103, -110, -112, -109, -102, -91, -78,
- -64, -49, -35, -23, -13, -5, 1, 5, 8, 9, 9, 7, 4, 0, -4, -9,
- -12, -15, -18, -18, -18, -17, -14, -12, -9, -6, -3, 0, 3, 6, 8, 10,
- 11, 12, 11, 11, 10, 8, 7, 5, 4, 2, 2, 1, 2, 3, 4, 6,
- 8, 11, 13, 15, 18, 21, 26, 31, 36, 42, 48, 53, 60, 66, 72, 77,
- 82, 87, 91, 91, 86, 73, 54, 28, -2, -32, -61, -86, -105, -119, -126, -126,
- -121, -111, -98, -82, -65, -48, -33, -19, -7, 1, 8, 12, 14, 14, 12, 10,
- 6, 1, -4, -9, -14, -18, -20, -21, -22, -21, -19, -17, -14, -11, -8, -4,
- 0, 3, 7, 10, 12, 13, 14, 14, 13, 12, 11, 10, 9, 8, 7, 5,
- 4, 3, 2, 2, 4, 6, 9, 12, 16, 20, 26, 31, 36, 42, 48, 53,
- 58, 64, 69, 74, 79, 82, 84, 83, 80, 72, 59, 39, 14, -14, -43, -70,
- -92, -109, -119, -123, -120, -113, -102, -88, -73, -56, -40, -25, -12, -2, 5, 10,
- 12, 12, 11, 9, 5, 1, -3, -8, -12, -15, -18, -20, -21, -21, -20, -18,
- -16, -13, -9, -6, -2, 1, 5, 8, 11, 13, 15, 16, 16, 16, 15, 14,
- 12, 10, 7, 5, 4, 3, 3, 5, 6, 8, 9, 12, 15, 19, 23, 27,
- 31, 35, 38, 42, 46, 50, 54, 59, 65, 71, 75, 77, 78, 76, 68, 54,
- 34, 10, -16, -43, -68, -88, -103, -112, -114, -112, -105, -94, -80, -65, -50, -35,
- -22, -10, -2, 5, 9, 11, 10, 9, 6, 2, -3, -7, -12, -15, -18, -20,
- -21, -22, -21, -20, -17, -14, -11, -7, -3, 0, 4, 7, 9, 11, 13, 15,
- 17, 17, 17, 16, 14, 12, 11, 10, 8, 7, 5, 5, 5, 6, 7, 8,
- 10, 11, 14, 17, 20, 24, 28, 32, 37, 43, 49, 57, 63, 70, 77, 82,
- 83, 80, 73, 60, 42, 18, -8, -34, -59, -80, -95, -105, -110, -109, -103, -94,
- -81, -67, -53, -38, -24, -13, -3, 4, 9, 11, 11, 9, 6, 3, -2, -6,
- -10, -14, -17, -19, -20, -20, -20, -19, -17, -15, -12, -8, -5, -1, 2, 6,
- 9, 11, 13, 15, 15, 16, 16, 15, 14, 12, 11, 9, 8, 6, 6, 5,
- 5, 5, 6, 7, 8, 10, 12, 15, 19, 23, 28, 32, 38, 44, 50, 58,
- 66, 74, 82, 87, 90, 89, 83, 69, 48, 21, -9, -41, -69, -93, -111, -121,
- -124, -121, -113, -100, -85, -68, -50, -33, -18, -5, 5, 12, 16, 17, 16, 13,
- 9, 4, -1, -6, -11, -15, -18, -20, -21, -21, -21, -19, -17, -15, -12, -8,
- -4, -1, 3, 6, 9, 12, 14, 15, 15, 14, 13, 12, 11, 10, 9, 9,
- 8, 8, 6, 6, 5, 5, 6, 7, 8, 11, 15, 18, 23, 27, 31, 36,
- 41, 46, 51, 58, 66, 74, 82, 88, 91, 90, 83, 68, 46, 16, -16, -48,
- -77, -101, -118, -127, -128, -124, -114, -101, -84, -66, -47, -30, -14, -1, 9, 16,
- 19, 20, 19, 15, 11, 5, -1, -6, -11, -16, -19, -21, -23, -23, -23, -21,
- -19, -16, -12, -8, -4, 0, 4, 8, 11, 13, 14, 15, 15, 14, 13, 12,
- 11, 10, 9, 8, 7, 7, 7, 7, 7, 8, 8, 9, 11, 12, 14, 16,
- 19, 23, 27, 31, 35, 40, 45, 51, 58, 66, 74, 82, 88, 90, 88, 77,
- 58, 32, 1, -31, -62, -87, -107, -119, -125, -123, -117, -105, -90, -73, -56, -38,
- -22, -8, 2, 10, 15, 17, 17, 15, 11, 7, 2, -4, -9, -14, -17, -20,
- -22, -23, -22, -21, -19, -17, -14, -10, -6, -2, 2, 5, 9, 12, 14, 15,
- 17, 18, 18, 18, 17, 15, 12, 10, 8, 6, 4, 4, 4, 5, 6, 7,
- 8, 10, 13, 16, 19, 22, 25, 28, 32, 35, 40, 45, 52, 59, 67, 75,
- 81, 85, 86, 80, 66, 45, 18, -12, -42, -69, -91, -107, -116, -119, -115, -107,
- -95, -80, -64, -47, -31, -17, -5, 4, 10, 13, 14, 14, 11, 7, 3, -2,
- -7, -12, -15, -18, -20, -21, -21, -20, -18, -16, -14, -11, -7, -4, 0, 4,
- 7, 10, 12, 14, 16, 16, 16, 16, 16, 15, 14, 12, 10, 9, 7, 6,
- 5, 4, 4, 5, 6, 7, 8, 10, 12, 15, 19, 23, 27, 31, 36, 41,
- 47, 55, 64, 73, 81, 87, 90, 86, 75, 56, 30, 1, -30, -58, -82, -100,
- -112, -117, -115, -109, -98, -84, -69, -52, -37, -22, -10, 0, 8, 12, 14, 14,
- 13, 10, 6, 2, -3, -8, -12, -16, -18, -20, -20, -20, -19, -17, -15, -12,
- -9, -5, -1, 2, 6, 9, 12, 14, 16, 17, 17, 17, 16, 14, 13, 11,
- 8, 6, 4, 3, 2, 2, 2, 3, 5, 6, 8, 10, 12, 15, 18, 22,
- 26, 30, 35, 40, 47, 55, 63, 71, 80, 87, 90, 88, 78, 59, 34, 4,
- -27, -57, -82, -101, -113, -118, -117, -110, -99, -85, -69, -53, -37, -22, -9, 2,
- 9, 14, 17, 17, 15, 12, 8, 3, -2, -7, -12, -16, -19, -20, -21, -21,
- -19, -18, -15, -12, -9, -6, -2, 2, 6, 9, 12, 14, 16, 17, 17, 16,
- 14, 12, 10, 8, 6, 5, 4, 3, 3, 2, 3, 4, 6, 7, 9, 11,
- 13, 16, 19, 22, 26, 30, 34, 39, 46, 53, 61, 70, 80, 88, 93, 91,
- 80, 61, 34, 3, -30, -59, -84, -102, -114, -119, -117, -110, -99, -84, -68, -51,
- -35, -20, -7, 3, 11, 15, 17, 18, 16, 13, 9, 4, -2, -7, -11, -15,
- -18, -20, -21, -21, -20, -19, -16, -14, -11, -8, -4, 0, 3, 7, 10, 13,
- 15, 16, 17, 16, 14, 12, 10, 9, 7, 6, 5, 4, 4, 4, 5, 6,
- 7, 8, 9, 11, 13, 15, 18, 21, 24, 27, 31, 35, 41, 48, 55, 64,
- 73, 82, 89, 91, 85, 71, 48, 19, -13, -44, -71, -93, -108, -117, -118, -114,
- -105, -92, -77, -60, -43, -27, -13, -1, 8, 14, 17, 18, 17, 14, 8, 13,
- -1, -1, 0, 2, 4, 6, 9, 11, 13, 14, 13, 12, 11, 8, 5, 2,
- -1, -5, -10, -14, -16, -17, -16, -14, -11, -8, -5, -4, -3, -1, -1, -1,
- -1, -3, -3, -3, -2, -1, -1, 0, 0, 0, 0, 2, 6, 11, 14, 16,
- 19, 22, 25, 32, 36, 34, 25, 11, -5, -20, -31, -35, -36, -34, -29, -23,
- -16, -8, -4, -4, -8, -11, -12, -13, -12, -10, -7, -4, -2, -1, 1, 4,
- 7, 7, 6, 6, 6, 7, 12, 17, 24, 30, 36, 41, 46, 51, 50, 43,
- 25, 2, -25, -48, -61, -62, -57, -48, -35, -23, -12, -5, -3, -5, -9, -12,
- -14, -14, -12, -7, -3, 0, 1, 2, 4, 6, 7, 9, 11, 11, 10, 9,
- 12, 17, 23, 30, 37, 43, 49, 55, 58, 50, 30, 1, -29, -54, -68, -68,
- -60, -49, -35, -22, -10, -2, 0, -3, -9, -16, -20, -21, -19, -14, -8, -2,
- 3, 7, 11, 12, 11, 9, 7, 7, 8, 10, 15, 19, 24, 28, 33, 36,
- 42, 47, 53, 56, 45, 23, -8, -37, -60, -71, -69, -56, -40, -27, -16, -8,
- -5, -6, -11, -17, -21, -22, -20, -16, -9, -2, 5, 8, 10, 11, 10, 9,
- 8, 8, 9, 10, 13, 16, 19, 24, 29, 35, 42, 49, 53, 59, 55, 37,
- 5, -29, -58, -74, -77, -69, -53, -35, -21, -11, -5, -4, -6, -10, -15, -19,
- -19, -16, -10, -5, 1, 5, 8, 11, 13, 14, 12, 10, 8, 6, 7, 10,
- 15, 21, 29, 39, 51, 62, 72, 82, 81, 52, 3, -50, -90, -110, -109, -91,
- -64, -35, -13, 1, 8, 9, 4, -4, -12, -18, -18, -14, -9, -3, 3, 8,
- 11, 11, 10, 7, 4, 2, 2, 4, 8, 13, 18, 26, 36, 48, 60, 72,
- 82, 91, 86, 54, -2, -61, -105, -126, -121, -98, -65, -33, -7, 8, 14, 12,
- 6, -4, -14, -20, -22, -19, -14, -8, 0, 7, 12, 14, 13, 11, 9, 7,
- 4, 2, 4, 9, 16, 26, 36, 48, 58, 69, 79, 84, 80, 59, 14, -43,
- -92, -119, -120, -102, -73, -40, -12, 5, 12, 11, 5, -3, -12, -18, -21, -20,
- -16, -9, -2, 5, 11, 15, 16, 15, 12, 7, 4, 4, 6, 9, 15, 23,
- 31, 38, 46, 54, 65, 75, 78, 68, 34, -16, -68, -103, -114, -105, -80, -50,
- -22, -1, 9, 10, 6, -3, -12, -18, -21, -21, -17, -11, -3, 4, 9, 13,
- 16, 17, 14, 11, 8, 5, 5, 7, 10, 14, 20, 28, 37, 49, 64, 77,
- 83, 73, 42, -8, -59, -95, -110, -103, -81, -53, -24, -3, 9, 11, 6, -2,
- -10, -17, -20, -20, -17, -12, -5, 2, 9, 13, 15, 16, 14, 11, 8, 6,
- 5, 6, 8, 12, 19, 28, 38, 50, 66, 82, 90, 83, 48, -9, -69, -111,
- -124, -113, -85, -50, -18, 5, 16, 16, 9, -1, -11, -18, -21, -21, -17, -12,
- -5, 3, 9, 14, 15, 13, 11, 9, 8, 6, 5, 6, 8, 15, 23, 31,
- 41, 52, 66, 82, 91, 83, 46, -16, -77, -118, -128, -114, -84, -47, -14, 9,
- 19, 19, 10, -1, -11, -19, -23, -23, -19, -12, -4, 4, 11, 14, 15, 13,
- 11, 9, 7, 7, 7, 8, 11, 14, 19, 27, 35, 45, 58, 74, 88, 88,
- 58, 1, -62, -107, -125, -116, -90, -56, -22, 2, 15, 17, 11, 2, -9, -17,
- -22, -22, -20, -14, -6, 2, 9, 14, 17, 18, 17, 12, 8, 4, 4, 6,
- 8, 13, 19, 25, 32, 40, 52, 67, 81, 86, 66, 18, -42, -91, -116, -115,
- -95, -64, -31, -5, 10, 14, 11, 3, -7, -15, -20, -21, -18, -14, -7, 0,
- 7, 12, 16, 17, 16, 14, 10, 7, 5, 4, 6, 8, 12, 19, 27, 36,
- 47, 64, 81, 90, 75, 30, -30, -82, -112, -115, -98, -69, -37, -10, 8, 14,
- 13, 6, -3, -12, -18, -20, -19, -15, -9, -1, 6, 12, 16, 17, 16, 13,
- 8, 4, 2, 2, 5, 8, 12, 18, 26, 35, 47, 63, 80, 90, 78, 34,
- -27, -82, -113, -117, -99, -69, -37, -9, 9, 17, 15, 8, -2, -12, -19, -21,
- -19, -15, -9, -2, 6, 12, 16, 17, 14, 10, 6, 4, 3, 3, 6, 9,
- 13, 19, 26, 34, 46, 61, 80, 93, 80, 34, -30, -84, -114, -117, -99, -68,
- -35, -7, 11, 17, 16, 9, -2, -11, -18, -21, -20, -16, -11, -4, 3, 10,
- 15, 17, 14, 10, 7, 5, 4, 5, 7, 9, 13, 18, 24, 31, 41, 55,
- 73, 89, 85, 48, -12, -71, -108, -118, -104, -77, -43, -13, 8, 16, 17, 16,
- 0, -3, -4, -5, -4, 0, -4, -8, -20, -25, 51, 11, -55, 9, 39, 55,
- -76, -19, 92, -23, -58, 2, -15, 57, 71, 34, -41, 20, 51, 22, 63, -21,
- 63, 74, 32, 36, 99, -14, 27, 102, 66, 90, 79, 77, 58, 66, 65, 114,
- 69, 26, 30, 92, 90, 53, 78, 97, 77, 66, 39, -4, 60, 57, 64, 68,
- -16, 36, 49, 12, 19, 12, -12, 21, 11, -32, -19, -41, -44, -12, -36, -44,
- -45, -51, -55, -70, -69, -73, -85, -102, -86, -99, -92, -105, -108, -103, -100, -107,
- -112, -104, -113, -112, -104, -119, -124, -115, -87, -100, -128, -106, -83, -105, -108, -109,
- -91, -95, -90, -83, -80, -79, -83, -68, -59, -53, -63, -69, -57, -28, -11, -38,
- -43, -23, -10, -6, 3, 1, 6, 14, 21, 23, 34, 40, 42, 48, 57, 61,
- 63, 65, 73, 82, 90, 82, 89, 98, 100, 110, 111, 109, 115, 120, 121, 121,
- 123, 123, 123, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 121, 121,
- 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 120, 120, 120, 120, 120, 120,
- 120, 120, 120, 120, 113, 104, 103, 113, 110, 94, 80, 88, 96, 89, 81, 70,
- 68, 64, 59, 59, 54, 44, 44, 39, 31, 31, 21, 18, 16, 8, 6, 2,
- -3, -6, -13, -19, -27, -31, -34, -30, -38, -47, -48, -51, -56, -64, -68, -67,
- -68, -76, -73, -79, -85, -94, -89, -90, -94, -92, -99, -100, -107, -107, -104, -107,
- -106, -112, -114, -113, -112, -111, -112, -116, -116, -115, -115, -115, -115, -115, -115, -115,
- -114, -114, -114, -114, -114, -114, -114, -114, -113, -113, -113, -113, -113, -108, -106, -107,
- -111, -110, -105, -108, -107, -102, -100, -103, -103, -100, -100, -97, -97, -100, -99, -97,
- -94, -90, -94, -94, -93, -93, -92, -92, -90, -89, -89, -90, -91, -87, -87, -88,
- -89, -88, -84, -85, -88, -87, -86, -85, -85, -84, -82, -83, -83, -82, -81, -80,
- -79, -79, -79, -78, -75, -74, -75, -73, -74, -71, -69, -67, -69, -66, -64, -66,
- -65, -64, -62, -58, -57, -57, -57, -56, -52, -51, -50, -48, -46, -43, -43, -42,
- -39, -36, -35, -34, -32, -31, -29, -26, -23, -23, -21, -15, -18, -15, -11, -8,
- -6, -7, 0, 2, 0, 2, 7, 15, 14, 15, 16, 19, 23, 27, 29, 30,
- 31, 34, 41, 41, 42, 44, 45, 51, 55, 54, 56, 57, 60, 65, 67, 69,
- 69, 71, 74, 77, 79, 78, 80, 82, 86, 86, 84, 86, 88, 87, 87, 87,
- 87, 87, 86, 86, 86, 86, 86, 85, 85, 85, 85, 85, 84, 84, 84, 84,
- 84, 83, 83, 83, 83, 83, 83, 82, 82, 82, 82, 82, 81, 81, 81, 81,
- 81, 80, 80, 80, 80, 80, 79, 79, 79, 79, 79, 78, 78, 78, 78, 76,
- 75, 72, 69, 67, 65, 64, 63, 59, 55, 54, 52, 50, 48, 45, 42, 38,
- 36, 34, 31, 30, 27, 24, 21, 18, 16, 14, 12, 9, 7, 4, 1, -2,
- -4, -7, -10, -11, -13, -16, -17, -18, -21, -24, -26, -27, -28, -30, -32, -33,
- -35, -36, -38, -39, -41, -42, -43, -45, -45, -46, -47, -48, -49, -50, -51, -50,
- -51, -52, -53, -53, -53, -53, -53, -53, -53, -54, -54, -54, -54, -53, -53, -52,
- -52, -52, -51, -51, -51, -50, -50, -50, -48, -49, -48, -47, -46, -45, -45, -44,
- -43, -42, -41, -41, -40, -39, -38, -37, -36, -35, -34, -33, -31, -30, -29, -28,
- -27, -26, -24, -24, -23, -22, -21, -20, -19, -18, -17, -16, -15, -14, -13, -13,
- -12, -11, -11, -10, -9, -9, -8, -8, -7, -6, -7, -6, -5, -5, -5, -4,
- -4, -3, -3, -3, -3, -3, -2, -2, -2, -2, -2, -2, -2, -2, 0, 0,
- 0, 0, -1, 0, 4, 9, 13, 13, 11, 5, -1, -10, -16, -17, -11, -5,
- -2, -1, -2, -3, -2, -1, 0, 0, 6, 14, 19, 26, 36, 25, -5, -30,
- -36, -29, -16, -4, -7, -13, -12, -7, -2, 1, 6, 7, 6, 11, 24, 36,
- 46, 50, 26, -25, -60, -57, -36, -12, -3, -9, -14, -12, -3, 1, 4, 7,
- 11, 10, 12, 23, 37, 49, 58, 31, -29, -67, -61, -36, -10, 0, -9, -20,
- -19, -8, 3, 11, 11, 7, 8, 15, 24, 32, 41, 53, 45, -7, -60, -68,
- -41, -16, -5, -11, -21, -20, -10, 4, 10, 10, 8, 9, 13, 19, 29, 42,
- 54, 55, 6, -57, -77, -54, -21, -6, -6, -15, -19, -11, 1, 8, 13, 12,
- 8, 7, 15, 29, 50, 73, 80, 5, -90, -109, -65, -13, 8, 4, -13, -18,
- -10, 3, 11, 10, 4, 2, 8, 18, 36, 60, 82, 86, 1, -105, -121, -66,
- -8, 13, 6, -14, -22, -15, -1, 12, 13, 9, 4, 3, 16, 36, 58, 78,
- 81, 15, -91, -121, -74, -13, 12, 5, -11, -21, -16, -2, 11, 16, 12, 4,
- 6, 15, 31, 46, 64, 79, 36, -66, -115, -81, -23, 9, 6, -11, -21, -17,
- -4, 9, 16, 15, 8, 5, 9, 20, 37, 63, 83, 43, -57, -110, -83, -25,
- 8, 7, -10, -20, -17, -5, 9, 15, 14, 8, 5, 8, 18, 37, 65, 91,
- 50, -67, -124, -86, -19, 16, 9, -10, -21, -18, -5, 9, 15, 11, 8, 5,
- 8, 22, 40, 65, 92, 48, -74, -128, -85, -16, 19, 11, -11, -23, -19, -4,
- 10, 15, 11, 8, 7, 11, 19, 35, 57, 88, 60, -58, -125, -92, -24, 15,
- 12, -8, -22, -20, -7, 9, 17, 17, 8, 4, 8, 18, 31, 51, 81, 67,
- -38, -116, -96, -33, 9, 11, -6, -20, -19, -8, 7, 16, 16, 11, 5, 5,
- 12, 26, 47, 80, 76, -26, -111, -99, -39, 7, 13, -3, -18, -19, -9, 5,
- 16, 16, 8, 2, 4, 12, 25, 46, 79, 79, -23, -112, -101, -39, 9, 15,
- -2, -18, -20, -9, 5, 16, 14, 7, 3, 5, 13, 25, 44, 79, 81, -25,
- -113, -100, -37, 10, 16, -1, -18, -20, -11, 3, 15, 15, 7, 4, 6, 13,
- 23, 40, 72, 86, -7, -107, -106, -46, 7, 16, 0, 16, 31, 47, 61, 75,
- 87, 98, 107, 115, 121, 125, 127, 127, 125, 121, 116, 108, 99, 88, 75, 62,
- 47, 32, 16, 0, -16, -31, -47, -61, -75, -87, -98, -108, -116, -122, -126, -128,
- -128, -126, -123, -117, -109, -100, -89, -77, -64, -49, -34, -18, -2, 14, 29, 45,
- 59, 73, 86, 97, 106, 114, 121, 125, 127, 127, 126, 122, 116, 109, 100, 89,
- 77, 63, 49, 34, 18, 2, -14, -30, -45, -60, -73, -86, -97, -107, -115, -121,
- -126, -128, -128, -127, -123, -118, -110, -101, -91, -79, -65, -51, -36, -20, -4, 12,
- 28, 43, 58, 72, 84, 96, 106, 114, 120, 124, 127, 127, 126, 122, 117, 109,
- 100, 90, 78, 64, 50, 35, 19, 3, -13, -29, -44, -59, -73, -85, -97, -107,
- -115, -121, -125, -128, -128, -127, -123, -118, -110, -101, -91, -79, -65, -51, -36, -20,
- -4, 12, 28, 43, 58, 72, 84, 96, 106, 114, 120, 124, 127, 127, 126, 122,
- 117, 109, 100, 90, 78, 64, 50, 35, 19, 3, -13, -29, -44, -59, -73, -85,
- -97, -107, -115, -121, -125, -128, -128, -127, -123, -118, -110, -101, -91, -79, -65, -51,
- -36, -20, -4, 12, 28, 43, 58, 72, 84, 96, 106, 114, 120, 124, 127, 127,
- 126, 122, 117, 109, 100, 90, 78, 64, 50, 35, 19, 3, -13, -29, -44, -59,
- -73, -85, -97, -107, -115, -121, -125, -128, -128, -127, -123, -118, -110, -101, -91, -79,
- -65, -51, -36, -20, -4, 12, 28, 43, 58, 72, 84, 96, 106, 114, 120, 124,
- 127, 127, 126, 122, 117, 109, 100, 90, 78, 64, 50, 35, 19, 3, -13, -29,
- -44, -59, -73, -85, -97, -107, -115, -121, -125, -128, -128, -127, -123, -118, -110, -101,
- -91, -79, -65, -51, -36, -20, -4, 12, 0, -104, -55, -11, 24, 33, 30, 7,
- -15, -31, -30, -25, -23, -20, -9, 10, 31, 59, 91, 111, 115, 92, 51, 7,
- -33, -64, -81, -81, -71, -51, -22, 16, 52, 74, 82, 81, 68, 38, 0, -40,
- -81, -112, -124, -102, -57, -11, 24, 33, 30, 7, -15, -31, -30, -25, -23, -20,
- -9, 10, 31, 59, 91, 111, 115, 92, 51, 7, -33, -64, -81, -81, -71, -51,
- -22, 16, 52, 74, 82, 81, 68, 38, 0, -40, -81, -112, -124, -102, -57, -11,
- 24, 33, 30, 7, -15, -31, -30, -25, -23, -20, -9, 10, 31, 59, 91, 111,
- 115, 92, 51, 7, -33, -64, -81, -81, -71, -51, -22, 16, 52, 74, 82, 81,
- 68, 38, 0, -40, -81, -112, -124, -102, -57, -11, 24, 33, 30, 7, -15, -31,
- -30, -25, -23, -20, -9, 10, 31, 59, 91, 111, 115, 92, 51, 7, -33, -64,
- -81, -81, -71, -51, -22, 16, 52, 74, 82, 81, 68, 38, 0, -40, -81, -112,
- -124, -102, -57, -11, 0
-};
-
-const EAS_U32 testSampleLengths[] =
-{
- 1568, 784, 642, 392, 302, 172
-};
-
-const EAS_U32 testSampleOffsets[] =
-{
- 0x00000000, 0x00000620, 0x00000930, 0x00000bb2, 0x00000d3a, 0x00000e68
-};
-
-/*----------------------------------------------------------------------------
- * S_EAS
- *----------------------------------------------------------------------------
-*/
-const S_EAS easTestLib =
-{
- 0x01534145,
- 0x00105622,
- testBanks,
- testPrograms,
- testRegions,
- testArticulations,
- testSampleLengths,
- testSampleOffsets,
- testSamples,
- 0,
- 0,
- 16,
- 152,
- 97,
- 6,
- 0
-}; /* end S_EAS */
-
-/*----------------------------------------------------------------------------
- * Statistics
- *
- * Number of banks: 0
- * Number of programs: 16
- * Number of regions: 152
- * Number of articulations: 97
- * Number of samples: 6
- * Size of sample pool: 3861
- *----------------------------------------------------------------------------
-*/
-/* end ..\..\EASLib\WTLibrary\eastestv37.c */
+/*----------------------------------------------------------------------------
+ *
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+*/
+
+#include "eas_sndlib.h"
+
+/*----------------------------------------------------------------------------
+ * Articulations
+ *----------------------------------------------------------------------------
+*/
+const S_ARTICULATION testArticulations[] =
+{
+ { /* articulation 0 */
+ { 32767, 0, 32767, 0 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 951, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 1 */
+ { 32767, 0, 32767, 0 },
+ { 32767, 32767, 32767, 0 },
+ 100, 0, 19, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 2 */
+ { 32767, 0, 32767, 0 },
+ { 32767, 32767, 32767, 0 },
+ 100, 34, 951, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 3 */
+ { 32767, 0, 32767, 0 },
+ { 32767, 32767, 32767, 0 },
+ 100, 86, 951, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 4 */
+ { 32767, 0, 32767, 0 },
+ { 32767, 32767, 32767, 0 },
+ 100, 172, 951, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 5 */
+ { 32767, 0, 32767, 0 },
+ { 32767, 32767, 32767, 0 },
+ 100, 345, 951, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 6 */
+ { 32767, 0, 32767, 0 },
+ { 32767, 32767, 32767, 0 },
+ 100, 517, 951, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 7 */
+ { 32767, 0, 32767, 0 },
+ { 32767, 32767, 32767, 0 },
+ 100, 689, 951, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 8 */
+ { 32767, 0, 32767, 0 },
+ { 32767, 32767, 32767, 0 },
+ 100, 861, 951, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 9 */
+ { 32767, 0, 32767, 0 },
+ { 32767, 32767, 32767, 0 },
+ 100, 1723, 951, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 10 */
+ { 32767, 0, 32767, 0 },
+ { 32767, 32767, 32767, 0 },
+ 100, 0, 191, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 11 */
+ { 32767, 0, 32767, 0 },
+ { 32767, 32767, 32767, 0 },
+ 100, 0, 382, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 12 */
+ { 32767, 0, 32767, 0 },
+ { 32767, 32767, 32767, 0 },
+ 100, 0, 951, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 13 */
+ { 32767, 0, 32767, 0 },
+ { 32767, 32767, 32767, 0 },
+ 100, 0, 1903, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 14 */
+ { 32767, 0, 32767, 0 },
+ { 32767, 32767, 32767, 0 },
+ 100, 0, 3804, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 15 */
+ { 1902, 0, 32767, 0 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 951, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 16 */
+ { 380, 0, 32767, 0 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 951, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 17 */
+ { 190, 0, 32767, 0 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 951, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 18 */
+ { 38, 0, 32767, 0 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 951, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 19 */
+ { 19, 0, 32767, 0 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 951, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 20 */
+ { 10, 0, 32767, 0 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 951, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 21 */
+ { 5, 0, 32767, 0 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 951, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 22 */
+ { 32767, 17213, 0, 0 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 951, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 23 */
+ { 32767, 28809, 0, 0 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 951, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 24 */
+ { 32767, 30725, 0, 0 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 951, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 25 */
+ { 32767, 32349, 0, 0 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 951, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 26 */
+ { 32767, 32558, 0, 0 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 951, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 27 */
+ { 32767, 32663, 0, 0 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 951, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 28 */
+ { 32767, 32715, 0, 0 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 951, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 29 */
+ { 32767, 30725, 32767, 0 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 951, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 30 */
+ { 32767, 30725, 3566, 0 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 951, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 31 */
+ { 32767, 30725, 42, 0 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 951, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 32 */
+ { 32767, 30725, 5, 0 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 951, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 33 */
+ { 32767, 30725, 2, 0 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 951, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 34 */
+ { 32767, 0, 32767, 17213 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 951, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 35 */
+ { 32767, 0, 32767, 28809 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 951, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 36 */
+ { 32767, 0, 32767, 30725 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 951, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 37 */
+ { 32767, 0, 32767, 32349 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 951, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 38 */
+ { 32767, 0, 32767, 32558 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 951, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 39 */
+ { 32767, 0, 32767, 32663 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 951, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 40 */
+ { 32767, 0, 32767, 32715 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 951, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 41 */
+ { 32767, 0, 32767, 0 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 190, 0, 0, 0, 1, 0, 0
+ },
+ { /* articulation 42 */
+ { 32767, 0, 32767, 0 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 189, 0, 0, 0, 3, 0, 0
+ },
+ { /* articulation 43 */
+ { 32767, 0, 32767, 0 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 190, 0, 0, 0, 4, 0, 0
+ },
+ { /* articulation 44 */
+ { 32767, 0, 32767, 0 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 190, 0, 0, 0, 6, 0, 0
+ },
+ { /* articulation 45 */
+ { 32767, 0, 32767, 0 },
+ { 32767, 32767, 32767, 0 },
+ -1200, 0, 190, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 46 */
+ { 32767, 0, 32767, 0 },
+ { 32767, 32767, 32767, 0 },
+ -600, 0, 190, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 47 */
+ { 32767, 0, 32767, 0 },
+ { 32767, 32767, 32767, 0 },
+ -100, 0, 190, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 48 */
+ { 32767, 0, 32767, 0 },
+ { 32767, 32767, 32767, 0 },
+ -50, 0, 190, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 49 */
+ { 32767, 0, 32767, 0 },
+ { 32767, 32767, 32767, 0 },
+ 50, 0, 190, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 50 */
+ { 32767, 0, 32767, 0 },
+ { 32767, 32767, 32767, 0 },
+ 100, 0, 190, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 51 */
+ { 32767, 0, 32767, 0 },
+ { 32767, 32767, 32767, 0 },
+ 600, 0, 190, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 52 */
+ { 32767, 0, 32767, 0 },
+ { 32767, 32767, 32767, 0 },
+ 1200, 0, 190, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 53 */
+ { 32767, 0, 32767, 0 },
+ { 190, 190, 0, 0 },
+ 0, 0, 951, -1200, 0, 0, 0, 0, 0
+ },
+ { /* articulation 54 */
+ { 32767, 0, 32767, 0 },
+ { 190, 190, 0, 0 },
+ 0, 0, 951, -600, 0, 0, 0, 0, 0
+ },
+ { /* articulation 55 */
+ { 32767, 0, 32767, 0 },
+ { 190, 190, 0, 0 },
+ 0, 0, 951, -100, 0, 0, 0, 0, 0
+ },
+ { /* articulation 56 */
+ { 32767, 0, 32767, 0 },
+ { 190, 190, 0, 0 },
+ 0, 0, 951, -50, 0, 0, 0, 0, 0
+ },
+ { /* articulation 57 */
+ { 32767, 0, 32767, 0 },
+ { 190, 190, 0, 0 },
+ 0, 0, 951, 50, 0, 0, 0, 0, 0
+ },
+ { /* articulation 58 */
+ { 32767, 0, 32767, 0 },
+ { 190, 190, 0, 0 },
+ 0, 0, 951, 100, 0, 0, 0, 0, 0
+ },
+ { /* articulation 59 */
+ { 32767, 0, 32767, 0 },
+ { 190, 190, 0, 0 },
+ 0, 0, 951, 600, 0, 0, 0, 0, 0
+ },
+ { /* articulation 60 */
+ { 32767, 0, 32767, 0 },
+ { 190, 190, 0, 0 },
+ 0, 0, 951, 1200, 0, 0, 0, 0, 0
+ },
+ { /* articulation 61 */
+ { 32767, 0, 32767, 0 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 951, 0, 0, 5535, 0, 0, 0
+ },
+ { /* articulation 62 */
+ { 32767, 0, 32767, 0 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 951, 0, 0, 7121, 0, 0, 0
+ },
+ { /* articulation 63 */
+ { 32767, 0, 32767, 0 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 951, 0, 0, 8321, 0, 0, 0
+ },
+ { /* articulation 64 */
+ { 32767, 0, 32767, 0 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 951, 0, 0, 9906, 0, 0, 0
+ },
+ { /* articulation 65 */
+ { 32767, 0, 32767, 0 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 951, 0, 0, 11106, 0, 0, 0
+ },
+ { /* articulation 66 */
+ { 32767, 0, 32767, 0 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 951, 0, 0, 9521, 0, 0, 0
+ },
+ { /* articulation 67 */
+ { 32767, 0, 32767, 0 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 951, 0, 0, 9521, 0, 8, 0
+ },
+ { /* articulation 68 */
+ { 32767, 0, 32767, 0 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 951, 0, 0, 9521, 0, 16, 0
+ },
+ { /* articulation 69 */
+ { 32767, 0, 32767, 0 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 951, 0, 0, 9521, 0, 24, 0
+ },
+ { /* articulation 70 */
+ { 32767, 0, 32767, 0 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 951, 0, 0, 9521, 0, 30, 0
+ },
+ { /* articulation 71 */
+ { 32767, 0, 32767, 0 },
+ { 190, 190, 0, 0 },
+ 0, 0, 951, 0, -6400, 9521, 0, 0, 0
+ },
+ { /* articulation 72 */
+ { 32767, 0, 32767, 0 },
+ { 190, 190, 0, 0 },
+ 0, 0, 951, 0, -3200, 9521, 0, 0, 0
+ },
+ { /* articulation 73 */
+ { 32767, 0, 32767, 0 },
+ { 190, 190, 0, 0 },
+ 0, 0, 951, 0, -1600, 9521, 0, 0, 0
+ },
+ { /* articulation 74 */
+ { 32767, 0, 32767, 0 },
+ { 190, 190, 0, 0 },
+ 0, 0, 951, 0, -800, 9521, 0, 0, 0
+ },
+ { /* articulation 75 */
+ { 32767, 0, 32767, 0 },
+ { 190, 190, 0, 0 },
+ 0, 0, 951, 0, 800, 7121, 0, 0, 0
+ },
+ { /* articulation 76 */
+ { 190, 30725, 32767, 0 },
+ { 190, 190, 0, 0 },
+ 0, 0, 951, 0, 1600, 7121, 0, 0, 0
+ },
+ { /* articulation 77 */
+ { 32767, 0, 32767, 0 },
+ { 190, 190, 0, 0 },
+ 0, 0, 951, 0, 3200, 7121, 0, 0, 0
+ },
+ { /* articulation 78 */
+ { 32767, 0, 32767, 0 },
+ { 190, 190, 0, 0 },
+ 0, 0, 951, 0, 6400, 7121, 0, 0, 0
+ },
+ { /* articulation 79 */
+ { 32767, 0, 32767, 0 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 190, 0, 0, 11106, 0, 0, 0
+ },
+ { /* articulation 80 */
+ { 32767, 0, 32767, 0 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 191, 0, 0, 11106, 0, 0, 0
+ },
+ { /* articulation 81 */
+ { 32767, 0, 32767, 0 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 190, 0, 0, 7121, 0, 0, 0
+ },
+ { /* articulation 82 */
+ { 32767, 0, 32767, 0 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 951, 0, 0, 0, 0, 0, -63
+ },
+ { /* articulation 83 */
+ { 32767, 0, 32767, 0 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 951, 0, 0, 0, 0, 0, -50
+ },
+ { /* articulation 84 */
+ { 32767, 0, 32767, 0 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 951, 0, 0, 0, 0, 0, -37
+ },
+ { /* articulation 85 */
+ { 32767, 0, 32767, 0 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 951, 0, 0, 0, 0, 0, -25
+ },
+ { /* articulation 86 */
+ { 32767, 0, 32767, 0 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 951, 0, 0, 0, 0, 0, -12
+ },
+ { /* articulation 87 */
+ { 32767, 0, 32767, 0 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 951, 0, 0, 0, 0, 0, 12
+ },
+ { /* articulation 88 */
+ { 32767, 0, 32767, 0 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 951, 0, 0, 0, 0, 0, 25
+ },
+ { /* articulation 89 */
+ { 32767, 0, 32767, 0 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 951, 0, 0, 0, 0, 0, 37
+ },
+ { /* articulation 90 */
+ { 32767, 0, 32767, 0 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 951, 0, 0, 0, 0, 0, 50
+ },
+ { /* articulation 91 */
+ { 32767, 0, 32767, 0 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 951, 0, 0, 0, 0, 0, 63
+ },
+ { /* articulation 92 */
+ { 32767, 0, 32767, 0 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 951, 0, 0, 9907, 0, 0, 0
+ },
+ { /* articulation 93 */
+ { 32767, 0, 32767, 0 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 951, 0, 0, 10574, 0, 0, 0
+ },
+ { /* articulation 94 */
+ { 32767, 0, 32767, 0 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 951, 0, 0, 11373, 0, 0, 0
+ },
+ { /* articulation 95 */
+ { 32767, 0, 32767, 0 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 951, 0, 0, 11376, 0, 0, 0
+ },
+ { /* articulation 96 */
+ { 32767, 0, 32767, 0 },
+ { 32767, 32767, 32767, 0 },
+ 100, 0, 949, 0, 0, 0, 0, 0, 0
+ }
+}; /*end Articulations */
+
+/*----------------------------------------------------------------------------
+ * Regions
+ *----------------------------------------------------------------------------
+*/
+const S_WT_REGION testRegions[] =
+{
+ { { 32769, 0, 127 }, -6000, 32767, 101, 301, 4, 0 }, /* region 0 */
+ { { 1, 0, 60 }, -6000, 32767, 101, 301, 4, 2 }, /* region 1 */
+ { { 1, 61, 61 }, -6000, 32767, 101, 301, 4, 3 }, /* region 2 */
+ { { 1, 62, 62 }, -6000, 32767, 101, 301, 4, 4 }, /* region 3 */
+ { { 1, 63, 63 }, -6000, 32767, 101, 301, 4, 5 }, /* region 4 */
+ { { 1, 64, 64 }, -6000, 32767, 101, 301, 4, 6 }, /* region 5 */
+ { { 1, 65, 65 }, -6000, 32767, 101, 301, 4, 7 }, /* region 6 */
+ { { 1, 66, 66 }, -6000, 32767, 101, 301, 4, 8 }, /* region 7 */
+ { { 32769, 67, 127 }, -6000, 32767, 101, 301, 4, 9 }, /* region 8 */
+ { { 32769, 0, 127 }, -6005, 32767, 3, 171, 5, 0 }, /* region 9 */
+ { { 32768, 0, 127 }, -6555, 32767, 0, 0, 2, 0 }, /* region 10 */
+ { { 32770, 0, 127 }, -6000, 32767, 0, 0, 0, 0 }, /* region 11 */
+ { { 1, 60, 60 }, -6000, 32767, 101, 301, 4, 0 }, /* region 12 */
+ { { 1, 61, 61 }, -6100, 16422, 101, 151, 4, 0 }, /* region 13 */
+ { { 1, 62, 62 }, -6200, 8231, 101, 151, 4, 0 }, /* region 14 */
+ { { 1, 63, 63 }, -6300, 2067, 101, 151, 4, 0 }, /* region 15 */
+ { { 1, 64, 64 }, -6400, 130, 101, 151, 4, 0 }, /* region 16 */
+ { { 32769, 65, 65 }, -6500, 1, 101, 151, 4, 0 }, /* region 17 */
+ { { 1, 60, 60 }, -6000, 32767, 101, 301, 4, 0 }, /* region 18 */
+ { { 1, 61, 61 }, -6200, 32767, 101, 151, 4, 0 }, /* region 19 */
+ { { 1, 62, 62 }, -6400, 32767, 101, 151, 4, 0 }, /* region 20 */
+ { { 1, 63, 63 }, -6600, 32767, 101, 151, 4, 0 }, /* region 21 */
+ { { 1, 64, 64 }, -6800, 32767, 101, 151, 4, 0 }, /* region 22 */
+ { { 1, 65, 65 }, -7000, 32767, 101, 151, 4, 0 }, /* region 23 */
+ { { 1, 66, 66 }, -7200, 32767, 101, 151, 4, 0 }, /* region 24 */
+ { { 1, 67, 67 }, -7400, 32767, 101, 151, 4, 0 }, /* region 25 */
+ { { 1, 68, 68 }, -7600, 32767, 101, 151, 4, 0 }, /* region 26 */
+ { { 1, 69, 69 }, -7800, 32767, 101, 151, 4, 0 }, /* region 27 */
+ { { 1, 70, 70 }, -8000, 32767, 101, 151, 4, 0 }, /* region 28 */
+ { { 1, 71, 71 }, -8200, 32767, 101, 151, 4, 0 }, /* region 29 */
+ { { 32769, 72, 72 }, -8400, 32767, 101, 151, 4, 0 }, /* region 30 */
+ { { 1, 60, 60 }, -6000, 32767, 101, 301, 4, 0 }, /* region 31 */
+ { { 1, 61, 61 }, -6099, 32767, 101, 151, 4, 0 }, /* region 32 */
+ { { 1, 62, 62 }, -6190, 32767, 101, 151, 4, 0 }, /* region 33 */
+ { { 1, 63, 63 }, -6250, 32767, 101, 151, 4, 0 }, /* region 34 */
+ { { 1, 64, 64 }, -6300, 32767, 101, 151, 4, 0 }, /* region 35 */
+ { { 1, 65, 65 }, -6500, 32767, 101, 151, 4, 0 }, /* region 36 */
+ { { 1, 66, 66 }, -6601, 32767, 101, 151, 4, 0 }, /* region 37 */
+ { { 1, 67, 67 }, -6710, 32767, 101, 151, 4, 0 }, /* region 38 */
+ { { 1, 68, 68 }, -6850, 32767, 101, 151, 4, 0 }, /* region 39 */
+ { { 32769, 69, 69 }, -7000, 32767, 101, 151, 4, 0 }, /* region 40 */
+ { { 1, 0, 0 }, 0, 32767, 101, 151, 4, 1 }, /* region 41 */
+ { { 1, 1, 1 }, -100, 32767, 101, 151, 4, 10 }, /* region 42 */
+ { { 1, 2, 2 }, -200, 32767, 101, 151, 4, 11 }, /* region 43 */
+ { { 1, 3, 3 }, -300, 32767, 101, 151, 4, 12 }, /* region 44 */
+ { { 1, 4, 4 }, -400, 32767, 101, 151, 4, 13 }, /* region 45 */
+ { { 1, 5, 5 }, -500, 32767, 101, 151, 4, 14 }, /* region 46 */
+ { { 1, 6, 6 }, -600, 32767, 101, 151, 4, 0 }, /* region 47 */
+ { { 1, 7, 7 }, -700, 32767, 101, 151, 4, 15 }, /* region 48 */
+ { { 1, 8, 8 }, -800, 32767, 101, 151, 4, 16 }, /* region 49 */
+ { { 1, 9, 9 }, -900, 32767, 101, 151, 4, 17 }, /* region 50 */
+ { { 1, 10, 10 }, -1000, 32767, 101, 151, 4, 18 }, /* region 51 */
+ { { 1, 11, 11 }, -1100, 32767, 101, 151, 4, 19 }, /* region 52 */
+ { { 1, 12, 12 }, -1200, 32767, 101, 151, 4, 20 }, /* region 53 */
+ { { 1, 13, 13 }, -1300, 32767, 101, 151, 4, 21 }, /* region 54 */
+ { { 1, 14, 14 }, -1400, 32767, 101, 151, 4, 22 }, /* region 55 */
+ { { 1, 15, 15 }, -1500, 32767, 101, 151, 4, 23 }, /* region 56 */
+ { { 1, 16, 16 }, -1600, 32767, 101, 151, 4, 24 }, /* region 57 */
+ { { 1, 17, 17 }, -1700, 32767, 101, 151, 4, 25 }, /* region 58 */
+ { { 1, 18, 18 }, -1800, 32767, 101, 151, 4, 26 }, /* region 59 */
+ { { 1, 19, 19 }, -1900, 32767, 101, 151, 4, 27 }, /* region 60 */
+ { { 1, 20, 20 }, -2000, 32767, 101, 151, 4, 28 }, /* region 61 */
+ { { 1, 21, 21 }, -2100, 32767, 101, 151, 4, 29 }, /* region 62 */
+ { { 1, 22, 22 }, -2200, 32767, 101, 151, 4, 30 }, /* region 63 */
+ { { 1, 23, 23 }, -2300, 32767, 101, 151, 4, 31 }, /* region 64 */
+ { { 1, 24, 24 }, -2400, 32767, 101, 151, 4, 32 }, /* region 65 */
+ { { 1, 25, 25 }, -2500, 32767, 101, 151, 4, 33 }, /* region 66 */
+ { { 1, 26, 26 }, -2600, 32767, 101, 151, 4, 24 }, /* region 67 */
+ { { 1, 27, 27 }, -2700, 32767, 101, 151, 4, 0 }, /* region 68 */
+ { { 1, 28, 28 }, -2800, 32767, 101, 151, 4, 34 }, /* region 69 */
+ { { 1, 29, 29 }, -2900, 32767, 101, 151, 4, 35 }, /* region 70 */
+ { { 1, 30, 30 }, -3000, 32767, 101, 151, 4, 36 }, /* region 71 */
+ { { 1, 31, 31 }, -3100, 32767, 101, 151, 4, 37 }, /* region 72 */
+ { { 1, 32, 32 }, -3200, 32767, 101, 151, 4, 38 }, /* region 73 */
+ { { 1, 33, 33 }, -3300, 32767, 101, 151, 4, 39 }, /* region 74 */
+ { { 1, 34, 34 }, -3400, 32767, 101, 151, 4, 40 }, /* region 75 */
+ { { 1, 35, 35 }, -3500, 32767, 101, 151, 4, 41 }, /* region 76 */
+ { { 1, 36, 36 }, -3600, 32767, 101, 151, 4, 42 }, /* region 77 */
+ { { 1, 37, 37 }, -3700, 32767, 101, 151, 4, 43 }, /* region 78 */
+ { { 1, 38, 38 }, -3800, 32767, 101, 151, 4, 44 }, /* region 79 */
+ { { 1, 39, 39 }, -3900, 32767, 101, 151, 4, 45 }, /* region 80 */
+ { { 1, 40, 40 }, -4000, 32767, 101, 151, 4, 46 }, /* region 81 */
+ { { 1, 41, 41 }, -4100, 32767, 101, 151, 4, 47 }, /* region 82 */
+ { { 1, 42, 42 }, -4200, 32767, 101, 151, 4, 48 }, /* region 83 */
+ { { 1, 43, 43 }, -4300, 32767, 101, 151, 4, 49 }, /* region 84 */
+ { { 1, 44, 44 }, -4400, 32767, 101, 151, 4, 50 }, /* region 85 */
+ { { 1, 45, 45 }, -4500, 32767, 101, 151, 4, 51 }, /* region 86 */
+ { { 1, 46, 46 }, -4600, 32767, 101, 151, 4, 52 }, /* region 87 */
+ { { 1, 47, 47 }, -4700, 32767, 101, 151, 4, 53 }, /* region 88 */
+ { { 1, 48, 48 }, -4800, 32767, 101, 151, 4, 54 }, /* region 89 */
+ { { 1, 49, 49 }, -4900, 32767, 101, 151, 4, 55 }, /* region 90 */
+ { { 1, 50, 50 }, -5000, 32767, 101, 151, 4, 56 }, /* region 91 */
+ { { 1, 51, 51 }, -5100, 32767, 101, 151, 4, 57 }, /* region 92 */
+ { { 1, 52, 52 }, -5200, 32767, 101, 151, 4, 58 }, /* region 93 */
+ { { 1, 53, 53 }, -5300, 32767, 101, 151, 4, 59 }, /* region 94 */
+ { { 1, 54, 54 }, -5400, 32767, 101, 151, 4, 60 }, /* region 95 */
+ { { 2, 55, 55 }, -5500, 32767, 0, 0, 0, 61 }, /* region 96 */
+ { { 2, 56, 56 }, -5600, 32767, 0, 0, 0, 62 }, /* region 97 */
+ { { 2, 57, 57 }, -5700, 32767, 0, 0, 0, 63 }, /* region 98 */
+ { { 2, 58, 58 }, -5800, 32767, 0, 0, 0, 64 }, /* region 99 */
+ { { 2, 59, 59 }, -5900, 32767, 0, 0, 0, 65 }, /* region 100 */
+ { { 2, 60, 60 }, -6000, 32767, 0, 0, 0, 0 }, /* region 101 */
+ { { 2, 61, 61 }, -6100, 32767, 0, 0, 0, 66 }, /* region 102 */
+ { { 2, 62, 62 }, -6200, 32767, 0, 0, 0, 67 }, /* region 103 */
+ { { 2, 63, 63 }, -6300, 32767, 0, 0, 0, 68 }, /* region 104 */
+ { { 2, 64, 64 }, -6400, 32767, 0, 0, 0, 69 }, /* region 105 */
+ { { 2, 65, 65 }, -6500, 32767, 0, 0, 0, 70 }, /* region 106 */
+ { { 2, 66, 66 }, -6600, 32767, 0, 0, 0, 71 }, /* region 107 */
+ { { 2, 67, 67 }, -6700, 32767, 0, 0, 0, 72 }, /* region 108 */
+ { { 2, 68, 68 }, -6800, 32767, 0, 0, 0, 73 }, /* region 109 */
+ { { 2, 69, 69 }, -6900, 32767, 0, 0, 0, 74 }, /* region 110 */
+ { { 2, 70, 70 }, -7000, 32767, 0, 0, 0, 75 }, /* region 111 */
+ { { 2, 71, 71 }, -7100, 32767, 0, 0, 0, 76 }, /* region 112 */
+ { { 2, 72, 72 }, -7200, 32767, 0, 0, 0, 77 }, /* region 113 */
+ { { 2, 73, 73 }, -7300, 32767, 0, 0, 0, 78 }, /* region 114 */
+ { { 2, 74, 74 }, -7400, 32767, 0, 0, 0, 79 }, /* region 115 */
+ { { 2, 75, 75 }, -7500, 32767, 0, 0, 0, 79 }, /* region 116 */
+ { { 2, 76, 76 }, -7600, 32767, 0, 0, 0, 79 }, /* region 117 */
+ { { 2, 77, 77 }, -7700, 32767, 0, 0, 0, 80 }, /* region 118 */
+ { { 2, 78, 78 }, -7800, 32767, 0, 0, 0, 81 }, /* region 119 */
+ { { 2, 79, 79 }, -7900, 32767, 0, 0, 0, 81 }, /* region 120 */
+ { { 2, 80, 80 }, -8000, 32767, 0, 0, 0, 81 }, /* region 121 */
+ { { 2, 81, 81 }, -8100, 32767, 0, 0, 0, 81 }, /* region 122 */
+ { { 2, 82, 82 }, -8200, 32767, 0, 0, 0, 0 }, /* region 123 */
+ { { 257, 83, 83 }, -8300, 32767, 101, 151, 4, 0 }, /* region 124 */
+ { { 257, 84, 84 }, -8405, 32767, 0, 171, 5, 0 }, /* region 125 */
+ { { 0, 85, 85 }, -9055, 32767, 0, 0, 2, 82 }, /* region 126 */
+ { { 0, 86, 86 }, -9155, 32767, 0, 0, 2, 83 }, /* region 127 */
+ { { 0, 87, 87 }, -9255, 32767, 0, 0, 2, 84 }, /* region 128 */
+ { { 0, 88, 88 }, -9355, 32767, 0, 0, 2, 85 }, /* region 129 */
+ { { 0, 89, 89 }, -9455, 32767, 0, 0, 2, 86 }, /* region 130 */
+ { { 0, 90, 90 }, -9555, 32767, 0, 0, 2, 0 }, /* region 131 */
+ { { 0, 91, 91 }, -9655, 32767, 0, 0, 2, 87 }, /* region 132 */
+ { { 0, 92, 92 }, -9755, 32767, 0, 0, 2, 88 }, /* region 133 */
+ { { 0, 93, 93 }, -9855, 32767, 0, 0, 2, 89 }, /* region 134 */
+ { { 0, 94, 94 }, -9955, 32767, 0, 0, 2, 90 }, /* region 135 */
+ { { 0, 95, 95 }, -10055, 32767, 0, 0, 2, 91 }, /* region 136 */
+ { { 2, 96, 96 }, -9600, 32767, 0, 0, 0, 63 }, /* region 137 */
+ { { 2, 97, 97 }, -9700, 32767, 0, 0, 0, 92 }, /* region 138 */
+ { { 2, 98, 98 }, -9800, 32767, 0, 0, 0, 93 }, /* region 139 */
+ { { 2, 99, 99 }, -9900, 32767, 0, 0, 0, 94 }, /* region 140 */
+ { { 2, 100, 100 }, -10000, 32767, 0, 0, 0, 95 }, /* region 141 */
+ { { 32770, 101, 101 }, -10100, 32767, 0, 0, 0, 0 }, /* region 142 */
+ { { 1, 36, 60 }, -6000, 32767, 1481, 1565, 0, 0 }, /* region 143 */
+ { { 1, 61, 61 }, -7300, 32767, 740, 782, 1, 0 }, /* region 144 */
+ { { 32769, 62, 62 }, -8599, 32767, 370, 391, 3, 0 }, /* region 145 */
+ { { 32769, 60, 60 }, -6000, 32767, 101, 301, 4, 1 }, /* region 146 */
+ { { 32769, 60, 60 }, -6000, 32767, 101, 301, 4, 50 }, /* region 147 */
+ { { 32769, 60, 60 }, -6000, 32767, 101, 301, 4, 11 }, /* region 148 */
+ { { 32769, 60, 60 }, -6000, 32767, 101, 301, 4, 96 }, /* region 149 */
+ { { 32769, 60, 60 }, -6000, 32767, 101, 301, 4, 13 }, /* region 150 */
+ { { 32769, 60, 60 }, -6000, 32767, 101, 301, 4, 14 } /* region 151 */
+}; /* end Regions */
+
+/*----------------------------------------------------------------------------
+ * Programs
+ *----------------------------------------------------------------------------
+*/
+const S_PROGRAM testPrograms[] =
+{
+ { 0, 41 } /* program 0 */,
+ { 1, 10 } /* program 1 */,
+ { 2, 11 } /* program 2 */,
+ { 3, 12 } /* program 3 */,
+ { 4, 18 } /* program 4 */,
+ { 5, 31 } /* program 5 */,
+ { 6, 143 } /* program 6 */,
+ { 7, 146 } /* program 7 */,
+ { 8, 147 } /* program 8 */,
+ { 9, 148 } /* program 9 */,
+ { 10, 149 } /* program 10 */,
+ { 11, 150 } /* program 11 */,
+ { 12, 151 } /* program 12 */,
+ { 13, 0 } /* program 13 */,
+ { 14, 9 } /* program 14 */,
+ { 15, 1 } /* program 15 */
+}; /* end Programs */
+
+/*----------------------------------------------------------------------------
+ * Banks
+ *----------------------------------------------------------------------------
+*/
+#define testBanks NULL
+
+/*----------------------------------------------------------------------------
+ * Samples
+ *----------------------------------------------------------------------------
+*/
+
+const EAS_SAMPLE testSamples[] =
+{
+ -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 9, 10, 11, 12,
+ 13, 13, 14, 13, 13, 13, 12, 12, 10, 9, 8, 6, 5, 3, 2, 0,
+ -1, -3, -5, -8, -10, -12, -14, -15, -16, -17, -17, -17, -17, -16, -14, -13,
+ -11, -10, -8, -6, -5, -4, -4, -3, -3, -2, -1, -1, -1, -1, -1, -1,
+ -1, -2, -3, -3, -3, -3, -3, -2, -2, -2, -1, -1, -1, -1, 0, 0,
+ 0, 0, 0, 0, 0, 1, 2, 4, 6, 9, 11, 12, 13, 15, 16, 17,
+ 19, 20, 22, 23, 25, 28, 32, 34, 36, 36, 35, 31, 25, 18, 11, 3,
+ -5, -13, -20, -26, -31, -34, -35, -36, -36, -35, -34, -32, -29, -26, -23, -19,
+ -16, -12, -8, -5, -4, -4, -4, -6, -8, -9, -11, -11, -12, -13, -13, -13,
+ -12, -11, -10, -9, -7, -5, -4, -3, -2, -1, -1, 0, 0, 2, 4, 5,
+ 7, 7, 7, 7, 6, 6, 6, 6, 6, 6, 7, 9, 12, 14, 17, 20,
+ 24, 27, 30, 33, 36, 39, 41, 43, 46, 49, 51, 51, 50, 48, 43, 35,
+ 25, 14, 1, -12, -25, -37, -48, -56, -61, -63, -62, -60, -57, -53, -48, -42,
+ -35, -29, -23, -17, -12, -8, -5, -3, -3, -4, -5, -7, -9, -11, -12, -14,
+ -14, -14, -14, -13, -11, -9, -7, -5, -3, -1, 0, 1, 1, 1, 2, 3,
+ 4, 5, 6, 6, 7, 8, 9, 10, 11, 11, 11, 11, 10, 9, 9, 10,
+ 12, 14, 17, 20, 23, 26, 30, 34, 38, 40, 43, 46, 49, 52, 55, 57,
+ 58, 56, 50, 42, 30, 16, 1, -15, -29, -43, -54, -63, -68, -69, -68, -65,
+ -60, -55, -49, -42, -35, -29, -22, -16, -10, -6, -2, -1, 0, -1, -3, -6,
+ -9, -12, -16, -18, -20, -21, -21, -21, -19, -17, -14, -11, -8, -5, -2, 1,
+ 3, 5, 7, 9, 11, 12, 12, 12, 11, 10, 9, 8, 7, 7, 7, 7,
+ 8, 9, 10, 12, 15, 17, 19, 22, 24, 26, 28, 30, 32, 34, 36, 38,
+ 42, 44, 47, 49, 53, 56, 55, 52, 45, 35, 22, 8, -8, -23, -37, -50,
+ -60, -67, -71, -71, -69, -63, -56, -48, -40, -33, -27, -21, -16, -12, -8, -6,
+ -5, -5, -6, -8, -11, -14, -17, -19, -21, -22, -22, -22, -20, -18, -16, -13,
+ -9, -6, -2, 1, 5, 7, 8, 9, 10, 11, 11, 11, 10, 10, 9, 9,
+ 9, 8, 8, 9, 9, 10, 10, 12, 13, 14, 16, 18, 19, 21, 24, 26,
+ 29, 32, 35, 39, 42, 46, 49, 51, 53, 56, 59, 59, 55, 48, 37, 22,
+ 5, -12, -29, -45, -58, -68, -74, -77, -77, -75, -69, -62, -53, -44, -35, -28,
+ -21, -15, -11, -8, -5, -4, -4, -4, -6, -8, -10, -13, -15, -17, -19, -19,
+ -19, -18, -16, -13, -10, -8, -4, -1, 1, 4, 5, 7, 8, 10, 11, 12,
+ 13, 14, 14, 13, 12, 12, 11, 9, 8, 7, 6, 6, 7, 8, 10, 12,
+ 15, 18, 21, 25, 29, 34, 39, 45, 51, 57, 61, 67, 73, 77, 82, 84,
+ 81, 70, 52, 29, 3, -24, -49, -72, -90, -103, -110, -112, -109, -102, -91, -78,
+ -64, -49, -35, -23, -13, -5, 1, 5, 8, 9, 9, 7, 4, 0, -4, -9,
+ -12, -15, -18, -18, -18, -17, -14, -12, -9, -6, -3, 0, 3, 6, 8, 10,
+ 11, 12, 11, 11, 10, 8, 7, 5, 4, 2, 2, 1, 2, 3, 4, 6,
+ 8, 11, 13, 15, 18, 21, 26, 31, 36, 42, 48, 53, 60, 66, 72, 77,
+ 82, 87, 91, 91, 86, 73, 54, 28, -2, -32, -61, -86, -105, -119, -126, -126,
+ -121, -111, -98, -82, -65, -48, -33, -19, -7, 1, 8, 12, 14, 14, 12, 10,
+ 6, 1, -4, -9, -14, -18, -20, -21, -22, -21, -19, -17, -14, -11, -8, -4,
+ 0, 3, 7, 10, 12, 13, 14, 14, 13, 12, 11, 10, 9, 8, 7, 5,
+ 4, 3, 2, 2, 4, 6, 9, 12, 16, 20, 26, 31, 36, 42, 48, 53,
+ 58, 64, 69, 74, 79, 82, 84, 83, 80, 72, 59, 39, 14, -14, -43, -70,
+ -92, -109, -119, -123, -120, -113, -102, -88, -73, -56, -40, -25, -12, -2, 5, 10,
+ 12, 12, 11, 9, 5, 1, -3, -8, -12, -15, -18, -20, -21, -21, -20, -18,
+ -16, -13, -9, -6, -2, 1, 5, 8, 11, 13, 15, 16, 16, 16, 15, 14,
+ 12, 10, 7, 5, 4, 3, 3, 5, 6, 8, 9, 12, 15, 19, 23, 27,
+ 31, 35, 38, 42, 46, 50, 54, 59, 65, 71, 75, 77, 78, 76, 68, 54,
+ 34, 10, -16, -43, -68, -88, -103, -112, -114, -112, -105, -94, -80, -65, -50, -35,
+ -22, -10, -2, 5, 9, 11, 10, 9, 6, 2, -3, -7, -12, -15, -18, -20,
+ -21, -22, -21, -20, -17, -14, -11, -7, -3, 0, 4, 7, 9, 11, 13, 15,
+ 17, 17, 17, 16, 14, 12, 11, 10, 8, 7, 5, 5, 5, 6, 7, 8,
+ 10, 11, 14, 17, 20, 24, 28, 32, 37, 43, 49, 57, 63, 70, 77, 82,
+ 83, 80, 73, 60, 42, 18, -8, -34, -59, -80, -95, -105, -110, -109, -103, -94,
+ -81, -67, -53, -38, -24, -13, -3, 4, 9, 11, 11, 9, 6, 3, -2, -6,
+ -10, -14, -17, -19, -20, -20, -20, -19, -17, -15, -12, -8, -5, -1, 2, 6,
+ 9, 11, 13, 15, 15, 16, 16, 15, 14, 12, 11, 9, 8, 6, 6, 5,
+ 5, 5, 6, 7, 8, 10, 12, 15, 19, 23, 28, 32, 38, 44, 50, 58,
+ 66, 74, 82, 87, 90, 89, 83, 69, 48, 21, -9, -41, -69, -93, -111, -121,
+ -124, -121, -113, -100, -85, -68, -50, -33, -18, -5, 5, 12, 16, 17, 16, 13,
+ 9, 4, -1, -6, -11, -15, -18, -20, -21, -21, -21, -19, -17, -15, -12, -8,
+ -4, -1, 3, 6, 9, 12, 14, 15, 15, 14, 13, 12, 11, 10, 9, 9,
+ 8, 8, 6, 6, 5, 5, 6, 7, 8, 11, 15, 18, 23, 27, 31, 36,
+ 41, 46, 51, 58, 66, 74, 82, 88, 91, 90, 83, 68, 46, 16, -16, -48,
+ -77, -101, -118, -127, -128, -124, -114, -101, -84, -66, -47, -30, -14, -1, 9, 16,
+ 19, 20, 19, 15, 11, 5, -1, -6, -11, -16, -19, -21, -23, -23, -23, -21,
+ -19, -16, -12, -8, -4, 0, 4, 8, 11, 13, 14, 15, 15, 14, 13, 12,
+ 11, 10, 9, 8, 7, 7, 7, 7, 7, 8, 8, 9, 11, 12, 14, 16,
+ 19, 23, 27, 31, 35, 40, 45, 51, 58, 66, 74, 82, 88, 90, 88, 77,
+ 58, 32, 1, -31, -62, -87, -107, -119, -125, -123, -117, -105, -90, -73, -56, -38,
+ -22, -8, 2, 10, 15, 17, 17, 15, 11, 7, 2, -4, -9, -14, -17, -20,
+ -22, -23, -22, -21, -19, -17, -14, -10, -6, -2, 2, 5, 9, 12, 14, 15,
+ 17, 18, 18, 18, 17, 15, 12, 10, 8, 6, 4, 4, 4, 5, 6, 7,
+ 8, 10, 13, 16, 19, 22, 25, 28, 32, 35, 40, 45, 52, 59, 67, 75,
+ 81, 85, 86, 80, 66, 45, 18, -12, -42, -69, -91, -107, -116, -119, -115, -107,
+ -95, -80, -64, -47, -31, -17, -5, 4, 10, 13, 14, 14, 11, 7, 3, -2,
+ -7, -12, -15, -18, -20, -21, -21, -20, -18, -16, -14, -11, -7, -4, 0, 4,
+ 7, 10, 12, 14, 16, 16, 16, 16, 16, 15, 14, 12, 10, 9, 7, 6,
+ 5, 4, 4, 5, 6, 7, 8, 10, 12, 15, 19, 23, 27, 31, 36, 41,
+ 47, 55, 64, 73, 81, 87, 90, 86, 75, 56, 30, 1, -30, -58, -82, -100,
+ -112, -117, -115, -109, -98, -84, -69, -52, -37, -22, -10, 0, 8, 12, 14, 14,
+ 13, 10, 6, 2, -3, -8, -12, -16, -18, -20, -20, -20, -19, -17, -15, -12,
+ -9, -5, -1, 2, 6, 9, 12, 14, 16, 17, 17, 17, 16, 14, 13, 11,
+ 8, 6, 4, 3, 2, 2, 2, 3, 5, 6, 8, 10, 12, 15, 18, 22,
+ 26, 30, 35, 40, 47, 55, 63, 71, 80, 87, 90, 88, 78, 59, 34, 4,
+ -27, -57, -82, -101, -113, -118, -117, -110, -99, -85, -69, -53, -37, -22, -9, 2,
+ 9, 14, 17, 17, 15, 12, 8, 3, -2, -7, -12, -16, -19, -20, -21, -21,
+ -19, -18, -15, -12, -9, -6, -2, 2, 6, 9, 12, 14, 16, 17, 17, 16,
+ 14, 12, 10, 8, 6, 5, 4, 3, 3, 2, 3, 4, 6, 7, 9, 11,
+ 13, 16, 19, 22, 26, 30, 34, 39, 46, 53, 61, 70, 80, 88, 93, 91,
+ 80, 61, 34, 3, -30, -59, -84, -102, -114, -119, -117, -110, -99, -84, -68, -51,
+ -35, -20, -7, 3, 11, 15, 17, 18, 16, 13, 9, 4, -2, -7, -11, -15,
+ -18, -20, -21, -21, -20, -19, -16, -14, -11, -8, -4, 0, 3, 7, 10, 13,
+ 15, 16, 17, 16, 14, 12, 10, 9, 7, 6, 5, 4, 4, 4, 5, 6,
+ 7, 8, 9, 11, 13, 15, 18, 21, 24, 27, 31, 35, 41, 48, 55, 64,
+ 73, 82, 89, 91, 85, 71, 48, 19, -13, -44, -71, -93, -108, -117, -118, -114,
+ -105, -92, -77, -60, -43, -27, -13, -1, 8, 14, 17, 18, 17, 14, 8, 13,
+ -1, -1, 0, 2, 4, 6, 9, 11, 13, 14, 13, 12, 11, 8, 5, 2,
+ -1, -5, -10, -14, -16, -17, -16, -14, -11, -8, -5, -4, -3, -1, -1, -1,
+ -1, -3, -3, -3, -2, -1, -1, 0, 0, 0, 0, 2, 6, 11, 14, 16,
+ 19, 22, 25, 32, 36, 34, 25, 11, -5, -20, -31, -35, -36, -34, -29, -23,
+ -16, -8, -4, -4, -8, -11, -12, -13, -12, -10, -7, -4, -2, -1, 1, 4,
+ 7, 7, 6, 6, 6, 7, 12, 17, 24, 30, 36, 41, 46, 51, 50, 43,
+ 25, 2, -25, -48, -61, -62, -57, -48, -35, -23, -12, -5, -3, -5, -9, -12,
+ -14, -14, -12, -7, -3, 0, 1, 2, 4, 6, 7, 9, 11, 11, 10, 9,
+ 12, 17, 23, 30, 37, 43, 49, 55, 58, 50, 30, 1, -29, -54, -68, -68,
+ -60, -49, -35, -22, -10, -2, 0, -3, -9, -16, -20, -21, -19, -14, -8, -2,
+ 3, 7, 11, 12, 11, 9, 7, 7, 8, 10, 15, 19, 24, 28, 33, 36,
+ 42, 47, 53, 56, 45, 23, -8, -37, -60, -71, -69, -56, -40, -27, -16, -8,
+ -5, -6, -11, -17, -21, -22, -20, -16, -9, -2, 5, 8, 10, 11, 10, 9,
+ 8, 8, 9, 10, 13, 16, 19, 24, 29, 35, 42, 49, 53, 59, 55, 37,
+ 5, -29, -58, -74, -77, -69, -53, -35, -21, -11, -5, -4, -6, -10, -15, -19,
+ -19, -16, -10, -5, 1, 5, 8, 11, 13, 14, 12, 10, 8, 6, 7, 10,
+ 15, 21, 29, 39, 51, 62, 72, 82, 81, 52, 3, -50, -90, -110, -109, -91,
+ -64, -35, -13, 1, 8, 9, 4, -4, -12, -18, -18, -14, -9, -3, 3, 8,
+ 11, 11, 10, 7, 4, 2, 2, 4, 8, 13, 18, 26, 36, 48, 60, 72,
+ 82, 91, 86, 54, -2, -61, -105, -126, -121, -98, -65, -33, -7, 8, 14, 12,
+ 6, -4, -14, -20, -22, -19, -14, -8, 0, 7, 12, 14, 13, 11, 9, 7,
+ 4, 2, 4, 9, 16, 26, 36, 48, 58, 69, 79, 84, 80, 59, 14, -43,
+ -92, -119, -120, -102, -73, -40, -12, 5, 12, 11, 5, -3, -12, -18, -21, -20,
+ -16, -9, -2, 5, 11, 15, 16, 15, 12, 7, 4, 4, 6, 9, 15, 23,
+ 31, 38, 46, 54, 65, 75, 78, 68, 34, -16, -68, -103, -114, -105, -80, -50,
+ -22, -1, 9, 10, 6, -3, -12, -18, -21, -21, -17, -11, -3, 4, 9, 13,
+ 16, 17, 14, 11, 8, 5, 5, 7, 10, 14, 20, 28, 37, 49, 64, 77,
+ 83, 73, 42, -8, -59, -95, -110, -103, -81, -53, -24, -3, 9, 11, 6, -2,
+ -10, -17, -20, -20, -17, -12, -5, 2, 9, 13, 15, 16, 14, 11, 8, 6,
+ 5, 6, 8, 12, 19, 28, 38, 50, 66, 82, 90, 83, 48, -9, -69, -111,
+ -124, -113, -85, -50, -18, 5, 16, 16, 9, -1, -11, -18, -21, -21, -17, -12,
+ -5, 3, 9, 14, 15, 13, 11, 9, 8, 6, 5, 6, 8, 15, 23, 31,
+ 41, 52, 66, 82, 91, 83, 46, -16, -77, -118, -128, -114, -84, -47, -14, 9,
+ 19, 19, 10, -1, -11, -19, -23, -23, -19, -12, -4, 4, 11, 14, 15, 13,
+ 11, 9, 7, 7, 7, 8, 11, 14, 19, 27, 35, 45, 58, 74, 88, 88,
+ 58, 1, -62, -107, -125, -116, -90, -56, -22, 2, 15, 17, 11, 2, -9, -17,
+ -22, -22, -20, -14, -6, 2, 9, 14, 17, 18, 17, 12, 8, 4, 4, 6,
+ 8, 13, 19, 25, 32, 40, 52, 67, 81, 86, 66, 18, -42, -91, -116, -115,
+ -95, -64, -31, -5, 10, 14, 11, 3, -7, -15, -20, -21, -18, -14, -7, 0,
+ 7, 12, 16, 17, 16, 14, 10, 7, 5, 4, 6, 8, 12, 19, 27, 36,
+ 47, 64, 81, 90, 75, 30, -30, -82, -112, -115, -98, -69, -37, -10, 8, 14,
+ 13, 6, -3, -12, -18, -20, -19, -15, -9, -1, 6, 12, 16, 17, 16, 13,
+ 8, 4, 2, 2, 5, 8, 12, 18, 26, 35, 47, 63, 80, 90, 78, 34,
+ -27, -82, -113, -117, -99, -69, -37, -9, 9, 17, 15, 8, -2, -12, -19, -21,
+ -19, -15, -9, -2, 6, 12, 16, 17, 14, 10, 6, 4, 3, 3, 6, 9,
+ 13, 19, 26, 34, 46, 61, 80, 93, 80, 34, -30, -84, -114, -117, -99, -68,
+ -35, -7, 11, 17, 16, 9, -2, -11, -18, -21, -20, -16, -11, -4, 3, 10,
+ 15, 17, 14, 10, 7, 5, 4, 5, 7, 9, 13, 18, 24, 31, 41, 55,
+ 73, 89, 85, 48, -12, -71, -108, -118, -104, -77, -43, -13, 8, 16, 17, 16,
+ 0, -3, -4, -5, -4, 0, -4, -8, -20, -25, 51, 11, -55, 9, 39, 55,
+ -76, -19, 92, -23, -58, 2, -15, 57, 71, 34, -41, 20, 51, 22, 63, -21,
+ 63, 74, 32, 36, 99, -14, 27, 102, 66, 90, 79, 77, 58, 66, 65, 114,
+ 69, 26, 30, 92, 90, 53, 78, 97, 77, 66, 39, -4, 60, 57, 64, 68,
+ -16, 36, 49, 12, 19, 12, -12, 21, 11, -32, -19, -41, -44, -12, -36, -44,
+ -45, -51, -55, -70, -69, -73, -85, -102, -86, -99, -92, -105, -108, -103, -100, -107,
+ -112, -104, -113, -112, -104, -119, -124, -115, -87, -100, -128, -106, -83, -105, -108, -109,
+ -91, -95, -90, -83, -80, -79, -83, -68, -59, -53, -63, -69, -57, -28, -11, -38,
+ -43, -23, -10, -6, 3, 1, 6, 14, 21, 23, 34, 40, 42, 48, 57, 61,
+ 63, 65, 73, 82, 90, 82, 89, 98, 100, 110, 111, 109, 115, 120, 121, 121,
+ 123, 123, 123, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 121, 121,
+ 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 120, 120, 120, 120, 120, 120,
+ 120, 120, 120, 120, 113, 104, 103, 113, 110, 94, 80, 88, 96, 89, 81, 70,
+ 68, 64, 59, 59, 54, 44, 44, 39, 31, 31, 21, 18, 16, 8, 6, 2,
+ -3, -6, -13, -19, -27, -31, -34, -30, -38, -47, -48, -51, -56, -64, -68, -67,
+ -68, -76, -73, -79, -85, -94, -89, -90, -94, -92, -99, -100, -107, -107, -104, -107,
+ -106, -112, -114, -113, -112, -111, -112, -116, -116, -115, -115, -115, -115, -115, -115, -115,
+ -114, -114, -114, -114, -114, -114, -114, -114, -113, -113, -113, -113, -113, -108, -106, -107,
+ -111, -110, -105, -108, -107, -102, -100, -103, -103, -100, -100, -97, -97, -100, -99, -97,
+ -94, -90, -94, -94, -93, -93, -92, -92, -90, -89, -89, -90, -91, -87, -87, -88,
+ -89, -88, -84, -85, -88, -87, -86, -85, -85, -84, -82, -83, -83, -82, -81, -80,
+ -79, -79, -79, -78, -75, -74, -75, -73, -74, -71, -69, -67, -69, -66, -64, -66,
+ -65, -64, -62, -58, -57, -57, -57, -56, -52, -51, -50, -48, -46, -43, -43, -42,
+ -39, -36, -35, -34, -32, -31, -29, -26, -23, -23, -21, -15, -18, -15, -11, -8,
+ -6, -7, 0, 2, 0, 2, 7, 15, 14, 15, 16, 19, 23, 27, 29, 30,
+ 31, 34, 41, 41, 42, 44, 45, 51, 55, 54, 56, 57, 60, 65, 67, 69,
+ 69, 71, 74, 77, 79, 78, 80, 82, 86, 86, 84, 86, 88, 87, 87, 87,
+ 87, 87, 86, 86, 86, 86, 86, 85, 85, 85, 85, 85, 84, 84, 84, 84,
+ 84, 83, 83, 83, 83, 83, 83, 82, 82, 82, 82, 82, 81, 81, 81, 81,
+ 81, 80, 80, 80, 80, 80, 79, 79, 79, 79, 79, 78, 78, 78, 78, 76,
+ 75, 72, 69, 67, 65, 64, 63, 59, 55, 54, 52, 50, 48, 45, 42, 38,
+ 36, 34, 31, 30, 27, 24, 21, 18, 16, 14, 12, 9, 7, 4, 1, -2,
+ -4, -7, -10, -11, -13, -16, -17, -18, -21, -24, -26, -27, -28, -30, -32, -33,
+ -35, -36, -38, -39, -41, -42, -43, -45, -45, -46, -47, -48, -49, -50, -51, -50,
+ -51, -52, -53, -53, -53, -53, -53, -53, -53, -54, -54, -54, -54, -53, -53, -52,
+ -52, -52, -51, -51, -51, -50, -50, -50, -48, -49, -48, -47, -46, -45, -45, -44,
+ -43, -42, -41, -41, -40, -39, -38, -37, -36, -35, -34, -33, -31, -30, -29, -28,
+ -27, -26, -24, -24, -23, -22, -21, -20, -19, -18, -17, -16, -15, -14, -13, -13,
+ -12, -11, -11, -10, -9, -9, -8, -8, -7, -6, -7, -6, -5, -5, -5, -4,
+ -4, -3, -3, -3, -3, -3, -2, -2, -2, -2, -2, -2, -2, -2, 0, 0,
+ 0, 0, -1, 0, 4, 9, 13, 13, 11, 5, -1, -10, -16, -17, -11, -5,
+ -2, -1, -2, -3, -2, -1, 0, 0, 6, 14, 19, 26, 36, 25, -5, -30,
+ -36, -29, -16, -4, -7, -13, -12, -7, -2, 1, 6, 7, 6, 11, 24, 36,
+ 46, 50, 26, -25, -60, -57, -36, -12, -3, -9, -14, -12, -3, 1, 4, 7,
+ 11, 10, 12, 23, 37, 49, 58, 31, -29, -67, -61, -36, -10, 0, -9, -20,
+ -19, -8, 3, 11, 11, 7, 8, 15, 24, 32, 41, 53, 45, -7, -60, -68,
+ -41, -16, -5, -11, -21, -20, -10, 4, 10, 10, 8, 9, 13, 19, 29, 42,
+ 54, 55, 6, -57, -77, -54, -21, -6, -6, -15, -19, -11, 1, 8, 13, 12,
+ 8, 7, 15, 29, 50, 73, 80, 5, -90, -109, -65, -13, 8, 4, -13, -18,
+ -10, 3, 11, 10, 4, 2, 8, 18, 36, 60, 82, 86, 1, -105, -121, -66,
+ -8, 13, 6, -14, -22, -15, -1, 12, 13, 9, 4, 3, 16, 36, 58, 78,
+ 81, 15, -91, -121, -74, -13, 12, 5, -11, -21, -16, -2, 11, 16, 12, 4,
+ 6, 15, 31, 46, 64, 79, 36, -66, -115, -81, -23, 9, 6, -11, -21, -17,
+ -4, 9, 16, 15, 8, 5, 9, 20, 37, 63, 83, 43, -57, -110, -83, -25,
+ 8, 7, -10, -20, -17, -5, 9, 15, 14, 8, 5, 8, 18, 37, 65, 91,
+ 50, -67, -124, -86, -19, 16, 9, -10, -21, -18, -5, 9, 15, 11, 8, 5,
+ 8, 22, 40, 65, 92, 48, -74, -128, -85, -16, 19, 11, -11, -23, -19, -4,
+ 10, 15, 11, 8, 7, 11, 19, 35, 57, 88, 60, -58, -125, -92, -24, 15,
+ 12, -8, -22, -20, -7, 9, 17, 17, 8, 4, 8, 18, 31, 51, 81, 67,
+ -38, -116, -96, -33, 9, 11, -6, -20, -19, -8, 7, 16, 16, 11, 5, 5,
+ 12, 26, 47, 80, 76, -26, -111, -99, -39, 7, 13, -3, -18, -19, -9, 5,
+ 16, 16, 8, 2, 4, 12, 25, 46, 79, 79, -23, -112, -101, -39, 9, 15,
+ -2, -18, -20, -9, 5, 16, 14, 7, 3, 5, 13, 25, 44, 79, 81, -25,
+ -113, -100, -37, 10, 16, -1, -18, -20, -11, 3, 15, 15, 7, 4, 6, 13,
+ 23, 40, 72, 86, -7, -107, -106, -46, 7, 16, 0, 16, 31, 47, 61, 75,
+ 87, 98, 107, 115, 121, 125, 127, 127, 125, 121, 116, 108, 99, 88, 75, 62,
+ 47, 32, 16, 0, -16, -31, -47, -61, -75, -87, -98, -108, -116, -122, -126, -128,
+ -128, -126, -123, -117, -109, -100, -89, -77, -64, -49, -34, -18, -2, 14, 29, 45,
+ 59, 73, 86, 97, 106, 114, 121, 125, 127, 127, 126, 122, 116, 109, 100, 89,
+ 77, 63, 49, 34, 18, 2, -14, -30, -45, -60, -73, -86, -97, -107, -115, -121,
+ -126, -128, -128, -127, -123, -118, -110, -101, -91, -79, -65, -51, -36, -20, -4, 12,
+ 28, 43, 58, 72, 84, 96, 106, 114, 120, 124, 127, 127, 126, 122, 117, 109,
+ 100, 90, 78, 64, 50, 35, 19, 3, -13, -29, -44, -59, -73, -85, -97, -107,
+ -115, -121, -125, -128, -128, -127, -123, -118, -110, -101, -91, -79, -65, -51, -36, -20,
+ -4, 12, 28, 43, 58, 72, 84, 96, 106, 114, 120, 124, 127, 127, 126, 122,
+ 117, 109, 100, 90, 78, 64, 50, 35, 19, 3, -13, -29, -44, -59, -73, -85,
+ -97, -107, -115, -121, -125, -128, -128, -127, -123, -118, -110, -101, -91, -79, -65, -51,
+ -36, -20, -4, 12, 28, 43, 58, 72, 84, 96, 106, 114, 120, 124, 127, 127,
+ 126, 122, 117, 109, 100, 90, 78, 64, 50, 35, 19, 3, -13, -29, -44, -59,
+ -73, -85, -97, -107, -115, -121, -125, -128, -128, -127, -123, -118, -110, -101, -91, -79,
+ -65, -51, -36, -20, -4, 12, 28, 43, 58, 72, 84, 96, 106, 114, 120, 124,
+ 127, 127, 126, 122, 117, 109, 100, 90, 78, 64, 50, 35, 19, 3, -13, -29,
+ -44, -59, -73, -85, -97, -107, -115, -121, -125, -128, -128, -127, -123, -118, -110, -101,
+ -91, -79, -65, -51, -36, -20, -4, 12, 0, -104, -55, -11, 24, 33, 30, 7,
+ -15, -31, -30, -25, -23, -20, -9, 10, 31, 59, 91, 111, 115, 92, 51, 7,
+ -33, -64, -81, -81, -71, -51, -22, 16, 52, 74, 82, 81, 68, 38, 0, -40,
+ -81, -112, -124, -102, -57, -11, 24, 33, 30, 7, -15, -31, -30, -25, -23, -20,
+ -9, 10, 31, 59, 91, 111, 115, 92, 51, 7, -33, -64, -81, -81, -71, -51,
+ -22, 16, 52, 74, 82, 81, 68, 38, 0, -40, -81, -112, -124, -102, -57, -11,
+ 24, 33, 30, 7, -15, -31, -30, -25, -23, -20, -9, 10, 31, 59, 91, 111,
+ 115, 92, 51, 7, -33, -64, -81, -81, -71, -51, -22, 16, 52, 74, 82, 81,
+ 68, 38, 0, -40, -81, -112, -124, -102, -57, -11, 24, 33, 30, 7, -15, -31,
+ -30, -25, -23, -20, -9, 10, 31, 59, 91, 111, 115, 92, 51, 7, -33, -64,
+ -81, -81, -71, -51, -22, 16, 52, 74, 82, 81, 68, 38, 0, -40, -81, -112,
+ -124, -102, -57, -11, 0
+};
+
+const EAS_U32 testSampleLengths[] =
+{
+ 1568, 784, 642, 392, 302, 172
+};
+
+const EAS_U32 testSampleOffsets[] =
+{
+ 0x00000000, 0x00000620, 0x00000930, 0x00000bb2, 0x00000d3a, 0x00000e68
+};
+
+/*----------------------------------------------------------------------------
+ * S_EAS
+ *----------------------------------------------------------------------------
+*/
+const S_EAS easTestLib =
+{
+ 0x01534145,
+ 0x00105622,
+ testBanks,
+ testPrograms,
+ testRegions,
+ testArticulations,
+ testSampleLengths,
+ testSampleOffsets,
+ testSamples,
+ 0,
+ 0,
+ 16,
+ 152,
+ 97,
+ 6,
+ 0
+}; /* end S_EAS */
+
+/*----------------------------------------------------------------------------
+ * Statistics
+ *
+ * Number of banks: 0
+ * Number of programs: 16
+ * Number of regions: 152
+ * Number of articulations: 97
+ * Number of samples: 6
+ * Size of sample pool: 3861
+ *----------------------------------------------------------------------------
+*/
+/* end ..\..\EASLib\WTLibrary\eastestv37.c */
diff --git a/arm-wt-22k/jetcreator_lib_src/darwin-x86/wt_44khz.c b/arm-wt-22k/jetcreator_lib_src/darwin-x86/wt_44khz.c
index 688c715..53cd952 100644
--- a/arm-wt-22k/jetcreator_lib_src/darwin-x86/wt_44khz.c
+++ b/arm-wt-22k/jetcreator_lib_src/darwin-x86/wt_44khz.c
@@ -1,14723 +1,14723 @@
-/*----------------------------------------------------------------------------
- *
- * Filename: wt_44khz.c
- * Purpose: Wavetable sound libary
- *
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
-*/
-
-#include "eas_sndlib.h"
-
-/*----------------------------------------------------------------------------
- * Articulations
- *----------------------------------------------------------------------------
-*/
-const S_ARTICULATION eas_articulations[] =
-{
- { /* articulation 0 */
- { 32767, 31730, 0, 31730 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 476, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 1 */
- { 32767, 29669, 0, 29669 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 476, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 2 */
- { 32767, 31605, 0, 31701 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 476, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 3 */
- { 32767, 29434, 0, 29434 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 476, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 4 */
- { 32767, 0, 32767, 32742 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 476, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 5 */
- { 32767, 26439, 0, 26439 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 476, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 6 */
- { 32767, 32322, 0, 32350 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 476, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 7 */
- { 32767, 32715, 32767, 32715 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 476, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 8 */
- { 32767, 0, 32767, 0 },
- { 32767, 951, 0, 0 },
- 0, 0, 476, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 9 */
- { 32767, 32558, 0, 32558 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 476, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 10 */
- { 32767, 0, 32767, 23749 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 476, 0, 0, 0, 0, 0, -1
- },
- { /* articulation 11 */
- { 32767, 32245, 0, 32245 },
- { 32767, 380, 0, 0 },
- 0, 0, 476, 0, 0, 0, 0, 0, -44
- },
- { /* articulation 12 */
- { 32767, 27897, 0, 27897 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 476, 0, 0, 0, 0, 0, 56
- },
- { /* articulation 13 */
- { 32767, 32245, 0, 32245 },
- { 32767, 380, 0, 0 },
- 0, 0, 476, 0, 0, 0, 0, 0, -31
- },
- { /* articulation 14 */
- { 4755, 26439, 0, 26439 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 476, 0, 0, 0, 0, 0, 56
- },
- { /* articulation 15 */
- { 32767, 32187, 0, 32187 },
- { 32767, 380, 0, 0 },
- 0, 0, 476, 0, 0, 0, 0, 0, -6
- },
- { /* articulation 16 */
- { 32767, 32444, 0, 32480 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 476, 0, 0, 0, 0, 0, 56
- },
- { /* articulation 17 */
- { 32767, 32153, 0, 32153 },
- { 32767, 380, 0, 0 },
- 0, 0, 476, 0, 0, 0, 0, 0, 6
- },
- { /* articulation 18 */
- { 32767, 32072, 0, 32072 },
- { 32767, 476, 0, 0 },
- 0, 0, 476, 0, 0, 0, 0, 0, 31
- },
- { /* articulation 19 */
- { 32767, 32363, 0, 32363 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 476, 0, 0, 0, 0, 0, 25
- },
- { /* articulation 20 */
- { 32767, 31901, 0, 31901 },
- { 32767, 476, 0, 0 },
- 0, 0, 476, 0, 0, 0, 0, 0, 63
- },
- { /* articulation 21 */
- { 32767, 32528, 0, 32518 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 476, 0, 0, 0, 0, 0, -37
- },
- { /* articulation 22 */
- { 9511, 32322, 0, 32337 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 476, 0, 0, 0, 0, 0, -37
- },
- { /* articulation 23 */
- { 32767, 32376, 0, 32398 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 476, 0, 0, 0, 0, 0, -37
- },
- { /* articulation 24 */
- { 32767, 0, 32767, 32715 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 476, 0, 0, 0, 0, 0, 12
- },
- { /* articulation 25 */
- { 32767, 32052, 0, 32052 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 476, 0, 0, 0, 0, 0, -25
- },
- { /* articulation 26 */
- { 32767, 0, 32767, 32715 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 476, 0, 0, 0, 0, 0, 25
- },
- { /* articulation 27 */
- { 32767, 32289, 0, 32271 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 476, 0, 0, 0, 0, 0, -25
- },
- { /* articulation 28 */
- { 32767, 31730, 0, 31730 },
- { 32767, 48, 0, 0 },
- 0, 0, 476, 240, 0, 0, 0, 0, -56
- },
- { /* articulation 29 */
- { 32767, 32498, 0, 32492 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 476, 0, 0, 0, 0, 0, -37
- },
- { /* articulation 30 */
- { 32767, 29434, 0, 29434 },
- { 32767, 1902, 0, 0 },
- 0, 0, 476, 0, 0, 0, 0, 0, 50
- },
- { /* articulation 31 */
- { 32767, 27897, 0, 27897 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 476, 0, 0, 0, 0, 0, -50
- },
- { /* articulation 32 */
- { 32767, 31056, 0, 31056 },
- { 32767, 1902, 0, 0 },
- 0, 0, 476, 0, 0, 0, 0, 0, -50
- },
- { /* articulation 33 */
- { 32767, 31479, 0, 31476 },
- { 32767, 1902, 0, 0 },
- 0, 0, 476, 0, 0, 0, 0, 0, -44
- },
- { /* articulation 34 */
- { 32767, 32663, 0, 32663 },
- { 32767, 127, 0, 0 },
- 0, 0, 476, 0, 0, 0, 0, 0, 25
- },
- { /* articulation 35 */
- { 32767, 0, 32767, 32715 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 476, 0, 0, 0, 0, 0, -63
- },
- { /* articulation 36 */
- { 1902, 27897, 0, 27897 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 476, 0, 0, 0, 0, 0, -63
- },
- { /* articulation 37 */
- { 32767, 27897, 0, 27897 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 476, 0, 0, 0, 0, 0, -59
- },
- { /* articulation 38 */
- { 32767, 31730, 0, 31730 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 476, 0, 0, 0, 0, 0, 50
- },
- { /* articulation 39 */
- { 32767, 30725, 0, 30725 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 476, 0, 0, 0, 0, 0, 44
- },
- { /* articulation 40 */
- { 951, 31730, 0, 31730 },
- { 32767, 190, 0, 0 },
- 0, 0, 476, -100, 0, 0, 0, 0, 44
- },
- { /* articulation 41 */
- { 32767, 17213, 0, 17213 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 476, 0, 0, 0, 0, 0, 25
- },
- { /* articulation 42 */
- { 32767, 31295, 0, 31295 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 476, 0, 0, 0, 0, 0, 63
- },
- { /* articulation 43 */
- { 32767, 31479, 0, 31476 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 476, 0, 0, 0, 0, 0, 63
- },
- { /* articulation 44 */
- { 9511, 25581, 0, 25581 },
- { 476, 32767, 32767, 0 },
- 0, 0, 476, 100, 0, 0, 0, 0, -25
- },
- { /* articulation 45 */
- { 1902, 23749, 0, 23749 },
- { 476, 32767, 32767, 0 },
- 0, 0, 476, 500, 0, 0, 0, 0, -25
- },
- { /* articulation 46 */
- { 32767, 23749, 0, 23749 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 476, 0, 0, 0, 0, 0, -56
- },
- { /* articulation 47 */
- { 32767, 31730, 0, 31730 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 476, 0, 0, 0, 0, 0, -56
- },
- { /* articulation 48 */
- { 32767, 0, 32767, 0 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 476, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 49 */
- { 32767, 31964, 0, 31964 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 476, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 50 */
- { 9511, 32363, 0, 32418 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 476, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 51 */
- { 32767, 31180, 0, 31180 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 476, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 52 */
- { 32767, 32251, 0, 32052 },
- { 32767, 147, 0, 0 },
- 0, 0, 476, 0, 10000, 7121, 0, 0, 0
- },
- { /* articulation 53 */
- { 32767, 0, 32767, 32072 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 778, 0, -2300, 11920, 0, 0, 0
- },
- { /* articulation 54 */
- { 587, 0, 32767, 32376 },
- { 32767, 63, 0, 0 },
- 0, 0, 778, 0, 2000, 10721, 0, 8, 15
- },
- { /* articulation 55 */
- { 587, 0, 32767, 32376 },
- { 476, 63, 0, 0 },
- 0, 0, 778, 0, 2000, 9023, 0, 5, 15
- },
- { /* articulation 56 */
- { 3804, 0, 32767, 31477 },
- { 32767, 34, 5898, 0 },
- 0, 0, 778, 0, 6000, 9080, 0, 0, -2
- },
- { /* articulation 57 */
- { 32767, 0, 32767, 31005 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 778, 0, 0, 0, 0, 0, 1
- },
- { /* articulation 58 */
- { 2570, 0, 32767, 31455 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 778, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 59 */
- { 32767, 32663, 0, 29434 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 476, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 60 */
- { 32767, 32558, 0, 29434 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 476, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 61 */
- { 32767, 32418, 0, 32418 },
- { 32767, 48, 0, 0 },
- 0, 69, 495, 0, 2400, 9521, 0, 0, 0
- },
- { /* articulation 62 */
- { 32767, 31476, 0, 31476 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 476, 0, 0, 11738, 0, 16, 0
- },
- { /* articulation 63 */
- { 32767, 32558, 0, 31391 },
- { 32767, 317, 0, 0 },
- 0, 69, 476, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 64 */
- { 32767, 32245, 0, 32115 },
- { 32767, 317, 0, 0 },
- 0, 69, 476, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 65 */
- { 32767, 32593, 0, 28809 },
- { 32767, 48, 0, 0 },
- 0, 69, 495, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 66 */
- { 32767, 32408, 0, 32363 },
- { 32767, 317, 0, 0 },
- 0, 69, 476, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 67 */
- { 32767, 32350, 0, 32350 },
- { 32767, 317, 0, 0 },
- 0, 69, 476, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 68 */
- { 4755, 32715, 18820, 27897 },
- { 951, 29, 13107, 0 },
- 0, 0, 495, 0, 6000, 5535, 0, 4, 0
- },
- { /* articulation 69 */
- { 32767, 32257, 0, 32245 },
- { 32767, 951, 0, 0 },
- 0, 103, 495, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 70 */
- { 63, 32727, 3811, 32558 },
- { 48, 19, 32767, 0 },
- 0, 0, 495, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 71 */
- { 2378, 32715, 3566, 30725 },
- { 1902, 32767, 32767, 0 },
- 0, 0, 495, 100, 0, 11919, 0, 0, 0
- },
- { /* articulation 72 */
- { 32767, 32349, 0, 32349 },
- { 32767, 168, 0, 0 },
- 0, 34, 495, 0, 7000, 9023, 0, 0, 0
- },
- { /* articulation 73 */
- { 32767, 32072, 0, 32072 },
- { 32767, 168, 0, 0 },
- 0, 3, 476, 0, 7000, 9023, 0, 0, 0
- },
- { /* articulation 74 */
- { 32767, 32698, 6208, 32349 },
- { 190, 48, 0, 0 },
- 0, 0, 495, 0, 3840, 8302, 0, 8, 0
- },
- { /* articulation 75 */
- { 32767, 32418, 0, 32468 },
- { 32767, 190, 0, 0 },
- 0, 0, 495, 0, 5000, 8321, 0, 0, 0
- },
- { /* articulation 76 */
- { 32767, 32349, 0, 32349 },
- { 32767, 190, 0, 0 },
- 0, 0, 476, 0, 5000, 7934, 0, 0, 0
- },
- { /* articulation 77 */
- { 32767, 32441, 0, 31709 },
- { 32767, 32, 0, 0 },
- 0, 34, 495, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 78 */
- { 32767, 32505, 0, 27897 },
- { 32767, 951, 0, 0 },
- 0, 345, 495, 0, 1000, 11107, 0, 0, 0
- },
- { /* articulation 79 */
- { 32767, 32715, 6208, 32349 },
- { 48, 48, 0, 0 },
- 0, 69, 811, 0, 3560, 8834, 1, 8, 0
- },
- { /* articulation 80 */
- { 32767, 32564, 0, 29434 },
- { 32767, 95, 0, 0 },
- 0, 34, 495, 0, 6000, 9907, 0, 0, 0
- },
- { /* articulation 81 */
- { 32767, 32505, 0, 27897 },
- { 32767, 32, 0, 0 },
- 0, 34, 495, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 82 */
- { 32767, 32245, 18820, 17213 },
- { 32767, 32767, 32767, 0 },
- 0, 34, 495, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 83 */
- { 32767, 32742, 128, 32466 },
- { 32767, 63, 0, 0 },
- 0, 0, 495, 0, 0, 11920, 0, 8, 0
- },
- { /* articulation 84 */
- { 32767, 32418, 0, 32418 },
- { 32767, 33, 0, 0 },
- 3, 0, 286, 0, 5000, 5535, 0, 0, 0
- },
- { /* articulation 85 */
- { 1902, 32715, 18820, 27897 },
- { 32767, 1012, 0, 0 },
- 10, 69, 504, -30, 0, 0, 0, 0, 0
- },
- { /* articulation 86 */
- { 9511, 32715, 18820, 27897 },
- { 380, 48, 0, 0 },
- 0, 69, 495, 0, 4473, 7131, 0, 8, 0
- },
- { /* articulation 87 */
- { 951, 32698, 6208, 32468 },
- { 317, 19, 16384, 0 },
- 0, 0, 495, 0, 2987, 7877, 0, 12, 0
- },
- { /* articulation 88 */
- { 32767, 32680, 0, 32349 },
- { 32767, 48, 0, 0 },
- 0, 0, 581, 0, 4053, 7930, 2, 12, 0
- },
- { /* articulation 89 */
- { 190, 32726, 6208, 32349 },
- { 32767, 56, 0, 0 },
- 0, 0, 495, 0, 0, 8887, 0, 0, 0
- },
- { /* articulation 90 */
- { 9511, 32715, 18820, 27897 },
- { 634, 48, 0, 0 },
- 0, 69, 495, 0, 5113, 7981, 0, 4, 0
- },
- { /* articulation 91 */
- { 951, 32715, 6208, 31730 },
- { 951, 63, 0, 0 },
- 0, 69, 495, 0, 3500, 7877, 0, 5, 0
- },
- { /* articulation 92 */
- { 951, 32715, 6208, 31730 },
- { 634, 48, 0, 0 },
- 0, 69, 476, 0, 4773, 8355, 0, 5, 0
- },
- { /* articulation 93 */
- { 238, 32715, 10809, 32349 },
- { 32767, 32767, 32767, 0 },
- 0, 69, 495, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 94 */
- { 1902, 32715, 18820, 31476 },
- { 32767, 32767, 32767, 0 },
- 0, 69, 495, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 95 */
- { 3804, 32715, 18820, 23749 },
- { 1268, 130, 0, 0 },
- 0, 69, 495, 0, 1200, 11690, 0, 4, 0
- },
- { /* articulation 96 */
- { 19021, 32618, 15076, 31476 },
- { 32767, 32767, 32767, 0 },
- 0, 72, 1091, 0, 0, 11919, 1, 0, 0
- },
- { /* articulation 97 */
- { 32767, 0, 32767, 32715 },
- { 190, 32767, 32767, 0 },
- 0, 0, 495, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 98 */
- { 32767, 32072, 0, 32072 },
- { 32767, 317, 0, 0 },
- 0, 0, 495, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 99 */
- { 32767, 32663, 0, 27897 },
- { 634, 95, 13107, 0 },
- 0, 69, 495, 0, 3200, 8321, 0, 0, 0
- },
- { /* articulation 100 */
- { 32767, 0, 32767, 0 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 495, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 101 */
- { 32767, 32418, 0, 27897 },
- { 32767, 543, 0, 0 },
- 0, 69, 495, 0, 8187, 5535, 0, 5, 0
- },
- { /* articulation 102 */
- { 19021, 32663, 0, 31056 },
- { 32767, 95, 7667, 0 },
- 5, 0, 495, 0, 6053, 5535, 0, 5, 0
- },
- { /* articulation 103 */
- { 32767, 32715, 18820, 27897 },
- { 951, 48, 0, 0 },
- 0, 0, 495, 0, 2700, 9852, 0, 0, 0
- },
- { /* articulation 104 */
- { 32767, 32715, 18820, 30234 },
- { 951, 48, 0, 0 },
- 0, 0, 495, 0, 2700, 9852, 0, 0, 0
- },
- { /* articulation 105 */
- { 32767, 32715, 18820, 27897 },
- { 32767, 634, 0, 0 },
- 0, 103, 476, 0, 2500, 10490, 1, 8, 0
- },
- { /* articulation 106 */
- { 32767, 32715, 23493, 27897 },
- { 32767, 190, 0, 0 },
- 0, 69, 494, 0, 4000, 10223, 1, 4, 0
- },
- { /* articulation 107 */
- { 32767, 32715, 18820, 30234 },
- { 32767, 63, 7667, 0 },
- 0, 0, 495, 0, 1813, 9154, 0, 0, 0
- },
- { /* articulation 108 */
- { 19021, 32245, 0, 32245 },
- { 32767, 190, 0, 0 },
- 0, 0, 476, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 109 */
- { 32767, 31964, 0, 31605 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 476, 0, 0, 11690, 0, 0, 0
- },
- { /* articulation 110 */
- { 32767, 31730, 0, 31730 },
- { 32767, 190, 0, 0 },
- 0, 0, 476, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 111 */
- { 32767, 32558, 18820, 30234 },
- { 32767, 48, 0, 0 },
- 12, 69, 476, 0, 3000, 10223, 0, 0, 0
- },
- { /* articulation 112 */
- { 32767, 32558, 18820, 30234 },
- { 32767, 32, 0, 0 },
- 12, 69, 476, 0, 1900, 10031, 0, 0, 0
- },
- { /* articulation 113 */
- { 32767, 32715, 18820, 29434 },
- { 32767, 32, 0, 0 },
- 12, 69, 494, 0, 1000, 11107, 0, 0, 0
- },
- { /* articulation 114 */
- { 32767, 32715, 18820, 29434 },
- { 32767, 32, 0, 0 },
- 12, 69, 494, 0, 2000, 11107, 0, 0, 0
- },
- { /* articulation 115 */
- { 32767, 32636, 0, 29434 },
- { 32767, 95, 0, 0 },
- 0, 34, 495, 0, 4000, 8321, 0, 0, 0
- },
- { /* articulation 116 */
- { 32767, 32297, 19893, 17213 },
- { 32767, 238, 0, 0 },
- 0, 69, 726, 0, 0, 11919, 0, 0, 0
- },
- { /* articulation 117 */
- { 9511, 32418, 23493, 17213 },
- { 32767, 32767, 32767, 0 },
- 0, 69, 678, 0, 0, 11877, 1, 0, 0
- },
- { /* articulation 118 */
- { 32767, 32618, 0, 27897 },
- { 32767, 95, 0, 0 },
- 0, 69, 495, 0, 3500, 9023, 0, 0, 0
- },
- { /* articulation 119 */
- { 32767, 23749, 23493, 0 },
- { 32767, 32767, 32767, 0 },
- 0, 34, 761, 0, 0, 10925, 1, 0, 0
- },
- { /* articulation 120 */
- { 32767, 32636, 0, 29434 },
- { 32767, 95, 0, 0 },
- 0, 103, 495, 0, 3200, 8721, 0, 4, 0
- },
- { /* articulation 121 */
- { 1902, 32715, 18820, 27897 },
- { 32767, 32767, 32767, 0 },
- 0, 69, 495, 0, 0, 0, 1, 0, 0
- },
- { /* articulation 122 */
- { 4755, 32715, 18820, 28809 },
- { 32767, 32767, 32767, 0 },
- 0, 69, 495, 0, 0, 11877, 0, 8, 0
- },
- { /* articulation 123 */
- { 32767, 32715, 18820, 27897 },
- { 32767, 16, 0, 0 },
- 0, 34, 495, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 124 */
- { 32767, 32663, 0, 27897 },
- { 32767, 190, 0, 0 },
- 0, 69, 495, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 125 */
- { 32767, 32715, 18820, 27897 },
- { 32767, 12, 0, 0 },
- 0, 34, 495, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 126 */
- { 32767, 31730, 0, 31730 },
- { 32767, 380, 0, 0 },
- 0, 0, 495, 0, 3000, 10223, 0, 8, 0
- },
- { /* articulation 127 */
- { 63, 0, 32767, 32558 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 761, 0, 0, 11423, 4, 0, 0
- },
- { /* articulation 128 */
- { 476, 32595, 0, 32577 },
- { 32767, 10, 0, 0 },
- 0, 0, 495, 0, 0, 11423, 0, 0, 0
- },
- { /* articulation 129 */
- { 196, 0, 0, 31964 },
- { 95, 32767, 32767, 0 },
- 0, 0, 495, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 130 */
- { 32767, 31730, 0, 31730 },
- { 32767, 380, 0, 0 },
- 0, 0, 495, 1200, 0, 0, 0, 0, 0
- },
- { /* articulation 131 */
- { 32767, 32245, 0, 32349 },
- { 32767, 190, 0, 0 },
- 0, 0, 495, 50, 0, 0, 0, 0, 0
- },
- { /* articulation 132 */
- { 32767, 32418, 0, 32418 },
- { 32767, 9511, 0, 0 },
- 0, 0, 495, 0, 4700, 7769, 0, 0, 0
- },
- { /* articulation 133 */
- { 32767, 31391, 0, 31391 },
- { 32767, 19021, 0, 0 },
- 0, 0, 495, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 134 */
- { 32767, 32663, 32767, 32663 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 476, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 135 */
- { 32767, 32715, 18820, 23749 },
- { 32767, 95, 0, 0 },
- 10, 68, 476, 0, 2000, 10696, 0, 0, 0
- },
- { /* articulation 136 */
- { 32767, 32715, 10809, 23749 },
- { 32767, 95, 0, 0 },
- 12, 69, 491, 0, 0, 10910, 0, 0, 0
- },
- { /* articulation 137 */
- { 32767, 32715, 18820, 23749 },
- { 32767, 95, 0, 0 },
- 10, 69, 476, 0, 1200, 10218, 0, 0, 0
- },
- { /* articulation 138 */
- { 19021, 32715, 18820, 23749 },
- { 32767, 95, 0, 0 },
- 10, 69, 476, 0, 1100, 9525, 0, 0, 0
- },
- { /* articulation 139 */
- { 9511, 32663, 18820, 27897 },
- { 32767, 10, 0, 0 },
- 10, 69, 494, 0, 2000, 10962, 0, 0, 0
- },
- { /* articulation 140 */
- { 32767, 32558, 18820, 27897 },
- { 9511, 317, 0, 0 },
- 10, 63, 504, 0, 1200, 10090, 0, 0, 0
- },
- { /* articulation 141 */
- { 1268, 0, 32767, 30234 },
- { 951, 190, 0, 0 },
- 7, 69, 494, 0, 1620, 8933, 0, 0, 0
- },
- { /* articulation 142 */
- { 32767, 32558, 10809, 27897 },
- { 19021, 190, 0, 0 },
- 7, 69, 494, 0, 2200, 8994, 0, 0, 0
- },
- { /* articulation 143 */
- { 32767, 32715, 15076, 27897 },
- { 32767, 951, 0, 0 },
- 10, 69, 491, 0, 2500, 9525, 0, 0, 0
- },
- { /* articulation 144 */
- { 32767, 32715, 15076, 27897 },
- { 32767, 95, 0, 0 },
- 10, 69, 476, 0, 1500, 11423, 0, 0, 0
- },
- { /* articulation 145 */
- { 32767, 32715, 18820, 27897 },
- { 32767, 951, 0, 0 },
- 9, 69, 491, 0, 1500, 9521, 0, 0, 0
- },
- { /* articulation 146 */
- { 1902, 0, 32767, 30725 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 761, 0, 0, 9521, 0, 0, 0
- },
- { /* articulation 147 */
- { 32767, 32663, 0, 27897 },
- { 32767, 9511, 0, 0 },
- 0, 34, 495, 0, 5000, 10223, 0, 0, 0
- },
- { /* articulation 148 */
- { 32767, 32715, 18820, 27897 },
- { 32767, 32, 0, 0 },
- 10, 69, 476, 0, 1500, 9907, 0, 0, 0
- },
- { /* articulation 149 */
- { 32767, 32733, 11682, 27897 },
- { 32767, 951, 0, 0 },
- 0, 69, 476, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 150 */
- { 32767, 32418, 0, 32418 },
- { 32767, 190, 0, 0 },
- 0, 34, 495, 0, 3440, 9260, 0, 0, 0
- },
- { /* articulation 151 */
- { 32767, 31476, 0, 31730 },
- { 32767, 951, 0, 0 },
- 0, 34, 495, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 152 */
- { 32767, 32245, 0, 31730 },
- { 32767, 190, 0, 0 },
- 0, 34, 495, 0, 4000, 7823, 0, 0, 0
- },
- { /* articulation 153 */
- { 32767, 32663, 3566, 27897 },
- { 391, 32767, 32767, 0 },
- 100, 0, 761, 500, 0, 11877, 0, 0, 0
- },
- { /* articulation 154 */
- { 32767, 32715, 18820, 23749 },
- { 32767, 951, 0, 0 },
- 8, 69, 495, -22, 0, 0, 0, 0, 0
- },
- { /* articulation 155 */
- { 9511, 30830, 6784, 27897 },
- { 32767, 951, 0, 0 },
- 0, 69, 476, 0, 5000, 9521, 1, 0, 0
- },
- { /* articulation 156 */
- { 32767, 32663, 0, 32349 },
- { 951, 127, 16384, 0 },
- 0, 103, 495, 0, 3627, 10547, 0, 5, 0
- },
- { /* articulation 157 */
- { 1902, 0, 32767, 27897 },
- { 951, 951, 0, 0 },
- 0, 69, 495, 27, 0, 11919, 0, 0, 0
- },
- { /* articulation 158 */
- { 32767, 0, 32767, 32245 },
- { 38, 33, 10092, 0 },
- 5, 0, 495, 0, 8007, 5535, 0, 8, 0
- },
- { /* articulation 159 */
- { 32767, 32618, 0, 31056 },
- { 32767, 63, 0, 0 },
- 0, 103, 495, 0, 2500, 9032, 0, 0, 0
- },
- { /* articulation 160 */
- { 4755, 32715, 10809, 28809 },
- { 32767, 32767, 32767, 0 },
- 0, 69, 495, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 161 */
- { 9511, 32663, 18820, 27897 },
- { 32767, 95, 0, 0 },
- 10, 69, 494, 0, 2600, 9513, 0, 0, 0
- },
- { /* articulation 162 */
- { 32767, 32435, 9568, 27897 },
- { 1174, 196, 0, 0 },
- 10, 103, 490, 0, 6500, 9023, 0, 0, 0
- },
- { /* articulation 163 */
- { 32767, 32663, 0, 29434 },
- { 32767, 32, 0, 0 },
- 0, 69, 495, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 164 */
- { 32767, 32418, 15076, 23749 },
- { 32767, 634, 0, 0 },
- 0, 0, 476, 0, 2000, 10223, 0, 0, 0
- },
- { /* articulation 165 */
- { 32767, 32663, 0, 27897 },
- { 32767, 190, 0, 0 },
- 0, 69, 495, 0, 3000, 9366, 0, 0, 0
- },
- { /* articulation 166 */
- { 32767, 32715, 18820, 27897 },
- { 951, 64, 10879, 0 },
- 0, 0, 495, 0, 6000, 7121, 0, 4, 0
- },
- { /* articulation 167 */
- { 32767, 32636, 0, 29434 },
- { 32767, 10, 0, 0 },
- 0, 103, 495, 0, 3500, 6236, 0, 5, 0
- },
- { /* articulation 168 */
- { 32767, 32636, 0, 29434 },
- { 32767, 95, 0, 0 },
- 0, 103, 495, 0, 2800, 7121, 0, 0, 0
- },
- { /* articulation 169 */
- { 32767, 32593, 0, 31056 },
- { 32767, 63, 0, 0 },
- 0, 103, 495, 0, 2100, 9626, 0, 0, 0
- },
- { /* articulation 170 */
- { 32767, 32558, 0, 31476 },
- { 32767, 63, 0, 0 },
- 0, 103, 495, 0, 3000, 9626, 0, 0, 0
- },
- { /* articulation 171 */
- { 32767, 32527, 0, 30506 },
- { 32767, 63, 0, 0 },
- 0, 103, 495, 0, 1000, 9032, 0, 0, 0
- },
- { /* articulation 172 */
- { 32767, 32418, 0, 30725 },
- { 32767, 63, 0, 0 },
- 0, 103, 495, 0, 1000, 9032, 0, 0, 0
- },
- { /* articulation 173 */
- { 1902, 32418, 15076, 23749 },
- { 32767, 634, 0, 0 },
- 0, 103, 496, 0, 0, 11107, 0, 8, 0
- },
- { /* articulation 174 */
- { 32767, 32558, 15076, 27897 },
- { 3804, 73, 0, 0 },
- 0, 0, 495, 0, 4500, 9521, 0, 8, 0
- },
- { /* articulation 175 */
- { 32767, 32715, 18820, 27897 },
- { 32767, 48, 0, 0 },
- 0, 0, 495, 0, 2000, 8321, 0, 8, 0
- },
- { /* articulation 176 */
- { 32767, 32742, 128, 31180 },
- { 32767, 865, 0, 0 },
- 0, 0, 495, 0, 6000, 7823, 0, 8, 0
- },
- { /* articulation 177 */
- { 9511, 32608, 0, 32322 },
- { 32767, 48, 0, 0 },
- 0, 0, 495, 0, 4500, 7121, 0, 8, 0
- },
- { /* articulation 178 */
- { 19021, 32664, 3646, 32436 },
- { 32767, 95, 0, 0 },
- 0, 0, 495, 0, 4000, 8321, 0, 8, 0
- },
- { /* articulation 179 */
- { 32767, 32685, 13644, 29434 },
- { 32767, 32, 0, 0 },
- 12, 69, 494, 0, 2000, 11107, 0, 0, 0
- },
- { /* articulation 180 */
- { 9511, 31605, 0, 27897 },
- { 32767, 951, 0, 0 },
- 0, 0, 495, 0, 5000, 8321, 1, 0, 0
- },
- { /* articulation 181 */
- { 130, 32617, 0, 32350 },
- { 32767, 317, 0, 0 },
- 0, 69, 476, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 182 */
- { 32767, 32593, 0, 32251 },
- { 1174, 20, 0, 0 },
- 0, 69, 495, 0, 3600, 7121, 0, 4, 0
- },
- { /* articulation 183 */
- { 32767, 32427, 0, 32427 },
- { 32767, 317, 0, 0 },
- 0, 69, 476, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 184 */
- { 834, 32742, 19242, 31455 },
- { 32767, 148, 0, 0 },
- 0, 0, 778, 0, 3000, 9907, 0, 4, 0
- }
-}; /*end Articulations */
-
-/*----------------------------------------------------------------------------
- * Regions
- *----------------------------------------------------------------------------
-*/
-const S_WT_REGION eas_regions[] =
-{
- { { 0, 27, 27 }, -4068, 16422, 0, 0, 81, 0 }, /* region 0 */
- { { 0, 28, 28 }, -4768, 32767, 0, 0, 40, 0 }, /* region 1 */
- { { 0, 29, 29 }, -5753, 32767, 0, 0, 32, 1 }, /* region 2 */
- { { 0, 30, 30 }, -6053, 32767, 0, 0, 32, 2 }, /* region 3 */
- { { 0, 31, 31 }, -5068, 23197, 0, 0, 48, 3 }, /* region 4 */
- { { 1536, 32, 32 }, -4400, 20675, 0, 0, 137, 4 }, /* region 5 */
- { { 1537, 33, 33 }, -4903, 20675, 792, 879, 50, 5 }, /* region 6 */
- { { 1537, 34, 34 }, -5003, 16422, 792, 879, 50, 6 }, /* region 7 */
- { { 0, 35, 35 }, -6168, 32767, 0, 0, 83, 7 }, /* region 8 */
- { { 0, 36, 36 }, -6168, 32767, 0, 0, 83, 7 }, /* region 9 */
- { { 0, 37, 37 }, -5251, 18426, 0, 0, 53, 8 }, /* region 10 */
- { { 0, 38, 38 }, -5351, 23197, 0, 0, 16, 9 }, /* region 11 */
- { { 0, 39, 39 }, -4768, 32767, 0, 0, 40, 10 }, /* region 12 */
- { { 0, 40, 40 }, -5351, 23197, 0, 0, 16, 4 }, /* region 13 */
- { { 1, 41, 41 }, -7055, 26028, 798, 993, 45, 11 }, /* region 14 */
- { { 257, 42, 42 }, -5400, 26028, 4288, 7488, 7, 12 }, /* region 15 */
- { { 1, 43, 43 }, -6955, 26028, 798, 993, 45, 13 }, /* region 16 */
- { { 257, 44, 44 }, -5600, 26028, 4288, 7488, 7, 14 }, /* region 17 */
- { { 1, 45, 45 }, -6955, 26028, 798, 993, 45, 15 }, /* region 18 */
- { { 257, 46, 46 }, -5800, 26028, 4288, 7488, 7, 16 }, /* region 19 */
- { { 1, 47, 47 }, -6655, 26028, 798, 993, 45, 17 }, /* region 20 */
- { { 1, 48, 48 }, -6555, 26028, 798, 993, 45, 18 }, /* region 21 */
- { { 1, 49, 49 }, -6400, 16422, 1294, 5778, 8, 19 }, /* region 22 */
- { { 1, 50, 50 }, -6455, 26028, 798, 993, 45, 20 }, /* region 23 */
- { { 1, 51, 51 }, -6468, 16422, 6592, 9921, 6, 21 }, /* region 24 */
- { { 1, 52, 52 }, -6800, 32767, 1294, 5778, 8, 22 }, /* region 25 */
- { { 1, 53, 53 }, -6618, 14636, 6592, 9921, 6, 23 }, /* region 26 */
- { { 0, 54, 54 }, -6951, 26028, 0, 0, 39, 24 }, /* region 27 */
- { { 1, 55, 55 }, -6500, 32767, 1294, 5778, 8, 25 }, /* region 28 */
- { { 0, 56, 56 }, -8455, 32767, 0, 0, 90, 26 }, /* region 29 */
- { { 1, 57, 57 }, -6900, 32767, 1294, 5778, 8, 27 }, /* region 30 */
- { { 1, 58, 58 }, -8253, 23197, 0, 166, 113, 28 }, /* region 31 */
- { { 1, 59, 59 }, -7168, 16422, 6592, 9921, 6, 29 }, /* region 32 */
- { { 1, 60, 60 }, -7653, 23197, 432, 582, 63, 30 }, /* region 33 */
- { { 1, 61, 61 }, -8053, 16422, 432, 582, 63, 30 }, /* region 34 */
- { { 1, 62, 62 }, -8453, 20675, 432, 582, 63, 31 }, /* region 35 */
- { { 1, 63, 63 }, -8553, 23197, 432, 582, 63, 32 }, /* region 36 */
- { { 1, 64, 64 }, -9153, 23197, 432, 582, 63, 33 }, /* region 37 */
- { { 0, 65, 65 }, -8755, 32767, 0, 0, 14, 34 }, /* region 38 */
- { { 0, 66, 66 }, -9155, 20675, 0, 0, 14, 34 }, /* region 39 */
- { { 512, 67, 67 }, -8355, 18426, 0, 0, 90, 35 }, /* region 40 */
- { { 512, 68, 68 }, -8955, 18426, 0, 0, 90, 35 }, /* region 41 */
- { { 0, 69, 69 }, -8955, 32767, 0, 0, 86, 36 }, /* region 42 */
- { { 0, 70, 70 }, -8055, 21900, 0, 0, 86, 37 }, /* region 43 */
- { { 769, 71, 71 }, -7555, 23197, 0, 1226, 35, 38 }, /* region 44 */
- { { 769, 72, 72 }, -8155, 26028, 0, 1226, 35, 38 }, /* region 45 */
- { { 1024, 73, 73 }, -9155, 32767, 0, 0, 22, 39 }, /* region 46 */
- { { 1024, 74, 74 }, -9655, 32767, 0, 0, 22, 40 }, /* region 47 */
- { { 1, 75, 75 }, -9100, 23197, 0, 31, 139, 41 }, /* region 48 */
- { { 0, 76, 76 }, -11655, 23197, 0, 0, 134, 42 }, /* region 49 */
- { { 0, 77, 77 }, -11255, 23197, 0, 0, 134, 43 }, /* region 50 */
- { { 0, 78, 78 }, -10053, 16422, 0, 0, 89, 44 }, /* region 51 */
- { { 0, 79, 79 }, -11453, 16422, 0, 0, 89, 45 }, /* region 52 */
- { { 1281, 80, 80 }, -7500, 13045, 209, 230, 103, 46 }, /* region 53 */
- { { 1281, 81, 81 }, -7600, 16422, 209, 230, 103, 47 }, /* region 54 */
- { { 0, 82, 82 }, -9655, 20675, 0, 0, 87, 48 }, /* region 55 */
- { { 0, 83, 83 }, -10100, 32767, 0, 0, 13, 49 }, /* region 56 */
- { { 1, 84, 84 }, -9600, 23197, 0, 10294, 5, 50 }, /* region 57 */
- { { 0, 85, 85 }, -10855, 32767, 0, 0, 135, 4 }, /* region 58 */
- { { 0, 86, 86 }, -10268, 16422, 0, 0, 24, 51 }, /* region 59 */
- { { 32769, 87, 87 }, -10368, 32767, 1335, 1603, 24, 52 }, /* region 60 */
- { { 1, 12, 67 }, -7805, 23197, 437, 16584, 2, 48 }, /* region 61 */
- { { 1, 68, 73 }, -8396, 23197, 452, 16803, 0, 48 }, /* region 62 */
- { { 32769, 74, 108 }, -9667, 23197, 404, 16698, 1, 48 }, /* region 63 */
- { { 1, 12, 78 }, -7805, 16422, 437, 16584, 2, 48 }, /* region 64 */
- { { 1, 79, 91 }, -8396, 16422, 452, 16803, 0, 48 }, /* region 65 */
- { { 32769, 92, 108 }, -9667, 16422, 404, 16698, 1, 48 }, /* region 66 */
- { { 1, 12, 78 }, -7805, 16422, 437, 16584, 2, 48 }, /* region 67 */
- { { 1, 79, 91 }, -8396, 16422, 452, 16803, 0, 48 }, /* region 68 */
- { { 32769, 92, 108 }, -9667, 16422, 404, 16698, 1, 48 }, /* region 69 */
- { { 1, 12, 70 }, -7800, 23197, 437, 16584, 2, 48 }, /* region 70 */
- { { 1, 71, 88 }, -8391, 23197, 452, 16803, 0, 48 }, /* region 71 */
- { { 32769, 89, 108 }, -9662, 23197, 404, 16698, 1, 48 }, /* region 72 */
- { { 1, 12, 54 }, -7156, 13045, 639, 4368, 10, 48 }, /* region 73 */
- { { 32769, 55, 108 }, -7551, 18426, 702, 3112, 12, 48 }, /* region 74 */
- { { 1, 12, 66 }, -7811, 23197, 437, 16584, 2, 48 }, /* region 75 */
- { { 1, 67, 87 }, -8402, 23197, 452, 16803, 0, 48 }, /* region 76 */
- { { 32769, 88, 108 }, -9673, 16422, 404, 16698, 1, 48 }, /* region 77 */
- { { 1, 12, 43 }, -4255, 23197, 920, 1383, 30, 59 }, /* region 78 */
- { { 32769, 44, 96 }, -6260, 18426, 885, 1176, 37, 59 }, /* region 79 */
- { { 1, 12, 48 }, -4661, 18426, 1148, 1514, 26, 60 }, /* region 80 */
- { { 32769, 49, 96 }, -7453, 16422, 1347, 1420, 29, 60 }, /* region 81 */
- { { 1, 33, 56 }, -6800, 26028, 1064, 1170, 38, 61 }, /* region 82 */
- { { 1, 57, 72 }, -7200, 26028, 930, 1014, 44, 61 }, /* region 83 */
- { { 32769, 73, 108 }, -8800, 26028, 726, 826, 52, 61 }, /* region 84 */
- { { 1, 36, 96 }, -8800, 20675, 635, 735, 58, 62 }, /* region 85 */
- { { 32769, 97, 108 }, -11308, 13045, 0, 31, 139, 62 }, /* region 86 */
- { { 1, 36, 96 }, -8800, 14636, 635, 735, 58, 0 }, /* region 87 */
- { { 32769, 97, 108 }, -11308, 13045, 0, 31, 139, 0 }, /* region 88 */
- { { 1, 36, 83 }, -7206, 13045, 838, 922, 47, 63 }, /* region 89 */
- { { 1, 84, 93 }, -9606, 14636, 209, 230, 103, 63 }, /* region 90 */
- { { 32769, 94, 108 }, -11308, 13045, 0, 31, 139, 63 }, /* region 91 */
- { { 1, 36, 83 }, -7206, 13045, 838, 922, 47, 64 }, /* region 92 */
- { { 1, 84, 93 }, -9606, 13045, 209, 230, 103, 64 }, /* region 93 */
- { { 32769, 94, 108 }, -11308, 13045, 0, 31, 139, 64 }, /* region 94 */
- { { 1, 21, 56 }, -6795, 23197, 1064, 1170, 38, 65 }, /* region 95 */
- { { 1, 57, 72 }, -7195, 23197, 930, 1014, 44, 65 }, /* region 96 */
- { { 32769, 73, 108 }, -8798, 23197, 726, 826, 52, 65 }, /* region 97 */
- { { 1, 12, 83 }, -7206, 16422, 838, 922, 47, 66 }, /* region 98 */
- { { 1, 84, 93 }, -9606, 16422, 209, 230, 103, 66 }, /* region 99 */
- { { 32769, 94, 108 }, -11308, 16422, 0, 31, 139, 66 }, /* region 100 */
- { { 1, 24, 83 }, -7206, 16422, 838, 922, 47, 67 }, /* region 101 */
- { { 1, 84, 93 }, -9606, 16422, 209, 230, 103, 67 }, /* region 102 */
- { { 32769, 94, 108 }, -11308, 16422, 0, 31, 139, 67 }, /* region 103 */
- { { 1, 12, 83 }, -7220, 16422, 0, 83, 126, 68 }, /* region 104 */
- { { 1, 84, 90 }, -9682, 16422, 0, 20, 145, 68 }, /* region 105 */
- { { 32769, 91, 108 }, -10301, 16422, 6, 20, 147, 68 }, /* region 106 */
- { { 1, 21, 75 }, -8441, 16422, 419, 460, 76, 69 }, /* region 107 */
- { { 32769, 76, 108 }, -10890, 14636, 254, 264, 101, 69 }, /* region 108 */
- { { 32769, 36, 84 }, -8955, 16422, 0, 2775, 17, 70 }, /* region 109 */
- { { 32769, 12, 108 }, -7855, 23197, 30, 276, 100, 71 }, /* region 110 */
- { { 0, 12, 60 }, -9114, 26028, 0, 0, 15, 72 }, /* region 111 */
- { { 32768, 61, 96 }, -9114, 26028, 0, 0, 15, 73 }, /* region 112 */
- { { 1, 12, 65 }, -8253, 16422, 23, 10953, 4, 74 }, /* region 113 */
- { { 32769, 66, 108 }, -8955, 20675, 11, 11753, 3, 74 }, /* region 114 */
- { { 1, 12, 35 }, -6555, 16422, 2869, 3778, 11, 75 }, /* region 115 */
- { { 1, 36, 48 }, -7755, 20675, 2869, 3778, 11, 75 }, /* region 116 */
- { { 32769, 49, 72 }, -7755, 20675, 2869, 3778, 11, 76 }, /* region 117 */
- { { 1, 16, 55 }, -7424, 20675, 1045, 1119, 41, 77 }, /* region 118 */
- { { 32769, 56, 96 }, -7918, 20675, 907, 963, 46, 77 }, /* region 119 */
- { { 1, 16, 53 }, -7194, 29204, 1140, 1479, 27, 78 }, /* region 120 */
- { { 1, 54, 70 }, -8371, 29204, 726, 812, 55, 78 }, /* region 121 */
- { { 32769, 71, 108 }, -8988, 29204, 718, 748, 56, 78 }, /* region 122 */
- { { 1, 12, 65 }, -8253, 16422, 23, 10953, 4, 79 }, /* region 123 */
- { { 32769, 66, 108 }, -8955, 20675, 11, 11753, 3, 79 }, /* region 124 */
- { { 1, 16, 54 }, -6927, 20675, 5362, 5461, 9, 80 }, /* region 125 */
- { { 1, 55, 63 }, -7051, 26028, 1362, 1454, 28, 80 }, /* region 126 */
- { { 32769, 64, 108 }, -7944, 16422, 311, 366, 88, 80 }, /* region 127 */
- { { 1, 16, 48 }, -5998, 20675, 1132, 1301, 31, 81 }, /* region 128 */
- { { 32769, 49, 108 }, -7188, 20675, 1099, 1184, 36, 81 }, /* region 129 */
- { { 1, 21, 68 }, -9658, 20675, 87, 2170, 18, 82 }, /* region 130 */
- { { 1, 69, 82 }, -10160, 20675, 120, 2167, 19, 82 }, /* region 131 */
- { { 32769, 83, 108 }, -11360, 20675, 376, 2041, 20, 82 }, /* region 132 */
- { { 1, 12, 65 }, -8253, 16422, 23, 10953, 4, 83 }, /* region 133 */
- { { 32769, 66, 108 }, -8955, 20675, 11, 11753, 3, 83 }, /* region 134 */
- { { 32769, 55, 108 }, -8568, 20675, 0, 477, 75, 84 }, /* region 135 */
- { { 32769, 36, 96 }, -8100, 14636, 101, 151, 116, 85 }, /* region 136 */
- { { 1, 24, 83 }, -7220, 13045, 0, 83, 126, 86 }, /* region 137 */
- { { 1, 84, 90 }, -9682, 13045, 0, 20, 145, 86 }, /* region 138 */
- { { 32769, 91, 108 }, -10301, 13045, 6, 20, 147, 86 }, /* region 139 */
- { { 1, 12, 65 }, -8253, 16422, 23, 10953, 4, 87 }, /* region 140 */
- { { 32769, 66, 108 }, -8955, 20675, 11, 11753, 3, 87 }, /* region 141 */
- { { 1, 12, 65 }, -8253, 16422, 23, 10953, 4, 88 }, /* region 142 */
- { { 32769, 66, 108 }, -8955, 20675, 11, 11753, 3, 88 }, /* region 143 */
- { { 1, 12, 65 }, -8253, 16422, 23, 10953, 4, 89 }, /* region 144 */
- { { 32769, 66, 108 }, -8955, 20675, 11, 11753, 3, 89 }, /* region 145 */
- { { 1, 24, 83 }, -7220, 13045, 0, 83, 126, 90 }, /* region 146 */
- { { 1, 84, 90 }, -9682, 13045, 0, 20, 145, 90 }, /* region 147 */
- { { 32769, 91, 108 }, -10301, 13045, 6, 20, 147, 90 }, /* region 148 */
- { { 1, 12, 65 }, -8253, 16422, 23, 10953, 4, 91 }, /* region 149 */
- { { 32769, 66, 108 }, -8955, 20675, 11, 11753, 3, 91 }, /* region 150 */
- { { 1, 12, 65 }, -8253, 16422, 23, 10953, 4, 92 }, /* region 151 */
- { { 32769, 66, 108 }, -8955, 20675, 11, 11753, 3, 92 }, /* region 152 */
- { { 1, 12, 62 }, -8253, 16422, 23, 10953, 4, 93 }, /* region 153 */
- { { 32769, 63, 108 }, -8955, 20675, 11, 11753, 3, 93 }, /* region 154 */
- { { 1, 12, 62 }, -8253, 16422, 23, 10953, 4, 94 }, /* region 155 */
- { { 32769, 63, 108 }, -8955, 16422, 11, 11753, 3, 94 }, /* region 156 */
- { { 1, 24, 79 }, -7220, 13045, 0, 83, 126, 95 }, /* region 157 */
- { { 1, 80, 90 }, -9682, 13045, 0, 20, 145, 95 }, /* region 158 */
- { { 32769, 91, 108 }, -10301, 13045, 6, 20, 147, 95 }, /* region 159 */
- { { 1, 12, 65 }, -8253, 13045, 23, 10953, 4, 96 }, /* region 160 */
- { { 32769, 66, 108 }, -8955, 16422, 11, 11753, 3, 96 }, /* region 161 */
- { { 32768, 36, 84 }, -8700, 20675, 0, 0, 25, 97 }, /* region 162 */
- { { 32769, 36, 96 }, -10055, 20675, 1482, 1613, 23, 98 }, /* region 163 */
- { { 32769, 12, 96 }, -5566, 32767, 818, 1033, 42, 99 }, /* region 164 */
- { { 32769, 36, 84 }, -9768, 18426, 0, 293, 98, 100 }, /* region 165 */
- { { 32769, 12, 96 }, -7220, 26028, 0, 83, 125, 101 }, /* region 166 */
- { { 32769, 12, 96 }, -7220, 20675, 0, 83, 125, 102 }, /* region 167 */
- { { 1, 12, 83 }, -7220, 13045, 0, 83, 125, 104 }, /* region 168 */
- { { 1, 84, 90 }, -9682, 13045, 0, 20, 146, 104 }, /* region 169 */
- { { 32769, 91, 108 }, -10301, 13045, 6, 20, 148, 104 }, /* region 170 */
- { { 32769, 36, 108 }, -9770, 32767, 472, 491, 74, 105 }, /* region 171 */
- { { 32769, 36, 108 }, -9770, 20675, 472, 491, 74, 106 }, /* region 172 */
- { { 1, 12, 72 }, -7212, 7336, 2, 86, 124, 107 }, /* region 173 */
- { { 1, 73, 101 }, -9700, 8231, 2, 22, 143, 107 }, /* region 174 */
- { { 32769, 102, 108 }, -10883, 20675, 173, 183, 110, 107 }, /* region 175 */
- { { 1, 21, 96 }, -8968, 13045, 477, 507, 73, 108 }, /* region 176 */
- { { 32769, 97, 108 }, -10883, 13045, 173, 183, 110, 109 }, /* region 177 */
- { { 32769, 12, 108 }, -8971, 16422, 477, 507, 73, 110 }, /* region 178 */
- { { 1, 12, 53 }, -6171, 16422, 388, 541, 68, 111 }, /* region 179 */
- { { 32769, 54, 60 }, -7149, 11626, 473, 560, 65, 111 }, /* region 180 */
- { { 32769, 36, 72 }, -7149, 16422, 473, 560, 65, 112 }, /* region 181 */
- { { 1, 48, 58 }, -8253, 16422, 356, 402, 82, 113 }, /* region 182 */
- { { 1, 59, 65 }, -8774, 16422, 514, 548, 67, 113 }, /* region 183 */
- { { 1, 66, 78 }, -9374, 16422, 505, 529, 71, 113 }, /* region 184 */
- { { 32769, 79, 96 }, -10433, 16422, 178, 191, 109, 113 }, /* region 185 */
- { { 1, 55, 60 }, -8253, 16422, 356, 402, 82, 114 }, /* region 186 */
- { { 1, 61, 69 }, -8774, 16422, 514, 548, 67, 114 }, /* region 187 */
- { { 1, 70, 79 }, -9374, 16422, 505, 529, 71, 114 }, /* region 188 */
- { { 32769, 80, 108 }, -10433, 16422, 178, 191, 109, 114 }, /* region 189 */
- { { 1, 16, 82 }, -9229, 23197, 180, 206, 106, 115 }, /* region 190 */
- { { 32769, 83, 108 }, -8440, 18426, 3, 44, 131, 115 }, /* region 191 */
- { { 32769, 21, 108 }, -10069, 20675, 483, 515, 72, 116 }, /* region 192 */
- { { 1, 21, 89 }, -8405, 18426, 3, 45, 130, 117 }, /* region 193 */
- { { 32769, 90, 108 }, -10301, 10362, 6, 20, 148, 117 }, /* region 194 */
- { { 1, 21, 42 }, -5886, 20675, 0, 180, 111, 118 }, /* region 195 */
- { { 1, 43, 51 }, -6486, 23197, 0, 127, 120, 118 }, /* region 196 */
- { { 1, 52, 58 }, -7492, 26028, 0, 71, 127, 118 }, /* region 197 */
- { { 1, 59, 68 }, -8668, 23197, 0, 36, 136, 118 }, /* region 198 */
- { { 32769, 69, 108 }, -9774, 20675, 0, 19, 149, 118 }, /* region 199 */
- { { 1, 21, 89 }, -8399, 20675, 3, 45, 130, 119 }, /* region 200 */
- { { 32769, 90, 108 }, -10301, 14636, 6, 20, 148, 119 }, /* region 201 */
- { { 1, 21, 46 }, -6851, 26028, 236, 340, 92, 120 }, /* region 202 */
- { { 1, 47, 71 }, -7763, 20675, 824, 885, 49, 120 }, /* region 203 */
- { { 1, 72, 88 }, -9107, 18426, 719, 747, 57, 120 }, /* region 204 */
- { { 1, 89, 93 }, -10076, 16422, 83, 99, 122, 120 }, /* region 205 */
- { { 32769, 94, 108 }, -10889, 16422, 173, 183, 110, 120 }, /* region 206 */
- { { 1, 60, 71 }, -8405, 16422, 0, 42, 132, 121 }, /* region 207 */
- { { 1, 72, 78 }, -9103, 16422, 0, 28, 141, 121 }, /* region 208 */
- { { 32769, 79, 96 }, -9605, 16422, 0, 21, 144, 121 }, /* region 209 */
- { { 1, 48, 65 }, -7516, 11626, 0, 70, 128, 122 }, /* region 210 */
- { { 1, 66, 79 }, -8924, 14636, 0, 31, 138, 122 }, /* region 211 */
- { { 32769, 80, 96 }, -9230, 11626, 0, 26, 142, 122 }, /* region 212 */
- { { 1, 16, 44 }, -7068, 14636, 163, 254, 102, 123 }, /* region 213 */
- { { 1, 45, 51 }, -7618, 16422, 261, 393, 85, 123 }, /* region 214 */
- { { 1, 52, 58 }, -8533, 18426, 190, 229, 104, 123 }, /* region 215 */
- { { 1, 59, 66 }, -9300, 18426, 168, 193, 108, 123 }, /* region 216 */
- { { 1, 67, 70 }, -9776, 18426, 138, 157, 115, 123 }, /* region 217 */
- { { 1, 71, 80 }, -10303, 18426, 166, 180, 112, 123 }, /* region 218 */
- { { 32769, 81, 108 }, -11274, 18426, 135, 151, 117, 123 }, /* region 219 */
- { { 32769, 12, 96 }, -6204, 23197, 570, 719, 59, 124 }, /* region 220 */
- { { 1, 12, 48 }, -7068, 14636, 163, 254, 102, 125 }, /* region 221 */
- { { 1, 49, 54 }, -7618, 16422, 261, 393, 85, 125 }, /* region 222 */
- { { 1, 55, 63 }, -8533, 18426, 190, 229, 104, 125 }, /* region 223 */
- { { 1, 64, 70 }, -9300, 18426, 168, 193, 108, 125 }, /* region 224 */
- { { 1, 71, 75 }, -9776, 18426, 138, 157, 115, 125 }, /* region 225 */
- { { 1, 76, 82 }, -10303, 18426, 166, 180, 112, 125 }, /* region 226 */
- { { 32769, 83, 108 }, -11274, 18426, 135, 151, 117, 125 }, /* region 227 */
- { { 32770, 36, 84 }, -8400, 29204, 0, 0, 0, 126 }, /* region 228 */
- { { 32770, 36, 84 }, -8800, 8231, 0, 0, 0, 127 }, /* region 229 */
- { { 32770, 36, 84 }, -8400, 20675, 0, 0, 0, 128 }, /* region 230 */
- { { 32769, 36, 84 }, -7200, -24285, 1294, 5778, 8, 129 }, /* region 231 */
- { { 32769, 36, 84 }, -7755, 29204, 798, 993, 45, 130 }, /* region 232 */
- { { 32769, 36, 84 }, -8055, 20675, 798, 993, 45, 131 }, /* region 233 */
- { { 32769, 36, 84 }, -8955, 29204, 798, 993, 45, 132 }, /* region 234 */
- { { 32768, 36, 84 }, -9355, 32767, 0, 0, 133, 133 }, /* region 235 */
- { { 32768, 36, 84 }, -7755, 20675, 0, 0, 91, 134 }, /* region 236 */
- { { 1, 24, 62 }, -8200, 23197, 286, 333, 94, 135 }, /* region 237 */
- { { 1, 63, 66 }, -8564, 26028, 297, 335, 93, 135 }, /* region 238 */
- { { 1, 67, 72 }, -8922, 23197, 368, 399, 84, 135 }, /* region 239 */
- { { 32769, 73, 96 }, -9510, 23197, 116, 138, 119, 135 }, /* region 240 */
- { { 1, 24, 48 }, -6341, 23197, 309, 447, 77, 136 }, /* region 241 */
- { { 1, 49, 56 }, -7466, 26028, 211, 283, 99, 136 }, /* region 242 */
- { { 1, 57, 63 }, -8200, 26028, 286, 333, 94, 136 }, /* region 243 */
- { { 32769, 64, 84 }, -8922, 23197, 368, 399, 84, 136 }, /* region 244 */
- { { 1, 24, 56 }, -7466, 29204, 211, 283, 99, 137 }, /* region 245 */
- { { 1, 57, 63 }, -8200, 29204, 286, 333, 94, 137 }, /* region 246 */
- { { 1, 64, 69 }, -8922, 29204, 368, 399, 84, 137 }, /* region 247 */
- { { 32769, 70, 96 }, -9510, 29204, 116, 138, 119, 137 }, /* region 248 */
- { { 1, 24, 68 }, -8922, 18426, 368, 399, 84, 138 }, /* region 249 */
- { { 1, 69, 76 }, -9510, 26028, 116, 138, 119, 138 }, /* region 250 */
- { { 32769, 77, 108 }, -9958, 23197, 127, 144, 118, 138 }, /* region 251 */
- { { 1, 24, 82 }, -8813, 23197, 389, 422, 80, 139 }, /* region 252 */
- { { 32769, 83, 108 }, -9964, 26028, 146, 163, 114, 139 }, /* region 253 */
- { { 1, 12, 58 }, -8098, 29204, 386, 436, 78, 140 }, /* region 254 */
- { { 32769, 59, 96 }, -8571, 26028, 290, 328, 95, 140 }, /* region 255 */
- { { 1, 12, 58 }, -8098, 16422, 386, 436, 78, 141 }, /* region 256 */
- { { 32769, 59, 96 }, -8571, 18426, 290, 328, 95, 141 }, /* region 257 */
- { { 1, 12, 48 }, -8098, -28771, 386, 436, 78, 142 }, /* region 258 */
- { { 32769, 49, 84 }, -8571, 29204, 290, 328, 95, 142 }, /* region 259 */
- { { 1, 12, 60 }, -6653, 20675, 314, 430, 79, 143 }, /* region 260 */
- { { 32769, 61, 84 }, -7753, 18426, 263, 324, 96, 143 }, /* region 261 */
- { { 1, 24, 60 }, -7753, 16422, 263, 324, 96, 144 }, /* region 262 */
- { { 1, 61, 70 }, -8869, 20675, 279, 311, 97, 144 }, /* region 263 */
- { { 32769, 71, 96 }, -9298, 23197, 179, 204, 107, 144 }, /* region 264 */
- { { 1, 24, 84 }, -9683, 20675, 191, 211, 105, 145 }, /* region 265 */
- { { 32769, 85, 108 }, -10883, 20675, 92, 102, 121, 145 }, /* region 266 */
- { { 1, 21, 69 }, -7753, 13045, 263, 324, 96, 146 }, /* region 267 */
- { { 1, 70, 94 }, -8869, 20675, 279, 311, 97, 146 }, /* region 268 */
- { { 1, 95, 96 }, -9298, -24285, 179, 204, 107, 146 }, /* region 269 */
- { { 32769, 97, 108 }, -10883, -24285, 173, 183, 110, 146 }, /* region 270 */
- { { 1, 16, 55 }, -9300, 20675, 168, 193, 108, 147 }, /* region 271 */
- { { 1, 56, 74 }, -9776, 26028, 138, 157, 115, 147 }, /* region 272 */
- { { 32769, 75, 96 }, -11274, 26028, 135, 151, 117, 147 }, /* region 273 */
- { { 1, 24, 72 }, -9298, 26028, 179, 204, 107, 148 }, /* region 274 */
- { { 1, 73, 85 }, -9683, 20675, 191, 211, 105, 148 }, /* region 275 */
- { { 32769, 86, 108 }, -10883, 18426, 92, 102, 121, 148 }, /* region 276 */
- { { 32769, 36, 108 }, -8930, 18426, 1839, 1901, 21, 149 }, /* region 277 */
- { { 32769, 24, 108 }, -8473, 20675, 494, 534, 69, 150 }, /* region 278 */
- { { 32769, 12, 108 }, -8473, 20675, 494, 534, 69, 151 }, /* region 279 */
- { { 32769, 24, 108 }, -8473, 20675, 494, 534, 69, 152 }, /* region 280 */
- { { 1, 36, 60 }, -6100, 5193, 2, 22, 143, 153 }, /* region 281 */
- { { 32769, 61, 84 }, -7283, 20675, 173, 183, 110, 153 }, /* region 282 */
- { { 32769, 24, 96 }, -7753, 14636, 263, 324, 96, 154 }, /* region 283 */
- { { 32769, 36, 96 }, -8930, 26028, 1839, 1901, 21, 155 }, /* region 284 */
- { { 32769, 24, 108 }, -8473, 20675, 494, 534, 69, 156 }, /* region 285 */
- { { 1, 24, 58 }, -9051, 14636, 0, 29, 140, 157 }, /* region 286 */
- { { 32769, 59, 96 }, -9051, 14636, 0, 29, 140, 157 }, /* region 287 */
- { { 1, 12, 83 }, -7220, 13045, 0, 83, 125, 158 }, /* region 288 */
- { { 1, 84, 90 }, -9682, 13045, 0, 20, 146, 158 }, /* region 289 */
- { { 32769, 91, 108 }, -10301, 13045, 6, 20, 148, 158 }, /* region 290 */
- { { 1, 21, 42 }, -5863, 26028, 1047, 1229, 34, 159 }, /* region 291 */
- { { 1, 43, 48 }, -6656, 29204, 1138, 1253, 33, 159 }, /* region 292 */
- { { 1, 49, 53 }, -7045, 26028, 559, 651, 60, 159 }, /* region 293 */
- { { 1, 54, 60 }, -7932, 26028, 508, 563, 64, 159 }, /* region 294 */
- { { 1, 61, 65 }, -8280, 32767, 819, 864, 51, 159 }, /* region 295 */
- { { 1, 66, 70 }, -8066, 26942, 981, 1032, 43, 159 }, /* region 296 */
- { { 1, 71, 76 }, -9366, 26028, 790, 814, 54, 159 }, /* region 297 */
- { { 1, 77, 82 }, -9966, 26028, 592, 609, 61, 159 }, /* region 298 */
- { { 1, 83, 87 }, -10717, 23197, 543, 554, 66, 159 }, /* region 299 */
- { { 1, 88, 96 }, -11271, 18426, 601, 609, 62, 159 }, /* region 300 */
- { { 32769, 97, 108 }, -11766, 18426, 523, 529, 70, 159 }, /* region 301 */
- { { 1, 48, 69 }, -7513, 14636, 0, 70, 128, 160 }, /* region 302 */
- { { 1, 70, 79 }, -8924, 18426, 0, 31, 138, 160 }, /* region 303 */
- { { 32769, 80, 96 }, -9230, 14636, 0, 26, 142, 160 }, /* region 304 */
- { { 1, 36, 72 }, -8334, 29204, 0, 87, 123, 161 }, /* region 305 */
- { { 32769, 73, 96 }, -9160, 29204, 0, 54, 129, 161 }, /* region 306 */
- { { 32769, 36, 96 }, -8930, 26028, 1839, 1901, 21, 162 }, /* region 307 */
- { { 32769, 12, 96 }, -5572, 32767, 818, 1033, 42, 163 }, /* region 308 */
- { { 32769, 36, 108 }, -9770, 26028, 472, 491, 74, 164 }, /* region 309 */
- { { 32769, 12, 96 }, -6204, 29204, 570, 719, 59, 165 }, /* region 310 */
- { { 1, 12, 83 }, -7220, 13045, 0, 83, 125, 166 }, /* region 311 */
- { { 1, 84, 90 }, -9682, 13045, 0, 20, 146, 166 }, /* region 312 */
- { { 32769, 91, 108 }, -10301, 13045, 6, 20, 148, 166 }, /* region 313 */
- { { 1, 21, 46 }, -6851, 32767, 236, 340, 92, 167 }, /* region 314 */
- { { 1, 47, 75 }, -7763, 26028, 824, 885, 49, 167 }, /* region 315 */
- { { 1, 76, 84 }, -9107, 23197, 719, 747, 57, 167 }, /* region 316 */
- { { 1, 85, 93 }, -10076, 20675, 83, 99, 122, 167 }, /* region 317 */
- { { 32769, 94, 108 }, -10889, 20675, 173, 183, 110, 167 }, /* region 318 */
- { { 1, 21, 46 }, -6851, 26028, 236, 340, 92, 168 }, /* region 319 */
- { { 1, 47, 71 }, -7763, 20675, 824, 885, 49, 168 }, /* region 320 */
- { { 1, 72, 88 }, -9107, 18426, 719, 747, 57, 168 }, /* region 321 */
- { { 1, 89, 93 }, -10076, 16422, 83, 99, 122, 168 }, /* region 322 */
- { { 32769, 94, 108 }, -10889, 16422, 173, 183, 110, 168 }, /* region 323 */
- { { 1, 21, 45 }, -5863, 26028, 1047, 1229, 34, 169 }, /* region 324 */
- { { 1, 46, 51 }, -6656, 29204, 1138, 1253, 33, 169 }, /* region 325 */
- { { 1, 52, 54 }, -7045, 26028, 559, 651, 60, 169 }, /* region 326 */
- { { 1, 55, 63 }, -7932, 26028, 508, 563, 64, 169 }, /* region 327 */
- { { 1, 64, 68 }, -8280, 32767, 819, 864, 51, 169 }, /* region 328 */
- { { 1, 69, 73 }, -8066, 26942, 981, 1032, 43, 169 }, /* region 329 */
- { { 1, 74, 79 }, -9366, 26028, 790, 814, 54, 169 }, /* region 330 */
- { { 1, 80, 88 }, -9966, 23197, 592, 609, 61, 169 }, /* region 331 */
- { { 1, 89, 99 }, -11271, 18426, 601, 609, 62, 169 }, /* region 332 */
- { { 32769, 100, 108 }, -11766, 18426, 523, 529, 70, 169 }, /* region 333 */
- { { 1, 21, 45 }, -5863, 26028, 1047, 1229, 34, 170 }, /* region 334 */
- { { 1, 46, 51 }, -6656, 29204, 1138, 1253, 33, 170 }, /* region 335 */
- { { 1, 52, 54 }, -7045, 26028, 559, 651, 60, 170 }, /* region 336 */
- { { 1, 55, 63 }, -7932, 26028, 508, 563, 64, 170 }, /* region 337 */
- { { 1, 64, 68 }, -8280, 32767, 819, 864, 51, 170 }, /* region 338 */
- { { 1, 69, 73 }, -8066, 26942, 981, 1032, 43, 170 }, /* region 339 */
- { { 1, 74, 79 }, -9366, 26028, 790, 814, 54, 170 }, /* region 340 */
- { { 1, 80, 88 }, -9966, 23197, 592, 609, 61, 170 }, /* region 341 */
- { { 1, 89, 99 }, -11271, 18426, 601, 609, 62, 171 }, /* region 342 */
- { { 32769, 100, 108 }, -11766, 18426, 523, 529, 70, 172 }, /* region 343 */
- { { 32769, 36, 108 }, -9770, 20675, 472, 491, 74, 173 }, /* region 344 */
- { { 32769, 12, 108 }, -8930, 20675, 1839, 1901, 21, 174 }, /* region 345 */
- { { 1, 12, 44 }, -7068, 18426, 163, 254, 102, 175 }, /* region 346 */
- { { 1, 45, 51 }, -7618, 20675, 261, 393, 85, 175 }, /* region 347 */
- { { 1, 52, 58 }, -8533, 23197, 190, 229, 104, 175 }, /* region 348 */
- { { 1, 59, 66 }, -9300, 23197, 168, 193, 108, 175 }, /* region 349 */
- { { 1, 67, 70 }, -9776, 23197, 138, 157, 115, 175 }, /* region 350 */
- { { 1, 71, 80 }, -10303, 23197, 166, 180, 112, 175 }, /* region 351 */
- { { 32769, 81, 108 }, -11274, 23197, 135, 151, 117, 175 }, /* region 352 */
- { { 1, 12, 65 }, -8253, 16422, 23, 10953, 4, 176 }, /* region 353 */
- { { 32769, 66, 108 }, -8955, 20675, 11, 11753, 3, 176 }, /* region 354 */
- { { 1, 12, 48 }, -5998, 29204, 1132, 1301, 31, 177 }, /* region 355 */
- { { 32769, 49, 108 }, -7188, 29204, 1099, 1184, 36, 177 }, /* region 356 */
- { { 1, 12, 83 }, -8441, 20675, 419, 460, 76, 178 }, /* region 357 */
- { { 32769, 84, 108 }, -11323, 20675, 0, 31, 139, 178 }, /* region 358 */
- { { 1, 55, 60 }, -8253, 18426, 356, 402, 82, 179 }, /* region 359 */
- { { 1, 61, 69 }, -8774, 18426, 514, 548, 67, 179 }, /* region 360 */
- { { 1, 70, 79 }, -9374, 18426, 505, 529, 71, 179 }, /* region 361 */
- { { 32769, 80, 108 }, -10433, 23197, 178, 191, 109, 179 }, /* region 362 */
- { { 32769, 36, 96 }, -8930, -24285, 1839, 1901, 21, 180 }, /* region 363 */
- { { 1, 12, 83 }, -7206, 16422, 838, 922, 47, 181 }, /* region 364 */
- { { 1, 84, 93 }, -9606, 18426, 209, 230, 103, 181 }, /* region 365 */
- { { 32769, 94, 108 }, -11308, 16422, 0, 31, 139, 181 }, /* region 366 */
- { { 1, 12, 56 }, -6795, 23197, 1064, 1170, 38, 182 }, /* region 367 */
- { { 1, 57, 72 }, -7195, 23197, 930, 1014, 44, 182 }, /* region 368 */
- { { 32769, 73, 108 }, -8798, 23197, 726, 826, 52, 182 }, /* region 369 */
- { { 32769, 24, 108 }, -8800, 23197, 635, 735, 58, 62 }, /* region 370 */
- { { 1, 36, 83 }, -7206, 13045, 838, 922, 47, 183 }, /* region 371 */
- { { 1, 84, 93 }, -9606, 13045, 209, 230, 103, 183 }, /* region 372 */
- { { 32769, 94, 108 }, -11308, 13045, 0, 31, 139, 183 }, /* region 373 */
- { { 1, 12, 66 }, -7811, 23197, 437, 16584, 2, 184 }, /* region 374 */
- { { 1, 67, 87 }, -8402, 23197, 452, 16803, 0, 184 }, /* region 375 */
- { { 32769, 88, 108 }, -9673, 16422, 404, 16698, 1, 184 } /* region 376 */
-}; /* end Regions */
-
-/*----------------------------------------------------------------------------
- * Programs
- *----------------------------------------------------------------------------
-*/
-const S_PROGRAM eas_programs[] =
-{
- { 7864320, 0 } /* program 0 */
-}; /* end Programs */
-
-/*----------------------------------------------------------------------------
- * Banks
- *----------------------------------------------------------------------------
-*/
-const S_BANK eas_banks[] =
-{
- { /* bank 0 */
- 30976,
- {
- 291, 324, 314, 334, 202, 319, 95, 195,
- 107, 92, 371, 89, 87, 85, 135, 82,
- 200, 192, 130, 267, 193, 302, 207, 210,
- 128, 125, 190, 120, 118, 213, 221, 271,
- 80, 78, 308, 164, 220, 310, 166, 167,
- 186, 182, 181, 179, 160, 178, 176, 115,
- 155, 153, 151, 149, 75, 73, 374, 111,
- 252, 254, 258, 305, 256, 157, 146, 137,
- 249, 237, 245, 241, 274, 262, 260, 265,
- 172, 171, 309, 277, 284, 307, 136, 344,
- 173, 168, 345, 353, 346, 70, 110, 311,
- 357, 144, 104, 67, 364, 367, 64, 288,
- 142, 140, 98, 355, 133, 123, 61, 113,
- 285, 280, 279, 278, 370, 286, 359, 283,
- 101, 236, 163, 235, 234, 233, 232, 231,
- 162, 363, 230, 281, 165, 229, 109, 228
- }
- }
-}; /* end Banks */
-
-/*----------------------------------------------------------------------------
- * Samples
- *----------------------------------------------------------------------------
-*/
-
-const EAS_SAMPLE eas_samples[] =
-{
- 0, 0, -3, -4, -6, -8, -10, -12, -12, -11, -8, -3, 3, 7, 10, 14,
- 16, 16, 15, 12, 9, 4, -4, -12, -18, -21, -21, -19, -18, -15, -10, -3,
- 10, 20, 34, 44, 51, 52, 48, 43, 38, 26, 8, -15, -37, -52, -61, -64,
- -66, -64, -59, -47, -31, -13, 4, 18, 30, 37, 40, 36, 30, 24, 19, 11,
- -2, -17, -24, -28, -28, -21, -18, -16, -10, -3, 12, 27, 39, 49, 53, 53,
- 50, 43, 37, 25, 11, -11, -31, -46, -57, -63, -66, -63, -57, -46, -34, -19,
- -3, 13, 27, 35, 39, 37, 32, 26, 20, 11, 0, -13, -20, -24, -25, -21,
- -19, -14, -8, -2, 9, 23, 37, 47, 53, 52, 49, 42, 35, 25, 13, -6,
- -28, -48, -60, -67, -67, -64, -60, -51, -39, -23, -7, 10, 23, 35, 39, 38,
- 32, 26, 21, 15, 4, -9, -20, -22, -21, -19, -14, -11, -5, 1, 9, 19,
- 31, 45, 51, 52, 47, 39, 35, 25, 15, -3, -23, -42, -58, -70, -71, -66,
- -60, -51, -43, -30, -13, 6, 22, 32, 40, 40, 38, 33, 27, 19, 9, -5,
- -17, -25, -26, -22, -16, -11, -8, -4, 7, 21, 35, 48, 53, 56, 50, 43,
- 34, 22, 13, -2, -22, -44, -63, -75, -76, -69, -61, -51, -43, -29, -13, 6,
- 23, 32, 41, 43, 41, 37, 26, 18, 7, -8, -19, -25, -25, -22, -15, -9,
- -5, 0, 10, 24, 37, 44, 48, 52, 52, 46, 33, 20, 8, -5, -20, -38,
- -59, -74, -79, -73, -67, -55, -43, -26, -11, 4, 18, 29, 41, 45, 45, 38,
- 29, 21, 11, -3, -15, -25, -27, -22, -16, -11, -8, 0, 10, 25, 38, 44,
- 47, 50, 53, 49, 37, 20, 7, -5, -17, -34, -58, -74, -82, -76, -67, -59,
- -47, -29, -12, 3, 14, 25, 38, 50, 52, 46, 33, 23, 14, 3, -11, -25,
- -28, -27, -21, -16, -13, -7, 8, 27, 41, 44, 45, 47, 54, 55, 44, 25,
- 7, -7, -18, -32, -53, -71, -81, -81, -72, -67, -55, -37, -16, 3, 15, 23,
- 34, 48, 57, 56, 44, 30, 19, 5, -12, -26, -33, -31, -25, -19, -16, -11,
- 7, 25, 45, 49, 49, 52, 57, 59, 48, 32, 11, -5, -22, -39, -56, -73,
- -82, -88, -84, -75, -60, -38, -16, 5, 21, 30, 39, 52, 59, 61, 53, 37,
- 22, 7, -12, -28, -35, -36, -30, -22, -19, -16, -2, 21, 41, 52, 51, 52,
- 57, 62, 54, 40, 18, -2, -18, -36, -54, -70, -80, -86, -87, -81, -69, -48,
- -23, 0, 18, 28, 35, 45, 57, 64, 59, 46, 27, 9, -11, -24, -30, -32,
- -29, -25, -20, -16, -5, 15, 36, 47, 50, 49, 53, 57, 54, 43, 24, 5,
- -14, -32, -50, -65, -75, -82, -86, -86, -77, -58, -32, -8, 14, 25, 30, 41,
- 56, 69, 69, 57, 36, 17, -4, -20, -29, -32, -27, -28, -27, -23, -13, 10,
- 33, 46, 50, 48, 50, 54, 55, 48, 34, 16, -6, -29, -50, -68, -75, -78,
- -82, -86, -84, -72, -47, -16, 11, 28, 34, 41, 51, 64, 70, 64, 49, 27,
- 5, -17, -30, -33, -29, -29, -30, -30, -22, -2, 23, 41, 49, 51, 51, 54,
- 56, 50, 42, 25, 4, -20, -44, -62, -70, -76, -83, -87, -89, -78, -56, -29,
- 0, 19, 31, 38, 48, 63, 72, 71, 60, 40, 14, -12, -25, -29, -26, -27,
- -33, -37, -30, -12, 11, 31, 41, 48, 51, 53, 55, 55, 51, 39, 17, -12,
- -38, -58, -67, -74, -82, -92, -98, -89, -69, -41, -13, 10, 29, 41, 50, 64,
- 72, 78, 74, 57, 29, 0, -18, -26, -28, -32, -38, -42, -38, -23, -3, 18,
- 30, 42, 52, 58, 60, 61, 57, 48, 28, 2, -30, -51, -62, -70, -81, -94,
- -101, -93, -75, -49, -23, -2, 18, 36, 50, 61, 69, 77, 78, 66, 42, 11,
- -11, -22, -27, -32, -39, -46, -46, -36, -14, 8, 25, 41, 52, 59, 62, 63,
- 62, 57, 38, 11, -20, -47, -61, -69, -78, -89, -98, -94, -80, -60, -37, -12,
- 13, 33, 48, 62, 70, 78, 81, 72, 52, 23, 0, -14, -24, -33, -43, -49,
- -49, -39, -23, -2, 15, 33, 47, 57, 63, 62, 62, 57, 40, 20, -7, -34,
- -52, -65, -74, -83, -94, -92, -81, -63, -42, -22, 0, 21, 39, 54, 63, 73,
- 79, 76, 61, 37, 12, -5, -19, -28, -37, -46, -51, -47, -32, -13, 7, 25,
- 43, 54, 58, 60, 60, 61, 48, 27, 3, -25, -45, -60, -72, -81, -90, -92,
- -84, -71, -52, -32, -9, 14, 33, 50, 61, 74, 80, 78, 67, 47, 24, 6,
- -12, -26, -37, -50, -56, -52, -37, -19, -2, 16, 35, 52, 61, 63, 61, 59,
- 51, 35, 12, -15, -38, -55, -66, -77, -83, -83, -80, -68, -55, -39, -19, 4,
- 25, 41, 54, 66, 73, 75, 68, 52, 31, 11, -7, -22, -33, -46, -54, -51,
- -39, -24, -5, 12, 32, 48, 56, 60, 61, 58, 50, 36, 17, -8, -30, -46,
- -63, -74, -80, -80, -74, -69, -58, -43, -27, -5, 15, 31, 48, 60, 68, 72,
- 68, 57, 39, 20, 2, -16, -30, -44, -51, -50, -41, -27, -10, 9, 28, 43,
- 53, 57, 57, 54, 48, 37, 19, -3, -25, -41, -56, -69, -75, -73, -69, -63,
- -59, -49, -32, -13, 9, 25, 37, 48, 58, 66, 65, 58, 42, 25, 8, -9,
- -22, -36, -41, -43, -37, -26, -14, 4, 21, 37, 48, 52, 53, 47, 42, 34,
- 21, 3, -18, -39, -51, -64, -67, -62, -60, -60, -58, -50, -36, -16, 3, 17,
- 29, 41, 49, 58, 61, 60, 49, 29, 11, -7, -19, -28, -32, -33, -30, -25,
- -14, 2, 19, 33, 41, 45, 42, 38, 36, 29, 20, 6, -14, -28, -43, -54,
- -58, -55, -50, -51, -54, -51, -41, -22, -4, 11, 19, 30, 37, 47, 55, 56,
- 51, 34, 16, 0, -15, -19, -23, -22, -22, -21, -14, 0, 15, 29, 39, 43,
- 37, 31, 25, 21, 18, 6, -11, -28, -42, -50, -51, -48, -44, -41, -44, -43,
- -41, -25, -8, 9, 16, 22, 26, 35, 43, 50, 48, 33, 16, -3, -13, -16,
- -16, -15, -13, -11, -6, 5, 16, 28, 38, 41, 35, 24, 15, 12, 10, 4,
- -11, -27, -39, -46, -46, -45, -40, -36, -36, -37, -38, -29, -13, 6, 16, 19,
- 22, 27, 37, 43, 42, 32, 19, 2, -10, -13, -12, -7, -4, -2, 2, 10,
- 18, 27, 36, 38, 32, 20, 9, 4, -2, -4, -11, -23, -34, -42, -42, -38,
- -31, -28, -29, -32, -33, -30, -18, 0, 10, 12, 12, 17, 26, 35, 36, 31,
- 19, 5, -6, -11, -9, -2, 7, 14, 13, 13, 16, 23, 31, 34, 29, 15,
- -3, -8, -10, -10, -14, -20, -26, -30, -32, -30, -25, -18, -17, -24, -31, -32,
- -26, -11, 2, 7, 8, 9, 17, 25, 29, 28, 21, 9, -2, -7, -5, 4,
- 12, 21, 24, 23, 25, 26, 29, 31, 27, 15, -2, -15, -21, -23, -23, -23,
- -28, -30, -31, -27, -19, -10, -9, -13, -21, -22, -20, -11, -4, -3, -5, -2,
- 5, 13, 17, 17, 16, 10, 6, 0, 3, 11, 23, 32, 33, 30, 28, 27,
- 24, 24, 19, 9, -6, -19, -29, -29, -26, -20, -19, -22, -24, -23, -16, -10,
- -9, -14, -20, -24, -21, -16, -10, -6, -5, 1, 5, 11, 12, 13, 11, 8,
- 6, 1, 4, 9, 23, 33, 39, 36, 32, 32, 28, 22, 17, 7, -7, -22,
- -31, -33, -31, -24, -19, -18, -18, -16, -13, -7, -6, -8, -14, -21, -24, -20,
- -15, -12, -9, -6, 0, 4, 6, 8, 8, 5, 5, 2, 7, 15, 27, 37,
- 42, 45, 41, 39, 32, 22, 13, 3, -11, -26, -37, -41, -37, -29, -21, -18,
- -15, -11, -6, -2, -2, -4, -7, -13, -16, -20, -21, -16, -14, -10, -6, -3,
- -3, 0, 3, 2, 3, 3, 9, 18, 32, 41, 46, 49, 44, 43, 35, 24,
- 12, 1, -14, -27, -39, -40, -36, -31, -22, -16, -13, -6, -3, -3, -4, -9,
- -9, -13, -16, -20, -21, -16, -15, -11, -6, -4, -4, -5, -5, -3, -3, 0,
- 10, 19, 33, 44, 51, 56, 52, 50, 40, 23, 11, -6, -19, -30, -40, -43,
- -40, -35, -24, -16, -7, 2, 6, 5, 1, -6, -9, -9, -9, -12, -19, -21,
- -21, -17, -9, -7, -9, -11, -15, -14, -9, -7, 7, 19, 36, 51, 57, 61,
- 59, 56, 48, 33, 13, -8, -24, -35, -45, -51, -46, -38, -26, -14, -7, 3,
- 11, 15, 12, 3, -5, -7, -6, -9, -15, -22, -25, -23, -17, -13, -12, -16,
- -19, -21, -18, -12, 3, 21, 38, 50, 58, 67, 65, 64, 55, 41, 21, -4,
- -25, -38, -46, -50, -49, -43, -33, -23, -11, 3, 14, 19, 16, 8, 0, -2,
- -2, 0, -8, -19, -27, -30, -25, -22, -20, -20, -22, -25, -24, -16, 1, 22,
- 43, 56, 62, 67, 68, 65, 60, 46, 24, -3, -25, -40, -45, -49, -50, -46,
- -37, -23, -10, 1, 12, 20, 20, 14, 7, 2, 3, 3, -4, -15, -26, -31,
- -30, -27, -26, -26, -29, -33, -33, -25, -8, 17, 41, 57, 65, 71, 73, 73,
- 66, 53, 33, 5, -23, -41, -48, -50, -48, -48, -40, -30, -14, 1, 12, 21,
- 24, 18, 13, 6, 5, 5, 0, -11, -25, -37, -39, -35, -31, -31, -33, -38,
- -37, -29, -12, 15, 40, 59, 67, 71, 72, 73, 69, 59, 39, 14, -16, -38,
- -50, -51, -50, -48, -45, -36, -21, -4, 12, 25, 30, 25, 18, 11, 11, 10,
- 6, -8, -25, -39, -46, -42, -38, -37, -37, -40, -42, -34, -15, 13, 40, 57,
- 66, 71, 72, 72, 69, 61, 45, 19, -10, -34, -46, -48, -47, -45, -45, -41,
- -28, -12, 7, 23, 27, 25, 18, 15, 17, 17, 12, 1, -20, -37, -47, -50,
- -46, -45, -44, -45, -46, -41, -21, 7, 37, 60, 69, 73, 72, 72, 72, 67,
- 52, 25, -6, -33, -47, -50, -47, -47, -47, -45, -35, -16, 6, 23, 31, 30,
- 24, 23, 24, 25, 18, 4, -15, -33, -50, -56, -57, -53, -48, -49, -49, -45,
- -29, 2, 35, 58, 68, 71, 72, 74, 73, 68, 56, 34, 5, -26, -43, -48,
- -45, -42, -46, -46, -41, -24, 0, 21, 33, 34, 31, 25, 27, 27, 19, 6,
- -14, -36, -55, -64, -64, -60, -50, -47, -45, -44, -31, -4, 32, 58, 71, 72,
- 68, 70, 70, 66, 57, 36, 11, -20, -43, -50, -48, -41, -37, -42, -40, -28,
- -5, 21, 36, 38, 34, 26, 29, 28, 20, 8, -13, -33, -52, -68, -69, -65,
- -55, -49, -47, -44, -31, -3, 30, 55, 67, 70, 68, 70, 70, 65, 57, 39,
- 15, -13, -38, -49, -47, -40, -35, -39, -41, -30, -9, 17, 37, 44, 45, 38,
- 32, 29, 22, 9, -10, -34, -54, -70, -75, -73, -64, -52, -45, -43, -31, -7,
- 25, 53, 67, 72, 70, 72, 70, 62, 53, 38, 16, -10, -32, -49, -50, -43,
- -35, -33, -36, -29, -10, 16, 35, 46, 46, 41, 35, 30, 23, 10, -10, -34,
- -53, -69, -75, -74, -66, -53, -45, -42, -34, -13, 17, 46, 63, 68, 66, 63,
- 65, 63, 54, 43, 24, 0, -20, -40, -43, -42, -36, -32, -32, -28, -16, 7,
- 29, 47, 52, 47, 39, 31, 21, 10, -9, -30, -50, -66, -78, -77, -71, -59,
- -49, -42, -34, -17, 9, 37, 56, 66, 66, 62, 62, 61, 56, 45, 30, 7,
- -13, -31, -39, -40, -36, -33, -32, -28, -18, 1, 21, 41, 54, 52, 44, 36,
- 26, 13, -8, -29, -48, -66, -76, -80, -74, -64, -55, -45, -34, -18, 5, 29,
- 50, 65, 68, 66, 64, 60, 59, 47, 33, 15, -5, -23, -37, -43, -41, -37,
- -35, -31, -21, -4, 16, 36, 52, 59, 54, 45, 33, 17, -5, -25, -45, -60,
- -74, -83, -82, -71, -59, -49, -37, -23, -2, 22, 43, 59, 66, 65, 64, 60,
- 58, 50, 39, 23, 2, -17, -32, -39, -40, -38, -35, -32, -23, -6, 14, 33,
- 49, 59, 58, 49, 34, 16, -5, -25, -43, -60, -74, -83, -83, -76, -63, -53,
- -40, -24, -5, 16, 36, 54, 65, 67, 65, 61, 57, 52, 43, 27, 9, -12,
- -26, -37, -40, -39, -36, -32, -28, -13, 6, 27, 46, 58, 60, 52, 39, 23,
- 5, -16, -36, -53, -66, -77, -84, -81, -72, -60, -45, -32, -15, 5, 25, 48,
- 62, 69, 71, 69, 65, 58, 50, 34, 16, -6, -24, -36, -42, -45, -44, -39,
- -33, -21, -2, 22, 43, 59, 64, 60, 47, 34, 17, -6, -28, -50, -66, -76,
- -84, -86, -82, -72, -57, -40, -21, -2, 21, 42, 58, 66, 73, 76, 71, 64,
- 53, 40, 26, 4, -17, -34, -45, -49, -48, -43, -38, -28, -10, 15, 40, 58,
- 66, 64, 56, 42, 25, 4, -21, -44, -62, -73, -81, -87, -86, -78, -65, -47,
- -31, -9, 15, 34, 52, 62, 72, 79, 80, 72, 61, 49, 34, 12, -12, -32,
- -43, -49, -54, -55, -48, -36, -16, 10, 35, 56, 67, 71, 67, 54, 38, 15,
- -10, -34, -57, -72, -85, -93, -97, -89, -76, -59, -40, -20, 8, 32, 50, 67,
- 77, 87, 89, 81, 66, 52, 35, 16, -6, -30, -47, -58, -61, -57, -50, -37,
- -19, 6, 29, 51, 65, 73, 73, 62, 44, 18, -6, -28, -49, -67, -81, -93,
- -97, -94, -83, -65, -47, -28, -5, 19, 42, 61, 76, 87, 90, 88, 80, 66,
- 48, 27, 3, -17, -40, -56, -65, -66, -58, -49, -30, -6, 17, 41, 59, 71,
- 77, 70, 56, 36, 11, -13, -34, -53, -71, -89, -98, -100, -94, -79, -62, -44,
- -21, 3, 27, 52, 74, 90, 98, 95, 86, 75, 59, 37, 12, -14, -35, -54,
- -64, -67, -64, -51, -34, -10, 11, 32, 50, 65, 73, 71, 58, 37, 14, -10,
- -29, -48, -64, -81, -93, -98, -94, -82, -63, -45, -26, -5, 16, 40, 65, 83,
- 94, 94, 84, 75, 63, 46, 23, -3, -27, -47, -58, -64, -64, -56, -39, -17,
- 3, 20, 38, 57, 71, 72, 61, 45, 24, 1, -19, -37, -56, -73, -91, -99,
- -100, -92, -74, -53, -34, -16, 7, 31, 59, 82, 97, 101, 92, 78, 65, 48,
- 29, 6, -21, -43, -55, -64, -66, -58, -40, -18, 3, 17, 32, 51, 69, 71,
- 62, 45, 27, 6, -15, -34, -50, -64, -81, -93, -99, -96, -80, -59, -40, -23,
- -4, 21, 50, 77, 94, 100, 93, 81, 67, 53, 36, 14, -12, -36, -53, -58,
- -63, -56, -42, -22, -5, 10, 23, 42, 63, 70, 62, 47, 29, 13, -6, -27,
- -43, -57, -72, -84, -98, -99, -87, -66, -44, -27, -11, 10, 38, 67, 91, 99,
- 92, 82, 70, 57, 41, 21, -3, -27, -47, -58, -63, -58, -44, -23, -5, 7,
- 17, 35, 55, 66, 61, 46, 29, 13, -4, -22, -39, -51, -65, -78, -90, -95,
- -85, -69, -47, -30, -12, 9, 30, 57, 83, 96, 91, 81, 67, 57, 42, 26,
- 6, -18, -39, -55, -62, -58, -43, -24, -8, 2, 14, 30, 47, 60, 60, 49,
- 34, 17, 0, -16, -31, -43, -58, -71, -86, -93, -86, -72, -52, -32, -15, 3,
- 22, 48, 76, 90, 89, 78, 69, 59, 46, 32, 14, -6, -27, -47, -57, -56,
- -45, -29, -12, -5, 4, 18, 37, 54, 58, 51, 36, 21, 6, -8, -20, -33,
- -52, -68, -84, -90, -85, -74, -58, -42, -22, 0, 20, 42, 67, 83, 87, 80,
- 68, 58, 47, 34, 19, 0, -20, -40, -52, -53, -45, -27, -13, -4, 6, 17,
- 33, 47, 53, 52, 38, 21, 3, -11, -24, -35, -50, -65, -80, -89, -85, -71,
- -55, -39, -21, -2, 20, 39, 59, 74, 81, 75, 67, 57, 47, 38, 23, 4,
- -17, -32, -43, -45, -39, -26, -14, -4, 4, 12, 26, 38, 47, 48, 35, 19,
- 4, -10, -20, -29, -41, -56, -71, -78, -81, -71, -56, -43, -23, -6, 15, 35,
- 49, 62, 72, 69, 63, 54, 45, 41, 28, 11, -11, -27, -37, -40, -35, -24,
- -17, -7, 2, 9, 22, 35, 46, 49, 37, 21, 4, -9, -18, -27, -41, -55,
- -71, -79, -79, -70, -53, -38, -23, -8, 9, 31, 46, 58, 63, 63, 59, 52,
- 45, 40, 32, 14, -6, -24, -32, -31, -30, -23, -18, -12, 1, 9, 21, 31,
- 41, 44, 33, 21, 5, -6, -20, -29, -43, -57, -69, -77, -73, -65, -52, -41,
- -27, -8, 11, 32, 49, 57, 64, 61, 55, 47, 39, 36, 29, 13, -8, -25,
- -36, -35, -26, -16, -9, -5, 1, 9, 22, 36, 45, 43, 33, 17, 1, -11,
- -21, -32, -45, -57, -71, -78, -73, -61, -45, -33, -23, -8, 11, 31, 46, 53,
- 57, 54, 48, 40, 34, 31, 27, 14, -4, -20, -29, -28, -22, -12, -4, 1,
- 4, 8, 21, 34, 43, 43, 31, 17, 1, -11, -22, -31, -44, -59, -72, -78,
- -70, -54, -40, -28, -19, -8, 10, 28, 45, 53, 57, 53, 43, 34, 28, 27,
- 26, 18, 0, -18, -31, -29, -20, -11, -3, 2, 5, 10, 19, 31, 43, 44,
- 34, 19, 2, -13, -23, -32, -43, -55, -68, -77, -73, -57, -41, -26, -15, -6,
- 11, 28, 43, 52, 52, 49, 41, 33, 24, 22, 21, 14, 1, -14, -25, -24,
- -18, -7, -2, 2, 7, 10, 20, 31, 40, 43, 33, 18, 3, -13, -24, -35,
- -44, -55, -70, -78, -74, -59, -40, -26, -11, 1, 13, 29, 44, 53, 57, 54,
- 45, 32, 24, 18, 13, 9, -4, -16, -26, -29, -22, -10, 1, 8, 13, 18,
- 23, 35, 42, 45, 37, 21, 5, -14, -30, -41, -49, -57, -69, -77, -76, -61,
- -39, -20, -5, 9, 20, 34, 47, 53, 55, 48, 39, 27, 14, 8, 3, 2,
- -4, -15, -23, -24, -16, -3, 6, 11, 19, 24, 30, 34, 41, 43, 35, 18,
- 1, -17, -31, -44, -52, -59, -68, -75, -73, -61, -38, -19, 1, 13, 23, 30,
- 42, 52, 52, 47, 36, 23, 14, 7, 4, 0, -6, -11, -20, -24, -18, -5,
- 7, 15, 18, 22, 28, 36, 43, 43, 38, 24, 4, -13, -30, -44, -55, -64,
- -69, -77, -76, -65, -44, -19, 1, 15, 27, 35, 46, 53, 53, 46, 36, 23,
- 11, 3, -5, -7, -9, -14, -20, -23, -19, -7, 11, 18, 21, 25, 30, 40,
- 43, 43, 38, 24, 7, -14, -30, -41, -55, -65, -73, -77, -74, -66, -49, -24,
- -2, 17, 29, 35, 44, 51, 54, 49, 35, 23, 11, 1, -6, -12, -15, -16,
- -20, -24, -21, -10, 8, 21, 27, 33, 35, 42, 48, 47, 37, 23, 7, -12,
- -28, -44, -60, -69, -75, -78, -74, -65, -49, -25, -2, 17, 30, 40, 48, 54,
- 55, 48, 36, 20, 6, -4, -9, -14, -20, -22, -24, -21, -15, -6, 7, 21,
- 32, 39, 43, 44, 49, 50, 38, 21, 4, -13, -28, -47, -62, -74, -77, -78,
- -77, -65, -48, -26, -4, 15, 28, 40, 50, 56, 54, 46, 33, 20, 9, -2,
- -10, -16, -21, -21, -23, -21, -15, -5, 9, 19, 30, 38, 42, 44, 46, 47,
- 36, 22, 6, -10, -23, -39, -57, -74, -78, -79, -75, -65, -51, -33, -11, 9,
- 25, 37, 46, 55, 56, 48, 34, 21, 10, 4, -4, -14, -20, -25, -24, -21,
- -12, -3, 8, 17, 26, 36, 47, 50, 50, 47, 36, 25, 10, -5, -21, -40,
- -57, -75, -82, -79, -75, -64, -51, -37, -16, 5, 25, 40, 48, 55, 55, 49,
- 37, 25, 15, 6, -6, -18, -26, -29, -25, -20, -16, -7, 5, 17, 29, 39,
- 49, 56, 56, 51, 39, 28, 15, 0, -17, -38, -58, -75, -86, -86, -80, -70,
- -54, -37, -16, 7, 25, 42, 50, 55, 58, 52, 40, 25, 11, 2, -5, -14,
- -21, -26, -26, -18, -12, -5, 4, 13, 25, 34, 45, 53, 55, 48, 39, 25,
- 16, 3, -13, -31, -54, -70, -83, -85, -78, -68, -55, -38, -20, 1, 20, 36,
- 46, 51, 55, 48, 39, 27, 17, 7, -5, -13, -20, -23, -23, -18, -10, -4,
- 3, 10, 21, 29, 40, 48, 52, 50, 40, 28, 20, 10, -5, -24, -48, -67,
- -82, -87, -81, -73, -56, -44, -25, -5, 15, 34, 46, 52, 55, 51, 39, 27,
- 18, 7, -2, -13, -22, -25, -24, -16, -9, 1, 8, 13, 22, 30, 42, 48,
- 50, 47, 38, 26, 15, 6, -8, -22, -41, -61, -77, -86, -81, -70, -54, -40,
- -27, -8, 12, 31, 42, 49, 50, 48, 38, 26, 16, 7, -4, -11, -18, -22,
- -21, -16, -9, 0, 9, 15, 21, 26, 35, 47, 50, 46, 36, 28, 18, 7,
- -7, -22, -37, -53, -70, -81, -83, -72, -58, -43, -30, -14, 5, 22, 37, 44,
- 46, 44, 37, 26, 17, 8, 2, -7, -12, -17, -16, -12, -6, 3, 8, 13,
- 17, 22, 31, 42, 43, 43, 35, 29, 25, 14, 2, -17, -35, -51, -65, -77,
- -80, -75, -63, -47, -34, -18, 4, 21, 32, 38, 41, 41, 36, 28, 17, 8,
- 1, -9, -12, -16, -15, -9, -2, 8, 13, 15, 17, 23, 28, 39, 43, 38,
- 30, 21, 17, 11, 4, -12, -28, -45, -60, -68, -71, -66, -58, -49, -38, -23,
- -5, 15, 27, 34, 34, 32, 28, 23, 18, 13, 4, -2, -7, -9, -7, -4,
- 5, 14, 16, 16, 14, 15, 24, 35, 39, 35, 23, 17, 15, 11, 8, -4,
- -19, -37, -53, -62, -65, -62, -57, -53, -43, -31, -14, 5, 19, 27, 31, 28,
- 26, 23, 20, 18, 11, 5, -2, -5, 0, 3, 8, 14, 16, 15, 11, 7,
- 12, 23, 32, 32, 21, 12, 10, 13, 12, 6, -9, -27, -43, -50, -55, -53,
- -51, -52, -44, -38, -23, -6, 7, 18, 22, 19, 16, 15, 16, 19, 17, 12,
- 6, 3, 7, 10, 16, 20, 23, 20, 14, 8, 9, 17, 27, 26, 17, 6,
- 3, 7, 10, 7, -5, -18, -32, -41, -46, -45, -45, -45, -44, -40, -30, -16,
- -3, 8, 15, 12, 10, 11, 16, 19, 19, 16, 12, 10, 11, 15, 20, 25,
- 26, 24, 18, 11, 6, 11, 17, 21, 15, 3, -6, -2, 4, 7, 2, -14,
- -25, -32, -36, -38, -37, -37, -35, -33, -33, -25, -15, -4, 3, 4, 0, -3,
- 2, 13, 21, 21, 20, 17, 19, 23, 27, 31, 33, 31, 24, 16, 4, 2,
- 7, 13, 13, 3, -10, -9, 0, 8, 7, -3, -15, -22, -24, -30, -32, -37,
- -39, -38, -37, -34, -28, -17, -8, -2, -4, -4, 4, 16, 26, 30, 26, 22,
- 22, 25, 29, 31, 30, 29, 24, 17, 6, -2, 7, 10, 13, 4, -11, -15,
- -10, 3, 8, 2, -10, -17, -17, -17, -23, -29, -35, -37, -34, -36, -35, -28,
- -19, -10, -11, -14, -8, 8, 21, 26, 26, 21, 24, 31, 38, 40, 38, 37,
- 33, 26, 15, 4, 1, 2, 1, -6, -19, -24, -18, -7, 2, 5, -4, -10,
- -9, -6, -7, -16, -27, -33, -35, -38, -41, -38, -32, -22, -20, -18, -10, 4,
- 20, 29, 31, 30, 28, 32, 38, 43, 42, 39, 34, 28, 14, 4, 1, 3,
- 4, -5, -21, -30, -26, -14, 1, 3, -4, -8, -8, 0, 0, -8, -15, -26,
- -29, -35, -40, -40, -36, -30, -28, -29, -22, -10, 9, 22, 28, 28, 27, 30,
- 39, 46, 50, 50, 43, 33, 21, 9, 3, 3, 1, -10, -22, -35, -34, -22,
- -8, 2, 0, -6, -7, 0, 5, -2, -9, -18, -28, -34, -41, -43, -39, -35,
- -33, -33, -25, -12, 5, 19, 26, 29, 31, 31, 39, 46, 51, 52, 47, 38,
- 27, 18, 10, 5, -3, -13, -22, -33, -36, -28, -16, -4, -2, -4, -6, 0,
- 8, 7, 0, -12, -22, -33, -40, -42, -39, -37, -38, -39, -32, -17, 2, 15,
- 24, 25, 28, 33, 39, 47, 51, 53, 51, 44, 35, 23, 15, 8, 1, -12,
- -25, -37, -41, -33, -22, -11, -4, -5, -3, 3, 10, 13, 6, -5, -17, -28,
- -38, -43, -44, -44, -44, -43, -36, -23, -7, 7, 20, 26, 29, 35, 43, 51,
- 54, 58, 56, 52, 44, 29, 18, 9, -2, -12, -28, -39, -45, -38, -26, -16,
- -7, -3, 1, 6, 12, 15, 12, 3, -11, -25, -37, -41, -43, -46, -47, -46,
- -39, -28, -15, 0, 11, 21, 25, 31, 38, 46, 53, 60, 62, 59, 53, 42,
- 32, 19, 6, -10, -27, -41, -47, -47, -39, -31, -21, -9, -2, 5, 11, 16,
- 19, 13, 2, -15, -30, -35, -37, -43, -47, -49, -42, -32, -21, -11, 0, 8,
- 19, 27, 38, 47, 51, 58, 63, 63, 59, 50, 41, 28, 10, -9, -26, -37,
- -43, -44, -40, -33, -23, -11, 0, 6, 9, 14, 15, 13, 1, -15, -25, -32,
- -34, -43, -49, -50, -43, -30, -20, -13, -9, 0, 10, 23, 36, 46, 52, 55,
- 62, 65, 66, 61, 51, 36, 15, -7, -24, -34, -42, -45, -46, -42, -34, -20,
- -5, 5, 11, 14, 16, 13, 2, -10, -18, -24, -31, -39, -49, -48, -42, -34,
- -24, -18, -15, -8, 2, 13, 29, 42, 51, 57, 62, 65, 70, 69, 60, 45,
- 20, -3, -24, -37, -43, -46, -49, -48, -39, -24, -6, 5, 12, 17, 20, 16,
- 6, -9, -15, -21, -26, -38, -50, -56, -50, -37, -26, -23, -19, -14, -4, 11,
- 27, 42, 54, 58, 63, 65, 68, 70, 63, 50, 26, 1, -21, -37, -43, -44,
- -44, -44, -40, -28, -11, 5, 10, 16, 18, 14, 5, -12, -19, -22, -24, -33,
- -47, -52, -52, -38, -25, -17, -17, -16, -10, 4, 22, 39, 53, 59, 62, 63,
- 66, 68, 66, 55, 32, 9, -17, -34, -43, -42, -39, -38, -38, -31, -19, -3,
- 10, 17, 19, 12, 3, -12, -21, -24, -24, -31, -40, -49, -52, -41, -30, -18,
- -15, -17, -10, 0, 16, 33, 47, 59, 65, 64, 65, 67, 63, 56, 38, 13,
- -12, -32, -41, -39, -35, -33, -32, -27, -17, -4, 8, 15, 16, 13, 4, -11,
- -20, -25, -27, -32, -40, -48, -52, -46, -37, -25, -18, -16, -10, 1, 16, 33,
- 49, 59, 66, 67, 65, 66, 62, 51, 38, 15, -9, -30, -38, -41, -33, -29,
- -26, -23, -17, -5, 7, 16, 15, 14, 5, -9, -19, -27, -31, -34, -40, -47,
- -52, -49, -40, -30, -22, -16, -8, 4, 19, 32, 46, 59, 67, 71, 69, 64,
- 57, 49, 36, 17, -7, -27, -38, -40, -35, -28, -23, -19, -12, -5, 6, 12,
- 16, 15, 10, -5, -19, -28, -32, -36, -39, -46, -53, -52, -45, -34, -25, -18,
- -7, 6, 20, 33, 46, 60, 67, 74, 71, 65, 56, 46, 37, 18, -2, -20,
- -33, -38, -38, -30, -22, -16, -12, -6, 2, 6, 15, 15, 11, 1, -11, -19,
- -31, -37, -42, -46, -51, -54, -53, -46, -35, -26, -14, 3, 17, 33, 45, 57,
- 67, 75, 77, 71, 62, 50, 36, 18, 0, -19, -31, -36, -37, -31, -23, -17,
- -11, -6, 1, 6, 11, 15, 14, 8, -3, -16, -27, -37, -41, -47, -52, -58,
- -60, -55, -46, -32, -16, 0, 17, 32, 46, 59, 70, 79, 80, 75, 65, 51,
- 35, 20, 2, -15, -27, -38, -42, -36, -27, -17, -10, -4, 3, 7, 12, 18,
- 19, 14, 5, -7, -22, -37, -46, -53, -57, -62, -67, -65, -58, -43, -22, 1,
- 20, 35, 48, 60, 69, 79, 82, 79, 68, 53, 36, 21, 4, -11, -24, -36,
- -40, -38, -31, -21, -14, -5, 1, 5, 11, 17, 22, 19, 14, -2, -17, -35,
- -48, -55, -63, -67, -73, -72, -64, -49, -27, -4, 19, 36, 52, 64, 73, 81,
- 85, 82, 72, 56, 36, 20, 3, -14, -24, -33, -36, -35, -32, -22, -13, -6,
- 2, 7, 10, 15, 19, 19, 17, 6, -10, -29, -48, -58, -67, -71, -75, -78,
- -72, -58, -35, -10, 16, 35, 52, 65, 74, 80, 86, 87, 79, 62, 39, 21,
- 5, -11, -22, -33, -39, -39, -34, -25, -15, -7, 3, 8, 16, 17, 21, 22,
- 19, 9, -6, -27, -47, -60, -71, -77, -80, -81, -73, -61, -39, -12, 16, 36,
- 52, 63, 73, 80, 85, 87, 76, 59, 41, 23, 8, -7, -18, -29, -36, -38,
- -33, -23, -13, -8, 1, 6, 14, 18, 19, 23, 23, 17, 1, -20, -43, -57,
- -67, -78, -83, -89, -81, -67, -45, -19, 9, 35, 55, 67, 74, 80, 87, 91,
- 83, 68, 44, 24, 6, -9, -21, -29, -36, -39, -39, -31, -20, -10, 1, 13,
- 20, 26, 26, 27, 28, 22, 8, -16, -40, -60, -75, -86, -93, -95, -89, -75,
- -52, -24, 7, 37, 57, 69, 77, 83, 90, 93, 85, 70, 48, 27, 8, -8,
- -19, -26, -32, -35, -39, -37, -28, -17, -2, 9, 19, 21, 27, 31, 32, 29,
- 12, -9, -32, -54, -71, -86, -94, -96, -90, -82, -62, -33, 2, 34, 56, 69,
- 78, 87, 94, 94, 85, 69, 49, 29, 9, -10, -21, -27, -30, -33, -37, -36,
- -29, -17, -5, 9, 19, 25, 27, 31, 33, 33, 21, -2, -25, -51, -71, -86,
- -95, -95, -92, -85, -69, -42, -8, 27, 52, 67, 74, 83, 92, 95, 89, 75,
- 56, 35, 16, -6, -17, -26, -28, -34, -41, -39, -37, -25, -9, 6, 20, 28,
- 31, 37, 37, 34, 24, 3, -20, -46, -69, -85, -96, -99, -97, -89, -73, -47,
- -11, 21, 45, 61, 73, 84, 92, 95, 89, 77, 61, 41, 20, -2, -13, -20,
- -28, -36, -43, -46, -40, -30, -16, 0, 12, 24, 30, 38, 43, 41, 33, 13,
- -14, -39, -63, -80, -93, -98, -100, -94, -76, -52, -19, 14, 38, 56, 70, 80,
- 90, 94, 88, 75, 58, 40, 22, 6, -8, -19, -25, -33, -39, -41, -38, -31,
- -19, -5, 7, 21, 31, 39, 45, 42, 32, 15, -8, -32, -55, -77, -93, -102,
- -101, -94, -80, -57, -29, 5, 34, 54, 70, 78, 88, 96, 92, 80, 62, 41,
- 24, 8, -9, -21, -32, -35, -38, -41, -39, -35, -22, -6, 6, 21, 31, 39,
- 46, 44, 35, 18, -5, -27, -49, -70, -86, -97, -102, -96, -84, -58, -30, -2,
- 26, 45, 62, 74, 82, 89, 89, 80, 66, 46, 28, 12, -3, -14, -26, -36,
- -39, -42, -40, -36, -28, -15, 0, 17, 30, 37, 45, 48, 40, 23, 3, -20,
- -43, -64, -81, -93, -98, -96, -85, -65, -38, -8, 20, 40, 55, 68, 80, 88,
- 88, 82, 68, 54, 35, 18, 2, -12, -24, -35, -40, -45, -45, -41, -33, -20,
- -4, 15, 31, 41, 49, 52, 48, 32, 13, -14, -38, -59, -77, -92, -101, -102,
- -91, -70, -45, -15, 15, 38, 53, 65, 77, 89, 91, 85, 71, 52, 38, 21,
- 5, -12, -26, -36, -42, -45, -45, -43, -34, -22, -7, 9, 26, 39, 50, 56,
- 50, 34, 14, -7, -29, -50, -69, -84, -96, -98, -90, -72, -50, -24, 7, 32,
- 48, 57, 68, 84, 91, 88, 74, 58, 44, 30, 11, -9, -26, -38, -41, -46,
- -45, -44, -38, -23, -7, 9, 24, 36, 49, 55, 51, 35, 18, -3, -24, -45,
- -64, -78, -89, -93, -90, -75, -54, -29, 0, 23, 42, 54, 67, 80, 90, 91,
- 81, 65, 48, 31, 13, -5, -24, -41, -50, -53, -51, -46, -42, -28, -10, 8,
- 23, 36, 50, 59, 56, 44, 26, 8, -13, -35, -56, -77, -89, -94, -92, -80,
- -61, -39, -11, 14, 33, 50, 63, 77, 88, 89, 81, 67, 54, 38, 21, 1,
- -23, -39, -50, -54, -53, -46, -42, -31, -17, 1, 17, 33, 46, 56, 56, 46,
- 33, 16, -4, -24, -46, -67, -82, -92, -94, -87, -67, -45, -19, 4, 22, 43,
- 62, 76, 87, 90, 87, 76, 59, 40, 20, 1, -22, -40, -55, -62, -58, -50,
- -40, -29, -17, -3, 14, 33, 49, 59, 58, 49, 35, 21, 2, -17, -39, -59,
- -76, -90, -93, -86, -70, -49, -29, -8, 12, 33, 57, 75, 84, 87, 84, 78,
- 65, 47, 28, 6, -18, -39, -58, -65, -64, -57, -44, -33, -22, -10, 6, 26,
- 44, 56, 56, 48, 40, 27, 11, -8, -30, -49, -65, -80, -86, -87, -72, -51,
- -31, -13, 5, 24, 48, 70, 81, 86, 83, 79, 69, 51, 30, 8, -16, -37,
- -55, -65, -67, -61, -48, -36, -21, -10, 5, 22, 40, 55, 58, 53, 43, 31,
- 16, -2, -23, -45, -60, -74, -82, -86, -75, -56, -36, -16, 1, 21, 44, 65,
- 81, 88, 85, 81, 72, 54, 33, 8, -18, -41, -58, -71, -74, -70, -56, -41,
- -23, -6, 8, 23, 38, 53, 60, 59, 50, 37, 22, 1, -20, -41, -56, -69,
- -79, -83, -78, -62, -42, -20, 2, 22, 41, 59, 77, 86, 87, 79, 67, 50,
- 31, 10, -15, -36, -52, -63, -69, -69, -59, -41, -23, -9, 4, 15, 29, 44,
- 55, 56, 53, 43, 27, 12, -8, -27, -44, -57, -68, -78, -77, -67, -48, -29,
- -12, 12, 32, 52, 70, 79, 84, 82, 73, 59, 38, 15, -9, -33, -52, -63,
- -71, -72, -66, -50, -30, -13, 2, 12, 27, 42, 50, 54, 54, 46, 34, 19,
- -2, -19, -35, -47, -61, -71, -72, -66, -51, -36, -19, 5, 27, 46, 63, 74,
- 79, 79, 70, 58, 41, 21, 3, -24, -44, -58, -66, -66, -65, -52, -36, -22,
- -10, 4, 18, 34, 43, 49, 52, 48, 43, 31, 14, -4, -21, -35, -51, -61,
- -66, -64, -56, -43, -29, -8, 16, 37, 54, 67, 72, 74, 70, 61, 46, 27,
- 7, -19, -40, -56, -62, -62, -63, -55, -43, -26, -10, 3, 13, 26, 38, 44,
- 47, 43, 39, 30, 19, 5, -12, -24, -40, -47, -51, -53, -51, -44, -32, -14,
- 6, 24, 41, 54, 61, 63, 61, 56, 47, 32, 13, -9, -31, -46, -56, -53,
- -54, -54, -48, -37, -18, -3, 8, 17, 27, 33, 38, 39, 39, 37, 30, 18,
- 1, -16, -29, -35, -39, -42, -47, -47, -39, -22, -3, 14, 29, 42, 51, 57,
- 56, 54, 45, 36, 20, -2, -23, -41, -50, -51, -52, -53, -51, -42, -27, -8,
- 5, 12, 19, 28, 35, 40, 39, 40, 37, 28, 12, -7, -23, -28, -30, -37,
- -43, -49, -45, -32, -15, 3, 19, 34, 45, 49, 49, 51, 47, 41, 26, 6,
- -18, -34, -43, -45, -45, -48, -51, -49, -33, -15, -2, 8, 12, 19, 26, 33,
- 38, 38, 38, 34, 25, 8, -11, -19, -20, -23, -32, -43, -48, -41, -24, -8,
- 10, 21, 31, 38, 43, 47, 48, 45, 34, 16, -9, -31, -41, -42, -42, -46,
- -52, -52, -40, -23, -6, 6, 11, 17, 24, 30, 35, 38, 39, 40, 29, 14,
- -3, -14, -14, -15, -24, -36, -47, -45, -33, -15, 3, 14, 23, 29, 35, 39,
- 44, 45, 38, 22, -3, -26, -38, -37, -37, -41, -50, -56, -45, -26, -8, 5,
- 12, 16, 22, 27, 32, 39, 41, 41, 33, 17, 1, -9, -8, -8, -16, -30,
- -41, -45, -35, -21, -5, 10, 18, 24, 28, 31, 38, 42, 39, 25, 2, -23,
- -36, -36, -37, -39, -47, -53, -47, -31, -11, 3, 12, 16, 23, 27, 32, 37,
- 40, 41, 33, 18, 2, -7, -8, -6, -10, -23, -36, -41, -35, -20, -6, 7,
- 14, 17, 24, 29, 36, 42, 40, 28, 5, -20, -35, -38, -38, -39, -45, -51,
- -46, -33, -15, 2, 13, 22, 27, 28, 27, 30, 37, 41, 35, 20, 5, -4,
- -4, -2, -3, -13, -28, -35, -32, -23, -10, 3, 11, 14, 14, 20, 28, 37,
- 40, 27, 7, -16, -31, -36, -37, -36, -41, -44, -45, -35, -18, 1, 12, 19,
- 25, 26, 27, 31, 34, 39, 34, 20, 8, 0, 0, 1, 0, -9, -23, -33,
- -34, -24, -10, 2, 8, 8, 10, 16, 27, 34, 35, 27, 10, -10, -27, -35,
- -35, -34, -39, -46, -47, -38, -22, -3, 10, 19, 26, 31, 32, 32, 35, 41,
- 39, 25, 9, -2, -3, -2, -2, -7, -19, -30, -33, -26, -14, -3, 6, 6,
- 7, 12, 26, 37, 37, 26, 10, -8, -25, -35, -39, -39, -42, -47, -49, -42,
- -27, -4, 12, 20, 29, 33, 36, 35, 35, 38, 37, 27, 10, -3, -6, -3,
- -2, -7, -16, -24, -28, -24, -13, -4, 4, 5, 7, 9, 19, 30, 33, 28,
- 12, -6, -24, -35, -40, -39, -42, -47, -47, -41, -26, -8, 10, 22, 31, 36,
- 41, 39, 34, 33, 33, 29, 15, 2, -7, -8, -6, -6, -10, -18, -24, -24,
- -15, -5, 6, 7, 7, 10, 17, 23, 23, 18, 9, -7, -23, -36, -42, -41,
- -41, -45, -45, -39, -28, -11, 7, 21, 31, 36, 39, 39, 34, 31, 33, 29,
- 19, 7, -5, -6, -6, -4, -6, -13, -17, -20, -16, -8, 1, 6, 7, 7,
- 11, 16, 20, 18, 9, -7, -24, -37, -43, -42, -42, -42, -45, -41, -28, -11,
- 7, 19, 28, 35, 40, 42, 38, 33, 29, 27, 21, 10, -2, -8, -8, -6,
- -8, -11, -13, -16, -14, -8, 1, 5, 8, 9, 15, 19, 20, 18, 9, -4,
- -18, -34, -42, -46, -47, -45, -47, -45, -36, -20, 0, 13, 26, 36, 45, 48,
- 42, 35, 29, 28, 26, 20, 6, -6, -10, -10, -6, -7, -8, -10, -14, -10,
- -7, 0, 6, 8, 13, 14, 16, 13, 7, -3, -13, -27, -37, -44, -49, -44,
- -42, -40, -37, -25, -9, 9, 23, 31, 41, 44, 44, 37, 30, 27, 28, 27,
- 15, 2, -7, -9, -6, -7, -9, -8, -13, -12, -8, -3, 4, 9, 13, 14,
- 14, 11, 6, 0, -9, -23, -34, -43, -49, -46, -42, -40, -35, -29, -13, 3,
- 19, 31, 41, 45, 43, 37, 31, 29, 30, 28, 19, 4, -5, -7, -7, -5,
- -8, -7, -9, -11, -9, -4, 0, 6, 12, 14, 13, 9, 5, -3, -9, -19,
- -28, -37, -48, -48, -45, -39, -34, -30, -18, -5, 12, 23, 34, 42, 44, 39,
- 34, 32, 31, 33, 30, 18, 8, 1, -5, -6, -5, -5, -8, -13, -16, -14,
- -7, 2, 7, 11, 10, 7, 4, -2, -7, -12, -22, -32, -45, -50, -45, -38,
- -33, -30, -24, -13, 2, 20, 31, 39, 43, 42, 38, 36, 33, 33, 33, 24,
- 14, 1, -8, -9, -7, -4, -5, -11, -16, -16, -11, -4, 2, 9, 8, 7,
- 3, -3, -6, -9, -15, -24, -38, -47, -48, -42, -35, -32, -29, -21, -9, 11,
- 27, 35, 42, 42, 42, 40, 40, 38, 36, 30, 19, 8, -4, -9, -8, -5,
- -5, -12, -18, -20, -15, -5, -2, 3, 4, 5, 6, 1, -3, -8, -12, -19,
- -31, -43, -47, -43, -36, -35, -36, -32, -19, 2, 19, 30, 38, 42, 46, 49,
- 50, 47, 43, 39, 28, 16, 1, -10, -13, -11, -9, -14, -21, -25, -20, -10,
- -4, 1, 3, 4, 7, 4, -3, -7, -7, -10, -23, -38, -47, -46, -41, -37,
- -38, -37, -27, -11, 11, 24, 33, 38, 45, 50, 53, 52, 48, 43, 37, 25,
- 10, -3, -11, -11, -11, -13, -20, -27, -29, -22, -14, -7, -2, 2, 6, 3,
- -2, -3, 0, 0, -11, -28, -41, -45, -39, -35, -36, -39, -37, -24, -7, 11,
- 22, 32, 41, 51, 55, 56, 54, 53, 50, 40, 23, 6, -5, -10, -11, -14,
- -20, -28, -34, -33, -25, -16, -10, -5, 0, 0, 1, 2, 4, 5, -4, -16,
- -29, -35, -37, -37, -35, -39, -39, -32, -19, 0, 13, 23, 36, 46, 54, 58,
- 57, 59, 56, 47, 33, 16, 3, -5, -9, -11, -19, -29, -36, -39, -33, -26,
- -18, -12, -7, -5, -2, 4, 11, 15, 10, -3, -18, -29, -32, -35, -36, -41,
- -44, -40, -30, -18, 0, 13, 28, 41, 50, 59, 63, 66, 66, 60, 44, 26,
- 11, 2, -6, -12, -19, -29, -38, -44, -41, -33, -25, -16, -9, -8, -6, 1,
- 11, 18, 16, 8, -6, -17, -27, -32, -36, -39, -43, -44, -37, -30, -12, 8,
- 26, 39, 46, 56, 64, 70, 72, 66, 51, 36, 18, 7, -4, -11, -18, -29,
- -42, -50, -51, -45, -35, -23, -14, -10, -9, 0, 14, 27, 29, 20, 7, -5,
- -15, -23, -30, -38, -45, -50, -49, -43, -30, -9, 13, 31, 41, 52, 65, 75,
- 79, 77, 66, 50, 30, 13, 3, -6, -14, -26, -41, -53, -57, -54, -44, -32,
- -23, -17, -13, -5, 10, 24, 31, 28, 20, 9, -5, -17, -26, -35, -40, -48,
- -54, -53, -44, -23, 0, 21, 35, 46, 60, 73, 81, 83, 77, 60, 42, 25,
- 11, 1, -11, -25, -42, -57, -64, -62, -54, -43, -33, -24, -17, -6, 9, 23,
- 37, 37, 33, 19, 6, -9, -20, -30, -41, -49, -57, -59, -54, -38, -16, 10,
- 31, 46, 58, 70, 78, 85, 84, 73, 54, 32, 16, 5, -5, -22, -41, -60,
- -72, -71, -66, -54, -43, -30, -19, -6, 10, 25, 41, 47, 43, 32, 20, 7,
- -10, -25, -40, -52, -61, -68, -65, -54, -34, -11, 16, 39, 57, 72, 80, 88,
- 91, 83, 67, 46, 28, 13, 1, -18, -40, -62, -77, -77, -70, -63, -54, -43,
- -30, -12, 7, 25, 40, 51, 51, 42, 31, 19, 3, -13, -32, -48, -60, -68,
- -71, -63, -49, -28, -2, 23, 46, 66, 77, 86, 92, 89, 82, 62, 43, 22,
- 7, -12, -39, -59, -74, -80, -78, -72, -63, -50, -35, -17, 5, 22, 35, 45,
- 49, 49, 42, 31, 13, -7, -25, -38, -49, -59, -66, -65, -57, -42, -20, 8,
- 34, 55, 69, 79, 84, 84, 84, 77, 64, 42, 18, -6, -29, -49, -69, -82,
- -87, -87, -78, -66, -48, -27, -4, 17, 33, 47, 56, 60, 58, 49, 31, 8,
- -18, -36, -47, -57, -67, -75, -74, -60, -36, -3, 25, 48, 65, 76, 83, 87,
- 90, 88, 77, 52, 24, -4, -26, -42, -61, -77, -91, -94, -85, -70, -54, -34,
- -11, 12, 30, 44, 56, 63, 66, 61, 43, 19, -8, -27, -39, -49, -62, -74,
- -80, -71, -49, -20, 9, 34, 56, 70, 79, 86, 93, 96, 91, 70, 41, 11,
- -18, -39, -58, -77, -91, -99, -95, -83, -65, -42, -17, 7, 27, 43, 57, 66,
- 69, 67, 55, 32, 5, -21, -32, -42, -56, -73, -84, -79, -60, -33, -5, 21,
- 44, 61, 72, 80, 92, 100, 99, 82, 54, 23, -10, -31, -51, -71, -87, -101,
- -101, -92, -76, -49, -24, 1, 21, 37, 52, 66, 72, 72, 64, 44, 18, -7,
- -23, -31, -45, -64, -79, -83, -71, -46, -18, 7, 27, 46, 62, 72, 85, 97,
- 100, 92, 65, 35, 2, -22, -40, -60, -78, -92, -100, -96, -82, -59, -29, -6,
- 15, 28, 44, 57, 65, 67, 65, 49, 27, 2, -17, -23, -35, -53, -70, -79,
- -73, -52, -27, -4, 16, 35, 54, 65, 77, 88, 95, 93, 73, 44, 12, -17,
- -38, -54, -74, -86, -97, -98, -89, -69, -37, -11, 9, 27, 42, 56, 65, 68,
- 71, 59, 39, 13, -9, -20, -30, -45, -62, -74, -75, -60, -41, -18, 3, 23,
- 43, 60, 74, 83, 91, 91, 78, 52, 22, -8, -30, -46, -66, -82, -90, -92,
- -85, -70, -44, -17, 5, 22, 33, 45, 56, 60, 63, 56, 39, 21, 5, -9,
- -20, -33, -49, -62, -70, -62, -47, -28, -9, 11, 29, 47, 60, 73, 83, 87,
- 81, 62, 32, 4, -21, -39, -60, -78, -88, -90, -86, -73, -55, -28, -2, 18,
- 30, 42, 50, 57, 58, 53, 44, 27, 15, 4, -10, -24, -40, -53, -59, -57,
- -49, -38, -21, -3, 17, 34, 49, 62, 75, 81, 76, 63, 39, 15, -11, -31,
- -50, -69, -79, -84, -82, -73, -57, -34, -7, 12, 26, 35, 42, 50, 56, 53,
- 42, 31, 20, 13, 1, -16, -30, -43, -50, -51, -49, -42, -28, -11, 7, 23,
- 38, 52, 65, 75, 73, 62, 43, 20, -2, -24, -43, -60, -69, -74, -74, -69,
- -59, -42, -19, 2, 19, 27, 34, 41, 48, 50, 45, 39, 33, 25, 13, -3,
- -18, -32, -42, -47, -49, -47, -40, -27, -8, 11, 28, 43, 57, 69, 73, 65,
- 50, 31, 8, -16, -36, -53, -63, -70, -72, -70, -62, -46, -25, -6, 11, 23,
- 30, 38, 45, 49, 50, 46, 42, 33, 22, 6, -13, -25, -37, -43, -48, -50,
- -45, -35, -18, 2, 21, 39, 51, 61, 64, 63, 53, 38, 19, -6, -30, -49,
- -59, -63, -65, -66, -64, -52, -31, -14, 2, 13, 25, 35, 42, 46, 46, 47,
- 48, 44, 33, 15, -6, -21, -32, -37, -42, -48, -46, -39, -26, -8, 12, 31,
- 45, 55, 58, 57, 51, 39, 22, 2, -21, -39, -49, -56, -59, -62, -59, -52,
- -38, -22, -9, 5, 16, 25, 32, 40, 46, 51, 54, 52, 40, 24, 5, -11,
- -20, -28, -35, -44, -48, -43, -33, -17, 0, 18, 32, 44, 48, 49, 48, 40,
- 28, 11, -10, -26, -37, -45, -52, -58, -57, -51, -41, -29, -19, -10, 3, 15,
- 27, 36, 40, 50, 59, 60, 51, 33, 15, 2, -11, -21, -34, -45, -49, -45,
- -36, -25, -11, 8, 26, 38, 43, 42, 41, 39, 31, 16, -5, -24, -31, -37,
- -43, -51, -54, -49, -40, -31, -24, -13, -3, 12, 22, 29, 33, 43, 55, 60,
- 53, 37, 18, 5, -4, -12, -23, -35, -44, -42, -35, -26, -15, -2, 15, 26,
- 33, 31, 31, 29, 28, 21, 6, -13, -27, -30, -37, -44, -48, -45, -39, -34,
- -28, -18, -8, 4, 17, 23, 31, 40, 51, 58, 56, 42, 25, 12, 2, -7,
- -16, -27, -36, -39, -37, -31, -21, -12, 3, 14, 21, 25, 23, 23, 25, 23,
- 11, -4, -16, -21, -26, -34, -39, -40, -34, -31, -30, -23, -17, -3, 9, 16,
- 23, 31, 42, 54, 57, 49, 29, 14, 7, 4, -3, -15, -26, -32, -32, -31,
- -24, -16, -5, 5, 8, 10, 9, 10, 16, 19, 14, 4, -8, -14, -16, -21,
- -29, -34, -33, -30, -29, -26, -20, -10, 2, 11, 20, 28, 40, 51, 55, 51,
- 33, 17, 9, 6, 4, -9, -20, -28, -32, -29, -25, -20, -11, -2, 3, 4,
- 1, 6, 12, 18, 16, 8, -5, -10, -14, -17, -20, -23, -25, -26, -28, -26,
- -21, -12, -2, 6, 13, 20, 29, 40, 48, 48, 37, 23, 13, 8, 7, 3,
- -6, -15, -22, -24, -24, -21, -16, -10, -6, -11, -15, -10, 1, 12, 15, 9,
- 4, 3, 1, -5, -11, -18, -18, -22, -25, -29, -27, -19, -7, 4, 10, 14,
- 21, 35, 46, 48, 40, 27, 16, 13, 11, 11, 5, -5, -14, -19, -21, -24,
- -19, -14, -13, -17, -21, -21, -11, 1, 11, 12, 5, 3, 2, 5, 6, 0,
- -6, -16, -20, -25, -26, -20, -12, -4, 1, 5, 11, 25, 38, 46, 41, 33,
- 21, 17, 15, 15, 14, 8, -3, -14, -23, -27, -26, -21, -20, -22, -26, -25,
- -20, -7, 5, 10, 10, 8, 5, 6, 6, 5, 1, -7, -14, -20, -23, -21,
- -17, -11, -4, 2, 7, 17, 29, 38, 40, 37, 30, 23, 21, 20, 17, 14,
- 5, -6, -19, -26, -29, -25, -24, -27, -28, -28, -26, -18, -4, 6, 9, 8,
- 4, 5, 10, 12, 11, 3, -8, -15, -18, -18, -15, -11, -10, -5, 1, 8,
- 16, 26, 35, 35, 31, 24, 22, 21, 22, 21, 16, 5, -12, -24, -30, -31,
- -29, -31, -32, -31, -32, -22, -12, 0, 7, 11, 12, 10, 11, 15, 13, 10,
- 2, -10, -13, -16, -17, -14, -14, -12, -6, 0, 10, 20, 26, 32, 30, 29,
- 27, 26, 28, 26, 22, 13, -2, -16, -25, -30, -32, -33, -35, -35, -34, -28,
- -19, -12, -5, 1, 5, 9, 11, 16, 17, 18, 11, 3, -4, -10, -12, -13,
- -12, -13, -14, -10, -4, 8, 20, 27, 31, 31, 28, 29, 31, 30, 26, 17,
- 5, -9, -23, -32, -37, -36, -34, -35, -34, -32, -24, -16, -7, 2, 4, 6,
- 10, 16, 17, 15, 12, 8, 3, -5, -11, -11, -10, -11, -12, -11, -5, 3,
- 13, 22, 30, 32, 27, 25, 25, 28, 27, 19, 7, -8, -22, -31, -34, -32,
- -30, -28, -31, -31, -29, -21, -12, -4, 1, 1, 3, 10, 16, 18, 18, 14,
- 12, 3, -5, -8, -7, -8, -10, -12, -12, -5, 6, 16, 26, 30, 29, 24,
- 25, 26, 29, 23, 13, -2, -16, -26, -32, -33, -30, -30, -30, -30, -29, -25,
- -18, -12, -5, -2, 2, 8, 14, 18, 16, 18, 14, 10, 4, 0, -5, -4,
- -7, -9, -14, -10, -3, 9, 19, 26, 26, 23, 23, 26, 29, 28, 21, 7,
- -10, -19, -25, -26, -27, -27, -29, -30, -32, -31, -27, -19, -13, -9, -7, 0,
- 9, 18, 24, 26, 21, 13, 9, 8, 4, -2, -6, -9, -11, -11, -7, 4,
- 16, 24, 26, 21, 19, 22, 26, 29, 23, 7, -10, -17, -19, -19, -23, -25,
- -25, -25, -26, -26, -29, -26, -17, -14, -9, -7, 1, 12, 21, 26, 23, 18,
- 13, 11, 11, 6, -4, -6, -10, -10, -9, -2, 9, 20, 25, 23, 18, 18,
- 23, 26, 24, 10, -5, -13, -17, -14, -15, -17, -20, -24, -25, -29, -31, -32,
- -28, -22, -16, -13, -8, 2, 14, 25, 27, 27, 22, 17, 15, 13, 10, 5,
- -3, -6, -8, -6, 1, 11, 18, 20, 13, 11, 15, 19, 20, 14, 4, -4,
- -12, -12, -12, -12, -14, -17, -23, -30, -35, -37, -31, -26, -20, -16, -12, -4,
- 9, 22, 28, 26, 22, 17, 14, 15, 11, 8, 6, 2, 0, -2, 4, 11,
- 16, 16, 12, 7, 8, 13, 13, 10, 1, -5, -8, -8, -8, -7, -7, -10,
- -20, -26, -34, -36, -33, -31, -29, -25, -19, -12, 4, 18, 27, 28, 23, 22,
- 18, 19, 17, 14, 9, 7, 4, 0, 2, 8, 14, 16, 12, 2, 0, 2,
- 5, 6, 2, -4, -7, -6, -2, -2, -3, -5, -11, -19, -28, -37, -37, -37,
- -34, -29, -24, -18, -8, 7, 20, 25, 25, 25, 22, 21, 21, 21, 19, 15,
- 11, 6, 6, 6, 10, 11, 6, -2, -5, -5, -2, 0, 0, 0, -4, 0,
- 2, 4, 2, -2, -8, -16, -25, -34, -39, -42, -39, -33, -26, -21, -16, -4,
- 11, 22, 25, 27, 25, 23, 23, 24, 25, 22, 17, 13, 10, 9, 12, 10,
- 4, -5, -12, -12, -11, -9, -8, -6, -5, 1, 4, 8, 10, 7, 4, -7,
- -18, -26, -34, -39, -43, -42, -34, -28, -22, -13, 2, 14, 18, 21, 23, 27,
- 30, 32, 31, 28, 23, 20, 20, 15, 14, 10, 2, -5, -13, -15, -16, -16,
- -12, -12, -5, 1, 5, 8, 8, 10, 8, 0, -13, -23, -27, -33, -40, -44,
- -41, -32, -24, -17, -6, 3, 9, 17, 22, 25, 29, 34, 39, 36, 32, 26,
- 25, 23, 19, 11, 1, -9, -16, -18, -17, -19, -21, -17, -8, 0, 4, 7,
- 8, 10, 11, 6, -4, -13, -21, -25, -35, -40, -41, -37, -26, -21, -13, -8,
- -3, 6, 15, 23, 27, 35, 40, 41, 38, 33, 31, 29, 24, 16, 5, -5,
- -16, -23, -23, -23, -18, -14, -6, 2, 3, 4, 7, 11, 13, 7, -5, -13,
- -21, -25, -32, -40, -42, -37, -28, -21, -14, -13, -9, 1, 11, 22, 27, 33,
- 39, 43, 42, 41, 33, 29, 25, 18, 7, -6, -17, -25, -24, -23, -21, -16,
- -9, 2, 6, 5, 5, 10, 15, 12, 3, -8, -16, -22, -29, -39, -44, -42,
- -34, -27, -22, -21, -17, -8, 4, 19, 29, 40, 48, 53, 51, 49, 43, 38,
- 28, 19, 6, -9, -19, -27, -30, -30, -24, -16, -10, -3, 3, 6, 5, 6,
- 9, 11, 7, 2, -7, -16, -25, -34, -37, -37, -33, -31, -28, -27, -24, -20,
- -10, 8, 22, 35, 46, 52, 53, 54, 49, 46, 37, 23, 9, -7, -18, -24,
- -30, -32, -28, -22, -12, -5, 1, 6, 4, 8, 9, 11, 9, 3, -3, -13,
- -21, -32, -37, -38, -35, -34, -32, -32, -32, -27, -14, 5, 24, 38, 48, 55,
- 56, 56, 54, 50, 40, 23, 4, -10, -18, -24, -26, -29, -29, -24, -17, -5,
- 2, 9, 9, 6, 6, 7, 12, 11, 6, -7, -18, -30, -36, -36, -37, -35,
- -38, -40, -41, -36, -24, -2, 20, 35, 47, 55, 60, 62, 62, 61, 47, 26,
- 7, -12, -18, -22, -24, -28, -33, -31, -24, -12, -2, 7, 9, 5, 4, 5,
- 11, 14, 13, 7, -8, -24, -37, -41, -38, -34, -37, -44, -50, -46, -33, -10,
- 16, 36, 49, 57, 61, 64, 66, 65, 55, 34, 11, -14, -24, -26, -26, -24,
- -30, -34, -33, -24, -7, 5, 12, 10, 5, 6, 9, 16, 22, 21, 10, -10,
- -32, -45, -44, -38, -38, -47, -61, -60, -48, -21, 11, 34, 51, 60, 63, 66,
- 70, 69, 63, 45, 18, -10, -27, -27, -23, -20, -28, -36, -37, -32, -17, -2,
- 8, 9, 5, 6, 8, 15, 24, 30, 25, 5, -22, -41, -44, -40, -38, -50,
- -64, -72, -62, -37, -3, 29, 52, 62, 66, 69, 73, 78, 72, 54, 26, -5,
- -25, -32, -29, -24, -27, -34, -37, -36, -26, -11, 5, 15, 15, 11, 9, 15,
- 26, 35, 33, 14, -14, -37, -49, -47, -45, -51, -63, -72, -66, -42, -10, 22,
- 49, 64, 69, 69, 70, 75, 73, 59, 34, 4, -20, -30, -30, -25, -24, -29,
- -36, -40, -35, -22, -2, 16, 20, 17, 14, 15, 27, 39, 41, 27, -4, -32,
- -48, -54, -53, -59, -65, -73, -71, -55, -23, 16, 49, 67, 70, 68, 71, 77,
- 78, 65, 40, 10, -17, -31, -34, -28, -24, -26, -31, -40, -40, -30, -10, 10,
- 21, 18, 15, 16, 26, 40, 48, 40, 13, -20, -44, -55, -61, -63, -69, -76,
- -76, -63, -35, 6, 41, 66, 75, 71, 71, 75, 77, 67, 44, 17, -10, -25,
- -34, -35, -29, -27, -28, -35, -40, -35, -18, 1, 16, 21, 20, 19, 25, 38,
- 47, 43, 23, -9, -34, -50, -59, -65, -72, -76, -74, -66, -43, -9, 27, 58,
- 71, 69, 70, 71, 73, 67, 48, 25, 2, -18, -28, -33, -29, -25, -25, -31,
- -39, -41, -28, -10, 8, 19, 20, 23, 27, 36, 45, 45, 31, 4, -22, -45,
- -58, -67, -74, -75, -73, -66, -50, -21, 16, 49, 67, 73, 72, 72, 74, 69,
- 53, 33, 9, -11, -25, -34, -35, -31, -27, -30, -38, -43, -33, -16, 6, 18,
- 24, 27, 30, 38, 45, 46, 34, 10, -16, -40, -61, -70, -77, -76, -72, -66,
- -52, -31, 2, 36, 60, 71, 72, 69, 71, 68, 57, 44, 20, 2, -17, -32,
- -36, -33, -31, -31, -40, -46, -41, -29, -5, 16, 27, 34, 35, 41, 49, 51,
- 41, 17, -11, -34, -56, -71, -79, -80, -76, -68, -57, -36, -10, 21, 48, 64,
- 71, 71, 73, 69, 61, 48, 32, 11, -5, -21, -31, -34, -34, -37, -43, -48,
- -45, -34, -14, 8, 25, 34, 41, 43, 49, 51, 43, 26, -2, -27, -49, -65,
- -74, -77, -74, -70, -58, -42, -20, 9, 38, 56, 64, 67, 69, 71, 66, 53,
- 37, 16, 1, -15, -30, -33, -39, -38, -41, -45, -42, -35, -15, 7, 25, 36,
- 41, 45, 49, 49, 40, 23, 1, -20, -41, -59, -71, -75, -73, -65, -57, -45,
- -28, -6, 22, 42, 56, 63, 67, 71, 70, 59, 44, 28, 12, -3, -19, -32,
- -40, -41, -46, -47, -46, -37, -20, -2, 20, 34, 45, 48, 52, 53, 42, 26,
- 4, -15, -35, -51, -65, -70, -70, -68, -61, -50, -34, -15, 9, 28, 45, 54,
- 64, 71, 72, 67, 53, 40, 24, 8, -10, -27, -37, -41, -49, -53, -53, -42,
- -25, -8, 14, 31, 43, 52, 56, 56, 46, 30, 11, -8, -26, -43, -59, -70,
- -69, -68, -62, -55, -44, -25, -4, 17, 36, 48, 62, 69, 69, 67, 57, 47,
- 33, 17, -2, -21, -33, -41, -47, -52, -53, -43, -25, -10, 9, 23, 36, 46,
- 52, 54, 47, 31, 14, -4, -19, -32, -49, -57, -62, -60, -57, -58, -51, -39,
- -19, 6, 23, 38, 51, 60, 68, 71, 67, 58, 44, 27, 7, -17, -32, -41,
- -47, -52, -54, -46, -31, -12, 7, 22, 35, 45, 51, 53, 46, 33, 18, 2,
- -12, -26, -42, -55, -61, -60, -56, -57, -55, -46, -29, -8, 10, 27, 42, 55,
- 65, 70, 69, 61, 49, 34, 16, -5, -23, -36, -45, -51, -54, -50, -35, -17,
- 3, 17, 29, 37, 44, 51, 47, 39, 21, 6, -8, -20, -31, -44, -52, -58,
- -60, -58, -58, -51, -39, -22, -4, 14, 31, 48, 62, 70, 69, 65, 57, 45,
- 28, 7, -15, -31, -44, -50, -53, -50, -39, -24, -6, 11, 24, 33, 43, 46,
- 45, 35, 25, 14, 1, -13, -23, -35, -44, -53, -57, -59, -59, -57, -47, -33,
- -15, 3, 21, 39, 56, 69, 72, 69, 60, 49, 36, 17, -5, -25, -42, -52,
- -52, -48, -40, -26, -9, 9, 20, 29, 34, 39, 40, 34, 25, 16, 6, -6,
- -16, -27, -34, -44, -50, -55, -58, -57, -52, -41, -27, -11, 11, 31, 51, 67,
- 70, 68, 61, 53, 43, 30, 7, -14, -35, -49, -54, -50, -40, -26, -13, -2,
- 9, 22, 30, 38, 41, 36, 28, 20, 12, 4, -5, -15, -26, -41, -52, -58,
- -60, -60, -59, -55, -41, -25, -5, 19, 42, 62, 74, 75, 70, 63, 55, 43,
- 22, -3, -24, -42, -51, -50, -45, -32, -22, -14, -2, 14, 28, 35, 34, 33,
- 30, 25, 21, 11, 4, -6, -18, -32, -46, -56, -61, -61, -62, -60, -51, -39,
- -16, 11, 37, 58, 70, 75, 72, 67, 58, 46, 31, 10, -17, -35, -48, -49,
- -41, -28, -17, -14, -7, 4, 18, 28, 32, 29, 27, 21, 19, 16, 7, 2,
- -11, -22, -35, -48, -57, -61, -60, -60, -56, -47, -30, -5, 23, 48, 63, 72,
- 75, 71, 64, 53, 39, 20, -2, -22, -40, -48, -45, -34, -21, -17, -10, -4,
- 10, 22, 27, 28, 29, 26, 26, 22, 14, 7, -3, -14, -30, -46, -59, -65,
- -65, -65, -64, -56, -41, -17, 15, 42, 62, 73, 77, 75, 69, 57, 43, 25,
- 6, -12, -31, -44, -46, -37, -24, -16, -11, -3, 6, 20, 24, 23, 24, 23,
- 25, 23, 16, 9, 1, -10, -23, -41, -56, -63, -67, -67, -66, -59, -47, -25,
- 3, 32, 54, 70, 75, 76, 70, 62, 47, 32, 15, -3, -21, -38, -44, -41,
- -31, -21, -15, -11, -2, 8, 18, 24, 27, 28, 29, 29, 24, 17, 8, -2,
- -17, -35, -54, -66, -73, -74, -71, -66, -55, -35, -6, 24, 50, 69, 77, 79,
- 74, 63, 51, 38, 22, 2, -17, -35, -42, -39, -32, -24, -17, -11, -5, 6,
- 13, 20, 28, 31, 33, 29, 23, 15, 10, 3, -12, -30, -51, -65, -73, -75,
- -71, -67, -58, -41, -18, 11, 38, 60, 75, 77, 74, 64, 53, 42, 31, 15,
- -7, -25, -38, -40, -37, -29, -24, -15, -11, -2, 9, 17, 28, 33, 36, 33,
- 27, 18, 13, 4, -8, -26, -48, -65, -75, -76, -72, -68, -58, -43, -18, 11,
- 37, 58, 72, 76, 73, 63, 51, 40, 28, 13, -6, -23, -35, -41, -40, -33,
- -24, -16, -9, -2, 7, 18, 29, 38, 42, 38, 31, 21, 11, 3, -10, -26,
- -47, -65, -75, -79, -75, -69, -58, -39, -19, 7, 33, 54, 71, 77, 75, 66,
- 52, 39, 27, 15, -2, -22, -35, -41, -41, -36, -27, -17, -8, 1, 11, 22,
- 33, 41, 47, 45, 35, 21, 11, 4, -7, -24, -46, -66, -77, -81, -79, -73,
- -62, -44, -24, -2, 23, 47, 69, 79, 79, 70, 57, 45, 33, 20, 5, -18,
- -36, -43, -41, -37, -32, -23, -14, -3, 8, 20, 34, 45, 53, 52, 41, 27,
- 16, 7, -5, -24, -47, -69, -83, -86, -84, -74, -62, -44, -22, 1, 24, 47,
- 66, 78, 76, 69, 57, 43, 31, 17, 5, -13, -33, -43, -46, -41, -31, -22,
- -12, 0, 11, 24, 39, 49, 57, 58, 48, 30, 15, 4, -8, -26, -52, -74,
- -86, -89, -83, -74, -60, -43, -21, 1, 22, 45, 65, 78, 79, 68, 54, 40,
- 26, 17, 7, -9, -31, -45, -46, -40, -31, -21, -11, 0, 8, 21, 39, 51,
- 60, 60, 52, 36, 19, 4, -9, -25, -49, -71, -87, -92, -89, -79, -63, -45,
- -24, 0, 22, 43, 65, 75, 80, 70, 57, 44, 30, 16, 2, -14, -31, -46,
- -52, -47, -35, -21, -9, 1, 12, 26, 44, 59, 68, 68, 59, 42, 22, 6,
- -11, -29, -49, -72, -87, -96, -95, -86, -67, -46, -23, -4, 16, 38, 59, 76,
- 82, 74, 61, 45, 31, 20, 3, -14, -30, -44, -51, -51, -41, -26, -11, 3,
- 13, 25, 44, 61, 71, 72, 59, 45, 28, 9, -10, -33, -53, -70, -83, -93,
- -96, -91, -74, -53, -27, -6, 15, 35, 53, 71, 80, 77, 66, 51, 34, 20,
- 3, -15, -30, -45, -53, -55, -48, -32, -17, 1, 16, 29, 47, 62, 73, 77,
- 67, 50, 30, 9, -10, -32, -55, -73, -86, -93, -94, -90, -76, -54, -27, -4,
- 17, 32, 48, 64, 74, 78, 68, 55, 38, 17, 1, -15, -28, -39, -47, -52,
- -49, -37, -21, -3, 16, 31, 46, 61, 70, 75, 70, 55, 36, 13, -9, -32,
- -56, -72, -84, -89, -93, -91, -81, -61, -30, -5, 18, 32, 45, 58, 71, 76,
- 70, 57, 40, 18, 1, -17, -28, -35, -45, -52, -50, -39, -25, -7, 15, 33,
- 48, 60, 67, 73, 70, 60, 42, 19, -8, -34, -57, -69, -77, -83, -87, -92,
- -85, -66, -39, -10, 12, 27, 39, 52, 62, 73, 72, 61, 46, 25, 4, -14,
- -27, -34, -41, -46, -48, -43, -30, -11, 14, 38, 53, 63, 66, 69, 72, 65,
- 48, 23, -4, -31, -56, -72, -81, -83, -87, -91, -87, -72, -46, -15, 11, 28,
- 40, 50, 60, 71, 75, 69, 54, 32, 8, -13, -29, -39, -45, -48, -50, -48,
- -40, -21, 9, 37, 57, 66, 71, 74, 75, 71, 55, 32, 2, -29, -55, -73,
- -81, -84, -87, -89, -88, -75, -49, -19, 10, 29, 39, 48, 53, 62, 72, 68,
- 58, 35, 9, -11, -27, -34, -39, -42, -44, -46, -41, -26, 5, 35, 56, 65,
- 69, 72, 73, 72, 59, 37, 9, -22, -50, -71, -83, -83, -83, -86, -88, -81,
- -55, -24, 5, 24, 37, 48, 54, 59, 64, 66, 59, 41, 17, -9, -27, -36,
- -38, -39, -42, -45, -41, -28, -2, 28, 53, 65, 68, 71, 71, 70, 58, 40,
- 16, -14, -46, -67, -79, -81, -80, -83, -87, -83, -64, -36, -4, 19, 35, 46,
- 51, 58, 65, 69, 64, 49, 26, -2, -25, -38, -41, -39, -40, -43, -45, -33,
- -8, 24, 52, 65, 72, 74, 72, 66, 55, 40, 20, -7, -38, -65, -80, -85,
- -80, -82, -84, -82, -65, -38, -9, 13, 29, 41, 49, 57, 62, 64, 59, 48,
- 29, 6, -19, -36, -39, -37, -35, -38, -39, -31, -11, 19, 47, 63, 70, 71,
- 71, 65, 55, 38, 17, -4, -33, -58, -76, -83, -79, -79, -80, -82, -70, -46,
- -19, 8, 25, 36, 43, 51, 59, 63, 62, 50, 34, 14, -9, -27, -35, -38,
- -36, -38, -39, -30, -15, 10, 34, 52, 67, 73, 74, 68, 54, 37, 21, 2,
- -21, -45, -68, -78, -81, -81, -80, -79, -70, -51, -28, -4, 17, 32, 40, 48,
- 56, 59, 57, 46, 34, 18, 3, -20, -34, -39, -35, -31, -30, -26, -13, 8,
- 31, 48, 61, 67, 69, 66, 53, 38, 16, -4, -23, -41, -58, -72, -78, -80,
- -76, -74, -64, -50, -33, -8, 12, 28, 35, 41, 50, 57, 53, 44, 31, 20,
- 10, -8, -24, -34, -34, -30, -25, -21, -13, 5, 22, 38, 52, 61, 66, 65,
- 53, 36, 15, -4, -18, -33, -45, -61, -73, -79, -78, -72, -62, -49, -33, -13,
- 3, 19, 29, 38, 48, 52, 49, 41, 29, 22, 14, 2, -11, -25, -27, -25,
- -20, -15, -8, 4, 19, 30, 42, 53, 57, 61, 50, 32, 15, -7, -18, -27,
- -37, -50, -65, -73, -72, -66, -57, -49, -37, -19, -3, 13, 23, 32, 41, 44,
- 41, 35, 29, 26, 21, 10, -2, -13, -21, -18, -14, -8, -4, 3, 12, 21,
- 29, 42, 51, 54, 49, 32, 14, -5, -15, -22, -28, -39, -55, -69, -68, -62,
- -52, -44, -37, -25, -11, 4, 16, 24, 32, 37, 35, 28, 23, 23, 23, 18,
- 8, -4, -12, -12, -8, -2, 5, 9, 14, 18, 23, 31, 41, 45, 43, 29,
- 11, -8, -18, -23, -21, -29, -43, -60, -65, -58, -50, -39, -32, -26, -17, -6,
- 8, 18, 25, 31, 29, 24, 17, 20, 24, 25, 19, 8, 0, -5, -3, 4,
- 11, 13, 12, 14, 16, 22, 31, 38, 37, 27, 9, -11, -22, -24, -22, -25,
- -36, -50, -57, -53, -46, -37, -30, -24, -17, -9, 1, 10, 16, 20, 19, 17,
- 13, 14, 21, 24, 24, 19, 10, 8, 9, 13, 18, 20, 15, 12, 11, 14,
- 21, 27, 30, 21, 8, -12, -23, -24, -22, -20, -29, -40, -49, -47, -41, -33,
- -26, -23, -20, -16, -11, -2, 7, 12, 14, 14, 13, 14, 19, 26, 30, 26,
- 20, 11, 11, 16, 21, 26, 22, 18, 15, 14, 15, 19, 20, 16, 4, -15,
- -29, -32, -27, -21, -24, -34, -40, -41, -33, -28, -24, -21, -20, -15, -14, -10,
- -5, 1, 7, 10, 10, 12, 18, 26, 36, 34, 27, 21, 17, 20, 23, 25,
- 24, 19, 11, 10, 9, 12, 16, 14, 3, -16, -32, -34, -27, -19, -20, -27,
- -34, -35, -31, -27, -22, -18, -18, -19, -19, -20, -15, -7, 2, 6, 8, 9,
- 18, 26, 38, 41, 37, 28, 21, 23, 25, 27, 25, 20, 13, 7, 3, 5,
- 9, 11, 4, -14, -31, -35, -29, -20, -18, -23, -26, -32, -29, -25, -23, -15,
- -17, -18, -21, -25, -23, -15, -6, 0, 5, 6, 16, 25, 37, 45, 43, 36,
- 27, 25, 28, 30, 29, 26, 16, 7, -2, -2, 2, 3, -2, -15, -31, -38,
- -35, -23, -15, -15, -19, -23, -26, -23, -21, -15, -12, -18, -24, -27, -25, -19,
- -9, -3, 2, 5, 12, 19, 32, 42, 45, 41, 31, 28, 31, 33, 37, 33,
- 26, 14, 4, -2, -3, -3, -5, -18, -34, -43, -42, -31, -20, -18, -17, -19,
- -18, -16, -13, -9, -8, -13, -22, -32, -32, -28, -19, -11, -6, -2, 7, 18,
- 31, 42, 46, 46, 41, 36, 32, 35, 39, 39, 30, 17, 5, -3, -3, -3,
- -7, -19, -32, -39, -41, -36, -26, -17, -12, -13, -18, -20, -14, -7, -6, -11,
- -23, -32, -34, -28, -23, -15, -9, -2, 9, 17, 28, 37, 44, 48, 45, 38,
- 32, 35, 41, 45, 37, 23, 10, 1, -3, -5, -8, -20, -35, -44, -44, -42,
- -34, -24, -14, -10, -12, -14, -11, -6, -2, -5, -15, -25, -32, -29, -24, -19,
- -15, -10, 1, 10, 20, 31, 40, 45, 48, 43, 39, 39, 45, 51, 43, 28,
- 15, 2, -4, -8, -13, -20, -34, -42, -45, -45, -36, -26, -13, -8, -11, -13,
- -8, -2, 1, -4, -13, -22, -30, -33, -28, -25, -18, -12, -5, 3, 13, 25,
- 37, 46, 47, 45, 40, 41, 47, 53, 49, 35, 21, 10, 2, -6, -11, -22,
- -32, -43, -50, -50, -47, -34, -17, -9, -9, -12, -9, 3, 7, 4, -8, -18,
- -25, -31, -31, -27, -21, -16, -11, -8, 2, 17, 31, 45, 47, 44, 40, 43,
- 54, 60, 58, 42, 26, 14, 4, -5, -14, -26, -37, -47, -54, -53, -49, -38,
- -22, -13, -9, -7, -3, 6, 11, 6, -5, -14, -22, -28, -31, -30, -29, -24,
- -18, -15, -2, 14, 29, 42, 45, 47, 45, 48, 56, 63, 59, 46, 29, 17,
- 5, -4, -11, -23, -36, -49, -53, -52, -48, -40, -29, -21, -16, -11, -2, 5,
- 6, 3, -5, -10, -13, -17, -21, -25, -26, -23, -19, -15, -8, 5, 20, 31,
- 38, 42, 41, 46, 55, 62, 63, 50, 36, 24, 12, 5, -7, -20, -33, -46,
- -51, -51, -48, -40, -33, -27, -20, -15, 0, 9, 7, 1, -6, -10, -11, -16,
- -22, -25, -30, -28, -25, -21, -11, 2, 17, 28, 32, 41, 47, 55, 64, 66,
- 64, 54, 41, 32, 19, 4, -9, -24, -37, -48, -54, -55, -51, -41, -33, -29,
- -24, -15, 0, 13, 14, 8, 1, -5, -6, -10, -17, -24, -30, -32, -33, -32,
- -22, -9, 9, 21, 25, 35, 45, 56, 67, 71, 71, 63, 49, 37, 25, 11,
- -5, -19, -32, -45, -54, -59, -54, -43, -36, -31, -27, -18, -3, 11, 13, 9,
- 2, -3, -6, -9, -13, -20, -25, -29, -33, -30, -23, -9, 2, 11, 19, 28,
- 40, 51, 63, 68, 71, 66, 55, 44, 31, 16, 1, -15, -30, -41, -50, -57,
- -56, -46, -37, -32, -30, -21, -7, 8, 17, 12, 5, 3, -2, -6, -11, -19,
- -23, -27, -33, -34, -28, -19, -6, 3, 13, 24, 38, 51, 62, 70, 72, 68,
- 60, 48, 38, 22, 6, -13, -27, -39, -46, -53, -52, -48, -42, -37, -36, -25,
- -9, 4, 11, 9, 7, 8, 6, 2, -6, -13, -20, -24, -28, -31, -30, -27,
- -19, -10, 4, 19, 33, 45, 57, 67, 74, 74, 70, 60, 47, 31, 10, -8,
- -25, -36, -42, -51, -56, -56, -51, -40, -35, -28, -16, -4, 7, 7, 10, 12,
- 13, 11, 3, -8, -18, -21, -25, -29, -33, -33, -30, -20, -8, 11, 27, 42,
- 54, 64, 72, 77, 76, 69, 56, 34, 14, -5, -20, -32, -43, -50, -57, -59,
- -57, -47, -39, -31, -17, -5, 6, 8, 9, 17, 19, 16, 5, -9, -13, -18,
- -21, -26, -33, -37, -35, -28, -15, 1, 18, 34, 47, 58, 68, 76, 77, 76,
- 65, 47, 25, 6, -12, -24, -37, -49, -57, -62, -64, -58, -50, -40, -24, -12,
- 3, 9, 13, 22, 26, 26, 17, 4, -9, -21, -25, -30, -36, -41, -44, -41,
- -27, -8, 12, 31, 44, 57, 68, 77, 81, 80, 72, 56, 34, 12, -6, -19,
- -30, -41, -53, -65, -68, -65, -56, -44, -30, -17, -8, 2, 10, 23, 31, 32,
- 25, 10, -4, -14, -20, -25, -31, -39, -45, -45, -35, -17, 2, 22, 37, 51,
- 63, 72, 79, 78, 74, 62, 43, 20, 2, -12, -24, -34, -49, -61, -69, -70,
- -63, -48, -35, -23, -11, 0, 9, 20, 31, 36, 32, 20, 7, -9, -18, -24,
- -30, -38, -47, -50, -44, -29, -9, 10, 27, 45, 60, 71, 78, 80, 78, 68,
- 54, 33, 13, -5, -18, -29, -44, -57, -68, -74, -66, -54, -41, -30, -18, -5,
- 8, 19, 26, 33, 32, 24, 13, -4, -15, -22, -24, -29, -40, -44, -42, -29,
- -14, 0, 15, 31, 48, 63, 69, 74, 74, 72, 64, 47, 27, 11, -4, -17,
- -33, -50, -66, -78, -78, -68, -54, -38, -25, -11, 4, 18, 31, 38, 40, 34,
- 21, 5, -12, -23, -28, -34, -43, -50, -51, -39, -22, -6, 10, 26, 46, 61,
- 70, 75, 79, 76, 67, 52, 34, 18, 4, -11, -27, -45, -63, -76, -78, -70,
- -57, -44, -29, -15, 0, 14, 26, 35, 39, 34, 23, 9, -7, -18, -23, -30,
- -40, -49, -51, -41, -24, -9, 5, 19, 39, 55, 67, 74, 77, 79, 72, 56,
- 39, 24, 12, -5, -23, -42, -60, -73, -78, -74, -62, -48, -33, -18, -6, 10,
- 25, 34, 37, 34, 26, 16, -2, -15, -23, -28, -32, -42, -46, -44, -31, -16,
- -4, 11, 28, 44, 56, 64, 69, 75, 73, 63, 50, 37, 22, 6, -10, -27,
- -47, -68, -81, -80, -68, -52, -39, -25, -13, 2, 17, 29, 36, 37, 32, 23,
- 4, -14, -24, -26, -26, -36, -44, -45, -36, -20, -7, 9, 25, 38, 49, 58,
- 66, 75, 77, 67, 52, 39, 26, 14, -3, -21, -43, -65, -81, -84, -74, -56,
- -40, -27, -15, -2, 15, 27, 37, 38, 35, 26, 8, -11, -23, -26, -27, -34,
- -42, -45, -40, -27, -13, 4, 19, 33, 45, 54, 60, 67, 72, 67, 57, 44,
- 32, 20, 5, -11, -32, -55, -72, -82, -76, -62, -46, -31, -21, -5, 6, 19,
- 29, 34, 33, 26, 12, -6, -17, -22, -23, -28, -38, -42, -38, -27, -14, 1,
- 14, 27, 40, 48, 53, 62, 68, 67, 58, 44, 32, 21, 9, -5, -22, -43,
- -63, -76, -75, -62, -46, -30, -24, -13, 0, 10, 20, 28, 31, 27, 12, -5,
- -16, -20, -19, -21, -29, -35, -35, -27, -16, -6, 9, 21, 33, 41, 47, 53,
- 61, 63, 60, 51, 39, 27, 15, 3, -13, -33, -55, -72, -75, -67, -52, -37,
- -26, -18, -7, 4, 15, 26, 27, 25, 14, 0, -10, -15, -16, -19, -24, -31,
- -32, -27, -17, -5, 5, 15, 26, 35, 43, 49, 54, 57, 57, 52, 42, 29,
- 18, 10, -3, -23, -46, -64, -71, -66, -53, -39, -27, -19, -11, 0, 5, 16,
- 22, 23, 15, 1, -10, -15, -18, -17, -17, -20, -24, -22, -14, -4, 7, 16,
- 25, 31, 36, 41, 47, 49, 49, 46, 41, 32, 21, 13, 3, -14, -33, -51,
- -60, -60, -52, -39, -28, -20, -14, -7, 1, 9, 14, 16, 10, 1, -10, -15,
- -14, -15, -15, -15, -17, -14, -11, -4, 5, 13, 22, 29, 33, 35, 39, 43,
- 45, 45, 42, 35, 26, 17, 7, -10, -25, -38, -48, -53, -53, -46, -33, -23,
- -16, -13, -8, -3, 4, 9, 7, 1, -6, -10, -13, -12, -12, -8, -7, -6,
- -2, 3, 6, 10, 14, 23, 28, 29, 30, 29, 34, 39, 40, 36, 30, 21,
- 13, 1, -15, -27, -36, -44, -48, -45, -36, -26, -17, -13, -10, -6, -2, 2,
- 3, -3, -6, -10, -14, -13, -12, -7, -3, 1, 2, 5, 6, 10, 15, 19,
- 25, 25, 26, 26, 29, 34, 35, 32, 29, 20, 13, 4, -12, -20, -27, -33,
- -38, -41, -36, -27, -19, -13, -10, -8, -8, -7, -5, -5, -7, -9, -13, -18,
- -15, -12, -5, 3, 7, 10, 10, 11, 13, 20, 27, 27, 23, 20, 20, 24,
- 27, 25, 26, 23, 17, 7, -6, -13, -16, -20, -26, -32, -33, -28, -20, -13,
- -12, -12, -16, -15, -15, -12, -10, -13, -13, -16, -12, -7, 0, 9, 14, 18,
- 18, 14, 11, 14, 18, 21, 17, 10, 11, 15, 20, 21, 20, 20, 17, 9,
- 2, -5, -10, -14, -21, -25, -29, -27, -23, -17, -13, -13, -16, -18, -20, -20,
- -12, -8, -9, -15, -16, -10, -2, 9, 14, 18, 18, 18, 14, 14, 17, 20,
- 18, 12, 8, 11, 13, 16, 18, 19, 16, 9, 3, 1, 1, -6, -13, -20,
- -23, -21, -19, -15, -15, -14, -17, -21, -22, -22, -17, -11, -11, -13, -18, -14,
- -4, 12, 21, 22, 23, 21, 20, 17, 16, 16, 12, 7, 1, 5, 7, 8,
- 12, 15, 15, 10, 3, 0, 3, 1, -5, -12, -19, -19, -16, -11, -9, -11,
- -14, -23, -28, -29, -24, -17, -13, -15, -19, -18, -10, 7, 22, 29, 30, 24,
- 22, 18, 17, 17, 11, 4, -2, -3, 2, 4, 8, 13, 16, 13, 7, 4,
- 9, 8, 2, -7, -16, -15, -14, -12, -10, -12, -12, -19, -25, -29, -25, -18,
- -15, -18, -21, -19, -12, 1, 16, 28, 34, 32, 29, 23, 18, 15, 11, 4,
- -3, -10, -8, -5, 0, 7, 12, 14, 10, 6, 10, 15, 13, 3, -7, -11,
- -13, -13, -13, -12, -14, -20, -28, -31, -29, -20, -13, -14, -18, -18, -15, -3,
- 12, 24, 33, 32, 29, 25, 22, 16, 11, 3, -3, -6, -7, -8, -3, 2,
- 8, 11, 11, 9, 10, 13, 13, 8, 0, -6, -9, -9, -9, -10, -11, -18,
- -26, -30, -29, -22, -17, -18, -20, -21, -17, -7, 6, 21, 34, 38, 34, 29,
- 21, 17, 13, 8, 1, -8, -13, -15, -10, -3, 5, 10, 11, 10, 11, 15,
- 16, 11, 3, -4, -7, -9, -8, -10, -13, -19, -26, -26, -23, -17, -15, -16,
- -17, -17, -15, -9, -2, 10, 26, 31, 31, 24, 21, 18, 13, 6, 1, -6,
- -8, -9, -8, -4, 0, 6, 10, 12, 15, 14, 13, 9, 5, -2, -7, -8,
- -9, -8, -10, -18, -25, -25, -23, -18, -16, -19, -22, -18, -16, -10, 0, 10,
- 24, 33, 35, 29, 22, 17, 13, 7, -3, -8, -12, -14, -12, -7, -3, 4,
- 10, 14, 16, 17, 16, 16, 11, 3, -7, -11, -10, -7, -10, -19, -26, -27,
- -23, -17, -14, -14, -17, -18, -16, -12, -3, 7, 20, 26, 28, 24, 20, 16,
- 15, 10, 2, -8, -13, -11, -7, -2, -2, 4, 6, 9, 14, 17, 19, 15,
- 8, -4, -12, -15, -11, -5, -8, -18, -25, -24, -17, -9, -6, -7, -11, -15,
- -15, -13, -6, 4, 11, 15, 16, 15, 16, 13, 9, 5, 1, -3, -7, -5,
- -2, 3, 5, 6, 8, 10, 14, 17, 18, 14, 3, -8, -15, -13, -9, -6,
- -9, -19, -22, -19, -13, -6, -4, -5, -8, -13, -15, -10, -5, 5, 8, 8,
- 8, 11, 14, 14, 8, 2, 1, 1, 2, -2, 1, 5, 6, 7, 7, 6,
- 11, 13, 16, 13, 3, -6, -13, -14, -8, -5, -6, -15, -20, -15, -10, -5,
- -2, -6, -6, -8, -12, -10, -8, -3, 5, 3, 3, 5, 7, 10, 6, 2,
- -3, -2, 2, 8, 9, 12, 11, 8, 9, 8, 11, 13, 11, 10, 0, -12,
- -20, -21, -13, -10, -11, -14, -16, -10, -3, 4, 8, 5, 2, -2, -4, -4,
- -7, -4, -4, -5, -7, -8, -5, 0, 2, 2, 0, 1, 6, 11, 15, 19,
- 19, 18, 14, 10, 12, 12, 11, 6, -6, -16, -23, -23, -17, -13, -12, -12,
- -13, -8, -2, 8, 13, 13, 8, 4, 1, -3, -3, -3, -4, -11, -16, -16,
- -13, -9, -5, -4, -2, 1, 6, 13, 17, 21, 24, 23, 18, 14, 10, 11,
- 12, 8, -3, -16, -26, -27, -20, -17, -21, -21, -17, -7, 2, 10, 16, 19,
- 18, 13, 10, 5, 2, -2, -5, -14, -22, -26, -21, -15, -11, -11, -6, -2,
- 6, 16, 22, 27, 28, 28, 23, 17, 13, 10, 12, 7, -4, -18, -29, -32,
- -24, -20, -21, -22, -18, -5, 5, 14, 19, 21, 20, 17, 13, 8, 5, -2,
- -9, -18, -26, -26, -21, -14, -12, -11, -8, -2, 10, 16, 21, 24, 25, 27,
- 24, 16, 11, 6, 7, 6, -4, -16, -25, -29, -25, -19, -19, -22, -18, -7,
- 6, 15, 17, 18, 19, 18, 15, 10, 8, 3, -5, -15, -24, -30, -27, -19,
- -15, -15, -13, -8, 5, 14, 20, 25, 28, 31, 30, 26, 18, 11, 9, 7,
- -2, -14, -27, -33, -30, -25, -25, -27, -26, -15, 2, 17, 22, 23, 23, 22,
- 22, 18, 14, 7, -4, -14, -24, -31, -30, -25, -19, -16, -16, -11, -3, 8,
- 17, 24, 29, 31, 31, 29, 22, 17, 12, 8, 2, -12, -26, -36, -35, -30,
- -26, -26, -29, -20, -5, 13, 24, 26, 26, 26, 28, 23, 19, 11, 1, -9,
- -24, -34, -33, -30, -24, -21, -21, -17, -11, 1, 9, 19, 27, 33, 34, 30,
- 28, 24, 21, 16, 7, -6, -23, -35, -40, -36, -33, -31, -32, -27, -13, 3,
- 17, 25, 29, 34, 34, 30, 23, 17, 11, 0, -14, -27, -32, -33, -30, -26,
- -21, -18, -15, -9, 1, 11, 22, 29, 32, 33, 30, 28, 23, 21, 13, 3,
- -15, -30, -37, -38, -35, -35, -33, -28, -18, -5, 10, 22, 30, 37, 36, 32,
- 26, 21, 14, 7, -6, -19, -28, -34, -32, -27, -21, -20, -21, -20, -11, 5,
- 17, 25, 29, 30, 33, 35, 31, 27, 19, 8, -7, -25, -37, -42, -41, -39,
- -35, -30, -22, -11, 4, 21, 32, 38, 39, 36, 29, 22, 15, 9, -4, -15,
- -24, -32, -35, -31, -24, -18, -18, -19, -14, -3, 11, 21, 27, 31, 32, 34,
- 34, 31, 27, 18, 1, -19, -33, -39, -38, -40, -39, -35, -28, -17, -3, 14,
- 28, 37, 41, 40, 34, 30, 24, 18, 7, -6, -20, -30, -36, -34, -30, -26,
- -26, -27, -26, -16, 0, 16, 26, 30, 33, 36, 42, 43, 38, 27, 10, -10,
- -27, -39, -43, -43, -43, -40, -34, -26, -14, 2, 21, 36, 42, 40, 36, 33,
- 30, 24, 16, 5, -11, -25, -34, -35, -32, -29, -30, -31, -31, -27, -15, 5,
- 21, 27, 30, 34, 42, 51, 48, 40, 20, -3, -21, -32, -38, -40, -43, -42,
- -38, -30, -18, -3, 15, 29, 40, 41, 39, 34, 31, 28, 20, 10, -4, -18,
- -29, -33, -34, -34, -35, -37, -38, -34, -21, -6, 12, 22, 26, 33, 44, 55,
- 56, 46, 26, 5, -11, -25, -36, -42, -47, -47, -43, -37, -24, -11, 9, 25,
- 36, 38, 38, 40, 39, 39, 28, 17, 3, -10, -23, -30, -37, -38, -42, -44,
- -43, -40, -30, -16, 3, 17, 26, 34, 44, 57, 61, 52, 34, 9, -7, -21,
- -30, -38, -46, -49, -48, -39, -27, -13, 5, 22, 32, 35, 35, 37, 41, 43,
- 33, 19, 4, -8, -16, -25, -32, -39, -42, -44, -42, -41, -33, -20, -4, 11,
- 21, 28, 38, 49, 58, 54, 36, 16, -6, -16, -21, -28, -36, -46, -49, -42,
- -29, -17, 0, 13, 26, 30, 30, 35, 41, 47, 41, 25, 9, -4, -12, -17,
- -28, -38, -46, -52, -51, -49, -39, -23, -9, 4, 12, 23, 39, 54, 66, 62,
- 43, 23, 2, -10, -16, -26, -36, -45, -51, -50, -37, -20, 0, 16, 27, 28,
- 29, 38, 47, 50, 44, 28, 13, -2, -10, -16, -26, -35, -45, -55, -57, -56,
- -44, -27, -13, -4, 5, 17, 34, 53, 64, 64, 46, 29, 13, 1, -8, -17,
- -28, -39, -48, -51, -42, -26, -8, 9, 18, 20, 24, 34, 46, 53, 47, 33,
- 15, 4, -4, -13, -22, -35, -47, -56, -59, -56, -48, -32, -18, -8, 3, 14,
- 33, 52, 65, 64, 49, 31, 17, 5, -3, -13, -25, -36, -45, -49, -44, -31,
- -14, 7, 16, 21, 21, 31, 48, 57, 53, 38, 20, 8, -3, -9, -21, -35,
- -47, -57, -62, -62, -54, -38, -22, -12, -5, 7, 26, 49, 66, 69, 56, 37,
- 24, 15, 6, -4, -17, -30, -43, -53, -47, -34, -18, -2, 9, 14, 17, 29,
- 46, 58, 56, 43, 25, 13, 2, -5, -15, -30, -45, -59, -66, -65, -57, -43,
- -28, -16, -10, 2, 21, 44, 66, 71, 62, 43, 28, 19, 13, 3, -12, -25,
- -42, -51, -50, -38, -18, -3, 5, 12, 17, 30, 48, 59, 58, 45, 26, 11,
- 0, -6, -15, -29, -45, -63, -71, -68, -58, -41, -28, -19, -12, -4, 16, 42,
- 62, 70, 61, 43, 29, 21, 16, 8, -6, -20, -35, -45, -45, -37, -21, -6,
- 3, 8, 14, 24, 42, 54, 58, 47, 29, 16, 3, -3, -12, -27, -42, -62,
- -73, -74, -66, -52, -34, -23, -14, -5, 12, 38, 60, 72, 68, 49, 34, 23,
- 17, 10, -3, -18, -31, -42, -42, -36, -20, -4, 5, 9, 11, 22, 37, 51,
- 55, 46, 29, 13, 2, -9, -14, -25, -38, -53, -67, -72, -67, -53, -35, -23,
- -17, -10, 6, 32, 55, 69, 67, 53, 36, 26, 19, 12, 2, -13, -26, -37,
- -40, -36, -24, -7, 3, 9, 13, 20, 36, 49, 52, 47, 32, 17, 3, -12,
- -19, -29, -38, -52, -66, -75, -72, -56, -36, -20, -15, -10, 2, 25, 48, 63,
- 63, 52, 39, 28, 20, 14, 5, -6, -19, -30, -38, -35, -25, -8, 4, 8,
- 11, 17, 33, 47, 54, 47, 34, 18, 4, -9, -19, -28, -40, -53, -65, -75,
- -74, -60, -41, -22, -15, -12, -2, 18, 43, 59, 63, 55, 41, 31, 27, 20,
- 13, 3, -11, -24, -35, -34, -26, -11, 2, 8, 9, 11, 22, 37, 47, 49,
- 39, 22, 6, -7, -19, -26, -36, -48, -60, -74, -77, -66, -47, -26, -13, -8,
- 1, 15, 36, 53, 63, 56, 45, 30, 22, 16, 10, 5, -7, -19, -32, -34,
- -25, -7, 8, 16, 17, 17, 23, 37, 48, 51, 40, 22, 4, -14, -24, -33,
- -39, -49, -61, -72, -77, -66, -47, -27, -13, -5, 1, 13, 30, 47, 59, 57,
- 47, 31, 23, 17, 15, 6, -5, -18, -26, -30, -24, -10, 8, 19, 21, 20,
- 22, 30, 40, 48, 41, 25, 3, -17, -29, -32, -37, -46, -59, -70, -73, -65,
- -46, -27, -14, -4, 3, 15, 29, 41, 52, 54, 45, 31, 19, 15, 15, 9,
- 1, -14, -26, -27, -21, -8, 10, 17, 23, 23, 23, 32, 39, 45, 44, 29,
- 7, -16, -32, -40, -42, -49, -61, -72, -76, -69, -50, -28, -12, -2, 5, 17,
- 31, 43, 48, 49, 44, 34, 24, 15, 13, 9, 5, -8, -24, -27, -21, -7,
- 10, 20, 25, 29, 29, 32, 36, 41, 41, 34, 14, -12, -35, -46, -49, -52,
- -61, -74, -78, -73, -56, -31, -14, 2, 10, 19, 31, 44, 54, 53, 47, 34,
- 24, 16, 9, 4, -2, -12, -25, -28, -22, -7, 9, 23, 32, 36, 36, 36,
- 37, 42, 42, 33, 15, -14, -36, -50, -57, -56, -62, -74, -81, -77, -59, -36,
- -15, 2, 11, 20, 31, 44, 56, 56, 51, 39, 26, 15, 7, 1, -3, -13,
- -26, -33, -31, -14, 9, 25, 36, 41, 40, 41, 40, 44, 44, 35, 17, -13,
- -39, -54, -61, -64, -69, -76, -81, -78, -63, -39, -15, 4, 14, 24, 35, 45,
- 54, 56, 53, 41, 25, 14, 7, 3, -4, -14, -26, -34, -31, -15, 9, 25,
- 36, 41, 43, 44, 43, 46, 45, 35, 16, -9, -31, -49, -63, -69, -75, -78,
- -84, -79, -66, -45, -22, 0, 13, 23, 35, 48, 56, 58, 53, 43, 30, 19,
- 10, 4, -7, -18, -26, -33, -30, -17, 4, 24, 37, 44, 50, 50, 49, 46,
- 43, 35, 16, -7, -30, -52, -65, -75, -78, -83, -85, -82, -70, -50, -26, -4,
- 14, 26, 39, 53, 63, 64, 59, 49, 35, 18, 6, -2, -13, -25, -35, -40,
- -36, -22, 3, 26, 38, 47, 54, 60, 61, 57, 50, 39, 20, -5, -26, -49,
- -66, -80, -87, -91, -93, -88, -74, -54, -34, -12, 8, 24, 40, 55, 68, 70,
- 66, 55, 41, 26, 14, 6, -9, -25, -37, -43, -39, -28, -9, 15, 32, 41,
- 48, 59, 65, 65, 58, 45, 25, 5, -17, -38, -61, -77, -91, -97, -100, -94,
- -79, -64, -44, -23, -2, 24, 42, 57, 72, 77, 74, 63, 48, 33, 21, 10,
- -7, -27, -43, -45, -41, -29, -14, 4, 26, 40, 49, 58, 66, 69, 64, 48,
- 29, 7, -13, -31, -53, -73, -89, -100, -102, -95, -83, -67, -51, -29, -7, 17,
- 37, 55, 72, 81, 77, 67, 55, 40, 25, 12, -4, -22, -40, -45, -42, -31,
- -19, -4, 15, 34, 48, 55, 63, 67, 66, 57, 41, 20, -4, -25, -46, -69,
- -88, -104, -110, -106, -95, -79, -63, -39, -13, 15, 39, 60, 75, 88, 91, 81,
- 66, 44, 27, 13, -3, -22, -41, -50, -48, -38, -26, -13, 6, 29, 46, 55,
- 62, 66, 69, 63, 48, 26, 5, -14, -33, -57, -84, -105, -115, -113, -102, -88,
- -73, -53, -26, 1, 31, 57, 78, 91, 95, 88, 75, 60, 41, 22, 1, -19,
- -38, -51, -53, -48, -36, -22, -6, 19, 39, 53, 62, 65, 69, 67, 55, 36,
- 14, -6, -28, -54, -79, -100, -111, -116, -110, -98, -83, -61, -35, -6, 26, 53,
- 75, 89, 96, 96, 87, 71, 50, 29, 10, -9, -30, -44, -53, -50, -45, -32,
- -19, 2, 23, 43, 55, 62, 66, 66, 62, 49, 30, 11, -12, -39, -70, -95,
- -112, -118, -118, -109, -94, -74, -48, -18, 17, 47, 70, 88, 98, 99, 95, 80,
- 61, 37, 14, -9, -26, -43, -51, -52, -48, -40, -25, -6, 17, 37, 52, 57,
- 63, 64, 62, 55, 36, 17, -8, -34, -62, -86, -106, -117, -118, -110, -99, -83,
- -57, -27, 10, 42, 67, 85, 96, 101, 101, 91, 69, 46, 21, 1, -21, -38,
- -49, -54, -49, -44, -35, -18, 2, 24, 44, 55, 64, 67, 63, 59, 46, 29,
- 7, -21, -51, -79, -104, -117, -122, -117, -108, -94, -70, -40, 0, 34, 63, 85,
- 96, 104, 105, 99, 82, 59, 31, 4, -20, -37, -46, -51, -51, -50, -44, -28,
- -8, 17, 38, 53, 60, 65, 67, 64, 54, 40, 18, -10, -40, -71, -98, -115,
- -121, -118, -113, -103, -82, -52, -14, 22, 53, 77, 94, 106, 109, 104, 93, 76,
- 50, 21, -11, -33, -43, -48, -53, -56, -56, -46, -27, 2, 29, 48, 58, 62,
- 63, 62, 58, 49, 33, 5, -27, -57, -87, -108, -119, -118, -114, -106, -91, -68,
- -31, 8, 42, 69, 88, 102, 110, 110, 100, 83, 60, 33, 3, -23, -39, -46,
- -52, -57, -57, -51, -35, -14, 15, 38, 54, 63, 65, 66, 58, 51, 40, 17,
- -11, -44, -76, -101, -114, -116, -111, -106, -96, -77, -47, -11, 28, 58, 81, 97,
- 109, 112, 105, 95, 77, 53, 23, -9, -30, -45, -52, -58, -64, -61, -52, -35,
- -9, 20, 44, 62, 67, 67, 65, 62, 54, 35, 7, -24, -60, -91, -110, -119,
- -116, -112, -105, -90, -65, -31, 8, 43, 73, 94, 109, 117, 113, 105, 91, 68,
- 39, 4, -24, -43, -56, -64, -67, -67, -61, -47, -21, 9, 35, 55, 63, 66,
- 66, 61, 56, 46, 23, -10, -46, -81, -100, -111, -115, -112, -107, -94, -75, -48,
- -12, 28, 59, 84, 103, 116, 120, 114, 103, 81, 56, 22, -10, -35, -53, -64,
- -71, -73, -71, -59, -39, -10, 19, 43, 60, 66, 68, 67, 64, 53, 33, 7,
- -27, -64, -91, -108, -115, -113, -108, -97, -82, -59, -27, 11, 46, 75, 98, 112,
- 119, 117, 109, 89, 64, 34, 4, -24, -50, -62, -69, -69, -70, -65, -49, -23,
- 8, 32, 52, 61, 64, 65, 64, 55, 39, 15, -16, -46, -76, -97, -109, -110,
- -107, -102, -91, -71, -42, -4, 34, 66, 90, 106, 116, 121, 118, 101, 78, 47,
- 15, -15, -44, -60, -70, -73, -75, -74, -63, -39, -7, 23, 45, 60, 66, 69,
- 69, 62, 49, 29, 1, -32, -65, -94, -108, -112, -109, -102, -97, -83, -58, -22,
- 18, 54, 84, 103, 116, 121, 120, 112, 91, 63, 29, -6, -34, -54, -66, -75,
- -79, -81, -72, -50, -22, 9, 33, 50, 59, 67, 70, 70, 60, 43, 13, -20,
- -51, -78, -97, -107, -111, -109, -105, -94, -72, -37, 5, 42, 72, 96, 114, 124,
- 127, 118, 100, 75, 42, 10, -22, -47, -62, -72, -79, -84, -82, -64, -35, -2,
- 23, 39, 50, 61, 69, 71, 66, 51, 27, -6, -36, -62, -81, -96, -104, -105,
- -106, -101, -83, -52, -11, 27, 57, 82, 103, 120, 127, 122, 107, 82, 53, 19,
- -12, -39, -55, -65, -73, -81, -81, -67, -40, -8, 16, 30, 41, 52, 62, 68,
- 66, 56, 34, 3, -28, -53, -71, -86, -96, -102, -106, -103, -88, -62, -25, 15,
- 47, 72, 90, 109, 120, 123, 115, 93, 63, 31, 1, -24, -40, -52, -64, -76,
- -82, -73, -50, -22, 1, 18, 27, 39, 51, 63, 67, 61, 44, 18, -13, -38,
- -53, -69, -83, -96, -105, -103, -93, -69, -36, -3, 30, 56, 77, 95, 111, 116,
- 113, 97, 72, 42, 13, -12, -25, -38, -54, -70, -79, -74, -57, -32, -11, 4,
- 15, 26, 40, 55, 65, 62, 51, 28, 1, -24, -40, -56, -73, -89, -101, -102,
- -95, -79, -50, -17, 16, 47, 68, 88, 104, 114, 115, 102, 80, 53, 24, 0,
- -18, -31, -45, -60, -73, -74, -63, -42, -21, -6, 6, 16, 28, 45, 56, 59,
- 51, 35, 14, -9, -26, -41, -57, -73, -87, -97, -95, -85, -62, -32, -2, 26,
- 50, 71, 91, 105, 111, 105, 89, 64, 40, 16, -4, -20, -35, -49, -64, -70,
- -68, -53, -35, -18, -6, 5, 14, 29, 45, 55, 54, 39, 21, 4, -13, -25,
- -42, -63, -77, -89, -90, -80, -66, -44, -19, 10, 35, 57, 76, 93, 104, 104,
- 91, 68, 48, 29, 13, -6, -24, -42, -56, -63, -61, -54, -42, -27, -17, -6,
- 5, 18, 33, 44, 47, 39, 25, 10, 0, -14, -29, -50, -67, -79, -85, -81,
- -70, -53, -32, -5, 24, 47, 67, 84, 98, 103, 95, 77, 56, 37, 22, 6,
- -14, -34, -48, -56, -57, -52, -48, -37, -28, -17, -6, 8, 23, 34, 41, 38,
- 28, 15, 4, -4, -16, -38, -59, -73, -78, -75, -66, -54, -37, -19, 7, 32,
- 53, 72, 87, 95, 92, 78, 58, 44, 32, 20, 2, -21, -38, -47, -48, -47,
- -46, -42, -36, -26, -14, -5, 9, 20, 32, 35, 30, 19, 12, 8, -5, -25,
- -48, -63, -71, -70, -63, -58, -44, -26, -6, 20, 40, 59, 79, 92, 93, 83,
- 60, 47, 37, 29, 13, -10, -28, -40, -44, -44, -48, -47, -41, -33, -22, -13,
- 0, 14, 29, 36, 34, 24, 18, 15, 4, -13, -39, -60, -69, -72, -68, -62,
- -51, -34, -13, 9, 31, 52, 73, 88, 95, 87, 70, 55, 45, 35, 20, -2,
- -23, -36, -42, -47, -48, -51, -50, -40, -30, -17, -8, 7, 23, 36, 37, 30,
- 22, 19, 13, -3, -24, -49, -65, -71, -71, -64, -54, -40, -20, -3, 21, 44,
- 65, 85, 92, 87, 72, 57, 48, 39, 29, 11, -12, -27, -36, -41, -42, -47,
- -49, -45, -37, -28, -17, -4, 13, 28, 33, 29, 26, 23, 17, 6, -11, -33,
- -53, -64, -66, -62, -55, -44, -29, -12, 10, 31, 51, 71, 84, 85, 77, 61,
- 50, 41, 36, 22, 2, -17, -33, -38, -42, -45, -48, -46, -41, -34, -23, -9,
- 7, 24, 35, 32, 28, 23, 17, 10, -4, -26, -49, -64, -68, -64, -58, -46,
- -32, -13, 8, 28, 45, 65, 78, 82, 76, 62, 52, 45, 37, 23, 6, -10,
- -26, -35, -41, -45, -46, -48, -48, -39, -27, -11, 3, 14, 23, 27, 28, 25,
- 23, 15, 2, -17, -34, -52, -60, -61, -56, -44, -32, -17, -3, 16, 34, 54,
- 66, 73, 68, 58, 47, 42, 37, 29, 17, 3, -14, -25, -31, -36, -39, -44,
- -48, -44, -33, -20, -9, 2, 13, 22, 26, 24, 20, 14, 5, -7, -22, -39,
- -50, -55, -51, -43, -32, -20, -7, 10, 28, 44, 57, 65, 67, 64, 54, 44,
- 36, 28, 18, 4, -9, -23, -32, -39, -42, -46, -44, -38, -29, -19, -12, -4,
- 10, 22, 27, 22, 14, 8, 1, -6, -17, -30, -43, -49, -47, -38, -26, -18,
- -10, 3, 17, 34, 45, 54, 59, 57, 53, 45, 37, 30, 22, 11, -3, -14,
- -24, -34, -40, -45, -43, -39, -29, -21, -14, -6, 3, 16, 20, 17, 10, 3,
- 0, -6, -15, -25, -33, -38, -37, -31, -21, -12, -6, 5, 15, 27, 39, 46,
- 50, 51, 47, 44, 36, 29, 20, 10, 1, -10, -18, -27, -36, -40, -42, -37,
- -29, -21, -14, -7, 1, 10, 16, 10, 3, -2, -3, -6, -12, -22, -28, -30,
- -28, -23, -16, -11, -7, 0, 7, 19, 31, 42, 47, 47, 46, 46, 40, 33,
- 21, 10, 2, -6, -12, -24, -33, -37, -38, -36, -31, -21, -14, -7, -2, 2,
- 7, 8, 4, -2, -7, -12, -14, -19, -23, -24, -20, -16, -11, -6, -2, 3,
- 9, 16, 24, 33, 37, 40, 44, 44, 40, 33, 22, 13, 5, -3, -8, -21,
- -30, -35, -34, -32, -30, -23, -13, -6, -3, -3, -2, -2, -4, -7, -9, -12,
- -13, -13, -14, -14, -11, -12, -4, -2, 2, 0, 3, 10, 18, 27, 32, 35,
- 38, 40, 37, 32, 23, 13, 8, 2, -4, -11, -22, -27, -31, -30, -29, -24,
- -14, -7, -8, -7, -10, -10, -10, -10, -11, -12, -13, -12, -11, -11, -7, -2,
- 4, 5, 3, -2, 0, 8, 15, 21, 26, 30, 32, 37, 37, 32, 26, 16,
- 10, 4, -4, -9, -16, -21, -26, -29, -28, -23, -15, -11, -9, -11, -13, -14,
- -14, -13, -13, -12, -13, -12, -8, -3, 3, 6, 8, 10, 7, 1, -3, 2,
- 8, 17, 22, 22, 27, 32, 37, 35, 29, 18, 11, 2, -4, -8, -14, -17,
- -21, -23, -25, -22, -17, -11, -9, -11, -16, -16, -16, -16, -14, -15, -14, -11,
- -5, 0, 4, 5, 6, 7, 6, 4, 0, 3, 8, 16, 21, 20, 24, 28,
- 34, 35, 29, 17, 8, 3, 1, -3, -9, -15, -20, -21, -23, -22, -21, -17,
- -13, -14, -18, -23, -22, -17, -13, -10, -9, -8, 0, 6, 9, 10, 8, 6,
- 6, 4, 0, -2, 1, 10, 17, 20, 22, 25, 29, 31, 29, 20, 10, 2,
- -2, 0, -5, -11, -18, -20, -19, -19, -19, -18, -16, -14, -18, -26, -26, -22,
- -16, -13, -9, -6, 1, 7, 10, 10, 7, 7, 7, 5, 0, -4, -2, 7,
- 14, 19, 22, 26, 30, 32, 30, 22, 13, 6, 1, -2, -7, -13, -16, -18,
- -19, -19, -21, -21, -19, -17, -16, -23, -25, -23, -17, -10, -9, -4, 2, 8,
- 10, 12, 9, 7, 5, 4, 2, -3, -2, 3, 9, 18, 23, 28, 29, 28,
- 27, 26, 19, 12, 6, 0, -7, -11, -15, -17, -20, -21, -20, -22, -23, -25,
- -24, -26, -27, -25, -20, -13, -5, 3, 9, 11, 15, 17, 15, 10, 4, 0,
- -4, -5, -4, 2, 5, 13, 19, 25, 29, 28, 26, 25, 20, 16, 11, 2,
- -5, -10, -10, -10, -14, -17, -21, -24, -26, -29, -27, -28, -28, -26, -23, -17,
- -8, 1, 12, 15, 16, 14, 13, 10, 6, 0, -5, -6, -5, 1, 6, 12,
- 20, 27, 30, 28, 24, 23, 21, 17, 11, 4, -6, -9, -10, -10, -11, -16,
- -18, -21, -24, -26, -29, -28, -27, -25, -23, -18, -11, -2, 11, 15, 15, 12,
- 11, 9, 6, 1, -6, -6, -2, 3, 7, 11, 19, 26, 28, 26, 22, 21,
- 23, 24, 17, 10, 4, 0, -2, -5, -10, -15, -20, -25, -32, -36, -36, -35,
- -32, -30, -26, -19, -10, 2, 14, 21, 21, 17, 13, 10, 7, 1, -5, -5,
- -6, -4, 0, 6, 12, 19, 22, 24, 20, 21, 24, 29, 28, 20, 13, 8,
- 3, 2, -4, -9, -16, -27, -34, -41, -44, -41, -38, -35, -31, -27, -18, -3,
- 13, 26, 29, 23, 18, 14, 11, 8, 4, -2, -8, -11, -9, -6, 4, 9,
- 16, 17, 16, 16, 23, 33, 37, 33, 26, 19, 12, 8, 1, -7, -15, -30,
- -41, -50, -53, -50, -43, -38, -34, -28, -17, -3, 13, 26, 30, 26, 19, 14,
- 12, 9, 4, -2, -10, -14, -13, -7, 4, 9, 12, 13, 13, 17, 25, 32,
- 40, 39, 32, 24, 15, 11, 8, 1, -10, -27, -43, -51, -55, -52, -49, -45,
- -40, -32, -21, -8, 9, 23, 31, 30, 24, 19, 17, 16, 11, 4, -7, -15,
- -18, -14, -6, 2, 5, 7, 9, 14, 24, 35, 45, 48, 45, 34, 25, 16,
- 8, 2, -11, -27, -46, -59, -64, -61, -53, -46, -40, -35, -24, -9, 8, 23,
- 30, 31, 27, 24, 21, 17, 12, 4, -6, -15, -19, -17, -12, -3, 3, 4,
- 6, 12, 25, 37, 45, 47, 47, 43, 35, 23, 12, 2, -10, -24, -42, -60,
- -71, -71, -63, -55, -45, -36, -22, -7, 9, 22, 30, 35, 34, 31, 24, 19,
- 13, 6, -3, -13, -20, -21, -16, -9, -3, -2, 4, 11, 26, 38, 45, 50,
- 49, 48, 42, 31, 16, 4, -9, -21, -38, -59, -72, -77, -70, -61, -53, -41,
- -26, -9, 7, 17, 26, 34, 41, 41, 35, 25, 17, 9, 0, -10, -21, -24,
- -22, -15, -9, -7, -2, 10, 25, 39, 44, 47, 49, 52, 50, 39, 22, 6,
- -8, -20, -34, -54, -70, -78, -77, -68, -61, -49, -33, -15, 3, 16, 25, 32,
- 43, 49, 47, 37, 25, 16, 3, -10, -22, -29, -27, -22, -15, -12, -7, 7,
- 25, 42, 47, 50, 53, 57, 57, 46, 31, 11, -5, -22, -39, -56, -72, -81,
- -85, -81, -71, -56, -36, -16, 4, 19, 29, 37, 48, 55, 56, 48, 34, 20,
- 7, -10, -25, -32, -34, -28, -21, -17, -14, 0, 20, 40, 50, 51, 53, 58,
- 61, 53, 39, 18, -2, -18, -36, -53, -70, -80, -85, -86, -79, -67, -46, -23,
- -2, 17, 27, 35, 44, 55, 62, 57, 44, 26, 9, -10, -23, -29, -32, -28,
- -24, -20, -15, -4, 15, 35, 47, 50, 49, 53, 57, 53, 43, 24, 5, -14,
- -32, -50, -64, -5, 0, -2, -3, -3, -3, -3, -2, -2, 1, 2, 3, 5,
- 8, 11, 11, 10, 8, 5, 1, -6, -13, -19, -21, -18, -15, -13, -10, -7,
- -2, 4, 8, 12, 17, 28, 33, 29, 23, 14, 7, -5, -19, -33, -42, -36,
- -28, -24, -17, -13, -8, 1, 7, 15, 23, 33, 42, 42, 35, 26, 15, 0,
- -16, -30, -44, -45, -34, -27, -20, -16, -13, -4, 4, 12, 21, 29, 40, 45,
- 40, 30, 20, 6, -13, -25, -38, -45, -38, -31, -24, -18, -15, -10, -4, 5,
- 17, 27, 35, 44, 43, 37, 27, 15, -4, -19, -31, -44, -44, -35, -30, -22,
- -19, -16, -8, 2, 15, 25, 32, 42, 47, 42, 32, 18, 0, -16, -26, -39,
- -45, -38, -31, -25, -19, -18, -14, -5, 11, 23, 29, 39, 46, 45, 38, 25,
- 7, -8, -18, -31, -44, -43, -35, -30, -25, -25, -20, -9, 7, 21, 27, 36,
- 48, 51, 44, 32, 14, -3, -16, -28, -42, -46, -41, -33, -27, -24, -23, -15,
- 1, 16, 27, 33, 42, 47, 46, 38, 21, 5, -9, -21, -34, -44, -45, -39,
- -31, -28, -26, -20, -8, 9, 25, 34, 41, 49, 51, 47, 31, 11, -6, -18,
- -30, -42, -48, -45, -36, -28, -26, -23, -12, 6, 23, 33, 38, 43, 51, 50,
- 36, 15, 0, -12, -22, -35, -50, -50, -40, -31, -29, -27, -18, 1, 20, 32,
- 36, 43, 52, 56, 45, 23, 2, -10, -20, -33, -48, -56, -49, -36, -30, -26,
- -18, -5, 17, 33, 39, 40, 46, 52, 49, 32, 9, -8, -18, -26, -40, -54,
- -53, -39, -30, -28, -23, -12, 10, 31, 39, 38, 42, 54, 54, 41, 17, -5,
- -15, -22, -35, -53, -59, -47, -36, -30, -24, -14, 6, 27, 40, 42, 43, 51,
- 56, 46, 26, 3, -13, -22, -33, -49, -61, -55, -41, -32, -26, -18, 0, 22,
- 38, 45, 43, 48, 55, 50, 33, 11, -10, -21, -29, -43, -59, -60, -46, -35,
- -28, -18, -6, 15, 35, 45, 46, 45, 52, 53, 41, 20, -6, -19, -26, -38,
- -54, -62, -53, -39, -29, -19, -11, 6, 29, 44, 48, 45, 47, 52, 49, 32,
- 5, -18, -26, -32, -45, -61, -61, -48, -35, -23, -14, -2, 22, 42, 52, 50,
- 46, 50, 50, 38, 12, -15, -26, -31, -43, -59, -65, -53, -37, -25, -16, -6,
- 16, 40, 53, 53, 47, 49, 51, 42, 22, -10, -27, -31, -38, -54, -67, -63,
- -46, -27, -18, -7, 10, 31, 52, 59, 53, 48, 50, 46, 32, 3, -24, -34,
- -39, -50, -66, -68, -54, -35, -20, -8, 6, 23, 47, 62, 59, 52, 50, 48,
- 37, 13, -18, -35, -40, -46, -62, -72, -63, -43, -25, -10, 6, 20, 41, 59,
- 63, 55, 49, 46, 39, 21, -9, -31, -39, -42, -52, -68, -68, -52, -32, -17,
- -4, 9, 31, 54, 66, 63, 54, 51, 44, 32, 6, -26, -40, -44, -51, -65,
- -72, -61, -41, -23, -5, 9, 25, 48, 64, 66, 59, 54, 46, 33, 12, -17,
- -36, -45, -51, -62, -73, -67, -48, -31, -11, 8, 21, 44, 64, 70, 64, 57,
- 49, 36, 20, -8, -34, -47, -52, -58, -68, -73, -59, -40, -19, 4, 17, 36,
- 58, 72, 73, 65, 56, 41, 26, 4, -24, -44, -55, -63, -69, -73, -66, -51,
- -28, -2, 18, 32, 51, 67, 75, 72, 62, 46, 29, 11, -13, -37, -54, -64,
- -70, -71, -70, -58, -38, -13, 14, 30, 48, 64, 73, 76, 69, 52, 34, 15,
- -7, -31, -50, -62, -69, -71, -71, -66, -47, -19, 8, 26, 40, 58, 73, 81,
- 76, 57, 39, 23, 2, -22, -45, -62, -71, -73, -71, -69, -57, -32, 0, 26,
- 41, 55, 70, 81, 83, 64, 41, 24, 6, -15, -39, -60, -71, -73, -69, -69,
- -62, -40, -11, 20, 39, 51, 65, 78, 86, 75, 50, 29, 11, -8, -30, -53,
- -70, -77, -71, -66, -67, -53, -22, 13, 37, 49, 60, 75, 89, 84, 58, 33,
- 16, -2, -22, -47, -68, -77, -72, -67, -68, -60, -34, 0, 29, 47, 56, 69,
- 85, 88, 69, 40, 20, 4, -13, -35, -61, -76, -74, -65, -66, -65, -47, -15,
- 20, 43, 53, 64, 81, 89, 77, 50, 26, 9, -10, -29, -51, -71, -78, -71,
- -66, -64, -52, -27, 9, 38, 54, 62, 73, 85, 82, 60, 34, 13, -3, -19,
- -40, -65, -80, -74, -68, -69, -61, -40, -4, 29, 49, 61, 72, 86, 86, 70,
- 45, 21, 3, -16, -33, -56, -80, -78, -70, -70, -65, -50, -18, 20, 48, 62,
- 68, 80, 88, 78, 53, 26, 5, -12, -26, -45, -72, -81, -71, -67, -64, -56,
- -34, 4, 37, 57, 63, 73, 85, 83, 63, 37, 16, 0, -17, -36, -63, -79,
- -74, -70, -69, -63, -44, -10, 26, 52, 62, 69, 81, 84, 69, 45, 22, 3,
- -15, -28, -52, -75, -76, -69, -67, -64, -52, -24, 14, 45, 60, 65, 74, 82,
- 75, 54, 32, 12, -6, -21, -44, -68, -78, -74, -71, -69, -60, -34, 2, 34,
- 55, 66, 73, 79, 78, 61, 39, 20, 2, -16, -34, -56, -72, -74, -70, -71,
- -66, -47, -14, 21, 48, 61, 68, 76, 80, 69, 46, 27, 11, -7, -26, -50,
- -68, -72, -70, -70, -69, -54, -24, 10, 39, 57, 66, 72, 76, 70, 52, 33,
- 16, -4, -20, -39, -59, -70, -71, -69, -67, -60, -37, -6, 27, 50, 62, 67,
- 72, 74, 61, 41, 25, 10, -10, -31, -51, -67, -74, -73, -73, -68, -48, -16,
- 17, 45, 60, 66, 73, 75, 66, 48, 29, 15, -3, -24, -45, -62, -70, -72,
- -74, -70, -55, -26, 7, 32, 51, 63, 70, 73, 67, 51, 35, 24, 9, -16,
- -38, -54, -64, -68, -75, -75, -62, -36, -5, 22, 45, 60, 69, 74, 68, 57,
- 43, 29, 15, -9, -29, -45, -60, -67, -75, -76, -64, -44, -16, 10, 32, 52,
- 63, 68, 66, 59, 48, 36, 24, 6, -17, -35, -51, -60, -70, -78, -72, -55,
- -27, 1, 20, 39, 56, 65, 68, 60, 51, 41, 31, 15, -9, -27, -44, -58,
- -67, -75, -73, -58, -35, -8, 11, 32, 50, 60, 61, 57, 53, 47, 37, 25,
- 4, -19, -35, -48, -60, -73, -76, -67, -46, -18, 2, 20, 40, 56, 64, 62,
- 56, 49, 43, 34, 15, -10, -31, -45, -57, -70, -78, -69, -52, -27, -4, 13,
- 34, 52, 60, 57, 53, 52, 46, 36, 22, 1, -19, -35, -50, -65, -73, -70,
- -58, -41, -17, 4, 22, 42, 55, 58, 57, 55, 50, 43, 32, 12, -11, -30,
- -47, -61, -71, -72, -63, -46, -26, -6, 13, 30, 47, 53, 54, 56, 52, 46,
- 38, 24, 5, -20, -39, -52, -63, -67, -66, -57, -37, -15, 3, 18, 37, 50,
- 55, 59, 55, 49, 45, 32, 15, -10, -34, -50, -61, -66, -66, -58, -42, -24,
- -4, 11, 27, 44, 50, 54, 57, 53, 49, 39, 23, 2, -23, -43, -57, -64,
- -67, -62, -50, -33, -14, 4, 18, 37, 48, 53, 57, 55, 52, 44, 30, 13,
- -14, -38, -54, -62, -65, -62, -54, -42, -24, -2, 13, 28, 41, 48, 56, 57,
- 52, 45, 37, 23, 0, -28, -47, -57, -62, -63, -59, -50, -34, -14, 1, 16,
- 35, 48, 56, 59, 59, 54, 45, 31, 8, -20, -42, -56, -62, -64, -60, -52,
- -40, -23, -5, 10, 28, 43, 52, 56, 57, 56, 49, 38, 21, -8, -33, -46,
- -56, -60, -59, -56, -47, -32, -15, 0, 17, 34, 47, 55, 58, 57, 53, 43,
- 30, 8, -24, -42, -52, -59, -58, -57, -51, -42, -26, -8, 11, 29, 42, 50,
- 57, 59, 55, 48, 34, 15, -15, -36, -45, -52, -55, -58, -55, -43, -31, -17,
- -2, 16, 37, 50, 56, 58, 58, 54, 43, 23, -8, -33, -40, -47, -54, -57,
- -58, -48, -34, -23, -10, 9, 31, 48, 54, 55, 55, 57, 50, 32, 3, -28,
- -37, -41, -49, -55, -58, -49, -36, -27, -17, 1, 21, 41, 50, 52, 51, 54,
- 55, 41, 13, -18, -32, -35, -42, -50, -57, -55, -41, -32, -24, -10, 10, 33,
- 47, 50, 51, 54, 59, 49, 24, -8, -26, -30, -37, -46, -56, -59, -46, -35,
- -29, -18, 2, 25, 44, 48, 47, 51, 57, 56, 36, 5, -20, -28, -31, -40,
- -51, -58, -52, -39, -33, -25, -8, 15, 38, 49, 47, 50, 56, 60, 46, 15,
- -11, -25, -30, -36, -49, -60, -54, -39, -33, -30, -14, 8, 32, 47, 44, 44,
- 51, 59, 52, 26, -4, -20, -24, -29, -41, -54, -55, -43, -34, -33, -26, -8,
- 17, 37, 43, 42, 48, 59, 60, 42, 13, -11, -21, -25, -36, -51, -59, -51,
- -38, -34, -32, -17, 10, 33, 43, 43, 44, 55, 60, 46, 21, -6, -18, -22,
- -28, -42, -54, -52, -39, -30, -32, -25, -4, 20, 36, 39, 39, 48, 60, 57,
- 36, 10, -11, -19, -22, -34, -51, -58, -48, -35, -36, -34, -13, 13, 35, 41,
- 38, 46, 59, 61, 44, 20, -5, -20, -22, -30, -46, -56, -53, -39, -34, -36,
- -22, 1, 25, 39, 39, 42, 53, 60, 54, 34, 10, -10, -17, -21, -39, -57,
- -59, -48, -38, -43, -35, -11, 16, 37, 43, 42, 52, 61, 58, 41, 19, -3,
- -16, -21, -31, -50, -59, -53, -40, -39, -39, -22, 5, 30, 40, 38, 45, 58,
- 64, 52, 28, 5, -12, -17, -23, -44, -58, -56, -46, -40, -43, -33, -7, 22,
- 39, 41, 44, 55, 64, 60, 40, 13, -7, -16, -21, -35, -56, -60, -52, -44,
- -43, -40, -21, 11, 34, 40, 40, 50, 61, 64, 53, 29, 6, -10, -16, -25,
- -47, -62, -61, -53, -49, -47, -35, -5, 26, 42, 45, 49, 58, 65, 59, 39,
- 15, -5, -16, -22, -37, -56, -61, -56, -50, -47, -42, -21, 11, 33, 40, 44,
- 53, 63, 66, 54, 29, 8, -6, -15, -28, -52, -64, -60, -57, -53, -49, -31,
- 1, 28, 40, 42, 51, 63, 66, 56, 36, 14, -3, -13, -25, -45, -61, -61,
- -58, -54, -47, -38, -11, 20, 36, 41, 44, 55, 64, 60, 47, 28, 9, -4,
- -15, -32, -56, -67, -64, -62, -55, -48, -27, 8, 29, 41, 47, 57, 66, 65,
- 56, 39, 17, 0, -13, -27, -49, -66, -68, -67, -58, -48, -36, -8, 22, 38,
- 45, 53, 63, 65, 61, 51, 28, 11, -4, -20, -40, -62, -70, -71, -68, -55,
- -44, -24, 9, 30, 42, 52, 66, 69, 64, 58, 42, 20, 4, -14, -34, -57,
- -71, -73, -73, -63, -51, -35, -5, 23, 38, 48, 62, 71, 69, 65, 54, 32,
- 14, -6, -26, -48, -68, -79, -82, -72, -57, -42, -18, 11, 33, 48, 63, 73,
- 72, 68, 62, 46, 22, 0, -21, -42, -63, -76, -83, -80, -65, -49, -28, -2,
- 23, 42, 58, 71, 75, 72, 68, 56, 33, 10, -12, -32, -54, -73, -84, -87,
- -73, -54, -36, -15, 11, 34, 52, 67, 73, 73, 72, 66, 48, 21, -6, -26,
- -47, -67, -80, -88, -81, -62, -41, -23, 0, 27, 47, 65, 74, 74, 71, 67,
- 57, 33, 4, -20, -42, -64, -77, -88, -88, -72, -49, -27, -7, 16, 40, 63,
- 75, 75, 74, 69, 64, 46, 16, -13, -35, -57, -74, -87, -93, -81, -58, -35,
- -17, 6, 33, 59, 73, 76, 76, 71, 68, 58, 29, -4, -29, -48, -68, -83,
- -94, -92, -70, -42, -22, -4, 21, 51, 73, 78, 76, 73, 70, 63, 40, 7,
- -24, -42, -60, -79, -91, -92, -76, -52, -30, -12, 9, 39, 66, 76, 76, 75,
- 74, 70, 54, 24, -12, -36, -52, -72, -93, -100, -90, -64, -38, -21, -5, 25,
- 61, 81, 81, 77, 78, 76, 63, 33, -5, -33, -49, -67, -90, -100, -92, -71,
- -44, -21, -8, 14, 49, 75, 82, 77, 76, 75, 66, 45, 10, -27, -45, -59,
- -80, -98, -98, -81, -52, -26, -12, 2, 34, 71, 86, 80, 75, 77, 71, 54,
- 23, -17, -44, -57, -74, -93, -99, -87, -65, -36, -14, -4, 20, 55, 79, 82,
- 78, 78, 75, 65, 41, 1, -34, -52, -67, -88, -104, -98, -76, -47, -23, -12,
- 6, 45, 81, 90, 81, 79, 81, 72, 50, 11, -28, -50, -61, -81, -102, -103,
- -84, -57, -30, -13, 1, 30, 70, 92, 88, 81, 80, 75, 59, 27, -15, -48,
- -62, -76, -97, -106, -94, -69, -39, -16, -4, 17, 59, 92, 94, 87, 86, 83,
- 67, 36, -4, -38, -61, -77, -96, -111, -102, -80, -53, -26, -8, 14, 50, 89,
- 101, 93, 87, 83, 73, 46, 7, -31, -58, -72, -87, -106, -106, -88, -59, -31,
- -12, 5, 33, 74, 99, 99, 90, 84, 78, 57, 22, -18, -49, -70, -84, -100,
- -108, -96, -72, -43, -21, -3, 24, 61, 95, 106, 99, 90, 82, 65, 34, -6,
- -40, -66, -83, -96, -106, -102, -82, -52, -27, -8, 15, 48, 86, 107, 105, 94,
- 85, 73, 45, 6, -32, -61, -80, -91, -102, -106, -92, -63, -35, -15, 8, 37,
- 74, 102, 109, 98, 87, 76, 54, 21, -16, -50, -76, -89, -98, -104, -98, -76,
- -46, -23, -2, 25, 60, 93, 111, 106, 92, 82, 65, 35, -5, -39, -66, -83,
- -95, -105, -105, -86, -57, -33, -11, 15, 50, 86, 111, 115, 102, 88, 71, 43,
- 7, -32, -64, -86, -96, -100, -102, -92, -67, -40, -13, 13, 42, 75, 103, 116,
- 106, 90, 74, 49, 16, -21, -54, -80, -94, -98, -100, -94, -75, -50, -23, 4,
- 30, 62, 95, 117, 115, 100, 81, 57, 28, -10, -46, -75, -95, -102, -101, -97,
- -83, -61, -32, -2, 24, 55, 87, 111, 118, 106, 88, 65, 35, 0, -36, -67,
- -89, -101, -102, -98, -89, -68, -43, -13, 16, 46, 80, 107, 121, 116, 98, 75,
- 47, 11, -27, -62, -87, -101, -104, -100, -93, -77, -51, -18, 13, 36, 67, 99,
- 119, 119, 103, 81, 53, 21, -16, -52, -79, -96, -106, -102, -93, -82, -60, -30,
- 3, 30, 59, 88, 111, 121, 111, 89, 61, 30, -4, -41, -74, -94, -106, -104,
- -95, -87, -70, -41, -8, 22, 49, 81, 106, 120, 118, 98, 73, 41, 8, -30,
- -64, -87, -104, -111, -100, -91, -77, -51, -21, 13, 41, 73, 100, 117, 122, 107,
- 83, 52, 19, -18, -55, -82, -101, -111, -105, -93, -83, -60, -29, 5, 35, 64,
- 92, 112, 121, 112, 88, 61, 29, -7, -45, -75, -94, -108, -108, -96, -87, -67,
- -37, -5, 26, 52, 83, 105, 116, 116, 97, 70, 41, 7, -33, -67, -91, -105,
- -110, -99, -88, -73, -48, -18, 15, 45, 74, 98, 114, 118, 104, 79, 51, 17,
- -21, -58, -86, -102, -109, -103, -90, -77, -54, -23, 9, 36, 62, 88, 107, 114,
- 107, 88, 63, 30, -8, -46, -77, -96, -107, -108, -97, -81, -63, -36, -4, 30,
- 59, 84, 104, 115, 112, 95, 69, 38, 5, -33, -69, -94, -104, -105, -99, -87,
- -72, -44, -11, 21, 47, 71, 97, 113, 113, 99, 77, 49, 17, -19, -57, -87,
- -101, -105, -103, -90, -72, -54, -24, 10, 41, 64, 86, 104, 111, 104, 85, 57,
- 25, -7, -42, -75, -96, -101, -98, -92, -79, -61, -36, -4, 28, 51, 74, 98,
- 110, 107, 94, 70, 38, 5, -30, -64, -89, -101, -101, -95, -79, -63, -43, -14,
- 21, 48, 68, 90, 105, 108, 97, 74, 44, 12, -20, -52, -83, -96, -96, -92,
- -82, -67, -49, -24, 10, 39, 59, 79, 99, 107, 101, 83, 54, 21, -11, -41,
- -71, -92, -98, -95, -84, -68, -54, -35, -5, 28, 54, 73, 92, 103, 103, 90,
- 64, 31, -4, -34, -63, -85, -94, -92, -84, -70, -56, -38, -11, 19, 44, 64,
- 83, 95, 98, 90, 66, 39, 9, -22, -50, -73, -86, -89, -84, -72, -59, -45,
- -23, 6, 35, 58, 75, 89, 96, 92, 75, 49, 19, -14, -42, -63, -80, -88,
- -84, -74, -60, -48, -30, -5, 23, 52, 70, 82, 91, 91, 79, 57, 29, -3,
- -33, -54, -70, -84, -87, -79, -65, -50, -35, -16, 10, 41, 68, 80, 85, 88,
- 82, 64, 36, 3, -28, -49, -60, -72, -83, -81, -66, -49, -37, -22, -2, 28,
- 58, 74, 78, 83, 81, 69, 45, 14, -18, -42, -55, -66, -77, -79, -68, -53,
- -39, -25, -8, 17, 46, 67, 72, 75, 74, 70, 53, 24, -9, -34, -48, -55,
- -64, -74, -70, -55, -40, -28, -17, 3, 33, 61, 70, 71, 69, 68, 61, 37,
- 3, -28, -44, -50, -57, -70, -73, -58, -41, -30, -21, -8, 21, 52, 67, 69,
- 66, 66, 64, 44, 10, -22, -39, -48, -52, -61, -72, -62, -43, -29, -20, -12,
- 7, 38, 62, 68, 61, 56, 60, 51, 23, -12, -36, -43, -44, -49, -65, -65,
- -45, -29, -22, -19, -7, 24, 52, 65, 57, 52, 58, 57, 36, 0, -30, -38,
- -37, -39, -55, -66, -52, -33, -23, -21, -14, 10, 40, 60, 59, 49, 51, 54,
- 43, 11, -21, -35, -37, -33, -42, -55, -49, -29, -19, -20, -19, -5, 23, 49,
- 54, 43, 42, 50, 49, 23, -12, -30, -34, -29, -31, -49, -54, -35, -19, -16,
- -18, -11, 10, 39, 55, 45, 35, 41, 47, 31, -3, -26, -33, -28, -23, -36,
- -47, -36, -18, -11, -16, -16, -3, 21, 42, 42, 32, 32, 40, 35, 13, -13,
- -25, -24, -17, -22, -37, -38, -25, -16, -16, -19, -11, 7, 30, 42, 34, 27,
- 33, 35, 19, -6, -21, -23, -17, -14, -23, -29, -21, -11, -10, -17, -16, -4,
- 14, 30, 31, 20, 21, 29, 24, 6, -11, -16, -11, -5, -10, -20, -22, -15,
- -12, -17, -21, -15, 0, 20, 29, 22, 17, 23, 25, 16, -2, -14, -14, -7,
- -2, -9, -14, -12, -9, -11, -17, -17, -11, 3, 18, 17, 9, 13, 19, 17,
- 7, -5, -5, 3, 8, 3, -7, -10, -12, -14, -20, -22, -17, -7, 9, 17,
- 10, 8, 15, 18, 11, 2, -3, 1, 8, 9, 5, -3, -9, -12, -18, -21,
- -21, -19, -4, 10, 9, 2, 5, 14, 16, 11, 4, 5, 13, 16, 14, 6,
- -8, -14, -19, -23, -24, -21, -13, -2, 7, 3, -2, 8, 12, 11, 9, 10,
- 14, 19, 20, 16, 4, -9, -17, -23, -26, -27, -24, -14, -2, 1, -5, 3,
- 15, 17, 14, 14, 17, 22, 25, 20, 9, -8, -19, -25, -30, -29, -26, -22,
- -11, 0, -3, -3, 9, 16, 19, 20, 21, 24, 28, 28, 20, 2, -16, -25,
- -30, -34, -33, -32, -23, -9, -6, -8, 2, 15, 21, 24, 26, 29, 33, 34,
- 30, 14, -11, -26, -33, -38, -38, -37, -34, -23, -12, -7, 0, 11, 21, 29,
- 34, 35, 37, 39, 35, 21, -5, -26, -34, -39, -40, -42, -42, -31, -17, -9,
- -4, 7, 19, 31, 38, 38, 41, 42, 40, 28, 3, -22, -36, -42, -45, -46,
- -46, -37, -23, -14, -6, 6, 20, 32, 40, 40, 44, 46, 41, 31, 13, -12,
- -32, -44, -47, -48, -49, -44, -32, -20, -8, 3, 15, 27, 40, 45, 47, 50,
- 47, 39, 21, -6, -29, -42, -46, -51, -56, -52, -41, -24, -13, -4, 11, 27,
- 41, 51, 52, 53, 52, 45, 29, 2, -25, -45, -50, -52, -57, -56, -49, -32,
- -16, -4, 9, 22, 36, 49, 55, 56, 56, 50, 35, 11, -14, -37, -51, -57,
- -61, -61, -56, -41, -23, -8, 8, 21, 33, 48, 61, 64, 60, 54, 40, 17,
- -8, -34, -52, -59, -62, -63, -60, -49, -30, -14, 2, 19, 33, 47, 60, 66,
- 67, 65, 50, 25, -3, -26, -47, -59, -68, -72, -66, -57, -38, -20, -5, 14,
- 30, 44, 61, 71, 71, 68, 57, 34, 7, -20, -43, -58, -68, -72, -69, -62,
- -45, -25, -10, 7, 24, 42, 59, 70, 74, 73, 65, 46, 16, -15, -38, -53,
- -65, -77, -77, -70, -54, -34, -19, 0, 20, 41, 60, 74, 82, 80, 71, 54,
- 27, -8, -36, -55, -68, -78, -82, -76, -61, -40, -20, -2, 17, 36, 57, 74,
- 83, 82, 74, 62, 39, 3, -31, -49, -62, -75, -84, -84, -69, -47, -27, -13,
- 6, 31, 56, 73, 82, 86, 80, 68, 49, 14, -24, -46, -60, -74, -83, -86,
- -76, -54, -32, -15, 3, 23, 48, 71, 85, 87, 80, 71, 57, 27, -12, -41,
- -57, -68, -78, -88, -84, -64, -41, -23, -5, 16, 40, 65, 84, 90, 87, 77,
- 63, 36, -3, -34, -57, -69, -76, -85, -87, -73, -48, -27, -8, 13, 34, 60,
- 83, 91, 86, 77, 66, 44, 9, -26, -53, -68, -74, -83, -88, -80, -56, -33,
- -13, 9, 29, 55, 79, 93, 89, 76, 67, 52, 21, -15, -46, -69, -74, -77,
- -84, -86, -67, -42, -20, 4, 23, 43, 71, 94, 95, 80, 67, 56, 32, 0,
- -37, -66, -74, -73, -78, -87, -76, -50, -25, 1, 21, 37, 61, 88, 97, 84,
- 67, 57, 38, 8, -25, -59, -77, -77, -76, -81, -80, -61, -34, -6, 20, 36,
- 55, 80, 96, 91, 70, 54, 39, 17, -14, -51, -75, -79, -75, -77, -80, -68,
- -40, -11, 15, 33, 48, 71, 92, 91, 73, 57, 45, 24, -3, -38, -68, -79,
- -77, -76, -80, -74, -51, -19, 12, 32, 46, 65, 88, 96, 83, 59, 40, 24,
- 4, -31, -67, -83, -80, -73, -73, -72, -55, -24, 9, 31, 44, 58, 78, 90,
- 84, 63, 42, 28, 10, -18, -53, -77, -82, -76, -73, -74, -65, -37, -2, 27,
- 42, 55, 73, 88, 90, 72, 47, 28, 13, -12, -45, -74, -84, -78, -70, -68,
- -63, -43, -9, 23, 42, 52, 64, 78, 84, 75, 52, 32, 17, -3, -32, -62,
- -79, -78, -71, -67, -65, -52, -19, 15, 38, 50, 61, 73, 80, 79, 59, 34,
- 18, 3, -21, -51, -75, -81, -72, -64, -61, -54, -31, 4, 31, 48, 55, 63,
- 73, 78, 67, 40, 21, 8, -12, -39, -65, -80, -76, -65, -58, -52, -38, -8,
- 25, 45, 56, 61, 67, 74, 69, 47, 22, 7, -10, -31, -56, -75, -77, -66,
- -57, -49, -37, -14, 16, 40, 53, 57, 61, 67, 69, 55, 30, 11, -6, -25,
- -47, -69, -78, -70, -59, -51, -40, -20, 10, 34, 51, 58, 59, 63, 66, 59,
- 36, 14, -2, -19, -40, -61, -75, -71, -59, -51, -41, -27, -2, 26, 47, 58,
- 58, 59, 64, 63, 46, 19, -2, -17, -35, -56, -71, -75, -64, -50, -40, -26,
- -6, 21, 43, 55, 57, 56, 58, 59, 47, 23, 1, -13, -29, -48, -63, -69,
- -61, -48, -40, -29, -11, 13, 35, 48, 53, 51, 53, 57, 50, 33, 9, -10,
- -25, -42, -56, -65, -64, -51, -40, -29, -13, 9, 30, 44, 50, 48, 47, 50,
- 46, 35, 13, -8, -20, -33, -47, -57, -56, -48, -38, -30, -16, 1, 21, 35,
- 44, 46, 42, 44, 44, 39, 21, -3, -18, -30, -40, -51, -57, -51, -37, -26,
- -14, 0, 16, 33, 42, 43, 37, 34, 37, 35, 22, 1, -17, -27, -34, -41,
- -48, -45, -36, -25, -11, 0, 11, 24, 34, 38, 35, 30, 29, 30, 24, 8,
- -11, -24, -31, -36, -42, -42, -35, -25, -12, -2, 9, 21, 29, 33, 32, 27,
- 25, 26, 23, 9, -8, -21, -31, -34, -36, -37, -33, -26, -13, -2, 8, 18,
- 24, 28, 29, 27, 22, 20, 21, 14, -2, -17, -27, -30, -31, -33, -32, -26,
- -14, -3, 6, 15, 22, 27, 26, 25, 22, 17, 17, 13, 3, -12, -25, -30,
- -31, -30, -27, -24, -14, 0, 8, 16, 20, 22, 22, 21, 16, 11, 13, 13,
- 3, -8, -21, -27, -26, -25, -25, -23, -12, 0, 6, 12, 18, 20, 22, 20,
- 15, 9, 9, 10, 3, -9, -21, -29, -28, -23, -20, -19, -10, 3, 13, 17,
- 19, 19, 21, 17, 11, 4, 1, 4, 0, -8, -17, -25, -24, -21, -19, -16,
- -9, 4, 13, 17, 19, 20, 22, 19, 11, 3, -4, -3, -4, -12, -18, -26,
- -28, -23, -16, -10, -5, 5, 18, 25, 25, 22, 21, 19, 9, 0, -9, -11,
- -10, -13, -16, -24, -27, -22, -14, -8, -2, 7, 17, 25, 25, 22, 20, 17,
- 10, -2, -10, -12, -13, -15, -18, -20, -24, -22, -16, -8, 3, 11, 17, 25,
- 27, 23, 21, 17, 9, 0, -10, -12, -13, -18, -19, -20, -24, -23, -17, -10,
- 0, 11, 19, 26, 30, 26, 24, 20, 12, 3, -8, -15, -18, -22, -25, -25,
- -25, -24, -20, -12, 2, 15, 20, 25, 31, 33, 29, 23, 12, 3, -5, -15,
- -23, -28, -28, -25, -22, -22, -18, -10, 2, 15, 19, 23, 30, 32, 28, 24,
- 15, 7, 1, -13, -23, -27, -29, -28, -26, -24, -20, -14, -2, 13, 20, 24,
- 32, 34, 32, 29, 22, 9, -2, -10, -21, -30, -34, -34, -29, -22, -20, -18,
- -5, 14, 23, 25, 31, 36, 35, 30, 22, 10, 0, -8, -21, -34, -39, -36,
- -32, -27, -20, -15, -5, 14, 27, 28, 32, 36, 35, 33, 25, 14, 0, -11,
- -21, -34, -40, -41, -39, -30, -20, -13, -6, 10, 27, 30, 32, 35, 34, 36,
- 29, 17, 5, -7, -16, -33, -45, -45, -43, -33, -24, -18, -9, 8, 26, 32,
- 33, 39, 38, 36, 31, 20, 10, -6, -19, -32, -45, -47, -46, -39, -25, -12,
- -3, 8, 22, 32, 32, 35, 35, 32, 31, 23, 14, 0, -15, -26, -43, -51,
- -50, -43, -29, -17, -6, 5, 19, 34, 36, 33, 37, 37, 34, 25, 16, 5,
- -11, -26, -41, -51, -55, -51, -36, -21, -7, 7, 16, 28, 37, 35, 35, 36,
- 34, 30, 20, 9, -7, -22, -37, -49, -56, -54, -42, -25, -11, 2, 13, 24,
- 35, 38, 37, 38, 37, 32, 25, 16, 1, -21, -38, -47, -56, -58, -50, -34,
- -14, 4, 13, 20, 31, 40, 39, 35, 36, 34, 28, 20, 5, -15, -33, -44,
- -55, -63, -54, -38, -19, -2, 10, 17, 30, 40, 41, 36, 38, 41, 33, 22,
- 9, -13, -36, -50, -55, -63, -61, -44, -22, 2, 18, 22, 28, 38, 42, 39,
- 34, 35, 34, 27, 14, -7, -29, -43, -51, -60, -63, -50, -30, -10, 8, 16,
- 21, 32, 40, 40, 38, 39, 41, 35, 24, 6, -20, -41, -54, -62, -65, -58,
- -39, -16, 7, 18, 22, 29, 39, 43, 40, 35, 38, 37, 27, 12, -14, -37,
- -51, -58, -64, -64, -47, -22, -2, 14, 18, 24, 36, 44, 45, 41, 43, 43,
- 32, 17, -8, -35, -54, -63, -67, -68, -56, -29, -4, 16, 24, 26, 35, 44,
- 47, 43, 38, 38, 36, 24, 0, -30, -50, -57, -59, -63, -61, -40, -11, 11,
- 20, 20, 26, 39, 48, 46, 40, 39, 42, 33, 12, -20, -47, -58, -60, -62,
- -61, -49, -23, 2, 17, 21, 22, 33, 48, 51, 45, 43, 43, 38, 20, -10,
- -41, -58, -61, -64, -62, -55, -35, -9, 10, 21, 23, 32, 50, 57, 49, 45,
- 45, 43, 26, -6, -38, -58, -62, -65, -67, -61, -44, -15, 10, 23, 26, 28,
- 44, 59, 55, 46, 42, 41, 33, 6, -30, -57, -64, -62, -64, -62, -50, -26,
- 2, 18, 26, 28, 39, 59, 60, 48, 43, 43, 37, 14, -22, -53, -67, -63,
- -65, -66, -55, -33, -2, 19, 28, 31, 37, 55, 64, 53, 41, 39, 37, 20,
- -16, -48, -66, -65, -62, -66, -60, -43, -12, 15, 26, 31, 37, 53, 69, 63,
- 46, 39, 38, 27, -5, -44, -72, -73, -65, -65, -63, -52, -24, 11, 31, 36,
- 38, 48, 65, 70, 53, 38, 34, 28, 5, -35, -69, -78, -70, -65, -63, -53,
- -30, 2, 26, 38, 43, 49, 62, 69, 58, 40, 33, 28, 9, -25, -61, -78,
- -75, -69, -64, -55, -37, -7, 22, 36, 43, 49, 57, 66, 62, 44, 31, 29,
- 15, -16, -52, -76, -77, -69, -63, -57, -44, -16, 14, 33, 42, 48, 54, 65,
- 68, 52, 33, 27, 19, -6, -41, -72, -82, -74, -65, -59, -48, -24, 7, 29,
- 43, 50, 53, 60, 67, 58, 39, 28, 22, 2, -31, -64, -82, -79, -71, -61,
- -49, -31, -2, 22, 40, 51, 55, 58, 65, 63, 46, 29, 21, 9, -21, -56,
- -79, -83, -77, -65, -54, -37, -10, 16, 36, 50, 57, 60, 65, 64, 50, 33,
- 22, 11, -13, -47, -73, -82, -80, -70, -57, -42, -19, 8, 30, 49, 58, 61,
- 62, 64, 56, 41, 24, 11, -6, -35, -66, -80, -82, -75, -61, -45, -25, -2,
- 22, 43, 57, 63, 64, 63, 58, 49, 31, 15, -2, -26, -58, -79, -85, -81,
- -66, -49, -31, -9, 17, 39, 55, 64, 69, 67, 61, 53, 35, 16, 1, -20,
- -49, -75, -86, -85, -74, -54, -34, -11, 11, 33, 53, 64, 70, 68, 59, 51,
- 40, 22, 5, -15, -40, -66, -79, -81, -78, -63, -41, -19, 4, 25, 44, 58,
- 67, 72, 65, 57, 47, 29, 11, -8, -31, -61, -81, -85, -82, -68, -47, -25,
- -3, 21, 44, 59, 68, 73, 68, 56, 47, 33, 15, -7, -27, -52, -76, -82,
- -82, -72, -52, -30, -7, 13, 36, 57, 67, 74, 72, 61, 48, 36, 20, -4,
- -25, -47, -71, -81, -81, -75, -56, -33, -10, 11, 30, 49, 63, 73, 74, 63,
- 48, 37, 25, 6, -20, -41, -63, -79, -81, -77, -65, -43, -19, 4, 25, 45,
- 63, 73, 76, 70, 55, 41, 28, 10, -15, -38, -59, -77, -83, -79, -70, -49,
- -25, -4, 20, 40, 59, 74, 76, 73, 62, 46, 33, 16, -10, -34, -51, -68,
- -83, -85, -75, -58, -34, -11, 14, 35, 55, 73, 79, 76, 69, 51, 33, 20,
- -2, -30, -53, -67, -81, -84, -76, -61, -39, -14, 11, 32, 49, 67, 77, 74,
- 68, 55, 37, 23, 5, -22, -45, -59, -73, -84, -82, -68, -46, -24, 3, 26,
- 43, 62, 75, 74, 72, 61, 42, 25, 10, -15, -40, -57, -70, -83, -84, -71,
- -49, -28, -6, 20, 41, 59, 72, 72, 69, 63, 48, 29, 13, -8, -31, -51,
- -66, -79, -84, -75, -56, -37, -16, 12, 36, 55, 71, 74, 72, 69, 54, 34,
- 16, -5, -28, -47, -61, -75, -85, -80, -60, -38, -20, 4, 30, 53, 68, 71,
- 69, 67, 57, 39, 20, 0, -21, -41, -58, -71, -79, -79, -66, -45, -25, -3,
- 23, 45, 61, 68, 69, 70, 63, 47, 29, 8, -16, -37, -56, -71, -80, -81,
- -71, -52, -30, -7, 17, 41, 60, 67, 67, 68, 65, 50, 30, 10, -14, -31,
- -47, -65, -77, -79, -70, -53, -33, -14, 8, 34, 56, 62, 62, 66, 64, 54,
- 36, 15, -8, -27, -42, -61, -73, -75, -70, -56, -36, -14, 5, 26, 49, 60,
- 59, 61, 60, 54, 42, 23, -2, -22, -35, -53, -69, -75, -70, -58, -41, -20,
- -3, 18, 43, 59, 57, 57, 60, 56, 44, 28, 7, -17, -32, -47, -63, -73,
- -72, -62, -46, -23, -6, 12, 35, 55, 60, 57, 59, 56, 49, 35, 14, -13,
- -28, -40, -58, -72, -73, -62, -50, -31, -13, 5, 30, 51, 59, 56, 58, 61,
- 56, 38, 17, -9, -26, -37, -52, -68, -74, -63, -50, -32, -14, 1, 22, 45,
- 57, 56, 51, 54, 54, 41, 21, -4, -22, -31, -44, -59, -69, -63, -48, -36,
- -21, -7, 11, 35, 52, 56, 53, 54, 58, 48, 30, 8, -17, -32, -43, -57,
- -68, -69, -56, -39, -22, -8, 6, 28, 49, 57, 54, 51, 55, 52, 35, 13,
- -13, -29, -36, -49, -64, -70, -58, -39, -23, -11, 0, 19, 43, 57, 55, 47,
- 49, 55, 43, 18, -9, -28, -35, -42, -57, -69, -65, -45, -25, -11, 1, 14,
- 37, 55, 60, 50, 45, 48, 42, 21, -4, -25, -35, -40, -50, -60, -61, -46,
- -27, -15, -6, 6, 25, 46, 56, 50, 43, 45, 47, 33, 9, -15, -30, -37,
- -45, -58, -64, -56, -36, -18, -8, 4, 18, 40, 58, 59, 47, 39, 41, 35,
- 12, -15, -32, -38, -39, -46, -57, -55, -37, -17, -7, 1, 11, 27, 48, 56,
- 47, 37, 38, 38, 21, -6, -24, -32, -37, -43, -54, -57, -44, -25, -9, 2,
- 11, 24, 44, 57, 51, 38, 32, 31, 21, -5, -28, -35, -36, -36, -45, -51,
- -41, -25, -8, 3, 8, 17, 33, 48, 49, 37, 31, 30, 25, 7, -18, -30,
- -34, -37, -40, -48, -47, -33, -16, 1, 11, 16, 28, 42, 50, 43, 30, 25,
- 22, 10, -12, -28, -33, -34, -35, -41, -44, -33, -18, -2, 9, 12, 20, 32,
- 43, 41, 29, 24, 22, 14, -3, -21, -29, -30, -31, -35, -41, -35, -21, -6,
- 9, 13, 18, 27, 38, 42, 29, 18, 16, 13, 4, -15, -27, -28, -27, -28,
- -34, -34, -23, -10, 5, 11, 14, 22, 32, 37, 31, 20, 16, 12, 6, -9,
- -22, -25, -27, -26, -32, -34, -27, -15, 0, 10, 12, 18, 28, 36, 35, 23,
- 14, 11, 8, -3, -19, -28, -28, -25, -27, -32, -28, -16, -2, 11, 14, 14,
- 22, 30, 31, 24, 15, 11, 8, 2, -11, -22, -25, -25, -26, -30, -28, -18,
- -7, 5, 12, 14, 19, 27, 30, 26, 19, 13, 9, 4, -6, -20, -26, -23,
- -24, -27, -27, -19, -6, 4, 12, 12, 13, 22, 26, 22, 15, 11, 10, 6,
- -2, -12, -19, -19, -21, -25, -25, -20, -11, -3, 5, 9, 13, 19, 24, 24,
- 21, 15, 12, 7, 2, -9, -20, -22, -22, -23, -24, -22, -11, -2, 7, 11,
- 13, 17, 21, 21, 18, 13, 11, 7, 1, -7, -15, -19, -19, -21, -20, -18,
- -12, -4, 2, 8, 11, 15, 17, 16, 15, 13, 11, 8, 4, -3, -11, -16,
- -15, -19, -20, -16, -12, -5, 2, 5, 8, 14, 17, 15, 11, 10, 9, 8,
- 4, -2, -6, -11, -12, -14, -18, -13, -7, -6, -3, 2, 6, 10, 13, 13,
- 9, 8, 9, 6, 1, 0, -5, -9, -12, -12, -13, -12, -4, 1, 3, 4,
- 4, 7, 11, 10, 7, 3, 3, 4, 2, -2, -3, -6, -7, -6, -6, -8,
- -5, 2, 1, 1, 0, 1, 5, 5, 3, 0, 0, 5, 5, 2, 3, 0,
- -3, -5, -6, -8, -7, -2, -3, -4, -2, -2, 3, 6, 4, 1, -3, 1,
- 5, 3, 2, 0, -2, -3, -4, -5, -5, 1, 2, -3, -3, -4, -3, 4,
- 4, 0, -5, -3, 3, 3, 2, 1, 1, 0, 0, 0, -3, -2, 1, -2,
- -4, -3, -4, 1, 5, 2, -5, -7, -2, 2, -2, -2, 0, 2, 3, 2,
- 2, 3, 6, 4, -2, -5, -6, -2, 3, -2, -9, -11, -5, 0, -3, -4,
- -2, 3, 7, 8, 4, 2, 4, 3, 0, -6, -8, -6, 2, 4, -3, -10,
- -10, -5, -2, -4, -5, -3, 5, 11, 11, 8, 5, 5, 4, -2, -9, -9,
- -2, 0, -5, -13, -14, -10, -5, -4, -2, 2, 6, 14, 15, 11, 8, 6,
- 1, -5, -10, -12, -6, 1, -2, -10, -15, -11, -4, -3, -6, -5, 2, 14,
- 19, 14, 10, 10, 8, 3, -6, -15, -12, -4, -4, -12, -18, -17, -10, -2,
- 0, 1, 6, 16, 25, 21, 12, 8, 4, -2, -8, -18, -20, -11, -6, -9,
- -14, -14, -10, -3, 0, 1, 6, 13, 23, 25, 17, 13, 9, 1, -6, -13,
- -18, -14, -11, -13, -17, -19, -14, -8, -3, 1, 7, 14, 24, 30, 24, 16,
- 12, 4, -5, -11, -18, -19, -15, -12, -14, -19, -18, -14, -9, 0, 8, 13,
- 19, 27, 28, 22, 18, 9, -4, -11, -14, -16, -15, -16, -16, -17, -16, -14,
- -13, -6, 4, 12, 19, 26, 31, 27, 19, 13, 3, -8, -12, -16, -18, -19,
- -17, -16, -20, -18, -15, -10, 1, 10, 18, 24, 31, 30, 22, 18, 9, -4,
- -10, -14, -17, -20, -22, -19, -19, -22, -18, -13, -2, 9, 16, 21, 29, 36,
- 29, 19, 12, 1, -7, -10, -15, -22, -24, -20, -18, -21, -21, -17, -8, 7,
- 16, 23, 27, 33, 35, 26, 17, 7, -5, -11, -14, -22, -27, -24, -19, -22,
- -25, -19, -11, 5, 16, 21, 25, 33, 38, 31, 18, 9, -2, -10, -13, -22,
- -29, -28, -21, -18, -24, -22, -15, -3, 14, 21, 24, 30, 38, 36, 24, 13,
- 4, -5, -9, -16, -28, -32, -25, -21, -25, -27, -18, -7, 8, 18, 24, 31,
- 40, 40, 29, 16, 6, -3, -8, -16, -27, -31, -27, -22, -24, -27, -21, -10,
- 4, 16, 22, 28, 37, 40, 33, 19, 7, 1, -5, -12, -23, -32, -28, -23,
- -23, -27, -26, -15, -2, 13, 21, 25, 34, 41, 38, 28, 14, 4, -3, -11,
- -22, -34, -35, -30, -26, -28, -29, -20, -3, 14, 24, 27, 32, 41, 42, 34,
- 17, 4, -4, -11, -20, -32, -38, -33, -28, -27, -27, -22, -9, 7, 20, 29,
- 34, 39, 40, 37, 24, 10, 2, -7, -16, -28, -40, -40, -33, -29, -28, -27,
- -16, 5, 21, 28, 32, 36, 41, 40, 30, 12, 1, -6, -11, -22, -37, -42,
- -34, -30, -29, -27, -20, -3, 16, 27, 32, 34, 39, 41, 35, 20, 6, -4,
- -11, -16, -32, -45, -41, -33, -31, -27, -23, -10, 13, 28, 33, 35, 38, 39,
- 36, 25, 8, -6, -11, -14, -26, -42, -45, -34, -29, -25, -23, -15, 6, 26,
- 36, 36, 36, 37, 36, 29, 14, -2, -12, -14, -23, -42, -50, -42, -32, -23,
- -18, -15, 3, 25, 38, 39, 35, 35, 37, 33, 18, -3, -15, -18, -20, -34,
- -48, -47, -34, -22, -14, -12, -4, 17, 35, 41, 37, 34, 33, 33, 24, 6,
- -13, -22, -22, -30, -45, -51, -39, -23, -10, -6, -3, 13, 32, 41, 37, 30,
- 29, 31, 27, 10, -10, -22, -23, -26, -38, -48, -44, -28, -12, -5, -3, 9,
- 27, 38, 38, 32, 28, 29, 27, 17, -4, -21, -26, -27, -35, -47, -49, -33,
- -12, 2, 5, 9, 23, 35, 40, 34, 21, 23, 25, 22, 5, -20, -28, -28,
- -29, -39, -50, -43, -19, 3, 10, 7, 15, 29, 41, 43, 28, 22, 23, 22,
- 12, -16, -33, -32, -32, -38, -46, -43, -21, 3, 15, 13, 16, 29, 35, 35,
- 27, 19, 19, 19, 15, -8, -30, -31, -30, -32, -40, -44, -29, -2, 18, 17,
- 11, 22, 34, 37, 32, 21, 18, 20, 17, -2, -28, -37, -34, -34, -38, -42,
- -30, -7, 16, 22, 16, 20, 31, 31, 29, 23, 17, 18, 19, 6, -21, -37,
- -35, -34, -35, -38, -35, -15, 14, 27, 21, 13, 23, 31, 31, 26, 16, 12,
- 16, 12, -10, -35, -39, -35, -36, -36, -34, -21, 6, 24, 24, 16, 20, 29,
- 28, 27, 22, 16, 17, 15, -4, -29, -41, -39, -40, -39, -36, -29, -6, 20,
- 27, 21, 19, 28, 33, 31, 27, 18, 14, 13, 2, -22, -41, -43, -40, -39,
- -34, -28, -12, 16, 28, 24, 19, 25, 29, 27, 24, 19, 15, 12, 4, -15,
- -34, -41, -40, -37, -32, -26, -18, 5, 24, 24, 20, 21, 26, 27, 26, 24,
- 18, 12, 6, -9, -30, -44, -45, -41, -33, -26, -19, -2, 23, 29, 24, 22,
- 24, 28, 25, 22, 18, 13, 7, -7, -24, -40, -46, -42, -36, -28, -21, -6,
- 15, 28, 25, 22, 25, 29, 28, 23, 20, 14, 6, -6, -22, -40, -47, -42,
- -36, -28, -23, -10, 13, 30, 28, 21, 23, 27, 28, 21, 18, 16, 9, -2,
- -17, -33, -44, -44, -38, -31, -23, -14, 5, 25, 32, 25, 23, 26, 29, 24,
- 16, 13, 8, -2, -15, -31, -43, -44, -37, -30, -23, -14, 1, 21, 31, 27,
- 22, 24, 28, 25, 17, 13, 10, 3, -10, -27, -40, -44, -38, -32, -26, -17,
- -3, 16, 31, 31, 25, 25, 30, 29, 17, 8, 7, 3, -8, -25, -39, -43,
- -37, -31, -27, -18, -4, 13, 29, 32, 26, 24, 27, 27, 17, 9, 8, 6,
- -5, -20, -34, -39, -37, -34, -30, -21, -8, 6, 23, 34, 31, 29, 28, 27,
- 22, 13, 6, 5, -4, -18, -34, -40, -37, -34, -29, -23, -10, 5, 21, 32,
- 29, 27, 29, 26, 20, 12, 4, 3, 0, -12, -28, -37, -35, -31, -29, -23,
- -13, 1, 16, 30, 33, 29, 27, 25, 21, 15, 5, -2, -3, -9, -22, -35,
- -36, -31, -29, -24, -14, 0, 12, 27, 35, 31, 29, 26, 21, 16, 8, -2,
- -3, -7, -19, -34, -36, -32, -31, -28, -18, -3, 11, 22, 32, 32, 30, 29,
- 23, 16, 11, 2, -3, -6, -17, -32, -37, -32, -30, -31, -23, -6, 9, 18,
- 30, 36, 32, 31, 25, 17, 13, 4, -6, -8, -14, -26, -36, -34, -31, -31,
- -25, -11, 6, 16, 24, 34, 35, 33, 28, 17, 16, 10, -3, -9, -13, -23,
- -34, -36, -32, -31, -27, -16, 2, 16, 22, 30, 35, 33, 30, 21, 15, 11,
- 0, -7, -11, -20, -31, -35, -31, -31, -29, -21, -6, 13, 21, 25, 32, 34,
- 33, 26, 18, 13, 4, -6, -10, -19, -29, -34, -34, -29, -27, -24, -12, 7,
- 20, 25, 30, 33, 32, 29, 21, 13, 7, -5, -11, -18, -28, -35, -36, -29,
- -25, -24, -16, 3, 21, 26, 28, 34, 37, 34, 26, 12, 4, -5, -13, -20,
- -30, -35, -39, -35, -24, -19, -13, -2, 15, 27, 30, 32, 34, 31, 28, 18,
- 5, -6, -15, -20, -24, -31, -37, -35, -24, -19, -16, -9, 8, 24, 30, 30,
- 33, 35, 35, 24, 5, -5, -11, -20, -27, -34, -40, -39, -30, -21, -16, -9,
- 4, 20, 32, 36, 36, 36, 35, 31, 13, -3, -13, -23, -27, -29, -41, -44,
- -33, -19, -11, -10, -4, 14, 32, 38, 34, 33, 36, 33, 18, -4, -13, -20,
- -25, -28, -37, -43, -34, -22, -14, -8, -4, 9, 26, 39, 38, 35, 35, 34,
- 23, 3, -12, -21, -28, -28, -31, -41, -40, -27, -15, -7, -6, 2, 20, 37,
- 42, 36, 34, 35, 28, 9, -10, -18, -24, -26, -29, -38, -42, -32, -21, -11,
- -6, -3, 12, 33, 45, 41, 37, 37, 29, 13, -4, -17, -26, -28, -28, -33,
- -39, -37, -26, -15, -8, -7, 6, 29, 47, 46, 39, 34, 30, 20, 1, -18,
- -26, -26, -25, -29, -37, -40, -31, -17, -8, -7, 0, 20, 42, 51, 45, 38,
- 30, 18, 7, -10, -24, -27, -26, -24, -29, -38, -37, -27, -14, -9, -6, 11,
- 36, 51, 47, 42, 34, 24, 14, -3, -20, -25, -23, -22, -26, -37, -42, -33,
- -17, -8, -7, 4, 28, 50, 54, 45, 35, 24, 15, 3, -16, -24, -25, -22,
- -23, -32, -41, -37, -22, -11, -8, 0, 21, 44, 54, 46, 34, 26, 18, 7,
- -11, -22, -21, -20, -21, -28, -40, -43, -30, -15, -10, -3, 16, 40, 56, 52,
- 37, 24, 16, 9, -6, -21, -22, -18, -17, -22, -35, -43, -34, -21, -14, -9,
- 7, 34, 53, 54, 40, 29, 21, 14, 4, -14, -21, -17, -17, -22, -33, -46,
- -45, -31, -16, -8, 4, 25, 50, 60, 49, 31, 20, 15, 9, -5, -17, -18,
- -15, -17, -26, -42, -50, -40, -24, -11, -2, 18, 43, 56, 52, 35, 21, 17,
- 11, 0, -12, -18, -14, -15, -22, -36, -50, -46, -30, -15, -3, 12, 35, 53,
- 55, 41, 24, 18, 12, 5, -4, -15, -18, -15, -20, -33, -46, -49, -37, -21,
- -7, 7, 25, 46, 54, 45, 27, 18, 14, 10, 3, -8, -15, -16, -18, -28,
- -41, -49, -44, -29, -12, 4, 17, 35, 49, 49, 34, 19, 16, 15, 9, 1,
- -10, -14, -16, -24, -38, -50, -49, -36, -18, -3, 10, 26, 43, 49, 38, 22,
- 18, 20, 16, 9, -5, -13, -16, -23, -36, -50, -53, -43, -25, -8, 6, 21,
- 38, 48, 44, 27, 19, 21, 19, 13, -2, -13, -17, -21, -30, -45, -52, -46,
- -29, -10, 3, 14, 29, 42, 44, 30, 17, 19, 21, 17, 6, -8, -14, -19,
- -26, -39, -49, -48, -36, -18, -2, 11, 27, 37, 42, 37, 22, 18, 21, 19,
- 9, -5, -13, -18, -24, -33, -45, -46, -39, -24, -8, 6, 20, 33, 40, 38,
- 27, 19, 22, 23, 17, 4, -8, -14, -22, -29, -43, -48, -43, -32, -16, -2,
- 13, 25, 34, 39, 33, 23, 21, 23, 20, 9, -4, -11, -19, -25, -33, -43,
- -42, -34, -20, -7, 3, 14, 24, 32, 31, 22, 20, 26, 28, 20, 6, -5,
- -11, -18, -28, -42, -44, -38, -28, -15, -5, 8, 19, 28, 31, 24, 21, 25,
- 27, 22, 10, 0, -6, -12, -22, -34, -38, -34, -30, -20, -11, 0, 11, 20,
- 26, 23, 19, 22, 27, 25, 17, 7, -2, -7, -17, -29, -35, -35, -34, -26,
- -16, -5, 7, 15, 23, 28, 24, 21, 22, 24, 20, 11, -2, -8, -14, -24,
- -29, -31, -31, -27, -18, -9, 0, 8, 15, 22, 23, 20, 21, 24, 24, 19,
- 7, -4, -10, -19, -26, -32, -34, -33, -24, -12, -2, 6, 14, 22, 26, 23,
- 22, 22, 22, 21, 10, 0, -6, -15, -21, -24, -28, -31, -28, -17, -7, 2,
- 7, 13, 19, 23, 23, 21, 19, 21, 18, 8, -2, -11, -17, -21, -24, -30,
- -33, -25, -11, 0, 4, 9, 16, 20, 21, 20, 18, 18, 20, 14, 4, -6,
- -12, -15, -17, -25, -32, -32, -20, -6, -3, -3, 7, 18, 23, 19, 16, 19,
- 26, 24, 11, 0, -6, -9, -15, -25, -33, -35, -26, -15, -9, -6, 5, 17,
- 22, 21, 17, 18, 25, 26, 16, 4, -5, -7, -9, -18, -29, -38, -35, -21,
- -11, -9, -4, 9, 22, 25, 20, 16, 22, 30, 24, 8, -4, -5, -5, -13,
- -25, -36, -38, -26, -16, -11, -10, 2, 19, 25, 18, 12, 19, 30, 28, 14,
- 1, -2, 3, -3, -17, -31, -36, -29, -21, -18, -19, -11, 7, 20, 16, 10,
- 16, 30, 36, 24, 8, 4, 8, 6, -12, -32, -40, -35, -26, -21, -20, -14,
- 2, 19, 20, 10, 12, 24, 35, 29, 13, 5, 7, 9, -3, -23, -37, -37,
- -31, -23, -21, -19, -8, 12, 19, 10, 6, 19, 36, 37, 23, 11, 12, 16,
- 7, -15, -35, -43, -38, -30, -27, -23, -16, 2, 18, 16, 7, 13, 30, 38,
- 29, 17, 12, 16, 15, -4, -27, -40, -39, -32, -28, -28, -24, -8, 12, 14,
- 5, 7, 26, 40, 36, 24, 18, 21, 21, 4, -20, -38, -41, -37, -34, -30,
- -26, -15, 4, 14, 7, 3, 18, 37, 41, 33, 24, 22, 25, 14, -10, -33,
- -44, -42, -36, -32, -29, -22, -6, 10, 9, 2, 9, 29, 40, 37, 32, 28,
- 29, 21, 0, -24, -39, -44, -44, -38, -31, -24, -16, 0, 7, 3, 8, 24,
- 38, 43, 41, 32, 28, 25, 9, -15, -34, -44, -44, -39, -31, -26, -20, -10,
- 3, 2, 1, 14, 32, 44, 46, 39, 33, 31, 20, -7, -31, -45, -47, -44,
- -38, -30, -26, -16, 0, 5, 4, 12, 30, 45, 52, 47, 36, 30, 22, 0,
- -24, -40, -50, -49, -42, -31, -24, -19, -10, -3, 3, 11, 24, 39, 51, 55,
- 49, 37, 27, 8, -18, -36, -50, -54, -47, -36, -29, -25, -16, -6, 4, 10,
- 18, 34, 52, 59, 53, 39, 28, 15, -8, -29, -45, -53, -51, -43, -34, -29,
- -23, -14, -4, 7, 17, 33, 52, 62, 61, 50, 37, 23, -4, -28, -44, -55,
- -55, -48, -38, -30, -25, -18, -8, 5, 13, 25, 46, 61, 65, 57, 43, 30,
- 8, -17, -36, -50, -55, -53, -47, -39, -32, -24, -15, -3, 11, 25, 45, 62,
- 68, 63, 51, 37, 14, -14, -34, -46, -56, -57, -51, -44, -33, -25, -18, -6,
- 8, 19, 36, 55, 67, 65, 53, 42, 23, -4, -26, -40, -50, -56, -54, -49,
- -41, -31, -23, -12, 1, 15, 34, 53, 65, 68, 59, 49, 33, 6, -21, -37,
- -47, -57, -60, -56, -48, -38, -28, -16, -2, 14, 33, 51, 64, 70, 63, 53,
- 38, 13, -14, -34, -44, -53, -59, -59, -53, -42, -30, -19, -8, 5, 26, 47,
- 61, 68, 64, 57, 48, 26, -3, -26, -39, -49, -58, -63, -59, -49, -37, -24,
- -13, 1, 20, 42, 55, 65, 69, 64, 54, 34, 7, -18, -34, -44, -55, -65,
- -64, -54, -42, -31, -19, -8, 12, 37, 54, 61, 67, 67, 60, 46, 22, -8,
- -29, -40, -50, -64, -70, -63, -50, -34, -21, -13, 2, 28, 51, 62, 68, 68,
- 61, 51, 32, 3, -23, -36, -47, -60, -70, -67, -58, -44, -27, -14, -2, 22,
- 45, 58, 65, 70, 68, 56, 38, 16, -11, -32, -45, -58, -69, -70, -62, -52,
- -34, -17, -6, 13, 38, 54, 64, 70, 67, 59, 47, 29, -2, -28, -40, -51,
- -65, -74, -67, -54, -37, -20, -11, 5, 33, 53, 59, 63, 67, 62, 51, 34,
- 7, -20, -35, -46, -59, -72, -70, -60, -46, -27, -12, 1, 24, 47, 60, 64,
- 69, 66, 54, 39, 15, -13, -32, -44, -54, -68, -71, -60, -48, -32, -18, -7,
- 14, 38, 54, 61, 68, 70, 60, 46, 26, -2, -23, -38, -50, -63, -72, -68,
- -55, -39, -24, -13, 5, 31, 52, 61, 67, 71, 64, 53, 34, 7, -21, -36,
- -46, -57, -69, -72, -60, -42, -27, -17, -2, 21, 45, 58, 65, 69, 66, 57,
- 42, 15, -13, -30, -43, -54, -66, -72, -65, -47, -30, -18, -5, 15, 40, 57,
- 64, 67, 62, 56, 46, 23, -6, -27, -39, -50, -58, -67, -67, -51, -32, -20,
- -9, 9, 31, 51, 60, 64, 64, 58, 48, 27, 1, -20, -34, -46, -56, -65,
- -70, -57, -37, -22, -14, 2, 26, 48, 62, 66, 64, 59, 51, 34, 8, -18,
- -31, -42, -52, -61, -70, -63, -42, -24, -15, -3, 19, 43, 60, 63, 60, 57,
- 52, 39, 14, -14, -28, -36, -46, -54, -65, -66, -49, -29, -17, -9, 10, 33,
- 54, 64, 62, 58, 53, 42, 23, -5, -25, -35, -46, -54, -63, -67, -54, -33,
- -17, -7, 7, 30, 51, 61, 58, 55, 51, 43, 28, 3, -21, -30, -37, -46,
- -56, -63, -56, -39, -22, -12, -5, 16, 40, 57, 58, 55, 53, 48, 38, 19,
- -10, -27, -35, -45, -56, -66, -65, -49, -28, -14, -6, 8, 34, 57, 60, 55,
- 54, 50, 42, 26, -4, -28, -35, -42, -52, -62, -63, -51, -32, -14, -5, 3,
- 24, 47, 57, 53, 50, 47, 41, 33, 11, -20, -35, -40, -46, -56, -65, -58,
- -38, -17, -4, 1, 15, 41, 57, 55, 47, 45, 42, 35, 17, -13, -33, -38,
- -41, -49, -58, -55, -41, -21, -4, 0, 7, 29, 50, 52, 45, 42, 40, 37,
- 25, 0, -28, -38, -38, -44, -53, -58, -46, -26, -6, 3, 4, 18, 42, 53,
- 47, 41, 39, 37, 30, 10, -21, -41, -43, -41, -47, -54, -46, -29, -8, 7,
- 9, 13, 31, 46, 45, 37, 33, 33, 28, 15, -10, -35, -42, -38, -39, -45,
- -46, -32, -10, 6, 9, 8, 19, 38, 44, 38, 30, 29, 30, 19, -3, -29,
- -42, -38, -34, -40, -43, -32, -14, 3, 11, 11, 15, 30, 41, 39, 30, 25,
- 25, 19, 4, -21, -40, -42, -32, -30, -33, -29, -15, 2, 11, 10, 8, 17,
- 30, 35, 30, 23, 24, 23, 11, -11, -32, -43, -34, -26, -29, -29, -18, -3,
- 9, 12, 9, 12, 26, 35, 32, 21, 18, 18, 12, -6, -29, -43, -36, -22,
- -22, -25, -15, 1, 10, 11, 10, 8, 17, 29, 29, 21, 16, 17, 15, 2,
- -21, -39, -39, -24, -17, -20, -16, -5, 9, 13, 10, 7, 12, 24, 28, 23,
- 14, 12, 11, 4, -14, -33, -39, -28, -15, -14, -12, -6, 5, 11, 9, 7,
- 7, 16, 26, 25, 16, 10, 11, 6, -8, -24, -37, -32, -17, -12, -11, -5,
- 5, 11, 11, 10, 7, 12, 21, 21, 16, 7, 4, 3, -6, -20, -32, -32,
- -20, -8, -5, 0, 5, 11, 11, 9, 8, 8, 13, 17, 16, 9, 3, 2,
- -3, -13, -25, -31, -23, -9, -4, -2, 5, 11, 14, 11, 7, 6, 12, 15,
- 12, 5, -2, -2, -3, -11, -22, -29, -24, -9, 0, 3, 8, 13, 13, 12,
- 8, 4, 5, 7, 9, 6, -3, -5, -4, -5, -14, -24, -23, -13, 0, 4,
- 6, 10, 14, 14, 9, 3, 3, 5, 6, 4, -4, -6, -5, -5, -9, -18,
- -20, -15, -4, 6, 9, 11, 13, 13, 10, 5, 1, 0, -3, 0, -4, -6,
- -6, -5, -4, -11, -16, -16, -9, 3, 8, 11, 11, 10, 11, 8, 3, -2,
- -5, -4, -3, -5, -6, -6, -2, -5, -12, -15, -13, -2, 8, 9, 11, 11,
- 11, 7, 4, 0, -6, -6, -4, -4, -6, -6, -2, 0, -7, -13, -15, -5,
- 8, 13, 12, 9, 11, 9, 4, -5, -11, -11, -8, -5, -5, -5, 0, 4,
- 3, -4, -11, -8, 3, 11, 12, 8, 7, 4, 2, -2, -10, -14, -13, -7,
- -3, -4, -2, 3, 4, 1, -8, -8, 3, 13, 17, 12, 11, 7, 1, -6,
- -16, -21, -19, -13, -7, -2, 3, 7, 10, 10, 1, -6, -2, 8, 14, 12,
- 10, 4, -2, -6, -15, -21, -20, -15, -8, -2, 3, 5, 9, 14, 5, -6,
- 1, 12, 18, 14, 9, 7, 2, -4, -18, -28, -27, -22, -12, -5, 3, 9,
- 13, 18, 16, 5, 1, 7, 14, 13, 8, 5, -5, -9, -17, -26, -26, -23,
- -15, -4, 5, 8, 11, 17, 17, 7, 2, 7, 16, 18, 10, 4, -2, -6,
- -16, -31, -33, -27, -18, -9, 0, 7, 12, 18, 22, 16, 9, 9, 16, 20,
- 13, 5, -2, -9, -18, -33, -37, -29, -22, -13, -4, 7, 15, 21, 25, 21,
- 15, 13, 17, 20, 14, 5, -3, -8, -18, -35, -42, -36, -24, -16, -6, 5,
- 13, 23, 27, 25, 20, 17, 19, 20, 15, 5, -3, -8, -21, -35, -45, -39,
- -25, -18, -11, 3, 16, 25, 29, 27, 26, 24, 23, 21, 17, 8, -4, -12,
- -23, -35, -46, -46, -34, -22, -15, -3, 13, 25, 31, 33, 34, 31, 28, 25,
- 20, 11, -4, -12, -22, -38, -49, -51, -39, -26, -21, -11, 8, 24, 34, 35,
- 36, 37, 35, 29, 21, 13, 0, -11, -20, -36, -48, -52, -46, -31, -22, -14,
- 1, 19, 34, 38, 39, 40, 38, 34, 24, 15, 0, -14, -21, -34, -47, -53,
- -50, -35, -22, -17, -5, 13, 31, 37, 38, 42, 41, 37, 28, 21, 9, -8,
- -19, -30, -44, -50, -53, -46, -32, -23, -11, 7, 26, 39, 43, 49, 48, 42,
- 32, 20, 9, -9, -21, -31, -46, -52, -54, -50, -35, -24, -13, 4, 23, 40,
- 46, 48, 49, 46, 37, 26, 13, -4, -20, -29, -42, -50, -53, -54, -43, -31,
- -21, -2, 17, 36, 47, 53, 56, 51, 42, 29, 17, 3, -16, -30, -41, -51,
- -55, -57, -51, -35, -24, -9, 11, 30, 47, 53, 57, 55, 46, 34, 20, 6,
- -12, -29, -43, -52, -55, -55, -55, -42, -29, -12, 8, 25, 41, 55, 62, 59,
- 51, 37, 23, 10, -6, -24, -40, -51, -56, -58, -58, -48, -33, -19, 2, 22,
- 41, 55, 61, 61, 56, 45, 28, 11, -3, -19, -37, -51, -57, -58, -58, -54,
- -39, -23, -2, 20, 36, 52, 64, 65, 58, 48, 33, 19, 4, -13, -35, -51,
- -58, -61, -62, -60, -47, -29, -7, 17, 34, 50, 67, 70, 62, 50, 35, 20,
- 6, -8, -29, -47, -57, -62, -61, -60, -54, -37, -15, 10, 29, 44, 60, 68,
- 66, 56, 42, 24, 12, 1, -19, -41, -55, -60, -62, -61, -57, -43, -21, 7,
- 24, 36, 53, 66, 67, 59, 46, 30, 15, 5, -11, -32, -48, -58, -63, -62,
- -59, -50, -32, -3, 22, 35, 49, 60, 66, 63, 53, 38, 19, 8, -5, -25,
- -43, -57, -64, -64, -62, -54, -39, -13, 16, 32, 46, 59, 65, 66, 56, 45,
- 26, 11, 3, -17, -39, -56, -65, -67, -62, -56, -44, -21, 10, 29, 40, 54,
- 63, 68, 61, 49, 33, 13, 2, -14, -34, -50, -64, -67, -63, -56, -44, -26,
- 2, 27, 38, 49, 57, 64, 61, 50, 36, 17, 6, -7, -27, -44, -60, -67,
- -63, -57, -48, -32, -7, 22, 36, 44, 53, 60, 62, 55, 41, 21, 7, -3,
- -20, -40, -58, -68, -65, -57, -47, -34, -14, 16, 37, 42, 47, 55, 59, 53,
- 42, 27, 10, -2, -14, -30, -47, -60, -63, -57, -49, -38, -20, 5, 30, 40,
- 44, 52, 57, 57, 46, 31, 13, -2, -12, -27, -44, -57, -64, -61, -50, -38,
- -20, 2, 25, 39, 41, 49, 55, 54, 45, 32, 17, 0, -12, -23, -37, -50,
- -59, -61, -52, -38, -22, -6, 17, 35, 39, 42, 48, 53, 48, 36, 22, 4,
- -9, -18, -30, -45, -56, -59, -54, -42, -27, -10, 12, 29, 37, 38, 44, 50,
- 47, 37, 25, 9, -5, -13, -23, -38, -50, -55, -54, -45, -32, -17, 5, 25,
- 34, 35, 39, 46, 48, 40, 29, 13, -3, -11, -21, -33, -44, -51, -54, -47,
- -34, -17, 2, 21, 32, 34, 34, 38, 42, 39, 27, 15, 1, -7, -13, -25,
- -36, -45, -49, -46, -36, -23, -6, 15, 27, 31, 31, 34, 39, 38, 30, 18,
- 3, -6, -10, -19, -32, -40, -46, -45, -36, -24, -11, 8, 24, 29, 27, 29,
- 34, 36, 30, 18, 4, -5, -5, -12, -25, -34, -39, -41, -37, -24, -11, 4,
- 18, 24, 25, 25, 29, 29, 26, 19, 5, -6, -6, -6, -18, -28, -33, -37,
- -34, -24, -11, 2, 15, 24, 23, 20, 24, 27, 22, 14, 4, -4, -4, -5,
- -15, -24, -26, -29, -32, -27, -13, 2, 14, 21, 21, 18, 21, 23, 20, 13,
- 5, -3, -5, -4, -9, -16, -21, -25, -28, -25, -14, 1, 10, 16, 19, 16,
- 16, 18, 16, 11, 5, -2, -5, -4, -6, -12, -17, -20, -22, -22, -17, -4,
- 8, 13, 16, 15, 13, 15, 14, 10, 4, -4, -6, -6, -5, -7, -11, -15,
- -17, -17, -15, -3, 10, 13, 14, 11, 7, 8, 9, 5, -3, -8, -7, -4,
- -2, -2, -6, -10, -9, -10, -12, -5, 11, 15, 13, 11, 5, 6, 7, 3,
- -6, -10, -8, -6, -6, -2, 1, -2, -6, -6, -7, -5, 8, 14, 10, 7,
- 4, 0, 1, -2, -6, -12, -11, -6, -2, 4, 8, 4, -2, -2, -4, -5,
- 3, 12, 8, 5, 4, 0, 0, -2, -8, -13, -15, -12, -7, -3, 6, 10,
- 7, 5, 6, 4, 6, 14, 10, 3, 0, -6, -10, -7, -10, -16, -19, -15,
- -8, 0, 11, 17, 13, 10, 11, 7, 5, 8, 9, 2, -4, -7, -12, -10,
- -10, -16, -21, -19, -13, -4, 10, 21, 22, 17, 17, 14, 9, 9, 9, 3,
- -7, -12, -17, -16, -14, -20, -25, -21, -15, -5, 10, 23, 27, 25, 22, 18,
- 11, 8, 4, -2, -9, -14, -18, -19, -14, -15, -23, -25, -20, -10, 9, 22,
- 29, 29, 26, 23, 16, 12, 6, 1, -6, -14, -18, -22, -20, -19, -27, -28,
- -25, -18, 0, 19, 32, 36, 33, 31, 23, 14, 7, 1, -4, -15, -23, -25,
- -24, -19, -25, -32, -29, -20, -3, 16, 31, 40, 38, 36, 29, 16, 9, 1,
- -4, -12, -23, -26, -28, -24, -26, -34, -33, -24, -8, 12, 29, 41, 44, 44,
- 37, 22, 11, 4, -4, -11, -24, -31, -32, -31, -30, -36, -39, -30, -11, 11,
- 29, 43, 51, 50, 44, 32, 15, 4, -4, -11, -24, -32, -33, -33, -34, -38,
- -42, -35, -17, 4, 24, 42, 56, 60, 52, 38, 19, 7, 1, -13, -28, -37,
- -37, -35, -37, -39, -43, -37, -19, 3, 22, 41, 57, 64, 57, 44, 26, 7,
- -2, -11, -24, -35, -41, -40, -38, -39, -43, -40, -24, 0, 20, 37, 55, 65,
- 63, 50, 32, 9, -4, -10, -24, -36, -42, -42, -41, -41, -41, -39, -26, -2,
- 19, 34, 51, 64, 66, 55, 38, 15, -3, -8, -20, -34, -42, -44, -43, -44,
- -45, -45, -35, -12, 14, 31, 50, 66, 73, 65, 49, 28, 7, -6, -18, -35,
- -45, -49, -51, -53, -51, -47, -37, -16, 10, 30, 49, 69, 78, 72, 56, 35,
- 14, -4, -17, -33, -46, -51, -55, -56, -54, -51, -40, -20, 5, 26, 44, 64,
- 76, 77, 64, 41, 19, 1, -14, -30, -43, -50, -57, -60, -58, -54, -43, -24,
- -2, 21, 39, 61, 76, 79, 72, 52, 28, 9, -10, -26, -41, -49, -54, -61,
- -62, -59, -51, -33, -10, 14, 34, 55, 75, 81, 79, 63, 39, 19, -2, -23,
- -40, -51, -56, -64, -67, -64, -56, -39, -16, 9, 29, 51, 73, 83, 82, 73,
- 50, 27, 9, -18, -40, -52, -56, -63, -69, -69, -61, -43, -20, 2, 21, 42,
- 66, 81, 82, 76, 59, 36, 19, -6, -33, -50, -57, -61, -71, -76, -68, -52,
- -28, -2, 17, 36, 62, 83, 86, 82, 69, 43, 22, 2, -28, -51, -60, -63,
- -67, -76, -74, -57, -34, -7, 14, 29, 53, 76, 87, 84, 75, 54, 33, 14,
- -18, -46, -58, -62, -69, -80, -84, -68, -44, -18, 7, 26, 49, 75, 91, 92,
- 82, 64, 42, 21, -8, -43, -63, -68, -68, -75, -86, -76, -48, -22, 4, 23,
- 41, 66, 87, 92, 83, 69, 51, 31, 6, -31, -59, -67, -69, -74, -88, -87,
- -62, -34, -7, 17, 36, 62, 87, 96, 90, 76, 60, 39, 14, -23, -58, -70,
- -71, -73, -83, -89, -68, -37, -13, 9, 26, 51, 79, 94, 91, 80, 68, 52,
- 28, -8, -48, -67, -70, -73, -84, -96, -83, -49, -22, 0, 20, 44, 75, 96,
- 98, 88, 75, 61, 40, 6, -39, -67, -72, -75, -83, -95, -91, -60, -29, -7,
- 13, 36, 66, 89, 97, 92, 78, 65, 50, 22, -21, -58, -71, -73, -78, -91,
- -98, -79, -45, -15, 4, 25, 56, 84, 101, 99, 86, 73, 60, 35, -9, -53,
- -72, -77, -80, -90, -98, -85, -51, -20, -2, 18, 48, 77, 96, 99, 87, 75,
- 62, 46, 9, -39, -68, -75, -75, -83, -95, -94, -67, -30, -7, 8, 34, 68,
- 92, 102, 93, 82, 72, 58, 26, -24, -61, -75, -78, -85, -97, -99, -78, -42,
- -12, 6, 28, 59, 87, 102, 99, 86, 74, 62, 38, -7, -52, -76, -81, -83,
- -93, -100, -90, -57, -23, -2, 18, 48, 80, 102, 103, 92, 81, 71, 51, 9,
- -41, -72, -83, -85, -93, -100, -92, -65, -32, -7, 13, 39, 72, 97, 103, 95,
- 85, 73, 55, 25, -21, -61, -79, -83, -90, -99, -97, -77, -45, -17, 1, 24,
- 59, 93, 107, 103, 92, 85, 72, 42, -6, -54, -80, -86, -91, -104, -105, -87,
- -56, -23, 0, 18, 48, 85, 106, 106, 96, 87, 77, 52, 13, -35, -71, -84,
- -88, -98, -106, -96, -70, -40, -14, 6, 31, 70, 103, 111, 103, 95, 88, 68,
- 29, -19, -61, -84, -91, -99, -106, -101, -80, -51, -22, 2, 23, 56, 91, 109,
- 108, 98, 89, 76, 45, 1, -44, -76, -87, -92, -102, -104, -90, -64, -34, -11,
- 8, 37, 78, 108, 113, 106, 96, 85, 61, 19, -29, -68, -88, -94, -102, -104,
- -93, -73, -46, -21, 2, 28, 63, 98, 113, 109, 100, 89, 70, 33, -14, -55,
- -81, -91, -98, -104, -98, -79, -54, -30, -9, 18, 52, 89, 108, 110, 104, 96,
- 79, 46, 2, -40, -71, -90, -100, -104, -100, -86, -67, -44, -19, 7, 40, 77,
- 105, 115, 109, 99, 86, 58, 17, -29, -63, -86, -97, -101, -101, -92, -74, -50,
- -26, -4, 28, 66, 98, 114, 113, 102, 90, 68, 33, -15, -53, -76, -93, -101,
- -104, -96, -79, -57, -34, -15, 15, 56, 90, 110, 115, 105, 93, 75, 44, 0,
- -43, -68, -86, -98, -101, -98, -83, -65, -42, -22, 4, 41, 79, 104, 113, 107,
- 96, 81, 57, 16, -31, -59, -79, -95, -101, -100, -90, -71, -49, -30, -9, 28,
- 67, 97, 110, 107, 97, 86, 65, 30, -14, -47, -67, -84, -98, -102, -96, -79,
- -59, -41, -22, 14, 53, 90, 110, 111, 101, 90, 75, 45, 2, -39, -64, -79,
- -93, -102, -101, -87, -64, -44, -28, 0, 39, 81, 108, 110, 102, 93, 82, 58,
- 18, -25, -54, -70, -85, -101, -103, -94, -72, -53, -39, -14, 25, 70, 104, 112,
- 103, 96, 88, 70, 34, -13, -48, -65, -78, -97, -108, -101, -79, -55, -42, -24,
- 11, 56, 96, 111, 103, 94, 90, 77, 46, 5, -34, -56, -71, -92, -109, -109,
- -91, -64, -46, -30, 0, 44, 89, 112, 108, 95, 88, 80, 57, 16, -27, -54,
- -66, -82, -104, -112, -100, -71, -46, -34, -13, 29, 80, 111, 112, 97, 86, 84,
- 69, 32, -15, -48, -61, -72, -94, -109, -106, -82, -54, -37, -23, 11, 61, 101,
- 113, 101, 85, 80, 75, 48, 4, -37, -56, -64, -84, -107, -112, -90, -60, -37,
- -29, -7, 43, 91, 111, 103, 86, 80, 77, 58, 20, -24, -52, -61, -75, -100,
- -111, -99, -72, -44, -27, -12, 29, 77, 105, 106, 91, 80, 75, 64, 33, -9,
- -43, -58, -69, -94, -111, -104, -78, -49, -28, -18, 11, 62, 97, 107, 94, 80,
- 75, 69, 47, 6, -36, -55, -62, -81, -105, -108, -87, -59, -33, -18, 1, 46,
- 86, 103, 97, 83, 75, 69, 52, 19, -23, -50, -59, -74, -97, -106, -91, -64,
- -38, -21, -9, 26, 70, 95, 95, 80, 71, 69, 60, 35, -6, -40, -53, -64,
- -87, -102, -96, -72, -45, -25, -14, 13, 56, 87, 95, 86, 75, 69, 60, 41,
- 6, -32, -54, -62, -77, -95, -99, -79, -51, -23, -8, 6, 39, 75, 92, 87,
- 72, 64, 62, 49, 21, -17, -47, -57, -67, -86, -97, -87, -59, -32, -16, -4,
- 25, 63, 89, 92, 78, 67, 63, 53, 27, -10, -40, -55, -63, -78, -93, -89,
- -65, -36, -17, -7, 11, 44, 77, 89, 79, 65, 61, 58, 41, 8, -26, -50,
- -59, -67, -83, -90, -76, -47, -25, -13, 3, 30, 63, 85, 82, 70, 63, 58,
- 45, 14, -18, -43, -56, -63, -74, -84, -78, -52, -26, -13, -2, 19, 46, 73,
- 81, 68, 57, 55, 49, 27, -5, -32, -48, -54, -63, -77, -80, -60, -34, -17,
- -5, 10, 34, 62, 79, 71, 57, 52, 48, 31, 2, -26, -45, -50, -53, -65,
- -75, -63, -37, -16, -6, 4, 19, 45, 68, 70, 57, 49, 49, 39, 16, -11,
- -33, -45, -49, -56, -70, -71, -51, -26, -8, 2, 13, 35, 63, 76, 63, 48,
- 43, 38, 23, -7, -32, -45, -47, -47, -58, -67, -55, -30, -8, 0, 4, 20,
- 46, 68, 65, 47, 38, 38, 31, 8, -19, -37, -44, -42, -48, -63, -62, -41,
- -16, -2, 5, 16, 37, 61, 68, 53, 38, 34, 31, 14, -14, -33, -40, -38,
- -41, -54, -60, -46, -20, -5, -3, 6, 25, 49, 63, 55, 38, 32, 33, 24,
- 1, -23, -34, -35, -36, -45, -59, -55, -30, -9, -3, 2, 16, 39, 59, 59,
- 44, 32, 30, 26, 7, -20, -33, -33, -32, -40, -53, -54, -35, -12, -3, -2,
- 10, 29, 48, 55, 45, 32, 28, 27, 14, -10, -27, -30, -28, -34, -46, -53,
- -41, -17, -5, -5, 5, 24, 44, 54, 46, 32, 25, 25, 18, -4, -25, -31,
- -24, -27, -39, -47, -42, -21, -4, -2, 1, 15, 35, 46, 44, 31, 22, 23,
- 20, 6, -15, -26, -23, -20, -29, -41, -42, -29, -11, -4, -4, 7, 26, 42,
- 47, 37, 25, 21, 19, 9, -10, -25, -25, -18, -24, -38, -40, -29, -11, 1,
- 0, 3, 19, 34, 42, 33, 19, 14, 15, 10, -5, -21, -24, -15, -13, -26,
- -35, -31, -17, -2, 0, -2, 11, 26, 37, 34, 20, 14, 13, 12, 2, -17,
- -25, -17, -12, -21, -31, -30, -19, -4, 4, 1, 9, 22, 32, 32, 19, 9,
- 9, 10, 4, -11, -21, -16, -9, -14, -23, -26, -20, -8, 0, -2, 3, 15,
- 26, 31, 24, 12, 9, 10, 6, -5, -17, -19, -12, -11, -18, -25, -22, -10,
- 1, 2, 2, 11, 22, 29, 24, 10, 3, 5, 4, -4, -13, -15, -8, -5,
- -10, -16, -18, -14, -5, -2, 0, 6, 13, 20, 23, 16, 6, 5, 5, 0,
- -7, -12, -12, -8, -7, -12, -19, -18, -7, 0, 2, 7, 13, 18, 20, 13,
- 3, -2, 1, -2, -6, -8, -6, -3, -2, -2, -10, -14, -10, -6, -4, 0,
- 4, 9, 14, 15, 6, -2, -2, -2, -4, -4, -5, -3, 2, 3, -3, -10,
- -9, -5, 0, 0, 0, 3, 8, 10, 3, -5, -7, -6, -4, 0, -2, -2,
- 3, 7, 7, 2, -5, -6, -3, 2, 2, 0, 0, 2, 2, -4, -9, -9,
- -7, -3, 2, 4, 8, 9, 6, 2, -3, -4, -3, -2, -2, -2, 0, 1,
- -3, -8, -11, -8, -6, -4, 2, 6, 9, 10, 9, 8, 5, -4, -7, -3,
- 1, 1, -6, -7, -6, -6, -11, -14, -10, -5, 3, 9, 12, 14, 13, 10,
- 9, 1, -6, -5, -4, -3, -4, -6, -8, -12, -12, -13, -13, -11, -3, 9,
- 16, 18, 15, 13, 14, 11, -2, -6, -4, -3, -5, -11, -13, -12, -14, -15,
- -14, -10, -4, 6, 15, 22, 21, 16, 13, 12, 3, -7, -8, -7, -7, -10,
- -14, -17, -16, -13, -12, -10, -7, 3, 15, 24, 26, 19, 16, 18, 12, -3,
- -9, -10, -9, -11, -18, -22, -21, -17, -14, -14, -10, 0, 14, 26, 32, 28,
- 23, 22, 21, 5, -9, -12, -16, -18, -22, -27, -27, -23, -17, -13, -8, 2,
- 12, 25, 35, 36, 29, 21, 20, 11, -6, -14, -17, -19, -22, -27, -28, -24,
- -20, -15, -11, -4, 7, 19, 32, 39, 35, 28, 25, 19, 4, -10, -17, -24,
- -28, -31, -33, -30, -26, -19, -11, -3, 8, 19, 31, 42, 42, 34, 27, 21,
- 9, -9, -19, -26, -31, -35, -34, -30, -26, -23, -13, -4, 4, 14, 25, 42,
- 49, 41, 31, 27, 20, 3, -15, -28, -37, -38, -39, -38, -35, -29, -16, 0,
- 9, 17, 26, 41, 52, 48, 36, 26, 19, 6, -16, -30, -39, -43, -41, -39,
- -33, -29, -22, -5, 7, 13, 21, 36, 55, 56, 46, 34, 24, 15, -8, -29,
- -44, -54, -50, -44, -39, -35, -27, -7, 11, 20, 25, 34, 54, 63, 53, 38,
- 22, 14, 0, -27, -45, -56, -56, -46, -39, -36, -31, -14, 8, 19, 23, 29,
- 46, 63, 61, 47, 30, 20, 8, -15, -39, -56, -62, -54, -44, -41, -38, -23,
- -2, 16, 23, 28, 42, 63, 69, 58, 41, 25, 13, -7, -34, -56, -68, -64,
- -50, -45, -43, -29, -7, 15, 26, 29, 40, 58, 72, 67, 48, 30, 16, 0,
- -26, -53, -68, -69, -57, -47, -46, -36, -16, 9, 25, 30, 38, 53, 71, 74,
- 58, 37, 17, 2, -21, -49, -70, -76, -64, -49, -43, -38, -21, 3, 25, 33,
- 37, 49, 65, 74, 65, 45, 24, 8, -11, -40, -68, -79, -72, -57, -48, -42,
- -29, -6, 20, 34, 39, 48, 63, 77, 74, 56, 31, 11, -8, -33, -61, -79,
- -80, -68, -53, -45, -34, -16, 11, 31, 41, 51, 61, 75, 78, 64, 42, 19,
- -3, -27, -55, -78, -84, -73, -59, -48, -37, -20, 5, 27, 40, 49, 58, 71,
- 80, 71, 49, 23, 2, -20, -47, -72, -86, -82, -66, -52, -39, -26, -5, 20,
- 39, 51, 59, 69, 79, 77, 61, 34, 7, -16, -42, -68, -88, -90, -75, -58,
- -41, -26, -8, 17, 39, 52, 59, 65, 74, 77, 65, 41, 12, -12, -35, -60,
- -81, -89, -79, -60, -45, -33, -17, 6, 31, 49, 59, 64, 73, 80, 74, 51,
- 22, -5, -29, -54, -78, -92, -90, -70, -49, -35, -18, 3, 26, 48, 60, 64,
- 68, 75, 75, 58, 31, 1, -25, -48, -73, -88, -90, -77, -56, -41, -23, -3,
- 21, 43, 58, 64, 70, 75, 77, 64, 40, 12, -18, -44, -70, -87, -94, -87,
- -64, -42, -22, -4, 16, 39, 58, 65, 66, 67, 74, 68, 46, 18, -12, -38,
- -62, -82, -92, -89, -67, -45, -28, -9, 13, 31, 52, 64, 67, 66, 72, 71,
- 53, 29, -3, -34, -59, -79, -94, -96, -77, -50, -29, -8, 12, 30, 49, 63,
- 68, 67, 68, 70, 56, 34, 6, -29, -57, -77, -92, -99, -84, -56, -32, -10,
- 11, 29, 45, 61, 69, 69, 68, 70, 60, 37, 12, -20, -50, -73, -90, -100,
- -91, -64, -37, -14, 7, 25, 42, 57, 66, 67, 65, 67, 64, 45, 21, -9,
- -41, -66, -84, -98, -95, -74, -47, -21, 3, 23, 39, 54, 64, 69, 69, 67,
- 63, 50, 27, 0, -33, -63, -83, -94, -95, -79, -54, -26, -2, 18, 35, 49,
- 61, 67, 67, 65, 64, 55, 33, 6, -25, -55, -82, -95, -98, -84, -60, -32,
- -6, 17, 36, 48, 56, 64, 66, 65, 62, 55, 39, 14, -16, -46, -76, -92,
- -96, -88, -69, -41, -9, 15, 33, 46, 54, 62, 68, 66, 59, 54, 44, 20,
- -12, -41, -72, -92, -97, -90, -71, -46, -14, 15, 34, 48, 55, 59, 62, 63,
- 60, 51, 42, 24, -6, -34, -63, -87, -95, -89, -75, -52, -23, 10, 31, 45,
- 54, 58, 62, 66, 63, 51, 42, 30, 1, -32, -59, -84, -96, -93, -80, -58,
- -28, 7, 32, 45, 53, 60, 64, 67, 62, 52, 41, 31, 9, -25, -55, -78,
- -92, -91, -82, -65, -39, -2, 30, 43, 49, 56, 61, 65, 63, 54, 44, 33,
- 16, -15, -47, -72, -88, -91, -84, -70, -45, -12, 22, 42, 48, 54, 58, 61,
- 63, 56, 43, 32, 20, -4, -36, -65, -82, -87, -82, -72, -53, -23, 15, 40,
- 46, 48, 55, 61, 62, 55, 43, 32, 21, 4, -26, -57, -75, -82, -80, -73,
- -58, -30, 5, 35, 46, 47, 51, 57, 61, 57, 46, 34, 22, 9, -15, -47,
- -71, -81, -80, -75, -62, -36, -4, 28, 46, 47, 49, 56, 60, 57, 48, 35,
- 23, 12, -9, -39, -67, -78, -76, -71, -65, -45, -13, 21, 45, 50, 46, 50,
- 58, 59, 49, 35, 23, 12, -4, -31, -62, -78, -74, -70, -65, -49, -18, 18,
- 43, 51, 45, 48, 56, 56, 45, 30, 20, 12, 0, -24, -53, -71, -69, -63,
- -60, -51, -25, 9, 36, 50, 47, 44, 50, 52, 45, 32, 21, 12, 1, -18,
- -44, -66, -70, -64, -59, -51, -31, 2, 32, 50, 51, 46, 47, 52, 47, 32,
- 17, 9, 0, -14, -34, -57, -67, -62, -56, -50, -33, -6, 24, 44, 51, 48,
- 47, 48, 46, 34, 21, 12, 2, -13, -32, -51, -62, -62, -56, -51, -38, -13,
- 18, 40, 51, 50, 45, 47, 46, 36, 20, 9, -2, -14, -28, -45, -59, -61,
- -54, -48, -37, -15, 14, 36, 49, 52, 48, 44, 42, 33, 19, 10, 0, -13,
- -26, -39, -52, -58, -54, -47, -37, -19, 9, 30, 44, 52, 48, 40, 38, 31,
- 19, 7, -3, -12, -22, -31, -42, -51, -49, -43, -36, -22, 1, 22, 35, 45,
- 47, 41, 37, 31, 23, 13, 3, -11, -22, -28, -36, -48, -53, -46, -35, -23,
- -4, 17, 31, 45, 49, 41, 33, 29, 23, 13, 2, -11, -22, -26, -29, -38,
- -46, -45, -34, -21, -6, 14, 25, 38, 46, 43, 35, 27, 19, 10, 3, -7,
- -20, -28, -28, -32, -38, -41, -35, -23, -8, 10, 23, 33, 44, 44, 36, 27,
- 18, 10, 0, -9, -22, -28, -28, -28, -33, -37, -32, -21, -7, 8, 20, 28,
- 38, 41, 36, 27, 17, 8, -2, -6, -17, -28, -31, -28, -27, -30, -30, -22,
- -7, 9, 19, 26, 35, 41, 37, 26, 16, 6, -5, -11, -18, -28, -31, -28,
- -22, -23, -23, -18, -4, 11, 19, 24, 27, 33, 33, 24, 14, 3, -8, -11,
- -15, -23, -29, -29, -21, -18, -19, -15, -5, 9, 16, 21, 26, 30, 32, 25,
- 13, 2, -9, -13, -16, -21, -27, -27, -20, -12, -13, -14, -7, 9, 17, 20,
- 24, 25, 26, 27, 15, 2, -9, -17, -17, -20, -25, -28, -23, -11, -6, -8,
- -5, 7, 19, 23, 24, 24, 24, 25, 16, 0, -13, -22, -22, -22, -26, -28,
- -22, -8, 2, 1, 0, 8, 18, 24, 24, 20, 18, 20, 15, 1, -12, -22,
- -24, -22, -23, -25, -22, -13, 2, 7, 3, 8, 16, 25, 28, 21, 15, 15,
- 15, 4, -13, -25, -29, -24, -20, -24, -21, -12, 1, 12, 10, 9, 16, 23,
- 27, 21, 14, 12, 10, 3, -10, -21, -28, -27, -22, -22, -20, -14, -4, 10,
- 14, 11, 17, 23, 29, 26, 15, 11, 10, 4, -12, -25, -33, -33, -26, -23,
- -22, -12, 0, 13, 22, 19, 20, 25, 29, 25, 12, 5, 3, 0, -12, -25,
- -32, -34, -27, -21, -20, -11, -2, 7, 18, 21, 22, 26, 30, 29, 21, 11,
- 4, -5, -14, -29, -38, -38, -33, -27, -23, -10, 4, 12, 22, 29, 30, 30,
- 31, 30, 21, 10, 0, -11, -19, -30, -39, -40, -36, -28, -20, -9, 4, 12,
- 20, 29, 32, 30, 32, 32, 23, 12, 3, -8, -18, -27, -39, -44, -40, -32,
- -25, -15, 1, 13, 22, 30, 37, 38, 36, 34, 26, 14, 2, -11, -22, -31,
- -40, -45, -42, -35, -26, -14, 0, 12, 19, 26, 35, 39, 36, 33, 28, 18,
- 6, -7, -18, -28, -37, -43, -43, -37, -30, -19, -6, 8, 20, 25, 34, 42,
- 41, 37, 32, 22, 8, -7, -19, -32, -40, -44, -44, -38, -30, -20, -6, 8,
- 19, 24, 30, 40, 41, 36, 29, 23, 13, -3, -16, -28, -39, -43, -44, -41,
- -34, -23, -11, 2, 16, 25, 32, 41, 46, 42, 34, 26, 15, 0, -16, -29,
- -40, -45, -45, -40, -32, -24, -12, -2, 12, 22, 26, 37, 45, 44, 34, 24,
- 18, 6, -12, -24, -37, -41, -40, -40, -36, -30, -17, -4, 9, 18, 25, 37,
- 45, 45, 40, 29, 19, 8, -8, -22, -38, -43, -42, -42, -35, -28, -17, -4,
- 7, 17, 23, 33, 43, 43, 38, 28, 19, 12, -3, -19, -34, -40, -38, -40,
- -38, -31, -22, -8, 5, 14, 21, 31, 44, 47, 41, 31, 20, 13, 3, -15,
- -33, -45, -45, -41, -38, -31, -24, -10, 4, 15, 21, 29, 42, 47, 41, 33,
- 22, 13, 4, -13, -29, -40, -41, -41, -41, -36, -26, -14, -2, 8, 17, 29,
- 42, 50, 46, 37, 27, 17, 7, -9, -27, -41, -48, -45, -42, -38, -29, -15,
- -2, 10, 18, 26, 38, 50, 51, 40, 28, 17, 6, -7, -24, -36, -43, -45,
- -41, -38, -31, -18, -8, 2, 13, 26, 38, 44, 49, 42, 33, 22, 8, -4,
- -20, -32, -41, -46, -44, -37, -32, -21, -8, 2, 14, 25, 35, 42, 47, 44,
- 31, 19, 7, -4, -15, -28, -36, -42, -40, -34, -31, -24, -9, 0, 7, 18,
- 30, 40, 44, 42, 32, 22, 12, 2, -10, -23, -31, -38, -42, -38, -31, -26,
- -13, -3, 2, 14, 29, 40, 41, 40, 36, 26, 13, 1, -10, -19, -26, -35,
- -43, -41, -33, -27, -17, -6, 1, 12, 27, 43, 47, 42, 37, 29, 14, 0,
- -10, -21, -29, -34, -40, -42, -33, -26, -18, -5, 3, 10, 23, 39, 45, 39,
- 33, 30, 18, 3, -8, -15, -22, -29, -37, -43, -36, -27, -22, -13, -4, 6,
- 19, 36, 47, 47, 37, 33, 25, 6, -8, -15, -25, -31, -36, -43, -42, -32,
- -21, -11, 0, 5, 15, 32, 46, 45, 35, 31, 28, 12, -6, -13, -20, -24,
- -31, -41, -46, -38, -26, -18, -9, 1, 14, 31, 43, 48, 42, 33, 28, 15,
- -5, -15, -18, -24, -31, -38, -41, -34, -26, -19, -8, 1, 10, 23, 37, 43,
- 41, 32, 26, 19, 3, -12, -15, -18, -24, -34, -42, -38, -28, -20, -13, -4,
- 6, 21, 37, 44, 43, 36, 28, 21, 8, -9, -16, -19, -25, -34, -42, -39,
- -29, -21, -13, -3, 8, 19, 34, 42, 41, 36, 28, 20, 8, -7, -15, -16,
- -19, -30, -41, -42, -31, -23, -15, -8, 3, 19, 36, 43, 39, 36, 30, 23,
- 13, -6, -19, -21, -20, -26, -38, -43, -35, -25, -15, -7, 3, 14, 30, 42,
- 40, 35, 28, 23, 16, 0, -14, -20, -19, -22, -34, -42, -37, -26, -15, -8,
- 0, 12, 27, 40, 41, 35, 29, 22, 16, 4, -9, -19, -20, -20, -29, -39,
- -39, -30, -19, -10, -3, 10, 24, 37, 42, 37, 31, 25, 18, 7, -7, -17,
- -21, -20, -28, -38, -40, -33, -22, -11, -5, 9, 25, 37, 44, 40, 32, 24,
- 17, 10, -5, -18, -24, -23, -28, -35, -38, -35, -26, -14, -5, 5, 19, 34,
- 44, 42, 33, 23, 18, 13, 0, -15, -20, -22, -26, -33, -39, -35, -28, -18,
- -10, 1, 18, 33, 43, 45, 38, 28, 20, 11, 2, -12, -22, -24, -28, -31,
- -36, -35, -29, -21, -11, 0, 15, 30, 40, 44, 39, 31, 21, 13, 8, -5,
- -17, -20, -25, -28, -32, -36, -34, -27, -18, -7, 9, 26, 39, 46, 45, 36,
- 25, 14, 10, -2, -16, -24, -29, -31, -31, -36, -36, -27, -16, -7, 6, 23,
- 37, 45, 44, 36, 26, 14, 8, 1, -14, -22, -23, -29, -32, -35, -36, -29,
- -21, -14, 0, 16, 35, 46, 45, 39, 33, 20, 8, 3, -9, -21, -28, -32,
- -34, -35, -36, -32, -25, -15, 1, 17, 32, 45, 49, 44, 35, 23, 7, 0,
- -7, -17, -25, -30, -31, -32, -34, -31, -25, -18, -7, 10, 27, 43, 50, 45,
- 35, 24, 13, 3, -7, -17, -24, -28, -30, -30, -33, -34, -26, -19, -11, 5,
- 22, 39, 50, 48, 37, 26, 16, 5, -7, -18, -23, -27, -28, -28, -33, -34,
- -24, -16, -11, 2, 17, 33, 48, 48, 37, 27, 18, 7, -5, -14, -20, -25,
- -30, -31, -32, -37, -31, -20, -15, -3, 15, 30, 46, 53, 43, 31, 20, 11,
- 0, -12, -21, -27, -31, -30, -30, -36, -33, -20, -10, -5, 9, 25, 41, 52,
- 46, 34, 23, 15, 6, -9, -21, -27, -30, -31, -31, -37, -39, -25, -12, -7,
- 1, 18, 36, 52, 53, 40, 28, 22, 13, -2, -18, -29, -32, -35, -34, -39,
- -40, -28, -13, -7, -2, 12, 33, 50, 56, 44, 30, 24, 18, 4, -15, -29,
- -32, -33, -33, -35, -40, -35, -20, -7, -2, 8, 25, 43, 54, 49, 35, 25,
- 18, 8, -7, -23, -32, -32, -34, -34, -37, -36, -24, -11, -5, 2, 18, 36,
- 51, 51, 39, 30, 24, 14, 0, -19, -32, -35, -35, -37, -38, -39, -29, -12,
- -2, 3, 14, 29, 47, 54, 45, 33, 26, 17, 5, -12, -31, -37, -36, -38,
- -38, -38, -32, -17, -3, 3, 9, 25, 42, 53, 49, 39, 31, 23, 10, -9,
- -27, -38, -40, -41, -41, -41, -36, -23, -5, 5, 8, 18, 36, 51, 51, 43,
- 34, 26, 16, 1, -20, -36, -40, -41, -42, -40, -38, -28, -10, 4, 7, 14,
- 30, 48, 51, 45, 39, 31, 21, 4, -16, -33, -41, -43, -43, -39, -38, -32,
- -15, 1, 7, 13, 25, 42, 52, 48, 39, 31, 22, 9, -10, -29, -40, -40,
- -40, -38, -35, -34, -20, -2, 5, 9, 17, 33, 49, 50, 43, 34, 25, 13,
- -4, -21, -36, -44, -44, -40, -35, -34, -26, -8, 5, 11, 17, 26, 43, 51,
- 46, 36, 27, 16, 1, -16, -31, -42, -46, -43, -37, -35, -29, -12, 3, 11,
- 17, 23, 37, 50, 52, 41, 29, 20, 4, -15, -30, -43, -49, -46, -39, -37,
- -33, -15, 3, 13, 19, 23, 35, 52, 55, 44, 29, 20, 8, -12, -28, -40,
- -48, -45, -39, -35, -32, -20, -2, 12, 16, 19, 28, 45, 55, 49, 35, 24,
- 14, -3, -20, -36, -49, -53, -45, -38, -35, -27, -9, 8, 19, 23, 26, 40,
- 55, 55, 41, 25, 15, -2, -19, -33, -46, -53, -47, -39, -35, -29, -14, 6,
- 19, 24, 25, 35, 53, 59, 47, 29, 17, 7, -12, -30, -47, -58, -56, -47,
- -39, -35, -22, -2, 17, 28, 30, 34, 50, 63, 56, 35, 19, 8, -9, -26,
- -43, -56, -58, -49, -42, -38, -27, -9, 12, 26, 33, 34, 44, 60, 62, 44,
- 23, 9, -4, -20, -40, -56, -63, -56, -44, -39, -30, -14, 8, 26, 35, 35,
- 43, 60, 64, 50, 28, 13, 2, -16, -37, -53, -62, -61, -50, -42, -32, -17,
- 2, 18, 32, 40, 44, 54, 63, 55, 37, 17, 4, -10, -31, -48, -61, -67,
- -59, -45, -36, -24, -5, 17, 33, 43, 47, 54, 64, 59, 42, 20, 3, -10,
- -28, -49, -63, -68, -63, -50, -37, -25, -7, 13, 31, 44, 48, 54, 61, 59,
- 48, 27, 6, -10, -24, -43, -59, -67, -67, -56, -39, -28, -13, 8, 24, 42,
- 51, 54, 58, 58, 52, 37, 14, -6, -20, -38, -54, -65, -70, -63, -45, -29,
- -17, 2, 18, 37, 52, 56, 58, 56, 51, 42, 23, -2, -19, -34, -50, -62,
- -70, -69, -52, -30, -17, -3, 15, 33, 50, 58, 58, 56, 52, 46, 29, 3,
- -15, -31, -45, -58, -68, -71, -60, -38, -20, -5, 11, 25, 42, 58, 62, 58,
- 51, 44, 36, 15, -10, -29, -43, -53, -64, -72, -67, -45, -21, -8, 4, 20,
- 40, 60, 65, 57, 53, 48, 42, 21, -8, -27, -40, -50, -62, -71, -71, -54,
- -29, -9, 3, 18, 34, 54, 68, 65, 57, 48, 40, 28, 2, -23, -41, -52,
- -60, -71, -75, -60, -34, -12, 0, 13, 31, 52, 69, 66, 56, 50, 44, 33,
- 7, -21, -38, -47, -55, -65, -75, -67, -41, -15, 2, 11, 23, 41, 61, 68,
- 59, 49, 40, 34, 17, -11, -35, -47, -48, -55, -69, -72, -50, -21, 0, 8,
- 15, 33, 56, 69, 62, 52, 44, 40, 26, -4, -30, -44, -48, -56, -69, -77,
- -59, -28, -7, 7, 15, 30, 52, 68, 66, 55, 45, 38, 30, 6, -24, -43,
- -49, -52, -64, -75, -65, -35, -10, 4, 11, 25, 45, 65, 67, 55, 48, 43,
- 34, 13, -18, -39, -45, -49, -61, -75, -72, -45, -17, -2, 9, 20, 39, 61,
- 70, 62, 52, 45, 36, 18, -9, -34, -47, -52, -58, -69, -72, -52, -23, -5,
- 7, 17, 35, 54, 65, 63, 55, 45, 37, 23, 0, -27, -45, -49, -53, -63,
- -71, -59, -31, -8, 7, 15, 28, 47, 61, 65, 58, 47, 38, 27, 6, -21,
- -41, -49, -53, -62, -69, -62, -39, -14, 3, 14, 28, 46, 59, 64, 62, 51,
- 39, 29, 11, -16, -40, -52, -55, -58, -65, -65, -47, -20, 1, 14, 24, 39,
- 52, 59, 64, 56, 43, 33, 16, -8, -32, -49, -55, -58, -63, -65, -54, -29,
- -3, 12, 21, 36, 51, 60, 65, 59, 46, 35, 21, -4, -28, -48, -56, -57,
- -59, -60, -55, -37, -12, 9, 19, 32, 46, 54, 58, 58, 48, 36, 26, 7,
- -18, -41, -53, -53, -52, -57, -58, -45, -19, 6, 15, 26, 42, 54, 59, 59,
- 52, 39, 28, 10, -16, -40, -56, -56, -52, -51, -53, -45, -22, 4, 17, 24,
- 35, 46, 56, 57, 52, 40, 30, 18, -7, -33, -54, -58, -52, -49, -53, -51,
- -33, -5, 17, 26, 34, 43, 54, 58, 53, 42, 31, 19, 0, -24, -47, -60,
- -55, -46, -46, -50, -39, -13, 13, 25, 32, 38, 48, 56, 52, 41, 30, 20,
- 7, -15, -41, -58, -55, -44, -41, -44, -40, -19, 10, 25, 28, 32, 41, 53,
- 52, 42, 31, 21, 13, -5, -32, -55, -60, -47, -36, -38, -40, -26, 2, 24,
- 29, 28, 32, 46, 48, 40, 29, 21, 14, 1, -23, -48, -56, -46, -34, -33,
- -36, -29, -7, 20, 28, 25, 26, 37, 46, 42, 30, 19, 15, 7, -13, -39,
- -58, -54, -37, -27, -27, -29, -17, 13, 29, 28, 24, 31, 42, 42, 34, 21,
- 11, 5, -10, -32, -51, -52, -40, -28, -24, -24, -18, 6, 27, 30, 26, 28,
- 36, 38, 33, 22, 11, 6, -7, -26, -44, -49, -42, -30, -21, -17, -16, -5,
- 18, 29, 26, 25, 29, 33, 33, 25, 13, 7, 0, -18, -36, -46, -45, -31,
- -20, -16, -16, -9, 12, 28, 29, 24, 25, 29, 31, 26, 13, 2, -5, -15,
- -26, -39, -46, -37, -19, -9, -9, -11, 1, 21, 31, 26, 21, 23, 26, 25,
- 15, 4, -4, -10, -20, -32, -41, -38, -22, -10, -7, -9, -6, 11, 26, 29,
- 22, 20, 21, 24, 19, 7, -6, -12, -17, -23, -30, -36, -27, -12, -3, 0,
- -5, 3, 18, 28, 25, 18, 15, 16, 15, 7, -4, -10, -14, -19, -24, -30,
- -26, -13, -3, 2, -3, -2, 12, 23, 26, 18, 13, 13, 14, 9, 0, -11,
- -14, -15, -18, -24, -26, -16, -4, 4, 0, -5, 6, 17, 25, 21, 11, 7,
- 8, 8, 1, -11, -14, -11, -10, -13, -20, -18, -7, 5, 7, -3, -2, 8,
- 21, 23, 12, 4, 4, 8, 7, -5, -15, -14, -11, -9, -15, -20, -13, 1,
- 8, 3, 0, 6, 17, 24, 16, 3, -2, 1, 0, -10, -17, -14, -8, -4,
- -5, -11, -12, 0, 9, 6, -3, 1, 10, 18, 16, 5, -3, 0, 3, -4,
- -13, -15, -10, -6, -4, -8, -13, -8, 5, 8, 5, 3, 9, 17, 18, 13,
- 0, -7, -5, -5, -11, -14, -11, -6, 2, 2, -6, -9, 1, 8, 5, -2,
- 1, 8, 14, 12, 2, -6, -5, -2, -6, -12, -10, -2, 3, 4, -5, -11,
- -6, 5, 6, 0, 0, 7, 12, 14, 6, -7, -8, -6, -6, -9, -10, -5,
- 4, 8, 4, -7, -11, -2, 6, 3, -2, 2, 9, 15, 12, -2, -8, -6,
- -3, -5, -11, -9, 2, 10, 7, -5, -15, -10, 4, 6, -2, -2, 8, 14,
- 14, 3, -9, -8, -5, -4, -8, -10, 0, 8, 9, 3, -9, -12, -3, 6,
- 3, -3, 1, 8, 13, 5, -9, -13, -7, -2, -2, -6, -2, 9, 13, 6,
- -6, -13, -10, 2, 4, -3, -2, 7, 13, 9, -6, -12, -11, -6, 0, -5,
- -5, 7, 15, 13, 1, -10, -13, -4, 5, -2, -7, -2, 9, 9, -3, -11,
- -11, -8, 2, 1, -3, 7, 15, 12, 4, -7, -13, -11, -2, 1, -4, -3,
- 7, 11, 3, -8, -11, -10, 0, 1, -5, 2, 12, 17, 11, -2, -11, -11,
- -3, 4, -4, -9, 1, 10, 3, -9, -11, -8, 0, 5, 1, 2, 11, 14,
- 9, 1, -11, -15, -11, -3, 1, -3, 3, 12, 11, 1, -7, -9, -6, -3,
- -5, -5, 5, 12, 9, 4, -3, -8, -8, -5, 0, -4, -3, 5, 6, -3,
- -10, -7, -3, 0, 2, 3, 10, 14, 11, 4, -3, -11, -15, -15, -9, -5,
- -5, 5, 13, 5, -2, 0, 2, 4, 1, -3, 4, 12, 11, 2, -5, -10,
- -13, -13, -11, -6, -4, 3, 13, 9, 1, -2, 4, 5, 1, -5, 3, 12,
- 13, 4, -9, -12, -14, -16, -17, -12, -5, 5, 16, 17, 6, 3, 9, 9,
- 2, -8, -7, 2, 7, 4, -8, -12, -10, -13, -14, -13, -6, 4, 13, 19,
- 10, 0, 6, 14, 8, -6, -9, 0, 7, 5, -8, -17, -13, -9, -14, -18,
- -13, 2, 15, 23, 16, 4, 5, 16, 15, 0, -10, -6, 3, 6, -4, -15,
- -15, -10, -11, -16, -16, -5, 10, 21, 18, 7, 2, 12, 18, 6, -7, -9,
- 1, 7, 1, -14, -19, -15, -13, -16, -18, -8, 7, 19, 24, 16, 5, 8,
- 16, 9, -4, -9, -5, 3, 4, -9, -19, -18, -13, -12, -17, -12, 2, 16,
- 22, 17, 6, 4, 14, 13, 1, -8, -6, 2, 6, -5, -18, -20, -16, -14,
- -18, -17, -5, 12, 23, 24, 14, 9, 15, 19, 9, -5, -8, -3, 2, -6,
- -17, -23, -19, -14, -16, -17, -8, 7, 19, 24, 19, 10, 11, 17, 13, 3,
- -5, -3, -2, -4, -14, -24, -25, -20, -18, -16, -10, 3, 16, 26, 28, 18,
- 11, 15, 17, 9, -4, -7, -6, -6, -12, -24, -29, -22, -16, -15, -10, 0,
- 13, 24, 27, 22, 14, 13, 16, 13, 2, -6, -7, -9, -12, -21, -29, -27,
- -21, -15, -10, -3, 8, 21, 29, 26, 17, 13, 17, 19, 9, -5, -10, -9,
- -12, -21, -30, -29, -22, -14, -10, -4, 7, 17, 26, 23, 17, 13, 12, 18,
- 16, 5, -6, -10, -11, -19, -29, -32, -27, -18, -10, -4, 4, 13, 25, 26,
- 21, 16, 11, 16, 17, 8, -5, -12, -12, -16, -25, -30, -27, -19, -10, -6,
- 0, 10, 21, 24, 18, 15, 13, 16, 20, 14, 1, -10, -12, -15, -26, -31,
- -29, -22, -12, -5, 0, 8, 19, 25, 22, 17, 14, 14, 19, 17, 4, -10,
- -15, -15, -22, -30, -30, -26, -16, -6, 1, 7, 15, 23, 23, 18, 17, 17,
- 17, 17, 8, -6, -15, -18, -24, -31, -29, -26, -19, -8, 2, 7, 15, 23,
- 24, 21, 17, 15, 15, 17, 13, -4, -16, -20, -23, -30, -32, -27, -19, -8,
- 3, 7, 14, 23, 24, 20, 16, 16, 15, 14, 10, 0, -12, -20, -24, -31,
- -32, -25, -19, -10, 0, 9, 14, 22, 27, 23, 17, 17, 18, 12, 8, 1,
- -12, -18, -23, -31, -34, -26, -17, -9, -2, 6, 14, 22, 27, 22, 16, 15,
- 18, 17, 10, 3, -9, -17, -21, -31, -38, -32, -23, -13, -5, 4, 14, 21,
- 30, 30, 21, 17, 18, 17, 10, 3, -8, -20, -23, -29, -38, -34, -25, -12,
- 0, 3, 11, 17, 26, 31, 23, 15, 13, 16, 14, 5, -4, -15, -19, -23,
- -35, -38, -32, -19, -7, -5, 6, 16, 25, 36, 32, 22, 19, 19, 15, 3,
- -7, -16, -23, -26, -35, -42, -34, -19, -3, 1, 6, 18, 26, 37, 34, 20,
- 15, 14, 14, 5, -7, -15, -21, -23, -28, -39, -37, -22, -5, 1, 3, 15,
- 25, 35, 40, 27, 14, 14, 14, 6, -7, -14, -20, -25, -27, -36, -41, -28,
- -8, 2, 4, 14, 24, 33, 40, 32, 17, 13, 12, 5, -7, -14, -17, -24,
- -28, -34, -40, -32, -14, 1, 4, 13, 26, 33, 41, 40, 26, 15, 12, 4,
- -9, -17, -20, -25, -31, -34, -41, -38, -20, 0, 7, 12, 24, 32, 40, 41,
- 30, 17, 11, 4, -10, -18, -19, -21, -27, -31, -35, -36, -24, -5, 5, 9,
- 21, 31, 37, 41, 36, 21, 11, 4, -8, -15, -18, -21, -26, -31, -34, -37,
- -30, -12, 3, 9, 18, 30, 38, 44, 42, 29, 15, 7, -6, -18, -23, -24,
- -25, -31, -34, -36, -33, -15, 3, 9, 17, 28, 38, 44, 42, 34, 20, 8,
- -5, -18, -23, -22, -24, -30, -35, -35, -35, -24, -6, 6, 14, 25, 36, 42,
- 45, 42, 28, 13, 1, -15, -26, -27, -26, -29, -35, -39, -38, -28, -10, 5,
- 13, 21, 36, 47, 48, 45, 36, 21, 6, -11, -25, -31, -30, -29, -35, -41,
- -41, -34, -18, 1, 15, 24, 35, 47, 52, 51, 42, 26, 8, -9, -25, -32,
- -34, -32, -34, -40, -41, -35, -22, -5, 11, 21, 30, 44, 52, 51, 45, 32,
- 15, -3, -19, -28, -33, -34, -36, -42, -44, -41, -30, -13, 6, 20, 29, 43,
- 54, 56, 50, 37, 22, 4, -17, -31, -39, -39, -38, -40, -44, -41, -31, -14,
- 4, 18, 26, 37, 52, 57, 54, 44, 29, 11, -9, -26, -38, -42, -40, -41,
- -45, -46, -39, -24, -2, 17, 25, 35, 49, 59, 59, 52, 36, 19, -2, -22,
- -38, -46, -45, -43, -44, -47, -41, -28, -7, 12, 22, 32, 45, 58, 60, 52,
- 40, 26, 9, -14, -36, -46, -47, -44, -44, -50, -47, -34, -14, 8, 21, 30,
- 42, 58, 65, 58, 46, 32, 14, -7, -30, -47, -51, -50, -45, -50, -51, -38,
- -20, 4, 19, 28, 38, 53, 67, 63, 50, 40, 23, 2, -22, -43, -54, -55,
- -50, -53, -57, -48, -31, -6, 17, 28, 39, 53, 69, 72, 60, 47, 29, 7,
- -18, -39, -54, -59, -56, -53, -55, -52, -37, -16, 10, 25, 36, 48, 65, 75,
- 68, 54, 40, 20, -6, -31, -52, -61, -61, -59, -63, -62, -46, -24, 2, 20,
- 33, 50, 67, 79, 75, 62, 49, 30, 2, -29, -50, -63, -66, -65, -64, -64,
- -50, -28, -6, 18, 34, 48, 62, 74, 79, 70, 54, 38, 14, -19, -45, -62,
- -70, -71, -67, -68, -61, -39, -15, 10, 28, 45, 63, 77, 82, 77, 62, 47,
- 25, -9, -40, -61, -70, -73, -69, -70, -66, -47, -23, 2, 23, 41, 57, 71,
- 79, 83, 72, 55, 37, 6, -27, -51, -67, -76, -78, -77, -75, -60, -35, -12,
- 13, 37, 59, 75, 82, 86, 81, 66, 48, 17, -23, -50, -66, -77, -83, -83,
- -78, -66, -43, -18, 7, 31, 54, 73, 83, 87, 87, 74, 55, 29, -10, -41,
- -61, -76, -85, -88, -84, -72, -53, -28, -3, 22, 51, 75, 84, 88, 92, 87,
- 67, 40, 0, -38, -60, -77, -89, -94, -89, -77, -59, -34, -7, 17, 44, 73,
- 88, 90, 91, 88, 74, 49, 12, -29, -57, -73, -84, -93, -94, -84, -68, -44,
- -17, 8, 33, 64, 85, 90, 92, 91, 83, 63, 30, -15, -50, -71, -82, -92,
- -96, -90, -74, -52, -26, 0, 24, 56, 82, 92, 93, 92, 89, 74, 42, 0,
- -41, -67, -80, -93, -100, -97, -83, -62, -35, -8, 16, 43, 74, 91, 96, 96,
- 93, 83, 56, 16, -28, -61, -79, -92, -99, -99, -90, -71, -45, -16, 9, 36,
- 66, 88, 98, 97, 93, 87, 68, 31, -16, -52, -75, -89, -98, -103, -98, -81,
- -54, -23, 1, 25, 56, 83, 97, 98, 92, 88, 76, 46, 1, -42, -68, -81,
- -91, -99, -97, -82, -58, -30, -6, 15, 44, 73, 91, 94, 89, 85, 78, 55,
- 16, -28, -59, -77, -87, -93, -95, -85, -65, -40, -16, 6, 33, 62, 85, 94,
- 90, 86, 81, 66, 32, -15, -52, -73, -84, -90, -93, -87, -69, -45, -22, 0,
- 22, 48, 75, 88, 88, 85, 80, 67, 42, 4, -36, -62, -77, -87, -90, -85,
- -72, -52, -30, -11, 11, 36, 63, 83, 86, 86, 82, 74, 54, 17, -25, -55,
- -72, -81, -88, -87, -77, -57, -34, -16, 4, 26, 54, 77, 84, 84, 82, 75,
- 58, 27, -12, -45, -65, -76, -84, -84, -76, -61, -41, -24, -7, 15, 41, 67,
- 78, 81, 80, 76, 67, 42, 5, -30, -54, -67, -79, -85, -79, -67, -50, -32,
- -16, 6, 32, 58, 73, 77, 81, 78, 68, 49, 16, -19, -45, -63, -74, -80,
- -77, -67, -53, -35, -20, -3, 20, 45, 65, 72, 76, 75, 68, 56, 29, -6,
- -33, -52, -65, -75, -77, -70, -57, -42, -28, -13, 9, 34, 57, 70, 73, 75,
- 72, 63, 41, 7, -24, -46, -60, -70, -75, -72, -59, -45, -31, -18, 0, 25,
- 48, 63, 68, 70, 71, 65, 47, 17, -13, -33, -49, -62, -73, -73, -61, -48,
- -37, -25, -10, 14, 39, 57, 64, 67, 70, 69, 54, 28, -3, -27, -44, -57,
- -68, -74, -66, -50, -39, -26, -13, 5, 30, 50, 60, 62, 64, 65, 58, 38,
- 9, -17, -35, -46, -59, -69, -67, -52, -40, -31, -20, -6, 18, 42, 55, 58,
- 60, 65, 62, 47, 20, -10, -28, -39, -51, -66, -70, -58, -44, -34, -23, -10,
- 11, 34, 51, 57, 58, 62, 63, 51, 29, 2, -21, -34, -46, -60, -69, -63,
- -49, -37, -27, -15, 3, 26, 45, 55, 56, 58, 62, 55, 37, 11, -14, -29,
- -39, -52, -65, -66, -52, -40, -30, -18, -5, 17, 39, 52, 54, 55, 58, 57,
- 44, 21, -8, -24, -33, -45, -59, -66, -57, -43, -31, -20, -11, 7, 30, 47,
- 53, 51, 52, 55, 51, 33, 4, -20, -29, -36, -49, -64, -63, -50, -36, -24,
- -14, 0, 22, 43, 55, 53, 49, 52, 51, 39, 12, -16, -27, -33, -45, -60,
- -66, -53, -37, -25, -16, -6, 16, 40, 53, 53, 47, 49, 51, 43, 22, 0,
- 0, 0, 0, 0, 0, 0, 0, 22, 0, 0, -2, -2, -2, -2, 0, -2,
- 0, 0, 1, 2, 3, 4, 4, 4, 5, 6, 7, 6, 3, 1, 0, -3,
- -5, -11, -17, -20, -20, -18, -16, -17, -17, -14, -10, -9, -13, -18, -19, -15,
- -13, -12, -13, -8, 1, 12, 25, 32, 40, 45, 50, 49, 41, 32, 24, 16,
- 9, 1, -12, -20, -23, -24, -20, -20, -18, -12, -11, -12, -7, 0, 10, 17,
- 23, 25, 24, 21, 22, 23, 21, 10, 1, -5, -8, -11, -19, -29, -33, -32,
- -26, -19, -16, -14, -12, -8, -7, -11, -19, -27, -29, -27, -25, -25, -24, -17,
- -4, 13, 26, 34, 43, 54, 59, 56, 46, 33, 23, 15, 5, -11, -23, -32,
- -35, -32, -30, -27, -23, -16, -11, -5, 3, 11, 23, 31, 36, 33, 28, 27,
- 26, 21, 11, 1, -9, -14, -18, -23, -28, -35, -33, -26, -18, -12, -11, -7,
- -4, -2, 0, -8, -19, -29, -33, -32, -30, -30, -25, -17, -4, 13, 26, 36,
- 47, 55, 59, 53, 43, 32, 23, 12, 0, -14, -23, -30, -35, -35, -35, -33,
- -28, -19, -11, -6, 3, 11, 22, 33, 39, 38, 34, 30, 27, 20, 11, 0,
- -9, -17, -21, -26, -31, -34, -29, -19, -8, -3, 0, -3, 1, 4, 1, -11,
- -25, -35, -37, -39, -35, -32, -27, -17, 0, 15, 29, 42, 55, 63, 62, 55,
- 47, 38, 27, 14, -4, -20, -31, -40, -44, -46, -45, -41, -34, -25, -14, -3,
- 8, 22, 32, 43, 44, 40, 36, 34, 26, 18, 8, -2, -11, -20, -25, -29,
- -33, -31, -21, -10, -2, -2, -2, 4, 6, 9, 0, -14, -28, -35, -39, -38,
- -38, -36, -30, -16, 0, 16, 29, 41, 55, 65, 67, 59, 49, 39, 28, 13,
- -3, -19, -32, -42, -48, -51, -53, -47, -36, -22, -12, 0, 10, 24, 38, 46,
- 48, 43, 39, 32, 26, 17, 6, -7, -16, -21, -26, -31, -34, -28, -16, -2,
- 3, 1, 2, 8, 16, 12, 2, -15, -27, -34, -37, -41, -47, -44, -33, -16,
- 1, 16, 31, 47, 65, 75, 73, 63, 52, 41, 27, 9, -14, -34, -47, -54,
- -55, -58, -57, -50, -35, -17, 0, 8, 20, 34, 47, 54, 49, 42, 36, 29,
- 21, 9, -4, -14, -21, -26, -30, -33, -28, -18, -5, 4, 6, 6, 8, 13,
- 17, 12, -4, -21, -33, -39, -44, -49, -50, -46, -35, -15, 4, 22, 36, 55,
- 72, 81, 78, 69, 54, 42, 27, 6, -19, -38, -52, -57, -62, -65, -64, -52,
- -35, -17, -3, 8, 19, 33, 45, 50, 48, 42, 35, 29, 18, 7, -5, -11,
- -20, -26, -29, -27, -20, -13, -4, 3, 8, 9, 11, 12, 12, 5, -8, -22,
- -33, -42, -50, -53, -51, -42, -27, -11, 9, 27, 45, 62, 75, 78, 73, 60,
- 48, 32, 14, -8, -30, -46, -54, -60, -64, -62, -53, -39, -23, -8, 5, 17,
- 30, 41, 46, 44, 38, 30, 22, 11, 4, -5, -12, -20, -25, -26, -24, -17,
- -7, 3, 8, 11, 12, 14, 15, 14, 9, -4, -17, -32, -44, -54, -57, -56,
- -48, -36, -22, -5, 18, 41, 61, 74, 79, 75, 67, 55, 39, 20, -2, -20,
- -37, -47, -56, -62, -63, -57, -44, -31, -18, -5, 7, 16, 28, 35, 38, 37,
- 32, 25, 16, 8, 3, -2, -5, -11, -19, -21, -16, -7, 3, 6, 8, 7,
- 8, 10, 9, 5, -4, -13, -23, -37, -49, -54, -54, -47, -38, -25, -9, 9,
- 30, 50, 67, 77, 75, 69, 58, 42, 26, 7, -12, -31, -46, -52, -56, -59,
- -58, -49, -36, -19, -5, 8, 14, 22, 28, 33, 35, 30, 23, 13, 4, 3,
- 3, 0, -8, -12, -13, -10, -6, 2, 8, 11, 12, 11, 9, 4, -2, -5,
- -12, -23, -35, -46, -52, -54, -48, -36, -22, -8, 9, 28, 46, 61, 70, 72,
- 68, 58, 45, 27, 9, -8, -22, -35, -43, -48, -48, -46, -39, -33, -23, -12,
- 1, 8, 11, 14, 16, 19, 19, 17, 11, 7, 8, 11, 13, 7, 5, 2,
- 2, 2, 4, 6, 6, 5, 2, -3, -5, -9, -11, -17, -23, -29, -34, -40,
- -45, -41, -32, -18, -5, 7, 19, 36, 54, 64, 67, 61, 55, 48, 36, 18,
- 3, -11, -23, -36, -45, -46, -42, -39, -34, -27, -20, -11, 0, 10, 13, 14,
- 12, 13, 13, 10, 7, 6, 9, 11, 11, 11, 10, 10, 8, 9, 9, 9,
- 6, 1, -4, -12, -16, -22, -25, -28, -29, -30, -39, -43, -39, -26, -11, 0,
- 8, 19, 33, 48, 58, 63, 61, 56, 50, 40, 25, 8, -5, -15, -24, -35,
- -41, -42, -39, -32, -29, -25, -21, -13, -6, 0, 4, 2, 2, 3, 6, 6,
- 7, 11, 17, 20, 22, 23, 24, 23, 21, 17, 12, 4, -5, -13, -22, -29,
- -37, -41, -40, -36, -31, -32, -34, -34, -22, -6, 8, 14, 20, 29, 41, 50,
- 56, 56, 49, 45, 39, 30, 17, 5, -8, -19, -28, -34, -35, -32, -27, -25,
- -25, -23, -19, -12, -7, -4, -6, -10, -11, -7, 0, 4, 10, 14, 19, 26,
- 32, 35, 34, 31, 25, 16, 6, -5, -17, -29, -39, -47, -51, -50, -44, -35,
- -28, -27, -25, -18, -6, 10, 18, 21, 25, 31, 40, 46, 49, 48, 44, 42,
- 37, 29, 19, 8, -5, -14, -21, -29, -30, -30, -27, -28, -32, -33, -31, -22,
- -17, -15, -17, -19, -19, -9, 5, 16, 22, 25, 31, 38, 44, 47, 43, 34,
- 20, 6, -9, -21, -35, -49, -59, -62, -60, -53, -42, -30, -22, -15, -6, 4,
- 14, 23, 27, 28, 27, 30, 35, 38, 39, 42, 38, 35, 30, 25, 20, 12,
- 4, -6, -18, -23, -22, -20, -22, -30, -37, -39, -34, -29, -27, -27, -26, -23,
- -16, -3, 10, 21, 29, 35, 43, 46, 50, 49, 41, 28, 15, -2, -19, -35,
- -50, -62, -67, -67, -60, -50, -36, -23, -14, -6, 3, 11, 21, 27, 27, 24,
- 25, 27, 29, 31, 36, 41, 42, 39, 33, 27, 22, 17, 8, -3, -11, -15,
- -15, -18, -25, -35, -42, -45, -42, -41, -41, -40, -38, -28, -12, 7, 22, 34,
- 43, 51, 59, 62, 59, 49, 37, 20, 1, -19, -38, -54, -65, -73, -74, -69,
- -55, -35, -19, -10, -2, 8, 18, 23, 25, 25, 22, 20, 19, 20, 22, 30,
- 39, 44, 42, 39, 35, 32, 29, 18, 4, -8, -13, -15, -17, -24, -33, -43,
- -47, -44, -42, -40, -40, -39, -32, -17, 3, 16, 28, 39, 47, 53, 56, 56,
- 52, 40, 24, 5, -12, -29, -43, -54, -65, -72, -71, -56, -36, -20, -13, -4,
- 5, 12, 18, 21, 23, 20, 18, 14, 16, 19, 27, 38, 45, 45, 42, 41,
- 42, 37, 27, 15, 1, -8, -12, -13, -17, -30, -40, -47, -48, -47, -46, -46,
- -45, -41, -28, -9, 11, 26, 38, 45, 51, 55, 58, 55, 47, 31, 10, -12,
- -27, -39, -49, -58, -67, -69, -62, -46, -26, -13, -4, 2, 7, 14, 18, 21,
- 20, 15, 11, 12, 14, 21, 32, 40, 44, 42, 42, 40, 37, 33, 22, 11,
- 1, -7, -11, -11, -19, -30, -39, -43, -43, -42, -43, -44, -44, -36, -20, 0,
- 14, 25, 35, 42, 46, 50, 50, 48, 36, 17, -3, -18, -30, -36, -43, -52,
- -59, -60, -49, -35, -20, -12, -7, -4, 2, 8, 12, 12, 9, 9, 12, 16,
- 23, 29, 39, 45, 46, 46, 43, 41, 37, 30, 20, 7, -5, -10, -11, -15,
- -25, -39, -46, -45, -43, -42, -45, -46, -39, -26, -8, 8, 20, 31, 41, 45,
- 48, 46, 44, 36, 21, 1, -20, -31, -33, -36, -44, -53, -59, -54, -41, -26,
- -17, -12, -6, -3, 5, 7, 9, 11, 11, 12, 15, 20, 29, 36, 42, 46,
- 45, 42, 40, 38, 33, 25, 13, 4, -7, -10, -11, -17, -29, -38, -38, -34,
- -35, -39, -41, -39, -31, -16, -6, 4, 14, 24, 30, 34, 34, 35, 32, 22,
- 8, -9, -16, -16, -17, -22, -33, -43, -46, -41, -34, -30, -25, -19, -14, -9,
- -6, -2, 5, 9, 13, 15, 21, 29, 36, 43, 47, 46, 46, 42, 39, 37,
- 31, 20, 10, 0, -6, -9, -14, -22, -29, -33, -31, -30, -34, -37, -37, -30,
- -21, -12, -5, 1, 10, 20, 28, 31, 31, 28, 20, 12, 0, -8, -10, -10,
- -16, -24, -33, -39, -44, -42, -35, -28, -23, -18, -14, -10, -4, 6, 12, 16,
- 17, 22, 29, 33, 35, 38, 41, 43, 41, 38, 34, 30, 24, 16, 9, 3,
- -4, -10, -15, -21, -23, -23, -23, -24, -28, -32, -31, -28, -22, -15, -10, -6,
- 2, 11, 20, 23, 25, 19, 14, 9, 5, 3, 2, -2, -8, -19, -28, -36,
- -42, -44, -39, -33, -28, -26, -20, -11, 0, 8, 15, 22, 28, 33, 35, 36,
- 37, 38, 41, 40, 38, 32, 27, 21, 17, 11, 4, -3, -8, -12, -17, -18,
- -16, -16, -15, -18, -22, -25, -26, -25, -23, -19, -15, -9, -2, 8, 13, 17,
- 18, 17, 16, 15, 13, 10, 6, 0, -9, -21, -32, -42, -47, -46, -43, -36,
- -30, -22, -15, -6, 4, 14, 22, 28, 33, 36, 37, 36, 35, 37, 36, 36,
- 32, 27, 23, 16, 10, 5, 0, -7, -10, -12, -11, -11, -11, -10, -9, -11,
- -16, -22, -27, -30, -30, -30, -25, -19, -9, 0, 7, 13, 18, 23, 27, 27,
- 26, 20, 12, 1, -13, -27, -40, -50, -54, -54, -49, -42, -33, -21, -10, 1,
- 14, 24, 30, 39, 44, 43, 38, 36, 38, 37, 34, 31, 28, 22, 13, 7,
- 5, -2, -7, -11, -14, -13, -13, -8, -6, -6, -10, -12, -14, -19, -26, -34,
- -38, -33, -26, -15, -7, 2, 7, 17, 26, 35, 40, 37, 29, 19, 7, -12,
- -31, -44, -53, -56, -61, -62, -59, -46, -27, -9, 5, 14, 25, 36, 47, 53,
- 51, 45, 37, 34, 32, 29, 26, 23, 18, 13, 5, 0, -3, -4, -6, -10,
- -12, -12, -6, 2, 6, 2, -6, -12, -17, -21, -31, -41, -47, -43, -32, -20,
- -11, -4, 9, 21, 40, 50, 48, 42, 34, 22, 5, -16, -36, -53, -58, -63,
- -69, -73, -63, -43, -19, -2, 9, 19, 34, 50, 60, 61, 53, 42, 37, 32,
- 30, 24, 21, 16, 11, 4, -4, -7, -6, -5, -5, -10, -14, -11, -4, 3,
- 2, -2, -8, -13, -19, -26, -36, -42, -40, -33, -21, -9, 1, 10, 22, 36,
- 49, 53, 47, 36, 19, 1, -18, -36, -51, -60, -65, -67, -67, -63, -47, -24,
- -4, 11, 20, 33, 48, 57, 57, 52, 42, 33, 30, 28, 25, 19, 16, 12,
- 8, 3, -2, -2, -2, -2, -5, -8, -10, -5, -2, 0, 0, -5, -8, -15,
- -23, -32, -39, -38, -33, -24, -15, -7, 5, 16, 30, 45, 52, 49, 40, 23,
- 4, -14, -29, -42, -55, -63, -67, -67, -61, -50, -35, -19, 0, 16, 31, 46,
- 56, 59, 56, 47, 38, 34, 31, 28, 23, 16, 10, 4, 0, -2, -2, 0,
- -5, -9, -12, -11, -7, -3, -3, -4, -5, -4, -7, -14, -26, -33, -32, -27,
- -20, -15, -7, 2, 13, 21, 34, 42, 46, 40, 25, 7, -13, -27, -35, -44,
- -54, -62, -64, -60, -51, -39, -26, -10, 8, 24, 40, 51, 58, 60, 54, 44,
- 36, 29, 24, 19, 13, 8, 0, -6, -5, 0, 1, 0, -4, -3, -2, 0,
- 1, -2, -5, -5, -4, -7, -17, -27, -31, -29, -24, -19, -15, -9, -3, 7,
- 18, 27, 34, 39, 37, 26, 9, -9, -24, -32, -39, -47, -55, -60, -57, -51,
- -42, -32, -20, -6, 14, 31, 48, 57, 60, 58, 52, 45, 35, 25, 21, 17,
- 9, 0, -8, -10, -8, -7, -6, -9, -9, -6, -2, 0, -3, -6, -6, -2,
- 1, -6, -15, -25, -25, -20, -17, -13, -11, -7, 1, 8, 16, 24, 31, 34,
- 29, 16, -3, -17, -28, -35, -41, -47, -54, -56, -54, -46, -37, -27, -15, 4,
- 23, 40, 50, 58, 60, 58, 50, 42, 34, 26, 19, 14, 4, -6, -13, -13,
- -13, -14, -16, -15, -12, -9, -7, -7, -4, -4, 2, 7, 5, 0, -8, -11,
- -13, -13, -11, -10, -11, -11, -9, 0, 8, 14, 22, 24, 19, 9, -3, -14,
- -23, -29, -32, -38, -47, -54, -52, -44, -32, -23, -9, 8, 23, 39, 52, 59,
- 58, 51, 46, 43, 33, 25, 16, 9, 4, -4, -11, -15, -16, -16, -15, -14,
- -15, -16, -13, -7, -5, 2, 5, 5, 5, 6, 3, -4, -6, -4, -5, -10,
- -16, -16, -13, -6, 4, 12, 15, 17, 14, 10, 4, -8, -17, -23, -30, -38,
- -46, -52, -51, -41, -30, -20, -8, 9, 29, 47, 56, 57, 55, 52, 50, 45,
- 34, 20, 10, 2, -2, -9, -16, -22, -24, -22, -21, -22, -19, -14, -7, -4,
- 1, 5, 11, 15, 20, 17, 9, 3, 3, 0, -6, -15, -21, -23, -16, -9,
- -3, 4, 10, 13, 15, 13, 4, -9, -15, -20, -27, -39, -48, -51, -47, -38,
- -29, -21, -7, 16, 36, 48, 51, 52, 55, 60, 59, 49, 33, 20, 12, 7,
- -2, -13, -24, -28, -27, -26, -30, -32, -29, -20, -9, 0, 3, 8, 16, 25,
- 28, 23, 17, 12, 6, -2, -14, -26, -31, -27, -18, -10, -3, 7, 15, 22,
- 24, 18, 9, 0, -9, -19, -34, -46, -57, -57, -51, -44, -38, -26, -5, 21,
- 42, 48, 53, 58, 67, 75, 71, 57, 37, 23, 12, 3, -12, -27, -39, -43,
- -43, -45, -47, -42, -28, -12, 2, 7, 12, 20, 32, 38, 37, 30, 21, 13,
- 1, -13, -26, -34, -33, -26, -17, -10, -3, 9, 20, 25, 22, 13, 5, -3,
- -13, -28, -43, -53, -56, -51, -46, -40, -31, -14, 10, 31, 41, 47, 56, 67,
- 76, 73, 63, 46, 30, 19, 9, -7, -25, -39, -47, -50, -54, -52, -50, -38,
- -22, -9, 4, 12, 22, 30, 39, 41, 39, 31, 22, 12, -3, -19, -30, -32,
- -29, -23, -17, -9, 1, 12, 20, 24, 18, 10, 2, -7, -19, -35, -50, -59,
- -59, -54, -49, -43, -31, -9, 15, 32, 41, 53, 70, 85, 87, 80, 64, 49,
- 37, 23, 2, -23, -42, -52, -59, -66, -69, -68, -56, -38, -18, -2, 9, 19,
- 31, 41, 49, 51, 44, 35, 21, 5, -9, -22, -29, -30, -26, -20, -14, -7,
- 5, 15, 17, 14, 9, 2, -4, -16, -29, -45, -55, -56, -50, -46, -44, -36,
- -19, 1, 19, 33, 46, 63, 79, 86, 84, 73, 60, 47, 32, 12, -10, -30,
- -48, -59, -68, -72, -73, -64, -49, -30, -12, 2, 12, 26, 35, 45, 51, 51,
- 44, 30, 15, 3, -9, -17, -20, -21, -19, -18, -14, 0, 10, 16, 15, 7,
- -4, -10, -14, -24, -38, -51, -58, -55, -50, -44, -36, -23, -7, 10, 26, 41,
- 57, 76, 89, 89, 81, 70, 59, 45, 25, 0, -24, -41, -56, -67, -75, -80,
- -76, -63, -45, -26, -9, 6, 20, 32, 44, 52, 54, 53, 47, 35, 18, 3,
- -6, -11, -14, -16, -19, -19, -12, -4, 5, 5, 0, -8, -12, -15, -21, -34,
- -47, -51, -45, -39, -34, -30, -23, -12, 4, 17, 31, 45, 60, 72, 78, 75,
- 69, 62, 53, 40, 18, -5, -24, -38, -50, -62, -73, -78, -74, -59, -41, -28,
- -17, -4, 14, 33, 47, 55, 58, 55, 48, 39, 29, 16, 4, -5, -11, -18,
- -21, -20, -15, -8, -7, -9, -13, -15, -16, -17, -23, -33, -43, -44, -41, -34,
- -28, -23, -16, -8, 5, 21, 36, 50, 62, 73, 76, 73, 68, 59, 48, 30,
- 9, -16, -35, -48, -59, -70, -77, -79, -72, -54, -38, -24, -8, 8, 29, 45,
- 56, 61, 62, 56, 51, 39, 27, 16, 4, -8, -16, -22, -23, -25, -19, -16,
- -17, -19, -20, -21, -18, -19, -25, -32, -38, -34, -24, -19, -15, -12, -7, 3,
- 15, 28, 39, 48, 56, 63, 63, 63, 57, 47, 32, 14, -5, -22, -36, -46,
- -58, -68, -73, -71, -61, -47, -35, -23, -9, 10, 29, 43, 52, 56, 56, 56,
- 52, 45, 33, 19, 6, -5, -15, -22, -25, -26, -26, -29, -29, -26, -24, -20,
- -19, -23, -27, -30, -27, -21, -18, -14, -10, -7, 0, 8, 18, 30, 40, 47,
- 52, 54, 54, 55, 49, 39, 22, 7, -9, -24, -37, -50, -58, -65, -71, -67,
- -59, -50, -39, -23, -6, 15, 32, 43, 51, 57, 61, 64, 61, 52, 37, 21,
- 4, -11, -20, -26, -30, -35, -37, -39, -35, -29, -22, -17, -20, -22, -20, -18,
- -17, -16, -13, -8, -3, 2, 7, 10, 17, 27, 35, 42, 43, 44, 45, 44,
- 38, 28, 16, 3, -10, -22, -33, -46, -57, -64, -64, -59, -53, -46, -34, -17,
- 3, 21, 32, 41, 48, 55, 60, 60, 54, 44, 31, 18, 3, -10, -19, -27,
- -30, -32, -34, -35, -30, -23, -17, -17, -20, -20, -20, -17, -15, -13, -11, -8,
- 1, 8, 12, 17, 23, 30, 39, 39, 37, 36, 35, 34, 27, 14, 0, -10,
- -15, -23, -34, -46, -56, -60, -56, -49, -39, -32, -23, -8, 8, 23, 32, 38,
- 44, 54, 58, 57, 48, 37, 29, 17, 4, -11, -21, -28, -29, -31, -34, -35,
- -27, -20, -15, -16, -16, -17, -13, -10, -10, -11, -10, -4, 5, 11, 13, 15,
- 21, 29, 33, 32, 28, 25, 25, 23, 16, 5, -6, -10, -16, -21, -30, -42,
- -48, -48, -43, -34, -29, -21, -13, -3, 11, 22, 27, 34, 39, 48, 53, 48,
- 42, 32, 23, 16, 4, -7, -18, -24, -24, -26, -28, -24, -19, -14, -13, -16,
- -18, -18, -16, -14, -15, -16, -15, -7, 3, 11, 14, 21, 27, 33, 36, 33,
- 30, 25, 22, 17, 9, -4, -15, -21, -24, -31, -39, -44, -44, -39, -30, -23,
- -16, -8, 4, 14, 21, 23, 25, 29, 37, 43, 42, 36, 31, 25, 18, 11,
- 4, -7, -11, -13, -16, -21, -22, -18, -14, -13, -16, -19, -21, -21, -19, -19,
- -20, -18, -11, -2, 8, 14, 18, 23, 30, 34, 35, 31, 27, 21, 13, 2,
- -11, -17, -23, -28, -36, -39, -40, -37, -31, -23, -14, -9, 0, 7, 13, 15,
- 15, 16, 22, 27, 30, 28, 29, 32, 29, 23, 16, 9, 4, 1, -2, -7,
- -14, -19, -14, -10, -10, -14, -18, -22, -24, -23, -26, -28, -27, -18, -8, -3,
- 2, 9, 22, 33, 40, 40, 36, 30, 25, 20, 8, -8, -22, -29, -32, -39,
- -48, -50, -42, -30, -19, -13, -8, 2, 11, 22, 25, 21, 17, 15, 20, 23,
- 21, 20, 20, 19, 19, 16, 11, 9, 7, 7, 3, 0, -3, -5, -5, -5,
- -7, -12, -22, -28, -32, -35, -35, -36, -30, -21, -12, -4, 3, 16, 29, 39,
- 46, 45, 40, 34, 26, 13, -2, -17, -28, -37, -48, -57, -60, -52, -36, -19,
- -12, -8, 2, 16, 28, 33, 28, 23, 21, 22, 21, 19, 18, 16, 14, 12,
- 8, 6, 5, 5, 7, 5, 4, 5, 7, 9, 7, 3, -5, -13, -22, -28,
- -35, -44, -49, -48, -38, -26, -14, -7, 4, 20, 38, 49, 54, 53, 49, 40,
- 26, 8, -11, -24, -33, -46, -61, -70, -67, -52, -31, -14, -5, 4, 14, 27,
- 36, 36, 33, 29, 26, 25, 21, 14, 10, 7, 8, 6, 5, 5, 6, 8,
- 9, 10, 14, 18, 17, 13, 5, -4, -12, -20, -28, -37, -49, -56, -56, -48,
- -36, -25, -15, -2, 16, 36, 51, 55, 57, 55, 48, 37, 20, 1, -17, -30,
- -43, -60, -73, -76, -63, -43, -24, -14, -6, 7, 23, 39, 44, 38, 34, 31,
- 32, 30, 24, 16, 8, 5, 6, 6, 5, 5, 6, 10, 10, 13, 16, 19,
- 19, 14, 5, -7, -18, -25, -34, -45, -55, -61, -59, -51, -39, -25, -12, 5,
- 27, 48, 58, 60, 61, 58, 49, 32, 14, -4, -20, -36, -54, -69, -79, -75,
- -57, -35, -21, -15, -4, 12, 28, 39, 42, 41, 38, 38, 38, 33, 23, 13,
- 8, 9, 11, 9, 5, 3, 6, 10, 13, 14, 15, 17, 16, 9, -6, -16,
- -21, -27, -40, -56, -65, -67, -57, -45, -33, -23, -5, 21, 44, 60, 66, 67,
- 65, 61, 47, 25, 2, -16, -34, -53, -72, -83, -82, -70, -51, -33, -20, -8,
- 8, 25, 39, 46, 43, 43, 43, 43, 38, 27, 17, 9, 8, 10, 11, 9,
- 5, 5, 8, 13, 14, 18, 20, 18, 12, -2, -13, -19, -25, -34, -48, -62,
- -69, -67, -58, -46, -32, -14, 9, 30, 48, 60, 69, 72, 69, 57, 36, 13,
- -6, -27, -47, -66, -79, -83, -77, -64, -46, -29, -13, 4, 17, 30, 39, 41,
- 46, 48, 45, 40, 31, 20, 12, 10, 13, 14, 12, 11, 10, 10, 15, 17,
- 20, 20, 17, 12, 0, -14, -24, -30, -37, -47, -60, -69, -68, -62, -51, -36,
- -18, 5, 25, 45, 58, 65, 68, 67, 59, 42, 20, -2, -22, -42, -61, -75,
- -81, -77, -66, -51, -35, -20, -4, 14, 28, 37, 38, 38, 42, 47, 43, 35,
- 24, 17, 14, 14, 17, 20, 20, 17, 13, 14, 17, 18, 18, 17, 11, -2,
- -15, -24, -31, -38, -46, -52, -58, -62, -61, -52, -38, -22, -4, 16, 35, 48,
- 55, 60, 62, 57, 46, 26, 6, -17, -35, -53, -68, -76, -75, -66, -51, -38,
- -23, -7, 10, 25, 35, 38, 37, 39, 40, 39, 30, 21, 16, 15, 15, 16,
- 20, 24, 26, 27, 27, 26, 24, 21, 19, 11, -3, -16, -29, -40, -44, -50,
- -54, -57, -58, -55, -48, -36, -21, -5, 13, 29, 41, 48, 52, 53, 50, 41,
- 26, 7, -14, -33, -49, -62, -70, -69, -61, -48, -36, -21, -5, 16, 30, 35,
- 35, 35, 32, 31, 29, 24, 17, 13, 13, 14, 15, 18, 26, 34, 39, 37,
- 32, 29, 26, 22, 13, 1, -15, -29, -40, -46, -51, -54, -55, -52, -46, -40,
- -32, -22, -10, 5, 19, 28, 33, 35, 37, 38, 33, 21, 8, -7, -20, -35,
- -50, -57, -57, -49, -37, -28, -21, -8, 10, 25, 32, 32, 31, 27, 24, 22,
- 20, 15, 13, 13, 15, 15, 19, 26, 36, 42, 43, 40, 33, 27, 22, 16,
- 3, -13, -26, -37, -44, -50, -55, -54, -48, -42, -32, -24, -18, -10, -3, 8,
- 20, 30, 31, 26, 22, 20, 15, 7, -7, -20, -32, -43, -52, -52, -46, -36,
- -25, -16, -5, 9, 24, 38, 42, 39, 30, 23, 19, 15, 11, 8, 6, 6,
- 6, 9, 18, 30, 42, 47, 45, 43, 38, 31, 22, 8, -9, -21, -33, -45,
- -55, -59, -56, -47, -37, -29, -21, -13, -5, 2, 8, 13, 19, 22, 20, 15,
- 9, 5, -3, -9, -20, -30, -39, -46, -45, -40, -31, -24, -16, -6, 7, 21,
- 35, 39, 36, 31, 24, 22, 15, 10, 8, 5, 6, 3, 4, 12, 25, 40,
- 48, 50, 48, 43, 37, 30, 17, -2, -18, -33, -45, -57, -64, -62, -53, -40,
- -31, -23, -13, -3, 4, 11, 16, 19, 18, 17, 13, 7, -3, -10, -16, -22,
- -31, -40, -45, -45, -41, -32, -24, -15, -5, 8, 24, 39, 47, 44, 38, 32,
- 26, 20, 12, 3, -4, -4, -5, -4, 1, 11, 29, 41, 49, 51, 49, 45,
- 38, 27, 9, -11, -27, -38, -52, -60, -64, -58, -45, -32, -21, -14, -5, 3,
- 10, 13, 13, 14, 14, 12, 4, -6, -12, -17, -21, -25, -31, -35, -40, -39,
- -33, -27, -19, -12, 1, 16, 29, 38, 42, 40, 36, 33, 30, 22, 11, 1,
- -2, -2, -3, -2, 2, 16, 32, 44, 48, 46, 44, 39, 31, 19, 1, -21,
- -36, -48, -58, -62, -59, -49, -38, -28, -20, -12, -2, 9, 16, 16, 15, 16,
- 14, 9, 2, -7, -14, -19, -25, -31, -36, -38, -38, -36, -34, -28, -20, -7,
- 8, 22, 33, 41, 46, 46, 42, 39, 33, 25, 14, 4, -4, -8, -8, -4,
- 4, 16, 30, 38, 42, 46, 45, 38, 25, 10, -7, -24, -39, -51, -58, -59,
- -53, -43, -34, -28, -21, -9, 5, 15, 17, 16, 15, 16, 15, 10, 2, -10,
- -17, -21, -26, -33, -38, -40, -37, -34, -33, -28, -17, 0, 15, 29, 40, 48,
- 50, 48, 44, 40, 34, 26, 15, 3, -6, -11, -11, -4, 7, 18, 24, 30,
- 36, 38, 35, 31, 24, 13, -7, -25, -40, -50, -53, -51, -47, -41, -38, -33,
- -25, -10, 4, 14, 19, 21, 22, 19, 19, 17, 7, -5, -15, -23, -31, -39,
- -46, -49, -49, -46, -41, -33, -19, 0, 21, 39, 53, 61, 64, 63, 56, 50,
- 42, 31, 15, -2, -13, -19, -19, -11, 0, 10, 15, 19, 27, 33, 37, 35,
- 25, 9, -13, -28, -38, -44, -46, -50, -53, -51, -46, -38, -23, -7, 10, 20,
- 21, 24, 25, 28, 28, 19, 8, -7, -18, -28, -36, -43, -52, -56, -57, -51,
- -44, -31, -13, 7, 29, 46, 60, 66, 71, 68, 61, 54, 45, 32, 13, -5,
- -17, -22, -20, -15, -8, -2, 8, 14, 24, 31, 35, 32, 21, 4, -13, -24,
- -34, -42, -49, -55, -58, -54, -48, -38, -23, -4, 14, 26, 32, 31, 32, 36,
- 34, 23, 7, -12, -25, -35, -47, -61, -68, -68, -61, -53, -42, -26, -7, 22,
- 45, 61, 71, 75, 78, 74, 66, 56, 42, 24, 7, -13, -24, -29, -25, -18,
- -11, -7, 2, 14, 27, 36, 38, 32, 19, 1, -14, -22, -33, -44, -56, -64,
- -65, -60, -47, -32, -16, 3, 18, 31, 37, 37, 38, 41, 35, 20, 0, -18,
- -31, -43, -56, -64, -69, -68, -60, -50, -36, -15, 6, 31, 50, 62, 71, 77,
- 78, 74, 66, 54, 38, 20, 2, -15, -23, -26, -24, -22, -17, -7, 8, 20,
- 29, 35, 33, 25, 13, -2, -14, -29, -42, -57, -67, -72, -67, -57, -42, -24,
- -5, 13, 31, 43, 46, 47, 48, 43, 32, 14, -5, -22, -40, -55, -63, -68,
- -69, -66, -57, -44, -25, -5, 18, 37, 55, 66, 75, 78, 75, 70, 62, 47,
- 28, 9, -7, -19, -27, -30, -27, -21, -11, 5, 18, 28, 34, 36, 32, 24,
- 12, -4, -20, -38, -55, -68, -75, -71, -65, -53, -35, -14, 6, 24, 39, 47,
- 50, 48, 44, 36, 22, 5, -16, -34, -47, -56, -60, -60, -59, -54, -45, -28,
- -9, 9, 25, 41, 53, 63, 67, 66, 65, 62, 54, 40, 22, 6, -8, -16,
- -22, -23, -20, -11, 1, 13, 22, 27, 29, 26, 24, 15, 2, -15, -33, -49,
- -64, -74, -74, -67, -55, -39, -20, -2, 16, 32, 45, 50, 49, 43, 35, 26,
- 11, -9, -25, -35, -44, -49, -52, -54, -50, -39, -26, -12, 1, 14, 27, 39,
- 48, 53, 55, 57, 56, 48, 36, 25, 15, 6, -5, -12, -17, -14, -8, 3,
- 14, 21, 26, 23, 21, 21, 14, 3, -11, -26, -44, -61, -72, -72, -68, -56,
- -42, -25, -11, 7, 24, 37, 44, 44, 40, 33, 25, 13, 0, -12, -24, -32,
- -39, -41, -39, -36, -30, -24, -18, -10, 1, 11, 21, 29, 36, 41, 47, 51,
- 51, 42, 35, 27, 19, 10, 1, -6, -10, -9, -2, 6, 11, 13, 13, 15,
- 14, 10, 4, -9, -19, -31, -45, -58, -67, -68, -56, -43, -31, -20, -9, 7,
- 21, 31, 35, 35, 33, 27, 18, 7, -3, -9, -13, -20, -27, -32, -33, -29,
- -23, -19, -16, -12, -4, 6, 15, 23, 30, 39, 47, 49, 42, 35, 31, 27,
- 22, 14, 2, -8, -9, -4, 5, 8, 8, 9, 7, 6, 3, 0, -5, -12,
- -22, -35, -50, -58, -58, -50, -39, -32, -26, -19, -8, 7, 21, 26, 27, 25,
- 22, 18, 11, 5, 2, 1, -3, -10, -19, -24, -23, -16, -15, -17, -20, -17,
- -10, -2, 6, 12, 21, 32, 44, 45, 38, 30, 27, 31, 31, 21, 8, 1,
- 0, 2, 8, 10, 7, 1, -3, -2, -4, -9, -12, -17, -25, -37, -47, -53,
- -50, -42, -32, -27, -26, -22, -11, 5, 15, 18, 20, 22, 23, 22, 18, 15,
- 14, 11, 7, -3, -14, -18, -17, -18, -22, -27, -27, -21, -14, -6, 3, 12,
- 24, 34, 40, 39, 35, 32, 31, 34, 30, 19, 10, 4, 2, 5, 7, 7,
- 1, -6, -10, -9, -8, -8, -11, -16, -25, -34, -41, -41, -36, -32, -33, -33,
- -29, -22, -11, -2, 6, 13, 17, 22, 23, 22, 22, 24, 23, 20, 12, 0,
- -7, -11, -14, -20, -26, -28, -26, -22, -15, -9, 2, 13, 25, 32, 33, 35,
- 36, 37, 38, 35, 29, 19, 9, 5, 7, 6, 4, -3, -9, -12, -11, -6,
- -4, -5, -10, -17, -26, -33, -37, -38, -38, -38, -41, -39, -31, -20, -9, -2,
- 6, 15, 23, 31, 31, 31, 30, 29, 28, 21, 13, 2, -9, -17, -20, -23,
- -26, -27, -26, -20, -14, -6, 6, 14, 22, 26, 32, 34, 35, 37, 37, 36,
- 27, 15, 6, 6, 7, 5, -3, -13, -17, -17, -11, -5, -5, -6, -11, -18,
- -24, -27, -30, -35, -40, -44, -44, -39, -28, -16, -6, 1, 9, 20, 31, 34,
- 36, 37, 36, 33, 23, 14, 5, -3, -10, -17, -23, -30, -34, -31, -22, -14,
- -8, 0, 7, 15, 20, 26, 30, 35, 40, 40, 34, 27, 18, 14, 9, 8,
- 5, -2, -11, -15, -13, -8, -4, 0, 1, -6, -12, -18, -23, -29, -38, -45,
- -52, -53, -47, -37, -28, -16, -5, 6, 17, 28, 37, 42, 43, 40, 37, 31,
- 19, 8, 1, -7, -14, -22, -27, -33, -34, -28, -18, -8, 0, 5, 10, 14,
- 19, 25, 33, 38, 39, 35, 27, 18, 13, 9, 8, 4, -3, -8, -12, -13,
- -10, -4, 4, 4, -2, -7, -14, -21, -28, -36, -45, -53, -54, -50, -44, -34,
- -20, -5, 7, 18, 28, 37, 39, 42, 40, 35, 28, 17, 7, 0, -7, -12,
- -18, -23, -28, -28, -23, -17, -8, 2, 8, 9, 10, 12, 17, 25, 32, 33,
- 28, 20, 13, 10, 10, 8, 6, 5, 1, -5, -6, -3, 3, 10, 10, 5,
- -6, -15, -21, -28, -38, -49, -59, -62, -59, -51, -39, -25, -8, 7, 17, 28,
- 37, 42, 44, 43, 38, 30, 17, 7, 0, -4, -10, -16, -24, -26, -27, -21,
- -14, -9, -2, 5, 11, 14, 12, 13, 19, 26, 29, 26, 19, 13, 8, 8,
- 9, 5, 2, 2, 4, 3, 1, 1, 5, 8, 7, 0, -10, -18, -25, -32,
- -42, -52, -56, -53, -48, -38, -29, -14, 1, 14, 23, 30, 33, 33, 35, 33,
- 26, 17, 9, 2, 1, 0, -5, -12, -19, -22, -21, -13, -8, -4, 5, 10,
- 12, 10, 10, 14, 21, 25, 24, 15, 5, 3, 5, 7, 5, 2, 5, 10,
- 12, 10, 9, 11, 13, 10, 2, -8, -18, -25, -32, -40, -50, -55, -53, -45,
- -35, -27, -17, -4, 11, 20, 28, 30, 28, 29, 30, 28, 19, 10, 6, 6,
- 5, 0, -10, -18, -20, -18, -14, -11, -10, -4, 6, 13, 13, 11, 13, 20,
- 25, 24, 15, 7, 3, 4, 5, 4, 0, 3, 9, 14, 15, 11, 9, 8,
- 8, 6, -5, -16, -24, -29, -35, -43, -48, -47, -42, -31, -23, -17, -7, 5,
- 17, 24, 26, 22, 19, 19, 20, 17, 11, 5, 2, 2, 0, -4, -10, -14,
- -14, -10, -8, -6, 1, 10, 19, 23, 22, 17, 16, 19, 18, 11, 1, -8,
- -11, -10, -7, -4, 1, 7, 15, 22, 22, 18, 17, 16, 12, 4, -8, -21,
- -29, -34, -39, -46, -49, -46, -37, -28, -19, -9, -2, 8, 19, 22, 20, 18,
- 18, 19, 19, 12, 6, 3, 2, 0, -5, -10, -16, -18, -14, -9, -8, -3,
- 6, 17, 25, 27, 26, 24, 25, 22, 15, 3, -8, -13, -13, -12, -11, -6,
- 0, 9, 16, 19, 19, 16, 13, 10, 6, -5, -14, -22, -26, -32, -37, -41,
- -39, -32, -23, -17, -14, -10, -3, 9, 17, 18, 10, 7, 10, 16, 18, 12,
- 5, 1, 1, -4, -13, -18, -18, -15, -12, -11, -10, 1, 15, 29, 37, 35,
- 31, 30, 30, 24, 11, -8, -18, -18, -15, -17, -20, -17, -6, 8, 15, 18,
- 16, 15, 11, 12, 8, 0, -10, -16, -20, -28, -35, -38, -33, -27, -23, -21,
- -19, -13, 0, 11, 14, 12, 9, 11, 18, 21, 19, 10, 2, -3, -5, -12,
- -21, -28, -26, -20, -15, -12, -6, 9, 25, 38, 43, 42, 40, 38, 34, 23,
- 6, -12, -18, -18, -18, -23, -25, -22, -13, 0, 7, 9, 8, 8, 11, 12,
- 9, 6, 2, -5, -14, -21, -24, -24, -22, -22, -21, -22, -20, -12, -3, 4,
- 5, 5, 6, 11, 15, 16, 10, 4, -2, -7, -11, -20, -25, -27, -21, -13,
- -11, -5, 6, 22, 37, 46, 50, 49, 44, 39, 31, 16, -3, -15, -21, -24,
- -27, -32, -33, -28, -17, -5, 5, 7, 7, 10, 15, 16, 15, 10, 4, -4,
- -11, -18, -22, -22, -20, -22, -21, -21, -17, -10, 1, 6, 9, 10, 15, 19,
- 18, 12, 5, 0, -9, -15, -23, -31, -36, -32, -24, -17, -11, -4, 12, 31,
- 47, 53, 58, 60, 56, 49, 35, 15, -4, -16, -21, -25, -32, -42, -45, -35,
- -23, -14, -8, 0, 6, 13, 20, 21, 19, 15, 9, 1, -6, -11, -13, -16,
- -18, -20, -23, -20, -14, -8, 0, 2, 5, 11, 18, 18, 14, 6, -2, -10,
- -18, -27, -34, -41, -40, -31, -20, -12, -7, 4, 23, 47, 64, 71, 71, 63,
- 56, 46, 30, 12, -7, -22, -35, -42, -49, -52, -48, -34, -22, -14, -7, 3,
- 15, 24, 27, 27, 24, 15, 6, -4, -8, -11, -13, -13, -15, -16, -14, -12,
- -7, -2, 3, 10, 12, 14, 15, 7, 0, -7, -16, -25, -32, -40, -44, -44,
- -36, -24, -11, 0, 6, 16, 36, 58, 72, 76, 71, 62, 51, 38, 24, 5,
- -13, -30, -42, -50, -52, -53, -46, -33, -21, -15, -6, 7, 20, 25, 25, 21,
- 18, 14, 7, 2, -5, -9, -9, -7, -8, -9, -10, -7, -3, 1, 6, 7,
- 8, 9, 6, -2, -13, -23, -30, -35, -41, -45, -44, -38, -26, -15, -3, 11,
- 19, 33, 52, 69, 75, 72, 65, 54, 42, 29, 13, -6, -25, -41, -49, -54,
- -55, -48, -38, -26, -18, -8, 1, 13, 24, 29, 26, 19, 11, 5, 2, -2,
- -6, -6, -6, -5, -7, -5, 1, 5, 9, 11, 8, 8, 7, 4, -6, -17,
- -28, -35, -42, -47, -48, -45, -39, -29, -16, -5, 7, 18, 32, 45, 57, 64,
- 67, 62, 54, 45, 35, 22, 5, -13, -28, -40, -47, -49, -46, -42, -32, -21,
- -11, -4, 6, 15, 21, 21, 16, 12, 6, 1, -3, -5, -3, 3, 8, 9,
- 8, 7, 7, 11, 12, 11, 6, -2, -9, -13, -20, -29, -40, -47, -47, -45,
- -42, -37, -29, -16, -5, 7, 17, 27, 38, 48, 56, 59, 53, 44, 40, 37,
- 30, 17, -2, -16, -25, -32, -35, -36, -35, -31, -23, -16, -10, -3, 4, 10,
- 11, 8, 1, 0, 0, 0, 0, 1, 6, 14, 20, 21, 19, 15, 14, 13,
- 11, 7, 0, -13, -21, -28, -37, -46, -51, -48, -43, -37, -32, -28, -21, -9,
- 4, 17, 27, 32, 40, 45, 50, 51, 46, 40, 38, 35, 27, 12, -3, -13,
- -23, -27, -29, -30, -29, -28, -23, -15, -10, -5, 2, 5, 5, 1, -2, -2,
- 1, 4, 4, 8, 14, 19, 25, 26, 21, 15, 13, 12, 12, 5, -9, -21,
- -30, -37, -43, -50, -51, -47, -42, -38, -34, -27, -17, -5, 10, 22, 30, 38,
- 44, 49, 50, 46, 40, 37, 38, 33, 19, 4, -8, -14, -18, -22, -24, -24,
- -22, -18, -16, -14, -10, -6, 1, 1, -6, -8, -9, -6, 0, 2, 8, 14,
- 21, 28, 31, 27, 24, 21, 20, 16, 9, -3, -16, -26, -33, -42, -50, -55,
- -56, -50, -43, -39, -38, -29, -13, 6, 18, 27, 33, 42, 51, 54, 53, 48,
- 41, 39, 38, 29, 12, -5, -15, -19, -20, -23, -24, -22, -18, -17, -13, -12,
- -10, -4, -3, -4, -7, -8, -9, -9, -7, 2, 9, 14, 21, 26, 27, 27,
- 22, 20, 19, 17, 12, 1, -14, -25, -35, -41, -45, -50, -53, -54, -51, -47,
- -41, -31, -18, -3, 12, 24, 35, 47, 55, 58, 57, 55, 49, 46, 40, 26,
- 11, -5, -17, -22, -23, -23, -22, -21, -21, -18, -15, -9, -5, -3, -4, -6,
- -7, -9, -12, -12, -8, 1, 7, 13, 14, 19, 23, 27, 26, 25, 25, 20,
- 13, 4, -9, -22, -36, -42, -48, -55, -61, -62, -59, -54, -43, -32, -18, 0,
- 18, 35, 49, 57, 60, 62, 63, 61, 57, 48, 33, 15, -2, -15, -24, -28,
- -27, -22, -23, -24, -21, -13, -4, 3, 3, 1, -2, -4, -4, -9, -15, -16,
- -13, -9, -5, 2, 7, 11, 19, 24, 28, 31, 29, 28, 24, 12, -4, -21,
- -33, -38, -48, -61, -72, -76, -71, -61, -47, -34, -20, 2, 26, 45, 58, 65,
- 69, 74, 75, 68, 55, 41, 28, 13, -7, -22, -32, -32, -29, -24, -23, -22,
- -19, -7, 6, 7, 2, -2, -3, 0, -3, -10, -20, -24, -19, -12, -5, 1,
- 5, 14, 23, 30, 33, 37, 39, 36, 24, 8, -10, -25, -33, -43, -55, -71,
- -82, -82, -71, -57, -44, -29, -11, 13, 34, 52, 64, 70, 73, 77, 76, 65,
- 50, 35, 20, 4, -13, -26, -31, -32, -27, -26, -25, -21, -10, 2, 8, 5,
- 3, 0, 1, 2, -3, -12, -22, -24, -21, -16, -9, -3, 6, 14, 22, 28,
- 34, 41, 42, 35, 23, 6, -10, -21, -32, -45, -61, -76, -85, -82, -70, -54,
- -43, -29, -7, 18, 40, 55, 64, 71, 77, 81, 76, 62, 48, 32, 19, 6,
- -10, -23, -30, -29, -28, -30, -27, -20, -10, -2, 3, 1, 0, 3, 6, 4,
- -9, -18, -24, -22, -18, -14, -8, 0, 8, 16, 24, 32, 38, 42, 42, 31,
- 15, -2, -14, -25, -38, -52, -67, -81, -85, -76, -63, -49, -37, -19, 3, 26,
- 43, 57, 67, 75, 82, 79, 70, 56, 41, 28, 15, 1, -12, -22, -27, -27,
- -28, -26, -21, -12, -3, 3, -2, -2, 1, 3, 1, -12, -22, -28, -29, -27,
- -23, -18, -11, 3, 16, 25, 34, 44, 51, 52, 43, 27, 12, -2, -17, -34,
- -51, -71, -82, -86, -83, -75, -61, -45, -27, -7, 16, 37, 53, 63, 72, 78,
- 77, 68, 60, 45, 33, 20, 10, -2, -9, -15, -18, -22, -23, -19, -15, -8,
- -5, -7, -8, -7, -4, -3, -10, -22, -29, -29, -24, -21, -18, -14, -3, 12,
- 23, 27, 35, 44, 49, 47, 34, 18, 1, -11, -23, -40, -57, -73, -81, -80,
- -74, -64, -50, -36, -19, 2, 22, 38, 49, 61, 69, 74, 69, 60, 50, 40,
- 29, 20, 10, 2, -5, -9, -12, -16, -18, -14, -9, -6, -10, -13, -12, -10,
- -11, -15, -23, -30, -31, -27, -25, -23, -19, -8, 8, 20, 28, 36, 45, 49,
- 49, 41, 29, 15, -2, -15, -31, -49, -65, -76, -79, -77, -67, -55, -43, -30,
- -13, 7, 25, 40, 51, 60, 66, 66, 62, 54, 45, 37, 29, 22, 14, 7,
- 3, -3, -7, -10, -12, -10, -8, -12, -18, -19, -16, -13, -15, -23, -31, -33,
- -29, -26, -25, -23, -15, 1, 14, 23, 31, 40, 50, 52, 46, 36, 21, 7,
- -8, -24, -41, -58, -70, -75, -74, -67, -57, -43, -30, -18, -3, 13, 26, 39,
- 48, 56, 60, 58, 51, 45, 42, 36, 29, 25, 20, 14, 9, 6, 3, 0,
- -5, -6, -12, -17, -22, -21, -20, -24, -33, -37, -38, -35, -30, -28, -24, -17,
- -3, 12, 24, 33, 43, 50, 52, 49, 40, 28, 13, -3, -18, -34, -51, -63,
- -71, -72, -67, -59, -49, -37, -24, -10, 3, 16, 27, 37, 46, 50, 53, 51,
- 49, 46, 43, 37, 32, 29, 25, 21, 17, 10, 4, -3, -8, -10, -11, -18,
- -25, -29, -31, -34, -37, -40, -40, -37, -31, -25, -20, -13, 0, 17, 31, 41,
- 48, 50, 49, 46, 36, 22, 8, -5, -20, -36, -49, -61, -67, -67, -61, -51,
- -44, -36, -23, -9, 4, 13, 20, 30, 38, 46, 48, 47, 44, 44, 44, 46,
- 42, 35, 31, 28, 24, 15, 5, -3, -6, -10, -18, -28, -35, -39, -41, -41,
- -43, -45, -42, -36, -29, -23, -15, 1, 15, 28, 40, 47, 51, 51, 46, 37,
- 27, 14, 2, -14, -29, -42, -49, -54, -62, -63, -57, -49, -41, -31, -21, -12,
- -3, 6, 17, 25, 32, 40, 45, 49, 50, 48, 49, 49, 48, 44, 39, 34,
- 26, 13, 4, -4, -11, -17, -23, -32, -41, -48, -48, -49, -48, -44, -39, -36,
- -31, -21, -5, 13, 24, 35, 44, 51, 52, 47, 39, 30, 21, 8, -6, -18,
- -34, -44, -50, -54, -59, -58, -53, -46, -38, -28, -18, -10, -4, 6, 16, 24,
- 30, 37, 42, 48, 49, 47, 48, 51, 51, 49, 45, 35, 27, 17, 9, 0,
- -12, -23, -32, -41, -48, -53, -55, -54, -53, -49, -43, -38, -27, -13, 5, 20,
- 33, 44, 52, 58, 57, 50, 40, 29, 16, 5, -11, -29, -43, -53, -56, -62,
- -65, -63, -54, -42, -33, -24, -16, -8, 3, 16, 23, 29, 33, 38, 44, 46,
- 45, 43, 45, 49, 52, 48, 42, 37, 28, 19, 10, 0, -13, -25, -36, -42,
- -47, -56, -58, -56, -53, -49, -48, -40, -26, -6, 13, 27, 39, 49, 59, 64,
- 62, 53, 42, 29, 16, 2, -18, -37, -52, -60, -65, -71, -75, -68, -55, -41,
- -30, -19, -10, 0, 14, 24, 33, 37, 38, 39, 42, 45, 45, 43, 45, 48,
- 47, 46, 41, 35, 28, 19, 8, -6, -20, -30, -38, -44, -50, -55, -57, -59,
- -57, -53, -46, -35, -19, 0, 17, 32, 45, 59, 66, 66, 59, 54, 46, 32,
- 15, -5, -24, -43, -57, -65, -71, -76, -78, -71, -58, -41, -27, -16, -5, 5,
- 15, 27, 37, 43, 43, 42, 42, 42, 43, 46, 46, 46, 45, 42, 41, 35,
- 28, 18, 7, -6, -18, -29, -37, -44, -51, -56, -59, -61, -60, -55, -45, -33,
- -18, -2, 18, 37, 50, 61, 67, 68, 65, 59, 47, 31, 10, -11, -32, -47,
- -58, -71, -81, -86, -83, -70, -52, -36, -21, -9, 2, 13, 25, 35, 41, 44,
- 43, 40, 39, 39, 40, 43, 43, 40, 39, 40, 40, 36, 28, 18, 9, -5,
- -18, -28, -36, -44, -52, -57, -61, -64, -63, -56, -43, -27, -13, 6, 26, 44,
- 56, 66, 71, 71, 64, 55, 42, 23, 3, -19, -38, -52, -66, -76, -82, -86,
- -81, -67, -49, -32, -19, -8, 3, 15, 28, 36, 42, 43, 43, 41, 41, 40,
- 40, 41, 40, 40, 41, 41, 36, 30, 24, 17, 10, -5, -19, -29, -37, -43,
- -50, -57, -64, -66, -60, -50, -40, -28, -10, 12, 32, 45, 54, 59, 64, 67,
- 63, 54, 35, 14, -6, -22, -35, -50, -64, -75, -82, -81, -73, -59, -46, -33,
- -21, -8, 5, 19, 27, 33, 40, 44, 44, 42, 40, 42, 41, 40, 38, 39,
- 38, 38, 35, 30, 21, 13, 4, -8, -16, -25, -35, -45, -53, -62, -65, -63,
- -56, -47, -39, -25, -6, 15, 32, 45, 53, 58, 64, 65, 60, 48, 30, 9,
- -7, -19, -31, -47, -60, -72, -79, -79, -73, -61, -50, -37, -24, -10, 3, 12,
- 22, 33, 43, 47, 46, 44, 43, 45, 46, 45, 45, 43, 41, 38, 34, 26,
- 16, 7, -2, -10, -19, -29, -39, -50, -59, -64, -62, -58, -51, -44, -34, -22,
- -2, 16, 30, 41, 52, 56, 57, 58, 54, 42, 29, 13, 2, -12, -27, -42,
- -56, -67, -71, -73, -70, -63, -55, -42, -26, -10, 2, 11, 20, 33, 41, 46,
- 45, 43, 49, 53, 52, 48, 44, 43, 42, 38, 33, 22, 12, 4, -5, -13,
- -23, -34, -43, -50, -57, -61, -60, -55, -49, -40, -29, -14, -2, 12, 25, 35,
- 44, 51, 56, 56, 49, 39, 30, 20, 10, -2, -17, -32, -48, -60, -67, -74,
- -77, -74, -66, -50, -36, -21, -9, 0, 14, 30, 43, 51, 53, 57, 62, 64,
- 62, 58, 53, 48, 42, 36, 25, 12, 4, -4, -12, -21, -31, -38, -43, -45,
- -47, -49, -47, -44, -40, -34, -28, -22, -11, 1, 11, 21, 28, 39, 49, 53,
- 52, 49, 44, 38, 29, 16, -4, -24, -41, -57, -74, -86, -90, -86, -73, -59,
- -44, -30, -16, 1, 21, 40, 54, 61, 66, 67, 71, 72, 65, 57, 49, 41,
- 33, 24, 12, 1, -8, -12, -15, -22, -31, -37, -35, -31, -33, -36, -39, -40,
- -38, -34, -32, -29, -24, -14, -2, 11, 24, 36, 48, 56, 61, 63, 59, 54,
- 44, 27, 6, -19, -46, -68, -84, -94, -99, -98, -90, -72, -51, -30, -15, 1,
- 22, 46, 64, 76, 78, 80, 81, 78, 72, 60, 45, 34, 24, 13, 0, -13,
- -18, -18, -18, -22, -28, -29, -24, -19, -19, -26, -33, -38, -40, -40, -41, -42,
- -41, -32, -15, 6, 22, 37, 50, 62, 74, 79, 76, 65, 50, 30, 6, -24,
- -54, -78, -94, -106, -110, -103, -89, -69, -49, -29, -10, 11, 36, 57, 73, 78,
- 80, 82, 83, 77, 66, 51, 37, 24, 14, 5, -5, -12, -17, -17, -17, -18,
- -19, -17, -13, -13, -19, -28, -37, -44, -44, -48, -53, -59, -54, -35, -12, 11,
- 29, 46, 61, 78, 88, 90, 84, 68, 49, 24, -6, -39, -71, -92, -104, -115,
- -116, -108, -89, -66, -43, -21, 1, 24, 49, 68, 78, 82, 81, 81, 79, 71,
- 56, 37, 24, 15, 6, -4, -9, -11, -9, -6, -6, -10, -11, -6, -4, -8,
- -20, -33, -44, -55, -61, -65, -70, -68, -55, -31, -6, 15, 38, 61, 82, 97,
- 101, 94, 80, 61, 37, 9, -25, -60, -88, -107, -119, -123, -116, -99, -77, -53,
- -30, -5, 20, 47, 68, 80, 82, 82, 80, 77, 70, 57, 40, 23, 10, 3,
- -2, -3, -4, -3, 2, 5, 7, 5, 5, 4, -4, -17, -32, -45, -60, -69,
- -74, -79, -80, -70, -47, -20, 9, 32, 55, 76, 94, 104, 103, 91, 71, 46,
- 16, -16, -48, -75, -97, -115, -121, -117, -101, -80, -57, -32, -8, 15, 39, 58,
- 68, 73, 73, 73, 69, 61, 50, 39, 26, 15, 7, 4, 7, 12, 18, 19,
- 20, 18, 17, 15, 10, -4, -20, -41, -57, -68, -77, -85, -91, -90, -76, -53,
- -25, 2, 28, 55, 79, 97, 106, 104, 94, 77, 52, 22, -9, -39, -67, -92,
- -111, -119, -115, -99, -79, -55, -33, -11, 15, 37, 55, 67, 71, 68, 61, 51,
- 44, 40, 35, 24, 10, 3, 4, 13, 25, 36, 42, 41, 34, 29, 20, 12,
- -2, -21, -43, -66, -84, -94, -96, -96, -93, -81, -55, -26, 4, 30, 56, 80,
- 98, 107, 106, 95, 77, 53, 24, -8, -38, -64, -85, -101, -109, -109, -100, -80,
- -55, -31, -8, 13, 31, 46, 56, 61, 59, 52, 43, 36, 30, 25, 16, 8,
- 7, 11, 23, 37, 48, 56, 59, 56, 48, 33, 17, -5, -29, -54, -79, -96,
- -106, -109, -105, -96, -82, -57, -25, 8, 38, 61, 79, 94, 103, 102, 92, 73,
- 46, 19, -10, -36, -62, -81, -95, -101, -100, -90, -71, -47, -25, -3, 18, 31,
- 41, 49, 53, 50, 42, 32, 21, 13, 9, 7, 8, 8, 12, 30, 49, 63,
- 71, 76, 75, 67, 48, 25, -3, -30, -59, -87, -107, -120, -124, -117, -105, -89,
- -63, -31, 5, 40, 63, 81, 92, 100, 100, 88, 69, 46, 20, -6, -31, -55,
- -73, -87, -91, -88, -80, -64, -45, -22, 1, 16, 27, 34, 39, 45, 41, 31,
- 20, 9, 4, 3, 1, 3, 6, 15, 32, 53, 71, 81, 85, 86, 78, 61,
- 35, 3, -29, -63, -93, -113, -124, -128, -124, -110, -89, -64, -32, 5, 38, 62,
- 80, 91, 98, 93, 80, 63, 42, 19, -5, -29, -51, -68, -78, -81, -79, -72,
- -58, -40, -19, 0, 13, 21, 29, 35, 35, 29, 21, 14, 8, 2, -2, -3,
- 1, 10, 20, 36, 56, 73, 84, 89, 89, 81, 65, 41, 6, -32, -63, -90,
- -110, -124, -127, -123, -110, -89, -61, -30, 2, 33, 56, 71, 81, 86, 85, 74,
- 58, 38, 17, -5, -21, -38, -52, -62, -69, -69, -64, -50, -34, -18, -5, 5,
- 13, 23, 28, 27, 22, 15, 10, 6, 1, 0, -2, 2, 9, 23, 41, 56,
- 72, 84, 88, 89, 81, 66, 45, 15, -20, -55, -84, -106, -119, -121, -116, -105,
- -89, -67, -38, -7, 21, 44, 58, 69, 75, 74, 64, 50, 36, 22, 8, -10,
- -26, -39, -47, -54, -56, -53, -47, -36, -25, -11, -2, 5, 14, 23, 24, 20,
- 12, 7, 6, 6, 6, 4, 5, 10, 22, 39, 57, 72, 80, 82, 80, 73,
- 62, 45, 18, -13, -48, -78, -96, -105, -105, -104, -97, -81, -64, -40, -15, 10,
- 28, 40, 49, 54, 53, 49, 42, 31, 22, 13, 2, -9, -17, -22, -30, -38,
- -40, -37, -33, -28, -22, -16, -10, -5, 5, 11, 11, 6, 3, 5, 11, 16,
- 16, 18, 22, 29, 40, 54, 68, 75, 74, 72, 63, 49, 35, 15, -10, -37,
- -63, -83, -94, -95, -89, -82, -73, -63, -46, -24, -2, 16, 25, 31, 35, 39,
- 41, 37, 30, 22, 15, 11, 4, -3, -11, -18, -25, -31, -35, -33, -28, -22,
- -18, -16, -13, -4, 5, 10, 11, 10, 5, 6, 14, 21, 23, 24, 27, 33,
- 45, 59, 68, 72, 67, 57, 46, 34, 19, 0, -24, -49, -70, -81, -82, -77,
- -70, -65, -60, -49, -34, -15, 2, 9, 13, 14, 18, 20, 21, 19, 18, 17,
- 16, 15, 13, 10, 5, -3, -12, -20, -26, -28, -27, -24, -26, -25, -18, -9,
- 3, 9, 10, 10, 11, 18, 27, 32, 33, 33, 35, 42, 51, 58, 59, 55,
- 46, 36, 25, 16, 3, -15, -33, -50, -61, -65, -64, -59, -57, -56, -52, -42,
- -29, -14, -5, -2, -3, 1, 8, 12, 13, 13, 16, 16, 18, 19, 19, 14,
- 4, -3, -10, -19, -24, -24, -22, -20, -24, -23, -16, -2, 10, 16, 14, 13,
- 16, 28, 35, 36, 35, 32, 33, 40, 45, 49, 47, 41, 31, 20, 12, 4,
- -8, -16, -29, -41, -50, -53, -50, -49, -51, -51, -48, -40, -30, -20, -13, -13,
- -12, -6, 2, 8, 12, 13, 16, 21, 26, 27, 23, 15, 8, 0, -10, -19,
- -23, -24, -24, -26, -25, -21, -9, 5, 15, 19, 20, 22, 28, 36, 39, 38,
- 36, 33, 33, 35, 37, 38, 36, 30, 20, 9, 4, -3, -10, -17, -26, -35,
- -40, -45, -47, -51, -52, -49, -46, -39, -30, -23, -19, -17, -12, -5, 1, 4,
- 7, 11, 18, 22, 22, 22, 20, 17, 12, 3, -8, -16, -18, -16, -17, -19,
- -18, -12, 3, 13, 19, 20, 24, 29, 34, 35, 33, 32, 31, 31, 30, 26,
- 24, 24, 25, 21, 14, 6, 0, -4, -5, -10, -19, -31, -37, -40, -47, -51,
- -50, -49, -45, -39, -31, -25, -19, -12, -6, -3, 0, 2, 6, 13, 17, 18,
- 16, 15, 16, 14, 7, -3, -10, -12, -13, -13, -14, -13, -6, 6, 18, 24,
- 25, 26, 29, 33, 32, 26, 24, 23, 23, 22, 18, 14, 15, 21, 24, 22,
- 14, 6, 4, 4, 1, -9, -21, -32, -41, -47, -50, -54, -54, -51, -47, -37,
- -30, -21, -10, -3, 1, 4, 6, 7, 8, 7, 7, 7, 7, 6, 6, 5,
- 2, -3, -8, -8, -6, -3, 1, 3, 9, 17, 25, 29, 32, 33, 29, 26,
- 24, 23, 20, 17, 14, 11, 8, 8, 14, 21, 22, 17, 13, 9, 9, 7,
- 1, -11, -25, -37, -44, -52, -53, -55, -55, -51, -43, -35, -24, -14, -4, 3,
- 4, 4, 6, 7, 6, 3, -2, -2, 2, 6, 5, 1, -4, -8, -7, -5,
- 3, 9, 9, 12, 17, 25, 32, 37, 37, 32, 25, 21, 19, 17, 15, 9,
- 6, 6, 6, 8, 14, 23, 24, 20, 15, 14, 11, 3, -6, -18, -31, -44,
- -53, -54, -57, -58, -55, -47, -37, -26, -16, -4, 7, 10, 10, 9, 7, 3,
- -2, -6, -8, -6, -5, -4, -7, -10, -8, -6, 0, 6, 12, 16, 20, 27,
- 33, 35, 35, 36, 34, 28, 21, 16, 10, 7, 7, 5, 3, 1, 5, 12,
- 21, 25, 23, 17, 14, 13, 9, -3, -17, -30, -41, -50, -54, -59, -61, -55,
- -46, -37, -26, -15, -4, 7, 14, 15, 12, 6, 1, -3, -7, -12, -14, -15,
- -13, -12, -12, -12, -8, 0, 8, 15, 20, 25, 31, 36, 40, 41, 41, 38,
- 33, 27, 21, 12, 4, 1, 0, -4, -5, -2, 5, 12, 17, 19, 19, 18,
- 14, 11, 2, -9, -21, -32, -42, -49, -55, -57, -56, -49, -39, -30, -20, -8,
- 3, 12, 17, 18, 12, 5, -2, -8, -14, -18, -21, -22, -21, -21, -19, -13,
- -7, 4, 14, 24, 32, 39, 44, 48, 47, 44, 41, 38, 33, 27, 17, 7,
- -3, -5, -5, -5, -5, -5, 3, 12, 17, 19, 16, 11, 7, 3, -6, -15,
- -26, -36, -42, -48, -53, -54, -50, -40, -31, -22, -12, -2, 11, 19, 20, 13,
- 6, 2, -5, -12, -21, -26, -29, -31, -30, -27, -21, -13, -2, 12, 25, 36,
- 48, 57, 62, 60, 51, 46, 43, 37, 28, 15, 3, -8, -12, -14, -12, -10,
- -7, -4, 8, 16, 20, 17, 14, 10, 6, -2, -12, -24, -32, -39, -45, -51,
- -54, -52, -43, -32, -21, -12, -2, 11, 22, 28, 24, 13, 4, -6, -14, -23,
- -32, -38, -41, -42, -39, -31, -20, -8, 6, 21, 37, 50, 63, 69, 68, 61,
- 55, 48, 39, 29, 20, 9, -6, -15, -17, -13, -11, -7, -4, 3, 11, 13,
- 16, 15, 10, 5, 0, -8, -15, -25, -31, -37, -42, -49, -52, -46, -37, -30,
- -21, -12, 0, 14, 25, 28, 25, 15, 2, -11, -22, -29, -36, -44, -49, -49,
- -43, -32, -18, -5, 13, 30, 50, 66, 74, 75, 71, 68, 61, 50, 37, 26,
- 15, 3, -13, -22, -22, -20, -16, -14, -9, 1, 9, 11, 11, 9, 9, 9,
- 6, -3, -15, -25, -32, -37, -41, -50, -53, -50, -41, -30, -20, -8, 6, 21,
- 31, 33, 26, 15, 0, -12, -23, -34, -46, -56, -60, -54, -44, -31, -19, -2,
- 21, 44, 66, 77, 81, 79, 75, 72, 63, 51, 35, 23, 10, -4, -16, -25,
- -28, -26, -22, -16, -12, -7, -2, 4, 8, 10, 14, 14, 7, -3, -12, -20,
- -28, -36, -42, -48, -53, -53, -43, -31, -19, -6, 12, 25, 31, 30, 26, 15,
- -2, -17, -28, -40, -52, -60, -61, -53, -40, -25, -9, 11, 32, 56, 74, 84,
- 85, 81, 76, 72, 61, 46, 29, 13, -2, -16, -23, -29, -33, -31, -25, -19,
- -14, -8, 2, 10, 14, 18, 19, 17, 8, 1, -12, -24, -35, -42, -49, -54,
- -57, -53, -43, -30, -13, 7, 22, 32, 34, 32, 26, 11, -8, -24, -40, -50,
- -60, -66, -63, -53, -36, -17, 2, 23, 45, 67, 84, 90, 91, 85, 78, 72,
- 62, 44, 24, 4, -9, -21, -32, -39, -41, -36, -30, -23, -17, -9, 2, 13,
- 23, 27, 26, 19, 12, 2, -12, -26, -38, -47, -54, -59, -59, -53, -41, -23,
- -5, 14, 28, 36, 36, 31, 21, 6, -13, -31, -46, -58, -66, -70, -65, -50,
- -28, -7, 14, 35, 58, 76, 89, 96, 94, 90, 82, 72, 54, 35, 16, -5,
- -21, -31, -40, -48, -47, -38, -28, -20, -13, 1, 15, 28, 33, 33, 27, 18,
- 8, -6, -21, -37, -52, -64, -66, -65, -58, -47, -30, -9, 13, 28, 38, 43,
- 40, 31, 15, -5, -24, -40, -57, -69, -75, -74, -65, -48, -26, -2, 24, 47,
- 66, 83, 97, 102, 102, 101, 91, 73, 51, 28, 7, -15, -33, -45, -56, -60,
- -54, -42, -28, -17, -4, 13, 26, 36, 38, 36, 29, 16, 2, -14, -34, -52,
- -62, -66, -65, -63, -53, -36, -15, 9, 27, 36, 41, 40, 35, 25, 8, -16,
- -37, -55, -68, -77, -81, -75, -60, -37, -12, 12, 35, 57, 75, 94, 105, 107,
- 103, 97, 84, 64, 41, 18, -6, -25, -40, -51, -57, -56, -46, -32, -19, -6,
- 7, 20, 30, 34, 32, 24, 12, 0, -17, -33, -47, -60, -65, -64, -58, -46,
- -31, -12, 8, 26, 37, 43, 44, 41, 28, 11, -12, -31, -49, -67, -81, -87,
- -85, -72, -52, -30, -6, 21, 45, 69, 87, 101, 110, 113, 110, 100, 77, 51,
- 27, 8, -11, -32, -49, -59, -59, -53, -41, -27, -11, 3, 14, 24, 28, 28,
- 24, 17, 5, -15, -32, -45, -54, -61, -58, -54, -44, -32, -13, 8, 26, 37,
- 41, 40, 36, 29, 16, -3, -24, -47, -66, -81, -89, -88, -76, -58, -37, -16,
- 10, 34, 58, 78, 94, 106, 111, 107, 97, 81, 58, 37, 17, 0, -17, -33,
- -45, -51, -48, -38, -26, -14, -3, 9, 16, 19, 17, 14, 10, 0, -15, -30,
- -42, -49, -52, -49, -44, -37, -25, -8, 9, 21, 29, 32, 35, 33, 29, 19,
- 1, -18, -38, -58, -75, -85, -85, -79, -70, -52, -29, -6, 20, 44, 67, 89,
- 101, 110, 114, 107, 93, 72, 49, 28, 10, -9, -25, -38, -48, -49, -42, -31,
- -20, -11, 0, 9, 13, 12, 7, 5, 0, -11, -24, -36, -42, -44, -43, -38,
- -28, -16, -4, 8, 16, 22, 29, 30, 29, 24, 13, 2, -14, -32, -51, -68,
- -79, -83, -77, -69, -56, -41, -19, 6, 31, 53, 74, 90, 101, 108, 109, 101,
- 83, 60, 38, 24, 9, -10, -25, -36, -40, -37, -29, -21, -13, -8, 0, 3,
- 0, -5, -6, -8, -16, -27, -35, -39, -40, -33, -27, -21, -11, 3, 14, 21,
- 24, 27, 26, 22, 19, 13, 3, -14, -32, -53, -66, -74, -80, -80, -75, -63,
- -47, -28, -4, 19, 41, 66, 85, 99, 105, 106, 104, 95, 76, 51, 29, 13,
- 2, -12, -27, -36, -38, -32, -22, -15, -12, -8, -3, -4, -9, -12, -14, -18,
- -26, -31, -35, -36, -29, -20, -10, -2, 7, 16, 25, 25, 24, 19, 15, 10,
- 4, -4, -16, -30, -44, -57, -67, -73, -75, -70, -60, -48, -34, -16, 5, 27,
- 51, 71, 85, 92, 99, 101, 95, 82, 64, 44, 28, 14, 1, -12, -22, -28,
- -27, -22, -18, -17, -15, -15, -15, -21, -23, -25, -24, -27, -31, -34, -30, -21,
- -6, 7, 13, 17, 22, 27, 28, 24, 16, 7, -3, -10, -17, -27, -35, -43,
- -50, -58, -68, -70, -65, -53, -42, -32, -22, -4, 15, 36, 54, 70, 83, 89,
- 92, 91, 82, 68, 54, 42, 29, 14, 2, -9, -17, -21, -22, -20, -21, -20,
- -23, -26, -30, -32, -32, -29, -27, -28, -30, -26, -15, 0, 15, 25, 25, 25,
- 26, 27, 21, 11, 0, -9, -17, -24, -30, -38, -45, -47, -49, -55, -59, -56,
- -48, -39, -28, -20, -9, 7, 26, 44, 55, 65, 72, 79, 80, 77, 66, 57,
- 49, 41, 30, 19, 7, -2, -7, -12, -17, -22, -25, -29, -33, -36, -39, -41,
- -36, -29, -26, -26, -22, -11, 2, 17, 28, 32, 31, 29, 28, 23, 11, -2,
- -9, -17, -24, -36, -44, -48, -49, -50, -53, -54, -54, -47, -36, -25, -17, -7,
- 7, 21, 36, 47, 55, 63, 70, 72, 69, 60, 52, 46, 42, 34, 23, 15,
- 8, 3, 0, -7, -14, -21, -24, -27, -32, -39, -44, -43, -37, -29, -25, -23,
- -16, -2, 14, 26, 32, 33, 32, 30, 25, 16, 4, -6, -16, -25, -36, -45,
- -50, -54, -51, -51, -54, -54, -48, -36, -23, -15, -6, 5, 17, 31, 42, 51,
- 59, 62, 63, 61, 56, 51, 43, 40, 38, 28, 20, 13, 9, 7, 2, -8,
- -16, -23, -27, -31, -36, -40, -43, -39, -31, -23, -20, -15, -4, 11, 24, 31,
- 32, 31, 30, 25, 17, 7, -3, -13, -23, -36, -48, -56, -58, -57, -53, -50,
- -52, -51, -40, -25, -12, 0, 7, 16, 25, 36, 49, 58, 60, 59, 57, 54,
- 49, 43, 36, 31, 26, 18, 13, 10, 6, 4, 0, -6, -12, -19, -22, -26,
- -31, -35, -35, -32, -27, -22, -16, -7, 4, 13, 21, 26, 30, 29, 27, 22,
- 15, 4, -7, -19, -31, -44, -55, -59, -59, -58, -54, -52, -49, -41, -28, -14,
- 0, 10, 18, 26, 33, 44, 50, 53, 51, 50, 48, 46, 41, 37, 30, 24,
- 21, 18, 15, 13, 8, 4, 0, -6, -9, -14, -19, -23, -27, -33, -33, -31,
- -25, -19, -11, -3, 3, 11, 20, 28, 31, 28, 22, 14, 8, -3, -15, -29,
- -40, -49, -57, -62, -60, -56, -50, -47, -42, -32, -18, -3, 11, 20, 25, 29,
- 35, 43, 49, 51, 47, 43, 41, 37, 33, 29, 24, 18, 15, 14, 13, 11,
- 8, 5, 1, 0, -5, -11, -19, -23, -24, -25, -25, -26, -22, -15, -9, -3,
- 4, 12, 19, 25, 26, 24, 17, 11, 2, -11, -26, -37, -45, -53, -58, -59,
- -57, -53, -47, -42, -35, -25, -10, 5, 15, 19, 22, 29, 37, 45, 48, 47,
- 44, 44, 43, 40, 33, 24, 19, 14, 13, 12, 8, 2, -2, 1, 1, 1,
- -4, -12, -15, -14, -13, -14, -18, -18, -15, -12, -8, -5, 2, 10, 18, 21,
- 20, 15, 10, 3, -7, -18, -31, -42, -47, -50, -53, -57, -57, -51, -42, -34,
- -25, -15, -5, 7, 16, 22, 30, 35, 40, 43, 42, 39, 39, 38, 38, 31,
- 22, 16, 14, 15, 17, 16, 12, 6, 4, 5, 7, 6, 0, -8, -12, -13,
- -15, -19, -21, -20, -17, -14, -11, -6, 2, 10, 18, 21, 21, 19, 11, -2,
- -17, -29, -37, -42, -46, -52, -55, -58, -52, -42, -34, -24, -15, -5, 5, 12,
- 17, 24, 32, 37, 37, 36, 33, 33, 35, 35, 32, 26, 22, 16, 17, 19,
- 19, 14, 7, 5, 5, 6, 5, 0, -7, -10, -9, -6, -7, -13, -17, -15,
- -11, -8, -7, -6, 1, 7, 12, 13, 11, 7, 0, -12, -25, -35, -40, -42,
- -43, -44, -47, -49, -43, -34, -22, -12, -7, 0, 4, 9, 17, 25, 31, 33,
- 33, 31, 30, 27, 28, 30, 29, 25, 20, 17, 20, 24, 22, 17, 11, 10,
- 9, 9, 5, -6, -11, -13, -9, -5, -9, -16, -19, -16, -9, -6, -6, -2,
- 4, 8, 11, 11, 6, -4, -11, -21, -34, -39, -41, -40, -38, -40, -44, -38,
- -28, -17, -10, -6, -5, -3, 3, 10, 15, 17, 20, 23, 26, 25, 24, 26,
- 28, 30, 30, 28, 25, 24, 23, 25, 22, 18, 14, 9, 5, 0, -7, -12,
- -13, -12, -7, -6, -9, -12, -10, -4, 2, 2, 3, 3, 3, 6, 7, 3,
- -9, -21, -28, -35, -40, -40, -37, -37, -36, -36, -29, -22, -11, -3, 2, 3,
- 0, 1, 3, 6, 9, 10, 10, 10, 13, 16, 21, 24, 29, 31, 33, 33,
- 33, 32, 30, 27, 23, 16, 12, 7, -2, -7, -14, -19, -16, -10, -5, -7,
- -9, -9, -6, 2, 6, 8, 7, 4, 3, 1, -3, -9, -16, -25, -34, -39,
- -41, -37, -33, -31, -31, -29, -22, -12, -4, 2, 7, 5, 1, -2, 0, 4,
- 4, 2, 2, 5, 10, 14, 19, 24, 28, 32, 36, 38, 36, 34, 31, 27,
- 23, 18, 11, 3, -5, -12, -15, -15, -11, -6, -5, -6, -8, -7, -3, 1,
- 4, 6, 3, -2, -7, -9, -12, -19, -24, -30, -34, -36, -35, -32, -29, -26,
- -22, -16, -10, -3, 4, 8, 9, 4, 0, -3, 0, 1, -5, -7, -5, 1,
- 7, 13, 14, 17, 27, 35, 38, 37, 35, 33, 31, 29, 25, 19, 11, 3,
- 0, -6, -10, -10, -7, -5, -5, -7, -7, -6, -3, 1, 4, 3, 0, -8,
- -15, -18, -20, -23, -27, -30, -32, -33, -29, -28, -25, -20, -16, -13, -6, 1,
- 6, 7, 4, 0, -5, -5, -5, -6, -7, -6, -2, 5, 10, 15, 20, 25,
- 32, 34, 34, 34, 32, 29, 24, 22, 19, 14, 9, 6, 4, 2, 0, 0,
- 2, 2, -2, -4, -6, -5, -5, -4, -4, -7, -12, -19, -25, -26, -26, -26,
- -26, -29, -28, -28, -25, -22, -18, -14, -10, -5, 0, 3, 4, 5, 4, 3,
- -2, -7, -10, -12, -9, -6, 0, 6, 11, 14, 16, 22, 30, 33, 34, 29,
- 25, 23, 21, 22, 22, 20, 18, 16, 14, 13, 11, 11, 11, 6, -4, -12,
- -16, -17, -16, -13, -16, -22, -26, -30, -30, -25, -21, -18, -17, -19, -18, -20,
- -19, -15, -13, -9, -7, -6, -5, -2, 3, 5, 4, 0, -5, -8, -6, -6,
- -6, -2, 4, 9, 11, 13, 15, 19, 23, 25, 22, 19, 16, 17, 20, 21,
- 22, 23, 24, 25, 24, 23, 22, 21, 16, 7, -4, -14, -21, -23, -24, -24,
- -28, -34, -38, -36, -31, -21, -13, -9, -8, -10, -11, -12, -14, -13, -12, -9,
- -10, -12, -11, -9, -4, 3, 4, 1, -3, -4, 1, 4, 7, 10, 10, 11,
- 12, 11, 8, 9, 11, 13, 11, 5, 4, 11, 20, 26, 29, 32, 35, 39,
- 39, 34, 30, 23, 15, 5, -10, -23, -31, -34, -32, -33, -37, -42, -41, -32,
- -21, -11, -6, -3, -3, -6, -8, -11, -14, -15, -14, -14, -14, -19, -20, -15,
- -7, 0, -2, -3, 0, 4, 10, 17, 19, 18, 18, 20, 18, 11, 5, 1,
- -2, -4, -7, -8, -4, 4, 14, 24, 32, 38, 46, 51, 52, 46, 37, 28,
- 19, 5, -12, -29, -39, -44, -46, -46, -50, -48, -39, -29, -14, -4, 6, 9,
- 8, 6, 0, -8, -13, -15, -18, -22, -28, -30, -26, -18, -9, -7, -4, 2,
- 10, 18, 24, 26, 26, 23, 22, 21, 14, 3, -5, -9, -14, -16, -16, -11,
- -4, 6, 14, 24, 37, 50, 58, 58, 53, 45, 36, 28, 17, 1, -18, -36,
- -47, -53, -54, -53, -51, -43, -33, -20, -8, 5, 15, 17, 13, 5, -4, -12,
- -14, -18, -23, -30, -34, -32, -24, -15, -10, -6, -3, 7, 18, 27, 32, 33,
- 30, 28, 24, 19, 12, 2, -10, -18, -24, -26, -23, -16, -6, 4, 12, 25,
- 39, 53, 60, 60, 58, 51, 42, 30, 16, 0, -20, -37, -49, -57, -61, -57,
- -50, -40, -29, -17, -4, 9, 17, 17, 11, 5, -3, -8, -13, -21, -30, -35,
- -34, -29, -22, -16, -11, -6, 1, 12, 24, 34, 39, 39, 35, 28, 21, 16,
- 8, -3, -16, -29, -35, -34, -26, -16, -9, 1, 14, 30, 46, 56, 60, 62,
- 59, 57, 46, 32, 15, -2, -17, -35, -51, -61, -61, -55, -46, -39, -30, -19,
- -4, 10, 14, 13, 7, 3, -2, -6, -15, -24, -31, -33, -31, -26, -23, -19,
- -11, -2, 6, 17, 30, 38, 41, 39, 34, 25, 18, 14, 6, -9, -24, -34,
- -38, -34, -28, -18, -9, 0, 14, 32, 44, 52, 58, 63, 66, 59, 45, 31,
- 18, 4, -17, -36, -53, -60, -59, -54, -46, -39, -30, -18, -3, 6, 8, 6,
- 3, 1, -3, -11, -22, -29, -28, -23, -20, -20, -18, -10, -2, 7, 17, 27,
- 34, 37, 38, 33, 26, 19, 15, 11, 0, -17, -31, -39, -40, -34, -27, -20,
- -11, 1, 16, 31, 43, 52, 59, 67, 70, 62, 47, 32, 19, 4, -18, -39,
- -53, -60, -57, -51, -44, -37, -30, -17, -6, 1, 2, 1, 0, -2, -7, -15,
- -23, -27, -25, -19, -16, -15, -12, -4, 5, 15, 25, 33, 37, 34, 31, 27,
- 22, 17, 11, 2, -11, -25, -35, -41, -41, -34, -23, -13, -4, 6, 18, 31,
- 43, 54, 61, 65, 62, 53, 44, 34, 22, 2, -20, -38, -47, -50, -47, -43,
- -42, -41, -32, -19, -13, -11, -10, -7, -5, -5, -9, -14, -18, -17, -12, -9,
- -8, -6, 1, 6, 12, 16, 21, 25, 25, 23, 19, 18, 14, 11, 8, 0,
- -10, -23, -34, -36, -32, -24, -16, -12, -6, 4, 15, 30, 42, 52, 59, 60,
- 58, 53, 46, 39, 27, 5, -19, -35, -43, -44, -43, -45, -49, -48, -39, -31,
- -27, -24, -19, -11, -6, -3, -4, -6, -8, -5, 3, 5, 7, 6, 7, 9,
- 12, 13, 15, 14, 12, 11, 11, 9, 8, 5, 4, 0, -12, -22, -28, -26,
- -21, -17, -13, -10, -5, 4, 14, 22, 32, 44, 56, 61, 59, 56, 48, 38,
- 25, 7, -10, -24, -33, -38, -44, -50, -51, -47, -41, -41, -41, -37, -26, -14,
- -6, 0, -2, -3, 5, 13, 19, 21, 16, 12, 9, 9, 10, 7, 3, 2,
- 2, 1, -2, 0, 3, 4, 1, -4, -12, -16, -16, -9, -9, -10, -9, -5,
- 2, 7, 11, 17, 27, 39, 51, 54, 52, 52, 49, 42, 28, 10, -4, -15,
- -25, -36, -48, -56, -58, -56, -52, -53, -54, -45, -28, -11, -2, 3, 8, 15,
- 24, 30, 34, 30, 22, 16, 12, 6, -4, -9, -9, -8, -12, -14, -12, -5,
- 3, 4, 2, -3, -4, 0, 3, 2, -4, -6, -6, -5, -4, -5, -3, 8,
- 21, 36, 44, 50, 55, 58, 55, 45, 33, 20, 5, -11, -27, -43, -55, -60,
- -61, -62, -64, -66, -58, -40, -20, -6, 3, 8, 16, 26, 34, 39, 38, 30,
- 21, 11, 2, -9, -14, -13, -13, -15, -16, -14, -6, 1, 4, 4, 3, 4,
- 7, 10, 10, 5, -3, -7, -8, -9, -12, -14, -11, 0, 13, 28, 40, 51,
- 58, 61, 60, 56, 47, 33, 15, -8, -28, -44, -55, -62, -72, -81, -83, -74,
- -58, -39, -21, -6, 8, 18, 30, 40, 47, 49, 44, 33, 19, 6, -6, -14,
- -19, -23, -26, -24, -19, -13, -5, -2, 2, 5, 8, 11, 14, 13, 9, 2,
- -4, -8, -12, -15, -19, -18, -13, -3, 14, 30, 44, 53, 62, 66, 66, 59,
- 48, 33, 12, -10, -31, -46, -58, -71, -79, -84, -81, -71, -54, -34, -14, 1,
- 14, 26, 37, 44, 48, 49, 41, 29, 12, -3, -13, -17, -19, -24, -26, -22,
- -16, -8, -3, -2, 3, 6, 10, 13, 12, 10, 6, 2, -4, -11, -18, -22,
- -22, -19, -14, -3, 13, 30, 46, 61, 68, 71, 70, 64, 52, 32, 10, -12,
- -31, -51, -67, -81, -88, -91, -84, -69, -51, -32, -12, 8, 25, 37, 43, 47,
- 52, 50, 40, 23, 5, -8, -13, -18, -23, -28, -26, -19, -12, -6, -4, -2,
- 2, 6, 11, 11, 5, 3, 4, 1, -9, -17, -21, -23, -22, -19, -14, 0,
- 17, 37, 54, 65, 70, 75, 76, 67, 50, 30, 6, -15, -35, -56, -75, -88,
- -93, -88, -78, -64, -47, -26, -3, 17, 31, 37, 42, 46, 48, 42, 27, 10,
- 0, -3, -7, -14, -21, -21, -13, -4, 1, -2, -3, 1, 5, 7, 4, -3,
- -8, -7, -7, -14, -19, -22, -23, -21, -20, -16, -6, 12, 32, 51, 63, 70,
- 76, 78, 75, 63, 44, 20, -5, -26, -46, -67, -83, -94, -93, -83, -69, -55,
- -40, -17, 8, 25, 34, 38, 43, 48, 45, 35, 20, 8, 2, 3, -2, -12,
- -18, -15, -8, 0, 0, -5, -6, -4, -3, -5, -11, -15, -14, -12, -13, -16,
- -19, -20, -20, -16, -10, -2, 11, 24, 42, 57, 64, 70, 73, 72, 64, 48,
- 26, 4, -15, -35, -50, -68, -81, -88, -81, -68, -55, -44, -29, -10, 9, 22,
- 25, 30, 37, 38, 35, 24, 14, 11, 13, 14, 9, 0, -5, -3, 3, 4,
- -2, -10, -15, -15, -15, -19, -25, -24, -20, -18, -19, -20, -18, -16, -13, -9,
- 1, 12, 25, 37, 53, 63, 69, 74, 73, 69, 56, 37, 15, -6, -25, -42,
- -59, -75, -82, -81, -72, -61, -50, -35, -17, -2, 13, 20, 27, 31, 34, 34,
- 28, 19, 14, 13, 15, 14, 8, 4, 3, 5, 5, 1, -6, -15, -18, -22,
- -27, -33, -34, -31, -25, -24, -20, -19, -17, -10, -2, 9, 18, 28, 39, 51,
- 60, 67, 71, 72, 67, 53, 35, 16, -4, -21, -40, -57, -70, -76, -74, -65,
- -55, -44, -34, -21, -7, 6, 15, 18, 20, 24, 24, 21, 16, 15, 16, 17,
- 17, 16, 13, 12, 13, 13, 9, 0, -12, -17, -22, -31, -40, -43, -40, -35,
- -30, -26, -24, -20, -11, -2, 9, 19, 29, 39, 46, 54, 60, 66, 67, 66,
- 58, 41, 21, 5, -11, -29, -47, -62, -68, -68, -65, -57, -49, -39, -27, -13,
- -2, 6, 11, 18, 23, 24, 21, 19, 19, 21, 21, 18, 15, 11, 13, 15,
- 15, 10, -2, -8, -14, -21, -30, -39, -44, -44, -40, -33, -29, -27, -21, -12,
- -3, 6, 16, 28, 40, 48, 54, 56, 59, 61, 62, 57, 44, 28, 12, -3,
- -22, -40, -55, -64, -63, -61, -56, -51, -41, -29, -15, -6, 1, 8, 15, 20,
- 20, 18, 17, 18, 23, 23, 20, 17, 15, 18, 20, 20, 15, 4, -5, -11,
- -20, -32, -43, -49, -48, -43, -36, -32, -29, -21, -13, 0, 11, 20, 30, 38,
- 46, 50, 51, 53, 56, 53, 48, 41, 30, 19, 5, -10, -26, -42, -50, -56,
- -57, -56, -53, -46, -38, -27, -18, -10, -2, 8, 16, 19, 24, 24, 22, 23,
- 25, 23, 17, 16, 15, 16, 14, 10, 3, -5, -11, -20, -28, -35, -42, -44,
- -42, -35, -29, -25, -19, -11, 0, 10, 20, 26, 31, 38, 45, 48, 46, 46,
- 44, 41, 37, 30, 22, 13, 1, -15, -27, -36, -44, -49, -51, -52, -49, -44,
- -37, -27, -20, -12, 1, 10, 19, 23, 28, 29, 28, 28, 24, 19, 17, 16,
- 15, 14, 10, 4, -3, -10, -15, -23, -31, -36, -41, -41, -39, -32, -24, -19,
- -11, -3, 5, 15, 24, 31, 36, 42, 45, 44, 41, 37, 33, 31, 29, 23,
- 14, 2, -8, -16, -22, -31, -40, -44, -46, -46, -46, -44, -37, -28, -20, -10,
- 2, 11, 20, 28, 32, 32, 29, 26, 22, 19, 17, 14, 12, 11, 8, 2,
- -5, -14, -20, -24, -30, -34, -37, -38, -36, -30, -21, -14, -6, 2, 11, 19,
- 26, 30, 34, 41, 44, 42, 38, 32, 27, 25, 24, 21, 11, 1, -9, -16,
- -25, -34, -40, -43, -45, -48, -50, -49, -40, -27, -15, -6, 4, 15, 27, 36,
- 40, 37, 32, 27, 22, 15, 11, 10, 8, 6, 0, -8, -14, -16, -17, -18,
- -24, -31, -33, -33, -27, -22, -17, -10, -4, 6, 13, 17, 22, 27, 33, 38,
- 39, 37, 35, 33, 31, 27, 23, 19, 11, 3, -7, -20, -30, -38, -42, -42,
- -46, -53, -58, -53, -41, -27, -13, -2, 10, 19, 30, 39, 43, 38, 29, 23,
- 18, 12, 8, 6, 6, 4, -3, -8, -12, -13, -10, -12, -17, -24, -25, -23,
- -23, -23, -19, -12, -4, 2, 5, 9, 14, 22, 32, 37, 39, 39, 37, 37,
- 33, 28, 27, 21, 12, 0, -14, -25, -33, -38, -43, -48, -54, -60, -59, -48,
- -36, -20, -8, 2, 12, 26, 39, 44, 40, 32, 27, 23, 16, 8, 3, 3,
- 2, 1, -4, -9, -9, -6, -6, -8, -13, -16, -18, -21, -22, -21, -16, -7,
- -2, 0, -2, 2, 13, 25, 30, 34, 34, 34, 34, 33, 33, 31, 26, 21,
- 11, -3, -15, -25, -31, -37, -48, -57, -62, -63, -56, -46, -35, -25, -12, 5,
- 18, 32, 40, 40, 36, 32, 29, 22, 15, 7, 3, 0, 0, 0, 1, -2,
- -2, 0, 0, -3, -4, -7, -13, -22, -28, -25, -17, -10, -10, -11, -10, -4,
- 12, 26, 36, 39, 40, 41, 40, 37, 35, 33, 28, 19, 3, -11, -22, -30,
- -37, -46, -56, -63, -65, -59, -52, -43, -29, -17, -4, 10, 23, 32, 36, 36,
- 34, 29, 24, 19, 12, 5, -2, 0, 4, 7, 10, 9, 6, 5, 5, 5,
- 0, -10, -20, -26, -29, -26, -20, -18, -19, -17, -9, 3, 16, 28, 36, 40,
- 42, 43, 41, 40, 36, 33, 26, 16, 3, -10, -21, -31, -42, -53, -61, -65,
- -63, -58, -52, -41, -31, -18, -4, 9, 21, 26, 29, 30, 31, 31, 28, 21,
- 12, 6, 5, 10, 13, 13, 14, 9, 8, 7, 5, 0, -8, -17, -24, -28,
- -27, -23, -17, -14, -12, -8, 2, 15, 26, 32, 36, 39, 38, 37, 36, 33,
- 28, 21, 16, 10, 1, -13, -25, -34, -41, -50, -59, -62, -62, -53, -44, -37,
- -28, -19, -6, 7, 14, 18, 22, 26, 28, 28, 21, 13, 6, 6, 15, 19,
- 21, 20, 20, 18, 16, 13, 7, -3, -12, -21, -27, -31, -30, -24, -15, -11,
- -8, 0, 10, 23, 29, 32, 34, 34, 34, 33, 32, 27, 23, 20, 17, 10,
- -2, -15, -25, -34, -43, -52, -61, -63, -58, -49, -43, -41, -33, -22, -9, 3,
- 11, 17, 21, 26, 30, 28, 23, 17, 15, 18, 22, 22, 20, 21, 21, 18,
- 12, 4, -5, -11, -16, -22, -28, -32, -24, -14, -7, -5, 1, 11, 20, 27,
- 30, 26, 25, 29, 30, 29, 22, 17, 18, 22, 20, 9, -8, -18, -25, -31,
- -40, -53, -60, -58, -54, -46, -45, -42, -32, -20, -10, -2, 5, 12, 19, 25,
- 27, 22, 18, 18, 21, 24, 25, 22, 24, 26, 27, 22, 10, 0, -7, -9,
- -12, -21, -28, -28, -20, -9, -4, -2, 5, 14, 22, 24, 21, 15, 18, 24,
- 28, 24, 19, 21, 26, 30, 22, 7, -6, -15, -23, -34, -50, -61, -66, -61,
- -52, -50, -49, -45, -36, -22, -10, 1, 11, 15, 20, 26, 26, 24, 21, 21,
- 27, 28, 24, 21, 22, 26, 24, 16, 5, -5, -7, -5, -11, -17, -22, -17,
- -7, 0, 1, 4, 9, 16, 19, 18, 13, 12, 16, 22, 24, 23, 23, 28,
- 33, 27, 16, 2, -12, -23, -33, -45, -57, -64, -64, -55, -51, -52, -49, -39,
- -25, -13, -6, 1, 6, 12, 16, 18, 20, 18, 20, 25, 28, 28, 29, 31,
- 36, 37, 28, 15, 7, 3, 0, -4, -14, -21, -23, -16, -7, -4, -3, 1,
- 10, 16, 17, 10, 7, 9, 18, 24, 24, 24, 28, 34, 34, 26, 12, -3,
- -15, -26, -40, -53, -61, -65, -62, -59, -57, -55, -49, -39, -27, -18, -6, 3,
- 8, 14, 17, 21, 25, 26, 27, 28, 30, 32, 32, 31, 32, 28, 22, 14,
- 6, 3, 0, -3, -8, -12, -12, -5, 0, 2, 1, 3, 6, 11, 11, 7,
- 4, 6, 13, 20, 24, 28, 31, 32, 28, 19, 7, -7, -20, -32, -44, -53,
- -58, -58, -55, -54, -53, -50, -46, -40, -27, -14, -6, -6, -5, 0, 8, 16,
- 20, 23, 25, 30, 37, 42, 43, 41, 39, 34, 28, 18, 9, 4, 3, 0,
- -10, -13, -12, -10, -5, 1, 1, 0, 4, 8, 7, 5, 6, 11, 19, 23,
- 27, 32, 33, 27, 20, 10, 0, -15, -30, -41, -49, -52, -54, -55, -55, -53,
- -50, -45, -40, -32, -24, -16, -11, -10, -8, -3, 6, 13, 17, 21, 29, 37,
- 43, 48, 47, 43, 38, 35, 30, 19, 11, 7, 2, -5, -9, -9, -5, 1,
- 1, 0, -2, 1, 3, 6, 5, 4, 5, 10, 16, 20, 24, 27, 25, 18,
- 10, 3, -9, -21, -31, -39, -44, -47, -47, -44, -46, -48, -48, -45, -39, -36,
- -30, -26, -25, -23, -19, -9, 4, 14, 24, 32, 41, 48, 54, 56, 57, 52,
- 47, 40, 28, 17, 10, 4, -3, -8, -10, -8, -6, -5, -5, -5, -3, 0,
- 3, 4, 4, 5, 7, 12, 19, 26, 27, 24, 18, 12, 5, -3, -12, -24,
- -34, -43, -46, -48, -48, -46, -46, -45, -44, -42, -38, -33, -29, -26, -26, -22,
- -14, -5, 5, 13, 23, 32, 40, 47, 52, 56, 57, 55, 52, 47, 36, 27,
- 19, 11, 3, -5, -6, -8, -10, -13, -15, -14, -13, -11, -6, 1, 4, 7,
- 11, 17, 21, 26, 28, 26, 19, 10, 2, -7, -17, -26, -36, -41, -45, -47,
- -45, -44, -44, -41, -39, -40, -40, -37, -33, -34, -32, -26, -18, -9, 2, 12,
- 26, 40, 47, 56, 63, 66, 66, 63, 60, 53, 40, 27, 14, 3, -8, -11,
- -12, -15, -19, -19, -18, -15, -12, -8, 0, 6, 11, 13, 14, 17, 23, 29,
- 27, 18, 9, 1, -7, -16, -25, -35, -43, -49, -47, -44, -43, -42, -40, -36,
- -34, -33, -33, -33, -35, -34, -30, -23, -16, -9, 2, 14, 27, 39, 49, 58,
- 66, 69, 68, 66, 61, 53, 45, 32, 18, 1, -11, -14, -17, -17, -20, -23,
- -21, -17, -13, -3, 4, 10, 13, 14, 17, 18, 21, 24, 22, 15, 6, -4,
- -12, -22, -28, -38, -49, -51, -48, -45, -43, -40, -38, -36, -35, -34, -33, -33,
- -34, -35, -33, -29, -18, -6, 6, 19, 33, 46, 59, 71, 78, 78, 78, 74,
- 67, 54, 39, 22, 6, -8, -16, -22, -25, -25, -26, -22, -17, -12, -3, 6,
- 15, 17, 16, 14, 14, 16, 17, 16, 13, 6, -2, -11, -20, -27, -34, -43,
- -49, -48, -44, -41, -39, -36, -33, -34, -33, -34, -32, -33, -35, -35, -30, -21,
- -11, 0, 9, 23, 38, 52, 65, 74, 76, 76, 74, 70, 62, 47, 28, 13,
- 2, -6, -14, -21, -23, -20, -18, -16, -13, -7, 1, 8, 10, 11, 9, 11,
- 11, 13, 15, 16, 13, 8, -2, -11, -19, -27, -37, -47, -52, -51, -48, -46,
- -43, -40, -38, -36, -35, -35, -38, -38, -33, -27, -21, -16, -7, 6, 21, 36,
- 49, 61, 70, 75, 79, 78, 73, 62, 49, 35, 22, 8, -3, -12, -17, -20,
- -18, -14, -13, -15, -12, -5, 4, 7, 8, 8, 9, 8, 9, 11, 14, 14,
- 10, 4, -6, -15, -25, -35, -41, -48, -54, -53, -47, -42, -38, -37, -35, -31,
- -31, -30, -30, -29, -26, -24, -19, -12, -2, 10, 22, 35, 48, 60, 70, 76,
- 76, 73, 67, 57, 44, 28, 14, 5, -3, -8, -13, -14, -13, -10, -11, -11,
- -8, -2, 4, 6, 5, 5, 5, 6, 10, 11, 10, 8, 4, -2, -9, -15,
- -24, -35, -44, -50, -52, -49, -45, -42, -42, -40, -37, -37, -37, -33, -29, -26,
- -24, -21, -16, -7, 6, 18, 30, 41, 54, 66, 75, 77, 79, 76, 67, 53,
- 37, 21, 8, 2, -5, -10, -14, -14, -12, -12, -11, -10, -5, 4, 7, 4,
- 1, 2, 6, 9, 9, 7, 5, 4, 0, -7, -14, -23, -32, -37, -43, -48,
- -50, -51, -47, -42, -34, -32, -32, -34, -32, -26, -21, -18, -17, -14, -11, -4,
- 5, 13, 24, 40, 55, 67, 72, 74, 76, 75, 67, 51, 37, 23, 11, 4,
- -4, -11, -15, -17, -17, -16, -14, -13, -8, -2, 1, 1, 1, 3, 5, 9,
- 7, 5, 4, 4, 3, -5, -14, -24, -32, -38, -41, -47, -52, -53, -49, -41,
- -35, -34, -35, -33, -29, -24, -19, -13, -10, -9, -7, -2, 8, 17, 29, 43,
- 56, 67, 74, 75, 75, 72, 64, 53, 38, 23, 13, 4, -5, -12, -16, -20,
- -21, -18, -16, -14, -11, -8, -5, -3, 0, 2, 6, 6, 6, 5, 5, 6,
- 3, -6, -19, -31, -37, -41, -45, -50, -52, -53, -48, -39, -32, -30, -26, -25,
- -22, -16, -10, -7, -11, -10, -8, -2, 6, 17, 31, 45, 58, 68, 78, 80,
- 76, 70, 65, 55, 37, 18, 5, -4, -10, -19, -25, -26, -24, -18, -13, -11,
- -9, -6, -2, 4, 6, 5, 4, 3, 4, 2, 1, -3, -4, -11, -20, -29,
- -38, -43, -45, -48, -51, -48, -44, -39, -35, -34, -31, -30, -25, -15, -8, -8,
- -10, -8, 1, 11, 22, 33, 42, 54, 66, 76, 80, 75, 70, 66, 59, 42,
- 23, 6, -4, -9, -17, -22, -27, -25, -19, -9, -7, -8, -5, 0, 4, 5,
- 2, -2, -5, -5, -4, -6, -7, -6, -10, -16, -21, -29, -34, -37, -38, -41,
- -44, -42, -36, -32, -33, -37, -39, -35, -27, -17, -12, -13, -12, -6, 6, 22,
- 36, 44, 54, 66, 77, 82, 80, 75, 68, 59, 47, 29, 10, -3, -13, -18,
- -23, -26, -27, -24, -16, -9, -5, -4, -2, 3, 6, 4, -2, -6, -8, -7,
- -8, -8, -9, -10, -13, -16, -22, -29, -31, -30, -34, -36, -36, -32, -28, -30,
- -36, -39, -38, -33, -28, -24, -24, -22, -15, -2, 13, 26, 38, 53, 67, 78,
- 84, 88, 85, 81, 71, 59, 39, 13, -5, -14, -19, -26, -32, -34, -30, -22,
- -13, -5, 0, 6, 7, 10, 8, 2, -4, -10, -12, -15, -18, -20, -20, -20,
- -22, -24, -26, -26, -23, -23, -23, -24, -21, -17, -18, -25, -31, -35, -37, -37,
- -36, -33, -29, -22, -10, 5, 19, 31, 45, 62, 75, 84, 86, 88, 87, 80,
- 66, 45, 22, 4, -9, -18, -26, -34, -37, -33, -24, -15, -9, -3, 6, 13,
- 15, 11, 2, -5, -10, -13, -20, -25, -27, -26, -25, -26, -29, -29, -23, -18,
- -16, -19, -18, -15, -9, -6, -12, -21, -32, -36, -36, -40, -39, -36, -30, -21,
- -10, 6, 20, 36, 55, 69, 79, 85, 90, 92, 88, 75, 56, 33, 12, -3,
- -15, -24, -33, -37, -35, -28, -20, -12, -4, 6, 14, 18, 16, 9, 0, -8,
- -15, -19, -27, -33, -35, -34, -34, -36, -36, -29, -19, -10, -10, -10, -8, -4,
- -2, -2, -8, -18, -28, -36, -43, -48, -46, -36, -25, -14, -4, 10, 27, 46,
- 65, 78, 86, 89, 87, 85, 78, 64, 42, 19, 0, -12, -20, -29, -34, -36,
- -30, -22, -12, -6, 1, 8, 16, 18, 13, 2, -7, -12, -17, -24, -33, -38,
- -39, -36, -36, -36, -34, -26, -18, -11, -7, -6, -5, -5, 1, 1, -5, -14,
- -24, -33, -41, -42, -37, -28, -19, -10, 3, 16, 30, 47, 64, 76, 83, 85,
- 83, 78, 69, 54, 37, 17, -2, -14, -21, -28, -32, -32, -27, -18, -11, -6,
- 2, 12, 18, 16, 5, -5, -11, -14, -19, -30, -40, -47, -45, -38, -36, -34,
- -33, -26, -15, -6, -2, 1, 1, 3, 5, 4, -3, -13, -26, -35, -41, -39,
- -33, -23, -13, -5, 7, 21, 36, 53, 68, 79, 82, 78, 72, 66, 59, 47,
- 30, 10, -6, -16, -21, -22, -25, -27, -25, -18, -10, -4, 4, 10, 11, 6,
- -4, -11, -13, -18, -25, -34, -43, -45, -41, -36, -34, -32, -27, -19, -10, -5,
- 0, 2, 5, 5, 5, 1, -7, -16, -25, -33, -38, -35, -25, -13, -6, 0,
- 11, 27, 46, 60, 69, 70, 68, 69, 68, 62, 52, 39, 22, 8, -2, -11,
- -18, -21, -22, -23, -24, -17, -10, -5, 1, 5, 5, 2, -3, -5, -9, -17,
- -28, -41, -46, -48, -43, -42, -42, -39, -30, -19, -9, -3, 6, 11, 15, 16,
- 12, 5, -2, -12, -23, -33, -37, -34, -25, -18, -8, 1, 15, 32, 48, 62,
- 69, 68, 67, 63, 62, 58, 50, 34, 15, -2, -8, -10, -11, -16, -24, -24,
- -19, -12, -6, -2, 2, 3, 1, 0, -6, -10, -17, -26, -37, -46, -48, -45,
- -44, -42, -38, -32, -22, -12, -6, 4, 10, 14, 16, 15, 11, 5, -2, -11,
- -23, -31, -29, -22, -18, -16, -11, 3, 17, 34, 50, 56, 59, 61, 63, 62,
- 59, 53, 44, 32, 16, 3, -8, -9, -13, -20, -26, -27, -21, -16, -11, -9,
- -6, 1, 7, 7, 0, -10, -15, -20, -30, -39, -45, -48, -48, -46, -41, -36,
- -29, -20, -11, 3, 11, 14, 19, 21, 19, 15, 6, -3, -13, -18, -18, -17,
- -20, -19, -12, 2, 15, 26, 36, 43, 51, 59, 61, 61, 57, 54, 49, 37,
- 21, 9, 1, -8, -17, -25, -29, -28, -27, -23, -19, -13, -5, 2, 8, 5,
- -4, -11, -13, -17, -27, -40, -49, -53, -53, -50, -44, -37, -28, -19, -7, 8,
- 18, 22, 26, 26, 23, 17, 10, 0, -8, -15, -20, -25, -23, -19, -11, 0,
- 13, 25, 34, 44, 54, 60, 62, 60, 58, 56, 52, 38, 21, 6, -6, -16,
- -26, -32, -33, -30, -26, -24, -17, -8, 3, 13, 16, 10, 1, -7, -12, -18,
- -34, -50, -61, -63, -58, -54, -50, -45, -33, -13, 6, 21, 27, 34, 37, 36,
- 30, 20, 11, -2, -13, -24, -32, -37, -34, -24, -10, 2, 12, 25, 41, 55,
- 61, 64, 65, 67, 64, 59, 48, 32, 16, 0, -12, -20, -27, -33, -33, -31,
- -28, -23, -12, 0, 10, 13, 9, 2, -2, -7, -13, -25, -41, -56, -65, -66,
- -62, -56, -53, -42, -25, -5, 13, 24, 34, 39, 42, 39, 32, 22, 11, -2,
- -15, -27, -36, -37, -31, -22, -13, 0, 12, 27, 43, 55, 61, 64, 65, 63,
- 60, 53, 42, 28, 10, -6, -20, -27, -28, -28, -25, -23, -20, -13, -2, 11,
- 16, 14, 8, 2, -6, -14, -25, -38, -53, -67, -73, -73, -67, -58, -46, -32,
- -14, 6, 24, 36, 43, 45, 44, 39, 30, 18, 5, -11, -25, -35, -39, -37,
- -28, -17, -7, 4, 16, 32, 48, 58, 64, 66, 63, 61, 56, 46, 31, 18,
- 3, -13, -21, -25, -23, -19, -15, -11, -7, -2, 6, 13, 14, 8, -3, -12,
- -21, -32, -40, -55, -70, -78, -75, -67, -56, -47, -29, -12, 10, 29, 40, 47,
- 49, 48, 43, 31, 15, 0, -16, -29, -39, -45, -41, -32, -18, -6, 3, 13,
- 27, 43, 57, 64, 65, 61, 58, 52, 43, 32, 18, 6, -9, -18, -20, -17,
- -12, -4, 1, 3, 7, 12, 17, 16, 9, -3, -15, -27, -39, -48, -60, -72,
- -82, -82, -73, -58, -45, -33, -14, 7, 28, 42, 49, 51, 51, 48, 38, 22,
- 2, -16, -30, -37, -42, -45, -40, -26, -11, 3, 11, 20, 34, 52, 65, 69,
- 64, 54, 46, 38, 28, 16, 4, -11, -18, -16, -10, -4, 3, 13, 21, 23,
- 22, 20, 18, 11, -2, -16, -34, -47, -59, -70, -76, -83, -83, -76, -64, -48,
- -31, -12, 10, 30, 42, 50, 53, 51, 46, 37, 25, 8, -13, -30, -41, -45,
- -43, -35, -23, -15, -5, 8, 17, 28, 40, 56, 64, 63, 55, 45, 34, 24,
- 14, 7, -4, -12, -13, -9, -2, 11, 23, 31, 33, 33, 31, 26, 17, 4,
- -14, -31, -48, -62, -75, -86, -90, -87, -79, -68, -54, -39, -18, 4, 23, 39,
- 47, 52, 52, 47, 39, 29, 15, -5, -23, -35, -41, -40, -34, -26, -16, -8,
- 2, 12, 22, 30, 43, 52, 58, 54, 45, 36, 25, 16, 7, -2, -7, -8,
- -3, 4, 13, 24, 32, 39, 42, 39, 30, 19, 6, -10, -25, -44, -62, -79,
- -88, -90, -85, -78, -70, -59, -45, -24, 0, 20, 35, 43, 48, 48, 46, 42,
- 33, 20, 2, -19, -32, -38, -41, -37, -29, -19, -8, 1, 11, 19, 26, 35,
- 43, 48, 48, 41, 35, 26, 16, 7, 0, 0, 3, 6, 10, 16, 24, 32,
- 40, 44, 43, 33, 21, 8, -5, -19, -37, -54, -72, -84, -87, -81, -75, -68,
- -61, -50, -33, -12, 8, 22, 29, 34, 40, 42, 41, 35, 24, 13, -2, -16,
- -27, -33, -33, -27, -22, -17, -13, -4, 9, 18, 25, 31, 36, 42, 44, 40,
- 32, 21, 12, 9, 7, 8, 9, 13, 17, 23, 29, 35, 40, 40, 35, 26,
- 13, 0, -11, -24, -41, -60, -74, -80, -79, -73, -68, -63, -56, -43, -27, -10,
- 6, 18, 24, 29, 34, 38, 37, 30, 20, 9, -3, -14, -24, -27, -27, -25,
- -23, -18, -9, 2, 10, 19, 25, 30, 37, 40, 41, 33, 22, 16, 10, 6,
- 6, 10, 16, 21, 28, 31, 35, 38, 44, 45, 34, 19, 5, -5, -17, -33,
- -52, -68, -76, -78, -75, -71, -67, -62, -51, -37, -20, -7, 4, 13, 21, 29,
- 34, 36, 33, 26, 17, 10, 0, -8, -13, -19, -21, -21, -17, -11, -6, 4,
- 10, 13, 19, 25, 30, 31, 28, 20, 14, 10, 7, 7, 11, 20, 26, 32,
- 36, 39, 41, 44, 46, 41, 30, 13, 0, -13, -27, -44, -62, -72, -74, -74,
- -74, -71, -66, -57, -47, -32, -19, -9, 2, 14, 24, 28, 32, 34, 33, 25,
- 17, 9, 2, -5, -10, -17, -22, -18, -13, -7, 0, 4, 10, 17, 23, 26,
- 25, 21, 15, 9, 9, 7, 4, 7, 16, 27, 34, 39, 43, 48, 49, 52,
- 49, 39, 24, 9, -3, -17, -32, -52, -67, -75, -75, -71, -70, -70, -66, -56,
- -43, -31, -21, -12, -2, 11, 21, 27, 30, 33, 31, 29, 22, 15, 8, 0,
- -6, -13, -14, -14, -11, -5, 0, 4, 8, 13, 16, 18, 15, 12, 10, 7,
- 7, 6, 7, 14, 24, 36, 44, 46, 46, 49, 52, 53, 47, 35, 21, 9,
- -6, -23, -43, -59, -68, -71, -74, -74, -76, -73, -64, -52, -39, -31, -25, -15,
- 0, 12, 20, 24, 29, 32, 30, 26, 21, 16, 10, 4, -2, -7, -7, -5,
- -3, 0, 3, 5, 6, 9, 8, 8, 6, 3, 2, 4, 5, 7, 14, 22,
- 34, 43, 49, 57, 57, 55, 52, 48, 43, 31, 17, 2, -13, -33, -49, -59,
- -63, -66, -72, -75, -76, -70, -61, -52, -44, -37, -30, -18, -4, 11, 20, 25,
- 28, 32, 32, 30, 26, 19, 13, 5, 0, -4, -5, -3, 1, 2, 1, -3,
- -2, 2, 6, 4, 2, -3, -2, 3, 10, 13, 18, 27, 40, 49, 56, 59,
- 60, 56, 52, 47, 41, 30, 17, 1, -19, -39, -55, -64, -67, -70, -76, -81,
- -78, -69, -56, -46, -40, -33, -24, -12, 3, 15, 22, 25, 26, 29, 27, 23,
- 19, 14, 9, 4, 0, -2, 1, 5, 9, 7, 2, -3, -3, 3, 3, -2,
- -10, -13, -10, -2, 7, 14, 22, 31, 45, 59, 65, 68, 65, 62, 58, 50,
- 41, 28, 12, -9, -31, -49, -59, -65, -70, -76, -84, -84, -77, -63, -50, -45,
- -40, -32, -21, -7, 7, 16, 24, 28, 29, 28, 23, 18, 15, 11, 6, 0,
- -4, -3, 4, 11, 14, 11, 6, 5, 7, 7, 2, -7, -12, -16, -13, -6,
- 1, 8, 17, 32, 50, 63, 68, 68, 69, 70, 65, 56, 43, 27, 7, -17,
- -38, -52, -62, -71, -78, -86, -88, -84, -73, -59, -50, -43, -34, -25, -11, 2,
- 11, 19, 23, 26, 26, 21, 17, 12, 9, 7, 5, 2, 2, 4, 11, 16,
- 14, 10, 9, 10, 9, 1, -8, -16, -19, -16, -11, -6, 0, 8, 24, 43,
- 57, 66, 70, 72, 72, 67, 63, 52, 37, 18, -5, -23, -41, -54, -62, -70,
- -78, -81, -82, -76, -67, -56, -45, -36, -31, -22, -12, 0, 10, 16, 20, 21,
- 17, 13, 7, 3, 3, 6, 6, 6, 9, 14, 20, 21, 20, 17, 17, 15,
- 9, -3, -15, -23, -27, -20, -14, -9, -4, 9, 31, 49, 64, 70, 75, 78,
- 76, 70, 60, 45, 31, 12, -11, -31, -46, -58, -66, -70, -73, -77, -74, -67,
- -59, -52, -44, -36, -29, -22, -14, -6, 1, 11, 14, 14, 11, 6, 6, 7,
- 10, 11, 12, 15, 18, 24, 23, 21, 19, 20, 18, 12, 0, -13, -20, -27,
- -27, -22, -16, -11, 1, 19, 36, 52, 64, 73, 79, 81, 77, 69, 56, 43,
- 26, 5, -16, -37, -54, -62, -66, -69, -72, -71, -65, -62, -56, -47, -39, -33,
- -26, -19, -14, -12, -3, 9, 9, 3, -6, -4, 5, 11, 12, 11, 12, 20,
- 29, 31, 29, 25, 25, 27, 24, 11, -6, -17, -25, -31, -32, -30, -26, -16,
- 0, 17, 35, 51, 66, 78, 87, 88, 84, 73, 57, 40, 23, 3, -20, -42,
- -57, -65, -69, -71, -70, -68, -63, -58, -52, -45, -38, -30, -26, -24, -23, -16,
- -8, -2, -5, -9, -6, 1, 9, 12, 13, 17, 24, 32, 37, 37, 34, 32,
- 33, 31, 19, 2, -15, -25, -31, -36, -38, -35, -27, -13, 4, 23, 40, 59,
- 76, 91, 96, 91, 80, 69, 55, 35, 13, -12, -35, -52, -61, -66, -71, -70,
- -63, -54, -48, -44, -42, -36, -31, -30, -34, -36, -33, -26, -20, -20, -21, -18,
- -9, 5, 13, 18, 21, 29, 40, 47, 50, 49, 44, 40, 34, 23, 6, -14,
- -27, -39, -45, -48, -45, -35, -23, -7, 11, 30, 51, 73, 89, 97, 96, 89,
- 80, 63, 44, 25, 4, -18, -39, -53, -59, -63, -61, -58, -55, -52, -49, -45,
- -39, -35, -37, -41, -46, -43, -38, -33, -29, -25, -18, -11, 3, 13, 20, 25,
- 30, 38, 46, 51, 50, 47, 43, 37, 26, 9, -7, -19, -32, -45, -52, -51,
- -40, -28, -12, 4, 19, 38, 61, 83, 94, 95, 89, 82, 67, 50, 30, 12,
- -8, -26, -40, -52, -57, -56, -52, -48, -46, -44, -40, -34, -32, -32, -37, -44,
- -47, -45, -41, -39, -35, -28, -17, -6, 7, 15, 23, 32, 40, 47, 52, 52,
- 51, 46, 39, 32, 17, 1, -14, -26, -37, -46, -50, -45, -35, -25, -11, 5,
- 24, 44, 62, 79, 88, 86, 79, 70, 59, 45, 25, 7, -13, -25, -36, -46,
- -50, -51, -50, -46, -43, -41, -37, -34, -33, -36, -40, -43, -46, -46, -41, -36,
- -31, -22, -10, 4, 13, 21, 30, 40, 47, 50, 53, 52, 47, 39, 30, 18,
- 3, -12, -22, -33, -42, -47, -45, -36, -25, -14, -2, 14, 34, 52, 67, 76,
- 77, 72, 65, 55, 43, 27, 12, -7, -21, -29, -36, -41, -44, -43, -39, -36,
- -32, -27, -26, -26, -29, -33, -36, -43, -49, -48, -44, -38, -32, -22, -11, 4,
- 15, 25, 34, 44, 50, 53, 54, 52, 44, 35, 23, 9, -4, -15, -27, -37,
- -43, -45, -42, -34, -21, -9, 5, 19, 34, 50, 63, 70, 69, 63, 54, 46,
- 35, 20, 4, -11, -23, -29, -33, -37, -41, -40, -33, -25, -20, -19, -21, -22,
- -23, -26, -34, -42, -47, -46, -43, -36, -30, -22, -11, 5, 17, 28, 37, 45,
- 52, 55, 53, 49, 41, 30, 19, 4, -12, -23, -33, -41, -45, -45, -40, -31,
- -18, -3, 11, 23, 38, 51, 63, 64, 58, 51, 45, 36, 25, 10, -4, -15,
- -24, -28, -32, -36, -35, -29, -19, -13, -13, -14, -13, -13, -13, -21, -33, -43,
- -45, -45, -41, -38, -34, -25, -11, 4, 17, 29, 39, 49, 57, 60, 55, 48,
- 39, 29, 16, 1, -14, -27, -35, -42, -47, -48, -42, -29, -15, -3, 10, 20,
- 34, 48, 56, 57, 51, 45, 38, 30, 20, 7, -7, -17, -22, -26, -32, -36,
- -31, -21, -9, -6, -8, -8, -4, 1, -4, -13, -26, -35, -39, -40, -42, -44,
- -40, -29, -13, 3, 16, 29, 43, 58, 67, 67, 59, 49, 39, 27, 11, -9,
- -28, -39, -47, -50, -53, -52, -44, -29, -12, 5, 13, 25, 38, 51, 57, 52,
- 45, 38, 30, 21, 9, -4, -14, -21, -26, -29, -33, -28, -18, -7, 2, 2,
- 2, 4, 8, 10, 5, -10, -25, -36, -42, -45, -49, -49, -45, -33, -14, 5,
- 22, 35, 54, 69, 78, 76, 67, 53, 41, 27, 6, -17, -36, -50, -55, -60,
- -63, -62, -51, -34, -16, -2, 9, 20, 34, 45, 50, 48, 42, 35, 29, 18,
- 7, 0, 0, 0, 0, 0, 0, 7, 0, -1, -7, -18, -16, 3, 6, -18,
- -29, -21, 6, 6, -12, -10, -10, -2, 4, 15, 21, 14, 4, 9, 29, 27,
- 15, 9, 13, 20, 0, -21, -11, 3, -11, -37, -36, -7, 11, -4, -26, -23,
- -4, 15, -4, -15, -11, -10, -1, 9, 23, 15, 8, 6, 24, 35, 19, 14,
- 6, 17, 10, -15, -26, -7, -1, -23, -40, -24, 4, 10, -16, -25, -13, 11,
- 10, -14, -15, -12, -6, 1, 19, 22, 6, 7, 15, 40, 31, 22, 7, 7,
- 15, 5, -22, -21, -5, -9, -33, -32, -15, 5, -4, -19, -20, 1, 17, -4,
- -15, -11, -12, -4, 9, 27, 13, 7, 11, 32, 44, 30, 14, 2, 7, 9,
- -8, -25, -18, -9, -19, -30, -21, -4, 2, -10, -21, -13, 15, 8, -11, -13,
- -16, -12, 0, 20, 24, 9, 9, 19, 44, 47, 25, 6, 2, 11, -1, -21,
- -27, -19, -17, -20, -23, -17, -5, -5, -14, -20, 0, 15, -4, -7, -17, -17,
- -8, 7, 25, 18, 7, 11, 31, 54, 41, 14, -1, 10, 3, -14, -27, -29,
- -21, -16, -16, -18, -17, -11, -10, -16, -16, 10, 6, -3, -9, -19, -16, -2,
- 18, 27, 16, 8, 19, 45, 54, 29, 5, 6, 4, -9, -18, -29, -30, -18,
- -10, -9, -14, -20, -12, -13, -17, -5, 12, 7, 2, -16, -22, -13, 8, 25,
- 23, 12, 11, 32, 53, 48, 17, 9, 9, -7, -16, -24, -37, -28, -12, -4,
- -2, -18, -21, -18, -23, -17, 7, 11, 10, -4, -16, -22, -7, 21, 28, 18,
- 9, 20, 43, 55, 37, 11, 11, 1, -14, -17, -31, -34, -21, -10, 4, -2,
- -20, -23, -26, -29, -3, 6, 13, 8, -5, -23, -27, 7, 28, 27, 15, 12,
- 32, 48, 50, 24, 9, 8, -12, -19, -26, -37, -35, -19, 3, 6, -12, -21,
- -31, -38, -17, 6, 4, 14, 6, -8, -35, -15, 19, 26, 21, 7, 23, 43,
- 52, 42, 14, 9, -2, -16, -21, -25, -33, -33, -4, 13, 3, -13, -30, -47,
- -37, 1, 6, 7, 12, 6, -15, -31, -1, 22, 30, 14, 9, 37, 48, 50,
- 26, 8, 6, -11, -22, -22, -25, -45, -22, 13, 15, 1, -22, -43, -56, -21,
- 7, 6, 10, 15, -7, -25, -21, 7, 28, 21, 2, 25, 47, 53, 39, 11,
- 10, 1, -20, -22, -18, -37, -42, 2, 15, 15, -8, -32, -57, -48, -9, 9,
- 5, 14, 8, -14, -20, -13, 17, 33, 8, 9, 37, 52, 55, 25, 7, 8,
- -11, -23, -15, -23, -47, -20, 12, 21, 10, -23, -50, -57, -31, 2, 10, 9,
- 11, -8, -10, -18, -3, 30, 22, 1, 22, 45, 57, 45, 11, 11, 0, -23,
- -22, -16, -36, -36, -6, 15, 18, -3, -43, -56, -49, -21, 5, 11, 12, -2,
- -8, -9, -15, 12, 31, 9, 10, 34, 48, 60, 29, 16, 10, -17, -24, -21,
- -27, -31, -17, 5, 14, 12, -22, -50, -48, -41, -9, 7, 13, -1, -8, -2,
- -11, -5, 26, 19, 6, 21, 37, 55, 49, 25, 22, -5, -20, -24, -26, -29,
- -23, -9, 8, 13, -1, -41, -48, -47, -30, -3, 12, 7, -12, -2, 1, -8,
- 10, 20, 11, 16, 26, 40, 54, 42, 36, 7, -13, -18, -26, -29, -26, -14,
- -2, 7, 8, -18, -45, -48, -45, -19, 6, 11, -10, -8, 5, -7, 2, 12,
- 17, 15, 16, 23, 45, 55, 48, 27, -7, -12, -18, -30, -31, -17, -5, -3,
- 4, 5, -24, -40, -50, -38, -8, 8, 1, -13, 1, -1, 3, 8, 15, 18,
- 15, 15, 28, 52, 59, 47, 9, -9, -10, -25, -40, -29, -3, -5, -13, 1,
- 3, -26, -47, -53, -23, -2, 5, -11, -6, 4, 6, 10, 10, 19, 11, 13,
- 15, 42, 61, 61, 32, 3, -5, -12, -35, -43, -14, 1, -16, -13, 9, -1,
- -33, -57, -46, -19, -3, -1, -16, -2, 5, 15, 6, 17, 9, 5, 9, 26,
- 54, 65, 52, 21, 3, -6, -21, -48, -33, -4, -7, -22, -2, 18, -4, -47,
- -58, -33, -11, 2, -13, -15, 3, 16, 15, 9, 15, -1, 5, 14, 48, 66,
- 65, 37, 23, 2, -11, -42, -48, -20, -4, -23, -18, 18, 19, -17, -61, -52,
- -27, -2, -5, -24, -7, 9, 20, 14, 18, 2, -3, 7, 34, 63, 68, 50,
- 37, 19, -9, -25, -49, -38, -14, -14, -28, 6, 25, 9, -40, -62, -45, -17,
- 3, -21, -16, -3, 12, 18, 18, 10, -6, 0, 16, 56, 69, 63, 43, 38,
- 2, -20, -42, -44, -33, -14, -25, -10, 22, 18, -11, -55, -57, -37, -3, -10,
- -26, -10, 2, 17, 21, 20, -3, -2, 5, 39, 67, 73, 56, 47, 22, -17,
- -35, -43, -36, -28, -18, -20, 9, 22, 8, -33, -56, -53, -26, -2, -23, -24,
- -11, 4, 23, 30, 4, -3, 0, 27, 60, 71, 69, 58, 43, -6, -35, -43,
- -35, -36, -27, -18, -2, 19, 17, -9, -41, -51, -45, -10, -12, -31, -21, -9,
- 8, 33, 17, 0, 2, 8, 50, 69, 75, 70, 64, 16, -31, -47, -35, -32,
- -34, -25, -14, 10, 16, 5, -26, -42, -50, -32, -8, -22, -31, -22, -8, 22,
- 32, 7, 6, 4, 28, 63, 69, 71, 78, 43, -20, -51, -41, -23, -34, -30,
- -22, 2, 13, 9, -10, -31, -45, -44, -21, -19, -27, -36, -26, 2, 29, 24,
- 12, 11, 13, 45, 69, 68, 81, 70, 6, -47, -52, -28, -23, -27, -26, -14,
- 11, 10, -2, -18, -33, -43, -34, -25, -22, -36, -44, -14, 14, 29, 27, 22,
- 18, 29, 60, 65, 71, 86, 41, -32, -57, -41, -23, -22, -22, -24, -4, 10,
- 0, -11, -21, -31, -37, -37, -29, -29, -53, -33, -3, 16, 33, 31, 27, 23,
- 46, 64, 65, 85, 71, -4, -48, -47, -31, -20, -15, -15, -19, 1, 0, -5,
- -14, -21, -26, -40, -39, -28, -51, -50, -18, 4, 26, 38, 36, 30, 32, 61,
- 64, 70, 80, 31, -35, -43, -40, -25, -19, -6, -17, -11, 0, -6, -11, -17,
- -15, -31, -47, -39, -45, -62, -34, -8, 12, 36, 38, 41, 37, 51, 65, 60,
- 71, 56, -7, -36, -38, -35, -27, -11, -5, -17, -8, -8, -9, -17, -13, -20,
- -37, -47, -50, -62, -49, -16, 1, 25, 34, 43, 53, 49, 62, 58, 62, 65,
- 22, -23, -31, -34, -35, -19, -3, -8, -18, -7, -4, -14, -17, -9, -27, -40,
- -56, -68, -64, -27, -4, 9, 28, 37, 54, 60, 61, 59, 54, 63, 43, -1,
- -25, -23, -37, -28, -8, 4, -10, -15, -3, -7, -26, -15, -11, -29, -51, -71,
- -71, -49, -8, 5, 14, 30, 48, 66, 68, 63, 51, 56, 51, 18, -18, -20,
- -25, -39, -23, -5, 3, -13, -6, -5, -21, -28, -10, -18, -43, -67, -78, -64,
- -25, 1, 8, 15, 38, 60, 75, 74, 58, 54, 57, 28, -7, -18, -8, -31,
- -34, -15, 4, -2, -4, 0, -15, -32, -21, -8, -28, -57, -77, -75, -44, -12,
- 6, 8, 20, 49, 68, 77, 71, 53, 61, 41, 3, -18, -4, -14, -36, -28,
- -7, 1, 7, 6, -8, -34, -35, -16, -15, -41, -66, -75, -59, -31, -4, 10,
- 11, 31, 56, 72, 85, 63, 58, 55, 14, -17, -10, -1, -24, -30, -22, -6,
- 11, 16, 9, -27, -43, -27, -15, -26, -53, -63, -66, -46, -21, 3, 13, 15,
- 40, 63, 83, 78, 60, 67, 38, -9, -20, 4, -7, -23, -25, -22, 6, 24,
- 20, -8, -48, -43, -24, -16, -39, -55, -57, -57, -36, -10, 9, 11, 22, 50,
- 73, 88, 71, 65, 59, 14, -24, -9, -3, -15, -18, -31, -14, 25, 28, 10,
- -36, -56, -41, -21, -29, -48, -47, -51, -50, -26, -2, 11, 6, 30, 57, 82,
- 83, 69, 65, 35, -12, -16, -3, -10, -12, -21, -26, 11, 33, 26, -7, -56,
- -54, -32, -26, -41, -39, -37, -52, -41, -16, 5, 7, 11, 37, 72, 91, 78,
- 66, 55, 11, -19, -14, -15, -9, -7, -19, -8, 22, 30, 13, -32, -62, -44,
- -31, -34, -40, -29, -40, -46, -29, -8, 2, 1, 18, 49, 84, 86, 72, 67,
- 39, -6, -21, -25, -16, 2, -6, -12, 6, 23, 18, -7, -51, -56, -39, -33,
- -41, -30, -24, -41, -36, -17, -8, -5, 7, 32, 66, 84, 78, 75, 58, 20,
- -15, -29, -33, 2, 4, -1, 1, 11, 17, 4, -27, -56, -46, -36, -37, -39,
- -22, -24, -38, -23, -16, -16, -7, 18, 46, 72, 82, 81, 72, 44, -1, -25,
- -41, -18, 14, 8, 10, 0, 5, 2, -11, -40, -50, -42, -38, -37, -33, -11,
- -27, -26, -20, -22, -13, 0, 31, 52, 73, 82, 80, 61, 26, -16, -37, -40,
- 0, 18, 17, 12, -5, -8, -10, -21, -41, -43, -44, -36, -35, -20, -12, -23,
- -14, -32, -21, -12, 15, 38, 58, 76, 82, 72, 46, 4, -26, -41, -23, 14,
- 25, 18, 2, -23, -18, -14, -29, -35, -45, -42, -35, -29, -15, -19, -3, -23,
- -32, -19, -1, 27, 40, 67, 81, 76, 61, 26, -11, -33, -36, -6, 28, 28,
- 13, -15, -38, -19, -20, -26, -36, -46, -35, -32, -20, -21, -4, -4, -28, -25,
- -16, 13, 31, 49, 74, 79, 69, 48, 8, -16, -33, -21, 7, 33, 24, 5,
- -32, -38, -22, -21, -22, -41, -43, -32, -25, -23, -16, 6, -9, -29, -28, -5,
- 20, 39, 58, 75, 71, 60, 22, 0, -18, -27, -10, 16, 30, 15, -14, -49,
- -34, -19, -16, -27, -43, -31, -25, -27, -24, -1, 7, -15, -32, -22, 3, 28,
- 50, 61, 67, 59, 38, 13, 5, -17, -16, -3, 21, 23, 3, -34, -49, -28,
- -17, -19, -34, -34, -18, -26, -32, -16, 14, 6, -23, -34, -11, 14, 44, 54,
- 56, 60, 44, 25, 18, 2, -18, -9, 3, 21, 9, -14, -45, -39, -24, -22,
- -28, -32, -18, -17, -36, -30, 5, 21, -5, -31, -27, 1, 30, 56, 46, 50,
- 47, 32, 29, 20, -4, -9, -9, 4, 10, -2, -28, -38, -31, -33, -26, -26,
- -19, -9, -24, -38, -11, 24, 10, -17, -36, -14, 14, 48, 49, 37, 43, 39,
- 33, 32, 11, 1, -5, -11, -6, -3, -16, -29, -28, -40, -38, -27, -20, -6,
- -11, -31, -29, 15, 22, 0, -25, -25, 2, 31, 51, 38, 35, 41, 41, 34,
- 27, 8, 6, -7, -20, -14, -7, -20, -19, -34, -52, -35, -23, -11, -5, -18,
- -33, -5, 26, 5, -11, -27, -11, 17, 43, 43, 30, 29, 46, 45, 38, 17,
- 6, 2, -22, -27, -16, -16, -18, -18, -53, -48, -23, -19, -3, -10, -21, -19,
- 18, 12, -6, -20, -21, 6, 29, 42, 31, 23, 37, 54, 48, 31, 13, 13,
- -13, -31, -25, -16, -16, -11, -38, -62, -33, -28, -7, -3, -12, -17, 6, 16,
- 2, -11, -17, -5, 15, 35, 34, 25, 23, 44, 55, 41, 22, 14, 2, -29,
- -32, -23, -11, -13, -18, -60, -50, -32, -16, -6, -11, -4, 3, 11, 3, -1,
- -14, -8, 5, 20, 39, 31, 24, 26, 54, 57, 37, 16, 8, -19, -32, -27,
- -17, -17, -17, -36, -58, -40, -32, -11, -11, -2, 6, 10, 2, 0, -4, -12,
- 1, 8, 33, 42, 26, 17, 35, 63, 53, 26, 6, -9, -27, -30, -25, -17,
- -23, -24, -47, -51, -38, -17, -11, -6, 12, 17, 8, -8, -1, -10, -7, 4,
- 18, 40, 33, 18, 22, 49, 70, 46, 12, -11, -16, -23, -27, -19, -28, -26,
- -36, -50, -48, -31, -13, -13, 10, 20, 21, 0, -6, -1, -7, 3, 15, 32,
- 40, 24, 17, 31, 58, 67, 28, -2, -21, -14, -31, -18, -24, -33, -33, -49,
- -49, -41, -18, -20, -2, 20, 23, 19, -12, -7, -2, -3, 10, 22, 33, 37,
- 21, 23, 39, 72, 51, 10, -17, -18, -20, -29, -17, -33, -36, -49, -48, -47,
- -24, -16, -15, 11, 24, 30, 6, -12, -2, -2, -1, 18, 29, 35, 27, 25,
- 25, 56, 63, 23, -5, -19, -14, -23, -21, -21, -38, -52, -54, -40, -32, -15,
- -23, -7, 18, 31, 22, -2, -7, 3, 0, 12, 21, 34, 31, 28, 22, 35,
- 66, 40, 2, -19, -19, -15, -21, -16, -30, -60, -62, -42, -33, -18, -18, -22,
- 4, 29, 29, 14, -2, -4, 5, 6, 16, 28, 36, 24, 29, 26, 52, 49,
- 14, -13, -24, -19, -14, -15, -17, -53, -75, -54, -32, -18, -11, -26, -18, 18,
- 28, 25, 13, -6, 4, 13, 9, 17, 37, 24, 28, 33, 37, 49, 26, 1,
- -19, -26, -16, -11, -7, -33, -77, -71, -45, -15, -8, -18, -30, 1, 25, 21,
- 26, 3, 5, 17, 14, 11, 33, 27, 17, 34, 38, 42, 33, 6, -11, -28,
- -22, -12, -3, -16, -60, -81, -62, -25, -2, -14, -27, -17, 20, 18, 24, 18,
- 6, 16, 21, 12, 24, 28, 12, 26, 44, 42, 35, 13, -5, -21, -31, -18,
- -2, -2, -42, -77, -76, -47, -10, -6, -22, -24, 4, 16, 18, 25, 18, 18,
- 24, 20, 20, 32, 14, 11, 40, 49, 41, 21, -6, -13, -27, -28, -5, 5,
- -18, -59, -79, -63, -30, -6, -11, -28, -11, 8, 10, 23, 27, 17, 24, 25,
- 25, 28, 19, 8, 25, 47, 46, 27, -5, -15, -18, -33, -20, -5, -3, -35,
- -70, -66, -51, -22, -7, -21, -19, -3, 6, 17, 29, 26, 23, 28, 25, 32,
- 23, 14, 11, 39, 50, 38, 3, -19, -10, -21, -29, -12, -3, -12, -55, -65,
- -56, -42, -14, -10, -23, -11, -3, 10, 23, 32, 26, 28, 28, 35, 29, 22,
- 13, 18, 41, 43, 18, -16, -18, -14, -29, -21, -11, -8, -32, -61, -52, -52,
- -30, -11, -18, -16, -10, 2, 22, 35, 30, 25, 32, 34, 40, 27, 19, 11,
- 23, 39, 32, -1, -22, -14, -22, -23, -14, -11, -17, -45, -52, -51, -51, -22,
- -17, -19, -17, -10, 11, 35, 39, 29, 26, 34, 43, 43, 27, 16, 12, 25,
- 31, 18, -13, -20, -19, -22, -12, -14, -15, -28, -44, -47, -53, -33, -15, -22,
- -24, -20, 5, 27, 38, 31, 21, 27, 46, 51, 40, 18, 8, 13, 23, 24,
- 3, -21, -22, -22, -8, -9, -22, -26, -31, -40, -51, -44, -17, -15, -26, -31,
- -10, 24, 35, 37, 25, 21, 42, 57, 53, 30, 11, 7, 11, 21, 12, -11,
- -23, -25, -12, 0, -18, -32, -31, -30, -45, -46, -26, -13, -25, -39, -25, 15,
- 36, 29, 25, 20, 37, 58, 63, 46, 15, 3, -2, 19, 16, -2, -19, -25,
- -23, 4, -4, -31, -36, -29, -32, -43, -37, -17, -16, -39, -43, -2, 34, 31,
- 21, 17, 30, 62, 67, 62, 27, 9, -9, 3, 26, 8, -18, -26, -26, -5,
- 9, -23, -44, -33, -26, -33, -40, -28, -12, -30, -52, -24, 23, 33, 15, 14,
- 22, 54, 75, 68, 47, 14, -9, -12, 19, 23, -12, -20, -20, -13, 11, -6,
- -40, -41, -19, -23, -34, -34, -14, -13, -48, -48, 4, 35, 23, 7, 13, 40,
- 77, 78, 57, 31, -3, -18, 3, 27, 7, -24, -19, -16, 1, 5, -29, -49,
- -28, -13, -26, -34, -26, -4, -30, -57, -24, 22, 30, 6, 7, 31, 63, 86,
- 68, 42, 10, -19, -13, 15, 25, -10, -22, -14, -7, 6, -11, -45, -40, -14,
- -24, -35, -31, -12, -8, -51, -44, -2, 29, 11, -1, 22, 47, 74, 78, 49,
- 25, -8, -26, -4, 26, 12, -16, -19, -11, -1, -1, -28, -45, -22, -13, -29,
- -29, -23, -1, -26, -55, -26, 14, 20, -3, 13, 39, 63, 80, 61, 33, 8,
- -22, -25, 10, 22, -1, -14, -15, -7, -1, -14, -37, -26, -13, -25, -28, -26,
- -2, -5, -48, -44, -7, 18, 3, 9, 30, 49, 71, 70, 45, 23, -13, -33,
- -5, 22, 11, -7, -17, -14, -6, -8, -29, -29, -15, -19, -26, -31, -15, 6,
- -25, -52, -30, 7, 7, 2, 21, 40, 60, 67, 52, 33, 7, -29, -19, 16,
- 22, 4, -8, -15, -11, -6, -23, -24, -10, -11, -23, -27, -22, 1, 0, -34,
- -45, -14, 2, 1, 15, 35, 52, 62, 49, 36, 21, -16, -26, 1, 20, 12,
- -7, -10, -20, -10, -19, -28, -9, -8, -15, -26, -27, -11, 2, -15, -41, -34,
- -10, -7, 6, 32, 48, 56, 51, 35, 26, 1, -24, -10, 15, 18, 2, -9,
- -17, -18, -11, -32, -6, 2, -9, -18, -22, -17, -3, -2, -21, -34, -26, -13,
- -8, 20, 47, 53, 52, 38, 24, 5, -14, -15, 9, 14, 4, -6, -14, -21,
- -14, -28, -22, 12, 0, -10, -23, -24, -13, 2, -10, -23, -34, -26, -13, 4,
- 39, 58, 51, 45, 28, 6, -9, -11, 3, 17, 7, -3, -10, -18, -15, -22,
- -35, 2, 18, 2, -11, -23, -20, -1, 0, -15, -24, -39, -25, -6, 17, 52,
- 56, 47, 35, 6, -10, -8, 0, 13, 13, -2, -9, -13, -13, -25, -43, -16,
- 21, 19, -3, -21, -25, -10, 2, -5, -14, -30, -40, -13, -1, 34, 58, 51,
- 44, 18, -10, -9, -2, 6, 12, 7, -7, -12, -12, -18, -40, -33, 9, 32,
- 19, -9, -23, -15, 1, 3, -9, -18, -40, -28, -4, 7, 47, 59, 49, 24,
- 1, -13, -5, 1, 10, 11, 5, -12, -12, -15, -35, -42, -9, 23, 33, 9,
- -22, -24, -5, 1, -5, -12, -30, -40, -7, -3, 22, 56, 58, 35, 11, -12,
- -9, -5, -1, 7, 13, -4, -13, -13, -25, -43, -29, 10, 34, 32, -6, -27,
- -8, 3, -5, -13, -22, -40, -18, -3, -1, 37, 61, 46, 23, -5, -13, -4,
- -4, -7, 12, 14, -10, -18, -22, -34, -35, -10, 22, 39, 23, -15, -14, 5,
- 3, -8, -15, -36, -23, -1, -7, 14, 51, 57, 37, 8, -13, -7, -2, -14,
- -6, 20, 3, -21, -26, -27, -30, -27, 1, 28, 36, 7, -10, 0, 5, -8,
- -14, -30, -29, -3, -10, -5, 31, 56, 46, 19, -7, -10, 3, -11, -21, 9,
- 19, -10, -30, -29, -19, -24, -20, 10, 35, 29, 8, -1, 5, -2, -13, -28,
- -33, -3, -1, -13, 12, 49, 55, 31, -1, -12, 2, -3, -26, -2, 21, 2,
- -28, -34, -21, -17, -29, -12, 23, 34, 19, 6, 7, 4, -4, -23, -40, -10,
- 7, -12, -2, 34, 55, 36, 8, -10, 1, 3, -19, -18, 15, 15, -10, -33,
- -30, -9, -19, -25, 4, 32, 30, 16, 11, 10, 3, -15, -35, -27, 9, -4,
- -10, 16, 52, 42, 12, -7, -6, 4, -6, -21, -2, 17, 0, -20, -41, -13,
- -9, -31, -16, 18, 34, 23, 14, 9, 10, -7, -26, -34, -3, 10, -10, 2,
- 42, 51, 16, -8, -11, -2, -2, -11, -9, 9, 2, -8, -36, -31, 3, -23,
- -30, -1, 27, 27, 23, 15, 18, 3, -17, -31, -19, 8, 1, -4, 24, 51,
- 30, -11, -16, -6, -3, -5, -10, 3, 1, -10, -22, -41, -4, -6, -29, -18,
- 12, 25, 26, 23, 20, 11, -10, -21, -27, -4, 7, 0, 13, 41, 40, 3,
- -24, -11, -1, -2, -3, 5, 5, -14, -15, -35, -20, 0, -19, -24, -4, 11,
- 23, 31, 24, 16, -3, -13, -23, -14, 2, 3, 18, 32, 38, 21, -20, -29,
- -5, -2, 0, 5, 11, -14, -22, -25, -26, -3, -11, -26, -11, -2, 8, 32,
- 34, 24, 2, -8, -16, -13, 1, 1, 10, 31, 31, 33, 1, -36, -22, 0,
- 0, 8, 18, -3, -27, -22, -22, -10, -9, -24, -16, -5, -16, 16, 40, 34,
- 8, -3, -13, -12, 1, 1, 3, 30, 30, 24, 18, -28, -35, -13, -2, 6,
- 19, 10, -25, -28, -15, -9, -10, -19, -20, -3, -15, -8, 27, 42, 25, 1,
- -14, -18, 7, 9, -1, 19, 37, 19, 23, -10, -41, -26, -9, 2, 20, 19,
- -17, -35, -21, 0, -9, -18, -20, -7, -8, -24, 6, 37, 43, 14, -10, -22,
- 3, 18, 4, 6, 36, 23, 16, 4, -32, -37, -19, -3, 17, 27, 0, -37,
- -34, -3, 7, -17, -27, -19, -1, -20, -13, 17, 44, 35, 2, -22, -9, 19,
- 20, 2, 26, 32, 15, 5, -17, -40, -29, -9, 10, 28, 17, -23, -41, -21,
- 9, -2, -27, -30, -5, -7, -21, -4, 27, 47, 27, -14, -21, 11, 29, 14,
- 15, 32, 20, 4, -11, -31, -38, -15, 2, 22, 22, -3, -32, -34, -6, 8,
- -13, -38, -19, 0, -16, -14, 6, 37, 39, 11, -18, -4, 25, 25, 16, 24,
- 27, 7, -10, -24, -38, -25, 0, 12, 23, 8, -16, -31, -23, 0, 0, -27,
- -33, -2, -9, -16, -11, 17, 41, 32, 5, -15, 12, 25, 24, 21, 27, 14,
- -4, -21, -31, -29, -4, 9, 19, 9, -9, -19, -25, -10, -5, -15, -38, -13,
- -6, -13, -17, -1, 30, 36, 27, -2, 2, 20, 24, 25, 24, 19, 2, -16,
- -32, -29, -13, 8, 18, 16, -6, -13, -21, -15, -14, -13, -26, -22, -6, -11,
- -14, -14, 11, 30, 37, 17, 1, 13, 20, 23, 24, 21, 5, -10, -32, -31,
- -15, 0, 17, 22, -3, -15, -17, -11, -15, -19, -23, -22, -8, -8, -13, -18,
- -8, 18, 40, 38, 12, 12, 15, 21, 23, 24, 7, -9, -22, -34, -19, -6,
- 11, 30, 9, -17, -20, -16, -11, -22, -30, -27, -8, -7, -10, -19, -16, -2,
- 32, 52, 31, 17, 16, 13, 21, 19, 19, -9, -17, -30, -25, -7, 3, 29,
- 25, -9, -21, -20, -11, -14, -29, -37, -14, 2, -5, -14, -22, -12, 13, 50,
- 49, 27, 23, 15, 13, 9, 18, 7, -22, -22, -28, -11, -5, 19, 35, 13,
- -20, -24, -18, -8, -22, -38, -31, 2, 3, -6, -26, -22, -3, 38, 56, 42,
- 34, 21, 12, 6, 11, 17, -15, -24, -20, -15, -6, 9, 29, 29, -4, -28,
- -23, -14, -13, -30, -39, -16, 9, 6, -12, -33, -16, 19, 57, 49, 41, 30,
- 13, 4, -1, 6, -4, -27, -21, -13, -6, 2, 12, 34, 12, -24, -24, -20,
- -16, -24, -38, -33, 2, 12, -2, -30, -31, 2, 45, 59, 46, 41, 24, 8,
- -3, -6, 1, -15, -25, -16, -3, 5, 2, 21, 28, -11, -26, -23, -18, -20,
- -32, -40, -14, 14, 11, -10, -40, -20, 30, 60, 55, 42, 34, 15, 6, -12,
- -12, -4, -19, -21, -9, 8, 4, 10, 28, 6, -25, -22, -20, -22, -29, -38,
- -27, 5, 16, 4, -24, -39, 12, 51, 61, 51, 41, 27, 10, -7, -25, -9,
- -10, -17, -15, 0, 9, 5, 21, 15, -13, -27, -17, -21, -23, -38, -33, -11,
- 10, 6, -4, -38, -17, 36, 55, 55, 45, 35, 21, 4, -27, -25, -2, -10,
- -14, -13, 3, 5, 14, 16, 0, -24, -21, -18, -22, -36, -39, -17, -3, 5,
- 3, -15, -28, 16, 50, 53, 52, 43, 29, 13, -14, -36, -10, -1, -15, -15,
- -6, 6, 5, 13, 4, -11, -24, -17, -18, -27, -43, -18, -12, -7, 4, 3,
- -17, -4, 38, 53, 52, 48, 41, 23, 0, -31, -30, 2, -7, -14, -13, -5,
- 3, 11, 7, -4, -21, -25, -21, -19, -39, -23, -9, -19, -8, 5, -1, -10,
- 24, 46, 48, 46, 44, 32, 10, -18, -37, -7, 0, -12, -14, -13, -4, 8,
- 9, 1, -16, -29, -28, -17, -33, -31, -6, -21, -21, -4, 12, 3, 13, 41,
- 46, 44, 46, 44, 20, -7, -36, -27, 6, -3, -18, -21, -12, 2, 12, 6,
- -5, -27, -36, -21, -20, -34, -12, -8, -29, -16, 11, 15, 10, 28, 47, 46,
- 41, 45, 35, 5, -24, -30, -5, 3, -14, -26, -16, -7, 7, 8, -3, -18,
- -39, -32, -16, -28, -26, -8, -23, -26, 0, 19, 16, 20, 42, 55, 45, 38,
- 39, 20, -11, -24, -13, -2, -6, -25, -22, -7, -5, 13, 0, -11, -36, -41,
- -20, -16, -29, -16, -14, -28, -12, 13, 17, 15, 32, 50, 57, 41, 38, 30,
- 2, -14, -9, -3, -3, -19, -33, -10, -7, 7, 7, -13, -30, -42, -28, -13,
- -17, -26, -14, -22, -15, 7, 19, 15, 26, 46, 59, 51, 34, 33, 12, -7,
- -11, -4, -5, -13, -38, -23, -3, 3, 15, -7, -32, -45, -34, -21, -11, -27,
- -25, -21, -19, -1, 13, 15, 22, 37, 53, 62, 46, 34, 15, -2, 0, -4,
- -8, -9, -34, -38, -8, 4, 17, 3, -25, -50, -44, -26, -12, -13, -32, -24,
- -20, -7, 11, 18, 17, 33, 50, 65, 57, 41, 24, 0, 5, 5, -9, -11,
- -25, -44, -25, -1, 17, 13, -18, -42, -51, -33, -20, -7, -27, -29, -23, -16,
- 0, 14, 14, 28, 48, 60, 66, 51, 34, 4, 0, 15, -3, -14, -20, -35,
- -37, -12, 12, 27, -7, -37, -50, -40, -29, -15, -15, -30, -24, -15, -7, 6,
- 17, 25, 46, 59, 68, 63, 43, 20, -6, 14, 10, -8, -20, -30, -34, -22,
- -2, 24, 15, -30, -49, -49, -37, -28, -15, -26, -28, -18, -11, -7, 7, 27,
- 42, 58, 70, 70, 53, 35, 4, 0, 18, -1, -15, -32, -31, -26, -12, 12,
- 28, -4, -44, -53, -44, -39, -25, -23, -28, -19, -11, -12, -16, 13, 42, 56,
- 71, 71, 57, 45, 23, -3, 10, 11, -6, -27, -35, -25, -22, -1, 23, 17,
- -29, -54, -46, -44, -39, -29, -28, -21, -15, -15, -26, -12, 39, 57, 70, 73,
- 60, 49, 41, 13, 1, 11, 0, -16, -32, -25, -15, -14, 10, 23, -5, -48,
- -46, -42, -49, -43, -31, -24, -15, -13, -24, -32, 18, 59, 71, 77, 67, 57,
- 47, 33, 3, 5, 5, -9, -23, -33, -16, -14, -5, 17, 12, -29, -44, -35,
- -50, -57, -43, -30, -18, -11, -22, -39, -9, 44, 68, 82, 69, 61, 49, 42,
- 18, 5, 5, -8, -12, -26, -14, -7, -9, 5, 16, -6, -36, -32, -42, -62,
- -55, -39, -29, -15, -14, -34, -30, 20, 59, 82, 79, 66, 58, 45, 38, 9,
- 1, -7, -11, -16, -19, -3, -6, -6, 9, 5, -22, -32, -32, -58, -70, -56,
- -42, -24, -16, -25, -39, -9, 41, 72, 86, 73, 65, 46, 40, 30, -4, -7,
- -14, -12, -20, -3, 4, -5, 1, 8, -9, -27, -25, -40, -67, -67, -55, -38,
- -24, -17, -25, -28, 16, 61, 81, 82, 71, 60, 37, 42, 17, -14, -17, -11,
- -13, -8, 10, 2, -2, 1, -1, -17, -20, -26, -54, -69, -70, -58, -34, -25,
- -16, -23, -9, 37, 70, 87, 80, 68, 44, 38, 39, -5, -27, -19, -12, -6,
- 13, 10, 4, 1, 1, -5, -19, -20, -37, -59, -71, -71, -54, -35, -17, -9,
- -20, 11, 49, 80, 86, 72, 54, 36, 45, 23, -25, -34, -16, -9, 11, 17,
- 8, 5, -4, -2, -15, -19, -26, -50, -69, -77, -71, -51, -29, -7, -11, -6,
- 26, 64, 87, 78, 60, 40, 42, 45, 2, -38, -34, -12, 10, 24, 10, 11,
- 3, -1, -6, -20, -16, -31, -61, -81, -80, -69, -41, -16, -5, -8, 10, 47,
- 81, 86, 70, 44, 36, 48, 32, -21, -48, -31, -3, 24, 24, 10, 15, 0,
- 2, -17, -21, -18, -45, -81, -87, -80, -57, -33, -11, -6, 2, 30, 74, 86,
- 77, 55, 34, 42, 48, 13, -39, -50, -20, 15, 34, 14, 16, 12, 4, -5,
- -26, -16, -19, -64, -92, -91, -65, -43, -26, -12, -1, 16, 47, 83, 76, 66,
- 40, 33, 45, 33, -8, -52, -41, -5, 32, 30, 15, 25, 13, 8, -22, -28,
- -11, -34, -85, -101, -86, -52, -36, -25, -13, 15, 32, 69, 80, 69, 52, 32,
- 37, 39, 19, -30, -54, -24, 10, 38, 25, 25, 22, 18, -6, -35, -20, -14,
- -59, -98, -99, -68, -41, -30, -23, 5, 28, 52, 74, 67, 59, 43, 32, 35,
- 32, -2, -47, -38, -13, 23, 33, 31, 26, 27, 16, -29, -37, -15, -33, -80,
- -104, -89, -54, -35, -31, -11, 17, 42, 63, 68, 60, 59, 37, 27, 33, 22,
- -28, -37, -26, 3, 32, 38, 30, 25, 30, -3, -41, -29, -23, -55, -90, -98,
- -76, -39, -32, -21, 4, 36, 52, 61, 61, 63, 48, 24, 28, 34, -10, -31,
- -29, -14, 15, 37, 37, 28, 31, 19, -27, -40, -24, -38, -69, -95, -96, -60,
- -32, -26, -10, 19, 45, 53, 58, 59, 58, 29, 23, 39, 14, -21, -25, -23,
- 1, 27, 43, 34, 34, 21, 0, -36, -32, -31, -49, -84, -102, -83, -41, -22,
- -19, -1, 35, 49, 52, 53, 56, 39, 23, 34, 33, -3, -23, -22, -10, 17,
- 36, 36, 39, 26, 8, -16, -34, -29, -36, -61, -93, -95, -58, -26, -18, -11,
- 22, 48, 53, 53, 51, 41, 31, 33, 37, 16, -15, -24, -14, 4, 29, 34,
- 41, 32, 8, -7, -19, -28, -30, -54, -83, -101, -76, -40, -20, -21, 1, 36,
- 54, 55, 44, 33, 32, 35, 36, 30, 7, -26, -19, -5, 22, 36, 37, 37,
- 15, -3, -5, -15, -24, -43, -75, -94, -87, -47, -29, -25, -14, 26, 48, 62,
- 49, 29, 23, 35, 45, 38, 19, -16, -28, -7, 10, 29, 32, 38, 23, -2,
- -10, -6, -12, -28, -67, -90, -98, -59, -32, -28, -25, 3, 43, 56, 59, 25,
- 16, 24, 46, 43, 31, 0, -31, -14, 5, 25, 29, 32, 29, 6, -13, -6,
- -3, -8, -49, -85, -97, -75, -31, -30, -30, -12, 31, 50, 61, 40, 12, 14,
- 34, 53, 43, 20, -23, -20, -3, 21, 29, 23, 24, 15, -10, -8, -1, 2,
- -25, -75, -98, -92, -42, -31, -35, -24, 14, 41, 50, 49, 22, 11, 20, 45,
- 52, 39, 0, -26, -12, 9, 35, 25, 18, 14, 1, -13, -6, 4, 3, -49,
- -89, -102, -61, -27, -30, -27, -4, 34, 46, 46, 32, 17, 13, 26, 47, 50,
- 29, -19, -22, -4, 30, 37, 15, 7, 7, -5, -10, -4, 9, -20, -72, -100,
- -86, -41, -33, -31, -16, 18, 43, 34, 32, 27, 23, 15, 31, 47, 48, 9,
- -24, -16, 12, 43, 25, -2, 0, 9, -9, -15, 2, 8, -40, -87, -99, -69,
- -37, -31, -19, 6, 38, 35, 25, 31, 35, 26, 18, 36, 49, 40, -10, -22,
- -9, 29, 40, 6, -12, 6, 6, -16, -11, 9, -6, -61, -95, -90, -58, -35,
- -26, -5, 23, 36, 18, 21, 36, 41, 28, 22, 38, 52, 23, -17, -17, 7,
- 39, 21, -12, -13, 16, -8, -22, -5, 6, -25, -77, -93, -79, -46, -30, -11,
- 15, 36, 22, 5, 29, 47, 47, 24, 22, 41, 48, 7, -15, -4, 22, 33,
- 6, -23, 4, 8, -21, -15, -1, -5, -49, -79, -92, -71, -43, -20, 11, 31,
- 29, 4, 16, 40, 55, 41, 22, 31, 50, 25, -9, -2, 8, 23, 16, -17,
- -6, 8, -10, -15, -6, -4, -29, -56, -80, -86, -61, -42, 0, 30, 33, 12,
- 2, 24, 47, 55, 37, 28, 39, 40, 4, -1, 6, 6, 16, -4, -13, 1,
- -2, -9, -11, -11, -21, -35, -55, -82, -80, -64, -24, 27, 36, 23, 3, 10,
- 35, 61, 55, 40, 35, 35, 19, 6, 12, 4, 1, 3, -12, -3, -2, -4,
- -4, -14, -23, -30, -37, -58, -83, -84, -58, 8, 37, 33, 11, 3, 20, 46,
- 62, 55, 50, 28, 16, 12, 15, 9, -4, -9, -9, -4, -5, -7, 2, -7,
- -28, -35, -31, -36, -67, -90, -86, -23, 28, 38, 25, 5, 13, 34, 58, 58,
- 69, 50, 15, 10, 20, 16, -3, -14, -14, -2, 1, -12, -3, 3, -20, -36,
- -39, -26, -46, -81, -98, -61, 6, 27, 30, 16, 12, 25, 50, 57, 66, 74,
- 31, 4, 16, 21, 8, -13, -21, -10, 8, -5, -11, 6, -8, -31, -40, -29,
- -30, -66, -93, -84, -22, 17, 22, 26, 16, 20, 43, 56, 56, 70, 60, 17,
- 8, 18, 15, -10, -26, -21, 6, 7, -12, -1, 1, -20, -33, -34, -31, -51,
- -79, -92, -52, -6, 9, 19, 23, 21, 40, 57, 59, 60, 72, 43, 17, 13,
- 18, 3, -23, -32, -5, 14, -7, -11, 7, -12, -26, -31, -37, -46, -66, -85,
- -67, -21, -5, 3, 16, 22, 37, 54, 59, 55, 60, 58, 30, 16, 13, 11,
- -15, -34, -23, 9, 7, -12, -2, -4, -19, -16, -31, -49, -64, -76, -72, -35,
- -12, -14, 0, 15, 34, 53, 60, 58, 53, 57, 43, 30, 18, 12, -4, -27,
- -28, -8, 14, -3, -9, -2, -13, -9, -17, -49, -66, -70, -69, -44, -15, -19,
- -11, 2, 21, 53, 64, 68, 55, 48, 44, 36, 28, 15, -1, -18, -23, -19,
- -4, 5, -3, 1, -9, -7, -1, -35, -70, -74, -70, -50, -21, -14, -22, -7,
- -1, 39, 66, 77, 69, 46, 38, 36, 38, 22, 5, -12, -16, -12, -17, -8,
- -5, 2, 1, -6, 5, -13, -64, -78, -73, -60, -31, -14, -17, -16, -10, 7,
- 61, 79, 81, 57, 38, 28, 32, 24, 9, -4, -10, -4, -11, -20, -13, -2,
- 11, 4, 4, -2, -41, -76, -76, -69, -43, -22, -12, -17, -14, -14, 25, 74,
- 92, 79, 47, 31, 26, 26, 11, 3, -5, 0, 0, -20, -26, -11, 9, 14,
- 9, 4, -24, -61, -76, -74, -53, -30, -13, -8, -12, -25, -8, 51, 90, 93,
- 63, 42, 21, 18, 13, 6, 2, 1, 8, -12, -30, -27, -2, 14, 18, 11,
- -13, -48, -68, -79, -70, -44, -19, -2, -5, -21, -31, 18, 77, 100, 81, 55,
- 29, 7, 8, 6, 7, 4, 14, 0, -26, -34, -13, 9, 16, 17, 1, -35,
- -58, -70, -82, -62, -29, -2, 1, -14, -36, -15, 50, 89, 95, 71, 46, 5,
- -6, 4, 11, 3, 11, 14, -12, -31, -22, -2, 8, 16, 16, -15, -53, -56,
- -80, -81, -41, -5, 9, -3, -30, -34, 17, 73, 97, 86, 63, 25, -12, -6,
- 11, 13, 1, 15, 4, -19, -25, -5, 2, 9, 19, 10, -39, -48, -61, -95,
- -67, -17, 12, 8, -23, -43, -9, 49, 85, 91, 76, 50, 1, -23, 2, 22,
- 5, 2, 14, -5, -23, -12, 0, -2, 13, 17, -15, -48, -43, -83, -88, -38,
- 5, 17, -11, -41, -28, 27, 67, 83, 82, 65, 29, -21, -18, 21, 19, -7,
- 3, 6, -8, -14, 1, 0, 0, 13, 2, -34, -42, -59, -99, -63, -12, 17,
- 0, -35, -42, 1, 53, 69, 79, 72, 53, -1, -34, 2, 32, 3, -8, 1,
- 2, -2, -3, 8, -2, 3, 7, -18, -40, -39, -76, -81, -35, 9, 17, -22,
- -46, -24, 34, 59, 68, 74, 66, 27, -26, -22, 31, 24, -10, -11, 0, 14,
- 1, 5, 8, -5, -2, -10, -34, -35, -48, -77, -59, -13, 20, -4, -37, -35,
- 8, 47, 55, 68, 74, 49, -4, -34, 10, 39, 1, -13, -11, 14, 14, 3,
- 20, 6, -9, -14, -29, -37, -28, -56, -66, -42, 9, 9, -25, -38, -14, 27,
- 45, 54, 72, 61, 21, -25, -14, 31, 19, -10, -15, -2, 22, 6, 22, 24,
- -4, -20, -28, -38, -24, -28, -54, -57, -20, 14, -10, -29, -26, 2, 29, 39,
- 61, 66, 39, -6, -25, 16, 30, 0, -16, -8, 12, 13, 18, 38, 10, -20,
- -36, -34, -31, -16, -33, -56, -42, 0, 0, -21, -22, -12, 11, 25, 49, 68,
- 53, 14, -20, -3, 29, 15, -11, -12, 3, 13, 13, 42, 34, -12, -39, -37,
- -27, -22, -18, -44, -50, -21, 3, -12, -15, -18, -5, 9, 27, 60, 60, 32,
- -6, -12, 21, 25, -4, -12, -2, 7, 8, 33, 53, 8, -37, -41, -25, -22,
- -16, -27, -47, -34, -10, -10, -15, -15, -15, -5, 5, 41, 63, 44, 12, -11,
- 10, 32, 10, -14, -8, 8, 5, 19, 53, 34, -24, -43, -25, -14, -15, -19,
- -35, -35, -20, -12, -8, -14, -17, -19, -13, 19, 55, 53, 22, -8, 4, 31,
- 26, -8, -13, 6, 10, 7, 39, 50, -2, -41, -31, -10, -13, -23, -31, -33,
- -24, -15, -7, -13, -16, -22, -23, -6, 38, 55, 34, 1, -1, 23, 34, 9,
- -18, -3, 14, 9, 20, 51, 24, -28, -37, -6, 2, -20, -30, -27, -21, -22,
- -6, -12, -17, -21, -32, -27, 9, 49, 43, 12, -4, 14, 34, 24, -9, -12,
- 12, 19, 13, 30, 37, -3, -35, -15, 12, -10, -31, -30, -15, -18, -13, -3,
- -19, -20, -31, -35, -17, 28, 44, 22, 0, 7, 28, 27, 5, -15, 1, 20,
- 20, 17, 28, 19, -21, -23, 12, 8, -22, -32, -20, -8, -15, 0, -13, -23,
- -25, -43, -36, 4, 37, 30, 11, 4, 22, 28, 15, 0, -10, 9, 23, 14,
- 11, 24, 5, -21, 2, 17, -8, -27, -27, -7, -10, -6, -1, -20, -26, -39,
- -53, -20, 23, 36, 17, 7, 14, 28, 16, 12, -3, 2, 19, 16, 2, 14,
- 19, -8, -5, 17, 4, -15, -26, -10, -4, -12, 1, -8, -23, -38, -58, -41,
- 0, 29, 23, 11, 16, 21, 15, 9, 11, -6, 11, 20, 4, 3, 24, 5,
- -5, 10, 17, -6, -15, -15, 6, -15, -8, 0, -11, -37, -54, -56, -24, 13,
- 29, 12, 15, 20, 19, 6, 16, 5, -2, 10, 11, -3, 22, 18, 0, 6,
- 20, 10, -6, -12, 1, -6, -23, 0, 1, -23, -56, -60, -43, -10, 19, 22,
- 15, 22, 18, 6, 11, 17, -2, -5, 10, 4, 7, 23, 1, 3, 16, 22,
- 5, -1, 0, 5, -21, -14, 6, -6, -46, -64, -54, -29, 1, 17, 18, 24,
- 25, 10, 1, 17, 9, -8, -1, 15, 6, 20, 11, 2, 14, 25, 16, 9,
- 5, 7, -11, -26, -5, 4, -27, -62, -62, -40, -17, 8, 11, 21, 29, 17,
- -2, 10, 17, -8, -16, 6, 13, 11, 15, 3, 8, 24, 26, 14, 12, 12,
- 4, -26, -15, 1, -12, -50, -64, -48, -27, -10, 5, 8, 32, 31, 1, -1,
- 18, 0, -23, -6, 18, 14, 11, 5, 3, 17, 35, 25, 16, 18, 14, -11,
- -27, -8, -6, -30, -55, -53, -36, -20, -5, 5, 14, 43, 13, -6, 11, 11,
- -22, -22, 7, 19, 13, 10, 1, 7, 30, 36, 22, 23, 23, 6, -28, -20,
- -6, -23, -43, -49, -43, -29, -19, 3, 1, 34, 29, -4, 3, 13, -13, -32,
- -3, 20, 14, 11, 5, 2, 23, 42, 34, 22, 23, 21, -13, -26, -14, -19,
- -32, -38, -43, -32, -29, -6, 4, 16, 35, 9, -4, 11, 0, -33, -22, 9,
- 13, 12, 9, 3, 14, 35, 47, 34, 23, 27, 8, -22, -19, -16, -30, -29,
- -42, -33, -32, -23, 4, 9, 24, 20, -1, 3, 10, -20, -36, -5, 13, 9,
- 11, 8, 8, 21, 43, 48, 27, 22, 23, -7, -25, -20, -28, -25, -31, -36,
- -28, -33, -8, 11, 14, 14, 6, -8, 7, -5, -39, -25, 7, 14, 9, 10,
- 12, 15, 29, 55, 41, 23, 22, 9, -12, -23, -28, -24, -23, -34, -26, -31,
- -21, 9, 19, 9, 1, -3, -1, 7, -32, -38, -9, 13, 11, 9, 11, 14,
- 21, 46, 53, 32, 24, 12, -2, -16, -26, -24, -17, -34, -33, -25, -24, -4,
- 17, 14, -3, -4, -7, 3, -13, -46, -25, 2, 17, 5, 8, 12, 18, 32,
- 56, 38, 29, 15, 8, -4, -22, -30, -14, -22, -42, -25, -15, -10, 6, 17,
- 1, -5, -7, -10, -2, -38, -37, -7, 15, 9, 2, 8, 21, 26, 43, 44,
- 29, 18, 7, 12, -9, -25, -24, -11, -35, -43, -17, -5, 3, 10, 9, -3,
- -3, -23, -9, -23, -45, -22, 7, 15, 2, 4, 17, 33, 31, 45, 35, 23,
- 8, 17, 6, -16, -26, -14, -20, -48, -27, -2, 6, 11, 9, -1, 6, -15,
- -28, -18, -39, -32, -7, 11, 7, 6, 7, 33, 30, 31, 41, 27, 7, 13,
- 24, -3, -18, -22, -9, -40, -41, -10, 4, 9, 17, 3, 5, -4, -37, -29,
- -29, -35, -19, 1, 10, 3, 7, 25, 41, 19, 31, 32, 13, 5, 27, 14,
- -6, -19, -12, -23, -48, -22, 7, 8, 16, 11, 1, 6, -29, -46, -32, -32,
- -20, -5, 7, 4, 3, 21, 43, 32, 15, 29, 16, 8, 19, 26, 3, -9,
- -22, -13, -42, -37, -8, 11, 14, 25, 9, 4, -17, -50, -44, -30, -25, -14,
- -1, 11, 1, 18, 36, 41, 12, 14, 18, 14, 15, 20, 17, 6, -14, -18,
- -27, -39, -19, 5, 12, 24, 27, 8, -13, -49, -53, -32, -27, -19, -12, 7,
- 7, 12, 31, 43, 26, 2, 8, 14, 22, 13, 17, 18, 6, -17, -26, -36,
- -28, -6, 14, 25, 35, 20, -6, -42, -57, -37, -23, -23, -20, 0, 9, 8,
- 25, 41, 40, 7, -4, 1, 23, 21, 14, 22, 20, -2, -24, -34, -31, -13,
- 8, 24, 37, 33, 8, -32, -62, -44, -20, -22, -27, -9, 9, 7, 16, 31,
- 42, 20, -10, -13, 10, 26, 7, 13, 25, 18, -11, -35, -39, -20, 0, 17,
- 37, 37, 19, -17, -58, -55, -26, -18, -25, -21, 0, 14, 12, 20, 38, 35,
- 0, -19, -9, 24, 19, 3, 21, 31, 17, -24, -42, -30, -3, 13, 34, 42,
- 28, -2, -45, -62, -38, -22, -19, -20, -12, 12, 17, 11, 29, 42, 18, -16,
- -20, 3, 24, 2, 4, 26, 36, 0, -38, -45, -13, 12, 27, 41, 34, 14,
- -27, -62, -55, -30, -19, -15, -16, -2, 18, 11, 14, 37, 31, -6, -22, -12,
- 15, 10, -10, 12, 36, 30, -19, -46, -33, 11, 24, 28, 35, 28, -5, -44,
- -65, -44, -23, -11, -9, -8, 5, 14, 10, 25, 37, 14, -17, -18, -2, 14,
- -7, -6, 23, 43, 10, -33, -38, -9, 24, 24, 28, 30, 11, -21, -57, -61,
- -39, -12, -5, -5, -3, 7, 10, 17, 31, 30, -3, -20, -14, 6, 1, -16,
- 2, 38, 38, -5, -30, -24, 13, 25, 21, 28, 15, 1, -34, -64, -62, -23,
- 0, 2, -1, -1, 5, 14, 24, 33, 14, -12, -23, -4, 7, -18, -18, 18,
- 43, 25, -9, -22, -2, 21, 19, 24, 20, 11, -13, -47, -69, -46, -7, 5,
- 6, -1, -4, 9, 21, 31, 25, 5, -15, -20, 3, -8, -33, -7, 29, 37,
- 20, -10, -10, 9, 15, 17, 14, 12, 1, -23, -55, -70, -30, 5, 13, 2,
- -8, -1, 15, 25, 30, 15, -1, -20, -8, -3, -31, -28, 8, 31, 41, 15,
- -6, 0, 9, 14, 12, 9, 8, -10, -28, -63, -55, -12, 17, 11, -7, -13,
- 8, 22, 26, 19, 9, -7, -13, -5, -23, -39, -10, 17, 41, 38, 8, 0,
- 5, 7, 12, 5, 7, -6, -8, -39, -60, -35, 7, 19, 6, -10, -6, 15,
- 26, 22, 15, 9, -8, -13, -24, -45, -29, -1, 29, 48, 30, 2, 6, 5,
- 9, 5, -1, -5, -4, -13, -51, -51, -16, 20, 13, 0, -11, 7, 25, 22,
- 18, 17, 10, -8, -22, -50, -43, -13, 15, 46, 42, 16, 7, 8, 7, 7,
- -1, -6, -10, -4, -27, -45, -36, 5, 16, 7, -5, -5, 20, 22, 19, 19,
- 22, 7, -15, -43, -62, -29, 3, 35, 43, 27, 11, 9, 8, 4, 2, -9,
- -13, -7, -15, -30, -43, -16, 12, 13, 4, -8, 12, 24, 17, 16, 24, 25,
- -3, -38, -72, -52, -9, 25, 42, 30, 21, 8, 14, 4, 6, -3, -13, -12,
- -13, -18, -36, -34, 3, 14, 9, -9, 5, 26, 18, 13, 26, 34, 13, -31,
- -69, -68, -16, 19, 35, 29, 22, 6, 16, 3, 2, 6, -5, -15, -20, -19,
- -21, -34, -17, 8, 16, -2, -3, 24, 27, 16, 23, 34, 32, -10, -56, -80,
- -45, 6, 29, 29, 22, 10, 14, 13, -4, 6, 7, -8, -27, -27, -18, -20,
- -28, -8, 14, 8, -7, 11, 29, 21, 17, 25, 35, 16, -36, -77, -67, -14,
- 25, 30, 22, 11, 10, 19, 5, 2, 6, 5, -18, -34, -25, -13, -23, -19,
- 4, 13, 0, 7, 24, 32, 24, 22, 31, 30, -12, -62, -76, -41, 9, 28,
- 24, 15, 6, 18, 16, 6, 6, 7, -7, -32, -37, -16, -18, -24, -8, 11,
- 7, 7, 20, 31, 35, 25, 24, 33, 9, -40, -72, -58, -16, 17, 27, 16,
- 6, 10, 22, 12, 8, 8, 2, -23, -43, -26, -16, -24, -18, 2, 6, 7,
- 21, 29, 36, 32, 21, 27, 22, -21, -57, -67, -38, -4, 26, 21, 9, 3,
- 18, 25, 18, 10, 2, -11, -42, -36, -24, -27, -23, -9, 5, 2, 17, 32,
- 42, 36, 27, 18, 25, -2, -39, -58, -51, -27, 11, 27, 11, 1, 9, 24,
- 25, 21, 5, -8, -31, -37, -30, -33, -24, -15, 0, -2, 13, 31, 48, 47,
- 33, 15, 18, 10, -27, -50, -52, -44, -12, 21, 21, 5, -1, 13, 33, 30,
- 16, -6, -26, -39, -33, -35, -28, -20, -10, -8, 4, 27, 51, 61, 45, 21,
- 13, 14, -11, -39, -40, -44, -36, 1, 25, 16, 1, 2, 27, 40, 28, 3,
- -22, -38, -38, -32, -33, -21, -18, -14, -8, 18, 50, 66, 60, 27, 7, 12,
- -3, -31, -36, -37, -46, -27, 18, 26, 5, -3, 8, 35, 43, 16, -14, -36,
- -43, -32, -32, -25, -16, -23, -14, 6, 46, 64, 74, 49, 9, 4, 7, -23,
- -37, -34, -41, -44, -8, 31, 19, -5, 0, 21, 47, 33, -2, -33, -43, -43,
- -32, -29, -14, -22, -23, -6, 34, 62, 75, 71, 30, 0, 8, -13, -37, -34,
- -35, -45, -34, 18, 31, 5, -5, 7, 35, 44, 12, -23, -45, -49, -40, -29,
- -18, -18, -27, -15, 22, 57, 74, 80, 57, 15, 4, -1, -39, -34, -34, -40,
- -46, -4, 25, 13, -3, 2, 22, 44, 25, -10, -38, -44, -50, -34, -20, -14,
- -31, -21, 5, 47, 63, 81, 76, 38, 8, 9, -30, -45, -35, -36, -43, -20,
- 9, 14, 5, 3, 7, 36, 32, 3, -32, -43, -50, -40, -28, -13, -24, -28,
- -2, 35, 56, 73, 86, 58, 23, 21, -10, -49, -45, -33, -39, -25, -3, 5,
- 5, 8, 5, 18, 32, 17, -19, -45, -49, -41, -35, -22, -19, -31, -12, 28,
- 52, 59, 76, 74, 41, 31, 10, -39, -58, -41, -32, -27, -5, -3, 3, 8,
- 8, 10, 24, 22, -4, -39, -52, -42, -35, -30, -18, -28, -22, 20, 53, 52,
- 60, 73, 62, 43, 31, -18, -56, -61, -35, -28, -9, -6, -3, 3, 9, 10,
- 12, 18, 8, -23, -53, -50, -31, -35, -24, -28, -26, 3, 48, 55, 52, 59,
- 66, 57, 46, 7, -37, -67, -53, -24, -11, -4, -6, 0, 3, 13, 10, 7,
- 10, -6, -38, -58, -36, -30, -30, -26, -26, -11, 33, 60, 56, 49, 59, 67,
- 58, 32, -15, -58, -69, -34, -14, -8, -6, 1, -4, 7, 8, 2, 4, 4,
- -21, -54, -49, -30, -30, -28, -29, -18, 13, 53, 60, 50, 44, 63, 61, 49,
- 11, -33, -71, -49, -19, -9, -10, 5, 2, -1, 4, -1, 4, 5, -5, -38,
- -55, -40, -28, -21, -25, -26, -2, 40, 61, 56, 39, 53, 66, 54, 33, -4,
- -55, -63, -29, -18, -12, 3, 11, -4, -4, -9, -3, 4, 4, -18, -49, -49,
- -35, -18, -18, -25, -16, 24, 51, 60, 42, 43, 66, 57, 42, 21, -23, -63,
- -44, -26, -18, -10, 13, 9, -8, -18, -17, 5, 5, -4, -35, -47, -42, -24,
- -11, -20, -21, 5, 36, 56, 53, 37, 60, 59, 40, 34, 11, -34, -52, -33,
- -21, -15, 1, 21, 2, -19, -33, -10, 8, 3, -20, -42, -41, -33, -14, -16,
- -18, -7, 21, 43, 54, 39, 47, 61, 44, 31, 27, -4, -41, -47, -28, -23,
- -9, 11, 15, -9, -34, -34, 1, 10, -2, -30, -38, -34, -18, -15, -17, -10,
- 10, 27, 43, 42, 42, 53, 54, 36, 24, 14, -15, -42, -36, -32, -22, 1,
- 13, 7, -26, -48, -24, 11, 10, -14, -35, -32, -19, -16, -15, -11, 5, 18,
- 31, 34, 41, 48, 51, 46, 28, 26, 8, -26, -36, -33, -35, -12, 7, 12,
- -8, -45, -47, -9, 13, 5, -24, -32, -17, -14, -16, -11, 6, 14, 20, 26,
- 27, 47, 49, 49, 34, 25, 22, -6, -31, -27, -39, -30, -10, 13, 6, -28,
- -57, -31, -3, 12, -7, -28, -19, -8, -21, -18, -2, 18, 17, 17, 19, 34,
- 47, 53, 42, 34, 30, 13, -22, -20, -30, -44, -32, -4, 15, -7, -45, -49,
- -18, 4, 10, -14, -18, 0, -11, -26, -7, 15, 23, 10, 10, 20, 34, 51,
- 49, 38, 41, 30, -8, -28, -15, -39, -47, -28, 5, 10, -26, -55, -34, -9,
- 10, 3, -13, -4, 1, -21, -19, 3, 25, 13, 5, 9, 18, 36, 54, 39,
- 40, 46, 16, -27, -17, -23, -47, -47, -18, 9, -2, -47, -51, -23, 0, 4,
- 0, 1, 9, -11, -20, -9, 20, 23, 4, 2, 8, 20, 45, 46, 38, 53,
- 41, -13, -30, -19, -36, -52, -40, -9, 5, -23, -53, -35, -6, 4, 3, 6,
- 10, 5, -16, -17, 6, 30, 12, 0, -4, 9, 32, 47, 43, 55, 57, 16,
- -27, -30, -28, -44, -52, -31, -6, -8, -43, -43, -15, -1, -1, 8, 10, 13,
- 2, -18, -11, 21, 23, 6, -5, 0, 19, 33, 41, 56, 67, 44, -5, -34,
- -35, -32, -46, -47, -27, -7, -30, -44, -23, -2, -2, 3, 7, 14, 18, -1,
- -19, 4, 20, 16, -5, -9, 10, 27, 30, 46, 65, 63, 26, -22, -42, -34,
- -41, -46, -40, -18, -25, -39, -28, -4, 1, -1, 5, 10, 24, 19, -8, -6,
- 11, 20, 4, -13, 2, 22, 24, 36, 59, 70, 51, 5, -39, -39, -43, -47,
- -45, -31, -30, -39, -33, -7, 1, -2, 1, 4, 19, 25, 5, -5, 1, 12,
- 13, -12, -12, 18, 25, 21, 46, 68, 69, 36, -17, -39, -44, -51, -43, -33,
- -35, -41, -38, -15, 8, 0, 0, 0, 13, 26, 19, 5, 0, -1, 10, -2,
- -14, 5, 25, 19, 29, 54, 71, 59, 9, -31, -43, -56, -50, -32, -38, -47,
- -42, -26, 8, 10, -3, -3, 7, 20, 23, 16, 8, -5, 3, 2, -17, -6,
- 22, 20, 18, 40, 66, 71, 37, -13, -36, -52, -61, -38, -32, -47, -51, -38,
- -7, 19, 6, -6, 4, 14, 19, 21, 19, 2, -5, 0, -13, -12, 14, 21,
- 13, 27, 53, 71, 57, 12, -25, -42, -61, -54, -33, -38, -52, -50, -22, 13,
- 17, -4, 1, 16, 17, 19, 25, 11, -2, -2, -11, -18, 6, 21, 15, 18,
- 43, 66, 67, 34, -7, -30, -49, -58, -42, -36, -42, -54, -36, -2, 20, 4,
- -4, 11, 16, 17, 26, 17, 4, 1, -8, -22, -8, 17, 16, 17, 27, 55,
- 66, 48, 10, -25, -36, -49, -52, -42, -39, -47, -46, -18, 13, 14, -1, 3,
- 13, 19, 27, 18, 2, 5, 1, -14, -17, 6, 13, 16, 26, 44, 64, 54,
- 27, -15, -30, -33, -49, -50, -43, -44, -45, -30, -1, 13, 3, 6, 10, 22,
- 30, 21, 3, 2, 2, -3, -18, -9, 8, 11, 23, 35, 55, 58, 37, 1,
- -25, -18, -33, -51, -48, -46, -41, -30, -17, 6, 3, 7, 9, 16, 30, 27,
- 9, 3, 3, 1, -10, -18, 0, 3, 12, 37, 46, 52, 40, 15, -23, -16,
- -14, -39, -48, -48, -45, -31, -20, -7, 1, 4, 14, 13, 21, 26, 16, 2,
- 1, 1, 1, -16, -12, 1, 5, 29, 50, 47, 39, 21, -11, -21, -3, -23,
- -41, -45, -47, -37, -21, -13, -6, 1, 16, 20, 22, 22, 18, 10, 2, 1,
- 6, -7, -16, -10, 0, 16, 51, 53, 38, 22, -1, -21, -1, -4, -30, -41,
- -45, -45, -28, -13, -13, -8, 13, 24, 26, 15, 13, 15, 8, -4, 1, -2,
- -11, -15, -11, 2, 40, 56, 44, 21, 1, -16, -10, 5, -16, -32, -38, -41,
- -36, -22, -14, -15, 4, 24, 32, 18, 7, 14, 14, 4, -2, -1, -8, -12,
- -15, -6, 24, 50, 51, 28, 1, -13, -14, 4, 1, -18, -31, -35, -36, -33,
- -21, -21, -5, 19, 38, 23, 3, 5, 17, 15, 2, -3, -7, -8, -18, -14,
- 12, 39, 50, 35, 2, -14, -14, -3, 6, -6, -24, -27, -32, -40, -25, -22,
- -12, 8, 35, 34, 10, 2, 5, 19, 9, -6, -4, -3, -15, -18, 4, 30,
- 42, 40, 13, -17, -16, -7, 3, 5, -14, -21, -24, -41, -37, -23, -18, -1,
- 22, 37, 17, 4, -1, 11, 17, 1, -7, -4, -12, -22, -6, 24, 35, 33,
- 25, -7, -26, -15, 2, 14, 3, -16, -19, -33, -42, -27, -23, -10, 15, 28,
- 27, 8, 2, 5, 20, 11, -4, -6, -7, -19, -11, 17, 31, 26, 25, 6,
- -24, -25, -6, 11, 14, -3, -13, -25, -39, -33, -23, -17, 7, 19, 26, 19,
- 4, 1, 15, 14, -1, -5, -10, -14, -22, 8, 33, 28, 20, 16, -13, -26,
- -17, 9, 22, 5, -8, -18, -37, -35, -28, -23, -4, 12, 16, 28, 12, 1,
- 12, 18, 3, -2, -9, -10, -27, -10, 29, 34, 18, 16, 2, -26, -29, -3,
- 27, 19, -4, -10, -29, -36, -30, -29, -12, 9, 3, 18, 21, 7, 12, 17,
- 3, -2, -7, -7, -19, -26, 15, 36, 21, 12, 9, -15, -30, -18, 19, 30,
- 6, -5, -21, -32, -25, -29, -22, 6, 0, 3, 20, 14, 12, 18, 12, 0,
- -9, -12, -9, -26, -4, 31, 28, 11, 10, -6, -24, -29, 3, 35, 19, -3,
- -15, -26, -19, -23, -31, -6, 4, -7, 13, 19, 17, 20, 18, 9, -9, -19,
- -5, -17, -20, 16, 34, 18, 9, 0, -16, -25, -10, 30, 29, 3, -10, -19,
- -19, -16, -29, -19, 3, -9, -5, 13, 21, 24, 16, 13, 1, -23, -14, -12,
- -19, -2, 28, 21, 8, 1, -11, -23, -19, 16, 41, 14, -8, -13, -9, -13,
- -18, -27, -4, -5, -12, -1, 19, 31, 18, 10, 16, -20, -22, -13, -14, -12,
- 18, 26, 12, 4, -4, -17, -18, -1, 38, 31, -5, -14, -7, -7, -14, -24,
- -13, -3, -13, -12, 7, 30, 34, 14, 18, -5, -33, -18, -10, -14, 1, 19,
- 14, 6, -8, -13, -15, -2, 19, 40, 8, -13, -9, -4, -8, -18, -20, -9,
- -14, -16, -7, 22, 37, 23, 16, 10, -26, -28, -13, -9, -5, 14, 14, 9,
- -9, -17, -13, -1, 8, 31, 26, -6, -10, -4, -2, -12, -19, -11, -11, -17,
- -12, 6, 34, 29, 15, 16, -7, -35, -25, -9, -6, 8, 14, 12, 1, -15,
- -14, 3, 10, 19, 29, 8, -10, -9, 1, -7, -20, -10, -9, -17, -17, -1,
- 30, 35, 18, 15, 5, -28, -33, -17, -6, -4, 8, 13, 5, -14, -19, 1,
- 14, 14, 20, 17, 0, -8, -2, -3, -14, -18, -9, -12, -18, -6, 21, 37,
- 26, 7, 10, -13, -33, -24, -6, -2, 0, 9, 11, -5, -19, -7, 16, 18,
- 13, 18, 11, -2, -6, -3, -6, -22, -10, -11, -16, -11, 17, 34, 32, 9,
- 9, 2, -26, -30, -14, -2, -5, 3, 8, 3, -16, -12, 8, 21, 13, 13,
- 15, 2, -3, -5, -5, -20, -16, -8, -16, -20, 6, 32, 34, 14, -4, 6,
- -12, -26, -20, -7, -6, -4, 4, 7, -2, -15, 1, 17, 15, 9, 15, 10,
- 0, -3, -7, -15, -22, -4, -7, -19, -7, 29, 36, 20, -6, -1, 0, -17,
- -19, -12, -9, -7, -1, 2, 6, -3, -8, 10, 18, 9, 8, 21, 4, -2,
- -8, -13, -20, -12, -2, -16, -14, 14, 39, 26, -3, -17, 1, -6, -16, -12,
- -7, -9, -9, 0, 3, 11, -3, 0, 15, 13, 3, 19, 12, -8, -6, -14,
- -19, -16, 0, -6, -17, 3, 33, 35, 5, -18, -9, 1, -15, -11, -8, -8,
- -16, -8, 1, 15, 15, 3, 11, 19, 2, 12, 26, 0, -10, -13, -21, -11,
- 1, -1, -18, -2, 23, 35, 17, -12, -21, -2, -8, -9, -8, -9, -12, -17,
- -5, 10, 22, 8, 7, 18, 7, -1, 23, 13, -13, -19, -23, -14, 5, 2,
- -15, -13, 17, 30, 22, -3, -24, -7, -2, -9, -6, -10, -8, -21, -19, 5,
- 22, 22, 13, 15, 13, -3, 11, 18, -4, -20, -28, -20, 4, 11, -10, -18,
- 6, 26, 17, 3, -20, -12, -2, -11, -7, -8, -8, -16, -27, -7, 19, 30,
- 21, 19, 15, 4, 3, 18, 2, -17, -33, -24, 0, 17, 1, -16, -6, 24,
- 19, 5, -17, -18, 1, -8, -12, -7, -11, -10, -22, -14, 10, 29, 29, 32,
- 23, 13, 0, 9, 6, -12, -28, -36, -7, 13, 12, -8, -17, 12, 24, 6,
- -10, -20, 1, 1, -13, -9, -12, -16, -20, -17, 0, 21, 27, 31, 35, 20,
- 7, 0, 2, -13, -19, -37, -19, 8, 18, 9, -16, -9, 20, 11, -2, -25,
- -13, 8, -4, -16, -13, -18, -23, -17, 0, 14, 29, 27, 43, 35, 17, -1,
- -4, -13, -22, -29, -31, -2, 17, 20, -5, -21, 6, 16, 5, -16, -25, 4,
- 11, -12, -17, -20, -27, -19, -2, 13, 26, 27, 36, 46, 32, 7, -8, -18,
- -26, -25, -32, -16, 12, 26, 11, -18, -11, 4, 13, -1, -27, -12, 14, 2,
- -21, -23, -31, -26, -11, 10, 24, 30, 29, 43, 50, 24, -4, -16, -34, -28,
- -28, -27, -1, 27, 24, -5, -21, -12, 6, 16, -13, -28, 1, 13, -9, -23,
- -33, -32, -18, 2, 24, 34, 33, 34, 50, 49, 12, -11, -34, -37, -28, -25,
- -14, 14, 28, 10, -10, -25, -9, 21, 15, -27, -15, 12, 2, -18, -33, -36,
- -24, -7, 13, 30, 39, 42, 35, 54, 36, 1, -29, -45, -35, -26, -17, -1,
- 20, 19, 2, -23, -30, 1, 30, -5, -32, 1, 7, -8, -27, -37, -25, -12,
- -1, 23, 37, 51, 38, 41, 49, 16, -15, -41, -40, -31, -21, -11, 4, 19,
- 15, -8, -33, -19, 22, 20, -21, -13, 2, -6, -17, -36, -32, -11, -8, 9,
- 28, 48, 54, 36, 48, 30, 3, -30, -41, -34, -24, -15, -6, 2, 17, 8,
- -19, -37, 0, 31, 3, -20, -6, -4, -7, -31, -35, -9, -3, -4, 16, 37,
- 62, 44, 41, 33, 13, -11, -36, -39, -29, -21, -11, -11, 6, 14, -2, -28,
- -24, 15, 22, -5, -10, -11, -10, -20, -35, -13, 2, -5, 2, 21, 55, 64,
- 46, 37, 19, 2, -23, -36, -28, -23, -17, -18, -17, 10, 11, -12, -32, -7,
- 23, 16, -7, -14, -17, -8, -27, -23, 1, 1, 0, 6, 31, 63, 60, 46,
- 21, 7, -12, -29, -24, -18, -24, -23, -27, -11, 11, 5, -16, -19, 11, 21,
- 4, -9, -21, -15, -17, -30, -5, 7, 2, -1, 9, 48, 65, 59, 30, 13,
- -4, -25, -19, -6, -22, -33, -32, -31, -3, 7, -3, -20, -4, 14, 11, -1,
- -11, -19, -13, -20, -16, 9, 7, 2, -3, 27, 60, 69, 44, 12, 7, -18,
- -20, 1, -4, -35, -38, -34, -22, -9, 4, -2, -11, 8, 8, 2, -6, -19,
- -23, -14, -16, 3, 13, 2, 2, 12, 47, 65, 62, 22, 10, -3, -21, -9,
- 9, -17, -46, -40, -34, -23, -6, 4, -1, 3, 7, 2, -4, -13, -25, -18,
- -11, -4, 18, 3, -2, 5, 30, 58, 66, 39, 12, 9, -10, -18, 8, 5,
- -41, -49, -38, -33, -18, -4, 2, 7, 8, 2, -7, -12, -18, -23, -12, -6,
- 18, 15, -8, 0, 21, 44, 62, 48, 22, 14, 7, -16, -7, 18, -18, -52,
- -44, -42, -32, -18, -1, 12, 10, 6, -8, -20, -11, -18, -19, -10, 14, 24,
- 2, -5, 14, 34, 57, 51, 27, 19, 20, -1, -13, 15, -1, -42, -45, -49,
- -38, -28, -15, 13, 19, 10, -1, -23, -16, -11, -24, -10, 6, 21, 14, -5,
- 3, 24, 48, 58, 29, 17, 24, 18, -6, 4, 8, -28, -38, -46, -50, -36,
- -29, 3, 22, 15, 4, -18, -31, -7, -20, -17, 5, 11, 18, 4, -2, 15,
- 37, 58, 35, 11, 26, 31, 11, -2, 6, -13, -32, -39, -55, -45, -38, -17,
- 21, 23, 11, -10, -31, -18, -11, -25, 1, 9, 14, 15, 0, 7, 26, 49,
- 49, 13, 10, 33, 26, 8, 4, -5, -25, -35, -46, -53, -41, -35, 5, 24,
- 17, 0, -25, -26, -14, -24, -9, 6, 5, 17, 6, 6, 20, 38, 55, 30,
- 3, 25, 38, 18, 10, -4, -16, -30, -42, -51, -46, -41, -16, 21, 23, 14,
- -16, -30, -16, -17, -17, 0, 2, 12, 16, 3, 17, 28, 46, 49, 14, 13,
- 39, 30, 17, 4, -9, -20, -38, -49, -50, -50, -34, 4, 21, 20, 4, -29,
- -23, -15, -15, -8, -3, 7, 19, 8, 9, 26, 35, 47, 29, 6, 29, 35,
- 26, 13, -5, -18, -29, -42, -49, -51, -50, -16, 11, 23, 18, -17, -34, -14,
- -15, -9, -10, -2, 17, 14, 5, 21, 33, 44, 38, 14, 23, 37, 30, 20,
- 6, -8, -26, -34, -47, -52, -54, -34, 0, 16, 19, 5, -29, -20, -13, -10,
- -9, -10, 4, 19, 11, 13, 29, 37, 36, 22, 22, 39, 32, 23, 10, 2,
- -18, -32, -40, -54, -56, -49, -23, 8, 17, 11, -15, -26, -11, -13, -9, -15,
- -11, 14, 17, 10, 23, 34, 36, 24, 21, 35, 42, 26, 12, 2, -4, -23,
- -31, -47, -57, -50, -33, -7, 17, 11, -2, -18, -12, -12, -11, -10, -21, -6,
- 18, 19, 21, 33, 35, 28, 23, 34, 51, 40, 12, -2, 1, -9, -27, -43,
- -59, -53, -39, -23, 4, 15, 1, -10, -14, -9, -8, -10, -22, -18, 5, 19,
- 16, 27, 34, 28, 23, 27, 47, 53, 27, -3, -4, -1, -13, -33, -53, -57,
- -45, -31, -13, 14, 4, -4, -11, -9, -9, -11, -19, -28, -16, 10, 24, 23,
- 35, 24, 26, 26, 38, 60, 44, 2, -13, -3, -5, -19, -44, -58, -49, -33,
- -26, 1, 14, 1, -4, -5, 0, -7, -14, -29, -26, -11, 20, 27, 30, 32,
- 21, 27, 34, 59, 58, 22, -11, -10, -6, -10, -29, -55, -53, -38, -34, -16,
- 12, 9, -5, -8, 5, 1, -16, -31, -32, -28, 0, 26, 26, 33, 23, 24,
- 33, 49, 61, 37, 3, -15, -8, -11, -19, -43, -56, -44, -34, -25, -2, 17,
- 5, -11, 2, 12, -2, -23, -32, -35, -23, 14, 26, 27, 35, 23, 32, 45,
- 58, 47, 19, -5, -9, -10, -16, -27, -46, -48, -41, -34, -18, 11, 20, -6,
- -10, 12, 9, -18, -34, -38, -29, -7, 17, 27, 32, 30, 30, 46, 52, 51,
- 28, 6, -8, -9, -15, -24, -32, -41, -45, -40, -30, -1, 23, 10, -12, 2,
- 17, -2, -31, -39, -32, -18, -6, 18, 29, 38, 32, 45, 54, 54, 33, 11,
- 2, -9, -11, -19, -32, -33, -41, -45, -40, -18, 16, 19, 2, -6, 13, 12,
- -20, -43, -35, -21, -18, -5, 21, 35, 36, 46, 58, 52, 38, 17, 9, -5,
- -9, -13, -29, -32, -28, -41, -43, -36, 0, 22, 18, -4, -3, 17, 2, -33,
- -43, -25, -18, -16, 4, 27, 38, 47, 64, 57, 40, 18, 10, 5, -7, -10,
- -22, -39, -24, -30, -42, -39, -22, 13, 28, 14, -9, 3, 17, -16, -51, -36,
- -17, -23, -18, 8, 35, 50, 66, 68, 43, 23, 12, 13, -1, -11, -17, -32,
- -27, -22, -40, -38, -37, -10, 22, 34, 1, -10, 8, 6, -39, -48, -27, -19,
- -25, -10, 18, 49, 66, 78, 54, 26, 17, 16, 3, -7, -15, -25, -29, -12,
- -32, -37, -35, -28, 3, 38, 26, -7, -4, 11, -15, -46, -42, -26, -23, -24,
- -2, 34, 66, 81, 70, 30, 19, 21, 10, -5, -11, -25, -29, -12, -20, -37,
- -33, -39, -17, 25, 46, 6, -11, 2, 0, -29, -44, -41, -30, -27, -17, 12,
- 58, 79, 84, 46, 19, 22, 19, 2, -7, -26, -35, -12, -1, -29, -33, -39,
- -36, 3, 46, 31, -11, -6, -1, -14, -38, -46, -39, -32, -22, -5, 40, 76,
- 88, 64, 23, 22, 30, 12, -8, -20, -39, -22, 0, -13, -29, -33, -43, -20,
- 24, 49, 13, -12, 2, -6, -26, -45, -45, -39, -32, -15, 19, 68, 85, 77,
- 32, 22, 35, 27, 0, -18, -36, -38, -6, 3, -17, -29, -44, -37, -2, 40,
- 34, -8, -6, 3, -18, -44, -47, -44, -43, -21, 3, 49, 76, 80, 53, 21,
- 35, 39, 15, -18, -35, -42, -23, 2, -3, -19, -33, -42, -23, 16, 46, 16,
- -8, 2, -6, -37, -45, -47, -51, -33, -8, 31, 68, 74, 66, 33, 35, 45,
- 36, -3, -33, -40, -34, -7, 5, -8, -18, -35, -39, -13, 32, 32, 3, -1,
- 5, -26, -46, -50, -52, -44, -20, 15, 59, 68, 69, 50, 32, 42, 48, 21,
- -26, -42, -42, -24, 2, 2, -8, -20, -38, -35, 6, 33, 17, -2, 5, -6,
- -41, -55, -57, -46, -33, -6, 40, 64, 62, 63, 45, 38, 54, 40, -4, -42,
- -50, -40, -11, 6, -2, -8, -24, -41, -19, 17, 28, 10, 0, 1, -26, -52,
- -64, -51, -40, -23, 19, 54, 56, 61, 60, 38, 52, 55, 24, -30, -50, -47,
- -27, 4, 8, -6, -11, -30, -36, -6, 19, 25, 4, 1, -9, -38, -64, -61,
- -42, -36, 0, 44, 55, 51, 66, 50, 49, 62, 46, -5, -48, -51, -40, -11,
- 11, 4, -14, -15, -36, -25, 1, 19, 15, -1, -2, -18, -53, -69, -48, -42,
- -20, 21, 51, 45, 56, 62, 51, 60, 59, 23, -32, -53, -49, -28, 5, 17,
- -12, -18, -22, -32, -12, 9, 20, 1, -6, -5, -29, -70, -62, -48, -32, 2,
- 36, 45, 44, 62, 62, 60, 64, 47, -10, -45, -54, -42, -11, 21, 5, -19,
- -18, -23, -20, -1, 15, 4, -6, -2, -6, -51, -72, -57, -44, -13, 19, 40,
- 41, 51, 65, 66, 69, 63, 14, -32, -47, -50, -30, 10, 14, -12, -16, -18,
- -16, -14, 7, 8, -6, -8, -1, -21, -65, -67, -54, -29, 1, 26, 38, 44,
- 53, 69, 77, 73, 37, -17, -41, -46, -37, -10, 13, -1, -11, -14, -14, -10,
- -6, 9, -5, -6, -11, -3, -43, -67, -68, -42, -15, 12, 27, 40, 47, 65,
- 80, 83, 55, 7, -34, -43, -34, -22, -5, 2, -3, -2, -13, -10, -11, 3,
- -2, -4, -13, -5, -15, -51, -72, -63, -31, -3, 16, 29, 42, 55, 78, 91,
- 68, 25, -11, -40, -32, -22, -21, -9, -1, 8, -1, -19, -11, -3, 1, -5,
- -11, -12, -3, -29, -58, -70, -48, -18, 6, 15, 35, 50, 68, 89, 84, 37,
- 11, -27, -38, -19, -20, -23, -8, 10, 18, -10, -19, -8, 4, 0, -11, -14,
- -7, -20, -42, -63, -60, -37, -4, 7, 23, 41, 67, 82, 90, 53, 19, -4,
- -34, -23, -20, -31, -22, 5, 25, 8, -17, -20, 0, 10, -5, -20, -9, -12,
- -31, -47, -60, -53, -26, -3, 12, 32, 58, 81, 85, 70, 27, 9, -19, -26,
- -19, -28, -31, -8, 24, 21, -2, -26, -11, 14, 10, -20, -18, -8, -24, -33,
- -53, -56, -44, -23, 3, 22, 44, 77, 85, 74, 40, 17, -3, -21, -21, -24,
- -36, -25, 11, 22, 15, -13, -28, 5, 23, 0, -28, -12, -19, -26, -42, -56,
- -48, -39, -17, 12, 34, 62, 84, 73, 52, 26, 9, -12, -21, -22, -31, -30,
- -1, 15, 16, 6, -25, -14, 23, 19, -17, -21, -13, -24, -34, -54, -44, -39,
- -36, -9, 27, 46, 79, 79, 59, 38, 16, -2, -17, -25, -25, -27, -10, 5,
- 10, 15, -4, -24, 5, 29, 5, -24, -18, -19, -28, -48, -50, -35, -38, -28,
- 10, 33, 62, 82, 62, 46, 27, 4, -8, -23, -24, -25, -15, -3, 0, 8,
- 6, -12, -9, 22, 25, -6, -21, -22, -28, -45, -53, -39, -30, -37, -11, 20,
- 43, 75, 66, 53, 41, 10, -8, -16, -25, -23, -15, -2, -4, -5, 4, 1,
- -7, 8, 29, 19, -9, -21, -24, -42, -55, -48, -30, -31, -19, 5, 23, 61,
- 74, 58, 53, 26, -7, -11, -18, -25, -14, 0, 1, -16, -8, 4, 0, 3,
- 20, 28, 11, -16, -19, -38, -58, -55, -35, -27, -16, -1, 5, 32, 63, 61,
- 56, 44, 3, -17, -13, -22, -19, -4, 5, -8, -21, -6, 7, 8, 12, 25,
- 25, 2, -17, -26, -54, -64, -47, -32, -11, 5, 3, 16, 40, 60, 58, 56,
- 26, -16, -19, -16, -20, -8, 0, -4, -20, -22, 1, 12, 9, 17, 30, 20,
- -2, -15, -42, -68, -57, -44, -19, 11, 6, 10, 19, 42, 58, 58, 45, 6,
- -23, -18, -13, -13, -3, -3, -10, -26, -14, 9, 15, 12, 26, 27, 10, -7,
- -25, -61, -68, -54, -36, 10, 15, 13, 16, 19, 42, 55, 52, 31, -9, -25,
- -18, -15, -7, -3, -9, -23, -26, -2, 15, 19, 19, 26, 18, 7, -10, -41,
- -72, -60, -51, -8, 25, 22, 20, 13, 19, 45, 51, 44, 19, -15, -28, -15,
- -7, -4, -9, -19, -28, -14, 6, 18, 18, 24, 22, 12, 1, -17, -55, -67,
- -56, -35, 19, 33, 30, 20, 9, 23, 44, 48, 39, 6, -22, -25, -9, -8,
- -9, -15, -29, -21, -3, 10, 16, 20, 23, 13, 7, -4, -31, -63, -61, -50,
- -11, 33, 37, 30, 12, 7, 24, 44, 48, 28, -4, -28, -14, -4, -14, -14,
- -27, -27, -8, 5, 13, 15, 19, 19, 11, 3, -12, -44, -64, -58, -31, 17,
- 40, 39, 24, 8, 3, 30, 46, 42, 16, -18, -21, -6, -16, -18, -26, -32,
- -15, 1, 6, 10, 10, 15, 12, 10, -3, -23, -51, -63, -50, -4, 34, 41,
- 33, 17, -4, 10, 35, 42, 32, 5, -15, -8, -10, -18, -21, -30, -22, 0,
- 3, -2, -2, 6, 5, 4, 3, -7, -25, -45, -45, -18, 25, 33, 32, 21,
- 7, 8, 20, 30, 31, 20, 3, -7, -10, -14, -17, -23, -29, -12, 6, -2,
- -11, -11, -4, 2, 3, -7, -10, -27, -33, -21, 13, 27, 23, 19, 8, 15,
- 17, 18, 21, 23, 19, 2, -12, -10, -9, -15, -27, -28, -2, 9, -8, -18,
- -17, -4, 9, -6, -7, -10, -17, -13, 2, 21, 20, 14, 4, 15, 25, 15,
- 11, 14, 19, 13, -13, -17, -6, -5, -20, -36, -23, 4, 6, -18, -28, -20,
- 6, 6, 0, 3, 5, 5, 28, 31, 31, 49, 55, 35, 11, 27, 26, 4,
- 7, 11, 31, 54, 38, 26, 34, 35, 20, -10, -32, -43, -47, -43, -20, -7,
- -37, -55, -62, -61, -63, -34, -21, -35, -28, -10, 15, 24, 23, 5, -31, -38,
- -6, 23, 19, 15, 24, 20, 31, 57, 54, 28, 13, 33, 20, 1, 4, 17,
- 38, 44, 33, 31, 43, 36, 10, -14, -34, -53, -53, -46, -22, -22, -38, -46,
- -54, -60, -58, -29, -25, -39, -29, -12, 11, 25, 27, 6, -31, -33, -3, 27,
- 32, 21, 13, 16, 38, 60, 53, 26, 18, 28, 11, -2, 8, 26, 37, 34,
- 36, 42, 47, 31, 6, -14, -41, -61, -54, -49, -26, -30, -41, -40, -44, -54,
- -48, -23, -28, -41, -33, -7, 14, 26, 29, 3, -32, -27, 6, 33, 35, 18,
- 5, 21, 45, 61, 49, 25, 30, 22, 0, -5, 9, 37, 39, 27, 33, 47,
- 50, 31, 1, -22, -51, -65, -59, -45, -31, -40, -36, -29, -35, -49, -41, -28,
- -39, -44, -26, -8, 6, 27, 31, -5, -31, -18, 14, 33, 31, 17, 4, 25,
- 48, 57, 45, 32, 27, 9, -6, -5, 14, 43, 36, 29, 39, 51, 50, 31,
- 0, -32, -65, -73, -62, -37, -36, -46, -36, -23, -26, -37, -32, -35, -46, -42,
- -22, -11, 2, 30, 28, -8, -29, -12, 22, 33, 32, 15, 4, 25, 49, 58,
- 50, 36, 20, 2, -9, -3, 21, 43, 37, 32, 44, 55, 53, 33, -7, -42,
- -67, -72, -64, -43, -43, -46, -35, -17, -17, -24, -31, -40, -47, -39, -18, -15,
- 0, 33, 22, -14, -22, 5, 29, 29, 28, 11, 7, 23, 49, 54, 50, 37,
- 13, -6, -11, -6, 25, 44, 38, 26, 40, 57, 54, 28, -12, -48, -70, -73,
- -66, -43, -43, -43, -29, -12, -15, -16, -32, -48, -51, -38, -24, -19, 4, 31,
- 12, -16, -14, 21, 34, 24, 24, 13, 10, 27, 49, 53, 53, 33, 6, -9,
- -16, -4, 33, 48, 37, 24, 45, 61, 54, 23, -15, -60, -76, -76, -60, -48,
- -45, -38, -26, -11, -3, -5, -33, -49, -52, -35, -25, -21, 7, 24, 1, -15,
- -1, 34, 30, 23, 29, 17, 5, 26, 49, 55, 53, 26, -3, -16, -16, 4,
- 38, 43, 33, 33, 49, 59, 45, 19, -18, -63, -78, -79, -58, -50, -39, -31,
- -21, -11, -2, -3, -30, -49, -51, -35, -29, -20, 8, 12, -10, -11, 17, 37,
- 27, 29, 29, 13, 2, 33, 56, 55, 38, 18, -7, -19, -17, 13, 40, 42,
- 33, 35, 52, 58, 40, 10, -28, -68, -84, -78, -56, -47, -36, -30, -17, -7,
- 5, -4, -30, -49, -51, -34, -30, -18, 10, 1, -18, -9, 30, 39, 26, 32,
- 28, 9, 7, 38, 51, 45, 35, 16, -13, -28, -11, 27, 41, 41, 34, 45,
- 58, 54, 29, 7, -33, -69, -80, -78, -59, -43, -31, -24, -15, -3, 9, -4,
- -29, -51, -51, -33, -27, -8, 8, -13, -24, -1, 40, 41, 29, 31, 22, 7,
- 15, 46, 48, 38, 33, 11, -19, -28, -7, 26, 42, 36, 39, 54, 54, 48,
- 20, 3, -39, -68, -79, -78, -54, -37, -32, -27, -16, 5, 11, -6, -31, -50,
- -49, -33, -24, -3, -3, -29, -26, 13, 44, 36, 30, 32, 17, 7, 28, 43,
- 37, 31, 28, 4, -17, -27, -5, 24, 46, 43, 48, 56, 50, 41, 20, -1,
- -47, -64, -82, -78, -48, -35, -34, -26, -14, 6, 9, -10, -31, -46, -43, -33,
- -21, 1, -16, -38, -15, 24, 38, 35, 44, 33, 10, 15, 37, 43, 30, 22,
- 18, 4, -20, -29, 0, 30, 43, 48, 54, 52, 46, 35, 19, -9, -41, -60,
- -83, -73, -44, -29, -37, -27, -12, 6, 8, -10, -28, -45, -43, -25, -9, -3,
- -33, -43, -4, 32, 35, 37, 49, 24, 7, 26, 47, 35, 17, 11, 14, 3,
- -21, -30, 6, 30, 44, 60, 56, 44, 37, 33, 15, -11, -40, -63, -82, -61,
- -36, -33, -39, -26, -13, 0, 4, -9, -29, -42, -37, -18, -7, -13, -39, -34,
- 2, 30, 34, 45, 49, 16, 11, 37, 45, 26, 11, 8, 9, -1, -26, -25,
- 17, 31, 46, 62, 52, 42, 29, 26, 15, -12, -45, -64, -71, -48, -34, -35,
- -33, -27, -16, 1, 2, -10, -23, -41, -32, -12, -6, -29, -46, -28, 12, 26,
- 36, 54, 43, 10, 23, 52, 43, 18, -2, 5, 5, -7, -25, -11, 19, 22,
- 49, 61, 50, 40, 24, 20, 15, -10, -47, -62, -62, -45, -34, -30, -30, -23,
- -16, -6, -1, -8, -25, -38, -29, -9, -10, -39, -42, -19, 5, 23, 48, 57,
- 33, 7, 32, 57, 39, 8, -7, 3, -2, -16, -16, 1, 20, 22, 48, 55,
- 46, 39, 17, 16, 17, -9, -48, -58, -54, -40, -37, -28, -26, -22, -23, -5,
- 2, -11, -28, -37, -27, -10, -18, -44, -35, -18, 3, 31, 54, 52, 25, 13,
- 45, 61, 29, -4, -10, 0, -5, -16, -8, 4, 21, 21, 50, 54, 45, 31,
- 4, 20, 18, -15, -43, -48, -48, -39, -33, -28, -25, -22, -21, 0, -1, -19,
- -29, -29, -22, -11, -29, -42, -30, -17, 3, 38, 61, 46, 24, 25, 53, 58,
- 20, -10, -9, -5, -16, -12, 4, 11, 22, 17, 48, 51, 43, 16, 2, 18,
- 13, -15, -35, -46, -43, -38, -31, -23, -27, -24, -13, 3, -8, -25, -29, -27,
- -22, -18, -36, -38, -31, -19, 6, 46, 60, 36, 24, 33, 56, 44, 10, -8,
- -9, -12, -24, -7, 14, 23, 18, 11, 45, 47, 39, 13, 5, 16, 1, -19,
- -22, -39, -45, -45, -31, -20, -24, -16, -6, -3, -19, -24, -25, -26, -22, -24,
- -39, -35, -25, -13, 8, 54, 64, 36, 29, 41, 56, 36, 5, -12, -11, -14,
- -26, -6, 24, 33, 7, 12, 45, 44, 30, 13, 10, 17, -4, -17, -16, -34,
- -46, -50, -30, -20, -23, -12, 1, -11, -26, -27, -24, -21, -19, -34, -48, -32,
- -23, -10, 13, 66, 65, 33, 32, 48, 55, 25, 0, -8, -1, -18, -36, -4,
- 40, 33, -1, 17, 37, 35, 25, 10, 14, 10, -13, -15, -9, -26, -46, -51,
- -32, -18, -15, -4, 3, -17, -31, -28, -25, -20, -26, -48, -48, -27, -20, -13,
- 19, 71, 61, 28, 33, 56, 50, 12, -8, -2, 5, -24, -41, 2, 52, 29,
- -1, 24, 36, 26, 16, 14, 19, 6, -19, -12, 1, -21, -49, -50, -28, -12,
- -3, 2, -2, -25, -32, -29, -24, -14, -31, -61, -44, -17, -15, -9, 28, 72,
- 61, 25, 38, 61, 41, 7, -7, 4, 3, -32, -36, 9, 45, 21, 4, 30,
- 33, 15, 11, 18, 17, -1, -18, -7, -4, -22, -47, -45, -24, -6, 2, 5,
- -7, -27, -34, -28, -21, -14, -42, -69, -40, -11, -16, -3, 41, 68, 53, 29,
- 48, 61, 32, 0, -5, 8, 2, -33, -28, 9, 31, 16, 16, 34, 22, 0,
- 10, 24, 10, -9, -19, -6, -8, -26, -38, -34, -20, -10, 1, 11, -9, -33,
- -31, -32, -25, -18, -50, -65, -40, -15, -8, 13, 47, 65, 50, 33, 54, 62,
- 24, -2, 2, 12, -6, -31, -20, 12, 21, 10, 28, 34, 9, -5, 20, 20,
- -2, -13, -10, -4, -18, -33, -26, -16, -19, -14, 6, 8, -14, -31, -32, -29,
- -29, -31, -51, -69, -47, -12, 2, 21, 49, 56, 43, 45, 62, 54, 16, -2,
- 7, 9, -13, -22, -4, 12, 7, 13, 37, 33, 7, -4, 23, 9, -8, -8,
- -2, -8, -33, -38, -7, -1, -22, -19, 11, 7, -21, -29, -29, -29, -31, -32,
- -55, -80, -49, -7, 16, 31, 43, 45, 44, 56, 66, 45, 12, 2, 10, 3,
- -18, -13, 7, 9, -2, 17, 38, 22, 1, 5, 17, 4, -14, -12, -1, -11,
- -43, -38, 6, 5, -22, -15, 12, 0, -23, -26, -28, -31, -32, -36, -60, -82,
- -46, 3, 24, 35, 38, 41, 46, 59, 62, 41, 13, -1, 3, -6, -18, 3,
- 22, 2, -9, 20, 36, 18, 10, 7, 4, -5, -17, -9, -2, -18, -55, -30,
- 17, 6, -20, -10, 6, -5, -16, -26, -32, -27, -30, -42, -69, -84, -41, 13,
- 31, 42, 37, 38, 45, 63, 65, 41, 12, 3, 1, -18, -10, 23, 27, -2,
- -12, 17, 36, 26, 13, 4, -2, -5, -14, -14, -11, -26, -54, -19, 21, 8,
- -16, -8, 6, -7, -20, -30, -33, -24, -33, -50, -74, -82, -32, 18, 34, 42,
- 38, 34, 50, 69, 58, 34, 16, 7, -9, -29, -2, 41, 32, -7, -15, 11,
- 34, 30, 9, 2, -3, -7, -23, -21, -15, -30, -52, -10, 18, 10, -8, -4,
- 5, -4, -25, -33, -26, -22, -42, -59, -79, -72, -20, 23, 36, 41, 37, 34,
- 54, 74, 53, 22, 17, 15, -17, -34, 10, 52, 37, -8, -11, 12, 33, 23,
- 8, 4, -1, -16, -31, -25, -18, -38, -49, -3, 19, 11, -4, 0, 7, -8,
- -34, -31, -19, -26, -52, -62, -79, -55, -7, 23, 41, 47, 41, 33, 61, 75,
- 43, 22, 21, 13, -26, -33, 17, 58, 39, -6, -8, 13, 27, 10, 5, 13,
- -2, -32, -43, -32, -19, -38, -36, -3, 12, 4, 4, 13, 6, -22, -41, -31,
- -13, -33, -59, -71, -76, -35, 2, 20, 39, 53, 47, 39, 60, 62, 37, 26,
- 22, 5, -33, -29, 26, 64, 40, 0, -5, 12, 21, 8, 16, 10, -13, -39,
- -49, -37, -25, -41, -30, -6, 9, 9, 13, 23, 0, -30, -44, -26, -13, -45,
- -67, -76, -68, -20, 10, 19, 39, 55, 50, 46, 57, 50, 37, 30, 16, -3,
- -34, -22, 34, 65, 40, 13, -2, 6, 19, 12, 21, 5, -23, -49, -52, -38,
- -33, -36, -24, -9, 10, 12, 25, 23, -11, -29, -43, -27, -21, -55, -73, -77,
- -50, -2, 19, 19, 35, 59, 59, 49, 45, 40, 36, 27, 4, -10, -24, -12,
- 31, 59, 44, 22, -5, 4, 19, 20, 12, -4, -27, -52, -50, -45, -39, -24,
- -23, -13, 16, 20, 30, 15, -16, -28, -37, -30, -36, -64, -79, -73, -28, 17,
- 24, 14, 36, 65, 68, 45, 33, 39, 40, 22, -2, -5, -11, -11, 28, 58,
- 57, 20, -13, 0, 27, 23, 1, -15, -35, -58, -55, -52, -39, -20, -22, -9,
- 20, 29, 30, 10, -15, -31, -39, -32, -48, -72, -86, -59, -4, 27, 19, 17,
- 44, 77, 69, 31, 26, 40, 38, 14, -6, 0, 1, -11, 26, 67, 62, 10,
- -18, 6, 31, 20, -5, -22, -44, -66, -61, -50, -31, -17, -24, -7, 24, 34,
- 31, 3, -17, -31, -36, -40, -61, -73, -76, -46, 11, 34, 20, 22, 56, 83,
- 60, 22, 24, 46, 32, 5, -4, 9, 0, -8, 31, 73, 53, 0, -13, 16,
- 28, 14, -15, -31, -51, -74, -64, -43, -25, -22, -25, -1, 30, 37, 20, -2,
- -20, -36, -39, -55, -69, -75, -69, -32, 21, 36, 22, 31, 63, 76, 50, 22,
- 25, 49, 29, 3, 4, 9, 2, 0, 43, 74, 37, -8, -1, 28, 24, 8,
- -22, -42, -65, -80, -60, -31, -25, -31, -24, 8, 41, 37, 10, -3, -22, -40,
- -45, -60, -69, -69, -55, -15, 32, 37, 25, 42, 72, 70, 37, 21, 32, 41,
- 20, 5, 15, 8, 0, 9, 46, 62, 26, -7, 8, 28, 21, 4, -29, -53,
- -79, -82, -57, -25, -27, -32, -21, 14, 48, 35, -1, -7, -24, -44, -52, -70,
- -69, -60, -38, 1, 34, 33, 32, 57, 70, 58, 34, 26, 31, 31, 16, 14,
- 14, 3, 8, 25, 47, 47, 18, -2, 13, 25, 19, -2, -33, -64, -87, -83,
- -53, -24, -29, -32, -17, 21, 46, 27, -4, -12, -30, -51, -61, -73, -60, -46,
- -17, 9, 25, 32, 47, 69, 61, 48, 41, 30, 26, 24, 18, 24, 15, 2,
- 14, 37, 42, 34, 17, 9, 19, 20, 11, -7, -35, -79, -97, -79, -45, -21,
- -29, -33, -12, 26, 43, 27, -3, -15, -43, -58, -66, -69, -52, -37, -2, 16,
- 24, 38, 61, 72, 56, 43, 41, 32, 28, 22, 22, 26, 12, 1, 23, 45,
- 34, 21, 8, 17, 22, 19, 4, -18, -47, -93, -97, -70, -40, -29, -33, -22,
- -5, 24, 44, 19, -6, -23, -53, -60, -74, -63, -41, -20, 10, 18, 19, 40,
- 70, 70, 47, 41, 43, 37, 27, 14, 24, 32, 10, 1, 29, 44, 27, 12,
- 7, 28, 32, 9, -11, -27, -56, -100, -94, -64, -43, -38, -31, -7, 0, 27,
- 41, 11, -7, -35, -60, -62, -75, -54, -29, -5, 17, 22, 14, 46, 80, 72,
- 46, 42, 44, 42, 24, 16, 31, 32, 9, 4, 33, 45, 22, 5, 8, 41,
- 34, 0, -22, -36, -69, -100, -92, -65, -40, -44, -25, 0, 5, 28, 36, 4,
- -12, -50, -64, -64, -68, -46, -19, 2, 25, 28, 19, 44, 72, 67, 46, 45,
- 44, 39, 21, 21, 38, 29, 1, 9, 39, 39, 13, -4, 9, 54, 41, -11,
- -38, -51, -76, -91, -92, -65, -44, -47, -17, 12, 11, 21, 27, 6, -24, -59,
- -65, -67, -61, -40, -17, 8, 31, 26, 20, 49, 74, 65, 45, 48, 47, 36,
- 25, 28, 36, 25, 5, 19, 42, 28, 6, -2, 21, 56, 27, -22, -45, -62,
- -83, -92, -84, -65, -49, -37, -8, 15, 16, 22, 23, -1, -38, -65, -66, -65,
- -51, -35, -15, 20, 42, 26, 25, 51, 70, 60, 45, 52, 47, 25, 25, 39,
- 33, 24, 16, 31, 37, 14, 3, 2, 33, 55, 14, -35, -55, -67, -84, -88,
- -84, -68, -47, -28, -1, 17, 22, 24, 17, -14, -54, -66, -64, -61, -46, -32,
- -10, 26, 45, 24, 29, 52, 66, 57, 49, 56, 41, 16, 29, 46, 31, 22,
- 24, 37, 30, 12, -1, 5, 40, 39, 1, -41, -63, -72, -89, -89, -77, -62,
- -48, -17, 5, 13, 26, 31, 10, -29, -62, -64, -65, -54, -41, -25, -4, 32,
- 52, 29, 32, 55, 61, 55, 56, 57, 35, 17, 33, 40, 28, 27, 37, 36,
- 26, 14, -3, 13, 41, 22, -13, -45, -65, -78, -90, -87, -70, -56, -47, -12,
- 9, 18, 35, 27, -5, -41, -63, -61, -65, -52, -37, -17, 5, 35, 52, 34,
- 38, 55, 58, 53, 60, 54, 31, 21, 33, 34, 30, 35, 40, 32, 29, 15,
- -4, 18, 30, 11, -25, -53, -69, -85, -91, -82, -66, -54, -36, -7, 6, 20,
- 40, 19, -17, -52, -63, -60, -65, -50, -32, -11, 9, 34, 50, 40, 46, 51,
- 56, 60, 60, 50, 28, 23, 33, 33, 31, 40, 43, 38, 38, 13, -6, 13,
- 19, -2, -34, -57, -78, -91, -85, -73, -63, -55, -28, -1, 6, 26, 39, 13,
- -28, -56, -61, -55, -61, -43, -27, -13, 12, 38, 48, 49, 54, 46, 52, 64,
- 64, 48, 27, 22, 28, 33, 36, 44, 42, 39, 44, 15, -3, 10, 6, -19,
- -46, -60, -81, -92, -83, -73, -52, -44, -22, -5, 5, 38, 37, -6, -41, -55,
- -54, -49, -53, -45, -28, -9, 19, 41, 47, 56, 57, 41, 56, 69, 64, 42,
- 26, 23, 27, 36, 39, 44, 39, 48, 53, 12, -4, 2, -8, -33, -61, -72,
- -84, -87, -80, -73, -49, -36, -12, -5, 9, 42, 24, -15, -44, -50, -51, -51,
- -51, -45, -26, -4, 20, 40, 47, 64, 58, 38, 61, 71, 55, 37, 32, 23,
- 30, 34, 39, 50, 43, 58, 53, 9, 4, -3, -27, -49, -71, -79, -79, -79,
- -82, -70, -44, -26, -7, -5, 16, 36, 9, -18, -40, -47, -49, -45, -42, -43,
- -20, 1, 21, 40, 53, 72, 54, 36, 64, 66, 41, 30, 36, 26, 28, 31,
- 44, 57, 48, 62, 45, 13, 3, -14, -47, -65, -77, -87, -78, -71, -75, -68,
- -43, -16, -2, -1, 18, 20, -4, -18, -37, -46, -50, -36, -39, -46, -15, 7,
- 23, 41, 62, 72, 49, 41, 69, 59, 33, 29, 38, 24, 28, 31, 52, 59,
- 49, 61, 45, 21, 2, -31, -64, -73, -78, -89, -79, -71, -77, -62, -36, -8,
- 3, 5, 15, 5, -10, -17, -34, -49, -50, -27, -37, -43, -12, 14, 25, 45,
- 67, 68, 48, 48, 64, 48, 27, 33, 41, 25, 24, 32, 64, 66, 51, 62,
- 41, 21, -7, -43, -77, -81, -83, -87, -74, -71, -77, -54, -29, -1, 7, 13,
- 12, -6, -9, -18, -38, -54, -44, -21, -37, -41, -8, 16, 28, 53, 73, 61,
- 46, 52, 60, 35, 25, 34, 38, 20, 25, 42, 73, 62, 60, 58, 39, 22,
- -19, -54, -85, -88, -95, -88, -65, -69, -73, -47, -22, 3, 14, 15, -5, -14,
- -6, -23, -42, -52, -34, -19, -42, -38, 0, 18, 30, 62, 76, 61, 49, 52,
- 49, 26, 23, 34, 33, 22, 21, 50, 78, 68, 66, 47, 40, 22, -23, -66,
- -95, -102, -97, -74, -61, -77, -68, -36, -12, 9, 15, 13, -18, -14, -5, -31,
- -50, -44, -21, -25, -49, -25, 8, 16, 30, 70, 82, 56, 45, 55, 39, 21,
- 25, 31, 24, 21, 28, 64, 81, 68, 64, 47, 44, 15, -30, -77, -101, -104,
- -96, -71, -66, -76, -53, -22, -9, 6, 22, 10, -22, -15, -13, -38, -48, -32,
- -9, -33, -49, -14, 10, 11, 37, 77, 85, 51, 44, 48, 30, 18, 21, 26,
- 16, 21, 36, 71, 76, 73, 68, 48, 35, 4, -38, -81, -103, -109, -91, -67,
- -71, -69, -40, -15, -12, 3, 23, 7, -23, -17, -24, -41, -45, -24, -11, -46,
- -46, -1, 10, 8, 49, 84, 83, 48, 50, 48, 27, 16, 18, 20, 14, 26,
- 44, 72, 75, 82, 71, 47, 26, -6, -45, -80, -107, -110, -88, -70, -69, -58,
- -28, -9, -12, 2, 23, 2, -21, -19, -35, -38, -33, -13, -17, -50, -35, 8,
- 9, 10, 57, 89, 74, 45, 52, 41, 24, 15, 11, 14, 13, 22, 54, 72,
- 74, 86, 72, 41, 13, -14, -47, -86, -113, -111, -88, -72, -67, -42, -18, -11,
- -11, 2, 18, -2, -17, -27, -44, -37, -28, -12, -26, -49, -22, 9, 3, 21,
- 69, 87, 63, 46, 49, 36, 24, 13, 11, 11, 8, 26, 64, 68, 76, 89,
- 74, 38, 3, -17, -44, -86, -117, -114, -86, -65, -58, -38, -19, -7, 0, 8,
- 9, -5, -20, -37, -45, -29, -19, -15, -36, -39, -10, 6, 4, 33, 79, 81,
- 55, 48, 42, 30, 23, 10, 13, 10, 3, 27, 62, 60, 76, 88, 68, 30,
- -5, -21, -49, -89, -120, -115, -81, -54, -46, -34, -14, -1, 7, 9, 1, -6,
- -18, -45, -52, -29, -16, -17, -35, -36, -12, 5, 11, 47, 81, 72, 53, 51,
- 39, 28, 24, 9, 13, 7, 5, 36, 57, 55, 82, 90, 62, 31, -10, -29,
- -55, -91, -121, -115, -76, -47, -38, -34, -13, 1, 13, 9, -4, -9, -17, -49,
- -56, -26, -9, -12, -33, -40, -17, 12, 25, 57, 71, 62, 52, 50, 35, 22,
- 21, 14, 11, -2, 10, 41, 50, 48, 85, 87, 66, 29, -15, -34, -64, -97,
- -121, -108, -73, -43, -37, -28, -7, 7, 16, 6, -7, -5, -15, -59, -56, -19,
- -4, -14, -37, -42, -10, 21, 38, 66, 63, 57, 52, 49, 28, 22, 28, 16,
- 5, -3, 22, 47, 38, 45, 79, 85, 68, 23, -16, -34, -70, -100, -122, -107,
- -62, -39, -38, -25, -4, 15, 18, 2, -3, 0, -27, -70, -51, -17, -3, -16,
- -44, -40, -1, 27, 45, 67, 57, 54, 48, 39, 17, 18, 28, 17, 3, -3,
- 27, 49, 37, 42, 69, 86, 66, 16, -17, -37, -72, -99, -117, -101, -55, -39,
- -36, -24, 1, 20, 13, 4, 4, -5, -46, -74, -43, -9, -4, -28, -49, -33,
- 6, 33, 63, 68, 54, 53, 49, 33, 18, 21, 24, 15, 7, 9, 33, 42,
- 35, 39, 70, 85, 55, 10, -16, -40, -75, -98, -113, -92, -47, -38, -35, -21,
- 1, 21, 15, 8, 7, -14, -62, -70, -30, -11, -15, -34, -49, -23, 9, 39,
- 64, 58, 51, 56, 42, 20, 16, 19, 16, 16, 4, 13, 40, 46, 33, 31,
- 65, 83, 49, 3, -24, -41, -73, -98, -105, -77, -45, -41, -30, -13, 7, 19,
- 12, 13, 8, -26, -68, -61, -22, -14, -25, -38, -40, -18, 12, 47, 68, 59,
- 49, 51, 42, 19, 17, 17, 12, 13, 5, 18, 41, 47, 26, 26, 67, 78,
- 44, -2, -31, -47, -71, -97, -96, -67, -44, -42, -29, -11, 13, 21, 13, 17,
- 8, -34, -68, -54, -17, -18, -36, -43, -35, -12, 14, 50, 69, 56, 49, 44,
- 35, 16, 13, 17, 13, 13, 6, 27, 46, 50, 24, 28, 66, 64, 28, 0,
- -25, -49, -75, -99, -87, -54, -42, -38, -28, -8, 20, 19, 11, 17, 1, -41,
- -62, -49, -18, -27, -41, -39, -29, -8, 15, 55, 73, 55, 42, 42, 33, 16,
- 12, 12, 9, 6, 14, 40, 52, 48, 21, 31, 60, 50, 23, 0, -32, -60,
- -76, -90, -73, -44, -39, -36, -32, 1, 29, 20, 6, 13, -3, -41, -53, -43,
- -21, -34, -47, -38, -22, -2, 22, 54, 65, 49, 38, 42, 32, 17, 12, 7,
- 6, 3, 21, 48, 53, 42, 24, 39, 53, 38, 15, -3, -38, -65, -76, -85,
- -59, -36, -35, -40, -26, 15, 26, 12, 6, 10, -12, -40, -49, -33, -26, -41,
- -53, -36, -12, 5, 28, 50, 61, 46, 34, 37, 31, 20, 12, 1, 0, 5,
- 32, 53, 56, 41, 23, 39, 48, 35, 13, -10, -44, -72, -81, -79, -50, -27,
- -34, -41, -18, 20, 27, 12, 5, 1, -19, -36, -40, -22, -34, -50, -55, -33,
- -3, 14, 33, 52, 54, 35, 27, 36, 37, 25, 7, -13, 1, 19, 41, 50,
- 50, 38, 32, 43, 41, 32, 6, -17, -46, -69, -79, -75, -43, -20, -34, -38,
- -8, 23, 26, 12, 6, -8, -23, -30, -30, -23, -46, -56, -52, -29, 6, 23,
- 35, 44, 47, 31, 25, 33, 40, 26, -4, -22, 3, 28, 39, 40, 50, 40,
- 28, 34, 37, 28, 0, -22, -50, -70, -81, -72, -34, -22, -36, -33, 2, 24,
- 25, 12, 4, -15, -24, -26, -25, -23, -46, -56, -50, -24, 10, 33, 36, 40,
- 35, 21, 25, 43, 47, 25, -13, -25, 11, 40, 36, 40, 56, 38, 27, 31,
- 33, 24, -4, -24, -53, -71, -80, -59, -34, -27, -31, -27, 8, 24, 25, 17,
- 2, -22, -25, -26, -19, -24, -51, -58, -40, -9, 14, 37, 36, 35, 27, 14,
- 28, 48, 46, 19, -19, -24, 18, 40, 29, 41, 50, 29, 29, 27, 33, 18,
- -12, -29, -53, -71, -75, -48, -33, -32, -25, -14, 13, 24, 19, 17, 2, -25,
- -28, -28, -18, -28, -55, -59, -30, -3, 20, 41, 34, 24, 15, 15, 36, 49,
- 39, 17, -17, -17, 22, 41, 33, 45, 38, 26, 30, 24, 27, 10, -11, -34,
- -58, -70, -66, -38, -32, -36, -21, -2, 14, 28, 19, 14, 0, -25, -29, -28,
- -17, -30, -57, -51, -22, 3, 23, 39, 34, 15, 11, 17, 38, 46, 39, 15,
- -18, -14, 27, 40, 37, 45, 32, 28, 30, 29, 28, 1, -16, -38, -55, -65,
- -62, -37, -31, -34, -17, 9, 18, 27, 18, 9, -1, -22, -35, -29, -17, -32,
- -57, -45, -17, 15, 30, 30, 25, 8, 10, 19, 35, 46, 37, 4, -19, -8,
- 31, 33, 33, 42, 28, 22, 24, 29, 23, -6, -21, -43, -54, -59, -55, -32,
- -34, -39, -10, 19, 30, 25, 9, 2, -2, -20, -38, -30, -23, -41, -51, -35,
- -12, 24, 32, 22, 12, 8, 16, 23, 32, 48, 33, 1, -16, 0, 29, 30,
- 33, 36, 24, 23, 22, 33, 14, -14, -20, -42, -55, -50, -44, -27, -38, -41,
- -3, 31, 35, 23, 5, -2, -4, -15, -34, -33, -38, -47, -40, -26, -3, 31,
- 31, 9, 2, 13, 14, 20, 38, 53, 27, -6, -14, 11, 30, 23, 32, 28,
- 25, 22, 24, 32, 5, -20, -26, -45, -49, -40, -36, -37, -48, -40, 8, 40,
- 37, 16, -3, -6, -2, -9, -27, -42, -52, -48, -32, -21, 8, 39, 28, -2,
- -5, 13, 17, 23, 40, 45, 19, -4, -3, 18, 15, 19, 33, 30, 29, 22,
- 21, 22, 0, -17, -27, -46, -48, -33, -31, -38, -53, -33, 23, 43, 31, 11,
- -7, -5, -3, -8, -26, -49, -59, -48, -25, -14, 15, 41, 23, -8, -6, 11,
- 10, 26, 49, 41, 12, 0, 10, 19, 4, 22, 31, 25, 25, 24, 20, 12,
- -4, -10, -37, -50, -37, -23, -26, -43, -55, -18, 34, 41, 28, 10, -9, -6,
- -3, -8, -27, -57, -62, -37, -15, -8, 24, 44, 23, -10, -6, 3, 8, 39,
- 55, 30, 12, 11, 20, 8, 3, 27, 26, 20, 21, 24, 19, -1, -10, -14,
- -42, -47, -25, -14, -28, -49, -50, -5, 38, 38, 23, 9, -11, -9, -1, -5,
- -33, -64, -59, -34, -14, -2, 32, 49, 17, -11, -6, -2, 11, 46, 46, 19,
- 16, 23, 24, -3, 3, 29, 29, 16, 17, 22, 11, -12, -12, -18, -50, -43,
- -15, -11, -30, -53, -38, 10, 31, 31, 25, 3, -16, -3, 3, -8, -41, -67,
- -53, -24, -14, 3, 35, 46, 17, -2, -7, -9, 16, 49, 41, 20, 22, 34,
- 21, -5, 5, 31, 29, 12, 14, 18, 8, -22, -17, -20, -52, -38, -13, -19,
- -32, -48, -25, 11, 23, 29, 26, 1, -14, 1, 1, -18, -47, -60, -47, -31,
- -11, 13, 45, 39, 8, -2, -2, -11, 16, 43, 35, 25, 34, 40, 18, -7,
- 6, 34, 28, 14, 7, 11, 2, -23, -25, -29, -51, -30, -11, -24, -38, -40,
- -15, 9, 18, 29, 32, -1, -10, 0, -9, -27, -48, -52, -46, -30, -2, 27,
- 47, 30, 10, 7, -6, -15, 12, 35, 28, 30, 45, 42, 19, -4, 11, 29,
- 21, 6, 1, 3, -3, -27, -31, -34, -40, -22, -18, -31, -35, -30, -18, 5,
- 19, 32, 28, -9, -7, 1, -14, -30, -42, -45, -47, -28, 7, 38, 45, 23,
- 14, 20, -2, -24, 7, 32, 30, 37, 43, 41, 22, 7, 18, 22, 14, 4,
- -7, 4, -7, -36, -37, -37, -27, -15, -26, -34, -34, -29, -18, 4, 19, 31,
- 20, -4, 0, -3, -21, -32, -37, -41, -40, -25, 14, 49, 44, 18, 19, 25,
- -1, -19, 5, 26, 35, 38, 46, 41, 18, 18, 16, 13, 12, 2, -5, -3,
- -23, -44, -37, -32, -20, -20, -33, -28, -32, -32, -16, 1, 17, 31, 17, -2,
- 2, -3, -22, -33, -39, -40, -34, -23, 15, 56, 44, 15, 27, 23, -4, -14,
- 2, 22, 38, 37, 48, 40, 25, 24, 15, 11, 2, -2, -3, -15, -31, -40,
- -37, -33, -17, -17, -28, -29, -41, -34, -7, 1, 13, 31, 17, -2, 4, 1,
- -20, -35, -47, -37, -24, -10, 22, 52, 38, 26, 35, 26, -2, -9, 4, 23,
- 40, 38, 46, 39, 32, 31, 16, 2, -7, -8, -2, -21, -38, -44, -38, -31,
- -18, -15, -29, -35, -45, -32, -1, -3, 4, 30, 16, 3, 8, 4, -20, -42,
- -48, -30, -17, -8, 21, 49, 41, 30, 38, 23, -2, -5, 1, 21, 35, 37,
- 44, 40, 40, 33, 17, 1, -13, -10, -9, -35, -41, -41, -39, -33, -19, -12,
- -27, -40, -48, -28, -4, -10, 10, 28, 15, 9, 12, 5, -24, -43, -43, -23,
- -18, 0, 26, 47, 43, 35, 40, 20, -1, 1, 4, 20, 28, 37, 42, 42,
- 46, 31, 22, 8, -17, -15, -15, -42, -41, -37, -44, -37, -16, -13, -33, -41,
- -41, -20, -11, -17, 10, 18, 13, 16, 17, 1, -24, -38, -38, -27, -21, 9,
- 29, 46, 44, 43, 38, 18, 3, 6, 6, 12, 19, 38, 41, 47, 44, 28,
- 29, 11, -26, -25, -27, -45, -39, -39, -48, -41, -18, -13, -33, -38, -36, -21,
- -19, -14, 13, 11, 11, 26, 17, -6, -25, -32, -32, -35, -14, 21, 31, 38,
- 49, 49, 34, 19, 13, 10, 4, 9, 20, 37, 41, 45, 39, 29, 35, 6,
- -28, -28, -35, -43, -37, -42, -50, -44, -20, -20, -37, -37, -27, -16, -23, -11,
- 10, 5, 17, 36, 16, -16, -23, -21, -33, -38, -5, 23, 28, 35, 55, 55,
- 31, 17, 18, 12, 3, 4, 21, 33, 41, 45, 31, 32, 39, 3, -29, -35,
- -41, -40, -38, -45, -55, -45, -26, -31, -36, -26, -22, -22, -29, 1, 9, -1,
- 24, 39, 8, -19, -17, -14, -32, -34, 5, 29, 29, 35, 58, 51, 32, 29,
- 23, 11, 1, 6, 29, 37, 38, 36, 24, 43, 39, -2, -32, -44, -45, -36,
- -36, -45, -55, -51, -37, -35, -30, -22, -20, -32, -24, 6, 2, 3, 30, 36,
- 3, -17, -16, -18, -29, -24, 10, 31, 25, 34, 58, 44, 33, 37, 26, 8,
- 5, 10, 37, 36, 35, 29, 22, 47, 36, -6, -36, -51, -49, -34, -38, -48,
- -58, -53, -46, -42, -24, -23, -22, -32, -13, 4, -7, 8, 35, 30, 6, -14,
- -20, -19, -21, -20, 14, 34, 29, 43, 52, 37, 39, 43, 24, 8, 7, 15,
- 45, 33, 36, 24, 25, 43, 25, -10, -39, -53, -47, -34, -39, -53, -56, -54,
- -56, -42, -21, -23, -29, -25, -5, 1, -10, 12, 35, 27, 7, -14, -25, -19,
- -11, -10, 13, 31, 37, 44, 42, 37, 45, 44, 24, 14, 13, 24, 40, 28,
- 35, 23, 31, 35, 15, -16, -38, -53, -45, -37, -48, -56, -54, -63, -63, -40,
- -23, -24, -27, -19, 3, 1, -11, 14, 33, 24, 5, -16, -28, -17, -6, -1,
- 15, 38, 39, 38, 29, 36, 54, 42, 20, 20, 19, 32, 38, 30, 31, 23,
- 33, 23, -1, -17, -35, -44, -43, -47, -51, -51, -56, -71, -67, -45, -28, -23,
- -23, -13, 12, -1, -15, 15, 33, 20, -2, -22, -25, -17, -3, 10, 24, 46,
- 44, 31, 26, 41, 53, 42, 23, 23, 26, 39, 37, 32, 24, 28, 36, 11,
- -7, -19, -38, -39, -37, -49, -54, -51, -62, -76, -68, -51, -28, -19, -21, 1,
- 22, -3, -11, 14, 25, 16, -5, -25, -25, -15, -2, 20, 36, 51, 42, 19,
- 19, 43, 58, 43, 25, 21, 35, 46, 41, 34, 17, 26, 33, 5, -15, -25,
- -39, -34, -37, -55, -50, -49, -69, -80, -67, -50, -31, -18, -12, 12, 17, -5,
- -5, 14, 17, 6, -15, -27, -22, -14, 3, 37, 49, 48, 40, 22, 22, 36,
- 51, 44, 29, 22, 42, 49, 41, 29, 16, 29, 31, -9, -30, -33, -35, -29,
- -38, -55, -45, -54, -79, -80, -65, -51, -34, -16, -2, 18, 18, 5, 7, 8,
- 6, 3, -19, -21, -22, -19, 12, 51, 53, 48, 39, 22, 18, 36, 46, 42,
- 35, 31, 44, 46, 42, 31, 24, 35, 21, -25, -39, -33, -30, -24, -41, -53,
- -47, -60, -81, -81, -63, -53, -40, -14, 6, 24, 20, 8, 7, 0, -1, -4,
- -21, -23, -29, -16, 30, 60, 55, 50, 37, 19, 19, 35, 43, 46, 37, 29,
- 43, 49, 43, 32, 27, 31, 13, -35, -46, -36, -26, -28, -44, -52, -47, -65,
- -84, -84, -68, -49, -27, 0, 10, 15, 19, 15, 9, -3, -10, -16, -20, -26,
- -28, -2, 41, 59, 62, 56, 37, 16, 15, 31, 43, 50, 42, 30, 41, 49,
- 49, 38, 28, 23, 5, -42, -55, -42, -21, -22, -40, -49, -54, -71, -86, -81,
- -62, -44, -21, 5, 17, 16, 25, 23, 0, -13, -17, -17, -24, -32, -21, 15,
- 45, 58, 66, 52, 33, 15, 9, 35, 42, 44, 44, 36, 38, 50, 52, 40,
- 28, 16, -11, -48, -60, -43, -22, -21, -40, -53, -58, -78, -90, -79, -61, -42,
- -9, 14, 15, 16, 22, 21, -4, -20, -21, -19, -30, -31, -10, 26, 54, 63,
- 69, 51, 33, 12, 13, 40, 42, 45, 42, 33, 36, 53, 57, 44, 24, 3,
- -24, -53, -63, -45, -21, -15, -39, -57, -63, -78, -89, -76, -55, -34, 3, 18,
- 9, 16, 21, 15, -8, -26, -28, -25, -32, -24, 4, 34, 56, 67, 75, 48,
- 22, 7, 23, 44, 39, 40, 40, 35, 40, 59, 59, 44, 18, -6, -31, -54,
- -58, -44, -20, -13, -43, -63, -69, -80, -88, -71, -48, -21, 12, 16, 12, 18,
- 13, 6, -12, -27, -32, -30, -34, -20, 13, 46, 63, 74, 73, 40, 15, 13,
- 39, 46, 33, 32, 35, 36, 48, 58, 61, 43, 16, -13, -36, -57, -62, -41,
- -22, -16, -42, -66, -73, -79, -85, -65, -38, -7, 13, 9, 7, 16, 11, -2,
- -18, -36, -39, -26, -25, -16, 21, 53, 64, 74, 68, 36, 19, 22, 38, 44,
- 32, 28, 32, 38, 52, 60, 56, 43, 13, -25, -39, -54, -52, -35, -30, -27,
- -46, -70, -79, -80, -79, -58, -26, 3, 15, 6, 0, 12, 6, -8, -27, -45,
- -39, -17, -16, -13, 28, 57, 67, 71, 57, 37, 22, 25, 41, 46, 29, 24,
- 34, 44, 56, 55, 52, 44, 7, -27, -38, -48, -44, -35, -31, -29, -46, -77,
- -83, -73, -70, -48, -15, 6, 9, 1, 1, 9, -3, -20, -41, -48, -30, -5,
- -14, -9, 39, 63, 70, 66, 47, 36, 25, 32, 40, 43, 26, 21, 36, 47,
- 59, 50, 49, 35, 0, -26, -36, -44, -41, -36, -35, -33, -50, -79, -79, -66,
- -63, -36, -8, 6, -3, -9, 2, 3, -13, -30, -49, -46, -18, -2, -15, 4,
- 42, 58, 65, 61, 50, 38, 28, 37, 40, 38, 28, 30, 38, 48, 50, 42,
- 46, 28, -3, -28, -37, -36, -36, -39, -36, -37, -59, -79, -69, -62, -52, -24,
- -2, 3, -12, -11, 4, -5, -29, -42, -53, -39, -12, -4, -4, 14, 37, 52,
- 63, 58, 50, 37, 34, 37, 36, 37, 38, 36, 35, 47, 46, 44, 42, 18,
- -7, -30, -34, -32, -34, -41, -37, -45, -66, -74, -64, -57, -36, -12, 1, -8,
- -23, -7, 6, -18, -39, -49, -53, -29, -5, -1, 10, 19, 30, 46, 59, 58,
- 50, 36, 37, 37, 32, 40, 46, 38, 34, 44, 42, 41, 36, 9, -9, -27,
- -29, -26, -34, -40, -40, -56, -69, -66, -56, -46, -22, -7, -7, -19, -21, 3,
- 1, -35, -48, -53, -49, -22, -3, 12, 23, 18, 22, 46, 66, 59, 47, 38,
- 43, 35, 30, 46, 51, 39, 33, 41, 37, 42, 24, 2, -8, -22, -23, -24,
- -33, -39, -50, -66, -69, -59, -49, -31, -13, -10, -17, -25, -16, 1, -17, -50,
- -55, -58, -42, -17, -1, 20, 31, 14, 15, 48, 70, 59, 42, 38, 45, 33,
- 33, 51, 53, 36, 35, 37, 36, 37, 12, 0, -9, -16, -18, -22, -33, -42,
- -59, -67, -62, -52, -40, -20, -11, -15, -23, -23, -11, -3, -28, -51, -59, -61,
- -38, -14, 4, 26, 30, 10, 18, 53, 71, 56, 40, 42, 45, 32, 34, 53,
- 52, 37, 36, 32, 37, 32, 10, -3, -10, -10, -11, -17, -31, -46, -62, -63,
- -54, -44, -30, -14, -14, -23, -27, -22, -11, -11, -35, -51, -65, -59, -32, -11,
- 11, 29, 25, 8, 24, 63, 73, 51, 38, 46, 44, 29, 34, 51, 51, 39,
- 34, 27, 34, 23, 3, -5, -9, -6, -10, -18, -33, -51, -66, -60, -50, -35,
- -20, -10, -21, -33, -29, -17, -9, -20, -39, -55, -71, -57, -26, -7, 11, 23,
- 22, 11, 35, 70, 71, 46, 39, 48, 42, 29, 33, 51, 47, 38, 31, 28,
- 35, 17, 0, -12, -7, 0, -4, -15, -36, -56, -67, -56, -42, -26, -15, -12,
- -29, -36, -28, -15, -13, -25, -40, -58, -70, -49, -23, -6, 8, 19, 17, 18,
- 49, 76, 66, 40, 42, 49, 39, 25, 35, 51, 43, 40, 30, 31, 32, 15,
- -1, -14, -7, 1, -2, -17, -40, -59, -61, -51, -38, -21, -10, -17, -34, -35,
- -28, -18, -17, -24, -40, -64, -65, -40, -18, -8, 5, 13, 17, 31, 61, 75,
- 60, 41, 43, 47, 34, 20, 36, 47, 43, 41, 31, 32, 26, 7, -7, -16,
- -6, 0, -3, -22, -44, -60, -56, -47, -34, -19, -8, -20, -39, -40, -27, -18,
- -20, -29, -44, -63, -56, -38, -23, -11, 4, 14, 21, 42, 65, 71, 59, 45,
- 42, 34, 21, 20, 42, 48, 44, 41, 31, 34, 24, 6, -10, -20, -11, 4,
- 0, -20, -48, -57, -47, -39, -30, -17, -4, -24, -43, -40, -26, -19, -24, -29,
- -45, -59, -51, -37, -25, -14, 3, 15, 27, 51, 72, 76, 61, 44, 38, 23,
- 12, 21, 43, 46, 45, 40, 31, 35, 21, 5, -17, -22, -13, 3, 1, -24,
- -51, -52, -43, -37, -28, -8, -7, -38, -46, -36, -21, -21, -31, -33, -45, -51,
- -47, -40, -30, -13, 4, 14, 33, 60, 76, 76, 61, 47, 30, 16, 8, 20,
- 40, 45, 48, 37, 37, 37, 22, 3, -19, -20, -10, 4, -6, -30, -49, -44,
- -41, -38, -23, -1, -14, -41, -44, -36, -22, -26, -35, -33, -45, -52, -48, -40,
- -32, -9, 6, 18, 35, 65, 85, 80, 62, 46, 24, 6, -1, 23, 41, 48,
- 45, 31, 42, 40, 23, -6, -21, -15, -6, 0, -13, -31, -44, -41, -38, -32,
- -15, 0, -22, -40, -41, -36, -24, -31, -28, -32, -46, -49, -47, -43, -30, -6,
- 9, 19, 46, 77, 87, 77, 61, 42, 18, -2, -7, 22, 39, 51, 41, 32,
- 43, 35, 13, -18, -18, -10, -5, -8, -21, -29, -39, -42, -41, -23, -3, -3,
- -32, -39, -38, -34, -31, -35, -23, -32, -46, -50, -51, -46, -26, 0, 12, 20,
- 54, 87, 91, 72, 60, 38, 13, -10, -11, 24, 44, 52, 43, 39, 45, 34,
- 2, -19, -8, -1, -8, -19, -19, -25, -35, -42, -39, -17, 7, -7, -38, -36,
- -36, -37, -37, -31, -20, -34, -49, -53, -50, -43, -19, 6, 10, 25, 66, 91,
- 84, 67, 60, 36, 1, -18, -10, 27, 48, 52, 42, 42, 38, 25, -3, -18,
- -5, -2, -13, -22, -24, -28, -35, -45, -35, -4, 14, -17, -41, -36, -33, -35,
- -41, -29, -20, -38, -51, -54, -46, -33, -14, 6, 14, 37, 74, 87, 76, 65,
- 64, 29, -9, -22, -7, 23, 52, 55, 46, 42, 25, 17, -5, -12, -4, -3,
- -17, -25, -33, -36, -33, -39, -30, 5, 12, -25, -37, -33, -34, -42, -41, -25,
- -22, -41, -52, -53, -40, -25, -10, 11, 21, 43, 72, 78, 74, 69, 58, 15,
- -13, -15, -4, 22, 54, 58, 53, 41, 15, 6, -2, -1, -3, -6, -18, -24,
- -42, -40, -29, -32, -20, 13, 8, -25, -35, -34, -29, -42, -43, -27, -27, -42,
- -51, -50, -30, -14, -5, 17, 26, 46, 70, 72, 72, 69, 48, 2, -13, -9,
- -3, 19, 55, 59, 53, 30, 1, -1, 5, 8, -7, -15, -19, -25, -48, -45,
- -31, -28, -10, 15, 1, -24, -35, -35, -22, -37, -43, -36, -35, -41, -47, -45,
- -18, -6, -1, 24, 32, 51, 65, 65, 67, 63, 37, -3, -13, -9, 1, 29,
- 54, 60, 50, 18, -4, -4, 13, 9, -10, -15, -17, -30, -54, -47, -29, -20,
- -8, 4, -8, -15, -29, -35, -21, -37, -43, -46, -37, -33, -48, -39, -10, 3,
- 13, 31, 34, 54, 56, 57, 63, 56, 32, -3, -16, -6, 14, 38, 48, 53,
- 40, 11, -3, 1, 6, -2, -11, -9, -11, -28, -54, -54, -29, -8, 2, -8,
- -16, -13, -27, -31, -21, -32, -45, -54, -36, -27, -44, -33, 1, 16, 25, 29,
- 39, 56, 48, 51, 57, 48, 22, 3, -14, 0, 22, 39, 42, 46, 36, 7,
- -7, 0, 0, -3, -8, -8, -15, -34, -50, -49, -27, -3, 0, -15, -14, -16,
- -28, -26, -21, -34, -56, -55, -32, -30, -41, -23, 8, 20, 31, 33, 45, 53,
- 38, 42, 54, 40, 18, -3, -9, 14, 33, 37, 34, 34, 27, 8, -5, -1,
- -9, -3, -1, -8, -19, -35, -43, -42, -28, -7, 1, -18, -13, -17, -29, -24,
- -21, -34, -55, -52, -34, -30, -26, -9, 15, 28, 28, 32, 55, 50, 29, 38,
- 45, 35, 17, -3, -1, 18, 36, 40, 27, 24, 19, 0, -5, -1, -14, -7,
- -2, -12, -20, -30, -40, -42, -25, -5, -5, -24, -14, -16, -25, -20, -26, -38,
- -52, -49, -35, -31, -13, 8, 16, 28, 29, 42, 57, 40, 23, 32, 35, 30,
- 12, -5, 9, 22, 40, 38, 19, 17, 16, -1, -9, -7, -12, -6, -5, -13,
- -18, -29, -39, -39, -18, -3, -19, -26, -11, -18, -24, -19, -30, -40, -51, -45,
- -30, -24, 0, 19, 22, 28, 36, 49, 54, 41, 22, 30, 31, 26, 10, 2,
- 10, 26, 43, 28, 14, 16, 7, -6, -12, -9, -9, -5, -12, -19, -16, -29,
- -35, -34, -8, -8, -35, -20, -7, -26, -23, -23, -30, -39, -53, -38, -25, -12,
- 11, 24, 24, 29, 47, 50, 48, 36, 20, 29, 24, 15, 5, 8, 12, 32,
- 40, 21, 17, 11, 0, -3, -15, -14, -7, -4, -13, -17, -16, -28, -31, -23,
- -6, -20, -37, -15, -12, -29, -22, -28, -30, -38, -54, -34, -20, -4, 21, 33,
- 24, 33, 50, 45, 40, 33, 27, 28, 14, 8, 8, 11, 11, 30, 33, 26,
- 20, -1, -8, -4, -17, -16, -2, -7, -22, -20, -20, -26, -26, -15, -10, -27,
- -35, -12, -19, -31, -21, -23, -23, -42, -57, -31, -11, 9, 35, 33, 23, 39,
- 53, 47, 40, 31, 31, 21, 10, 9, 11, 10, 13, 26, 35, 33, 13, -11,
- -10, -4, -19, -22, 3, -2, -28, -26, -16, -21, -24, -12, -12, -31, -34, -17,
- -27, -34, -25, -17, -19, -48, -59, -29, -2, 27, 46, 26, 22, 43, 54, 44,
- 38, 30, 29, 16, 6, 15, 15, 6, 9, 22, 36, 37, 9, -20, -10, -5,
- -21, -21, 2, -5, -29, -31, -18, -11, -17, -11, -15, -32, -34, -23, -30, -30,
- -25, -15, -22, -52, -50, -17, 9, 36, 42, 26, 29, 50, 53, 40, 33, 32,
- 27, 14, 7, 9, 7, 4, 12, 22, 36, 36, 3, -27, -16, -9, -20, -21,
- -1, -12, -31, -27, -13, -12, -18, -12, -17, -33, -39, -29, -34, -35, -23, -7,
- -25, -55, -42, -10, 20, 43, 40, 27, 33, 51, 51, 37, 34, 31, 21, 9,
- 8, 5, 2, 11, 16, 18, 34, 35, 3, -22, -17, -16, -20, -17, -7, -20,
- -32, -28, -14, -12, -10, -8, -17, -34, -41, -35, -34, -31, -19, -8, -27, -48,
- -29, -4, 26, 50, 44, 32, 37, 50, 49, 40, 36, 22, 11, 11, 12, 5,
- 3, 14, 12, 13, 34, 37, 9, -23, -24, -16, -21, -16, -17, -30, -27, -27,
- -20, -10, -10, -9, -18, -39, -46, -42, -35, -31, -14, -9, -33, -42, -19, 1,
- 36, 55, 41, 32, 46, 55, 47, 35, 32, 18, 6, 7, 9, -2, 7, 17,
- 8, 13, 34, 32, 10, -22, -27, -14, -20, -21, -26, -31, -23, -27, -22, -6,
- -5, -11, -21, -39, -46, -46, -37, -30, -14, -12, -33, -31, -8, 6, 41, 55,
- 40, 38, 54, 57, 39, 30, 33, 17, 2, 1, 4, 7, 14, 14, -2, 11,
- 37, 31, 11, -26, -30, -16, -20, -18, -21, -27, -32, -28, -12, 0, -4, -11,
- -23, -40, -46, -43, -33, -26, -16, -15, -29, -19, -1, 13, 44, 58, 41, 49,
- 68, 59, 36, 28, 36, 18, -9, -9, 4, 17, 20, 7, -6, 18, 36, 22,
- -1, -30, -26, -19, -25, -26, -31, -35, -33, -21, -3, -8, -10, -14, -24, -40,
- -45, -43, -35, -20, -18, -20, -22, -12, 0, 15, 48, 58, 41, 58, 77, 57,
- 30, 27, 33, 7, -23, -16, 11, 23, 21, 2, -5, 24, 33, 10, -10, -24,
- -19, -25, -37, -30, -30, -34, -29, -14, -5, -16, -8, -8, -26, -50, -47, -41,
- -30, -16, -25, -24, -14, -6, 3, 23, 50, 51, 49, 69, 81, 56, 29, 33,
- 30, -2, -29, -14, 15, 26, 18, 2, -1, 31, 28, 0, -20, -21, -21, -32,
- -43, -34, -33, -36, -23, -4, -8, -20, -8, -11, -25, -44, -41, -39, -32, -17,
- -30, -22, -4, 1, 6, 31, 48, 47, 63, 80, 82, 52, 31, 38, 23, -13,
- -33, -11, 20, 29, 14, -1, 9, 34, 19, -12, -26, -13, -23, -46, -46, -38,
- -39, -35, -24, -3, -7, -17, -15, -16, -25, -45, -37, -37, -33, -26, -36, -20,
- 5, 3, 4, 32, 42, 50, 76, 83, 75, 49, 34, 36, 17, -24, -33, -12,
- 23, 32, 10, 1, 23, 30, 7, -17, -22, -8, -27, -49, -50, -42, -38, -28,
- -18, -3, -8, -13, -14, -15, -24, -43, -35, -33, -29, -27, -34, -15, 16, 8,
- 5, 32, 43, 62, 84, 84, 73, 53, 40, 30, 6, -26, -34, -15, 25, 28,
- 8, 9, 38, 27, -4, -26, -21, -12, -33, -54, -47, -48, -38, -21, -14, -2,
- -3, -11, -25, -18, -26, -32, -34, -34, -29, -31, -35, -10, 18, 11, 7, 33,
- 47, 68, 83, 81, 71, 58, 42, 20, -5, -25, -36, -15, 23, 23, 7, 20,
- 40, 21, -14, -35, -21, -16, -40, -58, -52, -52, -31, -11, -9, -6, -1, -15,
- -26, -15, -29, -31, -36, -31, -29, -36, -32, -4, 17, 8, 15, 36, 48, 66,
- 77, 83, 77, 59, 38, 9, -11, -20, -34, -12, 22, 20, 14, 33, 39, 16,
- -22, -36, -23, -21, -40, -56, -52, -47, -24, -10, -4, 3, 1, -17, -22, -18,
- -28, -26, -32, -30, -32, -30, -22, 1, 15, 15, 27, 42, 52, 62, 75, 85,
- 80, 59, 35, 1, -16, -20, -35, -12, 18, 17, 18, 40, 34, 5, -34, -38,
- -27, -28, -42, -60, -58, -48, -18, -4, 0, 3, -4, -18, -20, -22, -35, -29,
- -27, -34, -42, -28, -12, 3, 8, 19, 31, 40, 45, 60, 75, 79, 76, 62,
- 37, -2, -20, -22, -31, -11, 13, 15, 31, 43, 27, 0, -28, -33, -36, -37,
- -43, -58, -61, -47, -13, 1, 1, 3, -5, -12, -17, -25, -36, -27, -25, -39,
- -45, -24, 1, 0, 8, 25, 43, 45, 42, 57, 76, 76, 73, 60, 37, -8,
- -25, -22, -25, -6, 9, 21, 41, 41, 15, -6, -18, -33, -48, -40, -38, -57,
- -64, -46, -6, 9, -4, 1, -1, -9, -18, -28, -33, -24, -27, -42, -45, -18,
- 2, 3, 13, 31, 49, 43, 37, 60, 74, 68, 68, 60, 30, -12, -28, -23,
- -19, -8, 5, 26, 48, 37, 11, -12, -17, -37, -54, -40, -41, -58, -65, -42,
- 5, 12, -8, 0, 2, -6, -22, -29, -30, -28, -37, -44, -42, -9, 6, 7,
- 17, 33, 44, 42, 40, 61, 72, 57, 63, 61, 24, -16, -34, -21, -15, -12,
- 3, 31, 47, 28, 7, -10, -15, -43, -51, -38, -45, -61, -61, -31, 10, 8,
- -3, 6, 5, -8, -24, -27, -28, -31, -44, -42, -29, -3, 6, 10, 24, 40,
- 44, 45, 46, 57, 62, 56, 65, 56, 16, -13, -32, -18, -12, -10, 11, 32,
- 39, 25, 6, -10, -19, -48, -44, -38, -49, -63, -61, -19, 12, 3, 4, 6,
- 3, -9, -25, -26, -27, -38, -46, -39, -18, 1, 12, 20, 29, 33, 36, 49,
- 47, 54, 59, 49, 63, 51, 8, -12, -25, -18, -18, -6, 20, 33, 28, 19,
- 4, -9, -27, -43, -41, -45, -55, -64, -51, -13, 7, -3, 0, 7, 3, -12,
- -28, -27, -33, -46, -51, -33, -10, -5, 15, 31, 34, 26, 32, 47, 51, 53,
- 47, 50, 61, 41, 1, -8, -12, -21, -20, 5, 27, 29, 16, 13, 8, -9,
- -28, -40, -40, -44, -55, -62, -40, -8, 5, -2, 4, 11, 4, -15, -26, -26,
- -37, -49, -47, -27, -8, -3, 22, 45, 38, 22, 34, 47, 55, 52, 39, 44,
- 58, 32, 2, 0, -7, -25, -21, 10, 29, 30, 9, 0, 0, -7, -26, -38,
- -40, -53, -61, -53, -30, -5, 1, -2, 5, 10, 3, -18, -25, -33, -43, -51,
- -46, -20, -10, -8, 26, 52, 35, 19, 32, 47, 56, 46, 33, 44, 48, 20,
- 10, 11, -7, -29, -20, 15, 35, 28, 2, -9, -8, -6, -26, -32, -36, -54,
- -64, -52, -22, 1, 3, 2, 3, 15, 2, -22, -24, -34, -41, -45, -39, -19,
- -9, 1, 35, 57, 37, 18, 27, 46, 52, 41, 37, 44, 40, 18, 16, 13,
- -7, -29, -14, 23, 36, 17, -6, -17, -2, 1, -24, -38, -43, -59, -62, -44,
- -22, -4, 7, 2, 5, 16, -2, -24, -27, -36, -43, -48, -37, -20, -5, 14,
- 40, 52, 36, 20, 26, 43, 46, 40, 41, 42, 28, 19, 19, 9, -4, -21,
- -10, 27, 32, 10, -6, -16, -4, -5, -14, -37, -48, -59, -58, -36, -24, -1,
- 13, -3, 7, 16, -5, -19, -32, -38, -46, -43, -32, -22, -7, 22, 49, 57,
- 37, 22, 20, 37, 41, 36, 46, 41, 21, 19, 16, 9, -2, -25, -9, 27,
- 24, 8, -12, -11, -2, -9, -10, -39, -51, -59, -59, -35, -21, 2, 15, -5,
- 10, 11, -12, -19, -35, -39, -46, -35, -29, -26, -5, 37, 60, 53, 36, 26,
- 19, 33, 37, 33, 48, 41, 18, 17, 19, 11, -8, -23, -3, 30, 21, -5,
- -14, -2, -6, -9, -9, -42, -59, -64, -54, -33, -16, 6, 14, 0, 15, 4,
- -14, -17, -35, -45, -46, -33, -27, -22, 2, 42, 56, 49, 37, 26, 19, 26,
- 23, 36, 58, 44, 11, 8, 23, 10, -7, -15, 3, 26, 12, -10, -8, 3,
- -10, -7, -13, -46, -58, -60, -57, -40, -11, 9, 9, 3, 13, -6, -12, -17,
- -42, -53, -45, -28, -23, -14, 11, 49, 60, 49, 40, 27, 14, 16, 13, 43,
- 62, 46, 6, 8, 22, 7, -9, -10, 11, 23, 4, -17, 2, 6, -6, -7,
- -21, -51, -58, -58, -55, -38, -12, 12, 10, 13, 1, -15, -7, -14, -47, -62,
- -45, -29, -19, -2, 21, 51, 63, 46, 37, 31, 16, 0, 4, 43, 64, 43,
- 6, 9, 24, 4, -15, -2, 14, 9, -9, -15, 14, 7, -11, -10, -29, -53,
- -54, -57, -48, -35, -9, 13, 9, 11, -5, -6, -2, -22, -57, -60, -39, -24,
- -11, 5, 30, 52, 62, 49, 42, 38, 11, -9, 7, 45, 61, 44, 10, 15,
- 21, -4, -15, 3, 13, 1, -13, -9, 13, 7, -9, -13, -32, -51, -53, -56,
- -44, -35, -9, 15, 11, 7, -8, 0, -2, -34, -65, -56, -31, -24, -7, 20,
- 37, 49, 56, 47, 47, 39, -3, -16, 12, 40, 53, 45, 16, 23, 17, -7,
- -8, 7, 8, -5, -12, -7, 7, 7, -4, -17, -38, -56, -60, -50, -37, -33,
- -8, 7, 9, 0, -6, 7, -8, -47, -71, -50, -25, -23, 0, 33, 41, 46,
- 52, 53, 54, 35, -6, -9, 13, 32, 50, 48, 23, 25, 13, -4, -3, 0,
- -1, -7, -7, -8, 3, 6, -3, -22, -41, -55, -62, -46, -30, -24, -5, 0,
- 5, 2, 3, 10, -20, -57, -69, -41, -19, -16, 5, 37, 47, 46, 49, 54,
- 58, 29, -4, -6, 7, 21, 49, 49, 24, 24, 12, -2, -5, -9, 0, 0,
- -10, -15, 2, 8, -4, -23, -42, -57, -66, -43, -22, -16, -11, -8, 3, 5,
- 7, 4, -28, -61, -61, -36, -19, -11, 10, 45, 51, 43, 46, 52, 54, 26,
- 3, -8, -3, 15, 52, 48, 27, 30, 15, -1, -9, -14, 0, -2, -15, -17,
- -2, -1, -5, -23, -37, -62, -64, -34, -17, -15, -19, -8, 4, 7, 8, -8,
- -37, -55, -50, -33, -19, -5, 16, 49, 54, 44, 45, 52, 53, 32, 3, -12,
- -5, 14, 46, 46, 38, 34, 21, 6, -13, -21, -2, -3, -18, -19, -14, -9,
- -2, -14, -44, -74, -56, -26, -15, -16, -18, -6, -1, 7, 6, -20, -43, -48,
- -35, -32, -24, 1, 23, 51, 54, 41, 42, 52, 49, 32, 3, -14, -5, 19,
- 42, 47, 43, 38, 27, 10, -18, -19, -5, -7, -18, -27, -23, -9, 2, -8,
- -51, -75, -41, -19, -15, -13, -15, -11, -5, 10, 1, -30, -37, -40, -30, -33,
- -24, 6, 30, 49, 49, 45, 43, 52, 39, 24, 7, -10, -7, 12, 33, 44,
- 48, 43, 36, 7, -29, -18, -6, -14, -23, -36, -32, -12, 2, -16, -60, -65,
- -27, -22, -22, -9, -6, -14, -6, 11, -10, -38, -35, -27, -26, -35, -15, 18,
- 39, 47, 48, 51, 55, 51, 28, 22, 13, -5, -6, 5, 27, 46, 57, 49,
- 39, 1, -29, -12, -7, -15, -28, -48, -39, -11, -1, -28, -61, -51, -22, -30,
- -22, -3, -4, -21, -6, 8, -23, -45, -29, -18, -27, -32, -11, 24, 44, 40,
- 46, 56, 61, 44, 17, 18, 19, 1, -11, -2, 24, 48, 57, 54, 45, 2,
- -27, -12, -11, -18, -32, -49, -41, -16, -10, -32, -47, -33, -25, -34, -13, 6,
- -5, -24, -13, -4, -29, -43, -29, -18, -25, -21, -1, 25, 44, 40, 49, 67,
- 60, 31, 12, 18, 24, -2, -18, -5, 22, 45, 62, 65, 46, -5, -21, -12,
- -12, -17, -36, -57, -48, -23, -15, -29, -35, -28, -33, -31, -3, 12, -16, -32,
- -12, -19, -36, -33, -25, -22, -29, -10, 14, 30, 41, 35, 51, 73, 57, 27,
- 16, 21, 14, -4, -12, -2, 21, 41, 62, 71, 43, -7, -12, -19, -22, -23,
- -46, -57, -51, -35, -20, -17, -22, -26, -37, -27, 7, 12, -24, -31, -14, -29,
- -34, -30, -22, -20, -21, 2, 15, 26, 40, 45, 55, 66, 52, 28, 20, 17,
- 10, -1, -12, -4, 21, 43, 65, 74, 39, 1, -9, -25, -27, -24, -45, -61,
- -55, -43, -22, -9, -12, -24, -32, -26, 9, 7, -25, -31, -30, -40, -31, -26,
- -19, -20, -11, 14, 18, 27, 45, 54, 52, 61, 49, 33, 24, 15, 5, 0,
- -14, -2, 24, 44, 62, 67, 37, 12, -9, -30, -29, -33, -49, -66, -58, -51,
- -25, -2, -6, -19, -31, -24, 6, 3, -21, -37, -43, -42, -31, -25, -17, -19,
- -5, 15, 19, 30, 52, 56, 45, 54, 52, 38, 22, 11, 8, 0, -16, 2,
- 27, 44, 63, 60, 34, 16, -10, -25, -31, -38, -55, -68, -62, -53, -18, 5,
- -2, -17, -31, -16, 5, -4, -22, -43, -50, -38, -32, -21, -16, -11, 8, 10,
- 19, 32, 60, 60, 43, 46, 51, 37, 24, 13, 8, -6, -17, 4, 32, 52,
- 56, 52, 39, 23, -5, -23, -41, -48, -64, -65, -63, -57, -14, 9, 3, -18,
- -28, -9, 0, -11, -25, -47, -53, -38, -30, -19, -11, 0, 10, 11, 23, 42,
- 66, 60, 42, 49, 53, 36, 24, 20, 9, -17, -18, 3, 39, 59, 49, 41,
- 39, 26, 1, -24, -53, -59, -70, -61, -66, -58, -12, 17, 7, -20, -26, -7,
- -7, -16, -30, -51, -60, -45, -26, -11, -5, 5, 8, 10, 23, 48, 66, 55,
- 40, 48, 48, 33, 30, 25, 2, -21, -15, 10, 41, 51, 44, 37, 41, 27,
- 6, -28, -60, -65, -70, -63, -70, -55, -6, 21, 1, -20, -15, -2, -15, -24,
- -32, -54, -66, -45, -22, -8, 6, 13, 5, 15, 31, 51, 64, 58, 41, 42,
- 44, 35, 36, 29, 0, -20, -9, 14, 43, 53, 46, 39, 39, 24, 7, -33,
- -69, -75, -73, -70, -75, -46, 4, 17, -2, -18, -6, 3, -18, -32, -38, -61,
- -65, -39, -17, -2, 10, 10, 5, 19, 33, 55, 61, 54, 39, 40, 41, 41,
- 40, 30, -6, -25, -6, 22, 44, 48, 42, 42, 37, 23, 11, -42, -73, -77,
- -75, -74, -75, -39, 4, 8, -5, -15, 1, -1, -30, -33, -38, -69, -66, -40,
- -14, 3, 16, 8, 5, 21, 39, 60, 59, 48, 40, 38, 39, 42, 42, 30,
- -8, -20, 0, 26, 48, 51, 48, 43, 29, 21, 1, -47, -70, -80, -83, -80,
- -70, -25, 0, -2, -9, -6, 9, -7, -29, -33, -49, -72, -59, -29, -3, 3,
- 11, 6, 14, 27, 47, 61, 54, 47, 43, 34, 42, 45, 39, 21, -10, -17,
- 4, 29, 53, 54, 47, 39, 29, 22, -11, -53, -70, -83, -86, -77, -61, -19,
- -6, -7, -12, -2, 9, -14, -29, -35, -61, -70, -54, -25, -8, 2, 11, 8,
- 17, 27, 54, 60, 50, 45, 42, 40, 43, 39, 35, 18, -9, -7, 8, 28,
- 55, 56, 49, 32, 30, 15, -21, -53, -71, -88, -87, -74, -45, -12, -11, -15,
- -14, 6, 12, -12, -30, -48, -66, -60, -44, -18, -8, 5, 13, 15, 21, 31,
- 51, 57, 48, 43, 42, 40, 43, 37, 29, 16, -3, -1, 7, 35, 60, 54,
- 38, 26, 29, 5, -30, -54, -72, -93, -87, -69, -34, -14, -19, -25, -12, 13,
- 6, -17, -37, -56, -66, -49, -38, -18, -11, 1, 17, 24, 26, 32, 47, 52,
- 50, 49, 45, 39, 40, 33, 32, 13, 4, 3, 3, 47, 65, 52, 29, 27,
- 20, -5, -35, -56, -76, -90, -79, -63, -27, -17, -26, -24, 0, 12, -2, -16,
- -33, -61, -61, -42, -33, -17, -16, -6, 22, 30, 25, 29, 45, 50, 46, 53,
- 41, 37, 37, 33, 28, 17, 15, 2, 15, 54, 64, 46, 21, 25, 9, -12,
- -39, -58, -77, -87, -75, -46, -21, -23, -34, -24, 9, 9, -7, -17, -40, -67,
- -53, -33, -27, -22, -26, -4, 34, 34, 25, 27, 46, 44, 52, 59, 37, 30,
- 35, 32, 26, 25, 16, 2, 30, 62, 57, 33, 19, 17, -7, -25, -43, -58,
- -80, -82, -64, -36, -26, -26, -33, -17, 11, 4, -9, -18, -45, -62, -44, -30,
- -24, -28, -29, 5, 38, 32, 25, 30, 48, 41, 53, 57, 35, 28, 26, 27,
- 31, 29, 14, 12, 47, 63, 48, 35, 24, 4, -19, -32, -46, -55, -76, -77,
- -58, -31, -30, -33, -36, -8, 12, -4, -9, -22, -51, -57, -30, -23, -27, -40,
- -31, 18, 36, 31, 30, 33, 39, 36, 56, 51, 32, 27, 20, 24, 39, 30,
- 16, 29, 55, 53, 43, 36, 21, -5, -28, -39, -45, -55, -71, -70, -47, -27,
- -35, -36, -25, -2, 1, -4, -6, -23, -48, -48, -25, -16, -25, -46, -23, 24,
- 30, 35, 34, 29, 33, 37, 51, 41, 30, 21, 12, 27, 47, 33, 19, 38,
- 51, 43, 39, 36, 15, -17, -35, -35, -42, -55, -68, -62, -45, -33, -40, -36,
- -19, -5, -4, -3, -6, -24, -47, -38, -17, -13, -37, -48, -13, 26, 30, 36,
- 32, 27, 29, 36, 48, 38, 27, 9, 5, 34, 47, 31, 30, 49, 47, 36,
- 38, 28, 11, -21, -32, -32, -47, -56, -60, -54, -40, -39, -42, -31, -12, -5,
- -7, -1, -4, -21, -39, -28, -11, -13, -45, -42, -2, 23, 25, 42, 33, 26,
- 26, 33, 44, 34, 20, 1, 5, 36, 47, 38, 40, 47, 37, 35, 38, 20,
- 1, -23, -26, -35, -49, -56, -55, -48, -40, -46, -42, -28, -12, -12, -10, 2,
- -6, -25, -32, -25, -13, -22, -43, -30, 5, 18, 24, 45, 35, 29, 21, 27,
- 39, 28, 16, 2, 9, 39, 40, 44, 55, 45, 25, 31, 34, 15, -1, -18,
- -25, -41, -49, -50, -52, -46, -42, -48, -40, -23, -9, -18, -13, 9, -1, -24,
- -27, -22, -14, -30, -41, -26, 8, 15, 25, 40, 36, 26, 15, 26, 35, 21,
- 11, 2, 17, 44, 37, 54, 63, 37, 16, 31, 27, 12, -3, -12, -24, -45,
- -47, -46, -45, -40, -44, -55, -40, -17, -12, -22, -7, 19, -2, -22, -24, -15,
- -17, -36, -36, -11, 16, 10, 17, 38, 43, 25, 15, 25, 26, 14, 7, 2,
- 25, 39, 38, 63, 67, 30, 16, 25, 18, 14, -5, -9, -26, -43, -45, -47,
- -42, -38, -52, -57, -35, -14, -22, -27, 0, 23, -5, -24, -22, -12, -21, -40,
- -31, 1, 19, 6, 11, 35, 44, 22, 18, 28, 14, 4, 4, 11, 32, 34,
- 38, 70, 68, 22, 18, 17, 15, 17, 0, -10, -31, -45, -43, -42, -34, -36,
- -62, -61, -25, -11, -28, -29, 3, 25, -3, -26, -15, -12, -28, -34, -21, 9,
- 17, 2, 10, 31, 40, 24, 23, 28, 5, -3, 6, 19, 35, 33, 42, 72,
- 59, 22, 22, 12, 17, 17, 2, -11, -31, -40, -40, -36, -28, -40, -66, -57,
- -18, -15, -32, -22, 9, 22, -3, -23, -8, -12, -31, -32, -12, 18, 15, -1,
- 9, 25, 36, 26, 27, 20, -7, -5, 12, 23, 29, 33, 45, 70, 48, 25,
- 20, 8, 16, 9, 4, -11, -33, -39, -37, -34, -30, -46, -65, -50, -23, -22,
- -30, -19, 13, 22, -4, -21, -6, -15, -32, -28, -3, 18, 9, 0, 9, 21,
- 30, 28, 30, 12, -14, -1, 17, 19, 27, 41, 51, 63, 35, 28, 22, 12,
- 10, 6, 9, -14, -31, -36, -31, -27, -38, -49, -62, -48, -29, -25, -27, -13,
- 13, 13, -3, -9, -9, -21, -30, -20, 4, 12, 4, 5, 12, 19, 27, 33,
- 29, 6, -12, 2, 21, 17, 31, 45, 54, 55, 31, 31, 25, 14, 3, 5,
- 11, -14, -27, -33, -24, -27, -41, -49, -63, -53, -37, -26, -22, -7, 11, 8,
- 0, -3, -14, -19, -27, -14, 8, 5, 2, 9, 12, 20, 25, 31, 18, 0,
- -6, 8, 20, 14, 27, 43, 59, 48, 24, 28, 25, 14, 2, 8, 6, -15,
- -26, -30, -16, -28, -44, -53, -61, -58, -37, -27, -21, -4, 8, 3, 1, -2,
- -18, -21, -24, -11, 3, -4, 3, 15, 17, 20, 22, 29, 15, 3, -2, 8,
- 17, 18, 30, 46, 56, 40, 21, 29, 26, 14, -1, 5, 4, -6, -22, -29,
- -13, -27, -46, -51, -62, -61, -37, -28, -14, 2, 7, 0, 5, -2, -16, -17,
- -19, -10, -7, -9, 11, 20, 22, 18, 17, 25, 19, 4, -1, 10, 19, 25,
- 32, 44, 53, 36, 19, 29, 24, 10, -4, 5, 4, -2, -22, -24, -13, -31,
- -48, -56, -63, -60, -40, -31, -11, 8, 8, 2, 8, -6, -20, -17, -12, -10,
- -20, -12, 14, 30, 26, 10, 14, 24, 24, -1, -7, 12, 25, 27, 30, 40,
- 52, 34, 17, 28, 24, 7, -9, 1, 8, 3, -20, -20, -16, -33, -53, -59,
- -62, -61, -47, -29, -5, 15, 5, 1, 9, -8, -20, -14, -5, -12, -30, -11,
- 20, 37, 25, 10, 19, 25, 19, -5, -2, 18, 28, 26, 29, 41, 49, 31,
- 20, 30, 24, 1, -8, 4, 10, 3, -17, -12, -18, -40, -57, -61, -62, -59,
- -48, -23, 0, 18, 5, 5, 12, -9, -19, -9, -2, -20, -37, -7, 25, 39,
- 23, 11, 25, 26, 10, -10, 5, 23, 24, 26, 30, 40, 42, 27, 23, 31,
- 18, -7, -5, 2, 7, -1, -10, -10, -22, -45, -59, -63, -62, -58, -45, -21,
- -1, 17, 10, 13, 7, -18, -21, -5, -3, -27, -38, -7, 26, 38, 21, 20,
- 31, 23, 0, -9, 15, 25, 21, 28, 33, 35, 35, 29, 28, 31, 12, -5,
- 0, 0, 4, 0, -3, -14, -27, -48, -57, -69, -66, -61, -40, -19, 1, 16,
- 13, 16, -3, -18, -17, -4, -9, -30, -33, -1, 24, 35, 28, 34, 31, 16,
- -4, -2, 22, 29, 20, 27, 38, 33, 30, 30, 31, 33, 9, 1, -3, -7,
- 2, 6, -1, -22, -31, -50, -61, -74, -67, -52, -34, -25, 1, 19, 21, 14,
- -8, -18, -14, -10, -14, -27, -26, -5, 21, 35, 38, 40, 31, 12, -1, 5,
- 22, 29, 19, 31, 41, 28, 30, 28, 31, 28, 12, 7, -13, -11, -2, 13,
- -5, -26, -32, -52, -67, -80, -65, -46, -34, -26, 2, 15, 25, 9, -8, -14,
- -16, -10, -18, -25, -25, -9, 20, 37, 46, 35, 26, 10, 7, 8, 18, 27,
- 18, 31, 39, 25, 29, 29, 34, 26, 20, 2, -18, -10, -5, 12, -9, -22,
- -31, -48, -74, -79, -66, -42, -34, -22, -1, 14, 25, 13, -6, -19, -16, -8,
- -19, -22, -21, -5, 21, 41, 51, 32, 25, 14, 19, 13, 14, 21, 21, 32,
- 34, 26, 26, 30, 32, 25, 25, -3, -19, -13, -2, 8, -12, -24, -32, -46,
- -75, -79, -67, -43, -33, -18, -7, 12, 25, 18, 0, -23, -13, -7, -23, -18,
- -15, -4, 21, 48, 51, 27, 27, 23, 22, 12, 12, 19, 22, 28, 28, 28,
- 28, 31, 28, 23, 28, -3, -20, -22, -5, 0, -14, -23, -28, -50, -78, -81,
- -63, -44, -34, -19, -14, 10, 25, 18, -6, -19, -5, -11, -30, -17, -8, 2,
- 21, 54, 45, 25, 28, 33, 25, 9, 12, 21, 26, 23, 24, 33, 37, 35,
- 20, 23, 32, -1, -21, -25, -12, -11, -12, -19, -27, -53, -78, -79, -55, -42,
- -31, -26, -18, 12, 24, 13, -9, -12, 0, -20, -33, -13, 1, 6, 26, 55,
- 38, 25, 33, 45, 26, 7, 13, 21, 26, 16, 18, 38, 44, 33, 14, 25,
- 30, 4, -24, -32, -21, -18, -19, -19, -25, -54, -79, -78, -53, -43, -29, -28,
- -20, 6, 20, 12, -3, 0, -3, -35, -28, 1, 9, 8, 25, 46, 34, 30,
- 37, 44, 19, 13, 20, 17, 20, 12, 18, 49, 49, 23, 13, 28, 33, 3,
- -34, -37, -28, -30, -21, -10, -26, -57, -77, -74, -52, -40, -25, -32, -22, 3,
- 17, 12, 3, 8, -15, -40, -18, 10, 10, 4, 32, 39, 27, 38, 48, 39,
- 11, 18, 28, 17, 15, 5, 23, 61, 46, 21, 23, 35, 26, -3, -31, -37,
- -39, -38, -23, -3, -29, -60, -74, -68, -58, -37, -27, -35, -22, -7, 15, 23,
- 14, 8, -27, -41, -6, 19, 14, 9, 35, 31, 31, 48, 54, 35, 11, 27,
- 26, 4, 7, 11, 31, 54, 38, 25, 34, 35, 20, -10, 19, 3, -8, -45,
- 64, -15, -41, 23, 40, -58, 22, 29, -27, -28, 42, -36, 21, -12, -19, 39,
- -14, 3, -18, 32, -27, 18, -8, -43, 43, 25, -52, 6, 19, 13, -7, -50,
- 55, 5, -46, -22, 94, -53, -33, 35, 27, -45, -2, 20, 19, -30, -23, 47,
- 8, -58, 5, 76, -67, -22, 42, 30, -54, 8, 23, 11, -51, 3, 47, -33,
- -7, 5, 27, -33, 34, -35, 17, 4, -26, 5, 17, -30, 33, 5, -29, -5,
- 44, -18, -50, 60, -33, 10, -5, 10, -7, 1, -5, 19, -36, 3, 37, -17,
- -51, 52, 37, -64, 9, 4, 37, -44, -13, 25, 45, -75, -9, 79, -34, -57,
- 53, 24, -59, 18, 22, -3, -24, 10, -2, 18, -53, 29, 35, -20, -43, 37,
- 18, -17, -31, 8, 45, -49, 8, 11, 9, -23, 30, -24, -22, 29, 14, -43,
- 27, 13, -22, -1, 2, 22, -37, 5, -5, 38, -43, 6, 36, -21, -20, 20,
- 0, -5, -27, 27, 21, -53, 4, 52, -2, -84, 70, 5, -29, -19, 36, -6,
- -8, -12, 3, 35, -32, -25, 48, 6, -60, 49, 4, -27, -13, 31, -15, -9,
- -4, 31, -13, -25, 29, 12, -34, -6, 30, -41, 36, -23, 6, 31, -30, 0,
- 17, -45, 47, -5, -47, 19, 28, -8, -30, 27, -6, 15, -54, 34, 21, -27,
- -9, 25, 3, -45, 26, 27, -52, 22, 20, -29, 34, -46, 22, 40, -69, -27,
- 108, -49, -54, 69, -11, -3, -18, 3, 15, -12, -23, 29, -8, 4, -23, 50,
- -38, -8, 33, -32, -2, 26, -27, 12, 13, -39, 56, -31, -22, 28, 2, -39,
- 54, -20, -36, 51, -6, -34, 15, 2, 1, 2, -36, 42, 2, -10, -39, 64,
- -36, -16, 24, 1, -1, -18, -10, 54, -27, -54, 80, -18, -61, 51, 27, -76,
- 64, -30, -1, 9, -19, 24, 13, -29, -13, 49, -18, -46, 43, 6, -47, 42,
- -28, 14, 18, -18, 2, 14, -39, 25, 16, -58, 33, 29, -49, 16, 41, -62,
- 43, -17, -17, 25, -10, -28, 41, -5, -30, 27, 14, -53, 27, 35, -63, 16,
- 30, 0, -30, -10, 22, 31, -57, 0, 68, -59, 2, 37, -30, 6, -3, -19,
- 35, -29, 1, 20, 22, -68, 33, 39, -71, 21, 27, -22, -1, 3, 0, 18,
- -16, -13, 17, 4, -37, 44, -15, -26, 48, -29, -11, 34, -25, -4, 25, -48,
- 43, 4, -49, 28, 42, -72, 7, 59, -36, -28, 45, -9, -28, 25, -19, 23,
- -9, -40, 47, 18, -85, 78, -2, -53, 39, -17, 2, 14, -36, 10, 63, -78,
- 17, 59, -66, -8, 54, -49, 14, 1, 5, 2, -18, 16, -12, 30, -58, 22,
- 53, -83, 17, 79, -84, 19, 17, -34, 44, -33, -27, 82, -62, -19, 91, -93,
- 22, 49, -51, -25, 48, -12, -6, 1, -2, -1, 22, -32, -1, 59, -78, 12,
- 58, -49, -26, 70, -40, -8, 16, -8, 12, 10, -65, 74, -1, -97, 90, 0,
- -56, 23, 25, -17, 11, -23, 14, 9, -24, -31, 77, -41, -48, 95, -38, -46,
- 59, -1, -57, 49, -33, 19, 18, -46, 34, 31, -79, 47, 11, -38, 10, 19,
- -14, -10, 26, -29, 28, -17, -27, 48, -15, -51, 78, -14, -73, 64, 12, -55,
- 29, 3, -24, 52, -65, 26, 50, -75, -5, 81, -76, 0, 42, -6, -26, 10,
- 18, -14, 4, -24, 33, 2, -69, 61, 43, -101, 40, 54, -73, 22, 18, -41,
- 44, -19, -43, 94, -69, -13, 65, -26, -46, 35, 24, -34, -2, 23, -13, 6,
- -19, 4, 38, -56, 14, 40, -37, -19, 66, -57, -9, 50, -47, 21, 6, -31,
- 55, -34, -50, 98, -44, -47, 44, 28, -51, 6, 31, -3, -34, 8, 11, 6,
- -18, -27, 78, -48, -28, 55, -2, -60, 57, -37, 14, 15, -48, 49, 22, -96,
- 74, 23, -83, 36, 18, -17, -25, 41, -12, -4, -2, 1, 9, -14, -18, 36,
- 12, -77, 54, 32, -67, 20, 38, -67, 61, -53, 32, 21, -60, 27, 41, -74,
- 27, 33, -30, -6, 22, -1, -30, 20, 1, -4, -22, 9, 8, 37, -65, 18,
- 61, -69, -3, 37, -19, -15, 15, -16, 57, -78, 20, 66, -67, -27, 76, -37,
- -16, 11, 11, -5, -18, 10, 16, -5, -38, 36, 9, -20, -32, 73, -41, -36,
- 62, -33, -9, 34, -41, 35, -7, -40, 65, -35, -26, 33, 2, -43, 42, -4,
- -9, 5, -11, 19, -10, -16, 11, 16, -28, -9, 41, 2, -70, 67, -3, -55,
- 23, 33, -26, 6, -29, 43, 16, -85, 51, 28, -54, 7, 27, -9, 2, -18,
- 27, -4, -42, 31, 10, -19, -9, 18, 8, -24, -3, 45, -57, 25, 0, -7,
- 15, -28, 10, 33, -46, -6, 52, -36, -15, 46, -29, -4, 12, -14, 34, -57,
- 16, 40, -41, 3, 16, 8, -32, 16, 15, -17, -27, 47, -30, -1, 14, -5,
- 16, -17, -33, 70, -44, -42, 84, -34, -27, 18, 15, 3, -20, -22, 55, -35,
- -22, 31, 10, -11, -27, 27, 13, -28, -10, 41, -21, -3, -22, 41, -21, -13,
- 6, 34, -68, 46, 25, -65, 50, -21, -1, 10, -33, 34, 1, -43, 58, -34,
- -2, 13, 8, -25, 0, -2, 34, -29, -26, 45, -12, 4, -34, 32, 15, -54,
- 17, 53, -76, 41, 4, -17, 13, -26, 13, 31, -47, 1, 52, -53, 11, 8,
- 14, -31, -7, 19, 30, -60, 26, 27, -22, -10, 0, 18, -13, -24, 52, -38,
- -17, 68, -60, 26, -9, -25, 41, -29, -8, 40, -25, -9, 26, -28, 15, -9,
- -3, 11, -21, -1, 44, -47, 19, 0, 3, -14, -12, 38, -22, -23, 37, -10,
- -13, 9, -6, 21, -14, -39, 61, -4, -68, 60, 6, -43, 28, -14, 21, -22,
- -13, 36, -7, -40, 46, -14, -5, -18, 20, 22, -49, 22, 10, -18, 21, -30,
- 9, 34, -54, 19, 22, -34, 27, 7, -45, 30, 0, -20, 23, -23, 29, -10,
- -21, 25, 3, -23, -1, 5, 16, -33, 14, 25, -21, -11, 16, 3, -22, 5,
- 6, 32, -73, 27, 62, -72, 5, 26, -21, 30, -37, 4, 40, -45, 5, 18,
- -18, -1, 12, -3, 0, -18, 28, -8, -14, 11, -11, 13, -15, -3, 27, -17,
- -30, 65, -45, -5, 28, -25, 1, 20, -36, 38, -11, -20, 35, -23, -20, 27,
- 11, -42, 13, 17, 1, -25, 20, 10, -33, 10, 6, -7, 9, -26, 40, -3,
- -63, 74, -30, -11, 10, -10, 5, 17, -47, 53, -10, -47, 29, 31, -45, 4,
- 16, 14, -15, -33, 40, -11, -3, -10, 2, 18, -20, 9, 22, -44, 19, 20,
- -42, 25, -5, -11, 25, -25, -3, 47, -63, 28, 20, -42, 7, 39, -41, 2,
- 13, 10, -24, -8, 41, -26, -1, -13, 9, 42, -60, 0, 61, -54, -4, 19,
- -6, 11, -19, -13, 52, -37, -26, 66, -38, -30, 49, -18, -11, 5, 7, 10,
- -30, 4, 17, 2, -12, -15, 38, -19, -20, 30, -16, -23, 38, -13, -16, 29,
- -22, 26, -17, -35, 62, -30, -35, 51, -16, -27, 40, -16, 3, -8, -4, 9,
- 4, -26, 11, 20, -11, -38, 56, -19, -29, 31, 7, -39, 17, 10, 6, -8,
- -41, 45, 26, -79, 36, 42, -58, 21, 6, -10, 7, -19, 17, -1, -15, -12,
- 53, -22, -32, 24, 25, -59, 24, 22, -36, 10, 18, -27, 44, -45, 0, 42,
- -45, -2, 30, -27, 12, 23, -38, 13, 5, 4, -4, -20, 1, 43, -27, -36,
- 43, 14, -51, 12, 40, -41, 5, 18, -11, -1, -5, -11, 53, -56, -29, 91,
- -41, -45, 57, -7, -18, -3, -4, 29, -20, -19, 20, 26, -57, 31, 17, -22,
- -13, 28, -31, 3, 36, -33, 9, 17, -39, 42, -9, -54, 58, 6, -69, 44,
- 30, -50, 24, 3, -17, 9, -20, 17, 8, -23, 1, 46, -50, 1, 27, 1,
- -49, 37, 5, -17, 4, -5, 7, 18, -55, 39, 36, -85, 37, 48, -63, 5,
- 27, -13, -6, -4, 5, 24, -26, -12, 42, -25, -34, 33, 20, -33, -13, 29,
- -2, 7, -34, 12, 37, -50, 1, 47, -46, -1, 56, -54, -18, 59, -35, -6,
- 12, -16, 20, -2, -27, 43, -12, -34, 22, 25, -41, -7, 43, -20, -18, 19,
- -1, 1, -6, -20, 54, -55, -12, 67, -24, -56, 56, -8, -12, -7, -3, 16,
- 20, -48, 20, 32, -46, 8, 23, -17, -38, 54, 1, -34, 2, 30, -1, -21,
- -18, 38, -14, -35, 41, 3, -36, 19, 22, -45, 40, -32, 12, 12, -26, 2,
- 35, -54, 34, 14, -25, -30, 47, 10, -53, 24, 13, -4, -18, 3, 5, 27,
- -61, 38, 15, -39, 6, 40, -36, 0, 2, -6, 28, -40, 7, 46, -37, -30,
- 59, -21, -29, 6, 48, -55, 12, 30, -21, -6, 5, -2, 1, -14, -7, 46,
- -41, -4, 35, -8, -33, 29, -20, 26, -31, -10, 63, -46, -4, 12, 7, -11,
- -15, 26, -14, -22, 54, -47, 12, 9, -1, -8, -7, -8, 41, -12, -60, 77,
- -21, -26, 11, 13, 1, -26, -9, 59, -45, -16, 38, -3, -27, -1, 28, -8,
- -19, 11, 20, -41, 34, -23, 22, -20, -9, 6, 51, -79, 40, 18, -40, 23,
- -5, -19, 13, 2, 3, -4, -35, 71, -39, 5, -30, 33, 6, -29, -3, 38,
- -29, -5, 18, -9, -4, -11, 16, 15, -32, -14, 77, -83, 30, 10, -10, -19,
- 20, 15, -17, -19, 29, 7, -32, 6, -1, 14, -14, -6, 5, 36, -58, 47,
- -18, -14, 4, 8, 8, -24, -15, 60, -36, -20, 43, -32, 3, -2, 1, 9,
- -5, -8, 30, -33, 6, 6, 2, -12, -11, 24, 1, -22, 9, 34, -61, 25,
- 11, -5, -18, -1, 38, -19, -33, 49, -19, -21, 18, -7, 1, 5, -4, -3,
- 13, -30, 25, -5, -12, 2, 8, 17, -37, 0, 50, -38, -26, 40, -15, 7,
- -24, 31, -11, -8, 6, -6, -3, 1, 9, -8, 6, -20, 25, 0, -21, 7,
- 22, -48, 29, -4, 10, -22, 7, 22, -9, -34, 45, -15, -31, 30, -2, 0,
- -30, 46, -18, -6, -17, 31, -6, -7, -21, 8, 45, -47, -7, 31, -17, -11,
- 25, -20, 17, -30, 47, -38, -2, 5, 16, -36, 24, -2, 3, -7, 6, 10,
- -23, 5, -11, 35, -42, 17, 0, 21, -35, 11, 16, -18, -15, 36, -24, -3,
- 9, 5, 13, -49, 36, -11, -2, -14, 37, -32, 13, -1, 0, -2, -2, -8,
- 17, -11, -21, 30, -1, -1, -41, 72, -65, 14, 14, 12, -41, 21, 4, 15,
- -32, -1, 25, -9, -18, 3, 29, -38, 35, -22, 14, -20, 16, -6, -6, -13,
- 29, -4, -17, 7, 14, -6, -38, 54, -32, 3, -16, 36, -39, 42, -40, 36,
- -22, -13, 17, 14, -36, 12, 23, -25, 6, -25, 53, -33, -12, 5, 37, -46,
- 6, 20, 9, -53, 52, -16, -22, 24, -9, 10, -17, 12, -20, 48, -73, 40,
- 18, -30, -20, 52, -34, 11, -6, 0, 1, -15, 24, -16, 16, -30, 44, -27,
- -10, 0, 34, -52, 24, 3, 2, -6, 12, -25, 35, -38, -14, 72, -73, 7,
- 31, 15, -50, 20, 12, -5, -25, 23, 3, -10, -9, 15, 9, -41, 28, 6,
- -5, -36, 44, -13, 10, -19, 2, 14, -10, -29, 56, -27, -35, 58, -19, -27,
- 17, 16, -30, 10, -7, 15, -12, -3, 11, 18, -30, -13, 38, -17, -16, 3,
- 32, -37, 23, -24, 30, -12, -26, 40, -14, -52, 59, 12, -55, 16, 35, -20,
- -30, 39, -24, 21, -26, 12, 13, -10, -19, 23, 2, -35, 17, 33, -30, -17,
- 39, -15, 12, -53, 50, -13, -25, 2, 50, -42, -1, 25, -22, 6, -5, 3,
- -4, 2, -18, 39, -25, -3, 1, 29, -57, 22, 26, -22, -18, 34, -10, -10,
- -11, 13, 31, -77, 46, 23, -22, -35, 61, -24, -13, 7, -3, 0, 4, -24,
- 27, 12, -50, 35, 13, -19, -37, 69, -46, -4, 13, 5, -8, 6, -25, 40,
- -26, -13, 38, -12, -28, 21, 22, -57, 40, -15, 11, -19, 4, 19, 9, -36,
- 3, 42, -35, -30, 46, 0, -50, 59, -26, 9, -16, 12, -10, 10, -33, 44,
- -8, -29, 8, 42, -43, -6, 26, -19, 14, -30, 34, 4, -21, -17, 49, -31,
- -24, 34, 14, -53, 32, 13, -26, 12, -22, 26, -3, -22, -11, 66, -59, 0,
- 43, -27, -23, 42, -32, 7, -7, 11, 9, -19, -1, 15, 16, -58, 43, 1,
- -32, 11, 36, -44, 18, 0, 4, -4, -7, -22, 50, -22, -44, 67, -14, -43,
- 37, 2, -32, 15, 7, 8, -22, -1, 14, 19, -43, 0, 40, -30, -14, 28,
- 10, -32, 11, 1, 21, -33, -9, 31, 15, -72, 61, 4, -40, 21, 14, -37,
- 22, 4, -4, -9, 5, -8, 23, -16, -22, 35, -24, 0, 12, 3, -17, 15,
- 2, -10, -6, -8, 21, 7, -58, 40, 43, -75, 25, 28, -25, -18, 28, -15,
- 6, -5, -4, 22, -5, -39, 37, 1, -30, 12, 23, -27, -8, 34, -22, 0,
- -12, 15, 10, -28, 2, 45, -45, -9, 36, -22, -7, 13, -7, 6, 2, -18,
- 17, 10, -34, 9, 18, -22, -1, 22, -9, -17, 23, -1, -22, 21, -20, 20,
- -17, -6, 38, -33, -18, 55, -32, -21, 26, -5, -9, 5, -8, 16, 9, -47,
- 36, 11, -36, -3, 38, -7, -48, 44, -2, -11, 2, -16, 15, 11, -36, 33,
- -3, -18, 9, 19, -46, 26, -1, -11, 20, -24, 12, 16, -16, -17, 37, -32,
- -6, 13, 13, -33, 25, 14, -27, 8, 1, -18, 22, -5, -15, 32, -46, 37,
- -2, -19, -13, 38, -32, 8, 2, -4, 15, -12, -4, 19, -25, -10, 37, -19,
- -11, -10, 57, -54, 19, -17, 18, 3, -18, -9, 27, -6, -36, 57, -23, -21,
- 14, 11, -23, 32, -53, 56, -24, -5, -3, 11, -16, 16, -7, -20, 17, 11,
- -3, -31, 42, -33, 14, -6, -2, -8, 39, -56, 48, -21, -20, 30, -8, -20,
- 12, 15, -32, 41, -36, 29, -25, 14, -22, 22, -19, 9, 4, 10, -31, 17,
- 11, -14, -1, -7, 17, -16, 6, -18, 64, -88, 47, 6, -20, -5, 22, -13,
- 18, -28, 2, 25, -19, -10, -3, 29, -23, 11, -22, 39, -25, 13, -27, 20,
- -2, -18, 15, -3, 3, 9, -17, -8, 38, -57, 35, 1, -9, -24, 43, -32,
- 30, -30, -3, 19, -3, -21, 12, 14, -12, 2, -5, 11, -37, 37, -3, -13,
- -4, 10, 11, -4, -38, 41, -9, -27, 37, -37, 16, 17, -7, -15, 22, -40,
- 33, -2, -16, 4, 3, 8, -4, -20, 21, -3, -10, 8, -26, 37, -21, 8,
- 0, -3, -3, 0, -8, 20, -15, -32, 54, -10, -26, 17, -12, 10, 24, -71,
- 51, 3, -21, 9, -3, 17, -22, 2, 15, -21, -11, 39, -25, 11, -27, 28,
- 3, -11, -26, 45, -43, 24, 7, -39, 47, -24, -15, 27, -13, -15, 35, -27,
- 15, -17, 9, 0, -7, 0, 4, -9, 13, -3, -16, 28, -29, 21, -23, 11,
- -4, 10, -30, 64, -63, 13, 28, -30, 16, -13, 0, 25, -39, -2, 53, -40,
- 5, -19, 41, -25, -6, -3, 37, -40, 6, 8, 0, 6, -34, 32, 4, -27,
- 13, 15, -34, 52, -63, 40, -5, -22, 5, 24, -32, 22, 11, -26, 14, -22,
- 26, -21, 10, -8, 5, -10, 46, -66, 44, -20, 14, -7, -27, 23, 30, -53,
- 24, 10, -37, 44, -40, 21, -11, 3, 6, 20, -47, 27, 5, -2, -18, -4,
- 29, -13, -20, 27, 9, -47, 43, -37, 55, -62, 14, 33, -13, -28, 24, -9,
- 23, -35, -4, 32, -14, -13, 28, -10, -30, 46, -43, 43, -46, 13, 13, -10,
- 7, -3, -20, 39, -19, -19, 14, -15, 39, -31, -10, 25, 2, -34, 41, -35,
- 15, -4, -3, 22, -18, -27, 46, -1, -36, 10, -4, 42, -56, 13, 31, -19,
- -18, 28, -29, 27, -32, 24, 10, -44, 20, 32, -32, -17, 32, -13, 13, -35,
- 20, 32, -53, 20, 9, -16, 16, -36, 39, -3, -33, 43, -26, 2, 2, 2,
- -17, 24, -22, 14, -3, -12, 31, -28, -8, 26, -29, 19, -4, -15, 33, -39,
- 22, 16, -37, 6, 17, -4, -13, -12, 37, 9, -65, 34, 25, -27, -9, 7,
- 5, 10, -36, 45, -11, -41, 42, -6, -21, 7, -5, 31, -5, -57, 62, -12,
- -15, -16, 23, 4, -24, 12, 26, -35, -11, 44, -25, -8, -1, -4, 28, -11,
- -37, 61, -48, 23, -1, -30, 29, -8, -2, 6, -19, 18, 15, -41, 30, -4,
- -11, -11, 28, -10, -4, -37, 81, -45, -43, 61, -19, 1, -11, 0, 31, -30,
- -25, 68, -43, -11, 0, 27, -1, -33, -7, 77, -54, -30, 44, -6, -5, -14,
- 17, -6, -10, 6, 30, -68, 50, -16, 5, 5, -30, 30, 26, -69, 36, 8,
- -34, 37, -28, 11, 0, -1, 9, 1, -41, 53, -22, -24, 23, 5, -9, -11,
- 12, 28, -61, 28, 36, -68, 51, -33, 25, -6, -26, 7, 53, -65, 2, 47,
- -25, -23, 17, 20, -4, -51, 38, 29, -67, 31, 1, 22, -35, -8, 40, -9,
- -46, 47, -13, -8, 5, -15, 37, -27, -20, 45, -16, -45, 59, -37, 19, -6,
- 2, 1, -11, -3, 34, -42, 0, 33, -30, 16, -13, 13, 2, -23, 18, -5,
- -26, 43, -24, 15, -26, 4, 35, -15, -62, 64, 19, -75, 50, -8, 8, -14,
- -12, 31, -19, -30, 45, -10, -12, -10, 36, 3, -53, 14, 45, -37, -22, 42,
- -25, 21, -36, 21, 37, -61, 5, 47, -49, 19, -4, 5, 1, -12, 7, 3,
- -11, 2, 18, -28, 13, -4, 18, -13, -20, 33, -22, -8, 21, -12, -10, 24,
- -9, 2, -27, 15, 33, -41, -18, 56, -40, 9, -5, 6, 20, -44, 11, 39,
- -35, -22, 50, -7, -36, -6, 41, -10, -30, 15, 20, -22, 7, -11, 16, 6,
- -51, 59, -21, -26, 24, 12, -24, 8, -7, 12, 3, -36, 27, 18, -42, 22,
- 9, -22, 11, -2, 15, -40, 38, -13, -16, 8, 24, -33, 15, -13, 4, 23,
- -42, 17, 30, -34, -5, 28, -22, 11, -23, 30, -14, -28, 37, 12, -46, 11,
- 31, -23, -12, -7, 36, -17, -6, -4, 25, -18, 4, -29, 53, -48, 4, 24,
- -9, -21, 30, -1, -20, 2, -13, 51, -51, -1, 39, -23, -18, 33, -23, 3,
- 3, 2, -13, 11, 4, -13, 15, -14, -3, 1, 24, -53, 55, -24, -17, 36,
- -1, -49, 45, -7, -12, -2, -4, 24, -23, 1, 6, 23, -51, 30, -8, 14,
- -29, 17, 12, -9, -21, 21, 1, 3, -32, 21, 30, -59, 27, 25, -21, -26,
- 36, -24, 16, -23, 15, 10, -15, 11, -11, -3, 14, 1, -30, 32, -24, 27,
- -25, 10, -12, 29, -33, 7, -5, 25, -29, 14, 15, -42, 20, 18, -27, 1,
- 21, -19, 17, -18, 2, 19, -12, -34, 47, -21, -6, 9, -2, 14, -32, 32,
- -23, 14, -21, 21, 0, -13, -8, 42, -35, -19, 33, 4, -34, 23, -5, -6,
- 22, -31, 21, -8, -5, -3, 15, -22, 10, 2, 7, -17, 11, 3, -10, 2,
- -1, -2, -9, 25, -20, 11, -18, 17, -3, -12, 2, 9, -1, -10, 5, 0,
- 15, -40, 36, -5, -28, 16, 24, -34, 16, -1, 13, -32, 11, 9, 5, -26,
- 5, 32, -32, 4, -1, 29, -38, 8, 7, -6, 5, -2, -5, 18, -26, -2,
- 39, -42, 0, 26, 2, -43, 45, -30, 20, -11, -6, -3, 16, -7, -6, 3,
- 12, -13, 5, -7, -21, 47, -29, -11, 9, 36, -45, 8, 0, 22, -28, -7,
- 32, -22, -9, 20, 12, -40, 24, -8, 14, -28, 10, 9, 12, -29, 15, -7,
- 15, -23, 5, 14, -24, 12, 8, 4, -38, 36, -4, -7, -30, 47, -13, -24,
- 16, 23, -46, 29, -3, -10, 20, -43, 35, 0, -4, -30, 47, -18, -21, 16,
- 19, -35, 11, 19, -21, -11, 27, -12, -9, 16, -21, 23, -32, 30, 3, -22,
- -15, 51, -38, -1, -2, 11, 15, -28, -1, 16, 13, -42, 23, 4, -6, -32,
- 61, -24, -35, 34, 29, -55, 4, 13, 9, -6, -26, 35, -6, -11, -11, 19,
- -6, -3, -15, 43, -41, 4, 22, -1, -34, 18, 15, -35, 18, -1, 23, -35,
- 18, -2, -9, 1, 10, -18, 17, -18, 21, -8, -17, 24, -1, -20, -7, 26,
- -11, 6, -33, 42, 0, -40, 9, 46, -48, -6, 24, 13, -39, 8, 41, -43,
- 3, 6, 6, -7, -6, -8, 42, -37, -11, 39, -16, -26, 25, 3, -24, 9,
- 11, 6, -34, 17, 14, -12, -22, 20, 0, 14, -38, 27, 10, -37, 22, -1,
- -5, -7, 11, 4, -3, -29, 38, -5, -26, 4, 20, -17, 6, 2, 11, -17,
- -10, 40, -49, 10, 26, -8, -24, 11, 12, 5, -36, 21, 20, -22, -29, 28,
- 30, -30, -24, 31, 25, -70, 39, 4, -16, 3, 9, -13, 16, -26, 23, 19,
- -46, 1, 29, 6, -37, 8, 27, -8, -33, 36, -24, 5, 14, -8, -8, 1,
- 4, 15, -27, -11, 44, -38, 6, 12, -3, -12, 20, -17, 16, -35, 28, -4,
- 0, -13, 8, 23, -24, -16, 28, 11, -58, 48, 6, -39, 11, 24, -9, -8,
- -25, 42, -16, -14, 12, 2, 13, -31, 6, 26, -10, -48, 64, -22, -21, 6,
- 28, -15, -11, -2, 22, -30, 11, 15, -25, 13, 2, -1, -7, -4, 6, 17,
- -37, 17, 0, 1, 14, -23, 4, 16, -23, 6, 12, -31, 30, 6, -18, -25,
- 45, -7, -20, -15, 44, -38, 9, 22, -37, 24, 6, -20, 14, -17, -8, 44,
- -27, -22, 16, 30, -33, -18, 20, 31, -50, 11, 27, -21, -4, -3, 26, -15,
- -24, 15, 20, -27, 16, -12, 9, 5, -24, 3, 26, -27, 5, 15, -19, 9,
- -9, 26, -25, -5, 10, -4, -6, 31, -45, 18, 24, -23, -23, 27, -3, 2,
- -18, 9, 13, -18, 19, -17, 7, -1, -24, 31, 5, -49, 31, 32, -40, -7,
- 10, 14, -12, -12, 5, 21, -30, 25, -12, 4, -18, 9, 11, -13, -20, 37,
- -8, -3, -13, -3, 33, -21, -32, 44, -7, -22, 28, -24, 5, 12, -19, 2,
- 6, 2, -16, 11, 10, -6, -23, 31, -25, 7, 6, -16, 18, 1, -35, 40,
- -9, -18, 12, 4, -2, -25, 20, 19, -16, -35, 46, -14, -8, -3, -1, 24,
- -12, -25, 26, -4, -6, 3, -12, 20, -24, 18, 9, -20, -2, 18, -13, -1,
- -16, 8, 26, -35, 12, 10, -11, 6, 2, -30, 46, -43, 16, 6, 1, -20,
- 26, -18, 8, -13, 9, -3, 3, 1, -25, 29, 13, -50, 12, 41, -47, 15,
- 14, -12, 2, -3, -1, 14, -25, -3, 26, -23, 19, -35, 41, -5, -23, -1,
- 31, -30, 8, -15, 32, -29, -7, 22, 10, -35, 12, 6, -2, 20, -50, 36,
- 7, -17, -4, -1, 7, 2, -21, 19, -12, 1, 28, -25, -5, 9, -3, -12,
- 32, -45, 16, 21, 0, -43, 21, 28, -19, -38, 45, -15, -8, 28, -43, 39,
- -12, -23, 13, 19, -39, 23, -3, 17, -32, 6, 20, -5, -32, 23, 8, -15,
- -1, 11, 9, -28, 5, 20, -18, -6, 9, -18, 50, -50, -8, 49, -30, -5,
- -4, 14, -19, 28, -21, 2, 4, 11, -20, 6, 3, -5, -24, 54, -34, -14,
- 26, -4, -2, -16, 5, 20, -23, 1, 6, -9, 32, -37, 1, 25, -22, -8,
- 31, -6, -37, 31, 0, 3, -37, 24, 25, -27, -20, 27, 1, 4, -26, 13,
- 3, -14, 12, -6, 6, -3, -6, 18, -14, -27, 38, 5, -36, 14, 13, -22,
- 26, -13, -22, 36, -23, -5, 3, 18, -12, -23, 31, -5, -24, 23, -15, 17,
- -7, -23, 20, 6, -4, -19, 20, -8, 15, -32, 13, 17, -30, 17, 13, -19,
- -8, 4, 24, -18, -29, 36, 7, -21, -20, 28, 13, -17, -31, 36, -9, -7,
- 7, 6, -9, -4, 7, -6, 10, -32, 41, -26, 12, -10, -12, 35, -10, -39,
- 36, -9, -7, 7, 6, -9, -4, 11, -14, 5, -7, 9, -13, 24, -27, 4,
- 14, 7, -31, 19, -14, 17, -5, -34, 57, -31, -7, -6, 28, -15, -11, 2,
- 25, -21, -14, 15, 18, -35, 12, 1, 9, -20, -2, 32, -37, 26, -17, 7,
- 1, -10, -18, 54, -37, -16, 23, 11, -13, -23, 34, -5, -16, -10, 25, -28,
- 30, -10, -7, -5, 18, -24, 25, -24, 18, -11, 0, 3, -19, 34, -12, -12,
- 2, 3, -13, 32, -37, 20, 4, -6, -25, 29, -3, -2, -11, -2, 28, -38,
- 18, 7, -5, -7, 0, -4, 21, -36, 30, -19, 25, -29, -15, 48, -11, -43,
- 33, 33, -64, 17, 26, -12, -18, 9, -1, 18, -33, 23, -13, 21, -18, -13,
- 18, -2, -20, 20, 6, -15, 4, -12, 28, -27, 1, 10, -5, 3, 0, -17,
- 15, 17, -30, 2, 5, -8, 17, -11, -2, 9, -20, 23, -27, 23, -10, -3,
- 7, -3, -25, 31, 9, -28, -9, 30, -5, -28, 15, 29, -36, -9, 29, -11,
- -20, 33, -27, 21, -14, -12, 21, -3, -9, -2, 12, -5, -27, 27, 7, -20,
- -11, 32, -9, -15, -1, 9, 20, -42, 12, 9, -4, 3, -6, -3, 6, 0,
- -12, 15, -25, 27, -6, -6, -6, 6, -2, -4, 5, 9, -20, 12, 8, -17,
- -10, 30, -12, -24, 25, -15, 18, -21, 21, -8, -6, -9, 12, -6, 15, -33,
- 26, 8, -32, 13, 21, -12, -28, 20, 11, -6, -28, 27, 11, -21, -10, 22,
- -1, -11, -7, 24, -12, -27, 35, -8, 0, -20, 23, -10, 9, -30, 32, -15,
- 3, -7, 6, -2, 10, -17, 1, 8, -4, -5, -3, 14, -9, 1, -11, 18,
- -13, 15, -33, 22, 14, -32, 11, 9, -1, -17, 14, 0, -3, -16, 29, -21,
- -4, -1, 28, -24, -2, -11, 41, -25, -23, 24, 6, -18, -13, 37, -21, -2,
- -4, 29, -40, 11, 12, 4, -25, 12, -9, 23, -17, -14, 27, -2, -26, 9,
- 18, -14, -1, -15, 29, -18, -4, 5, 12, -26, 18, -3, -7, 3, 13, -10,
- -25, 44, -38, 11, 8, -2, -25, 28, -9, 12, -13, -13, 10, 27, -53, 19,
- 16, -4, -20, 12, 12, -21, 5, 12, 3, -35, 22, 8, 0, -28, 18, 16,
- -25, -3, 9, 8, -3, -19, 8, 24, -34, -4, 38, -16, -30, 29, -1, -2,
- -25, 28, -1, -21, 11, 10, -18, -1, 10, 1, -7, 0, 1, -7, 15, -15,
- -5, 16, 2, -22, 8, 0, -1, 26, -34, -22, 56, -26, -11, 12, 9, -9,
- -9, 4, 7, -8, -1, 8, 0, -21, 10, 19, -8, -25, 17, 10, -18, 3,
- -4, 26, -15, -29, 30, 9, -46, 36, 12, -33, 1, 18, -2, -16, 4, 16,
- -10, -16, 11, 2, 8, -19, 5, 1, 10, -21, 20, -8, -1, -3, 1, 7,
- -19, 7, 11, -12, 5, 5, -26, 29, -11, -5, -2, 12, -13, 9, -22, 23,
- 3, -20, 4, 17, -16, -13, 17, 15, -16, -34, 37, -5, 8, -32, 23, 17,
- -36, -2, 36, -25, -4, 28, -18, -20, 15, 4, 7, -12, -24, 43, -19, 0,
- -11, 25, -9, -12, -7, 10, -1, 11, -2, -12, 13, -27, 30, -9, -15, 8,
- 17, -28, 18, -9, 3, 7, -8, -10, 16, -26, 35, -22, -10, 37, -35, 1,
- 11, 11, -19, -2, 9, 17, -37, 11, 10, 9, -16, -12, 27, -11, -22, 16,
- 24, -48, 25, -1, -3, 4, -20, 13, 39, -72, 34, 1, 2, -6, 4, -1,
- -8, 2, -8, 18, -10, -1, -5, 19, -30, 5, 30, -16, -26, 36, -26, 3,
- 21, -27, 10, 4, -10, 0, -4, 15, 9, -41, 32, -11, 2, -11, 15, -3,
- -7, -8, 16, -3, -21, 23, -2, -9, -4, -2, 20, -5, -37, 49, -20, -6,
- -9, 17, 17, -36, -8, 40, -24, -5, 3, 8, 5, -12, -6, 15, 2, -27,
- 28, -4, -23, 16, 5, -1, -26, 29, 11, -38, 22, -12, -8, 38, -34, -3,
- 10, 4, -2, -5, -8, 24, -16, -20, 21, 1, -7, 11, -7, -4, -15, 15,
- 15, -21, -6, 10, -1, 17, -45, 23, 29, -42, 2, 18, -5, -6, -1, 22,
- -20, -19, 16, 21, -20, -18, 23, 2, 5, -41, 36, 10, -34, 12, 12, -25,
- 11, 1, 6, -6, -11, 20, -11, 10, -11, -12, 13, 8, -21, 5, -1, 14,
- 3, -26, 5, 27, -39, 18, 7, -27, 34, -20, 13, -20, 7, -4, 25, -23,
- -16, 7, 47, -35, -29, 37, 10, -35, 4, 12, -1, 0, -15, 25, -23, -12,
- 35, 7, -51, 28, -1, 16, -33, 5, 27, -21, 2, -5, 13, -3, 0, -20,
- 27, -30, 8, 16, -4, -13, 14, -15, 19, -12, -6, 8, -9, 19, -27, 4,
- 20, -9, -12, 21, -37, 41, -22, 1, 1, 13, -33, 20, 14, -30, -2, 22,
- 21, -51, 3, 38, -7, -35, 17, 6, 11, -43, 33, 9, -36, 10, 31, -24,
- -13, 16, -6, 24, -36, -1, 16, 19, -45, 20, 11, 2, -30, 31, -21, -14,
- 29, -4, -12, 3, -6, 9, 15, -37, 20, -4, 8, -18, 12, -7, 17, -8,
- -12, -9, 23, 8, -28, 1, 29, -19, -18, 27, -2, -8, -28, 44, -4, -36,
- 15, 33, -30, -13, 13, 14, -20, -7, 25, -11, -5, -8, 21, -1, -8, -37,
- 50, 1, -53, 27, 28, -21, -10, 4, 16, -24, 10, 6, -12, 0, 2, 6,
- 1, -13, 2, 21, -26, 3, 13, -19, 10, 9, -18, -3, 22, -18, -1, -2,
- 14, -1, -23, 21, -6, -2, -9, 20, 5, -35, 1, 34, -21, -16, 22, 1,
- -8, -5, 1, 18, -12, -23, 18, 5, -17, -7, 37, -6, -35, 6, 47, -44,
- -7, 20, 5, -10, -23, 35, -6, -12, -12, 39, -27, -10, 9, 21, -21, -6,
- 2, 5, 1, 6, -28, 17, 20, -31, -3, 15, 7, -26, 31, -40, 43, -32,
- 23, -19, 11, -22, 26, -6, -1, -25, 33, 2, -25, -7, 9, 26, -16, -30,
- 29, 20, -47, 13, 16, -9, -19, 18, 23, -32, -17, 32, 21, -38, -13, 14,
- 43, -66, 19, 23, 5, -50, 47, -20, 2, -11, 22, -5, -6, -21, 4, 38,
- -15, -32, 12, 35, -35, -4, 7, 18, -17, -1, -7, 6, 5, 0, 0, -7,
- 0, -8, 21, -10, 5, -28, 30, 3, -17, -29, 57, -16, -17, -10, 28, -9,
- -20, 26, -12, 3, -20, 27, -3, -7, -42, 65, -9, -45, -3, 63, -33, -11,
- -6, 28, -17, -1, -6, 6, 7, -12, 0, 25, -21, -30, 54, -9, -37, 1,
- 28, 7, -42, 18, 11, 17, -46, 24, -9, 27, -38, 22, -20, 23, -21, 11,
- -6, 42, -71, 20, 32, -11, -43, 44, -3, -4, -27, 12, 24, -8, -18, -8,
- 30, -19, -23, 44, -8, -30, 0, 45, -39, 0, -1, 28, -16, -17, -15, 44,
- -13, -11, -13, 36, -24, -11, 12, 17, -30, 8, 17, -10, -18, 9, 22, -18,
- -15, 3, 25, -25, 11, -6, 5, 7, -18, -3, 15, -1, -17, 8, 28, -32,
- -17, 36, 8, -41, 12, 7, 13, -22, -14, 18, 41, -57, -1, 25, 10, -40,
- 18, 11, -8, -23, 25, -16, 37, -45, 17, 10, 2, -60, 64, -15, -3, -16,
- 22, -9, 9, -27, 30, -7, -21, 3, 20, -10, 6, -12, 15, -19, 14, -19,
- 3, 22, -8, -29, 37, -28, 29, -26, 11, -15, 15, -17, 21, -26, 18, 5,
- -5, -11, 2, 16, -10, -10, -5, 29, -30, 4, 3, 18, -21, 4, 1, 8,
- -13, -10, 1, 40, -35, -26, 44, 5, -38, 8, 30, -24, 0, -1, 0, 12,
- -18, -1, 18, -8, -28, 39, -18, 24, -35, 24, -36, 46, -41, 12, -3, 24,
- -37, 31, -28, 32, -16, 2, -27, 39, -34, 7, 24, -19, -6, 14, -10, -1,
- 14, -16, -4, 25, -26, -4, 8, 22, -40, 33, -30, 22, -15, 36, -63, 39,
- 1, 10, -54, 36, 9, 5, -51, 49, -13, 5, -7, -7, 15, -9, -10, 2,
- 12, -18, 6, 3, 18, -29, 9, 10, -10, 1, -20, 20, -3, -1, -13, 21,
- -26, 41, -36, 2, 23, -23, -10, 39, -41, 17, -10, 8, 7, -13, 23, -54,
- 66, -26, -50, 54, 17, -66, 59, -46, 30, -10, 6, -8, -18, 19, 16, -32,
- 12, 6, -2, 3, -36, 33, -6, -7, 12, -16, 6, 14, -21, 14, 16, -58,
- 37, 3, 0, -35, 44, -16, 17, -38, 28, -14, 25, -45, 28, -21, 32, -31,
- 11, 17, -24, 11, 5, -24, 18, -6, -3, 0, -3, 21, -33, 24, 20, -78,
- 66, -8, -24, 3, 17, -14, 24, -41, 34, -25, 27, -32, 17, -5, 13, -26,
- 28, -29, 22, -8, -16, 33, -30, 2, 25, -27, 1, 31, -36, -7, 31, -8,
- -12, -5, 17, -7, 5, -26, 32, 1, -18, -16, 27, -7, -10, 2, 21, -42,
- 30, -3, -19, 33, -40, 19, 6, -13, -5, 17, -10, 28, -63, 40, 6, -10,
- -9, 7, -3, 12, -20, -1, 17, -1, -6, -14, 18, 1, -19, 12, 5, -9,
- -2, -14, 33, -3, -44, 51, -17, -6, -16, 36, -35, 29, -31, 31, -24, 15,
- -23, 33, -35, 20, -4, -1, -19, 27, -1, -29, 25, 1, -20, 25, -23, -13,
- 62, -50, -18, 43, -20, 1, -4, 16, -18, 4, -16, 36, -42, 42, -42, 38,
- -28, 9, -10, 31, -40, 30, -39, 30, 8, -28, 11, 9, -7, -6, -8, 10,
- 22, -36, -5, 26, 4, -41, 30, 12, -11, -10, -14, 37, -29, 3, -6, 9,
- -5, 15, -30, 40, -26, 12, -25, 25, -21, -12, 46, -17, -39, 47, 7, -57,
- 45, -14, 1, -13, 21, -21, 14, -7, 7, -11, 18, -34, 25, 7, -28, 22,
- 1, -12, 11, -24, 4, 38, -44, 17, 2, -12, 19, -17, 0, 9, 17, -55,
- 29, 3, 3, -27, 48, -38, 16, -17, 24, -19, 26, -49, 29, 9, -18, -25,
- 50, 2, -31, -20, 43, -3, -35, 23, 13, -34, 9, 20, -15, -8, 29, -37,
- 29, -21, 4, -8, 36, -52, 29, -8, 6, -18, 35, -34, 22, -21, 10, 5,
- -11, -13, 35, -26, -3, 12, -17, 13, 1, -12, -4, 24, -18, -6, 18, -7,
- -13, 17, -4, -30, 48, -41, 10, 34, -39, -22, 73, -48, -12, 12, 22, -14,
- -31, 18, 29, -17, -21, 22, -3, -8, -12, 25, -11, 13, -41, 36, -3, -2,
- -27, 37, -6, -36, 17, 18, -7, -10, 4, -5, 10, -21, 13, 15, -21, 2,
- -1, -5, 8, -1, -16, 29, -24, 14, -18, 26, -24, 17, -26, 21, -18, 24,
- -49, 82, -52, -11, 36, -22, -17, 30, -21, 1, 1, -1, 8, -2, -7, 2,
- 17, -9, -36, 37, -5, -15, -4, 27, -20, 11, -31, 46, -18, -13, -11, 58,
- -67, 19, -4, 40, -43, 9, -14, 41, -32, -16, 46, -19, -13, 5, -5, 6,
- 2, -16, 10, -9, 18, -13, 3, 24, -37, 11, 1, 0, -8, -9, 28, -1,
- -41, 40, -10, 6, -13, 1, -11, 30, -28, -10, 30, 1, -36, 17, 28, -54,
- 51, -24, 1, -6, 6, -12, 33, -48, 23, 18, -17, -23, 27, 11, -23, -13,
- 27, -7, -1, -24, 35, 3, -48, 35, 8, -20, -3, 3, 16, -11, 8, -35,
- 32, 7, -27, -22, 81, -85, 36, -7, 16, -16, 2, 0, 13, -28, 12, -16,
- 24, 6, -25, -14, 47, -15, -25, 3, 37, -41, -5, 32, -25, 11, 6, -16,
- 25, -34, 14, 8, 13, -52, 30, 6, 13, -56, 56, -27, 13, -11, -6, 16,
- -12, -1, 18, -40, 18, 19, -13, -11, 7, -2, 9, 10, -39, 9, 46, -48,
- -18, 59, -32, -3, 14, -10, 10, -13, 10, -13, 14, -11, -10, 5, 31, -43,
- 10, 23, -16, 3, -29, 50, -23, -19, 16, 15, -19, 3, -20, 39, -19, -14,
- -6, 54, -44, -12, 18, 30, -56, 28, -15, 22, -16, -15, 31, -8, -9, -1,
- 1, 1, 2, -8, 9, 10, -43, 41, -9, 8, -48, 62, -30, -9, 13, 6,
- -24, 32, -31, 8, -4, 16, -27, 27, -19, -1, -6, 37, -40, 14, -3, 0,
- 25, -59, 34, 18, -18, -21, 17, 13, -11, -8, -11, 43, -40, 1, 6, 24,
- -37, 10, 14, -4, -12, -2, 17, 11, -40, 10, 16, 17, -51, 24, 14, -4,
- -31, 22, 18, -32, 15, -24, 46, -38, 9, 2, -2, 14, -15, -12, 15, 3,
- -28, 29, -7, -6, 13, -7, -6, 2, 3, -17, 28, -28, -9, 37, -17, 0,
- 3, 10, -19, -5, 19, -17, 12, -25, 30, -19, 8, -27, 49, -15, -27, 9,
- 10, 7, -31, 6, 30, -12, -45, 41, 24, -42, -1, 28, -2, -38, 29, -18,
- 23, -4, -43, 35, 26, -54, 23, 7, 6, -30, 17, -14, 32, -40, 24, -13,
- 17, -15, -11, 16, 16, -20, -26, 47, -10, -26, -6, 41, -19, -22, 36, -41,
- 33, 5, -32, 12, 28, -51, 19, 27, -40, 7, 35, -34, 9, -22, 42, -20,
- -15, -3, 43, -55, 15, 23, -10, -11, 3, 14, -32, 31, -26, 21, 7, -44,
- 15, 40, -22, -41, 54, -17, -17, 8, -6, 10, 11, -17, -6, 15, -2, -20,
- 31, -19, 4, -17, 22, 0, 2, -36, 39, 0, -31, 23, -38, 59, -15, -29,
- -13, 69, -50, -22, 43, -11, -16, 0, 16, -9, -10, 13, 5, -8, -18, 27,
- -8, -2, -12, 13, -1, -16, 16, -18, 27, -11, -19, 39, -28, -26, 28, 36,
- -85, 72, -40, 24, -10, 0, -9, 30, -29, -11, 22, -13, -7, 23, -10, -14,
- 6, 13, -15, 22, -31, 12, 0, 0, -3, -15, 19, 14, -21, -22, 27, 35,
- -72, 36, -3, 18, -54, 50, -29, 38, -47, 14, 19, -11, -25, 27, 9, -23,
- -2, 2, 16, -6, -24, 22, 10, -27, 7, 16, -30, 11, 24, -40, 31, -28,
- 29, 1, -28, 7, 17, 3, -45, 40, -11, -7, 4, 19, -45, 24, 24, -50,
- 48, -35, 11, 9, -12, -14, 30, -23, 8, 7, -15, -7, 53, -59, 13, 5,
- 15, -46, 49, -48, 57, -36, -20, 34, 1, -10, -15, 15, 20, -36, -9, 35,
- 6, -39, 7, 14, 27, -81, 70, -21, 5, -22, 21, -6, 1, -13, 19, -19,
- 4, -10, 35, -43, 31, -3, -7, -15, 40, -56, 33, -1, -33, 51, -35, -2,
- 24, -18, 5, 0, 4, -16, 10, -6, 9, -28, 37, -38, 45, -35, 0, 37,
- -38, 7, 19, -32, 3, 17, -2, -23, 19, 15, -23, 5, -2, 13, 1, -37,
- 8, 59, -80, 26, 13, 15, -31, -8, 30, -7, -7, -19, 22, -2, -9, -2,
- 12, -7, 3, 1, -25, 47, -53, 35, -5, -27, 21, 15, -25, 13, -24, 42,
- -41, 19, 2, -13, 1, 23, -40, 37, -45, 46, -8, -41, 44, -11, -17, 23,
- -9, -20, 22, -3, -15, 22, -23, 19, -7, 2, -34, 65, -56, 7, 28, -8,
- -37, 37, 3, -8, -34, 39, -11, 9, -29, 6, 35, -14, -49, 48, 5, -25,
- 5, -25, 66, -47, -9, 28, -7, -12, 0, 17, -20, -2, 21, -12, -23, 54,
- -50, 20, 7, -20, 7, -2, 3, 4, -26, 26, -6, -14, 15, -3, -10, 12,
- -10, -4, 23, -33, 14, -12, 38, -55, 36, 0, -6, -5, 0, -4, 7, 0,
- -14, 2, 8, -11, 13, 5, -33, 41, 4, -62, 40, 8, -6, -8, -31, 52,
- -4, -44, 25, 20, -18, -24, 32, -11, -9, -4, 30, -37, 34, -31, 7, 30,
- -29, -14, 28, -10, -9, 6, 0, -5, 14, -9, -3, -2, 10, -22, 29, -22,
- -2, 6, -5, 16, -25, 6, 27, -19, -9, -11, 29, -13, -5, -6, 16, 5,
- -20, -1, 30, -20, -8, 7, -8, -2, 3, 14, -9, -24, 35, -7, -14, -12,
- 32, -5, -18, -15, 35, -7, -13, -1, -4, 27, -20, -30, 58, -15, -29, 9,
- 15, -16, -3, 1, 4, 5, -4, -11, 17, 3, -29, 28, -10, -18, 20, -7,
- -2, 4, 2, -17, 22, -3, -31, 23, 23, -32, -14, 34, -3, -14, -13, 11,
- 21, -26, -16, 36, -7, -13, 15, -8, -3, -1, -11, 15, -8, -4, -4, 24,
- -21, 1, 11, 3, -22, 5, 15, -24, 0, 37, -31, 7, -18, 15, 16, -15,
- -19, 26, 0, -10, -26, 31, 6, -19, -6, 21, -19, 20, -13, -3, 13, -2,
- -32, 24, 2, -8, -10, 36, -29, -10, 19, 10, -25, 5, -9, 31, -23, -21,
- 21, 26, -25, -9, -5, 35, -17, -34, 17, 42, -44, -11, 30, 11, -40, 18,
- 8, -6, -11, 11, -26, 39, -18, -23, 37, -12, -32, 45, -8, -22, 5, 16,
- -15, -10, 6, 17, -15, -3, 9, -22, 41, -22, -25, 29, 5, -30, 6, 12,
- 17, -32, 7, 20, -26, 9, 9, -10, 7, -17, 10, 11, -16, -7, 12, 5,
- -4, -26, 25, 24, -46, -4, 50, -39, -11, 8, 35, -36, 2, -9, 33, -7,
- -22, -26, 76, -37, -41, 33, 28, -43, 14, 6, 2, -8, 2, -20, 34, -19,
- -2, -4, 15, -6, -23, 28, -3, -32, 33, -16, 7, -11, 14, 9, -10, -30,
- 35, -25, 17, -14, 1, 14, 12, -38, 16, 15, -7, -30, 15, 18, -24, -6,
- 47, -38, 6, 7, -9, -2, -3, 1, 12, -8, -23, 20, 35, -47, -14, 51,
- -9, -48, 19, 20, 0, -25, -2, 20, 16, -29, -25, 60, -17, -23, -8, 31,
- -4, -30, 12, 20, -14, -4, -1, 17, -11, -9, 7, 7, -17, 1, -12, 25,
- -5, -20, 15, 19, -29, 2, 5, 11, -19, -18, 31, 1, -27, 18, -17, 51,
- -53, -2, 29, 4, -37, 17, 11, -11, -23, 41, -17, -10, 13, -4, -8, 18,
- -27, 17, 1, -19, -7, 51, -37, -28, 53, 4, -47, 5, 18, 17, -32, -8,
- 14, 36, -46, 3, 11, 11, -24, 4, 0, 16, -7, -26, 25, 20, -44, 7,
- 20, -12, 2, -14, 4, 33, -38, 1, 8, 20, -34, -12, 61, -46, -19, 44,
- -10, -4, -18, 12, 12, -8, -26, 16, 22, 2, -51, 18, 53, -56, -5, 30,
- -9, -22, 32, -11, -18, 18, 13, -25, -7, 8, 9, 3, -20, 1, 32, -27,
- -9, 5, 19, -20, -13, 18, 8, 3, -35, 22, 31, -47, -2, 16, -8, 15,
- -10, -22, 54, -20, -23, -6, 51, -52, -13, 48, -23, -11, 28, -30, 38, -6,
- -50, 28, 33, -58, 2, 34, 16, -53, -1, 55, -13, -42, 15, 23, -7, -33,
- 13, 21, -14, -6, 2, -2, 27, -43, 27, 11, -19, -16, 26, -16, -4, 16,
- -17, 1, 20, -17, 8, -17, 6, 26, -25, -24, 40, -13, 6, -14, -14, 29,
- 3, -32, -5, 46, -21, -28, 38, -30, 6, 28, -47, 3, 65, -67, -5, 61,
- -34, -27, 31, 12, -30, -7, 11, 19, 0, -43, 18, 47, -52, -20, 52, -14,
- -9, -10, -5, 55, -45, -29, 55, 16, -83, 28, 36, -23, 6, -8, -13, 37,
- -17, -30, 32, -9, -6, 10, -19, 16, 4, 9, -35, 22, -1, -17, 3, 8,
- 10, -10, -21, 40, -27, -5, 16, -6, -27, 47, -23, -26, 48, -18, -19, 14,
- -1, -9, 5, 1, -20, 58, -57, -14, 55, -16, -40, 37, -6, 11, -19, -22,
- 43, 2, -55, 27, 37, -38, -29, 58, -6, -11, -22, 4, 26, -7, -67, 67,
- 21, -56, 19, 15, -5, 0, 2, -41, 37, 10, -65, 49, 8, 1, -19, 1,
- 9, 8, -20, -9, 22, -14, -3, 4, -1, 13, -6, -11, 15, -8, -15, 13,
- 16, -38, 14, 24, -39, 20, 9, -17, 14, -15, 7, 3, -12, -3, 30, -25,
- -24, 43, -1, -40, 18, 17, 0, -22, -14, 31, 20, -68, 35, 32, -43, -9,
- 35, -16, 4, 2, -35, 35, 27, -81, 40, 31, -21, -30, 29, -12, 13, 10,
- -42, 26, 17, -33, -1, 16, 12, -29, 6, 4, 21, -27, -9, 39, -6, -54,
- 40, -14, 15, -4, -17, 20, 4, -18, -4, 23, -24, -3, 30, -41, 15, 17,
- -4, -29, 19, 4, -9, -10, 12, 17, -21, -7, 26, -19, -17, 17, 3, 1,
- -3, -30, 47, 16, -62, -4, 68, -29, -54, 43, -1, -4, 20, -42, 22, 34,
- -32, -43, 63, -12, -26, 8, -6, 10, 22, -66, 55, 25, -65, 15, 9, 21,
- -22, -28, 36, 5, -16, -51, 102, -49, -12, 6, 21, -12, -23, 24, -15, 11,
- -14, -8, 31, 4, -53, 64, -35, 13, -28, 23, -23, 22, -16, 13, -22, 23,
- 27, -51, -8, 41, 6, -66, 36, 13, 4, -26, 7, 11, 9, -34, 0, 35,
- -21, -15, 10, 34, -57, 60, -69, 60, -22, 1, -27, 27, 14, -27, 1, -13,
- 35, -2, -51, 36, 35, -49, 5, -1, 31, -42, 25, -26, 34, -7, -60, 98,
- -46, -22, -1, 49, -45, -2, 10, 26, -33, 25, -36, 37, -19, 4, -3, -7,
- 9, 7, -8, -29, 48, -23, 0, -33, 45, 0, -23, -16, 47, -7, -31, -9,
- 38, -2, -36, 18, -8, 43, -55, 16, -1, 41, -72, 54, -35, 24, 4, -46,
- 47, -11, 6, -40, 24, 10, 8, -38, 16, 16, 24, -98, 80, 2, -28, -28,
- 44, 11, -47, 31, -7, 35, -42, -25, 41, 12, -64, 34, 14, -2, -21, 24,
- -14, 11, -3, -24, 22, -28, 46, -51, 38, -22, 35, -40, 2, 11, 22, -48,
- 23, -9, 34, -35, -24, 52, -7, -37, 9, 36, -21, 0, -32, 61, -44, 6,
- -1, -16, 41, -28, 19, -37, 49, -11, -38, -8, 65, -53, 9, -21, 59, -37,
- 8, -33, 59, -13, -80, 67, 19, -39, -28, 70, -21, -25, -3, 23, 17, -29,
- -44, 83, -41, 0, -23, 53, -27, -12, 21, -19, 21, -21, 13, -4, -12, -5,
- 38, -58, 34, 10, -22, -16, 47, -8, -39, 19, 12, 4, -46, 39, -24, 48,
- -69, 45, -18, 10, -5, -2, -4, 10, -5, 7, -17, -3, 20, 0, -40, 26,
- 40, -64, 11, 34, 1, -49, 11, 35, -22, -14, -32, 98, -47, -37, 9, 76,
- -70, -8, 7, 63, -92, 56, -49, 77, -64, 2, 41, -28, -25, 37, 0, -26,
- 35, -40, 16, 3, 14, -46, 22, 18, -6, -9, -11, 22, 26, -44, -46, 94,
- -60, 18, -37, 69, -33, 5, -20, 42, -32, -20, 24, -1, -10, -12, 39, -31,
- 13, 1, 9, -47, 42, -26, 39, -73, 48, 48, -73, -13, 56, 14, -78, 38,
- 11, 12, -50, 8, 39, 3, -79, 73, 2, -25, -17, 23, 27, -58, 26, -37,
- 67, -49, 11, -12, 62, -82, 64, -41, 3, 26, -17, -45, 55, -4, -22, 10,
- -2, 38, -54, 8, 5, 47, -79, 7, 54, -7, -64, 41, 49, -73, 29, -24,
- 54, -51, -4, 14, 33, -84, 82, -46, 17, -25, 57, -44, -2, 11, 8, 15,
- -66, 46, 19, -25, -44, 58, 10, -38, -23, 77, -48, -3, -12, 24, 24, -70,
- 37, 21, -15, -48, 81, -66, 44, -29, 6, 4, 9, -30, 31, -24, 5, 19,
- -51, 34, 21, 11, -92, 78, 19, -44, -54, 104, -47, -8, -19, 29, 45, -78,
- 6, 55, -11, -75, 66, -10, 8, -38, 24, 10, 4, -57, 66, -20, -25, 20,
- 6, 9, -71, 100, -60, -6, 8, 28, -37, 29, -42, 78, -58, -22, 42, 10,
- -69, 34, 33, -36, 29, -54, 81, -54, 0, 7, 1, -19, 22, -14, 4, -3,
- 32, -13, -59, 86, -54, 4, 0, 21, -35, 43, -68, 91, -31, -53, 38, 48,
- -72, -15, 50, 3, -11, -72, 96, -1, -49, -23, 81, -21, -57, 15, 63, -67,
- 5, 25, -27, 34, -48, 49, -26, 12, -33, 66, -73, 14, 35, -20, -27, 45,
- -24, 12, -12, 0, 24, -50, 33, -26, 45, -65, 47, -7, -4, -9, 19, -19,
- -2, 15, -17, 30, -39, 25, 2, -3, -57, 109, -86, 10, 14, 31, -53, 7,
- 32, 5, -44, -20, 84, -35, -34, -6, 99, -97, 1, 23, 40, -65, 15, 9,
- 36, -45, -22, 55, 4, -55, -3, 73, -80, 63, -49, 28, 2, -10, -19, 24,
- -13, 8, 1, -15, 5, 22, -4, -57, 72, -41, 16, -45, 76, -57, 30, -26,
- 38, -16, -34, 32, 12, -53, 22, 47, -46, -4, 6, 45, -65, 32, -21, 45,
- -44, -22, 69, -44, -16, 29, 19, -59, 40, -7, 42, -77, 39, -4, 29, -74,
- 27, 38, -12, -60, 69, 7, -32, 1, -9, 50, -56, -15, 19, 47, -75, 44,
- 5, -22, 27, -7, -22, 0, 23, -30, 1, 4, 33, -44, 29, -24, 57, -67,
- 17, 18, 4, -59, 32, 48, -72, 28, -2, 13, -10, -21, 16, 58, -117, 85,
- -14, -5, -34, 21, 29, -27, -20, 31, 23, -49, 16, -14, 51, -74, 24, 38,
- -38, -16, 56, -33, -7, 3, 0, 36, -80, 49, 23, -19, -48, 76, -61, 43,
- -41, 27, -11, 23, -30, 8, 3, 15, -14, -22, 16, 3, 15, -39, 11, 38,
- -13, -70, 88, -41, 2, 4, -30, 80, -84, 15, 37, -6, -61, 58, -19, 27,
- -72, 64, -6, -16, -30, 59, -21, -21, -12, 44, 22, -101, 78, -10, -16, -11,
- 20, -21, 31, -36, 37, -18, -20, 46, -24, -23, 10, 21, -36, 32, -38, 68,
- -50, 12, -6, 19, -33, 14, -16, 20, -11, -14, 47, -59, 56, -14, -27, 5,
- 29, -43, 49, -96, 106, -35, -41, 28, 35, -30, -29, 37, 12, -11, -58, 79,
- -31, -16, -11, 43, -13, -25, 3, 71, -76, -13, 64, -39, 3, -45, 66, -13,
- -1, -45, 80, -40, 6, -29, 26, -12, 6, -19, 21, -4, 9, 0, -37, 44,
- -28, 11, -22, 19, 7, 1, -45, 60, -13, -42, 32, -16, 31, -50, 35, 10,
- -22, -23, 60, -62, 21, -2, 39, -49, -4, 24, 30, -53, -23, 66, -33, 2,
- -34, 69, -33, -10, 7, 24, -51, 28, 0, 9, -24, -3, 38, -24, -16, -9,
- 68, -81, 38, -16, 35, -34, -4, 16, 20, -43, 10, 7, -3, 14, -30, 38,
- -39, 38, -20, -12, -20, 78, -79, 22, -4, 44, -48, -6, 37, -2, -25, -24,
- 60, -41, 15, -30, 50, -43, 7, 9, 27, -64, 45, 5, -15, -17, 1, 49,
- -56, 3, -11, 69, -78, 37, -5, 38, -60, 26, -2, 9, -51, 53, -20, -3,
- 9, -1, 38, -74, 40, 6, -13, -54, 69, -24, 6, -22, 31, 0, -17, 12,
- -13, 8, -9, 20, -53, 56, -27, 29, -63, 41, 8, 11, -73, 59, 15, -25,
- -21, -1, 61, -69, 10, 17, 28, -59, 34, -14, 32, -54, 17, 22, -11, -47,
- 63, 7, -56, 46, -28, 50, -96, 60, 2, 0, -37, 36, -11, 15, -38, 41,
- -19, -31, 46, -12, -25, 9, 49, -67, 47, -48, 51, -30, -15, 23, 19, -43,
- 8, 17, 4, -11, -29, 54, -48, 38, -28, 10, -9, 38, -48, 27, -47, 55,
- 3, -59, 22, 41, -5, -59, 38, 5, 31, -101, 72, 11, -36, -18, 54, -25,
- -1, -30, 54, -28, -34, 61, -27, 13, -46, 55, -21, -10, -21, 52, -34, -8,
- 30, -21, 20, -11, -21, 22, -2, -46, 79, -84, 60, -9, 13, -57, 51, 2,
- -16, -38, 34, 15, -23, -7, -6, 53, -38, -22, 29, 23, -63, 65, -34, -21,
- 34, -7, -19, -8, 24, 13, -8, -63, 110, -56, -8, -37, 79, -56, -3, -3,
- 62, -57, 19, 9, 8, -20, -29, 27, 13, -28, -19, 79, -80, 58, -31, 24,
- -16, -35, 46, 0, -52, 36, 21, -29, 16, -23, 26, -29, 38, -42, 26, -41,
- 60, -29, -16, -4, 42, 7, -85, 53, 47, -54, -29, 67, -53, 39, -58, 45,
- -5, 5, -37, 61, -56, 27, 17, -40, 1, 15, 17, -43, 19, 4, 30, -49,
- 12, -1, 49, -64, -27, 96, -41, -47, 45, 8, -38, 35, -50, 74, -81, 54,
- -14, 24, -64, 57, -5, -25, -19, 27, 16, -27, 4, 16, 2, -25, 26, -31,
- 22, -35, 56, -54, 0, 55, -23, -29, 9, 38, -38, 12, -41, 74, -28, -29,
- -3, 61, -71, 36, -32, 43, -19, -14, 21, 0, -10, -19, 32, -42, 20, 11,
- 23, -94, 107, -13, -53, 5, 35, -17, -11, -25, 32, 40, -76, 29, 32, -9,
- -65, 80, -42, 6, -22, 42, -27, -2, 10, -2, 13, -41, 32, 10, -17, -26,
- 53, -50, 40, -42, 30, -19, 41, -50, 33, -20, -1, 40, -67, 8, 29, 15,
- -58, 25, 32, 15, -81, 46, 14, -8, -51, 24, 40, -44, 17, 10, 2, -26,
- 47, -68, 49, -49, 50, -27, -3, -20, 84, -62, -32, 52, 12, -52, 0, 42,
- -30, 24, -47, 45, -16, 11, -51, 74, -47, -9, 45, -19, -18, -5, 41, -39,
- 11, -33, 56, -20, -14, -8, 64, -85, 60, -23, -13, -3, 33, -20, -25, 57,
- -34, 2, -23, 42, -21, 3, -49, 85, -35, -27, 1, 54, -34, -31, 24, 15,
- 6, -45, 54, -30, 12, -27, 40, -61, 39, 1, -5, -18, 17, 14, 7, -33,
- -27, 83, -44, -40, 21, 66, -82, 32, -7, 33, -54, 27, 3, 2, -13, -15,
- 52, -57, 14, 14, -6, -27, 54, -45, 23, -11, 16, -27, 27, -33, -3, 36,
- -46, 47, -15, -8, -7, 67, -93, 12, 34, 17, -73, 32, 15, 29, -44, -17,
- 47, 2, -40, -31, 81, -43, 3, -24, 52, -32, 4, 1, 20, -48, 20, 40,
- -68, 23, 14, 19, -64, 46, -8, 17, -48, 55, -29, 23, -59, 48, -2, -27,
- 11, 1, 21, -30, 25, -24, 29, -41, 21, 0, -15, -17, 64, -47, 1, 31,
- -22, 2, -11, 22, -56, 69, -53, 32, -30, 31, -16, 32, -68, 29, 42, -39,
- -49, 80, 17, -74, 17, 0, 55, -88, 25, 29, 14, -72, 56, 0, 0, -33,
- 20, 5, -34, 35, -33, 45, -37, 23, -9, 10, -54, 67, -22, -13, -15, 41,
- -14, -16, 8, 0, 19, -51, 56, -51, 39, -20, 19, -34, 26, -18, 19, -31,
- 23, 0, 12, -31, 7, 45, -65, 22, 4, 24, -73, 74, -13, -34, 18, 23,
- -16, -25, -2, 40, 5, -84, 76, -4, 6, -74, 75, -7, -10, -51, 60, -13,
- 0, -45, 50, 18, -57, 20, 21, -7, -26, 47, -51, 28, -19, 12, -13, 3,
- -1, 20, -23, 1, 28, -18, 3, -41, 67, -72, 34, -11, 33, -47, 47, -9,
- -20, -2, 28, -21, -27, 11, 26, -15, -25, 57, -44, 46, -67, 49, -5, -30,
- 1, 42, -36, -9, 22, 7, -13, -34, 67, -29, -16, -26, 84, -49, -21, -11,
- 77, -53, -43, 62, 0, -3, -32, 23, 13, -5, -69, 88, -42, 7, -17, 37,
- -35, 27, -6, -13, -11, 31, -17, -28, 45, -17, 8, -32, 41, -48, 39, -35,
- 41, -16, -28, 41, -3, -13, -26, 23, 12, -22, -50, 104, -57, 9, -28, 67,
- -53, -7, 0, 45, -41, -22, 50, -8, -21, -9, 38, -19, -18, -2, 55, -76,
- 38, -12, 39, -49, -14, 64, -24, -45, 25, 50, -66, 23, -15, 32, -36, 32,
- -46, 44, -14, 2, -16, 22, -7, -11, 14, -28, 21, 4, -10, -18, 63, -66,
- 30, -20, 36, -35, -16, 26, 12, -37, 6, 50, -35, -15, 6, 48, -64, 4,
- 12, 46, -85, 33, 12, 25, -49, -11, 77, -53, -18, 19, 29, -41, -1, 3,
- 39, -70, 55, -6, -1, -23, 38, -22, -12, 1, -11, 36, -39, 5, 15, 33,
- -55, 32, -8, 6, -37, 39, -32, 4, 27, -23, 11, -1, 10, -28, 19, -24,
- 52, -69, 27, 21, 11, -72, 52, 17, -35, -13, 16, 33, -44, 4, 19, 18,
- -60, 13, 35, 12, -93, 82, 9, -35, -20, 26, 40, -74, 14, 18, 28, -66,
- 37, 4, 9, -43, 34, -15, 17, -35, 38, -11, -14, 14, -5, 2, -36, 54,
- -35, 2, 1, 29, -35, 9, -4, 24, -32, -5, 31, -19, -17, 28, 34, -86,
- 49, 13, -16, -52, 71, -29, 3, -30, 51, -1, -36, 6, 25, 4, -75, 56,
- 10, -21, -18, 37, -16, 17, -53, 60, -7, -38, -9, 63, -18, -70, 67, 1,
- -19, -32, 50, -20, 11, -23, 24, -10, -3, -21, 32, -26, 7, 12, -19, 35,
- -29, 26, -41, 32, -22, 14, -43, 41, 7, -16, -24, 57, -20, -35, 25, 7,
- -11, -20, 31, -18, 10, -34, 44, -7, -22, -9, 49, -33, -18, 26, -4, 12,
- -63, 51, 11, -16, -40, 80, -28, -37, 5, 61, -78, 22, 16, -3, -10, -5,
- 26, -8, -2, -43, 68, -42, -24, 39, 11, -31, 15, -9, 18, -20, -1, 7,
- -17, 26, -30, 31, -31, 42, -28, -1, -15, 49, -51, -2, 26, 3, -12, -11,
- 7, 22, -9, -51, 70, -27, -14, -13, 53, -37, -12, 9, 44, -57, -14, 51,
- -6, -27, -10, 60, -55, 2, 14, 18, -45, 32, -19, 29, -27, -12, 31, 14,
- -54, 17, 41, -62, 51, -40, 40, -40, 12, -8, 28, -39, 16, 10, 10, -46,
- 37, 12, -42, 17, -4, 2, -17, 35, -34, 38, -30, 21, -6, -36, 36, 13,
- -56, 14, 53, -36, -13, -1, 61, -64, 7, -3, 54, -63, 5, 14, 34, -67,
- 10, 46, -27, -18, 26, 20, -41, 14, -13, 40, -66, 20, 38, -34, -11, 39,
- -16, 11, -26, 7, 28, -58, 26, 0, 30, -61, 44, 11, -30, -17, 66, -40,
- -33, 35, 6, -21, -2, 9, 16, -13, -39, 79, -71, 27, 9, -9, -29, 28,
- 4, -17, 1, 14, 2, -20, -2, 16, 24, -67, 20, 37, -4, -80, 75, 18,
- -46, 2, 10, 25, -31, -28, 43, 19, -75, 59, -13, 14, -40, 29, 7, -22,
- -20, 44, -20, -16, 10, 32, -21, -42, 61, -19, -29, 12, 39, -55, 32, -4,
- 0, -2, -24, 40, -19, -38, 34, 22, -33, 11, -3, 31, -49, 21, -16, 40,
- -54, 12, 29, -19, -8, 17, 17, -52, 28, 22, -39, -2, 45, -42, 23, -46,
- 51, 11, -68, 26, 55, -34, -44, 45, 9, -19, -43, 57, -16, -5, -9, 40,
- -24, -12, 8, 29, -54, -4, 50, -37, 0, 11, 7, -4, 0, -25, 57, -62,
- 19, 18, -7, -22, 12, 19, -27, 9, -5, 15, -19, 2, 15, 4, -45, 36,
- -5, 8, -48, 60, -13, -35, 36, -19, 21, -24, -7, 23, -24, -22, 73, -58,
- -5, 34, 25, -71, 19, 30, 0, -43, -4, 50, -9, -21, -21, 69, -28, -46,
- 24, 29, -45, 12, 3, 21, -13, -28, 47, -9, -37, 21, 22, -46, 21, 8,
- -1, -32, 42, -22, 14, -27, 19, 16, -29, 3, 17, -1, -39, 28, 21, -42,
- 8, 47, -45, 2, -16, 50, -20, -54, 50, 9, -25, -12, 41, -29, 8, -3,
- -5, -13, 25, -16, 19, -30, 15, 15, -2, -52, 38, 38, -69, 12, 37, 9,
- -54, 10, 36, 5, -79, 27, 57, -35, -40, 48, 21, -41, 13, -3, 10, -29,
- 4, 18, 4, -50, 52, 1, -28, -6, 41, -25, -22, 34, -22, 10, -5, 3,
- -6, -1, 2, 26, -48, 24, 12, 5, -54, 36, 18, -32, -6, -3, 48, -28,
- -21, 22, 35, -63, 6, 43, -28, -27, 42, -7, -22, 6, 21, 8, -56, 31,
- 23, -10, -73, 76, 18, -49, -26, 70, -21, -23, -8, 35, 0, -42, 7, 42,
- -26, -28, 47, -31, 0, 13, 11, -25, 14, -6, 10, -13, -26, 40, -14, -5,
- -8, 42, -36, 1, 15, -10, -34, 47, -24, 5, -22, 38, 14, -39, -10, 53,
- -26, -67, 72, 0, -15, -25, 29, 19, -29, -25, 50, -14, -31, 10, 42, -44,
- -24, 81, -40, -32, 12, 45, -41, -5, -1, 47, -27, -54, 54, 32, -64, 4,
- 26, 1, -1, -41, 44, 4, -22, -22, 47, -30, 7, 5, 3, -37, 45, 1,
- -53, 44, -1, -20, 7, 12, -13, 9, -23, 26, -2, -47, 32, 37, -61, 6,
- 42, 0, -25, -43, 76, -23, -38, -10, 73, -24, -57, 47, 45, -70, 3, 19,
- 7, -19, -8, 10, 24, -12, -36, 66, -60, -1, 50, -32, -19, 8, 26, 2,
- -44, 11, 53, -42, -26, 20, 42, -52, 14, 16, -26, -11, 42, -41, 16, 16,
- -23, 13, 1, -6, 17, -18, -41, 71, -39, -23, 40, 13, -30, 2, 19, 0,
- -39, 10, 24, -15, -25, 12, 66, -81, 6, 47, 9, -69, 12, 47, -9, -36,
- -27, 76, 9, -107, 58, 53, -68, 19, -10, 39, -49, 8, 14, -11, -17, 21,
- 18, -25, -17, 47, -4, -48, 32, -9, -4, -3, 8, -5, 29, -40, 13, 14,
- -31, 24, 7, -48, 27, 37, -61, 22, 15, 7, -46, 17, 10, 22, -45, -9,
- 56, 1, -73, 43, 34, -51, -15, 40, 2, -47, 35, 8, 27, -87, 31, 86,
- -94, -27, 67, 10, -44, -15, 43, 11, -46, 6, 9, 33, -71, 35, 26, -30,
- -18, 37, -18, -9, 20, -15, 1, 5, 9, -2, -23, -11, 50, -42, -3, 24,
- 6, -21, 17, -5, -8, 11, -26, 24, -19, -9, 33, 22, -78, 38, 44, -48,
- -53, 80, 6, -66, 14, 36, 8, -37, -15, 66, -24, -75, 87, -14, -27, -10,
- 45, -12, -38, 13, 33, 7, -67, 20, 75, -55, -67, 85, 8, -52, -11, 45,
- -10, 13, -34, 12, 26, -36, 7, -1, -1, -7, 23, -27, 18, 15, -12, -28,
- 27, -6, 9, -52, 40, 26, -50, 3, 51, -10, -71, 67, 10, -59, 4, 56,
- -27, -20, -19, 58, 6, -81, 38, 49, -39, -39, 47, 14, -25, -40, 54, -2,
- -20, -38, 82, -25, -51, 44, 24, -60, 8, 51, -47, -2, 6, 22, 9, -34,
- -20, 78, -56, -25, 36, 19, -49, 17, 32, -50, 44, -29, 4, -11, 14, 3,
- -13, -11, 19, 13, -24, 28, -32, 33, -37, 39, -61, 119, -76, 120, -70, 99,
- -122, 89, -113, 91, -123, 122, -123, 77, 86, -116, 6, -118, 123, -23, 64, -93,
- 17, 24, -125, 124, -125, 124, -24, -12, 56, 87, -54, 38, -91, 64, -2, -41,
- 126, -127, 20, 8, -48, -62, 127, -128, 88, -43, -18, 86, -100, 44, -32, -26,
- 71, -13, 6, 51, -33, -50, 106, -59, 33, 5, -20, 69, -56, 54, -48, -6,
- 38, -5, -38, 35, -1, 12, -1, 4, 23, -56, 19, -7, 5, -4, 31, -38,
- 3, -12, -9, -25, -7, 24, -32, 17, -21, -22, 24, -20, 6, -18, 0, -15,
- 5, -16, 15, 3, 2, -10, 3, 27, -31, 37, -12, 32, -5, 2, -21, 27,
- -14, 20, -8, 5, 15, -7, -11, 20, -37, 7, -23, 17, -22, 11, -14, 8,
- -44, 39, -52, 26, 3, 14, -10, 51, -45, 29, -19, 19, -3, 41, -21, 46,
- -23, 10, 16, -25, 3, 7, -30, 19, -9, -5, -1, 1, -19, 1, -24, -23,
- 51, -48, -10, 17, -34, -38, 60, -71, 26, -43, 65, -59, 70, -26, 61, -51,
- 63, -51, 42, -25, 58, -36, 31, 10, -14, -9, 8, -18, 8, 4, 8, 7,
- 31, -52, 39, -53, 53, -56, 24, 11, 1, -20, -8, -32, -18, -10, -25, 4,
- 1, 37, -37, 42, -42, 53, -57, 52, -18, 30, 11, 20, -52, 55, -61, 56,
- -50, 24, -26, 38, -42, 36, -1, -43, 58, -46, 6, 18, -35, 31, -36, 28,
- -55, 55, -98, 52, -41, 26, -24, 48, -31, 48, -26, 30, 19, -17, 23, -8,
- 13, 15, 19, -7, -23, 41, -36, 20, -39, 65, -64, 66, -38, -9, 7, -14,
- -10, -3, 6, 15, -19, -40, 53, -67, -11, -12, -25, 23, -11, -12, 46, -48,
- 39, -20, 20, -14, 31, -54, 71, -25, 2, -8, -5, -9, 1, 7, 27, 17,
- -14, 43, -31, 27, 11, -33, 20, -2, -33, 45, -38, 17, -9, -11, -17, -22,
- -19, 20, -25, 4, 29, -35, 14, -17, 1, -7, 19, 2, 16, 32, -3, -17,
- 4, 0, -9, 17, 5, -8, 52, -32, 40, -39, -5, -18, 14, -21, 31, 10,
- -17, 8, -34, -7, 1, -44, 7, 10, -8, -6, -18, -25, -1, -19, 16, -29,
- 62, 6, 9, 21, 0, -14, 4, 5, 20, 13, 27, -1, 18, -5, 21, -31,
- 11, 2, -9, -4, 21, -27, 8, -21, -28, -19, 14, -12, 5, -20, 20, -36,
- 4, -18, -27, -4, -4, 15, 4, 48, -7, -11, 20, -6, 7, 20, 1, 20,
- 0, 35, -35, 28, -37, 7, -43, 21, -22, 23, -18, 12, -22, -13, -20, -11,
- 7, 23, -10, 19, -18, 17, -41, 4, -16, -8, 21, 11, -4, 10, 30, -24,
- 32, -15, 15, -13, 28, -5, 38, -10, 0, -22, -13, -12, 24, -18, 30, -7,
- 4, -16, 27, -28, -3, -1, 18, -14, 31, -24, -3, -13, -19, -36, -2, -31,
- 9, -2, -12, 17, 12, -50, 46, -49, 43, -15, 13, 22, 15, -25, 10, -8,
- -6, 14, -2, 24, 15, 9, 17, -13, 5, 14, -15, 7, 20, 4, 4, 18,
- -16, 3, -47, 31, -46, 19, -24, 5, -19, -1, -42, 14, -44, 18, -7, -1,
- 15, 9, -35, 32, -44, 39, -46, 23, -16, 36, -25, 45, -34, 32, -8, 10,
- 5, 28, 0, 12, 11, 3, 20, -23, 6, -8, 16, 7, 17, -19, 32, -44,
- 3, -8, -21, -8, -5, 2, -29, 2, -3, -19, -14, 3, 7, -23, 10, 1,
- 3, 8, 13, -44, 20, 21, -16, 23, 3, 5, 10, -11, 32, -11, 13, -7,
- 30, 4, 16, -7, -6, -7, 14, -40, 4, -16, -26, 3, -1, 0, -6, 5,
- -50, 37, -27, 18, -16, -14, 6, -1, -4, -15, 8, -12, 14, 9, -22, 42,
- -10, 23, -11, 36, -15, 13, 30, 1, 47, -20, 33, -14, -12, 1, -20, -9,
- -9, -11, -13, 7, -37, 25, -47, 14, -13, 4, -12, 9, -32, 18, -48, -1,
- -35, -1, -7, 35, -20, 53, -4, 34, -7, 13, 19, 9, 30, 6, 45, -22,
- 23, -18, -6, -1, 3, -30, 14, -15, 9, -39, 10, -33, -13, -24, 10, 14,
- 14, -10, 2, -34, -4, -20, -21, -14, 40, -10, 17, -14, 28, -17, 37, -26,
- 69, -15, 38, 2, 21, -25, 37, -61, 13, -9, 5, -17, 18, -41, 22, -57,
- -1, -9, -13, 24, -10, 38, -5, 8, -16, -2, 1, 12, -25, -2, -13, 2,
- 2, -16, -19, 32, -30, 22, 20, -4, 12, 11, -17, 19, -17, -3, 20, -33,
- 65, -27, 32, -14, 8, -8, 13, -19, 9, -2, 7, 33, -40, 18, -18, -18,
- 6, -23, -11, -11, -28, 4, -11, -15, -14, -8, -5, 34, -6, 19, 1, -3,
- 9, -1, 5, 5, 14, -11, 40, -3, 18, -20, 16, -7, 2, -5, 9, -16,
- 9, -17, 0, -17, 4, -17, -3, 3, 8, -14, -19, 12, -21, -7, 1, -2,
- -8, 16, 3, -6, 35, -23, 33, -13, 11, 12, 3, -7, 26, -11, 19, -18,
- 23, -22, 39, -49, 39, -50, 11, -38, 26, -29, 10, -6, -22, 15, -8, 15,
- -37, 36, -43, 39, -43, 18, -26, 1, 11, 4, -2, 9, 7, 2, 7, 19,
- 1, 1, -4, 16, -5, 16, -9, -3, 4, -4, -1, -17, 0, 11, 16, -27,
- 12, -15, 15, -3, 0, 10, -3, -5, 12, -13, -7, -13, -31, -1, -3, -17,
- 15, -31, 25, -10, 15, -1, 2, 4, 10, 7, 32, -13, 7, -22, 2, -10,
- 16, 1, -15, 19, -24, 16, -18, -12, 18, -9, 9, 24, -8, 8, 11, 0,
- -31, 17, -55, 21, -43, 40, -40, 29, -54, 44, -34, 22, 11, 16, 7, 19,
- 21, -6, 2, -7, -16, 22, 0, -1, -4, 5, -8, 26, -42, 4, -6, -21,
- 35, -16, 8, 0, -22, -13, 11, -31, 7, -28, 4, 17, -12, -18, -2, -23,
- 23, -1, 19, 34, 7, 7, 35, -19, 11, -8, -17, 8, 4, 16, -16, -13,
- 9, -15, -5, -1, -6, 7, 3, 11, 1, -7, -24, 21, -31, 36, -3, -10,
- 8, 2, -17, 12, -24, 6, -3, 9, 15, 3, 13, -8, -13, -3, 6, -19,
- 14, -33, 16, -17, -5, -31, 3, -29, 24, -7, -6, 35, -20, -5, 34, -20,
- 25, -3, 10, 25, 8, 14, -13, 0, 1, 17, -33, 51, -38, 45, -32, 39,
- -3, -2, -24, 3, -18, 14, -4, -44, 2, -25, -15, -2, -23, 3, -2, -2,
- 20, -14, 8, -10, -4, 21, 11, -13, 32, -4, 8, 19, -16, -2, -2, -2,
- 14, -2, -1, 27, -26, 20, 11, -13, 10, -3, -7, 12, -13, -3, -30, -16,
- 10, -26, -3, -10, -2, -9, 15, -17, 1, -2, -7, 14, -8, 12, -3, -1,
- 2, 47, -26, 22, -19, 16, 2, 13, -3, 21, -10, 22, -32, 43, -24, 16,
- 0, 5, -2, 12, -44, -12, 1, -26, 1, -36, 5, 2, 9, -17, 20, -37,
- 14, -9, -5, 6, -3, -13, 23, -19, 25, -33, 6, 17, 10, 19, 15, -4,
- 12, 5, -9, 33, -20, 26, -9, 11, -2, 11, -21, -7, -13, -4, -8, -12,
- 0, -10, -9, 8, -33, 9, -26, 8, 6, -8, 12, 7, -8, 0, 7, -16,
- 25, -8, 27, 12, 0, 9, -9, 4, -17, 14, -16, 11, -8, 18, -2, 4,
- 2, -20, -18, 22, -16, -5, 3, -24, 13, -10, -12, -10, 2, -16, 33, -15,
- 21, -15, -4, -19, 29, -22, 18, 2, 20, 12, 18, -22, -7, -16, 7, -19,
- 14, 1, -17, 33, -22, 38, -8, 3, -3, 21, -17, 51, -43, 15, -22, -23,
- -6, -12, -14, 14, 9, 6, 4, -31, 3, -16, -14, 22, -22, 5, 13, -25,
- 17, -2, -18, 7, 1, 5, 36, -16, 23, 4, -15, 29, -20, 10, 1, 24,
- 17, 16, -4, -16, -37, -11, 1, -33, 27, -36, 17, -22, 2, -33, 16, -29,
- 32, -7, 24, -12, 14, -12, 22, -16, 15, -20, 19, 9, 14, 12, -1, -24,
- 13, -6, -1, 32, -19, 24, 12, -26, 4, -31, -38, 18, -16, -13, 3, -14,
- -1, 11, -15, 15, 0, -2, 30, -6, 35, -23, 10, -35, 5, -14, 17, -21,
- 20, 4, 7, 8, -5, -15, 20, -25, 26, 6, -3, 3, 5, -24, 26, -35,
- 4, 0, -6, 13, -23, 8, -25, 1, -2, 9, 3, 17, 4, 0, 13, -15,
- 3, -21, -16, 4, -5, -10, 11, -2, 7, 23, -22, 25, -19, 18, 25, -9,
- 14, -21, -7, 11, -24, 22, -12, -7, 6, 9, -33, 11, -20, 2, -9, 2,
- 3, -13, 12, -15, 23, -21, 16, -16, -2, 8, 13, -12, 18, -10, 16, -12,
- 20, -18, 18, -1, 21, -21, 20, -30, -6, 10, -2, 13, -6, -15, 6, 2,
- -1, 1, -19, 9, -15, -3, -11, 0, -5, 1, 5, 1, -4, -8, 1, -16,
- 23, 0, -23, 2, 8, -6, 38, -4, 2, 13, -17, 31, -4, -8, 22, -14,
- 0, 12, -22, 7, -7, 11, 4, -4, -12, -9, -22, 2, -17, -17, -11, 7,
- -17, 19, -24, 9, -8, -6, 29, -4, 10, 4, 4, 23, -1, 9, -6, -12,
- 23, 16, -6, 33, -29, 12, -7, -10, 17, -4, -18, 21, 0, -14, -2, -20,
- -21, 10, -28, 5, -18, -4, 0, -11, 1, 5, -17, 3, 9, 20, 6, 1,
- -7, 2, -7, 3, 9, -22, 29, 6, -1, 25, -10, 6, -1, 4, 12, 18,
- -13, 28, -11, 6, -15, -14, -22, -7, 5, -14, 1, -16, -12, -5, 5, -9,
- 4, -1, -14, 21, -10, -5, 0, -17, -7, 2, -10, 6, 11, 1, 37, -17,
- 6, 21, -24, 41, 2, 23, 0, 10, -18, 16, -26, 14, -21, -19, 18, -9,
- -14, -1, -9, -14, -3, -7, -10, 7, -7, 19, -11, 15, -25, -3, -6, 2,
- 8, -10, 4, 12, -3, 11, -2, -2, 5, 31, -9, 39, -21, 14, -23, 18,
- -16, -1, -3, -6, 0, 22, -9, -5, -17, -4, -12, 2, -3, -7, 10, -10,
- 7, -20, -19, -10, 0, -14, 32, -15, -18, 13, -9, 2, 17, -14, 6, 36,
- -9, 28, 1, 0, 17, -10, 5, 17, -8, 12, -2, 3, 2, -22, -6, -14,
- 6, 8, -11, -14, 2, -23, 25, -35, 3, -18, 1, -14, 22, -1, -12, -7,
- -9, 13, -4, 12, 4, -3, 18, 0, 1, 8, -14, 14, -2, 1, 17, -3,
- -14, 35, -17, 19, -14, -6, 1, -9, 18, -17, -4, -13, -2, -14, 10, -10,
- -6, 0, 3, 5, -12, -13, -3, -6, -6, 11, -13, -7, 13, -2, 6, 13,
- -7, 11, -5, 23, 1, 29, -17, 23, -10, 18, -16, 12, -20, 10, 7, -9,
- -5, -21, -9, 5, -13, -2, 0, -15, -11, 3, 0, -18, 5, -25, -2, 3,
- -2, -3, 4, 8, 14, -7, 15, 4, 8, 19, 9, 11, 7, -3, 14, -11,
- 1, 15, -35, 3, 3, -10, -16, 0, -15, 2, 3, -12, 27, -23, 32, -15,
- 10, -14, 3, -27, 10, -15, 12, -24, 7, 2, 9, -2, -2, -1, 3, 1,
- 1, 8, -4, 0, 6, -6, 1, 1, -1, 8, -11, 31, -27, 13, 4, -3,
- 5, -1, 0, 2, 9, 0, 12, -31, 4, -27, 1, -25, 20, -21, -14, 12,
- -14, 0, -5, -23, 18, -1, 15, 19, -5, 20, -8, 14, -7, 16, 3, 0,
- 8, 10, 0, -8, -10, 3, -8, 9, -12, 4, 15, -6, 2, -12, -29, -3,
- -16, -11, 35, -18, -1, -28, 7, -12, 0, 7, -5, 22, 10, 10, -4, 6,
- -13, 21, -23, 20, 8, -13, 11, 15, -6, -6, -22, -1, 3, 14, 7, 11,
- -27, 12, -17, -12, 8, -15, 3, -8, 12, -12, 5, -30, 12, -18, 9, -2,
- 3, 4, 15, 1, 5, -9, 0, -8, 24, -2, 21, 5, -4, -4, 14, -15,
- 0, -1, 3, 17, -5, 13, -19, -10, -4, -6, -4, -7, 18, -27, 8, 1,
- -12, -21, -13, 1, -9, 11, 1, -3, -1, 22, -21, 9, 6, -3, 20, -2,
- 17, 7, -12, 1, 4, 4, -9, 9, -20, 24, 7, -9, -3, -7, -6, 10,
- 7, 3, 9, -2, -3, -4, 1, -19, -8, -16, 0, -12, 0, -25, 4, -22,
- 10, -9, 0, -3, 15, -1, 8, 11, -15, 10, 13, 1, 22, -5, 15, 1,
- 24, 6, 0, -6, 5, 5, 10, 8, -1, -11, -14, 3, -31, 2, -22, -4,
- -8, -15, -2, -31, -12, 6, -7, 5, 2, 3, -4, 19, 3, 4, 7, 7,
- -8, 31, -6, 26, 1, -2, 2, -3, -10, -4, -4, 9, 3, 12, -16, 16,
- -9, -1, 5, 4, -7, 13, -17, 0, -11, -13, -22, 1, -9, 4, -7, 7,
- -10, 5, -1, -6, -3, -21, 7, -10, 18, -3, 1, -7, -11, 11, -8, 12,
- 20, 3, 13, 16, -1, 3, 13, -3, 23, 16, -3, 15, -14, 12, -6, -8,
- -28, 0, -33, 4, -11, -12, -13, -21, -17, -16, -5, -12, 16, -7, 15, -6,
- -5, 3, -9, 21, 17, 13, 14, 11, 21, -12, 31, -18, 7, 12, 8, 9,
- 7, 1, -3, -7, -14, 17, -35, -10, -2, -18, -8, -10, -20, -22, 2, -10,
- -3, 1, -1, 4, -5, 11, -20, 11, -6, 27, 7, 18, 8, -1, 2, 3,
- 11, -9, 5, 5, -7, 29, -6, 20, -21, 23, -15, 19, -19, 2, -22, 11,
- -26, -7, -10, -30, -1, -3, -6, 15, -22, 16, -7, -9, -2, -7, -5, 11,
- 17, -13, 2, 8, -5, 6, 27, -6, 12, -6, 4, 15, 3, 14, -3, -12,
- 11, -2, 6, 5, 4, -6, -12, 0, -32, 2, -22, 22, -12, -5, -7, -11,
- -7, 6, -1, -3, -3, -16, 2, -1, 0, 0, -7, -2, 1, 12, -4, 5,
- 20, 1, 16, -2, 14, -1, 19, 8, 29, -8, 7, -14, -2, 3, -13, 8,
- -40, 22, -18, 2, -14, -8, -11, -8, 12, -21, -1, -10, -12, -6, -4, -14,
- 6, -19, 7, 14, 1, 11, 11, -11, 25, 1, 14, -5, 31, 0, 22, 4,
- 1, 3, 6, -3, 4, -2, -20, -7, -26, 1, -12, -7, -10, 2, -1, -5,
- -7, -8, -10, 6, -7, -6, 10, -17, 6, 3, 15, -8, 15, -7, 12, 1,
- 9, -4, -2, 10, 9, -1, 10, -4, 9, -8, 17, 0, -13, -7, -2, -11,
- 3, -2, -15, -4, -11, -5, -9, 1, 8, -10, 8, -8, -6, -18, 21, -19,
- 26, -19, -1, -11, 10, 4, 12, -10, 16, -10, 17, 8, 13, -1, 17, 1,
- 5, -1, 11, -8, 9, 16, -17, 3, -26, -17, -14, 6, -17, 4, -20, 0,
- -1, -6, -4, 2, -15, 13, -3, -1, 0, -2, -8, 11, 7, -3, -8, 5,
- 14, -1, 28, -19, 13, -4, 8, 1, 11, 7, 6, -8, -2, -13, -10, -22,
- 6, 11, -1, -1, -5, -13, 18, 3, -10, 9, -17, -8, 9, -9, 1, -17,
- -4, -16, 18, -6, 15, -10, 17, 5, 0, -5, 0, -11, 12, 15, 4, 8,
- 5, -4, 0, -2, 3, -17, -2, -1, 11, -6, -7, 2, -33, 23, -6, -1,
- -2, -2, -1, -8, 3, -29, -2, -34, 16, -3, 16, 1, 10, -12, 23, 0,
- -3, 16, 12, 19, 23, -1, 8, -26, 16, -32, 26, -13, 2, -11, 5, -1,
- -15, -9, -16, 7, -6, 14, -15, 5, -10, -7, -9, -9, 6, -17, 13, 18,
- -5, -3, -4, -4, -18, 28, -6, 13, 17, 24, -2, 9, -14, 1, -11, 7,
- 17, 1, -15, 10, -23, -4, -12, 5, -20, 17, -10, 6, 0, -9, 4, -8,
- -15, 6, -16, 7, 9, 3, 6, -12, -17, 0, 4, 13, 22, -4, 10, -8,
- 7, -12, 5, 5, 1, 11, 2, 10, -3, -2, 3, -10, -5, -7, -4, -18,
- 17, -2, -14, -16, -7, -10, -3, 6, -1, 14, -11, 15, -18, 2, -6, 0,
- -1, 0, 20, -17, 1, 6, 2, 6, 12, -3, 7, 25, -5, 17, -14, 0,
- -6, 0, -2, -5, -1, -10, 8, 2, -9, -19, -7, -17, 5, 3, -7, 4,
- -15, -5, 9, -12, -1, -5, 3, -5, 26, -2, 3, -4, 5, 3, 7, 10,
- 5, 6, 6, 26, -17, 0, -1, 3, -3, 10, -7, -7, -9, 11, -18, 0,
- -16, -6, -5, 3, 7, -14, -14, 0, -21, 14, -8, -1, -12, 2, 1, 2,
- -3, -1, -3, 18, 5, 5, 9, 12, 7, 18, 8, 5, -25, 16, -15, 16,
- -7, 9, -22, 1, 14, -13, -5, 2, -6, -8, 13, -17, 6, -16, 1, -5,
- -14, -6, -6, -15, -2, 9, -9, -18, 15, -19, 12, 7, 4, 8, 14, 15,
- 6, 10, -3, 9, -7, 23, -17, 21, -20, 7, 0, -9, 8, -10, 1, 4,
- 2, 3, -9, -9, -15, -6, -21, -16, -6, 0, -11, 19, -8, -9, 5, -6,
- 0, 5, 14, 7, 1, 12, 8, 7, -5, 12, 8, -4, 19, 4, -7, 2,
- 3, -12, -8, -1, 0, 5, 7, -5, -8, -22, -8, -21, -2, -9, 10, -20,
- 13, -6, 8, -17, -9, -6, 2, 5, 8, 6, -3, 10, -9, -2, 15, -6,
- 20, 7, 11, 10, -3, -4, -8, 25, -25, 18, -12, 17, -6, 20, -22, -1,
- -17, -10, 5, -10, 9, -13, -9, -6, 10, -25, -5, -2, -5, 13, 2, -5,
- -8, -10, 11, -27, 10, -4, 11, 0, 33, -4, 10, -14, 1, 12, -2, 27,
- -8, 6, 11, 9, -12, -4, -10, -13, 12, 5, 1, -10, -14, -15, -8, -7,
- -9, 3, -5, 10, 3, -11, -12, -13, -3, -3, 3, 2, 9, 17, -6, 25,
- -3, -3, -8, 19, 3, 30, -10, 12, -22, 7, -5, -10, -3, 21, -8, 12,
- 6, -5, -13, -13, -9, -9, -1, -23, 13, -17, 15, -22, -11, -18, 8, -14,
- 20, 1, 4, -5, 3, 3, 5, 11, 1, 2, 27, 1, 10, -7, -8, -2,
- -2, 7, -1, 17, -5, 24, -7, 5, -10, -20, -6, 5, -4, -5, -1, -18,
- -5, -14, -1, -20, 1, 7, -7, 12, -4, -2, -4, 2, 8, 0, 7, 1,
- 6, -2, 18, -5, -7, 4, 3, -2, 13, 4, 0, 2, -3, 2, -10, -6,
- 1, -6, 6, -7, -3, -21, -2, -12, 5, -1, -9, 7, -3, 13, 5, 5,
- -8, 0, -8, 19, -5, 13, 13, -7, 3, 0, -10, 0, -8, 20, -8, 13,
- -20, -5, -7, 3, 5, -7, 2, -5, -4, -14, 11, -23, -13, 2, -1, 12,
- 13, 5, -6, 23, -9, 9, -6, -9, 18, -13, 16, -3, -7, -17, 3, -13,
- 12, -9, 4, 0, 0, 13, -18, -1, 3, -13, 20, -5, 1, -20, 15, -23,
- 18, -4, -8, 5, -7, 16, 4, 6, -3, 7, -21, 19, -17, -7, 9, 5,
- 3, -5, -3, -16, -9, 25, -9, 12, -5, 10, -5, 9, -4, -6, -3, 4,
- 10, -2, 11, -12, -2, -14, 8, -23, -5, 0, -8, 9, -2, -11, -3, -9,
- 9, 2, 2, 4, -5, 7, 11, -16, 0, -6, 7, 6, 25, 5, 6, -4,
- 3, 4, 3, 2, -8, -3, 5, -1, -11, -4, -9, -3, -15, 10, -12, -5,
- 11, -4, -7, 6, -29, -5, 6, 11, 3, 9, -18, 13, -14, 19, -1, -2,
- 4, 5, 12, 1, 5, -8, 3, 1, 20, -6, 2, 3, -16, 10, -10, -18,
- -11, -7, -7, 9, -4, -8, 9, -15, 13, -13, -3, -7, 3, 8, 11, -6,
- -16, 1, -8, 20, 4, 15, -5, -3, 11, -5, 6, 0, -5, 10, 13, 0,
- -6, -11, 0, 11, -11, 10, -7, -8, 1, 16, -9, 2, -22, -9, 0, 4,
- 5, -12, -22, 2, -8, -8, 14, -16, 0, 13, 0, 9, -7, 2, -1, 7,
- 8, -3, -3, 2, 15, 5, 10, -7, 12, -4, 22, -4, -3, -12, -2, -15,
- 8, -2, -22, 7, -10, 5, 12, -20, -9, -11, -2, -12, 2, -9, 5, -3,
- 11, 7, -9, 4, -4, 24, -7, 21, -15, -3, 2, 14, -1, 5, 18, -12,
- 13, 3, 5, -10, -11, 0, -8, -2, -4, 2, -15, 9, -10, -16, -9, -7,
- 0, -1, 3, -8, -10, 5, -8, 4, -3, 8, -2, 20, 1, 6, -4, -9,
- 4, 14, 7, -1, 3, -5, 18, -7, 20, -6, -10, 8, 1, -2, 3, -4,
- -5, -3, -6, 0, -16, -7, 12, 0, -17, 4, -31, -7, 1, 1, -4, 8,
- -11, 6, -1, 11, -5, -7, -4, 2, 4, 15, -3, 21, -5, 20, 3, -12,
- 21, -1, 10, 5, 6, -20, -1, -18, 2, 3, -4, -5, -1, 6, -2, -11,
- -17, -15, -13, 0, 6, -18, 7, -18, 7, -7, 6, 7, -10, 18, 16, 2,
- -1, 3, -11, 6, 14, 1, 15, -2, 29, -8, 17, -14, 2, -19, 12, 8,
- -6, -1, -23, 6, -11, 7, -19, -18, 0, 1, -8, -8, -4, -20, 8, -8,
- 4, 10, -12, 13, 0, 18, -10, -3, -4, 6, 4, 17, 7, -2, 18, -9,
- 14, -10, -4, -11, 4, 3, 23, -17, -6, -2, -7, -7, 9, -10, 1, 2,
- -4, -14, -7, -6, -8, -4, 7, 2, -3, 3, 0, 13, -10, -4, -9, -6,
- 18, 11, -4, 16, -8, -4, 1, -1, 7, 3, 3, 3, 10, -15, -2, -9,
- 9, 0, 2, 2, -9, 12, -7, 0, -23, -7, -19, 2, -1, 0, 4, -15,
- 7, 3, -3, 0, 9, -12, 19, 4, 8, -13, -6, 5, -1, 14, 10, 9,
- 13, -3, 16, -18, 13, -18, 7, -10, 13, -6, -11, -3, 7, -23, -6, -11,
- -21, 9, -1, 4, -3, -16, 0, -12, 7, 14, -5, 15, 0, 6, -5, -3,
- -9, 9, 4, 10, 4, -2, -7, 10, -1, 10, -6, -14, 15, -4, 13, -4,
- -4, -14, 5, -2, 4, -9, 3, -14, 2, 3, -10, -1, -9, 0, 3, -6,
- 12, -16, 0, 4, 10, -25, 6, -5, 2, 8, 3, -2, -4, 15, 4, 7,
- 2, -1, -6, 10, 11, 2, -2, -14, 6, -3, 0, -3, -9, -10, 1, -1,
- -15, 9, -29, 9, -10, 7, -3, -3, -10, -2, 14, 4, -6, 0, 1, 12,
- 4, 18, -15, 19, 1, 15, 1, 1, 3, -10, 8, -1, 7, -30, 8, -19,
- -2, -5, -9, -10, 0, -1, 6, -4, -12, 1, -18, 10, -1, -12, 2, 7,
- 12, 11, 0, -4, -1, 6, 10, 17, -8, 1, -12, 5, -2, 1, -7, -1,
- 4, 3, -3, -1, -18, 8, -9, 0, -2, 8, -12, 12, 7, -5, -2, -16,
- -7, 9, -5, 11, -9, -4, 3, 1, -9, -1, -2, -6, 7, 12, 0, -8,
- 9, -10, 3, 0, 2, -3, 11, 14, 4, 3, -12, 3, -3, 2, 12, -4,
- -2, -2, 9, -21, -5, -28, -6, -10, 6, 7, -6, -3, -24, 7, -11, 10,
- 0, 8, 13, 10, 6, -7, -2, -5, 7, -1, 9, 18, -2, 12, -4, 7,
- -26, 13, -6, 19, 6, 6, -5, -16, -6, -8, -18, -2, 1, -11, 3, 4,
- -16, -8, -10, -3, 2, -3, 5, 5, 0, 11, 0, -14, 0, 1, 14, 11,
- 13, 0, -2, 5, -1, -4, -2, -4, 5, 21, 3, 14, -5, -22, 5, -11,
- -3, -6, -3, -11, 0, -5, -13, -10, -18, 3, 9, -10, 2, 3, -11, 11,
- -11, 5, -19, 23, -1, 20, 18, 4, -3, -6, 9, 4, -3, 8, 4, 6,
- 2, 5, -14, -6, -3, 2, -6, -4, -3, -11, 0, -5, 0, -21, -2, -10,
- 11, 5, -4, -5, -5, -8, 10, -10, 4, -1, 6, 12, 9, 2, 8, -20,
- 8, -2, 11, -11, 1, -4, 5, 6, -6, 6, -14, 14, 4, -2, 12, -3,
- -10, 8, -5, -15, -9, -1, 5, 8, -3, 0, -23, -9, -11, 4, -12, 3,
- -4, 4, 1, 15, -12, 3, 13, 2, 5, 8, -8, 7, 11, -3, 17, -11,
- 5, 3, 19, 13, 3, -11, -11, -2, -9, -7, -4, -24, -1, -17, -3, -17,
- 0, -15, 2, -1, -5, -4, 3, 2, 2, 11, -4, 3, -6, 11, 8, 3,
- 6, 3, 7, 7, 6, -6, 2, 0, 14, 14, 3, 8, -6, 4, -3, 6,
- -13, -2, -9, -4, 5, -13, -5, -21, -1, -6, -1, -5, -14, 8, -7, 5,
- -7, -17, -11, 7, 3, 20, 7, 1, -3, 4, 5, 14, -3, 5, 3, 10,
- 8, 6, -6, -2, 6, 3, 7, -6, -3, -3, -6, -1, -27, -11, -17, 0,
- 11, 7, 1, -7, -9, -13, 5, -11, 0, -10, 15, 2, 5, -2, -5, 1,
- 6, 6, -6, -5, 6, 2, 5, 3, 10, -16, 11, 8, 18, 3, 13, -11,
- 7, 5, -7, -6, -20, 15, -1, 10, -1, -13, -17, -11, -3, -13, -4, -14,
- -3, -2, -6, 6, -28, 9, -8, 10, 0, 12, -2, 10, 9, 1, 3, -6,
- 5, 17, 24, 18, 3, 4, -9, -4, 2, -8, -4, -2, -11, 1, -8, -12,
- -9, -10, 5, 0, -7, -9, 7, -18, 6, -10, -12, -1, -1, 13, 1, 18,
- 2, -3, 4, 3, 3, -3, 3, 10, 9, 7, 5, -8, -7, 0, 3, -7,
- 7, -2, -2, 5, -10, 2, -5, -3, -1, 4, 1, -2, -10, 4, -9, -5,
- -12, -18, 3, 6, -3, 3, -15, -1, -13, 6, -2, 8, 0, 8, 16, -2,
- 17, -4, 8, 3, 23, -1, 11, -8, 10, -4, -5, -3, -13, -2, -1, -2,
- 2, -9, -13, -13, -2, -11, -2, -20, -5, 0, 3, 2, -1, -10, 1, 8,
- 3, 9, 6, 4, -3, 13, 3, 4, 11, 2, 11, 8, -2, -1, -2, -2,
- -2, -1, -21, -1, -14, 8, 6, -8, -10, 2, -16, 4, -3, -1, -10, 7,
- -1, 4, -4, -12, 3, -2, 13, 2, -3, -9, -2, 6, -7, 8, -8, -5,
- 12, 7, 8, -3, 6, -1, 16, 0, 7, -8, 3, -7, -1, 0, -6, -4,
- -8, 6, -1, 4, -19, 2, -3, -8, -3, -12, 4, -6, 2, -7, 1, -13,
- 2, 9, -1, 17, -19, 3, -3, 23, 9, 6, 3, 6, 6, -5, 11, -11,
- 1, 0, -5, 6, -6, -4, -5, -7, 3, -4, -14, -9, -7, -1, 5, -11,
- 4, -19, 14, -4, 3, 4, 2, 0, 9, -2, -3, 2, -2, 10, 15, -3,
- 14, -6, -4, 6, 1, -8, 11, -9, 4, 3, -9, 2, 2, -2, 2, -2,
- -9, -2, -2, 1, -6, -6, -22, -16, -10, 12, 0, 5, -8, -2, -4, -2,
- 5, -1, 7, 7, 9, 1, 7, 6, -1, 10, 11, 5, -3, 8, 1, -1,
- 8, -15, -6, -10, 12, 0, 2, -5, -9, -12, -7, -4, -14, -4, 0, -1,
- 5, -7, -8, -12, 0, 2, 16, -3, 11, -4, 16, 11, 2, -3, 2, 8,
- -1, 7, -13, 4, -3, -1, 3, -10, -2, -11, 3, 2, 3, -7, -10, -5,
- -10, 12, -8, 5, -7, 15, 1, -10, 7, -16, 1, 3, 4, -5, 7, -7,
- 4, -2, -1, -8, 0, -2, 17, 10, -2, 6, -5, 3, 10, -7, 2, -3,
- 4, 5, 5, -3, -8, -8, -1, 1, 7, -5, -11, -2, -10, -4, -15, -7,
- -10, -2, 2, -4, -10, -8, 0, 2, 6, 3, 2, 3, 10, 14, 8, 7,
- 3, 5, -5, 20, -6, -1, -2, 0, 1, -2, -2, -8, 3, -3, 10, -14,
- 3, -3, -2, 0, -5, 0, -15, 4, -2, 0, 4, -7, 3, -8, 7, -14,
- -2, -6, 4, 2, 3, -10, -2, 5, -3, 12, -2, -5, -9, 1, 4, 1,
- 11, -12, 15, 5, 20, 10, -5, 1, 5, 3, -13, 6, -16, 5, 1, -5,
- -8, -3, -14, -6, -2, -5, -8, -17, -9, 3, -6, -2, -3, -3, 1, 14,
- 2, 4, 5, 3, 8, 7, 12, 0, 11, 4, 16, 2, -3, -9, -1, 1,
- -1, -3, -6, -14, 4, -6, 2, -14, -9, -11, -1, 0, 0, -5, -6, -10,
- 5, -5, 2, -3, 2, 2, 17, -2, -1, -3, 3, 11, 1, 10, 2, 7,
- 6, 5, -5, -3, -3, -2, 7, 2, 1, -18, -5, -2, -3, -5, 0, -2,
- 0, 8, -9, -10, -15, -7, -2, -1, 6, -8, 16, -10, 13, -4, 2, -4,
- 4, 7, 9, 6, -5, -2, 8, -1, 11, -6, -1, 5, 8, 0, 9, -20,
- 0, -9, 4, -3, 1, -4, -11, 2, -6, 0, -12, 0, 1, 5, -2, 1,
- -7, -4, 3, -1, -10, 3, -3, 7, 4, 8, -9, -6, -10, 0, 0, 2,
- -4, 6, 9, 10, 2, 0, -1, 2, 14, 3, 7, -7, 2, -2, -2, -6,
- -9, 2, -3, 6, -3, -7, -9, -10, -2, 2, -1, -11, 2, 1, 7, -4,
- -7, -19, 3, -1, 6, 6, 6, 6, 0, 6, 7, 3, -1, 3, 8, 3,
- 4, -10, -5, -7, 5, -4, -14, 2, -8, 5, -2, 2, -16, -4, -11, 2,
- 4, -1, 2, -1, 0, 5, 4, -12, 3, 9, 7, 13, -3, -7, 2, 6,
- -1, 7, -1, -1, 5, -5, 7, -11, -9, -13, 2, 5, 2, -2, -7, 5,
- 4, -4, -2, -15, -4, 3, 0, 0, -5, 2, -7, -1, 9, -2, -1, 5,
- 1, 1, -4, -5, -4, 6, 8, 7, -5, 4, -7, 4, 0, 1, -6, -5,
- -2, 5, -1, 0, 1, 1, 3, 9, -4, -2, -4, -9, -1, 4, -17, 1,
- -13, 11, -1, 6, -9, -1, 5, 1, 8, -3, 4, -5, 1, 7, -5, 1,
- -3, 5, 3, 4, -7, -11, -7, 1, 5, -13, 11, -11, 1, 3, 6, -9,
- 6, -5, -7, 4, -13, 5, -7, 10, 5, 6, -15, -1, 6, 4, 18, -7,
- -7, -3, -4, 2, -5, 3, -4, 9, -4, 3, 3, -3, -10, 0, -1, 2,
- 5, -3, 7, 3, 2, -6, -11, -2, -1, 4, -5, 4, -5, 0, -5, 5,
- -5, -4, 2, 4, 2, 5, -8, -13, -3, 0, -1, -2, 4, 6, 9, 1,
- 3, -7, -1, 1, 12, 1, 1, -1, -5, -1, 2, -8, -9, -7, -2, 3,
- 10, -6, -7, -12, -7, -4, -5, 6, 0, 10, 5, 7, -4, -2, -8, 10,
- 5, 9, 4, -1, -1, -1, -1, -1, -2, -3, 3, 9, -2, 9, -14, -13,
- -8, -10, 1, 1, 3, 3, 1, -3, -12, -5, -7, 1, 6, 6, -2, -7,
- -3, -3, 2, 2, 4, -9, 14, 8, 11, -3, 5, -11, 1, -1, 5, 3,
- 8, 2, 8, -2, -6, -13, -10, 0, 4, 3, 4, -3, -9, 1, -5, -5,
- -6, 1, -2, 2, -10, -6, -15, 1, -5, 4, -1, 2, 2, 4, 10, 4,
- 2, -13, 0, 4, 8, 17, 2, 5, 4, 2, -6, 5, -5, 0, 8, -2,
- -1, -5, -4, -5, -1, -5, -4, -5, 0, 0, 1, -9, -15, -3, -12, 1,
- -1, -7, 10, 2, 5, -1, 2, -6, 2, 2, 10, 10, -1, 2, -2, 4,
- 5, 0, -6, 12, 5, 3, -1, -8, -8, -4, -4, 3, -11, 0, -1, -1,
- 0, -2, -14, -6, -9, 2, 1, 7, -4, 3, -1, 0, -3, 1, 2, 7,
- 5, 4, 3, -2, -3, 1, 6, -1, 6, -11, 7, 2, -6, 2, -4, 0,
- 2, 3, -7, -9, 3, 0, 4, -6, 0, -21, 0, -5, -1, 0, -1, 1,
- -6, -1, -1, 0, -7, 5, 7, -2, 8, -4, -1, 3, 9, -6, 10, -6,
- 7, 9, 10, 9, -6, 5, -14, 6, -5, 1, 2, -3, 0, -9, -10, -14,
- -2, -3, 6, -8, -15, 3, -9, 0, -3, 0, -6, -1, 3, 9, 10, 3,
- 3, -10, 6, 1, 3, -1, 9, 12, 4, 4, -9, -7, -5, 8, 6, 1,
- 1, -4, -5, -5, -1, -11, -3, -4, 1, -1, 1, -10, -7, -2, -3, -4,
- -3, -6, 11, 5, 3, 2, -8, -5, -2, 3, 9, 13, 5, 4, 4, 0,
- -5, -1, -5, 9, 2, 3, -9, -4, 3, -6, 2, 1, -9, 5, -2, 3,
- -2, -9, -8, -15, -5, -3, 3, -13, 11, 6, -3, 1, -6, -6, -1, 6,
- 4, 6, 7, 1, 5, 0, 8, -6, 7, 2, 6, 2, -5, 0, -3, -1,
- 3, -7, -1, -3, 5, 7, 6, -18, -10, -11, -7, -3, 10, -4, 3, -4,
- -8, -5, -12, -3, -4, 12, 10, 2, -4, 6, 3, 1, 2, 0, -3, 3,
- 7, 7, -5, 2, -4, 1, 3, 11, 2, 3, 4, -2, -7, -5, -17, -11,
- 4, -3, 5, -7, -7, -6, -1, -8, -5, -5, 1, 7, 1, 2, -1, -9,
- 7, 1, 7, 3, 3, 6, 9, 6, 1, -6, -4, 2, 5, 7, 4, -2,
- 1, 3, -11, -1, -16, -2, -6, 1, 3, -8, -15, -11, 4, -1, 9, -2,
- -5, 0, 6, 0, -7, 0, -8, 4, 2, 6, 2, 0, 2, 6, 2, -2,
- 4, -2, 4, 14, 2, 2, -6, -6, -3, 4, -4, -1, -4, 1, -3, -6,
- -1, -13, -1, -2, 7, -8, -7, -10, 0, 4, 3, -8, -3, 1, 4, 6,
- 4, 6, -3, 5, 3, 4, 0, 6, 1, 4, 7, -3, -10, 8, -1, 9,
- -1, 1, -11, -7, -3, -3, -6, -8, -9, -6, 1, -3, -6, -6, -5, 0,
- 0, 2, -3, 0, 6, 4, 3, 2, 7, 4, 11, 14, 5, -1, -5, 1,
- -2, 7, 3, 0, 1, 2, -5, -7, -10, -12, -10, -5, -5, -6, -6, -9,
- 1, -8, -2, -1, -9, 1, 8, 2, -5, -2, -5, 0, 5, 6, 6, 7,
- 8, 10, 2, 0, -3, -1, 2, 13, 3, 0, -6, 0, 1, -3, 0, -12,
- -2, 4, -4, 4, -8, -11, -1, -2, 1, -1, 2, -12, 3, -6, 1, -12,
- -7, -7, 3, 0, 9, 0, 1, 6, 1, -1, 2, 1, 2, 8, 9, -3,
- -1, 0, 7, 3, 8, -1, -4, -1, 1, 3, -9, -1, -17, -3, -2, -4,
- -4, -3, -4, -6, -11, -15, -2, -5, 6, 10, 1, 3, -1, -3, 13, 7,
- 1, 6, 4, 4, 9, 5, -3, -5, 9, 3, 5, -3, 1, -3, 3, 0,
- -7, -5, -7, 0, -5, 0, -1, -15, -11, -4, -5, -10, 2, -7, 5, -4,
- 1, -9, 2, 1, 8, 7, 10, 2, 2, 0, 4, 3, -2, 0, 4, 2,
- 6, 8, -2, 4, 4, -2, 5, -3, -6, 3, -3, -5, -9, -8, -11, -5,
- -1, -1, -5, -7, -5, -8, 0, -3, 5, -7, 11, 1, 0, 2, -3, -1,
- 3, 9, 6, -3, 8, 1, 11, 2, 8, -3, -3, 6, 2, 1, 2, -7,
- -3, -2, -4, -8, -3, -3, 5, -10, -10, -4, -12, -2, 3, -5, 3, -6,
- -8, -2, 5, -3, 0, 1, 4, 8, 4, 5, 0, 4, 8, 1, 7, -3,
- 0, 3, 4, 4, -5, -2, -7, -3, 0, 5, -5, -9, 3, -2, -1, -2,
- -5, -1, -4, -3, -11, -4, -5, -6, 0, 5, 0, -5, 5, 3, 8, -1,
- 3, 3, 2, 5, 7, -4, 3, 1, 3, 10, 2, -7, 1, 0, 6, -4,
- -3, -5, -7, -2, -4, -3, -6, 0, -10, 4, -6, -4, -7, -2, 1, -4,
- -1, -3, -1, 2, 6, 2, 4, -2, 2, 4, 2, 5, -3, 4, 2, 1,
- 0, 8, -3, 2, 5, -5, 3, -5, -2, 5, -5, 3, -1, -4, -3, 4,
- -10, -5, -7, -4, -4, 0, 0, -7, -1, -1, 2, 1, -2, -12, -4, -1,
- 0, 4, -5, 2, 0, 3, 12, 11, 3, 11, -1, -3, 6, -6, 1, 1,
- 7, 6, -7, -1, -7, -4, -4, -7, -8, -1, -6, -6, -2, -3, -5, 0,
- -4, 8, -7, 1, 4, -3, 6, 1, -7, 3, 5, 6, 5, 13, 2, 2,
- -4, 4, -3, 1, 4, -4, 2, -3, -10, -10, -7, -2, -2, -2, 0, -6,
- -2, 1, -3, -4, -2, -5, -2, 7, 1, 6, -5, 6, -1, -1, 2, -3,
- 4, 11, 2, -1, 2, -7, -5, 8, 0, 3, -3, -5, -1, -2, 3, 1,
- -4, 4, 7, 0, 2, 3, -3, 0, 1, -5, -15, -5, -3, 1, 3, -3,
- -11, -4, -7, 1, -2, -1, -1, 0, 1, 1, -5, -1, 3, -2, 7, 1,
- -4, -1, 0, 4, 5, 3, 3, -1, 8, 11, 1, 4, 1, -5, 7, -6,
- -4, -2, -4, -2, 3, -8, -3, -13, -6, 3, -3, -7, -4, -7, 3, 3,
- -3, 2, -1, 1, -4, -2, -2, -5, 1, 11, 9, -2, 6, -3, 7, 7,
- 1, 1, -7, 2, -3, 1, 4, -4, -4, 5, 1, 0, -3, -6, 2, -3,
- 0, -8, -12, -6, -2, -3, 6, -1, -9, 0, -1, 1, 3, -2, -1, 0,
- 1, 6, 0, -3, 5, 1, 6, 1, -1, 4, 1, 7, -3, -1, -1, -4,
- 4, 14, -1, -1, 2, -4, -1, -6, -8, -8, -3, -2, 2, -9, -5, -7,
- -12, 5, 0, -3, -4, -3, 5, 4, 3, -2, -6, 4, 7, 3, 5, 7,
- -3, 8, 0, -5, -1, -1, 11, 10, 3, 4, -8, -3, -3, 1, -3, 0,
- -4, -3, 1, -7, -8, -16, -7, -6, -2, 3, -7, -2, 1, -4, 0, -5,
- -5, 1, 5, 10, 5, 0, 3, 0, 1, 13, 0, 5, 9, 6, 8, -1,
- -4, 0, -3, 6, 4, -4, 0, -3, -15, -2, -12, -15, -3, -6, 2, 1,
- -3, -4, -9, -9, -3, -3, -2, 3, 4, 9, 0, 2, 1, 2, 14, 5,
- 3, 8, 2, 7, 4, -4, -4, -1, -9, 9, -5, -1, -7, -10, -2, -7,
- -4, 0, -5, 2, 5, 1, 0, -5, -5, -1, -1, -3, 4, -8, 5, 3,
- -4, 4, -5, -3, 9, 4, 8, 0, 0, 2, 0, -2, 0, -2, -7, 12,
- -1, 5, -4, 2, -3, 0, 2, -2, -4, -2, 2, -5, 3, -7, -9, -4,
- -3, -2, -6, -6, -2, -6, -1, -7, -8, 1, 3, 6, 10, 4, 5, 0,
- 5, 8, 1, 3, 8, 5, 11, 12, -7, 4, 0, -3, 2, -1, -8, -7,
- -4, -2, -6, -9, -6, -13, -4, -1, 0, -9, -5, -3, -4, -2, 3, 1,
- 1, 9, 4, 2, 6, -1, 3, 6, 2, 0, -3, 3, 2, 6, 3, -1,
- -4, 4, 1, 2, 2, -5, -8, -1, -3, -1, -9, -4, 1, -5, 5, -7,
- -4, 0, 3, -10, 3, -3, -5, 1, 5, 4, 1, -5, 1, -5, 4, 1,
- -6, 0, 5, 8, 8, 1, 6, 0, 3, 4, 2, -3, 1, -3, -3, 3,
- -10, -6, -8, -2, -1, -3, -6, -6, -5, -6, -6, -5, 5, -3, 5, 6,
- -2, -1, -1, -4, 6, -2, 6, 6, 2, 12, 8, -2, 3, -6, -2, 5,
- 4, -3, -2, -5, -4, -7, -6, 1, -5, 2, 2, 0, 1, -7, 0, -4,
- -2, -1, -2, -5, 7, -5, -2, -3, -2, -3, 4, 4, 9, 0, 1, 1,
- -5, -3, -4, -4, 4, 3, 6, 1, -2, -2, -7, 4, 1, 1, -3, 3,
- -1, 2, 0, -7, 0, 0, -1, -3, -2, -1, -5, -2, -3, -8, -5, -5,
- -1, 5, 5, 2, 2, -3, 4, 3, 4, 6, 3, -1, 10, -4, -3, -2,
- -3, 0, -4, 0, -2, -2, 0, 2, -5, -2, -5, -9, 8, -2, -1, -1,
- -3, -3, -2, -6, 2, 1, 2, 9, 0, 1, 4, -5, 2, 4, -6, -1,
- 2, -1, 6, 3, 0, -5, -3, -1, 0, 3, -3, 0, -6, -2, -3, -4,
- -2, 0, 3, 2, 2, 0, -10, 1, -6, -5, -1, -2, 5, 3, 6, -2,
- -6, -1, -3, 2, 4, 1, -1, 0, 1, 1, 3, -1, 5, -1, 7, 6,
- 1, -2, 0, -6, -2, -2, -8, -2, -2, -3, -5, -5, -8, -3, -1, 5,
- -3, 1, 2, 1, 2, -3, -2, -3, 2, 6, 2, 6, 0, 0, -2, 9,
- -1, 3, -2, 3, 0, 0, 0, -6, -6, -1, -5, -7, 1, -3, -6, 2,
- -2, -1, -5, -2, 1, 4, 2, 2, -3, -1, 6, -2, 2, 4, -3, 2,
- 2, 2, -3, 1, 0, -4, 2, -1, -2, 3, 1, 1, -1, -5, -8, -2,
- -5, 0, 1, -6, 3, -4, 2, 3, -6, 3, 0, 2, -2, -1, -4, -2,
- -4, 4, 0, -3, 0, -6, -3, 10, -3, 3, 0, 4, 7, 3, 0, 5,
- 1, 5, 1, -3, -2, 0, -6, 3, -1, -7, -5, -7, -1, -2, -2, -2,
- -3, -2, 2, -2, -1, -3, -3, 2, -2, -6, -3, -3, 4, 3, 2, 0,
- -1, 5, 5, 8, 2, 2, -2, 4, 0, 5, -5, -3, -1, -3, -3, -6,
- -4, -2, 3, 0, -2, -2, -5, 5, -1, 3, -1, -1, -3, 0, 0, -5,
- -4, -3, -2, 5, 0, -4, -4, 1, 2, 6, 0, -3, -1, 2, 3, 7,
- -3, 0, -4, -2, 4, 3, 0, 1, 3, -3, 1, -7, -4, 0, 1, 1,
- -4, -4, -4, -9, -1, -2, -3, -2, -3, -3, 4, 3, -1, -4, 2, 4,
- 4, 3, 2, -1, 0, 9, -1, 4, 2, 7, -1, 6, -2, -2, -5, -1,
- -9, -2, -2, -6, -1, -1, 1, -8, -6, -5, -1, -1, 1, -4, -5, 3,
- 1, 5, 3, -3, 0, -2, 7, 0, 1, -2, 3, -1, 5, -1, -5, 7,
- -1, 3, 2, -5, -6, -2, 4, 2, -1, -3, -1, -1, -1, -1, -2, -4,
- 1, -5, 3, -1, -3, -5, 2, 6, -6, -1, -5, -4, 4, -1, -1, -2,
- -1, 2, 0, 3, 1, 4, 2, 7, -1, 2, 0, -2, 1, 4, -5, -3,
- -7, -2, 0, -1, -1, -3, 0, 0, -2, -6, 2, -4, 2, -4, 1, -7,
- -2, -1, 5, 3, -2, -7, -4, 1, 6, 4, 5, 1, 4, 0, 5, 1,
- -1, 2, 0, -3, -3, -5, -6, 3, -1, 5, -1, -2, 1, 1, 4, 2,
- -6, -3, -4, -3, 2, -2, -8, -3, -6, -4, -2, -11, 0, 0, 1, 6,
- -3, -2, 1, 2, 10, 8, 4, -2, -1, 2, 2, 1, -2, 3, 1, 5,
- 3, -1, 0, -4, 4, -7, -2, -7, -8, -4, -3, -2, -7, -7, -3, -1,
- 5, -2, 0, -7, 2, -1, 3, 1, 4, 6, 5, 8, 3, 2, -1, 3,
- -3, 0, 0, -5, -1, 1, 1, -5, -3, -2, 6, 4, 5, -4, -8, -4,
- -3, -2, -5, -4, -4, -4, 2, -3, -2, -4, -4, -4, 6, 1, 0, 1,
- 3, 3, 5, 2, 1, 0, 6, 2, -1, 1, -3, -3, 2, -1, 0, 1,
- 3, 1, 4, -4, -5, -10, -8, 1, -6, -3, -4, -6, -3, 0, 2, -3,
- -1, 2, 0, 8, 1, 4, 4, 3, 6, 3, 1, 3, 5, 1, 2, -4,
- -7, -3, -3, 3, 0, -7, -5, 0, -3, -1, -2, -4, 0, -5, 1, -6,
- -1, -5, -3, 1, 4, -1, -3, 3, 3, 5, -1, -2, 2, -1, 2, 1,
- -1, -5, 5, 1, 2, 2, -4, 0, -1, 3, 0, -2, -1, 2, 1, 5,
- 4, -3, -5, 0, -2, -2, -6, -3, -3, -4, -1, -5, -4, -1, -2, 0,
- 2, -2, -6, -3, 1, 1, 1, -1, 3, 4, 7, 2, 3, 4, -1, 7,
- 2, 3, 1, -1, 1, -2, 0, -4, -5, -6, 0, -2, -7, -2, -5, -5,
- 1, -4, -5, -5, 3, -1, 1, 2, -2, 0, 1, 4, 1, -4, 2, 2,
- 0, 9, 2, 0, 4, 3, 1, 2, -4, -2, -4, 3, -4, -2, -6, 0,
- -1, 5, 2, -4, 0, -4, -4, -1, -5, -4, -7, -3, 1, 0, -2, -1,
- -5, 1, 0, -1, 0, 2, 4, 0, 3, -2, 1, 2, 6, 0, 1, 5,
- 0, 3, 3, 2, -5, -2, 1, 5, 2, -2, -5, -9, 0, -6, -1, -6,
- -7, -5, -4, 0, -2, -5, -3, 2, -2, 3, 2, 0, 9, 2, 0, 4,
- -3, 4, 5, 8, 6, -2, -4, -1, 0, -2, -2, 1, -5, 2, -5, -1,
- -4, -3, -4, 0, -2, -7, -3, -1, 0, -1, 0, -6, 3, -2, 5, 2,
- -1, -2, 1, 0, 1, -1, -3, 2, 3, 1, 2, -4, -3, -1, 5, 5,
- 3, -4, 0, 1, 2, 5, -5, 1, -5, 2, -2, 2, -4, -3, 0, -4,
- -3, -9, -7, -4, 2, -2, 1, -6, -3, 0, 1, 5, 1, -5, 0, 0,
- 2, 1, 2, 0, 6, 4, 6, 3, 2, 3, 1, -2, -2, -9, -4, -1,
- 4, 0, -1, -5, -8, -5, -4, 0, -4, -1, -3, 0, 0, -4, -3, -1,
- 1, 2, 0, -2, -3, 1, 3, 2, 3, 3, 0, 8, 2, 7, -1, 3,
- -2, 4, 0, 0, 1, -4, 5, -1, -3, -3, -6, -4, 2, 1, -5, -4,
- -7, -4, -4, -7, -2, -10, 1, 0, 1, -3, 4, -2, 5, 2, 1, -3,
- -1, 2, 8, 4, 5, 0, 1, 4, 5, 2, 2, -2, 1, -4, 0, -3,
- -3, -1, 0, 2, -4, -4, -5, -1, -7, 0, -4, -5, -1, -3, 2, -2,
- 0, 3, 0, 2, 0, 1, -2, 2, 4, -1, 0, -3, -1, 1, 3, 2,
- -3, 2, 0, 2, 2, -1, 2, -2, -3, 0, 0, -2, 2, -2, 4, -3,
- -6, -7, -6, 2, -1, -4, -1, -7, -1, -3, 3, -1, 0, -2, 2, 2,
- -3, 3, -4, 5, 7, 6, 3, 1, -1, 6, 2, 1, 0, -1, -1, 1,
- -3, 1, -3, -5, -5, -3, -8, -3, -11, -1, -1, 0, -8, -2, -5, 3,
- 4, 0, 1, -2, 2, 0, 6, 4, 1, 4, 1, 5, 0, 0, 1, 2,
- 5, 0, 1, -10, 0, -5, 2, 0, -6, -6, -2, -2, 2, -3, 0, -4,
- 2, -4, 1, -3, -4, 1, -2, 2, 1, -2, 0, 3, 2, -3, -1, -5,
- -3, 4, 2, 3, -1, 4, 1, 5, -1, 2, -3, 2, -3, 0, -3, -2,
- 1, 1, 5, 1, -2, -5, 1, -1, -4, -3, -7, 0, -5, -4, -4, 0,
- -4, 4, 0, -1, 1, -8, 1, 0, 9, 1, 2, -2, 5, 5, 1, 6,
- -1, 6, 3, 1, 1, -2, -2, -4, -3, -2, -3, -7, -4, -4, -1, -3,
- -8, -1, -8, 4, -5, 0, -3, 1, 0, 4, -1, 0, 1, 3, 3, 4,
- -4, 6, -2, 2, 5, 4, -3, 4, -3, 5, 0, -4, 0, 0, -1, 0,
- -4, -4, 3, -1, -2, -4, -8, -9, -5, -4, 4, -4, 1, -4, 1, 1,
- -1, -1, -1, 3, 2, 3, 0, 1, 2, 1, 5, 3, 1, 0, 5, 3,
- 3, 0, -5, -4, -2, 5, 0, -2, -5, -2, -6, -2, -5, -8, -2, 1,
- -1, -3, -7, -8, -6, 0, 4, 7, -2, 7, -1, 7, 3, 2, -5, 0,
- 2, 0, 1, -3, 2, 2, 3, 3, -3, 0, -2, 3, -1, -1, -4, -6,
- -2, -3, 4, -4, 0, -4, 6, -2, -6, -2, -7, 1, 2, -1, -3, -2,
- -2, 3, -1, 0, -3, -1, 4, 7, 4, 0, 2, -1, 0, 6, -2, 1,
- 1, 5, 4, 1, -3, -3, -2, 2, 2, 1, -6, -6, -3, -4, -2, -6,
- -5, -4, -5, -2, -8, -8, -3, 0, 4, 0, 1, -1, 2, 5, 4, 2,
- 2, 3, 3, 4, 10, 0, 2, 0, 3, 1, 1, 0, -3, 1, -3, 1,
- -7, 0, 1, -2, 1, -6, -4, -10, -1, -4, -2, -2, -3, 2, -4, 1,
- -5, -4, -4, 2, 1, 1, -4, -1, 3, 1, 6, 2, -2, -2, 3, 3,
- 2, 7, -5, 5, 0, 8, 1, -1, 2, 3, -1, -6, 0, -10, 3, -1,
- -1, -5, -6, -8, -2, 0, -3, -5, -8, -4, 2, -3, -1, -2, 0, -1,
- 7, -1, 3, 2, 4, 7, 3, 4, -1, 5, 1, 9, 1, -2, -1, -1,
- 1, -3, -2, -6, -7, 1, -3, -1, -9, -4, -6, 0, 2, -3, -2, -4,
- -3, 0, -4, -1, -4, 0, 1, 6, -1, 1, -1, 3, 5, -1, 3, 4,
- 5, 7, 4, -2, 0, -2, 0, 3, 1, -1, -8, -2, -1, -2, -5, -1,
- -2, -2, 2, -5, -7, -9, -2, -3, -2, 1, -5, 4, -4, 5, -1, -1,
- -3, 2, 3, 7, 3, -1, 3, 4, -1, 5, -4, 0, 4, 4, 3, 4,
- -9, 1, -5, 2, -2, -2, -3, -7, -1, -2, -2, -5, -3, -1, 1, -2,
- -1, -4, -4, 1, -1, -7, 0, -1, 2, 5, 4, -4, -5, -4, 0, 2,
- 1, -1, 3, 5, 4, 0, 0, -1, 3, 8, 3, 3, -4, 0, 1, 0,
- -2, -6, -2, -4, 3, -2, -3, -5, -6, -3, -1, -1, -7, 0, 0, 3,
- -5, -4, -11, 0, 0, 3, 3, 1, 1, 1, 4, 6, 1, 1, 2, 9,
- 3, 3, -4, -4, -3, 2, -1, -6, 1, -5, 2, 0, -1, -8, -5, -6,
- 1, 0, -2, -1, -2, -1, 2, 0, -9, 0, 5, 4, 7, -3, -3, 3,
- 4, 2, 4, 0, -1, 3, 1, 5, -5, -6, -7, 0, 3, 0, -2, -4,
- 3, 3, -3, -4, -7, -2, 4, 1, -1, -4, -1, -6, -2, 3, -2, -3,
- 1, 4, 1, -1, -4, -3, 3, 4, 5, -2, 2, -3, 4, 0, 3, -3,
- -3, 0, 3, 1, -2, -1, -3, 2, 4, -2, -2, -3, -1, -1, 3, -11,
- -2, -8, 5, -1, 3, -5, -2, 2, -1, 3, -3, 0, -1, -1, 5, -2,
- 0, -2, 3, 2, 3, -2, -6, -3, 2, 4, -6, 5, -6, 1, 2, 3,
- -6, 2, -3, -4, 3, -9, 2, -6, 3, 4, 2, -9, -1, 1, 2, 8,
- -3, -4, -1, -2, 2, -2, 2, -3, 3, -1, 1, 2, -1, -6, 1, 2,
- 2, 1, -2, 2, 3, 1, -3, -6, -3, 0, 1, -3, 0, -3, -1, -4,
- 2, -4, -3, -1, 4, 0, 5, -6, -7, -1, 0, 0, -3, -1, 2, 4,
- 0, 3, -4, -1, 1, 7, 4, 2, -1, -4, 0, 2, -4, -5, -5, -1,
- 1, 4, -5, -4, -6, -3, -2, -3, 2, -2, 5, 2, 3, -4, -2, -5,
- 6, 3, 4, 2, -3, 1, 0, 0, 1, -3, -1, 1, 7, 0, 6, -6,
- -7, -2, -7, 0, -1, 0, 2, 1, -2, -7, -2, -5, 0, 2, 0, -3,
- -5, -1, -3, 0, -1, 0, -6, 8, 4, 5, -1, 1, -4, 1, 1, 4,
- 2, 5, 3, 6, 0, -2, -9, -4, -1, 0, 0, 1, -1, -4, -1, -5,
- -5, -5, 0, 0, 1, -6, -5, -9, 0, -3, 0, -2, 0, 0, 3, 4,
- 2, 1, -7, 1, 3, 4, 9, 1, 4, 4, 2, -4, 2, -2, 1, 5,
- -2, 0, -3, -4, -3, -2, -4, -4, -4, 1, -1, 2, -6, -8, -3, -8,
- -1, -2, -4, 5, 2, 3, -1, 0, -4, 2, -1, 5, 5, -1, 3, 0,
- 3, 3, 0, -4, 9, 4, 2, -1, -6, -4, -2, -2, 2, -7, 0, 0,
- -2, -2, -2, -10, -4, -7, 0, -2, 2, -2, 2, 1, 0, -3, 0, 1,
- 6, 3, 2, 0, 0, -1, 2, 3, -1, 4, -5, 6, 2, -3, 0, -3,
- 0, 1, 0, -5, -6, 1, 0, 1, -5, -2, -14, 0, -4, -1, -1, -1,
- 1, -3, 0, -2, -1, -4, 4, 5, -1, 5, -1, 3, 3, 5, -3, 5,
- -3, 5, 5, 6, 4, -6, 2, -9, 4, -4, 0, 1, -2, -1, -8, -6,
- -11, -2, -3, 3, -6, -8, 3, -5, 1, -3, 1, -3, 1, 3, 5, 6,
- 2, 1, -6, 4, -1, 1, 0, 7, 7, 2, 3, -6, -4, -4, 3, 3,
- 0, 1, -1, -2, -4, 0, -8, -2, -3, 1, -2, 1, -5, -2, -1, -3,
- -3, -4, -3, 7, 4, 1, -1, -6, -5, -3, 2, 5, 8, 3, 3, 2,
- 1, -4, -1, -2, 6, 3, 2, -4, -1, 1, -5, -1, -1, -5, 2, -2,
- 1, -2, -7, -5, -11, -4, -3, 3, -8, 8, 4, -2, -2, -4, -4, -1,
- 4, 3, 5, 5, 2, 4, -1, 6, -3, 6, 2, 3, 0, -4, 0, -2,
- -2, 0, -5, -2, -1, 4, 3, 1, -13, -8, -8, -5, -3, 7, -2, 3,
- -2, -5, -3, -8, -2, -3, 8, 6, 1, -2, 5, 3, 1, 2, 0, -1,
- 2, 4, 3, -5, 1, -3, 0, 1, 7, 1, 2, 3, -1, -4, -4, -10,
- -7, 3, 0, 2, -5, -5, -4, -1, -7, -3, -3, 1, 3, 0, 0, -1,
- -6, 6, 1, 4, 1, 2, 5, 6, 4, -1, -4, -3, 1, 2, 5, 2,
- -1, 1, 3, -8, -1, -10, -2, -5, 0, -1, -6, -10, -7, 2, -2, 6,
- -1, -2, 1, 4, -1, -5, -1, -5, 4, 1, 4, 2, 1, 3, 4, 0,
- -2, 1, -1, 3, 8, 2, 1, -4, -3, -3, 3, -3, -1, -4, 0, -4,
- -6, -2, -8, 1, -2, 5, -6, -5, -6, 0, 3, 1, -6, -3, 1, 2,
- 4, 2, 4, -2, 3, 3, 3, 1, 5, 1, 2, 3, -2, -6, 6, -1,
- 6, -2, 1, -7, -5, -2, -3, -6, -6, -6, -4, 0, -2, -4, -4, -3,
- 0, -1, 1, -3, -1, 3, 1, 1, 0, 6, 4, 8, 10, 5, 0, -3,
- 1, -2, 5, 2, 1, 1, 1, -4, -6, -8, -8, -8, -5, -4, -5, -4,
- -5, 0, -5, -3, 0, -7, 0, 4, 1, -4, -1, -4, -2, 4, 4, 5,
- 6, 6, 7, 0, 0, -1, 0, 2, 9, 2, 1, -3, 0, 1, -3, 1,
- -9, -1, 3, -4, 3, -6, -7, -2, -1, -1, -1, 1, -9, 2, -5, 1,
- -8, -6, -6, 1, -1, 6, 0, 2, 5, 2, 0, 2, 1, 2, 6, 5,
- -2, -1, 0, 4, 1, 6, 0, -2, 1, 0, 3, -7, -1, -13, -4, -3,
- -3, -3, -2, -3, -5, -9, -11, -2, -3, 4, 7, -1, 2, 0, -2, 8,
- 5, 1, 4, 3, 2, 7, 3, -2, -4, 7, 2, 3, -2, 1, -1, 2,
- 0, -5, -4, -4, 0, -4, 0, -1, -10, -9, -3, -5, -8, 1, -5, 3,
- -3, 0, -7, 1, 0, 5, 4, 7, 1, 1, 0, 2, 2, -2, -1, 2,
- 1, 4, 6, -1, 4, 3, -1, 4, -2, -3, 3, -1, -2, -6, -6, -7,
- -3, -1, 0, -4, -6, -5, -6, 0, -3, 3, -5, 7, 0, -1, 1, -3,
- -1, 1, 6, 3, -3, 7, 1, 10, 1, 6, -1, -2, 5, 2, 1, 1,
- -4, -2, 0, -3, -7, -2, -4, 4, -8, -8, -4, -10, -2, 2, -4, 1,
- -5, -7, -1, 3, -1, 1, 1, 4, 6, 2, 2, 0, 4, 7, 0, 5,
- -2, 0, 3, 3, 3, -3, -1, -5, -2, 0, 3, -4, -6, 2, -1, 0,
- -2, -4, 0, -4, -3, -9, -3, -4, -4, 0, 3, -1, -4, 3, 1, 5,
- -2, 1, 2, 2, 4, 5, -3, 2, 1, 3, 7, 1, -5, 1, 0, 5,
- -3, -2, -3, -4, 0, -3, -2, -5, 0, -8, 3, -6, -4, -6, -2, 2,
- -4, -2, -3, -2, 1, 4, 2, 3, -2, 2, 4, 1, 4, -2, 3, 2,
- 1, 1, 7, -1, 2, 4, -4, 2, -4, -2, 5, -4, 3, -1, -3, -2,
- 3, -8, -4, -6, -3, -3, -1, 0, -6, -1, 0, 1, 1, -2, -10, -3,
- -1, 0, 2, -5, 1, 1, 2, 10, 8, 2, 8, -1, -2, 4, -5, 2,
- 2, 7, 6, -6, -1, -5, -4, -3, -6, -7, 0, -5, -5, -1, -2, -5,
- 0, -4, 6, -6, 0, 3, -3, 4, 0, -6, 2, 5, 5, 4, 10, 0,
- 2, -3, 3, -2, 0, 3, -3, 2, -3, -8, -8, -5, -1, -1, -1, 0,
- -5, -2, 0, -3, -4, -1, -5, -2, 5, 0, 5, -4, 4, -1, -1, 1,
- -3, 3, 9, 2, -1, 1, -6, -3, 7, 1, 3, -2, -4, 0, -1, 3,
- 1, -3, 4, 6, 0, 1, 2, -3, 0, 0, -5, -13, -4, -2, 1, 2,
- -3, -10, -4, -7, 1, -2, -2, -1, 0, 1, 1, -4, -1, 2, -2, 7,
- 1, -3, 0, 0, 4, 5, 2, 2, -1, 6, 9, 1, 3, 1, -5, 5,
- -6, -5, -2, -4, -2, 2, -7, -4, -11, -5, 3, -3, -6, -4, -6, 3,
- 3, -3, 2, 0, 1, -3, -1, -2, -4, 1, 10, 8, -2, 4, -3, 6,
- 6, 1, 0, -7, 2, -2, 1, 3, -4, -4, 4, 1, 0, -2, -5, 2,
- -2, 0, -7, -11, -5, -2, -2, 5, -1, -8, -1, -1, 1, 2, -2, -1,
- 1, 1, 5, 0, -3, 5, 1, 6, 1, -1, 3, 1, 6, -3, -1, -1,
- -3, 4, 12, -1, -1, 2, -4, -1, -6, -8, -7, -3, -2, 1, -9, -5,
- -6, -10, 5, 1, -2, -3, -2, 5, 4, 3, -1, -5, 4, 6, 3, 4,
- 6, -2, 7, 0, -4, -1, -1, 9, 8, 2, 2, -8, -3, -3, 0, -2,
- 0, -4, -2, 0, -6, -7, -14, -6, -5, -1, 3, -6, -2, 1, -3, 0,
- -4, -5, 1, 5, 9, 4, 0, 3, 0, 1, 12, 0, 4, 8, 5, 7,
- -1, -4, 0, -3, 5, 4, -4, 0, -3, -13, -2, -10, -14, -3, -5, 2,
- 1, -3, -4, -8, -8, -3, -2, -2, 3, 4, 8, 0, 2, 1, 2, 12,
- 5, 3, 8, 2, 6, 3, -4, -4, -2, -8, 8, -5, -2, -6, -10, -2,
- -6, -4, 0, -4, 2, 5, 1, 0, -4, -4, -1, -1, -3, 4, -7, 4,
- 3, -3, 4, -4, -3, 8, 4, 7, 0, 0, 2, -1, -2, -1, -2, -7,
- 11, -1, 5, -4, 2, -2, 0, 2, -2, -4, -2, 1, -5, 3, -6, -9,
- -3, -3, -2, -5, -5, -2, -6, -2, -7, -8, 1, 3, 5, 9, 4, 4,
- 0, 5, 8, 1, 3, 7, 5, 10, 11, -7, 3, 0, -3, 1, -1, -7,
- -7, -3, -2, -6, -9, -6, -12, -4, -1, 0, -8, -5, -3, -3, -2, 3,
- 1, 1, 9, 4, 2, 5, -1, 2, 6, 2, 0, -3, 2, 2, 5, 2,
- -1, -4, 4, 1, 1, 2, -5, -8, -1, -3, -1, -9, -4, 1, -4, 5,
- -6, -4, 0, 3, -9, 3, -3, -5, 1, 4, 4, 1, -4, 1, -4, 4,
- 1, -6, 0, 5, 7, 8, 1, 6, 0, 3, 4, 2, -3, 1, -3, -3,
- 3, -9, -6, -7, -2, -1, -3, -5, -6, -5, -5, -6, -5, 4, -3, 5,
- 5, -2, -1, -1, -3, 6, -2, 5, 6, 2, 11, 8, -1, 3, -6, -2,
- 5, 4, -3, -3, -5, -3, -7, -5, 0, -5, 2, 1, 0, 1, -7, 0,
- -3, -2, -1, -2, -5, 7, -4, -2, -3, -2, -3, 4, 4, 9, 0, 1,
- 1, -5, -3, -4, -4, 4, 3, 6, 0, -2, -2, -6, 4, 1, 1, -3,
- 3, -1, 2, 0, -7, 0, 0, -1, -3, -2, -1, -5, -2, -3, -8, -5,
- -5, -1, 5, 5, 2, 2, -3, 4, 3, 3, 6, 3, -1, 10, -4, -3,
- -2, -3, 0, -4, 0, -2, -2, 0, 1, -4, -2, -5, -9, 8, -2, -1,
- -1, -3, -3, -2, -6, 2, 1, 2, 9, 0, 1, 3, -4, 2, 4, -6,
- -1, 2, -1, 6, 3, 0, -5, -3, -1, 0, 3, -3, 0, -6, -2, -3,
- -4, -2, 0, 3, 2, 2, 0, -10, 1, -6, -5, -1, -2, 5, 3, 6,
- -2, -6, -1, -3, 2, -1, 0, 0, -1, 0, 0, 0, 1, -2, 2, -2,
- -5, -1, -2, 16, 12, -18, -10, 3, -14, -10, 16, -1, -3, -16, 28, 3,
- -1, -1, 12, -5, -6, 6, 7, -7, -18, -28, 11, 0, 6, -2, 26, -21,
- -10, -1, 24, -3, 20, -19, 15, -14, -3, -3, 15, -35, -2, 6, -14, 30,
- 6, -36, -8, 17, 0, -27, 26, 16, -38, 8, -14, 57, 3, -31, -14, 34,
- -20, 33, 2, -6, -7, -28, 20, -24, 8, 13, 8, -39, 17, 40, -42, -11,
- 13, -46, 1, 28, -22, 11, -3, -14, 5, 20, -12, -4, 49, -22, -24, 39,
- -11, -1, -9, 37, -30, 13, 34, 4, -11, -25, 18, -22, 1, 29, -17, -3,
- -26, -16, -21, 12, -18, 7, -17, -6, 51, 0, -21, 10, 24, -45, 8, 14,
- 31, -10, -37, 6, 0, 24, 3, -18, -13, 14, 11, 0, 7, -1, -38, -29,
- -21, 32, -30, 22, -26, 14, -40, 55, -36, 30, -12, 8, 31, -16, 19, -15,
- 23, -48, 36, 1, 63, 3, 24, 0, -3, 14, 26, -21, 15, 47, -21, -80,
- 14, -4, -25, -33, 11, 25, -35, -44, 13, -2, -48, -11, -23, -7, 27, -4,
- -15, -22, 5, 26, -36, 50, 23, 11, -23, -14, 19, 32, 14, 38, -66, 56,
- -11, 26, 18, -12, 17, -30, -6, -54, 22, 77, -62, -12, -16, 34, -25, 2,
- 14, -62, 12, 20, -22, -50, 58, -29, -58, 4, 28, 30, 13, 25, -78, 38,
- 45, -19, -7, 52, -61, 27, 17, -21, -4, 6, 37, -24, -38, 73, 8, -16,
- 21, -2, -15, -19, -19, 18, 3, 7, -48, -10, -10, 10, 4, 13, -13, -4,
- 0, 46, -12, 6, -18, -25, 4, 14, 27, -22, -37, 14, -6, -17, 55, 40,
- -111, 63, 9, -38, -16, 46, -35, 4, 0, -10, -8, -12, 58, -69, 1, 66,
- -38, 21, -33, -6, 10, 0, 10, -11, 18, -16, 32, -7, -10, -25, 65, -42,
- 42, -62, 18, -3, -2, -8, 21, 4, -71, 13, 40, -3, 18, -19, -29, 15,
- -66, 60, -50, -6, 67, -80, 17, 66, -21, -20, -15, 68, -16, 72, -4, -23,
- 4, 53, -8, 8, -4, 0, 27, -26, -22, 25, -31, 7, -39, -18, 27, -43,
- -25, -33, -6, 17, -16, 0, -55, 6, 26, -3, -67, 7, 60, -83, 25, 15,
- 45, -8, 51, -55, 28, 42, 42, -17, 37, -6, 17, 8, 11, -1, 59, -7,
- -45, 14, -41, 107, -49, -50, -25, 63, -58, -27, -57, 19, 13, -13, -27, 19,
- -42, 63, -113, -1, 44, 8, 1, -10, -33, 0, 55, -41, 15, 0, 76, -17,
- -39, 60, -20, 28, 54, -93, 15, 83, -30, 4, -56, 49, -58, 30, -28, 2,
- 54, -64, 83, -128, 86, 24, -40, -27, -66, 51, 11, -51, 59, 6, 20, -58,
- -24, 78, -7, -23, -27, 1, -3, -24, 10, -6, -16, 34, 39, -37, -17, 26,
- 52, -69, -7, 11, 24, -62, 38, -13, 41, 5, -2, -5, -12, 15, 77, -49,
- -10, 74, -12, -11, -38, 32, -24, 25, -6, 19, -24, -2, -38, 63, -91, 64,
- -27, -11, -56, -43, 27, -41, -55, -15, 1, -4, 27, 8, 37, -57, 3, 28,
- -11, -4, 46, -39, 3, 12, 100, -33, 39, 17, 6, 49, 5, 38, -12, 10,
- 21, -35, 23, -6, -36, 10, -9, 3, -1, 13, -65, -40, 36, -25, -28, 5,
- -37, -20, -14, 31, -16, -32, -16, 4, 15, -11, 26, -16, 29, -42, 46, 7,
- 39, -1, -5, -9, 33, -31, 35, -33, -7, 17, 56, -24, 22, 14, -22, -34,
- 44, 16, 11, -46, 43, -48, -27, 43, 36, -45, 21, 11, 0, -98, -22, 87,
- -126, 52, -45, 34, -28, -17, -31, 23, -38, 23, 25, -11, 25, -63, 21, 13,
- 19, 47, 28, -23, 20, 21, -5, -14, 112, -30, -67, 37, 43, -12, -57, 34,
- -9, -29, 52, -19, 14, -51, 0, 26, -69, 3, -18, -24, -34, 31, -15, -33,
- -36, 10, -20, -38, 63, 0, 44, -50, 72, 25, -16, -6, 6, 15, 23, 31,
- 3, -20, -9, 19, 63, 17, -18, -5, -12, -87, 31, 26, -37, -29, 49, -42,
- -15, 14, 11, -16, -31, 46, -19, -13, -37, 59, -91, 47, 4, -11, -26, 39,
- -29, -24, 48, 10, 39, -11, 45, -51, -1, -24, 47, -19, 39, -34, -29, -17,
- 1, 56, -25, -16, -13, 0, 48, -71, 49, 2, -2, -45, -10, 59, -17, -25,
- 9, 9, 44, 42, -32, -23, -49, 46, -11, -50, 76, -43, -45, -1, 41, -8,
- 2, 71, -36, -61, 35, 21, -13, -36, 44, -45, 26, -45, -21, 28, -37, 39,
- -29, 15, 4, -5, 24, -7, 7, 3, 68, -80, 26, 24, -22, 8, 26, 28,
- 10, -26, -3, 16, -51, 85, -8, -14, -54, 39, -28, -9, -25, 46, -39, -20,
- 34, 11, -25, -7, -12, -41, 12, -17, -5, -43, -8, 0, 18, 13, 9, 28,
- -40, 34, 0, 13, 40, -20, 5, 22, -25, -13, 51, 9, -34, 43, -16, -18,
- 2, 35, -4, -28, 14, -37, 6, -8, 31, -49, 9, -31, 61, -55, 35, -46,
- -37, -12, 32, 74, -59, -30, -21, 5, 38, 3, 48, -35, -42, 2, 29, 81,
- -8, -37, 24, 42, -31, 18, -11, -21, -67, 98, -18, 11, -26, -14, -76, 11,
- 71, -70, 30, -52, 37, -45, 61, 6, -33, -44, 58, 24, -16, -51, 49, -28,
- 51, -6, -15, 46, 10, -24, 36, -4, 6, -30, 46, -66, 54, 27, -16, -34,
- -23, 90, -61, -49, 22, -3, -22, 17, -35, -11, -59, 23, 2, -25, 69, -24,
- -26, -28, 37, 12, 11, -63, 27, 18, 3, 34, -25, 9, -14, 29, 4, 24,
- 21, -77, 12, 14, 37, 1, 45, -63, 1, 49, -14, -23, -7, -4, -42, 48,
- -57, 18, -36, 17, 15, -37, 47, 1, -41, -14, 11, 49, -32, 32, -36, -19,
- 21, -11, 39, -31, 43, 0, -24, 15, 6, 9, -46, 5, 21, -23, 2, -28,
- -15, 59, -13, -29, 50, -7, -45, -12, 23, -1, 27, 6, -17, 7, -4, -3,
- -3, 53, -10, 17, -52, 19, 24, -8, -7, 19, -51, -30, 55, -22, -22, 29,
- -38, -25, 39, 3, 34, -84, 26, -37, 42, 15, 4, -4, -16, -33, 29, 17,
- 43, -93, 24, -6, -20, -14, 107, -29, -36, 69, -21, 10, -7, 74, -67, 38,
- -23, -8, 27, -35, -49, 29, -8, -4, 7, -8, 5, -38, -28, -33, 22, 70,
- -37, -10, -56, 26, 5, 7, 59, -21, -58, 10, -2, 6, 49, -16, -9, -38,
- 60, 13, 43, -43, 23, -14, -9, 38, 17, -38, -15, 29, 6, -5, -11, -3,
- -4, -65, 45, -13, 26, -13, -4, -5, -38, 48, 0, 4, -40, 40, -48, 23,
- 21, 23, -42, 5, -17, 13, -9, 12, -3, 5, -25, 34, -24, -3, -18, 16,
- -44, 13, 27, -30, 44, -54, 6, -18, -3, 4, 21, -25, -13, 22, -20, -12,
- 37, -10, -10, 5, 24, -17, 23, 9, 0, 4, 3, 12, 26, -27, 17, 9,
- -41, 69, -1, 15, -37, 15, -6, 0, -1, 3, -13, -23, -18, 27, -5, 21,
- -16, -41, -2, 20, 13, -27, 6, -21, 8, 6, 0, 6, -5, -21, -22, 73,
- -40, 4, 6, 21, -8, -5, 29, -47, -1, 1, 19, 3, -10, -1, 2, -48,
- -11, 45, -27, 11, -33, -21, 21, 7, 12, -22, 21, -40, 13, 27, -20, 37,
- 5, -18, -18, 35, 40, -11, 20, -25, 10, -4, 33, 12, -29, 9, -20, -30,
- 34, 24, -9, -10, -24, -16, 8, 22, 6, -58, -5, -13, 18, 5, -43, 10,
- -16, -25, 13, 70, -25, -7, -25, -19, 16, 58, -46, -5, 6, -5, 40, -24,
- 22, 50, -73, -7, 7, 32, 39, -27, -23, -23, 56, -35, 21, 17, -40, 40,
- -52, 4, 0, 49, -29, -42, 24, 9, 31, 2, -46, 0, -9, -5, 9, -31,
- 64, -5, -45, -26, 42, -4, -34, -8, -3, 32, -15, -8, 22, -24, 13, -31,
- -2, 31, 10, -10, -18, 8, 24, 20, -29, 2, 14, 23, 25, -4, -19, 20,
- -25, -5, -3, 23, -8, 52, -42, -17, -7, 29, -26, 2, -19, 55, -50, -28,
- 1, -10, -7, 7, -41, 16, 21, 1, -20, 0, 16, -19, 14, -39, 86, -17,
- -34, -64, 73, 0, 20, -28, 30, -22, 9, 58, -4, -8, -18, -20, 31, -21,
- 1, 26, -49, 5, 41, -25, -13, -6, -7, 6, 10, 42, -30, -26, -43, 11,
- 44, -54, 31, -10, -11, -17, 25, 32, -43, 64, -23, 3, -37, 33, -30, -4,
- -35, 47, -29, 9, 23, -34, -5, 64, -37, 32, -11, -44, 21, 25, -19, 8,
- 6, -25, 34, 2, -18, -23, 38, 20, 7, 21, 1, -32, -37, 50, -9, -25,
- 34, -61, 55, -32, 7, -48, 20, 13, 0, -35, 17, 9, -42, -28, 14, 42,
- -33, -25, -5, 21, 41, -60, 32, -7, 38, -9, -3, 20, -4, 29, -69, 62,
- -16, 35, -64, 45, 10, 5, -1, -18, -18, -1, 5, 32, 0, -21, -12, -23,
- 29, -15, 13, -39, -3, -3, 6, 35, -24, -23, -7, -2, 44, -10, -37, 25,
- 25, -25, -23, 7, 40, 4, -40, -18, 21, -2, -3, 1, -16, 45, -26, -2,
- -16, 18, 41, -64, 8, -26, 40, 5, -32, 8, 18, -1, 15, -1, 9, 2,
- 2, -13, -12, 35, -9, 13, -62, -29, 72, 18, 7, -30, 26, -7, -29, 39,
- -38, 31, -56, -25, -3, 17, 2, -3, -46, 35, 6, 27, -39, -3, 3, 31,
- -25, -19, -2, 38, 26, -77, 22, 18, 40, 3, -22, 65, -48, 33, -16, -37,
- 78, -34, 1, -52, 23, 16, 1, -37, 17, 12, 1, -4, 8, -27, -1, -11,
- -18, 27, -23, -10, -11, -19, -6, -7, 51, -74, 16, 20, 17, -14, 7, 7,
- -13, -8, -5, -11, 39, 21, -5, -44, 31, 64, -38, -18, 20, 40, -4, -10,
- 10, -23, 23, -6, -20, 11, 9, 10, 6, -23, -11, 1, 17, -56, 56, -40,
- 0, -17, -60, 84, -80, 16, -13, 4, -25, 12, 17, -42, -26, 54, -29, 12,
- -5, 37, 16, -62, 94, -5, -2, -2, -2, -9, 5, 51, -25, -5, -11, 5,
- 16, -14, -9, 43, -44, -8, 27, 2, -1, 9, -18, -6, 5, 23, -46, -9,
- 13, 16, -10, -10, -23, 59, -47, -14, 23, 29, -15, -14, -30, 21, -21, 0,
- 14, -3, 25, -16, -35, -2, -8, 32, -19, 22, -23, -37, 30, -33, -19, 11,
- 12, -32, 47, -4, 27, 11, 9, -35, 39, 29, -18, -2, -11, 27, -2, 13,
- 0, 18, -26, 15, -25, 26, -4, 21, -29, -33, 18, -8, -31, -5, 21, -1,
- -38, -28, 41, -18, -4, -22, 47, -12, -44, 55, -79, -5, 19, -10, 25, 4,
- 21, 15, -28, 13, -6, 45, -24, 25, 10, -26, 4, 2, 31, 3, -7, 3,
- 5, -23, 51, -9, -32, -5, 35, -32, -21, -20, 35, -40, -10, 20, -8, 7,
- -5, -38, -1, -24, 39, -26, 20, -16, -9, -27, 25, 34, -32, 1, 12, -13,
- 3, 37, 13, 3, -31, 27, 30, 5, -15, -21, 2, 10, -13, 16, 36, -9,
- -59, 41, -10, 61, -60, -35, -11, 7, 5, -28, 30, 5, -23, -66, 34, 50,
- -26, -19, -10, 11, 8, 8, -35, -5, -11, 56, -24, 10, 35, 16, -10, -19,
- 30, 4, -11, 23, 0, -6, 6, 36, -15, 0, 15, -14, -26, -8, -5, 15,
- -31, -45, 42, -30, 0, -9, 6, -22, 9, -22, 7, -8, 15, -19, -3, -13,
- 29, -14, 9, -16, 3, -5, -10, 63, 0, 4, 4, 20, 16, -21, 18, 31,
- -24, -19, 31, 54, -39, -7, -16, 5, -3, 0, -29, 16, 6, -29, -25, -52,
- 49, -9, -66, -3, 50, -3, -2, -14, 4, -8, 33, -40, 2, 15, -6, -17,
- -4, 10, 48, -16, 14, -9, 27, 10, 2, 2, 40, -35, 5, -10, 7, 28,
- 1, 4, -30, -4, 0, 1, -14, -13, -11, 26, -17, 13, -44, -9, -6, -23,
- 17, 11, 11, -21, -11, 0, 9, 8, 8, -30, 29, 10, -26, -12, 15, 17,
- 4, -26, 14, 19, 20, -9, -24, 39, 23, -10, -35, 8, -6, 18, -25, 15,
- -17, 41, -48, -31, -5, 47, -14, -20, -4, -7, 5, -19, 3, 21, 12, -23,
- 15, -24, 8, 3, -25, 2, 28, 14, 21, 25, -72, 15, 26, -6, 45, -27,
- 29, -30, -17, 23, 6, -2, 27, -46, 13, 9, 15, -57, 27, 1, -18, 1,
- -11, -2, -20, -16, -23, 24, 18, -21, -5, -15, -14, 26, -12, 30, -48, 37,
- -24, -3, 23, 9, -5, 9, 8, -43, 23, 26, 6, 28, -29, 30, -8, -12,
- 25, -18, 33, -48, -4, 29, 1, -8, -4, -20, 41, -22, 1, 12, -33, 0,
- -17, -16, 29, -3, -2, -36, 6, -1, -11, 4, -24, 40, -24, -5, 26, -2,
- -28, 13, -11, 35, -9, -2, -3, -6, 13, 10, 1, 11, -22, 22, -27, -5,
- 20, 11, -1, 8, -23, 8, 7, -7, 17, -6, 16, -9, -10, 3, 13, -3,
- -17, 19, -21, 6, -13, -15, -7, 22, -15, -7, 11, -20, -19, -6, 0, 28,
- -10, -7, -13, 9, 7, 1, -11, -6, 21, -33, -4, 52, -11, -1, -2, -2,
- -4, 32, 17, -31, 7, 12, 2, -5, 11, -1, -6, 1, 3, -11, 5, 4,
- -15, -8, 10, 5, -18, 5, -26, -11, 22, -15, -23, 22, 19, -30, 3, 1,
- -5, 10, -17, 10, -2, 10, 7, -17, -5, 36, -12, -24, 27, 22, -3, -11,
- -6, -7, 20, 5, -21, 0, 23, -31, -27, 14, 2, 8, 7, -15, 0, 13,
- -7, -3, -21, 33, -4, -26, 7, 5, -7, -7, 1, 3, 4, 11, -24, 6,
- 11, -7, 14, -9, -11, -1, 34, -22, 11, 1, -18, 17, 4, -19, 28, -15,
- -7, -11, 12, 1, -7, -9, -12, 17, -20, 6, 5, 2, -10, 12, -23, -3,
- 26, -1, 4, 6, -25, 12, -3, -26, 2, 15, 14, -18, -6, -17, 14, 4,
- -10, 21, -13, 5, -15, -20, 27, 6, 8, -11, 18, 15, -34, 17, -2, -13,
- 41, -9, -10, -6, -2, 7, -11, -4, 28, -26, -6, 25, 17, -36, -2, 33,
- -39, -15, 11, -2, 26, -32, -31, 21, 26, -11, -24, 12, -17, 4, -33, 24,
- 14, -10, 12, -19, -3, 28, 11, -8, 0, 26, -17, -7, 8, -6, 20, 26,
- -29, -27, 25, -14, -2, 10, -16, 39, -24, -17, -4, -13, 24, -10, -3, -20,
- 25, -1, -24, 24, -20, -5, 21, -26, 7, 21, -26, 15, 17, 6, -34, 5,
- 11, -27, 20, 17, -13, -8, -16, 9, 33, -36, 19, 5, 4, -2, -33, -12,
- 38, -17, -10, -4, 19, 14, -4, -32, -41, 64, 5, -38, 28, 6, -2, -11,
- -22, 11, 17, 17, -24, 23, -7, 9, 10, -38, 0, 25, -9, -6, -27, 20,
- 2, -27, 34, -23, 17, -22, 4, 12, -43, 29, -8, 25, -19, 13, -17, -11,
- 27, -8, 14, -19, 12, 9, -22, -6, 11, -10, 17, -4, 2, -3, 15, -47,
- 32, -18, 11, 14, 0, 8, -33, -14, -12, 23, 17, -12, -4, 13, -27, 10,
- -17, 20, -2, -11, -11, 27, 18, -21, -6, 26, -18, 9, -7, 27, -12, 3,
- -9, -9, 22, 7, -38, -2, 14, -16, 12, -21, -10, 22, 1, -28, 20, 31,
- -11, -49, 9, 16, -4, -7, -4, -5, 46, -39, 9, -18, 16, 22, -24, -13,
- 14, 29, -10, 3, -23, 4, 11, -33, 30, 18, -9, 5, -11, 4, -20, 30,
- -9, -14, -7, -9, 4, 0, 4, -15, -11, 23, 5, -24, 26, -6, -8, -17,
- 21, 0, 3, 13, -10, -13, 19, -16, -10, -5, 10, 8, 22, -19, 4, -8,
- 0, -24, 38, 12, -33, 10, -9, 5, -13, 11, 3, 7, -18, -12, 11, -4,
- 8, -17, -7, 16, -9, -2, -9, 0, 10, -2, -1, -1, 12, -6, 13, -18,
- 18, -6, 10, 1, -3, 9, -2, -30, 23, -9, 29, -11, -31, 10, 6, -21,
- -19, 54, -30, 18, -12, -26, 23, -10, -31, 23, -5, 49, -34, 4, -18, 3,
- 11, -24, 27, 12, -24, 3, -13, 3, 16, -6, -7, 1, 19, -8, -3, -11,
- 13, -14, 19, 10, 17, -21, 14, -40, 12, 13, -5, -3, 21, -14, -29, 16,
- -24, 1, 10, -1, -3, 6, -15, -16, 16, -4, 2, 23, -32, -1, 7, -5,
- 13, 4, -15, 33, 1, -7, -7, -12, 13, 6, -8, 2, 21, 2, -21, 17,
- -14, -19, 36, -2, -16, -4, 3, 9, 15, -39, 3, 9, -10, -3, -12, -7,
- 28, -19, 8, -18, 22, -18, -11, -2, 17, 23, -15, -24, 11, 13, -14, -10,
- 9, 4, 14, -10, -13, 13, -3, -12, 25, 6, -12, 12, -19, -3, 19, -10,
- -13, 19, 10, 18, -31, -15, 19, -9, -14, -6, 25, -18, 2, 17, -41, 11,
- 16, -20, 3, -10, 16, 9, 14, -27, -1, -3, 9, -19, 36, -6, -4, -4,
- -16, 5, -7, 24, -1, -30, 13, -8, -4, -9, 47, -37, 3, 21, -24, 1,
- 3, 11, 5, -10, -8, 20, -31, 16, 10, -1, 0, -9, -1, -6, 14, -6,
- 6, -17, 20, 3, -23, 10, -14, 17, -16, -2, 26, 7, -20, -10, 9, -18,
- 31, -35, 3, 14, -8, 13, -27, -4, -4, 26, -20, -9, 14, 22, -27, -4,
- 18, 9, 9, 3, -13, -20, 15, -13, 6, 12, -5, -6, -12, 0, 4, -10,
- 18, -7, -8, -15, 1, -11, 17, 5, -11, 14, -6, -11, 4, 10, -5, 13,
- 0, -7, 15, -2, -16, 2, -3, 9, -6, 2, 34, -11, -17, -8, 21, 13,
- -21, -4, 14, -7, -7, -19, 13, -7, 4, -25, 7, 16, -14, -40, -11, 36,
- 3, -10, 4, -10, 7, -1, -1, 4, 14, 6, -14, -14, 17, 23, -13, -2,
- -1, -12, 9, 8, 1, -7, 22, -29, 7, 7, 0, -24, 13, -10, 18, -1,
- -3, 13, -24, 30, -32, -5, 18, -2, -6, -8, 11, -18, -12, 17, -11, 0,
- 5, -4, -14, 31, -15, -16, 13, 12, -4, 4, -4, -1, -11, -15, 26, -18,
- 29, -15, -3, -8, 6, 6, -34, 22, 0, 11, -18, 16, 20, -19, -21, -5,
- 11, 21, 10, 10, -27, -5, 3, 2, -5, 9, -9, -1, 1, -11, -3, 8,
- 4, 1, -1, -11, 19, -1, -21, -5, -2, 11, -2, -8, 10, -7, -1, 2,
- -18, 3, 0, 7, 2, 7, 1, 1, -28, -14, 10, 19, 12, -21, 7, -19,
- 20, -2, -3, -1, 17, -11, -13, -16, 32, 4, -5, -3, 4, -4, 18, -2,
- -17, -6, 16, -3, 4, -12, 4, -2, 2, 6, -18, 20, -24, 17, -10, 19,
- -16, -17, 8, -7, -5, 16, -12, -18, 11, 9, 2, -8, 17, -9, -3, -13,
- 7, -6, 30, -15, -11, 5, 14, -2, -15, -5, 14, 13, -12, -24, -10, 22,
- -2, -8, -1, 21, -5, -19, -16, 8, 42, -6, -27, -12, 23, 10, -17, -14,
- 16, 14, -16, -2, 9, -2, 16, -9, -31, 22, 0, -2, 3, 4, -5, 20,
- -24, -5, 13, -1, -5, -10, -6, 8, -11, 2, 8, -8, -5, -9, 1, -6,
- 16, -1, -18, 4, 9, -3, 6, -4, 6, 9, -7, -9, -1, 10, -7, 4,
- 3, -3, 4, -8, -5, 3, -4, 10, 6, -15, 2, 3, -5, -2, -3, -12,
- 18, 2, -16, 7, 13, 0, -19, -8, 11, -6, -1, -9, 5, 13, -8, -6,
- 6, 7, 11, -11, -6, 13, -2, -5, -1, 9, -2, -7, -15, 10, 5, -1,
- -13, 8, 0, -6, -2, -2, 18, -16, -7, 2, 3, -4, 6, -11, 4, 6,
- 1, -5, 22, -11, -5, -6, -3, 11, -1, -1, 4, 1, -4, -13, -4, 11,
- -9, 1, 9, -1, -8, 1, -5, -7, 5, -14, 18, -1, -12, 11, -12, 16,
- -5, -11, 11, -2, 15, -7, -18, -10, 0, 18, -12, 8, 3, 6, -16, -3,
- 3, 6, 0, -1, -3, 4, 9, 3, -17, -7, 11, 11, -19, 5, 15, -12,
- -3, -12, 4, 11, -19, 0, 0, -14, 21, -15, 2, 8, 3, 8, -8, 5,
- -18, 9, -2, -8, 23, -5, -16, 5, 3, -20, 13, 11, -6, -15, 5, 4,
- -12, 2, 10, -5, -12, 5, -14, -2, 18, 11, -14, 0, 28, -10, -20, 4,
- 7, 9, -13, -6, 15, 11, -9, -6, 14, -8, 10, 4, -12, 11, -18, 13,
- -17, -9, 16, -4, -14, -7, 17, -24, -5, 4, 6, -6, 14, 2, -24, -22,
- 11, 13, 8, -16, 6, 13, -28, 10, -2, 11, 8, -1, -8, -14, 22, 3,
- -5, -13, 18, 7, -26, 15, 20, -6, -10, 4, 11, 5, -8, -3, -5, 0,
- -1, -6, 0, 4, 4, -14, -1, 1, 8, -14, -10, -4, 6, 4, -8, 3,
- -9, 0, 11, -4, -7, 5, 4, 6, -29, 18, 22, -19, -16, -11, 17, 7,
- -4, 3, -23, 20, 8, -19, 3, 13, 13, -16, -18, 15, -6, 0, 3, 17,
- -7, -4, 2, -22, 21, -1, -2, -1, -15, 13, 3, -7, 4, 0, -7, 8,
- -7, 11, 3, -2, -8, 10, -15, 0, 9, -14, -8, 8, -2, -9, 10, -13,
- 9, 7, -6, 2, -12, -4, 6, -12, 8, 12, 3, -10, 6, 7, 1, -2,
- -11, -1, 7, -7, 8, -13, -10, 11, -9, -10, -8, 20, 9, -11, 8, -5,
- -4, 6, -3, 5, 13, -13, -7, -7, 6, 19, 0, -9, 9, -1, -3, 4,
- -7, 0, -2, -4, -5, 5, 0, -5, 14, -19, -14, 18, -1, -5, 3, -12,
- 18, -19, 4, -15, -10, 10, 10, -17, -4, 19, -6, -2, 5, 11, -4, -3,
- 9, -22, 28, -6, -5, 0, -1, 11, -11, -13, 22, 3, -8, -9, 1, 3,
- 0, 1, 2, 7, -5, -25, 10, 6, 6, 2, -11, 8, -16, 15, -20, 5,
- 9, -6, -13, -5, 14, 6, -21, 22, -7, -14, 4, 26, -8, -13, 8, 1,
- -10, -13, 11, 10, -10, 2, -13, -9, 15, 0, 10, -30, 14, 7, -13, -5,
- -12, 8, 10, -4, 10, 12, -15, -7, 5, 2, 2, 10, -13, -3, 0, 21,
- -2, -16, 9, 3, -1, 6, 15, -3, -21, 10, -8, 5, 1, 1, 2, -19,
- 10, -7, -3, -1, 8, 6, -26, -10, 18, -28, -3, -3, 4, 0, -7, 6,
- -10, -2, 25, -19, 5, -11, -2, 14, 4, -5, -3, 4, -5, 6, -2, -3,
- 11, -1, 13, -12, 5, 20, -15, -3, 17, 4, -14, -5, 11, 3, 1, 6,
- 11, -20, 10, -4, -4, -4, -4, -18, -7, 5, 10, -25, 7, -9, -15, 1,
- -4, 4, 4, -4, -1, -18, 9, -6, 4, 7, -19, 10, 0, 3, -6, 12,
- 18, -5, 2, 4, -4, 11, 2, 5, 2, 1, 3, -4, 3, 4, -3, -2,
- -8, 11, 5, -10, -12, 12, -6, 6, -9, -6, 4, 9, 0, -9, 4, 3,
- -7, -5, -12, 19, 2, -28, 1, 0, 9, -10, -6, 3, 3, -11, -4, 6,
- 7, -7, -3, 5, -12, 9, 10, -12, 7, 5, 5, -6, -9, 16, 6, -16,
- 3, 8, -17, 12, -5, 2, 1, 21, -25, -10, 5, -2, 15, -6, 1, 3,
- 5, -16, -2, -16, 32, -17, 7, -13, 6, -1, -4, 0, -4, 10, -2, -17,
- -7, 29, 0, -13, -1, -1, 2, 12, -4, 3, -2, 4, -19, -1, 18, 2,
- -3, -15, -2, 10, -4, 1, -2, -5, 20, -5, -6, -7, 9, 0, -2, -24,
- 5, 15, -2, -11, 1, 0, -2, -14, -2, -4, 7, 4, -4, -9, 2, 4,
- -8, 8, -1, 2, 10, -13, 4, 10, -4, 27, -22, 17, -18, -2, 5, 8,
- -1, 4, -6, 2, -1, 9, 1, -3, 16, -21, -18, 2, 10, -14, 9, 3,
- -14, -9, 0, -16, 9, -10, 11, -12, -3, 1, -10, 3, -2, 2, -13, 13,
- 10, -1, 4, 4, 1, -3, 9, 0, 4, 8, -14, 10, -4, 0, 8, 11,
- -2, 2, -11, 3, -13, -8, 11, 4, 1, -7, 4, -21, 0, 1, -4, -22,
- 17, -8, -16, 10, 4, -2, 0, -4, 2, -2, 2, -6, 10, 3, 3, 5,
- -1, 6, 5, 2, -6, -3, -2, 7, -4, -4, 12, 1, -30, 12, -7, 3,
- 4, -6, -7, -9, 9, -1, 7, -10, 12, -16, 2, -8, 23, -5, -5, -1,
- -8, 10, 3, -14, -12, 25, 7, -13, -6, 4, 15, -3, -23, 9, 12, -9,
- -13, 18, -9, 5, 1, -17, -4, 13, -10, 11, -10, -1, 6, 0, -7, -2,
- 9, -4, 9, -24, 7, 6, -5, 4, 15, -15, 11, -5, -24, 9, 11, -16,
- 2, 0, -9, -2, 10, 7, -12, 8, -12, -6, 10, 6, 10, -14, -5, 20,
- -16, 7, 8, -1, -19, 24, 2, -10, 15, 6, -6, -21, 3, -3, 15, -9,
- -3, 3, -2, -4, -3, -9, 5, 0, -5, -3, -15, -4, -1, 1, -14, 33,
- -12, -18, 9, -2, -10, 9, 9, -1, -1, -5, 10, -3, 2, 4, 2, -9,
- -1, 25, -2, -3, 15, -17, -7, 8, -7, 0, 10, -13, 9, -11, 0, -3,
- 18, -15, -11, 5, 0, -12, -2, 7, -6, -4, -9, 11, -6, 8, 1, -14,
- 3, 16, -10, -3, 2, 6, 4, 9, -9, -2, 0, 2, -3, 15, 3, -10,
- -4, -8, -1, 10, -13, -9, 16, -9, -3, -2, 5, -6, -6, -9, 10, 8,
- -4, 14, -7, -19, 12, 1, 2, 1, 4, -1, -6, -3, -3, 5, 7, -2,
- 0, 0, -5, 0, -6, 1, 6, -5, -4, 5, -6, 5, -4, -8, 15, -5,
- -7, 0, 3, -8, 0, 3, -8, -4, 6, -4, -4, 15, -5, -8, -7, 4,
- 7, -10, -6, 15, -4, -13, 7, 2, 2, 1, -4, 5, 0, 0, 1, 4,
- -7, 4, 4, -2, 4, 5, 1, -18, 12, 4, -3, -6, 11, 0, -13, -1,
- 1, -12, 3, 13, -9, -15, 7, 0, -4, -8, 0, 5, 0, -9, 1, 1,
- -3, 0, 3, 5, -10, 6, -1, -4, 4, 15, -15, -5, -9, 18, -2, 0,
- 15, -11, -9, 0, 6, -2, 8, 1, -8, -9, 7, 3, -7, -3, 6, 1,
- -5, 0, -5, -5, 0, -3, 11, 1, -3, -8, -4, -4, 5, 9, -6, -7,
- 4, 15, -13, 5, -4, 2, -6, -2, 0, 5, 4, -4, 0, -6, 8, 3,
- -2, -4, -4, -11, 4, 10, -1, -4, -2, -1, -3, 1, -4, -2, 3, 1,
- -4, -11, 12, -4, 5, -2, 7, -12, -2, 4, -4, 5, 8, 1, -8, 14,
- -11, -1, 1, 4, 0, 5, -5, 2, -7, -7, 10, 3, 1, -13, 0, -4,
- 5, -9, -1, 1, -11, -5, 5, 2, -6, 5, -5, -8, 12, -2, 7, -1,
- -10, -5, -7, 14, 9, 3, -5, -2, 5, 4, -2, 0, -5, 2, 3, 3,
- -12, 6, 3, 2, -9, -1, 24, -13, -9, -1, -2, 0, 7, -6, -17, 14,
- -12, -5, 10, 1, -4, -1, -1, 1, -3, 2, -2, -11, 1, -1, -1, 1,
- 10, -3, 2, 1, 5, -7, 1, -1, -5, 7, 1, 7, -4, 5, -11, -8,
- -8, 7, 8, 6, 0, -15, -1, 7, 0, -6, -3, 7, -4, -3, -2, 1,
- 5, 8, -6, -4, 11, 3, -14, -6, -3, -6, 9, -5, 4, -5, 2, 3,
- -13, -3, 1, -4, -3, 11, -1, 0, 7, -16, -6, 11, 5, 0, 4, 5,
- -2, -3, -2, 8, 7, -16, 1, 2, 6, 3, -17, 11, -2, -2, -9, 6,
- 0, -7, 6, -22, -2, 14, 3, -11, 0, -6, -2, -7, -7, 1, 4, 14,
- -1, -6, 0, 7, 3, -14, 4, 15, -4, -9, -2, 12, 14, -10, 5, 9,
- -11, -2, -9, 2, -9, 11, 2, -21, 7, 6, -11, -1, 0, 0, 1, -9,
- 4, 0, -10, 1, 3, -3, -7, 12, -9, -2, 4, 6, 3, -8, 0, 1,
- -2, -14, 12, 11, -5, 10, -3, -1, 3, -6, 1, 0, -3, 8, -1, -18,
- 12, 5, -13, -4, 17, -1, -6, 1, -11, 0, -6, 2, -2, -2, 5, 3,
- -17, 2, -5, 11, -4, 8, 8, -19, -6, 14, -6, -6, 0, 5, 0, -8,
- 7, 13, -6, -5, 6, -2, -9, -1, 8, 3, -4, -4, 10, -10, -9, 7,
- 2, -6, 14, 0, -15, 3, 5, -4, -10, 8, 0, -6, -11, 3, 10, -9,
- 1, 8, -7, 2, -1, -6, -8, 6, 2, -8, -2, 16, -3, -3, -1, 5,
- -3, -8, 6, 9, -6, 1, -1, -1, 2, -6, 6, -1, -9, 3, 9, -10,
- 1, 5, -4, -14, 2, 1, 7, -5, 3, -2, -13, 5, 10, -9, -8, 14,
- -6, -19, -3, 19, -3, -3, 6, -4, -10, 3, -1, -4, 5, 5, 1, 0,
- -1, 11, 4, -10, 3, -5, 4, -7, 1, 8, -3, 1, 2, 0, -10, 2,
- 5, -15, -3, 8, -8, -6, 5, -2, -5, -5, 11, 0, -12, -7, 5, 2,
- -5, 2, -1, -4, 2, 7, -12, 5, 6, -3, 5, -1, 12, 7, -13, -3,
- 0, 3, 0, 13, -1, -4, 0, -9, 5, -6, 5, -2, -10, -6, -2, 9,
- -8, 5, -6, -10, 5, 4, -6, -2, 1, 1, 6, -14, 10, -3, -4, -5,
- 1, 8, -16, 7, 7, -1, 0, 3, -5, 2, -1, -3, 11, -11, 9, 8,
- -18, 3, 8, 13, -4, -5, -9, 4, -2, -4, 9, 5, -6, -5, -15, -3,
- 17, -6, 2, -8, 4, 4, -4, -12, -3, -2, -2, -4, 5, -4, 1, 7,
- -12, -6, 8, 6, -2, 1, -3, 3, 10, -3, 7, -11, 12, 4, -1, -1,
- 1, 0, -11, 11, 4, 0, -2, -9, -2, -2, -8, -1, 5, -4, -5, -5,
- 1, 10, -8, -11, -5, -4, 5, -1, 1, 6, -2, -5, -5, 3, 6, -2,
- 6, -3, 0, 4, 5, 2, 4, -2, 1, 5, -2, -6, 11, -1, -5, 8,
- -14, 6, -2, -6, -11, 4, 2, -14, 6, -9, 5, -4, -3, 4, -12, -2,
- 2, -5, 4, 7, -5, 3, 6, -1, -3, -6, 0, 7, 0, 1, 6, 9,
- 4, -2, -7, -4, 7, 4, 4, -5, -5, 0, 3, -6, -1, 7, -2, -18,
- -1, 3, -15, 5, -2, -2, 0, 4, -10, -4, 3, 4, -10, 4, -1, 5,
- 4, -7, 8, -7, 0, 3, 2, -7, 13, 0, -2, -6, -6, 5, 10, -10,
- 4, -1, 2, -1, -5, 7, 5, -3, -7, 1, -5, 10, 1, -11, 7, 6,
- -10, -15, 12, 2, -4, 1, 0, -5, 3, 0, -2, 6, -5, -4, -13, -2,
- 3, 1, 4, 3, 3, -10, -7, -7, 11, -2, 2, 2, -7, 4, -1, 6,
- 2, 0, 8, 3, 0, -7, 8, 3, 5, -8, -3, -2, 2, 3, -12, -4,
- -3, 12, -12, -4, 7, -3, -10, -10, -4, 6, -2, -8, 9, 1, 1, 1,
- -3, -6, 12, -5, -6, -1, 11, -7, 5, 6, 2, 9, -11, 6, -2, 8,
- 1, -6, 4, 3, -6, -3, 5, -4, 4, 1, -19, -1, 3, 4, 0, 0,
- -10, -1, -3, -5, -3, 0, 11, -1, -12, -2, 6, 0, -3, 3, 4, -1,
- -7, 1, -2, -1, 2, -1, 0, 2, -2, 4, -5, -4, 11, -4, -5, -3,
- 7, 5, -8, 3, 6, -9, 0, 9, -5, -2, 5, -4, -6, 0, 7, -1,
- -2, 0, -1, -6, -9, -6, -1, 8, 4, -1, -9, -5, 13, 2, -11, -5,
- 9, 0, -8, -1, 5, -2, -5, -3, -2, 7, 5, -4, -13, 3, 11, -8,
- 3, 0, 2, 5, -12, -6, 6, 3, -4, -1, 8, 1, -5, -7, -6, 2,
- 8, 5, -2, -9, 7, -6, -2, 13, -7, 2, 1, -1, -5, 3, 7, -1,
- -11, 9, -6, -4, -2, -5, -1, 2, -1, 3, 8, -7, -1, -9, 0, 0,
- -1, 2, 5, -2, 1, -2, -3, 6, 6, -3, -6, -5, 4, -1, 1, 5,
- 1, -1, -2, -3, -4, 4, 3, 1, -7, 5, -1, 0, -8, -6, 1, 7,
- -3, -6, -2, 3, -1, -3, 2, 2, 0, -9, 1, -2, 4, 4, -5, 1,
- -1, 1, 6, -2, 2, -5, -4, -1, 14, -3, 2, -9, 1, -2, -4, 1,
- -1, 7, -9, 5, 2, -3, 2, -2, -9, -2, 4, -1, 2, -2, -2, 0,
- -1, -1, -2, 3, 1, -1, -3, -6, 3, 7, -5, -3, 9, -5, -4, -5,
- 8, -4, 2, 2, 8, -10, -1, 8, -14, 0, 6, -7, -1, 2, -3, 2,
- -4, 5, 2, -5, -4, 5, 1, -6, 3, 6, -4, -1, -3, 3, -7, 0,
- 1, 0, -4, 7, 6, -13, -3, 3, 2, -15, 8, 3, -3, -6, 9, -4,
- -1, 9, 1, -6, -6, 7, 1, 1, -2, 6, -1, -4, -1, -1, -7, 5,
- 3, 0, -5, -2, 8, -2, -8, 6, 7, -16, -5, 6, -6, -1, 1, 7,
- -4, -3, -6, 3, -10, -3, 8, -9, -1, 5, -1, -7, 5, 2, -1, 1,
- 5, 1, 2, -4, -5, 1, 1, 3, 1, -5, -2, 3, 2, -7, -1, 7,
- 5, -5, -7, 5, 0, 3, -1, -4, -4, 4, 0, -4, 1, 6, -3, -7,
- 0, -3, -3, -1, 0, -2, -4, 2, 1, -2, 3, -1, 0, -1, -6, 9,
- -5, 4, -1, -1, 4, -2, 5, -8, 2, -3, -2, 2, -3, 10, 2, -3,
- -5, 2, -4, -1, -3, -7, 9, 1, 0, 0, -5, 1, -2, -12, 6, 8,
- -18, 4, -1, 4, -1, 5, -5, -3, 3, -1, 4, -5, 9, -5, -4, -5,
- 2, 5, -1, -4, 0, -3, -2, 8, -5, 2, 1, -13, 3, 1, 4, 5,
- -8, 2, 8, 1, -1, 1, -9, 1, -2, -4, 1, 4, -3, 4, -4, -5,
- 6, 5, -6, -3, -3, 1, 1, -7, 1, 2, 1, -5, -4, -2, 2, -6,
- 6, 3, 7, -10, -9, 4, 1, -5, 6, 9, 3, 1, -2, -4, 3, 4,
- -1, -6, 3, 1, -2, -9, 4, 4, -5, 4, -10, 2, -4, -5, -1, 1,
- 2, 0, 2, -8, 1, 3, -4, -13, 0, 10, -1, -4, 5, 0, -4, 5,
- -3, 2, -5, 2, 1, 2, 4, 2, 2, -10, 5, 3, -11, -2, 3, 3,
- 0, -6, -2, 1, 1, 2, -1, -8, -1, -5, -4, -3, 5, 8, -4, -4,
- 2, 0, -2, -2, 1, -5, 0, 13, -8, -6, 4, 8, -6, -1, 6, -2,
- 4, -5, 3, 5, -7, -8, -2, -3, 7, 8, -8, -3, 1, 5, -5, -5,
- 9, -4, -7, -5, 4, 3, -6, 5, 1, -1, 3, 0, -6, -9, 0, -6,
- 1, 4, 10, 5, -13, 0, 6, -2, -4, 2, -2, 6, -1, -4, 0, -11,
- 6, 3, -1, -3, 14, -1, -15, 1, 2, 3, -1, 4, -3, -6, 0, 3,
- 0, -6, 10, -3, -14, -2, 10, -3, -9, -4, 0, 6, -1, 7, -3, -5,
- -6, 1, 0, -5, 11, -2, 1, -2, 5, -1, -4, -1, -3, -4, 2, 11,
- 2, -4, 1, 2, -12, 7, 3, -1, -11, 3, 15, -8, -11, 0, 0, 2,
- -7, 1, -3, -4, -3, -5, -4, 6, 11, -7, -8, -1, 6, -5, -3, 6,
- 8, 3, -6, 1, -1, -1, -1, -5, -3, 8, 7, 4, -9, 1, -2, -4,
- -6, 9, -4, 3, -8, 0, 6, -2, -4, -2, -2, -6, 8, -7, 3, 1,
- 3, -1, -3, 2, 1, -6, -9, 3, -5, 8, 5, -10, 7, 5, -3, -2,
- -1, -3, -1, -4, -7, 6, 6, 3, -7, 0, 0, 1, 0, -7, 3, -1,
- 0, 1, 2, 2, 2, -11, -8, 9, 6, 2, -6, -1, 1, -3, 3, 1,
- -6, 2, -3, -2, -1, 2, -4, 0, -4, -2, 0, -3, -2, -6, 5, 2,
- 0, -1, -3, -1, 3, 1, -2, 0, 2, 2, 0, 1, 7, 1, -4, -2,
- -6, 4, 3, -1, -4, -1, 3, 3, -9, -2, 0, -2, -1, -5, 6, 1,
- -5, 1, -5, 9, -10, -4, 0, -4, 6, 1, -3, -5, 9, -2, -5, 2,
- 0, 6, -6, 2, 5, 10, -8, -3, -2, -1, 4, -3, -1, -4, 0, -1,
- 1, -4, 0, 5, -8, -1, -5, -1, -1, 3, 3, 3, 2, -14, -5, 1,
- 2, 3, 1, -1, 2, 5, -2, 2, -5, 2, 3, -2, -2, -3, 4, 4,
- 4, -6, 3, 1, -10, 1, -6, 6, -2, -3, 0, -3, 1, -3, 1, -1,
- -4, -5, -4, 7, -2, -2, -3, 6, -5, -5, 2, -6, 1, 4, 3, -8,
- 11, 4, -4, -1, 2, 3, -5, -2, 1, 7, -4, 2, 4, -10, 7, -7,
- -1, 0, -3, 5, -4, -1, -4, 5, -7, 3, 3, -11, -2, -1, 5, 1,
- -1, 0, 6, -11, 0, 1, -2, 1, 0, -1, -4, 2, 9, -2, -9, -4,
- 2, 0, 2, -1, 1, 1, -7, 5, -3, 4, -1, -3, -8, 5, 7, -1,
- -1, -3, 3, -7, 0, 4, -3, -3, 1, 6, 0, -1, 0, -5, -1, 0,
- -4, 0, 0, -3, 1, -4, 1, 7, -3, -13, -2, -2, -1, 3, 5, 2,
- -6, 1, 6, -2, -6, 8, -1, -6, 0, 4, 6, -2, 0, -2, -4, 3,
- 5, -4, -7, 2, 5, -3, -3, 3, 1, -10, -7, 3, 1, -3, 2, 4,
- -7, -3, 0, 2, -5, -3, 3, -2, 0, 3, 5, -6, -1, 4, -2, 0,
- 5, 1, -2, -2, 3, 2, -1, -3, -3, -7, 7, 3, -1, -2, 0, 0,
- 1, -2, 1, 0, -15, -1, 3, 2, -3, 4, 0, -7, 0, -1, -1, -4,
- -3, 2, -1, -1, 11, -3, -1, -5, -1, 2, 2, 0, 1, 2, 3, 4,
- -6, -3, -2, 1, 0, -4, 2, 1, -1, -5, 1, -1, -7, 2, -2, -5,
- 0, 2, -2, 3, 5, 0, -2, -6, 6, -7, 3, -4, -6, 1, 6, 3,
- 1, -2, -3, -4, -6, -1, 7, -2, 0, -3, 0, 9, -3, -5, -1, 3,
- 0, -1, -3, 6, 1, -6, -3, 3, 6, 0, -6, -4, 2, 1, -1, 2,
- -5, 4, 1, -2, -5, 0, 7, -9, 3, -1, 1, -6, 0, -5, -1, 1,
- -1, 0, -4, 2, -2, -2, 1, 6, -1, -5, 0, 0, 0, 1, 3, 2,
- 2, -1, -3, 0, 1, 5, 1, -5, -7, 2, 6, -3, -3, -3, 2, -7,
- -5, 5, 0, 0, -3, -4, -1, 3, -4, -5, 1, 5, -1, -2, -4, 0,
- 5, 2, 0, 2, 2, -1, -1, -5, 5, 3, -1, -4, 1, 0, -1, -2,
- -1, 2, 2, -4, -4, 2, -2, -3, -4, -3, 0, 3, -3, -2, -2, 4,
- 1, -2, -2, 1, 2, -6, -1, 2, 6, 1, -2, 0, 4, -3, -1, -2,
- -1, 5, 1, -11, 4, 3, -1, -6, 2, -2, 3, -4, -8, -2, -1, 4,
- 0, 3, -2, -1, -2, -2, 1, 3, 3, -7, 0, 2, 10, 0, -4, 3,
- -3, 0, 0, 3, -4, 6, -4, -8, 2, 1, 3, -14, 1, -1, -2, 0,
- 0, -5, -1, 2, -6, -1, 3, 0, -5, -3, 3, 1, 6, -2, 0, 6,
- 2, -7, 1, 3, -5, 5, 8, 0, -1, 1, -4, -6, -2, 6, 4, -4,
- -1, 1, -10, 0, -4, 0, -3, 2, 0, -8, 3, -3, 0, 2, -1, 1,
- -8, -1, -1, -3, -1, 4, 1, 6, 1, 0, 0, -2, 0, -2, 7, -4,
- 3, -1, 2, 0, -2, -2, -8, 3, 2, -1, -4, 3, 0, -3, -5, 2,
- -3, -3, -2, 5, 2, 1, 1, -4, 1, -1, 4, 6, -4, 0, -6, -4,
- 1, 3, 3, -1, -2, -7, -1, -3, 6, -6, 2, 1, 5, -8, -5, -1,
- 2, -1, -3, -1, -1, 5, -7, 3, 3, 1, 4, -4, -3, -3, 8, 1,
- -2, 4, 4, -2, -8, 2, 1, 0, 2, 0, -6, 3, -2, -8, -2, 5,
- -1, -6, 0, 2, -1, -5, -2, -2, 6, 0, -5, -2, 3, 0, -5, -1,
- 6, 7, 2, -8, -4, 6, 2, -6, -4, 12, 2, -5, -2, -6, 1, 1,
- -3, -7, -3, 11, -3, -6, -1, 3, -2, -4, -4, 4, -3, 4, -2, -3,
- 1, 7, 0, -8, 7, 1, -2, -4, -6, 13, 0, -3, 1, 2, -1, -4,
- -3, 1, 3, -2, -3, -1, 0, 3, -1, -10, -1, 2, -8, -3, 3, 2,
- 1, 4, -6, -2, 1, -3, -1, -4, 6, 5, -1, -5, -1, 9, -2, 0,
- -4, 0, 1, -3, 4, -5, 1, 3, -4, -6, 0, 4, -2, -6, 9, -1,
- -3, 2, -4, 0, 4, -7, -4, -1, 1, 4, 0, -1, 6, -2, -2, 4,
- -3, -1, -6, -2, 2, 3, 1, -3, 8, -10, -10, 7, 0, -2, -1, -4,
- 3, -6, 0, -5, -5, 5, 3, -6, 1, 5, 0, -1, 1, -1, 0, 0,
- 0, -5, 7, -2, -1, 2, -1, 3, 0, -6, 4, -3, -2, -3, -2, 1,
- 3, 3, 0, -2, -1, -9, 2, 2, -1, 4, -4, 4, -10, 7, -8, 2,
- 1, -1, 0, -1, 4, 2, -7, 7, -6, -4, 3, 11, -5, -6, 1, 3,
- -4, -6, 2, 2, -2, -3, -7, -4, 6, 0, 7, -13, 6, 2, -9, -2,
- -5, 3, 8, 0, 0, 5, -5, -4, 3, 0, 2, 4, -7, 0, -1, 10,
- -3, -6, 7, 2, -1, 0, 6, -2, -7, 4, -2, -1, -2, 1, -3, -9,
- 6, 0, -4, 0, 3, 3, -11, -4, 7, -16, -2, 0, 2, 1, -2, 2,
- -5, -1, 12, -6, 2, -7, 2, 6, 0, -4, -1, 1, -3, 2, -1, 0,
- 7, -2, 2, -6, 2, 7, -9, -4, 8, 2, -9, -3, 8, 1, -1, 4,
- 5, -11, 2, 1, -1, 0, 0, -6, -2, 2, 6, -13, 2, -3, -8, 1,
- 1, 3, -2, -3, -2, -7, 4, -6, -2, 3, -10, 5, -2, 1, -3, 5,
- 8, -4, -1, 2, -1, 6, 2, 3, 2, -2, 0, -1, 0, 4, 1, -1,
- -2, 7, 1, -7, -5, 7, -5, 2, -5, -4, 0, 3, 3, -2, 0, -1,
- -9, -4, -9, 10, 1, -14, 0, -1, 6, -8, -3, 3, -1, -6, -1, 5,
- 3, -5, -1, 3, -6, 5, 7, -10, 5, 5, 2, -4, -3, 9, 4, -11,
- 0, 5, -11, 7, -6, 2, 2, 12, -15, -8, 2, -3, 7, -5, 3, 3,
- 1, -10, 0, -9, 17, -11, 7, -6, 2, 1, -3, 0, -1, 5, -2, -10,
- -4, 16, -1, -7, -1, -3, 1, 11, -3, 1, -3, 2, -12, -2, 12, 3,
- -1, -10, -2, 6, -3, 1, -1, -4, 12, -1, -2, -7, 6, -1, -1, -16,
- 5, 11, -3, -7, 1, -1, -2, -6, -4, -5, 3, 4, -3, -8, -1, 3,
- -5, 3, 1, 2, 6, -10, 1, 7, 0, 21, -15, 11, -12, 0, 1, 4,
- 1, 4, -4, -1, 3, 7, 0, -5, 10, -15, -14, 2, 6, -11, 5, 3,
- -10, -6, -1, -11, 4, -9, 6, -9, -2, 2, -8, 3, 0, 2, -9, 7,
- 7, 2, 2, 0, 3, 1, 6, 0, 3, 6, -10, 6, -4, 1, 7, 9,
- -1, 0, -7, 1, -11, -8, 9, 4, 0, -6, 2, -16, 0, 1, -2, -16,
- 10, -7, -12, 7, 4, -1, -1, -4, 2, -1, 2, -5, 8, 3, 3, 4,
- -2, 4, 3, 2, -4, -2, -1, 5, -5, -3, 9, 2, -22, 8, -6, 1,
- 3, -5, -4, -6, 7, 0, 5, -8, 9, -13, 0, -6, 18, -3, -3, -1,
- -6, 7, 3, -11, -9, 19, 6, -10, -6, 3, 12, -2, -18, 7, 8, -7,
- -10, 14, -8, 5, 1, -15, -4, 11, -6, 9, -8, -1, 5, 1, -6, -2,
- 7, -3, 7, -20, 6, 5, -4, 3, 12, -12, 11, -4, -22, 7, 9, -13,
- 1, 0, -8, -1, 9, 6, -10, 5, -9, -5, 8, 5, 8, -12, -4, 16,
- -14, 7, 6, -1, -16, 21, 2, -9, 13, 5, -4, -19, 2, -3, 12, -7,
- -2, 3, -2, -4, -3, -8, 4, 1, -4, -4, -14, -3, -1, 1, -11, 30,
- -11, -16, 8, -2, -9, 8, 8, -1, -1, -5, 10, -4, 1, 4, 3, -8,
- -1, 23, -2, -2, 14, -15, -7, 7, -7, 0, 9, -12, 8, -10, 0, -3,
- 16, -13, -11, 5, -1, -10, -2, 6, -5, -4, -9, 10, -6, 7, 1, -13,
- 2, 14, -9, -3, 2, 6, 4, 8, -8, -2, 0, 2, -3, 14, 3, -10,
- -4, -8, -1, 10, -13, -8, 15, -9, -3, -2, 5, -5, -6, -9, 9, 7,
- -4, 14, -7, -18, 12, 1, 2, 1, 4, -2, -6, -3, -2, 5, 7, -2,
- 0, 0, -4, 0, -6, 1, 5, -5, -4, 5, -6, 5, -4, -8, 15, -5,
- -6, 0, 3, -8, 0, 3, 0, -1, 0, -4, 6, -16, 22, -7, 3, -5,
- 2, 2, 1, -3, 4, -8, 4, 4, 0, -5, -9, 4, -5, -4, 3, 2,
- 1, 3, -4, 6, -15, -1, 4, 1, -9, 3, 1, -8, 3, -6, 11, -5,
- 6, -11, 17, -15, -2, -19, -11, 1, -4, 8, 0, 5, 18, -11, 0, 13,
- -4, 6, -13, 4, -11, -1, -7, -7, 11, 10, -9, 17, -11, 20, -6, 7,
- -14, 23, -7, -2, -2, 7, -10, 2, 0, 2, 5, 6, -8, 5, -4, -10,
- 9, -4, 6, 0, -7, 8, -7, 1, -20, -4, -1, -3, 6, -10, -6, -15,
- -11, 10, -5, 19, 3, 1, -19, -11, -1, -9, 9, 22, 24, 10, -5, -18,
- -8, -23, 14, 11, 0, 31, 43, -9, 0, -7, -15, -28, -35, -30, 3, 5,
- -5, 11, 52, 55, 7, -5, -10, -12, -25, -43, -12, 4, -37, -47, -21, -5,
- 4, -11, 1, 31, 27, 34, 46, 48, 61, 10, 16, 8, 7, -14, -40, -47,
- -36, -51, -42, -15, 4, 12, -32, -42, -10, -4, 10, 1, 15, 50, 31, 5,
- 15, 38, 37, 29, 15, 22, 11, -4, -35, 10, 3, -18, 1, -14, -33, -5,
- -47, -25, -13, -2, 15, -6, 5, -29, -17, -19, -1, 3, 7, 2, 17, 28,
- -8, -23, 7, 7, 36, 15, 2, 1, -2, -9, 1, 6, 20, 6, 14, -3,
- 21, -11, -12, -35, 11, -20, -18, -36, -23, -27, -19, 1, 10, 14, 27, 6,
- 44, 14, -9, 3, 20, 27, 45, -8, -13, 16, -16, 24, -10, -9, -3, -38,
- -19, -14, -38, -38, -41, 13, 40, -37, 5, -7, -7, -4, 4, -31, 32, 22,
- 15, 9, 13, 10, 10, -17, 22, 30, 9, -6, 27, 66, 47, -17, -21, -20,
- -9, -36, -73, -3, 22, -35, -12, 6, 7, 4, -17, -45, 22, 17, -17, 3,
- -9, -4, 11, -10, 13, -4, 8, 38, 3, 20, 42, -22, 9, 23, -28, -21,
- 3, 10, 1, 26, -28, -18, -9, 7, -30, -41, -24, -9, 10, -6, 31, -5,
- 2, 29, -9, 1, -27, -24, 7, -19, -5, 10, -13, 21, 21, 3, 30, -11,
- -17, 34, -11, 8, 7, -8, 1, 11, -1, 7, -13, 1, -3, 23, -12, 8,
- -19, -3, 20, -78, 42, -23, 4, -29, -16, -5, 38, -49, 30, -26, 26, 16,
- 8, -33, 53, 19, -20, 12, 5, 23, -11, 4, -6, 42, -111, 67, -40, 29,
- -32, -20, -77, 113, -46, -12, 8, -5, -14, 35, -52, 94, -5, -61, 58, -36,
- 41, -83, 21, -19, 61, -68, 37, -37, 12, 66, -69, -16, 100, -88, 48, 21,
- -39, 73, -24, -2, 45, 65, -59, 53, -103, 95, -97, 1, -14, -4, -41, 9,
- -13, -18, 16, -26, 9, 26, -15, 25, -16, 6, 8, 26, -52, 35, -21, 4,
- -2, -11, -4, 22, 0, 21, -40, 65, -6, -13, -11, -7, 32, -46, -48, 16,
- -26, -3, 0, -42, 87, -68, 34, 17, -14, 43, 23, -15, 30, 20, 47, -19,
- -33, -12, 15, 1, -37, 15, -12, -11, -7, 15, -75, 36, -41, 27, -8, -7,
- -12, 10, -4, 49, -6, 42, -32, 4, 20, 33, -65, 24, -52, 10, 13, -17,
- -15, 60, -14, -55, 35, -16, 50, -83, -3, 29, 58, -75, 71, -46, 47, -32,
- 44, -57, 10, -43, 33, 22, -48, 51, -41, 6, 7, 39, -3, -41, 7, -9,
- 37, -66, 22, 26, -13, 74, -87, 127, -39, -16, -29, -11, -8, -57, -15, -45,
- 52, -74, -5, -2, 103, -126, 85, 20, 28, -7, 53, -38, 58, -10, -11, 33,
- -70, 20, 1, 40, -36, 26, -58, 58, -23, 61, -71, -7, -39, 43, 22, -18,
- -1, -61, 90, -37, 35, -58, 30, -62, 27, -45, 47, -59, -6, -35, 70, -49,
- 9, -30, 92, -15, 21, 1, 26, 6, -19, 90, -43, 49, -46, 10, 6, 15,
- -90, 67, -51, -11, 4, 28, -36, 24, 41, -68, 24, -34, 63, -40, 17, -30,
- 18, -39, 14, -38, 15, 9, -54, 54, -20, 36, -21, -14, -13, 11, 23, 11,
- -54, 56, -25, 37, -46, 49, -74, 81, -40, 51, -44, 57, -69, 51, -50, 61,
- 27, -112, 111, -114, 106, -85, 49, -61, 75, -18, 26, -68, 32, -15, -25, 21,
- -15, 38, -46, 80, -119, 126, -85, 41, -40, 77, -65, 28, -6, -39, 45, -87,
- 39, -63, 81, -32, 4, -32, 44, -25, 42, -12, -15, 21, -1, -56, 21, 23,
- -30, 33, -28, -3, 32, 4, -36, 60, -20, 13, -3, 22, -43, 101, -88, 59,
- -53, 18, 8, 22, -33, -52, 34, -32, 35, -90, 112, -107, 56, -59, 43, -60,
- -18, -4, -21, 45, 11, -48, 11, 38, -27, 58, -49, 65, 19, 54, -38, 35,
- -37, 24, -11, 44, -62, 41, -16, -48, -8, 31, -68, 17, -3, -5, 52, -51,
- -10, 16, -26, 18, -29, 56, -41, 3, 5, -10, -37, 61, -14, -10, -9, 20,
- -8, 8, -2, -16, 44, -17, 14, -33, 30, -2, -27, 16, 3, 0, 51, -42,
- 32, -20, 8, -11, -24, 10, 12, -15, 6, -32, 10, 21, -38, -11, -12, 23,
- 13, -64, 19, 34, -23, -23, 16, 10, 39, 2, -36, 55, -31, 0, -29, 18,
- 8, 12, -61, 73, -28, 54, -34, 21, 9, 7, 53, -34, -29, 19, -7, -44,
- 7, 15, -16, -18, -31, 10, -29, 36, -69, 7, 4, 33, -72, 45, 14, 0,
- -8, 35, -13, 26, 16, -28, -3, -32, 45, -4, 8, -20, 65, -24, 2, -24,
- 40, -16, -16, 20, 8, 2, -3, -2, 23, -15, -11, -30, 19, -51, -19, -5,
- -36, 18, 24, -4, -1, 46, -90, 60, 4, 23, -17, 16, 60, -24, 0, 18,
- 0, 5, -6, -24, 27, -34, -28, -7, -4, 22, -30, -11, -3, -1, -44, 36,
- -38, -6, -9, 55, -34, 16, 27, 28, -65, 62, 22, -32, 36, 7, 2, 27,
- -19, 50, -71, 44, -19, -67, 13, -3, -14, -30, 33, 5, -12, -48, 60, -47,
- -28, 9, -6, 24, -11, -1, 13, 62, -53, 26, 7, -9, 6, 58, -38, -10,
- 0, 5, -23, 23, 8, -14, -19, 21, -9, 35, -17, -28, 14, 27, -17, -14,
- -29, 24, 6, -85, 74, -16, -18, -2, -19, 47, -29, -18, -15, 52, 0, 7,
- -10, -23, 45, 13, -11, 12, -28, 27, -26, 19, -69, 74, -55, 35, -21, 41,
- -24, -11, 39, -19, 7, 0, 7, -31, 10, 7, -45, -17, 25, -12, 9, -19,
- 3, 28, -53, 76, -19, -25, 49, -2, 6, -11, 24, -12, -23, 17, -1, -15,
- -10, -36, 26, -25, 0, -44, 59, -67, 45, -31, 5, 15, 56, -12, -14, 12,
- 10, 24, -52, 37, 5, -35, 52, 23, -55, -6, 24, -49, 26, 31, -24, 10,
- -33, 33, -11, 1, -49, 8, 7, 6, -78, 12, -22, 10, -11, 13, 13, -18,
- 38, 50, -18, -5, 64, -52, 59, 33, 3, -9, -6, -6, 26, -64, 18, -38,
- -47, 18, -33, 4, -39, 40, -31, -1, -23, 48, -30, 18, 17, 32, -20, 32,
- 19, 24, -58, 49, -38, -9, 15, -28, 16, -3, -2, -28, 33, -22, 23, -1,
- -34, 33, -48, 67, -55, 21, 51, -66, -2, 21, -5, -17, 24, -63, 53, 8,
- -19, 9, -11, 36, -37, -35, 43, -35, -3, -44, 68, -43, 53, -24, -5, 45,
- -16, -7, 14, 49, 3, -16, 22, -10, 2, -28, -9, -6, -5, 32, -76, -22,
- 35, -26, -35, -12, 0, 3, 13, 6, 36, 7, -32, 69, -15, 45, -20, -21,
- 35, 35, 1, -25, 11, 34, -24, -33, -9, 5, -25, -49, 31, -41, 15, -42,
- 25, -30, 42, -80, 32, 2, -18, 33, -12, -9, 43, -1, 4, -12, 54, -51,
- 22, -1, 18, 28, -29, 18, 7, 10, -19, 8, -1, 12, -21, -6, -11, 4,
- 4, -28, -8, 22, -27, -5, 9, -25, 20, -19, -36, 41, -8, 20, -32, 16,
- -29, 29, -13, 13, 4, 1, 17, 8, 0, 9, 22, -1, -3, 28, -11, -39,
- 36, -31, 5, -11, -27, 22, -39, 7, 15, -24, 19, 8, -37, 75, -52, 54,
- -65, 22, -13, 23, -26, 32, -19, 10, -8, -3, 12, 16, -44, 25, -23, 14,
- 9, -46, 20, 2, -4, -8, -6, 18, 4, -2, -3, -15, 4, 16, -9, -5,
- 34, -29, 27, -54, 98, -65, 11, -18, 16, -13, 0, -2, 0, 22, -43, 31,
- -46, 58, 2, -25, -2, 16, -2, -29, 17, 18, -26, 21, -17, 5, -4, -9,
- 0, -34, 50, -27, -3, 4, 31, -3, -47, 32, -25, 36, 6, -47, 33, -28,
- 39, -36, 42, -28, 5, -3, -2, 25, 27, -47, 20, 22, -5, -15, 1, -9,
- 16, -25, -10, -43, 40, -12, -19, 22, -24, -5, 14, -44, 42, -32, 32, -45,
- 40, 41, -17, 27, -44, 38, -16, 15, -36, 39, -13, -19, -4, 34, 1, -9,
- 9, -16, -2, -29, 31, -31, -4, 35, -21, -52, 63, -41, 2, -7, 30, -35,
- 13, 9, 15, -4, 14, -36, 18, -14, 55, -50, -6, 22, -23, -11, -5, 12,
- 17, -13, -43, 44, -33, 41, -42, 45, 3, -12, 26, 11, -11, 35, -76, 39,
- 2, 0, 3, -4, 15, -19, -6, -33, 11, 5, 16, -25, -2, 19, -7, -43,
- 30, 20, -27, -18, 12, 14, 33, -50, 14, -15, 23, 8, 2, -10, -4, 53,
- -86, 24, -9, 41, -34, -21, 22, 24, -54, 27, 13, 2, -9, 14, -29, 21,
- 40, -43, -9, -3, 27, -3, -22, 18, 10, -23, -15, 1, 14, -12, 3, -30,
- 30, -22, -28, 36, -15, 39, -57, 21, 3, -3, 33, -13, -2, 6, 20, -6,
- 4, -13, -5, -18, 13, -7, 7, 26, -26, 16, 7, -64, 37, -7, 10, -20,
- 12, -11, 7, -34, 37, -12, -24, 34, -18, -18, 39, 9, -42, -24, 43, 2,
- -16, 25, 12, -16, 8, 12, -44, 32, -9, 23, 1, -37, 40, -23, -17, 18,
- -42, 23, -12, -7, 10, -6, 6, -13, -13, 30, -23, 36, -4, 7, 17, -18,
- 18, -3, 8, 5, -1, -13, -15, 2, -5, -16, 7, -52, 23, -38, 30, -30,
- 16, -26, 21, -22, 24, 3, 20, -28, 22, 22, -31, 42, -16, -11, 32, -26,
- 0, 31, -14, 11, -15, 14, -17, -9, 10, 11, 27, -38, -4, 14, -18, 36,
- -44, 0, -11, 16, -14, -2, 16, -34, -23, 22, 4, -24, 14, -13, 16, 31,
- -28, -10, -6, 51, -27, 13, -49, 3, 68, -38, 1, 8, -27, 26, -16, 0,
- 15, -36, 7, -6, 38, -11, 0, -14, 10, -4, 22, -48, 31, -1, 23, -38,
- 1, 15, -7, 10, -1, -3, 4, -1, 10, -2, -12, 3, -22, 5, 9, 8,
- 4, -14, 12, -3, -7, 22, -20, 3, -6, 13, -15, -8, -7, 16, -14, -1,
- -3, 6, -17, 12, 22, -44, 68, -67, 50, 13, -20, -11, -4, -20, -3, 22,
- -13, -20, 28, -7, 2, 11, -9, -23, 5, 5, -26, 24, -31, 2, 20, 15,
- 2, -7, 4, 19, -6, 41, -51, -3, 24, 27, -30, 25, -37, 1, -7, -2,
- -4, -26, -1, 12, 5, -12, 9, -30, 5, 11, 26, -18, -32, 42, 7, 0,
- -23, 10, 10, -20, 53, -49, 6, -39, 18, 3, -27, 41, -21, 16, 28, 14,
- -24, -15, 19, 5, 16, -31, -1, 45, -25, -6, -16, -4, -19, 37, -47, 21,
- 2, -14, -7, 30, -35, 13, -30, 14, 21, 11, -18, -28, 37, 12, -18, 9,
- 5, -1, 33, -41, 3, -7, -19, 8, -14, 12, 15, -18, -4, 44, -25, 22,
- -46, 19, 40, -25, -12, -5, 17, 7, -53, 25, 4, -10, 14, 16, -31, 40,
- -27, -11, -4, 28, -40, -5, -9, -3, 34, -47, 33, -5, 11, -33, 33, 0,
- -14, 35, -18, -27, 11, 14, -37, 35, -20, 7, 15, 2, 27, -17, 15, -31,
- -1, 11, -27, 24, -26, 14, 13, -35, 20, -13, -2, 16, 16, -6, 2, 15,
- -7, -22, 51, -36, -2, 20, -19, 23, -20, -19, -9, -14, 8, -4, -13, 35,
- -66, 36, -37, 3, 19, -1, 15, 32, -45, 71, -15, -5, 12, 34, -33, 24,
- -5, 20, -43, 42, -59, 13, -12, -69, 66, -29, -34, 17, 7, -28, 24, 5,
- -27, 51, -40, -9, 46, 3, -17, 36, -56, 63, -7, -31, -19, 53, -12, -10,
- 4, 19, -47, 35, 0, -40, 17, -14, 13, -11, 11, 3, -39, 22, 5, 21,
- -19, -11, 25, -4, -5, 20, -13, 25, -6, -16, -16, 29, -61, 25, -33, 12,
- -17, 7, -19, 34, -27, 15, -19, 32, -26, 54, -46, 6, 9, 14, -6, -6,
- 23, -32, 58, -19, -5, 15, 46, -42, 39, -7, -23, -7, -14, -22, 42, -66,
- 0, 4, -8, -11, -4, -3, -7, 7, -23, 30, -14, 19, 8, -9, 20, 36,
- 5, -24, 25, 12, -20, 16, -53, 60, -49, -26, 24, -87, 67, -49, 13, -7,
- 5, -14, 5, 11, 38, -3, -15, 27, 26, -36, 20, 30, -47, 29, -5, 9,
- -10, 38, -65, 47, -49, -4, -10, -6, 1, -1, -28, 16, -14, 3, -14, 27,
- -8, 1, 2, 23, 21, -53, 40, 24, -16, -12, -2, 11, 17, -8, -18, 8,
- -25, 28, -10, -12, 13, -51, 10, 35, -10, -8, -9, 8, 10, 14, -20, 4,
- -9, 37, -5, -2, 2, 4, -9, -5, 16, -16, -23, 13, 7, -9, 14, -49,
- 13, 8, -3, -13, -9, 22, -8, 12, -13, 36, -36, 35, -17, 23, -12, 0,
- -37, 50, -31, -8, -31, 43, -4, -11, 0, 3, -7, -19, 16, -16, -28, 46,
- -28, 27, -13, 33, -21, -1, 39, -13, 3, -4, 4, -39, 74, -30, -17, 33,
- -3, -20, -12, 24, -94, 75, -63, 54, -62, 23, 4, 12, -33, 22, -35, 16,
- 12, -28, 34, 2, -12, -3, 22, 23, -31, -6, 26, 4, -41, 8, 37, -15,
- 21, -7, 18, -51, 42, -27, 35, -45, 35, -30, 18, 9, -20, 1, 18, -12,
- -51, 61, -61, 24, -20, 1, 11, -5, -2, -12, 11, 20, -35, -2, 37, -21,
- 23, -15, -2, 19, -51, 82, -50, 20, 29, -26, -34, 49, -2, -16, 11, -17,
- -4, 6, 15, -35, 13, -15, -10, -17, 15, 4, -42, 43, -31, 34, -30, 53,
- -43, 40, -22, 9, 9, -24, 64, -41, 29, -17, 8, -15, 8, 2, -27, 7,
- 10, -28, 0, 30, -50, 6, -13, -14, -21, 11, 9, 13, -47, 35, -11, 32,
- 28, -28, 1, 32, 2, -19, 28, -24, 9, 0, 19, -6, 16, -33, 6, -23,
- 33, -31, -1, -4, 26, -22, -22, -10, -11, 18, -26, 19, -8, -4, 21, -14,
- 36, -2, 12, -48, 49, -1, -13, -5, 8, -3, 9, -4, -18, 15, 28, -50,
- 10, 4, -7, 4, -39, 37, -39, 11, 2, -20, 13, 4, -6, 0, 35, -17,
- -9, 6, 38, -21, -1, -1, 12, -2, -16, 15, 7, -22, 18, -23, 11, 3,
- -9, -39, 29, -31, 44, -41, 0, 5, 21, -9, -25, 25, -6, 38, -55, 38,
- -14, 6, -26, 38, -24, 39, -39, -15, 17, 16, -20, -27, 17, 24, -20, -20,
- 33, 8, -31, 2, 2, 27, 11, -4, -7, 31, -20, -9, 4, -4, 17, -32,
- 2, -18, 31, -35, 38, -52, 42, -1, -28, -26, 25, 3, -51, 42, -35, 35,
- -39, 44, -38, 20, 20, -51, 34, 45, -10, -7, 27, -19, 33, -49, 22, 2,
- -7, -5, -27, 59, -24, -20, 21, -8, -15, 24, -51, 3, 9, -23, 24, -30,
- 2, 29, -26, -2, 4, 10, 0, -18, 50, 3, 9, -14, 17, -18, 24, -13,
- -33, 7, 25, -50, 2, -2, 30, -58, 31, -8, 23, -11, -1, -24, 21, 1,
- -41, 47, -30, 28, -39, 56, -16, -20, 51, -45, 33, 6, 23, -12, -19, -2,
- 7, 1, -14, -5, -11, -20, 25, -17, 7, -22, 21, -19, 34, -47, -2, 1,
- 33, -30, 14, 20, 6, -9, 17, 13, -22, 19, -58, 23, 26, -15, -52, 2,
- 18, 10, -13, 46, -5, -8, -6, 4, -14, 5, 11, -13, -7, 42, -25, 8,
- -37, 35, -10, 6, -25, 16, 15, -15, -9, -20, 18, -23, 26, -34, 35, -22,
- -10, 9, 14, -6, -21, 27, -8, 4, 1, 3, -19, 28, 2, -7, 30, -8,
- -13, 11, -9, -9, -19, 12, 0, -23, -1, -23, -6, 27, -31, 41, -28, 13,
- 5, 9, -21, 6, 2, -2, 18, -16, 31, -25, 40, -38, 39, -13, 8, 14,
- -3, 9, -30, 6, -12, -7, -15, 30, -64, 6, -22, 13, -8, 14, -40, 9,
- 32, -35, 14, -1, 12, -25, 63, -25, 35, -2, 19, -5, -3, 20, -29, -1,
- 35, -37, 53, -46, 4, -14, 22, -27, 23, -64, 8, 5, -25, 41, -18, 14,
- -42, 53, -56, 35, -42, 71, -63, 45, -38, 29, -12, 33, -22, 0, 24, -13,
- 3, 13, 1, -10, -19, 11, 19, -38, 5, -2, -18, -21, 33, -54, 41, 9,
- 4, -1, -21, 3, 3, 37, -31, 34, -40, 34, -19, 30, -26, 23, -53, 55,
- -8, -13, -16, 7, -13, 46, -38, 2, -3, 17, -1, -26, 18, -57, 68, -27,
- 23, -19, 32, -39, 2, 2, -18, 12, -16, 4, -23, 38, -65, 40, -5, 13,
- 19, -26, -13, 60, -25, 7, 1, 10, 22, -24, 23, -20, -16, -17, 14, -32,
- 26, -4, 17, -15, 9, -29, 4, -29, 11, 36, -18, -19, -2, 5, 28, -23,
- 31, 6, 4, 18, -14, 4, -7, 0, -45, 61, -31, 5, -15, -23, -21, 52,
- -62, 4, 22, 1, -9, 15, -24, -27, 60, -49, 38, 0, -6, 1, 13, 7,
- 4, 19, 6, 0, 27, -28, -14, -21, 17, -1, -30, 23, 10, -36, 18, -19,
- 2, -18, 0, 6, -1, 7, -1, -37, 26, 15, -35, 41, -24, 10, 10, -9,
- -12, 12, 7, 3, 10, -11, 11, -14, 27, -49, 71, -55, 25, 8, -11, 11,
- -5, -22, 7, 15, -17, -11, 18, 4, -54, 43, -38, 27, -1, 7, -13, 19,
- 10, -41, 50, -41, 13, 9, 10, -41, 38, -13, 13, -2, -2, -4, 9, -36,
- -5, 22, -31, -18, 8, 21, -22, 21, -24, 12, 3, 16, -24, 25, -16, 22,
- -35, 14, 3, 11, 12, -22, 40, -11, -25, 14, 0, 14, -2, 2, -10, -12,
- 14, -51, 11, -21, 55, -27, 9, 3, 38, 7, -25, 5, -19, 6, -14, 0,
- -10, 21, -57, 35, 18, -21, 21, -40, -13, 24, -24, -12, 10, -1, 11, 10,
- -12, -5, 38, -45, 23, 26, -13, -9, 32, 6, -3, 30, -28, -28, 27, 3,
- -10, -11, -10, 16, -28, 21, -12, -3, -1, -33, 14, -30, 12, -20, 40, -15,
- 7, 19, -18, -1, -1, 9, 4, -23, 32, 17, -19, 12, 16, -45, 4, -6,
- 18, -28, 36, -44, 44, -29, 10, 4, 14, -8, -13, 9, -30, 39, -17, -5,
- 10, -10, 5, -1, -16, 17, -7, -9, -10, 15, -21, 9, 10, 8, -10, -6,
- 3, -21, 34, -3, 6, -4, 15, 3, -2, 4, 26, -44, 30, -43, 2, 9,
- -5, -7, -18, 16, -28, 0, 5, -7, 0, 7, 0, -7, 21, -14, 17, 15,
- 2, -40, 7, 44, -30, 55, -33, -19, 40, -30, 17, -1, -20, -20, -20, 5,
- 14, 1, -7, -32, 26, -11, -11, 24, -23, 17, 17, 8, -19, 18, 11, -6,
- 17, -4, -13, 14, -9, 21, 9, -16, -8, 2, -16, 3, -9, -32, 6, -36,
- -4, 0, 10, -36, 26, -11, 3, 31, -20, 1, 7, 4, 45, -35, 39, 0,
- 4, 28, -21, 29, -39, 27, 15, -6, -14, 17, -25, -33, 16, -15, 18, -43,
- 28, -61, 33, 1, -27, 13, -19, -20, 26, 11, -27, 16, -21, 33, -13, 43,
- -44, 13, 24, -10, 35, -39, 36, 20, -39, 68, -68, 23, -16, -7, 0, 36,
- -30, -13, -27, 42, -21, -4, -23, -2, 23, 0, -3, -3, 2, 4, -15, -5,
- 28, -10, -20, 24, -7, 27, -58, 31, -7, -29, 39, -40, 41, -35, 8, -25,
- 30, 31, -17, -9, 3, 36, -8, -18, -11, 29, -2, 6, -25, 21, -5, -8,
- -17, -24, 20, -26, 20, -23, 46, -26, -13, 8, 13, 2, -15, 4, -9, 28,
- -25, -19, 49, 18, -50, 45, -11, -17, 5, -61, 15, 4, -22, -1, 22, 23,
- 33, -55, 46, -25, 37, 18, 2, -9, 11, -47, 23, -8, -25, 37, -32, 2,
- 5, 12, -18, -5, 19, -27, -7, 20, -40, 32, -44, -21, -29, 58, 8, -9,
- 57, -28, 29, -32, 14, -14, 4, 23, -33, 16, -4, -16, 21, 38, -37, 23,
- 10, -32, 17, 17, -12, -59, 9, -3, -12, 22, -13, -8, -26, 16, 1, 33,
- -9, -17, 16, -7, 21, -44, 26, 5, 35, -36, -1, 13, 36, -36, 39, -36,
- 17, -13, 2, -33, 20, -13, -51, -2, 9, -2, 35, -21, 19, -20, 18, -19,
- -5, 30, -39, 30, 22, -35, 74, -52, 33, -15, 17, -21, -13, 11, 6, -25,
- 25, -31, 29, -18, 18, -52, 40, -11, -17, -26, 56, -56, 69, -53, -14, 32,
- -10, -8, -2, 18, -14, 20, -18, 20, 22, -27, 0, -25, 56, -46, 16, -28,
- 52, -5, -33, 76, -75, 36, -1, -42, 42, -46, 13, -13, 25, -7, 35, -55,
- 5, 63, -56, 11, -24, 13, -8, -10, -27, 15, -15, 44, -66, 52, -3, -6,
- 0, 23, -33, 79, -55, 30, -27, 37, -18, -6, -2, -19, 52, -22, -50, 60,
- -32, 28, -56, 44, -28, 15, -37, -9, -28, 63, -75, 9, 39, 28, -21, 5,
- -17, 15, 2, -13, 30, 13, -14, 10, -12, 30, -22, -10, 4, -8, -9, 14,
- 6, -39, 34, -6, 4, 1, -5, 0, 33, -73, 34, -12, 23, -9, 53, -47,
- 17, 3, -18, -6, 2, -19, -12, -7, -45, 72, -9, -71, 55, -58, 50, -18,
- -36, 37, 19, -11, 13, -35, 32, 6, 5, 18, -6, 19, -26, 32, 16, 20,
- -43, 20, -10, -7, 16, -7, -68, 21, -36, 7, 19, -22, 19, -3, -35, -37,
- 25, 21, -57, 67, -9, 9, 32, -11, 28, -18, 35, -41, 60, -19, 29, 0,
- -38, 29, -6, -35, 0, 25, -37, -1, -31, -42, 30, -19, -21, 36, -66, 53,
- -33, 15, 16, -13, 20, -35, 73, -4, 18, 39, 4, 1, 3, 21, -2, -12,
- -18, -51, 44, -17, -50, 48, -30, -16, -13, -35, -7, 25, -33, -14, 14, 0,
- 8, -30, 45, -13, 50, -53, 28, 60, -33, 23, -7, -2, 15, 36, -11, 9,
- 19, -44, 4, -21, 19, -5, -27, -45, 48, 9, -47, -23, 12, 3, -25, -8,
- -21, 63, 1, -29, 31, -18, 19, 16, -24, -17, 50, -65, 65, -56, 93, -45,
- -17, -25, 45, -18, 23, -53, 50, -15, -12, -39, 51, -11, 11, 13, -31, 54,
- -14, -29, 22, -11, 10, -41, -19, 52, 10, -51, -60, 72, -13, 12, -38, 19,
- -2, 31, -56, 37, -4, -10, 22, -14, -33, 48, -40, 38, -14, 27, -24, 19,
- 29, 17, -31, -2, -41, 34, -17, 2, 5, 5, -13, -30, 14, 9, -9, 7,
- -11, 15, 5, -28, -2, 0, 45, -30, -25, 1, 10, 29, -55, -24, 52, -5,
- 5, 20, -25, 20, -15, 14, -64, 95, -53, 32, 13, -26, 31, -8, -27, 18,
- 48, -57, -3, -10, 25, -24, -32, -9, 18, 18, -33, -15, 27, -22, 14, -5,
- 10, 51, -21, -25, 19, 5, -15, -29, 16, 1, 33, -39, -12, 56, 14, -63,
- 36, -2, -17, 52, -11, -37, 5, 19, -52, 38, -23, -60, 93, -75, 52, -30,
- -2, -11, 49, -11, -25, 1, 42, -35, 26, -35, -9, 24, -1, 10, -6, -12,
- 7, 4, 22, -10, 41, -25, -8, -4, -2, 28, -43, 19, -32, 4, -27, 9,
- -47, 51, -16, 12, -52, 49, 8, 7, -37, 27, -33, 80, -44, 6, 5, 28,
- -15, 16, 15, 2, -12, 50, -77, 38, -38, -45, 30, 8, -37, -13, -8, -18,
- 50, 3, -54, 29, 29, -20, 4, 52, -57, 62, -52, -2, -9, 62, -64, -5,
- 24, 23, 0, -7, -23, 48, 25, -78, -9, 38, 18, -46, 30, -51, 39, 4,
- -48, 22, 15, 13, -39, 8, 10, 31, -20, -22, 21, -17, 17, -23, 22, 22,
- -24, -36, 11, 31, -16, -28, 34, -4, 0, -20, 6, -2, 35, -13, -60, 36,
- 24, -45, 21, -2, 36, 0, -73, 66, -37, 39, -66, -18, 22, 17, -17, -25,
- 24, 36, -47, 3, 25, 7, 8, 0, 1, 14, 20, -21, 4, 21, 12, -77,
- 17, -4, -12, 31, -57, 38, -11, -4, -31, -6, 29, -34, 11, 13, -20, 82,
- -36, -36, 40, -28, 77, -68, 12, 2, 34, -23, 5, -31, 11, -5, 44, -105,
- 79, -31, -29, -16, 37, 8, 18, -14, -9, 32, -10, -11, -7, 0, 41, 34,
- -56, 7, 13, -2, -31, 33, -67, 42, -31, -2, 22, -49, 18, -34, -11, 38,
- -40, 56, -16, 14, -2, 24, 0, 0, 41, -21, -8, 6, -11, 11, 11, -45,
- 26, 4, -17, -7, -26, -30, 7, -21, -29, 56, -29, 37, -3, 2, -8, -3,
- 22, 11, 40, -13, 58, -6, -38, 48, -23, 15, -52, -14, -6, 49, -66, -20,
- -11, 34, -32, -44, 41, 4, 20, -59, -24, 77, 23, -24, -17, 42, 19, -3,
- -19, -34, 54, 17, -22, -17, 46, -24, -9, 3, -22, 40, -47, -49, 72, 4,
- -18, -48, -33, 55, -4, -41, -51, 105, -26, -3, -22, 64, 28, -51, 31, 2,
- 15, 27, -62, 18, 21, 6, -15, -54, 52, -14, -46, 7, -30, 32, -1, 6,
- -37, 39, -3, -23, -20, 24, 23, 17, -25, -6, 67, -36, -11, -37, 56, -79,
- 3, 30, 45, -39, -17, -2, 21, 2, -4, -3, 3, 1, 16, -16, 9, 30,
- -37, 8, -6, 46, -65, 3, 14, -59, 104, -60, 2, 46, -29, -30, -2, -10,
- 24, -52, 63, -31, 81, -85, 18, 35, 16, -32, -18, -24, 45, -16, -15, -13,
- 37, -15, -20, -42, 91, -45, -15, -9, -16, 64, -11, -23, 31, -18, 38, -42,
- 3, 12, 1, 5, -5, 22, -44, 69, -31, -18, 15, 21, -64, -13, 34, -37,
- 30, -26, -15, 6, -3, 44, -28, 11, -3, -1, 16, -18, 25, -14, -26, 69,
- -56, -5, 31, -51, 24, 3, -36, 9, 52, -34, 31, 21, -11, -68, 31, -24,
- 53, -25, -29, 31, 23, -20, 9, -15, -11, 19, 12, -47, 84, -60, -16, -11,
- 17, -4, -15, 30, -45, 32, 34, -63, -7, 68, 0, -35, 17, 7, 33, -31,
- -8, 7, -32, 43, -13, -18, 15, 31, -32, -34, 5, 8, -16, 20, -26, -29,
- 32, -9, -20, 17, 33, -31, -13, -5, 86, -52, 23, -19, 2, 13, 14, -7,
- -20, 36, -16, -3, 8, 0, 14, -69, 76, -77, 25, -14, -17, 3, 39, -14,
- -46, 31, -2, -7, 37, -45, -6, 24, 28, -37, 22, 13, -35, 4, 8, 23,
- 7, -43, 53, -59, 23, 16, 4, -25, -15, 23, -9, -20, 26, -18, -1, 25,
- -3, -48, 53, 2, -43, 7, 14, -34, 15, 28, -33, 53, -2, -59, 31, -34,
- 40, 19, -27, 20, -2, 8, 2, 3, -8, -8, 4, -57, 62, 24, -72, -4,
- 17, -17, -3, -10, -26, 42, -30, 12, -29, 31, -10, 3, 24, 2, 21, -1,
- -36, 52, -7, 21, 14, -32, -18, 73, -45, -6, 8, -12, -66, 21, 25, -17,
- -6, -35, -14, 27, 26, -47, 40, -51, 56, -19, -24, 31, 6, 4, 11, -3,
- 37, -47, 41, -32, 50, 0, -72, 25, 16, -19, -1, -2, -4, -41, 20, 6,
- 9, -3, -44, 32, -54, 83, -30, -26, -8, 46, -47, 29, 5, -19, 37, -9,
- -20, 65, -14, -21, -4, 10, 28, -28, 18, -29, 35, -25, 3, -17, -31, 4,
- -4, 0, -9, 41, -42, -34, 40, -15, 8, -24, -8, 36, 22, -18, -27, 70,
- -39, 39, 1, -5, 57, -54, 12, 36, 3, -13, -1, -32, 69, 6, -64, -50,
- 13, -13, -34, 22, -13, 0, -10, -38, 41, -11, -22, -3, 11, 4, 38, 22,
- -10, 24, 32, -23, 23, -6, 8, -4, 21, -61, 66, -35, -41, 7, 5, -29,
- -19, -45, 23, -2, 46, -84, 78, -59, 40, -10, -18, 79, -35, -5, -1, 36,
- 16, 13, -21, -31, 52, 2, -50, 34, -5, -36, -37, 65, -42, 1, 16, -42,
- 35, -8, -50, -6, 41, -16, 27, -41, 22, 64, -50, -11, 31, -18, -17, 5,
- -3, 34, 34, -40, -41, 66, -37, 20, -11, -20, 29, -5, -14, -15, 45, -33,
- -37, -11, 36, -25, 18, -8, 20, 1, -23, 60, -32, 0, 34, -24, -32, 64,
- -39, -35, 48, -7, -13, 4, -39, 32, 0, 1, -31, 2, -12, 43, -38, -8,
- 26, 0, -57, 53, 19, -22, -10, 17, -30, 57, 6, -31, 33, 10, 0, -48,
- 29, -4, -23, 6, -7, 31, -39, 15, -41, 38, -19, 5, -37, 23, 11, -28,
- -14, 59, -48, 8, 22, -20, 50, 15, -34, -26, 67, -8, -15, -21, 53, -27,
- -9, 13, -24, -35, -10, 9, -15, -13, 18, -38, 28, 22, -14, 2, -22, 42,
- -20, 22, 12, -20, 45, -16, 17, -16, 22, 34, -27, -13, -7, 1, -21, -1,
- 13, -44, 36, -51, -8, 16, -7, -30, -46, 90, -54, 35, 1, 11, 9, 5,
- 1, -19, 20, 11, 21, -1, -49, 41, -6, 0, 37, -74, 9, 20, -12, -47,
- 65, -68, 28, -5, -26, 15, 14, -3, -23, 8, 18, -22, 13, 3, 31, -21,
- -5, 8, 24, -21, 48, -20, -21, 41, -43, 4, 18, 21, -60, 9, -27, 1,
- 13, -15, -33, 15, 23, -48, -8, 53, -50, 1, 6, -40, 90, -10, -15, 51,
- -52, 53, 29, -68, 50, 52, -30, -21, 7, -1, -8, -29, 11, -47, 6, 18,
- -12, -25, 53, -34, -23, -6, 19, -7, -13, 7, 5, -2, 14, 11, -15, 51,
- -29, 6, 12, 20, -27, 29, -12, 4, -18, -5, 2, -17, 10, -19, 2, -8,
- -5, 56, -82, 49, 0, -42, 48, -25, 19, 6, -41, 17, 35, -18, -17, -29,
- 26, 10, 4, -24, 26, -35, 47, -36, 2, 2, -23, 27, -42, 55, 0, -21,
- 19, 21, -8, 1, -3, -15, 7, 12, -23, -29, 47, -12, 4, -28, 17, 16,
- -7, -31, -8, 25, -6, 0, 13, -20, 6, 3, -7, 19, -21, -37, 27, 41,
- 7, -14, 12, -59, 57, 6, -49, -2, -8, 0, 19, 13, -20, -5, 16, 23,
- 4, -15, -33, 14, 2, 15, -26, -28, 10, 45, -17, -24, 14, 17, -39, 22,
- -8, 48, -51, -1, -16, 52, -34, -21, 11, 13, 18, -57, 26, 15, 27, -36,
- -12, 40, -7, -14, 15, -86, 91, -20, -13, -7, 53, -43, 33, -25, 13, 3,
- -38, -19, 28, 28, -18, -74, 58, -3, 40, -27, -34, 30, 28, -1, -22, 2,
- 9, -8, -12, 12, 21, -35, -2, -17, 17, 2, -27, 22, -36, 38, -11, 2,
- -20, 7, 20, -29, 39, 11, -3, 9, -24, 47, -36, 28, -14, -16, 38, -37,
- 12, -15, 18, -69, 56, -31, 17, -16, -18, -13, 21, -6, -9, -25, 37, 6,
- -1, -2, 5, -1, -26, 39, 6, -3, -10, 0, 12, 30, -12, -31, 24, 13,
- -14, 9, -23, 31, -43, -17, -2, 13, -23, -14, -21, 21, 19, -22, -12, 24,
- 41, -26, 10, 12, 19, -3, 9, -12, 26, 12, -52, -4, 16, -3, 0, -43,
- 7, 5, -14, -9, 12, -28, 15, -23, -2, 35, -12, -8, -10, 24, 57, -55,
- 26, -18, 19, 44, -30, 0, -5, 50, -56, -1, 8, -5, -39, 9, 19, -39,
- 38, -73, 30, -1, 2, 16, -24, 6, 29, -71, 70, -18, -6, 8, 31, 4,
- -13, 23, -11, 31, -56, 57, -25, 10, 15, -44, -10, 16, -17, -44, 18, -28,
- 10, 8, -21, -4, -9, 28, 20, -16, 17, -17, -6, 30, 0, 11, -21, 25,
- 25, -1, 31, -56, 31, 14, -32, 2, -19, 4, -17, -26, -13, 42, -59, 15,
- -29, 53, -4, 1, -23, 13, 31, 5, -22, 3, 30, -28, 2, -24, 37, 1,
- -3, -18, 18, 41, -40, 3, -40, 48, -31, -5, -20, 5, 9, 0, -30, -1,
- 26, -15, -5, -6, 51, -25, -27, 7, 44, -11, 10, -32, 14, 46, -31, 6,
- -11, 37, -33, -14, 19, -4, 22, -50, 26, -45, 21, 1, -23, 10, -15, 17,
- -63, 53, -14, -18, 56, -49, 21, 25, -7, 4, -21, 52, -33, 19, 3, 11,
- -9, -7, 0, -49, 22, -17, 25, -10, -11, 5, -19, 35, -26, 20, -7, -21,
- 37, -25, 29, -23, 3, 6, 17, -26, 27, 5, -16, 10, -9, -24, 11, -4,
- -17, 9, -5, -13, 1, -2, 10, 5, -13, 21, 0, 8, 9, -22, 12, 13,
- -24, -3, -22, 42, -18, 3, -4, -15, 1, -2, 8, -17, -13, -2, 1, 23,
- 10, -2, -31, 23, 17, -15, -9, -24, 31, 2, 19, -24, 4, -22, 28, -5,
- -20, 34, -57, 26, 71, -51, 28, -24, -12, 28, 10, -35, -4, -6, 7, -7,
- 8, -52, 61, -52, 7, -9, -21, 9, 18, -19, 3, 34, -53, 56, -29, 20,
- -11, 22, 4, -1, 23, 2, 1, 24, -15, 3, -32, 13, 21, -37, 6, -11,
- -25, 22, 7, -2, -41, 4, 10, -30, 39, -24, -7, 8, 12, 9, -1, -35,
- 13, 3, 9, -18, 21, 26, -14, 41, -8, -35, 31, -29, 17, -20, -12, 20,
- -30, 27, -26, 21, -9, -6, 5, -14, 3, -11, 15, 2, 8, -14, -5, 20,
- 4, 0, -31, 9, 4, 25, -24, 5, -5, -13, 27, -7, -32, 1, -5, -10,
- 28, 7, -4, 11, 10, 22, -3, -22, -15, 6, -3, -3, -27, -25, 5, 8,
- -10, -17, 18, -18, 12, 32, -18, 1, 25, -25, 50, 7, 2, 0, -3, -3,
- 16, -20, 9, -14, -15, 21, -27, -3, -17, 23, -31, -4, -18, 31, -21, 6,
- 0, 18, -16, 27, 3, -7, -17, 17, -15, -11, 19, -16, 6, 1, 12, -18,
- 5, -6, 24, 0, -19, 22, -23, 43, -35, 18, 22, -40, 1, 12, -4, -18,
- 26, -53, 34, 1, -10, 1, -18, 27, -25, -24, 33, -31, 9, -43, 53, -29,
- 33, -17, 5, 23, -7, 2, 23, 29, 1, -8, 20, -10, -1, -22, -3, -17,
- 4, 22, -61, -23, 31, -26, -29, -12, 2, -3, 12, 10, 26, 5, -29, 61,
- -9, 32, -18, -14, 29, 31, 2, -19, 9, 31, -20, -31, -7, 5, -22, -47,
- 31, -40, 15, -39, 22, -27, 40, -78, 31, 4, -19, 33, -13, -8, 41, -1,
- 5, -12, 53, -51, 22, -1, 18, 28, -29, -1, 0, 0, 11, 13, -2, -7,
- -5, -3, -3, 1, 2, -6, 0, 3, 8, 9, 5, 0, 14, -5, -28, -39,
- -39, -36, -37, -27, -43, -49, -13, 4, 6, -7, 0, -1, 3, 23, 39, 29,
- 35, 41, 21, 35, 0, 0, 21, 59, 67, 31, 21, 13, -3, 18, 34, 28,
- 5, 3, 13, 3, 0, 12, -7, -33, -27, -39, -14, -34, -50, -30, -37, -35,
- -53, -74, -70, -61, -62, -62, -50, -44, -61, -36, -3, -23, -15, -12, -17, -20,
- -6, 11, -6, -12, -6, -17, 7, 46, 71, 87, 79, 70, 77, 104, 109, 66,
- 37, 34, 27, 31, 40, 43, 31, 23, 17, 2, 10, 24, 32, 66, 56, 17,
- -13, -55, -54, -21, 19, -19, -56, -77, -37, -27, -10, -6, -38, -36, -37, -3,
- 23, 25, 25, 19, 35, 34, -7, -5, 28, 60, 66, 65, 51, 34, 22, 53,
- 51, 15, 20, 11, 21, 21, 16, 24, -2, -23, -36, -35, -21, -29, -51, -51,
- -47, -57, -85, -80, -70, -100, -97, -82, -78, -76, -64, -51, -56, -54, -49, -70,
- -62, -53, -54, -60, -57, -65, -78, -76, -62, -39, 0, 31, 13, 6, 31, 54,
- 55, 43, 30, 13, 9, 31, 23, 43, 28, 24, 36, 36, 24, 30, 54, 70,
- 113, 103, 75, 4, -3, 40, 55, 50, 23, 9, 25, 29, 48, 41, 29, 14,
- 6, 40, 63, 49, 39, 71, 80, 64, 21, 12, 17, 29, 68, 71, 52, 36,
- 24, 37, 24, 1, 5, 3, -6, -4, 1, 13, -3, -22, -35, -31, -27, -58,
- -59, -43, -55, -71, -76, -71, -88, -103, -95, -98, -85, -77, -68, -71, -58, -50,
- -47, -52, -46, -40, -47, -44, -48, -56, -60, -91, -96, -68, -15, -6, -16, 9,
- 3, 29, 31, 29, 8, 10, -6, 5, 10, -6, -4, -6, 15, 7, -2, 2,
- -5, 30, 91, 107, 74, 8, -3, 14, 27, 32, 26, 17, 21, 18, 34, 49,
- 20, -3, 2, 30, 42, 20, 36, 68, 79, 81, 52, 27, 22, 37, 80, 95,
- 77, 77, 72, 74, 57, 55, 56, 41, 35, 22, 40, 58, 32, 23, 24, 26,
- 0, -7, 6, -2, -16, -26, -31, -45, -46, -64, -77, -79, -73, -72, -75, -59,
- -49, -56, -35, -48, -44, -50, -43, -59, -58, -40, -78, -119, -123, -95, -73, -40,
- -52, -45, -29, -18, -3, -1, -11, -21, -28, -12, -24, -29, -21, -29, -16, -3,
- -5, -30, -40, 1, 69, 96, 78, 31, 14, 23, 17, 19, 33, 20, 9, 9,
- 45, 50, 14, 3, 12, 13, 16, 7, 14, 35, 54, 75, 56, 24, 1, 18,
- 47, 47, 60, 62, 66, 69, 46, 54, 53, 38, 11, 18, 44, 41, 28, 33,
- 37, 22, 14, 15, 13, 13, 1, -1, -13, -6, -11, -38, -33, -47, -40, -46,
- -31, -29, -22, -9, -5, -9, 9, 4, -23, -14, -4, -3, -26, -69, -87, -74,
- -60, -42, -49, -33, -28, -16, 9, 2, -16, -22, -25, -25, -33, -32, -44, -58,
- -41, -11, -19, -51, -77, -43, 24, 47, 49, 34, 21, 5, -9, 5, 18, -10,
- -14, 2, 23, 26, -3, -7, -4, 2, -3, -10, -4, -6, 38, 64, 50, 25,
- 1, 11, 17, 21, 36, 58, 62, 46, 46, 61, 56, 27, 11, 20, 18, 27,
- 15, 31, 26, 23, 17, 7, 16, 0, -9, -10, -3, -8, -14, -25, -36, -56,
- -41, -39, -50, -30, -12, -23, -8, 10, 23, 17, -2, 3, 14, 26, 7, -33,
- -48, -53, -52, -35, -30, -30, -23, 3, 21, 17, 8, 7, -8, -1, 0, -6,
- -29, -50, -26, 10, 5, -38, -64, -41, 5, 22, 49, 63, 38, 20, 13, 26,
- 15, -7, -9, -1, 28, 9, 1, -4, -12, -1, -5, -20, -38, -32, 6, 38,
- 36, 16, 10, 0, -8, -13, 15, 41, 25, 30, 30, 52, 35, 17, 8, 3,
- -5, -5, -6, 4, 7, 4, 4, 3, 3, -20, -25, -23, -28, -22, -18, -47,
- -50, -54, -62, -67, -62, -48, -43, -44, -31, -10, 17, 10, -8, 1, 22, 24,
- 17, -1, -21, -40, -39, -26, -38, -32, -21, 2, 17, 26, 29, 18, 5, 15,
- 35, 19, -11, -37, -9, 33, 17, -6, -30, -23, -10, 22, 65, 73, 71, 47,
- 57, 66, 38, 15, 16, 23, 34, 35, 27, 10, 11, 21, 32, -4, -26, -29,
- 4, 29, 28, 38, 32, 17, -6, -6, 17, 32, 21, 31, 39, 49, 36, 27,
- 25, 13, -1, -11, -8, -1, -15, -11, 4, -7, -9, -14, -38, -46, -35, -31,
- -43, -53, -54, -72, -84, -88, -86, -79, -73, -86, -69, -40, -16, -23, -28, -13,
- -9, 5, 5, -10, -34, -45, -48, -52, -61, -59, -42, -38, -9, 13, 19, 8,
- -14, 18, 42, 28, -18, -31, -3, 11, 21, 13, -9, -17, -22, 9, 57, 71,
- 62, 68, 83, 82, 65, 38, 38, 31, 52, 57, 45, 23, 25, 51, 56, 21,
- -2, -8, 7, 21, 28, 55, 55, 37, 15, 17, 30, 30, 30, 48, 55, 65,
- 55, 54, 61, 42, 24, 22, 13, 6, 6, 4, 4, 17, 19, 1, -20, -23,
- -25, -27, -26, -44, -44, -62, -79, -91, -83, -76, -99, -104, -87, -63, -51, -40,
- -42, -40, -29, -16, -6, -31, -40, -47, -63, -68, -81, -76, -81, -75, -49, -15,
- -5, -34, -38, 2, 15, 8, -29, -43, -33, -18, -11, 8, -9, -42, -45, -14,
- 25, 33, 41, 54, 67, 75, 71, 46, 30, 23, 52, 55, 38, 20, 25, 53,
- 59, 35, 17, 6, 3, 5, 27, 64, 61, 49, 40, 40, 45, 36, 38, 63,
- 69, 69, 77, 85, 78, 76, 63, 48, 38, 42, 28, 15, 30, 35, 41, 27,
- 14, 0, -4, -2, -14, -16, -15, -35, -65, -63, -56, -64, -80, -94, -77, -71,
- -46, -34, -42, -37, -21, -6, -5, -16, -20, -35, -44, -62, -66, -66, -96, -94,
- -58, -26, -32, -44, -50, -14, 2, -9, -26, -41, -53, -49, -27, -5, -28, -59,
- -65, -47, -20, -11, 7, 15, 28, 51, 57, 32, 7, 2, 30, 32, 15, 0,
- 7, 30, 30, 24, 21, -2, -19, -20, 6, 37, 40, 31, 40, 45, 30, 29,
- 35, 49, 52, 69, 74, 78, 89, 79, 72, 62, 60, 51, 37, 29, 29, 42,
- 51, 46, 30, 32, 18, 2, 8, 13, 15, -13, -35, -35, -38, -40, -53, -71,
- -70, -58, -34, -38, -32, -28, -9, 10, 10, 7, 11, -7, -28, -21, -26, -47,
- -80, -84, -49, -18, -28, -38, -32, -8, -4, 4, 3, -23, -46, -44, -19, -5,
- -22, -42, -55, -56, -35, -25, -12, -8, 11, 43, 51, 33, 1, 0, 24, 18,
- 1, -5, 0, 1, 9, 15, 21, -2, -38, -36, -19, 2, 2, 19, 26, 19,
- 20, 10, 11, 20, 31, 37, 49, 62, 64, 61, 60, 61, 50, 51, 32, 10,
- 16, 27, 31, 33, 33, 36, 7, -6, 3, 14, 12, -10, -21, -40, -34, -33,
- -47, -65, -67, -60, -40, -40, -44, -25, -10, -4, 14, 26, 22, 4, -7, 8,
- 8, -22, -67, -65, -33, -19, -24, -20, -18, -8, 1, 26, 30, -2, -22, -25,
- -6, 5, -1, -13, -38, -43, -31, -21, -16, -16, 9, 47, 61, 35, 22, 22,
- 31, 24, 10, 13, 5, -2, 0, 28, 34, 1, -21, -30, -28, -18, -5, 5,
- 18, 20, 14, 6, 6, 12, 9, 20, 33, 39, 51, 51, 42, 51, 51, 48,
- 20, 9, 7, 5, 7, 15, 28, 19, -1, -16, -15, -4, 4, -16, -30, -41,
- -45, -41, -50, -79, -77, -69, -65, -64, -56, -45, -40, -28, -4, 21, 17, -8,
- -9, 21, 16, -18, -56, -58, -44, -39, -24, -22, -28, -22, -4, 29, 31, 13,
- -9, -16, -3, 11, 13, 1, -18, -33, -15, -11, -23, -22, 11, 52, 58, 50,
- 46, 50, 49, 36, 40, 40, 17, 6, 20, 37, 45, 29, 9, -7, -12, -11,
- -6, 9, 30, 25, 26, 26, 17, 19, 15, 21, 24, 46, 55, 47, 43, 56,
- 64, 52, 33, 25, 13, -3, 2, 10, 21, 26, 4, -15, -16, -13, -2, -11,
- -32, -43, -37, -44, -61, -77, -78, -82, -82, -80, -71, -61, -72, -59, -21, 5,
- -2, -27, -10, 15, 7, -14, -44, -59, -67, -55, -37, -38, -50, -45, -23, 5,
- 23, 9, -6, -19, -15, 5, 14, 2, -22, -22, -10, -17, -35, -38, -3, 35,
- 38, 43, 57, 51, 44, 49, 57, 46, 25, 14, 24, 35, 54, 41, 31, 22,
- 1, -7, -4, 12, 23, 34, 37, 35, 35, 36, 26, 24, 33, 55, 62, 53,
- 58, 70, 70, 73, 62, 51, 38, 14, 6, 20, 31, 32, 27, 4, -9, -1,
- 9, -8, -21, -22, -27, -33, -53, -64, -67, -82, -86, -83, -67, -75, -97, -77,
- -36, -15, -27, -32, -18, -1, -1, -6, -31, -62, -73, -68, -52, -52, -68, -69,
- -50, -21, -2, 4, -10, -33, -29, -4, 2, -10, -29, -22, -8, -27, -55, -49,
- -27, -6, 12, 31, 43, 31, 38, 44, 54, 48, 25, 11, 19, 30, 36, 41,
- 41, 29, 11, -1, -9, 0, 15, 27, 34, 36, 46, 46, 26, 27, 39, 51,
- 59, 62, 62, 73, 76, 77, 85, 78, 58, 35, 23, 21, 37, 53, 37, 22,
- 15, 16, 20, 3, 0, -2, -2, -14, -33, -35, -45, -69, -77, -59, -53, -76,
- -96, -74, -41, -30, -25, -26, -19, -4, 7, 11, -8, -40, -62, -62, -51, -55,
- -69, -74, -71, -44, -15, -2, -14, -36, -38, -8, -7, -27, -33, -17, -12, -38,
- -51, -57, -58, -41, -14, 8, 19, 15, 15, 31, 46, 40, 21, 9, 7, 10,
- 20, 25, 33, 28, 16, 1, -18, -13, 0, 6, 12, 30, 39, 39, 26, 20,
- 32, 41, 45, 53, 64, 63, 62, 80, 84, 87, 81, 51, 29, 21, 44, 52,
- 41, 33, 29, 31, 27, 12, 8, 16, 10, -4, -7, -7, -29, -62, -57, -37,
- -44, -68, -81, -70, -48, -33, -23, -22, -17, -5, 16, 31, 14, -15, -33, -42,
- -41, -37, -53, -65, -74, -54, -16, 2, -12, -33, -19, -1, -10, -22, -17, -8,
- -8, -18, -33, -48, -62, -57, -31, -1, 7, 0, 9, 22, 40, 40, 27, 14,
- 4, 3, 10, 14, 21, 31, 20, 0, -13, -19, -17, -15, -7, 12, 29, 28,
- 13, 20, 18, 18, 31, 38, 47, 49, 51, 56, 67, 87, 84, 56, 30, 20,
- 31, 41, 31, 24, 32, 33, 20, 7, 14, 15, -2, -1, 13, 4, -28, -53,
- -45, -34, -38, -59, -75, -72, -58, -44, -26, -26, -29, -8, 14, 34, 28, 10,
- -9, -22, -26, -24, -30, -54, -78, -56, -13, -4, -17, -16, -5, 1, -6, -9,
- -8, -1, 3, -2, -4, -28, -53, -58, -37, -10, 1, -1, 6, 20, 34, 46,
- 40, 25, 19, 11, 7, 10, 23, 33, 28, 16, -3, -3, -17, -31, -14, 4,
- 15, 20, 20, 16, 10, 14, 19, 23, 37, 45, 35, 37, 53, 76, 83, 62,
- 34, 20, 27, 28, 13, 17, 29, 21, 7, 9, 13, -4, -17, -4, 13, 2,
- -27, -53, -47, -39, -46, -56, -77, -87, -77, -58, -45, -46, -47, -33, -6, 17,
- 22, 16, 1, -20, -25, -10, -21, -57, -79, -57, -32, -24, -23, -18, -3, -1,
- -6, -4, -4, -5, 3, 13, 14, -6, -38, -51, -39, -22, -4, -1, 3, 14,
- 32, 45, 46, 46, 33, 25, 15, 9, 28, 38, 32, 28, 26, 14, -9, -21,
- -15, -5, 10, 24, 22, 22, 21, 15, 15, 23, 36, 42, 35, 31, 41, 72,
- 87, 68, 46, 42, 34, 19, 14, 25, 25, 11, 14, 18, 14, -7, -24, -7,
- 12, 4, -19, -41, -47, -44, -41, -52, -74, -92, -88, -72, -59, -63, -68, -53,
- -34, -11, 12, 19, -7, -27, -15, -5, -22, -54, -76, -66, -52, -47, -41, -29,
- -17, -12, -12, -10, -11, -19, -7, 12, 19, 3, -23, -42, -48, -31, -19, -14,
- -6, 1, 20, 35, 39, 50, 51, 33, 16, 17, 30, 31, 32, 41, 39, 28,
- 14, -7, -14, -5, 8, 18, 27, 34, 29, 22, 21, 26, 38, 51, 39, 27,
- 43, 75, 84, 73, 75, 68, 46, 32, 31, 35, 27, 15, 23, 36, 26, 0,
- -13, -4, 12, 14, 1, -23, -36, -36, -32, -36, -60, -83, -84, -70, -67, -70,
- -66, -67, -62, -27, 8, 13, -11, -22, -7, 4, -16, -44, -63, -67, -63, -63,
- -53, -42, -33, -25, -15, -10, -22, -27, -18, -1, 16, 9, -13, -32, -46, -42,
- -31, -30, -24, -8, 5, 11, 25, 49, 50, 33, 25, 20, 21, 24, 29, 34,
- 41, 41, 26, 5, -5, -7, -4, 12, 23, 33, 37, 29, 19, 24, 49, 53,
- 33, 33, 49, 65, 73, 80, 89, 85, 63, 48, 50, 46, 30, 20, 35, 46,
- 39, 17, 0, 2, 15, 23, 18, -2, -20, -24, -12, -19, -45, -60, -66, -70,
- -66, -56, -61, -74, -74, -38, 0, 6, -8, -15, 3, 13, -1, -24, -42, -52,
- -65, -64, -54, -54, -47, -31, -19, -12, -21, -32, -27, -12, 7, 13, -2, -24,
- -36, -37, -44, -47, -32, -20, -18, -9, 12, 30, 38, 35, 26, 18, 17, 16,
- 13, 25, 36, 37, 32, 18, 2, -11, -10, -5, 3, 28, 38, 20, 8, 25,
- 42, 40, 28, 30, 40, 46, 54, 70, 87, 82, 66, 61, 59, 48, 28, 20,
- 32, 43, 43, 24, 8, 1, 7, 23, 25, 3, -13, -9, -8, -15, -28, -40,
- -58, -71, -60, -49, -58, -80, -82, -50, -17, -5, -13, -12, 6, 13, 8, -3,
- -24, -42, -54, -59, -57, -60, -59, -43, -24, -15, -20, -30, -35, -25, 1, 11,
- -2, -12, -18, -33, -48, -49, -41, -37, -32, -21, -8, 13, 27, 27, 27, 23,
- 16, 8, 7, 15, 22, 32, 35, 22, 9, 0, -18, -26, -8, 20, 25, 11,
- 4, 18, 32, 29, 22, 29, 30, 27, 38, 60, 75, 70, 68, 69, 67, 52,
- 30, 19, 27, 36, 40, 34, 10, -2, 6, 21, 20, 4, -2, -4, -7, -9,
- -12, -25, -52, -66, -53, -42, -53, -79, -86, -58, -33, -23, -16, -12, 0, 12,
- 17, 13, -5, -24, -38, -44, -50, -59, -61, -51, -33, -15, -11, -28, -36, -23,
- -4, 5, 5, 7, -3, -17, -31, -40, -38, -37, -36, -29, -14, 4, 15, 25,
- 34, 30, 24, 19, 9, 8, 22, 33, 31, 30, 31, 16, -14, -26, -13, 14,
- 17, 7, 8, 18, 24, 23, 28, 31, 23, 18, 30, 50, 62, 61, 63, 75,
- 73, 59, 40, 23, 20, 30, 43, 35, 11, 0, 8, 15, 12, 6, 3, -6,
- -10, -3, -1, -15, -46, -62, -47, -38, -54, -77, -84, -70, -53, -40, -30, -21,
- -12, 1, 16, 20, 5, -12, -21, -33, -44, -52, -64, -64, -44, -17, -15, -27,
- -30, -26, -15, -3, 6, 12, 9, -2, -17, -26, -29, -36, -41, -32, -21, -10,
- 6, 18, 27, 34, 37, 25, 11, 14, 21, 26, 27, 37, 48, 33, -1, -19,
- -8, 7, 8, 8, 16, 16, 17, 25, 34, 36, 23, 16, 28, 44, 53, 54,
- 61, 74, 79, 75, 56, 30, 19, 31, 45, 35, 15, 9, 9, 9, 11, 9,
- 5, -8, -14, 0, 9, -10, -40, -53, -44, -38, -51, -72, -84, -80, -69, -58,
- -45, -38, -30, -13, 5, 13, 8, 0, -14, -25, -30, -46, -67, -72, -55, -34,
- -26, -28, -31, -31, -26, -17, -4, 9, 11, 2, -4, -12, -22, -33, -38, -40,
- -34, -18, -7, 2, 17, 33, 38, 29, 19, 20, 22, 17, 19, 38, 57, 43,
- 15, 2, -1, 1, 3, 10, 18, 15, 14, 25, 38, 40, 27, 21, 28, 38,
- 46, 50, 55, 66, 81, 90, 71, 40, 30, 37, 44, 39, 26, 18, 12, 8,
- 14, 19, 8, -11, -13, 5, 15, -2, -28, -42, -36, -34, -45, -60, -76, -83,
- -77, -65, -59, -55, -43, -28, -13, 5, 11, 2, -9, -11, -17, -37, -61, -71,
- -65, -49, -38, -36, -34, -35, -36, -32, -16, -2, 1, 3, 0, -7, -13, -25,
- -39, -46, -42, -30, -22, -15, 2, 21, 30, 24, 22, 28, 19, 5, 11, 33,
- 50, 45, 31, 17, 6, -1, 0, 8, 16, 12, 11, 23, 37, 40, 33, 29,
- 29, 33, 45, 48, 46, 58, 83, 97, 84, 59, 45, 46, 47, 46, 42, 31,
- 16, 12, 23, 29, 16, -5, -9, 10, 21, 10, -12, -24, -25, -25, -29, -42,
- -64, -73, -70, -66, -63, -58, -52, -42, -22, 0, 8, 4, 1, 3, -1, -19,
- -44, -61, -63, -57, -50, -39, -33, -37, -39, -36, -27, -14, -4, 0, 0, 0,
- -1, -13, -30, -42, -43, -37, -36, -30, -10, 8, 12, 15, 26, 31, 16, 1,
- 4, 21, 37, 41, 38, 29, 13, 0, -1, 6, 8, 3, 7, 17, 26, 34,
- 35, 27, 24, 32, 40, 37, 32, 45, 72, 89, 86, 70, 57, 48, 45, 49,
- 50, 37, 16, 11, 25, 34, 20, -3, -7, 7, 18, 15, 2, -14, -20, -15,
- -17, -32, -49, -61, -67, -65, -60, -61, -63, -54, -33, -12, -1, 1, 2, 10,
- 12, -3, -26, -43, -57, -60, -54, -45, -38, -38, -39, -39, -35, -23, -13, -6,
- -3, 2, 7, -2, -20, -30, -34, -42, -47, -38, -19, -9, -5, 7, 24, 31,
- 19, 3, 0, 10, 23, 33, 40, 36, 18, 5, 4, 4, 0, 0, 0, 5,
- 16, 29, 30, 22, 22, 31, 36, 27, 21, 32, 54, 74, 81, 77, 65, 49,
- 44, 50, 55, 40, 16, 10, 24, 31, 20, 3, -6, -1, 11, 16, 5, -9,
- -13, -12, -14, -22, -36, -53, -63, -62, -59, -63, -69, -67, -48, -25, -14, -10,
- -1, 10, 16, 10, -6, -26, -45, -54, -55, -50, -42, -39, -39, -40, -39, -29,
- -19, -15, -8, 4, 11, 3, -6, -11, -21, -38, -48, -40, -26, -21, -16, -3,
- 18, 30, 24, 12, 6, 4, 11, 29, 41, 39, 28, 18, 11, 8, 5, 1,
- -4, -2, 11, 25, 25, 19, 23, 33, 35, 25, 17, 23, 39, 57, 74, 81,
- 72, 53, 47, 56, 60, 44, 23, 16, 22, 29, 25, 10, -4, -3, 7, 11,
- 6, -3, -9, -11, -9, -12, -26, -42, -56, -59, -55, -61, -73, -75, -60, -42,
- -32, -23, -12, 0, 12, 15, 7, -10, -30, -46, -53, -53, -46, -41, -43, -45,
- -41, -32, -30, -26, -14, -1, 5, 2, 3, 3, -9, -30, -43, -40, -31, -31,
- -28, -12, 8, 20, 25, 22, 9, 0, 6, 21, 34, 39, 35, 26, 18, 16,
- 14, 4, -7, -5, 9, 21, 19, 16, 23, 35, 37, 28, 20, 20, 26, 43,
- 67, 82, 74, 57, 54, 62, 63, 52, 33, 21, 23, 30, 28, 14, 1, -1,
- 3, 8, 7, -1, -7, -9, -6, -5, -15, -34, -49, -51, -51, -60, -72, -76,
- -70, -57, -46, -37, -25, -13, 3, 14, 14, 3, -15, -33, -48, -52, -47, -45,
- -49, -49, -41, -37, -39, -35, -21, -10, -5, -2, 6, 12, 1, -19, -32, -34,
- -36, -39, -34, -23, -9, 9, 23, 25, 14, 3, 2, 12, 25, 36, 37, 30,
- 24, 25, 24, 10, -5, -4, 9, 18, 15, 14, 23, 34, 38, 36, 30, 19,
- 15, 32, 61, 78, 75, 63, 60, 67, 71, 62, 42, 29, 30, 33, 32, 20,
- 8, 4, 6, 8, 8, 3, -5, -9, -2, 3, -7, -25, -37, -42, -45, -54,
- -66, -74, -74, -67, -58, -49, -40, -27, -9, 5, 13, 13, 0, -21, -39, -45,
- -44, -49, -54, -50, -44, -44, -47, -42, -29, -21, -19, -11, 5, 12, 4, -8,
- -18, -28, -36, -40, -40, -36, -24, -4, 14, 21, 17, 7, 0, 3, 17, 32,
- 34, 29, 28, 34, 33, 17, 0, 0, 9, 13, 12, 14, 20, 27, 38, 46,
- 39, 21, 11, 24, 51, 71, 74, 66, 64, 73, 78, 71, 54, 40, 38, 41,
- 38, 28, 17, 11, 9, 12, 14, 7, -3, -5, 3, 9, 2, -12, -23, -28,
- -35, -45, -55, -65, -71, -68, -62, -57, -50, -37, -22, -7, 10, 20, 12, -8,
- -24, -32, -39, -48, -52, -49, -45, -49, -52, -44, -34, -33, -30, -18, -3, 5,
- 5, 1, -8, -19, -29, -37, -43, -45, -37, -18, 0, 13, 18, 10, -1, -3,
- 10, 24, 26, 23, 29, 38, 37, 21, 8, 5, 6, 8, 10, 12, 11, 16,
- 34, 49, 46, 27, 10, 15, 38, 59, 67, 63, 63, 72, 81, 77, 61, 48,
- 45, 45, 42, 35, 23, 13, 11, 17, 18, 9, -3, -5, 3, 10, 6, -3,
- -12, -19, -24, -34, -46, -57, -64, -65, -66, -63, -56, -48, -39, -22, 1, 17,
- 16, 3, -8, -17, -30, -44, -47, -44, -47, -53, -52, -44, -41, -41, -38, -28,
- -14, -3, 3, 3, -2, -9, -17, -28, -42, -49, -46, -34, -17, 3, 14, 9,
- -3, -6, 5, 15, 13, 15, 26, 36, 35, 25, 16, 8, 2, 4, 9, 6,
- 1, 4, 22, 43, 48, 31, 11, 7, 24, 45, 55, 54, 55, 68, 79, 77,
- 66, 54, 48, 47, 47, 41, 27, 14, 11, 18, 20, 10, -2, -6, 0, 7,
- 8, 2, -6, -12, -14, -23, -38, -49, -55, -62, -66, -63, -60, -59, -53, -37,
- -12, 8, 13, 10, 7, -4, -21, -35, -37, -39, -47, -53, -51, -45, -44, -44,
- -42, -36, -24, -10, 0, 2, 1, 1, -3, -15, -30, -42, -49, -45, -30, -6,
- 10, 7, -2, -3, 5, 9, 6, 11, 23, 32, 35, 33, 25, 14, 6, 9,
- 12, 8, -2, -4, 13, 36, 48, 39, 18, 7, 17, 34, 43, 45, 50, 62,
- 74, 78, 71, 59, 51, 49, 52, 48, 32, 16, 12, 19, 21, 13, 1, -6,
- -5, 2, 6, 2, -4, -6, -9, -18, -29, -40, -51, -60, -65, -63, -63, -68,
- -68, -53, -30, -12, 0, 10, 13, 3, -14, -25, -29, -35, -45, -52, -52, -49,
- -47, -47, -47, -46, -35, -20, -10, -5, -1, 4, 4, -4, -15, -30, -47, -54,
- -41, -15, 1, 0, -2, 2, 6, 4, 3, 7, 16, 26, 35, 38, 32, 20,
- 12, 14, 18, 12, -1, -8, 3, 27, 46, 44, 26, 14, 17, 28, 35, 38,
- 44, 55, 69, 78, 77, 66, 55, 54, 60, 58, 41, 24, 17, 19, 23, 20,
- 7, -4, -4, 0, 2, 1, 0, -2, -4, -10, -17, -28, -42, -55, -59, -56,
- -61, -72, -74, -63, -47, -32, -14, 5, 13, 7, -4, -12, -19, -28, -38, -46,
- -51, -50, -46, -47, -51, -52, -43, -30, -20, -13, -5, 0, 4, 4, 2, -13,
- -40, -55, -47, -25, -12, -8, -3, 3, 5, 4, 2, 3, 7, 18, 32, 41,
- 36, 25, 18, 21, 25, 21, 5, -9, -3, 19, 41, 45, 34, 24, 23, 27,
- 30, 33, 38, 47, 62, 78, 82, 72, 61, 61, 67, 66, 54, 37, 24, 23,
- 28, 25, 15, 5, 0, 0, 0, 1, 2, 2, -1, -4, -5, -15, -34, -47,
- -49, -49, -58, -69, -73, -70, -63, -51, -30, -8, 5, 7, 3, -4, -11, -20,
- -29, -41, -49, -50, -46, -49, -54, -56, -50, -42, -33, -22, -13, -10, -6, 5,
- 12, -1, -30, -50, -50, -38, -27, -18, -10, -3, 1, 2, 2, -2, -4, 6,
- 24, 36, 36, 27, 19, 22, 30, 28, 10, -8, -10, 9, 30, 39, 35, 30,
- 26, 26, 28, 29, 29, 35, 53, 73, 80, 74, 65, 63, 69, 72, 64, 47,
- 33, 28, 29, 28, 21, 12, 6, 2, -2, 1, 4, 1, -2, 2, 6, -4,
- -23, -35, -38, -42, -51, -60, -66, -70, -71, -63, -45, -23, -5, 4, 6, 3,
- -2, -7, -18, -32, -42, -43, -43, -47, -52, -54, -53, -51, -42, -27, -20, -21,
- -14, 4, 17, 10, -13, -35, -45, -44, -37, -26, -17, -11, -3, 3, 3, -3,
- -9, -4, 13, 31, 35, 27, 19, 23, 34, 36, 19, -3, -10, 2, 19, 31,
- 35, 33, 29, 30, 32, 28, 22, 26, 43, 63, 76, 75, 67, 65, 71, 75,
- 70, 57, 43, 36, 34, 30, 26, 21, 14, 5, 1, 4, 3, -2, -2, 6,
- 11, 3, -11, -22, -29, -36, -43, -50, -57, -67, -74, -72, -60, -40, -19, -5,
- 2, 4, 6, 3, -8, -23, -32, -35, -40, -45, -47, -51, -57, -58, -47, -33,
- -30, -32, -24, -5, 13, 14, 1, -18, -36, -45, -42, -35, -27, -20, -11, 0,
- 3, -3, -12, -12, 1, 21, 31, 25, 16, 20, 34, 40, 26, 5, -7, -6,
- 7, 21, 27, 26, 27, 31, 33, 27, 17, 15, 28, 50, 65, 68, 64, 62,
- 68, 74, 72, 61, 51, 44, 35, 29, 28, 25, 15, 7, 5, 5, -1, -8,
- -5, 3, 8, 4, -4, -12, -22, -32, -38, -42, -50, -61, -72, -77, -73, -57,
- -36, -20, -11, -2, 7, 8, -3, -14, -22, -30, -38, -41, -42, -49, -60, -62,
- -52, -41, -40, -41, -34, -18, 0, 11, 10, -3, -23, -38, -42, -40, -36, -31,
- -20, -6, 2, -1, -13, -19, -9, 12, 25, 20, 12, 17, 30, 39, 34, 17,
- -2, -8, 1, 13, 19, 21, 23, 31, 37, 32, 18, 10, 18, 36, 55, 62,
- 60, 60, 67, 73, 72, 68, 61, 51, 41, 35, 34, 28, 18, 12, 11, 8,
- -2, -9, -7, 0, 4, 5, 3, -3, -14, -24, -31, -36, -41, -50, -64, -77,
- -80, -68, -51, -37, -26, -11, 3, 6, 2, -3, -13, -24, -32, -33, -34, -46,
- -60, -62, -54, -47, -46, -47, -43, -31, -13, 4, 12, 6, -9, -23, -34, -39,
- -40, -38, -29, -14, 0, 2, -11, -22, -15, 4, 17, 16, 11, 13, 25, 39,
- 41, 28, 9, -3, 0, 9, 15, 15, 19, 30, 40, 39, 26, 12, 11, 28,
- 45, 54, 56, 60, 66, 70, 73, 74, 69, 58, 49, 45, 42, 32, 22, 18,
- 19, 14, 3, -6, -7, -4, 0, 5, 6, 3, -5, -14, -24, -30, -32, -38,
- -53, -71, -78, -72, -63, -54, -39, -22, -8, 1, 6, 6, -4, -18, -25, -23,
- -25, -39, -54, -58, -54, -49, -49, -50, -49, -42, -26, -7, 7, 9, 2, -9,
- -20, -30, -38, -43, -39, -22, -2, 3, -9, -20, -16, -2, 11, 14, 10, 10,
- 20, 36, 46, 40, 22, 8, 6, 11, 13, 12, 15, 26, 41, 46, 36, 20,
- 14, 24, 38, 47, 54, 60, 64, 69, 76, 81, 76, 66, 60, 58, 53, 40,
- 30, 27, 27, 22, 12, 3, -3, -4, -1, 4, 8, 8, 5, -4, -15, -21,
- -21, -25, -41, -58, -69, -71, -70, -64, -51, -35, -23, -9, 5, 10, 1, -13,
- -17, -15, -19, -32, -46, -54, -54, -51, -50, -52, -55, -53, -40, -22, -6, 3,
- 4, -2, -10, -19, -32, -47, -49, -32, -11, -3, -10, -20, -20, -10, 2, 7,
- 5, 2, 10, 28, 42, 41, 29, 16, 10, 11, 11, 7, 6, 17, 35, 45,
- 39, 26, 18, 19, 26, 37, 47, 53, 56, 61, 73, 81, 76, 68, 65, 65,
- 59, 46, 36, 31, 28, 25, 19, 9, -1, -6, -4, -1, 2, 8, 9, 0,
- -10, -15, -14, -18, -32, -46, -57, -68, -74, -71, -61, -51, -41, -23, -2, 8,
- 2, -8, -11, -10, -13, -23, -37, -48, -53, -51, -49, -53, -59, -60, -53, -37,
- -19, -7, -3, -2, -1, -6, -22, -43, -52, -42, -21, -9, -12, -20, -23, -16,
- -4, 3, -1, -6, 0, 18, 34, 40, 33, 22, 16, 16, 13, 5, 0, 9,
- 27, 39, 40, 32, 24, 18, 19, 29, 40, 44, 46, 55, 69, 77, 75, 71,
- 70, 70, 65, 55, 45, 37, 32, 30, 26, 17, 7, 0, -5, -6, -1, 8,
- 11, 4, -5, -7, -7, -13, -21, -30, -44, -59, -69, -69, -65, -63, -56, -36,
- -13, 1, 1, -4, -6, -5, -6, -12, -25, -40, -47, -47, -46, -50, -56, -62,
- -61, -48, -30, -18, -12, -6, 4, 6, -7, -32, -49, -46, -30, -16, -12, -19,
- -25, -20, -7, 0, -3, -9, -7, 8, 26, 36, 34, 27, 24, 24, 19, 7,
- -2, 4, 18, 31, 38, 38, 30, 20, 18, 26, 34, 35, 38, 48, 62, 71,
- 73, 72, 73, 72, 70, 64, 53, 43, 38, 35, 30, 23, 16, 7, -4, -10,
- -4, 6, 8, 3, -1, -2, -4, -9, -12, -19, -33, -51, -61, -65, -69, -73,
- -70, -52, -30, -13, -6, -5, -7, -5, -2, -5, -17, -31, -41, -45, -44, -45,
- -53, -64, -67, -58, -43, -31, -26, -17, -1, 10, 3, -19, -41, -48, -39, -23,
- -16, -21, -27, -24, -12, -3, -5, -13, -15, -3, 16, 28, 29, 26, 28, 31,
- 24, 10, 0, 0, 8, 20, 33, 38, 32, 22, 19, 24, 28, 28, 30, 40,
- 52, 61, 68, 71, 72, 73, 73, 69, 59, 51, 45, 39, 32, 28, 26, 15,
- 0, -9, -5, 2, 4, 2, 1, -1, -4, -6, -5, -10, -24, -41, -50, -56,
- -66, -76, -77, -66, -47, -27, -15, -11, -10, -5, 0, -1, -8, -20, -33, -40,
- -40, -40, -48, -62, -70, -64, -51, -43, -39, -29, -11, 7, 10, -5, -28, -43,
- -41, -28, -20, -22, -29, -28, -17, -6, -5, -14, -20, -12, 6, 19, 22, 23,
- 30, 35, 31, 20, 8, 0, 1, 13, 29, 37, 33, 26, 25, 27, 27, 25,
- 26, 33, 43, 54, 63, 67, 70, 74, 76, 72, 66, 61, 54, 44, 37, 36,
- 34, 24, 8, -3, -4, -2, 0, 2, 3, -1, -5, -3, 2, -2, -16, -29,
- -36, -44, -57, -70, -79, -76, -60, -41, -27, -19, -14, -8, -1, 3, 0, -10,
- -24, -33, -33, -32, -40, -55, -65, -63, -56, -51, -48, -40, -23, -1, 12, 7,
- -13, -32, -37, -29, -21, -21, -28, -29, -19, -6, -2, -12, -20, -14, 0, 11,
- 16, 22, 30, 37, 38, 33, 21, 7, 0, 9, 26, 36, 35, 32, 32, 32,
- 31, 28, 27, 30, 38, 50, 58, 63, 70, 78, 79, 76, 74, 72, 64, 53,
- 46, 45, 44, 34, 20, 9, 3, -1, 1, 7, 7, 0, -4, 2, 8, 5,
- -5, -15, -23, -30, -41, -58, -73, -77, -68, -53, -38, -28, -21, -14, -5, 4,
- 7, -1, -15, -25, -25, -24, -32, -48, -59, -61, -59, -57, -57, -54, -39, -16,
- 4, 8, -5, -24, -33, -30, -24, -24, -32, -35, -26, -11, -6, -14, -20, -19,
- -10, -2, 5, 13, 21, 29, 37, 40, 30, 11, 0, 4, 17, 27, 30, 31,
- 31, 32, 32, 29, 23, 23, 31, 40, 45, 52, 63, 72, 74, 73, 75, 75,
- 67, 56, 51, 50, 46, 38, 29, 18, 6, -3, -1, 5, 3, -4, -7, -2,
- 4, 5, -2, -11, -17, -21, -30, -47, -66, -78, -77, -66, -53, -42, -34, -27,
- -16, -3, 6, 1, -12, -21, -21, -21, -28, -42, -54, -60, -60, -61, -65, -67,
- -57, -35, -11, 1, -3, -18, -30, -30, -25, -27, -36, -41, -32, -19, -13, -17,
- -22, -22, -19, -14, -6, 2, 7, 17, 31, 41, 34, 17, 3, 1, 8, 17,
- 23, 25, 26, 30, 32, 28, 22, 21, 25, 30, 34, 42, 54, 63, 66, 70,
- 77, 77, 69, 61, 57, 55, 49, 44, 39, 28, 11, 2, 2, 5, 3, -3,
- -8, -4, 3, 6, 2, -4, -9, -11, -16, -31, -52, -68, -75, -71, -61, -50,
- -43, -38, -26, -8, 5, 4, -6, -13, -14, -13, -19, -31, -44, -51, -52, -55,
- -64, -71, -67, -49, -24, -4, -1, -12, -22, -21, -18, -22, -33, -39, -33, -22,
- -16, -16, -17, -19, -20, -16, -9, -4, -2, 5, 18, 31, 37, 32, 21, 11,
- 9, 12, 17, 20, 24, 28, 32, 31, 28, 26, 26, 26, 28, 34, 43, 51,
- 57, 65, 74, 77, 75, 72, 68, 63, 59, 56, 53, 44, 31, 19, 12, 11,
- 8, 3, -2, -3, 0, 4, 5, 2, 0, -1, -3, -11, -25, -42, -58, -66,
- -65, -59, -54, -51, -42, -27, -11, -2, -3, -6, -7, -7, -9, -16, -27, -36,
- -40, -44, -52, -63, -70, -66, -49, -28, -15, -13, -16, -16, -13, -16, -24, -31,
- -33, -29, -24, -19, -17, -19, -20, -18, -14, -13, -12, -6, 7, 22, 33, 35,
- 28, 18, 12, 12, 14, 17, 21, 27, 31, 31, 30, 30, 28, 25, 25, 30,
- 36, 42, 49, 58, 67, 74, 76, 75, 71, 66, 62, 60, 59, 53, 41, 29,
- 19, 14, 11, 7, 1, -3, -2, 1, 3, 3, 1, 0, 0, -3, -11, -26,
- -44, -59, -65, -63, -60, -57, -52, -41, -25, -11, -4, -4, -6, -6, -6, -9,
- -17, -27, -35, -39, -44, -53, -65, -71, -65, -47, -28, -16, -15, -16, -15, -14,
- -17, -25, -32, -33, -29, -24, -19, -17, -19, -20, -18, -14, -13, -12, -6, -2,
- 1, 6, 5, 21, 46, 42, 15, 0, 5, 34, 48, 29, -4, -31, -33, -17,
- 26, 49, 32, 0, -21, -15, 14, 24, 24, 16, 0, 3, 11, 11, 11, 5,
- 9, 9, 8, 11, 30, 27, 22, 7, -3, -3, 10, 2, -2, -4, -13, -4,
- -4, -2, -2, -3, -7, -6, -14, -15, -14, -14, -13, -3, -14, -16, -18, -13,
- -15, -16, -22, -20, -14, -3, -6, -4, -14, -11, -6, -10, -15, -15, -16, -9,
- -10, -19, -3, -5, -17, -15, -18, -16, -14, -14, -12, -15, -7, -22, -19, -17,
- -20, -11, -17, -14, -11, -8, -10, -13, -12, -11, -6, -6, -9, 1, 1, -3,
- 0, 6, -2, -9, 7, -8, 8, 4, 3, 1, -6, -2, -2, 2, -5, -7,
- -4, -7, -8, -9, -6, -6, 0, -8, -12, -12, -13, -8, -4, -7, -3, -11,
- -6, -15, -7, -9, -9, -3, -10, -8, -9, -15, -10, -2, 2, -7, -16, -17,
- -15, -13, -9, -6, -5, -7, -9, -15, -17, -12, -19, -12, -8, -8, -4, -6,
- -3, 0, -4, -11, -13, -7, -6, -2, 4, 4, 8, 10, 4, 3, 3, 4,
- 7, 12, 11, 14, 15, 20, 20, 18, 16, 17, 15, 14, 15, 22, 23, 28,
- 34, 29, 28, 17, 22, 24, 23, 25, 28, 28, 30, 24, 19, 16, 13, 18,
- 20, 15, 8, 2, 3, 0, 2, 0, -3, -2, -9, -20, -23, -25, -24, -23,
- -27, -33, -38, -39, -44, -36, -42, -44, -48, -53, -54, -56, -52, -50, -40, -35,
- -44, -43, -44, -39, -28, -24, -23, -22, -15, -9, 2, 11, 19, 28, 31, 31,
- 32, 35, 43, 61, 70, 78, 81, 73, 78, 78, 78, 85, 82, 85, 88, 87,
- 84, 83, 83, 79, 74, 62, 49, 45, 42, 43, 44, 38, 30, 18, 6, -5,
- -15, -17, -15, -22, -28, -38, -46, -48, -50, -58, -59, -72, -80, -83, -89, -88,
- -89, -87, -81, -84, -93, -105, -110, -109, -110, -102, -96, -82, -65, -62, -60, -60,
- -60, -51, -43, -37, -28, -16, 1, 15, 28, 35, 41, 46, 53, 56, 60, 66,
- 77, 91, 101, 102, 101, 99, 104, 103, 97, 91, 86, 90, 91, 86, 85, 79,
- 75, 71, 59, 48, 39, 35, 33, 32, 28, 22, 15, 13, 7, 3, -7, -15,
- -16, -18, -19, -23, -28, -29, -33, -37, -47, -52, -56, -63, -61, -70, -67, -70,
- -72, -72, -80, -93, -91, -99, -103, -96, -108, -105, -109, -112, -94, -81, -73, -67,
- -71, -77, -69, -63, -57, -38, -27, -15, 0, 4, 6, 19, 26, 41, 53, 49,
- 56, 58, 69, 84, 91, 95, 101, 103, 98, 93, 85, 87, 102, 102, 103, 95,
- 81, 78, 78, 71, 66, 60, 51, 50, 44, 39, 34, 34, 32, 27, 15, 0,
- -6, -8, -3, -3, -11, -10, -18, -21, -26, -35, -39, -38, -44, -48, -53, -63,
- -61, -61, -71, -63, -86, -89, -86, -107, -99, -109, -108, -109, -108, -121, -128, -105,
- -102, -83, -67, -88, -82, -76, -78, -62, -47, -41, -19, -6, 1, 7, 13, 33,
- 44, 64, 61, 59, 68, 73, 93, 98, 107, 114, 109, 123, 107, 100, 105, 100,
- 111, 117, 100, 93, 92, 86, 85, 80, 70, 59, 58, 47, 38, 41, 33, 40,
- 38, 25, 16, 1, -2, -3, -3, -4, -10, -16, -12, -21, -28, -28, -36, -38,
- -39, -52, -61, -61, -67, -63, -65, -76, -77, -86, -95, -95, -107, -109, -112, -112,
- -121, -121, -122, -105, -79, -80, -71, -80, -84, -73, -70, -56, -43, -28, -10, 6,
- 11, 17, 31, 43, 63, 69, 69, 65, 77, 88, 101, 113, 112, 127, 122, 122,
- 115, 104, 112, 116, 122, 117, 106, 99, 97, 96, 94, 86, 75, 70, 61, 53,
- 44, 41, 46, 47, 45, 28, 19, 9, 5, 9, 1, -8, -14, -20, -24, -26,
- -28, -29, -36, -39, -42, -45, -41, -42, -45, -46, -49, -47, -50, -55, -53, -61,
- -63, -67, -83, -78, -89, -91, -88, -100, -93, -108, -110, -110, -115, -90, -100, -91,
- -80, -91, -73, -62, -60, -41, -33, -36, -25, -16, -9, 8, 18, 35, 40, 57,
- 61, 66, 95, 94, 106, 114, 105, 117, 111, 117, 118, 115, 120, 111, 109, 111,
- 104, 102, 106, 93, 88, 76, 66, 63, 52, 53, 31, 27, 25, 5, 12, 1,
- -5, 0, -15, -17, -23, -27, -27, -31, -31, -37, -44, -41, -43, -43, -35, -45,
- -43, -41, -50, -49, -51, -57, -58, -62, -72, -76, -79, -81, -82, -86, -92, -94,
- -100, -109, -110, -102, -99, -96, -83, -96, -83, -67, -73, -45, -41, -42, -27, -27,
- -19, -5, 7, 14, 30, 44, 46, 57, 75, 84, 98, 108, 102, 112, 114, 110,
- 120, 115, 116, 117, 108, 112, 107, 104, 108, 99, 96, 90, 73, 69, 66, 57,
- 48, 36, 26, 18, 13, 6, -3, 3, -8, -14, -15, -26, -25, -26, -33, -33,
- -40, -45, -45, -45, -42, -43, -44, -45, -48, -46, -55, -57, -58, -62, -67, -73,
- -78, -80, -81, -82, -89, -93, -99, -106, -108, -115, -100, -95, -103, -77, -91, -85,
- -59, -63, -48, -32, -36, -33, -18, -14, -6, 11, 21, 27, 47, 55, 56, 81,
- 92, 96, 114, 106, 111, 116, 110, 121, 113, 115, 115, 105, 111, 106, 101, 103,
- 100, 92, 84, 74, 66, 60, 58, 43, 29, 29, 13, 9, 10, -6, -2, -6,
- -16, -18, -22, -27, -30, -30, -35, -44, -43, -46, -46, -42, -44, -48, -45, -46,
- -50, -54, -51, -61, -63, -61, -85, -76, -80, -94, -75, -98, -97, -93, -111, -103,
- -106, -97, -97, -90, -79, -93, -73, -64, -67, -39, -38, -41, -20, -20, -12, 11,
- 10, 30, 40, 48, 62, 62, 85, 91, 99, 111, 101, 112, 111, 113, 120, 112,
- 119, 111, 108, 114, 101, 102, 104, 89, 91, 79, 63, 67, 56, 52, 41, 29,
- 26, 12, 14, 3, -5, 1, -14, -15, -19, -27, -24, -30, -31, -34, -43, -43,
- -45, -48, -40, -48, -48, -45, -51, -49, -53, -56, -57, -63, -69, -76, -86, -80,
- -86, -90, -87, -98, -101, -101, -108, -103, -88, -96, -88, -77, -89, -70, -60, -56,
- -39, -34, -30, -26, -11, -4, 6, 26, 27, 42, 54, 57, 72, 86, 95, 105,
- 107, 108, 112, 109, 116, 118, 112, 117, 108, 109, 107, 104, 103, 99, 97, 83,
- 77, 71, 57, 60, 49, 35, 30, 21, 11, 11, 4, -2, -3, -13, -17, -22,
- -24, -28, -29, -29, -39, -39, -44, -44, -41, -45, -44, -50, -49, -49, -56, -50,
- -60, -62, -55, -82, -70, -82, -90, -80, -95, -95, -100, -105, -112, -112, -93, -102,
- -91, -81, -91, -77, -60, -65, -45, -33, -40, -25, -21, -14, 5, 10, 30, 35,
- 49, 61, 61, 87, 94, 102, 109, 109, 112, 112, 116, 117, 116, 118, 116, 106,
- 113, 108, 101, 110, 96, 91, 84, 69, 66, 58, 54, 38, 29, 26, 12, 11,
- 6, -2, -2, -8, -16, -20, -23, -27, -28, -33, -34, -44, -43, -43, -47, -39,
- -44, -47, -43, -47, -49, -50, -52, -57, -58, -68, -75, -76, -83, -86, -86, -91,
- -97, -98, -103, -109, -102, -91, -99, -84, -81, -93, -65, -66, -60, -37, -42, -33,
- -25, -18, -9, 6, 16, 28, 41, 49, 57, 68, 84, 93, 102, 106, 106, 110,
- 107, 116, 114, 111, 119, 106, 111, 108, 101, 104, 99, 94, 85, 76, 68, 61,
- 56, 49, 34, 28, 21, 10, 10, 2, -3, -3, -13, -15, -24, -26, -28, -34,
- -31, -42, -45, -43, -48, -44, -43, -47, -47, -47, -48, -51, -57, -57, -63, -70,
- -72, -80, -86, -81, -92, -88, -96, -103, -100, -113, -110, -96, -101, -96, -79, -91,
- -82, -59, -68, -47, -34, -39, -29, -18, -13, -5, 18, 22, 32, 54, 52, 64,
- 83, 90, 100, 108, 109, 110, 113, 113, 116, 113, 117, 113, 106, 111, 103, 100,
- 101, 98, 86, 82, 73, 59, 61, 53, 36, 34, 24, 12, 10, 5, -5, -3,
- -8, -17, -18, -24, -27, -29, -30, -35, -40, -41, -45, -43, -43, -42, -45, -46,
- -44, -50, -49, -55, -58, -55, -71, -70, -79, -87, -77, -92, -88, -95, -104, -100,
- -115, -107, -91, -105, -85, -83, -97, -67, -68, -65, -37, -43, -33, -29, -21, -9,
- 0, 18, 23, 35, 55, 48, 69, 87, 86, 108, 107, 103, 117, 106, 117, 118,
- 113, 122, 109, 111, 111, 102, 110, 101, 98, 92, 77, 73, 62, 59, 54, 34,
- 34, 21, 11, 15, 2, 2, 2, -14, -12, -23, -26, -26, -33, -30, -40, -44,
- -42, -49, -41, -41, -44, -43, -46, -49, -51, -59, -54, -63, -67, -64, -84, -79,
- -76, -91, -82, -87, -100, -100, -101, -118, -101, -89, -107, -81, -82, -93, -65, -57,
- -57, -36, -26, -39, -17, -9, -13, 14, 21, 26, 45, 53, 54, 76, 88, 95,
- 111, 106, 111, 114, 109, 120, 115, 115, 116, 110, 105, 109, 104, 98, 105, 94,
- 83, 81, 68, 60, 62, 49, 32, 33, 18, 9, 12, 0, -3, -3, -13, -18,
- -20, -24, -27, -26, -31, -37, -40, -42, -42, -43, -42, -44, -48, -48, -47, -51,
- -54, -52, -56, -64, -68, -75, -84, -79, -89, -91, -93, -104, -105, -110, -114, -97,
- -97, -96, -78, -89, -81, -58, -66, -47, -34, -40, -31, -23, -14, -6, 14, 22,
- 31, 54, 55, 63, 87, 91, 103, 113, 105, 111, 113, 109, 119, 112, 117, 114,
- 106, 113, 106, 105, 105, 99, 93, 81, 74, 61, 58, 55, 36, 30, 25, 10,
- 11, 6, -5, 1, -8, -16, -19, -25, -27, -32, -32, -37, -44, -41, -47, -43,
- -39, -43, -44, -45, -46, -46, -56, -53, -55, -72, -64, -74, -91, -72, -88, -97,
- -80, -100, -105, -100, -111, -111, -88, -100, -99, -74, -97, -79, -54, -68, -43, -32,
- -41, -26, -10, -16, 6, 22, 19, 41, 51, 49, 69, 86, 88, 103, 107, 100,
- 119, 110, 111, 125, 110, 115, 115, 104, 108, 106, 99, 98, 98, 82, 76, 71,
- 60, 60, 52, 34, 30, 25, 9, 11, 3, -6, 0, -15, -18, -21, -27, -27,
- -30, -31, -38, -39, -43, -43, -39, -43, -44, -46, -47, -47, -54, -53, -59, -58,
- -65, -71, -75, -81, -75, -90, -83, -90, -100, -95, -111, -109, -101, -97, -100, -84,
- -86, -89, -62, -64, -50, -34, -37, -30, -21, -11, -8, 10, 19, 26, 47, 49,
- 59, 76, 89, 99, 107, 109, 110, 115, 113, 119, 115, 114, 115, 106, 111, 103,
- 103, 101, 98, 94, 81, 78, 65, 63, 59, 43, 34, 25, 17, 10, 7, -4,
- -3, -6, -14, -16, -23, -24, -28, -29, -33, -41, -41, -46, -43, -40, -44, -44,
- -46, -46, -47, -50, -54, -56, -58, -69, -70, -76, -83, -75, -87, -87, -91, -100,
- -100, -109, -108, -97, -98, -93, -83, -88, -76, -61, -59, -43, -36, -33, -28, -18,
- -11, -4, 14, 21, 31, 52, 51, 63, 84, 90, 101, 111, 104, 113, 113, 111,
- 118, 112, 114, 109, 108, 109, 102, 106, 101, 98, 94, 79, 74, 66, 58, 55,
- 39, 29, 24, 13, 11, 5, -4, 0, -10, -15, -17, -24, -25, -28, -29, -34,
- -41, -41, -47, -42, -44, -46, -45, -50, -45, -50, -55, -48, -60, -60, -65, -76,
- -77, -83, -84, -91, -92, -94, -106, -103, -109, -106, -89, -101, -82, -81, -88, -63,
- -66, -54, -36, -40, -31, -25, -16, -7, 6, 17, 30, 41, 55, 56, 73, 89,
- 92, 109, 104, 106, 114, 104, 117, 113, 110, 116, 105, 108, 106, 100, 102, 98,
- 94, 85, 74, 67, 59, 55, 48, 31, 28, 19, 10, 12, 0, 2, -2, -11,
- -11, -21, -21, -26, -30, -30, -40, -43, -43, -44, -40, -39, -41, -43, -42, -46,
- -52, -52, -58, -63, -65, -75, -79, -83, -80, -89, -85, -88, -101, -94, -104, -114,
- -93, -97, -104, -78, -92, -89, -60, -68, -48, -36, -36, -26, -21, -8, -5, 12,
- 23, 26, 47, 50, 54, 77, 85, 96, 109, 102, 114, 112, 109, 125, 112, 114,
- 118, 102, 110, 103, 99, 101, 96, 92, 79, 76, 66, 59, 61, 43, 32, 31,
- 14, 10, 9, -5, -2, -9, -17, -18, -28, -25, -31, -31, -31, -42, -38, -43,
- -41, -39, -43, -44, -47, -45, -48, -51, -53, -54, -61, -64, -67, -77, -76, -82,
- -81, -89, -93, -97, -106, -108, -105, -96, -99, -88, -82, -92, -67, -64, -60, -38,
- -38, -36, -24, -20, -16, 4, 11, 21, 36, 46, 53, 66, 85, 88, 103, 108,
- 102, 115, 107, 112, 115, 109, 114, 104, 106, 106, 99, 102, 101, 92, 89, 81,
- 67, 66, 58, 47, 39, 28, 21, 11, 12, 2, -2, 2, -12, -12, -17, -25,
- -24, -29, -30, -36, -39, -41, -41, -41, -39, -41, -44, -44, -47, -51, -52, -54,
- -59, -63, -65, -75, -79, -75, -90, -81, -89, -99, -92, -109, -109, -105, -99, -97,
- -92, -80, -90, -71, -58, -60, -37, -32, -37, -19, -15, -14, 9, 14, 23, 42,
- 46, 56, 67, 83, 96, 100, 111, 106, 111, 114, 111, 117, 111, 112, 109, 103,
- 107, 100, 99, 103, 92, 88, 82, 65, 66, 59, 48, 39, 27, 22, 12, 9,
- 5, -5, 0, -12, -16, -17, -26, -25, -26, -31, -34, -40, -41, -41, -41, -40,
- -42, -47, -43, -46, -46, -52, -50, -52, -61, -59, -74, -75, -77, -83, -84, -91,
- -92, -105, -100, -106, -109, -81, -103, -86, -73, -96, -64, -62, -59, -38, -39, -36,
- -28, -15, -11, 3, 18, 25, 37, 53, 53, 67, 89, 85, 106, 103, 98, 115,
- 99, 114, 115, 103, 116, 103, 104, 109, 98, 101, 98, 91, 84, 75, 67, 60,
- 55, 50, 31, 28, 20, 7, 15, 0, -3, 2, -15, -12, -19, -25, -24, -32,
- -32, -38, -44, -44, -45, -42, -41, -44, -43, -46, -44, -44, -58, -48, -63, -67,
- -63, -87, -75, -83, -90, -81, -94, -95, -95, -107, -109, -99, -95, -99, -85, -85,
- -90, -68, -62, -60, -36, -34, -39, -15, -13, -9, 14, 15, 29, 42, 50, 55,
- 68, 87, 91, 101, 107, 106, 110, 113, 114, 115, 114, 112, 108, 105, 106, 98,
- 98, 100, 88, 84, 75, 63, 63, 57, 46, 34, 28, 18, 10, 8, 0, -5,
- -5, -15, -19, -20, -26, -26, -26, -31, -36, -40, -42, -43, -42, -39, -44, -44,
- -42, -44, -47, -51, -52, -54, -65, -63, -76, -81, -68, -93, -84, -85, -104, -92,
- -105, -109, -95, -95, -96, -84, -82, -84, -64, -64, -52, -39, -37, -33, -23, -11,
- -9, 10, 20, 25, 49, 46, 60, 76, 82, 98, 101, 104, 110, 108, 108, 116,
- 111, 111, 113, 104, 108, 106, 101, 98, 99, 92, 80, 79, 63, 61, 59, 41,
- 35, 27, 18, 13, 9, 2, 0, -5, -12, -15, -20, -22, -26, -27, -30, -38,
- -39, -42, -40, -39, -40, -40, -45, -43, -47, -49, -54, -53, -57, -70, -59, -80,
- -77, -72, -93, -75, -91, -99, -93, -105, -108, -97, -92, -99, -80, -84, -84, -61,
- -59, -49, -35, -28, -34, -14, -9, -10, 19, 17, 27, 47, 47, 61, 72, 87,
- 95, 105, 104, 110, 111, 109, 117, 109, 111, 109, 103, 103, 102, 97, 95, 100,
- 85, 81, 77, 61, 64, 55, 42, 34, 26, 17, 10, 9, -3, -2, -5, -13,
- -15, -20, -23, -27, -27, -32, -37, -38, -41, -40, -41, -39, -43, -43, -40, -48,
- -47, -49, -55, -61, -59, -70, -80, -69, -87, -83, -79, -97, -89, -98, -101, -107,
- -96, -93, -101, -77, -90, -84, -62, -63, -49, -36, -34, -30, -15, -12, -2, 11,
- 20, 32, 39, 53, 56, 71, 87, 89, 103, 101, 109, 109, 109, 118, 106, 114,
- 111, 101, 107, 102, 93, 99, 94, 84, 85, 71, 65, 62, 54, 45, 32, 30,
- 16, 12, 8, -5, -2, -9, -14, -16, -24, -22, -27, -29, -31, -38, -41, -38,
- -44, -42, -41, -47, -45, -44, -48, -50, -50, -52, -62, -57, -69, -79, -69, -83,
- -88, -78, -99, -97, -92, -109, -106, -91, -100, -93, -76, -91, -80, -60, -66, -48,
- -37, -38, -32, -18, -15, -4, 11, 14, 31, 42, 48, 60, 69, 85, 94, 96,
- 102, 107, 103, 109, 115, 104, 112, 109, 100, 106, 103, 95, 97, 96, 84, 82,
- 73, 60, 62, 54, 41, 33, 27, 17, 14, 7, 0, 0, -8, -11, -16, -23,
- -23, -29, -29, -32, -39, -40, -40, -40, -41, -40, -46, -48, -45, -50, -51, -54,
- -56, -64, -63, -71, -78, -73, -84, -82, -87, -95, -93, -102, -102, -108, -95, -96,
- -95, -76, -90, -77, -57, -61, -42, -33, -35, -26, -13, -14, 3, 15, 17, 36,
- 45, 54, 60, 80, 89, 96, 108, 101, 111, 110, 109, 118, 107, 110, 109, 102,
- 103, 103, 95, 97, 96, 83, 82, 70, 60, 61, 51, 38, 28, 23, 11, 8,
- 4, -7, -3, -10, -16, -17, -22, -25, -27, -29, -35, -38, -43, -42, -41, -40,
- -39, -43, -42, -44, -45, -46, -53, -51, -55, -68, -65, -75, -79, -77, -88, -83,
- -94, -93, -101, -105, -96, -96, -92, -85, -85, -83, -71, -64, -57, -41, -41, -31,
- -27, -17, -7, 2, 18, 23, 38, 48, 51, 68, 78, 91, 98, 102, 106, 108,
- 110, 112, 115, 110, 115, 107, 107, 108, 99, 102, 97, 94, 87, 76, 70, 63,
- 60, 49, 39, 30, 22, 16, 8, 4, 0, -4, -10, -14, -20, -24, -25, -31,
- -30, -37, -41, -40, -41, -38, -39, -40, -42, -41, -43, -48, -44, -55, -58, -57,
- -71, -71, -73, -78, -79, -80, -88, -89, -95, -99, -103, -101, -88, -98, -85, -79,
- -90, -62, -60, -54, -35, -35, -27, -21, -9, -3, 7, 22, 26, 38, 52, 54,
- 67, 87, 89, 101, 105, 103, 114, 107, 117, 112, 107, 116, 100, 105, 103, 94,
- 98, 93, 87, 80, 73, 65, 59, 56, 45, 31, 28, 19, 6, 10, -3, -5,
- -4, -17, -16, -22, -24, -25, -30, -28, -39, -37, -40, -44, -40, -44, -46, -46,
- -47, -51, -50, -55, -55, -60, -67, -65, -81, -75, -78, -93, -78, -97, -101, -94,
- -113, -104, -92, -96, -91, -79, -86, -79, -58, -58, -49, -34, -34, -33, -14, -12,
- -5, 20, 19, 34, 49, 49, 66, 76, 91, 98, 98, 105, 104, 107, 111, 110,
- 109, 108, 108, 103, 101, 102, 97, 95, 96, 80, 75, 71, 56, 58, 49, 33,
- 28, 20, 13, 7, 4, -4, -7, -9, -18, -22, -22, -28, -30, -30, -38, -41,
- -41, -43, -40, -41, -40, -44, -43, -45, -48, -49, -55, -55, -59, -67, -66, -82,
- -70, -81, -86, -78, -101, -92, -98, -111, -98, -95, -95, -89, -76, -91, -70, -56,
- -61, -38, -34, -33, -25, -12, -10, 1, 21, 15, 39, 47, 48, 68, 75, 90,
- 97, 101, 103, 106, 106, 110, 111, 104, 111, 101, 99, 103, 96, 94, 95, 92,
- 75, 79, 64, 55, 64, 43, 36, 30, 17, 13, 9, 3, -4, -3, -12, -16,
- -18, -23, -25, -26, -29, -35, -38, -42, -40, -39, -41, -38, -48, -42, -45, -50,
- -49, -52, -57, -63, -57, -78, -76, -67, -94, -75, -88, -100, -92, -103, -106, -97,
- -88, -96, -81, -77, -85, -60, -55, -51, -35, -30, -33, -19, -9, -10, 17, 16,
- 30, 46, 48, 64, 72, 86, 96, 101, 104, 105, 111, 104, 116, 109, 107, 110,
- 104, 101, 104, 100, 93, 100, 86, 77, 78, 59, 60, 54, 40, 32, 23, 18,
- 9, 9, 0, -5, -6, -14, -17, -20, -23, -25, -26, -31, -35, -39, -40, -36,
- -40, -37, -40, -45, -42, -45, -48, -51, -50, -57, -64, -62, -76, -78, -71, -90,
- -84, -88, -101, -97, -105, -108, -94, -97, -92, -81, -87, -76, -63, -58, -42, -36,
- -33, -27, -15, -10, -2, 18, 19, 34, 49, 47, 66, 78, 86, 102, 104, 104,
- 111, 109, 112, 115, 112, 110, 108, 106, 101, 102, 98, 96, 97, 86, 79, 72,
- 62, 61, 51, 39, 32, 20, 15, 10, 2, 1, -4, -9, -13, -18, -22, -24,
- -25, -29, -33, -37, -41, -39, -37, -39, -39, -43, -46, -46, -49, -49, -56, -54,
- -57, -68, -66, -73, -77, -79, -83, -90, -96, -95, -107, -110, -98, -97, -98, -76,
- -87, -83, -56, -68, -49, -34, -43, -28, -26, -18, -8, 3, 14, 22, 39, 47,
- 54, 70, 83, 90, 101, 100, 104, 107, 102, 113, 103, 106, 109, 95, 106, 99,
- 95, 101, 92, 93, 83, 74, 66, 60, 56, 44, 33, 26, 17, 12, 8, 1,
- 2, -4, -11, -10, -21, -19, -25, -29, -28, -39, -38, -41, -41, -37, -40, -42,
- -43, -42, -45, -47, -48, -56, -52, -59, -69, -67, -78, -78, -79, -88, -86, -95,
- -100, -99, -112, -95, -92, -101, -77, -86, -86, -62, -65, -51, -39, -35, -31, -26,
- -8, -11, 7, 26, 21, 45, 53, 50, 76, 86, 90, 105, 102, 105, 109, 108,
- 115, 107, 112, 110, 100, 108, 100, 96, 100, 93, 89, 79, 72, 64, 58, 56,
- 42, 31, 28, 14, 10, 9, -5, -2, -6, -14, -15, -22, -22, -27, -28, -31,
- -41, -37, -41, -42, -37, -41, -45, -43, -45, -47, -48, -49, -58, -53, -64, -71,
- -68, -82, -75, -83, -91, -87, -103, -97, -104, -111, -90, -98, -95, -77, -91, -76,
- -61, -63, -43, -41, -35, -29, -23, -7, -7, 13, 22, 24, 50, 50, 59, 82,
- 82, 99, 102, 100, 110, 105, 111, 113, 104, 114, 103, 104, 107, 96, 102, 97,
- 92, 90, 77, 73, 64, 58, 53, 38, 31, 23, 13, 12, 3, 0, -2, -11,
- -10, -17, -21, -20, -29, -27, -33, -40, -38, -44, -39, -39, -43, -41, -42, -42,
- -46, -42, -53, -53, -52, -71, -67, -73, -83, -80, -81, -89, -93, -91, -100, -106,
- -97, -96, -93, -88, -81, -85, -79, -59, -58, -48, -30, -36, -28, -11, -9, -2,
- 21, 22, 32, 50, 52, 58, 79, 89, 90, 104, 104, 100, 113, 111, 109, 114,
- 109, 107, 103, 104, 99, 94, 97, 91, 78, 79, 65, 58, 61, 47, 37, 30,
- 23, 14, 10, 7, -7, -4, -8, -21, -17, -23, -30, -26, -30, -36, -37, -39,
- -38, -38, -36, -38, -45, -41, -45, -49, -51, -56, -57, -63, -64, -69, -78, -70,
- -80, -84, -84, -91, -100, -98, -106, -108, -90, -103, -90, -80, -93, -65, -64, -52,
- -38, -37, -27, -26, -12, -6, 3, 18, 22, 36, 48, 54, 69, 84, 89, 105,
- 103, 106, 117, 105, 117, 113, 106, 113, 101, 105, 101, 99, 98, 93, 94, 83,
- 75, 70, 60, 55, 49, 33, 27, 19, 10, 8, -2, -2, -7, -13, -12, -22,
- -20, -23, -28, -28, -35, -39, -40, -41, -40, -42, -40, -43, -42, -42, -44, -46,
- -49, -52, -59, -60, -70, -74, -71, -84, -82, -88, -96, -98, -100, -105, -102, -88,
- -95, -83, -79, -87, -62, -62, -52, -40, -39, -31, -27, -14, -10, 7, 17, 25,
- 42, 49, 59, 72, 85, 92, 103, 103, 102, 111, 104, 113, 110, 104, 112, 102,
- 107, 103, 101, 99, 97, 92, 81, 76, 64, 61, 54, 42, 33, 24, 17, 11,
- 8, -2, -2, -5, -13, -12, -22, -23, -26, -31, -32, -38, -40, -43, -39, -40,
- -41, -40, -44, -41, -44, -47, -51, -49, -62, -55, -68, -78, -68, -89, -79, -81,
- -96, -85, -101, -100, -103, -98, -91, -97, -79, -83, -87, -61, -64, -55, -31, -41,
- -29, -15, -19, 3, 9, 18, 33, 36, 56, 54, 71, 87, 87, 103, 103, 103,
- 110, 107, 113, 112, 108, 111, 101, 104, 103, 92, 101, 92, 84, 84, 66, 65,
- 59, 51, 45, 31, 27, 16, 10, 6, -3, -3, -9, -15, -16, -22, -24, -25,
- -30, -28, -36, -40, -36, -42, -38, -41, -45, -44, -47, -47, -49, -51, -52, -54,
- -62, -68, -73, -78, -81, -84, -83, -97, -94, -101, -113, -100, -99, -96, -87, -83,
- -85, -75, -60, -60, -43, -36, -38, -27, -20, -15, 0, 14, 19, 33, 47, 49,
- 67, 78, 90, 100, 103, 105, 107, 108, 110, 112, 109, 109, 107, 102, 105, 100,
- 99, 98, 95, 84, 80, 69, 59, 60, 48, 36, 31, 18, 14, 9, 3, -2,
- -5, -10, -15, -19, -24, -25, -28, -31, -34, -39, -41, -40, -38, -40, -38, -43,
- -43, -42, -48, -47, -53, -54, -58, -67, -63, -79, -73, -78, -90, -80, -98, -97,
- -101, -109, -105, -93, -98, -90, -76, -93, -66, -60, -59, -33, -42, -32, -26, -18,
- -9, 0, 17, 21, 38, 48, 53, 69, 82, 93, 101, 107, 102, 112, 108, 111,
- 115, 105, 112, 103, 105, 104, 96, 103, 95, 95, 85, 76, 68, 63, 59, 47,
- 38, 26, 19, 13, 7, 1, -3, -4, -14, -12, -19, -23, -21, -29, -29, -35,
- -40, -41, -42, -39, -43, -42, -46, -43, -47, -45, -48, -54, -47, -66, -61, -68,
- -85, -66, -90, -84, -84, -103, -91, -106, -105, -96, -90, -92, -81, -79, -86, -59,
- -59, -53, -34, -36, -33, -19, -10, -10, 17, 20, 26, 52, 48, 60, 75, 85,
- 95, 102, 104, 102, 111, 107, 113, 110, 109, 111, 103, 107, 102, 97, 96, 95,
- 85, 77, 73, 56, 60, 52, 37, 33, 22, 16, 11, 7, -3, -4, -6, -16,
- -14, -21, -24, -24, -28, -32, -37, -38, -42, -36, -37, -39, -39, -43, -40, -42,
- -48, -50, -50, -64, -57, -70, -84, -63, -90, -81, -77, -101, -85, -99, -105, -102,
- -100, -92, -99, -79, -89, -86, -58, -65, -49, -29, -41, -26, -11, -19, 6, 12,
- 14, 39, 37, 52, 60, 68, 90, 90, 104, 102, 106, 111, 108, 118, 109, 109,
- 111, 98, 106, 101, 90, 101, 90, 82, 86, 63, 65, 63, 48, 47, 29, 25,
- 16, 10, 6, -6, -3, -13, -18, -16, -26, -25, -25, -32, -30, -39, -43, -37,
- -43, -39, -39, -48, -44, -46, -53, -50, -56, -59, -59, -67, -72, -77, -76, -84,
- -83, -84, -100, -95, -103, -115, -98, -93, -103, -82, -82, -91, -60, -62, -54, -34,
- -35, -31, -23, -13, -11, 7, 19, 21, 43, 48, 55, 73, 85, 94, 104, 102,
- 109, 110, 105, 118, 107, 109, 113, 98, 106, 103, 96, 99, 98, 90, 82, 79,
- 62, 62, 58, 41, 34, 26, 14, 10, 8, -3, -2, -5, -14, -13, -20, -20,
- -24, -26, -28, -38, -39, -42, -42, -41, -41, -42, -48, -41, -43, -50, -41, -49,
- -59, -50, -68, -74, -67, -82, -80, -89, -87, -101, -101, -93, -121, -85, -90, -105,
- -65, -93, -82, -55, -69, -49, -38, -46, -32, -27, -19, -5, 3, 19, 26, 41,
- 53, 52, 81, 81, 95, 104, 90, 113, 101, 105, 118, 99, 113, 109, 100, 109,
- 104, 98, 104, 96, 89, 83, 71, 66, 57, 56, 38, 28, 29, 8, 17, 6,
- -2, 3, -24, -13, -79, -103, -120, -116, -104, -87, -76, -63, 63, 82, 97, 108,
- 119, 99, 70, 69, 80, 91, 92, 98, 115, 124, 127, 113, 82, 42, 4, -44,
- -70, -82, -100, -87, -62, -58, -71, -65, -79, -60, -102, -113, -62, -44, -31, -31,
- -22, -18, -3, 4, 11, 20, 28, 11, 15, 18, 27, 18, 7, 13, 26, 11,
- -19, -69, -108, -84, -51, -21, -3, -6, -18, -17, -31, -33, -18, 2, 4, 26,
- 47, 48, 77, 117, 127, 127, 127, 121, 110, 86, 72, 62, 46, 11, 17, -2,
- -7, -13, -44, -60, -61, -61, -63, -72, -79, -99, -116, -127, -128, -128, -124, -81,
- -51, -4, 5, -6, 7, 8, 9, 31, 31, 16, 34, 28, 34, 34, 46, 78,
- 84, 93, 69, 47, 40, 64, 44, 27, 22, 0, -29, -8, 15, -6, -36, -66,
- -68, -42, 0, 6, 1, 13, 24, 41, 64, 58, 50, 40, 4, 0, 3, -24,
- -3, 21, 28, 26, 9, -30, -42, -61, -85, -92, -91, -96, -87, -74, -31, -20,
- -38, -14, -44, -17, 18, -25, -9, 7, 1, 11, -2, -19, 12, 47, 76, 72,
- 58, 68, 69, 82, 86, 76, 58, 9, -23, -12, -7, -22, -2, 0, -9, -2,
- -15, -10, -3, -22, -17, -38, -44, -33, -24, -27, -16, 0, -15, 20, 19, 18,
- 1, 10, 41, -1, -25, -25, -11, 30, 37, 9, 45, 37, -30, -30, 21, 5,
- -26, -43, -56, -42, -48, -48, -29, -62, -76, -42, -23, -12, -14, 8, 45, 36,
- 40, 25, 14, 11, 40, 46, 55, 65, 30, 17, 30, 36, 33, 18, 13, 16,
- 15, 46, 37, 2, -1, -26, -36, -19, -21, -36, -62, -51, -48, -20, -2, 3,
- -12, -12, -10, -35, -37, -49, -22, 14, 61, 40, 60, 75, 33, 41, 48, 38,
- 29, -32, -45, -56, -64, -61, -30, -20, 30, 10, -46, -37, -35, -30, -24, -12,
- -23, -34, -29, -22, -20, -14, 4, 44, 77, 49, 10, 8, 24, 20, 28, 31,
- 27, 40, 35, 69, 39, 54, 38, 26, 22, 43, 36, 7, 14, 2, -25, -50,
- -51, -56, -42, -55, -46, -36, -44, -36, -35, 1, 23, 11, -3, -34, -66, -33,
- -12, -31, -27, -13, -1, 21, 31, 23, 0, -11, -3, -2, 9, 27, 5, -8,
- -2, -17, -13, 10, 9, 3, 35, 32, 43, 24, 15, 2, -15, -9, -5, 2,
- 5, 27, 25, 42, 76, 61, 17, 25, 14, -5, -17, -24, -6, 11, 23, 7,
- -8, 5, -11, -23, -27, -48, -30, -12, -26, -36, -37, -39, -46, -61, -55, -23,
- -20, -22, -14, -10, -16, -16, -22, -11, -3, -14, -34, -16, 9, 28, 25, 50,
- 63, 52, 56, 46, 50, 54, 56, 45, 54, 29, 20, 21, 0, 0, 6, 16,
- 28, 14, -1, -9, -10, -4, -9, -13, -7, -21, -27, -29, -40, -41, -35, -42,
- -64, -11, 9, 2, -12, -24, -37, -40, -34, -29, -34, -12, -26, -20, -6, -4,
- 5, 5, 27, 1, -17, 2, 21, 12, 8, 9, 15, 23, 24, 1, 5, 22,
- 25, 28, 57, 55, 41, 33, 36, 27, 5, 1, 15, 34, 23, 4, 20, 18,
- -1, -21, -22, -15, -17, -8, -6, -6, -12, -15, -26, 1, 29, -8, -40, -52,
- -55, -19, -21, -36, -48, -56, -29, -15, -29, -39, -46, -35, -14, -11, -16, 1,
- 27, 22, -10, -14, -7, -12, -12, 23, 55, 48, 65, 42, 20, 46, 45, 49,
- 42, 38, 34, 25, 33, 21, 10, 38, 40, 26, 22, 37, 33, 12, 4, 7,
- -14, -49, -41, -36, -53, -40, -35, -44, -31, -22, -19, -50, -78, -80, -78, -48,
- -31, -18, -27, -28, -7, -17, -11, 5, 32, 39, 19, 14, 22, 34, 37, 23,
- 20, 40, 40, 27, 14, 11, 7, 29, 34, 19, 32, 7, -15, -12, -24, -12,
- 8, 6, 21, 34, 29, -6, -22, -15, 1, -1, 24, 27, 20, 36, 42, 45,
- 27, -14, -50, -34, -14, -26, -25, -10, 10, -4, -28, -30, -34, -69, -91, -85,
- -74, -51, -38, -24, -19, -9, -7, -30, -35, -30, -36, -12, 25, 32, 44, 50,
- 45, 51, 68, 94, 90, 74, 60, 52, 64, 48, 30, 11, 11, 11, 2, 14,
- 24, 16, 13, -7, -17, -9, -12, -20, -32, -45, -54, -58, -35, -23, -46, -51,
- -33, -28, -29, -24, -36, -30, -24, -22, -20, -13, -9, -14, -7, 10, 26, 22,
- 9, 9, 10, -2, -9, -15, -11, -1, 19, 27, 33, 28, 5, 3, 5, 6,
- 10, 14, 24, 32, 36, 40, 41, 37, 19, 11, 3, -7, -10, -7, 6, 27,
- 38, 28, 23, 16, 18, 15, -7, -33, -20, -13, -24, -25, -19, -15, -26, -52,
- -56, -48, -41, -36, -30, -32, -30, -15, -38, -49, -47, -32, -17, -17, -11, -3,
- 3, 8, 24, 28, 16, 6, 1, 7, 28, 41, 42, 69, 87, 78, 73, 62,
- 30, 14, 9, 7, 15, 32, 20, 10, -8, -20, 2, 9, -2, 5, 12, -4,
- -12, -19, -32, -37, -29, -24, -28, -39, -43, -40, -44, -28, -25, -33, -39, -37,
- -34, -29, -28, -25, -19, -1, -5, -22, -12, 2, 6, 38, 46, 25, 30, 41,
- 47, 37, 21, 7, -7, -8, 11, 39, 48, 43, 35, 27, 25, 22, -1, -22,
- -11, 13, -4, -13, -3, -8, -7, -11, -17, -5, 5, 9, 8, 15, 25, 16,
- 22, 20, 5, -16, -27, -29, -30, -9, 9, 9, 3, -14, -50, -56, -56, -79,
- -92, -80, -57, -24, 12, 10, 11, 4, -22, -21, -13, -2, 4, 10, 15, 8,
- 35, 72, 53, 44, 25, 25, 48, 56, 69, 53, 50, 75, 85, 71, 33, 12,
- -16, -32, -25, -14, -5, -16, -23, -19, -22, -39, -41, -47, -45, -33, -35, -39,
- -38, -35, -34, -29, -28, -28, -23, -10, -7, -9, -11, -18, -5, 13, 1, -13,
- -8, -5, 6, 27, 46, 43, 25, 8, 11, 16, 18, 23, 30, 12, 5, 10,
- 7, 5, -6, -4, -5, 1, 10, 9, 15, 21, 17, 10, -8, -16, 10, 33,
- 34, 23, 13, 17, 17, 9, 11, 7, -4, -8, -8, -22, -27, -26, -19, -7,
- -18, -16, -16, -47, -62, -55, -36, -16, -25, -33, -30, -34, -42, -49, -41, -43,
- -31, -20, -3, 28, 48, 66, 64, 36, 20, 26, 21, 22, 39, 51, 45, 39,
- 40, 53, 56, 39, 24, 16, 12, 16, 24, 27, 16, 13, 7, -18, -33, -50,
- -47, -33, -24, -20, -26, -32, -31, -46, -53, -58, -56, -29, -13, -11, -2, 8,
- -11, -24, -11, -9, -6, -2, -6, 1, 4, 5, 11, 6, 7, 16, 30, 28,
- 19, 15, 7, 4, 11, 27, 22, 6, 9, 11, 3, 4, 17, 27, 18, 11,
- 12, 5, 2, -2, -6, -7, -2, 10, 12, 9, 1, -2, 3, 4, 11, 21,
- 30, 28, 6, -9, -18, -22, -22, -38, -41, -27, -18, -18, -27, -27, -23, -32,
- -35, -32, -34, -30, -25, -24, -18, -9, -5, 5, -5, -26, -19, -11, -4, 11,
- 37, 48, 46, 50, 53, 50, 45, 45, 37, 18, 24, 44, 38, 43, 47, 29,
- 15, 11, 10, 12, 4, -8, -6, -4, -17, -27, -28, -36, -34, -37, -53, -53,
- -46, -38, -38, -37, -28, -24, -23, -37, -42, -30, 0, 20, 18, 12, 14, 9,
- 2, 6, 15, 13, 10, 14, 12, 2, 12, 29, 21, 1, 7, 21, 19, 14,
- 15, 15, 4, -1, 5, -1, -4, 0, -2, 3, 6, 6, 13, 21, 15, 7,
- 3, 5, 2, -3, 3, 3, 5, 8, 10, 16, 14, -1, -7, 2, 11, 12,
- -10, -35, -42, -26, -21, -37, -44, -44, -47, -42, -27, -27, -23, -15, -16, -20,
- -21, -14, -12, -9, -7, -6, 0, 13, 30, 32, 37, 38, 31, 24, 25, 43,
- 54, 49, 46, 44, 40, 41, 30, 9, -1, 6, 22, 31, 22, 9, 0, -14,
- -23, -29, -29, -28, -35, -39, -39, -39, -33, -25, -30, -44, -49, -45, -45, -35,
- -19, 2, 16, 16, 9, 0, 0, 6, 2, -1, 11, 27, 40, 32, 16, -2,
- -2, 1, 3, 1, 7, 12, 6, 8, 11, 5, -1, -2, -1, 1, 8, 10,
- 5, 4, 14, 17, 6, -1, 0, 4, 4, 17, 23, 19, 25, 20, 5, -8,
- -9, -2, -1, -6, -3, 13, 16, 1, -13, -19, -21, -26, -34, -37, -23, -13,
- -13, -24, -40, -42, -40, -39, -29, -22, -21, -18, -12, -2, 18, 24, 10, 0,
- -6, -4, 15, 33, 34, 34, 44, 41, 31, 33, 44, 43, 31, 22, 20, 17,
- 16, 23, 22, 19, 21, 10, -5, -6, -9, -8, -2, -5, -16, -28, -36, -47,
- -53, -39, -23, -21, -24, -32, -43, -39, -34, -24, -18, -14, -11, -12, -6, 10,
- 29, 41, 40, 27, 14, 10, 4, 1, 3, 2, 9, 19, 21, 9, -10, -16,
- -10, 8, 18, 20, 13, -3, -8, -4, -1, 2, 5, 5, -1, 3, 9, 12,
- 16, 16, 14, 9, 3, 5, 10, 4, -6, 1, 6, 5, 13, 20, 11, 1,
- -7, -21, -30, -25, -12, -9, -13, -19, -24, -29, -34, -30, -32, -39, -33, -24,
- -20, -22, -24, -13, 3, 6, 2, 1, 3, 5, 16, 30, 35, 35, 24, 16,
- 15, 19, 31, 37, 33, 28, 29, 29, 30, 26, 20, 15, 13, 10, 10, 12,
- 9, 7, -3, -21, -39, -44, -43, -42, -34, -26, -23, -18, -12, -18, -32, -36,
- -31, -27, -20, -10, -7, -9, -11, -5, 2, 12, 19, 19, 25, 24, 11, 3,
- 15, 29, 30, 20, 9, 1, -1, 1, 5, 2, -3, -2, 0, -6, -18, -27,
- -20, -3, 8, 13, 15, 11, 7, 10, 18, 16, 10, 6, 3, -1, 1, 11,
- 19, 19, 15, 14, 5, -2, -2, -7, -12, -15, -20, -16, -10, -5, 2, 1,
- -13, -29, -33, -24, -10, -6, -13, -18, -23, -31, -32, -26, -22, -18, -13, -3,
- 2, 3, 7, 8, 10, 19, 27, 32, 33, 33, 35, 38, 43, 41, 29, 9,
- -4, -9, 2, 16, 17, 13, 15, 17, 13, 10, 5, -1, -8, -18, -29, -32,
- -27, -21, -22, -30, -31, -31, -33, -31, -27, -18, -7, -6, -15, -16, -8, -1,
- 4, 12, 18, 22, 20, 16, 11, 10, 14, 18, 16, 15, 14, 9, 6, 4,
- 3, 3, 0, -5, -13, -18, -15, -13, -9, -7, -8, -5, -2, -5, -1, 5,
- 8, 10, 11, 12, 17, 19, 16, 10, 4, 4, 8, 8, 8, 13, 14, 9,
- 3, 0, -1, 0, 0, -7, -19, -24, -20, -15, -12, -15, -21, -23, -24, -26,
- -28, -29, -28, -21, -10, -1, 5, 6, -3, -12, -14, -11, -1, 12, 16, 17,
- 28, 36, 28, 20, 25, 27, 24, 25, 28, 21, 15, 11, 3, 4, 12, 11,
- 0, -7, -5, -1, -1, -5, -8, -11, -17, -23, -22, -19, -21, -20, -20, -22,
- -24, -22, -17, -20, -24, -20, -10, 2, 10, 13, 14, 14, 11, 8, 8, 12,
- 17, 18, 20, 20, 14, 4, -1, -2, -1, 3, 11, 12, 6, 0, -9, -20,
- -25, -18, -9, -8, -13, -18, -19, -14, -6, 0, 4, 11, 19, 22, 20, 19,
- 15, 13, 14, 18, 17, 12, 7, 9, 14, 9, -1, -4, -1, -5, -10, -12,
- -16, -23, -19, -7, -5, -10, -10, -11, -19, -27, -24, -14, -6, -3, -10, -21,
- -24, -15, -6, 0, 9, 15, 12, 8, 6, 9, 9, 11, 20, 26, 31, 35,
- 30, 21, 16, 16, 13, 6, 2, 4, 5, 3, -2, -10, -13, -11, -8, -9,
- -13, -16, -18, -18, -19, -22, -18, -8, -3, -1, 0, -5, -11, -10, -9, -11,
- -9, -2, 2, 4, 10, 15, 18, 19, 21, 21, 22, 22, 15, 4, -4, -8,
- -7, -6, -10, -14, -18, -23, -20, -15, -8, -1, 0, -4, -7, -9, -9, -6,
- -2, 2, 6, 7, 4, 1, 0, 7, 13, 11, 14, 22, 22, 15, 8, 2,
- 4, 10, 16, 17, 13, 10, 9, 6, -3, -13, -23, -26, -21, -17, -14, -12,
- -13, -16, -14, -9, -8, -8, -11, -18, -18, -12, -4, 0, 2, 6, 6, -1,
- -6, 0, 8, 11, 13, 11, 6, 6, 9, 13, 16, 16, 15, 10, 7, 10,
- 10, 4, 0, -2, -3, -1, 2, 2, -1, -5, -13, -21, -27, -30, -26, -16,
- -4, 5, 8, 6, 2, -3, -5, -1, 4, 8, 9, 11, 11, 6, 0, 0,
- 7, 12, 13, 11, 7, 1, -4, -3, 0, 5, 6, 5, -2, -10, -13, -13,
- -10, -5, -4, -9, -18, -28, -31, -24, -14, -10, -4, 2, 5, 4, 2, 4,
- 13, 20, 21, 19, 14, 11, 11, 12, 13, 14, 15, 17, 18, 18, 14, 5,
- -3, -5, -8, -11, -11, -12, -15, -15, -13, -13, -15, -13, -12, -15, -16, -11,
- -7, -6, -4, -1, 4, 6, -1, -10, -11, -7, -4, -1, 4, 9, 11, 12,
- 9, 7, 8, 8, 7, 9, 13, 15, 12, 4, 1, 1, -2, -9, -10, -7,
- -1, 3, 3, -1, -9, -12, -9, -5, 1, 3, -2, -10, -10, -7, -4, 2,
- 8, 6, 4, 6, 5, -1, -1, 7, 17, 20, 17, 16, 19, 16, 7, -3,
- -8, -9, -9, -11, -15, -24, -27, -20, -15, -12, -11, -7, -3, -4, -6, -7,
- -6, -8, -14, -18, -18, -15, -10, -5, 3, 12, 18, 20, 17, 11, 10, 16,
- 21, 22, 23, 23, 22, 17, 9, 0, -3, 2, 10, 15, 16, 11, 2, -9,
- -19, -23, -22, -15, -10, -8, -11, -13, -15, -17, -19, -18, -15, -10, -3, 1,
- -2, -6, -3, 0, -3, -3, 0, 6, 10, 9, 7, 4, -1, -4, 0, 10,
- 17, 16, 11, 5, 0, -1, 2, 5, 1, -6, -10, -10, -8, -6, -4, -2,
- -4, -7, -9, -9, -6, 2, 12, 17, 16, 11, 8, 7, 6, 5, 7, 9,
- 12, 14, 14, 9, 3, -1, -3, -5, -4, 0, 4, -1, -10, -18, -24, -29,
- -28, -20, -14, -13, -12, -8, -5, -5, -9, -13, -14, -11, -10, -9, -4, 1,
- 3, 2, 3, 8, 16, 20, 18, 13, 10, 14, 24, 29, 29, 27, 23, 17,
- 14, 16, 17, 15, 9, -1, -7, -10, -14, -18, -16, -11, -8, -7, -8, -12,
- -18, -26, -29, -26, -19, -11, -5, -3, -3, -2, 0, 2, 0, -3, -3, -2,
- -3, -4, -2, -1, 3, 7, 9, 8, 7, 3, 1, 4, 5, 2, 3, 5,
- 5, 0, -7, -9, -6, -1, 5, 9, 8, 3, -2, -6, -5, 3, 9, 12,
- 11, 8, 4, 3, 4, 6, 11, 13, 8, 1, 0, 4, 9, 13, 12, 5,
- 2, 3, 3, 0, -6, -16, -26, -30, -28, -26, -22, -18, -17, -19, -22, -24,
- -19, -12, -7, -2, 1, 0, -2, -4, -5, -2, 4, 10, 14, 15, 15, 16,
- 16, 17, 19, 22, 26, 25, 19, 13, 10, 7, 9, 11, 10, 7, 4, 1,
- -5, -8, -8, -4, 0, 1, -4, -11, -16, -17, -16, -14, -12, -10, -11, -14,
- -15, -16, -13, -9, -3, 1, 2, 1, 0, 0, -3, -9, -13, -10, -8, -7,
- -4, 0, 3, 6, 9, 9, 5, 3, 3, 5, 8, 12, 12, 6, -1, -2,
- 2, 8, 8, 4, -2, -5, -1, 4, 10, 13, 14, 13, 13, 14, 14, 12,
- 10, 8, 8, 8, 6, 6, 9, 6, -1, -9, -15, -19, -22, -24, -23, -25,
- -25, -23, -20, -19, -19, -21, -20, -20, -21, -19, -11, -2, 2, 1, 0, 3,
- 9, 13, 15, 16, 14, 10, 5, 3, 8, 14, 16, 18, 20, 22, 24, 21,
- 15, 9, 6, 8, 14, 18, 15, 9, 4, 1, 0, -2, -4, -4, -3, -3,
- -4, -7, -11, -13, -12, -11, -15, -19, -22, -25, -25, -21, -14, -11, -15, -19,
- -18, -14, -7, -1, 4, 2, -3, -6, -4, 0, 5, 10, 16, 17, 12, 7,
- 2, -1, -3, 0, 3, 6, 10, 14, 12, 6, 2, 5, 10, 15, 18, 18,
- 16, 14, 11, 6, 4, 3, 1, 1, 2, 6, 9, 9, 3, -2, -3, -4,
- -6, -8, -10, -15, -19, -20, -19, -18, -17, -15, -16, -17, -18, -20, -22, -21,
- -16, -11, -4, 1, 0, -4, -4, -1, 1, 2, 4, 4, 3, 3, 4, 7,
- 11, 16, 21, 20, 15, 11, 9, 12, 16, 21, 24, 23, 21, 17, 13, 11,
- 9, 4, 0, 0, 1, 3, 4, 0, -4, -7, -7, -9, -13, -17, -20, -22,
- -23, -21, -16, -12, -12, -15, -17, -17, -15, -12, -10, -10, -11, -12, -15, -15,
- -10, -4, 0, -1, -1, 1, 4, 7, 13, 19, 22, 23, 21, 19, 18, 17,
- 11, 5, 2, 5, 10, 13, 15, 15, 14, 13, 10, 5, 1, 0, 2, 5,
- 8, 10, 9, 6, 4, 2, -1, -5, -7, -8, -7, -8, -11, -13, -14, -16,
- -19, -21, -22, -22, -24, -23, -20, -17, -16, -16, -15, -16, -16, -15, -13, -11,
- -9, -5, 0, 6, 12, 15, 18, 18, 17, 17, 19, 20, 19, 19, 20, 23,
- 25, 25, 23, 20, 17, 13, 11, 9, 9, 8, 6, 3, 1, -2, -5, -5,
- -2, -1, -3, -7, -6, -3, 0, -2, -9, -21, -29, -32, -32, -30, -27, -27,
- -29, -30, -28, -24, -23, -21, -16, -7, 0, 1, 2, 2, 4, 7, 10, 14,
- 16, 14, 12, 13, 15, 18, 20, 22, 23, 20, 15, 8, 3, 2, 7, 13,
- 15, 13, 7, 2, 0, 0, -1, -2, -1, 1, 2, 1, 0, 2, 3, 4,
- 4, 6, 7, 5, 0, -10, -21, -30, -36, -36, -33, -28, -23, -18, -15, -14,
- -17, -19, -19, -17, -12, -5, -2, -2, -3, -1, 2, 6, 10, 12, 14, 13,
- 12, 13, 18, 25, 29, 28, 24, 19, 14, 10, 6, 6, 9, 12, 13, 15,
- 17, 18, 18, 14, 7, 0, -1, 1, 1, -2, -6, -8, -10, -11, -13, -17,
- -19, -18, -17, -16, -14, -14, -15, -17, -19, -22, -26, -26, -24, -20, -17, -14,
- -13, -12, -10, -7, -4, 1, 5, 7, 9, 10, 13, 15, 17, 18, 21, 24,
- 22, 21, 19, 17, 15, 13, 14, 14, 16, 17, 18, 16, 12, 10, 8, 6,
- 5, 3, 0, -3, -6, -7, -5, -4, -4, -5, -5, -4, -4, -4, -8, -13,
- -19, -24, -27, -28, -27, -25, -25, -27, -27, -25, -19, -14, -8, -3, 1, 6,
- 9, 8, 3, -3, -6, -4, -1, 4, 9, 14, 18, 20, 22, 22, 23, 23,
- 22, 21, 20, 20, 21, 21, 19, 15, 9, 3, -2, -4, -3, 0, 2, 2,
- 2, 3, 3, 1, -4, -10, -15, -19, -19, -16, -11, -7, -7, -9, -13, -17,
- -23, -28, -30, -29, -24, -20, -18, -19, -20, -19, -18, -19, -18, -13, -5, 1,
- 6, 9, 11, 13, 16, 21, 26, 29, 30, 29, 29, 28, 26, 23, 20, 20,
- 21, 21, 20, 18, 15, 9, 2, -4, -6, -5, -3, -3, -4, -6, -7, -9,
- -10, -10, -10, -10, -11, -13, -12, -11, -8, -6, -6, -10, -17, -26, -32, -35,
- -35, -34, -32, -27, -19, -9, -3, -1, -2, -5, -7, -6, -1, 7, 14, 18,
- 21, 23, 25, 26, 26, 23, 20, 20, 23, 24, 24, 21, 19, 14, 8, 2,
- -1, 0, 1, 2, 3, 6, 8, 8, 5, 2, -2, -5, -5, -4, -1, 1,
- 1, -1, -6, -9, -11, -13, -17, -20, -24, -26, -27, -26, -23, -21, -20, -23,
- -26, -27, -26, -24, -20, -15, -9, -2, 4, 8, 10, 13, 16, 19, 21, 23,
- 25, 28, 33, 36, 38, 38, 35, 32, 29, 24, 16, 11, 6, 2, -2, -6,
- -6, -5, -4, -4, -7, -11, -14, -13, -10, -8, -8, -8, -9, -11, -12, -12,
- -11, -11, -12, -14, -17, -19, -19, -18, -18, -20, -22, -23, -21, -18, -14, -11,
- -8, -4, -1, 5, 11, 13, 11, 8, 6, 7, 9, 11, 13, 15, 19, 22,
- 23, 25, 27, 27, 22, 17, 11, 6, 4, 5, 9, 13, 15, 15, 11, 6,
- 0, -4, -7, -8, -6, -3, -2, -3, -6, -9, -13, -18, -22, -23, -20, -15,
- -11, -10, -11, -14, -19, -24, -27, -28, -28, -27, -26, -23, -19, -15, -10, -6,
- -1, 4, 8, 10, 11, 11, 13, 15, 17, 20, 23, 24, 24, 26, 28, 28,
- 28, 27, 26, 24, 22, 20, 16, 13, 10, 8, 6, 3, -3, -9, -15, -17,
- -16, -15, -13, -13, -14, -17, -19, -20, -20, -17, -14, -12, -13, -14, -13, -13,
- -14, -15, -14, -13, -12, -12, -12, -10, -8, -7, -8, -9, -9, -7, -4, 0,
- 3, 6, 8, 10, 12, 14, 18, 22, 25, 26, 27, 28, 28, 27, 24, 20,
- 16, 13, 11, 9, 6, 3, 0, -3, -3, -2, 1, 3, 5, 3, 0, -4,
- -8, -12, -17, -21, -22, -20, -17, -15, -14, -14, -13, -15, -19, -22, -21, -18,
- -14, -13, -15, -16, -17, -17, -19, -19, -16, -11, -4, 1, 6, 10, 13, 17,
- 20, 23, 24, 24, 24, 25, 28, 33, 37, 38, 35, 30, 24, 20, 16, 13,
- 9, 2, -4, -8, -8, -8, -7, -7, -9, -12, -16, -18, -18, -16, -15, -16,
- -16, -16, -13, -10, -10, -11, -13, -15, -15, -15, -15, -16, -17, -16, -14, -13,
- -13, -13, -13, -12, -9, -5, -2, 1, 3, 6, 12, 18, 22, 22, 21, 18,
- 16, 16, 19, 23, 29, 32, 30, 24, 18, 13, 9, 6, 3, 0, -2, -4,
- -6, -8, -10, -11, -10, -6, -3, -2, -3, -5, -5, -6, -6, -7, -6, -5,
- -4, -5, -8, -10, -11, -12, -14, -16, -18, -20, -21, -21, -22, -23, -24, -24,
- -22, -18, -11, -4, 1, 4, 5, 6, 8, 11, 15, 20, 24, 26, 27, 28,
- 31, 32, 31, 30, 28, 27, 24, 20, 17, 14, 12, 9, 3, -3, -9, -12,
- -15, -16, -17, -15, -13, -10, -10, -11, -13, -14, -15, -17, -19, -21, -23, -24,
- -22, -18, -13, -9, -8, -8, -8, -9, -9, -9, -7, -4, 0, 2, 3, 5,
- 5, 3, 3, 4, 5, 6, 7, 10, 14, 17, 20, 20, 20, 21, 22, 20,
- 18, 16, 15, 14, 12, 9, 7, 6, 4, 2, -2, -5, -7, -9, -9, -8,
- -5, -2, 0, 0, -1, -3, -7, -12, -16, -16, -15, -13, -12, -13, -13, -12,
- -11, -11, -12, -15, -19, -23, -24, -22, -19, -16, -13, -10, -5, -1, 3, 6,
- 7, 8, 8, 10, 13, 17, 21, 25, 27, 28, 28, 26, 24, 24, 25, 27,
- 28, 29, 28, 25, 19, 12, 4, -3, -10, -15, -19, -22, -24, -25, -26, -25,
- -23, -21, -20, -18, -17, -16, -14, -12, -11, -12, -14, -14, -13, -13, -15, -16,
- -16, -16, -15, -11, -4, 0, -2, 0, 0, 3, 14, 34, 24, -3, -14, -12,
- 6, 6, -11, -23, -5, 15, 20, 15, -19, -12, 3, 19, 11, -5, 1, 4,
- 7, -13, -3, 5, -13, 0, -2, 8, 0, -6, 16, 23, 13, 6, 2, 14,
- 25, 2, 11, 3, -7, -8, -24, -6, -4, -18, 6, 30, 14, 9, 0, 0,
- 13, -7, 0, -3, 9, 8, -6, -14, -15, -23, -19, -7, 0, -3, 1, -8,
- -10, -10, -17, -12, -7, -10, 1, -12, -13, 0, -15, -20, -25, -16, -6, -7,
- -6, -6, -2, -4, -13, -12, -6, -6, -5, 2, 8, -5, -13, -3, -4, -11,
- -16, -3, 12, -2, -8, -4, -4, 4, -15, -17, -6, -2, 5, -4, 3, -2,
- -10, -4, -5, -7, -8, 4, 17, 1, -3, -14, -4, -2, -7, -4, -6, 10,
- 5, -6, -7, -8, 10, -5, -3, 3, -8, 11, 7, -5, -3, -13, -7, 0,
- -6, 4, 0, -7, 12, -9, -17, -7, 5, 2, -3, -4, -7, 7, -2, -13,
- -5, -2, 5, 4, 0, 7, -3, 4, 1, -2, -4, 6, 8, 8, 0, -2,
- 2, 3, 2, 1, -2, 5, 12, 6, 3, 2, -3, 2, 3, 1, 8, 6,
- 7, 2, -5, -3, 1, 5, 2, 0, -3, 2, 7, 2, 0, -9, 0, 5,
- 1, 3, 1, 4, 6, -5, -3, -2, 2, 6, 4, 6, 1, 2, 4, 4,
- -2, 2, 5, 5, 7, 7, 2, 6, 0, 3, 0, -3, 8, 4, 4, 9,
- -3, 2, 1, 1, 2, 1, 5, 5, 4, 6, 1, -6, -2, 3, 5, 6,
- 4, 3, 4, 1, 2, -4, 0, 6, 2, 2, 4, 3, 5, -3, -2, -5,
- -3, 5, 2, 1, 3, 1, -2, -3, -4, -6, 3, 5, 1, -2, 1, 2,
- -2, -2, -2, -3, 3, 5, 3, 4, 2, 2, 1, 0, 1, 4, 9, 9,
- 5, 2, 1, 6, 4, 4, 5, 5, 7, 8, 4, 5, 1, 2, 3, 1,
- 1, 4, 2, 3, 0, -4, -7, -5, 0, -3, -3, -3, -5, 0, -8, -7,
- -8, -5, -3, -6, -3, -4, -5, 0, -7, -4, -5, -3, 1, 1, -2, 1,
- -2, 2, 0, 0, -2, 3, 5, 4, 5, 4, 2, 4, 2, 4, 5, 6,
- 5, 6, 4, 4, 4, 4, 3, 4, 2, 4, 4, 2, -2, -2, 0, -3,
- -3, -3, -4, -2, -7, -6, -7, -9, -7, -10, -9, -10, -10, -8, -11, -9,
- -9, -12, -10, -13, -12, -7, -8, -6, -6, -9, -6, -5, -3, 0, 0, 1,
- 1, 4, 3, 4, 8, 6, 8, 7, 6, 10, 9, 12, 12, 11, 12, 8,
- 13, 10, 11, 10, 8, 9, 8, 6, 9, 4, 5, 0, -3, -5, -5, -6,
- -7, -9, -12, -15, -17, -21, -18, -22, -21, -23, -25, -24, -27, -27, -26, -30,
- -27, -27, -28, -20, -22, -19, -14, -15, -12, -10, -10, -2, 3, 4, 12, 12,
- 14, 20, 17, 25, 27, 29, 33, 35, 35, 40, 38, 41, 39, 36, 38, 36,
- 36, 38, 31, 33, 25, 21, 14, 8, 1, 2, 0, -3, -5, -15, -23, -28,
- -40, -39, -43, -46, -43, -52, -53, -59, -66, -62, -69, -63, -64, -64, -50, -56,
- -44, -45, -43, -38, -36, -31, -20, -8, 4, 12, 19, 18, 28, 31, 40, 52,
- 57, 68, 73, 73, 77, 73, 81, 79, 82, 82, 77, 82, 77, 75, 69, 59,
- 53, 42, 33, 24, 22, 17, 11, 1, -17, -25, -36, -42, -46, -55, -60, -64,
- -73, -77, -88, -90, -92, -97, -98, -100, -100, -92, -85, -79, -80, -76, -79, -69,
- -56, -50, -32, -24, -15, 0, -2, 11, 15, 29, 45, 55, 67, 72, 82, 88,
- 95, 101, 102, 109, 109, 112, 109, 110, 110, 106, 104, 91, 81, 77, 68, 66,
- 54, 42, 32, 14, 6, -6, -12, -20, -29, -43, -55, -65, -76, -76, -85, -89,
- -97, -105, -107, -114, -115, -117, -117, -113, -112, -104, -101, -91, -85, -84, -70, -72,
- -55, -42, -34, -14, -8, 5, 16, 22, 35, 44, 57, 69, 78, 89, 94, 101,
- 104, 109, 109, 119, 118, 117, 120, 110, 114, 114, 99, 102, 84, 74, 72, 57,
- 52, 43, 32, 22, 10, -7, -20, -28, -34, -47, -54, -60, -67, -71, -80, -87,
- -90, -105, -105, -110, -120, -115, -120, -123, -113, -111, -109, -97, -98, -92, -83, -82,
- -76, -63, -61, -48, -39, -30, -16, -3, 10, 22, 32, 42, 49, 61, 67, 76,
- 84, 91, 101, 105, 115, 116, 117, 125, 115, 119, 116, 106, 111, 102, 97, 92,
- 84, 79, 70, 64, 50, 45, 31, 19, 14, -2, -9, -19, -30, -35, -47, -54,
- -62, -67, -73, -82, -86, -96, -100, -105, -109, -116, -118, -120, -120, -117, -111, -110,
- -97, -96, -90, -84, -78, -73, -64, -55, -50, -39, -25, -20, 1, 11, 19, 37,
- 40, 51, 61, 68, 76, 85, 94, 97, 105, 114, 112, 120, 122, 119, 121, 117,
- 110, 106, 105, 92, 90, 84, 69, 71, 57, 48, 45, 29, 22, 14, -2, -9,
- -22, -31, -40, -47, -59, -62, -68, -76, -80, -87, -97, -96, -111, -111, -116, -124,
- -119, -123, -120, -109, -109, -98, -95, -93, -84, -81, -75, -66, -55, -51, -37, -28,
- -16, 1, 12, 23, 39, 40, 55, 59, 68, 77, 86, 94, 103, 104, 116, 117,
- 118, 125, 122, 117, 120, 107, 108, 104, 95, 92, 85, 72, 70, 60, 48, 43,
- 29, 18, 10, -7, -12, -22, -30, -38, -49, -58, -63, -72, -75, -84, -90, -93,
- -100, -110, -103, -121, -115, -115, -124, -110, -112, -111, -92, -98, -86, -81, -77, -69,
- -61, -53, -48, -34, -27, -13, 1, 9, 28, 37, 45, 58, 59, 76, 78, 85,
- 97, 98, 109, 114, 111, 123, 120, 119, 121, 116, 111, 110, 101, 93, 92, 79,
- 73, 68, 55, 52, 40, 30, 21, 10, 0, -13, -23, -29, -41, -47, -58, -64,
- -69, -75, -84, -89, -93, -103, -105, -110, -120, -115, -117, -128, -105, -114, -109, -88,
- -102, -86, -76, -84, -64, -63, -56, -43, -37, -25, -10, 4, 11, 31, 36, 46,
- 56, 58, 74, 78, 84, 100, 95, 110, 114, 110, 124, 120, 116, 121, 110, 105,
- 108, 97, 96, 91, 79, 75, 66, 57, 51, 38, 29, 17, 5, -3, -13, -20,
- -28, -40, -46, -55, -66, -68, -76, -85, -88, -97, -102, -106, -110, -117, -115, -120,
- -122, -108, -117, -103, -98, -96, -86, -79, -77, -66, -59, -54, -46, -33, -31, -10,
- -2, 11, 27, 36, 47, 58, 62, 74, 78, 86, 94, 96, 106, 109, 115, 120,
- 118, 121, 119, 112, 114, 104, 98, 94, 85, 77, 72, 63, 56, 49, 37, 31,
- 20, 6, -2, -15, -24, -33, -44, -50, -58, -63, -68, -76, -82, -89, -95, -105,
- -105, -116, -118, -117, -126, -114, -111, -118, -92, -105, -92, -83, -88, -72, -71, -65,
- -51, -50, -31, -25, -9, 2, 16, 29, 35, 50, 53, 67, 73, 75, 92, 88,
- 104, 112, 108, 122, 117, 119, 123, 114, 116, 110, 104, 98, 94, 86, 80, 75,
- 63, 59, 47, 36, 29, 13, 9, -5, -16, -21, -36, -40, -50, -61, -61, -73,
- -77, -85, -93, -95, -103, -108, -117, -120, -118, -125, -117, -108, -116, -96, -98, -97,
- -83, -82, -78, -66, -61, -54, -43, -32, -25, -2, 3, 16, 33, 36, 52, 56,
- 66, 75, 78, 94, 91, 103, 113, 108, 122, 119, 119, 121, 116, 112, 110, 106,
- 93, 96, 83, 76, 74, 59, 58, 47, 34, 28, 14, 6, -6, -17, -27, -36,
- -44, -54, -61, -63, -70, -76, -86, -90, -99, -102, -108, -117, -115, -121, -123, -111,
- -120, -102, -100, -101, -84, -91, -76, -74, -70, -54, -56, -41, -30, -20, -3, 8,
- 23, 31, 46, 47, 59, 70, 71, 83, 89, 90, 108, 108, 115, 120, 121, 122,
- 118, 118, 109, 110, 102, 93, 93, 82, 78, 72, 62, 57, 45, 37, 22, 15,
- 4, -10, -18, -30, -36, -42, -54, -57, -63, -68, -77, -86, -91, -102, -103, -108,
- -117, -114, -119, -117, -115, -110, -106, -100, -91, -99, -79, -81, -77, -59, -61, -50,
- -36, -33, -16, -4, 10, 16, 35, 39, 48, 62, 64, 76, 85, 89, 98, 105,
- 110, 113, 120, 119, 118, 123, 112, 111, 110, 100, 98, 93, 82, 78, 70, 58,
- 54, 45, 30, 24, 12, 0, -7, -20, -28, -36, -45, -55, -61, -66, -73, -79,
- -88, -93, -103, -105, -112, -119, -115, -124, -123, -109, -119, -103, -98, -102, -92, -84,
- -83, -75, -62, -59, -50, -34, -34, -12, 1, 7, 26, 33, 42, 50, 62, 67,
- 76, 88, 90, 101, 110, 108, 118, 121, 119, 122, 121, 111, 113, 110, 98, 98,
- 91, 80, 78, 66, 58, 53, 40, 29, 20, 8, -4, -11, -22, -33, -37, -49,
- -57, -61, -68, -77, -81, -90, -96, -101, -110, -112, -116, -120, -116, -121, -119, -104,
- -111, -96, -91, -96, -79, -79, -76, -59, -57, -46, -33, -25, -14, 5, 11, 26,
- 39, 42, 55, 61, 70, 81, 86, 94, 101, 105, 114, 116, 120, 121, 119, 119,
- 115, 111, 107, 102, 94, 90, 82, 73, 68, 59, 50, 41, 28, 20, 7, -4,
- -12, -22, -30, -41, -48, -56, -62, -69, -75, -83, -90, -98, -100, -107, -111, -119,
- -112, -124, -120, -107, -119, -101, -93, -104, -80, -85, -83, -61, -65, -55, -40, -38,
- -25, -7, -3, 13, 29, 34, 45, 57, 59, 74, 79, 87, 98, 98, 108, 111,
- 112, 122, 117, 119, 119, 111, 110, 107, 96, 96, 89, 76, 74, 63, 54, 51,
- 35, 27, 19, 5, -3, -12, -25, -29, -43, -52, -58, -64, -71, -78, -82, -92,
- -98, -101, -108, -110, -114, -120, -119, -118, -115, -110, -106, -95, -97, -82, -84, -76,
- -62, -63, -51, -42, -39, -20, -12, 2, 15, 29, 36, 47, 58, 62, 74, 80,
- 85, 95, 101, 106, 111, 116, 118, 117, 122, 113, 115, 111, 99, 103, 90, 85,
- 80, 68, 63, 56, 46, 36, 28, 17, 5, -5, -19, -25, -35, -43, -52, -58,
- -62, -72, -75, -83, -94, -94, -105, -105, -115, -115, -116, -122, -114, -112, -108, -98,
- -99, -89, -86, -82, -72, -69, -58, -52, -44, -31, -21, -6, 4, 17, 28, 39,
- 48, 53, 66, 72, 80, 88, 92, 104, 108, 113, 116, 119, 121, 116, 119, 112,
- 108, 107, 94, 94, 85, 79, 72, 62, 57, 48, 37, 25, 17, 8, -8, -15,
- -26, -35, -42, -55, -59, -65, -73, -75, -87, -89, -97, -104, -109, -116, -116, -121,
- -120, -120, -109, -108, -103, -90, -97, -78, -78, -77, -60, -64, -50, -41, -34, -16,
- -7, 9, 19, 33, 42, 52, 60, 65, 77, 79, 87, 96, 99, 109, 113, 118,
- 124, 117, 121, 117, 109, 110, 99, 94, 93, 83, 77, 73, 63, 55, 50, 32,
- 26, 18, 0, -6, -20, -29, -34, -49, -53, -57, -63, -71, -76, -83, -91, -97,
- -108, -112, -114, -122, -115, -124, -112, -105, -112, -89, -99, -90, -78, -89, -72, -66,
- -61, -49, -41, -28, -16, 2, 6, 25, 35, 36, 53, 54, 67, 77, 79, 93,
- 97, 105, 112, 111, 122, 118, 119, 117, 112, 109, 108, 99, 95, 92, 82, 76,
- 71, 59, 56, 43, 30, 24, 10, 0, -9, -18, -26, -36, -45, -55, -59, -68,
- -75, -81, -88, -94, -99, -106, -109, -110, -119, -117, -119, -116, -111, -105, -101, -91,
- -92, -83, -75, -75, -61, -52, -52, -35, -29, -18, 0, 9, 22, 36, 41, 51,
- 64, 68, 78, 88, 90, 101, 103, 109, 113, 115, 121, 117, 118, 116, 109, 109,
- 102, 94, 90, 80, 71, 67, 57, 47, 42, 30, 19, 14, -4, -9, -19, -31,
- -36, -50, -55, -61, -68, -74, -79, -87, -93, -101, -107, -107, -115, -118, -118, -123,
- -112, -110, -109, -92, -93, -94, -74, -83, -71, -57, -61, -45, -34, -31, -10, 0,
- 12, 27, 37, 42, 55, 61, 70, 77, 87, 95, 96, 106, 112, 113, 123, 122,
- 117, 122, 112, 109, 110, 96, 96, 92, 76, 74, 68, 55, 50, 40, 28, 20,
- 7, -6, -10, -23, -31, -42, -51, -59, -65, -70, -76, -82, -88, -92, -104, -104,
- -105, -122, -113, -122, -126, -106, -119, -103, -91, -99, -82, -80, -76, -66, -59, -54,
- -46, -34, -30, -9, 1, 13, 33, 34, 51, 57, 63, 76, 77, 91, 95, 95,
- 110, 108, 115, 122, 120, 120, 123, 112, 110, 110, 94, 95, 87, 70, 74, 62,
- 55, 50, 39, 29, 20, 7, -5, -13, -26, -35, -44, -56, -61, -65, -69, -75,
- -83, -86, -98, -104, -104, -121, -115, -119, -128, -110, -117, -116, -92, -100, -90, -78,
- -83, -75, -63, -64, -55, -41, -39, -20, -7, 1, 21, 31, 40, 51, 55, 67,
- 72, 77, 91, 93, 99, 110, 109, 118, 125, 118, 124, 119, 108, 114, 101, 93,
- 96, 81, 75, 73, 59, 57, 48, 35, 27, 15, 1, -7, -20, -29, -37, -49,
- -56, -61, -65, -69, -74, -83, -91, -98, -107, -113, -117, -120, -122, -118, -115, -111,
- -103, -101, -92, -89, -85, -80, -77, -65, -61, -51, -41, -33, -16, -4, 8, 21,
- 34, 40, 49, 57, 63, 73, 82, 89, 98, 104, 109, 117, 118, 123, 122, 119,
- 116, 110, 108, 100, 97, 93, 83, 80, 70, 64, 55, 45, 34, 22, 12, -2,
- -10, -20, -30, -35, -48, -55, -62, -67, -71, -78, -86, -91, -101, -104, -110, -117,
- -117, -120, -123, -111, -111, -110, -90, -99, -90, -76, -85, -71, -58, -63, -45, -37,
- -33, -14, 1, 4, 27, 34, 41, 53, 59, 66, 79, 84, 92, 100, 103, 110,
- 115, 116, 123, 118, 118, 117, 107, 110, 101, 95, 93, 79, 76, 68, 57, 52,
- 43, 30, 23, 11, -3, -8, -20, -30, -34, -48, -55, -60, -69, -74, -81, -89,
- -92, -101, -105, -108, -114, -117, -118, -122, -112, -113, -108, -95, -101, -87, -82, -83,
- -68, -60, -56, -45, -38, -28, -17, -2, 6, 23, 33, 40, 54, 60, 68, 80,
- 85, 94, 96, 103, 109, 110, 119, 118, 118, 121, 113, 112, 110, 100, 98, 90,
- 77, 73, 66, 55, 51, 41, 29, 25, 8, 1, -9, -23, -28, -42, -51, -59,
- -64, -67, -75, -79, -86, -94, -98, -105, -111, -115, -117, -121, -123, -111, -120, -102,
- -95, -100, -79, -84, -81, -61, -69, -55, -46, -42, -27, -14, -3, 11, 30, 35,
- 49, 57, 60, 76, 76, 86, 95, 95, 109, 108, 116, 122, 121, 123, 120, 116,
- 114, 106, 100, 94, 88, 78, 73, 65, 59, 52, 38, 33, 20, 10, -2, -15,
- -22, -32, -42, -51, -58, -62, -67, -77, -80, -86, -94, -100, -106, -113, -115, -119,
- -122, -118, -117, -107, -106, -98, -89, -89, -78, -76, -71, -57, -56, -46, -36, -25,
- -12, 0, 16, 26, 39, 49, 54, 67, 72, 80, 88, 94, 101, 104, 115, 113,
- 121, 125, 116, 123, 116, 110, 109, 98, 93, 88, 78, 69, 65, 56, 47, 42,
- 27, 20, 8, -6, -15, -27, -33, -43, -53, -58, -64, -68, -74, -86, -87, -96,
- -106, -103, -117, -116, -117, -123, -117, -106, -114, -97, -96, -96, -81, -81, -80, -62,
- -64, -49, -45, -34, -19, -8, 4, 17, 28, 40, 47, 54, 66, 73, 79, 93,
- 95, 102, 113, 110, 117, 123, 119, 121, 117, 113, 111, 106, 96, 95, 88, 78,
- 72, 63, 55, 47, 35, 26, 14, 4, -9, -19, -24, -35, -43, -51, -61, -65,
- -72, -79, -88, -88, -99, -107, -107, -120, -114, -120, -122, -113, -116, -102, -106, -95,
- -89, -95, -72, -80, -70, -50, -58, -37, -30, -20, -5, 6, 18, 29, 44, 45,
- 57, 72, 68, 89, 89, 97, 109, 104, 120, 113, 118, 124, 112, 120, 112, 107,
- 106, 96, 91, 87, 78, 66, 65, 52, 40, 39, 17, 17, 4, -13, -13, -30,
- -35, -44, -58, -59, -66, -72, -78, -85, -93, -97, -106, -114, -110, -120, -120, -118,
- -120, -109, -110, -98, -100, -89, -81, -87, -68, -68, -59, -44, -46, -29, -18, -5,
- 5, 22, 32, 39, 54, 56, 68, 79, 79, 94, 98, 102, 110, 112, 117, 119,
- 124, 117, 116, 116, 104, 106, 97, 89, 86, 74, 67, 60, 53, 41, 34, 24,
- 12, 4, -9, -19, -28, -38, -47, -58, -60, -68, -73, -77, -88, -93, -96, -111,
- -109, -115, -124, -118, -122, -120, -107, -109, -102, -91, -95, -82, -78, -78, -60, -59,
- -51, -36, -35, -14, -3, 6, 24, 34, 41, 56, 59, 67, 81, 82, 92, 103,
- 102, 112, 119, 114, 123, 123, 116, 121, 112, 106, 107, 93, 91, 84, 74, 69,
- 61, 52, 43, 32, 21, 13, -2, -10, -22, -31, -38, -51, -56, -59, -69, -71,
- -76, -87, -90, -100, -107, -110, -119, -118, -120, -123, -108, -118, -101, -92, -102, -77,
- -85, -83, -63, -71, -58, -45, -44, -27, -15, -2, 10, 30, 32, 46, 57, 56,
- 74, 73, 84, 93, 95, 109, 108, 117, 117, 124, 119, 119, 119, 112, 109, 100,
- 96, 90, 81, 75, 65, 59, 51, 41, 33, 22, 12, 0, -12, -23, -30, -40,
- -51, -57, -64, -71, -73, -83, -84, -95, -102, -102, -116, -117, -118, -128, -116, -114,
- -116, -102, -99, -95, -86, -80, -80, -71, -58, -61, -46, -38, -30, -10, -4, 12,
- 26, 37, 47, 54, 67, 68, 79, 89, 86, 104, 104, 111, 118, 118, 123, 121,
- 119, 116, 112, 109, 99, 96, 88, 80, 75, 66, 58, 49, 41, 29, 19, 10,
- -5, -10, -25, -35, -39, -53, -58, -64, -69, -75, -81, -87, -100, -99, -112, -116,
- -118, -126, -123, -115, -120, -111, -102, -100, -93, -86, -85, -76, -69, -64, -56, -47,
- -38, -25, -10, 4, 16, 31, 40, 46, 61, 65, 70, 83, 86, 93, 103, 105,
- 114, 125, 118, 124, 125, 112, 120, 111, 98, 103, 91, 86, 83, 71, 66, 61,
- 49, 38, 32, 16, 7, -4, -17, -26, -36, -44, -54, -60, -59, -71, -75, -79,
- -94, -95, -103, -117, -112, -120, -127, -120, -118, -117, -104, -102, -99, -88, -84, -86,
- -73, -70, -64, -51, -47, -37, -17, -10, 7, 19, 32, 40, 52, 56, 67, 73,
- 80, 87, 92, 103, 109, 110, 123, 119, 121, 126, 111, 113, 112, 98, 98, 91,
- 80, 80, 71, 60, 61, 47, 36, 30, 13, 5, -5, -19, -27, -35, -43, -52,
- -58, -62, -71, -76, -84, -96, -100, -105, -118, -115, -121, -123, -121, -114, -117, -110,
- -98, -105, -91, -83, -90, -71, -68, -64, -48, -43, -33, -17, -5, 3, 23, 32,
- 38, 54, 59, 66, 79, 82, 92, 100, 105, 108, 116, 119, 117, 126, 116, 115,
- 118, 106, 105, 99, 91, 85, 78, 67, 60, 54, 41, 33, 24, 11, 0, 3,
- 10, 14, -8, 46, 7, -20, -23, -28, 17, 9, 47, -7, -15, -35, -1, -26,
- 44, 34, -31, 31, -47, -32, 30, -2, 32, 15, -15, -17, -39, 16, -2, 26,
- 23, 3, -43, 11, -37, 14, 37, 7, 4, -21, -30, -9, 14, 18, 38, -13,
- -16, -21, -24, 8, 38, 3, 16, -29, -11, -26, 20, 15, 24, -9, 0, -34,
- -21, 32, -16, 41, -1, -20, -7, -7, -7, 27, 0, -2, -2, -11, -11, 19,
- -16, 32, -19, -4, 11, -40, 49, -13, -12, 12, -32, 12, 17, 1, 23, -34,
- -20, 14, -20, 33, 44, -51, 7, -21, -38, 46, 19, 37, -28, -29, -17, -40,
- 63, 36, -33, 42, -45, -57, 16, 37, -3, 54, 0, -64, -25, -7, 15, 37,
- 34, -2, -65, -12, -3, -7, 76, -2, -6, -28, -22, -30, 40, 11, 12, 21,
- -43, -6, -1, -31, 73, -35, 33, -1, -67, 29, -24, 16, 42, 4, -26, 17,
- -71, 32, 0, 0, 72, -56, 4, -2, -75, 76, -25, 39, 24, -42, -6, -20,
- -31, 56, 1, 3, 49, -63, -12, -16, -10, 49, 12, 29, -32, -59, 35, -39,
- 35, 45, -33, -21, 46, -68, 13, 16, 12, 0, 2, 32, -70, 12, 30, -62,
- 64, 5, -31, 22, -30, 11, -30, 43, 2, -8, 16, -3, -60, 39, -11, -13,
- 63, -32, 8, -6, -45, 39, -38, 30, 49, -89, 96, -84, 0, 43, -51, 52,
- -4, -6, 7, -31, -10, 12, -22, 62, 8, -57, 65, -101, 1, 69, -46, 76,
- -18, -34, -24, -33, 50, -6, 55, 16, -70, -19, 2, -33, 59, 61, -40, 7,
- -44, -33, -7, 61, 31, -15, 5, -32, -70, 47, 34, 8, 22, -16, -44, -47,
- 56, -6, 12, 56, -46, -32, -3, 7, -4, 42, 19, -41, -35, 41, -59, 43,
- 45, -44, 9, -9, -7, -19, 36, 2, -50, 49, -6, -34, 33, -1, -38, 17,
- 44, -33, 5, 28, -68, -13, 62, -25, 15, 45, -57, -32, 23, -14, 37, 11,
- 29, -56, -48, 46, -55, 48, 94, -74, 22, -40, -59, 36, 9, 75, -19, -31,
- 6, -104, 39, 80, -23, 59, -12, -104, 10, -12, 24, 59, 5, 9, -78, -12,
- 24, -47, 116, -6, -51, 34, -71, -26, 55, 3, 11, 38, -31, -9, -45, 21,
- -11, 4, 92, -79, 16, -16, -41, 29, 27, 19, -5, -19, -13, -35, 29, 22,
- -7, 20, -35, 6, -21, 30, -2, 6, -8, -20, -12, 30, -13, 8, 23, -52,
- 21, 8, -16, 40, -20, -7, -15, -38, 62, -33, 48, 5, -66, 28, -25, 15,
- 39, 5, -46, 8, -46, 32, 12, 37, -9, -49, 43, -78, 43, 46, -43, 39,
- -41, -36, 13, 19, 48, -21, 9, -37, -54, 45, 32, -14, 41, -32, -66, 42,
- -8, 37, 12, -10, -12, -74, 71, -30, 16, 65, -64, -1, -13, -12, 17, 24,
- 10, -16, -31, -1, -3, 1, 68, -47, -7, -8, -41, 74, -16, 32, -27, -42,
- 22, -49, 80, -11, 0, 23, -84, 34, -24, 31, 48, -37, 23, -55, -25, 22,
- 14, 22, 59, -78, -11, -1, -45, 90, -35, 32, 0, -75, 63, -65, 34, 52,
- -71, 70, -56, -14, 30, -22, 10, 55, -74, 41, -19, -47, 88, -62, 50, -11,
- -57, 44, -54, 59, 17, -23, 12, -40, -41, 60, 3, 15, 28, -71, -1, -17,
- 11, 61, -28, 47, -59, -48, 35, -18, 51, 27, -20, -35, -36, 14, 6, 44,
- 23, -30, -33, -17, -1, 14, 49, -2, -32, -12, -20, 5, 29, 34, -33, 9,
- -34, -26, 36, -2, 40, -28, 5, -26, -39, 65, -27, 19, 31, -54, 0, -8,
- 12, 2, 30, -5, -25, -22, 24, -29, 26, 52, -57, 7, 5, -56, 46, 1,
- 8, 4, -5, 1, -51, 28, 14, -21, 48, -17, -46, 4, 11, -6, 35, 7,
- -16, -31, -10, 25, -49, 95, -28, -29, 19, -46, -5, 32, 21, 8, -1, -24,
- -36, -17, 59, -7, 33, 10, -76, -14, 19, -1, 56, 16, -23, -64, -8, 7,
- 8, 85, 0, -57, -21, -35, -7, 72, 23, 28, -66, -16, -47, 2, 68, 24,
- 5, 0, -69, -26, 22, -7, 72, 0, -12, -20, -51, 15, -11, 44, 44, -46,
- 36, -59, -38, 32, 19, -3, 71, -45, -28, -29, -17, 36, 8, 79, -47, -53,
- 18, -65, 38, 75, -24, 20, -36, -34, -26, 38, 39, -7, -3, 7, -85, 44,
- 26, -17, 42, -20, -29, -26, 26, 18, -8, 36, -17, -73, 40, 4, -1, 52,
- -16, -47, -15, 14, 4, 29, 30, -41, -44, 15, -2, 16, 60, -26, -54, 17,
- -33, 22, 48, -5, -15, -20, -13, -15, 31, 37, -28, 6, -17, -22, -10, 64,
- -43, 16, 22, -71, 41, 3, -1, 6, -12, 12, -38, 11, 38, -49, 37, 24,
- -64, 27, 18, -73, 81, -33, 14, -3, -32, 43, -60, 53, 24, -76, 70, -29,
- -33, 50, -18, -34, 48, -38, 37, -15, -5, 25, -80, 70, -4, -45, 89, -72,
- -3, 13, -23, 28, 21, -9, -9, -25, -11, 24, -26, 62, -14, -49, 67, -97,
- 57, 12, -23, 46, -46, 9, -20, -4, 25, -1, 5, 18, -31, -25, 38, -43,
- 44, 17, -42, 37, -66, 37, -16, 26, 18, -16, -17, -4, -17, 7, 38, -11,
- 4, -3, -51, 32, -17, 38, 18, -34, 23, -58, 4, 25, 0, 26, 3, -35,
- -11, -10, 16, 24, 8, 4, -33, -30, 22, -2, 14, 52, -61, 10, -23, -4,
- 20, 10, 32, -44, -2, 1, -36, 37, 32, -25, 2, 0, -40, 14, 24, -5,
- 13, -28, 20, -51, 41, 15, -23, 25, -12, -41, 30, -2, -11, 40, -34, 14,
- -24, 3, 22, -31, 44, -22, -31, 57, -55, 28, 0, -9, 1, 11, -10, 8,
- -13, 3, -2, -23, 60, -49, 23, 10, -59, 36, -3, -3, 35, -23, 5, -42,
- 15, 7, -2, 35, 0, -45, 8, -4, -27, 63, -4, -14, 9, -39, 1, 1,
- 27, 19, -27, 24, -49, -6, 34, -5, 10, 19, -32, -20, 14, -12, 16, 26,
- -9, -19, -9, -8, 8, 7, 40, -29, -14, -4, -25, 7, 56, -15, 6, -20,
- -36, 3, 10, 33, 20, -23, -5, -42, -18, 54, -17, 63, -5, -59, 2, -44,
- 12, 57, 17, 15, -33, -44, -16, -17, 65, 40, -9, 10, -72, -51, 39, 10,
- 65, 19, -25, -47, -51, 17, 20, 53, 30, -35, -35, -34, -16, 36, 48, 12,
- -3, -35, -42, -9, 28, 34, 12, 15, -42, -39, 7, 8, 24, 28, 1, -31,
- -36, 9, -1, 28, 29, -14, -34, 14, -43, 23, 34, -7, 24, -44, 10, -28,
- -5, 53, -29, 29, -7, -33, 2, -1, 5, 19, 10, -17, 2, -33, 14, 1,
- 8, 32, -36, 17, -28, -18, 36, -22, 29, 2, -25, 5, -17, 13, 1, 16,
- -1, -10, -12, 3, -9, 10, 19, -22, 16, -3, -20, 24, -22, 15, -3, -14,
- 22, -30, 31, -14, -11, 12, -11, 8, 17, -9, -4, -13, -13, 7, 10, 19,
- -6, -7, -2, -32, 24, 8, 0, 17, -20, -10, -15, 13, 10, 11, 4, -1,
- -40, 19, -4, -6, 42, -31, -1, -5, -12, 19, 6, 7, -5, -26, 10, -12,
- 15, 20, -8, -19, 12, -40, 31, 15, -3, 16, -23, -27, 7, -5, 31, 6,
- 3, -6, -41, 14, -2, 7, 38, -10, -29, 11, -44, 17, 29, 6, 20, -26,
- 1, -45, 9, 31, -18, 40, -1, -47, 8, -10, -4, 29, 33, -25, 1, -31,
- -12, -9, 35, 30, -25, 31, -48, -28, 20, 17, 9, 30, -19, -39, -13, 6,
- 8, 38, 15, -10, -42, 0, -24, 15, 49, -9, -12, 5, -44, -5, 42, 4,
- 6, 8, -27, -29, 5, 24, -2, 10, 28, -56, 1, 23, -29, 29, 15, -19,
- -11, 1, -4, -8, 24, 6, -15, 2, 7, -27, 12, 21, -40, 36, -15, -12,
- 22, -16, 17, -17, 15, -6, -18, 23, -3, -26, 39, -27, -5, 26, -20, 8,
- 5, -11, 7, -21, 19, -11, -8, 35, -25, 2, 18, -35, 9, 16, -21, 29,
- -16, 1, -13, -13, 28, -18, 23, 13, -36, 6, -1, -23, 26, 12, -15, 17,
- -20, -2, -7, 3, 22, -22, 27, -11, -34, 36, -30, 11, 17, 2, -12, 13,
- -22, -11, 11, -5, 26, -17, 26, -25, -32, 44, -47, 39, 25, -31, 16, -35,
- -1, -4, 26, 16, 3, -16, -10, -23, -8, 55, -27, 26, 0, -63, 41, -26,
- 28, 22, -23, 14, -42, 5, 20, -13, 28, 3, -42, 20, -6, -17, 52, -32,
- 6, -2, -37, 42, -27, 29, 15, -51, 40, -38, 2, 33, -19, 6, 11, -43,
- 25, 0, -19, 57, -54, 31, -9, -43, 58, -52, 36, 11, -44, 50, -44, 8,
- 23, -24, 12, 6, -34, 25, -9, -15, 50, -55, 35, -7, -25, 49, -48, 32,
- -23, -18, 37, -30, 28, 8, -27, 7, -2, -19, 22, 10, -11, 10, -27, 4,
- -16, 18, 29, -19, 20, -22, -36, 16, -2, 18, 14, 3, -24, -15, -5, 12,
- 13, 20, 4, -40, 2, -23, 8, 29, 7, 9, -23, -10, -13, 5, 19, 9,
- -3, -14, -7, -19, 21, 6, 5, 10, -20, 0, -14, 12, 0, 2, 5, -13,
- 1, -3, 12, -12, 20, -13, -7, 6, -11, 5, 0, 5, -5, -4, 10, -10,
- 2, 6, -5, -12, 18, -13, -9, 19, -17, 11, -1, 8, -5, -22, 26, -26,
- 1, 29, -17, -7, 16, -22, -8, 23, -3, 4, -3, -2, -15, -20, 42, -21,
- 4, 40, -55, 8, 8, -22, 21, 20, -17, 2, -14, -7, -2, 10, 31, -25,
- 10, -3, -54, 40, 5, -12, 42, -17, -37, 13, -12, 7, 24, 10, -6, -36,
- 12, -9, -25, 74, -24, -19, 38, -64, 5, 25, 0, 16, 1, -9, -25, -23,
- 36, -8, 6, 50, -58, -12, 22, -53, 52, 18, -12, 16, -51, 15, -30, 25,
- 46, -37, 31, -26, -49, 30, 9, -1, 42, -19, -28, -13, -5, 16, 4, 42,
- -18, -40, 20, -30, 1, 49, -4, -15, 0, -21, -19, 21, 26, 0, -9, 9,
- -43, -1, 26, -5, 21, -7, -6, -32, 9, 12, -3, 34, -17, -12, -17, -4,
- 9, 7, 28, -19, -3, -13, -11, 7, 15, 15, -19, 15, -38, -5, 17, -1,
- 29, -20, 15, -39, -11, 41, -33, 45, -8, -21, -11, -3, 7, 0, 28, -7,
- -19, -8, 7, -20, 23, 24, -40, 24, -17, -16, 26, -9, 21, -27, 13, -11,
- -22, 29, -7, 0, 22, -22, -16, 14, -12, 12, 11, -5, -6, -17, 14, -15,
- 9, 30, -28, 5, 1, -26, 8, 18, -7, 1, 6, -12, -15, 9, 13, -13,
- 13, 13, -42, 14, 3, -16, 20, 7, -3, -22, 25, -26, 4, 16, -7, 3,
- -8, 17, -33, 14, 9, -21, 25, -3, -11, -1, 1, -13, 1, 23, -20, 26,
- -18, 0, -18, 3, 24, -25, 36, -15, -29, 22, -22, 3, 24, -5, -1, 0,
- -18, 2, -11, 20, 10, -17, 30, -37, -15, 29, -33, 39, 11, -23, 7, -34,
- 8, 0, 11, 36, -27, -12, 9, -47, 29, 31, -29, 40, -37, -14, 3, -17,
- 45, -11, 8, 12, -60, 20, -2, -2, 41, -12, -18, 3, -37, 27, 12, -4,
- 37, -56, 17, -21, -5, 44, -20, 14, -2, -40, 20, 0, 3, 22, -13, -10,
- -6, -16, 29, -12, 14, 15, -49, 24, -11, -7, 39, -18, 3, -20, -12, 19,
- -10, 32, 2, -34, 10, -13, -13, 37, 1, -7, 3, -33, 4, 2, 18, 25,
- -25, 8, -33, -13, 34, -7, 24, 4, -33, -10, -2, 2, 25, 12, -1, -25,
- -12, 3, -18, 34, 12, -15, 4, -9, -25, 10, 17, -3, 9, 2, -13, -23,
- 9, 8, -13, 37, -10, -15, 1, -13, -1, 0, 31, -15, 0, 5, -29, 6,
- 5, 15, -9, 16, -9, -29, 15, -10, 3, 15, 9, -11, -12, 11, -29, 17,
- 14, -7, 6, -6, -7, -24, 30, -11, 9, 18, -20, -8, -6, 6, -10, 22,
- 10, -29, 14, -13, -8, 13, 17, -13, 2, 1, -24, 5, 5, 12, -10, 15,
- -7, -28, 21, -2, -8, 22, -9, -14, -2, 6, -5, 5, 12, -7, -15, 14,
- -4, -16, 27, -10, -14, 13, -5, -9, 10, 5, -8, -5, 16, -20, 2, 13,
- -14, -3, 17, -18, 2, 10, -12, 9, -6, -2, -16, 13, 10, -15, 33, -24,
- -17, 10, -4, 15, 1, 9, -23, -9, 6, -5, 5, 21, -10, -13, 11, -21,
- -2, 19, -10, 23, -20, 10, -16, -21, 33, -17, 17, 18, -30, 1, -14, -1,
- 20, -2, 18, -15, -24, 6, -5, 6, 36, -26, 6, -18, -23, 34, -12, 25,
- 1, -30, -1, -11, 10, 22, -1, 4, -19, -28, 21, -11, 22, 25, -33, 4,
- -21, -7, 22, 7, 19, -23, -13, -3, -13, 21, 17, -11, 7, -19, -12, 12,
- -10, 30, -13, -5, 4, -30, 27, -9, 17, -3, -25, 13, -23, 13, 27, -15,
- -5, 3, -35, 17, 19, -8, 29, -37, 1, -15, -10, 48, -20, 26, -7, -49,
- 22, -23, 21, 33, -10, -8, -17, -34, 11, 19, 12, 40, -39, -14, -13, -36,
- 64, -4, 20, 9, -55, 3, -24, 21, 31, 10, -1, -22, -30, -7, 12, 18,
- 29, -10, -7, -28, -22, 22, 3, 26, 4, -13, -18, -16, 21, -9, 28, -1,
- -21, 0, -12, 5, 6, 5, 10, -20, 1, 3, -20, 21, 7, -23, 24, -25,
- -6, 21, -13, 25, -19, -8, 2, -14, 20, 13, -23, 25, -31, -7, 24, -16,
- 20, 6, -25, 8, -24, 12, 15, -10, 24, -25, -2, 0, -12, 14, 10, -13,
- 4, 1, -17, 9, 6, -9, 9, 0, -3, -8, 11, -10, -2, 7, -1, -6,
- 6, 1, -12, 1, 18, -31, 23, -2, -21, 21, -6, -8, 15, -14, 4, -6,
- -1, 17, -22, 20, -6, -35, 37, -17, -6, 47, -41, 6, -6, -16, 12, 16,
- 6, 1, -36, 18, -26, 4, 59, -36, -1, 16, -64, 30, 14, 1, 16, -13,
- 0, -35, 17, 13, -8, 12, 14, -45, 11, 12, -24, 27, 12, -27, 10, -6,
- -9, 1, 14, -7, -6, 8, -4, -8, 8, 8, -24, 13, 7, -27, 28, -1,
- -28, 27, -19, -2, 17, -5, 6, -10, -5, 4, -25, 32, 2, -22, 32, -28,
- -20, 35, -20, 16, 7, -18, 1, -22, 20, 0, 2, 20, -15, -25, 24, -25,
- 12, 25, -23, 10, -19, -5, 8, 2, 20, -6, -13, 0, -22, 12, 15, -3,
- 13, -13, -25, 12, -6, 18, 13, -3, -14, -22, 3, -2, 14, 25, -10, -16,
- -5, -13, 2, 22, 9, -2, -11, -12, -20, 15, 20, 1, 14, -19, -17, -9,
- 1, 19, 5, 0, 4, -35, 17, -7, 5, 20, -16, 2, -8, -11, 11, -2,
- 2, 7, -19, 15, -10, 2, 12, -14, -3, 2, -9, 17, -3, 2, -7, -16,
- 10, 2, 9, 10, -14, -9, -6, -11, 21, 5, 4, 6, -24, -5, -4, 6,
- 18, 0, 8, -21, -18, 8, -8, 21, 16, -11, -9, -12, -15, 15, 3, 27,
- -9, -16, 5, -30, 13, 23, -11, 21, -19, -15, -3, -9, 30, -9, 14, -6,
- -22, -5, 15, -11, 23, -1, -14, -4, -9, 8, 4, 1, 20, -34, 9, 1,
- -17, 24, -6, 1, -9, 1, -4, 3, 6, 8, -16, 0, 2, -13, 11, 21,
- -31, 24, -21, -4, 13, -2, 7, -9, -3, 0, -18, 29, -4, -9, 16, -19,
- -13, 25, -5, -1, 15, -24, 4, -15, 22, 4, -11, 20, -21, -25, 39, -23,
- 14, 14, -23, 1, -8, 3, 12, -9, 23, -19, -18, 24, -22, 5, 30, -32,
- 11, 2, -21, 18, -6, 5, 1, -9, 13, -22, 4, 19, -28, 26, 3, -28,
- 21, -4, -25, 32, -15, 5, 0, -2, -4, -9, 15, 0, -13, 21, -14, -20,
- 31, -19, 2, 17, -14, -9, 12, -6, 4, -1, 4, -17, -1, 12, -2, 0,
- 20, -31, -8, 12, -8, 17, 14, -13, -16, -9, -7, 20, 11, 18, -13, -28,
- -3, -12, 13, 40, -12, 4, -20, -32, 8, 17, 14, 21, -10, -28, -18, -2,
- 11, 22, 17, 0, -34, -6, -3, -17, 50, 1, -13, 4, -22, -21, 17, 16,
- 4, 7, 0, -27, -11, 4, 10, 2, 24, -6, -28, 7, -12, -2, 33, -3,
- -6, 2, -37, 3, 9, 7, 24, -4, -14, -6, -24, 25, -1, 11, 16, -36,
- -9, 12, -25, 45, 5, -20, 11, -36, 11, 7, 0, 30, -32, -1, 7, -33,
- 37, 0, -9, 15, -21, -10, 12, -15, 24, -8, 3, 4, -20, 7, 3, -15,
- 28, -14, -7, 13, -23, 2, 11, 0, 4, 7, -9, -16, 1, 7, -7, 19,
- -3, -12, -14, 15, -10, 7, 30, -26, -13, 15, -30, 15, 26, -12, -1, -8,
- -9, -5, 13, 22, -12, -12, 7, -36, 17, 31, -24, 27, -21, -24, 15, -10,
- 26, 4, -12, 4, -36, 13, 14, -5, 27, -14, -22, 7, -12, 6, 23, -13,
- 7, -19, -2, 7, -8, 25, -5, -17, 18, -25, 3, 14, -8, 4, 0, -1,
- -11, 4, 12, -18, 15, 2, -23, 12, -2, -7, 12, 1, -1, -15, 11, -3,
- -17, 41, -24, -7, 13, -25, 3, 22, -9, 15, -12, -9, 0, -17, 32, -5,
- -5, 19, -49, 19, 3, -11, 45, -30, 2, -4, -28, 29, 0, 7, 12, -34,
- 6, -10, 1, 33, -9, -6, 4, -41, 25, 2, 4, 29, -40, 8, -17, -9,
- 42, -16, 16, -10, -33, 11, -7, 22, 12, -6, -6, -25, -4, 18, -3, 25,
- -4, -29, 5, -17, 8, 22, 1, 4, -22, 1, -13, 2, 31, -19, 9, 2,
- -36, 17, 5, -7, 20, -11, -2, -13, 4, 9, -18, 24, -3, -30, 33, -19,
- -11, 31, -21, 6, 0, -5, 3, -10, 17, -7, -19, 30, -24, 0, 26, -23,
- 3, 7, -17, 9, -3, 9, -1, -17, 23, -25, -3, 34, -27, 10, 15, -34,
- 9, 1, 1, 7, -1, 12, -31, 4, 16, -27, 32, 10, -33, 10, -1, -27,
- 29, 9, -9, 0, -1, -16, -6, 24, 2, -17, 23, -20, -24, 33, -11, -2,
- 17, -7, -21, 13, 1, -7, 10, 1, -12, -9, 13, -1, -5, 20, -16, -15,
- 15, -8, 5, 13, -10, -7, -9, 5, 2, 10, 7, -7, -22, 12, -13, 6,
- 26, -14, -6, 0, -17, 3, 16, 6, 0, -11, 3, -26, 13, 15, -6, 7,
- 4, -29, 6, 7, -3, 13, 1, -11, -9, 2, -1, 3, 9, -3, -8, 1,
- -4, 0, 5, 0, 0, -2, 0, -1, 0, 0, -2, 11, 23, 22, 24, 25,
- 20, 21, 15, 40, -1, -24, -42, -5, -19, -11, -8, 4, -46, -31, -14, -33,
- -40, -44, -48, -89, -63, -47, -33, -27, -10, -6, 22, 25, 26, 28, 37, 11,
- 15, 51, 44, 54, 66, 66, 71, 111, 84, 70, 63, 47, 39, 22, 47, -28,
- -79, -111, -90, -91, -112, -81, -87, -49, -46, -5, -24, 26, 24, 47, 29, 23,
- 30, 30, 13, -1, 4, -14, 17, 35, 62, 31, 53, 59, 72, 64, 27, 26,
- 9, 9, -61, -44, -88, -74, -81, -83, -124, -96, -37, -78, -48, -56, -68, -60,
- 7, 44, 39, 54, 77, 102, 110, 108, 89, 101, 100, 105, 64, 22, -1, 44,
- 40, -19, -29, -35, -16, -27, -40, -77, -82, -113, -104, -93, -57, -72, -56, -3,
- 1, 7, -1, 49, 39, 30, 31, 23, 10, 31, 11, 7, -19, -2, -2, 28,
- 62, 92, 75, 33, 34, -20, -47, -61, -85, -105, -93, -119, -112, -54, -70, -67,
- -32, -1, 4, 4, 20, 29, 62, 70, 54, 62, 78, 115, 92, 85, 78, 52,
- 21, 19, 27, 2, -8, 13, 0, 5, 3, 9, 18, 0, -59, -61, -45, -57,
- -65, -76, -89, -102, -48, -24, 17, 6, 26, 33, 35, 26, 41, 63, 20, 12,
- 29, 34, 8, 7, 31, 21, 31, 39, 33, -5, -8, -55, -57, -98, -94, -88,
- -64, -82, -74, -39, -14, 3, 16, 22, 8, 2, 17, 5, 36, 76, 74, 71,
- 57, 73, 62, 47, 30, 32, 19, 4, 7, -14, -18, -2, 17, -5, 13, 22,
- 31, 10, 8, -13, -47, -80, -85, -86, -71, -73, -60, -35, -10, 9, 19, 49,
- 53, 47, 60, 73, 43, 33, 20, 13, -1, -7, -7, 7, 9, -2, 5, -14,
- -40, -69, -61, -66, -67, -84, -58, -58, -33, 2, -7, -5, 12, 32, 18, 25,
- 19, 24, 65, 59, 62, 64, 63, 55, 60, 52, 31, 19, -12, -26, -4, -7,
- -10, -3, 6, -22, -14, 12, 19, 4, -26, -38, -40, -56, -61, -66, -59, -65,
- -51, -20, 29, 40, 51, 52, 62, 61, 53, 26, 20, 6, 8, 6, 9, -14,
- -14, -15, -2, -11, -23, -36, -38, -60, -77, -69, -60, -51, -56, -44, -27, 10,
- -2, 14, 10, 22, 16, 41, 60, 39, 35, 60, 62, 43, 45, 63, 52, 17,
- 12, 15, -1, -2, 0, -38, -48, -32, -22, -7, 3, 13, 10, -2, -1, -8,
- -12, -25, -48, -46, -52, -49, -36, -17, 9, 17, 26, 48, 57, 55, 69, 60,
- 32, 6, 4, -6, -20, -24, -9, -21, -25, -14, -18, -38, -38, -32, -51, -52,
- -60, -34, -6, -6, -16, -11, -2, -1, 17, 19, 3, 11, 25, 31, 41, 39,
- 33, 33, 41, 34, 34, 23, 21, 15, 6, -13, -24, -28, -20, -8, -12, -19,
- -12, -5, 9, 14, 2, -12, -25, -28, -21, -28, -23, -22, -18, -26, -5, 24,
- 45, 46, 47, 39, 33, 36, 42, 29, 7, -5, -10, -21, -29, -39, -39, -31,
- -24, -29, -39, -51, -43, -27, -22, -18, -25, -26, -20, 9, 19, 18, 4, -2,
- 19, 30, 38, 25, 24, 28, 33, 41, 38, 34, 32, 38, 24, 8, 4, -8,
- -11, -15, -25, -31, -25, -20, -22, -15, -11, -9, -12, -17, -20, -20, -15, -6,
- -11, -8, 0, 11, 29, 19, 17, 17, 18, 28, 31, 25, 18, 23, 18, 10,
- 1, -7, -18, -26, -24, -30, -41, -38, -44, -32, -31, -31, -35, -25, -12, -2,
- -8, -11, -13, -13, -2, 8, 15, 19, 29, 35, 37, 39, 43, 42, 40, 35,
- 27, 25, 18, 15, 9, 4, -4, -15, -28, -28, -26, -28, -18, -15, -25, -23,
- -12, -11, -14, -10, -2, -4, -1, 8, 15, 19, 22, 25, 16, 16, 17, 5,
- 7, 13, 18, 13, 9, 6, 6, 4, -4, -21, -31, -28, -37, -39, -34, -38,
- -38, -32, -17, -6, -4, -14, -19, -9, 3, -2, 3, 4, 7, 8, 13, 23,
- 35, 38, 43, 42, 31, 25, 23, 17, 8, 3, 4, -7, -7, -10, -13, -20,
- -19, -28, -33, -30, -23, -18, -13, -17, -12, 3, 14, 23, 31, 27, 23, 21,
- 22, 19, 12, 4, 2, 2, -2, 0, 4, 11, 11, 6, 4, -2, -5, -14,
- -17, -30, -38, -44, -42, -28, -21, -23, -21, -15, -15, -4, 8, 11, 4, -7,
- -15, -7, 5, 10, 21, 26, 28, 27, 34, 37, 36, 28, 19, 10, 11, 8,
- -2, -18, -17, -19, -19, -22, -24, -21, -24, -18, -17, -13, -19, -13, -1, 12,
- 19, 22, 21, 19, 19, 30, 34, 24, 13, 7, 2, 1, 1, 2, -1, -2,
- -6, 0, 0, -2, -15, -21, -17, -21, -28, -32, -31, -31, -32, -27, -24, -17,
- -4, 1, -3, -1, 1, 4, 7, 8, 15, 16, 15, 15, 20, 32, 36, 38,
- 32, 19, 12, 3, 2, -2, -4, -11, -19, -17, -15, -11, -16, -20, -27, -30,
- -28, -22, -13, -6, -2, 2, 12, 23, 29, 45, 44, 36, 32, 21, 16, 14,
- 10, 1, -9, -8, -2, -1, -7, -13, -13, -12, -9, -11, -18, -24, -26, -28,
- -30, -24, -21, -21, -21, -11, -11, -10, 0, -2, 0, 4, 12, 13, 14, 12,
- 17, 22, 28, 30, 28, 20, 16, 13, 8, 2, -2, -6, -15, -14, -18, -15,
- -15, -16, -18, -18, -16, -19, -18, -17, -10, 0, -1, 4, 13, 22, 37, 39,
- 36, 27, 27, 32, 26, 15, 6, -1, -4, -5, -7, -11, -11, -9, -15, -15,
- -14, -18, -21, -19, -17, -21, -19, -15, -15, -10, -15, -14, -12, -11, -6, -2,
- 1, -2, 1, 5, 14, 22, 33, 35, 23, 18, 16, 13, 11, 6, 1, -9,
- -18, -11, -6, -7, -8, -9, -11, -11, -12, -13, -17, -21, -24, -24, -15, -4,
- 7, 12, 17, 25, 30, 28, 31, 32, 31, 27, 22, 15, 12, 3, -2, -8,
- -6, -3, -9, -13, -22, -24, -20, -18, -22, -24, -18, -14, -13, -10, -11, -9,
- -3, -2, -3, -5, -10, -10, -5, -1, 4, 11, 15, 19, 22, 27, 23, 20,
- 16, 14, 5, -3, -11, -15, -16, -12, -12, -11, -5, 1, -3, -10, -13, -15,
- -11, -10, -10, -11, -8, -3, 2, 7, 9, 15, 25, 30, 33, 31, 25, 21,
- 20, 16, 13, 7, -2, -8, -5, -4, -11, -20, -21, -22, -21, -17, -20, -21,
- -22, -19, -19, -11, -4, -2, -2, -2, 2, 5, 2, 0, 0, -3, 1, 8,
- 16, 13, 14, 17, 15, 13, 8, 5, -1, -6, -10, -13, -14, -14, -13, -10,
- -7, -8, -8, -6, -6, -3, -1, -1, -9, -12, -7, 3, 13, 17, 14, 13,
- 17, 22, 23, 24, 18, 15, 18, 18, 18, 15, 8, 0, -5, -8, -11, -15,
- -17, -21, -26, -26, -24, -26, -24, -13, -9, -6, -3, -2, 3, 4, 6, 7,
- 5, 2, 4, 2, -2, -4, -3, 5, 13, 17, 10, 3, -1, -2, -4, -5,
- -11, -14, -13, -11, -8, -8, -8, -6, -3, 0, -1, -5, -5, 0, 4, 3,
- 1, 2, 0, 0, 6, 13, 20, 17, 17, 18, 21, 18, 14, 13, 11, 11,
- 7, 9, 3, -5, -12, -14, -18, -21, -23, -26, -26, -13, -3, -6, -13, -14,
- -5, 5, 8, 3, 0, 1, 3, 6, 4, -1, -1, 1, 3, 7, 5, 3,
- 0, 1, -1, 3, 0, -3, -11, -11, -9, -10, -9, -8, -5, -7, -7, -10,
- -9, -6, -1, 4, 6, 4, 2, 5, 10, 13, 9, 12, 13, 14, 15, 16,
- 13, 12, 10, 13, 14, 13, 8, 2, -1, -4, -6, -9, -15, -20, -21, -19,
- -14, -16, -22, -21, -13, -5, -3, -3, -1, 3, 5, 10, 9, 9, 6, 8,
- 7, 7, 7, 3, -4, -6, -4, -1, -4, -8, -10, -11, -8, -4, -6, -10,
- -7, -8, -11, -11, -8, -5, -4, 0, 3, 3, 8, 10, 10, 12, 12, 11,
- 10, 13, 12, 10, 6, 8, 9, 9, 11, 13, 11, 9, 10, 7, 2, -3,
- -8, -9, -14, -16, -16, -19, -18, -14, -13, -11, -11, -10, -5, -1, 3, 5,
- 2, 2, 9, 14, 11, 9, 10, 7, 2, 0, 2, -2, -9, -13, -15, -18,
- -17, -15, -13, -10, -5, -5, -7, -7, -4, -1, 0, -2, -4, -2, 1, 4,
- 9, 10, 10, 11, 11, 13, 14, 10, 11, 9, 9, 4, 6, 5, 4, 5,
- 7, 8, 10, 9, 4, -4, -8, -9, -10, -11, -12, -14, -15, -17, -15, -9,
- -4, -1, -6, -5, 2, 8, 8, 6, 5, 3, 4, 5, 9, 10, 10, 5,
- -1, -5, -10, -12, -14, -16, -18, -17, -11, -10, -11, -8, -5, -2, -2, 0,
- 3, 4, 5, 3, 2, 3, 5, 9, 12, 12, 11, 10, 12, 14, 12, 8,
- 5, 0, -1, 1, 3, 0, 1, 3, 5, 6, 5, 0, -5, -11, -10, -13,
- -12, -13, -15, -14, -8, -4, -3, -3, -4, 0, 4, 5, 3, 6, 4, 4,
- 7, 10, 9, 9, 8, 5, 5, 2, -4, -10, -15, -17, -20, -22, -22, -19,
- -14, -11, -10, -8, -6, 0, 3, 5, 3, 4, 8, 11, 11, 12, 13, 12,
- 12, 15, 15, 16, 16, 13, 11, 6, 3, -2, -5, -5, -3, -2, -1, 2,
- 0, -3, -4, -5, -7, -10, -12, -11, -12, -11, -8, -4, -2, 0, 1, 2,
- 2, 2, 4, 3, 3, 4, 5, 9, 10, 6, 2, 1, 2, 0, -3, -7,
- -13, -18, -19, -18, -16, -18, -20, -19, -14, -8, -4, -1, 3, 3, 5, 7,
- 9, 9, 10, 12, 13, 13, 13, 13, 16, 15, 13, 9, 6, 3, 2, 1,
- 0, -3, -5, -6, -4, -2, -2, -4, -4, -5, -5, -3, -3, -4, -6, -6,
- -7, -4, 0, 2, 3, 2, 2, 1, 2, 2, 1, 4, 5, 4, 1, 0,
- 2, 2, 0, -2, -6, -8, -6, -7, -9, -11, -15, -18, -19, -18, -18, -17,
- -13, -9, -2, 2, 3, 5, 10, 12, 13, 14, 14, 15, 17, 17, 16, 16,
- 15, 13, 11, 7, 2, -6, -10, -8, -6, -8, -8, -7, -6, -6, -3, -4,
- -6, -5, -3, -2, -2, 0, 1, 0, 2, 2, 3, 2, 3, 2, 3, 3,
- 5, 2, 0, 4, 6, 5, -1, -4, -2, -1, -2, -6, -8, -9, -10, -12,
- -10, -14, -17, -22, -22, -21, -19, -15, -8, -3, 1, 7, 12, 12, 15, 19,
- 22, 21, 18, 16, 16, 16, 13, 12, 6, 3, 3, 2, -3, -6, -7, -12,
- -12, -11, -8, -9, -8, -7, -3, 0, 0, 0, 0, -2, -2, 0, 1, 2,
- 2, 4, 6, 6, 7, 5, 4, 3, 4, 5, 3, 0, -2, -2, -4, -6,
- -10, -8, -8, -10, -11, -12, -12, -12, -13, -16, -16, -16, -14, -11, -8, -4,
- -2, 1, 6, 12, 17, 19, 20, 20, 21, 21, 19, 13, 10, 9, 5, 0,
- -3, -4, -4, -5, -6, -6, -4, -7, -10, -12, -12, -12, -10, -7, -4, -2,
- 4, 6, 8, 7, 7, 7, 7, 8, 8, 7, 5, 6, 6, 4, 1, -1,
- -1, 0, -3, -7, -10, -10, -8, -11, -14, -14, -12, -11, -9, -6, -8, -8,
- -8, -11, -13, -12, -9, -8, -5, 0, 4, 8, 11, 14, 18, 18, 20, 23,
- 23, 20, 14, 9, 4, 0, -3, -6, -8, -8, -8, -8, -9, -10, -11, -10,
- -9, -8, -8, -7, -6, -3, 0, 3, 6, 12, 16, 16, 14, 10, 8, 9,
- 7, 4, 1, 0, 0, -2, -1, 0, 0, -3, -7, -10, -13, -13, -12, -13,
- -15, -14, -13, -9, -6, -5, -5, -7, -8, -9, -7, -6, -5, -7, -5, 1,
- 8, 13, 17, 19, 20, 21, 22, 22, 18, 12, 9, 5, -1, -5, -9, -11,
- -13, -12, -12, -11, -10, -8, -7, -7, -6, -7, -6, -3, 0, 1, 3, 7,
- 10, 11, 12, 15, 15, 14, 9, 6, 3, 1, 0, -2, -2, -2, -3, -6,
- -8, -10, -11, -13, -15, -15, -15, -13, -12, -12, -7, -5, -5, -5, -4, -3,
- -3, -4, -4, -1, -1, 1, 4, 7, 10, 12, 14, 17, 20, 22, 19, 14,
- 8, 5, 2, -2, -5, -10, -14, -13, -11, -10, -10, -10, -10, -8, -6, -3,
- -3, -3, -1, -1, 2, 6, 10, 13, 14, 15, 15, 15, 13, 11, 8, 5,
- 1, -1, -3, -3, -6, -10, -12, -12, -12, -12, -13, -15, -18, -19, -15, -11,
- -6, -4, -3, -4, -4, -2, 1, 4, 2, -1, -2, 1, 4, 6, 8, 7,
- 7, 11, 14, 15, 15, 15, 13, 10, 6, 1, -3, -6, -9, -13, -15, -15,
- -13, -11, -9, -9, -9, -7, -3, 0, 2, 2, 4, 7, 11, 15, 16, 14,
- 11, 12, 13, 15, 13, 9, 4, 1, -1, -4, -6, -8, -11, -15, -17, -17,
- -17, -17, -15, -13, -13, -12, -10, -7, -6, -4, 1, 2, 2, 3, 4, 5,
- 4, 4, 3, 5, 6, 6, 8, 7, 7, 9, 11, 10, 9, 8, 5, 2,
- 0, -2, -6, -10, -13, -13, -14, -14, -13, -11, -9, -4, -1, -1, -1, 2,
- 6, 8, 10, 11, 12, 14, 14, 14, 13, 11, 10, 7, 4, 2, 3, 1,
- -3, -6, -10, -14, -17, -18, -18, -19, -19, -17, -15, -13, -9, -5, -1, 1,
- 0, 1, 3, 5, 6, 6, 6, 7, 8, 9, 8, 4, 1, 0, 2, 4,
- 5, 6, 5, 4, 4, 4, 3, 1, -3, -7, -9, -11, -12, -12, -12, -11,
- -10, -7, -4, -2, 1, 4, 5, 8, 11, 13, 14, 14, 11, 11, 11, 10,
- 10, 9, 6, 5, 3, 1, -2, -5, -10, -14, -16, -17, -18, -19, -20, -19,
- -17, -14, -10, -5, -1, 1, 3, 5, 6, 6, 6, 6, 6, 6, 6, 6,
- 8, 7, 6, 4, 2, 0, -1, 0, 0, 1, 2, 1, 1, 2, 1, -2,
- -5, -8, -9, -10, -11, -12, -12, -10, -7, -4, -1, 2, 8, 11, 13, 15,
- 15, 13, 12, 11, 10, 9, 8, 6, 5, 4, 4, 3, 0, -3, -6, -10,
- -14, -18, -21, -22, -21, -18, -16, -13, -10, -6, -3, 0, 3, 5, 5, 5,
- 6, 7, 8, 8, 8, 7, 8, 7, 6, 5, 4, 1, 0, -2, -4, -4,
- -5, -4, -4, -3, -2, -1, -2, -3, -4, -7, -8, -9, -9, -9, -8, -5,
- -2, 2, 4, 8, 11, 14, 15, 15, 14, 12, 10, 7, 5, 4, 4, 2,
- 1, 1, 2, -1, -3, -7, -10, -15, -18, -18, -18, -18, -17, -15, -11, -7,
- -3, 1, 3, 4, 5, 6, 7, 7, 8, 8, 9, 10, 10, 9, 6, 4,
- 2, 0, -3, -4, -6, -7, -7, -6, -5, -3, -2, -2, -2, -2, -3, -4,
- -5, -6, -6, -6, -6, -5, -4, -1, 4, 7, 9, 11, 12, 12, 11, 10,
- 9, 8, 7, 5, 3, 3, 2, 1, 0, -1, -4, -7, -8, -10, -13, -14,
- -15, -15, -15, -14, -11, -9, -6, -3, 0, 2, 4, 5, 6, 7, 8, 9,
- 10, 10, 9, 8, 6, 5, 3, 1, -3, -6, -8, -8, -7, -7, -7, -6,
- -4, -2, 0, -1, -2, -3, -3, -3, -3, -4, -3, -3, -1, 1, 3, 4,
- 6, 7, 8, 9, 10, 10, 9, 7, 6, 6, 4, 3, 2, 1, -1, -2,
- -4, -6, -9, -11, -12, -12, -12, -11, -11, -10, -9, -8, -7, -5, -4, -1,
- 1, 3, 5, 7, 9, 10, 11, 10, 9, 8, 7, 6, 2, -1, -3, -4,
- -6, -7, -7, -7, -7, -6, -5, -5, -4, -3, -3, -4, -4, -4, -3, -2,
- 0, 0, 1, 1, 2, 4, 6, 6, 7, 7, 8, 7, 7, 7, 7, 7,
- 6, 5, 2, 0, -2, -4, -5, -7, -8, -8, -8, -9, -10, -10, -9, -8,
- -7, -7, -7, -5, -3, -2, 0, 1, 2, 4, 6, 9, 10, 11, 12, 10,
- 8, 6, 3, 1, -2, -4, -6, -7, -7, -7, -7, -8, -7, -7, -6, -6,
- -5, -4, -3, -3, -2, -1, 1, 2, 2, 3, 4, 5, 5, 5, 6, 6,
- 6, 5, 5, 6, 6, 6, 4, 3, 2, 1, -1, -3, -4, -6, -8, -9,
- -9, -8, -8, -6, -5, -5, -5, -6, -6, -6, -5, -4, -2, 0, 2, 4,
- 6, 7, 8, 9, 9, 9, 9, 6, 4, 1, -1, -3, -5, -6, -7, -7,
- -7, -6, -6, -6, -6, -6, -5, -4, -3, -3, -2, -1, 1, 3, 4, 5,
- 5, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 1,
- -1, -3, -4, -5, -6, -7, -7, -7, -7, -7, -6, -5, -4, -4, -3, -3,
- -3, -3, -2, -1, 0, 1, 3, 5, 7, 8, 8, 8, 7, 6, 4, 2,
- 0, -2, -3, -4, -5, -6, -7, -7, -7, -7, -6, -6, -5, -5, -5, -3,
- -2, 0, 1, 2, 3, 4, 5, 6, 6, 6, 5, 5, 4, 3, 3, 3,
- 3, 3, 3, 2, 1, 1, -1, -2, -3, -4, -5, -6, -6, -7, -6, -5,
- -4, -3, -3, -3, -3, -3, -2, -1, -1, 0, 1, 1, 1, 2, 3, 5,
- 6, 6, 6, 5, 4, 2, 1, 0, -2, -4, -5, -5, -6, -6, -6, -7,
- -7, -7, -6, -5, -4, -3, -2, -1, 0, 2, 3, 3, 4, 4, 5, 5,
- 5, 4, 4, 4, 4, 3, 3, 2, 1, 1, 0, 0, -1, -1, -2, -3,
- -4, -5, -5, -5, -5, -5, -4, -4, -3, -3, -2, -1, -1, -1, -1, 0,
- 0, 0, 1, 2, 3, 3, 4, 4, 4, 4, 4, 3, 1, 0, 0, -2,
- -3, -4, -5, -5, -6, -6, -6, -5, -4, -4, -4, -3, -2, -2, -1, 0,
- 2, 3, 3, 4, 4, 4, 4, 3, 3, 3, 3, 2, 2, 1, 1, 1,
- 0, -1, -1, -2, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -2, -2,
- -2, -1, -1, -1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2,
- 2, 1, 1, 0, 0, -1, -1, -2, -3, -3, -3, -4, -4, -4, -4, -3,
- -3, -2, -1, -1, -1, 0, 1, 1, 1, 2, 2, 2, 3, 3, 2, 2,
- 1, 1, 1, 0, 0, 0, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -5, -41, -25, -37, -9, 28, 14, 6, 1,
- 19, 16, -83, -53, -35, -44, -29, 8, -23, -29, -6, -20, -22, -19, -40, -2,
- 14, 34, 78, 59, 73, 93, 73, 83, 124, 94, 87, 61, 98, 80, 29, 27,
- 6, 8, -9, -8, -26, -33, -35, -32, -25, -32, -28, -59, -46, -31, -19, -12,
- -12, 14, 14, -41, -59, -46, -33, -32, -52, -31, -29, -49, -51, -53, -85, -53,
- -60, -100, -85, -84, -66, -37, -26, -11, -8, 22, 41, 33, 39, 27, 29, 75,
- 59, 45, 52, 69, 66, 73, 90, 91, 103, 81, 46, 16, -21, -32, -13, -34,
- -22, -42, -51, -35, -53, -62, -45, -35, -34, -29, 25, 62, 61, 39, -8, -20,
- -5, -7, 2, 28, 1, -24, 8, 29, 11, -9, -54, -34, -35, -57, -41, -63,
- -50, -16, -18, 26, 23, -2, 38, 9, 17, 41, 39, 82, 64, 64, 103, 64,
- 43, 43, 51, 26, -3, 30, 1, 9, 14, -26, 20, -27, -50, -39, -47, -31,
- -23, -33, 25, 56, 51, 20, -19, -60, -41, -27, -10, 3, -36, -30, -22, -46,
- -5, -12, -7, -4, -54, 3, -25, -10, -1, -42, -75, -27, -84, -60, -88, -107,
- -73, -29, -67, -53, 9, -10, 17, -29, -33, 55, 12, 7, 121, 70, 42, 123,
- 96, 127, 74, 28, 51, 21, 60, 23, -10, 25, 103, 113, 65, 45, 15, -1,
- 10, 2, -26, 1, -16, 19, 27, -8, -8, -24, -20, -17, -35, -86, -87, -32,
- -51, -26, -60, -60, -50, -15, -31, -30, -50, -55, -19, 22, 14, 30, 49, 42,
- 15, -11, -57, -15, -29, -65, -37, -56, -29, 15, 70, 69, 36, 24, 19, 21,
- 19, 4, 60, 55, 18, -17, 0, -2, -21, 51, 49, -6, 22, 14, -24, -63,
- -5, 4, -53, -33, -1, -37, -34, 40, 30, 12, -6, -1, 12, 12, 23, 20,
- 43, 34, 11, -26, -40, 25, 56, -1, -41, -50, -37, -10, 20, -58, -65, -43,
- -26, 42, 57, 77, 57, 26, -4, -10, -57, -45, -23, -49, -1, -59, -41, -26,
- -27, 24, 52, -3, -12, 19, -44, -31, 33, 11, -14, 43, 31, 7, 58, 84,
- 45, 35, 18, -5, 6, -21, -6, -20, -7, 41, 53, 29, 25, 55, 68, 37,
- -29, -17, -41, -67, -76, -90, -112, -104, -60, -21, 25, 16, -23, -9, 30, 47,
- 17, 3, 19, 4, -2, 30, 24, 1, 26, 33, 34, 10, 14, 1, -5, 16,
- -2, -60, -32, -51, -48, -38, -34, -42, -20, 16, 17, -16, -32, -6, 4, -39,
- -18, 1, -20, -22, 55, 70, 34, 5, -1, 13, 2, 1, 28, 20, -31, -2,
- 51, 26, 24, 19, 11, -1, 2, 30, 13, 2, 70, 36, 15, 24, 5, 9,
- 14, 48, 43, 8, 2, -10, 18, 33, 22, -27, -19, -17, -22, 11, 19, -5,
- 0, -55, -60, -49, -63, -72, -45, -80, -55, -18, -8, 32, 52, 22, 0, -40,
- -42, -30, -68, -51, -9, -67, -52, -10, 7, 35, 12, 36, 64, 23, 13, 64,
- 39, 32, 73, 3, 6, -10, -6, 16, 18, 53, 51, 21, -20, -15, 13, -3,
- 2, -39, -30, -7, -3, 6, 10, -4, -25, -7, -10, -10, -18, -31, -23, -38,
- -48, -3, -26, -43, -7, 11, 31, 62, 41, -7, -34, -42, -24, 17, 12, 44,
- 25, 24, 18, 11, 32, 51, 46, 46, 51, 33, 24, 32, 30, 40, 8, -30,
- -39, -30, -44, -19, -33, -55, -41, -36, -70, -67, -64, -34, -37, -46, 1, 19,
- 27, 81, 23, 13, 10, -5, -18, -19, -51, -14, -48, -75, 11, 51, 43, 63,
- 37, 20, 19, 4, -23, 27, 47, 71, 29, 16, 15, -17, -11, 32, 40, 22,
- 6, 16, -7, 5, 34, 61, 12, -21, -24, -13, -38, -41, -36, -33, 2, 9,
- -45, -54, -36, 12, -18, -41, -25, -18, 19, 31, -11, -16, -22, -62, -65, -68,
- -42, -4, -48, -49, 4, 38, 65, 47, 12, -20, -20, -8, 3, 32, 69, 84,
- 44, 28, 31, 18, 36, 57, 74, 35, 19, 6, 24, 29, 36, 35, 6, -13,
- -25, -43, -45, -35, -33, -44, -23, -41, -57, -52, -41, -35, -21, -16, -22, -11,
- 33, 42, 14, 19, 16, 0, -6, -34, -17, -37, -25, -7, 6, 48, 47, 3,
- -14, -17, -19, -11, -9, -11, 42, 42, 16, 1, 6, 15, 51, 42, 33, 29,
- 20, -5, -3, 4, 54, 42, 8, -30, -19, -15, -15, -20, -6, -7, -24, -32,
- -24, -17, -1, -16, -18, -36, -55, -38, -2, 8, 16, 7, -21, -35, -56, -67,
- -17, -58, -67, -36, 21, 67, 48, 15, 8, 13, -9, -8, -1, 21, 107, 56,
- 40, 56, 32, 33, 71, 60, 36, 30, 3, 31, 15, 4, 21, 2, -2, -25,
- -30, -26, -13, -9, -26, -20, -34, -34, -51, -28, 6, -9, -24, -49, -67, -54,
- -54, -52, -41, -42, -58, -37, 16, 39, 31, 16, 19, 11, -4, -23, -5, 24,
- 1, 10, 24, 26, 15, 34, 70, 77, 56, 33, 43, 28, 17, 25, 12, 2,
- 0, -12, -15, -2, 10, -19, -28, -45, -41, -28, -17, -3, -2, -9, -3, -25,
- -45, -14, 23, 10, -5, -19, -32, -22, -10, -1, -15, -16, -6, 13, 48, 70,
- 55, 23, 23, 10, -8, -14, 6, 8, -12, -5, 13, 10, -14, 0, 33, 23,
- 18, 43, 21, 26, 33, 13, -14, -7, -3, -31, -29, -5, -5, -25, -27, -35,
- -56, -45, -21, -17, -40, -14, 2, -23, -38, -9, 8, -16, -16, -7, -13, -25,
- -4, -12, -21, -14, 3, 13, 44, 65, 60, 40, 15, 5, -20, -22, -3, 3,
- 20, 39, 39, 9, 6, 21, 48, 24, 25, 25, 11, 0, 4, -5, -31, -34,
- -22, -45, -40, -24, -24, -41, -38, -47, -54, -45, -16, -22, -32, -7, 16, -1,
- -11, 23, 31, -1, -10, -20, -19, -9, 15, -10, -28, -21, 4, 24, 45, 60,
- 56, 46, 30, 26, 23, 36, 48, 33, 46, 40, 34, 19, 12, 23, 43, 37,
- 41, 43, 22, 24, 11, -11, -2, -5, 8, -28, -33, -11, -5, -26, -30, -25,
- -45, -21, -8, -26, -35, -37, -39, -54, -56, -20, -23, -42, -52, -49, -63, -47,
- -31, -29, -16, -21, -7, 14, 26, 48, 32, 12, -10, -22, -24, -6, 0, 33,
- 44, 31, 25, 15, 10, 34, 48, 38, 14, 9, 16, 12, -23, -15, -15, -8,
- -9, -19, -22, -2, -8, -10, -32, -27, 4, 12, -5, 1, -1, 4, -5, -3,
- -5, 10, 37, 18, -8, -19, -3, 0, -10, -5, -31, -32, -29, -2, 18, 32,
- 33, 14, -12, -15, 6, 8, 36, 66, 48, 38, 37, 42, 29, 49, 50, 42,
- 28, 25, 33, 15, 2, 4, 2, 4, 2, -11, -1, 6, 3, 9, -14, -12,
- -5, -12, -33, -36, -29, -26, -38, -44, -42, -38, -38, -52, -67, -70, -50, -32,
- -27, -29, -38, -26, -27, 1, 21, 23, 16, -17, -34, -26, -18, -20, 2, 11,
- 13, 5, 10, 13, 12, 28, 33, 35, 14, 14, 14, -8, -24, -25, -8, -16,
- -23, -14, 12, 8, 21, 25, 13, 25, 29, 25, 6, 3, 36, 26, 34, 11,
- 30, 29, 34, 23, 0, 1, 7, 8, 1, -10, -9, -13, 5, 17, 30, 26,
- 25, 3, -11, -4, -4, 9, 13, 17, 6, 4, 17, -1, -4, 9, 16, 22,
- 3, -2, -4, -16, -28, -22, -13, -34, -37, -31, -9, -7, -12, -16, -26, -12,
- -14, -11, -23, -16, -24, -33, -24, -30, -17, -28, -34, -44, -51, -34, -24, -22,
- -25, -2, 14, 23, 38, 46, 43, 28, 10, -6, -11, 1, 0, 5, 18, 16,
- -3, 12, 27, 23, 32, 48, 42, 34, 21, 21, 10, -3, -10, -10, -20, -38,
- -34, -29, -22, -16, -15, -17, -9, 7, 6, 6, -6, 1, 7, 6, 3, 11,
- 30, 30, 15, 11, 11, 10, 17, 22, 23, 24, 9, 15, 5, -2, 4, 3,
- -17, -21, -4, -21, -6, 8, -9, -1, 0, 8, -7, -18, -16, -3, -14, -13,
- -8, -17, -10, -8, -26, -37, -28, -17, -35, -17, -10, 1, -6, 1, 25, 32,
- 26, 9, -18, -19, 1, -12, -20, 2, 12, 5, -4, 15, 14, 15, 15, 17,
- 14, 2, 6, 3, -18, -21, -9, -1, -15, -11, -15, -22, -1, 3, -7, 0,
- 14, 14, -4, -13, 4, 18, 12, 15, 19, 25, 28, 27, 12, 9, 9, -10,
- -17, -4, -5, -4, -20, -19, 11, 20, 13, 0, -19, -8, 6, -9, 6, 26,
- 18, 14, 17, 22, 24, 18, 21, 37, 20, 7, 11, -8, -11, -4, -3, -8,
- -22, -16, -18, -15, -4, -9, -21, -10, 5, -8, -7, -17, -7, -9, -20, -28,
- -35, -31, -23, -23, -29, -28, -28, -33, -28, -24, -6, 0, -4, 7, 29, 25,
- 15, -6, -19, 1, -2, -22, 4, 10, 1, 9, 10, 13, 4, 6, 21, 15,
- 5, 21, 11, -18, -21, -15, -3, -4, -15, -15, -19, 4, 19, 11, 2, 17,
- 16, 2, 14, 14, 17, 20, 22, 20, 10, 16, 27, 12, 8, 11, 5, -9,
- -10, -6, -1, -7, -12, -3, 3, 8, 9, -5, -3, 6, -5, -6, 23, 14,
- 11, 12, 21, 21, 4, 18, 30, 7, 12, 25, 3, -11, -16, -15, -10, -13,
- -8, -6, -21, 2, -2, -25, -18, -8, -22, -22, -17, -12, -7, -12, -15, -20,
- -41, -28, -24, -23, -12, -12, -15, -10, -7, 2, 1, 6, 18, 29, 23, 21,
- 20, 9, -3, -9, -9, -10, -15, -8, -11, -2, 6, 14, 7, 7, 11, 9,
- 14, 2, 3, 7, 6, 6, -21, -20, -10, -12, -15, -16, -18, -14, -11, -14,
- 0, 0, -5, 3, 14, 12, 9, 0, -11, 5, 5, 12, 11, -1, 5, 3,
- 1, 4, -1, -1, 13, 16, 8, 14, 9, -2, -7, -11, -17, -12, -5, -9,
- -10, -13, -4, 1, 0, 4, 5, 0, 2, 3, 5, 14, 18, 9, -3, 2,
- 15, 14, 6, 2, 1, -1, -5, -6, 0, 0, 0, 7, 20, 22, 23, 13,
- 13, 17, 20, 35, 25, 20, 20, 14, 17, 16, 3, 7, 18, 15, 13, 17,
- 6, -5, -6, -13, -23, -19, -19, -22, -22, -24, -17, -18, -22, -27, -31, -30,
- -29, -30, -33, -36, -34, -37, -47, -38, -24, -28, -27, -31, -30, -28, -26, -20,
- -14, -14, -9, 4, 17, 21, 15, 12, 25, 29, 33, 33, 30, 30, 31, 19,
- 20, 14, 4, 10, 17, 18, 21, 28, 19, 20, 20, 5, -2, -3, -7, -10,
- -2, 1, 4, 6, 4, 5, 3, 2, -1, -4, -7, -10, -3, -6, -16, -5,
- -1, -8, -7, -6, -9, -10, -11, -7, -6, -10, -11, 2, 11, 7, 1, 6,
- 12, 16, 18, 15, 11, 14, 16, 9, 11, 6, 5, 13, 14, 13, 11, 0,
- -11, -4, -4, -8, -7, -5, -6, -3, -1, 2, -1, -6, -7, -9, -9, -9,
- -15, -11, -14, -17, -16, -18, -17, -12, -7, -8, -7, -6, -2, -3, -12, -15,
- -15, -18, -13, -19, -23, -24, -21, -21, -13, -12, -7, -3, -7, -6, -4, 2,
- 1, 1, 3, 9, 23, 28, 23, 17, 24, 27, 22, 19, 16, 19, 10, 9,
- 10, 10, 19, 8, 11, 16, 15, 11, 13, 14, 7, 5, -3, -7, -12, -15,
- -16, -17, -10, -5, 4, -2, -2, -9, -13, -9, -8, -10, -10, -12, -5, 3,
- 7, 3, 9, 3, 4, -1, -2, 2, -4, -9, -4, 0, 4, 4, -6, -3,
- 12, 10, 15, 12, 7, 7, 1, -1, 8, 11, 9, 9, 13, 17, 17, 9,
- 11, 4, 0, -3, -6, -8, -9, -10, -17, -20, -24, -17, -19, -22, -20, -21,
- -15, -16, -19, -23, -21, -28, -26, -15, -14, -4, -1, -6, -3, -1, 4, 9,
- 2, 4, 7, 7, 11, 15, 6, 17, 24, 16, 15, 9, 6, 6, 3, 1,
- 3, 2, -2, 6, 6, 6, 3, -6, -3, -8, -7, -10, -13, -17, -18, -16,
- -19, -13, -9, -3, 4, 10, 7, 7, 12, 11, 13, 10, 6, 1, 2, 4,
- 4, 10, 10, 7, 4, 1, 4, -5, -12, -3, 1, 10, 7, 6, 4, 19,
- 22, 20, 23, 16, 15, 19, 17, 14, 9, 7, 4, 4, 2, 5, 3, 0,
- 0, -7, -7, -8, -7, -14, -15, -18, -25, -21, -21, -16, -13, -14, -17, -18,
- -23, -21, -23, -29, -32, -33, -30, -23, -13, -11, -10, -8, -7, -2, 1, -3,
- -1, 5, 13, 17, 13, 11, 13, 16, 14, 10, 11, 8, 16, 13, 4, 0,
- 7, 13, 14, 15, 15, 17, 17, 9, 8, 9, 9, 2, 5, 11, 14, 7,
- 4, 11, 10, 5, 7, 2, -1, -4, -9, -16, -15, -12, -9, -15, -23, -21,
- -22, -22, -20, -22, -22, -21, -22, -22, -13, -6, 4, 2, -2, 2, 7, 6,
- 10, 8, 9, 12, 21, 16, 11, 7, 11, 13, 11, 10, 11, 13, 9, 6,
- 6, 5, 4, -5, 1, 4, 5, -1, -2, 6, 3, 3, -3, -10, -14, -14,
- -14, -16, -8, -6, -1, -6, -7, -5, -7, -6, -9, -8, -8, -4, -5, -8,
- -6, 3, 12, 4, -2, 3, 1, 1, -1, -4, -4, 5, 6, 1, -4, -3,
- 5, 9, 8, 18, 20, 22, 15, 11, 11, 15, 12, 9, 11, 11, 11, 5,
- 10, 12, 5, 3, -2, -4, -9, -9, -16, -17, -14, -12, -14, -20, -15, -16,
- -17, -17, -19, -20, -19, -15, -17, -15, -13, -2, -3, -13, -8, 0, 4, 7,
- 6, 4, 11, 13, 14, 11, 5, 6, 3, -1, -2, 2, 3, -1, -2, -6,
- -4, -1, -3, 0, 3, 1, -2, -5, -5, -3, -6, -9, -7, -15, -13, -10,
- -8, -4, 1, 9, 7, 2, 8, 8, 9, 12, 14, 7, 12, 12, 12, 8,
- 14, 19, 11, 7, 10, 13, 10, 2, -2, -6, -1, 2, 6, 3, 1, 4,
- 2, 2, 5, 8, 8, 7, 7, 2, 0, -3, -6, -3, -1, -6, -12, -9,
- -6, -7, -9, -10, -14, -16, -12, -12, -11, -13, -16, -16, -20, -18, -14, -10,
- -8, -9, -13, -9, -8, -9, -7, -9, -8, -3, -4, -3, -6, 0, 2, 3,
- -3, 2, 5, 1, 6, 5, 5, 10, 11, 17, 15, 20, 25, 20, 15, 17,
- 13, 12, 11, 7, 4, -1, -2, 6, 7, 7, 9, 10, 7, 9, 7, 5,
- 5, 1, -6, -2, -5, -6, -3, -3, -1, -3, -5, -3, -6, -8, -7, -8,
- -11, -12, -16, -19, -19, -14, -14, -17, -17, -11, -12, -15, -6, -8, -12, -12,
- -9, -7, -6, 2, 9, 6, 8, 11, 13, 15, 14, 11, 7, 3, 3, 4,
- 7, 9, 10, 6, 6, 5, 7, 11, 11, 4, 1, 1, -3, -5, -1, -1,
- -1, -5, -2, -1, -1, 1, 1, -3, -7, -7, -9, -12, -11, -3, -3, -7,
- -6, -6, -5, -5, 0, -3, -4, -2, 2, -1, 0, 6, 7, 7, 4, 3,
- 5, -1, 0, -1, -7, -9, -8, -11, -5, 0, -1, 0, 2, 2, 5, 10,
- 10, 7, 7, 7, 8, 8, 9, 11, 9, 8, 9, 6, 4, 2, 0, -3,
- -5, -8, -8, -12, -8, -1, -4, -4, -5, -7, -9, -6, -5, -6, -8, -6,
- -3, -7, 0, 5, 6, 3, 1, 6, 6, 4, 3, 1, -2, -4, -6, -4,
- 3, 7, 3, 0, -1, -3, -2, -1, -2, -5, -8, -9, -7, -9, -8, -6,
- -9, -7, -9, -7, -6, -7, -6, -7, -7, -7, -7, -8, -2, 1, 2, 4,
- 3, 5, 6, 10, 11, 9, 10, 12, 9, 9, 11, 9, 10, 8, 7, 7,
- 6, 7, 5, 4, 5, 4, -1, -4, -3, -5, -1, -2, -4, -4, -4, -4,
- -2, -2, -3, -4, -2, -1, 0, 1, 8, 8, 4, 4, 4, 2, -2, -3,
- -5, -6, -9, -10, -8, -5, 2, 1, -2, -2, -2, -2, -2, -5, -5, -7,
- -7, -3, -4, -6, -4, -3, -5, -7, -5, -4, -7, -9, -6, -6, -9, -7,
- -6, -2, 3, 3, 4, 5, 3, 4, 5, 2, 0, 2, 3, 2, 5, 7,
- 10, 9, 7, 7, 6, 4, 1, -2, -5, -6, -10, -10, -8, 2, 8, 7,
- 6, 7, 5, 5, 7, 6, 3, 4, 3, 4, 1, 3, 2, 4, 2, 1,
- 1, -1, -3, -3, -4, -6, -9, -9, -9, -7, -6, -5, -5, -4, -5, -2,
- -1, -2, -3, -1, -1, -3, -2, 2, 2, 3, 4, 4, 2, 0, -1, -3,
- -4, -4, -5, -7, -2, 2, 2, -1, -3, -1, -4, -3, -2, -4, -4, -2,
- -1, -2, -4, -2, -2, -1, -2, -2, -2, -3, -2, 0, 2, 0, -2, -2,
- 0, 2, 3, 5, 4, 4, 4, 6, 3, 1, 0, 0, 0, 0, 5, 5,
- 4, 6, 4, 2, 0, -2, -3, -6, -9, -8, -10, -10, -2, 3, 4, 4,
- 4, 5, 4, 4, 5, 4, 4, 4, 4, 2, 3, 2, 2, 2, 1, 1,
- 0, -2, -3, -3, -4, -6, -8, -7, -4, -6, -3, -3, -3, -2, 1, 0,
- -1, -2, -2, -1, -1, 0, 1, 0, 0, 1, 0, 0, 0, -1, -2, -3,
- -3, -4, -5, -4, -3, -3, -3, -3, -3, -3, -2, -1, 0, -1, 0, 0,
- 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 2, 3,
- 3, 2, 2, 0, -1, -1, -2, -3, -3, -4, -5, -4, 0, 3, 3, 3,
- 3, 2, 3, 4, 6, 4, 4, 3, 2, 1, 2, 1, 0, 0, -1, -2,
- -3, -3, -2, -2, -3, -3, -3, -3, -3, -2, -2, -2, -2, -2, -2, -2,
- -2, -3, -2, -3, -2, -2, 0, 0, 0, 0, 0, -1, -1, -2, -2, -3,
- -2, -4, -4, -3, 0, -1, 0, 0, 0, 0, 0, 1, 2, 1, 1, 1,
- 0, 0, 0, -1, 0, -1, -1, -1, -1, -1, 0, 0, -1, 0, 0, 0,
- 1, 1, 1, 1, 1, 1, 0, 0, 0, -1, 0, -1, 0, 0, 0, 0,
- 0, 0, -1, -1, -2, -2, -2, -2, -2, -3, -3, -1, 0, 0, 0, 0,
- 0, 0, 0, 1, 1, 1, 0, 0, 0, -8, -33, -24, -25, -25, -26, -27,
- -32, -28, -36, -31, -36, -22, -34, 11, -74, -14, 94, 41, 28, 33, 30, 40,
- 34, 23, 41, 40, 60, 56, 59, 60, 44, 39, 54, 45, 52, 17, 44, 62,
- 34, 33, 19, 18, 43, 35, 22, 36, -15, -10, 32, -7, -12, -6, -8, -50,
- -47, -44, -4, -25, -48, -76, -58, -75, -96, -85, -118, -114, -63, -106, -103, -83,
- -110, -99, -84, -76, -58, -63, -61, -51, -53, -36, -32, -41, -27, -11, 11, 8,
- 27, 19, 30, 35, 28, 57, 53, 38, 71, 51, 68, 110, 78, 89, 109, 97,
- 82, 94, 115, 114, 79, 70, 79, 94, 85, 76, 84, 95, 83, 82, 55, 54,
- 54, 41, 41, 27, 20, 6, -11, -21, -16, -14, -33, -33, -52, -54, -59, -62,
- -71, -79, -88, -88, -78, -78, -72, -71, -94, -99, -93, -90, -78, -87, -105, -103,
- -79, -62, -71, -78, -63, -61, -66, -49, -23, -10, -11, -24, -20, -4, -22, 9,
- 8, 27, 43, 34, 38, 51, 83, 65, 58, 74, 75, 70, 73, 71, 65, 100,
- 89, 94, 65, 84, 49, 49, 61, 54, 43, 51, 58, 53, 35, 40, 36, 38,
- 34, 23, 14, -12, -10, -1, -1, -11, -12, -19, -33, -66, -52, -42, -37, -55,
- -42, -28, -32, -29, -35, -41, -28, -25, -46, -85, -64, -62, -55, -49, -68, -55,
- -53, -52, -47, -43, -26, -32, -41, -34, -35, -40, -26, -8, -1, -6, -11, 5,
- -2, 8, 3, 8, 6, 4, 20, 29, 43, 24, 33, 20, 30, 24, 39, 38,
- 40, 29, 37, 36, 39, 61, 58, 41, 51, 59, 51, 55, 58, 48, 32, 45,
- 40, 27, 30, 41, 44, 26, 19, 23, -3, 7, 0, -3, 2, 3, -6, -5,
- -14, -6, -10, -27, -45, -47, -41, -38, -50, -51, -46, -43, -45, -65, -65, -80,
- -95, -82, -74, -66, -69, -67, -33, -31, -53, -48, -51, -43, -18, -24, -24, -33,
- -26, -10, 0, -17, -6, 17, 31, 2, 23, 45, 46, 12, 75, 38, 63, 69,
- 31, 38, 80, 57, 48, 59, 81, 74, 32, 52, 72, 24, 60, 44, 55, 40,
- 28, 48, 33, 24, 10, -2, 21, 34, 13, 18, 7, -1, -12, -20, -18, -30,
- -9, -7, -30, -27, -26, -38, -20, -54, -55, -64, -53, -36, -62, -37, -71, -47,
- -42, -71, -45, -55, -50, -54, -56, -36, -37, -54, -36, -12, -38, -33, -26, -7,
- -22, -44, -10, 2, 3, 15, 8, 18, 6, 12, 8, 15, 28, 22, 50, 35,
- 55, 42, 36, 49, 52, 64, 48, 60, 49, 60, 62, 40, 47, 68, 52, 59,
- 61, 44, 53, 44, 35, 31, 31, 47, 22, 6, 4, -7, 5, -4, -21, -13,
- -9, -10, -27, -46, -32, -44, -46, -62, -44, -51, -67, -53, -59, -63, -74, -67,
- -61, -61, -65, -47, -58, -57, -45, -41, -46, -41, -38, -22, -25, -34, -16, -10,
- -18, 0, 1, -6, 5, 17, 15, 10, 23, 38, 28, 28, 54, 40, 19, 55,
- 55, 41, 46, 53, 40, 49, 51, 52, 41, 56, 39, 53, 38, 33, 35, 18,
- 15, 38, 30, 23, 27, 13, 11, 7, 16, -1, 0, 0, 13, -6, -10, -15,
- -10, -10, -24, -20, -16, -38, -36, -21, -40, -32, -42, -38, -52, -53, -41, -48,
- -58, -50, -47, -37, -41, -45, -29, -41, -6, -48, -24, -25, -15, -9, -10, -10,
- -10, -1, -17, 4, 3, 10, -4, 9, 15, 25, 24, 19, 23, 34, 28, 33,
- 37, 38, 26, 36, 47, 35, 46, 45, 28, 35, 32, 32, 24, 21, 26, 23,
- 19, 37, 20, 9, 29, -2, 26, 24, 8, 4, 14, 21, 11, -9, -8, 4,
- -9, -31, -11, -15, -21, -24, -29, -22, -33, -26, -29, -48, -32, -44, -28, -22,
- -35, -30, -38, -31, -46, -44, -36, -27, -23, -29, -24, -11, -20, -28, -13, -34,
- -19, -1, 7, -3, -1, 6, -3, 5, 4, 8, 17, 26, 19, 33, 27, 16,
- 35, 14, 36, 39, 22, 32, 31, 19, 32, 23, 29, 21, 30, 29, 23, 31,
- 13, 24, 17, 11, 26, 18, 12, 5, 23, 16, 9, 15, -10, 3, 18, -15,
- -4, -4, 6, -14, -15, -5, -34, -11, -20, -18, -8, -17, -29, -30, -29, -19,
- -34, -35, -20, -36, -20, -16, -21, -38, -16, -30, -24, -25, -19, -18, -15, -7,
- -5, -5, -10, -23, -3, -14, 0, -1, -12, -9, 7, 7, 2, 12, 5, 7,
- 19, 10, 21, 21, 27, 30, 22, 18, 34, 22, 11, 26, 24, 20, 21, 25,
- 29, 22, 27, 27, 20, 10, 20, 16, 22, 15, 16, 16, 5, 19, 10, 3,
- 22, -5, -5, -7, -16, -4, -11, -22, -7, -16, -11, -23, -16, -30, -24, -28,
- -20, -29, -24, -32, -22, -22, -30, -17, -23, -28, -22, -20, -21, -21, -17, -30,
- -15, -14, -20, -9, 3, 6, 5, -20, 10, 13, -2, 11, 8, -1, 7, 16,
- 5, 22, 23, 13, 22, 13, 22, 25, 15, 16, 11, 15, 13, 7, 12, 19,
- 18, 20, 12, 23, 11, 6, 10, 1, 11, 19, 5, 20, 0, 11, 11, 1,
- 14, 15, -3, -1, -7, 6, -6, -9, -9, 4, -3, -10, -20, -14, -9, -14,
- -7, -10, -5, -4, -29, -14, -12, -26, -21, -27, -18, -10, -19, -27, -18, -8,
- -25, -8, -13, -15, -14, -15, 5, -13, -7, -11, -4, -12, 0, 15, 5, 4,
- 1, 11, 6, 4, 3, 6, 21, 19, 8, 15, 13, 6, 14, 16, 18, 17,
- 20, 15, 11, 15, 24, 13, 11, 19, 7, 17, 14, 6, 17, 7, 7, 6,
- 6, 5, 11, 0, 6, 0, -6, 5, 1, -11, -6, -1, -8, -9, -15, -7,
- -4, -16, -17, -13, -13, -17, -14, -12, -12, -28, -13, -19, -25, -31, -24, -17,
- -17, -16, -7, -15, -12, -8, -15, -8, -16, -10, -4, -1, -2, 3, 5, 2,
- -2, 5, 3, 6, 10, 8, 11, 14, 14, 13, 15, 22, 16, 14, 18, 13,
- 17, 19, 16, 10, 17, 8, 17, 14, 3, 14, 7, 10, 10, 7, 6, 6,
- -1, 6, 1, 0, 12, -6, 6, 12, -4, -5, -4, -2, -2, -1, -2, -8,
- -11, -9, -11, -11, -18, -6, -5, -16, -9, -14, -10, -13, -10, -11, -15, -14,
- -14, -12, -17, -17, -17, -7, -11, -14, -15, -12, -6, -15, -5, -13, -9, 0,
- 12, -2, -2, 6, 2, -7, 4, 10, 2, 9, 8, 7, 4, 5, 11, 15,
- 11, 10, 18, 9, 13, 13, 13, 21, 11, 18, 19, 13, 14, 16, 6, 8,
- 1, 19, 11, 10, 11, 1, 3, -1, -1, 5, -11, 5, -1, -5, -3, -13,
- -10, -6, -7, -5, -15, -10, -11, -18, -8, -16, -20, -18, -9, -12, -17, -21,
- -21, -13, -21, -8, -10, -10, -5, -16, -7, 2, -6, -6, -9, -7, -2, -9,
- -5, 6, -7, 1, 3, -1, 2, 1, 2, 9, 8, 5, 15, 12, 1, 11,
- 9, 8, 10, 15, 14, 5, 13, 17, 14, 15, 10, 7, 16, 5, 5, 5,
- 8, 9, 10, 10, 7, 0, 4, 6, 9, -10, -4, 5, 2, -1, 0, -3,
- -4, -5, -10, -5, -8, -9, -10, -3, -13, -6, -9, -20, -15, -11, -18, -14,
- -10, -12, -20, -14, -14, -7, -12, -21, -14, -9, -8, -11, -5, -2, -7, -4,
- 4, -2, -3, -1, 0, -1, 8, 6, 9, 7, 10, 6, 3, 4, 7, 10,
- 11, 6, 9, 17, 11, 9, 7, -2, 16, 13, 12, 18, 5, 16, 9, 4,
- 9, 6, 8, 9, 4, 4, 3, -2, -3, 2, -6, -3, 1, -7, -6, -3,
- -6, -14, -8, -9, -4, -13, -9, -8, -16, -10, -12, -13, -11, -7, -8, -12,
- -9, -8, -7, -11, -4, -8, -7, -8, -3, -13, -10, -3, 6, -5, -5, 0,
- -5, -3, 6, -2, -2, 4, -2, 6, 2, -2, 5, 5, -2, 5, 15, 13,
- 4, 6, 6, 14, 9, 4, 8, 7, 3, 11, 12, 2, 10, 7, 10, 8,
- 4, 6, 2, 0, 3, 2, 4, 2, -6, -2, 2, -4, 3, -5, -6, -5,
- -5, -5, -4, -8, -7, -4, -4, -7, -8, -7, -13, -10, -10, -11, -9, -8,
- -8, -7, -11, -7, -3, -9, -6, -7, -3, -4, -5, 3, -3, -1, -2, -4,
- 1, 4, 0, 3, 0, 5, 2, 0, 5, 4, 1, 3, 1, 0, 1, 7,
- 3, 0, 4, 3, 6, 5, 0, 9, 5, 7, 6, 3, 6, 2, 3, 5,
- -4, 9, 0, 4, 10, 0, 5, 1, -2, 4, -3, -3, -2, 0, 2, -7,
- 3, -10, -1, -6, -9, -2, -4, -10, -3, -7, -6, -4, -10, -6, -6, -11,
- -6, 0, -6, -8, -4, -1, -9, -10, 0, -6, -7, -2, -7, 1, -5, -5,
- -1, 1, -6, 2, 0, -3, -1, 7, -4, 0, 7, 0, 8, 2, 3, 4,
- 4, 2, 5, -1, 6, 7, 5, 6, 4, 2, 4, 6, 8, 6, 3, 1,
- 8, 9, 2, -1, 4, 3, 4, 3, -3, 7, 4, 3, -2, 2, -4, -6,
- -2, -5, -2, -3, 0, -5, -6, -13, -5, -6, -11, -9, -10, -5, -4, -9,
- -9, -7, -7, -8, -8, -6, -5, -7, -5, -1, -3, -4, -2, -2, 2, -3,
- 1, 2, -3, 1, 2, 1, 0, 1, 5, 0, 2, 5, 2, 0, 4, 1,
- 7, 3, 2, 6, 0, 5, 7, 5, 5, 1, 3, 3, 5, 10, 3, 4,
- 8, 2, 7, 3, -2, 3, 0, -1, -1, 1, 0, 1, -3, -2, -5, -4,
- -3, -1, -7, -8, -4, -4, -10, -2, -8, -8, -8, -8, -9, -6, -8, -9,
- -4, -2, -7, -5, -2, -7, -6, -9, -2, 0, -4, 4, -6, -3, -4, -1,
- 2, 1, 2, 9, 0, 3, 0, 6, 4, 0, 5, 6, 2, 7, 7, 5,
- 7, 6, 8, 6, 6, 5, 5, 1, 6, 5, -1, 3, 4, -1, 4, 1,
- 4, 3, -5, 0, 4, 1, 4, -2, -3, -4, 0, -4, -8, -2, -5, -4,
- -8, -6, -5, -3, -3, -7, -9, -6, -10, -10, -6, -6, -5, -4, -7, -6,
- -4, -10, -3, -10, 0, -2, -2, -6, -1, 3, -3, -3, 1, 2, 1, 4,
- 3, 4, 3, 4, 1, 2, 6, 5, 5, 5, 7, 9, 1, 5, 4, 4,
- 7, 2, 9, 2, 4, 8, 2, 5, 6, 3, -2, -2, -1, -2, -1, 1,
- -2, -4, 1, -6, -2, -5, -3, -5, -5, -6, -4, -3, -4, -10, -4, -3,
- -8, -4, 0, -3, -5, -6, -6, -3, -1, -7, -3, 1, -1, -4, -2, 1,
- -2, 0, -1, -2, 0, 0, 5, -2, 0, 3, 3, 1, 5, 2, 4, 1,
- 4, 1, 2, 3, 3, 3, 4, 3, 3, 5, 1, 4, 2, 3, 1, 2,
- 0, 2, 1, -2, -2, -1, 0, -2, -1, -1, -3, -5, -2, 0, -5, -1,
- 0, -5, -2, -2, -2, -3, -3, -1, -4, -1, -2, -4, -2, -1, -2, -1,
- 0, -3, -1, -1, 0, 1, -1, -1, 3, -4, -2, -2, 4, -2, -1, -1,
- -1, 0, 0, -1, -1, -1, -1, 2, 0, -1, 2, -1, 0, -1, 2, 0,
- 3, 5, -2, 1, 2, 0, 5, 0, -3, 4, -3, 1, 2, 0, 4, -1,
- -2, 1, 0, 0, 0, -1, 1, -2, 0, 1, 1, 0, -5, 1, -2, -1,
- 0, -2, -3, -1, -3, 0, -2, -3, -4, 1, -2, -3, -2, -2, -1, -1,
- -2, -1, -4, -5, 2, -4, 0, 1, -1, 2, -2, -1, 0, 0, 1, -3,
- 3, 2, 0, -2, 2, 1, 2, -2, 5, 3, -2, -2, -1, 1, 0, 0,
- 1, 3, 2, 0, 0, -1, -2, 1, 1, 2, 1, 1, -1, 0, -1, -1,
- -1, -3, 1, 1, 2, -2, -1, 0, 0, -2, 0, -1, -1, 2, -2, 1,
- -1, 0, 0, -1, -1, -2, 0, -1, 1, -1, -1, 2, -2, 0, -1, -1,
- 2, -1, 0, -3, -1, 0, 0, 0, -3, -3, -2, 0, 0, -1, -1, 0,
- -4, 2, 0, -2, 0, 1, -3, -1, 2, 1, 0, -1, 0, 0, -1, 0,
- 2, -1, -1, 0, 0, -2, 1, 1, 0, 1, 0, 2, -3, -2, 2, -1,
- -1, 2, -2, 1, 1, 0, 0, 1, 1, 0, -4, 3, -1, 2, 0, 2,
- -1, -2, 0, 1, 1, -1, -1, -1, -1, -1, -2, -2, -2, -2, -2, -1,
- -1, 1, 0, -5, 0, -1, -1, -1, 1, -1, 1, -1, 1, 0, -2, 0,
- -2, 1, -1, 1, 0, -1, -2, 0, -1, 0, 0, 2, 0, 0, 0, 1,
- 0, 0, 2, 0, -1, 0, 0, 0, 2, -1, 1, 1, -1, -1, 0, 0,
- 1, 1, 0, 0, 0, 0, -1, 0, 0, -2, 0, 0, -1, 1, -2, -1,
- -1, -1, -2, -1, -2, 1, -1, 0, -2, -2, 1, -2, -1, 1, 0, 1,
- 1, -1, -1, 0, -1, 0, 0, 0, -2, 0, -1, 0, 0, -1, -2, -2,
- -2, 1, -1, 0, 0, -1, 1, 1, -2, -1, -2, -1, 1, -1, -1, -2,
- -2, 0, 0, 1, -1, -1, -1, -1, -2, 2, 0, 0, 1, 1, 1, -2,
- 0, -1, 0, -1, -1, 2, 0, -1, -1, -1, 1, -1, 2, 0, -1, 1,
- 1, 0, 1, 0, -1, -1, -1, -1, -3, 0, 0, -1, 1, 0, 0, -2,
- -2, -2, 0, -1, 0, 0, -1, 0, -1, -2, -1, -2, 0, -2, 0, 0,
- -1, -2, 1, -2, 0, -1, -2, 2, 0, -1, 2, -1, 1, -1, 0, 0,
- -1, 0, 0, 0, -1, 0, 1, 0, 0, 1, 0, -1, -1, 0, -2, -1,
- 0, 0, 1, 0, 0, 0, 0, -1, -1, 1, -1, -2, -1, 0, 0, -2,
- 0, -1, 0, 0, 0, 1, 0, 0, -1, 1, 0, -1, 0, 1, -1, 0,
- -1, -2, 0, -1, 0, -1, -1, -1, 0, -1, 0, 0, 0, -1, -1, 0,
- -2, 0, 0, 0, -2, -2, 0, -2, -1, -1, -1, -2, 0, -1, -1, -1,
- 0, 0, -1, -1, 0, 1, -1, -1, 0, -1, 0, 0, 1, 1, 0, 0,
- -1, 0, 0, 0, 0, 0, 1, -1, 0, 0, 0, 1, 0, 0, -1, 0,
- 0, -1, -1, 0, -1, -1, 0, -1, 0, -1, -1, 0, -2, -1, 0, -1,
- -1, -1, -1, 0, -1, 0, 0, 0, 0, -1, 1, 0, 0, 0, -1, -1,
- 0, -1, -1, 0, 0, 0, 0, 0, -1, -1, 0, -1, -1, 0, 0, -1,
- 0, -2, 0, -1, -1, -1, 0, -1, -1, 0, -1, 0, 0, 0, -2, -1,
- 0, -1, -1, 0, 1, -1, -1, 0, 0, 0, 0, -1, -1, -1, -1, 0,
- 1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, -1, 0, 0,
- -1, 0, 0, -1, -1, -1, 0, 0, -1, -1, 0, -1, 0, 0, 0, -1,
- 0, -1, -1, 0, -2, -1, -1, -1, 0, -1, 0, -1, -1, 0, 0, -1,
- 0, -1, 0, -1, -1, -1, 0, -1, 0, -1, 0, 0, -1, 0, -1, 0,
- 0, -1, -1, 0, 0, 0, -1, 0, -1, 0, 1, -1, 0, 0, 0, 0,
- 0, -1, 0, 0, 0, -1, 0, 0, -1, -1, 0, 0, 0, -1, 0, 1,
- -1, -1, -1, 0, 0, -1, -1, -1, -1, 0, -1, 0, 0, 0, 0, 0,
- 0, -1, -1, 0, -1, -1, 0, -1, 0, -1, -1, -1, -1, 0, -1, -1,
- -1, -1, -1, -1, -1, 0, -1, 0, -1, 0, 0, -1, -1, 0, -1, 0,
- -1, 0, 0, -1, 0, -1, -1, -1, 0, -1, 0, 0, 0, 0, 0, -1,
- -1, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, -1, 0, 0, 0,
- 0, -1, 0, -1, 0, 0, 0, -1, -1, 0, 0, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, 0, 0, -1, -1, -1, 0, 0, 0, -1, 0, -1, -1,
- 0, -1, 0, 0, -1, -1, -1, -1, -1, 0, 0, -1, 0, 0, -1, 0,
- 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, -1, 0, 0, 0, 0,
- -1, 0, 0, 0, 0, -1, 0, 0, -1, 0, -1, 0, 0, -1, -1, -1,
- 0, -1, -1, 0, -1, -1, 0, 0, -1, -1, -1, -1, 0, -1, -1, 0,
- 0, -1, 0, 0, 0, -1, -1, 0, -1, -1, -1, 0, 0, -1, -1, -1,
- -1, -1, 0, -1, 0, 0, -1, -1, 0, 0, -1, 0, 0, -1, -1, -1,
- 0, -1, 0, 0, -1, -1, 0, 0, -1, -1, 0, 0, 0, -1, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1,
- 0, 0, 0, -1, 0, -1, 0, -1, -1, -1, -1, -1, -1, 0, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, 0, -4, 11, 6, 16, 10, -16, -48,
- -44, 2, 67, 42, -17, -51, 15, 71, 12, -22, -14, -44, -35, 11, 17, -18,
- 2, -15, 19, 12, -1, -44, -15, 50, 45, -25, -61, 17, 10, -10, 31, 18,
- -72, -27, 57, 26, -13, -17, -2, 6, -1, -23, -54, 17, 39, 8, 30, 28,
- -6, -71, -5, 33, 27, -5, 17, 10, -23, -6, 12, -26, -6, -7, -9, -14,
- 11, 37, 41, 8, -33, -14, 8, -31, -38, 13, 9, 15, 35, 33, 11, 17,
- -41, -48, -33, 29, 25, 16, -9, -9, -17, -19, -29, 43, 64, -2, -55, -42,
- -1, -21, -4, 29, 34, -25, -67, -29, 1, 51, 49, 25, -6, -15, -48, -76,
- -3, 60, 78, 33, 19, 13, -38, -35, -35, -2, 62, 19, -4, -12, -4, -4,
- -32, -30, 8, 68, -43, -66, -28, 55, 51, 20, -28, -29, -19, 20, -2, 8,
- 21, -15, -43, 24, 22, -7, -2, 35, 15, -2, -24, -12, 3, 31, 13, -15,
- -20, -17, -17, 26, -26, 24, -3, 7, 21, 26, -3, -17, -26, -50, -26, 33,
- 58, 49, -22, -67, -17, 24, 7, -57, 5, 42, -11, -3, 32, -3, 7, 13,
- -11, -9, 27, 17, 1, -5, -9, -18, -19, -3, -23, -5, 7, -8, 9, 13,
- 12, -5, 7, -37, 22, 26, 21, 24, -20, -35, 23, 24, -35, -15, 46, -38,
- -48, -14, -4, 0, -22, 3, 43, 38, -1, -14, -8, -5, -14, 1, 21, 23,
- 29, -19, -47, -42, -49, -10, 66, 77, 48, -29, -32, 1, -11, 8, 17, -17,
- 3, 43, 33, -22, -19, -41, 29, 22, -42, 9, 63, 28, -23, -59, -65, 7,
- 53, -22, -10, -27, -30, 36, 48, -4, -6, -22, -16, 10, 14, -7, 22, 50,
- -4, -25, -41, -55, -62, 23, 68, -16, -31, 49, 57, 21, -38, 14, 12, -43,
- -49, -16, 28, 7, -12, -50, -17, 49, 65, 18, 1, -8, 28, 2, -27, -13,
- 12, -11, -52, 4, 31, -32, -39, 15, 8, -19, 6, 25, -1, -23, 13, 34,
- 59, 36, -16, -5, -7, -28, -30, 1, -14, -42, 10, 43, 26, -25, -37, -61,
- 1, 63, 62, 1, -36, -24, 38, -7, -26, 27, 10, 4, 2, -19, -22, -27,
- -24, 0, 33, -8, -57, -12, 62, 77, 51, -10, -42, -27, -28, -31, -3, 5,
- 21, 10, 15, -27, -18, -18, -10, 3, 17, 19, 18, -16, -20, 25, -3, -19,
- -5, 32, 17, -3, -32, -8, 2, -11, -24, -17, -11, 3, 42, 15, -12, -2,
- 26, 9, -4, -30, -3, 16, 7, 13, 34, 40, 114, 11, -104, -71, 7, -14,
- -34, -26, 35, 45, 47, 7, -7, -16, 11, -6, -29, -32, 1, 24, 32, 10,
- 29, -10, -74, -80, -20, 18, 9, 18, 61, 38, -27, -44, 13, 16, -26, 20,
- 69, 14, -14, -46, -7, -6, -35, 0, 9, 5, 58, 71, -36, -78, -15, 43,
- 34, -61, -101, -27, 45, 26, -10, 23, 69, 69, 5, -72, -62, 19, 16, -37,
- -60, 37, 60, 10, -49, -10, -2, -1, 43, 44, 10, -50, -5, 19, 8, -43,
- -58, -17, 32, 28, 4, -1, -18, -10, 13, 8, 1, 1, 22, -3, -4, 9,
- -8, -9, 17, 3, -15, -8, 14, 11, -14, -11, -5, 13, -24, -34, -1, -16,
- -4, 32, 35, -32, 9, 22, 12, -27, -16, 14, 15, 0, -2, -12, -31, -24,
- 14, 48, 10, -14, -7, -22, 4, -8, -14, 19, 21, -21, -25, -12, 19, 24,
- 19, 27, -3, -15, -16, 10, 21, -14, 3, 8, 3, -11, -33, -16, 7, 5,
- -8, 2, -3, 12, 5, -34, -19, -6, 26, 19, 0, -4, -12, 5, 12, 20,
- 16, 19, 18, -13, -42, -26, -1, 0, -18, -16, 10, 27, 23, -5, -7, 9,
- -8, 7, 22, 10, -28, -51, -26, 13, 44, 17, 16, 25, 14, -32, -45, -36,
- -40, -3, 22, 41, 34, -12, -35, -31, 18, 3, 31, 28, 4, -21, 2, -14,
- -24, -23, 19, -6, -7, -10, -1, -13, -13, 21, 52, 28, 7, 1, -25, -36,
- 2, 34, 10, -37, -31, -13, 19, 11, -4, -20, 15, -5, -18, 40, -13, 15,
- -36, 14, 18, 17, -21, 6, -39, 21, 7, -26, 8, -33, 24, 30, 32, -11,
- -26, -47, -39, 62, 10, 11, 5, -17, -21, 10, 0, 18, 15, -22, 7, 13,
- 14, -8, -9, 30, 33, -34, -41, -32, 37, 24, -19, -15, 1, 2, 10, 10,
- -27, -46, -14, -9, 9, 47, 1, -22, -18, 5, 37, 29, -3, -19, -19, -18,
- 8, 17, 1, -11, -6, -20, 27, 37, -2, -28, -34, -3, 22, 54, 34, -31,
- -43, -28, -30, -33, 26, 49, 45, 43, -15, -58, -13, -2, -27, -7, 41, 11,
- 19, -50, -74, -28, 31, 75, 39, -45, -7, 99, 44, -83, -47, 45, -1, -30,
- 23, 29, -55, -30, 31, 28, -19, 2, -44, -46, -49, 30, 22, 58, 31, -50,
- -20, 9, -38, -53, 49, 37, -9, 13, -25, -18, 18, -27, -7, 17, 3, 24,
- 57, 26, -51, -52, -54, -43, 53, 85, 31, -36, -44, 7, 13, 19, -23, -33,
- 36, 47, -38, -11, 37, -19, -6, 18, 17, 2, 31, 54, -29, -72, -80, -1,
- 27, 52, 10, -29, -40, -48, -72, 24, 108, 66, -44, -76, -32, -24, 21, 69,
- 54, 24, -2, -8, -28, -44, -50, 34, 95, 45, -40, -72, -32, 6, 28, -1,
- 18, -7, 27, 1, -14, 21, -8, -51, -62, -24, 64, 56, 12, 19, -36, -22,
- 10, 20, -10, -1, -5, -51, 36, 72, -42, -51, 70, 45, -48, -27, 54, 19,
- -46, 8, 0, -46, 10, 37, 35, -21, -32, -22, -44, -82, -33, 59, 105, 48,
- -32, -36, -31, 18, 60, -12, -49, 10, 89, 28, 12, 8, -45, -21, -6, -16,
- -32, -17, -18, 3, 29, -3, 0, -20, -51, -31, 24, 52, 1, -17, -20, 1,
- 35, 15, 5, 35, 27, 18, -19, 8, -71, -74, -8, 88, 57, -45, -37, 17,
- 51, -1, -13, -4, 3, -13, -24, -7, 30, -7, -25, -1, 16, -8, -43, -70,
- 11, 85, 77, 12, -62, -57, 35, 53, -33, -96, 8, 82, 21, -38, 25, 39,
- -1, -27, -14, 18, -16, -45, -24, 42, 7, -9, 22, 32, -39, -5, -8, -49,
- -17, 60, 88, 21, -93, -20, 82, 31, -26, -63, -17, 52, -28, -25, 13, -2,
- -32, -46, 55, 56, -37, 6, -57, -33, 65, 63, 5, -25, -31, 69, 86, -32,
- -34, -56, -23, -47, 14, 44, -23, 19, 6, 60, -27, -69, -37, 20, -14, -5,
- 50, 44, 15, 13, -23, -60, -46, 23, 40, -5, -25, 6, 46, -4, -10, -27,
- -12, 28, 45, 10, -13, -33, -19, -39, 42, 32, -23, -25, 24, -17, 13, 25,
- 13, -32, 13, 48, 4, -93, -5, 40, -7, 37, -39, -37, 41, 1, -13, -33,
- 43, -53, 106, 8, -57, -93, 55, 40, 56, -24, -4, -19, 7, -23, -65, -18,
- 34, -30, 7, 66, 92, 3, -43, -37, -23, 12, -7, -17, 14, -15, -9, -18,
- 18, 51, -1, -57, -17, 23, 19, 15, -40, -1, 0, -8, 39, -13, -43, 72,
- 57, -1, -54, -17, 32, -19, 11, 0, 36, 25, -23, -86, 21, -3, 14, -17,
- 76, 37, 23, 2, -23, -54, -42, -80, 61, 60, 63, -12, -57, -44, 15, 35,
- 26, 11, -44, -22, 8, 33, -24, -17, 21, 38, -25, -39, 16, 43, -36, -28,
- 54, 10, -52, -18, -34, -14, 76, 60, 24, -32, -19, 16, -13, -68, -5, 30,
- -13, -23, -14, 61, 24, 35, 39, 4, -50, -58, -39, 0, 43, 43, 21, 24,
- -20, -46, -36, 38, 8, -67, -8, 61, 38, 10, -12, 5, -4, -16, -47, -5,
- -18, -20, 37, 41, 24, 4, 7, -19, 11, -52, 0, 17, 20, -30, -33, -16,
- 60, 34, -15, -46, -77, 14, 29, 26, 21, 25, 8, 7, 36, 23, -39, -16,
- 21, 11, -23, 11, -4, -6, -35, 13, -8, -49, -17, 44, 19, -25, -17, 9,
- -5, -5, -1, -31, 11, 15, 17, -8, -31, -51, 12, 54, 85, 32, 4, -58,
- -35, -31, 0, 10, 21, -20, -20, -29, 15, 26, -7, 8, 4, 0, 30, 2,
- -26, 2, 19, 15, -18, -13, -20, -19, 47, 33, -6, -51, -30, -12, 12, 30,
- 34, 31, 4, -45, -81, -7, -22, 1, 73, 98, 24, -67, -13, 19, -32, -86,
- 6, 94, 4, -47, 21, -11, -50, 22, -3, -2, 50, 20, -37, -59, 35, 28,
- -16, -36, -30, -11, 4, 69, 98, -65, -84, 73, 27, -90, -17, 84, 10, -51,
- -14, 40, -24, -11, 16, -34, -26, 38, -43, -34, 58, 85, -33, -51, 17, 7,
- 4, 52, 25, -35, 0, 44, -21, -47, 40, 44, -69, -65, 37, 35, -21, 4,
- 32, -60, -75, 21, 64, 60, -6, -11, 6, 2, -41, -34, 19, 31, 9, 7,
- -1, 11, 6, -11, -26, -23, 16, 35, -39, -68, 6, 56, -3, -42, 29, 28,
- 3, 28, 14, -37, -16, 11, -8, -18, 15, -1, -8, 43, -20, -67, -12, 34,
- 7, -12, -9, 5, -4, 7, -12, 27, -3, -68, 26, 96, 30, -33, -28, -25,
- 19, 27, -33, -48, -3, 37, -1, -35, -11, 5, 42, 36, 6, -48, -38, 26,
- 54, -23, -41, 52, 44, -32, -22, 28, -23, -32, 12, 41, -16, -6, -6, -17,
- -18, -14, -12, -5, 18, 52, 45, -10, -16, 29, 11, -36, -26, 7, 36, 12,
- -57, -48, 48, 70, 16, 21, -13, -46, -33, -62, -63, -21, 94, 94, 20, -110,
- -47, 41, 67, -16, -57, -40, 85, 71, 7, -39, 15, -29, -50, -41, 18, -40,
- -42, 38, 69, 21, -8, -58, -19, 23, 24, -20, -10, 11, 41, 7, -6, -30,
- -23, 2, 16, 57, 38, -11, -50, 36, -16, -51, -51, 81, 24, -68, -84, 39,
- 112, 62, -79, -104, 24, 102, 15, -38, 20, 22, -49, -91, 15, 51, 30, -1,
- -15, -30, -12, 17, 42, -17, -48, 0, 49, 35, 2, -19, -16, -30, 9, 17,
- -12, -4, -15, 5, 34, -1, -56, -64, 7, 48, 54, -16, -51, 20, 62, -17,
- -27, -9, -10, -29, -1, 35, 44, -20, -23, -2, -12, -4, 31, 24, -24, -14,
- 2, -28, -27, 49, 61, -54, -61, 6, 23, -20, 2, 41, 26, 2, 15, -5,
- 6, -16, -36, -16, 2, -54, -53, -18, 62, 64, 10, -3, 91, 39, -54, -103,
- -5, 16, -31, -28, 75, 105, -32, -114, -52, 68, 32, -52, -19, 25, 54, 61,
- 14, -40, 12, 1, -56, -31, 74, 40, -73, -66, 0, 49, 36, 24, -20, 0,
- 13, -40, -99, -11, 55, 31, -33, 39, 24, 3, -18, 7, 10, 4, -29, 17,
- 19, 27, -30, -41, 9, 33, -24, -25, 30, 28, -34, -57, 8, -7, -46, 5,
- 48, -22, -6, 57, 58, -31, -72, -2, 72, 44, -53, -42, 41, 1, -54, 30,
- 54, -6, -79, -14, 33, -6, -22, 14, 10, -5, -8, 13, 23, 21, -47, -74,
- 22, 24, -10, -7, 39, 2, 12, -7, -2, 4, 33, -20, -33, 18, 22, -88,
- -71, 26, 81, 14, -37, 3, -24, 6, -8, 11, 40, 18, -7, -17, 20, -8,
- -15, -41, -11, 27, 52, -27, -46, 33, 21, 46, -30, -13, 26, -91, -106, -47,
- 54, 109, 67, -87, -90, 38, 92, 31, -10, -69, -73, -27, -6, 24, -6, 20,
- 30, 45, 33, -13, -25, 10, 57, -16, -32, 0, -14, -55, -20, 4, 7, -4,
- 3, 18, -11, 34, 11, -45, -45, -125, -38, -2, 19, 72, 82, 99, 98, 35,
- -51, -81, -53, 3, -39, 23, -4, -58, -63, -24, 40, 84, 48, -7, -18, -2,
- -8, -20, -10, 3, 21, 17, -39, -66, -20, -2, 37, 30, 39, 34, -5, -41,
- -26, 33, 40, 18, -2, 11, 13, -20, -60, -21, 33, -25, -35, 30, 65, 22,
- 13, -15, 2, 16, 11, -68, -18, 74, 10, -74, -34, -39, -17, 8, 59, 39,
- -22, -38, -8, 9, 30, 23, 11, -3, -12, 10, -1, 59, 9, -28, -72, -27,
- 32, 68, -11, -3, 27, 4, -33, -39, 7, -1, -5, -7, 26, -14, -26, -40,
- -12, 5, 5, 1, -12, 64, 63, -41, -56, 10, 26, 40, -26, -44, -42, 25,
- -6, 3, -1, 10, 9, -1, 9, 1, -28, 10, 24, 26, -33, -36, 46, 20,
- -43, -52, -35, 22, 53, 30, -6, 18, -16, -49, -36, 45, 10, 21, 7, 9,
- -33, -50, 21, 73, 33, -42, -46, 42, -12, -18, 5, -50, -25, 68, 55, -31,
- -79, -7, 77, 25, -6, 29, 78, 24, -87, -41, -30, -41, -23, 75, 35, -32,
- -65, -7, -13, 3, 41, 34, -24, -33, 25, 14, -52, -28, 19, 76, 45, -45,
- -47, -5, 24, 9, -14, -41, -5, 49, 22, 10, -31, -35, -1, -6, 3, 10,
- -1, -12, -20, -51, 9, 79, 53, -36, -38, -13, -14, -15, 50, 50, -36, -33,
- 0, 5, 22, 23, 24, -51, -81, -27, 56, 42, -10, -16, 0, 0, -5, 16,
- 12, -19, 11, 10, -15, -1, -32, -17, 1, 11, 62, -16, -21, 9, 21, -29,
- -50, 16, 82, 17, -35, -4, 11, 3, 8, 8, -9, -13, 10, -39, -63, -19,
- 54, 58, -16, -25, 18, 38, -8, -50, -54, -17, 18, 47, 17, -33, -45, 0,
- 52, 57, -5, -34, -17, 32, 10, -28, -10, -21, -3, -9, -20, 20, 47, 22,
- 5, -4, -15, -37, -22, -28, 9, 37, -18, -13, 3, 15, -33, -47, 20, 73,
- 0, -36, 33, 60, -11, -77, -13, 42, 13, -20, 9, 47, 22, -27, 29, 6,
- -71, -78, -20, 21, 4, 27, 23, 19, 31, 45, -29, -54, -10, 37, -78, -46,
- -14, 67, 108, 57, 12, -62, -108, -15, 116, 56, -58, -110, -33, 33, 30, -39,
- -26, 11, 29, 22, 8, 52, 76, 31, 0, -31, -50, -10, 59, 54, -13, -84,
- -65, -60, 0, 35, 105, 61, -30, -117, -62, 35, 88, 57, 48, -38, -85, 41,
- 12, -21, -6, 7, 15, 73, -30, -72, -37, 25, 0, -5, 65, 76, -90, -78,
- 24, 47, 2, -14, 40, 83, 0, -32, -46, -62, -26, 50, 37, -4, -44, -40,
- 55, 31, -38, -13, -17, -30, -4, 7, 68, 39, 1, -23, -38, -30, 6, -35,
- 14, 52, -9, -62, -47, 45, 44, 11, -17, -9, 6, 16, 34, -3, -32, -21,
- -33, -3, 21, 26, -39, 11, 65, 33, 19, -1, -49, -85, -97, 66, 58, -93,
- -15, 15, 5, 81, 76, 29, -2, -52, -51, -30, 65, 38, -45, -14, 1, 28,
- 22, 43, 19, -59, -109, -29, 29, -14, -22, -41, 0, 54, 76, 16, 8, 23,
- 15, -47, -39, -8, 5, 36, -6, -3, -4, 13, 13, 21, -47, -53, -6, -9,
- -27, -44, 8, 86, 64, 12, -5, -32, -10, -20, -27, -23, 8, 30, 1, 16,
- 42, -35, -8, 4, -39, -11, -62, -29, 108, 87, -20, -104, -18, -55, 8, 47,
- -16, 29, 38, 4, -44, -39, -20, 38, -13, 23, 82, 30, -67, -93, 26, 79,
- 20, -79, -74, -23, 33, 59, 80, 39, -42, -100, 0, 19, 38, 9, -55, 9,
- -15, 22, 68, -17, -55, -23, 1, 87, 19, -56, -60, 32, 37, 38, -67, -33,
- -1, 31, 24, 15, -30, -5, -36, -29, -27, 8, 27, -9, 12, 29, 38, 33,
- 0, -39, -18, 6, 19, 18, 8, 1, -33, 9, -1, 2, -29, -66, 0, 41,
- 6, -50, -13, 9, 73, -28, -47, -21, 30, 68, 31, 32, 29, -46, -14, 13,
- -44, -75, -3, 62, 55, 9, -49, -1, 54, 19, -6, 7, 16, 38, 13, -26,
- -55, -76, -23, 16, 21, -33, -22, 16, 61, 25, -14, -35, 12, 23, -7, -17,
- -32, -10, -16, -1, 7, 18, -1, 19, -2, -1, 21, -14, 1, -44, -44, -23,
- -29, -1, 28, -28, 47, 64, 12, -4, -15, -37, -7, 24, 50, 6, -15, -26,
- -5, 20, 12, -25, -21, -2, -18, -23, 9, 16, 24, 36, -30, -35, -12, 32,
- 19, -13, 19, -6, 2, -2, -22, -11, 14, 50, 10, -21, -55, -14, 23, 6,
- 6, -6, -26, -25, -8, 25, 14, 24, 14, -13, 18, 11, 23, -34, -49, -45,
- 6, 39, 37, 3, 0, -29, 8, 26, -6, -7, -21, 2, -11, 6, 16, -1,
- -17, 6, 32, -4, -54, -9, 22, -14, 6, 27, -1, -2, 34, 33, 8, 1,
- -8, -14, -32, 23, -22, -23, -29, -12, 5, 25, 22, -4, 14, 5, 24, -39,
- -29, 17, -21, -80, -60, -9, 78, 99, 81, -41, -53, 22, 11, -69, -22, -2,
- 70, 80, 18, -56, -54, -79, -27, 56, 46, 28, -1, 12, -37, -76, 23, 64,
- -4, -5, 4, 0, -2, -5, 10, -4, -9, 5, 3, 3, -2, 6, -2, -1,
- 0, 2, 0, 1, -2, 2, -3, -2, 0, 1, -1, 0, 0, -1, -1, -1,
- 0, -1, -1, -1, -1, 0, 0, -1, 0, -1, -1, -1, -1, -1, -1, 0,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -2, -3, -5, -6, -5, -5,
- -3, 0, -1, -3, -1, 7, 16, 20, 8, -8, -24, -35, -39, -36, -35, -42,
- -47, -35, -14, 0, 8, 17, 28, 45, 60, 65, 64, 66, 67, 60, 50, 39,
- 26, 14, 5, -14, -40, -54, -56, -56, -55, -47, -36, -20, 1, 13, 15, 16,
- 12, 2, -10, -20, -33, -43, -42, -38, -43, -40, -28, -17, -7, 6, 21, 34,
- 48, 60, 63, 64, 66, 61, 54, 51, 41, 23, 10, 1, -18, -37, -46, -54,
- -63, -60, -46, -30, -13, 5, 15, 16, 17, 11, -2, -11, -21, -34, -44, -45,
- -43, -42, -33, -21, -17, -10, 5, 23, 39, 54, 62, 61, 62, 63, 59, 53,
- 47, 38, 23, 10, -5, -23, -36, -42, -51, -61, -61, -48, -26, -2, 14, 16,
- 13, 13, 9, -1, -14, -27, -36, -42, -44, -48, -44, -31, -17, -10, -8, 1,
- 21, 47, 65, 67, 58, 54, 58, 61, 54, 41, 31, 23, 11, -9, -30, -41,
- -44, -45, -54, -61, -52, -21, 11, 25, 19, 8, 4, 7, 2, -15, -33, -39,
- -39, -44, -51, -48, -34, -12, -2, -4, -2, 19, 54, 74, 72, 58, 47, 51,
- 59, 54, 40, 26, 20, 7, -16, -37, -46, -44, -42, -51, -58, -47, -15, 19,
- 31, 25, 9, -1, -1, -4, -15, -30, -37, -41, -51, -55, -48, -28, -11, -4,
- -2, 6, 28, 58, 73, 74, 63, 50, 45, 46, 49, 42, 31, 19, -6, -30,
- -43, -44, -42, -51, -54, -49, -33, -3, 18, 30, 31, 17, 2, -13, -15, -15,
- -25, -31, -45, -62, -60, -45, -24, -16, -10, 6, 20, 40, 58, 68, 74, 69,
- 55, 41, 37, 44, 43, 34, 15, -17, -41, -48, -46, -51, -59, -51, -34, -16,
- 3, 17, 29, 33, 23, 2, -15, -18, -18, -22, -31, -50, -64, -61, -42, -30,
- -24, -8, 13, 35, 50, 57, 65, 70, 70, 58, 42, 40, 41, 40, 32, 6,
- -23, -45, -53, -55, -64, -60, -45, -24, -1, 10, 19, 27, 28, 23, 4, -9,
- -17, -22, -23, -36, -53, -61, -60, -47, -36, -22, -3, 19, 44, 56, 60, 65,
- 65, 65, 60, 52, 45, 39, 37, 23, -2, -26, -49, -63, -66, -63, -55, -42,
- -16, 3, 14, 25, 25, 22, 19, 11, -2, -17, -20, -29, -44, -50, -58, -64,
- -53, -32, -13, 0, 25, 45, 53, 65, 68, 61, 60, 63, 60, 47, 42, 33,
- 7, -10, -26, -56, -73, -68, -57, -53, -37, -12, -1, 14, 32, 26, 16, 17,
- 16, 1, -12, -19, -38, -52, -47, -55, -65, -50, -23, -9, 4, 27, 40, 48,
- 68, 72, 59, 58, 67, 64, 52, 42, 21, -5, -16, -31, -60, -73, -62, -54,
- -49, -34, -17, -4, 17, 32, 24, 13, 18, 20, 6, -11, -29, -46, -48, -46,
- -54, -59, -41, -17, -5, 6, 20, 35, 54, 71, 68, 55, 60, 74, 71, 53,
- 27, 5, -6, -16, -35, -62, -70, -57, -49, -45, -40, -25, 4, 25, 29, 15,
- 7, 23, 27, 10, -20, -46, -47, -41, -39, -47, -55, -34, -11, -1, 4, 11,
- 38, 67, 72, 62, 48, 61, 83, 76, 49, 9, -9, -7, -15, -31, -59, -70,
- -55, -48, -46, -43, -21, 16, 29, 22, 6, 1, 25, 32, 10, -28, -57, -47,
- -34, -30, -38, -49, -33, -12, -4, 3, 17, 50, 72, 68, 55, 44, 61, 86,
- 77, 41, -2, -16, -10, -13, -28, -56, -69, -58, -52, -47, -35, -7, 22, 25,
- 13, -4, -2, 25, 33, 7, -35, -58, -46, -29, -22, -32, -44, -34, -16, -5,
- 8, 30, 59, 72, 65, 46, 39, 62, 87, 76, 33, -8, -20, -13, -10, -28,
- -57, -70, -62, -51, -42, -24, 3, 23, 23, 4, -15, -4, 25, 34, 3, -38,
- -55, -45, -23, -17, -32, -43, -34, -15, -1, 14, 41, 64, 73, 59, 35, 35,
- 64, 89, 73, 26, -11, -23, -14, -11, -33, -60, -69, -59, -48, -39, -14, 11,
- 25, 17, -11, -24, -3, 30, 35, -3, -40, -54, -41, -18, -19, -36, -41, -28,
- -10, 0, 21, 51, 70, 71, 47, 24, 36, 72, 93, 65, 17, -14, -22, -13,
- -17, -43, -62, -63, -52, -48, -36, -5, 19, 26, 5, -26, -27, 5, 40, 31,
- -12, -42, -50, -34, -20, -28, -37, -33, -17, -8, -1, 29, 61, 75, 64, 31,
- 19, 44, 85, 93, 51, 9, -15, -18, -16, -30, -50, -57, -52, -48, -52, -32,
- 3, 25, 20, -10, -34, -21, 19, 42, 20, -17, -40, -43, -35, -30, -32, -32,
- -21, -12, -12, 3, 37, 67, 72, 50, 25, 24, 57, 92, 81, 42, 6, -12,
- -18, -25, -39, -53, -52, -44, -49, -51, -28, 6, 25, 13, -17, -32, -11, 29,
- 39, 8, -24, -38, -37, -33, -36, -39, -30, -10, -3, -9, 3, 38, 68, 71,
- 46, 23, 32, 68, 92, 71, 31, 5, -7, -16, -31, -50, -55, -45, -37, -49,
- -53, -27, 8, 23, 8, -20, -24, 3, 34, 28, -6, -28, -32, -30, -35, -46,
- -43, -23, 0, 0, -10, 5, 41, 67, 65, 42, 30, 47, 77, 83, 52, 23,
- 10, 2, -16, -43, -60, -55, -38, -36, -53, -53, -25, 8, 19, 3, -14, -8,
- 17, 29, 9, -17, -24, -22, -26, -43, -53, -42, -14, 4, -3, -9, 10, 44,
- 63, 58, 43, 43, 63, 77, 64, 38, 24, 20, 7, -23, -52, -62, -49, -38,
- -45, -57, -49, -19, 6, 11, 2, -1, 12, 22, 13, -7, -18, -15, -17, -32,
- -50, -52, -32, -11, -4, -8, -3, 21, 44, 55, 53, 52, 63, 70, 64, 49,
- 35, 34, 24, 0, -29, -53, -54, -50, -51, -56, -57, -37, -17, -2, 7, 9,
- 20, 21, 12, 1, -13, -11, -13, -24, -36, -49, -40, -30, -22, -12, -9, 10,
- 25, 38, 51, 57, 70, 71, 62, 57, 44, 42, 34, 15, -4, -30, -42, -53,
- -65, -61, -61, -49, -35, -22, -2, 10, 25, 27, 15, 11, -1, -8, -14, -22,
- -27, -37, -37, -37, -40, -26, -14, -2, 10, 24, 42, 54, 68, 73, 65, 65,
- 60, 49, 36, 27, 15, -7, -25, -43, -63, -69, -65, -61, -54, -36, -13, 3,
- 18, 26, 23, 20, 16, 1, -16, -21, -20, -31, -37, -38, -40, -38, -25, -15,
- -7, 11, 34, 48, 56, 66, 71, 72, 73, 61, 43, 34, 29, 11, -14, -31,
- -46, -63, -69, -72, -69, -53, -28, -7, 3, 16, 27, 30, 28, 15, -3, -14,
- -19, -25, -39, -42, -37, -38, -35, -30, -19, -2, 18, 39, 47, 56, 69, 75,
- 78, 71, 60, 49, 35, 22, -1, -20, -32, -50, -65, -76, -75, -63, -49, -27,
- -9, 6, 22, 28, 31, 27, 16, 6, -13, -26, -36, -43, -41, -42, -42, -36,
- -27, -10, 2, 18, 38, 52, 64, 70, 73, 79, 76, 70, 50, 27, 11, -5,
- -21, -41, -62, -69, -72, -68, -61, -50, -26, -4, 13, 21, 23, 32, 35, 27,
- 6, -21, -33, -37, -42, -48, -53, -45, -31, -19, -8, 3, 23, 45, 59, 65,
- 65, 73, 88, 88, 69, 40, 19, 10, -6, -30, -54, -69, -69, -68, -67, -59,
- -43, -18, 2, 10, 15, 22, 39, 46, 27, -3, -28, -34, -37, -48, -56, -60,
- -48, -29, -16, -1, 14, 35, 52, 58, 60, 64, 80, 96, 88, 64, 34, 16,
- 6, -11, -36, -62, -77, -75, -68, -58, -47, -33, -14, -1, 7, 15, 28, 43,
- 44, 24, -6, -30, -38, -40, -49, -63, -68, -56, -30, -5, 15, 27, 40, 51,
- 59, 63, 72, 84, 91, 83, 60, 32, 12, 1, -14, -45, -73, -84, -78, -62,
- -46, -36, -28, -17, 0, 11, 20, 31, 38, 35, 20, -6, -28, -40, -46, -58,
- -72, -71, -52, -26, 4, 26, 37, 45, 54, 64, 69, 74, 81, 80, 73, 59,
- 35, 13, -5, -28, -54, -75, -79, -74, -63, -43, -30, -21, -11, 0, 14, 23,
- 29, 33, 23, 14, -2, -25, -41, -58, -69, -71, -64, -43, -24, 3, 33, 47,
- 56, 60, 64, 73, 74, 75, 73, 62, 56, 38, 13, -12, -42, -57, -69, -77,
- -71, -63, -44, -25, -15, -3, 2, 13, 26, 23, 24, 19, 8, -2, -24, -44,
- -64, -74, -64, -60, -45, -16, 9, 34, 53, 63, 68, 66, 75, 73, 63, 66,
- 62, 49, 34, 11, -17, -43, -54, -66, -82, -72, -52, -43, -28, -10, 0, 4,
- 18, 27, 16, 13, 20, 8, -11, -26, -47, -66, -63, -59, -63, -47, -7, 20,
- 34, 56, 69, 65, 73, 81, 67, 54, 61, 63, 44, 25, 6, -23, -37, -44,
- -69, -85, -69, -48, -39, -26, -7, -4, 5, 27, 25, 9, 10, 15, 5, -17,
- -34, -52, -62, -54, -54, -60, -40, -5, 21, 41, 59, 67, 66, 78, 81, 64,
- 53, 58, 56, 39, 18, -3, -24, -34, -45, -64, -76, -67, -51, -37, -21, -8,
- -3, 11, 22, 20, 11, 9, 11, -4, -23, -38, -56, -57, -53, -50, -42, -31,
- -5, 21, 41, 63, 67, 72, 77, 69, 67, 58, 56, 49, 28, 16, -8, -28,
- -35, -50, -53, -62, -65, -53, -44, -20, -2, 2, 14, 10, 14, 17, 7, 5,
- -13, -27, -37, -60, -58, -55, -42, -22, -18, -2, 13, 36, 69, 73, 76, 71,
- 62, 70, 60, 53, 42, 23, 16, -13, -35, -45, -51, -40, -46, -58, -60, -52,
- -17, 4, 8, 11, 5, 14, 15, 4, -4, -20, -23, -37, -62, -67, -59, -27,
- -2, -3, -3, 3, 36, 70, 77, 75, 66, 67, 70, 57, 46, 32, 29, 19,
- -17, -49, -62, -46, -25, -33, -54, -68, -51, -15, 4, 8, 6, 11, 18, 8,
- -7, -19, -16, -12, -35, -68, -83, -56, -9, 13, 7, -7, 4, 40, 66, 73,
- 69, 73, 80, 69, 46, 27, 31, 42, 24, -23, -68, -69, -36, -14, -25, -57,
- -66, -43, -16, -3, -2, 11, 28, 23, -2, -31, -29, -4, -1, -34, -83, -89,
- -45, 3, 22, 6, -3, 16, 41, 56, 55, 68, 93, 93, 65, 23, 12, 38,
- 53, 27, -38, -80, -64, -29, -12, -31, -54, -49, -34, -22, -24, -11, 28, 47,
- 25, -24, -51, -27, 5, 5, -43, -90, -79, -34, 6, 11, 4, 17, 31, 39,
- 34, 38, 79, 114, 105, 50, 3, 12, 44, 56, 16, -49, -72, -54, -28, -29,
- -44, -37, -27, -28, -41, -45, -5, 46, 61, 17, -44, -53, -20, 7, -6, -53,
- -78, -62, -27, -7, -6, 14, 41, 45, 26, 11, 38, 93, 127, 101, 34, 1,
- 20, 48, 42, -1, -41, -53, -45, -40, -51, -44, -18, -9, -34, -61, -47, 7,
- 57, 58, 2, -46, -43, -14, -5, -27, -52, -58, -46, -31, -26, -12, 28, 59,
- 45, 10, 6, 50, 104, 124, 87, 30, 11, 30, 40, 19, -9, -26, -35, -44,
- -58, -62, -38, -4, -6, -46, -67, -37, 21, 56, 43, -4, -37, -30, -15, -25,
- -40, -44, -38, -38, -43, -38, -9, 40, 64, 37, 5, 14, 65, 106, 107, 75,
- 36, 26, 34, 24, 4, -8, -10, -24, -53, -70, -64, -30, 0, -16, -53, -61,
- -22, 28, 43, 29, -2, -21, -20, -26, -39, -43, -34, -26, -43, -54, -40, 0,
- 46, 56, 30, 12, 30, 75, 97, 90, 69, 47, 38, 29, 13, 2, 0, -1,
- -27, -61, -71, -55, -25, -14, -32, -50, -41, -6, 22, 25, 17, 4, -8, -19,
- -31, -38, -35, -28, -35, -53, -54, -29, 7, 31, 32, 23, 28, 51, 72, 78,
- 72, 65, 55, 42, 30, 19, 15, 11, -8, -36, -58, -58, -42, -35, -35, -43,
- -40, -18, 0, 12, 14, 11, 9, -4, -15, -25, -31, -28, -36, -49, -53, -45,
- -18, 1, 12, 19, 23, 43, 58, 64, 68, 64, 64, 57, 46, 40, 28, 22,
- 9, -17, -35, -48, -47, -44, -47, -45, -44, -31, -12, -2, 7, 10, 9, 7,
- -2, -8, -19, -28, -32, -44, -51, -48, -37, -21, -9, 5, 16, 26, 43, 55,
- 60, 64, 63, 61, 58, 55, 48, 34, 21, 6, -13, -27, -39, -49, -53, -50,
- -46, -41, -32, -16, -3, 5, 11, 9, 6, 5, -4, -17, -32, -40, -42, -44,
- -42, -40, -32, -12, 5, 17, 24, 35, 50, 58, 64, 64, 60, 65, 61, 50,
- 34, 18, 10, -2, -18, -38, -58, -56, -49, -45, -41, -38, -22, -4, 8, 14,
- 8, 11, 10, -5, -20, -38, -41, -36, -37, -40, -48, -37, -12, 4, 14, 19,
- 27, 46, 59, 66, 63, 62, 70, 64, 50, 34, 22, 17, 8, -11, -38, -59,
- -57, -50, -49, -47, -43, -28, -6, 10, 16, 10, 14, 8, 1, -5, -5, -4,
- -5, 5, 2, 2, 1, -1, 0, 1, 0, 2, 0, 0, -2, -1, -1, 2,
- 1, 1, 0, 0, -1, 0, -1, 0, 0, 0, 0, 0, 0, -1, -1, -1,
- 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, -1,
- -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1,
- -1, 0, 1, 0, 0, 0, 1, 0, 1, 0, -3, -10, -11, -8, -13, -25,
- -21, -10, 0, 2, 18, 41, 44, 42, 66, 62, 28, 10, 17, 17, -16, -10,
- 25, 28, 29, 34, 47, 34, -7, 7, 25, -12, -43, -44, -40, -61, -85, -78,
- -55, -42, -33, -10, 17, 31, 43, 59, 51, 25, 25, 40, 27, -1, 2, 25,
- 30, 15, 12, 27, 26, 13, 16, 9, -24, -43, -37, -49, -83, -92, -62, -40,
- -42, -36, 1, 33, 34, 45, 61, 46, 27, 32, 33, 10, -6, 15, 38, 26,
- 4, 15, 35, 19, 7, 17, 3, -26, -41, -50, -67, -91, -82, -48, -40, -46,
- -24, 18, 33, 32, 54, 62, 46, 30, 22, 20, 7, 4, 28, 33, 15, 10,
- 22, 25, 9, 13, 18, -2, -29, -54, -65, -74, -86, -68, -49, -46, -32, -8,
- 17, 29, 45, 65, 60, 43, 23, 13, 17, 12, 18, 28, 22, 19, 16, 13,
- 14, 16, 24, 13, -13, -40, -66, -72, -75, -74, -64, -55, -36, -20, -9, 15,
- 43, 63, 65, 51, 37, 17, 9, 19, 23, 21, 19, 24, 21, 3, 4, 24,
- 31, 18, -2, -20, -49, -77, -74, -65, -71, -69, -47, -27, -27, -10, 38, 66,
- 59, 52, 51, 34, 4, 11, 36, 26, 12, 22, 26, 2, -11, 25, 45, 18,
- 0, -1, -23, -72, -83, -55, -65, -83, -61, -34, -37, -36, 23, 71, 55, 43,
- 60, 55, 11, 1, 40, 37, 8, 16, 31, 6, -22, 14, 55, 27, -3, 8,
- 2, -52, -83, -57, -56, -89, -79, -43, -43, -55, -4, 66, 61, 35, 56, 68,
- 31, 4, 32, 46, 13, 7, 31, 16, -24, -4, 50, 42, 2, 7, 16, -25,
- -67, -60, -54, -86, -95, -55, -44, -63, -32, 40, 62, 40, 47, 67, 48, 22,
- 32, 42, 18, 4, 25, 25, -15, -16, 29, 44, 21, 11, 15, -5, -39, -49,
- -59, -85, -96, -72, -52, -62, -50, 7, 45, 49, 50, 56, 56, 43, 42, 39,
- 19, 9, 16, 21, 1, -16, 9, 32, 31, 24, 14, 5, -14, -34, -52, -81,
- -94, -85, -71, -62, -55, -21, 21, 41, 53, 55, 55, 57, 51, 44, 26, 13,
- 15, 11, 3, -3, 0, 19, 27, 29, 26, 11, 0, -16, -41, -70, -90, -88,
- -85, -80, -57, -34, -3, 26, 42, 57, 57, 60, 64, 50, 33, 20, 17, 9,
- -6, -1, 6, 10, 23, 26, 28, 22, 10, 1, -27, -60, -78, -87, -90, -94,
- -74, -42, -20, 10, 34, 44, 57, 65, 71, 58, 35, 30, 23, 8, -5, -7,
- 4, 7, 19, 33, 23, 19, 24, 17, -13, -53, -65, -75, -96, -98, -83, -61,
- -40, -7, 32, 38, 38, 66, 83, 65, 36, 36, 37, 8, -7, 1, 0, -5,
- 11, 39, 34, 10, 21, 36, 4, -45, -59, -59, -89, -106, -84, -67, -62, -32,
- 21, 41, 30, 47, 85, 80, 41, 34, 45, 20, -8, 0, 9, -7, -6, 31,
- 45, 21, 12, 32, 25, -27, -55, -52, -76, -104, -95, -70, -64, -57, -7, 33,
- 34, 38, 67, 84, 57, 35, 46, 29, -1, -4, 7, 7, -8, 12, 41, 31,
- 21, 24, 25, -5, -43, -45, -65, -98, -98, -82, -62, -58, -35, 13, 27, 38,
- 59, 70, 67, 45, 49, 39, 2, -3, 2, 9, 9, 6, 30, 30, 24, 31,
- 20, 3, -26, -37, -48, -91, -100, -88, -75, -53, -41, -9, 12, 23, 55, 65,
- 61, 54, 51, 51, 14, -6, 1, 1, 15, 18, 26, 29, 16, 30, 28, 4,
- -14, -29, -36, -71, -100, -93, -87, -64, -38, -16, 2, 6, 33, 61, 59, 56,
- 54, 55, 32, 1, -3, -4, 5, 25, 36, 36, 17, 14, 25, 14, -4, -19,
- -30, -53, -84, -94, -95, -82, -49, -16, 4, 2, 10, 37, 56, 61, 58, 54,
- 42, 19, 3, -9, -8, 14, 41, 53, 32, 10, 7, 10, 10, -7, -25, -43,
- -65, -81, -97, -99, -72, -29, 9, 11, 3, 10, 33, 61, 65, 55, 46, 30,
- 19, 0, -17, -5, 29, 62, 57, 24, -1, -6, 10, 8, -16, -35, -54, -64,
- -80, -105, -99, -57, -2, 26, 13, -2, 6, 42, 67, 60, 49, 36, 31, 22,
- -10, -24, 1, 49, 77, 53, 9, -14, -4, 10, -4, -26, -47, -56, -58, -89,
- -115, -93, -34, 23, 33, 6, -6, 16, 50, 62, 53, 39, 34, 40, 16, -24,
- -26, 15, 71, 82, 38, -5, -13, -1, 3, -13, -39, -53, -48, -61, -103, -119,
- -80, -6, 42, 27, -1, 2, 26, 51, 56, 43, 33, 43, 42, 4, -34, -23,
- 37, 87, 70, 20, -6, -10, -3, -5, -27, -49, -48, -44, -72, -115, -118, -56,
- 22, 43, 17, 3, 12, 33, 51, 45, 34, 38, 51, 38, -11, -42, -9, 59,
- 86, 53, 13, -5, -5, -3, -19, -42, -50, -43, -45, -85, -127, -105, -28, 34,
- 37, 15, 8, 23, 41, 42, 34, 33, 45, 55, 26, -27, -38, 12, 69, 77,
- 40, 9, 1, 0, -13, -33, -48, -49, -39, -55, -102, -124, -83, -8, 37, 31,
- 14, 19, 35, 39, 34, 30, 35, 51, 50, 9, -31, -25, 27, 72, 65, 30,
- 12, 9, -2, -23, -42, -52, -46, -43, -71, -109, -112, -63, 7, 36, 25, 20,
- 33, 42, 35, 29, 29, 40, 52, 35, -2, -28, -12, 40, 69, 51, 26, 18,
- 13, -8, -33, -48, -50, -46, -57, -84, -107, -98, -43, 14, 29, 24, 30, 44,
- 43, 30, 26, 34, 44, 40, 19, -8, -20, 4, 46, 59, 42, 29, 25, 10,
- -18, -40, -46, -47, -57, -73, -91, -100, -78, -30, 13, 25, 30, 44, 48, 39,
- 29, 31, 41, 35, 23, 9, -9, -5, 16, 43, 52, 40, 37, 25, 0, -23,
- -41, -43, -54, -74, -82, -93, -86, -60, -26, 12, 26, 41, 53, 44, 40, 33,
- 36, 38, 19, 12, 2, -3, 9, 18, 40, 48, 42, 41, 16, -6, -23, -41,
- -45, -68, -84, -86, -90, -71, -52, -22, 15, 32, 52, 54, 45, 45, 36, 36,
- 25, 6, 6, 0, 5, 15, 21, 41, 46, 46, 37, 10, -7, -24, -42, -57,
- -81, -88, -88, -83, -62, -43, -14, 16, 41, 59, 55, 48, 48, 40, 27, 10,
- 2, 2, 0, 8, 22, 30, 36, 45, 50, 32, 5, -9, -23, -48, -75, -86,
- -86, -88, -81, -54, -26, -11, 16, 52, 65, 55, 50, 53, 39, 9, -2, 4,
- 2, -4, 11, 36, 34, 27, 47, 51, 26, 0, -9, -23, -63, -91, -85, -81,
- -89, -79, -38, -13, -11, 23, 62, 67, 55, 52, 56, 29, -8, -7, 7, 0,
- -5, 19, 44, 30, 28, 49, 46, 21, -2, -10, -32, -79, -96, -83, -81, -87,
- -67, -27, -11, 0, 36, 65, 67, 58, 54, 48, 14, -15, -7, 3, 1, 6,
- 26, 35, 30, 38, 46, 37, 18, -2, -18, -48, -85, -96, -89, -81, -70, -52,
- -30, -8, 20, 48, 63, 66, 59, 50, 33, 6, -14, -15, -2, 13, 20, 21,
- 25, 36, 45, 42, 31, 12, -10, -31, -56, -84, -103, -96, -70, -50, -43, -31,
- 0, 35, 58, 68, 65, 51, 37, 26, 8, -19, -25, 2, 27, 27, 17, 20,
- 36, 45, 45, 29, 0, -27, -41, -55, -87, -111, -93, -57, -37, -33, -23, 5,
- 41, 70, 77, 59, 36, 26, 24, 4, -24, -22, 7, 31, 33, 19, 14, 29,
- 49, 50, 22, -16, -39, -48, -63, -92, -104, -86, -51, -25, -19, -16, 10, 53,
- 82, 74, 47, 26, 19, 16, -1, -18, -16, 7, 35, 37, 18, 10, 31, 55,
- 41, 4, -25, -45, -57, -73, -90, -95, -82, -42, -9, -8, -11, 20, 71, 84,
- 57, 39, 27, 13, 2, -6, -9, -12, 8, 45, 41, 8, 5, 42, 56, 20,
- -10, -24, -50, -73, -83, -83, -87, -76, -25, 10, -5, -9, 39, 84, 71, 44,
- 38, 26, 2, -9, -2, -4, -11, 17, 52, 36, 0, 11, 50, 43, 3, -19,
- -31, -57, -84, -84, -77, -82, -59, -9, 14, 1, 7, 55, 81, 61, 38, 29,
- 20, -2, -10, -1, -4, 0, 26, 42, 30, 8, 20, 41, 28, -4, -31, -46,
- -64, -84, -82, -79, -66, -37, -7, 15, 18, 30, 58, 68, 57, 33, 17, 9,
- 0, -3, -7, 0, 15, 23, 31, 29, 23, 24, 22, 14, -12, -43, -63, -72,
- -73, -83, -75, -47, -26, -2, 20, 37, 48, 50, 57, 52, 30, 6, -1, 11,
- 0, -9, 7, 16, 24, 28, 32, 33, 15, 7, 2, -21, -55, -79, -66, -67,
- -81, -63, -38, -12, 9, 29, 53, 48, 42, 51, 47, 22, -6, 5, 18, -4,
- -7, 6, 22, 28, 26, 39, 28, 2, -2, -8, -35, -73, -76, -56, -67, -77,
- -55, -20, 4, 16, 40, 54, 42, 41, 51, 37, 7, 0, 17, 13, -12, -9,
- 20, 31, 25, 29, 33, 15, -5, -8, -22, -57, -74, -62, -57, -74, -71, -33,
- 0, 11, 26, 44, 45, 41, 47, 45, 22, 3, 12, 19, 0, -15, 4, 30,
- 32, 27, 26, 17, 3, -4, -14, -44, -69, -66, -56, -63, -74, -52, -11, 12,
- 21, 29, 35, 41, 49, 51, 31, 9, 11, 19, 11, -8, -7, 20, 36, 34,
- 22, 10, 6, 5, -4, -33, -64, -66, -58, -58, -67, -63, -29, 4, 20, 21,
- 21, 35, 52, 57, 39, 12, 10, 18, 16, 3, -7, 8, 31, 39, 25, 5,
- 3, 10, 5, -22, -58, -67, -58, -56, -60, -64, -45, -11, 15, 19, 12, 24,
- 50, 62, 46, 17, 9, 18, 20, 12, 0, 2, 21, 37, 31, 7, 0, 11,
- 14, -12, -51, -66, -58, -53, -54, -59, -54, -29, 3, 16, 9, 17, 44, 62,
- 51, 22, 8, 17, 24, 21, 9, 1, 11, 30, 31, 14, 3, 11, 16, -4,
- -43, -65, -58, -49, -50, -53, -55, -43, -16, 5, 10, 16, 38, 59, 54, 26,
- 7, 18, 29, 24, 18, 8, 5, 16, 27, 23, 11, 14, 18, -1, -36, -63,
- -56, -43, -48, -47, -49, -52, -36, -12, 8, 17, 35, 55, 50, 28, 9, 17,
- 33, 25, 24, 20, 5, 4, 15, 27, 23, 20, 22, 0, -32, -58, -55, -40,
- -47, -44, -39, -52, -54, -34, -2, 19, 35, 53, 46, 27, 12, 18, 34, 26,
- 26, 33, 13, -6, 0, 22, 34, 32, 28, 3, -31, -53, -51, -39, -47, -45,
- -30, -45, -66, -56, -19, 15, 38, 52, 43, 22, 13, 22, 35, 26, 26, 41,
- 25, -7, -13, 10, 35, 46, 39, 10, -29, -50, -46, -37, -47, -46, -27, -35,
- -65, -72, -42, 2, 38, 55, 43, 19, 11, 24, 36, 27, 26, 43, 37, 2,
- -19, -6, 25, 53, 56, 20, -24, -46, -43, -36, -46, -48, -29, -28, -56, -77,
- -64, -22, 31, 61, 45, 16, 10, 23, 35, 30, 26, 41, 42, 16, -14, -21,
- 7, 51, 70, 36, -15, -38, -40, -35, -42, -49, -35, -29, -44, -71, -81, -49,
- 14, 60, 50, 18, 10, 21, 34, 34, 26, 37, 43, 30, 0, -27, -13, 37,
- 74, 54, 2, -29, -35, -32, -37, -49, -42, -32, -36, -57, -85, -73, -12, 46,
- 57, 27, 9, 17, 32, 38, 28, 30, 41, 39, 18, -20, -27, 15, 62, 68,
- 26, -17, -30, -28, -29, -45, -51, -40, -34, -45, -77, -86, -42, 18, 54, 43,
- 14, 12, 29, 42, 34, 25, 33, 41, 30, -2, -24, -5, 36, 65, 50, 3,
- -24, -24, -19, -33, -54, -52, -42, -45, -61, -75, -58, -15, 32, 48, 25, 10,
- 24, 45, 45, 27, 26, 32, 28, 13, -4, -6, 14, 44, 55, 24, -11, -18,
- -12, -20, -46, -57, -53, -54, -57, -63, -57, -33, 4, 35, 32, 16, 22, 40,
- 49, 36, 26, 28, 23, 17, 8, 1, 10, 27, 43, 33, 5, -6, -8, -14,
- -33, -53, -57, -61, -62, -61, -59, -38, -10, 15, 26, 20, 26, 40, 44, 41,
- 30, 27, 25, 18, 12, 3, 9, 26, 33, 28, 13, 5, 5, -8, -25, -45,
- -57, -60, -64, -66, -65, -49, -17, 6, 13, 16, 26, 43, 47, 39, 32, 27,
- 27, 25, 13, 3, 6, 22, 35, 26, 13, 10, 12, 5, -17, -40, -54, -58,
- -58, -68, -74, -61, -31, -1, 9, 10, 23, 40, 50, 45, 31, 24, 27, 31,
- 20, 3, 2, 17, 32, 31, 16, 12, 15, 12, -4, -31, -51, -55, -54, -62,
- -76, -73, -47, -17, 2, 8, 19, 37, 51, 50, 34, 24, 26, 31, 25, 9,
- 4, 13, 26, 34, 25, 9, 13, 20, -2, -33, -44, -43, -58, -78, -77, -59,
- -44, -33, -10, 17, 6, 12, -9, 32, 13, 4, -4, 6, -9, 27, 8, 2,
- -1, -3, -2, 3, -4, -3, 2, 0, -2, 1, -2, 1, -4, 2, 1, 0,
- -2, -1, -3, 2, 0, -1, -2, -2, -2, -1, -2, -2, -1, -2, -2, -2,
- -2, -1, -2, -1, 0, -1, -2, -2, -2, -1, 0, -2, -2, -2, -2, -1,
- -1, -2, -1, -2, -2, -2, -3, -1, -1, 0, 0, -1, -3, -2, 1, 3,
- 0, 0, -2, -8, -21, -17, -2, 12, 20, 19, 6, -13, -28, -73, -67, -64,
- -58, -39, -11, 19, 38, 60, 96, 80, 38, 12, 6, -20, -65, -83, -65, -61,
- -56, -17, 22, 35, 49, 74, 94, 55, 16, 20, -5, -52, -89, -81, -53, -65,
- -36, 21, 37, 48, 51, 85, 82, 25, 23, 9, -36, -80, -105, -58, -57, -54,
- 7, 36, 54, 44, 58, 97, 48, 26, 16, -21, -61, -115, -83, -45, -57, -12,
- 23, 57, 54, 36, 86, 77, 37, 21, -16, -40, -103, -110, -54, -46, -24, 6,
- 43, 68, 36, 62, 86, 60, 30, -12, -34, -80, -119, -76, -44, -24, -5, 24,
- 64, 51, 50, 76, 72, 48, 0, -34, -68, -106, -94, -56, -26, -7, 11, 45,
- 59, 58, 66, 71, 60, 23, -27, -68, -93, -93, -72, -37, -8, 10, 25, 50,
- 70, 68, 62, 62, 45, -10, -70, -88, -83, -79, -57, -15, 15, 13, 31, 73,
- 80, 59, 53, 61, 15, -67, -89, -73, -75, -75, -33, 21, 11, 10, 66, 92,
- 65, 42, 63, 42, -56, -92, -66, -66, -84, -57, 16, 19, -5, 50, 98, 76,
- 39, 56, 60, -35, -95, -64, -53, -84, -79, 0, 28, -8, 29, 96, 89, 42,
- 46, 69, -10, -90, -69, -41, -74, -95, -25, 28, -1, 13, 81, 101, 53, 37,
- 69, 11, -77, -75, -38, -53, -103, -55, 22, 8, 6, 61, 104, 75, 29, 59,
- 31, -61, -76, -43, -36, -91, -88, 6, 17, 1, 46, 96, 94, 34, 40, 48,
- -40, -80, -47, -27, -69, -107, -27, 26, 4, 29, 87, 105, 51, 24, 46, -10,
- -76, -58, -21, -49, -107, -62, 17, 16, 17, 70, 110, 67, 22, 38, 10, -60,
- -71, -24, -28, -97, -85, -6, 25, 18, 50, 106, 84, 28, 31, 16, -38, -71,
- -38, -17, -78, -94, -30, 15, 30, 41, 86, 92, 44, 31, 15, -25, -54, -53,
- -26, -57, -88, -51, -2, 33, 45, 68, 88, 59, 35, 17, -15, -42, -55, -41,
- -48, -73, -60, -19, 24, 50, 61, 74, 67, 46, 21, -8, -32, -48, -54, -53,
- -57, -57, -34, 9, 50, 63, 59, 65, 58, 29, -1, -24, -38, -62, -67, -48,
- -47, -40, -8, 43, 68, 48, 58, 66, 38, 6, -19, -26, -62, -85, -45, -35,
- -39, -21, 28, 72, 41, 47, 74, 45, 15, -14, -17, -53, -102, -50, -24, -36,
- -26, 10, 69, 42, 32, 81, 52, 21, -4, -15, -39, -109, -64, -12, -35, -26,
- -1, 54, 47, 21, 79, 65, 20, 7, -12, -33, -100, -82, -8, -27, -32, -2,
- 36, 47, 21, 66, 77, 25, 12, -2, -36, -88, -87, -18, -16, -36, -8, 27,
- 36, 30, 56, 77, 39, 12, 6, -33, -84, -79, -30, -11, -29, -20, 19, 27,
- 31, 58, 66, 50, 21, 5, -25, -81, -75, -32, -17, -17, -27, 2, 24, 28,
- 61, 61, 48, 35, 4, -22, -71, -77, -31, -19, -12, -23, -18, 16, 29, 59,
- 65, 45, 41, 10, -23, -59, -76, -37, -14, -11, -18, -29, -2, 29, 57, 68,
- 51, 37, 16, -21, -55, -67, -44, -12, -5, -21, -29, -19, 19, 59, 68, 61,
- 36, 14, -12, -55, -61, -44, -16, 3, -21, -29, -25, 0, 55, 72, 69, 43,
- 8, -6, -49, -63, -39, -18, 5, -15, -31, -26, -18, 39, 78, 75, 53, 8,
- -8, -40, -67, -37, -15, 2, -8, -30, -26, -29, 16, 79, 84, 59, 14, -11,
- -33, -66, -42, -9, -2, -6, -23, -26, -33, -7, 66, 94, 67, 22, -9, -32,
- -62, -48, -8, 0, -9, -16, -20, -35, -24, 46, 96, 78, 31, -2, -29, -59,
- -51, -13, 1, -10, -13, -9, -31, -35, 23, 86, 88, 42, 5, -22, -57, -53,
- -18, -3, -10, -13, 0, -19, -44, 2, 69, 90, 57, 12, -13, -50, -57, -21,
- -9, -13, -13, 1, -3, -41, -17, 51, 82, 69, 23, -9, -37, -57, -25, -12,
- -22, -15, 0, 10, -25, -32, 32, 69, 71, 37, -4, -25, -48, -30, -12, -32,
- -23, -3, 14, -2, -33, 11, 56, 63, 49, 3, -18, -32, -31, -13, -37, -38,
- -9, 11, 17, -16, -6, 41, 53, 51, 11, -17, -15, -23, -14, -35, -54, -22,
- 4, 26, 10, -10, 26, 43, 46, 19, -19, -6, -5, -10, -30, -65, -42, -9,
- 24, 35, 3, 12, 32, 37, 24, -20, -8, 14, 2, -23, -68, -62, -26, 10,
- 50, 28, 11, 22, 27, 24, -19, -19, 24, 21, -8, -63, -78, -45, -11, 47,
- 53, 23, 21, 19, 22, -17, -34, 21, 40, 15, -48, -89, -65, -34, 30, 68,
- 44, 27, 16, 16, -11, -47, 3, 49, 39, -22, -89, -82, -55, 3, 68, 61,
- 44, 21, 11, -6, -53, -21, 45, 56, 11, -74, -96, -72, -26, 52, 73, 60,
- 39, 10, -3, -48, -44, 27, 61, 42, -43, -101, -88, -52, 27, 73, 70, 59,
- 21, -1, -40, -60, 2, 52, 60, -4, -90, -100, -74, -2, 62, 72, 76, 42,
- 5, -30, -66, -22, 34, 63, 33, -62, -104, -92, -31, 44, 68, 84, 66, 21,
- -21, -64, -41, 13, 54, 55, -26, -94, -104, -57, 20, 56, 82, 84, 43, -6,
- -57, -54, -10, 36, 60, 7, -70, -107, -78, -6, 40, 73, 92, 66, 12, -45,
- -57, -27, 16, 52, 29, -41, -96, -90, -32, 20, 60, 91, 83, 34, -27, -52,
- -37, -3, 34, 36, -15, -77, -91, -52, -1, 43, 83, 93, 53, -5, -42, -40,
- -17, 14, 32, 1, -54, -81, -65, -21, 23, 71, 96, 67, 16, -25, -37, -24,
- -5, 21, 6, -36, -64, -69, -37, 3, 54, 93, 73, 35, -6, -28, -25, -19,
- 8, 4, -27, -46, -65, -46, -14, 34, 86, 73, 49, 15, -17, -19, -28, -4,
- -3, -28, -32, -56, -48, -24, 15, 74, 67, 55, 36, -2, -10, -28, -14, -9,
- -36, -25, -42, -50, -29, 1, 60, 59, 50, 55, 16, -3, -22, -20, -14, -46,
- -29, -28, -48, -33, -5, 47, 50, 40, 64, 40, 4, -14, -17, -19, -53, -40,
- -18, -40, -41, -6, 39, 39, 28, 61, 62, 17, -10, -7, -21, -59, -53, -20,
- -28, -47, -11, 38, 29, 15, 52, 77, 36, -6, 1, -12, -63, -66, -25, -20,
- -46, -19, 37, 28, 0, 38, 83, 54, 5, 5, -2, -57, -81, -34, -15, -44,
- -22, 29, 31, -4, 16, 85, 68, 17, 15, 1, -44, -87, -54, -8, -42, -27,
- 25, 24, 2, 0, 69, 88, 24, 25, 11, -42, -76, -75, -14, -25, -40, 23,
- 18, -3, 3, 42, 96, 45, 22, 29, -39, -70, -75, -40, -8, -39, 7, 24,
- -17, 8, 33, 79, 76, 22, 35, -21, -75, -64, -60, -15, -17, -14, 21, -21,
- -4, 40, 59, 88, 45, 24, -3, -71, -61, -59, -38, 1, -14, 0, -17, -18,
- 41, 54, 82, 74, 22, -3, -53, -61, -53, -54, -2, 3, -19, -25, -22, 30,
- 57, 73, 92, 38, -15, -40, -51, -50, -58, -17, 17, -23, -44, -22, 19, 55,
- 72, 97, 60, -22, -40, -35, -45, -55, -32, 14, -17, -60, -26, 11, 46, 75,
- 97, 78, -17, -46, -23, -38, -45, -37, -1, -14, -66, -31, 3, 34, 80, 98,
- 85, -4, -47, -19, -33, -33, -30, -20, -25, -63, -34, -4, 18, 79, 104, 84,
- 9, -38, -18, -29, -27, -14, -30, -46, -63, -32, -5, 3, 68, 111, 84, 18,
- -23, -12, -25, -28, -2, -25, -67, -75, -29, 1, -6, 46, 112, 91, 22, -11,
- 0, -18, -33, -1, -9, -76, -96, -34, 9, -8, 22, 101, 102, 27, -2, 14,
- -7, -36, -9, 4, -68, -114, -48, 13, -3, 5, 80, 109, 40, 4, 26, 6,
- -33, -18, 6, -52, -120, -67, 7, 4, -1, 55, 103, 58, 14, 31, 17, -21,
- -24, -4, -39, -110, -84, -10, 6, 2, 34, 87, 71, 29, 36, 25, -7, -23,
- -16, -33, -96, -90, -29, -1, 6, 22, 68, 75, 45, 45, 31, 4, -15, -24,
- -37, -84, -87, -43, -15, 3, 18, 53, 68, 57, 58, 38, 11, -7, -22, -45,
- -81, -79, -48, -29, -10, 17, 45, 57, 61, 71, 50, 17, 0, -15, -49, -85,
- -74, -45, -40, -25, 10, 42, 49, 55, 82, 65, 22, 7, -9, -43, -89, -80,
- -34, -47, -40, -1, 35, 52, 43, 85, 84, 25, 17, -4, -38, -85, -92, -28,
- -44, -55, -9, 21, 53, 42, 75, 100, 35, 22, 6, -38, -74, -99, -38, -34,
- -65, -18, 12, 42, 51, 63, 102, 52, 25, 21, -36, -70, -90, -56, -30, -64,
- -30, 7, 27, 55, 63, 90, 69, 33, 26, -26, -69, -79, -66, -43, -54, -37,
- -1, 17, 49, 69, 79, 72, 50, 30, -15, -61, -75, -68, -58, -52, -33, -12,
- 9, 42, 69, 78, 64, 60, 42, -9, -49, -71, -69, -68, -61, -25, -17, -1,
- 38, 64, 77, 59, 62, 58, -3, -37, -62, -72, -72, -73, -24, -12, -11, 35,
- 55, 73, 59, 58, 69, 8, -29, -48, -75, -76, -82, -31, -4, -14, 28, 49,
- 63, 61, 54, 73, 22, -21, -36, -71, -82, -88, -42, 0, -9, 21, 43, 53,
- 57, 56, 73, 33, -12, -25, -62, -89, -95, -49, -2, -2, 18, 37, 43, 49,
- 60, 75, 38, -2, -16, -49, -89, -105, -54, -7, 1, 19, 31, 37, 38, 59,
- 81, 39, 4, -7, -35, -83, -115, -62, -10, 0, 20, 27, 32, 30, 53, 87,
- 43, 4, 0, -24, -70, -118, -75, -12, -2, 19, 24, 27, 27, 45, 89, 52,
- 4, 1, -14, -55, -113, -87, -18, -3, 13, 20, 24, 28, 41, 85, 60, 7,
- -3, -9, -40, -100, -91, -28, -4, 7, 10, 21, 30, 43, 82, 62, 13, -8,
- -11, -26, -85, -87, -36, -10, 2, -4, 14, 35, 47, 81, 62, 18, -9, -21,
- -20, -65, -78, -38, -19, -4, -16, 0, 39, 54, 85, 65, 20, -7, -31, -24,
- -47, -62, -33, -26, -15, -25, -19, 35, 63, 90, 73, 22, -3, -39, -39, -35,
- -43, -20, -26, -30, -34, -36, 24, 71, 94, 85, 29, -3, -40, -58, -34, -24,
- -4, -16, -46, -47, -47, 6, 73, 100, 97, 42, -4, -39, -73, -45, -8, 12,
- 0, -51, -64, -56, -13, 66, 104, 106, 64, 2, -40, -82, -63, -3, 27, 18,
- -43, -82, -68, -28, 51, 104, 112, 86, 19, -42, -86, -81, -10, 40, 34, -26,
- -90, -86, -41, 31, 98, 116, 104, 46, -38, -92, -95, -25, 46, 48, -6, -84,
- -105, -55, 13, 84, 117, 114, 76, -20, -95, -105, -45, 41, 54, 8, -65, -112,
- -70, -1, 65, 109, 115, 100, 14, -85, -106, -62, 21, 50, 13, -44, -104, -84,
- -14, 45, 98, 112, 111, 53, -62, -105, -75, -3, 44, 12, -31, -85, -93, -27,
- 27, 82, 110, 110, 81, -27, -95, -81, -27, 31, 11, -31, -66, -90, -39, 12,
- 61, 106, 107, 94, 12, -73, -79, -48, 11, 13, -32, -57, -78, -46, -1, 38,
- 97, 109, 96, 43, -41, -69, -62, -13, 13, -30, -58, -68, -46, -11, 17, 81,
- 112, 97, 59, -7, -51, -67, -37, 6, -23, -62, -67, -42, -14, 2, 60, 110,
- 99, 65, 20, -24, -63, -56, -7, -15, -63, -75, -40, -12, -8, 39, 102, 103,
- 67, 35, 6, -48, -68, -25, -11, -56, -85, -46, -7, -10, 22, 86, 107, 72,
- 41, 29, -25, -70, -42, -14, -42, -91, -62, -5, -6, 9, 67, 105, 84, 40,
- 40, 3, -64, -56, -23, -30, -83, -85, -12, 3, 1, 50, 97, 96, 44, 36,
- 28, -45, -69, -33, -22, -67, -101, -34, 13, 2, 31, 88, 104, 56, 28, 37,
- -16, -71, -51, -18, -49, -103, -62, 9, 14, 18, 70, 109, 68, 26, 36, 6,
- -58, -68, -23, -28, -97, -84, -7, 23, 19, 50, 106, 84, 28, 31, -21, -26,
- -18, -30, -24, -77, -76, -48, -46, 31, 0, -1, 0, 0, 2, 0, 1, -2,
- 1, 0, -6, -7, -5, -3, 0, -3, -4, -2, 2, 0, -8, -11, -14, -10,
- -8, -4, 6, 13, 14, 9, 2, -6, -10, -9, -6, 9, 17, 15, 8, 0,
- 1, -4, -12, -19, -14, -8, -4, 3, 6, -2, -4, -6, -7, -10, -8, -12,
- -11, 3, 23, 27, 11, 4, -3, -5, 0, -9, -3, 6, 11, 19, 4, -8,
- -17, -20, -21, -3, 5, 8, 2, 3, 5, 2, -3, -3, -12, 4, 1, 3,
- -7, 0, 5, 6, 0, -7, -8, -5, -7, -5, -3, 4, 9, 5, -5, -5,
- -5, -17, -7, 3, 17, 15, 7, -2, -5, -3, 3, -8, -5, -3, 3, 8,
- 12, 5, -10, -27, -20, 1, 5, -4, -9, -17, 4, 10, 9, -2, -12, -16,
- -12, -2, 8, 16, 13, 11, 16, 19, 10, -2, -16, -21, -11, 14, 15, 21,
- 11, 6, -10, -8, -11, -24, -35, -31, -13, 9, 24, 17, -2, -11, -20, -11,
- -19, -7, 3, 8, 22, 21, 21, 2, -7, -10, 12, 24, 18, -3, -19, -6,
- 0, -5, -18, -17, 6, 12, 7, -16, -20, -22, -27, -19, -14, 12, 14, 3,
- 0, 2, 8, -3, -5, -3, 21, 29, 17, 6, -8, 3, 3, 10, 10, 3,
- 12, 4, -9, -18, -20, -20, -9, 6, 3, -9, -7, -14, -9, -8, -9, -23,
- -19, 7, 17, 20, 9, 8, 5, 9, 18, 9, 8, -10, -10, -4, 9, 25,
- -6, -19, -19, -5, -4, -7, -7, -17, -15, -7, -4, 0, 2, -2, -17, -4,
- 14, 23, 15, 2, -7, -5, 9, 11, 1, 0, -3, 0, 0, 15, 14, -4,
- -15, -20, -26, -22, -13, 0, 6, 12, 5, -10, 2, 8, -2, -18, -8, 6,
- 20, 28, 23, 0, -16, -7, 9, 7, 10, -12, -21, -19, 7, 12, 4, -17,
- -28, -24, -3, 14, 4, -19, -18, -9, 11, 22, 16, -13, -23, -15, 18, 32,
- 32, 17, -4, 1, 14, 11, 1, -20, -19, -3, 9, 13, -4, -13, -16, -18,
- -23, -12, -17, -16, -20, -15, -14, -4, 8, 12, 0, 8, 5, 12, 17, 26,
- 25, 14, 10, 11, 11, 18, 15, 4, -9, -13, -8, -9, -14, -20, -28, -32,
- -12, -9, -16, -17, -24, -18, -12, 5, 10, 4, 6, 8, 18, 35, 31, 17,
- 1, 12, 21, 33, 18, 6, -10, -11, -4, -9, -13, -19, -24, -24, -24, -18,
- -20, -18, -20, -13, -15, -10, -9, -5, 8, 10, 13, 23, 26, 29, 14, 13,
- 13, 13, 16, 25, 19, 17, 4, -15, -18, -15, -14, -17, -34, -23, -16, -12,
- -16, -26, -33, -23, -15, -4, 4, 10, 16, 19, 22, 29, 28, 7, 1, 2,
- 18, 26, 30, 21, 9, 3, -4, -10, -16, -29, -31, -27, -4, -9, -11, -28,
- -23, -17, -15, -13, -11, 4, 11, 9, 13, 16, 25, 18, 8, 10, 18, 17,
- 8, 18, 17, 11, -5, -19, -17, -12, -19, -38, -27, -8, 0, -3, -14, -19,
- -20, -14, -10, -13, -3, 6, 12, 26, 38, 34, 14, 2, -2, 11, 19, 14,
- 8, 5, 16, 9, -7, -19, -24, -29, -36, -26, -13, -12, -22, -28, -20, 5,
- -3, -10, -19, 7, 20, 18, 17, 24, 25, 14, 18, 19, 29, 21, 11, 10,
- 9, 13, -13, -29, -27, -20, -24, -30, -22, -12, -7, -15, -22, -21, -13, -14,
- -20, -8, 12, 26, 25, 21, 33, 27, 25, 16, 13, 16, 16, -2, 2, 11,
- 9, -2, -17, -18, -16, -25, -25, -26, -27, -30, -35, -30, -12, -6, -6, -6,
- -5, 19, 19, 11, 15, 17, 24, 23, 34, 28, 23, 13, 2, 9, 18, 16,
- -14, -18, -12, -7, -9, -31, -37, -33, -24, -14, -24, -20, -16, -21, -15, -7,
- 5, 9, 15, 20, 28, 38, 29, 21, 15, 22, 17, 4, 12, 6, 12, -4,
- -9, -15, -16, -19, -40, -38, -34, -23, -18, -17, -8, -10, -3, -7, 1, 3,
- 4, 11, 13, 36, 41, 36, 24, 9, 17, 20, 21, 14, -5, -9, -11, -8,
- -19, -14, -24, -30, -23, -18, -25, -30, -24, -17, -20, -9, -3, 6, 8, 22,
- 23, 20, 27, 18, 10, 10, 14, 18, 14, 23, 17, 6, 5, -4, -8, -26,
- -19, -24, -25, -24, -21, -27, -28, -15, -19, -16, -9, 0, 7, 9, 17, 14,
- 15, 24, 30, 29, 29, 32, 16, 10, 8, 0, -3, -10, -7, -17, -22, -25,
- -30, -36, -32, -25, -26, -22, -12, -16, -11, -3, 5, 7, 13, 21, 21, 26,
- 32, 28, 26, 28, 31, 17, 15, 15, 5, -4, -14, -18, -28, -25, -24, -28,
- -32, -33, -32, -29, -18, -17, -20, -10, -4, 6, 6, 18, 22, 22, 37, 38,
- 31, 27, 26, 23, 22, 23, 12, 4, -5, -2, -11, -19, -25, -35, -35, -36,
- -36, -43, -32, -24, -20, -12, -7, -3, -7, 3, 13, 23, 29, 35, 37, 35,
- 42, 33, 26, 22, 17, 12, 6, 4, -9, -23, -28, -34, -34, -33, -31, -40,
- -36, -27, -25, -22, -30, -20, -11, 2, 12, 22, 22, 26, 28, 35, 47, 44,
- 27, 29, 29, 29, 19, 2, 1, -9, -15, -21, -34, -35, -34, -40, -44, -42,
- -34, -31, -26, -21, -9, -12, -3, 10, 17, 29, 26, 27, 34, 48, 50, 34,
- 33, 25, 21, 16, 8, 3, -8, -11, -25, -30, -37, -37, -42, -51, -34, -28,
- -21, -26, -25, -19, -13, 4, 9, 17, 29, 41, 33, 33, 44, 45, 32, 31,
- 28, 22, 16, 5, -10, -13, -16, -23, -38, -39, -39, -45, -54, -40, -32, -24,
- -22, -17, -14, 0, 6, 9, 18, 41, 43, 34, 32, 40, 40, 31, 30, 27,
- 22, 19, 14, -2, -16, -21, -34, -48, -45, -41, -41, -41, -45, -38, -25, -21,
- -17, -20, -7, 11, 17, 19, 36, 40, 42, 44, 47, 46, 39, 33, 26, 15,
- 11, 8, -5, -19, -24, -29, -40, -44, -48, -44, -37, -37, -43, -43, -26, -19,
- -14, -2, 13, 23, 31, 36, 36, 43, 41, 47, 46, 44, 40, 24, 15, 14,
- 3, -12, -21, -23, -30, -36, -47, -51, -50, -47, -44, -46, -31, -19, -16, -11,
- 2, 16, 20, 25, 29, 40, 53, 51, 49, 45, 41, 35, 25, 18, 7, 5,
- -12, -18, -23, -34, -39, -56, -58, -54, -49, -50, -45, -35, -26, -12, -5, 6,
- 17, 29, 41, 42, 47, 50, 46, 49, 50, 50, 39, 30, 16, 2, -8, -15,
- -21, -30, -41, -49, -50, -46, -57, -63, -57, -41, -29, -24, -12, -3, 5, 12,
- 22, 33, 41, 50, 51, 53, 57, 55, 46, 36, 29, 16, 2, -4, -11, -21,
- -33, -40, -49, -47, -53, -60, -58, -51, -42, -34, -23, -13, -2, 5, 17, 27,
- 39, 49, 48, 51, 56, 54, 58, 44, 37, 28, 18, 4, -3, -15, -29, -39,
- -49, -49, -51, -62, -65, -64, -47, -42, -36, -26, -14, -5, 10, 24, 32, 45,
- 50, 49, 62, 65, 63, 47, 42, 41, 36, 23, 7, -7, -22, -31, -41, -53,
- -58, -62, -59, -62, -56, -54, -50, -44, -32, -16, 0, 11, 25, 35, 50, 54,
- 55, 56, 66, 65, 62, 54, 45, 36, 23, 14, -4, -22, -44, -55, -52, -62,
- -61, -66, -70, -68, -60, -54, -45, -29, -15, 4, 21, 34, 36, 44, 54, 62,
- 70, 73, 68, 67, 59, 50, 37, 21, -5, -12, -25, -39, -48, -53, -63, -76,
- -73, -71, -71, -67, -57, -45, -29, -12, 2, 13, 30, 42, 51, 61, 76, 71,
- 63, 66, 71, 60, 50, 40, 23, -2, -9, -20, -41, -54, -59, -72, -79, -71,
- -64, -73, -68, -60, -51, -36, -13, 2, 13, 27, 47, 54, 71, 78, 71, 60,
- 72, 74, 65, 54, 39, 28, 7, -6, -23, -50, -59, -64, -69, -75, -70, -78,
- -74, -73, -64, -52, -37, -13, 6, 18, 40, 51, 58, 64, 78, 79, 75, 68,
- 64, 68, 57, 45, 21, 4, -16, -34, -50, -65, -75, -83, -80, -71, -69, -68,
- -73, -63, -57, -36, -16, 6, 26, 45, 60, 70, 71, 79, 79, 81, 78, 80,
- 64, 55, 36, 16, -4, -23, -38, -54, -63, -69, -81, -85, -87, -76, -72, -66,
- -61, -52, -30, -12, 12, 24, 44, 55, 69, 78, 85, 84, 74, 70, 71, 71,
- 62, 41, 17, -11, -25, -42, -55, -66, -75, -87, -87, -81, -74, -76, -76, -63,
- -48, -32, -13, 7, 30, 51, 64, 76, 80, 82, 83, 81, 80, 82, 70, 61,
- 42, 19, 0, -28, -49, -61, -72, -78, -87, -90, -89, -88, -87, -82, -69, -54,
- -33, -13, 15, 36, 58, 68, 79, 90, 96, 90, 84, 86, 89, 79, 62, 38,
- 22, -3, -29, -55, -69, -81, -89, -94, -94, -94, -94, -89, -74, -62, -52, -35,
- -18, 14, 39, 54, 65, 76, 87, 98, 95, 94, 90, 82, 75, 69, 47, 26,
- -6, -33, -57, -72, -82, -88, -97, -90, -91, -88, -83, -80, -75, -59, -33, -9,
- 20, 42, 58, 68, 82, 90, 94, 93, 94, 88, 85, 77, 65, 43, 16, -10,
- -37, -60, -71, -84, -89, -95, -97, -102, -95, -84, -80, -72, -57, -26, -4, 19,
- 42, 62, 80, 89, 94, 97, 100, 99, 90, 83, 71, 65, 39, 14, -9, -43,
- -65, -83, -90, -95, -98, -96, -100, -96, -88, -76, -66, -51, -24, -12, 21, 45,
- 70, 85, 93, 95, 97, 101, 105, 92, 84, 69, 58, 35, 16, -14, -44, -68,
- -86, -88, -96, -101, -101, -102, -97, -90, -74, -69, -50, -19, 9, 35, 56, 76,
- 84, 92, 98, 96, 99, 97, 93, 84, 77, 59, 24, 2, -30, -52, -76, -87,
- -93, -98, -100, -102, -100, -96, -89, -81, -73, -46, -18, 12, 36, 62, 82, 88,
- 96, 104, 107, 105, 102, 92, 84, 77, 53, 26, -6, -35, -57, -75, -81, -92,
- -103, -114, -111, -108, -98, -88, -83, -67, -35, -7, 20, 39, 60, 70, 89, 106,
- 116, 107, 103, 99, 86, 90, 82, 53, 18, -13, -31, -52, -73, -92, -102, -106,
- -104, -97, -106, -99, -101, -92, -72, -42, -5, 16, 38, 66, 86, 101, 99, 101,
- 95, 112, 107, 99, 95, 81, 53, 16, -3, -29, -60, -81, -102, -98, -102, -102,
- -112, -114, -101, -104, -88, -69, -34, -8, 14, 41, 67, 92, 94, 99, 103, 104,
- 115, 109, 103, 90, 78, 52, 22, 0, -39, -65, -92, -95, -91, -103, -104, -118,
- -110, -102, -93, -84, -71, -36, -15, 19, 52, 81, 94, 89, 98, 103, 115, 117,
- 102, 92, 83, 80, 49, 23, -11, -43, -67, -90, -93, -102, -105, -110, -118, -104,
- -100, -89, -83, -64, -36, -7, 28, 50, 74, 88, 95, 104, 103, 115, 107, 106,
- 97, 87, 74, 50, 20, -17, -47, -75, -89, -93, -101, -102, -115, -117, -106, -97,
- -88, -90, -73, -38, 2, 36, 60, 75, 84, 96, 104, 115, 115, 102, 98, 96,
- 96, 84, 52, 10, -12, -32, -53, -71, -87, -101, -109, -112, -109, -106, -105, -102,
- -92, -74, -48, -19, 7, 33, 56, 76, 91, 101, 108, 111, 111, 108, 103, 96,
- 85, 63, 33, 1, -27, -51, -73, -90, -102, -109, -112, -110, -107, -103, -100, -93,
- -76, -50, -19, 10, 36, 58, 76, 91, 101, 108, 111, 111, 108, 103, 96, 85,
- 63, 33, 1, -27, -51, -73, -90, -102, -109, -112, -110, -107, -103, -100, -93, -76,
- -50, -19, 10, 36, 58, 76, -1, -2, -15, 21, -17, 23, -30, 1, 34, -34,
- 6, 5, -15, 19, 1, -25, 6, 20, -2, -28, 15, 10, -15, 0, -7, 10,
- 7, -5, -9, -6, 19, -3, -21, 3, 20, -4, -20, 1, 16, -3, -8, -2,
- 5, 1, -8, -6, 3, 9, 2, -13, -4, 15, -7, -9, 0, 3, 6, -7,
- -7, 5, 8, -8, -4, 0, 1, 1, -6, -4, 7, 2, -2, -7, 0, 4,
- -3, -4, 0, 2, 0, -2, -4, 1, 4, -2, -4, -3, 1, 3, -5, -4,
- 4, 3, -6, -5, 4, -1, -2, -3, 0, 3, -3, -1, -4, 3, 3, -5,
- -3, 1, 1, -2, -3, 1, 2, -2, -4, 0, 0, 0, -1, -3, 1, 1,
- -3, -2, 1, 0, -2, -2, 0, 0, -2, -1, 0, -1, 1, -2, -2, 1,
- 0, -2, 0, -1, 0, -1, -1, -1, 0, 0, -1, -3, 1, 1, -2, -2,
- 0, 1, -1, -2, -1, 0, 0, 0, -2, -1, 1, 0, -3, 0, 2, -1,
- -2, 0, 0, 0, -2, 0, -1, 0, -1, -1, 1, 0, -1, 0, -1, 1,
- 0, -13, 5, 7, -11, 24, -50, 41, 4, -29, 14, -11, 8, 11, -15, -12,
- 15, 18, -21, -14, 22, -2, -11, -3, -3, 18, -3, -5, -14, 9, 22, -24,
- -16, 23, 12, -23, -8, 9, 10, -4, -8, -3, 11, -4, -14, 0, 8, 8,
- -5, -14, 8, 10, -12, -4, -2, 10, 0, -11, -3, 11, 0, -7, -2, -1,
- 7, -6, -8, 3, 6, 0, -3, -8, 7, 2, -7, -2, 2, 1, -2, -4,
- -1, 3, 3, -4, -5, 1, 3, -3, -6, 2, 5, -1, -7, -1, 3, -1,
- -4, -3, 5, 0, -3, -2, -1, 4, -1, -5, -1, 3, -1, -4, -1, 3,
- 1, -4, -2, 1, 0, -2, -3, 0, 2, -1, -4, 1, 1, -1, -2, -2,
- 1, -1, -3, 0, 0, 0, -1, -2, 0, 0, -2, -1, 0, -1, 0, -2,
- -1, 0, -1, 0, -1, -2, 2, -1, -2, -1, 0, 1, -2, 0, -1, -1,
- 0, -1, -2, 0, 1, -1, -3, 0, 1, -1, -3, 0, 1, -2, -1, 0,
- 0, -1, -1, 0, -1, -1, -1, -1, 0, 0, -1, -1, 0, 0, -2, 0,
- 0, 0, 0, -2, 1, -1, 0, -1, 0, 0, 0, -1, 0, 0, 0, 0,
- -1, 0, 0, -1, 0, -1, 1, 0, 0, 0, 1, -1, -1, 0, 0, 0,
- 1, -2, 4, -3, 3, -40, 71, -73, 67, -27, -68, 127, -80, 3, 5, 1,
- 17, -14, 1, -30, 53, -3, -42, 15, 19, -9, -17, -1, 13, 16, -17, 4,
- -32, 43, 15, -68, 18, 54, -38, -7, -1, 11, 7, -3, -18, 5, 25, -27,
- -9, 9, 19, -6, -12, -8, 20, -1, -15, -1, 1, 17, -10, -16, 12, 12,
- -13, 0, -6, 10, 2, -16, -1, 14, -4, 4, -11, -2, 12, -6, -8, 4,
- 4, -2, -4, 1, -2, 4, 3, -7, -5, 8, 0, -10, 1, 4, 2, -4,
- -6, 4, 1, -1, -7, 1, 8, -9, 2, -5, 3, 3, -4, -3, 0, 3,
- -3, -5, 4, 3, -3, -4, 0, 2, 0, -3, -4, 5, 0, -5, -1, 2,
- 0, -3, 0, -1, 2, -2, -4, 3, 0, -1, -2, -1, 2, -2, -2, 1,
- -1, 0, -1, -3, 1, 1, -2, 1, -3, 1, 1, -3, -1, 1, 0, -1,
- -2, 1, -1, -1, 1, -2, 1, -1, -1, -1, -1, 0, 1, -3, 0, 0,
- 1, -4, 0, 1, -2, 0, -2, 0, 0, 0, -2, 1, -1, 0, -2, 0,
- 2, -2, -1, 0, -1, 2, -2, -1, 1, -2, 0, -1, 1, -1, -1, -1,
- 1, -2, 1, -1, -1, 2, -3, 0, 0, -1, 1, -1, 0, 1, 0, -2,
- 0, -1, 1, -2, 0, 0, -1, 1, 0, -2, 0, 1, -2, 1, 0, 0,
- -1, 0, 1, -1, -1, -1, 1, 1, -1, 0, 0, 0, -1, 1, 0, -1,
- 1, 0, 0, 1, 0, -1, 1, 0, 3, -40, 58, -39, 12, 42, -117, 108,
- 1, -66, 22, 17, 0, -9, 10, -39, 42, 4, -23, -12, 28, 3, -34, 9,
- 17, 3, -9, 10, -29, 13, 53, -79, 3, 64, -26, -24, 16, -9, 14, 2,
- -8, -15, 31, -9, -30, 11, 29, -15, -7, 0, 3, 6, -4, -9, -6, 22,
- 1, -24, 9, 11, -8, 0, -2, 2, 8, -12, -6, 10, 2, 2, -9, -4,
- 11, -2, -10, 3, 2, 3, -5, -1, 1, -1, 6, -4, -8, 9, 2, -8,
- -3, 6, 3, -4, -3, -1, 6, -2, -8, 0, 9, -4, -3, -2, 2, 4,
- -4, -1, -1, 4, -2, -6, 4, 2, -1, -4, 0, 1, 2, -3, -5, 3,
- 3, -3, -4, 3, 0, -1, 0, -2, 2, 0, -3, 0, 3, 0, -3, -1,
- 2, 0, -3, 1, 0, -1, 2, -2, -2, 2, -1, 0, -1, -1, 1, -1,
- -2, 0, 0, 1, -3, 1, 0, -1, 1, -2, -1, 2, -2, -1, 0, -1,
- 2, -3, -1, 1, 1, -2, -2, 2, 1, -2, -1, 0, 0, 1, -3, 1,
- 0, 0, 0, -2, 3, 0, -2, 0, 0, 1, 0, -1, 1, -2, 0, 0,
- 0, -1, 1, 0, 0, 0, -1, 1, -1, 1, 0, -1, 1, -2, 0, 1,
- 1, 0, 1, -2, 1, 0, 1, 0, 0, 3, -1, 0, 1, 0, 0, 3,
- -29, 35, -12, -16, 56, -88, 39, 62, -79, 5, 29, 1, -13, 12, -29, 26,
- 17, -28, -3, 12, 5, -11, -19, 28, 1, -5, 9, -21, -7, 60, -56, -20,
- 57, -10, -27, 21, -21, 16, 12, -12, -21, 24, 6, -29, 4, 19, 2, -7,
- -5, -3, 7, 6, -11, -9, 11, 13, -18, -4, 13, 1, -3, -6, -1, 10,
- -8, -6, 5, 3, 5, -3, -11, 4, 9, -11, 0, 4, 3, -4, -1, 0,
- 0, 7, 0, -14, 7, 5, -7, -4, 4, 5, -1, -4, -4, 4, 1, -4,
- -4, 7, -1, -1, -3, 0, 5, -1, -4, -1, 2, 0, -3, 1, 1, 2,
- -2, -4, 1, 2, 0, -5, 2, 3, -2, -2, 1, 1, -2, 2, -3, 0,
- 0, -1, -1, 0, 1, 0, -3, 0, 0, -1, 1, -1, -2, 1, -1, 0,
- -2, 2, 1, -2, -1, 1, 0, -1, -1, 0, 1, -1, 0, -2, 1, 1,
- -1, 0, -1, -1, 0, 0, -1, -1, 0, -1, -1, 2, -2, -1, 1, 0,
- 0, -1, -1, 1, 0, -1, 1, -1, 0, 1, -3, 1, 1, -1, -1, 0,
- 1, 0, 0, 0, -1, 0, 0, -1, 0, 1, 0, 0, 2, -2, 0, 1,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, -1, -1, -7, -9, 35, -52,
- 59, -33, -32, 64, -15, -41, 19, 22, -20, 9, -11, -3, 33, -27, 2, 7,
- -9, 19, -37, 24, 7, -11, 11, -1, -30, 37, 8, -57, 36, 19, -33, 14,
- 0, -17, 26, 1, -20, -5, 26, -18, -13, 14, 7, -6, 4, -9, -4, 11,
- 3, -14, -7, 20, 0, -18, 10, 1, 4, -5, -7, 6, 0, -3, -2, -2,
- 8, 5, -11, -6, 10, -1, -10, 6, -2, -1, 1, -3, 0, 3, 5, -9,
- -5, 9, -3, -4, 1, 1, 3, -1, -4, -1, 2, -2, -5, 5, -3, 0,
- 1, -5, 4, 2, -3, -3, 0, 0, -2, 1, 0, -2, 3, -2, -5, 2,
- 2, -2, -4, 3, 0, -2, 1, -2, -2, 5, -2, -6, 1, 2, -1, -1,
- 0, 1, -1, -2, -1, -1, 2, 0, -4, 0, 1, 0, -3, 0, 2, 0,
- -3, 0, 0, 1, -1, -1, 1, 0, -1, -2, 1, 0, 0, -1, 0, -2,
- 1, 0, -1, 1, -1, 0, -2, 1, 1, -2, -1, 2, -2, 1, -3, 1,
- 1, -1, 0, 0, -1, 1, 0, -2, 2, -1, -1, 0, 0, 1, 0, 1,
- 0, -2, 1, 0, 0, -1, 1, 0, 0, 0, 0, -3, -20, 45, -56, 40,
- -5, -34, 27, 24, -42, -1, 29, -14, -4, 2, -7, 24, -20, -1, 18, -25,
- 25, -29, 9, 21, -26, 14, 4, -20, 7, 27, -42, 5, 31, -24, -2, 19,
- -30, 21, 8, -11, -17, 20, 1, -22, 11, 7, -7, 6, -5, -7, 3, 11,
- -6, -18, 11, 16, -20, 1, 5, 2, -3, -3, 0, -3, 4, -1, -7, 2,
- 10, -9, -8, 7, 2, -9, 5, -1, -5, 2, 1, -3, -2, 9, -5, -8,
- 4, 1, -5, 0, 1, 2, -1, 0, -5, 4, -1, -5, 4, -3, 1, 1,
- -5, 3, 0, 0, -3, 0, -1, -2, 1, 2, -5, 2, 1, -5, -2, 3,
- -1, -5, 2, 1, -4, 2, -1, -4, 2, 3, -7, -1, 2, 0, -2, 1,
- 0, -2, -1, 0, -3, 1, 2, -3, -2, 3, 0, -3, -1, 1, 0, -1,
- -2, -1, 1, 0, 0, -1, 0, 0, -2, 0, 0, 1, -2, 2, -3, 1,
- 0, 0, -2, 1, 0, -1, 0, 0, -1, -1, 2, -3, 0, 0, -1, 0,
- 0, -1, 1, 0, -4, -13, 32, -41, 31, -10, -10, 4, 22, -25, -8, 21,
- -3, -14, 5, 1, 12, -23, 8, 18, -31, 25, -26, 10, 17, -23, 8, 5,
- -9, 0, 16, -25, 2, 23, -22, -2, 22, -30, 15, 7, -6, -13, 12, 1,
- -17, 9, 5, -6, 4, -3, -7, 5, 7, -6, -13, 7, 10, -11, 0, 0,
- 4, -3, -3, 2, -7, 4, 2, -5, 0, 6, -3, -8, 4, 2, -8, 7,
- 0, -8, -1, 6, 0, -8, 6, 0, -5, 1, 0, -5, 3, 2, -3, -2,
- 4, -5, -1, -1, -2, 3, -4, 1, -1, -3, 3, -1, -2, -2, 1, -2,
- -2, 1, 1, -4, 1, 2, -5, -3, 5, -3, -4, 4, -1, -4, 2, -1,
- -4, 3, 1, -5, -2, 2, 0, -2, 2, -1, -4, 3, -1, -3, 0, 1,
- -2, -2, 1, -1, -1, -1, 0, 0, -1, -1, -1, 0, -1, 1, -1, -1,
- 0, -2, 1, 0, -1, -1, 0, -1, -1, -1, 2, -2, -1, 1, -1, -2,
- 1, -1, -1, 1, -2, 1, -7, -3, 15, -23, 20, -16, 9, -12, 16, -12,
- -8, 11, 5, -18, 6, 8, 0, -18, 16, 4, -19, 16, -17, 10, 5, -8,
- -2, 9, -5, -4, 10, -17, 5, 13, -18, 2, 12, -17, 10, 0, -2, -8,
- 7, -4, -7, 6, 1, -3, 1, 3, -9, -2, 10, -7, -8, 4, 6, -6,
- 1, 0, 0, -2, 1, -1, -8, 6, 1, -5, 2, 4, -2, -4, 1, 1,
- -7, 5, -1, -4, -2, 4, 0, -4, 4, -3, -4, 1, 0, -3, 0, 2,
- -1, -2, 2, -2, -1, -3, 0, 3, -4, 3, -3, 0, 2, 0, -3, -1,
- 1, -3, -1, 2, 0, -1, 0, 0, -3, 0, 1, -4, -1, 2, 0, -2,
- 0, 1, -3, 1, 1, -3, -2, 2, -1, -1, 2, -1, -2, 1, 0, -1,
- -1, -1, -3, -8, -16, -20, -7, 14, 20, 19, 18, 16, 11, 3, -9, -21,
- -36, -43, -39, -24, 6, 38, 57, 55, 26, 0, -7, -10, -13, -12, -11, -29,
- -56, -59, -37, 0, 43, 74, 87, 75, 37, -2, -31, -51, -59, -45, -15, -16,
- -34, -20, -10, -5, 29, 61, 72, 51, 18, -2, -21, -39, -35, -24, 1, 0,
- -31, -29, -23, -44, -13, 48, 82, 79, 46, 16, -4, -44, -58, -26, 3, 6,
- -38, -52, -24, -42, -35, 47, 95, 88, 55, 19, 12, -22, -72, -38, 4, 3,
- -31, -67, -29, -24, -60, 23, 112, 111, 72, 22, 7, -20, -90, -73, -1, 19,
- -4, -57, -36, 3, -54, -32, 98, 125, 71, 14, 14, 0, -82, -106, 0, 42,
- 10, -48, -32, -2, -54, -63, 72, 125, 82, 24, 14, -8, -57, -104, -22, 52,
- 34, -34, -46, -16, -35, -83, 32, 127, 99, 26, 19, 4, -55, -110, -48, 45,
- 36, -12, -26, -22, -41, -64, -7, 107, 113, 56, 6, 4, -41, -92, -74, 35,
- 57, 12, -41, -21, -39, -67, -40, 86, 114, 71, 10, 22, -31, -83, -83, 16,
- 46, 34, -28, -18, -42, -58, -60, 55, 108, 97, 3, 21, -8, -77, -102, 10,
- 45, 42, -26, -2, -27, -68, -73, 45, 83, 92, 29, 25, -8, -56, -104, -13,
- 35, 52, -6, -7, -22, -46, -91, 10, 80, 95, 35, 26, 8, -38, -106, -34,
- 34, 42, 5, 1, -23, -39, -73, -28, 61, 89, 60, 20, 2, -7, -73, -86,
- 24, 52, 26, -12, -11, -19, -58, -86, 46, 91, 62, 17, 22, -15, -39, -106,
- 8, 55, 45, -13, -6, -30, -21, -102, 4, 82, 87, 7, 28, -3, -9, -115,
- -32, 50, 63, -23, 8, -19, -18, -94, -28, 61, 96, 14, 39, -4, 1, -85,
- -60, 23, 79, -3, 2, -20, -10, -82, -65, 25, 108, 28, 31, 19, 9, -65,
- -74, -5, 78, 16, -3, -9, -14, -65, -76, -3, 93, 60, 29, 22, 13, -43,
- -90, -30, 61, 49, -9, -1, 4, -52, -98, -16, 68, 72, 21, 38, 15, -31,
- -94, -34, 32, 67, 5, 9, 0, -28, -111, -33, 40, 85, 24, 37, 23, -6,
- -104, -44, 13, 69, 9, 14, 8, -11, -110, -53, 20, 80, 32, 48, 30, 5,
- -87, -66, -7, 63, 33, 12, 2, 5, -86, -94, -2, 79, 46, 26, 44, 22,
- -59, -88, -19, 54, 48, 13, 14, 4, -51, -112, -37, 67, 71, 21, 38, 29,
- -29, -104, -50, 44, 63, 11, 10, 14, -24, -103, -67, 49, 88, 20, 27, 43,
- -10, -90, -79, 24, 69, 21, 7, 18, -8, -82, -103, 17, 94, 38, 10, 54,
- 12, -70, -97, 1, 68, 37, -4, 27, -6, -56, -104, -21, 82, 67, -3, 46,
- 23, -37, -108, -31, 57, 58, -13, 29, 11, -32, -106, -50, 53, 92, -6, 38,
- 38, -15, -105, -54, 34, 79, -12, 20, 22, -11, -98, -70, 22, 99, 4, 16,
- 48, 14, -99, -75, 15, 82, 2, 0, 44, 8, -93, -80, 0, 84, 29, -3,
- 57, 32, -79, -94, 1, 66, 27, -19, 49, 29, -73, -109, -7, 54, 52, -17,
- 62, 53, -46, -113, -4, 43, 51, -30, 46, 37, -42, -128, -23, 26, 69, -18,
- 51, 59, -2, -122, -30, 24, 66, -27, 31, 51, 1, -128, -48, 13, 71, -11,
- 33, 66, 22, -110, -57, 8, 68, -9, 12, 53, 28, -104, -87, -4, 67, 8,
- 8, 72, 53, -80, -91, -4, 59, 10, -13, 63, 44, -81, -109, -19, 46, 33,
- -6, 76, 57, -43, -104, -24, 36, 42, -26, 55, 51, -34, -126, -39, 19, 58,
- -21, 68, 71, -8, -114, -32, 2, 62, -24, 52, 54, -4, -120, -53, -22, 71,
- -8, 49, 62, 31, -102, -52, -25, 70, -5, 24, 55, 35, -109, -69, -40, 59,
- 16, 25, 65, 55, -80, -70, -37, 47, 23, 7, 48, 51, -73, -97, -48, 30,
- 46, 6, 57, 74, -37, -98, -34, 21, 48, -10, 44, 58, -34, -123, -46, -2,
- 61, 2, 50, 69, 10, -110, -40, -5, 59, -9, 31, 53, 19, -126, -59, -20,
- 62, 8, 32, 64, 49, -105, -59, -16, 58, 2, 17, 50, 45, -102, -83, -31,
- 46, 24, 15, 53, 69, -65, -86, -24, 42, 25, -4, 45, 64, -58, -112, -37,
- 30, 41, -6, 51, 75, -24, -105, -32, 26, 41, -19, 39, 62, -14, -117, -51,
- 7, 54, -13, 35, 78, 19, -105, -47, 9, 58, -19, 21, 69, 18, -113, -66,
- -10, 52, -10, 14, 75, 42, -83, -60, -5, 52, 0, -3, 69, 43, -83, -83,
- -21, 35, 17, -13, 72, 57, -54, -82, -10, 29, 28, -29, 65, 52, -45, -98,
- -21, 1, 40, -30, 64, 63, -7, -94, -9, 1, 51, -36, 51, 54, -8, -115,
- -23, -22, 47, -30, 48, 65, 24, -90, -13, -15, 46, -26, 30, 55, 21, -100,
- -37, -26, 31, -10, 24, 65, 41, -71, -35, -10, 25, -2, 4, 58, 32, -69,
- -61, -16, 2, 8, 1, 67, 42, -33, -56, -1, -1, 20, -13, 59, 33, -28,
- -82, -10, -20, 22, -15, 64, 40, -1, -70, 0, -17, 29, -22, 53, 33, 1,
- -84, -15, -29, 22, -19, 53, 43, 22, -64, -7, -19, 25, -18, 37, 38, 16,
- -73, -30, -33, 11, -14, 32, 50, 31, -45, -17, -15, 16, -4, 16, 43, 23,
- -49, -43, -30, -2, -1, 8, 52, 36, -25, -32, -13, -1, 11, -1, 42, 30,
- -25, -49, -25, -18, 10, -7, 44, 40, -2, -34, -11, -15, 21, -6, 29, 33,
- -5, -54, -29, -30, 13, -6, 29, 46, 15, -32, -10, -18, 16, -1, 13, 36,
- 9, -45, -30, -32, 0, 1, 12, 43, 28, -23, -16, -16, 6, 9, 2, 33,
- 22, -33, -34, -27, -11, 2, 1, 35, 36, -14, -16, -11, -5, 8, 3, 24,
- 32, -19, -30, -29, -17, -4, 1, 20, 43, -5, -14, -13, -4, 0, 7, 11,
- 39, -9, -23, -28, -17, -16, 1, 9, 44, 3, -7, -15, -4, -4, 7, 5,
- 38, 3, -20, -30, -19, -19, -8, 0, 40, 17, -6, -7, -3, -2, -1, 4,
- 32, 16, -20, -21, -26, -17, -18, -3, 28, 32, -7, -1, -9, 4, -9, 3,
- 22, 34, -19, -14, -27, -13, -27, -10, 16, 44, -8, 5, -6, 3, -12, 1,
- 13, 40, -12, -11, -25, -17, -27, -15, 5, 45, 4, 2, 0, 0, -9, -5,
- 6, 38, 2, -17, -14, -20, -24, -23, 0, 38, 19, -4, 11, -4, -7, -10,
- 4, 27, 20, -20, -9, -23, -22, -30, -6, 26, 35, -8, 12, 2, -4, -15,
- 2, 20, 32, -16, -7, -15, -22, -37, -14, 18, 39, -3, 5, 8, -5, -18,
- -2, 18, 34, -4, -14, -4, -21, -35, -25, 15, 36, 8, -4, 21, -5, -17,
- -14, 23, 26, 9, -22, 4, -25, -32, -40, 14, 27, 24, -12, 30, 1, -8,
- -26, 24, 21, 19, -28, 9, -20, -28, -51, 7, 23, 30, -15, 27, 9, -7,
- -32, 16, 25, 23, -21, 4, -8, -27, -50, -10, 25, 29, -9, 13, 24, -7,
- -28, -3, 34, 20, -12, -9, 10, -31, -43, -29, 30, 23, 2, -3, 38, -9,
- -19, -19, 39, 18, -1, -20, 25, -29, -36, -42, 26, 17, 12, -14, 43, -3,
- -15, -29, 35, 19, 6, -28, 27, -18, -36, -48, 16, 17, 15, -15, 39, 12,
- -13, -29, 24, 24, 9, -25, 19, -1, -39, -50, 1, 18, 11, -11, 25, 26,
- -14, -26, 12, 32, 10, -17, 6, 17, -33, -48, -14, 20, 6, -7, 11, 36,
- -9, -26, -1, 34, 11, -9, -4, 25, -25, -49, -26, 19, 4, -4, 5, 41,
- 3, -21, -8, 31, 12, -7, -11, 23, -13, -47, -37, 13, 6, -3, 1, 40,
- 14, -17, -14, 26, 16, -2, -12, 20, -3, -40, -44, 2, 6, -2, -4, 35,
- 24, -9, -19, 19, 17, 2, -13, 16, 5, -29, -48, -7, 4, 3, -7, 28,
- 28, 2, -21, 13, 14, 9, -14, 11, 9, -15, -49, -17, -3, 6, -11, 20,
- 30, 14, -23, 7, 12, 14, -11, 6, 10, -4, -46, -24, -10, 6, -8, 11,
- 29, 24, -15, 0, 11, 14, -4, -2, 11, 3, -37, -36, -13, -3, -2, 2,
- 28, 27, -2, -10, 14, 9, 7, -8, 13, 3, -21, -42, -14, -14, 4, -6,
- 24, 24, 13, -16, 12, 3, 14, -8, 12, 4, -7, -44, -18, -20, 5, -6,
- 18, 22, 23, -13, 6, 2, 13, -4, 5, 5, 1, -36, -26, -20, -1, -1,
- 10, 23, 25, -3, -4, 5, 9, 5, -2, 8, 1, -24, -36, -18, -10, 4,
- 1, 24, 23, 11, -9, 8, 4, 12, -7, 9, 1, -12, -40, -19, -16, 4,
- -4, 21, 21, 16, -9, 6, 2, 13, -4, 6, 6, -4, -33, -24, -18, -2,
- -2, 10, 21, 18, 0, -3, 3, 8, 6, -1, 8, 0, -18, -31, -19, -10,
- 1, 0, 19, 20, 13, -5, 4, 5, 12, -4, 5, 2, -7, -34, -24, -17,
- 1, -4, 13, 20, 21, -3, 2, 5, 14, 0, 2, 4, 0, -26, -28, -20,
- -6, -4, 4, 18, 23, 6, -3, 5, 9, 7, -1, 6, 3, -14, -33, -22,
- -14, -1, -1, 16, 22, 17, -4, 4, 4, 10, -2, 4, 3, -4, -30, -25,
- -19, -2, -2, 11, 20, 23, 0, 0, 2, 10, 3, 1, 4, 1, -23, -30,
- -22, -8, -1, 4, 19, 23, 10, -3, 4, 6, 8, -2, 5, 2, -13, -33,
- -23, -15, 0, -1, 16, 21, 16, -3, 3, 4, 11, 0, 5, 6, -3, -27,
- -25, -19, -4, -2, 9, 19, 19, 2, -3, 2, 8, 6, -1, 8, 0, 0,
- 2, 33, 42, 58, 71, 79, 85, 88, 91, 94, 79, 95, 82, 106, 86, 105,
- 47, 16, -6, 13, 44, 31, -15, -38, -36, 20, 70, 41, 48, 58, 24, -57,
- -127, -119, -102, -126, -128, -111, -78, -82, -88, -87, -60, -66, -98, -104, -99, -97,
- -99, -104, -101, -88, -87, -91, -61, -27, -34, -54, -55, -45, -24, -10, -5, -4,
- 5, 34, 63, 101, 94, 78, 52, 51, 52, 74, 81, 77, 59, 46, 17, 7,
- 39, 53, 47, 42, 66, 83, 73, 52, 28, 22, 11, 8, 11, 0, -15, -23,
- -15, -14, -6, 16, 46, 62, 71, 76, 90, 102, 103, 103, 101, 100, 90, 75,
- 63, 67, 49, 37, 28, 12, 5, 6, 15, 15, 8, -7, -12, -4, -10, -28,
- -24, -17, -25, -50, -64, -81, -103, -116, -116, -113, -95, -72, -54, -41, -47, -65,
- -65, -50, -33, -24, -7, 11, 8, -4, -13, -28, -51, -75, -90, -91, -90, -90,
- -87, -88, -83, -84, -82, -81, -81, -76, -65, -71, -85, -84, -79, -83, -81, -77,
- -72, -70, -65, -66, -66, -65, -66, -68, -61, -56, -51, -36, -13, -3, -5, -8,
- -12, -12, 3, 16, 21, 31, 50, 69, 77, 82, 90, 102, 110, 114, 116, 117,
- 118, 119, 116, 112, 109, 105, 98, 99, 103, 102, 91, 73, 64, 63, 61, 57,
- 51, 40, 24, 35, 57, 75, 84, 79, 65, 37, 4, -26, -45, -57, -54, -46,
- -45, -54, -67, -67, -48, -16, 15, 35, 44, 45, 44, 45, 46, 38, 23, 2,
- -15, -34, -52, -60, -70, -77, -80, -79, -74, -77, -84, -86, -80, -72, -68, -72,
- -80, -87, -92, -96, -101, -104, -104, -101, -93, -90, -89, -86, -85, -84, -83, -82,
- -81, -79, -77, -76, -73, -71, -66, -62, -55, -39, -31, -27, -25, -31, -37, -46,
- -51, -53, -54, -48, -45, -38, -20, 3, 24, 35, 39, 32, 16, 5, 3, 0,
- -6, -13, -13, -11, -2, 14, 28, 40, 50, 53, 50, 55, 64, 74, 90, 105,
- 108, 112, 106, 104, 109, 112, 123, 127, 127, 127, 127, 127, 127, 118, 113, 107,
- 110, 114, 111, 104, 101, 101, 102, 103, 99, 99, 89, 73, 53, 35, 20, 0,
- -22, -43, -63, -77, -82, -76, -65, -48, -36, -29, -24, -25, -29, -37, -40, -49,
- -59, -67, -73, -76, -78, -79, -75, -73, -74, -75, -68, -52, -44, -30, -19, -9,
- -6, -9, -13, -24, -33, -35, -31, -30, -35, -40, -44, -45, -51, -53, -54, -50,
- -50, -47, -42, -50, -55, -54, -56, -56, -54, -54, -49, -48, -41, -32, -28, -18,
- -13, -5, 6, 18, 33, 49, 60, 71, 78, 88, 95, 97, 93, 88, 91, 93,
- 97, 98, 97, 94, 91, 85, 81, 72, 70, 66, 61, 60, 64, 66, 74, 83,
- 92, 102, 108, 109, 107, 102, 97, 95, 91, 87, 80, 74, 67, 62, 61, 58,
- 61, 61, 57, 53, 43, 35, 27, 25, 24, 20, 20, 22, 27, 34, 36, 32,
- 21, 8, -3, -10, -16, -18, -16, -16, -19, -15, -11, -11, -12, -20, -34, -45,
- -59, -72, -80, -89, -94, -95, -102, -111, -114, -111, -111, -108, -106, -104, -101, -98,
- -93, -90, -86, -86, -83, -82, -81, -79, -76, -73, -70, -72, -78, -81, -79, -79,
- -72, -60, -43, -31, -25, -27, -34, -37, -40, -42, -41, -39, -36, -34, -25, -12,
- -4, 5, 12, 16, 17, 15, 13, 6, -4, -7, -8, -6, -1, 4, 7, 9,
- 12, 16, 19, 19, 22, 28, 29, 28, 29, 30, 34, 40, 49, 57, 71, 78,
- 85, 92, 96, 95, 89, 85, 86, 93, 99, 104, 102, 100, 94, 85, 77, 73,
- 69, 66, 63, 60, 60, 59, 57, 52, 47, 41, 31, 18, 6, -3, -7, -11,
- -12, -14, -18, -22, -23, -22, -24, -30, -37, -41, -44, -50, -56, -64, -67, -65,
- -62, -58, -58, -58, -59, -61, -62, -66, -72, -78, -79, -77, -73, -68, -64, -61,
- -56, -53, -54, -52, -52, -57, -63, -69, -70, -68, -65, -62, -59, -57, -56, -58,
- -60, -61, -63, -64, -62, -61, -60, -58, -54, -49, -45, -42, -39, -36, -32, -28,
- -22, -13, -7, -3, 2, 13, 28, 41, 52, 64, 71, 73, 73, 70, 64, 61,
- 60, 64, 66, 65, 66, 64, 61, 60, 62, 65, 64, 66, 67, 67, 68, 66,
- 64, 66, 68, 73, 76, 74, 72, 66, 58, 52, 46, 42, 38, 38, 41, 47,
- 52, 52, 48, 45, 42, 40, 38, 34, 29, 27, 26, 28, 29, 28, 29, 30,
- 31, 28, 24, 21, 19, 17, 14, 10, 6, 3, -4, -9, -15, -19, -26, -33,
- -40, -49, -55, -60, -65, -70, -73, -72, -72, -71, -70, -71, -75, -78, -81, -83,
- -86, -86, -85, -84, -82, -80, -77, -72, -69, -66, -63, -61, -61, -61, -61, -61,
- -60, -58, -53, -48, -42, -36, -30, -28, -30, -32, -33, -32, -31, -28, -22, -18,
- -10, -5, 0, 3, 6, 11, 16, 19, 22, 24, 26, 27, 29, 34, 40, 46,
- 48, 48, 48, 45, 40, 36, 33, 31, 33, 35, 40, 48, 55, 62, 68, 73,
- 76, 78, 78, 77, 79, 82, 85, 87, 87, 87, 86, 86, 86, 83, 78, 71,
- 63, 55, 48, 44, 39, 36, 36, 36, 35, 32, 28, 24, 18, 13, 9, 6,
- 4, 1, -2, -5, -11, -17, -20, -21, -20, -21, -24, -28, -32, -34, -33, -33,
- -35, -37, -40, -43, -47, -52, -58, -63, -69, -74, -77, -80, -81, -82, -81, -80,
- -77, -74, -69, -62, -54, -48, -48, -51, -54, -57, -57, -57, -56, -55, -55, -56,
- -57, -56, -55, -54, -54, -54, -54, -52, -49, -45, -41, -38, -34, -31, -29, -27,
- -24, -20, -17, -11, -7, -3, 0, 5, 10, 16, 22, 27, 31, 34, 38, 42,
- 44, 45, 48, 50, 52, 57, 61, 64, 64, 65, 65, 63, 60, 57, 55, 55,
- 58, 61, 63, 65, 67, 69, 71, 74, 77, 79, 79, 77, 74, 71, 68, 66,
- 63, 60, 57, 55, 51, 46, 40, 36, 30, 25, 20, 17, 16, 17, 16, 14,
- 12, 10, 7, 3, -1, -5, -11, -15, -17, -18, -18, -19, -21, -25, -29, -32,
- -33, -33, -36, -39, -43, -46, -50, -53, -56, -58, -59, -60, -61, -62, -63, -65,
- -66, -67, -68, -70, -72, -72, -70, -67, -63, -61, -60, -60, -58, -56, -54, -53,
- -52, -52, -52, -51, -50, -49, -47, -45, -43, -40, -37, -35, -34, -32, -29, -25,
- -21, -18, -14, -9, -4, 0, 4, 7, 11, 15, 18, 21, 25, 28, 33, 37,
- 41, 44, 46, 47, 47, 46, 46, 45, 43, 42, 42, 43, 46, 48, 49, 50,
- 52, 55, 59, 62, 65, 66, 67, 68, 69, 69, 70, 72, 74, 74, 73, 72,
- 71, 69, 65, 61, 57, 53, 50, 46, 43, 38, 35, 32, 28, 23, 19, 17,
- 17, 15, 13, 11, 9, 5, 1, -3, -6, -9, -12, -14, -17, -19, -23, -27,
- -31, -35, -38, -40, -43, -46, -48, -52, -55, -57, -61, -64, -66, -67, -68, -69,
- -70, -70, -70, -69, -69, -70, -71, -70, -66, -62, -59, -55, -52, -50, -46, -43,
- -41, -38, -36, -35, -35, -34, -33, -33, -33, -33, -31, -30, -28, -26, -25, -24,
- -21, -20, -20, -19, -19, -18, -17, -16, -15, -13, -11, -8, -3, 2, 9, 15,
- 21, 27, 33, 38, 41, 45, 48, 51, 53, 55, 56, 56, 56, 56, 56, 56,
- 56, 55, 57, 58, 60, 61, 62, 62, 64, 66, 68, 69, 71, 72, 73, 74,
- 72, 70, 67, 63, 60, 57, 54, 50, 46, 41, 36, 31, 27, 23, 19, 16,
- 14, 12, 11, 9, 8, 5, 2, -1, -4, -8, -10, -15, -18, -19, -20, -22,
- -22, -23, -23, -24, -26, -29, -31, -33, -35, -36, -37, -38, -41, -44, -46, -48,
- -50, -52, -54, -56, -59, -61, -63, -63, -64, -65, -64, -63, -62, -61, -60, -59,
- -58, -57, -58, -57, -57, -55, -53, -50, -49, -47, -46, -43, -40, -37, -33, -31,
- -28, -26, -23, -20, -16, -14, -12, -9, -5, -2, 1, 5, 9, 13, 17, 21,
- 24, 26, 29, 32, 35, 37, 37, 38, 39, 41, 43, 44, 45, 46, 48, 50,
- 51, 53, 52, 52, 50, 48, 47, 46, 46, 46, 46, 47, 48, 49, 51, 54,
- 56, 58, 60, 61, 62, 62, 62, 61, 59, 57, 55, 54, 53, 52, 51, 49,
- 46, 41, 36, 31, 27, 22, 18, 14, 11, 9, 6, 3, 0, -2, -5, -8,
- -11, -16, -20, -25, -28, -31, -34, -37, -39, -41, -41, -42, -42, -42, -43, -45,
- -46, -47, -49, -50, -52, -54, -56, -57, -58, -60, -61, -63, -64, -64, -64, -63,
- -63, -61, -59, -58, -57, -55, -54, -53, -52, -52, -51, -50, -49, -47, -46, -45,
- -44, -42, -40, -38, -35, -32, -30, -28, -25, -22, -19, -17, -15, -12, -9, -5,
- -1, 3, 7, 11, 15, 19, 23, 25, 27, 30, 34, 36, 37, 38, 39, 40,
- 42, 44, 45, 46, 47, 49, 50, 52, 53, 52, 51, 49, 47, 47, 46, 46,
- 46, 47, 47, 48, 50, 52, 55, 57, 59, 61, 62, 62, 62, 61, 60, 58,
- 56, 54, 54, 53, 51, 50, 47, 44, 39, 34, 29, 25, 20, 16, 13, 10,
- 7, 4, 2, -1, -3, -6, -9, -14, -18, -22, -26, -30, -33, -35, -38, -40,
- -41, -41, -42, -42, -43, -44, -46, -47, -48, -49, -51, -53, -55, -56, -57, -59,
- -60, -62, -63, -64, -64, -63, -63, -62, -60, -59, -57, -56, -55, -53, -52, -52,
- -51, -51, -50, -48, -46, -45, -44, -43, -41, -39, -36, -34, -31, -29, -26, -24,
- -21, -16, -1, -2, -1, -3, 1, -2, -2, -4, 2, 6, 2, -2, -2, 0,
- 7, 8, 4, -2, -2, 6, 5, 6, 0, -2, 5, 12, 10, 0, -5, -3,
- 5, 10, 9, -7, -8, -7, 5, 8, 3, -9, -13, -5, 3, 5, -5, -9,
- -4, 0, 6, 0, -4, -11, -7, 3, 4, 0, -5, 0, -1, 5, 1, 4,
- -6, -5, -3, 12, 9, -2, -10, 4, 11, 8, -4, -5, -9, -6, 1, 19,
- 13, -2, -22, 4, 9, 6, -26, -4, 3, 12, -9, 0, 2, 0, -15, 4,
- 8, -8, -20, 0, 15, 8, -13, -2, -4, -4, -2, 12, 3, -14, -18, 1,
- 21, 13, -9, -25, -8, 17, 15, 5, -14, -17, 5, 19, 13, -15, -17, -3,
- 10, 20, 10, -27, -19, 5, 11, 12, 3, -13, -17, -1, 6, -3, -2, 1,
- -1, -11, -17, 7, 7, -7, -7, -13, 9, 0, -5, 9, -5, -9, 6, 5,
- -2, -16, -5, 15, 17, -10, -20, 1, 11, 14, -1, 1, 10, -11, -8, -1,
- 18, 13, -2, -12, 1, -16, -2, 34, 27, -28, -42, -3, 42, 26, -14, -39,
- -19, 7, 26, 25, -16, -55, -26, 32, 57, 4, -69, -48, 6, 75, 29, -51,
- -67, -32, 51, 56, 7, -57, -75, 14, 63, 43, -29, -82, -27, 31, 56, 28,
- -43, -81, -31, 59, 85, 1, -100, -59, 8, 102, 41, -42, -92, -52, 72, 79,
- 29, -103, -85, -1, 117, 49, -54, -113, 7, 24, 94, -28, -39, -84, 39, 28,
- 61, -44, -28, -67, 61, 23, 35, -40, -23, -37, 6, 38, 69, -42, -61, -53,
- 58, 86, 2, -93, -24, 19, 72, 17, -19, -87, 45, 10, 64, -13, -45, -57,
- 38, 48, 36, -51, -35, -37, 46, 26, 37, -73, -28, -12, 44, 22, 27, -84,
- -22, 6, 70, 17, -24, -82, -7, 26, 79, 9, -63, -78, 6, 90, 68, -55,
- -118, -3, 92, 62, -10, -73, -50, 14, 110, 15, -5, -118, 5, 69, 53, 22,
- -81, -45, 29, 47, 80, -69, -28, -52, 58, 66, -1, -25, -59, -22, 107, 2,
- 43, -108, -13, 20, 59, 56, -58, -66, -7, 34, 114, -42, -63, -50, 42, 69,
- 44, -63, -37, -50, 114, 27, 18, -49, -81, 20, 74, 51, -14, -102, -4, 40,
- 70, 38, -64, -73, 11, 60, 76, -41, -30, -78, 42, 46, 68, -63, -48, -56,
- 89, 43, 28, -100, -53, 41, 60, 11, -6, -76, -16, 44, 52, 9, -67, -48,
- 10, 69, 30, -1, -84, -4, 36, 72, -23, -22, -27, -33, 55, 74, -11, -86,
- -1, 27, 36, 31, -7, -101, 49, 5, 66, -7, -46, -39, 9, 64, 44, -63,
- -33, -22, 55, 23, 43, -79, -24, 5, 29, 54, -14, -59, -53, 63, 32, 20,
- -34, -32, -36, 93, -2, 20, -35, -38, 18, 51, 61, -94, 15, -14, 17, 69,
- 5, -87, 16, 28, 34, 1, 34, -57, -53, 118, -22, 34, -10, -71, 23, 70,
- 25, -29, -7, -19, -3, 117, -33, -12, -21, -19, 43, 84, -38, -57, 33, 0,
- 32, 41, -7, -103, 85, 2, 2, 58, -14, -103, 103, 7, -17, 34, -32, -59,
- 71, 51, -78, 76, -65, -30, 63, 48, -66, 9, -11, -28, 52, 50, -72, -37,
- 73, -61, 75, 7, -51, -44, 73, -3, -11, 40, -78, 7, 63, -15, -16, 30,
- -53, 12, 38, 12, -42, 39, -63, 47, 23, 0, -23, -11, 8, -25, 60, -37,
- -15, -3, -9, 12, 27, -14, -40, 22, 12, 14, 15, -31, -14, 15, 23, -12,
- 14, -31, 19, 13, 32, -39, 27, -51, 43, 8, 0, 5, -26, 16, 4, 19,
- -24, 17, -18, 6, -2, 49, -67, 39, -1, -30, 46, -13, -16, -9, 21, -17,
- 27, 2, -34, 19, -3, 24, 8, -38, 13, -10, 22, 15, -34, 2, 4, -10,
- 18, 14, -15, -15, 26, -12, 28, -21, 0, -6, 0, 7, 0, -15, 6, -2,
- -18, 9, 8, -18, -15, 59, -94, 81, -40, -24, 14, -18, 25, -15, 4, -21,
- -9, 24, -20, 3, 3, -52, 56, -29, 4, 5, -51, 45, -50, 73, -75, 13,
- 17, -48, 38, -10, -16, 5, 4, -22, 3, 17, -27, -23, 42, -30, -5, 41,
- -53, 10, 23, -28, 1, 29, -47, 9, 13, -3, -18, 9, -13, -11, 18, 12,
- -53, 28, 1, -41, 41, 7, -61, 32, 0, -34, 16, 9, -74, 45, -23, -33,
- 22, 39, -104, 49, 23, -96, 83, 5, -46, 36, -4, -45, 54, -25, -26, 21,
- 2, -39, 51, -25, -25, 43, -22, -25, 30, -2, -32, 39, 14, -69, 42, 22,
- -78, 60, 23, -83, 33, 44, -74, 19, 69, -113, 43, 53, -88, 51, 17, -74,
- 42, 1, -38, 4, 39, -67, 12, 35, -39, -23, 73, -82, -5, 67, -71, -5,
- 42, -36, -48, 78, -64, -4, 40, -48, -7, 50, -80, 17, 31, -56, 9, 6,
- -18, -36, 43, -37, -29, 47, -47, -18, 33, -29, -27, 40, -30, -37, 51, -46,
- -25, 61, -66, 7, 28, -48, 30, -15, -8, -6, 17, -14, -9, 26, -23, 4,
- 9, -15, 12, -9, 16, -22, 7, 22, -51, 59, -29, -23, 54, -49, 6, 20,
- -19, -11, 17, -3, -30, 32, -27, -5, 16, -28, 4, 4, -27, 32, -46, 27,
- -18, -8, 11, -25, 18, -6, -17, 10, 1, -18, 24, -33, 10, 8, -12, -10,
- 21, -19, 0, 8, -18, 14, 11, -44, 39, -22, -4, -6, 11, -15, -13, 17,
- -17, -6, 13, -22, -1, 7, -5, -8, 0, 4, -24, 29, -23, 0, 20, -25,
- -8, 30, -34, 31, -29, 11, -9, 21, -15, -1, 10, -9, -11, 32, -23, -2,
- -14, 27, -19, 10, -4, -23, 14, 13, -45, 48, -44, 11, -4, -7, -3, 4,
- -2, -34, -8, 37, -41, 20, -24, -4, -10, 2, 4, 12, -28, -30, 9, 32,
- -16, 6, -46, -23, 60, 0, -22, -3, -23, -15, 48, 12, -34, -17, -18, 10,
- 46, -1, -56, -8, 12, 9, 18, 13, -72, -3, 26, 9, 28, -14, -89, 15,
- 67, -18, 1, -19, -52, 45, 26, -8, -5, -25, -25, 36, 38, -13, -36, -18,
- -6, 55, 23, -51, -14, 4, 6, 25, 24, -41, -44, 38, 19, 10, 10, -59,
- -14, 42, 1, 6, -8, -43, -1, 43, 10, -30, -10, -36, 18, 35, -20, -14,
- -11, -19, 9, 20, -5, -22, -9, -6, 13, 26, -30, -23, 4, 1, 20, 9,
- -20, -22, 3, -1, 17, 28, -26, -25, 16, -2, -4, 12, -10, -16, 24, -2,
- -18, 17, -27, -1, 36, -6, -7, -4, -26, 6, 29, -3, -17, -6, -4, 18,
- 18, -26, -10, -4, 6, 30, -1, -6, -24, 0, 24, 12, 2, -16, -25, 13,
- 32, -3, -4, -3, -24, 15, 16, -7, 8, -20, -13, 36, 9, -24, -11, -10,
- 10, 20, -1, -13, -10, -9, 20, 17, -12, -9, -15, 9, 20, -11, -14, -6,
- 5, 10, 6, 5, -7, -11, 7, 19, 1, 3, -11, -10, 24, 14, -16, 2,
- -9, 11, 14, 7, -1, -11, -4, 15, 24, 3, -24, -4, 4, 15, 13, -3,
- -15, 0, 15, 8, 2, 0, -19, 16, 12, -1, 7, -13, -2, 18, 3, -3,
- 5, -9, -10, 12, 9, -2, 8, -9, 4, 9, 6, 1, -8, 10, 4, -2,
- 11, -14, 3, 5, 1, 9, 4, -15, 0, 10, 1, 5, -4, -10, 3, 7,
- -1, 8, -13, 1, 4, 10, 6, -9, -3, 1, 6, 14, -3, -4, 4, -10,
- 10, 13, -1, -4, 5, -3, 10, 13, -13, 4, 7, 1, 8, -1, 1, 4,
- 5, 4, 11, -5, -2, 1, 8, 6, 1, 3, -1, -5, 11, 3, -3, 4,
- -5, -1, 17, -4, -2, 6, -10, 10, 10, -4, 2, 3, -10, 10, 5, -2,
- -2, -1, 4, 3, -1, -2, -4, 1, 6, -4, 6, -4, -10, 8, 2, -4,
- 6, -4, -4, 12, -2, 2, 6, -9, 3, 2, 0, 7, -5, -3, 3, 2,
- 4, -4, -2, 7, 3, 5, 9, -3, 1, 12, -3, 7, 6, -9, 4, 9,
- -4, 12, 1, -7, 9, 2, 1, 10, -3, 1, 0, 0, 8, 0, -1, 5,
- -2, 8, 1, -3, 10, 2, 0, 11, -4, -1, 6, -3, 2, 3, -5, 4,
- 0, -5, 5, -3, 1, 3, 0, 4, -3, -3, 4, -2, -2, 5, -2, -1,
- 6, -5, 2, 3, -4, 4, -2, -3, 11, -8, 0, 5, -1, 1, 0, -3,
- 4, 2, 2, 6, -2, 4, 5, -3, 4, 7, -4, 11, -1, 0, 3, 0,
- 3, 7, -2, 5, 1, 0, 6, 3, 2, 4, -1, 2, 6, 0, 3, 5,
- -4, 6, 0, 2, 7, -4, -1, 2, -2, 7, 1, -1, 1, -2, 2, 4,
- -5, 0, 4, -1, 2, -1, -2, 1, -2, 3, 2, -3, 3, -1, -4, 5,
- -2, -2, 3, 0, -1, 2, -5, 2, 1, -4, 0, 1, -3, 5, -2, 2,
- 2, -3, 1, 3, -2, 3, 1, -2, 4, 1, 2, 5, -2, 3, 1, 2,
- 5, 0, -1, 4, 0, 1, 4, 2, 4, 4, -2, 0, 2, 3, 5, 0,
- 0, 0, 1, 5, -2, -3, 4, 0, 1, 2, -2, -4, -4, -5, -6, -7,
- -8, -9, -10, -11, -12, -13, -13, -14, -16, -18, -21, -25, -29, -34, -36, -38,
- -39, -40, -42, -44, -47, -50, -53, -56, -58, -59, -58, -55, -50, -44, -38, -31,
- -24, -18, -13, -9, -6, -3, 0, 3, 6, 9, 13, 17, 21, 27, 33, 42,
- 53, 63, 74, 83, 91, 98, 104, 108, 111, 113, 115, 118, 119, 121, 123, 125,
- 126, 127, 127, 127, 127, 126, 126, 126, 126, 127, 127, 127, 127, 127, 127, 127,
- 126, 125, 123, 121, 118, 114, 111, 107, 104, 101, 100, 99, 98, 98, 98, 98,
- 98, 99, 98, 98, 97, 95, 92, 88, 81, 73, 63, 54, 46, 39, 33, 29,
- 27, 25, 24, 22, 20, 18, 14, 10, 5, 0, -5, -8, -8, -7, -3, 2,
- 8, 14, 19, 23, 26, 28, 29, 30, 31, 32, 32, 31, 30, 28, 24, 20,
- 14, 9, 4, -1, -4, -7, -9, -10, -12, -13, -15, -17, -19, -22, -24, -25,
- -25, -23, -21, -19, -17, -15, -15, -14, -15, -15, -16, -17, -17, -17, -16, -16,
- -16, -17, -19, -22, -25, -30, -35, -39, -44, -47, -50, -53, -56, -58, -61, -63,
- -64, -65, -65, -63, -60, -55, -49, -43, -38, -34, -32, -31, -31, -32, -33, -35,
- -36, -37, -37, -36, -35, -34, -34, -34, -36, -39, -43, -49, -55, -61, -67, -72,
- -77, -81, -85, -88, -90, -92, -94, -94, -95, -94, -94, -94, -94, -95, -96, -98,
- -100, -102, -104, -105, -107, -108, -108, -109, -110, -110, -110, -109, -109, -109, -108, -108,
- -109, -109, -109, -109, -108, -108, -107, -106, -106, -105, -105, -105, -105, -105, -105, -104,
- -103, -101, -98, -93, -88, -82, -76, -70, -64, -58, -52, -47, -42, -38, -34, -31,
- -29, -27, -25, -22, -18, -13, -7, -1, 6, 13, 20, 26, 32, 37, 41, 45,
- 48, 51, 55, 58, 63, 68, 73, 77, 82, 85, 89, 91, 94, 96, 97, 98,
- 99, 99, 99, 100, 100, 100, 101, 101, 101, 101, 101, 101, 99, 97, 95, 93,
- 90, 87, 84, 81, 77, 73, 67, 60, 51, 40, 29, 17, 6, -5, -14, -23,
- -31, -38, -45, -52, -58, -65, -70, -75, -80, -84, -87, -90, -92, -94, -95, -96,
- -97, -98, -100, -101, -102, -102, -103, -103, -104, -104, -103, -102, -100, -97, -93, -89,
- -86, -82, -79, -77, -75, -72, -70, -67, -63, -59, -53, -47, -40, -33, -26, -20,
- -14, -9, -6, -3, 0, 3, 6, 9, 13, 17, 21, 26, 31, 37, 44, 51,
- 58, 64, 70, 75, 79, 83, 86, 88, 90, 92, 93, 95, 96, 97, 98, 100,
- 100, 101, 102, 102, 102, 102, 102, 102, 102, 102, 102, 103, 103, 103, 102, 102,
- 102, 101, 100, 98, 96, 94, 92, 90, 89, 88, 88, 87, 87, 87, 87, 87,
- 86, 85, 84, 82, 79, 76, 72, 67, 61, 55, 49, 43, 39, 35, 32, 30,
- 29, 27, 25, 24, 21, 18, 15, 12, 8, 5, 3, 3, 4, 6, 9, 12,
- 15, 18, 21, 23, 25, 27, 28, 30, 31, 31, 31, 30, 28, 25, 22, 18,
- 14, 10, 7, 5, 3, 1, 0, -2, -4, -6, -9, -11, -14, -16, -17, -17,
- -16, -14, -12, -11, -9, -9, -9, -10, -11, -12, -13, -14, -15, -15, -16, -16,
- -17, -19, -22, -26, -30, -34, -38, -42, -45, -48, -50, -52, -53, -54, -55, -56,
- -56, -55, -53, -50, -46, -42, -38, -35, -32, -31, -30, -31, -31, -33, -34, -35,
- -36, -36, -36, -35, -35, -35, -36, -38, -41, -45, -49, -54, -59, -64, -68, -73,
- -76, -80, -83, -86, -88, -89, -90, -91, -91, -91, -92, -92, -93, -95, -96, -98,
- -100, -101, -102, -103, -104, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105,
- -105, -105, -104, -104, -103, -102, -102, -101, -100, -100, -100, -99, -99, -99, -98, -96,
- -94, -91, -86, -82, -76, -71, -65, -59, -53, -48, -42, -37, -32, -28, -25, -22,
- -19, -16, -13, -8, -3, 3, 9, 16, 22, 28, 35, 40, 45, 49, 53, 56,
- 60, 63, 67, 71, 76, 80, 85, 88, 92, 94, 97, 99, 100, 102, 103, 103,
- 104, 104, 104, 104, 105, 105, 105, 105, 105, 104, 103, 101, 99, 97, 94, 91,
- 87, 84, 80, 76, 71, 65, 57, 48, 39, 28, 18, 8, -2, -11, -19, -27,
- -34, -41, -47, -54, -60, -65, -70, -75, -79, -82, -85, -87, -89, -91, -92, -94,
- -95, -96, -97, -98, -99, -100, -100, -100, -100, -100, -98, -96, -94, -90, -87, -84,
- -81, -78, -76, -73, -71, -68, -65, -61, -57, -52, -46, -40, -33, -27, -21, -15,
- -11, -7, -4, 0, 3, 7, 11, 15, 20, 24, 29, 35, 41, 48, 54, 61,
- 67, 72, 77, 81, 85, 88, 90, 92, 94, 95, 97, 98, 99, 101, 102, 103,
- 104, 104, 104, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 104,
- 104, 103, 101, 99, 98, 96, 95, 93, 93, 92, 92, 91, 91, 90, 90, 88,
- 87, 86, 84, 81, 78, 74, 69, 64, 59, 54, 49, 45, 42, 39, 37, 35,
- 33, 31, 29, 27, 24, 21, 18, 15, 13, 11, 11, 12, 13, 15, 17, 20,
- 22, 24, 25, 27, 28, 29, 30, 31, 31, 31, 30, 28, 26, 23, 20, 17,
- 14, 11, 9, 8, 6, 5, 3, 1, -1, -4, -6, -8, -10, -11, -11, -11,
- -10, -9, -8, -8, -8, -9, -10, -11, -13, -14, -15, -16, -17, -17, -18, -20,
- -22, -25, -28, -31, -35, -38, -41, -44, -46, -47, -49, -50, -51, -52, -52, -52,
- -51, -49, -47, -44, -40, -38, -35, -33, -33, -32, -33, -33, -34, -35, -36, -37,
- -38, -38, -38, -38, -39, -40, -42, -45, -49, -53, -57, -61, -65, -69, -73, -76,
- -79, -82, -85, -87, -88, -89, -90, -91, -91, -92, -93, -94, -95, -97, -98, -99,
- -100, -101, -102, -103, -103, -104, -104, -104, -104, -104, -104, -104, -104, -104, -103, -103,
- -103, -102, -102, -101, -100, -99, -99, -98, -97, -97, -96, -96, -95, -94, -92, -89,
- -86, -82, -77, -72, -67, -61, -56, -50, -45, -39, -34, -29, -25, -21, -18, -14,
- -11, -5, 4, 8, 14, 19, 25, 31, 37, 42, 47, 52, 57, 61, 65, 69,
- 72, 76, 79, 83, 86, 89, 92, 95, 97, 99, 101, 102, 104, 104, 105, 106,
- 106, 106, 106, 106, 106, 105, 104, 104, 103, 101, 99, 97, 95, 92, 89, 85,
- 81, 77, 73, 68, 62, 57, 50, 43, 35, 28, 19, 12, 4, -4, -11, -18,
- -25, -32, -38, -44, -50, -55, -61, -65, -69, -73, -77, -80, -82, -85, -87, -89,
- -91, -92, -93, -95, -95, -96, -97, -97, -97, -96, -96, -95, -93, -92, -90, -88,
- -86, -84, -82, -79, -77, -74, -71, -68, -64, -60, -55, -51, -46, -41, -36, -31,
- -26, -21, -16, -11, -7, -2, 3, 8, 14, 19, 25, 30, 36, 42, 47, 53,
- 58, 63, 68, 72, 76, 79, 82, 85, 87, 89, 91, 93, 95, 96, 98, 99,
- 101, 102, 103, 103, 104, 105, 105, 105, 106, 106, 106, 106, 106, 106, 106, 105,
- 105, 105, 104, 103, 103, 102, 101, 100, 99, 99, 98, 97, 96, 95, 93, 92,
- 91, 89, 87, 85, 82, 79, 76, 73, 70, 67, 63, 60, 58, 55, 53, 50,
- 48, 46, 44, 41, 39, 37, 34, 32, 31, 29, 28, 28, 27, 28, 28, 28,
- 28, 29, 29, 29, 29, 30, 30, 30, 29, 29, 28, 27, 26, 25, 23, 22,
- 20, 19, 17, 16, 15, 13, 12, 10, 8, 6, 4, 2, 1, -1, -2, -4,
- -5, -6, -7, -9, -10, -12, -13, -15, -17, -19, -21, -22, -24, -26, -27, -29,
- -31, -32, -34, -36, -38, -40, -42, -43, -45, -46, -47, -47, -48, -48, -49, -49,
- -48, -48, -47, -46, -45, -44, -44, -43, -43, -43, -44, -44, -45, -46, -47, -48,
- -49, -50, -51, -52, -53, -55, -57, -59, -61, -64, -67, -70, -72, -75, -78, -80,
- -82, -84, -86, -88, -90, -91, -92, -94, -95, -96, -97, -98, -98, -99, -100, -101,
- -101, -101, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -101, -101, -100, -100,
- -99, -98, -97, -96, -95, -94, -93, -92, -91, -89, -88, -87, -85, -83, -81, -78,
- -75, -71, -67, -63, -58, -54, -49, -44, -39, -33, -28, -23, -18, -13, -8, -3,
- 2, 7, 13, 18, 23, 29, 35, 40, 45, 51, 55, 60, 64, 68, 71, 75,
- 78, 82, 85, 88, 91, 93, 96, 98, 100, 101, 103, 104, 105, 105, 106, 106,
- 106, 106, 105, 105, 104, 104, 103, 101, 100, 98, 95, 93, 90, 86, 83, 79,
- 75, 70, 65, 60, 54, 47, 40, 33, 25, 18, 10, 2, -5, -12, -19, -26,
- -32, -38, -44, -50, -55, -60, -65, -69, -73, -76, -79, -82, -84, -87, -89, -90,
- -92, -93, -94, -95, -96, -96, -96, -96, -96, -95, -94, -93, -91, -90, -88, -86,
- -84, -81, -79, -76, -74, -70, -67, -63, -59, -54, -49, -44, -39, -34, -29, -24,
- -19, -14, -10, -5, -2, -1, 3, -2, 1, -3, 4, -2, 0, 0, 8, 0,
- 10, -9, -7, -128, -72, 13, -44, -13, -18, 4, -4, 12, 3, 31, 4, 66,
- 74, 38, 38, 36, 30, 25, 22, 18, 13, 7, 5, 2, 1, -5, -7, -9,
- -9, -11, -14, -12, -14, -12, -16, -13, -16, -13, -14, -16, -11, -14, -10, -13,
- -11, -13, -8, -8, -6, -6, -5, 0, -6, -3, -3, 3, -4, 6, -13, 17,
- -5, -5, 15, -1, -23, 6, 23, 28, 35, 13, 41, -3, 24, 25, -4, 6,
- 30, 4, 18, 10, -32, -64, -120, -64, -91, -76, -33, -45, -58, 2, 1, -19,
- -14, 18, 48, 50, 59, 51, 53, 47, 46, 41, 37, 35, 26, 28, 19, 21,
- 10, 13, 9, 3, 5, -4, 2, -5, -3, -8, -5, -8, -8, -10, -9, -10,
- -10, -12, -7, -17, -8, -11, -14, -5, -15, -5, -4, -10, -13, 11, -22, 3,
- -3, -4, -5, -11, 13, 2, -16, -9, -5, -12, 27, 15, 17, 21, 20, 20,
- 8, 14, 13, 0, 10, 35, 10, -1, -12, -52, -89, -78, -58, -85, -74, -51,
- -25, -25, -28, -30, -14, 12, 29, 44, 44, 51, 46, 50, 49, 43, 38, 36,
- 32, 29, 23, 19, 17, 14, 10, 6, 6, 2, 4, -8, 3, -7, -3, -6,
- -7, -11, -4, -12, -7, -6, -20, 1, -15, -14, -8, -7, -10, -10, -10, 2,
- -14, -12, 7, -10, -8, -5, -6, 1, 6, -2, -12, -19, -3, 3, 2, 19,
- 19, 14, 19, 24, 13, 5, 12, 12, 13, 21, 29, 5, -18, -43, -48, -64,
- -82, -82, -71, -44, -37, -37, -40, -33, -23, 5, 20, 33, 38, 45, 48, 51,
- 46, 44, 41, 38, 36, 27, 26, 24, 19, 13, 16, 5, 11, 4, -1, 3,
- -4, -3, 1, -9, -7, -2, -9, -6, -13, -4, -6, -17, -8, -6, -15, -10,
- -5, -10, -8, -10, -5, -7, -5, -2, -14, -10, 3, 5, -4, -3, -10, -17,
- -10, 3, 4, 5, 18, 18, 18, 16, 16, 10, 5, 11, 23, 26, 22, 7,
- -9, -16, -37, -62, -80, -76, -65, -46, -43, -43, -51, -41, -24, -4, 11, 24,
- 32, 41, 47, 43, 49, 45, 41, 40, 33, 31, 31, 20, 23, 18, 11, 16,
- 9, 5, 3, 2, 5, -2, -7, 2, -4, -10, -3, -5, -8, -10, -7, -8,
- -14, -10, -8, -11, -9, -6, -14, -10, -2, -3, -12, -10, -7, -9, 0, 6,
- -1, -11, -12, -11, -10, -7, 4, 7, 12, 17, 20, 18, 13, 6, 8, 19,
- 22, 24, 17, 14, 5, -8, -29, -54, -77, -71, -55, -50, -44, -54, -57, -39,
- -32, -15, 3, 15, 31, 34, 39, 47, 45, 44, 44, 37, 37, 33, 28, 27,
- 18, 20, 21, 10, 7, 10, 7, 1, 2, 2, 0, -5, 0, -2, -7, -3,
- -5, -8, -8, -5, -13, -13, -5, -6, -14, -11, -8, -8, -5, -5, -9, -17,
- -10, -2, 0, -2, -1, -9, -12, -14, -12, -6, -1, 3, 11, 19, 19, 14,
- 7, 9, 13, 17, 23, 22, 19, 21, 12, 2, -21, -55, -65, -59, -52, -47,
- -56, -56, -50, -53, -38, -22, -7, 10, 18, 29, 36, 40, 45, 43, 38, 41,
- 40, 32, 27, 26, 26, 19, 17, 17, 12, 9, 9, 6, 2, 4, 4, -1,
- -2, 2, -3, -3, 0, -2, -8, -9, -7, -7, -7, -6, -8, -12, -6, -4,
- -7, -12, -13, -10, -5, -2, -2, -3, -8, -12, -15, -16, -14, -13, -7, 2,
- 8, 11, 8, 4, 5, 8, 13, 20, 22, 23, 24, 23, 19, 6, -13, -23,
- -29, -32, -37, -42, -46, -53, -57, -53, -49, -39, -25, -12, -1, 10, 21, 28,
- 32, 35, 36, 34, 34, 32, 28, 25, 24, 21, 18, 19, 16, 10, 7, 8,
- 9, 8, 6, 5, 2, 3, 6, 7, 5, 2, -2, -4, -3, -1, -3, -4,
- -3, -1, -3, -8, -13, -14, -11, -4, -1, -2, -4, -6, -11, -16, -19, -21,
- -21, -17, -9, -3, 0, 0, -3, -5, -2, 4, 11, 18, 23, 25, 26, 24,
- 17, 10, 5, -1, -7, -12, -20, -29, -37, -44, -51, -55, -54, -47, -39, -28,
- -16, -4, 9, 18, 23, 27, 31, 31, 30, 30, 28, 23, 20, 22, 23, 20,
- 14, 10, 9, 9, 10, 9, 6, 4, 4, 6, 9, 10, 7, 2, 0, 1,
- -1, -2, -2, -1, 1, 2, -2, -10, -14, -11, -8, -5, -2, -1, -3, -6,
- -9, -14, -20, -23, -23, -18, -11, -5, -3, -4, -6, -8, -4, 2, 7, 14,
- 21, 25, 25, 23, 19, 13, 8, 4, -1, -9, -15, -23, -31, -39, -48, -53,
- -51, -48, -44, -34, -20, -8, 3, 12, 20, 24, 27, 30, 31, 29, 24, 22,
- 22, 23, 22, 18, 13, 10, 10, 11, 11, 9, 5, 3, 5, 10, 11, 9,
- 7, 5, 4, 2, 0, -3, -1, 3, 5, 2, -3, -8, -11, -10, -7, -5,
- -3, -2, -2, -4, -7, -14, -20, -24, -24, -19, -12, -6, -6, -8, -8, -8,
- -7, -2, 5, 12, 19, 23, 24, 22, 20, 16, 12, 7, 1, -5, -10, -17,
- -27, -36, -42, -47, -52, -51, -45, -36, -26, -12, 0, 9, 15, 21, 27, 30,
- 29, 26, 23, 22, 23, 23, 21, 17, 12, 9, 10, 12, 10, 6, 3, 4,
- 7, 10, 11, 9, 8, 9, 7, 2, -1, 0, 2, 6, 6, 3, -2, -7,
- -9, -8, -6, -4, -3, -1, -1, -2, -6, -13, -21, -26, -24, -18, -13, -10,
- -9, -10, -11, -11, -10, -5, 3, 10, 17, 21, 22, 22, 21, 19, 14, 8,
- 5, 1, -7, -14, -21, -29, -38, -45, -49, -50, -48, -40, -28, -16, -6, 3,
- 11, 19, 26, 27, 26, 24, 22, 22, 24, 24, 20, 14, 11, 11, 12, 11,
- 8, 4, 3, 6, 8, 9, 9, 10, 11, 10, 6, 2, 0, 2, 5, 8,
- 7, 3, -2, -5, -6, -7, -6, -4, -3, -1, 1, 1, -5, -13, -21, -24,
- -23, -18, -14, -12, -11, -12, -13, -14, -13, -8, 0, 8, 14, 17, 21, 22,
- 21, 18, 15, 12, 8, 2, -3, -9, -16, -24, -32, -40, -47, -51, -49, -41,
- -30, -21, -12, -1, 9, 17, 23, 25, 24, 21, 21, 24, 24, 22, 17, 12,
- 11, 13, 12, 8, 4, 3, 4, 6, 7, 7, 9, 11, 12, 10, 6, 3,
- 3, 6, 9, 10, 8, 5, 1, -2, -3, -3, -2, -1, 1, 3, 3, 1,
- -5, -12, -18, -20, -20, -18, -16, -16, -16, -17, -19, -20, -17, -11, -5, 1,
- 8, 13, 17, 18, 18, 17, 16, 14, 11, 7, 2, -3, -8, -14, -22, -34,
- -43, -46, -42, -35, -28, -20, -11, -2, 7, 15, 19, 19, 19, 19, 20, 20,
- 17, 14, 11, 10, 9, 7, 1, -4, -6, -4, 0, 2, 4, 6, 7, 8,
- 9, 8, 7, 7, 10, 13, 15, 15, 13, 9, 6, 3, 2, 4, 7, 9,
- 11, 11, 7, 1, -5, -10, -13, -14, -14, -14, -16, -19, -23, -26, -28, -27,
- -23, -18, -13, -7, -1, 6, 11, 14, 15, 14, 14, 15, 15, 12, 7, 2,
- -1, -4, -11, -22, -34, -41, -40, -34, -26, -19, -12, -4, 4, 10, 14, 17,
- 17, 18, 19, 18, 15, 12, 10, 9, 8, 6, 0, -6, -11, -10, -6, -1,
- 3, 5, 6, 6, 6, 7, 7, 8, 10, 13, 16, 18, 17, 13, 9, 5,
- 3, 4, 7, 11, 13, 14, 11, 5, -2, -7, -11, -12, -12, -13, -14, -17,
- -22, -26, -28, -29, -27, -22, -17, -11, -5, 1, 7, 12, 14, 14, 13, 14,
- 15, 14, 11, 5, 0, -2, -6, -15, -27, -37, -42, -38, -31, -24, -17, -9,
- -1, 6, 12, 15, 17, 18, 19, 19, 17, 13, 11, 9, 9, 8, 4, -2,
- -8, -11, -9, -4, 1, 4, 5, 6, 6, 6, 7, 7, 9, 11, 14, 17,
- 18, 16, 12, 8, 4, 3, 5, 9, 12, 14, 13, 9, 2, -4, -9, -12,
- -13, -12, -13, -15, -19, -23, -27, -29, -28, -25, -20, -15, -9, -3, 3, 9,
- 13, 15, 14, 13, 15, 15, 13, 9, 3, -1, -3, -9, -19, -31, -40, -41,
- -36, -28, -21, -14, -6, 2, 9, 13, 16, 17, 18, 19, 18, 16, 12, 10,
- 9, 9, 7, 2, -4, -10, -11, -8, -2, 2, 5, 5, 6, 6, 7, 7,
- 8, 9, 12, 16, 18, 17, 14, 10, 6, 4, 4, 6, 10, 13, 14, 12,
- 7, 0, -6, -10, -12, -13, -13, -14, -16, -21, -25, -28, -29, -28, -24, -18,
- -13, -7, -1, 6, 11, 14, 15, 13, 14, 15, 15, 12, 7, 2, -1, -5,
- -12, -23, -35, -41, -40, -34, -26, -19, -12, -3, 4, 10, 14, 17, 18, 18,
- 19, 18, 14, 11, 9, 9, 8, 6, 0, -7, -11, -10, -6, 0, 2, -1,
- -2, -9, -24, 4, -3, 3, -3, 10, 7, 4, 13, -4, 1, 3, 3, 0,
- 2, 8, -9, -9, 2, 1, -1, 7, 17, 21, 37, 25, 13, 14, -2, 15,
- 20, 5, 0, -3, -7, -27, -14, -18, -19, -29, -20, -4, -18, -32, -30, -30,
- -29, -32, -22, -26, -19, -19, -1, -6, 4, 7, 5, 2, 0, -8, -16, -12,
- -13, -17, -17, 19, 20, 24, 16, 8, -4, 8, 0, 13, 28, 33, 16, 11,
- 5, -3, -1, 4, 12, 12, 40, 20, 11, 4, 5, 8, -1, 2, 5, 5,
- 22, 13, 21, 8, 9, 18, 20, 13, 20, 26, 11, 24, 17, 10, 27, 30,
- 22, 28, 30, 41, 47, 57, 36, 36, 20, -16, 4, 6, -19, -21, -41, -39,
- -33, -38, -41, -46, -42, -36, -18, -37, -65, -75, -77, -78, -62, -63, -62, -68,
- -63, -63, -44, -50, -30, -41, -43, -26, -34, -35, -36, -45, -49, -27, 1, -6,
- -4, -7, -20, -16, -20, -21, -13, 2, -6, -1, -12, 0, -1, 15, 19, 20,
- 26, 37, 40, 46, 37, 50, 35, 34, 41, 43, 51, 54, 55, 50, 56, 47,
- 59, 51, 51, 75, 67, 66, 71, 59, 60, 72, 75, 72, 80, 79, 82, 98,
- 99, 87, 93, 62, 49, 58, 41, 42, 28, 5, -6, -6, -18, -24, -23, -30,
- -25, -20, -38, -60, -75, -77, -80, -75, -71, -75, -70, -73, -69, -76, -60, -66,
- -71, -66, -57, -62, -61, -61, -87, -90, -69, -63, -46, -31, -35, -47, -42, -53,
- -63, -53, -45, -33, -36, -39, -37, -43, -39, -34, -30, -19, -9, 2, -9, -1,
- -3, 1, -3, 5, 7, 15, 24, 22, 23, 20, 32, 43, 33, 48, 63, 67,
- 70, 68, 52, 59, 73, 73, 77, 85, 73, 81, 103, 98, 116, 115, 87, 80,
- 76, 72, 69, 60, 37, 27, 29, 12, 19, 4, -12, 1, 3, -3, -31, -42,
- -57, -67, -67, -61, -61, -61, -48, -58, -51, -41, -46, -48, -40, -35, -33, -26,
- -36, -67, -68, -65, -59, -47, -28, -34, -37, -36, -52, -61, -61, -47, -34, -39,
- -39, -42, -42, -48, -36, -38, -37, -20, -19, -16, -16, -18, -20, -22, -26, -22,
- -16, -15, 1, -4, -6, 10, 12, 13, 22, 32, 41, 54, 52, 44, 54, 66,
- 61, 78, 81, 71, 87, 89, 99, 119, 107, 91, 77, 76, 69, 76, 68, 47,
- 49, 35, 33, 37, 22, 14, 24, 37, 26, 13, -10, -26, -41, -43, -34, -40,
- -34, -33, -43, -39, -25, -27, -27, -18, -25, -15, -1, -10, -29, -42, -39, -39,
- -19, -7, -10, -10, -11, -20, -35, -44, -33, -30, -28, -36, -34, -47, -41, -36,
- -46, -42, -34, -27, -29, -25, -34, -30, -32, -40, -36, -36, -31, -16, -25, -25,
- -15, -21, -14, -9, -11, 1, 17, 15, 9, 25, 20, 25, 46, 39, 46, 50,
- 51, 68, 85, 87, 72, 65, 52, 50, 59, 44, 42, 29, 23, 22, 23, 11,
- -5, 8, 14, 19, 8, -6, -23, -38, -43, -42, -48, -41, -34, -42, -38, -19,
- -23, -16, -15, -19, -10, 8, 8, -9, -18, -27, -30, -10, -4, 7, 6, 15,
- 8, -8, -17, -15, -8, -11, -3, -15, -17, -14, -16, -27, -30, -26, -22, -19,
- -21, -22, -19, -30, -27, -26, -36, -22, -9, -13, -10, -10, -8, -9, -6, -12,
- -1, 16, 6, 11, 16, 6, 19, 24, 27, 38, 38, 38, 48, 71, 72, 78,
- 66, 51, 54, 52, 49, 42, 32, 21, 25, 26, 13, 1, -1, 10, 15, 8,
- 1, -22, -38, -47, -56, -58, -46, -43, -46, -33, -25, -17, -11, -9, -19, -9,
- 16, 18, 12, 1, -17, -18, -9, 3, 9, 17, 24, 26, 9, -4, -1, -6,
- 2, 9, 0, -2, 2, -3, -13, -16, -15, -8, -8, -8, -1, -6, -17, -11,
- -22, -24, -16, -12, -9, -9, -9, -9, -6, -8, -16, 2, 6, 2, 13, 9,
- 7, 10, 17, 19, 30, 31, 22, 37, 49, 61, 70, 56, 43, 37, 36, 31,
- 32, 15, 4, 11, 9, 4, -14, -16, -7, -5, -1, -8, -28, -46, -56, -75,
- -74, -67, -70, -67, -62, -55, -47, -36, -32, -42, -28, -9, 1, 4, -4, -17,
- -30, -18, -12, -2, 4, 15, 21, 7, 1, -7, -6, -1, 7, 0, 0, 3,
- -3, -8, -15, -18, -6, -9, -6, 5, -2, -2, 0, -7, -12, -7, -3, 2,
- 7, 3, 4, 14, 2, 1, 12, 11, 17, 20, 19, 16, 19, 20, 24, 39,
- 36, 37, 42, 55, 71, 84, 76, 63, 56, 47, 49, 46, 29, 18, 14, 18,
- 11, -5, -11, -8, -3, 4, 4, -16, -27, -44, -60, -64, -59, -62, -62, -55,
- -55, -47, -28, -32, -35, -29, -15, -3, 4, 3, -15, -25, -24, -13, -11, -3,
- 10, 14, 12, 4, -5, -9, -1, 2, -1, 1, 1, -1, -7, -17, -16, -12,
- -17, -8, 0, -1, -1, -2, -8, -13, -9, -9, 0, 9, 1, 14, 16, 6,
- 7, 10, 12, 18, 26, 20, 22, 22, 16, 25, 32, 36, 34, 36, 43, 60,
- 75, 72, 67, 52, 44, 50, 45, 38, 17, 14, 17, 11, -2, -9, -14, -10,
- 0, -4, -12, -24, -41, -59, -67, -63, -70, -69, -62, -70, -55, -40, -38, -42,
- -38, -29, -16, -3, -3, -9, -29, -31, -25, -26, -20, -7, 0, 2, -1, -14,
- -18, -14, -14, -12, -10, -10, -4, -13, -21, -19, -22, -24, -16, -10, -6, -2,
- -2, -10, -12, -15, -17, -4, -4, -5, 7, 9, 3, 4, 7, 5, 18, 23,
- 22, 28, 25, 22, 27, 34, 39, 43, 38, 41, 62, 71, 79, 78, 62, 55,
- 55, 57, 49, 31, 23, 30, 21, 15, 7, -5, 1, 8, 9, 8, -3, -16,
- -39, -46, -50, -60, -55, -58, -62, -53, -36, -33, -34, -34, -29, -18, -6, 5,
- -2, -17, -23, -22, -24, -17, -8, 1, 9, 10, -4, -7, -8, -9, -6, -9,
- -6, 0, -11, -14, -14, -21, -24, -21, -16, -10, 1, -3, -3, -5, -14, -11,
- -7, -7, -5, 6, 9, 4, 8, 1, 3, 11, 16, 20, 26, 24, 20, 25,
- 29, 36, 41, 32, 40, 51, 64, 77, 78, 67, 55, 54, 57, 53, 33, 27,
- 25, 22, 20, 9, -3, -3, 3, 7, 6, 4, -16, -32, -42, -55, -60, -61,
- -64, -70, -62, -49, -39, -41, -40, -37, -33, -18, -5, -8, -16, -24, -29, -31,
- -28, -24, -15, -1, 1, -7, -11, -14, -13, -14, -18, -11, -8, -14, -16, -16,
- -25, -31, -29, -31, -20, -12, -13, -6, -11, -19, -19, -14, -17, -12, -1, 2,
- 6, 7, 2, 4, 8, 11, 18, 24, 21, 22, 19, 21, 33, 33, 32, 32,
- 40, 55, 71, 76, 72, 58, 55, 62, 56, 42, 34, 28, 29, 26, 17, 4,
- 2, 6, 4, 13, 12, -4, -18, -30, -45, -50, -51, -59, -63, -61, -47, -37,
- -33, -32, -34, -32, -19, -4, -3, -5, -13, -21, -23, -22, -24, -13, 1, 5,
- 5, -3, -6, -1, -7, -9, -2, 1, -2, -2, -4, -13, -16, -22, -22, -15,
- -10, -4, 2, -1, -11, -8, -7, -12, -6, 1, 6, 12, 11, 8, 9, 9,
- 9, 20, 23, 26, 25, 20, 24, 32, 34, 35, 33, 35, 49, 63, 74, 74,
- 58, 55, 60, 54, 45, 33, 27, 25, 26, 19, 6, 4, 1, 1, 9, 12,
- -1, -10, -26, -43, -50, -54, -61, -70, -69, -61, -50, -43, -40, -44, -44, -34,
- -18, -12, -9, -15, -24, -25, -28, -31, -22, -12, -2, 1, -8, -8, -5, -12,
- -14, -8, -8, -8, -5, -9, -11, -18, -27, -26, -22, -19, -12, -1, -4, -9,
- -8, -11, -14, -12, -8, 0, 7, 5, 5, 6, 0, 3, 8, 13, 20, 18,
- 13, 15, 22, 27, 29, 25, 26, 36, 51, 70, 71, 59, 56, 57, 55, 47,
- 37, 25, 24, 27, 17, 9, 3, -2, -2, 8, 9, 6, -2, -16, -34, -44,
- -47, -54, -63, -66, -63, -55, -44, -39, -42, -44, -35, -23, -11, -4, -10, -16,
- -17, -23, -25, -22, -13, 1, 6, 1, 1, 4, -2, -4, 1, -1, 4, 3,
- 2, 2, -3, -12, -15, -14, -15, -7, 3, 5, 3, 2, 1, -2, -4, -4,
- 3, 9, 10, 13, 11, 9, 8, 9, 15, 22, 22, 20, 19, 21, 27, 30,
- 28, 28, 28, 42, 61, 69, 65, 60, 60, 58, 55, 47, 35, 30, 30, 24,
- 18, 10, 0, -1, 2, 6, 7, 3, -8, -24, -36, -43, -50, -59, -65, -66,
- -62, -52, -43, -43, -44, -41, -35, -21, -12, -12, -13, -17, -23, -26, -30, -24,
- -12, -4, -5, -3, -2, -5, -6, -6, -5, -3, -2, -1, 2, 2, -5, -3,
- 2, 8, 17, 26, 32, 42, 50, 56, 68, 73, 64, 63, 65, 48, 56, 71,
- 48, 49, 50, 26, 30, 30, 16, 25, 21, -2, 0, -13, -15, -2, -19, -17,
- -16, -50, -49, -49, -81, -85, -88, -108, -112, -116, -127, -126, -113, -113, -106, -79,
- -65, -48, -17, 5, 20, 41, 58, 63, 69, 59, 28, 17, 0, -32, -41, -52,
- -69, -63, -61, -59, -41, -26, -19, 6, 28, 33, 52, 67, 70, 81, 87, 84,
- 90, 93, 84, 72, 69, 60, 45, 56, 57, 40, 46, 39, 25, 29, 25, 16,
- 21, 12, -1, -3, -11, -8, -5, -16, -12, -21, -41, -38, -48, -68, -70, -77,
- -91, -93, -98, -106, -103, -93, -92, -82, -60, -47, -30, -4, 13, 27, 44, 56,
- 60, 62, 47, 23, 13, -8, -32, -40, -54, -64, -59, -59, -53, -36, -26, -14,
- 12, 27, 36, 56, 66, 72, 84, 86, 86, 93, 92, 82, 73, 70, 57, 49,
- 59, 52, 43, 47, 37, 29, 30, 24, 18, 18, 7, -2, -6, -11, -7, -10,
- -16, -14, -29, -42, -42, -57, -71, -73, -83, -93, -96, -102, -107, -101, -93, -90,
- -75, -55, -41, -22, 3, 19, 33, 50, 59, 61, 60, 41, 21, 10, -14, -33,
- -43, -57, -63, -60, -61, -51, -36, -27, -9, 15, 26, 40, 59, 66, 74, 85,
- 85, 88, 94, 90, 80, 75, 69, 56, 54, 60, 50, 47, 46, 36, 31, 30,
- 23, 19, 15, 4, -3, -7, -10, -9, -14, -17, -19, -35, -44, -47, -63, -73,
- -77, -88, -96, -98, -104, -107, -99, -92, -86, -69, -50, -35, -14, 9, 24, 38,
- 54, 60, 61, 56, 36, 19, 4, -20, -35, -46, -60, -62, -61, -60, -48, -35,
- -25, -3, 17, 27, 45, 60, 66, 77, 85, 86, 91, 94, 88, 80, 75, 67,
- 56, 58, 59, 50, 49, 45, 36, 33, 30, 23, 19, 13, 2, -5, -8, -10,
- -11, -16, -18, -25, -40, -45, -53, -68, -76, -81, -91, -97, -100, -106, -106, -97,
- -90, -81, -63, -44, -28, -6, 15, 28, 44, 57, 61, 61, 52, 31, 16, -1,
- -24, -37, -50, -61, -62, -62, -59, -46, -35, -22, 1, 18, 30, 48, 61, 68,
- 79, 85, 87, 92, 93, 86, 80, 75, 66, 58, 60, 58, 51, 50, 44, 37,
- 33, 29, 23, 17, 10, 0, -6, -9, -10, -14, -18, -21, -31, -43, -48, -59,
- -72, -78, -85, -94, -99, -102, -107, -104, -95, -88, -76, -56, -39, -22, 2, 20,
- 33, 49, 59, 61, 60, 47, 27, 12, -7, -27, -40, -53, -62, -62, -63, -57,
- -44, -34, -18, 5, 19, 33, 51, 61, 70, 81, 85, 88, 94, 92, 85, 80,
- 74, 65, 60, 62, 57, 52, 50, 43, 37, 33, 28, 22, 15, 8, -2, -7,
- -10, -12, -16, -20, -24, -36, -46, -52, -64, -75, -81, -89, -97, -100, -104, -107,
- -102, -93, -85, -70, -50, -33, -14, 8, 25, 38, 53, 61, 61, 58, 42, 24,
- 8, -12, -30, -43, -56, -62, -63, -63, -54, -43, -32, -13, 7, 20, 37, 53,
- 62, 72, 82, 85, 89, 94, 90, 84, 80, 73, 64, 62, 62, 56, 53, 49,
- 43, 37, 33, 27, 20, 14, 5, -3, -8, -11, -13, -18, -22, -28, -40, -49,
- -57, -69, -78, -84, -92, -99, -102, -105, -106, -99, -90, -81, -64, -44, -27, -7,
- 14, 29, 43, 56, 61, 61, 54, 37, 20, 4, -17, -33, -46, -58, -62, -64,
- -62, -52, -42, -29, -9, 9, 23, 40, 55, 64, 74, 83, 86, 91, 93, 89,
- 84, 80, 72, 65, 64, 62, 56, 53, 49, 42, 37, 33, 26, 19, 12, 3,
- -5, -8, -12, -16, -20, -24, -33, -44, -52, -61, -73, -80, -87, -95, -100, -103,
- -106, -104, -96, -88, -76, -57, -38, -21, 0, 20, 33, 47, 59, 62, 60, 51,
- 33, 17, -1, -21, -36, -49, -59, -63, -64, -61, -51, -40, -25, -5, 11, 26,
- 43, 56, 65, 76, 83, 87, 92, 93, 88, 84, 79, 71, 65, 65, 61, 56,
- 53, 48, 42, 37, 32, 25, 17, 10, 1, -6, -10, -13, -18, -22, -27, -37,
- -48, -55, -65, -76, -83, -90, -97, -101, -104, -106, -102, -94, -84, -71, -51, -33,
- -15, 7, 24, 38, 51, 60, 62, 59, 46, 29, 13, -6, -25, -39, -52, -60,
- -63, -64, -59, -49, -38, -21, -1, 14, 29, 46, 57, 67, 78, 84, 88, 92,
- 92, 87, 83, 78, 70, 66, 65, 61, 57, 53, 48, 42, 37, 31, 23, 15,
- 7, -1, -7, -11, -15, -20, -24, -31, -41, -51, -59, -69, -79, -85, -93, -99,
- -102, -105, -106, -100, -91, -80, -65, -45, -27, -8, 13, 29, 42, 55, 61, 61,
- 56, 42, 25, 8, -11, -28, -42, -54, -61, -64, -64, -57, -47, -35, -17, 1,
- 16, 33, 48, 59, 69, 79, 84, 89, 93, 91, 87, 83, 77, 70, 67, 65,
- 60, 57, 53, 47, 41, 36, 29, 21, 14, 5, -3, -8, -12, -17, -22, -27,
- -35, -45, -54, -63, -73, -81, -88, -95, -100, -103, -105, -104, -97, -88, -76, -58,
- -39, -21, -1, 18, 33, 46, 58, 62, 61, 53, 38, 21, 4, -15, -31, -45,
- -56, -62, -65, -64, -56, -46, -32, -13, 4, 19, 36, 50, 61, 71, 80, 85,
- 90, 92, 90, 86, 82, 76, 70, 68, 65, 60, 57, 52, 46, 41, 35, 27,
- 19, 12, 3, -5, -9, -14, -19, -24, -29, -38, -48, -57, -66, -76, -84, -91,
- -97, -101, -104, -105, -102, -94, -84, -71, -52, -33, -15, 5, 23, 37, 50, 60,
- 62, 60, 50, 34, 17, -1, -19, -35, -48, -58, -63, -65, -62, -54, -43, -28,
- -10, 7, 22, 39, 52, 62, 73, 81, 86, 91, 92, 89, 86, 82, 75, 70,
- 68, 64, 60, 57, 52, 46, 40, 34, 26, 17, 9, 1, -6, -11, -15, -21,
- -26, -32, -42, -52, -60, -70, -79, -86, -93, -99, -102, -104, -105, -100, -91, -80,
- -65, -46, -27, -9, 11, 28, 42, 54, 61, 62, 58, 46, 30, 13, -6, -23,
- -38, -51, -60, -64, -65, -61, -52, -41, -25, -6, 9, 26, 42, 54, 64, 75,
- 82, 87, 91, 91, 89, 85, 81, 74, 71, 68, 64, 60, 56, 51, 45, 39,
- 32, 24, 16, 7, -1, -7, -12, -17, -23, -28, -36, -45, -55, -64, -73, -82,
- -88, -95, -100, -103, -105, -104, -97, -88, -76, -59, -40, -22, -2, 17, 32, 45,
- 57, 62, 62, 56, 42, 26, 9, -10, -27, -41, -53, -61, -65, -65, -60, -50,
- -38, -21, -3, 12, 29, 44, 55, 66, 76, 82, 88, 91, 91, 88, 85, 80,
- 74, 71, 68, 63, 60, 56, 50, 44, 38, 30, 22, 14, 5, -3, -9, -14,
- -19, -25, -31, -39, -49, -58, -67, -77, -84, -91, -97, -101, -103, -105, -102, -95,
- -84, -71, -53, -34, -16, 4, 22, 37, 49, 59, 63, 61, 53, 38, 22, 4,
- -14, -30, -44, -56, -62, -66, -65, -58, -48, -35, -17, -1, 15, 32, 46, 57,
- 68, 77, 83, 88, 91, 90, 88, 84, 79, 74, 71, 67, 63, 60, 55, 49,
- 43, 37, 28, 20, 12, 3, -5, -10, -15, -21, -27, -33, -43, -52, -61, -70,
- -79, -86, -93, -98, -102, -104, -104, -100, -92, -81, -66, -47, -28, -10, 10, 27,
- 40, 53, 61, 63, 59, 49, 34, 18, -1, -18, -34, -47, -58, -63, -66, -64,
- -56, -46, -31, -14, 2, 18, 35, 48, 59, 70, 78, 84, 89, 91, 90, 87,
- 83, 78, 74, 71, 67, 63, 59, 54, 49, 42, 35, 27, 18, 9, 1, -6,
- -12, -17, -23, -29, -36, -46, -55, -64, -73, -82, -89, -95, -100, -102, -104, -103,
- -97, -88, -76, -60, -41, -23, -4, 15, 31, 44, 55, 62, 62, 57, 46, 30,
- 13, -5, -22, -37, -50, -59, -64, -66, -62, -55, -43, -28, -11, 5, 22, 37,
- 50, 61, 71, 79, 85, 89, 91, 89, 87, 82, 77, 73, 70, 66, 63, 59,
- 53, 47, 41, 33, 24, 16, 7, -1, -8, -14, -19, -25, -32, -40, -49, -58,
- -67, -76, -84, -91, -96, -101, -103, -104, -102, -95, -85, -72, -55, -37, -18, 1,
- 19, 34, 47, 57, 62, 62, 56, 43, 28, 10, -8, -25, -39, -52, -60, -65,
- -66, -62, -53, -42, -25, -9, 8, 24, 39, 51, 62, 72, 80, 86, 90, 90,
- 89, 86, 82, 77, 73, 70, 66, 62, 58, 53, 47, 40, 33, 24, 15, 6,
- -2, -8, -14, -19, -25, -32, -40, -49, -58, -67, -72, -103, -18, -76, 0, 0,
- 0, 0, 1, 2, 3, 5, 6, 0, -7, -8, -15, -9, 10, 8, 17, 33,
- 14, 5, 38, 44, 31, 63, 70, 51, 73, 82, 68, 85, 100, 96, 97, 103,
- 115, 114, 112, 127, 122, 110, 116, 113, 109, 120, 120, 118, 113, 91, 93, 109,
- 97, 98, 115, 110, 109, 120, 112, 94, 75, 63, 69, 72, 64, 64, 59, 45,
- 39, 36, 35, 42, 42, 24, 5, 2, 3, 4, 7, 9, 11, 14, 17, 19,
- 14, -3, -20, -26, -30, -26, -24, -31, -32, -34, -40, -39, -33, -34, -45, -56,
- -60, -66, -64, -55, -60, -62, -56, -59, -58, -50, -56, -70, -73, -76, -86, -77,
- -70, -80, -76, -71, -77, -71, -66, -76, -85, -82, -90, -95, -80, -82, -92, -85,
- -86, -94, -85, -79, -86, -92, -90, -94, -101, -92, -85, -90, -84, -77, -78, -74,
- -73, -85, -86, -85, -95, -85, -77, -90, -88, -83, -94, -93, -83, -81, -81, -86,
- -89, -89, -94, -88, -77, -77, -71, -59, -58, -59, -63, -72, -74, -77, -73, -61,
- -67, -72, -67, -73, -80, -74, -68, -60, -56, -65, -70, -67, -72, -66, -52, -49,
- -40, -27, -27, -32, -39, -47, -50, -42, -30, -31, -34, -32, -38, -46, -46, -43,
- -35, -20, -16, -24, -30, -30, -31, -24, -13, -6, 4, 13, 11, 3, -5, -9,
- -2, 12, 15, 15, 16, 9, 3, -2, -5, -1, 12, 24, 30, 29, 20, 17,
- 22, 25, 30, 41, 47, 49, 46, 37, 32, 41, 52, 54, 60, 61, 52, 48,
- 45, 36, 35, 43, 51, 60, 67, 69, 60, 57, 63, 63, 64, 73, 75, 72,
- 69, 63, 67, 78, 78, 82, 89, 80, 73, 76, 67, 60, 64, 67, 73, 79,
- 83, 88, 82, 75, 80, 81, 77, 83, 83, 76, 74, 77, 83, 85, 86, 94,
- 89, 80, 82, 78, 69, 68, 68, 69, 78, 80, 81, 90, 83, 73, 79, 77,
- 70, 73, 70, 62, 65, 73, 75, 76, 84, 82, 70, 71, 69, 59, 57, 54,
- 48, 53, 63, 64, 68, 76, 66, 57, 58, 51, 42, 40, 33, 28, 37, 46,
- 49, 55, 56, 42, 37, 37, 27, 22, 20, 10, 4, 8, 15, 24, 30, 31,
- 24, 14, 8, -3, -14, -21, -26, -26, -15, -4, -1, -4, -13, -21, -26, -34,
- -39, -42, -50, -57, -63, -66, -60, -47, -43, -48, -51, -57, -66, -75, -82, -88,
- -91, -88, -78, -74, -81, -86, -85, -92, -101, -100, -102, -109, -109, -110, -112, -113,
- -115, -109, -106, -113, -113, -107, -110, -110, -106, -108, -112, -109, -110, -114, -111, -98,
- -95, -98, -93, -93, -98, -94, -89, -81, -69, -65, -71, -73, -73, -77, -73, -62,
- -56, -48, -40, -41, -45, -47, -47, -37, -20, -11, -4, 5, 4, 3, 6, 9,
- 16, 30, 39, 47, 51, 44, 40, 45, 47, 50, 59, 64, 66, 68, 65, 65,
- 75, 80, 78, 87, 95, 91, 93, 98, 96, 98, 104, 100, 96, 99, 104, 101,
- 100, 106, 107, 105, 108, 109, 109, 110, 111, 110, 101, 87, 82, 84, 81, 82,
- 88, 89, 90, 91, 85, 71, 57, 49, 48, 51, 52, 55, 59, 58, 58, 60,
- 61, 61, 57, 42, 24, 14, 7, 5, 9, 11, 15, 20, 21, 19, 11, -3,
- -18, -27, -33, -31, -25, -24, -21, -16, -16, -14, -11, -17, -29, -40, -49, -59,
- -61, -55, -54, -52, -45, -42, -41, -41, -48, -59, -65, -72, -81, -79, -72, -73,
- -69, -62, -61, -59, -60, -69, -76, -79, -87, -92, -84, -81, -82, -76, -72, -71,
- -67, -66, -72, -79, -81, -87, -94, -92, -87, -86, -82, -76, -75, -75, -78, -85,
- -87, -91, -96, -91, -82, -83, -80, -74, -74, -71, -64, -64, -68, -73, -77, -81,
- -87, -88, -82, -79, -76, -70, -69, -72, -76, -80, -84, -87, -82, -71, -67, -64,
- -58, -57, -55, -49, -43, -39, -40, -47, -54, -58, -64, -66, -61, -58, -54, -49,
- -50, -55, -59, -63, -65, -58, -45, -38, -32, -25, -24, -23, -18, -13, -5, 3,
- 4, -2, -11, -17, -23, -26, -23, -20, -18, -15, -18, -24, -28, -28, -21, -7,
- 3, 11, 18, 20, 19, 22, 24, 30, 40, 47, 51, 49, 40, 32, 28, 24,
- 23, 25, 25, 23, 20, 15, 15, 23, 34, 43, 51, 59, 59, 58, 59, 58,
- 60, 67, 73, 78, 84, 85, 78, 71, 68, 63, 60, 60, 57, 53, 50, 50,
- 56, 65, 70, 76, 84, 84, 81, 81, 79, 76, 79, 84, 87, 91, 96, 98,
- 94, 88, 85, 81, 76, 73, 70, 66, 66, 70, 76, 80, 84, 91, 92, 87,
- 86, 83, 78, 76, 78, 81, 85, 88, 91, 96, 93, 86, 83, 78, 71, 68,
- 64, 61, 64, 71, 74, 78, 84, 86, 80, 76, 72, 64, 59, 56, 55, 59,
- 66, 69, 74, 79, 76, 69, 64, 57, 48, 43, 39, 39, 45, 52, 56, 62,
- 63, 55, 47, 41, 31, 21, 15, 8, 5, 9, 16, 24, 31, 35, 33, 26,
- 19, 10, 0, -6, -9, -7, -7, -13, -17, -22, -26, -31, -34, -37, -40, -42,
- -44, -46, -48, -50, -51, -54, -56, -58, -61, -64, -67, -70, -74, -78, -82, -86,
- -90, -93, -97, -99, -102, -104, -106, -108, -109, -110, -111, -112, -113, -113, -114, -114,
- -115, -115, -115, -115, -115, -114, -113, -111, -109, -107, -104, -100, -97, -93, -90, -87,
- -84, -82, -80, -78, -76, -74, -73, -71, -69, -67, -65, -61, -58, -53, -48, -42,
- -35, -28, -21, -13, -6, 1, 8, 15, 21, 26, 31, 35, 38, 41, 44, 46,
- 48, 50, 52, 55, 58, 61, 64, 68, 72, 76, 80, 83, 87, 90, 92, 94,
- 96, 98, 99, 100, 101, 102, 102, 103, 103, 103, 103, 104, 103, 103, 103, 102,
- 101, 99, 97, 94, 92, 88, 85, 81, 78, 74, 71, 67, 64, 61, 58, 55,
- 53, 51, 49, 47, 46, 44, 42, 40, 37, 34, 30, 26, 22, 17, 12, 8,
- 3, -1, -5, -9, -13, -16, -20, -23, -26, -29, -31, -33, -35, -37, -38, -40,
- -42, -44, -46, -48, -51, -54, -56, -59, -61, -64, -65, -67, -69, -70, -72, -74,
- -75, -77, -78, -80, -81, -82, -83, -84, -85, -86, -86, -87, -88, -89, -90, -90,
- -91, -92, -92, -92, -92, -92, -92, -91, -91, -92, -92, -92, -93, -93, -94, -94,
- -94, -95, -95, -95, -95, -95, -95, -95, -95, -95, -94, -93, -92, -91, -90, -89,
- -87, -86, -85, -85, -85, -84, -84, -85, -85, -85, -85, -85, -85, -85, -85, -85,
- -84, -83, -82, -81, -79, -77, -75, -73, -70, -68, -65, -63, -62, -60, -59, -59,
- -59, -59, -59, -59, -59, -60, -59, -59, -59, -58, -57, -55, -53, -50, -47, -44,
- -40, -36, -32, -29, -25, -22, -20, -18, -17, -16, -15, -15, -16, -16, -16, -16,
- -16, -16, -15, -13, -11, -9, -6, -2, 2, 6, 10, 15, 19, 22, 26, 29,
- 31, 33, 35, 36, 36, 36, 36, 35, 35, 35, 35, 35, 36, 38, 40, 42,
- 45, 48, 52, 55, 58, 61, 64, 67, 70, 72, 73, 74, 75, 76, 76, 76,
- 75, 75, 74, 74, 74, 74, 74, 75, 77, 78, 80, 82, 83, 85, 87, 89,
- 90, 91, 92, 93, 94, 94, 94, 94, 94, 93, 93, 92, 91, 91, 90, 90,
- 90, 90, 91, 91, 92, 92, 93, 93, 94, 94, 94, 94, 94, 94, 94, 94,
- 93, 93, 92, 92, 91, 90, 89, 88, 87, 87, 86, 86, 85, 85, 85, 84,
- 84, 83, 83, 82, 81, 80, 79, 78, 77, 77, 76, 75, 74, 72, 71, 70,
- 68, 67, 65, 64, 63, 61, 60, 58, 57, 55, 53, 50, 48, 45, 43, 40,
- 38, 36, 34, 32, 30, 29, 27, 25, 23, 21, 19, 17, 14, 12, 9, 6,
- 3, 0, -4, -8, -12, -17, -21, -25, -29, -33, -36, -39, -42, -45, -47, -49,
- -51, -53, -55, -58, -60, -63, -65, -68, -71, -74, -77, -81, -84, -87, -91, -94,
- -97, -99, -102, -104, -105, -107, -108, -109, -110, -111, -111, -112, -112, -113, -113, -113,
- -113, -113, -113, -112, -111, -109, -107, -105, -102, -99, -96, -93, -90, -87, -84, -82,
- -79, -77, -75, -73, -70, -69, -66, -64, -60, -58, -53, -49, -44, -39, -32, -27,
- -19, -14, -8, -3, 3, 11, 22, 10, 8, 1, 1, 1, 1, 1, 2, 2,
- 2, 2, 3, 3, 3, 3, 4, 4, 5, 5, 6, 5, 6, 6, 6, 6,
- 6, 6, 7, 5, 7, 5, 6, 4, 6, 4, 4, 4, 4, 3, 3, 2,
- 3, 1, 3, -2, 2, 0, 0, 0, 0, -2, -1, -2, -3, -3, 0, -5,
- -1, -2, -2, -2, -1, 0, -3, -1, -1, 0, 1, -1, 0, -1, 0, 0,
- 1, 0, 0, 1, -1, 1, -1, 1, -2, -1, -3, 0, -2, -1, -2, -2,
- -2, -3, -2, -3, -4, -5, -6, -5, -9, -8, -9, -9, -9, -11, -10, -13,
- -14, -14, -15, -16, -15, -17, -19, -19, -21, -18, -21, -20, -22, -20, -24, -21,
- -22, -19, -20, -21, -17, -19, -16, -17, -15, -17, -13, -11, -10, -7, -5, -3,
- 2, 6, 4, 8, 9, 18, 14, 31, 25, 24, 25, 24, 21, 13, 15, 15,
- 11, 9, 1, 4, -20, -18, -38, -44, -57, -57, -55, -55, -52, -55, -46, -47,
- -40, -32, -26, -19, -16, -2, 3, 13, 19, 28, 30, 37, 40, 44, 39, 38,
- 35, 34, 37, 41, 48, 51, 53, 58, 61, 70, 74, 76, 76, 80, 81, 86,
- 83, 83, 78, 78, 73, 69, 65, 55, 47, 40, 36, 29, 23, 16, 14, 8,
- -2, -4, -11, -11, -19, -22, -26, -25, -34, -39, -40, -41, -45, -49, -51, -57,
- -56, -58, -59, -66, -70, -70, -72, -65, -64, -59, -53, -49, -45, -34, -29, -21,
- -15, -10, -6, -6, -3, -4, 2, 3, 3, 3, -1, -3, -11, -11, -13, -16,
- -22, -24, -27, -32, -34, -37, -35, -31, -30, -26, -25, -22, -21, -15, -13, -15,
- -10, -12, -12, -7, 2, 15, 22, 27, 24, 28, 22, 22, 21, 22, 17, 13,
- 14, 9, 5, 2, -8, -12, -16, -14, -17, -17, -17, -17, -14, -8, -3, -3,
- 0, 5, 3, 5, 6, 3, -2, -6, -9, -11, -13, -18, -19, -29, -42, -61,
- -72, -79, -81, -83, -82, -79, -76, -65, -54, -42, -33, -24, -14, 0, 18, 33,
- 48, 62, 75, 87, 93, 99, 100, 102, 102, 104, 102, 100, 100, 96, 93, 95,
- 96, 105, 109, 112, 111, 110, 106, 106, 104, 102, 97, 93, 85, 80, 71, 60,
- 48, 36, 26, 12, 0, -5, -13, -21, -28, -31, -36, -42, -49, -53, -56, -59,
- -61, -63, -64, -64, -63, -67, -70, -77, -75, -77, -78, -79, -80, -81, -80, -75,
- -69, -64, -57, -50, -43, -35, -26, -16, -6, 6, 13, 17, 22, 26, 25, 27,
- 27, 26, 23, 19, 11, 5, -5, -12, -19, -24, -31, -37, -42, -45, -50, -49,
- -48, -47, -43, -41, -38, -38, -37, -35, -35, -37, -42, -40, -33, -27, -20, -12,
- -11, -13, -10, -9, -10, -10, -10, -13, -11, -9, -8, -11, -13, -16, -18, -17,
- -15, -15, -14, -12, -8, -3, 3, 8, 16, 22, 25, 31, 34, 36, 36, 34,
- 31, 25, 23, 24, 26, 23, 13, -1, -16, -29, -38, -45, -51, -56, -57, -54,
- -48, -39, -34, -29, -20, -10, 0, 13, 27, 39, 54, 68, 79, 87, 92, 94,
- 96, 94, 92, 89, 87, 82, 76, 72, 71, 74, 76, 81, 83, 83, 84, 84,
- 85, 85, 82, 81, 82, 80, 75, 71, 66, 57, 46, 34, 24, 15, 5, -2,
- -8, -13, -19, -26, -31, -37, -41, -44, -48, -53, -54, -53, -54, -54, -57, -61,
- -64, -67, -70, -72, -75, -77, -79, -79, -76, -73, -70, -63, -58, -53, -47, -38,
- -29, -21, -13, -6, 0, 4, 7, 7, 8, 8, 6, 5, -1, -8, -15, -22,
- -30, -36, -41, -47, -51, -54, -56, -58, -59, -56, -50, -45, -42, -37, -31, -26,
- -23, -23, -23, -24, -21, -14, -6, 2, 8, 12, 15, 18, 21, 20, 20, 20,
- 20, 21, 23, 22, 18, 13, 10, 8, 6, 5, 4, 3, 2, 2, 4, 7,
- 10, 13, 18, 22, 24, 26, 28, 27, 21, 14, 8, 5, 4, 2, -3, -12,
- -24, -37, -50, -59, -67, -76, -80, -79, -75, -69, -61, -55, -47, -38, -27, -15,
- -2, 11, 27, 43, 58, 71, 82, 90, 94, 96, 98, 98, 98, 95, 89, 84,
- 81, 79, 81, 85, 88, 89, 91, 92, 92, 90, 89, 89, 88, 85, 82, 79,
- 75, 67, 58, 48, 37, 25, 14, 4, -4, -10, -17, -24, -31, -37, -42, -47,
- -51, -56, -59, -59, -59, -59, -61, -63, -65, -67, -70, -72, -74, -76, -78, -78,
- -78, -75, -70, -66, -61, -56, -50, -41, -33, -23, -14, -6, 2, 10, 16, 19,
- 21, 23, 24, 24, 22, 19, 13, 7, 0, -6, -14, -20, -25, -27, -32, -37,
- -39, -39, -38, -36, -33, -30, -27, -22, -19, -19, -20, -23, -24, -22, -18, -13,
- -8, -4, 0, 2, 5, 6, 5, 3, 2, 4, 6, 6, 5, 1, -2, -6,
- -8, -9, -10, -11, -13, -12, -12, -11, -9, -4, 0, 4, 8, 13, 18, 20,
- 19, 14, 10, 6, 4, 4, 4, 0, -8, -17, -28, -38, -49, -60, -68, -72,
- -72, -70, -65, -59, -54, -46, -37, -27, -17, -5, 8, 22, 37, 51, 66, 77,
- 84, 88, 91, 93, 94, 94, 91, 85, 79, 75, 74, 76, 77, 80, 83, 85,
- 85, 85, 86, 86, 85, 85, 85, 83, 81, 77, 70, 64, 55, 44, 32, 22,
- 13, 6, -1, -9, -16, -22, -27, -32, -38, -43, -46, -47, -47, -47, -48, -49,
- -49, -50, -52, -54, -56, -59, -62, -64, -66, -65, -64, -61, -59, -56, -53, -48,
- -41, -33, -25, -17, -10, -2, 4, 9, 13, 15, 16, 17, 17, 15, 11, 7,
- 1, -7, -15, -22, -27, -33, -38, -43, -47, -49, -50, -50, -49, -46, -42, -37,
- -31, -28, -28, -29, -30, -29, -26, -22, -17, -13, -8, -3, 2, 6, 7, 6,
- 5, 6, 8, 10, 12, 11, 8, 5, 3, 1, -1, -2, -3, -4, -6, -7,
- -6, -3, 0, 1, 5, 10, 16, 20, 21, 19, 15, 10, 8, 6, 6, 4,
- 0, -5, -12, -22, -33, -45, -57, -65, -70, -72, -70, -68, -64, -58, -51, -44,
- -36, -24, -13, -2, 11, 27, 43, 58, 70, 78, 83, 88, 92, 96, 97, 93,
- 89, 85, 81, 80, 81, 83, 86, 88, 90, 91, 91, 91, 91, 91, 91, 91,
- 89, 86, 83, 79, 72, 63, 52, 41, 30, 21, 13, 4, -5, -11, -17, -23,
- -31, -38, -44, -47, -49, -50, -52, -54, -55, -57, -57, -58, -60, -63, -66, -69,
- -72, -74, -73, -72, -70, -69, -67, -64, -59, -53, -45, -37, -30, -22, -14, -7,
- -2, 3, 8, 10, 12, 12, 13, 12, 8, 3, -4, -10, -16, -21, -27, -33,
- -37, -41, -44, -46, -48, -48, -45, -48, -43, -37, -33, -31, -32, -33, -32, -29,
- -26, -22, -18, -12, -5, 1, 6, 9, 9, 9, 9, 11, 14, 16, 16, 14,
- 12, 8, 5, 3, 2, 1, -1, -3, -4, -4, -2, -1, 2, 5, 11, 18,
- 24, 27, 27, 24, 20, 17, 15, 13, 11, 9, 5, -1, -10, -22, -35, -49,
- -61, -70, -75, -77, -76, -73, -69, -63, -56, -47, -36, -25, -13, 0, 16, 34,
- 52, 67, 79, 88, 95, 101, 106, 109, 108, 105, 100, 95, 92, 90, 91, 93,
- 96, 99, 100, 101, 101, 101, 101, 101, 101, 100, 97, 95, 91, 85, 78, 67,
- 55, 43, 31, 21, 11, 1, -7, -14, -21, -29, -37, -45, -51, -54, -56, -58,
- -60, -62, -64, -65, -66, -67, -69, -72, -76, -80, -82, -84, -83, -82, -80, -79,
- -77, -73, -67, -60, -51, -42, -34, -25, -16, -8, -2, 4, 9, 12, 13, 14,
- 14, 13, 9, 3, -5, -12, -18, -25, -31, -37, -42, -47, -50, -53, -54, -53,
- -48, -41, -36, -32, -31, -31, -32, -31, -28, -25, -22, -17, -12, -5, 1, 1,
- -2, -1, -9, -9, -6, 5, 6, -1, -10, 8, 24, 11, -2, -14, -9, -15,
- -13, 5, 14, 12, -6, -1, -12, 1, -9, 12, 12, 10, 5, -19, -11, -13,
- -2, 8, 5, 1, -2, -3, 9, -6, 6, 5, 6, -3, -17, -7, 3, 2,
- -1, 0, 7, -7, 5, 4, 6, -18, -24, 6, 20, -1, -4, -1, 10, 3,
- -10, 8, 7, -11, -17, -15, 5, 18, 4, 1, 8, -16, -4, 0, 11, 9,
- -10, -15, 0, -22, -12, 19, 34, 16, -9, -16, -7, -12, -10, 13, 23, -1,
- -10, -2, -3, -11, 13, 7, -6, -9, 3, 11, -10, -18, 12, 22, 7, -27,
- -29, -4, 20, 20, 10, 8, -16, -26, -6, 22, 21, 7, 15, 8, -50, -50,
- -7, 35, 22, -13, 32, 41, -33, -46, -10, 23, -7, -25, 23, 21, -38, -36,
- 14, 44, 2, 2, 34, -14, -51, -29, 11, 19, 7, 22, 13, -23, -21, -8,
- -9, 1, 14, 26, 26, -8, -34, -33, 4, 1, -6, -2, 16, -7, -23, 12,
- 27, 5, 6, 6, 0, -8, 0, -1, -17, -13, -12, 3, 9, 4, 11, 23,
- 36, 0, -43, -16, 4, -21, -26, 27, 16, -25, 3, 65, 4, -34, 24, -10,
- -38, -14, 13, 4, -15, 36, 44, -42, -51, 20, -5, -6, 68, 20, -18, -39,
- -11, 9, 17, 6, -33, -20, -13, 48, 30, 22, -4, -9, -53, -20, 32, 32,
- -16, 17, -11, -36, -8, -5, 39, 28, 33, 21, -64, -48, 3, -22, 15, 62,
- -26, 0, 3, 5, 73, -14, -48, -20, -59, 4, 70, 60, -7, -2, -88, -22,
- -17, 39, 17, 33, -3, 15, 28, -47, -80, -37, 5, 7, 104, 16, -99, -92,
- -36, 109, 78, 26, -15, -92, -21, 62, 48, -51, -81, -25, 55, 63, 35, 21,
- -115, -54, 101, 73, -41, -110, -66, 50, 107, 45, -8, -109, -38, 12, 102, 3,
- 17, -45, -2, -36, 39, 46, -12, -28, -27, -17, 17, -18, 82, -5, -3, -25,
- -5, -14, 15, 9, -3, -17, -6, 2, 7, -36, -13, 6, 21, -23, -20, 16,
- -18, 3, -2, 26, 0, 13, -23, -2, -19, -28, -18, 15, 12, 22, -4, 23,
- -17, -22, -9, -18, -4, 11, 13, 0, 34, -16, -20, 26, 23, 15, -4, -25,
- 7, 8, -9, 8, 44, 1, -40, 17, -32, 9, -30, -52, 52, 3, 2, -21,
- 83, 58, -14, -46, -61, -12, -67, -20, 64, 72, 57, -10, 5, 1, -77, 31,
- -47, -39, 12, 22, 57, 28, 0, 9, -76, 15, -74, 33, -12, 39, 114, -35,
- -36, -38, -23, 27, -21, 14, 56, 47, 6, -72, -61, -4, 18, -4, 19, 13,
- 45, 71, 48, -1, -125, -52, -56, -20, -18, -12, 51, 78, 68, -46, 32, -40,
- -29, -28, -81, -25, 75, 42, 58, -38, 1, -29, -34, 31, -36, -14, 10, 64,
- 37, 2, -31, -72, -17, -33, 30, -52, -54, 25, 43, 70, 81, -9, -73, 4,
- -65, 15, -28, 25, 0, 28, 19, 51, -26, 6, 0, -37, -15, -22, -20, -16,
- -5, 50, 56, 67, 25, 16, -35, -29, -14, -39, 19, -24, -52, -13, -32, -10,
- 39, 33, 59, 6, 37, 55, 11, -9, -35, -15, -57, -56, -36, -34, 19, 19,
- 6, 20, 17, -11, 5, 26, 19, 16, 7, -20, -26, -55, -62, -36, -18, 19,
- 37, 47, 25, -6, -14, 1, -4, -13, 12, 23, 34, 38, 41, 33, 31, -10,
- -56, -52, -49, -31, -40, -21, -12, 0, 5, 12, 22, 22, 21, 31, 12, 2,
- -8, -4, -18, -7, 3, 1, -1, 11, 12, 18, 17, 9, -2, -12, -13, -11,
- -1, 8, 3, 3, 2, 5, -5, -16, -15, -13, -8, -12, -9, -2, -1, 2,
- 7, 10, 7, 11, 14, 7, -1, -4, 5, -3, -2, 0, -6, -10, -1, -5,
- 3, 9, 0, -8, -9, -6, -6, 0, 6, 3, 6, 7, 10, 0, -8, -3,
- -5, -1, -8, -7, -4, -3, -3, 0, -1, -6, 2, 7, 7, 5, 4, 10,
- 5, 8, -1, -11, -15, -11, -15, -10, -1, -8, -12, -5, 1, 3, 6, 8,
- 11, 18, 22, 26, 10, -10, -1, -15, -3, -21, -16, -14, -12, -7, -8, -18,
- -20, -11, 9, 20, 27, 26, 11, 1, 21, 6, 3, -9, -15, -9, -20, 3,
- 5, 21, 14, 6, 11, -21, -22, -6, -21, -23, -18, 11, 6, 5, 21, 9,
- 23, 16, -3, -30, -7, -27, -4, 5, 18, 22, 16, 2, 7, -1, -2, -10,
- -14, -10, -17, -10, -15, -16, 3, 12, 30, 18, -1, -6, -15, -3, 5, 11,
- -18, -2, 8, 21, 11, -13, -4, -30, -7, 0, 12, 25, -3, 17, 14, -20,
- -6, -27, -41, -11, -12, 23, -8, 13, 24, 18, 27, -11, -8, -12, -2, 17,
- 23, 13, -20, -21, -2, -21, -34, -46, -23, 28, 48, 9, -10, 8, 29, 27,
- 5, -29, -12, 13, -5, -2, -35, 1, 3, 24, 13, 17, -18, -30, -21, 14,
- -1, 6, -8, 48, 45, -7, -34, -49, -32, -6, -26, 20, 29, 76, 30, -21,
- -66, -36, -15, 40, -5, 29, 3, 10, -39, -25, -2, 24, 19, 19, -4, -8,
- 3, -22, -23, -18, 13, 17, -3, -25, 23, 66, 26, -18, -27, -34, -30, -30,
- 36, 25, 28, -22, -17, -7, -22, 21, 18, 42, 8, -25, -28, -31, -10, 15,
- 18, 0, -1, -5, 16, -12, 13, 13, 12, -8, -37, -9, 13, -5, 8, -3,
- 13, -8, 4, 24, -16, -43, -18, 26, 26, -11, -9, 19, 9, -15, 9, 15,
- -12, -31, -27, 8, 29, 5, 7, 17, -33, -14, 14, 23, -1, -18, -18, -4,
- -35, -17, 47, 71, -16, -20, -11, -16, -25, 6, 37, 14, -18, 1, -8, -14,
- 10, 14, 2, -20, 0, 20, -10, -25, 14, 32, 7, -39, -38, -3, 34, 25,
- 13, 3, -24, -34, 5, 38, 18, 7, 29, -30, -74, -41, 36, 40, -12, 26,
- 55, -17, -59, -26, 28, -2, -31, 24, 25, -44, -39, 21, 44, -1, 10, 33,
- -34, -50, -12, 18, 13, 20, 17, -6, -31, -10, -6, -1, 7, 12, 14, 6,
- -16, -24, 6, 9, -16, -16, 6, 2, -10, 13, 12, -10, 0, 11, 11, 10,
- -3, -22, -22, -12, -7, 19, 17, -2, -12, 6, 16, 7, -11, -1, -20, -22,
- -8, 26, 16, -3, 12, 1, -33, 2, 30, -23, -5, 28, -17, -19, 21, 9,
- -28, -14, 25, -1, 4, 24, 0, -26, -9, 7, 2, -2, 20, -10, -11, 5,
- -3, -4, 8, -9, 14, 18, 25, -22, -15, -22, -3, -12, 27, 30, 15, -11,
- -26, -4, 15, -7, -14, 23, -23, -4, 34, -2, -38, 14, -11, -24, 16, 34,
- 11, -13, 3, -3, -19, -34, 0, -3, 24, 43, 1, -12, -38, -25, -11, 23,
- 35, 12, -28, -25, -16, 7, 22, 1, -10, 8, 8, -3, 6, -24, -20, -13,
- 9, 31, 12, -16, 7, -29, 5, 8, -28, 3, 4, 12, 26, -9, -15, -5,
- -20, 9, 21, 0, 1, -9, 0, 8, -3, -7, -9, -3, 22, 8, 3, -11,
- -9, -11, 3, 15, 9, -10, 1, -3, -3, -2, -5, 9, 0, 12, 7, -15,
- -7, 0, -8, 5, 9, -5, 7, -7, 10, 4, -11, -2, -8, -4, 9, 9,
- 0, -2, -11, -3, -4, 3, 4, 3, -2, 3, 3, -8, -9, -2, 0, 3,
- 5, -1, -10, -7, 2, 8, 3, 0, -5, -5, 2, 4, -2, -5, -3, 2,
- 3, 0, 2, -5, -3, 3, 2, -2, -4, -2, 1, 2, 1, 0, 0, 0,
- 0, -1, -7, -9, -5, 0, 2, 2, 5, 6, 0, -11, -13, -5, 3, 1,
- 0, 0, 1, -3, -9, -6, -1, 5, 3, -3, -5, -3, -1, -4, -3, -1,
- 2, -2, -9, -7, -2, -5, -18, -31, -36, -36, -41, -38, -29, -21, -27, -31,
- -26, -4, 37, 65, 67, 44, 22, 10, 2, -4, 8, 32, 44, 38, 24, 17,
- 9, 4, 3, 12, 26, 32, 32, 23, 16, 7, 1, -7, -13, -8, 1, -5,
- -39, -72, -79, -64, -49, -40, -24, -1, 12, 0, -25, -44, -43, -30, -14, 1,
- 13, 13, 4, 4, 16, 34, 46, 55, 65, 73, 67, 53, 54, 58, 62, 60,
- 51, 38, 33, 20, -7, -27, -40, -46, -55, -58, -41, -9, 7, 8, 2, -26,
- -49, -71, -92, -101, -93, -80, -70, -71, -73, -65, -67, -69, -61, -42, -15, 15,
- 18, -5, -33, -54, -54, -40, -18, 2, 21, 21, 3, -28, -52, -33, 9, 35,
- 33, 30, 34, 45, 46, 43, 54, 63, 65, 61, 56, 43, 45, 59, 77, 96,
- 104, 112, 115, 100, 78, 53, 22, -3, -6, 5, 24, 37, 38, 35, 25, 3,
- -19, -38, -51, -46, -33, -34, -42, -47, -48, -38, -27, -30, -40, -48, -45, -30,
- -24, -38, -44, -43, -47, -34, -13, 7, 27, 30, 9, -18, -38, -22, 19, 47,
- 70, 83, 68, 28, -13, -41, -41, -19, -1, 10, 8, 4, 4, -7, -12, 6,
- 32, 42, 31, 0, -39, -71, -99, -115, -111, -85, -56, -46, -61, -74, -66, -45,
- -22, 4, 21, 27, 25, 1, -30, -51, -37, 4, 37, 40, 26, 17, 12, 12,
- 5, 1, 2, 12, 29, 43, 44, 45, 54, 45, 28, 10, 13, 26, 32, 43,
- 59, 67, 62, 60, 66, 72, 61, 34, 11, 0, 1, -6, -18, -12, 19, 47,
- 51, 32, 9, -8, -22, -26, -27, -30, -29, -12, 7, 18, 13, -1, -11, -11,
- 5, 16, 14, 11, 5, -19, -47, -54, -29, 13, 37, 42, 33, 9, -17, -31,
- -21, 14, 61, 81, 68, 39, 4, -26, -46, -38, -17, -1, 1, -4, -14, -25,
- -23, -4, 24, 43, 49, 37, 4, -48, -97, -123, -116, -89, -66, -65, -73, -67,
- -64, -66, -69, -46, 3, 36, 27, -3, -25, -39, -38, -39, -36, -24, -9, 5,
- 13, 13, 4, -1, -13, -15, 0, 22, 47, 65, 76, 67, 35, 3, -4, 6,
- 27, 47, 58, 68, 72, 73, 72, 66, 59, 62, 61, 49, 28, -5, -30, -27,
- 9, 40, 51, 46, 40, 28, 1, -30, -56, -57, -41, -13, 5, 12, 7, -11,
- -38, -54, -40, -16, 12, 23, 13, -16, -49, -62, -55, -29, 4, 38, 45, 28,
- -5, -36, -36, -5, 39, 68, 77, 73, 55, 8, -35, -46, -29, -15, -15, -16,
- -12, -9, -23, -30, -18, 16, 48, 51, 24, -18, -45, -72, -96, -111, -101, -80,
- -67, -71, -79, -77, -70, -46, -22, -7, -4, -5, -4, -2, -15, -37, -43, -42,
- -27, -5, 9, 27, 38, 27, 4, -14, -15, 6, 30, 61, 93, 90, 52, 16,
- 2, 1, 5, 11, 34, 64, 79, 71, 48, 35, 43, 61, 59, 46, 27, 1,
- -22, -33, -25, -9, 15, 37, 56, 54, 28, -10, -44, -58, -49, -27, -8, 20,
- 29, 0, -42, -66, -60, -34, -7, 16, 30, 15, -20, -50, -64, -49, -11, 21,
- 34, 34, 17, -7, -31, -29, 3, 43, 69, 78, 73, 45, 10, -20, -32, -33,
- -26, -12, -6, -18, -41, -44, -27, -6, 10, 17, 19, 18, -4, -49, -87, -108,
- -100, -84, -87, -93, -83, -67, -54, -45, -45, -35, -23, -13, 6, 17, 14, 1,
- -22, -40, -35, -18, 2, 28, 57, 63, 33, -7, -21, -4, 23, 57, 89, 102,
- 94, 68, 37, 8, -4, 4, 37, 71, 88, 79, 54, 46, 55, 62, 55, 53,
- 54, 46, 20, -14, -40, -41, -16, 15, 44, 60, 59, 30, -21, -61, -70, -54,
- -26, 10, 29, 19, -16, -49, -63, -58, -33, 4, 29, 26, -1, -33, -49, -50,
- -34, -9, 16, 34, 34, 9, -20, -25, -9, 13, 29, 54, 87, 91, 56, 11,
- -12, -11, -12, -20, -22, -17, -11, -12, -22, -25, -15, 3, 19, 19, 9, -11,
- -38, -62, -76, -92, -107, -109, -95, -68, -53, -49, -49, -58, -63, -48, -25, -5,
- 12, 12, -7, -36, -56, -56, -32, 8, 50, 64, 36, 6, -10, -15, -11, 9,
- 47, 94, 118, 100, 58, 14, -3, 3, 19, 44, 72, 83, 78, 75, 66, 53,
- 45, 52, 66, 70, 52, 22, -8, -36, -36, -14, 21, 63, 84, 63, 14, -29,
- -55, -54, -42, -12, 28, 40, 14, -24, -52, -58, -42, -22, 6, 19, 16, -5,
- -34, -49, -43, -24, -12, 2, 14, 22, 10, -10, -20, -16, 3, 28, 60, 72,
- 61, 42, 25, 1, -26, -44, -46, -31, -25, -26, -32, -30, -24, -12, -12, -15,
- 0, 6, -3, -23, -47, -79, -112, -128, -115, -84, -61, -45, -42, -51, -64, -68,
- -61, -33, 9, 29, 12, -28, -54, -64, -56, -30, 9, 36, 41, 34, 10, -18,
- -38, -29, 13, 70, 105, 106, 79, 48, 31, 12, -1, 12, 51, 78, 89, 87,
- 75, 66, 49, 44, 56, 73, 79, 66, 23, -23, -42, -39, -9, 31, 65, 75,
- 52, 7, -32, -54, -57, -30, 3, 24, 19, 2, -18, -39, -50, -39, -10, 8,
- 10, -2, -12, -18, -21, -29, -33, -16, 11, 28, 17, 1, -4, 3, -3, -6,
- 13, 42, 64, 67, 56, 29, 2, -21, -36, -42, -40, -25, -15, -10, -7, -10,
- -27, -38, -24, 2, 19, 14, -6, -44, -86, -115, -121, -109, -81, -45, -27, -36,
- -58, -76, -81, -53, -13, 11, 8, -11, -24, -40, -58, -62, -30, 11, 42, 44,
- 17, -15, -36, -38, -22, 15, 53, 84, 88, 73, 52, 19, -6, -9, 13, 44,
- 71, 88, 93, 79, 54, 42, 46, 67, 82, 79, 54, 20, -10, -28, -27, 0,
- 46, 70, 61, 29, 2, -18, -38, -45, -23, 7, 16, 10, -8, -22, -26, -30,
- -32, -23, -13, -2, 6, -6, -15, -16, -18, -20, -9, 0, 2, 11, 19, 17,
- -2, -21, -12, 14, 33, 50, 65, 61, 43, 19, -17, -44, -50, -42, -21, 1,
- 11, 1, -31, -56, -45, -22, -1, 17, 18, -4, -44, -95, -126, -123, -95, -56,
- -36, -41, -51, -59, -68, -60, -38, -15, 5, 14, 7, -17, -47, -61, -37, 1,
- 27, 33, 24, 7, -13, -30, -43, -26, 13, 47, 70, 74, 68, 48, 12, -19,
- -14, 14, 46, 74, 81, 75, 64, 52, 48, 56, 67, 82, 78, 44, 9, -12,
- -20, -8, 18, 41, 57, 46, 23, 0, -23, -33, -21, -10, -10, -2, 3, 5,
- -2, -19, -33, -32, -24, -16, -11, -14, -6, 7, -2, -20, -25, -16, -6, 6,
- 17, 27, 22, 2, -10, -11, 0, 24, 51, 68, 79, 65, 25, -19, -49, -48,
- -30, -9, 8, 10, -12, -40, -57, -57, -34, -1, 25, 24, -7, -56, -95, -111,
- -102, -84, -69, -57, -44, -42, -59, -74, -71, -47, -17, 0, 3, -6, -21, -37,
- -38, -27, -6, 15, 23, 22, 12, -4, -23, -32, -26, 1, 36, 63, 82, 78,
- 46, 12, -1, 2, 20, 41, 64, 81, 79, 66, 59, 61, 67, 75, 76, 66,
- 49, 27, 5, -7, 2, 24, 41, 44, 38, 28, 13, -5, -19, -21, -17, -11,
- -2, 4, 4, -2, -14, -28, -32, -27, -21, -16, -13, -1, 6, -4, -21, -25,
- -17, -7, 6, 0, 0, -4, -4, -5, -8, -4, 3, 8, 6, 1, 1, 2,
- 3, 3, -2, -7, -11, -10, -5, -2, 4, 6, 0, -2, -5, -4, -4, -9,
- -9, -7, -11, -11, -10, -7, 4, 0, -4, -4, -1, 4, 0, -4, -3, -5,
- -6, -5, -4, 4, -1, 2, 11, 5, -13, -20, -30, -49, -50, -34, -22, -33,
- -27, -20, -17, 0, 34, 70, 73, 42, 3, -26, -37, -25, -1, 25, 48, 71,
- 75, 44, 22, 45, 69, 57, 44, 52, 58, 24, -23, -41, -50, -58, -67, -82,
- -66, -29, -29, -41, -34, -19, -4, -4, -1, 20, 50, 56, 35, 12, 4, -8,
- -15, 4, 28, 44, 46, 34, 17, 2, 0, 11, 28, 42, 22, -28, -51, -45,
- -34, -39, -37, -19, -17, -30, -32, -18, -4, 9, 19, 38, 35, 3, -24, -35,
- -40, -23, -11, -25, -47, -52, -51, -58, -61, -52, -47, -37, -17, -5, -5, -16,
- -31, -24, -11, -1, -3, -23, -40, -48, -40, -12, 15, 25, 17, -5, -2, 14,
- 21, 15, -12, -26, -18, -2, 28, 48, 55, 52, 42, 35, 35, 42, 38, 36,
- 40, 53, 55, 52, 44, 36, 49, 57, 56, 57, 55, 50, 39, 27, 31, 30,
- 15, 11, 12, 6, 4, 14, 28, 23, 1, -6, -17, -35, -44, -41, -33, -22,
- -9, -6, -12, -15, -13, -27, -29, -7, 14, -5, -55, -71, -49, -33, -37, -46,
- -33, -18, -43, -89, -96, -65, -23, 2, 8, 20, 24, -11, -50, -51, -12, 15,
- 4, 1, 20, 47, 53, 43, 52, 77, 98, 114, 110, 100, 88, 53, 10, -29,
- -55, -71, -83, -77, -58, -55, -57, -52, -48, -47, -46, -12, 34, 59, 52, 25,
- -10, -33, -21, 18, 49, 54, 46, 18, 13, 30, 41, 48, 54, 53, 44, 24,
- 1, -13, -25, -43, -38, -28, -35, -55, -71, -64, -40, -13, 10, 24, 38, 41,
- 21, -1, -11, 1, 15, 7, -6, -13, -39, -57, -64, -51, -20, -12, -24, -37,
- -30, -4, 17, 21, 12, -7, -16, -15, -7, 6, 1, -20, -34, -30, -1, 32,
- 44, 36, 22, 25, 21, 6, 1, -2, -13, -5, 19, 28, 24, 12, 11, 16,
- 19, 38, 54, 49, 38, 28, 28, 39, 52, 49, 32, 25, 33, 45, 49, 39,
- 40, 46, 20, -9, -6, 6, 1, -22, -29, 10, 48, 33, -17, -51, -55, -44,
- -49, -50, -36, -33, -57, -84, -71, -21, 11, 13, 4, -1, -8, -32, -45, -32,
- -10, 2, -13, -37, -39, -42, -57, -65, -63, -36, -11, 10, 33, 22, -12, -34,
- -28, -12, 2, 8, 6, -2, -4, 0, 10, 22, 36, 57, 82, 104, 122, 127,
- 109, 70, 17, -28, -45, -36, -20, -33, -68, -102, -114, -103, -76, -45, -20, -7,
- -11, -10, -2, 6, 0, -14, -5, 30, 48, 29, 3, -8, 10, 39, 67, 86,
- 83, 59, 32, 17, 32, 46, 40, 11, -29, -48, -57, -68, -69, -57, -43, -26,
- -13, -2, 1, 1, 3, 4, 8, 21, 20, 11, 3, -2, -6, -26, -39, -33,
- -34, -36, -28, -23, -27, -28, -17, -1, 0, -6, -10, -9, -7, -12, -26, -44,
- -54, -38, -16, 0, 18, 27, 17, -3, -18, -3, 19, 11, -9, -7, 10, 14,
- 5, 5, 18, 29, 29, 12, 16, 38, 43, 14, 2, 24, 55, 59, 33, 17,
- 24, 44, 65, 75, 77, 55, 15, -16, -20, 6, 31, 27, 17, 18, 19, 17,
- 7, 0, -5, -20, -22, -25, -49, -69, -73, -58, -45, -29, -4, 9, -1, -23,
- -51, -52, -24, -2, 11, 12, -16, -51, -75, -77, -67, -59, -59, -54, -35, -15,
- -9, -9, -9, -7, -8, -12, -1, 15, 22, 10, -14, -34, -28, -14, 11, 64,
- 113, 127, 117, 97, 87, 84, 68, 50, 37, 36, 24, -15, -58, -78, -84, -71,
- -40, -14, -12, -34, -48, -41, -14, 20, 37, 35, 16, -6, 1, 14, 15, 20,
- 23, 24, 38, 58, 69, 57, 40, 54, 73, 75, 65, 40, -3, -49, -68, -56,
- -42, -42, -53, -59, -44, -23, -9, -3, -11, -18, -13, -11, -5, 3, 13, 4,
- -25, -39, -22, -14, -16, -27, -38, -37, -42, -55, -51, -21, 8, 10, -8, -12,
- -4, -10, -39, -55, -38, -13, -4, -11, -15, -3, 15, 12, 2, 11, 28, 34,
- 15, -5, 3, 11, 6, 12, 25, 25, 13, 10, 15, 27, 48, 55, 38, 23,
- 17, 23, 32, 23, 32, 57, 75, 75, 52, 22, 10, 5, 12, 28, 33, 23,
- 2, -14, -4, 19, 30, 25, 15, 1, -27, -64, -78, -67, -49, -45, -48, -42,
- -31, -25, -40, -50, -39, -18, -4, 13, 19, 12, -10, -43, -59, -53, -47, -54,
- -61, -51, -20, -2, -12, -23, -25, -18, 5, 33, 51, 45, 16, -16, -46, -53,
- -38, -6, 33, 57, 74, 81, 75, 77, 89, 105, 114, 110, 83, 39, -6, -25,
- -28, -39, -48, -52, -55, -59, -67, -67, -57, -42, -23, -3, 10, 3, -19, -33,
- -30, -8, 20, 23, 2, -18, -17, 12, 40, 58, 65, 65, 66, 71, 64, 54,
- 38, 1, -41, -62, -47, -26, -31, -49, -55, -42, -21, -17, -19, -10, -2, -3,
- -10, -13, 2, 13, -10, -38, -27, 3, 8, -18, -46, -61, -65, -53, -36, -18,
- -5, -6, -14, -22, -18, -12, -19, -29, -28, -21, -10, -15, -24, -18, -4, 16,
- 23, 17, 14, 10, 9, 13, 15, 28, 35, 19, 4, 2, -2, 9, 34, 62,
- 66, 43, 13, -2, 15, 42, 50, 48, 51, 56, 56, 45, 44, 45, 48, 40,
- 33, 31, 27, 10, -10, -4, 16, 41, 52, 48, 31, -1, -36, -56, -50, -27,
- -14, -25, -43, -60, -67, -47, -31, -38, -47, -40, -17, 13, 32, 28, -10, -50,
- -68, -62, -40, -21, -20, -33, -58, -72, -63, -45, -28, -11, 18, 48, 42, 15,
- -14, -43, -54, -40, -15, 4, 2, -5, 0, 20, 55, 91, 113, 120, 109, 89,
- 77, 63, 43, 26, 20, 12, -13, -47, -69, -68, -53, -49, -49, -36, -28, -27,
- -27, -28, -12, 5, 1, -9, -2, 14, 10, -25, -39, -6, 21, 35, 41, 53,
- 73, 82, 74, 64, 54, 39, 9, -23, -37, -30, -22, -30, -52, -62, -54, -32,
- -9, 2, 5, -3, -17, -25, -17, -1, 13, 8, -7, -12, -7, -7, -21, -40,
- -51, -51, -38, -21, -16, -22, -29, -33, -23, -10, -2, -9, -24, -33, -33, -29,
- -21, -8, 3, 2, -10, -18, -11, 8, 26, 32, 27, 21, 14, 7, 1, 3,
- 12, 22, 35, 45, 43, 29, 13, 10, 20, 37, 54, 59, 45, 28, 28, 37,
- 48, 55, 60, 60, 43, 17, 0, -3, 9, 24, 31, 31, 28, 28, 26, 14,
- -5, -22, -31, -30, -21, -7, -8, -34, -63, -82, -80, -63, -45, -28, -14, -5,
- 3, 2, -11, -27, -39, -33, -11, 2, -8, -39, -73, -95, -91, -54, -8, 19,
- 16, 4, 5, 14, 14, 2, -8, -14, -19, -33, -45, -38, -19, 2, 21, 54,
- 93, 106, 90, 74, 80, 97, 98, 76, 52, 34, 10, -18, -37, -36, -27, -35,
- -52, -62, -56, -44, -39, -37, -29, -17, -8, -2, 3, 4, -4, -16, -27, -32,
- -19, 1, 19, 41, 60, 70, 71, 67, 64, 61, 53, 38, 14, -8, -21, -29,
- -34, -38, -39, -29, -15, 0, 5, -5, -19, -25, -16, 5, 19, 17, 6, -3,
- -7, 0, -1, 1, -2, -5, 0, 0, 2, 0, -3, -2, 0, 1, 0, -2,
- -2, -2, 0, 3, 3, -2, -5, -1, -1, -1, -4, 3, 9, 1, -1, -2,
- -11, -7, 1, 9, 11, 8, -4, -11, -12, -9, -4, 18, 15, 14, 1, -22,
- -29, -14, 3, 30, 29, 14, -2, -35, -43, -11, 13, 36, 42, 15, -16, -49,
- -44, -10, 28, 47, 38, 11, -25, -66, -39, 4, 36, 58, 33, -3, -44, -65,
- -29, 19, 52, 54, 23, -13, -59, -65, -15, 32, 69, 49, 8, -30, -74, -51,
- 3, 43, 71, 40, -5, -48, -77, -31, 16, 57, 67, 24, -15, -67, -72, -12,
- 36, 66, 59, 5, -31, -80, -51, 3, 49, 75, 37, -2, -59, -81, -28, 20,
- 67, 66, 22, -23, -76, -65, -10, 41, 78, 48, 4, -36, -85, -47, 6, 59,
- 80, 31, -8, -69, -82, -22, 29, 73, 63, 17, -31, -81, -63, -1, 47, 79,
- 47, 3, -56, -90, -40, 19, 75, 73, 28, -25, -86, -74, -10, 48, 85, 56,
- 6, -51, -93, -48, 11, 67, 86, 33, -11, -78, -87, -29, 36, 89, 66, 13,
- -38, -91, -60, 2, 50, 83, 48, 0, -56, -90, -41, 16, 71, 78, 30, -17,
- -80, -75, -20, 31, 82, 62, 15, -32, -85, -66, -7, 48, 84, 50, 4, -53,
- -87, -44, 8, 62, 78, 35, -8, -65, -83, -30, 23, 70, 71, 24, -20, -76,
- -75, -12, 32, 73, 62, 15, -30, -85, -62, -2, 41, 76, 51, 9, -39, -86,
- -52, 1, 45, 79, 46, 8, -49, -89, -46, 3, 54, 80, 43, 7, -55, -83,
- -50, 0, 53, 76, 54, 11, -52, -83, -55, 0, 40, 67, 58, 22, -32, -79,
- -67, -11, 28, 63, 52, 37, -9, -70, -63, -28, 10, 42, 49, 53, 8, -46,
- -64, -41, 1, 22, 38, 51, 39, -16, -63, -46, -23, 5, 33, 38, 48, 14,
- -42, -57, -29, -5, 22, 37, 40, 28, -23, -53, -39, -10, 14, 30, 40, 31,
- -1, -48, -40, -18, 11, 19, 31, 26, 14, -20, -50, -25, -5, 11, 31, 30,
- 14, 0, -35, -39, -4, -1, 19, 27, 17, 9, -10, -39, -21, -8, 9, 24,
- 26, 13, -5, -19, -30, -12, -1, 17, 25, 16, 3, -19, -26, -13, -6, 17,
- 22, 20, 5, -16, -32, -19, -1, 23, 27, 23, 4, -30, -33, -23, -1, 35,
- 35, 24, -2, -41, -45, -21, 9, 45, 41, 22, -12, -50, -46, -18, 28, 55,
- 45, 10, -27, -78, -42, 0, 53, 66, 32, -1, -61, -74, -28, 27, 64, 64,
- 24, -28, -80, -66, -15, 53, 84, 48, 5, -59, -94, -41, 17, 75, 80, 26,
- -21, -91, -79, -12, 48, 87, 55, 10, -58, -96, -46, 9, 80, 81, 30, -23,
- -84, -80, -15, 49, 90, 49, 9, -57, -95, -45, 17, 76, 79, 26, -20, -91,
- -75, -18, 52, 90, 52, 6, -59, -92, -41, 15, 68, 80, 31, -21, -87, -76,
- -13, 45, 87, 49, 11, -60, -94, -35, 14, 80, 68, 22, -23, -89, -66, -7,
- 47, 93, 44, -8, -61, -95, -31, 24, 86, 75, 10, -35, -96, -66, -1, 61,
- 100, 44, -12, -77, -105, -33, 32, 97, 92, 16, -44, -111, -90, -5, 65, 121,
- 65, -3, -80, -123, -59, 17, 98, 111, 46, -25, -112, -109, -33, 42, 112, 90,
- 30, -55, -115, -84, -17, 66, 105, 71, 13, -73, -113, -61, 0, 77, 96, 56,
- 4, -80, -108, -50, 8, 78, 93, 47, 3, -88, -98, -40, 7, 65, 76, 53,
- 18, -71, -90, -44, 0, 39, 57, 43, 34, -19, -69, -54, -19, 18, 32, 31,
- 34, 7, -40, -36, -21, -1, 12, 12, 25, 27, -9, -32, -14, -14, 2, 0,
- 1, 20, 19, -2, -13, -11, -18, -12, -2, 18, 24, 12, -2, -14, -19, -19,
- -12, 18, 24, 22, -2, -15, -32, -20, 3, 22, 26, 17, -13, -31, -27, -13,
- 17, 33, 32, 5, -29, -47, -29, 2, 33, 42, 32, -6, -53, -52, -24, 22,
- 51, 41, 27, -32, -74, -45, 0, 45, 59, 33, -1, -62, -66, -31, 26, 73,
- 49, 17, -42, -80, -42, -8, 63, 72, 28, -10, -75, -72, -23, 32, 88, 47,
- 13, -56, -93, -38, 10, 76, 69, 26, -20, -96, -66, -10, 48, 90, 47, 0,
- -69, -103, -29, 25, 87, 73, 18, -35, -104, -68, -2, 61, 93, 47, -5, -83,
- -98, -31, 30, 92, 68, 17, -39, -97, -63, -5, 64, 88, 35, -9, -74, -86,
- -22, 31, 85, 54, 13, -44, -93, -46, 9, 65, 75, 23, -17, -75, -78, -15,
- 39, 84, 54, 3, -52, -96, -46, 12, 71, 90, 29, -18, -89, -87, -26, 36,
- 86, 72, 26, -37, -106, -77, -12, 45, 99, 68, 22, -46, -108, -73, -10, 43,
- 87, 69, 19, -27, -92, -79, -12, 27, 63, 57, 26, 4, -53, -75, -35, 12,
- 33, 37, 31, 26, -9, -53, -39, -16, 6, 20, 23, 22, 13, -8, -22, -23,
- -18, -3, 9, 25, 19, 4, -8, -20, -17, -10, 6, 16, 17, 13, -8, -34,
- -21, -6, 17, 33, 23, 6, -32, -51, -23, 11, 36, 46, 31, -11, -46, -65,
- -31, 15, 59, 55, 28, -20, -73, -64, -26, 42, 78, 51, 14, -53, -85, -48,
- -4, 70, 80, 38, -16, -80, -76, -32, 39, 90, 58, 19, -59, -99, -50, 14,
- 71, 75, 36, -21, -94, -70, -23, 51, 88, 53, 9, -68, -97, -40, 16, 83,
- 73, 29, -33, -100, -61, -13, 58, 87, 41, 0, -74, -81, -35, 24, 87, 55,
- 20, -41, -88, -58, 0, 69, 73, 34, -5, -86, -75, -20, 38, 79, 49, 13,
- -48, -90, -39, 2, 71, 68, 31, -16, -84, -67, -15, 38, 79, 42, 12, -50,
- -85, -37, 2, 62, 71, 34, -5, -83, -75, -24, 27, 82, 51, 27, -30, -88,
- -54, -15, 44, 73, 50, 16, -49, -81, -47, -6, 38, 58, 50, 27, -31, -69,
- -52, -13, 15, 36, 45, 33, -5, -41, -44, -23, 2, 14, 27, 33, 10, -25,
- -20, -18, -6, 1, -1, 17, 22, 3, -13, -10, -17, -13, -6, 13, 24, 15,
- 1, -11, -19, -19, -16, 12, 24, 24, 3, -12, -29, -26, -1, 18, 27, 19,
- -4, -31, -28, -19, 11, 30, 35, 12, -21, -46, -35, -6, 28, 42, 36, 5,
- -46, -57, -31, 10, 50, 43, 33, -16, -71, -55, -9, 35, 62, 38, 10, -51,
- -71, -40, 11, 69, 58, 24, -26, -81, -50, -18, 48, 79, 37, 1, -62, -81,
- -32, 16, 84, 59, 20, -37, -96, -50, -2, 63, 78, 33, -4, -85, -80, -20,
- 33, 88, 59, 10, -50, -107, -47, 14, 75, 85, 27, -19, -95, -83, -15, 47,
- 94, 60, 8, -66, -105, -46, 15, 83, 81, 26, -23, -91, -76, -18, 48, 92,
- 47, 1, -59, -94, -36, 18, 78, 66, 19, -27, -91, -60, -3, 53, 80, 35,
- -8, -62, -86, -28, 27, 79, 66, 13, -38, -94, -62, 1, 56, 95, 42, -6,
- -75, -96, -39, 22, 80, 80, 36, -20, -97, -92, -24, 30, 93, 79, 32, -27,
- -102, -87, -22, 31, 81, 79, 29, -14, -81, -91, -25, 19, 56, 63, 31, 11,
- -39, -77, -47, 3, 31, 37, 33, 27, 3, -48, -46, -20, 0, 18, 22, 23,
- 16, -3, -20, -19, -15, -4, 2, 8, 5, 0, 0, 0, 0, 2, 2, 5,
- 9, 12, 14, 12, 7, 6, 4, 0, -1, -1, 1, -2, -2, -11, -17, -32,
- -41, -49, -55, -58, -61, -61, -65, -61, -57, -47, -37, -27, -22, -15, -5, 6,
- 12, 16, 21, 27, 28, 32, 33, 35, 41, 44, 45, 47, 50, 54, 57, 56,
- 53, 53, 54, 50, 50, 52, 54, 56, 52, 53, 54, 50, 49, 46, 43, 38,
- 33, 27, 19, 8, 2, -11, -20, -27, -29, -30, -32, -35, -42, -52, -57, -57,
- -59, -48, -40, -27, -13, 4, 13, 20, 18, 14, 11, 7, 3, -1, -3, -10,
- -11, -20, -28, -46, -60, -72, -82, -92, -97, -97, -97, -94, -90, -81, -71, -61,
- -55, -55, -53, -47, -38, -29, -23, -11, -6, -3, 1, 2, 5, 6, 3, 3,
- 5, 15, 24, 28, 30, 30, 35, 37, 36, 39, 39, 44, 47, 48, 56, 62,
- 73, 84, 91, 96, 95, 91, 85, 76, 72, 63, 55, 47, 44, 43, 41, 38,
- 31, 19, 7, 0, -9, -7, -4, 8, 22, 40, 54, 67, 71, 70, 64, 56,
- 45, 32, 24, 15, 12, 3, -3, -21, -42, -66, -84, -102, -117, -124, -128, -127,
- -124, -118, -107, -96, -86, -86, -88, -86, -80, -70, -63, -50, -40, -33, -25, -23,
- -20, -18, -18, -21, -25, -22, -14, -8, -3, -3, -1, 1, 0, 1, -3, -1,
- 2, 4, 13, 24, 35, 49, 59, 67, 70, 69, 68, 59, 54, 46, 40, 31,
- 29, 27, 25, 23, 20, 12, -1, -9, -19, -22, -21, -11, 3, 23, 41, 60,
- 71, 76, 73, 71, 65, 56, 50, 44, 42, 35, 33, 24, 9, -13, -31, -48,
- -65, -76, -83, -83, -82, -77, -69, -59, -46, -40, -40, -41, -38, -30, -24, -13,
- -2, 8, 17, 22, 24, 25, 23, 20, 13, 9, 11, 15, 19, 16, 12, 9,
- 4, 1, -6, -10, -11, -14, -12, -5, 3, 15, 26, 35, 40, 41, 41, 35,
- 28, 19, 12, 3, -2, -6, -7, -10, -13, -19, -31, -39, -50, -56, -58, -52,
- -41, -22, -3, 18, 34, 46, 48, 47, 45, 38, 32, 26, 24, 20, 19, 15,
- 5, -14, -32, -49, -65, -79, -88, -91, -91, -88, -82, -75, -63, -52, -47, -46,
- -46, -38, -31, -21, -8, 4, 17, 26, 31, 36, 39, 42, 40, 35, 36, 39,
- 47, 48, 45, 43, 38, 36, 30, 24, 22, 19, 18, 23, 29, 40, 50, 61,
- 68, 72, 74, 71, 66, 57, 50, 40, 32, 24, 21, 16, 12, 7, -3, -14,
- -26, -38, -45, -46, -43, -31, -16, 3, 18, 33, 39, 39, 36, 31, 22, 13,
- 8, 3, -1, -4, -9, -24, -42, -60, -77, -94, -107, -115, -119, -120, -116, -112,
- -103, -91, -81, -78, -80, -75, -69, -61, -51, -39, -25, -13, -5, 2, 8, 14,
- 17, 16, 15, 16, 24, 31, 32, 32, 29, 29, 27, 22, 21, 20, 19, 22,
- 26, 35, 46, 59, 70, 77, 83, 85, 84, 79, 74, 66, 59, 50, 46, 41,
- 38, 35, 29, 21, 11, 0, -9, -14, -16, -11, 0, 16, 30, 48, 58, 62,
- 61, 58, 51, 40, 31, 25, 19, 15, 13, 4, -11, -28, -44, -61, -76, -87,
- -95, -100, -100, -99, -95, -86, -75, -68, -69, -68, -67, -62, -56, -49, -38, -27,
- -19, -13, -9, -3, 2, 1, -1, -3, 0, 7, 10, 10, 6, 5, 4, 0,
- -4, -5, -7, -7, -7, -2, 5, 16, 27, 36, 44, 49, 52, 50, 46, 40,
- 35, 26, 22, 18, 15, 15, 13, 9, 4, -5, -14, -19, -23, -21, -14, 0,
- 15, 33, 49, 60, 63, 63, 61, 53, 44, 38, 32, 27, 27, 23, 14, 0,
- -14, -29, -44, -58, -67, -74, -76, -76, -73, -67, -55, -45, -41, -41, -41, -39,
- -35, -30, -23, -12, -3, 4, 9, 14, 20, 21, 20, 17, 15, 19, 24, 26,
- 24, 21, 20, 18, 12, 9, 6, 3, 0, 1, 4, 11, 21, 30, 38, 43,
- 47, 48, 45, 38, 32, 23, 15, 9, 5, 3, 1, -2, -5, -13, -22, -30,
- -37, -41, -40, -30, -18, -3, 15, 30, 38, 41, 41, 37, 27, 19, 12, 6,
- 3, 2, -2, -13, -25, -39, -53, -67, -78, -88, -92, -92, -91, -86, -77, -63,
- -54, -50, -48, -47, -43, -38, -32, -23, -11, -1, 6, 11, 19, 25, 27, 26,
- 24, 26, 31, 36, 38, 36, 37, 37, 34, 32, 29, 27, 24, 22, 23, 27,
- 35, 45, 53, 61, 67, 70, 71, 66, 60, 51, 42, 34, 28, 24, 21, 18,
- 16, 11, 2, -8, -16, -24, -28, -25, -17, -5, 10, 26, 39, 45, 47, 45,
- 37, 27, 18, 9, 3, 0, -2, -10, -22, -36, -51, -67, -81, -93, -102, -107,
- -108, -107, -102, -90, -78, -71, -67, -66, -63, -59, -56, -49, -39, -28, -19, -13,
- -6, 1, 7, 8, 6, 5, 8, 14, 19, 19, 19, 20, 20, 19, 16, 15,
- 13, 12, 11, 13, 20, 30, 39, 49, 57, 63, 68, 68, 65, 58, 51, 43,
- 37, 32, 29, 27, 26, 24, 19, 11, 2, -5, -12, -14, -9, 0, 13, 30,
- 46, 56, 62, 65, 61, 53, 44, 35, 26, 22, 20, 15, 6, -6, -20, -36,
- -51, -66, -78, -87, -91, -92, -92, -85, -74, -65, -58, -56, -55, -52, -50, -46,
- -40, -30, -20, -14, -8, -2, 5, 7, 6, 3, 2, 5, 10, 11, 10, 9,
- 9, 8, 5, 2, 0, -2, -5, -5, -3, 5, 14, 23, 32, 39, 46, 50,
- 49, 45, 38, 31, 24, 17, 14, 11, 10, 9, 7, 2, -5, -12, -20, -25,
- -25, -19, -8, 7, 24, 40, 50, 58, 60, 56, 49, 41, 31, 24, 22, 20,
- 15, 6, -5, -19, -34, -48, -61, -72, -79, -83, -85, -81, -72, -62, -52, -47,
- -44, -41, -39, -35, -31, -24, -13, -5, 1, 7, 14, 20, 22, 21, 19, 18,
- 22, 25, 25, 24, 23, 23, 20, 17, 15, 12, 10, 7, 5, 9, 16, 24,
- 33, 40, 47, 53, 56, 54, 48, 41, 33, 25, 20, 15, 11, 9, 8, 5,
- -2, -10, -19, -27, -32, -31, -25, -15, 0, 17, 30, 40, 46, 46, 42, 35,
- 25, 15, 10, 9, 5, -2, -11, -23, -37, -52, -65, -79, -89, -95, -99, -100,
- -95, -85, -74, -65, -60, -55, -52, -48, -44, -40, -29, -18, -10, -4, 4, 12,
- 18, 20, 19, 17, 20, 24, 27, 27, 26, 26, 25, 23, 21, 19, 17, 15,
- 12, 13, 17, 25, 34, 41, 49, 57, 62, 65, 63, 57, 51, 42, 35, 30,
- 25, 22, 21, 19, 15, 8, 0, -9, -17, -21, -20, -14, -3, 13, 26, 38,
- 48, 53, 52, 47, 39, 28, 19, 15, 13, 8, 0, -10, -22, -37, -51, -65,
- -79, -88, -95, -100, -99, -94, -84, -74, -67, -61, -58, -55, -51, -49, -43, -33,
- -23, -17, -10, -2, 6, 10, 11, 9, 9, 12, 15, 17, 16, 16, 16, 14,
- 12, 11, 9, 8, 5, 3, 4, 10, 18, 26, 34, 42, 50, 57, 59, 57,
- 52, 45, 38, 32, 27, 23, 21, 20, 19, 14, 8, 1, -9, 2, 5, 7,
- 8, -1, 6, 15, 1, 20, 28, 1, 37, 41, 31, 29, 27, 61, 40, -12,
- 38, 52, -16, -20, -1, -23, -48, -56, -63, -61, -77, -100, -88, -76, -103, -113,
- -98, -103, -118, -120, -108, -107, -104, -110, -118, -104, -109, -128, -107, -83, -106, -86,
- -94, -100, -77, -113, -88, -43, -77, -46, -44, -69, -34, -54, -39, 4, -30, 11,
- 18, -25, 20, 16, 10, 52, 35, 52, 74, 33, 55, 74, 59, 70, 81, 85,
- 91, 81, 72, 89, 94, 82, 80, 99, 100, 85, 86, 91, 100, 91, 81, 91,
- 102, 83, 74, 92, 95, 63, 62, 75, 71, 63, 39, 54, 74, 15, 1, 31,
- 6, -5, -13, -20, -8, -44, -59, -38, -69, -73, -67, -86, -90, -68, -73, -77,
- -49, -82, -70, -43, -76, -27, 0, -29, 22, 25, -5, 44, 45, 29, 66, 71,
- 49, 84, 92, 73, 92, 74, 72, 91, 37, 48, 99, 47, 31, 44, 36, 33,
- -5, -11, 26, 6, -33, -22, -6, -32, -55, -44, -45, -52, -63, -73, -55, -51,
- -77, -79, -61, -73, -91, -83, -70, -77, -74, -82, -85, -68, -88, -98, -57, -67,
- -77, -58, -75, -66, -64, -78, -33, -37, -50, -19, -47, -38, -23, -41, 3, 6,
- -7, 30, 0, -4, 24, 15, 31, 45, 44, 66, 44, 34, 58, 54, 59, 67,
- 71, 87, 78, 60, 73, 84, 78, 76, 86, 95, 89, 76, 85, 94, 89, 73,
- 82, 99, 85, 66, 75, 93, 75, 50, 56, 69, 59, 31, 31, 61, 29, -15,
- 15, 5, -15, -14, -36, -25, -29, -69, -55, -53, -82, -78, -76, -95, -88, -69,
- -80, -65, -63, -86, -58, -67, -59, -12, -28, -9, 29, -8, 13, 44, 22, 44,
- 68, 53, 62, 91, 74, 81, 89, 64, 84, 78, 35, 78, 86, 44, 43, 47,
- 45, 22, -5, 17, 21, -16, -24, -14, -14, -34, -50, -40, -36, -63, -71, -58,
- -60, -69, -78, -78, -67, -81, -98, -78, -71, -89, -85, -84, -86, -82, -99, -82,
- -60, -76, -75, -74, -76, -71, -86, -68, -37, -51, -34, -41, -57, -37, -51, -31,
- -7, -17, -3, 1, 7, 22, 31, 46, 57, 41, 43, 56, 63, 62, 68, 85,
- 86, 80, 84, 92, 96, 93, 93, 104, 105, 96, 99, 108, 106, 102, 98, 102,
- 111, 99, 87, 106, 110, 85, 80, 88, 89, 79, 68, 70, 81, 48, 25, 39,
- 32, 18, 9, 12, 0, -29, -31, -38, -60, -52, -63, -79, -71, -66, -62, -59,
- -62, -74, -72, -73, -81, -43, -21, -28, 8, 10, -10, 16, 28, 27, 42, 50,
- 47, 66, 76, 68, 81, 73, 67, 72, 39, 40, 67, 41, 23, 25, 22, 12,
- -16, -22, -5, -27, -51, -44, -45, -57, -68, -73, -71, -74, -91, -89, -84, -90,
- -97, -98, -98, -102, -105, -108, -103, -97, -105, -109, -101, -107, -113, -106, -92, -87,
- -90, -92, -92, -92, -100, -92, -57, -56, -54, -40, -59, -58, -54, -61, -23, -9,
- -12, 16, 0, -14, 4, 5, 17, 32, 41, 57, 55, 43, 54, 66, 67, 68,
- 84, 89, 87, 87, 91, 98, 100, 96, 104, 109, 105, 103, 108, 111, 109, 105,
- 105, 113, 111, 99, 102, 115, 104, 88, 90, 97, 93, 80, 75, 86, 75, 37,
- 40, 43, 33, 20, 20, -14, -26, -36, -53, -52, -65, -75, -75, -69, -69, -69,
- -74, -77, -76, -74, -59, -34, -26, -9, 9, 5, 13, 32, 39, 42, 53, 58,
- 61, 73, 77, 77, 73, 61, 57, 46, 29, 37, 37, 17, 6, 2, -10, -27,
- -38, -41, -46, -58, -68, -69, -75, -85, -89, -92, -97, -101, -103, -106, -107, -108,
- -112, -111, -112, -115, -115, -115, -113, -111, -116, -115, -112, -116, -117, -110, -101, -98,
- -101, -101, -98, -101, -101, -86, -69, -65, -59, -57, -62, -58, -54, -39, -19, -12,
- 1, 7, -1, 5, 16, 24, 36, 46, 58, 64, 61, 64, 74, 79, 81, 90,
- 96, 97, 100, 100, 104, 108, 107, 111, 114, 113, 115, 115, 115, 118, 117, 116,
- 118, 119, 116, 115, 116, 117, 111, 104, 105, 107, 99, 93, 95, 91, 71, 57,
- 53, 47, 38, 29, 23, 14, -11, -28, -38, -49, -58, -67, -73, -80, -84, -84,
- -83, -82, -80, -78, -74, -67, -56, -42, -29, -16, -4, 7, 18, 29, 40, 49,
- 57, 64, 70, 74, 78, 79, 77, 72, 67, 60, 53, 48, 42, 33, 23, 14,
- 4, -6, -16, -24, -32, -40, -48, -55, -61, -68, -74, -78, -83, -87, -91, -94,
- -96, -99, -101, -103, -104, -106, -107, -107, -107, -107, -107, -108, -107, -107, -107, -105,
- -101, -98, -96, -94, -93, -91, -87, -82, -74, -67, -62, -57, -54, -49, -43, -35,
- -25, -16, -7, -1, 4, 10, 17, 25, 33, 41, 49, 55, 59, 63, 69, 74,
- 78, 83, 88, 91, 93, 96, 98, 100, 102, 104, 106, 107, 107, 108, 108, 109,
- 109, 108, 108, 108, 107, 105, 104, 102, 99, 94, 91, 87, 83, 78, 73, 66,
- 56, 46, 37, 28, 19, 9, 0, -11, -23, -35, -45, -55, -64, -71, -78, -83,
- -85, -84, -83, -81, -79, -75, -70, -61, -49, -36, -23, -10, 2, 12, 24, 35,
- 45, 53, 61, 67, 72, 76, 79, 78, 75, 70, 65, 58, 52, 46, 39, 29,
- 20, 11, 1, -9, -18, -26, -34, -42, -50, -56, -63, -69, -74, -79, -83, -88,
- -91, -94, -96, -98, -101, -102, -104, -105, -106, -106, -106, -106, -106, -106, -106, -106,
- -105, -102, -98, -96, -94, -92, -90, -88, -84, -77, -70, -64, -59, -55, -51, -45,
- -38, -29, -20, -11, -4, 2, 7, 13, 21, 29, 37, 44, 51, 56, 60, 65,
- 70, 75, 80, 84, 88, 91, 93, 96, 98, 100, 102, 104, 105, 106, 107, 107,
- 108, 108, 107, 107, 107, 106, 104, 103, 101, 99, 95, 91, 87, 83, 78, 73,
- 67, 59, 49, 39, 30, 21, 12, 3, -8, -19, -31, -41, -51, -60, -68, -75,
- -81, -84, -85, -84, -82, -80, -77, -73, -65, -55, -42, -29, -16, -4, 7, 18,
- 29, 40, 49, 57, 64, 70, 74, 78, 79, 77, 73, 68, 62, 56, 50, 44,
- 36, 26, 17, 7, -3, -12, -20, -28, -36, -44, -51, -58, -64, -70, -75, -79,
- -84, -88, -91, -93, -96, -98, -100, -102, -103, -105, -105, -105, -105, -105, -105, -105,
- -105, -104, -102, -99, -96, -94, -92, -90, -88, -85, -79, -72, -66, -61, -56, -52,
- -47, -41, -33, -24, -15, -8, -1, 4, 10, 17, 24, 32, 40, 47, 53, 57,
- 62, 67, 72, 77, 81, 85, 89, 91, 94, 96, 98, 100, 102, 104, 105, 105,
- 106, 106, 107, 106, 106, 106, 105, 104, 102, 101, 99, 95, 91, 87, 83, 79,
- 74, 68, 61, 52, 42, 33, 24, 15, 5, -5, -15, -27, -38, -48, -57, -66,
- -72, -79, -83, -85, -85, -83, -81, -79, -75, -69, -60, -48, -35, -23, -10, 2,
- 13, 24, 35, 45, 54, 61, 67, 72, 77, 78, 79, 76, 72, 66, 60, 54,
- 49, 41, 32, 23, 12, 3, -4, -17, -15, 1, -1, 0, 0, 1, 3, 5,
- 9, 13, 18, 24, 32, 38, 32, 18, -9, -48, -73, -41, 2, -3, -24, -34,
- -44, -72, -111, -124, -62, 40, 40, -51, -35, 45, 46, -22, -79, 35, 78, -47,
- -98, -88, -69, -57, -44, -31, -17, -9, -3, 6, 41, 85, 43, -91, -128, -65,
- -25, -21, -19, -12, 2, 16, 29, 39, 49, 48, 10, -69, -47, 50, 8, -52,
- -44, 5, 21, -40, -42, 33, 79, 66, 38, 24, 25, 26, 18, 21, 70, 117,
- 98, 28, -1, 20, 22, 0, 1, 9, -10, -49, -33, 39, 68, 39, -5, -17,
- -58, -76, 78, 104, 17, 6, -23, -43, -13, 58, 85, 43, 21, 35, 46, 31,
- 22, 35, 14, -48, -74, -38, 6, 10, -8, -17, -24, -37, -60, -69, -41, 15,
- 27, -21, -26, 18, 28, -1, -41, 5, 51, -9, -51, -48, -38, -31, -24, -16,
- -8, -2, 1, 6, 23, 52, 41, -39, -83, -50, -19, -13, -12, -8, 1, 10,
- 20, 27, 34, 35, 15, -40, -46, 27, 16, -35, -38, -6, 19, -18, -35, 17,
- 61, 55, 33, 21, 22, 25, 21, 18, 52, 98, 92, 31, -5, 9, 17, -1,
- -2, 7, -7, -47, -43, 24, 62, 39, -3, -20, -48, -88, 46, 113, 25, 4,
- -20, -45, -25, 42, 82, 47, 19, 28, 42, 32, 18, 30, 19, -39, -77, -51,
- -4, 10, -6, -18, -25, -37, -57, -70, -50, 4, 26, -15, -33, 9, 27, 6,
- -38, -12, 50, 6, -47, -50, -40, -32, -25, -17, -10, -3, 0, 4, 17, 45,
- 47, -23, -82, -60, -24, -14, -13, -10, -2, 7, 16, 24, 30, 33, 18, -32,
- -56, 13, 23, -31, -41, -15, 19, -6, -35, 4, 52, 55, 35, 21, 22, 25,
- 22, 15, 41, 89, 94, 38, -5, 4, 16, 2, -2, 7, -4, -41, -48, 12,
- 58, 43, 2, -20, -38, -89, 14, 118, 38, 3, -15, -43, -32, 28, 78, 53,
- 19, 24, 40, 34, 18, 26, 23, -28, -75, -61, -14, 10, -2, -16, -24, -34,
- -53, -68, -55, -7, 25, -8, -36, 1, 27, 12, -31, -26, 45, 22, -39, -50,
- -41, -32, -25, -17, -10, -4, 0, 3, 13, 38, 51, -5, -77, -69, -31, -15,
- -14, -11, -4, 5, 13, 21, 27, 31, 20, -24, -61, -3, 28, -23, -43, -23,
- 15, 5, -32, -6, 43, 53, 36, 22, 21, 26, 24, 14, 32, 79, 95, 46,
- -3, 0, 15, 5, -1, 7, -1, -36, -52, 2, 53, 46, 7, -18, -30, -84,
- -15, 114, 55, 4, -10, -40, -37, 15, 72, 59, 22, 20, 36, 36, 19, 23,
- 26, -18, -70, -68, -25, 7, 2, -13, -22, -32, -49, -65, -59, -16, 22, -1,
- -36, -8, 25, 17, -22, -35, 34, 36, -29, -48, -42, -32, -25, -18, -10, -4,
- 0, 3, 10, 32, 52, 11, -67, -76, -38, -16, -13, -11, -6, 3, 11, 19,
- 25, 30, 22, -15, -62, -19, 30, -14, -43, -30, 9, 13, -25, -15, 33, 51,
- 37, 23, 21, 26, 26, 15, 24, 68, 94, 54, 0, -3, 13, 8, 1, 8,
- 2, -30, -53, -8, 47, 49, 13, -16, -25, -75, -41, 102, 73, 6, -5, -36,
- -40, 2, 65, 64, 25, 18, 33, 37, 21, 21, 27, -8, -63, -73, -36, 2,
- 5, -10, -21, -30, -45, -62, -61, -25, 17, 5, -35, -17, 21, 21, -13, -39,
- 20, 46, -16, -46, -42, -32, -25, -17, -10, -4, 0, 3, 8, 27, 50, 25,
- -54, -81, -46, -19, -13, -12, -7, 1, 9, 17, 23, 28, 23, -8, -59, -35,
- 27, -5, -42, -35, 2, 20, -16, -20, 24, 47, 38, 24, 21, 27, 28, 17,
- 18, 58, 91, 62, 5, -6, 10, 10, 3, 9, 5, -24, -52, -17, 40, 50,
- 18, -13, -22, -64, -60, 83, 90, 12, -3, -31, -41, -8, 55, 67, 30, 17,
- 30, 37, 24, 19, 27, 1, -54, -75, -46, -4, 7, -7, -18, -28, -41, -58,
- -61, -32, 11, 10, -31, -24, 17, 23, -4, -39, 5, 52, -2, -42, -42, -32,
- -25, -17, -10, -4, 0, 3, 6, 22, 47, 35, -38, -82, -55, -23, -13, -12,
- -8, -1, 7, 15, 21, 26, 23, -1, -53, -48, 20, 5, -39, -39, -6, 22,
- -5, -22, 14, 43, 38, 25, 21, 27, 29, 19, 15, 47, 86, 68, 12, -7,
- 7, 11, 4, 10, 7, -18, -50, -25, 33, 51, 24, -10, -20, -52, -72, 58,
- 103, 21, -1, -26, -41, -17, 44, 67, 35, 16, 27, 36, 26, 18, 25, 8,
- -45, -76, -55, -13, 7, -3, -16, -26, -38, -55, -61, -38, 4, 13, -26, -30,
- 11, 25, 4, -36, -10, 51, 14, -37, -42, -33, -24, -17, -10, -4, 1, 3,
- 6, 18, 42, 42, -22, -80, -63, -28, -14, -12, -9, -3, 5, 12, 19, 24,
- 23, 3, -46, -58, 9, 14, -34, -41, -14, 21, 6, -21, 4, 36, 38, 26,
- 21, 26, 30, 22, 13, 37, 78, 73, 20, -7, 4, 11, 6, 10, 10, -11,
- -45, -33, 22, 49, 29, -4, -18, -40, -75, 23, 108, 40, 1, -18, -39, -26,
- 28, 65, 42, 17, 22, 34, 29, 18, 23, 15, -30, -71, -65, -27, 3, 2,
- -11, -22, -34, -49, -58, -45, -7, 13, -16, -35, -1, 24, 13, -23, -26, 37,
- 36, -20, -39, -34, -24, -17, -10, -4, 1, 3, 5, 12, 33, 46, 6, -64,
- -75, -40, -17, -12, -10, -5, 2, 9, 15, 20, 22, 10, -30, -65, -18, 20,
- -19, -42, -27, 11, 21, -8, -8, 22, 34, 27, 22, 26, 31, 27, 14, 22,
- 60, 75, 34, -4, -2, 8, 8, 11, 14, -2, -36, -42, 6, 44, 36, 4,
- -15, -26, -66, -24, 95, 71, 8, -10, -33, -32, 7, 56, 51, 21, 17, 29,
- 32, 20, 19, 20, -12, -59, -72, -45, -8, 5, -5, -17, -28, -42, -54, -50,
- -21, 9, -5, -36, -16, 19, 21, -7, -34, 12, 51, 4, -33, -34, -25, -17,
- -10, -4, 1, 4, 5, 9, 23, 44, 29, -39, -79, -55, -24, -13, -10, -7,
- -1, 6, 12, 16, 20, 14, -15, -62, -46, 16, -2, -39, -36, -2, 29, 9,
- -12, 8, 28, 27, 23, 25, 31, 31, 17, 13, 43, 72, 46, 2, -5, 5,
- 8, 11, 16, 5, -26, -44, -8, 36, 40, 12, -12, -19, -52, -53, 67, 94,
- 20, -5, -27, -35, -7, 45, 55, 27, 15, 25, 32, 23, 17, 21, 0, -47,
- -73, -57, -19, 4, 0, -13, -24, -37, -50, -51, -29, 3, 1, -32, -26, 12,
- 23, 3, -32, -6, 52, 22, -26, -34, -25, -17, -10, -4, 1, 5, 6, 8,
- 18, 39, 38, -21, -76, -64, -30, -14, -10, -8, -2, 4, 10, 15, 18, 14,
- -9, -56, -57, 7, 7, -35, -39, -10, 27, 18, -10, 2, 23, 26, 23, 24,
- 31, 32, 20, 11, 35, 67, 51, 7, -6, 3, 8, 11, 17, 8, -20, -44,
- -15, 31, 41, 16, -9, -17, -43, -61, 44, 102, 31, -2, -23, -35, -15, 36,
- 56, 32, 0, -27, 1, -1, -1, 3, -4, -2, 1, -1, -2, 2, 3, -6,
- 1, 2, -6, 2, 2, -4, -1, 2, -5, 1, 4, -4, 0, -1, 0, -1,
- -2, 2, 2, -6, 0, 4, -3, -3, 4, -2, -3, -2, 0, 1, 1, -2,
- -2, 3, -8, 27, -42, 11, 21, -35, 34, -25, 12, 9, -24, 14, 13, -38,
- 53, -42, -3, 46, -73, 55, -16, -9, 28, -49, 38, -12, -21, 49, -51, 20,
- 32, -73, 64, -28, -7, 32, -50, 42, -11, -30, 49, -21, -31, 46, -25, -7,
- 20, -22, 18, -16, -10, 21, -23, 5, 28, -35, 8, 0, 8, -26, 19, 6,
- -11, -20, 64, -46, -18, 51, -73, 119, -117, 46, 36, -80, 67, -46, 22, 0,
- -24, 56, -59, 14, 26, -40, 24, -9, 20, -20, -15, 43, -26, -11, 9, 14,
- -3, -31, 6, 54, -62, 3, 67, -78, 20, 21, -25, 31, -41, 18, 27, -53,
- 32, 15, -48, 37, -11, 4, -12, -3, 31, -24, -21, 42, -10, -45, 55, -32,
- 34, -43, -14, 86, -78, 8, 39, -35, -2, 13, 2, 5, -11, -4, 7, 5,
- -31, 37, -4, -28, 28, -9, -11, 10, -1, 4, -18, 17, -9, -13, 24, -18,
- 20, -18, -30, 59, -25, -29, 48, -15, -29, 23, 4, -3, -18, 14, 6, -8,
- -19, 19, 8, -13, 0, 13, -18, 4, 1, 0, 0, 10, -14, -12, 39, -46,
- 23, 9, -22, 23, -20, -22, 63, -42, -28, 77, -66, 12, 38, -56, 31, 27,
- -77, 66, -11, -39, 59, -33, -41, 92, -54, -50, 96, -36, -46, 46, -17, 31,
- -43, -28, 98, -57, -50, 84, -22, -44, 39, -8, 17, -28, -13, 63, -67, 16,
- 10, 3, -15, -4, 36, -34, -1, 26, -27, -2, 13, 7, -22, 0, 27, -11,
- -19, 6, 26, -42, 14, 18, -7, -14, -10, 37, -14, -24, 25, -4, -5, -10,
- 3, 35, -39, -7, 31, -8, -23, 15, 4, -1, -25, 28, 7, -35, 34, -16,
- -1, 9, -35, 45, -22, -17, 48, -52, 24, 22, -65, 48, 7, -45, 47, -19,
- -33, 71, -70, 46, -7, -52, 68, -25, -35, 48, -13, -17, 14, 2, -12, 8,
- -10, 1, 22, -32, 4, 34, -26, -18, 29, -7, -19, 15, -7, 15, -8, -29,
- 50, -22, -35, 53, -19, -37, 47, -9, -40, 41, 1, -27, 7, 3, 0, 0,
- -7, 13, -7, -21, 26, 14, -44, 11, 40, -51, 10, 26, -28, 16, -13, -3,
- 31, -42, 11, 34, -52, 11, 34, -43, 10, 29, -19, -21, 27, -10, -5, 10,
- -14, 11, 3, -35, 43, 3, -52, 37, 22, -66, 49, -12, -19, 50, -58, 16,
- 42, -70, 50, -2, -42, 60, -69, 43, 11, -57, 54, -8, -31, 23, -8, -7,
- 24, -32, 11, 21, -51, 60, -44, -6, 68, -87, 33, 45, -79, 50, -7, -13,
- 21, -40, 31, 12, -41, 18, 24, -39, 15, 7, -17, 25, -20, -12, 43, -47,
- 17, 6, -16, 10, 4, -11, -1, 14, -10, -7, 6, 9, -23, 9, 3, 13,
- -30, 16, 16, -33, 17, 4, -17, 23, -29, 3, 54, -86, 50, 11, -41, 30,
- -23, 15, 18, -60, 56, 7, -65, 49, -4, -12, 1, -6, 19, -4, -33, 35,
- -10, -12, 13, -2, -2, -2, 2, -10, 16, -8, -11, 19, -6, -19, 24, -14,
- 9, 3, -24, 24, -6, -13, 19, -11, -6, 6, -9, 16, -8, -10, 14, -10,
- -1, -5, 16, -8, -25, 37, -11, -27, 37, -14, -13, 19, -17, 14, -5, -15,
- 26, -27, 10, 11, -23, 22, -5, -19, 25, -7, -28, 44, -35, 0, 25, -31,
- 31, -10, -26, 46, -41, 2, 33, -40, 24, 8, -43, 44, -12, -25, 37, -25,
- -6, 29, -27, 5, 24, -40, 24, -1, -25, 23, -1, -6, -2, -1, 14, -24,
- 8, 13, -11, 0, -13, 16, 15, -56, 43, 12, -35, 14, -9, 18, -10, -19,
- 28, -3, -27, 23, -2, -14, 27, -35, 10, 35, -68, 44, 7, -43, 46, -21,
- -25, 56, -35, -21, 51, -33, -8, 28, -27, 19, -2, -26, 36, -26, 3, 13,
- -12, 6, -10, 8, -14, 15, -12, 0, 13, -9, -16, 32, -27, 3, 23, -49,
- 49, -17, -31, 63, -64, 25, 36, -76, 61, -11, -47, 75, -54, -9, 69, -81,
- 32, 29, -63, 46, -7, -26, 39, -31, 6, 18, -26, 13, -5, 5, -5, -2,
- 5, -12, 17, -17, -2, 22, -25, 1, 20, -19, 3, 6, -6, 3, -9, 10,
- -6, -3, 7, -7, -3, 12, -5, -5, -11, 24, -7, -23, 24, 0, -14, 0,
- 12, -10, -2, 5, 0, 1, -10, 10, -2, -17, 26, -11, -16, 28, -22, 6,
- 4, -17, 30, -27, -7, 46, -54, 15, 29, -42, 25, -4, -15, 26, -29, 11,
- 15, -28, 19, -7, 1, 8, -20, 14, 1, -15, 11, -2, -2, 0, -10, 15,
- -5, -12, 15, -1, -15, 12, 4, -15, 9, -1, -9, 9, -5, -6, 13, -12,
- 1, 6, -6, -3, 6, -4, 0, -6, 11, -9, -2, 13, -12, -2, -1, 8,
- -11, 4, 2, -6, 4, -4, 4, 0, -13, 15, 0, -21, 23, -5, -15, 15,
- -2, -9, 6, -2, -4, 2, 3, -1, -7, 7, -2, -9, 6, 2, -9, 4,
- 5, -12, 10, -9, 4, 5, -16, 12, -2, -13, 20, -13, -4, 17, -23, 14,
- 2, -20, 22, -13, -3, 15, -22, 12, 4, -18, 17, -7, -7, 13, -14, 6,
- 4, -10, 9, -5, -6, 7, 0, -7, 8, -4, -1, 0, -6, 4, 7, -14,
- 2, 13, -16, 3, 10, -15, 7, -1, -10, 14, -10, -2, 11, -9, -4, 7,
- -6, 3, -3, -5, 9, -6, -3, 5, 1, -7, 3, -2, 0, -2, 0, 4,
- -3, -2, 4, -6, 4, -2, -2, 0, 1, 0, -7, 7, -2, -7, 9, -7,
- -4, 11, -15, 11, -2, -9, 9, -4, -3, 2, 3, -7, 5, 0, -5, 6,
- -7, 1, 7, -10, -2, 13, -9, -4, 8, -4, -2, -1, 1, 1, -7, 4,
- 5, -8, 0, 6, -6, 0, 3, -4, 0, 1, -2, 2, -4, -4, 8, -7,
- -1, 6, -9, 8, -3, -6, 12, -12, 1, 10, -11, 1, 5, -6, 3, -2,
- -3, 7, -10, 2, 7, -12, 5, 2, -5, 3, -5, 0, 6, -10, 3, 4,
- -8, 2, 2, -3, 3, -8, 8, 2, -14, 10, 3, -12, 8, 2, -11, 8,
- -2, -6, 9, -7, -4, 10, -9, -1, 7, -7, 1, 3, -8, 8, -2, -8,
- 10, -3, -5, 5, -6, 3, 1, -8, 10, -5, -5, 7, -4, -2, 2, -3,
- 1, -1, -3, 4, -3, 0, 0, 0, 0, -4, 3, -2, -3, 3, -5, 3,
- 0, -7, 5, 1, -8, 5, 1, -6, 6, -5, 0, 3, -7, 3, 2, -6,
- 3, 2, -6, 3, 1, -3, -2, 5, -4, -1, 3, -4, 0, 0, -3, 5,
- -5, -3, 7, -5, -3, 6, -4, 0, -1, -3, 3, -2, -1, 2, -1, -2,
- 1, -2, 1, -1, -7, 8, -1, 5, -7, 13, -22, 8, -7, 8, -110, -28,
- 24, 54, 36, 2, 60, -45, 57, 42, -43, 20, 41, -66, 24, -11, 18, -18,
- -38, -63, -36, 30, -11, 33, 25, 30, 18, 11, -18, -5, 5, -46, 40, 1,
- -13, -18, -20, -31, 20, 10, 29, -7, -18, 40, -29, -17, 42, -19, 6, -4,
- 6, -8, 10, -26, -5, 3, 1, -17, 6, 0, 19, -1, 8, 0, -6, -10,
- -1, -12, -1, 1, -3, 8, -7, 4, 11, 4, 14, -13, 16, -19, -4, -13,
- -13, -14, 6, 4, -1, 4, 11, -1, 11, -1, 1, -4, -1, -15, 6, -9,
- 1, -1, 0, 3, 1, -8, 3, -1, -1, 2, -2, 2, -2, 1, -5, -7,
- 3, -3, 6, -3, 4, -1, 0, -4, 2, -7, 3, -6, -1, -1, 4, 0,
- 3, -2, 2, -5, 5, -8, -3, -3, 2, -5, 7, -1, 4, -2, 4, -10,
- 6, -6, -1, -4, 5, -13, 7, -6, 5, -8, 17, -20, 14, -6, 9, -40,
- 71, -127, 9, -73, 127, 76, -28, 74, -32, 8, -62, -49, -38, 40, -68, 22,
- -12, 68, 10, 39, -10, 0, 35, -23, 0, -59, -15, -7, -3, -23, 1, -20,
- 37, 27, 2, 30, -2, 17, 2, -5, -7, -27, -29, 16, -3, -11, 1, -16,
- -5, -8, -10, 7, 32, 9, 5, -4, 16, 5, -8, -17, -16, 5, -13, 8,
- 11, 15, -10, -9, 0, -1, 2, 7, -3, -23, 9, 2, 3, 1, -13, -1,
- -6, 11, -6, 8, 1, 12, -12, 9, -14, 8, -1, 0, -3, -13, 4, -7,
- -4, 8, 5, -5, -7, 4, -2, -3, 2, 3, -6, 8, -3, 1, -3, -2,
- 2, -6, 2, -4, -3, -4, 3, 1, 0, 0, 1, -1, -1, 2, -2, 0,
- -4, -2, 1, 2, 0, -3, 1, -3, 0, -1, -3, -6, 2, -2, 3, -4,
- 10, -8, 9, -5, 12, -19, 46, 37, -128, 60, -90, 102, -65, 40, -57, 39,
- -6, 23, -8, 19, 24, 15, -17, -47, -27, -36, -16, 21, 3, 23, 14, 50,
- -8, 19, 25, 7, -9, -28, -63, -37, 0, -42, 54, -17, 68, -3, 30, -12,
- -4, 11, -15, 9, -25, -15, -2, -27, -25, 38, -8, -13, 33, 24, 12, -38,
- 39, -12, -3, -17, -44, 38, 2, 27, 3, -5, -4, -13, -30, -56, -4, 11,
- 1, 9, 17, 46, 25, -14, 6, -3, -7, -21, 2, 16, -5, -22, 2, -2,
- 6, -12, -25, -15, 10, 9, 8, 11, 43, 8, -5, -22, -16, 14, -31, 16,
- 7, -7, -26, -20, -2, 9, 11, 26, 7, 6, -20, -13, 0, 4, 17, -17,
- -18, 10, 2, -10, 27, -8, 24, -23, -14, 1, 0, 13, -19, 14, 10, -16,
- 16, -4, -20, 20, -33, 2, 2, 24, 21, -3, -26, -24, -18, -18, 10, 10,
- 24, 18, 2, 9, -24, 16, -14, -8, 9, -5, -14, 8, -5, 30, -11, 11,
- -13, -15, -12, 7, 4, -13, -13, 13, -13, 12, 23, 9, 0, 14, -10, -9,
- -35, -2, -21, 12, -1, 17, 19, 11, -4, 0, -18, -24, 11, -10, 1, 11,
- 12, -13, -16, 10, -23, 21, 9, -9, 3, 12, -6, 3, -5, 12, 0, -2,
- 0, -19, -9, 5, -11, -7, 10, 1, -3, 9, 18, -6, 0, -1, 1, -13,
- 2, 1, -3, -8, 17, -4, -9, 18, -15, 8, -1, -11, -5, -14, 11, -5,
- -7, 12, 16, -7, 7, -3, -11, -5, -6, 1, 4, -3, -3, 15, 5, 0,
- 3, 6, -16, 4, -14, -6, -9, -4, 2, 11, 11, 7, -2, 4, -12, -7,
- -14, -6, -7, 9, 4, 7, -2, 6, 5, 6, -4, -3, -4, 7, -7, -11,
- -9, 0, -3, 7, -2, -2, 3, 13, -4, -6, -15, 9, -7, -1, 4, 6,
- 5, 8, -6, -8, 0, -11, -4, 6, -8, 4, 3, 5, 13, -4, -9, -3,
- 4, -3, -3, 4, -1, -12, 6, -14, 2, 3, 15, 2, 6, -7, -8, 3,
- 1, -2, 3, -3, -12, -6, -14, 7, -2, 13, 6, 10, 6, 0, -2, -10,
- -12, -8, -6, -7, -6, 6, 4, -2, 5, 2, 0, -1, 3, -11, 4, 0,
- 20, -8, -2, 0, -1, -3, 7, -3, -4, -2, -6, -10, -10, -8, 1, 2,
- 5, 8, 2, 5, 8, 3, 4, 3, -2, -15, 0, -1, -7, -2, -5, -10,
- 10, -1, 5, 3, 5, -1, -2, -8, -5, -9, 1, -8, 6, 5, 4, 1,
- 1, 2, 3, -2, 4, -7, 1, -7, -9, -2, 0, 2, 3, 6, -8, 8,
- 3, 0, -2, -9, -3, -2, 0, 3, -1, -2, -3, 7, -3, 10, -8, 1,
- -12, 3, -7, 2, -3, 7, 4, 4, 0, 0, -6, -1, -5, -3, -4, -7,
- 0, 5, 7, 0, 2, -3, 10, -1, 3, -7, -5, -4, -9, -3, -7, 5,
- -4, 9, 2, 1, 4, 5, 0, -5, 1, -8, 4, -9, 5, -5, 0, 3,
- -2, -1, 1, 1, -7, 7, 0, 3, -5, 0, -3, -1, -1, -5, -1, 1,
- -1, 1, -1, 0, 2, 0, 2, -7, -7, 4, -1, 0, 3, 4, -1, -3,
- -4, -6, 3, -2, 4, -1, 5, -2, -1, -5, -2, -4, 1, 3, 2, 2,
- 0, -3, 1, 1, -3, -3, -1, 1, -3, -2, -1, -2, -3, -1, 0, 4,
- 3, 5, 2, 1, -4, -9, -3, -7, 1, -2, 7, -2, 3, 3, 3, 1,
- 0, -1, -6, -7, -6, -4, -1, 1, 0, 5, 2, -2, 2, -3, -1, 3,
- -1, 1, -4, -4, -5, 0, -7, 2, -4, 3, 4, 1, 2, -1, -1, -2,
- -2, 0, -1, 1, -1, -1, -3, 1, 1, 3, -3, -1, 1, 1, -2, -3,
- -8, -5, 0, -1, 5, 2, 3, 1, -2, -1, -1, -3, 1, 1, -2, -3,
- -3, -1, 0, -1, 1, 2, 2, 5, 0, -1, -2, -1, -2, 0, -4, 0,
- -5, -1, -1, 0, 1, 5, 4, -2, -1, -2, 0, -6, -1, 0, 1, -1,
- -2, 1, 0, 0, 3, 1, -2, 1, -2, -4, -1, 0, -1, -1, -4, -2,
- -4, 2, -1, 1, 0, 3, 2, 0, 4, -1, 4, -6, 2, -4, -3, -5,
- -4, -3, 0, 2, 0, 1, 4, 2, 2, -2, -2, -5, -6, -5, -3, -2,
- 1, -1, 0, 0, 2, 2, 2, 0, 4, -2, 3, 2, -1, -2, -3, -3,
- -3, -5, -5, -5, -1, -1, 0, 2, 2, 4, 1, 2, 1, 2, -1, -1,
- -3, -4, -5, -3, -2, -2, -1, 1, 4, 2, 2, 2, 1, -1, -2, -6,
- -2, -3, 2, -1, 1, -2, 0, 2, 1, 2, -2, 1, 0, -2, -2, -3,
- 0, -2, -1, -1, 0, -2, -2, 1, 0, 2, -1, 1, -1, 0, -1, -1,
- 0, -1, 0, -2, 2, 0, 2, 2, 5, 3, 6, 8, 12, 13, -6, -110,
- -7, 51, -99, -128, 10, -28, -39, 25, -33, -27, 41, 34, -5, 17, 23, 25,
- 24, 23, 20, 24, 25, 24, 21, 20, 23, 23, 16, 20, 9, 20, 18, 10,
- 14, 5, 14, 11, 7, 5, 3, 10, 2, 7, -4, 0, 3, 0, -3, -5,
- -6, -1, -12, -4, -17, -10, 9, -42, -40, 65, 40, -58, 29, 72, 39, 50,
- 31, -1, 30, 25, -7, -4, -33, -47, -29, -49, -74, -69, -71, -79, -61, -51,
- -57, -53, -34, -20, -22, -16, -10, -6, -2, 1, 3, 4, 8, 8, 12, 10,
- 9, 14, 13, 12, 12, 13, 12, 12, 14, 12, 12, 12, 12, 13, 12, 9,
- 11, 11, 11, 7, 8, 7, 8, 9, 2, 5, 8, -6, 2, 17, -17, -20,
- 18, 5, -15, 15, 27, 21, 37, 44, 41, 46, 38, 26, 32, 26, -4, -15,
- -6, -20, -44, -50, -54, -60, -59, -58, -58, -54, -46, -38, -32, -26, -19, -14,
- -9, -5, -1, 2, 5, 7, 8, 10, 11, 12, 13, 13, 14, 14, 14, 13,
- 13, 14, 15, 14, 11, 13, 14, 13, 12, 10, 12, 12, 10, 10, 8, 6,
- 11, 9, -1, 5, 11, -1, -6, 1, -1, -4, 0, -1, 0, 14, 25, 24,
- 28, 37, 38, 38, 38, 31, 22, 14, 4, -5, -15, -26, -38, -47, -52, -54,
- -56, -57, -55, -51, -45, -39, -34, -28, -22, -17, -13, -8, -3, -1, 2, 5,
- 7, 8, 10, 11, 12, 13, 13, 13, 13, 14, 14, 13, 13, 14, 13, 12,
- 13, 13, 12, 11, 12, 11, 9, 11, 9, 6, 7, 8, 5, 3, 2, 0,
- 0, 0, -2, -3, 0, 3, 6, 11, 18, 23, 27, 31, 34, 35, 32, 27,
- 21, 14, 5, -5, -15, -26, -35, -43, -48, -52, -53, -53, -52, -49, -44, -40,
- -35, -29, -24, -19, -14, -10, -6, -3, 1, 3, 5, 7, 9, 10, 11, 12,
- 13, 13, 13, 13, 13, 13, 13, 13, 13, 12, 13, 12, 11, 13, 11, 10,
- 10, 9, 9, 8, 7, 7, 5, 4, 3, 2, 0, -1, -1, 0, 2, 4,
- 8, 12, 17, 22, 25, 28, 30, 30, 28, 24, 19, 12, 3, -5, -14, -23,
- -31, -37, -43, -46, -46, -48, -47, -43, -41, -38, -33, -29, -25, -21, -16, -12,
- -8, -5, -2, 0, 3, 5, 7, 9, 10, 11, 12, 12, 13, 14, 13, 13,
- 13, 13, 13, 12, 12, 12, 11, 11, 11, 10, 9, 9, 8, 7, 7, 6,
- 5, 4, 4, 3, 3, 3, 3, 5, 6, 8, 10, 12, 14, 17, 18, 19,
- 20, 19, 17, 14, 10, 5, 0, -6, -11, -17, -22, -26, -29, -32, -34, -34,
- -35, -34, -32, -31, -28, -26, -23, -20, -17, -14, -11, -8, -5, -3, 0, 2,
- 4, 6, 7, 8, 9, 10, 11, 11, 12, 12, 12, 12, 11, 11, 11, 10,
- 10, 9, 9, 8, 8, 7, 7, 6, 5, 5, 5, 4, 4, 5, 5, 5,
- 6, 7, 8, 9, 10, 11, 12, 13, 13, 13, 13, 12, 10, 8, 5, 2,
- -2, -6, -10, -14, -18, -21, -24, -26, -28, -29, -29, -30, -29, -28, -27, -25,
- -23, -20, -18, -15, -12, -10, -7, -4, -2, 0, 2, 4, 6, 7, 9, 10,
- 10, 11, 11, 12, 12, 12, 12, 11, 11, 11, 10, 10, 9, 9, 8, 8,
- 7, 7, 6, 6, 5, 5, 5, 5, 6, 6, 7, 7, 8, 9, 10, 11,
- 12, 13, 13, 13, 12, 11, 10, 8, 5, 2, -1, -5, -9, -13, -16, -19,
- -22, -24, -26, -27, -28, -28, -28, -27, -26, -24, -22, -20, -18, -15, -13, -10,
- -7, -5, -2, 0, 2, 4, 5, 7, 8, 9, 10, 11, 11, 11, 11, 11,
- 11, 11, 11, 10, 10, 9, 9, 8, 8, 7, 7, 6, 6, 6, 5, 5,
- 5, 5, 6, 6, 6, 7, 8, 9, 10, 11, 11, 12, 12, 12, 11, 10,
- 9, 7, 5, 2, -1, -5, -8, -12, -15, -18, -21, -23, -25, -26, -27, -27,
- -27, -26, -25, -24, -22, -20, -18, -16, -13, -11, -8, -6, -3, -1, 1, 3,
- 4, 6, 7, 8, 9, 10, 10, 10, 11, 11, 11, 10, 10, 10, 10, 9,
- 9, 8, 8, 7, 7, 6, 6, 6, 5, 5, 5, 5, 6, 6, 6, 7,
- 8, 9, 9, 10, 11, 11, 11, 11, 11, 10, 9, 7, 4, 2, -1, -4,
- -7, -11, -14, -17, -19, -21, -23, -24, -25, -26, -26, -25, -24, -23, -22, -20,
- -18, -16, -13, -11, -9, -6, -4, -2, 0, 2, 4, 5, 7, 8, 9, 9,
- 10, 10, 11, 11, 11, 11, 10, 10, 10, 9, 9, 8, 8, 7, 7, 7,
- 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 8, 9, 9, 10, 11, 11,
- 11, 11, 10, 10, 8, 7, 5, 2, -1, -3, -7, -10, -13, -15, -18, -20,
- -22, -23, -24, -25, -25, -24, -24, -23, -21, -20, -18, -16, -14, -11, -9, -7,
- -5, -2, 0, 1, 3, 5, 6, 7, 8, 9, 9, 10, 10, 10, 10, 10,
- 10, 10, 9, 9, 8, 8, 8, 7, 7, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 7, 7, 8, 8, 9, 9, 9, 10, 9, 9, 8, 7, 6, 4,
- 2, 0, -2, -5, -7, -10, -12, -15, -17, -18, -20, -21, -21, -22, -22, -21,
- -21, -20, -18, -17, -15, -13, -12, -10, -8, -6, -4, -2, 0, 1, 3, 4,
- 5, 6, 7, 8, 8, 8, 9, 9, 9, 9, 9, 8, 8, 8, 8, 7,
- 7, 7, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8,
- 8, 8, 8, 8, 7, 6, 5, 4, 3, 1, -1, -3, -5, -7, -9, -10,
- -12, -14, -15, -16, -17, -18, -18, -18, -18, -17, -17, -16, -15, -13, -12, -11,
- -9, -7, -6, -4, -3, -1, 0, 1, 3, 4, 5, 5, 6, 7, 7, 7,
- 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 6, 5,
- 4, 3, 2, 0, -1, -3, -5, -7, -9, -10, -12, -13, -15, -16, -17, -17,
- -18, -18, -18, -17, -17, -16, -15, -14, -12, -11, -9, -8, -6, -5, -3, -2,
- -1, 1, 2, 3, 4, 5, 5, 6, 6, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 6, 6, 5, 4, 3, 2, 0, -1, -3,
- 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 2, 3, 4, 5,
- 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 6, 7, 8, 9, 10, 10,
- 11, 12, 12, 13, 13, 14, 15, 17, 18, 19, 20, 21, 22, 23, 24, 26,
- 27, 29, 29, 29, 28, 28, 28, 29, 30, 31, 31, 31, 31, 28, 19, -8,
- -41, -53, -57, -59, -60, -62, -62, -63, -64, -65, -65, -66, -67, -69, -69, -69,
- -72, -74, -73, -74, -76, -78, -79, -81, -82, -82, -83, -81, -83, -85, -81, -81,
- -88, -90, -80, -64, -47, -32, -23, -18, -15, -13, -12, -12, -12, -13, -13, -13,
- -13, -13, -12, -12, -11, -9, -7, -6, -4, -2, -1, 0, 1, 2, 4, 5,
- 7, 10, 12, 14, 16, 18, 19, 18, 19, 21, 19, 20, 22, 22, 22, 25,
- 27, 28, 29, 29, 29, 29, 29, 30, 31, 31, 31, 33, 34, 34, 35, 34,
- 33, 31, 30, 29, 26, 25, 26, 25, 22, 22, 21, 20, 20, 19, 19, 19,
- 18, 18, 18, 17, 17, 17, 17, 16, 16, 16, 15, 13, 13, 14, 14, 15,
- 13, 12, 13, 13, 11, 12, 14, 14, 16, 17, 15, 16, 19, 19, 19, 19,
- 21, 19, 17, 18, 19, 18, 15, 15, 17, 18, 18, 13, 11, 14, 15, 14,
- 11, 6, 5, 10, 13, 17, 18, 11, 2, -2, -2, -3, 2, 14, 24, 30,
- 37, 47, 52, 52, 56, 63, 65, 65, 63, 65, 72, 75, 73, 71, 73, 77,
- 82, 82, 77, 77, 82, 90, 99, 104, 99, 89, 84, 86, 94, 106, 119, 127,
- 126, 117, 104, 87, 64, 42, 24, 10, -2, -15, -22, -25, -27, -30, -35, -37,
- -36, -34, -33, -36, -40, -42, -44, -43, -44, -48, -53, -57, -59, -57, -53, -52,
- -53, -57, -62, -68, -73, -75, -75, -71, -63, -56, -48, -40, -34, -29, -26, -23,
- -22, -21, -19, -19, -20, -21, -22, -22, -22, -22, -22, -21, -21, -21, -20, -19,
- -19, -18, -18, -17, -17, -16, -14, -14, -13, -11, -9, -9, -9, -9, -9, -8,
- -8, -8, -8, -8, -7, -6, -7, -6, -4, -3, -2, -2, -3, -4, -3, -3,
- -2, -1, 0, 0, -1, -1, 0, -1, -1, -1, -3, -5, -5, -8, -10, -10,
- -9, -9, -10, -11, -11, -11, -11, -11, -10, -9, -10, -10, -10, -11, -12, -12,
- -13, -12, -11, -12, -14, -14, -11, -10, -12, -11, -11, -12, -12, -11, -11, -13,
- -12, -9, -6, -6, -7, -7, -6, -5, -4, -4, -5, -8, -12, -11, -8, -4,
- -3, -5, -6, -7, -9, -12, -13, -8, -3, -2, -4, -8, -11, -14, -15, -17,
- -19, -19, -15, -8, -1, 2, 4, 8, 12, 17, 23, 26, 25, 24, 25, 30,
- 36, 40, 39, 36, 33, 32, 33, 37, 43, 49, 53, 53, 49, 45, 43, 43,
- 46, 52, 60, 67, 76, 82, 82, 78, 69, 58, 47, 37, 26, 14, 2, -9,
- -16, -21, -24, -28, -32, -35, -37, -38, -37, -36, -36, -36, -39, -43, -46, -49,
- -51, -49, -47, -46, -45, -45, -48, -52, -58, -62, -65, -66, -65, -62, -58, -54,
- -50, -45, -39, -34, -30, -28, -25, -23, -21, -20, -20, -20, -20, -19, -18, -19,
- -20, -18, -17, -18, -17, -17, -18, -17, -16, -15, -15, -13, -12, -10, -10, -10,
- -9, -8, -7, -6, -4, -4, -5, -6, -5, -4, -4, -3, -2, -2, -1, -1,
- -1, 0, 2, 3, 2, 2, 3, 2, 1, 2, 4, 5, 5, 4, 4, 4,
- 3, 2, 2, 1, 0, 0, -1, -4, -5, -4, -2, -2, -3, -3, -3, -2,
- -1, -2, -3, -2, -3, -4, -4, -3, -4, -6, -7, -4, 0, 0, -2, -4,
- -4, -3, -2, -2, -3, -4, -4, -3, -2, -1, 3, 6, 8, 6, 3, 0,
- 0, 2, 4, 5, 4, 3, 2, 2, 2, 1, 0, -1, 2, 7, 11, 9,
- 6, 2, -1, -3, -3, -5, -7, -8, -6, -3, 2, 8, 13, 17, 18, 18,
- 19, 23, 28, 34, 40, 42, 42, 40, 39, 39, 40, 42, 46, 50, 55, 59,
- 59, 55, 51, 48, 48, 51, 57, 63, 70, 76, 82, 86, 88, 89, 86, 80,
- 71, 61, 51, 43, 34, 25, 18, 10, 2, -5, -9, -12, -13, -12, -12, -13,
- -14, -17, -22, -26, -29, -28, -27, -25, -24, -24, -25, -27, -31, -35, -40, -43,
- -46, -47, -49, -49, -46, -43, -40, -36, -32, -28, -24, -21, -18, -16, -14, -13,
- -13, -12, -11, -11, -12, -11, -10, -9, -11, -11, -11, -12, -12, -12, -10, -10,
- -10, -10, -9, -8, -7, -6, -5, -4, -4, -4, -4, -4, -3, -2, -2, -1,
- -2, -3, -2, -1, 0, 0, 1, 2, 3, 2, 1, 1, 2, 3, 3, 4,
- 5, 4, 4, 5, 6, 7, 6, 4, 3, 3, 3, 2, -1, -3, -3, -1,
- -1, -2, -3, -3, -2, -1, 1, 0, -1, -1, -2, -5, -6, -5, -4, -4,
- -4, -4, -6, -6, -4, -1, 0, -2, -6, -9, -10, -8, -5, -4, -3, -3,
- -1, 1, 1, -1, -3, -4, -2, 0, 2, 2, 0, -3, -6, -7, -6, -4,
- -3, -2, -1, -1, -1, 0, 1, 0, -3, -9, -14, -18, -18, -15, -12, -9,
- -8, -7, -5, -3, -2, 0, 5, 11, 17, 22, 25, 24, 23, 21, 20, 22,
- 27, 32, 37, 40, 41, 40, 39, 37, 35, 34, 34, 35, 39, 45, 52, 59,
- 66, 71, 73, 75, 74, 71, 65, 60, 55, 48, 39, 28, 17, 7, -1, -7,
- -11, -13, -13, -14, -17, -21, -24, -28, -31, -32, -32, -32, -32, -31, -29, -29,
- -30, -33, -36, -40, -44, -47, -50, -52, -54, -55, -54, -52, -49, -47, -43, -39,
- -35, -31, -28, -26, -24, -22, -21, -19, -18, -17, -17, -16, -15, -16, -18, -17,
- -16, -16, -17, -18, -18, -17, -16, -16, -14, -13, -13, -12, -12, -12, -11, -10,
- -10, -9, -7, -8, -9, -10, -10, -8, -6, -5, -6, -6, -5, -3, -3, -4,
- -4, -4, -3, -2, -2, -1, -1, -1, 0, 2, 3, 3, 3, 2, 1, 0,
- -1, -1, -1, -2, -3, -5, -5, -4, -2, -3, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1,
- 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 1, 3, 2, 0,
- -1, 1, 2, 1, -1, -1, 2, 2, 0, 1, 2, 2, -1, -4, -10, -21,
- -30, -36, -41, -44, -40, -30, -18, -10, -8, -11, -13, -8, 3, 18, 32, 41,
- 44, 45, 48, 49, 43, 32, 23, 14, 7, 8, 16, 27, 35, 37, 30, 18,
- 9, 5, 3, 2, 1, 1, -1, -6, -11, -12, -6, -2, -5, -11, -18, -28,
- -39, -47, -55, -69, -86, -99, -102, -92, -70, -46, -28, -15, -3, 7, 17, 26,
- 28, 24, 23, 30, 42, 53, 57, 50, 36, 21, 5, -5, -4, 6, 20, 31,
- 35, 34, 29, 26, 27, 37, 56, 76, 85, 80, 71, 63, 55, 47, 34, 13,
- -13, -32, -39, -40, -46, -65, -93, -117, -128, -128, -126, -120, -110, -96, -78, -58,
- -36, -14, 3, 10, 20, 41, 60, 68, 63, 54, 45, 39, 36, 32, 28, 29,
- 35, 41, 47, 46, 41, 39, 43, 53, 68, 80, 78, 64, 46, 28, 13, 3,
- -9, -35, -64, -80, -82, -74, -66, -71, -91, -111, -121, -118, -105, -86, -68, -57,
- -49, -37, -22, -7, 5, 14, 26, 42, 55, 56, 46, 35, 25, 14, 6, 2,
- 1, 3, 11, 22, 32, 40, 43, 42, 46, 60, 77, 88, 90, 78, 54, 30,
- 14, 2, -15, -37, -62, -82, -90, -89, -86, -90, -99, -107, -109, -101, -81, -54,
- -29, -14, -5, 7, 24, 40, 49, 56, 68, 83, 92, 92, 87, 74, 54, 32,
- 12, -5, -19, -25, -24, -18, -7, 1, -1, -6, -4, 13, 41, 69, 84, 80,
- 63, 44, 32, 29, 25, 11, -10, -25, -31, -35, -40, -48, -65, -87, -104, -109,
- -102, -87, -69, -58, -54, -42, -21, 0, 13, 29, 51, 71, 84, 89, 86, 75,
- 54, 33, 14, -3, -19, -29, -27, -22, -18, -11, -8, -16, -26, -19, 2, 24,
- 40, 48, 42, 27, 21, 29, 34, 24, 7, -5, -14, -23, -28, -32, -45, -67,
- -82, -85, -78, -63, -46, -34, -29, -24, -13, 0, 12, 25, 44, 65, 79, 85,
- 86, 78, 60, 41, 27, 12, -5, -15, -15, -14, -13, -8, -7, -17, -27, -23,
- -3, 23, 44, 51, 43, 25, 12, 11, 14, 8, -3, -10, -15, -22, -28, -30,
- -36, -55, -73, -78, -74, -71, -63, -51, -43, -39, -34, -25, -18, -9, 8, 28,
- 46, 56, 61, 62, 58, 47, 36, 28, 20, 12, 11, 16, 19, 20, 21, 15,
- 0, -6, 10, 37, 57, 63, 55, 36, 15, 2, -3, -9, -19, -27, -34, -43,
- -49, -49, -52, -66, -82, -86, -81, -77, -71, -61, -51, -47, -43, -35, -22, -12,
- 2, 24, 47, 58, 63, 67, 66, 58, 51, 45, 34, 18, 9, 7, 7, 7,
- 8, 1, -14, -24, -12, 18, 47, 64, 68, 63, 53, 42, 37, 38, 36, 29,
- 21, 16, 11, 5, -2, -17, -36, -49, -52, -56, -62, -63, -61, -61, -63, -60,
- -56, -49, -37, -19, 2, 17, 25, 30, 34, 37, 37, 37, 34, 25, 15, 11,
- 13, 14, 14, 8, -7, -21, -16, 9, 37, 53, 60, 61, 53, 40, 33, 34,
- 32, 22, 14, 12, 10, 6, -2, -15, -32, -48, -57, -60, -63, -67, -66, -63,
- -63, -65, -64, -58, -49, -34, -13, 6, 16, 21, 28, 34, 38, 41, 43, 36,
- 25, 19, 21, 26, 27, 20, 4, -11, -11, 7, 31, 53, 66, 70, 66, 57,
- 49, 47, 44, 33, 21, 17, 16, 10, 1, -9, -26, -46, -60, -67, -76, -84,
- -84, -80, -78, -79, -78, -73, -65, -52, -32, -11, 4, 10, 17, 25, 32, 36,
- 40, 37, 24, 13, 15, 23, 23, 11, -5, -19, -25, -16, 9, 38, 59, 70,
- 72, 67, 63, 63, 60, 50, 39, 32, 28, 22, 14, 3, -14, -34, -53, -65,
- -76, -87, -94, -93, -91, -94, -96, -93, -86, -76, -56, -30, -9, 4, 16, 29,
- 40, 51, 63, 65, 52, 39, 39, 45, 42, 29, 11, -7, -22, -24, -8, 19,
- 42, 54, 60, 63, 61, 58, 57, 53, 43, 36, 36, 34, 28, 21, 11, -5,
- -24, -39, -52, -65, -75, -77, -75, -75, -78, -80, -78, -73, -61, -43, -23, -9,
- 1, 10, 23, 39, 52, 56, 47, 36, 35, 41, 42, 33, 17, -2, -24, -35,
- -26, -3, 18, 32, 42, 50, 52, 53, 52, 47, 38, 31, 30, 31, 29, 26,
- 22, 14, -1, -18, -33, -46, -58, -65, -65, -65, -71, -79, -81, -79, -75, -62,
- -42, -27, -21, -14, 1, 19, 34, 40, 36, 29, 27, 31, 38, 39, 29, 9,
- -12, -27, -28, -14, 8, 25, 37, 50, 62, 67, 66, 62, 53, 42, 36, 37,
- 36, 32, 30, 25, 12, -7, -24, -39, -54, -65, -67, -67, -72, -78, -81, -82,
- -81, -70, -51, -35, -29, -23, -7, 15, 30, 37, 40, 35, 25, 25, 36, 41,
- 33, 15, -6, -26, -36, -27, -9, 7, 20, 35, 50, 58, 59, 58, 52, 43,
- 37, 37, 37, 36, 34, 31, 24, 8, -11, -29, -44, -57, -67, -70, -73, -79,
- -86, -92, -93, -87, -72, -59, -53, -46, -29, -9, 7, 20, 28, 26, 19, 17,
- 27, 38, 38, 26, 7, -12, -25, -26, -15, 1, 14, 28, 47, 61, 67, 68,
- 68, 63, 54, 51, 53, 51, 49, 49, 47, 34, 14, -5, -22, -39, -56, -65,
- -67, -73, -86, -96, -97, -92, -86, -77, -69, -61, -49, -28, -6, 10, 22, 27,
- 25, 24, 33, 49, 56, 48, 32, 13, -5, -15, -12, -2, 7, 18, 35, 50,
- 59, 63, 65, 61, 53, 48, 46, 44, 43, 46, 49, 43, 27, 10, -6, -25,
- -45, -53, -53, -60, -75, -87, -90, -90, -88, -81, -75, -72, -65, -48, -25, -6,
- 5, 10, 13, 18, 31, 49, 60, 58, 44, 28, 12, -1, -7, -7, -1, 8,
- 23, 41, 54, 61, 65, 66, 63, 56, 48, 43, 41, 42, 44, 43, 37, 25,
- 8, -12, -32, -44, -49, -53, -64, -80, -91, -95, -93, -89, -85, -82, -78, -68,
- -50, -27, -6, 0, -1, 0, 0, 0, 1, 2, 3, 6, 9, 13, 17, 19,
- 13, -4, -15, -10, 4, 19, 26, 15, -9, -16, 6, -2, -18, 38, 64, 21,
- -48, 30, 82, -23, -63, -50, -26, -7, 12, 26, 47, 83, 100, 3, -108, -87,
- -30, -6, 5, 18, 33, 46, 47, 21, -52, -46, 48, 3, -54, -32, 22, 25,
- -7, 12, 9, -18, -33, -24, 2, 44, 88, 92, 10, -28, -1, 1, 20, 42,
- 1, -17, 53, 72, 12, -16, -74, -31, 127, 52, 1, -35, -46, 13, 39, -13,
- -13, 13, 12, 11, 8, -57, -80, -44, -5, 14, 18, 6, -13, -26, -11, -8,
- -24, 3, 30, 14, -28, -12, 41, -2, -37, -35, -23, -12, -1, 6, 17, 34,
- 53, 19, -55, -67, -32, -13, -5, 2, 12, 19, 24, 14, -24, -47, 12, 11,
- -36, -35, -1, 18, -3, 0, 5, -13, -25, -22, -5, 19, 53, 69, 21, -28,
- -10, -5, 6, 28, 8, -25, 23, 57, 17, -17, -49, -63, 84, 70, 3, -23,
- -50, -6, 36, -2, -20, 8, 14, 9, 13, -37, -82, -58, -19, 8, 17, 10,
- -9, -26, -19, -7, -24, -9, 25, 22, -17, -28, 33, 16, -32, -37, -27, -15,
- -4, 4, 13, 27, 48, 35, -35, -72, -43, -17, -7, -1, 9, 16, 23, 17,
- -12, -51, -7, 21, -27, -40, -12, 19, 6, -3, 5, -9, -22, -23, -8, 11,
- 42, 68, 38, -23, -16, -6, 3, 25, 19, -24, 8, 54, 31, -13, -33, -76,
- 46, 95, 13, -13, -48, -20, 32, 13, -22, 2, 15, 10, 15, -17, -77, -67,
- -31, 3, 17, 15, -3, -21, -23, -7, -20, -18, 18, 27, -4, -34, 17, 33,
- -21, -36, -29, -16, -6, 4, 11, 23, 42, 47, -12, -69, -54, -22, -8, -2,
- 7, 15, 22, 20, -2, -46, -27, 23, -13, -41, -22, 15, 16, -2, 4, -5,
- -18, -21, -10, 5, 32, 64, 53, -12, -21, -6, 0, 21, 27, -16, -6, 48,
- 42, -6, -22, -71, 2, 106, 31, -6, -41, -32, 22, 25, -18, -4, 15, 12,
- 14, -1, -64, -74, -42, -5, 16, 19, 4, -16, -25, -10, -14, -23, 9, 29,
- 9, -31, -2, 42, -5, -33, -30, -18, -8, 3, 9, 19, 36, 51, 10, -58,
- -63, -29, -11, -2, 4, 13, 20, 21, 6, -35, -44, 16, 1, -38, -30, 7,
- 23, 3, 2, -2, -16, -20, -12, 2, 23, 56, 62, 3, -24, -7, -2, 17,
- 30, -5, -17, 37, 49, 4, -17, -57, -37, 99, 55, 0, -31, -41, 9, 33,
- -10, -11, 13, 14, 12, 9, -47, -78, -53, -15, 12, 20, 9, -10, -24, -14,
- -11, -25, -2, 27, 18, -21, -20, 39, 13, -29, -31, -20, -9, 1, 8, 17,
- 30, 49, 29, -41, -70, -39, -15, -4, 2, 11, 17, 21, 11, -22, -52, 0,
- 14, -31, -36, -4, 25, 11, 1, -1, -13, -19, -13, 0, 15, 45, 65, 20,
- -24, -10, -4, 12, 30, 8, -22, 24, 52, 17, -14, -39, -61, 71, 81, 8,
- -21, -44, -5, 34, 2, -16, 9, 16, 11, 14, -29, -76, -62, -27, 6, 20,
- 15, -4, -21, -19, -9, -23, -12, 22, 25, -8, -30, 26, 30, -20, -31, -23,
- -11, -1, 8, 14, 25, 44, 42, -19, -69, -50, -20, -6, 1, 9, 15, 20,
- 15, -11, -51, -19, 20, -20, -39, -15, 23, 20, 2, 0, -11, -17, -14, -2,
- 9, 35, 63, 37, -19, -14, -5, 8, 28, 18, -22, 9, 50, 28, -11, -26,
- -68, 32, 100, 22, -13, -43, -18, 30, 15, -17, 4, 16, 12, 15, -12, -69,
- -69, -39, -2, 18, 19, 2, -17, -22, -10, -19, -20, 15, 27, 4, -31, 7,
- 41, -7, -30, -25, -13, -3, 6, 12, 22, 38, 48, 3, -61, -60, -27, -9,
- 0, 7, 13, 19, 17, -2, -44, -37, 18, -7, -39, -24, 15, 28, 7, 0,
- -9, -16, -14, -3, 6, 25, 57, 49, -9, -18, -7, 3, 25, 26, -15, -4,
- 45, 38, -5, -18, -61, -8, 103, 42, -6, -37, -30, 21, 25, -13, -3, 16,
- 13, 14, 2, -56, -73, -49, -12, 15, 21, 8, -11, -23, -13, -15, -24, 4,
- 28, 14, -25, -12, 42, 9, -26, -26, -15, -5, 5, 11, 19, 32, 48, 22,
- -46, -67, -36, -12, -2, 4, 12, 17, 18, 4, -33, -50, 6, 6, -35, -31,
- 4, 31, 14, 0, -8, -15, -14, -4, 4, 17, 48, 57, 4, -21, -8, -1,
- 21, 30, -5, -15, 36, 44, 5, -14, -46, -40, 88, 67, 2, -29, -37, 9,
- 31, -6, -9, 14, 15, 13, 11, -40, -74, -58, -24, 9, 22, 13, -6, -21,
- -17, -13, -25, -6, 25, 21, -13, -25, 33, 26, -19, -27, -18, -6, 3, 10,
- 16, 27, 45, 36, -26, -69, -46, -17, -4, 2, 10, 15, 18, 9, -22, -55,
- -11, 15, -26, -36, -8, 30, 23, 2, -6, -14, -14, -6, 4, 11, 37, 59,
- 19, -20, -10, -4, 16, 31, 7, -20, 23, 47, 15, -13, -32, -58, 58, 88,
- 13, -21, -40, -5, 32, 4, -13, 10, 17, 12, 14, -23, -70, -65, -35, 1,
- 20, 17, 0, -18, -20, -12, -23, -16, 19, 25, -1, -30, 16, 39, -8, -26,
- -20, -8, 1, 9, 14, 23, 39, 44, -5, -63, -57, -24, -7, 1, 8, 13,
- 17, 12, -12, -52, -30, 17, -15, -38, -18, 23, 32, 7, -6, -13, -14, -7,
- 3, 8, 27, 55, 33, -16, -13, -6, 10, 30, 17, -20, 10, 46, 25, -9,
- -21, -60, 19, 100, 31, -13, -39, -17, 27, 15, -13, 4, 17, 13, 15, -8,
- -61, -69, -46, -10, 17, 21, 6, -13, -22, -13, -20, -22, 10, 27, 9, -27,
- -4, 44, 6, -24, -22, -11, -1, 8, 13, 20, 33, 46, 14, -50, -65, -33,
- -11, 0, 5, 12, 15, 14, -4, -43, -46, 10, -2, -36, -27, 13, 36, 15,
- -4, -13, -14, -8, 3, 7, 18, 49, 43, -7, -16, -7, 5, 27, 24, -14,
- -3, 42, 33, -3, -16, -51, -17, 97, 51, -3, -38, -5, -13, 1, -7, 5,
- -22, -32, -35, -32, -43, -35, -55, -42, -66, -48, -80, -57, -17, -128, -59, -76,
- 0, -26, 1, -33, 21, 3, 16, 15, 26, 43, 28, 66, 6, 97, 40, 103,
- 67, 101, 102, 98, 94, 21, 98, 90, 57, 78, 89, 81, 61, -6, 54, 4,
- 62, 19, 27, 34, 12, 16, 14, -17, 19, -5, -2, -13, -38, -24, -3, -33,
- -14, -11, -16, 0, -13, 7, -26, -13, -16, 6, -57, -23, -28, -13, -9, -34,
- -32, -20, -87, -62, -28, -38, -75, -37, -27, -41, -71, -48, -30, -44, -83, -67,
- -52, -48, -45, -46, -45, -63, -47, -40, -32, -45, -24, -32, -43, -21, -17, 0,
- 21, 26, 43, 51, 62, 47, 41, 55, 57, 68, 34, 53, 63, 62, 71, 60,
- 61, 56, 53, 56, 54, 38, 50, 58, 50, 40, 28, 54, 39, 41, 38, 22,
- 32, 20, -3, 19, -1, -7, -6, -16, -16, -14, -27, -29, -46, -66, -61, -51,
- -54, -61, -41, -50, -47, -52, -55, -45, -44, -28, -58, -56, -31, -37, -36, -32,
- -18, -16, -34, -29, -9, -21, -20, -30, -22, -17, -19, -8, -12, -14, -6, -14,
- -6, -11, -2, 4, -6, 9, 8, 17, 23, 13, 31, 13, 24, 30, 28, 29,
- 30, 43, 34, 37, 52, 42, 44, 50, 67, 59, 49, 54, 48, 43, 51, 45,
- 42, 62, 47, 39, 37, 36, 24, 28, 13, 3, 9, -11, -3, -9, -14, -18,
- -34, -27, -29, -39, -42, -38, -46, -37, -46, -43, -41, -35, -38, -31, -38, -34,
- -39, -39, -34, -48, -44, -47, -49, -54, -52, -44, -53, -37, -47, -38, -31, -38,
- -27, -19, -19, -15, -16, 0, 0, 2, 7, 13, 29, 22, 32, 32, 39, 47,
- 41, 40, 55, 48, 41, 44, 57, 43, 36, 47, 43, 42, 37, 32, 32, 27,
- 33, 36, 30, 23, 25, 25, 22, 18, 22, 20, 16, 8, 6, 12, 7, 0,
- 1, 3, -5, -14, -9, -7, -8, -19, -15, -16, -23, -21, -21, -32, -31, -29,
- -26, -27, -29, -33, -26, -29, -30, -39, -28, -41, -43, -35, -34, -32, -29, -28,
- -28, -25, -27, -24, -27, -27, -27, -22, -23, -17, -9, -10, -14, -10, -8, -4,
- -2, -1, -3, 5, 4, 10, 11, 7, 13, 11, 14, 27, 22, 22, 22, 27,
- 36, 34, 36, 37, 45, 44, 47, 48, 51, 49, 52, 51, 52, 48, 50, 47,
- 48, 42, 40, 29, 33, 24, 22, 12, 5, 0, -3, -5, -9, -21, -21, -25,
- -19, -28, -28, -30, -33, -39, -42, -42, -46, -46, -45, -42, -43, -47, -47, -36,
- -32, -30, -34, -31, -22, -29, -29, -30, -26, -28, -30, -21, -26, -27, -21, -19,
- -16, -11, -12, -8, -2, 1, -4, 1, 0, 1, 9, 8, 7, 12, 10, 13,
- 20, 17, 18, 21, 26, 29, 30, 30, 29, 34, 33, 34, 33, 30, 32, 33,
- 28, 33, 29, 35, 32, 31, 30, 31, 30, 25, 27, 24, 21, 21, 20, 16,
- 17, 12, 6, 4, -3, 1, -6, -7, -11, -13, -11, -10, -8, -13, -12, -9,
- -17, -14, -19, -24, -22, -24, -30, -32, -30, -33, -37, -39, -40, -42, -39, -41,
- -39, -40, -41, -35, -35, -35, -37, -36, -33, -30, -25, -25, -19, -16, -16, -10,
- -6, -7, -4, -2, 1, 3, 6, 10, 9, 15, 17, 18, 17, 13, 19, 18,
- 17, 19, 20, 24, 24, 27, 27, 29, 30, 26, 28, 28, 27, 28, 26, 25,
- 24, 25, 20, 19, 17, 18, 15, 12, 13, 10, 6, 8, 6, 3, 4, 3,
- 0, -3, 0, -1, -2, -5, -4, -5, -4, -5, -6, -8, -9, -9, -12, -11,
- -16, -16, -15, -15, -13, -17, -16, -17, -17, -21, -20, -25, -24, -24, -24, -26,
- -30, -30, -27, -30, -26, -26, -27, -27, -25, -24, -19, -20, -17, -13, -12, -8,
- -8, -8, -6, -5, -2, -1, 0, 3, 8, 10, 12, 16, 18, 24, 25, 25,
- 28, 30, 28, 32, 33, 31, 32, 31, 35, 33, 31, 31, 27, 28, 26, 23,
- 23, 20, 22, 18, 16, 13, 11, 9, 5, 4, -2, -2, -3, -8, -9, -11,
- -12, -13, -15, -15, -15, -15, -15, -14, -12, -12, -13, -13, -8, -11, -10, -12,
- -10, -12, -12, -8, -8, -9, -9, -9, -8, -9, -10, -11, -11, -10, -13, -14,
- -13, -16, -16, -17, -17, -18, -19, -18, -17, -16, -16, -15, -15, -13, -12, -10,
- -12, -10, -9, -8, -6, -6, -3, 0, 0, 1, 2, 2, 3, 4, 4, 5,
- 6, 7, 8, 9, 10, 11, 12, 12, 13, 14, 14, 15, 15, 15, 16, 16,
- 16, 16, 16, 16, 16, 16, 16, 16, 15, 15, 14, 13, 13, 12, 11, 10,
- 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, -1, -1, -2, -3, -4, -5,
- -5, -6, -7, -7, -8, -9, -9, -10, -11, -11, -12, -12, -13, -13, -13, -13,
- -14, -14, -14, -15, -15, -15, -15, -15, -15, -16, -16, -16, -15, -15, -15, -14,
- -13, -13, -12, -11, -10, -9, -8, -7, -6, -5, -4, -2, -1, 0, 1, 2,
- 4, 5, 6, 7, 8, 9, 10, 11, 12, 12, 13, 13, 14, 14, 15, 15,
- 15, 15, 16, 16, 16, 16, 17, 17, 17, 17, 17, 17, 16, 16, 15, 15,
- 14, 14, 13, 12, 11, 10, 9, 7, 6, 5, 3, 1, 0, -2, -4, -5,
- -7, -9, -10, -11, -13, -14, -15, -15, -16, -17, -17, -18, -18, -18, -18, -18,
- -18, -18, -18, -18, -18, -18, -18, -17, -17, -16, -16, -15, -14, -14, -13, -12,
- -11, -10, -9, -8, -7, -6, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5,
- 6, 7, 8, 9, 9, 10, 11, 11, 12, 13, 13, 13, 14, 14, 14, 15,
- 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 14, 14, 14, 13, 12, 12,
- 11, 10, 9, 8, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0, -1, 0,
- 0, -1, 2, 1, 0, 1, 4, 2, 2, 2, 5, 2, 5, 5, 8, 4,
- 13, 15, 19, -62, -65, 56, -18, -128, -39, 15, -57, -10, 19, -22, -11, 36,
- 30, 5, 19, 25, 17, 21, 21, 16, 21, 18, 17, 17, 15, 14, 13, 12,
- 10, 6, 8, 6, 6, -1, 1, -4, 7, -10, -36, 35, 64, -25, -18, 83,
- 50, 22, 39, 21, 19, -4, -20, 28, 0, -88, -55, -5, -55, -83, -64, -58,
- -77, -61, -22, -39, -57, -15, 2, -14, -9, -1, 1, 1, 2, 9, 5, 6,
- 11, 9, 9, 10, 11, 12, 12, 10, 9, 9, 13, 7, 3, 14, 4, -3,
- 2, 2, 17, 40, 12, 14, 55, 58, 44, 39, 38, 37, 6, 4, 31, -6,
- -50, -25, -15, -49, -52, -41, -60, -68, -32, -25, -47, -36, -9, -5, -7, -3,
- 3, 4, 6, 8, 11, 9, 10, 14, 14, 11, 13, 15, 14, 13, 14, 12,
- 11, 12, 12, 8, 8, 3, 4, 5, -1, 8, 32, 21, 14, 43, 50, 39,
- 47, 39, 20, 23, 16, 5, -9, -23, -26, -34, -48, -37, -48, -71, -56, -34,
- -43, -49, -36, -20, -14, -13, -9, -4, -1, 1, 3, 6, 6, 6, 9, 10,
- 8, 10, 11, 11, 11, 11, 10, 10, 10, 10, 6, 6, 4, 3, 6, -3,
- 2, 25, 23, 16, 34, 38, 43, 51, 31, 19, 38, 22, -10, -7, 0, -25,
- -45, -34, -32, -54, -62, -47, -39, -45, -47, -36, -24, -19, -16, -11, -6, -3,
- 0, 2, 4, 6, 7, 8, 10, 11, 9, 11, 12, 11, 11, 12, 11, 10,
- 10, 8, 7, 6, 3, 5, 4, 0, 13, 28, 23, 19, 36, 50, 42, 30,
- 31, 39, 24, -6, -2, 7, -21, -40, -27, -34, -51, -51, -44, -42, -45, -45,
- -37, -27, -22, -18, -13, -9, -6, -2, 1, 2, 5, 7, 7, 9, 11, 10,
- 10, 12, 12, 11, 12, 11, 10, 10, 9, 7, 7, 4, 5, 7, 1, 7,
- 27, 24, 15, 34, 47, 37, 32, 36, 36, 26, 4, -1, 4, -13, -30, -27,
- -34, -47, -46, -42, -43, -45, -44, -38, -31, -25, -21, -17, -12, -8, -5, -1,
- 1, 3, 5, 6, 8, 9, 10, 10, 10, 11, 11, 11, 11, 11, 10, 9,
- 7, 7, 6, 3, 6, 5, 6, 17, 23, 19, 29, 40, 35, 33, 36, 34,
- 26, 14, 3, 0, -6, -18, -26, -32, -39, -40, -38, -39, -41, -40, -36, -31,
- -27, -23, -19, -15, -12, -8, -4, -2, 0, 3, 4, 5, 7, 8, 9, 9,
- 9, 10, 10, 10, 10, 10, 9, 8, 8, 8, 7, 8, 10, 11, 14, 19,
- 22, 25, 28, 29, 29, 29, 27, 21, 14, 7, -1, -5, -11, -19, -26, -29,
- -31, -32, -33, -34, -33, -32, -29, -26, -24, -21, -18, -15, -12, -9, -6, -4,
- -2, 0, 2, 3, 5, 6, 7, 7, 8, 8, 9, 9, 9, 9, 9, 9,
- 10, 10, 11, 12, 14, 16, 18, 20, 22, 23, 24, 24, 23, 20, 17, 12,
- 7, 2, -3, -8, -13, -17, -21, -23, -25, -26, -27, -27, -27, -26, -25, -23,
- -21, -19, -17, -14, -12, -9, -7, -5, -3, -1, 1, 2, 4, 5, 6, 6,
- 7, 7, 8, 8, 9, 9, 10, 10, 11, 12, 13, 15, 16, 18, 19, 21,
- 22, 22, 22, 21, 19, 17, 13, 9, 4, 0, -5, -10, -14, -18, -21, -23,
- -25, -26, -26, -26, -26, -25, -23, -22, -20, -18, -15, -13, -11, -9, -6, -4,
- -2, 0, 1, 3, 4, 5, 6, 7, 7, 8, 8, 8, 9, 9, 10, 11,
- 12, 13, 14, 15, 17, 18, 20, 21, 21, 21, 21, 19, 17, 14, 11, 7,
- 2, -3, -7, -11, -15, -19, -21, -23, -25, -25, -26, -25, -25, -24, -22, -21,
- -19, -17, -15, -12, -10, -8, -6, -4, -2, 0, 1, 3, 4, 5, 6, 6,
- 7, 8, 8, 9, 9, 10, 11, 11, 12, 13, 15, 16, 17, 19, 20, 20,
- 21, 20, 19, 18, 15, 12, 8, 4, 0, -4, -9, -13, -16, -19, -21, -23,
- -24, -25, -25, -25, -24, -23, -21, -20, -18, -16, -14, -12, -9, -7, -5, -3,
- -2, 0, 1, 3, 4, 5, 6, 6, 7, 8, 8, 9, 10, 10, 11, 12,
- 13, 14, 15, 17, 18, 19, 20, 20, 20, 19, 18, 16, 13, 10, 6, 2,
- -2, -6, -10, -13, -16, -19, -21, -23, -24, -24, -24, -24, -23, -22, -20, -19,
- -17, -15, -13, -11, -8, -6, -5, -3, -1, 0, 2, 3, 4, 5, 6, 7,
- 7, 8, 9, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 19, 20,
- 19, 18, 16, 14, 11, 8, 4, 0, -3, -7, -11, -14, -17, -19, -21, -22,
- -23, -23, -23, -23, -22, -21, -19, -18, -16, -14, -12, -10, -8, -6, -4, -2,
- -1, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 10, 11, 12, 12, 13,
- 14, 15, 16, 17, 18, 19, 19, 19, 18, 17, 15, 12, 9, 6, 3, -1,
- -5, -9, -12, -15, -17, -19, -21, -22, -23, -23, -23, -22, -21, -20, -18, -17,
- -15, -13, -11, -9, -7, -6, -4, -2, -1, 1, 2, 3, 4, 5, 6, 7,
- 8, 9, 9, 10, 11, 12, 13, 14, 15, 16, 17, 17, 18, 18, 18, 17,
- 16, 14, 12, 10, 7, 4, 0, -3, -6, -9, -12, -15, -17, -18, -20, -20,
- -21, -21, -21, -20, -19, -18, -17, -15, -14, -12, -10, -9, -7, -5, -4, -2,
- -1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 14,
- 15, 15, 16, 16, 16, 16, 16, 15, 14, 12, 11, 8, 6, 3, 0, -3,
- -6, -9, -12, 1, -1, 2, -1, 4, 2, 8, 5, 10, -5, 0, 5, 17,
- -11, 0, 19, -17, 26, 65, 15, 29, 3, 35, 67, 50, 88, 59, 117, 28,
- -6, -16, 29, 63, 62, -40, 59, 22, -95, -49, -55, 19, 36, -15, 26, -117,
- 60, 8, -101, -115, 23, 60, -32, -106, -84, -88, -127, -99, -117, -110, -56, -42,
- -53, -79, -44, 43, 10, -11, 72, 22, 61, 10, -92, -106, -111, -35, -68, -128,
- -67, -36, -118, -97, -96, -4, 75, 70, 113, 36, 73, 115, 37, 6, 79, 97,
- 89, -8, -38, -8, -72, -8, -29, -35, 73, 98, 66, 12, 40, 113, 106, 87,
- 126, 112, 127, 87, -3, -21, -23, 40, 14, -68, -20, 21, -57, -67, -67, -4,
- 69, 53, 90, 17, 36, 78, -7, -54, -2, 32, 21, -71, -109, -89, -124, -103,
- -114, -113, -37, -4, -30, -88, -83, 15, 13, -35, 42, 28, 33, 14, -90, -92,
- -104, -37, -34, -115, -73, -9, -75, -89, -85, -29, 67, 51, 97, 55, 47, 115,
- 46, -9, 42, 90, 96, 26, -36, 11, -43, -25, -6, -37, 59, 104, 88, 31,
- 22, 96, 116, 69, 110, 119, 119, 109, 11, -15, -26, 18, 37, -45, -32, 34,
- -13, -62, -62, -30, 61, 47, 75, 46, 14, 72, 14, -58, -35, 16, 30, -38,
- -109, -78, -109, -116, -102, -123, -57, -2, -11, -58, -95, -18, 22, -41, -3, 36,
- 20, 31, -69, -94, -100, -72, -21, -91, -92, -9, -33, -82, -81, -57, 48, 52,
- 70, 81, 35, 97, 69, -10, 8, 66, 94, 55, -27, 4, -5, -40, -1, -33,
- 30, 102, 101, 61, 19, 70, 121, 72, 77, 123, 112, 121, 36, -13, -21, -10,
- 38, -18, -43, 27, 25, -40, -59, -45, 40, 54, 52, 68, 15, 56, 35, -48,
- -58, -12, 25, -10, -98, -84, -83, -122, -101, -123, -81, -8, -3, -28, -85, -47,
- 20, -28, -39, 23, 18, 31, -38, -99, -92, -97, -35, -66, -102, -26, -3, -60,
- -77, -69, 18, 59, 47, 87, 46, 73, 86, 3, -13, 34, 80, 70, -8, -12,
- 19, -32, -12, -21, 3, 91, 105, 87, 34, 51, 114, 89, 53, 106, 115, 119,
- 65, -10, -13, -25, 20, 4, -45, 9, 44, -8, -49, -51, 14, 61, 39, 68,
- 34, 39, 51, -30, -67, -41, 7, 5, -76, -96, -65, -111, -110, -115, -103, -20,
- -1, -9, -58, -65, 8, -9, -55, -6, 17, 24, -11, -94, -89, -102, -64, -50,
- -101, -51, 6, -30, -66, -71, -12, 59, 40, 72, 67, 58, 91, 24, -21, 6,
- 56, 74, 14, -22, 23, -8, -24, -14, -13, 71, 106, 101, 62, 42, 101, 105,
- 49, 76, 114, 114, 87, 3, -12, -23, -6, 13, -37, -11, 45, 24, -29, -49,
- -8, 57, 40, 53, 54, 32, 56, -6, -65, -61, -21, 6, -52, -101, -65, -85,
- -115, -109, -116, -42, 0, -1, -27, -65, -12, 7, -51, -37, 7, 17, 6, -76,
- -95, -94, -91, -52, -90, -76, -2, -4, -46, -66, -35, 46, 46, 49, 78, 57,
- 85, 50, -17, -13, 26, 64, 34, -22, 9, 18, -22, -14, -18, 42, 103, 105,
- 88, 50, 83, 114, 63, 49, 96, 110, 99, 26, -14, -15, -23, 6, -24, -29,
- 33, 45, 0, -38, -23, 44, 50, 37, 60, 38, 52, 21, -54, -70, -48, -7,
- -31, -95, -78, -63, -104, -108, -117, -69, -4, -1, -5, -47, -30, 13, -33, -58,
- -14, 8, 11, -50, -99, -87, -101, -70, -77, -92, -22, 10, -22, -52, -46, 23,
- 55, 36, 70, 66, 74, 69, -2, -23, 1, 43, 43, -11, -8, 29, -4, -17,
- -16, 18, 91, 105, 102, 71, 72, 112, 83, 40, 70, 101, 102, 50, -10, -10,
- -24, -10, -13, -36, 14, 52, 27, -18, -28, 26, 58, 33, 51, 49, 46, 40,
- -34, -70, -66, -31, -22, -81, -92, -56, -83, -105, -112, -91, -17, 0, 2, -22,
- -37, 7, -12, -61, -39, -5, 7, -27, -93, -90, -96, -90, -72, -95, -48, 9,
- -1, -33, -46, 0, 55, 37, 50, 72, 68, 77, 20, -25, -15, 17, 40, 3,
- -20, 22, 19, -12, -14, 2, 70, 105, 106, 92, 72, 104, 100, 48, 46, 83,
- 98, 70, 3, -12, -16, -23, -11, -34, -8, 46, 47, 11, -21, 8, 57, 41,
- 36, 53, 45, 48, -6, -64, -72, -57, -28, -61, -98, -65, -60, -94, -105, -103,
- -41, 1, 0, -1, -29, -6, 5, -48, -60, -26, -3, -12, -74, -97, -86, -100,
- -80, -89, -74, -6, 13, -10, -35, -18, 41, 48, 33, 64, 68, 75, 46, -15,
- -25, -7, 24, 16, -20, 4, 33, 5, -11, -5, 43, 98, 105, 105, 85, 93,
- 110, 67, 35, 59, 87, 81, 25, -13, -9, -23, -18, -27, -25, 30, 55, 37,
- -1, -3, 46, 53, 29, 44, 47, 48, 20, -48, -72, -72, -47, -48, -93, -82,
- -51, -73, -96, -102, -66, -6, 0, 5, -10, -16, 10, -26, -66, -49, -20, -10,
- -51, -98, -86, -93, -93, -85, -88, -32, 14, 8, -16, -23, 22, 54, 32, 45,
- 67, 70, 61, 4, -27, -21, 2, 17, -13, -13, 29, 26, -1, -5, 23, 83,
- 104, 106, 100, 90, 110, 87, 40, 38, 68, 80, 45, -6, -9, -14, -24, -23,
- -32, 8, 52, 53, 25, 1, 31, 60, 35, 30, 45, 45, 36, -24, -68, -76,
- -67, -49, -80, -94, -57, -54, -81, -95, -82, -23, 2, 1, 4, -12, 4, -5,
- -57, -65, -40, -20, -36, -87, -94, -83, -97, -87, -90, -57, 2, 18, 2, -12,
- 8, 10, -20, 30, 25, 21, 14, 4, 15, -48, -33, 11, -70, 54, -5, -21,
- -8, -3, 73, -52, 65, -55, 80, -28, -67, -3, -13, 21, -49, -2, 11, 36,
- 59, -60, 34, -28, 21, -25, -45, 54, 5, 0, -19, -12, 20, 54, -51, -23,
- 22, 36, -59, -20, 8, 28, -9, -54, 127, -44, 69, -128, 5, 69, -8, -98,
- 45, 69, 20, -97, 23, -7, 121, -81, -2, -21, 51, -67, -14, -24, 127, -60,
- 45, -116, 127, -29, -93, -23, 107, -5, -21, -62, 37, 41, 29, -74, -63, 103,
- 24, -59, -44, 62, 43, -28, -46, 7, 72, 19, -70, -47, 42, 53, -68, -13,
- 37, 59, -38, -60, 39, 66, 27, -128, 36, 77, 15, -74, -15, 75, 38, -49,
- -11, -39, 16, -8, -30, 35, 41, -1, -2, 17, -68, 99, -97, 60, -49, 32,
- -44, -29, 82, -26, 39, -35, 10, 38, -20, -21, -92, 83, -24, 13, 31, -33,
- 22, 45, -31, -24, 9, -24, -32, 42, -17, 34, 7, -27, 6, 61, -9, -34,
- -5, -8, -17, -6, -34, 17, 43, -9, 35, -34, 16, 27, -24, -17, -17, 5,
- -17, 42, -31, 22, 17, -26, -22, 32, 41, -27, -25, -10, -5, 16, -2, 13,
- -1, 48, -33, -27, 6, 16, 13, -37, -11, 18, 25, -42, -11, 46, -7, -15,
- 9, 15, 4, -3, -36, -24, 31, -8, 14, 12, 27, -19, -17, -14, -7, 42,
- -5, -15, 5, 1, -15, 14, 43, -19, 1, -25, -35, 16, 16, 29, -12, 8,
- -14, 1, 21, -8, -12, -22, -4, 24, 26, -16, -22, 37, 3, -41, 7, 4,
- 3, 30, 4, -27, 11, -6, -26, 33, 23, -23, -14, -20, -7, -4, 36, 0,
- 18, 10, -27, 1, 1, 16, -1, -4, -44, -5, 17, 9, 13, -4, -3, 31,
- 24, -14, -26, 9, -27, -28, 19, 22, 32, -11, -15, 5, 15, -23, -21, 16,
- 14, 18, -11, -26, 13, 10, -12, -12, 11, 14, -6, -13, -3, 6, -6, 3,
- 12, 32, 14, -22, -45, -10, 37, 11, -50, -11, 50, 22, -13, -4, -4, 15,
- -16, -33, 7, 34, -9, -14, -1, 21, 15, -14, -12, -6, 7, 8, 2, 0,
- -5, 6, 15, 4, -9, 13, 3, -51, -18, 27, 10, 5, -11, 6, -1, 5,
- 22, 2, -14, -39, -12, 19, 17, 4, 11, 5, -25, 2, 23, 8, 2, -3,
- -39, -22, 4, 18, 6, 14, 25, 20, -17, -20, 17, 7, -43, -38, -18, 17,
- 24, -6, 30, 44, 6, -36, -20, 7, 24, 1, -69, -25, 47, 15, -4, 35,
- 19, -18, -22, -12, 20, 39, -36, -49, 9, 28, -16, 9, 34, 36, -22, -69,
- -16, 39, 7, -28, -3, 33, -18, -7, 18, 53, 24, -37, -61, -10, 38, 2,
- -24, -11, 12, 17, 0, 28, 50, -5, -59, -57, 22, 14, -15, -5, 22, 9,
- -20, 19, 33, 31, -33, -62, -13, -2, 45, -9, -4, -3, 19, 8, -8, 40,
- 8, -16, -44, -19, 16, 3, 23, -32, 22, 5, -9, 5, 26, 21, -27, -18,
- -45, 3, 15, 0, 7, 7, 7, 13, 18, -10, 3, -5, -30, -30, -3, 9,
- 31, 17, -10, 19, 28, -33, -20, 31, 14, -67, -27, 13, 20, 29, 1, -2,
- 24, -3, -26, -12, 32, -7, -31, -17, 5, 22, 11, -6, 6, 7, 2, 7,
- 5, -12, -22, -17, -24, 22, 47, 1, 2, 10, 5, -29, -5, 13, 1, -30,
- -28, -5, 23, 25, 6, 5, 1, 7, 0, 5, 3, -33, -37, -6, 19, 20,
- 26, -1, -15, 21, 9, -14, -13, 0, -11, -24, -9, 9, 23, 1, 1, 32,
- 11, -25, -18, 5, -5, -6, -9, -10, 2, 18, 4, 12, 6, -2, -8, 2,
- 2, -7, 2, -22, -5, 17, 25, 15, -5, -1, -24, -8, -10, -5, 12, 7,
- -4, -10, 4, 8, 22, 11, -1, -12, -31, -17, 6, 12, 11, 5, -3, -1,
- 22, 0, -4, 3, -18, -17, -3, 16, 9, 2, -5, 0, 4, -9, 18, 17,
- -22, -19, -8, -6, 21, 11, -6, -16, 33, 13, -15, -3, -15, 1, -3, -10,
- -7, 8, 17, -11, 9, 19, 0, 5, 0, -18, -13, 2, -20, 10, 29, -11,
- -13, 5, 11, 16, 4, -25, -21, 13, -5, 1, 3, -1, 6, 13, -7, -1,
- 17, -6, -6, -9, -6, -3, -1, 1, 18, 11, -22, 2, 18, -2, -15, 1,
- 5, -12, -10, -7, 9, 26, 10, -11, 5, 0, -7, -3, -11, -9, -3, 2,
- -10, 19, 28, -3, -3, -4, 9, -14, -5, -7, 8, -3, -27, 5, 37, 11,
- -2, 3, -27, -15, 12, -2, 14, 2, -8, -16, 22, 11, -1, 10, -17, -8,
- -5, -23, 2, 29, 8, -21, 8, 12, 6, 8, -17, 3, -2, -12, -27, 16,
- 25, -5, -7, 2, 19, 1, -15, 7, 2, -5, -34, 2, 18, 17, -10, 2,
- 18, -1, -12, -10, 5, 1, -16, -9, 12, 21, 4, -10, 2, 12, 1, -19,
- -11, 20, 5, -14, -21, 5, 17, -5, 3, 17, 4, -25, -5, 5, 4, 0,
- -5, 2, 2, -1, 1, 13, 0, -11, -8, 3, 2, -1, -3, -3, 11, 8,
- -6, 2, 7, 4, -5, -23, -2, 14, -1, -15, -2, 15, 10, 1, -4, 16,
- 1, -24, -12, 8, 8, -20, -2, 14, 13, 10, 2, 2, -9, -6, -9, -3,
- 5, 7, -3, -9, 0, 2, 8, 3, -1, 2, -4, 0, -1, -1, -1, -2,
- -8, -14, -19, -28, -51, -53, -49, -48, -49, -44, -37, -30, -23, -14, -8, -11,
- -5, 3, 11, 2, 0, 8, 19, 10, 1, 6, 18, 15, 4, 4, 17, 19,
- 13, 9, 20, 27, 26, 26, 33, 42, 45, 53, 59, 68, 69, 83, 89, 92,
- 85, 88, 91, 80, 56, 37, 29, 9, -25, -54, -65, -74, -94, -113, -112, -103,
- -101, -103, -93, -79, -66, -62, -50, -41, -33, -27, -17, -11, -12, -8, 0, 7,
- -1, -2, 5, 15, 8, -1, 3, 15, 13, 2, 2, 12, 17, 12, 8, 15,
- 23, 24, 25, 29, 38, 42, 50, 56, 65, 68, 78, 87, 91, 87, 87, 91,
- 84, 64, 43, 33, 16, -14, -44, -60, -70, -87, -107, -111, -105, -101, -103, -96,
- -84, -70, -64, -55, -45, -36, -30, -22, -14, -14, -11, -4, 4, 0, -3, 1,
- 11, 8, -1, 0, 10, 12, 3, 0, 9, 15, 11, 7, 14, 22, 23, 24,
- 28, 37, 42, 49, 55, 64, 67, 78, 87, 91, 88, 88, 93, 86, 67, 47,
- 36, 20, -10, -40, -56, -67, -84, -104, -109, -105, -101, -103, -96, -85, -71, -65,
- -56, -46, -38, -31, -23, -16, -15, -12, -6, 2, -1, -5, 0, 9, 6, -1,
- -1, 8, 11, 3, 0, 8, 14, 11, 7, 13, 21, 23, 23, 27, 37, 41,
- 48, 54, 63, 67, 77, 86, 91, 89, 89, 93, 87, 70, 51, 39, 23, -6,
- -36, -53, -64, -81, -101, -107, -103, -100, -102, -96, -85, -72, -66, -57, -47, -39,
- -32, -25, -17, -16, -13, -7, 0, -3, -5, -1, 7, 6, -2, -2, 7, 9,
- 2, -1, 7, 13, 10, 7, 12, 20, 22, 23, 27, 36, 41, 48, 54, 63,
- 68, 77, 87, 91, 91, 91, 95, 89, 73, 54, 43, 27, -1, -31, -49, -61,
- -78, -98, -105, -102, -99, -101, -96, -85, -73, -66, -58, -48, -40, -33, -26, -19,
- -17, -14, -9, -2, -4, -6, -3, 5, 4, -3, -3, 5, 8, 1, -1, 6,
- 12, 10, 7, 11, 20, 22, 23, 27, 35, 41, 47, 54, 62, 68, 76, 86,
- 91, 91, 92, 96, 91, 76, 58, 46, 30, 3, -27, -45, -57, -75, -94, -103,
- -100, -98, -100, -96, -85, -74, -67, -59, -49, -41, -34, -28, -20, -19, -15, -10,
- -3, -5, -7, -4, 3, 3, -4, -4, 4, 7, 1, -2, 5, 11, 9, 6,
- 11, 19, 21, 22, 26, 35, 40, 46, 53, 61, 67, 76, 86, 91, 92, 93,
- 97, 93, 78, 61, 49, 33, 7, -22, -41, -54, -72, -91, -100, -99, -97, -100,
- -96, -86, -74, -67, -60, -51, -42, -35, -29, -22, -20, -17, -11, -5, -6, -8,
- -5, 2, 1, -5, -5, 2, 5, 0, -3, 3, 10, 8, 5, 10, 18, 21,
- 21, 25, 34, 39, 45, 52, 61, 67, 75, 85, 91, 92, 94, 97, 94, 81,
- 64, 52, 37, 11, -18, -37, -51, -69, -88, -98, -98, -96, -99, -95, -86, -75,
- -68, -61, -52, -44, -36, -30, -23, -21, -17, -13, -6, -7, -9, -6, 0, 0,
- -5, -5, 1, 4, -1, -3, 2, 8, 8, 5, 10, 17, 20, 21, 25, 33,
- 39, 45, 51, 60, 66, 75, 85, 91, 93, 94, 98, 95, 83, 67, 55, 40,
- 15, -14, -33, -48, -66, -85, -96, -96, -95, -98, -95, -86, -75, -69, -62, -53,
- -45, -38, -32, -25, -22, -19, -14, -8, -9, -10, -8, -2, -1, -6, -7, -1,
- 2, -2, -4, 1, 7, 6, 5, 8, 16, 19, 20, 24, 32, 38, 44, 50,
- 59, 66, 74, 84, 91, 93, 95, 99, 97, 85, 70, 58, 43, 18, -10, -30,
- -45, -63, -82, -93, -95, -94, -97, -95, -87, -76, -70, -63, -54, -46, -39, -33,
- -26, -23, -20, -16, -10, -10, -12, -9, -3, -3, -7, -8, -2, 1, -2, -5,
- 0, 6, 6, 4, 8, 15, 18, 20, 23, 31, 37, 43, 50, 58, 65, 74,
- 83, 91, 93, 96, 100, 98, 87, 72, 61, 46, 22, -6, -27, -42, -60, -79,
- -91, -94, -93, -97, -95, -87, -77, -70, -64, -55, -47, -40, -34, -28, -25, -22,
- -17, -12, -11, -13, -11, -5, -4, -8, -9, -3, 0, -4, -6, -1, 5, 5,
- 3, 7, 14, 18, 19, 23, 30, 36, 42, 49, 57, 65, 73, 83, 90, 94,
- 96, 100, 99, 89, 75, 63, 49, 25, -2, -23, -38, -56, -76, -88, -92, -92,
- -95, -94, -87, -77, -71, -65, -57, -48, -41, -36, -29, -26, -23, -19, -13, -12,
- -14, -12, -7, -6, -9, -10, -5, -1, -4, -7, -2, 2, 5, 4, 6, 12,
- 18, 20, 24, 30, 38, 45, 52, 61, 70, 79, 89, 99, 106, 109, 113, 115,
- 109, 96, 81, 66, 44, 16, -12, -32, -52, -74, -92, -101, -104, -107, -108, -103,
- -94, -85, -78, -70, -60, -52, -45, -38, -33, -29, -25, -19, -16, -17, -16, -12,
- -9, -10, -12, -9, -5, -5, -7, -5, 0, 3, 3, 5, 11, 17, 20, 23,
- 29, 37, 44, 51, 59, 69, 78, 88, 98, 105, 110, 114, 116, 110, 98, 84,
- 69, 48, 20, -7, -29, -49, -71, -89, -99, -102, -105, -107, -103, -94, -86, -79,
- -71, -62, -54, -47, -40, -34, -30, -26, -21, -18, -18, -17, -14, -10, -12, -14,
- -11, -5, -10, 43, -94, 44, -13, 27, -98, 1, 9, 77, 63, 4, 8, -128,
- 63, -73, 78, -116, 127, -14, 111, -87, -67, -43, -45, 38, 53, 99, -37, 14,
- -51, -58, -23, -32, 34, 27, 75, 9, 51, -104, -71, -33, 27, 67, 0, -1,
- 25, 0, -35, 1, -70, 28, -4, 109, 3, 5, -42, -7, 42, -15, 37, -62,
- 67, -14, 48, -85, -46, -94, 37, 35, 23, 15, -79, 35, -50, 91, -64, 40,
- -69, 46, 20, 43, -21, -51, 8, -1, 95, -47, 69, -104, 98, -44, 74, -61,
- -14, -19, 7, 52, -40, 8, -89, 58, -53, 106, -106, 42, -82, 61, -1, -8,
- -10, -59, 53, -18, 85, -83, 63, -73, 89, -32, 50, -62, 10, 13, 20, 62,
- -81, 41, -84, 88, -32, 41, -78, 27, -30, 51, -6, -42, 6, -49, 74, -41,
- 41, -89, 27, -33, 57, 0, -16, -8, -4, 45, 8, 20, -63, 36, -29, 75,
- -23, -17, -23, -14, 45, -7, 17, -56, 20, -12, 45, -16, -13, -31, 6, 31,
- -7, 17, -81, 40, -35, 73, -34, 0, -31, 10, 35, -4, 19, -60, 44, -30,
- 83, -66, 41, -87, 59, -6, 23, -4, -59, 34, -33, 77, -70, 49, -89, 88,
- -45, 63, -62, 4, -20, 18, 46, -49, 45, -101, 91, -56, 78, -79, 35, -51,
- 67, -12, -2, -14, -49, 66, -35, 72, -87, 51, -74, 83, -38, 29, -36, -10,
- 23, 3, 30, -59, 27, -59, 91, -44, 41, -63, 12, 2, 23, 8, -36, 14,
- -35, 66, -38, 32, -59, 25, -11, 40, -6, -25, -2, -24, 55, -25, 29, -58,
- 30, -17, 41, -18, -17, -3, -13, 50, -25, 26, -63, 35, -23, 50, -22, -5,
- -18, 0, 33, -19, 22, -67, 57, -39, 63, -45, 6, -27, 13, 23, -6, 15,
- -55, 44, -42, 70, -59, 36, -60, 56, -13, 15, -9, -50, 49, -38, 72, -63,
- 37, -65, 67, -48, 55, -51, 10, 2, -5, 45, -61, 46, -83, 91, -58, 72,
- -69, 23, -27, 35, -8, -3, -2, -33, 66, -61, 79, -100, 67, -60, 66, -26,
- 13, -21, -13, 23, -11, 29, -49, 40, -53, 80, -67, 52, -63, 28, 6, -1,
- 23, -45, 25, -30, 42, -25, 22, -42, 33, -26, 39, -26, -9, 10, -28, 61,
- -50, 33, -43, 18, 2, 6, 4, -18, 4, -8, 24, -21, 22, -49, 50, -40,
- 52, -35, -10, 17, -34, 64, -53, 38, -47, 37, -28, 40, -47, 33, -32, 28,
- 3, -20, 30, -69, 79, -75, 88, -72, 39, -34, 22, -7, 9, -18, 1, 19,
- -27, 58, -89, 81, -90, 89, -58, 42, -27, -5, 16, -21, 29, -34, 28, -37,
- 59, -65, 72, -90, 69, -45, 31, 6, -36, 40, -53, 56, -47, 39, -42, 40,
- -38, 50, -52, 34, -31, 7, 32, -47, 62, -79, 66, -51, 41, -27, 12, -10,
- 12, -5, 3, -5, -18, 33, -44, 70, -75, 60, -52, 27, 4, -19, 22, -29,
- 27, -15, 18, -31, 26, -36, 50, -41, 35, -31, 3, 19, -37, 55, -62, 51,
- -38, 25, -11, 1, -13, 12, -7, 13, 4, -33, 38, -56, 72, -64, 52, -43,
- 20, 6, -20, 25, -40, 34, -25, 38, -41, 43, -68, 68, -59, 53, -28, -7,
- 27, -45, 63, -70, 56, -60, 59, -41, 48, -56, 39, -43, 35, -3, -19, 40,
- -70, 85, -81, 76, -75, 48, -36, 41, -20, 12, -23, 0, 16, -23, 51, -76,
- 78, -82, 80, -57, 29, -23, 3, 14, -2, 9, -29, 17, -31, 55, -51, 53,
- -66, 49, -27, 17, 3, -35, 36, -33, 44, -27, 11, -30, 24, -18, 37, -29,
- 4, -3, -15, 45, -47, 42, -57, 46, -19, 18, -11, -20, 10, -3, 24, -18,
- 14, -46, 52, -50, 64, -57, 25, -14, 1, 33, -42, 30, -52, 50, -28, 47,
- -54, 32, -49, 53, -25, 14, -4, -34, 57, -54, 69, -78, 46, -45, 52, -21,
- 21, -37, 7, 1, 3, 29, -57, 56, -74, 90, -66, 47, -51, 16, 6, 10,
- 10, -29, 9, -32, 58, -47, 59, -84, 65, -49, 52, -24, -18, 14, -30, 61,
- -39, 31, -57, 39, -38, 67, -56, 37, -46, 26, 10, -15, 18, -49, 45, -27,
- 42, -37, 11, -24, 30, -15, 21, -34, 15, -5, 11, 5, -24, 11, -16, 30,
- -16, 6, -20, 7, 3, 11, -9, -5, -6, 4, 16, -15, 9, -29, 22, -6,
- 14, -6, -16, 9, -12, 28, -22, 15, -27, 22, -11, 21, -23, 5, -10, 8,
- 17, -22, 19, -42, 41, -31, 39, -37, 20, -20, 19, -3, -7, 2, -17, 27,
- -20, 30, -43, 30, -34, 38, -24, 13, -13, -1, 16, -16, 19, -36, 28, -21,
- 30, -22, 7, -17, 11, 2, 1, 1, -19, 22, -21, 32, -34, 18, -21, 17,
- 6, -8, 5, -25, 21, -13, 24, -24, 12, -22, 24, -11, 10, -14, -7, 15,
- -11, 28, -36, 21, -30, 30, -10, 10, -13, -5, 6, -2, 14, -22, 15, -25,
- 33, -22, 23, -31, 11, -6, 8, 11, -21, 14, -28, 32, -23, 25, -31, 19,
- -15, 19, -7, -7, 1, -13, 26, -19, 24, -37, 25, -24, 30, -18, 6, -9,
- -2, 17, -16, 17, -34, 27, -19, 28, -21, 6, -15, 10, 4, 0, 2, -20,
- 22, -19, -21, 0, -3, -3, 2, 1, -1, 2, -2, -1, 4, 3, -3, -15,
- -21, -20, -23, -42, -45, -31, -27, -17, -8, 9, 29, 41, 44, 33, 20, 13,
- 6, 12, 16, 25, 43, 44, 33, 33, 35, 15, -5, -3, 8, 16, 8, -10,
- -6, 8, 4, -4, 1, -18, -38, -43, -51, -54, -55, -71, -85, -68, -58, -61,
- -50, -33, -27, -15, -5, 22, 67, 100, 109, 114, 110, 91, 69, 50, 37, 35,
- 46, 48, 37, 36, 14, -24, -38, -42, -38, -38, -59, -91, -86, -57, -44, -32,
- -15, -26, -44, -30, -30, -30, -16, -31, -50, -34, -43, -59, -49, -44, -52, -62,
- -69, -50, -4, 47, 83, 105, 120, 111, 88, 72, 55, 57, 76, 69, 59, 55,
- 41, 10, -18, -32, -28, -19, -36, -68, -76, -72, -71, -46, -35, -47, -43, -43,
- -61, -48, -28, -25, -22, -19, -23, -15, -7, 3, 4, -8, -28, -37, -5, 42,
- 72, 107, 127, 122, 117, 90, 48, 37, 48, 51, 54, 56, 43, 24, -8, -37,
- -33, -11, -28, -55, -61, -75, -75, -51, -58, -55, -33, -33, -41, -35, -30, -21,
- -16, -17, -24, -26, -20, -18, -17, -12, -36, -72, -65, -45, -6, 53, 88, 106,
- 119, 107, 71, 52, 50, 59, 75, 87, 85, 76, 43, -1, -7, 9, -1, -13,
- -34, -69, -80, -74, -80, -73, -65, -67, -65, -56, -44, -33, -23, -18, -24, -25,
- -16, -20, -9, -1, -21, -38, -55, -64, -40, 3, 39, 82, 113, 114, 95, 71,
- 54, 56, 68, 76, 87, 94, 57, 10, -9, -17, -17, -15, -35, -60, -75, -89,
- -92, -85, -76, -71, -74, -70, -53, -41, -20, -9, -9, 4, 4, 10, 33, 38,
- 25, 15, -17, -43, -33, -15, 3, 40, 77, 94, 91, 69, 37, 31, 33, 37,
- 68, 96, 82, 53, 25, 8, 22, 28, 9, -9, -27, -46, -56, -65, -62, -61,
- -60, -51, -51, -39, -25, -23, -11, -3, -15, -10, 5, 12, 20, 18, -11, -41,
- -52, -47, -34, -2, 33, 65, 82, 70, 51, 45, 28, 21, 49, 74, 86, 74,
- 33, 5, 10, 14, 7, -10, -28, -45, -67, -68, -73, -76, -66, -66, -65, -46,
- -39, -31, -9, -3, -6, 1, 8, 22, 41, 49, 33, 8, -16, -34, -30, -17,
- 7, 49, 73, 64, 63, 50, 19, 5, 13, 32, 62, 65, 37, 8, -5, 4,
- -1, -8, -15, -36, -50, -57, -71, -65, -53, -58, -49, -37, -40, -28, -10, -3,
- 0, 2, -2, 5, 30, 41, 36, 22, -7, -33, -39, -46, -30, 15, 44, 56,
- 72, 65, 44, 21, 2, 15, 42, 59, 49, 18, 2, -3, -4, 0, -10, -25,
- -34, -52, -65, -59, -56, -50, -37, -33, -33, -25, -12, -2, 10, 12, 3, 6,
- 27, 42, 52, 43, 16, -3, -24, -48, -41, -11, 16, 48, 67, 78, 75, 49,
- 21, 13, 36, 64, 63, 47, 25, -1, -2, 2, -12, -18, -28, -53, -65, -71,
- -76, -70, -55, -53, -49, -41, -35, -24, -1, 5, 1, 4, 8, 28, 51, 43,
- 26, 18, -14, -42, -51, -49, -23, 5, 31, 55, 67, 58, 26, -2, 11, 35,
- 49, 55, 35, 8, 3, -2, -5, -6, -13, -30, -38, -49, -61, -56, -45, -43,
- -36, -31, -37, -25, -7, 1, 6, 1, -10, 11, 33, 29, 27, 17, -6, -34,
- -58, -67, -57, -34, -4, 21, 50, 63, 37, 11, 8, 17, 45, 63, 55, 39,
- 26, 12, 11, 10, -1, -11, -19, -35, -51, -52, -52, -45, -35, -36, -41, -31,
- -24, -9, 9, -3, -12, 2, 19, 33, 40, 37, 25, -3, -30, -51, -59, -42,
- -24, -3, 38, 58, 51, 32, 8, 2, 25, 45, 50, 49, 35, 18, 16, 19,
- 10, 9, 4, -13, -27, -36, -45, -36, -24, -32, -29, -31, -33, -10, 6, 1,
- -4, -6, 4, 19, 30, 37, 30, 12, -13, -48, -59, -57, -56, -35, 2, 31,
- 48, 41, 12, -2, 7, 25, 41, 52, 44, 29, 25, 22, 18, 20, 15, 1,
- -6, -26, -38, -28, -26, -21, -17, -31, -33, -19, -4, 0, -8, -16, -15, -11,
- 9, 19, 22, 24, -2, -34, -49, -61, -70, -57, -32, 4, 38, 46, 26, 5,
- -1, 7, 29, 45, 44, 38, 32, 23, 27, 30, 23, 24, 14, -8, -16, -24,
- -24, -12, -10, -19, -27, -26, -9, -2, -4, -6, -16, -14, -2, 8, 23, 34,
- 17, -6, -26, -47, -61, -62, -50, -18, 26, 50, 48, 31, 12, 6, 24, 40,
- 44, 51, 40, 29, 34, 28, 27, 32, 20, 7, -5, -23, -26, -19, -9, -12,
- -25, -25, -17, -8, 1, -4, -13, -12, -16, -9, 13, 26, 23, 8, -13, -37,
- -55, -71, -78, -59, -18, 16, 35, 34, 8, -3, 4, 13, 31, 40, 34, 34,
- 29, 23, 30, 31, 27, 21, 7, -6, -21, -21, -10, -10, -19, -24, -28, -17,
- -6, -8, -9, -9, -19, -21, -5, 12, 23, 22, 5, -16, -34, -55, -80, -78,
- -56, -22, 18, 33, 24, 14, 3, 7, 25, 31, 37, 41, 33, 29, 29, 32,
- 33, 30, 24, 7, -16, -22, -18, -15, -14, -24, -31, -22, -13, -12, -8, -6,
- -18, -27, -22, -6, -5, -1, -1, -1, 1, 2, 7, 13, 19, 10, -12, -31,
- -13, 17, 29, -4, -29, 24, 53, 18, 92, 15, -15, 23, 13, -35, -52, 127,
- 9, 3, -9, 31, -63, -64, -5, -50, 14, 33, -29, -42, 0, 43, 39, -15,
- -59, -45, 3, 33, 12, -35, -10, 51, 18, 49, 55, -28, 16, 4, 3, -64,
- 54, 53, -12, 0, 5, -4, -72, -7, -31, -14, 26, -2, -37, -14, 17, 35,
- 4, -33, -45, -12, 15, 21, -16, -23, 22, 28, 12, 55, -7, -2, 7, 7,
- -34, -10, 65, -4, 1, -5, 14, -46, -28, -9, -29, 13, 13, -23, -23, 4,
- 27, 18, -17, -39, -25, 5, 20, 0, -26, 1, 34, 7, 41, 24, -20, 11,
- 1, -6, -45, 53, 22, -6, -4, 9, -17, -52, -4, -30, -6, 20, -9, -29,
- -8, 18, 27, -2, -33, -36, -6, 16, 13, -20, -16, 27, 19, 18, 49, -17,
- 3, 2, 6, -42, 9, 55, -9, 1, -3, 9, -54, -19, -16, -24, 16, 7,
- -27, -19, 8, 28, 12, -22, -40, -20, 8, 19, -7, -25, 9, 31, 7, 48,
- 9, -14, 9, 2, -17, -35, 62, 9, -2, -6, 13, -30, -44, -4, -31, 2,
- 18, -15, -27, -3, 22, 24, -8, -36, -32, -2, 17, 8, -23, -9, 31, 13,
- 28, 40, -21, 8, 1, 3, -47, 29, 43, -9, 0, 1, 1, -57, -11, -22,
- -17, 19, 2, -28, -14, 12, 29, 7, -27, -39, -14, 11, 17, -13, -22, 17,
- 27, 10, 51, -4, -7, 7, 5, -27, -19, 64, -1, 1, -6, 14, -41, -34,
- -8, -30, 8, 15, -20, -24, 2, 25, 20, -14, -38, -27, 2, 18, 2, -25,
- -1, 33, 9, 37, 29, -21, 11, 0, -3, -46, 46, 29, -7, -2, 7, -9,
- -54, -6, -27, -10, 20, -4, -28, -9, 16, 28, 1, -30, -37, -8, 14, 14,
- -18, -17, 25, 22, 16, 50, -13, 1, 4, 5, -37, 0, 59, -7, 2, -4,
- 12, -49, -24, -13, -26, 13, 11, -23, -19, 6, 27, 15, -19, -39, -21, 6,
- 18, -4, -24, 7, 32, 8, 45, 15, -16, 10, 2, -12, -39, 58, 16, -3,
- -5, 11, -22, -48, -4, -30, -2, 19, -10, -26, -4, 20, 25, -5, -34, -33,
- -4, 16, 10, -21, -11, 30, 16, 25, 43, -19, 7, 1, 4, -44, 20, 49,
- -8, 1, -1, 6, -54, -15, -19, -20, 17, 6, -26, -15, 10, 29, 9, -23,
- -39, -16, 9, 17, -10, -22, 15, 29, 10, 50, 2, -10, 8, 3, -22, -26,
- 63, 5, 0, -6, 14, -34, -39, -6, -30, 4, 17, -15, -24, 0, 24, 22,
- -11, -36, -28, 1, 17, 5, -23, -3, 32, 12, 34, 33, -21, 10, 0, 0,
- -46, 39, 36, -7, -1, 4, -3, -54, -9, -24, -14, 19, 0, -26, -10, 14,
- 28, 4, -27, -37, -11, 12, 15, -15, -18, 22, 24, 14, 50, -9, -2, 5,
- 5, -32, -8, 61, -3, 2, -5, 14, -44, -29, -10, -27, 10, 13, -20, -20,
- 4, 26, 17, -16, -37, -23, 4, 18, -1, -23, 5, 32, 9, 42, 20, -18,
- 11, 1, -7, -41, 53, 22, -4, -3, 9, -14, -50, -6, -27, -7, 19, -6,
- -26, -5, 18, 26, -2, -31, -34, -6, 14, 11, -19, -12, 28, 19, 22, 45,
- -17, 4, 2, 5, -40, 11, 54, -6, 2, -3, 10, -51, -20, -16, -23, 14,
- 9, -23, -15, 8, 28, 12, -20, -38, -18, 7, 17, -7, -22, 13, 30, 10,
- 47, 7, -12, 9, 2, -17, -31, 61, 10, 0, -5, 13, -26, -43, -6, -29,
- 0, 18, -11, -23, -1, 22, 23, -8, -34, -30, -1, 15, 7, -22, -5, 31,
- 14, 30, 37, -20, 9, 0, 2, -44, 30, 42, -7, 1, 2, 2, -53, -12,
- -21, -17, 17, 4, -25, -11, 12, 28, 6, -25, -37, -13, 10, 15, -13, -18,
- 20, 26, 13, 49, -5, -5, 6, 4, -27, -16, 62, 1, 2, -5, 14, -38,
- -34, -9, -28, 6, 15, -16, -20, 3, 25, 19, -13, -36, -25, 2, 16, 1,
- -23, 3, 32, 11, 38, 25, -19, 11, 0, -4, -43, 46, 29, -4, -2, 7,
- -8, -51, -8, -25, -10, 18, -2, -25, -7, 16, 27, 0, -28, -35, -8, 12,
- 12, -17, -13, 26, 21, 19, 46, -14, 2, 3, 4, -36, 2, 57, -4, 3,
- -4, 12, -46, -25, -13, -25, 11, 12, -20, -16, 7, 27, 14, -18, -37, -20,
- 5, 16, -5, -21, 10, 31, 10, 45, 12, -14, 10, 1, -12, -36, 57, 16,
- -1, -4, 11, -20, -46, -6, -28, -4, 18, -8, -23, -3, 20, 24, -5, -32,
- -31, -4, 13, 8, -20, -6, 29, 17, 27, 39, -19, 7, 0, 3, -42, 21,
- 47, -6, 2, 0, 7, -51, -17, -18, -20, 15, 7, -23, -12, 10, 28, 8,
- -22, -37, -15, 8, 15, -10, -19, 18, 27, 13, 47, 0, -8, 8, 3, -24,
- -20, 52, -36, -2, 0, -2, 3, 5, -4, -28, 22, -43, 36, -13, -127, -43,
- 2, -18, 126, 78, -127, -48, 68, -74, -67, 33, 62, 83, 42, -32, -46, -70,
- -26, 115, 21, -66, 72, 52, -27, 44, 50, 50, 61, 28, -12, 3, -59, 49,
- 3, -19, 39, 94, 16, 31, 6, 29, 3, -100, -1, -4, -60, 19, 7, -29,
- -28, -38, -3, -47, -20, -21, -1, 5, -55, -12, -55, -39, 26, 47, -22, -9,
- -41, -21, -19, -37, 0, 45, -56, 24, 75, -50, -9, 31, 28, 26, 13, -3,
- -15, -27, 1, 1, -31, -10, 38, -1, 7, 43, 19, 21, 41, 33, 9, -17,
- -3, -42, -76, -30, -8, -9, -1, 21, 22, 38, 32, 22, 0, -18, -32, -58,
- -12, 5, -48, -13, 64, 29, -2, 2, 19, 43, 25, -19, -39, -69, -92, -15,
- 23, 30, 30, 51, 37, 35, 37, 30, -27, -63, 5, -30, -56, -16, 26, 52,
- 20, 14, 59, 27, -9, 22, -4, -20, -37, -17, -34, -34, -1, 35, 26, 31,
- 5, -16, 4, 33, 22, 8, 5, -28, -41, -20, -10, -6, -2, -16, 12, 31,
- -23, 7, -2, -39, -28, -13, 8, 5, 16, -4, -6, -18, -24, -27, -50, -6,
- 5, 12, 0, -2, -14, -23, 5, -28, -10, 2, 28, 15, 2, 22, 27, 41,
- 31, 2, 12, 31, 5, 12, -6, 15, 40, 34, 18, 26, 26, 12, 34, 23,
- 34, 30, 22, 10, -26, -22, 1, 0, -1, 12, -4, -21, -5, -5, -20, -31,
- -25, -24, -42, -44, -41, -41, -37, -29, -28, -29, -40, -17, -21, -38, -42, -38,
- -40, -36, -13, -14, -8, -15, -7, -6, 5, 12, -1, -17, -1, 9, 2, 16,
- 30, 27, 37, 36, 38, 36, 36, 19, 45, 45, 33, 26, 33, 28, 36, 31,
- 17, 12, 22, 11, 11, 17, 5, -13, 6, 10, 2, -6, 2, 9, 15, -6,
- -8, -23, -44, -3, -11, -35, -25, -35, -23, -21, 0, -11, -21, -17, 11, -6,
- -11, -17, -33, -16, -16, -4, -7, -7, -9, -4, 1, 1, -3, 6, 7, 4,
- -17, -11, -6, -4, 1, 3, 6, 4, 5, -4, 17, 7, 3, 9, -20, 0,
- -7, -3, -5, 4, 9, 16, 2, 3, 8, 15, 15, 1, -3, 8, -1, 5,
- 14, 7, 4, 8, -8, 2, -3, 5, 11, 5, 3, -4, 10, 17, 13, -11,
- -5, 1, -3, 0, -6, -12, 2, -3, 13, -5, -25, -15, -7, 4, 1, -8,
- -4, -12, -16, 3, 9, -6, 3, -21, -4, 4, -14, 1, -1, -2, 3, -8,
- -5, 0, 7, -2, -3, -1, 3, -9, 5, -4, -17, -1, 9, 3, 7, 1,
- -4, -3, 5, 2, -7, -9, 12, -6, -14, -16, 2, -1, 16, 2, 2, 7,
- -6, -26, 3, -2, -4, -2, 10, 3, -7, 3, 8, 9, 5, 4, 1, -5,
- -5, 11, 8, 7, 11, 12, -1, -5, -16, 13, 7, 2, 11, 4, -4, 9,
- -8, -8, 14, 11, -8, 0, -1, -5, -2, -1, -10, -5, -9, -9, -16, -12,
- -8, -16, 5, -10, -4, -11, -3, 1, 0, -3, -5, -13, -9, -2, -8, 5,
- -9, -7, -2, 2, -11, -7, 13, 8, -3, 2, 7, -2, -1, 5, 0, 11,
- 6, 13, 15, 1, -4, 9, 5, 3, 8, -3, -4, 16, 4, 11, 9, 0,
- 8, 1, -6, -5, -18, 3, 7, -18, -4, 0, -3, -3, -6, -4, -5, -5,
- -10, -2, -9, -5, -2, -4, -11, -2, 1, -5, -2, 11, -6, -9, 1, 4,
- -6, -1, -5, 1, 2, 9, 5, 0, 4, 4, -2, 7, 0, -10, 5, 2,
- -3, 0, -6, 7, -4, -3, 6, -1, -6, -1, -1, 2, -2, -6, -3, 0,
- 8, -6, 4, -1, -5, -3, 3, 1, -5, -6, -2, -3, 5, 6, 0, 7,
- -3, 3, -1, 0, -2, 9, 1, 1, -3, 4, 5, -5, 2, -2, 2, -11,
- -2, -4, 11, 4, 5, 0, -5, -12, -6, -5, -5, 3, -2, -2, 2, 2,
- 1, 0, -1, -8, -5, -5, -3, 2, -1, 3, -1, 3, 0, -1, 0, -1,
- 1, 1, -4, -4, 2, -2, 1, -6, 1, 2, 4, 2, 2, -5, -1, 6,
- -3, -1, -4, 11, 3, -9, -2, -6, -3, 2, 4, 2, 1, 2, 4, 3,
- -6, -4, -3, -2, 0, 2, -2, 5, 2, -1, 3, -9, -3, -3, -4, -4,
- -1, 0, -2, 7, 3, 1, 1, -2, -4, -2, -3, -2, -4, 2, 4, -1,
- 2, 3, 0, 3, -1, 0, -2, -2, -3, 1, -1, -4, 5, -1, 5, 0,
- -3, -2, -1, -4, 3, -1, -3, -2, -2, -1, 0, 0, 1, -1, 0, -2,
- -2, 0, -3, -1, 0, 0, 1, 1, -2, -1, 1, -3, 1, 2, 0, -1,
- 0, -1, 1, 5, -2, 1, -3, -3, -1, -3, 0, 1, 3, 2, -1, -1,
- -2, -2, -1, 1, 0, -1, -2, -2, -2, -3, -3, -3, -2, -2, -2, -2,
- -2, -2, -2, -1, 0, 1, 1, -2, -2, 0, 0, 2, -3, -16, -22, -20,
- -28, -35, -31, -17, 19, 33, 36, 33, 34, 40, 36, 25, 18, 20, 18, 14,
- 17, 12, 14, 10, -24, -36, -27, -38, -55, -69, -66, -47, -33, -13, 3, 5,
- 10, 22, 25, 15, 28, 43, 41, 51, 56, 58, 58, 31, -18, -52, -64, -71,
- -92, -105, -98, -77, -50, -17, 23, 59, 85, 99, 94, 76, 55, 14, -9, -5,
- -7, -18, -17, -35, -53, -53, -33, -23, -33, -36, -15, 17, 32, 24, 12, 19,
- 37, 54, 49, 38, 21, -14, -44, -30, -22, -15, 5, 8, -1, -26, -42, -46,
- -49, -51, -37, -17, 1, -4, -19, -4, 45, 84, 91, 79, 57, 3, -30, -29,
- -35, -25, -8, -6, -26, -61, -75, -73, -77, -72, -54, -19, 9, 6, -10, 3,
- 47, 85, 92, 103, 92, 45, 21, 6, 4, 16, 27, 27, -1, -48, -69, -78,
- -80, -84, -72, -33, -10, -24, -41, -20, 40, 82, 99, 123, 102, 69, 49, 30,
- 27, 34, 42, 41, -2, -58, -96, -108, -103, -106, -83, -37, -10, -18, -38, -18,
- 40, 65, 92, 110, 84, 44, 1, -26, -23, -7, 21, 32, 7, -39, -78, -84,
- -79, -82, -61, -19, 5, -14, -52, -25, 25, 59, 102, 127, 116, 86, 40, 13,
- 4, 9, 27, 29, 4, -47, -88, -94, -87, -83, -56, -18, 15, -13, -49, -30,
- -2, 29, 69, 87, 80, 50, 9, -15, -27, -10, 18, 44, 36, -9, -45, -53,
- -53, -46, -33, 6, 31, -8, -36, -28, -11, 21, 54, 76, 76, 44, 4, -33,
- -53, -45, -18, 13, 10, -35, -62, -70, -61, -44, -19, 38, 63, 30, 9, 4,
- 9, 35, 60, 81, 75, 51, 14, -25, -44, -37, -9, 29, 24, -11, -41, -59,
- -51, -54, -33, 23, 35, 6, -13, -28, -18, 8, 43, 73, 76, 63, 33, -1,
- -21, -22, 10, 43, 35, 5, -32, -47, -51, -68, -44, 6, 14, 0, -21, -34,
- -25, 0, 37, 65, 73, 64, 35, 5, -22, -25, 11, 40, 39, 13, -20, -28,
- -42, -64, -32, 6, 15, -1, -25, -39, -39, -16, 19, 44, 58, 53, 27, -2,
- -39, -38, -2, 30, 40, 13, -16, -19, -45, -60, -29, 6, 17, 1, -21, -40,
- -44, -24, 9, 38, 58, 51, 38, 8, -31, -29, 0, 34, 44, 9, -11, -23,
- -58, -69, -42, -6, 9, 0, -16, -33, -36, -12, 19, 55, 72, 68, 58, 18,
- -22, -25, -6, 29, 31, 2, -5, -23, -57, -69, -45, -8, 12, 10, 0, -22,
- -24, -7, 20, 52, 61, 65, 59, 21, -15, -28, -11, 26, 20, 2, -2, -22,
- -56, -71, -49, -14, 3, 8, -5, -26, -28, -19, 14, 42, 54, 71, 67, 38,
- 8, -11, 16, 47, 37, 26, 18, -10, -51, -74, -59, -35, -19, -12, -24, -37,
- -44, -34, 0, 24, 44, 67, 64, 43, 3, -18, 11, 35, 28, 22, 18, -4,
- -47, -68, -55, -34, -11, -7, -15, -27, -43, -32, -1, 18, 42, 58, 60, 43,
- -8, -29, -6, 11, 7, 4, 4, -17, -59, -75, -66, -41, -13, -3, 1, -11,
- -29, -19, 1, 19, 42, 53, 64, 45, -8, -28, -9, 7, 4, 4, 9, -13,
- -51, -71, -69, -43, -19, -7, 3, -11, -25, -17, -2, 23, 43, 60, 78, 55,
- 1, -19, -5, 8, 3, 7, 13, -8, -41, -66, -67, -40, -19, 3, 16, 1,
- -7, -5, 10, 34, 46, 67, 87, 62, 11, -13, -1, 8, 4, 15, 20, 1,
- -33, -64, -65, -48, -30, -2, 6, -5, -14, -18, 1, 21, 32, 62, 86, 66,
- 20, -3, 6, 7, 5, 16, 20, 7, -29, -62, -65, -59, -39, -13, -5, -8,
- -22, -27, -6, 7, 17, 49, 74, 58, 14, -5, -2, -4, -3, 7, 14, 6,
- -32, -59, -66, -63, -40, -16, -2, -2, -19, -20, -1, 6, 18, 49, 77, 62,
- 21, 3, -1, -5, -2, 5, 18, 10, -26, -50, -65, -64, -43, -24, -5, -6,
- -24, -23, -8, -2, 10, 45, 75, 60, 25, 6, -4, -4, -5, 3, 20, 8,
- -20, -43, -60, -58, -45, -24, 1, -1, -15, -12, -1, 3, 16, 53, 83, 70,
- 42, 19, 9, 7, 3, 16, 29, 17, -7, -35, -55, -56, -49, -24, 2, -1,
- -11, -7, 3, 4, 16, 55, 83, 75, 50, 25, 15, 6, 0, 13, 21, 13,
- -9, -40, -58, -66, -62, -35, -11, -11, -18, -13, -3, -7, 9, 49, 75, 74,
- 51, 28, 19, 5, 1, 13, 20, 16, -3, -28, -48, -62, -61, -37, -16, -13,
- -20, -15, -12, -19, -5, 21, 50, 61, 47, 28, 15, -1, -6, 0, 9, 14,
- 1, -19, -37, -55, -56, -38, -16, -11, -13, -9, -9, -16, -8, 18, 48, 59,
- 44, 28, 9, 15, -3, 2, -5, 3, 3, 4, 1, 7, -2, 7, -4, 2,
- -124, -37, 33, -48, 7, -27, 8, -14, 77, 26, -9, 26, 7, 20, 10, 13,
- 8, 9, 7, 4, 5, 2, 3, 2, 1, -1, 0, -3, -2, -5, 1, -10,
- 11, 70, -6, 21, 5, 27, -2, 41, -15, -61, -66, -128, 0, -48, -21, -46,
- -6, -55, 23, 53, -6, 11, 2, 14, 11, 10, 11, 8, 9, 9, 8, 5,
- 8, 5, 6, 5, 6, 2, 7, -4, 6, 5, -23, 62, 29, 24, 8, 33,
- 4, 32, 36, -30, -16, -124, -58, -39, -18, -51, -3, -43, -40, 53, 19, 12,
- 4, 9, 12, 13, 10, 11, 9, 8, 11, 6, 5, 8, 6, 3, 9, 1,
- 7, 2, -5, 22, -33, 20, 37, 35, 7, 29, 14, 8, 52, -5, 17, -64,
- -84, -70, -15, -55, -23, -12, -72, 1, 28, 16, 8, 6, 7, 12, 10, 8,
- 11, 6, 8, 10, 5, 4, 10, 1, 8, 4, 2, 10, -15, 26, -16, -9,
- 14, 42, 17, 19, 29, -3, 42, 14, 28, -8, -45, -92, -37, -41, -54, 0,
- -53, -48, 2, 18, 10, 8, 4, 8, 12, 8, 10, 10, 6, 9, 10, 2,
- 10, 5, 3, 9, -2, 18, -16, 17, 3, -9, -12, 26, 28, 13, 35, 3,
- 27, 19, 31, 17, 4, -60, -67, -33, -66, -22, -22, -58, -38, 2, 11, 9,
- 7, 4, 9, 10, 8, 10, 9, 5, 12, 5, 5, 9, 2, 11, -5, 21,
- -8, 4, 10, 5, -17, -1, 28, 11, 34, 13, 20, 17, 28, 24, 27, -6,
- -61, -41, -57, -51, -17, -36, -56, -32, -1, 7, 8, 5, 6, 8, 10, 8,
- 12, 6, 9, 9, 5, 9, 1, 15, -7, 15, 5, -2, 4, 14, -3, -18,
- 15, 8, 28, 21, 20, 16, 23, 23, 29, 30, -20, -38, -45, -63, -38, -23,
- -43, -53, -29, -5, 5, 5, 5, 5, 9, 7, 11, 8, 8, 10, 5, 12,
- -2, 16, -1, 4, 11, 4, -3, 8, 15, -16, 0, 1, 16, 23, 23, 17,
- 20, 21, 21, 39, 19, -14, -28, -52, -58, -33, -28, -47, -50, -30, -6, 2,
- 5, 4, 6, 6, 9, 10, 7, 12, 3, 15, 0, 10, 8, 1, 6, 11,
- 2, -4, 20, -1, -6, -5, 4, 15, 24, 20, 18, 23, 15, 30, 38, 13,
- -6, -27, -56, -52, -30, -34, -48, -50, -28, -8, 2, 3, 5, 5, 6, 11,
- 5, 13, 3, 12, 6, 5, 10, 5, 2, 7, 13, -8, 10, 11, 0, -6,
- -4, 3, 17, 23, 16, 24, 18, 17, 36, 32, 13, -1, -30, -57, -45, -31,
- -36, -51, -49, -28, -7, -1, 3, 6, 2, 11, 5, 12, 6, 9, 10, 5,
- 8, 8, 5, -1, 16, 1, -1, 11, 9, -1, -5, -5, 4, 20, 17, 20,
- 24, 14, 23, 37, 29, 16, 2, -33, -53, -42, -30, -39, -52, -49, -27, -9,
- -3, 5, 0, 8, 5, 10, 8, 6, 10, 6, 7, 6, 11, -3, 8, 11,
- 0, 2, 11, 8, -1, -5, -7, 9, 18, 16, 24, 20, 14, 27, 35, 27,
- 21, 1, -33, -50, -38, -32, -42, -53, -48, -25, -14, -1, -2, 4, 3, 6,
- 9, 5, 9, 7, 7, 4, 12, 4, 1, 10, 6, 2, 6, 10, 4, 0,
- -6, -2, 11, 14, 18, 22, 17, 20, 32, 34, 28, 20, 0, -26, -36, -34,
- -37, -45, -54, -44, -30, -13, -8, -3, 1, 2, 6, 4, 7, 8, 8, 2,
- 8, 10, 1, 4, 6, 5, 5, 9, 6, 1, -3, -5, 3, 10, 14, 18,
- 18, 17, 26, 35, 35, 29, 17, -1, -17, -24, -32, -41, -50, -51, -44, -28,
- -18, -12, -5, -2, 2, 3, 3, 6, 9, 4, 3, 9, 6, 2, 2, 4,
- 5, 9, 10, 4, -2, -5, -1, 5, 10, 14, 16, 15, 19, 30, 38, 37,
- 29, 15, 1, -5, -14, -31, -43, -50, -52, -42, -29, -22, -16, -9, -3, 0,
- 0, 2, 6, 6, 2, 4, 7, 6, 2, 1, 2, 6, 11, 10, 2, -5,
- -4, 0, 5, 10, 14, 15, 14, 21, 32, 39, 38, 29, 14, 4, 0, -3,
- -19, -32, -40, -43, -41, -36, -31, -25, -19, -12, -9, -8, -6, -1, 2, 2,
- 0, -3, -4, -1, 3, 6, 6, 2, -3, -6, -2, 2, 2, 1, 2, 7,
- 16, 25, 32, 35, 35, 36, 36, 33, 24, 11, -3, -18, -32, -40, -42, -40,
- -36, -30, -25, -18, -12, -9, -8, -5, -1, 2, 2, 0, -3, -4, -1, 3,
- 7, 6, 2, -4, -5, -2, 2, 2, 1, 2, 8, 17, 25, 32, 35, 36,
- 36, 36, 32, 23, 10, -4, -20, -33, -41, -42, -40, -35, -30, -24, -18, -12,
- -9, -8, -5, -1, 3, 2, -1, -4, -4, -1, 4, 7, 6, 1, -4, -5,
- -2, -1, 3, 1, 3, 5, 3, -3, -1, -1, 1, -15, 1, 1, -5, -7,
- 7, -2, -4, 3, -2, -5, -1, -3, -3, -1, 6, 3, 2, 3, -26, -117,
- 35, -8, -19, 24, 58, -7, -6, 25, -9, 7, 4, 10, 2, 7, 6, 6,
- 0, 6, -2, -1, -3, -3, 8, 71, 0, 17, 27, 20, -102, -115, 39, -32,
- -18, -5, 58, -15, -12, 13, -10, -4, 1, 2, 1, 0, 6, 2, 1, 2,
- 0, -4, 0, -5, 2, 67, 9, 14, 28, 29, -72, -126, 27, -25, -19, -14,
- 58, -6, -11, 13, -5, -3, 3, 3, 4, 1, 8, 3, 3, 3, 3, -2,
- 2, -3, -3, 62, 17, 14, 27, 35, -45, -128, 11, -19, -20, -22, 53, 1,
- -12, 11, -3, -4, 2, 3, 4, 1, 7, 3, 3, 3, 3, -2, 2, -2,
- -9, 57, 22, 14, 25, 37, -23, -125, -8, -15, -20, -30, 46, 9, -12, 10,
- -2, -3, 0, 3, 3, 1, 6, 4, 2, 3, 2, -2, 1, 0, -16, 50,
- 26, 13, 22, 37, -2, -117, -27, -13, -18, -36, 36, 16, -13, 9, -2, -2,
- -2, 3, 2, 2, 4, 5, 1, 4, 2, -1, 0, 4, -20, 43, 29, 15,
- 20, 36, 14, -102, -43, -15, -16, -40, 26, 22, -12, 8, -2, -2, -3, 3,
- 1, 3, 2, 6, 1, 5, 1, 0, -1, 7, -23, 35, 31, 18, 18, 33,
- 27, -83, -57, -20, -14, -42, 14, 26, -9, 7, -2, 0, -5, 3, 1, 4,
- 1, 7, 0, 5, 1, 1, -2, 10, -24, 26, 31, 20, 17, 30, 36, -62,
- -65, -27, -12, -43, 2, 28, -7, 6, -2, 0, -5, 3, 0, 4, 0, 7,
- 0, 5, 1, 2, -4, 11, -23, 17, 32, 22, 16, 27, 42, -44, -67, -36,
- -9, -42, -8, 28, -3, 5, -1, 1, -5, 2, 0, 4, 1, 7, 1, 5,
- 1, 3, -5, 13, -22, 10, 31, 23, 17, 22, 45, -25, -66, -45, -8, -40,
- -18, 27, 0, 5, -1, 1, -5, 1, 0, 4, 0, 6, 2, 4, 2, 3,
- -6, 14, -19, 2, 29, 25, 19, 19, 47, -10, -60, -54, -10, -37, -27, 24,
- 4, 4, 0, 1, -5, 0, 0, 3, 1, 5, 2, 4, 2, 4, -7, 15,
- -16, -4, 27, 25, 21, 15, 48, 4, -51, -61, -12, -33, -34, 19, 7, 4,
- 1, 0, -4, -1, 0, 3, 2, 5, 3, 3, 3, 5, -8, 15, -11, -10,
- 24, 25, 23, 12, 45, 15, -39, -66, -18, -28, -40, 12, 10, 4, 2, 1,
- -3, -2, 0, 2, 2, 4, 3, 3, 3, 5, -8, 13, -6, -14, 19, 25,
- 25, 10, 43, 24, -25, -67, -25, -24, -45, 4, 11, 5, 3, 0, -2, -3,
- -1, 1, 2, 3, 3, 3, 2, 6, -9, 11, -2, -17, 15, 24, 27, 9,
- 39, 31, -13, -66, -33, -19, -48, -3, 11, 5, 3, 1, -2, -3, -1, 1,
- 2, 4, 3, 3, 2, 8, -9, 9, 3, -18, 10, 22, 29, 9, 35, 35,
- 0, -61, -41, -17, -49, -11, 10, 6, 3, 2, -2, -3, -2, 1, 1, 4,
- 3, 5, 1, 9, -9, 7, 6, -18, 5, 20, 29, 10, 32, 38, 11, -47,
- -45, -18, -47, -20, 5, 6, 4, 2, -1, -3, -2, 0, 1, 5, 1, 6,
- 1, 7, -7, 6, 6, -16, 1, 16, 27, 11, 29, 40, 20, -30, -43, -23,
- -46, -28, -2, 4, 4, 2, -1, -3, -2, -1, 0, 6, -1, 7, 2, 5,
- -6, 5, 6, -15, -3, 13, 25, 12, 26, 41, 26, -14, -36, -26, -44, -35,
- -11, 1, 4, 2, 0, -4, -3, -3, -1, 7, -2, 7, 4, 4, -6, 4,
- 7, -13, -6, 10, 23, 12, 24, 42, 31, 0, -24, -28, -42, -40, -19, -4,
- 4, 2, 1, -4, -3, -4, -3, 8, -3, 6, 6, 3, -6, 4, 7, -11,
- -8, 7, 20, 12, 21, 41, 34, -2, -31, -34, -29, -21, -12, -3, -4, -10,
- -7, -5, -6, -4, 5, 8, -3, -1, 7, -1, -11, -7, 0, 1, 6, 16,
- 28, 33, 33, 30, 13, -1, -26, -35, -30, -24, -14, -5, -4, -11, -7, -5,
- -6, -6, 3, 8, -2, -2, 7, 1, -11, -9, -1, 0, 4, 14, 26, 32,
- 33, 32, 17, 3, -22, -34, -31, -25, -16, -6, -3, -10, -8, -5, -6, -7,
- 2, 9, 0, -3, 6, 3, -9, -10, -2, 0, 3, 12, 24, 32, -1, 0,
- -3, -1, -8, -5, -16, -5, -14, -4, -13, -5, -1, -7, 16, -17, 28, -16,
- 47, 1, 70, 35, 97, 71, 98, 66, 32, -5, -71, -69, -122, -69, -105, -33,
- -67, -6, -35, 2, -12, -2, 4, -12, 16, -19, 29, -16, 44, 2, 66, 37,
- 92, 76, 95, 74, 33, 5, -69, -63, -122, -69, -106, -36, -66, -11, -33, -3,
- -9, -7, 7, -16, 18, -22, 29, -17, 42, 3, 61, 40, 86, 81, 91, 82,
- 34, 15, -67, -57, -122, -69, -105, -40, -64, -17, -29, -9, -6, -12, 10, -20,
- 20, -23, 28, -17, 39, 4, 56, 42, 80, 85, 88, 89, 35, 24, -63, -53,
- -119, -70, -104, -45, -62, -22, -26, -14, -2, -16, 12, -23, 20, -25, 27, -16,
- 35, 7, 51, 45, 74, 89, 85, 96, 38, 32, -58, -49, -116, -72, -102, -50,
- -60, -27, -24, -19, 0, -20, 14, -24, 20, -24, 24, -14, 31, 10, 45, 48,
- 69, 92, 82, 102, 40, 39, -53, -45, -112, -74, -100, -55, -57, -33, -21, -24,
- 3, -24, 15, -26, 19, -24, 22, -12, 27, 12, 40, 50, 63, 95, 80, 106,
- 43, 45, -47, -42, -107, -76, -97, -60, -55, -38, -18, -28, 4, -26, 15, -27,
- 18, -23, 19, -10, 23, 15, 35, 53, 59, 97, 78, 110, 47, 50, -39, -39,
- -102, -79, -94, -65, -52, -43, -16, -32, 5, -28, 14, -27, 16, -21, 15, -7,
- 18, 18, 30, 55, 54, 98, 76, 113, 51, 55, -32, -37, -96, -81, -91, -70,
- -50, -48, -15, -35, 6, -30, 13, -26, 13, -19, 11, -5, 13, 20, 25, 56,
- 50, 99, 75, 115, 56, 59, -24, -35, -90, -83, -88, -75, -48, -52, -14, -38,
- 5, -30, 11, -25, 10, -17, 7, -2, 9, 22, 21, 57, 47, 99, 75, 116,
- 61, 62, -15, -33, -82, -86, -84, -80, -47, -56, -14, -39, 4, -30, 9, -24,
- 6, -15, 3, 1, 5, 24, 17, 57, 44, 98, 75, 116, 66, 65, -6, -31,
- -75, -88, -81, -83, -46, -59, -14, -41, 3, -30, 6, -22, 3, -12, -1, 3,
- 1, 26, 13, 57, 41, 96, 75, 115, 72, 68, 2, -29, -69, -89, -78, -87,
- -45, -62, -15, -42, 0, -29, 3, -20, -1, -10, -5, 5, -2, 26, 11, 56,
- 40, 94, 76, 114, 77, 69, 12, -28, -61, -91, -75, -89, -45, -64, -16, -42,
- -2, -28, 0, -18, -5, -8, -9, 7, -6, 27, 8, 55, 38, 91, 77, 112,
- 82, 71, 20, -25, -55, -91, -73, -91, -46, -65, -18, -42, -5, -26, -4, -15,
- -10, -5, -13, 9, -9, 27, 7, 53, 37, 88, 78, 110, 87, 72, 29, -23,
- -48, -90, -71, -93, -47, -66, -21, -41, -9, -24, -8, -13, -13, -3, -16, 9,
- -11, 27, 5, 51, 37, 84, 79, 108, 93, 74, 37, -20, -42, -90, -70, -94,
- -49, -66, -24, -40, -12, -23, -12, -12, -16, -2, -18, 10, -12, 25, 5, 48,
- 37, 80, 81, 105, 98, 75, 45, -16, -36, -88, -68, -94, -51, -66, -28, -39,
- -16, -21, -15, -10, -19, -1, -21, 10, -13, 24, 4, 45, 37, 76, 82, 102,
- 102, 76, 52, -13, -30, -85, -67, -94, -54, -66, -31, -38, -20, -19, -19, -9,
- -22, 0, -22, 9, -14, 22, 4, 41, 37, 71, 83, 99, 105, 77, 59, -8,
- -25, -82, -67, -93, -56, -65, -35, -37, -23, -18, -22, -7, -25, 0, -24, 8,
- -14, 20, 5, 37, 38, 67, 84, 96, 108, 79, 65, -3, -20, -79, -66, -92,
- -59, -65, -39, -36, -27, -17, -25, -7, -27, -1, -24, 6, -14, 17, 6, 34,
- 39, 63, 84, 93, 111, 80, 71, 1, -15, -75, -66, -90, -62, -64, -43, -35,
- -31, -16, -28, -6, -28, -1, -25, 5, -14, 14, 6, 30, 39, 58, 85, 90,
- 113, 82, 76, 7, -11, -70, -66, -88, -66, -62, -46, -34, -34, -15, -30, -7,
- -30, -2, -25, 2, -13, 11, 7, 26, 40, 53, 84, 87, 115, 84, 81, 13,
- -7, -65, -66, -85, -68, -61, -50, -33, -37, -15, -32, -7, -30, -4, -25, 0,
- -12, 7, 9, 19, 37, 52, 80, 97, 118, 113, 98, 54, 7, -41, -72, -87,
- -87, -75, -65, -47, -42, -29, -30, -22, -24, -19, -19, -14, -9, -2, 8, 17,
- 36, 50, 77, 95, 117, 115, 101, 60, 13, -35, -69, -85, -88, -75, -66, -49,
- -44, -31, -31, -23, -25, -20, -20, -15, -9, -2, -1, 0, 0, 0, 0, -1,
- -1, -1, 3, 9, 14, 14, 10, -3, -17, -13, 1, 1, 23, 33, -14, -55,
- -59, -80, -75, -35, -7, 51, 40, -29, -35, -53, -128, -31, 111, 72, 46, 55,
- -19, -73, -23, 14, 64, 104, 87, 105, 68, -54, -76, -1, -18, 12, 92, 23,
- -79, -93, -105, -119, -64, -20, 39, 70, 2, -45, -52, -107, -82, 73, 106, 56,
- 53, 12, -57, -37, 14, 52, 105, 101, 94, 85, -5, -75, -25, -1, -8, 59,
- 52, -45, -89, -94, -117, -90, -42, 1, 53, 29, -29, -45, -79, -104, 3, 99,
- 78, 63, 42, -25, -49, -7, 30, 83, 112, 103, 99, 40, -54, -58, -11, -7,
- 36, 68, -4, -80, -98, -114, -106, -57, -15, 33, 42, -10, -46, -66, -97, -45,
- 68, 90, 67, 53, 4, -40, -20, 18, 60, 103, 107, 100, 69, -15, -62, -31,
- -9, 15, 60, 31, -50, -90, -108, -115, -79, -33, 11, 42, 15, -33, -58, -87,
- -75, 21, 87, 79, 63, 27, -26, -33, 1, 40, 88, 111, 105, 85, 20, -50,
- -49, -17, 5, 46, 49, -17, -77, -102, -115, -95, -49, -7, 31, 28, -15, -50,
- -76, -84, -21, 64, 84, 71, 45, -4, -32, -13, 22, 66, 103, 108, 95, 50,
- -23, -56, -32, -5, 30, 55, 14, -53, -92, -111, -107, -68, -24, 16, 34, 4,
- -37, -66, -85, -53, 32, 81, 77, 58, 17, -25, -24, 6, 46, 89, 108, 101,
- 71, 6, -49, -45, -16, 15, 49, 36, -26, -77, -103, -110, -85, -41, 0, 30,
- 20, -21, -55, -79, -72, -5, 65, 81, 67, 36, -10, -28, -8, 27, 71, 102,
- 104, 85, 34, -31, -51, -29, 1, 37, 48, 2, -57, -93, -109, -97, -58, -16,
- 20, 28, -4, -42, -70, -79, -36, 39, 78, 74, 51, 9, -24, -18, 11, 51,
- 91, 105, 94, 57, -6, -48, -41, -12, 22, 48, 26, -33, -79, -103, -104, -74,
- -32, 6, 28, 12, -27, -60, -78, -59, 8, 66, 78, 62, 27, -13, -24, -3,
- 33, 74, 100, 99, 74, 20, -35, -48, -25, 8, 40, 40, -7, -61, -94, -106,
- -88, -49, -9, 21, 21, -11, -47, -72, -71, -22, 45, 76, 71, 43, 2, -22,
- -13, 16, 56, 91, 101, 85, 43, -15, -47, -36, -6, 28, 45, 16, -38, -80,
- -102, -97, -65, -24, 11, 25, 4, -33, -63, -75, -46, 18, 66, 75, 56, 19,
- -15, -20, 2, 38, 77, 98, 93, 62, 8, -38, -44, -20, 14, 41, 32, -15,
- -64, -94, -101, -79, -40, -2, 22, 15, -17, -52, -72, -61, -9, 49, 74, 66,
- 36, -2, -21, -9, 22, 61, 91, 96, 76, 31, -22, -45, -32, 0, 32, 40,
- 7, -43, -82, -99, -89, -56, -17, 14, 21, -2, -38, -65, -69, -33, 26, 66,
- 71, 50, 13, -16, -16, 7, 43, 79, 95, 85, 50, -2, -40, -40, -14, 20,
- 40, 24, -22, -66, -93, -95, -70, -32, 3, 21, 9, -23, -55, -70, -51, 1,
- 52, 71, 60, 28, -6, -19, -4, 27, 64, 90, 91, 66, 19, -27, -43, -26,
- 6, 34, 35, -1, -48, -83, -96, -81, -47, -10, 16, 17, -9, -43, -66, -62,
- -22, 33, 66, 67, 43, 7, -16, -13, 12, 48, 80, 91, 77, 39, -10, -40,
- -36, -8, 24, 38, 17, -28, -69, -92, -89, -62, -25, 7, 19, 4, -29, -58,
- -67, -42, 10, 55, 70, 55, 22, -9, -17, 0, 33, 68, 90, 86, 57, 10,
- -31, -41, -21, 12, 36, 30, -8, -53, -85, -94, -75, -41, -5, 17, 13, -15,
- -48, -67, -57, -13, 39, 68, 64, 37, 3, -16, -9, 18, 54, 84, 91, 72,
- 30, -17, -41, -33, -2, 28, 37, 10, -35, -74, -94, -86, -56, -19, 10, 17,
- -2, -36, -63, -66, -34, 19, 60, 70, 51, 17, -11, -15, 5, 39, 74, 92,
- 83, 49, 1, -36, -40, -16, 18, 37, 24, -17, -61, -90, -93, -70, -34, 1,
- 18, 8, -22, -55, -69, -50, -2, 47, 70, 61, 31, -3, -17, -5, 26, 62,
- 88, 90, 65, 19, -25, -42, -27, 5, 33, 33, 1, -45, -81, -95, -81, -48,
- -11, 14, 15, -10, -43, -66, -61, -22, 31, 65, 68, 43, 9, -14, -11, 12,
- 49, 80, 92, 76, 38, -10, -39, -36, -8, 24, 38, 16, -27, -70, -92, -89,
- -61, -25, 7, 17, 3, -31, -59, -68, -39, 8, 55, 55, 19, 0, -9, -10,
- -14, -13, -21, -30, -32, -44, -49, -57, -65, -72, -83, -98, -104, -117, -123, -128,
- -127, -128, -128, -128, -128, -127, -128, -120, -117, -109, -100, -90, -83, -72, -66, -55,
- -50, -33, -42, -18, -29, -18, 15, -6, 11, 7, 19, 3, 38, 5, 48, 44,
- 64, 57, 97, 82, 111, 104, 110, 107, 120, 116, 125, 126, 126, 126, 126, 127,
- 117, 125, 123, 100, 127, 101, 124, 102, 121, 109, 126, 96, 125, 116, 127, 90,
- 119, 87, 127, 90, 118, 95, 123, 93, 106, 90, 100, 104, 74, 84, 73, 97,
- 72, 71, 57, 66, 80, 36, 59, 38, 55, 35, 57, -6, 64, 10, 25, 19,
- 19, -22, 65, -26, 14, 2, -17, -12, 22, -40, -3, -31, -24, -38, -1, -56,
- -6, -48, -36, -54, -19, -56, -33, -49, -69, -49, -52, -53, -60, -61, -84, -76,
- -85, -96, -95, -95, -114, -93, -117, -104, -93, -101, -98, -100, -101, -96, -78, -95,
- -71, -70, -72, -52, -63, -70, -43, -77, -41, -48, -65, -53, -53, -59, -42, -56,
- -37, -64, -54, -52, -50, -54, -56, -54, -55, -62, -51, -47, -44, -67, -60, -63,
- -56, -64, -53, -48, -61, -53, -58, -38, -48, -32, -38, -34, -28, -26, -23, -25,
- -22, -6, -7, -12, -1, 5, 6, 6, -7, 22, -4, 27, 15, 18, 24, 37,
- 30, 47, 24, 53, 29, 63, 29, 46, 46, 51, 52, 53, 36, 54, 65, 55,
- 33, 64, 36, 69, 54, 26, 62, 66, 36, 68, 30, 47, 54, 58, 20, 55,
- 31, 40, 50, 35, 19, 56, 33, 25, 46, 18, 22, 42, 21, 25, 32, 19,
- 19, 26, 18, 23, 29, 24, 7, 27, 6, 33, 8, 17, -2, 14, 3, 23,
- 14, 7, 5, -9, -13, -10, -23, -12, -16, -27, -8, -18, -15, -3, -18, -24,
- -5, -23, -9, 0, -11, 4, -1, 4, 2, 5, -2, 3, -1, -7, 4, -11,
- 1, -12, -4, -7, -10, -11, -11, -16, -23, -15, -20, -22, -23, -20, -30, -23,
- -31, -25, -32, -35, -41, -34, -44, -39, -34, -49, -33, -30, -36, -29, -33, -14,
- -24, -32, -18, -15, -7, -9, -11, 5, -14, 27, -11, 16, -10, 13, -9, 23,
- -10, 19, 10, 18, 11, 29, 1, 47, 27, -4, 45, 3, 43, 40, 14, 13,
- 57, 16, 34, 27, 22, 30, 32, 14, 24, 27, 20, 20, 17, 4, 20, 20,
- 8, 8, 0, 10, -3, 17, -8, -1, -4, 1, 0, 6, -7, -3, -3, -13,
- -5, -6, -18, -5, -28, -12, -13, -5, -11, -5, -28, -7, -15, -10, -6, -28,
- -16, -12, -17, -8, -10, -19, -10, -24, -30, -32, -26, -31, -36, -32, -33, -27,
- -25, -26, -26, -25, -25, -23, -16, -22, -10, -11, -7, -7, 4, -10, 10, -9,
- 11, -8, 4, -6, 4, -8, 3, -4, 2, -3, -5, -3, -11, -8, -6, -12,
- -11, -7, -24, -4, -17, -9, -18, -28, -16, -29, -23, -38, -24, -34, -22, -38,
- -18, -27, -10, -22, -19, -21, -2, -23, 10, -19, 0, 4, 16, 7, 0, 3,
- 17, 14, 26, 8, 25, 27, 30, 25, 38, 31, 49, 37, 42, 45, 48, 55,
- 63, 46, 54, 54, 56, 59, 56, 47, 50, 53, 47, 50, 44, 42, 35, 40,
- 31, 37, 35, 27, 20, 23, 19, 26, 24, 18, 11, 14, 18, 24, 18, 12,
- 10, 3, 12, 2, 9, 4, 0, 0, 3, -4, 11, 1, 1, -1, -5, -7,
- 1, -6, -1, 2, -4, 1, -1, -7, -9, -11, -21, -19, -20, -28, -27, -22,
- -29, -24, -26, -32, -22, -25, -31, -24, -19, -22, -11, -19, -15, -4, -5, -4,
- 0, -6, -6, 2, -9, -5, -5, -9, -10, -7, -18, -8, -14, -14, -19, -29,
- -25, -16, -25, -30, -30, -30, -21, -29, -38, -37, -36, -41, -44, -53, -48, -43,
- -44, -55, -46, -40, -33, -36, -40, -40, -28, -25, -24, -23, -17, -15, 1, -3,
- -1, 5, 2, 9, 1, 4, 12, 13, 14, 15, 9, 21, 26, 32, 31, 28,
- 28, 41, 38, 49, 45, 46, 53, 56, 57, 57, 57, 58, 55, 48, 56, 56,
- 56, 45, 39, 41, 41, 44, 42, 25, 28, 27, 24, 28, 21, 14, 17, 8,
- 15, 22, 13, 15, 16, 3, 11, 10, 4, 6, 4, -8, 0, -2, -2, -3,
- -2, 1, 3, -3, -3, -6, -8, -5, 4, 3, 2, -4, -2, -1, 5, 3,
- -2, -2, -2, 3, 7, -2, -26, -37, -34, -30, -13, -14, -21, -24, -27, -24,
- -13, -7, -15, 6, 3, -30, -50, -48, -47, -41, -26, -8, 28, 43, 38, 57,
- 63, 56, 75, 118, 127, 117, 99, 86, 85, 66, 46, 59, 80, 69, 43, 27,
- -6, -47, -74, -80, -71, -57, -40, -44, -56, -78, -88, -78, -59, -52, -51, -56,
- -57, -47, -36, -36, -39, -39, -32, -17, 6, 24, 33, 10, -14, -14, -2, -11,
- -20, -15, -24, -28, -28, -25, -28, -54, -73, -65, -43, -18, 6, 27, 21, 23,
- 17, 22, 18, 16, 31, 50, 45, 25, 22, 8, -20, -17, 8, 29, 10, -22,
- -41, -45, -51, -53, -31, -18, -23, -7, 37, 54, 38, 36, 60, 100, 119, 120,
- 122, 125, 110, 88, 94, 99, 90, 85, 82, 54, 26, -5, -49, -83, -85, -67,
- -36, -14, -30, -55, -76, -86, -65, -41, -45, -60, -53, -43, -35, -34, -41, -43,
- -45, -35, 10, 40, 32, 3, -3, -14, -30, -38, -33, -23, -29, -26, -18, -10,
- -17, -37, -46, -58, -61, -45, -17, -4, -2, 19, 31, 27, 13, 22, 38, 49,
- 59, 69, 60, 23, -13, -11, 13, 24, 19, 24, 8, -30, -58, -58, -66, -85,
- -90, -61, -19, -1, -11, -5, 25, 42, 61, 92, 109, 106, 110, 104, 93, 93,
- 89, 82, 86, 81, 71, 51, 13, -40, -74, -87, -73, -35, -24, -50, -71, -73,
- -53, -50, -58, -68, -60, -61, -54, -30, -25, -40, -52, -25, 13, 32, 45, 49,
- 44, 28, 22, 29, 32, 20, 3, 7, 6, 0, -1, -4, -30, -63, -69, -62,
- -57, -49, -25, 2, 17, 24, 27, 30, 10, 4, 38, 77, 66, 32, 13, 7,
- 0, 9, 31, 43, 23, -11, -25, -23, -46, -83, -87, -63, -42, -19, -6, -3,
- 6, 27, 49, 81, 108, 121, 123, 124, 115, 110, 98, 80, 78, 77, 77, 69,
- 54, 8, -56, -99, -92, -53, -46, -64, -75, -73, -70, -75, -62, -67, -86, -88,
- -54, -28, -33, -46, -50, -40, -24, -3, 29, 51, 48, 34, 44, 44, 30, 18,
- 13, -3, -15, -7, -1, -10, -36, -56, -65, -79, -100, -91, -64, -52, -40, -5,
- 20, 9, -14, -9, 21, 49, 59, 58, 49, 25, -1, 11, 39, 39, 22, 19,
- 20, 8, -19, -49, -72, -69, -58, -43, -27, -24, -13, -5, 12, 38, 74, 97,
- 110, 124, 126, 126, 114, 105, 100, 87, 91, 108, 115, 73, 5, -41, -49, -49,
- -53, -45, -49, -69, -77, -60, -51, -71, -94, -96, -68, -49, -46, -44, -45, -60,
- -60, -27, 0, 11, 26, 37, 37, 37, 40, 42, 34, 8, -1, 14, 15, -5,
- -12, -18, -44, -75, -85, -88, -98, -99, -76, -36, -12, -19, -24, -11, -9, 1,
- 36, 71, 58, 29, 13, 17, 33, 33, 30, 35, 44, 44, 27, -3, -39, -51,
- -61, -55, -41, -31, -25, -29, -21, -1, 23, 46, 76, 102, 109, 110, 116, 118,
- 92, 61, 76, 112, 120, 93, 57, 14, -28, -54, -50, -46, -60, -83, -82, -64,
- -62, -82, -89, -93, -101, -88, -59, -52, -64, -75, -76, -63, -50, -30, -1, 9,
- 8, 11, 32, 44, 36, 29, 32, 27, 20, 22, 28, 24, 0, -21, -30, -45,
- -78, -97, -83, -66, -50, -32, -17, -16, -23, -20, 4, 38, 51, 47, 37, 28,
- 29, 27, 27, 31, 42, 54, 55, 43, 20, -5, -29, -40, -37, -30, -27, -23,
- -15, -12, -11, 8, 43, 67, 78, 100, 122, 126, 107, 84, 81, 92, 106, 115,
- 110, 79, 31, -3, -13, -26, -47, -56, -56, -58, -58, -56, -59, -72, -86, -84,
- -66, -57, -56, -56, -60, -74, -74, -51, -32, -24, -14, 3, 14, 15, 19, 28,
- 33, 19, 11, 22, 29, 18, 8, 9, 0, 0, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -1,
- -1, -1, -1, -1, -1, -1, -1, 0, -1, -3, -2, -1, 0, 2, -4, -13,
- -21, -23, -19, -8, 7, 17, 23, 26, 33, 38, 32, 17, -5, -17, -24, -20,
- -6, -3, -16, -29, -26, -17, -5, -1, 2, 7, 11, 17, 15, 9, 9, 3,
- 10, 15, 9, -14, -33, -27, -18, -6, -7, -10, -6, 0, 12, 15, 29, 38,
- 36, 32, 11, 0, -30, -45, -50, -39, -23, -27, -24, -15, 6, 25, 37, 51,
- 46, 40, 0, -19, -22, -34, -30, -40, -45, -51, -34, -1, 25, 48, 40, 43,
- 51, 64, 58, 5, -22, -49, -63, -69, -68, -58, -54, -16, 13, 44, 66, 61,
- 68, 72, 86, 47, -17, -56, -82, -88, -93, -72, -58, -40, 4, 45, 94, 98,
- 84, 65, 68, 71, 15, -46, -88, -90, -88, -85, -62, -56, -34, -4, 41, 80,
- 82, 74, 54, 70, 66, 25, -29, -70, -74, -90, -87, -79, -73, -46, -10, 54,
- 90, 103, 88, 76, 90, 69, 25, -38, -76, -96, -119, -111, -103, -81, -57, -12,
- 50, 90, 113, 98, 100, 112, 103, 60, -11, -54, -95, -121, -124, -119, -95, -71,
- -10, 53, 103, 116, 93, 91, 89, 80, 31, -28, -67, -108, -122, -128, -110, -87,
- -53, 8, 60, 107, 107, 89, 83, 83, 76, 27, -14, -52, -84, -99, -103, -82,
- -72, -40, 4, 53, 92, 92, 88, 85, 97, 87, 42, 3, -45, -74, -106, -111,
- -105, -101, -70, -30, 27, 65, 77, 83, 87, 106, 90, 58, 16, -30, -67, -101,
- -100, -101, -93, -68, -27, 29, 60, 77, 79, 93, 111, 96, 71, 24, -21, -73,
- -109, -118, -127, -118, -98, -50, 6, 43, 65, 70, 99, 115, 108, 82, 40, -1,
- -53, -80, -94, -105, -101, -82, -31, 18, 56, 66, 72, 95, 103, 97, 64, 29,
- -15, -63, -85, -102, -105, -104, -81, -35, 13, 53, 58, 69, 86, 97, 94, 67,
- 39, -12, -54, -80, -97, -102, -103, -77, -38, 9, 40, 45, 60, 77, 95, 88,
- 70, 41, -8, -46, -74, -87, -99, -100, -78, -42, 10, 37, 50, 66, 89, 110,
- 103, 91, 57, 9, -33, -68, -86, -105, -105, -89, -51, -2, 23, 40, 53, 80,
- 99, 98, 89, 53, 8, -37, -68, -90, -107, -106, -94, -51, -5, 25, 43, 58,
- 86, 95, 98, 86, 52, 9, -36, -64, -92, -105, -108, -95, -53, -11, 22, 37,
- 57, 81, 90, 96, 82, 52, 6, -34, -64, -92, -104, -113, -97, -59, -18, 15,
- 31, 58, 79, 92, 98, 87, 57, 9, -29, -63, -87, -100, -109, -91, -58, -13,
- 16, 36, 62, 78, 93, 96, 88, 56, 12, -25, -62, -83, -101, -106, -89, -57,
- -15, 6, 30, 52, 71, 87, 94, 89, 55, 18, -21, -55, -76, -96, -100, -88,
- -53, -16, 6, 31, 53, 76, 93, 105, 98, 64, 26, -18, -52, -78, -99, -105,
- -95, -59, -26, 0, 24, 45, 66, 81, 97, 88, 62, 28, -12, -40, -67, -84,
- -95, -83, -50, -21, 4, 24, 47, 64, 81, 96, 85, 63, 26, -11, -41, -69,
- -88, -102, -91, -64, -36, -12, 10, 34, 51, 74, 87, 81, 62, 26, -7, -40,
- -63, -83, -95, -83, -58, -31, -10, 14, 34, 51, 75, 85, 82, 61, 30, -3,
- -34, -57, -81, -92, -83, -60, -36, -15, 11, 27, 47, 69, 80, 79, 59, 30,
- -5, -33, -57, -82, -93, -84, -61, -38, -15, 10, 25, 48, 68, 80, 77, 58,
- 29, -4, -30, -56, -80, -89, -78, -54, -34, -8, 10, 0, 0, 1, 0, -2,
- -2, -5, -8, -3, 3, -4, -10, 2, 8, 3, 4, 5, -3, -9, 10, 26,
- 26, 12, -4, -40, -64, -50, 1, 55, 69, 28, -23, -65, -83, -52, 13, 67,
- 67, 39, 16, -15, -48, -38, 10, 53, 44, 5, -5, -14, -43, -35, 16, 54,
- 37, -1, -26, -53, -82, -37, 35, 67, 44, 2, -10, -20, -39, -19, 27, 55,
- 42, 3, -26, -67, -107, -62, 43, 110, 102, 43, -18, -63, -91, -35, 73, 120,
- 77, -6, -72, -113, -109, -36, 53, 78, 50, 0, -46, -72, -71, -20, 67, 112,
- 100, 44, -24, -88, -123, -84, 5, 71, 97, 66, 7, -53, -100, -80, -1, 83,
- 127, 108, 38, -57, -121, -119, -57, 24, 84, 97, 62, -4, -77, -97, -46, 32,
- 101, 108, 56, -20, -103, -119, -69, 18, 105, 126, 90, 6, -92, -126, -90, -3,
- 85, 108, 75, 0, -86, -117, -85, -6, 76, 115, 101, 30, -68, -118, -105, -33,
- 57, 105, 102, 41, -46, -104, -112, -59, 25, 95, 121, 81, -5, -88, -126, -94,
- -12, 63, 101, 76, 7, -67, -107, -73, 11, 94, 127, 102, 21, -74, -124, -95,
- -21, 57, 101, 82, 21, -48, -89, -59, 6, 67, 95, 60, -11, -82, -115, -81,
- -13, 52, 84, 52, -9, -68, -96, -56, 9, 66, 93, 63, 10, -52, -86, -54,
- 1, 60, 96, 70, 19, -44, -80, -51, 0, 55, 94, 69, 20, -42, -88, -76,
- -40, 24, 79, 72, 34, -28, -75, -63, -23, 35, 71, 48, 4, -57, -95, -67,
- -10, 62, 103, 75, 18, -61, -110, -86, -22, 61, 110, 90, 37, -45, -100, -87,
- -39, 34, 81, 70, 33, -39, -88, -76, -24, 54, 94, 76, 32, -46, -100, -92,
- -42, 35, 73, 62, 26, -46, -97, -93, -44, 36, 81, 75, 35, -38, -87, -81,
- -26, 58, 99, 85, 37, -44, -101, -103, -46, 47, 98, 97, 56, -27, -90, -99,
- -49, 37, 88, 95, 62, -12, -74, -93, -51, 27, 69, 71, 35, -30, -78, -87,
- -38, 41, 84, 90, 57, -11, -71, -96, -56, 21, 69, 86, 60, -4, -67, -97,
- -61, 12, 65, 88, 65, 3, -61, -94, -60, 14, 71, 96, 68, 3, -66, -104,
- -70, 3, 59, 84, 59, -1, -67, -107, -76, -3, 59, 89, 64, 3, -67, -111,
- -82, -9, 57, 92, 76, 26, -43, -93, -71, -9, 50, 80, 64, 16, -51, -100,
- -79, -17, 49, 88, 77, 30, -41, -95, -79, -17, 49, 87, 77, 34, -36, -92,
- -78, -19, 44, 82, 73, 33, -37, -95, -84, -23, 47, 89, 83, 43, -30, -92,
- -83, -28, 39, 79, 74, 40, -28, -87, -82, -31, 34, 71, 67, 35, -31, -88,
- -85, -36, 28, 68, 69, 44, -20, -79, -83, -43, 19, 59, 64, 41, -25, -89,
- -100, -61, 9, 60, 76, 57, -10, -75, -90, -51, 22, 74, 88, 66, 1, -61,
- -78, -42, 25, 71, 84, 63, -1, -67, -90, -59, 8, 59, 81, 68, 8, -56,
- -85, -62, 1, 50, 74, 63, 7, -53, -84, -60, 5, 55, 80, 70, 17, -43,
- -76, -55, 4, 49, 73, 65, 17, -41, -77, -62, -9, 38, 68, 64, 17, -43,
- -84, -73, -22, 23, 56, 57, 18, -36, -77, -68, -23, 20, 51, 52, 16, -36,
- -77, -70, -26, 18, 54, 59, 28, -22, -64, -59, -20, 21, 56, 63, 36, -12,
- -55, -52, -16, 25, 58, 63, 35, -14, -59, -57, -22, 18, 51, 57, 31, -16,
- -58, -58, -27, 10, 43, 51, 30, -16, -59, -60, -28, 12, 48, 57, 35, -13,
- -59, -64, -35, 7, 47, 63, 47, 1, -46, -55, -32, 7, 47, 0, 0, -1,
- -1, -4, 1, -1, -3, -13, -8, -14, -3, -2, -2, 1, 8, 5, 7, -21,
- -13, -2, -6, -8, -22, -6, 5, 11, 34, 41, 33, 13, 28, 33, 48, 35,
- 21, -3, -26, -18, -10, 3, 7, 22, 21, 63, 40, 41, 43, 4, -8, -43,
- -63, -77, -77, -59, -18, 3, 2, -21, -46, -74, -90, -108, -101, -94, -89, -84,
- -85, -77, -59, -50, -33, -7, 18, 37, 47, 64, 101, 127, 125, 127, 126, 126,
- 126, 122, 100, 87, 62, 37, 28, 27, 25, 27, 34, 25, -4, -45, -85, -123,
- -128, -126, -128, -127, -123, -92, -73, -55, -45, -37, -33, -32, -33, -43, -53, -55,
- -43, -20, 3, 20, 34, 42, 49, 55, 63, 74, 84, 93, 101, 107, 112, 117,
- 109, 92, 63, 33, 8, -13, -25, -29, -30, -27, -27, -32, -46, -63, -82, -98,
- -109, -116, -121, -118, -104, -80, -49, -12, 21, 45, 58, 64, 66, 66, 61, 51,
- 44, 37, 32, 32, 33, 33, 28, 23, 15, 8, 3, 2, 9, 16, 20, 24,
- 23, 14, -1, -20, -37, -48, -53, -52, -47, -38, -26, -13, -5, -1, -4, -10,
- -22, -34, -43, -48, -46, -34, -16, 5, 25, 45, 65, 78, 84, 83, 71, 55,
- 39, 24, 9, -3, -12, -23, -34, -45, -57, -65, -71, -71, -63, -49, -34, -21,
- -11, -2, 2, 8, 11, 12, 14, 14, 20, 28, 38, 50, 58, 63, 61, 56,
- 46, 33, 17, -1, -19, -34, -45, -48, -44, -32, -19, -5, 5, 7, 4, -2,
- -7, -11, -15, -18, -21, -23, -26, -28, -30, -31, -29, -26, -20, -12, -1, 11,
- 21, 32, 42, 51, 55, 55, 52, 46, 41, 37, 32, 30, 28, 27, 24, 19,
- 12, -1, -21, -45, -67, -89, -103, -107, -101, -90, -70, -51, -33, -18, -2, 11,
- 23, 33, 39, 44, 49, 52, 57, 59, 59, 56, 52, 48, 41, 35, 28, 20,
- 15, 11, 4, 0, -5, -11, -18, -25, -34, -42, -47, -48, -46, -40, -33, -27,
- -24, -21, -24, -32, -42, -51, -56, -58, -56, -47, -35, -18, 2, 24, 48, 70,
- 88, 99, 104, 102, 97, 89, 79, 69, 59, 49, 37, 27, 14, 0, -14, -29,
- -44, -58, -71, -81, -87, -88, -88, -85, -81, -77, -72, -63, -51, -37, -21, -5,
- 12, 29, 43, 53, 59, 61, 57, 48, 36, 24, 13, 8, 8, 15, 25, 38,
- 48, 54, 54, 50, 43, 33, 22, 11, 3, -6, -15, -25, -35, -46, -54, -61,
- -65, -68, -69, -69, -68, -64, -59, -52, -43, -32, -20, -7, 6, 19, 31, 42,
- 51, 58, 62, 64, 62, 58, 52, 44, 35, 26, 17, 9, 1, -5, -10, -15,
- -18, -19, -20, -19, -18, -16, -15, -14, -14, -15, -16, -17, -18, -19, -19, -19,
- -19, -18, -16, -14, -11, -9, -6, -3, 0, 3, 6, 10, 14, 18, 22, 27,
- 32, 35, 37, 37, 35, 30, 23, 14, 4, -6, -15, -24, -31, -36, -39, -40,
- -39, -37, -32, -26, -19, -10, -1, 8, 17, 24, 29, 32, 33, 32, 29, 25,
- 20, 15, 11, 7, 3, -1, -5, -9, -14, -19, -24, -28, -31, -32, -31, -27,
- -23, -16, -10, -3, 2, 7, 10, 12, 13, 13, 13, 12, 10, 8, 7, 5,
- 5, 5, 5, 6, 8, 10, 13, 17, 20, 23, 25, 26, 25, 21, 16, 9,
- 1, -7, -16, -24, -31, -37, -42, -47, -49, -51, -52, -51, -48, -43, -37, -30,
- -20, -7, 6, 19, -1, -4, -4, 0, -1, -4, -3, 4, 4, -2, -3, 2,
- 1, -4, 0, 5, 0, -4, 2, -10, -26, -29, -34, -49, -61, -44, -21, -8,
- -3, -3, 1, 20, 32, 38, 32, 12, -4, 1, 14, 28, 51, 68, 78, 80,
- 72, 38, 1, -6, 16, 23, 2, -14, -15, -20, -33, -62, -65, -37, -18, -27,
- -29, -26, -45, -38, 8, 52, 55, 31, 26, 16, 17, 45, 80, 87, 77, 62,
- 54, 24, -23, -50, -43, -28, -47, -72, -86, -86, -87, -61, -35, -38, -57, -69,
- -55, -27, 1, 4, 22, 45, 54, 31, 0, -7, -5, -3, 0, -9, -21, -20,
- -15, -27, -31, -10, 5, 9, 3, -21, -67, -83, -46, -3, 8, 18, 22, 4,
- -3, 5, 35, 52, 67, 72, 83, 89, 71, 37, 19, 25, 8, -11, -37, -58,
- -80, -85, -68, -33, -24, -57, -60, -34, -16, -14, 17, 73, 96, 77, 48, 17,
- -7, -9, 4, -1, -3, 6, 3, -12, -10, 19, 33, 33, 41, 35, -29, -70,
- -64, -38, -18, 3, 17, -5, -26, -35, -5, 31, 63, 73, 86, 94, 80, 64,
- 50, 46, 37, 28, -2, -32, -65, -91, -84, -63, -59, -82, -97, -80, -66, -65,
- -43, 8, 49, 60, 61, 42, 27, 23, 23, 14, 15, 18, 10, -12, -17, -9,
- -13, 8, 35, 42, 2, -41, -76, -87, -67, -46, -31, -32, -45, -72, -53, -5,
- 32, 46, 72, 92, 96, 92, 77, 75, 73, 61, 44, 12, -32, -68, -72, -54,
- -58, -75, -85, -67, -57, -61, -60, -46, -11, 24, 35, 22, 15, 6, -1, -13,
- 8, 23, 8, -1, -1, -6, -8, 35, 71, 86, 79, 50, -11, -46, -38, -31,
- -29, -21, -30, -64, -68, -43, -12, 10, 28, 62, 89, 88, 84, 85, 90, 89,
- 95, 83, 28, -32, -53, -36, -44, -62, -64, -55, -59, -54, -52, -48, -23, 19,
- 48, 37, 39, 42, 31, 12, 19, 20, 5, 4, 1, -23, -40, -14, 14, 42,
- 68, 64, 14, -33, -53, -52, -32, -18, -24, -43, -67, -62, -36, -18, -1, 25,
- 54, 57, 58, 56, 54, 50, 66, 80, 44, -21, -50, -40, -52, -69, -77, -60,
- -56, -54, -53, -62, -49, -9, 28, 41, 58, 58, 47, 43, 49, 41, 34, 37,
- 18, -19, -44, -47, -36, 1, 35, 38, 19, -20, -62, -71, -59, -36, -34, -47,
- -63, -63, -50, -38, -17, 7, 37, 56, 74, 80, 73, 61, 87, 116, 99, 47,
- -7, -26, -22, -20, -32, -57, -72, -76, -76, -71, -47, -9, 13, 24, 29, 29,
- 25, 27, 52, 68, 62, 9, -38, -67, -66, -39, -11, -4, -24, -37, -47, -51,
- -49, -44, -55, -39, -6, -17, -52, -54, -19, 1, 15, 24, 31, 41, 55, 71,
- 79, 89, 111, 115, 88, 54, 22, -2, -8, -5, -7, -27, -49, -57, -69, -72,
- -64, -30, -3, 17, 31, 37, 29, 14, 39, 67, 73, 47, 10, -40, -72, -58,
- -23, -12, -19, -19, -39, -49, -42, -46, -62, -44, -8, -11, -36, -51, -39, -15,
- 0, 13, 21, 25, 40, 55, 63, 73, 95, 115, 115, 85, 53, 20, 2, -1,
- -2, -10, -32, -48, -64, -73, -77, -62, -33, -9, 16, 33, 31, 18, 17, 44,
- 67, 70, 49, 6, -45, -69, -53, -24, -13, -19, -24, -40, -47, -45, -50, -62,
- -43, -10, -13, -37, -51, -39, -15, 0, -3, -1, 1, -1, -6, -6, -4, -1,
- -2, -6, -8, -7, -4, -5, -10, -14, -16, -16, -16, -17, -18, -18, -17, -15,
- -15, -16, -15, -13, -10, -9, -9, -11, -13, -14, -11, -9, -8, -9, -7, -3,
- -2, -5, -8, -6, 1, 5, 4, 1, 0, 1, 4, 4, 4, 5, 7, 9,
- 9, 8, 8, 9, 10, 9, 5, 2, 3, 5, 7, 7, 9, 11, 11, 12,
- 14, 14, 12, 8, 7, 8, 5, 1, 3, 8, 9, 9, 10, 14, 16, 15,
- 14, 12, 11, 9, 7, 3, -2, -3, 3, 5, 0, -5, -1, -1, -6, -10,
- -16, -23, -28, -29, -32, -39, -36, -23, -16, -19, -19, -10, -7, -12, -11, -5,
- -6, -11, -13, -11, -9, -8, -2, 6, 8, 8, 9, 6, 2, 4, 8, 9,
- 4, 4, 12, 18, 17, 14, 17, 20, 20, 16, 9, 7, 7, 5, 3, 4,
- 1, -2, 0, 3, 2, -1, 1, 3, 3, 1, 2, 2, 0, 3, 6, 9,
- 8, 0, -5, -3, 7, 12, 8, -2, -2, 9, 10, 2, -3, 2, 5, 1,
- -3, -5, -6, -2, -3, -11, -20, -26, -28, -30, -32, -37, -43, -45, -43, -40,
- -42, -41, -31, -22, -20, -18, -16, -16, -19, -15, -8, -3, -3, 3, 17, 26,
- 22, 16, 18, 23, 27, 26, 23, 17, 15, 21, 25, 24, 25, 31, 36, 32,
- 29, 23, 17, 15, 11, 5, 1, 4, 6, 8, 6, 7, 8, 10, 14, 18,
- 22, 20, 17, 14, 15, 13, 10, 15, 15, 12, 9, 10, 15, 14, 9, 3,
- 6, 10, 5, -3, -9, -16, -16, -10, -11, -20, -24, -18, -20, -32, -42, -48,
- -55, -70, -84, -95, -100, -92, -75, -65, -68, -67, -56, -55, -51, -41, -33, -37,
- -42, -38, -33, -31, -26, -6, 19, 30, 25, 25, 28, 30, 27, 19, 16, 18,
- 31, 44, 46, 48, 56, 71, 77, 74, 66, 54, 47, 37, 19, 3, 2, 3,
- 3, 4, 13, 20, 21, 25, 24, 25, 19, 18, 19, 19, 14, 6, 17, 14,
- 1, 3, 12, 27, 29, 25, 13, 14, 24, 22, 6, -7, -7, 0, 11, 12,
- 1, 0, 10, 8, -13, -32, -46, -52, -57, -70, -88, -106, -101, -81, -74, -82,
- -75, -49, -37, -42, -44, -42, -46, -51, -47, -40, -32, -27, -6, 3, 16, 32,
- 29, 25, 24, 30, 54, 69, 74, 78, 90, 108, 118, 124, 117, 107, 102, 93,
- 76, 61, 50, 41, 35, 31, 26, 13, 4, 0, -1, 0, -6, -12, -10, -8,
- -4, 0, -3, -20, -31, -27, -18, -16, -22, -29, -28, -9, 0, -3, -1, 2,
- 11, 20, 24, 18, 22, 34, 32, 16, -1, -18, -34, -46, -55, -67, -91, -102,
- -91, -72, -73, -81, -68, -55, -55, -65, -74, -79, -87, -87, -83, -81, -77, -60,
- -25, 4, 4, -3, 0, 13, 29, 29, 24, 23, 29, 51, 67, 72, 77, 88,
- 105, 114, 122, 116, 106, 100, 93, 77, 63, 51, 42, 36, 31, 27, 15, 5,
- 0, -1, 0, -4, -10, -9, -7, -3, 2, -1, -16, -28, -26, -16, -13, -18,
- -25, -25, -8, 2, 1, 2, 5, 13, 21, 26, 20, 23, 35, 35, 20, 3,
- -14, -32, -45, -54, -67, -91, -102, -90, -72, -75, -82, -68, -56, -56, -66, -75,
- -81, -88, -88, -83, -82, -77, -59, -22, 4, 1, -1, -2, -3, -3, -1, -1,
- -6, -8, -9, -12, -5, 6, 15, 21, 22, 21, 9, -8, -16, -23, -32, -22,
- 4, 27, 32, 17, -2, -21, -34, -37, -30, -24, -3, 24, 47, 58, 50, 23,
- -12, -41, -52, -47, -33, -2, 28, 48, 45, 28, 0, -36, -58, -53, -34, -4,
- 26, 52, 75, 73, 45, -5, -66, -101, -90, -61, -14, 23, 59, 87, 89, 63,
- 10, -46, -79, -80, -55, -23, -3, 27, 58, 62, 41, -6, -66, -92, -77, -29,
- 19, 41, 65, 74, 69, 42, -9, -73, -109, -107, -67, -17, 23, 70, 104, 111,
- 83, 21, -56, -104, -109, -62, -21, 4, 34, 68, 89, 75, 19, -46, -89, -85,
- -38, -1, 23, 45, 64, 74, 62, 8, -53, -98, -93, -47, -9, 16, 36, 62,
- 86, 78, 13, -67, -121, -109, -56, -9, 25, 58, 89, 109, 81, 8, -70, -119,
- -106, -56, -7, 32, 63, 90, 108, 74, -3, -89, -128, -118, -70, -22, 23, 62,
- 101, 126, 98, 26, -64, -117, -110, -72, -32, 6, 44, 93, 124, 100, 28, -63,
- -116, -110, -71, -26, 16, 54, 101, 121, 92, 13, -86, -128, -120, -79, -28, 15,
- 60, 111, 127, 95, 11, -83, -127, -116, -80, -29, 15, 67, 117, 127, 100, 17,
- -75, -118, -108, -75, -31, 7, 60, 109, 123, 87, 3, -83, -118, -106, -67, -23,
- 13, 62, 106, 119, 85, 3, -77, -106, -95, -61, -27, 2, 52, 103, 124, 97,
- 19, -61, -95, -92, -63, -34, -4, 45, 94, 116, 87, 8, -63, -91, -85, -58,
- -36, -9, 36, 81, 104, 76, 2, -60, -87, -77, -52, -32, -2, 48, 97, 119,
- 86, 7, -59, -90, -85, -65, -50, -22, 26, 78, 107, 79, 11, -49, -78, -73,
- -58, -46, -18, 31, 85, 112, 75, 1, -59, -84, -73, -55, -40, -12, 30, 80,
- 106, 74, 10, -46, -70, -62, -49, -39, -13, 31, 86, 110, 74, 8, -49, -70,
- -59, -46, -33, -6, 38, 92, 111, 76, 13, -42, -62, -56, -51, -44, -23, 19,
- 75, 97, 67, 8, -44, -63, -58, -56, -48, -26, 19, 75, 94, 64, 8, -40,
- -55, -50, -49, -42, -25, 18, 69, 85, 57, 4, -41, -54, -51, -50, -45, -28,
- 18, 71, 88, 60, 8, -35, -46, -47, -48, -46, -30, 16, 66, 84, 59, 9,
- -30, -41, -43, -42, -40, -22, 25, 73, 88, 60, 8, -30, -42, -46, -45, -42,
- -21, 28, 74, 83, 52, -1, -36, -46, -45, -40, -37, -17, 26, 66, 73, 41,
- -10, -42, -54, -53, -48, -43, -19, 27, 68, 76, 44, -4, -34, -44, -41, -37,
- -33, -10, 34, 71, 75, 40, -7, -36, -47, -43, -39, -35, -9, 35, 72, 75,
- 39, -7, -38, -49, -45, -43, -38, -11, 33, 68, 70, 36, -4, -31, -39, -36,
- -35, -31, -5, 36, 69, 69, 35, -4, -31, -38, -35, -37, -33, -8, 31, 64,
- 63, 31, -7, -34, -42, -40, -43, -38, -12, 28, 61, 59, 27, -10, -34, -40,
- -38, -41, -35, -9, 31, 63, 60, 29, -6, -31, -37, -38, -42, -35, -10, 29,
- 60, 56, 27, -8, -30, -33, -34, -38, -32, -10, 28, 56, 51, 23, -9, -29,
- -32, -34, -38, -33, -10, 29, 55, 50, 23, -9, -28, -30, -33, -37, -32, -8,
- 32, 56, 52, 23, 23, 0, -2, 0, -2, -6, -6, -6, -5, -2, -1, 5,
- 15, 20, 11, 12, 12, 6, 0, -8, -19, -12, -4, -19, -19, -4, 4, -7,
- -3, 5, 8, 11, 14, 9, 9, 8, -4, -11, -6, -8, -16, -14, -7, -1,
- -3, 1, 10, 13, 24, 28, 12, 10, 14, 11, -14, -29, -19, -12, -21, -25,
- -16, 2, 0, -11, -7, 7, 10, 0, 0, 5, 11, 6, 10, 21, 13, 7,
- 14, 4, -4, -9, -5, -11, -16, -7, -3, 3, 15, -2, 2, 17, 6, -19,
- -16, 3, 3, -14, -10, 7, 7, 4, 8, 11, 4, -5, -12, -9, -6, -14,
- -13, -17, -13, -8, 5, 9, 3, 10, 12, 24, 28, 26, 35, 20, -3, 24,
- 23, -19, -31, -23, -23, -38, -34, -18, -10, -8, -6, -4, -1, 5, -4, -8,
- 2, 15, 12, 26, 56, 37, 10, 25, 25, -4, -21, -24, -23, -26, -30, -27,
- -8, 10, -5, 3, 30, 6, -26, -7, 13, -2, -19, -2, 11, 3, 14, 21,
- 8, 12, 5, -19, -26, -12, 9, 1, -8, -8, 20, 27, 17, 16, 15, 0,
- 23, 39, 11, -4, -13, -21, -21, -32, -36, -27, -20, -24, -10, -4, 5, 14,
- 4, -11, -10, 7, -8, -7, 7, 7, 2, 15, 29, 55, 26, 4, 22, 37,
- 32, 14, 10, 18, 7, -1, -28, -49, -24, -14, -41, -53, -37, -28, -27, -15,
- 1, 2, 14, 14, 13, 3, 0, 1, 18, 9, 7, 11, 23, 23, 25, 16,
- -7, 1, 13, 26, 26, 9, 13, 28, 28, 1, -29, -29, -26, -27, -43, -43,
- -31, -12, -26, -15, 6, 16, 6, 22, 11, -4, 0, 3, 0, -4, -20, -9,
- 15, 23, 19, 7, 25, 19, 42, 63, 40, 13, 22, 24, 1, -41, -60, -55,
- -63, -69, -61, -31, -7, 10, 8, 0, 7, 4, 4, 20, 5, -4, 9, 27,
- 31, 27, 23, 13, 19, 12, 2, 4, 15, 20, 35, 19, 16, 26, 3, -30,
- -48, -31, -40, -60, -59, -47, -13, -3, 12, 22, 11, 7, 9, 8, 3, -10,
- -34, -5, 6, 24, 38, 19, 13, 21, 40, 15, 2, 27, 26, 16, 44, 47,
- -7, -43, -41, -29, -44, -80, -81, -58, -26, -17, 3, 16, 30, 19, 10, 25,
- 16, 6, -12, -3, 13, 30, 38, 20, 17, 22, 25, 18, 13, 16, -3, 1,
- 32, 44, -11, -48, -51, -34, -38, -49, -64, -70, -23, -10, -14, -1, 20, 18,
- 20, 21, 11, 3, -8, -3, 13, 14, 22, 18, 32, 37, 30, 25, 16, 27,
- 27, 18, 37, 52, 12, -26, -56, -57, -46, -71, -92, -86, -50, -21, -10, 8,
- 15, 15, 18, 28, 17, 1, 1, 2, 13, 13, 23, 23, 21, 29, 31, 29,
- 15, 20, 33, 32, 29, 46, 21, -31, -49, -53, -51, -66, -82, -76, -54, -32,
- -10, 12, 19, 29, 18, 3, 0, 16, 20, 29, 31, 20, 25, 31, 43, 41,
- 34, 44, 27, 29, 65, 54, -15, -70, -79, -63, -86, -114, -114, -79, -26, -2,
- 6, 18, 19, 10, 19, 26, 15, 5, 0, 16, 23, 29, 30, 21, 25, 28,
- 37, 37, 38, 44, 32, 29, 66, 65, -7, -67, -74, -59, -82, -114, -117, -85,
- -31, -2, 11, 20, 18, 9, 20, 30, 15, 5, 0, 0, 1, 1, 2, 3,
- 3, 3, 4, 4, 5, 6, 6, 7, 8, 8, 7, 7, 7, 7, 7, 6,
- 4, 3, 2, 0, -1, -2, -3, -5, -6, -8, -9, -9, -11, -12, -14, -15,
- -17, -17, -17, -18, -19, -19, -19, -18, -17, -16, -15, -13, -11, -8, -7, -6,
- -5, -3, -1, 0, 0, 1, 3, 5, 8, 10, 12, 14, 17, 19, 21, 23,
- 26, 27, 28, 28, 28, 26, 25, 24, 23, 23, 21, 19, 18, 16, 15, 14,
- 13, 12, 11, 11, 11, 10, 8, 6, 5, 5, 4, 2, 0, -2, -4, -5,
- -7, -10, -11, -12, -13, -14, -15, -15, -15, -15, -15, -16, -17, -18, -18, -19,
- -21, -23, -25, -27, -28, -29, -29, -30, -30, -29, -27, -25, -23, -22, -20, -18,
- -16, -14, -13, -12, -11, -11, -10, -9, -8, -6, -5, -4, -3, -1, 1, 3,
- 4, 6, 7, 8, 8, 9, 10, 11, 12, 13, 13, 13, 13, 15, 18, 21,
- 23, 24, 25, 25, 28, 31, 33, 34, 34, 32, 31, 31, 31, 30, 27, 22,
- 16, 12, 10, 9, 7, 3, -5, -13, -19, -22, -22, -23, -25, -28, -31, -33,
- -33, -32, -32, -31, -32, -33, -32, -29, -25, -21, -19, -19, -19, -19, -18, -15,
- -9, -3, 2, 6, 9, 12, 16, 21, 27, 32, 37, 39, 40, 40, 39, 39,
- 40, 41, 40, 38, 35, 34, 34, 33, 29, 22, 16, 11, 10, 11, 12, 12,
- 10, 8, 7, 5, 3, 2, 0, -6, -12, -19, -23, -23, -22, -23, -26, -30,
- -33, -33, -33, -34, -35, -37, -40, -45, -50, -53, -52, -48, -42, -37, -32, -27,
- -22, -20, -18, -16, -16, -18, -21, -26, -30, -33, -34, -35, -36, -38, -40, -41,
- -41, -38, -36, -36, -38, -41, -40, -38, -34, -30, -27, -25, -22, -20, -16, -15,
- -16, -17, -18, -16, -13, -10, -7, -4, -2, 1, 6, 11, 16, 21, 24, 25,
- 26, 24, 22, 19, 18, 19, 22, 24, 26, 30, 33, 38, 44, 50, 56, 61,
- 63, 68, 72, 74, 73, 68, 64, 57, 50, 47, 46, 44, 37, 21, 3, -11,
- -20, -23, -25, -30, -33, -36, -36, -34, -31, -27, -22, -21, -22, -21, -18, -21,
- -24, -27, -31, -33, -32, -27, -21, -14, -13, -17, -17, -10, 0, 10, 15, 16,
- 14, 8, 6, 10, 16, 25, 34, 39, 43, 47, 53, 62, 72, 82, 89, 92,
- 90, 84, 79, 77, 77, 76, 67, 54, 42, 33, 26, 18, 5, -11, -27, -41,
- -53, -65, -73, -77, -79, -81, -86, -93, -102, -110, -116, -118, -120, -124, -127, -128,
- -128, -126, -122, -116, -107, -96, -85, -78, -72, -64, -54, -45, -39, -40, -46, -49,
- -49, -47, -45, -44, -45, -45, -44, -42, -38, -33, -29, -26, -23, -20, -18, -14,
- -11, -8, -5, -2, 2, 7, 11, 10, 8, 7, 9, 16, 22, 26, 28, 31,
- 34, 39, 44, 49, 53, 57, 60, 62, 63, 63, 65, 66, 63, 57, 51, 46,
- 46, 50, 53, 54, 55, 54, 55, 57, 63, 69, 73, 75, 73, 69, 66, 64,
- 65, 63, 55, 43, 30, 18, 11, 3, -6, -15, -23, -29, -32, -32, -28, -22,
- -16, -13, -16, -16, -11, -2, 9, 15, 1, 0, 0, 0, -1, 0, -3, 0,
- -1, 0, -18, 21, -22, 23, -41, 20, 84, -39, 50, -61, 26, -126, -19, -37,
- 15, 2, 70, -33, 127, -55, 117, -73, 15, -45, -50, 8, -11, 23, 33, 1,
- 26, -67, 26, -25, 14, -45, 57, -124, 12, -4, -23, 107, -54, 127, -49, 43,
- 27, -59, -30, 15, -128, 5, -128, 86, -39, 82, 12, 62, 9, 51, -59, 53,
- -95, 67, -92, 68, -28, 94, 21, 47, -11, -1, -41, 0, -25, -9, 18, -68,
- 15, -27, 49, -27, 103, -4, 3, -36, 58, -98, 56, -116, -31, -123, 25, -58,
- 89, -21, 110, -25, 73, -28, 39, -21, 35, -40, 37, -20, 50, 55, 51, 6,
- 1, -47, -11, -32, -23, 38, -67, 3, -54, 34, -55, 79, 1, 32, -61, 89,
- -86, 53, -67, -10, -128, -6, -68, 51, -4, 82, 15, 83, -16, 63, -24, 55,
- -29, 8, 0, 6, 11, 54, 14, 16, -39, -9, -12, -47, 37, -40, -22, -60,
- 21, -76, 51, -17, 74, -63, 98, -36, 44, -33, 24, -113, -37, -89, 20, -30,
- 67, 18, 87, 0, 67, -6, 38, 1, -2, -18, -5, -20, 32, 17, 21, -8,
- -30, 15, -47, 11, -17, 11, -97, 43, -87, 27, -36, 91, -41, 66, 3, 44,
- -28, 55, -74, -37, -92, -21, -37, 33, -1, 75, 22, 36, 14, 26, 8, 8,
- -12, -7, -21, -1, 27, 11, 21, -30, 21, -37, -3, -13, 23, -27, -32, -10,
- -23, -44, 56, -1, 43, -12, 76, -29, 48, -9, -25, -71, -70, -48, -20, 2,
- 9, 56, 8, 56, -10, 52, -12, 31, -29, 27, -60, 62, -42, 83, -45, 30,
- -24, 4, -26, 33, -23, 5, -18, -25, -53, -7, -6, -6, 19, 16, 31, 3,
- 58, -14, 0, -64, -33, -58, -8, -43, 42, -18, 57, -9, 54, 1, 47, -3,
- 36, -18, 3, 4, 6, 2, -17, 8, -14, -27, 35, 2, -3, 1, -8, -43,
- -34, -1, -22, 12, 2, 37, -6, 53, 14, 16, -43, -22, -75, -2, -67, 23,
- -24, 39, -3, 39, 6, 44, 9, 37, 5, 1, 3, 5, 12, -18, 0, 0,
- -31, 5, 23, 1, -3, 10, -20, -48, -6, -30, 7, -18, 35, -4, 32, 21,
- 39, -26, -1, -75, -9, -65, -3, -28, 20, -5, 32, 5, 36, 20, 30, 30,
- 3, 10, -1, 16, -10, -7, -1, -17, -23, 18, 14, -3, 8, 9, -45, -14,
- -35, -1, -27, 18, -2, 29, 1, 61, -14, 20, -56, -19, -51, -22, -38, 9,
- -14, 22, 5, 24, 27, 23, 41, 13, 20, -7, 23, -2, -8, -2, -9, -26,
- -6, 14, 11, -11, 37, -33, -12, -38, -6, -33, 7, -14, 30, -12, 55, 4,
- 33, -32, -14, -45, -22, -43, -7, -15, 18, 18, 33, 17, 41, 22, 15, 14,
- 8, -24, -16, -18, -16, -7, 6, 16, -2, 8, -14, -6, -23, 0, -22, 1,
- -23, 21, 4, 24, -1, 9, -9, -11, -14, -13, -16, -14, -15, -12, -16, -5,
- 8, 28, 25, 28, 34, 27, 15, 16, 2, -20, -22, -20, -15, -8, 10, 11,
- 7, -3, -5, -16, -10, -13, -5, -16, -5, 4, 17, 13, 6, 1, -9, -1,
- -2, -3, -4, -4, -5, -5, -5, -5, -5, -5, -5, -5, -5, -5, -5, -6,
- -6, -6, -6, -6, -5, -3, -3, -5, -5, -5, -7, -8, -5, 4, 5, 13,
- 12, -12, -5, 10, 5, 4, 0, 3, 26, 33, 10, -15, -69, -89, -25, 25,
- 58, 70, 22, -41, -62, -31, 18, 17, -17, -12, -9, 20, 99, 96, 0, -88,
- -123, -69, 61, 116, 54, -11, -45, -28, 40, 38, -42, -59, -53, -31, 63, 78,
- -9, -65, -83, -59, 48, 110, 50, -11, -51, -54, 41, 96, 9, -87, -119, -77,
- 42, 118, 67, -18, -57, -46, 24, 89, 81, 22, -43, -77, -65, -41, -23, -3,
- 4, 8, -13, -54, -52, -21, 30, 89, 86, 8, -49, -76, -56, 30, 55, 52,
- 47, -7, -45, -49, -48, -10, 68, 74, 43, 22, -27, -25, 12, 20, -5, -43,
- -69, -46, 21, 53, 51, 38, -8, -32, 6, 20, -1, -19, -56, -67, -26, 27,
- 76, 95, 23, -64, -60, -15, 33, 39, -8, -37, -24, -7, 7, 4, -25, -23,
- -10, -14, -7, -5, -12, 2, 28, 31, 37, 21, -18, -16, -4, -22, -37, -46,
- -56, -8, 58, 64, 53, 31, -9, -9, -2, -57, -85, -52, -13, 59, 92, 21,
- -42, -47, -33, 27, 75, 27, -22, -38, -44, 18, 77, 32, -21, -46, -50, 34,
- 89, 22, -37, -60, -56, 31, 95, 36, -27, -57, -82, -15, 53, 15, -13, -25,
- -44, 14, 66, 14, -32, -53, -62, 25, 96, 50, 3, -32, -56, 25, 98, 51,
- -9, -56, -78, 7, 92, 71, 28, -31, -92, -42, 28, 20, 24, 8, -34, 22,
- 70, 18, -17, -53, -88, -20, 39, 7, -2, -8, -28, 35, 80, 19, -23, -55,
- -93, -22, 63, 54, 47, 19, -52, -35, 2, -36, -32, -18, -49, -9, 41, 15,
- 26, 34, -22, -6, 31, 1, 8, 9, -43, -15, 30, -3, -1, -7, -73, -48,
- 6, -14, 5, 13, -47, -30, 12, -13, 6, 18, -37, -13, 39, 27, 45, 38,
- -37, -32, 12, 3, 32, 46, -10, 6, 48, 16, 15, 15, -32, -2, 47, 24,
- 26, 18, -51, -51, -15, -29, -1, 19, -28, -15, 21, 2, 18, 22, -34, -24,
- 13, -3, 15, 14, -45, -34, 7, 10, 38, 31, -34, -30, 4, 5, 43, 61,
- 13, 4, 6, -22, 4, 24, -13, -13, -10, -34, 0, 23, -16, -16, -13, -42,
- -18, -4, -36, -17, 5, -10, 14, 22, -21, -22, -16, -37, -6, 20, -2, 17,
- 36, 19, 43, 43, -9, -15, -12, -29, 6, 31, 6, 10, 7, -23, -2, 9,
- -23, -15, -10, -26, 3, 20, -5, 1, 0, -22, 5, 22, -6, -8, -16, -37,
- -5, 20, 2, 11, 6, -19, 11, 33, 12, 20, 16, -7, 20, 35, 11, 11,
- -3, -28, 2, 19, -1, 3, -6, -29, -5, 2, -25, -17, -12, -16, 22, 34,
- 3, -4, -21, -36, 4, 26, 8, -1, -30, -54, -23, -3, -11, 0, -12, -27,
- 7, 24, 13, 19, -1, -21, 10, 27, 14, 17, 0, -14, 18, 33, 19, 14,
- -17, -41, -10, 9, 2, 7, -14, -30, 4, 20, 9, 9, -15, -35, -3, 16,
- 9, 0, -1, -2, -3, 4, 7, 4, -2, -3, 0, 3, -1, -1, 4, 5,
- -2, -13, -9, 1, 4, 2, 1, 2, 2, -2, -8, -4, 0, 4, 4, -3,
- -4, -3, 1, 2, -1, 3, 14, 1, -7, -12, -4, -2, 1, 1, 9, 5,
- -6, -5, -2, -1, -1, 1, 14, 6, -6, -7, 3, 8, -2, -4, 13, 12,
- -10, -17, -10, -5, -4, 2, 3, 7, -6, -6, -1, -1, -4, 1, 11, 6,
- -6, -9, 10, 11, 3, 1, 14, 15, -12, -20, -12, -9, -15, -1, 7, 2,
- -16, -7, 6, 0, -2, 10, 26, 17, -6, -11, 24, 21, 1, 0, 18, 15,
- -17, -31, -28, -23, -14, 0, -4, 0, -16, -8, 8, -4, -3, 7, 15, 5,
- -3, -3, 26, 25, 12, 8, 28, 17, -15, -28, -18, -17, -18, -7, -3, -7,
- -20, 0, 7, 1, -9, 6, 9, -4, -9, 2, 15, 24, 34, 31, 10, -4,
- -15, -29, -17, -21, -41, -40, -5, 19, -20, 3, 11, 33, 28, 21, 18, 15,
- 16, 3, -1, 18, 17, 15, 1, -15, -10, -5, -14, -42, -48, -43, -26, 4,
- -29, -14, -9, 32, 20, 12, 15, 21, 39, 24, 8, 26, 33, 6, -3, 0,
- 1, -7, -16, -41, -44, -51, -34, -3, -6, -6, -19, 26, 10, 15, 35, 46,
- 32, 20, 16, 23, 38, 15, -4, -10, 17, -6, -41, -48, -53, -70, -52, -9,
- -9, -22, -15, 19, 24, 22, 30, 49, 34, 10, 1, 15, 33, 15, 1, 17,
- 46, 12, -38, -59, -50, -57, -46, -13, -16, -30, -24, 26, 37, 33, 30, 45,
- 40, 2, -11, 17, 41, 24, -4, 16, 48, 15, -38, -67, -64, -65, -46, -18,
- -18, -35, -32, 35, 39, 37, 21, 45, 42, -2, -19, 14, 37, 22, 7, 24,
- 40, 13, -42, -68, -63, -63, -38, -6, -12, -34, -25, 39, 43, 39, 17, 47,
- 45, 3, -19, 21, 45, 25, 2, 21, 31, 0, -45, -71, -78, -83, -48, 2,
- 7, -27, -32, 34, 45, 49, 23, 44, 36, 5, -5, 38, 60, 27, -13, 21,
- 42, -13, -69, -81, -86, -79, -38, -9, -11, -41, -36, 38, 56, 45, 10, 43,
- 43, 10, -6, 36, 57, 41, 10, 36, 46, -16, -67, -66, -71, -80, -44, -8,
- -5, -29, -27, 30, 43, 46, 20, 52, 39, -9, -21, 40, 68, 42, -1, 20,
- 32, -14, -70, -86, -94, -90, -45, -2, 0, -31, -17, 36, 47, 46, 18, 44,
- 29, -2, -11, 46, 74, 51, 14, 36, 46, -15, -78, -87, -91, -89, -46, -12,
- -11, -28, -5, 41, 46, 40, 17, 51, 33, -6, -13, 49, 75, 52, 15, 30,
- 34, -21, -79, -88, -93, -88, -42, -9, -4, -25, -3, 36, 40, 34, 16, 44,
- 23, -8, -10, 52, 83, 55, 17, 38, 31, -31, -82, -91, -93, -82, -39, -16,
- -10, -25, 5, 33, 42, 32, 20, 54, 25, -9, -3, 59, 85, 63, 24, 37,
- 24, -39, -86, -92, -97, -80, -34, -17, -15, -24, 10, 35, 45, 32, 16, 45,
- 12, -23, -2, 62, 78, 53, 21, 37, 26, -39, -91, -95, -96, -77, -29, -16,
- -16, -25, 10, -1, 0, 3, 21, -26, 18, -30, 32, -19, -15, -27, 2, 0,
- 103, -84, -53, -52, 79, 51, 36, -69, -31, 48, 71, 33, -74, -64, 10, 51,
- 49, -68, -91, -16, 30, 33, -31, -58, -42, 14, 24, -25, 23, -71, 79, -22,
- 123, -74, 28, 28, 115, 99, -7, 9, -15, 72, 1, 16, -47, -5, -71, -18,
- -75, -26, -71, -28, -56, -24, -57, -19, -33, -5, 7, -3, 14, -8, 82, 100,
- 23, -32, -15, 80, 98, 68, -30, -21, 24, 71, 28, -41, -96, -22, 32, 37,
- -57, -110, -67, 28, 35, -22, -112, -79, 13, 70, 27, -55, -63, 31, 95, 86,
- -4, -40, 29, 110, 110, 28, -50, -12, 66, 80, 14, -87, -81, -7, 36, -5,
- -95, -118, -42, 26, 8, -69, -121, -48, 37, 60, -6, -68, -29, 67, 104, 61,
- -24, -17, 70, 123, 92, -5, -43, 23, 82, 67, -28, -96, -54, 18, 30, -39,
- -115, -96, -7, 25, -13, -99, -101, -13, 52, 42, -35, -62, 9, 88, 93, 28,
- -32, 15, 97, 118, 58, -29, -24, 51, 82, 39, -61, -88, -26, 28, 9, -70,
- -117, -63, 7, 14, -46, -109, -71, 15, 55, 16, -51, -42, 43, 94, 75, 2,
- -21, 48, 107, 101, 23, -36, 4, 65, 70, 1, -81, -69, -3, 26, -19, -94,
- -106, -32, 14, -3, -74, -103, -37, 34, 46, -10, -56, -12, 66, 91, 49, -15,
- 1, 74, 111, 76, -4, -28, 31, 72, 50, -33, -85, -43, 11, 15, -46, -106,
- -80, -11, 13, -26, -92, -84, -8, 44, 29, -30, -48, 19, 80, 81, 26, -18,
- 27, 91, 103, 49, -22, -10, 48, 68, 22, -60, -75, -22, 17, -5, -71, -105,
- -54, 3, 3, -49, -98, -58, 14, 44, 11, -44, -27, 45, 85, 65, 5, -8,
- 53, 100, 87, 21, -26, 11, 60, 56, -6, -74, -58, -4, 13, -25, -90, -91,
- -29, 7, -12, -72, -90, -29, 32, 37, -10, -46, -2, 66, 83, 47, -8, 10,
- 74, 101, 68, -3, -19, 31, 62, 38, -36, -77, -40, 6, 4, -49, -100, -72,
- -12, 3, -31, -86, -73, -4, 37, 25, -28, -36, 25, 75, 74, 25, -9, 34,
- 88, 94, 43, -16, -4, 47, 58, 15, -57, -69, -22, 6, -12, -73, -96, -50,
- -4, -7, -53, -89, -49, 13, 36, 5, -37, -17, 47, 77, 59, 9, 2, 58,
- 92, 79, 19, -17, 16, 54, 45, -13, -69, -52, -8, 3, -33, -85, -82, -29,
- -2, -20, -68, -79, -23, 24, 29, -11, -34, 7, 61, 73, 41, 0, 22, 73,
- 90, 58, 1, -9, 32, 52, 26, -36, -69, -35, -3, -7, -53, -90, -63, -16,
- -7, -36, -78, -60, -4, 29, 16, -22, -23, 29, 68, 64, 26, 2, 42, 80,
- 81, 38, -8, 5, 42, 44, 4, -53, -57, -21, -2, -22, -69, -83, -43, -10,
- -15, -51, -77, -38, 11, 27, 3, -27, -5, 46, 68, 52, 13, 15, 58, 83,
- 68, 19, -8, 21, 46, 32, -16, -60, -44, -12, -6, -36, -76, -74, -34, -10,
- -20, -57, -73, -33, 12, 27, 3, -1, -6, -11, -3, 4, 0, -7, -8, 1,
- 21, 14, 28, 33, 25, -1, 7, 4, -13, -21, -44, -29, -17, -31, -32, 2,
- 0, -20, 4, 3, 4, 0, -2, -5, -4, -14, 3, 14, 9, 28, 34, 54,
- 43, 54, 39, 19, 17, -1, 5, -23, -31, -25, -35, -46, -60, -29, -29, -13,
- -37, -22, -16, -20, -27, -21, -6, -16, 8, -5, 15, 26, 69, 65, 74, 85,
- 81, 76, 51, 22, -10, -10, -19, -3, -39, -73, -55, -36, -18, -45, -49, -45,
- -52, -47, -74, -73, -56, -31, -15, -16, -5, 18, 65, 86, 108, 94, 97, 90,
- 79, 54, 30, 19, 10, 25, -16, -34, -37, -9, -16, -35, -44, -60, -60, -50,
- -62, -70, -66, -44, -34, -34, -29, -10, 23, 61, 85, 79, 75, 70, 61, 41,
- 31, 7, 8, 3, -22, -42, -28, 0, -13, -29, -39, -52, -56, -55, -58, -60,
- -57, -41, -35, -37, -19, 5, 35, 71, 87, 85, 97, 112, 97, 71, 56, 52,
- 53, 43, 18, -7, -3, 10, 0, -17, -39, -55, -58, -64, -80, -106, -121, -112,
- -110, -113, -105, -82, -51, -8, 16, 20, 45, 66, 66, 49, 46, 59, 75, 78,
- 63, 62, 74, 80, 80, 69, 51, 27, 11, 0, -14, -40, -53, -48, -55, -68,
- -71, -56, -34, -1, 14, 24, 49, 62, 59, 42, 34, 43, 47, 43, 26, 30,
- 33, 38, 26, 4, -17, -41, -66, -81, -92, -112, -120, -115, -116, -128, -125, -103,
- -71, -36, -11, 9, 33, 56, 59, 54, 61, 67, 77, 77, 77, 79, 74, 75,
- 73, 55, 30, 10, -21, -38, -46, -61, -70, -67, -70, -81, -77, -64, -45, -23,
- -4, 10, 30, 44, 44, 39, 42, 48, 51, 50, 51, 58, 58, 65, 65, 47,
- 29, 12, -14, -31, -41, -53, -63, -60, -62, -64, -58, -44, -26, -11, 1, 10,
- 20, 22, 17, 9, 5, 6, 6, 2, 4, 10, 10, 17, 19, 9, 7, -1,
- -14, -18, -13, -14, -9, 1, 7, 12, 17, 23, 31, 35, 36, 35, 38, 31,
- 21, 16, 3, 0, -8, -11, -11, -13, -19, -20, -23, -34, -39, -51, -69, -78,
- -81, -83, -83, -78, -70, -60, -47, -34, -19, 2, 20, 39, 57, 60, 66, 67,
- 63, 61, 53, 50, 51, 47, 37, 32, 23, 13, 6, -3, -17, -23, -28, -34,
- -37, -35, -27, -15, -2, 4, 12, 23, 30, 44, 47, 43, 41, 35, 29, 22,
- 15, 13, 14, 7, -1, -5, -11, -19, -20, -25, -37, -43, -41, -43, -47, -47,
- -40, -29, -17, -7, 5, 13, 23, 38, 44, 37, 34, 31, 23, 17, 6, 1,
- -2, -10, -20, -25, -35, -45, -50, -54, -64, -68, -65, -66, -65, -59, -47, -30,
- -19, -7, 5, 14, 28, 48, 62, 66, 72, 75, 78, 76, 67, 60, 56, 46,
- 32, 20, 9, -2, -10, -21, -35, -43, -44, -49, -56, -57, -51, -38, -25, -13,
- -2, 9, 25, 42, 56, 59, 64, 65, 67, 65, 57, 52, 49, 41, 28, 18,
- 8, -2, -10, 0, 8, 13, 21, 20, 20, 17, 10, 8, -2, -6, -17, -21,
- -29, -23, -25, -14, -7, -2, 7, 10, 20, 21, 22, 23, 19, 14, 9, -2,
- -6, -18, -20, -28, -25, -23, -18, -10, -3, 5, 9, 22, 17, 28, 22, 21,
- 17, 11, 2, -8, -18, -23, -27, -26, -24, -19, -13, -6, 3, 9, 17, 20,
- 28, 24, 25, 21, 13, 6, -5, -14, -21, -29, -29, -30, -23, -19, -7, -1,
- 10, 18, 25, 29, 27, 28, 20, 17, 5, -7, -13, -26, -29, -30, -30, -27,
- -20, -12, 0, 11, 19, 25, 27, 30, 26, 28, 19, 11, -2, -12, -24, -30,
- -35, -34, -30, -24, -14, -2, 9, 18, 23, 28, 26, 33, 31, 29, 24, 12,
- 5, -12, -23, -30, -37, -36, -36, -26, -19, -5, 5, 19, 22, 32, 32, 36,
- 35, 26, 21, 3, -6, -22, -34, -41, -44, -38, -31, -18, -6, 6, 15, 23,
- 32, 33, 39, 34, 31, 23, 10, -2, -21, -32, -44, -47, -45, -37, -23, -12,
- 6, 13, 28, 30, 38, 40, 40, 38, 23, 17, -6, -15, -35, -42, -50, -49,
- -41, -31, -14, 0, 14, 26, 35, 42, 45, 45, 40, 27, 18, -4, -14, -33,
- -42, -54, -52, -47, -36, -21, -5, 13, 24, 39, 43, 52, 47, 42, 36, 20,
- 7, -15, -32, -45, -55, -56, -54, -43, -27, -8, 12, 26, 38, 45, 50, 51,
- 48, 40, 27, 9, -11, -30, -46, -58, -62, -58, -49, -31, -11, 9, 24, 41,
- 45, 54, 53, 54, 45, 30, 14, -10, -27, -48, -58, -67, -64, -56, -35, -15,
- 6, 24, 37, 45, 54, 56, 56, 49, 39, 18, 0, -26, -45, -60, -74, -70,
- -63, -41, -23, 4, 21, 39, 48, 53, 61, 58, 59, 43, 29, 3, -20, -46,
- -64, -77, -77, -69, -50, -27, 0, 20, 36, 49, 56, 64, 64, 63, 51, 34,
- 6, -17, -46, -65, -79, -83, -76, -58, -33, -6, 17, 38, 49, 60, 67, 68,
- 66, 53, 37, 13, -13, -38, -65, -79, -90, -82, -68, -41, -15, 14, 36, 52,
- 63, 70, 73, 69, 62, 44, 19, -8, -38, -63, -83, -93, -90, -77, -49, -20,
- 12, 34, 54, 65, 72, 75, 76, 65, 51, 26, -1, -33, -62, -86, -98, -96,
- -86, -58, -29, 6, 32, 54, 66, 73, 79, 76, 73, 58, 36, 4, -27, -60,
- -85, -101, -104, -92, -70, -36, -1, 31, 53, 70, 75, 81, 80, 78, 65, 41,
- 15, -24, -56, -84, -105, -109, -101, -79, -46, -7, 25, 56, 65, 77, 82, 85,
- 83, 69, 51, 19, -14, -50, -83, -103, -115, -107, -88, -55, -17, 21, 50, 67,
- 81, 86, 89, 85, 79, 55, 28, -8, -46, -77, -103, -116, -117, -97, -67, -25,
- 1, 39, 66, 81, 92, 96, 97, 90, 73, 45, 11, -27, -64, -97, -120, -128,
- -117, -89, -49, -5, 35, 65, 81, 93, 98, 99, 91, 75, 46, 12, -27, 28,
- -9, -42, -57, -50, -18, 33, 77, 77, 17, -64, -96, -55, 22, 73, 68, 17,
- -43, -77, -67, -15, 59, 102, 79, 12, -48, -71, -57, -28, -3, 11, 10, -3,
- -17, -4, 44, 88, 79, 10, -69, -103, -74, -6, 54, 75, 53, -4, -63, -80,
- -38, 32, 73, 59, 7, -43, -67, -57, -18, 33, 71, 71, 24, -31, -47, -17,
- 20, 23, -14, -58, -73, -47, 10, 73, 110, 93, 20, -62, -97, -68, -6, 43,
- 54, 28, -13, -51, -65, -35, 26, 74, 69, 12, -50, -68, -37, 9, 37, 37,
- 16, -12, -26, -7, 36, 65, 45, -19, -87, -112, -75, -7, 58, 97, 92, 41,
- -30, -75, -62, -3, 49, 52, 7, -44, -63, -45, -6, 37, 60, 42, -5, -42,
- -41, -3, 38, 41, 8, -33, -51, -38, 3, 54, 90, 79, 12, -76, -127, -106,
- -29, 47, 78, 63, 23, -19, -36, -16, 24, 50, 35, -15, -59, -64, -27, 17,
- 40, 35, 11, -20, -39, -26, 19, 63, 67, 14, -61, -97, -72, -5, 64, 101,
- 87, 26, -49, -96, -86, -32, 24, 40, 17, -11, -17, -3, 24, 51, 55, 29,
- -20, -66, -69, -23, 35, 55, 25, -26, -59, -55, -14, 44, 86, 80, 23, -56,
- -105, -87, -19, 48, 79, 67, 27, -18, -46, -43, -14, 17, 16, -20, -54, -47,
- 3, 59, 83, 66, 18, -35, -64, -54, -8, 44, 59, 18, -48, -87, -72, -16,
- 49, 88, 84, 37, -31, -81, -79, -26, 33, 52, 29, -5, -19, -6, 20, 34,
- 27, -5, -51, -84, -71, -9, 62, 95, 71, 12, -40, -58, -37, 8, 52, 63,
- 22, -53, -103, -88, -23, 47, 80, 64, 24, -14, -33, -28, -3, 21, 18, -15,
- -45, -39, 5, 57, 78, 54, -1, -60, -97, -89, -29, 50, 92, 67, 0, -53,
- -57, -13, 38, 64, 52, 10, -44, -82, -76, -26, 28, 49, 32, 1, -14, -1,
- 24, 40, 38, 9, -43, -87, -79, -13, 69, 110, 80, 4, -65, -90, -69, -21,
- 32, 58, 39, -9, -48, -45, 0, 52, 69, 46, 5, -34, -57, -50, -14, 23,
- 28, -8, -48, -48, 4, 71, 99, 69, 3, -63, -99, -88, -30, 46, 92, 78,
- 16, -45, -66, -44, -6, 25, 34, 16, -24, -55, -43, 10, 67, 80, 37, -22,
- -48, -29, 7, 30, 27, -5, -51, -84, -73, -11, 71, 116, 95, 27, -43, -84,
- -84, -43, 18, 63, 60, 10, -44, -53, -9, 41, 49, 14, -31, -57, -50, -15,
- 29, 61, 57, 14, -37, -51, -14, 38, 63, 47, -1, -61, -106, -105, -47, 44,
- 115, 113, 42, -36, -64, -42, -2, 23, 20, -3, -28, -39, -21, 24, 64, 59,
- 7, -48, -67, -47, -7, 36, 59, 47, 2, -55, -77, -31, 55, 111, 89, 7,
- -75, -113, -96, -42, 21, 62, 64, 28, -13, -18, 17, 45, 28, -2, -7, -6,
- -7, -7, -8, -8, -8, -8, -7, -6, -5, -4, -3, -3, -2, -2, -1, 0,
- 1, 2, 4, 5, 6, 8, 9, 10, 11, 12, 13, 13, 14, 15, 16, 17,
- 17, 17, 17, 17, 16, 16, 15, 15, 14, 14, 13, 12, 10, 10, 9, 8,
- 7, 6, 5, 5, 4, 3, 2, 1, 0, -2, -3, -4, -5, -6, -7, -8,
- -9, -10, -11, -12, -13, -13, -14, -14, -14, -14, -14, -15, -15, -15, -15, -16,
- -16, -14, -14, -12, -10, -13, -10, -13, -7, -3, -5, -1, -1, -5, -5, 8,
- 13, 10, 10, 15, 16, 17, 30, 34, 19, 17, 22, 29, 27, 22, 16, 1,
- -3, 8, 18, 11, 6, 8, 8, 1, 6, 18, 5, -8, -4, 4, 5, 3,
- 5, -3, -6, 12, 30, 23, 9, 5, 6, 9, 15, 27, 20, 2, 0, 10,
- 17, 8, -1, -4, -8, -8, -3, -7, -19, -28, -24, -22, -31, -42, -47, -50,
- -50, -42, -35, -35, -43, -41, -31, -27, -23, -17, -9, -7, 3, 26, 37, 38,
- 37, 41, 39, 39, 49, 55, 50, 46, 53, 58, 51, 44, 36, 24, 9, 5,
- 2, -12, -25, -28, -26, -33, -42, -44, -55, -66, -69, -62, -60, -65, -57, -42,
- -33, -26, -15, -5, -6, 0, 15, 29, 34, 41, 55, 61, 62, 68, 71, 62,
- 49, 49, 49, 39, 29, 24, 14, -2, -10, -16, -34, -56, -67, -70, -77, -83,
- -85, -88, -93, -92, -79, -74, -78, -74, -61, -49, -41, -23, -9, -2, 11, 35,
- 54, 56, 58, 64, 69, 73, 81, 91, 86, 77, 78, 77, 67, 50, 39, 24,
- 6, -4, -10, -22, -41, -49, -52, -62, -73, -81, -87, -98, -97, -83, -74, -70,
- -63, -46, -33, -23, -6, 9, 18, 26, 48, 69, 77, 85, 97, 106, 107, 111,
- 114, 104, 89, 83, 84, 75, 60, 50, 34, 13, -5, -16, -34, -59, -74, -80,
- -86, -95, -97, -96, -104, -104, -95, -86, -86, -82, -66, -49, -32, -11, 12, 26,
- 36, 55, 73, 81, 84, 94, 104, 107, 114, 120, 116, 102, 92, 88, 73, 54,
- 37, 21, 0, -16, -23, -37, -58, -76, -85, -94, -108, -114, -116, -120, -119, -106,
- -89, -84, -78, -64, -49, -37, -21, 1, 13, 25, 46, 71, 88, 95, 105, 113,
- 112, 113, 116, 112, 97, 91, 91, 83, 68, 51, 35, 11, -10, -23, -38, -60,
- -80, -86, -93, -102, -107, -110, -116, -121, -114, -102, -98, -93, -77, -55, -38, -18,
- 1, 13, 25, 46, 71, 88, 95, 105, 113, 112, 113, 116, 112, 97, 91, 91,
- 83, 68, 51, 35, 11, -10, -23, -38, -60, -80, -86, -93, -102, -107, -110, -116,
- -121, -114, -102, -98, -93, -77, -55, -38, -18, 1, -3, -7, -8, -3, 1, 0,
- 3, -5, -9, -14, -15, -4, 0, 7, 12, 12, 11, 18, 16, 14, 14, 11,
- 20, 14, 19, 7, 12, 8, 13, 8, 7, 9, 0, 9, -7, -4, -5, -8,
- -7, -9, -7, -2, -7, -4, 1, 1, 0, -2, 3, 2, 1, 2, 1, -2,
- -3, -7, -2, -2, -2, -5, -4, -4, -4, 3, 6, 8, 3, 0, -3, -2,
- 3, 4, 3, 2, 2, -2, 1, 0, 2, 3, 9, 8, 2, -3, -4, -2,
- 1, 4, 0, -2, 3, 1, 7, 1, -4, 0, 2, 3, 1, 1, 2, -5,
- 3, -3, -4, -3, -8, 2, -7, 1, -3, -2, -5, -8, -7, -8, -7, -5,
- -7, -4, -8, -10, -7, -8, -7, -5, 0, -2, 0, -2, -3, -3, -2, 0,
- 1, 0, 1, 0, -3, -3, -5, -5, -9, -9, -13, -16, -21, -26, -25, -25,
- -16, -16, -12, -13, -15, -9, 3, 25, 44, 66, 68, 66, 49, 17, 13, 18,
- 41, 51, 40, 35, 25, 23, -2, -16, -28, -8, -4, -12, -18, -34, -29, -31,
- -28, -18, -4, 2, 16, 13, 20, 9, 4, 2, -3, -4, -9, -9, -9, -8,
- -9, -10, -13, -14, -15, -13, -4, 7, 13, 19, 18, 16, 9, 7, 4, 6,
- 8, 7, 7, 3, -3, -15, -19, -24, -21, -16, -9, 0, 3, 7, 4, 4,
- -3, -2, 6, 13, 20, 14, 16, 14, 11, 7, 0, -4, -3, -3, -7, -12,
- -12, -9, -5, -5, -7, -9, -4, -2, -2, -2, -4, -9, -10, -13, -13, -14,
- -15, -13, -9, -8, -9, -9, -7, -4, 2, 2, 6, 9, 8, 11, 9, 11,
- 9, 8, 6, 0, -7, -13, -21, -29, -36, -45, -53, -63, -72, -73, -61, -41,
- 0, 52, 98, 109, 81, 64, 54, 78, 77, 45, 39, 44, 25, 19, 6, -8,
- 25, 30, 44, 62, 46, -20, -85, -89, -88, -47, -29, -30, 2, 11, 8, 12,
- 24, 33, 29, 25, 22, 1, -15, -34, -37, -36, -41, -36, -28, -15, 2, 9,
- 11, 14, 12, 8, 12, 17, 18, 19, 23, 20, 20, 20, 8, -5, -14, -15,
- -15, -13, -13, -18, -19, -24, -29, -32, -31, -23, -12, -2, 12, 20, 23, 24,
- 25, 20, 22, 18, 16, 14, 9, 7, 2, 1, -9, -10, -19, -15, -12, -13,
- -8, -5, -4, -4, -7, -10, -12, -12, -16, -14, -8, -9, -13, -14, -18, -15,
- -10, -5, -3, 3, 4, 6, 11, 13, 13, 16, 16, 16, 12, 6, -3, -10,
- -16, -21, -28, -37, -48, -61, -77, -88, -87, -68, -34, 28, 92, 127, 99, 64,
- 50, 72, 92, 55, 43, 51, 41, 32, 4, -8, -7, -17, -23, -31, -33, -35,
- -32, -28, -23, -18, -12, -8, -4, -2, 0, 1, 2, 2, 3, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 3, 4, 6, 7, 7, 7, 8, 9, 9, 8,
- 8, 9, 11, 14, 18, 22, 27, 32, 33, 30, 21, 6, -12, -30, -45, -54,
- -56, -51, -41, -29, -17, -9, -3, 0, 1, 1, 1, 1, 1, 1, 1, 2,
- 2, 3, 3, 3, 3, 3, 2, 3, 4, 5, 8, 9, 10, 9, 8, 7,
- 7, 8, 10, 15, 20, 25, 30, 35, 39, 39, 32, 19, 0, -22, -42, -56,
- -62, -61, -53, -40, -27, -15, -7, -3, -1, 0, 0, 0, 0, 2, 3, 4,
- 5, 5, 5, 4, 2, 0, -1, 0, 2, 5, 8, 9, 10, 10, 9, 9,
- 8, 9, 10, 14, 19, 24, 28, 32, 34, 38, 36, 29, 17, -5, -28, -49,
- -61, -65, -61, -52, -39, -25, -14, -7, -3, -2, -1, -2, -1, 0, 2, 4,
- 6, 7, 7, 5, 3, 0, -1, -1, 0, 3, 7, 11, 13, 14, 13, 12,
- 10, 8, 8, 9, 12, 17, 22, 26, 29, 31, 33, 31, 26, 18, 3, -16,
- -35, -50, -59, -61, -56, -46, -35, -23, -14, -6, -2, 0, 1, 2, 3, 4,
- 4, 5, 5, 5, 4, 2, 1, -1, -1, 0, 2, 5, 9, 12, 13, 13,
- 12, 11, 9, 7, 7, 8, 11, 15, 20, 24, 29, 33, 35, 34, 30, 21,
- 4, -16, -37, -55, -66, -68, -63, -50, -35, -21, -9, -1, 4, 5, 5, 4,
- 4, 3, 3, 3, 3, 2, 2, 1, 0, -1, -1, 1, 6, 10, 13, 15,
- 15, 13, 11, 8, 5, 4, 4, 7, 11, 17, 22, 27, 32, 36, 39, 39,
- 36, 24, 6, -20, -48, -70, -81, -79, -67, -48, -29, -12, -1, 5, 7, 7,
- 4, 2, 1, 1, 2, 2, 3, 2, 2, -1, -2, -3, -3, -1, 3, 8,
- 13, 16, 17, 16, 12, 8, 3, -1, -3, -2, 2, 11, 21, 29, 36, 38,
- 39, 42, 48, 57, 52, 23, -27, -76, -107, -113, -98, -71, -42, -18, -1, 8,
- 12, 13, 10, 7, 3, 1, 1, 2, 3, 2, 1, 0, -2, -3, -3, -1,
- 2, 8, 13, 17, 18, 17, 12, 7, 1, -3, -4, -3, 20, 30, 38, 41,
- 39, 38, 46, 65, 75, 45, -23, -89, -126, -127, -101, -64, -31, -7, 5, 11,
- 13, 14, 13, 9, 4, 1, 0, 1, 2, 1, -1, -3, -4, -4, -2, 2,
- 6, 10, 14, 18, 18, 15, 9, 1, -6, -10, -13, -10, -4, 7, 20, 0,
- 14, 19, 23, 26, 28, 28, 26, 23, 18, 11, 3, -4, -10, -16, -21, -23,
- -24, -22, -20, -16, -12, -8, -3, 3, 8, 13, 19, 23, 26, 27, 26, 23,
- 17, 10, 4, -3, -9, -15, -20, -24, -25, -25, -22, -17, -11, -3, 3, 9,
- 14, 18, 20, 22, 23, 23, 21, 17, 13, 6, 1, -6, -11, -15, -18, -20,
- -19, -19, -17, -16, -13, -11, -8, -5, -1, 2, 5, 7, 9, 9, 8, 6,
- 3, 0, -3, -7, -10, -14, -17, -19, -19, -18, -16, -12, -7, -2, 3, 8,
- 13, 16, 18, 19, 17, 14, 8, -1, -11, -21, -31, -38, -41, -40, -34, -25,
- -12, 2, 17, 32, 45, 56, 62, 65, 63, 58, 49, 38, 25, 10, -6, -18,
- -28, -37, -44, -51, -59, -64, -64, -56, -40, -17, 7, 29, 46, 56, 58, 59,
- 56, 51, 45, 33, 19, 4, -13, -26, -39, -49, -56, -59, -55, -46, -34, -19,
- -4, 10, 21, 30, 40, 46, 51, 52, 49, 43, 31, 18, 5, -8, -16, -21,
- -23, -26, -29, -35, -39, -42, -40, -34, -22, -11, 2, 11, 18, 21, 24, 23,
- 22, 19, 14, 7, -3, -13, -21, -30, -39, -46, -50, -52, -49, -42, -31, -17,
- -3, 12, 26, 39, 49, 57, 60, 58, 51, 39, 22, 1, -23, -47, -68, -82,
- -89, -88, -77, -60, -37, -11, 16, 43, 65, 83, 94, 100, 101, 96, 87, 71,
- 51, 29, 4, -18, -38, -58, -75, -91, -104, -109, -105, -87, -61, -27, 8, 39,
- 67, 87, 97, 97, 88, 71, 54, 36, 16, -2, -23, -42, -57, -70, -75, -75,
- -71, -60, -43, -23, -1, 18, 31, 47, 57, 66, 71, 68, 61, 49, 32, 17,
- 1, -11, -22, -33, -41, -47, -54, -59, -63, -62, -57, -46, -30, -12, 1, 17,
- 30, 41, 49, 50, 47, 40, 29, 17, 3, -14, -30, -46, -60, -70, -76, -77,
- -73, -63, -48, -28, -4, 20, 44, 65, 81, 91, 93, 88, 77, 60, 37, 11,
- -19, -49, -76, -97, -109, -110, -100, -81, -56, -25, 7, 38, 67, 91, 109, 121,
- 127, 126, 116, 96, 68, 38, 8, -18, -43, -68, -90, -110, -124, -127, -116, -91,
- -59, -22, 14, 47, 77, 98, 107, 105, 93, 74, 54, 33, 13, -6, -26, -45,
- -60, -71, -78, -79, -74, -61, -42, -21, 1, 18, 33, 49, 60, 68, 73, 70,
- 62, 48, 32, 15, 0, -13, -24, -34, -42, -48, -55, -61, -65, -65, -60, -48,
- -32, -15, 2, 19, 32, 43, 50, 51, 47, 40, 28, 16, 1, -14, 2, -2,
- 2, -5, -3, -1, 0, -4, -4, -6, -4, -6, -4, -4, -7, -6, -7, -6,
- -1, 0, 3, 13, 14, 16, 12, 13, 2, 1, 0, -1, -1, -1, -2, -2,
- -2, -3, -3, -4, -8, -4, -4, -5, -5, -5, -7, -9, -12, -8, -14, -11,
- -14, -18, -8, 1, 31, 71, 68, 24, -5, -11, -7, -5, -5, -5, -3, -2,
- -5, -5, -9, -8, -7, -7, -9, -12, -11, -17, -14, -16, -15, -20, -26, -30,
- -27, -15, 16, 51, 87, 101, 70, 8, -18, -11, -14, -7, -7, -1, -2, -5,
- -7, -12, -14, -10, -10, -13, -14, -13, -16, -16, -17, -18, -35, -31, -30, -34,
- -9, 16, 56, 84, 89, 60, 30, 5, -7, -5, -8, -3, -4, -4, -6, -12,
- -14, -13, -10, -12, -12, -9, -10, -8, -12, -13, -15, -19, -23, -26, -33, -29,
- -28, -9, 12, 43, 71, 88, 72, 48, 29, -2, -16, -19, -12, -12, -12, -7,
- -11, -10, -10, -10, -11, -13, -15, -18, -19, -17, -16, -15, -13, -12, -13, -9,
- -13, -17, -21, -18, 2, 34, 59, 87, 92, 98, 38, -30, -24, -27, -18, -16,
- -11, -11, -13, -15, -12, -14, -15, -18, -17, -20, -18, -15, -10, -7, -3, -1,
- 2, -8, -11, -22, -22, -20, 7, 31, 61, 97, 106, 43, -23, -28, -25, -20,
- -12, -7, -5, -7, -10, -13, -13, -13, -11, -14, -15, -15, -12, -8, -7, -4,
- -2, -4, -10, -15, -19, -26, -10, 12, 42, 72, 101, 90, 20, -25, -27, -22,
- -18, -10, -6, -9, -11, -16, -17, -16, -14, -10, -8, -9, -9, -9, -9, -9,
- -8, -5, -3, -6, -10, -17, -24, -21, 4, 30, 61, 84, 96, 79, -16, -38,
- -27, -26, -17, -12, -8, -12, -13, -14, -14, -11, -8, -4, -4, -7, -9, -8,
- -10, -12, -8, -5, -4, -7, -10, -18, -24, -11, 14, 42, 70, 79, 93, 36,
- -32, -26, -28, -19, -15, -9, -9, -13, -16, -14, -12, -8, -5, -3, -7, -9,
- -9, -9, -11, -8, -5, -1, -6, -9, -15, -24, -23, 6, 28, 63, 86, 127,
- 37, -45, -27, -28, -26, -19, -4, -5, -8, -11, -12, -14, -12, -8, -4, -8,
- -8, -10, -8, -13, -8, -8, -3, -8, -8, -16, -23, -17, 7, 34, 69, 83,
- 113, 37, -50, -28, -25, -22, -16, 0, -3, -8, -12, -12, -14, -14, -10, -5,
- -7, -6, -9, -9, -13, -9, -10, -7, -9, -9, -15, -20, -14, 8, 33, 64,
- 81, 90, 57, -29, -28, 0, -4, 10, 10, 11, -15, 4, -1, 3, -11, 11,
- 2, -12, 3, 18, -10, -62, 89, -16, -95, 118, -128, 122, -128, 112, -100, 109,
- -121, 120, -104, 58, 10, -88, 127, -102, 6, 98, -126, 35, 89, -111, -7, 112,
- -53, -94, 92, 64, -106, -53, 109, 52, -100, -75, 86, 95, -45, -119, -12, 111,
- 74, -58, -118, -27, 97, 100, -4, -107, -95, 17, 109, 92, -4, -99, -109, -26,
- 78, 115, 66, -27, -104, -109, -41, 55, 112, 98, 32, -53, -109, -105, -44, 41,
- 102, 109, 67, -4, -74, -112, -102, -47, 27, 88, 112, 93, 45, -19, -78, -110,
- -105, -65, -4, 59, 101, 110, 87, 43, -13, -67, -103, -111, -89, -44, 13, 65,
- 100, 109, 93, 59, 14, -36, -78, -104, -108, -90, -53, -6, 43, 83, 104, 106,
- 88, 57, 17, -27, -66, -95, -108, -102, -80, -44, -2, 41, 77, 99, 106, 98,
- 77, 46, 10, -29, -64, -91, -105, -105, -91, -64, -29, 10, 48, 78, 98, 105,
- 100, 84, 59, 30, -3, -36, -65, -88, -101, -105, -99, -83, -60, -32, -1, 30,
- 58, 80, 96, 103, 102, 94, 80, 62, 40, 16, -10, -35, -58, -78, -92, -101,
- -104, -100, -91, -77, -58, -36, -13, 12, 36, 57, 75, 89, 98, 102, 102, 97,
- 88, 76, 61, 44, 25, 5, -15, -35, -54, -70, -84, -94, -101, -104, -103, -98,
- -89, -77, -63, -46, -27, -8, 12, 31, 49, 65, 79, 90, 97, 102, 104, 102,
- 97, 90, 81, 70, 57, 42, 27, 10, -7, -24, -40, -56, -70, -81, -91, -99,
- -103, -105, -105, -101, -95, -87, -76, -63, -49, -34, -18, -1, 16, 32, 48, 62,
- 74, 85, 93, 100, 104, 105, 105, 102, 97, 90, 82, 72, 61, 48, 35, 21,
- 6, -9, -24, -38, -52, -65, -76, -86, -94, -101, -105, -108, -108, -106, -102, -96,
- -87, -78, -66, -54, -40, -26, -11, 4, 19, 34, 48, 61, 73, 83, 92, 99,
- 104, 107, 108, 108, 105, 101, 96, 89, 80, 70, 60, 48, 36, 22, 9, -5,
- -19, -33, -46, -58, -69, -80, -89, -96, -102, -107, -109, -110, -110, -107, -102, -97,
- -89, -80, -70, -59, -47, -33, -20, -6, 7, 19, 30, 41, 50, 58, 65, 71,
- 75, 78, 79, 80, 79, 77, 74, 70, 65, 60, 54, 48, 42, 36, 29, 22,
- 16, 10, 4, -2, -7, -12, -16, -19, -22, -24, -26, -27, -27, -27, -26, -25,
- -23, -22, -19, -17, -14, -12, -10, -1, -1, -4, -9, -9, -7, -6, -7, -3,
- 4, 8, 10, 11, 13, 10, 4, -3, -10, -15, -13, -9, -10, -11, -5, 4,
- 12, 14, 12, 13, 14, 9, 1, -8, -15, -21, -23, -22, -13, -3, 7, 17,
- 24, 27, 19, 11, 16, 15, -5, -24, -29, -23, -27, -32, -21, 5, 18, 20,
- 21, 24, 24, 15, 11, 8, -6, -30, -31, -19, -17, -24, -14, 2, 17, 15,
- 12, 17, 16, 19, 8, -5, -2, -1, -17, -17, -3, 6, 5, -4, 0, 1,
- -12, -9, 9, 11, -4, -14, -8, 9, -2, -21, -14, 4, 9, 9, 11, 18,
- 21, 10, 8, 16, 10, 26, 35, 6, -14, -28, -25, -24, -55, -65, -33, -17,
- 1, -6, -6, 8, 23, 33, 49, 37, 19, 16, 11, 24, 42, 17, -37, -36,
- 3, 7, -23, -36, -9, 9, -12, -20, -8, -2, -4, -23, -17, -6, 0, 10,
- 24, 24, 40, 46, 33, 39, 26, 5, 6, 9, -12, -26, -33, -42, -61, -52,
- -43, -37, -21, -4, 7, 13, 28, 36, 31, 24, 1, -1, 20, 24, 23, 21,
- 26, 27, 8, -32, -44, -3, 28, -1, -36, -30, -6, 13, -12, -34, -18, -6,
- 9, 21, 25, 16, 10, 38, 62, 46, 17, -11, -7, 10, -8, -44, -53, -33,
- -35, -38, -29, -27, -16, 0, 1, 9, 37, 50, 36, 2, -20, -12, 15, 21,
- 24, 32, 29, 20, 23, 12, -8, -3, 4, -10, -5, 2, -19, -63, -70, -21,
- 20, 41, 23, 33, 57, 61, 42, 21, 15, 10, -45, -82, -60, -29, -44, -77,
- -50, -7, 4, -4, 10, 32, 56, 42, 1, -10, -18, 2, 22, 28, 33, 42,
- 47, 43, 47, 11, -23, 0, 10, -40, -81, -70, -28, -29, -68, -29, 19, 6,
- 7, 21, 40, 41, 32, 22, 28, 47, 69, 66, 35, 21, 15, -3, -20, -34,
- -24, -6, -19, -59, -47, -42, -35, -28, 15, 45, 51, 66, 78, 83, 37, 1,
- 13, 7, -51, -81, -92, -83, -87, -74, -58, -73, -51, 12, 35, 26, 35, 47,
- 69, 70, 63, 65, 49, 47, 68, 73, 52, 33, 15, -12, -30, -50, -51, -46,
- -45, -60, -50, -50, -50, -54, -24, 38, 78, 90, 106, 99, 40, -6, -11, -46,
- -110, -127, -107, -76, -67, -53, -41, -41, -23, 14, 33, 27, 34, 49, 70, 71,
- 66, 65, 51, 51, 69, 72, 52, 32, 10, -12, 0, -5, -2, -5, 2, -29,
- 22, 0, -27, 67, -59, 45, -13, -37, 28, 65, -4, 6, 60, 5, 58, 44,
- 60, 27, 43, 96, 71, 81, 48, 96, 70, 23, 90, 66, 80, 88, 40, 20,
- 61, 64, 12, 36, 24, 4, 7, 5, -27, -38, -26, -33, -49, -50, -70, -69,
- -93, -92, -94, -104, -104, -101, -110, -107, -111, -111, -126, -87, -119, -100, -94, -112,
- -93, -93, -80, -81, -76, -58, -56, -70, -30, -21, -42, -13, -3, 2, 8, 20,
- 28, 41, 45, 59, 62, 69, 84, 85, 90, 103, 109, 111, 118, 121, 121, 123,
- 121, 122, 121, 122, 121, 122, 121, 121, 120, 121, 120, 121, 120, 121, 120, 120,
- 119, 120, 119, 120, 118, 105, 106, 110, 83, 89, 92, 75, 67, 61, 57, 47,
- 40, 33, 24, 17, 10, 3, -2, -10, -20, -31, -31, -37, -49, -50, -63, -66,
- -69, -74, -79, -91, -89, -92, -95, -102, -106, -104, -107, -113, -113, -110, -113, -116,
- -114, -115, -114, -115, -114, -113, -114, -113, -114, -113, -112, -113, -109, -105, -111, -106,
- -107, -103, -100, -103, -99, -97, -98, -99, -92, -92, -93, -92, -92, -90, -88, -90,
- -88, -86, -89, -85, -85, -87, -85, -85, -82, -83, -82, -80, -78, -79, -76, -74,
- -73, -73, -69, -68, -66, -64, -65, -62, -58, -56, -56, -52, -50, -47, -43, -42,
- -39, -35, -33, -31, -27, -23, -21, -16, -16, -8, -7, -3, 1, 0, 10, 15,
- 15, 19, 26, 29, 30, 38, 41, 42, 47, 54, 54, 57, 63, 68, 69, 72,
- 77, 78, 80, 85, 84, 86, 87, 86, 87, 86, 85, 86, 85, 84, 85, 84,
- 83, 84, 83, 82, 82, 83, 82, 81, 82, 81, 80, 81, 80, 79, 80, 79,
- 79, 78, 79, 78, 78, 77, 74, 70, 66, 64, 61, 55, 52, 49, 45, 40,
- 35, 32, 29, 24, 19, 15, 12, 8, 4, 0, -4, -8, -11, -15, -17, -20,
- -25, -26, -29, -32, -34, -37, -39, -41, -43, -45, -46, -48, -49, -50, -50, -52,
- -52, -53, -52, -53, -54, -53, -53, -52, -52, -51, -50, -50, -49, -48, -48, -46,
- -45, -44, -42, -41, -40, -39, -37, -35, -34, -32, -30, -28, -27, -24, -23, -22,
- -20, -19, -17, -15, -14, -13, -12, -10, -9, -8, -8, -6, -6, -5, -4, -4,
- -3, -3, -2, -2, -1, -2, -1, -2, -1, -1, 0, -1, -1, 1, 0, 0,
- -3, -1, 1, -4, -4, -3, -2, -5, -3, 0, -1, -1, -3, -1, 0, 2,
- 0, -2, -5, 5, 4, 1, 7, 2, 2, 1, 8, 1, 6, 2, -4, 2,
- 1, -4, 6, -8, -3, -7, -2, -6, -1, -9, 1, -2, -4, 1, 2, 1,
- -2, 8, 2, 0, 14, 9, 10, 5, 3, 5, 6, 4, 3, -8, -2, -4,
- -10, -1, -5, -3, -4, -6, -13, -5, -4, -4, -3, 2, -13, -6, 3, 6,
- 6, 7, 1, 1, 6, 6, 16, 13, 9, 10, 9, 2, 7, 10, 4, -4,
- -3, -17, -7, -6, -6, -10, -17, -17, -10, -11, -9, -5, -6, -8, 2, 1,
- 8, 19, 15, 18, 24, 19, 16, 17, 19, 11, 7, 1, -5, -8, -9, -15,
- -8, -9, -14, -20, -19, -9, -18, -10, -13, -23, -13, -12, -7, 0, -1, 5,
- 16, 12, 28, 30, 32, 34, 34, 19, 24, 23, 16, 11, 5, -7, -19, -17,
- -16, -21, -26, -23, -32, -31, -30, -25, -26, -24, -19, -13, -9, -1, 0, 4,
- 6, 13, 15, 19, 17, 13, 8, 8, 8, 7, 0, -4, -8, -10, -7, -5,
- -6, -6, -9, -12, -8, -10, -9, -9, -11, -13, -12, -9, -4, -1, 4, 9,
- 19, 27, 31, 26, 16, 14, 16, 16, 12, 1, -8, -14, -11, -9, -6, -11,
- -11, -12, -14, -10, -11, -13, -15, -19, -23, -19, -14, -8, -5, -1, 8, 34,
- 62, 59, 12, 14, 32, 22, 6, 20, 6, -9, -54, -16, -1, -19, 7, -15,
- -13, -12, -14, -15, -14, -22, -24, -30, -30, -20, -12, -6, 3, 26, 66, 88,
- 39, 0, 47, 36, -2, 26, -23, 21, 13, -6, -60, -42, 6, -22, 4, -18,
- -16, -4, -16, -19, -24, -39, -31, -25, -32, -26, -11, 12, 55, 104, 75, 10,
- 35, 62, 9, 26, -16, -8, 19, 3, -9, -61, -46, 2, -26, -7, -16, -10,
- 2, -7, -22, -23, -38, -40, -37, -44, -33, -8, 37, 101, 124, 36, -5, 89,
- 20, 38, 5, -26, 3, 1, 5, -28, -65, -21, 1, -22, -12, -26, 1, -7,
- -10, -24, -26, -33, -37, -48, -50, -36, 5, 63, 122, 109, 7, 35, 84, 5,
- 59, -36, -4, -11, -1, -5, -40, -55, -4, -15, -21, -16, -22, 5, -10, -17,
- -20, -27, -23, -44, -54, -62, -23, 29, 114, 127, 51, 7, -2, -4, -2, 4,
- 11, 14, 10, 2, -7, -9, -9, -15, -16, -7, 3, 2, -10, -21, -17, 6,
- 10, -8, -28, -11, 45, 66, 64, 47, 36, 49, 49, 27, 9, -12, -18, -25,
- -30, -11, 0, -5, 0, -1, -18, -36, -33, -18, -10, -13, -31, -26, -25, -17,
- 4, 28, 70, 89, 48, 9, -32, -58, -56, -70, -57, -17, -38, -48, -35, -32,
- -7, 35, 38, 53, 62, 44, 33, 27, -6, -35, -52, -65, -54, -40, -43, -30,
- -25, 2, 63, 54, 34, 17, 34, 70, 60, 8, -15, -3, 0, 39, 55, 35,
- 39, 60, 75, 36, 20, -7, -25, -66, -110, -89, -89, -71, -36, -12, 9, 31,
- 41, 54, 46, 45, 59, 41, 22, 3, -69, -110, -126, -116, -64, -15, 9, 29,
- 33, 30, 56, 42, 12, 23, 6, -27, -36, -21, -22, -32, -21, -30, -29, -5,
- 9, 16, 22, -9, -12, 31, 24, -17, -41, -23, 32, 32, 26, 34, 64, 66,
- 109, 104, 51, 5, 12, 16, -36, -58, -59, -66, -63, -82, -64, -23, -9, 11,
- 16, 20, 19, 13, 12, 33, 37, 41, 46, 28, 7, -58, -93, -79, -64, -33,
- -1, 22, -4, 2, 19, 4, -7, -3, -3, 5, 1, -10, -3, 12, -6, -38,
- -29, -17, -5, 11, 2, -33, -20, 44, 42, 20, -30, -24, 9, 44, 38, 20,
- 36, 71, 61, 86, 72, 25, -8, 10, 17, -35, -54, -63, -67, -70, -78, -58,
- -16, -7, 19, 22, 20, 21, 29, 21, 16, 35, 36, 16, -8, -27, -61, -58,
- -67, -43, 3, 35, 38, -2, -2, 10, -9, -29, -14, -5, -1, -5, 2, 12,
- -6, -32, -23, -22, -16, -5, 3, -9, -29, 27, 56, 39, 11, -27, -28, 23,
- 34, 28, 18, 20, 62, 82, 71, 74, 24, -4, 16, 18, -39, -54, -65, -61,
- -52, -64, -49, -11, -4, 12, 17, 16, 25, 24, 6, 23, 36, 18, 18, -1,
- -42, -50, -90, -43, 3, 35, 38, -2, -2, 10, -9, -29, -14, -5, -1, -5,
- 2, 12, -6, -32, -23, -22, -16, -5, 3, -9, -29, 27, 56, 39, 11, -27,
- -28, 23, 34, 28, 18, 20, 62, 82, 71, 74, 24, -4, 16, 18, -39, -54,
- -65, -61, -52, -64, -49, -11, -4, 12, 17, 16, 25, 24, 6, 23, 36, 18,
- 18, -1, -42, -50, -90, -43, 0, 1, 6, -11, 19, -25, 24, -15, 11, -6,
- 1, 9, -6, -3, 11, -18, 28, -23, 8, 6, -2, -1, 0, -5, 18, -23,
- 24, -28, 27, -12, -1, -2, 6, 4, -14, 19, -29, 42, -40, 22, -6, -3,
- 14, -16, 4, 8, -9, 13, -22, 17, 5, -24, 37, -34, 20, -4, -11, 19,
- -20, 21, -16, 1, 17, -17, 5, -9, 25, -31, 31, -40, 32, -11, -7, 4,
- -4, 13, -23, 29, -40, 51, -49, 20, 3, -20, 38, -47, 34, -21, 14, -9,
- 4, -13, 20, -29, 37, -57, 59, -48, 23, -5, -7, 5, -6, -5, 13, -17,
- 9, -4, -12, 22, -19, -8, 10, -5, -7, 8, -18, 19, -13, 5, -12, 6,
- -10, 18, -40, 66, -91, 82, -56, 17, 19, -51, 56, -45, 30, -19, 5, -6,
- 7, -9, -4, -2, -5, 13, -19, 1, 20, -28, 13, -6, 0, -17, 33, -48,
- 38, -16, -20, 53, -75, 75, -61, 30, -12, -9, 2, 5, -9, -7, 15, -17,
- 9, 4, -46, 70, -85, 86, -67, 29, 18, -60, 76, -70, 29, -8, -1, 1,
- 14, -58, 93, -118, 127, -125, 85, -36, -2, 17, -39, 46, -61, 70, -99, 122,
- -120, 56, 15, -85, 116, -101, 30, 43, -108, 127, -122, 72, -38, -3, 20, -31,
- 29, -37, 42, -50, 63, -72, 40, -7, -46, 66, -82, 53, -25, 1, 1, -1,
- -3, 3, -24, 24, -34, 27, -24, 36, -49, 37, -38, 35, -42, 13, -4, -14,
- 14, -29, 42, -58, 58, -60, 41, -39, 27, -35, 27, -32, 25, -37, 43, -50,
- 32, -20, -4, 4, -14, 16, -43, 66, -93, 79, -58, 27, -11, -21, 34, -40,
- 24, -7, -25, 31, -29, 19, -18, -2, 1, -6, 4, -31, 47, -63, 62, -64,
- 32, 2, -29, 23, -21, 19, -41, 59, -76, 62, -52, 26, -11, -1, -10, 6,
- -10, -7, 17, -42, 34, -12, -34, 73, -106, 92, -61, 26, -24, 8, -7, -2,
- 3, -24, 31, -44, 27, -9, -22, 38, -43, 15, -4, -3, -2, -12, 5, 1,
- -7, 7, -25, 17, -17, 4, -15, 27, -40, 34, -18, 6, -13, 12, -3, -9,
- -6, 8, -18, 18, -36, 54, -55, 30, -25, 26, -41, 38, -49, 48, -38, 8,
- 16, -40, 47, -52, 34, -12, -4, 2, -13, 0, 1, 6, -11, 19, -25, 24,
- -15, 11, -6, 1, 9, -6, -3, 11, -18, 28, -23, 8, 6, -2, -1, 0,
- -5, 18, -23, 24, -28, 27, -12, -1, -2, 6, 4, -14, 19, -29, 42, -40,
- 22, -6, -3, 14, -16, 4, 8, -9, 13, -22, 17, 5, -24, 37, -34, 20,
- -4, -11, 19, -20, 21, -16, 1, 17, -17, 5, -9, 25, -31, 31, -40, 32,
- -11, -7, 4, -4, 13, -23, 29, -40, 51, -49, 20, 3, -20, 38, -47, 34,
- -21, 14, -9, 4, -13, 20, -29, 37, -57, 59, -48, 23, -5, -7, 5, -6,
- -5, 13, -17, 9, -4, -12, 22, -19, -8, 10, -5, -7, 8, -18, 19, -13,
- 5, -12, 6, -10, 18, -40, 66, -91, 82, -56, 17, 19, -51, 56, -45, 30,
- -19, 5, -6, 7, -9, -4, -2, -5, 13, -19, 1, 20, -28, 13, -6, 0,
- -17, 33, -48, 38, -16, -20, 53, -75, 75, -61, 30, -12, -9, 2, 5, -9,
- -7, 15, -17, 9, 4, -46, 70, -85, 86, -67, 29, 18, -60, 76, -70, 29,
- -8, -1, 1, 14, -58, 93, -118, 127, -125, 85, -36, -2, 17, -39, 46, -61,
- 70, -99, 122, -120, 56, 15, -85, 116, -101, 30, 43, -108, 127, -122, 72, -38,
- -3, 20, -31, 29, -37, 42, -50, 63, -72, 40, -7, -46, 66, -82, 53, -25,
- 1, 1, -1, -3, 3, -24, 24, -34, 27, -24, 36, -49, 37, -38, 35, -42,
- 13, -4, -14, 14, -29, 42, -58, 58, -60, 41, -39, 27, -35, 27, -32, 25,
- -37, 43, -50, 32, -20, -4, 4, -14, 16, -43, 66, -93, 79, -58, 27, -11,
- -21, 34, -40, 24, -7, -25, 31, -29, 19, -18, -2, 1, -6, 4, -31, 47,
- -63, 62, -64, 32, 2, -29, 23, -21, 19, -41, 59, -76, 62, -52, 26, -11,
- -1, -10, 6, -10, -7, 17, -42, 34, -12, -34, 73, -106, 92, -61, 26, -24,
- 8, -7, -2, 3, -24, 31, -44, 27, -9, -22, 38, -43, 15, -4, -3, -2,
- -12, 5, 1, -7, 7, -25, 17, -17, 4, -15, 27, -40, 34, -18, 6, -13,
- 12, -3, -9, -6, 8, -18, 18, -36, 54, -55, 30, -25, 26, -41, 38, -49,
- 48, -38, 8, 16, -40, 47, -52, 34, -12, -4, 2, -13, -1, -2, -1, -4,
- -3, -25, -41, 8, 16, 27, 2, 16, 1, 13, 21, -8, -6, -29, 17, 8,
- 8, 20, -13, 5, 4, 25, 17, 30, 22, 14, 15, 19, 7, 51, -16, -15,
- -32, -13, 12, -8, -17, -49, -27, -29, -29, -52, -66, -55, -32, -20, -41, -21,
- -36, -11, -16, 22, 3, 19, 0, -6, -10, 0, -38, -17, -35, -19, -27, 0,
- -35, -27, -9, -17, -14, -2, 20, 50, 63, 57, 49, 70, 70, 97, 81, 68,
- 52, 78, 93, 98, 102, 56, 34, 20, 53, 60, 45, 24, -18, 21, -10, 0,
- -38, -79, -38, -37, -13, -27, -41, -50, -51, 14, 10, 16, -21, -13, -22, -20,
- -48, -53, -55, -66, -76, -65, -91, -105, -92, -87, -101, -79, -56, -34, -7, -4,
- 7, 20, 15, 26, 29, 32, -8, 36, 47, 50, 66, 29, 18, -33, -11, -4,
- -10, -24, -42, -31, -22, 2, -23, -75, -34, -36, 5, 1, 1, -17, -47, 20,
- 43, 68, 28, 30, 9, 29, 7, -9, -5, -32, -46, -36, -15, -40, -35, -15,
- -26, -21, 2, 21, 49, 62, 83, 87, 106, 77, 97, 94, 67, 60, 85, 79,
- 110, 80, 61, 1, 8, 16, 50, 36, 2, -22, 4, -2, 21, -35, -33, -19,
- 4, 24, 19, 10, -58, -23, 18, 45, 34, 8, -12, -6, -5, -48, -51, -75,
- -72, -77, -37, -65, -80, -57, -66, -68, -38, -38, 2, 10, 38, 31, 58, 22,
- 39, 37, 27, -9, 23, 9, 35, 18, 15, -31, -50, -44, -5, 6, -10, -63,
- -41, -56, -15, -41, -71, -45, -37, 7, -6, 5, -56, -71, -6, 21, 41, 8,
- -13, -14, -40, -30, -41, -40, -56, -31, -31, -9, -15, -5, 10, 42, 27, 73,
- 82, 73, 73, 79, 70, 38, 28, 31, 23, 45, 42, 44, 30, -40, 8, 28,
- 52, 30, -18, -29, -40, -14, -45, -50, -55, -68, -39, -6, -29, -45, -59, -32,
- 4, 31, 23, 16, 20, 11, -1, 1, -28, -45, -53, -56, -67, -60, -55, -40,
- -31, -25, -16, 11, 20, 36, 67, 70, 75, 77, 81, 65, 46, 38, 34, 39,
- 51, 44, 57, 7, -4, 13, 37, 46, 19, -8, -29, -1, -9, -21, -32, -43,
- -55, -58, -40, -8, 15, 29, 38, 44, 59, 63, 51, 20, -20, -47, -61, -58,
- -48, -42, -43, -35, -15, 15, 41, 55, 61, 62, 70, 67, 45, 11, -31, -62,
- -80, -78, -71, -62, -54, -39, -15, 18, 50, 68, 79, 83, 92, 88, 57, 16,
- -31, -71, -94, -95, -90, -83, -71, -55, -28, 7, 49, 77, 93, 100, 109, 107,
- 78, 36, -20, -71, -99, -104, -100, -92, -83, -69, -43, -5, 42, 79, 100, 108,
- 114, 112, 90, 51, -9, -65, -100, -110, -105, -95, -87, -76, -52, -11, 35, 75,
- 100, 107, 111, 106, 90, 52, -4, -60, -97, -109, -99, -87, -80, -65, -35, 5,
- 43, 75, 91, 95, 93, 87, 71, 31, -19, -64, -93, -99, -88, -76, -66, -44,
- -9, 28, 59, 79, 84, 80, 71, 59, 35, -5, -45, -76, -96, -95, -77, -59,
- -39, -9, 28, 61, 86, 98, 93, 74, 52, 28, -6, -43, -72, -94, -108, -99,
- -77, -52, -20, 19, 56, 84, 106, 115, 106, 79, 45, 3, -40, -74, -93, -108,
- -112, -100, -79, -46, -1, 45, 78, 100, 113, 118, 108, 81, 39, -19, -67, -93,
- -103, -108, -104, -94, -74, -32, 19, 61, 88, 102, 108, 109, 100, 73, 21, -44,
- -87, -102, -104, -97, -90, -78, -49, 0, 46, 78, 90, 92, 89, 87, 77, 43,
- -15, -72, -101, -104, -93, -79, -69, -47, -3, 47, 84, 96, 89, 74, 65, 58,
- 37, -7, -61, -99, -110, -101, -82, -62, -38, 2, 49, 92, 112, 106, 82, 59,
- 41, 18, -19, -61, -95, -111, -110, -98, -74, -39, 6, 54, 99, 122, 123, 104,
- 79, 50, 12, -32, -72, -100, -111, -110, -106, -90, -54, -4, 49, 99, 123, 126,
- 113, 95, 69, 24, -27, -72, -102, -114, -109, -104, -94, -64, -16, 36, 87, 116,
- 121, 111, 97, 76, 36, -15, -61, -94, -110, -108, -98, -86, -60, -19, 29, 77,
- 104, 109, 99, 86, 67, 35, -7, -47, -82, -98, -101, -92, -77, -48, -14, 25,
- 67, 92, 95, 83, 66, 45, 18, -9, -37, -62, -77, -81, -78, -54, -16, 0,
- 0, 0, 12, -10, 16, -14, -18, 17, -31, -2, 3, -19, -8, 17, 28, 37,
- 31, -1, -25, -16, -47, -13, -43, -22, 6, 34, 41, 49, 41, 27, 6, -33,
- -62, -54, -59, -32, -13, 29, 53, 73, 60, 54, 16, -19, -58, -77, -89, -42,
- -46, 17, 55, 78, 86, 81, 33, -3, -35, -84, -110, -75, -70, 0, 39, 78,
- 92, 105, 70, 13, -15, -82, -107, -103, -84, -41, 20, 81, 85, 127, 86, 39,
- -4, -63, -103, -99, -107, -69, 2, 68, 82, 127, 84, 58, 28, -44, -88, -104,
- -108, -83, -13, 29, 69, 116, 87, 77, 40, -16, -65, -89, -104, -89, -40, -1,
- 47, 96, 90, 85, 52, 9, -38, -62, -96, -95, -62, -22, 21, 73, 78, 86,
- 65, 35, -15, -41, -80, -92, -69, -48, 1, 43, 65, 80, 73, 49, 8, -23,
- -59, -75, -74, -60, -22, 17, 49, 69, 65, 60, 25, -1, -36, -59, -70, -61,
- -40, -9, 30, 52, 57, 63, 37, 17, -12, -41, -61, -57, -50, -30, 9, 30,
- 49, 60, 47, 28, 6, -20, -49, -51, -53, -42, -11, 13, 34, 53, 50, 34,
- 18, -3, -35, -39, -52, -49, -23, 0, 18, 41, 47, 36, 31, 10, -21, -28,
- -43, -49, -31, -13, 2, 28, 39, 35, 38, 19, -7, -18, -33, -42, -36, -26,
- -12, 19, 30, 34, 36, 22, 6, -5, -25, -38, -36, -29, -17, 8, 19, 26,
- 35, 28, 12, 3, -17, -30, -29, -29, -22, -3, 9, 19, 33, 26, 14, 8,
- -9, -18, -22, -28, -25, -9, 3, 15, 22, 20, 18, 12, 1, -11, -22, -24,
- -21, -13, -3, 8, 11, 20, 21, 12, 5, -6, -19, -16, -17, -17, -7, 3,
- 8, 20, 17, 7, 7, -2, -11, -13, -16, -17, -5, 2, 5, 12, 13, 8,
- 6, 3, -9, -11, -9, -14, -5, 1, -3, 6, 11, 6, 7, 2, -6, -4,
- -4, -10, -6, -3, -4, 5, 8, 2, 5, 4, -2, 0, -3, -9, -4, -3,
- -3, 2, 3, 0, 6, 4, 0, -1, -2, -2, 0, 0, 0, 12, -10, 16,
- -14, -18, 17, -31, -2, 3, -19, -8, 17, 28, 37, 31, -1, -25, -16, -47,
- -13, -43, -22, 6, 34, 41, 49, 41, 27, 6, -33, -62, -54, -59, -32, -13,
- 29, 53, 73, 60, 54, 16, -19, -58, -77, -89, -42, -46, 17, 55, 78, 86,
- 81, 33, -3, -35, -84, -110, -75, -70, 0, 39, 78, 92, 105, 70, 13, -15,
- -82, -107, -103, -84, -41, 20, 81, 85, 127, 86, 39, -4, -63, -103, -99, -107,
- -69, 2, 68, 82, 127, 84, 58, 28, -44, -88, -104, -108, -83, -13, 29, 69,
- 116, 87, 77, 40, -16, -65, -89, -104, -89, -40, -1, 47, 96, 90, 85, 52,
- 9, -38, -62, -96, -95, -62, -22, 21, 73, 78, 86, 65, 35, -15, -41, -80,
- -92, -69, -48, 1, 43, 65, 80, 73, 49, 8, -23, -59, -75, -74, -60, -22,
- 17, 49, 69, 65, 60, 25, -1, -36, -59, -70, -61, -40, -9, 30, 52, 57,
- 63, 37, 17, -12, -41, -61, -57, -50, -30, 9, 30, 49, 60, 47, 28, 6,
- -20, -49, -51, -53, -42, -11, 13, 34, 53, 50, 34, 18, -3, -35, -39, -52,
- -49, -23, 0, 18, 41, 47, 36, 31, 10, -21, -28, -43, -49, -31, -13, 2,
- 28, 39, 35, 38, 19, -7, -18, -33, -42, -36, -26, -12, 19, 30, 34, 36,
- 22, 6, -5, -25, -38, -36, -29, -17, 8, 19, 26, 35, 28, 12, 3, -17,
- -30, -29, -29, -22, -3, 9, 19, 33, 26, 14, 8, -9, -18, -22, -28, -25,
- -9, 3, 15, 22, 20, 18, 12, 1, -11, -22, -24, -21, -13, -3, 8, 11,
- 20, 21, 12, 5, -6, -19, -16, -17, -17, -7, 3, 8, 20, 17, 7, 7,
- -2, -11, -13, -16, -17, -5, 2, 5, 12, 13, 8, 6, 3, -9, -11, -9,
- -14, -5, 1, -3, 6, 11, 6, 7, 2, -6, -4, -4, -10, -6, -3, -4,
- 5, 8, 2, 5, 4, -2, 0, -3, -9, -4, -3, -3, 2, 3, 0, 6,
- 4, 0, -1, -2, -2, 0, -1, -1, -3, -7, -14, -23, -32, -45, -55, -66,
- -74, -83, -88, -80, -77, -71, -64, -54, -46, -37, -31, -25, -19, -12, -6, -1,
- 4, 8, 12, 17, 21, 23, 25, 25, 27, 29, 32, 35, 36, 34, 32, 31,
- 32, 35, 37, 37, 35, 31, 29, 29, 31, 33, 34, 32, 29, 26, 25, 27,
- 30, 32, 31, 29, 27, 27, 29, 31, 34, 35, 35, 35, 36, 38, 41, 43,
- 45, 47, 49, 52, 55, 57, 59, 61, 63, 66, 69, 70, 70, 68, 66, 63,
- 61, 58, 54, 47, 36, 24, 11, 1, -9, -20, -33, -48, -64, -78, -89, -97,
- -103, -110, -116, -123, -128, -128, -126, -121, -116, -112, -107, -102, -95, -88, -78, -69,
- -61, -54, -47, -41, -34, -27, -21, -16, -12, -7, -2, 2, 5, 6, 8, 10,
- 13, 16, 19, 19, 19, 17, 18, 19, 22, 24, 24, 22, 19, 18, 19, 21,
- 23, 24, 22, 19, 17, 18, 20, 22, 24, 24, 22, 21, 22, 24, 27, 29,
- 30, 30, 31, 32, 35, 37, 40, 42, 45, 47, 50, 53, 56, 58, 60, 62,
- 66, 68, 70, 69, 68, 65, 63, 61, 59, 54, 46, 36, 24, 13, -1, -14,
- -28, -43, -57, -68, -78, -86, -94, -102, -109, -114, -117, -117, -115, -112, -109, -106,
- -101, -96, -89, -81, -73, -67, -59, -53, -46, -40, -34, -28, -23, -18, -13, -9,
- -5, -2, 0, 2, 5, 7, 10, 12, 14, 15, 15, 15, 16, 18, 19, 20,
- 20, 19, 18, 18, 19, 21, 22, 22, 21, 20, 19, 21, 23, 24, 25, 25,
- 25, 25, 26, 29, 31, 33, 34, 35, 36, 38, 40, 43, 46, 48, 51, 53,
- 56, 59, 62, 65, 68, 71, 74, 77, 78, 79, 78, 77, 76, 74, 71, 66,
- 58, 49, 39, 28, 17, 6, -6, -20, -35, -50, -64, -75, -85, -94, -102, -110,
- -117, -122, -124, -123, -121, -118, -114, -110, -106, -99, -92, -84, -76, -69, -61, -55,
- -48, -41, -34, -29, -23, -18, -13, -9, -5, -2, 0, -1, -1, 0, 2, 0,
- 3, 2, 2, 4, 5, 4, 4, 4, 4, 5, 3, 4, 3, 1, 2, 0,
- 0, -1, -3, -4, -2, -3, -5, -3, -4, -5, -5, -4, -3, -3, -6, -5,
- -4, -2, -5, -5, -2, -3, -3, -3, 1, 4, 4, 8, 8, 8, 13, 12,
- 13, 14, 12, 9, 8, 6, 6, 3, -2, -2, -5, -5, -4, -5, -11, -16,
- -12, -7, -3, -5, -10, -11, -6, -2, -2, -1, -4, -6, -6, -7, -8, -5,
- -2, 2, 5, 6, 8, 8, 9, 13, 16, 16, 14, 11, 7, 5, 4, 2,
- 0, -2, -3, -3, 0, -3, -13, -28, -11, 7, -1, -15, -1, -5, -18, -10,
- 6, 11, -11, -1, -10, -14, -13, -13, -4, 4, 6, 14, 13, 10, 10, 15,
- 17, 24, 24, 13, 12, 10, 1, 0, 2, -4, 0, -6, 2, 7, -22, -68,
- 2, 35, -40, 14, -24, -3, -10, -9, -20, -3, 28, 2, -9, -12, -28, -19,
- -4, -1, 15, 17, 17, 16, 12, 16, 22, 25, 28, 6, 17, 9, -1, -2,
- -3, 2, 12, -6, 6, -5, -35, -89, 32, 28, -39, 20, -36, 9, -20, -9,
- -34, 3, 34, 8, -16, -11, -37, -15, -3, 0, 26, 18, 13, 15, 13, 25,
- 27, 29, 20, 3, 21, 2, -2, 0, -8, 11, 16, -1, 8, -21, -76, -81,
- 87, -25, 4, -4, -23, 6, -26, -20, -35, 23, 28, 0, -18, -16, -43, 2,
- -9, 17, 25, 15, 9, 18, 17, 37, 28, 35, 3, 14, 12, -5, -1, -1,
- -5, 27, 0, 16, -11, -49, -128, 36, 40, -36, 35, -41, 21, -27, -14, -45,
- 4, 24, 20, -23, -6, -41, -9, -1, 6, 23, 19, 5, 15, 14, 33, 35,
- 40, 16, 5, 16, -3, -5, 4, -12, 24, 10, 18, 1, -38, -128, -21, 72,
- -50, 42, -38, 19, -16, -16, -43, -10, 21, 24, -22, -11, -30, -15, 6, 4,
- 22, 18, 6, 11, 13, 27, 39, 42, 22, 4, -3, -2, -2, -5, -3, -5,
- -3, -2, -6, -5, -5, -6, -5, -3, -5, -3, -5, -4, -6, -3, -1, -2,
- -1, 0, -2, 1, 2, 1, 4, 4, 5, 5, 5, 8, 10, 11, 9, 10,
- 11, 8, 5, 10, 7, 5, 5, 0, -3, 1, 0, -5, -2, -8, -9, -7,
- -7, -5, -9, -11, -9, -8, -8, -7, -9, -7, -6, -7, -5, -6, -5, -3,
- -3, -3, -4, -4, -2, 0, 1, 2, 5, 9, 12, 16, 19, 22, 22, 24,
- 22, 22, 19, 13, 11, 7, 7, 4, -2, -7, -9, -9, -8, -10, -14, -14,
- -15, -15, -13, -14, -17, -18, -14, -12, -12, -8, -9, -7, -6, -6, -6, -8,
- -9, -9, -11, -13, -11, -6, -1, 3, 9, 20, 27, 33, 37, 46, 46, 42,
- 37, 28, 21, 14, 11, 10, 14, 20, -2, -40, -47, -22, -5, -4, -1, 4,
- -15, -53, -56, -7, -33, -14, -2, -19, -7, -8, -15, -6, -9, -8, -3, -9,
- -15, -18, -26, -19, -6, -5, -6, 0, 12, 22, 29, 30, 28, 32, 29, 21,
- 15, 13, 5, 5, 3, 19, 30, 3, -68, -26, 2, -17, 17, -12, 15, -1,
- -12, -48, -43, -19, -1, 3, 6, -8, -4, -10, -10, -4, 0, -6, -1, -7,
- -9, -17, -12, -6, -9, -14, -5, 14, 33, 33, 41, 32, 41, 35, 20, 10,
- 8, 4, 10, -2, 36, 40, 3, -110, -8, -7, -6, 16, -18, 27, -2, -4,
- -56, -57, -33, 16, -2, 12, -11, -5, -17, -9, -5, 10, -6, 0, -12, -11,
- -20, -10, -8, -12, -17, -3, 17, 38, 34, 45, 36, 51, 37, 18, 4, -3,
- 3, 8, 8, 54, 48, -34, -128, 28, -33, 28, -13, 1, 21, 3, -20, -59,
- -65, -10, 17, -1, 7, -17, -10, -19, -8, 5, 11, -4, -2, -16, -17, -20,
- -9, -11, -18, -11, 3, 31, 36, 41, 41, 44, 53, 30, 10, 1, -13, 12,
- -5, 42, 63, 43, -127, -55, 19, -27, 28, -1, 0, 3, 5, 8, 12, 14,
- 15, 15, 14, 12, 8, 5, 1, -3, -9, -14, -17, -19, -18, -16, -12, -8,
- -5, -4, -2, -1, -1, -2, -3, -4, -3, -2, -1, -1, 0, 0, 0, 2,
- 8, 12, 16, 19, 23, 26, 34, 40, 39, 28, 11, -8, -26, -36, -40, -39,
- -35, -27, -19, -10, -5, -6, -10, -12, -15, -14, -12, -9, -5, -3, -1, 1,
- 6, 8, 7, 7, 7, 8, 13, 20, 28, 35, 43, 48, 55, 57, 51, 32,
- 3, -29, -56, -68, -67, -60, -46, -31, -17, -7, -4, -7, -11, -15, -16, -15,
- -10, -5, -1, 1, 3, 5, 7, 9, 11, 12, 12, 10, 13, 19, 26, 36,
- 43, 51, 58, 65, 61, 40, 6, -30, -60, -75, -73, -64, -49, -32, -16, -5,
- -1, -4, -11, -18, -23, -23, -19, -12, -5, 2, 8, 12, 13, 11, 9, 8,
- 8, 10, 15, 21, 27, 32, 37, 42, 49, 55, 63, 55, 32, -3, -39, -66,
- -79, -73, -56, -39, -24, -12, -7, -7, -12, -19, -24, -24, -21, -14, -6, 3,
- 8, 11, 12, 11, 10, 10, 10, 11, 14, 17, 21, 27, 33, 41, 49, 56,
- 63, 66, 49, 15, -27, -61, -82, -85, -73, -52, -33, -18, -9, -5, -7, -12,
- -18, -21, -20, -15, -9, -1, 4, 8, 12, 15, 15, 14, 11, 8, 7, 10,
- 15, 22, 32, 45, 59, 72, 86, 95, 75, 22, -40, -93, -119, -120, -97, -64,
- -32, -9, 5, 9, 5, -3, -14, -21, -23, -20, -13, -5, 4, 12, 17, 18,
- 15, 10, 7, 4, 3, 6, 9, 15, 21, 30, 40, 56, 77, 99, 99, 54,
- -19, -86, -123, -127, -103, -66, -27, 1, 16, 18, 11, -1, -12, -21, -23, -21,
- -16, -8, 1, 9, 16, 19, 16, 11, 8, 5, 5, 7, 9, 14, 19, 27,
- 35, 49, 68, 90, 101, 73, 6, -66, -114, -128, -113, -78, -39, -6, 13, 19,
- 11, -1, 0, 10, 30, 35, 40, 39, 37, 28, 18, 6, -9, -20, -30, -35,
- -33, -30, -28, -23, -24, -23, -19, -20, -15, -11, -8, -3, 0, 1, 0, -2,
- -4, -1, 0, 10, 15, 21, 27, 25, 25, 22, 13, 10, -5, -9, -15, -19,
- -17, -17, -12, -7, 0, 4, 10, 8, 5, -5, -13, -23, -31, -30, -24, -13,
- 11, 36, 62, 81, 83, 78, 54, 35, 19, -11, -29, -49, -57, -47, -35, -20,
- -19, -26, -27, -33, -30, -26, -22, -11, -8, 3, 11, 6, 0, -16, -23, -23,
- -11, 9, 23, 35, 45, 51, 46, 49, 26, 12, -13, -26, -37, -45, -31, -35,
- -17, -4, 8, 23, 24, 23, 9, -10, -22, -37, -40, -38, -33, -12, 22, 67,
- 100, 119, 111, 79, 50, 10, -12, -32, -52, -69, -62, -38, -14, -9, -21, -42,
- -60, -50, -39, -19, -4, -1, 3, 15, 19, 2, -16, -43, -57, -48, -21, 19,
- 38, 63, 66, 69, 74, 59, 39, 4, -33, -52, -67, -58, -39, -25, 2, 10,
- 32, 35, 36, 18, -7, -25, -37, -31, -28, -23, -10, 11, 53, 101, 121, 123,
- 92, 48, 11, -24, -42, -60, -66, -67, -48, -20, 2, -16, -41, -67, -87, -62,
- -44, -10, 8, 19, 30, 34, 35, 4, -36, -66, -78, -75, -27, 22, 49, 83,
- 91, 97, 90, 69, 39, -18, -61, -104, -98, -75, -32, 19, 47, 68, 70, 56,
- 16, -33, -77, -89, -76, -47, 7, 35, 64, 100, 123, 125, 107, 60, 5, -39,
- -76, -94, -101, -93, -69, -36, -3, 17, 10, -15, -56, -80, -86, -69, -40, -7,
- 25, 49, 66, 72, 54, 19, -19, -55, -77, -67, -40, 4, 45, 76, 96, 100,
- 92, 67, 32, -11, -56, -88, -91, -73, -33, 9, 41, 61, 65, 52, 17, -28,
- -67, -80, -68, -36, 6, 47, 82, 114, 126, 114, 74, 18, -32, -73, -93, -101,
- -93, -70, -36, -3, 17, 10, -15, 0, -1, -2, -2, 0, 2, 3, 6, 7,
- 6, 6, 3, 2, -1, -4, -8, -12, -14, -13, -13, -11, -5, -1, 5, 10,
- 14, 17, 19, 18, 15, 12, 7, 3, 1, -2, -4, -4, -7, -11, -13, -16,
- -16, -12, -9, -6, -3, -1, -1, -1, -4, -8, -11, -15, -16, -15, -10, -2,
- 7, 18, 25, 28, 28, 24, 16, 10, 4, -2, -5, -5, -4, -4, -1, 0,
- 0, 1, 1, 0, -1, -3, -6, -11, -11, -14, -16, -17, -19, -19, -16, -10,
- -2, 8, 19, 27, 33, 35, 32, 26, 21, 14, 7, 0, -6, -11, -18, -25,
- -31, -32, -27, -19, -9, 1, 10, 15, 14, 10, 0, -13, -28, -38, -42, -40,
- -26, -4, 17, 40, 58, 66, 62, 51, 35, 17, 3, -8, -16, -18, -18, -15,
- -13, -15, -17, -17, -15, -13, -11, -12, -3, -2, 1, -3, -15, -28, -36, -42,
- -40, -28, -11, 14, 45, 63, 70, 69, 56, 44, 36, 21, 3, -12, -18, -26,
- -37, -47, -58, -55, -41, -20, 4, 22, 34, 43, 37, 22, -7, -43, -71, -88,
- -86, -64, -31, 7, 56, 99, 115, 106, 85, 48, 17, 1, -14, -28, -33, -20,
- -11, -12, -18, -37, -44, -41, -29, -23, -7, 15, 31, 40, 33, 8, -27, -56,
- -73, -74, -63, -33, 4, 50, 93, 101, 91, 79, 56, 43, 24, 5, -17, -32,
- -31, -43, -56, -63, -72, -57, -32, 3, 26, 46, 62, 63, 45, 9, -39, -85,
- -112, -106, -84, -49, 6, 60, 104, 127, 115, 83, 46, 16, -1, -16, -21, -26,
- -16, -2, -8, -25, -47, -67, -62, -49, -26, 2, 34, 60, 74, 65, 33, -21,
- -71, -98, -92, -77, -36, 21, 69, 106, 112, 88, 58, 29, 9, -8, -18, -24,
- -17, -4, -10, -26, -47, -67, -62, -49, -26, 2, 34, 60, 74, 65, 33, 17,
- 16, -38, 9, 40, -58, 27, 43, -80, 52, -2, -54, 64, -27, -17, 32, 4,
- -49, 53, -22, -47, 90, -73, 17, 42, -45, 8, 23, -41, -1, 58, -74, 40,
- 25, -66, 56, -19, -45, 58, -9, -39, 45, 3, -48, 55, -41, -27, 78, -66,
- 13, 40, -38, 0, 29, -51, 12, 57, -79, 38, 31, -64, 40, -4, -47, 63,
- -16, -40, 55, -16, -32, 45, -31, -29, 76, -64, 0, 58, -49, 4, 31, -52,
- 31, 5, -35, 45, -21, 4, -5, 3, -17, -7, 55, -72, 43, 35, -88, 80,
- -57, 3, 45, -62, 53, -14, -2, -17, 46, -77, 42, 23, -61, 75, -54, 39,
- -40, 31, -42, 25, 11, -48, 93, -97, 62, -27, -13, 7, 0, 30, -59, 82,
- -74, 28, 10, -53, 65, -47, 46, -41, 40, -48, 7, 45, -95, 127, -99, 43,
- -9, -25, 40, -58, 84, -84, 78, -66, 11, 50, -96, 111, -85, 51, -26, -14,
- 36, -60, 91, -84, 58, -26, -22, 56, -87, 98, -71, 47, -25, -11, 44, -84,
- 103, -92, 69, -32, -3, 25, -59, 87, -90, 70, -45, 17, 16, -57, 81, -73,
- 50, -33, 14, 0, -35, 75, -84, 69, -42, 8, 11, -46, 74, -69, 57, -47,
- 36, -26, -20, 69, -89, 83, -58, 37, -24, -7, 41, -58, 54, -53, 53, -42,
- 14, 28, -54, 52, -55, 46, -41, 22, 30, -57, 58, -64, 56, -54, 26, 31,
- -55, 63, -73, 66, -68, 49, -3, -38, 61, -71, 75, -87, 69, -15, -27, 37,
- -55, 74, -84, 73, -34, -5, 26, -59, 74, -85, 84, -33, -12, 30, -57, 65,
- -85, 86, -40, 9, 15, -50, 69, -94, 93, -53, 15, 11, -38, 58, -86, 96,
- -64, 11, 21, -30, 17, -3, -3, 0, 0, -3, -4, -4, -3, -4, -4, -5,
- -6, -6, -8, -5, -6, -3, 0, 2, 4, 7, 8, 12, 12, 14, 13, 13,
- 12, 8, 7, 2, 2, -4, -6, -10, -11, -12, -12, -14, -10, -9, -3, -3,
- 2, 3, 3, 2, 1, 1, -3, -3, -4, -3, -3, -3, -4, 0, -3, -3,
- -3, 0, -3, 0, -3, 0, 1, 0, 0, 0, 0, 0, -3, 1, -3, 1,
- -3, 2, 1, 0, 0, -3, -4, -5, -9, -10, -15, -16, -17, -17, -14, -10,
- -3, 4, 9, 14, 19, 24, 25, 26, 28, 30, 34, 42, 31, 9, -31, -39,
- -23, -15, -17, -23, -30, -23, -12, -10, 4, 9, 19, 13, 14, 6, 0, -9,
- -11, -12, -9, -8, 0, 0, 2, 1, 1, -3, -3, -5, -3, -5, -3, -4,
- 0, -3, -4, -4, -3, -5, -3, -5, -3, 0, 3, 2, 7, 7, 7, 3,
- 0, -14, -17, -26, -26, -28, -21, -17, -11, -10, 2, 6, 19, 18, 32, 32,
- 60, 69, 98, 60, 7, -58, -8, -8, -14, -39, -30, -14, -47, -21, -45, -3,
- 7, 20, 14, 31, 12, 10, -15, -5, -23, -14, -15, -4, -8, 2, 1, 7,
- -3, 2, -8, -4, -6, -6, -3, 0, -6, -6, -8, -10, -11, -12, -9, -9,
- -4, -3, 0, 8, 10, 12, 15, 13, 4, -10, -15, -30, -32, -30, -23, -22,
- -19, -14, -4, 3, 10, 14, 26, 40, 70, 102, 127, 62, -17, -39, 9, -25,
- -9, -87, -12, -16, 0, -30, -27, -19, -9, 6, 18, 21, 19, 6, 0, -9,
- -17, -14, -16, -8, -6, 0, 4, 4, -5, -4, -11, -3, -6, 2, 2, 0,
- -6, 0, -2, -4, -8, -14, -21, -25, -28, -32, -36, -40, -44, -48, -51, -55,
- -59, -63, -67, -71, -74, -78, -82, -86, -90, -94, -98, -101, -84, -60, -38, -15,
- 8, 28, 27, 23, 19, 16, 11, 21, 46, 68, 93, 109, 106, 102, 98, 95,
- 91, 87, 83, 79, 75, 71, 67, 64, 60, 56, 52, 49, 45, 41, 37, 33,
- 30, 26, 22, 18, 15, 11, 7, 3, -1, -5, -9, -13, -17, -20, -24, -28,
- -32, -35, -39, -43, -47, -51, -54, -58, -62, -66, -69, -73, -77, -81, -85, -89,
- -93, -97, -100, -105, -95, -70, -48, -23, -7, -10, -14, -17, -22, -18, 4, 26,
- 50, 72, 96, 107, 103, 100, 96, 92, 88, 84, 80, 76, 72, 68, 64, 61,
- 57, 53, 49, 46, 42, 38, 34, 30, 26, 23, 19, 15, 11, 8, 4, 0,
- -4, -8, -11, -15, -19, -23, -27, -30, -35, -38, -43, -46, -51, -54, -58, -61,
- -66, -56, -31, -9, 16, 33, 30, 26, 22, 18, 15, 11, 7, 3, -1, -5,
- -9, -13, -16, -20, -24, -28, -32, -36, -40, -43, -48, -51, -55, -59, -63, -50,
- -26, -4, 20, 42, 64, 67, 62, 59, 55, 51, 47, 43, 39, 35, 31, 27,
- 23, 20, 16, 12, 8, 4, 0, -4, -7, -11, -15, -19, -22, -27, -17, 8,
- 30, 55, 72, 69, 65, 61, 57, 54, 50, 46, 42, 38, 34, 30, 26, 22,
- 18, 15, 11, 7, 3, 0, -4, -8, -12, -15, -19, -23, -27, -31, -35, -38,
- -42, -46, -50, -54, -57, -61, -65, -69, -73, -77, -81, -85, -89, -92, -96, -100,
- -100, -79, -64, -47, -31, -15, 0, 0, -4, -3, -6, -8, 6, 10, -8, -13,
- 22, 55, 15, -58, -102, -88, -25, 51, 77, 79, 82, 19, -45, -107, -128, -88,
- 19, 81, 86, 71, 35, -16, -50, -73, -55, -27, -14, 7, 77, 89, 31, -22,
- -27, -61, -86, -34, 40, 55, 67, 80, 57, -1, -48, -60, -41, -46, -31, 28,
- 62, 47, 43, 33, -5, -34, -45, -52, -33, 26, 66, 70, 41, 17, -34, -79,
- -93, -41, -6, 22, 53, 93, 62, 17, -20, -66, -118, -88, -4, 45, 60, 69,
- 67, 2, -72, -109, -95, -78, -7, 67, 101, 78, 69, 19, -56, -110, -89, -64,
- -19, 45, 100, 86, 36, -11, -65, -107, -108, -41, 24, 69, 93, 111, 56, -15,
- -70, -81, -88, -38, 30, 88, 90, 83, 43, -24, -81, -82, -57, -24, 38, 100,
- 115, 70, 26, -25, -75, -108, -66, -20, 29, 71, 105, 67, 7, -46, -67, -83,
- -60, 0, 58, 82, 81, 57, -9, -72, -99, -78, -60, -8, 54, 95, 69, 44,
- 0, -51, -92, -69, -26, 18, 53, 81, 63, 6, -44, -74, -88, -79, -19, 40,
- 75, 75, 72, 18, -42, -80, -74, -69, -25, 32, 76, 66, 39, 5, -41, -82,
- -76, -34, 3, 42, 79, 88, 38, -12, -49, -74, -92, -48, 8, 51, 70, 83,
- 50, -7, -58, -68, -65, -43, 13, 70, 82, 62, 34, -17, -72, -94, -65, -28,
- 17, 69, 101, 71, 25, -21, -60, -88, -66, -13, 37, 62, 82, 68, 11, -47,
- -73, -79, -66, -15, 49, 82, 76, 57, 11, -51, -88, -78, -48, -9, 49, 0,
- 0, 0, 0, 0, 0, -3, -5, -5, -7, -6, -2, 5, 16, 24, 21, 17,
- 12, 3, -10, -31, -44, -47, -42, -28, -2, 26, 29, 36, 35, 1, -26, -39,
- -52, -53, -38, -10, -32, -41, -7, 2, 22, 65, 89, 74, 15, -16, -24, 12,
- 62, 39, 6, -12, -3, 47, 48, 21, 109, 127, 119, 53, -9, 19, 9, -50,
- -55, -43, -71, -46, -5, -2, -20, -12, -9, 12, -27, -66, -50, -8, -19, -58,
- -22, -8, -19, -34, -42, 10, 32, -4, 4, 46, 96, 34, -51, -10, -8, -93,
- -70, -58, -46, -16, -32, -30, 6, 7, -41, -29, 3, 25, 73, 67, 45, 37,
- 30, 83, 0, -31, -4, -50, -28, -41, -75, -110, -53, -13, -3, 22, 14, 14,
- 13, 7, 9, 38, 47, 39, 17, -8, 90, 75, -5, -29, -46, -54, -102, -66,
- -35, -27, -29, -21, 32, 5, 1, 1, -2, 16, 16, 19, 30, 50, 89, 41,
- 6, 40, -10, -15, -41, -46, -43, -77, -100, -100, -48, -37, -26, -4, -9, 0,
- 13, 36, 70, 75, 59, 34, 12, -13, -27, 37, 71, 48, 53, 37, 7, 8,
- 34, 48, 40, 31, 25, 2, -20, -15, -5, 12, -11, -49, -20, 15, -13, -42,
- -29, 16, -6, -58, -28, 17, 12, -20, -11, 16, -3, -37, -14, 3, -32, -10,
- 40, 54, 53, 27, -3, -5, -34, -47, -49, -90, -68, -36, -32, -31, -16, 26,
- 3, 0, -2, -2, 15, 16, 19, 30, 51, 88, 40, 6, 39, -10, 3, -2,
- 11, -7, 23, 19, 74, 39, 32, -13, -21, -7, -39, -44, -128, -58, -21, 52,
- -86, -74, -94, 75, 61, 72, -38, 13, 59, 116, 71, -9, -33, -12, 68, -2,
- -35, -128, -42, -43, 39, -78, -57, -81, 56, 59, 63, -13, 7, 69, 98, 87,
- -13, -9, -24, 70, -11, -23, -128, -42, -48, 28, -68, -61, -69, 34, 64, 46,
- 8, -5, 79, 82, 100, -17, 5, -29, 69, -13, -21, -122, -49, -43, 11, -55,
- -72, -54, 13, 73, 30, 23, -16, 87, 72, 107, -17, 10, -26, 64, -6, -26,
- -109, -61, -31, -6, -40, -86, -41, -4, 80, 17, 31, -22, 88, 70, 106, -10,
- 6, -16, 53, 7, -37, -93, -76, -17, -21, -28, -99, -33, -15, 83, 12, 31,
- -21, 83, 76, 98, 2, -4, -1, 41, 24, -49, -77, -89, -6, -31, -20, -106,
- -32, -19, 79, 14, 23, -15, 71, 87, 87, 17, -16, 13, 30, 39, -57, -67,
- -97, -1, -34, -19, -106, -38, -16, 69, 23, 11, -5, 56, 100, 75, 32, -28,
- 25, 22, 50, -59, -62, -98, -2, -30, -24, -100, -52, -9, 55, 36, -4, 5,
- 41, 112, 67, 43, -34, 30, 21, 55, -53, -65, -93, -11, -18, -34, -88, -69,
- 0, 41, 48, -17, 12, 29, 118, 65, 49, -34, 28, 27, 53, -42, -72, -83,
- -23, -6, -44, -77, -85, 5, -69, 1, -12, -29, -28, -13, 1, 9, -4, -27,
- -18, -5, 11, 65, 87, 54, 59, 66, 30, 12, 8, -6, -7, 4, -7, -39,
- -59, -63, -48, -23, -13, -6, 22, 61, 68, 15, -59, -87, -41, 3, 5, -10,
- -17, -17, -20, -23, -20, -28, -17, -3, -10, -29, 23, 11, 25, 52, 56, 62,
- 80, 54, 22, -15, -31, -38, -5, 11, -9, -7, -36, -44, -6, 52, 127, 26,
- -68, -125, -105, 22, 15, -27, -27, 13, 25, 69, 28, -42, -77, -57, -70, 15,
- 44, 14, 26, 57, 69, 43, 33, 41, 33, 32, 25, -50, -98, -100, -38, 24,
- 7, -35, -38, -2, 76, 64, 15, -79, -93, -50, -12, 27, 45, 32, -4, 23,
- 6, -36, -47, -33, -52, -15, 37, 78, 49, 40, 17, 14, 14, 70, 81, 60,
- -3, -4, -12, -42, -50, -28, -20, 5, 9, 27, 46, -13, -69, -99, -88, -47,
- 5, -4, -10, 17, 39, -12, -8, -21, -16, 22, 9, -9, 1, 15, 15, 33,
- 29, 17, 11, 38, 72, 29, -8, -36, -27, -42, 17, -40, 25, 25, 8, -3,
- 14, 15, 2, 43, 33, -2, -19, -24, -8, 2, -69, -114, -94, -77, -87, 22,
- 27, 19, 24, 57, 121, 94, 40, -27, -29, 4, 28, -12, 5, -21, -28, -18,
- 0, -9, 1, 36, 22, 7, 6, 12, 7, 8, 55, 6, -2, -7, -13, -12,
- -12, -8, -5, -5, -1, -4, -4, -3, -1, 5, 11, 15, 18, 16, 11, 5,
- -5, -12, -16, -17, -14, -10, -7, -3, -2, -3, -3, -5, -3, 2, 9, 18,
- 22, 23, 18, 11, -2, -14, -20, -22, -18, -12, -8, -5, -3, -5, -6, -6,
- -5, 1, 11, 22, 30, 31, 24, 15, -1, -12, -20, -23, -19, -13, -8, -3,
- -3, -2, -6, -8, -9, -5, 6, 21, 32, 35, 29, 19, 1, -15, -27, -29,
- -25, -15, -9, -4, -1, -2, -7, -14, -15, -10, 4, 24, 42, 48, 43, 26,
- 4, -20, -36, -38, -30, -17, -7, -3, 0, -1, -4, -16, -24, -19, -3, 26,
- 49, 61, 60, 40, 9, -23, -45, -52, -39, -22, -5, -2, 1, 3, -2, -18,
- -32, -30, -10, 22, 55, 77, 78, 52, 15, -22, -51, -66, -52, -29, -5, 0,
- 2, 9, 6, -15, -37, -42, -22, 10, 55, 89, 99, 71, 22, -20, -58, -79,
- -68, -35, -8, 6, 1, 12, 13, -9, -37, -50, -35, 0, 46, 93, 116, 90,
- 33, -15, -60, -89, -84, -44, -9, 10, 3, 13, 19, -3, -35, -53, -43, -12,
- 34, 91, 127, 109, 46, -9, -57, -95, -96, -57, -13, 11, 7, 10, 25, 2,
- -2, -35, 0, 2, 7, 12, -7, -79, -68, 2, -6, -5, 19, 40, 33, 55,
- 56, 17, 32, 32, 2, -20, 5, 51, 27, -21, -13, -11, -17, -20, -6, -63,
- -125, -116, -86, -59, -34, 11, 23, 20, 39, 66, 50, 47, 54, 46, 11, -4,
- 44, 67, 30, 11, 16, 6, -2, 7, -4, -77, -114, -107, -70, -50, -20, 29,
- 26, 12, 48, 69, 44, 47, 49, 28, -8, 9, 53, 49, 15, 9, 8, -3,
- -11, 7, -33, -107, -123, -101, -62, -49, -5, 25, 6, 13, 55, 49, 32, 40,
- 39, 7, -17, 18, 49, 32, 7, 8, 1, -12, -3, 7, -62, -113, -109, -74,
- -50, -31, 23, 32, 13, 40, 69, 48, 46, 54, 42, 2, 1, 42, 52, 25,
- 10, 11, 0, -11, 10, -10, -90, -115, -101, -64, -52, -15, 29, 16, 10, 51,
- 59, 41, 46, 49, 25, -9, 15, 48, 42, 15, 10, 7, -9, -7, 16, -43,
- -107, -113, -89, -60, -47, 4, 27, 4, 19, 58, 47, 38, 46, 43, 6, -9,
- 28, 47, 29, 10, 11, 2, -14, 5, 5, -73, -111, -106, -73, -56, -29, 24,
- 22, 6, 40, 61, 43, 43, 52, 37, -3, 6, 41, 47, 23, 12, 11, 0,
- -14, 1, 3, 5, 5, 6, 8, 6, 4, 0, -4, -5, -6, -9, -9, -11,
- -11, -12, -13, -13, -13, -12, -11, -9, -5, -2, -1, 1, 4, 6, 9, 11,
- 12, 12, 11, 8, 5, 2, -2, -2, -2, -2, 0, -1, -1, -2, -5, -5,
- -5, -1, 4, 10, 17, 20, 22, 19, 15, 7, -1, -9, -15, -19, -21, -21,
- -18, -16, -13, -11, -12, -15, -19, -23, -24, -20, -13, -3, 9, 20, 34, 44,
- 50, 46, 35, 21, 7, -4, -14, -20, -19, -13, -8, 2, 0, -5, -15, -28,
- -32, -29, -14, 0, 11, 27, 42, 58, 59, 45, 22, 4, -15, -26, -37, -43,
- -42, -37, -17, 1, 18, 23, 8, -5, -29, -47, -47, -43, -25, -5, 20, 52,
- 80, 92, 76, 43, 9, -20, -35, -38, -46, -41, -29, -12, 19, 35, 22, 4,
- -34, -53, -58, -40, -26, -16, 14, 47, 88, 108, 90, 50, 16, -9, -36, -51,
- -64, -64, -52, -33, -1, 32, 40, 24, 3, -29, -62, -58, -65, -52, -18, 23,
- 68, 114, 127, 95, 41, 1, -36, -54, -56, -68, -55, -35, -17, 19, 42, 29,
- 13, -16, -46, -60, -54, -56, -47, -11, 29, 72, 116, 127, 94, 41, -3, 0,
- 16, 39, 54, 46, 18, 7, -15, -36, -9, -6, -16, -5, -15, -30, -23, -35,
- -20, 22, 3, -19, -20, -13, -9, 19, 23, 10, 12, 35, 66, 54, 4, -43,
- -58, -15, -10, 16, 55, 18, -39, -38, -30, 2, 9, 27, 51, -32, -60, -72,
- -4, 32, 71, 19, -8, 56, -2, -42, 10, 21, -6, 31, -9, -70, 8, -6,
- -19, -93, -20, -5, -31, 10, 5, 56, 24, -45, 11, 66, 48, 61, 89, 49,
- -57, -6, -20, -69, -104, -83, -50, 32, 10, -16, -87, -78, 30, 127, 63, -17,
- -91, -2, -12, 45, 83, 30, 56, 54, 42, 7, 79, -26, -52, -64, -97, 12,
- -3, -107, -99, -39, 34, 86, 19, -25, 25, 90, -8, -38, 65, 36, 10, 30,
- 36, 19, -6, 38, -47, -101, -52, -45, 30, -9, -106, 18, -10, -37, 16, 100,
- -94, -111, -25, -35, -12, -8, -9, 51, 24, -5, -70, -52, -52, -19, -11, 48,
- 93, 61, 17, 113, 125, 73, -16, -30, -57, -78, -116, -55, -38, -10, -5, -4,
- 38, 31, -3, -46, -46, -50, -20, -10, 52, 84, 48, 14, 115, 119, 64, -16,
- -1, 4, 0, -9, -11, -1, 6, 2, -2, 4, -6, -10, -2, 11, 14, 3,
- -10, -15, -1, 17, 4, 6, 4, -12, -18, 6, 10, 4, 6, -8, -36, 2,
- 3, 3, 5, 15, -20, -17, 9, 8, 11, 17, -8, -26, 18, 2, 5, 5,
- 13, -24, -8, -2, 2, 5, 7, -21, -18, 13, 5, -5, 17, 7, -14, -13,
- -12, 0, 14, 3, -12, -26, 13, 3, 10, 18, 12, -15, -14, -1, 3, 19,
- 0, -10, -29, 11, 4, 17, 15, 12, -24, -20, 6, 9, 22, -3, -13, -15,
- 9, 1, 7, 6, 18, -19, -26, -18, 2, 22, 0, -25, -20, 15, 8, -4,
- 8, 31, -12, -20, -15, 9, 33, 9, -29, -2, 27, 7, -11, 8, 20, -20,
- -41, -10, 15, 35, 15, -21, 11, 49, 6, -6, 4, 3, -48, -76, -35, 14,
- 37, 22, -24, 29, 68, 20, 3, 7, -5, -68, -90, -59, 19, 36, 28, -13,
- 59, 93, 30, 2, 18, -25, -88, -105, -81, 13, 26, 30, -4, 88, 109, 33,
- 0, 22, -30, -88, -112, -76, 17, 31, 18, 5, 94, 114, 30, -4, 0, 4,
- -30, -1, 0, -2, -2, -2, -1, 4, 11, 18, 30, 7, -64, -60, -30, -7,
- 0, 2, 22, 67, 117, 23, -128, -74, -30, -5, -2, 1, 19, 62, 116, 38,
- -123, -82, -31, -8, -1, -1, 16, 57, 114, 52, -117, -88, -33, -10, -2, -3,
- 14, 52, 112, 64, -108, -96, -35, -13, -2, -4, 12, 49, 108, 77, -99, -102,
- -37, -15, -2, -5, 10, 43, 104, 86, -87, -109, -40, -18, -2, -6, 8, 40,
- 100, 95, -73, -115, -42, -21, -2, -8, 7, 35, 95, 102, -59, -120, -45, -24,
- -2, -8, 5, 32, 90, 109, -44, -124, -49, -26, -3, -9, 3, 28, 85, 114,
- -29, -126, -53, -28, -4, -9, 2, 25, 81, 116, -13, -127, -58, -29, -6, -9,
- 0, 22, 75, 119, 3, -126, -63, -31, -7, -9, -2, 19, 70, 120, 18, -124,
- -69, -32, -9, -9, -3, 16, 65, 119, 34, -63, -107, -58, -23, -11, -7, 7,
- 46, 107, 89, -52, -109, -62, -25, -12, -8, 5, 42, 104, 97, -41, -87, -70,
- -36, -18, -11, 0, 30, 85, 100, -2, -87, -5, 11, -23, -10, -3, -20, -3,
- -17, -24, -33, -26, -1, -13, -12, -6, -9, 6, 25, 19, -7, -1, 22, -6,
- -20, 13, 6, -12, 26, 48, 0, -7, 34, 23, 4, 32, 23, -41, -11, 49,
- -3, -30, 35, 45, -14, -2, 62, 18, -44, -2, 26, -4, -28, -6, 16, 2,
- -9, -9, 2, 18, 24, 9, -25, -57, -36, 30, 38, -21, -63, -37, 9, 37,
- 40, 0, -56, -56, 3, 39, 20, -23, -52, -58, -46, 8, 67, 56, -18, -61,
- -18, 36, 70, 95, 73, -35, -128, -127, -73, -17, 32, 48, 29, 28, 60, 106,
- 113, 91, 36, -26, -67, -90, -91, -71, -44, -25, -13, 9, 36, 51, 69, 70,
- 32, -40, -92, -99, -70, -25, 12, 29, 21, 3, -9, 10, 21, 12, -11, -22,
- -27, -44, -23, 10, 30, 25, 24, 39, 18, 3, 8, 19, -1, -19, -8, 6,
- 5, 13, 50, 43, 37, 36, 40, 37, 4, 12, -10, -33, -31, -25, -1, 1,
- 7, 14, 10, -4, -11, -10, -6, -19, -42, -28, -54, -51, -18, -5, 3, 2,
- -10, -10, 10, 28, 27, 16, 5, -5, -24, -26, -7, -14, -25, -16, 53, 33,
- -49, -30, 53, 50, -24, -34, 40, 82, -118, -23, 120, -56, -70, -72, 106, -10,
- -48, 3, 87, 28, -126, -16, 81, 4, -84, -51, 38, 62, -32, 36, 84, -12,
- -41, 72, -42, -60, -64, 4, 77, -24, -79, -9, 122, 6, -94, 52, 43, 35,
- 13, -62, -7, -89, 24, -30, 16, 29, 56, -59, 83, 42, 31, 36, -76, -2,
- -128, -2, 45, 27, -104, -31, 66, 21, 19, 36, 121, 11, -76, -26, -93, 34,
- 24, -34, -65, -53, 53, 17, 73, 46, 75, -9, -64, -21, -103, 41, 51, -41,
- -83, -43, 108, 6, -11, 28, 127, 2, -84, -38, -72, 39, 17, -23, -15, -67,
- 37, 6, 29, 64, 79, 17, -39, -39, -120, 55, 23, -17, -62, -51, 81, 23,
- 20, 24, 99, -38, -99, 4, 17, -66, -41, -33, 63, 62, 16, 53, 91, 56,
- -65, -36, -99, -38, 14, -47, -29, -38, 35, 83, 9, 48, 83, 62, -45, -31,
- -103, -49, 14, 2, 6, -33, 33, -4, -1, 34, -93, 60, -49, 68, -21, 41,
- -38, -38, 27, -87, 127, -34, 38, -3, -34, -2, -85, 79, -24, 4, 75, -23,
- 11, -70, 1, -6, -6, 63, -48, 76, -71, 2, -7, -15, 46, -32, 48, -25,
- -5, 10, -31, 18, -23, 5, 6, 17, 11, 3, 24, -46, -21, -1, -5, 31,
- 1, 36, -23, -11, -4, -29, 14, -5, 29, 9, -2, -2, -20, -2, -15, 13,
- 7, 4, 15, -11, 4, -13, -1, 1, -13, 15, -6, 9, 9, -2, -4, -11,
- -2, -11, 7, 12, 9, 5, -6, -6, -16, -2, 3, 6, 13, 1, 7, -14,
- -3, -11, -1, 8, 0, 18, -3, -3, -6, -13, 0, 4, 2, 9, 2, 2,
- -6, -4, -1, -8, 2, 4, 2, 7, -4, 2, 1, -7, -3, -2, 0, 2,
- 8, -2, 2, -1, -7, -3, -1, 3, 4, 3, 3, -3, -4, -4, 0, 2,
- 1, 5, -1, -2, 1, -4, -1, 1, 0, 2, -5, -8, -3, -3, -9, -2,
- -2, 5, 10, 16, 11, 5, -3, -5, -1, -4, -6, -7, -15, -18, -27, -31,
- -21, -11, 22, 56, 90, 66, -17, -25, -25, 0, -12, -15, -25, -32, -39, -37,
- -26, 6, 33, 65, 69, 44, -1, -13, -12, 1, 0, -9, -14, -22, -40, -44,
- -42, -23, 8, 39, 60, 84, 57, -16, -25, -19, 2, -8, -11, -18, -32, -51,
- -45, -32, -6, 28, 54, 85, 96, -5, -29, -23, -7, -10, -17, -16, -28, -53,
- -44, -40, -7, 22, 52, 82, 112, 17, -37, -25, -20, -11, -18, -10, -23, -33,
- -51, -40, -23, 10, 45, 65, 96, 64, -21, -35, -34, -19, -20, -13, -5, -14,
- -35, -41, -39, -17, 9, 45, 58, 82, 98, -2, -57, -47, -23, -12, -11, -2,
- -18, -28, -39, -36, -24, -1, 26, 57, 84, 121, 23, -65, -50, -40, -12, -11,
- -4, -14, -20, -34, -32, -27, -5, 19, 56, 80, 127, 15, -66, -50, -2, -5,
- -5, 2, 10, 8, -7, -16, -9, 6, 17, 8, -19, -20, 14, 38, 34, 20,
- -5, 1, 50, 37, -50, -54, -66, -32, 32, -3, -13, -18, -17, 46, 89, -17,
- -62, 45, 127, 57, -57, -67, -109, -11, 88, -31, -90, -88, -27, 63, 97, -27,
- -105, -44, 65, 110, 60, -12, -30, -27, 17, 49, -2, -39, -6, 30, -16, -36,
- -43, 32, 67, -54, -58, -38, -21, 47, 95, 76, -33, -78, -62, 10, 107, 24,
- -106, -107, 12, 52, 27, 78, 8, -75, 25, 6, -26, 59, 32, -17, -7, -19,
- 11, 32, -51, -52, 41, -9, -13, 94, 2, -65, 5, -46, -86, 34, 62, 85,
- 29, -93, -89, -29, 44, 35, -31, -33, -19, 56, 127, 7, -9, -62, -52, 23,
- 46, 44, -56, -16, -55, -46, 22, 83, -13, -42, -7, 13, 81, 49, 3, -9,
- -30, -47, -30, 3, 23, 6, -7, -20, -44, 10, 96, -13, 0, 16, 31, 47,
- 61, 75, 87, 98, 107, 115, 121, 125, 127, 127, 125, 121, 116, 108, 99, 88,
- 75, 62, 47, 32, 16, 0, -16, -31, -47, -61, -75, -87, -98, -108, -116, -122,
- -126, -128, -128, -126, -123, -117, -109, -100, -89, -77, -64, -49, -34, -18, -2, 14,
- 29, 45, 59, 73, 86, 97, 106, 114, 121, 125, 127, 127, 126, 122, 116, 109,
- 100, 89, 77, 63, 49, 34, 18, 2, -14, -30, -45, -60, -73, -86, -97, -107,
- -115, -121, -126, -128, -128, -127, -123, -118, -110, -101, -91, -79, -65, -51, -36, -20,
- -4, 12, 28, 43, 58, 72, 84, 96, 106, 114, 120, 124, 127, 127, 126, 122,
- 117, 109, 100, 90, 78, 64, 50, 35, 19, 3, -13, -29, -44, -59, -73, -85,
- -97, -107, -115, -121, -125, -128, -128, -127, -123, -118, -110, -101, -91, -79, -65, -51,
- -36, -20, -4, 12, 2, 5, 5, 0, -16, -9, -2, -19, 4, 18, 6, 10,
- -16, -21, 22, -2, 3, -7, 21, 43, -57, -37, 46, -39, -31, 78, 23, -23,
- -10, -10, -7, -52, 44, 50, -44, 9, -9, -46, 47, 12, -75, 40, 45, 32,
- -10, -25, -15, -45, 24, 44, -40, -10, 18, -48, -29, 63, 44, -30, -1, 83,
- -45, -94, 96, 0, -103, 21, 29, -42, 21, 80, -25, -15, 26, 39, -79, -18,
- 73, -111, -45, 61, 29, 55, -22, -77, 40, 9, -72, 78, 35, -1, -1, -69,
- 12, -50, -42, 123, 45, -7, -39, -86, 3, 51, 30, 28, -4, -33, -41, -66,
- 54, -8, -30, 127, -7, -30, -32, -39, 48, -65, 20, 121, -33, -14, -53, -32,
- 46, -24, 36, 98, -49, -39, -61, 1, 49, -54, 65, 59, -83, -11, -49, 32,
- 39, -72, 113, 59, -83, -11, -49, 32, 39, -72, 113, 59, -2, -4, -4, -7,
- -8, -8, -7, -4, -3, -2, 1, 4, 6, 6, 6, 4, 2, 0, -2, -3,
- -4, -7, -7, -5, -3, 0, 4, 9, 11, 11, 9, 7, 4, 1, -3, -7,
- -9, -12, -13, -16, -19, -19, -13, -2, 9, 17, 19, 20, 18, 13, 8, 3,
- 0, -2, -3, -8, -14, -21, -25, -21, -9, 4, 15, 23, 28, 25, 20, 9,
- -7, -21, -14, 3, 3, -18, -38, -49, -32, -7, 8, 14, 26, 37, 42, 37,
- 26, 7, -18, -27, -5, 8, -7, -24, -34, -40, -32, -19, 1, 17, 42, 56,
- 58, 40, -19, -81, 1, 67, 0, -60, -49, -27, -24, 0, -18, -24, -8, 37,
- 67, 70, 59, 34, -42, -81, 7, 51, -12, -54, -37, -14, -25, -14, -16, -24,
- 4, 55, 75, 102, 52, -102, -104, 90, 30, -48, -76, 1, -14, 0, -2, -2,
- -3, -5, -7, -8, -8, -7, -6, -4, -2, 0, 1, 3, 4, 6, 6, 6,
- 6, 5, 4, 3, 1, 0, 0, -3, -4, -7, -10, -11, -11, -8, -6, 1,
- 5, 6, 8, 11, 11, 8, 5, 5, 2, 1, 0, 0, -2, 1, -4, -16,
- -36, -27, -5, 6, -3, -6, 0, -6, 2, 27, 24, 19, 16, 9, 3, 0,
- -4, 2, 1, 9, 19, -14, -79, -32, 22, -4, -22, -14, 25, 8, -11, 13,
- 28, 16, 19, 16, 1, -2, -4, -3, -6, 28, 38, -59, -111, 25, 16, -16,
- -40, 16, 24, -20, 4, 24, 29, 17, 27, 13, 1, -10, -6, -10, -8, 43,
- 61, -68, -128, 28, 12, -15, -39, 12, 21, -28, 12, 37, 25, 12, 27, 11,
- 0, -16, -2, -12, -11, 52, 67, -68, 35, 54, 47, 4, -60, -92, -68, -27,
- 0, -2, -18, -20, -6, 2, -8, -15, -11, -3, 3, -7, -11, -6, -2, 7,
- 15, 18, 19, 22, 27, 40, 40, 29, 20, 24, 28, 34, 30, 25, 32, 20,
- 14, 9, 16, 19, 17, 6, -1, 3, -6, -14, -23, -18, -7, 1, -18, -18,
- -24, -25, -24, -35, -35, -35, -21, -12, -14, -21, -17, -29, -24, -31, -34, -9,
- -11, -9, -3, -7, -7, 6, -17, -22, 7, 16, 14, -4, -11, 10, 33, 24,
- 21, 27, 3, -19, -25, -18, 17, 50, 48, 49, 61, 31, -48, -103, -73, 9,
- 56, 70, 82, 109, 127, 71, -46, -127, -96, -30, -4, 9, 47, 103, 117, 60,
- -39, -110, -119, -94, -64, -40, -4, 35, -8, -14, -9, -5, -4, -3, 6, 18,
- 19, 6, -14, -20, -12, -3, -3, -6, 2, 21, 28, 13, -16, -26, -14, -6,
- -6, -7, 1, 27, 36, 18, -15, -27, -15, -3, -2, -10, -6, 25, 41, 22,
- -17, -34, -18, -4, -3, -16, -12, 29, 56, 31, -24, -44, -20, -4, -1, -19,
- -22, 31, 73, 47, -27, -62, -25, -2, 4, -21, -36, 26, 91, 61, -27, -79,
- -33, 0, 10, -18, -49, 14, 106, 82, -24, -94, -40, 8, 14, -12, -59, 1,
- 112, 105, -19, -106, -51, 12, 16, -4, -63, -13, 110, 127, -12, -114, -51, 0,
- -1, -4, -8, -11, -8, -2, 0, 7, 14, 21, 46, 92, 120, 76, -36, -121,
- -119, -73, -31, -7, 3, 2, -4, -6, 2, 22, 60, 106, 116, 43, -72, -128,
- -105, -57, -21, -3, 3, -1, -6, -5, 7, 33, 76, 117, 102, 5, -100, -127,
- -89, -43, -13, 0, 2, -3, -7, -2, 14, 46, 92, 122, 79, -34, -118, -118,
- -72, -31, -8, 1, 0, -5, -7, 2, 23, 61, 107, 118, 46, -69, -126, -104,
- -56, -21, -4, 1, 0, -4, -5, 0, 16, 48, 87, 103, 60, -25, -87, -94,
- -58, -20, -4, -11, 12, 24, 31, -36, 29, -9, 2, -38, -5, -5, -10, -33,
- -10, -24, -20, -39, -36, -18, -38, -58, -5, -22, -15, -15, 90, -42, -3, -8,
- 25, 6, 28, 25, 17, 25, -16, 28, 80, 22, 12, -6, 35, 22, 8, -7,
- 28, 29, -19, 7, 8, -1, -29, -23, 10, -23, -13, -26, -17, -20, -33, -41,
- -19, -28, -64, -13, -21, -13, -29, 54, 25, -20, -36, 42, -4, 13, 52, -8,
- 47, -14, 9, 42, 88, -12, 20, -5, 43, 22, -11, 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, -128, -128, -128, -128, -128, -128, -128, -128,
- -128, -128, -128, -128, -128, -128, -128, 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, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
- 127, -128, 1, 4, 7, 10, 12, 16, 19, 22, 25, 28, 31, 35, 38, 42,
- 45, 49, 51, 56, 58, 63, 65, 70, 73, 78, 80, 85, 87, 93, 95, 100,
- 102, 108, 109, 117, 114, 127, 85, -63, -60, -64, -60, -62, -59, -61, -59, -61,
- -58, -60, -58, -59, -58, -58, -57, -57, -55, -55, -54, -54, -52, -51, -50, -49,
- -47, -46, -44, -43, -41, -40, -37, -36, -34, -32, -30, -28, -25, -24, -21, -19,
- -16, -14, -11, -9, -6, 1, 1, 4, 7, 10, 12, 16, 19, 22, 25, 28,
- 31, 35, 38, 42, 45, 49, 51, 56, 58, 63, 65, 70, 73, 78, 80, 85,
- 87, 93, 95, 100, 102, 108, 109, 117, 114, 127, 85, -63, -60, -64, -60, -62,
- -59, -61, -59, -61, -58, -60, -58, -59, -58, -58, -57, -57, -55, -55, -54, -54,
- -52, -51, -50, -49, -47, -46, -44, -43, -41, -40, -37, -36, -34, -32, -30, -28,
- -25, -24, -21, -19, -16, -14, -11, -9, -6, 1, -3, -19, -24, -14, -8, -19,
- -12, -10, -5, -12, -50, -19, 23, 35, 4, -20, -7, -26, 9, 40, 69, 16,
- -88, -69, -38, -32, -27, 41, 65, 55, 18, -40, -38, -20, 66, 127, 121, 57,
- -23, -55, -48, 13, 53, 31, -20, -38, -13, 10, 8, 0, 12, 17, 13, 2,
- -1, -3, -3, 6, 13, 7, -17, -24, -12, 4, 3, -10, -20, -32, -22, -18,
- -12, -3, 6, 16, 22, 29, 30, 27, 20, 11, 0, -7, -12, -11, -5, 0,
- -3, -14, -20, -16, -9, -9, -17, -25, -29, -31, -33, -35, -33, -29, -25, -22,
- -20, -17, -14, -13, -12, -11, -9, -10, -13, -15, -11, -5, 3, 9, 10, 9,
- 9, 12, 18, 30, 50, 80, 119, 127, 102, 82, 77, 60, 37, 5, -34, -70,
- -84, -83, -74, -60, -46, -29, -12, -2, 6, -23, 28, -20, 50, 50, -14, 14,
- -28, -2, 28, 52, -25, -13, -52, 43, -41, -9, -26, 36, -25, -20, -17, 3,
- -11, 38, 30, -61, 12, -6, 5, 45, 41, -4, 4, -20, -12, 45, 33, -11,
- -29, -44, 27, -17, -36, -1, 17, -11, -31, -12, 4, -10, 37, 20, -39, -23,
- 0, -104, -55, -11, 24, 33, 30, 7, -15, -31, -30, -25, -23, -20, -9, 10,
- 31, 59, 91, 111, 115, 92, 51, 7, -33, -64, -81, -81, -71, -51, -22, 16,
- 52, 74, 82, 81, 68, 38, 0, -40, -81, -112, -124, -102, -57, -11, 0, 7,
- -23, -58, -85, -100, -104, -100, -92, -81, -69, -57, -45, -33, -22, -11, -1, 8,
- 18, 27, 37, 49, 62, 79, 99, 118, 124, 111, 84, 53, 26, 5, -8, -14,
- -15, -12, -6, 2, 12, 21, 28, 26, 9, -22, -58, -20, 7, 10, 21, -14,
- 9, 22, 57, 62, 127, 56, 28, 26, -28, 10, -81, -31, -81, -35, -19, -55,
- -27, -4, -4, 23, 49, 88, 85, 22, 1, 0, -3, 18, -22, -12, -39, -14,
- -47, -67, -53, -53, -33, -20, 8, -22, 25, 30, 6, -19, -62, -19, 10, 83,
- 57, -67, -88, -52, 63, 127, 42, -63, -121, -70, 82, 111, 46, -43, -114, -35,
- 45, 73, 39, -19, -54, -41, 9, 49, 24, -16, -14, -9, -6, 10, 8, -22,
- 25, 30, 6, -19, -62, -19, 10, 83, 57, -67, -88, -52, 63, 127, 42, -63,
- -121, -70, 82, 111, 46, -43, -114, -35, 45, 73, 39, -19, -54, -41, 9, 49,
- 24, -16, -14, -9, -6, 10, 8, -22, 25, 30, 6, -19, -62, -19, 10, 83,
- 57, -67, -88, -52, 63, 127, 42, -63, -121, -70, 82, 111, 46, -43, -114, -35,
- 45, 73, 39, -19, -54, -41, 9, 49, 24, -16, -14, -9, -6, 10, -18, -15,
- 80, 127, 20, 18, 72, 60, -36, 22, 33, -73, -105, -27, 29, 25, 8, 43,
- 23, -22, -35, -14, -8, -34, -25, -5, -18, -46, -13, -28, -3, -19, -10, -28,
- -10, 17, -18, 96, 127, 123, 127, 126, 126, 95, 61, 22, -17, -56, -95, -118,
- -123, -128, -128, -128, -128, -128, -128, -128, -128, -124, -93, -55, -17, 25, 62, 100,
- 107, 119, 119, 127, 41, -4, -4, -10, -27, -62, -102, -128, -117, -85, -76, -49,
- -25, -7, 15, 24, 14, 0, -9, -12, -3, 33, 81, 105, 111, 101, 80, 62,
- 45, 30, 16, 8, 1, -4, 126, 86, -44, -68, -88, -63, 4, 84, 127, 14,
- -29, -51, -127, -47, 58, 87, 82, 24, -17, -112, -113, 18, 46, 72, 102, 19,
- -72, -118, -51, 9, 27, 126, 19, -53, -114, -108, 15, 122, 111, 21, -71, -70,
- 5, 59, 83, 23, -72, -84, -49, 12, 37, 38, -28, -65, -26, 7, -2, 11,
- 5, 23, 68, 19, 27, -54, 15, -24, -31, 46, 71, 81, -24, -33, -87, -41,
- -71, -61, -70, -36, -44, -3, 12, -25, -20, 20, 68, 85, 127, 15, 50, -5,
- 27, 51, 82, 106, 127, 118, 101, 92, 74, 52, 39, 37, 14, -41, -105, -108,
- -94, -119, -124, -93, -57, -40, -37, -45, -51, -41, -5, 51, 127, 127, -128, -128,
- -128, -128, -128, -128, -128, -128, -128, -128, 127, 127, 127, 127, 127, 127, 127, 127,
- 127, 127
-};
-
-const EAS_U32 eas_sampleLengths[] =
-{
- 16820, 16708, 16592, 11754, 10954, 10295, 9922, 7489,
- 5779, 5462, 4452, 3779, 3115, 3093, 3057, 3024,
- 2818, 2776, 2171, 2168, 2052, 1902, 1835, 1614,
- 1603, 1528, 1517, 1480, 1455, 1424, 1387, 1302,
- 1262, 1254, 1230, 1227, 1185, 1181, 1178, 1168,
- 1132, 1120, 1034, 1033, 1018, 994, 964, 926,
- 907, 886, 881, 866, 830, 817, 816, 813,
- 749, 748, 739, 720, 652, 610, 610, 583,
- 564, 561, 556, 549, 542, 535, 530, 530,
- 516, 508, 492, 478, 461, 448, 437, 431,
- 423, 418, 403, 402, 400, 394, 387, 387,
- 367, 357, 347, 347, 341, 336, 334, 329,
- 325, 312, 294, 284, 277, 265, 255, 233,
- 230, 213, 207, 205, 194, 193, 184, 181,
- 181, 167, 164, 158, 152, 152, 145, 139,
- 128, 103, 100, 88, 87, 84, 84, 72,
- 71, 55, 46, 45, 43, 40, 40, 40,
- 37, 35, 32, 32, 30, 29, 27, 23,
- 22, 21, 21, 21, 21, 20
-};
-
-const EAS_U32 eas_sampleOffsets[] =
-{
- 0x00000000, 0x000041b4, 0x000082f8, 0x0000c3c8, 0x0000f1b2, 0x00011c7c, 0x000144b3, 0x00016b75,
- 0x000188b6, 0x00019f49, 0x0001b49f, 0x0001c603, 0x0001d4c6, 0x0001e0f1, 0x0001ed06, 0x0001f8f7,
- 0x000204c7, 0x00020fc9, 0x00021aa1, 0x0002231c, 0x00022b94, 0x00023398, 0x00023b06, 0x00024231,
- 0x0002487f, 0x00024ec2, 0x000254ba, 0x00025aa7, 0x0002606f, 0x0002661e, 0x00026bae, 0x00027119,
- 0x0002762f, 0x00027b1d, 0x00028003, 0x000284d1, 0x0002899c, 0x00028e3d, 0x000292da, 0x00029774,
- 0x00029c04, 0x0002a070, 0x0002a4d0, 0x0002a8da, 0x0002ace3, 0x0002b0dd, 0x0002b4bf, 0x0002b883,
- 0x0002bc21, 0x0002bfac, 0x0002c322, 0x0002c693, 0x0002c9f5, 0x0002cd33, 0x0002d064, 0x0002d394,
- 0x0002d6c1, 0x0002d9ae, 0x0002dc9a, 0x0002df7d, 0x0002e24d, 0x0002e4d9, 0x0002e73b, 0x0002e99d,
- 0x0002ebe4, 0x0002ee18, 0x0002f049, 0x0002f275, 0x0002f49a, 0x0002f6b8, 0x0002f8cf, 0x0002fae1,
- 0x0002fcf3, 0x0002fef7, 0x000300f3, 0x000302df, 0x000304bd, 0x0003068a, 0x0003084a, 0x000309ff,
- 0x00030bae, 0x00030d55, 0x00030ef7, 0x0003108a, 0x0003121c, 0x000313ac, 0x00031536, 0x000316b9,
- 0x0003183c, 0x000319ab, 0x00031b10, 0x00031c6b, 0x00031dc6, 0x00031f1b, 0x0003206b, 0x000321b9,
- 0x00032302, 0x00032447, 0x0003257f, 0x000326a5, 0x000327c1, 0x000328d6, 0x000329df, 0x00032ade,
- 0x00032bc7, 0x00032cad, 0x00032d82, 0x00032e51, 0x00032f1e, 0x00032fe0, 0x000330a1, 0x00033159,
- 0x0003320e, 0x000332c3, 0x0003336a, 0x0003340e, 0x000334ac, 0x00033544, 0x000335dc, 0x0003366d,
- 0x000336f8, 0x00033778, 0x000337df, 0x00033843, 0x0003389b, 0x000338f2, 0x00033946, 0x0003399a,
- 0x000339e2, 0x00033a29, 0x00033a60, 0x00033a8e, 0x00033abb, 0x00033ae6, 0x00033b0e, 0x00033b36,
- 0x00033b5e, 0x00033b83, 0x00033ba6, 0x00033bc6, 0x00033be6, 0x00033c04, 0x00033c21, 0x00033c3c,
- 0x00033c53, 0x00033c69, 0x00033c7e, 0x00033c93, 0x00033ca8, 0x00033cbd
-};
-
-/*----------------------------------------------------------------------------
- * S_EAS
- *----------------------------------------------------------------------------
-*/
-const S_EAS easSoundLib =
-{
- 0x01534145,
- 0x0010ac44,
- eas_banks,
- eas_programs,
- eas_regions,
- eas_articulations,
- eas_sampleLengths,
- eas_sampleOffsets,
- eas_samples,
- 0,
- 1,
- 1,
- 377,
- 185,
- 150,
- 0
-}; /* end S_EAS */
-
-/*----------------------------------------------------------------------------
- * Statistics
- *
- * Number of banks: 1
- * Number of programs: 1
- * Number of regions: 377
- * Number of articulations: 185
- * Number of samples: 150
- * Size of sample pool: 212050
- *----------------------------------------------------------------------------
-*/
-/* end wt_200k_G_MAC.c */
+/*----------------------------------------------------------------------------
+ *
+ * Filename: wt_44khz.c
+ * Purpose: Wavetable sound libary
+ *
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+*/
+
+#include "eas_sndlib.h"
+
+/*----------------------------------------------------------------------------
+ * Articulations
+ *----------------------------------------------------------------------------
+*/
+const S_ARTICULATION eas_articulations[] =
+{
+ { /* articulation 0 */
+ { 32767, 31730, 0, 31730 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 476, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 1 */
+ { 32767, 29669, 0, 29669 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 476, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 2 */
+ { 32767, 31605, 0, 31701 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 476, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 3 */
+ { 32767, 29434, 0, 29434 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 476, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 4 */
+ { 32767, 0, 32767, 32742 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 476, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 5 */
+ { 32767, 26439, 0, 26439 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 476, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 6 */
+ { 32767, 32322, 0, 32350 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 476, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 7 */
+ { 32767, 32715, 32767, 32715 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 476, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 8 */
+ { 32767, 0, 32767, 0 },
+ { 32767, 951, 0, 0 },
+ 0, 0, 476, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 9 */
+ { 32767, 32558, 0, 32558 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 476, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 10 */
+ { 32767, 0, 32767, 23749 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 476, 0, 0, 0, 0, 0, -1
+ },
+ { /* articulation 11 */
+ { 32767, 32245, 0, 32245 },
+ { 32767, 380, 0, 0 },
+ 0, 0, 476, 0, 0, 0, 0, 0, -44
+ },
+ { /* articulation 12 */
+ { 32767, 27897, 0, 27897 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 476, 0, 0, 0, 0, 0, 56
+ },
+ { /* articulation 13 */
+ { 32767, 32245, 0, 32245 },
+ { 32767, 380, 0, 0 },
+ 0, 0, 476, 0, 0, 0, 0, 0, -31
+ },
+ { /* articulation 14 */
+ { 4755, 26439, 0, 26439 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 476, 0, 0, 0, 0, 0, 56
+ },
+ { /* articulation 15 */
+ { 32767, 32187, 0, 32187 },
+ { 32767, 380, 0, 0 },
+ 0, 0, 476, 0, 0, 0, 0, 0, -6
+ },
+ { /* articulation 16 */
+ { 32767, 32444, 0, 32480 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 476, 0, 0, 0, 0, 0, 56
+ },
+ { /* articulation 17 */
+ { 32767, 32153, 0, 32153 },
+ { 32767, 380, 0, 0 },
+ 0, 0, 476, 0, 0, 0, 0, 0, 6
+ },
+ { /* articulation 18 */
+ { 32767, 32072, 0, 32072 },
+ { 32767, 476, 0, 0 },
+ 0, 0, 476, 0, 0, 0, 0, 0, 31
+ },
+ { /* articulation 19 */
+ { 32767, 32363, 0, 32363 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 476, 0, 0, 0, 0, 0, 25
+ },
+ { /* articulation 20 */
+ { 32767, 31901, 0, 31901 },
+ { 32767, 476, 0, 0 },
+ 0, 0, 476, 0, 0, 0, 0, 0, 63
+ },
+ { /* articulation 21 */
+ { 32767, 32528, 0, 32518 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 476, 0, 0, 0, 0, 0, -37
+ },
+ { /* articulation 22 */
+ { 9511, 32322, 0, 32337 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 476, 0, 0, 0, 0, 0, -37
+ },
+ { /* articulation 23 */
+ { 32767, 32376, 0, 32398 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 476, 0, 0, 0, 0, 0, -37
+ },
+ { /* articulation 24 */
+ { 32767, 0, 32767, 32715 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 476, 0, 0, 0, 0, 0, 12
+ },
+ { /* articulation 25 */
+ { 32767, 32052, 0, 32052 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 476, 0, 0, 0, 0, 0, -25
+ },
+ { /* articulation 26 */
+ { 32767, 0, 32767, 32715 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 476, 0, 0, 0, 0, 0, 25
+ },
+ { /* articulation 27 */
+ { 32767, 32289, 0, 32271 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 476, 0, 0, 0, 0, 0, -25
+ },
+ { /* articulation 28 */
+ { 32767, 31730, 0, 31730 },
+ { 32767, 48, 0, 0 },
+ 0, 0, 476, 240, 0, 0, 0, 0, -56
+ },
+ { /* articulation 29 */
+ { 32767, 32498, 0, 32492 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 476, 0, 0, 0, 0, 0, -37
+ },
+ { /* articulation 30 */
+ { 32767, 29434, 0, 29434 },
+ { 32767, 1902, 0, 0 },
+ 0, 0, 476, 0, 0, 0, 0, 0, 50
+ },
+ { /* articulation 31 */
+ { 32767, 27897, 0, 27897 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 476, 0, 0, 0, 0, 0, -50
+ },
+ { /* articulation 32 */
+ { 32767, 31056, 0, 31056 },
+ { 32767, 1902, 0, 0 },
+ 0, 0, 476, 0, 0, 0, 0, 0, -50
+ },
+ { /* articulation 33 */
+ { 32767, 31479, 0, 31476 },
+ { 32767, 1902, 0, 0 },
+ 0, 0, 476, 0, 0, 0, 0, 0, -44
+ },
+ { /* articulation 34 */
+ { 32767, 32663, 0, 32663 },
+ { 32767, 127, 0, 0 },
+ 0, 0, 476, 0, 0, 0, 0, 0, 25
+ },
+ { /* articulation 35 */
+ { 32767, 0, 32767, 32715 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 476, 0, 0, 0, 0, 0, -63
+ },
+ { /* articulation 36 */
+ { 1902, 27897, 0, 27897 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 476, 0, 0, 0, 0, 0, -63
+ },
+ { /* articulation 37 */
+ { 32767, 27897, 0, 27897 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 476, 0, 0, 0, 0, 0, -59
+ },
+ { /* articulation 38 */
+ { 32767, 31730, 0, 31730 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 476, 0, 0, 0, 0, 0, 50
+ },
+ { /* articulation 39 */
+ { 32767, 30725, 0, 30725 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 476, 0, 0, 0, 0, 0, 44
+ },
+ { /* articulation 40 */
+ { 951, 31730, 0, 31730 },
+ { 32767, 190, 0, 0 },
+ 0, 0, 476, -100, 0, 0, 0, 0, 44
+ },
+ { /* articulation 41 */
+ { 32767, 17213, 0, 17213 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 476, 0, 0, 0, 0, 0, 25
+ },
+ { /* articulation 42 */
+ { 32767, 31295, 0, 31295 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 476, 0, 0, 0, 0, 0, 63
+ },
+ { /* articulation 43 */
+ { 32767, 31479, 0, 31476 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 476, 0, 0, 0, 0, 0, 63
+ },
+ { /* articulation 44 */
+ { 9511, 25581, 0, 25581 },
+ { 476, 32767, 32767, 0 },
+ 0, 0, 476, 100, 0, 0, 0, 0, -25
+ },
+ { /* articulation 45 */
+ { 1902, 23749, 0, 23749 },
+ { 476, 32767, 32767, 0 },
+ 0, 0, 476, 500, 0, 0, 0, 0, -25
+ },
+ { /* articulation 46 */
+ { 32767, 23749, 0, 23749 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 476, 0, 0, 0, 0, 0, -56
+ },
+ { /* articulation 47 */
+ { 32767, 31730, 0, 31730 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 476, 0, 0, 0, 0, 0, -56
+ },
+ { /* articulation 48 */
+ { 32767, 0, 32767, 0 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 476, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 49 */
+ { 32767, 31964, 0, 31964 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 476, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 50 */
+ { 9511, 32363, 0, 32418 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 476, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 51 */
+ { 32767, 31180, 0, 31180 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 476, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 52 */
+ { 32767, 32251, 0, 32052 },
+ { 32767, 147, 0, 0 },
+ 0, 0, 476, 0, 10000, 7121, 0, 0, 0
+ },
+ { /* articulation 53 */
+ { 32767, 0, 32767, 32072 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 778, 0, -2300, 11920, 0, 0, 0
+ },
+ { /* articulation 54 */
+ { 587, 0, 32767, 32376 },
+ { 32767, 63, 0, 0 },
+ 0, 0, 778, 0, 2000, 10721, 0, 8, 15
+ },
+ { /* articulation 55 */
+ { 587, 0, 32767, 32376 },
+ { 476, 63, 0, 0 },
+ 0, 0, 778, 0, 2000, 9023, 0, 5, 15
+ },
+ { /* articulation 56 */
+ { 3804, 0, 32767, 31477 },
+ { 32767, 34, 5898, 0 },
+ 0, 0, 778, 0, 6000, 9080, 0, 0, -2
+ },
+ { /* articulation 57 */
+ { 32767, 0, 32767, 31005 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 778, 0, 0, 0, 0, 0, 1
+ },
+ { /* articulation 58 */
+ { 2570, 0, 32767, 31455 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 778, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 59 */
+ { 32767, 32663, 0, 29434 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 476, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 60 */
+ { 32767, 32558, 0, 29434 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 476, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 61 */
+ { 32767, 32418, 0, 32418 },
+ { 32767, 48, 0, 0 },
+ 0, 69, 495, 0, 2400, 9521, 0, 0, 0
+ },
+ { /* articulation 62 */
+ { 32767, 31476, 0, 31476 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 476, 0, 0, 11738, 0, 16, 0
+ },
+ { /* articulation 63 */
+ { 32767, 32558, 0, 31391 },
+ { 32767, 317, 0, 0 },
+ 0, 69, 476, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 64 */
+ { 32767, 32245, 0, 32115 },
+ { 32767, 317, 0, 0 },
+ 0, 69, 476, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 65 */
+ { 32767, 32593, 0, 28809 },
+ { 32767, 48, 0, 0 },
+ 0, 69, 495, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 66 */
+ { 32767, 32408, 0, 32363 },
+ { 32767, 317, 0, 0 },
+ 0, 69, 476, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 67 */
+ { 32767, 32350, 0, 32350 },
+ { 32767, 317, 0, 0 },
+ 0, 69, 476, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 68 */
+ { 4755, 32715, 18820, 27897 },
+ { 951, 29, 13107, 0 },
+ 0, 0, 495, 0, 6000, 5535, 0, 4, 0
+ },
+ { /* articulation 69 */
+ { 32767, 32257, 0, 32245 },
+ { 32767, 951, 0, 0 },
+ 0, 103, 495, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 70 */
+ { 63, 32727, 3811, 32558 },
+ { 48, 19, 32767, 0 },
+ 0, 0, 495, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 71 */
+ { 2378, 32715, 3566, 30725 },
+ { 1902, 32767, 32767, 0 },
+ 0, 0, 495, 100, 0, 11919, 0, 0, 0
+ },
+ { /* articulation 72 */
+ { 32767, 32349, 0, 32349 },
+ { 32767, 168, 0, 0 },
+ 0, 34, 495, 0, 7000, 9023, 0, 0, 0
+ },
+ { /* articulation 73 */
+ { 32767, 32072, 0, 32072 },
+ { 32767, 168, 0, 0 },
+ 0, 3, 476, 0, 7000, 9023, 0, 0, 0
+ },
+ { /* articulation 74 */
+ { 32767, 32698, 6208, 32349 },
+ { 190, 48, 0, 0 },
+ 0, 0, 495, 0, 3840, 8302, 0, 8, 0
+ },
+ { /* articulation 75 */
+ { 32767, 32418, 0, 32468 },
+ { 32767, 190, 0, 0 },
+ 0, 0, 495, 0, 5000, 8321, 0, 0, 0
+ },
+ { /* articulation 76 */
+ { 32767, 32349, 0, 32349 },
+ { 32767, 190, 0, 0 },
+ 0, 0, 476, 0, 5000, 7934, 0, 0, 0
+ },
+ { /* articulation 77 */
+ { 32767, 32441, 0, 31709 },
+ { 32767, 32, 0, 0 },
+ 0, 34, 495, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 78 */
+ { 32767, 32505, 0, 27897 },
+ { 32767, 951, 0, 0 },
+ 0, 345, 495, 0, 1000, 11107, 0, 0, 0
+ },
+ { /* articulation 79 */
+ { 32767, 32715, 6208, 32349 },
+ { 48, 48, 0, 0 },
+ 0, 69, 811, 0, 3560, 8834, 1, 8, 0
+ },
+ { /* articulation 80 */
+ { 32767, 32564, 0, 29434 },
+ { 32767, 95, 0, 0 },
+ 0, 34, 495, 0, 6000, 9907, 0, 0, 0
+ },
+ { /* articulation 81 */
+ { 32767, 32505, 0, 27897 },
+ { 32767, 32, 0, 0 },
+ 0, 34, 495, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 82 */
+ { 32767, 32245, 18820, 17213 },
+ { 32767, 32767, 32767, 0 },
+ 0, 34, 495, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 83 */
+ { 32767, 32742, 128, 32466 },
+ { 32767, 63, 0, 0 },
+ 0, 0, 495, 0, 0, 11920, 0, 8, 0
+ },
+ { /* articulation 84 */
+ { 32767, 32418, 0, 32418 },
+ { 32767, 33, 0, 0 },
+ 3, 0, 286, 0, 5000, 5535, 0, 0, 0
+ },
+ { /* articulation 85 */
+ { 1902, 32715, 18820, 27897 },
+ { 32767, 1012, 0, 0 },
+ 10, 69, 504, -30, 0, 0, 0, 0, 0
+ },
+ { /* articulation 86 */
+ { 9511, 32715, 18820, 27897 },
+ { 380, 48, 0, 0 },
+ 0, 69, 495, 0, 4473, 7131, 0, 8, 0
+ },
+ { /* articulation 87 */
+ { 951, 32698, 6208, 32468 },
+ { 317, 19, 16384, 0 },
+ 0, 0, 495, 0, 2987, 7877, 0, 12, 0
+ },
+ { /* articulation 88 */
+ { 32767, 32680, 0, 32349 },
+ { 32767, 48, 0, 0 },
+ 0, 0, 581, 0, 4053, 7930, 2, 12, 0
+ },
+ { /* articulation 89 */
+ { 190, 32726, 6208, 32349 },
+ { 32767, 56, 0, 0 },
+ 0, 0, 495, 0, 0, 8887, 0, 0, 0
+ },
+ { /* articulation 90 */
+ { 9511, 32715, 18820, 27897 },
+ { 634, 48, 0, 0 },
+ 0, 69, 495, 0, 5113, 7981, 0, 4, 0
+ },
+ { /* articulation 91 */
+ { 951, 32715, 6208, 31730 },
+ { 951, 63, 0, 0 },
+ 0, 69, 495, 0, 3500, 7877, 0, 5, 0
+ },
+ { /* articulation 92 */
+ { 951, 32715, 6208, 31730 },
+ { 634, 48, 0, 0 },
+ 0, 69, 476, 0, 4773, 8355, 0, 5, 0
+ },
+ { /* articulation 93 */
+ { 238, 32715, 10809, 32349 },
+ { 32767, 32767, 32767, 0 },
+ 0, 69, 495, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 94 */
+ { 1902, 32715, 18820, 31476 },
+ { 32767, 32767, 32767, 0 },
+ 0, 69, 495, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 95 */
+ { 3804, 32715, 18820, 23749 },
+ { 1268, 130, 0, 0 },
+ 0, 69, 495, 0, 1200, 11690, 0, 4, 0
+ },
+ { /* articulation 96 */
+ { 19021, 32618, 15076, 31476 },
+ { 32767, 32767, 32767, 0 },
+ 0, 72, 1091, 0, 0, 11919, 1, 0, 0
+ },
+ { /* articulation 97 */
+ { 32767, 0, 32767, 32715 },
+ { 190, 32767, 32767, 0 },
+ 0, 0, 495, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 98 */
+ { 32767, 32072, 0, 32072 },
+ { 32767, 317, 0, 0 },
+ 0, 0, 495, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 99 */
+ { 32767, 32663, 0, 27897 },
+ { 634, 95, 13107, 0 },
+ 0, 69, 495, 0, 3200, 8321, 0, 0, 0
+ },
+ { /* articulation 100 */
+ { 32767, 0, 32767, 0 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 495, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 101 */
+ { 32767, 32418, 0, 27897 },
+ { 32767, 543, 0, 0 },
+ 0, 69, 495, 0, 8187, 5535, 0, 5, 0
+ },
+ { /* articulation 102 */
+ { 19021, 32663, 0, 31056 },
+ { 32767, 95, 7667, 0 },
+ 5, 0, 495, 0, 6053, 5535, 0, 5, 0
+ },
+ { /* articulation 103 */
+ { 32767, 32715, 18820, 27897 },
+ { 951, 48, 0, 0 },
+ 0, 0, 495, 0, 2700, 9852, 0, 0, 0
+ },
+ { /* articulation 104 */
+ { 32767, 32715, 18820, 30234 },
+ { 951, 48, 0, 0 },
+ 0, 0, 495, 0, 2700, 9852, 0, 0, 0
+ },
+ { /* articulation 105 */
+ { 32767, 32715, 18820, 27897 },
+ { 32767, 634, 0, 0 },
+ 0, 103, 476, 0, 2500, 10490, 1, 8, 0
+ },
+ { /* articulation 106 */
+ { 32767, 32715, 23493, 27897 },
+ { 32767, 190, 0, 0 },
+ 0, 69, 494, 0, 4000, 10223, 1, 4, 0
+ },
+ { /* articulation 107 */
+ { 32767, 32715, 18820, 30234 },
+ { 32767, 63, 7667, 0 },
+ 0, 0, 495, 0, 1813, 9154, 0, 0, 0
+ },
+ { /* articulation 108 */
+ { 19021, 32245, 0, 32245 },
+ { 32767, 190, 0, 0 },
+ 0, 0, 476, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 109 */
+ { 32767, 31964, 0, 31605 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 476, 0, 0, 11690, 0, 0, 0
+ },
+ { /* articulation 110 */
+ { 32767, 31730, 0, 31730 },
+ { 32767, 190, 0, 0 },
+ 0, 0, 476, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 111 */
+ { 32767, 32558, 18820, 30234 },
+ { 32767, 48, 0, 0 },
+ 12, 69, 476, 0, 3000, 10223, 0, 0, 0
+ },
+ { /* articulation 112 */
+ { 32767, 32558, 18820, 30234 },
+ { 32767, 32, 0, 0 },
+ 12, 69, 476, 0, 1900, 10031, 0, 0, 0
+ },
+ { /* articulation 113 */
+ { 32767, 32715, 18820, 29434 },
+ { 32767, 32, 0, 0 },
+ 12, 69, 494, 0, 1000, 11107, 0, 0, 0
+ },
+ { /* articulation 114 */
+ { 32767, 32715, 18820, 29434 },
+ { 32767, 32, 0, 0 },
+ 12, 69, 494, 0, 2000, 11107, 0, 0, 0
+ },
+ { /* articulation 115 */
+ { 32767, 32636, 0, 29434 },
+ { 32767, 95, 0, 0 },
+ 0, 34, 495, 0, 4000, 8321, 0, 0, 0
+ },
+ { /* articulation 116 */
+ { 32767, 32297, 19893, 17213 },
+ { 32767, 238, 0, 0 },
+ 0, 69, 726, 0, 0, 11919, 0, 0, 0
+ },
+ { /* articulation 117 */
+ { 9511, 32418, 23493, 17213 },
+ { 32767, 32767, 32767, 0 },
+ 0, 69, 678, 0, 0, 11877, 1, 0, 0
+ },
+ { /* articulation 118 */
+ { 32767, 32618, 0, 27897 },
+ { 32767, 95, 0, 0 },
+ 0, 69, 495, 0, 3500, 9023, 0, 0, 0
+ },
+ { /* articulation 119 */
+ { 32767, 23749, 23493, 0 },
+ { 32767, 32767, 32767, 0 },
+ 0, 34, 761, 0, 0, 10925, 1, 0, 0
+ },
+ { /* articulation 120 */
+ { 32767, 32636, 0, 29434 },
+ { 32767, 95, 0, 0 },
+ 0, 103, 495, 0, 3200, 8721, 0, 4, 0
+ },
+ { /* articulation 121 */
+ { 1902, 32715, 18820, 27897 },
+ { 32767, 32767, 32767, 0 },
+ 0, 69, 495, 0, 0, 0, 1, 0, 0
+ },
+ { /* articulation 122 */
+ { 4755, 32715, 18820, 28809 },
+ { 32767, 32767, 32767, 0 },
+ 0, 69, 495, 0, 0, 11877, 0, 8, 0
+ },
+ { /* articulation 123 */
+ { 32767, 32715, 18820, 27897 },
+ { 32767, 16, 0, 0 },
+ 0, 34, 495, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 124 */
+ { 32767, 32663, 0, 27897 },
+ { 32767, 190, 0, 0 },
+ 0, 69, 495, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 125 */
+ { 32767, 32715, 18820, 27897 },
+ { 32767, 12, 0, 0 },
+ 0, 34, 495, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 126 */
+ { 32767, 31730, 0, 31730 },
+ { 32767, 380, 0, 0 },
+ 0, 0, 495, 0, 3000, 10223, 0, 8, 0
+ },
+ { /* articulation 127 */
+ { 63, 0, 32767, 32558 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 761, 0, 0, 11423, 4, 0, 0
+ },
+ { /* articulation 128 */
+ { 476, 32595, 0, 32577 },
+ { 32767, 10, 0, 0 },
+ 0, 0, 495, 0, 0, 11423, 0, 0, 0
+ },
+ { /* articulation 129 */
+ { 196, 0, 0, 31964 },
+ { 95, 32767, 32767, 0 },
+ 0, 0, 495, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 130 */
+ { 32767, 31730, 0, 31730 },
+ { 32767, 380, 0, 0 },
+ 0, 0, 495, 1200, 0, 0, 0, 0, 0
+ },
+ { /* articulation 131 */
+ { 32767, 32245, 0, 32349 },
+ { 32767, 190, 0, 0 },
+ 0, 0, 495, 50, 0, 0, 0, 0, 0
+ },
+ { /* articulation 132 */
+ { 32767, 32418, 0, 32418 },
+ { 32767, 9511, 0, 0 },
+ 0, 0, 495, 0, 4700, 7769, 0, 0, 0
+ },
+ { /* articulation 133 */
+ { 32767, 31391, 0, 31391 },
+ { 32767, 19021, 0, 0 },
+ 0, 0, 495, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 134 */
+ { 32767, 32663, 32767, 32663 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 476, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 135 */
+ { 32767, 32715, 18820, 23749 },
+ { 32767, 95, 0, 0 },
+ 10, 68, 476, 0, 2000, 10696, 0, 0, 0
+ },
+ { /* articulation 136 */
+ { 32767, 32715, 10809, 23749 },
+ { 32767, 95, 0, 0 },
+ 12, 69, 491, 0, 0, 10910, 0, 0, 0
+ },
+ { /* articulation 137 */
+ { 32767, 32715, 18820, 23749 },
+ { 32767, 95, 0, 0 },
+ 10, 69, 476, 0, 1200, 10218, 0, 0, 0
+ },
+ { /* articulation 138 */
+ { 19021, 32715, 18820, 23749 },
+ { 32767, 95, 0, 0 },
+ 10, 69, 476, 0, 1100, 9525, 0, 0, 0
+ },
+ { /* articulation 139 */
+ { 9511, 32663, 18820, 27897 },
+ { 32767, 10, 0, 0 },
+ 10, 69, 494, 0, 2000, 10962, 0, 0, 0
+ },
+ { /* articulation 140 */
+ { 32767, 32558, 18820, 27897 },
+ { 9511, 317, 0, 0 },
+ 10, 63, 504, 0, 1200, 10090, 0, 0, 0
+ },
+ { /* articulation 141 */
+ { 1268, 0, 32767, 30234 },
+ { 951, 190, 0, 0 },
+ 7, 69, 494, 0, 1620, 8933, 0, 0, 0
+ },
+ { /* articulation 142 */
+ { 32767, 32558, 10809, 27897 },
+ { 19021, 190, 0, 0 },
+ 7, 69, 494, 0, 2200, 8994, 0, 0, 0
+ },
+ { /* articulation 143 */
+ { 32767, 32715, 15076, 27897 },
+ { 32767, 951, 0, 0 },
+ 10, 69, 491, 0, 2500, 9525, 0, 0, 0
+ },
+ { /* articulation 144 */
+ { 32767, 32715, 15076, 27897 },
+ { 32767, 95, 0, 0 },
+ 10, 69, 476, 0, 1500, 11423, 0, 0, 0
+ },
+ { /* articulation 145 */
+ { 32767, 32715, 18820, 27897 },
+ { 32767, 951, 0, 0 },
+ 9, 69, 491, 0, 1500, 9521, 0, 0, 0
+ },
+ { /* articulation 146 */
+ { 1902, 0, 32767, 30725 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 761, 0, 0, 9521, 0, 0, 0
+ },
+ { /* articulation 147 */
+ { 32767, 32663, 0, 27897 },
+ { 32767, 9511, 0, 0 },
+ 0, 34, 495, 0, 5000, 10223, 0, 0, 0
+ },
+ { /* articulation 148 */
+ { 32767, 32715, 18820, 27897 },
+ { 32767, 32, 0, 0 },
+ 10, 69, 476, 0, 1500, 9907, 0, 0, 0
+ },
+ { /* articulation 149 */
+ { 32767, 32733, 11682, 27897 },
+ { 32767, 951, 0, 0 },
+ 0, 69, 476, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 150 */
+ { 32767, 32418, 0, 32418 },
+ { 32767, 190, 0, 0 },
+ 0, 34, 495, 0, 3440, 9260, 0, 0, 0
+ },
+ { /* articulation 151 */
+ { 32767, 31476, 0, 31730 },
+ { 32767, 951, 0, 0 },
+ 0, 34, 495, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 152 */
+ { 32767, 32245, 0, 31730 },
+ { 32767, 190, 0, 0 },
+ 0, 34, 495, 0, 4000, 7823, 0, 0, 0
+ },
+ { /* articulation 153 */
+ { 32767, 32663, 3566, 27897 },
+ { 391, 32767, 32767, 0 },
+ 100, 0, 761, 500, 0, 11877, 0, 0, 0
+ },
+ { /* articulation 154 */
+ { 32767, 32715, 18820, 23749 },
+ { 32767, 951, 0, 0 },
+ 8, 69, 495, -22, 0, 0, 0, 0, 0
+ },
+ { /* articulation 155 */
+ { 9511, 30830, 6784, 27897 },
+ { 32767, 951, 0, 0 },
+ 0, 69, 476, 0, 5000, 9521, 1, 0, 0
+ },
+ { /* articulation 156 */
+ { 32767, 32663, 0, 32349 },
+ { 951, 127, 16384, 0 },
+ 0, 103, 495, 0, 3627, 10547, 0, 5, 0
+ },
+ { /* articulation 157 */
+ { 1902, 0, 32767, 27897 },
+ { 951, 951, 0, 0 },
+ 0, 69, 495, 27, 0, 11919, 0, 0, 0
+ },
+ { /* articulation 158 */
+ { 32767, 0, 32767, 32245 },
+ { 38, 33, 10092, 0 },
+ 5, 0, 495, 0, 8007, 5535, 0, 8, 0
+ },
+ { /* articulation 159 */
+ { 32767, 32618, 0, 31056 },
+ { 32767, 63, 0, 0 },
+ 0, 103, 495, 0, 2500, 9032, 0, 0, 0
+ },
+ { /* articulation 160 */
+ { 4755, 32715, 10809, 28809 },
+ { 32767, 32767, 32767, 0 },
+ 0, 69, 495, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 161 */
+ { 9511, 32663, 18820, 27897 },
+ { 32767, 95, 0, 0 },
+ 10, 69, 494, 0, 2600, 9513, 0, 0, 0
+ },
+ { /* articulation 162 */
+ { 32767, 32435, 9568, 27897 },
+ { 1174, 196, 0, 0 },
+ 10, 103, 490, 0, 6500, 9023, 0, 0, 0
+ },
+ { /* articulation 163 */
+ { 32767, 32663, 0, 29434 },
+ { 32767, 32, 0, 0 },
+ 0, 69, 495, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 164 */
+ { 32767, 32418, 15076, 23749 },
+ { 32767, 634, 0, 0 },
+ 0, 0, 476, 0, 2000, 10223, 0, 0, 0
+ },
+ { /* articulation 165 */
+ { 32767, 32663, 0, 27897 },
+ { 32767, 190, 0, 0 },
+ 0, 69, 495, 0, 3000, 9366, 0, 0, 0
+ },
+ { /* articulation 166 */
+ { 32767, 32715, 18820, 27897 },
+ { 951, 64, 10879, 0 },
+ 0, 0, 495, 0, 6000, 7121, 0, 4, 0
+ },
+ { /* articulation 167 */
+ { 32767, 32636, 0, 29434 },
+ { 32767, 10, 0, 0 },
+ 0, 103, 495, 0, 3500, 6236, 0, 5, 0
+ },
+ { /* articulation 168 */
+ { 32767, 32636, 0, 29434 },
+ { 32767, 95, 0, 0 },
+ 0, 103, 495, 0, 2800, 7121, 0, 0, 0
+ },
+ { /* articulation 169 */
+ { 32767, 32593, 0, 31056 },
+ { 32767, 63, 0, 0 },
+ 0, 103, 495, 0, 2100, 9626, 0, 0, 0
+ },
+ { /* articulation 170 */
+ { 32767, 32558, 0, 31476 },
+ { 32767, 63, 0, 0 },
+ 0, 103, 495, 0, 3000, 9626, 0, 0, 0
+ },
+ { /* articulation 171 */
+ { 32767, 32527, 0, 30506 },
+ { 32767, 63, 0, 0 },
+ 0, 103, 495, 0, 1000, 9032, 0, 0, 0
+ },
+ { /* articulation 172 */
+ { 32767, 32418, 0, 30725 },
+ { 32767, 63, 0, 0 },
+ 0, 103, 495, 0, 1000, 9032, 0, 0, 0
+ },
+ { /* articulation 173 */
+ { 1902, 32418, 15076, 23749 },
+ { 32767, 634, 0, 0 },
+ 0, 103, 496, 0, 0, 11107, 0, 8, 0
+ },
+ { /* articulation 174 */
+ { 32767, 32558, 15076, 27897 },
+ { 3804, 73, 0, 0 },
+ 0, 0, 495, 0, 4500, 9521, 0, 8, 0
+ },
+ { /* articulation 175 */
+ { 32767, 32715, 18820, 27897 },
+ { 32767, 48, 0, 0 },
+ 0, 0, 495, 0, 2000, 8321, 0, 8, 0
+ },
+ { /* articulation 176 */
+ { 32767, 32742, 128, 31180 },
+ { 32767, 865, 0, 0 },
+ 0, 0, 495, 0, 6000, 7823, 0, 8, 0
+ },
+ { /* articulation 177 */
+ { 9511, 32608, 0, 32322 },
+ { 32767, 48, 0, 0 },
+ 0, 0, 495, 0, 4500, 7121, 0, 8, 0
+ },
+ { /* articulation 178 */
+ { 19021, 32664, 3646, 32436 },
+ { 32767, 95, 0, 0 },
+ 0, 0, 495, 0, 4000, 8321, 0, 8, 0
+ },
+ { /* articulation 179 */
+ { 32767, 32685, 13644, 29434 },
+ { 32767, 32, 0, 0 },
+ 12, 69, 494, 0, 2000, 11107, 0, 0, 0
+ },
+ { /* articulation 180 */
+ { 9511, 31605, 0, 27897 },
+ { 32767, 951, 0, 0 },
+ 0, 0, 495, 0, 5000, 8321, 1, 0, 0
+ },
+ { /* articulation 181 */
+ { 130, 32617, 0, 32350 },
+ { 32767, 317, 0, 0 },
+ 0, 69, 476, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 182 */
+ { 32767, 32593, 0, 32251 },
+ { 1174, 20, 0, 0 },
+ 0, 69, 495, 0, 3600, 7121, 0, 4, 0
+ },
+ { /* articulation 183 */
+ { 32767, 32427, 0, 32427 },
+ { 32767, 317, 0, 0 },
+ 0, 69, 476, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 184 */
+ { 834, 32742, 19242, 31455 },
+ { 32767, 148, 0, 0 },
+ 0, 0, 778, 0, 3000, 9907, 0, 4, 0
+ }
+}; /*end Articulations */
+
+/*----------------------------------------------------------------------------
+ * Regions
+ *----------------------------------------------------------------------------
+*/
+const S_WT_REGION eas_regions[] =
+{
+ { { 0, 27, 27 }, -4068, 16422, 0, 0, 81, 0 }, /* region 0 */
+ { { 0, 28, 28 }, -4768, 32767, 0, 0, 40, 0 }, /* region 1 */
+ { { 0, 29, 29 }, -5753, 32767, 0, 0, 32, 1 }, /* region 2 */
+ { { 0, 30, 30 }, -6053, 32767, 0, 0, 32, 2 }, /* region 3 */
+ { { 0, 31, 31 }, -5068, 23197, 0, 0, 48, 3 }, /* region 4 */
+ { { 1536, 32, 32 }, -4400, 20675, 0, 0, 137, 4 }, /* region 5 */
+ { { 1537, 33, 33 }, -4903, 20675, 792, 879, 50, 5 }, /* region 6 */
+ { { 1537, 34, 34 }, -5003, 16422, 792, 879, 50, 6 }, /* region 7 */
+ { { 0, 35, 35 }, -6168, 32767, 0, 0, 83, 7 }, /* region 8 */
+ { { 0, 36, 36 }, -6168, 32767, 0, 0, 83, 7 }, /* region 9 */
+ { { 0, 37, 37 }, -5251, 18426, 0, 0, 53, 8 }, /* region 10 */
+ { { 0, 38, 38 }, -5351, 23197, 0, 0, 16, 9 }, /* region 11 */
+ { { 0, 39, 39 }, -4768, 32767, 0, 0, 40, 10 }, /* region 12 */
+ { { 0, 40, 40 }, -5351, 23197, 0, 0, 16, 4 }, /* region 13 */
+ { { 1, 41, 41 }, -7055, 26028, 798, 993, 45, 11 }, /* region 14 */
+ { { 257, 42, 42 }, -5400, 26028, 4288, 7488, 7, 12 }, /* region 15 */
+ { { 1, 43, 43 }, -6955, 26028, 798, 993, 45, 13 }, /* region 16 */
+ { { 257, 44, 44 }, -5600, 26028, 4288, 7488, 7, 14 }, /* region 17 */
+ { { 1, 45, 45 }, -6955, 26028, 798, 993, 45, 15 }, /* region 18 */
+ { { 257, 46, 46 }, -5800, 26028, 4288, 7488, 7, 16 }, /* region 19 */
+ { { 1, 47, 47 }, -6655, 26028, 798, 993, 45, 17 }, /* region 20 */
+ { { 1, 48, 48 }, -6555, 26028, 798, 993, 45, 18 }, /* region 21 */
+ { { 1, 49, 49 }, -6400, 16422, 1294, 5778, 8, 19 }, /* region 22 */
+ { { 1, 50, 50 }, -6455, 26028, 798, 993, 45, 20 }, /* region 23 */
+ { { 1, 51, 51 }, -6468, 16422, 6592, 9921, 6, 21 }, /* region 24 */
+ { { 1, 52, 52 }, -6800, 32767, 1294, 5778, 8, 22 }, /* region 25 */
+ { { 1, 53, 53 }, -6618, 14636, 6592, 9921, 6, 23 }, /* region 26 */
+ { { 0, 54, 54 }, -6951, 26028, 0, 0, 39, 24 }, /* region 27 */
+ { { 1, 55, 55 }, -6500, 32767, 1294, 5778, 8, 25 }, /* region 28 */
+ { { 0, 56, 56 }, -8455, 32767, 0, 0, 90, 26 }, /* region 29 */
+ { { 1, 57, 57 }, -6900, 32767, 1294, 5778, 8, 27 }, /* region 30 */
+ { { 1, 58, 58 }, -8253, 23197, 0, 166, 113, 28 }, /* region 31 */
+ { { 1, 59, 59 }, -7168, 16422, 6592, 9921, 6, 29 }, /* region 32 */
+ { { 1, 60, 60 }, -7653, 23197, 432, 582, 63, 30 }, /* region 33 */
+ { { 1, 61, 61 }, -8053, 16422, 432, 582, 63, 30 }, /* region 34 */
+ { { 1, 62, 62 }, -8453, 20675, 432, 582, 63, 31 }, /* region 35 */
+ { { 1, 63, 63 }, -8553, 23197, 432, 582, 63, 32 }, /* region 36 */
+ { { 1, 64, 64 }, -9153, 23197, 432, 582, 63, 33 }, /* region 37 */
+ { { 0, 65, 65 }, -8755, 32767, 0, 0, 14, 34 }, /* region 38 */
+ { { 0, 66, 66 }, -9155, 20675, 0, 0, 14, 34 }, /* region 39 */
+ { { 512, 67, 67 }, -8355, 18426, 0, 0, 90, 35 }, /* region 40 */
+ { { 512, 68, 68 }, -8955, 18426, 0, 0, 90, 35 }, /* region 41 */
+ { { 0, 69, 69 }, -8955, 32767, 0, 0, 86, 36 }, /* region 42 */
+ { { 0, 70, 70 }, -8055, 21900, 0, 0, 86, 37 }, /* region 43 */
+ { { 769, 71, 71 }, -7555, 23197, 0, 1226, 35, 38 }, /* region 44 */
+ { { 769, 72, 72 }, -8155, 26028, 0, 1226, 35, 38 }, /* region 45 */
+ { { 1024, 73, 73 }, -9155, 32767, 0, 0, 22, 39 }, /* region 46 */
+ { { 1024, 74, 74 }, -9655, 32767, 0, 0, 22, 40 }, /* region 47 */
+ { { 1, 75, 75 }, -9100, 23197, 0, 31, 139, 41 }, /* region 48 */
+ { { 0, 76, 76 }, -11655, 23197, 0, 0, 134, 42 }, /* region 49 */
+ { { 0, 77, 77 }, -11255, 23197, 0, 0, 134, 43 }, /* region 50 */
+ { { 0, 78, 78 }, -10053, 16422, 0, 0, 89, 44 }, /* region 51 */
+ { { 0, 79, 79 }, -11453, 16422, 0, 0, 89, 45 }, /* region 52 */
+ { { 1281, 80, 80 }, -7500, 13045, 209, 230, 103, 46 }, /* region 53 */
+ { { 1281, 81, 81 }, -7600, 16422, 209, 230, 103, 47 }, /* region 54 */
+ { { 0, 82, 82 }, -9655, 20675, 0, 0, 87, 48 }, /* region 55 */
+ { { 0, 83, 83 }, -10100, 32767, 0, 0, 13, 49 }, /* region 56 */
+ { { 1, 84, 84 }, -9600, 23197, 0, 10294, 5, 50 }, /* region 57 */
+ { { 0, 85, 85 }, -10855, 32767, 0, 0, 135, 4 }, /* region 58 */
+ { { 0, 86, 86 }, -10268, 16422, 0, 0, 24, 51 }, /* region 59 */
+ { { 32769, 87, 87 }, -10368, 32767, 1335, 1603, 24, 52 }, /* region 60 */
+ { { 1, 12, 67 }, -7805, 23197, 437, 16584, 2, 48 }, /* region 61 */
+ { { 1, 68, 73 }, -8396, 23197, 452, 16803, 0, 48 }, /* region 62 */
+ { { 32769, 74, 108 }, -9667, 23197, 404, 16698, 1, 48 }, /* region 63 */
+ { { 1, 12, 78 }, -7805, 16422, 437, 16584, 2, 48 }, /* region 64 */
+ { { 1, 79, 91 }, -8396, 16422, 452, 16803, 0, 48 }, /* region 65 */
+ { { 32769, 92, 108 }, -9667, 16422, 404, 16698, 1, 48 }, /* region 66 */
+ { { 1, 12, 78 }, -7805, 16422, 437, 16584, 2, 48 }, /* region 67 */
+ { { 1, 79, 91 }, -8396, 16422, 452, 16803, 0, 48 }, /* region 68 */
+ { { 32769, 92, 108 }, -9667, 16422, 404, 16698, 1, 48 }, /* region 69 */
+ { { 1, 12, 70 }, -7800, 23197, 437, 16584, 2, 48 }, /* region 70 */
+ { { 1, 71, 88 }, -8391, 23197, 452, 16803, 0, 48 }, /* region 71 */
+ { { 32769, 89, 108 }, -9662, 23197, 404, 16698, 1, 48 }, /* region 72 */
+ { { 1, 12, 54 }, -7156, 13045, 639, 4368, 10, 48 }, /* region 73 */
+ { { 32769, 55, 108 }, -7551, 18426, 702, 3112, 12, 48 }, /* region 74 */
+ { { 1, 12, 66 }, -7811, 23197, 437, 16584, 2, 48 }, /* region 75 */
+ { { 1, 67, 87 }, -8402, 23197, 452, 16803, 0, 48 }, /* region 76 */
+ { { 32769, 88, 108 }, -9673, 16422, 404, 16698, 1, 48 }, /* region 77 */
+ { { 1, 12, 43 }, -4255, 23197, 920, 1383, 30, 59 }, /* region 78 */
+ { { 32769, 44, 96 }, -6260, 18426, 885, 1176, 37, 59 }, /* region 79 */
+ { { 1, 12, 48 }, -4661, 18426, 1148, 1514, 26, 60 }, /* region 80 */
+ { { 32769, 49, 96 }, -7453, 16422, 1347, 1420, 29, 60 }, /* region 81 */
+ { { 1, 33, 56 }, -6800, 26028, 1064, 1170, 38, 61 }, /* region 82 */
+ { { 1, 57, 72 }, -7200, 26028, 930, 1014, 44, 61 }, /* region 83 */
+ { { 32769, 73, 108 }, -8800, 26028, 726, 826, 52, 61 }, /* region 84 */
+ { { 1, 36, 96 }, -8800, 20675, 635, 735, 58, 62 }, /* region 85 */
+ { { 32769, 97, 108 }, -11308, 13045, 0, 31, 139, 62 }, /* region 86 */
+ { { 1, 36, 96 }, -8800, 14636, 635, 735, 58, 0 }, /* region 87 */
+ { { 32769, 97, 108 }, -11308, 13045, 0, 31, 139, 0 }, /* region 88 */
+ { { 1, 36, 83 }, -7206, 13045, 838, 922, 47, 63 }, /* region 89 */
+ { { 1, 84, 93 }, -9606, 14636, 209, 230, 103, 63 }, /* region 90 */
+ { { 32769, 94, 108 }, -11308, 13045, 0, 31, 139, 63 }, /* region 91 */
+ { { 1, 36, 83 }, -7206, 13045, 838, 922, 47, 64 }, /* region 92 */
+ { { 1, 84, 93 }, -9606, 13045, 209, 230, 103, 64 }, /* region 93 */
+ { { 32769, 94, 108 }, -11308, 13045, 0, 31, 139, 64 }, /* region 94 */
+ { { 1, 21, 56 }, -6795, 23197, 1064, 1170, 38, 65 }, /* region 95 */
+ { { 1, 57, 72 }, -7195, 23197, 930, 1014, 44, 65 }, /* region 96 */
+ { { 32769, 73, 108 }, -8798, 23197, 726, 826, 52, 65 }, /* region 97 */
+ { { 1, 12, 83 }, -7206, 16422, 838, 922, 47, 66 }, /* region 98 */
+ { { 1, 84, 93 }, -9606, 16422, 209, 230, 103, 66 }, /* region 99 */
+ { { 32769, 94, 108 }, -11308, 16422, 0, 31, 139, 66 }, /* region 100 */
+ { { 1, 24, 83 }, -7206, 16422, 838, 922, 47, 67 }, /* region 101 */
+ { { 1, 84, 93 }, -9606, 16422, 209, 230, 103, 67 }, /* region 102 */
+ { { 32769, 94, 108 }, -11308, 16422, 0, 31, 139, 67 }, /* region 103 */
+ { { 1, 12, 83 }, -7220, 16422, 0, 83, 126, 68 }, /* region 104 */
+ { { 1, 84, 90 }, -9682, 16422, 0, 20, 145, 68 }, /* region 105 */
+ { { 32769, 91, 108 }, -10301, 16422, 6, 20, 147, 68 }, /* region 106 */
+ { { 1, 21, 75 }, -8441, 16422, 419, 460, 76, 69 }, /* region 107 */
+ { { 32769, 76, 108 }, -10890, 14636, 254, 264, 101, 69 }, /* region 108 */
+ { { 32769, 36, 84 }, -8955, 16422, 0, 2775, 17, 70 }, /* region 109 */
+ { { 32769, 12, 108 }, -7855, 23197, 30, 276, 100, 71 }, /* region 110 */
+ { { 0, 12, 60 }, -9114, 26028, 0, 0, 15, 72 }, /* region 111 */
+ { { 32768, 61, 96 }, -9114, 26028, 0, 0, 15, 73 }, /* region 112 */
+ { { 1, 12, 65 }, -8253, 16422, 23, 10953, 4, 74 }, /* region 113 */
+ { { 32769, 66, 108 }, -8955, 20675, 11, 11753, 3, 74 }, /* region 114 */
+ { { 1, 12, 35 }, -6555, 16422, 2869, 3778, 11, 75 }, /* region 115 */
+ { { 1, 36, 48 }, -7755, 20675, 2869, 3778, 11, 75 }, /* region 116 */
+ { { 32769, 49, 72 }, -7755, 20675, 2869, 3778, 11, 76 }, /* region 117 */
+ { { 1, 16, 55 }, -7424, 20675, 1045, 1119, 41, 77 }, /* region 118 */
+ { { 32769, 56, 96 }, -7918, 20675, 907, 963, 46, 77 }, /* region 119 */
+ { { 1, 16, 53 }, -7194, 29204, 1140, 1479, 27, 78 }, /* region 120 */
+ { { 1, 54, 70 }, -8371, 29204, 726, 812, 55, 78 }, /* region 121 */
+ { { 32769, 71, 108 }, -8988, 29204, 718, 748, 56, 78 }, /* region 122 */
+ { { 1, 12, 65 }, -8253, 16422, 23, 10953, 4, 79 }, /* region 123 */
+ { { 32769, 66, 108 }, -8955, 20675, 11, 11753, 3, 79 }, /* region 124 */
+ { { 1, 16, 54 }, -6927, 20675, 5362, 5461, 9, 80 }, /* region 125 */
+ { { 1, 55, 63 }, -7051, 26028, 1362, 1454, 28, 80 }, /* region 126 */
+ { { 32769, 64, 108 }, -7944, 16422, 311, 366, 88, 80 }, /* region 127 */
+ { { 1, 16, 48 }, -5998, 20675, 1132, 1301, 31, 81 }, /* region 128 */
+ { { 32769, 49, 108 }, -7188, 20675, 1099, 1184, 36, 81 }, /* region 129 */
+ { { 1, 21, 68 }, -9658, 20675, 87, 2170, 18, 82 }, /* region 130 */
+ { { 1, 69, 82 }, -10160, 20675, 120, 2167, 19, 82 }, /* region 131 */
+ { { 32769, 83, 108 }, -11360, 20675, 376, 2041, 20, 82 }, /* region 132 */
+ { { 1, 12, 65 }, -8253, 16422, 23, 10953, 4, 83 }, /* region 133 */
+ { { 32769, 66, 108 }, -8955, 20675, 11, 11753, 3, 83 }, /* region 134 */
+ { { 32769, 55, 108 }, -8568, 20675, 0, 477, 75, 84 }, /* region 135 */
+ { { 32769, 36, 96 }, -8100, 14636, 101, 151, 116, 85 }, /* region 136 */
+ { { 1, 24, 83 }, -7220, 13045, 0, 83, 126, 86 }, /* region 137 */
+ { { 1, 84, 90 }, -9682, 13045, 0, 20, 145, 86 }, /* region 138 */
+ { { 32769, 91, 108 }, -10301, 13045, 6, 20, 147, 86 }, /* region 139 */
+ { { 1, 12, 65 }, -8253, 16422, 23, 10953, 4, 87 }, /* region 140 */
+ { { 32769, 66, 108 }, -8955, 20675, 11, 11753, 3, 87 }, /* region 141 */
+ { { 1, 12, 65 }, -8253, 16422, 23, 10953, 4, 88 }, /* region 142 */
+ { { 32769, 66, 108 }, -8955, 20675, 11, 11753, 3, 88 }, /* region 143 */
+ { { 1, 12, 65 }, -8253, 16422, 23, 10953, 4, 89 }, /* region 144 */
+ { { 32769, 66, 108 }, -8955, 20675, 11, 11753, 3, 89 }, /* region 145 */
+ { { 1, 24, 83 }, -7220, 13045, 0, 83, 126, 90 }, /* region 146 */
+ { { 1, 84, 90 }, -9682, 13045, 0, 20, 145, 90 }, /* region 147 */
+ { { 32769, 91, 108 }, -10301, 13045, 6, 20, 147, 90 }, /* region 148 */
+ { { 1, 12, 65 }, -8253, 16422, 23, 10953, 4, 91 }, /* region 149 */
+ { { 32769, 66, 108 }, -8955, 20675, 11, 11753, 3, 91 }, /* region 150 */
+ { { 1, 12, 65 }, -8253, 16422, 23, 10953, 4, 92 }, /* region 151 */
+ { { 32769, 66, 108 }, -8955, 20675, 11, 11753, 3, 92 }, /* region 152 */
+ { { 1, 12, 62 }, -8253, 16422, 23, 10953, 4, 93 }, /* region 153 */
+ { { 32769, 63, 108 }, -8955, 20675, 11, 11753, 3, 93 }, /* region 154 */
+ { { 1, 12, 62 }, -8253, 16422, 23, 10953, 4, 94 }, /* region 155 */
+ { { 32769, 63, 108 }, -8955, 16422, 11, 11753, 3, 94 }, /* region 156 */
+ { { 1, 24, 79 }, -7220, 13045, 0, 83, 126, 95 }, /* region 157 */
+ { { 1, 80, 90 }, -9682, 13045, 0, 20, 145, 95 }, /* region 158 */
+ { { 32769, 91, 108 }, -10301, 13045, 6, 20, 147, 95 }, /* region 159 */
+ { { 1, 12, 65 }, -8253, 13045, 23, 10953, 4, 96 }, /* region 160 */
+ { { 32769, 66, 108 }, -8955, 16422, 11, 11753, 3, 96 }, /* region 161 */
+ { { 32768, 36, 84 }, -8700, 20675, 0, 0, 25, 97 }, /* region 162 */
+ { { 32769, 36, 96 }, -10055, 20675, 1482, 1613, 23, 98 }, /* region 163 */
+ { { 32769, 12, 96 }, -5566, 32767, 818, 1033, 42, 99 }, /* region 164 */
+ { { 32769, 36, 84 }, -9768, 18426, 0, 293, 98, 100 }, /* region 165 */
+ { { 32769, 12, 96 }, -7220, 26028, 0, 83, 125, 101 }, /* region 166 */
+ { { 32769, 12, 96 }, -7220, 20675, 0, 83, 125, 102 }, /* region 167 */
+ { { 1, 12, 83 }, -7220, 13045, 0, 83, 125, 104 }, /* region 168 */
+ { { 1, 84, 90 }, -9682, 13045, 0, 20, 146, 104 }, /* region 169 */
+ { { 32769, 91, 108 }, -10301, 13045, 6, 20, 148, 104 }, /* region 170 */
+ { { 32769, 36, 108 }, -9770, 32767, 472, 491, 74, 105 }, /* region 171 */
+ { { 32769, 36, 108 }, -9770, 20675, 472, 491, 74, 106 }, /* region 172 */
+ { { 1, 12, 72 }, -7212, 7336, 2, 86, 124, 107 }, /* region 173 */
+ { { 1, 73, 101 }, -9700, 8231, 2, 22, 143, 107 }, /* region 174 */
+ { { 32769, 102, 108 }, -10883, 20675, 173, 183, 110, 107 }, /* region 175 */
+ { { 1, 21, 96 }, -8968, 13045, 477, 507, 73, 108 }, /* region 176 */
+ { { 32769, 97, 108 }, -10883, 13045, 173, 183, 110, 109 }, /* region 177 */
+ { { 32769, 12, 108 }, -8971, 16422, 477, 507, 73, 110 }, /* region 178 */
+ { { 1, 12, 53 }, -6171, 16422, 388, 541, 68, 111 }, /* region 179 */
+ { { 32769, 54, 60 }, -7149, 11626, 473, 560, 65, 111 }, /* region 180 */
+ { { 32769, 36, 72 }, -7149, 16422, 473, 560, 65, 112 }, /* region 181 */
+ { { 1, 48, 58 }, -8253, 16422, 356, 402, 82, 113 }, /* region 182 */
+ { { 1, 59, 65 }, -8774, 16422, 514, 548, 67, 113 }, /* region 183 */
+ { { 1, 66, 78 }, -9374, 16422, 505, 529, 71, 113 }, /* region 184 */
+ { { 32769, 79, 96 }, -10433, 16422, 178, 191, 109, 113 }, /* region 185 */
+ { { 1, 55, 60 }, -8253, 16422, 356, 402, 82, 114 }, /* region 186 */
+ { { 1, 61, 69 }, -8774, 16422, 514, 548, 67, 114 }, /* region 187 */
+ { { 1, 70, 79 }, -9374, 16422, 505, 529, 71, 114 }, /* region 188 */
+ { { 32769, 80, 108 }, -10433, 16422, 178, 191, 109, 114 }, /* region 189 */
+ { { 1, 16, 82 }, -9229, 23197, 180, 206, 106, 115 }, /* region 190 */
+ { { 32769, 83, 108 }, -8440, 18426, 3, 44, 131, 115 }, /* region 191 */
+ { { 32769, 21, 108 }, -10069, 20675, 483, 515, 72, 116 }, /* region 192 */
+ { { 1, 21, 89 }, -8405, 18426, 3, 45, 130, 117 }, /* region 193 */
+ { { 32769, 90, 108 }, -10301, 10362, 6, 20, 148, 117 }, /* region 194 */
+ { { 1, 21, 42 }, -5886, 20675, 0, 180, 111, 118 }, /* region 195 */
+ { { 1, 43, 51 }, -6486, 23197, 0, 127, 120, 118 }, /* region 196 */
+ { { 1, 52, 58 }, -7492, 26028, 0, 71, 127, 118 }, /* region 197 */
+ { { 1, 59, 68 }, -8668, 23197, 0, 36, 136, 118 }, /* region 198 */
+ { { 32769, 69, 108 }, -9774, 20675, 0, 19, 149, 118 }, /* region 199 */
+ { { 1, 21, 89 }, -8399, 20675, 3, 45, 130, 119 }, /* region 200 */
+ { { 32769, 90, 108 }, -10301, 14636, 6, 20, 148, 119 }, /* region 201 */
+ { { 1, 21, 46 }, -6851, 26028, 236, 340, 92, 120 }, /* region 202 */
+ { { 1, 47, 71 }, -7763, 20675, 824, 885, 49, 120 }, /* region 203 */
+ { { 1, 72, 88 }, -9107, 18426, 719, 747, 57, 120 }, /* region 204 */
+ { { 1, 89, 93 }, -10076, 16422, 83, 99, 122, 120 }, /* region 205 */
+ { { 32769, 94, 108 }, -10889, 16422, 173, 183, 110, 120 }, /* region 206 */
+ { { 1, 60, 71 }, -8405, 16422, 0, 42, 132, 121 }, /* region 207 */
+ { { 1, 72, 78 }, -9103, 16422, 0, 28, 141, 121 }, /* region 208 */
+ { { 32769, 79, 96 }, -9605, 16422, 0, 21, 144, 121 }, /* region 209 */
+ { { 1, 48, 65 }, -7516, 11626, 0, 70, 128, 122 }, /* region 210 */
+ { { 1, 66, 79 }, -8924, 14636, 0, 31, 138, 122 }, /* region 211 */
+ { { 32769, 80, 96 }, -9230, 11626, 0, 26, 142, 122 }, /* region 212 */
+ { { 1, 16, 44 }, -7068, 14636, 163, 254, 102, 123 }, /* region 213 */
+ { { 1, 45, 51 }, -7618, 16422, 261, 393, 85, 123 }, /* region 214 */
+ { { 1, 52, 58 }, -8533, 18426, 190, 229, 104, 123 }, /* region 215 */
+ { { 1, 59, 66 }, -9300, 18426, 168, 193, 108, 123 }, /* region 216 */
+ { { 1, 67, 70 }, -9776, 18426, 138, 157, 115, 123 }, /* region 217 */
+ { { 1, 71, 80 }, -10303, 18426, 166, 180, 112, 123 }, /* region 218 */
+ { { 32769, 81, 108 }, -11274, 18426, 135, 151, 117, 123 }, /* region 219 */
+ { { 32769, 12, 96 }, -6204, 23197, 570, 719, 59, 124 }, /* region 220 */
+ { { 1, 12, 48 }, -7068, 14636, 163, 254, 102, 125 }, /* region 221 */
+ { { 1, 49, 54 }, -7618, 16422, 261, 393, 85, 125 }, /* region 222 */
+ { { 1, 55, 63 }, -8533, 18426, 190, 229, 104, 125 }, /* region 223 */
+ { { 1, 64, 70 }, -9300, 18426, 168, 193, 108, 125 }, /* region 224 */
+ { { 1, 71, 75 }, -9776, 18426, 138, 157, 115, 125 }, /* region 225 */
+ { { 1, 76, 82 }, -10303, 18426, 166, 180, 112, 125 }, /* region 226 */
+ { { 32769, 83, 108 }, -11274, 18426, 135, 151, 117, 125 }, /* region 227 */
+ { { 32770, 36, 84 }, -8400, 29204, 0, 0, 0, 126 }, /* region 228 */
+ { { 32770, 36, 84 }, -8800, 8231, 0, 0, 0, 127 }, /* region 229 */
+ { { 32770, 36, 84 }, -8400, 20675, 0, 0, 0, 128 }, /* region 230 */
+ { { 32769, 36, 84 }, -7200, -24285, 1294, 5778, 8, 129 }, /* region 231 */
+ { { 32769, 36, 84 }, -7755, 29204, 798, 993, 45, 130 }, /* region 232 */
+ { { 32769, 36, 84 }, -8055, 20675, 798, 993, 45, 131 }, /* region 233 */
+ { { 32769, 36, 84 }, -8955, 29204, 798, 993, 45, 132 }, /* region 234 */
+ { { 32768, 36, 84 }, -9355, 32767, 0, 0, 133, 133 }, /* region 235 */
+ { { 32768, 36, 84 }, -7755, 20675, 0, 0, 91, 134 }, /* region 236 */
+ { { 1, 24, 62 }, -8200, 23197, 286, 333, 94, 135 }, /* region 237 */
+ { { 1, 63, 66 }, -8564, 26028, 297, 335, 93, 135 }, /* region 238 */
+ { { 1, 67, 72 }, -8922, 23197, 368, 399, 84, 135 }, /* region 239 */
+ { { 32769, 73, 96 }, -9510, 23197, 116, 138, 119, 135 }, /* region 240 */
+ { { 1, 24, 48 }, -6341, 23197, 309, 447, 77, 136 }, /* region 241 */
+ { { 1, 49, 56 }, -7466, 26028, 211, 283, 99, 136 }, /* region 242 */
+ { { 1, 57, 63 }, -8200, 26028, 286, 333, 94, 136 }, /* region 243 */
+ { { 32769, 64, 84 }, -8922, 23197, 368, 399, 84, 136 }, /* region 244 */
+ { { 1, 24, 56 }, -7466, 29204, 211, 283, 99, 137 }, /* region 245 */
+ { { 1, 57, 63 }, -8200, 29204, 286, 333, 94, 137 }, /* region 246 */
+ { { 1, 64, 69 }, -8922, 29204, 368, 399, 84, 137 }, /* region 247 */
+ { { 32769, 70, 96 }, -9510, 29204, 116, 138, 119, 137 }, /* region 248 */
+ { { 1, 24, 68 }, -8922, 18426, 368, 399, 84, 138 }, /* region 249 */
+ { { 1, 69, 76 }, -9510, 26028, 116, 138, 119, 138 }, /* region 250 */
+ { { 32769, 77, 108 }, -9958, 23197, 127, 144, 118, 138 }, /* region 251 */
+ { { 1, 24, 82 }, -8813, 23197, 389, 422, 80, 139 }, /* region 252 */
+ { { 32769, 83, 108 }, -9964, 26028, 146, 163, 114, 139 }, /* region 253 */
+ { { 1, 12, 58 }, -8098, 29204, 386, 436, 78, 140 }, /* region 254 */
+ { { 32769, 59, 96 }, -8571, 26028, 290, 328, 95, 140 }, /* region 255 */
+ { { 1, 12, 58 }, -8098, 16422, 386, 436, 78, 141 }, /* region 256 */
+ { { 32769, 59, 96 }, -8571, 18426, 290, 328, 95, 141 }, /* region 257 */
+ { { 1, 12, 48 }, -8098, -28771, 386, 436, 78, 142 }, /* region 258 */
+ { { 32769, 49, 84 }, -8571, 29204, 290, 328, 95, 142 }, /* region 259 */
+ { { 1, 12, 60 }, -6653, 20675, 314, 430, 79, 143 }, /* region 260 */
+ { { 32769, 61, 84 }, -7753, 18426, 263, 324, 96, 143 }, /* region 261 */
+ { { 1, 24, 60 }, -7753, 16422, 263, 324, 96, 144 }, /* region 262 */
+ { { 1, 61, 70 }, -8869, 20675, 279, 311, 97, 144 }, /* region 263 */
+ { { 32769, 71, 96 }, -9298, 23197, 179, 204, 107, 144 }, /* region 264 */
+ { { 1, 24, 84 }, -9683, 20675, 191, 211, 105, 145 }, /* region 265 */
+ { { 32769, 85, 108 }, -10883, 20675, 92, 102, 121, 145 }, /* region 266 */
+ { { 1, 21, 69 }, -7753, 13045, 263, 324, 96, 146 }, /* region 267 */
+ { { 1, 70, 94 }, -8869, 20675, 279, 311, 97, 146 }, /* region 268 */
+ { { 1, 95, 96 }, -9298, -24285, 179, 204, 107, 146 }, /* region 269 */
+ { { 32769, 97, 108 }, -10883, -24285, 173, 183, 110, 146 }, /* region 270 */
+ { { 1, 16, 55 }, -9300, 20675, 168, 193, 108, 147 }, /* region 271 */
+ { { 1, 56, 74 }, -9776, 26028, 138, 157, 115, 147 }, /* region 272 */
+ { { 32769, 75, 96 }, -11274, 26028, 135, 151, 117, 147 }, /* region 273 */
+ { { 1, 24, 72 }, -9298, 26028, 179, 204, 107, 148 }, /* region 274 */
+ { { 1, 73, 85 }, -9683, 20675, 191, 211, 105, 148 }, /* region 275 */
+ { { 32769, 86, 108 }, -10883, 18426, 92, 102, 121, 148 }, /* region 276 */
+ { { 32769, 36, 108 }, -8930, 18426, 1839, 1901, 21, 149 }, /* region 277 */
+ { { 32769, 24, 108 }, -8473, 20675, 494, 534, 69, 150 }, /* region 278 */
+ { { 32769, 12, 108 }, -8473, 20675, 494, 534, 69, 151 }, /* region 279 */
+ { { 32769, 24, 108 }, -8473, 20675, 494, 534, 69, 152 }, /* region 280 */
+ { { 1, 36, 60 }, -6100, 5193, 2, 22, 143, 153 }, /* region 281 */
+ { { 32769, 61, 84 }, -7283, 20675, 173, 183, 110, 153 }, /* region 282 */
+ { { 32769, 24, 96 }, -7753, 14636, 263, 324, 96, 154 }, /* region 283 */
+ { { 32769, 36, 96 }, -8930, 26028, 1839, 1901, 21, 155 }, /* region 284 */
+ { { 32769, 24, 108 }, -8473, 20675, 494, 534, 69, 156 }, /* region 285 */
+ { { 1, 24, 58 }, -9051, 14636, 0, 29, 140, 157 }, /* region 286 */
+ { { 32769, 59, 96 }, -9051, 14636, 0, 29, 140, 157 }, /* region 287 */
+ { { 1, 12, 83 }, -7220, 13045, 0, 83, 125, 158 }, /* region 288 */
+ { { 1, 84, 90 }, -9682, 13045, 0, 20, 146, 158 }, /* region 289 */
+ { { 32769, 91, 108 }, -10301, 13045, 6, 20, 148, 158 }, /* region 290 */
+ { { 1, 21, 42 }, -5863, 26028, 1047, 1229, 34, 159 }, /* region 291 */
+ { { 1, 43, 48 }, -6656, 29204, 1138, 1253, 33, 159 }, /* region 292 */
+ { { 1, 49, 53 }, -7045, 26028, 559, 651, 60, 159 }, /* region 293 */
+ { { 1, 54, 60 }, -7932, 26028, 508, 563, 64, 159 }, /* region 294 */
+ { { 1, 61, 65 }, -8280, 32767, 819, 864, 51, 159 }, /* region 295 */
+ { { 1, 66, 70 }, -8066, 26942, 981, 1032, 43, 159 }, /* region 296 */
+ { { 1, 71, 76 }, -9366, 26028, 790, 814, 54, 159 }, /* region 297 */
+ { { 1, 77, 82 }, -9966, 26028, 592, 609, 61, 159 }, /* region 298 */
+ { { 1, 83, 87 }, -10717, 23197, 543, 554, 66, 159 }, /* region 299 */
+ { { 1, 88, 96 }, -11271, 18426, 601, 609, 62, 159 }, /* region 300 */
+ { { 32769, 97, 108 }, -11766, 18426, 523, 529, 70, 159 }, /* region 301 */
+ { { 1, 48, 69 }, -7513, 14636, 0, 70, 128, 160 }, /* region 302 */
+ { { 1, 70, 79 }, -8924, 18426, 0, 31, 138, 160 }, /* region 303 */
+ { { 32769, 80, 96 }, -9230, 14636, 0, 26, 142, 160 }, /* region 304 */
+ { { 1, 36, 72 }, -8334, 29204, 0, 87, 123, 161 }, /* region 305 */
+ { { 32769, 73, 96 }, -9160, 29204, 0, 54, 129, 161 }, /* region 306 */
+ { { 32769, 36, 96 }, -8930, 26028, 1839, 1901, 21, 162 }, /* region 307 */
+ { { 32769, 12, 96 }, -5572, 32767, 818, 1033, 42, 163 }, /* region 308 */
+ { { 32769, 36, 108 }, -9770, 26028, 472, 491, 74, 164 }, /* region 309 */
+ { { 32769, 12, 96 }, -6204, 29204, 570, 719, 59, 165 }, /* region 310 */
+ { { 1, 12, 83 }, -7220, 13045, 0, 83, 125, 166 }, /* region 311 */
+ { { 1, 84, 90 }, -9682, 13045, 0, 20, 146, 166 }, /* region 312 */
+ { { 32769, 91, 108 }, -10301, 13045, 6, 20, 148, 166 }, /* region 313 */
+ { { 1, 21, 46 }, -6851, 32767, 236, 340, 92, 167 }, /* region 314 */
+ { { 1, 47, 75 }, -7763, 26028, 824, 885, 49, 167 }, /* region 315 */
+ { { 1, 76, 84 }, -9107, 23197, 719, 747, 57, 167 }, /* region 316 */
+ { { 1, 85, 93 }, -10076, 20675, 83, 99, 122, 167 }, /* region 317 */
+ { { 32769, 94, 108 }, -10889, 20675, 173, 183, 110, 167 }, /* region 318 */
+ { { 1, 21, 46 }, -6851, 26028, 236, 340, 92, 168 }, /* region 319 */
+ { { 1, 47, 71 }, -7763, 20675, 824, 885, 49, 168 }, /* region 320 */
+ { { 1, 72, 88 }, -9107, 18426, 719, 747, 57, 168 }, /* region 321 */
+ { { 1, 89, 93 }, -10076, 16422, 83, 99, 122, 168 }, /* region 322 */
+ { { 32769, 94, 108 }, -10889, 16422, 173, 183, 110, 168 }, /* region 323 */
+ { { 1, 21, 45 }, -5863, 26028, 1047, 1229, 34, 169 }, /* region 324 */
+ { { 1, 46, 51 }, -6656, 29204, 1138, 1253, 33, 169 }, /* region 325 */
+ { { 1, 52, 54 }, -7045, 26028, 559, 651, 60, 169 }, /* region 326 */
+ { { 1, 55, 63 }, -7932, 26028, 508, 563, 64, 169 }, /* region 327 */
+ { { 1, 64, 68 }, -8280, 32767, 819, 864, 51, 169 }, /* region 328 */
+ { { 1, 69, 73 }, -8066, 26942, 981, 1032, 43, 169 }, /* region 329 */
+ { { 1, 74, 79 }, -9366, 26028, 790, 814, 54, 169 }, /* region 330 */
+ { { 1, 80, 88 }, -9966, 23197, 592, 609, 61, 169 }, /* region 331 */
+ { { 1, 89, 99 }, -11271, 18426, 601, 609, 62, 169 }, /* region 332 */
+ { { 32769, 100, 108 }, -11766, 18426, 523, 529, 70, 169 }, /* region 333 */
+ { { 1, 21, 45 }, -5863, 26028, 1047, 1229, 34, 170 }, /* region 334 */
+ { { 1, 46, 51 }, -6656, 29204, 1138, 1253, 33, 170 }, /* region 335 */
+ { { 1, 52, 54 }, -7045, 26028, 559, 651, 60, 170 }, /* region 336 */
+ { { 1, 55, 63 }, -7932, 26028, 508, 563, 64, 170 }, /* region 337 */
+ { { 1, 64, 68 }, -8280, 32767, 819, 864, 51, 170 }, /* region 338 */
+ { { 1, 69, 73 }, -8066, 26942, 981, 1032, 43, 170 }, /* region 339 */
+ { { 1, 74, 79 }, -9366, 26028, 790, 814, 54, 170 }, /* region 340 */
+ { { 1, 80, 88 }, -9966, 23197, 592, 609, 61, 170 }, /* region 341 */
+ { { 1, 89, 99 }, -11271, 18426, 601, 609, 62, 171 }, /* region 342 */
+ { { 32769, 100, 108 }, -11766, 18426, 523, 529, 70, 172 }, /* region 343 */
+ { { 32769, 36, 108 }, -9770, 20675, 472, 491, 74, 173 }, /* region 344 */
+ { { 32769, 12, 108 }, -8930, 20675, 1839, 1901, 21, 174 }, /* region 345 */
+ { { 1, 12, 44 }, -7068, 18426, 163, 254, 102, 175 }, /* region 346 */
+ { { 1, 45, 51 }, -7618, 20675, 261, 393, 85, 175 }, /* region 347 */
+ { { 1, 52, 58 }, -8533, 23197, 190, 229, 104, 175 }, /* region 348 */
+ { { 1, 59, 66 }, -9300, 23197, 168, 193, 108, 175 }, /* region 349 */
+ { { 1, 67, 70 }, -9776, 23197, 138, 157, 115, 175 }, /* region 350 */
+ { { 1, 71, 80 }, -10303, 23197, 166, 180, 112, 175 }, /* region 351 */
+ { { 32769, 81, 108 }, -11274, 23197, 135, 151, 117, 175 }, /* region 352 */
+ { { 1, 12, 65 }, -8253, 16422, 23, 10953, 4, 176 }, /* region 353 */
+ { { 32769, 66, 108 }, -8955, 20675, 11, 11753, 3, 176 }, /* region 354 */
+ { { 1, 12, 48 }, -5998, 29204, 1132, 1301, 31, 177 }, /* region 355 */
+ { { 32769, 49, 108 }, -7188, 29204, 1099, 1184, 36, 177 }, /* region 356 */
+ { { 1, 12, 83 }, -8441, 20675, 419, 460, 76, 178 }, /* region 357 */
+ { { 32769, 84, 108 }, -11323, 20675, 0, 31, 139, 178 }, /* region 358 */
+ { { 1, 55, 60 }, -8253, 18426, 356, 402, 82, 179 }, /* region 359 */
+ { { 1, 61, 69 }, -8774, 18426, 514, 548, 67, 179 }, /* region 360 */
+ { { 1, 70, 79 }, -9374, 18426, 505, 529, 71, 179 }, /* region 361 */
+ { { 32769, 80, 108 }, -10433, 23197, 178, 191, 109, 179 }, /* region 362 */
+ { { 32769, 36, 96 }, -8930, -24285, 1839, 1901, 21, 180 }, /* region 363 */
+ { { 1, 12, 83 }, -7206, 16422, 838, 922, 47, 181 }, /* region 364 */
+ { { 1, 84, 93 }, -9606, 18426, 209, 230, 103, 181 }, /* region 365 */
+ { { 32769, 94, 108 }, -11308, 16422, 0, 31, 139, 181 }, /* region 366 */
+ { { 1, 12, 56 }, -6795, 23197, 1064, 1170, 38, 182 }, /* region 367 */
+ { { 1, 57, 72 }, -7195, 23197, 930, 1014, 44, 182 }, /* region 368 */
+ { { 32769, 73, 108 }, -8798, 23197, 726, 826, 52, 182 }, /* region 369 */
+ { { 32769, 24, 108 }, -8800, 23197, 635, 735, 58, 62 }, /* region 370 */
+ { { 1, 36, 83 }, -7206, 13045, 838, 922, 47, 183 }, /* region 371 */
+ { { 1, 84, 93 }, -9606, 13045, 209, 230, 103, 183 }, /* region 372 */
+ { { 32769, 94, 108 }, -11308, 13045, 0, 31, 139, 183 }, /* region 373 */
+ { { 1, 12, 66 }, -7811, 23197, 437, 16584, 2, 184 }, /* region 374 */
+ { { 1, 67, 87 }, -8402, 23197, 452, 16803, 0, 184 }, /* region 375 */
+ { { 32769, 88, 108 }, -9673, 16422, 404, 16698, 1, 184 } /* region 376 */
+}; /* end Regions */
+
+/*----------------------------------------------------------------------------
+ * Programs
+ *----------------------------------------------------------------------------
+*/
+const S_PROGRAM eas_programs[] =
+{
+ { 7864320, 0 } /* program 0 */
+}; /* end Programs */
+
+/*----------------------------------------------------------------------------
+ * Banks
+ *----------------------------------------------------------------------------
+*/
+const S_BANK eas_banks[] =
+{
+ { /* bank 0 */
+ 30976,
+ {
+ 291, 324, 314, 334, 202, 319, 95, 195,
+ 107, 92, 371, 89, 87, 85, 135, 82,
+ 200, 192, 130, 267, 193, 302, 207, 210,
+ 128, 125, 190, 120, 118, 213, 221, 271,
+ 80, 78, 308, 164, 220, 310, 166, 167,
+ 186, 182, 181, 179, 160, 178, 176, 115,
+ 155, 153, 151, 149, 75, 73, 374, 111,
+ 252, 254, 258, 305, 256, 157, 146, 137,
+ 249, 237, 245, 241, 274, 262, 260, 265,
+ 172, 171, 309, 277, 284, 307, 136, 344,
+ 173, 168, 345, 353, 346, 70, 110, 311,
+ 357, 144, 104, 67, 364, 367, 64, 288,
+ 142, 140, 98, 355, 133, 123, 61, 113,
+ 285, 280, 279, 278, 370, 286, 359, 283,
+ 101, 236, 163, 235, 234, 233, 232, 231,
+ 162, 363, 230, 281, 165, 229, 109, 228
+ }
+ }
+}; /* end Banks */
+
+/*----------------------------------------------------------------------------
+ * Samples
+ *----------------------------------------------------------------------------
+*/
+
+const EAS_SAMPLE eas_samples[] =
+{
+ 0, 0, -3, -4, -6, -8, -10, -12, -12, -11, -8, -3, 3, 7, 10, 14,
+ 16, 16, 15, 12, 9, 4, -4, -12, -18, -21, -21, -19, -18, -15, -10, -3,
+ 10, 20, 34, 44, 51, 52, 48, 43, 38, 26, 8, -15, -37, -52, -61, -64,
+ -66, -64, -59, -47, -31, -13, 4, 18, 30, 37, 40, 36, 30, 24, 19, 11,
+ -2, -17, -24, -28, -28, -21, -18, -16, -10, -3, 12, 27, 39, 49, 53, 53,
+ 50, 43, 37, 25, 11, -11, -31, -46, -57, -63, -66, -63, -57, -46, -34, -19,
+ -3, 13, 27, 35, 39, 37, 32, 26, 20, 11, 0, -13, -20, -24, -25, -21,
+ -19, -14, -8, -2, 9, 23, 37, 47, 53, 52, 49, 42, 35, 25, 13, -6,
+ -28, -48, -60, -67, -67, -64, -60, -51, -39, -23, -7, 10, 23, 35, 39, 38,
+ 32, 26, 21, 15, 4, -9, -20, -22, -21, -19, -14, -11, -5, 1, 9, 19,
+ 31, 45, 51, 52, 47, 39, 35, 25, 15, -3, -23, -42, -58, -70, -71, -66,
+ -60, -51, -43, -30, -13, 6, 22, 32, 40, 40, 38, 33, 27, 19, 9, -5,
+ -17, -25, -26, -22, -16, -11, -8, -4, 7, 21, 35, 48, 53, 56, 50, 43,
+ 34, 22, 13, -2, -22, -44, -63, -75, -76, -69, -61, -51, -43, -29, -13, 6,
+ 23, 32, 41, 43, 41, 37, 26, 18, 7, -8, -19, -25, -25, -22, -15, -9,
+ -5, 0, 10, 24, 37, 44, 48, 52, 52, 46, 33, 20, 8, -5, -20, -38,
+ -59, -74, -79, -73, -67, -55, -43, -26, -11, 4, 18, 29, 41, 45, 45, 38,
+ 29, 21, 11, -3, -15, -25, -27, -22, -16, -11, -8, 0, 10, 25, 38, 44,
+ 47, 50, 53, 49, 37, 20, 7, -5, -17, -34, -58, -74, -82, -76, -67, -59,
+ -47, -29, -12, 3, 14, 25, 38, 50, 52, 46, 33, 23, 14, 3, -11, -25,
+ -28, -27, -21, -16, -13, -7, 8, 27, 41, 44, 45, 47, 54, 55, 44, 25,
+ 7, -7, -18, -32, -53, -71, -81, -81, -72, -67, -55, -37, -16, 3, 15, 23,
+ 34, 48, 57, 56, 44, 30, 19, 5, -12, -26, -33, -31, -25, -19, -16, -11,
+ 7, 25, 45, 49, 49, 52, 57, 59, 48, 32, 11, -5, -22, -39, -56, -73,
+ -82, -88, -84, -75, -60, -38, -16, 5, 21, 30, 39, 52, 59, 61, 53, 37,
+ 22, 7, -12, -28, -35, -36, -30, -22, -19, -16, -2, 21, 41, 52, 51, 52,
+ 57, 62, 54, 40, 18, -2, -18, -36, -54, -70, -80, -86, -87, -81, -69, -48,
+ -23, 0, 18, 28, 35, 45, 57, 64, 59, 46, 27, 9, -11, -24, -30, -32,
+ -29, -25, -20, -16, -5, 15, 36, 47, 50, 49, 53, 57, 54, 43, 24, 5,
+ -14, -32, -50, -65, -75, -82, -86, -86, -77, -58, -32, -8, 14, 25, 30, 41,
+ 56, 69, 69, 57, 36, 17, -4, -20, -29, -32, -27, -28, -27, -23, -13, 10,
+ 33, 46, 50, 48, 50, 54, 55, 48, 34, 16, -6, -29, -50, -68, -75, -78,
+ -82, -86, -84, -72, -47, -16, 11, 28, 34, 41, 51, 64, 70, 64, 49, 27,
+ 5, -17, -30, -33, -29, -29, -30, -30, -22, -2, 23, 41, 49, 51, 51, 54,
+ 56, 50, 42, 25, 4, -20, -44, -62, -70, -76, -83, -87, -89, -78, -56, -29,
+ 0, 19, 31, 38, 48, 63, 72, 71, 60, 40, 14, -12, -25, -29, -26, -27,
+ -33, -37, -30, -12, 11, 31, 41, 48, 51, 53, 55, 55, 51, 39, 17, -12,
+ -38, -58, -67, -74, -82, -92, -98, -89, -69, -41, -13, 10, 29, 41, 50, 64,
+ 72, 78, 74, 57, 29, 0, -18, -26, -28, -32, -38, -42, -38, -23, -3, 18,
+ 30, 42, 52, 58, 60, 61, 57, 48, 28, 2, -30, -51, -62, -70, -81, -94,
+ -101, -93, -75, -49, -23, -2, 18, 36, 50, 61, 69, 77, 78, 66, 42, 11,
+ -11, -22, -27, -32, -39, -46, -46, -36, -14, 8, 25, 41, 52, 59, 62, 63,
+ 62, 57, 38, 11, -20, -47, -61, -69, -78, -89, -98, -94, -80, -60, -37, -12,
+ 13, 33, 48, 62, 70, 78, 81, 72, 52, 23, 0, -14, -24, -33, -43, -49,
+ -49, -39, -23, -2, 15, 33, 47, 57, 63, 62, 62, 57, 40, 20, -7, -34,
+ -52, -65, -74, -83, -94, -92, -81, -63, -42, -22, 0, 21, 39, 54, 63, 73,
+ 79, 76, 61, 37, 12, -5, -19, -28, -37, -46, -51, -47, -32, -13, 7, 25,
+ 43, 54, 58, 60, 60, 61, 48, 27, 3, -25, -45, -60, -72, -81, -90, -92,
+ -84, -71, -52, -32, -9, 14, 33, 50, 61, 74, 80, 78, 67, 47, 24, 6,
+ -12, -26, -37, -50, -56, -52, -37, -19, -2, 16, 35, 52, 61, 63, 61, 59,
+ 51, 35, 12, -15, -38, -55, -66, -77, -83, -83, -80, -68, -55, -39, -19, 4,
+ 25, 41, 54, 66, 73, 75, 68, 52, 31, 11, -7, -22, -33, -46, -54, -51,
+ -39, -24, -5, 12, 32, 48, 56, 60, 61, 58, 50, 36, 17, -8, -30, -46,
+ -63, -74, -80, -80, -74, -69, -58, -43, -27, -5, 15, 31, 48, 60, 68, 72,
+ 68, 57, 39, 20, 2, -16, -30, -44, -51, -50, -41, -27, -10, 9, 28, 43,
+ 53, 57, 57, 54, 48, 37, 19, -3, -25, -41, -56, -69, -75, -73, -69, -63,
+ -59, -49, -32, -13, 9, 25, 37, 48, 58, 66, 65, 58, 42, 25, 8, -9,
+ -22, -36, -41, -43, -37, -26, -14, 4, 21, 37, 48, 52, 53, 47, 42, 34,
+ 21, 3, -18, -39, -51, -64, -67, -62, -60, -60, -58, -50, -36, -16, 3, 17,
+ 29, 41, 49, 58, 61, 60, 49, 29, 11, -7, -19, -28, -32, -33, -30, -25,
+ -14, 2, 19, 33, 41, 45, 42, 38, 36, 29, 20, 6, -14, -28, -43, -54,
+ -58, -55, -50, -51, -54, -51, -41, -22, -4, 11, 19, 30, 37, 47, 55, 56,
+ 51, 34, 16, 0, -15, -19, -23, -22, -22, -21, -14, 0, 15, 29, 39, 43,
+ 37, 31, 25, 21, 18, 6, -11, -28, -42, -50, -51, -48, -44, -41, -44, -43,
+ -41, -25, -8, 9, 16, 22, 26, 35, 43, 50, 48, 33, 16, -3, -13, -16,
+ -16, -15, -13, -11, -6, 5, 16, 28, 38, 41, 35, 24, 15, 12, 10, 4,
+ -11, -27, -39, -46, -46, -45, -40, -36, -36, -37, -38, -29, -13, 6, 16, 19,
+ 22, 27, 37, 43, 42, 32, 19, 2, -10, -13, -12, -7, -4, -2, 2, 10,
+ 18, 27, 36, 38, 32, 20, 9, 4, -2, -4, -11, -23, -34, -42, -42, -38,
+ -31, -28, -29, -32, -33, -30, -18, 0, 10, 12, 12, 17, 26, 35, 36, 31,
+ 19, 5, -6, -11, -9, -2, 7, 14, 13, 13, 16, 23, 31, 34, 29, 15,
+ -3, -8, -10, -10, -14, -20, -26, -30, -32, -30, -25, -18, -17, -24, -31, -32,
+ -26, -11, 2, 7, 8, 9, 17, 25, 29, 28, 21, 9, -2, -7, -5, 4,
+ 12, 21, 24, 23, 25, 26, 29, 31, 27, 15, -2, -15, -21, -23, -23, -23,
+ -28, -30, -31, -27, -19, -10, -9, -13, -21, -22, -20, -11, -4, -3, -5, -2,
+ 5, 13, 17, 17, 16, 10, 6, 0, 3, 11, 23, 32, 33, 30, 28, 27,
+ 24, 24, 19, 9, -6, -19, -29, -29, -26, -20, -19, -22, -24, -23, -16, -10,
+ -9, -14, -20, -24, -21, -16, -10, -6, -5, 1, 5, 11, 12, 13, 11, 8,
+ 6, 1, 4, 9, 23, 33, 39, 36, 32, 32, 28, 22, 17, 7, -7, -22,
+ -31, -33, -31, -24, -19, -18, -18, -16, -13, -7, -6, -8, -14, -21, -24, -20,
+ -15, -12, -9, -6, 0, 4, 6, 8, 8, 5, 5, 2, 7, 15, 27, 37,
+ 42, 45, 41, 39, 32, 22, 13, 3, -11, -26, -37, -41, -37, -29, -21, -18,
+ -15, -11, -6, -2, -2, -4, -7, -13, -16, -20, -21, -16, -14, -10, -6, -3,
+ -3, 0, 3, 2, 3, 3, 9, 18, 32, 41, 46, 49, 44, 43, 35, 24,
+ 12, 1, -14, -27, -39, -40, -36, -31, -22, -16, -13, -6, -3, -3, -4, -9,
+ -9, -13, -16, -20, -21, -16, -15, -11, -6, -4, -4, -5, -5, -3, -3, 0,
+ 10, 19, 33, 44, 51, 56, 52, 50, 40, 23, 11, -6, -19, -30, -40, -43,
+ -40, -35, -24, -16, -7, 2, 6, 5, 1, -6, -9, -9, -9, -12, -19, -21,
+ -21, -17, -9, -7, -9, -11, -15, -14, -9, -7, 7, 19, 36, 51, 57, 61,
+ 59, 56, 48, 33, 13, -8, -24, -35, -45, -51, -46, -38, -26, -14, -7, 3,
+ 11, 15, 12, 3, -5, -7, -6, -9, -15, -22, -25, -23, -17, -13, -12, -16,
+ -19, -21, -18, -12, 3, 21, 38, 50, 58, 67, 65, 64, 55, 41, 21, -4,
+ -25, -38, -46, -50, -49, -43, -33, -23, -11, 3, 14, 19, 16, 8, 0, -2,
+ -2, 0, -8, -19, -27, -30, -25, -22, -20, -20, -22, -25, -24, -16, 1, 22,
+ 43, 56, 62, 67, 68, 65, 60, 46, 24, -3, -25, -40, -45, -49, -50, -46,
+ -37, -23, -10, 1, 12, 20, 20, 14, 7, 2, 3, 3, -4, -15, -26, -31,
+ -30, -27, -26, -26, -29, -33, -33, -25, -8, 17, 41, 57, 65, 71, 73, 73,
+ 66, 53, 33, 5, -23, -41, -48, -50, -48, -48, -40, -30, -14, 1, 12, 21,
+ 24, 18, 13, 6, 5, 5, 0, -11, -25, -37, -39, -35, -31, -31, -33, -38,
+ -37, -29, -12, 15, 40, 59, 67, 71, 72, 73, 69, 59, 39, 14, -16, -38,
+ -50, -51, -50, -48, -45, -36, -21, -4, 12, 25, 30, 25, 18, 11, 11, 10,
+ 6, -8, -25, -39, -46, -42, -38, -37, -37, -40, -42, -34, -15, 13, 40, 57,
+ 66, 71, 72, 72, 69, 61, 45, 19, -10, -34, -46, -48, -47, -45, -45, -41,
+ -28, -12, 7, 23, 27, 25, 18, 15, 17, 17, 12, 1, -20, -37, -47, -50,
+ -46, -45, -44, -45, -46, -41, -21, 7, 37, 60, 69, 73, 72, 72, 72, 67,
+ 52, 25, -6, -33, -47, -50, -47, -47, -47, -45, -35, -16, 6, 23, 31, 30,
+ 24, 23, 24, 25, 18, 4, -15, -33, -50, -56, -57, -53, -48, -49, -49, -45,
+ -29, 2, 35, 58, 68, 71, 72, 74, 73, 68, 56, 34, 5, -26, -43, -48,
+ -45, -42, -46, -46, -41, -24, 0, 21, 33, 34, 31, 25, 27, 27, 19, 6,
+ -14, -36, -55, -64, -64, -60, -50, -47, -45, -44, -31, -4, 32, 58, 71, 72,
+ 68, 70, 70, 66, 57, 36, 11, -20, -43, -50, -48, -41, -37, -42, -40, -28,
+ -5, 21, 36, 38, 34, 26, 29, 28, 20, 8, -13, -33, -52, -68, -69, -65,
+ -55, -49, -47, -44, -31, -3, 30, 55, 67, 70, 68, 70, 70, 65, 57, 39,
+ 15, -13, -38, -49, -47, -40, -35, -39, -41, -30, -9, 17, 37, 44, 45, 38,
+ 32, 29, 22, 9, -10, -34, -54, -70, -75, -73, -64, -52, -45, -43, -31, -7,
+ 25, 53, 67, 72, 70, 72, 70, 62, 53, 38, 16, -10, -32, -49, -50, -43,
+ -35, -33, -36, -29, -10, 16, 35, 46, 46, 41, 35, 30, 23, 10, -10, -34,
+ -53, -69, -75, -74, -66, -53, -45, -42, -34, -13, 17, 46, 63, 68, 66, 63,
+ 65, 63, 54, 43, 24, 0, -20, -40, -43, -42, -36, -32, -32, -28, -16, 7,
+ 29, 47, 52, 47, 39, 31, 21, 10, -9, -30, -50, -66, -78, -77, -71, -59,
+ -49, -42, -34, -17, 9, 37, 56, 66, 66, 62, 62, 61, 56, 45, 30, 7,
+ -13, -31, -39, -40, -36, -33, -32, -28, -18, 1, 21, 41, 54, 52, 44, 36,
+ 26, 13, -8, -29, -48, -66, -76, -80, -74, -64, -55, -45, -34, -18, 5, 29,
+ 50, 65, 68, 66, 64, 60, 59, 47, 33, 15, -5, -23, -37, -43, -41, -37,
+ -35, -31, -21, -4, 16, 36, 52, 59, 54, 45, 33, 17, -5, -25, -45, -60,
+ -74, -83, -82, -71, -59, -49, -37, -23, -2, 22, 43, 59, 66, 65, 64, 60,
+ 58, 50, 39, 23, 2, -17, -32, -39, -40, -38, -35, -32, -23, -6, 14, 33,
+ 49, 59, 58, 49, 34, 16, -5, -25, -43, -60, -74, -83, -83, -76, -63, -53,
+ -40, -24, -5, 16, 36, 54, 65, 67, 65, 61, 57, 52, 43, 27, 9, -12,
+ -26, -37, -40, -39, -36, -32, -28, -13, 6, 27, 46, 58, 60, 52, 39, 23,
+ 5, -16, -36, -53, -66, -77, -84, -81, -72, -60, -45, -32, -15, 5, 25, 48,
+ 62, 69, 71, 69, 65, 58, 50, 34, 16, -6, -24, -36, -42, -45, -44, -39,
+ -33, -21, -2, 22, 43, 59, 64, 60, 47, 34, 17, -6, -28, -50, -66, -76,
+ -84, -86, -82, -72, -57, -40, -21, -2, 21, 42, 58, 66, 73, 76, 71, 64,
+ 53, 40, 26, 4, -17, -34, -45, -49, -48, -43, -38, -28, -10, 15, 40, 58,
+ 66, 64, 56, 42, 25, 4, -21, -44, -62, -73, -81, -87, -86, -78, -65, -47,
+ -31, -9, 15, 34, 52, 62, 72, 79, 80, 72, 61, 49, 34, 12, -12, -32,
+ -43, -49, -54, -55, -48, -36, -16, 10, 35, 56, 67, 71, 67, 54, 38, 15,
+ -10, -34, -57, -72, -85, -93, -97, -89, -76, -59, -40, -20, 8, 32, 50, 67,
+ 77, 87, 89, 81, 66, 52, 35, 16, -6, -30, -47, -58, -61, -57, -50, -37,
+ -19, 6, 29, 51, 65, 73, 73, 62, 44, 18, -6, -28, -49, -67, -81, -93,
+ -97, -94, -83, -65, -47, -28, -5, 19, 42, 61, 76, 87, 90, 88, 80, 66,
+ 48, 27, 3, -17, -40, -56, -65, -66, -58, -49, -30, -6, 17, 41, 59, 71,
+ 77, 70, 56, 36, 11, -13, -34, -53, -71, -89, -98, -100, -94, -79, -62, -44,
+ -21, 3, 27, 52, 74, 90, 98, 95, 86, 75, 59, 37, 12, -14, -35, -54,
+ -64, -67, -64, -51, -34, -10, 11, 32, 50, 65, 73, 71, 58, 37, 14, -10,
+ -29, -48, -64, -81, -93, -98, -94, -82, -63, -45, -26, -5, 16, 40, 65, 83,
+ 94, 94, 84, 75, 63, 46, 23, -3, -27, -47, -58, -64, -64, -56, -39, -17,
+ 3, 20, 38, 57, 71, 72, 61, 45, 24, 1, -19, -37, -56, -73, -91, -99,
+ -100, -92, -74, -53, -34, -16, 7, 31, 59, 82, 97, 101, 92, 78, 65, 48,
+ 29, 6, -21, -43, -55, -64, -66, -58, -40, -18, 3, 17, 32, 51, 69, 71,
+ 62, 45, 27, 6, -15, -34, -50, -64, -81, -93, -99, -96, -80, -59, -40, -23,
+ -4, 21, 50, 77, 94, 100, 93, 81, 67, 53, 36, 14, -12, -36, -53, -58,
+ -63, -56, -42, -22, -5, 10, 23, 42, 63, 70, 62, 47, 29, 13, -6, -27,
+ -43, -57, -72, -84, -98, -99, -87, -66, -44, -27, -11, 10, 38, 67, 91, 99,
+ 92, 82, 70, 57, 41, 21, -3, -27, -47, -58, -63, -58, -44, -23, -5, 7,
+ 17, 35, 55, 66, 61, 46, 29, 13, -4, -22, -39, -51, -65, -78, -90, -95,
+ -85, -69, -47, -30, -12, 9, 30, 57, 83, 96, 91, 81, 67, 57, 42, 26,
+ 6, -18, -39, -55, -62, -58, -43, -24, -8, 2, 14, 30, 47, 60, 60, 49,
+ 34, 17, 0, -16, -31, -43, -58, -71, -86, -93, -86, -72, -52, -32, -15, 3,
+ 22, 48, 76, 90, 89, 78, 69, 59, 46, 32, 14, -6, -27, -47, -57, -56,
+ -45, -29, -12, -5, 4, 18, 37, 54, 58, 51, 36, 21, 6, -8, -20, -33,
+ -52, -68, -84, -90, -85, -74, -58, -42, -22, 0, 20, 42, 67, 83, 87, 80,
+ 68, 58, 47, 34, 19, 0, -20, -40, -52, -53, -45, -27, -13, -4, 6, 17,
+ 33, 47, 53, 52, 38, 21, 3, -11, -24, -35, -50, -65, -80, -89, -85, -71,
+ -55, -39, -21, -2, 20, 39, 59, 74, 81, 75, 67, 57, 47, 38, 23, 4,
+ -17, -32, -43, -45, -39, -26, -14, -4, 4, 12, 26, 38, 47, 48, 35, 19,
+ 4, -10, -20, -29, -41, -56, -71, -78, -81, -71, -56, -43, -23, -6, 15, 35,
+ 49, 62, 72, 69, 63, 54, 45, 41, 28, 11, -11, -27, -37, -40, -35, -24,
+ -17, -7, 2, 9, 22, 35, 46, 49, 37, 21, 4, -9, -18, -27, -41, -55,
+ -71, -79, -79, -70, -53, -38, -23, -8, 9, 31, 46, 58, 63, 63, 59, 52,
+ 45, 40, 32, 14, -6, -24, -32, -31, -30, -23, -18, -12, 1, 9, 21, 31,
+ 41, 44, 33, 21, 5, -6, -20, -29, -43, -57, -69, -77, -73, -65, -52, -41,
+ -27, -8, 11, 32, 49, 57, 64, 61, 55, 47, 39, 36, 29, 13, -8, -25,
+ -36, -35, -26, -16, -9, -5, 1, 9, 22, 36, 45, 43, 33, 17, 1, -11,
+ -21, -32, -45, -57, -71, -78, -73, -61, -45, -33, -23, -8, 11, 31, 46, 53,
+ 57, 54, 48, 40, 34, 31, 27, 14, -4, -20, -29, -28, -22, -12, -4, 1,
+ 4, 8, 21, 34, 43, 43, 31, 17, 1, -11, -22, -31, -44, -59, -72, -78,
+ -70, -54, -40, -28, -19, -8, 10, 28, 45, 53, 57, 53, 43, 34, 28, 27,
+ 26, 18, 0, -18, -31, -29, -20, -11, -3, 2, 5, 10, 19, 31, 43, 44,
+ 34, 19, 2, -13, -23, -32, -43, -55, -68, -77, -73, -57, -41, -26, -15, -6,
+ 11, 28, 43, 52, 52, 49, 41, 33, 24, 22, 21, 14, 1, -14, -25, -24,
+ -18, -7, -2, 2, 7, 10, 20, 31, 40, 43, 33, 18, 3, -13, -24, -35,
+ -44, -55, -70, -78, -74, -59, -40, -26, -11, 1, 13, 29, 44, 53, 57, 54,
+ 45, 32, 24, 18, 13, 9, -4, -16, -26, -29, -22, -10, 1, 8, 13, 18,
+ 23, 35, 42, 45, 37, 21, 5, -14, -30, -41, -49, -57, -69, -77, -76, -61,
+ -39, -20, -5, 9, 20, 34, 47, 53, 55, 48, 39, 27, 14, 8, 3, 2,
+ -4, -15, -23, -24, -16, -3, 6, 11, 19, 24, 30, 34, 41, 43, 35, 18,
+ 1, -17, -31, -44, -52, -59, -68, -75, -73, -61, -38, -19, 1, 13, 23, 30,
+ 42, 52, 52, 47, 36, 23, 14, 7, 4, 0, -6, -11, -20, -24, -18, -5,
+ 7, 15, 18, 22, 28, 36, 43, 43, 38, 24, 4, -13, -30, -44, -55, -64,
+ -69, -77, -76, -65, -44, -19, 1, 15, 27, 35, 46, 53, 53, 46, 36, 23,
+ 11, 3, -5, -7, -9, -14, -20, -23, -19, -7, 11, 18, 21, 25, 30, 40,
+ 43, 43, 38, 24, 7, -14, -30, -41, -55, -65, -73, -77, -74, -66, -49, -24,
+ -2, 17, 29, 35, 44, 51, 54, 49, 35, 23, 11, 1, -6, -12, -15, -16,
+ -20, -24, -21, -10, 8, 21, 27, 33, 35, 42, 48, 47, 37, 23, 7, -12,
+ -28, -44, -60, -69, -75, -78, -74, -65, -49, -25, -2, 17, 30, 40, 48, 54,
+ 55, 48, 36, 20, 6, -4, -9, -14, -20, -22, -24, -21, -15, -6, 7, 21,
+ 32, 39, 43, 44, 49, 50, 38, 21, 4, -13, -28, -47, -62, -74, -77, -78,
+ -77, -65, -48, -26, -4, 15, 28, 40, 50, 56, 54, 46, 33, 20, 9, -2,
+ -10, -16, -21, -21, -23, -21, -15, -5, 9, 19, 30, 38, 42, 44, 46, 47,
+ 36, 22, 6, -10, -23, -39, -57, -74, -78, -79, -75, -65, -51, -33, -11, 9,
+ 25, 37, 46, 55, 56, 48, 34, 21, 10, 4, -4, -14, -20, -25, -24, -21,
+ -12, -3, 8, 17, 26, 36, 47, 50, 50, 47, 36, 25, 10, -5, -21, -40,
+ -57, -75, -82, -79, -75, -64, -51, -37, -16, 5, 25, 40, 48, 55, 55, 49,
+ 37, 25, 15, 6, -6, -18, -26, -29, -25, -20, -16, -7, 5, 17, 29, 39,
+ 49, 56, 56, 51, 39, 28, 15, 0, -17, -38, -58, -75, -86, -86, -80, -70,
+ -54, -37, -16, 7, 25, 42, 50, 55, 58, 52, 40, 25, 11, 2, -5, -14,
+ -21, -26, -26, -18, -12, -5, 4, 13, 25, 34, 45, 53, 55, 48, 39, 25,
+ 16, 3, -13, -31, -54, -70, -83, -85, -78, -68, -55, -38, -20, 1, 20, 36,
+ 46, 51, 55, 48, 39, 27, 17, 7, -5, -13, -20, -23, -23, -18, -10, -4,
+ 3, 10, 21, 29, 40, 48, 52, 50, 40, 28, 20, 10, -5, -24, -48, -67,
+ -82, -87, -81, -73, -56, -44, -25, -5, 15, 34, 46, 52, 55, 51, 39, 27,
+ 18, 7, -2, -13, -22, -25, -24, -16, -9, 1, 8, 13, 22, 30, 42, 48,
+ 50, 47, 38, 26, 15, 6, -8, -22, -41, -61, -77, -86, -81, -70, -54, -40,
+ -27, -8, 12, 31, 42, 49, 50, 48, 38, 26, 16, 7, -4, -11, -18, -22,
+ -21, -16, -9, 0, 9, 15, 21, 26, 35, 47, 50, 46, 36, 28, 18, 7,
+ -7, -22, -37, -53, -70, -81, -83, -72, -58, -43, -30, -14, 5, 22, 37, 44,
+ 46, 44, 37, 26, 17, 8, 2, -7, -12, -17, -16, -12, -6, 3, 8, 13,
+ 17, 22, 31, 42, 43, 43, 35, 29, 25, 14, 2, -17, -35, -51, -65, -77,
+ -80, -75, -63, -47, -34, -18, 4, 21, 32, 38, 41, 41, 36, 28, 17, 8,
+ 1, -9, -12, -16, -15, -9, -2, 8, 13, 15, 17, 23, 28, 39, 43, 38,
+ 30, 21, 17, 11, 4, -12, -28, -45, -60, -68, -71, -66, -58, -49, -38, -23,
+ -5, 15, 27, 34, 34, 32, 28, 23, 18, 13, 4, -2, -7, -9, -7, -4,
+ 5, 14, 16, 16, 14, 15, 24, 35, 39, 35, 23, 17, 15, 11, 8, -4,
+ -19, -37, -53, -62, -65, -62, -57, -53, -43, -31, -14, 5, 19, 27, 31, 28,
+ 26, 23, 20, 18, 11, 5, -2, -5, 0, 3, 8, 14, 16, 15, 11, 7,
+ 12, 23, 32, 32, 21, 12, 10, 13, 12, 6, -9, -27, -43, -50, -55, -53,
+ -51, -52, -44, -38, -23, -6, 7, 18, 22, 19, 16, 15, 16, 19, 17, 12,
+ 6, 3, 7, 10, 16, 20, 23, 20, 14, 8, 9, 17, 27, 26, 17, 6,
+ 3, 7, 10, 7, -5, -18, -32, -41, -46, -45, -45, -45, -44, -40, -30, -16,
+ -3, 8, 15, 12, 10, 11, 16, 19, 19, 16, 12, 10, 11, 15, 20, 25,
+ 26, 24, 18, 11, 6, 11, 17, 21, 15, 3, -6, -2, 4, 7, 2, -14,
+ -25, -32, -36, -38, -37, -37, -35, -33, -33, -25, -15, -4, 3, 4, 0, -3,
+ 2, 13, 21, 21, 20, 17, 19, 23, 27, 31, 33, 31, 24, 16, 4, 2,
+ 7, 13, 13, 3, -10, -9, 0, 8, 7, -3, -15, -22, -24, -30, -32, -37,
+ -39, -38, -37, -34, -28, -17, -8, -2, -4, -4, 4, 16, 26, 30, 26, 22,
+ 22, 25, 29, 31, 30, 29, 24, 17, 6, -2, 7, 10, 13, 4, -11, -15,
+ -10, 3, 8, 2, -10, -17, -17, -17, -23, -29, -35, -37, -34, -36, -35, -28,
+ -19, -10, -11, -14, -8, 8, 21, 26, 26, 21, 24, 31, 38, 40, 38, 37,
+ 33, 26, 15, 4, 1, 2, 1, -6, -19, -24, -18, -7, 2, 5, -4, -10,
+ -9, -6, -7, -16, -27, -33, -35, -38, -41, -38, -32, -22, -20, -18, -10, 4,
+ 20, 29, 31, 30, 28, 32, 38, 43, 42, 39, 34, 28, 14, 4, 1, 3,
+ 4, -5, -21, -30, -26, -14, 1, 3, -4, -8, -8, 0, 0, -8, -15, -26,
+ -29, -35, -40, -40, -36, -30, -28, -29, -22, -10, 9, 22, 28, 28, 27, 30,
+ 39, 46, 50, 50, 43, 33, 21, 9, 3, 3, 1, -10, -22, -35, -34, -22,
+ -8, 2, 0, -6, -7, 0, 5, -2, -9, -18, -28, -34, -41, -43, -39, -35,
+ -33, -33, -25, -12, 5, 19, 26, 29, 31, 31, 39, 46, 51, 52, 47, 38,
+ 27, 18, 10, 5, -3, -13, -22, -33, -36, -28, -16, -4, -2, -4, -6, 0,
+ 8, 7, 0, -12, -22, -33, -40, -42, -39, -37, -38, -39, -32, -17, 2, 15,
+ 24, 25, 28, 33, 39, 47, 51, 53, 51, 44, 35, 23, 15, 8, 1, -12,
+ -25, -37, -41, -33, -22, -11, -4, -5, -3, 3, 10, 13, 6, -5, -17, -28,
+ -38, -43, -44, -44, -44, -43, -36, -23, -7, 7, 20, 26, 29, 35, 43, 51,
+ 54, 58, 56, 52, 44, 29, 18, 9, -2, -12, -28, -39, -45, -38, -26, -16,
+ -7, -3, 1, 6, 12, 15, 12, 3, -11, -25, -37, -41, -43, -46, -47, -46,
+ -39, -28, -15, 0, 11, 21, 25, 31, 38, 46, 53, 60, 62, 59, 53, 42,
+ 32, 19, 6, -10, -27, -41, -47, -47, -39, -31, -21, -9, -2, 5, 11, 16,
+ 19, 13, 2, -15, -30, -35, -37, -43, -47, -49, -42, -32, -21, -11, 0, 8,
+ 19, 27, 38, 47, 51, 58, 63, 63, 59, 50, 41, 28, 10, -9, -26, -37,
+ -43, -44, -40, -33, -23, -11, 0, 6, 9, 14, 15, 13, 1, -15, -25, -32,
+ -34, -43, -49, -50, -43, -30, -20, -13, -9, 0, 10, 23, 36, 46, 52, 55,
+ 62, 65, 66, 61, 51, 36, 15, -7, -24, -34, -42, -45, -46, -42, -34, -20,
+ -5, 5, 11, 14, 16, 13, 2, -10, -18, -24, -31, -39, -49, -48, -42, -34,
+ -24, -18, -15, -8, 2, 13, 29, 42, 51, 57, 62, 65, 70, 69, 60, 45,
+ 20, -3, -24, -37, -43, -46, -49, -48, -39, -24, -6, 5, 12, 17, 20, 16,
+ 6, -9, -15, -21, -26, -38, -50, -56, -50, -37, -26, -23, -19, -14, -4, 11,
+ 27, 42, 54, 58, 63, 65, 68, 70, 63, 50, 26, 1, -21, -37, -43, -44,
+ -44, -44, -40, -28, -11, 5, 10, 16, 18, 14, 5, -12, -19, -22, -24, -33,
+ -47, -52, -52, -38, -25, -17, -17, -16, -10, 4, 22, 39, 53, 59, 62, 63,
+ 66, 68, 66, 55, 32, 9, -17, -34, -43, -42, -39, -38, -38, -31, -19, -3,
+ 10, 17, 19, 12, 3, -12, -21, -24, -24, -31, -40, -49, -52, -41, -30, -18,
+ -15, -17, -10, 0, 16, 33, 47, 59, 65, 64, 65, 67, 63, 56, 38, 13,
+ -12, -32, -41, -39, -35, -33, -32, -27, -17, -4, 8, 15, 16, 13, 4, -11,
+ -20, -25, -27, -32, -40, -48, -52, -46, -37, -25, -18, -16, -10, 1, 16, 33,
+ 49, 59, 66, 67, 65, 66, 62, 51, 38, 15, -9, -30, -38, -41, -33, -29,
+ -26, -23, -17, -5, 7, 16, 15, 14, 5, -9, -19, -27, -31, -34, -40, -47,
+ -52, -49, -40, -30, -22, -16, -8, 4, 19, 32, 46, 59, 67, 71, 69, 64,
+ 57, 49, 36, 17, -7, -27, -38, -40, -35, -28, -23, -19, -12, -5, 6, 12,
+ 16, 15, 10, -5, -19, -28, -32, -36, -39, -46, -53, -52, -45, -34, -25, -18,
+ -7, 6, 20, 33, 46, 60, 67, 74, 71, 65, 56, 46, 37, 18, -2, -20,
+ -33, -38, -38, -30, -22, -16, -12, -6, 2, 6, 15, 15, 11, 1, -11, -19,
+ -31, -37, -42, -46, -51, -54, -53, -46, -35, -26, -14, 3, 17, 33, 45, 57,
+ 67, 75, 77, 71, 62, 50, 36, 18, 0, -19, -31, -36, -37, -31, -23, -17,
+ -11, -6, 1, 6, 11, 15, 14, 8, -3, -16, -27, -37, -41, -47, -52, -58,
+ -60, -55, -46, -32, -16, 0, 17, 32, 46, 59, 70, 79, 80, 75, 65, 51,
+ 35, 20, 2, -15, -27, -38, -42, -36, -27, -17, -10, -4, 3, 7, 12, 18,
+ 19, 14, 5, -7, -22, -37, -46, -53, -57, -62, -67, -65, -58, -43, -22, 1,
+ 20, 35, 48, 60, 69, 79, 82, 79, 68, 53, 36, 21, 4, -11, -24, -36,
+ -40, -38, -31, -21, -14, -5, 1, 5, 11, 17, 22, 19, 14, -2, -17, -35,
+ -48, -55, -63, -67, -73, -72, -64, -49, -27, -4, 19, 36, 52, 64, 73, 81,
+ 85, 82, 72, 56, 36, 20, 3, -14, -24, -33, -36, -35, -32, -22, -13, -6,
+ 2, 7, 10, 15, 19, 19, 17, 6, -10, -29, -48, -58, -67, -71, -75, -78,
+ -72, -58, -35, -10, 16, 35, 52, 65, 74, 80, 86, 87, 79, 62, 39, 21,
+ 5, -11, -22, -33, -39, -39, -34, -25, -15, -7, 3, 8, 16, 17, 21, 22,
+ 19, 9, -6, -27, -47, -60, -71, -77, -80, -81, -73, -61, -39, -12, 16, 36,
+ 52, 63, 73, 80, 85, 87, 76, 59, 41, 23, 8, -7, -18, -29, -36, -38,
+ -33, -23, -13, -8, 1, 6, 14, 18, 19, 23, 23, 17, 1, -20, -43, -57,
+ -67, -78, -83, -89, -81, -67, -45, -19, 9, 35, 55, 67, 74, 80, 87, 91,
+ 83, 68, 44, 24, 6, -9, -21, -29, -36, -39, -39, -31, -20, -10, 1, 13,
+ 20, 26, 26, 27, 28, 22, 8, -16, -40, -60, -75, -86, -93, -95, -89, -75,
+ -52, -24, 7, 37, 57, 69, 77, 83, 90, 93, 85, 70, 48, 27, 8, -8,
+ -19, -26, -32, -35, -39, -37, -28, -17, -2, 9, 19, 21, 27, 31, 32, 29,
+ 12, -9, -32, -54, -71, -86, -94, -96, -90, -82, -62, -33, 2, 34, 56, 69,
+ 78, 87, 94, 94, 85, 69, 49, 29, 9, -10, -21, -27, -30, -33, -37, -36,
+ -29, -17, -5, 9, 19, 25, 27, 31, 33, 33, 21, -2, -25, -51, -71, -86,
+ -95, -95, -92, -85, -69, -42, -8, 27, 52, 67, 74, 83, 92, 95, 89, 75,
+ 56, 35, 16, -6, -17, -26, -28, -34, -41, -39, -37, -25, -9, 6, 20, 28,
+ 31, 37, 37, 34, 24, 3, -20, -46, -69, -85, -96, -99, -97, -89, -73, -47,
+ -11, 21, 45, 61, 73, 84, 92, 95, 89, 77, 61, 41, 20, -2, -13, -20,
+ -28, -36, -43, -46, -40, -30, -16, 0, 12, 24, 30, 38, 43, 41, 33, 13,
+ -14, -39, -63, -80, -93, -98, -100, -94, -76, -52, -19, 14, 38, 56, 70, 80,
+ 90, 94, 88, 75, 58, 40, 22, 6, -8, -19, -25, -33, -39, -41, -38, -31,
+ -19, -5, 7, 21, 31, 39, 45, 42, 32, 15, -8, -32, -55, -77, -93, -102,
+ -101, -94, -80, -57, -29, 5, 34, 54, 70, 78, 88, 96, 92, 80, 62, 41,
+ 24, 8, -9, -21, -32, -35, -38, -41, -39, -35, -22, -6, 6, 21, 31, 39,
+ 46, 44, 35, 18, -5, -27, -49, -70, -86, -97, -102, -96, -84, -58, -30, -2,
+ 26, 45, 62, 74, 82, 89, 89, 80, 66, 46, 28, 12, -3, -14, -26, -36,
+ -39, -42, -40, -36, -28, -15, 0, 17, 30, 37, 45, 48, 40, 23, 3, -20,
+ -43, -64, -81, -93, -98, -96, -85, -65, -38, -8, 20, 40, 55, 68, 80, 88,
+ 88, 82, 68, 54, 35, 18, 2, -12, -24, -35, -40, -45, -45, -41, -33, -20,
+ -4, 15, 31, 41, 49, 52, 48, 32, 13, -14, -38, -59, -77, -92, -101, -102,
+ -91, -70, -45, -15, 15, 38, 53, 65, 77, 89, 91, 85, 71, 52, 38, 21,
+ 5, -12, -26, -36, -42, -45, -45, -43, -34, -22, -7, 9, 26, 39, 50, 56,
+ 50, 34, 14, -7, -29, -50, -69, -84, -96, -98, -90, -72, -50, -24, 7, 32,
+ 48, 57, 68, 84, 91, 88, 74, 58, 44, 30, 11, -9, -26, -38, -41, -46,
+ -45, -44, -38, -23, -7, 9, 24, 36, 49, 55, 51, 35, 18, -3, -24, -45,
+ -64, -78, -89, -93, -90, -75, -54, -29, 0, 23, 42, 54, 67, 80, 90, 91,
+ 81, 65, 48, 31, 13, -5, -24, -41, -50, -53, -51, -46, -42, -28, -10, 8,
+ 23, 36, 50, 59, 56, 44, 26, 8, -13, -35, -56, -77, -89, -94, -92, -80,
+ -61, -39, -11, 14, 33, 50, 63, 77, 88, 89, 81, 67, 54, 38, 21, 1,
+ -23, -39, -50, -54, -53, -46, -42, -31, -17, 1, 17, 33, 46, 56, 56, 46,
+ 33, 16, -4, -24, -46, -67, -82, -92, -94, -87, -67, -45, -19, 4, 22, 43,
+ 62, 76, 87, 90, 87, 76, 59, 40, 20, 1, -22, -40, -55, -62, -58, -50,
+ -40, -29, -17, -3, 14, 33, 49, 59, 58, 49, 35, 21, 2, -17, -39, -59,
+ -76, -90, -93, -86, -70, -49, -29, -8, 12, 33, 57, 75, 84, 87, 84, 78,
+ 65, 47, 28, 6, -18, -39, -58, -65, -64, -57, -44, -33, -22, -10, 6, 26,
+ 44, 56, 56, 48, 40, 27, 11, -8, -30, -49, -65, -80, -86, -87, -72, -51,
+ -31, -13, 5, 24, 48, 70, 81, 86, 83, 79, 69, 51, 30, 8, -16, -37,
+ -55, -65, -67, -61, -48, -36, -21, -10, 5, 22, 40, 55, 58, 53, 43, 31,
+ 16, -2, -23, -45, -60, -74, -82, -86, -75, -56, -36, -16, 1, 21, 44, 65,
+ 81, 88, 85, 81, 72, 54, 33, 8, -18, -41, -58, -71, -74, -70, -56, -41,
+ -23, -6, 8, 23, 38, 53, 60, 59, 50, 37, 22, 1, -20, -41, -56, -69,
+ -79, -83, -78, -62, -42, -20, 2, 22, 41, 59, 77, 86, 87, 79, 67, 50,
+ 31, 10, -15, -36, -52, -63, -69, -69, -59, -41, -23, -9, 4, 15, 29, 44,
+ 55, 56, 53, 43, 27, 12, -8, -27, -44, -57, -68, -78, -77, -67, -48, -29,
+ -12, 12, 32, 52, 70, 79, 84, 82, 73, 59, 38, 15, -9, -33, -52, -63,
+ -71, -72, -66, -50, -30, -13, 2, 12, 27, 42, 50, 54, 54, 46, 34, 19,
+ -2, -19, -35, -47, -61, -71, -72, -66, -51, -36, -19, 5, 27, 46, 63, 74,
+ 79, 79, 70, 58, 41, 21, 3, -24, -44, -58, -66, -66, -65, -52, -36, -22,
+ -10, 4, 18, 34, 43, 49, 52, 48, 43, 31, 14, -4, -21, -35, -51, -61,
+ -66, -64, -56, -43, -29, -8, 16, 37, 54, 67, 72, 74, 70, 61, 46, 27,
+ 7, -19, -40, -56, -62, -62, -63, -55, -43, -26, -10, 3, 13, 26, 38, 44,
+ 47, 43, 39, 30, 19, 5, -12, -24, -40, -47, -51, -53, -51, -44, -32, -14,
+ 6, 24, 41, 54, 61, 63, 61, 56, 47, 32, 13, -9, -31, -46, -56, -53,
+ -54, -54, -48, -37, -18, -3, 8, 17, 27, 33, 38, 39, 39, 37, 30, 18,
+ 1, -16, -29, -35, -39, -42, -47, -47, -39, -22, -3, 14, 29, 42, 51, 57,
+ 56, 54, 45, 36, 20, -2, -23, -41, -50, -51, -52, -53, -51, -42, -27, -8,
+ 5, 12, 19, 28, 35, 40, 39, 40, 37, 28, 12, -7, -23, -28, -30, -37,
+ -43, -49, -45, -32, -15, 3, 19, 34, 45, 49, 49, 51, 47, 41, 26, 6,
+ -18, -34, -43, -45, -45, -48, -51, -49, -33, -15, -2, 8, 12, 19, 26, 33,
+ 38, 38, 38, 34, 25, 8, -11, -19, -20, -23, -32, -43, -48, -41, -24, -8,
+ 10, 21, 31, 38, 43, 47, 48, 45, 34, 16, -9, -31, -41, -42, -42, -46,
+ -52, -52, -40, -23, -6, 6, 11, 17, 24, 30, 35, 38, 39, 40, 29, 14,
+ -3, -14, -14, -15, -24, -36, -47, -45, -33, -15, 3, 14, 23, 29, 35, 39,
+ 44, 45, 38, 22, -3, -26, -38, -37, -37, -41, -50, -56, -45, -26, -8, 5,
+ 12, 16, 22, 27, 32, 39, 41, 41, 33, 17, 1, -9, -8, -8, -16, -30,
+ -41, -45, -35, -21, -5, 10, 18, 24, 28, 31, 38, 42, 39, 25, 2, -23,
+ -36, -36, -37, -39, -47, -53, -47, -31, -11, 3, 12, 16, 23, 27, 32, 37,
+ 40, 41, 33, 18, 2, -7, -8, -6, -10, -23, -36, -41, -35, -20, -6, 7,
+ 14, 17, 24, 29, 36, 42, 40, 28, 5, -20, -35, -38, -38, -39, -45, -51,
+ -46, -33, -15, 2, 13, 22, 27, 28, 27, 30, 37, 41, 35, 20, 5, -4,
+ -4, -2, -3, -13, -28, -35, -32, -23, -10, 3, 11, 14, 14, 20, 28, 37,
+ 40, 27, 7, -16, -31, -36, -37, -36, -41, -44, -45, -35, -18, 1, 12, 19,
+ 25, 26, 27, 31, 34, 39, 34, 20, 8, 0, 0, 1, 0, -9, -23, -33,
+ -34, -24, -10, 2, 8, 8, 10, 16, 27, 34, 35, 27, 10, -10, -27, -35,
+ -35, -34, -39, -46, -47, -38, -22, -3, 10, 19, 26, 31, 32, 32, 35, 41,
+ 39, 25, 9, -2, -3, -2, -2, -7, -19, -30, -33, -26, -14, -3, 6, 6,
+ 7, 12, 26, 37, 37, 26, 10, -8, -25, -35, -39, -39, -42, -47, -49, -42,
+ -27, -4, 12, 20, 29, 33, 36, 35, 35, 38, 37, 27, 10, -3, -6, -3,
+ -2, -7, -16, -24, -28, -24, -13, -4, 4, 5, 7, 9, 19, 30, 33, 28,
+ 12, -6, -24, -35, -40, -39, -42, -47, -47, -41, -26, -8, 10, 22, 31, 36,
+ 41, 39, 34, 33, 33, 29, 15, 2, -7, -8, -6, -6, -10, -18, -24, -24,
+ -15, -5, 6, 7, 7, 10, 17, 23, 23, 18, 9, -7, -23, -36, -42, -41,
+ -41, -45, -45, -39, -28, -11, 7, 21, 31, 36, 39, 39, 34, 31, 33, 29,
+ 19, 7, -5, -6, -6, -4, -6, -13, -17, -20, -16, -8, 1, 6, 7, 7,
+ 11, 16, 20, 18, 9, -7, -24, -37, -43, -42, -42, -42, -45, -41, -28, -11,
+ 7, 19, 28, 35, 40, 42, 38, 33, 29, 27, 21, 10, -2, -8, -8, -6,
+ -8, -11, -13, -16, -14, -8, 1, 5, 8, 9, 15, 19, 20, 18, 9, -4,
+ -18, -34, -42, -46, -47, -45, -47, -45, -36, -20, 0, 13, 26, 36, 45, 48,
+ 42, 35, 29, 28, 26, 20, 6, -6, -10, -10, -6, -7, -8, -10, -14, -10,
+ -7, 0, 6, 8, 13, 14, 16, 13, 7, -3, -13, -27, -37, -44, -49, -44,
+ -42, -40, -37, -25, -9, 9, 23, 31, 41, 44, 44, 37, 30, 27, 28, 27,
+ 15, 2, -7, -9, -6, -7, -9, -8, -13, -12, -8, -3, 4, 9, 13, 14,
+ 14, 11, 6, 0, -9, -23, -34, -43, -49, -46, -42, -40, -35, -29, -13, 3,
+ 19, 31, 41, 45, 43, 37, 31, 29, 30, 28, 19, 4, -5, -7, -7, -5,
+ -8, -7, -9, -11, -9, -4, 0, 6, 12, 14, 13, 9, 5, -3, -9, -19,
+ -28, -37, -48, -48, -45, -39, -34, -30, -18, -5, 12, 23, 34, 42, 44, 39,
+ 34, 32, 31, 33, 30, 18, 8, 1, -5, -6, -5, -5, -8, -13, -16, -14,
+ -7, 2, 7, 11, 10, 7, 4, -2, -7, -12, -22, -32, -45, -50, -45, -38,
+ -33, -30, -24, -13, 2, 20, 31, 39, 43, 42, 38, 36, 33, 33, 33, 24,
+ 14, 1, -8, -9, -7, -4, -5, -11, -16, -16, -11, -4, 2, 9, 8, 7,
+ 3, -3, -6, -9, -15, -24, -38, -47, -48, -42, -35, -32, -29, -21, -9, 11,
+ 27, 35, 42, 42, 42, 40, 40, 38, 36, 30, 19, 8, -4, -9, -8, -5,
+ -5, -12, -18, -20, -15, -5, -2, 3, 4, 5, 6, 1, -3, -8, -12, -19,
+ -31, -43, -47, -43, -36, -35, -36, -32, -19, 2, 19, 30, 38, 42, 46, 49,
+ 50, 47, 43, 39, 28, 16, 1, -10, -13, -11, -9, -14, -21, -25, -20, -10,
+ -4, 1, 3, 4, 7, 4, -3, -7, -7, -10, -23, -38, -47, -46, -41, -37,
+ -38, -37, -27, -11, 11, 24, 33, 38, 45, 50, 53, 52, 48, 43, 37, 25,
+ 10, -3, -11, -11, -11, -13, -20, -27, -29, -22, -14, -7, -2, 2, 6, 3,
+ -2, -3, 0, 0, -11, -28, -41, -45, -39, -35, -36, -39, -37, -24, -7, 11,
+ 22, 32, 41, 51, 55, 56, 54, 53, 50, 40, 23, 6, -5, -10, -11, -14,
+ -20, -28, -34, -33, -25, -16, -10, -5, 0, 0, 1, 2, 4, 5, -4, -16,
+ -29, -35, -37, -37, -35, -39, -39, -32, -19, 0, 13, 23, 36, 46, 54, 58,
+ 57, 59, 56, 47, 33, 16, 3, -5, -9, -11, -19, -29, -36, -39, -33, -26,
+ -18, -12, -7, -5, -2, 4, 11, 15, 10, -3, -18, -29, -32, -35, -36, -41,
+ -44, -40, -30, -18, 0, 13, 28, 41, 50, 59, 63, 66, 66, 60, 44, 26,
+ 11, 2, -6, -12, -19, -29, -38, -44, -41, -33, -25, -16, -9, -8, -6, 1,
+ 11, 18, 16, 8, -6, -17, -27, -32, -36, -39, -43, -44, -37, -30, -12, 8,
+ 26, 39, 46, 56, 64, 70, 72, 66, 51, 36, 18, 7, -4, -11, -18, -29,
+ -42, -50, -51, -45, -35, -23, -14, -10, -9, 0, 14, 27, 29, 20, 7, -5,
+ -15, -23, -30, -38, -45, -50, -49, -43, -30, -9, 13, 31, 41, 52, 65, 75,
+ 79, 77, 66, 50, 30, 13, 3, -6, -14, -26, -41, -53, -57, -54, -44, -32,
+ -23, -17, -13, -5, 10, 24, 31, 28, 20, 9, -5, -17, -26, -35, -40, -48,
+ -54, -53, -44, -23, 0, 21, 35, 46, 60, 73, 81, 83, 77, 60, 42, 25,
+ 11, 1, -11, -25, -42, -57, -64, -62, -54, -43, -33, -24, -17, -6, 9, 23,
+ 37, 37, 33, 19, 6, -9, -20, -30, -41, -49, -57, -59, -54, -38, -16, 10,
+ 31, 46, 58, 70, 78, 85, 84, 73, 54, 32, 16, 5, -5, -22, -41, -60,
+ -72, -71, -66, -54, -43, -30, -19, -6, 10, 25, 41, 47, 43, 32, 20, 7,
+ -10, -25, -40, -52, -61, -68, -65, -54, -34, -11, 16, 39, 57, 72, 80, 88,
+ 91, 83, 67, 46, 28, 13, 1, -18, -40, -62, -77, -77, -70, -63, -54, -43,
+ -30, -12, 7, 25, 40, 51, 51, 42, 31, 19, 3, -13, -32, -48, -60, -68,
+ -71, -63, -49, -28, -2, 23, 46, 66, 77, 86, 92, 89, 82, 62, 43, 22,
+ 7, -12, -39, -59, -74, -80, -78, -72, -63, -50, -35, -17, 5, 22, 35, 45,
+ 49, 49, 42, 31, 13, -7, -25, -38, -49, -59, -66, -65, -57, -42, -20, 8,
+ 34, 55, 69, 79, 84, 84, 84, 77, 64, 42, 18, -6, -29, -49, -69, -82,
+ -87, -87, -78, -66, -48, -27, -4, 17, 33, 47, 56, 60, 58, 49, 31, 8,
+ -18, -36, -47, -57, -67, -75, -74, -60, -36, -3, 25, 48, 65, 76, 83, 87,
+ 90, 88, 77, 52, 24, -4, -26, -42, -61, -77, -91, -94, -85, -70, -54, -34,
+ -11, 12, 30, 44, 56, 63, 66, 61, 43, 19, -8, -27, -39, -49, -62, -74,
+ -80, -71, -49, -20, 9, 34, 56, 70, 79, 86, 93, 96, 91, 70, 41, 11,
+ -18, -39, -58, -77, -91, -99, -95, -83, -65, -42, -17, 7, 27, 43, 57, 66,
+ 69, 67, 55, 32, 5, -21, -32, -42, -56, -73, -84, -79, -60, -33, -5, 21,
+ 44, 61, 72, 80, 92, 100, 99, 82, 54, 23, -10, -31, -51, -71, -87, -101,
+ -101, -92, -76, -49, -24, 1, 21, 37, 52, 66, 72, 72, 64, 44, 18, -7,
+ -23, -31, -45, -64, -79, -83, -71, -46, -18, 7, 27, 46, 62, 72, 85, 97,
+ 100, 92, 65, 35, 2, -22, -40, -60, -78, -92, -100, -96, -82, -59, -29, -6,
+ 15, 28, 44, 57, 65, 67, 65, 49, 27, 2, -17, -23, -35, -53, -70, -79,
+ -73, -52, -27, -4, 16, 35, 54, 65, 77, 88, 95, 93, 73, 44, 12, -17,
+ -38, -54, -74, -86, -97, -98, -89, -69, -37, -11, 9, 27, 42, 56, 65, 68,
+ 71, 59, 39, 13, -9, -20, -30, -45, -62, -74, -75, -60, -41, -18, 3, 23,
+ 43, 60, 74, 83, 91, 91, 78, 52, 22, -8, -30, -46, -66, -82, -90, -92,
+ -85, -70, -44, -17, 5, 22, 33, 45, 56, 60, 63, 56, 39, 21, 5, -9,
+ -20, -33, -49, -62, -70, -62, -47, -28, -9, 11, 29, 47, 60, 73, 83, 87,
+ 81, 62, 32, 4, -21, -39, -60, -78, -88, -90, -86, -73, -55, -28, -2, 18,
+ 30, 42, 50, 57, 58, 53, 44, 27, 15, 4, -10, -24, -40, -53, -59, -57,
+ -49, -38, -21, -3, 17, 34, 49, 62, 75, 81, 76, 63, 39, 15, -11, -31,
+ -50, -69, -79, -84, -82, -73, -57, -34, -7, 12, 26, 35, 42, 50, 56, 53,
+ 42, 31, 20, 13, 1, -16, -30, -43, -50, -51, -49, -42, -28, -11, 7, 23,
+ 38, 52, 65, 75, 73, 62, 43, 20, -2, -24, -43, -60, -69, -74, -74, -69,
+ -59, -42, -19, 2, 19, 27, 34, 41, 48, 50, 45, 39, 33, 25, 13, -3,
+ -18, -32, -42, -47, -49, -47, -40, -27, -8, 11, 28, 43, 57, 69, 73, 65,
+ 50, 31, 8, -16, -36, -53, -63, -70, -72, -70, -62, -46, -25, -6, 11, 23,
+ 30, 38, 45, 49, 50, 46, 42, 33, 22, 6, -13, -25, -37, -43, -48, -50,
+ -45, -35, -18, 2, 21, 39, 51, 61, 64, 63, 53, 38, 19, -6, -30, -49,
+ -59, -63, -65, -66, -64, -52, -31, -14, 2, 13, 25, 35, 42, 46, 46, 47,
+ 48, 44, 33, 15, -6, -21, -32, -37, -42, -48, -46, -39, -26, -8, 12, 31,
+ 45, 55, 58, 57, 51, 39, 22, 2, -21, -39, -49, -56, -59, -62, -59, -52,
+ -38, -22, -9, 5, 16, 25, 32, 40, 46, 51, 54, 52, 40, 24, 5, -11,
+ -20, -28, -35, -44, -48, -43, -33, -17, 0, 18, 32, 44, 48, 49, 48, 40,
+ 28, 11, -10, -26, -37, -45, -52, -58, -57, -51, -41, -29, -19, -10, 3, 15,
+ 27, 36, 40, 50, 59, 60, 51, 33, 15, 2, -11, -21, -34, -45, -49, -45,
+ -36, -25, -11, 8, 26, 38, 43, 42, 41, 39, 31, 16, -5, -24, -31, -37,
+ -43, -51, -54, -49, -40, -31, -24, -13, -3, 12, 22, 29, 33, 43, 55, 60,
+ 53, 37, 18, 5, -4, -12, -23, -35, -44, -42, -35, -26, -15, -2, 15, 26,
+ 33, 31, 31, 29, 28, 21, 6, -13, -27, -30, -37, -44, -48, -45, -39, -34,
+ -28, -18, -8, 4, 17, 23, 31, 40, 51, 58, 56, 42, 25, 12, 2, -7,
+ -16, -27, -36, -39, -37, -31, -21, -12, 3, 14, 21, 25, 23, 23, 25, 23,
+ 11, -4, -16, -21, -26, -34, -39, -40, -34, -31, -30, -23, -17, -3, 9, 16,
+ 23, 31, 42, 54, 57, 49, 29, 14, 7, 4, -3, -15, -26, -32, -32, -31,
+ -24, -16, -5, 5, 8, 10, 9, 10, 16, 19, 14, 4, -8, -14, -16, -21,
+ -29, -34, -33, -30, -29, -26, -20, -10, 2, 11, 20, 28, 40, 51, 55, 51,
+ 33, 17, 9, 6, 4, -9, -20, -28, -32, -29, -25, -20, -11, -2, 3, 4,
+ 1, 6, 12, 18, 16, 8, -5, -10, -14, -17, -20, -23, -25, -26, -28, -26,
+ -21, -12, -2, 6, 13, 20, 29, 40, 48, 48, 37, 23, 13, 8, 7, 3,
+ -6, -15, -22, -24, -24, -21, -16, -10, -6, -11, -15, -10, 1, 12, 15, 9,
+ 4, 3, 1, -5, -11, -18, -18, -22, -25, -29, -27, -19, -7, 4, 10, 14,
+ 21, 35, 46, 48, 40, 27, 16, 13, 11, 11, 5, -5, -14, -19, -21, -24,
+ -19, -14, -13, -17, -21, -21, -11, 1, 11, 12, 5, 3, 2, 5, 6, 0,
+ -6, -16, -20, -25, -26, -20, -12, -4, 1, 5, 11, 25, 38, 46, 41, 33,
+ 21, 17, 15, 15, 14, 8, -3, -14, -23, -27, -26, -21, -20, -22, -26, -25,
+ -20, -7, 5, 10, 10, 8, 5, 6, 6, 5, 1, -7, -14, -20, -23, -21,
+ -17, -11, -4, 2, 7, 17, 29, 38, 40, 37, 30, 23, 21, 20, 17, 14,
+ 5, -6, -19, -26, -29, -25, -24, -27, -28, -28, -26, -18, -4, 6, 9, 8,
+ 4, 5, 10, 12, 11, 3, -8, -15, -18, -18, -15, -11, -10, -5, 1, 8,
+ 16, 26, 35, 35, 31, 24, 22, 21, 22, 21, 16, 5, -12, -24, -30, -31,
+ -29, -31, -32, -31, -32, -22, -12, 0, 7, 11, 12, 10, 11, 15, 13, 10,
+ 2, -10, -13, -16, -17, -14, -14, -12, -6, 0, 10, 20, 26, 32, 30, 29,
+ 27, 26, 28, 26, 22, 13, -2, -16, -25, -30, -32, -33, -35, -35, -34, -28,
+ -19, -12, -5, 1, 5, 9, 11, 16, 17, 18, 11, 3, -4, -10, -12, -13,
+ -12, -13, -14, -10, -4, 8, 20, 27, 31, 31, 28, 29, 31, 30, 26, 17,
+ 5, -9, -23, -32, -37, -36, -34, -35, -34, -32, -24, -16, -7, 2, 4, 6,
+ 10, 16, 17, 15, 12, 8, 3, -5, -11, -11, -10, -11, -12, -11, -5, 3,
+ 13, 22, 30, 32, 27, 25, 25, 28, 27, 19, 7, -8, -22, -31, -34, -32,
+ -30, -28, -31, -31, -29, -21, -12, -4, 1, 1, 3, 10, 16, 18, 18, 14,
+ 12, 3, -5, -8, -7, -8, -10, -12, -12, -5, 6, 16, 26, 30, 29, 24,
+ 25, 26, 29, 23, 13, -2, -16, -26, -32, -33, -30, -30, -30, -30, -29, -25,
+ -18, -12, -5, -2, 2, 8, 14, 18, 16, 18, 14, 10, 4, 0, -5, -4,
+ -7, -9, -14, -10, -3, 9, 19, 26, 26, 23, 23, 26, 29, 28, 21, 7,
+ -10, -19, -25, -26, -27, -27, -29, -30, -32, -31, -27, -19, -13, -9, -7, 0,
+ 9, 18, 24, 26, 21, 13, 9, 8, 4, -2, -6, -9, -11, -11, -7, 4,
+ 16, 24, 26, 21, 19, 22, 26, 29, 23, 7, -10, -17, -19, -19, -23, -25,
+ -25, -25, -26, -26, -29, -26, -17, -14, -9, -7, 1, 12, 21, 26, 23, 18,
+ 13, 11, 11, 6, -4, -6, -10, -10, -9, -2, 9, 20, 25, 23, 18, 18,
+ 23, 26, 24, 10, -5, -13, -17, -14, -15, -17, -20, -24, -25, -29, -31, -32,
+ -28, -22, -16, -13, -8, 2, 14, 25, 27, 27, 22, 17, 15, 13, 10, 5,
+ -3, -6, -8, -6, 1, 11, 18, 20, 13, 11, 15, 19, 20, 14, 4, -4,
+ -12, -12, -12, -12, -14, -17, -23, -30, -35, -37, -31, -26, -20, -16, -12, -4,
+ 9, 22, 28, 26, 22, 17, 14, 15, 11, 8, 6, 2, 0, -2, 4, 11,
+ 16, 16, 12, 7, 8, 13, 13, 10, 1, -5, -8, -8, -8, -7, -7, -10,
+ -20, -26, -34, -36, -33, -31, -29, -25, -19, -12, 4, 18, 27, 28, 23, 22,
+ 18, 19, 17, 14, 9, 7, 4, 0, 2, 8, 14, 16, 12, 2, 0, 2,
+ 5, 6, 2, -4, -7, -6, -2, -2, -3, -5, -11, -19, -28, -37, -37, -37,
+ -34, -29, -24, -18, -8, 7, 20, 25, 25, 25, 22, 21, 21, 21, 19, 15,
+ 11, 6, 6, 6, 10, 11, 6, -2, -5, -5, -2, 0, 0, 0, -4, 0,
+ 2, 4, 2, -2, -8, -16, -25, -34, -39, -42, -39, -33, -26, -21, -16, -4,
+ 11, 22, 25, 27, 25, 23, 23, 24, 25, 22, 17, 13, 10, 9, 12, 10,
+ 4, -5, -12, -12, -11, -9, -8, -6, -5, 1, 4, 8, 10, 7, 4, -7,
+ -18, -26, -34, -39, -43, -42, -34, -28, -22, -13, 2, 14, 18, 21, 23, 27,
+ 30, 32, 31, 28, 23, 20, 20, 15, 14, 10, 2, -5, -13, -15, -16, -16,
+ -12, -12, -5, 1, 5, 8, 8, 10, 8, 0, -13, -23, -27, -33, -40, -44,
+ -41, -32, -24, -17, -6, 3, 9, 17, 22, 25, 29, 34, 39, 36, 32, 26,
+ 25, 23, 19, 11, 1, -9, -16, -18, -17, -19, -21, -17, -8, 0, 4, 7,
+ 8, 10, 11, 6, -4, -13, -21, -25, -35, -40, -41, -37, -26, -21, -13, -8,
+ -3, 6, 15, 23, 27, 35, 40, 41, 38, 33, 31, 29, 24, 16, 5, -5,
+ -16, -23, -23, -23, -18, -14, -6, 2, 3, 4, 7, 11, 13, 7, -5, -13,
+ -21, -25, -32, -40, -42, -37, -28, -21, -14, -13, -9, 1, 11, 22, 27, 33,
+ 39, 43, 42, 41, 33, 29, 25, 18, 7, -6, -17, -25, -24, -23, -21, -16,
+ -9, 2, 6, 5, 5, 10, 15, 12, 3, -8, -16, -22, -29, -39, -44, -42,
+ -34, -27, -22, -21, -17, -8, 4, 19, 29, 40, 48, 53, 51, 49, 43, 38,
+ 28, 19, 6, -9, -19, -27, -30, -30, -24, -16, -10, -3, 3, 6, 5, 6,
+ 9, 11, 7, 2, -7, -16, -25, -34, -37, -37, -33, -31, -28, -27, -24, -20,
+ -10, 8, 22, 35, 46, 52, 53, 54, 49, 46, 37, 23, 9, -7, -18, -24,
+ -30, -32, -28, -22, -12, -5, 1, 6, 4, 8, 9, 11, 9, 3, -3, -13,
+ -21, -32, -37, -38, -35, -34, -32, -32, -32, -27, -14, 5, 24, 38, 48, 55,
+ 56, 56, 54, 50, 40, 23, 4, -10, -18, -24, -26, -29, -29, -24, -17, -5,
+ 2, 9, 9, 6, 6, 7, 12, 11, 6, -7, -18, -30, -36, -36, -37, -35,
+ -38, -40, -41, -36, -24, -2, 20, 35, 47, 55, 60, 62, 62, 61, 47, 26,
+ 7, -12, -18, -22, -24, -28, -33, -31, -24, -12, -2, 7, 9, 5, 4, 5,
+ 11, 14, 13, 7, -8, -24, -37, -41, -38, -34, -37, -44, -50, -46, -33, -10,
+ 16, 36, 49, 57, 61, 64, 66, 65, 55, 34, 11, -14, -24, -26, -26, -24,
+ -30, -34, -33, -24, -7, 5, 12, 10, 5, 6, 9, 16, 22, 21, 10, -10,
+ -32, -45, -44, -38, -38, -47, -61, -60, -48, -21, 11, 34, 51, 60, 63, 66,
+ 70, 69, 63, 45, 18, -10, -27, -27, -23, -20, -28, -36, -37, -32, -17, -2,
+ 8, 9, 5, 6, 8, 15, 24, 30, 25, 5, -22, -41, -44, -40, -38, -50,
+ -64, -72, -62, -37, -3, 29, 52, 62, 66, 69, 73, 78, 72, 54, 26, -5,
+ -25, -32, -29, -24, -27, -34, -37, -36, -26, -11, 5, 15, 15, 11, 9, 15,
+ 26, 35, 33, 14, -14, -37, -49, -47, -45, -51, -63, -72, -66, -42, -10, 22,
+ 49, 64, 69, 69, 70, 75, 73, 59, 34, 4, -20, -30, -30, -25, -24, -29,
+ -36, -40, -35, -22, -2, 16, 20, 17, 14, 15, 27, 39, 41, 27, -4, -32,
+ -48, -54, -53, -59, -65, -73, -71, -55, -23, 16, 49, 67, 70, 68, 71, 77,
+ 78, 65, 40, 10, -17, -31, -34, -28, -24, -26, -31, -40, -40, -30, -10, 10,
+ 21, 18, 15, 16, 26, 40, 48, 40, 13, -20, -44, -55, -61, -63, -69, -76,
+ -76, -63, -35, 6, 41, 66, 75, 71, 71, 75, 77, 67, 44, 17, -10, -25,
+ -34, -35, -29, -27, -28, -35, -40, -35, -18, 1, 16, 21, 20, 19, 25, 38,
+ 47, 43, 23, -9, -34, -50, -59, -65, -72, -76, -74, -66, -43, -9, 27, 58,
+ 71, 69, 70, 71, 73, 67, 48, 25, 2, -18, -28, -33, -29, -25, -25, -31,
+ -39, -41, -28, -10, 8, 19, 20, 23, 27, 36, 45, 45, 31, 4, -22, -45,
+ -58, -67, -74, -75, -73, -66, -50, -21, 16, 49, 67, 73, 72, 72, 74, 69,
+ 53, 33, 9, -11, -25, -34, -35, -31, -27, -30, -38, -43, -33, -16, 6, 18,
+ 24, 27, 30, 38, 45, 46, 34, 10, -16, -40, -61, -70, -77, -76, -72, -66,
+ -52, -31, 2, 36, 60, 71, 72, 69, 71, 68, 57, 44, 20, 2, -17, -32,
+ -36, -33, -31, -31, -40, -46, -41, -29, -5, 16, 27, 34, 35, 41, 49, 51,
+ 41, 17, -11, -34, -56, -71, -79, -80, -76, -68, -57, -36, -10, 21, 48, 64,
+ 71, 71, 73, 69, 61, 48, 32, 11, -5, -21, -31, -34, -34, -37, -43, -48,
+ -45, -34, -14, 8, 25, 34, 41, 43, 49, 51, 43, 26, -2, -27, -49, -65,
+ -74, -77, -74, -70, -58, -42, -20, 9, 38, 56, 64, 67, 69, 71, 66, 53,
+ 37, 16, 1, -15, -30, -33, -39, -38, -41, -45, -42, -35, -15, 7, 25, 36,
+ 41, 45, 49, 49, 40, 23, 1, -20, -41, -59, -71, -75, -73, -65, -57, -45,
+ -28, -6, 22, 42, 56, 63, 67, 71, 70, 59, 44, 28, 12, -3, -19, -32,
+ -40, -41, -46, -47, -46, -37, -20, -2, 20, 34, 45, 48, 52, 53, 42, 26,
+ 4, -15, -35, -51, -65, -70, -70, -68, -61, -50, -34, -15, 9, 28, 45, 54,
+ 64, 71, 72, 67, 53, 40, 24, 8, -10, -27, -37, -41, -49, -53, -53, -42,
+ -25, -8, 14, 31, 43, 52, 56, 56, 46, 30, 11, -8, -26, -43, -59, -70,
+ -69, -68, -62, -55, -44, -25, -4, 17, 36, 48, 62, 69, 69, 67, 57, 47,
+ 33, 17, -2, -21, -33, -41, -47, -52, -53, -43, -25, -10, 9, 23, 36, 46,
+ 52, 54, 47, 31, 14, -4, -19, -32, -49, -57, -62, -60, -57, -58, -51, -39,
+ -19, 6, 23, 38, 51, 60, 68, 71, 67, 58, 44, 27, 7, -17, -32, -41,
+ -47, -52, -54, -46, -31, -12, 7, 22, 35, 45, 51, 53, 46, 33, 18, 2,
+ -12, -26, -42, -55, -61, -60, -56, -57, -55, -46, -29, -8, 10, 27, 42, 55,
+ 65, 70, 69, 61, 49, 34, 16, -5, -23, -36, -45, -51, -54, -50, -35, -17,
+ 3, 17, 29, 37, 44, 51, 47, 39, 21, 6, -8, -20, -31, -44, -52, -58,
+ -60, -58, -58, -51, -39, -22, -4, 14, 31, 48, 62, 70, 69, 65, 57, 45,
+ 28, 7, -15, -31, -44, -50, -53, -50, -39, -24, -6, 11, 24, 33, 43, 46,
+ 45, 35, 25, 14, 1, -13, -23, -35, -44, -53, -57, -59, -59, -57, -47, -33,
+ -15, 3, 21, 39, 56, 69, 72, 69, 60, 49, 36, 17, -5, -25, -42, -52,
+ -52, -48, -40, -26, -9, 9, 20, 29, 34, 39, 40, 34, 25, 16, 6, -6,
+ -16, -27, -34, -44, -50, -55, -58, -57, -52, -41, -27, -11, 11, 31, 51, 67,
+ 70, 68, 61, 53, 43, 30, 7, -14, -35, -49, -54, -50, -40, -26, -13, -2,
+ 9, 22, 30, 38, 41, 36, 28, 20, 12, 4, -5, -15, -26, -41, -52, -58,
+ -60, -60, -59, -55, -41, -25, -5, 19, 42, 62, 74, 75, 70, 63, 55, 43,
+ 22, -3, -24, -42, -51, -50, -45, -32, -22, -14, -2, 14, 28, 35, 34, 33,
+ 30, 25, 21, 11, 4, -6, -18, -32, -46, -56, -61, -61, -62, -60, -51, -39,
+ -16, 11, 37, 58, 70, 75, 72, 67, 58, 46, 31, 10, -17, -35, -48, -49,
+ -41, -28, -17, -14, -7, 4, 18, 28, 32, 29, 27, 21, 19, 16, 7, 2,
+ -11, -22, -35, -48, -57, -61, -60, -60, -56, -47, -30, -5, 23, 48, 63, 72,
+ 75, 71, 64, 53, 39, 20, -2, -22, -40, -48, -45, -34, -21, -17, -10, -4,
+ 10, 22, 27, 28, 29, 26, 26, 22, 14, 7, -3, -14, -30, -46, -59, -65,
+ -65, -65, -64, -56, -41, -17, 15, 42, 62, 73, 77, 75, 69, 57, 43, 25,
+ 6, -12, -31, -44, -46, -37, -24, -16, -11, -3, 6, 20, 24, 23, 24, 23,
+ 25, 23, 16, 9, 1, -10, -23, -41, -56, -63, -67, -67, -66, -59, -47, -25,
+ 3, 32, 54, 70, 75, 76, 70, 62, 47, 32, 15, -3, -21, -38, -44, -41,
+ -31, -21, -15, -11, -2, 8, 18, 24, 27, 28, 29, 29, 24, 17, 8, -2,
+ -17, -35, -54, -66, -73, -74, -71, -66, -55, -35, -6, 24, 50, 69, 77, 79,
+ 74, 63, 51, 38, 22, 2, -17, -35, -42, -39, -32, -24, -17, -11, -5, 6,
+ 13, 20, 28, 31, 33, 29, 23, 15, 10, 3, -12, -30, -51, -65, -73, -75,
+ -71, -67, -58, -41, -18, 11, 38, 60, 75, 77, 74, 64, 53, 42, 31, 15,
+ -7, -25, -38, -40, -37, -29, -24, -15, -11, -2, 9, 17, 28, 33, 36, 33,
+ 27, 18, 13, 4, -8, -26, -48, -65, -75, -76, -72, -68, -58, -43, -18, 11,
+ 37, 58, 72, 76, 73, 63, 51, 40, 28, 13, -6, -23, -35, -41, -40, -33,
+ -24, -16, -9, -2, 7, 18, 29, 38, 42, 38, 31, 21, 11, 3, -10, -26,
+ -47, -65, -75, -79, -75, -69, -58, -39, -19, 7, 33, 54, 71, 77, 75, 66,
+ 52, 39, 27, 15, -2, -22, -35, -41, -41, -36, -27, -17, -8, 1, 11, 22,
+ 33, 41, 47, 45, 35, 21, 11, 4, -7, -24, -46, -66, -77, -81, -79, -73,
+ -62, -44, -24, -2, 23, 47, 69, 79, 79, 70, 57, 45, 33, 20, 5, -18,
+ -36, -43, -41, -37, -32, -23, -14, -3, 8, 20, 34, 45, 53, 52, 41, 27,
+ 16, 7, -5, -24, -47, -69, -83, -86, -84, -74, -62, -44, -22, 1, 24, 47,
+ 66, 78, 76, 69, 57, 43, 31, 17, 5, -13, -33, -43, -46, -41, -31, -22,
+ -12, 0, 11, 24, 39, 49, 57, 58, 48, 30, 15, 4, -8, -26, -52, -74,
+ -86, -89, -83, -74, -60, -43, -21, 1, 22, 45, 65, 78, 79, 68, 54, 40,
+ 26, 17, 7, -9, -31, -45, -46, -40, -31, -21, -11, 0, 8, 21, 39, 51,
+ 60, 60, 52, 36, 19, 4, -9, -25, -49, -71, -87, -92, -89, -79, -63, -45,
+ -24, 0, 22, 43, 65, 75, 80, 70, 57, 44, 30, 16, 2, -14, -31, -46,
+ -52, -47, -35, -21, -9, 1, 12, 26, 44, 59, 68, 68, 59, 42, 22, 6,
+ -11, -29, -49, -72, -87, -96, -95, -86, -67, -46, -23, -4, 16, 38, 59, 76,
+ 82, 74, 61, 45, 31, 20, 3, -14, -30, -44, -51, -51, -41, -26, -11, 3,
+ 13, 25, 44, 61, 71, 72, 59, 45, 28, 9, -10, -33, -53, -70, -83, -93,
+ -96, -91, -74, -53, -27, -6, 15, 35, 53, 71, 80, 77, 66, 51, 34, 20,
+ 3, -15, -30, -45, -53, -55, -48, -32, -17, 1, 16, 29, 47, 62, 73, 77,
+ 67, 50, 30, 9, -10, -32, -55, -73, -86, -93, -94, -90, -76, -54, -27, -4,
+ 17, 32, 48, 64, 74, 78, 68, 55, 38, 17, 1, -15, -28, -39, -47, -52,
+ -49, -37, -21, -3, 16, 31, 46, 61, 70, 75, 70, 55, 36, 13, -9, -32,
+ -56, -72, -84, -89, -93, -91, -81, -61, -30, -5, 18, 32, 45, 58, 71, 76,
+ 70, 57, 40, 18, 1, -17, -28, -35, -45, -52, -50, -39, -25, -7, 15, 33,
+ 48, 60, 67, 73, 70, 60, 42, 19, -8, -34, -57, -69, -77, -83, -87, -92,
+ -85, -66, -39, -10, 12, 27, 39, 52, 62, 73, 72, 61, 46, 25, 4, -14,
+ -27, -34, -41, -46, -48, -43, -30, -11, 14, 38, 53, 63, 66, 69, 72, 65,
+ 48, 23, -4, -31, -56, -72, -81, -83, -87, -91, -87, -72, -46, -15, 11, 28,
+ 40, 50, 60, 71, 75, 69, 54, 32, 8, -13, -29, -39, -45, -48, -50, -48,
+ -40, -21, 9, 37, 57, 66, 71, 74, 75, 71, 55, 32, 2, -29, -55, -73,
+ -81, -84, -87, -89, -88, -75, -49, -19, 10, 29, 39, 48, 53, 62, 72, 68,
+ 58, 35, 9, -11, -27, -34, -39, -42, -44, -46, -41, -26, 5, 35, 56, 65,
+ 69, 72, 73, 72, 59, 37, 9, -22, -50, -71, -83, -83, -83, -86, -88, -81,
+ -55, -24, 5, 24, 37, 48, 54, 59, 64, 66, 59, 41, 17, -9, -27, -36,
+ -38, -39, -42, -45, -41, -28, -2, 28, 53, 65, 68, 71, 71, 70, 58, 40,
+ 16, -14, -46, -67, -79, -81, -80, -83, -87, -83, -64, -36, -4, 19, 35, 46,
+ 51, 58, 65, 69, 64, 49, 26, -2, -25, -38, -41, -39, -40, -43, -45, -33,
+ -8, 24, 52, 65, 72, 74, 72, 66, 55, 40, 20, -7, -38, -65, -80, -85,
+ -80, -82, -84, -82, -65, -38, -9, 13, 29, 41, 49, 57, 62, 64, 59, 48,
+ 29, 6, -19, -36, -39, -37, -35, -38, -39, -31, -11, 19, 47, 63, 70, 71,
+ 71, 65, 55, 38, 17, -4, -33, -58, -76, -83, -79, -79, -80, -82, -70, -46,
+ -19, 8, 25, 36, 43, 51, 59, 63, 62, 50, 34, 14, -9, -27, -35, -38,
+ -36, -38, -39, -30, -15, 10, 34, 52, 67, 73, 74, 68, 54, 37, 21, 2,
+ -21, -45, -68, -78, -81, -81, -80, -79, -70, -51, -28, -4, 17, 32, 40, 48,
+ 56, 59, 57, 46, 34, 18, 3, -20, -34, -39, -35, -31, -30, -26, -13, 8,
+ 31, 48, 61, 67, 69, 66, 53, 38, 16, -4, -23, -41, -58, -72, -78, -80,
+ -76, -74, -64, -50, -33, -8, 12, 28, 35, 41, 50, 57, 53, 44, 31, 20,
+ 10, -8, -24, -34, -34, -30, -25, -21, -13, 5, 22, 38, 52, 61, 66, 65,
+ 53, 36, 15, -4, -18, -33, -45, -61, -73, -79, -78, -72, -62, -49, -33, -13,
+ 3, 19, 29, 38, 48, 52, 49, 41, 29, 22, 14, 2, -11, -25, -27, -25,
+ -20, -15, -8, 4, 19, 30, 42, 53, 57, 61, 50, 32, 15, -7, -18, -27,
+ -37, -50, -65, -73, -72, -66, -57, -49, -37, -19, -3, 13, 23, 32, 41, 44,
+ 41, 35, 29, 26, 21, 10, -2, -13, -21, -18, -14, -8, -4, 3, 12, 21,
+ 29, 42, 51, 54, 49, 32, 14, -5, -15, -22, -28, -39, -55, -69, -68, -62,
+ -52, -44, -37, -25, -11, 4, 16, 24, 32, 37, 35, 28, 23, 23, 23, 18,
+ 8, -4, -12, -12, -8, -2, 5, 9, 14, 18, 23, 31, 41, 45, 43, 29,
+ 11, -8, -18, -23, -21, -29, -43, -60, -65, -58, -50, -39, -32, -26, -17, -6,
+ 8, 18, 25, 31, 29, 24, 17, 20, 24, 25, 19, 8, 0, -5, -3, 4,
+ 11, 13, 12, 14, 16, 22, 31, 38, 37, 27, 9, -11, -22, -24, -22, -25,
+ -36, -50, -57, -53, -46, -37, -30, -24, -17, -9, 1, 10, 16, 20, 19, 17,
+ 13, 14, 21, 24, 24, 19, 10, 8, 9, 13, 18, 20, 15, 12, 11, 14,
+ 21, 27, 30, 21, 8, -12, -23, -24, -22, -20, -29, -40, -49, -47, -41, -33,
+ -26, -23, -20, -16, -11, -2, 7, 12, 14, 14, 13, 14, 19, 26, 30, 26,
+ 20, 11, 11, 16, 21, 26, 22, 18, 15, 14, 15, 19, 20, 16, 4, -15,
+ -29, -32, -27, -21, -24, -34, -40, -41, -33, -28, -24, -21, -20, -15, -14, -10,
+ -5, 1, 7, 10, 10, 12, 18, 26, 36, 34, 27, 21, 17, 20, 23, 25,
+ 24, 19, 11, 10, 9, 12, 16, 14, 3, -16, -32, -34, -27, -19, -20, -27,
+ -34, -35, -31, -27, -22, -18, -18, -19, -19, -20, -15, -7, 2, 6, 8, 9,
+ 18, 26, 38, 41, 37, 28, 21, 23, 25, 27, 25, 20, 13, 7, 3, 5,
+ 9, 11, 4, -14, -31, -35, -29, -20, -18, -23, -26, -32, -29, -25, -23, -15,
+ -17, -18, -21, -25, -23, -15, -6, 0, 5, 6, 16, 25, 37, 45, 43, 36,
+ 27, 25, 28, 30, 29, 26, 16, 7, -2, -2, 2, 3, -2, -15, -31, -38,
+ -35, -23, -15, -15, -19, -23, -26, -23, -21, -15, -12, -18, -24, -27, -25, -19,
+ -9, -3, 2, 5, 12, 19, 32, 42, 45, 41, 31, 28, 31, 33, 37, 33,
+ 26, 14, 4, -2, -3, -3, -5, -18, -34, -43, -42, -31, -20, -18, -17, -19,
+ -18, -16, -13, -9, -8, -13, -22, -32, -32, -28, -19, -11, -6, -2, 7, 18,
+ 31, 42, 46, 46, 41, 36, 32, 35, 39, 39, 30, 17, 5, -3, -3, -3,
+ -7, -19, -32, -39, -41, -36, -26, -17, -12, -13, -18, -20, -14, -7, -6, -11,
+ -23, -32, -34, -28, -23, -15, -9, -2, 9, 17, 28, 37, 44, 48, 45, 38,
+ 32, 35, 41, 45, 37, 23, 10, 1, -3, -5, -8, -20, -35, -44, -44, -42,
+ -34, -24, -14, -10, -12, -14, -11, -6, -2, -5, -15, -25, -32, -29, -24, -19,
+ -15, -10, 1, 10, 20, 31, 40, 45, 48, 43, 39, 39, 45, 51, 43, 28,
+ 15, 2, -4, -8, -13, -20, -34, -42, -45, -45, -36, -26, -13, -8, -11, -13,
+ -8, -2, 1, -4, -13, -22, -30, -33, -28, -25, -18, -12, -5, 3, 13, 25,
+ 37, 46, 47, 45, 40, 41, 47, 53, 49, 35, 21, 10, 2, -6, -11, -22,
+ -32, -43, -50, -50, -47, -34, -17, -9, -9, -12, -9, 3, 7, 4, -8, -18,
+ -25, -31, -31, -27, -21, -16, -11, -8, 2, 17, 31, 45, 47, 44, 40, 43,
+ 54, 60, 58, 42, 26, 14, 4, -5, -14, -26, -37, -47, -54, -53, -49, -38,
+ -22, -13, -9, -7, -3, 6, 11, 6, -5, -14, -22, -28, -31, -30, -29, -24,
+ -18, -15, -2, 14, 29, 42, 45, 47, 45, 48, 56, 63, 59, 46, 29, 17,
+ 5, -4, -11, -23, -36, -49, -53, -52, -48, -40, -29, -21, -16, -11, -2, 5,
+ 6, 3, -5, -10, -13, -17, -21, -25, -26, -23, -19, -15, -8, 5, 20, 31,
+ 38, 42, 41, 46, 55, 62, 63, 50, 36, 24, 12, 5, -7, -20, -33, -46,
+ -51, -51, -48, -40, -33, -27, -20, -15, 0, 9, 7, 1, -6, -10, -11, -16,
+ -22, -25, -30, -28, -25, -21, -11, 2, 17, 28, 32, 41, 47, 55, 64, 66,
+ 64, 54, 41, 32, 19, 4, -9, -24, -37, -48, -54, -55, -51, -41, -33, -29,
+ -24, -15, 0, 13, 14, 8, 1, -5, -6, -10, -17, -24, -30, -32, -33, -32,
+ -22, -9, 9, 21, 25, 35, 45, 56, 67, 71, 71, 63, 49, 37, 25, 11,
+ -5, -19, -32, -45, -54, -59, -54, -43, -36, -31, -27, -18, -3, 11, 13, 9,
+ 2, -3, -6, -9, -13, -20, -25, -29, -33, -30, -23, -9, 2, 11, 19, 28,
+ 40, 51, 63, 68, 71, 66, 55, 44, 31, 16, 1, -15, -30, -41, -50, -57,
+ -56, -46, -37, -32, -30, -21, -7, 8, 17, 12, 5, 3, -2, -6, -11, -19,
+ -23, -27, -33, -34, -28, -19, -6, 3, 13, 24, 38, 51, 62, 70, 72, 68,
+ 60, 48, 38, 22, 6, -13, -27, -39, -46, -53, -52, -48, -42, -37, -36, -25,
+ -9, 4, 11, 9, 7, 8, 6, 2, -6, -13, -20, -24, -28, -31, -30, -27,
+ -19, -10, 4, 19, 33, 45, 57, 67, 74, 74, 70, 60, 47, 31, 10, -8,
+ -25, -36, -42, -51, -56, -56, -51, -40, -35, -28, -16, -4, 7, 7, 10, 12,
+ 13, 11, 3, -8, -18, -21, -25, -29, -33, -33, -30, -20, -8, 11, 27, 42,
+ 54, 64, 72, 77, 76, 69, 56, 34, 14, -5, -20, -32, -43, -50, -57, -59,
+ -57, -47, -39, -31, -17, -5, 6, 8, 9, 17, 19, 16, 5, -9, -13, -18,
+ -21, -26, -33, -37, -35, -28, -15, 1, 18, 34, 47, 58, 68, 76, 77, 76,
+ 65, 47, 25, 6, -12, -24, -37, -49, -57, -62, -64, -58, -50, -40, -24, -12,
+ 3, 9, 13, 22, 26, 26, 17, 4, -9, -21, -25, -30, -36, -41, -44, -41,
+ -27, -8, 12, 31, 44, 57, 68, 77, 81, 80, 72, 56, 34, 12, -6, -19,
+ -30, -41, -53, -65, -68, -65, -56, -44, -30, -17, -8, 2, 10, 23, 31, 32,
+ 25, 10, -4, -14, -20, -25, -31, -39, -45, -45, -35, -17, 2, 22, 37, 51,
+ 63, 72, 79, 78, 74, 62, 43, 20, 2, -12, -24, -34, -49, -61, -69, -70,
+ -63, -48, -35, -23, -11, 0, 9, 20, 31, 36, 32, 20, 7, -9, -18, -24,
+ -30, -38, -47, -50, -44, -29, -9, 10, 27, 45, 60, 71, 78, 80, 78, 68,
+ 54, 33, 13, -5, -18, -29, -44, -57, -68, -74, -66, -54, -41, -30, -18, -5,
+ 8, 19, 26, 33, 32, 24, 13, -4, -15, -22, -24, -29, -40, -44, -42, -29,
+ -14, 0, 15, 31, 48, 63, 69, 74, 74, 72, 64, 47, 27, 11, -4, -17,
+ -33, -50, -66, -78, -78, -68, -54, -38, -25, -11, 4, 18, 31, 38, 40, 34,
+ 21, 5, -12, -23, -28, -34, -43, -50, -51, -39, -22, -6, 10, 26, 46, 61,
+ 70, 75, 79, 76, 67, 52, 34, 18, 4, -11, -27, -45, -63, -76, -78, -70,
+ -57, -44, -29, -15, 0, 14, 26, 35, 39, 34, 23, 9, -7, -18, -23, -30,
+ -40, -49, -51, -41, -24, -9, 5, 19, 39, 55, 67, 74, 77, 79, 72, 56,
+ 39, 24, 12, -5, -23, -42, -60, -73, -78, -74, -62, -48, -33, -18, -6, 10,
+ 25, 34, 37, 34, 26, 16, -2, -15, -23, -28, -32, -42, -46, -44, -31, -16,
+ -4, 11, 28, 44, 56, 64, 69, 75, 73, 63, 50, 37, 22, 6, -10, -27,
+ -47, -68, -81, -80, -68, -52, -39, -25, -13, 2, 17, 29, 36, 37, 32, 23,
+ 4, -14, -24, -26, -26, -36, -44, -45, -36, -20, -7, 9, 25, 38, 49, 58,
+ 66, 75, 77, 67, 52, 39, 26, 14, -3, -21, -43, -65, -81, -84, -74, -56,
+ -40, -27, -15, -2, 15, 27, 37, 38, 35, 26, 8, -11, -23, -26, -27, -34,
+ -42, -45, -40, -27, -13, 4, 19, 33, 45, 54, 60, 67, 72, 67, 57, 44,
+ 32, 20, 5, -11, -32, -55, -72, -82, -76, -62, -46, -31, -21, -5, 6, 19,
+ 29, 34, 33, 26, 12, -6, -17, -22, -23, -28, -38, -42, -38, -27, -14, 1,
+ 14, 27, 40, 48, 53, 62, 68, 67, 58, 44, 32, 21, 9, -5, -22, -43,
+ -63, -76, -75, -62, -46, -30, -24, -13, 0, 10, 20, 28, 31, 27, 12, -5,
+ -16, -20, -19, -21, -29, -35, -35, -27, -16, -6, 9, 21, 33, 41, 47, 53,
+ 61, 63, 60, 51, 39, 27, 15, 3, -13, -33, -55, -72, -75, -67, -52, -37,
+ -26, -18, -7, 4, 15, 26, 27, 25, 14, 0, -10, -15, -16, -19, -24, -31,
+ -32, -27, -17, -5, 5, 15, 26, 35, 43, 49, 54, 57, 57, 52, 42, 29,
+ 18, 10, -3, -23, -46, -64, -71, -66, -53, -39, -27, -19, -11, 0, 5, 16,
+ 22, 23, 15, 1, -10, -15, -18, -17, -17, -20, -24, -22, -14, -4, 7, 16,
+ 25, 31, 36, 41, 47, 49, 49, 46, 41, 32, 21, 13, 3, -14, -33, -51,
+ -60, -60, -52, -39, -28, -20, -14, -7, 1, 9, 14, 16, 10, 1, -10, -15,
+ -14, -15, -15, -15, -17, -14, -11, -4, 5, 13, 22, 29, 33, 35, 39, 43,
+ 45, 45, 42, 35, 26, 17, 7, -10, -25, -38, -48, -53, -53, -46, -33, -23,
+ -16, -13, -8, -3, 4, 9, 7, 1, -6, -10, -13, -12, -12, -8, -7, -6,
+ -2, 3, 6, 10, 14, 23, 28, 29, 30, 29, 34, 39, 40, 36, 30, 21,
+ 13, 1, -15, -27, -36, -44, -48, -45, -36, -26, -17, -13, -10, -6, -2, 2,
+ 3, -3, -6, -10, -14, -13, -12, -7, -3, 1, 2, 5, 6, 10, 15, 19,
+ 25, 25, 26, 26, 29, 34, 35, 32, 29, 20, 13, 4, -12, -20, -27, -33,
+ -38, -41, -36, -27, -19, -13, -10, -8, -8, -7, -5, -5, -7, -9, -13, -18,
+ -15, -12, -5, 3, 7, 10, 10, 11, 13, 20, 27, 27, 23, 20, 20, 24,
+ 27, 25, 26, 23, 17, 7, -6, -13, -16, -20, -26, -32, -33, -28, -20, -13,
+ -12, -12, -16, -15, -15, -12, -10, -13, -13, -16, -12, -7, 0, 9, 14, 18,
+ 18, 14, 11, 14, 18, 21, 17, 10, 11, 15, 20, 21, 20, 20, 17, 9,
+ 2, -5, -10, -14, -21, -25, -29, -27, -23, -17, -13, -13, -16, -18, -20, -20,
+ -12, -8, -9, -15, -16, -10, -2, 9, 14, 18, 18, 18, 14, 14, 17, 20,
+ 18, 12, 8, 11, 13, 16, 18, 19, 16, 9, 3, 1, 1, -6, -13, -20,
+ -23, -21, -19, -15, -15, -14, -17, -21, -22, -22, -17, -11, -11, -13, -18, -14,
+ -4, 12, 21, 22, 23, 21, 20, 17, 16, 16, 12, 7, 1, 5, 7, 8,
+ 12, 15, 15, 10, 3, 0, 3, 1, -5, -12, -19, -19, -16, -11, -9, -11,
+ -14, -23, -28, -29, -24, -17, -13, -15, -19, -18, -10, 7, 22, 29, 30, 24,
+ 22, 18, 17, 17, 11, 4, -2, -3, 2, 4, 8, 13, 16, 13, 7, 4,
+ 9, 8, 2, -7, -16, -15, -14, -12, -10, -12, -12, -19, -25, -29, -25, -18,
+ -15, -18, -21, -19, -12, 1, 16, 28, 34, 32, 29, 23, 18, 15, 11, 4,
+ -3, -10, -8, -5, 0, 7, 12, 14, 10, 6, 10, 15, 13, 3, -7, -11,
+ -13, -13, -13, -12, -14, -20, -28, -31, -29, -20, -13, -14, -18, -18, -15, -3,
+ 12, 24, 33, 32, 29, 25, 22, 16, 11, 3, -3, -6, -7, -8, -3, 2,
+ 8, 11, 11, 9, 10, 13, 13, 8, 0, -6, -9, -9, -9, -10, -11, -18,
+ -26, -30, -29, -22, -17, -18, -20, -21, -17, -7, 6, 21, 34, 38, 34, 29,
+ 21, 17, 13, 8, 1, -8, -13, -15, -10, -3, 5, 10, 11, 10, 11, 15,
+ 16, 11, 3, -4, -7, -9, -8, -10, -13, -19, -26, -26, -23, -17, -15, -16,
+ -17, -17, -15, -9, -2, 10, 26, 31, 31, 24, 21, 18, 13, 6, 1, -6,
+ -8, -9, -8, -4, 0, 6, 10, 12, 15, 14, 13, 9, 5, -2, -7, -8,
+ -9, -8, -10, -18, -25, -25, -23, -18, -16, -19, -22, -18, -16, -10, 0, 10,
+ 24, 33, 35, 29, 22, 17, 13, 7, -3, -8, -12, -14, -12, -7, -3, 4,
+ 10, 14, 16, 17, 16, 16, 11, 3, -7, -11, -10, -7, -10, -19, -26, -27,
+ -23, -17, -14, -14, -17, -18, -16, -12, -3, 7, 20, 26, 28, 24, 20, 16,
+ 15, 10, 2, -8, -13, -11, -7, -2, -2, 4, 6, 9, 14, 17, 19, 15,
+ 8, -4, -12, -15, -11, -5, -8, -18, -25, -24, -17, -9, -6, -7, -11, -15,
+ -15, -13, -6, 4, 11, 15, 16, 15, 16, 13, 9, 5, 1, -3, -7, -5,
+ -2, 3, 5, 6, 8, 10, 14, 17, 18, 14, 3, -8, -15, -13, -9, -6,
+ -9, -19, -22, -19, -13, -6, -4, -5, -8, -13, -15, -10, -5, 5, 8, 8,
+ 8, 11, 14, 14, 8, 2, 1, 1, 2, -2, 1, 5, 6, 7, 7, 6,
+ 11, 13, 16, 13, 3, -6, -13, -14, -8, -5, -6, -15, -20, -15, -10, -5,
+ -2, -6, -6, -8, -12, -10, -8, -3, 5, 3, 3, 5, 7, 10, 6, 2,
+ -3, -2, 2, 8, 9, 12, 11, 8, 9, 8, 11, 13, 11, 10, 0, -12,
+ -20, -21, -13, -10, -11, -14, -16, -10, -3, 4, 8, 5, 2, -2, -4, -4,
+ -7, -4, -4, -5, -7, -8, -5, 0, 2, 2, 0, 1, 6, 11, 15, 19,
+ 19, 18, 14, 10, 12, 12, 11, 6, -6, -16, -23, -23, -17, -13, -12, -12,
+ -13, -8, -2, 8, 13, 13, 8, 4, 1, -3, -3, -3, -4, -11, -16, -16,
+ -13, -9, -5, -4, -2, 1, 6, 13, 17, 21, 24, 23, 18, 14, 10, 11,
+ 12, 8, -3, -16, -26, -27, -20, -17, -21, -21, -17, -7, 2, 10, 16, 19,
+ 18, 13, 10, 5, 2, -2, -5, -14, -22, -26, -21, -15, -11, -11, -6, -2,
+ 6, 16, 22, 27, 28, 28, 23, 17, 13, 10, 12, 7, -4, -18, -29, -32,
+ -24, -20, -21, -22, -18, -5, 5, 14, 19, 21, 20, 17, 13, 8, 5, -2,
+ -9, -18, -26, -26, -21, -14, -12, -11, -8, -2, 10, 16, 21, 24, 25, 27,
+ 24, 16, 11, 6, 7, 6, -4, -16, -25, -29, -25, -19, -19, -22, -18, -7,
+ 6, 15, 17, 18, 19, 18, 15, 10, 8, 3, -5, -15, -24, -30, -27, -19,
+ -15, -15, -13, -8, 5, 14, 20, 25, 28, 31, 30, 26, 18, 11, 9, 7,
+ -2, -14, -27, -33, -30, -25, -25, -27, -26, -15, 2, 17, 22, 23, 23, 22,
+ 22, 18, 14, 7, -4, -14, -24, -31, -30, -25, -19, -16, -16, -11, -3, 8,
+ 17, 24, 29, 31, 31, 29, 22, 17, 12, 8, 2, -12, -26, -36, -35, -30,
+ -26, -26, -29, -20, -5, 13, 24, 26, 26, 26, 28, 23, 19, 11, 1, -9,
+ -24, -34, -33, -30, -24, -21, -21, -17, -11, 1, 9, 19, 27, 33, 34, 30,
+ 28, 24, 21, 16, 7, -6, -23, -35, -40, -36, -33, -31, -32, -27, -13, 3,
+ 17, 25, 29, 34, 34, 30, 23, 17, 11, 0, -14, -27, -32, -33, -30, -26,
+ -21, -18, -15, -9, 1, 11, 22, 29, 32, 33, 30, 28, 23, 21, 13, 3,
+ -15, -30, -37, -38, -35, -35, -33, -28, -18, -5, 10, 22, 30, 37, 36, 32,
+ 26, 21, 14, 7, -6, -19, -28, -34, -32, -27, -21, -20, -21, -20, -11, 5,
+ 17, 25, 29, 30, 33, 35, 31, 27, 19, 8, -7, -25, -37, -42, -41, -39,
+ -35, -30, -22, -11, 4, 21, 32, 38, 39, 36, 29, 22, 15, 9, -4, -15,
+ -24, -32, -35, -31, -24, -18, -18, -19, -14, -3, 11, 21, 27, 31, 32, 34,
+ 34, 31, 27, 18, 1, -19, -33, -39, -38, -40, -39, -35, -28, -17, -3, 14,
+ 28, 37, 41, 40, 34, 30, 24, 18, 7, -6, -20, -30, -36, -34, -30, -26,
+ -26, -27, -26, -16, 0, 16, 26, 30, 33, 36, 42, 43, 38, 27, 10, -10,
+ -27, -39, -43, -43, -43, -40, -34, -26, -14, 2, 21, 36, 42, 40, 36, 33,
+ 30, 24, 16, 5, -11, -25, -34, -35, -32, -29, -30, -31, -31, -27, -15, 5,
+ 21, 27, 30, 34, 42, 51, 48, 40, 20, -3, -21, -32, -38, -40, -43, -42,
+ -38, -30, -18, -3, 15, 29, 40, 41, 39, 34, 31, 28, 20, 10, -4, -18,
+ -29, -33, -34, -34, -35, -37, -38, -34, -21, -6, 12, 22, 26, 33, 44, 55,
+ 56, 46, 26, 5, -11, -25, -36, -42, -47, -47, -43, -37, -24, -11, 9, 25,
+ 36, 38, 38, 40, 39, 39, 28, 17, 3, -10, -23, -30, -37, -38, -42, -44,
+ -43, -40, -30, -16, 3, 17, 26, 34, 44, 57, 61, 52, 34, 9, -7, -21,
+ -30, -38, -46, -49, -48, -39, -27, -13, 5, 22, 32, 35, 35, 37, 41, 43,
+ 33, 19, 4, -8, -16, -25, -32, -39, -42, -44, -42, -41, -33, -20, -4, 11,
+ 21, 28, 38, 49, 58, 54, 36, 16, -6, -16, -21, -28, -36, -46, -49, -42,
+ -29, -17, 0, 13, 26, 30, 30, 35, 41, 47, 41, 25, 9, -4, -12, -17,
+ -28, -38, -46, -52, -51, -49, -39, -23, -9, 4, 12, 23, 39, 54, 66, 62,
+ 43, 23, 2, -10, -16, -26, -36, -45, -51, -50, -37, -20, 0, 16, 27, 28,
+ 29, 38, 47, 50, 44, 28, 13, -2, -10, -16, -26, -35, -45, -55, -57, -56,
+ -44, -27, -13, -4, 5, 17, 34, 53, 64, 64, 46, 29, 13, 1, -8, -17,
+ -28, -39, -48, -51, -42, -26, -8, 9, 18, 20, 24, 34, 46, 53, 47, 33,
+ 15, 4, -4, -13, -22, -35, -47, -56, -59, -56, -48, -32, -18, -8, 3, 14,
+ 33, 52, 65, 64, 49, 31, 17, 5, -3, -13, -25, -36, -45, -49, -44, -31,
+ -14, 7, 16, 21, 21, 31, 48, 57, 53, 38, 20, 8, -3, -9, -21, -35,
+ -47, -57, -62, -62, -54, -38, -22, -12, -5, 7, 26, 49, 66, 69, 56, 37,
+ 24, 15, 6, -4, -17, -30, -43, -53, -47, -34, -18, -2, 9, 14, 17, 29,
+ 46, 58, 56, 43, 25, 13, 2, -5, -15, -30, -45, -59, -66, -65, -57, -43,
+ -28, -16, -10, 2, 21, 44, 66, 71, 62, 43, 28, 19, 13, 3, -12, -25,
+ -42, -51, -50, -38, -18, -3, 5, 12, 17, 30, 48, 59, 58, 45, 26, 11,
+ 0, -6, -15, -29, -45, -63, -71, -68, -58, -41, -28, -19, -12, -4, 16, 42,
+ 62, 70, 61, 43, 29, 21, 16, 8, -6, -20, -35, -45, -45, -37, -21, -6,
+ 3, 8, 14, 24, 42, 54, 58, 47, 29, 16, 3, -3, -12, -27, -42, -62,
+ -73, -74, -66, -52, -34, -23, -14, -5, 12, 38, 60, 72, 68, 49, 34, 23,
+ 17, 10, -3, -18, -31, -42, -42, -36, -20, -4, 5, 9, 11, 22, 37, 51,
+ 55, 46, 29, 13, 2, -9, -14, -25, -38, -53, -67, -72, -67, -53, -35, -23,
+ -17, -10, 6, 32, 55, 69, 67, 53, 36, 26, 19, 12, 2, -13, -26, -37,
+ -40, -36, -24, -7, 3, 9, 13, 20, 36, 49, 52, 47, 32, 17, 3, -12,
+ -19, -29, -38, -52, -66, -75, -72, -56, -36, -20, -15, -10, 2, 25, 48, 63,
+ 63, 52, 39, 28, 20, 14, 5, -6, -19, -30, -38, -35, -25, -8, 4, 8,
+ 11, 17, 33, 47, 54, 47, 34, 18, 4, -9, -19, -28, -40, -53, -65, -75,
+ -74, -60, -41, -22, -15, -12, -2, 18, 43, 59, 63, 55, 41, 31, 27, 20,
+ 13, 3, -11, -24, -35, -34, -26, -11, 2, 8, 9, 11, 22, 37, 47, 49,
+ 39, 22, 6, -7, -19, -26, -36, -48, -60, -74, -77, -66, -47, -26, -13, -8,
+ 1, 15, 36, 53, 63, 56, 45, 30, 22, 16, 10, 5, -7, -19, -32, -34,
+ -25, -7, 8, 16, 17, 17, 23, 37, 48, 51, 40, 22, 4, -14, -24, -33,
+ -39, -49, -61, -72, -77, -66, -47, -27, -13, -5, 1, 13, 30, 47, 59, 57,
+ 47, 31, 23, 17, 15, 6, -5, -18, -26, -30, -24, -10, 8, 19, 21, 20,
+ 22, 30, 40, 48, 41, 25, 3, -17, -29, -32, -37, -46, -59, -70, -73, -65,
+ -46, -27, -14, -4, 3, 15, 29, 41, 52, 54, 45, 31, 19, 15, 15, 9,
+ 1, -14, -26, -27, -21, -8, 10, 17, 23, 23, 23, 32, 39, 45, 44, 29,
+ 7, -16, -32, -40, -42, -49, -61, -72, -76, -69, -50, -28, -12, -2, 5, 17,
+ 31, 43, 48, 49, 44, 34, 24, 15, 13, 9, 5, -8, -24, -27, -21, -7,
+ 10, 20, 25, 29, 29, 32, 36, 41, 41, 34, 14, -12, -35, -46, -49, -52,
+ -61, -74, -78, -73, -56, -31, -14, 2, 10, 19, 31, 44, 54, 53, 47, 34,
+ 24, 16, 9, 4, -2, -12, -25, -28, -22, -7, 9, 23, 32, 36, 36, 36,
+ 37, 42, 42, 33, 15, -14, -36, -50, -57, -56, -62, -74, -81, -77, -59, -36,
+ -15, 2, 11, 20, 31, 44, 56, 56, 51, 39, 26, 15, 7, 1, -3, -13,
+ -26, -33, -31, -14, 9, 25, 36, 41, 40, 41, 40, 44, 44, 35, 17, -13,
+ -39, -54, -61, -64, -69, -76, -81, -78, -63, -39, -15, 4, 14, 24, 35, 45,
+ 54, 56, 53, 41, 25, 14, 7, 3, -4, -14, -26, -34, -31, -15, 9, 25,
+ 36, 41, 43, 44, 43, 46, 45, 35, 16, -9, -31, -49, -63, -69, -75, -78,
+ -84, -79, -66, -45, -22, 0, 13, 23, 35, 48, 56, 58, 53, 43, 30, 19,
+ 10, 4, -7, -18, -26, -33, -30, -17, 4, 24, 37, 44, 50, 50, 49, 46,
+ 43, 35, 16, -7, -30, -52, -65, -75, -78, -83, -85, -82, -70, -50, -26, -4,
+ 14, 26, 39, 53, 63, 64, 59, 49, 35, 18, 6, -2, -13, -25, -35, -40,
+ -36, -22, 3, 26, 38, 47, 54, 60, 61, 57, 50, 39, 20, -5, -26, -49,
+ -66, -80, -87, -91, -93, -88, -74, -54, -34, -12, 8, 24, 40, 55, 68, 70,
+ 66, 55, 41, 26, 14, 6, -9, -25, -37, -43, -39, -28, -9, 15, 32, 41,
+ 48, 59, 65, 65, 58, 45, 25, 5, -17, -38, -61, -77, -91, -97, -100, -94,
+ -79, -64, -44, -23, -2, 24, 42, 57, 72, 77, 74, 63, 48, 33, 21, 10,
+ -7, -27, -43, -45, -41, -29, -14, 4, 26, 40, 49, 58, 66, 69, 64, 48,
+ 29, 7, -13, -31, -53, -73, -89, -100, -102, -95, -83, -67, -51, -29, -7, 17,
+ 37, 55, 72, 81, 77, 67, 55, 40, 25, 12, -4, -22, -40, -45, -42, -31,
+ -19, -4, 15, 34, 48, 55, 63, 67, 66, 57, 41, 20, -4, -25, -46, -69,
+ -88, -104, -110, -106, -95, -79, -63, -39, -13, 15, 39, 60, 75, 88, 91, 81,
+ 66, 44, 27, 13, -3, -22, -41, -50, -48, -38, -26, -13, 6, 29, 46, 55,
+ 62, 66, 69, 63, 48, 26, 5, -14, -33, -57, -84, -105, -115, -113, -102, -88,
+ -73, -53, -26, 1, 31, 57, 78, 91, 95, 88, 75, 60, 41, 22, 1, -19,
+ -38, -51, -53, -48, -36, -22, -6, 19, 39, 53, 62, 65, 69, 67, 55, 36,
+ 14, -6, -28, -54, -79, -100, -111, -116, -110, -98, -83, -61, -35, -6, 26, 53,
+ 75, 89, 96, 96, 87, 71, 50, 29, 10, -9, -30, -44, -53, -50, -45, -32,
+ -19, 2, 23, 43, 55, 62, 66, 66, 62, 49, 30, 11, -12, -39, -70, -95,
+ -112, -118, -118, -109, -94, -74, -48, -18, 17, 47, 70, 88, 98, 99, 95, 80,
+ 61, 37, 14, -9, -26, -43, -51, -52, -48, -40, -25, -6, 17, 37, 52, 57,
+ 63, 64, 62, 55, 36, 17, -8, -34, -62, -86, -106, -117, -118, -110, -99, -83,
+ -57, -27, 10, 42, 67, 85, 96, 101, 101, 91, 69, 46, 21, 1, -21, -38,
+ -49, -54, -49, -44, -35, -18, 2, 24, 44, 55, 64, 67, 63, 59, 46, 29,
+ 7, -21, -51, -79, -104, -117, -122, -117, -108, -94, -70, -40, 0, 34, 63, 85,
+ 96, 104, 105, 99, 82, 59, 31, 4, -20, -37, -46, -51, -51, -50, -44, -28,
+ -8, 17, 38, 53, 60, 65, 67, 64, 54, 40, 18, -10, -40, -71, -98, -115,
+ -121, -118, -113, -103, -82, -52, -14, 22, 53, 77, 94, 106, 109, 104, 93, 76,
+ 50, 21, -11, -33, -43, -48, -53, -56, -56, -46, -27, 2, 29, 48, 58, 62,
+ 63, 62, 58, 49, 33, 5, -27, -57, -87, -108, -119, -118, -114, -106, -91, -68,
+ -31, 8, 42, 69, 88, 102, 110, 110, 100, 83, 60, 33, 3, -23, -39, -46,
+ -52, -57, -57, -51, -35, -14, 15, 38, 54, 63, 65, 66, 58, 51, 40, 17,
+ -11, -44, -76, -101, -114, -116, -111, -106, -96, -77, -47, -11, 28, 58, 81, 97,
+ 109, 112, 105, 95, 77, 53, 23, -9, -30, -45, -52, -58, -64, -61, -52, -35,
+ -9, 20, 44, 62, 67, 67, 65, 62, 54, 35, 7, -24, -60, -91, -110, -119,
+ -116, -112, -105, -90, -65, -31, 8, 43, 73, 94, 109, 117, 113, 105, 91, 68,
+ 39, 4, -24, -43, -56, -64, -67, -67, -61, -47, -21, 9, 35, 55, 63, 66,
+ 66, 61, 56, 46, 23, -10, -46, -81, -100, -111, -115, -112, -107, -94, -75, -48,
+ -12, 28, 59, 84, 103, 116, 120, 114, 103, 81, 56, 22, -10, -35, -53, -64,
+ -71, -73, -71, -59, -39, -10, 19, 43, 60, 66, 68, 67, 64, 53, 33, 7,
+ -27, -64, -91, -108, -115, -113, -108, -97, -82, -59, -27, 11, 46, 75, 98, 112,
+ 119, 117, 109, 89, 64, 34, 4, -24, -50, -62, -69, -69, -70, -65, -49, -23,
+ 8, 32, 52, 61, 64, 65, 64, 55, 39, 15, -16, -46, -76, -97, -109, -110,
+ -107, -102, -91, -71, -42, -4, 34, 66, 90, 106, 116, 121, 118, 101, 78, 47,
+ 15, -15, -44, -60, -70, -73, -75, -74, -63, -39, -7, 23, 45, 60, 66, 69,
+ 69, 62, 49, 29, 1, -32, -65, -94, -108, -112, -109, -102, -97, -83, -58, -22,
+ 18, 54, 84, 103, 116, 121, 120, 112, 91, 63, 29, -6, -34, -54, -66, -75,
+ -79, -81, -72, -50, -22, 9, 33, 50, 59, 67, 70, 70, 60, 43, 13, -20,
+ -51, -78, -97, -107, -111, -109, -105, -94, -72, -37, 5, 42, 72, 96, 114, 124,
+ 127, 118, 100, 75, 42, 10, -22, -47, -62, -72, -79, -84, -82, -64, -35, -2,
+ 23, 39, 50, 61, 69, 71, 66, 51, 27, -6, -36, -62, -81, -96, -104, -105,
+ -106, -101, -83, -52, -11, 27, 57, 82, 103, 120, 127, 122, 107, 82, 53, 19,
+ -12, -39, -55, -65, -73, -81, -81, -67, -40, -8, 16, 30, 41, 52, 62, 68,
+ 66, 56, 34, 3, -28, -53, -71, -86, -96, -102, -106, -103, -88, -62, -25, 15,
+ 47, 72, 90, 109, 120, 123, 115, 93, 63, 31, 1, -24, -40, -52, -64, -76,
+ -82, -73, -50, -22, 1, 18, 27, 39, 51, 63, 67, 61, 44, 18, -13, -38,
+ -53, -69, -83, -96, -105, -103, -93, -69, -36, -3, 30, 56, 77, 95, 111, 116,
+ 113, 97, 72, 42, 13, -12, -25, -38, -54, -70, -79, -74, -57, -32, -11, 4,
+ 15, 26, 40, 55, 65, 62, 51, 28, 1, -24, -40, -56, -73, -89, -101, -102,
+ -95, -79, -50, -17, 16, 47, 68, 88, 104, 114, 115, 102, 80, 53, 24, 0,
+ -18, -31, -45, -60, -73, -74, -63, -42, -21, -6, 6, 16, 28, 45, 56, 59,
+ 51, 35, 14, -9, -26, -41, -57, -73, -87, -97, -95, -85, -62, -32, -2, 26,
+ 50, 71, 91, 105, 111, 105, 89, 64, 40, 16, -4, -20, -35, -49, -64, -70,
+ -68, -53, -35, -18, -6, 5, 14, 29, 45, 55, 54, 39, 21, 4, -13, -25,
+ -42, -63, -77, -89, -90, -80, -66, -44, -19, 10, 35, 57, 76, 93, 104, 104,
+ 91, 68, 48, 29, 13, -6, -24, -42, -56, -63, -61, -54, -42, -27, -17, -6,
+ 5, 18, 33, 44, 47, 39, 25, 10, 0, -14, -29, -50, -67, -79, -85, -81,
+ -70, -53, -32, -5, 24, 47, 67, 84, 98, 103, 95, 77, 56, 37, 22, 6,
+ -14, -34, -48, -56, -57, -52, -48, -37, -28, -17, -6, 8, 23, 34, 41, 38,
+ 28, 15, 4, -4, -16, -38, -59, -73, -78, -75, -66, -54, -37, -19, 7, 32,
+ 53, 72, 87, 95, 92, 78, 58, 44, 32, 20, 2, -21, -38, -47, -48, -47,
+ -46, -42, -36, -26, -14, -5, 9, 20, 32, 35, 30, 19, 12, 8, -5, -25,
+ -48, -63, -71, -70, -63, -58, -44, -26, -6, 20, 40, 59, 79, 92, 93, 83,
+ 60, 47, 37, 29, 13, -10, -28, -40, -44, -44, -48, -47, -41, -33, -22, -13,
+ 0, 14, 29, 36, 34, 24, 18, 15, 4, -13, -39, -60, -69, -72, -68, -62,
+ -51, -34, -13, 9, 31, 52, 73, 88, 95, 87, 70, 55, 45, 35, 20, -2,
+ -23, -36, -42, -47, -48, -51, -50, -40, -30, -17, -8, 7, 23, 36, 37, 30,
+ 22, 19, 13, -3, -24, -49, -65, -71, -71, -64, -54, -40, -20, -3, 21, 44,
+ 65, 85, 92, 87, 72, 57, 48, 39, 29, 11, -12, -27, -36, -41, -42, -47,
+ -49, -45, -37, -28, -17, -4, 13, 28, 33, 29, 26, 23, 17, 6, -11, -33,
+ -53, -64, -66, -62, -55, -44, -29, -12, 10, 31, 51, 71, 84, 85, 77, 61,
+ 50, 41, 36, 22, 2, -17, -33, -38, -42, -45, -48, -46, -41, -34, -23, -9,
+ 7, 24, 35, 32, 28, 23, 17, 10, -4, -26, -49, -64, -68, -64, -58, -46,
+ -32, -13, 8, 28, 45, 65, 78, 82, 76, 62, 52, 45, 37, 23, 6, -10,
+ -26, -35, -41, -45, -46, -48, -48, -39, -27, -11, 3, 14, 23, 27, 28, 25,
+ 23, 15, 2, -17, -34, -52, -60, -61, -56, -44, -32, -17, -3, 16, 34, 54,
+ 66, 73, 68, 58, 47, 42, 37, 29, 17, 3, -14, -25, -31, -36, -39, -44,
+ -48, -44, -33, -20, -9, 2, 13, 22, 26, 24, 20, 14, 5, -7, -22, -39,
+ -50, -55, -51, -43, -32, -20, -7, 10, 28, 44, 57, 65, 67, 64, 54, 44,
+ 36, 28, 18, 4, -9, -23, -32, -39, -42, -46, -44, -38, -29, -19, -12, -4,
+ 10, 22, 27, 22, 14, 8, 1, -6, -17, -30, -43, -49, -47, -38, -26, -18,
+ -10, 3, 17, 34, 45, 54, 59, 57, 53, 45, 37, 30, 22, 11, -3, -14,
+ -24, -34, -40, -45, -43, -39, -29, -21, -14, -6, 3, 16, 20, 17, 10, 3,
+ 0, -6, -15, -25, -33, -38, -37, -31, -21, -12, -6, 5, 15, 27, 39, 46,
+ 50, 51, 47, 44, 36, 29, 20, 10, 1, -10, -18, -27, -36, -40, -42, -37,
+ -29, -21, -14, -7, 1, 10, 16, 10, 3, -2, -3, -6, -12, -22, -28, -30,
+ -28, -23, -16, -11, -7, 0, 7, 19, 31, 42, 47, 47, 46, 46, 40, 33,
+ 21, 10, 2, -6, -12, -24, -33, -37, -38, -36, -31, -21, -14, -7, -2, 2,
+ 7, 8, 4, -2, -7, -12, -14, -19, -23, -24, -20, -16, -11, -6, -2, 3,
+ 9, 16, 24, 33, 37, 40, 44, 44, 40, 33, 22, 13, 5, -3, -8, -21,
+ -30, -35, -34, -32, -30, -23, -13, -6, -3, -3, -2, -2, -4, -7, -9, -12,
+ -13, -13, -14, -14, -11, -12, -4, -2, 2, 0, 3, 10, 18, 27, 32, 35,
+ 38, 40, 37, 32, 23, 13, 8, 2, -4, -11, -22, -27, -31, -30, -29, -24,
+ -14, -7, -8, -7, -10, -10, -10, -10, -11, -12, -13, -12, -11, -11, -7, -2,
+ 4, 5, 3, -2, 0, 8, 15, 21, 26, 30, 32, 37, 37, 32, 26, 16,
+ 10, 4, -4, -9, -16, -21, -26, -29, -28, -23, -15, -11, -9, -11, -13, -14,
+ -14, -13, -13, -12, -13, -12, -8, -3, 3, 6, 8, 10, 7, 1, -3, 2,
+ 8, 17, 22, 22, 27, 32, 37, 35, 29, 18, 11, 2, -4, -8, -14, -17,
+ -21, -23, -25, -22, -17, -11, -9, -11, -16, -16, -16, -16, -14, -15, -14, -11,
+ -5, 0, 4, 5, 6, 7, 6, 4, 0, 3, 8, 16, 21, 20, 24, 28,
+ 34, 35, 29, 17, 8, 3, 1, -3, -9, -15, -20, -21, -23, -22, -21, -17,
+ -13, -14, -18, -23, -22, -17, -13, -10, -9, -8, 0, 6, 9, 10, 8, 6,
+ 6, 4, 0, -2, 1, 10, 17, 20, 22, 25, 29, 31, 29, 20, 10, 2,
+ -2, 0, -5, -11, -18, -20, -19, -19, -19, -18, -16, -14, -18, -26, -26, -22,
+ -16, -13, -9, -6, 1, 7, 10, 10, 7, 7, 7, 5, 0, -4, -2, 7,
+ 14, 19, 22, 26, 30, 32, 30, 22, 13, 6, 1, -2, -7, -13, -16, -18,
+ -19, -19, -21, -21, -19, -17, -16, -23, -25, -23, -17, -10, -9, -4, 2, 8,
+ 10, 12, 9, 7, 5, 4, 2, -3, -2, 3, 9, 18, 23, 28, 29, 28,
+ 27, 26, 19, 12, 6, 0, -7, -11, -15, -17, -20, -21, -20, -22, -23, -25,
+ -24, -26, -27, -25, -20, -13, -5, 3, 9, 11, 15, 17, 15, 10, 4, 0,
+ -4, -5, -4, 2, 5, 13, 19, 25, 29, 28, 26, 25, 20, 16, 11, 2,
+ -5, -10, -10, -10, -14, -17, -21, -24, -26, -29, -27, -28, -28, -26, -23, -17,
+ -8, 1, 12, 15, 16, 14, 13, 10, 6, 0, -5, -6, -5, 1, 6, 12,
+ 20, 27, 30, 28, 24, 23, 21, 17, 11, 4, -6, -9, -10, -10, -11, -16,
+ -18, -21, -24, -26, -29, -28, -27, -25, -23, -18, -11, -2, 11, 15, 15, 12,
+ 11, 9, 6, 1, -6, -6, -2, 3, 7, 11, 19, 26, 28, 26, 22, 21,
+ 23, 24, 17, 10, 4, 0, -2, -5, -10, -15, -20, -25, -32, -36, -36, -35,
+ -32, -30, -26, -19, -10, 2, 14, 21, 21, 17, 13, 10, 7, 1, -5, -5,
+ -6, -4, 0, 6, 12, 19, 22, 24, 20, 21, 24, 29, 28, 20, 13, 8,
+ 3, 2, -4, -9, -16, -27, -34, -41, -44, -41, -38, -35, -31, -27, -18, -3,
+ 13, 26, 29, 23, 18, 14, 11, 8, 4, -2, -8, -11, -9, -6, 4, 9,
+ 16, 17, 16, 16, 23, 33, 37, 33, 26, 19, 12, 8, 1, -7, -15, -30,
+ -41, -50, -53, -50, -43, -38, -34, -28, -17, -3, 13, 26, 30, 26, 19, 14,
+ 12, 9, 4, -2, -10, -14, -13, -7, 4, 9, 12, 13, 13, 17, 25, 32,
+ 40, 39, 32, 24, 15, 11, 8, 1, -10, -27, -43, -51, -55, -52, -49, -45,
+ -40, -32, -21, -8, 9, 23, 31, 30, 24, 19, 17, 16, 11, 4, -7, -15,
+ -18, -14, -6, 2, 5, 7, 9, 14, 24, 35, 45, 48, 45, 34, 25, 16,
+ 8, 2, -11, -27, -46, -59, -64, -61, -53, -46, -40, -35, -24, -9, 8, 23,
+ 30, 31, 27, 24, 21, 17, 12, 4, -6, -15, -19, -17, -12, -3, 3, 4,
+ 6, 12, 25, 37, 45, 47, 47, 43, 35, 23, 12, 2, -10, -24, -42, -60,
+ -71, -71, -63, -55, -45, -36, -22, -7, 9, 22, 30, 35, 34, 31, 24, 19,
+ 13, 6, -3, -13, -20, -21, -16, -9, -3, -2, 4, 11, 26, 38, 45, 50,
+ 49, 48, 42, 31, 16, 4, -9, -21, -38, -59, -72, -77, -70, -61, -53, -41,
+ -26, -9, 7, 17, 26, 34, 41, 41, 35, 25, 17, 9, 0, -10, -21, -24,
+ -22, -15, -9, -7, -2, 10, 25, 39, 44, 47, 49, 52, 50, 39, 22, 6,
+ -8, -20, -34, -54, -70, -78, -77, -68, -61, -49, -33, -15, 3, 16, 25, 32,
+ 43, 49, 47, 37, 25, 16, 3, -10, -22, -29, -27, -22, -15, -12, -7, 7,
+ 25, 42, 47, 50, 53, 57, 57, 46, 31, 11, -5, -22, -39, -56, -72, -81,
+ -85, -81, -71, -56, -36, -16, 4, 19, 29, 37, 48, 55, 56, 48, 34, 20,
+ 7, -10, -25, -32, -34, -28, -21, -17, -14, 0, 20, 40, 50, 51, 53, 58,
+ 61, 53, 39, 18, -2, -18, -36, -53, -70, -80, -85, -86, -79, -67, -46, -23,
+ -2, 17, 27, 35, 44, 55, 62, 57, 44, 26, 9, -10, -23, -29, -32, -28,
+ -24, -20, -15, -4, 15, 35, 47, 50, 49, 53, 57, 53, 43, 24, 5, -14,
+ -32, -50, -64, -5, 0, -2, -3, -3, -3, -3, -2, -2, 1, 2, 3, 5,
+ 8, 11, 11, 10, 8, 5, 1, -6, -13, -19, -21, -18, -15, -13, -10, -7,
+ -2, 4, 8, 12, 17, 28, 33, 29, 23, 14, 7, -5, -19, -33, -42, -36,
+ -28, -24, -17, -13, -8, 1, 7, 15, 23, 33, 42, 42, 35, 26, 15, 0,
+ -16, -30, -44, -45, -34, -27, -20, -16, -13, -4, 4, 12, 21, 29, 40, 45,
+ 40, 30, 20, 6, -13, -25, -38, -45, -38, -31, -24, -18, -15, -10, -4, 5,
+ 17, 27, 35, 44, 43, 37, 27, 15, -4, -19, -31, -44, -44, -35, -30, -22,
+ -19, -16, -8, 2, 15, 25, 32, 42, 47, 42, 32, 18, 0, -16, -26, -39,
+ -45, -38, -31, -25, -19, -18, -14, -5, 11, 23, 29, 39, 46, 45, 38, 25,
+ 7, -8, -18, -31, -44, -43, -35, -30, -25, -25, -20, -9, 7, 21, 27, 36,
+ 48, 51, 44, 32, 14, -3, -16, -28, -42, -46, -41, -33, -27, -24, -23, -15,
+ 1, 16, 27, 33, 42, 47, 46, 38, 21, 5, -9, -21, -34, -44, -45, -39,
+ -31, -28, -26, -20, -8, 9, 25, 34, 41, 49, 51, 47, 31, 11, -6, -18,
+ -30, -42, -48, -45, -36, -28, -26, -23, -12, 6, 23, 33, 38, 43, 51, 50,
+ 36, 15, 0, -12, -22, -35, -50, -50, -40, -31, -29, -27, -18, 1, 20, 32,
+ 36, 43, 52, 56, 45, 23, 2, -10, -20, -33, -48, -56, -49, -36, -30, -26,
+ -18, -5, 17, 33, 39, 40, 46, 52, 49, 32, 9, -8, -18, -26, -40, -54,
+ -53, -39, -30, -28, -23, -12, 10, 31, 39, 38, 42, 54, 54, 41, 17, -5,
+ -15, -22, -35, -53, -59, -47, -36, -30, -24, -14, 6, 27, 40, 42, 43, 51,
+ 56, 46, 26, 3, -13, -22, -33, -49, -61, -55, -41, -32, -26, -18, 0, 22,
+ 38, 45, 43, 48, 55, 50, 33, 11, -10, -21, -29, -43, -59, -60, -46, -35,
+ -28, -18, -6, 15, 35, 45, 46, 45, 52, 53, 41, 20, -6, -19, -26, -38,
+ -54, -62, -53, -39, -29, -19, -11, 6, 29, 44, 48, 45, 47, 52, 49, 32,
+ 5, -18, -26, -32, -45, -61, -61, -48, -35, -23, -14, -2, 22, 42, 52, 50,
+ 46, 50, 50, 38, 12, -15, -26, -31, -43, -59, -65, -53, -37, -25, -16, -6,
+ 16, 40, 53, 53, 47, 49, 51, 42, 22, -10, -27, -31, -38, -54, -67, -63,
+ -46, -27, -18, -7, 10, 31, 52, 59, 53, 48, 50, 46, 32, 3, -24, -34,
+ -39, -50, -66, -68, -54, -35, -20, -8, 6, 23, 47, 62, 59, 52, 50, 48,
+ 37, 13, -18, -35, -40, -46, -62, -72, -63, -43, -25, -10, 6, 20, 41, 59,
+ 63, 55, 49, 46, 39, 21, -9, -31, -39, -42, -52, -68, -68, -52, -32, -17,
+ -4, 9, 31, 54, 66, 63, 54, 51, 44, 32, 6, -26, -40, -44, -51, -65,
+ -72, -61, -41, -23, -5, 9, 25, 48, 64, 66, 59, 54, 46, 33, 12, -17,
+ -36, -45, -51, -62, -73, -67, -48, -31, -11, 8, 21, 44, 64, 70, 64, 57,
+ 49, 36, 20, -8, -34, -47, -52, -58, -68, -73, -59, -40, -19, 4, 17, 36,
+ 58, 72, 73, 65, 56, 41, 26, 4, -24, -44, -55, -63, -69, -73, -66, -51,
+ -28, -2, 18, 32, 51, 67, 75, 72, 62, 46, 29, 11, -13, -37, -54, -64,
+ -70, -71, -70, -58, -38, -13, 14, 30, 48, 64, 73, 76, 69, 52, 34, 15,
+ -7, -31, -50, -62, -69, -71, -71, -66, -47, -19, 8, 26, 40, 58, 73, 81,
+ 76, 57, 39, 23, 2, -22, -45, -62, -71, -73, -71, -69, -57, -32, 0, 26,
+ 41, 55, 70, 81, 83, 64, 41, 24, 6, -15, -39, -60, -71, -73, -69, -69,
+ -62, -40, -11, 20, 39, 51, 65, 78, 86, 75, 50, 29, 11, -8, -30, -53,
+ -70, -77, -71, -66, -67, -53, -22, 13, 37, 49, 60, 75, 89, 84, 58, 33,
+ 16, -2, -22, -47, -68, -77, -72, -67, -68, -60, -34, 0, 29, 47, 56, 69,
+ 85, 88, 69, 40, 20, 4, -13, -35, -61, -76, -74, -65, -66, -65, -47, -15,
+ 20, 43, 53, 64, 81, 89, 77, 50, 26, 9, -10, -29, -51, -71, -78, -71,
+ -66, -64, -52, -27, 9, 38, 54, 62, 73, 85, 82, 60, 34, 13, -3, -19,
+ -40, -65, -80, -74, -68, -69, -61, -40, -4, 29, 49, 61, 72, 86, 86, 70,
+ 45, 21, 3, -16, -33, -56, -80, -78, -70, -70, -65, -50, -18, 20, 48, 62,
+ 68, 80, 88, 78, 53, 26, 5, -12, -26, -45, -72, -81, -71, -67, -64, -56,
+ -34, 4, 37, 57, 63, 73, 85, 83, 63, 37, 16, 0, -17, -36, -63, -79,
+ -74, -70, -69, -63, -44, -10, 26, 52, 62, 69, 81, 84, 69, 45, 22, 3,
+ -15, -28, -52, -75, -76, -69, -67, -64, -52, -24, 14, 45, 60, 65, 74, 82,
+ 75, 54, 32, 12, -6, -21, -44, -68, -78, -74, -71, -69, -60, -34, 2, 34,
+ 55, 66, 73, 79, 78, 61, 39, 20, 2, -16, -34, -56, -72, -74, -70, -71,
+ -66, -47, -14, 21, 48, 61, 68, 76, 80, 69, 46, 27, 11, -7, -26, -50,
+ -68, -72, -70, -70, -69, -54, -24, 10, 39, 57, 66, 72, 76, 70, 52, 33,
+ 16, -4, -20, -39, -59, -70, -71, -69, -67, -60, -37, -6, 27, 50, 62, 67,
+ 72, 74, 61, 41, 25, 10, -10, -31, -51, -67, -74, -73, -73, -68, -48, -16,
+ 17, 45, 60, 66, 73, 75, 66, 48, 29, 15, -3, -24, -45, -62, -70, -72,
+ -74, -70, -55, -26, 7, 32, 51, 63, 70, 73, 67, 51, 35, 24, 9, -16,
+ -38, -54, -64, -68, -75, -75, -62, -36, -5, 22, 45, 60, 69, 74, 68, 57,
+ 43, 29, 15, -9, -29, -45, -60, -67, -75, -76, -64, -44, -16, 10, 32, 52,
+ 63, 68, 66, 59, 48, 36, 24, 6, -17, -35, -51, -60, -70, -78, -72, -55,
+ -27, 1, 20, 39, 56, 65, 68, 60, 51, 41, 31, 15, -9, -27, -44, -58,
+ -67, -75, -73, -58, -35, -8, 11, 32, 50, 60, 61, 57, 53, 47, 37, 25,
+ 4, -19, -35, -48, -60, -73, -76, -67, -46, -18, 2, 20, 40, 56, 64, 62,
+ 56, 49, 43, 34, 15, -10, -31, -45, -57, -70, -78, -69, -52, -27, -4, 13,
+ 34, 52, 60, 57, 53, 52, 46, 36, 22, 1, -19, -35, -50, -65, -73, -70,
+ -58, -41, -17, 4, 22, 42, 55, 58, 57, 55, 50, 43, 32, 12, -11, -30,
+ -47, -61, -71, -72, -63, -46, -26, -6, 13, 30, 47, 53, 54, 56, 52, 46,
+ 38, 24, 5, -20, -39, -52, -63, -67, -66, -57, -37, -15, 3, 18, 37, 50,
+ 55, 59, 55, 49, 45, 32, 15, -10, -34, -50, -61, -66, -66, -58, -42, -24,
+ -4, 11, 27, 44, 50, 54, 57, 53, 49, 39, 23, 2, -23, -43, -57, -64,
+ -67, -62, -50, -33, -14, 4, 18, 37, 48, 53, 57, 55, 52, 44, 30, 13,
+ -14, -38, -54, -62, -65, -62, -54, -42, -24, -2, 13, 28, 41, 48, 56, 57,
+ 52, 45, 37, 23, 0, -28, -47, -57, -62, -63, -59, -50, -34, -14, 1, 16,
+ 35, 48, 56, 59, 59, 54, 45, 31, 8, -20, -42, -56, -62, -64, -60, -52,
+ -40, -23, -5, 10, 28, 43, 52, 56, 57, 56, 49, 38, 21, -8, -33, -46,
+ -56, -60, -59, -56, -47, -32, -15, 0, 17, 34, 47, 55, 58, 57, 53, 43,
+ 30, 8, -24, -42, -52, -59, -58, -57, -51, -42, -26, -8, 11, 29, 42, 50,
+ 57, 59, 55, 48, 34, 15, -15, -36, -45, -52, -55, -58, -55, -43, -31, -17,
+ -2, 16, 37, 50, 56, 58, 58, 54, 43, 23, -8, -33, -40, -47, -54, -57,
+ -58, -48, -34, -23, -10, 9, 31, 48, 54, 55, 55, 57, 50, 32, 3, -28,
+ -37, -41, -49, -55, -58, -49, -36, -27, -17, 1, 21, 41, 50, 52, 51, 54,
+ 55, 41, 13, -18, -32, -35, -42, -50, -57, -55, -41, -32, -24, -10, 10, 33,
+ 47, 50, 51, 54, 59, 49, 24, -8, -26, -30, -37, -46, -56, -59, -46, -35,
+ -29, -18, 2, 25, 44, 48, 47, 51, 57, 56, 36, 5, -20, -28, -31, -40,
+ -51, -58, -52, -39, -33, -25, -8, 15, 38, 49, 47, 50, 56, 60, 46, 15,
+ -11, -25, -30, -36, -49, -60, -54, -39, -33, -30, -14, 8, 32, 47, 44, 44,
+ 51, 59, 52, 26, -4, -20, -24, -29, -41, -54, -55, -43, -34, -33, -26, -8,
+ 17, 37, 43, 42, 48, 59, 60, 42, 13, -11, -21, -25, -36, -51, -59, -51,
+ -38, -34, -32, -17, 10, 33, 43, 43, 44, 55, 60, 46, 21, -6, -18, -22,
+ -28, -42, -54, -52, -39, -30, -32, -25, -4, 20, 36, 39, 39, 48, 60, 57,
+ 36, 10, -11, -19, -22, -34, -51, -58, -48, -35, -36, -34, -13, 13, 35, 41,
+ 38, 46, 59, 61, 44, 20, -5, -20, -22, -30, -46, -56, -53, -39, -34, -36,
+ -22, 1, 25, 39, 39, 42, 53, 60, 54, 34, 10, -10, -17, -21, -39, -57,
+ -59, -48, -38, -43, -35, -11, 16, 37, 43, 42, 52, 61, 58, 41, 19, -3,
+ -16, -21, -31, -50, -59, -53, -40, -39, -39, -22, 5, 30, 40, 38, 45, 58,
+ 64, 52, 28, 5, -12, -17, -23, -44, -58, -56, -46, -40, -43, -33, -7, 22,
+ 39, 41, 44, 55, 64, 60, 40, 13, -7, -16, -21, -35, -56, -60, -52, -44,
+ -43, -40, -21, 11, 34, 40, 40, 50, 61, 64, 53, 29, 6, -10, -16, -25,
+ -47, -62, -61, -53, -49, -47, -35, -5, 26, 42, 45, 49, 58, 65, 59, 39,
+ 15, -5, -16, -22, -37, -56, -61, -56, -50, -47, -42, -21, 11, 33, 40, 44,
+ 53, 63, 66, 54, 29, 8, -6, -15, -28, -52, -64, -60, -57, -53, -49, -31,
+ 1, 28, 40, 42, 51, 63, 66, 56, 36, 14, -3, -13, -25, -45, -61, -61,
+ -58, -54, -47, -38, -11, 20, 36, 41, 44, 55, 64, 60, 47, 28, 9, -4,
+ -15, -32, -56, -67, -64, -62, -55, -48, -27, 8, 29, 41, 47, 57, 66, 65,
+ 56, 39, 17, 0, -13, -27, -49, -66, -68, -67, -58, -48, -36, -8, 22, 38,
+ 45, 53, 63, 65, 61, 51, 28, 11, -4, -20, -40, -62, -70, -71, -68, -55,
+ -44, -24, 9, 30, 42, 52, 66, 69, 64, 58, 42, 20, 4, -14, -34, -57,
+ -71, -73, -73, -63, -51, -35, -5, 23, 38, 48, 62, 71, 69, 65, 54, 32,
+ 14, -6, -26, -48, -68, -79, -82, -72, -57, -42, -18, 11, 33, 48, 63, 73,
+ 72, 68, 62, 46, 22, 0, -21, -42, -63, -76, -83, -80, -65, -49, -28, -2,
+ 23, 42, 58, 71, 75, 72, 68, 56, 33, 10, -12, -32, -54, -73, -84, -87,
+ -73, -54, -36, -15, 11, 34, 52, 67, 73, 73, 72, 66, 48, 21, -6, -26,
+ -47, -67, -80, -88, -81, -62, -41, -23, 0, 27, 47, 65, 74, 74, 71, 67,
+ 57, 33, 4, -20, -42, -64, -77, -88, -88, -72, -49, -27, -7, 16, 40, 63,
+ 75, 75, 74, 69, 64, 46, 16, -13, -35, -57, -74, -87, -93, -81, -58, -35,
+ -17, 6, 33, 59, 73, 76, 76, 71, 68, 58, 29, -4, -29, -48, -68, -83,
+ -94, -92, -70, -42, -22, -4, 21, 51, 73, 78, 76, 73, 70, 63, 40, 7,
+ -24, -42, -60, -79, -91, -92, -76, -52, -30, -12, 9, 39, 66, 76, 76, 75,
+ 74, 70, 54, 24, -12, -36, -52, -72, -93, -100, -90, -64, -38, -21, -5, 25,
+ 61, 81, 81, 77, 78, 76, 63, 33, -5, -33, -49, -67, -90, -100, -92, -71,
+ -44, -21, -8, 14, 49, 75, 82, 77, 76, 75, 66, 45, 10, -27, -45, -59,
+ -80, -98, -98, -81, -52, -26, -12, 2, 34, 71, 86, 80, 75, 77, 71, 54,
+ 23, -17, -44, -57, -74, -93, -99, -87, -65, -36, -14, -4, 20, 55, 79, 82,
+ 78, 78, 75, 65, 41, 1, -34, -52, -67, -88, -104, -98, -76, -47, -23, -12,
+ 6, 45, 81, 90, 81, 79, 81, 72, 50, 11, -28, -50, -61, -81, -102, -103,
+ -84, -57, -30, -13, 1, 30, 70, 92, 88, 81, 80, 75, 59, 27, -15, -48,
+ -62, -76, -97, -106, -94, -69, -39, -16, -4, 17, 59, 92, 94, 87, 86, 83,
+ 67, 36, -4, -38, -61, -77, -96, -111, -102, -80, -53, -26, -8, 14, 50, 89,
+ 101, 93, 87, 83, 73, 46, 7, -31, -58, -72, -87, -106, -106, -88, -59, -31,
+ -12, 5, 33, 74, 99, 99, 90, 84, 78, 57, 22, -18, -49, -70, -84, -100,
+ -108, -96, -72, -43, -21, -3, 24, 61, 95, 106, 99, 90, 82, 65, 34, -6,
+ -40, -66, -83, -96, -106, -102, -82, -52, -27, -8, 15, 48, 86, 107, 105, 94,
+ 85, 73, 45, 6, -32, -61, -80, -91, -102, -106, -92, -63, -35, -15, 8, 37,
+ 74, 102, 109, 98, 87, 76, 54, 21, -16, -50, -76, -89, -98, -104, -98, -76,
+ -46, -23, -2, 25, 60, 93, 111, 106, 92, 82, 65, 35, -5, -39, -66, -83,
+ -95, -105, -105, -86, -57, -33, -11, 15, 50, 86, 111, 115, 102, 88, 71, 43,
+ 7, -32, -64, -86, -96, -100, -102, -92, -67, -40, -13, 13, 42, 75, 103, 116,
+ 106, 90, 74, 49, 16, -21, -54, -80, -94, -98, -100, -94, -75, -50, -23, 4,
+ 30, 62, 95, 117, 115, 100, 81, 57, 28, -10, -46, -75, -95, -102, -101, -97,
+ -83, -61, -32, -2, 24, 55, 87, 111, 118, 106, 88, 65, 35, 0, -36, -67,
+ -89, -101, -102, -98, -89, -68, -43, -13, 16, 46, 80, 107, 121, 116, 98, 75,
+ 47, 11, -27, -62, -87, -101, -104, -100, -93, -77, -51, -18, 13, 36, 67, 99,
+ 119, 119, 103, 81, 53, 21, -16, -52, -79, -96, -106, -102, -93, -82, -60, -30,
+ 3, 30, 59, 88, 111, 121, 111, 89, 61, 30, -4, -41, -74, -94, -106, -104,
+ -95, -87, -70, -41, -8, 22, 49, 81, 106, 120, 118, 98, 73, 41, 8, -30,
+ -64, -87, -104, -111, -100, -91, -77, -51, -21, 13, 41, 73, 100, 117, 122, 107,
+ 83, 52, 19, -18, -55, -82, -101, -111, -105, -93, -83, -60, -29, 5, 35, 64,
+ 92, 112, 121, 112, 88, 61, 29, -7, -45, -75, -94, -108, -108, -96, -87, -67,
+ -37, -5, 26, 52, 83, 105, 116, 116, 97, 70, 41, 7, -33, -67, -91, -105,
+ -110, -99, -88, -73, -48, -18, 15, 45, 74, 98, 114, 118, 104, 79, 51, 17,
+ -21, -58, -86, -102, -109, -103, -90, -77, -54, -23, 9, 36, 62, 88, 107, 114,
+ 107, 88, 63, 30, -8, -46, -77, -96, -107, -108, -97, -81, -63, -36, -4, 30,
+ 59, 84, 104, 115, 112, 95, 69, 38, 5, -33, -69, -94, -104, -105, -99, -87,
+ -72, -44, -11, 21, 47, 71, 97, 113, 113, 99, 77, 49, 17, -19, -57, -87,
+ -101, -105, -103, -90, -72, -54, -24, 10, 41, 64, 86, 104, 111, 104, 85, 57,
+ 25, -7, -42, -75, -96, -101, -98, -92, -79, -61, -36, -4, 28, 51, 74, 98,
+ 110, 107, 94, 70, 38, 5, -30, -64, -89, -101, -101, -95, -79, -63, -43, -14,
+ 21, 48, 68, 90, 105, 108, 97, 74, 44, 12, -20, -52, -83, -96, -96, -92,
+ -82, -67, -49, -24, 10, 39, 59, 79, 99, 107, 101, 83, 54, 21, -11, -41,
+ -71, -92, -98, -95, -84, -68, -54, -35, -5, 28, 54, 73, 92, 103, 103, 90,
+ 64, 31, -4, -34, -63, -85, -94, -92, -84, -70, -56, -38, -11, 19, 44, 64,
+ 83, 95, 98, 90, 66, 39, 9, -22, -50, -73, -86, -89, -84, -72, -59, -45,
+ -23, 6, 35, 58, 75, 89, 96, 92, 75, 49, 19, -14, -42, -63, -80, -88,
+ -84, -74, -60, -48, -30, -5, 23, 52, 70, 82, 91, 91, 79, 57, 29, -3,
+ -33, -54, -70, -84, -87, -79, -65, -50, -35, -16, 10, 41, 68, 80, 85, 88,
+ 82, 64, 36, 3, -28, -49, -60, -72, -83, -81, -66, -49, -37, -22, -2, 28,
+ 58, 74, 78, 83, 81, 69, 45, 14, -18, -42, -55, -66, -77, -79, -68, -53,
+ -39, -25, -8, 17, 46, 67, 72, 75, 74, 70, 53, 24, -9, -34, -48, -55,
+ -64, -74, -70, -55, -40, -28, -17, 3, 33, 61, 70, 71, 69, 68, 61, 37,
+ 3, -28, -44, -50, -57, -70, -73, -58, -41, -30, -21, -8, 21, 52, 67, 69,
+ 66, 66, 64, 44, 10, -22, -39, -48, -52, -61, -72, -62, -43, -29, -20, -12,
+ 7, 38, 62, 68, 61, 56, 60, 51, 23, -12, -36, -43, -44, -49, -65, -65,
+ -45, -29, -22, -19, -7, 24, 52, 65, 57, 52, 58, 57, 36, 0, -30, -38,
+ -37, -39, -55, -66, -52, -33, -23, -21, -14, 10, 40, 60, 59, 49, 51, 54,
+ 43, 11, -21, -35, -37, -33, -42, -55, -49, -29, -19, -20, -19, -5, 23, 49,
+ 54, 43, 42, 50, 49, 23, -12, -30, -34, -29, -31, -49, -54, -35, -19, -16,
+ -18, -11, 10, 39, 55, 45, 35, 41, 47, 31, -3, -26, -33, -28, -23, -36,
+ -47, -36, -18, -11, -16, -16, -3, 21, 42, 42, 32, 32, 40, 35, 13, -13,
+ -25, -24, -17, -22, -37, -38, -25, -16, -16, -19, -11, 7, 30, 42, 34, 27,
+ 33, 35, 19, -6, -21, -23, -17, -14, -23, -29, -21, -11, -10, -17, -16, -4,
+ 14, 30, 31, 20, 21, 29, 24, 6, -11, -16, -11, -5, -10, -20, -22, -15,
+ -12, -17, -21, -15, 0, 20, 29, 22, 17, 23, 25, 16, -2, -14, -14, -7,
+ -2, -9, -14, -12, -9, -11, -17, -17, -11, 3, 18, 17, 9, 13, 19, 17,
+ 7, -5, -5, 3, 8, 3, -7, -10, -12, -14, -20, -22, -17, -7, 9, 17,
+ 10, 8, 15, 18, 11, 2, -3, 1, 8, 9, 5, -3, -9, -12, -18, -21,
+ -21, -19, -4, 10, 9, 2, 5, 14, 16, 11, 4, 5, 13, 16, 14, 6,
+ -8, -14, -19, -23, -24, -21, -13, -2, 7, 3, -2, 8, 12, 11, 9, 10,
+ 14, 19, 20, 16, 4, -9, -17, -23, -26, -27, -24, -14, -2, 1, -5, 3,
+ 15, 17, 14, 14, 17, 22, 25, 20, 9, -8, -19, -25, -30, -29, -26, -22,
+ -11, 0, -3, -3, 9, 16, 19, 20, 21, 24, 28, 28, 20, 2, -16, -25,
+ -30, -34, -33, -32, -23, -9, -6, -8, 2, 15, 21, 24, 26, 29, 33, 34,
+ 30, 14, -11, -26, -33, -38, -38, -37, -34, -23, -12, -7, 0, 11, 21, 29,
+ 34, 35, 37, 39, 35, 21, -5, -26, -34, -39, -40, -42, -42, -31, -17, -9,
+ -4, 7, 19, 31, 38, 38, 41, 42, 40, 28, 3, -22, -36, -42, -45, -46,
+ -46, -37, -23, -14, -6, 6, 20, 32, 40, 40, 44, 46, 41, 31, 13, -12,
+ -32, -44, -47, -48, -49, -44, -32, -20, -8, 3, 15, 27, 40, 45, 47, 50,
+ 47, 39, 21, -6, -29, -42, -46, -51, -56, -52, -41, -24, -13, -4, 11, 27,
+ 41, 51, 52, 53, 52, 45, 29, 2, -25, -45, -50, -52, -57, -56, -49, -32,
+ -16, -4, 9, 22, 36, 49, 55, 56, 56, 50, 35, 11, -14, -37, -51, -57,
+ -61, -61, -56, -41, -23, -8, 8, 21, 33, 48, 61, 64, 60, 54, 40, 17,
+ -8, -34, -52, -59, -62, -63, -60, -49, -30, -14, 2, 19, 33, 47, 60, 66,
+ 67, 65, 50, 25, -3, -26, -47, -59, -68, -72, -66, -57, -38, -20, -5, 14,
+ 30, 44, 61, 71, 71, 68, 57, 34, 7, -20, -43, -58, -68, -72, -69, -62,
+ -45, -25, -10, 7, 24, 42, 59, 70, 74, 73, 65, 46, 16, -15, -38, -53,
+ -65, -77, -77, -70, -54, -34, -19, 0, 20, 41, 60, 74, 82, 80, 71, 54,
+ 27, -8, -36, -55, -68, -78, -82, -76, -61, -40, -20, -2, 17, 36, 57, 74,
+ 83, 82, 74, 62, 39, 3, -31, -49, -62, -75, -84, -84, -69, -47, -27, -13,
+ 6, 31, 56, 73, 82, 86, 80, 68, 49, 14, -24, -46, -60, -74, -83, -86,
+ -76, -54, -32, -15, 3, 23, 48, 71, 85, 87, 80, 71, 57, 27, -12, -41,
+ -57, -68, -78, -88, -84, -64, -41, -23, -5, 16, 40, 65, 84, 90, 87, 77,
+ 63, 36, -3, -34, -57, -69, -76, -85, -87, -73, -48, -27, -8, 13, 34, 60,
+ 83, 91, 86, 77, 66, 44, 9, -26, -53, -68, -74, -83, -88, -80, -56, -33,
+ -13, 9, 29, 55, 79, 93, 89, 76, 67, 52, 21, -15, -46, -69, -74, -77,
+ -84, -86, -67, -42, -20, 4, 23, 43, 71, 94, 95, 80, 67, 56, 32, 0,
+ -37, -66, -74, -73, -78, -87, -76, -50, -25, 1, 21, 37, 61, 88, 97, 84,
+ 67, 57, 38, 8, -25, -59, -77, -77, -76, -81, -80, -61, -34, -6, 20, 36,
+ 55, 80, 96, 91, 70, 54, 39, 17, -14, -51, -75, -79, -75, -77, -80, -68,
+ -40, -11, 15, 33, 48, 71, 92, 91, 73, 57, 45, 24, -3, -38, -68, -79,
+ -77, -76, -80, -74, -51, -19, 12, 32, 46, 65, 88, 96, 83, 59, 40, 24,
+ 4, -31, -67, -83, -80, -73, -73, -72, -55, -24, 9, 31, 44, 58, 78, 90,
+ 84, 63, 42, 28, 10, -18, -53, -77, -82, -76, -73, -74, -65, -37, -2, 27,
+ 42, 55, 73, 88, 90, 72, 47, 28, 13, -12, -45, -74, -84, -78, -70, -68,
+ -63, -43, -9, 23, 42, 52, 64, 78, 84, 75, 52, 32, 17, -3, -32, -62,
+ -79, -78, -71, -67, -65, -52, -19, 15, 38, 50, 61, 73, 80, 79, 59, 34,
+ 18, 3, -21, -51, -75, -81, -72, -64, -61, -54, -31, 4, 31, 48, 55, 63,
+ 73, 78, 67, 40, 21, 8, -12, -39, -65, -80, -76, -65, -58, -52, -38, -8,
+ 25, 45, 56, 61, 67, 74, 69, 47, 22, 7, -10, -31, -56, -75, -77, -66,
+ -57, -49, -37, -14, 16, 40, 53, 57, 61, 67, 69, 55, 30, 11, -6, -25,
+ -47, -69, -78, -70, -59, -51, -40, -20, 10, 34, 51, 58, 59, 63, 66, 59,
+ 36, 14, -2, -19, -40, -61, -75, -71, -59, -51, -41, -27, -2, 26, 47, 58,
+ 58, 59, 64, 63, 46, 19, -2, -17, -35, -56, -71, -75, -64, -50, -40, -26,
+ -6, 21, 43, 55, 57, 56, 58, 59, 47, 23, 1, -13, -29, -48, -63, -69,
+ -61, -48, -40, -29, -11, 13, 35, 48, 53, 51, 53, 57, 50, 33, 9, -10,
+ -25, -42, -56, -65, -64, -51, -40, -29, -13, 9, 30, 44, 50, 48, 47, 50,
+ 46, 35, 13, -8, -20, -33, -47, -57, -56, -48, -38, -30, -16, 1, 21, 35,
+ 44, 46, 42, 44, 44, 39, 21, -3, -18, -30, -40, -51, -57, -51, -37, -26,
+ -14, 0, 16, 33, 42, 43, 37, 34, 37, 35, 22, 1, -17, -27, -34, -41,
+ -48, -45, -36, -25, -11, 0, 11, 24, 34, 38, 35, 30, 29, 30, 24, 8,
+ -11, -24, -31, -36, -42, -42, -35, -25, -12, -2, 9, 21, 29, 33, 32, 27,
+ 25, 26, 23, 9, -8, -21, -31, -34, -36, -37, -33, -26, -13, -2, 8, 18,
+ 24, 28, 29, 27, 22, 20, 21, 14, -2, -17, -27, -30, -31, -33, -32, -26,
+ -14, -3, 6, 15, 22, 27, 26, 25, 22, 17, 17, 13, 3, -12, -25, -30,
+ -31, -30, -27, -24, -14, 0, 8, 16, 20, 22, 22, 21, 16, 11, 13, 13,
+ 3, -8, -21, -27, -26, -25, -25, -23, -12, 0, 6, 12, 18, 20, 22, 20,
+ 15, 9, 9, 10, 3, -9, -21, -29, -28, -23, -20, -19, -10, 3, 13, 17,
+ 19, 19, 21, 17, 11, 4, 1, 4, 0, -8, -17, -25, -24, -21, -19, -16,
+ -9, 4, 13, 17, 19, 20, 22, 19, 11, 3, -4, -3, -4, -12, -18, -26,
+ -28, -23, -16, -10, -5, 5, 18, 25, 25, 22, 21, 19, 9, 0, -9, -11,
+ -10, -13, -16, -24, -27, -22, -14, -8, -2, 7, 17, 25, 25, 22, 20, 17,
+ 10, -2, -10, -12, -13, -15, -18, -20, -24, -22, -16, -8, 3, 11, 17, 25,
+ 27, 23, 21, 17, 9, 0, -10, -12, -13, -18, -19, -20, -24, -23, -17, -10,
+ 0, 11, 19, 26, 30, 26, 24, 20, 12, 3, -8, -15, -18, -22, -25, -25,
+ -25, -24, -20, -12, 2, 15, 20, 25, 31, 33, 29, 23, 12, 3, -5, -15,
+ -23, -28, -28, -25, -22, -22, -18, -10, 2, 15, 19, 23, 30, 32, 28, 24,
+ 15, 7, 1, -13, -23, -27, -29, -28, -26, -24, -20, -14, -2, 13, 20, 24,
+ 32, 34, 32, 29, 22, 9, -2, -10, -21, -30, -34, -34, -29, -22, -20, -18,
+ -5, 14, 23, 25, 31, 36, 35, 30, 22, 10, 0, -8, -21, -34, -39, -36,
+ -32, -27, -20, -15, -5, 14, 27, 28, 32, 36, 35, 33, 25, 14, 0, -11,
+ -21, -34, -40, -41, -39, -30, -20, -13, -6, 10, 27, 30, 32, 35, 34, 36,
+ 29, 17, 5, -7, -16, -33, -45, -45, -43, -33, -24, -18, -9, 8, 26, 32,
+ 33, 39, 38, 36, 31, 20, 10, -6, -19, -32, -45, -47, -46, -39, -25, -12,
+ -3, 8, 22, 32, 32, 35, 35, 32, 31, 23, 14, 0, -15, -26, -43, -51,
+ -50, -43, -29, -17, -6, 5, 19, 34, 36, 33, 37, 37, 34, 25, 16, 5,
+ -11, -26, -41, -51, -55, -51, -36, -21, -7, 7, 16, 28, 37, 35, 35, 36,
+ 34, 30, 20, 9, -7, -22, -37, -49, -56, -54, -42, -25, -11, 2, 13, 24,
+ 35, 38, 37, 38, 37, 32, 25, 16, 1, -21, -38, -47, -56, -58, -50, -34,
+ -14, 4, 13, 20, 31, 40, 39, 35, 36, 34, 28, 20, 5, -15, -33, -44,
+ -55, -63, -54, -38, -19, -2, 10, 17, 30, 40, 41, 36, 38, 41, 33, 22,
+ 9, -13, -36, -50, -55, -63, -61, -44, -22, 2, 18, 22, 28, 38, 42, 39,
+ 34, 35, 34, 27, 14, -7, -29, -43, -51, -60, -63, -50, -30, -10, 8, 16,
+ 21, 32, 40, 40, 38, 39, 41, 35, 24, 6, -20, -41, -54, -62, -65, -58,
+ -39, -16, 7, 18, 22, 29, 39, 43, 40, 35, 38, 37, 27, 12, -14, -37,
+ -51, -58, -64, -64, -47, -22, -2, 14, 18, 24, 36, 44, 45, 41, 43, 43,
+ 32, 17, -8, -35, -54, -63, -67, -68, -56, -29, -4, 16, 24, 26, 35, 44,
+ 47, 43, 38, 38, 36, 24, 0, -30, -50, -57, -59, -63, -61, -40, -11, 11,
+ 20, 20, 26, 39, 48, 46, 40, 39, 42, 33, 12, -20, -47, -58, -60, -62,
+ -61, -49, -23, 2, 17, 21, 22, 33, 48, 51, 45, 43, 43, 38, 20, -10,
+ -41, -58, -61, -64, -62, -55, -35, -9, 10, 21, 23, 32, 50, 57, 49, 45,
+ 45, 43, 26, -6, -38, -58, -62, -65, -67, -61, -44, -15, 10, 23, 26, 28,
+ 44, 59, 55, 46, 42, 41, 33, 6, -30, -57, -64, -62, -64, -62, -50, -26,
+ 2, 18, 26, 28, 39, 59, 60, 48, 43, 43, 37, 14, -22, -53, -67, -63,
+ -65, -66, -55, -33, -2, 19, 28, 31, 37, 55, 64, 53, 41, 39, 37, 20,
+ -16, -48, -66, -65, -62, -66, -60, -43, -12, 15, 26, 31, 37, 53, 69, 63,
+ 46, 39, 38, 27, -5, -44, -72, -73, -65, -65, -63, -52, -24, 11, 31, 36,
+ 38, 48, 65, 70, 53, 38, 34, 28, 5, -35, -69, -78, -70, -65, -63, -53,
+ -30, 2, 26, 38, 43, 49, 62, 69, 58, 40, 33, 28, 9, -25, -61, -78,
+ -75, -69, -64, -55, -37, -7, 22, 36, 43, 49, 57, 66, 62, 44, 31, 29,
+ 15, -16, -52, -76, -77, -69, -63, -57, -44, -16, 14, 33, 42, 48, 54, 65,
+ 68, 52, 33, 27, 19, -6, -41, -72, -82, -74, -65, -59, -48, -24, 7, 29,
+ 43, 50, 53, 60, 67, 58, 39, 28, 22, 2, -31, -64, -82, -79, -71, -61,
+ -49, -31, -2, 22, 40, 51, 55, 58, 65, 63, 46, 29, 21, 9, -21, -56,
+ -79, -83, -77, -65, -54, -37, -10, 16, 36, 50, 57, 60, 65, 64, 50, 33,
+ 22, 11, -13, -47, -73, -82, -80, -70, -57, -42, -19, 8, 30, 49, 58, 61,
+ 62, 64, 56, 41, 24, 11, -6, -35, -66, -80, -82, -75, -61, -45, -25, -2,
+ 22, 43, 57, 63, 64, 63, 58, 49, 31, 15, -2, -26, -58, -79, -85, -81,
+ -66, -49, -31, -9, 17, 39, 55, 64, 69, 67, 61, 53, 35, 16, 1, -20,
+ -49, -75, -86, -85, -74, -54, -34, -11, 11, 33, 53, 64, 70, 68, 59, 51,
+ 40, 22, 5, -15, -40, -66, -79, -81, -78, -63, -41, -19, 4, 25, 44, 58,
+ 67, 72, 65, 57, 47, 29, 11, -8, -31, -61, -81, -85, -82, -68, -47, -25,
+ -3, 21, 44, 59, 68, 73, 68, 56, 47, 33, 15, -7, -27, -52, -76, -82,
+ -82, -72, -52, -30, -7, 13, 36, 57, 67, 74, 72, 61, 48, 36, 20, -4,
+ -25, -47, -71, -81, -81, -75, -56, -33, -10, 11, 30, 49, 63, 73, 74, 63,
+ 48, 37, 25, 6, -20, -41, -63, -79, -81, -77, -65, -43, -19, 4, 25, 45,
+ 63, 73, 76, 70, 55, 41, 28, 10, -15, -38, -59, -77, -83, -79, -70, -49,
+ -25, -4, 20, 40, 59, 74, 76, 73, 62, 46, 33, 16, -10, -34, -51, -68,
+ -83, -85, -75, -58, -34, -11, 14, 35, 55, 73, 79, 76, 69, 51, 33, 20,
+ -2, -30, -53, -67, -81, -84, -76, -61, -39, -14, 11, 32, 49, 67, 77, 74,
+ 68, 55, 37, 23, 5, -22, -45, -59, -73, -84, -82, -68, -46, -24, 3, 26,
+ 43, 62, 75, 74, 72, 61, 42, 25, 10, -15, -40, -57, -70, -83, -84, -71,
+ -49, -28, -6, 20, 41, 59, 72, 72, 69, 63, 48, 29, 13, -8, -31, -51,
+ -66, -79, -84, -75, -56, -37, -16, 12, 36, 55, 71, 74, 72, 69, 54, 34,
+ 16, -5, -28, -47, -61, -75, -85, -80, -60, -38, -20, 4, 30, 53, 68, 71,
+ 69, 67, 57, 39, 20, 0, -21, -41, -58, -71, -79, -79, -66, -45, -25, -3,
+ 23, 45, 61, 68, 69, 70, 63, 47, 29, 8, -16, -37, -56, -71, -80, -81,
+ -71, -52, -30, -7, 17, 41, 60, 67, 67, 68, 65, 50, 30, 10, -14, -31,
+ -47, -65, -77, -79, -70, -53, -33, -14, 8, 34, 56, 62, 62, 66, 64, 54,
+ 36, 15, -8, -27, -42, -61, -73, -75, -70, -56, -36, -14, 5, 26, 49, 60,
+ 59, 61, 60, 54, 42, 23, -2, -22, -35, -53, -69, -75, -70, -58, -41, -20,
+ -3, 18, 43, 59, 57, 57, 60, 56, 44, 28, 7, -17, -32, -47, -63, -73,
+ -72, -62, -46, -23, -6, 12, 35, 55, 60, 57, 59, 56, 49, 35, 14, -13,
+ -28, -40, -58, -72, -73, -62, -50, -31, -13, 5, 30, 51, 59, 56, 58, 61,
+ 56, 38, 17, -9, -26, -37, -52, -68, -74, -63, -50, -32, -14, 1, 22, 45,
+ 57, 56, 51, 54, 54, 41, 21, -4, -22, -31, -44, -59, -69, -63, -48, -36,
+ -21, -7, 11, 35, 52, 56, 53, 54, 58, 48, 30, 8, -17, -32, -43, -57,
+ -68, -69, -56, -39, -22, -8, 6, 28, 49, 57, 54, 51, 55, 52, 35, 13,
+ -13, -29, -36, -49, -64, -70, -58, -39, -23, -11, 0, 19, 43, 57, 55, 47,
+ 49, 55, 43, 18, -9, -28, -35, -42, -57, -69, -65, -45, -25, -11, 1, 14,
+ 37, 55, 60, 50, 45, 48, 42, 21, -4, -25, -35, -40, -50, -60, -61, -46,
+ -27, -15, -6, 6, 25, 46, 56, 50, 43, 45, 47, 33, 9, -15, -30, -37,
+ -45, -58, -64, -56, -36, -18, -8, 4, 18, 40, 58, 59, 47, 39, 41, 35,
+ 12, -15, -32, -38, -39, -46, -57, -55, -37, -17, -7, 1, 11, 27, 48, 56,
+ 47, 37, 38, 38, 21, -6, -24, -32, -37, -43, -54, -57, -44, -25, -9, 2,
+ 11, 24, 44, 57, 51, 38, 32, 31, 21, -5, -28, -35, -36, -36, -45, -51,
+ -41, -25, -8, 3, 8, 17, 33, 48, 49, 37, 31, 30, 25, 7, -18, -30,
+ -34, -37, -40, -48, -47, -33, -16, 1, 11, 16, 28, 42, 50, 43, 30, 25,
+ 22, 10, -12, -28, -33, -34, -35, -41, -44, -33, -18, -2, 9, 12, 20, 32,
+ 43, 41, 29, 24, 22, 14, -3, -21, -29, -30, -31, -35, -41, -35, -21, -6,
+ 9, 13, 18, 27, 38, 42, 29, 18, 16, 13, 4, -15, -27, -28, -27, -28,
+ -34, -34, -23, -10, 5, 11, 14, 22, 32, 37, 31, 20, 16, 12, 6, -9,
+ -22, -25, -27, -26, -32, -34, -27, -15, 0, 10, 12, 18, 28, 36, 35, 23,
+ 14, 11, 8, -3, -19, -28, -28, -25, -27, -32, -28, -16, -2, 11, 14, 14,
+ 22, 30, 31, 24, 15, 11, 8, 2, -11, -22, -25, -25, -26, -30, -28, -18,
+ -7, 5, 12, 14, 19, 27, 30, 26, 19, 13, 9, 4, -6, -20, -26, -23,
+ -24, -27, -27, -19, -6, 4, 12, 12, 13, 22, 26, 22, 15, 11, 10, 6,
+ -2, -12, -19, -19, -21, -25, -25, -20, -11, -3, 5, 9, 13, 19, 24, 24,
+ 21, 15, 12, 7, 2, -9, -20, -22, -22, -23, -24, -22, -11, -2, 7, 11,
+ 13, 17, 21, 21, 18, 13, 11, 7, 1, -7, -15, -19, -19, -21, -20, -18,
+ -12, -4, 2, 8, 11, 15, 17, 16, 15, 13, 11, 8, 4, -3, -11, -16,
+ -15, -19, -20, -16, -12, -5, 2, 5, 8, 14, 17, 15, 11, 10, 9, 8,
+ 4, -2, -6, -11, -12, -14, -18, -13, -7, -6, -3, 2, 6, 10, 13, 13,
+ 9, 8, 9, 6, 1, 0, -5, -9, -12, -12, -13, -12, -4, 1, 3, 4,
+ 4, 7, 11, 10, 7, 3, 3, 4, 2, -2, -3, -6, -7, -6, -6, -8,
+ -5, 2, 1, 1, 0, 1, 5, 5, 3, 0, 0, 5, 5, 2, 3, 0,
+ -3, -5, -6, -8, -7, -2, -3, -4, -2, -2, 3, 6, 4, 1, -3, 1,
+ 5, 3, 2, 0, -2, -3, -4, -5, -5, 1, 2, -3, -3, -4, -3, 4,
+ 4, 0, -5, -3, 3, 3, 2, 1, 1, 0, 0, 0, -3, -2, 1, -2,
+ -4, -3, -4, 1, 5, 2, -5, -7, -2, 2, -2, -2, 0, 2, 3, 2,
+ 2, 3, 6, 4, -2, -5, -6, -2, 3, -2, -9, -11, -5, 0, -3, -4,
+ -2, 3, 7, 8, 4, 2, 4, 3, 0, -6, -8, -6, 2, 4, -3, -10,
+ -10, -5, -2, -4, -5, -3, 5, 11, 11, 8, 5, 5, 4, -2, -9, -9,
+ -2, 0, -5, -13, -14, -10, -5, -4, -2, 2, 6, 14, 15, 11, 8, 6,
+ 1, -5, -10, -12, -6, 1, -2, -10, -15, -11, -4, -3, -6, -5, 2, 14,
+ 19, 14, 10, 10, 8, 3, -6, -15, -12, -4, -4, -12, -18, -17, -10, -2,
+ 0, 1, 6, 16, 25, 21, 12, 8, 4, -2, -8, -18, -20, -11, -6, -9,
+ -14, -14, -10, -3, 0, 1, 6, 13, 23, 25, 17, 13, 9, 1, -6, -13,
+ -18, -14, -11, -13, -17, -19, -14, -8, -3, 1, 7, 14, 24, 30, 24, 16,
+ 12, 4, -5, -11, -18, -19, -15, -12, -14, -19, -18, -14, -9, 0, 8, 13,
+ 19, 27, 28, 22, 18, 9, -4, -11, -14, -16, -15, -16, -16, -17, -16, -14,
+ -13, -6, 4, 12, 19, 26, 31, 27, 19, 13, 3, -8, -12, -16, -18, -19,
+ -17, -16, -20, -18, -15, -10, 1, 10, 18, 24, 31, 30, 22, 18, 9, -4,
+ -10, -14, -17, -20, -22, -19, -19, -22, -18, -13, -2, 9, 16, 21, 29, 36,
+ 29, 19, 12, 1, -7, -10, -15, -22, -24, -20, -18, -21, -21, -17, -8, 7,
+ 16, 23, 27, 33, 35, 26, 17, 7, -5, -11, -14, -22, -27, -24, -19, -22,
+ -25, -19, -11, 5, 16, 21, 25, 33, 38, 31, 18, 9, -2, -10, -13, -22,
+ -29, -28, -21, -18, -24, -22, -15, -3, 14, 21, 24, 30, 38, 36, 24, 13,
+ 4, -5, -9, -16, -28, -32, -25, -21, -25, -27, -18, -7, 8, 18, 24, 31,
+ 40, 40, 29, 16, 6, -3, -8, -16, -27, -31, -27, -22, -24, -27, -21, -10,
+ 4, 16, 22, 28, 37, 40, 33, 19, 7, 1, -5, -12, -23, -32, -28, -23,
+ -23, -27, -26, -15, -2, 13, 21, 25, 34, 41, 38, 28, 14, 4, -3, -11,
+ -22, -34, -35, -30, -26, -28, -29, -20, -3, 14, 24, 27, 32, 41, 42, 34,
+ 17, 4, -4, -11, -20, -32, -38, -33, -28, -27, -27, -22, -9, 7, 20, 29,
+ 34, 39, 40, 37, 24, 10, 2, -7, -16, -28, -40, -40, -33, -29, -28, -27,
+ -16, 5, 21, 28, 32, 36, 41, 40, 30, 12, 1, -6, -11, -22, -37, -42,
+ -34, -30, -29, -27, -20, -3, 16, 27, 32, 34, 39, 41, 35, 20, 6, -4,
+ -11, -16, -32, -45, -41, -33, -31, -27, -23, -10, 13, 28, 33, 35, 38, 39,
+ 36, 25, 8, -6, -11, -14, -26, -42, -45, -34, -29, -25, -23, -15, 6, 26,
+ 36, 36, 36, 37, 36, 29, 14, -2, -12, -14, -23, -42, -50, -42, -32, -23,
+ -18, -15, 3, 25, 38, 39, 35, 35, 37, 33, 18, -3, -15, -18, -20, -34,
+ -48, -47, -34, -22, -14, -12, -4, 17, 35, 41, 37, 34, 33, 33, 24, 6,
+ -13, -22, -22, -30, -45, -51, -39, -23, -10, -6, -3, 13, 32, 41, 37, 30,
+ 29, 31, 27, 10, -10, -22, -23, -26, -38, -48, -44, -28, -12, -5, -3, 9,
+ 27, 38, 38, 32, 28, 29, 27, 17, -4, -21, -26, -27, -35, -47, -49, -33,
+ -12, 2, 5, 9, 23, 35, 40, 34, 21, 23, 25, 22, 5, -20, -28, -28,
+ -29, -39, -50, -43, -19, 3, 10, 7, 15, 29, 41, 43, 28, 22, 23, 22,
+ 12, -16, -33, -32, -32, -38, -46, -43, -21, 3, 15, 13, 16, 29, 35, 35,
+ 27, 19, 19, 19, 15, -8, -30, -31, -30, -32, -40, -44, -29, -2, 18, 17,
+ 11, 22, 34, 37, 32, 21, 18, 20, 17, -2, -28, -37, -34, -34, -38, -42,
+ -30, -7, 16, 22, 16, 20, 31, 31, 29, 23, 17, 18, 19, 6, -21, -37,
+ -35, -34, -35, -38, -35, -15, 14, 27, 21, 13, 23, 31, 31, 26, 16, 12,
+ 16, 12, -10, -35, -39, -35, -36, -36, -34, -21, 6, 24, 24, 16, 20, 29,
+ 28, 27, 22, 16, 17, 15, -4, -29, -41, -39, -40, -39, -36, -29, -6, 20,
+ 27, 21, 19, 28, 33, 31, 27, 18, 14, 13, 2, -22, -41, -43, -40, -39,
+ -34, -28, -12, 16, 28, 24, 19, 25, 29, 27, 24, 19, 15, 12, 4, -15,
+ -34, -41, -40, -37, -32, -26, -18, 5, 24, 24, 20, 21, 26, 27, 26, 24,
+ 18, 12, 6, -9, -30, -44, -45, -41, -33, -26, -19, -2, 23, 29, 24, 22,
+ 24, 28, 25, 22, 18, 13, 7, -7, -24, -40, -46, -42, -36, -28, -21, -6,
+ 15, 28, 25, 22, 25, 29, 28, 23, 20, 14, 6, -6, -22, -40, -47, -42,
+ -36, -28, -23, -10, 13, 30, 28, 21, 23, 27, 28, 21, 18, 16, 9, -2,
+ -17, -33, -44, -44, -38, -31, -23, -14, 5, 25, 32, 25, 23, 26, 29, 24,
+ 16, 13, 8, -2, -15, -31, -43, -44, -37, -30, -23, -14, 1, 21, 31, 27,
+ 22, 24, 28, 25, 17, 13, 10, 3, -10, -27, -40, -44, -38, -32, -26, -17,
+ -3, 16, 31, 31, 25, 25, 30, 29, 17, 8, 7, 3, -8, -25, -39, -43,
+ -37, -31, -27, -18, -4, 13, 29, 32, 26, 24, 27, 27, 17, 9, 8, 6,
+ -5, -20, -34, -39, -37, -34, -30, -21, -8, 6, 23, 34, 31, 29, 28, 27,
+ 22, 13, 6, 5, -4, -18, -34, -40, -37, -34, -29, -23, -10, 5, 21, 32,
+ 29, 27, 29, 26, 20, 12, 4, 3, 0, -12, -28, -37, -35, -31, -29, -23,
+ -13, 1, 16, 30, 33, 29, 27, 25, 21, 15, 5, -2, -3, -9, -22, -35,
+ -36, -31, -29, -24, -14, 0, 12, 27, 35, 31, 29, 26, 21, 16, 8, -2,
+ -3, -7, -19, -34, -36, -32, -31, -28, -18, -3, 11, 22, 32, 32, 30, 29,
+ 23, 16, 11, 2, -3, -6, -17, -32, -37, -32, -30, -31, -23, -6, 9, 18,
+ 30, 36, 32, 31, 25, 17, 13, 4, -6, -8, -14, -26, -36, -34, -31, -31,
+ -25, -11, 6, 16, 24, 34, 35, 33, 28, 17, 16, 10, -3, -9, -13, -23,
+ -34, -36, -32, -31, -27, -16, 2, 16, 22, 30, 35, 33, 30, 21, 15, 11,
+ 0, -7, -11, -20, -31, -35, -31, -31, -29, -21, -6, 13, 21, 25, 32, 34,
+ 33, 26, 18, 13, 4, -6, -10, -19, -29, -34, -34, -29, -27, -24, -12, 7,
+ 20, 25, 30, 33, 32, 29, 21, 13, 7, -5, -11, -18, -28, -35, -36, -29,
+ -25, -24, -16, 3, 21, 26, 28, 34, 37, 34, 26, 12, 4, -5, -13, -20,
+ -30, -35, -39, -35, -24, -19, -13, -2, 15, 27, 30, 32, 34, 31, 28, 18,
+ 5, -6, -15, -20, -24, -31, -37, -35, -24, -19, -16, -9, 8, 24, 30, 30,
+ 33, 35, 35, 24, 5, -5, -11, -20, -27, -34, -40, -39, -30, -21, -16, -9,
+ 4, 20, 32, 36, 36, 36, 35, 31, 13, -3, -13, -23, -27, -29, -41, -44,
+ -33, -19, -11, -10, -4, 14, 32, 38, 34, 33, 36, 33, 18, -4, -13, -20,
+ -25, -28, -37, -43, -34, -22, -14, -8, -4, 9, 26, 39, 38, 35, 35, 34,
+ 23, 3, -12, -21, -28, -28, -31, -41, -40, -27, -15, -7, -6, 2, 20, 37,
+ 42, 36, 34, 35, 28, 9, -10, -18, -24, -26, -29, -38, -42, -32, -21, -11,
+ -6, -3, 12, 33, 45, 41, 37, 37, 29, 13, -4, -17, -26, -28, -28, -33,
+ -39, -37, -26, -15, -8, -7, 6, 29, 47, 46, 39, 34, 30, 20, 1, -18,
+ -26, -26, -25, -29, -37, -40, -31, -17, -8, -7, 0, 20, 42, 51, 45, 38,
+ 30, 18, 7, -10, -24, -27, -26, -24, -29, -38, -37, -27, -14, -9, -6, 11,
+ 36, 51, 47, 42, 34, 24, 14, -3, -20, -25, -23, -22, -26, -37, -42, -33,
+ -17, -8, -7, 4, 28, 50, 54, 45, 35, 24, 15, 3, -16, -24, -25, -22,
+ -23, -32, -41, -37, -22, -11, -8, 0, 21, 44, 54, 46, 34, 26, 18, 7,
+ -11, -22, -21, -20, -21, -28, -40, -43, -30, -15, -10, -3, 16, 40, 56, 52,
+ 37, 24, 16, 9, -6, -21, -22, -18, -17, -22, -35, -43, -34, -21, -14, -9,
+ 7, 34, 53, 54, 40, 29, 21, 14, 4, -14, -21, -17, -17, -22, -33, -46,
+ -45, -31, -16, -8, 4, 25, 50, 60, 49, 31, 20, 15, 9, -5, -17, -18,
+ -15, -17, -26, -42, -50, -40, -24, -11, -2, 18, 43, 56, 52, 35, 21, 17,
+ 11, 0, -12, -18, -14, -15, -22, -36, -50, -46, -30, -15, -3, 12, 35, 53,
+ 55, 41, 24, 18, 12, 5, -4, -15, -18, -15, -20, -33, -46, -49, -37, -21,
+ -7, 7, 25, 46, 54, 45, 27, 18, 14, 10, 3, -8, -15, -16, -18, -28,
+ -41, -49, -44, -29, -12, 4, 17, 35, 49, 49, 34, 19, 16, 15, 9, 1,
+ -10, -14, -16, -24, -38, -50, -49, -36, -18, -3, 10, 26, 43, 49, 38, 22,
+ 18, 20, 16, 9, -5, -13, -16, -23, -36, -50, -53, -43, -25, -8, 6, 21,
+ 38, 48, 44, 27, 19, 21, 19, 13, -2, -13, -17, -21, -30, -45, -52, -46,
+ -29, -10, 3, 14, 29, 42, 44, 30, 17, 19, 21, 17, 6, -8, -14, -19,
+ -26, -39, -49, -48, -36, -18, -2, 11, 27, 37, 42, 37, 22, 18, 21, 19,
+ 9, -5, -13, -18, -24, -33, -45, -46, -39, -24, -8, 6, 20, 33, 40, 38,
+ 27, 19, 22, 23, 17, 4, -8, -14, -22, -29, -43, -48, -43, -32, -16, -2,
+ 13, 25, 34, 39, 33, 23, 21, 23, 20, 9, -4, -11, -19, -25, -33, -43,
+ -42, -34, -20, -7, 3, 14, 24, 32, 31, 22, 20, 26, 28, 20, 6, -5,
+ -11, -18, -28, -42, -44, -38, -28, -15, -5, 8, 19, 28, 31, 24, 21, 25,
+ 27, 22, 10, 0, -6, -12, -22, -34, -38, -34, -30, -20, -11, 0, 11, 20,
+ 26, 23, 19, 22, 27, 25, 17, 7, -2, -7, -17, -29, -35, -35, -34, -26,
+ -16, -5, 7, 15, 23, 28, 24, 21, 22, 24, 20, 11, -2, -8, -14, -24,
+ -29, -31, -31, -27, -18, -9, 0, 8, 15, 22, 23, 20, 21, 24, 24, 19,
+ 7, -4, -10, -19, -26, -32, -34, -33, -24, -12, -2, 6, 14, 22, 26, 23,
+ 22, 22, 22, 21, 10, 0, -6, -15, -21, -24, -28, -31, -28, -17, -7, 2,
+ 7, 13, 19, 23, 23, 21, 19, 21, 18, 8, -2, -11, -17, -21, -24, -30,
+ -33, -25, -11, 0, 4, 9, 16, 20, 21, 20, 18, 18, 20, 14, 4, -6,
+ -12, -15, -17, -25, -32, -32, -20, -6, -3, -3, 7, 18, 23, 19, 16, 19,
+ 26, 24, 11, 0, -6, -9, -15, -25, -33, -35, -26, -15, -9, -6, 5, 17,
+ 22, 21, 17, 18, 25, 26, 16, 4, -5, -7, -9, -18, -29, -38, -35, -21,
+ -11, -9, -4, 9, 22, 25, 20, 16, 22, 30, 24, 8, -4, -5, -5, -13,
+ -25, -36, -38, -26, -16, -11, -10, 2, 19, 25, 18, 12, 19, 30, 28, 14,
+ 1, -2, 3, -3, -17, -31, -36, -29, -21, -18, -19, -11, 7, 20, 16, 10,
+ 16, 30, 36, 24, 8, 4, 8, 6, -12, -32, -40, -35, -26, -21, -20, -14,
+ 2, 19, 20, 10, 12, 24, 35, 29, 13, 5, 7, 9, -3, -23, -37, -37,
+ -31, -23, -21, -19, -8, 12, 19, 10, 6, 19, 36, 37, 23, 11, 12, 16,
+ 7, -15, -35, -43, -38, -30, -27, -23, -16, 2, 18, 16, 7, 13, 30, 38,
+ 29, 17, 12, 16, 15, -4, -27, -40, -39, -32, -28, -28, -24, -8, 12, 14,
+ 5, 7, 26, 40, 36, 24, 18, 21, 21, 4, -20, -38, -41, -37, -34, -30,
+ -26, -15, 4, 14, 7, 3, 18, 37, 41, 33, 24, 22, 25, 14, -10, -33,
+ -44, -42, -36, -32, -29, -22, -6, 10, 9, 2, 9, 29, 40, 37, 32, 28,
+ 29, 21, 0, -24, -39, -44, -44, -38, -31, -24, -16, 0, 7, 3, 8, 24,
+ 38, 43, 41, 32, 28, 25, 9, -15, -34, -44, -44, -39, -31, -26, -20, -10,
+ 3, 2, 1, 14, 32, 44, 46, 39, 33, 31, 20, -7, -31, -45, -47, -44,
+ -38, -30, -26, -16, 0, 5, 4, 12, 30, 45, 52, 47, 36, 30, 22, 0,
+ -24, -40, -50, -49, -42, -31, -24, -19, -10, -3, 3, 11, 24, 39, 51, 55,
+ 49, 37, 27, 8, -18, -36, -50, -54, -47, -36, -29, -25, -16, -6, 4, 10,
+ 18, 34, 52, 59, 53, 39, 28, 15, -8, -29, -45, -53, -51, -43, -34, -29,
+ -23, -14, -4, 7, 17, 33, 52, 62, 61, 50, 37, 23, -4, -28, -44, -55,
+ -55, -48, -38, -30, -25, -18, -8, 5, 13, 25, 46, 61, 65, 57, 43, 30,
+ 8, -17, -36, -50, -55, -53, -47, -39, -32, -24, -15, -3, 11, 25, 45, 62,
+ 68, 63, 51, 37, 14, -14, -34, -46, -56, -57, -51, -44, -33, -25, -18, -6,
+ 8, 19, 36, 55, 67, 65, 53, 42, 23, -4, -26, -40, -50, -56, -54, -49,
+ -41, -31, -23, -12, 1, 15, 34, 53, 65, 68, 59, 49, 33, 6, -21, -37,
+ -47, -57, -60, -56, -48, -38, -28, -16, -2, 14, 33, 51, 64, 70, 63, 53,
+ 38, 13, -14, -34, -44, -53, -59, -59, -53, -42, -30, -19, -8, 5, 26, 47,
+ 61, 68, 64, 57, 48, 26, -3, -26, -39, -49, -58, -63, -59, -49, -37, -24,
+ -13, 1, 20, 42, 55, 65, 69, 64, 54, 34, 7, -18, -34, -44, -55, -65,
+ -64, -54, -42, -31, -19, -8, 12, 37, 54, 61, 67, 67, 60, 46, 22, -8,
+ -29, -40, -50, -64, -70, -63, -50, -34, -21, -13, 2, 28, 51, 62, 68, 68,
+ 61, 51, 32, 3, -23, -36, -47, -60, -70, -67, -58, -44, -27, -14, -2, 22,
+ 45, 58, 65, 70, 68, 56, 38, 16, -11, -32, -45, -58, -69, -70, -62, -52,
+ -34, -17, -6, 13, 38, 54, 64, 70, 67, 59, 47, 29, -2, -28, -40, -51,
+ -65, -74, -67, -54, -37, -20, -11, 5, 33, 53, 59, 63, 67, 62, 51, 34,
+ 7, -20, -35, -46, -59, -72, -70, -60, -46, -27, -12, 1, 24, 47, 60, 64,
+ 69, 66, 54, 39, 15, -13, -32, -44, -54, -68, -71, -60, -48, -32, -18, -7,
+ 14, 38, 54, 61, 68, 70, 60, 46, 26, -2, -23, -38, -50, -63, -72, -68,
+ -55, -39, -24, -13, 5, 31, 52, 61, 67, 71, 64, 53, 34, 7, -21, -36,
+ -46, -57, -69, -72, -60, -42, -27, -17, -2, 21, 45, 58, 65, 69, 66, 57,
+ 42, 15, -13, -30, -43, -54, -66, -72, -65, -47, -30, -18, -5, 15, 40, 57,
+ 64, 67, 62, 56, 46, 23, -6, -27, -39, -50, -58, -67, -67, -51, -32, -20,
+ -9, 9, 31, 51, 60, 64, 64, 58, 48, 27, 1, -20, -34, -46, -56, -65,
+ -70, -57, -37, -22, -14, 2, 26, 48, 62, 66, 64, 59, 51, 34, 8, -18,
+ -31, -42, -52, -61, -70, -63, -42, -24, -15, -3, 19, 43, 60, 63, 60, 57,
+ 52, 39, 14, -14, -28, -36, -46, -54, -65, -66, -49, -29, -17, -9, 10, 33,
+ 54, 64, 62, 58, 53, 42, 23, -5, -25, -35, -46, -54, -63, -67, -54, -33,
+ -17, -7, 7, 30, 51, 61, 58, 55, 51, 43, 28, 3, -21, -30, -37, -46,
+ -56, -63, -56, -39, -22, -12, -5, 16, 40, 57, 58, 55, 53, 48, 38, 19,
+ -10, -27, -35, -45, -56, -66, -65, -49, -28, -14, -6, 8, 34, 57, 60, 55,
+ 54, 50, 42, 26, -4, -28, -35, -42, -52, -62, -63, -51, -32, -14, -5, 3,
+ 24, 47, 57, 53, 50, 47, 41, 33, 11, -20, -35, -40, -46, -56, -65, -58,
+ -38, -17, -4, 1, 15, 41, 57, 55, 47, 45, 42, 35, 17, -13, -33, -38,
+ -41, -49, -58, -55, -41, -21, -4, 0, 7, 29, 50, 52, 45, 42, 40, 37,
+ 25, 0, -28, -38, -38, -44, -53, -58, -46, -26, -6, 3, 4, 18, 42, 53,
+ 47, 41, 39, 37, 30, 10, -21, -41, -43, -41, -47, -54, -46, -29, -8, 7,
+ 9, 13, 31, 46, 45, 37, 33, 33, 28, 15, -10, -35, -42, -38, -39, -45,
+ -46, -32, -10, 6, 9, 8, 19, 38, 44, 38, 30, 29, 30, 19, -3, -29,
+ -42, -38, -34, -40, -43, -32, -14, 3, 11, 11, 15, 30, 41, 39, 30, 25,
+ 25, 19, 4, -21, -40, -42, -32, -30, -33, -29, -15, 2, 11, 10, 8, 17,
+ 30, 35, 30, 23, 24, 23, 11, -11, -32, -43, -34, -26, -29, -29, -18, -3,
+ 9, 12, 9, 12, 26, 35, 32, 21, 18, 18, 12, -6, -29, -43, -36, -22,
+ -22, -25, -15, 1, 10, 11, 10, 8, 17, 29, 29, 21, 16, 17, 15, 2,
+ -21, -39, -39, -24, -17, -20, -16, -5, 9, 13, 10, 7, 12, 24, 28, 23,
+ 14, 12, 11, 4, -14, -33, -39, -28, -15, -14, -12, -6, 5, 11, 9, 7,
+ 7, 16, 26, 25, 16, 10, 11, 6, -8, -24, -37, -32, -17, -12, -11, -5,
+ 5, 11, 11, 10, 7, 12, 21, 21, 16, 7, 4, 3, -6, -20, -32, -32,
+ -20, -8, -5, 0, 5, 11, 11, 9, 8, 8, 13, 17, 16, 9, 3, 2,
+ -3, -13, -25, -31, -23, -9, -4, -2, 5, 11, 14, 11, 7, 6, 12, 15,
+ 12, 5, -2, -2, -3, -11, -22, -29, -24, -9, 0, 3, 8, 13, 13, 12,
+ 8, 4, 5, 7, 9, 6, -3, -5, -4, -5, -14, -24, -23, -13, 0, 4,
+ 6, 10, 14, 14, 9, 3, 3, 5, 6, 4, -4, -6, -5, -5, -9, -18,
+ -20, -15, -4, 6, 9, 11, 13, 13, 10, 5, 1, 0, -3, 0, -4, -6,
+ -6, -5, -4, -11, -16, -16, -9, 3, 8, 11, 11, 10, 11, 8, 3, -2,
+ -5, -4, -3, -5, -6, -6, -2, -5, -12, -15, -13, -2, 8, 9, 11, 11,
+ 11, 7, 4, 0, -6, -6, -4, -4, -6, -6, -2, 0, -7, -13, -15, -5,
+ 8, 13, 12, 9, 11, 9, 4, -5, -11, -11, -8, -5, -5, -5, 0, 4,
+ 3, -4, -11, -8, 3, 11, 12, 8, 7, 4, 2, -2, -10, -14, -13, -7,
+ -3, -4, -2, 3, 4, 1, -8, -8, 3, 13, 17, 12, 11, 7, 1, -6,
+ -16, -21, -19, -13, -7, -2, 3, 7, 10, 10, 1, -6, -2, 8, 14, 12,
+ 10, 4, -2, -6, -15, -21, -20, -15, -8, -2, 3, 5, 9, 14, 5, -6,
+ 1, 12, 18, 14, 9, 7, 2, -4, -18, -28, -27, -22, -12, -5, 3, 9,
+ 13, 18, 16, 5, 1, 7, 14, 13, 8, 5, -5, -9, -17, -26, -26, -23,
+ -15, -4, 5, 8, 11, 17, 17, 7, 2, 7, 16, 18, 10, 4, -2, -6,
+ -16, -31, -33, -27, -18, -9, 0, 7, 12, 18, 22, 16, 9, 9, 16, 20,
+ 13, 5, -2, -9, -18, -33, -37, -29, -22, -13, -4, 7, 15, 21, 25, 21,
+ 15, 13, 17, 20, 14, 5, -3, -8, -18, -35, -42, -36, -24, -16, -6, 5,
+ 13, 23, 27, 25, 20, 17, 19, 20, 15, 5, -3, -8, -21, -35, -45, -39,
+ -25, -18, -11, 3, 16, 25, 29, 27, 26, 24, 23, 21, 17, 8, -4, -12,
+ -23, -35, -46, -46, -34, -22, -15, -3, 13, 25, 31, 33, 34, 31, 28, 25,
+ 20, 11, -4, -12, -22, -38, -49, -51, -39, -26, -21, -11, 8, 24, 34, 35,
+ 36, 37, 35, 29, 21, 13, 0, -11, -20, -36, -48, -52, -46, -31, -22, -14,
+ 1, 19, 34, 38, 39, 40, 38, 34, 24, 15, 0, -14, -21, -34, -47, -53,
+ -50, -35, -22, -17, -5, 13, 31, 37, 38, 42, 41, 37, 28, 21, 9, -8,
+ -19, -30, -44, -50, -53, -46, -32, -23, -11, 7, 26, 39, 43, 49, 48, 42,
+ 32, 20, 9, -9, -21, -31, -46, -52, -54, -50, -35, -24, -13, 4, 23, 40,
+ 46, 48, 49, 46, 37, 26, 13, -4, -20, -29, -42, -50, -53, -54, -43, -31,
+ -21, -2, 17, 36, 47, 53, 56, 51, 42, 29, 17, 3, -16, -30, -41, -51,
+ -55, -57, -51, -35, -24, -9, 11, 30, 47, 53, 57, 55, 46, 34, 20, 6,
+ -12, -29, -43, -52, -55, -55, -55, -42, -29, -12, 8, 25, 41, 55, 62, 59,
+ 51, 37, 23, 10, -6, -24, -40, -51, -56, -58, -58, -48, -33, -19, 2, 22,
+ 41, 55, 61, 61, 56, 45, 28, 11, -3, -19, -37, -51, -57, -58, -58, -54,
+ -39, -23, -2, 20, 36, 52, 64, 65, 58, 48, 33, 19, 4, -13, -35, -51,
+ -58, -61, -62, -60, -47, -29, -7, 17, 34, 50, 67, 70, 62, 50, 35, 20,
+ 6, -8, -29, -47, -57, -62, -61, -60, -54, -37, -15, 10, 29, 44, 60, 68,
+ 66, 56, 42, 24, 12, 1, -19, -41, -55, -60, -62, -61, -57, -43, -21, 7,
+ 24, 36, 53, 66, 67, 59, 46, 30, 15, 5, -11, -32, -48, -58, -63, -62,
+ -59, -50, -32, -3, 22, 35, 49, 60, 66, 63, 53, 38, 19, 8, -5, -25,
+ -43, -57, -64, -64, -62, -54, -39, -13, 16, 32, 46, 59, 65, 66, 56, 45,
+ 26, 11, 3, -17, -39, -56, -65, -67, -62, -56, -44, -21, 10, 29, 40, 54,
+ 63, 68, 61, 49, 33, 13, 2, -14, -34, -50, -64, -67, -63, -56, -44, -26,
+ 2, 27, 38, 49, 57, 64, 61, 50, 36, 17, 6, -7, -27, -44, -60, -67,
+ -63, -57, -48, -32, -7, 22, 36, 44, 53, 60, 62, 55, 41, 21, 7, -3,
+ -20, -40, -58, -68, -65, -57, -47, -34, -14, 16, 37, 42, 47, 55, 59, 53,
+ 42, 27, 10, -2, -14, -30, -47, -60, -63, -57, -49, -38, -20, 5, 30, 40,
+ 44, 52, 57, 57, 46, 31, 13, -2, -12, -27, -44, -57, -64, -61, -50, -38,
+ -20, 2, 25, 39, 41, 49, 55, 54, 45, 32, 17, 0, -12, -23, -37, -50,
+ -59, -61, -52, -38, -22, -6, 17, 35, 39, 42, 48, 53, 48, 36, 22, 4,
+ -9, -18, -30, -45, -56, -59, -54, -42, -27, -10, 12, 29, 37, 38, 44, 50,
+ 47, 37, 25, 9, -5, -13, -23, -38, -50, -55, -54, -45, -32, -17, 5, 25,
+ 34, 35, 39, 46, 48, 40, 29, 13, -3, -11, -21, -33, -44, -51, -54, -47,
+ -34, -17, 2, 21, 32, 34, 34, 38, 42, 39, 27, 15, 1, -7, -13, -25,
+ -36, -45, -49, -46, -36, -23, -6, 15, 27, 31, 31, 34, 39, 38, 30, 18,
+ 3, -6, -10, -19, -32, -40, -46, -45, -36, -24, -11, 8, 24, 29, 27, 29,
+ 34, 36, 30, 18, 4, -5, -5, -12, -25, -34, -39, -41, -37, -24, -11, 4,
+ 18, 24, 25, 25, 29, 29, 26, 19, 5, -6, -6, -6, -18, -28, -33, -37,
+ -34, -24, -11, 2, 15, 24, 23, 20, 24, 27, 22, 14, 4, -4, -4, -5,
+ -15, -24, -26, -29, -32, -27, -13, 2, 14, 21, 21, 18, 21, 23, 20, 13,
+ 5, -3, -5, -4, -9, -16, -21, -25, -28, -25, -14, 1, 10, 16, 19, 16,
+ 16, 18, 16, 11, 5, -2, -5, -4, -6, -12, -17, -20, -22, -22, -17, -4,
+ 8, 13, 16, 15, 13, 15, 14, 10, 4, -4, -6, -6, -5, -7, -11, -15,
+ -17, -17, -15, -3, 10, 13, 14, 11, 7, 8, 9, 5, -3, -8, -7, -4,
+ -2, -2, -6, -10, -9, -10, -12, -5, 11, 15, 13, 11, 5, 6, 7, 3,
+ -6, -10, -8, -6, -6, -2, 1, -2, -6, -6, -7, -5, 8, 14, 10, 7,
+ 4, 0, 1, -2, -6, -12, -11, -6, -2, 4, 8, 4, -2, -2, -4, -5,
+ 3, 12, 8, 5, 4, 0, 0, -2, -8, -13, -15, -12, -7, -3, 6, 10,
+ 7, 5, 6, 4, 6, 14, 10, 3, 0, -6, -10, -7, -10, -16, -19, -15,
+ -8, 0, 11, 17, 13, 10, 11, 7, 5, 8, 9, 2, -4, -7, -12, -10,
+ -10, -16, -21, -19, -13, -4, 10, 21, 22, 17, 17, 14, 9, 9, 9, 3,
+ -7, -12, -17, -16, -14, -20, -25, -21, -15, -5, 10, 23, 27, 25, 22, 18,
+ 11, 8, 4, -2, -9, -14, -18, -19, -14, -15, -23, -25, -20, -10, 9, 22,
+ 29, 29, 26, 23, 16, 12, 6, 1, -6, -14, -18, -22, -20, -19, -27, -28,
+ -25, -18, 0, 19, 32, 36, 33, 31, 23, 14, 7, 1, -4, -15, -23, -25,
+ -24, -19, -25, -32, -29, -20, -3, 16, 31, 40, 38, 36, 29, 16, 9, 1,
+ -4, -12, -23, -26, -28, -24, -26, -34, -33, -24, -8, 12, 29, 41, 44, 44,
+ 37, 22, 11, 4, -4, -11, -24, -31, -32, -31, -30, -36, -39, -30, -11, 11,
+ 29, 43, 51, 50, 44, 32, 15, 4, -4, -11, -24, -32, -33, -33, -34, -38,
+ -42, -35, -17, 4, 24, 42, 56, 60, 52, 38, 19, 7, 1, -13, -28, -37,
+ -37, -35, -37, -39, -43, -37, -19, 3, 22, 41, 57, 64, 57, 44, 26, 7,
+ -2, -11, -24, -35, -41, -40, -38, -39, -43, -40, -24, 0, 20, 37, 55, 65,
+ 63, 50, 32, 9, -4, -10, -24, -36, -42, -42, -41, -41, -41, -39, -26, -2,
+ 19, 34, 51, 64, 66, 55, 38, 15, -3, -8, -20, -34, -42, -44, -43, -44,
+ -45, -45, -35, -12, 14, 31, 50, 66, 73, 65, 49, 28, 7, -6, -18, -35,
+ -45, -49, -51, -53, -51, -47, -37, -16, 10, 30, 49, 69, 78, 72, 56, 35,
+ 14, -4, -17, -33, -46, -51, -55, -56, -54, -51, -40, -20, 5, 26, 44, 64,
+ 76, 77, 64, 41, 19, 1, -14, -30, -43, -50, -57, -60, -58, -54, -43, -24,
+ -2, 21, 39, 61, 76, 79, 72, 52, 28, 9, -10, -26, -41, -49, -54, -61,
+ -62, -59, -51, -33, -10, 14, 34, 55, 75, 81, 79, 63, 39, 19, -2, -23,
+ -40, -51, -56, -64, -67, -64, -56, -39, -16, 9, 29, 51, 73, 83, 82, 73,
+ 50, 27, 9, -18, -40, -52, -56, -63, -69, -69, -61, -43, -20, 2, 21, 42,
+ 66, 81, 82, 76, 59, 36, 19, -6, -33, -50, -57, -61, -71, -76, -68, -52,
+ -28, -2, 17, 36, 62, 83, 86, 82, 69, 43, 22, 2, -28, -51, -60, -63,
+ -67, -76, -74, -57, -34, -7, 14, 29, 53, 76, 87, 84, 75, 54, 33, 14,
+ -18, -46, -58, -62, -69, -80, -84, -68, -44, -18, 7, 26, 49, 75, 91, 92,
+ 82, 64, 42, 21, -8, -43, -63, -68, -68, -75, -86, -76, -48, -22, 4, 23,
+ 41, 66, 87, 92, 83, 69, 51, 31, 6, -31, -59, -67, -69, -74, -88, -87,
+ -62, -34, -7, 17, 36, 62, 87, 96, 90, 76, 60, 39, 14, -23, -58, -70,
+ -71, -73, -83, -89, -68, -37, -13, 9, 26, 51, 79, 94, 91, 80, 68, 52,
+ 28, -8, -48, -67, -70, -73, -84, -96, -83, -49, -22, 0, 20, 44, 75, 96,
+ 98, 88, 75, 61, 40, 6, -39, -67, -72, -75, -83, -95, -91, -60, -29, -7,
+ 13, 36, 66, 89, 97, 92, 78, 65, 50, 22, -21, -58, -71, -73, -78, -91,
+ -98, -79, -45, -15, 4, 25, 56, 84, 101, 99, 86, 73, 60, 35, -9, -53,
+ -72, -77, -80, -90, -98, -85, -51, -20, -2, 18, 48, 77, 96, 99, 87, 75,
+ 62, 46, 9, -39, -68, -75, -75, -83, -95, -94, -67, -30, -7, 8, 34, 68,
+ 92, 102, 93, 82, 72, 58, 26, -24, -61, -75, -78, -85, -97, -99, -78, -42,
+ -12, 6, 28, 59, 87, 102, 99, 86, 74, 62, 38, -7, -52, -76, -81, -83,
+ -93, -100, -90, -57, -23, -2, 18, 48, 80, 102, 103, 92, 81, 71, 51, 9,
+ -41, -72, -83, -85, -93, -100, -92, -65, -32, -7, 13, 39, 72, 97, 103, 95,
+ 85, 73, 55, 25, -21, -61, -79, -83, -90, -99, -97, -77, -45, -17, 1, 24,
+ 59, 93, 107, 103, 92, 85, 72, 42, -6, -54, -80, -86, -91, -104, -105, -87,
+ -56, -23, 0, 18, 48, 85, 106, 106, 96, 87, 77, 52, 13, -35, -71, -84,
+ -88, -98, -106, -96, -70, -40, -14, 6, 31, 70, 103, 111, 103, 95, 88, 68,
+ 29, -19, -61, -84, -91, -99, -106, -101, -80, -51, -22, 2, 23, 56, 91, 109,
+ 108, 98, 89, 76, 45, 1, -44, -76, -87, -92, -102, -104, -90, -64, -34, -11,
+ 8, 37, 78, 108, 113, 106, 96, 85, 61, 19, -29, -68, -88, -94, -102, -104,
+ -93, -73, -46, -21, 2, 28, 63, 98, 113, 109, 100, 89, 70, 33, -14, -55,
+ -81, -91, -98, -104, -98, -79, -54, -30, -9, 18, 52, 89, 108, 110, 104, 96,
+ 79, 46, 2, -40, -71, -90, -100, -104, -100, -86, -67, -44, -19, 7, 40, 77,
+ 105, 115, 109, 99, 86, 58, 17, -29, -63, -86, -97, -101, -101, -92, -74, -50,
+ -26, -4, 28, 66, 98, 114, 113, 102, 90, 68, 33, -15, -53, -76, -93, -101,
+ -104, -96, -79, -57, -34, -15, 15, 56, 90, 110, 115, 105, 93, 75, 44, 0,
+ -43, -68, -86, -98, -101, -98, -83, -65, -42, -22, 4, 41, 79, 104, 113, 107,
+ 96, 81, 57, 16, -31, -59, -79, -95, -101, -100, -90, -71, -49, -30, -9, 28,
+ 67, 97, 110, 107, 97, 86, 65, 30, -14, -47, -67, -84, -98, -102, -96, -79,
+ -59, -41, -22, 14, 53, 90, 110, 111, 101, 90, 75, 45, 2, -39, -64, -79,
+ -93, -102, -101, -87, -64, -44, -28, 0, 39, 81, 108, 110, 102, 93, 82, 58,
+ 18, -25, -54, -70, -85, -101, -103, -94, -72, -53, -39, -14, 25, 70, 104, 112,
+ 103, 96, 88, 70, 34, -13, -48, -65, -78, -97, -108, -101, -79, -55, -42, -24,
+ 11, 56, 96, 111, 103, 94, 90, 77, 46, 5, -34, -56, -71, -92, -109, -109,
+ -91, -64, -46, -30, 0, 44, 89, 112, 108, 95, 88, 80, 57, 16, -27, -54,
+ -66, -82, -104, -112, -100, -71, -46, -34, -13, 29, 80, 111, 112, 97, 86, 84,
+ 69, 32, -15, -48, -61, -72, -94, -109, -106, -82, -54, -37, -23, 11, 61, 101,
+ 113, 101, 85, 80, 75, 48, 4, -37, -56, -64, -84, -107, -112, -90, -60, -37,
+ -29, -7, 43, 91, 111, 103, 86, 80, 77, 58, 20, -24, -52, -61, -75, -100,
+ -111, -99, -72, -44, -27, -12, 29, 77, 105, 106, 91, 80, 75, 64, 33, -9,
+ -43, -58, -69, -94, -111, -104, -78, -49, -28, -18, 11, 62, 97, 107, 94, 80,
+ 75, 69, 47, 6, -36, -55, -62, -81, -105, -108, -87, -59, -33, -18, 1, 46,
+ 86, 103, 97, 83, 75, 69, 52, 19, -23, -50, -59, -74, -97, -106, -91, -64,
+ -38, -21, -9, 26, 70, 95, 95, 80, 71, 69, 60, 35, -6, -40, -53, -64,
+ -87, -102, -96, -72, -45, -25, -14, 13, 56, 87, 95, 86, 75, 69, 60, 41,
+ 6, -32, -54, -62, -77, -95, -99, -79, -51, -23, -8, 6, 39, 75, 92, 87,
+ 72, 64, 62, 49, 21, -17, -47, -57, -67, -86, -97, -87, -59, -32, -16, -4,
+ 25, 63, 89, 92, 78, 67, 63, 53, 27, -10, -40, -55, -63, -78, -93, -89,
+ -65, -36, -17, -7, 11, 44, 77, 89, 79, 65, 61, 58, 41, 8, -26, -50,
+ -59, -67, -83, -90, -76, -47, -25, -13, 3, 30, 63, 85, 82, 70, 63, 58,
+ 45, 14, -18, -43, -56, -63, -74, -84, -78, -52, -26, -13, -2, 19, 46, 73,
+ 81, 68, 57, 55, 49, 27, -5, -32, -48, -54, -63, -77, -80, -60, -34, -17,
+ -5, 10, 34, 62, 79, 71, 57, 52, 48, 31, 2, -26, -45, -50, -53, -65,
+ -75, -63, -37, -16, -6, 4, 19, 45, 68, 70, 57, 49, 49, 39, 16, -11,
+ -33, -45, -49, -56, -70, -71, -51, -26, -8, 2, 13, 35, 63, 76, 63, 48,
+ 43, 38, 23, -7, -32, -45, -47, -47, -58, -67, -55, -30, -8, 0, 4, 20,
+ 46, 68, 65, 47, 38, 38, 31, 8, -19, -37, -44, -42, -48, -63, -62, -41,
+ -16, -2, 5, 16, 37, 61, 68, 53, 38, 34, 31, 14, -14, -33, -40, -38,
+ -41, -54, -60, -46, -20, -5, -3, 6, 25, 49, 63, 55, 38, 32, 33, 24,
+ 1, -23, -34, -35, -36, -45, -59, -55, -30, -9, -3, 2, 16, 39, 59, 59,
+ 44, 32, 30, 26, 7, -20, -33, -33, -32, -40, -53, -54, -35, -12, -3, -2,
+ 10, 29, 48, 55, 45, 32, 28, 27, 14, -10, -27, -30, -28, -34, -46, -53,
+ -41, -17, -5, -5, 5, 24, 44, 54, 46, 32, 25, 25, 18, -4, -25, -31,
+ -24, -27, -39, -47, -42, -21, -4, -2, 1, 15, 35, 46, 44, 31, 22, 23,
+ 20, 6, -15, -26, -23, -20, -29, -41, -42, -29, -11, -4, -4, 7, 26, 42,
+ 47, 37, 25, 21, 19, 9, -10, -25, -25, -18, -24, -38, -40, -29, -11, 1,
+ 0, 3, 19, 34, 42, 33, 19, 14, 15, 10, -5, -21, -24, -15, -13, -26,
+ -35, -31, -17, -2, 0, -2, 11, 26, 37, 34, 20, 14, 13, 12, 2, -17,
+ -25, -17, -12, -21, -31, -30, -19, -4, 4, 1, 9, 22, 32, 32, 19, 9,
+ 9, 10, 4, -11, -21, -16, -9, -14, -23, -26, -20, -8, 0, -2, 3, 15,
+ 26, 31, 24, 12, 9, 10, 6, -5, -17, -19, -12, -11, -18, -25, -22, -10,
+ 1, 2, 2, 11, 22, 29, 24, 10, 3, 5, 4, -4, -13, -15, -8, -5,
+ -10, -16, -18, -14, -5, -2, 0, 6, 13, 20, 23, 16, 6, 5, 5, 0,
+ -7, -12, -12, -8, -7, -12, -19, -18, -7, 0, 2, 7, 13, 18, 20, 13,
+ 3, -2, 1, -2, -6, -8, -6, -3, -2, -2, -10, -14, -10, -6, -4, 0,
+ 4, 9, 14, 15, 6, -2, -2, -2, -4, -4, -5, -3, 2, 3, -3, -10,
+ -9, -5, 0, 0, 0, 3, 8, 10, 3, -5, -7, -6, -4, 0, -2, -2,
+ 3, 7, 7, 2, -5, -6, -3, 2, 2, 0, 0, 2, 2, -4, -9, -9,
+ -7, -3, 2, 4, 8, 9, 6, 2, -3, -4, -3, -2, -2, -2, 0, 1,
+ -3, -8, -11, -8, -6, -4, 2, 6, 9, 10, 9, 8, 5, -4, -7, -3,
+ 1, 1, -6, -7, -6, -6, -11, -14, -10, -5, 3, 9, 12, 14, 13, 10,
+ 9, 1, -6, -5, -4, -3, -4, -6, -8, -12, -12, -13, -13, -11, -3, 9,
+ 16, 18, 15, 13, 14, 11, -2, -6, -4, -3, -5, -11, -13, -12, -14, -15,
+ -14, -10, -4, 6, 15, 22, 21, 16, 13, 12, 3, -7, -8, -7, -7, -10,
+ -14, -17, -16, -13, -12, -10, -7, 3, 15, 24, 26, 19, 16, 18, 12, -3,
+ -9, -10, -9, -11, -18, -22, -21, -17, -14, -14, -10, 0, 14, 26, 32, 28,
+ 23, 22, 21, 5, -9, -12, -16, -18, -22, -27, -27, -23, -17, -13, -8, 2,
+ 12, 25, 35, 36, 29, 21, 20, 11, -6, -14, -17, -19, -22, -27, -28, -24,
+ -20, -15, -11, -4, 7, 19, 32, 39, 35, 28, 25, 19, 4, -10, -17, -24,
+ -28, -31, -33, -30, -26, -19, -11, -3, 8, 19, 31, 42, 42, 34, 27, 21,
+ 9, -9, -19, -26, -31, -35, -34, -30, -26, -23, -13, -4, 4, 14, 25, 42,
+ 49, 41, 31, 27, 20, 3, -15, -28, -37, -38, -39, -38, -35, -29, -16, 0,
+ 9, 17, 26, 41, 52, 48, 36, 26, 19, 6, -16, -30, -39, -43, -41, -39,
+ -33, -29, -22, -5, 7, 13, 21, 36, 55, 56, 46, 34, 24, 15, -8, -29,
+ -44, -54, -50, -44, -39, -35, -27, -7, 11, 20, 25, 34, 54, 63, 53, 38,
+ 22, 14, 0, -27, -45, -56, -56, -46, -39, -36, -31, -14, 8, 19, 23, 29,
+ 46, 63, 61, 47, 30, 20, 8, -15, -39, -56, -62, -54, -44, -41, -38, -23,
+ -2, 16, 23, 28, 42, 63, 69, 58, 41, 25, 13, -7, -34, -56, -68, -64,
+ -50, -45, -43, -29, -7, 15, 26, 29, 40, 58, 72, 67, 48, 30, 16, 0,
+ -26, -53, -68, -69, -57, -47, -46, -36, -16, 9, 25, 30, 38, 53, 71, 74,
+ 58, 37, 17, 2, -21, -49, -70, -76, -64, -49, -43, -38, -21, 3, 25, 33,
+ 37, 49, 65, 74, 65, 45, 24, 8, -11, -40, -68, -79, -72, -57, -48, -42,
+ -29, -6, 20, 34, 39, 48, 63, 77, 74, 56, 31, 11, -8, -33, -61, -79,
+ -80, -68, -53, -45, -34, -16, 11, 31, 41, 51, 61, 75, 78, 64, 42, 19,
+ -3, -27, -55, -78, -84, -73, -59, -48, -37, -20, 5, 27, 40, 49, 58, 71,
+ 80, 71, 49, 23, 2, -20, -47, -72, -86, -82, -66, -52, -39, -26, -5, 20,
+ 39, 51, 59, 69, 79, 77, 61, 34, 7, -16, -42, -68, -88, -90, -75, -58,
+ -41, -26, -8, 17, 39, 52, 59, 65, 74, 77, 65, 41, 12, -12, -35, -60,
+ -81, -89, -79, -60, -45, -33, -17, 6, 31, 49, 59, 64, 73, 80, 74, 51,
+ 22, -5, -29, -54, -78, -92, -90, -70, -49, -35, -18, 3, 26, 48, 60, 64,
+ 68, 75, 75, 58, 31, 1, -25, -48, -73, -88, -90, -77, -56, -41, -23, -3,
+ 21, 43, 58, 64, 70, 75, 77, 64, 40, 12, -18, -44, -70, -87, -94, -87,
+ -64, -42, -22, -4, 16, 39, 58, 65, 66, 67, 74, 68, 46, 18, -12, -38,
+ -62, -82, -92, -89, -67, -45, -28, -9, 13, 31, 52, 64, 67, 66, 72, 71,
+ 53, 29, -3, -34, -59, -79, -94, -96, -77, -50, -29, -8, 12, 30, 49, 63,
+ 68, 67, 68, 70, 56, 34, 6, -29, -57, -77, -92, -99, -84, -56, -32, -10,
+ 11, 29, 45, 61, 69, 69, 68, 70, 60, 37, 12, -20, -50, -73, -90, -100,
+ -91, -64, -37, -14, 7, 25, 42, 57, 66, 67, 65, 67, 64, 45, 21, -9,
+ -41, -66, -84, -98, -95, -74, -47, -21, 3, 23, 39, 54, 64, 69, 69, 67,
+ 63, 50, 27, 0, -33, -63, -83, -94, -95, -79, -54, -26, -2, 18, 35, 49,
+ 61, 67, 67, 65, 64, 55, 33, 6, -25, -55, -82, -95, -98, -84, -60, -32,
+ -6, 17, 36, 48, 56, 64, 66, 65, 62, 55, 39, 14, -16, -46, -76, -92,
+ -96, -88, -69, -41, -9, 15, 33, 46, 54, 62, 68, 66, 59, 54, 44, 20,
+ -12, -41, -72, -92, -97, -90, -71, -46, -14, 15, 34, 48, 55, 59, 62, 63,
+ 60, 51, 42, 24, -6, -34, -63, -87, -95, -89, -75, -52, -23, 10, 31, 45,
+ 54, 58, 62, 66, 63, 51, 42, 30, 1, -32, -59, -84, -96, -93, -80, -58,
+ -28, 7, 32, 45, 53, 60, 64, 67, 62, 52, 41, 31, 9, -25, -55, -78,
+ -92, -91, -82, -65, -39, -2, 30, 43, 49, 56, 61, 65, 63, 54, 44, 33,
+ 16, -15, -47, -72, -88, -91, -84, -70, -45, -12, 22, 42, 48, 54, 58, 61,
+ 63, 56, 43, 32, 20, -4, -36, -65, -82, -87, -82, -72, -53, -23, 15, 40,
+ 46, 48, 55, 61, 62, 55, 43, 32, 21, 4, -26, -57, -75, -82, -80, -73,
+ -58, -30, 5, 35, 46, 47, 51, 57, 61, 57, 46, 34, 22, 9, -15, -47,
+ -71, -81, -80, -75, -62, -36, -4, 28, 46, 47, 49, 56, 60, 57, 48, 35,
+ 23, 12, -9, -39, -67, -78, -76, -71, -65, -45, -13, 21, 45, 50, 46, 50,
+ 58, 59, 49, 35, 23, 12, -4, -31, -62, -78, -74, -70, -65, -49, -18, 18,
+ 43, 51, 45, 48, 56, 56, 45, 30, 20, 12, 0, -24, -53, -71, -69, -63,
+ -60, -51, -25, 9, 36, 50, 47, 44, 50, 52, 45, 32, 21, 12, 1, -18,
+ -44, -66, -70, -64, -59, -51, -31, 2, 32, 50, 51, 46, 47, 52, 47, 32,
+ 17, 9, 0, -14, -34, -57, -67, -62, -56, -50, -33, -6, 24, 44, 51, 48,
+ 47, 48, 46, 34, 21, 12, 2, -13, -32, -51, -62, -62, -56, -51, -38, -13,
+ 18, 40, 51, 50, 45, 47, 46, 36, 20, 9, -2, -14, -28, -45, -59, -61,
+ -54, -48, -37, -15, 14, 36, 49, 52, 48, 44, 42, 33, 19, 10, 0, -13,
+ -26, -39, -52, -58, -54, -47, -37, -19, 9, 30, 44, 52, 48, 40, 38, 31,
+ 19, 7, -3, -12, -22, -31, -42, -51, -49, -43, -36, -22, 1, 22, 35, 45,
+ 47, 41, 37, 31, 23, 13, 3, -11, -22, -28, -36, -48, -53, -46, -35, -23,
+ -4, 17, 31, 45, 49, 41, 33, 29, 23, 13, 2, -11, -22, -26, -29, -38,
+ -46, -45, -34, -21, -6, 14, 25, 38, 46, 43, 35, 27, 19, 10, 3, -7,
+ -20, -28, -28, -32, -38, -41, -35, -23, -8, 10, 23, 33, 44, 44, 36, 27,
+ 18, 10, 0, -9, -22, -28, -28, -28, -33, -37, -32, -21, -7, 8, 20, 28,
+ 38, 41, 36, 27, 17, 8, -2, -6, -17, -28, -31, -28, -27, -30, -30, -22,
+ -7, 9, 19, 26, 35, 41, 37, 26, 16, 6, -5, -11, -18, -28, -31, -28,
+ -22, -23, -23, -18, -4, 11, 19, 24, 27, 33, 33, 24, 14, 3, -8, -11,
+ -15, -23, -29, -29, -21, -18, -19, -15, -5, 9, 16, 21, 26, 30, 32, 25,
+ 13, 2, -9, -13, -16, -21, -27, -27, -20, -12, -13, -14, -7, 9, 17, 20,
+ 24, 25, 26, 27, 15, 2, -9, -17, -17, -20, -25, -28, -23, -11, -6, -8,
+ -5, 7, 19, 23, 24, 24, 24, 25, 16, 0, -13, -22, -22, -22, -26, -28,
+ -22, -8, 2, 1, 0, 8, 18, 24, 24, 20, 18, 20, 15, 1, -12, -22,
+ -24, -22, -23, -25, -22, -13, 2, 7, 3, 8, 16, 25, 28, 21, 15, 15,
+ 15, 4, -13, -25, -29, -24, -20, -24, -21, -12, 1, 12, 10, 9, 16, 23,
+ 27, 21, 14, 12, 10, 3, -10, -21, -28, -27, -22, -22, -20, -14, -4, 10,
+ 14, 11, 17, 23, 29, 26, 15, 11, 10, 4, -12, -25, -33, -33, -26, -23,
+ -22, -12, 0, 13, 22, 19, 20, 25, 29, 25, 12, 5, 3, 0, -12, -25,
+ -32, -34, -27, -21, -20, -11, -2, 7, 18, 21, 22, 26, 30, 29, 21, 11,
+ 4, -5, -14, -29, -38, -38, -33, -27, -23, -10, 4, 12, 22, 29, 30, 30,
+ 31, 30, 21, 10, 0, -11, -19, -30, -39, -40, -36, -28, -20, -9, 4, 12,
+ 20, 29, 32, 30, 32, 32, 23, 12, 3, -8, -18, -27, -39, -44, -40, -32,
+ -25, -15, 1, 13, 22, 30, 37, 38, 36, 34, 26, 14, 2, -11, -22, -31,
+ -40, -45, -42, -35, -26, -14, 0, 12, 19, 26, 35, 39, 36, 33, 28, 18,
+ 6, -7, -18, -28, -37, -43, -43, -37, -30, -19, -6, 8, 20, 25, 34, 42,
+ 41, 37, 32, 22, 8, -7, -19, -32, -40, -44, -44, -38, -30, -20, -6, 8,
+ 19, 24, 30, 40, 41, 36, 29, 23, 13, -3, -16, -28, -39, -43, -44, -41,
+ -34, -23, -11, 2, 16, 25, 32, 41, 46, 42, 34, 26, 15, 0, -16, -29,
+ -40, -45, -45, -40, -32, -24, -12, -2, 12, 22, 26, 37, 45, 44, 34, 24,
+ 18, 6, -12, -24, -37, -41, -40, -40, -36, -30, -17, -4, 9, 18, 25, 37,
+ 45, 45, 40, 29, 19, 8, -8, -22, -38, -43, -42, -42, -35, -28, -17, -4,
+ 7, 17, 23, 33, 43, 43, 38, 28, 19, 12, -3, -19, -34, -40, -38, -40,
+ -38, -31, -22, -8, 5, 14, 21, 31, 44, 47, 41, 31, 20, 13, 3, -15,
+ -33, -45, -45, -41, -38, -31, -24, -10, 4, 15, 21, 29, 42, 47, 41, 33,
+ 22, 13, 4, -13, -29, -40, -41, -41, -41, -36, -26, -14, -2, 8, 17, 29,
+ 42, 50, 46, 37, 27, 17, 7, -9, -27, -41, -48, -45, -42, -38, -29, -15,
+ -2, 10, 18, 26, 38, 50, 51, 40, 28, 17, 6, -7, -24, -36, -43, -45,
+ -41, -38, -31, -18, -8, 2, 13, 26, 38, 44, 49, 42, 33, 22, 8, -4,
+ -20, -32, -41, -46, -44, -37, -32, -21, -8, 2, 14, 25, 35, 42, 47, 44,
+ 31, 19, 7, -4, -15, -28, -36, -42, -40, -34, -31, -24, -9, 0, 7, 18,
+ 30, 40, 44, 42, 32, 22, 12, 2, -10, -23, -31, -38, -42, -38, -31, -26,
+ -13, -3, 2, 14, 29, 40, 41, 40, 36, 26, 13, 1, -10, -19, -26, -35,
+ -43, -41, -33, -27, -17, -6, 1, 12, 27, 43, 47, 42, 37, 29, 14, 0,
+ -10, -21, -29, -34, -40, -42, -33, -26, -18, -5, 3, 10, 23, 39, 45, 39,
+ 33, 30, 18, 3, -8, -15, -22, -29, -37, -43, -36, -27, -22, -13, -4, 6,
+ 19, 36, 47, 47, 37, 33, 25, 6, -8, -15, -25, -31, -36, -43, -42, -32,
+ -21, -11, 0, 5, 15, 32, 46, 45, 35, 31, 28, 12, -6, -13, -20, -24,
+ -31, -41, -46, -38, -26, -18, -9, 1, 14, 31, 43, 48, 42, 33, 28, 15,
+ -5, -15, -18, -24, -31, -38, -41, -34, -26, -19, -8, 1, 10, 23, 37, 43,
+ 41, 32, 26, 19, 3, -12, -15, -18, -24, -34, -42, -38, -28, -20, -13, -4,
+ 6, 21, 37, 44, 43, 36, 28, 21, 8, -9, -16, -19, -25, -34, -42, -39,
+ -29, -21, -13, -3, 8, 19, 34, 42, 41, 36, 28, 20, 8, -7, -15, -16,
+ -19, -30, -41, -42, -31, -23, -15, -8, 3, 19, 36, 43, 39, 36, 30, 23,
+ 13, -6, -19, -21, -20, -26, -38, -43, -35, -25, -15, -7, 3, 14, 30, 42,
+ 40, 35, 28, 23, 16, 0, -14, -20, -19, -22, -34, -42, -37, -26, -15, -8,
+ 0, 12, 27, 40, 41, 35, 29, 22, 16, 4, -9, -19, -20, -20, -29, -39,
+ -39, -30, -19, -10, -3, 10, 24, 37, 42, 37, 31, 25, 18, 7, -7, -17,
+ -21, -20, -28, -38, -40, -33, -22, -11, -5, 9, 25, 37, 44, 40, 32, 24,
+ 17, 10, -5, -18, -24, -23, -28, -35, -38, -35, -26, -14, -5, 5, 19, 34,
+ 44, 42, 33, 23, 18, 13, 0, -15, -20, -22, -26, -33, -39, -35, -28, -18,
+ -10, 1, 18, 33, 43, 45, 38, 28, 20, 11, 2, -12, -22, -24, -28, -31,
+ -36, -35, -29, -21, -11, 0, 15, 30, 40, 44, 39, 31, 21, 13, 8, -5,
+ -17, -20, -25, -28, -32, -36, -34, -27, -18, -7, 9, 26, 39, 46, 45, 36,
+ 25, 14, 10, -2, -16, -24, -29, -31, -31, -36, -36, -27, -16, -7, 6, 23,
+ 37, 45, 44, 36, 26, 14, 8, 1, -14, -22, -23, -29, -32, -35, -36, -29,
+ -21, -14, 0, 16, 35, 46, 45, 39, 33, 20, 8, 3, -9, -21, -28, -32,
+ -34, -35, -36, -32, -25, -15, 1, 17, 32, 45, 49, 44, 35, 23, 7, 0,
+ -7, -17, -25, -30, -31, -32, -34, -31, -25, -18, -7, 10, 27, 43, 50, 45,
+ 35, 24, 13, 3, -7, -17, -24, -28, -30, -30, -33, -34, -26, -19, -11, 5,
+ 22, 39, 50, 48, 37, 26, 16, 5, -7, -18, -23, -27, -28, -28, -33, -34,
+ -24, -16, -11, 2, 17, 33, 48, 48, 37, 27, 18, 7, -5, -14, -20, -25,
+ -30, -31, -32, -37, -31, -20, -15, -3, 15, 30, 46, 53, 43, 31, 20, 11,
+ 0, -12, -21, -27, -31, -30, -30, -36, -33, -20, -10, -5, 9, 25, 41, 52,
+ 46, 34, 23, 15, 6, -9, -21, -27, -30, -31, -31, -37, -39, -25, -12, -7,
+ 1, 18, 36, 52, 53, 40, 28, 22, 13, -2, -18, -29, -32, -35, -34, -39,
+ -40, -28, -13, -7, -2, 12, 33, 50, 56, 44, 30, 24, 18, 4, -15, -29,
+ -32, -33, -33, -35, -40, -35, -20, -7, -2, 8, 25, 43, 54, 49, 35, 25,
+ 18, 8, -7, -23, -32, -32, -34, -34, -37, -36, -24, -11, -5, 2, 18, 36,
+ 51, 51, 39, 30, 24, 14, 0, -19, -32, -35, -35, -37, -38, -39, -29, -12,
+ -2, 3, 14, 29, 47, 54, 45, 33, 26, 17, 5, -12, -31, -37, -36, -38,
+ -38, -38, -32, -17, -3, 3, 9, 25, 42, 53, 49, 39, 31, 23, 10, -9,
+ -27, -38, -40, -41, -41, -41, -36, -23, -5, 5, 8, 18, 36, 51, 51, 43,
+ 34, 26, 16, 1, -20, -36, -40, -41, -42, -40, -38, -28, -10, 4, 7, 14,
+ 30, 48, 51, 45, 39, 31, 21, 4, -16, -33, -41, -43, -43, -39, -38, -32,
+ -15, 1, 7, 13, 25, 42, 52, 48, 39, 31, 22, 9, -10, -29, -40, -40,
+ -40, -38, -35, -34, -20, -2, 5, 9, 17, 33, 49, 50, 43, 34, 25, 13,
+ -4, -21, -36, -44, -44, -40, -35, -34, -26, -8, 5, 11, 17, 26, 43, 51,
+ 46, 36, 27, 16, 1, -16, -31, -42, -46, -43, -37, -35, -29, -12, 3, 11,
+ 17, 23, 37, 50, 52, 41, 29, 20, 4, -15, -30, -43, -49, -46, -39, -37,
+ -33, -15, 3, 13, 19, 23, 35, 52, 55, 44, 29, 20, 8, -12, -28, -40,
+ -48, -45, -39, -35, -32, -20, -2, 12, 16, 19, 28, 45, 55, 49, 35, 24,
+ 14, -3, -20, -36, -49, -53, -45, -38, -35, -27, -9, 8, 19, 23, 26, 40,
+ 55, 55, 41, 25, 15, -2, -19, -33, -46, -53, -47, -39, -35, -29, -14, 6,
+ 19, 24, 25, 35, 53, 59, 47, 29, 17, 7, -12, -30, -47, -58, -56, -47,
+ -39, -35, -22, -2, 17, 28, 30, 34, 50, 63, 56, 35, 19, 8, -9, -26,
+ -43, -56, -58, -49, -42, -38, -27, -9, 12, 26, 33, 34, 44, 60, 62, 44,
+ 23, 9, -4, -20, -40, -56, -63, -56, -44, -39, -30, -14, 8, 26, 35, 35,
+ 43, 60, 64, 50, 28, 13, 2, -16, -37, -53, -62, -61, -50, -42, -32, -17,
+ 2, 18, 32, 40, 44, 54, 63, 55, 37, 17, 4, -10, -31, -48, -61, -67,
+ -59, -45, -36, -24, -5, 17, 33, 43, 47, 54, 64, 59, 42, 20, 3, -10,
+ -28, -49, -63, -68, -63, -50, -37, -25, -7, 13, 31, 44, 48, 54, 61, 59,
+ 48, 27, 6, -10, -24, -43, -59, -67, -67, -56, -39, -28, -13, 8, 24, 42,
+ 51, 54, 58, 58, 52, 37, 14, -6, -20, -38, -54, -65, -70, -63, -45, -29,
+ -17, 2, 18, 37, 52, 56, 58, 56, 51, 42, 23, -2, -19, -34, -50, -62,
+ -70, -69, -52, -30, -17, -3, 15, 33, 50, 58, 58, 56, 52, 46, 29, 3,
+ -15, -31, -45, -58, -68, -71, -60, -38, -20, -5, 11, 25, 42, 58, 62, 58,
+ 51, 44, 36, 15, -10, -29, -43, -53, -64, -72, -67, -45, -21, -8, 4, 20,
+ 40, 60, 65, 57, 53, 48, 42, 21, -8, -27, -40, -50, -62, -71, -71, -54,
+ -29, -9, 3, 18, 34, 54, 68, 65, 57, 48, 40, 28, 2, -23, -41, -52,
+ -60, -71, -75, -60, -34, -12, 0, 13, 31, 52, 69, 66, 56, 50, 44, 33,
+ 7, -21, -38, -47, -55, -65, -75, -67, -41, -15, 2, 11, 23, 41, 61, 68,
+ 59, 49, 40, 34, 17, -11, -35, -47, -48, -55, -69, -72, -50, -21, 0, 8,
+ 15, 33, 56, 69, 62, 52, 44, 40, 26, -4, -30, -44, -48, -56, -69, -77,
+ -59, -28, -7, 7, 15, 30, 52, 68, 66, 55, 45, 38, 30, 6, -24, -43,
+ -49, -52, -64, -75, -65, -35, -10, 4, 11, 25, 45, 65, 67, 55, 48, 43,
+ 34, 13, -18, -39, -45, -49, -61, -75, -72, -45, -17, -2, 9, 20, 39, 61,
+ 70, 62, 52, 45, 36, 18, -9, -34, -47, -52, -58, -69, -72, -52, -23, -5,
+ 7, 17, 35, 54, 65, 63, 55, 45, 37, 23, 0, -27, -45, -49, -53, -63,
+ -71, -59, -31, -8, 7, 15, 28, 47, 61, 65, 58, 47, 38, 27, 6, -21,
+ -41, -49, -53, -62, -69, -62, -39, -14, 3, 14, 28, 46, 59, 64, 62, 51,
+ 39, 29, 11, -16, -40, -52, -55, -58, -65, -65, -47, -20, 1, 14, 24, 39,
+ 52, 59, 64, 56, 43, 33, 16, -8, -32, -49, -55, -58, -63, -65, -54, -29,
+ -3, 12, 21, 36, 51, 60, 65, 59, 46, 35, 21, -4, -28, -48, -56, -57,
+ -59, -60, -55, -37, -12, 9, 19, 32, 46, 54, 58, 58, 48, 36, 26, 7,
+ -18, -41, -53, -53, -52, -57, -58, -45, -19, 6, 15, 26, 42, 54, 59, 59,
+ 52, 39, 28, 10, -16, -40, -56, -56, -52, -51, -53, -45, -22, 4, 17, 24,
+ 35, 46, 56, 57, 52, 40, 30, 18, -7, -33, -54, -58, -52, -49, -53, -51,
+ -33, -5, 17, 26, 34, 43, 54, 58, 53, 42, 31, 19, 0, -24, -47, -60,
+ -55, -46, -46, -50, -39, -13, 13, 25, 32, 38, 48, 56, 52, 41, 30, 20,
+ 7, -15, -41, -58, -55, -44, -41, -44, -40, -19, 10, 25, 28, 32, 41, 53,
+ 52, 42, 31, 21, 13, -5, -32, -55, -60, -47, -36, -38, -40, -26, 2, 24,
+ 29, 28, 32, 46, 48, 40, 29, 21, 14, 1, -23, -48, -56, -46, -34, -33,
+ -36, -29, -7, 20, 28, 25, 26, 37, 46, 42, 30, 19, 15, 7, -13, -39,
+ -58, -54, -37, -27, -27, -29, -17, 13, 29, 28, 24, 31, 42, 42, 34, 21,
+ 11, 5, -10, -32, -51, -52, -40, -28, -24, -24, -18, 6, 27, 30, 26, 28,
+ 36, 38, 33, 22, 11, 6, -7, -26, -44, -49, -42, -30, -21, -17, -16, -5,
+ 18, 29, 26, 25, 29, 33, 33, 25, 13, 7, 0, -18, -36, -46, -45, -31,
+ -20, -16, -16, -9, 12, 28, 29, 24, 25, 29, 31, 26, 13, 2, -5, -15,
+ -26, -39, -46, -37, -19, -9, -9, -11, 1, 21, 31, 26, 21, 23, 26, 25,
+ 15, 4, -4, -10, -20, -32, -41, -38, -22, -10, -7, -9, -6, 11, 26, 29,
+ 22, 20, 21, 24, 19, 7, -6, -12, -17, -23, -30, -36, -27, -12, -3, 0,
+ -5, 3, 18, 28, 25, 18, 15, 16, 15, 7, -4, -10, -14, -19, -24, -30,
+ -26, -13, -3, 2, -3, -2, 12, 23, 26, 18, 13, 13, 14, 9, 0, -11,
+ -14, -15, -18, -24, -26, -16, -4, 4, 0, -5, 6, 17, 25, 21, 11, 7,
+ 8, 8, 1, -11, -14, -11, -10, -13, -20, -18, -7, 5, 7, -3, -2, 8,
+ 21, 23, 12, 4, 4, 8, 7, -5, -15, -14, -11, -9, -15, -20, -13, 1,
+ 8, 3, 0, 6, 17, 24, 16, 3, -2, 1, 0, -10, -17, -14, -8, -4,
+ -5, -11, -12, 0, 9, 6, -3, 1, 10, 18, 16, 5, -3, 0, 3, -4,
+ -13, -15, -10, -6, -4, -8, -13, -8, 5, 8, 5, 3, 9, 17, 18, 13,
+ 0, -7, -5, -5, -11, -14, -11, -6, 2, 2, -6, -9, 1, 8, 5, -2,
+ 1, 8, 14, 12, 2, -6, -5, -2, -6, -12, -10, -2, 3, 4, -5, -11,
+ -6, 5, 6, 0, 0, 7, 12, 14, 6, -7, -8, -6, -6, -9, -10, -5,
+ 4, 8, 4, -7, -11, -2, 6, 3, -2, 2, 9, 15, 12, -2, -8, -6,
+ -3, -5, -11, -9, 2, 10, 7, -5, -15, -10, 4, 6, -2, -2, 8, 14,
+ 14, 3, -9, -8, -5, -4, -8, -10, 0, 8, 9, 3, -9, -12, -3, 6,
+ 3, -3, 1, 8, 13, 5, -9, -13, -7, -2, -2, -6, -2, 9, 13, 6,
+ -6, -13, -10, 2, 4, -3, -2, 7, 13, 9, -6, -12, -11, -6, 0, -5,
+ -5, 7, 15, 13, 1, -10, -13, -4, 5, -2, -7, -2, 9, 9, -3, -11,
+ -11, -8, 2, 1, -3, 7, 15, 12, 4, -7, -13, -11, -2, 1, -4, -3,
+ 7, 11, 3, -8, -11, -10, 0, 1, -5, 2, 12, 17, 11, -2, -11, -11,
+ -3, 4, -4, -9, 1, 10, 3, -9, -11, -8, 0, 5, 1, 2, 11, 14,
+ 9, 1, -11, -15, -11, -3, 1, -3, 3, 12, 11, 1, -7, -9, -6, -3,
+ -5, -5, 5, 12, 9, 4, -3, -8, -8, -5, 0, -4, -3, 5, 6, -3,
+ -10, -7, -3, 0, 2, 3, 10, 14, 11, 4, -3, -11, -15, -15, -9, -5,
+ -5, 5, 13, 5, -2, 0, 2, 4, 1, -3, 4, 12, 11, 2, -5, -10,
+ -13, -13, -11, -6, -4, 3, 13, 9, 1, -2, 4, 5, 1, -5, 3, 12,
+ 13, 4, -9, -12, -14, -16, -17, -12, -5, 5, 16, 17, 6, 3, 9, 9,
+ 2, -8, -7, 2, 7, 4, -8, -12, -10, -13, -14, -13, -6, 4, 13, 19,
+ 10, 0, 6, 14, 8, -6, -9, 0, 7, 5, -8, -17, -13, -9, -14, -18,
+ -13, 2, 15, 23, 16, 4, 5, 16, 15, 0, -10, -6, 3, 6, -4, -15,
+ -15, -10, -11, -16, -16, -5, 10, 21, 18, 7, 2, 12, 18, 6, -7, -9,
+ 1, 7, 1, -14, -19, -15, -13, -16, -18, -8, 7, 19, 24, 16, 5, 8,
+ 16, 9, -4, -9, -5, 3, 4, -9, -19, -18, -13, -12, -17, -12, 2, 16,
+ 22, 17, 6, 4, 14, 13, 1, -8, -6, 2, 6, -5, -18, -20, -16, -14,
+ -18, -17, -5, 12, 23, 24, 14, 9, 15, 19, 9, -5, -8, -3, 2, -6,
+ -17, -23, -19, -14, -16, -17, -8, 7, 19, 24, 19, 10, 11, 17, 13, 3,
+ -5, -3, -2, -4, -14, -24, -25, -20, -18, -16, -10, 3, 16, 26, 28, 18,
+ 11, 15, 17, 9, -4, -7, -6, -6, -12, -24, -29, -22, -16, -15, -10, 0,
+ 13, 24, 27, 22, 14, 13, 16, 13, 2, -6, -7, -9, -12, -21, -29, -27,
+ -21, -15, -10, -3, 8, 21, 29, 26, 17, 13, 17, 19, 9, -5, -10, -9,
+ -12, -21, -30, -29, -22, -14, -10, -4, 7, 17, 26, 23, 17, 13, 12, 18,
+ 16, 5, -6, -10, -11, -19, -29, -32, -27, -18, -10, -4, 4, 13, 25, 26,
+ 21, 16, 11, 16, 17, 8, -5, -12, -12, -16, -25, -30, -27, -19, -10, -6,
+ 0, 10, 21, 24, 18, 15, 13, 16, 20, 14, 1, -10, -12, -15, -26, -31,
+ -29, -22, -12, -5, 0, 8, 19, 25, 22, 17, 14, 14, 19, 17, 4, -10,
+ -15, -15, -22, -30, -30, -26, -16, -6, 1, 7, 15, 23, 23, 18, 17, 17,
+ 17, 17, 8, -6, -15, -18, -24, -31, -29, -26, -19, -8, 2, 7, 15, 23,
+ 24, 21, 17, 15, 15, 17, 13, -4, -16, -20, -23, -30, -32, -27, -19, -8,
+ 3, 7, 14, 23, 24, 20, 16, 16, 15, 14, 10, 0, -12, -20, -24, -31,
+ -32, -25, -19, -10, 0, 9, 14, 22, 27, 23, 17, 17, 18, 12, 8, 1,
+ -12, -18, -23, -31, -34, -26, -17, -9, -2, 6, 14, 22, 27, 22, 16, 15,
+ 18, 17, 10, 3, -9, -17, -21, -31, -38, -32, -23, -13, -5, 4, 14, 21,
+ 30, 30, 21, 17, 18, 17, 10, 3, -8, -20, -23, -29, -38, -34, -25, -12,
+ 0, 3, 11, 17, 26, 31, 23, 15, 13, 16, 14, 5, -4, -15, -19, -23,
+ -35, -38, -32, -19, -7, -5, 6, 16, 25, 36, 32, 22, 19, 19, 15, 3,
+ -7, -16, -23, -26, -35, -42, -34, -19, -3, 1, 6, 18, 26, 37, 34, 20,
+ 15, 14, 14, 5, -7, -15, -21, -23, -28, -39, -37, -22, -5, 1, 3, 15,
+ 25, 35, 40, 27, 14, 14, 14, 6, -7, -14, -20, -25, -27, -36, -41, -28,
+ -8, 2, 4, 14, 24, 33, 40, 32, 17, 13, 12, 5, -7, -14, -17, -24,
+ -28, -34, -40, -32, -14, 1, 4, 13, 26, 33, 41, 40, 26, 15, 12, 4,
+ -9, -17, -20, -25, -31, -34, -41, -38, -20, 0, 7, 12, 24, 32, 40, 41,
+ 30, 17, 11, 4, -10, -18, -19, -21, -27, -31, -35, -36, -24, -5, 5, 9,
+ 21, 31, 37, 41, 36, 21, 11, 4, -8, -15, -18, -21, -26, -31, -34, -37,
+ -30, -12, 3, 9, 18, 30, 38, 44, 42, 29, 15, 7, -6, -18, -23, -24,
+ -25, -31, -34, -36, -33, -15, 3, 9, 17, 28, 38, 44, 42, 34, 20, 8,
+ -5, -18, -23, -22, -24, -30, -35, -35, -35, -24, -6, 6, 14, 25, 36, 42,
+ 45, 42, 28, 13, 1, -15, -26, -27, -26, -29, -35, -39, -38, -28, -10, 5,
+ 13, 21, 36, 47, 48, 45, 36, 21, 6, -11, -25, -31, -30, -29, -35, -41,
+ -41, -34, -18, 1, 15, 24, 35, 47, 52, 51, 42, 26, 8, -9, -25, -32,
+ -34, -32, -34, -40, -41, -35, -22, -5, 11, 21, 30, 44, 52, 51, 45, 32,
+ 15, -3, -19, -28, -33, -34, -36, -42, -44, -41, -30, -13, 6, 20, 29, 43,
+ 54, 56, 50, 37, 22, 4, -17, -31, -39, -39, -38, -40, -44, -41, -31, -14,
+ 4, 18, 26, 37, 52, 57, 54, 44, 29, 11, -9, -26, -38, -42, -40, -41,
+ -45, -46, -39, -24, -2, 17, 25, 35, 49, 59, 59, 52, 36, 19, -2, -22,
+ -38, -46, -45, -43, -44, -47, -41, -28, -7, 12, 22, 32, 45, 58, 60, 52,
+ 40, 26, 9, -14, -36, -46, -47, -44, -44, -50, -47, -34, -14, 8, 21, 30,
+ 42, 58, 65, 58, 46, 32, 14, -7, -30, -47, -51, -50, -45, -50, -51, -38,
+ -20, 4, 19, 28, 38, 53, 67, 63, 50, 40, 23, 2, -22, -43, -54, -55,
+ -50, -53, -57, -48, -31, -6, 17, 28, 39, 53, 69, 72, 60, 47, 29, 7,
+ -18, -39, -54, -59, -56, -53, -55, -52, -37, -16, 10, 25, 36, 48, 65, 75,
+ 68, 54, 40, 20, -6, -31, -52, -61, -61, -59, -63, -62, -46, -24, 2, 20,
+ 33, 50, 67, 79, 75, 62, 49, 30, 2, -29, -50, -63, -66, -65, -64, -64,
+ -50, -28, -6, 18, 34, 48, 62, 74, 79, 70, 54, 38, 14, -19, -45, -62,
+ -70, -71, -67, -68, -61, -39, -15, 10, 28, 45, 63, 77, 82, 77, 62, 47,
+ 25, -9, -40, -61, -70, -73, -69, -70, -66, -47, -23, 2, 23, 41, 57, 71,
+ 79, 83, 72, 55, 37, 6, -27, -51, -67, -76, -78, -77, -75, -60, -35, -12,
+ 13, 37, 59, 75, 82, 86, 81, 66, 48, 17, -23, -50, -66, -77, -83, -83,
+ -78, -66, -43, -18, 7, 31, 54, 73, 83, 87, 87, 74, 55, 29, -10, -41,
+ -61, -76, -85, -88, -84, -72, -53, -28, -3, 22, 51, 75, 84, 88, 92, 87,
+ 67, 40, 0, -38, -60, -77, -89, -94, -89, -77, -59, -34, -7, 17, 44, 73,
+ 88, 90, 91, 88, 74, 49, 12, -29, -57, -73, -84, -93, -94, -84, -68, -44,
+ -17, 8, 33, 64, 85, 90, 92, 91, 83, 63, 30, -15, -50, -71, -82, -92,
+ -96, -90, -74, -52, -26, 0, 24, 56, 82, 92, 93, 92, 89, 74, 42, 0,
+ -41, -67, -80, -93, -100, -97, -83, -62, -35, -8, 16, 43, 74, 91, 96, 96,
+ 93, 83, 56, 16, -28, -61, -79, -92, -99, -99, -90, -71, -45, -16, 9, 36,
+ 66, 88, 98, 97, 93, 87, 68, 31, -16, -52, -75, -89, -98, -103, -98, -81,
+ -54, -23, 1, 25, 56, 83, 97, 98, 92, 88, 76, 46, 1, -42, -68, -81,
+ -91, -99, -97, -82, -58, -30, -6, 15, 44, 73, 91, 94, 89, 85, 78, 55,
+ 16, -28, -59, -77, -87, -93, -95, -85, -65, -40, -16, 6, 33, 62, 85, 94,
+ 90, 86, 81, 66, 32, -15, -52, -73, -84, -90, -93, -87, -69, -45, -22, 0,
+ 22, 48, 75, 88, 88, 85, 80, 67, 42, 4, -36, -62, -77, -87, -90, -85,
+ -72, -52, -30, -11, 11, 36, 63, 83, 86, 86, 82, 74, 54, 17, -25, -55,
+ -72, -81, -88, -87, -77, -57, -34, -16, 4, 26, 54, 77, 84, 84, 82, 75,
+ 58, 27, -12, -45, -65, -76, -84, -84, -76, -61, -41, -24, -7, 15, 41, 67,
+ 78, 81, 80, 76, 67, 42, 5, -30, -54, -67, -79, -85, -79, -67, -50, -32,
+ -16, 6, 32, 58, 73, 77, 81, 78, 68, 49, 16, -19, -45, -63, -74, -80,
+ -77, -67, -53, -35, -20, -3, 20, 45, 65, 72, 76, 75, 68, 56, 29, -6,
+ -33, -52, -65, -75, -77, -70, -57, -42, -28, -13, 9, 34, 57, 70, 73, 75,
+ 72, 63, 41, 7, -24, -46, -60, -70, -75, -72, -59, -45, -31, -18, 0, 25,
+ 48, 63, 68, 70, 71, 65, 47, 17, -13, -33, -49, -62, -73, -73, -61, -48,
+ -37, -25, -10, 14, 39, 57, 64, 67, 70, 69, 54, 28, -3, -27, -44, -57,
+ -68, -74, -66, -50, -39, -26, -13, 5, 30, 50, 60, 62, 64, 65, 58, 38,
+ 9, -17, -35, -46, -59, -69, -67, -52, -40, -31, -20, -6, 18, 42, 55, 58,
+ 60, 65, 62, 47, 20, -10, -28, -39, -51, -66, -70, -58, -44, -34, -23, -10,
+ 11, 34, 51, 57, 58, 62, 63, 51, 29, 2, -21, -34, -46, -60, -69, -63,
+ -49, -37, -27, -15, 3, 26, 45, 55, 56, 58, 62, 55, 37, 11, -14, -29,
+ -39, -52, -65, -66, -52, -40, -30, -18, -5, 17, 39, 52, 54, 55, 58, 57,
+ 44, 21, -8, -24, -33, -45, -59, -66, -57, -43, -31, -20, -11, 7, 30, 47,
+ 53, 51, 52, 55, 51, 33, 4, -20, -29, -36, -49, -64, -63, -50, -36, -24,
+ -14, 0, 22, 43, 55, 53, 49, 52, 51, 39, 12, -16, -27, -33, -45, -60,
+ -66, -53, -37, -25, -16, -6, 16, 40, 53, 53, 47, 49, 51, 43, 22, 0,
+ 0, 0, 0, 0, 0, 0, 0, 22, 0, 0, -2, -2, -2, -2, 0, -2,
+ 0, 0, 1, 2, 3, 4, 4, 4, 5, 6, 7, 6, 3, 1, 0, -3,
+ -5, -11, -17, -20, -20, -18, -16, -17, -17, -14, -10, -9, -13, -18, -19, -15,
+ -13, -12, -13, -8, 1, 12, 25, 32, 40, 45, 50, 49, 41, 32, 24, 16,
+ 9, 1, -12, -20, -23, -24, -20, -20, -18, -12, -11, -12, -7, 0, 10, 17,
+ 23, 25, 24, 21, 22, 23, 21, 10, 1, -5, -8, -11, -19, -29, -33, -32,
+ -26, -19, -16, -14, -12, -8, -7, -11, -19, -27, -29, -27, -25, -25, -24, -17,
+ -4, 13, 26, 34, 43, 54, 59, 56, 46, 33, 23, 15, 5, -11, -23, -32,
+ -35, -32, -30, -27, -23, -16, -11, -5, 3, 11, 23, 31, 36, 33, 28, 27,
+ 26, 21, 11, 1, -9, -14, -18, -23, -28, -35, -33, -26, -18, -12, -11, -7,
+ -4, -2, 0, -8, -19, -29, -33, -32, -30, -30, -25, -17, -4, 13, 26, 36,
+ 47, 55, 59, 53, 43, 32, 23, 12, 0, -14, -23, -30, -35, -35, -35, -33,
+ -28, -19, -11, -6, 3, 11, 22, 33, 39, 38, 34, 30, 27, 20, 11, 0,
+ -9, -17, -21, -26, -31, -34, -29, -19, -8, -3, 0, -3, 1, 4, 1, -11,
+ -25, -35, -37, -39, -35, -32, -27, -17, 0, 15, 29, 42, 55, 63, 62, 55,
+ 47, 38, 27, 14, -4, -20, -31, -40, -44, -46, -45, -41, -34, -25, -14, -3,
+ 8, 22, 32, 43, 44, 40, 36, 34, 26, 18, 8, -2, -11, -20, -25, -29,
+ -33, -31, -21, -10, -2, -2, -2, 4, 6, 9, 0, -14, -28, -35, -39, -38,
+ -38, -36, -30, -16, 0, 16, 29, 41, 55, 65, 67, 59, 49, 39, 28, 13,
+ -3, -19, -32, -42, -48, -51, -53, -47, -36, -22, -12, 0, 10, 24, 38, 46,
+ 48, 43, 39, 32, 26, 17, 6, -7, -16, -21, -26, -31, -34, -28, -16, -2,
+ 3, 1, 2, 8, 16, 12, 2, -15, -27, -34, -37, -41, -47, -44, -33, -16,
+ 1, 16, 31, 47, 65, 75, 73, 63, 52, 41, 27, 9, -14, -34, -47, -54,
+ -55, -58, -57, -50, -35, -17, 0, 8, 20, 34, 47, 54, 49, 42, 36, 29,
+ 21, 9, -4, -14, -21, -26, -30, -33, -28, -18, -5, 4, 6, 6, 8, 13,
+ 17, 12, -4, -21, -33, -39, -44, -49, -50, -46, -35, -15, 4, 22, 36, 55,
+ 72, 81, 78, 69, 54, 42, 27, 6, -19, -38, -52, -57, -62, -65, -64, -52,
+ -35, -17, -3, 8, 19, 33, 45, 50, 48, 42, 35, 29, 18, 7, -5, -11,
+ -20, -26, -29, -27, -20, -13, -4, 3, 8, 9, 11, 12, 12, 5, -8, -22,
+ -33, -42, -50, -53, -51, -42, -27, -11, 9, 27, 45, 62, 75, 78, 73, 60,
+ 48, 32, 14, -8, -30, -46, -54, -60, -64, -62, -53, -39, -23, -8, 5, 17,
+ 30, 41, 46, 44, 38, 30, 22, 11, 4, -5, -12, -20, -25, -26, -24, -17,
+ -7, 3, 8, 11, 12, 14, 15, 14, 9, -4, -17, -32, -44, -54, -57, -56,
+ -48, -36, -22, -5, 18, 41, 61, 74, 79, 75, 67, 55, 39, 20, -2, -20,
+ -37, -47, -56, -62, -63, -57, -44, -31, -18, -5, 7, 16, 28, 35, 38, 37,
+ 32, 25, 16, 8, 3, -2, -5, -11, -19, -21, -16, -7, 3, 6, 8, 7,
+ 8, 10, 9, 5, -4, -13, -23, -37, -49, -54, -54, -47, -38, -25, -9, 9,
+ 30, 50, 67, 77, 75, 69, 58, 42, 26, 7, -12, -31, -46, -52, -56, -59,
+ -58, -49, -36, -19, -5, 8, 14, 22, 28, 33, 35, 30, 23, 13, 4, 3,
+ 3, 0, -8, -12, -13, -10, -6, 2, 8, 11, 12, 11, 9, 4, -2, -5,
+ -12, -23, -35, -46, -52, -54, -48, -36, -22, -8, 9, 28, 46, 61, 70, 72,
+ 68, 58, 45, 27, 9, -8, -22, -35, -43, -48, -48, -46, -39, -33, -23, -12,
+ 1, 8, 11, 14, 16, 19, 19, 17, 11, 7, 8, 11, 13, 7, 5, 2,
+ 2, 2, 4, 6, 6, 5, 2, -3, -5, -9, -11, -17, -23, -29, -34, -40,
+ -45, -41, -32, -18, -5, 7, 19, 36, 54, 64, 67, 61, 55, 48, 36, 18,
+ 3, -11, -23, -36, -45, -46, -42, -39, -34, -27, -20, -11, 0, 10, 13, 14,
+ 12, 13, 13, 10, 7, 6, 9, 11, 11, 11, 10, 10, 8, 9, 9, 9,
+ 6, 1, -4, -12, -16, -22, -25, -28, -29, -30, -39, -43, -39, -26, -11, 0,
+ 8, 19, 33, 48, 58, 63, 61, 56, 50, 40, 25, 8, -5, -15, -24, -35,
+ -41, -42, -39, -32, -29, -25, -21, -13, -6, 0, 4, 2, 2, 3, 6, 6,
+ 7, 11, 17, 20, 22, 23, 24, 23, 21, 17, 12, 4, -5, -13, -22, -29,
+ -37, -41, -40, -36, -31, -32, -34, -34, -22, -6, 8, 14, 20, 29, 41, 50,
+ 56, 56, 49, 45, 39, 30, 17, 5, -8, -19, -28, -34, -35, -32, -27, -25,
+ -25, -23, -19, -12, -7, -4, -6, -10, -11, -7, 0, 4, 10, 14, 19, 26,
+ 32, 35, 34, 31, 25, 16, 6, -5, -17, -29, -39, -47, -51, -50, -44, -35,
+ -28, -27, -25, -18, -6, 10, 18, 21, 25, 31, 40, 46, 49, 48, 44, 42,
+ 37, 29, 19, 8, -5, -14, -21, -29, -30, -30, -27, -28, -32, -33, -31, -22,
+ -17, -15, -17, -19, -19, -9, 5, 16, 22, 25, 31, 38, 44, 47, 43, 34,
+ 20, 6, -9, -21, -35, -49, -59, -62, -60, -53, -42, -30, -22, -15, -6, 4,
+ 14, 23, 27, 28, 27, 30, 35, 38, 39, 42, 38, 35, 30, 25, 20, 12,
+ 4, -6, -18, -23, -22, -20, -22, -30, -37, -39, -34, -29, -27, -27, -26, -23,
+ -16, -3, 10, 21, 29, 35, 43, 46, 50, 49, 41, 28, 15, -2, -19, -35,
+ -50, -62, -67, -67, -60, -50, -36, -23, -14, -6, 3, 11, 21, 27, 27, 24,
+ 25, 27, 29, 31, 36, 41, 42, 39, 33, 27, 22, 17, 8, -3, -11, -15,
+ -15, -18, -25, -35, -42, -45, -42, -41, -41, -40, -38, -28, -12, 7, 22, 34,
+ 43, 51, 59, 62, 59, 49, 37, 20, 1, -19, -38, -54, -65, -73, -74, -69,
+ -55, -35, -19, -10, -2, 8, 18, 23, 25, 25, 22, 20, 19, 20, 22, 30,
+ 39, 44, 42, 39, 35, 32, 29, 18, 4, -8, -13, -15, -17, -24, -33, -43,
+ -47, -44, -42, -40, -40, -39, -32, -17, 3, 16, 28, 39, 47, 53, 56, 56,
+ 52, 40, 24, 5, -12, -29, -43, -54, -65, -72, -71, -56, -36, -20, -13, -4,
+ 5, 12, 18, 21, 23, 20, 18, 14, 16, 19, 27, 38, 45, 45, 42, 41,
+ 42, 37, 27, 15, 1, -8, -12, -13, -17, -30, -40, -47, -48, -47, -46, -46,
+ -45, -41, -28, -9, 11, 26, 38, 45, 51, 55, 58, 55, 47, 31, 10, -12,
+ -27, -39, -49, -58, -67, -69, -62, -46, -26, -13, -4, 2, 7, 14, 18, 21,
+ 20, 15, 11, 12, 14, 21, 32, 40, 44, 42, 42, 40, 37, 33, 22, 11,
+ 1, -7, -11, -11, -19, -30, -39, -43, -43, -42, -43, -44, -44, -36, -20, 0,
+ 14, 25, 35, 42, 46, 50, 50, 48, 36, 17, -3, -18, -30, -36, -43, -52,
+ -59, -60, -49, -35, -20, -12, -7, -4, 2, 8, 12, 12, 9, 9, 12, 16,
+ 23, 29, 39, 45, 46, 46, 43, 41, 37, 30, 20, 7, -5, -10, -11, -15,
+ -25, -39, -46, -45, -43, -42, -45, -46, -39, -26, -8, 8, 20, 31, 41, 45,
+ 48, 46, 44, 36, 21, 1, -20, -31, -33, -36, -44, -53, -59, -54, -41, -26,
+ -17, -12, -6, -3, 5, 7, 9, 11, 11, 12, 15, 20, 29, 36, 42, 46,
+ 45, 42, 40, 38, 33, 25, 13, 4, -7, -10, -11, -17, -29, -38, -38, -34,
+ -35, -39, -41, -39, -31, -16, -6, 4, 14, 24, 30, 34, 34, 35, 32, 22,
+ 8, -9, -16, -16, -17, -22, -33, -43, -46, -41, -34, -30, -25, -19, -14, -9,
+ -6, -2, 5, 9, 13, 15, 21, 29, 36, 43, 47, 46, 46, 42, 39, 37,
+ 31, 20, 10, 0, -6, -9, -14, -22, -29, -33, -31, -30, -34, -37, -37, -30,
+ -21, -12, -5, 1, 10, 20, 28, 31, 31, 28, 20, 12, 0, -8, -10, -10,
+ -16, -24, -33, -39, -44, -42, -35, -28, -23, -18, -14, -10, -4, 6, 12, 16,
+ 17, 22, 29, 33, 35, 38, 41, 43, 41, 38, 34, 30, 24, 16, 9, 3,
+ -4, -10, -15, -21, -23, -23, -23, -24, -28, -32, -31, -28, -22, -15, -10, -6,
+ 2, 11, 20, 23, 25, 19, 14, 9, 5, 3, 2, -2, -8, -19, -28, -36,
+ -42, -44, -39, -33, -28, -26, -20, -11, 0, 8, 15, 22, 28, 33, 35, 36,
+ 37, 38, 41, 40, 38, 32, 27, 21, 17, 11, 4, -3, -8, -12, -17, -18,
+ -16, -16, -15, -18, -22, -25, -26, -25, -23, -19, -15, -9, -2, 8, 13, 17,
+ 18, 17, 16, 15, 13, 10, 6, 0, -9, -21, -32, -42, -47, -46, -43, -36,
+ -30, -22, -15, -6, 4, 14, 22, 28, 33, 36, 37, 36, 35, 37, 36, 36,
+ 32, 27, 23, 16, 10, 5, 0, -7, -10, -12, -11, -11, -11, -10, -9, -11,
+ -16, -22, -27, -30, -30, -30, -25, -19, -9, 0, 7, 13, 18, 23, 27, 27,
+ 26, 20, 12, 1, -13, -27, -40, -50, -54, -54, -49, -42, -33, -21, -10, 1,
+ 14, 24, 30, 39, 44, 43, 38, 36, 38, 37, 34, 31, 28, 22, 13, 7,
+ 5, -2, -7, -11, -14, -13, -13, -8, -6, -6, -10, -12, -14, -19, -26, -34,
+ -38, -33, -26, -15, -7, 2, 7, 17, 26, 35, 40, 37, 29, 19, 7, -12,
+ -31, -44, -53, -56, -61, -62, -59, -46, -27, -9, 5, 14, 25, 36, 47, 53,
+ 51, 45, 37, 34, 32, 29, 26, 23, 18, 13, 5, 0, -3, -4, -6, -10,
+ -12, -12, -6, 2, 6, 2, -6, -12, -17, -21, -31, -41, -47, -43, -32, -20,
+ -11, -4, 9, 21, 40, 50, 48, 42, 34, 22, 5, -16, -36, -53, -58, -63,
+ -69, -73, -63, -43, -19, -2, 9, 19, 34, 50, 60, 61, 53, 42, 37, 32,
+ 30, 24, 21, 16, 11, 4, -4, -7, -6, -5, -5, -10, -14, -11, -4, 3,
+ 2, -2, -8, -13, -19, -26, -36, -42, -40, -33, -21, -9, 1, 10, 22, 36,
+ 49, 53, 47, 36, 19, 1, -18, -36, -51, -60, -65, -67, -67, -63, -47, -24,
+ -4, 11, 20, 33, 48, 57, 57, 52, 42, 33, 30, 28, 25, 19, 16, 12,
+ 8, 3, -2, -2, -2, -2, -5, -8, -10, -5, -2, 0, 0, -5, -8, -15,
+ -23, -32, -39, -38, -33, -24, -15, -7, 5, 16, 30, 45, 52, 49, 40, 23,
+ 4, -14, -29, -42, -55, -63, -67, -67, -61, -50, -35, -19, 0, 16, 31, 46,
+ 56, 59, 56, 47, 38, 34, 31, 28, 23, 16, 10, 4, 0, -2, -2, 0,
+ -5, -9, -12, -11, -7, -3, -3, -4, -5, -4, -7, -14, -26, -33, -32, -27,
+ -20, -15, -7, 2, 13, 21, 34, 42, 46, 40, 25, 7, -13, -27, -35, -44,
+ -54, -62, -64, -60, -51, -39, -26, -10, 8, 24, 40, 51, 58, 60, 54, 44,
+ 36, 29, 24, 19, 13, 8, 0, -6, -5, 0, 1, 0, -4, -3, -2, 0,
+ 1, -2, -5, -5, -4, -7, -17, -27, -31, -29, -24, -19, -15, -9, -3, 7,
+ 18, 27, 34, 39, 37, 26, 9, -9, -24, -32, -39, -47, -55, -60, -57, -51,
+ -42, -32, -20, -6, 14, 31, 48, 57, 60, 58, 52, 45, 35, 25, 21, 17,
+ 9, 0, -8, -10, -8, -7, -6, -9, -9, -6, -2, 0, -3, -6, -6, -2,
+ 1, -6, -15, -25, -25, -20, -17, -13, -11, -7, 1, 8, 16, 24, 31, 34,
+ 29, 16, -3, -17, -28, -35, -41, -47, -54, -56, -54, -46, -37, -27, -15, 4,
+ 23, 40, 50, 58, 60, 58, 50, 42, 34, 26, 19, 14, 4, -6, -13, -13,
+ -13, -14, -16, -15, -12, -9, -7, -7, -4, -4, 2, 7, 5, 0, -8, -11,
+ -13, -13, -11, -10, -11, -11, -9, 0, 8, 14, 22, 24, 19, 9, -3, -14,
+ -23, -29, -32, -38, -47, -54, -52, -44, -32, -23, -9, 8, 23, 39, 52, 59,
+ 58, 51, 46, 43, 33, 25, 16, 9, 4, -4, -11, -15, -16, -16, -15, -14,
+ -15, -16, -13, -7, -5, 2, 5, 5, 5, 6, 3, -4, -6, -4, -5, -10,
+ -16, -16, -13, -6, 4, 12, 15, 17, 14, 10, 4, -8, -17, -23, -30, -38,
+ -46, -52, -51, -41, -30, -20, -8, 9, 29, 47, 56, 57, 55, 52, 50, 45,
+ 34, 20, 10, 2, -2, -9, -16, -22, -24, -22, -21, -22, -19, -14, -7, -4,
+ 1, 5, 11, 15, 20, 17, 9, 3, 3, 0, -6, -15, -21, -23, -16, -9,
+ -3, 4, 10, 13, 15, 13, 4, -9, -15, -20, -27, -39, -48, -51, -47, -38,
+ -29, -21, -7, 16, 36, 48, 51, 52, 55, 60, 59, 49, 33, 20, 12, 7,
+ -2, -13, -24, -28, -27, -26, -30, -32, -29, -20, -9, 0, 3, 8, 16, 25,
+ 28, 23, 17, 12, 6, -2, -14, -26, -31, -27, -18, -10, -3, 7, 15, 22,
+ 24, 18, 9, 0, -9, -19, -34, -46, -57, -57, -51, -44, -38, -26, -5, 21,
+ 42, 48, 53, 58, 67, 75, 71, 57, 37, 23, 12, 3, -12, -27, -39, -43,
+ -43, -45, -47, -42, -28, -12, 2, 7, 12, 20, 32, 38, 37, 30, 21, 13,
+ 1, -13, -26, -34, -33, -26, -17, -10, -3, 9, 20, 25, 22, 13, 5, -3,
+ -13, -28, -43, -53, -56, -51, -46, -40, -31, -14, 10, 31, 41, 47, 56, 67,
+ 76, 73, 63, 46, 30, 19, 9, -7, -25, -39, -47, -50, -54, -52, -50, -38,
+ -22, -9, 4, 12, 22, 30, 39, 41, 39, 31, 22, 12, -3, -19, -30, -32,
+ -29, -23, -17, -9, 1, 12, 20, 24, 18, 10, 2, -7, -19, -35, -50, -59,
+ -59, -54, -49, -43, -31, -9, 15, 32, 41, 53, 70, 85, 87, 80, 64, 49,
+ 37, 23, 2, -23, -42, -52, -59, -66, -69, -68, -56, -38, -18, -2, 9, 19,
+ 31, 41, 49, 51, 44, 35, 21, 5, -9, -22, -29, -30, -26, -20, -14, -7,
+ 5, 15, 17, 14, 9, 2, -4, -16, -29, -45, -55, -56, -50, -46, -44, -36,
+ -19, 1, 19, 33, 46, 63, 79, 86, 84, 73, 60, 47, 32, 12, -10, -30,
+ -48, -59, -68, -72, -73, -64, -49, -30, -12, 2, 12, 26, 35, 45, 51, 51,
+ 44, 30, 15, 3, -9, -17, -20, -21, -19, -18, -14, 0, 10, 16, 15, 7,
+ -4, -10, -14, -24, -38, -51, -58, -55, -50, -44, -36, -23, -7, 10, 26, 41,
+ 57, 76, 89, 89, 81, 70, 59, 45, 25, 0, -24, -41, -56, -67, -75, -80,
+ -76, -63, -45, -26, -9, 6, 20, 32, 44, 52, 54, 53, 47, 35, 18, 3,
+ -6, -11, -14, -16, -19, -19, -12, -4, 5, 5, 0, -8, -12, -15, -21, -34,
+ -47, -51, -45, -39, -34, -30, -23, -12, 4, 17, 31, 45, 60, 72, 78, 75,
+ 69, 62, 53, 40, 18, -5, -24, -38, -50, -62, -73, -78, -74, -59, -41, -28,
+ -17, -4, 14, 33, 47, 55, 58, 55, 48, 39, 29, 16, 4, -5, -11, -18,
+ -21, -20, -15, -8, -7, -9, -13, -15, -16, -17, -23, -33, -43, -44, -41, -34,
+ -28, -23, -16, -8, 5, 21, 36, 50, 62, 73, 76, 73, 68, 59, 48, 30,
+ 9, -16, -35, -48, -59, -70, -77, -79, -72, -54, -38, -24, -8, 8, 29, 45,
+ 56, 61, 62, 56, 51, 39, 27, 16, 4, -8, -16, -22, -23, -25, -19, -16,
+ -17, -19, -20, -21, -18, -19, -25, -32, -38, -34, -24, -19, -15, -12, -7, 3,
+ 15, 28, 39, 48, 56, 63, 63, 63, 57, 47, 32, 14, -5, -22, -36, -46,
+ -58, -68, -73, -71, -61, -47, -35, -23, -9, 10, 29, 43, 52, 56, 56, 56,
+ 52, 45, 33, 19, 6, -5, -15, -22, -25, -26, -26, -29, -29, -26, -24, -20,
+ -19, -23, -27, -30, -27, -21, -18, -14, -10, -7, 0, 8, 18, 30, 40, 47,
+ 52, 54, 54, 55, 49, 39, 22, 7, -9, -24, -37, -50, -58, -65, -71, -67,
+ -59, -50, -39, -23, -6, 15, 32, 43, 51, 57, 61, 64, 61, 52, 37, 21,
+ 4, -11, -20, -26, -30, -35, -37, -39, -35, -29, -22, -17, -20, -22, -20, -18,
+ -17, -16, -13, -8, -3, 2, 7, 10, 17, 27, 35, 42, 43, 44, 45, 44,
+ 38, 28, 16, 3, -10, -22, -33, -46, -57, -64, -64, -59, -53, -46, -34, -17,
+ 3, 21, 32, 41, 48, 55, 60, 60, 54, 44, 31, 18, 3, -10, -19, -27,
+ -30, -32, -34, -35, -30, -23, -17, -17, -20, -20, -20, -17, -15, -13, -11, -8,
+ 1, 8, 12, 17, 23, 30, 39, 39, 37, 36, 35, 34, 27, 14, 0, -10,
+ -15, -23, -34, -46, -56, -60, -56, -49, -39, -32, -23, -8, 8, 23, 32, 38,
+ 44, 54, 58, 57, 48, 37, 29, 17, 4, -11, -21, -28, -29, -31, -34, -35,
+ -27, -20, -15, -16, -16, -17, -13, -10, -10, -11, -10, -4, 5, 11, 13, 15,
+ 21, 29, 33, 32, 28, 25, 25, 23, 16, 5, -6, -10, -16, -21, -30, -42,
+ -48, -48, -43, -34, -29, -21, -13, -3, 11, 22, 27, 34, 39, 48, 53, 48,
+ 42, 32, 23, 16, 4, -7, -18, -24, -24, -26, -28, -24, -19, -14, -13, -16,
+ -18, -18, -16, -14, -15, -16, -15, -7, 3, 11, 14, 21, 27, 33, 36, 33,
+ 30, 25, 22, 17, 9, -4, -15, -21, -24, -31, -39, -44, -44, -39, -30, -23,
+ -16, -8, 4, 14, 21, 23, 25, 29, 37, 43, 42, 36, 31, 25, 18, 11,
+ 4, -7, -11, -13, -16, -21, -22, -18, -14, -13, -16, -19, -21, -21, -19, -19,
+ -20, -18, -11, -2, 8, 14, 18, 23, 30, 34, 35, 31, 27, 21, 13, 2,
+ -11, -17, -23, -28, -36, -39, -40, -37, -31, -23, -14, -9, 0, 7, 13, 15,
+ 15, 16, 22, 27, 30, 28, 29, 32, 29, 23, 16, 9, 4, 1, -2, -7,
+ -14, -19, -14, -10, -10, -14, -18, -22, -24, -23, -26, -28, -27, -18, -8, -3,
+ 2, 9, 22, 33, 40, 40, 36, 30, 25, 20, 8, -8, -22, -29, -32, -39,
+ -48, -50, -42, -30, -19, -13, -8, 2, 11, 22, 25, 21, 17, 15, 20, 23,
+ 21, 20, 20, 19, 19, 16, 11, 9, 7, 7, 3, 0, -3, -5, -5, -5,
+ -7, -12, -22, -28, -32, -35, -35, -36, -30, -21, -12, -4, 3, 16, 29, 39,
+ 46, 45, 40, 34, 26, 13, -2, -17, -28, -37, -48, -57, -60, -52, -36, -19,
+ -12, -8, 2, 16, 28, 33, 28, 23, 21, 22, 21, 19, 18, 16, 14, 12,
+ 8, 6, 5, 5, 7, 5, 4, 5, 7, 9, 7, 3, -5, -13, -22, -28,
+ -35, -44, -49, -48, -38, -26, -14, -7, 4, 20, 38, 49, 54, 53, 49, 40,
+ 26, 8, -11, -24, -33, -46, -61, -70, -67, -52, -31, -14, -5, 4, 14, 27,
+ 36, 36, 33, 29, 26, 25, 21, 14, 10, 7, 8, 6, 5, 5, 6, 8,
+ 9, 10, 14, 18, 17, 13, 5, -4, -12, -20, -28, -37, -49, -56, -56, -48,
+ -36, -25, -15, -2, 16, 36, 51, 55, 57, 55, 48, 37, 20, 1, -17, -30,
+ -43, -60, -73, -76, -63, -43, -24, -14, -6, 7, 23, 39, 44, 38, 34, 31,
+ 32, 30, 24, 16, 8, 5, 6, 6, 5, 5, 6, 10, 10, 13, 16, 19,
+ 19, 14, 5, -7, -18, -25, -34, -45, -55, -61, -59, -51, -39, -25, -12, 5,
+ 27, 48, 58, 60, 61, 58, 49, 32, 14, -4, -20, -36, -54, -69, -79, -75,
+ -57, -35, -21, -15, -4, 12, 28, 39, 42, 41, 38, 38, 38, 33, 23, 13,
+ 8, 9, 11, 9, 5, 3, 6, 10, 13, 14, 15, 17, 16, 9, -6, -16,
+ -21, -27, -40, -56, -65, -67, -57, -45, -33, -23, -5, 21, 44, 60, 66, 67,
+ 65, 61, 47, 25, 2, -16, -34, -53, -72, -83, -82, -70, -51, -33, -20, -8,
+ 8, 25, 39, 46, 43, 43, 43, 43, 38, 27, 17, 9, 8, 10, 11, 9,
+ 5, 5, 8, 13, 14, 18, 20, 18, 12, -2, -13, -19, -25, -34, -48, -62,
+ -69, -67, -58, -46, -32, -14, 9, 30, 48, 60, 69, 72, 69, 57, 36, 13,
+ -6, -27, -47, -66, -79, -83, -77, -64, -46, -29, -13, 4, 17, 30, 39, 41,
+ 46, 48, 45, 40, 31, 20, 12, 10, 13, 14, 12, 11, 10, 10, 15, 17,
+ 20, 20, 17, 12, 0, -14, -24, -30, -37, -47, -60, -69, -68, -62, -51, -36,
+ -18, 5, 25, 45, 58, 65, 68, 67, 59, 42, 20, -2, -22, -42, -61, -75,
+ -81, -77, -66, -51, -35, -20, -4, 14, 28, 37, 38, 38, 42, 47, 43, 35,
+ 24, 17, 14, 14, 17, 20, 20, 17, 13, 14, 17, 18, 18, 17, 11, -2,
+ -15, -24, -31, -38, -46, -52, -58, -62, -61, -52, -38, -22, -4, 16, 35, 48,
+ 55, 60, 62, 57, 46, 26, 6, -17, -35, -53, -68, -76, -75, -66, -51, -38,
+ -23, -7, 10, 25, 35, 38, 37, 39, 40, 39, 30, 21, 16, 15, 15, 16,
+ 20, 24, 26, 27, 27, 26, 24, 21, 19, 11, -3, -16, -29, -40, -44, -50,
+ -54, -57, -58, -55, -48, -36, -21, -5, 13, 29, 41, 48, 52, 53, 50, 41,
+ 26, 7, -14, -33, -49, -62, -70, -69, -61, -48, -36, -21, -5, 16, 30, 35,
+ 35, 35, 32, 31, 29, 24, 17, 13, 13, 14, 15, 18, 26, 34, 39, 37,
+ 32, 29, 26, 22, 13, 1, -15, -29, -40, -46, -51, -54, -55, -52, -46, -40,
+ -32, -22, -10, 5, 19, 28, 33, 35, 37, 38, 33, 21, 8, -7, -20, -35,
+ -50, -57, -57, -49, -37, -28, -21, -8, 10, 25, 32, 32, 31, 27, 24, 22,
+ 20, 15, 13, 13, 15, 15, 19, 26, 36, 42, 43, 40, 33, 27, 22, 16,
+ 3, -13, -26, -37, -44, -50, -55, -54, -48, -42, -32, -24, -18, -10, -3, 8,
+ 20, 30, 31, 26, 22, 20, 15, 7, -7, -20, -32, -43, -52, -52, -46, -36,
+ -25, -16, -5, 9, 24, 38, 42, 39, 30, 23, 19, 15, 11, 8, 6, 6,
+ 6, 9, 18, 30, 42, 47, 45, 43, 38, 31, 22, 8, -9, -21, -33, -45,
+ -55, -59, -56, -47, -37, -29, -21, -13, -5, 2, 8, 13, 19, 22, 20, 15,
+ 9, 5, -3, -9, -20, -30, -39, -46, -45, -40, -31, -24, -16, -6, 7, 21,
+ 35, 39, 36, 31, 24, 22, 15, 10, 8, 5, 6, 3, 4, 12, 25, 40,
+ 48, 50, 48, 43, 37, 30, 17, -2, -18, -33, -45, -57, -64, -62, -53, -40,
+ -31, -23, -13, -3, 4, 11, 16, 19, 18, 17, 13, 7, -3, -10, -16, -22,
+ -31, -40, -45, -45, -41, -32, -24, -15, -5, 8, 24, 39, 47, 44, 38, 32,
+ 26, 20, 12, 3, -4, -4, -5, -4, 1, 11, 29, 41, 49, 51, 49, 45,
+ 38, 27, 9, -11, -27, -38, -52, -60, -64, -58, -45, -32, -21, -14, -5, 3,
+ 10, 13, 13, 14, 14, 12, 4, -6, -12, -17, -21, -25, -31, -35, -40, -39,
+ -33, -27, -19, -12, 1, 16, 29, 38, 42, 40, 36, 33, 30, 22, 11, 1,
+ -2, -2, -3, -2, 2, 16, 32, 44, 48, 46, 44, 39, 31, 19, 1, -21,
+ -36, -48, -58, -62, -59, -49, -38, -28, -20, -12, -2, 9, 16, 16, 15, 16,
+ 14, 9, 2, -7, -14, -19, -25, -31, -36, -38, -38, -36, -34, -28, -20, -7,
+ 8, 22, 33, 41, 46, 46, 42, 39, 33, 25, 14, 4, -4, -8, -8, -4,
+ 4, 16, 30, 38, 42, 46, 45, 38, 25, 10, -7, -24, -39, -51, -58, -59,
+ -53, -43, -34, -28, -21, -9, 5, 15, 17, 16, 15, 16, 15, 10, 2, -10,
+ -17, -21, -26, -33, -38, -40, -37, -34, -33, -28, -17, 0, 15, 29, 40, 48,
+ 50, 48, 44, 40, 34, 26, 15, 3, -6, -11, -11, -4, 7, 18, 24, 30,
+ 36, 38, 35, 31, 24, 13, -7, -25, -40, -50, -53, -51, -47, -41, -38, -33,
+ -25, -10, 4, 14, 19, 21, 22, 19, 19, 17, 7, -5, -15, -23, -31, -39,
+ -46, -49, -49, -46, -41, -33, -19, 0, 21, 39, 53, 61, 64, 63, 56, 50,
+ 42, 31, 15, -2, -13, -19, -19, -11, 0, 10, 15, 19, 27, 33, 37, 35,
+ 25, 9, -13, -28, -38, -44, -46, -50, -53, -51, -46, -38, -23, -7, 10, 20,
+ 21, 24, 25, 28, 28, 19, 8, -7, -18, -28, -36, -43, -52, -56, -57, -51,
+ -44, -31, -13, 7, 29, 46, 60, 66, 71, 68, 61, 54, 45, 32, 13, -5,
+ -17, -22, -20, -15, -8, -2, 8, 14, 24, 31, 35, 32, 21, 4, -13, -24,
+ -34, -42, -49, -55, -58, -54, -48, -38, -23, -4, 14, 26, 32, 31, 32, 36,
+ 34, 23, 7, -12, -25, -35, -47, -61, -68, -68, -61, -53, -42, -26, -7, 22,
+ 45, 61, 71, 75, 78, 74, 66, 56, 42, 24, 7, -13, -24, -29, -25, -18,
+ -11, -7, 2, 14, 27, 36, 38, 32, 19, 1, -14, -22, -33, -44, -56, -64,
+ -65, -60, -47, -32, -16, 3, 18, 31, 37, 37, 38, 41, 35, 20, 0, -18,
+ -31, -43, -56, -64, -69, -68, -60, -50, -36, -15, 6, 31, 50, 62, 71, 77,
+ 78, 74, 66, 54, 38, 20, 2, -15, -23, -26, -24, -22, -17, -7, 8, 20,
+ 29, 35, 33, 25, 13, -2, -14, -29, -42, -57, -67, -72, -67, -57, -42, -24,
+ -5, 13, 31, 43, 46, 47, 48, 43, 32, 14, -5, -22, -40, -55, -63, -68,
+ -69, -66, -57, -44, -25, -5, 18, 37, 55, 66, 75, 78, 75, 70, 62, 47,
+ 28, 9, -7, -19, -27, -30, -27, -21, -11, 5, 18, 28, 34, 36, 32, 24,
+ 12, -4, -20, -38, -55, -68, -75, -71, -65, -53, -35, -14, 6, 24, 39, 47,
+ 50, 48, 44, 36, 22, 5, -16, -34, -47, -56, -60, -60, -59, -54, -45, -28,
+ -9, 9, 25, 41, 53, 63, 67, 66, 65, 62, 54, 40, 22, 6, -8, -16,
+ -22, -23, -20, -11, 1, 13, 22, 27, 29, 26, 24, 15, 2, -15, -33, -49,
+ -64, -74, -74, -67, -55, -39, -20, -2, 16, 32, 45, 50, 49, 43, 35, 26,
+ 11, -9, -25, -35, -44, -49, -52, -54, -50, -39, -26, -12, 1, 14, 27, 39,
+ 48, 53, 55, 57, 56, 48, 36, 25, 15, 6, -5, -12, -17, -14, -8, 3,
+ 14, 21, 26, 23, 21, 21, 14, 3, -11, -26, -44, -61, -72, -72, -68, -56,
+ -42, -25, -11, 7, 24, 37, 44, 44, 40, 33, 25, 13, 0, -12, -24, -32,
+ -39, -41, -39, -36, -30, -24, -18, -10, 1, 11, 21, 29, 36, 41, 47, 51,
+ 51, 42, 35, 27, 19, 10, 1, -6, -10, -9, -2, 6, 11, 13, 13, 15,
+ 14, 10, 4, -9, -19, -31, -45, -58, -67, -68, -56, -43, -31, -20, -9, 7,
+ 21, 31, 35, 35, 33, 27, 18, 7, -3, -9, -13, -20, -27, -32, -33, -29,
+ -23, -19, -16, -12, -4, 6, 15, 23, 30, 39, 47, 49, 42, 35, 31, 27,
+ 22, 14, 2, -8, -9, -4, 5, 8, 8, 9, 7, 6, 3, 0, -5, -12,
+ -22, -35, -50, -58, -58, -50, -39, -32, -26, -19, -8, 7, 21, 26, 27, 25,
+ 22, 18, 11, 5, 2, 1, -3, -10, -19, -24, -23, -16, -15, -17, -20, -17,
+ -10, -2, 6, 12, 21, 32, 44, 45, 38, 30, 27, 31, 31, 21, 8, 1,
+ 0, 2, 8, 10, 7, 1, -3, -2, -4, -9, -12, -17, -25, -37, -47, -53,
+ -50, -42, -32, -27, -26, -22, -11, 5, 15, 18, 20, 22, 23, 22, 18, 15,
+ 14, 11, 7, -3, -14, -18, -17, -18, -22, -27, -27, -21, -14, -6, 3, 12,
+ 24, 34, 40, 39, 35, 32, 31, 34, 30, 19, 10, 4, 2, 5, 7, 7,
+ 1, -6, -10, -9, -8, -8, -11, -16, -25, -34, -41, -41, -36, -32, -33, -33,
+ -29, -22, -11, -2, 6, 13, 17, 22, 23, 22, 22, 24, 23, 20, 12, 0,
+ -7, -11, -14, -20, -26, -28, -26, -22, -15, -9, 2, 13, 25, 32, 33, 35,
+ 36, 37, 38, 35, 29, 19, 9, 5, 7, 6, 4, -3, -9, -12, -11, -6,
+ -4, -5, -10, -17, -26, -33, -37, -38, -38, -38, -41, -39, -31, -20, -9, -2,
+ 6, 15, 23, 31, 31, 31, 30, 29, 28, 21, 13, 2, -9, -17, -20, -23,
+ -26, -27, -26, -20, -14, -6, 6, 14, 22, 26, 32, 34, 35, 37, 37, 36,
+ 27, 15, 6, 6, 7, 5, -3, -13, -17, -17, -11, -5, -5, -6, -11, -18,
+ -24, -27, -30, -35, -40, -44, -44, -39, -28, -16, -6, 1, 9, 20, 31, 34,
+ 36, 37, 36, 33, 23, 14, 5, -3, -10, -17, -23, -30, -34, -31, -22, -14,
+ -8, 0, 7, 15, 20, 26, 30, 35, 40, 40, 34, 27, 18, 14, 9, 8,
+ 5, -2, -11, -15, -13, -8, -4, 0, 1, -6, -12, -18, -23, -29, -38, -45,
+ -52, -53, -47, -37, -28, -16, -5, 6, 17, 28, 37, 42, 43, 40, 37, 31,
+ 19, 8, 1, -7, -14, -22, -27, -33, -34, -28, -18, -8, 0, 5, 10, 14,
+ 19, 25, 33, 38, 39, 35, 27, 18, 13, 9, 8, 4, -3, -8, -12, -13,
+ -10, -4, 4, 4, -2, -7, -14, -21, -28, -36, -45, -53, -54, -50, -44, -34,
+ -20, -5, 7, 18, 28, 37, 39, 42, 40, 35, 28, 17, 7, 0, -7, -12,
+ -18, -23, -28, -28, -23, -17, -8, 2, 8, 9, 10, 12, 17, 25, 32, 33,
+ 28, 20, 13, 10, 10, 8, 6, 5, 1, -5, -6, -3, 3, 10, 10, 5,
+ -6, -15, -21, -28, -38, -49, -59, -62, -59, -51, -39, -25, -8, 7, 17, 28,
+ 37, 42, 44, 43, 38, 30, 17, 7, 0, -4, -10, -16, -24, -26, -27, -21,
+ -14, -9, -2, 5, 11, 14, 12, 13, 19, 26, 29, 26, 19, 13, 8, 8,
+ 9, 5, 2, 2, 4, 3, 1, 1, 5, 8, 7, 0, -10, -18, -25, -32,
+ -42, -52, -56, -53, -48, -38, -29, -14, 1, 14, 23, 30, 33, 33, 35, 33,
+ 26, 17, 9, 2, 1, 0, -5, -12, -19, -22, -21, -13, -8, -4, 5, 10,
+ 12, 10, 10, 14, 21, 25, 24, 15, 5, 3, 5, 7, 5, 2, 5, 10,
+ 12, 10, 9, 11, 13, 10, 2, -8, -18, -25, -32, -40, -50, -55, -53, -45,
+ -35, -27, -17, -4, 11, 20, 28, 30, 28, 29, 30, 28, 19, 10, 6, 6,
+ 5, 0, -10, -18, -20, -18, -14, -11, -10, -4, 6, 13, 13, 11, 13, 20,
+ 25, 24, 15, 7, 3, 4, 5, 4, 0, 3, 9, 14, 15, 11, 9, 8,
+ 8, 6, -5, -16, -24, -29, -35, -43, -48, -47, -42, -31, -23, -17, -7, 5,
+ 17, 24, 26, 22, 19, 19, 20, 17, 11, 5, 2, 2, 0, -4, -10, -14,
+ -14, -10, -8, -6, 1, 10, 19, 23, 22, 17, 16, 19, 18, 11, 1, -8,
+ -11, -10, -7, -4, 1, 7, 15, 22, 22, 18, 17, 16, 12, 4, -8, -21,
+ -29, -34, -39, -46, -49, -46, -37, -28, -19, -9, -2, 8, 19, 22, 20, 18,
+ 18, 19, 19, 12, 6, 3, 2, 0, -5, -10, -16, -18, -14, -9, -8, -3,
+ 6, 17, 25, 27, 26, 24, 25, 22, 15, 3, -8, -13, -13, -12, -11, -6,
+ 0, 9, 16, 19, 19, 16, 13, 10, 6, -5, -14, -22, -26, -32, -37, -41,
+ -39, -32, -23, -17, -14, -10, -3, 9, 17, 18, 10, 7, 10, 16, 18, 12,
+ 5, 1, 1, -4, -13, -18, -18, -15, -12, -11, -10, 1, 15, 29, 37, 35,
+ 31, 30, 30, 24, 11, -8, -18, -18, -15, -17, -20, -17, -6, 8, 15, 18,
+ 16, 15, 11, 12, 8, 0, -10, -16, -20, -28, -35, -38, -33, -27, -23, -21,
+ -19, -13, 0, 11, 14, 12, 9, 11, 18, 21, 19, 10, 2, -3, -5, -12,
+ -21, -28, -26, -20, -15, -12, -6, 9, 25, 38, 43, 42, 40, 38, 34, 23,
+ 6, -12, -18, -18, -18, -23, -25, -22, -13, 0, 7, 9, 8, 8, 11, 12,
+ 9, 6, 2, -5, -14, -21, -24, -24, -22, -22, -21, -22, -20, -12, -3, 4,
+ 5, 5, 6, 11, 15, 16, 10, 4, -2, -7, -11, -20, -25, -27, -21, -13,
+ -11, -5, 6, 22, 37, 46, 50, 49, 44, 39, 31, 16, -3, -15, -21, -24,
+ -27, -32, -33, -28, -17, -5, 5, 7, 7, 10, 15, 16, 15, 10, 4, -4,
+ -11, -18, -22, -22, -20, -22, -21, -21, -17, -10, 1, 6, 9, 10, 15, 19,
+ 18, 12, 5, 0, -9, -15, -23, -31, -36, -32, -24, -17, -11, -4, 12, 31,
+ 47, 53, 58, 60, 56, 49, 35, 15, -4, -16, -21, -25, -32, -42, -45, -35,
+ -23, -14, -8, 0, 6, 13, 20, 21, 19, 15, 9, 1, -6, -11, -13, -16,
+ -18, -20, -23, -20, -14, -8, 0, 2, 5, 11, 18, 18, 14, 6, -2, -10,
+ -18, -27, -34, -41, -40, -31, -20, -12, -7, 4, 23, 47, 64, 71, 71, 63,
+ 56, 46, 30, 12, -7, -22, -35, -42, -49, -52, -48, -34, -22, -14, -7, 3,
+ 15, 24, 27, 27, 24, 15, 6, -4, -8, -11, -13, -13, -15, -16, -14, -12,
+ -7, -2, 3, 10, 12, 14, 15, 7, 0, -7, -16, -25, -32, -40, -44, -44,
+ -36, -24, -11, 0, 6, 16, 36, 58, 72, 76, 71, 62, 51, 38, 24, 5,
+ -13, -30, -42, -50, -52, -53, -46, -33, -21, -15, -6, 7, 20, 25, 25, 21,
+ 18, 14, 7, 2, -5, -9, -9, -7, -8, -9, -10, -7, -3, 1, 6, 7,
+ 8, 9, 6, -2, -13, -23, -30, -35, -41, -45, -44, -38, -26, -15, -3, 11,
+ 19, 33, 52, 69, 75, 72, 65, 54, 42, 29, 13, -6, -25, -41, -49, -54,
+ -55, -48, -38, -26, -18, -8, 1, 13, 24, 29, 26, 19, 11, 5, 2, -2,
+ -6, -6, -6, -5, -7, -5, 1, 5, 9, 11, 8, 8, 7, 4, -6, -17,
+ -28, -35, -42, -47, -48, -45, -39, -29, -16, -5, 7, 18, 32, 45, 57, 64,
+ 67, 62, 54, 45, 35, 22, 5, -13, -28, -40, -47, -49, -46, -42, -32, -21,
+ -11, -4, 6, 15, 21, 21, 16, 12, 6, 1, -3, -5, -3, 3, 8, 9,
+ 8, 7, 7, 11, 12, 11, 6, -2, -9, -13, -20, -29, -40, -47, -47, -45,
+ -42, -37, -29, -16, -5, 7, 17, 27, 38, 48, 56, 59, 53, 44, 40, 37,
+ 30, 17, -2, -16, -25, -32, -35, -36, -35, -31, -23, -16, -10, -3, 4, 10,
+ 11, 8, 1, 0, 0, 0, 0, 1, 6, 14, 20, 21, 19, 15, 14, 13,
+ 11, 7, 0, -13, -21, -28, -37, -46, -51, -48, -43, -37, -32, -28, -21, -9,
+ 4, 17, 27, 32, 40, 45, 50, 51, 46, 40, 38, 35, 27, 12, -3, -13,
+ -23, -27, -29, -30, -29, -28, -23, -15, -10, -5, 2, 5, 5, 1, -2, -2,
+ 1, 4, 4, 8, 14, 19, 25, 26, 21, 15, 13, 12, 12, 5, -9, -21,
+ -30, -37, -43, -50, -51, -47, -42, -38, -34, -27, -17, -5, 10, 22, 30, 38,
+ 44, 49, 50, 46, 40, 37, 38, 33, 19, 4, -8, -14, -18, -22, -24, -24,
+ -22, -18, -16, -14, -10, -6, 1, 1, -6, -8, -9, -6, 0, 2, 8, 14,
+ 21, 28, 31, 27, 24, 21, 20, 16, 9, -3, -16, -26, -33, -42, -50, -55,
+ -56, -50, -43, -39, -38, -29, -13, 6, 18, 27, 33, 42, 51, 54, 53, 48,
+ 41, 39, 38, 29, 12, -5, -15, -19, -20, -23, -24, -22, -18, -17, -13, -12,
+ -10, -4, -3, -4, -7, -8, -9, -9, -7, 2, 9, 14, 21, 26, 27, 27,
+ 22, 20, 19, 17, 12, 1, -14, -25, -35, -41, -45, -50, -53, -54, -51, -47,
+ -41, -31, -18, -3, 12, 24, 35, 47, 55, 58, 57, 55, 49, 46, 40, 26,
+ 11, -5, -17, -22, -23, -23, -22, -21, -21, -18, -15, -9, -5, -3, -4, -6,
+ -7, -9, -12, -12, -8, 1, 7, 13, 14, 19, 23, 27, 26, 25, 25, 20,
+ 13, 4, -9, -22, -36, -42, -48, -55, -61, -62, -59, -54, -43, -32, -18, 0,
+ 18, 35, 49, 57, 60, 62, 63, 61, 57, 48, 33, 15, -2, -15, -24, -28,
+ -27, -22, -23, -24, -21, -13, -4, 3, 3, 1, -2, -4, -4, -9, -15, -16,
+ -13, -9, -5, 2, 7, 11, 19, 24, 28, 31, 29, 28, 24, 12, -4, -21,
+ -33, -38, -48, -61, -72, -76, -71, -61, -47, -34, -20, 2, 26, 45, 58, 65,
+ 69, 74, 75, 68, 55, 41, 28, 13, -7, -22, -32, -32, -29, -24, -23, -22,
+ -19, -7, 6, 7, 2, -2, -3, 0, -3, -10, -20, -24, -19, -12, -5, 1,
+ 5, 14, 23, 30, 33, 37, 39, 36, 24, 8, -10, -25, -33, -43, -55, -71,
+ -82, -82, -71, -57, -44, -29, -11, 13, 34, 52, 64, 70, 73, 77, 76, 65,
+ 50, 35, 20, 4, -13, -26, -31, -32, -27, -26, -25, -21, -10, 2, 8, 5,
+ 3, 0, 1, 2, -3, -12, -22, -24, -21, -16, -9, -3, 6, 14, 22, 28,
+ 34, 41, 42, 35, 23, 6, -10, -21, -32, -45, -61, -76, -85, -82, -70, -54,
+ -43, -29, -7, 18, 40, 55, 64, 71, 77, 81, 76, 62, 48, 32, 19, 6,
+ -10, -23, -30, -29, -28, -30, -27, -20, -10, -2, 3, 1, 0, 3, 6, 4,
+ -9, -18, -24, -22, -18, -14, -8, 0, 8, 16, 24, 32, 38, 42, 42, 31,
+ 15, -2, -14, -25, -38, -52, -67, -81, -85, -76, -63, -49, -37, -19, 3, 26,
+ 43, 57, 67, 75, 82, 79, 70, 56, 41, 28, 15, 1, -12, -22, -27, -27,
+ -28, -26, -21, -12, -3, 3, -2, -2, 1, 3, 1, -12, -22, -28, -29, -27,
+ -23, -18, -11, 3, 16, 25, 34, 44, 51, 52, 43, 27, 12, -2, -17, -34,
+ -51, -71, -82, -86, -83, -75, -61, -45, -27, -7, 16, 37, 53, 63, 72, 78,
+ 77, 68, 60, 45, 33, 20, 10, -2, -9, -15, -18, -22, -23, -19, -15, -8,
+ -5, -7, -8, -7, -4, -3, -10, -22, -29, -29, -24, -21, -18, -14, -3, 12,
+ 23, 27, 35, 44, 49, 47, 34, 18, 1, -11, -23, -40, -57, -73, -81, -80,
+ -74, -64, -50, -36, -19, 2, 22, 38, 49, 61, 69, 74, 69, 60, 50, 40,
+ 29, 20, 10, 2, -5, -9, -12, -16, -18, -14, -9, -6, -10, -13, -12, -10,
+ -11, -15, -23, -30, -31, -27, -25, -23, -19, -8, 8, 20, 28, 36, 45, 49,
+ 49, 41, 29, 15, -2, -15, -31, -49, -65, -76, -79, -77, -67, -55, -43, -30,
+ -13, 7, 25, 40, 51, 60, 66, 66, 62, 54, 45, 37, 29, 22, 14, 7,
+ 3, -3, -7, -10, -12, -10, -8, -12, -18, -19, -16, -13, -15, -23, -31, -33,
+ -29, -26, -25, -23, -15, 1, 14, 23, 31, 40, 50, 52, 46, 36, 21, 7,
+ -8, -24, -41, -58, -70, -75, -74, -67, -57, -43, -30, -18, -3, 13, 26, 39,
+ 48, 56, 60, 58, 51, 45, 42, 36, 29, 25, 20, 14, 9, 6, 3, 0,
+ -5, -6, -12, -17, -22, -21, -20, -24, -33, -37, -38, -35, -30, -28, -24, -17,
+ -3, 12, 24, 33, 43, 50, 52, 49, 40, 28, 13, -3, -18, -34, -51, -63,
+ -71, -72, -67, -59, -49, -37, -24, -10, 3, 16, 27, 37, 46, 50, 53, 51,
+ 49, 46, 43, 37, 32, 29, 25, 21, 17, 10, 4, -3, -8, -10, -11, -18,
+ -25, -29, -31, -34, -37, -40, -40, -37, -31, -25, -20, -13, 0, 17, 31, 41,
+ 48, 50, 49, 46, 36, 22, 8, -5, -20, -36, -49, -61, -67, -67, -61, -51,
+ -44, -36, -23, -9, 4, 13, 20, 30, 38, 46, 48, 47, 44, 44, 44, 46,
+ 42, 35, 31, 28, 24, 15, 5, -3, -6, -10, -18, -28, -35, -39, -41, -41,
+ -43, -45, -42, -36, -29, -23, -15, 1, 15, 28, 40, 47, 51, 51, 46, 37,
+ 27, 14, 2, -14, -29, -42, -49, -54, -62, -63, -57, -49, -41, -31, -21, -12,
+ -3, 6, 17, 25, 32, 40, 45, 49, 50, 48, 49, 49, 48, 44, 39, 34,
+ 26, 13, 4, -4, -11, -17, -23, -32, -41, -48, -48, -49, -48, -44, -39, -36,
+ -31, -21, -5, 13, 24, 35, 44, 51, 52, 47, 39, 30, 21, 8, -6, -18,
+ -34, -44, -50, -54, -59, -58, -53, -46, -38, -28, -18, -10, -4, 6, 16, 24,
+ 30, 37, 42, 48, 49, 47, 48, 51, 51, 49, 45, 35, 27, 17, 9, 0,
+ -12, -23, -32, -41, -48, -53, -55, -54, -53, -49, -43, -38, -27, -13, 5, 20,
+ 33, 44, 52, 58, 57, 50, 40, 29, 16, 5, -11, -29, -43, -53, -56, -62,
+ -65, -63, -54, -42, -33, -24, -16, -8, 3, 16, 23, 29, 33, 38, 44, 46,
+ 45, 43, 45, 49, 52, 48, 42, 37, 28, 19, 10, 0, -13, -25, -36, -42,
+ -47, -56, -58, -56, -53, -49, -48, -40, -26, -6, 13, 27, 39, 49, 59, 64,
+ 62, 53, 42, 29, 16, 2, -18, -37, -52, -60, -65, -71, -75, -68, -55, -41,
+ -30, -19, -10, 0, 14, 24, 33, 37, 38, 39, 42, 45, 45, 43, 45, 48,
+ 47, 46, 41, 35, 28, 19, 8, -6, -20, -30, -38, -44, -50, -55, -57, -59,
+ -57, -53, -46, -35, -19, 0, 17, 32, 45, 59, 66, 66, 59, 54, 46, 32,
+ 15, -5, -24, -43, -57, -65, -71, -76, -78, -71, -58, -41, -27, -16, -5, 5,
+ 15, 27, 37, 43, 43, 42, 42, 42, 43, 46, 46, 46, 45, 42, 41, 35,
+ 28, 18, 7, -6, -18, -29, -37, -44, -51, -56, -59, -61, -60, -55, -45, -33,
+ -18, -2, 18, 37, 50, 61, 67, 68, 65, 59, 47, 31, 10, -11, -32, -47,
+ -58, -71, -81, -86, -83, -70, -52, -36, -21, -9, 2, 13, 25, 35, 41, 44,
+ 43, 40, 39, 39, 40, 43, 43, 40, 39, 40, 40, 36, 28, 18, 9, -5,
+ -18, -28, -36, -44, -52, -57, -61, -64, -63, -56, -43, -27, -13, 6, 26, 44,
+ 56, 66, 71, 71, 64, 55, 42, 23, 3, -19, -38, -52, -66, -76, -82, -86,
+ -81, -67, -49, -32, -19, -8, 3, 15, 28, 36, 42, 43, 43, 41, 41, 40,
+ 40, 41, 40, 40, 41, 41, 36, 30, 24, 17, 10, -5, -19, -29, -37, -43,
+ -50, -57, -64, -66, -60, -50, -40, -28, -10, 12, 32, 45, 54, 59, 64, 67,
+ 63, 54, 35, 14, -6, -22, -35, -50, -64, -75, -82, -81, -73, -59, -46, -33,
+ -21, -8, 5, 19, 27, 33, 40, 44, 44, 42, 40, 42, 41, 40, 38, 39,
+ 38, 38, 35, 30, 21, 13, 4, -8, -16, -25, -35, -45, -53, -62, -65, -63,
+ -56, -47, -39, -25, -6, 15, 32, 45, 53, 58, 64, 65, 60, 48, 30, 9,
+ -7, -19, -31, -47, -60, -72, -79, -79, -73, -61, -50, -37, -24, -10, 3, 12,
+ 22, 33, 43, 47, 46, 44, 43, 45, 46, 45, 45, 43, 41, 38, 34, 26,
+ 16, 7, -2, -10, -19, -29, -39, -50, -59, -64, -62, -58, -51, -44, -34, -22,
+ -2, 16, 30, 41, 52, 56, 57, 58, 54, 42, 29, 13, 2, -12, -27, -42,
+ -56, -67, -71, -73, -70, -63, -55, -42, -26, -10, 2, 11, 20, 33, 41, 46,
+ 45, 43, 49, 53, 52, 48, 44, 43, 42, 38, 33, 22, 12, 4, -5, -13,
+ -23, -34, -43, -50, -57, -61, -60, -55, -49, -40, -29, -14, -2, 12, 25, 35,
+ 44, 51, 56, 56, 49, 39, 30, 20, 10, -2, -17, -32, -48, -60, -67, -74,
+ -77, -74, -66, -50, -36, -21, -9, 0, 14, 30, 43, 51, 53, 57, 62, 64,
+ 62, 58, 53, 48, 42, 36, 25, 12, 4, -4, -12, -21, -31, -38, -43, -45,
+ -47, -49, -47, -44, -40, -34, -28, -22, -11, 1, 11, 21, 28, 39, 49, 53,
+ 52, 49, 44, 38, 29, 16, -4, -24, -41, -57, -74, -86, -90, -86, -73, -59,
+ -44, -30, -16, 1, 21, 40, 54, 61, 66, 67, 71, 72, 65, 57, 49, 41,
+ 33, 24, 12, 1, -8, -12, -15, -22, -31, -37, -35, -31, -33, -36, -39, -40,
+ -38, -34, -32, -29, -24, -14, -2, 11, 24, 36, 48, 56, 61, 63, 59, 54,
+ 44, 27, 6, -19, -46, -68, -84, -94, -99, -98, -90, -72, -51, -30, -15, 1,
+ 22, 46, 64, 76, 78, 80, 81, 78, 72, 60, 45, 34, 24, 13, 0, -13,
+ -18, -18, -18, -22, -28, -29, -24, -19, -19, -26, -33, -38, -40, -40, -41, -42,
+ -41, -32, -15, 6, 22, 37, 50, 62, 74, 79, 76, 65, 50, 30, 6, -24,
+ -54, -78, -94, -106, -110, -103, -89, -69, -49, -29, -10, 11, 36, 57, 73, 78,
+ 80, 82, 83, 77, 66, 51, 37, 24, 14, 5, -5, -12, -17, -17, -17, -18,
+ -19, -17, -13, -13, -19, -28, -37, -44, -44, -48, -53, -59, -54, -35, -12, 11,
+ 29, 46, 61, 78, 88, 90, 84, 68, 49, 24, -6, -39, -71, -92, -104, -115,
+ -116, -108, -89, -66, -43, -21, 1, 24, 49, 68, 78, 82, 81, 81, 79, 71,
+ 56, 37, 24, 15, 6, -4, -9, -11, -9, -6, -6, -10, -11, -6, -4, -8,
+ -20, -33, -44, -55, -61, -65, -70, -68, -55, -31, -6, 15, 38, 61, 82, 97,
+ 101, 94, 80, 61, 37, 9, -25, -60, -88, -107, -119, -123, -116, -99, -77, -53,
+ -30, -5, 20, 47, 68, 80, 82, 82, 80, 77, 70, 57, 40, 23, 10, 3,
+ -2, -3, -4, -3, 2, 5, 7, 5, 5, 4, -4, -17, -32, -45, -60, -69,
+ -74, -79, -80, -70, -47, -20, 9, 32, 55, 76, 94, 104, 103, 91, 71, 46,
+ 16, -16, -48, -75, -97, -115, -121, -117, -101, -80, -57, -32, -8, 15, 39, 58,
+ 68, 73, 73, 73, 69, 61, 50, 39, 26, 15, 7, 4, 7, 12, 18, 19,
+ 20, 18, 17, 15, 10, -4, -20, -41, -57, -68, -77, -85, -91, -90, -76, -53,
+ -25, 2, 28, 55, 79, 97, 106, 104, 94, 77, 52, 22, -9, -39, -67, -92,
+ -111, -119, -115, -99, -79, -55, -33, -11, 15, 37, 55, 67, 71, 68, 61, 51,
+ 44, 40, 35, 24, 10, 3, 4, 13, 25, 36, 42, 41, 34, 29, 20, 12,
+ -2, -21, -43, -66, -84, -94, -96, -96, -93, -81, -55, -26, 4, 30, 56, 80,
+ 98, 107, 106, 95, 77, 53, 24, -8, -38, -64, -85, -101, -109, -109, -100, -80,
+ -55, -31, -8, 13, 31, 46, 56, 61, 59, 52, 43, 36, 30, 25, 16, 8,
+ 7, 11, 23, 37, 48, 56, 59, 56, 48, 33, 17, -5, -29, -54, -79, -96,
+ -106, -109, -105, -96, -82, -57, -25, 8, 38, 61, 79, 94, 103, 102, 92, 73,
+ 46, 19, -10, -36, -62, -81, -95, -101, -100, -90, -71, -47, -25, -3, 18, 31,
+ 41, 49, 53, 50, 42, 32, 21, 13, 9, 7, 8, 8, 12, 30, 49, 63,
+ 71, 76, 75, 67, 48, 25, -3, -30, -59, -87, -107, -120, -124, -117, -105, -89,
+ -63, -31, 5, 40, 63, 81, 92, 100, 100, 88, 69, 46, 20, -6, -31, -55,
+ -73, -87, -91, -88, -80, -64, -45, -22, 1, 16, 27, 34, 39, 45, 41, 31,
+ 20, 9, 4, 3, 1, 3, 6, 15, 32, 53, 71, 81, 85, 86, 78, 61,
+ 35, 3, -29, -63, -93, -113, -124, -128, -124, -110, -89, -64, -32, 5, 38, 62,
+ 80, 91, 98, 93, 80, 63, 42, 19, -5, -29, -51, -68, -78, -81, -79, -72,
+ -58, -40, -19, 0, 13, 21, 29, 35, 35, 29, 21, 14, 8, 2, -2, -3,
+ 1, 10, 20, 36, 56, 73, 84, 89, 89, 81, 65, 41, 6, -32, -63, -90,
+ -110, -124, -127, -123, -110, -89, -61, -30, 2, 33, 56, 71, 81, 86, 85, 74,
+ 58, 38, 17, -5, -21, -38, -52, -62, -69, -69, -64, -50, -34, -18, -5, 5,
+ 13, 23, 28, 27, 22, 15, 10, 6, 1, 0, -2, 2, 9, 23, 41, 56,
+ 72, 84, 88, 89, 81, 66, 45, 15, -20, -55, -84, -106, -119, -121, -116, -105,
+ -89, -67, -38, -7, 21, 44, 58, 69, 75, 74, 64, 50, 36, 22, 8, -10,
+ -26, -39, -47, -54, -56, -53, -47, -36, -25, -11, -2, 5, 14, 23, 24, 20,
+ 12, 7, 6, 6, 6, 4, 5, 10, 22, 39, 57, 72, 80, 82, 80, 73,
+ 62, 45, 18, -13, -48, -78, -96, -105, -105, -104, -97, -81, -64, -40, -15, 10,
+ 28, 40, 49, 54, 53, 49, 42, 31, 22, 13, 2, -9, -17, -22, -30, -38,
+ -40, -37, -33, -28, -22, -16, -10, -5, 5, 11, 11, 6, 3, 5, 11, 16,
+ 16, 18, 22, 29, 40, 54, 68, 75, 74, 72, 63, 49, 35, 15, -10, -37,
+ -63, -83, -94, -95, -89, -82, -73, -63, -46, -24, -2, 16, 25, 31, 35, 39,
+ 41, 37, 30, 22, 15, 11, 4, -3, -11, -18, -25, -31, -35, -33, -28, -22,
+ -18, -16, -13, -4, 5, 10, 11, 10, 5, 6, 14, 21, 23, 24, 27, 33,
+ 45, 59, 68, 72, 67, 57, 46, 34, 19, 0, -24, -49, -70, -81, -82, -77,
+ -70, -65, -60, -49, -34, -15, 2, 9, 13, 14, 18, 20, 21, 19, 18, 17,
+ 16, 15, 13, 10, 5, -3, -12, -20, -26, -28, -27, -24, -26, -25, -18, -9,
+ 3, 9, 10, 10, 11, 18, 27, 32, 33, 33, 35, 42, 51, 58, 59, 55,
+ 46, 36, 25, 16, 3, -15, -33, -50, -61, -65, -64, -59, -57, -56, -52, -42,
+ -29, -14, -5, -2, -3, 1, 8, 12, 13, 13, 16, 16, 18, 19, 19, 14,
+ 4, -3, -10, -19, -24, -24, -22, -20, -24, -23, -16, -2, 10, 16, 14, 13,
+ 16, 28, 35, 36, 35, 32, 33, 40, 45, 49, 47, 41, 31, 20, 12, 4,
+ -8, -16, -29, -41, -50, -53, -50, -49, -51, -51, -48, -40, -30, -20, -13, -13,
+ -12, -6, 2, 8, 12, 13, 16, 21, 26, 27, 23, 15, 8, 0, -10, -19,
+ -23, -24, -24, -26, -25, -21, -9, 5, 15, 19, 20, 22, 28, 36, 39, 38,
+ 36, 33, 33, 35, 37, 38, 36, 30, 20, 9, 4, -3, -10, -17, -26, -35,
+ -40, -45, -47, -51, -52, -49, -46, -39, -30, -23, -19, -17, -12, -5, 1, 4,
+ 7, 11, 18, 22, 22, 22, 20, 17, 12, 3, -8, -16, -18, -16, -17, -19,
+ -18, -12, 3, 13, 19, 20, 24, 29, 34, 35, 33, 32, 31, 31, 30, 26,
+ 24, 24, 25, 21, 14, 6, 0, -4, -5, -10, -19, -31, -37, -40, -47, -51,
+ -50, -49, -45, -39, -31, -25, -19, -12, -6, -3, 0, 2, 6, 13, 17, 18,
+ 16, 15, 16, 14, 7, -3, -10, -12, -13, -13, -14, -13, -6, 6, 18, 24,
+ 25, 26, 29, 33, 32, 26, 24, 23, 23, 22, 18, 14, 15, 21, 24, 22,
+ 14, 6, 4, 4, 1, -9, -21, -32, -41, -47, -50, -54, -54, -51, -47, -37,
+ -30, -21, -10, -3, 1, 4, 6, 7, 8, 7, 7, 7, 7, 6, 6, 5,
+ 2, -3, -8, -8, -6, -3, 1, 3, 9, 17, 25, 29, 32, 33, 29, 26,
+ 24, 23, 20, 17, 14, 11, 8, 8, 14, 21, 22, 17, 13, 9, 9, 7,
+ 1, -11, -25, -37, -44, -52, -53, -55, -55, -51, -43, -35, -24, -14, -4, 3,
+ 4, 4, 6, 7, 6, 3, -2, -2, 2, 6, 5, 1, -4, -8, -7, -5,
+ 3, 9, 9, 12, 17, 25, 32, 37, 37, 32, 25, 21, 19, 17, 15, 9,
+ 6, 6, 6, 8, 14, 23, 24, 20, 15, 14, 11, 3, -6, -18, -31, -44,
+ -53, -54, -57, -58, -55, -47, -37, -26, -16, -4, 7, 10, 10, 9, 7, 3,
+ -2, -6, -8, -6, -5, -4, -7, -10, -8, -6, 0, 6, 12, 16, 20, 27,
+ 33, 35, 35, 36, 34, 28, 21, 16, 10, 7, 7, 5, 3, 1, 5, 12,
+ 21, 25, 23, 17, 14, 13, 9, -3, -17, -30, -41, -50, -54, -59, -61, -55,
+ -46, -37, -26, -15, -4, 7, 14, 15, 12, 6, 1, -3, -7, -12, -14, -15,
+ -13, -12, -12, -12, -8, 0, 8, 15, 20, 25, 31, 36, 40, 41, 41, 38,
+ 33, 27, 21, 12, 4, 1, 0, -4, -5, -2, 5, 12, 17, 19, 19, 18,
+ 14, 11, 2, -9, -21, -32, -42, -49, -55, -57, -56, -49, -39, -30, -20, -8,
+ 3, 12, 17, 18, 12, 5, -2, -8, -14, -18, -21, -22, -21, -21, -19, -13,
+ -7, 4, 14, 24, 32, 39, 44, 48, 47, 44, 41, 38, 33, 27, 17, 7,
+ -3, -5, -5, -5, -5, -5, 3, 12, 17, 19, 16, 11, 7, 3, -6, -15,
+ -26, -36, -42, -48, -53, -54, -50, -40, -31, -22, -12, -2, 11, 19, 20, 13,
+ 6, 2, -5, -12, -21, -26, -29, -31, -30, -27, -21, -13, -2, 12, 25, 36,
+ 48, 57, 62, 60, 51, 46, 43, 37, 28, 15, 3, -8, -12, -14, -12, -10,
+ -7, -4, 8, 16, 20, 17, 14, 10, 6, -2, -12, -24, -32, -39, -45, -51,
+ -54, -52, -43, -32, -21, -12, -2, 11, 22, 28, 24, 13, 4, -6, -14, -23,
+ -32, -38, -41, -42, -39, -31, -20, -8, 6, 21, 37, 50, 63, 69, 68, 61,
+ 55, 48, 39, 29, 20, 9, -6, -15, -17, -13, -11, -7, -4, 3, 11, 13,
+ 16, 15, 10, 5, 0, -8, -15, -25, -31, -37, -42, -49, -52, -46, -37, -30,
+ -21, -12, 0, 14, 25, 28, 25, 15, 2, -11, -22, -29, -36, -44, -49, -49,
+ -43, -32, -18, -5, 13, 30, 50, 66, 74, 75, 71, 68, 61, 50, 37, 26,
+ 15, 3, -13, -22, -22, -20, -16, -14, -9, 1, 9, 11, 11, 9, 9, 9,
+ 6, -3, -15, -25, -32, -37, -41, -50, -53, -50, -41, -30, -20, -8, 6, 21,
+ 31, 33, 26, 15, 0, -12, -23, -34, -46, -56, -60, -54, -44, -31, -19, -2,
+ 21, 44, 66, 77, 81, 79, 75, 72, 63, 51, 35, 23, 10, -4, -16, -25,
+ -28, -26, -22, -16, -12, -7, -2, 4, 8, 10, 14, 14, 7, -3, -12, -20,
+ -28, -36, -42, -48, -53, -53, -43, -31, -19, -6, 12, 25, 31, 30, 26, 15,
+ -2, -17, -28, -40, -52, -60, -61, -53, -40, -25, -9, 11, 32, 56, 74, 84,
+ 85, 81, 76, 72, 61, 46, 29, 13, -2, -16, -23, -29, -33, -31, -25, -19,
+ -14, -8, 2, 10, 14, 18, 19, 17, 8, 1, -12, -24, -35, -42, -49, -54,
+ -57, -53, -43, -30, -13, 7, 22, 32, 34, 32, 26, 11, -8, -24, -40, -50,
+ -60, -66, -63, -53, -36, -17, 2, 23, 45, 67, 84, 90, 91, 85, 78, 72,
+ 62, 44, 24, 4, -9, -21, -32, -39, -41, -36, -30, -23, -17, -9, 2, 13,
+ 23, 27, 26, 19, 12, 2, -12, -26, -38, -47, -54, -59, -59, -53, -41, -23,
+ -5, 14, 28, 36, 36, 31, 21, 6, -13, -31, -46, -58, -66, -70, -65, -50,
+ -28, -7, 14, 35, 58, 76, 89, 96, 94, 90, 82, 72, 54, 35, 16, -5,
+ -21, -31, -40, -48, -47, -38, -28, -20, -13, 1, 15, 28, 33, 33, 27, 18,
+ 8, -6, -21, -37, -52, -64, -66, -65, -58, -47, -30, -9, 13, 28, 38, 43,
+ 40, 31, 15, -5, -24, -40, -57, -69, -75, -74, -65, -48, -26, -2, 24, 47,
+ 66, 83, 97, 102, 102, 101, 91, 73, 51, 28, 7, -15, -33, -45, -56, -60,
+ -54, -42, -28, -17, -4, 13, 26, 36, 38, 36, 29, 16, 2, -14, -34, -52,
+ -62, -66, -65, -63, -53, -36, -15, 9, 27, 36, 41, 40, 35, 25, 8, -16,
+ -37, -55, -68, -77, -81, -75, -60, -37, -12, 12, 35, 57, 75, 94, 105, 107,
+ 103, 97, 84, 64, 41, 18, -6, -25, -40, -51, -57, -56, -46, -32, -19, -6,
+ 7, 20, 30, 34, 32, 24, 12, 0, -17, -33, -47, -60, -65, -64, -58, -46,
+ -31, -12, 8, 26, 37, 43, 44, 41, 28, 11, -12, -31, -49, -67, -81, -87,
+ -85, -72, -52, -30, -6, 21, 45, 69, 87, 101, 110, 113, 110, 100, 77, 51,
+ 27, 8, -11, -32, -49, -59, -59, -53, -41, -27, -11, 3, 14, 24, 28, 28,
+ 24, 17, 5, -15, -32, -45, -54, -61, -58, -54, -44, -32, -13, 8, 26, 37,
+ 41, 40, 36, 29, 16, -3, -24, -47, -66, -81, -89, -88, -76, -58, -37, -16,
+ 10, 34, 58, 78, 94, 106, 111, 107, 97, 81, 58, 37, 17, 0, -17, -33,
+ -45, -51, -48, -38, -26, -14, -3, 9, 16, 19, 17, 14, 10, 0, -15, -30,
+ -42, -49, -52, -49, -44, -37, -25, -8, 9, 21, 29, 32, 35, 33, 29, 19,
+ 1, -18, -38, -58, -75, -85, -85, -79, -70, -52, -29, -6, 20, 44, 67, 89,
+ 101, 110, 114, 107, 93, 72, 49, 28, 10, -9, -25, -38, -48, -49, -42, -31,
+ -20, -11, 0, 9, 13, 12, 7, 5, 0, -11, -24, -36, -42, -44, -43, -38,
+ -28, -16, -4, 8, 16, 22, 29, 30, 29, 24, 13, 2, -14, -32, -51, -68,
+ -79, -83, -77, -69, -56, -41, -19, 6, 31, 53, 74, 90, 101, 108, 109, 101,
+ 83, 60, 38, 24, 9, -10, -25, -36, -40, -37, -29, -21, -13, -8, 0, 3,
+ 0, -5, -6, -8, -16, -27, -35, -39, -40, -33, -27, -21, -11, 3, 14, 21,
+ 24, 27, 26, 22, 19, 13, 3, -14, -32, -53, -66, -74, -80, -80, -75, -63,
+ -47, -28, -4, 19, 41, 66, 85, 99, 105, 106, 104, 95, 76, 51, 29, 13,
+ 2, -12, -27, -36, -38, -32, -22, -15, -12, -8, -3, -4, -9, -12, -14, -18,
+ -26, -31, -35, -36, -29, -20, -10, -2, 7, 16, 25, 25, 24, 19, 15, 10,
+ 4, -4, -16, -30, -44, -57, -67, -73, -75, -70, -60, -48, -34, -16, 5, 27,
+ 51, 71, 85, 92, 99, 101, 95, 82, 64, 44, 28, 14, 1, -12, -22, -28,
+ -27, -22, -18, -17, -15, -15, -15, -21, -23, -25, -24, -27, -31, -34, -30, -21,
+ -6, 7, 13, 17, 22, 27, 28, 24, 16, 7, -3, -10, -17, -27, -35, -43,
+ -50, -58, -68, -70, -65, -53, -42, -32, -22, -4, 15, 36, 54, 70, 83, 89,
+ 92, 91, 82, 68, 54, 42, 29, 14, 2, -9, -17, -21, -22, -20, -21, -20,
+ -23, -26, -30, -32, -32, -29, -27, -28, -30, -26, -15, 0, 15, 25, 25, 25,
+ 26, 27, 21, 11, 0, -9, -17, -24, -30, -38, -45, -47, -49, -55, -59, -56,
+ -48, -39, -28, -20, -9, 7, 26, 44, 55, 65, 72, 79, 80, 77, 66, 57,
+ 49, 41, 30, 19, 7, -2, -7, -12, -17, -22, -25, -29, -33, -36, -39, -41,
+ -36, -29, -26, -26, -22, -11, 2, 17, 28, 32, 31, 29, 28, 23, 11, -2,
+ -9, -17, -24, -36, -44, -48, -49, -50, -53, -54, -54, -47, -36, -25, -17, -7,
+ 7, 21, 36, 47, 55, 63, 70, 72, 69, 60, 52, 46, 42, 34, 23, 15,
+ 8, 3, 0, -7, -14, -21, -24, -27, -32, -39, -44, -43, -37, -29, -25, -23,
+ -16, -2, 14, 26, 32, 33, 32, 30, 25, 16, 4, -6, -16, -25, -36, -45,
+ -50, -54, -51, -51, -54, -54, -48, -36, -23, -15, -6, 5, 17, 31, 42, 51,
+ 59, 62, 63, 61, 56, 51, 43, 40, 38, 28, 20, 13, 9, 7, 2, -8,
+ -16, -23, -27, -31, -36, -40, -43, -39, -31, -23, -20, -15, -4, 11, 24, 31,
+ 32, 31, 30, 25, 17, 7, -3, -13, -23, -36, -48, -56, -58, -57, -53, -50,
+ -52, -51, -40, -25, -12, 0, 7, 16, 25, 36, 49, 58, 60, 59, 57, 54,
+ 49, 43, 36, 31, 26, 18, 13, 10, 6, 4, 0, -6, -12, -19, -22, -26,
+ -31, -35, -35, -32, -27, -22, -16, -7, 4, 13, 21, 26, 30, 29, 27, 22,
+ 15, 4, -7, -19, -31, -44, -55, -59, -59, -58, -54, -52, -49, -41, -28, -14,
+ 0, 10, 18, 26, 33, 44, 50, 53, 51, 50, 48, 46, 41, 37, 30, 24,
+ 21, 18, 15, 13, 8, 4, 0, -6, -9, -14, -19, -23, -27, -33, -33, -31,
+ -25, -19, -11, -3, 3, 11, 20, 28, 31, 28, 22, 14, 8, -3, -15, -29,
+ -40, -49, -57, -62, -60, -56, -50, -47, -42, -32, -18, -3, 11, 20, 25, 29,
+ 35, 43, 49, 51, 47, 43, 41, 37, 33, 29, 24, 18, 15, 14, 13, 11,
+ 8, 5, 1, 0, -5, -11, -19, -23, -24, -25, -25, -26, -22, -15, -9, -3,
+ 4, 12, 19, 25, 26, 24, 17, 11, 2, -11, -26, -37, -45, -53, -58, -59,
+ -57, -53, -47, -42, -35, -25, -10, 5, 15, 19, 22, 29, 37, 45, 48, 47,
+ 44, 44, 43, 40, 33, 24, 19, 14, 13, 12, 8, 2, -2, 1, 1, 1,
+ -4, -12, -15, -14, -13, -14, -18, -18, -15, -12, -8, -5, 2, 10, 18, 21,
+ 20, 15, 10, 3, -7, -18, -31, -42, -47, -50, -53, -57, -57, -51, -42, -34,
+ -25, -15, -5, 7, 16, 22, 30, 35, 40, 43, 42, 39, 39, 38, 38, 31,
+ 22, 16, 14, 15, 17, 16, 12, 6, 4, 5, 7, 6, 0, -8, -12, -13,
+ -15, -19, -21, -20, -17, -14, -11, -6, 2, 10, 18, 21, 21, 19, 11, -2,
+ -17, -29, -37, -42, -46, -52, -55, -58, -52, -42, -34, -24, -15, -5, 5, 12,
+ 17, 24, 32, 37, 37, 36, 33, 33, 35, 35, 32, 26, 22, 16, 17, 19,
+ 19, 14, 7, 5, 5, 6, 5, 0, -7, -10, -9, -6, -7, -13, -17, -15,
+ -11, -8, -7, -6, 1, 7, 12, 13, 11, 7, 0, -12, -25, -35, -40, -42,
+ -43, -44, -47, -49, -43, -34, -22, -12, -7, 0, 4, 9, 17, 25, 31, 33,
+ 33, 31, 30, 27, 28, 30, 29, 25, 20, 17, 20, 24, 22, 17, 11, 10,
+ 9, 9, 5, -6, -11, -13, -9, -5, -9, -16, -19, -16, -9, -6, -6, -2,
+ 4, 8, 11, 11, 6, -4, -11, -21, -34, -39, -41, -40, -38, -40, -44, -38,
+ -28, -17, -10, -6, -5, -3, 3, 10, 15, 17, 20, 23, 26, 25, 24, 26,
+ 28, 30, 30, 28, 25, 24, 23, 25, 22, 18, 14, 9, 5, 0, -7, -12,
+ -13, -12, -7, -6, -9, -12, -10, -4, 2, 2, 3, 3, 3, 6, 7, 3,
+ -9, -21, -28, -35, -40, -40, -37, -37, -36, -36, -29, -22, -11, -3, 2, 3,
+ 0, 1, 3, 6, 9, 10, 10, 10, 13, 16, 21, 24, 29, 31, 33, 33,
+ 33, 32, 30, 27, 23, 16, 12, 7, -2, -7, -14, -19, -16, -10, -5, -7,
+ -9, -9, -6, 2, 6, 8, 7, 4, 3, 1, -3, -9, -16, -25, -34, -39,
+ -41, -37, -33, -31, -31, -29, -22, -12, -4, 2, 7, 5, 1, -2, 0, 4,
+ 4, 2, 2, 5, 10, 14, 19, 24, 28, 32, 36, 38, 36, 34, 31, 27,
+ 23, 18, 11, 3, -5, -12, -15, -15, -11, -6, -5, -6, -8, -7, -3, 1,
+ 4, 6, 3, -2, -7, -9, -12, -19, -24, -30, -34, -36, -35, -32, -29, -26,
+ -22, -16, -10, -3, 4, 8, 9, 4, 0, -3, 0, 1, -5, -7, -5, 1,
+ 7, 13, 14, 17, 27, 35, 38, 37, 35, 33, 31, 29, 25, 19, 11, 3,
+ 0, -6, -10, -10, -7, -5, -5, -7, -7, -6, -3, 1, 4, 3, 0, -8,
+ -15, -18, -20, -23, -27, -30, -32, -33, -29, -28, -25, -20, -16, -13, -6, 1,
+ 6, 7, 4, 0, -5, -5, -5, -6, -7, -6, -2, 5, 10, 15, 20, 25,
+ 32, 34, 34, 34, 32, 29, 24, 22, 19, 14, 9, 6, 4, 2, 0, 0,
+ 2, 2, -2, -4, -6, -5, -5, -4, -4, -7, -12, -19, -25, -26, -26, -26,
+ -26, -29, -28, -28, -25, -22, -18, -14, -10, -5, 0, 3, 4, 5, 4, 3,
+ -2, -7, -10, -12, -9, -6, 0, 6, 11, 14, 16, 22, 30, 33, 34, 29,
+ 25, 23, 21, 22, 22, 20, 18, 16, 14, 13, 11, 11, 11, 6, -4, -12,
+ -16, -17, -16, -13, -16, -22, -26, -30, -30, -25, -21, -18, -17, -19, -18, -20,
+ -19, -15, -13, -9, -7, -6, -5, -2, 3, 5, 4, 0, -5, -8, -6, -6,
+ -6, -2, 4, 9, 11, 13, 15, 19, 23, 25, 22, 19, 16, 17, 20, 21,
+ 22, 23, 24, 25, 24, 23, 22, 21, 16, 7, -4, -14, -21, -23, -24, -24,
+ -28, -34, -38, -36, -31, -21, -13, -9, -8, -10, -11, -12, -14, -13, -12, -9,
+ -10, -12, -11, -9, -4, 3, 4, 1, -3, -4, 1, 4, 7, 10, 10, 11,
+ 12, 11, 8, 9, 11, 13, 11, 5, 4, 11, 20, 26, 29, 32, 35, 39,
+ 39, 34, 30, 23, 15, 5, -10, -23, -31, -34, -32, -33, -37, -42, -41, -32,
+ -21, -11, -6, -3, -3, -6, -8, -11, -14, -15, -14, -14, -14, -19, -20, -15,
+ -7, 0, -2, -3, 0, 4, 10, 17, 19, 18, 18, 20, 18, 11, 5, 1,
+ -2, -4, -7, -8, -4, 4, 14, 24, 32, 38, 46, 51, 52, 46, 37, 28,
+ 19, 5, -12, -29, -39, -44, -46, -46, -50, -48, -39, -29, -14, -4, 6, 9,
+ 8, 6, 0, -8, -13, -15, -18, -22, -28, -30, -26, -18, -9, -7, -4, 2,
+ 10, 18, 24, 26, 26, 23, 22, 21, 14, 3, -5, -9, -14, -16, -16, -11,
+ -4, 6, 14, 24, 37, 50, 58, 58, 53, 45, 36, 28, 17, 1, -18, -36,
+ -47, -53, -54, -53, -51, -43, -33, -20, -8, 5, 15, 17, 13, 5, -4, -12,
+ -14, -18, -23, -30, -34, -32, -24, -15, -10, -6, -3, 7, 18, 27, 32, 33,
+ 30, 28, 24, 19, 12, 2, -10, -18, -24, -26, -23, -16, -6, 4, 12, 25,
+ 39, 53, 60, 60, 58, 51, 42, 30, 16, 0, -20, -37, -49, -57, -61, -57,
+ -50, -40, -29, -17, -4, 9, 17, 17, 11, 5, -3, -8, -13, -21, -30, -35,
+ -34, -29, -22, -16, -11, -6, 1, 12, 24, 34, 39, 39, 35, 28, 21, 16,
+ 8, -3, -16, -29, -35, -34, -26, -16, -9, 1, 14, 30, 46, 56, 60, 62,
+ 59, 57, 46, 32, 15, -2, -17, -35, -51, -61, -61, -55, -46, -39, -30, -19,
+ -4, 10, 14, 13, 7, 3, -2, -6, -15, -24, -31, -33, -31, -26, -23, -19,
+ -11, -2, 6, 17, 30, 38, 41, 39, 34, 25, 18, 14, 6, -9, -24, -34,
+ -38, -34, -28, -18, -9, 0, 14, 32, 44, 52, 58, 63, 66, 59, 45, 31,
+ 18, 4, -17, -36, -53, -60, -59, -54, -46, -39, -30, -18, -3, 6, 8, 6,
+ 3, 1, -3, -11, -22, -29, -28, -23, -20, -20, -18, -10, -2, 7, 17, 27,
+ 34, 37, 38, 33, 26, 19, 15, 11, 0, -17, -31, -39, -40, -34, -27, -20,
+ -11, 1, 16, 31, 43, 52, 59, 67, 70, 62, 47, 32, 19, 4, -18, -39,
+ -53, -60, -57, -51, -44, -37, -30, -17, -6, 1, 2, 1, 0, -2, -7, -15,
+ -23, -27, -25, -19, -16, -15, -12, -4, 5, 15, 25, 33, 37, 34, 31, 27,
+ 22, 17, 11, 2, -11, -25, -35, -41, -41, -34, -23, -13, -4, 6, 18, 31,
+ 43, 54, 61, 65, 62, 53, 44, 34, 22, 2, -20, -38, -47, -50, -47, -43,
+ -42, -41, -32, -19, -13, -11, -10, -7, -5, -5, -9, -14, -18, -17, -12, -9,
+ -8, -6, 1, 6, 12, 16, 21, 25, 25, 23, 19, 18, 14, 11, 8, 0,
+ -10, -23, -34, -36, -32, -24, -16, -12, -6, 4, 15, 30, 42, 52, 59, 60,
+ 58, 53, 46, 39, 27, 5, -19, -35, -43, -44, -43, -45, -49, -48, -39, -31,
+ -27, -24, -19, -11, -6, -3, -4, -6, -8, -5, 3, 5, 7, 6, 7, 9,
+ 12, 13, 15, 14, 12, 11, 11, 9, 8, 5, 4, 0, -12, -22, -28, -26,
+ -21, -17, -13, -10, -5, 4, 14, 22, 32, 44, 56, 61, 59, 56, 48, 38,
+ 25, 7, -10, -24, -33, -38, -44, -50, -51, -47, -41, -41, -41, -37, -26, -14,
+ -6, 0, -2, -3, 5, 13, 19, 21, 16, 12, 9, 9, 10, 7, 3, 2,
+ 2, 1, -2, 0, 3, 4, 1, -4, -12, -16, -16, -9, -9, -10, -9, -5,
+ 2, 7, 11, 17, 27, 39, 51, 54, 52, 52, 49, 42, 28, 10, -4, -15,
+ -25, -36, -48, -56, -58, -56, -52, -53, -54, -45, -28, -11, -2, 3, 8, 15,
+ 24, 30, 34, 30, 22, 16, 12, 6, -4, -9, -9, -8, -12, -14, -12, -5,
+ 3, 4, 2, -3, -4, 0, 3, 2, -4, -6, -6, -5, -4, -5, -3, 8,
+ 21, 36, 44, 50, 55, 58, 55, 45, 33, 20, 5, -11, -27, -43, -55, -60,
+ -61, -62, -64, -66, -58, -40, -20, -6, 3, 8, 16, 26, 34, 39, 38, 30,
+ 21, 11, 2, -9, -14, -13, -13, -15, -16, -14, -6, 1, 4, 4, 3, 4,
+ 7, 10, 10, 5, -3, -7, -8, -9, -12, -14, -11, 0, 13, 28, 40, 51,
+ 58, 61, 60, 56, 47, 33, 15, -8, -28, -44, -55, -62, -72, -81, -83, -74,
+ -58, -39, -21, -6, 8, 18, 30, 40, 47, 49, 44, 33, 19, 6, -6, -14,
+ -19, -23, -26, -24, -19, -13, -5, -2, 2, 5, 8, 11, 14, 13, 9, 2,
+ -4, -8, -12, -15, -19, -18, -13, -3, 14, 30, 44, 53, 62, 66, 66, 59,
+ 48, 33, 12, -10, -31, -46, -58, -71, -79, -84, -81, -71, -54, -34, -14, 1,
+ 14, 26, 37, 44, 48, 49, 41, 29, 12, -3, -13, -17, -19, -24, -26, -22,
+ -16, -8, -3, -2, 3, 6, 10, 13, 12, 10, 6, 2, -4, -11, -18, -22,
+ -22, -19, -14, -3, 13, 30, 46, 61, 68, 71, 70, 64, 52, 32, 10, -12,
+ -31, -51, -67, -81, -88, -91, -84, -69, -51, -32, -12, 8, 25, 37, 43, 47,
+ 52, 50, 40, 23, 5, -8, -13, -18, -23, -28, -26, -19, -12, -6, -4, -2,
+ 2, 6, 11, 11, 5, 3, 4, 1, -9, -17, -21, -23, -22, -19, -14, 0,
+ 17, 37, 54, 65, 70, 75, 76, 67, 50, 30, 6, -15, -35, -56, -75, -88,
+ -93, -88, -78, -64, -47, -26, -3, 17, 31, 37, 42, 46, 48, 42, 27, 10,
+ 0, -3, -7, -14, -21, -21, -13, -4, 1, -2, -3, 1, 5, 7, 4, -3,
+ -8, -7, -7, -14, -19, -22, -23, -21, -20, -16, -6, 12, 32, 51, 63, 70,
+ 76, 78, 75, 63, 44, 20, -5, -26, -46, -67, -83, -94, -93, -83, -69, -55,
+ -40, -17, 8, 25, 34, 38, 43, 48, 45, 35, 20, 8, 2, 3, -2, -12,
+ -18, -15, -8, 0, 0, -5, -6, -4, -3, -5, -11, -15, -14, -12, -13, -16,
+ -19, -20, -20, -16, -10, -2, 11, 24, 42, 57, 64, 70, 73, 72, 64, 48,
+ 26, 4, -15, -35, -50, -68, -81, -88, -81, -68, -55, -44, -29, -10, 9, 22,
+ 25, 30, 37, 38, 35, 24, 14, 11, 13, 14, 9, 0, -5, -3, 3, 4,
+ -2, -10, -15, -15, -15, -19, -25, -24, -20, -18, -19, -20, -18, -16, -13, -9,
+ 1, 12, 25, 37, 53, 63, 69, 74, 73, 69, 56, 37, 15, -6, -25, -42,
+ -59, -75, -82, -81, -72, -61, -50, -35, -17, -2, 13, 20, 27, 31, 34, 34,
+ 28, 19, 14, 13, 15, 14, 8, 4, 3, 5, 5, 1, -6, -15, -18, -22,
+ -27, -33, -34, -31, -25, -24, -20, -19, -17, -10, -2, 9, 18, 28, 39, 51,
+ 60, 67, 71, 72, 67, 53, 35, 16, -4, -21, -40, -57, -70, -76, -74, -65,
+ -55, -44, -34, -21, -7, 6, 15, 18, 20, 24, 24, 21, 16, 15, 16, 17,
+ 17, 16, 13, 12, 13, 13, 9, 0, -12, -17, -22, -31, -40, -43, -40, -35,
+ -30, -26, -24, -20, -11, -2, 9, 19, 29, 39, 46, 54, 60, 66, 67, 66,
+ 58, 41, 21, 5, -11, -29, -47, -62, -68, -68, -65, -57, -49, -39, -27, -13,
+ -2, 6, 11, 18, 23, 24, 21, 19, 19, 21, 21, 18, 15, 11, 13, 15,
+ 15, 10, -2, -8, -14, -21, -30, -39, -44, -44, -40, -33, -29, -27, -21, -12,
+ -3, 6, 16, 28, 40, 48, 54, 56, 59, 61, 62, 57, 44, 28, 12, -3,
+ -22, -40, -55, -64, -63, -61, -56, -51, -41, -29, -15, -6, 1, 8, 15, 20,
+ 20, 18, 17, 18, 23, 23, 20, 17, 15, 18, 20, 20, 15, 4, -5, -11,
+ -20, -32, -43, -49, -48, -43, -36, -32, -29, -21, -13, 0, 11, 20, 30, 38,
+ 46, 50, 51, 53, 56, 53, 48, 41, 30, 19, 5, -10, -26, -42, -50, -56,
+ -57, -56, -53, -46, -38, -27, -18, -10, -2, 8, 16, 19, 24, 24, 22, 23,
+ 25, 23, 17, 16, 15, 16, 14, 10, 3, -5, -11, -20, -28, -35, -42, -44,
+ -42, -35, -29, -25, -19, -11, 0, 10, 20, 26, 31, 38, 45, 48, 46, 46,
+ 44, 41, 37, 30, 22, 13, 1, -15, -27, -36, -44, -49, -51, -52, -49, -44,
+ -37, -27, -20, -12, 1, 10, 19, 23, 28, 29, 28, 28, 24, 19, 17, 16,
+ 15, 14, 10, 4, -3, -10, -15, -23, -31, -36, -41, -41, -39, -32, -24, -19,
+ -11, -3, 5, 15, 24, 31, 36, 42, 45, 44, 41, 37, 33, 31, 29, 23,
+ 14, 2, -8, -16, -22, -31, -40, -44, -46, -46, -46, -44, -37, -28, -20, -10,
+ 2, 11, 20, 28, 32, 32, 29, 26, 22, 19, 17, 14, 12, 11, 8, 2,
+ -5, -14, -20, -24, -30, -34, -37, -38, -36, -30, -21, -14, -6, 2, 11, 19,
+ 26, 30, 34, 41, 44, 42, 38, 32, 27, 25, 24, 21, 11, 1, -9, -16,
+ -25, -34, -40, -43, -45, -48, -50, -49, -40, -27, -15, -6, 4, 15, 27, 36,
+ 40, 37, 32, 27, 22, 15, 11, 10, 8, 6, 0, -8, -14, -16, -17, -18,
+ -24, -31, -33, -33, -27, -22, -17, -10, -4, 6, 13, 17, 22, 27, 33, 38,
+ 39, 37, 35, 33, 31, 27, 23, 19, 11, 3, -7, -20, -30, -38, -42, -42,
+ -46, -53, -58, -53, -41, -27, -13, -2, 10, 19, 30, 39, 43, 38, 29, 23,
+ 18, 12, 8, 6, 6, 4, -3, -8, -12, -13, -10, -12, -17, -24, -25, -23,
+ -23, -23, -19, -12, -4, 2, 5, 9, 14, 22, 32, 37, 39, 39, 37, 37,
+ 33, 28, 27, 21, 12, 0, -14, -25, -33, -38, -43, -48, -54, -60, -59, -48,
+ -36, -20, -8, 2, 12, 26, 39, 44, 40, 32, 27, 23, 16, 8, 3, 3,
+ 2, 1, -4, -9, -9, -6, -6, -8, -13, -16, -18, -21, -22, -21, -16, -7,
+ -2, 0, -2, 2, 13, 25, 30, 34, 34, 34, 34, 33, 33, 31, 26, 21,
+ 11, -3, -15, -25, -31, -37, -48, -57, -62, -63, -56, -46, -35, -25, -12, 5,
+ 18, 32, 40, 40, 36, 32, 29, 22, 15, 7, 3, 0, 0, 0, 1, -2,
+ -2, 0, 0, -3, -4, -7, -13, -22, -28, -25, -17, -10, -10, -11, -10, -4,
+ 12, 26, 36, 39, 40, 41, 40, 37, 35, 33, 28, 19, 3, -11, -22, -30,
+ -37, -46, -56, -63, -65, -59, -52, -43, -29, -17, -4, 10, 23, 32, 36, 36,
+ 34, 29, 24, 19, 12, 5, -2, 0, 4, 7, 10, 9, 6, 5, 5, 5,
+ 0, -10, -20, -26, -29, -26, -20, -18, -19, -17, -9, 3, 16, 28, 36, 40,
+ 42, 43, 41, 40, 36, 33, 26, 16, 3, -10, -21, -31, -42, -53, -61, -65,
+ -63, -58, -52, -41, -31, -18, -4, 9, 21, 26, 29, 30, 31, 31, 28, 21,
+ 12, 6, 5, 10, 13, 13, 14, 9, 8, 7, 5, 0, -8, -17, -24, -28,
+ -27, -23, -17, -14, -12, -8, 2, 15, 26, 32, 36, 39, 38, 37, 36, 33,
+ 28, 21, 16, 10, 1, -13, -25, -34, -41, -50, -59, -62, -62, -53, -44, -37,
+ -28, -19, -6, 7, 14, 18, 22, 26, 28, 28, 21, 13, 6, 6, 15, 19,
+ 21, 20, 20, 18, 16, 13, 7, -3, -12, -21, -27, -31, -30, -24, -15, -11,
+ -8, 0, 10, 23, 29, 32, 34, 34, 34, 33, 32, 27, 23, 20, 17, 10,
+ -2, -15, -25, -34, -43, -52, -61, -63, -58, -49, -43, -41, -33, -22, -9, 3,
+ 11, 17, 21, 26, 30, 28, 23, 17, 15, 18, 22, 22, 20, 21, 21, 18,
+ 12, 4, -5, -11, -16, -22, -28, -32, -24, -14, -7, -5, 1, 11, 20, 27,
+ 30, 26, 25, 29, 30, 29, 22, 17, 18, 22, 20, 9, -8, -18, -25, -31,
+ -40, -53, -60, -58, -54, -46, -45, -42, -32, -20, -10, -2, 5, 12, 19, 25,
+ 27, 22, 18, 18, 21, 24, 25, 22, 24, 26, 27, 22, 10, 0, -7, -9,
+ -12, -21, -28, -28, -20, -9, -4, -2, 5, 14, 22, 24, 21, 15, 18, 24,
+ 28, 24, 19, 21, 26, 30, 22, 7, -6, -15, -23, -34, -50, -61, -66, -61,
+ -52, -50, -49, -45, -36, -22, -10, 1, 11, 15, 20, 26, 26, 24, 21, 21,
+ 27, 28, 24, 21, 22, 26, 24, 16, 5, -5, -7, -5, -11, -17, -22, -17,
+ -7, 0, 1, 4, 9, 16, 19, 18, 13, 12, 16, 22, 24, 23, 23, 28,
+ 33, 27, 16, 2, -12, -23, -33, -45, -57, -64, -64, -55, -51, -52, -49, -39,
+ -25, -13, -6, 1, 6, 12, 16, 18, 20, 18, 20, 25, 28, 28, 29, 31,
+ 36, 37, 28, 15, 7, 3, 0, -4, -14, -21, -23, -16, -7, -4, -3, 1,
+ 10, 16, 17, 10, 7, 9, 18, 24, 24, 24, 28, 34, 34, 26, 12, -3,
+ -15, -26, -40, -53, -61, -65, -62, -59, -57, -55, -49, -39, -27, -18, -6, 3,
+ 8, 14, 17, 21, 25, 26, 27, 28, 30, 32, 32, 31, 32, 28, 22, 14,
+ 6, 3, 0, -3, -8, -12, -12, -5, 0, 2, 1, 3, 6, 11, 11, 7,
+ 4, 6, 13, 20, 24, 28, 31, 32, 28, 19, 7, -7, -20, -32, -44, -53,
+ -58, -58, -55, -54, -53, -50, -46, -40, -27, -14, -6, -6, -5, 0, 8, 16,
+ 20, 23, 25, 30, 37, 42, 43, 41, 39, 34, 28, 18, 9, 4, 3, 0,
+ -10, -13, -12, -10, -5, 1, 1, 0, 4, 8, 7, 5, 6, 11, 19, 23,
+ 27, 32, 33, 27, 20, 10, 0, -15, -30, -41, -49, -52, -54, -55, -55, -53,
+ -50, -45, -40, -32, -24, -16, -11, -10, -8, -3, 6, 13, 17, 21, 29, 37,
+ 43, 48, 47, 43, 38, 35, 30, 19, 11, 7, 2, -5, -9, -9, -5, 1,
+ 1, 0, -2, 1, 3, 6, 5, 4, 5, 10, 16, 20, 24, 27, 25, 18,
+ 10, 3, -9, -21, -31, -39, -44, -47, -47, -44, -46, -48, -48, -45, -39, -36,
+ -30, -26, -25, -23, -19, -9, 4, 14, 24, 32, 41, 48, 54, 56, 57, 52,
+ 47, 40, 28, 17, 10, 4, -3, -8, -10, -8, -6, -5, -5, -5, -3, 0,
+ 3, 4, 4, 5, 7, 12, 19, 26, 27, 24, 18, 12, 5, -3, -12, -24,
+ -34, -43, -46, -48, -48, -46, -46, -45, -44, -42, -38, -33, -29, -26, -26, -22,
+ -14, -5, 5, 13, 23, 32, 40, 47, 52, 56, 57, 55, 52, 47, 36, 27,
+ 19, 11, 3, -5, -6, -8, -10, -13, -15, -14, -13, -11, -6, 1, 4, 7,
+ 11, 17, 21, 26, 28, 26, 19, 10, 2, -7, -17, -26, -36, -41, -45, -47,
+ -45, -44, -44, -41, -39, -40, -40, -37, -33, -34, -32, -26, -18, -9, 2, 12,
+ 26, 40, 47, 56, 63, 66, 66, 63, 60, 53, 40, 27, 14, 3, -8, -11,
+ -12, -15, -19, -19, -18, -15, -12, -8, 0, 6, 11, 13, 14, 17, 23, 29,
+ 27, 18, 9, 1, -7, -16, -25, -35, -43, -49, -47, -44, -43, -42, -40, -36,
+ -34, -33, -33, -33, -35, -34, -30, -23, -16, -9, 2, 14, 27, 39, 49, 58,
+ 66, 69, 68, 66, 61, 53, 45, 32, 18, 1, -11, -14, -17, -17, -20, -23,
+ -21, -17, -13, -3, 4, 10, 13, 14, 17, 18, 21, 24, 22, 15, 6, -4,
+ -12, -22, -28, -38, -49, -51, -48, -45, -43, -40, -38, -36, -35, -34, -33, -33,
+ -34, -35, -33, -29, -18, -6, 6, 19, 33, 46, 59, 71, 78, 78, 78, 74,
+ 67, 54, 39, 22, 6, -8, -16, -22, -25, -25, -26, -22, -17, -12, -3, 6,
+ 15, 17, 16, 14, 14, 16, 17, 16, 13, 6, -2, -11, -20, -27, -34, -43,
+ -49, -48, -44, -41, -39, -36, -33, -34, -33, -34, -32, -33, -35, -35, -30, -21,
+ -11, 0, 9, 23, 38, 52, 65, 74, 76, 76, 74, 70, 62, 47, 28, 13,
+ 2, -6, -14, -21, -23, -20, -18, -16, -13, -7, 1, 8, 10, 11, 9, 11,
+ 11, 13, 15, 16, 13, 8, -2, -11, -19, -27, -37, -47, -52, -51, -48, -46,
+ -43, -40, -38, -36, -35, -35, -38, -38, -33, -27, -21, -16, -7, 6, 21, 36,
+ 49, 61, 70, 75, 79, 78, 73, 62, 49, 35, 22, 8, -3, -12, -17, -20,
+ -18, -14, -13, -15, -12, -5, 4, 7, 8, 8, 9, 8, 9, 11, 14, 14,
+ 10, 4, -6, -15, -25, -35, -41, -48, -54, -53, -47, -42, -38, -37, -35, -31,
+ -31, -30, -30, -29, -26, -24, -19, -12, -2, 10, 22, 35, 48, 60, 70, 76,
+ 76, 73, 67, 57, 44, 28, 14, 5, -3, -8, -13, -14, -13, -10, -11, -11,
+ -8, -2, 4, 6, 5, 5, 5, 6, 10, 11, 10, 8, 4, -2, -9, -15,
+ -24, -35, -44, -50, -52, -49, -45, -42, -42, -40, -37, -37, -37, -33, -29, -26,
+ -24, -21, -16, -7, 6, 18, 30, 41, 54, 66, 75, 77, 79, 76, 67, 53,
+ 37, 21, 8, 2, -5, -10, -14, -14, -12, -12, -11, -10, -5, 4, 7, 4,
+ 1, 2, 6, 9, 9, 7, 5, 4, 0, -7, -14, -23, -32, -37, -43, -48,
+ -50, -51, -47, -42, -34, -32, -32, -34, -32, -26, -21, -18, -17, -14, -11, -4,
+ 5, 13, 24, 40, 55, 67, 72, 74, 76, 75, 67, 51, 37, 23, 11, 4,
+ -4, -11, -15, -17, -17, -16, -14, -13, -8, -2, 1, 1, 1, 3, 5, 9,
+ 7, 5, 4, 4, 3, -5, -14, -24, -32, -38, -41, -47, -52, -53, -49, -41,
+ -35, -34, -35, -33, -29, -24, -19, -13, -10, -9, -7, -2, 8, 17, 29, 43,
+ 56, 67, 74, 75, 75, 72, 64, 53, 38, 23, 13, 4, -5, -12, -16, -20,
+ -21, -18, -16, -14, -11, -8, -5, -3, 0, 2, 6, 6, 6, 5, 5, 6,
+ 3, -6, -19, -31, -37, -41, -45, -50, -52, -53, -48, -39, -32, -30, -26, -25,
+ -22, -16, -10, -7, -11, -10, -8, -2, 6, 17, 31, 45, 58, 68, 78, 80,
+ 76, 70, 65, 55, 37, 18, 5, -4, -10, -19, -25, -26, -24, -18, -13, -11,
+ -9, -6, -2, 4, 6, 5, 4, 3, 4, 2, 1, -3, -4, -11, -20, -29,
+ -38, -43, -45, -48, -51, -48, -44, -39, -35, -34, -31, -30, -25, -15, -8, -8,
+ -10, -8, 1, 11, 22, 33, 42, 54, 66, 76, 80, 75, 70, 66, 59, 42,
+ 23, 6, -4, -9, -17, -22, -27, -25, -19, -9, -7, -8, -5, 0, 4, 5,
+ 2, -2, -5, -5, -4, -6, -7, -6, -10, -16, -21, -29, -34, -37, -38, -41,
+ -44, -42, -36, -32, -33, -37, -39, -35, -27, -17, -12, -13, -12, -6, 6, 22,
+ 36, 44, 54, 66, 77, 82, 80, 75, 68, 59, 47, 29, 10, -3, -13, -18,
+ -23, -26, -27, -24, -16, -9, -5, -4, -2, 3, 6, 4, -2, -6, -8, -7,
+ -8, -8, -9, -10, -13, -16, -22, -29, -31, -30, -34, -36, -36, -32, -28, -30,
+ -36, -39, -38, -33, -28, -24, -24, -22, -15, -2, 13, 26, 38, 53, 67, 78,
+ 84, 88, 85, 81, 71, 59, 39, 13, -5, -14, -19, -26, -32, -34, -30, -22,
+ -13, -5, 0, 6, 7, 10, 8, 2, -4, -10, -12, -15, -18, -20, -20, -20,
+ -22, -24, -26, -26, -23, -23, -23, -24, -21, -17, -18, -25, -31, -35, -37, -37,
+ -36, -33, -29, -22, -10, 5, 19, 31, 45, 62, 75, 84, 86, 88, 87, 80,
+ 66, 45, 22, 4, -9, -18, -26, -34, -37, -33, -24, -15, -9, -3, 6, 13,
+ 15, 11, 2, -5, -10, -13, -20, -25, -27, -26, -25, -26, -29, -29, -23, -18,
+ -16, -19, -18, -15, -9, -6, -12, -21, -32, -36, -36, -40, -39, -36, -30, -21,
+ -10, 6, 20, 36, 55, 69, 79, 85, 90, 92, 88, 75, 56, 33, 12, -3,
+ -15, -24, -33, -37, -35, -28, -20, -12, -4, 6, 14, 18, 16, 9, 0, -8,
+ -15, -19, -27, -33, -35, -34, -34, -36, -36, -29, -19, -10, -10, -10, -8, -4,
+ -2, -2, -8, -18, -28, -36, -43, -48, -46, -36, -25, -14, -4, 10, 27, 46,
+ 65, 78, 86, 89, 87, 85, 78, 64, 42, 19, 0, -12, -20, -29, -34, -36,
+ -30, -22, -12, -6, 1, 8, 16, 18, 13, 2, -7, -12, -17, -24, -33, -38,
+ -39, -36, -36, -36, -34, -26, -18, -11, -7, -6, -5, -5, 1, 1, -5, -14,
+ -24, -33, -41, -42, -37, -28, -19, -10, 3, 16, 30, 47, 64, 76, 83, 85,
+ 83, 78, 69, 54, 37, 17, -2, -14, -21, -28, -32, -32, -27, -18, -11, -6,
+ 2, 12, 18, 16, 5, -5, -11, -14, -19, -30, -40, -47, -45, -38, -36, -34,
+ -33, -26, -15, -6, -2, 1, 1, 3, 5, 4, -3, -13, -26, -35, -41, -39,
+ -33, -23, -13, -5, 7, 21, 36, 53, 68, 79, 82, 78, 72, 66, 59, 47,
+ 30, 10, -6, -16, -21, -22, -25, -27, -25, -18, -10, -4, 4, 10, 11, 6,
+ -4, -11, -13, -18, -25, -34, -43, -45, -41, -36, -34, -32, -27, -19, -10, -5,
+ 0, 2, 5, 5, 5, 1, -7, -16, -25, -33, -38, -35, -25, -13, -6, 0,
+ 11, 27, 46, 60, 69, 70, 68, 69, 68, 62, 52, 39, 22, 8, -2, -11,
+ -18, -21, -22, -23, -24, -17, -10, -5, 1, 5, 5, 2, -3, -5, -9, -17,
+ -28, -41, -46, -48, -43, -42, -42, -39, -30, -19, -9, -3, 6, 11, 15, 16,
+ 12, 5, -2, -12, -23, -33, -37, -34, -25, -18, -8, 1, 15, 32, 48, 62,
+ 69, 68, 67, 63, 62, 58, 50, 34, 15, -2, -8, -10, -11, -16, -24, -24,
+ -19, -12, -6, -2, 2, 3, 1, 0, -6, -10, -17, -26, -37, -46, -48, -45,
+ -44, -42, -38, -32, -22, -12, -6, 4, 10, 14, 16, 15, 11, 5, -2, -11,
+ -23, -31, -29, -22, -18, -16, -11, 3, 17, 34, 50, 56, 59, 61, 63, 62,
+ 59, 53, 44, 32, 16, 3, -8, -9, -13, -20, -26, -27, -21, -16, -11, -9,
+ -6, 1, 7, 7, 0, -10, -15, -20, -30, -39, -45, -48, -48, -46, -41, -36,
+ -29, -20, -11, 3, 11, 14, 19, 21, 19, 15, 6, -3, -13, -18, -18, -17,
+ -20, -19, -12, 2, 15, 26, 36, 43, 51, 59, 61, 61, 57, 54, 49, 37,
+ 21, 9, 1, -8, -17, -25, -29, -28, -27, -23, -19, -13, -5, 2, 8, 5,
+ -4, -11, -13, -17, -27, -40, -49, -53, -53, -50, -44, -37, -28, -19, -7, 8,
+ 18, 22, 26, 26, 23, 17, 10, 0, -8, -15, -20, -25, -23, -19, -11, 0,
+ 13, 25, 34, 44, 54, 60, 62, 60, 58, 56, 52, 38, 21, 6, -6, -16,
+ -26, -32, -33, -30, -26, -24, -17, -8, 3, 13, 16, 10, 1, -7, -12, -18,
+ -34, -50, -61, -63, -58, -54, -50, -45, -33, -13, 6, 21, 27, 34, 37, 36,
+ 30, 20, 11, -2, -13, -24, -32, -37, -34, -24, -10, 2, 12, 25, 41, 55,
+ 61, 64, 65, 67, 64, 59, 48, 32, 16, 0, -12, -20, -27, -33, -33, -31,
+ -28, -23, -12, 0, 10, 13, 9, 2, -2, -7, -13, -25, -41, -56, -65, -66,
+ -62, -56, -53, -42, -25, -5, 13, 24, 34, 39, 42, 39, 32, 22, 11, -2,
+ -15, -27, -36, -37, -31, -22, -13, 0, 12, 27, 43, 55, 61, 64, 65, 63,
+ 60, 53, 42, 28, 10, -6, -20, -27, -28, -28, -25, -23, -20, -13, -2, 11,
+ 16, 14, 8, 2, -6, -14, -25, -38, -53, -67, -73, -73, -67, -58, -46, -32,
+ -14, 6, 24, 36, 43, 45, 44, 39, 30, 18, 5, -11, -25, -35, -39, -37,
+ -28, -17, -7, 4, 16, 32, 48, 58, 64, 66, 63, 61, 56, 46, 31, 18,
+ 3, -13, -21, -25, -23, -19, -15, -11, -7, -2, 6, 13, 14, 8, -3, -12,
+ -21, -32, -40, -55, -70, -78, -75, -67, -56, -47, -29, -12, 10, 29, 40, 47,
+ 49, 48, 43, 31, 15, 0, -16, -29, -39, -45, -41, -32, -18, -6, 3, 13,
+ 27, 43, 57, 64, 65, 61, 58, 52, 43, 32, 18, 6, -9, -18, -20, -17,
+ -12, -4, 1, 3, 7, 12, 17, 16, 9, -3, -15, -27, -39, -48, -60, -72,
+ -82, -82, -73, -58, -45, -33, -14, 7, 28, 42, 49, 51, 51, 48, 38, 22,
+ 2, -16, -30, -37, -42, -45, -40, -26, -11, 3, 11, 20, 34, 52, 65, 69,
+ 64, 54, 46, 38, 28, 16, 4, -11, -18, -16, -10, -4, 3, 13, 21, 23,
+ 22, 20, 18, 11, -2, -16, -34, -47, -59, -70, -76, -83, -83, -76, -64, -48,
+ -31, -12, 10, 30, 42, 50, 53, 51, 46, 37, 25, 8, -13, -30, -41, -45,
+ -43, -35, -23, -15, -5, 8, 17, 28, 40, 56, 64, 63, 55, 45, 34, 24,
+ 14, 7, -4, -12, -13, -9, -2, 11, 23, 31, 33, 33, 31, 26, 17, 4,
+ -14, -31, -48, -62, -75, -86, -90, -87, -79, -68, -54, -39, -18, 4, 23, 39,
+ 47, 52, 52, 47, 39, 29, 15, -5, -23, -35, -41, -40, -34, -26, -16, -8,
+ 2, 12, 22, 30, 43, 52, 58, 54, 45, 36, 25, 16, 7, -2, -7, -8,
+ -3, 4, 13, 24, 32, 39, 42, 39, 30, 19, 6, -10, -25, -44, -62, -79,
+ -88, -90, -85, -78, -70, -59, -45, -24, 0, 20, 35, 43, 48, 48, 46, 42,
+ 33, 20, 2, -19, -32, -38, -41, -37, -29, -19, -8, 1, 11, 19, 26, 35,
+ 43, 48, 48, 41, 35, 26, 16, 7, 0, 0, 3, 6, 10, 16, 24, 32,
+ 40, 44, 43, 33, 21, 8, -5, -19, -37, -54, -72, -84, -87, -81, -75, -68,
+ -61, -50, -33, -12, 8, 22, 29, 34, 40, 42, 41, 35, 24, 13, -2, -16,
+ -27, -33, -33, -27, -22, -17, -13, -4, 9, 18, 25, 31, 36, 42, 44, 40,
+ 32, 21, 12, 9, 7, 8, 9, 13, 17, 23, 29, 35, 40, 40, 35, 26,
+ 13, 0, -11, -24, -41, -60, -74, -80, -79, -73, -68, -63, -56, -43, -27, -10,
+ 6, 18, 24, 29, 34, 38, 37, 30, 20, 9, -3, -14, -24, -27, -27, -25,
+ -23, -18, -9, 2, 10, 19, 25, 30, 37, 40, 41, 33, 22, 16, 10, 6,
+ 6, 10, 16, 21, 28, 31, 35, 38, 44, 45, 34, 19, 5, -5, -17, -33,
+ -52, -68, -76, -78, -75, -71, -67, -62, -51, -37, -20, -7, 4, 13, 21, 29,
+ 34, 36, 33, 26, 17, 10, 0, -8, -13, -19, -21, -21, -17, -11, -6, 4,
+ 10, 13, 19, 25, 30, 31, 28, 20, 14, 10, 7, 7, 11, 20, 26, 32,
+ 36, 39, 41, 44, 46, 41, 30, 13, 0, -13, -27, -44, -62, -72, -74, -74,
+ -74, -71, -66, -57, -47, -32, -19, -9, 2, 14, 24, 28, 32, 34, 33, 25,
+ 17, 9, 2, -5, -10, -17, -22, -18, -13, -7, 0, 4, 10, 17, 23, 26,
+ 25, 21, 15, 9, 9, 7, 4, 7, 16, 27, 34, 39, 43, 48, 49, 52,
+ 49, 39, 24, 9, -3, -17, -32, -52, -67, -75, -75, -71, -70, -70, -66, -56,
+ -43, -31, -21, -12, -2, 11, 21, 27, 30, 33, 31, 29, 22, 15, 8, 0,
+ -6, -13, -14, -14, -11, -5, 0, 4, 8, 13, 16, 18, 15, 12, 10, 7,
+ 7, 6, 7, 14, 24, 36, 44, 46, 46, 49, 52, 53, 47, 35, 21, 9,
+ -6, -23, -43, -59, -68, -71, -74, -74, -76, -73, -64, -52, -39, -31, -25, -15,
+ 0, 12, 20, 24, 29, 32, 30, 26, 21, 16, 10, 4, -2, -7, -7, -5,
+ -3, 0, 3, 5, 6, 9, 8, 8, 6, 3, 2, 4, 5, 7, 14, 22,
+ 34, 43, 49, 57, 57, 55, 52, 48, 43, 31, 17, 2, -13, -33, -49, -59,
+ -63, -66, -72, -75, -76, -70, -61, -52, -44, -37, -30, -18, -4, 11, 20, 25,
+ 28, 32, 32, 30, 26, 19, 13, 5, 0, -4, -5, -3, 1, 2, 1, -3,
+ -2, 2, 6, 4, 2, -3, -2, 3, 10, 13, 18, 27, 40, 49, 56, 59,
+ 60, 56, 52, 47, 41, 30, 17, 1, -19, -39, -55, -64, -67, -70, -76, -81,
+ -78, -69, -56, -46, -40, -33, -24, -12, 3, 15, 22, 25, 26, 29, 27, 23,
+ 19, 14, 9, 4, 0, -2, 1, 5, 9, 7, 2, -3, -3, 3, 3, -2,
+ -10, -13, -10, -2, 7, 14, 22, 31, 45, 59, 65, 68, 65, 62, 58, 50,
+ 41, 28, 12, -9, -31, -49, -59, -65, -70, -76, -84, -84, -77, -63, -50, -45,
+ -40, -32, -21, -7, 7, 16, 24, 28, 29, 28, 23, 18, 15, 11, 6, 0,
+ -4, -3, 4, 11, 14, 11, 6, 5, 7, 7, 2, -7, -12, -16, -13, -6,
+ 1, 8, 17, 32, 50, 63, 68, 68, 69, 70, 65, 56, 43, 27, 7, -17,
+ -38, -52, -62, -71, -78, -86, -88, -84, -73, -59, -50, -43, -34, -25, -11, 2,
+ 11, 19, 23, 26, 26, 21, 17, 12, 9, 7, 5, 2, 2, 4, 11, 16,
+ 14, 10, 9, 10, 9, 1, -8, -16, -19, -16, -11, -6, 0, 8, 24, 43,
+ 57, 66, 70, 72, 72, 67, 63, 52, 37, 18, -5, -23, -41, -54, -62, -70,
+ -78, -81, -82, -76, -67, -56, -45, -36, -31, -22, -12, 0, 10, 16, 20, 21,
+ 17, 13, 7, 3, 3, 6, 6, 6, 9, 14, 20, 21, 20, 17, 17, 15,
+ 9, -3, -15, -23, -27, -20, -14, -9, -4, 9, 31, 49, 64, 70, 75, 78,
+ 76, 70, 60, 45, 31, 12, -11, -31, -46, -58, -66, -70, -73, -77, -74, -67,
+ -59, -52, -44, -36, -29, -22, -14, -6, 1, 11, 14, 14, 11, 6, 6, 7,
+ 10, 11, 12, 15, 18, 24, 23, 21, 19, 20, 18, 12, 0, -13, -20, -27,
+ -27, -22, -16, -11, 1, 19, 36, 52, 64, 73, 79, 81, 77, 69, 56, 43,
+ 26, 5, -16, -37, -54, -62, -66, -69, -72, -71, -65, -62, -56, -47, -39, -33,
+ -26, -19, -14, -12, -3, 9, 9, 3, -6, -4, 5, 11, 12, 11, 12, 20,
+ 29, 31, 29, 25, 25, 27, 24, 11, -6, -17, -25, -31, -32, -30, -26, -16,
+ 0, 17, 35, 51, 66, 78, 87, 88, 84, 73, 57, 40, 23, 3, -20, -42,
+ -57, -65, -69, -71, -70, -68, -63, -58, -52, -45, -38, -30, -26, -24, -23, -16,
+ -8, -2, -5, -9, -6, 1, 9, 12, 13, 17, 24, 32, 37, 37, 34, 32,
+ 33, 31, 19, 2, -15, -25, -31, -36, -38, -35, -27, -13, 4, 23, 40, 59,
+ 76, 91, 96, 91, 80, 69, 55, 35, 13, -12, -35, -52, -61, -66, -71, -70,
+ -63, -54, -48, -44, -42, -36, -31, -30, -34, -36, -33, -26, -20, -20, -21, -18,
+ -9, 5, 13, 18, 21, 29, 40, 47, 50, 49, 44, 40, 34, 23, 6, -14,
+ -27, -39, -45, -48, -45, -35, -23, -7, 11, 30, 51, 73, 89, 97, 96, 89,
+ 80, 63, 44, 25, 4, -18, -39, -53, -59, -63, -61, -58, -55, -52, -49, -45,
+ -39, -35, -37, -41, -46, -43, -38, -33, -29, -25, -18, -11, 3, 13, 20, 25,
+ 30, 38, 46, 51, 50, 47, 43, 37, 26, 9, -7, -19, -32, -45, -52, -51,
+ -40, -28, -12, 4, 19, 38, 61, 83, 94, 95, 89, 82, 67, 50, 30, 12,
+ -8, -26, -40, -52, -57, -56, -52, -48, -46, -44, -40, -34, -32, -32, -37, -44,
+ -47, -45, -41, -39, -35, -28, -17, -6, 7, 15, 23, 32, 40, 47, 52, 52,
+ 51, 46, 39, 32, 17, 1, -14, -26, -37, -46, -50, -45, -35, -25, -11, 5,
+ 24, 44, 62, 79, 88, 86, 79, 70, 59, 45, 25, 7, -13, -25, -36, -46,
+ -50, -51, -50, -46, -43, -41, -37, -34, -33, -36, -40, -43, -46, -46, -41, -36,
+ -31, -22, -10, 4, 13, 21, 30, 40, 47, 50, 53, 52, 47, 39, 30, 18,
+ 3, -12, -22, -33, -42, -47, -45, -36, -25, -14, -2, 14, 34, 52, 67, 76,
+ 77, 72, 65, 55, 43, 27, 12, -7, -21, -29, -36, -41, -44, -43, -39, -36,
+ -32, -27, -26, -26, -29, -33, -36, -43, -49, -48, -44, -38, -32, -22, -11, 4,
+ 15, 25, 34, 44, 50, 53, 54, 52, 44, 35, 23, 9, -4, -15, -27, -37,
+ -43, -45, -42, -34, -21, -9, 5, 19, 34, 50, 63, 70, 69, 63, 54, 46,
+ 35, 20, 4, -11, -23, -29, -33, -37, -41, -40, -33, -25, -20, -19, -21, -22,
+ -23, -26, -34, -42, -47, -46, -43, -36, -30, -22, -11, 5, 17, 28, 37, 45,
+ 52, 55, 53, 49, 41, 30, 19, 4, -12, -23, -33, -41, -45, -45, -40, -31,
+ -18, -3, 11, 23, 38, 51, 63, 64, 58, 51, 45, 36, 25, 10, -4, -15,
+ -24, -28, -32, -36, -35, -29, -19, -13, -13, -14, -13, -13, -13, -21, -33, -43,
+ -45, -45, -41, -38, -34, -25, -11, 4, 17, 29, 39, 49, 57, 60, 55, 48,
+ 39, 29, 16, 1, -14, -27, -35, -42, -47, -48, -42, -29, -15, -3, 10, 20,
+ 34, 48, 56, 57, 51, 45, 38, 30, 20, 7, -7, -17, -22, -26, -32, -36,
+ -31, -21, -9, -6, -8, -8, -4, 1, -4, -13, -26, -35, -39, -40, -42, -44,
+ -40, -29, -13, 3, 16, 29, 43, 58, 67, 67, 59, 49, 39, 27, 11, -9,
+ -28, -39, -47, -50, -53, -52, -44, -29, -12, 5, 13, 25, 38, 51, 57, 52,
+ 45, 38, 30, 21, 9, -4, -14, -21, -26, -29, -33, -28, -18, -7, 2, 2,
+ 2, 4, 8, 10, 5, -10, -25, -36, -42, -45, -49, -49, -45, -33, -14, 5,
+ 22, 35, 54, 69, 78, 76, 67, 53, 41, 27, 6, -17, -36, -50, -55, -60,
+ -63, -62, -51, -34, -16, -2, 9, 20, 34, 45, 50, 48, 42, 35, 29, 18,
+ 7, 0, 0, 0, 0, 0, 0, 7, 0, -1, -7, -18, -16, 3, 6, -18,
+ -29, -21, 6, 6, -12, -10, -10, -2, 4, 15, 21, 14, 4, 9, 29, 27,
+ 15, 9, 13, 20, 0, -21, -11, 3, -11, -37, -36, -7, 11, -4, -26, -23,
+ -4, 15, -4, -15, -11, -10, -1, 9, 23, 15, 8, 6, 24, 35, 19, 14,
+ 6, 17, 10, -15, -26, -7, -1, -23, -40, -24, 4, 10, -16, -25, -13, 11,
+ 10, -14, -15, -12, -6, 1, 19, 22, 6, 7, 15, 40, 31, 22, 7, 7,
+ 15, 5, -22, -21, -5, -9, -33, -32, -15, 5, -4, -19, -20, 1, 17, -4,
+ -15, -11, -12, -4, 9, 27, 13, 7, 11, 32, 44, 30, 14, 2, 7, 9,
+ -8, -25, -18, -9, -19, -30, -21, -4, 2, -10, -21, -13, 15, 8, -11, -13,
+ -16, -12, 0, 20, 24, 9, 9, 19, 44, 47, 25, 6, 2, 11, -1, -21,
+ -27, -19, -17, -20, -23, -17, -5, -5, -14, -20, 0, 15, -4, -7, -17, -17,
+ -8, 7, 25, 18, 7, 11, 31, 54, 41, 14, -1, 10, 3, -14, -27, -29,
+ -21, -16, -16, -18, -17, -11, -10, -16, -16, 10, 6, -3, -9, -19, -16, -2,
+ 18, 27, 16, 8, 19, 45, 54, 29, 5, 6, 4, -9, -18, -29, -30, -18,
+ -10, -9, -14, -20, -12, -13, -17, -5, 12, 7, 2, -16, -22, -13, 8, 25,
+ 23, 12, 11, 32, 53, 48, 17, 9, 9, -7, -16, -24, -37, -28, -12, -4,
+ -2, -18, -21, -18, -23, -17, 7, 11, 10, -4, -16, -22, -7, 21, 28, 18,
+ 9, 20, 43, 55, 37, 11, 11, 1, -14, -17, -31, -34, -21, -10, 4, -2,
+ -20, -23, -26, -29, -3, 6, 13, 8, -5, -23, -27, 7, 28, 27, 15, 12,
+ 32, 48, 50, 24, 9, 8, -12, -19, -26, -37, -35, -19, 3, 6, -12, -21,
+ -31, -38, -17, 6, 4, 14, 6, -8, -35, -15, 19, 26, 21, 7, 23, 43,
+ 52, 42, 14, 9, -2, -16, -21, -25, -33, -33, -4, 13, 3, -13, -30, -47,
+ -37, 1, 6, 7, 12, 6, -15, -31, -1, 22, 30, 14, 9, 37, 48, 50,
+ 26, 8, 6, -11, -22, -22, -25, -45, -22, 13, 15, 1, -22, -43, -56, -21,
+ 7, 6, 10, 15, -7, -25, -21, 7, 28, 21, 2, 25, 47, 53, 39, 11,
+ 10, 1, -20, -22, -18, -37, -42, 2, 15, 15, -8, -32, -57, -48, -9, 9,
+ 5, 14, 8, -14, -20, -13, 17, 33, 8, 9, 37, 52, 55, 25, 7, 8,
+ -11, -23, -15, -23, -47, -20, 12, 21, 10, -23, -50, -57, -31, 2, 10, 9,
+ 11, -8, -10, -18, -3, 30, 22, 1, 22, 45, 57, 45, 11, 11, 0, -23,
+ -22, -16, -36, -36, -6, 15, 18, -3, -43, -56, -49, -21, 5, 11, 12, -2,
+ -8, -9, -15, 12, 31, 9, 10, 34, 48, 60, 29, 16, 10, -17, -24, -21,
+ -27, -31, -17, 5, 14, 12, -22, -50, -48, -41, -9, 7, 13, -1, -8, -2,
+ -11, -5, 26, 19, 6, 21, 37, 55, 49, 25, 22, -5, -20, -24, -26, -29,
+ -23, -9, 8, 13, -1, -41, -48, -47, -30, -3, 12, 7, -12, -2, 1, -8,
+ 10, 20, 11, 16, 26, 40, 54, 42, 36, 7, -13, -18, -26, -29, -26, -14,
+ -2, 7, 8, -18, -45, -48, -45, -19, 6, 11, -10, -8, 5, -7, 2, 12,
+ 17, 15, 16, 23, 45, 55, 48, 27, -7, -12, -18, -30, -31, -17, -5, -3,
+ 4, 5, -24, -40, -50, -38, -8, 8, 1, -13, 1, -1, 3, 8, 15, 18,
+ 15, 15, 28, 52, 59, 47, 9, -9, -10, -25, -40, -29, -3, -5, -13, 1,
+ 3, -26, -47, -53, -23, -2, 5, -11, -6, 4, 6, 10, 10, 19, 11, 13,
+ 15, 42, 61, 61, 32, 3, -5, -12, -35, -43, -14, 1, -16, -13, 9, -1,
+ -33, -57, -46, -19, -3, -1, -16, -2, 5, 15, 6, 17, 9, 5, 9, 26,
+ 54, 65, 52, 21, 3, -6, -21, -48, -33, -4, -7, -22, -2, 18, -4, -47,
+ -58, -33, -11, 2, -13, -15, 3, 16, 15, 9, 15, -1, 5, 14, 48, 66,
+ 65, 37, 23, 2, -11, -42, -48, -20, -4, -23, -18, 18, 19, -17, -61, -52,
+ -27, -2, -5, -24, -7, 9, 20, 14, 18, 2, -3, 7, 34, 63, 68, 50,
+ 37, 19, -9, -25, -49, -38, -14, -14, -28, 6, 25, 9, -40, -62, -45, -17,
+ 3, -21, -16, -3, 12, 18, 18, 10, -6, 0, 16, 56, 69, 63, 43, 38,
+ 2, -20, -42, -44, -33, -14, -25, -10, 22, 18, -11, -55, -57, -37, -3, -10,
+ -26, -10, 2, 17, 21, 20, -3, -2, 5, 39, 67, 73, 56, 47, 22, -17,
+ -35, -43, -36, -28, -18, -20, 9, 22, 8, -33, -56, -53, -26, -2, -23, -24,
+ -11, 4, 23, 30, 4, -3, 0, 27, 60, 71, 69, 58, 43, -6, -35, -43,
+ -35, -36, -27, -18, -2, 19, 17, -9, -41, -51, -45, -10, -12, -31, -21, -9,
+ 8, 33, 17, 0, 2, 8, 50, 69, 75, 70, 64, 16, -31, -47, -35, -32,
+ -34, -25, -14, 10, 16, 5, -26, -42, -50, -32, -8, -22, -31, -22, -8, 22,
+ 32, 7, 6, 4, 28, 63, 69, 71, 78, 43, -20, -51, -41, -23, -34, -30,
+ -22, 2, 13, 9, -10, -31, -45, -44, -21, -19, -27, -36, -26, 2, 29, 24,
+ 12, 11, 13, 45, 69, 68, 81, 70, 6, -47, -52, -28, -23, -27, -26, -14,
+ 11, 10, -2, -18, -33, -43, -34, -25, -22, -36, -44, -14, 14, 29, 27, 22,
+ 18, 29, 60, 65, 71, 86, 41, -32, -57, -41, -23, -22, -22, -24, -4, 10,
+ 0, -11, -21, -31, -37, -37, -29, -29, -53, -33, -3, 16, 33, 31, 27, 23,
+ 46, 64, 65, 85, 71, -4, -48, -47, -31, -20, -15, -15, -19, 1, 0, -5,
+ -14, -21, -26, -40, -39, -28, -51, -50, -18, 4, 26, 38, 36, 30, 32, 61,
+ 64, 70, 80, 31, -35, -43, -40, -25, -19, -6, -17, -11, 0, -6, -11, -17,
+ -15, -31, -47, -39, -45, -62, -34, -8, 12, 36, 38, 41, 37, 51, 65, 60,
+ 71, 56, -7, -36, -38, -35, -27, -11, -5, -17, -8, -8, -9, -17, -13, -20,
+ -37, -47, -50, -62, -49, -16, 1, 25, 34, 43, 53, 49, 62, 58, 62, 65,
+ 22, -23, -31, -34, -35, -19, -3, -8, -18, -7, -4, -14, -17, -9, -27, -40,
+ -56, -68, -64, -27, -4, 9, 28, 37, 54, 60, 61, 59, 54, 63, 43, -1,
+ -25, -23, -37, -28, -8, 4, -10, -15, -3, -7, -26, -15, -11, -29, -51, -71,
+ -71, -49, -8, 5, 14, 30, 48, 66, 68, 63, 51, 56, 51, 18, -18, -20,
+ -25, -39, -23, -5, 3, -13, -6, -5, -21, -28, -10, -18, -43, -67, -78, -64,
+ -25, 1, 8, 15, 38, 60, 75, 74, 58, 54, 57, 28, -7, -18, -8, -31,
+ -34, -15, 4, -2, -4, 0, -15, -32, -21, -8, -28, -57, -77, -75, -44, -12,
+ 6, 8, 20, 49, 68, 77, 71, 53, 61, 41, 3, -18, -4, -14, -36, -28,
+ -7, 1, 7, 6, -8, -34, -35, -16, -15, -41, -66, -75, -59, -31, -4, 10,
+ 11, 31, 56, 72, 85, 63, 58, 55, 14, -17, -10, -1, -24, -30, -22, -6,
+ 11, 16, 9, -27, -43, -27, -15, -26, -53, -63, -66, -46, -21, 3, 13, 15,
+ 40, 63, 83, 78, 60, 67, 38, -9, -20, 4, -7, -23, -25, -22, 6, 24,
+ 20, -8, -48, -43, -24, -16, -39, -55, -57, -57, -36, -10, 9, 11, 22, 50,
+ 73, 88, 71, 65, 59, 14, -24, -9, -3, -15, -18, -31, -14, 25, 28, 10,
+ -36, -56, -41, -21, -29, -48, -47, -51, -50, -26, -2, 11, 6, 30, 57, 82,
+ 83, 69, 65, 35, -12, -16, -3, -10, -12, -21, -26, 11, 33, 26, -7, -56,
+ -54, -32, -26, -41, -39, -37, -52, -41, -16, 5, 7, 11, 37, 72, 91, 78,
+ 66, 55, 11, -19, -14, -15, -9, -7, -19, -8, 22, 30, 13, -32, -62, -44,
+ -31, -34, -40, -29, -40, -46, -29, -8, 2, 1, 18, 49, 84, 86, 72, 67,
+ 39, -6, -21, -25, -16, 2, -6, -12, 6, 23, 18, -7, -51, -56, -39, -33,
+ -41, -30, -24, -41, -36, -17, -8, -5, 7, 32, 66, 84, 78, 75, 58, 20,
+ -15, -29, -33, 2, 4, -1, 1, 11, 17, 4, -27, -56, -46, -36, -37, -39,
+ -22, -24, -38, -23, -16, -16, -7, 18, 46, 72, 82, 81, 72, 44, -1, -25,
+ -41, -18, 14, 8, 10, 0, 5, 2, -11, -40, -50, -42, -38, -37, -33, -11,
+ -27, -26, -20, -22, -13, 0, 31, 52, 73, 82, 80, 61, 26, -16, -37, -40,
+ 0, 18, 17, 12, -5, -8, -10, -21, -41, -43, -44, -36, -35, -20, -12, -23,
+ -14, -32, -21, -12, 15, 38, 58, 76, 82, 72, 46, 4, -26, -41, -23, 14,
+ 25, 18, 2, -23, -18, -14, -29, -35, -45, -42, -35, -29, -15, -19, -3, -23,
+ -32, -19, -1, 27, 40, 67, 81, 76, 61, 26, -11, -33, -36, -6, 28, 28,
+ 13, -15, -38, -19, -20, -26, -36, -46, -35, -32, -20, -21, -4, -4, -28, -25,
+ -16, 13, 31, 49, 74, 79, 69, 48, 8, -16, -33, -21, 7, 33, 24, 5,
+ -32, -38, -22, -21, -22, -41, -43, -32, -25, -23, -16, 6, -9, -29, -28, -5,
+ 20, 39, 58, 75, 71, 60, 22, 0, -18, -27, -10, 16, 30, 15, -14, -49,
+ -34, -19, -16, -27, -43, -31, -25, -27, -24, -1, 7, -15, -32, -22, 3, 28,
+ 50, 61, 67, 59, 38, 13, 5, -17, -16, -3, 21, 23, 3, -34, -49, -28,
+ -17, -19, -34, -34, -18, -26, -32, -16, 14, 6, -23, -34, -11, 14, 44, 54,
+ 56, 60, 44, 25, 18, 2, -18, -9, 3, 21, 9, -14, -45, -39, -24, -22,
+ -28, -32, -18, -17, -36, -30, 5, 21, -5, -31, -27, 1, 30, 56, 46, 50,
+ 47, 32, 29, 20, -4, -9, -9, 4, 10, -2, -28, -38, -31, -33, -26, -26,
+ -19, -9, -24, -38, -11, 24, 10, -17, -36, -14, 14, 48, 49, 37, 43, 39,
+ 33, 32, 11, 1, -5, -11, -6, -3, -16, -29, -28, -40, -38, -27, -20, -6,
+ -11, -31, -29, 15, 22, 0, -25, -25, 2, 31, 51, 38, 35, 41, 41, 34,
+ 27, 8, 6, -7, -20, -14, -7, -20, -19, -34, -52, -35, -23, -11, -5, -18,
+ -33, -5, 26, 5, -11, -27, -11, 17, 43, 43, 30, 29, 46, 45, 38, 17,
+ 6, 2, -22, -27, -16, -16, -18, -18, -53, -48, -23, -19, -3, -10, -21, -19,
+ 18, 12, -6, -20, -21, 6, 29, 42, 31, 23, 37, 54, 48, 31, 13, 13,
+ -13, -31, -25, -16, -16, -11, -38, -62, -33, -28, -7, -3, -12, -17, 6, 16,
+ 2, -11, -17, -5, 15, 35, 34, 25, 23, 44, 55, 41, 22, 14, 2, -29,
+ -32, -23, -11, -13, -18, -60, -50, -32, -16, -6, -11, -4, 3, 11, 3, -1,
+ -14, -8, 5, 20, 39, 31, 24, 26, 54, 57, 37, 16, 8, -19, -32, -27,
+ -17, -17, -17, -36, -58, -40, -32, -11, -11, -2, 6, 10, 2, 0, -4, -12,
+ 1, 8, 33, 42, 26, 17, 35, 63, 53, 26, 6, -9, -27, -30, -25, -17,
+ -23, -24, -47, -51, -38, -17, -11, -6, 12, 17, 8, -8, -1, -10, -7, 4,
+ 18, 40, 33, 18, 22, 49, 70, 46, 12, -11, -16, -23, -27, -19, -28, -26,
+ -36, -50, -48, -31, -13, -13, 10, 20, 21, 0, -6, -1, -7, 3, 15, 32,
+ 40, 24, 17, 31, 58, 67, 28, -2, -21, -14, -31, -18, -24, -33, -33, -49,
+ -49, -41, -18, -20, -2, 20, 23, 19, -12, -7, -2, -3, 10, 22, 33, 37,
+ 21, 23, 39, 72, 51, 10, -17, -18, -20, -29, -17, -33, -36, -49, -48, -47,
+ -24, -16, -15, 11, 24, 30, 6, -12, -2, -2, -1, 18, 29, 35, 27, 25,
+ 25, 56, 63, 23, -5, -19, -14, -23, -21, -21, -38, -52, -54, -40, -32, -15,
+ -23, -7, 18, 31, 22, -2, -7, 3, 0, 12, 21, 34, 31, 28, 22, 35,
+ 66, 40, 2, -19, -19, -15, -21, -16, -30, -60, -62, -42, -33, -18, -18, -22,
+ 4, 29, 29, 14, -2, -4, 5, 6, 16, 28, 36, 24, 29, 26, 52, 49,
+ 14, -13, -24, -19, -14, -15, -17, -53, -75, -54, -32, -18, -11, -26, -18, 18,
+ 28, 25, 13, -6, 4, 13, 9, 17, 37, 24, 28, 33, 37, 49, 26, 1,
+ -19, -26, -16, -11, -7, -33, -77, -71, -45, -15, -8, -18, -30, 1, 25, 21,
+ 26, 3, 5, 17, 14, 11, 33, 27, 17, 34, 38, 42, 33, 6, -11, -28,
+ -22, -12, -3, -16, -60, -81, -62, -25, -2, -14, -27, -17, 20, 18, 24, 18,
+ 6, 16, 21, 12, 24, 28, 12, 26, 44, 42, 35, 13, -5, -21, -31, -18,
+ -2, -2, -42, -77, -76, -47, -10, -6, -22, -24, 4, 16, 18, 25, 18, 18,
+ 24, 20, 20, 32, 14, 11, 40, 49, 41, 21, -6, -13, -27, -28, -5, 5,
+ -18, -59, -79, -63, -30, -6, -11, -28, -11, 8, 10, 23, 27, 17, 24, 25,
+ 25, 28, 19, 8, 25, 47, 46, 27, -5, -15, -18, -33, -20, -5, -3, -35,
+ -70, -66, -51, -22, -7, -21, -19, -3, 6, 17, 29, 26, 23, 28, 25, 32,
+ 23, 14, 11, 39, 50, 38, 3, -19, -10, -21, -29, -12, -3, -12, -55, -65,
+ -56, -42, -14, -10, -23, -11, -3, 10, 23, 32, 26, 28, 28, 35, 29, 22,
+ 13, 18, 41, 43, 18, -16, -18, -14, -29, -21, -11, -8, -32, -61, -52, -52,
+ -30, -11, -18, -16, -10, 2, 22, 35, 30, 25, 32, 34, 40, 27, 19, 11,
+ 23, 39, 32, -1, -22, -14, -22, -23, -14, -11, -17, -45, -52, -51, -51, -22,
+ -17, -19, -17, -10, 11, 35, 39, 29, 26, 34, 43, 43, 27, 16, 12, 25,
+ 31, 18, -13, -20, -19, -22, -12, -14, -15, -28, -44, -47, -53, -33, -15, -22,
+ -24, -20, 5, 27, 38, 31, 21, 27, 46, 51, 40, 18, 8, 13, 23, 24,
+ 3, -21, -22, -22, -8, -9, -22, -26, -31, -40, -51, -44, -17, -15, -26, -31,
+ -10, 24, 35, 37, 25, 21, 42, 57, 53, 30, 11, 7, 11, 21, 12, -11,
+ -23, -25, -12, 0, -18, -32, -31, -30, -45, -46, -26, -13, -25, -39, -25, 15,
+ 36, 29, 25, 20, 37, 58, 63, 46, 15, 3, -2, 19, 16, -2, -19, -25,
+ -23, 4, -4, -31, -36, -29, -32, -43, -37, -17, -16, -39, -43, -2, 34, 31,
+ 21, 17, 30, 62, 67, 62, 27, 9, -9, 3, 26, 8, -18, -26, -26, -5,
+ 9, -23, -44, -33, -26, -33, -40, -28, -12, -30, -52, -24, 23, 33, 15, 14,
+ 22, 54, 75, 68, 47, 14, -9, -12, 19, 23, -12, -20, -20, -13, 11, -6,
+ -40, -41, -19, -23, -34, -34, -14, -13, -48, -48, 4, 35, 23, 7, 13, 40,
+ 77, 78, 57, 31, -3, -18, 3, 27, 7, -24, -19, -16, 1, 5, -29, -49,
+ -28, -13, -26, -34, -26, -4, -30, -57, -24, 22, 30, 6, 7, 31, 63, 86,
+ 68, 42, 10, -19, -13, 15, 25, -10, -22, -14, -7, 6, -11, -45, -40, -14,
+ -24, -35, -31, -12, -8, -51, -44, -2, 29, 11, -1, 22, 47, 74, 78, 49,
+ 25, -8, -26, -4, 26, 12, -16, -19, -11, -1, -1, -28, -45, -22, -13, -29,
+ -29, -23, -1, -26, -55, -26, 14, 20, -3, 13, 39, 63, 80, 61, 33, 8,
+ -22, -25, 10, 22, -1, -14, -15, -7, -1, -14, -37, -26, -13, -25, -28, -26,
+ -2, -5, -48, -44, -7, 18, 3, 9, 30, 49, 71, 70, 45, 23, -13, -33,
+ -5, 22, 11, -7, -17, -14, -6, -8, -29, -29, -15, -19, -26, -31, -15, 6,
+ -25, -52, -30, 7, 7, 2, 21, 40, 60, 67, 52, 33, 7, -29, -19, 16,
+ 22, 4, -8, -15, -11, -6, -23, -24, -10, -11, -23, -27, -22, 1, 0, -34,
+ -45, -14, 2, 1, 15, 35, 52, 62, 49, 36, 21, -16, -26, 1, 20, 12,
+ -7, -10, -20, -10, -19, -28, -9, -8, -15, -26, -27, -11, 2, -15, -41, -34,
+ -10, -7, 6, 32, 48, 56, 51, 35, 26, 1, -24, -10, 15, 18, 2, -9,
+ -17, -18, -11, -32, -6, 2, -9, -18, -22, -17, -3, -2, -21, -34, -26, -13,
+ -8, 20, 47, 53, 52, 38, 24, 5, -14, -15, 9, 14, 4, -6, -14, -21,
+ -14, -28, -22, 12, 0, -10, -23, -24, -13, 2, -10, -23, -34, -26, -13, 4,
+ 39, 58, 51, 45, 28, 6, -9, -11, 3, 17, 7, -3, -10, -18, -15, -22,
+ -35, 2, 18, 2, -11, -23, -20, -1, 0, -15, -24, -39, -25, -6, 17, 52,
+ 56, 47, 35, 6, -10, -8, 0, 13, 13, -2, -9, -13, -13, -25, -43, -16,
+ 21, 19, -3, -21, -25, -10, 2, -5, -14, -30, -40, -13, -1, 34, 58, 51,
+ 44, 18, -10, -9, -2, 6, 12, 7, -7, -12, -12, -18, -40, -33, 9, 32,
+ 19, -9, -23, -15, 1, 3, -9, -18, -40, -28, -4, 7, 47, 59, 49, 24,
+ 1, -13, -5, 1, 10, 11, 5, -12, -12, -15, -35, -42, -9, 23, 33, 9,
+ -22, -24, -5, 1, -5, -12, -30, -40, -7, -3, 22, 56, 58, 35, 11, -12,
+ -9, -5, -1, 7, 13, -4, -13, -13, -25, -43, -29, 10, 34, 32, -6, -27,
+ -8, 3, -5, -13, -22, -40, -18, -3, -1, 37, 61, 46, 23, -5, -13, -4,
+ -4, -7, 12, 14, -10, -18, -22, -34, -35, -10, 22, 39, 23, -15, -14, 5,
+ 3, -8, -15, -36, -23, -1, -7, 14, 51, 57, 37, 8, -13, -7, -2, -14,
+ -6, 20, 3, -21, -26, -27, -30, -27, 1, 28, 36, 7, -10, 0, 5, -8,
+ -14, -30, -29, -3, -10, -5, 31, 56, 46, 19, -7, -10, 3, -11, -21, 9,
+ 19, -10, -30, -29, -19, -24, -20, 10, 35, 29, 8, -1, 5, -2, -13, -28,
+ -33, -3, -1, -13, 12, 49, 55, 31, -1, -12, 2, -3, -26, -2, 21, 2,
+ -28, -34, -21, -17, -29, -12, 23, 34, 19, 6, 7, 4, -4, -23, -40, -10,
+ 7, -12, -2, 34, 55, 36, 8, -10, 1, 3, -19, -18, 15, 15, -10, -33,
+ -30, -9, -19, -25, 4, 32, 30, 16, 11, 10, 3, -15, -35, -27, 9, -4,
+ -10, 16, 52, 42, 12, -7, -6, 4, -6, -21, -2, 17, 0, -20, -41, -13,
+ -9, -31, -16, 18, 34, 23, 14, 9, 10, -7, -26, -34, -3, 10, -10, 2,
+ 42, 51, 16, -8, -11, -2, -2, -11, -9, 9, 2, -8, -36, -31, 3, -23,
+ -30, -1, 27, 27, 23, 15, 18, 3, -17, -31, -19, 8, 1, -4, 24, 51,
+ 30, -11, -16, -6, -3, -5, -10, 3, 1, -10, -22, -41, -4, -6, -29, -18,
+ 12, 25, 26, 23, 20, 11, -10, -21, -27, -4, 7, 0, 13, 41, 40, 3,
+ -24, -11, -1, -2, -3, 5, 5, -14, -15, -35, -20, 0, -19, -24, -4, 11,
+ 23, 31, 24, 16, -3, -13, -23, -14, 2, 3, 18, 32, 38, 21, -20, -29,
+ -5, -2, 0, 5, 11, -14, -22, -25, -26, -3, -11, -26, -11, -2, 8, 32,
+ 34, 24, 2, -8, -16, -13, 1, 1, 10, 31, 31, 33, 1, -36, -22, 0,
+ 0, 8, 18, -3, -27, -22, -22, -10, -9, -24, -16, -5, -16, 16, 40, 34,
+ 8, -3, -13, -12, 1, 1, 3, 30, 30, 24, 18, -28, -35, -13, -2, 6,
+ 19, 10, -25, -28, -15, -9, -10, -19, -20, -3, -15, -8, 27, 42, 25, 1,
+ -14, -18, 7, 9, -1, 19, 37, 19, 23, -10, -41, -26, -9, 2, 20, 19,
+ -17, -35, -21, 0, -9, -18, -20, -7, -8, -24, 6, 37, 43, 14, -10, -22,
+ 3, 18, 4, 6, 36, 23, 16, 4, -32, -37, -19, -3, 17, 27, 0, -37,
+ -34, -3, 7, -17, -27, -19, -1, -20, -13, 17, 44, 35, 2, -22, -9, 19,
+ 20, 2, 26, 32, 15, 5, -17, -40, -29, -9, 10, 28, 17, -23, -41, -21,
+ 9, -2, -27, -30, -5, -7, -21, -4, 27, 47, 27, -14, -21, 11, 29, 14,
+ 15, 32, 20, 4, -11, -31, -38, -15, 2, 22, 22, -3, -32, -34, -6, 8,
+ -13, -38, -19, 0, -16, -14, 6, 37, 39, 11, -18, -4, 25, 25, 16, 24,
+ 27, 7, -10, -24, -38, -25, 0, 12, 23, 8, -16, -31, -23, 0, 0, -27,
+ -33, -2, -9, -16, -11, 17, 41, 32, 5, -15, 12, 25, 24, 21, 27, 14,
+ -4, -21, -31, -29, -4, 9, 19, 9, -9, -19, -25, -10, -5, -15, -38, -13,
+ -6, -13, -17, -1, 30, 36, 27, -2, 2, 20, 24, 25, 24, 19, 2, -16,
+ -32, -29, -13, 8, 18, 16, -6, -13, -21, -15, -14, -13, -26, -22, -6, -11,
+ -14, -14, 11, 30, 37, 17, 1, 13, 20, 23, 24, 21, 5, -10, -32, -31,
+ -15, 0, 17, 22, -3, -15, -17, -11, -15, -19, -23, -22, -8, -8, -13, -18,
+ -8, 18, 40, 38, 12, 12, 15, 21, 23, 24, 7, -9, -22, -34, -19, -6,
+ 11, 30, 9, -17, -20, -16, -11, -22, -30, -27, -8, -7, -10, -19, -16, -2,
+ 32, 52, 31, 17, 16, 13, 21, 19, 19, -9, -17, -30, -25, -7, 3, 29,
+ 25, -9, -21, -20, -11, -14, -29, -37, -14, 2, -5, -14, -22, -12, 13, 50,
+ 49, 27, 23, 15, 13, 9, 18, 7, -22, -22, -28, -11, -5, 19, 35, 13,
+ -20, -24, -18, -8, -22, -38, -31, 2, 3, -6, -26, -22, -3, 38, 56, 42,
+ 34, 21, 12, 6, 11, 17, -15, -24, -20, -15, -6, 9, 29, 29, -4, -28,
+ -23, -14, -13, -30, -39, -16, 9, 6, -12, -33, -16, 19, 57, 49, 41, 30,
+ 13, 4, -1, 6, -4, -27, -21, -13, -6, 2, 12, 34, 12, -24, -24, -20,
+ -16, -24, -38, -33, 2, 12, -2, -30, -31, 2, 45, 59, 46, 41, 24, 8,
+ -3, -6, 1, -15, -25, -16, -3, 5, 2, 21, 28, -11, -26, -23, -18, -20,
+ -32, -40, -14, 14, 11, -10, -40, -20, 30, 60, 55, 42, 34, 15, 6, -12,
+ -12, -4, -19, -21, -9, 8, 4, 10, 28, 6, -25, -22, -20, -22, -29, -38,
+ -27, 5, 16, 4, -24, -39, 12, 51, 61, 51, 41, 27, 10, -7, -25, -9,
+ -10, -17, -15, 0, 9, 5, 21, 15, -13, -27, -17, -21, -23, -38, -33, -11,
+ 10, 6, -4, -38, -17, 36, 55, 55, 45, 35, 21, 4, -27, -25, -2, -10,
+ -14, -13, 3, 5, 14, 16, 0, -24, -21, -18, -22, -36, -39, -17, -3, 5,
+ 3, -15, -28, 16, 50, 53, 52, 43, 29, 13, -14, -36, -10, -1, -15, -15,
+ -6, 6, 5, 13, 4, -11, -24, -17, -18, -27, -43, -18, -12, -7, 4, 3,
+ -17, -4, 38, 53, 52, 48, 41, 23, 0, -31, -30, 2, -7, -14, -13, -5,
+ 3, 11, 7, -4, -21, -25, -21, -19, -39, -23, -9, -19, -8, 5, -1, -10,
+ 24, 46, 48, 46, 44, 32, 10, -18, -37, -7, 0, -12, -14, -13, -4, 8,
+ 9, 1, -16, -29, -28, -17, -33, -31, -6, -21, -21, -4, 12, 3, 13, 41,
+ 46, 44, 46, 44, 20, -7, -36, -27, 6, -3, -18, -21, -12, 2, 12, 6,
+ -5, -27, -36, -21, -20, -34, -12, -8, -29, -16, 11, 15, 10, 28, 47, 46,
+ 41, 45, 35, 5, -24, -30, -5, 3, -14, -26, -16, -7, 7, 8, -3, -18,
+ -39, -32, -16, -28, -26, -8, -23, -26, 0, 19, 16, 20, 42, 55, 45, 38,
+ 39, 20, -11, -24, -13, -2, -6, -25, -22, -7, -5, 13, 0, -11, -36, -41,
+ -20, -16, -29, -16, -14, -28, -12, 13, 17, 15, 32, 50, 57, 41, 38, 30,
+ 2, -14, -9, -3, -3, -19, -33, -10, -7, 7, 7, -13, -30, -42, -28, -13,
+ -17, -26, -14, -22, -15, 7, 19, 15, 26, 46, 59, 51, 34, 33, 12, -7,
+ -11, -4, -5, -13, -38, -23, -3, 3, 15, -7, -32, -45, -34, -21, -11, -27,
+ -25, -21, -19, -1, 13, 15, 22, 37, 53, 62, 46, 34, 15, -2, 0, -4,
+ -8, -9, -34, -38, -8, 4, 17, 3, -25, -50, -44, -26, -12, -13, -32, -24,
+ -20, -7, 11, 18, 17, 33, 50, 65, 57, 41, 24, 0, 5, 5, -9, -11,
+ -25, -44, -25, -1, 17, 13, -18, -42, -51, -33, -20, -7, -27, -29, -23, -16,
+ 0, 14, 14, 28, 48, 60, 66, 51, 34, 4, 0, 15, -3, -14, -20, -35,
+ -37, -12, 12, 27, -7, -37, -50, -40, -29, -15, -15, -30, -24, -15, -7, 6,
+ 17, 25, 46, 59, 68, 63, 43, 20, -6, 14, 10, -8, -20, -30, -34, -22,
+ -2, 24, 15, -30, -49, -49, -37, -28, -15, -26, -28, -18, -11, -7, 7, 27,
+ 42, 58, 70, 70, 53, 35, 4, 0, 18, -1, -15, -32, -31, -26, -12, 12,
+ 28, -4, -44, -53, -44, -39, -25, -23, -28, -19, -11, -12, -16, 13, 42, 56,
+ 71, 71, 57, 45, 23, -3, 10, 11, -6, -27, -35, -25, -22, -1, 23, 17,
+ -29, -54, -46, -44, -39, -29, -28, -21, -15, -15, -26, -12, 39, 57, 70, 73,
+ 60, 49, 41, 13, 1, 11, 0, -16, -32, -25, -15, -14, 10, 23, -5, -48,
+ -46, -42, -49, -43, -31, -24, -15, -13, -24, -32, 18, 59, 71, 77, 67, 57,
+ 47, 33, 3, 5, 5, -9, -23, -33, -16, -14, -5, 17, 12, -29, -44, -35,
+ -50, -57, -43, -30, -18, -11, -22, -39, -9, 44, 68, 82, 69, 61, 49, 42,
+ 18, 5, 5, -8, -12, -26, -14, -7, -9, 5, 16, -6, -36, -32, -42, -62,
+ -55, -39, -29, -15, -14, -34, -30, 20, 59, 82, 79, 66, 58, 45, 38, 9,
+ 1, -7, -11, -16, -19, -3, -6, -6, 9, 5, -22, -32, -32, -58, -70, -56,
+ -42, -24, -16, -25, -39, -9, 41, 72, 86, 73, 65, 46, 40, 30, -4, -7,
+ -14, -12, -20, -3, 4, -5, 1, 8, -9, -27, -25, -40, -67, -67, -55, -38,
+ -24, -17, -25, -28, 16, 61, 81, 82, 71, 60, 37, 42, 17, -14, -17, -11,
+ -13, -8, 10, 2, -2, 1, -1, -17, -20, -26, -54, -69, -70, -58, -34, -25,
+ -16, -23, -9, 37, 70, 87, 80, 68, 44, 38, 39, -5, -27, -19, -12, -6,
+ 13, 10, 4, 1, 1, -5, -19, -20, -37, -59, -71, -71, -54, -35, -17, -9,
+ -20, 11, 49, 80, 86, 72, 54, 36, 45, 23, -25, -34, -16, -9, 11, 17,
+ 8, 5, -4, -2, -15, -19, -26, -50, -69, -77, -71, -51, -29, -7, -11, -6,
+ 26, 64, 87, 78, 60, 40, 42, 45, 2, -38, -34, -12, 10, 24, 10, 11,
+ 3, -1, -6, -20, -16, -31, -61, -81, -80, -69, -41, -16, -5, -8, 10, 47,
+ 81, 86, 70, 44, 36, 48, 32, -21, -48, -31, -3, 24, 24, 10, 15, 0,
+ 2, -17, -21, -18, -45, -81, -87, -80, -57, -33, -11, -6, 2, 30, 74, 86,
+ 77, 55, 34, 42, 48, 13, -39, -50, -20, 15, 34, 14, 16, 12, 4, -5,
+ -26, -16, -19, -64, -92, -91, -65, -43, -26, -12, -1, 16, 47, 83, 76, 66,
+ 40, 33, 45, 33, -8, -52, -41, -5, 32, 30, 15, 25, 13, 8, -22, -28,
+ -11, -34, -85, -101, -86, -52, -36, -25, -13, 15, 32, 69, 80, 69, 52, 32,
+ 37, 39, 19, -30, -54, -24, 10, 38, 25, 25, 22, 18, -6, -35, -20, -14,
+ -59, -98, -99, -68, -41, -30, -23, 5, 28, 52, 74, 67, 59, 43, 32, 35,
+ 32, -2, -47, -38, -13, 23, 33, 31, 26, 27, 16, -29, -37, -15, -33, -80,
+ -104, -89, -54, -35, -31, -11, 17, 42, 63, 68, 60, 59, 37, 27, 33, 22,
+ -28, -37, -26, 3, 32, 38, 30, 25, 30, -3, -41, -29, -23, -55, -90, -98,
+ -76, -39, -32, -21, 4, 36, 52, 61, 61, 63, 48, 24, 28, 34, -10, -31,
+ -29, -14, 15, 37, 37, 28, 31, 19, -27, -40, -24, -38, -69, -95, -96, -60,
+ -32, -26, -10, 19, 45, 53, 58, 59, 58, 29, 23, 39, 14, -21, -25, -23,
+ 1, 27, 43, 34, 34, 21, 0, -36, -32, -31, -49, -84, -102, -83, -41, -22,
+ -19, -1, 35, 49, 52, 53, 56, 39, 23, 34, 33, -3, -23, -22, -10, 17,
+ 36, 36, 39, 26, 8, -16, -34, -29, -36, -61, -93, -95, -58, -26, -18, -11,
+ 22, 48, 53, 53, 51, 41, 31, 33, 37, 16, -15, -24, -14, 4, 29, 34,
+ 41, 32, 8, -7, -19, -28, -30, -54, -83, -101, -76, -40, -20, -21, 1, 36,
+ 54, 55, 44, 33, 32, 35, 36, 30, 7, -26, -19, -5, 22, 36, 37, 37,
+ 15, -3, -5, -15, -24, -43, -75, -94, -87, -47, -29, -25, -14, 26, 48, 62,
+ 49, 29, 23, 35, 45, 38, 19, -16, -28, -7, 10, 29, 32, 38, 23, -2,
+ -10, -6, -12, -28, -67, -90, -98, -59, -32, -28, -25, 3, 43, 56, 59, 25,
+ 16, 24, 46, 43, 31, 0, -31, -14, 5, 25, 29, 32, 29, 6, -13, -6,
+ -3, -8, -49, -85, -97, -75, -31, -30, -30, -12, 31, 50, 61, 40, 12, 14,
+ 34, 53, 43, 20, -23, -20, -3, 21, 29, 23, 24, 15, -10, -8, -1, 2,
+ -25, -75, -98, -92, -42, -31, -35, -24, 14, 41, 50, 49, 22, 11, 20, 45,
+ 52, 39, 0, -26, -12, 9, 35, 25, 18, 14, 1, -13, -6, 4, 3, -49,
+ -89, -102, -61, -27, -30, -27, -4, 34, 46, 46, 32, 17, 13, 26, 47, 50,
+ 29, -19, -22, -4, 30, 37, 15, 7, 7, -5, -10, -4, 9, -20, -72, -100,
+ -86, -41, -33, -31, -16, 18, 43, 34, 32, 27, 23, 15, 31, 47, 48, 9,
+ -24, -16, 12, 43, 25, -2, 0, 9, -9, -15, 2, 8, -40, -87, -99, -69,
+ -37, -31, -19, 6, 38, 35, 25, 31, 35, 26, 18, 36, 49, 40, -10, -22,
+ -9, 29, 40, 6, -12, 6, 6, -16, -11, 9, -6, -61, -95, -90, -58, -35,
+ -26, -5, 23, 36, 18, 21, 36, 41, 28, 22, 38, 52, 23, -17, -17, 7,
+ 39, 21, -12, -13, 16, -8, -22, -5, 6, -25, -77, -93, -79, -46, -30, -11,
+ 15, 36, 22, 5, 29, 47, 47, 24, 22, 41, 48, 7, -15, -4, 22, 33,
+ 6, -23, 4, 8, -21, -15, -1, -5, -49, -79, -92, -71, -43, -20, 11, 31,
+ 29, 4, 16, 40, 55, 41, 22, 31, 50, 25, -9, -2, 8, 23, 16, -17,
+ -6, 8, -10, -15, -6, -4, -29, -56, -80, -86, -61, -42, 0, 30, 33, 12,
+ 2, 24, 47, 55, 37, 28, 39, 40, 4, -1, 6, 6, 16, -4, -13, 1,
+ -2, -9, -11, -11, -21, -35, -55, -82, -80, -64, -24, 27, 36, 23, 3, 10,
+ 35, 61, 55, 40, 35, 35, 19, 6, 12, 4, 1, 3, -12, -3, -2, -4,
+ -4, -14, -23, -30, -37, -58, -83, -84, -58, 8, 37, 33, 11, 3, 20, 46,
+ 62, 55, 50, 28, 16, 12, 15, 9, -4, -9, -9, -4, -5, -7, 2, -7,
+ -28, -35, -31, -36, -67, -90, -86, -23, 28, 38, 25, 5, 13, 34, 58, 58,
+ 69, 50, 15, 10, 20, 16, -3, -14, -14, -2, 1, -12, -3, 3, -20, -36,
+ -39, -26, -46, -81, -98, -61, 6, 27, 30, 16, 12, 25, 50, 57, 66, 74,
+ 31, 4, 16, 21, 8, -13, -21, -10, 8, -5, -11, 6, -8, -31, -40, -29,
+ -30, -66, -93, -84, -22, 17, 22, 26, 16, 20, 43, 56, 56, 70, 60, 17,
+ 8, 18, 15, -10, -26, -21, 6, 7, -12, -1, 1, -20, -33, -34, -31, -51,
+ -79, -92, -52, -6, 9, 19, 23, 21, 40, 57, 59, 60, 72, 43, 17, 13,
+ 18, 3, -23, -32, -5, 14, -7, -11, 7, -12, -26, -31, -37, -46, -66, -85,
+ -67, -21, -5, 3, 16, 22, 37, 54, 59, 55, 60, 58, 30, 16, 13, 11,
+ -15, -34, -23, 9, 7, -12, -2, -4, -19, -16, -31, -49, -64, -76, -72, -35,
+ -12, -14, 0, 15, 34, 53, 60, 58, 53, 57, 43, 30, 18, 12, -4, -27,
+ -28, -8, 14, -3, -9, -2, -13, -9, -17, -49, -66, -70, -69, -44, -15, -19,
+ -11, 2, 21, 53, 64, 68, 55, 48, 44, 36, 28, 15, -1, -18, -23, -19,
+ -4, 5, -3, 1, -9, -7, -1, -35, -70, -74, -70, -50, -21, -14, -22, -7,
+ -1, 39, 66, 77, 69, 46, 38, 36, 38, 22, 5, -12, -16, -12, -17, -8,
+ -5, 2, 1, -6, 5, -13, -64, -78, -73, -60, -31, -14, -17, -16, -10, 7,
+ 61, 79, 81, 57, 38, 28, 32, 24, 9, -4, -10, -4, -11, -20, -13, -2,
+ 11, 4, 4, -2, -41, -76, -76, -69, -43, -22, -12, -17, -14, -14, 25, 74,
+ 92, 79, 47, 31, 26, 26, 11, 3, -5, 0, 0, -20, -26, -11, 9, 14,
+ 9, 4, -24, -61, -76, -74, -53, -30, -13, -8, -12, -25, -8, 51, 90, 93,
+ 63, 42, 21, 18, 13, 6, 2, 1, 8, -12, -30, -27, -2, 14, 18, 11,
+ -13, -48, -68, -79, -70, -44, -19, -2, -5, -21, -31, 18, 77, 100, 81, 55,
+ 29, 7, 8, 6, 7, 4, 14, 0, -26, -34, -13, 9, 16, 17, 1, -35,
+ -58, -70, -82, -62, -29, -2, 1, -14, -36, -15, 50, 89, 95, 71, 46, 5,
+ -6, 4, 11, 3, 11, 14, -12, -31, -22, -2, 8, 16, 16, -15, -53, -56,
+ -80, -81, -41, -5, 9, -3, -30, -34, 17, 73, 97, 86, 63, 25, -12, -6,
+ 11, 13, 1, 15, 4, -19, -25, -5, 2, 9, 19, 10, -39, -48, -61, -95,
+ -67, -17, 12, 8, -23, -43, -9, 49, 85, 91, 76, 50, 1, -23, 2, 22,
+ 5, 2, 14, -5, -23, -12, 0, -2, 13, 17, -15, -48, -43, -83, -88, -38,
+ 5, 17, -11, -41, -28, 27, 67, 83, 82, 65, 29, -21, -18, 21, 19, -7,
+ 3, 6, -8, -14, 1, 0, 0, 13, 2, -34, -42, -59, -99, -63, -12, 17,
+ 0, -35, -42, 1, 53, 69, 79, 72, 53, -1, -34, 2, 32, 3, -8, 1,
+ 2, -2, -3, 8, -2, 3, 7, -18, -40, -39, -76, -81, -35, 9, 17, -22,
+ -46, -24, 34, 59, 68, 74, 66, 27, -26, -22, 31, 24, -10, -11, 0, 14,
+ 1, 5, 8, -5, -2, -10, -34, -35, -48, -77, -59, -13, 20, -4, -37, -35,
+ 8, 47, 55, 68, 74, 49, -4, -34, 10, 39, 1, -13, -11, 14, 14, 3,
+ 20, 6, -9, -14, -29, -37, -28, -56, -66, -42, 9, 9, -25, -38, -14, 27,
+ 45, 54, 72, 61, 21, -25, -14, 31, 19, -10, -15, -2, 22, 6, 22, 24,
+ -4, -20, -28, -38, -24, -28, -54, -57, -20, 14, -10, -29, -26, 2, 29, 39,
+ 61, 66, 39, -6, -25, 16, 30, 0, -16, -8, 12, 13, 18, 38, 10, -20,
+ -36, -34, -31, -16, -33, -56, -42, 0, 0, -21, -22, -12, 11, 25, 49, 68,
+ 53, 14, -20, -3, 29, 15, -11, -12, 3, 13, 13, 42, 34, -12, -39, -37,
+ -27, -22, -18, -44, -50, -21, 3, -12, -15, -18, -5, 9, 27, 60, 60, 32,
+ -6, -12, 21, 25, -4, -12, -2, 7, 8, 33, 53, 8, -37, -41, -25, -22,
+ -16, -27, -47, -34, -10, -10, -15, -15, -15, -5, 5, 41, 63, 44, 12, -11,
+ 10, 32, 10, -14, -8, 8, 5, 19, 53, 34, -24, -43, -25, -14, -15, -19,
+ -35, -35, -20, -12, -8, -14, -17, -19, -13, 19, 55, 53, 22, -8, 4, 31,
+ 26, -8, -13, 6, 10, 7, 39, 50, -2, -41, -31, -10, -13, -23, -31, -33,
+ -24, -15, -7, -13, -16, -22, -23, -6, 38, 55, 34, 1, -1, 23, 34, 9,
+ -18, -3, 14, 9, 20, 51, 24, -28, -37, -6, 2, -20, -30, -27, -21, -22,
+ -6, -12, -17, -21, -32, -27, 9, 49, 43, 12, -4, 14, 34, 24, -9, -12,
+ 12, 19, 13, 30, 37, -3, -35, -15, 12, -10, -31, -30, -15, -18, -13, -3,
+ -19, -20, -31, -35, -17, 28, 44, 22, 0, 7, 28, 27, 5, -15, 1, 20,
+ 20, 17, 28, 19, -21, -23, 12, 8, -22, -32, -20, -8, -15, 0, -13, -23,
+ -25, -43, -36, 4, 37, 30, 11, 4, 22, 28, 15, 0, -10, 9, 23, 14,
+ 11, 24, 5, -21, 2, 17, -8, -27, -27, -7, -10, -6, -1, -20, -26, -39,
+ -53, -20, 23, 36, 17, 7, 14, 28, 16, 12, -3, 2, 19, 16, 2, 14,
+ 19, -8, -5, 17, 4, -15, -26, -10, -4, -12, 1, -8, -23, -38, -58, -41,
+ 0, 29, 23, 11, 16, 21, 15, 9, 11, -6, 11, 20, 4, 3, 24, 5,
+ -5, 10, 17, -6, -15, -15, 6, -15, -8, 0, -11, -37, -54, -56, -24, 13,
+ 29, 12, 15, 20, 19, 6, 16, 5, -2, 10, 11, -3, 22, 18, 0, 6,
+ 20, 10, -6, -12, 1, -6, -23, 0, 1, -23, -56, -60, -43, -10, 19, 22,
+ 15, 22, 18, 6, 11, 17, -2, -5, 10, 4, 7, 23, 1, 3, 16, 22,
+ 5, -1, 0, 5, -21, -14, 6, -6, -46, -64, -54, -29, 1, 17, 18, 24,
+ 25, 10, 1, 17, 9, -8, -1, 15, 6, 20, 11, 2, 14, 25, 16, 9,
+ 5, 7, -11, -26, -5, 4, -27, -62, -62, -40, -17, 8, 11, 21, 29, 17,
+ -2, 10, 17, -8, -16, 6, 13, 11, 15, 3, 8, 24, 26, 14, 12, 12,
+ 4, -26, -15, 1, -12, -50, -64, -48, -27, -10, 5, 8, 32, 31, 1, -1,
+ 18, 0, -23, -6, 18, 14, 11, 5, 3, 17, 35, 25, 16, 18, 14, -11,
+ -27, -8, -6, -30, -55, -53, -36, -20, -5, 5, 14, 43, 13, -6, 11, 11,
+ -22, -22, 7, 19, 13, 10, 1, 7, 30, 36, 22, 23, 23, 6, -28, -20,
+ -6, -23, -43, -49, -43, -29, -19, 3, 1, 34, 29, -4, 3, 13, -13, -32,
+ -3, 20, 14, 11, 5, 2, 23, 42, 34, 22, 23, 21, -13, -26, -14, -19,
+ -32, -38, -43, -32, -29, -6, 4, 16, 35, 9, -4, 11, 0, -33, -22, 9,
+ 13, 12, 9, 3, 14, 35, 47, 34, 23, 27, 8, -22, -19, -16, -30, -29,
+ -42, -33, -32, -23, 4, 9, 24, 20, -1, 3, 10, -20, -36, -5, 13, 9,
+ 11, 8, 8, 21, 43, 48, 27, 22, 23, -7, -25, -20, -28, -25, -31, -36,
+ -28, -33, -8, 11, 14, 14, 6, -8, 7, -5, -39, -25, 7, 14, 9, 10,
+ 12, 15, 29, 55, 41, 23, 22, 9, -12, -23, -28, -24, -23, -34, -26, -31,
+ -21, 9, 19, 9, 1, -3, -1, 7, -32, -38, -9, 13, 11, 9, 11, 14,
+ 21, 46, 53, 32, 24, 12, -2, -16, -26, -24, -17, -34, -33, -25, -24, -4,
+ 17, 14, -3, -4, -7, 3, -13, -46, -25, 2, 17, 5, 8, 12, 18, 32,
+ 56, 38, 29, 15, 8, -4, -22, -30, -14, -22, -42, -25, -15, -10, 6, 17,
+ 1, -5, -7, -10, -2, -38, -37, -7, 15, 9, 2, 8, 21, 26, 43, 44,
+ 29, 18, 7, 12, -9, -25, -24, -11, -35, -43, -17, -5, 3, 10, 9, -3,
+ -3, -23, -9, -23, -45, -22, 7, 15, 2, 4, 17, 33, 31, 45, 35, 23,
+ 8, 17, 6, -16, -26, -14, -20, -48, -27, -2, 6, 11, 9, -1, 6, -15,
+ -28, -18, -39, -32, -7, 11, 7, 6, 7, 33, 30, 31, 41, 27, 7, 13,
+ 24, -3, -18, -22, -9, -40, -41, -10, 4, 9, 17, 3, 5, -4, -37, -29,
+ -29, -35, -19, 1, 10, 3, 7, 25, 41, 19, 31, 32, 13, 5, 27, 14,
+ -6, -19, -12, -23, -48, -22, 7, 8, 16, 11, 1, 6, -29, -46, -32, -32,
+ -20, -5, 7, 4, 3, 21, 43, 32, 15, 29, 16, 8, 19, 26, 3, -9,
+ -22, -13, -42, -37, -8, 11, 14, 25, 9, 4, -17, -50, -44, -30, -25, -14,
+ -1, 11, 1, 18, 36, 41, 12, 14, 18, 14, 15, 20, 17, 6, -14, -18,
+ -27, -39, -19, 5, 12, 24, 27, 8, -13, -49, -53, -32, -27, -19, -12, 7,
+ 7, 12, 31, 43, 26, 2, 8, 14, 22, 13, 17, 18, 6, -17, -26, -36,
+ -28, -6, 14, 25, 35, 20, -6, -42, -57, -37, -23, -23, -20, 0, 9, 8,
+ 25, 41, 40, 7, -4, 1, 23, 21, 14, 22, 20, -2, -24, -34, -31, -13,
+ 8, 24, 37, 33, 8, -32, -62, -44, -20, -22, -27, -9, 9, 7, 16, 31,
+ 42, 20, -10, -13, 10, 26, 7, 13, 25, 18, -11, -35, -39, -20, 0, 17,
+ 37, 37, 19, -17, -58, -55, -26, -18, -25, -21, 0, 14, 12, 20, 38, 35,
+ 0, -19, -9, 24, 19, 3, 21, 31, 17, -24, -42, -30, -3, 13, 34, 42,
+ 28, -2, -45, -62, -38, -22, -19, -20, -12, 12, 17, 11, 29, 42, 18, -16,
+ -20, 3, 24, 2, 4, 26, 36, 0, -38, -45, -13, 12, 27, 41, 34, 14,
+ -27, -62, -55, -30, -19, -15, -16, -2, 18, 11, 14, 37, 31, -6, -22, -12,
+ 15, 10, -10, 12, 36, 30, -19, -46, -33, 11, 24, 28, 35, 28, -5, -44,
+ -65, -44, -23, -11, -9, -8, 5, 14, 10, 25, 37, 14, -17, -18, -2, 14,
+ -7, -6, 23, 43, 10, -33, -38, -9, 24, 24, 28, 30, 11, -21, -57, -61,
+ -39, -12, -5, -5, -3, 7, 10, 17, 31, 30, -3, -20, -14, 6, 1, -16,
+ 2, 38, 38, -5, -30, -24, 13, 25, 21, 28, 15, 1, -34, -64, -62, -23,
+ 0, 2, -1, -1, 5, 14, 24, 33, 14, -12, -23, -4, 7, -18, -18, 18,
+ 43, 25, -9, -22, -2, 21, 19, 24, 20, 11, -13, -47, -69, -46, -7, 5,
+ 6, -1, -4, 9, 21, 31, 25, 5, -15, -20, 3, -8, -33, -7, 29, 37,
+ 20, -10, -10, 9, 15, 17, 14, 12, 1, -23, -55, -70, -30, 5, 13, 2,
+ -8, -1, 15, 25, 30, 15, -1, -20, -8, -3, -31, -28, 8, 31, 41, 15,
+ -6, 0, 9, 14, 12, 9, 8, -10, -28, -63, -55, -12, 17, 11, -7, -13,
+ 8, 22, 26, 19, 9, -7, -13, -5, -23, -39, -10, 17, 41, 38, 8, 0,
+ 5, 7, 12, 5, 7, -6, -8, -39, -60, -35, 7, 19, 6, -10, -6, 15,
+ 26, 22, 15, 9, -8, -13, -24, -45, -29, -1, 29, 48, 30, 2, 6, 5,
+ 9, 5, -1, -5, -4, -13, -51, -51, -16, 20, 13, 0, -11, 7, 25, 22,
+ 18, 17, 10, -8, -22, -50, -43, -13, 15, 46, 42, 16, 7, 8, 7, 7,
+ -1, -6, -10, -4, -27, -45, -36, 5, 16, 7, -5, -5, 20, 22, 19, 19,
+ 22, 7, -15, -43, -62, -29, 3, 35, 43, 27, 11, 9, 8, 4, 2, -9,
+ -13, -7, -15, -30, -43, -16, 12, 13, 4, -8, 12, 24, 17, 16, 24, 25,
+ -3, -38, -72, -52, -9, 25, 42, 30, 21, 8, 14, 4, 6, -3, -13, -12,
+ -13, -18, -36, -34, 3, 14, 9, -9, 5, 26, 18, 13, 26, 34, 13, -31,
+ -69, -68, -16, 19, 35, 29, 22, 6, 16, 3, 2, 6, -5, -15, -20, -19,
+ -21, -34, -17, 8, 16, -2, -3, 24, 27, 16, 23, 34, 32, -10, -56, -80,
+ -45, 6, 29, 29, 22, 10, 14, 13, -4, 6, 7, -8, -27, -27, -18, -20,
+ -28, -8, 14, 8, -7, 11, 29, 21, 17, 25, 35, 16, -36, -77, -67, -14,
+ 25, 30, 22, 11, 10, 19, 5, 2, 6, 5, -18, -34, -25, -13, -23, -19,
+ 4, 13, 0, 7, 24, 32, 24, 22, 31, 30, -12, -62, -76, -41, 9, 28,
+ 24, 15, 6, 18, 16, 6, 6, 7, -7, -32, -37, -16, -18, -24, -8, 11,
+ 7, 7, 20, 31, 35, 25, 24, 33, 9, -40, -72, -58, -16, 17, 27, 16,
+ 6, 10, 22, 12, 8, 8, 2, -23, -43, -26, -16, -24, -18, 2, 6, 7,
+ 21, 29, 36, 32, 21, 27, 22, -21, -57, -67, -38, -4, 26, 21, 9, 3,
+ 18, 25, 18, 10, 2, -11, -42, -36, -24, -27, -23, -9, 5, 2, 17, 32,
+ 42, 36, 27, 18, 25, -2, -39, -58, -51, -27, 11, 27, 11, 1, 9, 24,
+ 25, 21, 5, -8, -31, -37, -30, -33, -24, -15, 0, -2, 13, 31, 48, 47,
+ 33, 15, 18, 10, -27, -50, -52, -44, -12, 21, 21, 5, -1, 13, 33, 30,
+ 16, -6, -26, -39, -33, -35, -28, -20, -10, -8, 4, 27, 51, 61, 45, 21,
+ 13, 14, -11, -39, -40, -44, -36, 1, 25, 16, 1, 2, 27, 40, 28, 3,
+ -22, -38, -38, -32, -33, -21, -18, -14, -8, 18, 50, 66, 60, 27, 7, 12,
+ -3, -31, -36, -37, -46, -27, 18, 26, 5, -3, 8, 35, 43, 16, -14, -36,
+ -43, -32, -32, -25, -16, -23, -14, 6, 46, 64, 74, 49, 9, 4, 7, -23,
+ -37, -34, -41, -44, -8, 31, 19, -5, 0, 21, 47, 33, -2, -33, -43, -43,
+ -32, -29, -14, -22, -23, -6, 34, 62, 75, 71, 30, 0, 8, -13, -37, -34,
+ -35, -45, -34, 18, 31, 5, -5, 7, 35, 44, 12, -23, -45, -49, -40, -29,
+ -18, -18, -27, -15, 22, 57, 74, 80, 57, 15, 4, -1, -39, -34, -34, -40,
+ -46, -4, 25, 13, -3, 2, 22, 44, 25, -10, -38, -44, -50, -34, -20, -14,
+ -31, -21, 5, 47, 63, 81, 76, 38, 8, 9, -30, -45, -35, -36, -43, -20,
+ 9, 14, 5, 3, 7, 36, 32, 3, -32, -43, -50, -40, -28, -13, -24, -28,
+ -2, 35, 56, 73, 86, 58, 23, 21, -10, -49, -45, -33, -39, -25, -3, 5,
+ 5, 8, 5, 18, 32, 17, -19, -45, -49, -41, -35, -22, -19, -31, -12, 28,
+ 52, 59, 76, 74, 41, 31, 10, -39, -58, -41, -32, -27, -5, -3, 3, 8,
+ 8, 10, 24, 22, -4, -39, -52, -42, -35, -30, -18, -28, -22, 20, 53, 52,
+ 60, 73, 62, 43, 31, -18, -56, -61, -35, -28, -9, -6, -3, 3, 9, 10,
+ 12, 18, 8, -23, -53, -50, -31, -35, -24, -28, -26, 3, 48, 55, 52, 59,
+ 66, 57, 46, 7, -37, -67, -53, -24, -11, -4, -6, 0, 3, 13, 10, 7,
+ 10, -6, -38, -58, -36, -30, -30, -26, -26, -11, 33, 60, 56, 49, 59, 67,
+ 58, 32, -15, -58, -69, -34, -14, -8, -6, 1, -4, 7, 8, 2, 4, 4,
+ -21, -54, -49, -30, -30, -28, -29, -18, 13, 53, 60, 50, 44, 63, 61, 49,
+ 11, -33, -71, -49, -19, -9, -10, 5, 2, -1, 4, -1, 4, 5, -5, -38,
+ -55, -40, -28, -21, -25, -26, -2, 40, 61, 56, 39, 53, 66, 54, 33, -4,
+ -55, -63, -29, -18, -12, 3, 11, -4, -4, -9, -3, 4, 4, -18, -49, -49,
+ -35, -18, -18, -25, -16, 24, 51, 60, 42, 43, 66, 57, 42, 21, -23, -63,
+ -44, -26, -18, -10, 13, 9, -8, -18, -17, 5, 5, -4, -35, -47, -42, -24,
+ -11, -20, -21, 5, 36, 56, 53, 37, 60, 59, 40, 34, 11, -34, -52, -33,
+ -21, -15, 1, 21, 2, -19, -33, -10, 8, 3, -20, -42, -41, -33, -14, -16,
+ -18, -7, 21, 43, 54, 39, 47, 61, 44, 31, 27, -4, -41, -47, -28, -23,
+ -9, 11, 15, -9, -34, -34, 1, 10, -2, -30, -38, -34, -18, -15, -17, -10,
+ 10, 27, 43, 42, 42, 53, 54, 36, 24, 14, -15, -42, -36, -32, -22, 1,
+ 13, 7, -26, -48, -24, 11, 10, -14, -35, -32, -19, -16, -15, -11, 5, 18,
+ 31, 34, 41, 48, 51, 46, 28, 26, 8, -26, -36, -33, -35, -12, 7, 12,
+ -8, -45, -47, -9, 13, 5, -24, -32, -17, -14, -16, -11, 6, 14, 20, 26,
+ 27, 47, 49, 49, 34, 25, 22, -6, -31, -27, -39, -30, -10, 13, 6, -28,
+ -57, -31, -3, 12, -7, -28, -19, -8, -21, -18, -2, 18, 17, 17, 19, 34,
+ 47, 53, 42, 34, 30, 13, -22, -20, -30, -44, -32, -4, 15, -7, -45, -49,
+ -18, 4, 10, -14, -18, 0, -11, -26, -7, 15, 23, 10, 10, 20, 34, 51,
+ 49, 38, 41, 30, -8, -28, -15, -39, -47, -28, 5, 10, -26, -55, -34, -9,
+ 10, 3, -13, -4, 1, -21, -19, 3, 25, 13, 5, 9, 18, 36, 54, 39,
+ 40, 46, 16, -27, -17, -23, -47, -47, -18, 9, -2, -47, -51, -23, 0, 4,
+ 0, 1, 9, -11, -20, -9, 20, 23, 4, 2, 8, 20, 45, 46, 38, 53,
+ 41, -13, -30, -19, -36, -52, -40, -9, 5, -23, -53, -35, -6, 4, 3, 6,
+ 10, 5, -16, -17, 6, 30, 12, 0, -4, 9, 32, 47, 43, 55, 57, 16,
+ -27, -30, -28, -44, -52, -31, -6, -8, -43, -43, -15, -1, -1, 8, 10, 13,
+ 2, -18, -11, 21, 23, 6, -5, 0, 19, 33, 41, 56, 67, 44, -5, -34,
+ -35, -32, -46, -47, -27, -7, -30, -44, -23, -2, -2, 3, 7, 14, 18, -1,
+ -19, 4, 20, 16, -5, -9, 10, 27, 30, 46, 65, 63, 26, -22, -42, -34,
+ -41, -46, -40, -18, -25, -39, -28, -4, 1, -1, 5, 10, 24, 19, -8, -6,
+ 11, 20, 4, -13, 2, 22, 24, 36, 59, 70, 51, 5, -39, -39, -43, -47,
+ -45, -31, -30, -39, -33, -7, 1, -2, 1, 4, 19, 25, 5, -5, 1, 12,
+ 13, -12, -12, 18, 25, 21, 46, 68, 69, 36, -17, -39, -44, -51, -43, -33,
+ -35, -41, -38, -15, 8, 0, 0, 0, 13, 26, 19, 5, 0, -1, 10, -2,
+ -14, 5, 25, 19, 29, 54, 71, 59, 9, -31, -43, -56, -50, -32, -38, -47,
+ -42, -26, 8, 10, -3, -3, 7, 20, 23, 16, 8, -5, 3, 2, -17, -6,
+ 22, 20, 18, 40, 66, 71, 37, -13, -36, -52, -61, -38, -32, -47, -51, -38,
+ -7, 19, 6, -6, 4, 14, 19, 21, 19, 2, -5, 0, -13, -12, 14, 21,
+ 13, 27, 53, 71, 57, 12, -25, -42, -61, -54, -33, -38, -52, -50, -22, 13,
+ 17, -4, 1, 16, 17, 19, 25, 11, -2, -2, -11, -18, 6, 21, 15, 18,
+ 43, 66, 67, 34, -7, -30, -49, -58, -42, -36, -42, -54, -36, -2, 20, 4,
+ -4, 11, 16, 17, 26, 17, 4, 1, -8, -22, -8, 17, 16, 17, 27, 55,
+ 66, 48, 10, -25, -36, -49, -52, -42, -39, -47, -46, -18, 13, 14, -1, 3,
+ 13, 19, 27, 18, 2, 5, 1, -14, -17, 6, 13, 16, 26, 44, 64, 54,
+ 27, -15, -30, -33, -49, -50, -43, -44, -45, -30, -1, 13, 3, 6, 10, 22,
+ 30, 21, 3, 2, 2, -3, -18, -9, 8, 11, 23, 35, 55, 58, 37, 1,
+ -25, -18, -33, -51, -48, -46, -41, -30, -17, 6, 3, 7, 9, 16, 30, 27,
+ 9, 3, 3, 1, -10, -18, 0, 3, 12, 37, 46, 52, 40, 15, -23, -16,
+ -14, -39, -48, -48, -45, -31, -20, -7, 1, 4, 14, 13, 21, 26, 16, 2,
+ 1, 1, 1, -16, -12, 1, 5, 29, 50, 47, 39, 21, -11, -21, -3, -23,
+ -41, -45, -47, -37, -21, -13, -6, 1, 16, 20, 22, 22, 18, 10, 2, 1,
+ 6, -7, -16, -10, 0, 16, 51, 53, 38, 22, -1, -21, -1, -4, -30, -41,
+ -45, -45, -28, -13, -13, -8, 13, 24, 26, 15, 13, 15, 8, -4, 1, -2,
+ -11, -15, -11, 2, 40, 56, 44, 21, 1, -16, -10, 5, -16, -32, -38, -41,
+ -36, -22, -14, -15, 4, 24, 32, 18, 7, 14, 14, 4, -2, -1, -8, -12,
+ -15, -6, 24, 50, 51, 28, 1, -13, -14, 4, 1, -18, -31, -35, -36, -33,
+ -21, -21, -5, 19, 38, 23, 3, 5, 17, 15, 2, -3, -7, -8, -18, -14,
+ 12, 39, 50, 35, 2, -14, -14, -3, 6, -6, -24, -27, -32, -40, -25, -22,
+ -12, 8, 35, 34, 10, 2, 5, 19, 9, -6, -4, -3, -15, -18, 4, 30,
+ 42, 40, 13, -17, -16, -7, 3, 5, -14, -21, -24, -41, -37, -23, -18, -1,
+ 22, 37, 17, 4, -1, 11, 17, 1, -7, -4, -12, -22, -6, 24, 35, 33,
+ 25, -7, -26, -15, 2, 14, 3, -16, -19, -33, -42, -27, -23, -10, 15, 28,
+ 27, 8, 2, 5, 20, 11, -4, -6, -7, -19, -11, 17, 31, 26, 25, 6,
+ -24, -25, -6, 11, 14, -3, -13, -25, -39, -33, -23, -17, 7, 19, 26, 19,
+ 4, 1, 15, 14, -1, -5, -10, -14, -22, 8, 33, 28, 20, 16, -13, -26,
+ -17, 9, 22, 5, -8, -18, -37, -35, -28, -23, -4, 12, 16, 28, 12, 1,
+ 12, 18, 3, -2, -9, -10, -27, -10, 29, 34, 18, 16, 2, -26, -29, -3,
+ 27, 19, -4, -10, -29, -36, -30, -29, -12, 9, 3, 18, 21, 7, 12, 17,
+ 3, -2, -7, -7, -19, -26, 15, 36, 21, 12, 9, -15, -30, -18, 19, 30,
+ 6, -5, -21, -32, -25, -29, -22, 6, 0, 3, 20, 14, 12, 18, 12, 0,
+ -9, -12, -9, -26, -4, 31, 28, 11, 10, -6, -24, -29, 3, 35, 19, -3,
+ -15, -26, -19, -23, -31, -6, 4, -7, 13, 19, 17, 20, 18, 9, -9, -19,
+ -5, -17, -20, 16, 34, 18, 9, 0, -16, -25, -10, 30, 29, 3, -10, -19,
+ -19, -16, -29, -19, 3, -9, -5, 13, 21, 24, 16, 13, 1, -23, -14, -12,
+ -19, -2, 28, 21, 8, 1, -11, -23, -19, 16, 41, 14, -8, -13, -9, -13,
+ -18, -27, -4, -5, -12, -1, 19, 31, 18, 10, 16, -20, -22, -13, -14, -12,
+ 18, 26, 12, 4, -4, -17, -18, -1, 38, 31, -5, -14, -7, -7, -14, -24,
+ -13, -3, -13, -12, 7, 30, 34, 14, 18, -5, -33, -18, -10, -14, 1, 19,
+ 14, 6, -8, -13, -15, -2, 19, 40, 8, -13, -9, -4, -8, -18, -20, -9,
+ -14, -16, -7, 22, 37, 23, 16, 10, -26, -28, -13, -9, -5, 14, 14, 9,
+ -9, -17, -13, -1, 8, 31, 26, -6, -10, -4, -2, -12, -19, -11, -11, -17,
+ -12, 6, 34, 29, 15, 16, -7, -35, -25, -9, -6, 8, 14, 12, 1, -15,
+ -14, 3, 10, 19, 29, 8, -10, -9, 1, -7, -20, -10, -9, -17, -17, -1,
+ 30, 35, 18, 15, 5, -28, -33, -17, -6, -4, 8, 13, 5, -14, -19, 1,
+ 14, 14, 20, 17, 0, -8, -2, -3, -14, -18, -9, -12, -18, -6, 21, 37,
+ 26, 7, 10, -13, -33, -24, -6, -2, 0, 9, 11, -5, -19, -7, 16, 18,
+ 13, 18, 11, -2, -6, -3, -6, -22, -10, -11, -16, -11, 17, 34, 32, 9,
+ 9, 2, -26, -30, -14, -2, -5, 3, 8, 3, -16, -12, 8, 21, 13, 13,
+ 15, 2, -3, -5, -5, -20, -16, -8, -16, -20, 6, 32, 34, 14, -4, 6,
+ -12, -26, -20, -7, -6, -4, 4, 7, -2, -15, 1, 17, 15, 9, 15, 10,
+ 0, -3, -7, -15, -22, -4, -7, -19, -7, 29, 36, 20, -6, -1, 0, -17,
+ -19, -12, -9, -7, -1, 2, 6, -3, -8, 10, 18, 9, 8, 21, 4, -2,
+ -8, -13, -20, -12, -2, -16, -14, 14, 39, 26, -3, -17, 1, -6, -16, -12,
+ -7, -9, -9, 0, 3, 11, -3, 0, 15, 13, 3, 19, 12, -8, -6, -14,
+ -19, -16, 0, -6, -17, 3, 33, 35, 5, -18, -9, 1, -15, -11, -8, -8,
+ -16, -8, 1, 15, 15, 3, 11, 19, 2, 12, 26, 0, -10, -13, -21, -11,
+ 1, -1, -18, -2, 23, 35, 17, -12, -21, -2, -8, -9, -8, -9, -12, -17,
+ -5, 10, 22, 8, 7, 18, 7, -1, 23, 13, -13, -19, -23, -14, 5, 2,
+ -15, -13, 17, 30, 22, -3, -24, -7, -2, -9, -6, -10, -8, -21, -19, 5,
+ 22, 22, 13, 15, 13, -3, 11, 18, -4, -20, -28, -20, 4, 11, -10, -18,
+ 6, 26, 17, 3, -20, -12, -2, -11, -7, -8, -8, -16, -27, -7, 19, 30,
+ 21, 19, 15, 4, 3, 18, 2, -17, -33, -24, 0, 17, 1, -16, -6, 24,
+ 19, 5, -17, -18, 1, -8, -12, -7, -11, -10, -22, -14, 10, 29, 29, 32,
+ 23, 13, 0, 9, 6, -12, -28, -36, -7, 13, 12, -8, -17, 12, 24, 6,
+ -10, -20, 1, 1, -13, -9, -12, -16, -20, -17, 0, 21, 27, 31, 35, 20,
+ 7, 0, 2, -13, -19, -37, -19, 8, 18, 9, -16, -9, 20, 11, -2, -25,
+ -13, 8, -4, -16, -13, -18, -23, -17, 0, 14, 29, 27, 43, 35, 17, -1,
+ -4, -13, -22, -29, -31, -2, 17, 20, -5, -21, 6, 16, 5, -16, -25, 4,
+ 11, -12, -17, -20, -27, -19, -2, 13, 26, 27, 36, 46, 32, 7, -8, -18,
+ -26, -25, -32, -16, 12, 26, 11, -18, -11, 4, 13, -1, -27, -12, 14, 2,
+ -21, -23, -31, -26, -11, 10, 24, 30, 29, 43, 50, 24, -4, -16, -34, -28,
+ -28, -27, -1, 27, 24, -5, -21, -12, 6, 16, -13, -28, 1, 13, -9, -23,
+ -33, -32, -18, 2, 24, 34, 33, 34, 50, 49, 12, -11, -34, -37, -28, -25,
+ -14, 14, 28, 10, -10, -25, -9, 21, 15, -27, -15, 12, 2, -18, -33, -36,
+ -24, -7, 13, 30, 39, 42, 35, 54, 36, 1, -29, -45, -35, -26, -17, -1,
+ 20, 19, 2, -23, -30, 1, 30, -5, -32, 1, 7, -8, -27, -37, -25, -12,
+ -1, 23, 37, 51, 38, 41, 49, 16, -15, -41, -40, -31, -21, -11, 4, 19,
+ 15, -8, -33, -19, 22, 20, -21, -13, 2, -6, -17, -36, -32, -11, -8, 9,
+ 28, 48, 54, 36, 48, 30, 3, -30, -41, -34, -24, -15, -6, 2, 17, 8,
+ -19, -37, 0, 31, 3, -20, -6, -4, -7, -31, -35, -9, -3, -4, 16, 37,
+ 62, 44, 41, 33, 13, -11, -36, -39, -29, -21, -11, -11, 6, 14, -2, -28,
+ -24, 15, 22, -5, -10, -11, -10, -20, -35, -13, 2, -5, 2, 21, 55, 64,
+ 46, 37, 19, 2, -23, -36, -28, -23, -17, -18, -17, 10, 11, -12, -32, -7,
+ 23, 16, -7, -14, -17, -8, -27, -23, 1, 1, 0, 6, 31, 63, 60, 46,
+ 21, 7, -12, -29, -24, -18, -24, -23, -27, -11, 11, 5, -16, -19, 11, 21,
+ 4, -9, -21, -15, -17, -30, -5, 7, 2, -1, 9, 48, 65, 59, 30, 13,
+ -4, -25, -19, -6, -22, -33, -32, -31, -3, 7, -3, -20, -4, 14, 11, -1,
+ -11, -19, -13, -20, -16, 9, 7, 2, -3, 27, 60, 69, 44, 12, 7, -18,
+ -20, 1, -4, -35, -38, -34, -22, -9, 4, -2, -11, 8, 8, 2, -6, -19,
+ -23, -14, -16, 3, 13, 2, 2, 12, 47, 65, 62, 22, 10, -3, -21, -9,
+ 9, -17, -46, -40, -34, -23, -6, 4, -1, 3, 7, 2, -4, -13, -25, -18,
+ -11, -4, 18, 3, -2, 5, 30, 58, 66, 39, 12, 9, -10, -18, 8, 5,
+ -41, -49, -38, -33, -18, -4, 2, 7, 8, 2, -7, -12, -18, -23, -12, -6,
+ 18, 15, -8, 0, 21, 44, 62, 48, 22, 14, 7, -16, -7, 18, -18, -52,
+ -44, -42, -32, -18, -1, 12, 10, 6, -8, -20, -11, -18, -19, -10, 14, 24,
+ 2, -5, 14, 34, 57, 51, 27, 19, 20, -1, -13, 15, -1, -42, -45, -49,
+ -38, -28, -15, 13, 19, 10, -1, -23, -16, -11, -24, -10, 6, 21, 14, -5,
+ 3, 24, 48, 58, 29, 17, 24, 18, -6, 4, 8, -28, -38, -46, -50, -36,
+ -29, 3, 22, 15, 4, -18, -31, -7, -20, -17, 5, 11, 18, 4, -2, 15,
+ 37, 58, 35, 11, 26, 31, 11, -2, 6, -13, -32, -39, -55, -45, -38, -17,
+ 21, 23, 11, -10, -31, -18, -11, -25, 1, 9, 14, 15, 0, 7, 26, 49,
+ 49, 13, 10, 33, 26, 8, 4, -5, -25, -35, -46, -53, -41, -35, 5, 24,
+ 17, 0, -25, -26, -14, -24, -9, 6, 5, 17, 6, 6, 20, 38, 55, 30,
+ 3, 25, 38, 18, 10, -4, -16, -30, -42, -51, -46, -41, -16, 21, 23, 14,
+ -16, -30, -16, -17, -17, 0, 2, 12, 16, 3, 17, 28, 46, 49, 14, 13,
+ 39, 30, 17, 4, -9, -20, -38, -49, -50, -50, -34, 4, 21, 20, 4, -29,
+ -23, -15, -15, -8, -3, 7, 19, 8, 9, 26, 35, 47, 29, 6, 29, 35,
+ 26, 13, -5, -18, -29, -42, -49, -51, -50, -16, 11, 23, 18, -17, -34, -14,
+ -15, -9, -10, -2, 17, 14, 5, 21, 33, 44, 38, 14, 23, 37, 30, 20,
+ 6, -8, -26, -34, -47, -52, -54, -34, 0, 16, 19, 5, -29, -20, -13, -10,
+ -9, -10, 4, 19, 11, 13, 29, 37, 36, 22, 22, 39, 32, 23, 10, 2,
+ -18, -32, -40, -54, -56, -49, -23, 8, 17, 11, -15, -26, -11, -13, -9, -15,
+ -11, 14, 17, 10, 23, 34, 36, 24, 21, 35, 42, 26, 12, 2, -4, -23,
+ -31, -47, -57, -50, -33, -7, 17, 11, -2, -18, -12, -12, -11, -10, -21, -6,
+ 18, 19, 21, 33, 35, 28, 23, 34, 51, 40, 12, -2, 1, -9, -27, -43,
+ -59, -53, -39, -23, 4, 15, 1, -10, -14, -9, -8, -10, -22, -18, 5, 19,
+ 16, 27, 34, 28, 23, 27, 47, 53, 27, -3, -4, -1, -13, -33, -53, -57,
+ -45, -31, -13, 14, 4, -4, -11, -9, -9, -11, -19, -28, -16, 10, 24, 23,
+ 35, 24, 26, 26, 38, 60, 44, 2, -13, -3, -5, -19, -44, -58, -49, -33,
+ -26, 1, 14, 1, -4, -5, 0, -7, -14, -29, -26, -11, 20, 27, 30, 32,
+ 21, 27, 34, 59, 58, 22, -11, -10, -6, -10, -29, -55, -53, -38, -34, -16,
+ 12, 9, -5, -8, 5, 1, -16, -31, -32, -28, 0, 26, 26, 33, 23, 24,
+ 33, 49, 61, 37, 3, -15, -8, -11, -19, -43, -56, -44, -34, -25, -2, 17,
+ 5, -11, 2, 12, -2, -23, -32, -35, -23, 14, 26, 27, 35, 23, 32, 45,
+ 58, 47, 19, -5, -9, -10, -16, -27, -46, -48, -41, -34, -18, 11, 20, -6,
+ -10, 12, 9, -18, -34, -38, -29, -7, 17, 27, 32, 30, 30, 46, 52, 51,
+ 28, 6, -8, -9, -15, -24, -32, -41, -45, -40, -30, -1, 23, 10, -12, 2,
+ 17, -2, -31, -39, -32, -18, -6, 18, 29, 38, 32, 45, 54, 54, 33, 11,
+ 2, -9, -11, -19, -32, -33, -41, -45, -40, -18, 16, 19, 2, -6, 13, 12,
+ -20, -43, -35, -21, -18, -5, 21, 35, 36, 46, 58, 52, 38, 17, 9, -5,
+ -9, -13, -29, -32, -28, -41, -43, -36, 0, 22, 18, -4, -3, 17, 2, -33,
+ -43, -25, -18, -16, 4, 27, 38, 47, 64, 57, 40, 18, 10, 5, -7, -10,
+ -22, -39, -24, -30, -42, -39, -22, 13, 28, 14, -9, 3, 17, -16, -51, -36,
+ -17, -23, -18, 8, 35, 50, 66, 68, 43, 23, 12, 13, -1, -11, -17, -32,
+ -27, -22, -40, -38, -37, -10, 22, 34, 1, -10, 8, 6, -39, -48, -27, -19,
+ -25, -10, 18, 49, 66, 78, 54, 26, 17, 16, 3, -7, -15, -25, -29, -12,
+ -32, -37, -35, -28, 3, 38, 26, -7, -4, 11, -15, -46, -42, -26, -23, -24,
+ -2, 34, 66, 81, 70, 30, 19, 21, 10, -5, -11, -25, -29, -12, -20, -37,
+ -33, -39, -17, 25, 46, 6, -11, 2, 0, -29, -44, -41, -30, -27, -17, 12,
+ 58, 79, 84, 46, 19, 22, 19, 2, -7, -26, -35, -12, -1, -29, -33, -39,
+ -36, 3, 46, 31, -11, -6, -1, -14, -38, -46, -39, -32, -22, -5, 40, 76,
+ 88, 64, 23, 22, 30, 12, -8, -20, -39, -22, 0, -13, -29, -33, -43, -20,
+ 24, 49, 13, -12, 2, -6, -26, -45, -45, -39, -32, -15, 19, 68, 85, 77,
+ 32, 22, 35, 27, 0, -18, -36, -38, -6, 3, -17, -29, -44, -37, -2, 40,
+ 34, -8, -6, 3, -18, -44, -47, -44, -43, -21, 3, 49, 76, 80, 53, 21,
+ 35, 39, 15, -18, -35, -42, -23, 2, -3, -19, -33, -42, -23, 16, 46, 16,
+ -8, 2, -6, -37, -45, -47, -51, -33, -8, 31, 68, 74, 66, 33, 35, 45,
+ 36, -3, -33, -40, -34, -7, 5, -8, -18, -35, -39, -13, 32, 32, 3, -1,
+ 5, -26, -46, -50, -52, -44, -20, 15, 59, 68, 69, 50, 32, 42, 48, 21,
+ -26, -42, -42, -24, 2, 2, -8, -20, -38, -35, 6, 33, 17, -2, 5, -6,
+ -41, -55, -57, -46, -33, -6, 40, 64, 62, 63, 45, 38, 54, 40, -4, -42,
+ -50, -40, -11, 6, -2, -8, -24, -41, -19, 17, 28, 10, 0, 1, -26, -52,
+ -64, -51, -40, -23, 19, 54, 56, 61, 60, 38, 52, 55, 24, -30, -50, -47,
+ -27, 4, 8, -6, -11, -30, -36, -6, 19, 25, 4, 1, -9, -38, -64, -61,
+ -42, -36, 0, 44, 55, 51, 66, 50, 49, 62, 46, -5, -48, -51, -40, -11,
+ 11, 4, -14, -15, -36, -25, 1, 19, 15, -1, -2, -18, -53, -69, -48, -42,
+ -20, 21, 51, 45, 56, 62, 51, 60, 59, 23, -32, -53, -49, -28, 5, 17,
+ -12, -18, -22, -32, -12, 9, 20, 1, -6, -5, -29, -70, -62, -48, -32, 2,
+ 36, 45, 44, 62, 62, 60, 64, 47, -10, -45, -54, -42, -11, 21, 5, -19,
+ -18, -23, -20, -1, 15, 4, -6, -2, -6, -51, -72, -57, -44, -13, 19, 40,
+ 41, 51, 65, 66, 69, 63, 14, -32, -47, -50, -30, 10, 14, -12, -16, -18,
+ -16, -14, 7, 8, -6, -8, -1, -21, -65, -67, -54, -29, 1, 26, 38, 44,
+ 53, 69, 77, 73, 37, -17, -41, -46, -37, -10, 13, -1, -11, -14, -14, -10,
+ -6, 9, -5, -6, -11, -3, -43, -67, -68, -42, -15, 12, 27, 40, 47, 65,
+ 80, 83, 55, 7, -34, -43, -34, -22, -5, 2, -3, -2, -13, -10, -11, 3,
+ -2, -4, -13, -5, -15, -51, -72, -63, -31, -3, 16, 29, 42, 55, 78, 91,
+ 68, 25, -11, -40, -32, -22, -21, -9, -1, 8, -1, -19, -11, -3, 1, -5,
+ -11, -12, -3, -29, -58, -70, -48, -18, 6, 15, 35, 50, 68, 89, 84, 37,
+ 11, -27, -38, -19, -20, -23, -8, 10, 18, -10, -19, -8, 4, 0, -11, -14,
+ -7, -20, -42, -63, -60, -37, -4, 7, 23, 41, 67, 82, 90, 53, 19, -4,
+ -34, -23, -20, -31, -22, 5, 25, 8, -17, -20, 0, 10, -5, -20, -9, -12,
+ -31, -47, -60, -53, -26, -3, 12, 32, 58, 81, 85, 70, 27, 9, -19, -26,
+ -19, -28, -31, -8, 24, 21, -2, -26, -11, 14, 10, -20, -18, -8, -24, -33,
+ -53, -56, -44, -23, 3, 22, 44, 77, 85, 74, 40, 17, -3, -21, -21, -24,
+ -36, -25, 11, 22, 15, -13, -28, 5, 23, 0, -28, -12, -19, -26, -42, -56,
+ -48, -39, -17, 12, 34, 62, 84, 73, 52, 26, 9, -12, -21, -22, -31, -30,
+ -1, 15, 16, 6, -25, -14, 23, 19, -17, -21, -13, -24, -34, -54, -44, -39,
+ -36, -9, 27, 46, 79, 79, 59, 38, 16, -2, -17, -25, -25, -27, -10, 5,
+ 10, 15, -4, -24, 5, 29, 5, -24, -18, -19, -28, -48, -50, -35, -38, -28,
+ 10, 33, 62, 82, 62, 46, 27, 4, -8, -23, -24, -25, -15, -3, 0, 8,
+ 6, -12, -9, 22, 25, -6, -21, -22, -28, -45, -53, -39, -30, -37, -11, 20,
+ 43, 75, 66, 53, 41, 10, -8, -16, -25, -23, -15, -2, -4, -5, 4, 1,
+ -7, 8, 29, 19, -9, -21, -24, -42, -55, -48, -30, -31, -19, 5, 23, 61,
+ 74, 58, 53, 26, -7, -11, -18, -25, -14, 0, 1, -16, -8, 4, 0, 3,
+ 20, 28, 11, -16, -19, -38, -58, -55, -35, -27, -16, -1, 5, 32, 63, 61,
+ 56, 44, 3, -17, -13, -22, -19, -4, 5, -8, -21, -6, 7, 8, 12, 25,
+ 25, 2, -17, -26, -54, -64, -47, -32, -11, 5, 3, 16, 40, 60, 58, 56,
+ 26, -16, -19, -16, -20, -8, 0, -4, -20, -22, 1, 12, 9, 17, 30, 20,
+ -2, -15, -42, -68, -57, -44, -19, 11, 6, 10, 19, 42, 58, 58, 45, 6,
+ -23, -18, -13, -13, -3, -3, -10, -26, -14, 9, 15, 12, 26, 27, 10, -7,
+ -25, -61, -68, -54, -36, 10, 15, 13, 16, 19, 42, 55, 52, 31, -9, -25,
+ -18, -15, -7, -3, -9, -23, -26, -2, 15, 19, 19, 26, 18, 7, -10, -41,
+ -72, -60, -51, -8, 25, 22, 20, 13, 19, 45, 51, 44, 19, -15, -28, -15,
+ -7, -4, -9, -19, -28, -14, 6, 18, 18, 24, 22, 12, 1, -17, -55, -67,
+ -56, -35, 19, 33, 30, 20, 9, 23, 44, 48, 39, 6, -22, -25, -9, -8,
+ -9, -15, -29, -21, -3, 10, 16, 20, 23, 13, 7, -4, -31, -63, -61, -50,
+ -11, 33, 37, 30, 12, 7, 24, 44, 48, 28, -4, -28, -14, -4, -14, -14,
+ -27, -27, -8, 5, 13, 15, 19, 19, 11, 3, -12, -44, -64, -58, -31, 17,
+ 40, 39, 24, 8, 3, 30, 46, 42, 16, -18, -21, -6, -16, -18, -26, -32,
+ -15, 1, 6, 10, 10, 15, 12, 10, -3, -23, -51, -63, -50, -4, 34, 41,
+ 33, 17, -4, 10, 35, 42, 32, 5, -15, -8, -10, -18, -21, -30, -22, 0,
+ 3, -2, -2, 6, 5, 4, 3, -7, -25, -45, -45, -18, 25, 33, 32, 21,
+ 7, 8, 20, 30, 31, 20, 3, -7, -10, -14, -17, -23, -29, -12, 6, -2,
+ -11, -11, -4, 2, 3, -7, -10, -27, -33, -21, 13, 27, 23, 19, 8, 15,
+ 17, 18, 21, 23, 19, 2, -12, -10, -9, -15, -27, -28, -2, 9, -8, -18,
+ -17, -4, 9, -6, -7, -10, -17, -13, 2, 21, 20, 14, 4, 15, 25, 15,
+ 11, 14, 19, 13, -13, -17, -6, -5, -20, -36, -23, 4, 6, -18, -28, -20,
+ 6, 6, 0, 3, 5, 5, 28, 31, 31, 49, 55, 35, 11, 27, 26, 4,
+ 7, 11, 31, 54, 38, 26, 34, 35, 20, -10, -32, -43, -47, -43, -20, -7,
+ -37, -55, -62, -61, -63, -34, -21, -35, -28, -10, 15, 24, 23, 5, -31, -38,
+ -6, 23, 19, 15, 24, 20, 31, 57, 54, 28, 13, 33, 20, 1, 4, 17,
+ 38, 44, 33, 31, 43, 36, 10, -14, -34, -53, -53, -46, -22, -22, -38, -46,
+ -54, -60, -58, -29, -25, -39, -29, -12, 11, 25, 27, 6, -31, -33, -3, 27,
+ 32, 21, 13, 16, 38, 60, 53, 26, 18, 28, 11, -2, 8, 26, 37, 34,
+ 36, 42, 47, 31, 6, -14, -41, -61, -54, -49, -26, -30, -41, -40, -44, -54,
+ -48, -23, -28, -41, -33, -7, 14, 26, 29, 3, -32, -27, 6, 33, 35, 18,
+ 5, 21, 45, 61, 49, 25, 30, 22, 0, -5, 9, 37, 39, 27, 33, 47,
+ 50, 31, 1, -22, -51, -65, -59, -45, -31, -40, -36, -29, -35, -49, -41, -28,
+ -39, -44, -26, -8, 6, 27, 31, -5, -31, -18, 14, 33, 31, 17, 4, 25,
+ 48, 57, 45, 32, 27, 9, -6, -5, 14, 43, 36, 29, 39, 51, 50, 31,
+ 0, -32, -65, -73, -62, -37, -36, -46, -36, -23, -26, -37, -32, -35, -46, -42,
+ -22, -11, 2, 30, 28, -8, -29, -12, 22, 33, 32, 15, 4, 25, 49, 58,
+ 50, 36, 20, 2, -9, -3, 21, 43, 37, 32, 44, 55, 53, 33, -7, -42,
+ -67, -72, -64, -43, -43, -46, -35, -17, -17, -24, -31, -40, -47, -39, -18, -15,
+ 0, 33, 22, -14, -22, 5, 29, 29, 28, 11, 7, 23, 49, 54, 50, 37,
+ 13, -6, -11, -6, 25, 44, 38, 26, 40, 57, 54, 28, -12, -48, -70, -73,
+ -66, -43, -43, -43, -29, -12, -15, -16, -32, -48, -51, -38, -24, -19, 4, 31,
+ 12, -16, -14, 21, 34, 24, 24, 13, 10, 27, 49, 53, 53, 33, 6, -9,
+ -16, -4, 33, 48, 37, 24, 45, 61, 54, 23, -15, -60, -76, -76, -60, -48,
+ -45, -38, -26, -11, -3, -5, -33, -49, -52, -35, -25, -21, 7, 24, 1, -15,
+ -1, 34, 30, 23, 29, 17, 5, 26, 49, 55, 53, 26, -3, -16, -16, 4,
+ 38, 43, 33, 33, 49, 59, 45, 19, -18, -63, -78, -79, -58, -50, -39, -31,
+ -21, -11, -2, -3, -30, -49, -51, -35, -29, -20, 8, 12, -10, -11, 17, 37,
+ 27, 29, 29, 13, 2, 33, 56, 55, 38, 18, -7, -19, -17, 13, 40, 42,
+ 33, 35, 52, 58, 40, 10, -28, -68, -84, -78, -56, -47, -36, -30, -17, -7,
+ 5, -4, -30, -49, -51, -34, -30, -18, 10, 1, -18, -9, 30, 39, 26, 32,
+ 28, 9, 7, 38, 51, 45, 35, 16, -13, -28, -11, 27, 41, 41, 34, 45,
+ 58, 54, 29, 7, -33, -69, -80, -78, -59, -43, -31, -24, -15, -3, 9, -4,
+ -29, -51, -51, -33, -27, -8, 8, -13, -24, -1, 40, 41, 29, 31, 22, 7,
+ 15, 46, 48, 38, 33, 11, -19, -28, -7, 26, 42, 36, 39, 54, 54, 48,
+ 20, 3, -39, -68, -79, -78, -54, -37, -32, -27, -16, 5, 11, -6, -31, -50,
+ -49, -33, -24, -3, -3, -29, -26, 13, 44, 36, 30, 32, 17, 7, 28, 43,
+ 37, 31, 28, 4, -17, -27, -5, 24, 46, 43, 48, 56, 50, 41, 20, -1,
+ -47, -64, -82, -78, -48, -35, -34, -26, -14, 6, 9, -10, -31, -46, -43, -33,
+ -21, 1, -16, -38, -15, 24, 38, 35, 44, 33, 10, 15, 37, 43, 30, 22,
+ 18, 4, -20, -29, 0, 30, 43, 48, 54, 52, 46, 35, 19, -9, -41, -60,
+ -83, -73, -44, -29, -37, -27, -12, 6, 8, -10, -28, -45, -43, -25, -9, -3,
+ -33, -43, -4, 32, 35, 37, 49, 24, 7, 26, 47, 35, 17, 11, 14, 3,
+ -21, -30, 6, 30, 44, 60, 56, 44, 37, 33, 15, -11, -40, -63, -82, -61,
+ -36, -33, -39, -26, -13, 0, 4, -9, -29, -42, -37, -18, -7, -13, -39, -34,
+ 2, 30, 34, 45, 49, 16, 11, 37, 45, 26, 11, 8, 9, -1, -26, -25,
+ 17, 31, 46, 62, 52, 42, 29, 26, 15, -12, -45, -64, -71, -48, -34, -35,
+ -33, -27, -16, 1, 2, -10, -23, -41, -32, -12, -6, -29, -46, -28, 12, 26,
+ 36, 54, 43, 10, 23, 52, 43, 18, -2, 5, 5, -7, -25, -11, 19, 22,
+ 49, 61, 50, 40, 24, 20, 15, -10, -47, -62, -62, -45, -34, -30, -30, -23,
+ -16, -6, -1, -8, -25, -38, -29, -9, -10, -39, -42, -19, 5, 23, 48, 57,
+ 33, 7, 32, 57, 39, 8, -7, 3, -2, -16, -16, 1, 20, 22, 48, 55,
+ 46, 39, 17, 16, 17, -9, -48, -58, -54, -40, -37, -28, -26, -22, -23, -5,
+ 2, -11, -28, -37, -27, -10, -18, -44, -35, -18, 3, 31, 54, 52, 25, 13,
+ 45, 61, 29, -4, -10, 0, -5, -16, -8, 4, 21, 21, 50, 54, 45, 31,
+ 4, 20, 18, -15, -43, -48, -48, -39, -33, -28, -25, -22, -21, 0, -1, -19,
+ -29, -29, -22, -11, -29, -42, -30, -17, 3, 38, 61, 46, 24, 25, 53, 58,
+ 20, -10, -9, -5, -16, -12, 4, 11, 22, 17, 48, 51, 43, 16, 2, 18,
+ 13, -15, -35, -46, -43, -38, -31, -23, -27, -24, -13, 3, -8, -25, -29, -27,
+ -22, -18, -36, -38, -31, -19, 6, 46, 60, 36, 24, 33, 56, 44, 10, -8,
+ -9, -12, -24, -7, 14, 23, 18, 11, 45, 47, 39, 13, 5, 16, 1, -19,
+ -22, -39, -45, -45, -31, -20, -24, -16, -6, -3, -19, -24, -25, -26, -22, -24,
+ -39, -35, -25, -13, 8, 54, 64, 36, 29, 41, 56, 36, 5, -12, -11, -14,
+ -26, -6, 24, 33, 7, 12, 45, 44, 30, 13, 10, 17, -4, -17, -16, -34,
+ -46, -50, -30, -20, -23, -12, 1, -11, -26, -27, -24, -21, -19, -34, -48, -32,
+ -23, -10, 13, 66, 65, 33, 32, 48, 55, 25, 0, -8, -1, -18, -36, -4,
+ 40, 33, -1, 17, 37, 35, 25, 10, 14, 10, -13, -15, -9, -26, -46, -51,
+ -32, -18, -15, -4, 3, -17, -31, -28, -25, -20, -26, -48, -48, -27, -20, -13,
+ 19, 71, 61, 28, 33, 56, 50, 12, -8, -2, 5, -24, -41, 2, 52, 29,
+ -1, 24, 36, 26, 16, 14, 19, 6, -19, -12, 1, -21, -49, -50, -28, -12,
+ -3, 2, -2, -25, -32, -29, -24, -14, -31, -61, -44, -17, -15, -9, 28, 72,
+ 61, 25, 38, 61, 41, 7, -7, 4, 3, -32, -36, 9, 45, 21, 4, 30,
+ 33, 15, 11, 18, 17, -1, -18, -7, -4, -22, -47, -45, -24, -6, 2, 5,
+ -7, -27, -34, -28, -21, -14, -42, -69, -40, -11, -16, -3, 41, 68, 53, 29,
+ 48, 61, 32, 0, -5, 8, 2, -33, -28, 9, 31, 16, 16, 34, 22, 0,
+ 10, 24, 10, -9, -19, -6, -8, -26, -38, -34, -20, -10, 1, 11, -9, -33,
+ -31, -32, -25, -18, -50, -65, -40, -15, -8, 13, 47, 65, 50, 33, 54, 62,
+ 24, -2, 2, 12, -6, -31, -20, 12, 21, 10, 28, 34, 9, -5, 20, 20,
+ -2, -13, -10, -4, -18, -33, -26, -16, -19, -14, 6, 8, -14, -31, -32, -29,
+ -29, -31, -51, -69, -47, -12, 2, 21, 49, 56, 43, 45, 62, 54, 16, -2,
+ 7, 9, -13, -22, -4, 12, 7, 13, 37, 33, 7, -4, 23, 9, -8, -8,
+ -2, -8, -33, -38, -7, -1, -22, -19, 11, 7, -21, -29, -29, -29, -31, -32,
+ -55, -80, -49, -7, 16, 31, 43, 45, 44, 56, 66, 45, 12, 2, 10, 3,
+ -18, -13, 7, 9, -2, 17, 38, 22, 1, 5, 17, 4, -14, -12, -1, -11,
+ -43, -38, 6, 5, -22, -15, 12, 0, -23, -26, -28, -31, -32, -36, -60, -82,
+ -46, 3, 24, 35, 38, 41, 46, 59, 62, 41, 13, -1, 3, -6, -18, 3,
+ 22, 2, -9, 20, 36, 18, 10, 7, 4, -5, -17, -9, -2, -18, -55, -30,
+ 17, 6, -20, -10, 6, -5, -16, -26, -32, -27, -30, -42, -69, -84, -41, 13,
+ 31, 42, 37, 38, 45, 63, 65, 41, 12, 3, 1, -18, -10, 23, 27, -2,
+ -12, 17, 36, 26, 13, 4, -2, -5, -14, -14, -11, -26, -54, -19, 21, 8,
+ -16, -8, 6, -7, -20, -30, -33, -24, -33, -50, -74, -82, -32, 18, 34, 42,
+ 38, 34, 50, 69, 58, 34, 16, 7, -9, -29, -2, 41, 32, -7, -15, 11,
+ 34, 30, 9, 2, -3, -7, -23, -21, -15, -30, -52, -10, 18, 10, -8, -4,
+ 5, -4, -25, -33, -26, -22, -42, -59, -79, -72, -20, 23, 36, 41, 37, 34,
+ 54, 74, 53, 22, 17, 15, -17, -34, 10, 52, 37, -8, -11, 12, 33, 23,
+ 8, 4, -1, -16, -31, -25, -18, -38, -49, -3, 19, 11, -4, 0, 7, -8,
+ -34, -31, -19, -26, -52, -62, -79, -55, -7, 23, 41, 47, 41, 33, 61, 75,
+ 43, 22, 21, 13, -26, -33, 17, 58, 39, -6, -8, 13, 27, 10, 5, 13,
+ -2, -32, -43, -32, -19, -38, -36, -3, 12, 4, 4, 13, 6, -22, -41, -31,
+ -13, -33, -59, -71, -76, -35, 2, 20, 39, 53, 47, 39, 60, 62, 37, 26,
+ 22, 5, -33, -29, 26, 64, 40, 0, -5, 12, 21, 8, 16, 10, -13, -39,
+ -49, -37, -25, -41, -30, -6, 9, 9, 13, 23, 0, -30, -44, -26, -13, -45,
+ -67, -76, -68, -20, 10, 19, 39, 55, 50, 46, 57, 50, 37, 30, 16, -3,
+ -34, -22, 34, 65, 40, 13, -2, 6, 19, 12, 21, 5, -23, -49, -52, -38,
+ -33, -36, -24, -9, 10, 12, 25, 23, -11, -29, -43, -27, -21, -55, -73, -77,
+ -50, -2, 19, 19, 35, 59, 59, 49, 45, 40, 36, 27, 4, -10, -24, -12,
+ 31, 59, 44, 22, -5, 4, 19, 20, 12, -4, -27, -52, -50, -45, -39, -24,
+ -23, -13, 16, 20, 30, 15, -16, -28, -37, -30, -36, -64, -79, -73, -28, 17,
+ 24, 14, 36, 65, 68, 45, 33, 39, 40, 22, -2, -5, -11, -11, 28, 58,
+ 57, 20, -13, 0, 27, 23, 1, -15, -35, -58, -55, -52, -39, -20, -22, -9,
+ 20, 29, 30, 10, -15, -31, -39, -32, -48, -72, -86, -59, -4, 27, 19, 17,
+ 44, 77, 69, 31, 26, 40, 38, 14, -6, 0, 1, -11, 26, 67, 62, 10,
+ -18, 6, 31, 20, -5, -22, -44, -66, -61, -50, -31, -17, -24, -7, 24, 34,
+ 31, 3, -17, -31, -36, -40, -61, -73, -76, -46, 11, 34, 20, 22, 56, 83,
+ 60, 22, 24, 46, 32, 5, -4, 9, 0, -8, 31, 73, 53, 0, -13, 16,
+ 28, 14, -15, -31, -51, -74, -64, -43, -25, -22, -25, -1, 30, 37, 20, -2,
+ -20, -36, -39, -55, -69, -75, -69, -32, 21, 36, 22, 31, 63, 76, 50, 22,
+ 25, 49, 29, 3, 4, 9, 2, 0, 43, 74, 37, -8, -1, 28, 24, 8,
+ -22, -42, -65, -80, -60, -31, -25, -31, -24, 8, 41, 37, 10, -3, -22, -40,
+ -45, -60, -69, -69, -55, -15, 32, 37, 25, 42, 72, 70, 37, 21, 32, 41,
+ 20, 5, 15, 8, 0, 9, 46, 62, 26, -7, 8, 28, 21, 4, -29, -53,
+ -79, -82, -57, -25, -27, -32, -21, 14, 48, 35, -1, -7, -24, -44, -52, -70,
+ -69, -60, -38, 1, 34, 33, 32, 57, 70, 58, 34, 26, 31, 31, 16, 14,
+ 14, 3, 8, 25, 47, 47, 18, -2, 13, 25, 19, -2, -33, -64, -87, -83,
+ -53, -24, -29, -32, -17, 21, 46, 27, -4, -12, -30, -51, -61, -73, -60, -46,
+ -17, 9, 25, 32, 47, 69, 61, 48, 41, 30, 26, 24, 18, 24, 15, 2,
+ 14, 37, 42, 34, 17, 9, 19, 20, 11, -7, -35, -79, -97, -79, -45, -21,
+ -29, -33, -12, 26, 43, 27, -3, -15, -43, -58, -66, -69, -52, -37, -2, 16,
+ 24, 38, 61, 72, 56, 43, 41, 32, 28, 22, 22, 26, 12, 1, 23, 45,
+ 34, 21, 8, 17, 22, 19, 4, -18, -47, -93, -97, -70, -40, -29, -33, -22,
+ -5, 24, 44, 19, -6, -23, -53, -60, -74, -63, -41, -20, 10, 18, 19, 40,
+ 70, 70, 47, 41, 43, 37, 27, 14, 24, 32, 10, 1, 29, 44, 27, 12,
+ 7, 28, 32, 9, -11, -27, -56, -100, -94, -64, -43, -38, -31, -7, 0, 27,
+ 41, 11, -7, -35, -60, -62, -75, -54, -29, -5, 17, 22, 14, 46, 80, 72,
+ 46, 42, 44, 42, 24, 16, 31, 32, 9, 4, 33, 45, 22, 5, 8, 41,
+ 34, 0, -22, -36, -69, -100, -92, -65, -40, -44, -25, 0, 5, 28, 36, 4,
+ -12, -50, -64, -64, -68, -46, -19, 2, 25, 28, 19, 44, 72, 67, 46, 45,
+ 44, 39, 21, 21, 38, 29, 1, 9, 39, 39, 13, -4, 9, 54, 41, -11,
+ -38, -51, -76, -91, -92, -65, -44, -47, -17, 12, 11, 21, 27, 6, -24, -59,
+ -65, -67, -61, -40, -17, 8, 31, 26, 20, 49, 74, 65, 45, 48, 47, 36,
+ 25, 28, 36, 25, 5, 19, 42, 28, 6, -2, 21, 56, 27, -22, -45, -62,
+ -83, -92, -84, -65, -49, -37, -8, 15, 16, 22, 23, -1, -38, -65, -66, -65,
+ -51, -35, -15, 20, 42, 26, 25, 51, 70, 60, 45, 52, 47, 25, 25, 39,
+ 33, 24, 16, 31, 37, 14, 3, 2, 33, 55, 14, -35, -55, -67, -84, -88,
+ -84, -68, -47, -28, -1, 17, 22, 24, 17, -14, -54, -66, -64, -61, -46, -32,
+ -10, 26, 45, 24, 29, 52, 66, 57, 49, 56, 41, 16, 29, 46, 31, 22,
+ 24, 37, 30, 12, -1, 5, 40, 39, 1, -41, -63, -72, -89, -89, -77, -62,
+ -48, -17, 5, 13, 26, 31, 10, -29, -62, -64, -65, -54, -41, -25, -4, 32,
+ 52, 29, 32, 55, 61, 55, 56, 57, 35, 17, 33, 40, 28, 27, 37, 36,
+ 26, 14, -3, 13, 41, 22, -13, -45, -65, -78, -90, -87, -70, -56, -47, -12,
+ 9, 18, 35, 27, -5, -41, -63, -61, -65, -52, -37, -17, 5, 35, 52, 34,
+ 38, 55, 58, 53, 60, 54, 31, 21, 33, 34, 30, 35, 40, 32, 29, 15,
+ -4, 18, 30, 11, -25, -53, -69, -85, -91, -82, -66, -54, -36, -7, 6, 20,
+ 40, 19, -17, -52, -63, -60, -65, -50, -32, -11, 9, 34, 50, 40, 46, 51,
+ 56, 60, 60, 50, 28, 23, 33, 33, 31, 40, 43, 38, 38, 13, -6, 13,
+ 19, -2, -34, -57, -78, -91, -85, -73, -63, -55, -28, -1, 6, 26, 39, 13,
+ -28, -56, -61, -55, -61, -43, -27, -13, 12, 38, 48, 49, 54, 46, 52, 64,
+ 64, 48, 27, 22, 28, 33, 36, 44, 42, 39, 44, 15, -3, 10, 6, -19,
+ -46, -60, -81, -92, -83, -73, -52, -44, -22, -5, 5, 38, 37, -6, -41, -55,
+ -54, -49, -53, -45, -28, -9, 19, 41, 47, 56, 57, 41, 56, 69, 64, 42,
+ 26, 23, 27, 36, 39, 44, 39, 48, 53, 12, -4, 2, -8, -33, -61, -72,
+ -84, -87, -80, -73, -49, -36, -12, -5, 9, 42, 24, -15, -44, -50, -51, -51,
+ -51, -45, -26, -4, 20, 40, 47, 64, 58, 38, 61, 71, 55, 37, 32, 23,
+ 30, 34, 39, 50, 43, 58, 53, 9, 4, -3, -27, -49, -71, -79, -79, -79,
+ -82, -70, -44, -26, -7, -5, 16, 36, 9, -18, -40, -47, -49, -45, -42, -43,
+ -20, 1, 21, 40, 53, 72, 54, 36, 64, 66, 41, 30, 36, 26, 28, 31,
+ 44, 57, 48, 62, 45, 13, 3, -14, -47, -65, -77, -87, -78, -71, -75, -68,
+ -43, -16, -2, -1, 18, 20, -4, -18, -37, -46, -50, -36, -39, -46, -15, 7,
+ 23, 41, 62, 72, 49, 41, 69, 59, 33, 29, 38, 24, 28, 31, 52, 59,
+ 49, 61, 45, 21, 2, -31, -64, -73, -78, -89, -79, -71, -77, -62, -36, -8,
+ 3, 5, 15, 5, -10, -17, -34, -49, -50, -27, -37, -43, -12, 14, 25, 45,
+ 67, 68, 48, 48, 64, 48, 27, 33, 41, 25, 24, 32, 64, 66, 51, 62,
+ 41, 21, -7, -43, -77, -81, -83, -87, -74, -71, -77, -54, -29, -1, 7, 13,
+ 12, -6, -9, -18, -38, -54, -44, -21, -37, -41, -8, 16, 28, 53, 73, 61,
+ 46, 52, 60, 35, 25, 34, 38, 20, 25, 42, 73, 62, 60, 58, 39, 22,
+ -19, -54, -85, -88, -95, -88, -65, -69, -73, -47, -22, 3, 14, 15, -5, -14,
+ -6, -23, -42, -52, -34, -19, -42, -38, 0, 18, 30, 62, 76, 61, 49, 52,
+ 49, 26, 23, 34, 33, 22, 21, 50, 78, 68, 66, 47, 40, 22, -23, -66,
+ -95, -102, -97, -74, -61, -77, -68, -36, -12, 9, 15, 13, -18, -14, -5, -31,
+ -50, -44, -21, -25, -49, -25, 8, 16, 30, 70, 82, 56, 45, 55, 39, 21,
+ 25, 31, 24, 21, 28, 64, 81, 68, 64, 47, 44, 15, -30, -77, -101, -104,
+ -96, -71, -66, -76, -53, -22, -9, 6, 22, 10, -22, -15, -13, -38, -48, -32,
+ -9, -33, -49, -14, 10, 11, 37, 77, 85, 51, 44, 48, 30, 18, 21, 26,
+ 16, 21, 36, 71, 76, 73, 68, 48, 35, 4, -38, -81, -103, -109, -91, -67,
+ -71, -69, -40, -15, -12, 3, 23, 7, -23, -17, -24, -41, -45, -24, -11, -46,
+ -46, -1, 10, 8, 49, 84, 83, 48, 50, 48, 27, 16, 18, 20, 14, 26,
+ 44, 72, 75, 82, 71, 47, 26, -6, -45, -80, -107, -110, -88, -70, -69, -58,
+ -28, -9, -12, 2, 23, 2, -21, -19, -35, -38, -33, -13, -17, -50, -35, 8,
+ 9, 10, 57, 89, 74, 45, 52, 41, 24, 15, 11, 14, 13, 22, 54, 72,
+ 74, 86, 72, 41, 13, -14, -47, -86, -113, -111, -88, -72, -67, -42, -18, -11,
+ -11, 2, 18, -2, -17, -27, -44, -37, -28, -12, -26, -49, -22, 9, 3, 21,
+ 69, 87, 63, 46, 49, 36, 24, 13, 11, 11, 8, 26, 64, 68, 76, 89,
+ 74, 38, 3, -17, -44, -86, -117, -114, -86, -65, -58, -38, -19, -7, 0, 8,
+ 9, -5, -20, -37, -45, -29, -19, -15, -36, -39, -10, 6, 4, 33, 79, 81,
+ 55, 48, 42, 30, 23, 10, 13, 10, 3, 27, 62, 60, 76, 88, 68, 30,
+ -5, -21, -49, -89, -120, -115, -81, -54, -46, -34, -14, -1, 7, 9, 1, -6,
+ -18, -45, -52, -29, -16, -17, -35, -36, -12, 5, 11, 47, 81, 72, 53, 51,
+ 39, 28, 24, 9, 13, 7, 5, 36, 57, 55, 82, 90, 62, 31, -10, -29,
+ -55, -91, -121, -115, -76, -47, -38, -34, -13, 1, 13, 9, -4, -9, -17, -49,
+ -56, -26, -9, -12, -33, -40, -17, 12, 25, 57, 71, 62, 52, 50, 35, 22,
+ 21, 14, 11, -2, 10, 41, 50, 48, 85, 87, 66, 29, -15, -34, -64, -97,
+ -121, -108, -73, -43, -37, -28, -7, 7, 16, 6, -7, -5, -15, -59, -56, -19,
+ -4, -14, -37, -42, -10, 21, 38, 66, 63, 57, 52, 49, 28, 22, 28, 16,
+ 5, -3, 22, 47, 38, 45, 79, 85, 68, 23, -16, -34, -70, -100, -122, -107,
+ -62, -39, -38, -25, -4, 15, 18, 2, -3, 0, -27, -70, -51, -17, -3, -16,
+ -44, -40, -1, 27, 45, 67, 57, 54, 48, 39, 17, 18, 28, 17, 3, -3,
+ 27, 49, 37, 42, 69, 86, 66, 16, -17, -37, -72, -99, -117, -101, -55, -39,
+ -36, -24, 1, 20, 13, 4, 4, -5, -46, -74, -43, -9, -4, -28, -49, -33,
+ 6, 33, 63, 68, 54, 53, 49, 33, 18, 21, 24, 15, 7, 9, 33, 42,
+ 35, 39, 70, 85, 55, 10, -16, -40, -75, -98, -113, -92, -47, -38, -35, -21,
+ 1, 21, 15, 8, 7, -14, -62, -70, -30, -11, -15, -34, -49, -23, 9, 39,
+ 64, 58, 51, 56, 42, 20, 16, 19, 16, 16, 4, 13, 40, 46, 33, 31,
+ 65, 83, 49, 3, -24, -41, -73, -98, -105, -77, -45, -41, -30, -13, 7, 19,
+ 12, 13, 8, -26, -68, -61, -22, -14, -25, -38, -40, -18, 12, 47, 68, 59,
+ 49, 51, 42, 19, 17, 17, 12, 13, 5, 18, 41, 47, 26, 26, 67, 78,
+ 44, -2, -31, -47, -71, -97, -96, -67, -44, -42, -29, -11, 13, 21, 13, 17,
+ 8, -34, -68, -54, -17, -18, -36, -43, -35, -12, 14, 50, 69, 56, 49, 44,
+ 35, 16, 13, 17, 13, 13, 6, 27, 46, 50, 24, 28, 66, 64, 28, 0,
+ -25, -49, -75, -99, -87, -54, -42, -38, -28, -8, 20, 19, 11, 17, 1, -41,
+ -62, -49, -18, -27, -41, -39, -29, -8, 15, 55, 73, 55, 42, 42, 33, 16,
+ 12, 12, 9, 6, 14, 40, 52, 48, 21, 31, 60, 50, 23, 0, -32, -60,
+ -76, -90, -73, -44, -39, -36, -32, 1, 29, 20, 6, 13, -3, -41, -53, -43,
+ -21, -34, -47, -38, -22, -2, 22, 54, 65, 49, 38, 42, 32, 17, 12, 7,
+ 6, 3, 21, 48, 53, 42, 24, 39, 53, 38, 15, -3, -38, -65, -76, -85,
+ -59, -36, -35, -40, -26, 15, 26, 12, 6, 10, -12, -40, -49, -33, -26, -41,
+ -53, -36, -12, 5, 28, 50, 61, 46, 34, 37, 31, 20, 12, 1, 0, 5,
+ 32, 53, 56, 41, 23, 39, 48, 35, 13, -10, -44, -72, -81, -79, -50, -27,
+ -34, -41, -18, 20, 27, 12, 5, 1, -19, -36, -40, -22, -34, -50, -55, -33,
+ -3, 14, 33, 52, 54, 35, 27, 36, 37, 25, 7, -13, 1, 19, 41, 50,
+ 50, 38, 32, 43, 41, 32, 6, -17, -46, -69, -79, -75, -43, -20, -34, -38,
+ -8, 23, 26, 12, 6, -8, -23, -30, -30, -23, -46, -56, -52, -29, 6, 23,
+ 35, 44, 47, 31, 25, 33, 40, 26, -4, -22, 3, 28, 39, 40, 50, 40,
+ 28, 34, 37, 28, 0, -22, -50, -70, -81, -72, -34, -22, -36, -33, 2, 24,
+ 25, 12, 4, -15, -24, -26, -25, -23, -46, -56, -50, -24, 10, 33, 36, 40,
+ 35, 21, 25, 43, 47, 25, -13, -25, 11, 40, 36, 40, 56, 38, 27, 31,
+ 33, 24, -4, -24, -53, -71, -80, -59, -34, -27, -31, -27, 8, 24, 25, 17,
+ 2, -22, -25, -26, -19, -24, -51, -58, -40, -9, 14, 37, 36, 35, 27, 14,
+ 28, 48, 46, 19, -19, -24, 18, 40, 29, 41, 50, 29, 29, 27, 33, 18,
+ -12, -29, -53, -71, -75, -48, -33, -32, -25, -14, 13, 24, 19, 17, 2, -25,
+ -28, -28, -18, -28, -55, -59, -30, -3, 20, 41, 34, 24, 15, 15, 36, 49,
+ 39, 17, -17, -17, 22, 41, 33, 45, 38, 26, 30, 24, 27, 10, -11, -34,
+ -58, -70, -66, -38, -32, -36, -21, -2, 14, 28, 19, 14, 0, -25, -29, -28,
+ -17, -30, -57, -51, -22, 3, 23, 39, 34, 15, 11, 17, 38, 46, 39, 15,
+ -18, -14, 27, 40, 37, 45, 32, 28, 30, 29, 28, 1, -16, -38, -55, -65,
+ -62, -37, -31, -34, -17, 9, 18, 27, 18, 9, -1, -22, -35, -29, -17, -32,
+ -57, -45, -17, 15, 30, 30, 25, 8, 10, 19, 35, 46, 37, 4, -19, -8,
+ 31, 33, 33, 42, 28, 22, 24, 29, 23, -6, -21, -43, -54, -59, -55, -32,
+ -34, -39, -10, 19, 30, 25, 9, 2, -2, -20, -38, -30, -23, -41, -51, -35,
+ -12, 24, 32, 22, 12, 8, 16, 23, 32, 48, 33, 1, -16, 0, 29, 30,
+ 33, 36, 24, 23, 22, 33, 14, -14, -20, -42, -55, -50, -44, -27, -38, -41,
+ -3, 31, 35, 23, 5, -2, -4, -15, -34, -33, -38, -47, -40, -26, -3, 31,
+ 31, 9, 2, 13, 14, 20, 38, 53, 27, -6, -14, 11, 30, 23, 32, 28,
+ 25, 22, 24, 32, 5, -20, -26, -45, -49, -40, -36, -37, -48, -40, 8, 40,
+ 37, 16, -3, -6, -2, -9, -27, -42, -52, -48, -32, -21, 8, 39, 28, -2,
+ -5, 13, 17, 23, 40, 45, 19, -4, -3, 18, 15, 19, 33, 30, 29, 22,
+ 21, 22, 0, -17, -27, -46, -48, -33, -31, -38, -53, -33, 23, 43, 31, 11,
+ -7, -5, -3, -8, -26, -49, -59, -48, -25, -14, 15, 41, 23, -8, -6, 11,
+ 10, 26, 49, 41, 12, 0, 10, 19, 4, 22, 31, 25, 25, 24, 20, 12,
+ -4, -10, -37, -50, -37, -23, -26, -43, -55, -18, 34, 41, 28, 10, -9, -6,
+ -3, -8, -27, -57, -62, -37, -15, -8, 24, 44, 23, -10, -6, 3, 8, 39,
+ 55, 30, 12, 11, 20, 8, 3, 27, 26, 20, 21, 24, 19, -1, -10, -14,
+ -42, -47, -25, -14, -28, -49, -50, -5, 38, 38, 23, 9, -11, -9, -1, -5,
+ -33, -64, -59, -34, -14, -2, 32, 49, 17, -11, -6, -2, 11, 46, 46, 19,
+ 16, 23, 24, -3, 3, 29, 29, 16, 17, 22, 11, -12, -12, -18, -50, -43,
+ -15, -11, -30, -53, -38, 10, 31, 31, 25, 3, -16, -3, 3, -8, -41, -67,
+ -53, -24, -14, 3, 35, 46, 17, -2, -7, -9, 16, 49, 41, 20, 22, 34,
+ 21, -5, 5, 31, 29, 12, 14, 18, 8, -22, -17, -20, -52, -38, -13, -19,
+ -32, -48, -25, 11, 23, 29, 26, 1, -14, 1, 1, -18, -47, -60, -47, -31,
+ -11, 13, 45, 39, 8, -2, -2, -11, 16, 43, 35, 25, 34, 40, 18, -7,
+ 6, 34, 28, 14, 7, 11, 2, -23, -25, -29, -51, -30, -11, -24, -38, -40,
+ -15, 9, 18, 29, 32, -1, -10, 0, -9, -27, -48, -52, -46, -30, -2, 27,
+ 47, 30, 10, 7, -6, -15, 12, 35, 28, 30, 45, 42, 19, -4, 11, 29,
+ 21, 6, 1, 3, -3, -27, -31, -34, -40, -22, -18, -31, -35, -30, -18, 5,
+ 19, 32, 28, -9, -7, 1, -14, -30, -42, -45, -47, -28, 7, 38, 45, 23,
+ 14, 20, -2, -24, 7, 32, 30, 37, 43, 41, 22, 7, 18, 22, 14, 4,
+ -7, 4, -7, -36, -37, -37, -27, -15, -26, -34, -34, -29, -18, 4, 19, 31,
+ 20, -4, 0, -3, -21, -32, -37, -41, -40, -25, 14, 49, 44, 18, 19, 25,
+ -1, -19, 5, 26, 35, 38, 46, 41, 18, 18, 16, 13, 12, 2, -5, -3,
+ -23, -44, -37, -32, -20, -20, -33, -28, -32, -32, -16, 1, 17, 31, 17, -2,
+ 2, -3, -22, -33, -39, -40, -34, -23, 15, 56, 44, 15, 27, 23, -4, -14,
+ 2, 22, 38, 37, 48, 40, 25, 24, 15, 11, 2, -2, -3, -15, -31, -40,
+ -37, -33, -17, -17, -28, -29, -41, -34, -7, 1, 13, 31, 17, -2, 4, 1,
+ -20, -35, -47, -37, -24, -10, 22, 52, 38, 26, 35, 26, -2, -9, 4, 23,
+ 40, 38, 46, 39, 32, 31, 16, 2, -7, -8, -2, -21, -38, -44, -38, -31,
+ -18, -15, -29, -35, -45, -32, -1, -3, 4, 30, 16, 3, 8, 4, -20, -42,
+ -48, -30, -17, -8, 21, 49, 41, 30, 38, 23, -2, -5, 1, 21, 35, 37,
+ 44, 40, 40, 33, 17, 1, -13, -10, -9, -35, -41, -41, -39, -33, -19, -12,
+ -27, -40, -48, -28, -4, -10, 10, 28, 15, 9, 12, 5, -24, -43, -43, -23,
+ -18, 0, 26, 47, 43, 35, 40, 20, -1, 1, 4, 20, 28, 37, 42, 42,
+ 46, 31, 22, 8, -17, -15, -15, -42, -41, -37, -44, -37, -16, -13, -33, -41,
+ -41, -20, -11, -17, 10, 18, 13, 16, 17, 1, -24, -38, -38, -27, -21, 9,
+ 29, 46, 44, 43, 38, 18, 3, 6, 6, 12, 19, 38, 41, 47, 44, 28,
+ 29, 11, -26, -25, -27, -45, -39, -39, -48, -41, -18, -13, -33, -38, -36, -21,
+ -19, -14, 13, 11, 11, 26, 17, -6, -25, -32, -32, -35, -14, 21, 31, 38,
+ 49, 49, 34, 19, 13, 10, 4, 9, 20, 37, 41, 45, 39, 29, 35, 6,
+ -28, -28, -35, -43, -37, -42, -50, -44, -20, -20, -37, -37, -27, -16, -23, -11,
+ 10, 5, 17, 36, 16, -16, -23, -21, -33, -38, -5, 23, 28, 35, 55, 55,
+ 31, 17, 18, 12, 3, 4, 21, 33, 41, 45, 31, 32, 39, 3, -29, -35,
+ -41, -40, -38, -45, -55, -45, -26, -31, -36, -26, -22, -22, -29, 1, 9, -1,
+ 24, 39, 8, -19, -17, -14, -32, -34, 5, 29, 29, 35, 58, 51, 32, 29,
+ 23, 11, 1, 6, 29, 37, 38, 36, 24, 43, 39, -2, -32, -44, -45, -36,
+ -36, -45, -55, -51, -37, -35, -30, -22, -20, -32, -24, 6, 2, 3, 30, 36,
+ 3, -17, -16, -18, -29, -24, 10, 31, 25, 34, 58, 44, 33, 37, 26, 8,
+ 5, 10, 37, 36, 35, 29, 22, 47, 36, -6, -36, -51, -49, -34, -38, -48,
+ -58, -53, -46, -42, -24, -23, -22, -32, -13, 4, -7, 8, 35, 30, 6, -14,
+ -20, -19, -21, -20, 14, 34, 29, 43, 52, 37, 39, 43, 24, 8, 7, 15,
+ 45, 33, 36, 24, 25, 43, 25, -10, -39, -53, -47, -34, -39, -53, -56, -54,
+ -56, -42, -21, -23, -29, -25, -5, 1, -10, 12, 35, 27, 7, -14, -25, -19,
+ -11, -10, 13, 31, 37, 44, 42, 37, 45, 44, 24, 14, 13, 24, 40, 28,
+ 35, 23, 31, 35, 15, -16, -38, -53, -45, -37, -48, -56, -54, -63, -63, -40,
+ -23, -24, -27, -19, 3, 1, -11, 14, 33, 24, 5, -16, -28, -17, -6, -1,
+ 15, 38, 39, 38, 29, 36, 54, 42, 20, 20, 19, 32, 38, 30, 31, 23,
+ 33, 23, -1, -17, -35, -44, -43, -47, -51, -51, -56, -71, -67, -45, -28, -23,
+ -23, -13, 12, -1, -15, 15, 33, 20, -2, -22, -25, -17, -3, 10, 24, 46,
+ 44, 31, 26, 41, 53, 42, 23, 23, 26, 39, 37, 32, 24, 28, 36, 11,
+ -7, -19, -38, -39, -37, -49, -54, -51, -62, -76, -68, -51, -28, -19, -21, 1,
+ 22, -3, -11, 14, 25, 16, -5, -25, -25, -15, -2, 20, 36, 51, 42, 19,
+ 19, 43, 58, 43, 25, 21, 35, 46, 41, 34, 17, 26, 33, 5, -15, -25,
+ -39, -34, -37, -55, -50, -49, -69, -80, -67, -50, -31, -18, -12, 12, 17, -5,
+ -5, 14, 17, 6, -15, -27, -22, -14, 3, 37, 49, 48, 40, 22, 22, 36,
+ 51, 44, 29, 22, 42, 49, 41, 29, 16, 29, 31, -9, -30, -33, -35, -29,
+ -38, -55, -45, -54, -79, -80, -65, -51, -34, -16, -2, 18, 18, 5, 7, 8,
+ 6, 3, -19, -21, -22, -19, 12, 51, 53, 48, 39, 22, 18, 36, 46, 42,
+ 35, 31, 44, 46, 42, 31, 24, 35, 21, -25, -39, -33, -30, -24, -41, -53,
+ -47, -60, -81, -81, -63, -53, -40, -14, 6, 24, 20, 8, 7, 0, -1, -4,
+ -21, -23, -29, -16, 30, 60, 55, 50, 37, 19, 19, 35, 43, 46, 37, 29,
+ 43, 49, 43, 32, 27, 31, 13, -35, -46, -36, -26, -28, -44, -52, -47, -65,
+ -84, -84, -68, -49, -27, 0, 10, 15, 19, 15, 9, -3, -10, -16, -20, -26,
+ -28, -2, 41, 59, 62, 56, 37, 16, 15, 31, 43, 50, 42, 30, 41, 49,
+ 49, 38, 28, 23, 5, -42, -55, -42, -21, -22, -40, -49, -54, -71, -86, -81,
+ -62, -44, -21, 5, 17, 16, 25, 23, 0, -13, -17, -17, -24, -32, -21, 15,
+ 45, 58, 66, 52, 33, 15, 9, 35, 42, 44, 44, 36, 38, 50, 52, 40,
+ 28, 16, -11, -48, -60, -43, -22, -21, -40, -53, -58, -78, -90, -79, -61, -42,
+ -9, 14, 15, 16, 22, 21, -4, -20, -21, -19, -30, -31, -10, 26, 54, 63,
+ 69, 51, 33, 12, 13, 40, 42, 45, 42, 33, 36, 53, 57, 44, 24, 3,
+ -24, -53, -63, -45, -21, -15, -39, -57, -63, -78, -89, -76, -55, -34, 3, 18,
+ 9, 16, 21, 15, -8, -26, -28, -25, -32, -24, 4, 34, 56, 67, 75, 48,
+ 22, 7, 23, 44, 39, 40, 40, 35, 40, 59, 59, 44, 18, -6, -31, -54,
+ -58, -44, -20, -13, -43, -63, -69, -80, -88, -71, -48, -21, 12, 16, 12, 18,
+ 13, 6, -12, -27, -32, -30, -34, -20, 13, 46, 63, 74, 73, 40, 15, 13,
+ 39, 46, 33, 32, 35, 36, 48, 58, 61, 43, 16, -13, -36, -57, -62, -41,
+ -22, -16, -42, -66, -73, -79, -85, -65, -38, -7, 13, 9, 7, 16, 11, -2,
+ -18, -36, -39, -26, -25, -16, 21, 53, 64, 74, 68, 36, 19, 22, 38, 44,
+ 32, 28, 32, 38, 52, 60, 56, 43, 13, -25, -39, -54, -52, -35, -30, -27,
+ -46, -70, -79, -80, -79, -58, -26, 3, 15, 6, 0, 12, 6, -8, -27, -45,
+ -39, -17, -16, -13, 28, 57, 67, 71, 57, 37, 22, 25, 41, 46, 29, 24,
+ 34, 44, 56, 55, 52, 44, 7, -27, -38, -48, -44, -35, -31, -29, -46, -77,
+ -83, -73, -70, -48, -15, 6, 9, 1, 1, 9, -3, -20, -41, -48, -30, -5,
+ -14, -9, 39, 63, 70, 66, 47, 36, 25, 32, 40, 43, 26, 21, 36, 47,
+ 59, 50, 49, 35, 0, -26, -36, -44, -41, -36, -35, -33, -50, -79, -79, -66,
+ -63, -36, -8, 6, -3, -9, 2, 3, -13, -30, -49, -46, -18, -2, -15, 4,
+ 42, 58, 65, 61, 50, 38, 28, 37, 40, 38, 28, 30, 38, 48, 50, 42,
+ 46, 28, -3, -28, -37, -36, -36, -39, -36, -37, -59, -79, -69, -62, -52, -24,
+ -2, 3, -12, -11, 4, -5, -29, -42, -53, -39, -12, -4, -4, 14, 37, 52,
+ 63, 58, 50, 37, 34, 37, 36, 37, 38, 36, 35, 47, 46, 44, 42, 18,
+ -7, -30, -34, -32, -34, -41, -37, -45, -66, -74, -64, -57, -36, -12, 1, -8,
+ -23, -7, 6, -18, -39, -49, -53, -29, -5, -1, 10, 19, 30, 46, 59, 58,
+ 50, 36, 37, 37, 32, 40, 46, 38, 34, 44, 42, 41, 36, 9, -9, -27,
+ -29, -26, -34, -40, -40, -56, -69, -66, -56, -46, -22, -7, -7, -19, -21, 3,
+ 1, -35, -48, -53, -49, -22, -3, 12, 23, 18, 22, 46, 66, 59, 47, 38,
+ 43, 35, 30, 46, 51, 39, 33, 41, 37, 42, 24, 2, -8, -22, -23, -24,
+ -33, -39, -50, -66, -69, -59, -49, -31, -13, -10, -17, -25, -16, 1, -17, -50,
+ -55, -58, -42, -17, -1, 20, 31, 14, 15, 48, 70, 59, 42, 38, 45, 33,
+ 33, 51, 53, 36, 35, 37, 36, 37, 12, 0, -9, -16, -18, -22, -33, -42,
+ -59, -67, -62, -52, -40, -20, -11, -15, -23, -23, -11, -3, -28, -51, -59, -61,
+ -38, -14, 4, 26, 30, 10, 18, 53, 71, 56, 40, 42, 45, 32, 34, 53,
+ 52, 37, 36, 32, 37, 32, 10, -3, -10, -10, -11, -17, -31, -46, -62, -63,
+ -54, -44, -30, -14, -14, -23, -27, -22, -11, -11, -35, -51, -65, -59, -32, -11,
+ 11, 29, 25, 8, 24, 63, 73, 51, 38, 46, 44, 29, 34, 51, 51, 39,
+ 34, 27, 34, 23, 3, -5, -9, -6, -10, -18, -33, -51, -66, -60, -50, -35,
+ -20, -10, -21, -33, -29, -17, -9, -20, -39, -55, -71, -57, -26, -7, 11, 23,
+ 22, 11, 35, 70, 71, 46, 39, 48, 42, 29, 33, 51, 47, 38, 31, 28,
+ 35, 17, 0, -12, -7, 0, -4, -15, -36, -56, -67, -56, -42, -26, -15, -12,
+ -29, -36, -28, -15, -13, -25, -40, -58, -70, -49, -23, -6, 8, 19, 17, 18,
+ 49, 76, 66, 40, 42, 49, 39, 25, 35, 51, 43, 40, 30, 31, 32, 15,
+ -1, -14, -7, 1, -2, -17, -40, -59, -61, -51, -38, -21, -10, -17, -34, -35,
+ -28, -18, -17, -24, -40, -64, -65, -40, -18, -8, 5, 13, 17, 31, 61, 75,
+ 60, 41, 43, 47, 34, 20, 36, 47, 43, 41, 31, 32, 26, 7, -7, -16,
+ -6, 0, -3, -22, -44, -60, -56, -47, -34, -19, -8, -20, -39, -40, -27, -18,
+ -20, -29, -44, -63, -56, -38, -23, -11, 4, 14, 21, 42, 65, 71, 59, 45,
+ 42, 34, 21, 20, 42, 48, 44, 41, 31, 34, 24, 6, -10, -20, -11, 4,
+ 0, -20, -48, -57, -47, -39, -30, -17, -4, -24, -43, -40, -26, -19, -24, -29,
+ -45, -59, -51, -37, -25, -14, 3, 15, 27, 51, 72, 76, 61, 44, 38, 23,
+ 12, 21, 43, 46, 45, 40, 31, 35, 21, 5, -17, -22, -13, 3, 1, -24,
+ -51, -52, -43, -37, -28, -8, -7, -38, -46, -36, -21, -21, -31, -33, -45, -51,
+ -47, -40, -30, -13, 4, 14, 33, 60, 76, 76, 61, 47, 30, 16, 8, 20,
+ 40, 45, 48, 37, 37, 37, 22, 3, -19, -20, -10, 4, -6, -30, -49, -44,
+ -41, -38, -23, -1, -14, -41, -44, -36, -22, -26, -35, -33, -45, -52, -48, -40,
+ -32, -9, 6, 18, 35, 65, 85, 80, 62, 46, 24, 6, -1, 23, 41, 48,
+ 45, 31, 42, 40, 23, -6, -21, -15, -6, 0, -13, -31, -44, -41, -38, -32,
+ -15, 0, -22, -40, -41, -36, -24, -31, -28, -32, -46, -49, -47, -43, -30, -6,
+ 9, 19, 46, 77, 87, 77, 61, 42, 18, -2, -7, 22, 39, 51, 41, 32,
+ 43, 35, 13, -18, -18, -10, -5, -8, -21, -29, -39, -42, -41, -23, -3, -3,
+ -32, -39, -38, -34, -31, -35, -23, -32, -46, -50, -51, -46, -26, 0, 12, 20,
+ 54, 87, 91, 72, 60, 38, 13, -10, -11, 24, 44, 52, 43, 39, 45, 34,
+ 2, -19, -8, -1, -8, -19, -19, -25, -35, -42, -39, -17, 7, -7, -38, -36,
+ -36, -37, -37, -31, -20, -34, -49, -53, -50, -43, -19, 6, 10, 25, 66, 91,
+ 84, 67, 60, 36, 1, -18, -10, 27, 48, 52, 42, 42, 38, 25, -3, -18,
+ -5, -2, -13, -22, -24, -28, -35, -45, -35, -4, 14, -17, -41, -36, -33, -35,
+ -41, -29, -20, -38, -51, -54, -46, -33, -14, 6, 14, 37, 74, 87, 76, 65,
+ 64, 29, -9, -22, -7, 23, 52, 55, 46, 42, 25, 17, -5, -12, -4, -3,
+ -17, -25, -33, -36, -33, -39, -30, 5, 12, -25, -37, -33, -34, -42, -41, -25,
+ -22, -41, -52, -53, -40, -25, -10, 11, 21, 43, 72, 78, 74, 69, 58, 15,
+ -13, -15, -4, 22, 54, 58, 53, 41, 15, 6, -2, -1, -3, -6, -18, -24,
+ -42, -40, -29, -32, -20, 13, 8, -25, -35, -34, -29, -42, -43, -27, -27, -42,
+ -51, -50, -30, -14, -5, 17, 26, 46, 70, 72, 72, 69, 48, 2, -13, -9,
+ -3, 19, 55, 59, 53, 30, 1, -1, 5, 8, -7, -15, -19, -25, -48, -45,
+ -31, -28, -10, 15, 1, -24, -35, -35, -22, -37, -43, -36, -35, -41, -47, -45,
+ -18, -6, -1, 24, 32, 51, 65, 65, 67, 63, 37, -3, -13, -9, 1, 29,
+ 54, 60, 50, 18, -4, -4, 13, 9, -10, -15, -17, -30, -54, -47, -29, -20,
+ -8, 4, -8, -15, -29, -35, -21, -37, -43, -46, -37, -33, -48, -39, -10, 3,
+ 13, 31, 34, 54, 56, 57, 63, 56, 32, -3, -16, -6, 14, 38, 48, 53,
+ 40, 11, -3, 1, 6, -2, -11, -9, -11, -28, -54, -54, -29, -8, 2, -8,
+ -16, -13, -27, -31, -21, -32, -45, -54, -36, -27, -44, -33, 1, 16, 25, 29,
+ 39, 56, 48, 51, 57, 48, 22, 3, -14, 0, 22, 39, 42, 46, 36, 7,
+ -7, 0, 0, -3, -8, -8, -15, -34, -50, -49, -27, -3, 0, -15, -14, -16,
+ -28, -26, -21, -34, -56, -55, -32, -30, -41, -23, 8, 20, 31, 33, 45, 53,
+ 38, 42, 54, 40, 18, -3, -9, 14, 33, 37, 34, 34, 27, 8, -5, -1,
+ -9, -3, -1, -8, -19, -35, -43, -42, -28, -7, 1, -18, -13, -17, -29, -24,
+ -21, -34, -55, -52, -34, -30, -26, -9, 15, 28, 28, 32, 55, 50, 29, 38,
+ 45, 35, 17, -3, -1, 18, 36, 40, 27, 24, 19, 0, -5, -1, -14, -7,
+ -2, -12, -20, -30, -40, -42, -25, -5, -5, -24, -14, -16, -25, -20, -26, -38,
+ -52, -49, -35, -31, -13, 8, 16, 28, 29, 42, 57, 40, 23, 32, 35, 30,
+ 12, -5, 9, 22, 40, 38, 19, 17, 16, -1, -9, -7, -12, -6, -5, -13,
+ -18, -29, -39, -39, -18, -3, -19, -26, -11, -18, -24, -19, -30, -40, -51, -45,
+ -30, -24, 0, 19, 22, 28, 36, 49, 54, 41, 22, 30, 31, 26, 10, 2,
+ 10, 26, 43, 28, 14, 16, 7, -6, -12, -9, -9, -5, -12, -19, -16, -29,
+ -35, -34, -8, -8, -35, -20, -7, -26, -23, -23, -30, -39, -53, -38, -25, -12,
+ 11, 24, 24, 29, 47, 50, 48, 36, 20, 29, 24, 15, 5, 8, 12, 32,
+ 40, 21, 17, 11, 0, -3, -15, -14, -7, -4, -13, -17, -16, -28, -31, -23,
+ -6, -20, -37, -15, -12, -29, -22, -28, -30, -38, -54, -34, -20, -4, 21, 33,
+ 24, 33, 50, 45, 40, 33, 27, 28, 14, 8, 8, 11, 11, 30, 33, 26,
+ 20, -1, -8, -4, -17, -16, -2, -7, -22, -20, -20, -26, -26, -15, -10, -27,
+ -35, -12, -19, -31, -21, -23, -23, -42, -57, -31, -11, 9, 35, 33, 23, 39,
+ 53, 47, 40, 31, 31, 21, 10, 9, 11, 10, 13, 26, 35, 33, 13, -11,
+ -10, -4, -19, -22, 3, -2, -28, -26, -16, -21, -24, -12, -12, -31, -34, -17,
+ -27, -34, -25, -17, -19, -48, -59, -29, -2, 27, 46, 26, 22, 43, 54, 44,
+ 38, 30, 29, 16, 6, 15, 15, 6, 9, 22, 36, 37, 9, -20, -10, -5,
+ -21, -21, 2, -5, -29, -31, -18, -11, -17, -11, -15, -32, -34, -23, -30, -30,
+ -25, -15, -22, -52, -50, -17, 9, 36, 42, 26, 29, 50, 53, 40, 33, 32,
+ 27, 14, 7, 9, 7, 4, 12, 22, 36, 36, 3, -27, -16, -9, -20, -21,
+ -1, -12, -31, -27, -13, -12, -18, -12, -17, -33, -39, -29, -34, -35, -23, -7,
+ -25, -55, -42, -10, 20, 43, 40, 27, 33, 51, 51, 37, 34, 31, 21, 9,
+ 8, 5, 2, 11, 16, 18, 34, 35, 3, -22, -17, -16, -20, -17, -7, -20,
+ -32, -28, -14, -12, -10, -8, -17, -34, -41, -35, -34, -31, -19, -8, -27, -48,
+ -29, -4, 26, 50, 44, 32, 37, 50, 49, 40, 36, 22, 11, 11, 12, 5,
+ 3, 14, 12, 13, 34, 37, 9, -23, -24, -16, -21, -16, -17, -30, -27, -27,
+ -20, -10, -10, -9, -18, -39, -46, -42, -35, -31, -14, -9, -33, -42, -19, 1,
+ 36, 55, 41, 32, 46, 55, 47, 35, 32, 18, 6, 7, 9, -2, 7, 17,
+ 8, 13, 34, 32, 10, -22, -27, -14, -20, -21, -26, -31, -23, -27, -22, -6,
+ -5, -11, -21, -39, -46, -46, -37, -30, -14, -12, -33, -31, -8, 6, 41, 55,
+ 40, 38, 54, 57, 39, 30, 33, 17, 2, 1, 4, 7, 14, 14, -2, 11,
+ 37, 31, 11, -26, -30, -16, -20, -18, -21, -27, -32, -28, -12, 0, -4, -11,
+ -23, -40, -46, -43, -33, -26, -16, -15, -29, -19, -1, 13, 44, 58, 41, 49,
+ 68, 59, 36, 28, 36, 18, -9, -9, 4, 17, 20, 7, -6, 18, 36, 22,
+ -1, -30, -26, -19, -25, -26, -31, -35, -33, -21, -3, -8, -10, -14, -24, -40,
+ -45, -43, -35, -20, -18, -20, -22, -12, 0, 15, 48, 58, 41, 58, 77, 57,
+ 30, 27, 33, 7, -23, -16, 11, 23, 21, 2, -5, 24, 33, 10, -10, -24,
+ -19, -25, -37, -30, -30, -34, -29, -14, -5, -16, -8, -8, -26, -50, -47, -41,
+ -30, -16, -25, -24, -14, -6, 3, 23, 50, 51, 49, 69, 81, 56, 29, 33,
+ 30, -2, -29, -14, 15, 26, 18, 2, -1, 31, 28, 0, -20, -21, -21, -32,
+ -43, -34, -33, -36, -23, -4, -8, -20, -8, -11, -25, -44, -41, -39, -32, -17,
+ -30, -22, -4, 1, 6, 31, 48, 47, 63, 80, 82, 52, 31, 38, 23, -13,
+ -33, -11, 20, 29, 14, -1, 9, 34, 19, -12, -26, -13, -23, -46, -46, -38,
+ -39, -35, -24, -3, -7, -17, -15, -16, -25, -45, -37, -37, -33, -26, -36, -20,
+ 5, 3, 4, 32, 42, 50, 76, 83, 75, 49, 34, 36, 17, -24, -33, -12,
+ 23, 32, 10, 1, 23, 30, 7, -17, -22, -8, -27, -49, -50, -42, -38, -28,
+ -18, -3, -8, -13, -14, -15, -24, -43, -35, -33, -29, -27, -34, -15, 16, 8,
+ 5, 32, 43, 62, 84, 84, 73, 53, 40, 30, 6, -26, -34, -15, 25, 28,
+ 8, 9, 38, 27, -4, -26, -21, -12, -33, -54, -47, -48, -38, -21, -14, -2,
+ -3, -11, -25, -18, -26, -32, -34, -34, -29, -31, -35, -10, 18, 11, 7, 33,
+ 47, 68, 83, 81, 71, 58, 42, 20, -5, -25, -36, -15, 23, 23, 7, 20,
+ 40, 21, -14, -35, -21, -16, -40, -58, -52, -52, -31, -11, -9, -6, -1, -15,
+ -26, -15, -29, -31, -36, -31, -29, -36, -32, -4, 17, 8, 15, 36, 48, 66,
+ 77, 83, 77, 59, 38, 9, -11, -20, -34, -12, 22, 20, 14, 33, 39, 16,
+ -22, -36, -23, -21, -40, -56, -52, -47, -24, -10, -4, 3, 1, -17, -22, -18,
+ -28, -26, -32, -30, -32, -30, -22, 1, 15, 15, 27, 42, 52, 62, 75, 85,
+ 80, 59, 35, 1, -16, -20, -35, -12, 18, 17, 18, 40, 34, 5, -34, -38,
+ -27, -28, -42, -60, -58, -48, -18, -4, 0, 3, -4, -18, -20, -22, -35, -29,
+ -27, -34, -42, -28, -12, 3, 8, 19, 31, 40, 45, 60, 75, 79, 76, 62,
+ 37, -2, -20, -22, -31, -11, 13, 15, 31, 43, 27, 0, -28, -33, -36, -37,
+ -43, -58, -61, -47, -13, 1, 1, 3, -5, -12, -17, -25, -36, -27, -25, -39,
+ -45, -24, 1, 0, 8, 25, 43, 45, 42, 57, 76, 76, 73, 60, 37, -8,
+ -25, -22, -25, -6, 9, 21, 41, 41, 15, -6, -18, -33, -48, -40, -38, -57,
+ -64, -46, -6, 9, -4, 1, -1, -9, -18, -28, -33, -24, -27, -42, -45, -18,
+ 2, 3, 13, 31, 49, 43, 37, 60, 74, 68, 68, 60, 30, -12, -28, -23,
+ -19, -8, 5, 26, 48, 37, 11, -12, -17, -37, -54, -40, -41, -58, -65, -42,
+ 5, 12, -8, 0, 2, -6, -22, -29, -30, -28, -37, -44, -42, -9, 6, 7,
+ 17, 33, 44, 42, 40, 61, 72, 57, 63, 61, 24, -16, -34, -21, -15, -12,
+ 3, 31, 47, 28, 7, -10, -15, -43, -51, -38, -45, -61, -61, -31, 10, 8,
+ -3, 6, 5, -8, -24, -27, -28, -31, -44, -42, -29, -3, 6, 10, 24, 40,
+ 44, 45, 46, 57, 62, 56, 65, 56, 16, -13, -32, -18, -12, -10, 11, 32,
+ 39, 25, 6, -10, -19, -48, -44, -38, -49, -63, -61, -19, 12, 3, 4, 6,
+ 3, -9, -25, -26, -27, -38, -46, -39, -18, 1, 12, 20, 29, 33, 36, 49,
+ 47, 54, 59, 49, 63, 51, 8, -12, -25, -18, -18, -6, 20, 33, 28, 19,
+ 4, -9, -27, -43, -41, -45, -55, -64, -51, -13, 7, -3, 0, 7, 3, -12,
+ -28, -27, -33, -46, -51, -33, -10, -5, 15, 31, 34, 26, 32, 47, 51, 53,
+ 47, 50, 61, 41, 1, -8, -12, -21, -20, 5, 27, 29, 16, 13, 8, -9,
+ -28, -40, -40, -44, -55, -62, -40, -8, 5, -2, 4, 11, 4, -15, -26, -26,
+ -37, -49, -47, -27, -8, -3, 22, 45, 38, 22, 34, 47, 55, 52, 39, 44,
+ 58, 32, 2, 0, -7, -25, -21, 10, 29, 30, 9, 0, 0, -7, -26, -38,
+ -40, -53, -61, -53, -30, -5, 1, -2, 5, 10, 3, -18, -25, -33, -43, -51,
+ -46, -20, -10, -8, 26, 52, 35, 19, 32, 47, 56, 46, 33, 44, 48, 20,
+ 10, 11, -7, -29, -20, 15, 35, 28, 2, -9, -8, -6, -26, -32, -36, -54,
+ -64, -52, -22, 1, 3, 2, 3, 15, 2, -22, -24, -34, -41, -45, -39, -19,
+ -9, 1, 35, 57, 37, 18, 27, 46, 52, 41, 37, 44, 40, 18, 16, 13,
+ -7, -29, -14, 23, 36, 17, -6, -17, -2, 1, -24, -38, -43, -59, -62, -44,
+ -22, -4, 7, 2, 5, 16, -2, -24, -27, -36, -43, -48, -37, -20, -5, 14,
+ 40, 52, 36, 20, 26, 43, 46, 40, 41, 42, 28, 19, 19, 9, -4, -21,
+ -10, 27, 32, 10, -6, -16, -4, -5, -14, -37, -48, -59, -58, -36, -24, -1,
+ 13, -3, 7, 16, -5, -19, -32, -38, -46, -43, -32, -22, -7, 22, 49, 57,
+ 37, 22, 20, 37, 41, 36, 46, 41, 21, 19, 16, 9, -2, -25, -9, 27,
+ 24, 8, -12, -11, -2, -9, -10, -39, -51, -59, -59, -35, -21, 2, 15, -5,
+ 10, 11, -12, -19, -35, -39, -46, -35, -29, -26, -5, 37, 60, 53, 36, 26,
+ 19, 33, 37, 33, 48, 41, 18, 17, 19, 11, -8, -23, -3, 30, 21, -5,
+ -14, -2, -6, -9, -9, -42, -59, -64, -54, -33, -16, 6, 14, 0, 15, 4,
+ -14, -17, -35, -45, -46, -33, -27, -22, 2, 42, 56, 49, 37, 26, 19, 26,
+ 23, 36, 58, 44, 11, 8, 23, 10, -7, -15, 3, 26, 12, -10, -8, 3,
+ -10, -7, -13, -46, -58, -60, -57, -40, -11, 9, 9, 3, 13, -6, -12, -17,
+ -42, -53, -45, -28, -23, -14, 11, 49, 60, 49, 40, 27, 14, 16, 13, 43,
+ 62, 46, 6, 8, 22, 7, -9, -10, 11, 23, 4, -17, 2, 6, -6, -7,
+ -21, -51, -58, -58, -55, -38, -12, 12, 10, 13, 1, -15, -7, -14, -47, -62,
+ -45, -29, -19, -2, 21, 51, 63, 46, 37, 31, 16, 0, 4, 43, 64, 43,
+ 6, 9, 24, 4, -15, -2, 14, 9, -9, -15, 14, 7, -11, -10, -29, -53,
+ -54, -57, -48, -35, -9, 13, 9, 11, -5, -6, -2, -22, -57, -60, -39, -24,
+ -11, 5, 30, 52, 62, 49, 42, 38, 11, -9, 7, 45, 61, 44, 10, 15,
+ 21, -4, -15, 3, 13, 1, -13, -9, 13, 7, -9, -13, -32, -51, -53, -56,
+ -44, -35, -9, 15, 11, 7, -8, 0, -2, -34, -65, -56, -31, -24, -7, 20,
+ 37, 49, 56, 47, 47, 39, -3, -16, 12, 40, 53, 45, 16, 23, 17, -7,
+ -8, 7, 8, -5, -12, -7, 7, 7, -4, -17, -38, -56, -60, -50, -37, -33,
+ -8, 7, 9, 0, -6, 7, -8, -47, -71, -50, -25, -23, 0, 33, 41, 46,
+ 52, 53, 54, 35, -6, -9, 13, 32, 50, 48, 23, 25, 13, -4, -3, 0,
+ -1, -7, -7, -8, 3, 6, -3, -22, -41, -55, -62, -46, -30, -24, -5, 0,
+ 5, 2, 3, 10, -20, -57, -69, -41, -19, -16, 5, 37, 47, 46, 49, 54,
+ 58, 29, -4, -6, 7, 21, 49, 49, 24, 24, 12, -2, -5, -9, 0, 0,
+ -10, -15, 2, 8, -4, -23, -42, -57, -66, -43, -22, -16, -11, -8, 3, 5,
+ 7, 4, -28, -61, -61, -36, -19, -11, 10, 45, 51, 43, 46, 52, 54, 26,
+ 3, -8, -3, 15, 52, 48, 27, 30, 15, -1, -9, -14, 0, -2, -15, -17,
+ -2, -1, -5, -23, -37, -62, -64, -34, -17, -15, -19, -8, 4, 7, 8, -8,
+ -37, -55, -50, -33, -19, -5, 16, 49, 54, 44, 45, 52, 53, 32, 3, -12,
+ -5, 14, 46, 46, 38, 34, 21, 6, -13, -21, -2, -3, -18, -19, -14, -9,
+ -2, -14, -44, -74, -56, -26, -15, -16, -18, -6, -1, 7, 6, -20, -43, -48,
+ -35, -32, -24, 1, 23, 51, 54, 41, 42, 52, 49, 32, 3, -14, -5, 19,
+ 42, 47, 43, 38, 27, 10, -18, -19, -5, -7, -18, -27, -23, -9, 2, -8,
+ -51, -75, -41, -19, -15, -13, -15, -11, -5, 10, 1, -30, -37, -40, -30, -33,
+ -24, 6, 30, 49, 49, 45, 43, 52, 39, 24, 7, -10, -7, 12, 33, 44,
+ 48, 43, 36, 7, -29, -18, -6, -14, -23, -36, -32, -12, 2, -16, -60, -65,
+ -27, -22, -22, -9, -6, -14, -6, 11, -10, -38, -35, -27, -26, -35, -15, 18,
+ 39, 47, 48, 51, 55, 51, 28, 22, 13, -5, -6, 5, 27, 46, 57, 49,
+ 39, 1, -29, -12, -7, -15, -28, -48, -39, -11, -1, -28, -61, -51, -22, -30,
+ -22, -3, -4, -21, -6, 8, -23, -45, -29, -18, -27, -32, -11, 24, 44, 40,
+ 46, 56, 61, 44, 17, 18, 19, 1, -11, -2, 24, 48, 57, 54, 45, 2,
+ -27, -12, -11, -18, -32, -49, -41, -16, -10, -32, -47, -33, -25, -34, -13, 6,
+ -5, -24, -13, -4, -29, -43, -29, -18, -25, -21, -1, 25, 44, 40, 49, 67,
+ 60, 31, 12, 18, 24, -2, -18, -5, 22, 45, 62, 65, 46, -5, -21, -12,
+ -12, -17, -36, -57, -48, -23, -15, -29, -35, -28, -33, -31, -3, 12, -16, -32,
+ -12, -19, -36, -33, -25, -22, -29, -10, 14, 30, 41, 35, 51, 73, 57, 27,
+ 16, 21, 14, -4, -12, -2, 21, 41, 62, 71, 43, -7, -12, -19, -22, -23,
+ -46, -57, -51, -35, -20, -17, -22, -26, -37, -27, 7, 12, -24, -31, -14, -29,
+ -34, -30, -22, -20, -21, 2, 15, 26, 40, 45, 55, 66, 52, 28, 20, 17,
+ 10, -1, -12, -4, 21, 43, 65, 74, 39, 1, -9, -25, -27, -24, -45, -61,
+ -55, -43, -22, -9, -12, -24, -32, -26, 9, 7, -25, -31, -30, -40, -31, -26,
+ -19, -20, -11, 14, 18, 27, 45, 54, 52, 61, 49, 33, 24, 15, 5, 0,
+ -14, -2, 24, 44, 62, 67, 37, 12, -9, -30, -29, -33, -49, -66, -58, -51,
+ -25, -2, -6, -19, -31, -24, 6, 3, -21, -37, -43, -42, -31, -25, -17, -19,
+ -5, 15, 19, 30, 52, 56, 45, 54, 52, 38, 22, 11, 8, 0, -16, 2,
+ 27, 44, 63, 60, 34, 16, -10, -25, -31, -38, -55, -68, -62, -53, -18, 5,
+ -2, -17, -31, -16, 5, -4, -22, -43, -50, -38, -32, -21, -16, -11, 8, 10,
+ 19, 32, 60, 60, 43, 46, 51, 37, 24, 13, 8, -6, -17, 4, 32, 52,
+ 56, 52, 39, 23, -5, -23, -41, -48, -64, -65, -63, -57, -14, 9, 3, -18,
+ -28, -9, 0, -11, -25, -47, -53, -38, -30, -19, -11, 0, 10, 11, 23, 42,
+ 66, 60, 42, 49, 53, 36, 24, 20, 9, -17, -18, 3, 39, 59, 49, 41,
+ 39, 26, 1, -24, -53, -59, -70, -61, -66, -58, -12, 17, 7, -20, -26, -7,
+ -7, -16, -30, -51, -60, -45, -26, -11, -5, 5, 8, 10, 23, 48, 66, 55,
+ 40, 48, 48, 33, 30, 25, 2, -21, -15, 10, 41, 51, 44, 37, 41, 27,
+ 6, -28, -60, -65, -70, -63, -70, -55, -6, 21, 1, -20, -15, -2, -15, -24,
+ -32, -54, -66, -45, -22, -8, 6, 13, 5, 15, 31, 51, 64, 58, 41, 42,
+ 44, 35, 36, 29, 0, -20, -9, 14, 43, 53, 46, 39, 39, 24, 7, -33,
+ -69, -75, -73, -70, -75, -46, 4, 17, -2, -18, -6, 3, -18, -32, -38, -61,
+ -65, -39, -17, -2, 10, 10, 5, 19, 33, 55, 61, 54, 39, 40, 41, 41,
+ 40, 30, -6, -25, -6, 22, 44, 48, 42, 42, 37, 23, 11, -42, -73, -77,
+ -75, -74, -75, -39, 4, 8, -5, -15, 1, -1, -30, -33, -38, -69, -66, -40,
+ -14, 3, 16, 8, 5, 21, 39, 60, 59, 48, 40, 38, 39, 42, 42, 30,
+ -8, -20, 0, 26, 48, 51, 48, 43, 29, 21, 1, -47, -70, -80, -83, -80,
+ -70, -25, 0, -2, -9, -6, 9, -7, -29, -33, -49, -72, -59, -29, -3, 3,
+ 11, 6, 14, 27, 47, 61, 54, 47, 43, 34, 42, 45, 39, 21, -10, -17,
+ 4, 29, 53, 54, 47, 39, 29, 22, -11, -53, -70, -83, -86, -77, -61, -19,
+ -6, -7, -12, -2, 9, -14, -29, -35, -61, -70, -54, -25, -8, 2, 11, 8,
+ 17, 27, 54, 60, 50, 45, 42, 40, 43, 39, 35, 18, -9, -7, 8, 28,
+ 55, 56, 49, 32, 30, 15, -21, -53, -71, -88, -87, -74, -45, -12, -11, -15,
+ -14, 6, 12, -12, -30, -48, -66, -60, -44, -18, -8, 5, 13, 15, 21, 31,
+ 51, 57, 48, 43, 42, 40, 43, 37, 29, 16, -3, -1, 7, 35, 60, 54,
+ 38, 26, 29, 5, -30, -54, -72, -93, -87, -69, -34, -14, -19, -25, -12, 13,
+ 6, -17, -37, -56, -66, -49, -38, -18, -11, 1, 17, 24, 26, 32, 47, 52,
+ 50, 49, 45, 39, 40, 33, 32, 13, 4, 3, 3, 47, 65, 52, 29, 27,
+ 20, -5, -35, -56, -76, -90, -79, -63, -27, -17, -26, -24, 0, 12, -2, -16,
+ -33, -61, -61, -42, -33, -17, -16, -6, 22, 30, 25, 29, 45, 50, 46, 53,
+ 41, 37, 37, 33, 28, 17, 15, 2, 15, 54, 64, 46, 21, 25, 9, -12,
+ -39, -58, -77, -87, -75, -46, -21, -23, -34, -24, 9, 9, -7, -17, -40, -67,
+ -53, -33, -27, -22, -26, -4, 34, 34, 25, 27, 46, 44, 52, 59, 37, 30,
+ 35, 32, 26, 25, 16, 2, 30, 62, 57, 33, 19, 17, -7, -25, -43, -58,
+ -80, -82, -64, -36, -26, -26, -33, -17, 11, 4, -9, -18, -45, -62, -44, -30,
+ -24, -28, -29, 5, 38, 32, 25, 30, 48, 41, 53, 57, 35, 28, 26, 27,
+ 31, 29, 14, 12, 47, 63, 48, 35, 24, 4, -19, -32, -46, -55, -76, -77,
+ -58, -31, -30, -33, -36, -8, 12, -4, -9, -22, -51, -57, -30, -23, -27, -40,
+ -31, 18, 36, 31, 30, 33, 39, 36, 56, 51, 32, 27, 20, 24, 39, 30,
+ 16, 29, 55, 53, 43, 36, 21, -5, -28, -39, -45, -55, -71, -70, -47, -27,
+ -35, -36, -25, -2, 1, -4, -6, -23, -48, -48, -25, -16, -25, -46, -23, 24,
+ 30, 35, 34, 29, 33, 37, 51, 41, 30, 21, 12, 27, 47, 33, 19, 38,
+ 51, 43, 39, 36, 15, -17, -35, -35, -42, -55, -68, -62, -45, -33, -40, -36,
+ -19, -5, -4, -3, -6, -24, -47, -38, -17, -13, -37, -48, -13, 26, 30, 36,
+ 32, 27, 29, 36, 48, 38, 27, 9, 5, 34, 47, 31, 30, 49, 47, 36,
+ 38, 28, 11, -21, -32, -32, -47, -56, -60, -54, -40, -39, -42, -31, -12, -5,
+ -7, -1, -4, -21, -39, -28, -11, -13, -45, -42, -2, 23, 25, 42, 33, 26,
+ 26, 33, 44, 34, 20, 1, 5, 36, 47, 38, 40, 47, 37, 35, 38, 20,
+ 1, -23, -26, -35, -49, -56, -55, -48, -40, -46, -42, -28, -12, -12, -10, 2,
+ -6, -25, -32, -25, -13, -22, -43, -30, 5, 18, 24, 45, 35, 29, 21, 27,
+ 39, 28, 16, 2, 9, 39, 40, 44, 55, 45, 25, 31, 34, 15, -1, -18,
+ -25, -41, -49, -50, -52, -46, -42, -48, -40, -23, -9, -18, -13, 9, -1, -24,
+ -27, -22, -14, -30, -41, -26, 8, 15, 25, 40, 36, 26, 15, 26, 35, 21,
+ 11, 2, 17, 44, 37, 54, 63, 37, 16, 31, 27, 12, -3, -12, -24, -45,
+ -47, -46, -45, -40, -44, -55, -40, -17, -12, -22, -7, 19, -2, -22, -24, -15,
+ -17, -36, -36, -11, 16, 10, 17, 38, 43, 25, 15, 25, 26, 14, 7, 2,
+ 25, 39, 38, 63, 67, 30, 16, 25, 18, 14, -5, -9, -26, -43, -45, -47,
+ -42, -38, -52, -57, -35, -14, -22, -27, 0, 23, -5, -24, -22, -12, -21, -40,
+ -31, 1, 19, 6, 11, 35, 44, 22, 18, 28, 14, 4, 4, 11, 32, 34,
+ 38, 70, 68, 22, 18, 17, 15, 17, 0, -10, -31, -45, -43, -42, -34, -36,
+ -62, -61, -25, -11, -28, -29, 3, 25, -3, -26, -15, -12, -28, -34, -21, 9,
+ 17, 2, 10, 31, 40, 24, 23, 28, 5, -3, 6, 19, 35, 33, 42, 72,
+ 59, 22, 22, 12, 17, 17, 2, -11, -31, -40, -40, -36, -28, -40, -66, -57,
+ -18, -15, -32, -22, 9, 22, -3, -23, -8, -12, -31, -32, -12, 18, 15, -1,
+ 9, 25, 36, 26, 27, 20, -7, -5, 12, 23, 29, 33, 45, 70, 48, 25,
+ 20, 8, 16, 9, 4, -11, -33, -39, -37, -34, -30, -46, -65, -50, -23, -22,
+ -30, -19, 13, 22, -4, -21, -6, -15, -32, -28, -3, 18, 9, 0, 9, 21,
+ 30, 28, 30, 12, -14, -1, 17, 19, 27, 41, 51, 63, 35, 28, 22, 12,
+ 10, 6, 9, -14, -31, -36, -31, -27, -38, -49, -62, -48, -29, -25, -27, -13,
+ 13, 13, -3, -9, -9, -21, -30, -20, 4, 12, 4, 5, 12, 19, 27, 33,
+ 29, 6, -12, 2, 21, 17, 31, 45, 54, 55, 31, 31, 25, 14, 3, 5,
+ 11, -14, -27, -33, -24, -27, -41, -49, -63, -53, -37, -26, -22, -7, 11, 8,
+ 0, -3, -14, -19, -27, -14, 8, 5, 2, 9, 12, 20, 25, 31, 18, 0,
+ -6, 8, 20, 14, 27, 43, 59, 48, 24, 28, 25, 14, 2, 8, 6, -15,
+ -26, -30, -16, -28, -44, -53, -61, -58, -37, -27, -21, -4, 8, 3, 1, -2,
+ -18, -21, -24, -11, 3, -4, 3, 15, 17, 20, 22, 29, 15, 3, -2, 8,
+ 17, 18, 30, 46, 56, 40, 21, 29, 26, 14, -1, 5, 4, -6, -22, -29,
+ -13, -27, -46, -51, -62, -61, -37, -28, -14, 2, 7, 0, 5, -2, -16, -17,
+ -19, -10, -7, -9, 11, 20, 22, 18, 17, 25, 19, 4, -1, 10, 19, 25,
+ 32, 44, 53, 36, 19, 29, 24, 10, -4, 5, 4, -2, -22, -24, -13, -31,
+ -48, -56, -63, -60, -40, -31, -11, 8, 8, 2, 8, -6, -20, -17, -12, -10,
+ -20, -12, 14, 30, 26, 10, 14, 24, 24, -1, -7, 12, 25, 27, 30, 40,
+ 52, 34, 17, 28, 24, 7, -9, 1, 8, 3, -20, -20, -16, -33, -53, -59,
+ -62, -61, -47, -29, -5, 15, 5, 1, 9, -8, -20, -14, -5, -12, -30, -11,
+ 20, 37, 25, 10, 19, 25, 19, -5, -2, 18, 28, 26, 29, 41, 49, 31,
+ 20, 30, 24, 1, -8, 4, 10, 3, -17, -12, -18, -40, -57, -61, -62, -59,
+ -48, -23, 0, 18, 5, 5, 12, -9, -19, -9, -2, -20, -37, -7, 25, 39,
+ 23, 11, 25, 26, 10, -10, 5, 23, 24, 26, 30, 40, 42, 27, 23, 31,
+ 18, -7, -5, 2, 7, -1, -10, -10, -22, -45, -59, -63, -62, -58, -45, -21,
+ -1, 17, 10, 13, 7, -18, -21, -5, -3, -27, -38, -7, 26, 38, 21, 20,
+ 31, 23, 0, -9, 15, 25, 21, 28, 33, 35, 35, 29, 28, 31, 12, -5,
+ 0, 0, 4, 0, -3, -14, -27, -48, -57, -69, -66, -61, -40, -19, 1, 16,
+ 13, 16, -3, -18, -17, -4, -9, -30, -33, -1, 24, 35, 28, 34, 31, 16,
+ -4, -2, 22, 29, 20, 27, 38, 33, 30, 30, 31, 33, 9, 1, -3, -7,
+ 2, 6, -1, -22, -31, -50, -61, -74, -67, -52, -34, -25, 1, 19, 21, 14,
+ -8, -18, -14, -10, -14, -27, -26, -5, 21, 35, 38, 40, 31, 12, -1, 5,
+ 22, 29, 19, 31, 41, 28, 30, 28, 31, 28, 12, 7, -13, -11, -2, 13,
+ -5, -26, -32, -52, -67, -80, -65, -46, -34, -26, 2, 15, 25, 9, -8, -14,
+ -16, -10, -18, -25, -25, -9, 20, 37, 46, 35, 26, 10, 7, 8, 18, 27,
+ 18, 31, 39, 25, 29, 29, 34, 26, 20, 2, -18, -10, -5, 12, -9, -22,
+ -31, -48, -74, -79, -66, -42, -34, -22, -1, 14, 25, 13, -6, -19, -16, -8,
+ -19, -22, -21, -5, 21, 41, 51, 32, 25, 14, 19, 13, 14, 21, 21, 32,
+ 34, 26, 26, 30, 32, 25, 25, -3, -19, -13, -2, 8, -12, -24, -32, -46,
+ -75, -79, -67, -43, -33, -18, -7, 12, 25, 18, 0, -23, -13, -7, -23, -18,
+ -15, -4, 21, 48, 51, 27, 27, 23, 22, 12, 12, 19, 22, 28, 28, 28,
+ 28, 31, 28, 23, 28, -3, -20, -22, -5, 0, -14, -23, -28, -50, -78, -81,
+ -63, -44, -34, -19, -14, 10, 25, 18, -6, -19, -5, -11, -30, -17, -8, 2,
+ 21, 54, 45, 25, 28, 33, 25, 9, 12, 21, 26, 23, 24, 33, 37, 35,
+ 20, 23, 32, -1, -21, -25, -12, -11, -12, -19, -27, -53, -78, -79, -55, -42,
+ -31, -26, -18, 12, 24, 13, -9, -12, 0, -20, -33, -13, 1, 6, 26, 55,
+ 38, 25, 33, 45, 26, 7, 13, 21, 26, 16, 18, 38, 44, 33, 14, 25,
+ 30, 4, -24, -32, -21, -18, -19, -19, -25, -54, -79, -78, -53, -43, -29, -28,
+ -20, 6, 20, 12, -3, 0, -3, -35, -28, 1, 9, 8, 25, 46, 34, 30,
+ 37, 44, 19, 13, 20, 17, 20, 12, 18, 49, 49, 23, 13, 28, 33, 3,
+ -34, -37, -28, -30, -21, -10, -26, -57, -77, -74, -52, -40, -25, -32, -22, 3,
+ 17, 12, 3, 8, -15, -40, -18, 10, 10, 4, 32, 39, 27, 38, 48, 39,
+ 11, 18, 28, 17, 15, 5, 23, 61, 46, 21, 23, 35, 26, -3, -31, -37,
+ -39, -38, -23, -3, -29, -60, -74, -68, -58, -37, -27, -35, -22, -7, 15, 23,
+ 14, 8, -27, -41, -6, 19, 14, 9, 35, 31, 31, 48, 54, 35, 11, 27,
+ 26, 4, 7, 11, 31, 54, 38, 25, 34, 35, 20, -10, 19, 3, -8, -45,
+ 64, -15, -41, 23, 40, -58, 22, 29, -27, -28, 42, -36, 21, -12, -19, 39,
+ -14, 3, -18, 32, -27, 18, -8, -43, 43, 25, -52, 6, 19, 13, -7, -50,
+ 55, 5, -46, -22, 94, -53, -33, 35, 27, -45, -2, 20, 19, -30, -23, 47,
+ 8, -58, 5, 76, -67, -22, 42, 30, -54, 8, 23, 11, -51, 3, 47, -33,
+ -7, 5, 27, -33, 34, -35, 17, 4, -26, 5, 17, -30, 33, 5, -29, -5,
+ 44, -18, -50, 60, -33, 10, -5, 10, -7, 1, -5, 19, -36, 3, 37, -17,
+ -51, 52, 37, -64, 9, 4, 37, -44, -13, 25, 45, -75, -9, 79, -34, -57,
+ 53, 24, -59, 18, 22, -3, -24, 10, -2, 18, -53, 29, 35, -20, -43, 37,
+ 18, -17, -31, 8, 45, -49, 8, 11, 9, -23, 30, -24, -22, 29, 14, -43,
+ 27, 13, -22, -1, 2, 22, -37, 5, -5, 38, -43, 6, 36, -21, -20, 20,
+ 0, -5, -27, 27, 21, -53, 4, 52, -2, -84, 70, 5, -29, -19, 36, -6,
+ -8, -12, 3, 35, -32, -25, 48, 6, -60, 49, 4, -27, -13, 31, -15, -9,
+ -4, 31, -13, -25, 29, 12, -34, -6, 30, -41, 36, -23, 6, 31, -30, 0,
+ 17, -45, 47, -5, -47, 19, 28, -8, -30, 27, -6, 15, -54, 34, 21, -27,
+ -9, 25, 3, -45, 26, 27, -52, 22, 20, -29, 34, -46, 22, 40, -69, -27,
+ 108, -49, -54, 69, -11, -3, -18, 3, 15, -12, -23, 29, -8, 4, -23, 50,
+ -38, -8, 33, -32, -2, 26, -27, 12, 13, -39, 56, -31, -22, 28, 2, -39,
+ 54, -20, -36, 51, -6, -34, 15, 2, 1, 2, -36, 42, 2, -10, -39, 64,
+ -36, -16, 24, 1, -1, -18, -10, 54, -27, -54, 80, -18, -61, 51, 27, -76,
+ 64, -30, -1, 9, -19, 24, 13, -29, -13, 49, -18, -46, 43, 6, -47, 42,
+ -28, 14, 18, -18, 2, 14, -39, 25, 16, -58, 33, 29, -49, 16, 41, -62,
+ 43, -17, -17, 25, -10, -28, 41, -5, -30, 27, 14, -53, 27, 35, -63, 16,
+ 30, 0, -30, -10, 22, 31, -57, 0, 68, -59, 2, 37, -30, 6, -3, -19,
+ 35, -29, 1, 20, 22, -68, 33, 39, -71, 21, 27, -22, -1, 3, 0, 18,
+ -16, -13, 17, 4, -37, 44, -15, -26, 48, -29, -11, 34, -25, -4, 25, -48,
+ 43, 4, -49, 28, 42, -72, 7, 59, -36, -28, 45, -9, -28, 25, -19, 23,
+ -9, -40, 47, 18, -85, 78, -2, -53, 39, -17, 2, 14, -36, 10, 63, -78,
+ 17, 59, -66, -8, 54, -49, 14, 1, 5, 2, -18, 16, -12, 30, -58, 22,
+ 53, -83, 17, 79, -84, 19, 17, -34, 44, -33, -27, 82, -62, -19, 91, -93,
+ 22, 49, -51, -25, 48, -12, -6, 1, -2, -1, 22, -32, -1, 59, -78, 12,
+ 58, -49, -26, 70, -40, -8, 16, -8, 12, 10, -65, 74, -1, -97, 90, 0,
+ -56, 23, 25, -17, 11, -23, 14, 9, -24, -31, 77, -41, -48, 95, -38, -46,
+ 59, -1, -57, 49, -33, 19, 18, -46, 34, 31, -79, 47, 11, -38, 10, 19,
+ -14, -10, 26, -29, 28, -17, -27, 48, -15, -51, 78, -14, -73, 64, 12, -55,
+ 29, 3, -24, 52, -65, 26, 50, -75, -5, 81, -76, 0, 42, -6, -26, 10,
+ 18, -14, 4, -24, 33, 2, -69, 61, 43, -101, 40, 54, -73, 22, 18, -41,
+ 44, -19, -43, 94, -69, -13, 65, -26, -46, 35, 24, -34, -2, 23, -13, 6,
+ -19, 4, 38, -56, 14, 40, -37, -19, 66, -57, -9, 50, -47, 21, 6, -31,
+ 55, -34, -50, 98, -44, -47, 44, 28, -51, 6, 31, -3, -34, 8, 11, 6,
+ -18, -27, 78, -48, -28, 55, -2, -60, 57, -37, 14, 15, -48, 49, 22, -96,
+ 74, 23, -83, 36, 18, -17, -25, 41, -12, -4, -2, 1, 9, -14, -18, 36,
+ 12, -77, 54, 32, -67, 20, 38, -67, 61, -53, 32, 21, -60, 27, 41, -74,
+ 27, 33, -30, -6, 22, -1, -30, 20, 1, -4, -22, 9, 8, 37, -65, 18,
+ 61, -69, -3, 37, -19, -15, 15, -16, 57, -78, 20, 66, -67, -27, 76, -37,
+ -16, 11, 11, -5, -18, 10, 16, -5, -38, 36, 9, -20, -32, 73, -41, -36,
+ 62, -33, -9, 34, -41, 35, -7, -40, 65, -35, -26, 33, 2, -43, 42, -4,
+ -9, 5, -11, 19, -10, -16, 11, 16, -28, -9, 41, 2, -70, 67, -3, -55,
+ 23, 33, -26, 6, -29, 43, 16, -85, 51, 28, -54, 7, 27, -9, 2, -18,
+ 27, -4, -42, 31, 10, -19, -9, 18, 8, -24, -3, 45, -57, 25, 0, -7,
+ 15, -28, 10, 33, -46, -6, 52, -36, -15, 46, -29, -4, 12, -14, 34, -57,
+ 16, 40, -41, 3, 16, 8, -32, 16, 15, -17, -27, 47, -30, -1, 14, -5,
+ 16, -17, -33, 70, -44, -42, 84, -34, -27, 18, 15, 3, -20, -22, 55, -35,
+ -22, 31, 10, -11, -27, 27, 13, -28, -10, 41, -21, -3, -22, 41, -21, -13,
+ 6, 34, -68, 46, 25, -65, 50, -21, -1, 10, -33, 34, 1, -43, 58, -34,
+ -2, 13, 8, -25, 0, -2, 34, -29, -26, 45, -12, 4, -34, 32, 15, -54,
+ 17, 53, -76, 41, 4, -17, 13, -26, 13, 31, -47, 1, 52, -53, 11, 8,
+ 14, -31, -7, 19, 30, -60, 26, 27, -22, -10, 0, 18, -13, -24, 52, -38,
+ -17, 68, -60, 26, -9, -25, 41, -29, -8, 40, -25, -9, 26, -28, 15, -9,
+ -3, 11, -21, -1, 44, -47, 19, 0, 3, -14, -12, 38, -22, -23, 37, -10,
+ -13, 9, -6, 21, -14, -39, 61, -4, -68, 60, 6, -43, 28, -14, 21, -22,
+ -13, 36, -7, -40, 46, -14, -5, -18, 20, 22, -49, 22, 10, -18, 21, -30,
+ 9, 34, -54, 19, 22, -34, 27, 7, -45, 30, 0, -20, 23, -23, 29, -10,
+ -21, 25, 3, -23, -1, 5, 16, -33, 14, 25, -21, -11, 16, 3, -22, 5,
+ 6, 32, -73, 27, 62, -72, 5, 26, -21, 30, -37, 4, 40, -45, 5, 18,
+ -18, -1, 12, -3, 0, -18, 28, -8, -14, 11, -11, 13, -15, -3, 27, -17,
+ -30, 65, -45, -5, 28, -25, 1, 20, -36, 38, -11, -20, 35, -23, -20, 27,
+ 11, -42, 13, 17, 1, -25, 20, 10, -33, 10, 6, -7, 9, -26, 40, -3,
+ -63, 74, -30, -11, 10, -10, 5, 17, -47, 53, -10, -47, 29, 31, -45, 4,
+ 16, 14, -15, -33, 40, -11, -3, -10, 2, 18, -20, 9, 22, -44, 19, 20,
+ -42, 25, -5, -11, 25, -25, -3, 47, -63, 28, 20, -42, 7, 39, -41, 2,
+ 13, 10, -24, -8, 41, -26, -1, -13, 9, 42, -60, 0, 61, -54, -4, 19,
+ -6, 11, -19, -13, 52, -37, -26, 66, -38, -30, 49, -18, -11, 5, 7, 10,
+ -30, 4, 17, 2, -12, -15, 38, -19, -20, 30, -16, -23, 38, -13, -16, 29,
+ -22, 26, -17, -35, 62, -30, -35, 51, -16, -27, 40, -16, 3, -8, -4, 9,
+ 4, -26, 11, 20, -11, -38, 56, -19, -29, 31, 7, -39, 17, 10, 6, -8,
+ -41, 45, 26, -79, 36, 42, -58, 21, 6, -10, 7, -19, 17, -1, -15, -12,
+ 53, -22, -32, 24, 25, -59, 24, 22, -36, 10, 18, -27, 44, -45, 0, 42,
+ -45, -2, 30, -27, 12, 23, -38, 13, 5, 4, -4, -20, 1, 43, -27, -36,
+ 43, 14, -51, 12, 40, -41, 5, 18, -11, -1, -5, -11, 53, -56, -29, 91,
+ -41, -45, 57, -7, -18, -3, -4, 29, -20, -19, 20, 26, -57, 31, 17, -22,
+ -13, 28, -31, 3, 36, -33, 9, 17, -39, 42, -9, -54, 58, 6, -69, 44,
+ 30, -50, 24, 3, -17, 9, -20, 17, 8, -23, 1, 46, -50, 1, 27, 1,
+ -49, 37, 5, -17, 4, -5, 7, 18, -55, 39, 36, -85, 37, 48, -63, 5,
+ 27, -13, -6, -4, 5, 24, -26, -12, 42, -25, -34, 33, 20, -33, -13, 29,
+ -2, 7, -34, 12, 37, -50, 1, 47, -46, -1, 56, -54, -18, 59, -35, -6,
+ 12, -16, 20, -2, -27, 43, -12, -34, 22, 25, -41, -7, 43, -20, -18, 19,
+ -1, 1, -6, -20, 54, -55, -12, 67, -24, -56, 56, -8, -12, -7, -3, 16,
+ 20, -48, 20, 32, -46, 8, 23, -17, -38, 54, 1, -34, 2, 30, -1, -21,
+ -18, 38, -14, -35, 41, 3, -36, 19, 22, -45, 40, -32, 12, 12, -26, 2,
+ 35, -54, 34, 14, -25, -30, 47, 10, -53, 24, 13, -4, -18, 3, 5, 27,
+ -61, 38, 15, -39, 6, 40, -36, 0, 2, -6, 28, -40, 7, 46, -37, -30,
+ 59, -21, -29, 6, 48, -55, 12, 30, -21, -6, 5, -2, 1, -14, -7, 46,
+ -41, -4, 35, -8, -33, 29, -20, 26, -31, -10, 63, -46, -4, 12, 7, -11,
+ -15, 26, -14, -22, 54, -47, 12, 9, -1, -8, -7, -8, 41, -12, -60, 77,
+ -21, -26, 11, 13, 1, -26, -9, 59, -45, -16, 38, -3, -27, -1, 28, -8,
+ -19, 11, 20, -41, 34, -23, 22, -20, -9, 6, 51, -79, 40, 18, -40, 23,
+ -5, -19, 13, 2, 3, -4, -35, 71, -39, 5, -30, 33, 6, -29, -3, 38,
+ -29, -5, 18, -9, -4, -11, 16, 15, -32, -14, 77, -83, 30, 10, -10, -19,
+ 20, 15, -17, -19, 29, 7, -32, 6, -1, 14, -14, -6, 5, 36, -58, 47,
+ -18, -14, 4, 8, 8, -24, -15, 60, -36, -20, 43, -32, 3, -2, 1, 9,
+ -5, -8, 30, -33, 6, 6, 2, -12, -11, 24, 1, -22, 9, 34, -61, 25,
+ 11, -5, -18, -1, 38, -19, -33, 49, -19, -21, 18, -7, 1, 5, -4, -3,
+ 13, -30, 25, -5, -12, 2, 8, 17, -37, 0, 50, -38, -26, 40, -15, 7,
+ -24, 31, -11, -8, 6, -6, -3, 1, 9, -8, 6, -20, 25, 0, -21, 7,
+ 22, -48, 29, -4, 10, -22, 7, 22, -9, -34, 45, -15, -31, 30, -2, 0,
+ -30, 46, -18, -6, -17, 31, -6, -7, -21, 8, 45, -47, -7, 31, -17, -11,
+ 25, -20, 17, -30, 47, -38, -2, 5, 16, -36, 24, -2, 3, -7, 6, 10,
+ -23, 5, -11, 35, -42, 17, 0, 21, -35, 11, 16, -18, -15, 36, -24, -3,
+ 9, 5, 13, -49, 36, -11, -2, -14, 37, -32, 13, -1, 0, -2, -2, -8,
+ 17, -11, -21, 30, -1, -1, -41, 72, -65, 14, 14, 12, -41, 21, 4, 15,
+ -32, -1, 25, -9, -18, 3, 29, -38, 35, -22, 14, -20, 16, -6, -6, -13,
+ 29, -4, -17, 7, 14, -6, -38, 54, -32, 3, -16, 36, -39, 42, -40, 36,
+ -22, -13, 17, 14, -36, 12, 23, -25, 6, -25, 53, -33, -12, 5, 37, -46,
+ 6, 20, 9, -53, 52, -16, -22, 24, -9, 10, -17, 12, -20, 48, -73, 40,
+ 18, -30, -20, 52, -34, 11, -6, 0, 1, -15, 24, -16, 16, -30, 44, -27,
+ -10, 0, 34, -52, 24, 3, 2, -6, 12, -25, 35, -38, -14, 72, -73, 7,
+ 31, 15, -50, 20, 12, -5, -25, 23, 3, -10, -9, 15, 9, -41, 28, 6,
+ -5, -36, 44, -13, 10, -19, 2, 14, -10, -29, 56, -27, -35, 58, -19, -27,
+ 17, 16, -30, 10, -7, 15, -12, -3, 11, 18, -30, -13, 38, -17, -16, 3,
+ 32, -37, 23, -24, 30, -12, -26, 40, -14, -52, 59, 12, -55, 16, 35, -20,
+ -30, 39, -24, 21, -26, 12, 13, -10, -19, 23, 2, -35, 17, 33, -30, -17,
+ 39, -15, 12, -53, 50, -13, -25, 2, 50, -42, -1, 25, -22, 6, -5, 3,
+ -4, 2, -18, 39, -25, -3, 1, 29, -57, 22, 26, -22, -18, 34, -10, -10,
+ -11, 13, 31, -77, 46, 23, -22, -35, 61, -24, -13, 7, -3, 0, 4, -24,
+ 27, 12, -50, 35, 13, -19, -37, 69, -46, -4, 13, 5, -8, 6, -25, 40,
+ -26, -13, 38, -12, -28, 21, 22, -57, 40, -15, 11, -19, 4, 19, 9, -36,
+ 3, 42, -35, -30, 46, 0, -50, 59, -26, 9, -16, 12, -10, 10, -33, 44,
+ -8, -29, 8, 42, -43, -6, 26, -19, 14, -30, 34, 4, -21, -17, 49, -31,
+ -24, 34, 14, -53, 32, 13, -26, 12, -22, 26, -3, -22, -11, 66, -59, 0,
+ 43, -27, -23, 42, -32, 7, -7, 11, 9, -19, -1, 15, 16, -58, 43, 1,
+ -32, 11, 36, -44, 18, 0, 4, -4, -7, -22, 50, -22, -44, 67, -14, -43,
+ 37, 2, -32, 15, 7, 8, -22, -1, 14, 19, -43, 0, 40, -30, -14, 28,
+ 10, -32, 11, 1, 21, -33, -9, 31, 15, -72, 61, 4, -40, 21, 14, -37,
+ 22, 4, -4, -9, 5, -8, 23, -16, -22, 35, -24, 0, 12, 3, -17, 15,
+ 2, -10, -6, -8, 21, 7, -58, 40, 43, -75, 25, 28, -25, -18, 28, -15,
+ 6, -5, -4, 22, -5, -39, 37, 1, -30, 12, 23, -27, -8, 34, -22, 0,
+ -12, 15, 10, -28, 2, 45, -45, -9, 36, -22, -7, 13, -7, 6, 2, -18,
+ 17, 10, -34, 9, 18, -22, -1, 22, -9, -17, 23, -1, -22, 21, -20, 20,
+ -17, -6, 38, -33, -18, 55, -32, -21, 26, -5, -9, 5, -8, 16, 9, -47,
+ 36, 11, -36, -3, 38, -7, -48, 44, -2, -11, 2, -16, 15, 11, -36, 33,
+ -3, -18, 9, 19, -46, 26, -1, -11, 20, -24, 12, 16, -16, -17, 37, -32,
+ -6, 13, 13, -33, 25, 14, -27, 8, 1, -18, 22, -5, -15, 32, -46, 37,
+ -2, -19, -13, 38, -32, 8, 2, -4, 15, -12, -4, 19, -25, -10, 37, -19,
+ -11, -10, 57, -54, 19, -17, 18, 3, -18, -9, 27, -6, -36, 57, -23, -21,
+ 14, 11, -23, 32, -53, 56, -24, -5, -3, 11, -16, 16, -7, -20, 17, 11,
+ -3, -31, 42, -33, 14, -6, -2, -8, 39, -56, 48, -21, -20, 30, -8, -20,
+ 12, 15, -32, 41, -36, 29, -25, 14, -22, 22, -19, 9, 4, 10, -31, 17,
+ 11, -14, -1, -7, 17, -16, 6, -18, 64, -88, 47, 6, -20, -5, 22, -13,
+ 18, -28, 2, 25, -19, -10, -3, 29, -23, 11, -22, 39, -25, 13, -27, 20,
+ -2, -18, 15, -3, 3, 9, -17, -8, 38, -57, 35, 1, -9, -24, 43, -32,
+ 30, -30, -3, 19, -3, -21, 12, 14, -12, 2, -5, 11, -37, 37, -3, -13,
+ -4, 10, 11, -4, -38, 41, -9, -27, 37, -37, 16, 17, -7, -15, 22, -40,
+ 33, -2, -16, 4, 3, 8, -4, -20, 21, -3, -10, 8, -26, 37, -21, 8,
+ 0, -3, -3, 0, -8, 20, -15, -32, 54, -10, -26, 17, -12, 10, 24, -71,
+ 51, 3, -21, 9, -3, 17, -22, 2, 15, -21, -11, 39, -25, 11, -27, 28,
+ 3, -11, -26, 45, -43, 24, 7, -39, 47, -24, -15, 27, -13, -15, 35, -27,
+ 15, -17, 9, 0, -7, 0, 4, -9, 13, -3, -16, 28, -29, 21, -23, 11,
+ -4, 10, -30, 64, -63, 13, 28, -30, 16, -13, 0, 25, -39, -2, 53, -40,
+ 5, -19, 41, -25, -6, -3, 37, -40, 6, 8, 0, 6, -34, 32, 4, -27,
+ 13, 15, -34, 52, -63, 40, -5, -22, 5, 24, -32, 22, 11, -26, 14, -22,
+ 26, -21, 10, -8, 5, -10, 46, -66, 44, -20, 14, -7, -27, 23, 30, -53,
+ 24, 10, -37, 44, -40, 21, -11, 3, 6, 20, -47, 27, 5, -2, -18, -4,
+ 29, -13, -20, 27, 9, -47, 43, -37, 55, -62, 14, 33, -13, -28, 24, -9,
+ 23, -35, -4, 32, -14, -13, 28, -10, -30, 46, -43, 43, -46, 13, 13, -10,
+ 7, -3, -20, 39, -19, -19, 14, -15, 39, -31, -10, 25, 2, -34, 41, -35,
+ 15, -4, -3, 22, -18, -27, 46, -1, -36, 10, -4, 42, -56, 13, 31, -19,
+ -18, 28, -29, 27, -32, 24, 10, -44, 20, 32, -32, -17, 32, -13, 13, -35,
+ 20, 32, -53, 20, 9, -16, 16, -36, 39, -3, -33, 43, -26, 2, 2, 2,
+ -17, 24, -22, 14, -3, -12, 31, -28, -8, 26, -29, 19, -4, -15, 33, -39,
+ 22, 16, -37, 6, 17, -4, -13, -12, 37, 9, -65, 34, 25, -27, -9, 7,
+ 5, 10, -36, 45, -11, -41, 42, -6, -21, 7, -5, 31, -5, -57, 62, -12,
+ -15, -16, 23, 4, -24, 12, 26, -35, -11, 44, -25, -8, -1, -4, 28, -11,
+ -37, 61, -48, 23, -1, -30, 29, -8, -2, 6, -19, 18, 15, -41, 30, -4,
+ -11, -11, 28, -10, -4, -37, 81, -45, -43, 61, -19, 1, -11, 0, 31, -30,
+ -25, 68, -43, -11, 0, 27, -1, -33, -7, 77, -54, -30, 44, -6, -5, -14,
+ 17, -6, -10, 6, 30, -68, 50, -16, 5, 5, -30, 30, 26, -69, 36, 8,
+ -34, 37, -28, 11, 0, -1, 9, 1, -41, 53, -22, -24, 23, 5, -9, -11,
+ 12, 28, -61, 28, 36, -68, 51, -33, 25, -6, -26, 7, 53, -65, 2, 47,
+ -25, -23, 17, 20, -4, -51, 38, 29, -67, 31, 1, 22, -35, -8, 40, -9,
+ -46, 47, -13, -8, 5, -15, 37, -27, -20, 45, -16, -45, 59, -37, 19, -6,
+ 2, 1, -11, -3, 34, -42, 0, 33, -30, 16, -13, 13, 2, -23, 18, -5,
+ -26, 43, -24, 15, -26, 4, 35, -15, -62, 64, 19, -75, 50, -8, 8, -14,
+ -12, 31, -19, -30, 45, -10, -12, -10, 36, 3, -53, 14, 45, -37, -22, 42,
+ -25, 21, -36, 21, 37, -61, 5, 47, -49, 19, -4, 5, 1, -12, 7, 3,
+ -11, 2, 18, -28, 13, -4, 18, -13, -20, 33, -22, -8, 21, -12, -10, 24,
+ -9, 2, -27, 15, 33, -41, -18, 56, -40, 9, -5, 6, 20, -44, 11, 39,
+ -35, -22, 50, -7, -36, -6, 41, -10, -30, 15, 20, -22, 7, -11, 16, 6,
+ -51, 59, -21, -26, 24, 12, -24, 8, -7, 12, 3, -36, 27, 18, -42, 22,
+ 9, -22, 11, -2, 15, -40, 38, -13, -16, 8, 24, -33, 15, -13, 4, 23,
+ -42, 17, 30, -34, -5, 28, -22, 11, -23, 30, -14, -28, 37, 12, -46, 11,
+ 31, -23, -12, -7, 36, -17, -6, -4, 25, -18, 4, -29, 53, -48, 4, 24,
+ -9, -21, 30, -1, -20, 2, -13, 51, -51, -1, 39, -23, -18, 33, -23, 3,
+ 3, 2, -13, 11, 4, -13, 15, -14, -3, 1, 24, -53, 55, -24, -17, 36,
+ -1, -49, 45, -7, -12, -2, -4, 24, -23, 1, 6, 23, -51, 30, -8, 14,
+ -29, 17, 12, -9, -21, 21, 1, 3, -32, 21, 30, -59, 27, 25, -21, -26,
+ 36, -24, 16, -23, 15, 10, -15, 11, -11, -3, 14, 1, -30, 32, -24, 27,
+ -25, 10, -12, 29, -33, 7, -5, 25, -29, 14, 15, -42, 20, 18, -27, 1,
+ 21, -19, 17, -18, 2, 19, -12, -34, 47, -21, -6, 9, -2, 14, -32, 32,
+ -23, 14, -21, 21, 0, -13, -8, 42, -35, -19, 33, 4, -34, 23, -5, -6,
+ 22, -31, 21, -8, -5, -3, 15, -22, 10, 2, 7, -17, 11, 3, -10, 2,
+ -1, -2, -9, 25, -20, 11, -18, 17, -3, -12, 2, 9, -1, -10, 5, 0,
+ 15, -40, 36, -5, -28, 16, 24, -34, 16, -1, 13, -32, 11, 9, 5, -26,
+ 5, 32, -32, 4, -1, 29, -38, 8, 7, -6, 5, -2, -5, 18, -26, -2,
+ 39, -42, 0, 26, 2, -43, 45, -30, 20, -11, -6, -3, 16, -7, -6, 3,
+ 12, -13, 5, -7, -21, 47, -29, -11, 9, 36, -45, 8, 0, 22, -28, -7,
+ 32, -22, -9, 20, 12, -40, 24, -8, 14, -28, 10, 9, 12, -29, 15, -7,
+ 15, -23, 5, 14, -24, 12, 8, 4, -38, 36, -4, -7, -30, 47, -13, -24,
+ 16, 23, -46, 29, -3, -10, 20, -43, 35, 0, -4, -30, 47, -18, -21, 16,
+ 19, -35, 11, 19, -21, -11, 27, -12, -9, 16, -21, 23, -32, 30, 3, -22,
+ -15, 51, -38, -1, -2, 11, 15, -28, -1, 16, 13, -42, 23, 4, -6, -32,
+ 61, -24, -35, 34, 29, -55, 4, 13, 9, -6, -26, 35, -6, -11, -11, 19,
+ -6, -3, -15, 43, -41, 4, 22, -1, -34, 18, 15, -35, 18, -1, 23, -35,
+ 18, -2, -9, 1, 10, -18, 17, -18, 21, -8, -17, 24, -1, -20, -7, 26,
+ -11, 6, -33, 42, 0, -40, 9, 46, -48, -6, 24, 13, -39, 8, 41, -43,
+ 3, 6, 6, -7, -6, -8, 42, -37, -11, 39, -16, -26, 25, 3, -24, 9,
+ 11, 6, -34, 17, 14, -12, -22, 20, 0, 14, -38, 27, 10, -37, 22, -1,
+ -5, -7, 11, 4, -3, -29, 38, -5, -26, 4, 20, -17, 6, 2, 11, -17,
+ -10, 40, -49, 10, 26, -8, -24, 11, 12, 5, -36, 21, 20, -22, -29, 28,
+ 30, -30, -24, 31, 25, -70, 39, 4, -16, 3, 9, -13, 16, -26, 23, 19,
+ -46, 1, 29, 6, -37, 8, 27, -8, -33, 36, -24, 5, 14, -8, -8, 1,
+ 4, 15, -27, -11, 44, -38, 6, 12, -3, -12, 20, -17, 16, -35, 28, -4,
+ 0, -13, 8, 23, -24, -16, 28, 11, -58, 48, 6, -39, 11, 24, -9, -8,
+ -25, 42, -16, -14, 12, 2, 13, -31, 6, 26, -10, -48, 64, -22, -21, 6,
+ 28, -15, -11, -2, 22, -30, 11, 15, -25, 13, 2, -1, -7, -4, 6, 17,
+ -37, 17, 0, 1, 14, -23, 4, 16, -23, 6, 12, -31, 30, 6, -18, -25,
+ 45, -7, -20, -15, 44, -38, 9, 22, -37, 24, 6, -20, 14, -17, -8, 44,
+ -27, -22, 16, 30, -33, -18, 20, 31, -50, 11, 27, -21, -4, -3, 26, -15,
+ -24, 15, 20, -27, 16, -12, 9, 5, -24, 3, 26, -27, 5, 15, -19, 9,
+ -9, 26, -25, -5, 10, -4, -6, 31, -45, 18, 24, -23, -23, 27, -3, 2,
+ -18, 9, 13, -18, 19, -17, 7, -1, -24, 31, 5, -49, 31, 32, -40, -7,
+ 10, 14, -12, -12, 5, 21, -30, 25, -12, 4, -18, 9, 11, -13, -20, 37,
+ -8, -3, -13, -3, 33, -21, -32, 44, -7, -22, 28, -24, 5, 12, -19, 2,
+ 6, 2, -16, 11, 10, -6, -23, 31, -25, 7, 6, -16, 18, 1, -35, 40,
+ -9, -18, 12, 4, -2, -25, 20, 19, -16, -35, 46, -14, -8, -3, -1, 24,
+ -12, -25, 26, -4, -6, 3, -12, 20, -24, 18, 9, -20, -2, 18, -13, -1,
+ -16, 8, 26, -35, 12, 10, -11, 6, 2, -30, 46, -43, 16, 6, 1, -20,
+ 26, -18, 8, -13, 9, -3, 3, 1, -25, 29, 13, -50, 12, 41, -47, 15,
+ 14, -12, 2, -3, -1, 14, -25, -3, 26, -23, 19, -35, 41, -5, -23, -1,
+ 31, -30, 8, -15, 32, -29, -7, 22, 10, -35, 12, 6, -2, 20, -50, 36,
+ 7, -17, -4, -1, 7, 2, -21, 19, -12, 1, 28, -25, -5, 9, -3, -12,
+ 32, -45, 16, 21, 0, -43, 21, 28, -19, -38, 45, -15, -8, 28, -43, 39,
+ -12, -23, 13, 19, -39, 23, -3, 17, -32, 6, 20, -5, -32, 23, 8, -15,
+ -1, 11, 9, -28, 5, 20, -18, -6, 9, -18, 50, -50, -8, 49, -30, -5,
+ -4, 14, -19, 28, -21, 2, 4, 11, -20, 6, 3, -5, -24, 54, -34, -14,
+ 26, -4, -2, -16, 5, 20, -23, 1, 6, -9, 32, -37, 1, 25, -22, -8,
+ 31, -6, -37, 31, 0, 3, -37, 24, 25, -27, -20, 27, 1, 4, -26, 13,
+ 3, -14, 12, -6, 6, -3, -6, 18, -14, -27, 38, 5, -36, 14, 13, -22,
+ 26, -13, -22, 36, -23, -5, 3, 18, -12, -23, 31, -5, -24, 23, -15, 17,
+ -7, -23, 20, 6, -4, -19, 20, -8, 15, -32, 13, 17, -30, 17, 13, -19,
+ -8, 4, 24, -18, -29, 36, 7, -21, -20, 28, 13, -17, -31, 36, -9, -7,
+ 7, 6, -9, -4, 7, -6, 10, -32, 41, -26, 12, -10, -12, 35, -10, -39,
+ 36, -9, -7, 7, 6, -9, -4, 11, -14, 5, -7, 9, -13, 24, -27, 4,
+ 14, 7, -31, 19, -14, 17, -5, -34, 57, -31, -7, -6, 28, -15, -11, 2,
+ 25, -21, -14, 15, 18, -35, 12, 1, 9, -20, -2, 32, -37, 26, -17, 7,
+ 1, -10, -18, 54, -37, -16, 23, 11, -13, -23, 34, -5, -16, -10, 25, -28,
+ 30, -10, -7, -5, 18, -24, 25, -24, 18, -11, 0, 3, -19, 34, -12, -12,
+ 2, 3, -13, 32, -37, 20, 4, -6, -25, 29, -3, -2, -11, -2, 28, -38,
+ 18, 7, -5, -7, 0, -4, 21, -36, 30, -19, 25, -29, -15, 48, -11, -43,
+ 33, 33, -64, 17, 26, -12, -18, 9, -1, 18, -33, 23, -13, 21, -18, -13,
+ 18, -2, -20, 20, 6, -15, 4, -12, 28, -27, 1, 10, -5, 3, 0, -17,
+ 15, 17, -30, 2, 5, -8, 17, -11, -2, 9, -20, 23, -27, 23, -10, -3,
+ 7, -3, -25, 31, 9, -28, -9, 30, -5, -28, 15, 29, -36, -9, 29, -11,
+ -20, 33, -27, 21, -14, -12, 21, -3, -9, -2, 12, -5, -27, 27, 7, -20,
+ -11, 32, -9, -15, -1, 9, 20, -42, 12, 9, -4, 3, -6, -3, 6, 0,
+ -12, 15, -25, 27, -6, -6, -6, 6, -2, -4, 5, 9, -20, 12, 8, -17,
+ -10, 30, -12, -24, 25, -15, 18, -21, 21, -8, -6, -9, 12, -6, 15, -33,
+ 26, 8, -32, 13, 21, -12, -28, 20, 11, -6, -28, 27, 11, -21, -10, 22,
+ -1, -11, -7, 24, -12, -27, 35, -8, 0, -20, 23, -10, 9, -30, 32, -15,
+ 3, -7, 6, -2, 10, -17, 1, 8, -4, -5, -3, 14, -9, 1, -11, 18,
+ -13, 15, -33, 22, 14, -32, 11, 9, -1, -17, 14, 0, -3, -16, 29, -21,
+ -4, -1, 28, -24, -2, -11, 41, -25, -23, 24, 6, -18, -13, 37, -21, -2,
+ -4, 29, -40, 11, 12, 4, -25, 12, -9, 23, -17, -14, 27, -2, -26, 9,
+ 18, -14, -1, -15, 29, -18, -4, 5, 12, -26, 18, -3, -7, 3, 13, -10,
+ -25, 44, -38, 11, 8, -2, -25, 28, -9, 12, -13, -13, 10, 27, -53, 19,
+ 16, -4, -20, 12, 12, -21, 5, 12, 3, -35, 22, 8, 0, -28, 18, 16,
+ -25, -3, 9, 8, -3, -19, 8, 24, -34, -4, 38, -16, -30, 29, -1, -2,
+ -25, 28, -1, -21, 11, 10, -18, -1, 10, 1, -7, 0, 1, -7, 15, -15,
+ -5, 16, 2, -22, 8, 0, -1, 26, -34, -22, 56, -26, -11, 12, 9, -9,
+ -9, 4, 7, -8, -1, 8, 0, -21, 10, 19, -8, -25, 17, 10, -18, 3,
+ -4, 26, -15, -29, 30, 9, -46, 36, 12, -33, 1, 18, -2, -16, 4, 16,
+ -10, -16, 11, 2, 8, -19, 5, 1, 10, -21, 20, -8, -1, -3, 1, 7,
+ -19, 7, 11, -12, 5, 5, -26, 29, -11, -5, -2, 12, -13, 9, -22, 23,
+ 3, -20, 4, 17, -16, -13, 17, 15, -16, -34, 37, -5, 8, -32, 23, 17,
+ -36, -2, 36, -25, -4, 28, -18, -20, 15, 4, 7, -12, -24, 43, -19, 0,
+ -11, 25, -9, -12, -7, 10, -1, 11, -2, -12, 13, -27, 30, -9, -15, 8,
+ 17, -28, 18, -9, 3, 7, -8, -10, 16, -26, 35, -22, -10, 37, -35, 1,
+ 11, 11, -19, -2, 9, 17, -37, 11, 10, 9, -16, -12, 27, -11, -22, 16,
+ 24, -48, 25, -1, -3, 4, -20, 13, 39, -72, 34, 1, 2, -6, 4, -1,
+ -8, 2, -8, 18, -10, -1, -5, 19, -30, 5, 30, -16, -26, 36, -26, 3,
+ 21, -27, 10, 4, -10, 0, -4, 15, 9, -41, 32, -11, 2, -11, 15, -3,
+ -7, -8, 16, -3, -21, 23, -2, -9, -4, -2, 20, -5, -37, 49, -20, -6,
+ -9, 17, 17, -36, -8, 40, -24, -5, 3, 8, 5, -12, -6, 15, 2, -27,
+ 28, -4, -23, 16, 5, -1, -26, 29, 11, -38, 22, -12, -8, 38, -34, -3,
+ 10, 4, -2, -5, -8, 24, -16, -20, 21, 1, -7, 11, -7, -4, -15, 15,
+ 15, -21, -6, 10, -1, 17, -45, 23, 29, -42, 2, 18, -5, -6, -1, 22,
+ -20, -19, 16, 21, -20, -18, 23, 2, 5, -41, 36, 10, -34, 12, 12, -25,
+ 11, 1, 6, -6, -11, 20, -11, 10, -11, -12, 13, 8, -21, 5, -1, 14,
+ 3, -26, 5, 27, -39, 18, 7, -27, 34, -20, 13, -20, 7, -4, 25, -23,
+ -16, 7, 47, -35, -29, 37, 10, -35, 4, 12, -1, 0, -15, 25, -23, -12,
+ 35, 7, -51, 28, -1, 16, -33, 5, 27, -21, 2, -5, 13, -3, 0, -20,
+ 27, -30, 8, 16, -4, -13, 14, -15, 19, -12, -6, 8, -9, 19, -27, 4,
+ 20, -9, -12, 21, -37, 41, -22, 1, 1, 13, -33, 20, 14, -30, -2, 22,
+ 21, -51, 3, 38, -7, -35, 17, 6, 11, -43, 33, 9, -36, 10, 31, -24,
+ -13, 16, -6, 24, -36, -1, 16, 19, -45, 20, 11, 2, -30, 31, -21, -14,
+ 29, -4, -12, 3, -6, 9, 15, -37, 20, -4, 8, -18, 12, -7, 17, -8,
+ -12, -9, 23, 8, -28, 1, 29, -19, -18, 27, -2, -8, -28, 44, -4, -36,
+ 15, 33, -30, -13, 13, 14, -20, -7, 25, -11, -5, -8, 21, -1, -8, -37,
+ 50, 1, -53, 27, 28, -21, -10, 4, 16, -24, 10, 6, -12, 0, 2, 6,
+ 1, -13, 2, 21, -26, 3, 13, -19, 10, 9, -18, -3, 22, -18, -1, -2,
+ 14, -1, -23, 21, -6, -2, -9, 20, 5, -35, 1, 34, -21, -16, 22, 1,
+ -8, -5, 1, 18, -12, -23, 18, 5, -17, -7, 37, -6, -35, 6, 47, -44,
+ -7, 20, 5, -10, -23, 35, -6, -12, -12, 39, -27, -10, 9, 21, -21, -6,
+ 2, 5, 1, 6, -28, 17, 20, -31, -3, 15, 7, -26, 31, -40, 43, -32,
+ 23, -19, 11, -22, 26, -6, -1, -25, 33, 2, -25, -7, 9, 26, -16, -30,
+ 29, 20, -47, 13, 16, -9, -19, 18, 23, -32, -17, 32, 21, -38, -13, 14,
+ 43, -66, 19, 23, 5, -50, 47, -20, 2, -11, 22, -5, -6, -21, 4, 38,
+ -15, -32, 12, 35, -35, -4, 7, 18, -17, -1, -7, 6, 5, 0, 0, -7,
+ 0, -8, 21, -10, 5, -28, 30, 3, -17, -29, 57, -16, -17, -10, 28, -9,
+ -20, 26, -12, 3, -20, 27, -3, -7, -42, 65, -9, -45, -3, 63, -33, -11,
+ -6, 28, -17, -1, -6, 6, 7, -12, 0, 25, -21, -30, 54, -9, -37, 1,
+ 28, 7, -42, 18, 11, 17, -46, 24, -9, 27, -38, 22, -20, 23, -21, 11,
+ -6, 42, -71, 20, 32, -11, -43, 44, -3, -4, -27, 12, 24, -8, -18, -8,
+ 30, -19, -23, 44, -8, -30, 0, 45, -39, 0, -1, 28, -16, -17, -15, 44,
+ -13, -11, -13, 36, -24, -11, 12, 17, -30, 8, 17, -10, -18, 9, 22, -18,
+ -15, 3, 25, -25, 11, -6, 5, 7, -18, -3, 15, -1, -17, 8, 28, -32,
+ -17, 36, 8, -41, 12, 7, 13, -22, -14, 18, 41, -57, -1, 25, 10, -40,
+ 18, 11, -8, -23, 25, -16, 37, -45, 17, 10, 2, -60, 64, -15, -3, -16,
+ 22, -9, 9, -27, 30, -7, -21, 3, 20, -10, 6, -12, 15, -19, 14, -19,
+ 3, 22, -8, -29, 37, -28, 29, -26, 11, -15, 15, -17, 21, -26, 18, 5,
+ -5, -11, 2, 16, -10, -10, -5, 29, -30, 4, 3, 18, -21, 4, 1, 8,
+ -13, -10, 1, 40, -35, -26, 44, 5, -38, 8, 30, -24, 0, -1, 0, 12,
+ -18, -1, 18, -8, -28, 39, -18, 24, -35, 24, -36, 46, -41, 12, -3, 24,
+ -37, 31, -28, 32, -16, 2, -27, 39, -34, 7, 24, -19, -6, 14, -10, -1,
+ 14, -16, -4, 25, -26, -4, 8, 22, -40, 33, -30, 22, -15, 36, -63, 39,
+ 1, 10, -54, 36, 9, 5, -51, 49, -13, 5, -7, -7, 15, -9, -10, 2,
+ 12, -18, 6, 3, 18, -29, 9, 10, -10, 1, -20, 20, -3, -1, -13, 21,
+ -26, 41, -36, 2, 23, -23, -10, 39, -41, 17, -10, 8, 7, -13, 23, -54,
+ 66, -26, -50, 54, 17, -66, 59, -46, 30, -10, 6, -8, -18, 19, 16, -32,
+ 12, 6, -2, 3, -36, 33, -6, -7, 12, -16, 6, 14, -21, 14, 16, -58,
+ 37, 3, 0, -35, 44, -16, 17, -38, 28, -14, 25, -45, 28, -21, 32, -31,
+ 11, 17, -24, 11, 5, -24, 18, -6, -3, 0, -3, 21, -33, 24, 20, -78,
+ 66, -8, -24, 3, 17, -14, 24, -41, 34, -25, 27, -32, 17, -5, 13, -26,
+ 28, -29, 22, -8, -16, 33, -30, 2, 25, -27, 1, 31, -36, -7, 31, -8,
+ -12, -5, 17, -7, 5, -26, 32, 1, -18, -16, 27, -7, -10, 2, 21, -42,
+ 30, -3, -19, 33, -40, 19, 6, -13, -5, 17, -10, 28, -63, 40, 6, -10,
+ -9, 7, -3, 12, -20, -1, 17, -1, -6, -14, 18, 1, -19, 12, 5, -9,
+ -2, -14, 33, -3, -44, 51, -17, -6, -16, 36, -35, 29, -31, 31, -24, 15,
+ -23, 33, -35, 20, -4, -1, -19, 27, -1, -29, 25, 1, -20, 25, -23, -13,
+ 62, -50, -18, 43, -20, 1, -4, 16, -18, 4, -16, 36, -42, 42, -42, 38,
+ -28, 9, -10, 31, -40, 30, -39, 30, 8, -28, 11, 9, -7, -6, -8, 10,
+ 22, -36, -5, 26, 4, -41, 30, 12, -11, -10, -14, 37, -29, 3, -6, 9,
+ -5, 15, -30, 40, -26, 12, -25, 25, -21, -12, 46, -17, -39, 47, 7, -57,
+ 45, -14, 1, -13, 21, -21, 14, -7, 7, -11, 18, -34, 25, 7, -28, 22,
+ 1, -12, 11, -24, 4, 38, -44, 17, 2, -12, 19, -17, 0, 9, 17, -55,
+ 29, 3, 3, -27, 48, -38, 16, -17, 24, -19, 26, -49, 29, 9, -18, -25,
+ 50, 2, -31, -20, 43, -3, -35, 23, 13, -34, 9, 20, -15, -8, 29, -37,
+ 29, -21, 4, -8, 36, -52, 29, -8, 6, -18, 35, -34, 22, -21, 10, 5,
+ -11, -13, 35, -26, -3, 12, -17, 13, 1, -12, -4, 24, -18, -6, 18, -7,
+ -13, 17, -4, -30, 48, -41, 10, 34, -39, -22, 73, -48, -12, 12, 22, -14,
+ -31, 18, 29, -17, -21, 22, -3, -8, -12, 25, -11, 13, -41, 36, -3, -2,
+ -27, 37, -6, -36, 17, 18, -7, -10, 4, -5, 10, -21, 13, 15, -21, 2,
+ -1, -5, 8, -1, -16, 29, -24, 14, -18, 26, -24, 17, -26, 21, -18, 24,
+ -49, 82, -52, -11, 36, -22, -17, 30, -21, 1, 1, -1, 8, -2, -7, 2,
+ 17, -9, -36, 37, -5, -15, -4, 27, -20, 11, -31, 46, -18, -13, -11, 58,
+ -67, 19, -4, 40, -43, 9, -14, 41, -32, -16, 46, -19, -13, 5, -5, 6,
+ 2, -16, 10, -9, 18, -13, 3, 24, -37, 11, 1, 0, -8, -9, 28, -1,
+ -41, 40, -10, 6, -13, 1, -11, 30, -28, -10, 30, 1, -36, 17, 28, -54,
+ 51, -24, 1, -6, 6, -12, 33, -48, 23, 18, -17, -23, 27, 11, -23, -13,
+ 27, -7, -1, -24, 35, 3, -48, 35, 8, -20, -3, 3, 16, -11, 8, -35,
+ 32, 7, -27, -22, 81, -85, 36, -7, 16, -16, 2, 0, 13, -28, 12, -16,
+ 24, 6, -25, -14, 47, -15, -25, 3, 37, -41, -5, 32, -25, 11, 6, -16,
+ 25, -34, 14, 8, 13, -52, 30, 6, 13, -56, 56, -27, 13, -11, -6, 16,
+ -12, -1, 18, -40, 18, 19, -13, -11, 7, -2, 9, 10, -39, 9, 46, -48,
+ -18, 59, -32, -3, 14, -10, 10, -13, 10, -13, 14, -11, -10, 5, 31, -43,
+ 10, 23, -16, 3, -29, 50, -23, -19, 16, 15, -19, 3, -20, 39, -19, -14,
+ -6, 54, -44, -12, 18, 30, -56, 28, -15, 22, -16, -15, 31, -8, -9, -1,
+ 1, 1, 2, -8, 9, 10, -43, 41, -9, 8, -48, 62, -30, -9, 13, 6,
+ -24, 32, -31, 8, -4, 16, -27, 27, -19, -1, -6, 37, -40, 14, -3, 0,
+ 25, -59, 34, 18, -18, -21, 17, 13, -11, -8, -11, 43, -40, 1, 6, 24,
+ -37, 10, 14, -4, -12, -2, 17, 11, -40, 10, 16, 17, -51, 24, 14, -4,
+ -31, 22, 18, -32, 15, -24, 46, -38, 9, 2, -2, 14, -15, -12, 15, 3,
+ -28, 29, -7, -6, 13, -7, -6, 2, 3, -17, 28, -28, -9, 37, -17, 0,
+ 3, 10, -19, -5, 19, -17, 12, -25, 30, -19, 8, -27, 49, -15, -27, 9,
+ 10, 7, -31, 6, 30, -12, -45, 41, 24, -42, -1, 28, -2, -38, 29, -18,
+ 23, -4, -43, 35, 26, -54, 23, 7, 6, -30, 17, -14, 32, -40, 24, -13,
+ 17, -15, -11, 16, 16, -20, -26, 47, -10, -26, -6, 41, -19, -22, 36, -41,
+ 33, 5, -32, 12, 28, -51, 19, 27, -40, 7, 35, -34, 9, -22, 42, -20,
+ -15, -3, 43, -55, 15, 23, -10, -11, 3, 14, -32, 31, -26, 21, 7, -44,
+ 15, 40, -22, -41, 54, -17, -17, 8, -6, 10, 11, -17, -6, 15, -2, -20,
+ 31, -19, 4, -17, 22, 0, 2, -36, 39, 0, -31, 23, -38, 59, -15, -29,
+ -13, 69, -50, -22, 43, -11, -16, 0, 16, -9, -10, 13, 5, -8, -18, 27,
+ -8, -2, -12, 13, -1, -16, 16, -18, 27, -11, -19, 39, -28, -26, 28, 36,
+ -85, 72, -40, 24, -10, 0, -9, 30, -29, -11, 22, -13, -7, 23, -10, -14,
+ 6, 13, -15, 22, -31, 12, 0, 0, -3, -15, 19, 14, -21, -22, 27, 35,
+ -72, 36, -3, 18, -54, 50, -29, 38, -47, 14, 19, -11, -25, 27, 9, -23,
+ -2, 2, 16, -6, -24, 22, 10, -27, 7, 16, -30, 11, 24, -40, 31, -28,
+ 29, 1, -28, 7, 17, 3, -45, 40, -11, -7, 4, 19, -45, 24, 24, -50,
+ 48, -35, 11, 9, -12, -14, 30, -23, 8, 7, -15, -7, 53, -59, 13, 5,
+ 15, -46, 49, -48, 57, -36, -20, 34, 1, -10, -15, 15, 20, -36, -9, 35,
+ 6, -39, 7, 14, 27, -81, 70, -21, 5, -22, 21, -6, 1, -13, 19, -19,
+ 4, -10, 35, -43, 31, -3, -7, -15, 40, -56, 33, -1, -33, 51, -35, -2,
+ 24, -18, 5, 0, 4, -16, 10, -6, 9, -28, 37, -38, 45, -35, 0, 37,
+ -38, 7, 19, -32, 3, 17, -2, -23, 19, 15, -23, 5, -2, 13, 1, -37,
+ 8, 59, -80, 26, 13, 15, -31, -8, 30, -7, -7, -19, 22, -2, -9, -2,
+ 12, -7, 3, 1, -25, 47, -53, 35, -5, -27, 21, 15, -25, 13, -24, 42,
+ -41, 19, 2, -13, 1, 23, -40, 37, -45, 46, -8, -41, 44, -11, -17, 23,
+ -9, -20, 22, -3, -15, 22, -23, 19, -7, 2, -34, 65, -56, 7, 28, -8,
+ -37, 37, 3, -8, -34, 39, -11, 9, -29, 6, 35, -14, -49, 48, 5, -25,
+ 5, -25, 66, -47, -9, 28, -7, -12, 0, 17, -20, -2, 21, -12, -23, 54,
+ -50, 20, 7, -20, 7, -2, 3, 4, -26, 26, -6, -14, 15, -3, -10, 12,
+ -10, -4, 23, -33, 14, -12, 38, -55, 36, 0, -6, -5, 0, -4, 7, 0,
+ -14, 2, 8, -11, 13, 5, -33, 41, 4, -62, 40, 8, -6, -8, -31, 52,
+ -4, -44, 25, 20, -18, -24, 32, -11, -9, -4, 30, -37, 34, -31, 7, 30,
+ -29, -14, 28, -10, -9, 6, 0, -5, 14, -9, -3, -2, 10, -22, 29, -22,
+ -2, 6, -5, 16, -25, 6, 27, -19, -9, -11, 29, -13, -5, -6, 16, 5,
+ -20, -1, 30, -20, -8, 7, -8, -2, 3, 14, -9, -24, 35, -7, -14, -12,
+ 32, -5, -18, -15, 35, -7, -13, -1, -4, 27, -20, -30, 58, -15, -29, 9,
+ 15, -16, -3, 1, 4, 5, -4, -11, 17, 3, -29, 28, -10, -18, 20, -7,
+ -2, 4, 2, -17, 22, -3, -31, 23, 23, -32, -14, 34, -3, -14, -13, 11,
+ 21, -26, -16, 36, -7, -13, 15, -8, -3, -1, -11, 15, -8, -4, -4, 24,
+ -21, 1, 11, 3, -22, 5, 15, -24, 0, 37, -31, 7, -18, 15, 16, -15,
+ -19, 26, 0, -10, -26, 31, 6, -19, -6, 21, -19, 20, -13, -3, 13, -2,
+ -32, 24, 2, -8, -10, 36, -29, -10, 19, 10, -25, 5, -9, 31, -23, -21,
+ 21, 26, -25, -9, -5, 35, -17, -34, 17, 42, -44, -11, 30, 11, -40, 18,
+ 8, -6, -11, 11, -26, 39, -18, -23, 37, -12, -32, 45, -8, -22, 5, 16,
+ -15, -10, 6, 17, -15, -3, 9, -22, 41, -22, -25, 29, 5, -30, 6, 12,
+ 17, -32, 7, 20, -26, 9, 9, -10, 7, -17, 10, 11, -16, -7, 12, 5,
+ -4, -26, 25, 24, -46, -4, 50, -39, -11, 8, 35, -36, 2, -9, 33, -7,
+ -22, -26, 76, -37, -41, 33, 28, -43, 14, 6, 2, -8, 2, -20, 34, -19,
+ -2, -4, 15, -6, -23, 28, -3, -32, 33, -16, 7, -11, 14, 9, -10, -30,
+ 35, -25, 17, -14, 1, 14, 12, -38, 16, 15, -7, -30, 15, 18, -24, -6,
+ 47, -38, 6, 7, -9, -2, -3, 1, 12, -8, -23, 20, 35, -47, -14, 51,
+ -9, -48, 19, 20, 0, -25, -2, 20, 16, -29, -25, 60, -17, -23, -8, 31,
+ -4, -30, 12, 20, -14, -4, -1, 17, -11, -9, 7, 7, -17, 1, -12, 25,
+ -5, -20, 15, 19, -29, 2, 5, 11, -19, -18, 31, 1, -27, 18, -17, 51,
+ -53, -2, 29, 4, -37, 17, 11, -11, -23, 41, -17, -10, 13, -4, -8, 18,
+ -27, 17, 1, -19, -7, 51, -37, -28, 53, 4, -47, 5, 18, 17, -32, -8,
+ 14, 36, -46, 3, 11, 11, -24, 4, 0, 16, -7, -26, 25, 20, -44, 7,
+ 20, -12, 2, -14, 4, 33, -38, 1, 8, 20, -34, -12, 61, -46, -19, 44,
+ -10, -4, -18, 12, 12, -8, -26, 16, 22, 2, -51, 18, 53, -56, -5, 30,
+ -9, -22, 32, -11, -18, 18, 13, -25, -7, 8, 9, 3, -20, 1, 32, -27,
+ -9, 5, 19, -20, -13, 18, 8, 3, -35, 22, 31, -47, -2, 16, -8, 15,
+ -10, -22, 54, -20, -23, -6, 51, -52, -13, 48, -23, -11, 28, -30, 38, -6,
+ -50, 28, 33, -58, 2, 34, 16, -53, -1, 55, -13, -42, 15, 23, -7, -33,
+ 13, 21, -14, -6, 2, -2, 27, -43, 27, 11, -19, -16, 26, -16, -4, 16,
+ -17, 1, 20, -17, 8, -17, 6, 26, -25, -24, 40, -13, 6, -14, -14, 29,
+ 3, -32, -5, 46, -21, -28, 38, -30, 6, 28, -47, 3, 65, -67, -5, 61,
+ -34, -27, 31, 12, -30, -7, 11, 19, 0, -43, 18, 47, -52, -20, 52, -14,
+ -9, -10, -5, 55, -45, -29, 55, 16, -83, 28, 36, -23, 6, -8, -13, 37,
+ -17, -30, 32, -9, -6, 10, -19, 16, 4, 9, -35, 22, -1, -17, 3, 8,
+ 10, -10, -21, 40, -27, -5, 16, -6, -27, 47, -23, -26, 48, -18, -19, 14,
+ -1, -9, 5, 1, -20, 58, -57, -14, 55, -16, -40, 37, -6, 11, -19, -22,
+ 43, 2, -55, 27, 37, -38, -29, 58, -6, -11, -22, 4, 26, -7, -67, 67,
+ 21, -56, 19, 15, -5, 0, 2, -41, 37, 10, -65, 49, 8, 1, -19, 1,
+ 9, 8, -20, -9, 22, -14, -3, 4, -1, 13, -6, -11, 15, -8, -15, 13,
+ 16, -38, 14, 24, -39, 20, 9, -17, 14, -15, 7, 3, -12, -3, 30, -25,
+ -24, 43, -1, -40, 18, 17, 0, -22, -14, 31, 20, -68, 35, 32, -43, -9,
+ 35, -16, 4, 2, -35, 35, 27, -81, 40, 31, -21, -30, 29, -12, 13, 10,
+ -42, 26, 17, -33, -1, 16, 12, -29, 6, 4, 21, -27, -9, 39, -6, -54,
+ 40, -14, 15, -4, -17, 20, 4, -18, -4, 23, -24, -3, 30, -41, 15, 17,
+ -4, -29, 19, 4, -9, -10, 12, 17, -21, -7, 26, -19, -17, 17, 3, 1,
+ -3, -30, 47, 16, -62, -4, 68, -29, -54, 43, -1, -4, 20, -42, 22, 34,
+ -32, -43, 63, -12, -26, 8, -6, 10, 22, -66, 55, 25, -65, 15, 9, 21,
+ -22, -28, 36, 5, -16, -51, 102, -49, -12, 6, 21, -12, -23, 24, -15, 11,
+ -14, -8, 31, 4, -53, 64, -35, 13, -28, 23, -23, 22, -16, 13, -22, 23,
+ 27, -51, -8, 41, 6, -66, 36, 13, 4, -26, 7, 11, 9, -34, 0, 35,
+ -21, -15, 10, 34, -57, 60, -69, 60, -22, 1, -27, 27, 14, -27, 1, -13,
+ 35, -2, -51, 36, 35, -49, 5, -1, 31, -42, 25, -26, 34, -7, -60, 98,
+ -46, -22, -1, 49, -45, -2, 10, 26, -33, 25, -36, 37, -19, 4, -3, -7,
+ 9, 7, -8, -29, 48, -23, 0, -33, 45, 0, -23, -16, 47, -7, -31, -9,
+ 38, -2, -36, 18, -8, 43, -55, 16, -1, 41, -72, 54, -35, 24, 4, -46,
+ 47, -11, 6, -40, 24, 10, 8, -38, 16, 16, 24, -98, 80, 2, -28, -28,
+ 44, 11, -47, 31, -7, 35, -42, -25, 41, 12, -64, 34, 14, -2, -21, 24,
+ -14, 11, -3, -24, 22, -28, 46, -51, 38, -22, 35, -40, 2, 11, 22, -48,
+ 23, -9, 34, -35, -24, 52, -7, -37, 9, 36, -21, 0, -32, 61, -44, 6,
+ -1, -16, 41, -28, 19, -37, 49, -11, -38, -8, 65, -53, 9, -21, 59, -37,
+ 8, -33, 59, -13, -80, 67, 19, -39, -28, 70, -21, -25, -3, 23, 17, -29,
+ -44, 83, -41, 0, -23, 53, -27, -12, 21, -19, 21, -21, 13, -4, -12, -5,
+ 38, -58, 34, 10, -22, -16, 47, -8, -39, 19, 12, 4, -46, 39, -24, 48,
+ -69, 45, -18, 10, -5, -2, -4, 10, -5, 7, -17, -3, 20, 0, -40, 26,
+ 40, -64, 11, 34, 1, -49, 11, 35, -22, -14, -32, 98, -47, -37, 9, 76,
+ -70, -8, 7, 63, -92, 56, -49, 77, -64, 2, 41, -28, -25, 37, 0, -26,
+ 35, -40, 16, 3, 14, -46, 22, 18, -6, -9, -11, 22, 26, -44, -46, 94,
+ -60, 18, -37, 69, -33, 5, -20, 42, -32, -20, 24, -1, -10, -12, 39, -31,
+ 13, 1, 9, -47, 42, -26, 39, -73, 48, 48, -73, -13, 56, 14, -78, 38,
+ 11, 12, -50, 8, 39, 3, -79, 73, 2, -25, -17, 23, 27, -58, 26, -37,
+ 67, -49, 11, -12, 62, -82, 64, -41, 3, 26, -17, -45, 55, -4, -22, 10,
+ -2, 38, -54, 8, 5, 47, -79, 7, 54, -7, -64, 41, 49, -73, 29, -24,
+ 54, -51, -4, 14, 33, -84, 82, -46, 17, -25, 57, -44, -2, 11, 8, 15,
+ -66, 46, 19, -25, -44, 58, 10, -38, -23, 77, -48, -3, -12, 24, 24, -70,
+ 37, 21, -15, -48, 81, -66, 44, -29, 6, 4, 9, -30, 31, -24, 5, 19,
+ -51, 34, 21, 11, -92, 78, 19, -44, -54, 104, -47, -8, -19, 29, 45, -78,
+ 6, 55, -11, -75, 66, -10, 8, -38, 24, 10, 4, -57, 66, -20, -25, 20,
+ 6, 9, -71, 100, -60, -6, 8, 28, -37, 29, -42, 78, -58, -22, 42, 10,
+ -69, 34, 33, -36, 29, -54, 81, -54, 0, 7, 1, -19, 22, -14, 4, -3,
+ 32, -13, -59, 86, -54, 4, 0, 21, -35, 43, -68, 91, -31, -53, 38, 48,
+ -72, -15, 50, 3, -11, -72, 96, -1, -49, -23, 81, -21, -57, 15, 63, -67,
+ 5, 25, -27, 34, -48, 49, -26, 12, -33, 66, -73, 14, 35, -20, -27, 45,
+ -24, 12, -12, 0, 24, -50, 33, -26, 45, -65, 47, -7, -4, -9, 19, -19,
+ -2, 15, -17, 30, -39, 25, 2, -3, -57, 109, -86, 10, 14, 31, -53, 7,
+ 32, 5, -44, -20, 84, -35, -34, -6, 99, -97, 1, 23, 40, -65, 15, 9,
+ 36, -45, -22, 55, 4, -55, -3, 73, -80, 63, -49, 28, 2, -10, -19, 24,
+ -13, 8, 1, -15, 5, 22, -4, -57, 72, -41, 16, -45, 76, -57, 30, -26,
+ 38, -16, -34, 32, 12, -53, 22, 47, -46, -4, 6, 45, -65, 32, -21, 45,
+ -44, -22, 69, -44, -16, 29, 19, -59, 40, -7, 42, -77, 39, -4, 29, -74,
+ 27, 38, -12, -60, 69, 7, -32, 1, -9, 50, -56, -15, 19, 47, -75, 44,
+ 5, -22, 27, -7, -22, 0, 23, -30, 1, 4, 33, -44, 29, -24, 57, -67,
+ 17, 18, 4, -59, 32, 48, -72, 28, -2, 13, -10, -21, 16, 58, -117, 85,
+ -14, -5, -34, 21, 29, -27, -20, 31, 23, -49, 16, -14, 51, -74, 24, 38,
+ -38, -16, 56, -33, -7, 3, 0, 36, -80, 49, 23, -19, -48, 76, -61, 43,
+ -41, 27, -11, 23, -30, 8, 3, 15, -14, -22, 16, 3, 15, -39, 11, 38,
+ -13, -70, 88, -41, 2, 4, -30, 80, -84, 15, 37, -6, -61, 58, -19, 27,
+ -72, 64, -6, -16, -30, 59, -21, -21, -12, 44, 22, -101, 78, -10, -16, -11,
+ 20, -21, 31, -36, 37, -18, -20, 46, -24, -23, 10, 21, -36, 32, -38, 68,
+ -50, 12, -6, 19, -33, 14, -16, 20, -11, -14, 47, -59, 56, -14, -27, 5,
+ 29, -43, 49, -96, 106, -35, -41, 28, 35, -30, -29, 37, 12, -11, -58, 79,
+ -31, -16, -11, 43, -13, -25, 3, 71, -76, -13, 64, -39, 3, -45, 66, -13,
+ -1, -45, 80, -40, 6, -29, 26, -12, 6, -19, 21, -4, 9, 0, -37, 44,
+ -28, 11, -22, 19, 7, 1, -45, 60, -13, -42, 32, -16, 31, -50, 35, 10,
+ -22, -23, 60, -62, 21, -2, 39, -49, -4, 24, 30, -53, -23, 66, -33, 2,
+ -34, 69, -33, -10, 7, 24, -51, 28, 0, 9, -24, -3, 38, -24, -16, -9,
+ 68, -81, 38, -16, 35, -34, -4, 16, 20, -43, 10, 7, -3, 14, -30, 38,
+ -39, 38, -20, -12, -20, 78, -79, 22, -4, 44, -48, -6, 37, -2, -25, -24,
+ 60, -41, 15, -30, 50, -43, 7, 9, 27, -64, 45, 5, -15, -17, 1, 49,
+ -56, 3, -11, 69, -78, 37, -5, 38, -60, 26, -2, 9, -51, 53, -20, -3,
+ 9, -1, 38, -74, 40, 6, -13, -54, 69, -24, 6, -22, 31, 0, -17, 12,
+ -13, 8, -9, 20, -53, 56, -27, 29, -63, 41, 8, 11, -73, 59, 15, -25,
+ -21, -1, 61, -69, 10, 17, 28, -59, 34, -14, 32, -54, 17, 22, -11, -47,
+ 63, 7, -56, 46, -28, 50, -96, 60, 2, 0, -37, 36, -11, 15, -38, 41,
+ -19, -31, 46, -12, -25, 9, 49, -67, 47, -48, 51, -30, -15, 23, 19, -43,
+ 8, 17, 4, -11, -29, 54, -48, 38, -28, 10, -9, 38, -48, 27, -47, 55,
+ 3, -59, 22, 41, -5, -59, 38, 5, 31, -101, 72, 11, -36, -18, 54, -25,
+ -1, -30, 54, -28, -34, 61, -27, 13, -46, 55, -21, -10, -21, 52, -34, -8,
+ 30, -21, 20, -11, -21, 22, -2, -46, 79, -84, 60, -9, 13, -57, 51, 2,
+ -16, -38, 34, 15, -23, -7, -6, 53, -38, -22, 29, 23, -63, 65, -34, -21,
+ 34, -7, -19, -8, 24, 13, -8, -63, 110, -56, -8, -37, 79, -56, -3, -3,
+ 62, -57, 19, 9, 8, -20, -29, 27, 13, -28, -19, 79, -80, 58, -31, 24,
+ -16, -35, 46, 0, -52, 36, 21, -29, 16, -23, 26, -29, 38, -42, 26, -41,
+ 60, -29, -16, -4, 42, 7, -85, 53, 47, -54, -29, 67, -53, 39, -58, 45,
+ -5, 5, -37, 61, -56, 27, 17, -40, 1, 15, 17, -43, 19, 4, 30, -49,
+ 12, -1, 49, -64, -27, 96, -41, -47, 45, 8, -38, 35, -50, 74, -81, 54,
+ -14, 24, -64, 57, -5, -25, -19, 27, 16, -27, 4, 16, 2, -25, 26, -31,
+ 22, -35, 56, -54, 0, 55, -23, -29, 9, 38, -38, 12, -41, 74, -28, -29,
+ -3, 61, -71, 36, -32, 43, -19, -14, 21, 0, -10, -19, 32, -42, 20, 11,
+ 23, -94, 107, -13, -53, 5, 35, -17, -11, -25, 32, 40, -76, 29, 32, -9,
+ -65, 80, -42, 6, -22, 42, -27, -2, 10, -2, 13, -41, 32, 10, -17, -26,
+ 53, -50, 40, -42, 30, -19, 41, -50, 33, -20, -1, 40, -67, 8, 29, 15,
+ -58, 25, 32, 15, -81, 46, 14, -8, -51, 24, 40, -44, 17, 10, 2, -26,
+ 47, -68, 49, -49, 50, -27, -3, -20, 84, -62, -32, 52, 12, -52, 0, 42,
+ -30, 24, -47, 45, -16, 11, -51, 74, -47, -9, 45, -19, -18, -5, 41, -39,
+ 11, -33, 56, -20, -14, -8, 64, -85, 60, -23, -13, -3, 33, -20, -25, 57,
+ -34, 2, -23, 42, -21, 3, -49, 85, -35, -27, 1, 54, -34, -31, 24, 15,
+ 6, -45, 54, -30, 12, -27, 40, -61, 39, 1, -5, -18, 17, 14, 7, -33,
+ -27, 83, -44, -40, 21, 66, -82, 32, -7, 33, -54, 27, 3, 2, -13, -15,
+ 52, -57, 14, 14, -6, -27, 54, -45, 23, -11, 16, -27, 27, -33, -3, 36,
+ -46, 47, -15, -8, -7, 67, -93, 12, 34, 17, -73, 32, 15, 29, -44, -17,
+ 47, 2, -40, -31, 81, -43, 3, -24, 52, -32, 4, 1, 20, -48, 20, 40,
+ -68, 23, 14, 19, -64, 46, -8, 17, -48, 55, -29, 23, -59, 48, -2, -27,
+ 11, 1, 21, -30, 25, -24, 29, -41, 21, 0, -15, -17, 64, -47, 1, 31,
+ -22, 2, -11, 22, -56, 69, -53, 32, -30, 31, -16, 32, -68, 29, 42, -39,
+ -49, 80, 17, -74, 17, 0, 55, -88, 25, 29, 14, -72, 56, 0, 0, -33,
+ 20, 5, -34, 35, -33, 45, -37, 23, -9, 10, -54, 67, -22, -13, -15, 41,
+ -14, -16, 8, 0, 19, -51, 56, -51, 39, -20, 19, -34, 26, -18, 19, -31,
+ 23, 0, 12, -31, 7, 45, -65, 22, 4, 24, -73, 74, -13, -34, 18, 23,
+ -16, -25, -2, 40, 5, -84, 76, -4, 6, -74, 75, -7, -10, -51, 60, -13,
+ 0, -45, 50, 18, -57, 20, 21, -7, -26, 47, -51, 28, -19, 12, -13, 3,
+ -1, 20, -23, 1, 28, -18, 3, -41, 67, -72, 34, -11, 33, -47, 47, -9,
+ -20, -2, 28, -21, -27, 11, 26, -15, -25, 57, -44, 46, -67, 49, -5, -30,
+ 1, 42, -36, -9, 22, 7, -13, -34, 67, -29, -16, -26, 84, -49, -21, -11,
+ 77, -53, -43, 62, 0, -3, -32, 23, 13, -5, -69, 88, -42, 7, -17, 37,
+ -35, 27, -6, -13, -11, 31, -17, -28, 45, -17, 8, -32, 41, -48, 39, -35,
+ 41, -16, -28, 41, -3, -13, -26, 23, 12, -22, -50, 104, -57, 9, -28, 67,
+ -53, -7, 0, 45, -41, -22, 50, -8, -21, -9, 38, -19, -18, -2, 55, -76,
+ 38, -12, 39, -49, -14, 64, -24, -45, 25, 50, -66, 23, -15, 32, -36, 32,
+ -46, 44, -14, 2, -16, 22, -7, -11, 14, -28, 21, 4, -10, -18, 63, -66,
+ 30, -20, 36, -35, -16, 26, 12, -37, 6, 50, -35, -15, 6, 48, -64, 4,
+ 12, 46, -85, 33, 12, 25, -49, -11, 77, -53, -18, 19, 29, -41, -1, 3,
+ 39, -70, 55, -6, -1, -23, 38, -22, -12, 1, -11, 36, -39, 5, 15, 33,
+ -55, 32, -8, 6, -37, 39, -32, 4, 27, -23, 11, -1, 10, -28, 19, -24,
+ 52, -69, 27, 21, 11, -72, 52, 17, -35, -13, 16, 33, -44, 4, 19, 18,
+ -60, 13, 35, 12, -93, 82, 9, -35, -20, 26, 40, -74, 14, 18, 28, -66,
+ 37, 4, 9, -43, 34, -15, 17, -35, 38, -11, -14, 14, -5, 2, -36, 54,
+ -35, 2, 1, 29, -35, 9, -4, 24, -32, -5, 31, -19, -17, 28, 34, -86,
+ 49, 13, -16, -52, 71, -29, 3, -30, 51, -1, -36, 6, 25, 4, -75, 56,
+ 10, -21, -18, 37, -16, 17, -53, 60, -7, -38, -9, 63, -18, -70, 67, 1,
+ -19, -32, 50, -20, 11, -23, 24, -10, -3, -21, 32, -26, 7, 12, -19, 35,
+ -29, 26, -41, 32, -22, 14, -43, 41, 7, -16, -24, 57, -20, -35, 25, 7,
+ -11, -20, 31, -18, 10, -34, 44, -7, -22, -9, 49, -33, -18, 26, -4, 12,
+ -63, 51, 11, -16, -40, 80, -28, -37, 5, 61, -78, 22, 16, -3, -10, -5,
+ 26, -8, -2, -43, 68, -42, -24, 39, 11, -31, 15, -9, 18, -20, -1, 7,
+ -17, 26, -30, 31, -31, 42, -28, -1, -15, 49, -51, -2, 26, 3, -12, -11,
+ 7, 22, -9, -51, 70, -27, -14, -13, 53, -37, -12, 9, 44, -57, -14, 51,
+ -6, -27, -10, 60, -55, 2, 14, 18, -45, 32, -19, 29, -27, -12, 31, 14,
+ -54, 17, 41, -62, 51, -40, 40, -40, 12, -8, 28, -39, 16, 10, 10, -46,
+ 37, 12, -42, 17, -4, 2, -17, 35, -34, 38, -30, 21, -6, -36, 36, 13,
+ -56, 14, 53, -36, -13, -1, 61, -64, 7, -3, 54, -63, 5, 14, 34, -67,
+ 10, 46, -27, -18, 26, 20, -41, 14, -13, 40, -66, 20, 38, -34, -11, 39,
+ -16, 11, -26, 7, 28, -58, 26, 0, 30, -61, 44, 11, -30, -17, 66, -40,
+ -33, 35, 6, -21, -2, 9, 16, -13, -39, 79, -71, 27, 9, -9, -29, 28,
+ 4, -17, 1, 14, 2, -20, -2, 16, 24, -67, 20, 37, -4, -80, 75, 18,
+ -46, 2, 10, 25, -31, -28, 43, 19, -75, 59, -13, 14, -40, 29, 7, -22,
+ -20, 44, -20, -16, 10, 32, -21, -42, 61, -19, -29, 12, 39, -55, 32, -4,
+ 0, -2, -24, 40, -19, -38, 34, 22, -33, 11, -3, 31, -49, 21, -16, 40,
+ -54, 12, 29, -19, -8, 17, 17, -52, 28, 22, -39, -2, 45, -42, 23, -46,
+ 51, 11, -68, 26, 55, -34, -44, 45, 9, -19, -43, 57, -16, -5, -9, 40,
+ -24, -12, 8, 29, -54, -4, 50, -37, 0, 11, 7, -4, 0, -25, 57, -62,
+ 19, 18, -7, -22, 12, 19, -27, 9, -5, 15, -19, 2, 15, 4, -45, 36,
+ -5, 8, -48, 60, -13, -35, 36, -19, 21, -24, -7, 23, -24, -22, 73, -58,
+ -5, 34, 25, -71, 19, 30, 0, -43, -4, 50, -9, -21, -21, 69, -28, -46,
+ 24, 29, -45, 12, 3, 21, -13, -28, 47, -9, -37, 21, 22, -46, 21, 8,
+ -1, -32, 42, -22, 14, -27, 19, 16, -29, 3, 17, -1, -39, 28, 21, -42,
+ 8, 47, -45, 2, -16, 50, -20, -54, 50, 9, -25, -12, 41, -29, 8, -3,
+ -5, -13, 25, -16, 19, -30, 15, 15, -2, -52, 38, 38, -69, 12, 37, 9,
+ -54, 10, 36, 5, -79, 27, 57, -35, -40, 48, 21, -41, 13, -3, 10, -29,
+ 4, 18, 4, -50, 52, 1, -28, -6, 41, -25, -22, 34, -22, 10, -5, 3,
+ -6, -1, 2, 26, -48, 24, 12, 5, -54, 36, 18, -32, -6, -3, 48, -28,
+ -21, 22, 35, -63, 6, 43, -28, -27, 42, -7, -22, 6, 21, 8, -56, 31,
+ 23, -10, -73, 76, 18, -49, -26, 70, -21, -23, -8, 35, 0, -42, 7, 42,
+ -26, -28, 47, -31, 0, 13, 11, -25, 14, -6, 10, -13, -26, 40, -14, -5,
+ -8, 42, -36, 1, 15, -10, -34, 47, -24, 5, -22, 38, 14, -39, -10, 53,
+ -26, -67, 72, 0, -15, -25, 29, 19, -29, -25, 50, -14, -31, 10, 42, -44,
+ -24, 81, -40, -32, 12, 45, -41, -5, -1, 47, -27, -54, 54, 32, -64, 4,
+ 26, 1, -1, -41, 44, 4, -22, -22, 47, -30, 7, 5, 3, -37, 45, 1,
+ -53, 44, -1, -20, 7, 12, -13, 9, -23, 26, -2, -47, 32, 37, -61, 6,
+ 42, 0, -25, -43, 76, -23, -38, -10, 73, -24, -57, 47, 45, -70, 3, 19,
+ 7, -19, -8, 10, 24, -12, -36, 66, -60, -1, 50, -32, -19, 8, 26, 2,
+ -44, 11, 53, -42, -26, 20, 42, -52, 14, 16, -26, -11, 42, -41, 16, 16,
+ -23, 13, 1, -6, 17, -18, -41, 71, -39, -23, 40, 13, -30, 2, 19, 0,
+ -39, 10, 24, -15, -25, 12, 66, -81, 6, 47, 9, -69, 12, 47, -9, -36,
+ -27, 76, 9, -107, 58, 53, -68, 19, -10, 39, -49, 8, 14, -11, -17, 21,
+ 18, -25, -17, 47, -4, -48, 32, -9, -4, -3, 8, -5, 29, -40, 13, 14,
+ -31, 24, 7, -48, 27, 37, -61, 22, 15, 7, -46, 17, 10, 22, -45, -9,
+ 56, 1, -73, 43, 34, -51, -15, 40, 2, -47, 35, 8, 27, -87, 31, 86,
+ -94, -27, 67, 10, -44, -15, 43, 11, -46, 6, 9, 33, -71, 35, 26, -30,
+ -18, 37, -18, -9, 20, -15, 1, 5, 9, -2, -23, -11, 50, -42, -3, 24,
+ 6, -21, 17, -5, -8, 11, -26, 24, -19, -9, 33, 22, -78, 38, 44, -48,
+ -53, 80, 6, -66, 14, 36, 8, -37, -15, 66, -24, -75, 87, -14, -27, -10,
+ 45, -12, -38, 13, 33, 7, -67, 20, 75, -55, -67, 85, 8, -52, -11, 45,
+ -10, 13, -34, 12, 26, -36, 7, -1, -1, -7, 23, -27, 18, 15, -12, -28,
+ 27, -6, 9, -52, 40, 26, -50, 3, 51, -10, -71, 67, 10, -59, 4, 56,
+ -27, -20, -19, 58, 6, -81, 38, 49, -39, -39, 47, 14, -25, -40, 54, -2,
+ -20, -38, 82, -25, -51, 44, 24, -60, 8, 51, -47, -2, 6, 22, 9, -34,
+ -20, 78, -56, -25, 36, 19, -49, 17, 32, -50, 44, -29, 4, -11, 14, 3,
+ -13, -11, 19, 13, -24, 28, -32, 33, -37, 39, -61, 119, -76, 120, -70, 99,
+ -122, 89, -113, 91, -123, 122, -123, 77, 86, -116, 6, -118, 123, -23, 64, -93,
+ 17, 24, -125, 124, -125, 124, -24, -12, 56, 87, -54, 38, -91, 64, -2, -41,
+ 126, -127, 20, 8, -48, -62, 127, -128, 88, -43, -18, 86, -100, 44, -32, -26,
+ 71, -13, 6, 51, -33, -50, 106, -59, 33, 5, -20, 69, -56, 54, -48, -6,
+ 38, -5, -38, 35, -1, 12, -1, 4, 23, -56, 19, -7, 5, -4, 31, -38,
+ 3, -12, -9, -25, -7, 24, -32, 17, -21, -22, 24, -20, 6, -18, 0, -15,
+ 5, -16, 15, 3, 2, -10, 3, 27, -31, 37, -12, 32, -5, 2, -21, 27,
+ -14, 20, -8, 5, 15, -7, -11, 20, -37, 7, -23, 17, -22, 11, -14, 8,
+ -44, 39, -52, 26, 3, 14, -10, 51, -45, 29, -19, 19, -3, 41, -21, 46,
+ -23, 10, 16, -25, 3, 7, -30, 19, -9, -5, -1, 1, -19, 1, -24, -23,
+ 51, -48, -10, 17, -34, -38, 60, -71, 26, -43, 65, -59, 70, -26, 61, -51,
+ 63, -51, 42, -25, 58, -36, 31, 10, -14, -9, 8, -18, 8, 4, 8, 7,
+ 31, -52, 39, -53, 53, -56, 24, 11, 1, -20, -8, -32, -18, -10, -25, 4,
+ 1, 37, -37, 42, -42, 53, -57, 52, -18, 30, 11, 20, -52, 55, -61, 56,
+ -50, 24, -26, 38, -42, 36, -1, -43, 58, -46, 6, 18, -35, 31, -36, 28,
+ -55, 55, -98, 52, -41, 26, -24, 48, -31, 48, -26, 30, 19, -17, 23, -8,
+ 13, 15, 19, -7, -23, 41, -36, 20, -39, 65, -64, 66, -38, -9, 7, -14,
+ -10, -3, 6, 15, -19, -40, 53, -67, -11, -12, -25, 23, -11, -12, 46, -48,
+ 39, -20, 20, -14, 31, -54, 71, -25, 2, -8, -5, -9, 1, 7, 27, 17,
+ -14, 43, -31, 27, 11, -33, 20, -2, -33, 45, -38, 17, -9, -11, -17, -22,
+ -19, 20, -25, 4, 29, -35, 14, -17, 1, -7, 19, 2, 16, 32, -3, -17,
+ 4, 0, -9, 17, 5, -8, 52, -32, 40, -39, -5, -18, 14, -21, 31, 10,
+ -17, 8, -34, -7, 1, -44, 7, 10, -8, -6, -18, -25, -1, -19, 16, -29,
+ 62, 6, 9, 21, 0, -14, 4, 5, 20, 13, 27, -1, 18, -5, 21, -31,
+ 11, 2, -9, -4, 21, -27, 8, -21, -28, -19, 14, -12, 5, -20, 20, -36,
+ 4, -18, -27, -4, -4, 15, 4, 48, -7, -11, 20, -6, 7, 20, 1, 20,
+ 0, 35, -35, 28, -37, 7, -43, 21, -22, 23, -18, 12, -22, -13, -20, -11,
+ 7, 23, -10, 19, -18, 17, -41, 4, -16, -8, 21, 11, -4, 10, 30, -24,
+ 32, -15, 15, -13, 28, -5, 38, -10, 0, -22, -13, -12, 24, -18, 30, -7,
+ 4, -16, 27, -28, -3, -1, 18, -14, 31, -24, -3, -13, -19, -36, -2, -31,
+ 9, -2, -12, 17, 12, -50, 46, -49, 43, -15, 13, 22, 15, -25, 10, -8,
+ -6, 14, -2, 24, 15, 9, 17, -13, 5, 14, -15, 7, 20, 4, 4, 18,
+ -16, 3, -47, 31, -46, 19, -24, 5, -19, -1, -42, 14, -44, 18, -7, -1,
+ 15, 9, -35, 32, -44, 39, -46, 23, -16, 36, -25, 45, -34, 32, -8, 10,
+ 5, 28, 0, 12, 11, 3, 20, -23, 6, -8, 16, 7, 17, -19, 32, -44,
+ 3, -8, -21, -8, -5, 2, -29, 2, -3, -19, -14, 3, 7, -23, 10, 1,
+ 3, 8, 13, -44, 20, 21, -16, 23, 3, 5, 10, -11, 32, -11, 13, -7,
+ 30, 4, 16, -7, -6, -7, 14, -40, 4, -16, -26, 3, -1, 0, -6, 5,
+ -50, 37, -27, 18, -16, -14, 6, -1, -4, -15, 8, -12, 14, 9, -22, 42,
+ -10, 23, -11, 36, -15, 13, 30, 1, 47, -20, 33, -14, -12, 1, -20, -9,
+ -9, -11, -13, 7, -37, 25, -47, 14, -13, 4, -12, 9, -32, 18, -48, -1,
+ -35, -1, -7, 35, -20, 53, -4, 34, -7, 13, 19, 9, 30, 6, 45, -22,
+ 23, -18, -6, -1, 3, -30, 14, -15, 9, -39, 10, -33, -13, -24, 10, 14,
+ 14, -10, 2, -34, -4, -20, -21, -14, 40, -10, 17, -14, 28, -17, 37, -26,
+ 69, -15, 38, 2, 21, -25, 37, -61, 13, -9, 5, -17, 18, -41, 22, -57,
+ -1, -9, -13, 24, -10, 38, -5, 8, -16, -2, 1, 12, -25, -2, -13, 2,
+ 2, -16, -19, 32, -30, 22, 20, -4, 12, 11, -17, 19, -17, -3, 20, -33,
+ 65, -27, 32, -14, 8, -8, 13, -19, 9, -2, 7, 33, -40, 18, -18, -18,
+ 6, -23, -11, -11, -28, 4, -11, -15, -14, -8, -5, 34, -6, 19, 1, -3,
+ 9, -1, 5, 5, 14, -11, 40, -3, 18, -20, 16, -7, 2, -5, 9, -16,
+ 9, -17, 0, -17, 4, -17, -3, 3, 8, -14, -19, 12, -21, -7, 1, -2,
+ -8, 16, 3, -6, 35, -23, 33, -13, 11, 12, 3, -7, 26, -11, 19, -18,
+ 23, -22, 39, -49, 39, -50, 11, -38, 26, -29, 10, -6, -22, 15, -8, 15,
+ -37, 36, -43, 39, -43, 18, -26, 1, 11, 4, -2, 9, 7, 2, 7, 19,
+ 1, 1, -4, 16, -5, 16, -9, -3, 4, -4, -1, -17, 0, 11, 16, -27,
+ 12, -15, 15, -3, 0, 10, -3, -5, 12, -13, -7, -13, -31, -1, -3, -17,
+ 15, -31, 25, -10, 15, -1, 2, 4, 10, 7, 32, -13, 7, -22, 2, -10,
+ 16, 1, -15, 19, -24, 16, -18, -12, 18, -9, 9, 24, -8, 8, 11, 0,
+ -31, 17, -55, 21, -43, 40, -40, 29, -54, 44, -34, 22, 11, 16, 7, 19,
+ 21, -6, 2, -7, -16, 22, 0, -1, -4, 5, -8, 26, -42, 4, -6, -21,
+ 35, -16, 8, 0, -22, -13, 11, -31, 7, -28, 4, 17, -12, -18, -2, -23,
+ 23, -1, 19, 34, 7, 7, 35, -19, 11, -8, -17, 8, 4, 16, -16, -13,
+ 9, -15, -5, -1, -6, 7, 3, 11, 1, -7, -24, 21, -31, 36, -3, -10,
+ 8, 2, -17, 12, -24, 6, -3, 9, 15, 3, 13, -8, -13, -3, 6, -19,
+ 14, -33, 16, -17, -5, -31, 3, -29, 24, -7, -6, 35, -20, -5, 34, -20,
+ 25, -3, 10, 25, 8, 14, -13, 0, 1, 17, -33, 51, -38, 45, -32, 39,
+ -3, -2, -24, 3, -18, 14, -4, -44, 2, -25, -15, -2, -23, 3, -2, -2,
+ 20, -14, 8, -10, -4, 21, 11, -13, 32, -4, 8, 19, -16, -2, -2, -2,
+ 14, -2, -1, 27, -26, 20, 11, -13, 10, -3, -7, 12, -13, -3, -30, -16,
+ 10, -26, -3, -10, -2, -9, 15, -17, 1, -2, -7, 14, -8, 12, -3, -1,
+ 2, 47, -26, 22, -19, 16, 2, 13, -3, 21, -10, 22, -32, 43, -24, 16,
+ 0, 5, -2, 12, -44, -12, 1, -26, 1, -36, 5, 2, 9, -17, 20, -37,
+ 14, -9, -5, 6, -3, -13, 23, -19, 25, -33, 6, 17, 10, 19, 15, -4,
+ 12, 5, -9, 33, -20, 26, -9, 11, -2, 11, -21, -7, -13, -4, -8, -12,
+ 0, -10, -9, 8, -33, 9, -26, 8, 6, -8, 12, 7, -8, 0, 7, -16,
+ 25, -8, 27, 12, 0, 9, -9, 4, -17, 14, -16, 11, -8, 18, -2, 4,
+ 2, -20, -18, 22, -16, -5, 3, -24, 13, -10, -12, -10, 2, -16, 33, -15,
+ 21, -15, -4, -19, 29, -22, 18, 2, 20, 12, 18, -22, -7, -16, 7, -19,
+ 14, 1, -17, 33, -22, 38, -8, 3, -3, 21, -17, 51, -43, 15, -22, -23,
+ -6, -12, -14, 14, 9, 6, 4, -31, 3, -16, -14, 22, -22, 5, 13, -25,
+ 17, -2, -18, 7, 1, 5, 36, -16, 23, 4, -15, 29, -20, 10, 1, 24,
+ 17, 16, -4, -16, -37, -11, 1, -33, 27, -36, 17, -22, 2, -33, 16, -29,
+ 32, -7, 24, -12, 14, -12, 22, -16, 15, -20, 19, 9, 14, 12, -1, -24,
+ 13, -6, -1, 32, -19, 24, 12, -26, 4, -31, -38, 18, -16, -13, 3, -14,
+ -1, 11, -15, 15, 0, -2, 30, -6, 35, -23, 10, -35, 5, -14, 17, -21,
+ 20, 4, 7, 8, -5, -15, 20, -25, 26, 6, -3, 3, 5, -24, 26, -35,
+ 4, 0, -6, 13, -23, 8, -25, 1, -2, 9, 3, 17, 4, 0, 13, -15,
+ 3, -21, -16, 4, -5, -10, 11, -2, 7, 23, -22, 25, -19, 18, 25, -9,
+ 14, -21, -7, 11, -24, 22, -12, -7, 6, 9, -33, 11, -20, 2, -9, 2,
+ 3, -13, 12, -15, 23, -21, 16, -16, -2, 8, 13, -12, 18, -10, 16, -12,
+ 20, -18, 18, -1, 21, -21, 20, -30, -6, 10, -2, 13, -6, -15, 6, 2,
+ -1, 1, -19, 9, -15, -3, -11, 0, -5, 1, 5, 1, -4, -8, 1, -16,
+ 23, 0, -23, 2, 8, -6, 38, -4, 2, 13, -17, 31, -4, -8, 22, -14,
+ 0, 12, -22, 7, -7, 11, 4, -4, -12, -9, -22, 2, -17, -17, -11, 7,
+ -17, 19, -24, 9, -8, -6, 29, -4, 10, 4, 4, 23, -1, 9, -6, -12,
+ 23, 16, -6, 33, -29, 12, -7, -10, 17, -4, -18, 21, 0, -14, -2, -20,
+ -21, 10, -28, 5, -18, -4, 0, -11, 1, 5, -17, 3, 9, 20, 6, 1,
+ -7, 2, -7, 3, 9, -22, 29, 6, -1, 25, -10, 6, -1, 4, 12, 18,
+ -13, 28, -11, 6, -15, -14, -22, -7, 5, -14, 1, -16, -12, -5, 5, -9,
+ 4, -1, -14, 21, -10, -5, 0, -17, -7, 2, -10, 6, 11, 1, 37, -17,
+ 6, 21, -24, 41, 2, 23, 0, 10, -18, 16, -26, 14, -21, -19, 18, -9,
+ -14, -1, -9, -14, -3, -7, -10, 7, -7, 19, -11, 15, -25, -3, -6, 2,
+ 8, -10, 4, 12, -3, 11, -2, -2, 5, 31, -9, 39, -21, 14, -23, 18,
+ -16, -1, -3, -6, 0, 22, -9, -5, -17, -4, -12, 2, -3, -7, 10, -10,
+ 7, -20, -19, -10, 0, -14, 32, -15, -18, 13, -9, 2, 17, -14, 6, 36,
+ -9, 28, 1, 0, 17, -10, 5, 17, -8, 12, -2, 3, 2, -22, -6, -14,
+ 6, 8, -11, -14, 2, -23, 25, -35, 3, -18, 1, -14, 22, -1, -12, -7,
+ -9, 13, -4, 12, 4, -3, 18, 0, 1, 8, -14, 14, -2, 1, 17, -3,
+ -14, 35, -17, 19, -14, -6, 1, -9, 18, -17, -4, -13, -2, -14, 10, -10,
+ -6, 0, 3, 5, -12, -13, -3, -6, -6, 11, -13, -7, 13, -2, 6, 13,
+ -7, 11, -5, 23, 1, 29, -17, 23, -10, 18, -16, 12, -20, 10, 7, -9,
+ -5, -21, -9, 5, -13, -2, 0, -15, -11, 3, 0, -18, 5, -25, -2, 3,
+ -2, -3, 4, 8, 14, -7, 15, 4, 8, 19, 9, 11, 7, -3, 14, -11,
+ 1, 15, -35, 3, 3, -10, -16, 0, -15, 2, 3, -12, 27, -23, 32, -15,
+ 10, -14, 3, -27, 10, -15, 12, -24, 7, 2, 9, -2, -2, -1, 3, 1,
+ 1, 8, -4, 0, 6, -6, 1, 1, -1, 8, -11, 31, -27, 13, 4, -3,
+ 5, -1, 0, 2, 9, 0, 12, -31, 4, -27, 1, -25, 20, -21, -14, 12,
+ -14, 0, -5, -23, 18, -1, 15, 19, -5, 20, -8, 14, -7, 16, 3, 0,
+ 8, 10, 0, -8, -10, 3, -8, 9, -12, 4, 15, -6, 2, -12, -29, -3,
+ -16, -11, 35, -18, -1, -28, 7, -12, 0, 7, -5, 22, 10, 10, -4, 6,
+ -13, 21, -23, 20, 8, -13, 11, 15, -6, -6, -22, -1, 3, 14, 7, 11,
+ -27, 12, -17, -12, 8, -15, 3, -8, 12, -12, 5, -30, 12, -18, 9, -2,
+ 3, 4, 15, 1, 5, -9, 0, -8, 24, -2, 21, 5, -4, -4, 14, -15,
+ 0, -1, 3, 17, -5, 13, -19, -10, -4, -6, -4, -7, 18, -27, 8, 1,
+ -12, -21, -13, 1, -9, 11, 1, -3, -1, 22, -21, 9, 6, -3, 20, -2,
+ 17, 7, -12, 1, 4, 4, -9, 9, -20, 24, 7, -9, -3, -7, -6, 10,
+ 7, 3, 9, -2, -3, -4, 1, -19, -8, -16, 0, -12, 0, -25, 4, -22,
+ 10, -9, 0, -3, 15, -1, 8, 11, -15, 10, 13, 1, 22, -5, 15, 1,
+ 24, 6, 0, -6, 5, 5, 10, 8, -1, -11, -14, 3, -31, 2, -22, -4,
+ -8, -15, -2, -31, -12, 6, -7, 5, 2, 3, -4, 19, 3, 4, 7, 7,
+ -8, 31, -6, 26, 1, -2, 2, -3, -10, -4, -4, 9, 3, 12, -16, 16,
+ -9, -1, 5, 4, -7, 13, -17, 0, -11, -13, -22, 1, -9, 4, -7, 7,
+ -10, 5, -1, -6, -3, -21, 7, -10, 18, -3, 1, -7, -11, 11, -8, 12,
+ 20, 3, 13, 16, -1, 3, 13, -3, 23, 16, -3, 15, -14, 12, -6, -8,
+ -28, 0, -33, 4, -11, -12, -13, -21, -17, -16, -5, -12, 16, -7, 15, -6,
+ -5, 3, -9, 21, 17, 13, 14, 11, 21, -12, 31, -18, 7, 12, 8, 9,
+ 7, 1, -3, -7, -14, 17, -35, -10, -2, -18, -8, -10, -20, -22, 2, -10,
+ -3, 1, -1, 4, -5, 11, -20, 11, -6, 27, 7, 18, 8, -1, 2, 3,
+ 11, -9, 5, 5, -7, 29, -6, 20, -21, 23, -15, 19, -19, 2, -22, 11,
+ -26, -7, -10, -30, -1, -3, -6, 15, -22, 16, -7, -9, -2, -7, -5, 11,
+ 17, -13, 2, 8, -5, 6, 27, -6, 12, -6, 4, 15, 3, 14, -3, -12,
+ 11, -2, 6, 5, 4, -6, -12, 0, -32, 2, -22, 22, -12, -5, -7, -11,
+ -7, 6, -1, -3, -3, -16, 2, -1, 0, 0, -7, -2, 1, 12, -4, 5,
+ 20, 1, 16, -2, 14, -1, 19, 8, 29, -8, 7, -14, -2, 3, -13, 8,
+ -40, 22, -18, 2, -14, -8, -11, -8, 12, -21, -1, -10, -12, -6, -4, -14,
+ 6, -19, 7, 14, 1, 11, 11, -11, 25, 1, 14, -5, 31, 0, 22, 4,
+ 1, 3, 6, -3, 4, -2, -20, -7, -26, 1, -12, -7, -10, 2, -1, -5,
+ -7, -8, -10, 6, -7, -6, 10, -17, 6, 3, 15, -8, 15, -7, 12, 1,
+ 9, -4, -2, 10, 9, -1, 10, -4, 9, -8, 17, 0, -13, -7, -2, -11,
+ 3, -2, -15, -4, -11, -5, -9, 1, 8, -10, 8, -8, -6, -18, 21, -19,
+ 26, -19, -1, -11, 10, 4, 12, -10, 16, -10, 17, 8, 13, -1, 17, 1,
+ 5, -1, 11, -8, 9, 16, -17, 3, -26, -17, -14, 6, -17, 4, -20, 0,
+ -1, -6, -4, 2, -15, 13, -3, -1, 0, -2, -8, 11, 7, -3, -8, 5,
+ 14, -1, 28, -19, 13, -4, 8, 1, 11, 7, 6, -8, -2, -13, -10, -22,
+ 6, 11, -1, -1, -5, -13, 18, 3, -10, 9, -17, -8, 9, -9, 1, -17,
+ -4, -16, 18, -6, 15, -10, 17, 5, 0, -5, 0, -11, 12, 15, 4, 8,
+ 5, -4, 0, -2, 3, -17, -2, -1, 11, -6, -7, 2, -33, 23, -6, -1,
+ -2, -2, -1, -8, 3, -29, -2, -34, 16, -3, 16, 1, 10, -12, 23, 0,
+ -3, 16, 12, 19, 23, -1, 8, -26, 16, -32, 26, -13, 2, -11, 5, -1,
+ -15, -9, -16, 7, -6, 14, -15, 5, -10, -7, -9, -9, 6, -17, 13, 18,
+ -5, -3, -4, -4, -18, 28, -6, 13, 17, 24, -2, 9, -14, 1, -11, 7,
+ 17, 1, -15, 10, -23, -4, -12, 5, -20, 17, -10, 6, 0, -9, 4, -8,
+ -15, 6, -16, 7, 9, 3, 6, -12, -17, 0, 4, 13, 22, -4, 10, -8,
+ 7, -12, 5, 5, 1, 11, 2, 10, -3, -2, 3, -10, -5, -7, -4, -18,
+ 17, -2, -14, -16, -7, -10, -3, 6, -1, 14, -11, 15, -18, 2, -6, 0,
+ -1, 0, 20, -17, 1, 6, 2, 6, 12, -3, 7, 25, -5, 17, -14, 0,
+ -6, 0, -2, -5, -1, -10, 8, 2, -9, -19, -7, -17, 5, 3, -7, 4,
+ -15, -5, 9, -12, -1, -5, 3, -5, 26, -2, 3, -4, 5, 3, 7, 10,
+ 5, 6, 6, 26, -17, 0, -1, 3, -3, 10, -7, -7, -9, 11, -18, 0,
+ -16, -6, -5, 3, 7, -14, -14, 0, -21, 14, -8, -1, -12, 2, 1, 2,
+ -3, -1, -3, 18, 5, 5, 9, 12, 7, 18, 8, 5, -25, 16, -15, 16,
+ -7, 9, -22, 1, 14, -13, -5, 2, -6, -8, 13, -17, 6, -16, 1, -5,
+ -14, -6, -6, -15, -2, 9, -9, -18, 15, -19, 12, 7, 4, 8, 14, 15,
+ 6, 10, -3, 9, -7, 23, -17, 21, -20, 7, 0, -9, 8, -10, 1, 4,
+ 2, 3, -9, -9, -15, -6, -21, -16, -6, 0, -11, 19, -8, -9, 5, -6,
+ 0, 5, 14, 7, 1, 12, 8, 7, -5, 12, 8, -4, 19, 4, -7, 2,
+ 3, -12, -8, -1, 0, 5, 7, -5, -8, -22, -8, -21, -2, -9, 10, -20,
+ 13, -6, 8, -17, -9, -6, 2, 5, 8, 6, -3, 10, -9, -2, 15, -6,
+ 20, 7, 11, 10, -3, -4, -8, 25, -25, 18, -12, 17, -6, 20, -22, -1,
+ -17, -10, 5, -10, 9, -13, -9, -6, 10, -25, -5, -2, -5, 13, 2, -5,
+ -8, -10, 11, -27, 10, -4, 11, 0, 33, -4, 10, -14, 1, 12, -2, 27,
+ -8, 6, 11, 9, -12, -4, -10, -13, 12, 5, 1, -10, -14, -15, -8, -7,
+ -9, 3, -5, 10, 3, -11, -12, -13, -3, -3, 3, 2, 9, 17, -6, 25,
+ -3, -3, -8, 19, 3, 30, -10, 12, -22, 7, -5, -10, -3, 21, -8, 12,
+ 6, -5, -13, -13, -9, -9, -1, -23, 13, -17, 15, -22, -11, -18, 8, -14,
+ 20, 1, 4, -5, 3, 3, 5, 11, 1, 2, 27, 1, 10, -7, -8, -2,
+ -2, 7, -1, 17, -5, 24, -7, 5, -10, -20, -6, 5, -4, -5, -1, -18,
+ -5, -14, -1, -20, 1, 7, -7, 12, -4, -2, -4, 2, 8, 0, 7, 1,
+ 6, -2, 18, -5, -7, 4, 3, -2, 13, 4, 0, 2, -3, 2, -10, -6,
+ 1, -6, 6, -7, -3, -21, -2, -12, 5, -1, -9, 7, -3, 13, 5, 5,
+ -8, 0, -8, 19, -5, 13, 13, -7, 3, 0, -10, 0, -8, 20, -8, 13,
+ -20, -5, -7, 3, 5, -7, 2, -5, -4, -14, 11, -23, -13, 2, -1, 12,
+ 13, 5, -6, 23, -9, 9, -6, -9, 18, -13, 16, -3, -7, -17, 3, -13,
+ 12, -9, 4, 0, 0, 13, -18, -1, 3, -13, 20, -5, 1, -20, 15, -23,
+ 18, -4, -8, 5, -7, 16, 4, 6, -3, 7, -21, 19, -17, -7, 9, 5,
+ 3, -5, -3, -16, -9, 25, -9, 12, -5, 10, -5, 9, -4, -6, -3, 4,
+ 10, -2, 11, -12, -2, -14, 8, -23, -5, 0, -8, 9, -2, -11, -3, -9,
+ 9, 2, 2, 4, -5, 7, 11, -16, 0, -6, 7, 6, 25, 5, 6, -4,
+ 3, 4, 3, 2, -8, -3, 5, -1, -11, -4, -9, -3, -15, 10, -12, -5,
+ 11, -4, -7, 6, -29, -5, 6, 11, 3, 9, -18, 13, -14, 19, -1, -2,
+ 4, 5, 12, 1, 5, -8, 3, 1, 20, -6, 2, 3, -16, 10, -10, -18,
+ -11, -7, -7, 9, -4, -8, 9, -15, 13, -13, -3, -7, 3, 8, 11, -6,
+ -16, 1, -8, 20, 4, 15, -5, -3, 11, -5, 6, 0, -5, 10, 13, 0,
+ -6, -11, 0, 11, -11, 10, -7, -8, 1, 16, -9, 2, -22, -9, 0, 4,
+ 5, -12, -22, 2, -8, -8, 14, -16, 0, 13, 0, 9, -7, 2, -1, 7,
+ 8, -3, -3, 2, 15, 5, 10, -7, 12, -4, 22, -4, -3, -12, -2, -15,
+ 8, -2, -22, 7, -10, 5, 12, -20, -9, -11, -2, -12, 2, -9, 5, -3,
+ 11, 7, -9, 4, -4, 24, -7, 21, -15, -3, 2, 14, -1, 5, 18, -12,
+ 13, 3, 5, -10, -11, 0, -8, -2, -4, 2, -15, 9, -10, -16, -9, -7,
+ 0, -1, 3, -8, -10, 5, -8, 4, -3, 8, -2, 20, 1, 6, -4, -9,
+ 4, 14, 7, -1, 3, -5, 18, -7, 20, -6, -10, 8, 1, -2, 3, -4,
+ -5, -3, -6, 0, -16, -7, 12, 0, -17, 4, -31, -7, 1, 1, -4, 8,
+ -11, 6, -1, 11, -5, -7, -4, 2, 4, 15, -3, 21, -5, 20, 3, -12,
+ 21, -1, 10, 5, 6, -20, -1, -18, 2, 3, -4, -5, -1, 6, -2, -11,
+ -17, -15, -13, 0, 6, -18, 7, -18, 7, -7, 6, 7, -10, 18, 16, 2,
+ -1, 3, -11, 6, 14, 1, 15, -2, 29, -8, 17, -14, 2, -19, 12, 8,
+ -6, -1, -23, 6, -11, 7, -19, -18, 0, 1, -8, -8, -4, -20, 8, -8,
+ 4, 10, -12, 13, 0, 18, -10, -3, -4, 6, 4, 17, 7, -2, 18, -9,
+ 14, -10, -4, -11, 4, 3, 23, -17, -6, -2, -7, -7, 9, -10, 1, 2,
+ -4, -14, -7, -6, -8, -4, 7, 2, -3, 3, 0, 13, -10, -4, -9, -6,
+ 18, 11, -4, 16, -8, -4, 1, -1, 7, 3, 3, 3, 10, -15, -2, -9,
+ 9, 0, 2, 2, -9, 12, -7, 0, -23, -7, -19, 2, -1, 0, 4, -15,
+ 7, 3, -3, 0, 9, -12, 19, 4, 8, -13, -6, 5, -1, 14, 10, 9,
+ 13, -3, 16, -18, 13, -18, 7, -10, 13, -6, -11, -3, 7, -23, -6, -11,
+ -21, 9, -1, 4, -3, -16, 0, -12, 7, 14, -5, 15, 0, 6, -5, -3,
+ -9, 9, 4, 10, 4, -2, -7, 10, -1, 10, -6, -14, 15, -4, 13, -4,
+ -4, -14, 5, -2, 4, -9, 3, -14, 2, 3, -10, -1, -9, 0, 3, -6,
+ 12, -16, 0, 4, 10, -25, 6, -5, 2, 8, 3, -2, -4, 15, 4, 7,
+ 2, -1, -6, 10, 11, 2, -2, -14, 6, -3, 0, -3, -9, -10, 1, -1,
+ -15, 9, -29, 9, -10, 7, -3, -3, -10, -2, 14, 4, -6, 0, 1, 12,
+ 4, 18, -15, 19, 1, 15, 1, 1, 3, -10, 8, -1, 7, -30, 8, -19,
+ -2, -5, -9, -10, 0, -1, 6, -4, -12, 1, -18, 10, -1, -12, 2, 7,
+ 12, 11, 0, -4, -1, 6, 10, 17, -8, 1, -12, 5, -2, 1, -7, -1,
+ 4, 3, -3, -1, -18, 8, -9, 0, -2, 8, -12, 12, 7, -5, -2, -16,
+ -7, 9, -5, 11, -9, -4, 3, 1, -9, -1, -2, -6, 7, 12, 0, -8,
+ 9, -10, 3, 0, 2, -3, 11, 14, 4, 3, -12, 3, -3, 2, 12, -4,
+ -2, -2, 9, -21, -5, -28, -6, -10, 6, 7, -6, -3, -24, 7, -11, 10,
+ 0, 8, 13, 10, 6, -7, -2, -5, 7, -1, 9, 18, -2, 12, -4, 7,
+ -26, 13, -6, 19, 6, 6, -5, -16, -6, -8, -18, -2, 1, -11, 3, 4,
+ -16, -8, -10, -3, 2, -3, 5, 5, 0, 11, 0, -14, 0, 1, 14, 11,
+ 13, 0, -2, 5, -1, -4, -2, -4, 5, 21, 3, 14, -5, -22, 5, -11,
+ -3, -6, -3, -11, 0, -5, -13, -10, -18, 3, 9, -10, 2, 3, -11, 11,
+ -11, 5, -19, 23, -1, 20, 18, 4, -3, -6, 9, 4, -3, 8, 4, 6,
+ 2, 5, -14, -6, -3, 2, -6, -4, -3, -11, 0, -5, 0, -21, -2, -10,
+ 11, 5, -4, -5, -5, -8, 10, -10, 4, -1, 6, 12, 9, 2, 8, -20,
+ 8, -2, 11, -11, 1, -4, 5, 6, -6, 6, -14, 14, 4, -2, 12, -3,
+ -10, 8, -5, -15, -9, -1, 5, 8, -3, 0, -23, -9, -11, 4, -12, 3,
+ -4, 4, 1, 15, -12, 3, 13, 2, 5, 8, -8, 7, 11, -3, 17, -11,
+ 5, 3, 19, 13, 3, -11, -11, -2, -9, -7, -4, -24, -1, -17, -3, -17,
+ 0, -15, 2, -1, -5, -4, 3, 2, 2, 11, -4, 3, -6, 11, 8, 3,
+ 6, 3, 7, 7, 6, -6, 2, 0, 14, 14, 3, 8, -6, 4, -3, 6,
+ -13, -2, -9, -4, 5, -13, -5, -21, -1, -6, -1, -5, -14, 8, -7, 5,
+ -7, -17, -11, 7, 3, 20, 7, 1, -3, 4, 5, 14, -3, 5, 3, 10,
+ 8, 6, -6, -2, 6, 3, 7, -6, -3, -3, -6, -1, -27, -11, -17, 0,
+ 11, 7, 1, -7, -9, -13, 5, -11, 0, -10, 15, 2, 5, -2, -5, 1,
+ 6, 6, -6, -5, 6, 2, 5, 3, 10, -16, 11, 8, 18, 3, 13, -11,
+ 7, 5, -7, -6, -20, 15, -1, 10, -1, -13, -17, -11, -3, -13, -4, -14,
+ -3, -2, -6, 6, -28, 9, -8, 10, 0, 12, -2, 10, 9, 1, 3, -6,
+ 5, 17, 24, 18, 3, 4, -9, -4, 2, -8, -4, -2, -11, 1, -8, -12,
+ -9, -10, 5, 0, -7, -9, 7, -18, 6, -10, -12, -1, -1, 13, 1, 18,
+ 2, -3, 4, 3, 3, -3, 3, 10, 9, 7, 5, -8, -7, 0, 3, -7,
+ 7, -2, -2, 5, -10, 2, -5, -3, -1, 4, 1, -2, -10, 4, -9, -5,
+ -12, -18, 3, 6, -3, 3, -15, -1, -13, 6, -2, 8, 0, 8, 16, -2,
+ 17, -4, 8, 3, 23, -1, 11, -8, 10, -4, -5, -3, -13, -2, -1, -2,
+ 2, -9, -13, -13, -2, -11, -2, -20, -5, 0, 3, 2, -1, -10, 1, 8,
+ 3, 9, 6, 4, -3, 13, 3, 4, 11, 2, 11, 8, -2, -1, -2, -2,
+ -2, -1, -21, -1, -14, 8, 6, -8, -10, 2, -16, 4, -3, -1, -10, 7,
+ -1, 4, -4, -12, 3, -2, 13, 2, -3, -9, -2, 6, -7, 8, -8, -5,
+ 12, 7, 8, -3, 6, -1, 16, 0, 7, -8, 3, -7, -1, 0, -6, -4,
+ -8, 6, -1, 4, -19, 2, -3, -8, -3, -12, 4, -6, 2, -7, 1, -13,
+ 2, 9, -1, 17, -19, 3, -3, 23, 9, 6, 3, 6, 6, -5, 11, -11,
+ 1, 0, -5, 6, -6, -4, -5, -7, 3, -4, -14, -9, -7, -1, 5, -11,
+ 4, -19, 14, -4, 3, 4, 2, 0, 9, -2, -3, 2, -2, 10, 15, -3,
+ 14, -6, -4, 6, 1, -8, 11, -9, 4, 3, -9, 2, 2, -2, 2, -2,
+ -9, -2, -2, 1, -6, -6, -22, -16, -10, 12, 0, 5, -8, -2, -4, -2,
+ 5, -1, 7, 7, 9, 1, 7, 6, -1, 10, 11, 5, -3, 8, 1, -1,
+ 8, -15, -6, -10, 12, 0, 2, -5, -9, -12, -7, -4, -14, -4, 0, -1,
+ 5, -7, -8, -12, 0, 2, 16, -3, 11, -4, 16, 11, 2, -3, 2, 8,
+ -1, 7, -13, 4, -3, -1, 3, -10, -2, -11, 3, 2, 3, -7, -10, -5,
+ -10, 12, -8, 5, -7, 15, 1, -10, 7, -16, 1, 3, 4, -5, 7, -7,
+ 4, -2, -1, -8, 0, -2, 17, 10, -2, 6, -5, 3, 10, -7, 2, -3,
+ 4, 5, 5, -3, -8, -8, -1, 1, 7, -5, -11, -2, -10, -4, -15, -7,
+ -10, -2, 2, -4, -10, -8, 0, 2, 6, 3, 2, 3, 10, 14, 8, 7,
+ 3, 5, -5, 20, -6, -1, -2, 0, 1, -2, -2, -8, 3, -3, 10, -14,
+ 3, -3, -2, 0, -5, 0, -15, 4, -2, 0, 4, -7, 3, -8, 7, -14,
+ -2, -6, 4, 2, 3, -10, -2, 5, -3, 12, -2, -5, -9, 1, 4, 1,
+ 11, -12, 15, 5, 20, 10, -5, 1, 5, 3, -13, 6, -16, 5, 1, -5,
+ -8, -3, -14, -6, -2, -5, -8, -17, -9, 3, -6, -2, -3, -3, 1, 14,
+ 2, 4, 5, 3, 8, 7, 12, 0, 11, 4, 16, 2, -3, -9, -1, 1,
+ -1, -3, -6, -14, 4, -6, 2, -14, -9, -11, -1, 0, 0, -5, -6, -10,
+ 5, -5, 2, -3, 2, 2, 17, -2, -1, -3, 3, 11, 1, 10, 2, 7,
+ 6, 5, -5, -3, -3, -2, 7, 2, 1, -18, -5, -2, -3, -5, 0, -2,
+ 0, 8, -9, -10, -15, -7, -2, -1, 6, -8, 16, -10, 13, -4, 2, -4,
+ 4, 7, 9, 6, -5, -2, 8, -1, 11, -6, -1, 5, 8, 0, 9, -20,
+ 0, -9, 4, -3, 1, -4, -11, 2, -6, 0, -12, 0, 1, 5, -2, 1,
+ -7, -4, 3, -1, -10, 3, -3, 7, 4, 8, -9, -6, -10, 0, 0, 2,
+ -4, 6, 9, 10, 2, 0, -1, 2, 14, 3, 7, -7, 2, -2, -2, -6,
+ -9, 2, -3, 6, -3, -7, -9, -10, -2, 2, -1, -11, 2, 1, 7, -4,
+ -7, -19, 3, -1, 6, 6, 6, 6, 0, 6, 7, 3, -1, 3, 8, 3,
+ 4, -10, -5, -7, 5, -4, -14, 2, -8, 5, -2, 2, -16, -4, -11, 2,
+ 4, -1, 2, -1, 0, 5, 4, -12, 3, 9, 7, 13, -3, -7, 2, 6,
+ -1, 7, -1, -1, 5, -5, 7, -11, -9, -13, 2, 5, 2, -2, -7, 5,
+ 4, -4, -2, -15, -4, 3, 0, 0, -5, 2, -7, -1, 9, -2, -1, 5,
+ 1, 1, -4, -5, -4, 6, 8, 7, -5, 4, -7, 4, 0, 1, -6, -5,
+ -2, 5, -1, 0, 1, 1, 3, 9, -4, -2, -4, -9, -1, 4, -17, 1,
+ -13, 11, -1, 6, -9, -1, 5, 1, 8, -3, 4, -5, 1, 7, -5, 1,
+ -3, 5, 3, 4, -7, -11, -7, 1, 5, -13, 11, -11, 1, 3, 6, -9,
+ 6, -5, -7, 4, -13, 5, -7, 10, 5, 6, -15, -1, 6, 4, 18, -7,
+ -7, -3, -4, 2, -5, 3, -4, 9, -4, 3, 3, -3, -10, 0, -1, 2,
+ 5, -3, 7, 3, 2, -6, -11, -2, -1, 4, -5, 4, -5, 0, -5, 5,
+ -5, -4, 2, 4, 2, 5, -8, -13, -3, 0, -1, -2, 4, 6, 9, 1,
+ 3, -7, -1, 1, 12, 1, 1, -1, -5, -1, 2, -8, -9, -7, -2, 3,
+ 10, -6, -7, -12, -7, -4, -5, 6, 0, 10, 5, 7, -4, -2, -8, 10,
+ 5, 9, 4, -1, -1, -1, -1, -1, -2, -3, 3, 9, -2, 9, -14, -13,
+ -8, -10, 1, 1, 3, 3, 1, -3, -12, -5, -7, 1, 6, 6, -2, -7,
+ -3, -3, 2, 2, 4, -9, 14, 8, 11, -3, 5, -11, 1, -1, 5, 3,
+ 8, 2, 8, -2, -6, -13, -10, 0, 4, 3, 4, -3, -9, 1, -5, -5,
+ -6, 1, -2, 2, -10, -6, -15, 1, -5, 4, -1, 2, 2, 4, 10, 4,
+ 2, -13, 0, 4, 8, 17, 2, 5, 4, 2, -6, 5, -5, 0, 8, -2,
+ -1, -5, -4, -5, -1, -5, -4, -5, 0, 0, 1, -9, -15, -3, -12, 1,
+ -1, -7, 10, 2, 5, -1, 2, -6, 2, 2, 10, 10, -1, 2, -2, 4,
+ 5, 0, -6, 12, 5, 3, -1, -8, -8, -4, -4, 3, -11, 0, -1, -1,
+ 0, -2, -14, -6, -9, 2, 1, 7, -4, 3, -1, 0, -3, 1, 2, 7,
+ 5, 4, 3, -2, -3, 1, 6, -1, 6, -11, 7, 2, -6, 2, -4, 0,
+ 2, 3, -7, -9, 3, 0, 4, -6, 0, -21, 0, -5, -1, 0, -1, 1,
+ -6, -1, -1, 0, -7, 5, 7, -2, 8, -4, -1, 3, 9, -6, 10, -6,
+ 7, 9, 10, 9, -6, 5, -14, 6, -5, 1, 2, -3, 0, -9, -10, -14,
+ -2, -3, 6, -8, -15, 3, -9, 0, -3, 0, -6, -1, 3, 9, 10, 3,
+ 3, -10, 6, 1, 3, -1, 9, 12, 4, 4, -9, -7, -5, 8, 6, 1,
+ 1, -4, -5, -5, -1, -11, -3, -4, 1, -1, 1, -10, -7, -2, -3, -4,
+ -3, -6, 11, 5, 3, 2, -8, -5, -2, 3, 9, 13, 5, 4, 4, 0,
+ -5, -1, -5, 9, 2, 3, -9, -4, 3, -6, 2, 1, -9, 5, -2, 3,
+ -2, -9, -8, -15, -5, -3, 3, -13, 11, 6, -3, 1, -6, -6, -1, 6,
+ 4, 6, 7, 1, 5, 0, 8, -6, 7, 2, 6, 2, -5, 0, -3, -1,
+ 3, -7, -1, -3, 5, 7, 6, -18, -10, -11, -7, -3, 10, -4, 3, -4,
+ -8, -5, -12, -3, -4, 12, 10, 2, -4, 6, 3, 1, 2, 0, -3, 3,
+ 7, 7, -5, 2, -4, 1, 3, 11, 2, 3, 4, -2, -7, -5, -17, -11,
+ 4, -3, 5, -7, -7, -6, -1, -8, -5, -5, 1, 7, 1, 2, -1, -9,
+ 7, 1, 7, 3, 3, 6, 9, 6, 1, -6, -4, 2, 5, 7, 4, -2,
+ 1, 3, -11, -1, -16, -2, -6, 1, 3, -8, -15, -11, 4, -1, 9, -2,
+ -5, 0, 6, 0, -7, 0, -8, 4, 2, 6, 2, 0, 2, 6, 2, -2,
+ 4, -2, 4, 14, 2, 2, -6, -6, -3, 4, -4, -1, -4, 1, -3, -6,
+ -1, -13, -1, -2, 7, -8, -7, -10, 0, 4, 3, -8, -3, 1, 4, 6,
+ 4, 6, -3, 5, 3, 4, 0, 6, 1, 4, 7, -3, -10, 8, -1, 9,
+ -1, 1, -11, -7, -3, -3, -6, -8, -9, -6, 1, -3, -6, -6, -5, 0,
+ 0, 2, -3, 0, 6, 4, 3, 2, 7, 4, 11, 14, 5, -1, -5, 1,
+ -2, 7, 3, 0, 1, 2, -5, -7, -10, -12, -10, -5, -5, -6, -6, -9,
+ 1, -8, -2, -1, -9, 1, 8, 2, -5, -2, -5, 0, 5, 6, 6, 7,
+ 8, 10, 2, 0, -3, -1, 2, 13, 3, 0, -6, 0, 1, -3, 0, -12,
+ -2, 4, -4, 4, -8, -11, -1, -2, 1, -1, 2, -12, 3, -6, 1, -12,
+ -7, -7, 3, 0, 9, 0, 1, 6, 1, -1, 2, 1, 2, 8, 9, -3,
+ -1, 0, 7, 3, 8, -1, -4, -1, 1, 3, -9, -1, -17, -3, -2, -4,
+ -4, -3, -4, -6, -11, -15, -2, -5, 6, 10, 1, 3, -1, -3, 13, 7,
+ 1, 6, 4, 4, 9, 5, -3, -5, 9, 3, 5, -3, 1, -3, 3, 0,
+ -7, -5, -7, 0, -5, 0, -1, -15, -11, -4, -5, -10, 2, -7, 5, -4,
+ 1, -9, 2, 1, 8, 7, 10, 2, 2, 0, 4, 3, -2, 0, 4, 2,
+ 6, 8, -2, 4, 4, -2, 5, -3, -6, 3, -3, -5, -9, -8, -11, -5,
+ -1, -1, -5, -7, -5, -8, 0, -3, 5, -7, 11, 1, 0, 2, -3, -1,
+ 3, 9, 6, -3, 8, 1, 11, 2, 8, -3, -3, 6, 2, 1, 2, -7,
+ -3, -2, -4, -8, -3, -3, 5, -10, -10, -4, -12, -2, 3, -5, 3, -6,
+ -8, -2, 5, -3, 0, 1, 4, 8, 4, 5, 0, 4, 8, 1, 7, -3,
+ 0, 3, 4, 4, -5, -2, -7, -3, 0, 5, -5, -9, 3, -2, -1, -2,
+ -5, -1, -4, -3, -11, -4, -5, -6, 0, 5, 0, -5, 5, 3, 8, -1,
+ 3, 3, 2, 5, 7, -4, 3, 1, 3, 10, 2, -7, 1, 0, 6, -4,
+ -3, -5, -7, -2, -4, -3, -6, 0, -10, 4, -6, -4, -7, -2, 1, -4,
+ -1, -3, -1, 2, 6, 2, 4, -2, 2, 4, 2, 5, -3, 4, 2, 1,
+ 0, 8, -3, 2, 5, -5, 3, -5, -2, 5, -5, 3, -1, -4, -3, 4,
+ -10, -5, -7, -4, -4, 0, 0, -7, -1, -1, 2, 1, -2, -12, -4, -1,
+ 0, 4, -5, 2, 0, 3, 12, 11, 3, 11, -1, -3, 6, -6, 1, 1,
+ 7, 6, -7, -1, -7, -4, -4, -7, -8, -1, -6, -6, -2, -3, -5, 0,
+ -4, 8, -7, 1, 4, -3, 6, 1, -7, 3, 5, 6, 5, 13, 2, 2,
+ -4, 4, -3, 1, 4, -4, 2, -3, -10, -10, -7, -2, -2, -2, 0, -6,
+ -2, 1, -3, -4, -2, -5, -2, 7, 1, 6, -5, 6, -1, -1, 2, -3,
+ 4, 11, 2, -1, 2, -7, -5, 8, 0, 3, -3, -5, -1, -2, 3, 1,
+ -4, 4, 7, 0, 2, 3, -3, 0, 1, -5, -15, -5, -3, 1, 3, -3,
+ -11, -4, -7, 1, -2, -1, -1, 0, 1, 1, -5, -1, 3, -2, 7, 1,
+ -4, -1, 0, 4, 5, 3, 3, -1, 8, 11, 1, 4, 1, -5, 7, -6,
+ -4, -2, -4, -2, 3, -8, -3, -13, -6, 3, -3, -7, -4, -7, 3, 3,
+ -3, 2, -1, 1, -4, -2, -2, -5, 1, 11, 9, -2, 6, -3, 7, 7,
+ 1, 1, -7, 2, -3, 1, 4, -4, -4, 5, 1, 0, -3, -6, 2, -3,
+ 0, -8, -12, -6, -2, -3, 6, -1, -9, 0, -1, 1, 3, -2, -1, 0,
+ 1, 6, 0, -3, 5, 1, 6, 1, -1, 4, 1, 7, -3, -1, -1, -4,
+ 4, 14, -1, -1, 2, -4, -1, -6, -8, -8, -3, -2, 2, -9, -5, -7,
+ -12, 5, 0, -3, -4, -3, 5, 4, 3, -2, -6, 4, 7, 3, 5, 7,
+ -3, 8, 0, -5, -1, -1, 11, 10, 3, 4, -8, -3, -3, 1, -3, 0,
+ -4, -3, 1, -7, -8, -16, -7, -6, -2, 3, -7, -2, 1, -4, 0, -5,
+ -5, 1, 5, 10, 5, 0, 3, 0, 1, 13, 0, 5, 9, 6, 8, -1,
+ -4, 0, -3, 6, 4, -4, 0, -3, -15, -2, -12, -15, -3, -6, 2, 1,
+ -3, -4, -9, -9, -3, -3, -2, 3, 4, 9, 0, 2, 1, 2, 14, 5,
+ 3, 8, 2, 7, 4, -4, -4, -1, -9, 9, -5, -1, -7, -10, -2, -7,
+ -4, 0, -5, 2, 5, 1, 0, -5, -5, -1, -1, -3, 4, -8, 5, 3,
+ -4, 4, -5, -3, 9, 4, 8, 0, 0, 2, 0, -2, 0, -2, -7, 12,
+ -1, 5, -4, 2, -3, 0, 2, -2, -4, -2, 2, -5, 3, -7, -9, -4,
+ -3, -2, -6, -6, -2, -6, -1, -7, -8, 1, 3, 6, 10, 4, 5, 0,
+ 5, 8, 1, 3, 8, 5, 11, 12, -7, 4, 0, -3, 2, -1, -8, -7,
+ -4, -2, -6, -9, -6, -13, -4, -1, 0, -9, -5, -3, -4, -2, 3, 1,
+ 1, 9, 4, 2, 6, -1, 3, 6, 2, 0, -3, 3, 2, 6, 3, -1,
+ -4, 4, 1, 2, 2, -5, -8, -1, -3, -1, -9, -4, 1, -5, 5, -7,
+ -4, 0, 3, -10, 3, -3, -5, 1, 5, 4, 1, -5, 1, -5, 4, 1,
+ -6, 0, 5, 8, 8, 1, 6, 0, 3, 4, 2, -3, 1, -3, -3, 3,
+ -10, -6, -8, -2, -1, -3, -6, -6, -5, -6, -6, -5, 5, -3, 5, 6,
+ -2, -1, -1, -4, 6, -2, 6, 6, 2, 12, 8, -2, 3, -6, -2, 5,
+ 4, -3, -2, -5, -4, -7, -6, 1, -5, 2, 2, 0, 1, -7, 0, -4,
+ -2, -1, -2, -5, 7, -5, -2, -3, -2, -3, 4, 4, 9, 0, 1, 1,
+ -5, -3, -4, -4, 4, 3, 6, 1, -2, -2, -7, 4, 1, 1, -3, 3,
+ -1, 2, 0, -7, 0, 0, -1, -3, -2, -1, -5, -2, -3, -8, -5, -5,
+ -1, 5, 5, 2, 2, -3, 4, 3, 4, 6, 3, -1, 10, -4, -3, -2,
+ -3, 0, -4, 0, -2, -2, 0, 2, -5, -2, -5, -9, 8, -2, -1, -1,
+ -3, -3, -2, -6, 2, 1, 2, 9, 0, 1, 4, -5, 2, 4, -6, -1,
+ 2, -1, 6, 3, 0, -5, -3, -1, 0, 3, -3, 0, -6, -2, -3, -4,
+ -2, 0, 3, 2, 2, 0, -10, 1, -6, -5, -1, -2, 5, 3, 6, -2,
+ -6, -1, -3, 2, 4, 1, -1, 0, 1, 1, 3, -1, 5, -1, 7, 6,
+ 1, -2, 0, -6, -2, -2, -8, -2, -2, -3, -5, -5, -8, -3, -1, 5,
+ -3, 1, 2, 1, 2, -3, -2, -3, 2, 6, 2, 6, 0, 0, -2, 9,
+ -1, 3, -2, 3, 0, 0, 0, -6, -6, -1, -5, -7, 1, -3, -6, 2,
+ -2, -1, -5, -2, 1, 4, 2, 2, -3, -1, 6, -2, 2, 4, -3, 2,
+ 2, 2, -3, 1, 0, -4, 2, -1, -2, 3, 1, 1, -1, -5, -8, -2,
+ -5, 0, 1, -6, 3, -4, 2, 3, -6, 3, 0, 2, -2, -1, -4, -2,
+ -4, 4, 0, -3, 0, -6, -3, 10, -3, 3, 0, 4, 7, 3, 0, 5,
+ 1, 5, 1, -3, -2, 0, -6, 3, -1, -7, -5, -7, -1, -2, -2, -2,
+ -3, -2, 2, -2, -1, -3, -3, 2, -2, -6, -3, -3, 4, 3, 2, 0,
+ -1, 5, 5, 8, 2, 2, -2, 4, 0, 5, -5, -3, -1, -3, -3, -6,
+ -4, -2, 3, 0, -2, -2, -5, 5, -1, 3, -1, -1, -3, 0, 0, -5,
+ -4, -3, -2, 5, 0, -4, -4, 1, 2, 6, 0, -3, -1, 2, 3, 7,
+ -3, 0, -4, -2, 4, 3, 0, 1, 3, -3, 1, -7, -4, 0, 1, 1,
+ -4, -4, -4, -9, -1, -2, -3, -2, -3, -3, 4, 3, -1, -4, 2, 4,
+ 4, 3, 2, -1, 0, 9, -1, 4, 2, 7, -1, 6, -2, -2, -5, -1,
+ -9, -2, -2, -6, -1, -1, 1, -8, -6, -5, -1, -1, 1, -4, -5, 3,
+ 1, 5, 3, -3, 0, -2, 7, 0, 1, -2, 3, -1, 5, -1, -5, 7,
+ -1, 3, 2, -5, -6, -2, 4, 2, -1, -3, -1, -1, -1, -1, -2, -4,
+ 1, -5, 3, -1, -3, -5, 2, 6, -6, -1, -5, -4, 4, -1, -1, -2,
+ -1, 2, 0, 3, 1, 4, 2, 7, -1, 2, 0, -2, 1, 4, -5, -3,
+ -7, -2, 0, -1, -1, -3, 0, 0, -2, -6, 2, -4, 2, -4, 1, -7,
+ -2, -1, 5, 3, -2, -7, -4, 1, 6, 4, 5, 1, 4, 0, 5, 1,
+ -1, 2, 0, -3, -3, -5, -6, 3, -1, 5, -1, -2, 1, 1, 4, 2,
+ -6, -3, -4, -3, 2, -2, -8, -3, -6, -4, -2, -11, 0, 0, 1, 6,
+ -3, -2, 1, 2, 10, 8, 4, -2, -1, 2, 2, 1, -2, 3, 1, 5,
+ 3, -1, 0, -4, 4, -7, -2, -7, -8, -4, -3, -2, -7, -7, -3, -1,
+ 5, -2, 0, -7, 2, -1, 3, 1, 4, 6, 5, 8, 3, 2, -1, 3,
+ -3, 0, 0, -5, -1, 1, 1, -5, -3, -2, 6, 4, 5, -4, -8, -4,
+ -3, -2, -5, -4, -4, -4, 2, -3, -2, -4, -4, -4, 6, 1, 0, 1,
+ 3, 3, 5, 2, 1, 0, 6, 2, -1, 1, -3, -3, 2, -1, 0, 1,
+ 3, 1, 4, -4, -5, -10, -8, 1, -6, -3, -4, -6, -3, 0, 2, -3,
+ -1, 2, 0, 8, 1, 4, 4, 3, 6, 3, 1, 3, 5, 1, 2, -4,
+ -7, -3, -3, 3, 0, -7, -5, 0, -3, -1, -2, -4, 0, -5, 1, -6,
+ -1, -5, -3, 1, 4, -1, -3, 3, 3, 5, -1, -2, 2, -1, 2, 1,
+ -1, -5, 5, 1, 2, 2, -4, 0, -1, 3, 0, -2, -1, 2, 1, 5,
+ 4, -3, -5, 0, -2, -2, -6, -3, -3, -4, -1, -5, -4, -1, -2, 0,
+ 2, -2, -6, -3, 1, 1, 1, -1, 3, 4, 7, 2, 3, 4, -1, 7,
+ 2, 3, 1, -1, 1, -2, 0, -4, -5, -6, 0, -2, -7, -2, -5, -5,
+ 1, -4, -5, -5, 3, -1, 1, 2, -2, 0, 1, 4, 1, -4, 2, 2,
+ 0, 9, 2, 0, 4, 3, 1, 2, -4, -2, -4, 3, -4, -2, -6, 0,
+ -1, 5, 2, -4, 0, -4, -4, -1, -5, -4, -7, -3, 1, 0, -2, -1,
+ -5, 1, 0, -1, 0, 2, 4, 0, 3, -2, 1, 2, 6, 0, 1, 5,
+ 0, 3, 3, 2, -5, -2, 1, 5, 2, -2, -5, -9, 0, -6, -1, -6,
+ -7, -5, -4, 0, -2, -5, -3, 2, -2, 3, 2, 0, 9, 2, 0, 4,
+ -3, 4, 5, 8, 6, -2, -4, -1, 0, -2, -2, 1, -5, 2, -5, -1,
+ -4, -3, -4, 0, -2, -7, -3, -1, 0, -1, 0, -6, 3, -2, 5, 2,
+ -1, -2, 1, 0, 1, -1, -3, 2, 3, 1, 2, -4, -3, -1, 5, 5,
+ 3, -4, 0, 1, 2, 5, -5, 1, -5, 2, -2, 2, -4, -3, 0, -4,
+ -3, -9, -7, -4, 2, -2, 1, -6, -3, 0, 1, 5, 1, -5, 0, 0,
+ 2, 1, 2, 0, 6, 4, 6, 3, 2, 3, 1, -2, -2, -9, -4, -1,
+ 4, 0, -1, -5, -8, -5, -4, 0, -4, -1, -3, 0, 0, -4, -3, -1,
+ 1, 2, 0, -2, -3, 1, 3, 2, 3, 3, 0, 8, 2, 7, -1, 3,
+ -2, 4, 0, 0, 1, -4, 5, -1, -3, -3, -6, -4, 2, 1, -5, -4,
+ -7, -4, -4, -7, -2, -10, 1, 0, 1, -3, 4, -2, 5, 2, 1, -3,
+ -1, 2, 8, 4, 5, 0, 1, 4, 5, 2, 2, -2, 1, -4, 0, -3,
+ -3, -1, 0, 2, -4, -4, -5, -1, -7, 0, -4, -5, -1, -3, 2, -2,
+ 0, 3, 0, 2, 0, 1, -2, 2, 4, -1, 0, -3, -1, 1, 3, 2,
+ -3, 2, 0, 2, 2, -1, 2, -2, -3, 0, 0, -2, 2, -2, 4, -3,
+ -6, -7, -6, 2, -1, -4, -1, -7, -1, -3, 3, -1, 0, -2, 2, 2,
+ -3, 3, -4, 5, 7, 6, 3, 1, -1, 6, 2, 1, 0, -1, -1, 1,
+ -3, 1, -3, -5, -5, -3, -8, -3, -11, -1, -1, 0, -8, -2, -5, 3,
+ 4, 0, 1, -2, 2, 0, 6, 4, 1, 4, 1, 5, 0, 0, 1, 2,
+ 5, 0, 1, -10, 0, -5, 2, 0, -6, -6, -2, -2, 2, -3, 0, -4,
+ 2, -4, 1, -3, -4, 1, -2, 2, 1, -2, 0, 3, 2, -3, -1, -5,
+ -3, 4, 2, 3, -1, 4, 1, 5, -1, 2, -3, 2, -3, 0, -3, -2,
+ 1, 1, 5, 1, -2, -5, 1, -1, -4, -3, -7, 0, -5, -4, -4, 0,
+ -4, 4, 0, -1, 1, -8, 1, 0, 9, 1, 2, -2, 5, 5, 1, 6,
+ -1, 6, 3, 1, 1, -2, -2, -4, -3, -2, -3, -7, -4, -4, -1, -3,
+ -8, -1, -8, 4, -5, 0, -3, 1, 0, 4, -1, 0, 1, 3, 3, 4,
+ -4, 6, -2, 2, 5, 4, -3, 4, -3, 5, 0, -4, 0, 0, -1, 0,
+ -4, -4, 3, -1, -2, -4, -8, -9, -5, -4, 4, -4, 1, -4, 1, 1,
+ -1, -1, -1, 3, 2, 3, 0, 1, 2, 1, 5, 3, 1, 0, 5, 3,
+ 3, 0, -5, -4, -2, 5, 0, -2, -5, -2, -6, -2, -5, -8, -2, 1,
+ -1, -3, -7, -8, -6, 0, 4, 7, -2, 7, -1, 7, 3, 2, -5, 0,
+ 2, 0, 1, -3, 2, 2, 3, 3, -3, 0, -2, 3, -1, -1, -4, -6,
+ -2, -3, 4, -4, 0, -4, 6, -2, -6, -2, -7, 1, 2, -1, -3, -2,
+ -2, 3, -1, 0, -3, -1, 4, 7, 4, 0, 2, -1, 0, 6, -2, 1,
+ 1, 5, 4, 1, -3, -3, -2, 2, 2, 1, -6, -6, -3, -4, -2, -6,
+ -5, -4, -5, -2, -8, -8, -3, 0, 4, 0, 1, -1, 2, 5, 4, 2,
+ 2, 3, 3, 4, 10, 0, 2, 0, 3, 1, 1, 0, -3, 1, -3, 1,
+ -7, 0, 1, -2, 1, -6, -4, -10, -1, -4, -2, -2, -3, 2, -4, 1,
+ -5, -4, -4, 2, 1, 1, -4, -1, 3, 1, 6, 2, -2, -2, 3, 3,
+ 2, 7, -5, 5, 0, 8, 1, -1, 2, 3, -1, -6, 0, -10, 3, -1,
+ -1, -5, -6, -8, -2, 0, -3, -5, -8, -4, 2, -3, -1, -2, 0, -1,
+ 7, -1, 3, 2, 4, 7, 3, 4, -1, 5, 1, 9, 1, -2, -1, -1,
+ 1, -3, -2, -6, -7, 1, -3, -1, -9, -4, -6, 0, 2, -3, -2, -4,
+ -3, 0, -4, -1, -4, 0, 1, 6, -1, 1, -1, 3, 5, -1, 3, 4,
+ 5, 7, 4, -2, 0, -2, 0, 3, 1, -1, -8, -2, -1, -2, -5, -1,
+ -2, -2, 2, -5, -7, -9, -2, -3, -2, 1, -5, 4, -4, 5, -1, -1,
+ -3, 2, 3, 7, 3, -1, 3, 4, -1, 5, -4, 0, 4, 4, 3, 4,
+ -9, 1, -5, 2, -2, -2, -3, -7, -1, -2, -2, -5, -3, -1, 1, -2,
+ -1, -4, -4, 1, -1, -7, 0, -1, 2, 5, 4, -4, -5, -4, 0, 2,
+ 1, -1, 3, 5, 4, 0, 0, -1, 3, 8, 3, 3, -4, 0, 1, 0,
+ -2, -6, -2, -4, 3, -2, -3, -5, -6, -3, -1, -1, -7, 0, 0, 3,
+ -5, -4, -11, 0, 0, 3, 3, 1, 1, 1, 4, 6, 1, 1, 2, 9,
+ 3, 3, -4, -4, -3, 2, -1, -6, 1, -5, 2, 0, -1, -8, -5, -6,
+ 1, 0, -2, -1, -2, -1, 2, 0, -9, 0, 5, 4, 7, -3, -3, 3,
+ 4, 2, 4, 0, -1, 3, 1, 5, -5, -6, -7, 0, 3, 0, -2, -4,
+ 3, 3, -3, -4, -7, -2, 4, 1, -1, -4, -1, -6, -2, 3, -2, -3,
+ 1, 4, 1, -1, -4, -3, 3, 4, 5, -2, 2, -3, 4, 0, 3, -3,
+ -3, 0, 3, 1, -2, -1, -3, 2, 4, -2, -2, -3, -1, -1, 3, -11,
+ -2, -8, 5, -1, 3, -5, -2, 2, -1, 3, -3, 0, -1, -1, 5, -2,
+ 0, -2, 3, 2, 3, -2, -6, -3, 2, 4, -6, 5, -6, 1, 2, 3,
+ -6, 2, -3, -4, 3, -9, 2, -6, 3, 4, 2, -9, -1, 1, 2, 8,
+ -3, -4, -1, -2, 2, -2, 2, -3, 3, -1, 1, 2, -1, -6, 1, 2,
+ 2, 1, -2, 2, 3, 1, -3, -6, -3, 0, 1, -3, 0, -3, -1, -4,
+ 2, -4, -3, -1, 4, 0, 5, -6, -7, -1, 0, 0, -3, -1, 2, 4,
+ 0, 3, -4, -1, 1, 7, 4, 2, -1, -4, 0, 2, -4, -5, -5, -1,
+ 1, 4, -5, -4, -6, -3, -2, -3, 2, -2, 5, 2, 3, -4, -2, -5,
+ 6, 3, 4, 2, -3, 1, 0, 0, 1, -3, -1, 1, 7, 0, 6, -6,
+ -7, -2, -7, 0, -1, 0, 2, 1, -2, -7, -2, -5, 0, 2, 0, -3,
+ -5, -1, -3, 0, -1, 0, -6, 8, 4, 5, -1, 1, -4, 1, 1, 4,
+ 2, 5, 3, 6, 0, -2, -9, -4, -1, 0, 0, 1, -1, -4, -1, -5,
+ -5, -5, 0, 0, 1, -6, -5, -9, 0, -3, 0, -2, 0, 0, 3, 4,
+ 2, 1, -7, 1, 3, 4, 9, 1, 4, 4, 2, -4, 2, -2, 1, 5,
+ -2, 0, -3, -4, -3, -2, -4, -4, -4, 1, -1, 2, -6, -8, -3, -8,
+ -1, -2, -4, 5, 2, 3, -1, 0, -4, 2, -1, 5, 5, -1, 3, 0,
+ 3, 3, 0, -4, 9, 4, 2, -1, -6, -4, -2, -2, 2, -7, 0, 0,
+ -2, -2, -2, -10, -4, -7, 0, -2, 2, -2, 2, 1, 0, -3, 0, 1,
+ 6, 3, 2, 0, 0, -1, 2, 3, -1, 4, -5, 6, 2, -3, 0, -3,
+ 0, 1, 0, -5, -6, 1, 0, 1, -5, -2, -14, 0, -4, -1, -1, -1,
+ 1, -3, 0, -2, -1, -4, 4, 5, -1, 5, -1, 3, 3, 5, -3, 5,
+ -3, 5, 5, 6, 4, -6, 2, -9, 4, -4, 0, 1, -2, -1, -8, -6,
+ -11, -2, -3, 3, -6, -8, 3, -5, 1, -3, 1, -3, 1, 3, 5, 6,
+ 2, 1, -6, 4, -1, 1, 0, 7, 7, 2, 3, -6, -4, -4, 3, 3,
+ 0, 1, -1, -2, -4, 0, -8, -2, -3, 1, -2, 1, -5, -2, -1, -3,
+ -3, -4, -3, 7, 4, 1, -1, -6, -5, -3, 2, 5, 8, 3, 3, 2,
+ 1, -4, -1, -2, 6, 3, 2, -4, -1, 1, -5, -1, -1, -5, 2, -2,
+ 1, -2, -7, -5, -11, -4, -3, 3, -8, 8, 4, -2, -2, -4, -4, -1,
+ 4, 3, 5, 5, 2, 4, -1, 6, -3, 6, 2, 3, 0, -4, 0, -2,
+ -2, 0, -5, -2, -1, 4, 3, 1, -13, -8, -8, -5, -3, 7, -2, 3,
+ -2, -5, -3, -8, -2, -3, 8, 6, 1, -2, 5, 3, 1, 2, 0, -1,
+ 2, 4, 3, -5, 1, -3, 0, 1, 7, 1, 2, 3, -1, -4, -4, -10,
+ -7, 3, 0, 2, -5, -5, -4, -1, -7, -3, -3, 1, 3, 0, 0, -1,
+ -6, 6, 1, 4, 1, 2, 5, 6, 4, -1, -4, -3, 1, 2, 5, 2,
+ -1, 1, 3, -8, -1, -10, -2, -5, 0, -1, -6, -10, -7, 2, -2, 6,
+ -1, -2, 1, 4, -1, -5, -1, -5, 4, 1, 4, 2, 1, 3, 4, 0,
+ -2, 1, -1, 3, 8, 2, 1, -4, -3, -3, 3, -3, -1, -4, 0, -4,
+ -6, -2, -8, 1, -2, 5, -6, -5, -6, 0, 3, 1, -6, -3, 1, 2,
+ 4, 2, 4, -2, 3, 3, 3, 1, 5, 1, 2, 3, -2, -6, 6, -1,
+ 6, -2, 1, -7, -5, -2, -3, -6, -6, -6, -4, 0, -2, -4, -4, -3,
+ 0, -1, 1, -3, -1, 3, 1, 1, 0, 6, 4, 8, 10, 5, 0, -3,
+ 1, -2, 5, 2, 1, 1, 1, -4, -6, -8, -8, -8, -5, -4, -5, -4,
+ -5, 0, -5, -3, 0, -7, 0, 4, 1, -4, -1, -4, -2, 4, 4, 5,
+ 6, 6, 7, 0, 0, -1, 0, 2, 9, 2, 1, -3, 0, 1, -3, 1,
+ -9, -1, 3, -4, 3, -6, -7, -2, -1, -1, -1, 1, -9, 2, -5, 1,
+ -8, -6, -6, 1, -1, 6, 0, 2, 5, 2, 0, 2, 1, 2, 6, 5,
+ -2, -1, 0, 4, 1, 6, 0, -2, 1, 0, 3, -7, -1, -13, -4, -3,
+ -3, -3, -2, -3, -5, -9, -11, -2, -3, 4, 7, -1, 2, 0, -2, 8,
+ 5, 1, 4, 3, 2, 7, 3, -2, -4, 7, 2, 3, -2, 1, -1, 2,
+ 0, -5, -4, -4, 0, -4, 0, -1, -10, -9, -3, -5, -8, 1, -5, 3,
+ -3, 0, -7, 1, 0, 5, 4, 7, 1, 1, 0, 2, 2, -2, -1, 2,
+ 1, 4, 6, -1, 4, 3, -1, 4, -2, -3, 3, -1, -2, -6, -6, -7,
+ -3, -1, 0, -4, -6, -5, -6, 0, -3, 3, -5, 7, 0, -1, 1, -3,
+ -1, 1, 6, 3, -3, 7, 1, 10, 1, 6, -1, -2, 5, 2, 1, 1,
+ -4, -2, 0, -3, -7, -2, -4, 4, -8, -8, -4, -10, -2, 2, -4, 1,
+ -5, -7, -1, 3, -1, 1, 1, 4, 6, 2, 2, 0, 4, 7, 0, 5,
+ -2, 0, 3, 3, 3, -3, -1, -5, -2, 0, 3, -4, -6, 2, -1, 0,
+ -2, -4, 0, -4, -3, -9, -3, -4, -4, 0, 3, -1, -4, 3, 1, 5,
+ -2, 1, 2, 2, 4, 5, -3, 2, 1, 3, 7, 1, -5, 1, 0, 5,
+ -3, -2, -3, -4, 0, -3, -2, -5, 0, -8, 3, -6, -4, -6, -2, 2,
+ -4, -2, -3, -2, 1, 4, 2, 3, -2, 2, 4, 1, 4, -2, 3, 2,
+ 1, 1, 7, -1, 2, 4, -4, 2, -4, -2, 5, -4, 3, -1, -3, -2,
+ 3, -8, -4, -6, -3, -3, -1, 0, -6, -1, 0, 1, 1, -2, -10, -3,
+ -1, 0, 2, -5, 1, 1, 2, 10, 8, 2, 8, -1, -2, 4, -5, 2,
+ 2, 7, 6, -6, -1, -5, -4, -3, -6, -7, 0, -5, -5, -1, -2, -5,
+ 0, -4, 6, -6, 0, 3, -3, 4, 0, -6, 2, 5, 5, 4, 10, 0,
+ 2, -3, 3, -2, 0, 3, -3, 2, -3, -8, -8, -5, -1, -1, -1, 0,
+ -5, -2, 0, -3, -4, -1, -5, -2, 5, 0, 5, -4, 4, -1, -1, 1,
+ -3, 3, 9, 2, -1, 1, -6, -3, 7, 1, 3, -2, -4, 0, -1, 3,
+ 1, -3, 4, 6, 0, 1, 2, -3, 0, 0, -5, -13, -4, -2, 1, 2,
+ -3, -10, -4, -7, 1, -2, -2, -1, 0, 1, 1, -4, -1, 2, -2, 7,
+ 1, -3, 0, 0, 4, 5, 2, 2, -1, 6, 9, 1, 3, 1, -5, 5,
+ -6, -5, -2, -4, -2, 2, -7, -4, -11, -5, 3, -3, -6, -4, -6, 3,
+ 3, -3, 2, 0, 1, -3, -1, -2, -4, 1, 10, 8, -2, 4, -3, 6,
+ 6, 1, 0, -7, 2, -2, 1, 3, -4, -4, 4, 1, 0, -2, -5, 2,
+ -2, 0, -7, -11, -5, -2, -2, 5, -1, -8, -1, -1, 1, 2, -2, -1,
+ 1, 1, 5, 0, -3, 5, 1, 6, 1, -1, 3, 1, 6, -3, -1, -1,
+ -3, 4, 12, -1, -1, 2, -4, -1, -6, -8, -7, -3, -2, 1, -9, -5,
+ -6, -10, 5, 1, -2, -3, -2, 5, 4, 3, -1, -5, 4, 6, 3, 4,
+ 6, -2, 7, 0, -4, -1, -1, 9, 8, 2, 2, -8, -3, -3, 0, -2,
+ 0, -4, -2, 0, -6, -7, -14, -6, -5, -1, 3, -6, -2, 1, -3, 0,
+ -4, -5, 1, 5, 9, 4, 0, 3, 0, 1, 12, 0, 4, 8, 5, 7,
+ -1, -4, 0, -3, 5, 4, -4, 0, -3, -13, -2, -10, -14, -3, -5, 2,
+ 1, -3, -4, -8, -8, -3, -2, -2, 3, 4, 8, 0, 2, 1, 2, 12,
+ 5, 3, 8, 2, 6, 3, -4, -4, -2, -8, 8, -5, -2, -6, -10, -2,
+ -6, -4, 0, -4, 2, 5, 1, 0, -4, -4, -1, -1, -3, 4, -7, 4,
+ 3, -3, 4, -4, -3, 8, 4, 7, 0, 0, 2, -1, -2, -1, -2, -7,
+ 11, -1, 5, -4, 2, -2, 0, 2, -2, -4, -2, 1, -5, 3, -6, -9,
+ -3, -3, -2, -5, -5, -2, -6, -2, -7, -8, 1, 3, 5, 9, 4, 4,
+ 0, 5, 8, 1, 3, 7, 5, 10, 11, -7, 3, 0, -3, 1, -1, -7,
+ -7, -3, -2, -6, -9, -6, -12, -4, -1, 0, -8, -5, -3, -3, -2, 3,
+ 1, 1, 9, 4, 2, 5, -1, 2, 6, 2, 0, -3, 2, 2, 5, 2,
+ -1, -4, 4, 1, 1, 2, -5, -8, -1, -3, -1, -9, -4, 1, -4, 5,
+ -6, -4, 0, 3, -9, 3, -3, -5, 1, 4, 4, 1, -4, 1, -4, 4,
+ 1, -6, 0, 5, 7, 8, 1, 6, 0, 3, 4, 2, -3, 1, -3, -3,
+ 3, -9, -6, -7, -2, -1, -3, -5, -6, -5, -5, -6, -5, 4, -3, 5,
+ 5, -2, -1, -1, -3, 6, -2, 5, 6, 2, 11, 8, -1, 3, -6, -2,
+ 5, 4, -3, -3, -5, -3, -7, -5, 0, -5, 2, 1, 0, 1, -7, 0,
+ -3, -2, -1, -2, -5, 7, -4, -2, -3, -2, -3, 4, 4, 9, 0, 1,
+ 1, -5, -3, -4, -4, 4, 3, 6, 0, -2, -2, -6, 4, 1, 1, -3,
+ 3, -1, 2, 0, -7, 0, 0, -1, -3, -2, -1, -5, -2, -3, -8, -5,
+ -5, -1, 5, 5, 2, 2, -3, 4, 3, 3, 6, 3, -1, 10, -4, -3,
+ -2, -3, 0, -4, 0, -2, -2, 0, 1, -4, -2, -5, -9, 8, -2, -1,
+ -1, -3, -3, -2, -6, 2, 1, 2, 9, 0, 1, 3, -4, 2, 4, -6,
+ -1, 2, -1, 6, 3, 0, -5, -3, -1, 0, 3, -3, 0, -6, -2, -3,
+ -4, -2, 0, 3, 2, 2, 0, -10, 1, -6, -5, -1, -2, 5, 3, 6,
+ -2, -6, -1, -3, 2, -1, 0, 0, -1, 0, 0, 0, 1, -2, 2, -2,
+ -5, -1, -2, 16, 12, -18, -10, 3, -14, -10, 16, -1, -3, -16, 28, 3,
+ -1, -1, 12, -5, -6, 6, 7, -7, -18, -28, 11, 0, 6, -2, 26, -21,
+ -10, -1, 24, -3, 20, -19, 15, -14, -3, -3, 15, -35, -2, 6, -14, 30,
+ 6, -36, -8, 17, 0, -27, 26, 16, -38, 8, -14, 57, 3, -31, -14, 34,
+ -20, 33, 2, -6, -7, -28, 20, -24, 8, 13, 8, -39, 17, 40, -42, -11,
+ 13, -46, 1, 28, -22, 11, -3, -14, 5, 20, -12, -4, 49, -22, -24, 39,
+ -11, -1, -9, 37, -30, 13, 34, 4, -11, -25, 18, -22, 1, 29, -17, -3,
+ -26, -16, -21, 12, -18, 7, -17, -6, 51, 0, -21, 10, 24, -45, 8, 14,
+ 31, -10, -37, 6, 0, 24, 3, -18, -13, 14, 11, 0, 7, -1, -38, -29,
+ -21, 32, -30, 22, -26, 14, -40, 55, -36, 30, -12, 8, 31, -16, 19, -15,
+ 23, -48, 36, 1, 63, 3, 24, 0, -3, 14, 26, -21, 15, 47, -21, -80,
+ 14, -4, -25, -33, 11, 25, -35, -44, 13, -2, -48, -11, -23, -7, 27, -4,
+ -15, -22, 5, 26, -36, 50, 23, 11, -23, -14, 19, 32, 14, 38, -66, 56,
+ -11, 26, 18, -12, 17, -30, -6, -54, 22, 77, -62, -12, -16, 34, -25, 2,
+ 14, -62, 12, 20, -22, -50, 58, -29, -58, 4, 28, 30, 13, 25, -78, 38,
+ 45, -19, -7, 52, -61, 27, 17, -21, -4, 6, 37, -24, -38, 73, 8, -16,
+ 21, -2, -15, -19, -19, 18, 3, 7, -48, -10, -10, 10, 4, 13, -13, -4,
+ 0, 46, -12, 6, -18, -25, 4, 14, 27, -22, -37, 14, -6, -17, 55, 40,
+ -111, 63, 9, -38, -16, 46, -35, 4, 0, -10, -8, -12, 58, -69, 1, 66,
+ -38, 21, -33, -6, 10, 0, 10, -11, 18, -16, 32, -7, -10, -25, 65, -42,
+ 42, -62, 18, -3, -2, -8, 21, 4, -71, 13, 40, -3, 18, -19, -29, 15,
+ -66, 60, -50, -6, 67, -80, 17, 66, -21, -20, -15, 68, -16, 72, -4, -23,
+ 4, 53, -8, 8, -4, 0, 27, -26, -22, 25, -31, 7, -39, -18, 27, -43,
+ -25, -33, -6, 17, -16, 0, -55, 6, 26, -3, -67, 7, 60, -83, 25, 15,
+ 45, -8, 51, -55, 28, 42, 42, -17, 37, -6, 17, 8, 11, -1, 59, -7,
+ -45, 14, -41, 107, -49, -50, -25, 63, -58, -27, -57, 19, 13, -13, -27, 19,
+ -42, 63, -113, -1, 44, 8, 1, -10, -33, 0, 55, -41, 15, 0, 76, -17,
+ -39, 60, -20, 28, 54, -93, 15, 83, -30, 4, -56, 49, -58, 30, -28, 2,
+ 54, -64, 83, -128, 86, 24, -40, -27, -66, 51, 11, -51, 59, 6, 20, -58,
+ -24, 78, -7, -23, -27, 1, -3, -24, 10, -6, -16, 34, 39, -37, -17, 26,
+ 52, -69, -7, 11, 24, -62, 38, -13, 41, 5, -2, -5, -12, 15, 77, -49,
+ -10, 74, -12, -11, -38, 32, -24, 25, -6, 19, -24, -2, -38, 63, -91, 64,
+ -27, -11, -56, -43, 27, -41, -55, -15, 1, -4, 27, 8, 37, -57, 3, 28,
+ -11, -4, 46, -39, 3, 12, 100, -33, 39, 17, 6, 49, 5, 38, -12, 10,
+ 21, -35, 23, -6, -36, 10, -9, 3, -1, 13, -65, -40, 36, -25, -28, 5,
+ -37, -20, -14, 31, -16, -32, -16, 4, 15, -11, 26, -16, 29, -42, 46, 7,
+ 39, -1, -5, -9, 33, -31, 35, -33, -7, 17, 56, -24, 22, 14, -22, -34,
+ 44, 16, 11, -46, 43, -48, -27, 43, 36, -45, 21, 11, 0, -98, -22, 87,
+ -126, 52, -45, 34, -28, -17, -31, 23, -38, 23, 25, -11, 25, -63, 21, 13,
+ 19, 47, 28, -23, 20, 21, -5, -14, 112, -30, -67, 37, 43, -12, -57, 34,
+ -9, -29, 52, -19, 14, -51, 0, 26, -69, 3, -18, -24, -34, 31, -15, -33,
+ -36, 10, -20, -38, 63, 0, 44, -50, 72, 25, -16, -6, 6, 15, 23, 31,
+ 3, -20, -9, 19, 63, 17, -18, -5, -12, -87, 31, 26, -37, -29, 49, -42,
+ -15, 14, 11, -16, -31, 46, -19, -13, -37, 59, -91, 47, 4, -11, -26, 39,
+ -29, -24, 48, 10, 39, -11, 45, -51, -1, -24, 47, -19, 39, -34, -29, -17,
+ 1, 56, -25, -16, -13, 0, 48, -71, 49, 2, -2, -45, -10, 59, -17, -25,
+ 9, 9, 44, 42, -32, -23, -49, 46, -11, -50, 76, -43, -45, -1, 41, -8,
+ 2, 71, -36, -61, 35, 21, -13, -36, 44, -45, 26, -45, -21, 28, -37, 39,
+ -29, 15, 4, -5, 24, -7, 7, 3, 68, -80, 26, 24, -22, 8, 26, 28,
+ 10, -26, -3, 16, -51, 85, -8, -14, -54, 39, -28, -9, -25, 46, -39, -20,
+ 34, 11, -25, -7, -12, -41, 12, -17, -5, -43, -8, 0, 18, 13, 9, 28,
+ -40, 34, 0, 13, 40, -20, 5, 22, -25, -13, 51, 9, -34, 43, -16, -18,
+ 2, 35, -4, -28, 14, -37, 6, -8, 31, -49, 9, -31, 61, -55, 35, -46,
+ -37, -12, 32, 74, -59, -30, -21, 5, 38, 3, 48, -35, -42, 2, 29, 81,
+ -8, -37, 24, 42, -31, 18, -11, -21, -67, 98, -18, 11, -26, -14, -76, 11,
+ 71, -70, 30, -52, 37, -45, 61, 6, -33, -44, 58, 24, -16, -51, 49, -28,
+ 51, -6, -15, 46, 10, -24, 36, -4, 6, -30, 46, -66, 54, 27, -16, -34,
+ -23, 90, -61, -49, 22, -3, -22, 17, -35, -11, -59, 23, 2, -25, 69, -24,
+ -26, -28, 37, 12, 11, -63, 27, 18, 3, 34, -25, 9, -14, 29, 4, 24,
+ 21, -77, 12, 14, 37, 1, 45, -63, 1, 49, -14, -23, -7, -4, -42, 48,
+ -57, 18, -36, 17, 15, -37, 47, 1, -41, -14, 11, 49, -32, 32, -36, -19,
+ 21, -11, 39, -31, 43, 0, -24, 15, 6, 9, -46, 5, 21, -23, 2, -28,
+ -15, 59, -13, -29, 50, -7, -45, -12, 23, -1, 27, 6, -17, 7, -4, -3,
+ -3, 53, -10, 17, -52, 19, 24, -8, -7, 19, -51, -30, 55, -22, -22, 29,
+ -38, -25, 39, 3, 34, -84, 26, -37, 42, 15, 4, -4, -16, -33, 29, 17,
+ 43, -93, 24, -6, -20, -14, 107, -29, -36, 69, -21, 10, -7, 74, -67, 38,
+ -23, -8, 27, -35, -49, 29, -8, -4, 7, -8, 5, -38, -28, -33, 22, 70,
+ -37, -10, -56, 26, 5, 7, 59, -21, -58, 10, -2, 6, 49, -16, -9, -38,
+ 60, 13, 43, -43, 23, -14, -9, 38, 17, -38, -15, 29, 6, -5, -11, -3,
+ -4, -65, 45, -13, 26, -13, -4, -5, -38, 48, 0, 4, -40, 40, -48, 23,
+ 21, 23, -42, 5, -17, 13, -9, 12, -3, 5, -25, 34, -24, -3, -18, 16,
+ -44, 13, 27, -30, 44, -54, 6, -18, -3, 4, 21, -25, -13, 22, -20, -12,
+ 37, -10, -10, 5, 24, -17, 23, 9, 0, 4, 3, 12, 26, -27, 17, 9,
+ -41, 69, -1, 15, -37, 15, -6, 0, -1, 3, -13, -23, -18, 27, -5, 21,
+ -16, -41, -2, 20, 13, -27, 6, -21, 8, 6, 0, 6, -5, -21, -22, 73,
+ -40, 4, 6, 21, -8, -5, 29, -47, -1, 1, 19, 3, -10, -1, 2, -48,
+ -11, 45, -27, 11, -33, -21, 21, 7, 12, -22, 21, -40, 13, 27, -20, 37,
+ 5, -18, -18, 35, 40, -11, 20, -25, 10, -4, 33, 12, -29, 9, -20, -30,
+ 34, 24, -9, -10, -24, -16, 8, 22, 6, -58, -5, -13, 18, 5, -43, 10,
+ -16, -25, 13, 70, -25, -7, -25, -19, 16, 58, -46, -5, 6, -5, 40, -24,
+ 22, 50, -73, -7, 7, 32, 39, -27, -23, -23, 56, -35, 21, 17, -40, 40,
+ -52, 4, 0, 49, -29, -42, 24, 9, 31, 2, -46, 0, -9, -5, 9, -31,
+ 64, -5, -45, -26, 42, -4, -34, -8, -3, 32, -15, -8, 22, -24, 13, -31,
+ -2, 31, 10, -10, -18, 8, 24, 20, -29, 2, 14, 23, 25, -4, -19, 20,
+ -25, -5, -3, 23, -8, 52, -42, -17, -7, 29, -26, 2, -19, 55, -50, -28,
+ 1, -10, -7, 7, -41, 16, 21, 1, -20, 0, 16, -19, 14, -39, 86, -17,
+ -34, -64, 73, 0, 20, -28, 30, -22, 9, 58, -4, -8, -18, -20, 31, -21,
+ 1, 26, -49, 5, 41, -25, -13, -6, -7, 6, 10, 42, -30, -26, -43, 11,
+ 44, -54, 31, -10, -11, -17, 25, 32, -43, 64, -23, 3, -37, 33, -30, -4,
+ -35, 47, -29, 9, 23, -34, -5, 64, -37, 32, -11, -44, 21, 25, -19, 8,
+ 6, -25, 34, 2, -18, -23, 38, 20, 7, 21, 1, -32, -37, 50, -9, -25,
+ 34, -61, 55, -32, 7, -48, 20, 13, 0, -35, 17, 9, -42, -28, 14, 42,
+ -33, -25, -5, 21, 41, -60, 32, -7, 38, -9, -3, 20, -4, 29, -69, 62,
+ -16, 35, -64, 45, 10, 5, -1, -18, -18, -1, 5, 32, 0, -21, -12, -23,
+ 29, -15, 13, -39, -3, -3, 6, 35, -24, -23, -7, -2, 44, -10, -37, 25,
+ 25, -25, -23, 7, 40, 4, -40, -18, 21, -2, -3, 1, -16, 45, -26, -2,
+ -16, 18, 41, -64, 8, -26, 40, 5, -32, 8, 18, -1, 15, -1, 9, 2,
+ 2, -13, -12, 35, -9, 13, -62, -29, 72, 18, 7, -30, 26, -7, -29, 39,
+ -38, 31, -56, -25, -3, 17, 2, -3, -46, 35, 6, 27, -39, -3, 3, 31,
+ -25, -19, -2, 38, 26, -77, 22, 18, 40, 3, -22, 65, -48, 33, -16, -37,
+ 78, -34, 1, -52, 23, 16, 1, -37, 17, 12, 1, -4, 8, -27, -1, -11,
+ -18, 27, -23, -10, -11, -19, -6, -7, 51, -74, 16, 20, 17, -14, 7, 7,
+ -13, -8, -5, -11, 39, 21, -5, -44, 31, 64, -38, -18, 20, 40, -4, -10,
+ 10, -23, 23, -6, -20, 11, 9, 10, 6, -23, -11, 1, 17, -56, 56, -40,
+ 0, -17, -60, 84, -80, 16, -13, 4, -25, 12, 17, -42, -26, 54, -29, 12,
+ -5, 37, 16, -62, 94, -5, -2, -2, -2, -9, 5, 51, -25, -5, -11, 5,
+ 16, -14, -9, 43, -44, -8, 27, 2, -1, 9, -18, -6, 5, 23, -46, -9,
+ 13, 16, -10, -10, -23, 59, -47, -14, 23, 29, -15, -14, -30, 21, -21, 0,
+ 14, -3, 25, -16, -35, -2, -8, 32, -19, 22, -23, -37, 30, -33, -19, 11,
+ 12, -32, 47, -4, 27, 11, 9, -35, 39, 29, -18, -2, -11, 27, -2, 13,
+ 0, 18, -26, 15, -25, 26, -4, 21, -29, -33, 18, -8, -31, -5, 21, -1,
+ -38, -28, 41, -18, -4, -22, 47, -12, -44, 55, -79, -5, 19, -10, 25, 4,
+ 21, 15, -28, 13, -6, 45, -24, 25, 10, -26, 4, 2, 31, 3, -7, 3,
+ 5, -23, 51, -9, -32, -5, 35, -32, -21, -20, 35, -40, -10, 20, -8, 7,
+ -5, -38, -1, -24, 39, -26, 20, -16, -9, -27, 25, 34, -32, 1, 12, -13,
+ 3, 37, 13, 3, -31, 27, 30, 5, -15, -21, 2, 10, -13, 16, 36, -9,
+ -59, 41, -10, 61, -60, -35, -11, 7, 5, -28, 30, 5, -23, -66, 34, 50,
+ -26, -19, -10, 11, 8, 8, -35, -5, -11, 56, -24, 10, 35, 16, -10, -19,
+ 30, 4, -11, 23, 0, -6, 6, 36, -15, 0, 15, -14, -26, -8, -5, 15,
+ -31, -45, 42, -30, 0, -9, 6, -22, 9, -22, 7, -8, 15, -19, -3, -13,
+ 29, -14, 9, -16, 3, -5, -10, 63, 0, 4, 4, 20, 16, -21, 18, 31,
+ -24, -19, 31, 54, -39, -7, -16, 5, -3, 0, -29, 16, 6, -29, -25, -52,
+ 49, -9, -66, -3, 50, -3, -2, -14, 4, -8, 33, -40, 2, 15, -6, -17,
+ -4, 10, 48, -16, 14, -9, 27, 10, 2, 2, 40, -35, 5, -10, 7, 28,
+ 1, 4, -30, -4, 0, 1, -14, -13, -11, 26, -17, 13, -44, -9, -6, -23,
+ 17, 11, 11, -21, -11, 0, 9, 8, 8, -30, 29, 10, -26, -12, 15, 17,
+ 4, -26, 14, 19, 20, -9, -24, 39, 23, -10, -35, 8, -6, 18, -25, 15,
+ -17, 41, -48, -31, -5, 47, -14, -20, -4, -7, 5, -19, 3, 21, 12, -23,
+ 15, -24, 8, 3, -25, 2, 28, 14, 21, 25, -72, 15, 26, -6, 45, -27,
+ 29, -30, -17, 23, 6, -2, 27, -46, 13, 9, 15, -57, 27, 1, -18, 1,
+ -11, -2, -20, -16, -23, 24, 18, -21, -5, -15, -14, 26, -12, 30, -48, 37,
+ -24, -3, 23, 9, -5, 9, 8, -43, 23, 26, 6, 28, -29, 30, -8, -12,
+ 25, -18, 33, -48, -4, 29, 1, -8, -4, -20, 41, -22, 1, 12, -33, 0,
+ -17, -16, 29, -3, -2, -36, 6, -1, -11, 4, -24, 40, -24, -5, 26, -2,
+ -28, 13, -11, 35, -9, -2, -3, -6, 13, 10, 1, 11, -22, 22, -27, -5,
+ 20, 11, -1, 8, -23, 8, 7, -7, 17, -6, 16, -9, -10, 3, 13, -3,
+ -17, 19, -21, 6, -13, -15, -7, 22, -15, -7, 11, -20, -19, -6, 0, 28,
+ -10, -7, -13, 9, 7, 1, -11, -6, 21, -33, -4, 52, -11, -1, -2, -2,
+ -4, 32, 17, -31, 7, 12, 2, -5, 11, -1, -6, 1, 3, -11, 5, 4,
+ -15, -8, 10, 5, -18, 5, -26, -11, 22, -15, -23, 22, 19, -30, 3, 1,
+ -5, 10, -17, 10, -2, 10, 7, -17, -5, 36, -12, -24, 27, 22, -3, -11,
+ -6, -7, 20, 5, -21, 0, 23, -31, -27, 14, 2, 8, 7, -15, 0, 13,
+ -7, -3, -21, 33, -4, -26, 7, 5, -7, -7, 1, 3, 4, 11, -24, 6,
+ 11, -7, 14, -9, -11, -1, 34, -22, 11, 1, -18, 17, 4, -19, 28, -15,
+ -7, -11, 12, 1, -7, -9, -12, 17, -20, 6, 5, 2, -10, 12, -23, -3,
+ 26, -1, 4, 6, -25, 12, -3, -26, 2, 15, 14, -18, -6, -17, 14, 4,
+ -10, 21, -13, 5, -15, -20, 27, 6, 8, -11, 18, 15, -34, 17, -2, -13,
+ 41, -9, -10, -6, -2, 7, -11, -4, 28, -26, -6, 25, 17, -36, -2, 33,
+ -39, -15, 11, -2, 26, -32, -31, 21, 26, -11, -24, 12, -17, 4, -33, 24,
+ 14, -10, 12, -19, -3, 28, 11, -8, 0, 26, -17, -7, 8, -6, 20, 26,
+ -29, -27, 25, -14, -2, 10, -16, 39, -24, -17, -4, -13, 24, -10, -3, -20,
+ 25, -1, -24, 24, -20, -5, 21, -26, 7, 21, -26, 15, 17, 6, -34, 5,
+ 11, -27, 20, 17, -13, -8, -16, 9, 33, -36, 19, 5, 4, -2, -33, -12,
+ 38, -17, -10, -4, 19, 14, -4, -32, -41, 64, 5, -38, 28, 6, -2, -11,
+ -22, 11, 17, 17, -24, 23, -7, 9, 10, -38, 0, 25, -9, -6, -27, 20,
+ 2, -27, 34, -23, 17, -22, 4, 12, -43, 29, -8, 25, -19, 13, -17, -11,
+ 27, -8, 14, -19, 12, 9, -22, -6, 11, -10, 17, -4, 2, -3, 15, -47,
+ 32, -18, 11, 14, 0, 8, -33, -14, -12, 23, 17, -12, -4, 13, -27, 10,
+ -17, 20, -2, -11, -11, 27, 18, -21, -6, 26, -18, 9, -7, 27, -12, 3,
+ -9, -9, 22, 7, -38, -2, 14, -16, 12, -21, -10, 22, 1, -28, 20, 31,
+ -11, -49, 9, 16, -4, -7, -4, -5, 46, -39, 9, -18, 16, 22, -24, -13,
+ 14, 29, -10, 3, -23, 4, 11, -33, 30, 18, -9, 5, -11, 4, -20, 30,
+ -9, -14, -7, -9, 4, 0, 4, -15, -11, 23, 5, -24, 26, -6, -8, -17,
+ 21, 0, 3, 13, -10, -13, 19, -16, -10, -5, 10, 8, 22, -19, 4, -8,
+ 0, -24, 38, 12, -33, 10, -9, 5, -13, 11, 3, 7, -18, -12, 11, -4,
+ 8, -17, -7, 16, -9, -2, -9, 0, 10, -2, -1, -1, 12, -6, 13, -18,
+ 18, -6, 10, 1, -3, 9, -2, -30, 23, -9, 29, -11, -31, 10, 6, -21,
+ -19, 54, -30, 18, -12, -26, 23, -10, -31, 23, -5, 49, -34, 4, -18, 3,
+ 11, -24, 27, 12, -24, 3, -13, 3, 16, -6, -7, 1, 19, -8, -3, -11,
+ 13, -14, 19, 10, 17, -21, 14, -40, 12, 13, -5, -3, 21, -14, -29, 16,
+ -24, 1, 10, -1, -3, 6, -15, -16, 16, -4, 2, 23, -32, -1, 7, -5,
+ 13, 4, -15, 33, 1, -7, -7, -12, 13, 6, -8, 2, 21, 2, -21, 17,
+ -14, -19, 36, -2, -16, -4, 3, 9, 15, -39, 3, 9, -10, -3, -12, -7,
+ 28, -19, 8, -18, 22, -18, -11, -2, 17, 23, -15, -24, 11, 13, -14, -10,
+ 9, 4, 14, -10, -13, 13, -3, -12, 25, 6, -12, 12, -19, -3, 19, -10,
+ -13, 19, 10, 18, -31, -15, 19, -9, -14, -6, 25, -18, 2, 17, -41, 11,
+ 16, -20, 3, -10, 16, 9, 14, -27, -1, -3, 9, -19, 36, -6, -4, -4,
+ -16, 5, -7, 24, -1, -30, 13, -8, -4, -9, 47, -37, 3, 21, -24, 1,
+ 3, 11, 5, -10, -8, 20, -31, 16, 10, -1, 0, -9, -1, -6, 14, -6,
+ 6, -17, 20, 3, -23, 10, -14, 17, -16, -2, 26, 7, -20, -10, 9, -18,
+ 31, -35, 3, 14, -8, 13, -27, -4, -4, 26, -20, -9, 14, 22, -27, -4,
+ 18, 9, 9, 3, -13, -20, 15, -13, 6, 12, -5, -6, -12, 0, 4, -10,
+ 18, -7, -8, -15, 1, -11, 17, 5, -11, 14, -6, -11, 4, 10, -5, 13,
+ 0, -7, 15, -2, -16, 2, -3, 9, -6, 2, 34, -11, -17, -8, 21, 13,
+ -21, -4, 14, -7, -7, -19, 13, -7, 4, -25, 7, 16, -14, -40, -11, 36,
+ 3, -10, 4, -10, 7, -1, -1, 4, 14, 6, -14, -14, 17, 23, -13, -2,
+ -1, -12, 9, 8, 1, -7, 22, -29, 7, 7, 0, -24, 13, -10, 18, -1,
+ -3, 13, -24, 30, -32, -5, 18, -2, -6, -8, 11, -18, -12, 17, -11, 0,
+ 5, -4, -14, 31, -15, -16, 13, 12, -4, 4, -4, -1, -11, -15, 26, -18,
+ 29, -15, -3, -8, 6, 6, -34, 22, 0, 11, -18, 16, 20, -19, -21, -5,
+ 11, 21, 10, 10, -27, -5, 3, 2, -5, 9, -9, -1, 1, -11, -3, 8,
+ 4, 1, -1, -11, 19, -1, -21, -5, -2, 11, -2, -8, 10, -7, -1, 2,
+ -18, 3, 0, 7, 2, 7, 1, 1, -28, -14, 10, 19, 12, -21, 7, -19,
+ 20, -2, -3, -1, 17, -11, -13, -16, 32, 4, -5, -3, 4, -4, 18, -2,
+ -17, -6, 16, -3, 4, -12, 4, -2, 2, 6, -18, 20, -24, 17, -10, 19,
+ -16, -17, 8, -7, -5, 16, -12, -18, 11, 9, 2, -8, 17, -9, -3, -13,
+ 7, -6, 30, -15, -11, 5, 14, -2, -15, -5, 14, 13, -12, -24, -10, 22,
+ -2, -8, -1, 21, -5, -19, -16, 8, 42, -6, -27, -12, 23, 10, -17, -14,
+ 16, 14, -16, -2, 9, -2, 16, -9, -31, 22, 0, -2, 3, 4, -5, 20,
+ -24, -5, 13, -1, -5, -10, -6, 8, -11, 2, 8, -8, -5, -9, 1, -6,
+ 16, -1, -18, 4, 9, -3, 6, -4, 6, 9, -7, -9, -1, 10, -7, 4,
+ 3, -3, 4, -8, -5, 3, -4, 10, 6, -15, 2, 3, -5, -2, -3, -12,
+ 18, 2, -16, 7, 13, 0, -19, -8, 11, -6, -1, -9, 5, 13, -8, -6,
+ 6, 7, 11, -11, -6, 13, -2, -5, -1, 9, -2, -7, -15, 10, 5, -1,
+ -13, 8, 0, -6, -2, -2, 18, -16, -7, 2, 3, -4, 6, -11, 4, 6,
+ 1, -5, 22, -11, -5, -6, -3, 11, -1, -1, 4, 1, -4, -13, -4, 11,
+ -9, 1, 9, -1, -8, 1, -5, -7, 5, -14, 18, -1, -12, 11, -12, 16,
+ -5, -11, 11, -2, 15, -7, -18, -10, 0, 18, -12, 8, 3, 6, -16, -3,
+ 3, 6, 0, -1, -3, 4, 9, 3, -17, -7, 11, 11, -19, 5, 15, -12,
+ -3, -12, 4, 11, -19, 0, 0, -14, 21, -15, 2, 8, 3, 8, -8, 5,
+ -18, 9, -2, -8, 23, -5, -16, 5, 3, -20, 13, 11, -6, -15, 5, 4,
+ -12, 2, 10, -5, -12, 5, -14, -2, 18, 11, -14, 0, 28, -10, -20, 4,
+ 7, 9, -13, -6, 15, 11, -9, -6, 14, -8, 10, 4, -12, 11, -18, 13,
+ -17, -9, 16, -4, -14, -7, 17, -24, -5, 4, 6, -6, 14, 2, -24, -22,
+ 11, 13, 8, -16, 6, 13, -28, 10, -2, 11, 8, -1, -8, -14, 22, 3,
+ -5, -13, 18, 7, -26, 15, 20, -6, -10, 4, 11, 5, -8, -3, -5, 0,
+ -1, -6, 0, 4, 4, -14, -1, 1, 8, -14, -10, -4, 6, 4, -8, 3,
+ -9, 0, 11, -4, -7, 5, 4, 6, -29, 18, 22, -19, -16, -11, 17, 7,
+ -4, 3, -23, 20, 8, -19, 3, 13, 13, -16, -18, 15, -6, 0, 3, 17,
+ -7, -4, 2, -22, 21, -1, -2, -1, -15, 13, 3, -7, 4, 0, -7, 8,
+ -7, 11, 3, -2, -8, 10, -15, 0, 9, -14, -8, 8, -2, -9, 10, -13,
+ 9, 7, -6, 2, -12, -4, 6, -12, 8, 12, 3, -10, 6, 7, 1, -2,
+ -11, -1, 7, -7, 8, -13, -10, 11, -9, -10, -8, 20, 9, -11, 8, -5,
+ -4, 6, -3, 5, 13, -13, -7, -7, 6, 19, 0, -9, 9, -1, -3, 4,
+ -7, 0, -2, -4, -5, 5, 0, -5, 14, -19, -14, 18, -1, -5, 3, -12,
+ 18, -19, 4, -15, -10, 10, 10, -17, -4, 19, -6, -2, 5, 11, -4, -3,
+ 9, -22, 28, -6, -5, 0, -1, 11, -11, -13, 22, 3, -8, -9, 1, 3,
+ 0, 1, 2, 7, -5, -25, 10, 6, 6, 2, -11, 8, -16, 15, -20, 5,
+ 9, -6, -13, -5, 14, 6, -21, 22, -7, -14, 4, 26, -8, -13, 8, 1,
+ -10, -13, 11, 10, -10, 2, -13, -9, 15, 0, 10, -30, 14, 7, -13, -5,
+ -12, 8, 10, -4, 10, 12, -15, -7, 5, 2, 2, 10, -13, -3, 0, 21,
+ -2, -16, 9, 3, -1, 6, 15, -3, -21, 10, -8, 5, 1, 1, 2, -19,
+ 10, -7, -3, -1, 8, 6, -26, -10, 18, -28, -3, -3, 4, 0, -7, 6,
+ -10, -2, 25, -19, 5, -11, -2, 14, 4, -5, -3, 4, -5, 6, -2, -3,
+ 11, -1, 13, -12, 5, 20, -15, -3, 17, 4, -14, -5, 11, 3, 1, 6,
+ 11, -20, 10, -4, -4, -4, -4, -18, -7, 5, 10, -25, 7, -9, -15, 1,
+ -4, 4, 4, -4, -1, -18, 9, -6, 4, 7, -19, 10, 0, 3, -6, 12,
+ 18, -5, 2, 4, -4, 11, 2, 5, 2, 1, 3, -4, 3, 4, -3, -2,
+ -8, 11, 5, -10, -12, 12, -6, 6, -9, -6, 4, 9, 0, -9, 4, 3,
+ -7, -5, -12, 19, 2, -28, 1, 0, 9, -10, -6, 3, 3, -11, -4, 6,
+ 7, -7, -3, 5, -12, 9, 10, -12, 7, 5, 5, -6, -9, 16, 6, -16,
+ 3, 8, -17, 12, -5, 2, 1, 21, -25, -10, 5, -2, 15, -6, 1, 3,
+ 5, -16, -2, -16, 32, -17, 7, -13, 6, -1, -4, 0, -4, 10, -2, -17,
+ -7, 29, 0, -13, -1, -1, 2, 12, -4, 3, -2, 4, -19, -1, 18, 2,
+ -3, -15, -2, 10, -4, 1, -2, -5, 20, -5, -6, -7, 9, 0, -2, -24,
+ 5, 15, -2, -11, 1, 0, -2, -14, -2, -4, 7, 4, -4, -9, 2, 4,
+ -8, 8, -1, 2, 10, -13, 4, 10, -4, 27, -22, 17, -18, -2, 5, 8,
+ -1, 4, -6, 2, -1, 9, 1, -3, 16, -21, -18, 2, 10, -14, 9, 3,
+ -14, -9, 0, -16, 9, -10, 11, -12, -3, 1, -10, 3, -2, 2, -13, 13,
+ 10, -1, 4, 4, 1, -3, 9, 0, 4, 8, -14, 10, -4, 0, 8, 11,
+ -2, 2, -11, 3, -13, -8, 11, 4, 1, -7, 4, -21, 0, 1, -4, -22,
+ 17, -8, -16, 10, 4, -2, 0, -4, 2, -2, 2, -6, 10, 3, 3, 5,
+ -1, 6, 5, 2, -6, -3, -2, 7, -4, -4, 12, 1, -30, 12, -7, 3,
+ 4, -6, -7, -9, 9, -1, 7, -10, 12, -16, 2, -8, 23, -5, -5, -1,
+ -8, 10, 3, -14, -12, 25, 7, -13, -6, 4, 15, -3, -23, 9, 12, -9,
+ -13, 18, -9, 5, 1, -17, -4, 13, -10, 11, -10, -1, 6, 0, -7, -2,
+ 9, -4, 9, -24, 7, 6, -5, 4, 15, -15, 11, -5, -24, 9, 11, -16,
+ 2, 0, -9, -2, 10, 7, -12, 8, -12, -6, 10, 6, 10, -14, -5, 20,
+ -16, 7, 8, -1, -19, 24, 2, -10, 15, 6, -6, -21, 3, -3, 15, -9,
+ -3, 3, -2, -4, -3, -9, 5, 0, -5, -3, -15, -4, -1, 1, -14, 33,
+ -12, -18, 9, -2, -10, 9, 9, -1, -1, -5, 10, -3, 2, 4, 2, -9,
+ -1, 25, -2, -3, 15, -17, -7, 8, -7, 0, 10, -13, 9, -11, 0, -3,
+ 18, -15, -11, 5, 0, -12, -2, 7, -6, -4, -9, 11, -6, 8, 1, -14,
+ 3, 16, -10, -3, 2, 6, 4, 9, -9, -2, 0, 2, -3, 15, 3, -10,
+ -4, -8, -1, 10, -13, -9, 16, -9, -3, -2, 5, -6, -6, -9, 10, 8,
+ -4, 14, -7, -19, 12, 1, 2, 1, 4, -1, -6, -3, -3, 5, 7, -2,
+ 0, 0, -5, 0, -6, 1, 6, -5, -4, 5, -6, 5, -4, -8, 15, -5,
+ -7, 0, 3, -8, 0, 3, -8, -4, 6, -4, -4, 15, -5, -8, -7, 4,
+ 7, -10, -6, 15, -4, -13, 7, 2, 2, 1, -4, 5, 0, 0, 1, 4,
+ -7, 4, 4, -2, 4, 5, 1, -18, 12, 4, -3, -6, 11, 0, -13, -1,
+ 1, -12, 3, 13, -9, -15, 7, 0, -4, -8, 0, 5, 0, -9, 1, 1,
+ -3, 0, 3, 5, -10, 6, -1, -4, 4, 15, -15, -5, -9, 18, -2, 0,
+ 15, -11, -9, 0, 6, -2, 8, 1, -8, -9, 7, 3, -7, -3, 6, 1,
+ -5, 0, -5, -5, 0, -3, 11, 1, -3, -8, -4, -4, 5, 9, -6, -7,
+ 4, 15, -13, 5, -4, 2, -6, -2, 0, 5, 4, -4, 0, -6, 8, 3,
+ -2, -4, -4, -11, 4, 10, -1, -4, -2, -1, -3, 1, -4, -2, 3, 1,
+ -4, -11, 12, -4, 5, -2, 7, -12, -2, 4, -4, 5, 8, 1, -8, 14,
+ -11, -1, 1, 4, 0, 5, -5, 2, -7, -7, 10, 3, 1, -13, 0, -4,
+ 5, -9, -1, 1, -11, -5, 5, 2, -6, 5, -5, -8, 12, -2, 7, -1,
+ -10, -5, -7, 14, 9, 3, -5, -2, 5, 4, -2, 0, -5, 2, 3, 3,
+ -12, 6, 3, 2, -9, -1, 24, -13, -9, -1, -2, 0, 7, -6, -17, 14,
+ -12, -5, 10, 1, -4, -1, -1, 1, -3, 2, -2, -11, 1, -1, -1, 1,
+ 10, -3, 2, 1, 5, -7, 1, -1, -5, 7, 1, 7, -4, 5, -11, -8,
+ -8, 7, 8, 6, 0, -15, -1, 7, 0, -6, -3, 7, -4, -3, -2, 1,
+ 5, 8, -6, -4, 11, 3, -14, -6, -3, -6, 9, -5, 4, -5, 2, 3,
+ -13, -3, 1, -4, -3, 11, -1, 0, 7, -16, -6, 11, 5, 0, 4, 5,
+ -2, -3, -2, 8, 7, -16, 1, 2, 6, 3, -17, 11, -2, -2, -9, 6,
+ 0, -7, 6, -22, -2, 14, 3, -11, 0, -6, -2, -7, -7, 1, 4, 14,
+ -1, -6, 0, 7, 3, -14, 4, 15, -4, -9, -2, 12, 14, -10, 5, 9,
+ -11, -2, -9, 2, -9, 11, 2, -21, 7, 6, -11, -1, 0, 0, 1, -9,
+ 4, 0, -10, 1, 3, -3, -7, 12, -9, -2, 4, 6, 3, -8, 0, 1,
+ -2, -14, 12, 11, -5, 10, -3, -1, 3, -6, 1, 0, -3, 8, -1, -18,
+ 12, 5, -13, -4, 17, -1, -6, 1, -11, 0, -6, 2, -2, -2, 5, 3,
+ -17, 2, -5, 11, -4, 8, 8, -19, -6, 14, -6, -6, 0, 5, 0, -8,
+ 7, 13, -6, -5, 6, -2, -9, -1, 8, 3, -4, -4, 10, -10, -9, 7,
+ 2, -6, 14, 0, -15, 3, 5, -4, -10, 8, 0, -6, -11, 3, 10, -9,
+ 1, 8, -7, 2, -1, -6, -8, 6, 2, -8, -2, 16, -3, -3, -1, 5,
+ -3, -8, 6, 9, -6, 1, -1, -1, 2, -6, 6, -1, -9, 3, 9, -10,
+ 1, 5, -4, -14, 2, 1, 7, -5, 3, -2, -13, 5, 10, -9, -8, 14,
+ -6, -19, -3, 19, -3, -3, 6, -4, -10, 3, -1, -4, 5, 5, 1, 0,
+ -1, 11, 4, -10, 3, -5, 4, -7, 1, 8, -3, 1, 2, 0, -10, 2,
+ 5, -15, -3, 8, -8, -6, 5, -2, -5, -5, 11, 0, -12, -7, 5, 2,
+ -5, 2, -1, -4, 2, 7, -12, 5, 6, -3, 5, -1, 12, 7, -13, -3,
+ 0, 3, 0, 13, -1, -4, 0, -9, 5, -6, 5, -2, -10, -6, -2, 9,
+ -8, 5, -6, -10, 5, 4, -6, -2, 1, 1, 6, -14, 10, -3, -4, -5,
+ 1, 8, -16, 7, 7, -1, 0, 3, -5, 2, -1, -3, 11, -11, 9, 8,
+ -18, 3, 8, 13, -4, -5, -9, 4, -2, -4, 9, 5, -6, -5, -15, -3,
+ 17, -6, 2, -8, 4, 4, -4, -12, -3, -2, -2, -4, 5, -4, 1, 7,
+ -12, -6, 8, 6, -2, 1, -3, 3, 10, -3, 7, -11, 12, 4, -1, -1,
+ 1, 0, -11, 11, 4, 0, -2, -9, -2, -2, -8, -1, 5, -4, -5, -5,
+ 1, 10, -8, -11, -5, -4, 5, -1, 1, 6, -2, -5, -5, 3, 6, -2,
+ 6, -3, 0, 4, 5, 2, 4, -2, 1, 5, -2, -6, 11, -1, -5, 8,
+ -14, 6, -2, -6, -11, 4, 2, -14, 6, -9, 5, -4, -3, 4, -12, -2,
+ 2, -5, 4, 7, -5, 3, 6, -1, -3, -6, 0, 7, 0, 1, 6, 9,
+ 4, -2, -7, -4, 7, 4, 4, -5, -5, 0, 3, -6, -1, 7, -2, -18,
+ -1, 3, -15, 5, -2, -2, 0, 4, -10, -4, 3, 4, -10, 4, -1, 5,
+ 4, -7, 8, -7, 0, 3, 2, -7, 13, 0, -2, -6, -6, 5, 10, -10,
+ 4, -1, 2, -1, -5, 7, 5, -3, -7, 1, -5, 10, 1, -11, 7, 6,
+ -10, -15, 12, 2, -4, 1, 0, -5, 3, 0, -2, 6, -5, -4, -13, -2,
+ 3, 1, 4, 3, 3, -10, -7, -7, 11, -2, 2, 2, -7, 4, -1, 6,
+ 2, 0, 8, 3, 0, -7, 8, 3, 5, -8, -3, -2, 2, 3, -12, -4,
+ -3, 12, -12, -4, 7, -3, -10, -10, -4, 6, -2, -8, 9, 1, 1, 1,
+ -3, -6, 12, -5, -6, -1, 11, -7, 5, 6, 2, 9, -11, 6, -2, 8,
+ 1, -6, 4, 3, -6, -3, 5, -4, 4, 1, -19, -1, 3, 4, 0, 0,
+ -10, -1, -3, -5, -3, 0, 11, -1, -12, -2, 6, 0, -3, 3, 4, -1,
+ -7, 1, -2, -1, 2, -1, 0, 2, -2, 4, -5, -4, 11, -4, -5, -3,
+ 7, 5, -8, 3, 6, -9, 0, 9, -5, -2, 5, -4, -6, 0, 7, -1,
+ -2, 0, -1, -6, -9, -6, -1, 8, 4, -1, -9, -5, 13, 2, -11, -5,
+ 9, 0, -8, -1, 5, -2, -5, -3, -2, 7, 5, -4, -13, 3, 11, -8,
+ 3, 0, 2, 5, -12, -6, 6, 3, -4, -1, 8, 1, -5, -7, -6, 2,
+ 8, 5, -2, -9, 7, -6, -2, 13, -7, 2, 1, -1, -5, 3, 7, -1,
+ -11, 9, -6, -4, -2, -5, -1, 2, -1, 3, 8, -7, -1, -9, 0, 0,
+ -1, 2, 5, -2, 1, -2, -3, 6, 6, -3, -6, -5, 4, -1, 1, 5,
+ 1, -1, -2, -3, -4, 4, 3, 1, -7, 5, -1, 0, -8, -6, 1, 7,
+ -3, -6, -2, 3, -1, -3, 2, 2, 0, -9, 1, -2, 4, 4, -5, 1,
+ -1, 1, 6, -2, 2, -5, -4, -1, 14, -3, 2, -9, 1, -2, -4, 1,
+ -1, 7, -9, 5, 2, -3, 2, -2, -9, -2, 4, -1, 2, -2, -2, 0,
+ -1, -1, -2, 3, 1, -1, -3, -6, 3, 7, -5, -3, 9, -5, -4, -5,
+ 8, -4, 2, 2, 8, -10, -1, 8, -14, 0, 6, -7, -1, 2, -3, 2,
+ -4, 5, 2, -5, -4, 5, 1, -6, 3, 6, -4, -1, -3, 3, -7, 0,
+ 1, 0, -4, 7, 6, -13, -3, 3, 2, -15, 8, 3, -3, -6, 9, -4,
+ -1, 9, 1, -6, -6, 7, 1, 1, -2, 6, -1, -4, -1, -1, -7, 5,
+ 3, 0, -5, -2, 8, -2, -8, 6, 7, -16, -5, 6, -6, -1, 1, 7,
+ -4, -3, -6, 3, -10, -3, 8, -9, -1, 5, -1, -7, 5, 2, -1, 1,
+ 5, 1, 2, -4, -5, 1, 1, 3, 1, -5, -2, 3, 2, -7, -1, 7,
+ 5, -5, -7, 5, 0, 3, -1, -4, -4, 4, 0, -4, 1, 6, -3, -7,
+ 0, -3, -3, -1, 0, -2, -4, 2, 1, -2, 3, -1, 0, -1, -6, 9,
+ -5, 4, -1, -1, 4, -2, 5, -8, 2, -3, -2, 2, -3, 10, 2, -3,
+ -5, 2, -4, -1, -3, -7, 9, 1, 0, 0, -5, 1, -2, -12, 6, 8,
+ -18, 4, -1, 4, -1, 5, -5, -3, 3, -1, 4, -5, 9, -5, -4, -5,
+ 2, 5, -1, -4, 0, -3, -2, 8, -5, 2, 1, -13, 3, 1, 4, 5,
+ -8, 2, 8, 1, -1, 1, -9, 1, -2, -4, 1, 4, -3, 4, -4, -5,
+ 6, 5, -6, -3, -3, 1, 1, -7, 1, 2, 1, -5, -4, -2, 2, -6,
+ 6, 3, 7, -10, -9, 4, 1, -5, 6, 9, 3, 1, -2, -4, 3, 4,
+ -1, -6, 3, 1, -2, -9, 4, 4, -5, 4, -10, 2, -4, -5, -1, 1,
+ 2, 0, 2, -8, 1, 3, -4, -13, 0, 10, -1, -4, 5, 0, -4, 5,
+ -3, 2, -5, 2, 1, 2, 4, 2, 2, -10, 5, 3, -11, -2, 3, 3,
+ 0, -6, -2, 1, 1, 2, -1, -8, -1, -5, -4, -3, 5, 8, -4, -4,
+ 2, 0, -2, -2, 1, -5, 0, 13, -8, -6, 4, 8, -6, -1, 6, -2,
+ 4, -5, 3, 5, -7, -8, -2, -3, 7, 8, -8, -3, 1, 5, -5, -5,
+ 9, -4, -7, -5, 4, 3, -6, 5, 1, -1, 3, 0, -6, -9, 0, -6,
+ 1, 4, 10, 5, -13, 0, 6, -2, -4, 2, -2, 6, -1, -4, 0, -11,
+ 6, 3, -1, -3, 14, -1, -15, 1, 2, 3, -1, 4, -3, -6, 0, 3,
+ 0, -6, 10, -3, -14, -2, 10, -3, -9, -4, 0, 6, -1, 7, -3, -5,
+ -6, 1, 0, -5, 11, -2, 1, -2, 5, -1, -4, -1, -3, -4, 2, 11,
+ 2, -4, 1, 2, -12, 7, 3, -1, -11, 3, 15, -8, -11, 0, 0, 2,
+ -7, 1, -3, -4, -3, -5, -4, 6, 11, -7, -8, -1, 6, -5, -3, 6,
+ 8, 3, -6, 1, -1, -1, -1, -5, -3, 8, 7, 4, -9, 1, -2, -4,
+ -6, 9, -4, 3, -8, 0, 6, -2, -4, -2, -2, -6, 8, -7, 3, 1,
+ 3, -1, -3, 2, 1, -6, -9, 3, -5, 8, 5, -10, 7, 5, -3, -2,
+ -1, -3, -1, -4, -7, 6, 6, 3, -7, 0, 0, 1, 0, -7, 3, -1,
+ 0, 1, 2, 2, 2, -11, -8, 9, 6, 2, -6, -1, 1, -3, 3, 1,
+ -6, 2, -3, -2, -1, 2, -4, 0, -4, -2, 0, -3, -2, -6, 5, 2,
+ 0, -1, -3, -1, 3, 1, -2, 0, 2, 2, 0, 1, 7, 1, -4, -2,
+ -6, 4, 3, -1, -4, -1, 3, 3, -9, -2, 0, -2, -1, -5, 6, 1,
+ -5, 1, -5, 9, -10, -4, 0, -4, 6, 1, -3, -5, 9, -2, -5, 2,
+ 0, 6, -6, 2, 5, 10, -8, -3, -2, -1, 4, -3, -1, -4, 0, -1,
+ 1, -4, 0, 5, -8, -1, -5, -1, -1, 3, 3, 3, 2, -14, -5, 1,
+ 2, 3, 1, -1, 2, 5, -2, 2, -5, 2, 3, -2, -2, -3, 4, 4,
+ 4, -6, 3, 1, -10, 1, -6, 6, -2, -3, 0, -3, 1, -3, 1, -1,
+ -4, -5, -4, 7, -2, -2, -3, 6, -5, -5, 2, -6, 1, 4, 3, -8,
+ 11, 4, -4, -1, 2, 3, -5, -2, 1, 7, -4, 2, 4, -10, 7, -7,
+ -1, 0, -3, 5, -4, -1, -4, 5, -7, 3, 3, -11, -2, -1, 5, 1,
+ -1, 0, 6, -11, 0, 1, -2, 1, 0, -1, -4, 2, 9, -2, -9, -4,
+ 2, 0, 2, -1, 1, 1, -7, 5, -3, 4, -1, -3, -8, 5, 7, -1,
+ -1, -3, 3, -7, 0, 4, -3, -3, 1, 6, 0, -1, 0, -5, -1, 0,
+ -4, 0, 0, -3, 1, -4, 1, 7, -3, -13, -2, -2, -1, 3, 5, 2,
+ -6, 1, 6, -2, -6, 8, -1, -6, 0, 4, 6, -2, 0, -2, -4, 3,
+ 5, -4, -7, 2, 5, -3, -3, 3, 1, -10, -7, 3, 1, -3, 2, 4,
+ -7, -3, 0, 2, -5, -3, 3, -2, 0, 3, 5, -6, -1, 4, -2, 0,
+ 5, 1, -2, -2, 3, 2, -1, -3, -3, -7, 7, 3, -1, -2, 0, 0,
+ 1, -2, 1, 0, -15, -1, 3, 2, -3, 4, 0, -7, 0, -1, -1, -4,
+ -3, 2, -1, -1, 11, -3, -1, -5, -1, 2, 2, 0, 1, 2, 3, 4,
+ -6, -3, -2, 1, 0, -4, 2, 1, -1, -5, 1, -1, -7, 2, -2, -5,
+ 0, 2, -2, 3, 5, 0, -2, -6, 6, -7, 3, -4, -6, 1, 6, 3,
+ 1, -2, -3, -4, -6, -1, 7, -2, 0, -3, 0, 9, -3, -5, -1, 3,
+ 0, -1, -3, 6, 1, -6, -3, 3, 6, 0, -6, -4, 2, 1, -1, 2,
+ -5, 4, 1, -2, -5, 0, 7, -9, 3, -1, 1, -6, 0, -5, -1, 1,
+ -1, 0, -4, 2, -2, -2, 1, 6, -1, -5, 0, 0, 0, 1, 3, 2,
+ 2, -1, -3, 0, 1, 5, 1, -5, -7, 2, 6, -3, -3, -3, 2, -7,
+ -5, 5, 0, 0, -3, -4, -1, 3, -4, -5, 1, 5, -1, -2, -4, 0,
+ 5, 2, 0, 2, 2, -1, -1, -5, 5, 3, -1, -4, 1, 0, -1, -2,
+ -1, 2, 2, -4, -4, 2, -2, -3, -4, -3, 0, 3, -3, -2, -2, 4,
+ 1, -2, -2, 1, 2, -6, -1, 2, 6, 1, -2, 0, 4, -3, -1, -2,
+ -1, 5, 1, -11, 4, 3, -1, -6, 2, -2, 3, -4, -8, -2, -1, 4,
+ 0, 3, -2, -1, -2, -2, 1, 3, 3, -7, 0, 2, 10, 0, -4, 3,
+ -3, 0, 0, 3, -4, 6, -4, -8, 2, 1, 3, -14, 1, -1, -2, 0,
+ 0, -5, -1, 2, -6, -1, 3, 0, -5, -3, 3, 1, 6, -2, 0, 6,
+ 2, -7, 1, 3, -5, 5, 8, 0, -1, 1, -4, -6, -2, 6, 4, -4,
+ -1, 1, -10, 0, -4, 0, -3, 2, 0, -8, 3, -3, 0, 2, -1, 1,
+ -8, -1, -1, -3, -1, 4, 1, 6, 1, 0, 0, -2, 0, -2, 7, -4,
+ 3, -1, 2, 0, -2, -2, -8, 3, 2, -1, -4, 3, 0, -3, -5, 2,
+ -3, -3, -2, 5, 2, 1, 1, -4, 1, -1, 4, 6, -4, 0, -6, -4,
+ 1, 3, 3, -1, -2, -7, -1, -3, 6, -6, 2, 1, 5, -8, -5, -1,
+ 2, -1, -3, -1, -1, 5, -7, 3, 3, 1, 4, -4, -3, -3, 8, 1,
+ -2, 4, 4, -2, -8, 2, 1, 0, 2, 0, -6, 3, -2, -8, -2, 5,
+ -1, -6, 0, 2, -1, -5, -2, -2, 6, 0, -5, -2, 3, 0, -5, -1,
+ 6, 7, 2, -8, -4, 6, 2, -6, -4, 12, 2, -5, -2, -6, 1, 1,
+ -3, -7, -3, 11, -3, -6, -1, 3, -2, -4, -4, 4, -3, 4, -2, -3,
+ 1, 7, 0, -8, 7, 1, -2, -4, -6, 13, 0, -3, 1, 2, -1, -4,
+ -3, 1, 3, -2, -3, -1, 0, 3, -1, -10, -1, 2, -8, -3, 3, 2,
+ 1, 4, -6, -2, 1, -3, -1, -4, 6, 5, -1, -5, -1, 9, -2, 0,
+ -4, 0, 1, -3, 4, -5, 1, 3, -4, -6, 0, 4, -2, -6, 9, -1,
+ -3, 2, -4, 0, 4, -7, -4, -1, 1, 4, 0, -1, 6, -2, -2, 4,
+ -3, -1, -6, -2, 2, 3, 1, -3, 8, -10, -10, 7, 0, -2, -1, -4,
+ 3, -6, 0, -5, -5, 5, 3, -6, 1, 5, 0, -1, 1, -1, 0, 0,
+ 0, -5, 7, -2, -1, 2, -1, 3, 0, -6, 4, -3, -2, -3, -2, 1,
+ 3, 3, 0, -2, -1, -9, 2, 2, -1, 4, -4, 4, -10, 7, -8, 2,
+ 1, -1, 0, -1, 4, 2, -7, 7, -6, -4, 3, 11, -5, -6, 1, 3,
+ -4, -6, 2, 2, -2, -3, -7, -4, 6, 0, 7, -13, 6, 2, -9, -2,
+ -5, 3, 8, 0, 0, 5, -5, -4, 3, 0, 2, 4, -7, 0, -1, 10,
+ -3, -6, 7, 2, -1, 0, 6, -2, -7, 4, -2, -1, -2, 1, -3, -9,
+ 6, 0, -4, 0, 3, 3, -11, -4, 7, -16, -2, 0, 2, 1, -2, 2,
+ -5, -1, 12, -6, 2, -7, 2, 6, 0, -4, -1, 1, -3, 2, -1, 0,
+ 7, -2, 2, -6, 2, 7, -9, -4, 8, 2, -9, -3, 8, 1, -1, 4,
+ 5, -11, 2, 1, -1, 0, 0, -6, -2, 2, 6, -13, 2, -3, -8, 1,
+ 1, 3, -2, -3, -2, -7, 4, -6, -2, 3, -10, 5, -2, 1, -3, 5,
+ 8, -4, -1, 2, -1, 6, 2, 3, 2, -2, 0, -1, 0, 4, 1, -1,
+ -2, 7, 1, -7, -5, 7, -5, 2, -5, -4, 0, 3, 3, -2, 0, -1,
+ -9, -4, -9, 10, 1, -14, 0, -1, 6, -8, -3, 3, -1, -6, -1, 5,
+ 3, -5, -1, 3, -6, 5, 7, -10, 5, 5, 2, -4, -3, 9, 4, -11,
+ 0, 5, -11, 7, -6, 2, 2, 12, -15, -8, 2, -3, 7, -5, 3, 3,
+ 1, -10, 0, -9, 17, -11, 7, -6, 2, 1, -3, 0, -1, 5, -2, -10,
+ -4, 16, -1, -7, -1, -3, 1, 11, -3, 1, -3, 2, -12, -2, 12, 3,
+ -1, -10, -2, 6, -3, 1, -1, -4, 12, -1, -2, -7, 6, -1, -1, -16,
+ 5, 11, -3, -7, 1, -1, -2, -6, -4, -5, 3, 4, -3, -8, -1, 3,
+ -5, 3, 1, 2, 6, -10, 1, 7, 0, 21, -15, 11, -12, 0, 1, 4,
+ 1, 4, -4, -1, 3, 7, 0, -5, 10, -15, -14, 2, 6, -11, 5, 3,
+ -10, -6, -1, -11, 4, -9, 6, -9, -2, 2, -8, 3, 0, 2, -9, 7,
+ 7, 2, 2, 0, 3, 1, 6, 0, 3, 6, -10, 6, -4, 1, 7, 9,
+ -1, 0, -7, 1, -11, -8, 9, 4, 0, -6, 2, -16, 0, 1, -2, -16,
+ 10, -7, -12, 7, 4, -1, -1, -4, 2, -1, 2, -5, 8, 3, 3, 4,
+ -2, 4, 3, 2, -4, -2, -1, 5, -5, -3, 9, 2, -22, 8, -6, 1,
+ 3, -5, -4, -6, 7, 0, 5, -8, 9, -13, 0, -6, 18, -3, -3, -1,
+ -6, 7, 3, -11, -9, 19, 6, -10, -6, 3, 12, -2, -18, 7, 8, -7,
+ -10, 14, -8, 5, 1, -15, -4, 11, -6, 9, -8, -1, 5, 1, -6, -2,
+ 7, -3, 7, -20, 6, 5, -4, 3, 12, -12, 11, -4, -22, 7, 9, -13,
+ 1, 0, -8, -1, 9, 6, -10, 5, -9, -5, 8, 5, 8, -12, -4, 16,
+ -14, 7, 6, -1, -16, 21, 2, -9, 13, 5, -4, -19, 2, -3, 12, -7,
+ -2, 3, -2, -4, -3, -8, 4, 1, -4, -4, -14, -3, -1, 1, -11, 30,
+ -11, -16, 8, -2, -9, 8, 8, -1, -1, -5, 10, -4, 1, 4, 3, -8,
+ -1, 23, -2, -2, 14, -15, -7, 7, -7, 0, 9, -12, 8, -10, 0, -3,
+ 16, -13, -11, 5, -1, -10, -2, 6, -5, -4, -9, 10, -6, 7, 1, -13,
+ 2, 14, -9, -3, 2, 6, 4, 8, -8, -2, 0, 2, -3, 14, 3, -10,
+ -4, -8, -1, 10, -13, -8, 15, -9, -3, -2, 5, -5, -6, -9, 9, 7,
+ -4, 14, -7, -18, 12, 1, 2, 1, 4, -2, -6, -3, -2, 5, 7, -2,
+ 0, 0, -4, 0, -6, 1, 5, -5, -4, 5, -6, 5, -4, -8, 15, -5,
+ -6, 0, 3, -8, 0, 3, 0, -1, 0, -4, 6, -16, 22, -7, 3, -5,
+ 2, 2, 1, -3, 4, -8, 4, 4, 0, -5, -9, 4, -5, -4, 3, 2,
+ 1, 3, -4, 6, -15, -1, 4, 1, -9, 3, 1, -8, 3, -6, 11, -5,
+ 6, -11, 17, -15, -2, -19, -11, 1, -4, 8, 0, 5, 18, -11, 0, 13,
+ -4, 6, -13, 4, -11, -1, -7, -7, 11, 10, -9, 17, -11, 20, -6, 7,
+ -14, 23, -7, -2, -2, 7, -10, 2, 0, 2, 5, 6, -8, 5, -4, -10,
+ 9, -4, 6, 0, -7, 8, -7, 1, -20, -4, -1, -3, 6, -10, -6, -15,
+ -11, 10, -5, 19, 3, 1, -19, -11, -1, -9, 9, 22, 24, 10, -5, -18,
+ -8, -23, 14, 11, 0, 31, 43, -9, 0, -7, -15, -28, -35, -30, 3, 5,
+ -5, 11, 52, 55, 7, -5, -10, -12, -25, -43, -12, 4, -37, -47, -21, -5,
+ 4, -11, 1, 31, 27, 34, 46, 48, 61, 10, 16, 8, 7, -14, -40, -47,
+ -36, -51, -42, -15, 4, 12, -32, -42, -10, -4, 10, 1, 15, 50, 31, 5,
+ 15, 38, 37, 29, 15, 22, 11, -4, -35, 10, 3, -18, 1, -14, -33, -5,
+ -47, -25, -13, -2, 15, -6, 5, -29, -17, -19, -1, 3, 7, 2, 17, 28,
+ -8, -23, 7, 7, 36, 15, 2, 1, -2, -9, 1, 6, 20, 6, 14, -3,
+ 21, -11, -12, -35, 11, -20, -18, -36, -23, -27, -19, 1, 10, 14, 27, 6,
+ 44, 14, -9, 3, 20, 27, 45, -8, -13, 16, -16, 24, -10, -9, -3, -38,
+ -19, -14, -38, -38, -41, 13, 40, -37, 5, -7, -7, -4, 4, -31, 32, 22,
+ 15, 9, 13, 10, 10, -17, 22, 30, 9, -6, 27, 66, 47, -17, -21, -20,
+ -9, -36, -73, -3, 22, -35, -12, 6, 7, 4, -17, -45, 22, 17, -17, 3,
+ -9, -4, 11, -10, 13, -4, 8, 38, 3, 20, 42, -22, 9, 23, -28, -21,
+ 3, 10, 1, 26, -28, -18, -9, 7, -30, -41, -24, -9, 10, -6, 31, -5,
+ 2, 29, -9, 1, -27, -24, 7, -19, -5, 10, -13, 21, 21, 3, 30, -11,
+ -17, 34, -11, 8, 7, -8, 1, 11, -1, 7, -13, 1, -3, 23, -12, 8,
+ -19, -3, 20, -78, 42, -23, 4, -29, -16, -5, 38, -49, 30, -26, 26, 16,
+ 8, -33, 53, 19, -20, 12, 5, 23, -11, 4, -6, 42, -111, 67, -40, 29,
+ -32, -20, -77, 113, -46, -12, 8, -5, -14, 35, -52, 94, -5, -61, 58, -36,
+ 41, -83, 21, -19, 61, -68, 37, -37, 12, 66, -69, -16, 100, -88, 48, 21,
+ -39, 73, -24, -2, 45, 65, -59, 53, -103, 95, -97, 1, -14, -4, -41, 9,
+ -13, -18, 16, -26, 9, 26, -15, 25, -16, 6, 8, 26, -52, 35, -21, 4,
+ -2, -11, -4, 22, 0, 21, -40, 65, -6, -13, -11, -7, 32, -46, -48, 16,
+ -26, -3, 0, -42, 87, -68, 34, 17, -14, 43, 23, -15, 30, 20, 47, -19,
+ -33, -12, 15, 1, -37, 15, -12, -11, -7, 15, -75, 36, -41, 27, -8, -7,
+ -12, 10, -4, 49, -6, 42, -32, 4, 20, 33, -65, 24, -52, 10, 13, -17,
+ -15, 60, -14, -55, 35, -16, 50, -83, -3, 29, 58, -75, 71, -46, 47, -32,
+ 44, -57, 10, -43, 33, 22, -48, 51, -41, 6, 7, 39, -3, -41, 7, -9,
+ 37, -66, 22, 26, -13, 74, -87, 127, -39, -16, -29, -11, -8, -57, -15, -45,
+ 52, -74, -5, -2, 103, -126, 85, 20, 28, -7, 53, -38, 58, -10, -11, 33,
+ -70, 20, 1, 40, -36, 26, -58, 58, -23, 61, -71, -7, -39, 43, 22, -18,
+ -1, -61, 90, -37, 35, -58, 30, -62, 27, -45, 47, -59, -6, -35, 70, -49,
+ 9, -30, 92, -15, 21, 1, 26, 6, -19, 90, -43, 49, -46, 10, 6, 15,
+ -90, 67, -51, -11, 4, 28, -36, 24, 41, -68, 24, -34, 63, -40, 17, -30,
+ 18, -39, 14, -38, 15, 9, -54, 54, -20, 36, -21, -14, -13, 11, 23, 11,
+ -54, 56, -25, 37, -46, 49, -74, 81, -40, 51, -44, 57, -69, 51, -50, 61,
+ 27, -112, 111, -114, 106, -85, 49, -61, 75, -18, 26, -68, 32, -15, -25, 21,
+ -15, 38, -46, 80, -119, 126, -85, 41, -40, 77, -65, 28, -6, -39, 45, -87,
+ 39, -63, 81, -32, 4, -32, 44, -25, 42, -12, -15, 21, -1, -56, 21, 23,
+ -30, 33, -28, -3, 32, 4, -36, 60, -20, 13, -3, 22, -43, 101, -88, 59,
+ -53, 18, 8, 22, -33, -52, 34, -32, 35, -90, 112, -107, 56, -59, 43, -60,
+ -18, -4, -21, 45, 11, -48, 11, 38, -27, 58, -49, 65, 19, 54, -38, 35,
+ -37, 24, -11, 44, -62, 41, -16, -48, -8, 31, -68, 17, -3, -5, 52, -51,
+ -10, 16, -26, 18, -29, 56, -41, 3, 5, -10, -37, 61, -14, -10, -9, 20,
+ -8, 8, -2, -16, 44, -17, 14, -33, 30, -2, -27, 16, 3, 0, 51, -42,
+ 32, -20, 8, -11, -24, 10, 12, -15, 6, -32, 10, 21, -38, -11, -12, 23,
+ 13, -64, 19, 34, -23, -23, 16, 10, 39, 2, -36, 55, -31, 0, -29, 18,
+ 8, 12, -61, 73, -28, 54, -34, 21, 9, 7, 53, -34, -29, 19, -7, -44,
+ 7, 15, -16, -18, -31, 10, -29, 36, -69, 7, 4, 33, -72, 45, 14, 0,
+ -8, 35, -13, 26, 16, -28, -3, -32, 45, -4, 8, -20, 65, -24, 2, -24,
+ 40, -16, -16, 20, 8, 2, -3, -2, 23, -15, -11, -30, 19, -51, -19, -5,
+ -36, 18, 24, -4, -1, 46, -90, 60, 4, 23, -17, 16, 60, -24, 0, 18,
+ 0, 5, -6, -24, 27, -34, -28, -7, -4, 22, -30, -11, -3, -1, -44, 36,
+ -38, -6, -9, 55, -34, 16, 27, 28, -65, 62, 22, -32, 36, 7, 2, 27,
+ -19, 50, -71, 44, -19, -67, 13, -3, -14, -30, 33, 5, -12, -48, 60, -47,
+ -28, 9, -6, 24, -11, -1, 13, 62, -53, 26, 7, -9, 6, 58, -38, -10,
+ 0, 5, -23, 23, 8, -14, -19, 21, -9, 35, -17, -28, 14, 27, -17, -14,
+ -29, 24, 6, -85, 74, -16, -18, -2, -19, 47, -29, -18, -15, 52, 0, 7,
+ -10, -23, 45, 13, -11, 12, -28, 27, -26, 19, -69, 74, -55, 35, -21, 41,
+ -24, -11, 39, -19, 7, 0, 7, -31, 10, 7, -45, -17, 25, -12, 9, -19,
+ 3, 28, -53, 76, -19, -25, 49, -2, 6, -11, 24, -12, -23, 17, -1, -15,
+ -10, -36, 26, -25, 0, -44, 59, -67, 45, -31, 5, 15, 56, -12, -14, 12,
+ 10, 24, -52, 37, 5, -35, 52, 23, -55, -6, 24, -49, 26, 31, -24, 10,
+ -33, 33, -11, 1, -49, 8, 7, 6, -78, 12, -22, 10, -11, 13, 13, -18,
+ 38, 50, -18, -5, 64, -52, 59, 33, 3, -9, -6, -6, 26, -64, 18, -38,
+ -47, 18, -33, 4, -39, 40, -31, -1, -23, 48, -30, 18, 17, 32, -20, 32,
+ 19, 24, -58, 49, -38, -9, 15, -28, 16, -3, -2, -28, 33, -22, 23, -1,
+ -34, 33, -48, 67, -55, 21, 51, -66, -2, 21, -5, -17, 24, -63, 53, 8,
+ -19, 9, -11, 36, -37, -35, 43, -35, -3, -44, 68, -43, 53, -24, -5, 45,
+ -16, -7, 14, 49, 3, -16, 22, -10, 2, -28, -9, -6, -5, 32, -76, -22,
+ 35, -26, -35, -12, 0, 3, 13, 6, 36, 7, -32, 69, -15, 45, -20, -21,
+ 35, 35, 1, -25, 11, 34, -24, -33, -9, 5, -25, -49, 31, -41, 15, -42,
+ 25, -30, 42, -80, 32, 2, -18, 33, -12, -9, 43, -1, 4, -12, 54, -51,
+ 22, -1, 18, 28, -29, 18, 7, 10, -19, 8, -1, 12, -21, -6, -11, 4,
+ 4, -28, -8, 22, -27, -5, 9, -25, 20, -19, -36, 41, -8, 20, -32, 16,
+ -29, 29, -13, 13, 4, 1, 17, 8, 0, 9, 22, -1, -3, 28, -11, -39,
+ 36, -31, 5, -11, -27, 22, -39, 7, 15, -24, 19, 8, -37, 75, -52, 54,
+ -65, 22, -13, 23, -26, 32, -19, 10, -8, -3, 12, 16, -44, 25, -23, 14,
+ 9, -46, 20, 2, -4, -8, -6, 18, 4, -2, -3, -15, 4, 16, -9, -5,
+ 34, -29, 27, -54, 98, -65, 11, -18, 16, -13, 0, -2, 0, 22, -43, 31,
+ -46, 58, 2, -25, -2, 16, -2, -29, 17, 18, -26, 21, -17, 5, -4, -9,
+ 0, -34, 50, -27, -3, 4, 31, -3, -47, 32, -25, 36, 6, -47, 33, -28,
+ 39, -36, 42, -28, 5, -3, -2, 25, 27, -47, 20, 22, -5, -15, 1, -9,
+ 16, -25, -10, -43, 40, -12, -19, 22, -24, -5, 14, -44, 42, -32, 32, -45,
+ 40, 41, -17, 27, -44, 38, -16, 15, -36, 39, -13, -19, -4, 34, 1, -9,
+ 9, -16, -2, -29, 31, -31, -4, 35, -21, -52, 63, -41, 2, -7, 30, -35,
+ 13, 9, 15, -4, 14, -36, 18, -14, 55, -50, -6, 22, -23, -11, -5, 12,
+ 17, -13, -43, 44, -33, 41, -42, 45, 3, -12, 26, 11, -11, 35, -76, 39,
+ 2, 0, 3, -4, 15, -19, -6, -33, 11, 5, 16, -25, -2, 19, -7, -43,
+ 30, 20, -27, -18, 12, 14, 33, -50, 14, -15, 23, 8, 2, -10, -4, 53,
+ -86, 24, -9, 41, -34, -21, 22, 24, -54, 27, 13, 2, -9, 14, -29, 21,
+ 40, -43, -9, -3, 27, -3, -22, 18, 10, -23, -15, 1, 14, -12, 3, -30,
+ 30, -22, -28, 36, -15, 39, -57, 21, 3, -3, 33, -13, -2, 6, 20, -6,
+ 4, -13, -5, -18, 13, -7, 7, 26, -26, 16, 7, -64, 37, -7, 10, -20,
+ 12, -11, 7, -34, 37, -12, -24, 34, -18, -18, 39, 9, -42, -24, 43, 2,
+ -16, 25, 12, -16, 8, 12, -44, 32, -9, 23, 1, -37, 40, -23, -17, 18,
+ -42, 23, -12, -7, 10, -6, 6, -13, -13, 30, -23, 36, -4, 7, 17, -18,
+ 18, -3, 8, 5, -1, -13, -15, 2, -5, -16, 7, -52, 23, -38, 30, -30,
+ 16, -26, 21, -22, 24, 3, 20, -28, 22, 22, -31, 42, -16, -11, 32, -26,
+ 0, 31, -14, 11, -15, 14, -17, -9, 10, 11, 27, -38, -4, 14, -18, 36,
+ -44, 0, -11, 16, -14, -2, 16, -34, -23, 22, 4, -24, 14, -13, 16, 31,
+ -28, -10, -6, 51, -27, 13, -49, 3, 68, -38, 1, 8, -27, 26, -16, 0,
+ 15, -36, 7, -6, 38, -11, 0, -14, 10, -4, 22, -48, 31, -1, 23, -38,
+ 1, 15, -7, 10, -1, -3, 4, -1, 10, -2, -12, 3, -22, 5, 9, 8,
+ 4, -14, 12, -3, -7, 22, -20, 3, -6, 13, -15, -8, -7, 16, -14, -1,
+ -3, 6, -17, 12, 22, -44, 68, -67, 50, 13, -20, -11, -4, -20, -3, 22,
+ -13, -20, 28, -7, 2, 11, -9, -23, 5, 5, -26, 24, -31, 2, 20, 15,
+ 2, -7, 4, 19, -6, 41, -51, -3, 24, 27, -30, 25, -37, 1, -7, -2,
+ -4, -26, -1, 12, 5, -12, 9, -30, 5, 11, 26, -18, -32, 42, 7, 0,
+ -23, 10, 10, -20, 53, -49, 6, -39, 18, 3, -27, 41, -21, 16, 28, 14,
+ -24, -15, 19, 5, 16, -31, -1, 45, -25, -6, -16, -4, -19, 37, -47, 21,
+ 2, -14, -7, 30, -35, 13, -30, 14, 21, 11, -18, -28, 37, 12, -18, 9,
+ 5, -1, 33, -41, 3, -7, -19, 8, -14, 12, 15, -18, -4, 44, -25, 22,
+ -46, 19, 40, -25, -12, -5, 17, 7, -53, 25, 4, -10, 14, 16, -31, 40,
+ -27, -11, -4, 28, -40, -5, -9, -3, 34, -47, 33, -5, 11, -33, 33, 0,
+ -14, 35, -18, -27, 11, 14, -37, 35, -20, 7, 15, 2, 27, -17, 15, -31,
+ -1, 11, -27, 24, -26, 14, 13, -35, 20, -13, -2, 16, 16, -6, 2, 15,
+ -7, -22, 51, -36, -2, 20, -19, 23, -20, -19, -9, -14, 8, -4, -13, 35,
+ -66, 36, -37, 3, 19, -1, 15, 32, -45, 71, -15, -5, 12, 34, -33, 24,
+ -5, 20, -43, 42, -59, 13, -12, -69, 66, -29, -34, 17, 7, -28, 24, 5,
+ -27, 51, -40, -9, 46, 3, -17, 36, -56, 63, -7, -31, -19, 53, -12, -10,
+ 4, 19, -47, 35, 0, -40, 17, -14, 13, -11, 11, 3, -39, 22, 5, 21,
+ -19, -11, 25, -4, -5, 20, -13, 25, -6, -16, -16, 29, -61, 25, -33, 12,
+ -17, 7, -19, 34, -27, 15, -19, 32, -26, 54, -46, 6, 9, 14, -6, -6,
+ 23, -32, 58, -19, -5, 15, 46, -42, 39, -7, -23, -7, -14, -22, 42, -66,
+ 0, 4, -8, -11, -4, -3, -7, 7, -23, 30, -14, 19, 8, -9, 20, 36,
+ 5, -24, 25, 12, -20, 16, -53, 60, -49, -26, 24, -87, 67, -49, 13, -7,
+ 5, -14, 5, 11, 38, -3, -15, 27, 26, -36, 20, 30, -47, 29, -5, 9,
+ -10, 38, -65, 47, -49, -4, -10, -6, 1, -1, -28, 16, -14, 3, -14, 27,
+ -8, 1, 2, 23, 21, -53, 40, 24, -16, -12, -2, 11, 17, -8, -18, 8,
+ -25, 28, -10, -12, 13, -51, 10, 35, -10, -8, -9, 8, 10, 14, -20, 4,
+ -9, 37, -5, -2, 2, 4, -9, -5, 16, -16, -23, 13, 7, -9, 14, -49,
+ 13, 8, -3, -13, -9, 22, -8, 12, -13, 36, -36, 35, -17, 23, -12, 0,
+ -37, 50, -31, -8, -31, 43, -4, -11, 0, 3, -7, -19, 16, -16, -28, 46,
+ -28, 27, -13, 33, -21, -1, 39, -13, 3, -4, 4, -39, 74, -30, -17, 33,
+ -3, -20, -12, 24, -94, 75, -63, 54, -62, 23, 4, 12, -33, 22, -35, 16,
+ 12, -28, 34, 2, -12, -3, 22, 23, -31, -6, 26, 4, -41, 8, 37, -15,
+ 21, -7, 18, -51, 42, -27, 35, -45, 35, -30, 18, 9, -20, 1, 18, -12,
+ -51, 61, -61, 24, -20, 1, 11, -5, -2, -12, 11, 20, -35, -2, 37, -21,
+ 23, -15, -2, 19, -51, 82, -50, 20, 29, -26, -34, 49, -2, -16, 11, -17,
+ -4, 6, 15, -35, 13, -15, -10, -17, 15, 4, -42, 43, -31, 34, -30, 53,
+ -43, 40, -22, 9, 9, -24, 64, -41, 29, -17, 8, -15, 8, 2, -27, 7,
+ 10, -28, 0, 30, -50, 6, -13, -14, -21, 11, 9, 13, -47, 35, -11, 32,
+ 28, -28, 1, 32, 2, -19, 28, -24, 9, 0, 19, -6, 16, -33, 6, -23,
+ 33, -31, -1, -4, 26, -22, -22, -10, -11, 18, -26, 19, -8, -4, 21, -14,
+ 36, -2, 12, -48, 49, -1, -13, -5, 8, -3, 9, -4, -18, 15, 28, -50,
+ 10, 4, -7, 4, -39, 37, -39, 11, 2, -20, 13, 4, -6, 0, 35, -17,
+ -9, 6, 38, -21, -1, -1, 12, -2, -16, 15, 7, -22, 18, -23, 11, 3,
+ -9, -39, 29, -31, 44, -41, 0, 5, 21, -9, -25, 25, -6, 38, -55, 38,
+ -14, 6, -26, 38, -24, 39, -39, -15, 17, 16, -20, -27, 17, 24, -20, -20,
+ 33, 8, -31, 2, 2, 27, 11, -4, -7, 31, -20, -9, 4, -4, 17, -32,
+ 2, -18, 31, -35, 38, -52, 42, -1, -28, -26, 25, 3, -51, 42, -35, 35,
+ -39, 44, -38, 20, 20, -51, 34, 45, -10, -7, 27, -19, 33, -49, 22, 2,
+ -7, -5, -27, 59, -24, -20, 21, -8, -15, 24, -51, 3, 9, -23, 24, -30,
+ 2, 29, -26, -2, 4, 10, 0, -18, 50, 3, 9, -14, 17, -18, 24, -13,
+ -33, 7, 25, -50, 2, -2, 30, -58, 31, -8, 23, -11, -1, -24, 21, 1,
+ -41, 47, -30, 28, -39, 56, -16, -20, 51, -45, 33, 6, 23, -12, -19, -2,
+ 7, 1, -14, -5, -11, -20, 25, -17, 7, -22, 21, -19, 34, -47, -2, 1,
+ 33, -30, 14, 20, 6, -9, 17, 13, -22, 19, -58, 23, 26, -15, -52, 2,
+ 18, 10, -13, 46, -5, -8, -6, 4, -14, 5, 11, -13, -7, 42, -25, 8,
+ -37, 35, -10, 6, -25, 16, 15, -15, -9, -20, 18, -23, 26, -34, 35, -22,
+ -10, 9, 14, -6, -21, 27, -8, 4, 1, 3, -19, 28, 2, -7, 30, -8,
+ -13, 11, -9, -9, -19, 12, 0, -23, -1, -23, -6, 27, -31, 41, -28, 13,
+ 5, 9, -21, 6, 2, -2, 18, -16, 31, -25, 40, -38, 39, -13, 8, 14,
+ -3, 9, -30, 6, -12, -7, -15, 30, -64, 6, -22, 13, -8, 14, -40, 9,
+ 32, -35, 14, -1, 12, -25, 63, -25, 35, -2, 19, -5, -3, 20, -29, -1,
+ 35, -37, 53, -46, 4, -14, 22, -27, 23, -64, 8, 5, -25, 41, -18, 14,
+ -42, 53, -56, 35, -42, 71, -63, 45, -38, 29, -12, 33, -22, 0, 24, -13,
+ 3, 13, 1, -10, -19, 11, 19, -38, 5, -2, -18, -21, 33, -54, 41, 9,
+ 4, -1, -21, 3, 3, 37, -31, 34, -40, 34, -19, 30, -26, 23, -53, 55,
+ -8, -13, -16, 7, -13, 46, -38, 2, -3, 17, -1, -26, 18, -57, 68, -27,
+ 23, -19, 32, -39, 2, 2, -18, 12, -16, 4, -23, 38, -65, 40, -5, 13,
+ 19, -26, -13, 60, -25, 7, 1, 10, 22, -24, 23, -20, -16, -17, 14, -32,
+ 26, -4, 17, -15, 9, -29, 4, -29, 11, 36, -18, -19, -2, 5, 28, -23,
+ 31, 6, 4, 18, -14, 4, -7, 0, -45, 61, -31, 5, -15, -23, -21, 52,
+ -62, 4, 22, 1, -9, 15, -24, -27, 60, -49, 38, 0, -6, 1, 13, 7,
+ 4, 19, 6, 0, 27, -28, -14, -21, 17, -1, -30, 23, 10, -36, 18, -19,
+ 2, -18, 0, 6, -1, 7, -1, -37, 26, 15, -35, 41, -24, 10, 10, -9,
+ -12, 12, 7, 3, 10, -11, 11, -14, 27, -49, 71, -55, 25, 8, -11, 11,
+ -5, -22, 7, 15, -17, -11, 18, 4, -54, 43, -38, 27, -1, 7, -13, 19,
+ 10, -41, 50, -41, 13, 9, 10, -41, 38, -13, 13, -2, -2, -4, 9, -36,
+ -5, 22, -31, -18, 8, 21, -22, 21, -24, 12, 3, 16, -24, 25, -16, 22,
+ -35, 14, 3, 11, 12, -22, 40, -11, -25, 14, 0, 14, -2, 2, -10, -12,
+ 14, -51, 11, -21, 55, -27, 9, 3, 38, 7, -25, 5, -19, 6, -14, 0,
+ -10, 21, -57, 35, 18, -21, 21, -40, -13, 24, -24, -12, 10, -1, 11, 10,
+ -12, -5, 38, -45, 23, 26, -13, -9, 32, 6, -3, 30, -28, -28, 27, 3,
+ -10, -11, -10, 16, -28, 21, -12, -3, -1, -33, 14, -30, 12, -20, 40, -15,
+ 7, 19, -18, -1, -1, 9, 4, -23, 32, 17, -19, 12, 16, -45, 4, -6,
+ 18, -28, 36, -44, 44, -29, 10, 4, 14, -8, -13, 9, -30, 39, -17, -5,
+ 10, -10, 5, -1, -16, 17, -7, -9, -10, 15, -21, 9, 10, 8, -10, -6,
+ 3, -21, 34, -3, 6, -4, 15, 3, -2, 4, 26, -44, 30, -43, 2, 9,
+ -5, -7, -18, 16, -28, 0, 5, -7, 0, 7, 0, -7, 21, -14, 17, 15,
+ 2, -40, 7, 44, -30, 55, -33, -19, 40, -30, 17, -1, -20, -20, -20, 5,
+ 14, 1, -7, -32, 26, -11, -11, 24, -23, 17, 17, 8, -19, 18, 11, -6,
+ 17, -4, -13, 14, -9, 21, 9, -16, -8, 2, -16, 3, -9, -32, 6, -36,
+ -4, 0, 10, -36, 26, -11, 3, 31, -20, 1, 7, 4, 45, -35, 39, 0,
+ 4, 28, -21, 29, -39, 27, 15, -6, -14, 17, -25, -33, 16, -15, 18, -43,
+ 28, -61, 33, 1, -27, 13, -19, -20, 26, 11, -27, 16, -21, 33, -13, 43,
+ -44, 13, 24, -10, 35, -39, 36, 20, -39, 68, -68, 23, -16, -7, 0, 36,
+ -30, -13, -27, 42, -21, -4, -23, -2, 23, 0, -3, -3, 2, 4, -15, -5,
+ 28, -10, -20, 24, -7, 27, -58, 31, -7, -29, 39, -40, 41, -35, 8, -25,
+ 30, 31, -17, -9, 3, 36, -8, -18, -11, 29, -2, 6, -25, 21, -5, -8,
+ -17, -24, 20, -26, 20, -23, 46, -26, -13, 8, 13, 2, -15, 4, -9, 28,
+ -25, -19, 49, 18, -50, 45, -11, -17, 5, -61, 15, 4, -22, -1, 22, 23,
+ 33, -55, 46, -25, 37, 18, 2, -9, 11, -47, 23, -8, -25, 37, -32, 2,
+ 5, 12, -18, -5, 19, -27, -7, 20, -40, 32, -44, -21, -29, 58, 8, -9,
+ 57, -28, 29, -32, 14, -14, 4, 23, -33, 16, -4, -16, 21, 38, -37, 23,
+ 10, -32, 17, 17, -12, -59, 9, -3, -12, 22, -13, -8, -26, 16, 1, 33,
+ -9, -17, 16, -7, 21, -44, 26, 5, 35, -36, -1, 13, 36, -36, 39, -36,
+ 17, -13, 2, -33, 20, -13, -51, -2, 9, -2, 35, -21, 19, -20, 18, -19,
+ -5, 30, -39, 30, 22, -35, 74, -52, 33, -15, 17, -21, -13, 11, 6, -25,
+ 25, -31, 29, -18, 18, -52, 40, -11, -17, -26, 56, -56, 69, -53, -14, 32,
+ -10, -8, -2, 18, -14, 20, -18, 20, 22, -27, 0, -25, 56, -46, 16, -28,
+ 52, -5, -33, 76, -75, 36, -1, -42, 42, -46, 13, -13, 25, -7, 35, -55,
+ 5, 63, -56, 11, -24, 13, -8, -10, -27, 15, -15, 44, -66, 52, -3, -6,
+ 0, 23, -33, 79, -55, 30, -27, 37, -18, -6, -2, -19, 52, -22, -50, 60,
+ -32, 28, -56, 44, -28, 15, -37, -9, -28, 63, -75, 9, 39, 28, -21, 5,
+ -17, 15, 2, -13, 30, 13, -14, 10, -12, 30, -22, -10, 4, -8, -9, 14,
+ 6, -39, 34, -6, 4, 1, -5, 0, 33, -73, 34, -12, 23, -9, 53, -47,
+ 17, 3, -18, -6, 2, -19, -12, -7, -45, 72, -9, -71, 55, -58, 50, -18,
+ -36, 37, 19, -11, 13, -35, 32, 6, 5, 18, -6, 19, -26, 32, 16, 20,
+ -43, 20, -10, -7, 16, -7, -68, 21, -36, 7, 19, -22, 19, -3, -35, -37,
+ 25, 21, -57, 67, -9, 9, 32, -11, 28, -18, 35, -41, 60, -19, 29, 0,
+ -38, 29, -6, -35, 0, 25, -37, -1, -31, -42, 30, -19, -21, 36, -66, 53,
+ -33, 15, 16, -13, 20, -35, 73, -4, 18, 39, 4, 1, 3, 21, -2, -12,
+ -18, -51, 44, -17, -50, 48, -30, -16, -13, -35, -7, 25, -33, -14, 14, 0,
+ 8, -30, 45, -13, 50, -53, 28, 60, -33, 23, -7, -2, 15, 36, -11, 9,
+ 19, -44, 4, -21, 19, -5, -27, -45, 48, 9, -47, -23, 12, 3, -25, -8,
+ -21, 63, 1, -29, 31, -18, 19, 16, -24, -17, 50, -65, 65, -56, 93, -45,
+ -17, -25, 45, -18, 23, -53, 50, -15, -12, -39, 51, -11, 11, 13, -31, 54,
+ -14, -29, 22, -11, 10, -41, -19, 52, 10, -51, -60, 72, -13, 12, -38, 19,
+ -2, 31, -56, 37, -4, -10, 22, -14, -33, 48, -40, 38, -14, 27, -24, 19,
+ 29, 17, -31, -2, -41, 34, -17, 2, 5, 5, -13, -30, 14, 9, -9, 7,
+ -11, 15, 5, -28, -2, 0, 45, -30, -25, 1, 10, 29, -55, -24, 52, -5,
+ 5, 20, -25, 20, -15, 14, -64, 95, -53, 32, 13, -26, 31, -8, -27, 18,
+ 48, -57, -3, -10, 25, -24, -32, -9, 18, 18, -33, -15, 27, -22, 14, -5,
+ 10, 51, -21, -25, 19, 5, -15, -29, 16, 1, 33, -39, -12, 56, 14, -63,
+ 36, -2, -17, 52, -11, -37, 5, 19, -52, 38, -23, -60, 93, -75, 52, -30,
+ -2, -11, 49, -11, -25, 1, 42, -35, 26, -35, -9, 24, -1, 10, -6, -12,
+ 7, 4, 22, -10, 41, -25, -8, -4, -2, 28, -43, 19, -32, 4, -27, 9,
+ -47, 51, -16, 12, -52, 49, 8, 7, -37, 27, -33, 80, -44, 6, 5, 28,
+ -15, 16, 15, 2, -12, 50, -77, 38, -38, -45, 30, 8, -37, -13, -8, -18,
+ 50, 3, -54, 29, 29, -20, 4, 52, -57, 62, -52, -2, -9, 62, -64, -5,
+ 24, 23, 0, -7, -23, 48, 25, -78, -9, 38, 18, -46, 30, -51, 39, 4,
+ -48, 22, 15, 13, -39, 8, 10, 31, -20, -22, 21, -17, 17, -23, 22, 22,
+ -24, -36, 11, 31, -16, -28, 34, -4, 0, -20, 6, -2, 35, -13, -60, 36,
+ 24, -45, 21, -2, 36, 0, -73, 66, -37, 39, -66, -18, 22, 17, -17, -25,
+ 24, 36, -47, 3, 25, 7, 8, 0, 1, 14, 20, -21, 4, 21, 12, -77,
+ 17, -4, -12, 31, -57, 38, -11, -4, -31, -6, 29, -34, 11, 13, -20, 82,
+ -36, -36, 40, -28, 77, -68, 12, 2, 34, -23, 5, -31, 11, -5, 44, -105,
+ 79, -31, -29, -16, 37, 8, 18, -14, -9, 32, -10, -11, -7, 0, 41, 34,
+ -56, 7, 13, -2, -31, 33, -67, 42, -31, -2, 22, -49, 18, -34, -11, 38,
+ -40, 56, -16, 14, -2, 24, 0, 0, 41, -21, -8, 6, -11, 11, 11, -45,
+ 26, 4, -17, -7, -26, -30, 7, -21, -29, 56, -29, 37, -3, 2, -8, -3,
+ 22, 11, 40, -13, 58, -6, -38, 48, -23, 15, -52, -14, -6, 49, -66, -20,
+ -11, 34, -32, -44, 41, 4, 20, -59, -24, 77, 23, -24, -17, 42, 19, -3,
+ -19, -34, 54, 17, -22, -17, 46, -24, -9, 3, -22, 40, -47, -49, 72, 4,
+ -18, -48, -33, 55, -4, -41, -51, 105, -26, -3, -22, 64, 28, -51, 31, 2,
+ 15, 27, -62, 18, 21, 6, -15, -54, 52, -14, -46, 7, -30, 32, -1, 6,
+ -37, 39, -3, -23, -20, 24, 23, 17, -25, -6, 67, -36, -11, -37, 56, -79,
+ 3, 30, 45, -39, -17, -2, 21, 2, -4, -3, 3, 1, 16, -16, 9, 30,
+ -37, 8, -6, 46, -65, 3, 14, -59, 104, -60, 2, 46, -29, -30, -2, -10,
+ 24, -52, 63, -31, 81, -85, 18, 35, 16, -32, -18, -24, 45, -16, -15, -13,
+ 37, -15, -20, -42, 91, -45, -15, -9, -16, 64, -11, -23, 31, -18, 38, -42,
+ 3, 12, 1, 5, -5, 22, -44, 69, -31, -18, 15, 21, -64, -13, 34, -37,
+ 30, -26, -15, 6, -3, 44, -28, 11, -3, -1, 16, -18, 25, -14, -26, 69,
+ -56, -5, 31, -51, 24, 3, -36, 9, 52, -34, 31, 21, -11, -68, 31, -24,
+ 53, -25, -29, 31, 23, -20, 9, -15, -11, 19, 12, -47, 84, -60, -16, -11,
+ 17, -4, -15, 30, -45, 32, 34, -63, -7, 68, 0, -35, 17, 7, 33, -31,
+ -8, 7, -32, 43, -13, -18, 15, 31, -32, -34, 5, 8, -16, 20, -26, -29,
+ 32, -9, -20, 17, 33, -31, -13, -5, 86, -52, 23, -19, 2, 13, 14, -7,
+ -20, 36, -16, -3, 8, 0, 14, -69, 76, -77, 25, -14, -17, 3, 39, -14,
+ -46, 31, -2, -7, 37, -45, -6, 24, 28, -37, 22, 13, -35, 4, 8, 23,
+ 7, -43, 53, -59, 23, 16, 4, -25, -15, 23, -9, -20, 26, -18, -1, 25,
+ -3, -48, 53, 2, -43, 7, 14, -34, 15, 28, -33, 53, -2, -59, 31, -34,
+ 40, 19, -27, 20, -2, 8, 2, 3, -8, -8, 4, -57, 62, 24, -72, -4,
+ 17, -17, -3, -10, -26, 42, -30, 12, -29, 31, -10, 3, 24, 2, 21, -1,
+ -36, 52, -7, 21, 14, -32, -18, 73, -45, -6, 8, -12, -66, 21, 25, -17,
+ -6, -35, -14, 27, 26, -47, 40, -51, 56, -19, -24, 31, 6, 4, 11, -3,
+ 37, -47, 41, -32, 50, 0, -72, 25, 16, -19, -1, -2, -4, -41, 20, 6,
+ 9, -3, -44, 32, -54, 83, -30, -26, -8, 46, -47, 29, 5, -19, 37, -9,
+ -20, 65, -14, -21, -4, 10, 28, -28, 18, -29, 35, -25, 3, -17, -31, 4,
+ -4, 0, -9, 41, -42, -34, 40, -15, 8, -24, -8, 36, 22, -18, -27, 70,
+ -39, 39, 1, -5, 57, -54, 12, 36, 3, -13, -1, -32, 69, 6, -64, -50,
+ 13, -13, -34, 22, -13, 0, -10, -38, 41, -11, -22, -3, 11, 4, 38, 22,
+ -10, 24, 32, -23, 23, -6, 8, -4, 21, -61, 66, -35, -41, 7, 5, -29,
+ -19, -45, 23, -2, 46, -84, 78, -59, 40, -10, -18, 79, -35, -5, -1, 36,
+ 16, 13, -21, -31, 52, 2, -50, 34, -5, -36, -37, 65, -42, 1, 16, -42,
+ 35, -8, -50, -6, 41, -16, 27, -41, 22, 64, -50, -11, 31, -18, -17, 5,
+ -3, 34, 34, -40, -41, 66, -37, 20, -11, -20, 29, -5, -14, -15, 45, -33,
+ -37, -11, 36, -25, 18, -8, 20, 1, -23, 60, -32, 0, 34, -24, -32, 64,
+ -39, -35, 48, -7, -13, 4, -39, 32, 0, 1, -31, 2, -12, 43, -38, -8,
+ 26, 0, -57, 53, 19, -22, -10, 17, -30, 57, 6, -31, 33, 10, 0, -48,
+ 29, -4, -23, 6, -7, 31, -39, 15, -41, 38, -19, 5, -37, 23, 11, -28,
+ -14, 59, -48, 8, 22, -20, 50, 15, -34, -26, 67, -8, -15, -21, 53, -27,
+ -9, 13, -24, -35, -10, 9, -15, -13, 18, -38, 28, 22, -14, 2, -22, 42,
+ -20, 22, 12, -20, 45, -16, 17, -16, 22, 34, -27, -13, -7, 1, -21, -1,
+ 13, -44, 36, -51, -8, 16, -7, -30, -46, 90, -54, 35, 1, 11, 9, 5,
+ 1, -19, 20, 11, 21, -1, -49, 41, -6, 0, 37, -74, 9, 20, -12, -47,
+ 65, -68, 28, -5, -26, 15, 14, -3, -23, 8, 18, -22, 13, 3, 31, -21,
+ -5, 8, 24, -21, 48, -20, -21, 41, -43, 4, 18, 21, -60, 9, -27, 1,
+ 13, -15, -33, 15, 23, -48, -8, 53, -50, 1, 6, -40, 90, -10, -15, 51,
+ -52, 53, 29, -68, 50, 52, -30, -21, 7, -1, -8, -29, 11, -47, 6, 18,
+ -12, -25, 53, -34, -23, -6, 19, -7, -13, 7, 5, -2, 14, 11, -15, 51,
+ -29, 6, 12, 20, -27, 29, -12, 4, -18, -5, 2, -17, 10, -19, 2, -8,
+ -5, 56, -82, 49, 0, -42, 48, -25, 19, 6, -41, 17, 35, -18, -17, -29,
+ 26, 10, 4, -24, 26, -35, 47, -36, 2, 2, -23, 27, -42, 55, 0, -21,
+ 19, 21, -8, 1, -3, -15, 7, 12, -23, -29, 47, -12, 4, -28, 17, 16,
+ -7, -31, -8, 25, -6, 0, 13, -20, 6, 3, -7, 19, -21, -37, 27, 41,
+ 7, -14, 12, -59, 57, 6, -49, -2, -8, 0, 19, 13, -20, -5, 16, 23,
+ 4, -15, -33, 14, 2, 15, -26, -28, 10, 45, -17, -24, 14, 17, -39, 22,
+ -8, 48, -51, -1, -16, 52, -34, -21, 11, 13, 18, -57, 26, 15, 27, -36,
+ -12, 40, -7, -14, 15, -86, 91, -20, -13, -7, 53, -43, 33, -25, 13, 3,
+ -38, -19, 28, 28, -18, -74, 58, -3, 40, -27, -34, 30, 28, -1, -22, 2,
+ 9, -8, -12, 12, 21, -35, -2, -17, 17, 2, -27, 22, -36, 38, -11, 2,
+ -20, 7, 20, -29, 39, 11, -3, 9, -24, 47, -36, 28, -14, -16, 38, -37,
+ 12, -15, 18, -69, 56, -31, 17, -16, -18, -13, 21, -6, -9, -25, 37, 6,
+ -1, -2, 5, -1, -26, 39, 6, -3, -10, 0, 12, 30, -12, -31, 24, 13,
+ -14, 9, -23, 31, -43, -17, -2, 13, -23, -14, -21, 21, 19, -22, -12, 24,
+ 41, -26, 10, 12, 19, -3, 9, -12, 26, 12, -52, -4, 16, -3, 0, -43,
+ 7, 5, -14, -9, 12, -28, 15, -23, -2, 35, -12, -8, -10, 24, 57, -55,
+ 26, -18, 19, 44, -30, 0, -5, 50, -56, -1, 8, -5, -39, 9, 19, -39,
+ 38, -73, 30, -1, 2, 16, -24, 6, 29, -71, 70, -18, -6, 8, 31, 4,
+ -13, 23, -11, 31, -56, 57, -25, 10, 15, -44, -10, 16, -17, -44, 18, -28,
+ 10, 8, -21, -4, -9, 28, 20, -16, 17, -17, -6, 30, 0, 11, -21, 25,
+ 25, -1, 31, -56, 31, 14, -32, 2, -19, 4, -17, -26, -13, 42, -59, 15,
+ -29, 53, -4, 1, -23, 13, 31, 5, -22, 3, 30, -28, 2, -24, 37, 1,
+ -3, -18, 18, 41, -40, 3, -40, 48, -31, -5, -20, 5, 9, 0, -30, -1,
+ 26, -15, -5, -6, 51, -25, -27, 7, 44, -11, 10, -32, 14, 46, -31, 6,
+ -11, 37, -33, -14, 19, -4, 22, -50, 26, -45, 21, 1, -23, 10, -15, 17,
+ -63, 53, -14, -18, 56, -49, 21, 25, -7, 4, -21, 52, -33, 19, 3, 11,
+ -9, -7, 0, -49, 22, -17, 25, -10, -11, 5, -19, 35, -26, 20, -7, -21,
+ 37, -25, 29, -23, 3, 6, 17, -26, 27, 5, -16, 10, -9, -24, 11, -4,
+ -17, 9, -5, -13, 1, -2, 10, 5, -13, 21, 0, 8, 9, -22, 12, 13,
+ -24, -3, -22, 42, -18, 3, -4, -15, 1, -2, 8, -17, -13, -2, 1, 23,
+ 10, -2, -31, 23, 17, -15, -9, -24, 31, 2, 19, -24, 4, -22, 28, -5,
+ -20, 34, -57, 26, 71, -51, 28, -24, -12, 28, 10, -35, -4, -6, 7, -7,
+ 8, -52, 61, -52, 7, -9, -21, 9, 18, -19, 3, 34, -53, 56, -29, 20,
+ -11, 22, 4, -1, 23, 2, 1, 24, -15, 3, -32, 13, 21, -37, 6, -11,
+ -25, 22, 7, -2, -41, 4, 10, -30, 39, -24, -7, 8, 12, 9, -1, -35,
+ 13, 3, 9, -18, 21, 26, -14, 41, -8, -35, 31, -29, 17, -20, -12, 20,
+ -30, 27, -26, 21, -9, -6, 5, -14, 3, -11, 15, 2, 8, -14, -5, 20,
+ 4, 0, -31, 9, 4, 25, -24, 5, -5, -13, 27, -7, -32, 1, -5, -10,
+ 28, 7, -4, 11, 10, 22, -3, -22, -15, 6, -3, -3, -27, -25, 5, 8,
+ -10, -17, 18, -18, 12, 32, -18, 1, 25, -25, 50, 7, 2, 0, -3, -3,
+ 16, -20, 9, -14, -15, 21, -27, -3, -17, 23, -31, -4, -18, 31, -21, 6,
+ 0, 18, -16, 27, 3, -7, -17, 17, -15, -11, 19, -16, 6, 1, 12, -18,
+ 5, -6, 24, 0, -19, 22, -23, 43, -35, 18, 22, -40, 1, 12, -4, -18,
+ 26, -53, 34, 1, -10, 1, -18, 27, -25, -24, 33, -31, 9, -43, 53, -29,
+ 33, -17, 5, 23, -7, 2, 23, 29, 1, -8, 20, -10, -1, -22, -3, -17,
+ 4, 22, -61, -23, 31, -26, -29, -12, 2, -3, 12, 10, 26, 5, -29, 61,
+ -9, 32, -18, -14, 29, 31, 2, -19, 9, 31, -20, -31, -7, 5, -22, -47,
+ 31, -40, 15, -39, 22, -27, 40, -78, 31, 4, -19, 33, -13, -8, 41, -1,
+ 5, -12, 53, -51, 22, -1, 18, 28, -29, -1, 0, 0, 11, 13, -2, -7,
+ -5, -3, -3, 1, 2, -6, 0, 3, 8, 9, 5, 0, 14, -5, -28, -39,
+ -39, -36, -37, -27, -43, -49, -13, 4, 6, -7, 0, -1, 3, 23, 39, 29,
+ 35, 41, 21, 35, 0, 0, 21, 59, 67, 31, 21, 13, -3, 18, 34, 28,
+ 5, 3, 13, 3, 0, 12, -7, -33, -27, -39, -14, -34, -50, -30, -37, -35,
+ -53, -74, -70, -61, -62, -62, -50, -44, -61, -36, -3, -23, -15, -12, -17, -20,
+ -6, 11, -6, -12, -6, -17, 7, 46, 71, 87, 79, 70, 77, 104, 109, 66,
+ 37, 34, 27, 31, 40, 43, 31, 23, 17, 2, 10, 24, 32, 66, 56, 17,
+ -13, -55, -54, -21, 19, -19, -56, -77, -37, -27, -10, -6, -38, -36, -37, -3,
+ 23, 25, 25, 19, 35, 34, -7, -5, 28, 60, 66, 65, 51, 34, 22, 53,
+ 51, 15, 20, 11, 21, 21, 16, 24, -2, -23, -36, -35, -21, -29, -51, -51,
+ -47, -57, -85, -80, -70, -100, -97, -82, -78, -76, -64, -51, -56, -54, -49, -70,
+ -62, -53, -54, -60, -57, -65, -78, -76, -62, -39, 0, 31, 13, 6, 31, 54,
+ 55, 43, 30, 13, 9, 31, 23, 43, 28, 24, 36, 36, 24, 30, 54, 70,
+ 113, 103, 75, 4, -3, 40, 55, 50, 23, 9, 25, 29, 48, 41, 29, 14,
+ 6, 40, 63, 49, 39, 71, 80, 64, 21, 12, 17, 29, 68, 71, 52, 36,
+ 24, 37, 24, 1, 5, 3, -6, -4, 1, 13, -3, -22, -35, -31, -27, -58,
+ -59, -43, -55, -71, -76, -71, -88, -103, -95, -98, -85, -77, -68, -71, -58, -50,
+ -47, -52, -46, -40, -47, -44, -48, -56, -60, -91, -96, -68, -15, -6, -16, 9,
+ 3, 29, 31, 29, 8, 10, -6, 5, 10, -6, -4, -6, 15, 7, -2, 2,
+ -5, 30, 91, 107, 74, 8, -3, 14, 27, 32, 26, 17, 21, 18, 34, 49,
+ 20, -3, 2, 30, 42, 20, 36, 68, 79, 81, 52, 27, 22, 37, 80, 95,
+ 77, 77, 72, 74, 57, 55, 56, 41, 35, 22, 40, 58, 32, 23, 24, 26,
+ 0, -7, 6, -2, -16, -26, -31, -45, -46, -64, -77, -79, -73, -72, -75, -59,
+ -49, -56, -35, -48, -44, -50, -43, -59, -58, -40, -78, -119, -123, -95, -73, -40,
+ -52, -45, -29, -18, -3, -1, -11, -21, -28, -12, -24, -29, -21, -29, -16, -3,
+ -5, -30, -40, 1, 69, 96, 78, 31, 14, 23, 17, 19, 33, 20, 9, 9,
+ 45, 50, 14, 3, 12, 13, 16, 7, 14, 35, 54, 75, 56, 24, 1, 18,
+ 47, 47, 60, 62, 66, 69, 46, 54, 53, 38, 11, 18, 44, 41, 28, 33,
+ 37, 22, 14, 15, 13, 13, 1, -1, -13, -6, -11, -38, -33, -47, -40, -46,
+ -31, -29, -22, -9, -5, -9, 9, 4, -23, -14, -4, -3, -26, -69, -87, -74,
+ -60, -42, -49, -33, -28, -16, 9, 2, -16, -22, -25, -25, -33, -32, -44, -58,
+ -41, -11, -19, -51, -77, -43, 24, 47, 49, 34, 21, 5, -9, 5, 18, -10,
+ -14, 2, 23, 26, -3, -7, -4, 2, -3, -10, -4, -6, 38, 64, 50, 25,
+ 1, 11, 17, 21, 36, 58, 62, 46, 46, 61, 56, 27, 11, 20, 18, 27,
+ 15, 31, 26, 23, 17, 7, 16, 0, -9, -10, -3, -8, -14, -25, -36, -56,
+ -41, -39, -50, -30, -12, -23, -8, 10, 23, 17, -2, 3, 14, 26, 7, -33,
+ -48, -53, -52, -35, -30, -30, -23, 3, 21, 17, 8, 7, -8, -1, 0, -6,
+ -29, -50, -26, 10, 5, -38, -64, -41, 5, 22, 49, 63, 38, 20, 13, 26,
+ 15, -7, -9, -1, 28, 9, 1, -4, -12, -1, -5, -20, -38, -32, 6, 38,
+ 36, 16, 10, 0, -8, -13, 15, 41, 25, 30, 30, 52, 35, 17, 8, 3,
+ -5, -5, -6, 4, 7, 4, 4, 3, 3, -20, -25, -23, -28, -22, -18, -47,
+ -50, -54, -62, -67, -62, -48, -43, -44, -31, -10, 17, 10, -8, 1, 22, 24,
+ 17, -1, -21, -40, -39, -26, -38, -32, -21, 2, 17, 26, 29, 18, 5, 15,
+ 35, 19, -11, -37, -9, 33, 17, -6, -30, -23, -10, 22, 65, 73, 71, 47,
+ 57, 66, 38, 15, 16, 23, 34, 35, 27, 10, 11, 21, 32, -4, -26, -29,
+ 4, 29, 28, 38, 32, 17, -6, -6, 17, 32, 21, 31, 39, 49, 36, 27,
+ 25, 13, -1, -11, -8, -1, -15, -11, 4, -7, -9, -14, -38, -46, -35, -31,
+ -43, -53, -54, -72, -84, -88, -86, -79, -73, -86, -69, -40, -16, -23, -28, -13,
+ -9, 5, 5, -10, -34, -45, -48, -52, -61, -59, -42, -38, -9, 13, 19, 8,
+ -14, 18, 42, 28, -18, -31, -3, 11, 21, 13, -9, -17, -22, 9, 57, 71,
+ 62, 68, 83, 82, 65, 38, 38, 31, 52, 57, 45, 23, 25, 51, 56, 21,
+ -2, -8, 7, 21, 28, 55, 55, 37, 15, 17, 30, 30, 30, 48, 55, 65,
+ 55, 54, 61, 42, 24, 22, 13, 6, 6, 4, 4, 17, 19, 1, -20, -23,
+ -25, -27, -26, -44, -44, -62, -79, -91, -83, -76, -99, -104, -87, -63, -51, -40,
+ -42, -40, -29, -16, -6, -31, -40, -47, -63, -68, -81, -76, -81, -75, -49, -15,
+ -5, -34, -38, 2, 15, 8, -29, -43, -33, -18, -11, 8, -9, -42, -45, -14,
+ 25, 33, 41, 54, 67, 75, 71, 46, 30, 23, 52, 55, 38, 20, 25, 53,
+ 59, 35, 17, 6, 3, 5, 27, 64, 61, 49, 40, 40, 45, 36, 38, 63,
+ 69, 69, 77, 85, 78, 76, 63, 48, 38, 42, 28, 15, 30, 35, 41, 27,
+ 14, 0, -4, -2, -14, -16, -15, -35, -65, -63, -56, -64, -80, -94, -77, -71,
+ -46, -34, -42, -37, -21, -6, -5, -16, -20, -35, -44, -62, -66, -66, -96, -94,
+ -58, -26, -32, -44, -50, -14, 2, -9, -26, -41, -53, -49, -27, -5, -28, -59,
+ -65, -47, -20, -11, 7, 15, 28, 51, 57, 32, 7, 2, 30, 32, 15, 0,
+ 7, 30, 30, 24, 21, -2, -19, -20, 6, 37, 40, 31, 40, 45, 30, 29,
+ 35, 49, 52, 69, 74, 78, 89, 79, 72, 62, 60, 51, 37, 29, 29, 42,
+ 51, 46, 30, 32, 18, 2, 8, 13, 15, -13, -35, -35, -38, -40, -53, -71,
+ -70, -58, -34, -38, -32, -28, -9, 10, 10, 7, 11, -7, -28, -21, -26, -47,
+ -80, -84, -49, -18, -28, -38, -32, -8, -4, 4, 3, -23, -46, -44, -19, -5,
+ -22, -42, -55, -56, -35, -25, -12, -8, 11, 43, 51, 33, 1, 0, 24, 18,
+ 1, -5, 0, 1, 9, 15, 21, -2, -38, -36, -19, 2, 2, 19, 26, 19,
+ 20, 10, 11, 20, 31, 37, 49, 62, 64, 61, 60, 61, 50, 51, 32, 10,
+ 16, 27, 31, 33, 33, 36, 7, -6, 3, 14, 12, -10, -21, -40, -34, -33,
+ -47, -65, -67, -60, -40, -40, -44, -25, -10, -4, 14, 26, 22, 4, -7, 8,
+ 8, -22, -67, -65, -33, -19, -24, -20, -18, -8, 1, 26, 30, -2, -22, -25,
+ -6, 5, -1, -13, -38, -43, -31, -21, -16, -16, 9, 47, 61, 35, 22, 22,
+ 31, 24, 10, 13, 5, -2, 0, 28, 34, 1, -21, -30, -28, -18, -5, 5,
+ 18, 20, 14, 6, 6, 12, 9, 20, 33, 39, 51, 51, 42, 51, 51, 48,
+ 20, 9, 7, 5, 7, 15, 28, 19, -1, -16, -15, -4, 4, -16, -30, -41,
+ -45, -41, -50, -79, -77, -69, -65, -64, -56, -45, -40, -28, -4, 21, 17, -8,
+ -9, 21, 16, -18, -56, -58, -44, -39, -24, -22, -28, -22, -4, 29, 31, 13,
+ -9, -16, -3, 11, 13, 1, -18, -33, -15, -11, -23, -22, 11, 52, 58, 50,
+ 46, 50, 49, 36, 40, 40, 17, 6, 20, 37, 45, 29, 9, -7, -12, -11,
+ -6, 9, 30, 25, 26, 26, 17, 19, 15, 21, 24, 46, 55, 47, 43, 56,
+ 64, 52, 33, 25, 13, -3, 2, 10, 21, 26, 4, -15, -16, -13, -2, -11,
+ -32, -43, -37, -44, -61, -77, -78, -82, -82, -80, -71, -61, -72, -59, -21, 5,
+ -2, -27, -10, 15, 7, -14, -44, -59, -67, -55, -37, -38, -50, -45, -23, 5,
+ 23, 9, -6, -19, -15, 5, 14, 2, -22, -22, -10, -17, -35, -38, -3, 35,
+ 38, 43, 57, 51, 44, 49, 57, 46, 25, 14, 24, 35, 54, 41, 31, 22,
+ 1, -7, -4, 12, 23, 34, 37, 35, 35, 36, 26, 24, 33, 55, 62, 53,
+ 58, 70, 70, 73, 62, 51, 38, 14, 6, 20, 31, 32, 27, 4, -9, -1,
+ 9, -8, -21, -22, -27, -33, -53, -64, -67, -82, -86, -83, -67, -75, -97, -77,
+ -36, -15, -27, -32, -18, -1, -1, -6, -31, -62, -73, -68, -52, -52, -68, -69,
+ -50, -21, -2, 4, -10, -33, -29, -4, 2, -10, -29, -22, -8, -27, -55, -49,
+ -27, -6, 12, 31, 43, 31, 38, 44, 54, 48, 25, 11, 19, 30, 36, 41,
+ 41, 29, 11, -1, -9, 0, 15, 27, 34, 36, 46, 46, 26, 27, 39, 51,
+ 59, 62, 62, 73, 76, 77, 85, 78, 58, 35, 23, 21, 37, 53, 37, 22,
+ 15, 16, 20, 3, 0, -2, -2, -14, -33, -35, -45, -69, -77, -59, -53, -76,
+ -96, -74, -41, -30, -25, -26, -19, -4, 7, 11, -8, -40, -62, -62, -51, -55,
+ -69, -74, -71, -44, -15, -2, -14, -36, -38, -8, -7, -27, -33, -17, -12, -38,
+ -51, -57, -58, -41, -14, 8, 19, 15, 15, 31, 46, 40, 21, 9, 7, 10,
+ 20, 25, 33, 28, 16, 1, -18, -13, 0, 6, 12, 30, 39, 39, 26, 20,
+ 32, 41, 45, 53, 64, 63, 62, 80, 84, 87, 81, 51, 29, 21, 44, 52,
+ 41, 33, 29, 31, 27, 12, 8, 16, 10, -4, -7, -7, -29, -62, -57, -37,
+ -44, -68, -81, -70, -48, -33, -23, -22, -17, -5, 16, 31, 14, -15, -33, -42,
+ -41, -37, -53, -65, -74, -54, -16, 2, -12, -33, -19, -1, -10, -22, -17, -8,
+ -8, -18, -33, -48, -62, -57, -31, -1, 7, 0, 9, 22, 40, 40, 27, 14,
+ 4, 3, 10, 14, 21, 31, 20, 0, -13, -19, -17, -15, -7, 12, 29, 28,
+ 13, 20, 18, 18, 31, 38, 47, 49, 51, 56, 67, 87, 84, 56, 30, 20,
+ 31, 41, 31, 24, 32, 33, 20, 7, 14, 15, -2, -1, 13, 4, -28, -53,
+ -45, -34, -38, -59, -75, -72, -58, -44, -26, -26, -29, -8, 14, 34, 28, 10,
+ -9, -22, -26, -24, -30, -54, -78, -56, -13, -4, -17, -16, -5, 1, -6, -9,
+ -8, -1, 3, -2, -4, -28, -53, -58, -37, -10, 1, -1, 6, 20, 34, 46,
+ 40, 25, 19, 11, 7, 10, 23, 33, 28, 16, -3, -3, -17, -31, -14, 4,
+ 15, 20, 20, 16, 10, 14, 19, 23, 37, 45, 35, 37, 53, 76, 83, 62,
+ 34, 20, 27, 28, 13, 17, 29, 21, 7, 9, 13, -4, -17, -4, 13, 2,
+ -27, -53, -47, -39, -46, -56, -77, -87, -77, -58, -45, -46, -47, -33, -6, 17,
+ 22, 16, 1, -20, -25, -10, -21, -57, -79, -57, -32, -24, -23, -18, -3, -1,
+ -6, -4, -4, -5, 3, 13, 14, -6, -38, -51, -39, -22, -4, -1, 3, 14,
+ 32, 45, 46, 46, 33, 25, 15, 9, 28, 38, 32, 28, 26, 14, -9, -21,
+ -15, -5, 10, 24, 22, 22, 21, 15, 15, 23, 36, 42, 35, 31, 41, 72,
+ 87, 68, 46, 42, 34, 19, 14, 25, 25, 11, 14, 18, 14, -7, -24, -7,
+ 12, 4, -19, -41, -47, -44, -41, -52, -74, -92, -88, -72, -59, -63, -68, -53,
+ -34, -11, 12, 19, -7, -27, -15, -5, -22, -54, -76, -66, -52, -47, -41, -29,
+ -17, -12, -12, -10, -11, -19, -7, 12, 19, 3, -23, -42, -48, -31, -19, -14,
+ -6, 1, 20, 35, 39, 50, 51, 33, 16, 17, 30, 31, 32, 41, 39, 28,
+ 14, -7, -14, -5, 8, 18, 27, 34, 29, 22, 21, 26, 38, 51, 39, 27,
+ 43, 75, 84, 73, 75, 68, 46, 32, 31, 35, 27, 15, 23, 36, 26, 0,
+ -13, -4, 12, 14, 1, -23, -36, -36, -32, -36, -60, -83, -84, -70, -67, -70,
+ -66, -67, -62, -27, 8, 13, -11, -22, -7, 4, -16, -44, -63, -67, -63, -63,
+ -53, -42, -33, -25, -15, -10, -22, -27, -18, -1, 16, 9, -13, -32, -46, -42,
+ -31, -30, -24, -8, 5, 11, 25, 49, 50, 33, 25, 20, 21, 24, 29, 34,
+ 41, 41, 26, 5, -5, -7, -4, 12, 23, 33, 37, 29, 19, 24, 49, 53,
+ 33, 33, 49, 65, 73, 80, 89, 85, 63, 48, 50, 46, 30, 20, 35, 46,
+ 39, 17, 0, 2, 15, 23, 18, -2, -20, -24, -12, -19, -45, -60, -66, -70,
+ -66, -56, -61, -74, -74, -38, 0, 6, -8, -15, 3, 13, -1, -24, -42, -52,
+ -65, -64, -54, -54, -47, -31, -19, -12, -21, -32, -27, -12, 7, 13, -2, -24,
+ -36, -37, -44, -47, -32, -20, -18, -9, 12, 30, 38, 35, 26, 18, 17, 16,
+ 13, 25, 36, 37, 32, 18, 2, -11, -10, -5, 3, 28, 38, 20, 8, 25,
+ 42, 40, 28, 30, 40, 46, 54, 70, 87, 82, 66, 61, 59, 48, 28, 20,
+ 32, 43, 43, 24, 8, 1, 7, 23, 25, 3, -13, -9, -8, -15, -28, -40,
+ -58, -71, -60, -49, -58, -80, -82, -50, -17, -5, -13, -12, 6, 13, 8, -3,
+ -24, -42, -54, -59, -57, -60, -59, -43, -24, -15, -20, -30, -35, -25, 1, 11,
+ -2, -12, -18, -33, -48, -49, -41, -37, -32, -21, -8, 13, 27, 27, 27, 23,
+ 16, 8, 7, 15, 22, 32, 35, 22, 9, 0, -18, -26, -8, 20, 25, 11,
+ 4, 18, 32, 29, 22, 29, 30, 27, 38, 60, 75, 70, 68, 69, 67, 52,
+ 30, 19, 27, 36, 40, 34, 10, -2, 6, 21, 20, 4, -2, -4, -7, -9,
+ -12, -25, -52, -66, -53, -42, -53, -79, -86, -58, -33, -23, -16, -12, 0, 12,
+ 17, 13, -5, -24, -38, -44, -50, -59, -61, -51, -33, -15, -11, -28, -36, -23,
+ -4, 5, 5, 7, -3, -17, -31, -40, -38, -37, -36, -29, -14, 4, 15, 25,
+ 34, 30, 24, 19, 9, 8, 22, 33, 31, 30, 31, 16, -14, -26, -13, 14,
+ 17, 7, 8, 18, 24, 23, 28, 31, 23, 18, 30, 50, 62, 61, 63, 75,
+ 73, 59, 40, 23, 20, 30, 43, 35, 11, 0, 8, 15, 12, 6, 3, -6,
+ -10, -3, -1, -15, -46, -62, -47, -38, -54, -77, -84, -70, -53, -40, -30, -21,
+ -12, 1, 16, 20, 5, -12, -21, -33, -44, -52, -64, -64, -44, -17, -15, -27,
+ -30, -26, -15, -3, 6, 12, 9, -2, -17, -26, -29, -36, -41, -32, -21, -10,
+ 6, 18, 27, 34, 37, 25, 11, 14, 21, 26, 27, 37, 48, 33, -1, -19,
+ -8, 7, 8, 8, 16, 16, 17, 25, 34, 36, 23, 16, 28, 44, 53, 54,
+ 61, 74, 79, 75, 56, 30, 19, 31, 45, 35, 15, 9, 9, 9, 11, 9,
+ 5, -8, -14, 0, 9, -10, -40, -53, -44, -38, -51, -72, -84, -80, -69, -58,
+ -45, -38, -30, -13, 5, 13, 8, 0, -14, -25, -30, -46, -67, -72, -55, -34,
+ -26, -28, -31, -31, -26, -17, -4, 9, 11, 2, -4, -12, -22, -33, -38, -40,
+ -34, -18, -7, 2, 17, 33, 38, 29, 19, 20, 22, 17, 19, 38, 57, 43,
+ 15, 2, -1, 1, 3, 10, 18, 15, 14, 25, 38, 40, 27, 21, 28, 38,
+ 46, 50, 55, 66, 81, 90, 71, 40, 30, 37, 44, 39, 26, 18, 12, 8,
+ 14, 19, 8, -11, -13, 5, 15, -2, -28, -42, -36, -34, -45, -60, -76, -83,
+ -77, -65, -59, -55, -43, -28, -13, 5, 11, 2, -9, -11, -17, -37, -61, -71,
+ -65, -49, -38, -36, -34, -35, -36, -32, -16, -2, 1, 3, 0, -7, -13, -25,
+ -39, -46, -42, -30, -22, -15, 2, 21, 30, 24, 22, 28, 19, 5, 11, 33,
+ 50, 45, 31, 17, 6, -1, 0, 8, 16, 12, 11, 23, 37, 40, 33, 29,
+ 29, 33, 45, 48, 46, 58, 83, 97, 84, 59, 45, 46, 47, 46, 42, 31,
+ 16, 12, 23, 29, 16, -5, -9, 10, 21, 10, -12, -24, -25, -25, -29, -42,
+ -64, -73, -70, -66, -63, -58, -52, -42, -22, 0, 8, 4, 1, 3, -1, -19,
+ -44, -61, -63, -57, -50, -39, -33, -37, -39, -36, -27, -14, -4, 0, 0, 0,
+ -1, -13, -30, -42, -43, -37, -36, -30, -10, 8, 12, 15, 26, 31, 16, 1,
+ 4, 21, 37, 41, 38, 29, 13, 0, -1, 6, 8, 3, 7, 17, 26, 34,
+ 35, 27, 24, 32, 40, 37, 32, 45, 72, 89, 86, 70, 57, 48, 45, 49,
+ 50, 37, 16, 11, 25, 34, 20, -3, -7, 7, 18, 15, 2, -14, -20, -15,
+ -17, -32, -49, -61, -67, -65, -60, -61, -63, -54, -33, -12, -1, 1, 2, 10,
+ 12, -3, -26, -43, -57, -60, -54, -45, -38, -38, -39, -39, -35, -23, -13, -6,
+ -3, 2, 7, -2, -20, -30, -34, -42, -47, -38, -19, -9, -5, 7, 24, 31,
+ 19, 3, 0, 10, 23, 33, 40, 36, 18, 5, 4, 4, 0, 0, 0, 5,
+ 16, 29, 30, 22, 22, 31, 36, 27, 21, 32, 54, 74, 81, 77, 65, 49,
+ 44, 50, 55, 40, 16, 10, 24, 31, 20, 3, -6, -1, 11, 16, 5, -9,
+ -13, -12, -14, -22, -36, -53, -63, -62, -59, -63, -69, -67, -48, -25, -14, -10,
+ -1, 10, 16, 10, -6, -26, -45, -54, -55, -50, -42, -39, -39, -40, -39, -29,
+ -19, -15, -8, 4, 11, 3, -6, -11, -21, -38, -48, -40, -26, -21, -16, -3,
+ 18, 30, 24, 12, 6, 4, 11, 29, 41, 39, 28, 18, 11, 8, 5, 1,
+ -4, -2, 11, 25, 25, 19, 23, 33, 35, 25, 17, 23, 39, 57, 74, 81,
+ 72, 53, 47, 56, 60, 44, 23, 16, 22, 29, 25, 10, -4, -3, 7, 11,
+ 6, -3, -9, -11, -9, -12, -26, -42, -56, -59, -55, -61, -73, -75, -60, -42,
+ -32, -23, -12, 0, 12, 15, 7, -10, -30, -46, -53, -53, -46, -41, -43, -45,
+ -41, -32, -30, -26, -14, -1, 5, 2, 3, 3, -9, -30, -43, -40, -31, -31,
+ -28, -12, 8, 20, 25, 22, 9, 0, 6, 21, 34, 39, 35, 26, 18, 16,
+ 14, 4, -7, -5, 9, 21, 19, 16, 23, 35, 37, 28, 20, 20, 26, 43,
+ 67, 82, 74, 57, 54, 62, 63, 52, 33, 21, 23, 30, 28, 14, 1, -1,
+ 3, 8, 7, -1, -7, -9, -6, -5, -15, -34, -49, -51, -51, -60, -72, -76,
+ -70, -57, -46, -37, -25, -13, 3, 14, 14, 3, -15, -33, -48, -52, -47, -45,
+ -49, -49, -41, -37, -39, -35, -21, -10, -5, -2, 6, 12, 1, -19, -32, -34,
+ -36, -39, -34, -23, -9, 9, 23, 25, 14, 3, 2, 12, 25, 36, 37, 30,
+ 24, 25, 24, 10, -5, -4, 9, 18, 15, 14, 23, 34, 38, 36, 30, 19,
+ 15, 32, 61, 78, 75, 63, 60, 67, 71, 62, 42, 29, 30, 33, 32, 20,
+ 8, 4, 6, 8, 8, 3, -5, -9, -2, 3, -7, -25, -37, -42, -45, -54,
+ -66, -74, -74, -67, -58, -49, -40, -27, -9, 5, 13, 13, 0, -21, -39, -45,
+ -44, -49, -54, -50, -44, -44, -47, -42, -29, -21, -19, -11, 5, 12, 4, -8,
+ -18, -28, -36, -40, -40, -36, -24, -4, 14, 21, 17, 7, 0, 3, 17, 32,
+ 34, 29, 28, 34, 33, 17, 0, 0, 9, 13, 12, 14, 20, 27, 38, 46,
+ 39, 21, 11, 24, 51, 71, 74, 66, 64, 73, 78, 71, 54, 40, 38, 41,
+ 38, 28, 17, 11, 9, 12, 14, 7, -3, -5, 3, 9, 2, -12, -23, -28,
+ -35, -45, -55, -65, -71, -68, -62, -57, -50, -37, -22, -7, 10, 20, 12, -8,
+ -24, -32, -39, -48, -52, -49, -45, -49, -52, -44, -34, -33, -30, -18, -3, 5,
+ 5, 1, -8, -19, -29, -37, -43, -45, -37, -18, 0, 13, 18, 10, -1, -3,
+ 10, 24, 26, 23, 29, 38, 37, 21, 8, 5, 6, 8, 10, 12, 11, 16,
+ 34, 49, 46, 27, 10, 15, 38, 59, 67, 63, 63, 72, 81, 77, 61, 48,
+ 45, 45, 42, 35, 23, 13, 11, 17, 18, 9, -3, -5, 3, 10, 6, -3,
+ -12, -19, -24, -34, -46, -57, -64, -65, -66, -63, -56, -48, -39, -22, 1, 17,
+ 16, 3, -8, -17, -30, -44, -47, -44, -47, -53, -52, -44, -41, -41, -38, -28,
+ -14, -3, 3, 3, -2, -9, -17, -28, -42, -49, -46, -34, -17, 3, 14, 9,
+ -3, -6, 5, 15, 13, 15, 26, 36, 35, 25, 16, 8, 2, 4, 9, 6,
+ 1, 4, 22, 43, 48, 31, 11, 7, 24, 45, 55, 54, 55, 68, 79, 77,
+ 66, 54, 48, 47, 47, 41, 27, 14, 11, 18, 20, 10, -2, -6, 0, 7,
+ 8, 2, -6, -12, -14, -23, -38, -49, -55, -62, -66, -63, -60, -59, -53, -37,
+ -12, 8, 13, 10, 7, -4, -21, -35, -37, -39, -47, -53, -51, -45, -44, -44,
+ -42, -36, -24, -10, 0, 2, 1, 1, -3, -15, -30, -42, -49, -45, -30, -6,
+ 10, 7, -2, -3, 5, 9, 6, 11, 23, 32, 35, 33, 25, 14, 6, 9,
+ 12, 8, -2, -4, 13, 36, 48, 39, 18, 7, 17, 34, 43, 45, 50, 62,
+ 74, 78, 71, 59, 51, 49, 52, 48, 32, 16, 12, 19, 21, 13, 1, -6,
+ -5, 2, 6, 2, -4, -6, -9, -18, -29, -40, -51, -60, -65, -63, -63, -68,
+ -68, -53, -30, -12, 0, 10, 13, 3, -14, -25, -29, -35, -45, -52, -52, -49,
+ -47, -47, -47, -46, -35, -20, -10, -5, -1, 4, 4, -4, -15, -30, -47, -54,
+ -41, -15, 1, 0, -2, 2, 6, 4, 3, 7, 16, 26, 35, 38, 32, 20,
+ 12, 14, 18, 12, -1, -8, 3, 27, 46, 44, 26, 14, 17, 28, 35, 38,
+ 44, 55, 69, 78, 77, 66, 55, 54, 60, 58, 41, 24, 17, 19, 23, 20,
+ 7, -4, -4, 0, 2, 1, 0, -2, -4, -10, -17, -28, -42, -55, -59, -56,
+ -61, -72, -74, -63, -47, -32, -14, 5, 13, 7, -4, -12, -19, -28, -38, -46,
+ -51, -50, -46, -47, -51, -52, -43, -30, -20, -13, -5, 0, 4, 4, 2, -13,
+ -40, -55, -47, -25, -12, -8, -3, 3, 5, 4, 2, 3, 7, 18, 32, 41,
+ 36, 25, 18, 21, 25, 21, 5, -9, -3, 19, 41, 45, 34, 24, 23, 27,
+ 30, 33, 38, 47, 62, 78, 82, 72, 61, 61, 67, 66, 54, 37, 24, 23,
+ 28, 25, 15, 5, 0, 0, 0, 1, 2, 2, -1, -4, -5, -15, -34, -47,
+ -49, -49, -58, -69, -73, -70, -63, -51, -30, -8, 5, 7, 3, -4, -11, -20,
+ -29, -41, -49, -50, -46, -49, -54, -56, -50, -42, -33, -22, -13, -10, -6, 5,
+ 12, -1, -30, -50, -50, -38, -27, -18, -10, -3, 1, 2, 2, -2, -4, 6,
+ 24, 36, 36, 27, 19, 22, 30, 28, 10, -8, -10, 9, 30, 39, 35, 30,
+ 26, 26, 28, 29, 29, 35, 53, 73, 80, 74, 65, 63, 69, 72, 64, 47,
+ 33, 28, 29, 28, 21, 12, 6, 2, -2, 1, 4, 1, -2, 2, 6, -4,
+ -23, -35, -38, -42, -51, -60, -66, -70, -71, -63, -45, -23, -5, 4, 6, 3,
+ -2, -7, -18, -32, -42, -43, -43, -47, -52, -54, -53, -51, -42, -27, -20, -21,
+ -14, 4, 17, 10, -13, -35, -45, -44, -37, -26, -17, -11, -3, 3, 3, -3,
+ -9, -4, 13, 31, 35, 27, 19, 23, 34, 36, 19, -3, -10, 2, 19, 31,
+ 35, 33, 29, 30, 32, 28, 22, 26, 43, 63, 76, 75, 67, 65, 71, 75,
+ 70, 57, 43, 36, 34, 30, 26, 21, 14, 5, 1, 4, 3, -2, -2, 6,
+ 11, 3, -11, -22, -29, -36, -43, -50, -57, -67, -74, -72, -60, -40, -19, -5,
+ 2, 4, 6, 3, -8, -23, -32, -35, -40, -45, -47, -51, -57, -58, -47, -33,
+ -30, -32, -24, -5, 13, 14, 1, -18, -36, -45, -42, -35, -27, -20, -11, 0,
+ 3, -3, -12, -12, 1, 21, 31, 25, 16, 20, 34, 40, 26, 5, -7, -6,
+ 7, 21, 27, 26, 27, 31, 33, 27, 17, 15, 28, 50, 65, 68, 64, 62,
+ 68, 74, 72, 61, 51, 44, 35, 29, 28, 25, 15, 7, 5, 5, -1, -8,
+ -5, 3, 8, 4, -4, -12, -22, -32, -38, -42, -50, -61, -72, -77, -73, -57,
+ -36, -20, -11, -2, 7, 8, -3, -14, -22, -30, -38, -41, -42, -49, -60, -62,
+ -52, -41, -40, -41, -34, -18, 0, 11, 10, -3, -23, -38, -42, -40, -36, -31,
+ -20, -6, 2, -1, -13, -19, -9, 12, 25, 20, 12, 17, 30, 39, 34, 17,
+ -2, -8, 1, 13, 19, 21, 23, 31, 37, 32, 18, 10, 18, 36, 55, 62,
+ 60, 60, 67, 73, 72, 68, 61, 51, 41, 35, 34, 28, 18, 12, 11, 8,
+ -2, -9, -7, 0, 4, 5, 3, -3, -14, -24, -31, -36, -41, -50, -64, -77,
+ -80, -68, -51, -37, -26, -11, 3, 6, 2, -3, -13, -24, -32, -33, -34, -46,
+ -60, -62, -54, -47, -46, -47, -43, -31, -13, 4, 12, 6, -9, -23, -34, -39,
+ -40, -38, -29, -14, 0, 2, -11, -22, -15, 4, 17, 16, 11, 13, 25, 39,
+ 41, 28, 9, -3, 0, 9, 15, 15, 19, 30, 40, 39, 26, 12, 11, 28,
+ 45, 54, 56, 60, 66, 70, 73, 74, 69, 58, 49, 45, 42, 32, 22, 18,
+ 19, 14, 3, -6, -7, -4, 0, 5, 6, 3, -5, -14, -24, -30, -32, -38,
+ -53, -71, -78, -72, -63, -54, -39, -22, -8, 1, 6, 6, -4, -18, -25, -23,
+ -25, -39, -54, -58, -54, -49, -49, -50, -49, -42, -26, -7, 7, 9, 2, -9,
+ -20, -30, -38, -43, -39, -22, -2, 3, -9, -20, -16, -2, 11, 14, 10, 10,
+ 20, 36, 46, 40, 22, 8, 6, 11, 13, 12, 15, 26, 41, 46, 36, 20,
+ 14, 24, 38, 47, 54, 60, 64, 69, 76, 81, 76, 66, 60, 58, 53, 40,
+ 30, 27, 27, 22, 12, 3, -3, -4, -1, 4, 8, 8, 5, -4, -15, -21,
+ -21, -25, -41, -58, -69, -71, -70, -64, -51, -35, -23, -9, 5, 10, 1, -13,
+ -17, -15, -19, -32, -46, -54, -54, -51, -50, -52, -55, -53, -40, -22, -6, 3,
+ 4, -2, -10, -19, -32, -47, -49, -32, -11, -3, -10, -20, -20, -10, 2, 7,
+ 5, 2, 10, 28, 42, 41, 29, 16, 10, 11, 11, 7, 6, 17, 35, 45,
+ 39, 26, 18, 19, 26, 37, 47, 53, 56, 61, 73, 81, 76, 68, 65, 65,
+ 59, 46, 36, 31, 28, 25, 19, 9, -1, -6, -4, -1, 2, 8, 9, 0,
+ -10, -15, -14, -18, -32, -46, -57, -68, -74, -71, -61, -51, -41, -23, -2, 8,
+ 2, -8, -11, -10, -13, -23, -37, -48, -53, -51, -49, -53, -59, -60, -53, -37,
+ -19, -7, -3, -2, -1, -6, -22, -43, -52, -42, -21, -9, -12, -20, -23, -16,
+ -4, 3, -1, -6, 0, 18, 34, 40, 33, 22, 16, 16, 13, 5, 0, 9,
+ 27, 39, 40, 32, 24, 18, 19, 29, 40, 44, 46, 55, 69, 77, 75, 71,
+ 70, 70, 65, 55, 45, 37, 32, 30, 26, 17, 7, 0, -5, -6, -1, 8,
+ 11, 4, -5, -7, -7, -13, -21, -30, -44, -59, -69, -69, -65, -63, -56, -36,
+ -13, 1, 1, -4, -6, -5, -6, -12, -25, -40, -47, -47, -46, -50, -56, -62,
+ -61, -48, -30, -18, -12, -6, 4, 6, -7, -32, -49, -46, -30, -16, -12, -19,
+ -25, -20, -7, 0, -3, -9, -7, 8, 26, 36, 34, 27, 24, 24, 19, 7,
+ -2, 4, 18, 31, 38, 38, 30, 20, 18, 26, 34, 35, 38, 48, 62, 71,
+ 73, 72, 73, 72, 70, 64, 53, 43, 38, 35, 30, 23, 16, 7, -4, -10,
+ -4, 6, 8, 3, -1, -2, -4, -9, -12, -19, -33, -51, -61, -65, -69, -73,
+ -70, -52, -30, -13, -6, -5, -7, -5, -2, -5, -17, -31, -41, -45, -44, -45,
+ -53, -64, -67, -58, -43, -31, -26, -17, -1, 10, 3, -19, -41, -48, -39, -23,
+ -16, -21, -27, -24, -12, -3, -5, -13, -15, -3, 16, 28, 29, 26, 28, 31,
+ 24, 10, 0, 0, 8, 20, 33, 38, 32, 22, 19, 24, 28, 28, 30, 40,
+ 52, 61, 68, 71, 72, 73, 73, 69, 59, 51, 45, 39, 32, 28, 26, 15,
+ 0, -9, -5, 2, 4, 2, 1, -1, -4, -6, -5, -10, -24, -41, -50, -56,
+ -66, -76, -77, -66, -47, -27, -15, -11, -10, -5, 0, -1, -8, -20, -33, -40,
+ -40, -40, -48, -62, -70, -64, -51, -43, -39, -29, -11, 7, 10, -5, -28, -43,
+ -41, -28, -20, -22, -29, -28, -17, -6, -5, -14, -20, -12, 6, 19, 22, 23,
+ 30, 35, 31, 20, 8, 0, 1, 13, 29, 37, 33, 26, 25, 27, 27, 25,
+ 26, 33, 43, 54, 63, 67, 70, 74, 76, 72, 66, 61, 54, 44, 37, 36,
+ 34, 24, 8, -3, -4, -2, 0, 2, 3, -1, -5, -3, 2, -2, -16, -29,
+ -36, -44, -57, -70, -79, -76, -60, -41, -27, -19, -14, -8, -1, 3, 0, -10,
+ -24, -33, -33, -32, -40, -55, -65, -63, -56, -51, -48, -40, -23, -1, 12, 7,
+ -13, -32, -37, -29, -21, -21, -28, -29, -19, -6, -2, -12, -20, -14, 0, 11,
+ 16, 22, 30, 37, 38, 33, 21, 7, 0, 9, 26, 36, 35, 32, 32, 32,
+ 31, 28, 27, 30, 38, 50, 58, 63, 70, 78, 79, 76, 74, 72, 64, 53,
+ 46, 45, 44, 34, 20, 9, 3, -1, 1, 7, 7, 0, -4, 2, 8, 5,
+ -5, -15, -23, -30, -41, -58, -73, -77, -68, -53, -38, -28, -21, -14, -5, 4,
+ 7, -1, -15, -25, -25, -24, -32, -48, -59, -61, -59, -57, -57, -54, -39, -16,
+ 4, 8, -5, -24, -33, -30, -24, -24, -32, -35, -26, -11, -6, -14, -20, -19,
+ -10, -2, 5, 13, 21, 29, 37, 40, 30, 11, 0, 4, 17, 27, 30, 31,
+ 31, 32, 32, 29, 23, 23, 31, 40, 45, 52, 63, 72, 74, 73, 75, 75,
+ 67, 56, 51, 50, 46, 38, 29, 18, 6, -3, -1, 5, 3, -4, -7, -2,
+ 4, 5, -2, -11, -17, -21, -30, -47, -66, -78, -77, -66, -53, -42, -34, -27,
+ -16, -3, 6, 1, -12, -21, -21, -21, -28, -42, -54, -60, -60, -61, -65, -67,
+ -57, -35, -11, 1, -3, -18, -30, -30, -25, -27, -36, -41, -32, -19, -13, -17,
+ -22, -22, -19, -14, -6, 2, 7, 17, 31, 41, 34, 17, 3, 1, 8, 17,
+ 23, 25, 26, 30, 32, 28, 22, 21, 25, 30, 34, 42, 54, 63, 66, 70,
+ 77, 77, 69, 61, 57, 55, 49, 44, 39, 28, 11, 2, 2, 5, 3, -3,
+ -8, -4, 3, 6, 2, -4, -9, -11, -16, -31, -52, -68, -75, -71, -61, -50,
+ -43, -38, -26, -8, 5, 4, -6, -13, -14, -13, -19, -31, -44, -51, -52, -55,
+ -64, -71, -67, -49, -24, -4, -1, -12, -22, -21, -18, -22, -33, -39, -33, -22,
+ -16, -16, -17, -19, -20, -16, -9, -4, -2, 5, 18, 31, 37, 32, 21, 11,
+ 9, 12, 17, 20, 24, 28, 32, 31, 28, 26, 26, 26, 28, 34, 43, 51,
+ 57, 65, 74, 77, 75, 72, 68, 63, 59, 56, 53, 44, 31, 19, 12, 11,
+ 8, 3, -2, -3, 0, 4, 5, 2, 0, -1, -3, -11, -25, -42, -58, -66,
+ -65, -59, -54, -51, -42, -27, -11, -2, -3, -6, -7, -7, -9, -16, -27, -36,
+ -40, -44, -52, -63, -70, -66, -49, -28, -15, -13, -16, -16, -13, -16, -24, -31,
+ -33, -29, -24, -19, -17, -19, -20, -18, -14, -13, -12, -6, 7, 22, 33, 35,
+ 28, 18, 12, 12, 14, 17, 21, 27, 31, 31, 30, 30, 28, 25, 25, 30,
+ 36, 42, 49, 58, 67, 74, 76, 75, 71, 66, 62, 60, 59, 53, 41, 29,
+ 19, 14, 11, 7, 1, -3, -2, 1, 3, 3, 1, 0, 0, -3, -11, -26,
+ -44, -59, -65, -63, -60, -57, -52, -41, -25, -11, -4, -4, -6, -6, -6, -9,
+ -17, -27, -35, -39, -44, -53, -65, -71, -65, -47, -28, -16, -15, -16, -15, -14,
+ -17, -25, -32, -33, -29, -24, -19, -17, -19, -20, -18, -14, -13, -12, -6, -2,
+ 1, 6, 5, 21, 46, 42, 15, 0, 5, 34, 48, 29, -4, -31, -33, -17,
+ 26, 49, 32, 0, -21, -15, 14, 24, 24, 16, 0, 3, 11, 11, 11, 5,
+ 9, 9, 8, 11, 30, 27, 22, 7, -3, -3, 10, 2, -2, -4, -13, -4,
+ -4, -2, -2, -3, -7, -6, -14, -15, -14, -14, -13, -3, -14, -16, -18, -13,
+ -15, -16, -22, -20, -14, -3, -6, -4, -14, -11, -6, -10, -15, -15, -16, -9,
+ -10, -19, -3, -5, -17, -15, -18, -16, -14, -14, -12, -15, -7, -22, -19, -17,
+ -20, -11, -17, -14, -11, -8, -10, -13, -12, -11, -6, -6, -9, 1, 1, -3,
+ 0, 6, -2, -9, 7, -8, 8, 4, 3, 1, -6, -2, -2, 2, -5, -7,
+ -4, -7, -8, -9, -6, -6, 0, -8, -12, -12, -13, -8, -4, -7, -3, -11,
+ -6, -15, -7, -9, -9, -3, -10, -8, -9, -15, -10, -2, 2, -7, -16, -17,
+ -15, -13, -9, -6, -5, -7, -9, -15, -17, -12, -19, -12, -8, -8, -4, -6,
+ -3, 0, -4, -11, -13, -7, -6, -2, 4, 4, 8, 10, 4, 3, 3, 4,
+ 7, 12, 11, 14, 15, 20, 20, 18, 16, 17, 15, 14, 15, 22, 23, 28,
+ 34, 29, 28, 17, 22, 24, 23, 25, 28, 28, 30, 24, 19, 16, 13, 18,
+ 20, 15, 8, 2, 3, 0, 2, 0, -3, -2, -9, -20, -23, -25, -24, -23,
+ -27, -33, -38, -39, -44, -36, -42, -44, -48, -53, -54, -56, -52, -50, -40, -35,
+ -44, -43, -44, -39, -28, -24, -23, -22, -15, -9, 2, 11, 19, 28, 31, 31,
+ 32, 35, 43, 61, 70, 78, 81, 73, 78, 78, 78, 85, 82, 85, 88, 87,
+ 84, 83, 83, 79, 74, 62, 49, 45, 42, 43, 44, 38, 30, 18, 6, -5,
+ -15, -17, -15, -22, -28, -38, -46, -48, -50, -58, -59, -72, -80, -83, -89, -88,
+ -89, -87, -81, -84, -93, -105, -110, -109, -110, -102, -96, -82, -65, -62, -60, -60,
+ -60, -51, -43, -37, -28, -16, 1, 15, 28, 35, 41, 46, 53, 56, 60, 66,
+ 77, 91, 101, 102, 101, 99, 104, 103, 97, 91, 86, 90, 91, 86, 85, 79,
+ 75, 71, 59, 48, 39, 35, 33, 32, 28, 22, 15, 13, 7, 3, -7, -15,
+ -16, -18, -19, -23, -28, -29, -33, -37, -47, -52, -56, -63, -61, -70, -67, -70,
+ -72, -72, -80, -93, -91, -99, -103, -96, -108, -105, -109, -112, -94, -81, -73, -67,
+ -71, -77, -69, -63, -57, -38, -27, -15, 0, 4, 6, 19, 26, 41, 53, 49,
+ 56, 58, 69, 84, 91, 95, 101, 103, 98, 93, 85, 87, 102, 102, 103, 95,
+ 81, 78, 78, 71, 66, 60, 51, 50, 44, 39, 34, 34, 32, 27, 15, 0,
+ -6, -8, -3, -3, -11, -10, -18, -21, -26, -35, -39, -38, -44, -48, -53, -63,
+ -61, -61, -71, -63, -86, -89, -86, -107, -99, -109, -108, -109, -108, -121, -128, -105,
+ -102, -83, -67, -88, -82, -76, -78, -62, -47, -41, -19, -6, 1, 7, 13, 33,
+ 44, 64, 61, 59, 68, 73, 93, 98, 107, 114, 109, 123, 107, 100, 105, 100,
+ 111, 117, 100, 93, 92, 86, 85, 80, 70, 59, 58, 47, 38, 41, 33, 40,
+ 38, 25, 16, 1, -2, -3, -3, -4, -10, -16, -12, -21, -28, -28, -36, -38,
+ -39, -52, -61, -61, -67, -63, -65, -76, -77, -86, -95, -95, -107, -109, -112, -112,
+ -121, -121, -122, -105, -79, -80, -71, -80, -84, -73, -70, -56, -43, -28, -10, 6,
+ 11, 17, 31, 43, 63, 69, 69, 65, 77, 88, 101, 113, 112, 127, 122, 122,
+ 115, 104, 112, 116, 122, 117, 106, 99, 97, 96, 94, 86, 75, 70, 61, 53,
+ 44, 41, 46, 47, 45, 28, 19, 9, 5, 9, 1, -8, -14, -20, -24, -26,
+ -28, -29, -36, -39, -42, -45, -41, -42, -45, -46, -49, -47, -50, -55, -53, -61,
+ -63, -67, -83, -78, -89, -91, -88, -100, -93, -108, -110, -110, -115, -90, -100, -91,
+ -80, -91, -73, -62, -60, -41, -33, -36, -25, -16, -9, 8, 18, 35, 40, 57,
+ 61, 66, 95, 94, 106, 114, 105, 117, 111, 117, 118, 115, 120, 111, 109, 111,
+ 104, 102, 106, 93, 88, 76, 66, 63, 52, 53, 31, 27, 25, 5, 12, 1,
+ -5, 0, -15, -17, -23, -27, -27, -31, -31, -37, -44, -41, -43, -43, -35, -45,
+ -43, -41, -50, -49, -51, -57, -58, -62, -72, -76, -79, -81, -82, -86, -92, -94,
+ -100, -109, -110, -102, -99, -96, -83, -96, -83, -67, -73, -45, -41, -42, -27, -27,
+ -19, -5, 7, 14, 30, 44, 46, 57, 75, 84, 98, 108, 102, 112, 114, 110,
+ 120, 115, 116, 117, 108, 112, 107, 104, 108, 99, 96, 90, 73, 69, 66, 57,
+ 48, 36, 26, 18, 13, 6, -3, 3, -8, -14, -15, -26, -25, -26, -33, -33,
+ -40, -45, -45, -45, -42, -43, -44, -45, -48, -46, -55, -57, -58, -62, -67, -73,
+ -78, -80, -81, -82, -89, -93, -99, -106, -108, -115, -100, -95, -103, -77, -91, -85,
+ -59, -63, -48, -32, -36, -33, -18, -14, -6, 11, 21, 27, 47, 55, 56, 81,
+ 92, 96, 114, 106, 111, 116, 110, 121, 113, 115, 115, 105, 111, 106, 101, 103,
+ 100, 92, 84, 74, 66, 60, 58, 43, 29, 29, 13, 9, 10, -6, -2, -6,
+ -16, -18, -22, -27, -30, -30, -35, -44, -43, -46, -46, -42, -44, -48, -45, -46,
+ -50, -54, -51, -61, -63, -61, -85, -76, -80, -94, -75, -98, -97, -93, -111, -103,
+ -106, -97, -97, -90, -79, -93, -73, -64, -67, -39, -38, -41, -20, -20, -12, 11,
+ 10, 30, 40, 48, 62, 62, 85, 91, 99, 111, 101, 112, 111, 113, 120, 112,
+ 119, 111, 108, 114, 101, 102, 104, 89, 91, 79, 63, 67, 56, 52, 41, 29,
+ 26, 12, 14, 3, -5, 1, -14, -15, -19, -27, -24, -30, -31, -34, -43, -43,
+ -45, -48, -40, -48, -48, -45, -51, -49, -53, -56, -57, -63, -69, -76, -86, -80,
+ -86, -90, -87, -98, -101, -101, -108, -103, -88, -96, -88, -77, -89, -70, -60, -56,
+ -39, -34, -30, -26, -11, -4, 6, 26, 27, 42, 54, 57, 72, 86, 95, 105,
+ 107, 108, 112, 109, 116, 118, 112, 117, 108, 109, 107, 104, 103, 99, 97, 83,
+ 77, 71, 57, 60, 49, 35, 30, 21, 11, 11, 4, -2, -3, -13, -17, -22,
+ -24, -28, -29, -29, -39, -39, -44, -44, -41, -45, -44, -50, -49, -49, -56, -50,
+ -60, -62, -55, -82, -70, -82, -90, -80, -95, -95, -100, -105, -112, -112, -93, -102,
+ -91, -81, -91, -77, -60, -65, -45, -33, -40, -25, -21, -14, 5, 10, 30, 35,
+ 49, 61, 61, 87, 94, 102, 109, 109, 112, 112, 116, 117, 116, 118, 116, 106,
+ 113, 108, 101, 110, 96, 91, 84, 69, 66, 58, 54, 38, 29, 26, 12, 11,
+ 6, -2, -2, -8, -16, -20, -23, -27, -28, -33, -34, -44, -43, -43, -47, -39,
+ -44, -47, -43, -47, -49, -50, -52, -57, -58, -68, -75, -76, -83, -86, -86, -91,
+ -97, -98, -103, -109, -102, -91, -99, -84, -81, -93, -65, -66, -60, -37, -42, -33,
+ -25, -18, -9, 6, 16, 28, 41, 49, 57, 68, 84, 93, 102, 106, 106, 110,
+ 107, 116, 114, 111, 119, 106, 111, 108, 101, 104, 99, 94, 85, 76, 68, 61,
+ 56, 49, 34, 28, 21, 10, 10, 2, -3, -3, -13, -15, -24, -26, -28, -34,
+ -31, -42, -45, -43, -48, -44, -43, -47, -47, -47, -48, -51, -57, -57, -63, -70,
+ -72, -80, -86, -81, -92, -88, -96, -103, -100, -113, -110, -96, -101, -96, -79, -91,
+ -82, -59, -68, -47, -34, -39, -29, -18, -13, -5, 18, 22, 32, 54, 52, 64,
+ 83, 90, 100, 108, 109, 110, 113, 113, 116, 113, 117, 113, 106, 111, 103, 100,
+ 101, 98, 86, 82, 73, 59, 61, 53, 36, 34, 24, 12, 10, 5, -5, -3,
+ -8, -17, -18, -24, -27, -29, -30, -35, -40, -41, -45, -43, -43, -42, -45, -46,
+ -44, -50, -49, -55, -58, -55, -71, -70, -79, -87, -77, -92, -88, -95, -104, -100,
+ -115, -107, -91, -105, -85, -83, -97, -67, -68, -65, -37, -43, -33, -29, -21, -9,
+ 0, 18, 23, 35, 55, 48, 69, 87, 86, 108, 107, 103, 117, 106, 117, 118,
+ 113, 122, 109, 111, 111, 102, 110, 101, 98, 92, 77, 73, 62, 59, 54, 34,
+ 34, 21, 11, 15, 2, 2, 2, -14, -12, -23, -26, -26, -33, -30, -40, -44,
+ -42, -49, -41, -41, -44, -43, -46, -49, -51, -59, -54, -63, -67, -64, -84, -79,
+ -76, -91, -82, -87, -100, -100, -101, -118, -101, -89, -107, -81, -82, -93, -65, -57,
+ -57, -36, -26, -39, -17, -9, -13, 14, 21, 26, 45, 53, 54, 76, 88, 95,
+ 111, 106, 111, 114, 109, 120, 115, 115, 116, 110, 105, 109, 104, 98, 105, 94,
+ 83, 81, 68, 60, 62, 49, 32, 33, 18, 9, 12, 0, -3, -3, -13, -18,
+ -20, -24, -27, -26, -31, -37, -40, -42, -42, -43, -42, -44, -48, -48, -47, -51,
+ -54, -52, -56, -64, -68, -75, -84, -79, -89, -91, -93, -104, -105, -110, -114, -97,
+ -97, -96, -78, -89, -81, -58, -66, -47, -34, -40, -31, -23, -14, -6, 14, 22,
+ 31, 54, 55, 63, 87, 91, 103, 113, 105, 111, 113, 109, 119, 112, 117, 114,
+ 106, 113, 106, 105, 105, 99, 93, 81, 74, 61, 58, 55, 36, 30, 25, 10,
+ 11, 6, -5, 1, -8, -16, -19, -25, -27, -32, -32, -37, -44, -41, -47, -43,
+ -39, -43, -44, -45, -46, -46, -56, -53, -55, -72, -64, -74, -91, -72, -88, -97,
+ -80, -100, -105, -100, -111, -111, -88, -100, -99, -74, -97, -79, -54, -68, -43, -32,
+ -41, -26, -10, -16, 6, 22, 19, 41, 51, 49, 69, 86, 88, 103, 107, 100,
+ 119, 110, 111, 125, 110, 115, 115, 104, 108, 106, 99, 98, 98, 82, 76, 71,
+ 60, 60, 52, 34, 30, 25, 9, 11, 3, -6, 0, -15, -18, -21, -27, -27,
+ -30, -31, -38, -39, -43, -43, -39, -43, -44, -46, -47, -47, -54, -53, -59, -58,
+ -65, -71, -75, -81, -75, -90, -83, -90, -100, -95, -111, -109, -101, -97, -100, -84,
+ -86, -89, -62, -64, -50, -34, -37, -30, -21, -11, -8, 10, 19, 26, 47, 49,
+ 59, 76, 89, 99, 107, 109, 110, 115, 113, 119, 115, 114, 115, 106, 111, 103,
+ 103, 101, 98, 94, 81, 78, 65, 63, 59, 43, 34, 25, 17, 10, 7, -4,
+ -3, -6, -14, -16, -23, -24, -28, -29, -33, -41, -41, -46, -43, -40, -44, -44,
+ -46, -46, -47, -50, -54, -56, -58, -69, -70, -76, -83, -75, -87, -87, -91, -100,
+ -100, -109, -108, -97, -98, -93, -83, -88, -76, -61, -59, -43, -36, -33, -28, -18,
+ -11, -4, 14, 21, 31, 52, 51, 63, 84, 90, 101, 111, 104, 113, 113, 111,
+ 118, 112, 114, 109, 108, 109, 102, 106, 101, 98, 94, 79, 74, 66, 58, 55,
+ 39, 29, 24, 13, 11, 5, -4, 0, -10, -15, -17, -24, -25, -28, -29, -34,
+ -41, -41, -47, -42, -44, -46, -45, -50, -45, -50, -55, -48, -60, -60, -65, -76,
+ -77, -83, -84, -91, -92, -94, -106, -103, -109, -106, -89, -101, -82, -81, -88, -63,
+ -66, -54, -36, -40, -31, -25, -16, -7, 6, 17, 30, 41, 55, 56, 73, 89,
+ 92, 109, 104, 106, 114, 104, 117, 113, 110, 116, 105, 108, 106, 100, 102, 98,
+ 94, 85, 74, 67, 59, 55, 48, 31, 28, 19, 10, 12, 0, 2, -2, -11,
+ -11, -21, -21, -26, -30, -30, -40, -43, -43, -44, -40, -39, -41, -43, -42, -46,
+ -52, -52, -58, -63, -65, -75, -79, -83, -80, -89, -85, -88, -101, -94, -104, -114,
+ -93, -97, -104, -78, -92, -89, -60, -68, -48, -36, -36, -26, -21, -8, -5, 12,
+ 23, 26, 47, 50, 54, 77, 85, 96, 109, 102, 114, 112, 109, 125, 112, 114,
+ 118, 102, 110, 103, 99, 101, 96, 92, 79, 76, 66, 59, 61, 43, 32, 31,
+ 14, 10, 9, -5, -2, -9, -17, -18, -28, -25, -31, -31, -31, -42, -38, -43,
+ -41, -39, -43, -44, -47, -45, -48, -51, -53, -54, -61, -64, -67, -77, -76, -82,
+ -81, -89, -93, -97, -106, -108, -105, -96, -99, -88, -82, -92, -67, -64, -60, -38,
+ -38, -36, -24, -20, -16, 4, 11, 21, 36, 46, 53, 66, 85, 88, 103, 108,
+ 102, 115, 107, 112, 115, 109, 114, 104, 106, 106, 99, 102, 101, 92, 89, 81,
+ 67, 66, 58, 47, 39, 28, 21, 11, 12, 2, -2, 2, -12, -12, -17, -25,
+ -24, -29, -30, -36, -39, -41, -41, -41, -39, -41, -44, -44, -47, -51, -52, -54,
+ -59, -63, -65, -75, -79, -75, -90, -81, -89, -99, -92, -109, -109, -105, -99, -97,
+ -92, -80, -90, -71, -58, -60, -37, -32, -37, -19, -15, -14, 9, 14, 23, 42,
+ 46, 56, 67, 83, 96, 100, 111, 106, 111, 114, 111, 117, 111, 112, 109, 103,
+ 107, 100, 99, 103, 92, 88, 82, 65, 66, 59, 48, 39, 27, 22, 12, 9,
+ 5, -5, 0, -12, -16, -17, -26, -25, -26, -31, -34, -40, -41, -41, -41, -40,
+ -42, -47, -43, -46, -46, -52, -50, -52, -61, -59, -74, -75, -77, -83, -84, -91,
+ -92, -105, -100, -106, -109, -81, -103, -86, -73, -96, -64, -62, -59, -38, -39, -36,
+ -28, -15, -11, 3, 18, 25, 37, 53, 53, 67, 89, 85, 106, 103, 98, 115,
+ 99, 114, 115, 103, 116, 103, 104, 109, 98, 101, 98, 91, 84, 75, 67, 60,
+ 55, 50, 31, 28, 20, 7, 15, 0, -3, 2, -15, -12, -19, -25, -24, -32,
+ -32, -38, -44, -44, -45, -42, -41, -44, -43, -46, -44, -44, -58, -48, -63, -67,
+ -63, -87, -75, -83, -90, -81, -94, -95, -95, -107, -109, -99, -95, -99, -85, -85,
+ -90, -68, -62, -60, -36, -34, -39, -15, -13, -9, 14, 15, 29, 42, 50, 55,
+ 68, 87, 91, 101, 107, 106, 110, 113, 114, 115, 114, 112, 108, 105, 106, 98,
+ 98, 100, 88, 84, 75, 63, 63, 57, 46, 34, 28, 18, 10, 8, 0, -5,
+ -5, -15, -19, -20, -26, -26, -26, -31, -36, -40, -42, -43, -42, -39, -44, -44,
+ -42, -44, -47, -51, -52, -54, -65, -63, -76, -81, -68, -93, -84, -85, -104, -92,
+ -105, -109, -95, -95, -96, -84, -82, -84, -64, -64, -52, -39, -37, -33, -23, -11,
+ -9, 10, 20, 25, 49, 46, 60, 76, 82, 98, 101, 104, 110, 108, 108, 116,
+ 111, 111, 113, 104, 108, 106, 101, 98, 99, 92, 80, 79, 63, 61, 59, 41,
+ 35, 27, 18, 13, 9, 2, 0, -5, -12, -15, -20, -22, -26, -27, -30, -38,
+ -39, -42, -40, -39, -40, -40, -45, -43, -47, -49, -54, -53, -57, -70, -59, -80,
+ -77, -72, -93, -75, -91, -99, -93, -105, -108, -97, -92, -99, -80, -84, -84, -61,
+ -59, -49, -35, -28, -34, -14, -9, -10, 19, 17, 27, 47, 47, 61, 72, 87,
+ 95, 105, 104, 110, 111, 109, 117, 109, 111, 109, 103, 103, 102, 97, 95, 100,
+ 85, 81, 77, 61, 64, 55, 42, 34, 26, 17, 10, 9, -3, -2, -5, -13,
+ -15, -20, -23, -27, -27, -32, -37, -38, -41, -40, -41, -39, -43, -43, -40, -48,
+ -47, -49, -55, -61, -59, -70, -80, -69, -87, -83, -79, -97, -89, -98, -101, -107,
+ -96, -93, -101, -77, -90, -84, -62, -63, -49, -36, -34, -30, -15, -12, -2, 11,
+ 20, 32, 39, 53, 56, 71, 87, 89, 103, 101, 109, 109, 109, 118, 106, 114,
+ 111, 101, 107, 102, 93, 99, 94, 84, 85, 71, 65, 62, 54, 45, 32, 30,
+ 16, 12, 8, -5, -2, -9, -14, -16, -24, -22, -27, -29, -31, -38, -41, -38,
+ -44, -42, -41, -47, -45, -44, -48, -50, -50, -52, -62, -57, -69, -79, -69, -83,
+ -88, -78, -99, -97, -92, -109, -106, -91, -100, -93, -76, -91, -80, -60, -66, -48,
+ -37, -38, -32, -18, -15, -4, 11, 14, 31, 42, 48, 60, 69, 85, 94, 96,
+ 102, 107, 103, 109, 115, 104, 112, 109, 100, 106, 103, 95, 97, 96, 84, 82,
+ 73, 60, 62, 54, 41, 33, 27, 17, 14, 7, 0, 0, -8, -11, -16, -23,
+ -23, -29, -29, -32, -39, -40, -40, -40, -41, -40, -46, -48, -45, -50, -51, -54,
+ -56, -64, -63, -71, -78, -73, -84, -82, -87, -95, -93, -102, -102, -108, -95, -96,
+ -95, -76, -90, -77, -57, -61, -42, -33, -35, -26, -13, -14, 3, 15, 17, 36,
+ 45, 54, 60, 80, 89, 96, 108, 101, 111, 110, 109, 118, 107, 110, 109, 102,
+ 103, 103, 95, 97, 96, 83, 82, 70, 60, 61, 51, 38, 28, 23, 11, 8,
+ 4, -7, -3, -10, -16, -17, -22, -25, -27, -29, -35, -38, -43, -42, -41, -40,
+ -39, -43, -42, -44, -45, -46, -53, -51, -55, -68, -65, -75, -79, -77, -88, -83,
+ -94, -93, -101, -105, -96, -96, -92, -85, -85, -83, -71, -64, -57, -41, -41, -31,
+ -27, -17, -7, 2, 18, 23, 38, 48, 51, 68, 78, 91, 98, 102, 106, 108,
+ 110, 112, 115, 110, 115, 107, 107, 108, 99, 102, 97, 94, 87, 76, 70, 63,
+ 60, 49, 39, 30, 22, 16, 8, 4, 0, -4, -10, -14, -20, -24, -25, -31,
+ -30, -37, -41, -40, -41, -38, -39, -40, -42, -41, -43, -48, -44, -55, -58, -57,
+ -71, -71, -73, -78, -79, -80, -88, -89, -95, -99, -103, -101, -88, -98, -85, -79,
+ -90, -62, -60, -54, -35, -35, -27, -21, -9, -3, 7, 22, 26, 38, 52, 54,
+ 67, 87, 89, 101, 105, 103, 114, 107, 117, 112, 107, 116, 100, 105, 103, 94,
+ 98, 93, 87, 80, 73, 65, 59, 56, 45, 31, 28, 19, 6, 10, -3, -5,
+ -4, -17, -16, -22, -24, -25, -30, -28, -39, -37, -40, -44, -40, -44, -46, -46,
+ -47, -51, -50, -55, -55, -60, -67, -65, -81, -75, -78, -93, -78, -97, -101, -94,
+ -113, -104, -92, -96, -91, -79, -86, -79, -58, -58, -49, -34, -34, -33, -14, -12,
+ -5, 20, 19, 34, 49, 49, 66, 76, 91, 98, 98, 105, 104, 107, 111, 110,
+ 109, 108, 108, 103, 101, 102, 97, 95, 96, 80, 75, 71, 56, 58, 49, 33,
+ 28, 20, 13, 7, 4, -4, -7, -9, -18, -22, -22, -28, -30, -30, -38, -41,
+ -41, -43, -40, -41, -40, -44, -43, -45, -48, -49, -55, -55, -59, -67, -66, -82,
+ -70, -81, -86, -78, -101, -92, -98, -111, -98, -95, -95, -89, -76, -91, -70, -56,
+ -61, -38, -34, -33, -25, -12, -10, 1, 21, 15, 39, 47, 48, 68, 75, 90,
+ 97, 101, 103, 106, 106, 110, 111, 104, 111, 101, 99, 103, 96, 94, 95, 92,
+ 75, 79, 64, 55, 64, 43, 36, 30, 17, 13, 9, 3, -4, -3, -12, -16,
+ -18, -23, -25, -26, -29, -35, -38, -42, -40, -39, -41, -38, -48, -42, -45, -50,
+ -49, -52, -57, -63, -57, -78, -76, -67, -94, -75, -88, -100, -92, -103, -106, -97,
+ -88, -96, -81, -77, -85, -60, -55, -51, -35, -30, -33, -19, -9, -10, 17, 16,
+ 30, 46, 48, 64, 72, 86, 96, 101, 104, 105, 111, 104, 116, 109, 107, 110,
+ 104, 101, 104, 100, 93, 100, 86, 77, 78, 59, 60, 54, 40, 32, 23, 18,
+ 9, 9, 0, -5, -6, -14, -17, -20, -23, -25, -26, -31, -35, -39, -40, -36,
+ -40, -37, -40, -45, -42, -45, -48, -51, -50, -57, -64, -62, -76, -78, -71, -90,
+ -84, -88, -101, -97, -105, -108, -94, -97, -92, -81, -87, -76, -63, -58, -42, -36,
+ -33, -27, -15, -10, -2, 18, 19, 34, 49, 47, 66, 78, 86, 102, 104, 104,
+ 111, 109, 112, 115, 112, 110, 108, 106, 101, 102, 98, 96, 97, 86, 79, 72,
+ 62, 61, 51, 39, 32, 20, 15, 10, 2, 1, -4, -9, -13, -18, -22, -24,
+ -25, -29, -33, -37, -41, -39, -37, -39, -39, -43, -46, -46, -49, -49, -56, -54,
+ -57, -68, -66, -73, -77, -79, -83, -90, -96, -95, -107, -110, -98, -97, -98, -76,
+ -87, -83, -56, -68, -49, -34, -43, -28, -26, -18, -8, 3, 14, 22, 39, 47,
+ 54, 70, 83, 90, 101, 100, 104, 107, 102, 113, 103, 106, 109, 95, 106, 99,
+ 95, 101, 92, 93, 83, 74, 66, 60, 56, 44, 33, 26, 17, 12, 8, 1,
+ 2, -4, -11, -10, -21, -19, -25, -29, -28, -39, -38, -41, -41, -37, -40, -42,
+ -43, -42, -45, -47, -48, -56, -52, -59, -69, -67, -78, -78, -79, -88, -86, -95,
+ -100, -99, -112, -95, -92, -101, -77, -86, -86, -62, -65, -51, -39, -35, -31, -26,
+ -8, -11, 7, 26, 21, 45, 53, 50, 76, 86, 90, 105, 102, 105, 109, 108,
+ 115, 107, 112, 110, 100, 108, 100, 96, 100, 93, 89, 79, 72, 64, 58, 56,
+ 42, 31, 28, 14, 10, 9, -5, -2, -6, -14, -15, -22, -22, -27, -28, -31,
+ -41, -37, -41, -42, -37, -41, -45, -43, -45, -47, -48, -49, -58, -53, -64, -71,
+ -68, -82, -75, -83, -91, -87, -103, -97, -104, -111, -90, -98, -95, -77, -91, -76,
+ -61, -63, -43, -41, -35, -29, -23, -7, -7, 13, 22, 24, 50, 50, 59, 82,
+ 82, 99, 102, 100, 110, 105, 111, 113, 104, 114, 103, 104, 107, 96, 102, 97,
+ 92, 90, 77, 73, 64, 58, 53, 38, 31, 23, 13, 12, 3, 0, -2, -11,
+ -10, -17, -21, -20, -29, -27, -33, -40, -38, -44, -39, -39, -43, -41, -42, -42,
+ -46, -42, -53, -53, -52, -71, -67, -73, -83, -80, -81, -89, -93, -91, -100, -106,
+ -97, -96, -93, -88, -81, -85, -79, -59, -58, -48, -30, -36, -28, -11, -9, -2,
+ 21, 22, 32, 50, 52, 58, 79, 89, 90, 104, 104, 100, 113, 111, 109, 114,
+ 109, 107, 103, 104, 99, 94, 97, 91, 78, 79, 65, 58, 61, 47, 37, 30,
+ 23, 14, 10, 7, -7, -4, -8, -21, -17, -23, -30, -26, -30, -36, -37, -39,
+ -38, -38, -36, -38, -45, -41, -45, -49, -51, -56, -57, -63, -64, -69, -78, -70,
+ -80, -84, -84, -91, -100, -98, -106, -108, -90, -103, -90, -80, -93, -65, -64, -52,
+ -38, -37, -27, -26, -12, -6, 3, 18, 22, 36, 48, 54, 69, 84, 89, 105,
+ 103, 106, 117, 105, 117, 113, 106, 113, 101, 105, 101, 99, 98, 93, 94, 83,
+ 75, 70, 60, 55, 49, 33, 27, 19, 10, 8, -2, -2, -7, -13, -12, -22,
+ -20, -23, -28, -28, -35, -39, -40, -41, -40, -42, -40, -43, -42, -42, -44, -46,
+ -49, -52, -59, -60, -70, -74, -71, -84, -82, -88, -96, -98, -100, -105, -102, -88,
+ -95, -83, -79, -87, -62, -62, -52, -40, -39, -31, -27, -14, -10, 7, 17, 25,
+ 42, 49, 59, 72, 85, 92, 103, 103, 102, 111, 104, 113, 110, 104, 112, 102,
+ 107, 103, 101, 99, 97, 92, 81, 76, 64, 61, 54, 42, 33, 24, 17, 11,
+ 8, -2, -2, -5, -13, -12, -22, -23, -26, -31, -32, -38, -40, -43, -39, -40,
+ -41, -40, -44, -41, -44, -47, -51, -49, -62, -55, -68, -78, -68, -89, -79, -81,
+ -96, -85, -101, -100, -103, -98, -91, -97, -79, -83, -87, -61, -64, -55, -31, -41,
+ -29, -15, -19, 3, 9, 18, 33, 36, 56, 54, 71, 87, 87, 103, 103, 103,
+ 110, 107, 113, 112, 108, 111, 101, 104, 103, 92, 101, 92, 84, 84, 66, 65,
+ 59, 51, 45, 31, 27, 16, 10, 6, -3, -3, -9, -15, -16, -22, -24, -25,
+ -30, -28, -36, -40, -36, -42, -38, -41, -45, -44, -47, -47, -49, -51, -52, -54,
+ -62, -68, -73, -78, -81, -84, -83, -97, -94, -101, -113, -100, -99, -96, -87, -83,
+ -85, -75, -60, -60, -43, -36, -38, -27, -20, -15, 0, 14, 19, 33, 47, 49,
+ 67, 78, 90, 100, 103, 105, 107, 108, 110, 112, 109, 109, 107, 102, 105, 100,
+ 99, 98, 95, 84, 80, 69, 59, 60, 48, 36, 31, 18, 14, 9, 3, -2,
+ -5, -10, -15, -19, -24, -25, -28, -31, -34, -39, -41, -40, -38, -40, -38, -43,
+ -43, -42, -48, -47, -53, -54, -58, -67, -63, -79, -73, -78, -90, -80, -98, -97,
+ -101, -109, -105, -93, -98, -90, -76, -93, -66, -60, -59, -33, -42, -32, -26, -18,
+ -9, 0, 17, 21, 38, 48, 53, 69, 82, 93, 101, 107, 102, 112, 108, 111,
+ 115, 105, 112, 103, 105, 104, 96, 103, 95, 95, 85, 76, 68, 63, 59, 47,
+ 38, 26, 19, 13, 7, 1, -3, -4, -14, -12, -19, -23, -21, -29, -29, -35,
+ -40, -41, -42, -39, -43, -42, -46, -43, -47, -45, -48, -54, -47, -66, -61, -68,
+ -85, -66, -90, -84, -84, -103, -91, -106, -105, -96, -90, -92, -81, -79, -86, -59,
+ -59, -53, -34, -36, -33, -19, -10, -10, 17, 20, 26, 52, 48, 60, 75, 85,
+ 95, 102, 104, 102, 111, 107, 113, 110, 109, 111, 103, 107, 102, 97, 96, 95,
+ 85, 77, 73, 56, 60, 52, 37, 33, 22, 16, 11, 7, -3, -4, -6, -16,
+ -14, -21, -24, -24, -28, -32, -37, -38, -42, -36, -37, -39, -39, -43, -40, -42,
+ -48, -50, -50, -64, -57, -70, -84, -63, -90, -81, -77, -101, -85, -99, -105, -102,
+ -100, -92, -99, -79, -89, -86, -58, -65, -49, -29, -41, -26, -11, -19, 6, 12,
+ 14, 39, 37, 52, 60, 68, 90, 90, 104, 102, 106, 111, 108, 118, 109, 109,
+ 111, 98, 106, 101, 90, 101, 90, 82, 86, 63, 65, 63, 48, 47, 29, 25,
+ 16, 10, 6, -6, -3, -13, -18, -16, -26, -25, -25, -32, -30, -39, -43, -37,
+ -43, -39, -39, -48, -44, -46, -53, -50, -56, -59, -59, -67, -72, -77, -76, -84,
+ -83, -84, -100, -95, -103, -115, -98, -93, -103, -82, -82, -91, -60, -62, -54, -34,
+ -35, -31, -23, -13, -11, 7, 19, 21, 43, 48, 55, 73, 85, 94, 104, 102,
+ 109, 110, 105, 118, 107, 109, 113, 98, 106, 103, 96, 99, 98, 90, 82, 79,
+ 62, 62, 58, 41, 34, 26, 14, 10, 8, -3, -2, -5, -14, -13, -20, -20,
+ -24, -26, -28, -38, -39, -42, -42, -41, -41, -42, -48, -41, -43, -50, -41, -49,
+ -59, -50, -68, -74, -67, -82, -80, -89, -87, -101, -101, -93, -121, -85, -90, -105,
+ -65, -93, -82, -55, -69, -49, -38, -46, -32, -27, -19, -5, 3, 19, 26, 41,
+ 53, 52, 81, 81, 95, 104, 90, 113, 101, 105, 118, 99, 113, 109, 100, 109,
+ 104, 98, 104, 96, 89, 83, 71, 66, 57, 56, 38, 28, 29, 8, 17, 6,
+ -2, 3, -24, -13, -79, -103, -120, -116, -104, -87, -76, -63, 63, 82, 97, 108,
+ 119, 99, 70, 69, 80, 91, 92, 98, 115, 124, 127, 113, 82, 42, 4, -44,
+ -70, -82, -100, -87, -62, -58, -71, -65, -79, -60, -102, -113, -62, -44, -31, -31,
+ -22, -18, -3, 4, 11, 20, 28, 11, 15, 18, 27, 18, 7, 13, 26, 11,
+ -19, -69, -108, -84, -51, -21, -3, -6, -18, -17, -31, -33, -18, 2, 4, 26,
+ 47, 48, 77, 117, 127, 127, 127, 121, 110, 86, 72, 62, 46, 11, 17, -2,
+ -7, -13, -44, -60, -61, -61, -63, -72, -79, -99, -116, -127, -128, -128, -124, -81,
+ -51, -4, 5, -6, 7, 8, 9, 31, 31, 16, 34, 28, 34, 34, 46, 78,
+ 84, 93, 69, 47, 40, 64, 44, 27, 22, 0, -29, -8, 15, -6, -36, -66,
+ -68, -42, 0, 6, 1, 13, 24, 41, 64, 58, 50, 40, 4, 0, 3, -24,
+ -3, 21, 28, 26, 9, -30, -42, -61, -85, -92, -91, -96, -87, -74, -31, -20,
+ -38, -14, -44, -17, 18, -25, -9, 7, 1, 11, -2, -19, 12, 47, 76, 72,
+ 58, 68, 69, 82, 86, 76, 58, 9, -23, -12, -7, -22, -2, 0, -9, -2,
+ -15, -10, -3, -22, -17, -38, -44, -33, -24, -27, -16, 0, -15, 20, 19, 18,
+ 1, 10, 41, -1, -25, -25, -11, 30, 37, 9, 45, 37, -30, -30, 21, 5,
+ -26, -43, -56, -42, -48, -48, -29, -62, -76, -42, -23, -12, -14, 8, 45, 36,
+ 40, 25, 14, 11, 40, 46, 55, 65, 30, 17, 30, 36, 33, 18, 13, 16,
+ 15, 46, 37, 2, -1, -26, -36, -19, -21, -36, -62, -51, -48, -20, -2, 3,
+ -12, -12, -10, -35, -37, -49, -22, 14, 61, 40, 60, 75, 33, 41, 48, 38,
+ 29, -32, -45, -56, -64, -61, -30, -20, 30, 10, -46, -37, -35, -30, -24, -12,
+ -23, -34, -29, -22, -20, -14, 4, 44, 77, 49, 10, 8, 24, 20, 28, 31,
+ 27, 40, 35, 69, 39, 54, 38, 26, 22, 43, 36, 7, 14, 2, -25, -50,
+ -51, -56, -42, -55, -46, -36, -44, -36, -35, 1, 23, 11, -3, -34, -66, -33,
+ -12, -31, -27, -13, -1, 21, 31, 23, 0, -11, -3, -2, 9, 27, 5, -8,
+ -2, -17, -13, 10, 9, 3, 35, 32, 43, 24, 15, 2, -15, -9, -5, 2,
+ 5, 27, 25, 42, 76, 61, 17, 25, 14, -5, -17, -24, -6, 11, 23, 7,
+ -8, 5, -11, -23, -27, -48, -30, -12, -26, -36, -37, -39, -46, -61, -55, -23,
+ -20, -22, -14, -10, -16, -16, -22, -11, -3, -14, -34, -16, 9, 28, 25, 50,
+ 63, 52, 56, 46, 50, 54, 56, 45, 54, 29, 20, 21, 0, 0, 6, 16,
+ 28, 14, -1, -9, -10, -4, -9, -13, -7, -21, -27, -29, -40, -41, -35, -42,
+ -64, -11, 9, 2, -12, -24, -37, -40, -34, -29, -34, -12, -26, -20, -6, -4,
+ 5, 5, 27, 1, -17, 2, 21, 12, 8, 9, 15, 23, 24, 1, 5, 22,
+ 25, 28, 57, 55, 41, 33, 36, 27, 5, 1, 15, 34, 23, 4, 20, 18,
+ -1, -21, -22, -15, -17, -8, -6, -6, -12, -15, -26, 1, 29, -8, -40, -52,
+ -55, -19, -21, -36, -48, -56, -29, -15, -29, -39, -46, -35, -14, -11, -16, 1,
+ 27, 22, -10, -14, -7, -12, -12, 23, 55, 48, 65, 42, 20, 46, 45, 49,
+ 42, 38, 34, 25, 33, 21, 10, 38, 40, 26, 22, 37, 33, 12, 4, 7,
+ -14, -49, -41, -36, -53, -40, -35, -44, -31, -22, -19, -50, -78, -80, -78, -48,
+ -31, -18, -27, -28, -7, -17, -11, 5, 32, 39, 19, 14, 22, 34, 37, 23,
+ 20, 40, 40, 27, 14, 11, 7, 29, 34, 19, 32, 7, -15, -12, -24, -12,
+ 8, 6, 21, 34, 29, -6, -22, -15, 1, -1, 24, 27, 20, 36, 42, 45,
+ 27, -14, -50, -34, -14, -26, -25, -10, 10, -4, -28, -30, -34, -69, -91, -85,
+ -74, -51, -38, -24, -19, -9, -7, -30, -35, -30, -36, -12, 25, 32, 44, 50,
+ 45, 51, 68, 94, 90, 74, 60, 52, 64, 48, 30, 11, 11, 11, 2, 14,
+ 24, 16, 13, -7, -17, -9, -12, -20, -32, -45, -54, -58, -35, -23, -46, -51,
+ -33, -28, -29, -24, -36, -30, -24, -22, -20, -13, -9, -14, -7, 10, 26, 22,
+ 9, 9, 10, -2, -9, -15, -11, -1, 19, 27, 33, 28, 5, 3, 5, 6,
+ 10, 14, 24, 32, 36, 40, 41, 37, 19, 11, 3, -7, -10, -7, 6, 27,
+ 38, 28, 23, 16, 18, 15, -7, -33, -20, -13, -24, -25, -19, -15, -26, -52,
+ -56, -48, -41, -36, -30, -32, -30, -15, -38, -49, -47, -32, -17, -17, -11, -3,
+ 3, 8, 24, 28, 16, 6, 1, 7, 28, 41, 42, 69, 87, 78, 73, 62,
+ 30, 14, 9, 7, 15, 32, 20, 10, -8, -20, 2, 9, -2, 5, 12, -4,
+ -12, -19, -32, -37, -29, -24, -28, -39, -43, -40, -44, -28, -25, -33, -39, -37,
+ -34, -29, -28, -25, -19, -1, -5, -22, -12, 2, 6, 38, 46, 25, 30, 41,
+ 47, 37, 21, 7, -7, -8, 11, 39, 48, 43, 35, 27, 25, 22, -1, -22,
+ -11, 13, -4, -13, -3, -8, -7, -11, -17, -5, 5, 9, 8, 15, 25, 16,
+ 22, 20, 5, -16, -27, -29, -30, -9, 9, 9, 3, -14, -50, -56, -56, -79,
+ -92, -80, -57, -24, 12, 10, 11, 4, -22, -21, -13, -2, 4, 10, 15, 8,
+ 35, 72, 53, 44, 25, 25, 48, 56, 69, 53, 50, 75, 85, 71, 33, 12,
+ -16, -32, -25, -14, -5, -16, -23, -19, -22, -39, -41, -47, -45, -33, -35, -39,
+ -38, -35, -34, -29, -28, -28, -23, -10, -7, -9, -11, -18, -5, 13, 1, -13,
+ -8, -5, 6, 27, 46, 43, 25, 8, 11, 16, 18, 23, 30, 12, 5, 10,
+ 7, 5, -6, -4, -5, 1, 10, 9, 15, 21, 17, 10, -8, -16, 10, 33,
+ 34, 23, 13, 17, 17, 9, 11, 7, -4, -8, -8, -22, -27, -26, -19, -7,
+ -18, -16, -16, -47, -62, -55, -36, -16, -25, -33, -30, -34, -42, -49, -41, -43,
+ -31, -20, -3, 28, 48, 66, 64, 36, 20, 26, 21, 22, 39, 51, 45, 39,
+ 40, 53, 56, 39, 24, 16, 12, 16, 24, 27, 16, 13, 7, -18, -33, -50,
+ -47, -33, -24, -20, -26, -32, -31, -46, -53, -58, -56, -29, -13, -11, -2, 8,
+ -11, -24, -11, -9, -6, -2, -6, 1, 4, 5, 11, 6, 7, 16, 30, 28,
+ 19, 15, 7, 4, 11, 27, 22, 6, 9, 11, 3, 4, 17, 27, 18, 11,
+ 12, 5, 2, -2, -6, -7, -2, 10, 12, 9, 1, -2, 3, 4, 11, 21,
+ 30, 28, 6, -9, -18, -22, -22, -38, -41, -27, -18, -18, -27, -27, -23, -32,
+ -35, -32, -34, -30, -25, -24, -18, -9, -5, 5, -5, -26, -19, -11, -4, 11,
+ 37, 48, 46, 50, 53, 50, 45, 45, 37, 18, 24, 44, 38, 43, 47, 29,
+ 15, 11, 10, 12, 4, -8, -6, -4, -17, -27, -28, -36, -34, -37, -53, -53,
+ -46, -38, -38, -37, -28, -24, -23, -37, -42, -30, 0, 20, 18, 12, 14, 9,
+ 2, 6, 15, 13, 10, 14, 12, 2, 12, 29, 21, 1, 7, 21, 19, 14,
+ 15, 15, 4, -1, 5, -1, -4, 0, -2, 3, 6, 6, 13, 21, 15, 7,
+ 3, 5, 2, -3, 3, 3, 5, 8, 10, 16, 14, -1, -7, 2, 11, 12,
+ -10, -35, -42, -26, -21, -37, -44, -44, -47, -42, -27, -27, -23, -15, -16, -20,
+ -21, -14, -12, -9, -7, -6, 0, 13, 30, 32, 37, 38, 31, 24, 25, 43,
+ 54, 49, 46, 44, 40, 41, 30, 9, -1, 6, 22, 31, 22, 9, 0, -14,
+ -23, -29, -29, -28, -35, -39, -39, -39, -33, -25, -30, -44, -49, -45, -45, -35,
+ -19, 2, 16, 16, 9, 0, 0, 6, 2, -1, 11, 27, 40, 32, 16, -2,
+ -2, 1, 3, 1, 7, 12, 6, 8, 11, 5, -1, -2, -1, 1, 8, 10,
+ 5, 4, 14, 17, 6, -1, 0, 4, 4, 17, 23, 19, 25, 20, 5, -8,
+ -9, -2, -1, -6, -3, 13, 16, 1, -13, -19, -21, -26, -34, -37, -23, -13,
+ -13, -24, -40, -42, -40, -39, -29, -22, -21, -18, -12, -2, 18, 24, 10, 0,
+ -6, -4, 15, 33, 34, 34, 44, 41, 31, 33, 44, 43, 31, 22, 20, 17,
+ 16, 23, 22, 19, 21, 10, -5, -6, -9, -8, -2, -5, -16, -28, -36, -47,
+ -53, -39, -23, -21, -24, -32, -43, -39, -34, -24, -18, -14, -11, -12, -6, 10,
+ 29, 41, 40, 27, 14, 10, 4, 1, 3, 2, 9, 19, 21, 9, -10, -16,
+ -10, 8, 18, 20, 13, -3, -8, -4, -1, 2, 5, 5, -1, 3, 9, 12,
+ 16, 16, 14, 9, 3, 5, 10, 4, -6, 1, 6, 5, 13, 20, 11, 1,
+ -7, -21, -30, -25, -12, -9, -13, -19, -24, -29, -34, -30, -32, -39, -33, -24,
+ -20, -22, -24, -13, 3, 6, 2, 1, 3, 5, 16, 30, 35, 35, 24, 16,
+ 15, 19, 31, 37, 33, 28, 29, 29, 30, 26, 20, 15, 13, 10, 10, 12,
+ 9, 7, -3, -21, -39, -44, -43, -42, -34, -26, -23, -18, -12, -18, -32, -36,
+ -31, -27, -20, -10, -7, -9, -11, -5, 2, 12, 19, 19, 25, 24, 11, 3,
+ 15, 29, 30, 20, 9, 1, -1, 1, 5, 2, -3, -2, 0, -6, -18, -27,
+ -20, -3, 8, 13, 15, 11, 7, 10, 18, 16, 10, 6, 3, -1, 1, 11,
+ 19, 19, 15, 14, 5, -2, -2, -7, -12, -15, -20, -16, -10, -5, 2, 1,
+ -13, -29, -33, -24, -10, -6, -13, -18, -23, -31, -32, -26, -22, -18, -13, -3,
+ 2, 3, 7, 8, 10, 19, 27, 32, 33, 33, 35, 38, 43, 41, 29, 9,
+ -4, -9, 2, 16, 17, 13, 15, 17, 13, 10, 5, -1, -8, -18, -29, -32,
+ -27, -21, -22, -30, -31, -31, -33, -31, -27, -18, -7, -6, -15, -16, -8, -1,
+ 4, 12, 18, 22, 20, 16, 11, 10, 14, 18, 16, 15, 14, 9, 6, 4,
+ 3, 3, 0, -5, -13, -18, -15, -13, -9, -7, -8, -5, -2, -5, -1, 5,
+ 8, 10, 11, 12, 17, 19, 16, 10, 4, 4, 8, 8, 8, 13, 14, 9,
+ 3, 0, -1, 0, 0, -7, -19, -24, -20, -15, -12, -15, -21, -23, -24, -26,
+ -28, -29, -28, -21, -10, -1, 5, 6, -3, -12, -14, -11, -1, 12, 16, 17,
+ 28, 36, 28, 20, 25, 27, 24, 25, 28, 21, 15, 11, 3, 4, 12, 11,
+ 0, -7, -5, -1, -1, -5, -8, -11, -17, -23, -22, -19, -21, -20, -20, -22,
+ -24, -22, -17, -20, -24, -20, -10, 2, 10, 13, 14, 14, 11, 8, 8, 12,
+ 17, 18, 20, 20, 14, 4, -1, -2, -1, 3, 11, 12, 6, 0, -9, -20,
+ -25, -18, -9, -8, -13, -18, -19, -14, -6, 0, 4, 11, 19, 22, 20, 19,
+ 15, 13, 14, 18, 17, 12, 7, 9, 14, 9, -1, -4, -1, -5, -10, -12,
+ -16, -23, -19, -7, -5, -10, -10, -11, -19, -27, -24, -14, -6, -3, -10, -21,
+ -24, -15, -6, 0, 9, 15, 12, 8, 6, 9, 9, 11, 20, 26, 31, 35,
+ 30, 21, 16, 16, 13, 6, 2, 4, 5, 3, -2, -10, -13, -11, -8, -9,
+ -13, -16, -18, -18, -19, -22, -18, -8, -3, -1, 0, -5, -11, -10, -9, -11,
+ -9, -2, 2, 4, 10, 15, 18, 19, 21, 21, 22, 22, 15, 4, -4, -8,
+ -7, -6, -10, -14, -18, -23, -20, -15, -8, -1, 0, -4, -7, -9, -9, -6,
+ -2, 2, 6, 7, 4, 1, 0, 7, 13, 11, 14, 22, 22, 15, 8, 2,
+ 4, 10, 16, 17, 13, 10, 9, 6, -3, -13, -23, -26, -21, -17, -14, -12,
+ -13, -16, -14, -9, -8, -8, -11, -18, -18, -12, -4, 0, 2, 6, 6, -1,
+ -6, 0, 8, 11, 13, 11, 6, 6, 9, 13, 16, 16, 15, 10, 7, 10,
+ 10, 4, 0, -2, -3, -1, 2, 2, -1, -5, -13, -21, -27, -30, -26, -16,
+ -4, 5, 8, 6, 2, -3, -5, -1, 4, 8, 9, 11, 11, 6, 0, 0,
+ 7, 12, 13, 11, 7, 1, -4, -3, 0, 5, 6, 5, -2, -10, -13, -13,
+ -10, -5, -4, -9, -18, -28, -31, -24, -14, -10, -4, 2, 5, 4, 2, 4,
+ 13, 20, 21, 19, 14, 11, 11, 12, 13, 14, 15, 17, 18, 18, 14, 5,
+ -3, -5, -8, -11, -11, -12, -15, -15, -13, -13, -15, -13, -12, -15, -16, -11,
+ -7, -6, -4, -1, 4, 6, -1, -10, -11, -7, -4, -1, 4, 9, 11, 12,
+ 9, 7, 8, 8, 7, 9, 13, 15, 12, 4, 1, 1, -2, -9, -10, -7,
+ -1, 3, 3, -1, -9, -12, -9, -5, 1, 3, -2, -10, -10, -7, -4, 2,
+ 8, 6, 4, 6, 5, -1, -1, 7, 17, 20, 17, 16, 19, 16, 7, -3,
+ -8, -9, -9, -11, -15, -24, -27, -20, -15, -12, -11, -7, -3, -4, -6, -7,
+ -6, -8, -14, -18, -18, -15, -10, -5, 3, 12, 18, 20, 17, 11, 10, 16,
+ 21, 22, 23, 23, 22, 17, 9, 0, -3, 2, 10, 15, 16, 11, 2, -9,
+ -19, -23, -22, -15, -10, -8, -11, -13, -15, -17, -19, -18, -15, -10, -3, 1,
+ -2, -6, -3, 0, -3, -3, 0, 6, 10, 9, 7, 4, -1, -4, 0, 10,
+ 17, 16, 11, 5, 0, -1, 2, 5, 1, -6, -10, -10, -8, -6, -4, -2,
+ -4, -7, -9, -9, -6, 2, 12, 17, 16, 11, 8, 7, 6, 5, 7, 9,
+ 12, 14, 14, 9, 3, -1, -3, -5, -4, 0, 4, -1, -10, -18, -24, -29,
+ -28, -20, -14, -13, -12, -8, -5, -5, -9, -13, -14, -11, -10, -9, -4, 1,
+ 3, 2, 3, 8, 16, 20, 18, 13, 10, 14, 24, 29, 29, 27, 23, 17,
+ 14, 16, 17, 15, 9, -1, -7, -10, -14, -18, -16, -11, -8, -7, -8, -12,
+ -18, -26, -29, -26, -19, -11, -5, -3, -3, -2, 0, 2, 0, -3, -3, -2,
+ -3, -4, -2, -1, 3, 7, 9, 8, 7, 3, 1, 4, 5, 2, 3, 5,
+ 5, 0, -7, -9, -6, -1, 5, 9, 8, 3, -2, -6, -5, 3, 9, 12,
+ 11, 8, 4, 3, 4, 6, 11, 13, 8, 1, 0, 4, 9, 13, 12, 5,
+ 2, 3, 3, 0, -6, -16, -26, -30, -28, -26, -22, -18, -17, -19, -22, -24,
+ -19, -12, -7, -2, 1, 0, -2, -4, -5, -2, 4, 10, 14, 15, 15, 16,
+ 16, 17, 19, 22, 26, 25, 19, 13, 10, 7, 9, 11, 10, 7, 4, 1,
+ -5, -8, -8, -4, 0, 1, -4, -11, -16, -17, -16, -14, -12, -10, -11, -14,
+ -15, -16, -13, -9, -3, 1, 2, 1, 0, 0, -3, -9, -13, -10, -8, -7,
+ -4, 0, 3, 6, 9, 9, 5, 3, 3, 5, 8, 12, 12, 6, -1, -2,
+ 2, 8, 8, 4, -2, -5, -1, 4, 10, 13, 14, 13, 13, 14, 14, 12,
+ 10, 8, 8, 8, 6, 6, 9, 6, -1, -9, -15, -19, -22, -24, -23, -25,
+ -25, -23, -20, -19, -19, -21, -20, -20, -21, -19, -11, -2, 2, 1, 0, 3,
+ 9, 13, 15, 16, 14, 10, 5, 3, 8, 14, 16, 18, 20, 22, 24, 21,
+ 15, 9, 6, 8, 14, 18, 15, 9, 4, 1, 0, -2, -4, -4, -3, -3,
+ -4, -7, -11, -13, -12, -11, -15, -19, -22, -25, -25, -21, -14, -11, -15, -19,
+ -18, -14, -7, -1, 4, 2, -3, -6, -4, 0, 5, 10, 16, 17, 12, 7,
+ 2, -1, -3, 0, 3, 6, 10, 14, 12, 6, 2, 5, 10, 15, 18, 18,
+ 16, 14, 11, 6, 4, 3, 1, 1, 2, 6, 9, 9, 3, -2, -3, -4,
+ -6, -8, -10, -15, -19, -20, -19, -18, -17, -15, -16, -17, -18, -20, -22, -21,
+ -16, -11, -4, 1, 0, -4, -4, -1, 1, 2, 4, 4, 3, 3, 4, 7,
+ 11, 16, 21, 20, 15, 11, 9, 12, 16, 21, 24, 23, 21, 17, 13, 11,
+ 9, 4, 0, 0, 1, 3, 4, 0, -4, -7, -7, -9, -13, -17, -20, -22,
+ -23, -21, -16, -12, -12, -15, -17, -17, -15, -12, -10, -10, -11, -12, -15, -15,
+ -10, -4, 0, -1, -1, 1, 4, 7, 13, 19, 22, 23, 21, 19, 18, 17,
+ 11, 5, 2, 5, 10, 13, 15, 15, 14, 13, 10, 5, 1, 0, 2, 5,
+ 8, 10, 9, 6, 4, 2, -1, -5, -7, -8, -7, -8, -11, -13, -14, -16,
+ -19, -21, -22, -22, -24, -23, -20, -17, -16, -16, -15, -16, -16, -15, -13, -11,
+ -9, -5, 0, 6, 12, 15, 18, 18, 17, 17, 19, 20, 19, 19, 20, 23,
+ 25, 25, 23, 20, 17, 13, 11, 9, 9, 8, 6, 3, 1, -2, -5, -5,
+ -2, -1, -3, -7, -6, -3, 0, -2, -9, -21, -29, -32, -32, -30, -27, -27,
+ -29, -30, -28, -24, -23, -21, -16, -7, 0, 1, 2, 2, 4, 7, 10, 14,
+ 16, 14, 12, 13, 15, 18, 20, 22, 23, 20, 15, 8, 3, 2, 7, 13,
+ 15, 13, 7, 2, 0, 0, -1, -2, -1, 1, 2, 1, 0, 2, 3, 4,
+ 4, 6, 7, 5, 0, -10, -21, -30, -36, -36, -33, -28, -23, -18, -15, -14,
+ -17, -19, -19, -17, -12, -5, -2, -2, -3, -1, 2, 6, 10, 12, 14, 13,
+ 12, 13, 18, 25, 29, 28, 24, 19, 14, 10, 6, 6, 9, 12, 13, 15,
+ 17, 18, 18, 14, 7, 0, -1, 1, 1, -2, -6, -8, -10, -11, -13, -17,
+ -19, -18, -17, -16, -14, -14, -15, -17, -19, -22, -26, -26, -24, -20, -17, -14,
+ -13, -12, -10, -7, -4, 1, 5, 7, 9, 10, 13, 15, 17, 18, 21, 24,
+ 22, 21, 19, 17, 15, 13, 14, 14, 16, 17, 18, 16, 12, 10, 8, 6,
+ 5, 3, 0, -3, -6, -7, -5, -4, -4, -5, -5, -4, -4, -4, -8, -13,
+ -19, -24, -27, -28, -27, -25, -25, -27, -27, -25, -19, -14, -8, -3, 1, 6,
+ 9, 8, 3, -3, -6, -4, -1, 4, 9, 14, 18, 20, 22, 22, 23, 23,
+ 22, 21, 20, 20, 21, 21, 19, 15, 9, 3, -2, -4, -3, 0, 2, 2,
+ 2, 3, 3, 1, -4, -10, -15, -19, -19, -16, -11, -7, -7, -9, -13, -17,
+ -23, -28, -30, -29, -24, -20, -18, -19, -20, -19, -18, -19, -18, -13, -5, 1,
+ 6, 9, 11, 13, 16, 21, 26, 29, 30, 29, 29, 28, 26, 23, 20, 20,
+ 21, 21, 20, 18, 15, 9, 2, -4, -6, -5, -3, -3, -4, -6, -7, -9,
+ -10, -10, -10, -10, -11, -13, -12, -11, -8, -6, -6, -10, -17, -26, -32, -35,
+ -35, -34, -32, -27, -19, -9, -3, -1, -2, -5, -7, -6, -1, 7, 14, 18,
+ 21, 23, 25, 26, 26, 23, 20, 20, 23, 24, 24, 21, 19, 14, 8, 2,
+ -1, 0, 1, 2, 3, 6, 8, 8, 5, 2, -2, -5, -5, -4, -1, 1,
+ 1, -1, -6, -9, -11, -13, -17, -20, -24, -26, -27, -26, -23, -21, -20, -23,
+ -26, -27, -26, -24, -20, -15, -9, -2, 4, 8, 10, 13, 16, 19, 21, 23,
+ 25, 28, 33, 36, 38, 38, 35, 32, 29, 24, 16, 11, 6, 2, -2, -6,
+ -6, -5, -4, -4, -7, -11, -14, -13, -10, -8, -8, -8, -9, -11, -12, -12,
+ -11, -11, -12, -14, -17, -19, -19, -18, -18, -20, -22, -23, -21, -18, -14, -11,
+ -8, -4, -1, 5, 11, 13, 11, 8, 6, 7, 9, 11, 13, 15, 19, 22,
+ 23, 25, 27, 27, 22, 17, 11, 6, 4, 5, 9, 13, 15, 15, 11, 6,
+ 0, -4, -7, -8, -6, -3, -2, -3, -6, -9, -13, -18, -22, -23, -20, -15,
+ -11, -10, -11, -14, -19, -24, -27, -28, -28, -27, -26, -23, -19, -15, -10, -6,
+ -1, 4, 8, 10, 11, 11, 13, 15, 17, 20, 23, 24, 24, 26, 28, 28,
+ 28, 27, 26, 24, 22, 20, 16, 13, 10, 8, 6, 3, -3, -9, -15, -17,
+ -16, -15, -13, -13, -14, -17, -19, -20, -20, -17, -14, -12, -13, -14, -13, -13,
+ -14, -15, -14, -13, -12, -12, -12, -10, -8, -7, -8, -9, -9, -7, -4, 0,
+ 3, 6, 8, 10, 12, 14, 18, 22, 25, 26, 27, 28, 28, 27, 24, 20,
+ 16, 13, 11, 9, 6, 3, 0, -3, -3, -2, 1, 3, 5, 3, 0, -4,
+ -8, -12, -17, -21, -22, -20, -17, -15, -14, -14, -13, -15, -19, -22, -21, -18,
+ -14, -13, -15, -16, -17, -17, -19, -19, -16, -11, -4, 1, 6, 10, 13, 17,
+ 20, 23, 24, 24, 24, 25, 28, 33, 37, 38, 35, 30, 24, 20, 16, 13,
+ 9, 2, -4, -8, -8, -8, -7, -7, -9, -12, -16, -18, -18, -16, -15, -16,
+ -16, -16, -13, -10, -10, -11, -13, -15, -15, -15, -15, -16, -17, -16, -14, -13,
+ -13, -13, -13, -12, -9, -5, -2, 1, 3, 6, 12, 18, 22, 22, 21, 18,
+ 16, 16, 19, 23, 29, 32, 30, 24, 18, 13, 9, 6, 3, 0, -2, -4,
+ -6, -8, -10, -11, -10, -6, -3, -2, -3, -5, -5, -6, -6, -7, -6, -5,
+ -4, -5, -8, -10, -11, -12, -14, -16, -18, -20, -21, -21, -22, -23, -24, -24,
+ -22, -18, -11, -4, 1, 4, 5, 6, 8, 11, 15, 20, 24, 26, 27, 28,
+ 31, 32, 31, 30, 28, 27, 24, 20, 17, 14, 12, 9, 3, -3, -9, -12,
+ -15, -16, -17, -15, -13, -10, -10, -11, -13, -14, -15, -17, -19, -21, -23, -24,
+ -22, -18, -13, -9, -8, -8, -8, -9, -9, -9, -7, -4, 0, 2, 3, 5,
+ 5, 3, 3, 4, 5, 6, 7, 10, 14, 17, 20, 20, 20, 21, 22, 20,
+ 18, 16, 15, 14, 12, 9, 7, 6, 4, 2, -2, -5, -7, -9, -9, -8,
+ -5, -2, 0, 0, -1, -3, -7, -12, -16, -16, -15, -13, -12, -13, -13, -12,
+ -11, -11, -12, -15, -19, -23, -24, -22, -19, -16, -13, -10, -5, -1, 3, 6,
+ 7, 8, 8, 10, 13, 17, 21, 25, 27, 28, 28, 26, 24, 24, 25, 27,
+ 28, 29, 28, 25, 19, 12, 4, -3, -10, -15, -19, -22, -24, -25, -26, -25,
+ -23, -21, -20, -18, -17, -16, -14, -12, -11, -12, -14, -14, -13, -13, -15, -16,
+ -16, -16, -15, -11, -4, 0, -2, 0, 0, 3, 14, 34, 24, -3, -14, -12,
+ 6, 6, -11, -23, -5, 15, 20, 15, -19, -12, 3, 19, 11, -5, 1, 4,
+ 7, -13, -3, 5, -13, 0, -2, 8, 0, -6, 16, 23, 13, 6, 2, 14,
+ 25, 2, 11, 3, -7, -8, -24, -6, -4, -18, 6, 30, 14, 9, 0, 0,
+ 13, -7, 0, -3, 9, 8, -6, -14, -15, -23, -19, -7, 0, -3, 1, -8,
+ -10, -10, -17, -12, -7, -10, 1, -12, -13, 0, -15, -20, -25, -16, -6, -7,
+ -6, -6, -2, -4, -13, -12, -6, -6, -5, 2, 8, -5, -13, -3, -4, -11,
+ -16, -3, 12, -2, -8, -4, -4, 4, -15, -17, -6, -2, 5, -4, 3, -2,
+ -10, -4, -5, -7, -8, 4, 17, 1, -3, -14, -4, -2, -7, -4, -6, 10,
+ 5, -6, -7, -8, 10, -5, -3, 3, -8, 11, 7, -5, -3, -13, -7, 0,
+ -6, 4, 0, -7, 12, -9, -17, -7, 5, 2, -3, -4, -7, 7, -2, -13,
+ -5, -2, 5, 4, 0, 7, -3, 4, 1, -2, -4, 6, 8, 8, 0, -2,
+ 2, 3, 2, 1, -2, 5, 12, 6, 3, 2, -3, 2, 3, 1, 8, 6,
+ 7, 2, -5, -3, 1, 5, 2, 0, -3, 2, 7, 2, 0, -9, 0, 5,
+ 1, 3, 1, 4, 6, -5, -3, -2, 2, 6, 4, 6, 1, 2, 4, 4,
+ -2, 2, 5, 5, 7, 7, 2, 6, 0, 3, 0, -3, 8, 4, 4, 9,
+ -3, 2, 1, 1, 2, 1, 5, 5, 4, 6, 1, -6, -2, 3, 5, 6,
+ 4, 3, 4, 1, 2, -4, 0, 6, 2, 2, 4, 3, 5, -3, -2, -5,
+ -3, 5, 2, 1, 3, 1, -2, -3, -4, -6, 3, 5, 1, -2, 1, 2,
+ -2, -2, -2, -3, 3, 5, 3, 4, 2, 2, 1, 0, 1, 4, 9, 9,
+ 5, 2, 1, 6, 4, 4, 5, 5, 7, 8, 4, 5, 1, 2, 3, 1,
+ 1, 4, 2, 3, 0, -4, -7, -5, 0, -3, -3, -3, -5, 0, -8, -7,
+ -8, -5, -3, -6, -3, -4, -5, 0, -7, -4, -5, -3, 1, 1, -2, 1,
+ -2, 2, 0, 0, -2, 3, 5, 4, 5, 4, 2, 4, 2, 4, 5, 6,
+ 5, 6, 4, 4, 4, 4, 3, 4, 2, 4, 4, 2, -2, -2, 0, -3,
+ -3, -3, -4, -2, -7, -6, -7, -9, -7, -10, -9, -10, -10, -8, -11, -9,
+ -9, -12, -10, -13, -12, -7, -8, -6, -6, -9, -6, -5, -3, 0, 0, 1,
+ 1, 4, 3, 4, 8, 6, 8, 7, 6, 10, 9, 12, 12, 11, 12, 8,
+ 13, 10, 11, 10, 8, 9, 8, 6, 9, 4, 5, 0, -3, -5, -5, -6,
+ -7, -9, -12, -15, -17, -21, -18, -22, -21, -23, -25, -24, -27, -27, -26, -30,
+ -27, -27, -28, -20, -22, -19, -14, -15, -12, -10, -10, -2, 3, 4, 12, 12,
+ 14, 20, 17, 25, 27, 29, 33, 35, 35, 40, 38, 41, 39, 36, 38, 36,
+ 36, 38, 31, 33, 25, 21, 14, 8, 1, 2, 0, -3, -5, -15, -23, -28,
+ -40, -39, -43, -46, -43, -52, -53, -59, -66, -62, -69, -63, -64, -64, -50, -56,
+ -44, -45, -43, -38, -36, -31, -20, -8, 4, 12, 19, 18, 28, 31, 40, 52,
+ 57, 68, 73, 73, 77, 73, 81, 79, 82, 82, 77, 82, 77, 75, 69, 59,
+ 53, 42, 33, 24, 22, 17, 11, 1, -17, -25, -36, -42, -46, -55, -60, -64,
+ -73, -77, -88, -90, -92, -97, -98, -100, -100, -92, -85, -79, -80, -76, -79, -69,
+ -56, -50, -32, -24, -15, 0, -2, 11, 15, 29, 45, 55, 67, 72, 82, 88,
+ 95, 101, 102, 109, 109, 112, 109, 110, 110, 106, 104, 91, 81, 77, 68, 66,
+ 54, 42, 32, 14, 6, -6, -12, -20, -29, -43, -55, -65, -76, -76, -85, -89,
+ -97, -105, -107, -114, -115, -117, -117, -113, -112, -104, -101, -91, -85, -84, -70, -72,
+ -55, -42, -34, -14, -8, 5, 16, 22, 35, 44, 57, 69, 78, 89, 94, 101,
+ 104, 109, 109, 119, 118, 117, 120, 110, 114, 114, 99, 102, 84, 74, 72, 57,
+ 52, 43, 32, 22, 10, -7, -20, -28, -34, -47, -54, -60, -67, -71, -80, -87,
+ -90, -105, -105, -110, -120, -115, -120, -123, -113, -111, -109, -97, -98, -92, -83, -82,
+ -76, -63, -61, -48, -39, -30, -16, -3, 10, 22, 32, 42, 49, 61, 67, 76,
+ 84, 91, 101, 105, 115, 116, 117, 125, 115, 119, 116, 106, 111, 102, 97, 92,
+ 84, 79, 70, 64, 50, 45, 31, 19, 14, -2, -9, -19, -30, -35, -47, -54,
+ -62, -67, -73, -82, -86, -96, -100, -105, -109, -116, -118, -120, -120, -117, -111, -110,
+ -97, -96, -90, -84, -78, -73, -64, -55, -50, -39, -25, -20, 1, 11, 19, 37,
+ 40, 51, 61, 68, 76, 85, 94, 97, 105, 114, 112, 120, 122, 119, 121, 117,
+ 110, 106, 105, 92, 90, 84, 69, 71, 57, 48, 45, 29, 22, 14, -2, -9,
+ -22, -31, -40, -47, -59, -62, -68, -76, -80, -87, -97, -96, -111, -111, -116, -124,
+ -119, -123, -120, -109, -109, -98, -95, -93, -84, -81, -75, -66, -55, -51, -37, -28,
+ -16, 1, 12, 23, 39, 40, 55, 59, 68, 77, 86, 94, 103, 104, 116, 117,
+ 118, 125, 122, 117, 120, 107, 108, 104, 95, 92, 85, 72, 70, 60, 48, 43,
+ 29, 18, 10, -7, -12, -22, -30, -38, -49, -58, -63, -72, -75, -84, -90, -93,
+ -100, -110, -103, -121, -115, -115, -124, -110, -112, -111, -92, -98, -86, -81, -77, -69,
+ -61, -53, -48, -34, -27, -13, 1, 9, 28, 37, 45, 58, 59, 76, 78, 85,
+ 97, 98, 109, 114, 111, 123, 120, 119, 121, 116, 111, 110, 101, 93, 92, 79,
+ 73, 68, 55, 52, 40, 30, 21, 10, 0, -13, -23, -29, -41, -47, -58, -64,
+ -69, -75, -84, -89, -93, -103, -105, -110, -120, -115, -117, -128, -105, -114, -109, -88,
+ -102, -86, -76, -84, -64, -63, -56, -43, -37, -25, -10, 4, 11, 31, 36, 46,
+ 56, 58, 74, 78, 84, 100, 95, 110, 114, 110, 124, 120, 116, 121, 110, 105,
+ 108, 97, 96, 91, 79, 75, 66, 57, 51, 38, 29, 17, 5, -3, -13, -20,
+ -28, -40, -46, -55, -66, -68, -76, -85, -88, -97, -102, -106, -110, -117, -115, -120,
+ -122, -108, -117, -103, -98, -96, -86, -79, -77, -66, -59, -54, -46, -33, -31, -10,
+ -2, 11, 27, 36, 47, 58, 62, 74, 78, 86, 94, 96, 106, 109, 115, 120,
+ 118, 121, 119, 112, 114, 104, 98, 94, 85, 77, 72, 63, 56, 49, 37, 31,
+ 20, 6, -2, -15, -24, -33, -44, -50, -58, -63, -68, -76, -82, -89, -95, -105,
+ -105, -116, -118, -117, -126, -114, -111, -118, -92, -105, -92, -83, -88, -72, -71, -65,
+ -51, -50, -31, -25, -9, 2, 16, 29, 35, 50, 53, 67, 73, 75, 92, 88,
+ 104, 112, 108, 122, 117, 119, 123, 114, 116, 110, 104, 98, 94, 86, 80, 75,
+ 63, 59, 47, 36, 29, 13, 9, -5, -16, -21, -36, -40, -50, -61, -61, -73,
+ -77, -85, -93, -95, -103, -108, -117, -120, -118, -125, -117, -108, -116, -96, -98, -97,
+ -83, -82, -78, -66, -61, -54, -43, -32, -25, -2, 3, 16, 33, 36, 52, 56,
+ 66, 75, 78, 94, 91, 103, 113, 108, 122, 119, 119, 121, 116, 112, 110, 106,
+ 93, 96, 83, 76, 74, 59, 58, 47, 34, 28, 14, 6, -6, -17, -27, -36,
+ -44, -54, -61, -63, -70, -76, -86, -90, -99, -102, -108, -117, -115, -121, -123, -111,
+ -120, -102, -100, -101, -84, -91, -76, -74, -70, -54, -56, -41, -30, -20, -3, 8,
+ 23, 31, 46, 47, 59, 70, 71, 83, 89, 90, 108, 108, 115, 120, 121, 122,
+ 118, 118, 109, 110, 102, 93, 93, 82, 78, 72, 62, 57, 45, 37, 22, 15,
+ 4, -10, -18, -30, -36, -42, -54, -57, -63, -68, -77, -86, -91, -102, -103, -108,
+ -117, -114, -119, -117, -115, -110, -106, -100, -91, -99, -79, -81, -77, -59, -61, -50,
+ -36, -33, -16, -4, 10, 16, 35, 39, 48, 62, 64, 76, 85, 89, 98, 105,
+ 110, 113, 120, 119, 118, 123, 112, 111, 110, 100, 98, 93, 82, 78, 70, 58,
+ 54, 45, 30, 24, 12, 0, -7, -20, -28, -36, -45, -55, -61, -66, -73, -79,
+ -88, -93, -103, -105, -112, -119, -115, -124, -123, -109, -119, -103, -98, -102, -92, -84,
+ -83, -75, -62, -59, -50, -34, -34, -12, 1, 7, 26, 33, 42, 50, 62, 67,
+ 76, 88, 90, 101, 110, 108, 118, 121, 119, 122, 121, 111, 113, 110, 98, 98,
+ 91, 80, 78, 66, 58, 53, 40, 29, 20, 8, -4, -11, -22, -33, -37, -49,
+ -57, -61, -68, -77, -81, -90, -96, -101, -110, -112, -116, -120, -116, -121, -119, -104,
+ -111, -96, -91, -96, -79, -79, -76, -59, -57, -46, -33, -25, -14, 5, 11, 26,
+ 39, 42, 55, 61, 70, 81, 86, 94, 101, 105, 114, 116, 120, 121, 119, 119,
+ 115, 111, 107, 102, 94, 90, 82, 73, 68, 59, 50, 41, 28, 20, 7, -4,
+ -12, -22, -30, -41, -48, -56, -62, -69, -75, -83, -90, -98, -100, -107, -111, -119,
+ -112, -124, -120, -107, -119, -101, -93, -104, -80, -85, -83, -61, -65, -55, -40, -38,
+ -25, -7, -3, 13, 29, 34, 45, 57, 59, 74, 79, 87, 98, 98, 108, 111,
+ 112, 122, 117, 119, 119, 111, 110, 107, 96, 96, 89, 76, 74, 63, 54, 51,
+ 35, 27, 19, 5, -3, -12, -25, -29, -43, -52, -58, -64, -71, -78, -82, -92,
+ -98, -101, -108, -110, -114, -120, -119, -118, -115, -110, -106, -95, -97, -82, -84, -76,
+ -62, -63, -51, -42, -39, -20, -12, 2, 15, 29, 36, 47, 58, 62, 74, 80,
+ 85, 95, 101, 106, 111, 116, 118, 117, 122, 113, 115, 111, 99, 103, 90, 85,
+ 80, 68, 63, 56, 46, 36, 28, 17, 5, -5, -19, -25, -35, -43, -52, -58,
+ -62, -72, -75, -83, -94, -94, -105, -105, -115, -115, -116, -122, -114, -112, -108, -98,
+ -99, -89, -86, -82, -72, -69, -58, -52, -44, -31, -21, -6, 4, 17, 28, 39,
+ 48, 53, 66, 72, 80, 88, 92, 104, 108, 113, 116, 119, 121, 116, 119, 112,
+ 108, 107, 94, 94, 85, 79, 72, 62, 57, 48, 37, 25, 17, 8, -8, -15,
+ -26, -35, -42, -55, -59, -65, -73, -75, -87, -89, -97, -104, -109, -116, -116, -121,
+ -120, -120, -109, -108, -103, -90, -97, -78, -78, -77, -60, -64, -50, -41, -34, -16,
+ -7, 9, 19, 33, 42, 52, 60, 65, 77, 79, 87, 96, 99, 109, 113, 118,
+ 124, 117, 121, 117, 109, 110, 99, 94, 93, 83, 77, 73, 63, 55, 50, 32,
+ 26, 18, 0, -6, -20, -29, -34, -49, -53, -57, -63, -71, -76, -83, -91, -97,
+ -108, -112, -114, -122, -115, -124, -112, -105, -112, -89, -99, -90, -78, -89, -72, -66,
+ -61, -49, -41, -28, -16, 2, 6, 25, 35, 36, 53, 54, 67, 77, 79, 93,
+ 97, 105, 112, 111, 122, 118, 119, 117, 112, 109, 108, 99, 95, 92, 82, 76,
+ 71, 59, 56, 43, 30, 24, 10, 0, -9, -18, -26, -36, -45, -55, -59, -68,
+ -75, -81, -88, -94, -99, -106, -109, -110, -119, -117, -119, -116, -111, -105, -101, -91,
+ -92, -83, -75, -75, -61, -52, -52, -35, -29, -18, 0, 9, 22, 36, 41, 51,
+ 64, 68, 78, 88, 90, 101, 103, 109, 113, 115, 121, 117, 118, 116, 109, 109,
+ 102, 94, 90, 80, 71, 67, 57, 47, 42, 30, 19, 14, -4, -9, -19, -31,
+ -36, -50, -55, -61, -68, -74, -79, -87, -93, -101, -107, -107, -115, -118, -118, -123,
+ -112, -110, -109, -92, -93, -94, -74, -83, -71, -57, -61, -45, -34, -31, -10, 0,
+ 12, 27, 37, 42, 55, 61, 70, 77, 87, 95, 96, 106, 112, 113, 123, 122,
+ 117, 122, 112, 109, 110, 96, 96, 92, 76, 74, 68, 55, 50, 40, 28, 20,
+ 7, -6, -10, -23, -31, -42, -51, -59, -65, -70, -76, -82, -88, -92, -104, -104,
+ -105, -122, -113, -122, -126, -106, -119, -103, -91, -99, -82, -80, -76, -66, -59, -54,
+ -46, -34, -30, -9, 1, 13, 33, 34, 51, 57, 63, 76, 77, 91, 95, 95,
+ 110, 108, 115, 122, 120, 120, 123, 112, 110, 110, 94, 95, 87, 70, 74, 62,
+ 55, 50, 39, 29, 20, 7, -5, -13, -26, -35, -44, -56, -61, -65, -69, -75,
+ -83, -86, -98, -104, -104, -121, -115, -119, -128, -110, -117, -116, -92, -100, -90, -78,
+ -83, -75, -63, -64, -55, -41, -39, -20, -7, 1, 21, 31, 40, 51, 55, 67,
+ 72, 77, 91, 93, 99, 110, 109, 118, 125, 118, 124, 119, 108, 114, 101, 93,
+ 96, 81, 75, 73, 59, 57, 48, 35, 27, 15, 1, -7, -20, -29, -37, -49,
+ -56, -61, -65, -69, -74, -83, -91, -98, -107, -113, -117, -120, -122, -118, -115, -111,
+ -103, -101, -92, -89, -85, -80, -77, -65, -61, -51, -41, -33, -16, -4, 8, 21,
+ 34, 40, 49, 57, 63, 73, 82, 89, 98, 104, 109, 117, 118, 123, 122, 119,
+ 116, 110, 108, 100, 97, 93, 83, 80, 70, 64, 55, 45, 34, 22, 12, -2,
+ -10, -20, -30, -35, -48, -55, -62, -67, -71, -78, -86, -91, -101, -104, -110, -117,
+ -117, -120, -123, -111, -111, -110, -90, -99, -90, -76, -85, -71, -58, -63, -45, -37,
+ -33, -14, 1, 4, 27, 34, 41, 53, 59, 66, 79, 84, 92, 100, 103, 110,
+ 115, 116, 123, 118, 118, 117, 107, 110, 101, 95, 93, 79, 76, 68, 57, 52,
+ 43, 30, 23, 11, -3, -8, -20, -30, -34, -48, -55, -60, -69, -74, -81, -89,
+ -92, -101, -105, -108, -114, -117, -118, -122, -112, -113, -108, -95, -101, -87, -82, -83,
+ -68, -60, -56, -45, -38, -28, -17, -2, 6, 23, 33, 40, 54, 60, 68, 80,
+ 85, 94, 96, 103, 109, 110, 119, 118, 118, 121, 113, 112, 110, 100, 98, 90,
+ 77, 73, 66, 55, 51, 41, 29, 25, 8, 1, -9, -23, -28, -42, -51, -59,
+ -64, -67, -75, -79, -86, -94, -98, -105, -111, -115, -117, -121, -123, -111, -120, -102,
+ -95, -100, -79, -84, -81, -61, -69, -55, -46, -42, -27, -14, -3, 11, 30, 35,
+ 49, 57, 60, 76, 76, 86, 95, 95, 109, 108, 116, 122, 121, 123, 120, 116,
+ 114, 106, 100, 94, 88, 78, 73, 65, 59, 52, 38, 33, 20, 10, -2, -15,
+ -22, -32, -42, -51, -58, -62, -67, -77, -80, -86, -94, -100, -106, -113, -115, -119,
+ -122, -118, -117, -107, -106, -98, -89, -89, -78, -76, -71, -57, -56, -46, -36, -25,
+ -12, 0, 16, 26, 39, 49, 54, 67, 72, 80, 88, 94, 101, 104, 115, 113,
+ 121, 125, 116, 123, 116, 110, 109, 98, 93, 88, 78, 69, 65, 56, 47, 42,
+ 27, 20, 8, -6, -15, -27, -33, -43, -53, -58, -64, -68, -74, -86, -87, -96,
+ -106, -103, -117, -116, -117, -123, -117, -106, -114, -97, -96, -96, -81, -81, -80, -62,
+ -64, -49, -45, -34, -19, -8, 4, 17, 28, 40, 47, 54, 66, 73, 79, 93,
+ 95, 102, 113, 110, 117, 123, 119, 121, 117, 113, 111, 106, 96, 95, 88, 78,
+ 72, 63, 55, 47, 35, 26, 14, 4, -9, -19, -24, -35, -43, -51, -61, -65,
+ -72, -79, -88, -88, -99, -107, -107, -120, -114, -120, -122, -113, -116, -102, -106, -95,
+ -89, -95, -72, -80, -70, -50, -58, -37, -30, -20, -5, 6, 18, 29, 44, 45,
+ 57, 72, 68, 89, 89, 97, 109, 104, 120, 113, 118, 124, 112, 120, 112, 107,
+ 106, 96, 91, 87, 78, 66, 65, 52, 40, 39, 17, 17, 4, -13, -13, -30,
+ -35, -44, -58, -59, -66, -72, -78, -85, -93, -97, -106, -114, -110, -120, -120, -118,
+ -120, -109, -110, -98, -100, -89, -81, -87, -68, -68, -59, -44, -46, -29, -18, -5,
+ 5, 22, 32, 39, 54, 56, 68, 79, 79, 94, 98, 102, 110, 112, 117, 119,
+ 124, 117, 116, 116, 104, 106, 97, 89, 86, 74, 67, 60, 53, 41, 34, 24,
+ 12, 4, -9, -19, -28, -38, -47, -58, -60, -68, -73, -77, -88, -93, -96, -111,
+ -109, -115, -124, -118, -122, -120, -107, -109, -102, -91, -95, -82, -78, -78, -60, -59,
+ -51, -36, -35, -14, -3, 6, 24, 34, 41, 56, 59, 67, 81, 82, 92, 103,
+ 102, 112, 119, 114, 123, 123, 116, 121, 112, 106, 107, 93, 91, 84, 74, 69,
+ 61, 52, 43, 32, 21, 13, -2, -10, -22, -31, -38, -51, -56, -59, -69, -71,
+ -76, -87, -90, -100, -107, -110, -119, -118, -120, -123, -108, -118, -101, -92, -102, -77,
+ -85, -83, -63, -71, -58, -45, -44, -27, -15, -2, 10, 30, 32, 46, 57, 56,
+ 74, 73, 84, 93, 95, 109, 108, 117, 117, 124, 119, 119, 119, 112, 109, 100,
+ 96, 90, 81, 75, 65, 59, 51, 41, 33, 22, 12, 0, -12, -23, -30, -40,
+ -51, -57, -64, -71, -73, -83, -84, -95, -102, -102, -116, -117, -118, -128, -116, -114,
+ -116, -102, -99, -95, -86, -80, -80, -71, -58, -61, -46, -38, -30, -10, -4, 12,
+ 26, 37, 47, 54, 67, 68, 79, 89, 86, 104, 104, 111, 118, 118, 123, 121,
+ 119, 116, 112, 109, 99, 96, 88, 80, 75, 66, 58, 49, 41, 29, 19, 10,
+ -5, -10, -25, -35, -39, -53, -58, -64, -69, -75, -81, -87, -100, -99, -112, -116,
+ -118, -126, -123, -115, -120, -111, -102, -100, -93, -86, -85, -76, -69, -64, -56, -47,
+ -38, -25, -10, 4, 16, 31, 40, 46, 61, 65, 70, 83, 86, 93, 103, 105,
+ 114, 125, 118, 124, 125, 112, 120, 111, 98, 103, 91, 86, 83, 71, 66, 61,
+ 49, 38, 32, 16, 7, -4, -17, -26, -36, -44, -54, -60, -59, -71, -75, -79,
+ -94, -95, -103, -117, -112, -120, -127, -120, -118, -117, -104, -102, -99, -88, -84, -86,
+ -73, -70, -64, -51, -47, -37, -17, -10, 7, 19, 32, 40, 52, 56, 67, 73,
+ 80, 87, 92, 103, 109, 110, 123, 119, 121, 126, 111, 113, 112, 98, 98, 91,
+ 80, 80, 71, 60, 61, 47, 36, 30, 13, 5, -5, -19, -27, -35, -43, -52,
+ -58, -62, -71, -76, -84, -96, -100, -105, -118, -115, -121, -123, -121, -114, -117, -110,
+ -98, -105, -91, -83, -90, -71, -68, -64, -48, -43, -33, -17, -5, 3, 23, 32,
+ 38, 54, 59, 66, 79, 82, 92, 100, 105, 108, 116, 119, 117, 126, 116, 115,
+ 118, 106, 105, 99, 91, 85, 78, 67, 60, 54, 41, 33, 24, 11, 0, 3,
+ 10, 14, -8, 46, 7, -20, -23, -28, 17, 9, 47, -7, -15, -35, -1, -26,
+ 44, 34, -31, 31, -47, -32, 30, -2, 32, 15, -15, -17, -39, 16, -2, 26,
+ 23, 3, -43, 11, -37, 14, 37, 7, 4, -21, -30, -9, 14, 18, 38, -13,
+ -16, -21, -24, 8, 38, 3, 16, -29, -11, -26, 20, 15, 24, -9, 0, -34,
+ -21, 32, -16, 41, -1, -20, -7, -7, -7, 27, 0, -2, -2, -11, -11, 19,
+ -16, 32, -19, -4, 11, -40, 49, -13, -12, 12, -32, 12, 17, 1, 23, -34,
+ -20, 14, -20, 33, 44, -51, 7, -21, -38, 46, 19, 37, -28, -29, -17, -40,
+ 63, 36, -33, 42, -45, -57, 16, 37, -3, 54, 0, -64, -25, -7, 15, 37,
+ 34, -2, -65, -12, -3, -7, 76, -2, -6, -28, -22, -30, 40, 11, 12, 21,
+ -43, -6, -1, -31, 73, -35, 33, -1, -67, 29, -24, 16, 42, 4, -26, 17,
+ -71, 32, 0, 0, 72, -56, 4, -2, -75, 76, -25, 39, 24, -42, -6, -20,
+ -31, 56, 1, 3, 49, -63, -12, -16, -10, 49, 12, 29, -32, -59, 35, -39,
+ 35, 45, -33, -21, 46, -68, 13, 16, 12, 0, 2, 32, -70, 12, 30, -62,
+ 64, 5, -31, 22, -30, 11, -30, 43, 2, -8, 16, -3, -60, 39, -11, -13,
+ 63, -32, 8, -6, -45, 39, -38, 30, 49, -89, 96, -84, 0, 43, -51, 52,
+ -4, -6, 7, -31, -10, 12, -22, 62, 8, -57, 65, -101, 1, 69, -46, 76,
+ -18, -34, -24, -33, 50, -6, 55, 16, -70, -19, 2, -33, 59, 61, -40, 7,
+ -44, -33, -7, 61, 31, -15, 5, -32, -70, 47, 34, 8, 22, -16, -44, -47,
+ 56, -6, 12, 56, -46, -32, -3, 7, -4, 42, 19, -41, -35, 41, -59, 43,
+ 45, -44, 9, -9, -7, -19, 36, 2, -50, 49, -6, -34, 33, -1, -38, 17,
+ 44, -33, 5, 28, -68, -13, 62, -25, 15, 45, -57, -32, 23, -14, 37, 11,
+ 29, -56, -48, 46, -55, 48, 94, -74, 22, -40, -59, 36, 9, 75, -19, -31,
+ 6, -104, 39, 80, -23, 59, -12, -104, 10, -12, 24, 59, 5, 9, -78, -12,
+ 24, -47, 116, -6, -51, 34, -71, -26, 55, 3, 11, 38, -31, -9, -45, 21,
+ -11, 4, 92, -79, 16, -16, -41, 29, 27, 19, -5, -19, -13, -35, 29, 22,
+ -7, 20, -35, 6, -21, 30, -2, 6, -8, -20, -12, 30, -13, 8, 23, -52,
+ 21, 8, -16, 40, -20, -7, -15, -38, 62, -33, 48, 5, -66, 28, -25, 15,
+ 39, 5, -46, 8, -46, 32, 12, 37, -9, -49, 43, -78, 43, 46, -43, 39,
+ -41, -36, 13, 19, 48, -21, 9, -37, -54, 45, 32, -14, 41, -32, -66, 42,
+ -8, 37, 12, -10, -12, -74, 71, -30, 16, 65, -64, -1, -13, -12, 17, 24,
+ 10, -16, -31, -1, -3, 1, 68, -47, -7, -8, -41, 74, -16, 32, -27, -42,
+ 22, -49, 80, -11, 0, 23, -84, 34, -24, 31, 48, -37, 23, -55, -25, 22,
+ 14, 22, 59, -78, -11, -1, -45, 90, -35, 32, 0, -75, 63, -65, 34, 52,
+ -71, 70, -56, -14, 30, -22, 10, 55, -74, 41, -19, -47, 88, -62, 50, -11,
+ -57, 44, -54, 59, 17, -23, 12, -40, -41, 60, 3, 15, 28, -71, -1, -17,
+ 11, 61, -28, 47, -59, -48, 35, -18, 51, 27, -20, -35, -36, 14, 6, 44,
+ 23, -30, -33, -17, -1, 14, 49, -2, -32, -12, -20, 5, 29, 34, -33, 9,
+ -34, -26, 36, -2, 40, -28, 5, -26, -39, 65, -27, 19, 31, -54, 0, -8,
+ 12, 2, 30, -5, -25, -22, 24, -29, 26, 52, -57, 7, 5, -56, 46, 1,
+ 8, 4, -5, 1, -51, 28, 14, -21, 48, -17, -46, 4, 11, -6, 35, 7,
+ -16, -31, -10, 25, -49, 95, -28, -29, 19, -46, -5, 32, 21, 8, -1, -24,
+ -36, -17, 59, -7, 33, 10, -76, -14, 19, -1, 56, 16, -23, -64, -8, 7,
+ 8, 85, 0, -57, -21, -35, -7, 72, 23, 28, -66, -16, -47, 2, 68, 24,
+ 5, 0, -69, -26, 22, -7, 72, 0, -12, -20, -51, 15, -11, 44, 44, -46,
+ 36, -59, -38, 32, 19, -3, 71, -45, -28, -29, -17, 36, 8, 79, -47, -53,
+ 18, -65, 38, 75, -24, 20, -36, -34, -26, 38, 39, -7, -3, 7, -85, 44,
+ 26, -17, 42, -20, -29, -26, 26, 18, -8, 36, -17, -73, 40, 4, -1, 52,
+ -16, -47, -15, 14, 4, 29, 30, -41, -44, 15, -2, 16, 60, -26, -54, 17,
+ -33, 22, 48, -5, -15, -20, -13, -15, 31, 37, -28, 6, -17, -22, -10, 64,
+ -43, 16, 22, -71, 41, 3, -1, 6, -12, 12, -38, 11, 38, -49, 37, 24,
+ -64, 27, 18, -73, 81, -33, 14, -3, -32, 43, -60, 53, 24, -76, 70, -29,
+ -33, 50, -18, -34, 48, -38, 37, -15, -5, 25, -80, 70, -4, -45, 89, -72,
+ -3, 13, -23, 28, 21, -9, -9, -25, -11, 24, -26, 62, -14, -49, 67, -97,
+ 57, 12, -23, 46, -46, 9, -20, -4, 25, -1, 5, 18, -31, -25, 38, -43,
+ 44, 17, -42, 37, -66, 37, -16, 26, 18, -16, -17, -4, -17, 7, 38, -11,
+ 4, -3, -51, 32, -17, 38, 18, -34, 23, -58, 4, 25, 0, 26, 3, -35,
+ -11, -10, 16, 24, 8, 4, -33, -30, 22, -2, 14, 52, -61, 10, -23, -4,
+ 20, 10, 32, -44, -2, 1, -36, 37, 32, -25, 2, 0, -40, 14, 24, -5,
+ 13, -28, 20, -51, 41, 15, -23, 25, -12, -41, 30, -2, -11, 40, -34, 14,
+ -24, 3, 22, -31, 44, -22, -31, 57, -55, 28, 0, -9, 1, 11, -10, 8,
+ -13, 3, -2, -23, 60, -49, 23, 10, -59, 36, -3, -3, 35, -23, 5, -42,
+ 15, 7, -2, 35, 0, -45, 8, -4, -27, 63, -4, -14, 9, -39, 1, 1,
+ 27, 19, -27, 24, -49, -6, 34, -5, 10, 19, -32, -20, 14, -12, 16, 26,
+ -9, -19, -9, -8, 8, 7, 40, -29, -14, -4, -25, 7, 56, -15, 6, -20,
+ -36, 3, 10, 33, 20, -23, -5, -42, -18, 54, -17, 63, -5, -59, 2, -44,
+ 12, 57, 17, 15, -33, -44, -16, -17, 65, 40, -9, 10, -72, -51, 39, 10,
+ 65, 19, -25, -47, -51, 17, 20, 53, 30, -35, -35, -34, -16, 36, 48, 12,
+ -3, -35, -42, -9, 28, 34, 12, 15, -42, -39, 7, 8, 24, 28, 1, -31,
+ -36, 9, -1, 28, 29, -14, -34, 14, -43, 23, 34, -7, 24, -44, 10, -28,
+ -5, 53, -29, 29, -7, -33, 2, -1, 5, 19, 10, -17, 2, -33, 14, 1,
+ 8, 32, -36, 17, -28, -18, 36, -22, 29, 2, -25, 5, -17, 13, 1, 16,
+ -1, -10, -12, 3, -9, 10, 19, -22, 16, -3, -20, 24, -22, 15, -3, -14,
+ 22, -30, 31, -14, -11, 12, -11, 8, 17, -9, -4, -13, -13, 7, 10, 19,
+ -6, -7, -2, -32, 24, 8, 0, 17, -20, -10, -15, 13, 10, 11, 4, -1,
+ -40, 19, -4, -6, 42, -31, -1, -5, -12, 19, 6, 7, -5, -26, 10, -12,
+ 15, 20, -8, -19, 12, -40, 31, 15, -3, 16, -23, -27, 7, -5, 31, 6,
+ 3, -6, -41, 14, -2, 7, 38, -10, -29, 11, -44, 17, 29, 6, 20, -26,
+ 1, -45, 9, 31, -18, 40, -1, -47, 8, -10, -4, 29, 33, -25, 1, -31,
+ -12, -9, 35, 30, -25, 31, -48, -28, 20, 17, 9, 30, -19, -39, -13, 6,
+ 8, 38, 15, -10, -42, 0, -24, 15, 49, -9, -12, 5, -44, -5, 42, 4,
+ 6, 8, -27, -29, 5, 24, -2, 10, 28, -56, 1, 23, -29, 29, 15, -19,
+ -11, 1, -4, -8, 24, 6, -15, 2, 7, -27, 12, 21, -40, 36, -15, -12,
+ 22, -16, 17, -17, 15, -6, -18, 23, -3, -26, 39, -27, -5, 26, -20, 8,
+ 5, -11, 7, -21, 19, -11, -8, 35, -25, 2, 18, -35, 9, 16, -21, 29,
+ -16, 1, -13, -13, 28, -18, 23, 13, -36, 6, -1, -23, 26, 12, -15, 17,
+ -20, -2, -7, 3, 22, -22, 27, -11, -34, 36, -30, 11, 17, 2, -12, 13,
+ -22, -11, 11, -5, 26, -17, 26, -25, -32, 44, -47, 39, 25, -31, 16, -35,
+ -1, -4, 26, 16, 3, -16, -10, -23, -8, 55, -27, 26, 0, -63, 41, -26,
+ 28, 22, -23, 14, -42, 5, 20, -13, 28, 3, -42, 20, -6, -17, 52, -32,
+ 6, -2, -37, 42, -27, 29, 15, -51, 40, -38, 2, 33, -19, 6, 11, -43,
+ 25, 0, -19, 57, -54, 31, -9, -43, 58, -52, 36, 11, -44, 50, -44, 8,
+ 23, -24, 12, 6, -34, 25, -9, -15, 50, -55, 35, -7, -25, 49, -48, 32,
+ -23, -18, 37, -30, 28, 8, -27, 7, -2, -19, 22, 10, -11, 10, -27, 4,
+ -16, 18, 29, -19, 20, -22, -36, 16, -2, 18, 14, 3, -24, -15, -5, 12,
+ 13, 20, 4, -40, 2, -23, 8, 29, 7, 9, -23, -10, -13, 5, 19, 9,
+ -3, -14, -7, -19, 21, 6, 5, 10, -20, 0, -14, 12, 0, 2, 5, -13,
+ 1, -3, 12, -12, 20, -13, -7, 6, -11, 5, 0, 5, -5, -4, 10, -10,
+ 2, 6, -5, -12, 18, -13, -9, 19, -17, 11, -1, 8, -5, -22, 26, -26,
+ 1, 29, -17, -7, 16, -22, -8, 23, -3, 4, -3, -2, -15, -20, 42, -21,
+ 4, 40, -55, 8, 8, -22, 21, 20, -17, 2, -14, -7, -2, 10, 31, -25,
+ 10, -3, -54, 40, 5, -12, 42, -17, -37, 13, -12, 7, 24, 10, -6, -36,
+ 12, -9, -25, 74, -24, -19, 38, -64, 5, 25, 0, 16, 1, -9, -25, -23,
+ 36, -8, 6, 50, -58, -12, 22, -53, 52, 18, -12, 16, -51, 15, -30, 25,
+ 46, -37, 31, -26, -49, 30, 9, -1, 42, -19, -28, -13, -5, 16, 4, 42,
+ -18, -40, 20, -30, 1, 49, -4, -15, 0, -21, -19, 21, 26, 0, -9, 9,
+ -43, -1, 26, -5, 21, -7, -6, -32, 9, 12, -3, 34, -17, -12, -17, -4,
+ 9, 7, 28, -19, -3, -13, -11, 7, 15, 15, -19, 15, -38, -5, 17, -1,
+ 29, -20, 15, -39, -11, 41, -33, 45, -8, -21, -11, -3, 7, 0, 28, -7,
+ -19, -8, 7, -20, 23, 24, -40, 24, -17, -16, 26, -9, 21, -27, 13, -11,
+ -22, 29, -7, 0, 22, -22, -16, 14, -12, 12, 11, -5, -6, -17, 14, -15,
+ 9, 30, -28, 5, 1, -26, 8, 18, -7, 1, 6, -12, -15, 9, 13, -13,
+ 13, 13, -42, 14, 3, -16, 20, 7, -3, -22, 25, -26, 4, 16, -7, 3,
+ -8, 17, -33, 14, 9, -21, 25, -3, -11, -1, 1, -13, 1, 23, -20, 26,
+ -18, 0, -18, 3, 24, -25, 36, -15, -29, 22, -22, 3, 24, -5, -1, 0,
+ -18, 2, -11, 20, 10, -17, 30, -37, -15, 29, -33, 39, 11, -23, 7, -34,
+ 8, 0, 11, 36, -27, -12, 9, -47, 29, 31, -29, 40, -37, -14, 3, -17,
+ 45, -11, 8, 12, -60, 20, -2, -2, 41, -12, -18, 3, -37, 27, 12, -4,
+ 37, -56, 17, -21, -5, 44, -20, 14, -2, -40, 20, 0, 3, 22, -13, -10,
+ -6, -16, 29, -12, 14, 15, -49, 24, -11, -7, 39, -18, 3, -20, -12, 19,
+ -10, 32, 2, -34, 10, -13, -13, 37, 1, -7, 3, -33, 4, 2, 18, 25,
+ -25, 8, -33, -13, 34, -7, 24, 4, -33, -10, -2, 2, 25, 12, -1, -25,
+ -12, 3, -18, 34, 12, -15, 4, -9, -25, 10, 17, -3, 9, 2, -13, -23,
+ 9, 8, -13, 37, -10, -15, 1, -13, -1, 0, 31, -15, 0, 5, -29, 6,
+ 5, 15, -9, 16, -9, -29, 15, -10, 3, 15, 9, -11, -12, 11, -29, 17,
+ 14, -7, 6, -6, -7, -24, 30, -11, 9, 18, -20, -8, -6, 6, -10, 22,
+ 10, -29, 14, -13, -8, 13, 17, -13, 2, 1, -24, 5, 5, 12, -10, 15,
+ -7, -28, 21, -2, -8, 22, -9, -14, -2, 6, -5, 5, 12, -7, -15, 14,
+ -4, -16, 27, -10, -14, 13, -5, -9, 10, 5, -8, -5, 16, -20, 2, 13,
+ -14, -3, 17, -18, 2, 10, -12, 9, -6, -2, -16, 13, 10, -15, 33, -24,
+ -17, 10, -4, 15, 1, 9, -23, -9, 6, -5, 5, 21, -10, -13, 11, -21,
+ -2, 19, -10, 23, -20, 10, -16, -21, 33, -17, 17, 18, -30, 1, -14, -1,
+ 20, -2, 18, -15, -24, 6, -5, 6, 36, -26, 6, -18, -23, 34, -12, 25,
+ 1, -30, -1, -11, 10, 22, -1, 4, -19, -28, 21, -11, 22, 25, -33, 4,
+ -21, -7, 22, 7, 19, -23, -13, -3, -13, 21, 17, -11, 7, -19, -12, 12,
+ -10, 30, -13, -5, 4, -30, 27, -9, 17, -3, -25, 13, -23, 13, 27, -15,
+ -5, 3, -35, 17, 19, -8, 29, -37, 1, -15, -10, 48, -20, 26, -7, -49,
+ 22, -23, 21, 33, -10, -8, -17, -34, 11, 19, 12, 40, -39, -14, -13, -36,
+ 64, -4, 20, 9, -55, 3, -24, 21, 31, 10, -1, -22, -30, -7, 12, 18,
+ 29, -10, -7, -28, -22, 22, 3, 26, 4, -13, -18, -16, 21, -9, 28, -1,
+ -21, 0, -12, 5, 6, 5, 10, -20, 1, 3, -20, 21, 7, -23, 24, -25,
+ -6, 21, -13, 25, -19, -8, 2, -14, 20, 13, -23, 25, -31, -7, 24, -16,
+ 20, 6, -25, 8, -24, 12, 15, -10, 24, -25, -2, 0, -12, 14, 10, -13,
+ 4, 1, -17, 9, 6, -9, 9, 0, -3, -8, 11, -10, -2, 7, -1, -6,
+ 6, 1, -12, 1, 18, -31, 23, -2, -21, 21, -6, -8, 15, -14, 4, -6,
+ -1, 17, -22, 20, -6, -35, 37, -17, -6, 47, -41, 6, -6, -16, 12, 16,
+ 6, 1, -36, 18, -26, 4, 59, -36, -1, 16, -64, 30, 14, 1, 16, -13,
+ 0, -35, 17, 13, -8, 12, 14, -45, 11, 12, -24, 27, 12, -27, 10, -6,
+ -9, 1, 14, -7, -6, 8, -4, -8, 8, 8, -24, 13, 7, -27, 28, -1,
+ -28, 27, -19, -2, 17, -5, 6, -10, -5, 4, -25, 32, 2, -22, 32, -28,
+ -20, 35, -20, 16, 7, -18, 1, -22, 20, 0, 2, 20, -15, -25, 24, -25,
+ 12, 25, -23, 10, -19, -5, 8, 2, 20, -6, -13, 0, -22, 12, 15, -3,
+ 13, -13, -25, 12, -6, 18, 13, -3, -14, -22, 3, -2, 14, 25, -10, -16,
+ -5, -13, 2, 22, 9, -2, -11, -12, -20, 15, 20, 1, 14, -19, -17, -9,
+ 1, 19, 5, 0, 4, -35, 17, -7, 5, 20, -16, 2, -8, -11, 11, -2,
+ 2, 7, -19, 15, -10, 2, 12, -14, -3, 2, -9, 17, -3, 2, -7, -16,
+ 10, 2, 9, 10, -14, -9, -6, -11, 21, 5, 4, 6, -24, -5, -4, 6,
+ 18, 0, 8, -21, -18, 8, -8, 21, 16, -11, -9, -12, -15, 15, 3, 27,
+ -9, -16, 5, -30, 13, 23, -11, 21, -19, -15, -3, -9, 30, -9, 14, -6,
+ -22, -5, 15, -11, 23, -1, -14, -4, -9, 8, 4, 1, 20, -34, 9, 1,
+ -17, 24, -6, 1, -9, 1, -4, 3, 6, 8, -16, 0, 2, -13, 11, 21,
+ -31, 24, -21, -4, 13, -2, 7, -9, -3, 0, -18, 29, -4, -9, 16, -19,
+ -13, 25, -5, -1, 15, -24, 4, -15, 22, 4, -11, 20, -21, -25, 39, -23,
+ 14, 14, -23, 1, -8, 3, 12, -9, 23, -19, -18, 24, -22, 5, 30, -32,
+ 11, 2, -21, 18, -6, 5, 1, -9, 13, -22, 4, 19, -28, 26, 3, -28,
+ 21, -4, -25, 32, -15, 5, 0, -2, -4, -9, 15, 0, -13, 21, -14, -20,
+ 31, -19, 2, 17, -14, -9, 12, -6, 4, -1, 4, -17, -1, 12, -2, 0,
+ 20, -31, -8, 12, -8, 17, 14, -13, -16, -9, -7, 20, 11, 18, -13, -28,
+ -3, -12, 13, 40, -12, 4, -20, -32, 8, 17, 14, 21, -10, -28, -18, -2,
+ 11, 22, 17, 0, -34, -6, -3, -17, 50, 1, -13, 4, -22, -21, 17, 16,
+ 4, 7, 0, -27, -11, 4, 10, 2, 24, -6, -28, 7, -12, -2, 33, -3,
+ -6, 2, -37, 3, 9, 7, 24, -4, -14, -6, -24, 25, -1, 11, 16, -36,
+ -9, 12, -25, 45, 5, -20, 11, -36, 11, 7, 0, 30, -32, -1, 7, -33,
+ 37, 0, -9, 15, -21, -10, 12, -15, 24, -8, 3, 4, -20, 7, 3, -15,
+ 28, -14, -7, 13, -23, 2, 11, 0, 4, 7, -9, -16, 1, 7, -7, 19,
+ -3, -12, -14, 15, -10, 7, 30, -26, -13, 15, -30, 15, 26, -12, -1, -8,
+ -9, -5, 13, 22, -12, -12, 7, -36, 17, 31, -24, 27, -21, -24, 15, -10,
+ 26, 4, -12, 4, -36, 13, 14, -5, 27, -14, -22, 7, -12, 6, 23, -13,
+ 7, -19, -2, 7, -8, 25, -5, -17, 18, -25, 3, 14, -8, 4, 0, -1,
+ -11, 4, 12, -18, 15, 2, -23, 12, -2, -7, 12, 1, -1, -15, 11, -3,
+ -17, 41, -24, -7, 13, -25, 3, 22, -9, 15, -12, -9, 0, -17, 32, -5,
+ -5, 19, -49, 19, 3, -11, 45, -30, 2, -4, -28, 29, 0, 7, 12, -34,
+ 6, -10, 1, 33, -9, -6, 4, -41, 25, 2, 4, 29, -40, 8, -17, -9,
+ 42, -16, 16, -10, -33, 11, -7, 22, 12, -6, -6, -25, -4, 18, -3, 25,
+ -4, -29, 5, -17, 8, 22, 1, 4, -22, 1, -13, 2, 31, -19, 9, 2,
+ -36, 17, 5, -7, 20, -11, -2, -13, 4, 9, -18, 24, -3, -30, 33, -19,
+ -11, 31, -21, 6, 0, -5, 3, -10, 17, -7, -19, 30, -24, 0, 26, -23,
+ 3, 7, -17, 9, -3, 9, -1, -17, 23, -25, -3, 34, -27, 10, 15, -34,
+ 9, 1, 1, 7, -1, 12, -31, 4, 16, -27, 32, 10, -33, 10, -1, -27,
+ 29, 9, -9, 0, -1, -16, -6, 24, 2, -17, 23, -20, -24, 33, -11, -2,
+ 17, -7, -21, 13, 1, -7, 10, 1, -12, -9, 13, -1, -5, 20, -16, -15,
+ 15, -8, 5, 13, -10, -7, -9, 5, 2, 10, 7, -7, -22, 12, -13, 6,
+ 26, -14, -6, 0, -17, 3, 16, 6, 0, -11, 3, -26, 13, 15, -6, 7,
+ 4, -29, 6, 7, -3, 13, 1, -11, -9, 2, -1, 3, 9, -3, -8, 1,
+ -4, 0, 5, 0, 0, -2, 0, -1, 0, 0, -2, 11, 23, 22, 24, 25,
+ 20, 21, 15, 40, -1, -24, -42, -5, -19, -11, -8, 4, -46, -31, -14, -33,
+ -40, -44, -48, -89, -63, -47, -33, -27, -10, -6, 22, 25, 26, 28, 37, 11,
+ 15, 51, 44, 54, 66, 66, 71, 111, 84, 70, 63, 47, 39, 22, 47, -28,
+ -79, -111, -90, -91, -112, -81, -87, -49, -46, -5, -24, 26, 24, 47, 29, 23,
+ 30, 30, 13, -1, 4, -14, 17, 35, 62, 31, 53, 59, 72, 64, 27, 26,
+ 9, 9, -61, -44, -88, -74, -81, -83, -124, -96, -37, -78, -48, -56, -68, -60,
+ 7, 44, 39, 54, 77, 102, 110, 108, 89, 101, 100, 105, 64, 22, -1, 44,
+ 40, -19, -29, -35, -16, -27, -40, -77, -82, -113, -104, -93, -57, -72, -56, -3,
+ 1, 7, -1, 49, 39, 30, 31, 23, 10, 31, 11, 7, -19, -2, -2, 28,
+ 62, 92, 75, 33, 34, -20, -47, -61, -85, -105, -93, -119, -112, -54, -70, -67,
+ -32, -1, 4, 4, 20, 29, 62, 70, 54, 62, 78, 115, 92, 85, 78, 52,
+ 21, 19, 27, 2, -8, 13, 0, 5, 3, 9, 18, 0, -59, -61, -45, -57,
+ -65, -76, -89, -102, -48, -24, 17, 6, 26, 33, 35, 26, 41, 63, 20, 12,
+ 29, 34, 8, 7, 31, 21, 31, 39, 33, -5, -8, -55, -57, -98, -94, -88,
+ -64, -82, -74, -39, -14, 3, 16, 22, 8, 2, 17, 5, 36, 76, 74, 71,
+ 57, 73, 62, 47, 30, 32, 19, 4, 7, -14, -18, -2, 17, -5, 13, 22,
+ 31, 10, 8, -13, -47, -80, -85, -86, -71, -73, -60, -35, -10, 9, 19, 49,
+ 53, 47, 60, 73, 43, 33, 20, 13, -1, -7, -7, 7, 9, -2, 5, -14,
+ -40, -69, -61, -66, -67, -84, -58, -58, -33, 2, -7, -5, 12, 32, 18, 25,
+ 19, 24, 65, 59, 62, 64, 63, 55, 60, 52, 31, 19, -12, -26, -4, -7,
+ -10, -3, 6, -22, -14, 12, 19, 4, -26, -38, -40, -56, -61, -66, -59, -65,
+ -51, -20, 29, 40, 51, 52, 62, 61, 53, 26, 20, 6, 8, 6, 9, -14,
+ -14, -15, -2, -11, -23, -36, -38, -60, -77, -69, -60, -51, -56, -44, -27, 10,
+ -2, 14, 10, 22, 16, 41, 60, 39, 35, 60, 62, 43, 45, 63, 52, 17,
+ 12, 15, -1, -2, 0, -38, -48, -32, -22, -7, 3, 13, 10, -2, -1, -8,
+ -12, -25, -48, -46, -52, -49, -36, -17, 9, 17, 26, 48, 57, 55, 69, 60,
+ 32, 6, 4, -6, -20, -24, -9, -21, -25, -14, -18, -38, -38, -32, -51, -52,
+ -60, -34, -6, -6, -16, -11, -2, -1, 17, 19, 3, 11, 25, 31, 41, 39,
+ 33, 33, 41, 34, 34, 23, 21, 15, 6, -13, -24, -28, -20, -8, -12, -19,
+ -12, -5, 9, 14, 2, -12, -25, -28, -21, -28, -23, -22, -18, -26, -5, 24,
+ 45, 46, 47, 39, 33, 36, 42, 29, 7, -5, -10, -21, -29, -39, -39, -31,
+ -24, -29, -39, -51, -43, -27, -22, -18, -25, -26, -20, 9, 19, 18, 4, -2,
+ 19, 30, 38, 25, 24, 28, 33, 41, 38, 34, 32, 38, 24, 8, 4, -8,
+ -11, -15, -25, -31, -25, -20, -22, -15, -11, -9, -12, -17, -20, -20, -15, -6,
+ -11, -8, 0, 11, 29, 19, 17, 17, 18, 28, 31, 25, 18, 23, 18, 10,
+ 1, -7, -18, -26, -24, -30, -41, -38, -44, -32, -31, -31, -35, -25, -12, -2,
+ -8, -11, -13, -13, -2, 8, 15, 19, 29, 35, 37, 39, 43, 42, 40, 35,
+ 27, 25, 18, 15, 9, 4, -4, -15, -28, -28, -26, -28, -18, -15, -25, -23,
+ -12, -11, -14, -10, -2, -4, -1, 8, 15, 19, 22, 25, 16, 16, 17, 5,
+ 7, 13, 18, 13, 9, 6, 6, 4, -4, -21, -31, -28, -37, -39, -34, -38,
+ -38, -32, -17, -6, -4, -14, -19, -9, 3, -2, 3, 4, 7, 8, 13, 23,
+ 35, 38, 43, 42, 31, 25, 23, 17, 8, 3, 4, -7, -7, -10, -13, -20,
+ -19, -28, -33, -30, -23, -18, -13, -17, -12, 3, 14, 23, 31, 27, 23, 21,
+ 22, 19, 12, 4, 2, 2, -2, 0, 4, 11, 11, 6, 4, -2, -5, -14,
+ -17, -30, -38, -44, -42, -28, -21, -23, -21, -15, -15, -4, 8, 11, 4, -7,
+ -15, -7, 5, 10, 21, 26, 28, 27, 34, 37, 36, 28, 19, 10, 11, 8,
+ -2, -18, -17, -19, -19, -22, -24, -21, -24, -18, -17, -13, -19, -13, -1, 12,
+ 19, 22, 21, 19, 19, 30, 34, 24, 13, 7, 2, 1, 1, 2, -1, -2,
+ -6, 0, 0, -2, -15, -21, -17, -21, -28, -32, -31, -31, -32, -27, -24, -17,
+ -4, 1, -3, -1, 1, 4, 7, 8, 15, 16, 15, 15, 20, 32, 36, 38,
+ 32, 19, 12, 3, 2, -2, -4, -11, -19, -17, -15, -11, -16, -20, -27, -30,
+ -28, -22, -13, -6, -2, 2, 12, 23, 29, 45, 44, 36, 32, 21, 16, 14,
+ 10, 1, -9, -8, -2, -1, -7, -13, -13, -12, -9, -11, -18, -24, -26, -28,
+ -30, -24, -21, -21, -21, -11, -11, -10, 0, -2, 0, 4, 12, 13, 14, 12,
+ 17, 22, 28, 30, 28, 20, 16, 13, 8, 2, -2, -6, -15, -14, -18, -15,
+ -15, -16, -18, -18, -16, -19, -18, -17, -10, 0, -1, 4, 13, 22, 37, 39,
+ 36, 27, 27, 32, 26, 15, 6, -1, -4, -5, -7, -11, -11, -9, -15, -15,
+ -14, -18, -21, -19, -17, -21, -19, -15, -15, -10, -15, -14, -12, -11, -6, -2,
+ 1, -2, 1, 5, 14, 22, 33, 35, 23, 18, 16, 13, 11, 6, 1, -9,
+ -18, -11, -6, -7, -8, -9, -11, -11, -12, -13, -17, -21, -24, -24, -15, -4,
+ 7, 12, 17, 25, 30, 28, 31, 32, 31, 27, 22, 15, 12, 3, -2, -8,
+ -6, -3, -9, -13, -22, -24, -20, -18, -22, -24, -18, -14, -13, -10, -11, -9,
+ -3, -2, -3, -5, -10, -10, -5, -1, 4, 11, 15, 19, 22, 27, 23, 20,
+ 16, 14, 5, -3, -11, -15, -16, -12, -12, -11, -5, 1, -3, -10, -13, -15,
+ -11, -10, -10, -11, -8, -3, 2, 7, 9, 15, 25, 30, 33, 31, 25, 21,
+ 20, 16, 13, 7, -2, -8, -5, -4, -11, -20, -21, -22, -21, -17, -20, -21,
+ -22, -19, -19, -11, -4, -2, -2, -2, 2, 5, 2, 0, 0, -3, 1, 8,
+ 16, 13, 14, 17, 15, 13, 8, 5, -1, -6, -10, -13, -14, -14, -13, -10,
+ -7, -8, -8, -6, -6, -3, -1, -1, -9, -12, -7, 3, 13, 17, 14, 13,
+ 17, 22, 23, 24, 18, 15, 18, 18, 18, 15, 8, 0, -5, -8, -11, -15,
+ -17, -21, -26, -26, -24, -26, -24, -13, -9, -6, -3, -2, 3, 4, 6, 7,
+ 5, 2, 4, 2, -2, -4, -3, 5, 13, 17, 10, 3, -1, -2, -4, -5,
+ -11, -14, -13, -11, -8, -8, -8, -6, -3, 0, -1, -5, -5, 0, 4, 3,
+ 1, 2, 0, 0, 6, 13, 20, 17, 17, 18, 21, 18, 14, 13, 11, 11,
+ 7, 9, 3, -5, -12, -14, -18, -21, -23, -26, -26, -13, -3, -6, -13, -14,
+ -5, 5, 8, 3, 0, 1, 3, 6, 4, -1, -1, 1, 3, 7, 5, 3,
+ 0, 1, -1, 3, 0, -3, -11, -11, -9, -10, -9, -8, -5, -7, -7, -10,
+ -9, -6, -1, 4, 6, 4, 2, 5, 10, 13, 9, 12, 13, 14, 15, 16,
+ 13, 12, 10, 13, 14, 13, 8, 2, -1, -4, -6, -9, -15, -20, -21, -19,
+ -14, -16, -22, -21, -13, -5, -3, -3, -1, 3, 5, 10, 9, 9, 6, 8,
+ 7, 7, 7, 3, -4, -6, -4, -1, -4, -8, -10, -11, -8, -4, -6, -10,
+ -7, -8, -11, -11, -8, -5, -4, 0, 3, 3, 8, 10, 10, 12, 12, 11,
+ 10, 13, 12, 10, 6, 8, 9, 9, 11, 13, 11, 9, 10, 7, 2, -3,
+ -8, -9, -14, -16, -16, -19, -18, -14, -13, -11, -11, -10, -5, -1, 3, 5,
+ 2, 2, 9, 14, 11, 9, 10, 7, 2, 0, 2, -2, -9, -13, -15, -18,
+ -17, -15, -13, -10, -5, -5, -7, -7, -4, -1, 0, -2, -4, -2, 1, 4,
+ 9, 10, 10, 11, 11, 13, 14, 10, 11, 9, 9, 4, 6, 5, 4, 5,
+ 7, 8, 10, 9, 4, -4, -8, -9, -10, -11, -12, -14, -15, -17, -15, -9,
+ -4, -1, -6, -5, 2, 8, 8, 6, 5, 3, 4, 5, 9, 10, 10, 5,
+ -1, -5, -10, -12, -14, -16, -18, -17, -11, -10, -11, -8, -5, -2, -2, 0,
+ 3, 4, 5, 3, 2, 3, 5, 9, 12, 12, 11, 10, 12, 14, 12, 8,
+ 5, 0, -1, 1, 3, 0, 1, 3, 5, 6, 5, 0, -5, -11, -10, -13,
+ -12, -13, -15, -14, -8, -4, -3, -3, -4, 0, 4, 5, 3, 6, 4, 4,
+ 7, 10, 9, 9, 8, 5, 5, 2, -4, -10, -15, -17, -20, -22, -22, -19,
+ -14, -11, -10, -8, -6, 0, 3, 5, 3, 4, 8, 11, 11, 12, 13, 12,
+ 12, 15, 15, 16, 16, 13, 11, 6, 3, -2, -5, -5, -3, -2, -1, 2,
+ 0, -3, -4, -5, -7, -10, -12, -11, -12, -11, -8, -4, -2, 0, 1, 2,
+ 2, 2, 4, 3, 3, 4, 5, 9, 10, 6, 2, 1, 2, 0, -3, -7,
+ -13, -18, -19, -18, -16, -18, -20, -19, -14, -8, -4, -1, 3, 3, 5, 7,
+ 9, 9, 10, 12, 13, 13, 13, 13, 16, 15, 13, 9, 6, 3, 2, 1,
+ 0, -3, -5, -6, -4, -2, -2, -4, -4, -5, -5, -3, -3, -4, -6, -6,
+ -7, -4, 0, 2, 3, 2, 2, 1, 2, 2, 1, 4, 5, 4, 1, 0,
+ 2, 2, 0, -2, -6, -8, -6, -7, -9, -11, -15, -18, -19, -18, -18, -17,
+ -13, -9, -2, 2, 3, 5, 10, 12, 13, 14, 14, 15, 17, 17, 16, 16,
+ 15, 13, 11, 7, 2, -6, -10, -8, -6, -8, -8, -7, -6, -6, -3, -4,
+ -6, -5, -3, -2, -2, 0, 1, 0, 2, 2, 3, 2, 3, 2, 3, 3,
+ 5, 2, 0, 4, 6, 5, -1, -4, -2, -1, -2, -6, -8, -9, -10, -12,
+ -10, -14, -17, -22, -22, -21, -19, -15, -8, -3, 1, 7, 12, 12, 15, 19,
+ 22, 21, 18, 16, 16, 16, 13, 12, 6, 3, 3, 2, -3, -6, -7, -12,
+ -12, -11, -8, -9, -8, -7, -3, 0, 0, 0, 0, -2, -2, 0, 1, 2,
+ 2, 4, 6, 6, 7, 5, 4, 3, 4, 5, 3, 0, -2, -2, -4, -6,
+ -10, -8, -8, -10, -11, -12, -12, -12, -13, -16, -16, -16, -14, -11, -8, -4,
+ -2, 1, 6, 12, 17, 19, 20, 20, 21, 21, 19, 13, 10, 9, 5, 0,
+ -3, -4, -4, -5, -6, -6, -4, -7, -10, -12, -12, -12, -10, -7, -4, -2,
+ 4, 6, 8, 7, 7, 7, 7, 8, 8, 7, 5, 6, 6, 4, 1, -1,
+ -1, 0, -3, -7, -10, -10, -8, -11, -14, -14, -12, -11, -9, -6, -8, -8,
+ -8, -11, -13, -12, -9, -8, -5, 0, 4, 8, 11, 14, 18, 18, 20, 23,
+ 23, 20, 14, 9, 4, 0, -3, -6, -8, -8, -8, -8, -9, -10, -11, -10,
+ -9, -8, -8, -7, -6, -3, 0, 3, 6, 12, 16, 16, 14, 10, 8, 9,
+ 7, 4, 1, 0, 0, -2, -1, 0, 0, -3, -7, -10, -13, -13, -12, -13,
+ -15, -14, -13, -9, -6, -5, -5, -7, -8, -9, -7, -6, -5, -7, -5, 1,
+ 8, 13, 17, 19, 20, 21, 22, 22, 18, 12, 9, 5, -1, -5, -9, -11,
+ -13, -12, -12, -11, -10, -8, -7, -7, -6, -7, -6, -3, 0, 1, 3, 7,
+ 10, 11, 12, 15, 15, 14, 9, 6, 3, 1, 0, -2, -2, -2, -3, -6,
+ -8, -10, -11, -13, -15, -15, -15, -13, -12, -12, -7, -5, -5, -5, -4, -3,
+ -3, -4, -4, -1, -1, 1, 4, 7, 10, 12, 14, 17, 20, 22, 19, 14,
+ 8, 5, 2, -2, -5, -10, -14, -13, -11, -10, -10, -10, -10, -8, -6, -3,
+ -3, -3, -1, -1, 2, 6, 10, 13, 14, 15, 15, 15, 13, 11, 8, 5,
+ 1, -1, -3, -3, -6, -10, -12, -12, -12, -12, -13, -15, -18, -19, -15, -11,
+ -6, -4, -3, -4, -4, -2, 1, 4, 2, -1, -2, 1, 4, 6, 8, 7,
+ 7, 11, 14, 15, 15, 15, 13, 10, 6, 1, -3, -6, -9, -13, -15, -15,
+ -13, -11, -9, -9, -9, -7, -3, 0, 2, 2, 4, 7, 11, 15, 16, 14,
+ 11, 12, 13, 15, 13, 9, 4, 1, -1, -4, -6, -8, -11, -15, -17, -17,
+ -17, -17, -15, -13, -13, -12, -10, -7, -6, -4, 1, 2, 2, 3, 4, 5,
+ 4, 4, 3, 5, 6, 6, 8, 7, 7, 9, 11, 10, 9, 8, 5, 2,
+ 0, -2, -6, -10, -13, -13, -14, -14, -13, -11, -9, -4, -1, -1, -1, 2,
+ 6, 8, 10, 11, 12, 14, 14, 14, 13, 11, 10, 7, 4, 2, 3, 1,
+ -3, -6, -10, -14, -17, -18, -18, -19, -19, -17, -15, -13, -9, -5, -1, 1,
+ 0, 1, 3, 5, 6, 6, 6, 7, 8, 9, 8, 4, 1, 0, 2, 4,
+ 5, 6, 5, 4, 4, 4, 3, 1, -3, -7, -9, -11, -12, -12, -12, -11,
+ -10, -7, -4, -2, 1, 4, 5, 8, 11, 13, 14, 14, 11, 11, 11, 10,
+ 10, 9, 6, 5, 3, 1, -2, -5, -10, -14, -16, -17, -18, -19, -20, -19,
+ -17, -14, -10, -5, -1, 1, 3, 5, 6, 6, 6, 6, 6, 6, 6, 6,
+ 8, 7, 6, 4, 2, 0, -1, 0, 0, 1, 2, 1, 1, 2, 1, -2,
+ -5, -8, -9, -10, -11, -12, -12, -10, -7, -4, -1, 2, 8, 11, 13, 15,
+ 15, 13, 12, 11, 10, 9, 8, 6, 5, 4, 4, 3, 0, -3, -6, -10,
+ -14, -18, -21, -22, -21, -18, -16, -13, -10, -6, -3, 0, 3, 5, 5, 5,
+ 6, 7, 8, 8, 8, 7, 8, 7, 6, 5, 4, 1, 0, -2, -4, -4,
+ -5, -4, -4, -3, -2, -1, -2, -3, -4, -7, -8, -9, -9, -9, -8, -5,
+ -2, 2, 4, 8, 11, 14, 15, 15, 14, 12, 10, 7, 5, 4, 4, 2,
+ 1, 1, 2, -1, -3, -7, -10, -15, -18, -18, -18, -18, -17, -15, -11, -7,
+ -3, 1, 3, 4, 5, 6, 7, 7, 8, 8, 9, 10, 10, 9, 6, 4,
+ 2, 0, -3, -4, -6, -7, -7, -6, -5, -3, -2, -2, -2, -2, -3, -4,
+ -5, -6, -6, -6, -6, -5, -4, -1, 4, 7, 9, 11, 12, 12, 11, 10,
+ 9, 8, 7, 5, 3, 3, 2, 1, 0, -1, -4, -7, -8, -10, -13, -14,
+ -15, -15, -15, -14, -11, -9, -6, -3, 0, 2, 4, 5, 6, 7, 8, 9,
+ 10, 10, 9, 8, 6, 5, 3, 1, -3, -6, -8, -8, -7, -7, -7, -6,
+ -4, -2, 0, -1, -2, -3, -3, -3, -3, -4, -3, -3, -1, 1, 3, 4,
+ 6, 7, 8, 9, 10, 10, 9, 7, 6, 6, 4, 3, 2, 1, -1, -2,
+ -4, -6, -9, -11, -12, -12, -12, -11, -11, -10, -9, -8, -7, -5, -4, -1,
+ 1, 3, 5, 7, 9, 10, 11, 10, 9, 8, 7, 6, 2, -1, -3, -4,
+ -6, -7, -7, -7, -7, -6, -5, -5, -4, -3, -3, -4, -4, -4, -3, -2,
+ 0, 0, 1, 1, 2, 4, 6, 6, 7, 7, 8, 7, 7, 7, 7, 7,
+ 6, 5, 2, 0, -2, -4, -5, -7, -8, -8, -8, -9, -10, -10, -9, -8,
+ -7, -7, -7, -5, -3, -2, 0, 1, 2, 4, 6, 9, 10, 11, 12, 10,
+ 8, 6, 3, 1, -2, -4, -6, -7, -7, -7, -7, -8, -7, -7, -6, -6,
+ -5, -4, -3, -3, -2, -1, 1, 2, 2, 3, 4, 5, 5, 5, 6, 6,
+ 6, 5, 5, 6, 6, 6, 4, 3, 2, 1, -1, -3, -4, -6, -8, -9,
+ -9, -8, -8, -6, -5, -5, -5, -6, -6, -6, -5, -4, -2, 0, 2, 4,
+ 6, 7, 8, 9, 9, 9, 9, 6, 4, 1, -1, -3, -5, -6, -7, -7,
+ -7, -6, -6, -6, -6, -6, -5, -4, -3, -3, -2, -1, 1, 3, 4, 5,
+ 5, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 1,
+ -1, -3, -4, -5, -6, -7, -7, -7, -7, -7, -6, -5, -4, -4, -3, -3,
+ -3, -3, -2, -1, 0, 1, 3, 5, 7, 8, 8, 8, 7, 6, 4, 2,
+ 0, -2, -3, -4, -5, -6, -7, -7, -7, -7, -6, -6, -5, -5, -5, -3,
+ -2, 0, 1, 2, 3, 4, 5, 6, 6, 6, 5, 5, 4, 3, 3, 3,
+ 3, 3, 3, 2, 1, 1, -1, -2, -3, -4, -5, -6, -6, -7, -6, -5,
+ -4, -3, -3, -3, -3, -3, -2, -1, -1, 0, 1, 1, 1, 2, 3, 5,
+ 6, 6, 6, 5, 4, 2, 1, 0, -2, -4, -5, -5, -6, -6, -6, -7,
+ -7, -7, -6, -5, -4, -3, -2, -1, 0, 2, 3, 3, 4, 4, 5, 5,
+ 5, 4, 4, 4, 4, 3, 3, 2, 1, 1, 0, 0, -1, -1, -2, -3,
+ -4, -5, -5, -5, -5, -5, -4, -4, -3, -3, -2, -1, -1, -1, -1, 0,
+ 0, 0, 1, 2, 3, 3, 4, 4, 4, 4, 4, 3, 1, 0, 0, -2,
+ -3, -4, -5, -5, -6, -6, -6, -5, -4, -4, -4, -3, -2, -2, -1, 0,
+ 2, 3, 3, 4, 4, 4, 4, 3, 3, 3, 3, 2, 2, 1, 1, 1,
+ 0, -1, -1, -2, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -2, -2,
+ -2, -1, -1, -1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2,
+ 2, 1, 1, 0, 0, -1, -1, -2, -3, -3, -3, -4, -4, -4, -4, -3,
+ -3, -2, -1, -1, -1, 0, 1, 1, 1, 2, 2, 2, 3, 3, 2, 2,
+ 1, 1, 1, 0, 0, 0, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -5, -41, -25, -37, -9, 28, 14, 6, 1,
+ 19, 16, -83, -53, -35, -44, -29, 8, -23, -29, -6, -20, -22, -19, -40, -2,
+ 14, 34, 78, 59, 73, 93, 73, 83, 124, 94, 87, 61, 98, 80, 29, 27,
+ 6, 8, -9, -8, -26, -33, -35, -32, -25, -32, -28, -59, -46, -31, -19, -12,
+ -12, 14, 14, -41, -59, -46, -33, -32, -52, -31, -29, -49, -51, -53, -85, -53,
+ -60, -100, -85, -84, -66, -37, -26, -11, -8, 22, 41, 33, 39, 27, 29, 75,
+ 59, 45, 52, 69, 66, 73, 90, 91, 103, 81, 46, 16, -21, -32, -13, -34,
+ -22, -42, -51, -35, -53, -62, -45, -35, -34, -29, 25, 62, 61, 39, -8, -20,
+ -5, -7, 2, 28, 1, -24, 8, 29, 11, -9, -54, -34, -35, -57, -41, -63,
+ -50, -16, -18, 26, 23, -2, 38, 9, 17, 41, 39, 82, 64, 64, 103, 64,
+ 43, 43, 51, 26, -3, 30, 1, 9, 14, -26, 20, -27, -50, -39, -47, -31,
+ -23, -33, 25, 56, 51, 20, -19, -60, -41, -27, -10, 3, -36, -30, -22, -46,
+ -5, -12, -7, -4, -54, 3, -25, -10, -1, -42, -75, -27, -84, -60, -88, -107,
+ -73, -29, -67, -53, 9, -10, 17, -29, -33, 55, 12, 7, 121, 70, 42, 123,
+ 96, 127, 74, 28, 51, 21, 60, 23, -10, 25, 103, 113, 65, 45, 15, -1,
+ 10, 2, -26, 1, -16, 19, 27, -8, -8, -24, -20, -17, -35, -86, -87, -32,
+ -51, -26, -60, -60, -50, -15, -31, -30, -50, -55, -19, 22, 14, 30, 49, 42,
+ 15, -11, -57, -15, -29, -65, -37, -56, -29, 15, 70, 69, 36, 24, 19, 21,
+ 19, 4, 60, 55, 18, -17, 0, -2, -21, 51, 49, -6, 22, 14, -24, -63,
+ -5, 4, -53, -33, -1, -37, -34, 40, 30, 12, -6, -1, 12, 12, 23, 20,
+ 43, 34, 11, -26, -40, 25, 56, -1, -41, -50, -37, -10, 20, -58, -65, -43,
+ -26, 42, 57, 77, 57, 26, -4, -10, -57, -45, -23, -49, -1, -59, -41, -26,
+ -27, 24, 52, -3, -12, 19, -44, -31, 33, 11, -14, 43, 31, 7, 58, 84,
+ 45, 35, 18, -5, 6, -21, -6, -20, -7, 41, 53, 29, 25, 55, 68, 37,
+ -29, -17, -41, -67, -76, -90, -112, -104, -60, -21, 25, 16, -23, -9, 30, 47,
+ 17, 3, 19, 4, -2, 30, 24, 1, 26, 33, 34, 10, 14, 1, -5, 16,
+ -2, -60, -32, -51, -48, -38, -34, -42, -20, 16, 17, -16, -32, -6, 4, -39,
+ -18, 1, -20, -22, 55, 70, 34, 5, -1, 13, 2, 1, 28, 20, -31, -2,
+ 51, 26, 24, 19, 11, -1, 2, 30, 13, 2, 70, 36, 15, 24, 5, 9,
+ 14, 48, 43, 8, 2, -10, 18, 33, 22, -27, -19, -17, -22, 11, 19, -5,
+ 0, -55, -60, -49, -63, -72, -45, -80, -55, -18, -8, 32, 52, 22, 0, -40,
+ -42, -30, -68, -51, -9, -67, -52, -10, 7, 35, 12, 36, 64, 23, 13, 64,
+ 39, 32, 73, 3, 6, -10, -6, 16, 18, 53, 51, 21, -20, -15, 13, -3,
+ 2, -39, -30, -7, -3, 6, 10, -4, -25, -7, -10, -10, -18, -31, -23, -38,
+ -48, -3, -26, -43, -7, 11, 31, 62, 41, -7, -34, -42, -24, 17, 12, 44,
+ 25, 24, 18, 11, 32, 51, 46, 46, 51, 33, 24, 32, 30, 40, 8, -30,
+ -39, -30, -44, -19, -33, -55, -41, -36, -70, -67, -64, -34, -37, -46, 1, 19,
+ 27, 81, 23, 13, 10, -5, -18, -19, -51, -14, -48, -75, 11, 51, 43, 63,
+ 37, 20, 19, 4, -23, 27, 47, 71, 29, 16, 15, -17, -11, 32, 40, 22,
+ 6, 16, -7, 5, 34, 61, 12, -21, -24, -13, -38, -41, -36, -33, 2, 9,
+ -45, -54, -36, 12, -18, -41, -25, -18, 19, 31, -11, -16, -22, -62, -65, -68,
+ -42, -4, -48, -49, 4, 38, 65, 47, 12, -20, -20, -8, 3, 32, 69, 84,
+ 44, 28, 31, 18, 36, 57, 74, 35, 19, 6, 24, 29, 36, 35, 6, -13,
+ -25, -43, -45, -35, -33, -44, -23, -41, -57, -52, -41, -35, -21, -16, -22, -11,
+ 33, 42, 14, 19, 16, 0, -6, -34, -17, -37, -25, -7, 6, 48, 47, 3,
+ -14, -17, -19, -11, -9, -11, 42, 42, 16, 1, 6, 15, 51, 42, 33, 29,
+ 20, -5, -3, 4, 54, 42, 8, -30, -19, -15, -15, -20, -6, -7, -24, -32,
+ -24, -17, -1, -16, -18, -36, -55, -38, -2, 8, 16, 7, -21, -35, -56, -67,
+ -17, -58, -67, -36, 21, 67, 48, 15, 8, 13, -9, -8, -1, 21, 107, 56,
+ 40, 56, 32, 33, 71, 60, 36, 30, 3, 31, 15, 4, 21, 2, -2, -25,
+ -30, -26, -13, -9, -26, -20, -34, -34, -51, -28, 6, -9, -24, -49, -67, -54,
+ -54, -52, -41, -42, -58, -37, 16, 39, 31, 16, 19, 11, -4, -23, -5, 24,
+ 1, 10, 24, 26, 15, 34, 70, 77, 56, 33, 43, 28, 17, 25, 12, 2,
+ 0, -12, -15, -2, 10, -19, -28, -45, -41, -28, -17, -3, -2, -9, -3, -25,
+ -45, -14, 23, 10, -5, -19, -32, -22, -10, -1, -15, -16, -6, 13, 48, 70,
+ 55, 23, 23, 10, -8, -14, 6, 8, -12, -5, 13, 10, -14, 0, 33, 23,
+ 18, 43, 21, 26, 33, 13, -14, -7, -3, -31, -29, -5, -5, -25, -27, -35,
+ -56, -45, -21, -17, -40, -14, 2, -23, -38, -9, 8, -16, -16, -7, -13, -25,
+ -4, -12, -21, -14, 3, 13, 44, 65, 60, 40, 15, 5, -20, -22, -3, 3,
+ 20, 39, 39, 9, 6, 21, 48, 24, 25, 25, 11, 0, 4, -5, -31, -34,
+ -22, -45, -40, -24, -24, -41, -38, -47, -54, -45, -16, -22, -32, -7, 16, -1,
+ -11, 23, 31, -1, -10, -20, -19, -9, 15, -10, -28, -21, 4, 24, 45, 60,
+ 56, 46, 30, 26, 23, 36, 48, 33, 46, 40, 34, 19, 12, 23, 43, 37,
+ 41, 43, 22, 24, 11, -11, -2, -5, 8, -28, -33, -11, -5, -26, -30, -25,
+ -45, -21, -8, -26, -35, -37, -39, -54, -56, -20, -23, -42, -52, -49, -63, -47,
+ -31, -29, -16, -21, -7, 14, 26, 48, 32, 12, -10, -22, -24, -6, 0, 33,
+ 44, 31, 25, 15, 10, 34, 48, 38, 14, 9, 16, 12, -23, -15, -15, -8,
+ -9, -19, -22, -2, -8, -10, -32, -27, 4, 12, -5, 1, -1, 4, -5, -3,
+ -5, 10, 37, 18, -8, -19, -3, 0, -10, -5, -31, -32, -29, -2, 18, 32,
+ 33, 14, -12, -15, 6, 8, 36, 66, 48, 38, 37, 42, 29, 49, 50, 42,
+ 28, 25, 33, 15, 2, 4, 2, 4, 2, -11, -1, 6, 3, 9, -14, -12,
+ -5, -12, -33, -36, -29, -26, -38, -44, -42, -38, -38, -52, -67, -70, -50, -32,
+ -27, -29, -38, -26, -27, 1, 21, 23, 16, -17, -34, -26, -18, -20, 2, 11,
+ 13, 5, 10, 13, 12, 28, 33, 35, 14, 14, 14, -8, -24, -25, -8, -16,
+ -23, -14, 12, 8, 21, 25, 13, 25, 29, 25, 6, 3, 36, 26, 34, 11,
+ 30, 29, 34, 23, 0, 1, 7, 8, 1, -10, -9, -13, 5, 17, 30, 26,
+ 25, 3, -11, -4, -4, 9, 13, 17, 6, 4, 17, -1, -4, 9, 16, 22,
+ 3, -2, -4, -16, -28, -22, -13, -34, -37, -31, -9, -7, -12, -16, -26, -12,
+ -14, -11, -23, -16, -24, -33, -24, -30, -17, -28, -34, -44, -51, -34, -24, -22,
+ -25, -2, 14, 23, 38, 46, 43, 28, 10, -6, -11, 1, 0, 5, 18, 16,
+ -3, 12, 27, 23, 32, 48, 42, 34, 21, 21, 10, -3, -10, -10, -20, -38,
+ -34, -29, -22, -16, -15, -17, -9, 7, 6, 6, -6, 1, 7, 6, 3, 11,
+ 30, 30, 15, 11, 11, 10, 17, 22, 23, 24, 9, 15, 5, -2, 4, 3,
+ -17, -21, -4, -21, -6, 8, -9, -1, 0, 8, -7, -18, -16, -3, -14, -13,
+ -8, -17, -10, -8, -26, -37, -28, -17, -35, -17, -10, 1, -6, 1, 25, 32,
+ 26, 9, -18, -19, 1, -12, -20, 2, 12, 5, -4, 15, 14, 15, 15, 17,
+ 14, 2, 6, 3, -18, -21, -9, -1, -15, -11, -15, -22, -1, 3, -7, 0,
+ 14, 14, -4, -13, 4, 18, 12, 15, 19, 25, 28, 27, 12, 9, 9, -10,
+ -17, -4, -5, -4, -20, -19, 11, 20, 13, 0, -19, -8, 6, -9, 6, 26,
+ 18, 14, 17, 22, 24, 18, 21, 37, 20, 7, 11, -8, -11, -4, -3, -8,
+ -22, -16, -18, -15, -4, -9, -21, -10, 5, -8, -7, -17, -7, -9, -20, -28,
+ -35, -31, -23, -23, -29, -28, -28, -33, -28, -24, -6, 0, -4, 7, 29, 25,
+ 15, -6, -19, 1, -2, -22, 4, 10, 1, 9, 10, 13, 4, 6, 21, 15,
+ 5, 21, 11, -18, -21, -15, -3, -4, -15, -15, -19, 4, 19, 11, 2, 17,
+ 16, 2, 14, 14, 17, 20, 22, 20, 10, 16, 27, 12, 8, 11, 5, -9,
+ -10, -6, -1, -7, -12, -3, 3, 8, 9, -5, -3, 6, -5, -6, 23, 14,
+ 11, 12, 21, 21, 4, 18, 30, 7, 12, 25, 3, -11, -16, -15, -10, -13,
+ -8, -6, -21, 2, -2, -25, -18, -8, -22, -22, -17, -12, -7, -12, -15, -20,
+ -41, -28, -24, -23, -12, -12, -15, -10, -7, 2, 1, 6, 18, 29, 23, 21,
+ 20, 9, -3, -9, -9, -10, -15, -8, -11, -2, 6, 14, 7, 7, 11, 9,
+ 14, 2, 3, 7, 6, 6, -21, -20, -10, -12, -15, -16, -18, -14, -11, -14,
+ 0, 0, -5, 3, 14, 12, 9, 0, -11, 5, 5, 12, 11, -1, 5, 3,
+ 1, 4, -1, -1, 13, 16, 8, 14, 9, -2, -7, -11, -17, -12, -5, -9,
+ -10, -13, -4, 1, 0, 4, 5, 0, 2, 3, 5, 14, 18, 9, -3, 2,
+ 15, 14, 6, 2, 1, -1, -5, -6, 0, 0, 0, 7, 20, 22, 23, 13,
+ 13, 17, 20, 35, 25, 20, 20, 14, 17, 16, 3, 7, 18, 15, 13, 17,
+ 6, -5, -6, -13, -23, -19, -19, -22, -22, -24, -17, -18, -22, -27, -31, -30,
+ -29, -30, -33, -36, -34, -37, -47, -38, -24, -28, -27, -31, -30, -28, -26, -20,
+ -14, -14, -9, 4, 17, 21, 15, 12, 25, 29, 33, 33, 30, 30, 31, 19,
+ 20, 14, 4, 10, 17, 18, 21, 28, 19, 20, 20, 5, -2, -3, -7, -10,
+ -2, 1, 4, 6, 4, 5, 3, 2, -1, -4, -7, -10, -3, -6, -16, -5,
+ -1, -8, -7, -6, -9, -10, -11, -7, -6, -10, -11, 2, 11, 7, 1, 6,
+ 12, 16, 18, 15, 11, 14, 16, 9, 11, 6, 5, 13, 14, 13, 11, 0,
+ -11, -4, -4, -8, -7, -5, -6, -3, -1, 2, -1, -6, -7, -9, -9, -9,
+ -15, -11, -14, -17, -16, -18, -17, -12, -7, -8, -7, -6, -2, -3, -12, -15,
+ -15, -18, -13, -19, -23, -24, -21, -21, -13, -12, -7, -3, -7, -6, -4, 2,
+ 1, 1, 3, 9, 23, 28, 23, 17, 24, 27, 22, 19, 16, 19, 10, 9,
+ 10, 10, 19, 8, 11, 16, 15, 11, 13, 14, 7, 5, -3, -7, -12, -15,
+ -16, -17, -10, -5, 4, -2, -2, -9, -13, -9, -8, -10, -10, -12, -5, 3,
+ 7, 3, 9, 3, 4, -1, -2, 2, -4, -9, -4, 0, 4, 4, -6, -3,
+ 12, 10, 15, 12, 7, 7, 1, -1, 8, 11, 9, 9, 13, 17, 17, 9,
+ 11, 4, 0, -3, -6, -8, -9, -10, -17, -20, -24, -17, -19, -22, -20, -21,
+ -15, -16, -19, -23, -21, -28, -26, -15, -14, -4, -1, -6, -3, -1, 4, 9,
+ 2, 4, 7, 7, 11, 15, 6, 17, 24, 16, 15, 9, 6, 6, 3, 1,
+ 3, 2, -2, 6, 6, 6, 3, -6, -3, -8, -7, -10, -13, -17, -18, -16,
+ -19, -13, -9, -3, 4, 10, 7, 7, 12, 11, 13, 10, 6, 1, 2, 4,
+ 4, 10, 10, 7, 4, 1, 4, -5, -12, -3, 1, 10, 7, 6, 4, 19,
+ 22, 20, 23, 16, 15, 19, 17, 14, 9, 7, 4, 4, 2, 5, 3, 0,
+ 0, -7, -7, -8, -7, -14, -15, -18, -25, -21, -21, -16, -13, -14, -17, -18,
+ -23, -21, -23, -29, -32, -33, -30, -23, -13, -11, -10, -8, -7, -2, 1, -3,
+ -1, 5, 13, 17, 13, 11, 13, 16, 14, 10, 11, 8, 16, 13, 4, 0,
+ 7, 13, 14, 15, 15, 17, 17, 9, 8, 9, 9, 2, 5, 11, 14, 7,
+ 4, 11, 10, 5, 7, 2, -1, -4, -9, -16, -15, -12, -9, -15, -23, -21,
+ -22, -22, -20, -22, -22, -21, -22, -22, -13, -6, 4, 2, -2, 2, 7, 6,
+ 10, 8, 9, 12, 21, 16, 11, 7, 11, 13, 11, 10, 11, 13, 9, 6,
+ 6, 5, 4, -5, 1, 4, 5, -1, -2, 6, 3, 3, -3, -10, -14, -14,
+ -14, -16, -8, -6, -1, -6, -7, -5, -7, -6, -9, -8, -8, -4, -5, -8,
+ -6, 3, 12, 4, -2, 3, 1, 1, -1, -4, -4, 5, 6, 1, -4, -3,
+ 5, 9, 8, 18, 20, 22, 15, 11, 11, 15, 12, 9, 11, 11, 11, 5,
+ 10, 12, 5, 3, -2, -4, -9, -9, -16, -17, -14, -12, -14, -20, -15, -16,
+ -17, -17, -19, -20, -19, -15, -17, -15, -13, -2, -3, -13, -8, 0, 4, 7,
+ 6, 4, 11, 13, 14, 11, 5, 6, 3, -1, -2, 2, 3, -1, -2, -6,
+ -4, -1, -3, 0, 3, 1, -2, -5, -5, -3, -6, -9, -7, -15, -13, -10,
+ -8, -4, 1, 9, 7, 2, 8, 8, 9, 12, 14, 7, 12, 12, 12, 8,
+ 14, 19, 11, 7, 10, 13, 10, 2, -2, -6, -1, 2, 6, 3, 1, 4,
+ 2, 2, 5, 8, 8, 7, 7, 2, 0, -3, -6, -3, -1, -6, -12, -9,
+ -6, -7, -9, -10, -14, -16, -12, -12, -11, -13, -16, -16, -20, -18, -14, -10,
+ -8, -9, -13, -9, -8, -9, -7, -9, -8, -3, -4, -3, -6, 0, 2, 3,
+ -3, 2, 5, 1, 6, 5, 5, 10, 11, 17, 15, 20, 25, 20, 15, 17,
+ 13, 12, 11, 7, 4, -1, -2, 6, 7, 7, 9, 10, 7, 9, 7, 5,
+ 5, 1, -6, -2, -5, -6, -3, -3, -1, -3, -5, -3, -6, -8, -7, -8,
+ -11, -12, -16, -19, -19, -14, -14, -17, -17, -11, -12, -15, -6, -8, -12, -12,
+ -9, -7, -6, 2, 9, 6, 8, 11, 13, 15, 14, 11, 7, 3, 3, 4,
+ 7, 9, 10, 6, 6, 5, 7, 11, 11, 4, 1, 1, -3, -5, -1, -1,
+ -1, -5, -2, -1, -1, 1, 1, -3, -7, -7, -9, -12, -11, -3, -3, -7,
+ -6, -6, -5, -5, 0, -3, -4, -2, 2, -1, 0, 6, 7, 7, 4, 3,
+ 5, -1, 0, -1, -7, -9, -8, -11, -5, 0, -1, 0, 2, 2, 5, 10,
+ 10, 7, 7, 7, 8, 8, 9, 11, 9, 8, 9, 6, 4, 2, 0, -3,
+ -5, -8, -8, -12, -8, -1, -4, -4, -5, -7, -9, -6, -5, -6, -8, -6,
+ -3, -7, 0, 5, 6, 3, 1, 6, 6, 4, 3, 1, -2, -4, -6, -4,
+ 3, 7, 3, 0, -1, -3, -2, -1, -2, -5, -8, -9, -7, -9, -8, -6,
+ -9, -7, -9, -7, -6, -7, -6, -7, -7, -7, -7, -8, -2, 1, 2, 4,
+ 3, 5, 6, 10, 11, 9, 10, 12, 9, 9, 11, 9, 10, 8, 7, 7,
+ 6, 7, 5, 4, 5, 4, -1, -4, -3, -5, -1, -2, -4, -4, -4, -4,
+ -2, -2, -3, -4, -2, -1, 0, 1, 8, 8, 4, 4, 4, 2, -2, -3,
+ -5, -6, -9, -10, -8, -5, 2, 1, -2, -2, -2, -2, -2, -5, -5, -7,
+ -7, -3, -4, -6, -4, -3, -5, -7, -5, -4, -7, -9, -6, -6, -9, -7,
+ -6, -2, 3, 3, 4, 5, 3, 4, 5, 2, 0, 2, 3, 2, 5, 7,
+ 10, 9, 7, 7, 6, 4, 1, -2, -5, -6, -10, -10, -8, 2, 8, 7,
+ 6, 7, 5, 5, 7, 6, 3, 4, 3, 4, 1, 3, 2, 4, 2, 1,
+ 1, -1, -3, -3, -4, -6, -9, -9, -9, -7, -6, -5, -5, -4, -5, -2,
+ -1, -2, -3, -1, -1, -3, -2, 2, 2, 3, 4, 4, 2, 0, -1, -3,
+ -4, -4, -5, -7, -2, 2, 2, -1, -3, -1, -4, -3, -2, -4, -4, -2,
+ -1, -2, -4, -2, -2, -1, -2, -2, -2, -3, -2, 0, 2, 0, -2, -2,
+ 0, 2, 3, 5, 4, 4, 4, 6, 3, 1, 0, 0, 0, 0, 5, 5,
+ 4, 6, 4, 2, 0, -2, -3, -6, -9, -8, -10, -10, -2, 3, 4, 4,
+ 4, 5, 4, 4, 5, 4, 4, 4, 4, 2, 3, 2, 2, 2, 1, 1,
+ 0, -2, -3, -3, -4, -6, -8, -7, -4, -6, -3, -3, -3, -2, 1, 0,
+ -1, -2, -2, -1, -1, 0, 1, 0, 0, 1, 0, 0, 0, -1, -2, -3,
+ -3, -4, -5, -4, -3, -3, -3, -3, -3, -3, -2, -1, 0, -1, 0, 0,
+ 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 2, 3,
+ 3, 2, 2, 0, -1, -1, -2, -3, -3, -4, -5, -4, 0, 3, 3, 3,
+ 3, 2, 3, 4, 6, 4, 4, 3, 2, 1, 2, 1, 0, 0, -1, -2,
+ -3, -3, -2, -2, -3, -3, -3, -3, -3, -2, -2, -2, -2, -2, -2, -2,
+ -2, -3, -2, -3, -2, -2, 0, 0, 0, 0, 0, -1, -1, -2, -2, -3,
+ -2, -4, -4, -3, 0, -1, 0, 0, 0, 0, 0, 1, 2, 1, 1, 1,
+ 0, 0, 0, -1, 0, -1, -1, -1, -1, -1, 0, 0, -1, 0, 0, 0,
+ 1, 1, 1, 1, 1, 1, 0, 0, 0, -1, 0, -1, 0, 0, 0, 0,
+ 0, 0, -1, -1, -2, -2, -2, -2, -2, -3, -3, -1, 0, 0, 0, 0,
+ 0, 0, 0, 1, 1, 1, 0, 0, 0, -8, -33, -24, -25, -25, -26, -27,
+ -32, -28, -36, -31, -36, -22, -34, 11, -74, -14, 94, 41, 28, 33, 30, 40,
+ 34, 23, 41, 40, 60, 56, 59, 60, 44, 39, 54, 45, 52, 17, 44, 62,
+ 34, 33, 19, 18, 43, 35, 22, 36, -15, -10, 32, -7, -12, -6, -8, -50,
+ -47, -44, -4, -25, -48, -76, -58, -75, -96, -85, -118, -114, -63, -106, -103, -83,
+ -110, -99, -84, -76, -58, -63, -61, -51, -53, -36, -32, -41, -27, -11, 11, 8,
+ 27, 19, 30, 35, 28, 57, 53, 38, 71, 51, 68, 110, 78, 89, 109, 97,
+ 82, 94, 115, 114, 79, 70, 79, 94, 85, 76, 84, 95, 83, 82, 55, 54,
+ 54, 41, 41, 27, 20, 6, -11, -21, -16, -14, -33, -33, -52, -54, -59, -62,
+ -71, -79, -88, -88, -78, -78, -72, -71, -94, -99, -93, -90, -78, -87, -105, -103,
+ -79, -62, -71, -78, -63, -61, -66, -49, -23, -10, -11, -24, -20, -4, -22, 9,
+ 8, 27, 43, 34, 38, 51, 83, 65, 58, 74, 75, 70, 73, 71, 65, 100,
+ 89, 94, 65, 84, 49, 49, 61, 54, 43, 51, 58, 53, 35, 40, 36, 38,
+ 34, 23, 14, -12, -10, -1, -1, -11, -12, -19, -33, -66, -52, -42, -37, -55,
+ -42, -28, -32, -29, -35, -41, -28, -25, -46, -85, -64, -62, -55, -49, -68, -55,
+ -53, -52, -47, -43, -26, -32, -41, -34, -35, -40, -26, -8, -1, -6, -11, 5,
+ -2, 8, 3, 8, 6, 4, 20, 29, 43, 24, 33, 20, 30, 24, 39, 38,
+ 40, 29, 37, 36, 39, 61, 58, 41, 51, 59, 51, 55, 58, 48, 32, 45,
+ 40, 27, 30, 41, 44, 26, 19, 23, -3, 7, 0, -3, 2, 3, -6, -5,
+ -14, -6, -10, -27, -45, -47, -41, -38, -50, -51, -46, -43, -45, -65, -65, -80,
+ -95, -82, -74, -66, -69, -67, -33, -31, -53, -48, -51, -43, -18, -24, -24, -33,
+ -26, -10, 0, -17, -6, 17, 31, 2, 23, 45, 46, 12, 75, 38, 63, 69,
+ 31, 38, 80, 57, 48, 59, 81, 74, 32, 52, 72, 24, 60, 44, 55, 40,
+ 28, 48, 33, 24, 10, -2, 21, 34, 13, 18, 7, -1, -12, -20, -18, -30,
+ -9, -7, -30, -27, -26, -38, -20, -54, -55, -64, -53, -36, -62, -37, -71, -47,
+ -42, -71, -45, -55, -50, -54, -56, -36, -37, -54, -36, -12, -38, -33, -26, -7,
+ -22, -44, -10, 2, 3, 15, 8, 18, 6, 12, 8, 15, 28, 22, 50, 35,
+ 55, 42, 36, 49, 52, 64, 48, 60, 49, 60, 62, 40, 47, 68, 52, 59,
+ 61, 44, 53, 44, 35, 31, 31, 47, 22, 6, 4, -7, 5, -4, -21, -13,
+ -9, -10, -27, -46, -32, -44, -46, -62, -44, -51, -67, -53, -59, -63, -74, -67,
+ -61, -61, -65, -47, -58, -57, -45, -41, -46, -41, -38, -22, -25, -34, -16, -10,
+ -18, 0, 1, -6, 5, 17, 15, 10, 23, 38, 28, 28, 54, 40, 19, 55,
+ 55, 41, 46, 53, 40, 49, 51, 52, 41, 56, 39, 53, 38, 33, 35, 18,
+ 15, 38, 30, 23, 27, 13, 11, 7, 16, -1, 0, 0, 13, -6, -10, -15,
+ -10, -10, -24, -20, -16, -38, -36, -21, -40, -32, -42, -38, -52, -53, -41, -48,
+ -58, -50, -47, -37, -41, -45, -29, -41, -6, -48, -24, -25, -15, -9, -10, -10,
+ -10, -1, -17, 4, 3, 10, -4, 9, 15, 25, 24, 19, 23, 34, 28, 33,
+ 37, 38, 26, 36, 47, 35, 46, 45, 28, 35, 32, 32, 24, 21, 26, 23,
+ 19, 37, 20, 9, 29, -2, 26, 24, 8, 4, 14, 21, 11, -9, -8, 4,
+ -9, -31, -11, -15, -21, -24, -29, -22, -33, -26, -29, -48, -32, -44, -28, -22,
+ -35, -30, -38, -31, -46, -44, -36, -27, -23, -29, -24, -11, -20, -28, -13, -34,
+ -19, -1, 7, -3, -1, 6, -3, 5, 4, 8, 17, 26, 19, 33, 27, 16,
+ 35, 14, 36, 39, 22, 32, 31, 19, 32, 23, 29, 21, 30, 29, 23, 31,
+ 13, 24, 17, 11, 26, 18, 12, 5, 23, 16, 9, 15, -10, 3, 18, -15,
+ -4, -4, 6, -14, -15, -5, -34, -11, -20, -18, -8, -17, -29, -30, -29, -19,
+ -34, -35, -20, -36, -20, -16, -21, -38, -16, -30, -24, -25, -19, -18, -15, -7,
+ -5, -5, -10, -23, -3, -14, 0, -1, -12, -9, 7, 7, 2, 12, 5, 7,
+ 19, 10, 21, 21, 27, 30, 22, 18, 34, 22, 11, 26, 24, 20, 21, 25,
+ 29, 22, 27, 27, 20, 10, 20, 16, 22, 15, 16, 16, 5, 19, 10, 3,
+ 22, -5, -5, -7, -16, -4, -11, -22, -7, -16, -11, -23, -16, -30, -24, -28,
+ -20, -29, -24, -32, -22, -22, -30, -17, -23, -28, -22, -20, -21, -21, -17, -30,
+ -15, -14, -20, -9, 3, 6, 5, -20, 10, 13, -2, 11, 8, -1, 7, 16,
+ 5, 22, 23, 13, 22, 13, 22, 25, 15, 16, 11, 15, 13, 7, 12, 19,
+ 18, 20, 12, 23, 11, 6, 10, 1, 11, 19, 5, 20, 0, 11, 11, 1,
+ 14, 15, -3, -1, -7, 6, -6, -9, -9, 4, -3, -10, -20, -14, -9, -14,
+ -7, -10, -5, -4, -29, -14, -12, -26, -21, -27, -18, -10, -19, -27, -18, -8,
+ -25, -8, -13, -15, -14, -15, 5, -13, -7, -11, -4, -12, 0, 15, 5, 4,
+ 1, 11, 6, 4, 3, 6, 21, 19, 8, 15, 13, 6, 14, 16, 18, 17,
+ 20, 15, 11, 15, 24, 13, 11, 19, 7, 17, 14, 6, 17, 7, 7, 6,
+ 6, 5, 11, 0, 6, 0, -6, 5, 1, -11, -6, -1, -8, -9, -15, -7,
+ -4, -16, -17, -13, -13, -17, -14, -12, -12, -28, -13, -19, -25, -31, -24, -17,
+ -17, -16, -7, -15, -12, -8, -15, -8, -16, -10, -4, -1, -2, 3, 5, 2,
+ -2, 5, 3, 6, 10, 8, 11, 14, 14, 13, 15, 22, 16, 14, 18, 13,
+ 17, 19, 16, 10, 17, 8, 17, 14, 3, 14, 7, 10, 10, 7, 6, 6,
+ -1, 6, 1, 0, 12, -6, 6, 12, -4, -5, -4, -2, -2, -1, -2, -8,
+ -11, -9, -11, -11, -18, -6, -5, -16, -9, -14, -10, -13, -10, -11, -15, -14,
+ -14, -12, -17, -17, -17, -7, -11, -14, -15, -12, -6, -15, -5, -13, -9, 0,
+ 12, -2, -2, 6, 2, -7, 4, 10, 2, 9, 8, 7, 4, 5, 11, 15,
+ 11, 10, 18, 9, 13, 13, 13, 21, 11, 18, 19, 13, 14, 16, 6, 8,
+ 1, 19, 11, 10, 11, 1, 3, -1, -1, 5, -11, 5, -1, -5, -3, -13,
+ -10, -6, -7, -5, -15, -10, -11, -18, -8, -16, -20, -18, -9, -12, -17, -21,
+ -21, -13, -21, -8, -10, -10, -5, -16, -7, 2, -6, -6, -9, -7, -2, -9,
+ -5, 6, -7, 1, 3, -1, 2, 1, 2, 9, 8, 5, 15, 12, 1, 11,
+ 9, 8, 10, 15, 14, 5, 13, 17, 14, 15, 10, 7, 16, 5, 5, 5,
+ 8, 9, 10, 10, 7, 0, 4, 6, 9, -10, -4, 5, 2, -1, 0, -3,
+ -4, -5, -10, -5, -8, -9, -10, -3, -13, -6, -9, -20, -15, -11, -18, -14,
+ -10, -12, -20, -14, -14, -7, -12, -21, -14, -9, -8, -11, -5, -2, -7, -4,
+ 4, -2, -3, -1, 0, -1, 8, 6, 9, 7, 10, 6, 3, 4, 7, 10,
+ 11, 6, 9, 17, 11, 9, 7, -2, 16, 13, 12, 18, 5, 16, 9, 4,
+ 9, 6, 8, 9, 4, 4, 3, -2, -3, 2, -6, -3, 1, -7, -6, -3,
+ -6, -14, -8, -9, -4, -13, -9, -8, -16, -10, -12, -13, -11, -7, -8, -12,
+ -9, -8, -7, -11, -4, -8, -7, -8, -3, -13, -10, -3, 6, -5, -5, 0,
+ -5, -3, 6, -2, -2, 4, -2, 6, 2, -2, 5, 5, -2, 5, 15, 13,
+ 4, 6, 6, 14, 9, 4, 8, 7, 3, 11, 12, 2, 10, 7, 10, 8,
+ 4, 6, 2, 0, 3, 2, 4, 2, -6, -2, 2, -4, 3, -5, -6, -5,
+ -5, -5, -4, -8, -7, -4, -4, -7, -8, -7, -13, -10, -10, -11, -9, -8,
+ -8, -7, -11, -7, -3, -9, -6, -7, -3, -4, -5, 3, -3, -1, -2, -4,
+ 1, 4, 0, 3, 0, 5, 2, 0, 5, 4, 1, 3, 1, 0, 1, 7,
+ 3, 0, 4, 3, 6, 5, 0, 9, 5, 7, 6, 3, 6, 2, 3, 5,
+ -4, 9, 0, 4, 10, 0, 5, 1, -2, 4, -3, -3, -2, 0, 2, -7,
+ 3, -10, -1, -6, -9, -2, -4, -10, -3, -7, -6, -4, -10, -6, -6, -11,
+ -6, 0, -6, -8, -4, -1, -9, -10, 0, -6, -7, -2, -7, 1, -5, -5,
+ -1, 1, -6, 2, 0, -3, -1, 7, -4, 0, 7, 0, 8, 2, 3, 4,
+ 4, 2, 5, -1, 6, 7, 5, 6, 4, 2, 4, 6, 8, 6, 3, 1,
+ 8, 9, 2, -1, 4, 3, 4, 3, -3, 7, 4, 3, -2, 2, -4, -6,
+ -2, -5, -2, -3, 0, -5, -6, -13, -5, -6, -11, -9, -10, -5, -4, -9,
+ -9, -7, -7, -8, -8, -6, -5, -7, -5, -1, -3, -4, -2, -2, 2, -3,
+ 1, 2, -3, 1, 2, 1, 0, 1, 5, 0, 2, 5, 2, 0, 4, 1,
+ 7, 3, 2, 6, 0, 5, 7, 5, 5, 1, 3, 3, 5, 10, 3, 4,
+ 8, 2, 7, 3, -2, 3, 0, -1, -1, 1, 0, 1, -3, -2, -5, -4,
+ -3, -1, -7, -8, -4, -4, -10, -2, -8, -8, -8, -8, -9, -6, -8, -9,
+ -4, -2, -7, -5, -2, -7, -6, -9, -2, 0, -4, 4, -6, -3, -4, -1,
+ 2, 1, 2, 9, 0, 3, 0, 6, 4, 0, 5, 6, 2, 7, 7, 5,
+ 7, 6, 8, 6, 6, 5, 5, 1, 6, 5, -1, 3, 4, -1, 4, 1,
+ 4, 3, -5, 0, 4, 1, 4, -2, -3, -4, 0, -4, -8, -2, -5, -4,
+ -8, -6, -5, -3, -3, -7, -9, -6, -10, -10, -6, -6, -5, -4, -7, -6,
+ -4, -10, -3, -10, 0, -2, -2, -6, -1, 3, -3, -3, 1, 2, 1, 4,
+ 3, 4, 3, 4, 1, 2, 6, 5, 5, 5, 7, 9, 1, 5, 4, 4,
+ 7, 2, 9, 2, 4, 8, 2, 5, 6, 3, -2, -2, -1, -2, -1, 1,
+ -2, -4, 1, -6, -2, -5, -3, -5, -5, -6, -4, -3, -4, -10, -4, -3,
+ -8, -4, 0, -3, -5, -6, -6, -3, -1, -7, -3, 1, -1, -4, -2, 1,
+ -2, 0, -1, -2, 0, 0, 5, -2, 0, 3, 3, 1, 5, 2, 4, 1,
+ 4, 1, 2, 3, 3, 3, 4, 3, 3, 5, 1, 4, 2, 3, 1, 2,
+ 0, 2, 1, -2, -2, -1, 0, -2, -1, -1, -3, -5, -2, 0, -5, -1,
+ 0, -5, -2, -2, -2, -3, -3, -1, -4, -1, -2, -4, -2, -1, -2, -1,
+ 0, -3, -1, -1, 0, 1, -1, -1, 3, -4, -2, -2, 4, -2, -1, -1,
+ -1, 0, 0, -1, -1, -1, -1, 2, 0, -1, 2, -1, 0, -1, 2, 0,
+ 3, 5, -2, 1, 2, 0, 5, 0, -3, 4, -3, 1, 2, 0, 4, -1,
+ -2, 1, 0, 0, 0, -1, 1, -2, 0, 1, 1, 0, -5, 1, -2, -1,
+ 0, -2, -3, -1, -3, 0, -2, -3, -4, 1, -2, -3, -2, -2, -1, -1,
+ -2, -1, -4, -5, 2, -4, 0, 1, -1, 2, -2, -1, 0, 0, 1, -3,
+ 3, 2, 0, -2, 2, 1, 2, -2, 5, 3, -2, -2, -1, 1, 0, 0,
+ 1, 3, 2, 0, 0, -1, -2, 1, 1, 2, 1, 1, -1, 0, -1, -1,
+ -1, -3, 1, 1, 2, -2, -1, 0, 0, -2, 0, -1, -1, 2, -2, 1,
+ -1, 0, 0, -1, -1, -2, 0, -1, 1, -1, -1, 2, -2, 0, -1, -1,
+ 2, -1, 0, -3, -1, 0, 0, 0, -3, -3, -2, 0, 0, -1, -1, 0,
+ -4, 2, 0, -2, 0, 1, -3, -1, 2, 1, 0, -1, 0, 0, -1, 0,
+ 2, -1, -1, 0, 0, -2, 1, 1, 0, 1, 0, 2, -3, -2, 2, -1,
+ -1, 2, -2, 1, 1, 0, 0, 1, 1, 0, -4, 3, -1, 2, 0, 2,
+ -1, -2, 0, 1, 1, -1, -1, -1, -1, -1, -2, -2, -2, -2, -2, -1,
+ -1, 1, 0, -5, 0, -1, -1, -1, 1, -1, 1, -1, 1, 0, -2, 0,
+ -2, 1, -1, 1, 0, -1, -2, 0, -1, 0, 0, 2, 0, 0, 0, 1,
+ 0, 0, 2, 0, -1, 0, 0, 0, 2, -1, 1, 1, -1, -1, 0, 0,
+ 1, 1, 0, 0, 0, 0, -1, 0, 0, -2, 0, 0, -1, 1, -2, -1,
+ -1, -1, -2, -1, -2, 1, -1, 0, -2, -2, 1, -2, -1, 1, 0, 1,
+ 1, -1, -1, 0, -1, 0, 0, 0, -2, 0, -1, 0, 0, -1, -2, -2,
+ -2, 1, -1, 0, 0, -1, 1, 1, -2, -1, -2, -1, 1, -1, -1, -2,
+ -2, 0, 0, 1, -1, -1, -1, -1, -2, 2, 0, 0, 1, 1, 1, -2,
+ 0, -1, 0, -1, -1, 2, 0, -1, -1, -1, 1, -1, 2, 0, -1, 1,
+ 1, 0, 1, 0, -1, -1, -1, -1, -3, 0, 0, -1, 1, 0, 0, -2,
+ -2, -2, 0, -1, 0, 0, -1, 0, -1, -2, -1, -2, 0, -2, 0, 0,
+ -1, -2, 1, -2, 0, -1, -2, 2, 0, -1, 2, -1, 1, -1, 0, 0,
+ -1, 0, 0, 0, -1, 0, 1, 0, 0, 1, 0, -1, -1, 0, -2, -1,
+ 0, 0, 1, 0, 0, 0, 0, -1, -1, 1, -1, -2, -1, 0, 0, -2,
+ 0, -1, 0, 0, 0, 1, 0, 0, -1, 1, 0, -1, 0, 1, -1, 0,
+ -1, -2, 0, -1, 0, -1, -1, -1, 0, -1, 0, 0, 0, -1, -1, 0,
+ -2, 0, 0, 0, -2, -2, 0, -2, -1, -1, -1, -2, 0, -1, -1, -1,
+ 0, 0, -1, -1, 0, 1, -1, -1, 0, -1, 0, 0, 1, 1, 0, 0,
+ -1, 0, 0, 0, 0, 0, 1, -1, 0, 0, 0, 1, 0, 0, -1, 0,
+ 0, -1, -1, 0, -1, -1, 0, -1, 0, -1, -1, 0, -2, -1, 0, -1,
+ -1, -1, -1, 0, -1, 0, 0, 0, 0, -1, 1, 0, 0, 0, -1, -1,
+ 0, -1, -1, 0, 0, 0, 0, 0, -1, -1, 0, -1, -1, 0, 0, -1,
+ 0, -2, 0, -1, -1, -1, 0, -1, -1, 0, -1, 0, 0, 0, -2, -1,
+ 0, -1, -1, 0, 1, -1, -1, 0, 0, 0, 0, -1, -1, -1, -1, 0,
+ 1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, -1, 0, 0,
+ -1, 0, 0, -1, -1, -1, 0, 0, -1, -1, 0, -1, 0, 0, 0, -1,
+ 0, -1, -1, 0, -2, -1, -1, -1, 0, -1, 0, -1, -1, 0, 0, -1,
+ 0, -1, 0, -1, -1, -1, 0, -1, 0, -1, 0, 0, -1, 0, -1, 0,
+ 0, -1, -1, 0, 0, 0, -1, 0, -1, 0, 1, -1, 0, 0, 0, 0,
+ 0, -1, 0, 0, 0, -1, 0, 0, -1, -1, 0, 0, 0, -1, 0, 1,
+ -1, -1, -1, 0, 0, -1, -1, -1, -1, 0, -1, 0, 0, 0, 0, 0,
+ 0, -1, -1, 0, -1, -1, 0, -1, 0, -1, -1, -1, -1, 0, -1, -1,
+ -1, -1, -1, -1, -1, 0, -1, 0, -1, 0, 0, -1, -1, 0, -1, 0,
+ -1, 0, 0, -1, 0, -1, -1, -1, 0, -1, 0, 0, 0, 0, 0, -1,
+ -1, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, -1, 0, 0, 0,
+ 0, -1, 0, -1, 0, 0, 0, -1, -1, 0, 0, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, 0, 0, -1, -1, -1, 0, 0, 0, -1, 0, -1, -1,
+ 0, -1, 0, 0, -1, -1, -1, -1, -1, 0, 0, -1, 0, 0, -1, 0,
+ 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, -1, 0, 0, 0, 0,
+ -1, 0, 0, 0, 0, -1, 0, 0, -1, 0, -1, 0, 0, -1, -1, -1,
+ 0, -1, -1, 0, -1, -1, 0, 0, -1, -1, -1, -1, 0, -1, -1, 0,
+ 0, -1, 0, 0, 0, -1, -1, 0, -1, -1, -1, 0, 0, -1, -1, -1,
+ -1, -1, 0, -1, 0, 0, -1, -1, 0, 0, -1, 0, 0, -1, -1, -1,
+ 0, -1, 0, 0, -1, -1, 0, 0, -1, -1, 0, 0, 0, -1, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1,
+ 0, 0, 0, -1, 0, -1, 0, -1, -1, -1, -1, -1, -1, 0, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, 0, -4, 11, 6, 16, 10, -16, -48,
+ -44, 2, 67, 42, -17, -51, 15, 71, 12, -22, -14, -44, -35, 11, 17, -18,
+ 2, -15, 19, 12, -1, -44, -15, 50, 45, -25, -61, 17, 10, -10, 31, 18,
+ -72, -27, 57, 26, -13, -17, -2, 6, -1, -23, -54, 17, 39, 8, 30, 28,
+ -6, -71, -5, 33, 27, -5, 17, 10, -23, -6, 12, -26, -6, -7, -9, -14,
+ 11, 37, 41, 8, -33, -14, 8, -31, -38, 13, 9, 15, 35, 33, 11, 17,
+ -41, -48, -33, 29, 25, 16, -9, -9, -17, -19, -29, 43, 64, -2, -55, -42,
+ -1, -21, -4, 29, 34, -25, -67, -29, 1, 51, 49, 25, -6, -15, -48, -76,
+ -3, 60, 78, 33, 19, 13, -38, -35, -35, -2, 62, 19, -4, -12, -4, -4,
+ -32, -30, 8, 68, -43, -66, -28, 55, 51, 20, -28, -29, -19, 20, -2, 8,
+ 21, -15, -43, 24, 22, -7, -2, 35, 15, -2, -24, -12, 3, 31, 13, -15,
+ -20, -17, -17, 26, -26, 24, -3, 7, 21, 26, -3, -17, -26, -50, -26, 33,
+ 58, 49, -22, -67, -17, 24, 7, -57, 5, 42, -11, -3, 32, -3, 7, 13,
+ -11, -9, 27, 17, 1, -5, -9, -18, -19, -3, -23, -5, 7, -8, 9, 13,
+ 12, -5, 7, -37, 22, 26, 21, 24, -20, -35, 23, 24, -35, -15, 46, -38,
+ -48, -14, -4, 0, -22, 3, 43, 38, -1, -14, -8, -5, -14, 1, 21, 23,
+ 29, -19, -47, -42, -49, -10, 66, 77, 48, -29, -32, 1, -11, 8, 17, -17,
+ 3, 43, 33, -22, -19, -41, 29, 22, -42, 9, 63, 28, -23, -59, -65, 7,
+ 53, -22, -10, -27, -30, 36, 48, -4, -6, -22, -16, 10, 14, -7, 22, 50,
+ -4, -25, -41, -55, -62, 23, 68, -16, -31, 49, 57, 21, -38, 14, 12, -43,
+ -49, -16, 28, 7, -12, -50, -17, 49, 65, 18, 1, -8, 28, 2, -27, -13,
+ 12, -11, -52, 4, 31, -32, -39, 15, 8, -19, 6, 25, -1, -23, 13, 34,
+ 59, 36, -16, -5, -7, -28, -30, 1, -14, -42, 10, 43, 26, -25, -37, -61,
+ 1, 63, 62, 1, -36, -24, 38, -7, -26, 27, 10, 4, 2, -19, -22, -27,
+ -24, 0, 33, -8, -57, -12, 62, 77, 51, -10, -42, -27, -28, -31, -3, 5,
+ 21, 10, 15, -27, -18, -18, -10, 3, 17, 19, 18, -16, -20, 25, -3, -19,
+ -5, 32, 17, -3, -32, -8, 2, -11, -24, -17, -11, 3, 42, 15, -12, -2,
+ 26, 9, -4, -30, -3, 16, 7, 13, 34, 40, 114, 11, -104, -71, 7, -14,
+ -34, -26, 35, 45, 47, 7, -7, -16, 11, -6, -29, -32, 1, 24, 32, 10,
+ 29, -10, -74, -80, -20, 18, 9, 18, 61, 38, -27, -44, 13, 16, -26, 20,
+ 69, 14, -14, -46, -7, -6, -35, 0, 9, 5, 58, 71, -36, -78, -15, 43,
+ 34, -61, -101, -27, 45, 26, -10, 23, 69, 69, 5, -72, -62, 19, 16, -37,
+ -60, 37, 60, 10, -49, -10, -2, -1, 43, 44, 10, -50, -5, 19, 8, -43,
+ -58, -17, 32, 28, 4, -1, -18, -10, 13, 8, 1, 1, 22, -3, -4, 9,
+ -8, -9, 17, 3, -15, -8, 14, 11, -14, -11, -5, 13, -24, -34, -1, -16,
+ -4, 32, 35, -32, 9, 22, 12, -27, -16, 14, 15, 0, -2, -12, -31, -24,
+ 14, 48, 10, -14, -7, -22, 4, -8, -14, 19, 21, -21, -25, -12, 19, 24,
+ 19, 27, -3, -15, -16, 10, 21, -14, 3, 8, 3, -11, -33, -16, 7, 5,
+ -8, 2, -3, 12, 5, -34, -19, -6, 26, 19, 0, -4, -12, 5, 12, 20,
+ 16, 19, 18, -13, -42, -26, -1, 0, -18, -16, 10, 27, 23, -5, -7, 9,
+ -8, 7, 22, 10, -28, -51, -26, 13, 44, 17, 16, 25, 14, -32, -45, -36,
+ -40, -3, 22, 41, 34, -12, -35, -31, 18, 3, 31, 28, 4, -21, 2, -14,
+ -24, -23, 19, -6, -7, -10, -1, -13, -13, 21, 52, 28, 7, 1, -25, -36,
+ 2, 34, 10, -37, -31, -13, 19, 11, -4, -20, 15, -5, -18, 40, -13, 15,
+ -36, 14, 18, 17, -21, 6, -39, 21, 7, -26, 8, -33, 24, 30, 32, -11,
+ -26, -47, -39, 62, 10, 11, 5, -17, -21, 10, 0, 18, 15, -22, 7, 13,
+ 14, -8, -9, 30, 33, -34, -41, -32, 37, 24, -19, -15, 1, 2, 10, 10,
+ -27, -46, -14, -9, 9, 47, 1, -22, -18, 5, 37, 29, -3, -19, -19, -18,
+ 8, 17, 1, -11, -6, -20, 27, 37, -2, -28, -34, -3, 22, 54, 34, -31,
+ -43, -28, -30, -33, 26, 49, 45, 43, -15, -58, -13, -2, -27, -7, 41, 11,
+ 19, -50, -74, -28, 31, 75, 39, -45, -7, 99, 44, -83, -47, 45, -1, -30,
+ 23, 29, -55, -30, 31, 28, -19, 2, -44, -46, -49, 30, 22, 58, 31, -50,
+ -20, 9, -38, -53, 49, 37, -9, 13, -25, -18, 18, -27, -7, 17, 3, 24,
+ 57, 26, -51, -52, -54, -43, 53, 85, 31, -36, -44, 7, 13, 19, -23, -33,
+ 36, 47, -38, -11, 37, -19, -6, 18, 17, 2, 31, 54, -29, -72, -80, -1,
+ 27, 52, 10, -29, -40, -48, -72, 24, 108, 66, -44, -76, -32, -24, 21, 69,
+ 54, 24, -2, -8, -28, -44, -50, 34, 95, 45, -40, -72, -32, 6, 28, -1,
+ 18, -7, 27, 1, -14, 21, -8, -51, -62, -24, 64, 56, 12, 19, -36, -22,
+ 10, 20, -10, -1, -5, -51, 36, 72, -42, -51, 70, 45, -48, -27, 54, 19,
+ -46, 8, 0, -46, 10, 37, 35, -21, -32, -22, -44, -82, -33, 59, 105, 48,
+ -32, -36, -31, 18, 60, -12, -49, 10, 89, 28, 12, 8, -45, -21, -6, -16,
+ -32, -17, -18, 3, 29, -3, 0, -20, -51, -31, 24, 52, 1, -17, -20, 1,
+ 35, 15, 5, 35, 27, 18, -19, 8, -71, -74, -8, 88, 57, -45, -37, 17,
+ 51, -1, -13, -4, 3, -13, -24, -7, 30, -7, -25, -1, 16, -8, -43, -70,
+ 11, 85, 77, 12, -62, -57, 35, 53, -33, -96, 8, 82, 21, -38, 25, 39,
+ -1, -27, -14, 18, -16, -45, -24, 42, 7, -9, 22, 32, -39, -5, -8, -49,
+ -17, 60, 88, 21, -93, -20, 82, 31, -26, -63, -17, 52, -28, -25, 13, -2,
+ -32, -46, 55, 56, -37, 6, -57, -33, 65, 63, 5, -25, -31, 69, 86, -32,
+ -34, -56, -23, -47, 14, 44, -23, 19, 6, 60, -27, -69, -37, 20, -14, -5,
+ 50, 44, 15, 13, -23, -60, -46, 23, 40, -5, -25, 6, 46, -4, -10, -27,
+ -12, 28, 45, 10, -13, -33, -19, -39, 42, 32, -23, -25, 24, -17, 13, 25,
+ 13, -32, 13, 48, 4, -93, -5, 40, -7, 37, -39, -37, 41, 1, -13, -33,
+ 43, -53, 106, 8, -57, -93, 55, 40, 56, -24, -4, -19, 7, -23, -65, -18,
+ 34, -30, 7, 66, 92, 3, -43, -37, -23, 12, -7, -17, 14, -15, -9, -18,
+ 18, 51, -1, -57, -17, 23, 19, 15, -40, -1, 0, -8, 39, -13, -43, 72,
+ 57, -1, -54, -17, 32, -19, 11, 0, 36, 25, -23, -86, 21, -3, 14, -17,
+ 76, 37, 23, 2, -23, -54, -42, -80, 61, 60, 63, -12, -57, -44, 15, 35,
+ 26, 11, -44, -22, 8, 33, -24, -17, 21, 38, -25, -39, 16, 43, -36, -28,
+ 54, 10, -52, -18, -34, -14, 76, 60, 24, -32, -19, 16, -13, -68, -5, 30,
+ -13, -23, -14, 61, 24, 35, 39, 4, -50, -58, -39, 0, 43, 43, 21, 24,
+ -20, -46, -36, 38, 8, -67, -8, 61, 38, 10, -12, 5, -4, -16, -47, -5,
+ -18, -20, 37, 41, 24, 4, 7, -19, 11, -52, 0, 17, 20, -30, -33, -16,
+ 60, 34, -15, -46, -77, 14, 29, 26, 21, 25, 8, 7, 36, 23, -39, -16,
+ 21, 11, -23, 11, -4, -6, -35, 13, -8, -49, -17, 44, 19, -25, -17, 9,
+ -5, -5, -1, -31, 11, 15, 17, -8, -31, -51, 12, 54, 85, 32, 4, -58,
+ -35, -31, 0, 10, 21, -20, -20, -29, 15, 26, -7, 8, 4, 0, 30, 2,
+ -26, 2, 19, 15, -18, -13, -20, -19, 47, 33, -6, -51, -30, -12, 12, 30,
+ 34, 31, 4, -45, -81, -7, -22, 1, 73, 98, 24, -67, -13, 19, -32, -86,
+ 6, 94, 4, -47, 21, -11, -50, 22, -3, -2, 50, 20, -37, -59, 35, 28,
+ -16, -36, -30, -11, 4, 69, 98, -65, -84, 73, 27, -90, -17, 84, 10, -51,
+ -14, 40, -24, -11, 16, -34, -26, 38, -43, -34, 58, 85, -33, -51, 17, 7,
+ 4, 52, 25, -35, 0, 44, -21, -47, 40, 44, -69, -65, 37, 35, -21, 4,
+ 32, -60, -75, 21, 64, 60, -6, -11, 6, 2, -41, -34, 19, 31, 9, 7,
+ -1, 11, 6, -11, -26, -23, 16, 35, -39, -68, 6, 56, -3, -42, 29, 28,
+ 3, 28, 14, -37, -16, 11, -8, -18, 15, -1, -8, 43, -20, -67, -12, 34,
+ 7, -12, -9, 5, -4, 7, -12, 27, -3, -68, 26, 96, 30, -33, -28, -25,
+ 19, 27, -33, -48, -3, 37, -1, -35, -11, 5, 42, 36, 6, -48, -38, 26,
+ 54, -23, -41, 52, 44, -32, -22, 28, -23, -32, 12, 41, -16, -6, -6, -17,
+ -18, -14, -12, -5, 18, 52, 45, -10, -16, 29, 11, -36, -26, 7, 36, 12,
+ -57, -48, 48, 70, 16, 21, -13, -46, -33, -62, -63, -21, 94, 94, 20, -110,
+ -47, 41, 67, -16, -57, -40, 85, 71, 7, -39, 15, -29, -50, -41, 18, -40,
+ -42, 38, 69, 21, -8, -58, -19, 23, 24, -20, -10, 11, 41, 7, -6, -30,
+ -23, 2, 16, 57, 38, -11, -50, 36, -16, -51, -51, 81, 24, -68, -84, 39,
+ 112, 62, -79, -104, 24, 102, 15, -38, 20, 22, -49, -91, 15, 51, 30, -1,
+ -15, -30, -12, 17, 42, -17, -48, 0, 49, 35, 2, -19, -16, -30, 9, 17,
+ -12, -4, -15, 5, 34, -1, -56, -64, 7, 48, 54, -16, -51, 20, 62, -17,
+ -27, -9, -10, -29, -1, 35, 44, -20, -23, -2, -12, -4, 31, 24, -24, -14,
+ 2, -28, -27, 49, 61, -54, -61, 6, 23, -20, 2, 41, 26, 2, 15, -5,
+ 6, -16, -36, -16, 2, -54, -53, -18, 62, 64, 10, -3, 91, 39, -54, -103,
+ -5, 16, -31, -28, 75, 105, -32, -114, -52, 68, 32, -52, -19, 25, 54, 61,
+ 14, -40, 12, 1, -56, -31, 74, 40, -73, -66, 0, 49, 36, 24, -20, 0,
+ 13, -40, -99, -11, 55, 31, -33, 39, 24, 3, -18, 7, 10, 4, -29, 17,
+ 19, 27, -30, -41, 9, 33, -24, -25, 30, 28, -34, -57, 8, -7, -46, 5,
+ 48, -22, -6, 57, 58, -31, -72, -2, 72, 44, -53, -42, 41, 1, -54, 30,
+ 54, -6, -79, -14, 33, -6, -22, 14, 10, -5, -8, 13, 23, 21, -47, -74,
+ 22, 24, -10, -7, 39, 2, 12, -7, -2, 4, 33, -20, -33, 18, 22, -88,
+ -71, 26, 81, 14, -37, 3, -24, 6, -8, 11, 40, 18, -7, -17, 20, -8,
+ -15, -41, -11, 27, 52, -27, -46, 33, 21, 46, -30, -13, 26, -91, -106, -47,
+ 54, 109, 67, -87, -90, 38, 92, 31, -10, -69, -73, -27, -6, 24, -6, 20,
+ 30, 45, 33, -13, -25, 10, 57, -16, -32, 0, -14, -55, -20, 4, 7, -4,
+ 3, 18, -11, 34, 11, -45, -45, -125, -38, -2, 19, 72, 82, 99, 98, 35,
+ -51, -81, -53, 3, -39, 23, -4, -58, -63, -24, 40, 84, 48, -7, -18, -2,
+ -8, -20, -10, 3, 21, 17, -39, -66, -20, -2, 37, 30, 39, 34, -5, -41,
+ -26, 33, 40, 18, -2, 11, 13, -20, -60, -21, 33, -25, -35, 30, 65, 22,
+ 13, -15, 2, 16, 11, -68, -18, 74, 10, -74, -34, -39, -17, 8, 59, 39,
+ -22, -38, -8, 9, 30, 23, 11, -3, -12, 10, -1, 59, 9, -28, -72, -27,
+ 32, 68, -11, -3, 27, 4, -33, -39, 7, -1, -5, -7, 26, -14, -26, -40,
+ -12, 5, 5, 1, -12, 64, 63, -41, -56, 10, 26, 40, -26, -44, -42, 25,
+ -6, 3, -1, 10, 9, -1, 9, 1, -28, 10, 24, 26, -33, -36, 46, 20,
+ -43, -52, -35, 22, 53, 30, -6, 18, -16, -49, -36, 45, 10, 21, 7, 9,
+ -33, -50, 21, 73, 33, -42, -46, 42, -12, -18, 5, -50, -25, 68, 55, -31,
+ -79, -7, 77, 25, -6, 29, 78, 24, -87, -41, -30, -41, -23, 75, 35, -32,
+ -65, -7, -13, 3, 41, 34, -24, -33, 25, 14, -52, -28, 19, 76, 45, -45,
+ -47, -5, 24, 9, -14, -41, -5, 49, 22, 10, -31, -35, -1, -6, 3, 10,
+ -1, -12, -20, -51, 9, 79, 53, -36, -38, -13, -14, -15, 50, 50, -36, -33,
+ 0, 5, 22, 23, 24, -51, -81, -27, 56, 42, -10, -16, 0, 0, -5, 16,
+ 12, -19, 11, 10, -15, -1, -32, -17, 1, 11, 62, -16, -21, 9, 21, -29,
+ -50, 16, 82, 17, -35, -4, 11, 3, 8, 8, -9, -13, 10, -39, -63, -19,
+ 54, 58, -16, -25, 18, 38, -8, -50, -54, -17, 18, 47, 17, -33, -45, 0,
+ 52, 57, -5, -34, -17, 32, 10, -28, -10, -21, -3, -9, -20, 20, 47, 22,
+ 5, -4, -15, -37, -22, -28, 9, 37, -18, -13, 3, 15, -33, -47, 20, 73,
+ 0, -36, 33, 60, -11, -77, -13, 42, 13, -20, 9, 47, 22, -27, 29, 6,
+ -71, -78, -20, 21, 4, 27, 23, 19, 31, 45, -29, -54, -10, 37, -78, -46,
+ -14, 67, 108, 57, 12, -62, -108, -15, 116, 56, -58, -110, -33, 33, 30, -39,
+ -26, 11, 29, 22, 8, 52, 76, 31, 0, -31, -50, -10, 59, 54, -13, -84,
+ -65, -60, 0, 35, 105, 61, -30, -117, -62, 35, 88, 57, 48, -38, -85, 41,
+ 12, -21, -6, 7, 15, 73, -30, -72, -37, 25, 0, -5, 65, 76, -90, -78,
+ 24, 47, 2, -14, 40, 83, 0, -32, -46, -62, -26, 50, 37, -4, -44, -40,
+ 55, 31, -38, -13, -17, -30, -4, 7, 68, 39, 1, -23, -38, -30, 6, -35,
+ 14, 52, -9, -62, -47, 45, 44, 11, -17, -9, 6, 16, 34, -3, -32, -21,
+ -33, -3, 21, 26, -39, 11, 65, 33, 19, -1, -49, -85, -97, 66, 58, -93,
+ -15, 15, 5, 81, 76, 29, -2, -52, -51, -30, 65, 38, -45, -14, 1, 28,
+ 22, 43, 19, -59, -109, -29, 29, -14, -22, -41, 0, 54, 76, 16, 8, 23,
+ 15, -47, -39, -8, 5, 36, -6, -3, -4, 13, 13, 21, -47, -53, -6, -9,
+ -27, -44, 8, 86, 64, 12, -5, -32, -10, -20, -27, -23, 8, 30, 1, 16,
+ 42, -35, -8, 4, -39, -11, -62, -29, 108, 87, -20, -104, -18, -55, 8, 47,
+ -16, 29, 38, 4, -44, -39, -20, 38, -13, 23, 82, 30, -67, -93, 26, 79,
+ 20, -79, -74, -23, 33, 59, 80, 39, -42, -100, 0, 19, 38, 9, -55, 9,
+ -15, 22, 68, -17, -55, -23, 1, 87, 19, -56, -60, 32, 37, 38, -67, -33,
+ -1, 31, 24, 15, -30, -5, -36, -29, -27, 8, 27, -9, 12, 29, 38, 33,
+ 0, -39, -18, 6, 19, 18, 8, 1, -33, 9, -1, 2, -29, -66, 0, 41,
+ 6, -50, -13, 9, 73, -28, -47, -21, 30, 68, 31, 32, 29, -46, -14, 13,
+ -44, -75, -3, 62, 55, 9, -49, -1, 54, 19, -6, 7, 16, 38, 13, -26,
+ -55, -76, -23, 16, 21, -33, -22, 16, 61, 25, -14, -35, 12, 23, -7, -17,
+ -32, -10, -16, -1, 7, 18, -1, 19, -2, -1, 21, -14, 1, -44, -44, -23,
+ -29, -1, 28, -28, 47, 64, 12, -4, -15, -37, -7, 24, 50, 6, -15, -26,
+ -5, 20, 12, -25, -21, -2, -18, -23, 9, 16, 24, 36, -30, -35, -12, 32,
+ 19, -13, 19, -6, 2, -2, -22, -11, 14, 50, 10, -21, -55, -14, 23, 6,
+ 6, -6, -26, -25, -8, 25, 14, 24, 14, -13, 18, 11, 23, -34, -49, -45,
+ 6, 39, 37, 3, 0, -29, 8, 26, -6, -7, -21, 2, -11, 6, 16, -1,
+ -17, 6, 32, -4, -54, -9, 22, -14, 6, 27, -1, -2, 34, 33, 8, 1,
+ -8, -14, -32, 23, -22, -23, -29, -12, 5, 25, 22, -4, 14, 5, 24, -39,
+ -29, 17, -21, -80, -60, -9, 78, 99, 81, -41, -53, 22, 11, -69, -22, -2,
+ 70, 80, 18, -56, -54, -79, -27, 56, 46, 28, -1, 12, -37, -76, 23, 64,
+ -4, -5, 4, 0, -2, -5, 10, -4, -9, 5, 3, 3, -2, 6, -2, -1,
+ 0, 2, 0, 1, -2, 2, -3, -2, 0, 1, -1, 0, 0, -1, -1, -1,
+ 0, -1, -1, -1, -1, 0, 0, -1, 0, -1, -1, -1, -1, -1, -1, 0,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -2, -3, -5, -6, -5, -5,
+ -3, 0, -1, -3, -1, 7, 16, 20, 8, -8, -24, -35, -39, -36, -35, -42,
+ -47, -35, -14, 0, 8, 17, 28, 45, 60, 65, 64, 66, 67, 60, 50, 39,
+ 26, 14, 5, -14, -40, -54, -56, -56, -55, -47, -36, -20, 1, 13, 15, 16,
+ 12, 2, -10, -20, -33, -43, -42, -38, -43, -40, -28, -17, -7, 6, 21, 34,
+ 48, 60, 63, 64, 66, 61, 54, 51, 41, 23, 10, 1, -18, -37, -46, -54,
+ -63, -60, -46, -30, -13, 5, 15, 16, 17, 11, -2, -11, -21, -34, -44, -45,
+ -43, -42, -33, -21, -17, -10, 5, 23, 39, 54, 62, 61, 62, 63, 59, 53,
+ 47, 38, 23, 10, -5, -23, -36, -42, -51, -61, -61, -48, -26, -2, 14, 16,
+ 13, 13, 9, -1, -14, -27, -36, -42, -44, -48, -44, -31, -17, -10, -8, 1,
+ 21, 47, 65, 67, 58, 54, 58, 61, 54, 41, 31, 23, 11, -9, -30, -41,
+ -44, -45, -54, -61, -52, -21, 11, 25, 19, 8, 4, 7, 2, -15, -33, -39,
+ -39, -44, -51, -48, -34, -12, -2, -4, -2, 19, 54, 74, 72, 58, 47, 51,
+ 59, 54, 40, 26, 20, 7, -16, -37, -46, -44, -42, -51, -58, -47, -15, 19,
+ 31, 25, 9, -1, -1, -4, -15, -30, -37, -41, -51, -55, -48, -28, -11, -4,
+ -2, 6, 28, 58, 73, 74, 63, 50, 45, 46, 49, 42, 31, 19, -6, -30,
+ -43, -44, -42, -51, -54, -49, -33, -3, 18, 30, 31, 17, 2, -13, -15, -15,
+ -25, -31, -45, -62, -60, -45, -24, -16, -10, 6, 20, 40, 58, 68, 74, 69,
+ 55, 41, 37, 44, 43, 34, 15, -17, -41, -48, -46, -51, -59, -51, -34, -16,
+ 3, 17, 29, 33, 23, 2, -15, -18, -18, -22, -31, -50, -64, -61, -42, -30,
+ -24, -8, 13, 35, 50, 57, 65, 70, 70, 58, 42, 40, 41, 40, 32, 6,
+ -23, -45, -53, -55, -64, -60, -45, -24, -1, 10, 19, 27, 28, 23, 4, -9,
+ -17, -22, -23, -36, -53, -61, -60, -47, -36, -22, -3, 19, 44, 56, 60, 65,
+ 65, 65, 60, 52, 45, 39, 37, 23, -2, -26, -49, -63, -66, -63, -55, -42,
+ -16, 3, 14, 25, 25, 22, 19, 11, -2, -17, -20, -29, -44, -50, -58, -64,
+ -53, -32, -13, 0, 25, 45, 53, 65, 68, 61, 60, 63, 60, 47, 42, 33,
+ 7, -10, -26, -56, -73, -68, -57, -53, -37, -12, -1, 14, 32, 26, 16, 17,
+ 16, 1, -12, -19, -38, -52, -47, -55, -65, -50, -23, -9, 4, 27, 40, 48,
+ 68, 72, 59, 58, 67, 64, 52, 42, 21, -5, -16, -31, -60, -73, -62, -54,
+ -49, -34, -17, -4, 17, 32, 24, 13, 18, 20, 6, -11, -29, -46, -48, -46,
+ -54, -59, -41, -17, -5, 6, 20, 35, 54, 71, 68, 55, 60, 74, 71, 53,
+ 27, 5, -6, -16, -35, -62, -70, -57, -49, -45, -40, -25, 4, 25, 29, 15,
+ 7, 23, 27, 10, -20, -46, -47, -41, -39, -47, -55, -34, -11, -1, 4, 11,
+ 38, 67, 72, 62, 48, 61, 83, 76, 49, 9, -9, -7, -15, -31, -59, -70,
+ -55, -48, -46, -43, -21, 16, 29, 22, 6, 1, 25, 32, 10, -28, -57, -47,
+ -34, -30, -38, -49, -33, -12, -4, 3, 17, 50, 72, 68, 55, 44, 61, 86,
+ 77, 41, -2, -16, -10, -13, -28, -56, -69, -58, -52, -47, -35, -7, 22, 25,
+ 13, -4, -2, 25, 33, 7, -35, -58, -46, -29, -22, -32, -44, -34, -16, -5,
+ 8, 30, 59, 72, 65, 46, 39, 62, 87, 76, 33, -8, -20, -13, -10, -28,
+ -57, -70, -62, -51, -42, -24, 3, 23, 23, 4, -15, -4, 25, 34, 3, -38,
+ -55, -45, -23, -17, -32, -43, -34, -15, -1, 14, 41, 64, 73, 59, 35, 35,
+ 64, 89, 73, 26, -11, -23, -14, -11, -33, -60, -69, -59, -48, -39, -14, 11,
+ 25, 17, -11, -24, -3, 30, 35, -3, -40, -54, -41, -18, -19, -36, -41, -28,
+ -10, 0, 21, 51, 70, 71, 47, 24, 36, 72, 93, 65, 17, -14, -22, -13,
+ -17, -43, -62, -63, -52, -48, -36, -5, 19, 26, 5, -26, -27, 5, 40, 31,
+ -12, -42, -50, -34, -20, -28, -37, -33, -17, -8, -1, 29, 61, 75, 64, 31,
+ 19, 44, 85, 93, 51, 9, -15, -18, -16, -30, -50, -57, -52, -48, -52, -32,
+ 3, 25, 20, -10, -34, -21, 19, 42, 20, -17, -40, -43, -35, -30, -32, -32,
+ -21, -12, -12, 3, 37, 67, 72, 50, 25, 24, 57, 92, 81, 42, 6, -12,
+ -18, -25, -39, -53, -52, -44, -49, -51, -28, 6, 25, 13, -17, -32, -11, 29,
+ 39, 8, -24, -38, -37, -33, -36, -39, -30, -10, -3, -9, 3, 38, 68, 71,
+ 46, 23, 32, 68, 92, 71, 31, 5, -7, -16, -31, -50, -55, -45, -37, -49,
+ -53, -27, 8, 23, 8, -20, -24, 3, 34, 28, -6, -28, -32, -30, -35, -46,
+ -43, -23, 0, 0, -10, 5, 41, 67, 65, 42, 30, 47, 77, 83, 52, 23,
+ 10, 2, -16, -43, -60, -55, -38, -36, -53, -53, -25, 8, 19, 3, -14, -8,
+ 17, 29, 9, -17, -24, -22, -26, -43, -53, -42, -14, 4, -3, -9, 10, 44,
+ 63, 58, 43, 43, 63, 77, 64, 38, 24, 20, 7, -23, -52, -62, -49, -38,
+ -45, -57, -49, -19, 6, 11, 2, -1, 12, 22, 13, -7, -18, -15, -17, -32,
+ -50, -52, -32, -11, -4, -8, -3, 21, 44, 55, 53, 52, 63, 70, 64, 49,
+ 35, 34, 24, 0, -29, -53, -54, -50, -51, -56, -57, -37, -17, -2, 7, 9,
+ 20, 21, 12, 1, -13, -11, -13, -24, -36, -49, -40, -30, -22, -12, -9, 10,
+ 25, 38, 51, 57, 70, 71, 62, 57, 44, 42, 34, 15, -4, -30, -42, -53,
+ -65, -61, -61, -49, -35, -22, -2, 10, 25, 27, 15, 11, -1, -8, -14, -22,
+ -27, -37, -37, -37, -40, -26, -14, -2, 10, 24, 42, 54, 68, 73, 65, 65,
+ 60, 49, 36, 27, 15, -7, -25, -43, -63, -69, -65, -61, -54, -36, -13, 3,
+ 18, 26, 23, 20, 16, 1, -16, -21, -20, -31, -37, -38, -40, -38, -25, -15,
+ -7, 11, 34, 48, 56, 66, 71, 72, 73, 61, 43, 34, 29, 11, -14, -31,
+ -46, -63, -69, -72, -69, -53, -28, -7, 3, 16, 27, 30, 28, 15, -3, -14,
+ -19, -25, -39, -42, -37, -38, -35, -30, -19, -2, 18, 39, 47, 56, 69, 75,
+ 78, 71, 60, 49, 35, 22, -1, -20, -32, -50, -65, -76, -75, -63, -49, -27,
+ -9, 6, 22, 28, 31, 27, 16, 6, -13, -26, -36, -43, -41, -42, -42, -36,
+ -27, -10, 2, 18, 38, 52, 64, 70, 73, 79, 76, 70, 50, 27, 11, -5,
+ -21, -41, -62, -69, -72, -68, -61, -50, -26, -4, 13, 21, 23, 32, 35, 27,
+ 6, -21, -33, -37, -42, -48, -53, -45, -31, -19, -8, 3, 23, 45, 59, 65,
+ 65, 73, 88, 88, 69, 40, 19, 10, -6, -30, -54, -69, -69, -68, -67, -59,
+ -43, -18, 2, 10, 15, 22, 39, 46, 27, -3, -28, -34, -37, -48, -56, -60,
+ -48, -29, -16, -1, 14, 35, 52, 58, 60, 64, 80, 96, 88, 64, 34, 16,
+ 6, -11, -36, -62, -77, -75, -68, -58, -47, -33, -14, -1, 7, 15, 28, 43,
+ 44, 24, -6, -30, -38, -40, -49, -63, -68, -56, -30, -5, 15, 27, 40, 51,
+ 59, 63, 72, 84, 91, 83, 60, 32, 12, 1, -14, -45, -73, -84, -78, -62,
+ -46, -36, -28, -17, 0, 11, 20, 31, 38, 35, 20, -6, -28, -40, -46, -58,
+ -72, -71, -52, -26, 4, 26, 37, 45, 54, 64, 69, 74, 81, 80, 73, 59,
+ 35, 13, -5, -28, -54, -75, -79, -74, -63, -43, -30, -21, -11, 0, 14, 23,
+ 29, 33, 23, 14, -2, -25, -41, -58, -69, -71, -64, -43, -24, 3, 33, 47,
+ 56, 60, 64, 73, 74, 75, 73, 62, 56, 38, 13, -12, -42, -57, -69, -77,
+ -71, -63, -44, -25, -15, -3, 2, 13, 26, 23, 24, 19, 8, -2, -24, -44,
+ -64, -74, -64, -60, -45, -16, 9, 34, 53, 63, 68, 66, 75, 73, 63, 66,
+ 62, 49, 34, 11, -17, -43, -54, -66, -82, -72, -52, -43, -28, -10, 0, 4,
+ 18, 27, 16, 13, 20, 8, -11, -26, -47, -66, -63, -59, -63, -47, -7, 20,
+ 34, 56, 69, 65, 73, 81, 67, 54, 61, 63, 44, 25, 6, -23, -37, -44,
+ -69, -85, -69, -48, -39, -26, -7, -4, 5, 27, 25, 9, 10, 15, 5, -17,
+ -34, -52, -62, -54, -54, -60, -40, -5, 21, 41, 59, 67, 66, 78, 81, 64,
+ 53, 58, 56, 39, 18, -3, -24, -34, -45, -64, -76, -67, -51, -37, -21, -8,
+ -3, 11, 22, 20, 11, 9, 11, -4, -23, -38, -56, -57, -53, -50, -42, -31,
+ -5, 21, 41, 63, 67, 72, 77, 69, 67, 58, 56, 49, 28, 16, -8, -28,
+ -35, -50, -53, -62, -65, -53, -44, -20, -2, 2, 14, 10, 14, 17, 7, 5,
+ -13, -27, -37, -60, -58, -55, -42, -22, -18, -2, 13, 36, 69, 73, 76, 71,
+ 62, 70, 60, 53, 42, 23, 16, -13, -35, -45, -51, -40, -46, -58, -60, -52,
+ -17, 4, 8, 11, 5, 14, 15, 4, -4, -20, -23, -37, -62, -67, -59, -27,
+ -2, -3, -3, 3, 36, 70, 77, 75, 66, 67, 70, 57, 46, 32, 29, 19,
+ -17, -49, -62, -46, -25, -33, -54, -68, -51, -15, 4, 8, 6, 11, 18, 8,
+ -7, -19, -16, -12, -35, -68, -83, -56, -9, 13, 7, -7, 4, 40, 66, 73,
+ 69, 73, 80, 69, 46, 27, 31, 42, 24, -23, -68, -69, -36, -14, -25, -57,
+ -66, -43, -16, -3, -2, 11, 28, 23, -2, -31, -29, -4, -1, -34, -83, -89,
+ -45, 3, 22, 6, -3, 16, 41, 56, 55, 68, 93, 93, 65, 23, 12, 38,
+ 53, 27, -38, -80, -64, -29, -12, -31, -54, -49, -34, -22, -24, -11, 28, 47,
+ 25, -24, -51, -27, 5, 5, -43, -90, -79, -34, 6, 11, 4, 17, 31, 39,
+ 34, 38, 79, 114, 105, 50, 3, 12, 44, 56, 16, -49, -72, -54, -28, -29,
+ -44, -37, -27, -28, -41, -45, -5, 46, 61, 17, -44, -53, -20, 7, -6, -53,
+ -78, -62, -27, -7, -6, 14, 41, 45, 26, 11, 38, 93, 127, 101, 34, 1,
+ 20, 48, 42, -1, -41, -53, -45, -40, -51, -44, -18, -9, -34, -61, -47, 7,
+ 57, 58, 2, -46, -43, -14, -5, -27, -52, -58, -46, -31, -26, -12, 28, 59,
+ 45, 10, 6, 50, 104, 124, 87, 30, 11, 30, 40, 19, -9, -26, -35, -44,
+ -58, -62, -38, -4, -6, -46, -67, -37, 21, 56, 43, -4, -37, -30, -15, -25,
+ -40, -44, -38, -38, -43, -38, -9, 40, 64, 37, 5, 14, 65, 106, 107, 75,
+ 36, 26, 34, 24, 4, -8, -10, -24, -53, -70, -64, -30, 0, -16, -53, -61,
+ -22, 28, 43, 29, -2, -21, -20, -26, -39, -43, -34, -26, -43, -54, -40, 0,
+ 46, 56, 30, 12, 30, 75, 97, 90, 69, 47, 38, 29, 13, 2, 0, -1,
+ -27, -61, -71, -55, -25, -14, -32, -50, -41, -6, 22, 25, 17, 4, -8, -19,
+ -31, -38, -35, -28, -35, -53, -54, -29, 7, 31, 32, 23, 28, 51, 72, 78,
+ 72, 65, 55, 42, 30, 19, 15, 11, -8, -36, -58, -58, -42, -35, -35, -43,
+ -40, -18, 0, 12, 14, 11, 9, -4, -15, -25, -31, -28, -36, -49, -53, -45,
+ -18, 1, 12, 19, 23, 43, 58, 64, 68, 64, 64, 57, 46, 40, 28, 22,
+ 9, -17, -35, -48, -47, -44, -47, -45, -44, -31, -12, -2, 7, 10, 9, 7,
+ -2, -8, -19, -28, -32, -44, -51, -48, -37, -21, -9, 5, 16, 26, 43, 55,
+ 60, 64, 63, 61, 58, 55, 48, 34, 21, 6, -13, -27, -39, -49, -53, -50,
+ -46, -41, -32, -16, -3, 5, 11, 9, 6, 5, -4, -17, -32, -40, -42, -44,
+ -42, -40, -32, -12, 5, 17, 24, 35, 50, 58, 64, 64, 60, 65, 61, 50,
+ 34, 18, 10, -2, -18, -38, -58, -56, -49, -45, -41, -38, -22, -4, 8, 14,
+ 8, 11, 10, -5, -20, -38, -41, -36, -37, -40, -48, -37, -12, 4, 14, 19,
+ 27, 46, 59, 66, 63, 62, 70, 64, 50, 34, 22, 17, 8, -11, -38, -59,
+ -57, -50, -49, -47, -43, -28, -6, 10, 16, 10, 14, 8, 1, -5, -5, -4,
+ -5, 5, 2, 2, 1, -1, 0, 1, 0, 2, 0, 0, -2, -1, -1, 2,
+ 1, 1, 0, 0, -1, 0, -1, 0, 0, 0, 0, 0, 0, -1, -1, -1,
+ 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, -1,
+ -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1,
+ -1, 0, 1, 0, 0, 0, 1, 0, 1, 0, -3, -10, -11, -8, -13, -25,
+ -21, -10, 0, 2, 18, 41, 44, 42, 66, 62, 28, 10, 17, 17, -16, -10,
+ 25, 28, 29, 34, 47, 34, -7, 7, 25, -12, -43, -44, -40, -61, -85, -78,
+ -55, -42, -33, -10, 17, 31, 43, 59, 51, 25, 25, 40, 27, -1, 2, 25,
+ 30, 15, 12, 27, 26, 13, 16, 9, -24, -43, -37, -49, -83, -92, -62, -40,
+ -42, -36, 1, 33, 34, 45, 61, 46, 27, 32, 33, 10, -6, 15, 38, 26,
+ 4, 15, 35, 19, 7, 17, 3, -26, -41, -50, -67, -91, -82, -48, -40, -46,
+ -24, 18, 33, 32, 54, 62, 46, 30, 22, 20, 7, 4, 28, 33, 15, 10,
+ 22, 25, 9, 13, 18, -2, -29, -54, -65, -74, -86, -68, -49, -46, -32, -8,
+ 17, 29, 45, 65, 60, 43, 23, 13, 17, 12, 18, 28, 22, 19, 16, 13,
+ 14, 16, 24, 13, -13, -40, -66, -72, -75, -74, -64, -55, -36, -20, -9, 15,
+ 43, 63, 65, 51, 37, 17, 9, 19, 23, 21, 19, 24, 21, 3, 4, 24,
+ 31, 18, -2, -20, -49, -77, -74, -65, -71, -69, -47, -27, -27, -10, 38, 66,
+ 59, 52, 51, 34, 4, 11, 36, 26, 12, 22, 26, 2, -11, 25, 45, 18,
+ 0, -1, -23, -72, -83, -55, -65, -83, -61, -34, -37, -36, 23, 71, 55, 43,
+ 60, 55, 11, 1, 40, 37, 8, 16, 31, 6, -22, 14, 55, 27, -3, 8,
+ 2, -52, -83, -57, -56, -89, -79, -43, -43, -55, -4, 66, 61, 35, 56, 68,
+ 31, 4, 32, 46, 13, 7, 31, 16, -24, -4, 50, 42, 2, 7, 16, -25,
+ -67, -60, -54, -86, -95, -55, -44, -63, -32, 40, 62, 40, 47, 67, 48, 22,
+ 32, 42, 18, 4, 25, 25, -15, -16, 29, 44, 21, 11, 15, -5, -39, -49,
+ -59, -85, -96, -72, -52, -62, -50, 7, 45, 49, 50, 56, 56, 43, 42, 39,
+ 19, 9, 16, 21, 1, -16, 9, 32, 31, 24, 14, 5, -14, -34, -52, -81,
+ -94, -85, -71, -62, -55, -21, 21, 41, 53, 55, 55, 57, 51, 44, 26, 13,
+ 15, 11, 3, -3, 0, 19, 27, 29, 26, 11, 0, -16, -41, -70, -90, -88,
+ -85, -80, -57, -34, -3, 26, 42, 57, 57, 60, 64, 50, 33, 20, 17, 9,
+ -6, -1, 6, 10, 23, 26, 28, 22, 10, 1, -27, -60, -78, -87, -90, -94,
+ -74, -42, -20, 10, 34, 44, 57, 65, 71, 58, 35, 30, 23, 8, -5, -7,
+ 4, 7, 19, 33, 23, 19, 24, 17, -13, -53, -65, -75, -96, -98, -83, -61,
+ -40, -7, 32, 38, 38, 66, 83, 65, 36, 36, 37, 8, -7, 1, 0, -5,
+ 11, 39, 34, 10, 21, 36, 4, -45, -59, -59, -89, -106, -84, -67, -62, -32,
+ 21, 41, 30, 47, 85, 80, 41, 34, 45, 20, -8, 0, 9, -7, -6, 31,
+ 45, 21, 12, 32, 25, -27, -55, -52, -76, -104, -95, -70, -64, -57, -7, 33,
+ 34, 38, 67, 84, 57, 35, 46, 29, -1, -4, 7, 7, -8, 12, 41, 31,
+ 21, 24, 25, -5, -43, -45, -65, -98, -98, -82, -62, -58, -35, 13, 27, 38,
+ 59, 70, 67, 45, 49, 39, 2, -3, 2, 9, 9, 6, 30, 30, 24, 31,
+ 20, 3, -26, -37, -48, -91, -100, -88, -75, -53, -41, -9, 12, 23, 55, 65,
+ 61, 54, 51, 51, 14, -6, 1, 1, 15, 18, 26, 29, 16, 30, 28, 4,
+ -14, -29, -36, -71, -100, -93, -87, -64, -38, -16, 2, 6, 33, 61, 59, 56,
+ 54, 55, 32, 1, -3, -4, 5, 25, 36, 36, 17, 14, 25, 14, -4, -19,
+ -30, -53, -84, -94, -95, -82, -49, -16, 4, 2, 10, 37, 56, 61, 58, 54,
+ 42, 19, 3, -9, -8, 14, 41, 53, 32, 10, 7, 10, 10, -7, -25, -43,
+ -65, -81, -97, -99, -72, -29, 9, 11, 3, 10, 33, 61, 65, 55, 46, 30,
+ 19, 0, -17, -5, 29, 62, 57, 24, -1, -6, 10, 8, -16, -35, -54, -64,
+ -80, -105, -99, -57, -2, 26, 13, -2, 6, 42, 67, 60, 49, 36, 31, 22,
+ -10, -24, 1, 49, 77, 53, 9, -14, -4, 10, -4, -26, -47, -56, -58, -89,
+ -115, -93, -34, 23, 33, 6, -6, 16, 50, 62, 53, 39, 34, 40, 16, -24,
+ -26, 15, 71, 82, 38, -5, -13, -1, 3, -13, -39, -53, -48, -61, -103, -119,
+ -80, -6, 42, 27, -1, 2, 26, 51, 56, 43, 33, 43, 42, 4, -34, -23,
+ 37, 87, 70, 20, -6, -10, -3, -5, -27, -49, -48, -44, -72, -115, -118, -56,
+ 22, 43, 17, 3, 12, 33, 51, 45, 34, 38, 51, 38, -11, -42, -9, 59,
+ 86, 53, 13, -5, -5, -3, -19, -42, -50, -43, -45, -85, -127, -105, -28, 34,
+ 37, 15, 8, 23, 41, 42, 34, 33, 45, 55, 26, -27, -38, 12, 69, 77,
+ 40, 9, 1, 0, -13, -33, -48, -49, -39, -55, -102, -124, -83, -8, 37, 31,
+ 14, 19, 35, 39, 34, 30, 35, 51, 50, 9, -31, -25, 27, 72, 65, 30,
+ 12, 9, -2, -23, -42, -52, -46, -43, -71, -109, -112, -63, 7, 36, 25, 20,
+ 33, 42, 35, 29, 29, 40, 52, 35, -2, -28, -12, 40, 69, 51, 26, 18,
+ 13, -8, -33, -48, -50, -46, -57, -84, -107, -98, -43, 14, 29, 24, 30, 44,
+ 43, 30, 26, 34, 44, 40, 19, -8, -20, 4, 46, 59, 42, 29, 25, 10,
+ -18, -40, -46, -47, -57, -73, -91, -100, -78, -30, 13, 25, 30, 44, 48, 39,
+ 29, 31, 41, 35, 23, 9, -9, -5, 16, 43, 52, 40, 37, 25, 0, -23,
+ -41, -43, -54, -74, -82, -93, -86, -60, -26, 12, 26, 41, 53, 44, 40, 33,
+ 36, 38, 19, 12, 2, -3, 9, 18, 40, 48, 42, 41, 16, -6, -23, -41,
+ -45, -68, -84, -86, -90, -71, -52, -22, 15, 32, 52, 54, 45, 45, 36, 36,
+ 25, 6, 6, 0, 5, 15, 21, 41, 46, 46, 37, 10, -7, -24, -42, -57,
+ -81, -88, -88, -83, -62, -43, -14, 16, 41, 59, 55, 48, 48, 40, 27, 10,
+ 2, 2, 0, 8, 22, 30, 36, 45, 50, 32, 5, -9, -23, -48, -75, -86,
+ -86, -88, -81, -54, -26, -11, 16, 52, 65, 55, 50, 53, 39, 9, -2, 4,
+ 2, -4, 11, 36, 34, 27, 47, 51, 26, 0, -9, -23, -63, -91, -85, -81,
+ -89, -79, -38, -13, -11, 23, 62, 67, 55, 52, 56, 29, -8, -7, 7, 0,
+ -5, 19, 44, 30, 28, 49, 46, 21, -2, -10, -32, -79, -96, -83, -81, -87,
+ -67, -27, -11, 0, 36, 65, 67, 58, 54, 48, 14, -15, -7, 3, 1, 6,
+ 26, 35, 30, 38, 46, 37, 18, -2, -18, -48, -85, -96, -89, -81, -70, -52,
+ -30, -8, 20, 48, 63, 66, 59, 50, 33, 6, -14, -15, -2, 13, 20, 21,
+ 25, 36, 45, 42, 31, 12, -10, -31, -56, -84, -103, -96, -70, -50, -43, -31,
+ 0, 35, 58, 68, 65, 51, 37, 26, 8, -19, -25, 2, 27, 27, 17, 20,
+ 36, 45, 45, 29, 0, -27, -41, -55, -87, -111, -93, -57, -37, -33, -23, 5,
+ 41, 70, 77, 59, 36, 26, 24, 4, -24, -22, 7, 31, 33, 19, 14, 29,
+ 49, 50, 22, -16, -39, -48, -63, -92, -104, -86, -51, -25, -19, -16, 10, 53,
+ 82, 74, 47, 26, 19, 16, -1, -18, -16, 7, 35, 37, 18, 10, 31, 55,
+ 41, 4, -25, -45, -57, -73, -90, -95, -82, -42, -9, -8, -11, 20, 71, 84,
+ 57, 39, 27, 13, 2, -6, -9, -12, 8, 45, 41, 8, 5, 42, 56, 20,
+ -10, -24, -50, -73, -83, -83, -87, -76, -25, 10, -5, -9, 39, 84, 71, 44,
+ 38, 26, 2, -9, -2, -4, -11, 17, 52, 36, 0, 11, 50, 43, 3, -19,
+ -31, -57, -84, -84, -77, -82, -59, -9, 14, 1, 7, 55, 81, 61, 38, 29,
+ 20, -2, -10, -1, -4, 0, 26, 42, 30, 8, 20, 41, 28, -4, -31, -46,
+ -64, -84, -82, -79, -66, -37, -7, 15, 18, 30, 58, 68, 57, 33, 17, 9,
+ 0, -3, -7, 0, 15, 23, 31, 29, 23, 24, 22, 14, -12, -43, -63, -72,
+ -73, -83, -75, -47, -26, -2, 20, 37, 48, 50, 57, 52, 30, 6, -1, 11,
+ 0, -9, 7, 16, 24, 28, 32, 33, 15, 7, 2, -21, -55, -79, -66, -67,
+ -81, -63, -38, -12, 9, 29, 53, 48, 42, 51, 47, 22, -6, 5, 18, -4,
+ -7, 6, 22, 28, 26, 39, 28, 2, -2, -8, -35, -73, -76, -56, -67, -77,
+ -55, -20, 4, 16, 40, 54, 42, 41, 51, 37, 7, 0, 17, 13, -12, -9,
+ 20, 31, 25, 29, 33, 15, -5, -8, -22, -57, -74, -62, -57, -74, -71, -33,
+ 0, 11, 26, 44, 45, 41, 47, 45, 22, 3, 12, 19, 0, -15, 4, 30,
+ 32, 27, 26, 17, 3, -4, -14, -44, -69, -66, -56, -63, -74, -52, -11, 12,
+ 21, 29, 35, 41, 49, 51, 31, 9, 11, 19, 11, -8, -7, 20, 36, 34,
+ 22, 10, 6, 5, -4, -33, -64, -66, -58, -58, -67, -63, -29, 4, 20, 21,
+ 21, 35, 52, 57, 39, 12, 10, 18, 16, 3, -7, 8, 31, 39, 25, 5,
+ 3, 10, 5, -22, -58, -67, -58, -56, -60, -64, -45, -11, 15, 19, 12, 24,
+ 50, 62, 46, 17, 9, 18, 20, 12, 0, 2, 21, 37, 31, 7, 0, 11,
+ 14, -12, -51, -66, -58, -53, -54, -59, -54, -29, 3, 16, 9, 17, 44, 62,
+ 51, 22, 8, 17, 24, 21, 9, 1, 11, 30, 31, 14, 3, 11, 16, -4,
+ -43, -65, -58, -49, -50, -53, -55, -43, -16, 5, 10, 16, 38, 59, 54, 26,
+ 7, 18, 29, 24, 18, 8, 5, 16, 27, 23, 11, 14, 18, -1, -36, -63,
+ -56, -43, -48, -47, -49, -52, -36, -12, 8, 17, 35, 55, 50, 28, 9, 17,
+ 33, 25, 24, 20, 5, 4, 15, 27, 23, 20, 22, 0, -32, -58, -55, -40,
+ -47, -44, -39, -52, -54, -34, -2, 19, 35, 53, 46, 27, 12, 18, 34, 26,
+ 26, 33, 13, -6, 0, 22, 34, 32, 28, 3, -31, -53, -51, -39, -47, -45,
+ -30, -45, -66, -56, -19, 15, 38, 52, 43, 22, 13, 22, 35, 26, 26, 41,
+ 25, -7, -13, 10, 35, 46, 39, 10, -29, -50, -46, -37, -47, -46, -27, -35,
+ -65, -72, -42, 2, 38, 55, 43, 19, 11, 24, 36, 27, 26, 43, 37, 2,
+ -19, -6, 25, 53, 56, 20, -24, -46, -43, -36, -46, -48, -29, -28, -56, -77,
+ -64, -22, 31, 61, 45, 16, 10, 23, 35, 30, 26, 41, 42, 16, -14, -21,
+ 7, 51, 70, 36, -15, -38, -40, -35, -42, -49, -35, -29, -44, -71, -81, -49,
+ 14, 60, 50, 18, 10, 21, 34, 34, 26, 37, 43, 30, 0, -27, -13, 37,
+ 74, 54, 2, -29, -35, -32, -37, -49, -42, -32, -36, -57, -85, -73, -12, 46,
+ 57, 27, 9, 17, 32, 38, 28, 30, 41, 39, 18, -20, -27, 15, 62, 68,
+ 26, -17, -30, -28, -29, -45, -51, -40, -34, -45, -77, -86, -42, 18, 54, 43,
+ 14, 12, 29, 42, 34, 25, 33, 41, 30, -2, -24, -5, 36, 65, 50, 3,
+ -24, -24, -19, -33, -54, -52, -42, -45, -61, -75, -58, -15, 32, 48, 25, 10,
+ 24, 45, 45, 27, 26, 32, 28, 13, -4, -6, 14, 44, 55, 24, -11, -18,
+ -12, -20, -46, -57, -53, -54, -57, -63, -57, -33, 4, 35, 32, 16, 22, 40,
+ 49, 36, 26, 28, 23, 17, 8, 1, 10, 27, 43, 33, 5, -6, -8, -14,
+ -33, -53, -57, -61, -62, -61, -59, -38, -10, 15, 26, 20, 26, 40, 44, 41,
+ 30, 27, 25, 18, 12, 3, 9, 26, 33, 28, 13, 5, 5, -8, -25, -45,
+ -57, -60, -64, -66, -65, -49, -17, 6, 13, 16, 26, 43, 47, 39, 32, 27,
+ 27, 25, 13, 3, 6, 22, 35, 26, 13, 10, 12, 5, -17, -40, -54, -58,
+ -58, -68, -74, -61, -31, -1, 9, 10, 23, 40, 50, 45, 31, 24, 27, 31,
+ 20, 3, 2, 17, 32, 31, 16, 12, 15, 12, -4, -31, -51, -55, -54, -62,
+ -76, -73, -47, -17, 2, 8, 19, 37, 51, 50, 34, 24, 26, 31, 25, 9,
+ 4, 13, 26, 34, 25, 9, 13, 20, -2, -33, -44, -43, -58, -78, -77, -59,
+ -44, -33, -10, 17, 6, 12, -9, 32, 13, 4, -4, 6, -9, 27, 8, 2,
+ -1, -3, -2, 3, -4, -3, 2, 0, -2, 1, -2, 1, -4, 2, 1, 0,
+ -2, -1, -3, 2, 0, -1, -2, -2, -2, -1, -2, -2, -1, -2, -2, -2,
+ -2, -1, -2, -1, 0, -1, -2, -2, -2, -1, 0, -2, -2, -2, -2, -1,
+ -1, -2, -1, -2, -2, -2, -3, -1, -1, 0, 0, -1, -3, -2, 1, 3,
+ 0, 0, -2, -8, -21, -17, -2, 12, 20, 19, 6, -13, -28, -73, -67, -64,
+ -58, -39, -11, 19, 38, 60, 96, 80, 38, 12, 6, -20, -65, -83, -65, -61,
+ -56, -17, 22, 35, 49, 74, 94, 55, 16, 20, -5, -52, -89, -81, -53, -65,
+ -36, 21, 37, 48, 51, 85, 82, 25, 23, 9, -36, -80, -105, -58, -57, -54,
+ 7, 36, 54, 44, 58, 97, 48, 26, 16, -21, -61, -115, -83, -45, -57, -12,
+ 23, 57, 54, 36, 86, 77, 37, 21, -16, -40, -103, -110, -54, -46, -24, 6,
+ 43, 68, 36, 62, 86, 60, 30, -12, -34, -80, -119, -76, -44, -24, -5, 24,
+ 64, 51, 50, 76, 72, 48, 0, -34, -68, -106, -94, -56, -26, -7, 11, 45,
+ 59, 58, 66, 71, 60, 23, -27, -68, -93, -93, -72, -37, -8, 10, 25, 50,
+ 70, 68, 62, 62, 45, -10, -70, -88, -83, -79, -57, -15, 15, 13, 31, 73,
+ 80, 59, 53, 61, 15, -67, -89, -73, -75, -75, -33, 21, 11, 10, 66, 92,
+ 65, 42, 63, 42, -56, -92, -66, -66, -84, -57, 16, 19, -5, 50, 98, 76,
+ 39, 56, 60, -35, -95, -64, -53, -84, -79, 0, 28, -8, 29, 96, 89, 42,
+ 46, 69, -10, -90, -69, -41, -74, -95, -25, 28, -1, 13, 81, 101, 53, 37,
+ 69, 11, -77, -75, -38, -53, -103, -55, 22, 8, 6, 61, 104, 75, 29, 59,
+ 31, -61, -76, -43, -36, -91, -88, 6, 17, 1, 46, 96, 94, 34, 40, 48,
+ -40, -80, -47, -27, -69, -107, -27, 26, 4, 29, 87, 105, 51, 24, 46, -10,
+ -76, -58, -21, -49, -107, -62, 17, 16, 17, 70, 110, 67, 22, 38, 10, -60,
+ -71, -24, -28, -97, -85, -6, 25, 18, 50, 106, 84, 28, 31, 16, -38, -71,
+ -38, -17, -78, -94, -30, 15, 30, 41, 86, 92, 44, 31, 15, -25, -54, -53,
+ -26, -57, -88, -51, -2, 33, 45, 68, 88, 59, 35, 17, -15, -42, -55, -41,
+ -48, -73, -60, -19, 24, 50, 61, 74, 67, 46, 21, -8, -32, -48, -54, -53,
+ -57, -57, -34, 9, 50, 63, 59, 65, 58, 29, -1, -24, -38, -62, -67, -48,
+ -47, -40, -8, 43, 68, 48, 58, 66, 38, 6, -19, -26, -62, -85, -45, -35,
+ -39, -21, 28, 72, 41, 47, 74, 45, 15, -14, -17, -53, -102, -50, -24, -36,
+ -26, 10, 69, 42, 32, 81, 52, 21, -4, -15, -39, -109, -64, -12, -35, -26,
+ -1, 54, 47, 21, 79, 65, 20, 7, -12, -33, -100, -82, -8, -27, -32, -2,
+ 36, 47, 21, 66, 77, 25, 12, -2, -36, -88, -87, -18, -16, -36, -8, 27,
+ 36, 30, 56, 77, 39, 12, 6, -33, -84, -79, -30, -11, -29, -20, 19, 27,
+ 31, 58, 66, 50, 21, 5, -25, -81, -75, -32, -17, -17, -27, 2, 24, 28,
+ 61, 61, 48, 35, 4, -22, -71, -77, -31, -19, -12, -23, -18, 16, 29, 59,
+ 65, 45, 41, 10, -23, -59, -76, -37, -14, -11, -18, -29, -2, 29, 57, 68,
+ 51, 37, 16, -21, -55, -67, -44, -12, -5, -21, -29, -19, 19, 59, 68, 61,
+ 36, 14, -12, -55, -61, -44, -16, 3, -21, -29, -25, 0, 55, 72, 69, 43,
+ 8, -6, -49, -63, -39, -18, 5, -15, -31, -26, -18, 39, 78, 75, 53, 8,
+ -8, -40, -67, -37, -15, 2, -8, -30, -26, -29, 16, 79, 84, 59, 14, -11,
+ -33, -66, -42, -9, -2, -6, -23, -26, -33, -7, 66, 94, 67, 22, -9, -32,
+ -62, -48, -8, 0, -9, -16, -20, -35, -24, 46, 96, 78, 31, -2, -29, -59,
+ -51, -13, 1, -10, -13, -9, -31, -35, 23, 86, 88, 42, 5, -22, -57, -53,
+ -18, -3, -10, -13, 0, -19, -44, 2, 69, 90, 57, 12, -13, -50, -57, -21,
+ -9, -13, -13, 1, -3, -41, -17, 51, 82, 69, 23, -9, -37, -57, -25, -12,
+ -22, -15, 0, 10, -25, -32, 32, 69, 71, 37, -4, -25, -48, -30, -12, -32,
+ -23, -3, 14, -2, -33, 11, 56, 63, 49, 3, -18, -32, -31, -13, -37, -38,
+ -9, 11, 17, -16, -6, 41, 53, 51, 11, -17, -15, -23, -14, -35, -54, -22,
+ 4, 26, 10, -10, 26, 43, 46, 19, -19, -6, -5, -10, -30, -65, -42, -9,
+ 24, 35, 3, 12, 32, 37, 24, -20, -8, 14, 2, -23, -68, -62, -26, 10,
+ 50, 28, 11, 22, 27, 24, -19, -19, 24, 21, -8, -63, -78, -45, -11, 47,
+ 53, 23, 21, 19, 22, -17, -34, 21, 40, 15, -48, -89, -65, -34, 30, 68,
+ 44, 27, 16, 16, -11, -47, 3, 49, 39, -22, -89, -82, -55, 3, 68, 61,
+ 44, 21, 11, -6, -53, -21, 45, 56, 11, -74, -96, -72, -26, 52, 73, 60,
+ 39, 10, -3, -48, -44, 27, 61, 42, -43, -101, -88, -52, 27, 73, 70, 59,
+ 21, -1, -40, -60, 2, 52, 60, -4, -90, -100, -74, -2, 62, 72, 76, 42,
+ 5, -30, -66, -22, 34, 63, 33, -62, -104, -92, -31, 44, 68, 84, 66, 21,
+ -21, -64, -41, 13, 54, 55, -26, -94, -104, -57, 20, 56, 82, 84, 43, -6,
+ -57, -54, -10, 36, 60, 7, -70, -107, -78, -6, 40, 73, 92, 66, 12, -45,
+ -57, -27, 16, 52, 29, -41, -96, -90, -32, 20, 60, 91, 83, 34, -27, -52,
+ -37, -3, 34, 36, -15, -77, -91, -52, -1, 43, 83, 93, 53, -5, -42, -40,
+ -17, 14, 32, 1, -54, -81, -65, -21, 23, 71, 96, 67, 16, -25, -37, -24,
+ -5, 21, 6, -36, -64, -69, -37, 3, 54, 93, 73, 35, -6, -28, -25, -19,
+ 8, 4, -27, -46, -65, -46, -14, 34, 86, 73, 49, 15, -17, -19, -28, -4,
+ -3, -28, -32, -56, -48, -24, 15, 74, 67, 55, 36, -2, -10, -28, -14, -9,
+ -36, -25, -42, -50, -29, 1, 60, 59, 50, 55, 16, -3, -22, -20, -14, -46,
+ -29, -28, -48, -33, -5, 47, 50, 40, 64, 40, 4, -14, -17, -19, -53, -40,
+ -18, -40, -41, -6, 39, 39, 28, 61, 62, 17, -10, -7, -21, -59, -53, -20,
+ -28, -47, -11, 38, 29, 15, 52, 77, 36, -6, 1, -12, -63, -66, -25, -20,
+ -46, -19, 37, 28, 0, 38, 83, 54, 5, 5, -2, -57, -81, -34, -15, -44,
+ -22, 29, 31, -4, 16, 85, 68, 17, 15, 1, -44, -87, -54, -8, -42, -27,
+ 25, 24, 2, 0, 69, 88, 24, 25, 11, -42, -76, -75, -14, -25, -40, 23,
+ 18, -3, 3, 42, 96, 45, 22, 29, -39, -70, -75, -40, -8, -39, 7, 24,
+ -17, 8, 33, 79, 76, 22, 35, -21, -75, -64, -60, -15, -17, -14, 21, -21,
+ -4, 40, 59, 88, 45, 24, -3, -71, -61, -59, -38, 1, -14, 0, -17, -18,
+ 41, 54, 82, 74, 22, -3, -53, -61, -53, -54, -2, 3, -19, -25, -22, 30,
+ 57, 73, 92, 38, -15, -40, -51, -50, -58, -17, 17, -23, -44, -22, 19, 55,
+ 72, 97, 60, -22, -40, -35, -45, -55, -32, 14, -17, -60, -26, 11, 46, 75,
+ 97, 78, -17, -46, -23, -38, -45, -37, -1, -14, -66, -31, 3, 34, 80, 98,
+ 85, -4, -47, -19, -33, -33, -30, -20, -25, -63, -34, -4, 18, 79, 104, 84,
+ 9, -38, -18, -29, -27, -14, -30, -46, -63, -32, -5, 3, 68, 111, 84, 18,
+ -23, -12, -25, -28, -2, -25, -67, -75, -29, 1, -6, 46, 112, 91, 22, -11,
+ 0, -18, -33, -1, -9, -76, -96, -34, 9, -8, 22, 101, 102, 27, -2, 14,
+ -7, -36, -9, 4, -68, -114, -48, 13, -3, 5, 80, 109, 40, 4, 26, 6,
+ -33, -18, 6, -52, -120, -67, 7, 4, -1, 55, 103, 58, 14, 31, 17, -21,
+ -24, -4, -39, -110, -84, -10, 6, 2, 34, 87, 71, 29, 36, 25, -7, -23,
+ -16, -33, -96, -90, -29, -1, 6, 22, 68, 75, 45, 45, 31, 4, -15, -24,
+ -37, -84, -87, -43, -15, 3, 18, 53, 68, 57, 58, 38, 11, -7, -22, -45,
+ -81, -79, -48, -29, -10, 17, 45, 57, 61, 71, 50, 17, 0, -15, -49, -85,
+ -74, -45, -40, -25, 10, 42, 49, 55, 82, 65, 22, 7, -9, -43, -89, -80,
+ -34, -47, -40, -1, 35, 52, 43, 85, 84, 25, 17, -4, -38, -85, -92, -28,
+ -44, -55, -9, 21, 53, 42, 75, 100, 35, 22, 6, -38, -74, -99, -38, -34,
+ -65, -18, 12, 42, 51, 63, 102, 52, 25, 21, -36, -70, -90, -56, -30, -64,
+ -30, 7, 27, 55, 63, 90, 69, 33, 26, -26, -69, -79, -66, -43, -54, -37,
+ -1, 17, 49, 69, 79, 72, 50, 30, -15, -61, -75, -68, -58, -52, -33, -12,
+ 9, 42, 69, 78, 64, 60, 42, -9, -49, -71, -69, -68, -61, -25, -17, -1,
+ 38, 64, 77, 59, 62, 58, -3, -37, -62, -72, -72, -73, -24, -12, -11, 35,
+ 55, 73, 59, 58, 69, 8, -29, -48, -75, -76, -82, -31, -4, -14, 28, 49,
+ 63, 61, 54, 73, 22, -21, -36, -71, -82, -88, -42, 0, -9, 21, 43, 53,
+ 57, 56, 73, 33, -12, -25, -62, -89, -95, -49, -2, -2, 18, 37, 43, 49,
+ 60, 75, 38, -2, -16, -49, -89, -105, -54, -7, 1, 19, 31, 37, 38, 59,
+ 81, 39, 4, -7, -35, -83, -115, -62, -10, 0, 20, 27, 32, 30, 53, 87,
+ 43, 4, 0, -24, -70, -118, -75, -12, -2, 19, 24, 27, 27, 45, 89, 52,
+ 4, 1, -14, -55, -113, -87, -18, -3, 13, 20, 24, 28, 41, 85, 60, 7,
+ -3, -9, -40, -100, -91, -28, -4, 7, 10, 21, 30, 43, 82, 62, 13, -8,
+ -11, -26, -85, -87, -36, -10, 2, -4, 14, 35, 47, 81, 62, 18, -9, -21,
+ -20, -65, -78, -38, -19, -4, -16, 0, 39, 54, 85, 65, 20, -7, -31, -24,
+ -47, -62, -33, -26, -15, -25, -19, 35, 63, 90, 73, 22, -3, -39, -39, -35,
+ -43, -20, -26, -30, -34, -36, 24, 71, 94, 85, 29, -3, -40, -58, -34, -24,
+ -4, -16, -46, -47, -47, 6, 73, 100, 97, 42, -4, -39, -73, -45, -8, 12,
+ 0, -51, -64, -56, -13, 66, 104, 106, 64, 2, -40, -82, -63, -3, 27, 18,
+ -43, -82, -68, -28, 51, 104, 112, 86, 19, -42, -86, -81, -10, 40, 34, -26,
+ -90, -86, -41, 31, 98, 116, 104, 46, -38, -92, -95, -25, 46, 48, -6, -84,
+ -105, -55, 13, 84, 117, 114, 76, -20, -95, -105, -45, 41, 54, 8, -65, -112,
+ -70, -1, 65, 109, 115, 100, 14, -85, -106, -62, 21, 50, 13, -44, -104, -84,
+ -14, 45, 98, 112, 111, 53, -62, -105, -75, -3, 44, 12, -31, -85, -93, -27,
+ 27, 82, 110, 110, 81, -27, -95, -81, -27, 31, 11, -31, -66, -90, -39, 12,
+ 61, 106, 107, 94, 12, -73, -79, -48, 11, 13, -32, -57, -78, -46, -1, 38,
+ 97, 109, 96, 43, -41, -69, -62, -13, 13, -30, -58, -68, -46, -11, 17, 81,
+ 112, 97, 59, -7, -51, -67, -37, 6, -23, -62, -67, -42, -14, 2, 60, 110,
+ 99, 65, 20, -24, -63, -56, -7, -15, -63, -75, -40, -12, -8, 39, 102, 103,
+ 67, 35, 6, -48, -68, -25, -11, -56, -85, -46, -7, -10, 22, 86, 107, 72,
+ 41, 29, -25, -70, -42, -14, -42, -91, -62, -5, -6, 9, 67, 105, 84, 40,
+ 40, 3, -64, -56, -23, -30, -83, -85, -12, 3, 1, 50, 97, 96, 44, 36,
+ 28, -45, -69, -33, -22, -67, -101, -34, 13, 2, 31, 88, 104, 56, 28, 37,
+ -16, -71, -51, -18, -49, -103, -62, 9, 14, 18, 70, 109, 68, 26, 36, 6,
+ -58, -68, -23, -28, -97, -84, -7, 23, 19, 50, 106, 84, 28, 31, -21, -26,
+ -18, -30, -24, -77, -76, -48, -46, 31, 0, -1, 0, 0, 2, 0, 1, -2,
+ 1, 0, -6, -7, -5, -3, 0, -3, -4, -2, 2, 0, -8, -11, -14, -10,
+ -8, -4, 6, 13, 14, 9, 2, -6, -10, -9, -6, 9, 17, 15, 8, 0,
+ 1, -4, -12, -19, -14, -8, -4, 3, 6, -2, -4, -6, -7, -10, -8, -12,
+ -11, 3, 23, 27, 11, 4, -3, -5, 0, -9, -3, 6, 11, 19, 4, -8,
+ -17, -20, -21, -3, 5, 8, 2, 3, 5, 2, -3, -3, -12, 4, 1, 3,
+ -7, 0, 5, 6, 0, -7, -8, -5, -7, -5, -3, 4, 9, 5, -5, -5,
+ -5, -17, -7, 3, 17, 15, 7, -2, -5, -3, 3, -8, -5, -3, 3, 8,
+ 12, 5, -10, -27, -20, 1, 5, -4, -9, -17, 4, 10, 9, -2, -12, -16,
+ -12, -2, 8, 16, 13, 11, 16, 19, 10, -2, -16, -21, -11, 14, 15, 21,
+ 11, 6, -10, -8, -11, -24, -35, -31, -13, 9, 24, 17, -2, -11, -20, -11,
+ -19, -7, 3, 8, 22, 21, 21, 2, -7, -10, 12, 24, 18, -3, -19, -6,
+ 0, -5, -18, -17, 6, 12, 7, -16, -20, -22, -27, -19, -14, 12, 14, 3,
+ 0, 2, 8, -3, -5, -3, 21, 29, 17, 6, -8, 3, 3, 10, 10, 3,
+ 12, 4, -9, -18, -20, -20, -9, 6, 3, -9, -7, -14, -9, -8, -9, -23,
+ -19, 7, 17, 20, 9, 8, 5, 9, 18, 9, 8, -10, -10, -4, 9, 25,
+ -6, -19, -19, -5, -4, -7, -7, -17, -15, -7, -4, 0, 2, -2, -17, -4,
+ 14, 23, 15, 2, -7, -5, 9, 11, 1, 0, -3, 0, 0, 15, 14, -4,
+ -15, -20, -26, -22, -13, 0, 6, 12, 5, -10, 2, 8, -2, -18, -8, 6,
+ 20, 28, 23, 0, -16, -7, 9, 7, 10, -12, -21, -19, 7, 12, 4, -17,
+ -28, -24, -3, 14, 4, -19, -18, -9, 11, 22, 16, -13, -23, -15, 18, 32,
+ 32, 17, -4, 1, 14, 11, 1, -20, -19, -3, 9, 13, -4, -13, -16, -18,
+ -23, -12, -17, -16, -20, -15, -14, -4, 8, 12, 0, 8, 5, 12, 17, 26,
+ 25, 14, 10, 11, 11, 18, 15, 4, -9, -13, -8, -9, -14, -20, -28, -32,
+ -12, -9, -16, -17, -24, -18, -12, 5, 10, 4, 6, 8, 18, 35, 31, 17,
+ 1, 12, 21, 33, 18, 6, -10, -11, -4, -9, -13, -19, -24, -24, -24, -18,
+ -20, -18, -20, -13, -15, -10, -9, -5, 8, 10, 13, 23, 26, 29, 14, 13,
+ 13, 13, 16, 25, 19, 17, 4, -15, -18, -15, -14, -17, -34, -23, -16, -12,
+ -16, -26, -33, -23, -15, -4, 4, 10, 16, 19, 22, 29, 28, 7, 1, 2,
+ 18, 26, 30, 21, 9, 3, -4, -10, -16, -29, -31, -27, -4, -9, -11, -28,
+ -23, -17, -15, -13, -11, 4, 11, 9, 13, 16, 25, 18, 8, 10, 18, 17,
+ 8, 18, 17, 11, -5, -19, -17, -12, -19, -38, -27, -8, 0, -3, -14, -19,
+ -20, -14, -10, -13, -3, 6, 12, 26, 38, 34, 14, 2, -2, 11, 19, 14,
+ 8, 5, 16, 9, -7, -19, -24, -29, -36, -26, -13, -12, -22, -28, -20, 5,
+ -3, -10, -19, 7, 20, 18, 17, 24, 25, 14, 18, 19, 29, 21, 11, 10,
+ 9, 13, -13, -29, -27, -20, -24, -30, -22, -12, -7, -15, -22, -21, -13, -14,
+ -20, -8, 12, 26, 25, 21, 33, 27, 25, 16, 13, 16, 16, -2, 2, 11,
+ 9, -2, -17, -18, -16, -25, -25, -26, -27, -30, -35, -30, -12, -6, -6, -6,
+ -5, 19, 19, 11, 15, 17, 24, 23, 34, 28, 23, 13, 2, 9, 18, 16,
+ -14, -18, -12, -7, -9, -31, -37, -33, -24, -14, -24, -20, -16, -21, -15, -7,
+ 5, 9, 15, 20, 28, 38, 29, 21, 15, 22, 17, 4, 12, 6, 12, -4,
+ -9, -15, -16, -19, -40, -38, -34, -23, -18, -17, -8, -10, -3, -7, 1, 3,
+ 4, 11, 13, 36, 41, 36, 24, 9, 17, 20, 21, 14, -5, -9, -11, -8,
+ -19, -14, -24, -30, -23, -18, -25, -30, -24, -17, -20, -9, -3, 6, 8, 22,
+ 23, 20, 27, 18, 10, 10, 14, 18, 14, 23, 17, 6, 5, -4, -8, -26,
+ -19, -24, -25, -24, -21, -27, -28, -15, -19, -16, -9, 0, 7, 9, 17, 14,
+ 15, 24, 30, 29, 29, 32, 16, 10, 8, 0, -3, -10, -7, -17, -22, -25,
+ -30, -36, -32, -25, -26, -22, -12, -16, -11, -3, 5, 7, 13, 21, 21, 26,
+ 32, 28, 26, 28, 31, 17, 15, 15, 5, -4, -14, -18, -28, -25, -24, -28,
+ -32, -33, -32, -29, -18, -17, -20, -10, -4, 6, 6, 18, 22, 22, 37, 38,
+ 31, 27, 26, 23, 22, 23, 12, 4, -5, -2, -11, -19, -25, -35, -35, -36,
+ -36, -43, -32, -24, -20, -12, -7, -3, -7, 3, 13, 23, 29, 35, 37, 35,
+ 42, 33, 26, 22, 17, 12, 6, 4, -9, -23, -28, -34, -34, -33, -31, -40,
+ -36, -27, -25, -22, -30, -20, -11, 2, 12, 22, 22, 26, 28, 35, 47, 44,
+ 27, 29, 29, 29, 19, 2, 1, -9, -15, -21, -34, -35, -34, -40, -44, -42,
+ -34, -31, -26, -21, -9, -12, -3, 10, 17, 29, 26, 27, 34, 48, 50, 34,
+ 33, 25, 21, 16, 8, 3, -8, -11, -25, -30, -37, -37, -42, -51, -34, -28,
+ -21, -26, -25, -19, -13, 4, 9, 17, 29, 41, 33, 33, 44, 45, 32, 31,
+ 28, 22, 16, 5, -10, -13, -16, -23, -38, -39, -39, -45, -54, -40, -32, -24,
+ -22, -17, -14, 0, 6, 9, 18, 41, 43, 34, 32, 40, 40, 31, 30, 27,
+ 22, 19, 14, -2, -16, -21, -34, -48, -45, -41, -41, -41, -45, -38, -25, -21,
+ -17, -20, -7, 11, 17, 19, 36, 40, 42, 44, 47, 46, 39, 33, 26, 15,
+ 11, 8, -5, -19, -24, -29, -40, -44, -48, -44, -37, -37, -43, -43, -26, -19,
+ -14, -2, 13, 23, 31, 36, 36, 43, 41, 47, 46, 44, 40, 24, 15, 14,
+ 3, -12, -21, -23, -30, -36, -47, -51, -50, -47, -44, -46, -31, -19, -16, -11,
+ 2, 16, 20, 25, 29, 40, 53, 51, 49, 45, 41, 35, 25, 18, 7, 5,
+ -12, -18, -23, -34, -39, -56, -58, -54, -49, -50, -45, -35, -26, -12, -5, 6,
+ 17, 29, 41, 42, 47, 50, 46, 49, 50, 50, 39, 30, 16, 2, -8, -15,
+ -21, -30, -41, -49, -50, -46, -57, -63, -57, -41, -29, -24, -12, -3, 5, 12,
+ 22, 33, 41, 50, 51, 53, 57, 55, 46, 36, 29, 16, 2, -4, -11, -21,
+ -33, -40, -49, -47, -53, -60, -58, -51, -42, -34, -23, -13, -2, 5, 17, 27,
+ 39, 49, 48, 51, 56, 54, 58, 44, 37, 28, 18, 4, -3, -15, -29, -39,
+ -49, -49, -51, -62, -65, -64, -47, -42, -36, -26, -14, -5, 10, 24, 32, 45,
+ 50, 49, 62, 65, 63, 47, 42, 41, 36, 23, 7, -7, -22, -31, -41, -53,
+ -58, -62, -59, -62, -56, -54, -50, -44, -32, -16, 0, 11, 25, 35, 50, 54,
+ 55, 56, 66, 65, 62, 54, 45, 36, 23, 14, -4, -22, -44, -55, -52, -62,
+ -61, -66, -70, -68, -60, -54, -45, -29, -15, 4, 21, 34, 36, 44, 54, 62,
+ 70, 73, 68, 67, 59, 50, 37, 21, -5, -12, -25, -39, -48, -53, -63, -76,
+ -73, -71, -71, -67, -57, -45, -29, -12, 2, 13, 30, 42, 51, 61, 76, 71,
+ 63, 66, 71, 60, 50, 40, 23, -2, -9, -20, -41, -54, -59, -72, -79, -71,
+ -64, -73, -68, -60, -51, -36, -13, 2, 13, 27, 47, 54, 71, 78, 71, 60,
+ 72, 74, 65, 54, 39, 28, 7, -6, -23, -50, -59, -64, -69, -75, -70, -78,
+ -74, -73, -64, -52, -37, -13, 6, 18, 40, 51, 58, 64, 78, 79, 75, 68,
+ 64, 68, 57, 45, 21, 4, -16, -34, -50, -65, -75, -83, -80, -71, -69, -68,
+ -73, -63, -57, -36, -16, 6, 26, 45, 60, 70, 71, 79, 79, 81, 78, 80,
+ 64, 55, 36, 16, -4, -23, -38, -54, -63, -69, -81, -85, -87, -76, -72, -66,
+ -61, -52, -30, -12, 12, 24, 44, 55, 69, 78, 85, 84, 74, 70, 71, 71,
+ 62, 41, 17, -11, -25, -42, -55, -66, -75, -87, -87, -81, -74, -76, -76, -63,
+ -48, -32, -13, 7, 30, 51, 64, 76, 80, 82, 83, 81, 80, 82, 70, 61,
+ 42, 19, 0, -28, -49, -61, -72, -78, -87, -90, -89, -88, -87, -82, -69, -54,
+ -33, -13, 15, 36, 58, 68, 79, 90, 96, 90, 84, 86, 89, 79, 62, 38,
+ 22, -3, -29, -55, -69, -81, -89, -94, -94, -94, -94, -89, -74, -62, -52, -35,
+ -18, 14, 39, 54, 65, 76, 87, 98, 95, 94, 90, 82, 75, 69, 47, 26,
+ -6, -33, -57, -72, -82, -88, -97, -90, -91, -88, -83, -80, -75, -59, -33, -9,
+ 20, 42, 58, 68, 82, 90, 94, 93, 94, 88, 85, 77, 65, 43, 16, -10,
+ -37, -60, -71, -84, -89, -95, -97, -102, -95, -84, -80, -72, -57, -26, -4, 19,
+ 42, 62, 80, 89, 94, 97, 100, 99, 90, 83, 71, 65, 39, 14, -9, -43,
+ -65, -83, -90, -95, -98, -96, -100, -96, -88, -76, -66, -51, -24, -12, 21, 45,
+ 70, 85, 93, 95, 97, 101, 105, 92, 84, 69, 58, 35, 16, -14, -44, -68,
+ -86, -88, -96, -101, -101, -102, -97, -90, -74, -69, -50, -19, 9, 35, 56, 76,
+ 84, 92, 98, 96, 99, 97, 93, 84, 77, 59, 24, 2, -30, -52, -76, -87,
+ -93, -98, -100, -102, -100, -96, -89, -81, -73, -46, -18, 12, 36, 62, 82, 88,
+ 96, 104, 107, 105, 102, 92, 84, 77, 53, 26, -6, -35, -57, -75, -81, -92,
+ -103, -114, -111, -108, -98, -88, -83, -67, -35, -7, 20, 39, 60, 70, 89, 106,
+ 116, 107, 103, 99, 86, 90, 82, 53, 18, -13, -31, -52, -73, -92, -102, -106,
+ -104, -97, -106, -99, -101, -92, -72, -42, -5, 16, 38, 66, 86, 101, 99, 101,
+ 95, 112, 107, 99, 95, 81, 53, 16, -3, -29, -60, -81, -102, -98, -102, -102,
+ -112, -114, -101, -104, -88, -69, -34, -8, 14, 41, 67, 92, 94, 99, 103, 104,
+ 115, 109, 103, 90, 78, 52, 22, 0, -39, -65, -92, -95, -91, -103, -104, -118,
+ -110, -102, -93, -84, -71, -36, -15, 19, 52, 81, 94, 89, 98, 103, 115, 117,
+ 102, 92, 83, 80, 49, 23, -11, -43, -67, -90, -93, -102, -105, -110, -118, -104,
+ -100, -89, -83, -64, -36, -7, 28, 50, 74, 88, 95, 104, 103, 115, 107, 106,
+ 97, 87, 74, 50, 20, -17, -47, -75, -89, -93, -101, -102, -115, -117, -106, -97,
+ -88, -90, -73, -38, 2, 36, 60, 75, 84, 96, 104, 115, 115, 102, 98, 96,
+ 96, 84, 52, 10, -12, -32, -53, -71, -87, -101, -109, -112, -109, -106, -105, -102,
+ -92, -74, -48, -19, 7, 33, 56, 76, 91, 101, 108, 111, 111, 108, 103, 96,
+ 85, 63, 33, 1, -27, -51, -73, -90, -102, -109, -112, -110, -107, -103, -100, -93,
+ -76, -50, -19, 10, 36, 58, 76, 91, 101, 108, 111, 111, 108, 103, 96, 85,
+ 63, 33, 1, -27, -51, -73, -90, -102, -109, -112, -110, -107, -103, -100, -93, -76,
+ -50, -19, 10, 36, 58, 76, -1, -2, -15, 21, -17, 23, -30, 1, 34, -34,
+ 6, 5, -15, 19, 1, -25, 6, 20, -2, -28, 15, 10, -15, 0, -7, 10,
+ 7, -5, -9, -6, 19, -3, -21, 3, 20, -4, -20, 1, 16, -3, -8, -2,
+ 5, 1, -8, -6, 3, 9, 2, -13, -4, 15, -7, -9, 0, 3, 6, -7,
+ -7, 5, 8, -8, -4, 0, 1, 1, -6, -4, 7, 2, -2, -7, 0, 4,
+ -3, -4, 0, 2, 0, -2, -4, 1, 4, -2, -4, -3, 1, 3, -5, -4,
+ 4, 3, -6, -5, 4, -1, -2, -3, 0, 3, -3, -1, -4, 3, 3, -5,
+ -3, 1, 1, -2, -3, 1, 2, -2, -4, 0, 0, 0, -1, -3, 1, 1,
+ -3, -2, 1, 0, -2, -2, 0, 0, -2, -1, 0, -1, 1, -2, -2, 1,
+ 0, -2, 0, -1, 0, -1, -1, -1, 0, 0, -1, -3, 1, 1, -2, -2,
+ 0, 1, -1, -2, -1, 0, 0, 0, -2, -1, 1, 0, -3, 0, 2, -1,
+ -2, 0, 0, 0, -2, 0, -1, 0, -1, -1, 1, 0, -1, 0, -1, 1,
+ 0, -13, 5, 7, -11, 24, -50, 41, 4, -29, 14, -11, 8, 11, -15, -12,
+ 15, 18, -21, -14, 22, -2, -11, -3, -3, 18, -3, -5, -14, 9, 22, -24,
+ -16, 23, 12, -23, -8, 9, 10, -4, -8, -3, 11, -4, -14, 0, 8, 8,
+ -5, -14, 8, 10, -12, -4, -2, 10, 0, -11, -3, 11, 0, -7, -2, -1,
+ 7, -6, -8, 3, 6, 0, -3, -8, 7, 2, -7, -2, 2, 1, -2, -4,
+ -1, 3, 3, -4, -5, 1, 3, -3, -6, 2, 5, -1, -7, -1, 3, -1,
+ -4, -3, 5, 0, -3, -2, -1, 4, -1, -5, -1, 3, -1, -4, -1, 3,
+ 1, -4, -2, 1, 0, -2, -3, 0, 2, -1, -4, 1, 1, -1, -2, -2,
+ 1, -1, -3, 0, 0, 0, -1, -2, 0, 0, -2, -1, 0, -1, 0, -2,
+ -1, 0, -1, 0, -1, -2, 2, -1, -2, -1, 0, 1, -2, 0, -1, -1,
+ 0, -1, -2, 0, 1, -1, -3, 0, 1, -1, -3, 0, 1, -2, -1, 0,
+ 0, -1, -1, 0, -1, -1, -1, -1, 0, 0, -1, -1, 0, 0, -2, 0,
+ 0, 0, 0, -2, 1, -1, 0, -1, 0, 0, 0, -1, 0, 0, 0, 0,
+ -1, 0, 0, -1, 0, -1, 1, 0, 0, 0, 1, -1, -1, 0, 0, 0,
+ 1, -2, 4, -3, 3, -40, 71, -73, 67, -27, -68, 127, -80, 3, 5, 1,
+ 17, -14, 1, -30, 53, -3, -42, 15, 19, -9, -17, -1, 13, 16, -17, 4,
+ -32, 43, 15, -68, 18, 54, -38, -7, -1, 11, 7, -3, -18, 5, 25, -27,
+ -9, 9, 19, -6, -12, -8, 20, -1, -15, -1, 1, 17, -10, -16, 12, 12,
+ -13, 0, -6, 10, 2, -16, -1, 14, -4, 4, -11, -2, 12, -6, -8, 4,
+ 4, -2, -4, 1, -2, 4, 3, -7, -5, 8, 0, -10, 1, 4, 2, -4,
+ -6, 4, 1, -1, -7, 1, 8, -9, 2, -5, 3, 3, -4, -3, 0, 3,
+ -3, -5, 4, 3, -3, -4, 0, 2, 0, -3, -4, 5, 0, -5, -1, 2,
+ 0, -3, 0, -1, 2, -2, -4, 3, 0, -1, -2, -1, 2, -2, -2, 1,
+ -1, 0, -1, -3, 1, 1, -2, 1, -3, 1, 1, -3, -1, 1, 0, -1,
+ -2, 1, -1, -1, 1, -2, 1, -1, -1, -1, -1, 0, 1, -3, 0, 0,
+ 1, -4, 0, 1, -2, 0, -2, 0, 0, 0, -2, 1, -1, 0, -2, 0,
+ 2, -2, -1, 0, -1, 2, -2, -1, 1, -2, 0, -1, 1, -1, -1, -1,
+ 1, -2, 1, -1, -1, 2, -3, 0, 0, -1, 1, -1, 0, 1, 0, -2,
+ 0, -1, 1, -2, 0, 0, -1, 1, 0, -2, 0, 1, -2, 1, 0, 0,
+ -1, 0, 1, -1, -1, -1, 1, 1, -1, 0, 0, 0, -1, 1, 0, -1,
+ 1, 0, 0, 1, 0, -1, 1, 0, 3, -40, 58, -39, 12, 42, -117, 108,
+ 1, -66, 22, 17, 0, -9, 10, -39, 42, 4, -23, -12, 28, 3, -34, 9,
+ 17, 3, -9, 10, -29, 13, 53, -79, 3, 64, -26, -24, 16, -9, 14, 2,
+ -8, -15, 31, -9, -30, 11, 29, -15, -7, 0, 3, 6, -4, -9, -6, 22,
+ 1, -24, 9, 11, -8, 0, -2, 2, 8, -12, -6, 10, 2, 2, -9, -4,
+ 11, -2, -10, 3, 2, 3, -5, -1, 1, -1, 6, -4, -8, 9, 2, -8,
+ -3, 6, 3, -4, -3, -1, 6, -2, -8, 0, 9, -4, -3, -2, 2, 4,
+ -4, -1, -1, 4, -2, -6, 4, 2, -1, -4, 0, 1, 2, -3, -5, 3,
+ 3, -3, -4, 3, 0, -1, 0, -2, 2, 0, -3, 0, 3, 0, -3, -1,
+ 2, 0, -3, 1, 0, -1, 2, -2, -2, 2, -1, 0, -1, -1, 1, -1,
+ -2, 0, 0, 1, -3, 1, 0, -1, 1, -2, -1, 2, -2, -1, 0, -1,
+ 2, -3, -1, 1, 1, -2, -2, 2, 1, -2, -1, 0, 0, 1, -3, 1,
+ 0, 0, 0, -2, 3, 0, -2, 0, 0, 1, 0, -1, 1, -2, 0, 0,
+ 0, -1, 1, 0, 0, 0, -1, 1, -1, 1, 0, -1, 1, -2, 0, 1,
+ 1, 0, 1, -2, 1, 0, 1, 0, 0, 3, -1, 0, 1, 0, 0, 3,
+ -29, 35, -12, -16, 56, -88, 39, 62, -79, 5, 29, 1, -13, 12, -29, 26,
+ 17, -28, -3, 12, 5, -11, -19, 28, 1, -5, 9, -21, -7, 60, -56, -20,
+ 57, -10, -27, 21, -21, 16, 12, -12, -21, 24, 6, -29, 4, 19, 2, -7,
+ -5, -3, 7, 6, -11, -9, 11, 13, -18, -4, 13, 1, -3, -6, -1, 10,
+ -8, -6, 5, 3, 5, -3, -11, 4, 9, -11, 0, 4, 3, -4, -1, 0,
+ 0, 7, 0, -14, 7, 5, -7, -4, 4, 5, -1, -4, -4, 4, 1, -4,
+ -4, 7, -1, -1, -3, 0, 5, -1, -4, -1, 2, 0, -3, 1, 1, 2,
+ -2, -4, 1, 2, 0, -5, 2, 3, -2, -2, 1, 1, -2, 2, -3, 0,
+ 0, -1, -1, 0, 1, 0, -3, 0, 0, -1, 1, -1, -2, 1, -1, 0,
+ -2, 2, 1, -2, -1, 1, 0, -1, -1, 0, 1, -1, 0, -2, 1, 1,
+ -1, 0, -1, -1, 0, 0, -1, -1, 0, -1, -1, 2, -2, -1, 1, 0,
+ 0, -1, -1, 1, 0, -1, 1, -1, 0, 1, -3, 1, 1, -1, -1, 0,
+ 1, 0, 0, 0, -1, 0, 0, -1, 0, 1, 0, 0, 2, -2, 0, 1,
+ 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, -1, -1, -7, -9, 35, -52,
+ 59, -33, -32, 64, -15, -41, 19, 22, -20, 9, -11, -3, 33, -27, 2, 7,
+ -9, 19, -37, 24, 7, -11, 11, -1, -30, 37, 8, -57, 36, 19, -33, 14,
+ 0, -17, 26, 1, -20, -5, 26, -18, -13, 14, 7, -6, 4, -9, -4, 11,
+ 3, -14, -7, 20, 0, -18, 10, 1, 4, -5, -7, 6, 0, -3, -2, -2,
+ 8, 5, -11, -6, 10, -1, -10, 6, -2, -1, 1, -3, 0, 3, 5, -9,
+ -5, 9, -3, -4, 1, 1, 3, -1, -4, -1, 2, -2, -5, 5, -3, 0,
+ 1, -5, 4, 2, -3, -3, 0, 0, -2, 1, 0, -2, 3, -2, -5, 2,
+ 2, -2, -4, 3, 0, -2, 1, -2, -2, 5, -2, -6, 1, 2, -1, -1,
+ 0, 1, -1, -2, -1, -1, 2, 0, -4, 0, 1, 0, -3, 0, 2, 0,
+ -3, 0, 0, 1, -1, -1, 1, 0, -1, -2, 1, 0, 0, -1, 0, -2,
+ 1, 0, -1, 1, -1, 0, -2, 1, 1, -2, -1, 2, -2, 1, -3, 1,
+ 1, -1, 0, 0, -1, 1, 0, -2, 2, -1, -1, 0, 0, 1, 0, 1,
+ 0, -2, 1, 0, 0, -1, 1, 0, 0, 0, 0, -3, -20, 45, -56, 40,
+ -5, -34, 27, 24, -42, -1, 29, -14, -4, 2, -7, 24, -20, -1, 18, -25,
+ 25, -29, 9, 21, -26, 14, 4, -20, 7, 27, -42, 5, 31, -24, -2, 19,
+ -30, 21, 8, -11, -17, 20, 1, -22, 11, 7, -7, 6, -5, -7, 3, 11,
+ -6, -18, 11, 16, -20, 1, 5, 2, -3, -3, 0, -3, 4, -1, -7, 2,
+ 10, -9, -8, 7, 2, -9, 5, -1, -5, 2, 1, -3, -2, 9, -5, -8,
+ 4, 1, -5, 0, 1, 2, -1, 0, -5, 4, -1, -5, 4, -3, 1, 1,
+ -5, 3, 0, 0, -3, 0, -1, -2, 1, 2, -5, 2, 1, -5, -2, 3,
+ -1, -5, 2, 1, -4, 2, -1, -4, 2, 3, -7, -1, 2, 0, -2, 1,
+ 0, -2, -1, 0, -3, 1, 2, -3, -2, 3, 0, -3, -1, 1, 0, -1,
+ -2, -1, 1, 0, 0, -1, 0, 0, -2, 0, 0, 1, -2, 2, -3, 1,
+ 0, 0, -2, 1, 0, -1, 0, 0, -1, -1, 2, -3, 0, 0, -1, 0,
+ 0, -1, 1, 0, -4, -13, 32, -41, 31, -10, -10, 4, 22, -25, -8, 21,
+ -3, -14, 5, 1, 12, -23, 8, 18, -31, 25, -26, 10, 17, -23, 8, 5,
+ -9, 0, 16, -25, 2, 23, -22, -2, 22, -30, 15, 7, -6, -13, 12, 1,
+ -17, 9, 5, -6, 4, -3, -7, 5, 7, -6, -13, 7, 10, -11, 0, 0,
+ 4, -3, -3, 2, -7, 4, 2, -5, 0, 6, -3, -8, 4, 2, -8, 7,
+ 0, -8, -1, 6, 0, -8, 6, 0, -5, 1, 0, -5, 3, 2, -3, -2,
+ 4, -5, -1, -1, -2, 3, -4, 1, -1, -3, 3, -1, -2, -2, 1, -2,
+ -2, 1, 1, -4, 1, 2, -5, -3, 5, -3, -4, 4, -1, -4, 2, -1,
+ -4, 3, 1, -5, -2, 2, 0, -2, 2, -1, -4, 3, -1, -3, 0, 1,
+ -2, -2, 1, -1, -1, -1, 0, 0, -1, -1, -1, 0, -1, 1, -1, -1,
+ 0, -2, 1, 0, -1, -1, 0, -1, -1, -1, 2, -2, -1, 1, -1, -2,
+ 1, -1, -1, 1, -2, 1, -7, -3, 15, -23, 20, -16, 9, -12, 16, -12,
+ -8, 11, 5, -18, 6, 8, 0, -18, 16, 4, -19, 16, -17, 10, 5, -8,
+ -2, 9, -5, -4, 10, -17, 5, 13, -18, 2, 12, -17, 10, 0, -2, -8,
+ 7, -4, -7, 6, 1, -3, 1, 3, -9, -2, 10, -7, -8, 4, 6, -6,
+ 1, 0, 0, -2, 1, -1, -8, 6, 1, -5, 2, 4, -2, -4, 1, 1,
+ -7, 5, -1, -4, -2, 4, 0, -4, 4, -3, -4, 1, 0, -3, 0, 2,
+ -1, -2, 2, -2, -1, -3, 0, 3, -4, 3, -3, 0, 2, 0, -3, -1,
+ 1, -3, -1, 2, 0, -1, 0, 0, -3, 0, 1, -4, -1, 2, 0, -2,
+ 0, 1, -3, 1, 1, -3, -2, 2, -1, -1, 2, -1, -2, 1, 0, -1,
+ -1, -1, -3, -8, -16, -20, -7, 14, 20, 19, 18, 16, 11, 3, -9, -21,
+ -36, -43, -39, -24, 6, 38, 57, 55, 26, 0, -7, -10, -13, -12, -11, -29,
+ -56, -59, -37, 0, 43, 74, 87, 75, 37, -2, -31, -51, -59, -45, -15, -16,
+ -34, -20, -10, -5, 29, 61, 72, 51, 18, -2, -21, -39, -35, -24, 1, 0,
+ -31, -29, -23, -44, -13, 48, 82, 79, 46, 16, -4, -44, -58, -26, 3, 6,
+ -38, -52, -24, -42, -35, 47, 95, 88, 55, 19, 12, -22, -72, -38, 4, 3,
+ -31, -67, -29, -24, -60, 23, 112, 111, 72, 22, 7, -20, -90, -73, -1, 19,
+ -4, -57, -36, 3, -54, -32, 98, 125, 71, 14, 14, 0, -82, -106, 0, 42,
+ 10, -48, -32, -2, -54, -63, 72, 125, 82, 24, 14, -8, -57, -104, -22, 52,
+ 34, -34, -46, -16, -35, -83, 32, 127, 99, 26, 19, 4, -55, -110, -48, 45,
+ 36, -12, -26, -22, -41, -64, -7, 107, 113, 56, 6, 4, -41, -92, -74, 35,
+ 57, 12, -41, -21, -39, -67, -40, 86, 114, 71, 10, 22, -31, -83, -83, 16,
+ 46, 34, -28, -18, -42, -58, -60, 55, 108, 97, 3, 21, -8, -77, -102, 10,
+ 45, 42, -26, -2, -27, -68, -73, 45, 83, 92, 29, 25, -8, -56, -104, -13,
+ 35, 52, -6, -7, -22, -46, -91, 10, 80, 95, 35, 26, 8, -38, -106, -34,
+ 34, 42, 5, 1, -23, -39, -73, -28, 61, 89, 60, 20, 2, -7, -73, -86,
+ 24, 52, 26, -12, -11, -19, -58, -86, 46, 91, 62, 17, 22, -15, -39, -106,
+ 8, 55, 45, -13, -6, -30, -21, -102, 4, 82, 87, 7, 28, -3, -9, -115,
+ -32, 50, 63, -23, 8, -19, -18, -94, -28, 61, 96, 14, 39, -4, 1, -85,
+ -60, 23, 79, -3, 2, -20, -10, -82, -65, 25, 108, 28, 31, 19, 9, -65,
+ -74, -5, 78, 16, -3, -9, -14, -65, -76, -3, 93, 60, 29, 22, 13, -43,
+ -90, -30, 61, 49, -9, -1, 4, -52, -98, -16, 68, 72, 21, 38, 15, -31,
+ -94, -34, 32, 67, 5, 9, 0, -28, -111, -33, 40, 85, 24, 37, 23, -6,
+ -104, -44, 13, 69, 9, 14, 8, -11, -110, -53, 20, 80, 32, 48, 30, 5,
+ -87, -66, -7, 63, 33, 12, 2, 5, -86, -94, -2, 79, 46, 26, 44, 22,
+ -59, -88, -19, 54, 48, 13, 14, 4, -51, -112, -37, 67, 71, 21, 38, 29,
+ -29, -104, -50, 44, 63, 11, 10, 14, -24, -103, -67, 49, 88, 20, 27, 43,
+ -10, -90, -79, 24, 69, 21, 7, 18, -8, -82, -103, 17, 94, 38, 10, 54,
+ 12, -70, -97, 1, 68, 37, -4, 27, -6, -56, -104, -21, 82, 67, -3, 46,
+ 23, -37, -108, -31, 57, 58, -13, 29, 11, -32, -106, -50, 53, 92, -6, 38,
+ 38, -15, -105, -54, 34, 79, -12, 20, 22, -11, -98, -70, 22, 99, 4, 16,
+ 48, 14, -99, -75, 15, 82, 2, 0, 44, 8, -93, -80, 0, 84, 29, -3,
+ 57, 32, -79, -94, 1, 66, 27, -19, 49, 29, -73, -109, -7, 54, 52, -17,
+ 62, 53, -46, -113, -4, 43, 51, -30, 46, 37, -42, -128, -23, 26, 69, -18,
+ 51, 59, -2, -122, -30, 24, 66, -27, 31, 51, 1, -128, -48, 13, 71, -11,
+ 33, 66, 22, -110, -57, 8, 68, -9, 12, 53, 28, -104, -87, -4, 67, 8,
+ 8, 72, 53, -80, -91, -4, 59, 10, -13, 63, 44, -81, -109, -19, 46, 33,
+ -6, 76, 57, -43, -104, -24, 36, 42, -26, 55, 51, -34, -126, -39, 19, 58,
+ -21, 68, 71, -8, -114, -32, 2, 62, -24, 52, 54, -4, -120, -53, -22, 71,
+ -8, 49, 62, 31, -102, -52, -25, 70, -5, 24, 55, 35, -109, -69, -40, 59,
+ 16, 25, 65, 55, -80, -70, -37, 47, 23, 7, 48, 51, -73, -97, -48, 30,
+ 46, 6, 57, 74, -37, -98, -34, 21, 48, -10, 44, 58, -34, -123, -46, -2,
+ 61, 2, 50, 69, 10, -110, -40, -5, 59, -9, 31, 53, 19, -126, -59, -20,
+ 62, 8, 32, 64, 49, -105, -59, -16, 58, 2, 17, 50, 45, -102, -83, -31,
+ 46, 24, 15, 53, 69, -65, -86, -24, 42, 25, -4, 45, 64, -58, -112, -37,
+ 30, 41, -6, 51, 75, -24, -105, -32, 26, 41, -19, 39, 62, -14, -117, -51,
+ 7, 54, -13, 35, 78, 19, -105, -47, 9, 58, -19, 21, 69, 18, -113, -66,
+ -10, 52, -10, 14, 75, 42, -83, -60, -5, 52, 0, -3, 69, 43, -83, -83,
+ -21, 35, 17, -13, 72, 57, -54, -82, -10, 29, 28, -29, 65, 52, -45, -98,
+ -21, 1, 40, -30, 64, 63, -7, -94, -9, 1, 51, -36, 51, 54, -8, -115,
+ -23, -22, 47, -30, 48, 65, 24, -90, -13, -15, 46, -26, 30, 55, 21, -100,
+ -37, -26, 31, -10, 24, 65, 41, -71, -35, -10, 25, -2, 4, 58, 32, -69,
+ -61, -16, 2, 8, 1, 67, 42, -33, -56, -1, -1, 20, -13, 59, 33, -28,
+ -82, -10, -20, 22, -15, 64, 40, -1, -70, 0, -17, 29, -22, 53, 33, 1,
+ -84, -15, -29, 22, -19, 53, 43, 22, -64, -7, -19, 25, -18, 37, 38, 16,
+ -73, -30, -33, 11, -14, 32, 50, 31, -45, -17, -15, 16, -4, 16, 43, 23,
+ -49, -43, -30, -2, -1, 8, 52, 36, -25, -32, -13, -1, 11, -1, 42, 30,
+ -25, -49, -25, -18, 10, -7, 44, 40, -2, -34, -11, -15, 21, -6, 29, 33,
+ -5, -54, -29, -30, 13, -6, 29, 46, 15, -32, -10, -18, 16, -1, 13, 36,
+ 9, -45, -30, -32, 0, 1, 12, 43, 28, -23, -16, -16, 6, 9, 2, 33,
+ 22, -33, -34, -27, -11, 2, 1, 35, 36, -14, -16, -11, -5, 8, 3, 24,
+ 32, -19, -30, -29, -17, -4, 1, 20, 43, -5, -14, -13, -4, 0, 7, 11,
+ 39, -9, -23, -28, -17, -16, 1, 9, 44, 3, -7, -15, -4, -4, 7, 5,
+ 38, 3, -20, -30, -19, -19, -8, 0, 40, 17, -6, -7, -3, -2, -1, 4,
+ 32, 16, -20, -21, -26, -17, -18, -3, 28, 32, -7, -1, -9, 4, -9, 3,
+ 22, 34, -19, -14, -27, -13, -27, -10, 16, 44, -8, 5, -6, 3, -12, 1,
+ 13, 40, -12, -11, -25, -17, -27, -15, 5, 45, 4, 2, 0, 0, -9, -5,
+ 6, 38, 2, -17, -14, -20, -24, -23, 0, 38, 19, -4, 11, -4, -7, -10,
+ 4, 27, 20, -20, -9, -23, -22, -30, -6, 26, 35, -8, 12, 2, -4, -15,
+ 2, 20, 32, -16, -7, -15, -22, -37, -14, 18, 39, -3, 5, 8, -5, -18,
+ -2, 18, 34, -4, -14, -4, -21, -35, -25, 15, 36, 8, -4, 21, -5, -17,
+ -14, 23, 26, 9, -22, 4, -25, -32, -40, 14, 27, 24, -12, 30, 1, -8,
+ -26, 24, 21, 19, -28, 9, -20, -28, -51, 7, 23, 30, -15, 27, 9, -7,
+ -32, 16, 25, 23, -21, 4, -8, -27, -50, -10, 25, 29, -9, 13, 24, -7,
+ -28, -3, 34, 20, -12, -9, 10, -31, -43, -29, 30, 23, 2, -3, 38, -9,
+ -19, -19, 39, 18, -1, -20, 25, -29, -36, -42, 26, 17, 12, -14, 43, -3,
+ -15, -29, 35, 19, 6, -28, 27, -18, -36, -48, 16, 17, 15, -15, 39, 12,
+ -13, -29, 24, 24, 9, -25, 19, -1, -39, -50, 1, 18, 11, -11, 25, 26,
+ -14, -26, 12, 32, 10, -17, 6, 17, -33, -48, -14, 20, 6, -7, 11, 36,
+ -9, -26, -1, 34, 11, -9, -4, 25, -25, -49, -26, 19, 4, -4, 5, 41,
+ 3, -21, -8, 31, 12, -7, -11, 23, -13, -47, -37, 13, 6, -3, 1, 40,
+ 14, -17, -14, 26, 16, -2, -12, 20, -3, -40, -44, 2, 6, -2, -4, 35,
+ 24, -9, -19, 19, 17, 2, -13, 16, 5, -29, -48, -7, 4, 3, -7, 28,
+ 28, 2, -21, 13, 14, 9, -14, 11, 9, -15, -49, -17, -3, 6, -11, 20,
+ 30, 14, -23, 7, 12, 14, -11, 6, 10, -4, -46, -24, -10, 6, -8, 11,
+ 29, 24, -15, 0, 11, 14, -4, -2, 11, 3, -37, -36, -13, -3, -2, 2,
+ 28, 27, -2, -10, 14, 9, 7, -8, 13, 3, -21, -42, -14, -14, 4, -6,
+ 24, 24, 13, -16, 12, 3, 14, -8, 12, 4, -7, -44, -18, -20, 5, -6,
+ 18, 22, 23, -13, 6, 2, 13, -4, 5, 5, 1, -36, -26, -20, -1, -1,
+ 10, 23, 25, -3, -4, 5, 9, 5, -2, 8, 1, -24, -36, -18, -10, 4,
+ 1, 24, 23, 11, -9, 8, 4, 12, -7, 9, 1, -12, -40, -19, -16, 4,
+ -4, 21, 21, 16, -9, 6, 2, 13, -4, 6, 6, -4, -33, -24, -18, -2,
+ -2, 10, 21, 18, 0, -3, 3, 8, 6, -1, 8, 0, -18, -31, -19, -10,
+ 1, 0, 19, 20, 13, -5, 4, 5, 12, -4, 5, 2, -7, -34, -24, -17,
+ 1, -4, 13, 20, 21, -3, 2, 5, 14, 0, 2, 4, 0, -26, -28, -20,
+ -6, -4, 4, 18, 23, 6, -3, 5, 9, 7, -1, 6, 3, -14, -33, -22,
+ -14, -1, -1, 16, 22, 17, -4, 4, 4, 10, -2, 4, 3, -4, -30, -25,
+ -19, -2, -2, 11, 20, 23, 0, 0, 2, 10, 3, 1, 4, 1, -23, -30,
+ -22, -8, -1, 4, 19, 23, 10, -3, 4, 6, 8, -2, 5, 2, -13, -33,
+ -23, -15, 0, -1, 16, 21, 16, -3, 3, 4, 11, 0, 5, 6, -3, -27,
+ -25, -19, -4, -2, 9, 19, 19, 2, -3, 2, 8, 6, -1, 8, 0, 0,
+ 2, 33, 42, 58, 71, 79, 85, 88, 91, 94, 79, 95, 82, 106, 86, 105,
+ 47, 16, -6, 13, 44, 31, -15, -38, -36, 20, 70, 41, 48, 58, 24, -57,
+ -127, -119, -102, -126, -128, -111, -78, -82, -88, -87, -60, -66, -98, -104, -99, -97,
+ -99, -104, -101, -88, -87, -91, -61, -27, -34, -54, -55, -45, -24, -10, -5, -4,
+ 5, 34, 63, 101, 94, 78, 52, 51, 52, 74, 81, 77, 59, 46, 17, 7,
+ 39, 53, 47, 42, 66, 83, 73, 52, 28, 22, 11, 8, 11, 0, -15, -23,
+ -15, -14, -6, 16, 46, 62, 71, 76, 90, 102, 103, 103, 101, 100, 90, 75,
+ 63, 67, 49, 37, 28, 12, 5, 6, 15, 15, 8, -7, -12, -4, -10, -28,
+ -24, -17, -25, -50, -64, -81, -103, -116, -116, -113, -95, -72, -54, -41, -47, -65,
+ -65, -50, -33, -24, -7, 11, 8, -4, -13, -28, -51, -75, -90, -91, -90, -90,
+ -87, -88, -83, -84, -82, -81, -81, -76, -65, -71, -85, -84, -79, -83, -81, -77,
+ -72, -70, -65, -66, -66, -65, -66, -68, -61, -56, -51, -36, -13, -3, -5, -8,
+ -12, -12, 3, 16, 21, 31, 50, 69, 77, 82, 90, 102, 110, 114, 116, 117,
+ 118, 119, 116, 112, 109, 105, 98, 99, 103, 102, 91, 73, 64, 63, 61, 57,
+ 51, 40, 24, 35, 57, 75, 84, 79, 65, 37, 4, -26, -45, -57, -54, -46,
+ -45, -54, -67, -67, -48, -16, 15, 35, 44, 45, 44, 45, 46, 38, 23, 2,
+ -15, -34, -52, -60, -70, -77, -80, -79, -74, -77, -84, -86, -80, -72, -68, -72,
+ -80, -87, -92, -96, -101, -104, -104, -101, -93, -90, -89, -86, -85, -84, -83, -82,
+ -81, -79, -77, -76, -73, -71, -66, -62, -55, -39, -31, -27, -25, -31, -37, -46,
+ -51, -53, -54, -48, -45, -38, -20, 3, 24, 35, 39, 32, 16, 5, 3, 0,
+ -6, -13, -13, -11, -2, 14, 28, 40, 50, 53, 50, 55, 64, 74, 90, 105,
+ 108, 112, 106, 104, 109, 112, 123, 127, 127, 127, 127, 127, 127, 118, 113, 107,
+ 110, 114, 111, 104, 101, 101, 102, 103, 99, 99, 89, 73, 53, 35, 20, 0,
+ -22, -43, -63, -77, -82, -76, -65, -48, -36, -29, -24, -25, -29, -37, -40, -49,
+ -59, -67, -73, -76, -78, -79, -75, -73, -74, -75, -68, -52, -44, -30, -19, -9,
+ -6, -9, -13, -24, -33, -35, -31, -30, -35, -40, -44, -45, -51, -53, -54, -50,
+ -50, -47, -42, -50, -55, -54, -56, -56, -54, -54, -49, -48, -41, -32, -28, -18,
+ -13, -5, 6, 18, 33, 49, 60, 71, 78, 88, 95, 97, 93, 88, 91, 93,
+ 97, 98, 97, 94, 91, 85, 81, 72, 70, 66, 61, 60, 64, 66, 74, 83,
+ 92, 102, 108, 109, 107, 102, 97, 95, 91, 87, 80, 74, 67, 62, 61, 58,
+ 61, 61, 57, 53, 43, 35, 27, 25, 24, 20, 20, 22, 27, 34, 36, 32,
+ 21, 8, -3, -10, -16, -18, -16, -16, -19, -15, -11, -11, -12, -20, -34, -45,
+ -59, -72, -80, -89, -94, -95, -102, -111, -114, -111, -111, -108, -106, -104, -101, -98,
+ -93, -90, -86, -86, -83, -82, -81, -79, -76, -73, -70, -72, -78, -81, -79, -79,
+ -72, -60, -43, -31, -25, -27, -34, -37, -40, -42, -41, -39, -36, -34, -25, -12,
+ -4, 5, 12, 16, 17, 15, 13, 6, -4, -7, -8, -6, -1, 4, 7, 9,
+ 12, 16, 19, 19, 22, 28, 29, 28, 29, 30, 34, 40, 49, 57, 71, 78,
+ 85, 92, 96, 95, 89, 85, 86, 93, 99, 104, 102, 100, 94, 85, 77, 73,
+ 69, 66, 63, 60, 60, 59, 57, 52, 47, 41, 31, 18, 6, -3, -7, -11,
+ -12, -14, -18, -22, -23, -22, -24, -30, -37, -41, -44, -50, -56, -64, -67, -65,
+ -62, -58, -58, -58, -59, -61, -62, -66, -72, -78, -79, -77, -73, -68, -64, -61,
+ -56, -53, -54, -52, -52, -57, -63, -69, -70, -68, -65, -62, -59, -57, -56, -58,
+ -60, -61, -63, -64, -62, -61, -60, -58, -54, -49, -45, -42, -39, -36, -32, -28,
+ -22, -13, -7, -3, 2, 13, 28, 41, 52, 64, 71, 73, 73, 70, 64, 61,
+ 60, 64, 66, 65, 66, 64, 61, 60, 62, 65, 64, 66, 67, 67, 68, 66,
+ 64, 66, 68, 73, 76, 74, 72, 66, 58, 52, 46, 42, 38, 38, 41, 47,
+ 52, 52, 48, 45, 42, 40, 38, 34, 29, 27, 26, 28, 29, 28, 29, 30,
+ 31, 28, 24, 21, 19, 17, 14, 10, 6, 3, -4, -9, -15, -19, -26, -33,
+ -40, -49, -55, -60, -65, -70, -73, -72, -72, -71, -70, -71, -75, -78, -81, -83,
+ -86, -86, -85, -84, -82, -80, -77, -72, -69, -66, -63, -61, -61, -61, -61, -61,
+ -60, -58, -53, -48, -42, -36, -30, -28, -30, -32, -33, -32, -31, -28, -22, -18,
+ -10, -5, 0, 3, 6, 11, 16, 19, 22, 24, 26, 27, 29, 34, 40, 46,
+ 48, 48, 48, 45, 40, 36, 33, 31, 33, 35, 40, 48, 55, 62, 68, 73,
+ 76, 78, 78, 77, 79, 82, 85, 87, 87, 87, 86, 86, 86, 83, 78, 71,
+ 63, 55, 48, 44, 39, 36, 36, 36, 35, 32, 28, 24, 18, 13, 9, 6,
+ 4, 1, -2, -5, -11, -17, -20, -21, -20, -21, -24, -28, -32, -34, -33, -33,
+ -35, -37, -40, -43, -47, -52, -58, -63, -69, -74, -77, -80, -81, -82, -81, -80,
+ -77, -74, -69, -62, -54, -48, -48, -51, -54, -57, -57, -57, -56, -55, -55, -56,
+ -57, -56, -55, -54, -54, -54, -54, -52, -49, -45, -41, -38, -34, -31, -29, -27,
+ -24, -20, -17, -11, -7, -3, 0, 5, 10, 16, 22, 27, 31, 34, 38, 42,
+ 44, 45, 48, 50, 52, 57, 61, 64, 64, 65, 65, 63, 60, 57, 55, 55,
+ 58, 61, 63, 65, 67, 69, 71, 74, 77, 79, 79, 77, 74, 71, 68, 66,
+ 63, 60, 57, 55, 51, 46, 40, 36, 30, 25, 20, 17, 16, 17, 16, 14,
+ 12, 10, 7, 3, -1, -5, -11, -15, -17, -18, -18, -19, -21, -25, -29, -32,
+ -33, -33, -36, -39, -43, -46, -50, -53, -56, -58, -59, -60, -61, -62, -63, -65,
+ -66, -67, -68, -70, -72, -72, -70, -67, -63, -61, -60, -60, -58, -56, -54, -53,
+ -52, -52, -52, -51, -50, -49, -47, -45, -43, -40, -37, -35, -34, -32, -29, -25,
+ -21, -18, -14, -9, -4, 0, 4, 7, 11, 15, 18, 21, 25, 28, 33, 37,
+ 41, 44, 46, 47, 47, 46, 46, 45, 43, 42, 42, 43, 46, 48, 49, 50,
+ 52, 55, 59, 62, 65, 66, 67, 68, 69, 69, 70, 72, 74, 74, 73, 72,
+ 71, 69, 65, 61, 57, 53, 50, 46, 43, 38, 35, 32, 28, 23, 19, 17,
+ 17, 15, 13, 11, 9, 5, 1, -3, -6, -9, -12, -14, -17, -19, -23, -27,
+ -31, -35, -38, -40, -43, -46, -48, -52, -55, -57, -61, -64, -66, -67, -68, -69,
+ -70, -70, -70, -69, -69, -70, -71, -70, -66, -62, -59, -55, -52, -50, -46, -43,
+ -41, -38, -36, -35, -35, -34, -33, -33, -33, -33, -31, -30, -28, -26, -25, -24,
+ -21, -20, -20, -19, -19, -18, -17, -16, -15, -13, -11, -8, -3, 2, 9, 15,
+ 21, 27, 33, 38, 41, 45, 48, 51, 53, 55, 56, 56, 56, 56, 56, 56,
+ 56, 55, 57, 58, 60, 61, 62, 62, 64, 66, 68, 69, 71, 72, 73, 74,
+ 72, 70, 67, 63, 60, 57, 54, 50, 46, 41, 36, 31, 27, 23, 19, 16,
+ 14, 12, 11, 9, 8, 5, 2, -1, -4, -8, -10, -15, -18, -19, -20, -22,
+ -22, -23, -23, -24, -26, -29, -31, -33, -35, -36, -37, -38, -41, -44, -46, -48,
+ -50, -52, -54, -56, -59, -61, -63, -63, -64, -65, -64, -63, -62, -61, -60, -59,
+ -58, -57, -58, -57, -57, -55, -53, -50, -49, -47, -46, -43, -40, -37, -33, -31,
+ -28, -26, -23, -20, -16, -14, -12, -9, -5, -2, 1, 5, 9, 13, 17, 21,
+ 24, 26, 29, 32, 35, 37, 37, 38, 39, 41, 43, 44, 45, 46, 48, 50,
+ 51, 53, 52, 52, 50, 48, 47, 46, 46, 46, 46, 47, 48, 49, 51, 54,
+ 56, 58, 60, 61, 62, 62, 62, 61, 59, 57, 55, 54, 53, 52, 51, 49,
+ 46, 41, 36, 31, 27, 22, 18, 14, 11, 9, 6, 3, 0, -2, -5, -8,
+ -11, -16, -20, -25, -28, -31, -34, -37, -39, -41, -41, -42, -42, -42, -43, -45,
+ -46, -47, -49, -50, -52, -54, -56, -57, -58, -60, -61, -63, -64, -64, -64, -63,
+ -63, -61, -59, -58, -57, -55, -54, -53, -52, -52, -51, -50, -49, -47, -46, -45,
+ -44, -42, -40, -38, -35, -32, -30, -28, -25, -22, -19, -17, -15, -12, -9, -5,
+ -1, 3, 7, 11, 15, 19, 23, 25, 27, 30, 34, 36, 37, 38, 39, 40,
+ 42, 44, 45, 46, 47, 49, 50, 52, 53, 52, 51, 49, 47, 47, 46, 46,
+ 46, 47, 47, 48, 50, 52, 55, 57, 59, 61, 62, 62, 62, 61, 60, 58,
+ 56, 54, 54, 53, 51, 50, 47, 44, 39, 34, 29, 25, 20, 16, 13, 10,
+ 7, 4, 2, -1, -3, -6, -9, -14, -18, -22, -26, -30, -33, -35, -38, -40,
+ -41, -41, -42, -42, -43, -44, -46, -47, -48, -49, -51, -53, -55, -56, -57, -59,
+ -60, -62, -63, -64, -64, -63, -63, -62, -60, -59, -57, -56, -55, -53, -52, -52,
+ -51, -51, -50, -48, -46, -45, -44, -43, -41, -39, -36, -34, -31, -29, -26, -24,
+ -21, -16, -1, -2, -1, -3, 1, -2, -2, -4, 2, 6, 2, -2, -2, 0,
+ 7, 8, 4, -2, -2, 6, 5, 6, 0, -2, 5, 12, 10, 0, -5, -3,
+ 5, 10, 9, -7, -8, -7, 5, 8, 3, -9, -13, -5, 3, 5, -5, -9,
+ -4, 0, 6, 0, -4, -11, -7, 3, 4, 0, -5, 0, -1, 5, 1, 4,
+ -6, -5, -3, 12, 9, -2, -10, 4, 11, 8, -4, -5, -9, -6, 1, 19,
+ 13, -2, -22, 4, 9, 6, -26, -4, 3, 12, -9, 0, 2, 0, -15, 4,
+ 8, -8, -20, 0, 15, 8, -13, -2, -4, -4, -2, 12, 3, -14, -18, 1,
+ 21, 13, -9, -25, -8, 17, 15, 5, -14, -17, 5, 19, 13, -15, -17, -3,
+ 10, 20, 10, -27, -19, 5, 11, 12, 3, -13, -17, -1, 6, -3, -2, 1,
+ -1, -11, -17, 7, 7, -7, -7, -13, 9, 0, -5, 9, -5, -9, 6, 5,
+ -2, -16, -5, 15, 17, -10, -20, 1, 11, 14, -1, 1, 10, -11, -8, -1,
+ 18, 13, -2, -12, 1, -16, -2, 34, 27, -28, -42, -3, 42, 26, -14, -39,
+ -19, 7, 26, 25, -16, -55, -26, 32, 57, 4, -69, -48, 6, 75, 29, -51,
+ -67, -32, 51, 56, 7, -57, -75, 14, 63, 43, -29, -82, -27, 31, 56, 28,
+ -43, -81, -31, 59, 85, 1, -100, -59, 8, 102, 41, -42, -92, -52, 72, 79,
+ 29, -103, -85, -1, 117, 49, -54, -113, 7, 24, 94, -28, -39, -84, 39, 28,
+ 61, -44, -28, -67, 61, 23, 35, -40, -23, -37, 6, 38, 69, -42, -61, -53,
+ 58, 86, 2, -93, -24, 19, 72, 17, -19, -87, 45, 10, 64, -13, -45, -57,
+ 38, 48, 36, -51, -35, -37, 46, 26, 37, -73, -28, -12, 44, 22, 27, -84,
+ -22, 6, 70, 17, -24, -82, -7, 26, 79, 9, -63, -78, 6, 90, 68, -55,
+ -118, -3, 92, 62, -10, -73, -50, 14, 110, 15, -5, -118, 5, 69, 53, 22,
+ -81, -45, 29, 47, 80, -69, -28, -52, 58, 66, -1, -25, -59, -22, 107, 2,
+ 43, -108, -13, 20, 59, 56, -58, -66, -7, 34, 114, -42, -63, -50, 42, 69,
+ 44, -63, -37, -50, 114, 27, 18, -49, -81, 20, 74, 51, -14, -102, -4, 40,
+ 70, 38, -64, -73, 11, 60, 76, -41, -30, -78, 42, 46, 68, -63, -48, -56,
+ 89, 43, 28, -100, -53, 41, 60, 11, -6, -76, -16, 44, 52, 9, -67, -48,
+ 10, 69, 30, -1, -84, -4, 36, 72, -23, -22, -27, -33, 55, 74, -11, -86,
+ -1, 27, 36, 31, -7, -101, 49, 5, 66, -7, -46, -39, 9, 64, 44, -63,
+ -33, -22, 55, 23, 43, -79, -24, 5, 29, 54, -14, -59, -53, 63, 32, 20,
+ -34, -32, -36, 93, -2, 20, -35, -38, 18, 51, 61, -94, 15, -14, 17, 69,
+ 5, -87, 16, 28, 34, 1, 34, -57, -53, 118, -22, 34, -10, -71, 23, 70,
+ 25, -29, -7, -19, -3, 117, -33, -12, -21, -19, 43, 84, -38, -57, 33, 0,
+ 32, 41, -7, -103, 85, 2, 2, 58, -14, -103, 103, 7, -17, 34, -32, -59,
+ 71, 51, -78, 76, -65, -30, 63, 48, -66, 9, -11, -28, 52, 50, -72, -37,
+ 73, -61, 75, 7, -51, -44, 73, -3, -11, 40, -78, 7, 63, -15, -16, 30,
+ -53, 12, 38, 12, -42, 39, -63, 47, 23, 0, -23, -11, 8, -25, 60, -37,
+ -15, -3, -9, 12, 27, -14, -40, 22, 12, 14, 15, -31, -14, 15, 23, -12,
+ 14, -31, 19, 13, 32, -39, 27, -51, 43, 8, 0, 5, -26, 16, 4, 19,
+ -24, 17, -18, 6, -2, 49, -67, 39, -1, -30, 46, -13, -16, -9, 21, -17,
+ 27, 2, -34, 19, -3, 24, 8, -38, 13, -10, 22, 15, -34, 2, 4, -10,
+ 18, 14, -15, -15, 26, -12, 28, -21, 0, -6, 0, 7, 0, -15, 6, -2,
+ -18, 9, 8, -18, -15, 59, -94, 81, -40, -24, 14, -18, 25, -15, 4, -21,
+ -9, 24, -20, 3, 3, -52, 56, -29, 4, 5, -51, 45, -50, 73, -75, 13,
+ 17, -48, 38, -10, -16, 5, 4, -22, 3, 17, -27, -23, 42, -30, -5, 41,
+ -53, 10, 23, -28, 1, 29, -47, 9, 13, -3, -18, 9, -13, -11, 18, 12,
+ -53, 28, 1, -41, 41, 7, -61, 32, 0, -34, 16, 9, -74, 45, -23, -33,
+ 22, 39, -104, 49, 23, -96, 83, 5, -46, 36, -4, -45, 54, -25, -26, 21,
+ 2, -39, 51, -25, -25, 43, -22, -25, 30, -2, -32, 39, 14, -69, 42, 22,
+ -78, 60, 23, -83, 33, 44, -74, 19, 69, -113, 43, 53, -88, 51, 17, -74,
+ 42, 1, -38, 4, 39, -67, 12, 35, -39, -23, 73, -82, -5, 67, -71, -5,
+ 42, -36, -48, 78, -64, -4, 40, -48, -7, 50, -80, 17, 31, -56, 9, 6,
+ -18, -36, 43, -37, -29, 47, -47, -18, 33, -29, -27, 40, -30, -37, 51, -46,
+ -25, 61, -66, 7, 28, -48, 30, -15, -8, -6, 17, -14, -9, 26, -23, 4,
+ 9, -15, 12, -9, 16, -22, 7, 22, -51, 59, -29, -23, 54, -49, 6, 20,
+ -19, -11, 17, -3, -30, 32, -27, -5, 16, -28, 4, 4, -27, 32, -46, 27,
+ -18, -8, 11, -25, 18, -6, -17, 10, 1, -18, 24, -33, 10, 8, -12, -10,
+ 21, -19, 0, 8, -18, 14, 11, -44, 39, -22, -4, -6, 11, -15, -13, 17,
+ -17, -6, 13, -22, -1, 7, -5, -8, 0, 4, -24, 29, -23, 0, 20, -25,
+ -8, 30, -34, 31, -29, 11, -9, 21, -15, -1, 10, -9, -11, 32, -23, -2,
+ -14, 27, -19, 10, -4, -23, 14, 13, -45, 48, -44, 11, -4, -7, -3, 4,
+ -2, -34, -8, 37, -41, 20, -24, -4, -10, 2, 4, 12, -28, -30, 9, 32,
+ -16, 6, -46, -23, 60, 0, -22, -3, -23, -15, 48, 12, -34, -17, -18, 10,
+ 46, -1, -56, -8, 12, 9, 18, 13, -72, -3, 26, 9, 28, -14, -89, 15,
+ 67, -18, 1, -19, -52, 45, 26, -8, -5, -25, -25, 36, 38, -13, -36, -18,
+ -6, 55, 23, -51, -14, 4, 6, 25, 24, -41, -44, 38, 19, 10, 10, -59,
+ -14, 42, 1, 6, -8, -43, -1, 43, 10, -30, -10, -36, 18, 35, -20, -14,
+ -11, -19, 9, 20, -5, -22, -9, -6, 13, 26, -30, -23, 4, 1, 20, 9,
+ -20, -22, 3, -1, 17, 28, -26, -25, 16, -2, -4, 12, -10, -16, 24, -2,
+ -18, 17, -27, -1, 36, -6, -7, -4, -26, 6, 29, -3, -17, -6, -4, 18,
+ 18, -26, -10, -4, 6, 30, -1, -6, -24, 0, 24, 12, 2, -16, -25, 13,
+ 32, -3, -4, -3, -24, 15, 16, -7, 8, -20, -13, 36, 9, -24, -11, -10,
+ 10, 20, -1, -13, -10, -9, 20, 17, -12, -9, -15, 9, 20, -11, -14, -6,
+ 5, 10, 6, 5, -7, -11, 7, 19, 1, 3, -11, -10, 24, 14, -16, 2,
+ -9, 11, 14, 7, -1, -11, -4, 15, 24, 3, -24, -4, 4, 15, 13, -3,
+ -15, 0, 15, 8, 2, 0, -19, 16, 12, -1, 7, -13, -2, 18, 3, -3,
+ 5, -9, -10, 12, 9, -2, 8, -9, 4, 9, 6, 1, -8, 10, 4, -2,
+ 11, -14, 3, 5, 1, 9, 4, -15, 0, 10, 1, 5, -4, -10, 3, 7,
+ -1, 8, -13, 1, 4, 10, 6, -9, -3, 1, 6, 14, -3, -4, 4, -10,
+ 10, 13, -1, -4, 5, -3, 10, 13, -13, 4, 7, 1, 8, -1, 1, 4,
+ 5, 4, 11, -5, -2, 1, 8, 6, 1, 3, -1, -5, 11, 3, -3, 4,
+ -5, -1, 17, -4, -2, 6, -10, 10, 10, -4, 2, 3, -10, 10, 5, -2,
+ -2, -1, 4, 3, -1, -2, -4, 1, 6, -4, 6, -4, -10, 8, 2, -4,
+ 6, -4, -4, 12, -2, 2, 6, -9, 3, 2, 0, 7, -5, -3, 3, 2,
+ 4, -4, -2, 7, 3, 5, 9, -3, 1, 12, -3, 7, 6, -9, 4, 9,
+ -4, 12, 1, -7, 9, 2, 1, 10, -3, 1, 0, 0, 8, 0, -1, 5,
+ -2, 8, 1, -3, 10, 2, 0, 11, -4, -1, 6, -3, 2, 3, -5, 4,
+ 0, -5, 5, -3, 1, 3, 0, 4, -3, -3, 4, -2, -2, 5, -2, -1,
+ 6, -5, 2, 3, -4, 4, -2, -3, 11, -8, 0, 5, -1, 1, 0, -3,
+ 4, 2, 2, 6, -2, 4, 5, -3, 4, 7, -4, 11, -1, 0, 3, 0,
+ 3, 7, -2, 5, 1, 0, 6, 3, 2, 4, -1, 2, 6, 0, 3, 5,
+ -4, 6, 0, 2, 7, -4, -1, 2, -2, 7, 1, -1, 1, -2, 2, 4,
+ -5, 0, 4, -1, 2, -1, -2, 1, -2, 3, 2, -3, 3, -1, -4, 5,
+ -2, -2, 3, 0, -1, 2, -5, 2, 1, -4, 0, 1, -3, 5, -2, 2,
+ 2, -3, 1, 3, -2, 3, 1, -2, 4, 1, 2, 5, -2, 3, 1, 2,
+ 5, 0, -1, 4, 0, 1, 4, 2, 4, 4, -2, 0, 2, 3, 5, 0,
+ 0, 0, 1, 5, -2, -3, 4, 0, 1, 2, -2, -4, -4, -5, -6, -7,
+ -8, -9, -10, -11, -12, -13, -13, -14, -16, -18, -21, -25, -29, -34, -36, -38,
+ -39, -40, -42, -44, -47, -50, -53, -56, -58, -59, -58, -55, -50, -44, -38, -31,
+ -24, -18, -13, -9, -6, -3, 0, 3, 6, 9, 13, 17, 21, 27, 33, 42,
+ 53, 63, 74, 83, 91, 98, 104, 108, 111, 113, 115, 118, 119, 121, 123, 125,
+ 126, 127, 127, 127, 127, 126, 126, 126, 126, 127, 127, 127, 127, 127, 127, 127,
+ 126, 125, 123, 121, 118, 114, 111, 107, 104, 101, 100, 99, 98, 98, 98, 98,
+ 98, 99, 98, 98, 97, 95, 92, 88, 81, 73, 63, 54, 46, 39, 33, 29,
+ 27, 25, 24, 22, 20, 18, 14, 10, 5, 0, -5, -8, -8, -7, -3, 2,
+ 8, 14, 19, 23, 26, 28, 29, 30, 31, 32, 32, 31, 30, 28, 24, 20,
+ 14, 9, 4, -1, -4, -7, -9, -10, -12, -13, -15, -17, -19, -22, -24, -25,
+ -25, -23, -21, -19, -17, -15, -15, -14, -15, -15, -16, -17, -17, -17, -16, -16,
+ -16, -17, -19, -22, -25, -30, -35, -39, -44, -47, -50, -53, -56, -58, -61, -63,
+ -64, -65, -65, -63, -60, -55, -49, -43, -38, -34, -32, -31, -31, -32, -33, -35,
+ -36, -37, -37, -36, -35, -34, -34, -34, -36, -39, -43, -49, -55, -61, -67, -72,
+ -77, -81, -85, -88, -90, -92, -94, -94, -95, -94, -94, -94, -94, -95, -96, -98,
+ -100, -102, -104, -105, -107, -108, -108, -109, -110, -110, -110, -109, -109, -109, -108, -108,
+ -109, -109, -109, -109, -108, -108, -107, -106, -106, -105, -105, -105, -105, -105, -105, -104,
+ -103, -101, -98, -93, -88, -82, -76, -70, -64, -58, -52, -47, -42, -38, -34, -31,
+ -29, -27, -25, -22, -18, -13, -7, -1, 6, 13, 20, 26, 32, 37, 41, 45,
+ 48, 51, 55, 58, 63, 68, 73, 77, 82, 85, 89, 91, 94, 96, 97, 98,
+ 99, 99, 99, 100, 100, 100, 101, 101, 101, 101, 101, 101, 99, 97, 95, 93,
+ 90, 87, 84, 81, 77, 73, 67, 60, 51, 40, 29, 17, 6, -5, -14, -23,
+ -31, -38, -45, -52, -58, -65, -70, -75, -80, -84, -87, -90, -92, -94, -95, -96,
+ -97, -98, -100, -101, -102, -102, -103, -103, -104, -104, -103, -102, -100, -97, -93, -89,
+ -86, -82, -79, -77, -75, -72, -70, -67, -63, -59, -53, -47, -40, -33, -26, -20,
+ -14, -9, -6, -3, 0, 3, 6, 9, 13, 17, 21, 26, 31, 37, 44, 51,
+ 58, 64, 70, 75, 79, 83, 86, 88, 90, 92, 93, 95, 96, 97, 98, 100,
+ 100, 101, 102, 102, 102, 102, 102, 102, 102, 102, 102, 103, 103, 103, 102, 102,
+ 102, 101, 100, 98, 96, 94, 92, 90, 89, 88, 88, 87, 87, 87, 87, 87,
+ 86, 85, 84, 82, 79, 76, 72, 67, 61, 55, 49, 43, 39, 35, 32, 30,
+ 29, 27, 25, 24, 21, 18, 15, 12, 8, 5, 3, 3, 4, 6, 9, 12,
+ 15, 18, 21, 23, 25, 27, 28, 30, 31, 31, 31, 30, 28, 25, 22, 18,
+ 14, 10, 7, 5, 3, 1, 0, -2, -4, -6, -9, -11, -14, -16, -17, -17,
+ -16, -14, -12, -11, -9, -9, -9, -10, -11, -12, -13, -14, -15, -15, -16, -16,
+ -17, -19, -22, -26, -30, -34, -38, -42, -45, -48, -50, -52, -53, -54, -55, -56,
+ -56, -55, -53, -50, -46, -42, -38, -35, -32, -31, -30, -31, -31, -33, -34, -35,
+ -36, -36, -36, -35, -35, -35, -36, -38, -41, -45, -49, -54, -59, -64, -68, -73,
+ -76, -80, -83, -86, -88, -89, -90, -91, -91, -91, -92, -92, -93, -95, -96, -98,
+ -100, -101, -102, -103, -104, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105,
+ -105, -105, -104, -104, -103, -102, -102, -101, -100, -100, -100, -99, -99, -99, -98, -96,
+ -94, -91, -86, -82, -76, -71, -65, -59, -53, -48, -42, -37, -32, -28, -25, -22,
+ -19, -16, -13, -8, -3, 3, 9, 16, 22, 28, 35, 40, 45, 49, 53, 56,
+ 60, 63, 67, 71, 76, 80, 85, 88, 92, 94, 97, 99, 100, 102, 103, 103,
+ 104, 104, 104, 104, 105, 105, 105, 105, 105, 104, 103, 101, 99, 97, 94, 91,
+ 87, 84, 80, 76, 71, 65, 57, 48, 39, 28, 18, 8, -2, -11, -19, -27,
+ -34, -41, -47, -54, -60, -65, -70, -75, -79, -82, -85, -87, -89, -91, -92, -94,
+ -95, -96, -97, -98, -99, -100, -100, -100, -100, -100, -98, -96, -94, -90, -87, -84,
+ -81, -78, -76, -73, -71, -68, -65, -61, -57, -52, -46, -40, -33, -27, -21, -15,
+ -11, -7, -4, 0, 3, 7, 11, 15, 20, 24, 29, 35, 41, 48, 54, 61,
+ 67, 72, 77, 81, 85, 88, 90, 92, 94, 95, 97, 98, 99, 101, 102, 103,
+ 104, 104, 104, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 104,
+ 104, 103, 101, 99, 98, 96, 95, 93, 93, 92, 92, 91, 91, 90, 90, 88,
+ 87, 86, 84, 81, 78, 74, 69, 64, 59, 54, 49, 45, 42, 39, 37, 35,
+ 33, 31, 29, 27, 24, 21, 18, 15, 13, 11, 11, 12, 13, 15, 17, 20,
+ 22, 24, 25, 27, 28, 29, 30, 31, 31, 31, 30, 28, 26, 23, 20, 17,
+ 14, 11, 9, 8, 6, 5, 3, 1, -1, -4, -6, -8, -10, -11, -11, -11,
+ -10, -9, -8, -8, -8, -9, -10, -11, -13, -14, -15, -16, -17, -17, -18, -20,
+ -22, -25, -28, -31, -35, -38, -41, -44, -46, -47, -49, -50, -51, -52, -52, -52,
+ -51, -49, -47, -44, -40, -38, -35, -33, -33, -32, -33, -33, -34, -35, -36, -37,
+ -38, -38, -38, -38, -39, -40, -42, -45, -49, -53, -57, -61, -65, -69, -73, -76,
+ -79, -82, -85, -87, -88, -89, -90, -91, -91, -92, -93, -94, -95, -97, -98, -99,
+ -100, -101, -102, -103, -103, -104, -104, -104, -104, -104, -104, -104, -104, -104, -103, -103,
+ -103, -102, -102, -101, -100, -99, -99, -98, -97, -97, -96, -96, -95, -94, -92, -89,
+ -86, -82, -77, -72, -67, -61, -56, -50, -45, -39, -34, -29, -25, -21, -18, -14,
+ -11, -5, 4, 8, 14, 19, 25, 31, 37, 42, 47, 52, 57, 61, 65, 69,
+ 72, 76, 79, 83, 86, 89, 92, 95, 97, 99, 101, 102, 104, 104, 105, 106,
+ 106, 106, 106, 106, 106, 105, 104, 104, 103, 101, 99, 97, 95, 92, 89, 85,
+ 81, 77, 73, 68, 62, 57, 50, 43, 35, 28, 19, 12, 4, -4, -11, -18,
+ -25, -32, -38, -44, -50, -55, -61, -65, -69, -73, -77, -80, -82, -85, -87, -89,
+ -91, -92, -93, -95, -95, -96, -97, -97, -97, -96, -96, -95, -93, -92, -90, -88,
+ -86, -84, -82, -79, -77, -74, -71, -68, -64, -60, -55, -51, -46, -41, -36, -31,
+ -26, -21, -16, -11, -7, -2, 3, 8, 14, 19, 25, 30, 36, 42, 47, 53,
+ 58, 63, 68, 72, 76, 79, 82, 85, 87, 89, 91, 93, 95, 96, 98, 99,
+ 101, 102, 103, 103, 104, 105, 105, 105, 106, 106, 106, 106, 106, 106, 106, 105,
+ 105, 105, 104, 103, 103, 102, 101, 100, 99, 99, 98, 97, 96, 95, 93, 92,
+ 91, 89, 87, 85, 82, 79, 76, 73, 70, 67, 63, 60, 58, 55, 53, 50,
+ 48, 46, 44, 41, 39, 37, 34, 32, 31, 29, 28, 28, 27, 28, 28, 28,
+ 28, 29, 29, 29, 29, 30, 30, 30, 29, 29, 28, 27, 26, 25, 23, 22,
+ 20, 19, 17, 16, 15, 13, 12, 10, 8, 6, 4, 2, 1, -1, -2, -4,
+ -5, -6, -7, -9, -10, -12, -13, -15, -17, -19, -21, -22, -24, -26, -27, -29,
+ -31, -32, -34, -36, -38, -40, -42, -43, -45, -46, -47, -47, -48, -48, -49, -49,
+ -48, -48, -47, -46, -45, -44, -44, -43, -43, -43, -44, -44, -45, -46, -47, -48,
+ -49, -50, -51, -52, -53, -55, -57, -59, -61, -64, -67, -70, -72, -75, -78, -80,
+ -82, -84, -86, -88, -90, -91, -92, -94, -95, -96, -97, -98, -98, -99, -100, -101,
+ -101, -101, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -101, -101, -100, -100,
+ -99, -98, -97, -96, -95, -94, -93, -92, -91, -89, -88, -87, -85, -83, -81, -78,
+ -75, -71, -67, -63, -58, -54, -49, -44, -39, -33, -28, -23, -18, -13, -8, -3,
+ 2, 7, 13, 18, 23, 29, 35, 40, 45, 51, 55, 60, 64, 68, 71, 75,
+ 78, 82, 85, 88, 91, 93, 96, 98, 100, 101, 103, 104, 105, 105, 106, 106,
+ 106, 106, 105, 105, 104, 104, 103, 101, 100, 98, 95, 93, 90, 86, 83, 79,
+ 75, 70, 65, 60, 54, 47, 40, 33, 25, 18, 10, 2, -5, -12, -19, -26,
+ -32, -38, -44, -50, -55, -60, -65, -69, -73, -76, -79, -82, -84, -87, -89, -90,
+ -92, -93, -94, -95, -96, -96, -96, -96, -96, -95, -94, -93, -91, -90, -88, -86,
+ -84, -81, -79, -76, -74, -70, -67, -63, -59, -54, -49, -44, -39, -34, -29, -24,
+ -19, -14, -10, -5, -2, -1, 3, -2, 1, -3, 4, -2, 0, 0, 8, 0,
+ 10, -9, -7, -128, -72, 13, -44, -13, -18, 4, -4, 12, 3, 31, 4, 66,
+ 74, 38, 38, 36, 30, 25, 22, 18, 13, 7, 5, 2, 1, -5, -7, -9,
+ -9, -11, -14, -12, -14, -12, -16, -13, -16, -13, -14, -16, -11, -14, -10, -13,
+ -11, -13, -8, -8, -6, -6, -5, 0, -6, -3, -3, 3, -4, 6, -13, 17,
+ -5, -5, 15, -1, -23, 6, 23, 28, 35, 13, 41, -3, 24, 25, -4, 6,
+ 30, 4, 18, 10, -32, -64, -120, -64, -91, -76, -33, -45, -58, 2, 1, -19,
+ -14, 18, 48, 50, 59, 51, 53, 47, 46, 41, 37, 35, 26, 28, 19, 21,
+ 10, 13, 9, 3, 5, -4, 2, -5, -3, -8, -5, -8, -8, -10, -9, -10,
+ -10, -12, -7, -17, -8, -11, -14, -5, -15, -5, -4, -10, -13, 11, -22, 3,
+ -3, -4, -5, -11, 13, 2, -16, -9, -5, -12, 27, 15, 17, 21, 20, 20,
+ 8, 14, 13, 0, 10, 35, 10, -1, -12, -52, -89, -78, -58, -85, -74, -51,
+ -25, -25, -28, -30, -14, 12, 29, 44, 44, 51, 46, 50, 49, 43, 38, 36,
+ 32, 29, 23, 19, 17, 14, 10, 6, 6, 2, 4, -8, 3, -7, -3, -6,
+ -7, -11, -4, -12, -7, -6, -20, 1, -15, -14, -8, -7, -10, -10, -10, 2,
+ -14, -12, 7, -10, -8, -5, -6, 1, 6, -2, -12, -19, -3, 3, 2, 19,
+ 19, 14, 19, 24, 13, 5, 12, 12, 13, 21, 29, 5, -18, -43, -48, -64,
+ -82, -82, -71, -44, -37, -37, -40, -33, -23, 5, 20, 33, 38, 45, 48, 51,
+ 46, 44, 41, 38, 36, 27, 26, 24, 19, 13, 16, 5, 11, 4, -1, 3,
+ -4, -3, 1, -9, -7, -2, -9, -6, -13, -4, -6, -17, -8, -6, -15, -10,
+ -5, -10, -8, -10, -5, -7, -5, -2, -14, -10, 3, 5, -4, -3, -10, -17,
+ -10, 3, 4, 5, 18, 18, 18, 16, 16, 10, 5, 11, 23, 26, 22, 7,
+ -9, -16, -37, -62, -80, -76, -65, -46, -43, -43, -51, -41, -24, -4, 11, 24,
+ 32, 41, 47, 43, 49, 45, 41, 40, 33, 31, 31, 20, 23, 18, 11, 16,
+ 9, 5, 3, 2, 5, -2, -7, 2, -4, -10, -3, -5, -8, -10, -7, -8,
+ -14, -10, -8, -11, -9, -6, -14, -10, -2, -3, -12, -10, -7, -9, 0, 6,
+ -1, -11, -12, -11, -10, -7, 4, 7, 12, 17, 20, 18, 13, 6, 8, 19,
+ 22, 24, 17, 14, 5, -8, -29, -54, -77, -71, -55, -50, -44, -54, -57, -39,
+ -32, -15, 3, 15, 31, 34, 39, 47, 45, 44, 44, 37, 37, 33, 28, 27,
+ 18, 20, 21, 10, 7, 10, 7, 1, 2, 2, 0, -5, 0, -2, -7, -3,
+ -5, -8, -8, -5, -13, -13, -5, -6, -14, -11, -8, -8, -5, -5, -9, -17,
+ -10, -2, 0, -2, -1, -9, -12, -14, -12, -6, -1, 3, 11, 19, 19, 14,
+ 7, 9, 13, 17, 23, 22, 19, 21, 12, 2, -21, -55, -65, -59, -52, -47,
+ -56, -56, -50, -53, -38, -22, -7, 10, 18, 29, 36, 40, 45, 43, 38, 41,
+ 40, 32, 27, 26, 26, 19, 17, 17, 12, 9, 9, 6, 2, 4, 4, -1,
+ -2, 2, -3, -3, 0, -2, -8, -9, -7, -7, -7, -6, -8, -12, -6, -4,
+ -7, -12, -13, -10, -5, -2, -2, -3, -8, -12, -15, -16, -14, -13, -7, 2,
+ 8, 11, 8, 4, 5, 8, 13, 20, 22, 23, 24, 23, 19, 6, -13, -23,
+ -29, -32, -37, -42, -46, -53, -57, -53, -49, -39, -25, -12, -1, 10, 21, 28,
+ 32, 35, 36, 34, 34, 32, 28, 25, 24, 21, 18, 19, 16, 10, 7, 8,
+ 9, 8, 6, 5, 2, 3, 6, 7, 5, 2, -2, -4, -3, -1, -3, -4,
+ -3, -1, -3, -8, -13, -14, -11, -4, -1, -2, -4, -6, -11, -16, -19, -21,
+ -21, -17, -9, -3, 0, 0, -3, -5, -2, 4, 11, 18, 23, 25, 26, 24,
+ 17, 10, 5, -1, -7, -12, -20, -29, -37, -44, -51, -55, -54, -47, -39, -28,
+ -16, -4, 9, 18, 23, 27, 31, 31, 30, 30, 28, 23, 20, 22, 23, 20,
+ 14, 10, 9, 9, 10, 9, 6, 4, 4, 6, 9, 10, 7, 2, 0, 1,
+ -1, -2, -2, -1, 1, 2, -2, -10, -14, -11, -8, -5, -2, -1, -3, -6,
+ -9, -14, -20, -23, -23, -18, -11, -5, -3, -4, -6, -8, -4, 2, 7, 14,
+ 21, 25, 25, 23, 19, 13, 8, 4, -1, -9, -15, -23, -31, -39, -48, -53,
+ -51, -48, -44, -34, -20, -8, 3, 12, 20, 24, 27, 30, 31, 29, 24, 22,
+ 22, 23, 22, 18, 13, 10, 10, 11, 11, 9, 5, 3, 5, 10, 11, 9,
+ 7, 5, 4, 2, 0, -3, -1, 3, 5, 2, -3, -8, -11, -10, -7, -5,
+ -3, -2, -2, -4, -7, -14, -20, -24, -24, -19, -12, -6, -6, -8, -8, -8,
+ -7, -2, 5, 12, 19, 23, 24, 22, 20, 16, 12, 7, 1, -5, -10, -17,
+ -27, -36, -42, -47, -52, -51, -45, -36, -26, -12, 0, 9, 15, 21, 27, 30,
+ 29, 26, 23, 22, 23, 23, 21, 17, 12, 9, 10, 12, 10, 6, 3, 4,
+ 7, 10, 11, 9, 8, 9, 7, 2, -1, 0, 2, 6, 6, 3, -2, -7,
+ -9, -8, -6, -4, -3, -1, -1, -2, -6, -13, -21, -26, -24, -18, -13, -10,
+ -9, -10, -11, -11, -10, -5, 3, 10, 17, 21, 22, 22, 21, 19, 14, 8,
+ 5, 1, -7, -14, -21, -29, -38, -45, -49, -50, -48, -40, -28, -16, -6, 3,
+ 11, 19, 26, 27, 26, 24, 22, 22, 24, 24, 20, 14, 11, 11, 12, 11,
+ 8, 4, 3, 6, 8, 9, 9, 10, 11, 10, 6, 2, 0, 2, 5, 8,
+ 7, 3, -2, -5, -6, -7, -6, -4, -3, -1, 1, 1, -5, -13, -21, -24,
+ -23, -18, -14, -12, -11, -12, -13, -14, -13, -8, 0, 8, 14, 17, 21, 22,
+ 21, 18, 15, 12, 8, 2, -3, -9, -16, -24, -32, -40, -47, -51, -49, -41,
+ -30, -21, -12, -1, 9, 17, 23, 25, 24, 21, 21, 24, 24, 22, 17, 12,
+ 11, 13, 12, 8, 4, 3, 4, 6, 7, 7, 9, 11, 12, 10, 6, 3,
+ 3, 6, 9, 10, 8, 5, 1, -2, -3, -3, -2, -1, 1, 3, 3, 1,
+ -5, -12, -18, -20, -20, -18, -16, -16, -16, -17, -19, -20, -17, -11, -5, 1,
+ 8, 13, 17, 18, 18, 17, 16, 14, 11, 7, 2, -3, -8, -14, -22, -34,
+ -43, -46, -42, -35, -28, -20, -11, -2, 7, 15, 19, 19, 19, 19, 20, 20,
+ 17, 14, 11, 10, 9, 7, 1, -4, -6, -4, 0, 2, 4, 6, 7, 8,
+ 9, 8, 7, 7, 10, 13, 15, 15, 13, 9, 6, 3, 2, 4, 7, 9,
+ 11, 11, 7, 1, -5, -10, -13, -14, -14, -14, -16, -19, -23, -26, -28, -27,
+ -23, -18, -13, -7, -1, 6, 11, 14, 15, 14, 14, 15, 15, 12, 7, 2,
+ -1, -4, -11, -22, -34, -41, -40, -34, -26, -19, -12, -4, 4, 10, 14, 17,
+ 17, 18, 19, 18, 15, 12, 10, 9, 8, 6, 0, -6, -11, -10, -6, -1,
+ 3, 5, 6, 6, 6, 7, 7, 8, 10, 13, 16, 18, 17, 13, 9, 5,
+ 3, 4, 7, 11, 13, 14, 11, 5, -2, -7, -11, -12, -12, -13, -14, -17,
+ -22, -26, -28, -29, -27, -22, -17, -11, -5, 1, 7, 12, 14, 14, 13, 14,
+ 15, 14, 11, 5, 0, -2, -6, -15, -27, -37, -42, -38, -31, -24, -17, -9,
+ -1, 6, 12, 15, 17, 18, 19, 19, 17, 13, 11, 9, 9, 8, 4, -2,
+ -8, -11, -9, -4, 1, 4, 5, 6, 6, 6, 7, 7, 9, 11, 14, 17,
+ 18, 16, 12, 8, 4, 3, 5, 9, 12, 14, 13, 9, 2, -4, -9, -12,
+ -13, -12, -13, -15, -19, -23, -27, -29, -28, -25, -20, -15, -9, -3, 3, 9,
+ 13, 15, 14, 13, 15, 15, 13, 9, 3, -1, -3, -9, -19, -31, -40, -41,
+ -36, -28, -21, -14, -6, 2, 9, 13, 16, 17, 18, 19, 18, 16, 12, 10,
+ 9, 9, 7, 2, -4, -10, -11, -8, -2, 2, 5, 5, 6, 6, 7, 7,
+ 8, 9, 12, 16, 18, 17, 14, 10, 6, 4, 4, 6, 10, 13, 14, 12,
+ 7, 0, -6, -10, -12, -13, -13, -14, -16, -21, -25, -28, -29, -28, -24, -18,
+ -13, -7, -1, 6, 11, 14, 15, 13, 14, 15, 15, 12, 7, 2, -1, -5,
+ -12, -23, -35, -41, -40, -34, -26, -19, -12, -3, 4, 10, 14, 17, 18, 18,
+ 19, 18, 14, 11, 9, 9, 8, 6, 0, -7, -11, -10, -6, 0, 2, -1,
+ -2, -9, -24, 4, -3, 3, -3, 10, 7, 4, 13, -4, 1, 3, 3, 0,
+ 2, 8, -9, -9, 2, 1, -1, 7, 17, 21, 37, 25, 13, 14, -2, 15,
+ 20, 5, 0, -3, -7, -27, -14, -18, -19, -29, -20, -4, -18, -32, -30, -30,
+ -29, -32, -22, -26, -19, -19, -1, -6, 4, 7, 5, 2, 0, -8, -16, -12,
+ -13, -17, -17, 19, 20, 24, 16, 8, -4, 8, 0, 13, 28, 33, 16, 11,
+ 5, -3, -1, 4, 12, 12, 40, 20, 11, 4, 5, 8, -1, 2, 5, 5,
+ 22, 13, 21, 8, 9, 18, 20, 13, 20, 26, 11, 24, 17, 10, 27, 30,
+ 22, 28, 30, 41, 47, 57, 36, 36, 20, -16, 4, 6, -19, -21, -41, -39,
+ -33, -38, -41, -46, -42, -36, -18, -37, -65, -75, -77, -78, -62, -63, -62, -68,
+ -63, -63, -44, -50, -30, -41, -43, -26, -34, -35, -36, -45, -49, -27, 1, -6,
+ -4, -7, -20, -16, -20, -21, -13, 2, -6, -1, -12, 0, -1, 15, 19, 20,
+ 26, 37, 40, 46, 37, 50, 35, 34, 41, 43, 51, 54, 55, 50, 56, 47,
+ 59, 51, 51, 75, 67, 66, 71, 59, 60, 72, 75, 72, 80, 79, 82, 98,
+ 99, 87, 93, 62, 49, 58, 41, 42, 28, 5, -6, -6, -18, -24, -23, -30,
+ -25, -20, -38, -60, -75, -77, -80, -75, -71, -75, -70, -73, -69, -76, -60, -66,
+ -71, -66, -57, -62, -61, -61, -87, -90, -69, -63, -46, -31, -35, -47, -42, -53,
+ -63, -53, -45, -33, -36, -39, -37, -43, -39, -34, -30, -19, -9, 2, -9, -1,
+ -3, 1, -3, 5, 7, 15, 24, 22, 23, 20, 32, 43, 33, 48, 63, 67,
+ 70, 68, 52, 59, 73, 73, 77, 85, 73, 81, 103, 98, 116, 115, 87, 80,
+ 76, 72, 69, 60, 37, 27, 29, 12, 19, 4, -12, 1, 3, -3, -31, -42,
+ -57, -67, -67, -61, -61, -61, -48, -58, -51, -41, -46, -48, -40, -35, -33, -26,
+ -36, -67, -68, -65, -59, -47, -28, -34, -37, -36, -52, -61, -61, -47, -34, -39,
+ -39, -42, -42, -48, -36, -38, -37, -20, -19, -16, -16, -18, -20, -22, -26, -22,
+ -16, -15, 1, -4, -6, 10, 12, 13, 22, 32, 41, 54, 52, 44, 54, 66,
+ 61, 78, 81, 71, 87, 89, 99, 119, 107, 91, 77, 76, 69, 76, 68, 47,
+ 49, 35, 33, 37, 22, 14, 24, 37, 26, 13, -10, -26, -41, -43, -34, -40,
+ -34, -33, -43, -39, -25, -27, -27, -18, -25, -15, -1, -10, -29, -42, -39, -39,
+ -19, -7, -10, -10, -11, -20, -35, -44, -33, -30, -28, -36, -34, -47, -41, -36,
+ -46, -42, -34, -27, -29, -25, -34, -30, -32, -40, -36, -36, -31, -16, -25, -25,
+ -15, -21, -14, -9, -11, 1, 17, 15, 9, 25, 20, 25, 46, 39, 46, 50,
+ 51, 68, 85, 87, 72, 65, 52, 50, 59, 44, 42, 29, 23, 22, 23, 11,
+ -5, 8, 14, 19, 8, -6, -23, -38, -43, -42, -48, -41, -34, -42, -38, -19,
+ -23, -16, -15, -19, -10, 8, 8, -9, -18, -27, -30, -10, -4, 7, 6, 15,
+ 8, -8, -17, -15, -8, -11, -3, -15, -17, -14, -16, -27, -30, -26, -22, -19,
+ -21, -22, -19, -30, -27, -26, -36, -22, -9, -13, -10, -10, -8, -9, -6, -12,
+ -1, 16, 6, 11, 16, 6, 19, 24, 27, 38, 38, 38, 48, 71, 72, 78,
+ 66, 51, 54, 52, 49, 42, 32, 21, 25, 26, 13, 1, -1, 10, 15, 8,
+ 1, -22, -38, -47, -56, -58, -46, -43, -46, -33, -25, -17, -11, -9, -19, -9,
+ 16, 18, 12, 1, -17, -18, -9, 3, 9, 17, 24, 26, 9, -4, -1, -6,
+ 2, 9, 0, -2, 2, -3, -13, -16, -15, -8, -8, -8, -1, -6, -17, -11,
+ -22, -24, -16, -12, -9, -9, -9, -9, -6, -8, -16, 2, 6, 2, 13, 9,
+ 7, 10, 17, 19, 30, 31, 22, 37, 49, 61, 70, 56, 43, 37, 36, 31,
+ 32, 15, 4, 11, 9, 4, -14, -16, -7, -5, -1, -8, -28, -46, -56, -75,
+ -74, -67, -70, -67, -62, -55, -47, -36, -32, -42, -28, -9, 1, 4, -4, -17,
+ -30, -18, -12, -2, 4, 15, 21, 7, 1, -7, -6, -1, 7, 0, 0, 3,
+ -3, -8, -15, -18, -6, -9, -6, 5, -2, -2, 0, -7, -12, -7, -3, 2,
+ 7, 3, 4, 14, 2, 1, 12, 11, 17, 20, 19, 16, 19, 20, 24, 39,
+ 36, 37, 42, 55, 71, 84, 76, 63, 56, 47, 49, 46, 29, 18, 14, 18,
+ 11, -5, -11, -8, -3, 4, 4, -16, -27, -44, -60, -64, -59, -62, -62, -55,
+ -55, -47, -28, -32, -35, -29, -15, -3, 4, 3, -15, -25, -24, -13, -11, -3,
+ 10, 14, 12, 4, -5, -9, -1, 2, -1, 1, 1, -1, -7, -17, -16, -12,
+ -17, -8, 0, -1, -1, -2, -8, -13, -9, -9, 0, 9, 1, 14, 16, 6,
+ 7, 10, 12, 18, 26, 20, 22, 22, 16, 25, 32, 36, 34, 36, 43, 60,
+ 75, 72, 67, 52, 44, 50, 45, 38, 17, 14, 17, 11, -2, -9, -14, -10,
+ 0, -4, -12, -24, -41, -59, -67, -63, -70, -69, -62, -70, -55, -40, -38, -42,
+ -38, -29, -16, -3, -3, -9, -29, -31, -25, -26, -20, -7, 0, 2, -1, -14,
+ -18, -14, -14, -12, -10, -10, -4, -13, -21, -19, -22, -24, -16, -10, -6, -2,
+ -2, -10, -12, -15, -17, -4, -4, -5, 7, 9, 3, 4, 7, 5, 18, 23,
+ 22, 28, 25, 22, 27, 34, 39, 43, 38, 41, 62, 71, 79, 78, 62, 55,
+ 55, 57, 49, 31, 23, 30, 21, 15, 7, -5, 1, 8, 9, 8, -3, -16,
+ -39, -46, -50, -60, -55, -58, -62, -53, -36, -33, -34, -34, -29, -18, -6, 5,
+ -2, -17, -23, -22, -24, -17, -8, 1, 9, 10, -4, -7, -8, -9, -6, -9,
+ -6, 0, -11, -14, -14, -21, -24, -21, -16, -10, 1, -3, -3, -5, -14, -11,
+ -7, -7, -5, 6, 9, 4, 8, 1, 3, 11, 16, 20, 26, 24, 20, 25,
+ 29, 36, 41, 32, 40, 51, 64, 77, 78, 67, 55, 54, 57, 53, 33, 27,
+ 25, 22, 20, 9, -3, -3, 3, 7, 6, 4, -16, -32, -42, -55, -60, -61,
+ -64, -70, -62, -49, -39, -41, -40, -37, -33, -18, -5, -8, -16, -24, -29, -31,
+ -28, -24, -15, -1, 1, -7, -11, -14, -13, -14, -18, -11, -8, -14, -16, -16,
+ -25, -31, -29, -31, -20, -12, -13, -6, -11, -19, -19, -14, -17, -12, -1, 2,
+ 6, 7, 2, 4, 8, 11, 18, 24, 21, 22, 19, 21, 33, 33, 32, 32,
+ 40, 55, 71, 76, 72, 58, 55, 62, 56, 42, 34, 28, 29, 26, 17, 4,
+ 2, 6, 4, 13, 12, -4, -18, -30, -45, -50, -51, -59, -63, -61, -47, -37,
+ -33, -32, -34, -32, -19, -4, -3, -5, -13, -21, -23, -22, -24, -13, 1, 5,
+ 5, -3, -6, -1, -7, -9, -2, 1, -2, -2, -4, -13, -16, -22, -22, -15,
+ -10, -4, 2, -1, -11, -8, -7, -12, -6, 1, 6, 12, 11, 8, 9, 9,
+ 9, 20, 23, 26, 25, 20, 24, 32, 34, 35, 33, 35, 49, 63, 74, 74,
+ 58, 55, 60, 54, 45, 33, 27, 25, 26, 19, 6, 4, 1, 1, 9, 12,
+ -1, -10, -26, -43, -50, -54, -61, -70, -69, -61, -50, -43, -40, -44, -44, -34,
+ -18, -12, -9, -15, -24, -25, -28, -31, -22, -12, -2, 1, -8, -8, -5, -12,
+ -14, -8, -8, -8, -5, -9, -11, -18, -27, -26, -22, -19, -12, -1, -4, -9,
+ -8, -11, -14, -12, -8, 0, 7, 5, 5, 6, 0, 3, 8, 13, 20, 18,
+ 13, 15, 22, 27, 29, 25, 26, 36, 51, 70, 71, 59, 56, 57, 55, 47,
+ 37, 25, 24, 27, 17, 9, 3, -2, -2, 8, 9, 6, -2, -16, -34, -44,
+ -47, -54, -63, -66, -63, -55, -44, -39, -42, -44, -35, -23, -11, -4, -10, -16,
+ -17, -23, -25, -22, -13, 1, 6, 1, 1, 4, -2, -4, 1, -1, 4, 3,
+ 2, 2, -3, -12, -15, -14, -15, -7, 3, 5, 3, 2, 1, -2, -4, -4,
+ 3, 9, 10, 13, 11, 9, 8, 9, 15, 22, 22, 20, 19, 21, 27, 30,
+ 28, 28, 28, 42, 61, 69, 65, 60, 60, 58, 55, 47, 35, 30, 30, 24,
+ 18, 10, 0, -1, 2, 6, 7, 3, -8, -24, -36, -43, -50, -59, -65, -66,
+ -62, -52, -43, -43, -44, -41, -35, -21, -12, -12, -13, -17, -23, -26, -30, -24,
+ -12, -4, -5, -3, -2, -5, -6, -6, -5, -3, -2, -1, 2, 2, -5, -3,
+ 2, 8, 17, 26, 32, 42, 50, 56, 68, 73, 64, 63, 65, 48, 56, 71,
+ 48, 49, 50, 26, 30, 30, 16, 25, 21, -2, 0, -13, -15, -2, -19, -17,
+ -16, -50, -49, -49, -81, -85, -88, -108, -112, -116, -127, -126, -113, -113, -106, -79,
+ -65, -48, -17, 5, 20, 41, 58, 63, 69, 59, 28, 17, 0, -32, -41, -52,
+ -69, -63, -61, -59, -41, -26, -19, 6, 28, 33, 52, 67, 70, 81, 87, 84,
+ 90, 93, 84, 72, 69, 60, 45, 56, 57, 40, 46, 39, 25, 29, 25, 16,
+ 21, 12, -1, -3, -11, -8, -5, -16, -12, -21, -41, -38, -48, -68, -70, -77,
+ -91, -93, -98, -106, -103, -93, -92, -82, -60, -47, -30, -4, 13, 27, 44, 56,
+ 60, 62, 47, 23, 13, -8, -32, -40, -54, -64, -59, -59, -53, -36, -26, -14,
+ 12, 27, 36, 56, 66, 72, 84, 86, 86, 93, 92, 82, 73, 70, 57, 49,
+ 59, 52, 43, 47, 37, 29, 30, 24, 18, 18, 7, -2, -6, -11, -7, -10,
+ -16, -14, -29, -42, -42, -57, -71, -73, -83, -93, -96, -102, -107, -101, -93, -90,
+ -75, -55, -41, -22, 3, 19, 33, 50, 59, 61, 60, 41, 21, 10, -14, -33,
+ -43, -57, -63, -60, -61, -51, -36, -27, -9, 15, 26, 40, 59, 66, 74, 85,
+ 85, 88, 94, 90, 80, 75, 69, 56, 54, 60, 50, 47, 46, 36, 31, 30,
+ 23, 19, 15, 4, -3, -7, -10, -9, -14, -17, -19, -35, -44, -47, -63, -73,
+ -77, -88, -96, -98, -104, -107, -99, -92, -86, -69, -50, -35, -14, 9, 24, 38,
+ 54, 60, 61, 56, 36, 19, 4, -20, -35, -46, -60, -62, -61, -60, -48, -35,
+ -25, -3, 17, 27, 45, 60, 66, 77, 85, 86, 91, 94, 88, 80, 75, 67,
+ 56, 58, 59, 50, 49, 45, 36, 33, 30, 23, 19, 13, 2, -5, -8, -10,
+ -11, -16, -18, -25, -40, -45, -53, -68, -76, -81, -91, -97, -100, -106, -106, -97,
+ -90, -81, -63, -44, -28, -6, 15, 28, 44, 57, 61, 61, 52, 31, 16, -1,
+ -24, -37, -50, -61, -62, -62, -59, -46, -35, -22, 1, 18, 30, 48, 61, 68,
+ 79, 85, 87, 92, 93, 86, 80, 75, 66, 58, 60, 58, 51, 50, 44, 37,
+ 33, 29, 23, 17, 10, 0, -6, -9, -10, -14, -18, -21, -31, -43, -48, -59,
+ -72, -78, -85, -94, -99, -102, -107, -104, -95, -88, -76, -56, -39, -22, 2, 20,
+ 33, 49, 59, 61, 60, 47, 27, 12, -7, -27, -40, -53, -62, -62, -63, -57,
+ -44, -34, -18, 5, 19, 33, 51, 61, 70, 81, 85, 88, 94, 92, 85, 80,
+ 74, 65, 60, 62, 57, 52, 50, 43, 37, 33, 28, 22, 15, 8, -2, -7,
+ -10, -12, -16, -20, -24, -36, -46, -52, -64, -75, -81, -89, -97, -100, -104, -107,
+ -102, -93, -85, -70, -50, -33, -14, 8, 25, 38, 53, 61, 61, 58, 42, 24,
+ 8, -12, -30, -43, -56, -62, -63, -63, -54, -43, -32, -13, 7, 20, 37, 53,
+ 62, 72, 82, 85, 89, 94, 90, 84, 80, 73, 64, 62, 62, 56, 53, 49,
+ 43, 37, 33, 27, 20, 14, 5, -3, -8, -11, -13, -18, -22, -28, -40, -49,
+ -57, -69, -78, -84, -92, -99, -102, -105, -106, -99, -90, -81, -64, -44, -27, -7,
+ 14, 29, 43, 56, 61, 61, 54, 37, 20, 4, -17, -33, -46, -58, -62, -64,
+ -62, -52, -42, -29, -9, 9, 23, 40, 55, 64, 74, 83, 86, 91, 93, 89,
+ 84, 80, 72, 65, 64, 62, 56, 53, 49, 42, 37, 33, 26, 19, 12, 3,
+ -5, -8, -12, -16, -20, -24, -33, -44, -52, -61, -73, -80, -87, -95, -100, -103,
+ -106, -104, -96, -88, -76, -57, -38, -21, 0, 20, 33, 47, 59, 62, 60, 51,
+ 33, 17, -1, -21, -36, -49, -59, -63, -64, -61, -51, -40, -25, -5, 11, 26,
+ 43, 56, 65, 76, 83, 87, 92, 93, 88, 84, 79, 71, 65, 65, 61, 56,
+ 53, 48, 42, 37, 32, 25, 17, 10, 1, -6, -10, -13, -18, -22, -27, -37,
+ -48, -55, -65, -76, -83, -90, -97, -101, -104, -106, -102, -94, -84, -71, -51, -33,
+ -15, 7, 24, 38, 51, 60, 62, 59, 46, 29, 13, -6, -25, -39, -52, -60,
+ -63, -64, -59, -49, -38, -21, -1, 14, 29, 46, 57, 67, 78, 84, 88, 92,
+ 92, 87, 83, 78, 70, 66, 65, 61, 57, 53, 48, 42, 37, 31, 23, 15,
+ 7, -1, -7, -11, -15, -20, -24, -31, -41, -51, -59, -69, -79, -85, -93, -99,
+ -102, -105, -106, -100, -91, -80, -65, -45, -27, -8, 13, 29, 42, 55, 61, 61,
+ 56, 42, 25, 8, -11, -28, -42, -54, -61, -64, -64, -57, -47, -35, -17, 1,
+ 16, 33, 48, 59, 69, 79, 84, 89, 93, 91, 87, 83, 77, 70, 67, 65,
+ 60, 57, 53, 47, 41, 36, 29, 21, 14, 5, -3, -8, -12, -17, -22, -27,
+ -35, -45, -54, -63, -73, -81, -88, -95, -100, -103, -105, -104, -97, -88, -76, -58,
+ -39, -21, -1, 18, 33, 46, 58, 62, 61, 53, 38, 21, 4, -15, -31, -45,
+ -56, -62, -65, -64, -56, -46, -32, -13, 4, 19, 36, 50, 61, 71, 80, 85,
+ 90, 92, 90, 86, 82, 76, 70, 68, 65, 60, 57, 52, 46, 41, 35, 27,
+ 19, 12, 3, -5, -9, -14, -19, -24, -29, -38, -48, -57, -66, -76, -84, -91,
+ -97, -101, -104, -105, -102, -94, -84, -71, -52, -33, -15, 5, 23, 37, 50, 60,
+ 62, 60, 50, 34, 17, -1, -19, -35, -48, -58, -63, -65, -62, -54, -43, -28,
+ -10, 7, 22, 39, 52, 62, 73, 81, 86, 91, 92, 89, 86, 82, 75, 70,
+ 68, 64, 60, 57, 52, 46, 40, 34, 26, 17, 9, 1, -6, -11, -15, -21,
+ -26, -32, -42, -52, -60, -70, -79, -86, -93, -99, -102, -104, -105, -100, -91, -80,
+ -65, -46, -27, -9, 11, 28, 42, 54, 61, 62, 58, 46, 30, 13, -6, -23,
+ -38, -51, -60, -64, -65, -61, -52, -41, -25, -6, 9, 26, 42, 54, 64, 75,
+ 82, 87, 91, 91, 89, 85, 81, 74, 71, 68, 64, 60, 56, 51, 45, 39,
+ 32, 24, 16, 7, -1, -7, -12, -17, -23, -28, -36, -45, -55, -64, -73, -82,
+ -88, -95, -100, -103, -105, -104, -97, -88, -76, -59, -40, -22, -2, 17, 32, 45,
+ 57, 62, 62, 56, 42, 26, 9, -10, -27, -41, -53, -61, -65, -65, -60, -50,
+ -38, -21, -3, 12, 29, 44, 55, 66, 76, 82, 88, 91, 91, 88, 85, 80,
+ 74, 71, 68, 63, 60, 56, 50, 44, 38, 30, 22, 14, 5, -3, -9, -14,
+ -19, -25, -31, -39, -49, -58, -67, -77, -84, -91, -97, -101, -103, -105, -102, -95,
+ -84, -71, -53, -34, -16, 4, 22, 37, 49, 59, 63, 61, 53, 38, 22, 4,
+ -14, -30, -44, -56, -62, -66, -65, -58, -48, -35, -17, -1, 15, 32, 46, 57,
+ 68, 77, 83, 88, 91, 90, 88, 84, 79, 74, 71, 67, 63, 60, 55, 49,
+ 43, 37, 28, 20, 12, 3, -5, -10, -15, -21, -27, -33, -43, -52, -61, -70,
+ -79, -86, -93, -98, -102, -104, -104, -100, -92, -81, -66, -47, -28, -10, 10, 27,
+ 40, 53, 61, 63, 59, 49, 34, 18, -1, -18, -34, -47, -58, -63, -66, -64,
+ -56, -46, -31, -14, 2, 18, 35, 48, 59, 70, 78, 84, 89, 91, 90, 87,
+ 83, 78, 74, 71, 67, 63, 59, 54, 49, 42, 35, 27, 18, 9, 1, -6,
+ -12, -17, -23, -29, -36, -46, -55, -64, -73, -82, -89, -95, -100, -102, -104, -103,
+ -97, -88, -76, -60, -41, -23, -4, 15, 31, 44, 55, 62, 62, 57, 46, 30,
+ 13, -5, -22, -37, -50, -59, -64, -66, -62, -55, -43, -28, -11, 5, 22, 37,
+ 50, 61, 71, 79, 85, 89, 91, 89, 87, 82, 77, 73, 70, 66, 63, 59,
+ 53, 47, 41, 33, 24, 16, 7, -1, -8, -14, -19, -25, -32, -40, -49, -58,
+ -67, -76, -84, -91, -96, -101, -103, -104, -102, -95, -85, -72, -55, -37, -18, 1,
+ 19, 34, 47, 57, 62, 62, 56, 43, 28, 10, -8, -25, -39, -52, -60, -65,
+ -66, -62, -53, -42, -25, -9, 8, 24, 39, 51, 62, 72, 80, 86, 90, 90,
+ 89, 86, 82, 77, 73, 70, 66, 62, 58, 53, 47, 40, 33, 24, 15, 6,
+ -2, -8, -14, -19, -25, -32, -40, -49, -58, -67, -72, -103, -18, -76, 0, 0,
+ 0, 0, 1, 2, 3, 5, 6, 0, -7, -8, -15, -9, 10, 8, 17, 33,
+ 14, 5, 38, 44, 31, 63, 70, 51, 73, 82, 68, 85, 100, 96, 97, 103,
+ 115, 114, 112, 127, 122, 110, 116, 113, 109, 120, 120, 118, 113, 91, 93, 109,
+ 97, 98, 115, 110, 109, 120, 112, 94, 75, 63, 69, 72, 64, 64, 59, 45,
+ 39, 36, 35, 42, 42, 24, 5, 2, 3, 4, 7, 9, 11, 14, 17, 19,
+ 14, -3, -20, -26, -30, -26, -24, -31, -32, -34, -40, -39, -33, -34, -45, -56,
+ -60, -66, -64, -55, -60, -62, -56, -59, -58, -50, -56, -70, -73, -76, -86, -77,
+ -70, -80, -76, -71, -77, -71, -66, -76, -85, -82, -90, -95, -80, -82, -92, -85,
+ -86, -94, -85, -79, -86, -92, -90, -94, -101, -92, -85, -90, -84, -77, -78, -74,
+ -73, -85, -86, -85, -95, -85, -77, -90, -88, -83, -94, -93, -83, -81, -81, -86,
+ -89, -89, -94, -88, -77, -77, -71, -59, -58, -59, -63, -72, -74, -77, -73, -61,
+ -67, -72, -67, -73, -80, -74, -68, -60, -56, -65, -70, -67, -72, -66, -52, -49,
+ -40, -27, -27, -32, -39, -47, -50, -42, -30, -31, -34, -32, -38, -46, -46, -43,
+ -35, -20, -16, -24, -30, -30, -31, -24, -13, -6, 4, 13, 11, 3, -5, -9,
+ -2, 12, 15, 15, 16, 9, 3, -2, -5, -1, 12, 24, 30, 29, 20, 17,
+ 22, 25, 30, 41, 47, 49, 46, 37, 32, 41, 52, 54, 60, 61, 52, 48,
+ 45, 36, 35, 43, 51, 60, 67, 69, 60, 57, 63, 63, 64, 73, 75, 72,
+ 69, 63, 67, 78, 78, 82, 89, 80, 73, 76, 67, 60, 64, 67, 73, 79,
+ 83, 88, 82, 75, 80, 81, 77, 83, 83, 76, 74, 77, 83, 85, 86, 94,
+ 89, 80, 82, 78, 69, 68, 68, 69, 78, 80, 81, 90, 83, 73, 79, 77,
+ 70, 73, 70, 62, 65, 73, 75, 76, 84, 82, 70, 71, 69, 59, 57, 54,
+ 48, 53, 63, 64, 68, 76, 66, 57, 58, 51, 42, 40, 33, 28, 37, 46,
+ 49, 55, 56, 42, 37, 37, 27, 22, 20, 10, 4, 8, 15, 24, 30, 31,
+ 24, 14, 8, -3, -14, -21, -26, -26, -15, -4, -1, -4, -13, -21, -26, -34,
+ -39, -42, -50, -57, -63, -66, -60, -47, -43, -48, -51, -57, -66, -75, -82, -88,
+ -91, -88, -78, -74, -81, -86, -85, -92, -101, -100, -102, -109, -109, -110, -112, -113,
+ -115, -109, -106, -113, -113, -107, -110, -110, -106, -108, -112, -109, -110, -114, -111, -98,
+ -95, -98, -93, -93, -98, -94, -89, -81, -69, -65, -71, -73, -73, -77, -73, -62,
+ -56, -48, -40, -41, -45, -47, -47, -37, -20, -11, -4, 5, 4, 3, 6, 9,
+ 16, 30, 39, 47, 51, 44, 40, 45, 47, 50, 59, 64, 66, 68, 65, 65,
+ 75, 80, 78, 87, 95, 91, 93, 98, 96, 98, 104, 100, 96, 99, 104, 101,
+ 100, 106, 107, 105, 108, 109, 109, 110, 111, 110, 101, 87, 82, 84, 81, 82,
+ 88, 89, 90, 91, 85, 71, 57, 49, 48, 51, 52, 55, 59, 58, 58, 60,
+ 61, 61, 57, 42, 24, 14, 7, 5, 9, 11, 15, 20, 21, 19, 11, -3,
+ -18, -27, -33, -31, -25, -24, -21, -16, -16, -14, -11, -17, -29, -40, -49, -59,
+ -61, -55, -54, -52, -45, -42, -41, -41, -48, -59, -65, -72, -81, -79, -72, -73,
+ -69, -62, -61, -59, -60, -69, -76, -79, -87, -92, -84, -81, -82, -76, -72, -71,
+ -67, -66, -72, -79, -81, -87, -94, -92, -87, -86, -82, -76, -75, -75, -78, -85,
+ -87, -91, -96, -91, -82, -83, -80, -74, -74, -71, -64, -64, -68, -73, -77, -81,
+ -87, -88, -82, -79, -76, -70, -69, -72, -76, -80, -84, -87, -82, -71, -67, -64,
+ -58, -57, -55, -49, -43, -39, -40, -47, -54, -58, -64, -66, -61, -58, -54, -49,
+ -50, -55, -59, -63, -65, -58, -45, -38, -32, -25, -24, -23, -18, -13, -5, 3,
+ 4, -2, -11, -17, -23, -26, -23, -20, -18, -15, -18, -24, -28, -28, -21, -7,
+ 3, 11, 18, 20, 19, 22, 24, 30, 40, 47, 51, 49, 40, 32, 28, 24,
+ 23, 25, 25, 23, 20, 15, 15, 23, 34, 43, 51, 59, 59, 58, 59, 58,
+ 60, 67, 73, 78, 84, 85, 78, 71, 68, 63, 60, 60, 57, 53, 50, 50,
+ 56, 65, 70, 76, 84, 84, 81, 81, 79, 76, 79, 84, 87, 91, 96, 98,
+ 94, 88, 85, 81, 76, 73, 70, 66, 66, 70, 76, 80, 84, 91, 92, 87,
+ 86, 83, 78, 76, 78, 81, 85, 88, 91, 96, 93, 86, 83, 78, 71, 68,
+ 64, 61, 64, 71, 74, 78, 84, 86, 80, 76, 72, 64, 59, 56, 55, 59,
+ 66, 69, 74, 79, 76, 69, 64, 57, 48, 43, 39, 39, 45, 52, 56, 62,
+ 63, 55, 47, 41, 31, 21, 15, 8, 5, 9, 16, 24, 31, 35, 33, 26,
+ 19, 10, 0, -6, -9, -7, -7, -13, -17, -22, -26, -31, -34, -37, -40, -42,
+ -44, -46, -48, -50, -51, -54, -56, -58, -61, -64, -67, -70, -74, -78, -82, -86,
+ -90, -93, -97, -99, -102, -104, -106, -108, -109, -110, -111, -112, -113, -113, -114, -114,
+ -115, -115, -115, -115, -115, -114, -113, -111, -109, -107, -104, -100, -97, -93, -90, -87,
+ -84, -82, -80, -78, -76, -74, -73, -71, -69, -67, -65, -61, -58, -53, -48, -42,
+ -35, -28, -21, -13, -6, 1, 8, 15, 21, 26, 31, 35, 38, 41, 44, 46,
+ 48, 50, 52, 55, 58, 61, 64, 68, 72, 76, 80, 83, 87, 90, 92, 94,
+ 96, 98, 99, 100, 101, 102, 102, 103, 103, 103, 103, 104, 103, 103, 103, 102,
+ 101, 99, 97, 94, 92, 88, 85, 81, 78, 74, 71, 67, 64, 61, 58, 55,
+ 53, 51, 49, 47, 46, 44, 42, 40, 37, 34, 30, 26, 22, 17, 12, 8,
+ 3, -1, -5, -9, -13, -16, -20, -23, -26, -29, -31, -33, -35, -37, -38, -40,
+ -42, -44, -46, -48, -51, -54, -56, -59, -61, -64, -65, -67, -69, -70, -72, -74,
+ -75, -77, -78, -80, -81, -82, -83, -84, -85, -86, -86, -87, -88, -89, -90, -90,
+ -91, -92, -92, -92, -92, -92, -92, -91, -91, -92, -92, -92, -93, -93, -94, -94,
+ -94, -95, -95, -95, -95, -95, -95, -95, -95, -95, -94, -93, -92, -91, -90, -89,
+ -87, -86, -85, -85, -85, -84, -84, -85, -85, -85, -85, -85, -85, -85, -85, -85,
+ -84, -83, -82, -81, -79, -77, -75, -73, -70, -68, -65, -63, -62, -60, -59, -59,
+ -59, -59, -59, -59, -59, -60, -59, -59, -59, -58, -57, -55, -53, -50, -47, -44,
+ -40, -36, -32, -29, -25, -22, -20, -18, -17, -16, -15, -15, -16, -16, -16, -16,
+ -16, -16, -15, -13, -11, -9, -6, -2, 2, 6, 10, 15, 19, 22, 26, 29,
+ 31, 33, 35, 36, 36, 36, 36, 35, 35, 35, 35, 35, 36, 38, 40, 42,
+ 45, 48, 52, 55, 58, 61, 64, 67, 70, 72, 73, 74, 75, 76, 76, 76,
+ 75, 75, 74, 74, 74, 74, 74, 75, 77, 78, 80, 82, 83, 85, 87, 89,
+ 90, 91, 92, 93, 94, 94, 94, 94, 94, 93, 93, 92, 91, 91, 90, 90,
+ 90, 90, 91, 91, 92, 92, 93, 93, 94, 94, 94, 94, 94, 94, 94, 94,
+ 93, 93, 92, 92, 91, 90, 89, 88, 87, 87, 86, 86, 85, 85, 85, 84,
+ 84, 83, 83, 82, 81, 80, 79, 78, 77, 77, 76, 75, 74, 72, 71, 70,
+ 68, 67, 65, 64, 63, 61, 60, 58, 57, 55, 53, 50, 48, 45, 43, 40,
+ 38, 36, 34, 32, 30, 29, 27, 25, 23, 21, 19, 17, 14, 12, 9, 6,
+ 3, 0, -4, -8, -12, -17, -21, -25, -29, -33, -36, -39, -42, -45, -47, -49,
+ -51, -53, -55, -58, -60, -63, -65, -68, -71, -74, -77, -81, -84, -87, -91, -94,
+ -97, -99, -102, -104, -105, -107, -108, -109, -110, -111, -111, -112, -112, -113, -113, -113,
+ -113, -113, -113, -112, -111, -109, -107, -105, -102, -99, -96, -93, -90, -87, -84, -82,
+ -79, -77, -75, -73, -70, -69, -66, -64, -60, -58, -53, -49, -44, -39, -32, -27,
+ -19, -14, -8, -3, 3, 11, 22, 10, 8, 1, 1, 1, 1, 1, 2, 2,
+ 2, 2, 3, 3, 3, 3, 4, 4, 5, 5, 6, 5, 6, 6, 6, 6,
+ 6, 6, 7, 5, 7, 5, 6, 4, 6, 4, 4, 4, 4, 3, 3, 2,
+ 3, 1, 3, -2, 2, 0, 0, 0, 0, -2, -1, -2, -3, -3, 0, -5,
+ -1, -2, -2, -2, -1, 0, -3, -1, -1, 0, 1, -1, 0, -1, 0, 0,
+ 1, 0, 0, 1, -1, 1, -1, 1, -2, -1, -3, 0, -2, -1, -2, -2,
+ -2, -3, -2, -3, -4, -5, -6, -5, -9, -8, -9, -9, -9, -11, -10, -13,
+ -14, -14, -15, -16, -15, -17, -19, -19, -21, -18, -21, -20, -22, -20, -24, -21,
+ -22, -19, -20, -21, -17, -19, -16, -17, -15, -17, -13, -11, -10, -7, -5, -3,
+ 2, 6, 4, 8, 9, 18, 14, 31, 25, 24, 25, 24, 21, 13, 15, 15,
+ 11, 9, 1, 4, -20, -18, -38, -44, -57, -57, -55, -55, -52, -55, -46, -47,
+ -40, -32, -26, -19, -16, -2, 3, 13, 19, 28, 30, 37, 40, 44, 39, 38,
+ 35, 34, 37, 41, 48, 51, 53, 58, 61, 70, 74, 76, 76, 80, 81, 86,
+ 83, 83, 78, 78, 73, 69, 65, 55, 47, 40, 36, 29, 23, 16, 14, 8,
+ -2, -4, -11, -11, -19, -22, -26, -25, -34, -39, -40, -41, -45, -49, -51, -57,
+ -56, -58, -59, -66, -70, -70, -72, -65, -64, -59, -53, -49, -45, -34, -29, -21,
+ -15, -10, -6, -6, -3, -4, 2, 3, 3, 3, -1, -3, -11, -11, -13, -16,
+ -22, -24, -27, -32, -34, -37, -35, -31, -30, -26, -25, -22, -21, -15, -13, -15,
+ -10, -12, -12, -7, 2, 15, 22, 27, 24, 28, 22, 22, 21, 22, 17, 13,
+ 14, 9, 5, 2, -8, -12, -16, -14, -17, -17, -17, -17, -14, -8, -3, -3,
+ 0, 5, 3, 5, 6, 3, -2, -6, -9, -11, -13, -18, -19, -29, -42, -61,
+ -72, -79, -81, -83, -82, -79, -76, -65, -54, -42, -33, -24, -14, 0, 18, 33,
+ 48, 62, 75, 87, 93, 99, 100, 102, 102, 104, 102, 100, 100, 96, 93, 95,
+ 96, 105, 109, 112, 111, 110, 106, 106, 104, 102, 97, 93, 85, 80, 71, 60,
+ 48, 36, 26, 12, 0, -5, -13, -21, -28, -31, -36, -42, -49, -53, -56, -59,
+ -61, -63, -64, -64, -63, -67, -70, -77, -75, -77, -78, -79, -80, -81, -80, -75,
+ -69, -64, -57, -50, -43, -35, -26, -16, -6, 6, 13, 17, 22, 26, 25, 27,
+ 27, 26, 23, 19, 11, 5, -5, -12, -19, -24, -31, -37, -42, -45, -50, -49,
+ -48, -47, -43, -41, -38, -38, -37, -35, -35, -37, -42, -40, -33, -27, -20, -12,
+ -11, -13, -10, -9, -10, -10, -10, -13, -11, -9, -8, -11, -13, -16, -18, -17,
+ -15, -15, -14, -12, -8, -3, 3, 8, 16, 22, 25, 31, 34, 36, 36, 34,
+ 31, 25, 23, 24, 26, 23, 13, -1, -16, -29, -38, -45, -51, -56, -57, -54,
+ -48, -39, -34, -29, -20, -10, 0, 13, 27, 39, 54, 68, 79, 87, 92, 94,
+ 96, 94, 92, 89, 87, 82, 76, 72, 71, 74, 76, 81, 83, 83, 84, 84,
+ 85, 85, 82, 81, 82, 80, 75, 71, 66, 57, 46, 34, 24, 15, 5, -2,
+ -8, -13, -19, -26, -31, -37, -41, -44, -48, -53, -54, -53, -54, -54, -57, -61,
+ -64, -67, -70, -72, -75, -77, -79, -79, -76, -73, -70, -63, -58, -53, -47, -38,
+ -29, -21, -13, -6, 0, 4, 7, 7, 8, 8, 6, 5, -1, -8, -15, -22,
+ -30, -36, -41, -47, -51, -54, -56, -58, -59, -56, -50, -45, -42, -37, -31, -26,
+ -23, -23, -23, -24, -21, -14, -6, 2, 8, 12, 15, 18, 21, 20, 20, 20,
+ 20, 21, 23, 22, 18, 13, 10, 8, 6, 5, 4, 3, 2, 2, 4, 7,
+ 10, 13, 18, 22, 24, 26, 28, 27, 21, 14, 8, 5, 4, 2, -3, -12,
+ -24, -37, -50, -59, -67, -76, -80, -79, -75, -69, -61, -55, -47, -38, -27, -15,
+ -2, 11, 27, 43, 58, 71, 82, 90, 94, 96, 98, 98, 98, 95, 89, 84,
+ 81, 79, 81, 85, 88, 89, 91, 92, 92, 90, 89, 89, 88, 85, 82, 79,
+ 75, 67, 58, 48, 37, 25, 14, 4, -4, -10, -17, -24, -31, -37, -42, -47,
+ -51, -56, -59, -59, -59, -59, -61, -63, -65, -67, -70, -72, -74, -76, -78, -78,
+ -78, -75, -70, -66, -61, -56, -50, -41, -33, -23, -14, -6, 2, 10, 16, 19,
+ 21, 23, 24, 24, 22, 19, 13, 7, 0, -6, -14, -20, -25, -27, -32, -37,
+ -39, -39, -38, -36, -33, -30, -27, -22, -19, -19, -20, -23, -24, -22, -18, -13,
+ -8, -4, 0, 2, 5, 6, 5, 3, 2, 4, 6, 6, 5, 1, -2, -6,
+ -8, -9, -10, -11, -13, -12, -12, -11, -9, -4, 0, 4, 8, 13, 18, 20,
+ 19, 14, 10, 6, 4, 4, 4, 0, -8, -17, -28, -38, -49, -60, -68, -72,
+ -72, -70, -65, -59, -54, -46, -37, -27, -17, -5, 8, 22, 37, 51, 66, 77,
+ 84, 88, 91, 93, 94, 94, 91, 85, 79, 75, 74, 76, 77, 80, 83, 85,
+ 85, 85, 86, 86, 85, 85, 85, 83, 81, 77, 70, 64, 55, 44, 32, 22,
+ 13, 6, -1, -9, -16, -22, -27, -32, -38, -43, -46, -47, -47, -47, -48, -49,
+ -49, -50, -52, -54, -56, -59, -62, -64, -66, -65, -64, -61, -59, -56, -53, -48,
+ -41, -33, -25, -17, -10, -2, 4, 9, 13, 15, 16, 17, 17, 15, 11, 7,
+ 1, -7, -15, -22, -27, -33, -38, -43, -47, -49, -50, -50, -49, -46, -42, -37,
+ -31, -28, -28, -29, -30, -29, -26, -22, -17, -13, -8, -3, 2, 6, 7, 6,
+ 5, 6, 8, 10, 12, 11, 8, 5, 3, 1, -1, -2, -3, -4, -6, -7,
+ -6, -3, 0, 1, 5, 10, 16, 20, 21, 19, 15, 10, 8, 6, 6, 4,
+ 0, -5, -12, -22, -33, -45, -57, -65, -70, -72, -70, -68, -64, -58, -51, -44,
+ -36, -24, -13, -2, 11, 27, 43, 58, 70, 78, 83, 88, 92, 96, 97, 93,
+ 89, 85, 81, 80, 81, 83, 86, 88, 90, 91, 91, 91, 91, 91, 91, 91,
+ 89, 86, 83, 79, 72, 63, 52, 41, 30, 21, 13, 4, -5, -11, -17, -23,
+ -31, -38, -44, -47, -49, -50, -52, -54, -55, -57, -57, -58, -60, -63, -66, -69,
+ -72, -74, -73, -72, -70, -69, -67, -64, -59, -53, -45, -37, -30, -22, -14, -7,
+ -2, 3, 8, 10, 12, 12, 13, 12, 8, 3, -4, -10, -16, -21, -27, -33,
+ -37, -41, -44, -46, -48, -48, -45, -48, -43, -37, -33, -31, -32, -33, -32, -29,
+ -26, -22, -18, -12, -5, 1, 6, 9, 9, 9, 9, 11, 14, 16, 16, 14,
+ 12, 8, 5, 3, 2, 1, -1, -3, -4, -4, -2, -1, 2, 5, 11, 18,
+ 24, 27, 27, 24, 20, 17, 15, 13, 11, 9, 5, -1, -10, -22, -35, -49,
+ -61, -70, -75, -77, -76, -73, -69, -63, -56, -47, -36, -25, -13, 0, 16, 34,
+ 52, 67, 79, 88, 95, 101, 106, 109, 108, 105, 100, 95, 92, 90, 91, 93,
+ 96, 99, 100, 101, 101, 101, 101, 101, 101, 100, 97, 95, 91, 85, 78, 67,
+ 55, 43, 31, 21, 11, 1, -7, -14, -21, -29, -37, -45, -51, -54, -56, -58,
+ -60, -62, -64, -65, -66, -67, -69, -72, -76, -80, -82, -84, -83, -82, -80, -79,
+ -77, -73, -67, -60, -51, -42, -34, -25, -16, -8, -2, 4, 9, 12, 13, 14,
+ 14, 13, 9, 3, -5, -12, -18, -25, -31, -37, -42, -47, -50, -53, -54, -53,
+ -48, -41, -36, -32, -31, -31, -32, -31, -28, -25, -22, -17, -12, -5, 1, 1,
+ -2, -1, -9, -9, -6, 5, 6, -1, -10, 8, 24, 11, -2, -14, -9, -15,
+ -13, 5, 14, 12, -6, -1, -12, 1, -9, 12, 12, 10, 5, -19, -11, -13,
+ -2, 8, 5, 1, -2, -3, 9, -6, 6, 5, 6, -3, -17, -7, 3, 2,
+ -1, 0, 7, -7, 5, 4, 6, -18, -24, 6, 20, -1, -4, -1, 10, 3,
+ -10, 8, 7, -11, -17, -15, 5, 18, 4, 1, 8, -16, -4, 0, 11, 9,
+ -10, -15, 0, -22, -12, 19, 34, 16, -9, -16, -7, -12, -10, 13, 23, -1,
+ -10, -2, -3, -11, 13, 7, -6, -9, 3, 11, -10, -18, 12, 22, 7, -27,
+ -29, -4, 20, 20, 10, 8, -16, -26, -6, 22, 21, 7, 15, 8, -50, -50,
+ -7, 35, 22, -13, 32, 41, -33, -46, -10, 23, -7, -25, 23, 21, -38, -36,
+ 14, 44, 2, 2, 34, -14, -51, -29, 11, 19, 7, 22, 13, -23, -21, -8,
+ -9, 1, 14, 26, 26, -8, -34, -33, 4, 1, -6, -2, 16, -7, -23, 12,
+ 27, 5, 6, 6, 0, -8, 0, -1, -17, -13, -12, 3, 9, 4, 11, 23,
+ 36, 0, -43, -16, 4, -21, -26, 27, 16, -25, 3, 65, 4, -34, 24, -10,
+ -38, -14, 13, 4, -15, 36, 44, -42, -51, 20, -5, -6, 68, 20, -18, -39,
+ -11, 9, 17, 6, -33, -20, -13, 48, 30, 22, -4, -9, -53, -20, 32, 32,
+ -16, 17, -11, -36, -8, -5, 39, 28, 33, 21, -64, -48, 3, -22, 15, 62,
+ -26, 0, 3, 5, 73, -14, -48, -20, -59, 4, 70, 60, -7, -2, -88, -22,
+ -17, 39, 17, 33, -3, 15, 28, -47, -80, -37, 5, 7, 104, 16, -99, -92,
+ -36, 109, 78, 26, -15, -92, -21, 62, 48, -51, -81, -25, 55, 63, 35, 21,
+ -115, -54, 101, 73, -41, -110, -66, 50, 107, 45, -8, -109, -38, 12, 102, 3,
+ 17, -45, -2, -36, 39, 46, -12, -28, -27, -17, 17, -18, 82, -5, -3, -25,
+ -5, -14, 15, 9, -3, -17, -6, 2, 7, -36, -13, 6, 21, -23, -20, 16,
+ -18, 3, -2, 26, 0, 13, -23, -2, -19, -28, -18, 15, 12, 22, -4, 23,
+ -17, -22, -9, -18, -4, 11, 13, 0, 34, -16, -20, 26, 23, 15, -4, -25,
+ 7, 8, -9, 8, 44, 1, -40, 17, -32, 9, -30, -52, 52, 3, 2, -21,
+ 83, 58, -14, -46, -61, -12, -67, -20, 64, 72, 57, -10, 5, 1, -77, 31,
+ -47, -39, 12, 22, 57, 28, 0, 9, -76, 15, -74, 33, -12, 39, 114, -35,
+ -36, -38, -23, 27, -21, 14, 56, 47, 6, -72, -61, -4, 18, -4, 19, 13,
+ 45, 71, 48, -1, -125, -52, -56, -20, -18, -12, 51, 78, 68, -46, 32, -40,
+ -29, -28, -81, -25, 75, 42, 58, -38, 1, -29, -34, 31, -36, -14, 10, 64,
+ 37, 2, -31, -72, -17, -33, 30, -52, -54, 25, 43, 70, 81, -9, -73, 4,
+ -65, 15, -28, 25, 0, 28, 19, 51, -26, 6, 0, -37, -15, -22, -20, -16,
+ -5, 50, 56, 67, 25, 16, -35, -29, -14, -39, 19, -24, -52, -13, -32, -10,
+ 39, 33, 59, 6, 37, 55, 11, -9, -35, -15, -57, -56, -36, -34, 19, 19,
+ 6, 20, 17, -11, 5, 26, 19, 16, 7, -20, -26, -55, -62, -36, -18, 19,
+ 37, 47, 25, -6, -14, 1, -4, -13, 12, 23, 34, 38, 41, 33, 31, -10,
+ -56, -52, -49, -31, -40, -21, -12, 0, 5, 12, 22, 22, 21, 31, 12, 2,
+ -8, -4, -18, -7, 3, 1, -1, 11, 12, 18, 17, 9, -2, -12, -13, -11,
+ -1, 8, 3, 3, 2, 5, -5, -16, -15, -13, -8, -12, -9, -2, -1, 2,
+ 7, 10, 7, 11, 14, 7, -1, -4, 5, -3, -2, 0, -6, -10, -1, -5,
+ 3, 9, 0, -8, -9, -6, -6, 0, 6, 3, 6, 7, 10, 0, -8, -3,
+ -5, -1, -8, -7, -4, -3, -3, 0, -1, -6, 2, 7, 7, 5, 4, 10,
+ 5, 8, -1, -11, -15, -11, -15, -10, -1, -8, -12, -5, 1, 3, 6, 8,
+ 11, 18, 22, 26, 10, -10, -1, -15, -3, -21, -16, -14, -12, -7, -8, -18,
+ -20, -11, 9, 20, 27, 26, 11, 1, 21, 6, 3, -9, -15, -9, -20, 3,
+ 5, 21, 14, 6, 11, -21, -22, -6, -21, -23, -18, 11, 6, 5, 21, 9,
+ 23, 16, -3, -30, -7, -27, -4, 5, 18, 22, 16, 2, 7, -1, -2, -10,
+ -14, -10, -17, -10, -15, -16, 3, 12, 30, 18, -1, -6, -15, -3, 5, 11,
+ -18, -2, 8, 21, 11, -13, -4, -30, -7, 0, 12, 25, -3, 17, 14, -20,
+ -6, -27, -41, -11, -12, 23, -8, 13, 24, 18, 27, -11, -8, -12, -2, 17,
+ 23, 13, -20, -21, -2, -21, -34, -46, -23, 28, 48, 9, -10, 8, 29, 27,
+ 5, -29, -12, 13, -5, -2, -35, 1, 3, 24, 13, 17, -18, -30, -21, 14,
+ -1, 6, -8, 48, 45, -7, -34, -49, -32, -6, -26, 20, 29, 76, 30, -21,
+ -66, -36, -15, 40, -5, 29, 3, 10, -39, -25, -2, 24, 19, 19, -4, -8,
+ 3, -22, -23, -18, 13, 17, -3, -25, 23, 66, 26, -18, -27, -34, -30, -30,
+ 36, 25, 28, -22, -17, -7, -22, 21, 18, 42, 8, -25, -28, -31, -10, 15,
+ 18, 0, -1, -5, 16, -12, 13, 13, 12, -8, -37, -9, 13, -5, 8, -3,
+ 13, -8, 4, 24, -16, -43, -18, 26, 26, -11, -9, 19, 9, -15, 9, 15,
+ -12, -31, -27, 8, 29, 5, 7, 17, -33, -14, 14, 23, -1, -18, -18, -4,
+ -35, -17, 47, 71, -16, -20, -11, -16, -25, 6, 37, 14, -18, 1, -8, -14,
+ 10, 14, 2, -20, 0, 20, -10, -25, 14, 32, 7, -39, -38, -3, 34, 25,
+ 13, 3, -24, -34, 5, 38, 18, 7, 29, -30, -74, -41, 36, 40, -12, 26,
+ 55, -17, -59, -26, 28, -2, -31, 24, 25, -44, -39, 21, 44, -1, 10, 33,
+ -34, -50, -12, 18, 13, 20, 17, -6, -31, -10, -6, -1, 7, 12, 14, 6,
+ -16, -24, 6, 9, -16, -16, 6, 2, -10, 13, 12, -10, 0, 11, 11, 10,
+ -3, -22, -22, -12, -7, 19, 17, -2, -12, 6, 16, 7, -11, -1, -20, -22,
+ -8, 26, 16, -3, 12, 1, -33, 2, 30, -23, -5, 28, -17, -19, 21, 9,
+ -28, -14, 25, -1, 4, 24, 0, -26, -9, 7, 2, -2, 20, -10, -11, 5,
+ -3, -4, 8, -9, 14, 18, 25, -22, -15, -22, -3, -12, 27, 30, 15, -11,
+ -26, -4, 15, -7, -14, 23, -23, -4, 34, -2, -38, 14, -11, -24, 16, 34,
+ 11, -13, 3, -3, -19, -34, 0, -3, 24, 43, 1, -12, -38, -25, -11, 23,
+ 35, 12, -28, -25, -16, 7, 22, 1, -10, 8, 8, -3, 6, -24, -20, -13,
+ 9, 31, 12, -16, 7, -29, 5, 8, -28, 3, 4, 12, 26, -9, -15, -5,
+ -20, 9, 21, 0, 1, -9, 0, 8, -3, -7, -9, -3, 22, 8, 3, -11,
+ -9, -11, 3, 15, 9, -10, 1, -3, -3, -2, -5, 9, 0, 12, 7, -15,
+ -7, 0, -8, 5, 9, -5, 7, -7, 10, 4, -11, -2, -8, -4, 9, 9,
+ 0, -2, -11, -3, -4, 3, 4, 3, -2, 3, 3, -8, -9, -2, 0, 3,
+ 5, -1, -10, -7, 2, 8, 3, 0, -5, -5, 2, 4, -2, -5, -3, 2,
+ 3, 0, 2, -5, -3, 3, 2, -2, -4, -2, 1, 2, 1, 0, 0, 0,
+ 0, -1, -7, -9, -5, 0, 2, 2, 5, 6, 0, -11, -13, -5, 3, 1,
+ 0, 0, 1, -3, -9, -6, -1, 5, 3, -3, -5, -3, -1, -4, -3, -1,
+ 2, -2, -9, -7, -2, -5, -18, -31, -36, -36, -41, -38, -29, -21, -27, -31,
+ -26, -4, 37, 65, 67, 44, 22, 10, 2, -4, 8, 32, 44, 38, 24, 17,
+ 9, 4, 3, 12, 26, 32, 32, 23, 16, 7, 1, -7, -13, -8, 1, -5,
+ -39, -72, -79, -64, -49, -40, -24, -1, 12, 0, -25, -44, -43, -30, -14, 1,
+ 13, 13, 4, 4, 16, 34, 46, 55, 65, 73, 67, 53, 54, 58, 62, 60,
+ 51, 38, 33, 20, -7, -27, -40, -46, -55, -58, -41, -9, 7, 8, 2, -26,
+ -49, -71, -92, -101, -93, -80, -70, -71, -73, -65, -67, -69, -61, -42, -15, 15,
+ 18, -5, -33, -54, -54, -40, -18, 2, 21, 21, 3, -28, -52, -33, 9, 35,
+ 33, 30, 34, 45, 46, 43, 54, 63, 65, 61, 56, 43, 45, 59, 77, 96,
+ 104, 112, 115, 100, 78, 53, 22, -3, -6, 5, 24, 37, 38, 35, 25, 3,
+ -19, -38, -51, -46, -33, -34, -42, -47, -48, -38, -27, -30, -40, -48, -45, -30,
+ -24, -38, -44, -43, -47, -34, -13, 7, 27, 30, 9, -18, -38, -22, 19, 47,
+ 70, 83, 68, 28, -13, -41, -41, -19, -1, 10, 8, 4, 4, -7, -12, 6,
+ 32, 42, 31, 0, -39, -71, -99, -115, -111, -85, -56, -46, -61, -74, -66, -45,
+ -22, 4, 21, 27, 25, 1, -30, -51, -37, 4, 37, 40, 26, 17, 12, 12,
+ 5, 1, 2, 12, 29, 43, 44, 45, 54, 45, 28, 10, 13, 26, 32, 43,
+ 59, 67, 62, 60, 66, 72, 61, 34, 11, 0, 1, -6, -18, -12, 19, 47,
+ 51, 32, 9, -8, -22, -26, -27, -30, -29, -12, 7, 18, 13, -1, -11, -11,
+ 5, 16, 14, 11, 5, -19, -47, -54, -29, 13, 37, 42, 33, 9, -17, -31,
+ -21, 14, 61, 81, 68, 39, 4, -26, -46, -38, -17, -1, 1, -4, -14, -25,
+ -23, -4, 24, 43, 49, 37, 4, -48, -97, -123, -116, -89, -66, -65, -73, -67,
+ -64, -66, -69, -46, 3, 36, 27, -3, -25, -39, -38, -39, -36, -24, -9, 5,
+ 13, 13, 4, -1, -13, -15, 0, 22, 47, 65, 76, 67, 35, 3, -4, 6,
+ 27, 47, 58, 68, 72, 73, 72, 66, 59, 62, 61, 49, 28, -5, -30, -27,
+ 9, 40, 51, 46, 40, 28, 1, -30, -56, -57, -41, -13, 5, 12, 7, -11,
+ -38, -54, -40, -16, 12, 23, 13, -16, -49, -62, -55, -29, 4, 38, 45, 28,
+ -5, -36, -36, -5, 39, 68, 77, 73, 55, 8, -35, -46, -29, -15, -15, -16,
+ -12, -9, -23, -30, -18, 16, 48, 51, 24, -18, -45, -72, -96, -111, -101, -80,
+ -67, -71, -79, -77, -70, -46, -22, -7, -4, -5, -4, -2, -15, -37, -43, -42,
+ -27, -5, 9, 27, 38, 27, 4, -14, -15, 6, 30, 61, 93, 90, 52, 16,
+ 2, 1, 5, 11, 34, 64, 79, 71, 48, 35, 43, 61, 59, 46, 27, 1,
+ -22, -33, -25, -9, 15, 37, 56, 54, 28, -10, -44, -58, -49, -27, -8, 20,
+ 29, 0, -42, -66, -60, -34, -7, 16, 30, 15, -20, -50, -64, -49, -11, 21,
+ 34, 34, 17, -7, -31, -29, 3, 43, 69, 78, 73, 45, 10, -20, -32, -33,
+ -26, -12, -6, -18, -41, -44, -27, -6, 10, 17, 19, 18, -4, -49, -87, -108,
+ -100, -84, -87, -93, -83, -67, -54, -45, -45, -35, -23, -13, 6, 17, 14, 1,
+ -22, -40, -35, -18, 2, 28, 57, 63, 33, -7, -21, -4, 23, 57, 89, 102,
+ 94, 68, 37, 8, -4, 4, 37, 71, 88, 79, 54, 46, 55, 62, 55, 53,
+ 54, 46, 20, -14, -40, -41, -16, 15, 44, 60, 59, 30, -21, -61, -70, -54,
+ -26, 10, 29, 19, -16, -49, -63, -58, -33, 4, 29, 26, -1, -33, -49, -50,
+ -34, -9, 16, 34, 34, 9, -20, -25, -9, 13, 29, 54, 87, 91, 56, 11,
+ -12, -11, -12, -20, -22, -17, -11, -12, -22, -25, -15, 3, 19, 19, 9, -11,
+ -38, -62, -76, -92, -107, -109, -95, -68, -53, -49, -49, -58, -63, -48, -25, -5,
+ 12, 12, -7, -36, -56, -56, -32, 8, 50, 64, 36, 6, -10, -15, -11, 9,
+ 47, 94, 118, 100, 58, 14, -3, 3, 19, 44, 72, 83, 78, 75, 66, 53,
+ 45, 52, 66, 70, 52, 22, -8, -36, -36, -14, 21, 63, 84, 63, 14, -29,
+ -55, -54, -42, -12, 28, 40, 14, -24, -52, -58, -42, -22, 6, 19, 16, -5,
+ -34, -49, -43, -24, -12, 2, 14, 22, 10, -10, -20, -16, 3, 28, 60, 72,
+ 61, 42, 25, 1, -26, -44, -46, -31, -25, -26, -32, -30, -24, -12, -12, -15,
+ 0, 6, -3, -23, -47, -79, -112, -128, -115, -84, -61, -45, -42, -51, -64, -68,
+ -61, -33, 9, 29, 12, -28, -54, -64, -56, -30, 9, 36, 41, 34, 10, -18,
+ -38, -29, 13, 70, 105, 106, 79, 48, 31, 12, -1, 12, 51, 78, 89, 87,
+ 75, 66, 49, 44, 56, 73, 79, 66, 23, -23, -42, -39, -9, 31, 65, 75,
+ 52, 7, -32, -54, -57, -30, 3, 24, 19, 2, -18, -39, -50, -39, -10, 8,
+ 10, -2, -12, -18, -21, -29, -33, -16, 11, 28, 17, 1, -4, 3, -3, -6,
+ 13, 42, 64, 67, 56, 29, 2, -21, -36, -42, -40, -25, -15, -10, -7, -10,
+ -27, -38, -24, 2, 19, 14, -6, -44, -86, -115, -121, -109, -81, -45, -27, -36,
+ -58, -76, -81, -53, -13, 11, 8, -11, -24, -40, -58, -62, -30, 11, 42, 44,
+ 17, -15, -36, -38, -22, 15, 53, 84, 88, 73, 52, 19, -6, -9, 13, 44,
+ 71, 88, 93, 79, 54, 42, 46, 67, 82, 79, 54, 20, -10, -28, -27, 0,
+ 46, 70, 61, 29, 2, -18, -38, -45, -23, 7, 16, 10, -8, -22, -26, -30,
+ -32, -23, -13, -2, 6, -6, -15, -16, -18, -20, -9, 0, 2, 11, 19, 17,
+ -2, -21, -12, 14, 33, 50, 65, 61, 43, 19, -17, -44, -50, -42, -21, 1,
+ 11, 1, -31, -56, -45, -22, -1, 17, 18, -4, -44, -95, -126, -123, -95, -56,
+ -36, -41, -51, -59, -68, -60, -38, -15, 5, 14, 7, -17, -47, -61, -37, 1,
+ 27, 33, 24, 7, -13, -30, -43, -26, 13, 47, 70, 74, 68, 48, 12, -19,
+ -14, 14, 46, 74, 81, 75, 64, 52, 48, 56, 67, 82, 78, 44, 9, -12,
+ -20, -8, 18, 41, 57, 46, 23, 0, -23, -33, -21, -10, -10, -2, 3, 5,
+ -2, -19, -33, -32, -24, -16, -11, -14, -6, 7, -2, -20, -25, -16, -6, 6,
+ 17, 27, 22, 2, -10, -11, 0, 24, 51, 68, 79, 65, 25, -19, -49, -48,
+ -30, -9, 8, 10, -12, -40, -57, -57, -34, -1, 25, 24, -7, -56, -95, -111,
+ -102, -84, -69, -57, -44, -42, -59, -74, -71, -47, -17, 0, 3, -6, -21, -37,
+ -38, -27, -6, 15, 23, 22, 12, -4, -23, -32, -26, 1, 36, 63, 82, 78,
+ 46, 12, -1, 2, 20, 41, 64, 81, 79, 66, 59, 61, 67, 75, 76, 66,
+ 49, 27, 5, -7, 2, 24, 41, 44, 38, 28, 13, -5, -19, -21, -17, -11,
+ -2, 4, 4, -2, -14, -28, -32, -27, -21, -16, -13, -1, 6, -4, -21, -25,
+ -17, -7, 6, 0, 0, -4, -4, -5, -8, -4, 3, 8, 6, 1, 1, 2,
+ 3, 3, -2, -7, -11, -10, -5, -2, 4, 6, 0, -2, -5, -4, -4, -9,
+ -9, -7, -11, -11, -10, -7, 4, 0, -4, -4, -1, 4, 0, -4, -3, -5,
+ -6, -5, -4, 4, -1, 2, 11, 5, -13, -20, -30, -49, -50, -34, -22, -33,
+ -27, -20, -17, 0, 34, 70, 73, 42, 3, -26, -37, -25, -1, 25, 48, 71,
+ 75, 44, 22, 45, 69, 57, 44, 52, 58, 24, -23, -41, -50, -58, -67, -82,
+ -66, -29, -29, -41, -34, -19, -4, -4, -1, 20, 50, 56, 35, 12, 4, -8,
+ -15, 4, 28, 44, 46, 34, 17, 2, 0, 11, 28, 42, 22, -28, -51, -45,
+ -34, -39, -37, -19, -17, -30, -32, -18, -4, 9, 19, 38, 35, 3, -24, -35,
+ -40, -23, -11, -25, -47, -52, -51, -58, -61, -52, -47, -37, -17, -5, -5, -16,
+ -31, -24, -11, -1, -3, -23, -40, -48, -40, -12, 15, 25, 17, -5, -2, 14,
+ 21, 15, -12, -26, -18, -2, 28, 48, 55, 52, 42, 35, 35, 42, 38, 36,
+ 40, 53, 55, 52, 44, 36, 49, 57, 56, 57, 55, 50, 39, 27, 31, 30,
+ 15, 11, 12, 6, 4, 14, 28, 23, 1, -6, -17, -35, -44, -41, -33, -22,
+ -9, -6, -12, -15, -13, -27, -29, -7, 14, -5, -55, -71, -49, -33, -37, -46,
+ -33, -18, -43, -89, -96, -65, -23, 2, 8, 20, 24, -11, -50, -51, -12, 15,
+ 4, 1, 20, 47, 53, 43, 52, 77, 98, 114, 110, 100, 88, 53, 10, -29,
+ -55, -71, -83, -77, -58, -55, -57, -52, -48, -47, -46, -12, 34, 59, 52, 25,
+ -10, -33, -21, 18, 49, 54, 46, 18, 13, 30, 41, 48, 54, 53, 44, 24,
+ 1, -13, -25, -43, -38, -28, -35, -55, -71, -64, -40, -13, 10, 24, 38, 41,
+ 21, -1, -11, 1, 15, 7, -6, -13, -39, -57, -64, -51, -20, -12, -24, -37,
+ -30, -4, 17, 21, 12, -7, -16, -15, -7, 6, 1, -20, -34, -30, -1, 32,
+ 44, 36, 22, 25, 21, 6, 1, -2, -13, -5, 19, 28, 24, 12, 11, 16,
+ 19, 38, 54, 49, 38, 28, 28, 39, 52, 49, 32, 25, 33, 45, 49, 39,
+ 40, 46, 20, -9, -6, 6, 1, -22, -29, 10, 48, 33, -17, -51, -55, -44,
+ -49, -50, -36, -33, -57, -84, -71, -21, 11, 13, 4, -1, -8, -32, -45, -32,
+ -10, 2, -13, -37, -39, -42, -57, -65, -63, -36, -11, 10, 33, 22, -12, -34,
+ -28, -12, 2, 8, 6, -2, -4, 0, 10, 22, 36, 57, 82, 104, 122, 127,
+ 109, 70, 17, -28, -45, -36, -20, -33, -68, -102, -114, -103, -76, -45, -20, -7,
+ -11, -10, -2, 6, 0, -14, -5, 30, 48, 29, 3, -8, 10, 39, 67, 86,
+ 83, 59, 32, 17, 32, 46, 40, 11, -29, -48, -57, -68, -69, -57, -43, -26,
+ -13, -2, 1, 1, 3, 4, 8, 21, 20, 11, 3, -2, -6, -26, -39, -33,
+ -34, -36, -28, -23, -27, -28, -17, -1, 0, -6, -10, -9, -7, -12, -26, -44,
+ -54, -38, -16, 0, 18, 27, 17, -3, -18, -3, 19, 11, -9, -7, 10, 14,
+ 5, 5, 18, 29, 29, 12, 16, 38, 43, 14, 2, 24, 55, 59, 33, 17,
+ 24, 44, 65, 75, 77, 55, 15, -16, -20, 6, 31, 27, 17, 18, 19, 17,
+ 7, 0, -5, -20, -22, -25, -49, -69, -73, -58, -45, -29, -4, 9, -1, -23,
+ -51, -52, -24, -2, 11, 12, -16, -51, -75, -77, -67, -59, -59, -54, -35, -15,
+ -9, -9, -9, -7, -8, -12, -1, 15, 22, 10, -14, -34, -28, -14, 11, 64,
+ 113, 127, 117, 97, 87, 84, 68, 50, 37, 36, 24, -15, -58, -78, -84, -71,
+ -40, -14, -12, -34, -48, -41, -14, 20, 37, 35, 16, -6, 1, 14, 15, 20,
+ 23, 24, 38, 58, 69, 57, 40, 54, 73, 75, 65, 40, -3, -49, -68, -56,
+ -42, -42, -53, -59, -44, -23, -9, -3, -11, -18, -13, -11, -5, 3, 13, 4,
+ -25, -39, -22, -14, -16, -27, -38, -37, -42, -55, -51, -21, 8, 10, -8, -12,
+ -4, -10, -39, -55, -38, -13, -4, -11, -15, -3, 15, 12, 2, 11, 28, 34,
+ 15, -5, 3, 11, 6, 12, 25, 25, 13, 10, 15, 27, 48, 55, 38, 23,
+ 17, 23, 32, 23, 32, 57, 75, 75, 52, 22, 10, 5, 12, 28, 33, 23,
+ 2, -14, -4, 19, 30, 25, 15, 1, -27, -64, -78, -67, -49, -45, -48, -42,
+ -31, -25, -40, -50, -39, -18, -4, 13, 19, 12, -10, -43, -59, -53, -47, -54,
+ -61, -51, -20, -2, -12, -23, -25, -18, 5, 33, 51, 45, 16, -16, -46, -53,
+ -38, -6, 33, 57, 74, 81, 75, 77, 89, 105, 114, 110, 83, 39, -6, -25,
+ -28, -39, -48, -52, -55, -59, -67, -67, -57, -42, -23, -3, 10, 3, -19, -33,
+ -30, -8, 20, 23, 2, -18, -17, 12, 40, 58, 65, 65, 66, 71, 64, 54,
+ 38, 1, -41, -62, -47, -26, -31, -49, -55, -42, -21, -17, -19, -10, -2, -3,
+ -10, -13, 2, 13, -10, -38, -27, 3, 8, -18, -46, -61, -65, -53, -36, -18,
+ -5, -6, -14, -22, -18, -12, -19, -29, -28, -21, -10, -15, -24, -18, -4, 16,
+ 23, 17, 14, 10, 9, 13, 15, 28, 35, 19, 4, 2, -2, 9, 34, 62,
+ 66, 43, 13, -2, 15, 42, 50, 48, 51, 56, 56, 45, 44, 45, 48, 40,
+ 33, 31, 27, 10, -10, -4, 16, 41, 52, 48, 31, -1, -36, -56, -50, -27,
+ -14, -25, -43, -60, -67, -47, -31, -38, -47, -40, -17, 13, 32, 28, -10, -50,
+ -68, -62, -40, -21, -20, -33, -58, -72, -63, -45, -28, -11, 18, 48, 42, 15,
+ -14, -43, -54, -40, -15, 4, 2, -5, 0, 20, 55, 91, 113, 120, 109, 89,
+ 77, 63, 43, 26, 20, 12, -13, -47, -69, -68, -53, -49, -49, -36, -28, -27,
+ -27, -28, -12, 5, 1, -9, -2, 14, 10, -25, -39, -6, 21, 35, 41, 53,
+ 73, 82, 74, 64, 54, 39, 9, -23, -37, -30, -22, -30, -52, -62, -54, -32,
+ -9, 2, 5, -3, -17, -25, -17, -1, 13, 8, -7, -12, -7, -7, -21, -40,
+ -51, -51, -38, -21, -16, -22, -29, -33, -23, -10, -2, -9, -24, -33, -33, -29,
+ -21, -8, 3, 2, -10, -18, -11, 8, 26, 32, 27, 21, 14, 7, 1, 3,
+ 12, 22, 35, 45, 43, 29, 13, 10, 20, 37, 54, 59, 45, 28, 28, 37,
+ 48, 55, 60, 60, 43, 17, 0, -3, 9, 24, 31, 31, 28, 28, 26, 14,
+ -5, -22, -31, -30, -21, -7, -8, -34, -63, -82, -80, -63, -45, -28, -14, -5,
+ 3, 2, -11, -27, -39, -33, -11, 2, -8, -39, -73, -95, -91, -54, -8, 19,
+ 16, 4, 5, 14, 14, 2, -8, -14, -19, -33, -45, -38, -19, 2, 21, 54,
+ 93, 106, 90, 74, 80, 97, 98, 76, 52, 34, 10, -18, -37, -36, -27, -35,
+ -52, -62, -56, -44, -39, -37, -29, -17, -8, -2, 3, 4, -4, -16, -27, -32,
+ -19, 1, 19, 41, 60, 70, 71, 67, 64, 61, 53, 38, 14, -8, -21, -29,
+ -34, -38, -39, -29, -15, 0, 5, -5, -19, -25, -16, 5, 19, 17, 6, -3,
+ -7, 0, -1, 1, -2, -5, 0, 0, 2, 0, -3, -2, 0, 1, 0, -2,
+ -2, -2, 0, 3, 3, -2, -5, -1, -1, -1, -4, 3, 9, 1, -1, -2,
+ -11, -7, 1, 9, 11, 8, -4, -11, -12, -9, -4, 18, 15, 14, 1, -22,
+ -29, -14, 3, 30, 29, 14, -2, -35, -43, -11, 13, 36, 42, 15, -16, -49,
+ -44, -10, 28, 47, 38, 11, -25, -66, -39, 4, 36, 58, 33, -3, -44, -65,
+ -29, 19, 52, 54, 23, -13, -59, -65, -15, 32, 69, 49, 8, -30, -74, -51,
+ 3, 43, 71, 40, -5, -48, -77, -31, 16, 57, 67, 24, -15, -67, -72, -12,
+ 36, 66, 59, 5, -31, -80, -51, 3, 49, 75, 37, -2, -59, -81, -28, 20,
+ 67, 66, 22, -23, -76, -65, -10, 41, 78, 48, 4, -36, -85, -47, 6, 59,
+ 80, 31, -8, -69, -82, -22, 29, 73, 63, 17, -31, -81, -63, -1, 47, 79,
+ 47, 3, -56, -90, -40, 19, 75, 73, 28, -25, -86, -74, -10, 48, 85, 56,
+ 6, -51, -93, -48, 11, 67, 86, 33, -11, -78, -87, -29, 36, 89, 66, 13,
+ -38, -91, -60, 2, 50, 83, 48, 0, -56, -90, -41, 16, 71, 78, 30, -17,
+ -80, -75, -20, 31, 82, 62, 15, -32, -85, -66, -7, 48, 84, 50, 4, -53,
+ -87, -44, 8, 62, 78, 35, -8, -65, -83, -30, 23, 70, 71, 24, -20, -76,
+ -75, -12, 32, 73, 62, 15, -30, -85, -62, -2, 41, 76, 51, 9, -39, -86,
+ -52, 1, 45, 79, 46, 8, -49, -89, -46, 3, 54, 80, 43, 7, -55, -83,
+ -50, 0, 53, 76, 54, 11, -52, -83, -55, 0, 40, 67, 58, 22, -32, -79,
+ -67, -11, 28, 63, 52, 37, -9, -70, -63, -28, 10, 42, 49, 53, 8, -46,
+ -64, -41, 1, 22, 38, 51, 39, -16, -63, -46, -23, 5, 33, 38, 48, 14,
+ -42, -57, -29, -5, 22, 37, 40, 28, -23, -53, -39, -10, 14, 30, 40, 31,
+ -1, -48, -40, -18, 11, 19, 31, 26, 14, -20, -50, -25, -5, 11, 31, 30,
+ 14, 0, -35, -39, -4, -1, 19, 27, 17, 9, -10, -39, -21, -8, 9, 24,
+ 26, 13, -5, -19, -30, -12, -1, 17, 25, 16, 3, -19, -26, -13, -6, 17,
+ 22, 20, 5, -16, -32, -19, -1, 23, 27, 23, 4, -30, -33, -23, -1, 35,
+ 35, 24, -2, -41, -45, -21, 9, 45, 41, 22, -12, -50, -46, -18, 28, 55,
+ 45, 10, -27, -78, -42, 0, 53, 66, 32, -1, -61, -74, -28, 27, 64, 64,
+ 24, -28, -80, -66, -15, 53, 84, 48, 5, -59, -94, -41, 17, 75, 80, 26,
+ -21, -91, -79, -12, 48, 87, 55, 10, -58, -96, -46, 9, 80, 81, 30, -23,
+ -84, -80, -15, 49, 90, 49, 9, -57, -95, -45, 17, 76, 79, 26, -20, -91,
+ -75, -18, 52, 90, 52, 6, -59, -92, -41, 15, 68, 80, 31, -21, -87, -76,
+ -13, 45, 87, 49, 11, -60, -94, -35, 14, 80, 68, 22, -23, -89, -66, -7,
+ 47, 93, 44, -8, -61, -95, -31, 24, 86, 75, 10, -35, -96, -66, -1, 61,
+ 100, 44, -12, -77, -105, -33, 32, 97, 92, 16, -44, -111, -90, -5, 65, 121,
+ 65, -3, -80, -123, -59, 17, 98, 111, 46, -25, -112, -109, -33, 42, 112, 90,
+ 30, -55, -115, -84, -17, 66, 105, 71, 13, -73, -113, -61, 0, 77, 96, 56,
+ 4, -80, -108, -50, 8, 78, 93, 47, 3, -88, -98, -40, 7, 65, 76, 53,
+ 18, -71, -90, -44, 0, 39, 57, 43, 34, -19, -69, -54, -19, 18, 32, 31,
+ 34, 7, -40, -36, -21, -1, 12, 12, 25, 27, -9, -32, -14, -14, 2, 0,
+ 1, 20, 19, -2, -13, -11, -18, -12, -2, 18, 24, 12, -2, -14, -19, -19,
+ -12, 18, 24, 22, -2, -15, -32, -20, 3, 22, 26, 17, -13, -31, -27, -13,
+ 17, 33, 32, 5, -29, -47, -29, 2, 33, 42, 32, -6, -53, -52, -24, 22,
+ 51, 41, 27, -32, -74, -45, 0, 45, 59, 33, -1, -62, -66, -31, 26, 73,
+ 49, 17, -42, -80, -42, -8, 63, 72, 28, -10, -75, -72, -23, 32, 88, 47,
+ 13, -56, -93, -38, 10, 76, 69, 26, -20, -96, -66, -10, 48, 90, 47, 0,
+ -69, -103, -29, 25, 87, 73, 18, -35, -104, -68, -2, 61, 93, 47, -5, -83,
+ -98, -31, 30, 92, 68, 17, -39, -97, -63, -5, 64, 88, 35, -9, -74, -86,
+ -22, 31, 85, 54, 13, -44, -93, -46, 9, 65, 75, 23, -17, -75, -78, -15,
+ 39, 84, 54, 3, -52, -96, -46, 12, 71, 90, 29, -18, -89, -87, -26, 36,
+ 86, 72, 26, -37, -106, -77, -12, 45, 99, 68, 22, -46, -108, -73, -10, 43,
+ 87, 69, 19, -27, -92, -79, -12, 27, 63, 57, 26, 4, -53, -75, -35, 12,
+ 33, 37, 31, 26, -9, -53, -39, -16, 6, 20, 23, 22, 13, -8, -22, -23,
+ -18, -3, 9, 25, 19, 4, -8, -20, -17, -10, 6, 16, 17, 13, -8, -34,
+ -21, -6, 17, 33, 23, 6, -32, -51, -23, 11, 36, 46, 31, -11, -46, -65,
+ -31, 15, 59, 55, 28, -20, -73, -64, -26, 42, 78, 51, 14, -53, -85, -48,
+ -4, 70, 80, 38, -16, -80, -76, -32, 39, 90, 58, 19, -59, -99, -50, 14,
+ 71, 75, 36, -21, -94, -70, -23, 51, 88, 53, 9, -68, -97, -40, 16, 83,
+ 73, 29, -33, -100, -61, -13, 58, 87, 41, 0, -74, -81, -35, 24, 87, 55,
+ 20, -41, -88, -58, 0, 69, 73, 34, -5, -86, -75, -20, 38, 79, 49, 13,
+ -48, -90, -39, 2, 71, 68, 31, -16, -84, -67, -15, 38, 79, 42, 12, -50,
+ -85, -37, 2, 62, 71, 34, -5, -83, -75, -24, 27, 82, 51, 27, -30, -88,
+ -54, -15, 44, 73, 50, 16, -49, -81, -47, -6, 38, 58, 50, 27, -31, -69,
+ -52, -13, 15, 36, 45, 33, -5, -41, -44, -23, 2, 14, 27, 33, 10, -25,
+ -20, -18, -6, 1, -1, 17, 22, 3, -13, -10, -17, -13, -6, 13, 24, 15,
+ 1, -11, -19, -19, -16, 12, 24, 24, 3, -12, -29, -26, -1, 18, 27, 19,
+ -4, -31, -28, -19, 11, 30, 35, 12, -21, -46, -35, -6, 28, 42, 36, 5,
+ -46, -57, -31, 10, 50, 43, 33, -16, -71, -55, -9, 35, 62, 38, 10, -51,
+ -71, -40, 11, 69, 58, 24, -26, -81, -50, -18, 48, 79, 37, 1, -62, -81,
+ -32, 16, 84, 59, 20, -37, -96, -50, -2, 63, 78, 33, -4, -85, -80, -20,
+ 33, 88, 59, 10, -50, -107, -47, 14, 75, 85, 27, -19, -95, -83, -15, 47,
+ 94, 60, 8, -66, -105, -46, 15, 83, 81, 26, -23, -91, -76, -18, 48, 92,
+ 47, 1, -59, -94, -36, 18, 78, 66, 19, -27, -91, -60, -3, 53, 80, 35,
+ -8, -62, -86, -28, 27, 79, 66, 13, -38, -94, -62, 1, 56, 95, 42, -6,
+ -75, -96, -39, 22, 80, 80, 36, -20, -97, -92, -24, 30, 93, 79, 32, -27,
+ -102, -87, -22, 31, 81, 79, 29, -14, -81, -91, -25, 19, 56, 63, 31, 11,
+ -39, -77, -47, 3, 31, 37, 33, 27, 3, -48, -46, -20, 0, 18, 22, 23,
+ 16, -3, -20, -19, -15, -4, 2, 8, 5, 0, 0, 0, 0, 2, 2, 5,
+ 9, 12, 14, 12, 7, 6, 4, 0, -1, -1, 1, -2, -2, -11, -17, -32,
+ -41, -49, -55, -58, -61, -61, -65, -61, -57, -47, -37, -27, -22, -15, -5, 6,
+ 12, 16, 21, 27, 28, 32, 33, 35, 41, 44, 45, 47, 50, 54, 57, 56,
+ 53, 53, 54, 50, 50, 52, 54, 56, 52, 53, 54, 50, 49, 46, 43, 38,
+ 33, 27, 19, 8, 2, -11, -20, -27, -29, -30, -32, -35, -42, -52, -57, -57,
+ -59, -48, -40, -27, -13, 4, 13, 20, 18, 14, 11, 7, 3, -1, -3, -10,
+ -11, -20, -28, -46, -60, -72, -82, -92, -97, -97, -97, -94, -90, -81, -71, -61,
+ -55, -55, -53, -47, -38, -29, -23, -11, -6, -3, 1, 2, 5, 6, 3, 3,
+ 5, 15, 24, 28, 30, 30, 35, 37, 36, 39, 39, 44, 47, 48, 56, 62,
+ 73, 84, 91, 96, 95, 91, 85, 76, 72, 63, 55, 47, 44, 43, 41, 38,
+ 31, 19, 7, 0, -9, -7, -4, 8, 22, 40, 54, 67, 71, 70, 64, 56,
+ 45, 32, 24, 15, 12, 3, -3, -21, -42, -66, -84, -102, -117, -124, -128, -127,
+ -124, -118, -107, -96, -86, -86, -88, -86, -80, -70, -63, -50, -40, -33, -25, -23,
+ -20, -18, -18, -21, -25, -22, -14, -8, -3, -3, -1, 1, 0, 1, -3, -1,
+ 2, 4, 13, 24, 35, 49, 59, 67, 70, 69, 68, 59, 54, 46, 40, 31,
+ 29, 27, 25, 23, 20, 12, -1, -9, -19, -22, -21, -11, 3, 23, 41, 60,
+ 71, 76, 73, 71, 65, 56, 50, 44, 42, 35, 33, 24, 9, -13, -31, -48,
+ -65, -76, -83, -83, -82, -77, -69, -59, -46, -40, -40, -41, -38, -30, -24, -13,
+ -2, 8, 17, 22, 24, 25, 23, 20, 13, 9, 11, 15, 19, 16, 12, 9,
+ 4, 1, -6, -10, -11, -14, -12, -5, 3, 15, 26, 35, 40, 41, 41, 35,
+ 28, 19, 12, 3, -2, -6, -7, -10, -13, -19, -31, -39, -50, -56, -58, -52,
+ -41, -22, -3, 18, 34, 46, 48, 47, 45, 38, 32, 26, 24, 20, 19, 15,
+ 5, -14, -32, -49, -65, -79, -88, -91, -91, -88, -82, -75, -63, -52, -47, -46,
+ -46, -38, -31, -21, -8, 4, 17, 26, 31, 36, 39, 42, 40, 35, 36, 39,
+ 47, 48, 45, 43, 38, 36, 30, 24, 22, 19, 18, 23, 29, 40, 50, 61,
+ 68, 72, 74, 71, 66, 57, 50, 40, 32, 24, 21, 16, 12, 7, -3, -14,
+ -26, -38, -45, -46, -43, -31, -16, 3, 18, 33, 39, 39, 36, 31, 22, 13,
+ 8, 3, -1, -4, -9, -24, -42, -60, -77, -94, -107, -115, -119, -120, -116, -112,
+ -103, -91, -81, -78, -80, -75, -69, -61, -51, -39, -25, -13, -5, 2, 8, 14,
+ 17, 16, 15, 16, 24, 31, 32, 32, 29, 29, 27, 22, 21, 20, 19, 22,
+ 26, 35, 46, 59, 70, 77, 83, 85, 84, 79, 74, 66, 59, 50, 46, 41,
+ 38, 35, 29, 21, 11, 0, -9, -14, -16, -11, 0, 16, 30, 48, 58, 62,
+ 61, 58, 51, 40, 31, 25, 19, 15, 13, 4, -11, -28, -44, -61, -76, -87,
+ -95, -100, -100, -99, -95, -86, -75, -68, -69, -68, -67, -62, -56, -49, -38, -27,
+ -19, -13, -9, -3, 2, 1, -1, -3, 0, 7, 10, 10, 6, 5, 4, 0,
+ -4, -5, -7, -7, -7, -2, 5, 16, 27, 36, 44, 49, 52, 50, 46, 40,
+ 35, 26, 22, 18, 15, 15, 13, 9, 4, -5, -14, -19, -23, -21, -14, 0,
+ 15, 33, 49, 60, 63, 63, 61, 53, 44, 38, 32, 27, 27, 23, 14, 0,
+ -14, -29, -44, -58, -67, -74, -76, -76, -73, -67, -55, -45, -41, -41, -41, -39,
+ -35, -30, -23, -12, -3, 4, 9, 14, 20, 21, 20, 17, 15, 19, 24, 26,
+ 24, 21, 20, 18, 12, 9, 6, 3, 0, 1, 4, 11, 21, 30, 38, 43,
+ 47, 48, 45, 38, 32, 23, 15, 9, 5, 3, 1, -2, -5, -13, -22, -30,
+ -37, -41, -40, -30, -18, -3, 15, 30, 38, 41, 41, 37, 27, 19, 12, 6,
+ 3, 2, -2, -13, -25, -39, -53, -67, -78, -88, -92, -92, -91, -86, -77, -63,
+ -54, -50, -48, -47, -43, -38, -32, -23, -11, -1, 6, 11, 19, 25, 27, 26,
+ 24, 26, 31, 36, 38, 36, 37, 37, 34, 32, 29, 27, 24, 22, 23, 27,
+ 35, 45, 53, 61, 67, 70, 71, 66, 60, 51, 42, 34, 28, 24, 21, 18,
+ 16, 11, 2, -8, -16, -24, -28, -25, -17, -5, 10, 26, 39, 45, 47, 45,
+ 37, 27, 18, 9, 3, 0, -2, -10, -22, -36, -51, -67, -81, -93, -102, -107,
+ -108, -107, -102, -90, -78, -71, -67, -66, -63, -59, -56, -49, -39, -28, -19, -13,
+ -6, 1, 7, 8, 6, 5, 8, 14, 19, 19, 19, 20, 20, 19, 16, 15,
+ 13, 12, 11, 13, 20, 30, 39, 49, 57, 63, 68, 68, 65, 58, 51, 43,
+ 37, 32, 29, 27, 26, 24, 19, 11, 2, -5, -12, -14, -9, 0, 13, 30,
+ 46, 56, 62, 65, 61, 53, 44, 35, 26, 22, 20, 15, 6, -6, -20, -36,
+ -51, -66, -78, -87, -91, -92, -92, -85, -74, -65, -58, -56, -55, -52, -50, -46,
+ -40, -30, -20, -14, -8, -2, 5, 7, 6, 3, 2, 5, 10, 11, 10, 9,
+ 9, 8, 5, 2, 0, -2, -5, -5, -3, 5, 14, 23, 32, 39, 46, 50,
+ 49, 45, 38, 31, 24, 17, 14, 11, 10, 9, 7, 2, -5, -12, -20, -25,
+ -25, -19, -8, 7, 24, 40, 50, 58, 60, 56, 49, 41, 31, 24, 22, 20,
+ 15, 6, -5, -19, -34, -48, -61, -72, -79, -83, -85, -81, -72, -62, -52, -47,
+ -44, -41, -39, -35, -31, -24, -13, -5, 1, 7, 14, 20, 22, 21, 19, 18,
+ 22, 25, 25, 24, 23, 23, 20, 17, 15, 12, 10, 7, 5, 9, 16, 24,
+ 33, 40, 47, 53, 56, 54, 48, 41, 33, 25, 20, 15, 11, 9, 8, 5,
+ -2, -10, -19, -27, -32, -31, -25, -15, 0, 17, 30, 40, 46, 46, 42, 35,
+ 25, 15, 10, 9, 5, -2, -11, -23, -37, -52, -65, -79, -89, -95, -99, -100,
+ -95, -85, -74, -65, -60, -55, -52, -48, -44, -40, -29, -18, -10, -4, 4, 12,
+ 18, 20, 19, 17, 20, 24, 27, 27, 26, 26, 25, 23, 21, 19, 17, 15,
+ 12, 13, 17, 25, 34, 41, 49, 57, 62, 65, 63, 57, 51, 42, 35, 30,
+ 25, 22, 21, 19, 15, 8, 0, -9, -17, -21, -20, -14, -3, 13, 26, 38,
+ 48, 53, 52, 47, 39, 28, 19, 15, 13, 8, 0, -10, -22, -37, -51, -65,
+ -79, -88, -95, -100, -99, -94, -84, -74, -67, -61, -58, -55, -51, -49, -43, -33,
+ -23, -17, -10, -2, 6, 10, 11, 9, 9, 12, 15, 17, 16, 16, 16, 14,
+ 12, 11, 9, 8, 5, 3, 4, 10, 18, 26, 34, 42, 50, 57, 59, 57,
+ 52, 45, 38, 32, 27, 23, 21, 20, 19, 14, 8, 1, -9, 2, 5, 7,
+ 8, -1, 6, 15, 1, 20, 28, 1, 37, 41, 31, 29, 27, 61, 40, -12,
+ 38, 52, -16, -20, -1, -23, -48, -56, -63, -61, -77, -100, -88, -76, -103, -113,
+ -98, -103, -118, -120, -108, -107, -104, -110, -118, -104, -109, -128, -107, -83, -106, -86,
+ -94, -100, -77, -113, -88, -43, -77, -46, -44, -69, -34, -54, -39, 4, -30, 11,
+ 18, -25, 20, 16, 10, 52, 35, 52, 74, 33, 55, 74, 59, 70, 81, 85,
+ 91, 81, 72, 89, 94, 82, 80, 99, 100, 85, 86, 91, 100, 91, 81, 91,
+ 102, 83, 74, 92, 95, 63, 62, 75, 71, 63, 39, 54, 74, 15, 1, 31,
+ 6, -5, -13, -20, -8, -44, -59, -38, -69, -73, -67, -86, -90, -68, -73, -77,
+ -49, -82, -70, -43, -76, -27, 0, -29, 22, 25, -5, 44, 45, 29, 66, 71,
+ 49, 84, 92, 73, 92, 74, 72, 91, 37, 48, 99, 47, 31, 44, 36, 33,
+ -5, -11, 26, 6, -33, -22, -6, -32, -55, -44, -45, -52, -63, -73, -55, -51,
+ -77, -79, -61, -73, -91, -83, -70, -77, -74, -82, -85, -68, -88, -98, -57, -67,
+ -77, -58, -75, -66, -64, -78, -33, -37, -50, -19, -47, -38, -23, -41, 3, 6,
+ -7, 30, 0, -4, 24, 15, 31, 45, 44, 66, 44, 34, 58, 54, 59, 67,
+ 71, 87, 78, 60, 73, 84, 78, 76, 86, 95, 89, 76, 85, 94, 89, 73,
+ 82, 99, 85, 66, 75, 93, 75, 50, 56, 69, 59, 31, 31, 61, 29, -15,
+ 15, 5, -15, -14, -36, -25, -29, -69, -55, -53, -82, -78, -76, -95, -88, -69,
+ -80, -65, -63, -86, -58, -67, -59, -12, -28, -9, 29, -8, 13, 44, 22, 44,
+ 68, 53, 62, 91, 74, 81, 89, 64, 84, 78, 35, 78, 86, 44, 43, 47,
+ 45, 22, -5, 17, 21, -16, -24, -14, -14, -34, -50, -40, -36, -63, -71, -58,
+ -60, -69, -78, -78, -67, -81, -98, -78, -71, -89, -85, -84, -86, -82, -99, -82,
+ -60, -76, -75, -74, -76, -71, -86, -68, -37, -51, -34, -41, -57, -37, -51, -31,
+ -7, -17, -3, 1, 7, 22, 31, 46, 57, 41, 43, 56, 63, 62, 68, 85,
+ 86, 80, 84, 92, 96, 93, 93, 104, 105, 96, 99, 108, 106, 102, 98, 102,
+ 111, 99, 87, 106, 110, 85, 80, 88, 89, 79, 68, 70, 81, 48, 25, 39,
+ 32, 18, 9, 12, 0, -29, -31, -38, -60, -52, -63, -79, -71, -66, -62, -59,
+ -62, -74, -72, -73, -81, -43, -21, -28, 8, 10, -10, 16, 28, 27, 42, 50,
+ 47, 66, 76, 68, 81, 73, 67, 72, 39, 40, 67, 41, 23, 25, 22, 12,
+ -16, -22, -5, -27, -51, -44, -45, -57, -68, -73, -71, -74, -91, -89, -84, -90,
+ -97, -98, -98, -102, -105, -108, -103, -97, -105, -109, -101, -107, -113, -106, -92, -87,
+ -90, -92, -92, -92, -100, -92, -57, -56, -54, -40, -59, -58, -54, -61, -23, -9,
+ -12, 16, 0, -14, 4, 5, 17, 32, 41, 57, 55, 43, 54, 66, 67, 68,
+ 84, 89, 87, 87, 91, 98, 100, 96, 104, 109, 105, 103, 108, 111, 109, 105,
+ 105, 113, 111, 99, 102, 115, 104, 88, 90, 97, 93, 80, 75, 86, 75, 37,
+ 40, 43, 33, 20, 20, -14, -26, -36, -53, -52, -65, -75, -75, -69, -69, -69,
+ -74, -77, -76, -74, -59, -34, -26, -9, 9, 5, 13, 32, 39, 42, 53, 58,
+ 61, 73, 77, 77, 73, 61, 57, 46, 29, 37, 37, 17, 6, 2, -10, -27,
+ -38, -41, -46, -58, -68, -69, -75, -85, -89, -92, -97, -101, -103, -106, -107, -108,
+ -112, -111, -112, -115, -115, -115, -113, -111, -116, -115, -112, -116, -117, -110, -101, -98,
+ -101, -101, -98, -101, -101, -86, -69, -65, -59, -57, -62, -58, -54, -39, -19, -12,
+ 1, 7, -1, 5, 16, 24, 36, 46, 58, 64, 61, 64, 74, 79, 81, 90,
+ 96, 97, 100, 100, 104, 108, 107, 111, 114, 113, 115, 115, 115, 118, 117, 116,
+ 118, 119, 116, 115, 116, 117, 111, 104, 105, 107, 99, 93, 95, 91, 71, 57,
+ 53, 47, 38, 29, 23, 14, -11, -28, -38, -49, -58, -67, -73, -80, -84, -84,
+ -83, -82, -80, -78, -74, -67, -56, -42, -29, -16, -4, 7, 18, 29, 40, 49,
+ 57, 64, 70, 74, 78, 79, 77, 72, 67, 60, 53, 48, 42, 33, 23, 14,
+ 4, -6, -16, -24, -32, -40, -48, -55, -61, -68, -74, -78, -83, -87, -91, -94,
+ -96, -99, -101, -103, -104, -106, -107, -107, -107, -107, -107, -108, -107, -107, -107, -105,
+ -101, -98, -96, -94, -93, -91, -87, -82, -74, -67, -62, -57, -54, -49, -43, -35,
+ -25, -16, -7, -1, 4, 10, 17, 25, 33, 41, 49, 55, 59, 63, 69, 74,
+ 78, 83, 88, 91, 93, 96, 98, 100, 102, 104, 106, 107, 107, 108, 108, 109,
+ 109, 108, 108, 108, 107, 105, 104, 102, 99, 94, 91, 87, 83, 78, 73, 66,
+ 56, 46, 37, 28, 19, 9, 0, -11, -23, -35, -45, -55, -64, -71, -78, -83,
+ -85, -84, -83, -81, -79, -75, -70, -61, -49, -36, -23, -10, 2, 12, 24, 35,
+ 45, 53, 61, 67, 72, 76, 79, 78, 75, 70, 65, 58, 52, 46, 39, 29,
+ 20, 11, 1, -9, -18, -26, -34, -42, -50, -56, -63, -69, -74, -79, -83, -88,
+ -91, -94, -96, -98, -101, -102, -104, -105, -106, -106, -106, -106, -106, -106, -106, -106,
+ -105, -102, -98, -96, -94, -92, -90, -88, -84, -77, -70, -64, -59, -55, -51, -45,
+ -38, -29, -20, -11, -4, 2, 7, 13, 21, 29, 37, 44, 51, 56, 60, 65,
+ 70, 75, 80, 84, 88, 91, 93, 96, 98, 100, 102, 104, 105, 106, 107, 107,
+ 108, 108, 107, 107, 107, 106, 104, 103, 101, 99, 95, 91, 87, 83, 78, 73,
+ 67, 59, 49, 39, 30, 21, 12, 3, -8, -19, -31, -41, -51, -60, -68, -75,
+ -81, -84, -85, -84, -82, -80, -77, -73, -65, -55, -42, -29, -16, -4, 7, 18,
+ 29, 40, 49, 57, 64, 70, 74, 78, 79, 77, 73, 68, 62, 56, 50, 44,
+ 36, 26, 17, 7, -3, -12, -20, -28, -36, -44, -51, -58, -64, -70, -75, -79,
+ -84, -88, -91, -93, -96, -98, -100, -102, -103, -105, -105, -105, -105, -105, -105, -105,
+ -105, -104, -102, -99, -96, -94, -92, -90, -88, -85, -79, -72, -66, -61, -56, -52,
+ -47, -41, -33, -24, -15, -8, -1, 4, 10, 17, 24, 32, 40, 47, 53, 57,
+ 62, 67, 72, 77, 81, 85, 89, 91, 94, 96, 98, 100, 102, 104, 105, 105,
+ 106, 106, 107, 106, 106, 106, 105, 104, 102, 101, 99, 95, 91, 87, 83, 79,
+ 74, 68, 61, 52, 42, 33, 24, 15, 5, -5, -15, -27, -38, -48, -57, -66,
+ -72, -79, -83, -85, -85, -83, -81, -79, -75, -69, -60, -48, -35, -23, -10, 2,
+ 13, 24, 35, 45, 54, 61, 67, 72, 77, 78, 79, 76, 72, 66, 60, 54,
+ 49, 41, 32, 23, 12, 3, -4, -17, -15, 1, -1, 0, 0, 1, 3, 5,
+ 9, 13, 18, 24, 32, 38, 32, 18, -9, -48, -73, -41, 2, -3, -24, -34,
+ -44, -72, -111, -124, -62, 40, 40, -51, -35, 45, 46, -22, -79, 35, 78, -47,
+ -98, -88, -69, -57, -44, -31, -17, -9, -3, 6, 41, 85, 43, -91, -128, -65,
+ -25, -21, -19, -12, 2, 16, 29, 39, 49, 48, 10, -69, -47, 50, 8, -52,
+ -44, 5, 21, -40, -42, 33, 79, 66, 38, 24, 25, 26, 18, 21, 70, 117,
+ 98, 28, -1, 20, 22, 0, 1, 9, -10, -49, -33, 39, 68, 39, -5, -17,
+ -58, -76, 78, 104, 17, 6, -23, -43, -13, 58, 85, 43, 21, 35, 46, 31,
+ 22, 35, 14, -48, -74, -38, 6, 10, -8, -17, -24, -37, -60, -69, -41, 15,
+ 27, -21, -26, 18, 28, -1, -41, 5, 51, -9, -51, -48, -38, -31, -24, -16,
+ -8, -2, 1, 6, 23, 52, 41, -39, -83, -50, -19, -13, -12, -8, 1, 10,
+ 20, 27, 34, 35, 15, -40, -46, 27, 16, -35, -38, -6, 19, -18, -35, 17,
+ 61, 55, 33, 21, 22, 25, 21, 18, 52, 98, 92, 31, -5, 9, 17, -1,
+ -2, 7, -7, -47, -43, 24, 62, 39, -3, -20, -48, -88, 46, 113, 25, 4,
+ -20, -45, -25, 42, 82, 47, 19, 28, 42, 32, 18, 30, 19, -39, -77, -51,
+ -4, 10, -6, -18, -25, -37, -57, -70, -50, 4, 26, -15, -33, 9, 27, 6,
+ -38, -12, 50, 6, -47, -50, -40, -32, -25, -17, -10, -3, 0, 4, 17, 45,
+ 47, -23, -82, -60, -24, -14, -13, -10, -2, 7, 16, 24, 30, 33, 18, -32,
+ -56, 13, 23, -31, -41, -15, 19, -6, -35, 4, 52, 55, 35, 21, 22, 25,
+ 22, 15, 41, 89, 94, 38, -5, 4, 16, 2, -2, 7, -4, -41, -48, 12,
+ 58, 43, 2, -20, -38, -89, 14, 118, 38, 3, -15, -43, -32, 28, 78, 53,
+ 19, 24, 40, 34, 18, 26, 23, -28, -75, -61, -14, 10, -2, -16, -24, -34,
+ -53, -68, -55, -7, 25, -8, -36, 1, 27, 12, -31, -26, 45, 22, -39, -50,
+ -41, -32, -25, -17, -10, -4, 0, 3, 13, 38, 51, -5, -77, -69, -31, -15,
+ -14, -11, -4, 5, 13, 21, 27, 31, 20, -24, -61, -3, 28, -23, -43, -23,
+ 15, 5, -32, -6, 43, 53, 36, 22, 21, 26, 24, 14, 32, 79, 95, 46,
+ -3, 0, 15, 5, -1, 7, -1, -36, -52, 2, 53, 46, 7, -18, -30, -84,
+ -15, 114, 55, 4, -10, -40, -37, 15, 72, 59, 22, 20, 36, 36, 19, 23,
+ 26, -18, -70, -68, -25, 7, 2, -13, -22, -32, -49, -65, -59, -16, 22, -1,
+ -36, -8, 25, 17, -22, -35, 34, 36, -29, -48, -42, -32, -25, -18, -10, -4,
+ 0, 3, 10, 32, 52, 11, -67, -76, -38, -16, -13, -11, -6, 3, 11, 19,
+ 25, 30, 22, -15, -62, -19, 30, -14, -43, -30, 9, 13, -25, -15, 33, 51,
+ 37, 23, 21, 26, 26, 15, 24, 68, 94, 54, 0, -3, 13, 8, 1, 8,
+ 2, -30, -53, -8, 47, 49, 13, -16, -25, -75, -41, 102, 73, 6, -5, -36,
+ -40, 2, 65, 64, 25, 18, 33, 37, 21, 21, 27, -8, -63, -73, -36, 2,
+ 5, -10, -21, -30, -45, -62, -61, -25, 17, 5, -35, -17, 21, 21, -13, -39,
+ 20, 46, -16, -46, -42, -32, -25, -17, -10, -4, 0, 3, 8, 27, 50, 25,
+ -54, -81, -46, -19, -13, -12, -7, 1, 9, 17, 23, 28, 23, -8, -59, -35,
+ 27, -5, -42, -35, 2, 20, -16, -20, 24, 47, 38, 24, 21, 27, 28, 17,
+ 18, 58, 91, 62, 5, -6, 10, 10, 3, 9, 5, -24, -52, -17, 40, 50,
+ 18, -13, -22, -64, -60, 83, 90, 12, -3, -31, -41, -8, 55, 67, 30, 17,
+ 30, 37, 24, 19, 27, 1, -54, -75, -46, -4, 7, -7, -18, -28, -41, -58,
+ -61, -32, 11, 10, -31, -24, 17, 23, -4, -39, 5, 52, -2, -42, -42, -32,
+ -25, -17, -10, -4, 0, 3, 6, 22, 47, 35, -38, -82, -55, -23, -13, -12,
+ -8, -1, 7, 15, 21, 26, 23, -1, -53, -48, 20, 5, -39, -39, -6, 22,
+ -5, -22, 14, 43, 38, 25, 21, 27, 29, 19, 15, 47, 86, 68, 12, -7,
+ 7, 11, 4, 10, 7, -18, -50, -25, 33, 51, 24, -10, -20, -52, -72, 58,
+ 103, 21, -1, -26, -41, -17, 44, 67, 35, 16, 27, 36, 26, 18, 25, 8,
+ -45, -76, -55, -13, 7, -3, -16, -26, -38, -55, -61, -38, 4, 13, -26, -30,
+ 11, 25, 4, -36, -10, 51, 14, -37, -42, -33, -24, -17, -10, -4, 1, 3,
+ 6, 18, 42, 42, -22, -80, -63, -28, -14, -12, -9, -3, 5, 12, 19, 24,
+ 23, 3, -46, -58, 9, 14, -34, -41, -14, 21, 6, -21, 4, 36, 38, 26,
+ 21, 26, 30, 22, 13, 37, 78, 73, 20, -7, 4, 11, 6, 10, 10, -11,
+ -45, -33, 22, 49, 29, -4, -18, -40, -75, 23, 108, 40, 1, -18, -39, -26,
+ 28, 65, 42, 17, 22, 34, 29, 18, 23, 15, -30, -71, -65, -27, 3, 2,
+ -11, -22, -34, -49, -58, -45, -7, 13, -16, -35, -1, 24, 13, -23, -26, 37,
+ 36, -20, -39, -34, -24, -17, -10, -4, 1, 3, 5, 12, 33, 46, 6, -64,
+ -75, -40, -17, -12, -10, -5, 2, 9, 15, 20, 22, 10, -30, -65, -18, 20,
+ -19, -42, -27, 11, 21, -8, -8, 22, 34, 27, 22, 26, 31, 27, 14, 22,
+ 60, 75, 34, -4, -2, 8, 8, 11, 14, -2, -36, -42, 6, 44, 36, 4,
+ -15, -26, -66, -24, 95, 71, 8, -10, -33, -32, 7, 56, 51, 21, 17, 29,
+ 32, 20, 19, 20, -12, -59, -72, -45, -8, 5, -5, -17, -28, -42, -54, -50,
+ -21, 9, -5, -36, -16, 19, 21, -7, -34, 12, 51, 4, -33, -34, -25, -17,
+ -10, -4, 1, 4, 5, 9, 23, 44, 29, -39, -79, -55, -24, -13, -10, -7,
+ -1, 6, 12, 16, 20, 14, -15, -62, -46, 16, -2, -39, -36, -2, 29, 9,
+ -12, 8, 28, 27, 23, 25, 31, 31, 17, 13, 43, 72, 46, 2, -5, 5,
+ 8, 11, 16, 5, -26, -44, -8, 36, 40, 12, -12, -19, -52, -53, 67, 94,
+ 20, -5, -27, -35, -7, 45, 55, 27, 15, 25, 32, 23, 17, 21, 0, -47,
+ -73, -57, -19, 4, 0, -13, -24, -37, -50, -51, -29, 3, 1, -32, -26, 12,
+ 23, 3, -32, -6, 52, 22, -26, -34, -25, -17, -10, -4, 1, 5, 6, 8,
+ 18, 39, 38, -21, -76, -64, -30, -14, -10, -8, -2, 4, 10, 15, 18, 14,
+ -9, -56, -57, 7, 7, -35, -39, -10, 27, 18, -10, 2, 23, 26, 23, 24,
+ 31, 32, 20, 11, 35, 67, 51, 7, -6, 3, 8, 11, 17, 8, -20, -44,
+ -15, 31, 41, 16, -9, -17, -43, -61, 44, 102, 31, -2, -23, -35, -15, 36,
+ 56, 32, 0, -27, 1, -1, -1, 3, -4, -2, 1, -1, -2, 2, 3, -6,
+ 1, 2, -6, 2, 2, -4, -1, 2, -5, 1, 4, -4, 0, -1, 0, -1,
+ -2, 2, 2, -6, 0, 4, -3, -3, 4, -2, -3, -2, 0, 1, 1, -2,
+ -2, 3, -8, 27, -42, 11, 21, -35, 34, -25, 12, 9, -24, 14, 13, -38,
+ 53, -42, -3, 46, -73, 55, -16, -9, 28, -49, 38, -12, -21, 49, -51, 20,
+ 32, -73, 64, -28, -7, 32, -50, 42, -11, -30, 49, -21, -31, 46, -25, -7,
+ 20, -22, 18, -16, -10, 21, -23, 5, 28, -35, 8, 0, 8, -26, 19, 6,
+ -11, -20, 64, -46, -18, 51, -73, 119, -117, 46, 36, -80, 67, -46, 22, 0,
+ -24, 56, -59, 14, 26, -40, 24, -9, 20, -20, -15, 43, -26, -11, 9, 14,
+ -3, -31, 6, 54, -62, 3, 67, -78, 20, 21, -25, 31, -41, 18, 27, -53,
+ 32, 15, -48, 37, -11, 4, -12, -3, 31, -24, -21, 42, -10, -45, 55, -32,
+ 34, -43, -14, 86, -78, 8, 39, -35, -2, 13, 2, 5, -11, -4, 7, 5,
+ -31, 37, -4, -28, 28, -9, -11, 10, -1, 4, -18, 17, -9, -13, 24, -18,
+ 20, -18, -30, 59, -25, -29, 48, -15, -29, 23, 4, -3, -18, 14, 6, -8,
+ -19, 19, 8, -13, 0, 13, -18, 4, 1, 0, 0, 10, -14, -12, 39, -46,
+ 23, 9, -22, 23, -20, -22, 63, -42, -28, 77, -66, 12, 38, -56, 31, 27,
+ -77, 66, -11, -39, 59, -33, -41, 92, -54, -50, 96, -36, -46, 46, -17, 31,
+ -43, -28, 98, -57, -50, 84, -22, -44, 39, -8, 17, -28, -13, 63, -67, 16,
+ 10, 3, -15, -4, 36, -34, -1, 26, -27, -2, 13, 7, -22, 0, 27, -11,
+ -19, 6, 26, -42, 14, 18, -7, -14, -10, 37, -14, -24, 25, -4, -5, -10,
+ 3, 35, -39, -7, 31, -8, -23, 15, 4, -1, -25, 28, 7, -35, 34, -16,
+ -1, 9, -35, 45, -22, -17, 48, -52, 24, 22, -65, 48, 7, -45, 47, -19,
+ -33, 71, -70, 46, -7, -52, 68, -25, -35, 48, -13, -17, 14, 2, -12, 8,
+ -10, 1, 22, -32, 4, 34, -26, -18, 29, -7, -19, 15, -7, 15, -8, -29,
+ 50, -22, -35, 53, -19, -37, 47, -9, -40, 41, 1, -27, 7, 3, 0, 0,
+ -7, 13, -7, -21, 26, 14, -44, 11, 40, -51, 10, 26, -28, 16, -13, -3,
+ 31, -42, 11, 34, -52, 11, 34, -43, 10, 29, -19, -21, 27, -10, -5, 10,
+ -14, 11, 3, -35, 43, 3, -52, 37, 22, -66, 49, -12, -19, 50, -58, 16,
+ 42, -70, 50, -2, -42, 60, -69, 43, 11, -57, 54, -8, -31, 23, -8, -7,
+ 24, -32, 11, 21, -51, 60, -44, -6, 68, -87, 33, 45, -79, 50, -7, -13,
+ 21, -40, 31, 12, -41, 18, 24, -39, 15, 7, -17, 25, -20, -12, 43, -47,
+ 17, 6, -16, 10, 4, -11, -1, 14, -10, -7, 6, 9, -23, 9, 3, 13,
+ -30, 16, 16, -33, 17, 4, -17, 23, -29, 3, 54, -86, 50, 11, -41, 30,
+ -23, 15, 18, -60, 56, 7, -65, 49, -4, -12, 1, -6, 19, -4, -33, 35,
+ -10, -12, 13, -2, -2, -2, 2, -10, 16, -8, -11, 19, -6, -19, 24, -14,
+ 9, 3, -24, 24, -6, -13, 19, -11, -6, 6, -9, 16, -8, -10, 14, -10,
+ -1, -5, 16, -8, -25, 37, -11, -27, 37, -14, -13, 19, -17, 14, -5, -15,
+ 26, -27, 10, 11, -23, 22, -5, -19, 25, -7, -28, 44, -35, 0, 25, -31,
+ 31, -10, -26, 46, -41, 2, 33, -40, 24, 8, -43, 44, -12, -25, 37, -25,
+ -6, 29, -27, 5, 24, -40, 24, -1, -25, 23, -1, -6, -2, -1, 14, -24,
+ 8, 13, -11, 0, -13, 16, 15, -56, 43, 12, -35, 14, -9, 18, -10, -19,
+ 28, -3, -27, 23, -2, -14, 27, -35, 10, 35, -68, 44, 7, -43, 46, -21,
+ -25, 56, -35, -21, 51, -33, -8, 28, -27, 19, -2, -26, 36, -26, 3, 13,
+ -12, 6, -10, 8, -14, 15, -12, 0, 13, -9, -16, 32, -27, 3, 23, -49,
+ 49, -17, -31, 63, -64, 25, 36, -76, 61, -11, -47, 75, -54, -9, 69, -81,
+ 32, 29, -63, 46, -7, -26, 39, -31, 6, 18, -26, 13, -5, 5, -5, -2,
+ 5, -12, 17, -17, -2, 22, -25, 1, 20, -19, 3, 6, -6, 3, -9, 10,
+ -6, -3, 7, -7, -3, 12, -5, -5, -11, 24, -7, -23, 24, 0, -14, 0,
+ 12, -10, -2, 5, 0, 1, -10, 10, -2, -17, 26, -11, -16, 28, -22, 6,
+ 4, -17, 30, -27, -7, 46, -54, 15, 29, -42, 25, -4, -15, 26, -29, 11,
+ 15, -28, 19, -7, 1, 8, -20, 14, 1, -15, 11, -2, -2, 0, -10, 15,
+ -5, -12, 15, -1, -15, 12, 4, -15, 9, -1, -9, 9, -5, -6, 13, -12,
+ 1, 6, -6, -3, 6, -4, 0, -6, 11, -9, -2, 13, -12, -2, -1, 8,
+ -11, 4, 2, -6, 4, -4, 4, 0, -13, 15, 0, -21, 23, -5, -15, 15,
+ -2, -9, 6, -2, -4, 2, 3, -1, -7, 7, -2, -9, 6, 2, -9, 4,
+ 5, -12, 10, -9, 4, 5, -16, 12, -2, -13, 20, -13, -4, 17, -23, 14,
+ 2, -20, 22, -13, -3, 15, -22, 12, 4, -18, 17, -7, -7, 13, -14, 6,
+ 4, -10, 9, -5, -6, 7, 0, -7, 8, -4, -1, 0, -6, 4, 7, -14,
+ 2, 13, -16, 3, 10, -15, 7, -1, -10, 14, -10, -2, 11, -9, -4, 7,
+ -6, 3, -3, -5, 9, -6, -3, 5, 1, -7, 3, -2, 0, -2, 0, 4,
+ -3, -2, 4, -6, 4, -2, -2, 0, 1, 0, -7, 7, -2, -7, 9, -7,
+ -4, 11, -15, 11, -2, -9, 9, -4, -3, 2, 3, -7, 5, 0, -5, 6,
+ -7, 1, 7, -10, -2, 13, -9, -4, 8, -4, -2, -1, 1, 1, -7, 4,
+ 5, -8, 0, 6, -6, 0, 3, -4, 0, 1, -2, 2, -4, -4, 8, -7,
+ -1, 6, -9, 8, -3, -6, 12, -12, 1, 10, -11, 1, 5, -6, 3, -2,
+ -3, 7, -10, 2, 7, -12, 5, 2, -5, 3, -5, 0, 6, -10, 3, 4,
+ -8, 2, 2, -3, 3, -8, 8, 2, -14, 10, 3, -12, 8, 2, -11, 8,
+ -2, -6, 9, -7, -4, 10, -9, -1, 7, -7, 1, 3, -8, 8, -2, -8,
+ 10, -3, -5, 5, -6, 3, 1, -8, 10, -5, -5, 7, -4, -2, 2, -3,
+ 1, -1, -3, 4, -3, 0, 0, 0, 0, -4, 3, -2, -3, 3, -5, 3,
+ 0, -7, 5, 1, -8, 5, 1, -6, 6, -5, 0, 3, -7, 3, 2, -6,
+ 3, 2, -6, 3, 1, -3, -2, 5, -4, -1, 3, -4, 0, 0, -3, 5,
+ -5, -3, 7, -5, -3, 6, -4, 0, -1, -3, 3, -2, -1, 2, -1, -2,
+ 1, -2, 1, -1, -7, 8, -1, 5, -7, 13, -22, 8, -7, 8, -110, -28,
+ 24, 54, 36, 2, 60, -45, 57, 42, -43, 20, 41, -66, 24, -11, 18, -18,
+ -38, -63, -36, 30, -11, 33, 25, 30, 18, 11, -18, -5, 5, -46, 40, 1,
+ -13, -18, -20, -31, 20, 10, 29, -7, -18, 40, -29, -17, 42, -19, 6, -4,
+ 6, -8, 10, -26, -5, 3, 1, -17, 6, 0, 19, -1, 8, 0, -6, -10,
+ -1, -12, -1, 1, -3, 8, -7, 4, 11, 4, 14, -13, 16, -19, -4, -13,
+ -13, -14, 6, 4, -1, 4, 11, -1, 11, -1, 1, -4, -1, -15, 6, -9,
+ 1, -1, 0, 3, 1, -8, 3, -1, -1, 2, -2, 2, -2, 1, -5, -7,
+ 3, -3, 6, -3, 4, -1, 0, -4, 2, -7, 3, -6, -1, -1, 4, 0,
+ 3, -2, 2, -5, 5, -8, -3, -3, 2, -5, 7, -1, 4, -2, 4, -10,
+ 6, -6, -1, -4, 5, -13, 7, -6, 5, -8, 17, -20, 14, -6, 9, -40,
+ 71, -127, 9, -73, 127, 76, -28, 74, -32, 8, -62, -49, -38, 40, -68, 22,
+ -12, 68, 10, 39, -10, 0, 35, -23, 0, -59, -15, -7, -3, -23, 1, -20,
+ 37, 27, 2, 30, -2, 17, 2, -5, -7, -27, -29, 16, -3, -11, 1, -16,
+ -5, -8, -10, 7, 32, 9, 5, -4, 16, 5, -8, -17, -16, 5, -13, 8,
+ 11, 15, -10, -9, 0, -1, 2, 7, -3, -23, 9, 2, 3, 1, -13, -1,
+ -6, 11, -6, 8, 1, 12, -12, 9, -14, 8, -1, 0, -3, -13, 4, -7,
+ -4, 8, 5, -5, -7, 4, -2, -3, 2, 3, -6, 8, -3, 1, -3, -2,
+ 2, -6, 2, -4, -3, -4, 3, 1, 0, 0, 1, -1, -1, 2, -2, 0,
+ -4, -2, 1, 2, 0, -3, 1, -3, 0, -1, -3, -6, 2, -2, 3, -4,
+ 10, -8, 9, -5, 12, -19, 46, 37, -128, 60, -90, 102, -65, 40, -57, 39,
+ -6, 23, -8, 19, 24, 15, -17, -47, -27, -36, -16, 21, 3, 23, 14, 50,
+ -8, 19, 25, 7, -9, -28, -63, -37, 0, -42, 54, -17, 68, -3, 30, -12,
+ -4, 11, -15, 9, -25, -15, -2, -27, -25, 38, -8, -13, 33, 24, 12, -38,
+ 39, -12, -3, -17, -44, 38, 2, 27, 3, -5, -4, -13, -30, -56, -4, 11,
+ 1, 9, 17, 46, 25, -14, 6, -3, -7, -21, 2, 16, -5, -22, 2, -2,
+ 6, -12, -25, -15, 10, 9, 8, 11, 43, 8, -5, -22, -16, 14, -31, 16,
+ 7, -7, -26, -20, -2, 9, 11, 26, 7, 6, -20, -13, 0, 4, 17, -17,
+ -18, 10, 2, -10, 27, -8, 24, -23, -14, 1, 0, 13, -19, 14, 10, -16,
+ 16, -4, -20, 20, -33, 2, 2, 24, 21, -3, -26, -24, -18, -18, 10, 10,
+ 24, 18, 2, 9, -24, 16, -14, -8, 9, -5, -14, 8, -5, 30, -11, 11,
+ -13, -15, -12, 7, 4, -13, -13, 13, -13, 12, 23, 9, 0, 14, -10, -9,
+ -35, -2, -21, 12, -1, 17, 19, 11, -4, 0, -18, -24, 11, -10, 1, 11,
+ 12, -13, -16, 10, -23, 21, 9, -9, 3, 12, -6, 3, -5, 12, 0, -2,
+ 0, -19, -9, 5, -11, -7, 10, 1, -3, 9, 18, -6, 0, -1, 1, -13,
+ 2, 1, -3, -8, 17, -4, -9, 18, -15, 8, -1, -11, -5, -14, 11, -5,
+ -7, 12, 16, -7, 7, -3, -11, -5, -6, 1, 4, -3, -3, 15, 5, 0,
+ 3, 6, -16, 4, -14, -6, -9, -4, 2, 11, 11, 7, -2, 4, -12, -7,
+ -14, -6, -7, 9, 4, 7, -2, 6, 5, 6, -4, -3, -4, 7, -7, -11,
+ -9, 0, -3, 7, -2, -2, 3, 13, -4, -6, -15, 9, -7, -1, 4, 6,
+ 5, 8, -6, -8, 0, -11, -4, 6, -8, 4, 3, 5, 13, -4, -9, -3,
+ 4, -3, -3, 4, -1, -12, 6, -14, 2, 3, 15, 2, 6, -7, -8, 3,
+ 1, -2, 3, -3, -12, -6, -14, 7, -2, 13, 6, 10, 6, 0, -2, -10,
+ -12, -8, -6, -7, -6, 6, 4, -2, 5, 2, 0, -1, 3, -11, 4, 0,
+ 20, -8, -2, 0, -1, -3, 7, -3, -4, -2, -6, -10, -10, -8, 1, 2,
+ 5, 8, 2, 5, 8, 3, 4, 3, -2, -15, 0, -1, -7, -2, -5, -10,
+ 10, -1, 5, 3, 5, -1, -2, -8, -5, -9, 1, -8, 6, 5, 4, 1,
+ 1, 2, 3, -2, 4, -7, 1, -7, -9, -2, 0, 2, 3, 6, -8, 8,
+ 3, 0, -2, -9, -3, -2, 0, 3, -1, -2, -3, 7, -3, 10, -8, 1,
+ -12, 3, -7, 2, -3, 7, 4, 4, 0, 0, -6, -1, -5, -3, -4, -7,
+ 0, 5, 7, 0, 2, -3, 10, -1, 3, -7, -5, -4, -9, -3, -7, 5,
+ -4, 9, 2, 1, 4, 5, 0, -5, 1, -8, 4, -9, 5, -5, 0, 3,
+ -2, -1, 1, 1, -7, 7, 0, 3, -5, 0, -3, -1, -1, -5, -1, 1,
+ -1, 1, -1, 0, 2, 0, 2, -7, -7, 4, -1, 0, 3, 4, -1, -3,
+ -4, -6, 3, -2, 4, -1, 5, -2, -1, -5, -2, -4, 1, 3, 2, 2,
+ 0, -3, 1, 1, -3, -3, -1, 1, -3, -2, -1, -2, -3, -1, 0, 4,
+ 3, 5, 2, 1, -4, -9, -3, -7, 1, -2, 7, -2, 3, 3, 3, 1,
+ 0, -1, -6, -7, -6, -4, -1, 1, 0, 5, 2, -2, 2, -3, -1, 3,
+ -1, 1, -4, -4, -5, 0, -7, 2, -4, 3, 4, 1, 2, -1, -1, -2,
+ -2, 0, -1, 1, -1, -1, -3, 1, 1, 3, -3, -1, 1, 1, -2, -3,
+ -8, -5, 0, -1, 5, 2, 3, 1, -2, -1, -1, -3, 1, 1, -2, -3,
+ -3, -1, 0, -1, 1, 2, 2, 5, 0, -1, -2, -1, -2, 0, -4, 0,
+ -5, -1, -1, 0, 1, 5, 4, -2, -1, -2, 0, -6, -1, 0, 1, -1,
+ -2, 1, 0, 0, 3, 1, -2, 1, -2, -4, -1, 0, -1, -1, -4, -2,
+ -4, 2, -1, 1, 0, 3, 2, 0, 4, -1, 4, -6, 2, -4, -3, -5,
+ -4, -3, 0, 2, 0, 1, 4, 2, 2, -2, -2, -5, -6, -5, -3, -2,
+ 1, -1, 0, 0, 2, 2, 2, 0, 4, -2, 3, 2, -1, -2, -3, -3,
+ -3, -5, -5, -5, -1, -1, 0, 2, 2, 4, 1, 2, 1, 2, -1, -1,
+ -3, -4, -5, -3, -2, -2, -1, 1, 4, 2, 2, 2, 1, -1, -2, -6,
+ -2, -3, 2, -1, 1, -2, 0, 2, 1, 2, -2, 1, 0, -2, -2, -3,
+ 0, -2, -1, -1, 0, -2, -2, 1, 0, 2, -1, 1, -1, 0, -1, -1,
+ 0, -1, 0, -2, 2, 0, 2, 2, 5, 3, 6, 8, 12, 13, -6, -110,
+ -7, 51, -99, -128, 10, -28, -39, 25, -33, -27, 41, 34, -5, 17, 23, 25,
+ 24, 23, 20, 24, 25, 24, 21, 20, 23, 23, 16, 20, 9, 20, 18, 10,
+ 14, 5, 14, 11, 7, 5, 3, 10, 2, 7, -4, 0, 3, 0, -3, -5,
+ -6, -1, -12, -4, -17, -10, 9, -42, -40, 65, 40, -58, 29, 72, 39, 50,
+ 31, -1, 30, 25, -7, -4, -33, -47, -29, -49, -74, -69, -71, -79, -61, -51,
+ -57, -53, -34, -20, -22, -16, -10, -6, -2, 1, 3, 4, 8, 8, 12, 10,
+ 9, 14, 13, 12, 12, 13, 12, 12, 14, 12, 12, 12, 12, 13, 12, 9,
+ 11, 11, 11, 7, 8, 7, 8, 9, 2, 5, 8, -6, 2, 17, -17, -20,
+ 18, 5, -15, 15, 27, 21, 37, 44, 41, 46, 38, 26, 32, 26, -4, -15,
+ -6, -20, -44, -50, -54, -60, -59, -58, -58, -54, -46, -38, -32, -26, -19, -14,
+ -9, -5, -1, 2, 5, 7, 8, 10, 11, 12, 13, 13, 14, 14, 14, 13,
+ 13, 14, 15, 14, 11, 13, 14, 13, 12, 10, 12, 12, 10, 10, 8, 6,
+ 11, 9, -1, 5, 11, -1, -6, 1, -1, -4, 0, -1, 0, 14, 25, 24,
+ 28, 37, 38, 38, 38, 31, 22, 14, 4, -5, -15, -26, -38, -47, -52, -54,
+ -56, -57, -55, -51, -45, -39, -34, -28, -22, -17, -13, -8, -3, -1, 2, 5,
+ 7, 8, 10, 11, 12, 13, 13, 13, 13, 14, 14, 13, 13, 14, 13, 12,
+ 13, 13, 12, 11, 12, 11, 9, 11, 9, 6, 7, 8, 5, 3, 2, 0,
+ 0, 0, -2, -3, 0, 3, 6, 11, 18, 23, 27, 31, 34, 35, 32, 27,
+ 21, 14, 5, -5, -15, -26, -35, -43, -48, -52, -53, -53, -52, -49, -44, -40,
+ -35, -29, -24, -19, -14, -10, -6, -3, 1, 3, 5, 7, 9, 10, 11, 12,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 12, 13, 12, 11, 13, 11, 10,
+ 10, 9, 9, 8, 7, 7, 5, 4, 3, 2, 0, -1, -1, 0, 2, 4,
+ 8, 12, 17, 22, 25, 28, 30, 30, 28, 24, 19, 12, 3, -5, -14, -23,
+ -31, -37, -43, -46, -46, -48, -47, -43, -41, -38, -33, -29, -25, -21, -16, -12,
+ -8, -5, -2, 0, 3, 5, 7, 9, 10, 11, 12, 12, 13, 14, 13, 13,
+ 13, 13, 13, 12, 12, 12, 11, 11, 11, 10, 9, 9, 8, 7, 7, 6,
+ 5, 4, 4, 3, 3, 3, 3, 5, 6, 8, 10, 12, 14, 17, 18, 19,
+ 20, 19, 17, 14, 10, 5, 0, -6, -11, -17, -22, -26, -29, -32, -34, -34,
+ -35, -34, -32, -31, -28, -26, -23, -20, -17, -14, -11, -8, -5, -3, 0, 2,
+ 4, 6, 7, 8, 9, 10, 11, 11, 12, 12, 12, 12, 11, 11, 11, 10,
+ 10, 9, 9, 8, 8, 7, 7, 6, 5, 5, 5, 4, 4, 5, 5, 5,
+ 6, 7, 8, 9, 10, 11, 12, 13, 13, 13, 13, 12, 10, 8, 5, 2,
+ -2, -6, -10, -14, -18, -21, -24, -26, -28, -29, -29, -30, -29, -28, -27, -25,
+ -23, -20, -18, -15, -12, -10, -7, -4, -2, 0, 2, 4, 6, 7, 9, 10,
+ 10, 11, 11, 12, 12, 12, 12, 11, 11, 11, 10, 10, 9, 9, 8, 8,
+ 7, 7, 6, 6, 5, 5, 5, 5, 6, 6, 7, 7, 8, 9, 10, 11,
+ 12, 13, 13, 13, 12, 11, 10, 8, 5, 2, -1, -5, -9, -13, -16, -19,
+ -22, -24, -26, -27, -28, -28, -28, -27, -26, -24, -22, -20, -18, -15, -13, -10,
+ -7, -5, -2, 0, 2, 4, 5, 7, 8, 9, 10, 11, 11, 11, 11, 11,
+ 11, 11, 11, 10, 10, 9, 9, 8, 8, 7, 7, 6, 6, 6, 5, 5,
+ 5, 5, 6, 6, 6, 7, 8, 9, 10, 11, 11, 12, 12, 12, 11, 10,
+ 9, 7, 5, 2, -1, -5, -8, -12, -15, -18, -21, -23, -25, -26, -27, -27,
+ -27, -26, -25, -24, -22, -20, -18, -16, -13, -11, -8, -6, -3, -1, 1, 3,
+ 4, 6, 7, 8, 9, 10, 10, 10, 11, 11, 11, 10, 10, 10, 10, 9,
+ 9, 8, 8, 7, 7, 6, 6, 6, 5, 5, 5, 5, 6, 6, 6, 7,
+ 8, 9, 9, 10, 11, 11, 11, 11, 11, 10, 9, 7, 4, 2, -1, -4,
+ -7, -11, -14, -17, -19, -21, -23, -24, -25, -26, -26, -25, -24, -23, -22, -20,
+ -18, -16, -13, -11, -9, -6, -4, -2, 0, 2, 4, 5, 7, 8, 9, 9,
+ 10, 10, 11, 11, 11, 11, 10, 10, 10, 9, 9, 8, 8, 7, 7, 7,
+ 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 8, 9, 9, 10, 11, 11,
+ 11, 11, 10, 10, 8, 7, 5, 2, -1, -3, -7, -10, -13, -15, -18, -20,
+ -22, -23, -24, -25, -25, -24, -24, -23, -21, -20, -18, -16, -14, -11, -9, -7,
+ -5, -2, 0, 1, 3, 5, 6, 7, 8, 9, 9, 10, 10, 10, 10, 10,
+ 10, 10, 9, 9, 8, 8, 8, 7, 7, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 7, 7, 8, 8, 9, 9, 9, 10, 9, 9, 8, 7, 6, 4,
+ 2, 0, -2, -5, -7, -10, -12, -15, -17, -18, -20, -21, -21, -22, -22, -21,
+ -21, -20, -18, -17, -15, -13, -12, -10, -8, -6, -4, -2, 0, 1, 3, 4,
+ 5, 6, 7, 8, 8, 8, 9, 9, 9, 9, 9, 8, 8, 8, 8, 7,
+ 7, 7, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8,
+ 8, 8, 8, 8, 7, 6, 5, 4, 3, 1, -1, -3, -5, -7, -9, -10,
+ -12, -14, -15, -16, -17, -18, -18, -18, -18, -17, -17, -16, -15, -13, -12, -11,
+ -9, -7, -6, -4, -3, -1, 0, 1, 3, 4, 5, 5, 6, 7, 7, 7,
+ 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 6, 5,
+ 4, 3, 2, 0, -1, -3, -5, -7, -9, -10, -12, -13, -15, -16, -17, -17,
+ -18, -18, -18, -17, -17, -16, -15, -14, -12, -11, -9, -8, -6, -5, -3, -2,
+ -1, 1, 2, 3, 4, 5, 5, 6, 6, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 6, 6, 5, 4, 3, 2, 0, -1, -3,
+ 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 2, 3, 4, 5,
+ 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 6, 7, 8, 9, 10, 10,
+ 11, 12, 12, 13, 13, 14, 15, 17, 18, 19, 20, 21, 22, 23, 24, 26,
+ 27, 29, 29, 29, 28, 28, 28, 29, 30, 31, 31, 31, 31, 28, 19, -8,
+ -41, -53, -57, -59, -60, -62, -62, -63, -64, -65, -65, -66, -67, -69, -69, -69,
+ -72, -74, -73, -74, -76, -78, -79, -81, -82, -82, -83, -81, -83, -85, -81, -81,
+ -88, -90, -80, -64, -47, -32, -23, -18, -15, -13, -12, -12, -12, -13, -13, -13,
+ -13, -13, -12, -12, -11, -9, -7, -6, -4, -2, -1, 0, 1, 2, 4, 5,
+ 7, 10, 12, 14, 16, 18, 19, 18, 19, 21, 19, 20, 22, 22, 22, 25,
+ 27, 28, 29, 29, 29, 29, 29, 30, 31, 31, 31, 33, 34, 34, 35, 34,
+ 33, 31, 30, 29, 26, 25, 26, 25, 22, 22, 21, 20, 20, 19, 19, 19,
+ 18, 18, 18, 17, 17, 17, 17, 16, 16, 16, 15, 13, 13, 14, 14, 15,
+ 13, 12, 13, 13, 11, 12, 14, 14, 16, 17, 15, 16, 19, 19, 19, 19,
+ 21, 19, 17, 18, 19, 18, 15, 15, 17, 18, 18, 13, 11, 14, 15, 14,
+ 11, 6, 5, 10, 13, 17, 18, 11, 2, -2, -2, -3, 2, 14, 24, 30,
+ 37, 47, 52, 52, 56, 63, 65, 65, 63, 65, 72, 75, 73, 71, 73, 77,
+ 82, 82, 77, 77, 82, 90, 99, 104, 99, 89, 84, 86, 94, 106, 119, 127,
+ 126, 117, 104, 87, 64, 42, 24, 10, -2, -15, -22, -25, -27, -30, -35, -37,
+ -36, -34, -33, -36, -40, -42, -44, -43, -44, -48, -53, -57, -59, -57, -53, -52,
+ -53, -57, -62, -68, -73, -75, -75, -71, -63, -56, -48, -40, -34, -29, -26, -23,
+ -22, -21, -19, -19, -20, -21, -22, -22, -22, -22, -22, -21, -21, -21, -20, -19,
+ -19, -18, -18, -17, -17, -16, -14, -14, -13, -11, -9, -9, -9, -9, -9, -8,
+ -8, -8, -8, -8, -7, -6, -7, -6, -4, -3, -2, -2, -3, -4, -3, -3,
+ -2, -1, 0, 0, -1, -1, 0, -1, -1, -1, -3, -5, -5, -8, -10, -10,
+ -9, -9, -10, -11, -11, -11, -11, -11, -10, -9, -10, -10, -10, -11, -12, -12,
+ -13, -12, -11, -12, -14, -14, -11, -10, -12, -11, -11, -12, -12, -11, -11, -13,
+ -12, -9, -6, -6, -7, -7, -6, -5, -4, -4, -5, -8, -12, -11, -8, -4,
+ -3, -5, -6, -7, -9, -12, -13, -8, -3, -2, -4, -8, -11, -14, -15, -17,
+ -19, -19, -15, -8, -1, 2, 4, 8, 12, 17, 23, 26, 25, 24, 25, 30,
+ 36, 40, 39, 36, 33, 32, 33, 37, 43, 49, 53, 53, 49, 45, 43, 43,
+ 46, 52, 60, 67, 76, 82, 82, 78, 69, 58, 47, 37, 26, 14, 2, -9,
+ -16, -21, -24, -28, -32, -35, -37, -38, -37, -36, -36, -36, -39, -43, -46, -49,
+ -51, -49, -47, -46, -45, -45, -48, -52, -58, -62, -65, -66, -65, -62, -58, -54,
+ -50, -45, -39, -34, -30, -28, -25, -23, -21, -20, -20, -20, -20, -19, -18, -19,
+ -20, -18, -17, -18, -17, -17, -18, -17, -16, -15, -15, -13, -12, -10, -10, -10,
+ -9, -8, -7, -6, -4, -4, -5, -6, -5, -4, -4, -3, -2, -2, -1, -1,
+ -1, 0, 2, 3, 2, 2, 3, 2, 1, 2, 4, 5, 5, 4, 4, 4,
+ 3, 2, 2, 1, 0, 0, -1, -4, -5, -4, -2, -2, -3, -3, -3, -2,
+ -1, -2, -3, -2, -3, -4, -4, -3, -4, -6, -7, -4, 0, 0, -2, -4,
+ -4, -3, -2, -2, -3, -4, -4, -3, -2, -1, 3, 6, 8, 6, 3, 0,
+ 0, 2, 4, 5, 4, 3, 2, 2, 2, 1, 0, -1, 2, 7, 11, 9,
+ 6, 2, -1, -3, -3, -5, -7, -8, -6, -3, 2, 8, 13, 17, 18, 18,
+ 19, 23, 28, 34, 40, 42, 42, 40, 39, 39, 40, 42, 46, 50, 55, 59,
+ 59, 55, 51, 48, 48, 51, 57, 63, 70, 76, 82, 86, 88, 89, 86, 80,
+ 71, 61, 51, 43, 34, 25, 18, 10, 2, -5, -9, -12, -13, -12, -12, -13,
+ -14, -17, -22, -26, -29, -28, -27, -25, -24, -24, -25, -27, -31, -35, -40, -43,
+ -46, -47, -49, -49, -46, -43, -40, -36, -32, -28, -24, -21, -18, -16, -14, -13,
+ -13, -12, -11, -11, -12, -11, -10, -9, -11, -11, -11, -12, -12, -12, -10, -10,
+ -10, -10, -9, -8, -7, -6, -5, -4, -4, -4, -4, -4, -3, -2, -2, -1,
+ -2, -3, -2, -1, 0, 0, 1, 2, 3, 2, 1, 1, 2, 3, 3, 4,
+ 5, 4, 4, 5, 6, 7, 6, 4, 3, 3, 3, 2, -1, -3, -3, -1,
+ -1, -2, -3, -3, -2, -1, 1, 0, -1, -1, -2, -5, -6, -5, -4, -4,
+ -4, -4, -6, -6, -4, -1, 0, -2, -6, -9, -10, -8, -5, -4, -3, -3,
+ -1, 1, 1, -1, -3, -4, -2, 0, 2, 2, 0, -3, -6, -7, -6, -4,
+ -3, -2, -1, -1, -1, 0, 1, 0, -3, -9, -14, -18, -18, -15, -12, -9,
+ -8, -7, -5, -3, -2, 0, 5, 11, 17, 22, 25, 24, 23, 21, 20, 22,
+ 27, 32, 37, 40, 41, 40, 39, 37, 35, 34, 34, 35, 39, 45, 52, 59,
+ 66, 71, 73, 75, 74, 71, 65, 60, 55, 48, 39, 28, 17, 7, -1, -7,
+ -11, -13, -13, -14, -17, -21, -24, -28, -31, -32, -32, -32, -32, -31, -29, -29,
+ -30, -33, -36, -40, -44, -47, -50, -52, -54, -55, -54, -52, -49, -47, -43, -39,
+ -35, -31, -28, -26, -24, -22, -21, -19, -18, -17, -17, -16, -15, -16, -18, -17,
+ -16, -16, -17, -18, -18, -17, -16, -16, -14, -13, -13, -12, -12, -12, -11, -10,
+ -10, -9, -7, -8, -9, -10, -10, -8, -6, -5, -6, -6, -5, -3, -3, -4,
+ -4, -4, -3, -2, -2, -1, -1, -1, 0, 2, 3, 3, 3, 2, 1, 0,
+ -1, -1, -1, -2, -3, -5, -5, -4, -2, -3, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1,
+ 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 1, 3, 2, 0,
+ -1, 1, 2, 1, -1, -1, 2, 2, 0, 1, 2, 2, -1, -4, -10, -21,
+ -30, -36, -41, -44, -40, -30, -18, -10, -8, -11, -13, -8, 3, 18, 32, 41,
+ 44, 45, 48, 49, 43, 32, 23, 14, 7, 8, 16, 27, 35, 37, 30, 18,
+ 9, 5, 3, 2, 1, 1, -1, -6, -11, -12, -6, -2, -5, -11, -18, -28,
+ -39, -47, -55, -69, -86, -99, -102, -92, -70, -46, -28, -15, -3, 7, 17, 26,
+ 28, 24, 23, 30, 42, 53, 57, 50, 36, 21, 5, -5, -4, 6, 20, 31,
+ 35, 34, 29, 26, 27, 37, 56, 76, 85, 80, 71, 63, 55, 47, 34, 13,
+ -13, -32, -39, -40, -46, -65, -93, -117, -128, -128, -126, -120, -110, -96, -78, -58,
+ -36, -14, 3, 10, 20, 41, 60, 68, 63, 54, 45, 39, 36, 32, 28, 29,
+ 35, 41, 47, 46, 41, 39, 43, 53, 68, 80, 78, 64, 46, 28, 13, 3,
+ -9, -35, -64, -80, -82, -74, -66, -71, -91, -111, -121, -118, -105, -86, -68, -57,
+ -49, -37, -22, -7, 5, 14, 26, 42, 55, 56, 46, 35, 25, 14, 6, 2,
+ 1, 3, 11, 22, 32, 40, 43, 42, 46, 60, 77, 88, 90, 78, 54, 30,
+ 14, 2, -15, -37, -62, -82, -90, -89, -86, -90, -99, -107, -109, -101, -81, -54,
+ -29, -14, -5, 7, 24, 40, 49, 56, 68, 83, 92, 92, 87, 74, 54, 32,
+ 12, -5, -19, -25, -24, -18, -7, 1, -1, -6, -4, 13, 41, 69, 84, 80,
+ 63, 44, 32, 29, 25, 11, -10, -25, -31, -35, -40, -48, -65, -87, -104, -109,
+ -102, -87, -69, -58, -54, -42, -21, 0, 13, 29, 51, 71, 84, 89, 86, 75,
+ 54, 33, 14, -3, -19, -29, -27, -22, -18, -11, -8, -16, -26, -19, 2, 24,
+ 40, 48, 42, 27, 21, 29, 34, 24, 7, -5, -14, -23, -28, -32, -45, -67,
+ -82, -85, -78, -63, -46, -34, -29, -24, -13, 0, 12, 25, 44, 65, 79, 85,
+ 86, 78, 60, 41, 27, 12, -5, -15, -15, -14, -13, -8, -7, -17, -27, -23,
+ -3, 23, 44, 51, 43, 25, 12, 11, 14, 8, -3, -10, -15, -22, -28, -30,
+ -36, -55, -73, -78, -74, -71, -63, -51, -43, -39, -34, -25, -18, -9, 8, 28,
+ 46, 56, 61, 62, 58, 47, 36, 28, 20, 12, 11, 16, 19, 20, 21, 15,
+ 0, -6, 10, 37, 57, 63, 55, 36, 15, 2, -3, -9, -19, -27, -34, -43,
+ -49, -49, -52, -66, -82, -86, -81, -77, -71, -61, -51, -47, -43, -35, -22, -12,
+ 2, 24, 47, 58, 63, 67, 66, 58, 51, 45, 34, 18, 9, 7, 7, 7,
+ 8, 1, -14, -24, -12, 18, 47, 64, 68, 63, 53, 42, 37, 38, 36, 29,
+ 21, 16, 11, 5, -2, -17, -36, -49, -52, -56, -62, -63, -61, -61, -63, -60,
+ -56, -49, -37, -19, 2, 17, 25, 30, 34, 37, 37, 37, 34, 25, 15, 11,
+ 13, 14, 14, 8, -7, -21, -16, 9, 37, 53, 60, 61, 53, 40, 33, 34,
+ 32, 22, 14, 12, 10, 6, -2, -15, -32, -48, -57, -60, -63, -67, -66, -63,
+ -63, -65, -64, -58, -49, -34, -13, 6, 16, 21, 28, 34, 38, 41, 43, 36,
+ 25, 19, 21, 26, 27, 20, 4, -11, -11, 7, 31, 53, 66, 70, 66, 57,
+ 49, 47, 44, 33, 21, 17, 16, 10, 1, -9, -26, -46, -60, -67, -76, -84,
+ -84, -80, -78, -79, -78, -73, -65, -52, -32, -11, 4, 10, 17, 25, 32, 36,
+ 40, 37, 24, 13, 15, 23, 23, 11, -5, -19, -25, -16, 9, 38, 59, 70,
+ 72, 67, 63, 63, 60, 50, 39, 32, 28, 22, 14, 3, -14, -34, -53, -65,
+ -76, -87, -94, -93, -91, -94, -96, -93, -86, -76, -56, -30, -9, 4, 16, 29,
+ 40, 51, 63, 65, 52, 39, 39, 45, 42, 29, 11, -7, -22, -24, -8, 19,
+ 42, 54, 60, 63, 61, 58, 57, 53, 43, 36, 36, 34, 28, 21, 11, -5,
+ -24, -39, -52, -65, -75, -77, -75, -75, -78, -80, -78, -73, -61, -43, -23, -9,
+ 1, 10, 23, 39, 52, 56, 47, 36, 35, 41, 42, 33, 17, -2, -24, -35,
+ -26, -3, 18, 32, 42, 50, 52, 53, 52, 47, 38, 31, 30, 31, 29, 26,
+ 22, 14, -1, -18, -33, -46, -58, -65, -65, -65, -71, -79, -81, -79, -75, -62,
+ -42, -27, -21, -14, 1, 19, 34, 40, 36, 29, 27, 31, 38, 39, 29, 9,
+ -12, -27, -28, -14, 8, 25, 37, 50, 62, 67, 66, 62, 53, 42, 36, 37,
+ 36, 32, 30, 25, 12, -7, -24, -39, -54, -65, -67, -67, -72, -78, -81, -82,
+ -81, -70, -51, -35, -29, -23, -7, 15, 30, 37, 40, 35, 25, 25, 36, 41,
+ 33, 15, -6, -26, -36, -27, -9, 7, 20, 35, 50, 58, 59, 58, 52, 43,
+ 37, 37, 37, 36, 34, 31, 24, 8, -11, -29, -44, -57, -67, -70, -73, -79,
+ -86, -92, -93, -87, -72, -59, -53, -46, -29, -9, 7, 20, 28, 26, 19, 17,
+ 27, 38, 38, 26, 7, -12, -25, -26, -15, 1, 14, 28, 47, 61, 67, 68,
+ 68, 63, 54, 51, 53, 51, 49, 49, 47, 34, 14, -5, -22, -39, -56, -65,
+ -67, -73, -86, -96, -97, -92, -86, -77, -69, -61, -49, -28, -6, 10, 22, 27,
+ 25, 24, 33, 49, 56, 48, 32, 13, -5, -15, -12, -2, 7, 18, 35, 50,
+ 59, 63, 65, 61, 53, 48, 46, 44, 43, 46, 49, 43, 27, 10, -6, -25,
+ -45, -53, -53, -60, -75, -87, -90, -90, -88, -81, -75, -72, -65, -48, -25, -6,
+ 5, 10, 13, 18, 31, 49, 60, 58, 44, 28, 12, -1, -7, -7, -1, 8,
+ 23, 41, 54, 61, 65, 66, 63, 56, 48, 43, 41, 42, 44, 43, 37, 25,
+ 8, -12, -32, -44, -49, -53, -64, -80, -91, -95, -93, -89, -85, -82, -78, -68,
+ -50, -27, -6, 0, -1, 0, 0, 0, 1, 2, 3, 6, 9, 13, 17, 19,
+ 13, -4, -15, -10, 4, 19, 26, 15, -9, -16, 6, -2, -18, 38, 64, 21,
+ -48, 30, 82, -23, -63, -50, -26, -7, 12, 26, 47, 83, 100, 3, -108, -87,
+ -30, -6, 5, 18, 33, 46, 47, 21, -52, -46, 48, 3, -54, -32, 22, 25,
+ -7, 12, 9, -18, -33, -24, 2, 44, 88, 92, 10, -28, -1, 1, 20, 42,
+ 1, -17, 53, 72, 12, -16, -74, -31, 127, 52, 1, -35, -46, 13, 39, -13,
+ -13, 13, 12, 11, 8, -57, -80, -44, -5, 14, 18, 6, -13, -26, -11, -8,
+ -24, 3, 30, 14, -28, -12, 41, -2, -37, -35, -23, -12, -1, 6, 17, 34,
+ 53, 19, -55, -67, -32, -13, -5, 2, 12, 19, 24, 14, -24, -47, 12, 11,
+ -36, -35, -1, 18, -3, 0, 5, -13, -25, -22, -5, 19, 53, 69, 21, -28,
+ -10, -5, 6, 28, 8, -25, 23, 57, 17, -17, -49, -63, 84, 70, 3, -23,
+ -50, -6, 36, -2, -20, 8, 14, 9, 13, -37, -82, -58, -19, 8, 17, 10,
+ -9, -26, -19, -7, -24, -9, 25, 22, -17, -28, 33, 16, -32, -37, -27, -15,
+ -4, 4, 13, 27, 48, 35, -35, -72, -43, -17, -7, -1, 9, 16, 23, 17,
+ -12, -51, -7, 21, -27, -40, -12, 19, 6, -3, 5, -9, -22, -23, -8, 11,
+ 42, 68, 38, -23, -16, -6, 3, 25, 19, -24, 8, 54, 31, -13, -33, -76,
+ 46, 95, 13, -13, -48, -20, 32, 13, -22, 2, 15, 10, 15, -17, -77, -67,
+ -31, 3, 17, 15, -3, -21, -23, -7, -20, -18, 18, 27, -4, -34, 17, 33,
+ -21, -36, -29, -16, -6, 4, 11, 23, 42, 47, -12, -69, -54, -22, -8, -2,
+ 7, 15, 22, 20, -2, -46, -27, 23, -13, -41, -22, 15, 16, -2, 4, -5,
+ -18, -21, -10, 5, 32, 64, 53, -12, -21, -6, 0, 21, 27, -16, -6, 48,
+ 42, -6, -22, -71, 2, 106, 31, -6, -41, -32, 22, 25, -18, -4, 15, 12,
+ 14, -1, -64, -74, -42, -5, 16, 19, 4, -16, -25, -10, -14, -23, 9, 29,
+ 9, -31, -2, 42, -5, -33, -30, -18, -8, 3, 9, 19, 36, 51, 10, -58,
+ -63, -29, -11, -2, 4, 13, 20, 21, 6, -35, -44, 16, 1, -38, -30, 7,
+ 23, 3, 2, -2, -16, -20, -12, 2, 23, 56, 62, 3, -24, -7, -2, 17,
+ 30, -5, -17, 37, 49, 4, -17, -57, -37, 99, 55, 0, -31, -41, 9, 33,
+ -10, -11, 13, 14, 12, 9, -47, -78, -53, -15, 12, 20, 9, -10, -24, -14,
+ -11, -25, -2, 27, 18, -21, -20, 39, 13, -29, -31, -20, -9, 1, 8, 17,
+ 30, 49, 29, -41, -70, -39, -15, -4, 2, 11, 17, 21, 11, -22, -52, 0,
+ 14, -31, -36, -4, 25, 11, 1, -1, -13, -19, -13, 0, 15, 45, 65, 20,
+ -24, -10, -4, 12, 30, 8, -22, 24, 52, 17, -14, -39, -61, 71, 81, 8,
+ -21, -44, -5, 34, 2, -16, 9, 16, 11, 14, -29, -76, -62, -27, 6, 20,
+ 15, -4, -21, -19, -9, -23, -12, 22, 25, -8, -30, 26, 30, -20, -31, -23,
+ -11, -1, 8, 14, 25, 44, 42, -19, -69, -50, -20, -6, 1, 9, 15, 20,
+ 15, -11, -51, -19, 20, -20, -39, -15, 23, 20, 2, 0, -11, -17, -14, -2,
+ 9, 35, 63, 37, -19, -14, -5, 8, 28, 18, -22, 9, 50, 28, -11, -26,
+ -68, 32, 100, 22, -13, -43, -18, 30, 15, -17, 4, 16, 12, 15, -12, -69,
+ -69, -39, -2, 18, 19, 2, -17, -22, -10, -19, -20, 15, 27, 4, -31, 7,
+ 41, -7, -30, -25, -13, -3, 6, 12, 22, 38, 48, 3, -61, -60, -27, -9,
+ 0, 7, 13, 19, 17, -2, -44, -37, 18, -7, -39, -24, 15, 28, 7, 0,
+ -9, -16, -14, -3, 6, 25, 57, 49, -9, -18, -7, 3, 25, 26, -15, -4,
+ 45, 38, -5, -18, -61, -8, 103, 42, -6, -37, -30, 21, 25, -13, -3, 16,
+ 13, 14, 2, -56, -73, -49, -12, 15, 21, 8, -11, -23, -13, -15, -24, 4,
+ 28, 14, -25, -12, 42, 9, -26, -26, -15, -5, 5, 11, 19, 32, 48, 22,
+ -46, -67, -36, -12, -2, 4, 12, 17, 18, 4, -33, -50, 6, 6, -35, -31,
+ 4, 31, 14, 0, -8, -15, -14, -4, 4, 17, 48, 57, 4, -21, -8, -1,
+ 21, 30, -5, -15, 36, 44, 5, -14, -46, -40, 88, 67, 2, -29, -37, 9,
+ 31, -6, -9, 14, 15, 13, 11, -40, -74, -58, -24, 9, 22, 13, -6, -21,
+ -17, -13, -25, -6, 25, 21, -13, -25, 33, 26, -19, -27, -18, -6, 3, 10,
+ 16, 27, 45, 36, -26, -69, -46, -17, -4, 2, 10, 15, 18, 9, -22, -55,
+ -11, 15, -26, -36, -8, 30, 23, 2, -6, -14, -14, -6, 4, 11, 37, 59,
+ 19, -20, -10, -4, 16, 31, 7, -20, 23, 47, 15, -13, -32, -58, 58, 88,
+ 13, -21, -40, -5, 32, 4, -13, 10, 17, 12, 14, -23, -70, -65, -35, 1,
+ 20, 17, 0, -18, -20, -12, -23, -16, 19, 25, -1, -30, 16, 39, -8, -26,
+ -20, -8, 1, 9, 14, 23, 39, 44, -5, -63, -57, -24, -7, 1, 8, 13,
+ 17, 12, -12, -52, -30, 17, -15, -38, -18, 23, 32, 7, -6, -13, -14, -7,
+ 3, 8, 27, 55, 33, -16, -13, -6, 10, 30, 17, -20, 10, 46, 25, -9,
+ -21, -60, 19, 100, 31, -13, -39, -17, 27, 15, -13, 4, 17, 13, 15, -8,
+ -61, -69, -46, -10, 17, 21, 6, -13, -22, -13, -20, -22, 10, 27, 9, -27,
+ -4, 44, 6, -24, -22, -11, -1, 8, 13, 20, 33, 46, 14, -50, -65, -33,
+ -11, 0, 5, 12, 15, 14, -4, -43, -46, 10, -2, -36, -27, 13, 36, 15,
+ -4, -13, -14, -8, 3, 7, 18, 49, 43, -7, -16, -7, 5, 27, 24, -14,
+ -3, 42, 33, -3, -16, -51, -17, 97, 51, -3, -38, -5, -13, 1, -7, 5,
+ -22, -32, -35, -32, -43, -35, -55, -42, -66, -48, -80, -57, -17, -128, -59, -76,
+ 0, -26, 1, -33, 21, 3, 16, 15, 26, 43, 28, 66, 6, 97, 40, 103,
+ 67, 101, 102, 98, 94, 21, 98, 90, 57, 78, 89, 81, 61, -6, 54, 4,
+ 62, 19, 27, 34, 12, 16, 14, -17, 19, -5, -2, -13, -38, -24, -3, -33,
+ -14, -11, -16, 0, -13, 7, -26, -13, -16, 6, -57, -23, -28, -13, -9, -34,
+ -32, -20, -87, -62, -28, -38, -75, -37, -27, -41, -71, -48, -30, -44, -83, -67,
+ -52, -48, -45, -46, -45, -63, -47, -40, -32, -45, -24, -32, -43, -21, -17, 0,
+ 21, 26, 43, 51, 62, 47, 41, 55, 57, 68, 34, 53, 63, 62, 71, 60,
+ 61, 56, 53, 56, 54, 38, 50, 58, 50, 40, 28, 54, 39, 41, 38, 22,
+ 32, 20, -3, 19, -1, -7, -6, -16, -16, -14, -27, -29, -46, -66, -61, -51,
+ -54, -61, -41, -50, -47, -52, -55, -45, -44, -28, -58, -56, -31, -37, -36, -32,
+ -18, -16, -34, -29, -9, -21, -20, -30, -22, -17, -19, -8, -12, -14, -6, -14,
+ -6, -11, -2, 4, -6, 9, 8, 17, 23, 13, 31, 13, 24, 30, 28, 29,
+ 30, 43, 34, 37, 52, 42, 44, 50, 67, 59, 49, 54, 48, 43, 51, 45,
+ 42, 62, 47, 39, 37, 36, 24, 28, 13, 3, 9, -11, -3, -9, -14, -18,
+ -34, -27, -29, -39, -42, -38, -46, -37, -46, -43, -41, -35, -38, -31, -38, -34,
+ -39, -39, -34, -48, -44, -47, -49, -54, -52, -44, -53, -37, -47, -38, -31, -38,
+ -27, -19, -19, -15, -16, 0, 0, 2, 7, 13, 29, 22, 32, 32, 39, 47,
+ 41, 40, 55, 48, 41, 44, 57, 43, 36, 47, 43, 42, 37, 32, 32, 27,
+ 33, 36, 30, 23, 25, 25, 22, 18, 22, 20, 16, 8, 6, 12, 7, 0,
+ 1, 3, -5, -14, -9, -7, -8, -19, -15, -16, -23, -21, -21, -32, -31, -29,
+ -26, -27, -29, -33, -26, -29, -30, -39, -28, -41, -43, -35, -34, -32, -29, -28,
+ -28, -25, -27, -24, -27, -27, -27, -22, -23, -17, -9, -10, -14, -10, -8, -4,
+ -2, -1, -3, 5, 4, 10, 11, 7, 13, 11, 14, 27, 22, 22, 22, 27,
+ 36, 34, 36, 37, 45, 44, 47, 48, 51, 49, 52, 51, 52, 48, 50, 47,
+ 48, 42, 40, 29, 33, 24, 22, 12, 5, 0, -3, -5, -9, -21, -21, -25,
+ -19, -28, -28, -30, -33, -39, -42, -42, -46, -46, -45, -42, -43, -47, -47, -36,
+ -32, -30, -34, -31, -22, -29, -29, -30, -26, -28, -30, -21, -26, -27, -21, -19,
+ -16, -11, -12, -8, -2, 1, -4, 1, 0, 1, 9, 8, 7, 12, 10, 13,
+ 20, 17, 18, 21, 26, 29, 30, 30, 29, 34, 33, 34, 33, 30, 32, 33,
+ 28, 33, 29, 35, 32, 31, 30, 31, 30, 25, 27, 24, 21, 21, 20, 16,
+ 17, 12, 6, 4, -3, 1, -6, -7, -11, -13, -11, -10, -8, -13, -12, -9,
+ -17, -14, -19, -24, -22, -24, -30, -32, -30, -33, -37, -39, -40, -42, -39, -41,
+ -39, -40, -41, -35, -35, -35, -37, -36, -33, -30, -25, -25, -19, -16, -16, -10,
+ -6, -7, -4, -2, 1, 3, 6, 10, 9, 15, 17, 18, 17, 13, 19, 18,
+ 17, 19, 20, 24, 24, 27, 27, 29, 30, 26, 28, 28, 27, 28, 26, 25,
+ 24, 25, 20, 19, 17, 18, 15, 12, 13, 10, 6, 8, 6, 3, 4, 3,
+ 0, -3, 0, -1, -2, -5, -4, -5, -4, -5, -6, -8, -9, -9, -12, -11,
+ -16, -16, -15, -15, -13, -17, -16, -17, -17, -21, -20, -25, -24, -24, -24, -26,
+ -30, -30, -27, -30, -26, -26, -27, -27, -25, -24, -19, -20, -17, -13, -12, -8,
+ -8, -8, -6, -5, -2, -1, 0, 3, 8, 10, 12, 16, 18, 24, 25, 25,
+ 28, 30, 28, 32, 33, 31, 32, 31, 35, 33, 31, 31, 27, 28, 26, 23,
+ 23, 20, 22, 18, 16, 13, 11, 9, 5, 4, -2, -2, -3, -8, -9, -11,
+ -12, -13, -15, -15, -15, -15, -15, -14, -12, -12, -13, -13, -8, -11, -10, -12,
+ -10, -12, -12, -8, -8, -9, -9, -9, -8, -9, -10, -11, -11, -10, -13, -14,
+ -13, -16, -16, -17, -17, -18, -19, -18, -17, -16, -16, -15, -15, -13, -12, -10,
+ -12, -10, -9, -8, -6, -6, -3, 0, 0, 1, 2, 2, 3, 4, 4, 5,
+ 6, 7, 8, 9, 10, 11, 12, 12, 13, 14, 14, 15, 15, 15, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 15, 15, 14, 13, 13, 12, 11, 10,
+ 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, -1, -1, -2, -3, -4, -5,
+ -5, -6, -7, -7, -8, -9, -9, -10, -11, -11, -12, -12, -13, -13, -13, -13,
+ -14, -14, -14, -15, -15, -15, -15, -15, -15, -16, -16, -16, -15, -15, -15, -14,
+ -13, -13, -12, -11, -10, -9, -8, -7, -6, -5, -4, -2, -1, 0, 1, 2,
+ 4, 5, 6, 7, 8, 9, 10, 11, 12, 12, 13, 13, 14, 14, 15, 15,
+ 15, 15, 16, 16, 16, 16, 17, 17, 17, 17, 17, 17, 16, 16, 15, 15,
+ 14, 14, 13, 12, 11, 10, 9, 7, 6, 5, 3, 1, 0, -2, -4, -5,
+ -7, -9, -10, -11, -13, -14, -15, -15, -16, -17, -17, -18, -18, -18, -18, -18,
+ -18, -18, -18, -18, -18, -18, -18, -17, -17, -16, -16, -15, -14, -14, -13, -12,
+ -11, -10, -9, -8, -7, -6, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5,
+ 6, 7, 8, 9, 9, 10, 11, 11, 12, 13, 13, 13, 14, 14, 14, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 14, 14, 14, 13, 12, 12,
+ 11, 10, 9, 8, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0, -1, 0,
+ 0, -1, 2, 1, 0, 1, 4, 2, 2, 2, 5, 2, 5, 5, 8, 4,
+ 13, 15, 19, -62, -65, 56, -18, -128, -39, 15, -57, -10, 19, -22, -11, 36,
+ 30, 5, 19, 25, 17, 21, 21, 16, 21, 18, 17, 17, 15, 14, 13, 12,
+ 10, 6, 8, 6, 6, -1, 1, -4, 7, -10, -36, 35, 64, -25, -18, 83,
+ 50, 22, 39, 21, 19, -4, -20, 28, 0, -88, -55, -5, -55, -83, -64, -58,
+ -77, -61, -22, -39, -57, -15, 2, -14, -9, -1, 1, 1, 2, 9, 5, 6,
+ 11, 9, 9, 10, 11, 12, 12, 10, 9, 9, 13, 7, 3, 14, 4, -3,
+ 2, 2, 17, 40, 12, 14, 55, 58, 44, 39, 38, 37, 6, 4, 31, -6,
+ -50, -25, -15, -49, -52, -41, -60, -68, -32, -25, -47, -36, -9, -5, -7, -3,
+ 3, 4, 6, 8, 11, 9, 10, 14, 14, 11, 13, 15, 14, 13, 14, 12,
+ 11, 12, 12, 8, 8, 3, 4, 5, -1, 8, 32, 21, 14, 43, 50, 39,
+ 47, 39, 20, 23, 16, 5, -9, -23, -26, -34, -48, -37, -48, -71, -56, -34,
+ -43, -49, -36, -20, -14, -13, -9, -4, -1, 1, 3, 6, 6, 6, 9, 10,
+ 8, 10, 11, 11, 11, 11, 10, 10, 10, 10, 6, 6, 4, 3, 6, -3,
+ 2, 25, 23, 16, 34, 38, 43, 51, 31, 19, 38, 22, -10, -7, 0, -25,
+ -45, -34, -32, -54, -62, -47, -39, -45, -47, -36, -24, -19, -16, -11, -6, -3,
+ 0, 2, 4, 6, 7, 8, 10, 11, 9, 11, 12, 11, 11, 12, 11, 10,
+ 10, 8, 7, 6, 3, 5, 4, 0, 13, 28, 23, 19, 36, 50, 42, 30,
+ 31, 39, 24, -6, -2, 7, -21, -40, -27, -34, -51, -51, -44, -42, -45, -45,
+ -37, -27, -22, -18, -13, -9, -6, -2, 1, 2, 5, 7, 7, 9, 11, 10,
+ 10, 12, 12, 11, 12, 11, 10, 10, 9, 7, 7, 4, 5, 7, 1, 7,
+ 27, 24, 15, 34, 47, 37, 32, 36, 36, 26, 4, -1, 4, -13, -30, -27,
+ -34, -47, -46, -42, -43, -45, -44, -38, -31, -25, -21, -17, -12, -8, -5, -1,
+ 1, 3, 5, 6, 8, 9, 10, 10, 10, 11, 11, 11, 11, 11, 10, 9,
+ 7, 7, 6, 3, 6, 5, 6, 17, 23, 19, 29, 40, 35, 33, 36, 34,
+ 26, 14, 3, 0, -6, -18, -26, -32, -39, -40, -38, -39, -41, -40, -36, -31,
+ -27, -23, -19, -15, -12, -8, -4, -2, 0, 3, 4, 5, 7, 8, 9, 9,
+ 9, 10, 10, 10, 10, 10, 9, 8, 8, 8, 7, 8, 10, 11, 14, 19,
+ 22, 25, 28, 29, 29, 29, 27, 21, 14, 7, -1, -5, -11, -19, -26, -29,
+ -31, -32, -33, -34, -33, -32, -29, -26, -24, -21, -18, -15, -12, -9, -6, -4,
+ -2, 0, 2, 3, 5, 6, 7, 7, 8, 8, 9, 9, 9, 9, 9, 9,
+ 10, 10, 11, 12, 14, 16, 18, 20, 22, 23, 24, 24, 23, 20, 17, 12,
+ 7, 2, -3, -8, -13, -17, -21, -23, -25, -26, -27, -27, -27, -26, -25, -23,
+ -21, -19, -17, -14, -12, -9, -7, -5, -3, -1, 1, 2, 4, 5, 6, 6,
+ 7, 7, 8, 8, 9, 9, 10, 10, 11, 12, 13, 15, 16, 18, 19, 21,
+ 22, 22, 22, 21, 19, 17, 13, 9, 4, 0, -5, -10, -14, -18, -21, -23,
+ -25, -26, -26, -26, -26, -25, -23, -22, -20, -18, -15, -13, -11, -9, -6, -4,
+ -2, 0, 1, 3, 4, 5, 6, 7, 7, 8, 8, 8, 9, 9, 10, 11,
+ 12, 13, 14, 15, 17, 18, 20, 21, 21, 21, 21, 19, 17, 14, 11, 7,
+ 2, -3, -7, -11, -15, -19, -21, -23, -25, -25, -26, -25, -25, -24, -22, -21,
+ -19, -17, -15, -12, -10, -8, -6, -4, -2, 0, 1, 3, 4, 5, 6, 6,
+ 7, 8, 8, 9, 9, 10, 11, 11, 12, 13, 15, 16, 17, 19, 20, 20,
+ 21, 20, 19, 18, 15, 12, 8, 4, 0, -4, -9, -13, -16, -19, -21, -23,
+ -24, -25, -25, -25, -24, -23, -21, -20, -18, -16, -14, -12, -9, -7, -5, -3,
+ -2, 0, 1, 3, 4, 5, 6, 6, 7, 8, 8, 9, 10, 10, 11, 12,
+ 13, 14, 15, 17, 18, 19, 20, 20, 20, 19, 18, 16, 13, 10, 6, 2,
+ -2, -6, -10, -13, -16, -19, -21, -23, -24, -24, -24, -24, -23, -22, -20, -19,
+ -17, -15, -13, -11, -8, -6, -5, -3, -1, 0, 2, 3, 4, 5, 6, 7,
+ 7, 8, 9, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 19, 20,
+ 19, 18, 16, 14, 11, 8, 4, 0, -3, -7, -11, -14, -17, -19, -21, -22,
+ -23, -23, -23, -23, -22, -21, -19, -18, -16, -14, -12, -10, -8, -6, -4, -2,
+ -1, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 10, 11, 12, 12, 13,
+ 14, 15, 16, 17, 18, 19, 19, 19, 18, 17, 15, 12, 9, 6, 3, -1,
+ -5, -9, -12, -15, -17, -19, -21, -22, -23, -23, -23, -22, -21, -20, -18, -17,
+ -15, -13, -11, -9, -7, -6, -4, -2, -1, 1, 2, 3, 4, 5, 6, 7,
+ 8, 9, 9, 10, 11, 12, 13, 14, 15, 16, 17, 17, 18, 18, 18, 17,
+ 16, 14, 12, 10, 7, 4, 0, -3, -6, -9, -12, -15, -17, -18, -20, -20,
+ -21, -21, -21, -20, -19, -18, -17, -15, -14, -12, -10, -9, -7, -5, -4, -2,
+ -1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 14,
+ 15, 15, 16, 16, 16, 16, 16, 15, 14, 12, 11, 8, 6, 3, 0, -3,
+ -6, -9, -12, 1, -1, 2, -1, 4, 2, 8, 5, 10, -5, 0, 5, 17,
+ -11, 0, 19, -17, 26, 65, 15, 29, 3, 35, 67, 50, 88, 59, 117, 28,
+ -6, -16, 29, 63, 62, -40, 59, 22, -95, -49, -55, 19, 36, -15, 26, -117,
+ 60, 8, -101, -115, 23, 60, -32, -106, -84, -88, -127, -99, -117, -110, -56, -42,
+ -53, -79, -44, 43, 10, -11, 72, 22, 61, 10, -92, -106, -111, -35, -68, -128,
+ -67, -36, -118, -97, -96, -4, 75, 70, 113, 36, 73, 115, 37, 6, 79, 97,
+ 89, -8, -38, -8, -72, -8, -29, -35, 73, 98, 66, 12, 40, 113, 106, 87,
+ 126, 112, 127, 87, -3, -21, -23, 40, 14, -68, -20, 21, -57, -67, -67, -4,
+ 69, 53, 90, 17, 36, 78, -7, -54, -2, 32, 21, -71, -109, -89, -124, -103,
+ -114, -113, -37, -4, -30, -88, -83, 15, 13, -35, 42, 28, 33, 14, -90, -92,
+ -104, -37, -34, -115, -73, -9, -75, -89, -85, -29, 67, 51, 97, 55, 47, 115,
+ 46, -9, 42, 90, 96, 26, -36, 11, -43, -25, -6, -37, 59, 104, 88, 31,
+ 22, 96, 116, 69, 110, 119, 119, 109, 11, -15, -26, 18, 37, -45, -32, 34,
+ -13, -62, -62, -30, 61, 47, 75, 46, 14, 72, 14, -58, -35, 16, 30, -38,
+ -109, -78, -109, -116, -102, -123, -57, -2, -11, -58, -95, -18, 22, -41, -3, 36,
+ 20, 31, -69, -94, -100, -72, -21, -91, -92, -9, -33, -82, -81, -57, 48, 52,
+ 70, 81, 35, 97, 69, -10, 8, 66, 94, 55, -27, 4, -5, -40, -1, -33,
+ 30, 102, 101, 61, 19, 70, 121, 72, 77, 123, 112, 121, 36, -13, -21, -10,
+ 38, -18, -43, 27, 25, -40, -59, -45, 40, 54, 52, 68, 15, 56, 35, -48,
+ -58, -12, 25, -10, -98, -84, -83, -122, -101, -123, -81, -8, -3, -28, -85, -47,
+ 20, -28, -39, 23, 18, 31, -38, -99, -92, -97, -35, -66, -102, -26, -3, -60,
+ -77, -69, 18, 59, 47, 87, 46, 73, 86, 3, -13, 34, 80, 70, -8, -12,
+ 19, -32, -12, -21, 3, 91, 105, 87, 34, 51, 114, 89, 53, 106, 115, 119,
+ 65, -10, -13, -25, 20, 4, -45, 9, 44, -8, -49, -51, 14, 61, 39, 68,
+ 34, 39, 51, -30, -67, -41, 7, 5, -76, -96, -65, -111, -110, -115, -103, -20,
+ -1, -9, -58, -65, 8, -9, -55, -6, 17, 24, -11, -94, -89, -102, -64, -50,
+ -101, -51, 6, -30, -66, -71, -12, 59, 40, 72, 67, 58, 91, 24, -21, 6,
+ 56, 74, 14, -22, 23, -8, -24, -14, -13, 71, 106, 101, 62, 42, 101, 105,
+ 49, 76, 114, 114, 87, 3, -12, -23, -6, 13, -37, -11, 45, 24, -29, -49,
+ -8, 57, 40, 53, 54, 32, 56, -6, -65, -61, -21, 6, -52, -101, -65, -85,
+ -115, -109, -116, -42, 0, -1, -27, -65, -12, 7, -51, -37, 7, 17, 6, -76,
+ -95, -94, -91, -52, -90, -76, -2, -4, -46, -66, -35, 46, 46, 49, 78, 57,
+ 85, 50, -17, -13, 26, 64, 34, -22, 9, 18, -22, -14, -18, 42, 103, 105,
+ 88, 50, 83, 114, 63, 49, 96, 110, 99, 26, -14, -15, -23, 6, -24, -29,
+ 33, 45, 0, -38, -23, 44, 50, 37, 60, 38, 52, 21, -54, -70, -48, -7,
+ -31, -95, -78, -63, -104, -108, -117, -69, -4, -1, -5, -47, -30, 13, -33, -58,
+ -14, 8, 11, -50, -99, -87, -101, -70, -77, -92, -22, 10, -22, -52, -46, 23,
+ 55, 36, 70, 66, 74, 69, -2, -23, 1, 43, 43, -11, -8, 29, -4, -17,
+ -16, 18, 91, 105, 102, 71, 72, 112, 83, 40, 70, 101, 102, 50, -10, -10,
+ -24, -10, -13, -36, 14, 52, 27, -18, -28, 26, 58, 33, 51, 49, 46, 40,
+ -34, -70, -66, -31, -22, -81, -92, -56, -83, -105, -112, -91, -17, 0, 2, -22,
+ -37, 7, -12, -61, -39, -5, 7, -27, -93, -90, -96, -90, -72, -95, -48, 9,
+ -1, -33, -46, 0, 55, 37, 50, 72, 68, 77, 20, -25, -15, 17, 40, 3,
+ -20, 22, 19, -12, -14, 2, 70, 105, 106, 92, 72, 104, 100, 48, 46, 83,
+ 98, 70, 3, -12, -16, -23, -11, -34, -8, 46, 47, 11, -21, 8, 57, 41,
+ 36, 53, 45, 48, -6, -64, -72, -57, -28, -61, -98, -65, -60, -94, -105, -103,
+ -41, 1, 0, -1, -29, -6, 5, -48, -60, -26, -3, -12, -74, -97, -86, -100,
+ -80, -89, -74, -6, 13, -10, -35, -18, 41, 48, 33, 64, 68, 75, 46, -15,
+ -25, -7, 24, 16, -20, 4, 33, 5, -11, -5, 43, 98, 105, 105, 85, 93,
+ 110, 67, 35, 59, 87, 81, 25, -13, -9, -23, -18, -27, -25, 30, 55, 37,
+ -1, -3, 46, 53, 29, 44, 47, 48, 20, -48, -72, -72, -47, -48, -93, -82,
+ -51, -73, -96, -102, -66, -6, 0, 5, -10, -16, 10, -26, -66, -49, -20, -10,
+ -51, -98, -86, -93, -93, -85, -88, -32, 14, 8, -16, -23, 22, 54, 32, 45,
+ 67, 70, 61, 4, -27, -21, 2, 17, -13, -13, 29, 26, -1, -5, 23, 83,
+ 104, 106, 100, 90, 110, 87, 40, 38, 68, 80, 45, -6, -9, -14, -24, -23,
+ -32, 8, 52, 53, 25, 1, 31, 60, 35, 30, 45, 45, 36, -24, -68, -76,
+ -67, -49, -80, -94, -57, -54, -81, -95, -82, -23, 2, 1, 4, -12, 4, -5,
+ -57, -65, -40, -20, -36, -87, -94, -83, -97, -87, -90, -57, 2, 18, 2, -12,
+ 8, 10, -20, 30, 25, 21, 14, 4, 15, -48, -33, 11, -70, 54, -5, -21,
+ -8, -3, 73, -52, 65, -55, 80, -28, -67, -3, -13, 21, -49, -2, 11, 36,
+ 59, -60, 34, -28, 21, -25, -45, 54, 5, 0, -19, -12, 20, 54, -51, -23,
+ 22, 36, -59, -20, 8, 28, -9, -54, 127, -44, 69, -128, 5, 69, -8, -98,
+ 45, 69, 20, -97, 23, -7, 121, -81, -2, -21, 51, -67, -14, -24, 127, -60,
+ 45, -116, 127, -29, -93, -23, 107, -5, -21, -62, 37, 41, 29, -74, -63, 103,
+ 24, -59, -44, 62, 43, -28, -46, 7, 72, 19, -70, -47, 42, 53, -68, -13,
+ 37, 59, -38, -60, 39, 66, 27, -128, 36, 77, 15, -74, -15, 75, 38, -49,
+ -11, -39, 16, -8, -30, 35, 41, -1, -2, 17, -68, 99, -97, 60, -49, 32,
+ -44, -29, 82, -26, 39, -35, 10, 38, -20, -21, -92, 83, -24, 13, 31, -33,
+ 22, 45, -31, -24, 9, -24, -32, 42, -17, 34, 7, -27, 6, 61, -9, -34,
+ -5, -8, -17, -6, -34, 17, 43, -9, 35, -34, 16, 27, -24, -17, -17, 5,
+ -17, 42, -31, 22, 17, -26, -22, 32, 41, -27, -25, -10, -5, 16, -2, 13,
+ -1, 48, -33, -27, 6, 16, 13, -37, -11, 18, 25, -42, -11, 46, -7, -15,
+ 9, 15, 4, -3, -36, -24, 31, -8, 14, 12, 27, -19, -17, -14, -7, 42,
+ -5, -15, 5, 1, -15, 14, 43, -19, 1, -25, -35, 16, 16, 29, -12, 8,
+ -14, 1, 21, -8, -12, -22, -4, 24, 26, -16, -22, 37, 3, -41, 7, 4,
+ 3, 30, 4, -27, 11, -6, -26, 33, 23, -23, -14, -20, -7, -4, 36, 0,
+ 18, 10, -27, 1, 1, 16, -1, -4, -44, -5, 17, 9, 13, -4, -3, 31,
+ 24, -14, -26, 9, -27, -28, 19, 22, 32, -11, -15, 5, 15, -23, -21, 16,
+ 14, 18, -11, -26, 13, 10, -12, -12, 11, 14, -6, -13, -3, 6, -6, 3,
+ 12, 32, 14, -22, -45, -10, 37, 11, -50, -11, 50, 22, -13, -4, -4, 15,
+ -16, -33, 7, 34, -9, -14, -1, 21, 15, -14, -12, -6, 7, 8, 2, 0,
+ -5, 6, 15, 4, -9, 13, 3, -51, -18, 27, 10, 5, -11, 6, -1, 5,
+ 22, 2, -14, -39, -12, 19, 17, 4, 11, 5, -25, 2, 23, 8, 2, -3,
+ -39, -22, 4, 18, 6, 14, 25, 20, -17, -20, 17, 7, -43, -38, -18, 17,
+ 24, -6, 30, 44, 6, -36, -20, 7, 24, 1, -69, -25, 47, 15, -4, 35,
+ 19, -18, -22, -12, 20, 39, -36, -49, 9, 28, -16, 9, 34, 36, -22, -69,
+ -16, 39, 7, -28, -3, 33, -18, -7, 18, 53, 24, -37, -61, -10, 38, 2,
+ -24, -11, 12, 17, 0, 28, 50, -5, -59, -57, 22, 14, -15, -5, 22, 9,
+ -20, 19, 33, 31, -33, -62, -13, -2, 45, -9, -4, -3, 19, 8, -8, 40,
+ 8, -16, -44, -19, 16, 3, 23, -32, 22, 5, -9, 5, 26, 21, -27, -18,
+ -45, 3, 15, 0, 7, 7, 7, 13, 18, -10, 3, -5, -30, -30, -3, 9,
+ 31, 17, -10, 19, 28, -33, -20, 31, 14, -67, -27, 13, 20, 29, 1, -2,
+ 24, -3, -26, -12, 32, -7, -31, -17, 5, 22, 11, -6, 6, 7, 2, 7,
+ 5, -12, -22, -17, -24, 22, 47, 1, 2, 10, 5, -29, -5, 13, 1, -30,
+ -28, -5, 23, 25, 6, 5, 1, 7, 0, 5, 3, -33, -37, -6, 19, 20,
+ 26, -1, -15, 21, 9, -14, -13, 0, -11, -24, -9, 9, 23, 1, 1, 32,
+ 11, -25, -18, 5, -5, -6, -9, -10, 2, 18, 4, 12, 6, -2, -8, 2,
+ 2, -7, 2, -22, -5, 17, 25, 15, -5, -1, -24, -8, -10, -5, 12, 7,
+ -4, -10, 4, 8, 22, 11, -1, -12, -31, -17, 6, 12, 11, 5, -3, -1,
+ 22, 0, -4, 3, -18, -17, -3, 16, 9, 2, -5, 0, 4, -9, 18, 17,
+ -22, -19, -8, -6, 21, 11, -6, -16, 33, 13, -15, -3, -15, 1, -3, -10,
+ -7, 8, 17, -11, 9, 19, 0, 5, 0, -18, -13, 2, -20, 10, 29, -11,
+ -13, 5, 11, 16, 4, -25, -21, 13, -5, 1, 3, -1, 6, 13, -7, -1,
+ 17, -6, -6, -9, -6, -3, -1, 1, 18, 11, -22, 2, 18, -2, -15, 1,
+ 5, -12, -10, -7, 9, 26, 10, -11, 5, 0, -7, -3, -11, -9, -3, 2,
+ -10, 19, 28, -3, -3, -4, 9, -14, -5, -7, 8, -3, -27, 5, 37, 11,
+ -2, 3, -27, -15, 12, -2, 14, 2, -8, -16, 22, 11, -1, 10, -17, -8,
+ -5, -23, 2, 29, 8, -21, 8, 12, 6, 8, -17, 3, -2, -12, -27, 16,
+ 25, -5, -7, 2, 19, 1, -15, 7, 2, -5, -34, 2, 18, 17, -10, 2,
+ 18, -1, -12, -10, 5, 1, -16, -9, 12, 21, 4, -10, 2, 12, 1, -19,
+ -11, 20, 5, -14, -21, 5, 17, -5, 3, 17, 4, -25, -5, 5, 4, 0,
+ -5, 2, 2, -1, 1, 13, 0, -11, -8, 3, 2, -1, -3, -3, 11, 8,
+ -6, 2, 7, 4, -5, -23, -2, 14, -1, -15, -2, 15, 10, 1, -4, 16,
+ 1, -24, -12, 8, 8, -20, -2, 14, 13, 10, 2, 2, -9, -6, -9, -3,
+ 5, 7, -3, -9, 0, 2, 8, 3, -1, 2, -4, 0, -1, -1, -1, -2,
+ -8, -14, -19, -28, -51, -53, -49, -48, -49, -44, -37, -30, -23, -14, -8, -11,
+ -5, 3, 11, 2, 0, 8, 19, 10, 1, 6, 18, 15, 4, 4, 17, 19,
+ 13, 9, 20, 27, 26, 26, 33, 42, 45, 53, 59, 68, 69, 83, 89, 92,
+ 85, 88, 91, 80, 56, 37, 29, 9, -25, -54, -65, -74, -94, -113, -112, -103,
+ -101, -103, -93, -79, -66, -62, -50, -41, -33, -27, -17, -11, -12, -8, 0, 7,
+ -1, -2, 5, 15, 8, -1, 3, 15, 13, 2, 2, 12, 17, 12, 8, 15,
+ 23, 24, 25, 29, 38, 42, 50, 56, 65, 68, 78, 87, 91, 87, 87, 91,
+ 84, 64, 43, 33, 16, -14, -44, -60, -70, -87, -107, -111, -105, -101, -103, -96,
+ -84, -70, -64, -55, -45, -36, -30, -22, -14, -14, -11, -4, 4, 0, -3, 1,
+ 11, 8, -1, 0, 10, 12, 3, 0, 9, 15, 11, 7, 14, 22, 23, 24,
+ 28, 37, 42, 49, 55, 64, 67, 78, 87, 91, 88, 88, 93, 86, 67, 47,
+ 36, 20, -10, -40, -56, -67, -84, -104, -109, -105, -101, -103, -96, -85, -71, -65,
+ -56, -46, -38, -31, -23, -16, -15, -12, -6, 2, -1, -5, 0, 9, 6, -1,
+ -1, 8, 11, 3, 0, 8, 14, 11, 7, 13, 21, 23, 23, 27, 37, 41,
+ 48, 54, 63, 67, 77, 86, 91, 89, 89, 93, 87, 70, 51, 39, 23, -6,
+ -36, -53, -64, -81, -101, -107, -103, -100, -102, -96, -85, -72, -66, -57, -47, -39,
+ -32, -25, -17, -16, -13, -7, 0, -3, -5, -1, 7, 6, -2, -2, 7, 9,
+ 2, -1, 7, 13, 10, 7, 12, 20, 22, 23, 27, 36, 41, 48, 54, 63,
+ 68, 77, 87, 91, 91, 91, 95, 89, 73, 54, 43, 27, -1, -31, -49, -61,
+ -78, -98, -105, -102, -99, -101, -96, -85, -73, -66, -58, -48, -40, -33, -26, -19,
+ -17, -14, -9, -2, -4, -6, -3, 5, 4, -3, -3, 5, 8, 1, -1, 6,
+ 12, 10, 7, 11, 20, 22, 23, 27, 35, 41, 47, 54, 62, 68, 76, 86,
+ 91, 91, 92, 96, 91, 76, 58, 46, 30, 3, -27, -45, -57, -75, -94, -103,
+ -100, -98, -100, -96, -85, -74, -67, -59, -49, -41, -34, -28, -20, -19, -15, -10,
+ -3, -5, -7, -4, 3, 3, -4, -4, 4, 7, 1, -2, 5, 11, 9, 6,
+ 11, 19, 21, 22, 26, 35, 40, 46, 53, 61, 67, 76, 86, 91, 92, 93,
+ 97, 93, 78, 61, 49, 33, 7, -22, -41, -54, -72, -91, -100, -99, -97, -100,
+ -96, -86, -74, -67, -60, -51, -42, -35, -29, -22, -20, -17, -11, -5, -6, -8,
+ -5, 2, 1, -5, -5, 2, 5, 0, -3, 3, 10, 8, 5, 10, 18, 21,
+ 21, 25, 34, 39, 45, 52, 61, 67, 75, 85, 91, 92, 94, 97, 94, 81,
+ 64, 52, 37, 11, -18, -37, -51, -69, -88, -98, -98, -96, -99, -95, -86, -75,
+ -68, -61, -52, -44, -36, -30, -23, -21, -17, -13, -6, -7, -9, -6, 0, 0,
+ -5, -5, 1, 4, -1, -3, 2, 8, 8, 5, 10, 17, 20, 21, 25, 33,
+ 39, 45, 51, 60, 66, 75, 85, 91, 93, 94, 98, 95, 83, 67, 55, 40,
+ 15, -14, -33, -48, -66, -85, -96, -96, -95, -98, -95, -86, -75, -69, -62, -53,
+ -45, -38, -32, -25, -22, -19, -14, -8, -9, -10, -8, -2, -1, -6, -7, -1,
+ 2, -2, -4, 1, 7, 6, 5, 8, 16, 19, 20, 24, 32, 38, 44, 50,
+ 59, 66, 74, 84, 91, 93, 95, 99, 97, 85, 70, 58, 43, 18, -10, -30,
+ -45, -63, -82, -93, -95, -94, -97, -95, -87, -76, -70, -63, -54, -46, -39, -33,
+ -26, -23, -20, -16, -10, -10, -12, -9, -3, -3, -7, -8, -2, 1, -2, -5,
+ 0, 6, 6, 4, 8, 15, 18, 20, 23, 31, 37, 43, 50, 58, 65, 74,
+ 83, 91, 93, 96, 100, 98, 87, 72, 61, 46, 22, -6, -27, -42, -60, -79,
+ -91, -94, -93, -97, -95, -87, -77, -70, -64, -55, -47, -40, -34, -28, -25, -22,
+ -17, -12, -11, -13, -11, -5, -4, -8, -9, -3, 0, -4, -6, -1, 5, 5,
+ 3, 7, 14, 18, 19, 23, 30, 36, 42, 49, 57, 65, 73, 83, 90, 94,
+ 96, 100, 99, 89, 75, 63, 49, 25, -2, -23, -38, -56, -76, -88, -92, -92,
+ -95, -94, -87, -77, -71, -65, -57, -48, -41, -36, -29, -26, -23, -19, -13, -12,
+ -14, -12, -7, -6, -9, -10, -5, -1, -4, -7, -2, 2, 5, 4, 6, 12,
+ 18, 20, 24, 30, 38, 45, 52, 61, 70, 79, 89, 99, 106, 109, 113, 115,
+ 109, 96, 81, 66, 44, 16, -12, -32, -52, -74, -92, -101, -104, -107, -108, -103,
+ -94, -85, -78, -70, -60, -52, -45, -38, -33, -29, -25, -19, -16, -17, -16, -12,
+ -9, -10, -12, -9, -5, -5, -7, -5, 0, 3, 3, 5, 11, 17, 20, 23,
+ 29, 37, 44, 51, 59, 69, 78, 88, 98, 105, 110, 114, 116, 110, 98, 84,
+ 69, 48, 20, -7, -29, -49, -71, -89, -99, -102, -105, -107, -103, -94, -86, -79,
+ -71, -62, -54, -47, -40, -34, -30, -26, -21, -18, -18, -17, -14, -10, -12, -14,
+ -11, -5, -10, 43, -94, 44, -13, 27, -98, 1, 9, 77, 63, 4, 8, -128,
+ 63, -73, 78, -116, 127, -14, 111, -87, -67, -43, -45, 38, 53, 99, -37, 14,
+ -51, -58, -23, -32, 34, 27, 75, 9, 51, -104, -71, -33, 27, 67, 0, -1,
+ 25, 0, -35, 1, -70, 28, -4, 109, 3, 5, -42, -7, 42, -15, 37, -62,
+ 67, -14, 48, -85, -46, -94, 37, 35, 23, 15, -79, 35, -50, 91, -64, 40,
+ -69, 46, 20, 43, -21, -51, 8, -1, 95, -47, 69, -104, 98, -44, 74, -61,
+ -14, -19, 7, 52, -40, 8, -89, 58, -53, 106, -106, 42, -82, 61, -1, -8,
+ -10, -59, 53, -18, 85, -83, 63, -73, 89, -32, 50, -62, 10, 13, 20, 62,
+ -81, 41, -84, 88, -32, 41, -78, 27, -30, 51, -6, -42, 6, -49, 74, -41,
+ 41, -89, 27, -33, 57, 0, -16, -8, -4, 45, 8, 20, -63, 36, -29, 75,
+ -23, -17, -23, -14, 45, -7, 17, -56, 20, -12, 45, -16, -13, -31, 6, 31,
+ -7, 17, -81, 40, -35, 73, -34, 0, -31, 10, 35, -4, 19, -60, 44, -30,
+ 83, -66, 41, -87, 59, -6, 23, -4, -59, 34, -33, 77, -70, 49, -89, 88,
+ -45, 63, -62, 4, -20, 18, 46, -49, 45, -101, 91, -56, 78, -79, 35, -51,
+ 67, -12, -2, -14, -49, 66, -35, 72, -87, 51, -74, 83, -38, 29, -36, -10,
+ 23, 3, 30, -59, 27, -59, 91, -44, 41, -63, 12, 2, 23, 8, -36, 14,
+ -35, 66, -38, 32, -59, 25, -11, 40, -6, -25, -2, -24, 55, -25, 29, -58,
+ 30, -17, 41, -18, -17, -3, -13, 50, -25, 26, -63, 35, -23, 50, -22, -5,
+ -18, 0, 33, -19, 22, -67, 57, -39, 63, -45, 6, -27, 13, 23, -6, 15,
+ -55, 44, -42, 70, -59, 36, -60, 56, -13, 15, -9, -50, 49, -38, 72, -63,
+ 37, -65, 67, -48, 55, -51, 10, 2, -5, 45, -61, 46, -83, 91, -58, 72,
+ -69, 23, -27, 35, -8, -3, -2, -33, 66, -61, 79, -100, 67, -60, 66, -26,
+ 13, -21, -13, 23, -11, 29, -49, 40, -53, 80, -67, 52, -63, 28, 6, -1,
+ 23, -45, 25, -30, 42, -25, 22, -42, 33, -26, 39, -26, -9, 10, -28, 61,
+ -50, 33, -43, 18, 2, 6, 4, -18, 4, -8, 24, -21, 22, -49, 50, -40,
+ 52, -35, -10, 17, -34, 64, -53, 38, -47, 37, -28, 40, -47, 33, -32, 28,
+ 3, -20, 30, -69, 79, -75, 88, -72, 39, -34, 22, -7, 9, -18, 1, 19,
+ -27, 58, -89, 81, -90, 89, -58, 42, -27, -5, 16, -21, 29, -34, 28, -37,
+ 59, -65, 72, -90, 69, -45, 31, 6, -36, 40, -53, 56, -47, 39, -42, 40,
+ -38, 50, -52, 34, -31, 7, 32, -47, 62, -79, 66, -51, 41, -27, 12, -10,
+ 12, -5, 3, -5, -18, 33, -44, 70, -75, 60, -52, 27, 4, -19, 22, -29,
+ 27, -15, 18, -31, 26, -36, 50, -41, 35, -31, 3, 19, -37, 55, -62, 51,
+ -38, 25, -11, 1, -13, 12, -7, 13, 4, -33, 38, -56, 72, -64, 52, -43,
+ 20, 6, -20, 25, -40, 34, -25, 38, -41, 43, -68, 68, -59, 53, -28, -7,
+ 27, -45, 63, -70, 56, -60, 59, -41, 48, -56, 39, -43, 35, -3, -19, 40,
+ -70, 85, -81, 76, -75, 48, -36, 41, -20, 12, -23, 0, 16, -23, 51, -76,
+ 78, -82, 80, -57, 29, -23, 3, 14, -2, 9, -29, 17, -31, 55, -51, 53,
+ -66, 49, -27, 17, 3, -35, 36, -33, 44, -27, 11, -30, 24, -18, 37, -29,
+ 4, -3, -15, 45, -47, 42, -57, 46, -19, 18, -11, -20, 10, -3, 24, -18,
+ 14, -46, 52, -50, 64, -57, 25, -14, 1, 33, -42, 30, -52, 50, -28, 47,
+ -54, 32, -49, 53, -25, 14, -4, -34, 57, -54, 69, -78, 46, -45, 52, -21,
+ 21, -37, 7, 1, 3, 29, -57, 56, -74, 90, -66, 47, -51, 16, 6, 10,
+ 10, -29, 9, -32, 58, -47, 59, -84, 65, -49, 52, -24, -18, 14, -30, 61,
+ -39, 31, -57, 39, -38, 67, -56, 37, -46, 26, 10, -15, 18, -49, 45, -27,
+ 42, -37, 11, -24, 30, -15, 21, -34, 15, -5, 11, 5, -24, 11, -16, 30,
+ -16, 6, -20, 7, 3, 11, -9, -5, -6, 4, 16, -15, 9, -29, 22, -6,
+ 14, -6, -16, 9, -12, 28, -22, 15, -27, 22, -11, 21, -23, 5, -10, 8,
+ 17, -22, 19, -42, 41, -31, 39, -37, 20, -20, 19, -3, -7, 2, -17, 27,
+ -20, 30, -43, 30, -34, 38, -24, 13, -13, -1, 16, -16, 19, -36, 28, -21,
+ 30, -22, 7, -17, 11, 2, 1, 1, -19, 22, -21, 32, -34, 18, -21, 17,
+ 6, -8, 5, -25, 21, -13, 24, -24, 12, -22, 24, -11, 10, -14, -7, 15,
+ -11, 28, -36, 21, -30, 30, -10, 10, -13, -5, 6, -2, 14, -22, 15, -25,
+ 33, -22, 23, -31, 11, -6, 8, 11, -21, 14, -28, 32, -23, 25, -31, 19,
+ -15, 19, -7, -7, 1, -13, 26, -19, 24, -37, 25, -24, 30, -18, 6, -9,
+ -2, 17, -16, 17, -34, 27, -19, 28, -21, 6, -15, 10, 4, 0, 2, -20,
+ 22, -19, -21, 0, -3, -3, 2, 1, -1, 2, -2, -1, 4, 3, -3, -15,
+ -21, -20, -23, -42, -45, -31, -27, -17, -8, 9, 29, 41, 44, 33, 20, 13,
+ 6, 12, 16, 25, 43, 44, 33, 33, 35, 15, -5, -3, 8, 16, 8, -10,
+ -6, 8, 4, -4, 1, -18, -38, -43, -51, -54, -55, -71, -85, -68, -58, -61,
+ -50, -33, -27, -15, -5, 22, 67, 100, 109, 114, 110, 91, 69, 50, 37, 35,
+ 46, 48, 37, 36, 14, -24, -38, -42, -38, -38, -59, -91, -86, -57, -44, -32,
+ -15, -26, -44, -30, -30, -30, -16, -31, -50, -34, -43, -59, -49, -44, -52, -62,
+ -69, -50, -4, 47, 83, 105, 120, 111, 88, 72, 55, 57, 76, 69, 59, 55,
+ 41, 10, -18, -32, -28, -19, -36, -68, -76, -72, -71, -46, -35, -47, -43, -43,
+ -61, -48, -28, -25, -22, -19, -23, -15, -7, 3, 4, -8, -28, -37, -5, 42,
+ 72, 107, 127, 122, 117, 90, 48, 37, 48, 51, 54, 56, 43, 24, -8, -37,
+ -33, -11, -28, -55, -61, -75, -75, -51, -58, -55, -33, -33, -41, -35, -30, -21,
+ -16, -17, -24, -26, -20, -18, -17, -12, -36, -72, -65, -45, -6, 53, 88, 106,
+ 119, 107, 71, 52, 50, 59, 75, 87, 85, 76, 43, -1, -7, 9, -1, -13,
+ -34, -69, -80, -74, -80, -73, -65, -67, -65, -56, -44, -33, -23, -18, -24, -25,
+ -16, -20, -9, -1, -21, -38, -55, -64, -40, 3, 39, 82, 113, 114, 95, 71,
+ 54, 56, 68, 76, 87, 94, 57, 10, -9, -17, -17, -15, -35, -60, -75, -89,
+ -92, -85, -76, -71, -74, -70, -53, -41, -20, -9, -9, 4, 4, 10, 33, 38,
+ 25, 15, -17, -43, -33, -15, 3, 40, 77, 94, 91, 69, 37, 31, 33, 37,
+ 68, 96, 82, 53, 25, 8, 22, 28, 9, -9, -27, -46, -56, -65, -62, -61,
+ -60, -51, -51, -39, -25, -23, -11, -3, -15, -10, 5, 12, 20, 18, -11, -41,
+ -52, -47, -34, -2, 33, 65, 82, 70, 51, 45, 28, 21, 49, 74, 86, 74,
+ 33, 5, 10, 14, 7, -10, -28, -45, -67, -68, -73, -76, -66, -66, -65, -46,
+ -39, -31, -9, -3, -6, 1, 8, 22, 41, 49, 33, 8, -16, -34, -30, -17,
+ 7, 49, 73, 64, 63, 50, 19, 5, 13, 32, 62, 65, 37, 8, -5, 4,
+ -1, -8, -15, -36, -50, -57, -71, -65, -53, -58, -49, -37, -40, -28, -10, -3,
+ 0, 2, -2, 5, 30, 41, 36, 22, -7, -33, -39, -46, -30, 15, 44, 56,
+ 72, 65, 44, 21, 2, 15, 42, 59, 49, 18, 2, -3, -4, 0, -10, -25,
+ -34, -52, -65, -59, -56, -50, -37, -33, -33, -25, -12, -2, 10, 12, 3, 6,
+ 27, 42, 52, 43, 16, -3, -24, -48, -41, -11, 16, 48, 67, 78, 75, 49,
+ 21, 13, 36, 64, 63, 47, 25, -1, -2, 2, -12, -18, -28, -53, -65, -71,
+ -76, -70, -55, -53, -49, -41, -35, -24, -1, 5, 1, 4, 8, 28, 51, 43,
+ 26, 18, -14, -42, -51, -49, -23, 5, 31, 55, 67, 58, 26, -2, 11, 35,
+ 49, 55, 35, 8, 3, -2, -5, -6, -13, -30, -38, -49, -61, -56, -45, -43,
+ -36, -31, -37, -25, -7, 1, 6, 1, -10, 11, 33, 29, 27, 17, -6, -34,
+ -58, -67, -57, -34, -4, 21, 50, 63, 37, 11, 8, 17, 45, 63, 55, 39,
+ 26, 12, 11, 10, -1, -11, -19, -35, -51, -52, -52, -45, -35, -36, -41, -31,
+ -24, -9, 9, -3, -12, 2, 19, 33, 40, 37, 25, -3, -30, -51, -59, -42,
+ -24, -3, 38, 58, 51, 32, 8, 2, 25, 45, 50, 49, 35, 18, 16, 19,
+ 10, 9, 4, -13, -27, -36, -45, -36, -24, -32, -29, -31, -33, -10, 6, 1,
+ -4, -6, 4, 19, 30, 37, 30, 12, -13, -48, -59, -57, -56, -35, 2, 31,
+ 48, 41, 12, -2, 7, 25, 41, 52, 44, 29, 25, 22, 18, 20, 15, 1,
+ -6, -26, -38, -28, -26, -21, -17, -31, -33, -19, -4, 0, -8, -16, -15, -11,
+ 9, 19, 22, 24, -2, -34, -49, -61, -70, -57, -32, 4, 38, 46, 26, 5,
+ -1, 7, 29, 45, 44, 38, 32, 23, 27, 30, 23, 24, 14, -8, -16, -24,
+ -24, -12, -10, -19, -27, -26, -9, -2, -4, -6, -16, -14, -2, 8, 23, 34,
+ 17, -6, -26, -47, -61, -62, -50, -18, 26, 50, 48, 31, 12, 6, 24, 40,
+ 44, 51, 40, 29, 34, 28, 27, 32, 20, 7, -5, -23, -26, -19, -9, -12,
+ -25, -25, -17, -8, 1, -4, -13, -12, -16, -9, 13, 26, 23, 8, -13, -37,
+ -55, -71, -78, -59, -18, 16, 35, 34, 8, -3, 4, 13, 31, 40, 34, 34,
+ 29, 23, 30, 31, 27, 21, 7, -6, -21, -21, -10, -10, -19, -24, -28, -17,
+ -6, -8, -9, -9, -19, -21, -5, 12, 23, 22, 5, -16, -34, -55, -80, -78,
+ -56, -22, 18, 33, 24, 14, 3, 7, 25, 31, 37, 41, 33, 29, 29, 32,
+ 33, 30, 24, 7, -16, -22, -18, -15, -14, -24, -31, -22, -13, -12, -8, -6,
+ -18, -27, -22, -6, -5, -1, -1, -1, 1, 2, 7, 13, 19, 10, -12, -31,
+ -13, 17, 29, -4, -29, 24, 53, 18, 92, 15, -15, 23, 13, -35, -52, 127,
+ 9, 3, -9, 31, -63, -64, -5, -50, 14, 33, -29, -42, 0, 43, 39, -15,
+ -59, -45, 3, 33, 12, -35, -10, 51, 18, 49, 55, -28, 16, 4, 3, -64,
+ 54, 53, -12, 0, 5, -4, -72, -7, -31, -14, 26, -2, -37, -14, 17, 35,
+ 4, -33, -45, -12, 15, 21, -16, -23, 22, 28, 12, 55, -7, -2, 7, 7,
+ -34, -10, 65, -4, 1, -5, 14, -46, -28, -9, -29, 13, 13, -23, -23, 4,
+ 27, 18, -17, -39, -25, 5, 20, 0, -26, 1, 34, 7, 41, 24, -20, 11,
+ 1, -6, -45, 53, 22, -6, -4, 9, -17, -52, -4, -30, -6, 20, -9, -29,
+ -8, 18, 27, -2, -33, -36, -6, 16, 13, -20, -16, 27, 19, 18, 49, -17,
+ 3, 2, 6, -42, 9, 55, -9, 1, -3, 9, -54, -19, -16, -24, 16, 7,
+ -27, -19, 8, 28, 12, -22, -40, -20, 8, 19, -7, -25, 9, 31, 7, 48,
+ 9, -14, 9, 2, -17, -35, 62, 9, -2, -6, 13, -30, -44, -4, -31, 2,
+ 18, -15, -27, -3, 22, 24, -8, -36, -32, -2, 17, 8, -23, -9, 31, 13,
+ 28, 40, -21, 8, 1, 3, -47, 29, 43, -9, 0, 1, 1, -57, -11, -22,
+ -17, 19, 2, -28, -14, 12, 29, 7, -27, -39, -14, 11, 17, -13, -22, 17,
+ 27, 10, 51, -4, -7, 7, 5, -27, -19, 64, -1, 1, -6, 14, -41, -34,
+ -8, -30, 8, 15, -20, -24, 2, 25, 20, -14, -38, -27, 2, 18, 2, -25,
+ -1, 33, 9, 37, 29, -21, 11, 0, -3, -46, 46, 29, -7, -2, 7, -9,
+ -54, -6, -27, -10, 20, -4, -28, -9, 16, 28, 1, -30, -37, -8, 14, 14,
+ -18, -17, 25, 22, 16, 50, -13, 1, 4, 5, -37, 0, 59, -7, 2, -4,
+ 12, -49, -24, -13, -26, 13, 11, -23, -19, 6, 27, 15, -19, -39, -21, 6,
+ 18, -4, -24, 7, 32, 8, 45, 15, -16, 10, 2, -12, -39, 58, 16, -3,
+ -5, 11, -22, -48, -4, -30, -2, 19, -10, -26, -4, 20, 25, -5, -34, -33,
+ -4, 16, 10, -21, -11, 30, 16, 25, 43, -19, 7, 1, 4, -44, 20, 49,
+ -8, 1, -1, 6, -54, -15, -19, -20, 17, 6, -26, -15, 10, 29, 9, -23,
+ -39, -16, 9, 17, -10, -22, 15, 29, 10, 50, 2, -10, 8, 3, -22, -26,
+ 63, 5, 0, -6, 14, -34, -39, -6, -30, 4, 17, -15, -24, 0, 24, 22,
+ -11, -36, -28, 1, 17, 5, -23, -3, 32, 12, 34, 33, -21, 10, 0, 0,
+ -46, 39, 36, -7, -1, 4, -3, -54, -9, -24, -14, 19, 0, -26, -10, 14,
+ 28, 4, -27, -37, -11, 12, 15, -15, -18, 22, 24, 14, 50, -9, -2, 5,
+ 5, -32, -8, 61, -3, 2, -5, 14, -44, -29, -10, -27, 10, 13, -20, -20,
+ 4, 26, 17, -16, -37, -23, 4, 18, -1, -23, 5, 32, 9, 42, 20, -18,
+ 11, 1, -7, -41, 53, 22, -4, -3, 9, -14, -50, -6, -27, -7, 19, -6,
+ -26, -5, 18, 26, -2, -31, -34, -6, 14, 11, -19, -12, 28, 19, 22, 45,
+ -17, 4, 2, 5, -40, 11, 54, -6, 2, -3, 10, -51, -20, -16, -23, 14,
+ 9, -23, -15, 8, 28, 12, -20, -38, -18, 7, 17, -7, -22, 13, 30, 10,
+ 47, 7, -12, 9, 2, -17, -31, 61, 10, 0, -5, 13, -26, -43, -6, -29,
+ 0, 18, -11, -23, -1, 22, 23, -8, -34, -30, -1, 15, 7, -22, -5, 31,
+ 14, 30, 37, -20, 9, 0, 2, -44, 30, 42, -7, 1, 2, 2, -53, -12,
+ -21, -17, 17, 4, -25, -11, 12, 28, 6, -25, -37, -13, 10, 15, -13, -18,
+ 20, 26, 13, 49, -5, -5, 6, 4, -27, -16, 62, 1, 2, -5, 14, -38,
+ -34, -9, -28, 6, 15, -16, -20, 3, 25, 19, -13, -36, -25, 2, 16, 1,
+ -23, 3, 32, 11, 38, 25, -19, 11, 0, -4, -43, 46, 29, -4, -2, 7,
+ -8, -51, -8, -25, -10, 18, -2, -25, -7, 16, 27, 0, -28, -35, -8, 12,
+ 12, -17, -13, 26, 21, 19, 46, -14, 2, 3, 4, -36, 2, 57, -4, 3,
+ -4, 12, -46, -25, -13, -25, 11, 12, -20, -16, 7, 27, 14, -18, -37, -20,
+ 5, 16, -5, -21, 10, 31, 10, 45, 12, -14, 10, 1, -12, -36, 57, 16,
+ -1, -4, 11, -20, -46, -6, -28, -4, 18, -8, -23, -3, 20, 24, -5, -32,
+ -31, -4, 13, 8, -20, -6, 29, 17, 27, 39, -19, 7, 0, 3, -42, 21,
+ 47, -6, 2, 0, 7, -51, -17, -18, -20, 15, 7, -23, -12, 10, 28, 8,
+ -22, -37, -15, 8, 15, -10, -19, 18, 27, 13, 47, 0, -8, 8, 3, -24,
+ -20, 52, -36, -2, 0, -2, 3, 5, -4, -28, 22, -43, 36, -13, -127, -43,
+ 2, -18, 126, 78, -127, -48, 68, -74, -67, 33, 62, 83, 42, -32, -46, -70,
+ -26, 115, 21, -66, 72, 52, -27, 44, 50, 50, 61, 28, -12, 3, -59, 49,
+ 3, -19, 39, 94, 16, 31, 6, 29, 3, -100, -1, -4, -60, 19, 7, -29,
+ -28, -38, -3, -47, -20, -21, -1, 5, -55, -12, -55, -39, 26, 47, -22, -9,
+ -41, -21, -19, -37, 0, 45, -56, 24, 75, -50, -9, 31, 28, 26, 13, -3,
+ -15, -27, 1, 1, -31, -10, 38, -1, 7, 43, 19, 21, 41, 33, 9, -17,
+ -3, -42, -76, -30, -8, -9, -1, 21, 22, 38, 32, 22, 0, -18, -32, -58,
+ -12, 5, -48, -13, 64, 29, -2, 2, 19, 43, 25, -19, -39, -69, -92, -15,
+ 23, 30, 30, 51, 37, 35, 37, 30, -27, -63, 5, -30, -56, -16, 26, 52,
+ 20, 14, 59, 27, -9, 22, -4, -20, -37, -17, -34, -34, -1, 35, 26, 31,
+ 5, -16, 4, 33, 22, 8, 5, -28, -41, -20, -10, -6, -2, -16, 12, 31,
+ -23, 7, -2, -39, -28, -13, 8, 5, 16, -4, -6, -18, -24, -27, -50, -6,
+ 5, 12, 0, -2, -14, -23, 5, -28, -10, 2, 28, 15, 2, 22, 27, 41,
+ 31, 2, 12, 31, 5, 12, -6, 15, 40, 34, 18, 26, 26, 12, 34, 23,
+ 34, 30, 22, 10, -26, -22, 1, 0, -1, 12, -4, -21, -5, -5, -20, -31,
+ -25, -24, -42, -44, -41, -41, -37, -29, -28, -29, -40, -17, -21, -38, -42, -38,
+ -40, -36, -13, -14, -8, -15, -7, -6, 5, 12, -1, -17, -1, 9, 2, 16,
+ 30, 27, 37, 36, 38, 36, 36, 19, 45, 45, 33, 26, 33, 28, 36, 31,
+ 17, 12, 22, 11, 11, 17, 5, -13, 6, 10, 2, -6, 2, 9, 15, -6,
+ -8, -23, -44, -3, -11, -35, -25, -35, -23, -21, 0, -11, -21, -17, 11, -6,
+ -11, -17, -33, -16, -16, -4, -7, -7, -9, -4, 1, 1, -3, 6, 7, 4,
+ -17, -11, -6, -4, 1, 3, 6, 4, 5, -4, 17, 7, 3, 9, -20, 0,
+ -7, -3, -5, 4, 9, 16, 2, 3, 8, 15, 15, 1, -3, 8, -1, 5,
+ 14, 7, 4, 8, -8, 2, -3, 5, 11, 5, 3, -4, 10, 17, 13, -11,
+ -5, 1, -3, 0, -6, -12, 2, -3, 13, -5, -25, -15, -7, 4, 1, -8,
+ -4, -12, -16, 3, 9, -6, 3, -21, -4, 4, -14, 1, -1, -2, 3, -8,
+ -5, 0, 7, -2, -3, -1, 3, -9, 5, -4, -17, -1, 9, 3, 7, 1,
+ -4, -3, 5, 2, -7, -9, 12, -6, -14, -16, 2, -1, 16, 2, 2, 7,
+ -6, -26, 3, -2, -4, -2, 10, 3, -7, 3, 8, 9, 5, 4, 1, -5,
+ -5, 11, 8, 7, 11, 12, -1, -5, -16, 13, 7, 2, 11, 4, -4, 9,
+ -8, -8, 14, 11, -8, 0, -1, -5, -2, -1, -10, -5, -9, -9, -16, -12,
+ -8, -16, 5, -10, -4, -11, -3, 1, 0, -3, -5, -13, -9, -2, -8, 5,
+ -9, -7, -2, 2, -11, -7, 13, 8, -3, 2, 7, -2, -1, 5, 0, 11,
+ 6, 13, 15, 1, -4, 9, 5, 3, 8, -3, -4, 16, 4, 11, 9, 0,
+ 8, 1, -6, -5, -18, 3, 7, -18, -4, 0, -3, -3, -6, -4, -5, -5,
+ -10, -2, -9, -5, -2, -4, -11, -2, 1, -5, -2, 11, -6, -9, 1, 4,
+ -6, -1, -5, 1, 2, 9, 5, 0, 4, 4, -2, 7, 0, -10, 5, 2,
+ -3, 0, -6, 7, -4, -3, 6, -1, -6, -1, -1, 2, -2, -6, -3, 0,
+ 8, -6, 4, -1, -5, -3, 3, 1, -5, -6, -2, -3, 5, 6, 0, 7,
+ -3, 3, -1, 0, -2, 9, 1, 1, -3, 4, 5, -5, 2, -2, 2, -11,
+ -2, -4, 11, 4, 5, 0, -5, -12, -6, -5, -5, 3, -2, -2, 2, 2,
+ 1, 0, -1, -8, -5, -5, -3, 2, -1, 3, -1, 3, 0, -1, 0, -1,
+ 1, 1, -4, -4, 2, -2, 1, -6, 1, 2, 4, 2, 2, -5, -1, 6,
+ -3, -1, -4, 11, 3, -9, -2, -6, -3, 2, 4, 2, 1, 2, 4, 3,
+ -6, -4, -3, -2, 0, 2, -2, 5, 2, -1, 3, -9, -3, -3, -4, -4,
+ -1, 0, -2, 7, 3, 1, 1, -2, -4, -2, -3, -2, -4, 2, 4, -1,
+ 2, 3, 0, 3, -1, 0, -2, -2, -3, 1, -1, -4, 5, -1, 5, 0,
+ -3, -2, -1, -4, 3, -1, -3, -2, -2, -1, 0, 0, 1, -1, 0, -2,
+ -2, 0, -3, -1, 0, 0, 1, 1, -2, -1, 1, -3, 1, 2, 0, -1,
+ 0, -1, 1, 5, -2, 1, -3, -3, -1, -3, 0, 1, 3, 2, -1, -1,
+ -2, -2, -1, 1, 0, -1, -2, -2, -2, -3, -3, -3, -2, -2, -2, -2,
+ -2, -2, -2, -1, 0, 1, 1, -2, -2, 0, 0, 2, -3, -16, -22, -20,
+ -28, -35, -31, -17, 19, 33, 36, 33, 34, 40, 36, 25, 18, 20, 18, 14,
+ 17, 12, 14, 10, -24, -36, -27, -38, -55, -69, -66, -47, -33, -13, 3, 5,
+ 10, 22, 25, 15, 28, 43, 41, 51, 56, 58, 58, 31, -18, -52, -64, -71,
+ -92, -105, -98, -77, -50, -17, 23, 59, 85, 99, 94, 76, 55, 14, -9, -5,
+ -7, -18, -17, -35, -53, -53, -33, -23, -33, -36, -15, 17, 32, 24, 12, 19,
+ 37, 54, 49, 38, 21, -14, -44, -30, -22, -15, 5, 8, -1, -26, -42, -46,
+ -49, -51, -37, -17, 1, -4, -19, -4, 45, 84, 91, 79, 57, 3, -30, -29,
+ -35, -25, -8, -6, -26, -61, -75, -73, -77, -72, -54, -19, 9, 6, -10, 3,
+ 47, 85, 92, 103, 92, 45, 21, 6, 4, 16, 27, 27, -1, -48, -69, -78,
+ -80, -84, -72, -33, -10, -24, -41, -20, 40, 82, 99, 123, 102, 69, 49, 30,
+ 27, 34, 42, 41, -2, -58, -96, -108, -103, -106, -83, -37, -10, -18, -38, -18,
+ 40, 65, 92, 110, 84, 44, 1, -26, -23, -7, 21, 32, 7, -39, -78, -84,
+ -79, -82, -61, -19, 5, -14, -52, -25, 25, 59, 102, 127, 116, 86, 40, 13,
+ 4, 9, 27, 29, 4, -47, -88, -94, -87, -83, -56, -18, 15, -13, -49, -30,
+ -2, 29, 69, 87, 80, 50, 9, -15, -27, -10, 18, 44, 36, -9, -45, -53,
+ -53, -46, -33, 6, 31, -8, -36, -28, -11, 21, 54, 76, 76, 44, 4, -33,
+ -53, -45, -18, 13, 10, -35, -62, -70, -61, -44, -19, 38, 63, 30, 9, 4,
+ 9, 35, 60, 81, 75, 51, 14, -25, -44, -37, -9, 29, 24, -11, -41, -59,
+ -51, -54, -33, 23, 35, 6, -13, -28, -18, 8, 43, 73, 76, 63, 33, -1,
+ -21, -22, 10, 43, 35, 5, -32, -47, -51, -68, -44, 6, 14, 0, -21, -34,
+ -25, 0, 37, 65, 73, 64, 35, 5, -22, -25, 11, 40, 39, 13, -20, -28,
+ -42, -64, -32, 6, 15, -1, -25, -39, -39, -16, 19, 44, 58, 53, 27, -2,
+ -39, -38, -2, 30, 40, 13, -16, -19, -45, -60, -29, 6, 17, 1, -21, -40,
+ -44, -24, 9, 38, 58, 51, 38, 8, -31, -29, 0, 34, 44, 9, -11, -23,
+ -58, -69, -42, -6, 9, 0, -16, -33, -36, -12, 19, 55, 72, 68, 58, 18,
+ -22, -25, -6, 29, 31, 2, -5, -23, -57, -69, -45, -8, 12, 10, 0, -22,
+ -24, -7, 20, 52, 61, 65, 59, 21, -15, -28, -11, 26, 20, 2, -2, -22,
+ -56, -71, -49, -14, 3, 8, -5, -26, -28, -19, 14, 42, 54, 71, 67, 38,
+ 8, -11, 16, 47, 37, 26, 18, -10, -51, -74, -59, -35, -19, -12, -24, -37,
+ -44, -34, 0, 24, 44, 67, 64, 43, 3, -18, 11, 35, 28, 22, 18, -4,
+ -47, -68, -55, -34, -11, -7, -15, -27, -43, -32, -1, 18, 42, 58, 60, 43,
+ -8, -29, -6, 11, 7, 4, 4, -17, -59, -75, -66, -41, -13, -3, 1, -11,
+ -29, -19, 1, 19, 42, 53, 64, 45, -8, -28, -9, 7, 4, 4, 9, -13,
+ -51, -71, -69, -43, -19, -7, 3, -11, -25, -17, -2, 23, 43, 60, 78, 55,
+ 1, -19, -5, 8, 3, 7, 13, -8, -41, -66, -67, -40, -19, 3, 16, 1,
+ -7, -5, 10, 34, 46, 67, 87, 62, 11, -13, -1, 8, 4, 15, 20, 1,
+ -33, -64, -65, -48, -30, -2, 6, -5, -14, -18, 1, 21, 32, 62, 86, 66,
+ 20, -3, 6, 7, 5, 16, 20, 7, -29, -62, -65, -59, -39, -13, -5, -8,
+ -22, -27, -6, 7, 17, 49, 74, 58, 14, -5, -2, -4, -3, 7, 14, 6,
+ -32, -59, -66, -63, -40, -16, -2, -2, -19, -20, -1, 6, 18, 49, 77, 62,
+ 21, 3, -1, -5, -2, 5, 18, 10, -26, -50, -65, -64, -43, -24, -5, -6,
+ -24, -23, -8, -2, 10, 45, 75, 60, 25, 6, -4, -4, -5, 3, 20, 8,
+ -20, -43, -60, -58, -45, -24, 1, -1, -15, -12, -1, 3, 16, 53, 83, 70,
+ 42, 19, 9, 7, 3, 16, 29, 17, -7, -35, -55, -56, -49, -24, 2, -1,
+ -11, -7, 3, 4, 16, 55, 83, 75, 50, 25, 15, 6, 0, 13, 21, 13,
+ -9, -40, -58, -66, -62, -35, -11, -11, -18, -13, -3, -7, 9, 49, 75, 74,
+ 51, 28, 19, 5, 1, 13, 20, 16, -3, -28, -48, -62, -61, -37, -16, -13,
+ -20, -15, -12, -19, -5, 21, 50, 61, 47, 28, 15, -1, -6, 0, 9, 14,
+ 1, -19, -37, -55, -56, -38, -16, -11, -13, -9, -9, -16, -8, 18, 48, 59,
+ 44, 28, 9, 15, -3, 2, -5, 3, 3, 4, 1, 7, -2, 7, -4, 2,
+ -124, -37, 33, -48, 7, -27, 8, -14, 77, 26, -9, 26, 7, 20, 10, 13,
+ 8, 9, 7, 4, 5, 2, 3, 2, 1, -1, 0, -3, -2, -5, 1, -10,
+ 11, 70, -6, 21, 5, 27, -2, 41, -15, -61, -66, -128, 0, -48, -21, -46,
+ -6, -55, 23, 53, -6, 11, 2, 14, 11, 10, 11, 8, 9, 9, 8, 5,
+ 8, 5, 6, 5, 6, 2, 7, -4, 6, 5, -23, 62, 29, 24, 8, 33,
+ 4, 32, 36, -30, -16, -124, -58, -39, -18, -51, -3, -43, -40, 53, 19, 12,
+ 4, 9, 12, 13, 10, 11, 9, 8, 11, 6, 5, 8, 6, 3, 9, 1,
+ 7, 2, -5, 22, -33, 20, 37, 35, 7, 29, 14, 8, 52, -5, 17, -64,
+ -84, -70, -15, -55, -23, -12, -72, 1, 28, 16, 8, 6, 7, 12, 10, 8,
+ 11, 6, 8, 10, 5, 4, 10, 1, 8, 4, 2, 10, -15, 26, -16, -9,
+ 14, 42, 17, 19, 29, -3, 42, 14, 28, -8, -45, -92, -37, -41, -54, 0,
+ -53, -48, 2, 18, 10, 8, 4, 8, 12, 8, 10, 10, 6, 9, 10, 2,
+ 10, 5, 3, 9, -2, 18, -16, 17, 3, -9, -12, 26, 28, 13, 35, 3,
+ 27, 19, 31, 17, 4, -60, -67, -33, -66, -22, -22, -58, -38, 2, 11, 9,
+ 7, 4, 9, 10, 8, 10, 9, 5, 12, 5, 5, 9, 2, 11, -5, 21,
+ -8, 4, 10, 5, -17, -1, 28, 11, 34, 13, 20, 17, 28, 24, 27, -6,
+ -61, -41, -57, -51, -17, -36, -56, -32, -1, 7, 8, 5, 6, 8, 10, 8,
+ 12, 6, 9, 9, 5, 9, 1, 15, -7, 15, 5, -2, 4, 14, -3, -18,
+ 15, 8, 28, 21, 20, 16, 23, 23, 29, 30, -20, -38, -45, -63, -38, -23,
+ -43, -53, -29, -5, 5, 5, 5, 5, 9, 7, 11, 8, 8, 10, 5, 12,
+ -2, 16, -1, 4, 11, 4, -3, 8, 15, -16, 0, 1, 16, 23, 23, 17,
+ 20, 21, 21, 39, 19, -14, -28, -52, -58, -33, -28, -47, -50, -30, -6, 2,
+ 5, 4, 6, 6, 9, 10, 7, 12, 3, 15, 0, 10, 8, 1, 6, 11,
+ 2, -4, 20, -1, -6, -5, 4, 15, 24, 20, 18, 23, 15, 30, 38, 13,
+ -6, -27, -56, -52, -30, -34, -48, -50, -28, -8, 2, 3, 5, 5, 6, 11,
+ 5, 13, 3, 12, 6, 5, 10, 5, 2, 7, 13, -8, 10, 11, 0, -6,
+ -4, 3, 17, 23, 16, 24, 18, 17, 36, 32, 13, -1, -30, -57, -45, -31,
+ -36, -51, -49, -28, -7, -1, 3, 6, 2, 11, 5, 12, 6, 9, 10, 5,
+ 8, 8, 5, -1, 16, 1, -1, 11, 9, -1, -5, -5, 4, 20, 17, 20,
+ 24, 14, 23, 37, 29, 16, 2, -33, -53, -42, -30, -39, -52, -49, -27, -9,
+ -3, 5, 0, 8, 5, 10, 8, 6, 10, 6, 7, 6, 11, -3, 8, 11,
+ 0, 2, 11, 8, -1, -5, -7, 9, 18, 16, 24, 20, 14, 27, 35, 27,
+ 21, 1, -33, -50, -38, -32, -42, -53, -48, -25, -14, -1, -2, 4, 3, 6,
+ 9, 5, 9, 7, 7, 4, 12, 4, 1, 10, 6, 2, 6, 10, 4, 0,
+ -6, -2, 11, 14, 18, 22, 17, 20, 32, 34, 28, 20, 0, -26, -36, -34,
+ -37, -45, -54, -44, -30, -13, -8, -3, 1, 2, 6, 4, 7, 8, 8, 2,
+ 8, 10, 1, 4, 6, 5, 5, 9, 6, 1, -3, -5, 3, 10, 14, 18,
+ 18, 17, 26, 35, 35, 29, 17, -1, -17, -24, -32, -41, -50, -51, -44, -28,
+ -18, -12, -5, -2, 2, 3, 3, 6, 9, 4, 3, 9, 6, 2, 2, 4,
+ 5, 9, 10, 4, -2, -5, -1, 5, 10, 14, 16, 15, 19, 30, 38, 37,
+ 29, 15, 1, -5, -14, -31, -43, -50, -52, -42, -29, -22, -16, -9, -3, 0,
+ 0, 2, 6, 6, 2, 4, 7, 6, 2, 1, 2, 6, 11, 10, 2, -5,
+ -4, 0, 5, 10, 14, 15, 14, 21, 32, 39, 38, 29, 14, 4, 0, -3,
+ -19, -32, -40, -43, -41, -36, -31, -25, -19, -12, -9, -8, -6, -1, 2, 2,
+ 0, -3, -4, -1, 3, 6, 6, 2, -3, -6, -2, 2, 2, 1, 2, 7,
+ 16, 25, 32, 35, 35, 36, 36, 33, 24, 11, -3, -18, -32, -40, -42, -40,
+ -36, -30, -25, -18, -12, -9, -8, -5, -1, 2, 2, 0, -3, -4, -1, 3,
+ 7, 6, 2, -4, -5, -2, 2, 2, 1, 2, 8, 17, 25, 32, 35, 36,
+ 36, 36, 32, 23, 10, -4, -20, -33, -41, -42, -40, -35, -30, -24, -18, -12,
+ -9, -8, -5, -1, 3, 2, -1, -4, -4, -1, 4, 7, 6, 1, -4, -5,
+ -2, -1, 3, 1, 3, 5, 3, -3, -1, -1, 1, -15, 1, 1, -5, -7,
+ 7, -2, -4, 3, -2, -5, -1, -3, -3, -1, 6, 3, 2, 3, -26, -117,
+ 35, -8, -19, 24, 58, -7, -6, 25, -9, 7, 4, 10, 2, 7, 6, 6,
+ 0, 6, -2, -1, -3, -3, 8, 71, 0, 17, 27, 20, -102, -115, 39, -32,
+ -18, -5, 58, -15, -12, 13, -10, -4, 1, 2, 1, 0, 6, 2, 1, 2,
+ 0, -4, 0, -5, 2, 67, 9, 14, 28, 29, -72, -126, 27, -25, -19, -14,
+ 58, -6, -11, 13, -5, -3, 3, 3, 4, 1, 8, 3, 3, 3, 3, -2,
+ 2, -3, -3, 62, 17, 14, 27, 35, -45, -128, 11, -19, -20, -22, 53, 1,
+ -12, 11, -3, -4, 2, 3, 4, 1, 7, 3, 3, 3, 3, -2, 2, -2,
+ -9, 57, 22, 14, 25, 37, -23, -125, -8, -15, -20, -30, 46, 9, -12, 10,
+ -2, -3, 0, 3, 3, 1, 6, 4, 2, 3, 2, -2, 1, 0, -16, 50,
+ 26, 13, 22, 37, -2, -117, -27, -13, -18, -36, 36, 16, -13, 9, -2, -2,
+ -2, 3, 2, 2, 4, 5, 1, 4, 2, -1, 0, 4, -20, 43, 29, 15,
+ 20, 36, 14, -102, -43, -15, -16, -40, 26, 22, -12, 8, -2, -2, -3, 3,
+ 1, 3, 2, 6, 1, 5, 1, 0, -1, 7, -23, 35, 31, 18, 18, 33,
+ 27, -83, -57, -20, -14, -42, 14, 26, -9, 7, -2, 0, -5, 3, 1, 4,
+ 1, 7, 0, 5, 1, 1, -2, 10, -24, 26, 31, 20, 17, 30, 36, -62,
+ -65, -27, -12, -43, 2, 28, -7, 6, -2, 0, -5, 3, 0, 4, 0, 7,
+ 0, 5, 1, 2, -4, 11, -23, 17, 32, 22, 16, 27, 42, -44, -67, -36,
+ -9, -42, -8, 28, -3, 5, -1, 1, -5, 2, 0, 4, 1, 7, 1, 5,
+ 1, 3, -5, 13, -22, 10, 31, 23, 17, 22, 45, -25, -66, -45, -8, -40,
+ -18, 27, 0, 5, -1, 1, -5, 1, 0, 4, 0, 6, 2, 4, 2, 3,
+ -6, 14, -19, 2, 29, 25, 19, 19, 47, -10, -60, -54, -10, -37, -27, 24,
+ 4, 4, 0, 1, -5, 0, 0, 3, 1, 5, 2, 4, 2, 4, -7, 15,
+ -16, -4, 27, 25, 21, 15, 48, 4, -51, -61, -12, -33, -34, 19, 7, 4,
+ 1, 0, -4, -1, 0, 3, 2, 5, 3, 3, 3, 5, -8, 15, -11, -10,
+ 24, 25, 23, 12, 45, 15, -39, -66, -18, -28, -40, 12, 10, 4, 2, 1,
+ -3, -2, 0, 2, 2, 4, 3, 3, 3, 5, -8, 13, -6, -14, 19, 25,
+ 25, 10, 43, 24, -25, -67, -25, -24, -45, 4, 11, 5, 3, 0, -2, -3,
+ -1, 1, 2, 3, 3, 3, 2, 6, -9, 11, -2, -17, 15, 24, 27, 9,
+ 39, 31, -13, -66, -33, -19, -48, -3, 11, 5, 3, 1, -2, -3, -1, 1,
+ 2, 4, 3, 3, 2, 8, -9, 9, 3, -18, 10, 22, 29, 9, 35, 35,
+ 0, -61, -41, -17, -49, -11, 10, 6, 3, 2, -2, -3, -2, 1, 1, 4,
+ 3, 5, 1, 9, -9, 7, 6, -18, 5, 20, 29, 10, 32, 38, 11, -47,
+ -45, -18, -47, -20, 5, 6, 4, 2, -1, -3, -2, 0, 1, 5, 1, 6,
+ 1, 7, -7, 6, 6, -16, 1, 16, 27, 11, 29, 40, 20, -30, -43, -23,
+ -46, -28, -2, 4, 4, 2, -1, -3, -2, -1, 0, 6, -1, 7, 2, 5,
+ -6, 5, 6, -15, -3, 13, 25, 12, 26, 41, 26, -14, -36, -26, -44, -35,
+ -11, 1, 4, 2, 0, -4, -3, -3, -1, 7, -2, 7, 4, 4, -6, 4,
+ 7, -13, -6, 10, 23, 12, 24, 42, 31, 0, -24, -28, -42, -40, -19, -4,
+ 4, 2, 1, -4, -3, -4, -3, 8, -3, 6, 6, 3, -6, 4, 7, -11,
+ -8, 7, 20, 12, 21, 41, 34, -2, -31, -34, -29, -21, -12, -3, -4, -10,
+ -7, -5, -6, -4, 5, 8, -3, -1, 7, -1, -11, -7, 0, 1, 6, 16,
+ 28, 33, 33, 30, 13, -1, -26, -35, -30, -24, -14, -5, -4, -11, -7, -5,
+ -6, -6, 3, 8, -2, -2, 7, 1, -11, -9, -1, 0, 4, 14, 26, 32,
+ 33, 32, 17, 3, -22, -34, -31, -25, -16, -6, -3, -10, -8, -5, -6, -7,
+ 2, 9, 0, -3, 6, 3, -9, -10, -2, 0, 3, 12, 24, 32, -1, 0,
+ -3, -1, -8, -5, -16, -5, -14, -4, -13, -5, -1, -7, 16, -17, 28, -16,
+ 47, 1, 70, 35, 97, 71, 98, 66, 32, -5, -71, -69, -122, -69, -105, -33,
+ -67, -6, -35, 2, -12, -2, 4, -12, 16, -19, 29, -16, 44, 2, 66, 37,
+ 92, 76, 95, 74, 33, 5, -69, -63, -122, -69, -106, -36, -66, -11, -33, -3,
+ -9, -7, 7, -16, 18, -22, 29, -17, 42, 3, 61, 40, 86, 81, 91, 82,
+ 34, 15, -67, -57, -122, -69, -105, -40, -64, -17, -29, -9, -6, -12, 10, -20,
+ 20, -23, 28, -17, 39, 4, 56, 42, 80, 85, 88, 89, 35, 24, -63, -53,
+ -119, -70, -104, -45, -62, -22, -26, -14, -2, -16, 12, -23, 20, -25, 27, -16,
+ 35, 7, 51, 45, 74, 89, 85, 96, 38, 32, -58, -49, -116, -72, -102, -50,
+ -60, -27, -24, -19, 0, -20, 14, -24, 20, -24, 24, -14, 31, 10, 45, 48,
+ 69, 92, 82, 102, 40, 39, -53, -45, -112, -74, -100, -55, -57, -33, -21, -24,
+ 3, -24, 15, -26, 19, -24, 22, -12, 27, 12, 40, 50, 63, 95, 80, 106,
+ 43, 45, -47, -42, -107, -76, -97, -60, -55, -38, -18, -28, 4, -26, 15, -27,
+ 18, -23, 19, -10, 23, 15, 35, 53, 59, 97, 78, 110, 47, 50, -39, -39,
+ -102, -79, -94, -65, -52, -43, -16, -32, 5, -28, 14, -27, 16, -21, 15, -7,
+ 18, 18, 30, 55, 54, 98, 76, 113, 51, 55, -32, -37, -96, -81, -91, -70,
+ -50, -48, -15, -35, 6, -30, 13, -26, 13, -19, 11, -5, 13, 20, 25, 56,
+ 50, 99, 75, 115, 56, 59, -24, -35, -90, -83, -88, -75, -48, -52, -14, -38,
+ 5, -30, 11, -25, 10, -17, 7, -2, 9, 22, 21, 57, 47, 99, 75, 116,
+ 61, 62, -15, -33, -82, -86, -84, -80, -47, -56, -14, -39, 4, -30, 9, -24,
+ 6, -15, 3, 1, 5, 24, 17, 57, 44, 98, 75, 116, 66, 65, -6, -31,
+ -75, -88, -81, -83, -46, -59, -14, -41, 3, -30, 6, -22, 3, -12, -1, 3,
+ 1, 26, 13, 57, 41, 96, 75, 115, 72, 68, 2, -29, -69, -89, -78, -87,
+ -45, -62, -15, -42, 0, -29, 3, -20, -1, -10, -5, 5, -2, 26, 11, 56,
+ 40, 94, 76, 114, 77, 69, 12, -28, -61, -91, -75, -89, -45, -64, -16, -42,
+ -2, -28, 0, -18, -5, -8, -9, 7, -6, 27, 8, 55, 38, 91, 77, 112,
+ 82, 71, 20, -25, -55, -91, -73, -91, -46, -65, -18, -42, -5, -26, -4, -15,
+ -10, -5, -13, 9, -9, 27, 7, 53, 37, 88, 78, 110, 87, 72, 29, -23,
+ -48, -90, -71, -93, -47, -66, -21, -41, -9, -24, -8, -13, -13, -3, -16, 9,
+ -11, 27, 5, 51, 37, 84, 79, 108, 93, 74, 37, -20, -42, -90, -70, -94,
+ -49, -66, -24, -40, -12, -23, -12, -12, -16, -2, -18, 10, -12, 25, 5, 48,
+ 37, 80, 81, 105, 98, 75, 45, -16, -36, -88, -68, -94, -51, -66, -28, -39,
+ -16, -21, -15, -10, -19, -1, -21, 10, -13, 24, 4, 45, 37, 76, 82, 102,
+ 102, 76, 52, -13, -30, -85, -67, -94, -54, -66, -31, -38, -20, -19, -19, -9,
+ -22, 0, -22, 9, -14, 22, 4, 41, 37, 71, 83, 99, 105, 77, 59, -8,
+ -25, -82, -67, -93, -56, -65, -35, -37, -23, -18, -22, -7, -25, 0, -24, 8,
+ -14, 20, 5, 37, 38, 67, 84, 96, 108, 79, 65, -3, -20, -79, -66, -92,
+ -59, -65, -39, -36, -27, -17, -25, -7, -27, -1, -24, 6, -14, 17, 6, 34,
+ 39, 63, 84, 93, 111, 80, 71, 1, -15, -75, -66, -90, -62, -64, -43, -35,
+ -31, -16, -28, -6, -28, -1, -25, 5, -14, 14, 6, 30, 39, 58, 85, 90,
+ 113, 82, 76, 7, -11, -70, -66, -88, -66, -62, -46, -34, -34, -15, -30, -7,
+ -30, -2, -25, 2, -13, 11, 7, 26, 40, 53, 84, 87, 115, 84, 81, 13,
+ -7, -65, -66, -85, -68, -61, -50, -33, -37, -15, -32, -7, -30, -4, -25, 0,
+ -12, 7, 9, 19, 37, 52, 80, 97, 118, 113, 98, 54, 7, -41, -72, -87,
+ -87, -75, -65, -47, -42, -29, -30, -22, -24, -19, -19, -14, -9, -2, 8, 17,
+ 36, 50, 77, 95, 117, 115, 101, 60, 13, -35, -69, -85, -88, -75, -66, -49,
+ -44, -31, -31, -23, -25, -20, -20, -15, -9, -2, -1, 0, 0, 0, 0, -1,
+ -1, -1, 3, 9, 14, 14, 10, -3, -17, -13, 1, 1, 23, 33, -14, -55,
+ -59, -80, -75, -35, -7, 51, 40, -29, -35, -53, -128, -31, 111, 72, 46, 55,
+ -19, -73, -23, 14, 64, 104, 87, 105, 68, -54, -76, -1, -18, 12, 92, 23,
+ -79, -93, -105, -119, -64, -20, 39, 70, 2, -45, -52, -107, -82, 73, 106, 56,
+ 53, 12, -57, -37, 14, 52, 105, 101, 94, 85, -5, -75, -25, -1, -8, 59,
+ 52, -45, -89, -94, -117, -90, -42, 1, 53, 29, -29, -45, -79, -104, 3, 99,
+ 78, 63, 42, -25, -49, -7, 30, 83, 112, 103, 99, 40, -54, -58, -11, -7,
+ 36, 68, -4, -80, -98, -114, -106, -57, -15, 33, 42, -10, -46, -66, -97, -45,
+ 68, 90, 67, 53, 4, -40, -20, 18, 60, 103, 107, 100, 69, -15, -62, -31,
+ -9, 15, 60, 31, -50, -90, -108, -115, -79, -33, 11, 42, 15, -33, -58, -87,
+ -75, 21, 87, 79, 63, 27, -26, -33, 1, 40, 88, 111, 105, 85, 20, -50,
+ -49, -17, 5, 46, 49, -17, -77, -102, -115, -95, -49, -7, 31, 28, -15, -50,
+ -76, -84, -21, 64, 84, 71, 45, -4, -32, -13, 22, 66, 103, 108, 95, 50,
+ -23, -56, -32, -5, 30, 55, 14, -53, -92, -111, -107, -68, -24, 16, 34, 4,
+ -37, -66, -85, -53, 32, 81, 77, 58, 17, -25, -24, 6, 46, 89, 108, 101,
+ 71, 6, -49, -45, -16, 15, 49, 36, -26, -77, -103, -110, -85, -41, 0, 30,
+ 20, -21, -55, -79, -72, -5, 65, 81, 67, 36, -10, -28, -8, 27, 71, 102,
+ 104, 85, 34, -31, -51, -29, 1, 37, 48, 2, -57, -93, -109, -97, -58, -16,
+ 20, 28, -4, -42, -70, -79, -36, 39, 78, 74, 51, 9, -24, -18, 11, 51,
+ 91, 105, 94, 57, -6, -48, -41, -12, 22, 48, 26, -33, -79, -103, -104, -74,
+ -32, 6, 28, 12, -27, -60, -78, -59, 8, 66, 78, 62, 27, -13, -24, -3,
+ 33, 74, 100, 99, 74, 20, -35, -48, -25, 8, 40, 40, -7, -61, -94, -106,
+ -88, -49, -9, 21, 21, -11, -47, -72, -71, -22, 45, 76, 71, 43, 2, -22,
+ -13, 16, 56, 91, 101, 85, 43, -15, -47, -36, -6, 28, 45, 16, -38, -80,
+ -102, -97, -65, -24, 11, 25, 4, -33, -63, -75, -46, 18, 66, 75, 56, 19,
+ -15, -20, 2, 38, 77, 98, 93, 62, 8, -38, -44, -20, 14, 41, 32, -15,
+ -64, -94, -101, -79, -40, -2, 22, 15, -17, -52, -72, -61, -9, 49, 74, 66,
+ 36, -2, -21, -9, 22, 61, 91, 96, 76, 31, -22, -45, -32, 0, 32, 40,
+ 7, -43, -82, -99, -89, -56, -17, 14, 21, -2, -38, -65, -69, -33, 26, 66,
+ 71, 50, 13, -16, -16, 7, 43, 79, 95, 85, 50, -2, -40, -40, -14, 20,
+ 40, 24, -22, -66, -93, -95, -70, -32, 3, 21, 9, -23, -55, -70, -51, 1,
+ 52, 71, 60, 28, -6, -19, -4, 27, 64, 90, 91, 66, 19, -27, -43, -26,
+ 6, 34, 35, -1, -48, -83, -96, -81, -47, -10, 16, 17, -9, -43, -66, -62,
+ -22, 33, 66, 67, 43, 7, -16, -13, 12, 48, 80, 91, 77, 39, -10, -40,
+ -36, -8, 24, 38, 17, -28, -69, -92, -89, -62, -25, 7, 19, 4, -29, -58,
+ -67, -42, 10, 55, 70, 55, 22, -9, -17, 0, 33, 68, 90, 86, 57, 10,
+ -31, -41, -21, 12, 36, 30, -8, -53, -85, -94, -75, -41, -5, 17, 13, -15,
+ -48, -67, -57, -13, 39, 68, 64, 37, 3, -16, -9, 18, 54, 84, 91, 72,
+ 30, -17, -41, -33, -2, 28, 37, 10, -35, -74, -94, -86, -56, -19, 10, 17,
+ -2, -36, -63, -66, -34, 19, 60, 70, 51, 17, -11, -15, 5, 39, 74, 92,
+ 83, 49, 1, -36, -40, -16, 18, 37, 24, -17, -61, -90, -93, -70, -34, 1,
+ 18, 8, -22, -55, -69, -50, -2, 47, 70, 61, 31, -3, -17, -5, 26, 62,
+ 88, 90, 65, 19, -25, -42, -27, 5, 33, 33, 1, -45, -81, -95, -81, -48,
+ -11, 14, 15, -10, -43, -66, -61, -22, 31, 65, 68, 43, 9, -14, -11, 12,
+ 49, 80, 92, 76, 38, -10, -39, -36, -8, 24, 38, 16, -27, -70, -92, -89,
+ -61, -25, 7, 17, 3, -31, -59, -68, -39, 8, 55, 55, 19, 0, -9, -10,
+ -14, -13, -21, -30, -32, -44, -49, -57, -65, -72, -83, -98, -104, -117, -123, -128,
+ -127, -128, -128, -128, -128, -127, -128, -120, -117, -109, -100, -90, -83, -72, -66, -55,
+ -50, -33, -42, -18, -29, -18, 15, -6, 11, 7, 19, 3, 38, 5, 48, 44,
+ 64, 57, 97, 82, 111, 104, 110, 107, 120, 116, 125, 126, 126, 126, 126, 127,
+ 117, 125, 123, 100, 127, 101, 124, 102, 121, 109, 126, 96, 125, 116, 127, 90,
+ 119, 87, 127, 90, 118, 95, 123, 93, 106, 90, 100, 104, 74, 84, 73, 97,
+ 72, 71, 57, 66, 80, 36, 59, 38, 55, 35, 57, -6, 64, 10, 25, 19,
+ 19, -22, 65, -26, 14, 2, -17, -12, 22, -40, -3, -31, -24, -38, -1, -56,
+ -6, -48, -36, -54, -19, -56, -33, -49, -69, -49, -52, -53, -60, -61, -84, -76,
+ -85, -96, -95, -95, -114, -93, -117, -104, -93, -101, -98, -100, -101, -96, -78, -95,
+ -71, -70, -72, -52, -63, -70, -43, -77, -41, -48, -65, -53, -53, -59, -42, -56,
+ -37, -64, -54, -52, -50, -54, -56, -54, -55, -62, -51, -47, -44, -67, -60, -63,
+ -56, -64, -53, -48, -61, -53, -58, -38, -48, -32, -38, -34, -28, -26, -23, -25,
+ -22, -6, -7, -12, -1, 5, 6, 6, -7, 22, -4, 27, 15, 18, 24, 37,
+ 30, 47, 24, 53, 29, 63, 29, 46, 46, 51, 52, 53, 36, 54, 65, 55,
+ 33, 64, 36, 69, 54, 26, 62, 66, 36, 68, 30, 47, 54, 58, 20, 55,
+ 31, 40, 50, 35, 19, 56, 33, 25, 46, 18, 22, 42, 21, 25, 32, 19,
+ 19, 26, 18, 23, 29, 24, 7, 27, 6, 33, 8, 17, -2, 14, 3, 23,
+ 14, 7, 5, -9, -13, -10, -23, -12, -16, -27, -8, -18, -15, -3, -18, -24,
+ -5, -23, -9, 0, -11, 4, -1, 4, 2, 5, -2, 3, -1, -7, 4, -11,
+ 1, -12, -4, -7, -10, -11, -11, -16, -23, -15, -20, -22, -23, -20, -30, -23,
+ -31, -25, -32, -35, -41, -34, -44, -39, -34, -49, -33, -30, -36, -29, -33, -14,
+ -24, -32, -18, -15, -7, -9, -11, 5, -14, 27, -11, 16, -10, 13, -9, 23,
+ -10, 19, 10, 18, 11, 29, 1, 47, 27, -4, 45, 3, 43, 40, 14, 13,
+ 57, 16, 34, 27, 22, 30, 32, 14, 24, 27, 20, 20, 17, 4, 20, 20,
+ 8, 8, 0, 10, -3, 17, -8, -1, -4, 1, 0, 6, -7, -3, -3, -13,
+ -5, -6, -18, -5, -28, -12, -13, -5, -11, -5, -28, -7, -15, -10, -6, -28,
+ -16, -12, -17, -8, -10, -19, -10, -24, -30, -32, -26, -31, -36, -32, -33, -27,
+ -25, -26, -26, -25, -25, -23, -16, -22, -10, -11, -7, -7, 4, -10, 10, -9,
+ 11, -8, 4, -6, 4, -8, 3, -4, 2, -3, -5, -3, -11, -8, -6, -12,
+ -11, -7, -24, -4, -17, -9, -18, -28, -16, -29, -23, -38, -24, -34, -22, -38,
+ -18, -27, -10, -22, -19, -21, -2, -23, 10, -19, 0, 4, 16, 7, 0, 3,
+ 17, 14, 26, 8, 25, 27, 30, 25, 38, 31, 49, 37, 42, 45, 48, 55,
+ 63, 46, 54, 54, 56, 59, 56, 47, 50, 53, 47, 50, 44, 42, 35, 40,
+ 31, 37, 35, 27, 20, 23, 19, 26, 24, 18, 11, 14, 18, 24, 18, 12,
+ 10, 3, 12, 2, 9, 4, 0, 0, 3, -4, 11, 1, 1, -1, -5, -7,
+ 1, -6, -1, 2, -4, 1, -1, -7, -9, -11, -21, -19, -20, -28, -27, -22,
+ -29, -24, -26, -32, -22, -25, -31, -24, -19, -22, -11, -19, -15, -4, -5, -4,
+ 0, -6, -6, 2, -9, -5, -5, -9, -10, -7, -18, -8, -14, -14, -19, -29,
+ -25, -16, -25, -30, -30, -30, -21, -29, -38, -37, -36, -41, -44, -53, -48, -43,
+ -44, -55, -46, -40, -33, -36, -40, -40, -28, -25, -24, -23, -17, -15, 1, -3,
+ -1, 5, 2, 9, 1, 4, 12, 13, 14, 15, 9, 21, 26, 32, 31, 28,
+ 28, 41, 38, 49, 45, 46, 53, 56, 57, 57, 57, 58, 55, 48, 56, 56,
+ 56, 45, 39, 41, 41, 44, 42, 25, 28, 27, 24, 28, 21, 14, 17, 8,
+ 15, 22, 13, 15, 16, 3, 11, 10, 4, 6, 4, -8, 0, -2, -2, -3,
+ -2, 1, 3, -3, -3, -6, -8, -5, 4, 3, 2, -4, -2, -1, 5, 3,
+ -2, -2, -2, 3, 7, -2, -26, -37, -34, -30, -13, -14, -21, -24, -27, -24,
+ -13, -7, -15, 6, 3, -30, -50, -48, -47, -41, -26, -8, 28, 43, 38, 57,
+ 63, 56, 75, 118, 127, 117, 99, 86, 85, 66, 46, 59, 80, 69, 43, 27,
+ -6, -47, -74, -80, -71, -57, -40, -44, -56, -78, -88, -78, -59, -52, -51, -56,
+ -57, -47, -36, -36, -39, -39, -32, -17, 6, 24, 33, 10, -14, -14, -2, -11,
+ -20, -15, -24, -28, -28, -25, -28, -54, -73, -65, -43, -18, 6, 27, 21, 23,
+ 17, 22, 18, 16, 31, 50, 45, 25, 22, 8, -20, -17, 8, 29, 10, -22,
+ -41, -45, -51, -53, -31, -18, -23, -7, 37, 54, 38, 36, 60, 100, 119, 120,
+ 122, 125, 110, 88, 94, 99, 90, 85, 82, 54, 26, -5, -49, -83, -85, -67,
+ -36, -14, -30, -55, -76, -86, -65, -41, -45, -60, -53, -43, -35, -34, -41, -43,
+ -45, -35, 10, 40, 32, 3, -3, -14, -30, -38, -33, -23, -29, -26, -18, -10,
+ -17, -37, -46, -58, -61, -45, -17, -4, -2, 19, 31, 27, 13, 22, 38, 49,
+ 59, 69, 60, 23, -13, -11, 13, 24, 19, 24, 8, -30, -58, -58, -66, -85,
+ -90, -61, -19, -1, -11, -5, 25, 42, 61, 92, 109, 106, 110, 104, 93, 93,
+ 89, 82, 86, 81, 71, 51, 13, -40, -74, -87, -73, -35, -24, -50, -71, -73,
+ -53, -50, -58, -68, -60, -61, -54, -30, -25, -40, -52, -25, 13, 32, 45, 49,
+ 44, 28, 22, 29, 32, 20, 3, 7, 6, 0, -1, -4, -30, -63, -69, -62,
+ -57, -49, -25, 2, 17, 24, 27, 30, 10, 4, 38, 77, 66, 32, 13, 7,
+ 0, 9, 31, 43, 23, -11, -25, -23, -46, -83, -87, -63, -42, -19, -6, -3,
+ 6, 27, 49, 81, 108, 121, 123, 124, 115, 110, 98, 80, 78, 77, 77, 69,
+ 54, 8, -56, -99, -92, -53, -46, -64, -75, -73, -70, -75, -62, -67, -86, -88,
+ -54, -28, -33, -46, -50, -40, -24, -3, 29, 51, 48, 34, 44, 44, 30, 18,
+ 13, -3, -15, -7, -1, -10, -36, -56, -65, -79, -100, -91, -64, -52, -40, -5,
+ 20, 9, -14, -9, 21, 49, 59, 58, 49, 25, -1, 11, 39, 39, 22, 19,
+ 20, 8, -19, -49, -72, -69, -58, -43, -27, -24, -13, -5, 12, 38, 74, 97,
+ 110, 124, 126, 126, 114, 105, 100, 87, 91, 108, 115, 73, 5, -41, -49, -49,
+ -53, -45, -49, -69, -77, -60, -51, -71, -94, -96, -68, -49, -46, -44, -45, -60,
+ -60, -27, 0, 11, 26, 37, 37, 37, 40, 42, 34, 8, -1, 14, 15, -5,
+ -12, -18, -44, -75, -85, -88, -98, -99, -76, -36, -12, -19, -24, -11, -9, 1,
+ 36, 71, 58, 29, 13, 17, 33, 33, 30, 35, 44, 44, 27, -3, -39, -51,
+ -61, -55, -41, -31, -25, -29, -21, -1, 23, 46, 76, 102, 109, 110, 116, 118,
+ 92, 61, 76, 112, 120, 93, 57, 14, -28, -54, -50, -46, -60, -83, -82, -64,
+ -62, -82, -89, -93, -101, -88, -59, -52, -64, -75, -76, -63, -50, -30, -1, 9,
+ 8, 11, 32, 44, 36, 29, 32, 27, 20, 22, 28, 24, 0, -21, -30, -45,
+ -78, -97, -83, -66, -50, -32, -17, -16, -23, -20, 4, 38, 51, 47, 37, 28,
+ 29, 27, 27, 31, 42, 54, 55, 43, 20, -5, -29, -40, -37, -30, -27, -23,
+ -15, -12, -11, 8, 43, 67, 78, 100, 122, 126, 107, 84, 81, 92, 106, 115,
+ 110, 79, 31, -3, -13, -26, -47, -56, -56, -58, -58, -56, -59, -72, -86, -84,
+ -66, -57, -56, -56, -60, -74, -74, -51, -32, -24, -14, 3, 14, 15, 19, 28,
+ 33, 19, 11, 22, 29, 18, 8, 9, 0, 0, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -1,
+ -1, -1, -1, -1, -1, -1, -1, 0, -1, -3, -2, -1, 0, 2, -4, -13,
+ -21, -23, -19, -8, 7, 17, 23, 26, 33, 38, 32, 17, -5, -17, -24, -20,
+ -6, -3, -16, -29, -26, -17, -5, -1, 2, 7, 11, 17, 15, 9, 9, 3,
+ 10, 15, 9, -14, -33, -27, -18, -6, -7, -10, -6, 0, 12, 15, 29, 38,
+ 36, 32, 11, 0, -30, -45, -50, -39, -23, -27, -24, -15, 6, 25, 37, 51,
+ 46, 40, 0, -19, -22, -34, -30, -40, -45, -51, -34, -1, 25, 48, 40, 43,
+ 51, 64, 58, 5, -22, -49, -63, -69, -68, -58, -54, -16, 13, 44, 66, 61,
+ 68, 72, 86, 47, -17, -56, -82, -88, -93, -72, -58, -40, 4, 45, 94, 98,
+ 84, 65, 68, 71, 15, -46, -88, -90, -88, -85, -62, -56, -34, -4, 41, 80,
+ 82, 74, 54, 70, 66, 25, -29, -70, -74, -90, -87, -79, -73, -46, -10, 54,
+ 90, 103, 88, 76, 90, 69, 25, -38, -76, -96, -119, -111, -103, -81, -57, -12,
+ 50, 90, 113, 98, 100, 112, 103, 60, -11, -54, -95, -121, -124, -119, -95, -71,
+ -10, 53, 103, 116, 93, 91, 89, 80, 31, -28, -67, -108, -122, -128, -110, -87,
+ -53, 8, 60, 107, 107, 89, 83, 83, 76, 27, -14, -52, -84, -99, -103, -82,
+ -72, -40, 4, 53, 92, 92, 88, 85, 97, 87, 42, 3, -45, -74, -106, -111,
+ -105, -101, -70, -30, 27, 65, 77, 83, 87, 106, 90, 58, 16, -30, -67, -101,
+ -100, -101, -93, -68, -27, 29, 60, 77, 79, 93, 111, 96, 71, 24, -21, -73,
+ -109, -118, -127, -118, -98, -50, 6, 43, 65, 70, 99, 115, 108, 82, 40, -1,
+ -53, -80, -94, -105, -101, -82, -31, 18, 56, 66, 72, 95, 103, 97, 64, 29,
+ -15, -63, -85, -102, -105, -104, -81, -35, 13, 53, 58, 69, 86, 97, 94, 67,
+ 39, -12, -54, -80, -97, -102, -103, -77, -38, 9, 40, 45, 60, 77, 95, 88,
+ 70, 41, -8, -46, -74, -87, -99, -100, -78, -42, 10, 37, 50, 66, 89, 110,
+ 103, 91, 57, 9, -33, -68, -86, -105, -105, -89, -51, -2, 23, 40, 53, 80,
+ 99, 98, 89, 53, 8, -37, -68, -90, -107, -106, -94, -51, -5, 25, 43, 58,
+ 86, 95, 98, 86, 52, 9, -36, -64, -92, -105, -108, -95, -53, -11, 22, 37,
+ 57, 81, 90, 96, 82, 52, 6, -34, -64, -92, -104, -113, -97, -59, -18, 15,
+ 31, 58, 79, 92, 98, 87, 57, 9, -29, -63, -87, -100, -109, -91, -58, -13,
+ 16, 36, 62, 78, 93, 96, 88, 56, 12, -25, -62, -83, -101, -106, -89, -57,
+ -15, 6, 30, 52, 71, 87, 94, 89, 55, 18, -21, -55, -76, -96, -100, -88,
+ -53, -16, 6, 31, 53, 76, 93, 105, 98, 64, 26, -18, -52, -78, -99, -105,
+ -95, -59, -26, 0, 24, 45, 66, 81, 97, 88, 62, 28, -12, -40, -67, -84,
+ -95, -83, -50, -21, 4, 24, 47, 64, 81, 96, 85, 63, 26, -11, -41, -69,
+ -88, -102, -91, -64, -36, -12, 10, 34, 51, 74, 87, 81, 62, 26, -7, -40,
+ -63, -83, -95, -83, -58, -31, -10, 14, 34, 51, 75, 85, 82, 61, 30, -3,
+ -34, -57, -81, -92, -83, -60, -36, -15, 11, 27, 47, 69, 80, 79, 59, 30,
+ -5, -33, -57, -82, -93, -84, -61, -38, -15, 10, 25, 48, 68, 80, 77, 58,
+ 29, -4, -30, -56, -80, -89, -78, -54, -34, -8, 10, 0, 0, 1, 0, -2,
+ -2, -5, -8, -3, 3, -4, -10, 2, 8, 3, 4, 5, -3, -9, 10, 26,
+ 26, 12, -4, -40, -64, -50, 1, 55, 69, 28, -23, -65, -83, -52, 13, 67,
+ 67, 39, 16, -15, -48, -38, 10, 53, 44, 5, -5, -14, -43, -35, 16, 54,
+ 37, -1, -26, -53, -82, -37, 35, 67, 44, 2, -10, -20, -39, -19, 27, 55,
+ 42, 3, -26, -67, -107, -62, 43, 110, 102, 43, -18, -63, -91, -35, 73, 120,
+ 77, -6, -72, -113, -109, -36, 53, 78, 50, 0, -46, -72, -71, -20, 67, 112,
+ 100, 44, -24, -88, -123, -84, 5, 71, 97, 66, 7, -53, -100, -80, -1, 83,
+ 127, 108, 38, -57, -121, -119, -57, 24, 84, 97, 62, -4, -77, -97, -46, 32,
+ 101, 108, 56, -20, -103, -119, -69, 18, 105, 126, 90, 6, -92, -126, -90, -3,
+ 85, 108, 75, 0, -86, -117, -85, -6, 76, 115, 101, 30, -68, -118, -105, -33,
+ 57, 105, 102, 41, -46, -104, -112, -59, 25, 95, 121, 81, -5, -88, -126, -94,
+ -12, 63, 101, 76, 7, -67, -107, -73, 11, 94, 127, 102, 21, -74, -124, -95,
+ -21, 57, 101, 82, 21, -48, -89, -59, 6, 67, 95, 60, -11, -82, -115, -81,
+ -13, 52, 84, 52, -9, -68, -96, -56, 9, 66, 93, 63, 10, -52, -86, -54,
+ 1, 60, 96, 70, 19, -44, -80, -51, 0, 55, 94, 69, 20, -42, -88, -76,
+ -40, 24, 79, 72, 34, -28, -75, -63, -23, 35, 71, 48, 4, -57, -95, -67,
+ -10, 62, 103, 75, 18, -61, -110, -86, -22, 61, 110, 90, 37, -45, -100, -87,
+ -39, 34, 81, 70, 33, -39, -88, -76, -24, 54, 94, 76, 32, -46, -100, -92,
+ -42, 35, 73, 62, 26, -46, -97, -93, -44, 36, 81, 75, 35, -38, -87, -81,
+ -26, 58, 99, 85, 37, -44, -101, -103, -46, 47, 98, 97, 56, -27, -90, -99,
+ -49, 37, 88, 95, 62, -12, -74, -93, -51, 27, 69, 71, 35, -30, -78, -87,
+ -38, 41, 84, 90, 57, -11, -71, -96, -56, 21, 69, 86, 60, -4, -67, -97,
+ -61, 12, 65, 88, 65, 3, -61, -94, -60, 14, 71, 96, 68, 3, -66, -104,
+ -70, 3, 59, 84, 59, -1, -67, -107, -76, -3, 59, 89, 64, 3, -67, -111,
+ -82, -9, 57, 92, 76, 26, -43, -93, -71, -9, 50, 80, 64, 16, -51, -100,
+ -79, -17, 49, 88, 77, 30, -41, -95, -79, -17, 49, 87, 77, 34, -36, -92,
+ -78, -19, 44, 82, 73, 33, -37, -95, -84, -23, 47, 89, 83, 43, -30, -92,
+ -83, -28, 39, 79, 74, 40, -28, -87, -82, -31, 34, 71, 67, 35, -31, -88,
+ -85, -36, 28, 68, 69, 44, -20, -79, -83, -43, 19, 59, 64, 41, -25, -89,
+ -100, -61, 9, 60, 76, 57, -10, -75, -90, -51, 22, 74, 88, 66, 1, -61,
+ -78, -42, 25, 71, 84, 63, -1, -67, -90, -59, 8, 59, 81, 68, 8, -56,
+ -85, -62, 1, 50, 74, 63, 7, -53, -84, -60, 5, 55, 80, 70, 17, -43,
+ -76, -55, 4, 49, 73, 65, 17, -41, -77, -62, -9, 38, 68, 64, 17, -43,
+ -84, -73, -22, 23, 56, 57, 18, -36, -77, -68, -23, 20, 51, 52, 16, -36,
+ -77, -70, -26, 18, 54, 59, 28, -22, -64, -59, -20, 21, 56, 63, 36, -12,
+ -55, -52, -16, 25, 58, 63, 35, -14, -59, -57, -22, 18, 51, 57, 31, -16,
+ -58, -58, -27, 10, 43, 51, 30, -16, -59, -60, -28, 12, 48, 57, 35, -13,
+ -59, -64, -35, 7, 47, 63, 47, 1, -46, -55, -32, 7, 47, 0, 0, -1,
+ -1, -4, 1, -1, -3, -13, -8, -14, -3, -2, -2, 1, 8, 5, 7, -21,
+ -13, -2, -6, -8, -22, -6, 5, 11, 34, 41, 33, 13, 28, 33, 48, 35,
+ 21, -3, -26, -18, -10, 3, 7, 22, 21, 63, 40, 41, 43, 4, -8, -43,
+ -63, -77, -77, -59, -18, 3, 2, -21, -46, -74, -90, -108, -101, -94, -89, -84,
+ -85, -77, -59, -50, -33, -7, 18, 37, 47, 64, 101, 127, 125, 127, 126, 126,
+ 126, 122, 100, 87, 62, 37, 28, 27, 25, 27, 34, 25, -4, -45, -85, -123,
+ -128, -126, -128, -127, -123, -92, -73, -55, -45, -37, -33, -32, -33, -43, -53, -55,
+ -43, -20, 3, 20, 34, 42, 49, 55, 63, 74, 84, 93, 101, 107, 112, 117,
+ 109, 92, 63, 33, 8, -13, -25, -29, -30, -27, -27, -32, -46, -63, -82, -98,
+ -109, -116, -121, -118, -104, -80, -49, -12, 21, 45, 58, 64, 66, 66, 61, 51,
+ 44, 37, 32, 32, 33, 33, 28, 23, 15, 8, 3, 2, 9, 16, 20, 24,
+ 23, 14, -1, -20, -37, -48, -53, -52, -47, -38, -26, -13, -5, -1, -4, -10,
+ -22, -34, -43, -48, -46, -34, -16, 5, 25, 45, 65, 78, 84, 83, 71, 55,
+ 39, 24, 9, -3, -12, -23, -34, -45, -57, -65, -71, -71, -63, -49, -34, -21,
+ -11, -2, 2, 8, 11, 12, 14, 14, 20, 28, 38, 50, 58, 63, 61, 56,
+ 46, 33, 17, -1, -19, -34, -45, -48, -44, -32, -19, -5, 5, 7, 4, -2,
+ -7, -11, -15, -18, -21, -23, -26, -28, -30, -31, -29, -26, -20, -12, -1, 11,
+ 21, 32, 42, 51, 55, 55, 52, 46, 41, 37, 32, 30, 28, 27, 24, 19,
+ 12, -1, -21, -45, -67, -89, -103, -107, -101, -90, -70, -51, -33, -18, -2, 11,
+ 23, 33, 39, 44, 49, 52, 57, 59, 59, 56, 52, 48, 41, 35, 28, 20,
+ 15, 11, 4, 0, -5, -11, -18, -25, -34, -42, -47, -48, -46, -40, -33, -27,
+ -24, -21, -24, -32, -42, -51, -56, -58, -56, -47, -35, -18, 2, 24, 48, 70,
+ 88, 99, 104, 102, 97, 89, 79, 69, 59, 49, 37, 27, 14, 0, -14, -29,
+ -44, -58, -71, -81, -87, -88, -88, -85, -81, -77, -72, -63, -51, -37, -21, -5,
+ 12, 29, 43, 53, 59, 61, 57, 48, 36, 24, 13, 8, 8, 15, 25, 38,
+ 48, 54, 54, 50, 43, 33, 22, 11, 3, -6, -15, -25, -35, -46, -54, -61,
+ -65, -68, -69, -69, -68, -64, -59, -52, -43, -32, -20, -7, 6, 19, 31, 42,
+ 51, 58, 62, 64, 62, 58, 52, 44, 35, 26, 17, 9, 1, -5, -10, -15,
+ -18, -19, -20, -19, -18, -16, -15, -14, -14, -15, -16, -17, -18, -19, -19, -19,
+ -19, -18, -16, -14, -11, -9, -6, -3, 0, 3, 6, 10, 14, 18, 22, 27,
+ 32, 35, 37, 37, 35, 30, 23, 14, 4, -6, -15, -24, -31, -36, -39, -40,
+ -39, -37, -32, -26, -19, -10, -1, 8, 17, 24, 29, 32, 33, 32, 29, 25,
+ 20, 15, 11, 7, 3, -1, -5, -9, -14, -19, -24, -28, -31, -32, -31, -27,
+ -23, -16, -10, -3, 2, 7, 10, 12, 13, 13, 13, 12, 10, 8, 7, 5,
+ 5, 5, 5, 6, 8, 10, 13, 17, 20, 23, 25, 26, 25, 21, 16, 9,
+ 1, -7, -16, -24, -31, -37, -42, -47, -49, -51, -52, -51, -48, -43, -37, -30,
+ -20, -7, 6, 19, -1, -4, -4, 0, -1, -4, -3, 4, 4, -2, -3, 2,
+ 1, -4, 0, 5, 0, -4, 2, -10, -26, -29, -34, -49, -61, -44, -21, -8,
+ -3, -3, 1, 20, 32, 38, 32, 12, -4, 1, 14, 28, 51, 68, 78, 80,
+ 72, 38, 1, -6, 16, 23, 2, -14, -15, -20, -33, -62, -65, -37, -18, -27,
+ -29, -26, -45, -38, 8, 52, 55, 31, 26, 16, 17, 45, 80, 87, 77, 62,
+ 54, 24, -23, -50, -43, -28, -47, -72, -86, -86, -87, -61, -35, -38, -57, -69,
+ -55, -27, 1, 4, 22, 45, 54, 31, 0, -7, -5, -3, 0, -9, -21, -20,
+ -15, -27, -31, -10, 5, 9, 3, -21, -67, -83, -46, -3, 8, 18, 22, 4,
+ -3, 5, 35, 52, 67, 72, 83, 89, 71, 37, 19, 25, 8, -11, -37, -58,
+ -80, -85, -68, -33, -24, -57, -60, -34, -16, -14, 17, 73, 96, 77, 48, 17,
+ -7, -9, 4, -1, -3, 6, 3, -12, -10, 19, 33, 33, 41, 35, -29, -70,
+ -64, -38, -18, 3, 17, -5, -26, -35, -5, 31, 63, 73, 86, 94, 80, 64,
+ 50, 46, 37, 28, -2, -32, -65, -91, -84, -63, -59, -82, -97, -80, -66, -65,
+ -43, 8, 49, 60, 61, 42, 27, 23, 23, 14, 15, 18, 10, -12, -17, -9,
+ -13, 8, 35, 42, 2, -41, -76, -87, -67, -46, -31, -32, -45, -72, -53, -5,
+ 32, 46, 72, 92, 96, 92, 77, 75, 73, 61, 44, 12, -32, -68, -72, -54,
+ -58, -75, -85, -67, -57, -61, -60, -46, -11, 24, 35, 22, 15, 6, -1, -13,
+ 8, 23, 8, -1, -1, -6, -8, 35, 71, 86, 79, 50, -11, -46, -38, -31,
+ -29, -21, -30, -64, -68, -43, -12, 10, 28, 62, 89, 88, 84, 85, 90, 89,
+ 95, 83, 28, -32, -53, -36, -44, -62, -64, -55, -59, -54, -52, -48, -23, 19,
+ 48, 37, 39, 42, 31, 12, 19, 20, 5, 4, 1, -23, -40, -14, 14, 42,
+ 68, 64, 14, -33, -53, -52, -32, -18, -24, -43, -67, -62, -36, -18, -1, 25,
+ 54, 57, 58, 56, 54, 50, 66, 80, 44, -21, -50, -40, -52, -69, -77, -60,
+ -56, -54, -53, -62, -49, -9, 28, 41, 58, 58, 47, 43, 49, 41, 34, 37,
+ 18, -19, -44, -47, -36, 1, 35, 38, 19, -20, -62, -71, -59, -36, -34, -47,
+ -63, -63, -50, -38, -17, 7, 37, 56, 74, 80, 73, 61, 87, 116, 99, 47,
+ -7, -26, -22, -20, -32, -57, -72, -76, -76, -71, -47, -9, 13, 24, 29, 29,
+ 25, 27, 52, 68, 62, 9, -38, -67, -66, -39, -11, -4, -24, -37, -47, -51,
+ -49, -44, -55, -39, -6, -17, -52, -54, -19, 1, 15, 24, 31, 41, 55, 71,
+ 79, 89, 111, 115, 88, 54, 22, -2, -8, -5, -7, -27, -49, -57, -69, -72,
+ -64, -30, -3, 17, 31, 37, 29, 14, 39, 67, 73, 47, 10, -40, -72, -58,
+ -23, -12, -19, -19, -39, -49, -42, -46, -62, -44, -8, -11, -36, -51, -39, -15,
+ 0, 13, 21, 25, 40, 55, 63, 73, 95, 115, 115, 85, 53, 20, 2, -1,
+ -2, -10, -32, -48, -64, -73, -77, -62, -33, -9, 16, 33, 31, 18, 17, 44,
+ 67, 70, 49, 6, -45, -69, -53, -24, -13, -19, -24, -40, -47, -45, -50, -62,
+ -43, -10, -13, -37, -51, -39, -15, 0, -3, -1, 1, -1, -6, -6, -4, -1,
+ -2, -6, -8, -7, -4, -5, -10, -14, -16, -16, -16, -17, -18, -18, -17, -15,
+ -15, -16, -15, -13, -10, -9, -9, -11, -13, -14, -11, -9, -8, -9, -7, -3,
+ -2, -5, -8, -6, 1, 5, 4, 1, 0, 1, 4, 4, 4, 5, 7, 9,
+ 9, 8, 8, 9, 10, 9, 5, 2, 3, 5, 7, 7, 9, 11, 11, 12,
+ 14, 14, 12, 8, 7, 8, 5, 1, 3, 8, 9, 9, 10, 14, 16, 15,
+ 14, 12, 11, 9, 7, 3, -2, -3, 3, 5, 0, -5, -1, -1, -6, -10,
+ -16, -23, -28, -29, -32, -39, -36, -23, -16, -19, -19, -10, -7, -12, -11, -5,
+ -6, -11, -13, -11, -9, -8, -2, 6, 8, 8, 9, 6, 2, 4, 8, 9,
+ 4, 4, 12, 18, 17, 14, 17, 20, 20, 16, 9, 7, 7, 5, 3, 4,
+ 1, -2, 0, 3, 2, -1, 1, 3, 3, 1, 2, 2, 0, 3, 6, 9,
+ 8, 0, -5, -3, 7, 12, 8, -2, -2, 9, 10, 2, -3, 2, 5, 1,
+ -3, -5, -6, -2, -3, -11, -20, -26, -28, -30, -32, -37, -43, -45, -43, -40,
+ -42, -41, -31, -22, -20, -18, -16, -16, -19, -15, -8, -3, -3, 3, 17, 26,
+ 22, 16, 18, 23, 27, 26, 23, 17, 15, 21, 25, 24, 25, 31, 36, 32,
+ 29, 23, 17, 15, 11, 5, 1, 4, 6, 8, 6, 7, 8, 10, 14, 18,
+ 22, 20, 17, 14, 15, 13, 10, 15, 15, 12, 9, 10, 15, 14, 9, 3,
+ 6, 10, 5, -3, -9, -16, -16, -10, -11, -20, -24, -18, -20, -32, -42, -48,
+ -55, -70, -84, -95, -100, -92, -75, -65, -68, -67, -56, -55, -51, -41, -33, -37,
+ -42, -38, -33, -31, -26, -6, 19, 30, 25, 25, 28, 30, 27, 19, 16, 18,
+ 31, 44, 46, 48, 56, 71, 77, 74, 66, 54, 47, 37, 19, 3, 2, 3,
+ 3, 4, 13, 20, 21, 25, 24, 25, 19, 18, 19, 19, 14, 6, 17, 14,
+ 1, 3, 12, 27, 29, 25, 13, 14, 24, 22, 6, -7, -7, 0, 11, 12,
+ 1, 0, 10, 8, -13, -32, -46, -52, -57, -70, -88, -106, -101, -81, -74, -82,
+ -75, -49, -37, -42, -44, -42, -46, -51, -47, -40, -32, -27, -6, 3, 16, 32,
+ 29, 25, 24, 30, 54, 69, 74, 78, 90, 108, 118, 124, 117, 107, 102, 93,
+ 76, 61, 50, 41, 35, 31, 26, 13, 4, 0, -1, 0, -6, -12, -10, -8,
+ -4, 0, -3, -20, -31, -27, -18, -16, -22, -29, -28, -9, 0, -3, -1, 2,
+ 11, 20, 24, 18, 22, 34, 32, 16, -1, -18, -34, -46, -55, -67, -91, -102,
+ -91, -72, -73, -81, -68, -55, -55, -65, -74, -79, -87, -87, -83, -81, -77, -60,
+ -25, 4, 4, -3, 0, 13, 29, 29, 24, 23, 29, 51, 67, 72, 77, 88,
+ 105, 114, 122, 116, 106, 100, 93, 77, 63, 51, 42, 36, 31, 27, 15, 5,
+ 0, -1, 0, -4, -10, -9, -7, -3, 2, -1, -16, -28, -26, -16, -13, -18,
+ -25, -25, -8, 2, 1, 2, 5, 13, 21, 26, 20, 23, 35, 35, 20, 3,
+ -14, -32, -45, -54, -67, -91, -102, -90, -72, -75, -82, -68, -56, -56, -66, -75,
+ -81, -88, -88, -83, -82, -77, -59, -22, 4, 1, -1, -2, -3, -3, -1, -1,
+ -6, -8, -9, -12, -5, 6, 15, 21, 22, 21, 9, -8, -16, -23, -32, -22,
+ 4, 27, 32, 17, -2, -21, -34, -37, -30, -24, -3, 24, 47, 58, 50, 23,
+ -12, -41, -52, -47, -33, -2, 28, 48, 45, 28, 0, -36, -58, -53, -34, -4,
+ 26, 52, 75, 73, 45, -5, -66, -101, -90, -61, -14, 23, 59, 87, 89, 63,
+ 10, -46, -79, -80, -55, -23, -3, 27, 58, 62, 41, -6, -66, -92, -77, -29,
+ 19, 41, 65, 74, 69, 42, -9, -73, -109, -107, -67, -17, 23, 70, 104, 111,
+ 83, 21, -56, -104, -109, -62, -21, 4, 34, 68, 89, 75, 19, -46, -89, -85,
+ -38, -1, 23, 45, 64, 74, 62, 8, -53, -98, -93, -47, -9, 16, 36, 62,
+ 86, 78, 13, -67, -121, -109, -56, -9, 25, 58, 89, 109, 81, 8, -70, -119,
+ -106, -56, -7, 32, 63, 90, 108, 74, -3, -89, -128, -118, -70, -22, 23, 62,
+ 101, 126, 98, 26, -64, -117, -110, -72, -32, 6, 44, 93, 124, 100, 28, -63,
+ -116, -110, -71, -26, 16, 54, 101, 121, 92, 13, -86, -128, -120, -79, -28, 15,
+ 60, 111, 127, 95, 11, -83, -127, -116, -80, -29, 15, 67, 117, 127, 100, 17,
+ -75, -118, -108, -75, -31, 7, 60, 109, 123, 87, 3, -83, -118, -106, -67, -23,
+ 13, 62, 106, 119, 85, 3, -77, -106, -95, -61, -27, 2, 52, 103, 124, 97,
+ 19, -61, -95, -92, -63, -34, -4, 45, 94, 116, 87, 8, -63, -91, -85, -58,
+ -36, -9, 36, 81, 104, 76, 2, -60, -87, -77, -52, -32, -2, 48, 97, 119,
+ 86, 7, -59, -90, -85, -65, -50, -22, 26, 78, 107, 79, 11, -49, -78, -73,
+ -58, -46, -18, 31, 85, 112, 75, 1, -59, -84, -73, -55, -40, -12, 30, 80,
+ 106, 74, 10, -46, -70, -62, -49, -39, -13, 31, 86, 110, 74, 8, -49, -70,
+ -59, -46, -33, -6, 38, 92, 111, 76, 13, -42, -62, -56, -51, -44, -23, 19,
+ 75, 97, 67, 8, -44, -63, -58, -56, -48, -26, 19, 75, 94, 64, 8, -40,
+ -55, -50, -49, -42, -25, 18, 69, 85, 57, 4, -41, -54, -51, -50, -45, -28,
+ 18, 71, 88, 60, 8, -35, -46, -47, -48, -46, -30, 16, 66, 84, 59, 9,
+ -30, -41, -43, -42, -40, -22, 25, 73, 88, 60, 8, -30, -42, -46, -45, -42,
+ -21, 28, 74, 83, 52, -1, -36, -46, -45, -40, -37, -17, 26, 66, 73, 41,
+ -10, -42, -54, -53, -48, -43, -19, 27, 68, 76, 44, -4, -34, -44, -41, -37,
+ -33, -10, 34, 71, 75, 40, -7, -36, -47, -43, -39, -35, -9, 35, 72, 75,
+ 39, -7, -38, -49, -45, -43, -38, -11, 33, 68, 70, 36, -4, -31, -39, -36,
+ -35, -31, -5, 36, 69, 69, 35, -4, -31, -38, -35, -37, -33, -8, 31, 64,
+ 63, 31, -7, -34, -42, -40, -43, -38, -12, 28, 61, 59, 27, -10, -34, -40,
+ -38, -41, -35, -9, 31, 63, 60, 29, -6, -31, -37, -38, -42, -35, -10, 29,
+ 60, 56, 27, -8, -30, -33, -34, -38, -32, -10, 28, 56, 51, 23, -9, -29,
+ -32, -34, -38, -33, -10, 29, 55, 50, 23, -9, -28, -30, -33, -37, -32, -8,
+ 32, 56, 52, 23, 23, 0, -2, 0, -2, -6, -6, -6, -5, -2, -1, 5,
+ 15, 20, 11, 12, 12, 6, 0, -8, -19, -12, -4, -19, -19, -4, 4, -7,
+ -3, 5, 8, 11, 14, 9, 9, 8, -4, -11, -6, -8, -16, -14, -7, -1,
+ -3, 1, 10, 13, 24, 28, 12, 10, 14, 11, -14, -29, -19, -12, -21, -25,
+ -16, 2, 0, -11, -7, 7, 10, 0, 0, 5, 11, 6, 10, 21, 13, 7,
+ 14, 4, -4, -9, -5, -11, -16, -7, -3, 3, 15, -2, 2, 17, 6, -19,
+ -16, 3, 3, -14, -10, 7, 7, 4, 8, 11, 4, -5, -12, -9, -6, -14,
+ -13, -17, -13, -8, 5, 9, 3, 10, 12, 24, 28, 26, 35, 20, -3, 24,
+ 23, -19, -31, -23, -23, -38, -34, -18, -10, -8, -6, -4, -1, 5, -4, -8,
+ 2, 15, 12, 26, 56, 37, 10, 25, 25, -4, -21, -24, -23, -26, -30, -27,
+ -8, 10, -5, 3, 30, 6, -26, -7, 13, -2, -19, -2, 11, 3, 14, 21,
+ 8, 12, 5, -19, -26, -12, 9, 1, -8, -8, 20, 27, 17, 16, 15, 0,
+ 23, 39, 11, -4, -13, -21, -21, -32, -36, -27, -20, -24, -10, -4, 5, 14,
+ 4, -11, -10, 7, -8, -7, 7, 7, 2, 15, 29, 55, 26, 4, 22, 37,
+ 32, 14, 10, 18, 7, -1, -28, -49, -24, -14, -41, -53, -37, -28, -27, -15,
+ 1, 2, 14, 14, 13, 3, 0, 1, 18, 9, 7, 11, 23, 23, 25, 16,
+ -7, 1, 13, 26, 26, 9, 13, 28, 28, 1, -29, -29, -26, -27, -43, -43,
+ -31, -12, -26, -15, 6, 16, 6, 22, 11, -4, 0, 3, 0, -4, -20, -9,
+ 15, 23, 19, 7, 25, 19, 42, 63, 40, 13, 22, 24, 1, -41, -60, -55,
+ -63, -69, -61, -31, -7, 10, 8, 0, 7, 4, 4, 20, 5, -4, 9, 27,
+ 31, 27, 23, 13, 19, 12, 2, 4, 15, 20, 35, 19, 16, 26, 3, -30,
+ -48, -31, -40, -60, -59, -47, -13, -3, 12, 22, 11, 7, 9, 8, 3, -10,
+ -34, -5, 6, 24, 38, 19, 13, 21, 40, 15, 2, 27, 26, 16, 44, 47,
+ -7, -43, -41, -29, -44, -80, -81, -58, -26, -17, 3, 16, 30, 19, 10, 25,
+ 16, 6, -12, -3, 13, 30, 38, 20, 17, 22, 25, 18, 13, 16, -3, 1,
+ 32, 44, -11, -48, -51, -34, -38, -49, -64, -70, -23, -10, -14, -1, 20, 18,
+ 20, 21, 11, 3, -8, -3, 13, 14, 22, 18, 32, 37, 30, 25, 16, 27,
+ 27, 18, 37, 52, 12, -26, -56, -57, -46, -71, -92, -86, -50, -21, -10, 8,
+ 15, 15, 18, 28, 17, 1, 1, 2, 13, 13, 23, 23, 21, 29, 31, 29,
+ 15, 20, 33, 32, 29, 46, 21, -31, -49, -53, -51, -66, -82, -76, -54, -32,
+ -10, 12, 19, 29, 18, 3, 0, 16, 20, 29, 31, 20, 25, 31, 43, 41,
+ 34, 44, 27, 29, 65, 54, -15, -70, -79, -63, -86, -114, -114, -79, -26, -2,
+ 6, 18, 19, 10, 19, 26, 15, 5, 0, 16, 23, 29, 30, 21, 25, 28,
+ 37, 37, 38, 44, 32, 29, 66, 65, -7, -67, -74, -59, -82, -114, -117, -85,
+ -31, -2, 11, 20, 18, 9, 20, 30, 15, 5, 0, 0, 1, 1, 2, 3,
+ 3, 3, 4, 4, 5, 6, 6, 7, 8, 8, 7, 7, 7, 7, 7, 6,
+ 4, 3, 2, 0, -1, -2, -3, -5, -6, -8, -9, -9, -11, -12, -14, -15,
+ -17, -17, -17, -18, -19, -19, -19, -18, -17, -16, -15, -13, -11, -8, -7, -6,
+ -5, -3, -1, 0, 0, 1, 3, 5, 8, 10, 12, 14, 17, 19, 21, 23,
+ 26, 27, 28, 28, 28, 26, 25, 24, 23, 23, 21, 19, 18, 16, 15, 14,
+ 13, 12, 11, 11, 11, 10, 8, 6, 5, 5, 4, 2, 0, -2, -4, -5,
+ -7, -10, -11, -12, -13, -14, -15, -15, -15, -15, -15, -16, -17, -18, -18, -19,
+ -21, -23, -25, -27, -28, -29, -29, -30, -30, -29, -27, -25, -23, -22, -20, -18,
+ -16, -14, -13, -12, -11, -11, -10, -9, -8, -6, -5, -4, -3, -1, 1, 3,
+ 4, 6, 7, 8, 8, 9, 10, 11, 12, 13, 13, 13, 13, 15, 18, 21,
+ 23, 24, 25, 25, 28, 31, 33, 34, 34, 32, 31, 31, 31, 30, 27, 22,
+ 16, 12, 10, 9, 7, 3, -5, -13, -19, -22, -22, -23, -25, -28, -31, -33,
+ -33, -32, -32, -31, -32, -33, -32, -29, -25, -21, -19, -19, -19, -19, -18, -15,
+ -9, -3, 2, 6, 9, 12, 16, 21, 27, 32, 37, 39, 40, 40, 39, 39,
+ 40, 41, 40, 38, 35, 34, 34, 33, 29, 22, 16, 11, 10, 11, 12, 12,
+ 10, 8, 7, 5, 3, 2, 0, -6, -12, -19, -23, -23, -22, -23, -26, -30,
+ -33, -33, -33, -34, -35, -37, -40, -45, -50, -53, -52, -48, -42, -37, -32, -27,
+ -22, -20, -18, -16, -16, -18, -21, -26, -30, -33, -34, -35, -36, -38, -40, -41,
+ -41, -38, -36, -36, -38, -41, -40, -38, -34, -30, -27, -25, -22, -20, -16, -15,
+ -16, -17, -18, -16, -13, -10, -7, -4, -2, 1, 6, 11, 16, 21, 24, 25,
+ 26, 24, 22, 19, 18, 19, 22, 24, 26, 30, 33, 38, 44, 50, 56, 61,
+ 63, 68, 72, 74, 73, 68, 64, 57, 50, 47, 46, 44, 37, 21, 3, -11,
+ -20, -23, -25, -30, -33, -36, -36, -34, -31, -27, -22, -21, -22, -21, -18, -21,
+ -24, -27, -31, -33, -32, -27, -21, -14, -13, -17, -17, -10, 0, 10, 15, 16,
+ 14, 8, 6, 10, 16, 25, 34, 39, 43, 47, 53, 62, 72, 82, 89, 92,
+ 90, 84, 79, 77, 77, 76, 67, 54, 42, 33, 26, 18, 5, -11, -27, -41,
+ -53, -65, -73, -77, -79, -81, -86, -93, -102, -110, -116, -118, -120, -124, -127, -128,
+ -128, -126, -122, -116, -107, -96, -85, -78, -72, -64, -54, -45, -39, -40, -46, -49,
+ -49, -47, -45, -44, -45, -45, -44, -42, -38, -33, -29, -26, -23, -20, -18, -14,
+ -11, -8, -5, -2, 2, 7, 11, 10, 8, 7, 9, 16, 22, 26, 28, 31,
+ 34, 39, 44, 49, 53, 57, 60, 62, 63, 63, 65, 66, 63, 57, 51, 46,
+ 46, 50, 53, 54, 55, 54, 55, 57, 63, 69, 73, 75, 73, 69, 66, 64,
+ 65, 63, 55, 43, 30, 18, 11, 3, -6, -15, -23, -29, -32, -32, -28, -22,
+ -16, -13, -16, -16, -11, -2, 9, 15, 1, 0, 0, 0, -1, 0, -3, 0,
+ -1, 0, -18, 21, -22, 23, -41, 20, 84, -39, 50, -61, 26, -126, -19, -37,
+ 15, 2, 70, -33, 127, -55, 117, -73, 15, -45, -50, 8, -11, 23, 33, 1,
+ 26, -67, 26, -25, 14, -45, 57, -124, 12, -4, -23, 107, -54, 127, -49, 43,
+ 27, -59, -30, 15, -128, 5, -128, 86, -39, 82, 12, 62, 9, 51, -59, 53,
+ -95, 67, -92, 68, -28, 94, 21, 47, -11, -1, -41, 0, -25, -9, 18, -68,
+ 15, -27, 49, -27, 103, -4, 3, -36, 58, -98, 56, -116, -31, -123, 25, -58,
+ 89, -21, 110, -25, 73, -28, 39, -21, 35, -40, 37, -20, 50, 55, 51, 6,
+ 1, -47, -11, -32, -23, 38, -67, 3, -54, 34, -55, 79, 1, 32, -61, 89,
+ -86, 53, -67, -10, -128, -6, -68, 51, -4, 82, 15, 83, -16, 63, -24, 55,
+ -29, 8, 0, 6, 11, 54, 14, 16, -39, -9, -12, -47, 37, -40, -22, -60,
+ 21, -76, 51, -17, 74, -63, 98, -36, 44, -33, 24, -113, -37, -89, 20, -30,
+ 67, 18, 87, 0, 67, -6, 38, 1, -2, -18, -5, -20, 32, 17, 21, -8,
+ -30, 15, -47, 11, -17, 11, -97, 43, -87, 27, -36, 91, -41, 66, 3, 44,
+ -28, 55, -74, -37, -92, -21, -37, 33, -1, 75, 22, 36, 14, 26, 8, 8,
+ -12, -7, -21, -1, 27, 11, 21, -30, 21, -37, -3, -13, 23, -27, -32, -10,
+ -23, -44, 56, -1, 43, -12, 76, -29, 48, -9, -25, -71, -70, -48, -20, 2,
+ 9, 56, 8, 56, -10, 52, -12, 31, -29, 27, -60, 62, -42, 83, -45, 30,
+ -24, 4, -26, 33, -23, 5, -18, -25, -53, -7, -6, -6, 19, 16, 31, 3,
+ 58, -14, 0, -64, -33, -58, -8, -43, 42, -18, 57, -9, 54, 1, 47, -3,
+ 36, -18, 3, 4, 6, 2, -17, 8, -14, -27, 35, 2, -3, 1, -8, -43,
+ -34, -1, -22, 12, 2, 37, -6, 53, 14, 16, -43, -22, -75, -2, -67, 23,
+ -24, 39, -3, 39, 6, 44, 9, 37, 5, 1, 3, 5, 12, -18, 0, 0,
+ -31, 5, 23, 1, -3, 10, -20, -48, -6, -30, 7, -18, 35, -4, 32, 21,
+ 39, -26, -1, -75, -9, -65, -3, -28, 20, -5, 32, 5, 36, 20, 30, 30,
+ 3, 10, -1, 16, -10, -7, -1, -17, -23, 18, 14, -3, 8, 9, -45, -14,
+ -35, -1, -27, 18, -2, 29, 1, 61, -14, 20, -56, -19, -51, -22, -38, 9,
+ -14, 22, 5, 24, 27, 23, 41, 13, 20, -7, 23, -2, -8, -2, -9, -26,
+ -6, 14, 11, -11, 37, -33, -12, -38, -6, -33, 7, -14, 30, -12, 55, 4,
+ 33, -32, -14, -45, -22, -43, -7, -15, 18, 18, 33, 17, 41, 22, 15, 14,
+ 8, -24, -16, -18, -16, -7, 6, 16, -2, 8, -14, -6, -23, 0, -22, 1,
+ -23, 21, 4, 24, -1, 9, -9, -11, -14, -13, -16, -14, -15, -12, -16, -5,
+ 8, 28, 25, 28, 34, 27, 15, 16, 2, -20, -22, -20, -15, -8, 10, 11,
+ 7, -3, -5, -16, -10, -13, -5, -16, -5, 4, 17, 13, 6, 1, -9, -1,
+ -2, -3, -4, -4, -5, -5, -5, -5, -5, -5, -5, -5, -5, -5, -5, -6,
+ -6, -6, -6, -6, -5, -3, -3, -5, -5, -5, -7, -8, -5, 4, 5, 13,
+ 12, -12, -5, 10, 5, 4, 0, 3, 26, 33, 10, -15, -69, -89, -25, 25,
+ 58, 70, 22, -41, -62, -31, 18, 17, -17, -12, -9, 20, 99, 96, 0, -88,
+ -123, -69, 61, 116, 54, -11, -45, -28, 40, 38, -42, -59, -53, -31, 63, 78,
+ -9, -65, -83, -59, 48, 110, 50, -11, -51, -54, 41, 96, 9, -87, -119, -77,
+ 42, 118, 67, -18, -57, -46, 24, 89, 81, 22, -43, -77, -65, -41, -23, -3,
+ 4, 8, -13, -54, -52, -21, 30, 89, 86, 8, -49, -76, -56, 30, 55, 52,
+ 47, -7, -45, -49, -48, -10, 68, 74, 43, 22, -27, -25, 12, 20, -5, -43,
+ -69, -46, 21, 53, 51, 38, -8, -32, 6, 20, -1, -19, -56, -67, -26, 27,
+ 76, 95, 23, -64, -60, -15, 33, 39, -8, -37, -24, -7, 7, 4, -25, -23,
+ -10, -14, -7, -5, -12, 2, 28, 31, 37, 21, -18, -16, -4, -22, -37, -46,
+ -56, -8, 58, 64, 53, 31, -9, -9, -2, -57, -85, -52, -13, 59, 92, 21,
+ -42, -47, -33, 27, 75, 27, -22, -38, -44, 18, 77, 32, -21, -46, -50, 34,
+ 89, 22, -37, -60, -56, 31, 95, 36, -27, -57, -82, -15, 53, 15, -13, -25,
+ -44, 14, 66, 14, -32, -53, -62, 25, 96, 50, 3, -32, -56, 25, 98, 51,
+ -9, -56, -78, 7, 92, 71, 28, -31, -92, -42, 28, 20, 24, 8, -34, 22,
+ 70, 18, -17, -53, -88, -20, 39, 7, -2, -8, -28, 35, 80, 19, -23, -55,
+ -93, -22, 63, 54, 47, 19, -52, -35, 2, -36, -32, -18, -49, -9, 41, 15,
+ 26, 34, -22, -6, 31, 1, 8, 9, -43, -15, 30, -3, -1, -7, -73, -48,
+ 6, -14, 5, 13, -47, -30, 12, -13, 6, 18, -37, -13, 39, 27, 45, 38,
+ -37, -32, 12, 3, 32, 46, -10, 6, 48, 16, 15, 15, -32, -2, 47, 24,
+ 26, 18, -51, -51, -15, -29, -1, 19, -28, -15, 21, 2, 18, 22, -34, -24,
+ 13, -3, 15, 14, -45, -34, 7, 10, 38, 31, -34, -30, 4, 5, 43, 61,
+ 13, 4, 6, -22, 4, 24, -13, -13, -10, -34, 0, 23, -16, -16, -13, -42,
+ -18, -4, -36, -17, 5, -10, 14, 22, -21, -22, -16, -37, -6, 20, -2, 17,
+ 36, 19, 43, 43, -9, -15, -12, -29, 6, 31, 6, 10, 7, -23, -2, 9,
+ -23, -15, -10, -26, 3, 20, -5, 1, 0, -22, 5, 22, -6, -8, -16, -37,
+ -5, 20, 2, 11, 6, -19, 11, 33, 12, 20, 16, -7, 20, 35, 11, 11,
+ -3, -28, 2, 19, -1, 3, -6, -29, -5, 2, -25, -17, -12, -16, 22, 34,
+ 3, -4, -21, -36, 4, 26, 8, -1, -30, -54, -23, -3, -11, 0, -12, -27,
+ 7, 24, 13, 19, -1, -21, 10, 27, 14, 17, 0, -14, 18, 33, 19, 14,
+ -17, -41, -10, 9, 2, 7, -14, -30, 4, 20, 9, 9, -15, -35, -3, 16,
+ 9, 0, -1, -2, -3, 4, 7, 4, -2, -3, 0, 3, -1, -1, 4, 5,
+ -2, -13, -9, 1, 4, 2, 1, 2, 2, -2, -8, -4, 0, 4, 4, -3,
+ -4, -3, 1, 2, -1, 3, 14, 1, -7, -12, -4, -2, 1, 1, 9, 5,
+ -6, -5, -2, -1, -1, 1, 14, 6, -6, -7, 3, 8, -2, -4, 13, 12,
+ -10, -17, -10, -5, -4, 2, 3, 7, -6, -6, -1, -1, -4, 1, 11, 6,
+ -6, -9, 10, 11, 3, 1, 14, 15, -12, -20, -12, -9, -15, -1, 7, 2,
+ -16, -7, 6, 0, -2, 10, 26, 17, -6, -11, 24, 21, 1, 0, 18, 15,
+ -17, -31, -28, -23, -14, 0, -4, 0, -16, -8, 8, -4, -3, 7, 15, 5,
+ -3, -3, 26, 25, 12, 8, 28, 17, -15, -28, -18, -17, -18, -7, -3, -7,
+ -20, 0, 7, 1, -9, 6, 9, -4, -9, 2, 15, 24, 34, 31, 10, -4,
+ -15, -29, -17, -21, -41, -40, -5, 19, -20, 3, 11, 33, 28, 21, 18, 15,
+ 16, 3, -1, 18, 17, 15, 1, -15, -10, -5, -14, -42, -48, -43, -26, 4,
+ -29, -14, -9, 32, 20, 12, 15, 21, 39, 24, 8, 26, 33, 6, -3, 0,
+ 1, -7, -16, -41, -44, -51, -34, -3, -6, -6, -19, 26, 10, 15, 35, 46,
+ 32, 20, 16, 23, 38, 15, -4, -10, 17, -6, -41, -48, -53, -70, -52, -9,
+ -9, -22, -15, 19, 24, 22, 30, 49, 34, 10, 1, 15, 33, 15, 1, 17,
+ 46, 12, -38, -59, -50, -57, -46, -13, -16, -30, -24, 26, 37, 33, 30, 45,
+ 40, 2, -11, 17, 41, 24, -4, 16, 48, 15, -38, -67, -64, -65, -46, -18,
+ -18, -35, -32, 35, 39, 37, 21, 45, 42, -2, -19, 14, 37, 22, 7, 24,
+ 40, 13, -42, -68, -63, -63, -38, -6, -12, -34, -25, 39, 43, 39, 17, 47,
+ 45, 3, -19, 21, 45, 25, 2, 21, 31, 0, -45, -71, -78, -83, -48, 2,
+ 7, -27, -32, 34, 45, 49, 23, 44, 36, 5, -5, 38, 60, 27, -13, 21,
+ 42, -13, -69, -81, -86, -79, -38, -9, -11, -41, -36, 38, 56, 45, 10, 43,
+ 43, 10, -6, 36, 57, 41, 10, 36, 46, -16, -67, -66, -71, -80, -44, -8,
+ -5, -29, -27, 30, 43, 46, 20, 52, 39, -9, -21, 40, 68, 42, -1, 20,
+ 32, -14, -70, -86, -94, -90, -45, -2, 0, -31, -17, 36, 47, 46, 18, 44,
+ 29, -2, -11, 46, 74, 51, 14, 36, 46, -15, -78, -87, -91, -89, -46, -12,
+ -11, -28, -5, 41, 46, 40, 17, 51, 33, -6, -13, 49, 75, 52, 15, 30,
+ 34, -21, -79, -88, -93, -88, -42, -9, -4, -25, -3, 36, 40, 34, 16, 44,
+ 23, -8, -10, 52, 83, 55, 17, 38, 31, -31, -82, -91, -93, -82, -39, -16,
+ -10, -25, 5, 33, 42, 32, 20, 54, 25, -9, -3, 59, 85, 63, 24, 37,
+ 24, -39, -86, -92, -97, -80, -34, -17, -15, -24, 10, 35, 45, 32, 16, 45,
+ 12, -23, -2, 62, 78, 53, 21, 37, 26, -39, -91, -95, -96, -77, -29, -16,
+ -16, -25, 10, -1, 0, 3, 21, -26, 18, -30, 32, -19, -15, -27, 2, 0,
+ 103, -84, -53, -52, 79, 51, 36, -69, -31, 48, 71, 33, -74, -64, 10, 51,
+ 49, -68, -91, -16, 30, 33, -31, -58, -42, 14, 24, -25, 23, -71, 79, -22,
+ 123, -74, 28, 28, 115, 99, -7, 9, -15, 72, 1, 16, -47, -5, -71, -18,
+ -75, -26, -71, -28, -56, -24, -57, -19, -33, -5, 7, -3, 14, -8, 82, 100,
+ 23, -32, -15, 80, 98, 68, -30, -21, 24, 71, 28, -41, -96, -22, 32, 37,
+ -57, -110, -67, 28, 35, -22, -112, -79, 13, 70, 27, -55, -63, 31, 95, 86,
+ -4, -40, 29, 110, 110, 28, -50, -12, 66, 80, 14, -87, -81, -7, 36, -5,
+ -95, -118, -42, 26, 8, -69, -121, -48, 37, 60, -6, -68, -29, 67, 104, 61,
+ -24, -17, 70, 123, 92, -5, -43, 23, 82, 67, -28, -96, -54, 18, 30, -39,
+ -115, -96, -7, 25, -13, -99, -101, -13, 52, 42, -35, -62, 9, 88, 93, 28,
+ -32, 15, 97, 118, 58, -29, -24, 51, 82, 39, -61, -88, -26, 28, 9, -70,
+ -117, -63, 7, 14, -46, -109, -71, 15, 55, 16, -51, -42, 43, 94, 75, 2,
+ -21, 48, 107, 101, 23, -36, 4, 65, 70, 1, -81, -69, -3, 26, -19, -94,
+ -106, -32, 14, -3, -74, -103, -37, 34, 46, -10, -56, -12, 66, 91, 49, -15,
+ 1, 74, 111, 76, -4, -28, 31, 72, 50, -33, -85, -43, 11, 15, -46, -106,
+ -80, -11, 13, -26, -92, -84, -8, 44, 29, -30, -48, 19, 80, 81, 26, -18,
+ 27, 91, 103, 49, -22, -10, 48, 68, 22, -60, -75, -22, 17, -5, -71, -105,
+ -54, 3, 3, -49, -98, -58, 14, 44, 11, -44, -27, 45, 85, 65, 5, -8,
+ 53, 100, 87, 21, -26, 11, 60, 56, -6, -74, -58, -4, 13, -25, -90, -91,
+ -29, 7, -12, -72, -90, -29, 32, 37, -10, -46, -2, 66, 83, 47, -8, 10,
+ 74, 101, 68, -3, -19, 31, 62, 38, -36, -77, -40, 6, 4, -49, -100, -72,
+ -12, 3, -31, -86, -73, -4, 37, 25, -28, -36, 25, 75, 74, 25, -9, 34,
+ 88, 94, 43, -16, -4, 47, 58, 15, -57, -69, -22, 6, -12, -73, -96, -50,
+ -4, -7, -53, -89, -49, 13, 36, 5, -37, -17, 47, 77, 59, 9, 2, 58,
+ 92, 79, 19, -17, 16, 54, 45, -13, -69, -52, -8, 3, -33, -85, -82, -29,
+ -2, -20, -68, -79, -23, 24, 29, -11, -34, 7, 61, 73, 41, 0, 22, 73,
+ 90, 58, 1, -9, 32, 52, 26, -36, -69, -35, -3, -7, -53, -90, -63, -16,
+ -7, -36, -78, -60, -4, 29, 16, -22, -23, 29, 68, 64, 26, 2, 42, 80,
+ 81, 38, -8, 5, 42, 44, 4, -53, -57, -21, -2, -22, -69, -83, -43, -10,
+ -15, -51, -77, -38, 11, 27, 3, -27, -5, 46, 68, 52, 13, 15, 58, 83,
+ 68, 19, -8, 21, 46, 32, -16, -60, -44, -12, -6, -36, -76, -74, -34, -10,
+ -20, -57, -73, -33, 12, 27, 3, -1, -6, -11, -3, 4, 0, -7, -8, 1,
+ 21, 14, 28, 33, 25, -1, 7, 4, -13, -21, -44, -29, -17, -31, -32, 2,
+ 0, -20, 4, 3, 4, 0, -2, -5, -4, -14, 3, 14, 9, 28, 34, 54,
+ 43, 54, 39, 19, 17, -1, 5, -23, -31, -25, -35, -46, -60, -29, -29, -13,
+ -37, -22, -16, -20, -27, -21, -6, -16, 8, -5, 15, 26, 69, 65, 74, 85,
+ 81, 76, 51, 22, -10, -10, -19, -3, -39, -73, -55, -36, -18, -45, -49, -45,
+ -52, -47, -74, -73, -56, -31, -15, -16, -5, 18, 65, 86, 108, 94, 97, 90,
+ 79, 54, 30, 19, 10, 25, -16, -34, -37, -9, -16, -35, -44, -60, -60, -50,
+ -62, -70, -66, -44, -34, -34, -29, -10, 23, 61, 85, 79, 75, 70, 61, 41,
+ 31, 7, 8, 3, -22, -42, -28, 0, -13, -29, -39, -52, -56, -55, -58, -60,
+ -57, -41, -35, -37, -19, 5, 35, 71, 87, 85, 97, 112, 97, 71, 56, 52,
+ 53, 43, 18, -7, -3, 10, 0, -17, -39, -55, -58, -64, -80, -106, -121, -112,
+ -110, -113, -105, -82, -51, -8, 16, 20, 45, 66, 66, 49, 46, 59, 75, 78,
+ 63, 62, 74, 80, 80, 69, 51, 27, 11, 0, -14, -40, -53, -48, -55, -68,
+ -71, -56, -34, -1, 14, 24, 49, 62, 59, 42, 34, 43, 47, 43, 26, 30,
+ 33, 38, 26, 4, -17, -41, -66, -81, -92, -112, -120, -115, -116, -128, -125, -103,
+ -71, -36, -11, 9, 33, 56, 59, 54, 61, 67, 77, 77, 77, 79, 74, 75,
+ 73, 55, 30, 10, -21, -38, -46, -61, -70, -67, -70, -81, -77, -64, -45, -23,
+ -4, 10, 30, 44, 44, 39, 42, 48, 51, 50, 51, 58, 58, 65, 65, 47,
+ 29, 12, -14, -31, -41, -53, -63, -60, -62, -64, -58, -44, -26, -11, 1, 10,
+ 20, 22, 17, 9, 5, 6, 6, 2, 4, 10, 10, 17, 19, 9, 7, -1,
+ -14, -18, -13, -14, -9, 1, 7, 12, 17, 23, 31, 35, 36, 35, 38, 31,
+ 21, 16, 3, 0, -8, -11, -11, -13, -19, -20, -23, -34, -39, -51, -69, -78,
+ -81, -83, -83, -78, -70, -60, -47, -34, -19, 2, 20, 39, 57, 60, 66, 67,
+ 63, 61, 53, 50, 51, 47, 37, 32, 23, 13, 6, -3, -17, -23, -28, -34,
+ -37, -35, -27, -15, -2, 4, 12, 23, 30, 44, 47, 43, 41, 35, 29, 22,
+ 15, 13, 14, 7, -1, -5, -11, -19, -20, -25, -37, -43, -41, -43, -47, -47,
+ -40, -29, -17, -7, 5, 13, 23, 38, 44, 37, 34, 31, 23, 17, 6, 1,
+ -2, -10, -20, -25, -35, -45, -50, -54, -64, -68, -65, -66, -65, -59, -47, -30,
+ -19, -7, 5, 14, 28, 48, 62, 66, 72, 75, 78, 76, 67, 60, 56, 46,
+ 32, 20, 9, -2, -10, -21, -35, -43, -44, -49, -56, -57, -51, -38, -25, -13,
+ -2, 9, 25, 42, 56, 59, 64, 65, 67, 65, 57, 52, 49, 41, 28, 18,
+ 8, -2, -10, 0, 8, 13, 21, 20, 20, 17, 10, 8, -2, -6, -17, -21,
+ -29, -23, -25, -14, -7, -2, 7, 10, 20, 21, 22, 23, 19, 14, 9, -2,
+ -6, -18, -20, -28, -25, -23, -18, -10, -3, 5, 9, 22, 17, 28, 22, 21,
+ 17, 11, 2, -8, -18, -23, -27, -26, -24, -19, -13, -6, 3, 9, 17, 20,
+ 28, 24, 25, 21, 13, 6, -5, -14, -21, -29, -29, -30, -23, -19, -7, -1,
+ 10, 18, 25, 29, 27, 28, 20, 17, 5, -7, -13, -26, -29, -30, -30, -27,
+ -20, -12, 0, 11, 19, 25, 27, 30, 26, 28, 19, 11, -2, -12, -24, -30,
+ -35, -34, -30, -24, -14, -2, 9, 18, 23, 28, 26, 33, 31, 29, 24, 12,
+ 5, -12, -23, -30, -37, -36, -36, -26, -19, -5, 5, 19, 22, 32, 32, 36,
+ 35, 26, 21, 3, -6, -22, -34, -41, -44, -38, -31, -18, -6, 6, 15, 23,
+ 32, 33, 39, 34, 31, 23, 10, -2, -21, -32, -44, -47, -45, -37, -23, -12,
+ 6, 13, 28, 30, 38, 40, 40, 38, 23, 17, -6, -15, -35, -42, -50, -49,
+ -41, -31, -14, 0, 14, 26, 35, 42, 45, 45, 40, 27, 18, -4, -14, -33,
+ -42, -54, -52, -47, -36, -21, -5, 13, 24, 39, 43, 52, 47, 42, 36, 20,
+ 7, -15, -32, -45, -55, -56, -54, -43, -27, -8, 12, 26, 38, 45, 50, 51,
+ 48, 40, 27, 9, -11, -30, -46, -58, -62, -58, -49, -31, -11, 9, 24, 41,
+ 45, 54, 53, 54, 45, 30, 14, -10, -27, -48, -58, -67, -64, -56, -35, -15,
+ 6, 24, 37, 45, 54, 56, 56, 49, 39, 18, 0, -26, -45, -60, -74, -70,
+ -63, -41, -23, 4, 21, 39, 48, 53, 61, 58, 59, 43, 29, 3, -20, -46,
+ -64, -77, -77, -69, -50, -27, 0, 20, 36, 49, 56, 64, 64, 63, 51, 34,
+ 6, -17, -46, -65, -79, -83, -76, -58, -33, -6, 17, 38, 49, 60, 67, 68,
+ 66, 53, 37, 13, -13, -38, -65, -79, -90, -82, -68, -41, -15, 14, 36, 52,
+ 63, 70, 73, 69, 62, 44, 19, -8, -38, -63, -83, -93, -90, -77, -49, -20,
+ 12, 34, 54, 65, 72, 75, 76, 65, 51, 26, -1, -33, -62, -86, -98, -96,
+ -86, -58, -29, 6, 32, 54, 66, 73, 79, 76, 73, 58, 36, 4, -27, -60,
+ -85, -101, -104, -92, -70, -36, -1, 31, 53, 70, 75, 81, 80, 78, 65, 41,
+ 15, -24, -56, -84, -105, -109, -101, -79, -46, -7, 25, 56, 65, 77, 82, 85,
+ 83, 69, 51, 19, -14, -50, -83, -103, -115, -107, -88, -55, -17, 21, 50, 67,
+ 81, 86, 89, 85, 79, 55, 28, -8, -46, -77, -103, -116, -117, -97, -67, -25,
+ 1, 39, 66, 81, 92, 96, 97, 90, 73, 45, 11, -27, -64, -97, -120, -128,
+ -117, -89, -49, -5, 35, 65, 81, 93, 98, 99, 91, 75, 46, 12, -27, 28,
+ -9, -42, -57, -50, -18, 33, 77, 77, 17, -64, -96, -55, 22, 73, 68, 17,
+ -43, -77, -67, -15, 59, 102, 79, 12, -48, -71, -57, -28, -3, 11, 10, -3,
+ -17, -4, 44, 88, 79, 10, -69, -103, -74, -6, 54, 75, 53, -4, -63, -80,
+ -38, 32, 73, 59, 7, -43, -67, -57, -18, 33, 71, 71, 24, -31, -47, -17,
+ 20, 23, -14, -58, -73, -47, 10, 73, 110, 93, 20, -62, -97, -68, -6, 43,
+ 54, 28, -13, -51, -65, -35, 26, 74, 69, 12, -50, -68, -37, 9, 37, 37,
+ 16, -12, -26, -7, 36, 65, 45, -19, -87, -112, -75, -7, 58, 97, 92, 41,
+ -30, -75, -62, -3, 49, 52, 7, -44, -63, -45, -6, 37, 60, 42, -5, -42,
+ -41, -3, 38, 41, 8, -33, -51, -38, 3, 54, 90, 79, 12, -76, -127, -106,
+ -29, 47, 78, 63, 23, -19, -36, -16, 24, 50, 35, -15, -59, -64, -27, 17,
+ 40, 35, 11, -20, -39, -26, 19, 63, 67, 14, -61, -97, -72, -5, 64, 101,
+ 87, 26, -49, -96, -86, -32, 24, 40, 17, -11, -17, -3, 24, 51, 55, 29,
+ -20, -66, -69, -23, 35, 55, 25, -26, -59, -55, -14, 44, 86, 80, 23, -56,
+ -105, -87, -19, 48, 79, 67, 27, -18, -46, -43, -14, 17, 16, -20, -54, -47,
+ 3, 59, 83, 66, 18, -35, -64, -54, -8, 44, 59, 18, -48, -87, -72, -16,
+ 49, 88, 84, 37, -31, -81, -79, -26, 33, 52, 29, -5, -19, -6, 20, 34,
+ 27, -5, -51, -84, -71, -9, 62, 95, 71, 12, -40, -58, -37, 8, 52, 63,
+ 22, -53, -103, -88, -23, 47, 80, 64, 24, -14, -33, -28, -3, 21, 18, -15,
+ -45, -39, 5, 57, 78, 54, -1, -60, -97, -89, -29, 50, 92, 67, 0, -53,
+ -57, -13, 38, 64, 52, 10, -44, -82, -76, -26, 28, 49, 32, 1, -14, -1,
+ 24, 40, 38, 9, -43, -87, -79, -13, 69, 110, 80, 4, -65, -90, -69, -21,
+ 32, 58, 39, -9, -48, -45, 0, 52, 69, 46, 5, -34, -57, -50, -14, 23,
+ 28, -8, -48, -48, 4, 71, 99, 69, 3, -63, -99, -88, -30, 46, 92, 78,
+ 16, -45, -66, -44, -6, 25, 34, 16, -24, -55, -43, 10, 67, 80, 37, -22,
+ -48, -29, 7, 30, 27, -5, -51, -84, -73, -11, 71, 116, 95, 27, -43, -84,
+ -84, -43, 18, 63, 60, 10, -44, -53, -9, 41, 49, 14, -31, -57, -50, -15,
+ 29, 61, 57, 14, -37, -51, -14, 38, 63, 47, -1, -61, -106, -105, -47, 44,
+ 115, 113, 42, -36, -64, -42, -2, 23, 20, -3, -28, -39, -21, 24, 64, 59,
+ 7, -48, -67, -47, -7, 36, 59, 47, 2, -55, -77, -31, 55, 111, 89, 7,
+ -75, -113, -96, -42, 21, 62, 64, 28, -13, -18, 17, 45, 28, -2, -7, -6,
+ -7, -7, -8, -8, -8, -8, -7, -6, -5, -4, -3, -3, -2, -2, -1, 0,
+ 1, 2, 4, 5, 6, 8, 9, 10, 11, 12, 13, 13, 14, 15, 16, 17,
+ 17, 17, 17, 17, 16, 16, 15, 15, 14, 14, 13, 12, 10, 10, 9, 8,
+ 7, 6, 5, 5, 4, 3, 2, 1, 0, -2, -3, -4, -5, -6, -7, -8,
+ -9, -10, -11, -12, -13, -13, -14, -14, -14, -14, -14, -15, -15, -15, -15, -16,
+ -16, -14, -14, -12, -10, -13, -10, -13, -7, -3, -5, -1, -1, -5, -5, 8,
+ 13, 10, 10, 15, 16, 17, 30, 34, 19, 17, 22, 29, 27, 22, 16, 1,
+ -3, 8, 18, 11, 6, 8, 8, 1, 6, 18, 5, -8, -4, 4, 5, 3,
+ 5, -3, -6, 12, 30, 23, 9, 5, 6, 9, 15, 27, 20, 2, 0, 10,
+ 17, 8, -1, -4, -8, -8, -3, -7, -19, -28, -24, -22, -31, -42, -47, -50,
+ -50, -42, -35, -35, -43, -41, -31, -27, -23, -17, -9, -7, 3, 26, 37, 38,
+ 37, 41, 39, 39, 49, 55, 50, 46, 53, 58, 51, 44, 36, 24, 9, 5,
+ 2, -12, -25, -28, -26, -33, -42, -44, -55, -66, -69, -62, -60, -65, -57, -42,
+ -33, -26, -15, -5, -6, 0, 15, 29, 34, 41, 55, 61, 62, 68, 71, 62,
+ 49, 49, 49, 39, 29, 24, 14, -2, -10, -16, -34, -56, -67, -70, -77, -83,
+ -85, -88, -93, -92, -79, -74, -78, -74, -61, -49, -41, -23, -9, -2, 11, 35,
+ 54, 56, 58, 64, 69, 73, 81, 91, 86, 77, 78, 77, 67, 50, 39, 24,
+ 6, -4, -10, -22, -41, -49, -52, -62, -73, -81, -87, -98, -97, -83, -74, -70,
+ -63, -46, -33, -23, -6, 9, 18, 26, 48, 69, 77, 85, 97, 106, 107, 111,
+ 114, 104, 89, 83, 84, 75, 60, 50, 34, 13, -5, -16, -34, -59, -74, -80,
+ -86, -95, -97, -96, -104, -104, -95, -86, -86, -82, -66, -49, -32, -11, 12, 26,
+ 36, 55, 73, 81, 84, 94, 104, 107, 114, 120, 116, 102, 92, 88, 73, 54,
+ 37, 21, 0, -16, -23, -37, -58, -76, -85, -94, -108, -114, -116, -120, -119, -106,
+ -89, -84, -78, -64, -49, -37, -21, 1, 13, 25, 46, 71, 88, 95, 105, 113,
+ 112, 113, 116, 112, 97, 91, 91, 83, 68, 51, 35, 11, -10, -23, -38, -60,
+ -80, -86, -93, -102, -107, -110, -116, -121, -114, -102, -98, -93, -77, -55, -38, -18,
+ 1, 13, 25, 46, 71, 88, 95, 105, 113, 112, 113, 116, 112, 97, 91, 91,
+ 83, 68, 51, 35, 11, -10, -23, -38, -60, -80, -86, -93, -102, -107, -110, -116,
+ -121, -114, -102, -98, -93, -77, -55, -38, -18, 1, -3, -7, -8, -3, 1, 0,
+ 3, -5, -9, -14, -15, -4, 0, 7, 12, 12, 11, 18, 16, 14, 14, 11,
+ 20, 14, 19, 7, 12, 8, 13, 8, 7, 9, 0, 9, -7, -4, -5, -8,
+ -7, -9, -7, -2, -7, -4, 1, 1, 0, -2, 3, 2, 1, 2, 1, -2,
+ -3, -7, -2, -2, -2, -5, -4, -4, -4, 3, 6, 8, 3, 0, -3, -2,
+ 3, 4, 3, 2, 2, -2, 1, 0, 2, 3, 9, 8, 2, -3, -4, -2,
+ 1, 4, 0, -2, 3, 1, 7, 1, -4, 0, 2, 3, 1, 1, 2, -5,
+ 3, -3, -4, -3, -8, 2, -7, 1, -3, -2, -5, -8, -7, -8, -7, -5,
+ -7, -4, -8, -10, -7, -8, -7, -5, 0, -2, 0, -2, -3, -3, -2, 0,
+ 1, 0, 1, 0, -3, -3, -5, -5, -9, -9, -13, -16, -21, -26, -25, -25,
+ -16, -16, -12, -13, -15, -9, 3, 25, 44, 66, 68, 66, 49, 17, 13, 18,
+ 41, 51, 40, 35, 25, 23, -2, -16, -28, -8, -4, -12, -18, -34, -29, -31,
+ -28, -18, -4, 2, 16, 13, 20, 9, 4, 2, -3, -4, -9, -9, -9, -8,
+ -9, -10, -13, -14, -15, -13, -4, 7, 13, 19, 18, 16, 9, 7, 4, 6,
+ 8, 7, 7, 3, -3, -15, -19, -24, -21, -16, -9, 0, 3, 7, 4, 4,
+ -3, -2, 6, 13, 20, 14, 16, 14, 11, 7, 0, -4, -3, -3, -7, -12,
+ -12, -9, -5, -5, -7, -9, -4, -2, -2, -2, -4, -9, -10, -13, -13, -14,
+ -15, -13, -9, -8, -9, -9, -7, -4, 2, 2, 6, 9, 8, 11, 9, 11,
+ 9, 8, 6, 0, -7, -13, -21, -29, -36, -45, -53, -63, -72, -73, -61, -41,
+ 0, 52, 98, 109, 81, 64, 54, 78, 77, 45, 39, 44, 25, 19, 6, -8,
+ 25, 30, 44, 62, 46, -20, -85, -89, -88, -47, -29, -30, 2, 11, 8, 12,
+ 24, 33, 29, 25, 22, 1, -15, -34, -37, -36, -41, -36, -28, -15, 2, 9,
+ 11, 14, 12, 8, 12, 17, 18, 19, 23, 20, 20, 20, 8, -5, -14, -15,
+ -15, -13, -13, -18, -19, -24, -29, -32, -31, -23, -12, -2, 12, 20, 23, 24,
+ 25, 20, 22, 18, 16, 14, 9, 7, 2, 1, -9, -10, -19, -15, -12, -13,
+ -8, -5, -4, -4, -7, -10, -12, -12, -16, -14, -8, -9, -13, -14, -18, -15,
+ -10, -5, -3, 3, 4, 6, 11, 13, 13, 16, 16, 16, 12, 6, -3, -10,
+ -16, -21, -28, -37, -48, -61, -77, -88, -87, -68, -34, 28, 92, 127, 99, 64,
+ 50, 72, 92, 55, 43, 51, 41, 32, 4, -8, -7, -17, -23, -31, -33, -35,
+ -32, -28, -23, -18, -12, -8, -4, -2, 0, 1, 2, 2, 3, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 3, 4, 6, 7, 7, 7, 8, 9, 9, 8,
+ 8, 9, 11, 14, 18, 22, 27, 32, 33, 30, 21, 6, -12, -30, -45, -54,
+ -56, -51, -41, -29, -17, -9, -3, 0, 1, 1, 1, 1, 1, 1, 1, 2,
+ 2, 3, 3, 3, 3, 3, 2, 3, 4, 5, 8, 9, 10, 9, 8, 7,
+ 7, 8, 10, 15, 20, 25, 30, 35, 39, 39, 32, 19, 0, -22, -42, -56,
+ -62, -61, -53, -40, -27, -15, -7, -3, -1, 0, 0, 0, 0, 2, 3, 4,
+ 5, 5, 5, 4, 2, 0, -1, 0, 2, 5, 8, 9, 10, 10, 9, 9,
+ 8, 9, 10, 14, 19, 24, 28, 32, 34, 38, 36, 29, 17, -5, -28, -49,
+ -61, -65, -61, -52, -39, -25, -14, -7, -3, -2, -1, -2, -1, 0, 2, 4,
+ 6, 7, 7, 5, 3, 0, -1, -1, 0, 3, 7, 11, 13, 14, 13, 12,
+ 10, 8, 8, 9, 12, 17, 22, 26, 29, 31, 33, 31, 26, 18, 3, -16,
+ -35, -50, -59, -61, -56, -46, -35, -23, -14, -6, -2, 0, 1, 2, 3, 4,
+ 4, 5, 5, 5, 4, 2, 1, -1, -1, 0, 2, 5, 9, 12, 13, 13,
+ 12, 11, 9, 7, 7, 8, 11, 15, 20, 24, 29, 33, 35, 34, 30, 21,
+ 4, -16, -37, -55, -66, -68, -63, -50, -35, -21, -9, -1, 4, 5, 5, 4,
+ 4, 3, 3, 3, 3, 2, 2, 1, 0, -1, -1, 1, 6, 10, 13, 15,
+ 15, 13, 11, 8, 5, 4, 4, 7, 11, 17, 22, 27, 32, 36, 39, 39,
+ 36, 24, 6, -20, -48, -70, -81, -79, -67, -48, -29, -12, -1, 5, 7, 7,
+ 4, 2, 1, 1, 2, 2, 3, 2, 2, -1, -2, -3, -3, -1, 3, 8,
+ 13, 16, 17, 16, 12, 8, 3, -1, -3, -2, 2, 11, 21, 29, 36, 38,
+ 39, 42, 48, 57, 52, 23, -27, -76, -107, -113, -98, -71, -42, -18, -1, 8,
+ 12, 13, 10, 7, 3, 1, 1, 2, 3, 2, 1, 0, -2, -3, -3, -1,
+ 2, 8, 13, 17, 18, 17, 12, 7, 1, -3, -4, -3, 20, 30, 38, 41,
+ 39, 38, 46, 65, 75, 45, -23, -89, -126, -127, -101, -64, -31, -7, 5, 11,
+ 13, 14, 13, 9, 4, 1, 0, 1, 2, 1, -1, -3, -4, -4, -2, 2,
+ 6, 10, 14, 18, 18, 15, 9, 1, -6, -10, -13, -10, -4, 7, 20, 0,
+ 14, 19, 23, 26, 28, 28, 26, 23, 18, 11, 3, -4, -10, -16, -21, -23,
+ -24, -22, -20, -16, -12, -8, -3, 3, 8, 13, 19, 23, 26, 27, 26, 23,
+ 17, 10, 4, -3, -9, -15, -20, -24, -25, -25, -22, -17, -11, -3, 3, 9,
+ 14, 18, 20, 22, 23, 23, 21, 17, 13, 6, 1, -6, -11, -15, -18, -20,
+ -19, -19, -17, -16, -13, -11, -8, -5, -1, 2, 5, 7, 9, 9, 8, 6,
+ 3, 0, -3, -7, -10, -14, -17, -19, -19, -18, -16, -12, -7, -2, 3, 8,
+ 13, 16, 18, 19, 17, 14, 8, -1, -11, -21, -31, -38, -41, -40, -34, -25,
+ -12, 2, 17, 32, 45, 56, 62, 65, 63, 58, 49, 38, 25, 10, -6, -18,
+ -28, -37, -44, -51, -59, -64, -64, -56, -40, -17, 7, 29, 46, 56, 58, 59,
+ 56, 51, 45, 33, 19, 4, -13, -26, -39, -49, -56, -59, -55, -46, -34, -19,
+ -4, 10, 21, 30, 40, 46, 51, 52, 49, 43, 31, 18, 5, -8, -16, -21,
+ -23, -26, -29, -35, -39, -42, -40, -34, -22, -11, 2, 11, 18, 21, 24, 23,
+ 22, 19, 14, 7, -3, -13, -21, -30, -39, -46, -50, -52, -49, -42, -31, -17,
+ -3, 12, 26, 39, 49, 57, 60, 58, 51, 39, 22, 1, -23, -47, -68, -82,
+ -89, -88, -77, -60, -37, -11, 16, 43, 65, 83, 94, 100, 101, 96, 87, 71,
+ 51, 29, 4, -18, -38, -58, -75, -91, -104, -109, -105, -87, -61, -27, 8, 39,
+ 67, 87, 97, 97, 88, 71, 54, 36, 16, -2, -23, -42, -57, -70, -75, -75,
+ -71, -60, -43, -23, -1, 18, 31, 47, 57, 66, 71, 68, 61, 49, 32, 17,
+ 1, -11, -22, -33, -41, -47, -54, -59, -63, -62, -57, -46, -30, -12, 1, 17,
+ 30, 41, 49, 50, 47, 40, 29, 17, 3, -14, -30, -46, -60, -70, -76, -77,
+ -73, -63, -48, -28, -4, 20, 44, 65, 81, 91, 93, 88, 77, 60, 37, 11,
+ -19, -49, -76, -97, -109, -110, -100, -81, -56, -25, 7, 38, 67, 91, 109, 121,
+ 127, 126, 116, 96, 68, 38, 8, -18, -43, -68, -90, -110, -124, -127, -116, -91,
+ -59, -22, 14, 47, 77, 98, 107, 105, 93, 74, 54, 33, 13, -6, -26, -45,
+ -60, -71, -78, -79, -74, -61, -42, -21, 1, 18, 33, 49, 60, 68, 73, 70,
+ 62, 48, 32, 15, 0, -13, -24, -34, -42, -48, -55, -61, -65, -65, -60, -48,
+ -32, -15, 2, 19, 32, 43, 50, 51, 47, 40, 28, 16, 1, -14, 2, -2,
+ 2, -5, -3, -1, 0, -4, -4, -6, -4, -6, -4, -4, -7, -6, -7, -6,
+ -1, 0, 3, 13, 14, 16, 12, 13, 2, 1, 0, -1, -1, -1, -2, -2,
+ -2, -3, -3, -4, -8, -4, -4, -5, -5, -5, -7, -9, -12, -8, -14, -11,
+ -14, -18, -8, 1, 31, 71, 68, 24, -5, -11, -7, -5, -5, -5, -3, -2,
+ -5, -5, -9, -8, -7, -7, -9, -12, -11, -17, -14, -16, -15, -20, -26, -30,
+ -27, -15, 16, 51, 87, 101, 70, 8, -18, -11, -14, -7, -7, -1, -2, -5,
+ -7, -12, -14, -10, -10, -13, -14, -13, -16, -16, -17, -18, -35, -31, -30, -34,
+ -9, 16, 56, 84, 89, 60, 30, 5, -7, -5, -8, -3, -4, -4, -6, -12,
+ -14, -13, -10, -12, -12, -9, -10, -8, -12, -13, -15, -19, -23, -26, -33, -29,
+ -28, -9, 12, 43, 71, 88, 72, 48, 29, -2, -16, -19, -12, -12, -12, -7,
+ -11, -10, -10, -10, -11, -13, -15, -18, -19, -17, -16, -15, -13, -12, -13, -9,
+ -13, -17, -21, -18, 2, 34, 59, 87, 92, 98, 38, -30, -24, -27, -18, -16,
+ -11, -11, -13, -15, -12, -14, -15, -18, -17, -20, -18, -15, -10, -7, -3, -1,
+ 2, -8, -11, -22, -22, -20, 7, 31, 61, 97, 106, 43, -23, -28, -25, -20,
+ -12, -7, -5, -7, -10, -13, -13, -13, -11, -14, -15, -15, -12, -8, -7, -4,
+ -2, -4, -10, -15, -19, -26, -10, 12, 42, 72, 101, 90, 20, -25, -27, -22,
+ -18, -10, -6, -9, -11, -16, -17, -16, -14, -10, -8, -9, -9, -9, -9, -9,
+ -8, -5, -3, -6, -10, -17, -24, -21, 4, 30, 61, 84, 96, 79, -16, -38,
+ -27, -26, -17, -12, -8, -12, -13, -14, -14, -11, -8, -4, -4, -7, -9, -8,
+ -10, -12, -8, -5, -4, -7, -10, -18, -24, -11, 14, 42, 70, 79, 93, 36,
+ -32, -26, -28, -19, -15, -9, -9, -13, -16, -14, -12, -8, -5, -3, -7, -9,
+ -9, -9, -11, -8, -5, -1, -6, -9, -15, -24, -23, 6, 28, 63, 86, 127,
+ 37, -45, -27, -28, -26, -19, -4, -5, -8, -11, -12, -14, -12, -8, -4, -8,
+ -8, -10, -8, -13, -8, -8, -3, -8, -8, -16, -23, -17, 7, 34, 69, 83,
+ 113, 37, -50, -28, -25, -22, -16, 0, -3, -8, -12, -12, -14, -14, -10, -5,
+ -7, -6, -9, -9, -13, -9, -10, -7, -9, -9, -15, -20, -14, 8, 33, 64,
+ 81, 90, 57, -29, -28, 0, -4, 10, 10, 11, -15, 4, -1, 3, -11, 11,
+ 2, -12, 3, 18, -10, -62, 89, -16, -95, 118, -128, 122, -128, 112, -100, 109,
+ -121, 120, -104, 58, 10, -88, 127, -102, 6, 98, -126, 35, 89, -111, -7, 112,
+ -53, -94, 92, 64, -106, -53, 109, 52, -100, -75, 86, 95, -45, -119, -12, 111,
+ 74, -58, -118, -27, 97, 100, -4, -107, -95, 17, 109, 92, -4, -99, -109, -26,
+ 78, 115, 66, -27, -104, -109, -41, 55, 112, 98, 32, -53, -109, -105, -44, 41,
+ 102, 109, 67, -4, -74, -112, -102, -47, 27, 88, 112, 93, 45, -19, -78, -110,
+ -105, -65, -4, 59, 101, 110, 87, 43, -13, -67, -103, -111, -89, -44, 13, 65,
+ 100, 109, 93, 59, 14, -36, -78, -104, -108, -90, -53, -6, 43, 83, 104, 106,
+ 88, 57, 17, -27, -66, -95, -108, -102, -80, -44, -2, 41, 77, 99, 106, 98,
+ 77, 46, 10, -29, -64, -91, -105, -105, -91, -64, -29, 10, 48, 78, 98, 105,
+ 100, 84, 59, 30, -3, -36, -65, -88, -101, -105, -99, -83, -60, -32, -1, 30,
+ 58, 80, 96, 103, 102, 94, 80, 62, 40, 16, -10, -35, -58, -78, -92, -101,
+ -104, -100, -91, -77, -58, -36, -13, 12, 36, 57, 75, 89, 98, 102, 102, 97,
+ 88, 76, 61, 44, 25, 5, -15, -35, -54, -70, -84, -94, -101, -104, -103, -98,
+ -89, -77, -63, -46, -27, -8, 12, 31, 49, 65, 79, 90, 97, 102, 104, 102,
+ 97, 90, 81, 70, 57, 42, 27, 10, -7, -24, -40, -56, -70, -81, -91, -99,
+ -103, -105, -105, -101, -95, -87, -76, -63, -49, -34, -18, -1, 16, 32, 48, 62,
+ 74, 85, 93, 100, 104, 105, 105, 102, 97, 90, 82, 72, 61, 48, 35, 21,
+ 6, -9, -24, -38, -52, -65, -76, -86, -94, -101, -105, -108, -108, -106, -102, -96,
+ -87, -78, -66, -54, -40, -26, -11, 4, 19, 34, 48, 61, 73, 83, 92, 99,
+ 104, 107, 108, 108, 105, 101, 96, 89, 80, 70, 60, 48, 36, 22, 9, -5,
+ -19, -33, -46, -58, -69, -80, -89, -96, -102, -107, -109, -110, -110, -107, -102, -97,
+ -89, -80, -70, -59, -47, -33, -20, -6, 7, 19, 30, 41, 50, 58, 65, 71,
+ 75, 78, 79, 80, 79, 77, 74, 70, 65, 60, 54, 48, 42, 36, 29, 22,
+ 16, 10, 4, -2, -7, -12, -16, -19, -22, -24, -26, -27, -27, -27, -26, -25,
+ -23, -22, -19, -17, -14, -12, -10, -1, -1, -4, -9, -9, -7, -6, -7, -3,
+ 4, 8, 10, 11, 13, 10, 4, -3, -10, -15, -13, -9, -10, -11, -5, 4,
+ 12, 14, 12, 13, 14, 9, 1, -8, -15, -21, -23, -22, -13, -3, 7, 17,
+ 24, 27, 19, 11, 16, 15, -5, -24, -29, -23, -27, -32, -21, 5, 18, 20,
+ 21, 24, 24, 15, 11, 8, -6, -30, -31, -19, -17, -24, -14, 2, 17, 15,
+ 12, 17, 16, 19, 8, -5, -2, -1, -17, -17, -3, 6, 5, -4, 0, 1,
+ -12, -9, 9, 11, -4, -14, -8, 9, -2, -21, -14, 4, 9, 9, 11, 18,
+ 21, 10, 8, 16, 10, 26, 35, 6, -14, -28, -25, -24, -55, -65, -33, -17,
+ 1, -6, -6, 8, 23, 33, 49, 37, 19, 16, 11, 24, 42, 17, -37, -36,
+ 3, 7, -23, -36, -9, 9, -12, -20, -8, -2, -4, -23, -17, -6, 0, 10,
+ 24, 24, 40, 46, 33, 39, 26, 5, 6, 9, -12, -26, -33, -42, -61, -52,
+ -43, -37, -21, -4, 7, 13, 28, 36, 31, 24, 1, -1, 20, 24, 23, 21,
+ 26, 27, 8, -32, -44, -3, 28, -1, -36, -30, -6, 13, -12, -34, -18, -6,
+ 9, 21, 25, 16, 10, 38, 62, 46, 17, -11, -7, 10, -8, -44, -53, -33,
+ -35, -38, -29, -27, -16, 0, 1, 9, 37, 50, 36, 2, -20, -12, 15, 21,
+ 24, 32, 29, 20, 23, 12, -8, -3, 4, -10, -5, 2, -19, -63, -70, -21,
+ 20, 41, 23, 33, 57, 61, 42, 21, 15, 10, -45, -82, -60, -29, -44, -77,
+ -50, -7, 4, -4, 10, 32, 56, 42, 1, -10, -18, 2, 22, 28, 33, 42,
+ 47, 43, 47, 11, -23, 0, 10, -40, -81, -70, -28, -29, -68, -29, 19, 6,
+ 7, 21, 40, 41, 32, 22, 28, 47, 69, 66, 35, 21, 15, -3, -20, -34,
+ -24, -6, -19, -59, -47, -42, -35, -28, 15, 45, 51, 66, 78, 83, 37, 1,
+ 13, 7, -51, -81, -92, -83, -87, -74, -58, -73, -51, 12, 35, 26, 35, 47,
+ 69, 70, 63, 65, 49, 47, 68, 73, 52, 33, 15, -12, -30, -50, -51, -46,
+ -45, -60, -50, -50, -50, -54, -24, 38, 78, 90, 106, 99, 40, -6, -11, -46,
+ -110, -127, -107, -76, -67, -53, -41, -41, -23, 14, 33, 27, 34, 49, 70, 71,
+ 66, 65, 51, 51, 69, 72, 52, 32, 10, -12, 0, -5, -2, -5, 2, -29,
+ 22, 0, -27, 67, -59, 45, -13, -37, 28, 65, -4, 6, 60, 5, 58, 44,
+ 60, 27, 43, 96, 71, 81, 48, 96, 70, 23, 90, 66, 80, 88, 40, 20,
+ 61, 64, 12, 36, 24, 4, 7, 5, -27, -38, -26, -33, -49, -50, -70, -69,
+ -93, -92, -94, -104, -104, -101, -110, -107, -111, -111, -126, -87, -119, -100, -94, -112,
+ -93, -93, -80, -81, -76, -58, -56, -70, -30, -21, -42, -13, -3, 2, 8, 20,
+ 28, 41, 45, 59, 62, 69, 84, 85, 90, 103, 109, 111, 118, 121, 121, 123,
+ 121, 122, 121, 122, 121, 122, 121, 121, 120, 121, 120, 121, 120, 121, 120, 120,
+ 119, 120, 119, 120, 118, 105, 106, 110, 83, 89, 92, 75, 67, 61, 57, 47,
+ 40, 33, 24, 17, 10, 3, -2, -10, -20, -31, -31, -37, -49, -50, -63, -66,
+ -69, -74, -79, -91, -89, -92, -95, -102, -106, -104, -107, -113, -113, -110, -113, -116,
+ -114, -115, -114, -115, -114, -113, -114, -113, -114, -113, -112, -113, -109, -105, -111, -106,
+ -107, -103, -100, -103, -99, -97, -98, -99, -92, -92, -93, -92, -92, -90, -88, -90,
+ -88, -86, -89, -85, -85, -87, -85, -85, -82, -83, -82, -80, -78, -79, -76, -74,
+ -73, -73, -69, -68, -66, -64, -65, -62, -58, -56, -56, -52, -50, -47, -43, -42,
+ -39, -35, -33, -31, -27, -23, -21, -16, -16, -8, -7, -3, 1, 0, 10, 15,
+ 15, 19, 26, 29, 30, 38, 41, 42, 47, 54, 54, 57, 63, 68, 69, 72,
+ 77, 78, 80, 85, 84, 86, 87, 86, 87, 86, 85, 86, 85, 84, 85, 84,
+ 83, 84, 83, 82, 82, 83, 82, 81, 82, 81, 80, 81, 80, 79, 80, 79,
+ 79, 78, 79, 78, 78, 77, 74, 70, 66, 64, 61, 55, 52, 49, 45, 40,
+ 35, 32, 29, 24, 19, 15, 12, 8, 4, 0, -4, -8, -11, -15, -17, -20,
+ -25, -26, -29, -32, -34, -37, -39, -41, -43, -45, -46, -48, -49, -50, -50, -52,
+ -52, -53, -52, -53, -54, -53, -53, -52, -52, -51, -50, -50, -49, -48, -48, -46,
+ -45, -44, -42, -41, -40, -39, -37, -35, -34, -32, -30, -28, -27, -24, -23, -22,
+ -20, -19, -17, -15, -14, -13, -12, -10, -9, -8, -8, -6, -6, -5, -4, -4,
+ -3, -3, -2, -2, -1, -2, -1, -2, -1, -1, 0, -1, -1, 1, 0, 0,
+ -3, -1, 1, -4, -4, -3, -2, -5, -3, 0, -1, -1, -3, -1, 0, 2,
+ 0, -2, -5, 5, 4, 1, 7, 2, 2, 1, 8, 1, 6, 2, -4, 2,
+ 1, -4, 6, -8, -3, -7, -2, -6, -1, -9, 1, -2, -4, 1, 2, 1,
+ -2, 8, 2, 0, 14, 9, 10, 5, 3, 5, 6, 4, 3, -8, -2, -4,
+ -10, -1, -5, -3, -4, -6, -13, -5, -4, -4, -3, 2, -13, -6, 3, 6,
+ 6, 7, 1, 1, 6, 6, 16, 13, 9, 10, 9, 2, 7, 10, 4, -4,
+ -3, -17, -7, -6, -6, -10, -17, -17, -10, -11, -9, -5, -6, -8, 2, 1,
+ 8, 19, 15, 18, 24, 19, 16, 17, 19, 11, 7, 1, -5, -8, -9, -15,
+ -8, -9, -14, -20, -19, -9, -18, -10, -13, -23, -13, -12, -7, 0, -1, 5,
+ 16, 12, 28, 30, 32, 34, 34, 19, 24, 23, 16, 11, 5, -7, -19, -17,
+ -16, -21, -26, -23, -32, -31, -30, -25, -26, -24, -19, -13, -9, -1, 0, 4,
+ 6, 13, 15, 19, 17, 13, 8, 8, 8, 7, 0, -4, -8, -10, -7, -5,
+ -6, -6, -9, -12, -8, -10, -9, -9, -11, -13, -12, -9, -4, -1, 4, 9,
+ 19, 27, 31, 26, 16, 14, 16, 16, 12, 1, -8, -14, -11, -9, -6, -11,
+ -11, -12, -14, -10, -11, -13, -15, -19, -23, -19, -14, -8, -5, -1, 8, 34,
+ 62, 59, 12, 14, 32, 22, 6, 20, 6, -9, -54, -16, -1, -19, 7, -15,
+ -13, -12, -14, -15, -14, -22, -24, -30, -30, -20, -12, -6, 3, 26, 66, 88,
+ 39, 0, 47, 36, -2, 26, -23, 21, 13, -6, -60, -42, 6, -22, 4, -18,
+ -16, -4, -16, -19, -24, -39, -31, -25, -32, -26, -11, 12, 55, 104, 75, 10,
+ 35, 62, 9, 26, -16, -8, 19, 3, -9, -61, -46, 2, -26, -7, -16, -10,
+ 2, -7, -22, -23, -38, -40, -37, -44, -33, -8, 37, 101, 124, 36, -5, 89,
+ 20, 38, 5, -26, 3, 1, 5, -28, -65, -21, 1, -22, -12, -26, 1, -7,
+ -10, -24, -26, -33, -37, -48, -50, -36, 5, 63, 122, 109, 7, 35, 84, 5,
+ 59, -36, -4, -11, -1, -5, -40, -55, -4, -15, -21, -16, -22, 5, -10, -17,
+ -20, -27, -23, -44, -54, -62, -23, 29, 114, 127, 51, 7, -2, -4, -2, 4,
+ 11, 14, 10, 2, -7, -9, -9, -15, -16, -7, 3, 2, -10, -21, -17, 6,
+ 10, -8, -28, -11, 45, 66, 64, 47, 36, 49, 49, 27, 9, -12, -18, -25,
+ -30, -11, 0, -5, 0, -1, -18, -36, -33, -18, -10, -13, -31, -26, -25, -17,
+ 4, 28, 70, 89, 48, 9, -32, -58, -56, -70, -57, -17, -38, -48, -35, -32,
+ -7, 35, 38, 53, 62, 44, 33, 27, -6, -35, -52, -65, -54, -40, -43, -30,
+ -25, 2, 63, 54, 34, 17, 34, 70, 60, 8, -15, -3, 0, 39, 55, 35,
+ 39, 60, 75, 36, 20, -7, -25, -66, -110, -89, -89, -71, -36, -12, 9, 31,
+ 41, 54, 46, 45, 59, 41, 22, 3, -69, -110, -126, -116, -64, -15, 9, 29,
+ 33, 30, 56, 42, 12, 23, 6, -27, -36, -21, -22, -32, -21, -30, -29, -5,
+ 9, 16, 22, -9, -12, 31, 24, -17, -41, -23, 32, 32, 26, 34, 64, 66,
+ 109, 104, 51, 5, 12, 16, -36, -58, -59, -66, -63, -82, -64, -23, -9, 11,
+ 16, 20, 19, 13, 12, 33, 37, 41, 46, 28, 7, -58, -93, -79, -64, -33,
+ -1, 22, -4, 2, 19, 4, -7, -3, -3, 5, 1, -10, -3, 12, -6, -38,
+ -29, -17, -5, 11, 2, -33, -20, 44, 42, 20, -30, -24, 9, 44, 38, 20,
+ 36, 71, 61, 86, 72, 25, -8, 10, 17, -35, -54, -63, -67, -70, -78, -58,
+ -16, -7, 19, 22, 20, 21, 29, 21, 16, 35, 36, 16, -8, -27, -61, -58,
+ -67, -43, 3, 35, 38, -2, -2, 10, -9, -29, -14, -5, -1, -5, 2, 12,
+ -6, -32, -23, -22, -16, -5, 3, -9, -29, 27, 56, 39, 11, -27, -28, 23,
+ 34, 28, 18, 20, 62, 82, 71, 74, 24, -4, 16, 18, -39, -54, -65, -61,
+ -52, -64, -49, -11, -4, 12, 17, 16, 25, 24, 6, 23, 36, 18, 18, -1,
+ -42, -50, -90, -43, 3, 35, 38, -2, -2, 10, -9, -29, -14, -5, -1, -5,
+ 2, 12, -6, -32, -23, -22, -16, -5, 3, -9, -29, 27, 56, 39, 11, -27,
+ -28, 23, 34, 28, 18, 20, 62, 82, 71, 74, 24, -4, 16, 18, -39, -54,
+ -65, -61, -52, -64, -49, -11, -4, 12, 17, 16, 25, 24, 6, 23, 36, 18,
+ 18, -1, -42, -50, -90, -43, 0, 1, 6, -11, 19, -25, 24, -15, 11, -6,
+ 1, 9, -6, -3, 11, -18, 28, -23, 8, 6, -2, -1, 0, -5, 18, -23,
+ 24, -28, 27, -12, -1, -2, 6, 4, -14, 19, -29, 42, -40, 22, -6, -3,
+ 14, -16, 4, 8, -9, 13, -22, 17, 5, -24, 37, -34, 20, -4, -11, 19,
+ -20, 21, -16, 1, 17, -17, 5, -9, 25, -31, 31, -40, 32, -11, -7, 4,
+ -4, 13, -23, 29, -40, 51, -49, 20, 3, -20, 38, -47, 34, -21, 14, -9,
+ 4, -13, 20, -29, 37, -57, 59, -48, 23, -5, -7, 5, -6, -5, 13, -17,
+ 9, -4, -12, 22, -19, -8, 10, -5, -7, 8, -18, 19, -13, 5, -12, 6,
+ -10, 18, -40, 66, -91, 82, -56, 17, 19, -51, 56, -45, 30, -19, 5, -6,
+ 7, -9, -4, -2, -5, 13, -19, 1, 20, -28, 13, -6, 0, -17, 33, -48,
+ 38, -16, -20, 53, -75, 75, -61, 30, -12, -9, 2, 5, -9, -7, 15, -17,
+ 9, 4, -46, 70, -85, 86, -67, 29, 18, -60, 76, -70, 29, -8, -1, 1,
+ 14, -58, 93, -118, 127, -125, 85, -36, -2, 17, -39, 46, -61, 70, -99, 122,
+ -120, 56, 15, -85, 116, -101, 30, 43, -108, 127, -122, 72, -38, -3, 20, -31,
+ 29, -37, 42, -50, 63, -72, 40, -7, -46, 66, -82, 53, -25, 1, 1, -1,
+ -3, 3, -24, 24, -34, 27, -24, 36, -49, 37, -38, 35, -42, 13, -4, -14,
+ 14, -29, 42, -58, 58, -60, 41, -39, 27, -35, 27, -32, 25, -37, 43, -50,
+ 32, -20, -4, 4, -14, 16, -43, 66, -93, 79, -58, 27, -11, -21, 34, -40,
+ 24, -7, -25, 31, -29, 19, -18, -2, 1, -6, 4, -31, 47, -63, 62, -64,
+ 32, 2, -29, 23, -21, 19, -41, 59, -76, 62, -52, 26, -11, -1, -10, 6,
+ -10, -7, 17, -42, 34, -12, -34, 73, -106, 92, -61, 26, -24, 8, -7, -2,
+ 3, -24, 31, -44, 27, -9, -22, 38, -43, 15, -4, -3, -2, -12, 5, 1,
+ -7, 7, -25, 17, -17, 4, -15, 27, -40, 34, -18, 6, -13, 12, -3, -9,
+ -6, 8, -18, 18, -36, 54, -55, 30, -25, 26, -41, 38, -49, 48, -38, 8,
+ 16, -40, 47, -52, 34, -12, -4, 2, -13, 0, 1, 6, -11, 19, -25, 24,
+ -15, 11, -6, 1, 9, -6, -3, 11, -18, 28, -23, 8, 6, -2, -1, 0,
+ -5, 18, -23, 24, -28, 27, -12, -1, -2, 6, 4, -14, 19, -29, 42, -40,
+ 22, -6, -3, 14, -16, 4, 8, -9, 13, -22, 17, 5, -24, 37, -34, 20,
+ -4, -11, 19, -20, 21, -16, 1, 17, -17, 5, -9, 25, -31, 31, -40, 32,
+ -11, -7, 4, -4, 13, -23, 29, -40, 51, -49, 20, 3, -20, 38, -47, 34,
+ -21, 14, -9, 4, -13, 20, -29, 37, -57, 59, -48, 23, -5, -7, 5, -6,
+ -5, 13, -17, 9, -4, -12, 22, -19, -8, 10, -5, -7, 8, -18, 19, -13,
+ 5, -12, 6, -10, 18, -40, 66, -91, 82, -56, 17, 19, -51, 56, -45, 30,
+ -19, 5, -6, 7, -9, -4, -2, -5, 13, -19, 1, 20, -28, 13, -6, 0,
+ -17, 33, -48, 38, -16, -20, 53, -75, 75, -61, 30, -12, -9, 2, 5, -9,
+ -7, 15, -17, 9, 4, -46, 70, -85, 86, -67, 29, 18, -60, 76, -70, 29,
+ -8, -1, 1, 14, -58, 93, -118, 127, -125, 85, -36, -2, 17, -39, 46, -61,
+ 70, -99, 122, -120, 56, 15, -85, 116, -101, 30, 43, -108, 127, -122, 72, -38,
+ -3, 20, -31, 29, -37, 42, -50, 63, -72, 40, -7, -46, 66, -82, 53, -25,
+ 1, 1, -1, -3, 3, -24, 24, -34, 27, -24, 36, -49, 37, -38, 35, -42,
+ 13, -4, -14, 14, -29, 42, -58, 58, -60, 41, -39, 27, -35, 27, -32, 25,
+ -37, 43, -50, 32, -20, -4, 4, -14, 16, -43, 66, -93, 79, -58, 27, -11,
+ -21, 34, -40, 24, -7, -25, 31, -29, 19, -18, -2, 1, -6, 4, -31, 47,
+ -63, 62, -64, 32, 2, -29, 23, -21, 19, -41, 59, -76, 62, -52, 26, -11,
+ -1, -10, 6, -10, -7, 17, -42, 34, -12, -34, 73, -106, 92, -61, 26, -24,
+ 8, -7, -2, 3, -24, 31, -44, 27, -9, -22, 38, -43, 15, -4, -3, -2,
+ -12, 5, 1, -7, 7, -25, 17, -17, 4, -15, 27, -40, 34, -18, 6, -13,
+ 12, -3, -9, -6, 8, -18, 18, -36, 54, -55, 30, -25, 26, -41, 38, -49,
+ 48, -38, 8, 16, -40, 47, -52, 34, -12, -4, 2, -13, -1, -2, -1, -4,
+ -3, -25, -41, 8, 16, 27, 2, 16, 1, 13, 21, -8, -6, -29, 17, 8,
+ 8, 20, -13, 5, 4, 25, 17, 30, 22, 14, 15, 19, 7, 51, -16, -15,
+ -32, -13, 12, -8, -17, -49, -27, -29, -29, -52, -66, -55, -32, -20, -41, -21,
+ -36, -11, -16, 22, 3, 19, 0, -6, -10, 0, -38, -17, -35, -19, -27, 0,
+ -35, -27, -9, -17, -14, -2, 20, 50, 63, 57, 49, 70, 70, 97, 81, 68,
+ 52, 78, 93, 98, 102, 56, 34, 20, 53, 60, 45, 24, -18, 21, -10, 0,
+ -38, -79, -38, -37, -13, -27, -41, -50, -51, 14, 10, 16, -21, -13, -22, -20,
+ -48, -53, -55, -66, -76, -65, -91, -105, -92, -87, -101, -79, -56, -34, -7, -4,
+ 7, 20, 15, 26, 29, 32, -8, 36, 47, 50, 66, 29, 18, -33, -11, -4,
+ -10, -24, -42, -31, -22, 2, -23, -75, -34, -36, 5, 1, 1, -17, -47, 20,
+ 43, 68, 28, 30, 9, 29, 7, -9, -5, -32, -46, -36, -15, -40, -35, -15,
+ -26, -21, 2, 21, 49, 62, 83, 87, 106, 77, 97, 94, 67, 60, 85, 79,
+ 110, 80, 61, 1, 8, 16, 50, 36, 2, -22, 4, -2, 21, -35, -33, -19,
+ 4, 24, 19, 10, -58, -23, 18, 45, 34, 8, -12, -6, -5, -48, -51, -75,
+ -72, -77, -37, -65, -80, -57, -66, -68, -38, -38, 2, 10, 38, 31, 58, 22,
+ 39, 37, 27, -9, 23, 9, 35, 18, 15, -31, -50, -44, -5, 6, -10, -63,
+ -41, -56, -15, -41, -71, -45, -37, 7, -6, 5, -56, -71, -6, 21, 41, 8,
+ -13, -14, -40, -30, -41, -40, -56, -31, -31, -9, -15, -5, 10, 42, 27, 73,
+ 82, 73, 73, 79, 70, 38, 28, 31, 23, 45, 42, 44, 30, -40, 8, 28,
+ 52, 30, -18, -29, -40, -14, -45, -50, -55, -68, -39, -6, -29, -45, -59, -32,
+ 4, 31, 23, 16, 20, 11, -1, 1, -28, -45, -53, -56, -67, -60, -55, -40,
+ -31, -25, -16, 11, 20, 36, 67, 70, 75, 77, 81, 65, 46, 38, 34, 39,
+ 51, 44, 57, 7, -4, 13, 37, 46, 19, -8, -29, -1, -9, -21, -32, -43,
+ -55, -58, -40, -8, 15, 29, 38, 44, 59, 63, 51, 20, -20, -47, -61, -58,
+ -48, -42, -43, -35, -15, 15, 41, 55, 61, 62, 70, 67, 45, 11, -31, -62,
+ -80, -78, -71, -62, -54, -39, -15, 18, 50, 68, 79, 83, 92, 88, 57, 16,
+ -31, -71, -94, -95, -90, -83, -71, -55, -28, 7, 49, 77, 93, 100, 109, 107,
+ 78, 36, -20, -71, -99, -104, -100, -92, -83, -69, -43, -5, 42, 79, 100, 108,
+ 114, 112, 90, 51, -9, -65, -100, -110, -105, -95, -87, -76, -52, -11, 35, 75,
+ 100, 107, 111, 106, 90, 52, -4, -60, -97, -109, -99, -87, -80, -65, -35, 5,
+ 43, 75, 91, 95, 93, 87, 71, 31, -19, -64, -93, -99, -88, -76, -66, -44,
+ -9, 28, 59, 79, 84, 80, 71, 59, 35, -5, -45, -76, -96, -95, -77, -59,
+ -39, -9, 28, 61, 86, 98, 93, 74, 52, 28, -6, -43, -72, -94, -108, -99,
+ -77, -52, -20, 19, 56, 84, 106, 115, 106, 79, 45, 3, -40, -74, -93, -108,
+ -112, -100, -79, -46, -1, 45, 78, 100, 113, 118, 108, 81, 39, -19, -67, -93,
+ -103, -108, -104, -94, -74, -32, 19, 61, 88, 102, 108, 109, 100, 73, 21, -44,
+ -87, -102, -104, -97, -90, -78, -49, 0, 46, 78, 90, 92, 89, 87, 77, 43,
+ -15, -72, -101, -104, -93, -79, -69, -47, -3, 47, 84, 96, 89, 74, 65, 58,
+ 37, -7, -61, -99, -110, -101, -82, -62, -38, 2, 49, 92, 112, 106, 82, 59,
+ 41, 18, -19, -61, -95, -111, -110, -98, -74, -39, 6, 54, 99, 122, 123, 104,
+ 79, 50, 12, -32, -72, -100, -111, -110, -106, -90, -54, -4, 49, 99, 123, 126,
+ 113, 95, 69, 24, -27, -72, -102, -114, -109, -104, -94, -64, -16, 36, 87, 116,
+ 121, 111, 97, 76, 36, -15, -61, -94, -110, -108, -98, -86, -60, -19, 29, 77,
+ 104, 109, 99, 86, 67, 35, -7, -47, -82, -98, -101, -92, -77, -48, -14, 25,
+ 67, 92, 95, 83, 66, 45, 18, -9, -37, -62, -77, -81, -78, -54, -16, 0,
+ 0, 0, 12, -10, 16, -14, -18, 17, -31, -2, 3, -19, -8, 17, 28, 37,
+ 31, -1, -25, -16, -47, -13, -43, -22, 6, 34, 41, 49, 41, 27, 6, -33,
+ -62, -54, -59, -32, -13, 29, 53, 73, 60, 54, 16, -19, -58, -77, -89, -42,
+ -46, 17, 55, 78, 86, 81, 33, -3, -35, -84, -110, -75, -70, 0, 39, 78,
+ 92, 105, 70, 13, -15, -82, -107, -103, -84, -41, 20, 81, 85, 127, 86, 39,
+ -4, -63, -103, -99, -107, -69, 2, 68, 82, 127, 84, 58, 28, -44, -88, -104,
+ -108, -83, -13, 29, 69, 116, 87, 77, 40, -16, -65, -89, -104, -89, -40, -1,
+ 47, 96, 90, 85, 52, 9, -38, -62, -96, -95, -62, -22, 21, 73, 78, 86,
+ 65, 35, -15, -41, -80, -92, -69, -48, 1, 43, 65, 80, 73, 49, 8, -23,
+ -59, -75, -74, -60, -22, 17, 49, 69, 65, 60, 25, -1, -36, -59, -70, -61,
+ -40, -9, 30, 52, 57, 63, 37, 17, -12, -41, -61, -57, -50, -30, 9, 30,
+ 49, 60, 47, 28, 6, -20, -49, -51, -53, -42, -11, 13, 34, 53, 50, 34,
+ 18, -3, -35, -39, -52, -49, -23, 0, 18, 41, 47, 36, 31, 10, -21, -28,
+ -43, -49, -31, -13, 2, 28, 39, 35, 38, 19, -7, -18, -33, -42, -36, -26,
+ -12, 19, 30, 34, 36, 22, 6, -5, -25, -38, -36, -29, -17, 8, 19, 26,
+ 35, 28, 12, 3, -17, -30, -29, -29, -22, -3, 9, 19, 33, 26, 14, 8,
+ -9, -18, -22, -28, -25, -9, 3, 15, 22, 20, 18, 12, 1, -11, -22, -24,
+ -21, -13, -3, 8, 11, 20, 21, 12, 5, -6, -19, -16, -17, -17, -7, 3,
+ 8, 20, 17, 7, 7, -2, -11, -13, -16, -17, -5, 2, 5, 12, 13, 8,
+ 6, 3, -9, -11, -9, -14, -5, 1, -3, 6, 11, 6, 7, 2, -6, -4,
+ -4, -10, -6, -3, -4, 5, 8, 2, 5, 4, -2, 0, -3, -9, -4, -3,
+ -3, 2, 3, 0, 6, 4, 0, -1, -2, -2, 0, 0, 0, 12, -10, 16,
+ -14, -18, 17, -31, -2, 3, -19, -8, 17, 28, 37, 31, -1, -25, -16, -47,
+ -13, -43, -22, 6, 34, 41, 49, 41, 27, 6, -33, -62, -54, -59, -32, -13,
+ 29, 53, 73, 60, 54, 16, -19, -58, -77, -89, -42, -46, 17, 55, 78, 86,
+ 81, 33, -3, -35, -84, -110, -75, -70, 0, 39, 78, 92, 105, 70, 13, -15,
+ -82, -107, -103, -84, -41, 20, 81, 85, 127, 86, 39, -4, -63, -103, -99, -107,
+ -69, 2, 68, 82, 127, 84, 58, 28, -44, -88, -104, -108, -83, -13, 29, 69,
+ 116, 87, 77, 40, -16, -65, -89, -104, -89, -40, -1, 47, 96, 90, 85, 52,
+ 9, -38, -62, -96, -95, -62, -22, 21, 73, 78, 86, 65, 35, -15, -41, -80,
+ -92, -69, -48, 1, 43, 65, 80, 73, 49, 8, -23, -59, -75, -74, -60, -22,
+ 17, 49, 69, 65, 60, 25, -1, -36, -59, -70, -61, -40, -9, 30, 52, 57,
+ 63, 37, 17, -12, -41, -61, -57, -50, -30, 9, 30, 49, 60, 47, 28, 6,
+ -20, -49, -51, -53, -42, -11, 13, 34, 53, 50, 34, 18, -3, -35, -39, -52,
+ -49, -23, 0, 18, 41, 47, 36, 31, 10, -21, -28, -43, -49, -31, -13, 2,
+ 28, 39, 35, 38, 19, -7, -18, -33, -42, -36, -26, -12, 19, 30, 34, 36,
+ 22, 6, -5, -25, -38, -36, -29, -17, 8, 19, 26, 35, 28, 12, 3, -17,
+ -30, -29, -29, -22, -3, 9, 19, 33, 26, 14, 8, -9, -18, -22, -28, -25,
+ -9, 3, 15, 22, 20, 18, 12, 1, -11, -22, -24, -21, -13, -3, 8, 11,
+ 20, 21, 12, 5, -6, -19, -16, -17, -17, -7, 3, 8, 20, 17, 7, 7,
+ -2, -11, -13, -16, -17, -5, 2, 5, 12, 13, 8, 6, 3, -9, -11, -9,
+ -14, -5, 1, -3, 6, 11, 6, 7, 2, -6, -4, -4, -10, -6, -3, -4,
+ 5, 8, 2, 5, 4, -2, 0, -3, -9, -4, -3, -3, 2, 3, 0, 6,
+ 4, 0, -1, -2, -2, 0, -1, -1, -3, -7, -14, -23, -32, -45, -55, -66,
+ -74, -83, -88, -80, -77, -71, -64, -54, -46, -37, -31, -25, -19, -12, -6, -1,
+ 4, 8, 12, 17, 21, 23, 25, 25, 27, 29, 32, 35, 36, 34, 32, 31,
+ 32, 35, 37, 37, 35, 31, 29, 29, 31, 33, 34, 32, 29, 26, 25, 27,
+ 30, 32, 31, 29, 27, 27, 29, 31, 34, 35, 35, 35, 36, 38, 41, 43,
+ 45, 47, 49, 52, 55, 57, 59, 61, 63, 66, 69, 70, 70, 68, 66, 63,
+ 61, 58, 54, 47, 36, 24, 11, 1, -9, -20, -33, -48, -64, -78, -89, -97,
+ -103, -110, -116, -123, -128, -128, -126, -121, -116, -112, -107, -102, -95, -88, -78, -69,
+ -61, -54, -47, -41, -34, -27, -21, -16, -12, -7, -2, 2, 5, 6, 8, 10,
+ 13, 16, 19, 19, 19, 17, 18, 19, 22, 24, 24, 22, 19, 18, 19, 21,
+ 23, 24, 22, 19, 17, 18, 20, 22, 24, 24, 22, 21, 22, 24, 27, 29,
+ 30, 30, 31, 32, 35, 37, 40, 42, 45, 47, 50, 53, 56, 58, 60, 62,
+ 66, 68, 70, 69, 68, 65, 63, 61, 59, 54, 46, 36, 24, 13, -1, -14,
+ -28, -43, -57, -68, -78, -86, -94, -102, -109, -114, -117, -117, -115, -112, -109, -106,
+ -101, -96, -89, -81, -73, -67, -59, -53, -46, -40, -34, -28, -23, -18, -13, -9,
+ -5, -2, 0, 2, 5, 7, 10, 12, 14, 15, 15, 15, 16, 18, 19, 20,
+ 20, 19, 18, 18, 19, 21, 22, 22, 21, 20, 19, 21, 23, 24, 25, 25,
+ 25, 25, 26, 29, 31, 33, 34, 35, 36, 38, 40, 43, 46, 48, 51, 53,
+ 56, 59, 62, 65, 68, 71, 74, 77, 78, 79, 78, 77, 76, 74, 71, 66,
+ 58, 49, 39, 28, 17, 6, -6, -20, -35, -50, -64, -75, -85, -94, -102, -110,
+ -117, -122, -124, -123, -121, -118, -114, -110, -106, -99, -92, -84, -76, -69, -61, -55,
+ -48, -41, -34, -29, -23, -18, -13, -9, -5, -2, 0, -1, -1, 0, 2, 0,
+ 3, 2, 2, 4, 5, 4, 4, 4, 4, 5, 3, 4, 3, 1, 2, 0,
+ 0, -1, -3, -4, -2, -3, -5, -3, -4, -5, -5, -4, -3, -3, -6, -5,
+ -4, -2, -5, -5, -2, -3, -3, -3, 1, 4, 4, 8, 8, 8, 13, 12,
+ 13, 14, 12, 9, 8, 6, 6, 3, -2, -2, -5, -5, -4, -5, -11, -16,
+ -12, -7, -3, -5, -10, -11, -6, -2, -2, -1, -4, -6, -6, -7, -8, -5,
+ -2, 2, 5, 6, 8, 8, 9, 13, 16, 16, 14, 11, 7, 5, 4, 2,
+ 0, -2, -3, -3, 0, -3, -13, -28, -11, 7, -1, -15, -1, -5, -18, -10,
+ 6, 11, -11, -1, -10, -14, -13, -13, -4, 4, 6, 14, 13, 10, 10, 15,
+ 17, 24, 24, 13, 12, 10, 1, 0, 2, -4, 0, -6, 2, 7, -22, -68,
+ 2, 35, -40, 14, -24, -3, -10, -9, -20, -3, 28, 2, -9, -12, -28, -19,
+ -4, -1, 15, 17, 17, 16, 12, 16, 22, 25, 28, 6, 17, 9, -1, -2,
+ -3, 2, 12, -6, 6, -5, -35, -89, 32, 28, -39, 20, -36, 9, -20, -9,
+ -34, 3, 34, 8, -16, -11, -37, -15, -3, 0, 26, 18, 13, 15, 13, 25,
+ 27, 29, 20, 3, 21, 2, -2, 0, -8, 11, 16, -1, 8, -21, -76, -81,
+ 87, -25, 4, -4, -23, 6, -26, -20, -35, 23, 28, 0, -18, -16, -43, 2,
+ -9, 17, 25, 15, 9, 18, 17, 37, 28, 35, 3, 14, 12, -5, -1, -1,
+ -5, 27, 0, 16, -11, -49, -128, 36, 40, -36, 35, -41, 21, -27, -14, -45,
+ 4, 24, 20, -23, -6, -41, -9, -1, 6, 23, 19, 5, 15, 14, 33, 35,
+ 40, 16, 5, 16, -3, -5, 4, -12, 24, 10, 18, 1, -38, -128, -21, 72,
+ -50, 42, -38, 19, -16, -16, -43, -10, 21, 24, -22, -11, -30, -15, 6, 4,
+ 22, 18, 6, 11, 13, 27, 39, 42, 22, 4, -3, -2, -2, -5, -3, -5,
+ -3, -2, -6, -5, -5, -6, -5, -3, -5, -3, -5, -4, -6, -3, -1, -2,
+ -1, 0, -2, 1, 2, 1, 4, 4, 5, 5, 5, 8, 10, 11, 9, 10,
+ 11, 8, 5, 10, 7, 5, 5, 0, -3, 1, 0, -5, -2, -8, -9, -7,
+ -7, -5, -9, -11, -9, -8, -8, -7, -9, -7, -6, -7, -5, -6, -5, -3,
+ -3, -3, -4, -4, -2, 0, 1, 2, 5, 9, 12, 16, 19, 22, 22, 24,
+ 22, 22, 19, 13, 11, 7, 7, 4, -2, -7, -9, -9, -8, -10, -14, -14,
+ -15, -15, -13, -14, -17, -18, -14, -12, -12, -8, -9, -7, -6, -6, -6, -8,
+ -9, -9, -11, -13, -11, -6, -1, 3, 9, 20, 27, 33, 37, 46, 46, 42,
+ 37, 28, 21, 14, 11, 10, 14, 20, -2, -40, -47, -22, -5, -4, -1, 4,
+ -15, -53, -56, -7, -33, -14, -2, -19, -7, -8, -15, -6, -9, -8, -3, -9,
+ -15, -18, -26, -19, -6, -5, -6, 0, 12, 22, 29, 30, 28, 32, 29, 21,
+ 15, 13, 5, 5, 3, 19, 30, 3, -68, -26, 2, -17, 17, -12, 15, -1,
+ -12, -48, -43, -19, -1, 3, 6, -8, -4, -10, -10, -4, 0, -6, -1, -7,
+ -9, -17, -12, -6, -9, -14, -5, 14, 33, 33, 41, 32, 41, 35, 20, 10,
+ 8, 4, 10, -2, 36, 40, 3, -110, -8, -7, -6, 16, -18, 27, -2, -4,
+ -56, -57, -33, 16, -2, 12, -11, -5, -17, -9, -5, 10, -6, 0, -12, -11,
+ -20, -10, -8, -12, -17, -3, 17, 38, 34, 45, 36, 51, 37, 18, 4, -3,
+ 3, 8, 8, 54, 48, -34, -128, 28, -33, 28, -13, 1, 21, 3, -20, -59,
+ -65, -10, 17, -1, 7, -17, -10, -19, -8, 5, 11, -4, -2, -16, -17, -20,
+ -9, -11, -18, -11, 3, 31, 36, 41, 41, 44, 53, 30, 10, 1, -13, 12,
+ -5, 42, 63, 43, -127, -55, 19, -27, 28, -1, 0, 3, 5, 8, 12, 14,
+ 15, 15, 14, 12, 8, 5, 1, -3, -9, -14, -17, -19, -18, -16, -12, -8,
+ -5, -4, -2, -1, -1, -2, -3, -4, -3, -2, -1, -1, 0, 0, 0, 2,
+ 8, 12, 16, 19, 23, 26, 34, 40, 39, 28, 11, -8, -26, -36, -40, -39,
+ -35, -27, -19, -10, -5, -6, -10, -12, -15, -14, -12, -9, -5, -3, -1, 1,
+ 6, 8, 7, 7, 7, 8, 13, 20, 28, 35, 43, 48, 55, 57, 51, 32,
+ 3, -29, -56, -68, -67, -60, -46, -31, -17, -7, -4, -7, -11, -15, -16, -15,
+ -10, -5, -1, 1, 3, 5, 7, 9, 11, 12, 12, 10, 13, 19, 26, 36,
+ 43, 51, 58, 65, 61, 40, 6, -30, -60, -75, -73, -64, -49, -32, -16, -5,
+ -1, -4, -11, -18, -23, -23, -19, -12, -5, 2, 8, 12, 13, 11, 9, 8,
+ 8, 10, 15, 21, 27, 32, 37, 42, 49, 55, 63, 55, 32, -3, -39, -66,
+ -79, -73, -56, -39, -24, -12, -7, -7, -12, -19, -24, -24, -21, -14, -6, 3,
+ 8, 11, 12, 11, 10, 10, 10, 11, 14, 17, 21, 27, 33, 41, 49, 56,
+ 63, 66, 49, 15, -27, -61, -82, -85, -73, -52, -33, -18, -9, -5, -7, -12,
+ -18, -21, -20, -15, -9, -1, 4, 8, 12, 15, 15, 14, 11, 8, 7, 10,
+ 15, 22, 32, 45, 59, 72, 86, 95, 75, 22, -40, -93, -119, -120, -97, -64,
+ -32, -9, 5, 9, 5, -3, -14, -21, -23, -20, -13, -5, 4, 12, 17, 18,
+ 15, 10, 7, 4, 3, 6, 9, 15, 21, 30, 40, 56, 77, 99, 99, 54,
+ -19, -86, -123, -127, -103, -66, -27, 1, 16, 18, 11, -1, -12, -21, -23, -21,
+ -16, -8, 1, 9, 16, 19, 16, 11, 8, 5, 5, 7, 9, 14, 19, 27,
+ 35, 49, 68, 90, 101, 73, 6, -66, -114, -128, -113, -78, -39, -6, 13, 19,
+ 11, -1, 0, 10, 30, 35, 40, 39, 37, 28, 18, 6, -9, -20, -30, -35,
+ -33, -30, -28, -23, -24, -23, -19, -20, -15, -11, -8, -3, 0, 1, 0, -2,
+ -4, -1, 0, 10, 15, 21, 27, 25, 25, 22, 13, 10, -5, -9, -15, -19,
+ -17, -17, -12, -7, 0, 4, 10, 8, 5, -5, -13, -23, -31, -30, -24, -13,
+ 11, 36, 62, 81, 83, 78, 54, 35, 19, -11, -29, -49, -57, -47, -35, -20,
+ -19, -26, -27, -33, -30, -26, -22, -11, -8, 3, 11, 6, 0, -16, -23, -23,
+ -11, 9, 23, 35, 45, 51, 46, 49, 26, 12, -13, -26, -37, -45, -31, -35,
+ -17, -4, 8, 23, 24, 23, 9, -10, -22, -37, -40, -38, -33, -12, 22, 67,
+ 100, 119, 111, 79, 50, 10, -12, -32, -52, -69, -62, -38, -14, -9, -21, -42,
+ -60, -50, -39, -19, -4, -1, 3, 15, 19, 2, -16, -43, -57, -48, -21, 19,
+ 38, 63, 66, 69, 74, 59, 39, 4, -33, -52, -67, -58, -39, -25, 2, 10,
+ 32, 35, 36, 18, -7, -25, -37, -31, -28, -23, -10, 11, 53, 101, 121, 123,
+ 92, 48, 11, -24, -42, -60, -66, -67, -48, -20, 2, -16, -41, -67, -87, -62,
+ -44, -10, 8, 19, 30, 34, 35, 4, -36, -66, -78, -75, -27, 22, 49, 83,
+ 91, 97, 90, 69, 39, -18, -61, -104, -98, -75, -32, 19, 47, 68, 70, 56,
+ 16, -33, -77, -89, -76, -47, 7, 35, 64, 100, 123, 125, 107, 60, 5, -39,
+ -76, -94, -101, -93, -69, -36, -3, 17, 10, -15, -56, -80, -86, -69, -40, -7,
+ 25, 49, 66, 72, 54, 19, -19, -55, -77, -67, -40, 4, 45, 76, 96, 100,
+ 92, 67, 32, -11, -56, -88, -91, -73, -33, 9, 41, 61, 65, 52, 17, -28,
+ -67, -80, -68, -36, 6, 47, 82, 114, 126, 114, 74, 18, -32, -73, -93, -101,
+ -93, -70, -36, -3, 17, 10, -15, 0, -1, -2, -2, 0, 2, 3, 6, 7,
+ 6, 6, 3, 2, -1, -4, -8, -12, -14, -13, -13, -11, -5, -1, 5, 10,
+ 14, 17, 19, 18, 15, 12, 7, 3, 1, -2, -4, -4, -7, -11, -13, -16,
+ -16, -12, -9, -6, -3, -1, -1, -1, -4, -8, -11, -15, -16, -15, -10, -2,
+ 7, 18, 25, 28, 28, 24, 16, 10, 4, -2, -5, -5, -4, -4, -1, 0,
+ 0, 1, 1, 0, -1, -3, -6, -11, -11, -14, -16, -17, -19, -19, -16, -10,
+ -2, 8, 19, 27, 33, 35, 32, 26, 21, 14, 7, 0, -6, -11, -18, -25,
+ -31, -32, -27, -19, -9, 1, 10, 15, 14, 10, 0, -13, -28, -38, -42, -40,
+ -26, -4, 17, 40, 58, 66, 62, 51, 35, 17, 3, -8, -16, -18, -18, -15,
+ -13, -15, -17, -17, -15, -13, -11, -12, -3, -2, 1, -3, -15, -28, -36, -42,
+ -40, -28, -11, 14, 45, 63, 70, 69, 56, 44, 36, 21, 3, -12, -18, -26,
+ -37, -47, -58, -55, -41, -20, 4, 22, 34, 43, 37, 22, -7, -43, -71, -88,
+ -86, -64, -31, 7, 56, 99, 115, 106, 85, 48, 17, 1, -14, -28, -33, -20,
+ -11, -12, -18, -37, -44, -41, -29, -23, -7, 15, 31, 40, 33, 8, -27, -56,
+ -73, -74, -63, -33, 4, 50, 93, 101, 91, 79, 56, 43, 24, 5, -17, -32,
+ -31, -43, -56, -63, -72, -57, -32, 3, 26, 46, 62, 63, 45, 9, -39, -85,
+ -112, -106, -84, -49, 6, 60, 104, 127, 115, 83, 46, 16, -1, -16, -21, -26,
+ -16, -2, -8, -25, -47, -67, -62, -49, -26, 2, 34, 60, 74, 65, 33, -21,
+ -71, -98, -92, -77, -36, 21, 69, 106, 112, 88, 58, 29, 9, -8, -18, -24,
+ -17, -4, -10, -26, -47, -67, -62, -49, -26, 2, 34, 60, 74, 65, 33, 17,
+ 16, -38, 9, 40, -58, 27, 43, -80, 52, -2, -54, 64, -27, -17, 32, 4,
+ -49, 53, -22, -47, 90, -73, 17, 42, -45, 8, 23, -41, -1, 58, -74, 40,
+ 25, -66, 56, -19, -45, 58, -9, -39, 45, 3, -48, 55, -41, -27, 78, -66,
+ 13, 40, -38, 0, 29, -51, 12, 57, -79, 38, 31, -64, 40, -4, -47, 63,
+ -16, -40, 55, -16, -32, 45, -31, -29, 76, -64, 0, 58, -49, 4, 31, -52,
+ 31, 5, -35, 45, -21, 4, -5, 3, -17, -7, 55, -72, 43, 35, -88, 80,
+ -57, 3, 45, -62, 53, -14, -2, -17, 46, -77, 42, 23, -61, 75, -54, 39,
+ -40, 31, -42, 25, 11, -48, 93, -97, 62, -27, -13, 7, 0, 30, -59, 82,
+ -74, 28, 10, -53, 65, -47, 46, -41, 40, -48, 7, 45, -95, 127, -99, 43,
+ -9, -25, 40, -58, 84, -84, 78, -66, 11, 50, -96, 111, -85, 51, -26, -14,
+ 36, -60, 91, -84, 58, -26, -22, 56, -87, 98, -71, 47, -25, -11, 44, -84,
+ 103, -92, 69, -32, -3, 25, -59, 87, -90, 70, -45, 17, 16, -57, 81, -73,
+ 50, -33, 14, 0, -35, 75, -84, 69, -42, 8, 11, -46, 74, -69, 57, -47,
+ 36, -26, -20, 69, -89, 83, -58, 37, -24, -7, 41, -58, 54, -53, 53, -42,
+ 14, 28, -54, 52, -55, 46, -41, 22, 30, -57, 58, -64, 56, -54, 26, 31,
+ -55, 63, -73, 66, -68, 49, -3, -38, 61, -71, 75, -87, 69, -15, -27, 37,
+ -55, 74, -84, 73, -34, -5, 26, -59, 74, -85, 84, -33, -12, 30, -57, 65,
+ -85, 86, -40, 9, 15, -50, 69, -94, 93, -53, 15, 11, -38, 58, -86, 96,
+ -64, 11, 21, -30, 17, -3, -3, 0, 0, -3, -4, -4, -3, -4, -4, -5,
+ -6, -6, -8, -5, -6, -3, 0, 2, 4, 7, 8, 12, 12, 14, 13, 13,
+ 12, 8, 7, 2, 2, -4, -6, -10, -11, -12, -12, -14, -10, -9, -3, -3,
+ 2, 3, 3, 2, 1, 1, -3, -3, -4, -3, -3, -3, -4, 0, -3, -3,
+ -3, 0, -3, 0, -3, 0, 1, 0, 0, 0, 0, 0, -3, 1, -3, 1,
+ -3, 2, 1, 0, 0, -3, -4, -5, -9, -10, -15, -16, -17, -17, -14, -10,
+ -3, 4, 9, 14, 19, 24, 25, 26, 28, 30, 34, 42, 31, 9, -31, -39,
+ -23, -15, -17, -23, -30, -23, -12, -10, 4, 9, 19, 13, 14, 6, 0, -9,
+ -11, -12, -9, -8, 0, 0, 2, 1, 1, -3, -3, -5, -3, -5, -3, -4,
+ 0, -3, -4, -4, -3, -5, -3, -5, -3, 0, 3, 2, 7, 7, 7, 3,
+ 0, -14, -17, -26, -26, -28, -21, -17, -11, -10, 2, 6, 19, 18, 32, 32,
+ 60, 69, 98, 60, 7, -58, -8, -8, -14, -39, -30, -14, -47, -21, -45, -3,
+ 7, 20, 14, 31, 12, 10, -15, -5, -23, -14, -15, -4, -8, 2, 1, 7,
+ -3, 2, -8, -4, -6, -6, -3, 0, -6, -6, -8, -10, -11, -12, -9, -9,
+ -4, -3, 0, 8, 10, 12, 15, 13, 4, -10, -15, -30, -32, -30, -23, -22,
+ -19, -14, -4, 3, 10, 14, 26, 40, 70, 102, 127, 62, -17, -39, 9, -25,
+ -9, -87, -12, -16, 0, -30, -27, -19, -9, 6, 18, 21, 19, 6, 0, -9,
+ -17, -14, -16, -8, -6, 0, 4, 4, -5, -4, -11, -3, -6, 2, 2, 0,
+ -6, 0, -2, -4, -8, -14, -21, -25, -28, -32, -36, -40, -44, -48, -51, -55,
+ -59, -63, -67, -71, -74, -78, -82, -86, -90, -94, -98, -101, -84, -60, -38, -15,
+ 8, 28, 27, 23, 19, 16, 11, 21, 46, 68, 93, 109, 106, 102, 98, 95,
+ 91, 87, 83, 79, 75, 71, 67, 64, 60, 56, 52, 49, 45, 41, 37, 33,
+ 30, 26, 22, 18, 15, 11, 7, 3, -1, -5, -9, -13, -17, -20, -24, -28,
+ -32, -35, -39, -43, -47, -51, -54, -58, -62, -66, -69, -73, -77, -81, -85, -89,
+ -93, -97, -100, -105, -95, -70, -48, -23, -7, -10, -14, -17, -22, -18, 4, 26,
+ 50, 72, 96, 107, 103, 100, 96, 92, 88, 84, 80, 76, 72, 68, 64, 61,
+ 57, 53, 49, 46, 42, 38, 34, 30, 26, 23, 19, 15, 11, 8, 4, 0,
+ -4, -8, -11, -15, -19, -23, -27, -30, -35, -38, -43, -46, -51, -54, -58, -61,
+ -66, -56, -31, -9, 16, 33, 30, 26, 22, 18, 15, 11, 7, 3, -1, -5,
+ -9, -13, -16, -20, -24, -28, -32, -36, -40, -43, -48, -51, -55, -59, -63, -50,
+ -26, -4, 20, 42, 64, 67, 62, 59, 55, 51, 47, 43, 39, 35, 31, 27,
+ 23, 20, 16, 12, 8, 4, 0, -4, -7, -11, -15, -19, -22, -27, -17, 8,
+ 30, 55, 72, 69, 65, 61, 57, 54, 50, 46, 42, 38, 34, 30, 26, 22,
+ 18, 15, 11, 7, 3, 0, -4, -8, -12, -15, -19, -23, -27, -31, -35, -38,
+ -42, -46, -50, -54, -57, -61, -65, -69, -73, -77, -81, -85, -89, -92, -96, -100,
+ -100, -79, -64, -47, -31, -15, 0, 0, -4, -3, -6, -8, 6, 10, -8, -13,
+ 22, 55, 15, -58, -102, -88, -25, 51, 77, 79, 82, 19, -45, -107, -128, -88,
+ 19, 81, 86, 71, 35, -16, -50, -73, -55, -27, -14, 7, 77, 89, 31, -22,
+ -27, -61, -86, -34, 40, 55, 67, 80, 57, -1, -48, -60, -41, -46, -31, 28,
+ 62, 47, 43, 33, -5, -34, -45, -52, -33, 26, 66, 70, 41, 17, -34, -79,
+ -93, -41, -6, 22, 53, 93, 62, 17, -20, -66, -118, -88, -4, 45, 60, 69,
+ 67, 2, -72, -109, -95, -78, -7, 67, 101, 78, 69, 19, -56, -110, -89, -64,
+ -19, 45, 100, 86, 36, -11, -65, -107, -108, -41, 24, 69, 93, 111, 56, -15,
+ -70, -81, -88, -38, 30, 88, 90, 83, 43, -24, -81, -82, -57, -24, 38, 100,
+ 115, 70, 26, -25, -75, -108, -66, -20, 29, 71, 105, 67, 7, -46, -67, -83,
+ -60, 0, 58, 82, 81, 57, -9, -72, -99, -78, -60, -8, 54, 95, 69, 44,
+ 0, -51, -92, -69, -26, 18, 53, 81, 63, 6, -44, -74, -88, -79, -19, 40,
+ 75, 75, 72, 18, -42, -80, -74, -69, -25, 32, 76, 66, 39, 5, -41, -82,
+ -76, -34, 3, 42, 79, 88, 38, -12, -49, -74, -92, -48, 8, 51, 70, 83,
+ 50, -7, -58, -68, -65, -43, 13, 70, 82, 62, 34, -17, -72, -94, -65, -28,
+ 17, 69, 101, 71, 25, -21, -60, -88, -66, -13, 37, 62, 82, 68, 11, -47,
+ -73, -79, -66, -15, 49, 82, 76, 57, 11, -51, -88, -78, -48, -9, 49, 0,
+ 0, 0, 0, 0, 0, -3, -5, -5, -7, -6, -2, 5, 16, 24, 21, 17,
+ 12, 3, -10, -31, -44, -47, -42, -28, -2, 26, 29, 36, 35, 1, -26, -39,
+ -52, -53, -38, -10, -32, -41, -7, 2, 22, 65, 89, 74, 15, -16, -24, 12,
+ 62, 39, 6, -12, -3, 47, 48, 21, 109, 127, 119, 53, -9, 19, 9, -50,
+ -55, -43, -71, -46, -5, -2, -20, -12, -9, 12, -27, -66, -50, -8, -19, -58,
+ -22, -8, -19, -34, -42, 10, 32, -4, 4, 46, 96, 34, -51, -10, -8, -93,
+ -70, -58, -46, -16, -32, -30, 6, 7, -41, -29, 3, 25, 73, 67, 45, 37,
+ 30, 83, 0, -31, -4, -50, -28, -41, -75, -110, -53, -13, -3, 22, 14, 14,
+ 13, 7, 9, 38, 47, 39, 17, -8, 90, 75, -5, -29, -46, -54, -102, -66,
+ -35, -27, -29, -21, 32, 5, 1, 1, -2, 16, 16, 19, 30, 50, 89, 41,
+ 6, 40, -10, -15, -41, -46, -43, -77, -100, -100, -48, -37, -26, -4, -9, 0,
+ 13, 36, 70, 75, 59, 34, 12, -13, -27, 37, 71, 48, 53, 37, 7, 8,
+ 34, 48, 40, 31, 25, 2, -20, -15, -5, 12, -11, -49, -20, 15, -13, -42,
+ -29, 16, -6, -58, -28, 17, 12, -20, -11, 16, -3, -37, -14, 3, -32, -10,
+ 40, 54, 53, 27, -3, -5, -34, -47, -49, -90, -68, -36, -32, -31, -16, 26,
+ 3, 0, -2, -2, 15, 16, 19, 30, 51, 88, 40, 6, 39, -10, 3, -2,
+ 11, -7, 23, 19, 74, 39, 32, -13, -21, -7, -39, -44, -128, -58, -21, 52,
+ -86, -74, -94, 75, 61, 72, -38, 13, 59, 116, 71, -9, -33, -12, 68, -2,
+ -35, -128, -42, -43, 39, -78, -57, -81, 56, 59, 63, -13, 7, 69, 98, 87,
+ -13, -9, -24, 70, -11, -23, -128, -42, -48, 28, -68, -61, -69, 34, 64, 46,
+ 8, -5, 79, 82, 100, -17, 5, -29, 69, -13, -21, -122, -49, -43, 11, -55,
+ -72, -54, 13, 73, 30, 23, -16, 87, 72, 107, -17, 10, -26, 64, -6, -26,
+ -109, -61, -31, -6, -40, -86, -41, -4, 80, 17, 31, -22, 88, 70, 106, -10,
+ 6, -16, 53, 7, -37, -93, -76, -17, -21, -28, -99, -33, -15, 83, 12, 31,
+ -21, 83, 76, 98, 2, -4, -1, 41, 24, -49, -77, -89, -6, -31, -20, -106,
+ -32, -19, 79, 14, 23, -15, 71, 87, 87, 17, -16, 13, 30, 39, -57, -67,
+ -97, -1, -34, -19, -106, -38, -16, 69, 23, 11, -5, 56, 100, 75, 32, -28,
+ 25, 22, 50, -59, -62, -98, -2, -30, -24, -100, -52, -9, 55, 36, -4, 5,
+ 41, 112, 67, 43, -34, 30, 21, 55, -53, -65, -93, -11, -18, -34, -88, -69,
+ 0, 41, 48, -17, 12, 29, 118, 65, 49, -34, 28, 27, 53, -42, -72, -83,
+ -23, -6, -44, -77, -85, 5, -69, 1, -12, -29, -28, -13, 1, 9, -4, -27,
+ -18, -5, 11, 65, 87, 54, 59, 66, 30, 12, 8, -6, -7, 4, -7, -39,
+ -59, -63, -48, -23, -13, -6, 22, 61, 68, 15, -59, -87, -41, 3, 5, -10,
+ -17, -17, -20, -23, -20, -28, -17, -3, -10, -29, 23, 11, 25, 52, 56, 62,
+ 80, 54, 22, -15, -31, -38, -5, 11, -9, -7, -36, -44, -6, 52, 127, 26,
+ -68, -125, -105, 22, 15, -27, -27, 13, 25, 69, 28, -42, -77, -57, -70, 15,
+ 44, 14, 26, 57, 69, 43, 33, 41, 33, 32, 25, -50, -98, -100, -38, 24,
+ 7, -35, -38, -2, 76, 64, 15, -79, -93, -50, -12, 27, 45, 32, -4, 23,
+ 6, -36, -47, -33, -52, -15, 37, 78, 49, 40, 17, 14, 14, 70, 81, 60,
+ -3, -4, -12, -42, -50, -28, -20, 5, 9, 27, 46, -13, -69, -99, -88, -47,
+ 5, -4, -10, 17, 39, -12, -8, -21, -16, 22, 9, -9, 1, 15, 15, 33,
+ 29, 17, 11, 38, 72, 29, -8, -36, -27, -42, 17, -40, 25, 25, 8, -3,
+ 14, 15, 2, 43, 33, -2, -19, -24, -8, 2, -69, -114, -94, -77, -87, 22,
+ 27, 19, 24, 57, 121, 94, 40, -27, -29, 4, 28, -12, 5, -21, -28, -18,
+ 0, -9, 1, 36, 22, 7, 6, 12, 7, 8, 55, 6, -2, -7, -13, -12,
+ -12, -8, -5, -5, -1, -4, -4, -3, -1, 5, 11, 15, 18, 16, 11, 5,
+ -5, -12, -16, -17, -14, -10, -7, -3, -2, -3, -3, -5, -3, 2, 9, 18,
+ 22, 23, 18, 11, -2, -14, -20, -22, -18, -12, -8, -5, -3, -5, -6, -6,
+ -5, 1, 11, 22, 30, 31, 24, 15, -1, -12, -20, -23, -19, -13, -8, -3,
+ -3, -2, -6, -8, -9, -5, 6, 21, 32, 35, 29, 19, 1, -15, -27, -29,
+ -25, -15, -9, -4, -1, -2, -7, -14, -15, -10, 4, 24, 42, 48, 43, 26,
+ 4, -20, -36, -38, -30, -17, -7, -3, 0, -1, -4, -16, -24, -19, -3, 26,
+ 49, 61, 60, 40, 9, -23, -45, -52, -39, -22, -5, -2, 1, 3, -2, -18,
+ -32, -30, -10, 22, 55, 77, 78, 52, 15, -22, -51, -66, -52, -29, -5, 0,
+ 2, 9, 6, -15, -37, -42, -22, 10, 55, 89, 99, 71, 22, -20, -58, -79,
+ -68, -35, -8, 6, 1, 12, 13, -9, -37, -50, -35, 0, 46, 93, 116, 90,
+ 33, -15, -60, -89, -84, -44, -9, 10, 3, 13, 19, -3, -35, -53, -43, -12,
+ 34, 91, 127, 109, 46, -9, -57, -95, -96, -57, -13, 11, 7, 10, 25, 2,
+ -2, -35, 0, 2, 7, 12, -7, -79, -68, 2, -6, -5, 19, 40, 33, 55,
+ 56, 17, 32, 32, 2, -20, 5, 51, 27, -21, -13, -11, -17, -20, -6, -63,
+ -125, -116, -86, -59, -34, 11, 23, 20, 39, 66, 50, 47, 54, 46, 11, -4,
+ 44, 67, 30, 11, 16, 6, -2, 7, -4, -77, -114, -107, -70, -50, -20, 29,
+ 26, 12, 48, 69, 44, 47, 49, 28, -8, 9, 53, 49, 15, 9, 8, -3,
+ -11, 7, -33, -107, -123, -101, -62, -49, -5, 25, 6, 13, 55, 49, 32, 40,
+ 39, 7, -17, 18, 49, 32, 7, 8, 1, -12, -3, 7, -62, -113, -109, -74,
+ -50, -31, 23, 32, 13, 40, 69, 48, 46, 54, 42, 2, 1, 42, 52, 25,
+ 10, 11, 0, -11, 10, -10, -90, -115, -101, -64, -52, -15, 29, 16, 10, 51,
+ 59, 41, 46, 49, 25, -9, 15, 48, 42, 15, 10, 7, -9, -7, 16, -43,
+ -107, -113, -89, -60, -47, 4, 27, 4, 19, 58, 47, 38, 46, 43, 6, -9,
+ 28, 47, 29, 10, 11, 2, -14, 5, 5, -73, -111, -106, -73, -56, -29, 24,
+ 22, 6, 40, 61, 43, 43, 52, 37, -3, 6, 41, 47, 23, 12, 11, 0,
+ -14, 1, 3, 5, 5, 6, 8, 6, 4, 0, -4, -5, -6, -9, -9, -11,
+ -11, -12, -13, -13, -13, -12, -11, -9, -5, -2, -1, 1, 4, 6, 9, 11,
+ 12, 12, 11, 8, 5, 2, -2, -2, -2, -2, 0, -1, -1, -2, -5, -5,
+ -5, -1, 4, 10, 17, 20, 22, 19, 15, 7, -1, -9, -15, -19, -21, -21,
+ -18, -16, -13, -11, -12, -15, -19, -23, -24, -20, -13, -3, 9, 20, 34, 44,
+ 50, 46, 35, 21, 7, -4, -14, -20, -19, -13, -8, 2, 0, -5, -15, -28,
+ -32, -29, -14, 0, 11, 27, 42, 58, 59, 45, 22, 4, -15, -26, -37, -43,
+ -42, -37, -17, 1, 18, 23, 8, -5, -29, -47, -47, -43, -25, -5, 20, 52,
+ 80, 92, 76, 43, 9, -20, -35, -38, -46, -41, -29, -12, 19, 35, 22, 4,
+ -34, -53, -58, -40, -26, -16, 14, 47, 88, 108, 90, 50, 16, -9, -36, -51,
+ -64, -64, -52, -33, -1, 32, 40, 24, 3, -29, -62, -58, -65, -52, -18, 23,
+ 68, 114, 127, 95, 41, 1, -36, -54, -56, -68, -55, -35, -17, 19, 42, 29,
+ 13, -16, -46, -60, -54, -56, -47, -11, 29, 72, 116, 127, 94, 41, -3, 0,
+ 16, 39, 54, 46, 18, 7, -15, -36, -9, -6, -16, -5, -15, -30, -23, -35,
+ -20, 22, 3, -19, -20, -13, -9, 19, 23, 10, 12, 35, 66, 54, 4, -43,
+ -58, -15, -10, 16, 55, 18, -39, -38, -30, 2, 9, 27, 51, -32, -60, -72,
+ -4, 32, 71, 19, -8, 56, -2, -42, 10, 21, -6, 31, -9, -70, 8, -6,
+ -19, -93, -20, -5, -31, 10, 5, 56, 24, -45, 11, 66, 48, 61, 89, 49,
+ -57, -6, -20, -69, -104, -83, -50, 32, 10, -16, -87, -78, 30, 127, 63, -17,
+ -91, -2, -12, 45, 83, 30, 56, 54, 42, 7, 79, -26, -52, -64, -97, 12,
+ -3, -107, -99, -39, 34, 86, 19, -25, 25, 90, -8, -38, 65, 36, 10, 30,
+ 36, 19, -6, 38, -47, -101, -52, -45, 30, -9, -106, 18, -10, -37, 16, 100,
+ -94, -111, -25, -35, -12, -8, -9, 51, 24, -5, -70, -52, -52, -19, -11, 48,
+ 93, 61, 17, 113, 125, 73, -16, -30, -57, -78, -116, -55, -38, -10, -5, -4,
+ 38, 31, -3, -46, -46, -50, -20, -10, 52, 84, 48, 14, 115, 119, 64, -16,
+ -1, 4, 0, -9, -11, -1, 6, 2, -2, 4, -6, -10, -2, 11, 14, 3,
+ -10, -15, -1, 17, 4, 6, 4, -12, -18, 6, 10, 4, 6, -8, -36, 2,
+ 3, 3, 5, 15, -20, -17, 9, 8, 11, 17, -8, -26, 18, 2, 5, 5,
+ 13, -24, -8, -2, 2, 5, 7, -21, -18, 13, 5, -5, 17, 7, -14, -13,
+ -12, 0, 14, 3, -12, -26, 13, 3, 10, 18, 12, -15, -14, -1, 3, 19,
+ 0, -10, -29, 11, 4, 17, 15, 12, -24, -20, 6, 9, 22, -3, -13, -15,
+ 9, 1, 7, 6, 18, -19, -26, -18, 2, 22, 0, -25, -20, 15, 8, -4,
+ 8, 31, -12, -20, -15, 9, 33, 9, -29, -2, 27, 7, -11, 8, 20, -20,
+ -41, -10, 15, 35, 15, -21, 11, 49, 6, -6, 4, 3, -48, -76, -35, 14,
+ 37, 22, -24, 29, 68, 20, 3, 7, -5, -68, -90, -59, 19, 36, 28, -13,
+ 59, 93, 30, 2, 18, -25, -88, -105, -81, 13, 26, 30, -4, 88, 109, 33,
+ 0, 22, -30, -88, -112, -76, 17, 31, 18, 5, 94, 114, 30, -4, 0, 4,
+ -30, -1, 0, -2, -2, -2, -1, 4, 11, 18, 30, 7, -64, -60, -30, -7,
+ 0, 2, 22, 67, 117, 23, -128, -74, -30, -5, -2, 1, 19, 62, 116, 38,
+ -123, -82, -31, -8, -1, -1, 16, 57, 114, 52, -117, -88, -33, -10, -2, -3,
+ 14, 52, 112, 64, -108, -96, -35, -13, -2, -4, 12, 49, 108, 77, -99, -102,
+ -37, -15, -2, -5, 10, 43, 104, 86, -87, -109, -40, -18, -2, -6, 8, 40,
+ 100, 95, -73, -115, -42, -21, -2, -8, 7, 35, 95, 102, -59, -120, -45, -24,
+ -2, -8, 5, 32, 90, 109, -44, -124, -49, -26, -3, -9, 3, 28, 85, 114,
+ -29, -126, -53, -28, -4, -9, 2, 25, 81, 116, -13, -127, -58, -29, -6, -9,
+ 0, 22, 75, 119, 3, -126, -63, -31, -7, -9, -2, 19, 70, 120, 18, -124,
+ -69, -32, -9, -9, -3, 16, 65, 119, 34, -63, -107, -58, -23, -11, -7, 7,
+ 46, 107, 89, -52, -109, -62, -25, -12, -8, 5, 42, 104, 97, -41, -87, -70,
+ -36, -18, -11, 0, 30, 85, 100, -2, -87, -5, 11, -23, -10, -3, -20, -3,
+ -17, -24, -33, -26, -1, -13, -12, -6, -9, 6, 25, 19, -7, -1, 22, -6,
+ -20, 13, 6, -12, 26, 48, 0, -7, 34, 23, 4, 32, 23, -41, -11, 49,
+ -3, -30, 35, 45, -14, -2, 62, 18, -44, -2, 26, -4, -28, -6, 16, 2,
+ -9, -9, 2, 18, 24, 9, -25, -57, -36, 30, 38, -21, -63, -37, 9, 37,
+ 40, 0, -56, -56, 3, 39, 20, -23, -52, -58, -46, 8, 67, 56, -18, -61,
+ -18, 36, 70, 95, 73, -35, -128, -127, -73, -17, 32, 48, 29, 28, 60, 106,
+ 113, 91, 36, -26, -67, -90, -91, -71, -44, -25, -13, 9, 36, 51, 69, 70,
+ 32, -40, -92, -99, -70, -25, 12, 29, 21, 3, -9, 10, 21, 12, -11, -22,
+ -27, -44, -23, 10, 30, 25, 24, 39, 18, 3, 8, 19, -1, -19, -8, 6,
+ 5, 13, 50, 43, 37, 36, 40, 37, 4, 12, -10, -33, -31, -25, -1, 1,
+ 7, 14, 10, -4, -11, -10, -6, -19, -42, -28, -54, -51, -18, -5, 3, 2,
+ -10, -10, 10, 28, 27, 16, 5, -5, -24, -26, -7, -14, -25, -16, 53, 33,
+ -49, -30, 53, 50, -24, -34, 40, 82, -118, -23, 120, -56, -70, -72, 106, -10,
+ -48, 3, 87, 28, -126, -16, 81, 4, -84, -51, 38, 62, -32, 36, 84, -12,
+ -41, 72, -42, -60, -64, 4, 77, -24, -79, -9, 122, 6, -94, 52, 43, 35,
+ 13, -62, -7, -89, 24, -30, 16, 29, 56, -59, 83, 42, 31, 36, -76, -2,
+ -128, -2, 45, 27, -104, -31, 66, 21, 19, 36, 121, 11, -76, -26, -93, 34,
+ 24, -34, -65, -53, 53, 17, 73, 46, 75, -9, -64, -21, -103, 41, 51, -41,
+ -83, -43, 108, 6, -11, 28, 127, 2, -84, -38, -72, 39, 17, -23, -15, -67,
+ 37, 6, 29, 64, 79, 17, -39, -39, -120, 55, 23, -17, -62, -51, 81, 23,
+ 20, 24, 99, -38, -99, 4, 17, -66, -41, -33, 63, 62, 16, 53, 91, 56,
+ -65, -36, -99, -38, 14, -47, -29, -38, 35, 83, 9, 48, 83, 62, -45, -31,
+ -103, -49, 14, 2, 6, -33, 33, -4, -1, 34, -93, 60, -49, 68, -21, 41,
+ -38, -38, 27, -87, 127, -34, 38, -3, -34, -2, -85, 79, -24, 4, 75, -23,
+ 11, -70, 1, -6, -6, 63, -48, 76, -71, 2, -7, -15, 46, -32, 48, -25,
+ -5, 10, -31, 18, -23, 5, 6, 17, 11, 3, 24, -46, -21, -1, -5, 31,
+ 1, 36, -23, -11, -4, -29, 14, -5, 29, 9, -2, -2, -20, -2, -15, 13,
+ 7, 4, 15, -11, 4, -13, -1, 1, -13, 15, -6, 9, 9, -2, -4, -11,
+ -2, -11, 7, 12, 9, 5, -6, -6, -16, -2, 3, 6, 13, 1, 7, -14,
+ -3, -11, -1, 8, 0, 18, -3, -3, -6, -13, 0, 4, 2, 9, 2, 2,
+ -6, -4, -1, -8, 2, 4, 2, 7, -4, 2, 1, -7, -3, -2, 0, 2,
+ 8, -2, 2, -1, -7, -3, -1, 3, 4, 3, 3, -3, -4, -4, 0, 2,
+ 1, 5, -1, -2, 1, -4, -1, 1, 0, 2, -5, -8, -3, -3, -9, -2,
+ -2, 5, 10, 16, 11, 5, -3, -5, -1, -4, -6, -7, -15, -18, -27, -31,
+ -21, -11, 22, 56, 90, 66, -17, -25, -25, 0, -12, -15, -25, -32, -39, -37,
+ -26, 6, 33, 65, 69, 44, -1, -13, -12, 1, 0, -9, -14, -22, -40, -44,
+ -42, -23, 8, 39, 60, 84, 57, -16, -25, -19, 2, -8, -11, -18, -32, -51,
+ -45, -32, -6, 28, 54, 85, 96, -5, -29, -23, -7, -10, -17, -16, -28, -53,
+ -44, -40, -7, 22, 52, 82, 112, 17, -37, -25, -20, -11, -18, -10, -23, -33,
+ -51, -40, -23, 10, 45, 65, 96, 64, -21, -35, -34, -19, -20, -13, -5, -14,
+ -35, -41, -39, -17, 9, 45, 58, 82, 98, -2, -57, -47, -23, -12, -11, -2,
+ -18, -28, -39, -36, -24, -1, 26, 57, 84, 121, 23, -65, -50, -40, -12, -11,
+ -4, -14, -20, -34, -32, -27, -5, 19, 56, 80, 127, 15, -66, -50, -2, -5,
+ -5, 2, 10, 8, -7, -16, -9, 6, 17, 8, -19, -20, 14, 38, 34, 20,
+ -5, 1, 50, 37, -50, -54, -66, -32, 32, -3, -13, -18, -17, 46, 89, -17,
+ -62, 45, 127, 57, -57, -67, -109, -11, 88, -31, -90, -88, -27, 63, 97, -27,
+ -105, -44, 65, 110, 60, -12, -30, -27, 17, 49, -2, -39, -6, 30, -16, -36,
+ -43, 32, 67, -54, -58, -38, -21, 47, 95, 76, -33, -78, -62, 10, 107, 24,
+ -106, -107, 12, 52, 27, 78, 8, -75, 25, 6, -26, 59, 32, -17, -7, -19,
+ 11, 32, -51, -52, 41, -9, -13, 94, 2, -65, 5, -46, -86, 34, 62, 85,
+ 29, -93, -89, -29, 44, 35, -31, -33, -19, 56, 127, 7, -9, -62, -52, 23,
+ 46, 44, -56, -16, -55, -46, 22, 83, -13, -42, -7, 13, 81, 49, 3, -9,
+ -30, -47, -30, 3, 23, 6, -7, -20, -44, 10, 96, -13, 0, 16, 31, 47,
+ 61, 75, 87, 98, 107, 115, 121, 125, 127, 127, 125, 121, 116, 108, 99, 88,
+ 75, 62, 47, 32, 16, 0, -16, -31, -47, -61, -75, -87, -98, -108, -116, -122,
+ -126, -128, -128, -126, -123, -117, -109, -100, -89, -77, -64, -49, -34, -18, -2, 14,
+ 29, 45, 59, 73, 86, 97, 106, 114, 121, 125, 127, 127, 126, 122, 116, 109,
+ 100, 89, 77, 63, 49, 34, 18, 2, -14, -30, -45, -60, -73, -86, -97, -107,
+ -115, -121, -126, -128, -128, -127, -123, -118, -110, -101, -91, -79, -65, -51, -36, -20,
+ -4, 12, 28, 43, 58, 72, 84, 96, 106, 114, 120, 124, 127, 127, 126, 122,
+ 117, 109, 100, 90, 78, 64, 50, 35, 19, 3, -13, -29, -44, -59, -73, -85,
+ -97, -107, -115, -121, -125, -128, -128, -127, -123, -118, -110, -101, -91, -79, -65, -51,
+ -36, -20, -4, 12, 2, 5, 5, 0, -16, -9, -2, -19, 4, 18, 6, 10,
+ -16, -21, 22, -2, 3, -7, 21, 43, -57, -37, 46, -39, -31, 78, 23, -23,
+ -10, -10, -7, -52, 44, 50, -44, 9, -9, -46, 47, 12, -75, 40, 45, 32,
+ -10, -25, -15, -45, 24, 44, -40, -10, 18, -48, -29, 63, 44, -30, -1, 83,
+ -45, -94, 96, 0, -103, 21, 29, -42, 21, 80, -25, -15, 26, 39, -79, -18,
+ 73, -111, -45, 61, 29, 55, -22, -77, 40, 9, -72, 78, 35, -1, -1, -69,
+ 12, -50, -42, 123, 45, -7, -39, -86, 3, 51, 30, 28, -4, -33, -41, -66,
+ 54, -8, -30, 127, -7, -30, -32, -39, 48, -65, 20, 121, -33, -14, -53, -32,
+ 46, -24, 36, 98, -49, -39, -61, 1, 49, -54, 65, 59, -83, -11, -49, 32,
+ 39, -72, 113, 59, -83, -11, -49, 32, 39, -72, 113, 59, -2, -4, -4, -7,
+ -8, -8, -7, -4, -3, -2, 1, 4, 6, 6, 6, 4, 2, 0, -2, -3,
+ -4, -7, -7, -5, -3, 0, 4, 9, 11, 11, 9, 7, 4, 1, -3, -7,
+ -9, -12, -13, -16, -19, -19, -13, -2, 9, 17, 19, 20, 18, 13, 8, 3,
+ 0, -2, -3, -8, -14, -21, -25, -21, -9, 4, 15, 23, 28, 25, 20, 9,
+ -7, -21, -14, 3, 3, -18, -38, -49, -32, -7, 8, 14, 26, 37, 42, 37,
+ 26, 7, -18, -27, -5, 8, -7, -24, -34, -40, -32, -19, 1, 17, 42, 56,
+ 58, 40, -19, -81, 1, 67, 0, -60, -49, -27, -24, 0, -18, -24, -8, 37,
+ 67, 70, 59, 34, -42, -81, 7, 51, -12, -54, -37, -14, -25, -14, -16, -24,
+ 4, 55, 75, 102, 52, -102, -104, 90, 30, -48, -76, 1, -14, 0, -2, -2,
+ -3, -5, -7, -8, -8, -7, -6, -4, -2, 0, 1, 3, 4, 6, 6, 6,
+ 6, 5, 4, 3, 1, 0, 0, -3, -4, -7, -10, -11, -11, -8, -6, 1,
+ 5, 6, 8, 11, 11, 8, 5, 5, 2, 1, 0, 0, -2, 1, -4, -16,
+ -36, -27, -5, 6, -3, -6, 0, -6, 2, 27, 24, 19, 16, 9, 3, 0,
+ -4, 2, 1, 9, 19, -14, -79, -32, 22, -4, -22, -14, 25, 8, -11, 13,
+ 28, 16, 19, 16, 1, -2, -4, -3, -6, 28, 38, -59, -111, 25, 16, -16,
+ -40, 16, 24, -20, 4, 24, 29, 17, 27, 13, 1, -10, -6, -10, -8, 43,
+ 61, -68, -128, 28, 12, -15, -39, 12, 21, -28, 12, 37, 25, 12, 27, 11,
+ 0, -16, -2, -12, -11, 52, 67, -68, 35, 54, 47, 4, -60, -92, -68, -27,
+ 0, -2, -18, -20, -6, 2, -8, -15, -11, -3, 3, -7, -11, -6, -2, 7,
+ 15, 18, 19, 22, 27, 40, 40, 29, 20, 24, 28, 34, 30, 25, 32, 20,
+ 14, 9, 16, 19, 17, 6, -1, 3, -6, -14, -23, -18, -7, 1, -18, -18,
+ -24, -25, -24, -35, -35, -35, -21, -12, -14, -21, -17, -29, -24, -31, -34, -9,
+ -11, -9, -3, -7, -7, 6, -17, -22, 7, 16, 14, -4, -11, 10, 33, 24,
+ 21, 27, 3, -19, -25, -18, 17, 50, 48, 49, 61, 31, -48, -103, -73, 9,
+ 56, 70, 82, 109, 127, 71, -46, -127, -96, -30, -4, 9, 47, 103, 117, 60,
+ -39, -110, -119, -94, -64, -40, -4, 35, -8, -14, -9, -5, -4, -3, 6, 18,
+ 19, 6, -14, -20, -12, -3, -3, -6, 2, 21, 28, 13, -16, -26, -14, -6,
+ -6, -7, 1, 27, 36, 18, -15, -27, -15, -3, -2, -10, -6, 25, 41, 22,
+ -17, -34, -18, -4, -3, -16, -12, 29, 56, 31, -24, -44, -20, -4, -1, -19,
+ -22, 31, 73, 47, -27, -62, -25, -2, 4, -21, -36, 26, 91, 61, -27, -79,
+ -33, 0, 10, -18, -49, 14, 106, 82, -24, -94, -40, 8, 14, -12, -59, 1,
+ 112, 105, -19, -106, -51, 12, 16, -4, -63, -13, 110, 127, -12, -114, -51, 0,
+ -1, -4, -8, -11, -8, -2, 0, 7, 14, 21, 46, 92, 120, 76, -36, -121,
+ -119, -73, -31, -7, 3, 2, -4, -6, 2, 22, 60, 106, 116, 43, -72, -128,
+ -105, -57, -21, -3, 3, -1, -6, -5, 7, 33, 76, 117, 102, 5, -100, -127,
+ -89, -43, -13, 0, 2, -3, -7, -2, 14, 46, 92, 122, 79, -34, -118, -118,
+ -72, -31, -8, 1, 0, -5, -7, 2, 23, 61, 107, 118, 46, -69, -126, -104,
+ -56, -21, -4, 1, 0, -4, -5, 0, 16, 48, 87, 103, 60, -25, -87, -94,
+ -58, -20, -4, -11, 12, 24, 31, -36, 29, -9, 2, -38, -5, -5, -10, -33,
+ -10, -24, -20, -39, -36, -18, -38, -58, -5, -22, -15, -15, 90, -42, -3, -8,
+ 25, 6, 28, 25, 17, 25, -16, 28, 80, 22, 12, -6, 35, 22, 8, -7,
+ 28, 29, -19, 7, 8, -1, -29, -23, 10, -23, -13, -26, -17, -20, -33, -41,
+ -19, -28, -64, -13, -21, -13, -29, 54, 25, -20, -36, 42, -4, 13, 52, -8,
+ 47, -14, 9, 42, 88, -12, 20, -5, 43, 22, -11, 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, -128, -128, -128, -128, -128, -128, -128, -128,
+ -128, -128, -128, -128, -128, -128, -128, 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, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, -128, 1, 4, 7, 10, 12, 16, 19, 22, 25, 28, 31, 35, 38, 42,
+ 45, 49, 51, 56, 58, 63, 65, 70, 73, 78, 80, 85, 87, 93, 95, 100,
+ 102, 108, 109, 117, 114, 127, 85, -63, -60, -64, -60, -62, -59, -61, -59, -61,
+ -58, -60, -58, -59, -58, -58, -57, -57, -55, -55, -54, -54, -52, -51, -50, -49,
+ -47, -46, -44, -43, -41, -40, -37, -36, -34, -32, -30, -28, -25, -24, -21, -19,
+ -16, -14, -11, -9, -6, 1, 1, 4, 7, 10, 12, 16, 19, 22, 25, 28,
+ 31, 35, 38, 42, 45, 49, 51, 56, 58, 63, 65, 70, 73, 78, 80, 85,
+ 87, 93, 95, 100, 102, 108, 109, 117, 114, 127, 85, -63, -60, -64, -60, -62,
+ -59, -61, -59, -61, -58, -60, -58, -59, -58, -58, -57, -57, -55, -55, -54, -54,
+ -52, -51, -50, -49, -47, -46, -44, -43, -41, -40, -37, -36, -34, -32, -30, -28,
+ -25, -24, -21, -19, -16, -14, -11, -9, -6, 1, -3, -19, -24, -14, -8, -19,
+ -12, -10, -5, -12, -50, -19, 23, 35, 4, -20, -7, -26, 9, 40, 69, 16,
+ -88, -69, -38, -32, -27, 41, 65, 55, 18, -40, -38, -20, 66, 127, 121, 57,
+ -23, -55, -48, 13, 53, 31, -20, -38, -13, 10, 8, 0, 12, 17, 13, 2,
+ -1, -3, -3, 6, 13, 7, -17, -24, -12, 4, 3, -10, -20, -32, -22, -18,
+ -12, -3, 6, 16, 22, 29, 30, 27, 20, 11, 0, -7, -12, -11, -5, 0,
+ -3, -14, -20, -16, -9, -9, -17, -25, -29, -31, -33, -35, -33, -29, -25, -22,
+ -20, -17, -14, -13, -12, -11, -9, -10, -13, -15, -11, -5, 3, 9, 10, 9,
+ 9, 12, 18, 30, 50, 80, 119, 127, 102, 82, 77, 60, 37, 5, -34, -70,
+ -84, -83, -74, -60, -46, -29, -12, -2, 6, -23, 28, -20, 50, 50, -14, 14,
+ -28, -2, 28, 52, -25, -13, -52, 43, -41, -9, -26, 36, -25, -20, -17, 3,
+ -11, 38, 30, -61, 12, -6, 5, 45, 41, -4, 4, -20, -12, 45, 33, -11,
+ -29, -44, 27, -17, -36, -1, 17, -11, -31, -12, 4, -10, 37, 20, -39, -23,
+ 0, -104, -55, -11, 24, 33, 30, 7, -15, -31, -30, -25, -23, -20, -9, 10,
+ 31, 59, 91, 111, 115, 92, 51, 7, -33, -64, -81, -81, -71, -51, -22, 16,
+ 52, 74, 82, 81, 68, 38, 0, -40, -81, -112, -124, -102, -57, -11, 0, 7,
+ -23, -58, -85, -100, -104, -100, -92, -81, -69, -57, -45, -33, -22, -11, -1, 8,
+ 18, 27, 37, 49, 62, 79, 99, 118, 124, 111, 84, 53, 26, 5, -8, -14,
+ -15, -12, -6, 2, 12, 21, 28, 26, 9, -22, -58, -20, 7, 10, 21, -14,
+ 9, 22, 57, 62, 127, 56, 28, 26, -28, 10, -81, -31, -81, -35, -19, -55,
+ -27, -4, -4, 23, 49, 88, 85, 22, 1, 0, -3, 18, -22, -12, -39, -14,
+ -47, -67, -53, -53, -33, -20, 8, -22, 25, 30, 6, -19, -62, -19, 10, 83,
+ 57, -67, -88, -52, 63, 127, 42, -63, -121, -70, 82, 111, 46, -43, -114, -35,
+ 45, 73, 39, -19, -54, -41, 9, 49, 24, -16, -14, -9, -6, 10, 8, -22,
+ 25, 30, 6, -19, -62, -19, 10, 83, 57, -67, -88, -52, 63, 127, 42, -63,
+ -121, -70, 82, 111, 46, -43, -114, -35, 45, 73, 39, -19, -54, -41, 9, 49,
+ 24, -16, -14, -9, -6, 10, 8, -22, 25, 30, 6, -19, -62, -19, 10, 83,
+ 57, -67, -88, -52, 63, 127, 42, -63, -121, -70, 82, 111, 46, -43, -114, -35,
+ 45, 73, 39, -19, -54, -41, 9, 49, 24, -16, -14, -9, -6, 10, -18, -15,
+ 80, 127, 20, 18, 72, 60, -36, 22, 33, -73, -105, -27, 29, 25, 8, 43,
+ 23, -22, -35, -14, -8, -34, -25, -5, -18, -46, -13, -28, -3, -19, -10, -28,
+ -10, 17, -18, 96, 127, 123, 127, 126, 126, 95, 61, 22, -17, -56, -95, -118,
+ -123, -128, -128, -128, -128, -128, -128, -128, -128, -124, -93, -55, -17, 25, 62, 100,
+ 107, 119, 119, 127, 41, -4, -4, -10, -27, -62, -102, -128, -117, -85, -76, -49,
+ -25, -7, 15, 24, 14, 0, -9, -12, -3, 33, 81, 105, 111, 101, 80, 62,
+ 45, 30, 16, 8, 1, -4, 126, 86, -44, -68, -88, -63, 4, 84, 127, 14,
+ -29, -51, -127, -47, 58, 87, 82, 24, -17, -112, -113, 18, 46, 72, 102, 19,
+ -72, -118, -51, 9, 27, 126, 19, -53, -114, -108, 15, 122, 111, 21, -71, -70,
+ 5, 59, 83, 23, -72, -84, -49, 12, 37, 38, -28, -65, -26, 7, -2, 11,
+ 5, 23, 68, 19, 27, -54, 15, -24, -31, 46, 71, 81, -24, -33, -87, -41,
+ -71, -61, -70, -36, -44, -3, 12, -25, -20, 20, 68, 85, 127, 15, 50, -5,
+ 27, 51, 82, 106, 127, 118, 101, 92, 74, 52, 39, 37, 14, -41, -105, -108,
+ -94, -119, -124, -93, -57, -40, -37, -45, -51, -41, -5, 51, 127, 127, -128, -128,
+ -128, -128, -128, -128, -128, -128, -128, -128, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127
+};
+
+const EAS_U32 eas_sampleLengths[] =
+{
+ 16820, 16708, 16592, 11754, 10954, 10295, 9922, 7489,
+ 5779, 5462, 4452, 3779, 3115, 3093, 3057, 3024,
+ 2818, 2776, 2171, 2168, 2052, 1902, 1835, 1614,
+ 1603, 1528, 1517, 1480, 1455, 1424, 1387, 1302,
+ 1262, 1254, 1230, 1227, 1185, 1181, 1178, 1168,
+ 1132, 1120, 1034, 1033, 1018, 994, 964, 926,
+ 907, 886, 881, 866, 830, 817, 816, 813,
+ 749, 748, 739, 720, 652, 610, 610, 583,
+ 564, 561, 556, 549, 542, 535, 530, 530,
+ 516, 508, 492, 478, 461, 448, 437, 431,
+ 423, 418, 403, 402, 400, 394, 387, 387,
+ 367, 357, 347, 347, 341, 336, 334, 329,
+ 325, 312, 294, 284, 277, 265, 255, 233,
+ 230, 213, 207, 205, 194, 193, 184, 181,
+ 181, 167, 164, 158, 152, 152, 145, 139,
+ 128, 103, 100, 88, 87, 84, 84, 72,
+ 71, 55, 46, 45, 43, 40, 40, 40,
+ 37, 35, 32, 32, 30, 29, 27, 23,
+ 22, 21, 21, 21, 21, 20
+};
+
+const EAS_U32 eas_sampleOffsets[] =
+{
+ 0x00000000, 0x000041b4, 0x000082f8, 0x0000c3c8, 0x0000f1b2, 0x00011c7c, 0x000144b3, 0x00016b75,
+ 0x000188b6, 0x00019f49, 0x0001b49f, 0x0001c603, 0x0001d4c6, 0x0001e0f1, 0x0001ed06, 0x0001f8f7,
+ 0x000204c7, 0x00020fc9, 0x00021aa1, 0x0002231c, 0x00022b94, 0x00023398, 0x00023b06, 0x00024231,
+ 0x0002487f, 0x00024ec2, 0x000254ba, 0x00025aa7, 0x0002606f, 0x0002661e, 0x00026bae, 0x00027119,
+ 0x0002762f, 0x00027b1d, 0x00028003, 0x000284d1, 0x0002899c, 0x00028e3d, 0x000292da, 0x00029774,
+ 0x00029c04, 0x0002a070, 0x0002a4d0, 0x0002a8da, 0x0002ace3, 0x0002b0dd, 0x0002b4bf, 0x0002b883,
+ 0x0002bc21, 0x0002bfac, 0x0002c322, 0x0002c693, 0x0002c9f5, 0x0002cd33, 0x0002d064, 0x0002d394,
+ 0x0002d6c1, 0x0002d9ae, 0x0002dc9a, 0x0002df7d, 0x0002e24d, 0x0002e4d9, 0x0002e73b, 0x0002e99d,
+ 0x0002ebe4, 0x0002ee18, 0x0002f049, 0x0002f275, 0x0002f49a, 0x0002f6b8, 0x0002f8cf, 0x0002fae1,
+ 0x0002fcf3, 0x0002fef7, 0x000300f3, 0x000302df, 0x000304bd, 0x0003068a, 0x0003084a, 0x000309ff,
+ 0x00030bae, 0x00030d55, 0x00030ef7, 0x0003108a, 0x0003121c, 0x000313ac, 0x00031536, 0x000316b9,
+ 0x0003183c, 0x000319ab, 0x00031b10, 0x00031c6b, 0x00031dc6, 0x00031f1b, 0x0003206b, 0x000321b9,
+ 0x00032302, 0x00032447, 0x0003257f, 0x000326a5, 0x000327c1, 0x000328d6, 0x000329df, 0x00032ade,
+ 0x00032bc7, 0x00032cad, 0x00032d82, 0x00032e51, 0x00032f1e, 0x00032fe0, 0x000330a1, 0x00033159,
+ 0x0003320e, 0x000332c3, 0x0003336a, 0x0003340e, 0x000334ac, 0x00033544, 0x000335dc, 0x0003366d,
+ 0x000336f8, 0x00033778, 0x000337df, 0x00033843, 0x0003389b, 0x000338f2, 0x00033946, 0x0003399a,
+ 0x000339e2, 0x00033a29, 0x00033a60, 0x00033a8e, 0x00033abb, 0x00033ae6, 0x00033b0e, 0x00033b36,
+ 0x00033b5e, 0x00033b83, 0x00033ba6, 0x00033bc6, 0x00033be6, 0x00033c04, 0x00033c21, 0x00033c3c,
+ 0x00033c53, 0x00033c69, 0x00033c7e, 0x00033c93, 0x00033ca8, 0x00033cbd
+};
+
+/*----------------------------------------------------------------------------
+ * S_EAS
+ *----------------------------------------------------------------------------
+*/
+const S_EAS easSoundLib =
+{
+ 0x01534145,
+ 0x0010ac44,
+ eas_banks,
+ eas_programs,
+ eas_regions,
+ eas_articulations,
+ eas_sampleLengths,
+ eas_sampleOffsets,
+ eas_samples,
+ 0,
+ 1,
+ 1,
+ 377,
+ 185,
+ 150,
+ 0
+}; /* end S_EAS */
+
+/*----------------------------------------------------------------------------
+ * Statistics
+ *
+ * Number of banks: 1
+ * Number of programs: 1
+ * Number of regions: 377
+ * Number of articulations: 185
+ * Number of samples: 150
+ * Size of sample pool: 212050
+ *----------------------------------------------------------------------------
+*/
+/* end wt_200k_G_MAC.c */
diff --git a/arm-wt-22k/lib_src/ARM_synth_constants_gnu.inc b/arm-wt-22k/lib_src/ARM_synth_constants_gnu.inc
index b4cd29a..c0f8df3 100644
--- a/arm-wt-22k/lib_src/ARM_synth_constants_gnu.inc
+++ b/arm-wt-22k/lib_src/ARM_synth_constants_gnu.inc
@@ -1,153 +1,153 @@
-@***********************************************************
-@ File: ARM_synth_constants.inc
-@ Processor: ARM
-@ Description: Contains constants and defines, most of which
-@ are mirrored in synth.h
-@
-@ Copyright Sonic Network Inc. 2004
-@****************************************************************
-@ Revision Control:
-@ $Revision: 741 $
-@ $Date: 2007-06-22 16:39:21 -0700 (Fri, 22 Jun 2007) $
-@****************************************************************
-
-
- .ifdef SAMPLE_RATE_8000
- .equ SYNTH_UPDATE_PERIOD_IN_BITS, 5
- .equ BUFFER_SIZE_IN_MONO_SAMPLES, 32
- .endif
-
- .ifdef SAMPLE_RATE_16000
- .equ SYNTH_UPDATE_PERIOD_IN_BITS, 6
- .equ BUFFER_SIZE_IN_MONO_SAMPLES, 64
- .endif
-
- .ifdef SAMPLE_RATE_20000
- .equ SYNTH_UPDATE_PERIOD_IN_BITS, 7
- .equ BUFFER_SIZE_IN_MONO_SAMPLES, 128
- .endif
-
- .ifdef SAMPLE_RATE_22050
- .equ SYNTH_UPDATE_PERIOD_IN_BITS, 7
- .equ BUFFER_SIZE_IN_MONO_SAMPLES, 128
- .endif
-
- .ifdef SAMPLE_RATE_24000
- .equ SYNTH_UPDATE_PERIOD_IN_BITS, 7
- .equ BUFFER_SIZE_IN_MONO_SAMPLES, 128
- .endif
-
- .ifdef SAMPLE_RATE_32000
- .equ SYNTH_UPDATE_PERIOD_IN_BITS, 7
- .equ BUFFER_SIZE_IN_MONO_SAMPLES, 128
- .endif
-
- .ifdef SAMPLE_RATE_44100
- .equ SYNTH_UPDATE_PERIOD_IN_BITS, 8
- .equ BUFFER_SIZE_IN_MONO_SAMPLES, 256
- .endif
-
- .ifdef SAMPLE_RATE_48000
- .equ SYNTH_UPDATE_PERIOD_IN_BITS, 8
- .equ BUFFER_SIZE_IN_MONO_SAMPLES, 256
- .endif
-
-
-@ if the OUTPUT PCM sample is 16-bits, then when using indexed addressing,
-@ the next sample is this many bytes away
- .equ NEXT_OUTPUT_PCM, 2
-
-@****************************************************************************
-@/* macros for fractional phase accumulator */
- .equ NUM_PHASE_FRAC_BITS, 15
-
- .equ PHASE_FRAC_MASK, 0x7FFF
-
-@ shift for phase accumulator when fraction carries over
- .ifdef SAMPLES_8_BIT
- .equ NEXT_INPUT_PCM_SHIFT, 0
- .endif
-
- .ifdef SAMPLES_16_BIT
- .equ NEXT_INPUT_PCM_SHIFT, 1
- .endif
-
-@****************************************************************************
- .equ NUM_MIXER_GUARD_BITS, 4
-
-@****************************************************************************
-@/* Envelope 1 (EG1) calculation macros */
- .equ NUM_EG1_FRAC_BITS, 15
-
-@****************************************************************************
-
- .equ NUM_ENHANCER_FILTER_COEF_FRAC_BITS, 5
-
-@****************************************************************************
-
-@
-@ I've temporarily given up on the idea of getting ADS/RV and gcc to
-@ handle a struct in a compatible fashion. Switching to old fashion EQU
-@
-
- .if FILTER_ENABLED
-@**************************************
-@ typedef struct s_filter_tag
- .equ m_z1, 0
- .equ m_z2, 2
- .endif
-
-@**************************************
-@ typedef struct s_wt_frame_tag
- .equ m_gainTarget, 0
- .equ m_phaseIncrement, 4
-
- .if FILTER_ENABLED
- .equ m_k, 8
- .equ m_b1, 12
- .equ m_b2, 16
- .equ m_pAudioBuffer, 20
- .equ m_pMixBuffer, 24
- .equ m_numSamples, 28
- .equ m_prevGain, 32
- .else
- .equ m_pAudioBuffer, 8
- .equ m_pMixBuffer, 12
- .equ m_numSamples, 16
- .equ m_prevGain, 20
- .endif
-
-
-@**************************************
-@ typedef struct s_wt_voice_tag
- .equ m_pLoopEnd, 0 @ /* points to last PCM sample (not 1 beyond last) */
- .equ m_pLoopStart, 4 @ /* points to first sample at start of loop */
- .equ m_pPhaseAccum, 8 @ /* points to first sample at start of loop */
- .equ m_phaseFrac, 12 @ /* points to first sample at start of loop */
-
- .if STEREO_OUTPUT
- .equ m_gainLeft, 16 @ /* current gain, left ch */
- .equ m_gainRight, 18 @ /* current gain, right ch */
- .endif
-
-
-@****************************************************************************
-@ enhancer
- .equ m_nEnhancerFeedForward1, 0
- .equ m_nEnhancerFeedback1, 1
- .equ m_nDriveCoef, 2
- .equ m_nEnhancerFeedback2, 3
- .equ m_nWet, 4
- .equ m_nDry, 5
-
- .equ m_zF0L, 6 @ filter 1 zero state var, left
- .equ m_zF1L, 8 @ filter 1 pole state var, left
- .equ m_zF2L, 10 @ filter 2 zero state var, left
- .equ m_zF0R, 12 @ filter 1 zero state var, right
- .equ m_zF1R, 14 @ filter 1 pole state var, right
- .equ m_zF2R, 16 @ filter 2 zero state var, right
-
-@****************************************************************************
-
-
-
+@***********************************************************
+@ File: ARM_synth_constants.inc
+@ Processor: ARM
+@ Description: Contains constants and defines, most of which
+@ are mirrored in synth.h
+@
+@ Copyright Sonic Network Inc. 2004
+@****************************************************************
+@ Revision Control:
+@ $Revision: 741 $
+@ $Date: 2007-06-22 16:39:21 -0700 (Fri, 22 Jun 2007) $
+@****************************************************************
+
+
+ .ifdef SAMPLE_RATE_8000
+ .equ SYNTH_UPDATE_PERIOD_IN_BITS, 5
+ .equ BUFFER_SIZE_IN_MONO_SAMPLES, 32
+ .endif
+
+ .ifdef SAMPLE_RATE_16000
+ .equ SYNTH_UPDATE_PERIOD_IN_BITS, 6
+ .equ BUFFER_SIZE_IN_MONO_SAMPLES, 64
+ .endif
+
+ .ifdef SAMPLE_RATE_20000
+ .equ SYNTH_UPDATE_PERIOD_IN_BITS, 7
+ .equ BUFFER_SIZE_IN_MONO_SAMPLES, 128
+ .endif
+
+ .ifdef SAMPLE_RATE_22050
+ .equ SYNTH_UPDATE_PERIOD_IN_BITS, 7
+ .equ BUFFER_SIZE_IN_MONO_SAMPLES, 128
+ .endif
+
+ .ifdef SAMPLE_RATE_24000
+ .equ SYNTH_UPDATE_PERIOD_IN_BITS, 7
+ .equ BUFFER_SIZE_IN_MONO_SAMPLES, 128
+ .endif
+
+ .ifdef SAMPLE_RATE_32000
+ .equ SYNTH_UPDATE_PERIOD_IN_BITS, 7
+ .equ BUFFER_SIZE_IN_MONO_SAMPLES, 128
+ .endif
+
+ .ifdef SAMPLE_RATE_44100
+ .equ SYNTH_UPDATE_PERIOD_IN_BITS, 8
+ .equ BUFFER_SIZE_IN_MONO_SAMPLES, 256
+ .endif
+
+ .ifdef SAMPLE_RATE_48000
+ .equ SYNTH_UPDATE_PERIOD_IN_BITS, 8
+ .equ BUFFER_SIZE_IN_MONO_SAMPLES, 256
+ .endif
+
+
+@ if the OUTPUT PCM sample is 16-bits, then when using indexed addressing,
+@ the next sample is this many bytes away
+ .equ NEXT_OUTPUT_PCM, 2
+
+@****************************************************************************
+@/* macros for fractional phase accumulator */
+ .equ NUM_PHASE_FRAC_BITS, 15
+
+ .equ PHASE_FRAC_MASK, 0x7FFF
+
+@ shift for phase accumulator when fraction carries over
+ .ifdef SAMPLES_8_BIT
+ .equ NEXT_INPUT_PCM_SHIFT, 0
+ .endif
+
+ .ifdef SAMPLES_16_BIT
+ .equ NEXT_INPUT_PCM_SHIFT, 1
+ .endif
+
+@****************************************************************************
+ .equ NUM_MIXER_GUARD_BITS, 4
+
+@****************************************************************************
+@/* Envelope 1 (EG1) calculation macros */
+ .equ NUM_EG1_FRAC_BITS, 15
+
+@****************************************************************************
+
+ .equ NUM_ENHANCER_FILTER_COEF_FRAC_BITS, 5
+
+@****************************************************************************
+
+@
+@ I've temporarily given up on the idea of getting ADS/RV and gcc to
+@ handle a struct in a compatible fashion. Switching to old fashion EQU
+@
+
+ .if FILTER_ENABLED
+@**************************************
+@ typedef struct s_filter_tag
+ .equ m_z1, 0
+ .equ m_z2, 2
+ .endif
+
+@**************************************
+@ typedef struct s_wt_frame_tag
+ .equ m_gainTarget, 0
+ .equ m_phaseIncrement, 4
+
+ .if FILTER_ENABLED
+ .equ m_k, 8
+ .equ m_b1, 12
+ .equ m_b2, 16
+ .equ m_pAudioBuffer, 20
+ .equ m_pMixBuffer, 24
+ .equ m_numSamples, 28
+ .equ m_prevGain, 32
+ .else
+ .equ m_pAudioBuffer, 8
+ .equ m_pMixBuffer, 12
+ .equ m_numSamples, 16
+ .equ m_prevGain, 20
+ .endif
+
+
+@**************************************
+@ typedef struct s_wt_voice_tag
+ .equ m_pLoopEnd, 0 @ /* points to last PCM sample (not 1 beyond last) */
+ .equ m_pLoopStart, 4 @ /* points to first sample at start of loop */
+ .equ m_pPhaseAccum, 8 @ /* points to first sample at start of loop */
+ .equ m_phaseFrac, 12 @ /* points to first sample at start of loop */
+
+ .if STEREO_OUTPUT
+ .equ m_gainLeft, 16 @ /* current gain, left ch */
+ .equ m_gainRight, 18 @ /* current gain, right ch */
+ .endif
+
+
+@****************************************************************************
+@ enhancer
+ .equ m_nEnhancerFeedForward1, 0
+ .equ m_nEnhancerFeedback1, 1
+ .equ m_nDriveCoef, 2
+ .equ m_nEnhancerFeedback2, 3
+ .equ m_nWet, 4
+ .equ m_nDry, 5
+
+ .equ m_zF0L, 6 @ filter 1 zero state var, left
+ .equ m_zF1L, 8 @ filter 1 pole state var, left
+ .equ m_zF2L, 10 @ filter 2 zero state var, left
+ .equ m_zF0R, 12 @ filter 1 zero state var, right
+ .equ m_zF1R, 14 @ filter 1 pole state var, right
+ .equ m_zF2R, 16 @ filter 2 zero state var, right
+
+@****************************************************************************
+
+
+
diff --git a/arm-wt-22k/lib_src/dls.h b/arm-wt-22k/lib_src/dls.h
index ca1d4c7..0a9e302 100644
--- a/arm-wt-22k/lib_src/dls.h
+++ b/arm-wt-22k/lib_src/dls.h
@@ -1,268 +1,268 @@
- /*
-
- dls.h
-
- Description:
-
- Interface defines and structures for the Instrument Collection Form
- RIFF DLS.
-
- Written by Sonic Foundry 1996. Released for public use.
-
- */
-
- #ifndef _INC_DLS
- #define _INC_DLS
-
- /*
-
- Layout of an instrument collection:
-
-
- RIFF [] 'DLS ' [colh,INSTLIST,WAVEPOOL,INFOLIST]
-
- INSTLIST
- LIST [] 'lins'
- LIST [] 'ins ' [insh,RGNLIST,ARTLIST,INFOLIST]
- LIST [] 'ins ' [insh,RGNLIST,ARTLIST,INFOLIST]
- LIST [] 'ins ' [insh,RGNLIST,ARTLIST,INFOLIST]
-
- RGNLIST
- LIST [] 'lrgn'
- LIST [] 'rgn ' [rgnh,wsmp,wlnk,ARTLIST]
- LIST [] 'rgn ' [rgnh,wsmp,wlnk,ARTLIST]
- LIST [] 'rgn ' [rgnh,wsmp,wlnk,ARTLIST]
-
- ARTLIST
- LIST [] 'lart'
- 'art1' level 1 Articulation connection graph
- 'art2' level 2 Articulation connection graph
- '3rd1' Possible 3rd party articulation structure 1
- '3rd2' Possible 3rd party articulation structure 2 .... and so on
-
- WAVEPOOL
- ptbl [] [pool table]
- LIST [] 'wvpl'
- [path],
- [path],
- LIST [] 'wave',RIFFWAVE
- LIST [] 'wave',RIFFWAVE
- LIST [] 'wave',RIFFWAVE
- LIST [] 'wave',RIFFWAVE
- LIST [] 'wave',RIFFWAVE
-
- INFOLIST
- LIST [] 'INFO'
- 'icmt' 'One of those crazy comments.'
- 'icop' 'Copyright (C) 1996 Sonic Foundry'
-
- */
-
-
- /*
- FOURCC's used in the DLS file
- */
-/* shree */
-//#define FAR
-
-/* shree
-
- #define FOURCC_DLS mmioFOURCC('D','L','S',' ')
- #define FOURCC_COLH mmioFOURCC('c','o','l','h')
- #define FOURCC_WVPL mmioFOURCC('w','v','p','l')
- #define FOURCC_PTBL mmioFOURCC('p','t','b','l')
- #define FOURCC_PATH mmioFOURCC('p','a','t','h')
- #define FOURCC_wave mmioFOURCC('w','a','v','e')
- #define FOURCC_LINS mmioFOURCC('l','i','n','s')
- #define FOURCC_INS mmioFOURCC('i','n','s',' ')
- #define FOURCC_INSH mmioFOURCC('i','n','s','h')
- #define FOURCC_LRGN mmioFOURCC('l','r','g','n')
- #define FOURCC_RGN mmioFOURCC('r','g','n',' ')
- #define FOURCC_RGNH mmioFOURCC('r','g','n','h')
- #define FOURCC_LART mmioFOURCC('l','a','r','t')
- #define FOURCC_ART1 mmioFOURCC('a','r','t','1')
- #define FOURCC_WLNK mmioFOURCC('w','l','n','k')
- #define FOURCC_WSMP mmioFOURCC('w','s','m','p')
- #define FOURCC_VERS mmioFOURCC('v','e','r','s')
-*/
- /*
- Articulation connection graph definitions
- */
-
- /* Generic Sources */
- #define CONN_SRC_NONE 0x0000
- #define CONN_SRC_LFO 0x0001
- #define CONN_SRC_KEYONVELOCITY 0x0002
- #define CONN_SRC_KEYNUMBER 0x0003
- #define CONN_SRC_EG1 0x0004
- #define CONN_SRC_EG2 0x0005
- #define CONN_SRC_PITCHWHEEL 0x0006
-
- /* Midi Controllers 0-127 */
- #define CONN_SRC_CC1 0x0081
- #define CONN_SRC_CC7 0x0087
- #define CONN_SRC_CC10 0x008a
- #define CONN_SRC_CC11 0x008b
-
- /* Registered Parameter Numbers */
- #define CONN_SRC_RPN0 0x0100
- #define CONN_SRC_RPN1 0x0101
- #define CONN_SRC_RPN2 0x0102
-
- /* Generic Destinations */
- #define CONN_DST_NONE 0x0000
- #define CONN_DST_ATTENUATION 0x0001
- #define CONN_DST_RESERVED 0x0002
- #define CONN_DST_PITCH 0x0003
- #define CONN_DST_PAN 0x0004
-
- /* LFO Destinations */
- #define CONN_DST_LFO_FREQUENCY 0x0104
- #define CONN_DST_LFO_STARTDELAY 0x0105
-
- /* EG1 Destinations */
- #define CONN_DST_EG1_ATTACKTIME 0x0206
- #define CONN_DST_EG1_DECAYTIME 0x0207
- #define CONN_DST_EG1_RESERVED 0x0208
- #define CONN_DST_EG1_RELEASETIME 0x0209
- #define CONN_DST_EG1_SUSTAINLEVEL 0x020a
-
- /* EG2 Destinations */
- #define CONN_DST_EG2_ATTACKTIME 0x030a
- #define CONN_DST_EG2_DECAYTIME 0x030b
- #define CONN_DST_EG2_RESERVED 0x030c
- #define CONN_DST_EG2_RELEASETIME 0x030d
- #define CONN_DST_EG2_SUSTAINLEVEL 0x030e
-
- #define CONN_TRN_NONE 0x0000
- #define CONN_TRN_CONCAVE 0x0001
-
- typedef struct _DLSVERSION {
- DWORD dwVersionMS;
- DWORD dwVersionLS;
- }DLSVERSION, FAR *LPDLSVERSION;
-
-
- typedef struct _CONNECTION {
- USHORT usSource;
- USHORT usControl;
- USHORT usDestination;
- USHORT usTransform;
- LONG lScale;
- }CONNECTION, FAR *LPCONNECTION;
-
-
- /* Level 1 Articulation Data */
-
- typedef struct _CONNECTIONLIST {
- ULONG cbSize; /* size of the connection list structure */
- ULONG cConnections; /* count of connections in the list */
- } CONNECTIONLIST, FAR *LPCONNECTIONLIST;
-
-
-
- /*
- Generic type defines for regions and instruments
- */
-
- typedef struct _RGNRANGE {
- USHORT usLow;
- USHORT usHigh;
- }RGNRANGE, FAR * LPRGNRANGE;
-
- #define F_INSTRUMENT_DRUMS 0x80000000
-
- typedef struct _MIDILOCALE {
- ULONG ulBank;
- ULONG ulInstrument;
- }MIDILOCALE, FAR *LPMIDILOCALE;
-
- /*
- Header structures found in an DLS file for collection, instruments, and
- regions.
- */
-
- #define F_RGN_OPTION_SELFNONEXCLUSIVE 0x0001
-
- typedef struct _RGNHEADER {
- RGNRANGE RangeKey; /* Key range */
- RGNRANGE RangeVelocity; /* Velocity Range */
- USHORT fusOptions; /* Synthesis options for this range */
- USHORT usKeyGroup; /* Key grouping for non simultaneous play
- 0 = no group, 1 up is group
- for Level 1 only groups 1-15 are allowed */
- }RGNHEADER, FAR *LPRGNHEADER;
-
- typedef struct _INSTHEADER {
- ULONG cRegions; /* Count of regions in this instrument */
- MIDILOCALE Locale; /* Intended MIDI locale of this instrument */
- }INSTHEADER, FAR *LPINSTHEADER;
-
- typedef struct _DLSHEADER {
- ULONG cInstruments; /* Count of instruments in the collection */
- }DLSHEADER, FAR *LPDLSHEADER;
-
- /*
- definitions for the Wave link structure
- */
-
- /***** For level 1 only WAVELINK_CHANNEL_MONO is valid ****
- ulChannel allows for up to 32 channels of audio with each bit position
- specifiying a channel of playback */
-
- #define WAVELINK_CHANNEL_LEFT 0x0001
- #define WAVELINK_CHANNEL_RIGHT 0x0002
-
- #define F_WAVELINK_PHASE_MASTER 0x0001
-
- typedef struct _WAVELINK { /* any paths or links are stored right after struct */
- USHORT fusOptions; /* options flags for this wave */
- USHORT usPhaseGroup; /* Phase grouping for locking channels */
- ULONG ulChannel; /* channel placement */
- ULONG ulTableIndex; /* index into the wave pool table, 0 based */
- }WAVELINK, FAR *LPWAVELINK;
-
- #define POOL_CUE_NULL 0xffffffff
-
- typedef struct _POOLCUE {
- // ULONG ulEntryIndex; /* Index entry in the list */
- ULONG ulOffset; /* Offset to the entry in the list */
- }POOLCUE, FAR *LPPOOLCUE;
-
- typedef struct _POOLTABLE {
- ULONG cbSize; /* size of the pool table structure */
- ULONG cCues; /* count of cues in the list */
- } POOLTABLE, FAR *LPPOOLTABLE;
-
- /*
- Structures for the "wsmp" chunk
- */
-
- #define F_WSMP_NO_TRUNCATION 0x0001
- #define F_WSMP_NO_COMPRESSION 0x0002
-
-
- typedef struct _rwsmp {
- ULONG cbSize;
- USHORT usUnityNote; /* MIDI Unity Playback Note */
- SHORT sFineTune; /* Fine Tune in log tuning */
- LONG lAttenuation; /* Overall Attenuation to be applied to data */
- ULONG fulOptions; /* Flag options */
- ULONG cSampleLoops; /* Count of Sample loops, 0 loops is one shot */
- } WSMPL, FAR *LPWSMPL;
-
-
- /* This loop type is a normal forward playing loop which is continually
- played until the envelope reaches an off threshold in the release
- portion of the volume envelope */
-
- #define WLOOP_TYPE_FORWARD 0
-
- typedef struct _rloop {
- ULONG cbSize;
- ULONG ulType; /* Loop Type */
- ULONG ulStart; /* Start of loop in samples */
- ULONG ulLength; /* Length of loop in samples */
- } WLOOP, FAR *LPWLOOP;
-
- #endif /* _INC_DLS */
+ /*
+
+ dls.h
+
+ Description:
+
+ Interface defines and structures for the Instrument Collection Form
+ RIFF DLS.
+
+ Written by Sonic Foundry 1996. Released for public use.
+
+ */
+
+ #ifndef _INC_DLS
+ #define _INC_DLS
+
+ /*
+
+ Layout of an instrument collection:
+
+
+ RIFF [] 'DLS ' [colh,INSTLIST,WAVEPOOL,INFOLIST]
+
+ INSTLIST
+ LIST [] 'lins'
+ LIST [] 'ins ' [insh,RGNLIST,ARTLIST,INFOLIST]
+ LIST [] 'ins ' [insh,RGNLIST,ARTLIST,INFOLIST]
+ LIST [] 'ins ' [insh,RGNLIST,ARTLIST,INFOLIST]
+
+ RGNLIST
+ LIST [] 'lrgn'
+ LIST [] 'rgn ' [rgnh,wsmp,wlnk,ARTLIST]
+ LIST [] 'rgn ' [rgnh,wsmp,wlnk,ARTLIST]
+ LIST [] 'rgn ' [rgnh,wsmp,wlnk,ARTLIST]
+
+ ARTLIST
+ LIST [] 'lart'
+ 'art1' level 1 Articulation connection graph
+ 'art2' level 2 Articulation connection graph
+ '3rd1' Possible 3rd party articulation structure 1
+ '3rd2' Possible 3rd party articulation structure 2 .... and so on
+
+ WAVEPOOL
+ ptbl [] [pool table]
+ LIST [] 'wvpl'
+ [path],
+ [path],
+ LIST [] 'wave',RIFFWAVE
+ LIST [] 'wave',RIFFWAVE
+ LIST [] 'wave',RIFFWAVE
+ LIST [] 'wave',RIFFWAVE
+ LIST [] 'wave',RIFFWAVE
+
+ INFOLIST
+ LIST [] 'INFO'
+ 'icmt' 'One of those crazy comments.'
+ 'icop' 'Copyright (C) 1996 Sonic Foundry'
+
+ */
+
+
+ /*
+ FOURCC's used in the DLS file
+ */
+/* shree */
+//#define FAR
+
+/* shree
+
+ #define FOURCC_DLS mmioFOURCC('D','L','S',' ')
+ #define FOURCC_COLH mmioFOURCC('c','o','l','h')
+ #define FOURCC_WVPL mmioFOURCC('w','v','p','l')
+ #define FOURCC_PTBL mmioFOURCC('p','t','b','l')
+ #define FOURCC_PATH mmioFOURCC('p','a','t','h')
+ #define FOURCC_wave mmioFOURCC('w','a','v','e')
+ #define FOURCC_LINS mmioFOURCC('l','i','n','s')
+ #define FOURCC_INS mmioFOURCC('i','n','s',' ')
+ #define FOURCC_INSH mmioFOURCC('i','n','s','h')
+ #define FOURCC_LRGN mmioFOURCC('l','r','g','n')
+ #define FOURCC_RGN mmioFOURCC('r','g','n',' ')
+ #define FOURCC_RGNH mmioFOURCC('r','g','n','h')
+ #define FOURCC_LART mmioFOURCC('l','a','r','t')
+ #define FOURCC_ART1 mmioFOURCC('a','r','t','1')
+ #define FOURCC_WLNK mmioFOURCC('w','l','n','k')
+ #define FOURCC_WSMP mmioFOURCC('w','s','m','p')
+ #define FOURCC_VERS mmioFOURCC('v','e','r','s')
+*/
+ /*
+ Articulation connection graph definitions
+ */
+
+ /* Generic Sources */
+ #define CONN_SRC_NONE 0x0000
+ #define CONN_SRC_LFO 0x0001
+ #define CONN_SRC_KEYONVELOCITY 0x0002
+ #define CONN_SRC_KEYNUMBER 0x0003
+ #define CONN_SRC_EG1 0x0004
+ #define CONN_SRC_EG2 0x0005
+ #define CONN_SRC_PITCHWHEEL 0x0006
+
+ /* Midi Controllers 0-127 */
+ #define CONN_SRC_CC1 0x0081
+ #define CONN_SRC_CC7 0x0087
+ #define CONN_SRC_CC10 0x008a
+ #define CONN_SRC_CC11 0x008b
+
+ /* Registered Parameter Numbers */
+ #define CONN_SRC_RPN0 0x0100
+ #define CONN_SRC_RPN1 0x0101
+ #define CONN_SRC_RPN2 0x0102
+
+ /* Generic Destinations */
+ #define CONN_DST_NONE 0x0000
+ #define CONN_DST_ATTENUATION 0x0001
+ #define CONN_DST_RESERVED 0x0002
+ #define CONN_DST_PITCH 0x0003
+ #define CONN_DST_PAN 0x0004
+
+ /* LFO Destinations */
+ #define CONN_DST_LFO_FREQUENCY 0x0104
+ #define CONN_DST_LFO_STARTDELAY 0x0105
+
+ /* EG1 Destinations */
+ #define CONN_DST_EG1_ATTACKTIME 0x0206
+ #define CONN_DST_EG1_DECAYTIME 0x0207
+ #define CONN_DST_EG1_RESERVED 0x0208
+ #define CONN_DST_EG1_RELEASETIME 0x0209
+ #define CONN_DST_EG1_SUSTAINLEVEL 0x020a
+
+ /* EG2 Destinations */
+ #define CONN_DST_EG2_ATTACKTIME 0x030a
+ #define CONN_DST_EG2_DECAYTIME 0x030b
+ #define CONN_DST_EG2_RESERVED 0x030c
+ #define CONN_DST_EG2_RELEASETIME 0x030d
+ #define CONN_DST_EG2_SUSTAINLEVEL 0x030e
+
+ #define CONN_TRN_NONE 0x0000
+ #define CONN_TRN_CONCAVE 0x0001
+
+ typedef struct _DLSVERSION {
+ DWORD dwVersionMS;
+ DWORD dwVersionLS;
+ }DLSVERSION, FAR *LPDLSVERSION;
+
+
+ typedef struct _CONNECTION {
+ USHORT usSource;
+ USHORT usControl;
+ USHORT usDestination;
+ USHORT usTransform;
+ LONG lScale;
+ }CONNECTION, FAR *LPCONNECTION;
+
+
+ /* Level 1 Articulation Data */
+
+ typedef struct _CONNECTIONLIST {
+ ULONG cbSize; /* size of the connection list structure */
+ ULONG cConnections; /* count of connections in the list */
+ } CONNECTIONLIST, FAR *LPCONNECTIONLIST;
+
+
+
+ /*
+ Generic type defines for regions and instruments
+ */
+
+ typedef struct _RGNRANGE {
+ USHORT usLow;
+ USHORT usHigh;
+ }RGNRANGE, FAR * LPRGNRANGE;
+
+ #define F_INSTRUMENT_DRUMS 0x80000000
+
+ typedef struct _MIDILOCALE {
+ ULONG ulBank;
+ ULONG ulInstrument;
+ }MIDILOCALE, FAR *LPMIDILOCALE;
+
+ /*
+ Header structures found in an DLS file for collection, instruments, and
+ regions.
+ */
+
+ #define F_RGN_OPTION_SELFNONEXCLUSIVE 0x0001
+
+ typedef struct _RGNHEADER {
+ RGNRANGE RangeKey; /* Key range */
+ RGNRANGE RangeVelocity; /* Velocity Range */
+ USHORT fusOptions; /* Synthesis options for this range */
+ USHORT usKeyGroup; /* Key grouping for non simultaneous play
+ 0 = no group, 1 up is group
+ for Level 1 only groups 1-15 are allowed */
+ }RGNHEADER, FAR *LPRGNHEADER;
+
+ typedef struct _INSTHEADER {
+ ULONG cRegions; /* Count of regions in this instrument */
+ MIDILOCALE Locale; /* Intended MIDI locale of this instrument */
+ }INSTHEADER, FAR *LPINSTHEADER;
+
+ typedef struct _DLSHEADER {
+ ULONG cInstruments; /* Count of instruments in the collection */
+ }DLSHEADER, FAR *LPDLSHEADER;
+
+ /*
+ definitions for the Wave link structure
+ */
+
+ /***** For level 1 only WAVELINK_CHANNEL_MONO is valid ****
+ ulChannel allows for up to 32 channels of audio with each bit position
+ specifiying a channel of playback */
+
+ #define WAVELINK_CHANNEL_LEFT 0x0001
+ #define WAVELINK_CHANNEL_RIGHT 0x0002
+
+ #define F_WAVELINK_PHASE_MASTER 0x0001
+
+ typedef struct _WAVELINK { /* any paths or links are stored right after struct */
+ USHORT fusOptions; /* options flags for this wave */
+ USHORT usPhaseGroup; /* Phase grouping for locking channels */
+ ULONG ulChannel; /* channel placement */
+ ULONG ulTableIndex; /* index into the wave pool table, 0 based */
+ }WAVELINK, FAR *LPWAVELINK;
+
+ #define POOL_CUE_NULL 0xffffffff
+
+ typedef struct _POOLCUE {
+ // ULONG ulEntryIndex; /* Index entry in the list */
+ ULONG ulOffset; /* Offset to the entry in the list */
+ }POOLCUE, FAR *LPPOOLCUE;
+
+ typedef struct _POOLTABLE {
+ ULONG cbSize; /* size of the pool table structure */
+ ULONG cCues; /* count of cues in the list */
+ } POOLTABLE, FAR *LPPOOLTABLE;
+
+ /*
+ Structures for the "wsmp" chunk
+ */
+
+ #define F_WSMP_NO_TRUNCATION 0x0001
+ #define F_WSMP_NO_COMPRESSION 0x0002
+
+
+ typedef struct _rwsmp {
+ ULONG cbSize;
+ USHORT usUnityNote; /* MIDI Unity Playback Note */
+ SHORT sFineTune; /* Fine Tune in log tuning */
+ LONG lAttenuation; /* Overall Attenuation to be applied to data */
+ ULONG fulOptions; /* Flag options */
+ ULONG cSampleLoops; /* Count of Sample loops, 0 loops is one shot */
+ } WSMPL, FAR *LPWSMPL;
+
+
+ /* This loop type is a normal forward playing loop which is continually
+ played until the envelope reaches an off threshold in the release
+ portion of the volume envelope */
+
+ #define WLOOP_TYPE_FORWARD 0
+
+ typedef struct _rloop {
+ ULONG cbSize;
+ ULONG ulType; /* Loop Type */
+ ULONG ulStart; /* Start of loop in samples */
+ ULONG ulLength; /* Length of loop in samples */
+ } WLOOP, FAR *LPWLOOP;
+
+ #endif /* _INC_DLS */
diff --git a/arm-wt-22k/lib_src/dls2.h b/arm-wt-22k/lib_src/dls2.h
index 17d6efd..081557d 100644
--- a/arm-wt-22k/lib_src/dls2.h
+++ b/arm-wt-22k/lib_src/dls2.h
@@ -1,122 +1,122 @@
-/*
-
- dls2.h
-
- Description:
-
- Interface defines and structures for the DLS2 extensions of DLS.
-
-
- Written by Microsoft 1998. Released for public use.
-
-*/
-
-#ifndef _INC_DLS2
-#define _INC_DLS2
-
-/*
- FOURCC's used in the DLS2 file, in addition to DLS1 chunks
-*/
-
-#define FOURCC_RGN2 mmioFOURCC('r','g','n','2')
-#define FOURCC_LAR2 mmioFOURCC('l','a','r','2')
-#define FOURCC_ART2 mmioFOURCC('a','r','t','2')
-#define FOURCC_CDL mmioFOURCC('c','d','l',' ')
-#define FOURCC_DLID mmioFOURCC('d','l','i','d')
-
-/*
- Articulation connection graph definitions. These are in addition to
- the definitions in the DLS1 header.
-*/
-
-/* Generic Sources (in addition to DLS1 sources. */
-#define CONN_SRC_POLYPRESSURE 0x0007 /* Polyphonic Pressure */
-#define CONN_SRC_CHANNELPRESSURE 0x0008 /* Channel Pressure */
-#define CONN_SRC_VIBRATO 0x0009 /* Vibrato LFO */
-#define CONN_SRC_MONOPRESSURE 0x000a /* MIDI Mono pressure */
-
-
-/* Midi Controllers */
-#define CONN_SRC_CC91 0x00db /* Reverb Send */
-#define CONN_SRC_CC93 0x00dd /* Chorus Send */
-
-
-/* Generic Destinations */
-#define CONN_DST_GAIN 0x0001 /* Same as CONN_DST_ ATTENUATION, but more appropriate terminology. */
-#define CONN_DST_KEYNUMBER 0x0005 /* Key Number Generator */
-
-/* Audio Channel Output Destinations */
-#define CONN_DST_LEFT 0x0010 /* Left Channel Send */
-#define CONN_DST_RIGHT 0x0011 /* Right Channel Send */
-#define CONN_DST_CENTER 0x0012 /* Center Channel Send */
-#define CONN_DST_LEFTREAR 0x0013 /* Left Rear Channel Send */
-#define CONN_DST_RIGHTREAR 0x0014 /* Right Rear Channel Send */
-#define CONN_DST_LFE_CHANNEL 0x0015 /* LFE Channel Send */
-#define CONN_DST_CHORUS 0x0080 /* Chorus Send */
-#define CONN_DST_REVERB 0x0081 /* Reverb Send */
-
-/* Vibrato LFO Destinations */
-#define CONN_DST_VIB_FREQUENCY 0x0114 /* Vibrato Frequency */
-#define CONN_DST_VIB_STARTDELAY 0x0115 /* Vibrato Start Delay */
-
-/* EG1 Destinations */
-#define CONN_DST_EG1_DELAYTIME 0x020B /* EG1 Delay Time */
-#define CONN_DST_EG1_HOLDTIME 0x020C /* EG1 Hold Time */
-#define CONN_DST_EG1_SHUTDOWNTIME 0x020D /* EG1 Shutdown Time */
-
-
-/* EG2 Destinations */
-#define CONN_DST_EG2_DELAYTIME 0x030F /* EG2 Delay Time */
-#define CONN_DST_EG2_HOLDTIME 0x0310 /* EG2 Hold Time */
-
-
-/* Filter Destinations */
-#define CONN_DST_FILTER_CUTOFF 0x0500 /* Filter Cutoff Frequency */
-#define CONN_DST_FILTER_Q 0x0501 /* Filter Resonance */
-
-
-/* Transforms */
-#define CONN_TRN_CONVEX 0x0002 /* Convex Transform */
-#define CONN_TRN_SWITCH 0x0003 /* Switch Transform */
-
-
-/* Conditional chunk operators */
- #define DLS_CDL_AND 0x0001 /* X = X & Y */
- #define DLS_CDL_OR 0x0002 /* X = X | Y */
- #define DLS_CDL_XOR 0x0003 /* X = X ^ Y */
- #define DLS_CDL_ADD 0x0004 /* X = X + Y */
- #define DLS_CDL_SUBTRACT 0x0005 /* X = X - Y */
- #define DLS_CDL_MULTIPLY 0x0006 /* X = X * Y */
- #define DLS_CDL_DIVIDE 0x0007 /* X = X / Y */
- #define DLS_CDL_LOGICAL_AND 0x0008 /* X = X && Y */
- #define DLS_CDL_LOGICAL_OR 0x0009 /* X = X || Y */
- #define DLS_CDL_LT 0x000A /* X = (X < Y) */
- #define DLS_CDL_LE 0x000B /* X = (X <= Y) */
- #define DLS_CDL_GT 0x000C /* X = (X > Y) */
- #define DLS_CDL_GE 0x000D /* X = (X >= Y) */
- #define DLS_CDL_EQ 0x000E /* X = (X == Y) */
- #define DLS_CDL_NOT 0x000F /* X = !X */
- #define DLS_CDL_CONST 0x0010 /* 32-bit constant */
- #define DLS_CDL_QUERY 0x0011 /* 32-bit value returned from query */
- #define DLS_CDL_QUERYSUPPORTED 0x0012 /* 32-bit value returned from query */
-
-/*
- Loop and release
-*/
-
-#define WLOOP_TYPE_RELEASE 1
-
-/*
- DLSID queries for <cdl-ck>
-*/
-DEFINE_DLSID(DLSID_GMInHardware, 0x178f2f24, 0xc364, 0x11d1, 0xa7, 0x60, 0x00, 0x00, 0xf8, 0x75, 0xac, 0x12);
-DEFINE_DLSID(DLSID_GSInHardware, 0x178f2f25, 0xc364, 0x11d1, 0xa7, 0x60, 0x00, 0x00, 0xf8, 0x75, 0xac, 0x12);
-DEFINE_DLSID(DLSID_XGInHardware, 0x178f2f26, 0xc364, 0x11d1, 0xa7, 0x60, 0x00, 0x00, 0xf8, 0x75, 0xac, 0x12);
-DEFINE_DLSID(DLSID_SupportsDLS1, 0x178f2f27, 0xc364, 0x11d1, 0xa7, 0x60, 0x00, 0x00, 0xf8, 0x75, 0xac, 0x12);
-DEFINE_DLSID(DLSID_SupportsDLS2, 0xf14599e5, 0x4689, 0x11d2, 0xaf, 0xa6, 0x0, 0xaa, 0x0, 0x24, 0xd8, 0xb6);
-DEFINE_DLSID(DLSID_SampleMemorySize, 0x178f2f28, 0xc364, 0x11d1, 0xa7, 0x60, 0x00, 0x00, 0xf8, 0x75, 0xac, 0x12);
-DEFINE_DLSID(DLSID_ManufacturersID, 0xb03e1181, 0x8095, 0x11d2, 0xa1, 0xef, 0x0, 0x60, 0x8, 0x33, 0xdb, 0xd8);
-DEFINE_DLSID(DLSID_ProductID, 0xb03e1182, 0x8095, 0x11d2, 0xa1, 0xef, 0x0, 0x60, 0x8, 0x33, 0xdb, 0xd8);
-DEFINE_DLSID(DLSID_SamplePlaybackRate, 0x2a91f713, 0xa4bf, 0x11d2, 0xbb, 0xdf, 0x0, 0x60, 0x8, 0x33, 0xdb, 0xd8);
-#endif /* _INC_DLS2 */
-
+/*
+
+ dls2.h
+
+ Description:
+
+ Interface defines and structures for the DLS2 extensions of DLS.
+
+
+ Written by Microsoft 1998. Released for public use.
+
+*/
+
+#ifndef _INC_DLS2
+#define _INC_DLS2
+
+/*
+ FOURCC's used in the DLS2 file, in addition to DLS1 chunks
+*/
+
+#define FOURCC_RGN2 mmioFOURCC('r','g','n','2')
+#define FOURCC_LAR2 mmioFOURCC('l','a','r','2')
+#define FOURCC_ART2 mmioFOURCC('a','r','t','2')
+#define FOURCC_CDL mmioFOURCC('c','d','l',' ')
+#define FOURCC_DLID mmioFOURCC('d','l','i','d')
+
+/*
+ Articulation connection graph definitions. These are in addition to
+ the definitions in the DLS1 header.
+*/
+
+/* Generic Sources (in addition to DLS1 sources. */
+#define CONN_SRC_POLYPRESSURE 0x0007 /* Polyphonic Pressure */
+#define CONN_SRC_CHANNELPRESSURE 0x0008 /* Channel Pressure */
+#define CONN_SRC_VIBRATO 0x0009 /* Vibrato LFO */
+#define CONN_SRC_MONOPRESSURE 0x000a /* MIDI Mono pressure */
+
+
+/* Midi Controllers */
+#define CONN_SRC_CC91 0x00db /* Reverb Send */
+#define CONN_SRC_CC93 0x00dd /* Chorus Send */
+
+
+/* Generic Destinations */
+#define CONN_DST_GAIN 0x0001 /* Same as CONN_DST_ ATTENUATION, but more appropriate terminology. */
+#define CONN_DST_KEYNUMBER 0x0005 /* Key Number Generator */
+
+/* Audio Channel Output Destinations */
+#define CONN_DST_LEFT 0x0010 /* Left Channel Send */
+#define CONN_DST_RIGHT 0x0011 /* Right Channel Send */
+#define CONN_DST_CENTER 0x0012 /* Center Channel Send */
+#define CONN_DST_LEFTREAR 0x0013 /* Left Rear Channel Send */
+#define CONN_DST_RIGHTREAR 0x0014 /* Right Rear Channel Send */
+#define CONN_DST_LFE_CHANNEL 0x0015 /* LFE Channel Send */
+#define CONN_DST_CHORUS 0x0080 /* Chorus Send */
+#define CONN_DST_REVERB 0x0081 /* Reverb Send */
+
+/* Vibrato LFO Destinations */
+#define CONN_DST_VIB_FREQUENCY 0x0114 /* Vibrato Frequency */
+#define CONN_DST_VIB_STARTDELAY 0x0115 /* Vibrato Start Delay */
+
+/* EG1 Destinations */
+#define CONN_DST_EG1_DELAYTIME 0x020B /* EG1 Delay Time */
+#define CONN_DST_EG1_HOLDTIME 0x020C /* EG1 Hold Time */
+#define CONN_DST_EG1_SHUTDOWNTIME 0x020D /* EG1 Shutdown Time */
+
+
+/* EG2 Destinations */
+#define CONN_DST_EG2_DELAYTIME 0x030F /* EG2 Delay Time */
+#define CONN_DST_EG2_HOLDTIME 0x0310 /* EG2 Hold Time */
+
+
+/* Filter Destinations */
+#define CONN_DST_FILTER_CUTOFF 0x0500 /* Filter Cutoff Frequency */
+#define CONN_DST_FILTER_Q 0x0501 /* Filter Resonance */
+
+
+/* Transforms */
+#define CONN_TRN_CONVEX 0x0002 /* Convex Transform */
+#define CONN_TRN_SWITCH 0x0003 /* Switch Transform */
+
+
+/* Conditional chunk operators */
+ #define DLS_CDL_AND 0x0001 /* X = X & Y */
+ #define DLS_CDL_OR 0x0002 /* X = X | Y */
+ #define DLS_CDL_XOR 0x0003 /* X = X ^ Y */
+ #define DLS_CDL_ADD 0x0004 /* X = X + Y */
+ #define DLS_CDL_SUBTRACT 0x0005 /* X = X - Y */
+ #define DLS_CDL_MULTIPLY 0x0006 /* X = X * Y */
+ #define DLS_CDL_DIVIDE 0x0007 /* X = X / Y */
+ #define DLS_CDL_LOGICAL_AND 0x0008 /* X = X && Y */
+ #define DLS_CDL_LOGICAL_OR 0x0009 /* X = X || Y */
+ #define DLS_CDL_LT 0x000A /* X = (X < Y) */
+ #define DLS_CDL_LE 0x000B /* X = (X <= Y) */
+ #define DLS_CDL_GT 0x000C /* X = (X > Y) */
+ #define DLS_CDL_GE 0x000D /* X = (X >= Y) */
+ #define DLS_CDL_EQ 0x000E /* X = (X == Y) */
+ #define DLS_CDL_NOT 0x000F /* X = !X */
+ #define DLS_CDL_CONST 0x0010 /* 32-bit constant */
+ #define DLS_CDL_QUERY 0x0011 /* 32-bit value returned from query */
+ #define DLS_CDL_QUERYSUPPORTED 0x0012 /* 32-bit value returned from query */
+
+/*
+ Loop and release
+*/
+
+#define WLOOP_TYPE_RELEASE 1
+
+/*
+ DLSID queries for <cdl-ck>
+*/
+DEFINE_DLSID(DLSID_GMInHardware, 0x178f2f24, 0xc364, 0x11d1, 0xa7, 0x60, 0x00, 0x00, 0xf8, 0x75, 0xac, 0x12);
+DEFINE_DLSID(DLSID_GSInHardware, 0x178f2f25, 0xc364, 0x11d1, 0xa7, 0x60, 0x00, 0x00, 0xf8, 0x75, 0xac, 0x12);
+DEFINE_DLSID(DLSID_XGInHardware, 0x178f2f26, 0xc364, 0x11d1, 0xa7, 0x60, 0x00, 0x00, 0xf8, 0x75, 0xac, 0x12);
+DEFINE_DLSID(DLSID_SupportsDLS1, 0x178f2f27, 0xc364, 0x11d1, 0xa7, 0x60, 0x00, 0x00, 0xf8, 0x75, 0xac, 0x12);
+DEFINE_DLSID(DLSID_SupportsDLS2, 0xf14599e5, 0x4689, 0x11d2, 0xaf, 0xa6, 0x0, 0xaa, 0x0, 0x24, 0xd8, 0xb6);
+DEFINE_DLSID(DLSID_SampleMemorySize, 0x178f2f28, 0xc364, 0x11d1, 0xa7, 0x60, 0x00, 0x00, 0xf8, 0x75, 0xac, 0x12);
+DEFINE_DLSID(DLSID_ManufacturersID, 0xb03e1181, 0x8095, 0x11d2, 0xa1, 0xef, 0x0, 0x60, 0x8, 0x33, 0xdb, 0xd8);
+DEFINE_DLSID(DLSID_ProductID, 0xb03e1182, 0x8095, 0x11d2, 0xa1, 0xef, 0x0, 0x60, 0x8, 0x33, 0xdb, 0xd8);
+DEFINE_DLSID(DLSID_SamplePlaybackRate, 0x2a91f713, 0xa4bf, 0x11d2, 0xbb, 0xdf, 0x0, 0x60, 0x8, 0x33, 0xdb, 0xd8);
+#endif /* _INC_DLS2 */
+
diff --git a/arm-wt-22k/lib_src/eas_audioconst.h b/arm-wt-22k/lib_src/eas_audioconst.h
index 1cfa404..066148e 100644
--- a/arm-wt-22k/lib_src/eas_audioconst.h
+++ b/arm-wt-22k/lib_src/eas_audioconst.h
@@ -1,13 +1,13 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_audioconst.h
- *
- * Contents and purpose:
- * Defines audio constants related to the sample rate, bit size, etc.
- *
- *
- * Copyright Sonic Network Inc. 2005
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_audioconst.h
+ *
+ * Contents and purpose:
+ * Defines audio constants related to the sample rate, bit size, etc.
+ *
+ *
+ * Copyright Sonic Network Inc. 2005
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,78 +20,78 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 82 $
- * $Date: 2006-07-10 11:45:19 -0700 (Mon, 10 Jul 2006) $
- *----------------------------------------------------------------------------
-*/
-
-#ifndef _EAS_AUDIOCONST_H
-#define _EAS_AUDIOCONST_H
-
-/*----------------------------------------------------------------------------
- * These macros define the various characteristics of the defined sample rates
- *----------------------------------------------------------------------------
- * BUFFER_SIZE_IN_MONO_SAMPLES size of buffer in samples
- * _OUTPUT_SAMPLE_RATE compiled output sample rate
- * AUDIO_FRAME_LENGTH length of an audio frame in 256ths of a millisecond
- * SYNTH_UPDATE_PERIOD_IN_BITS length of an audio frame (2^x samples)
- *----------------------------------------------------------------------------
-*/
-
-#if defined (_SAMPLE_RATE_8000)
-#define BUFFER_SIZE_IN_MONO_SAMPLES 32
-#define _OUTPUT_SAMPLE_RATE 8000
-#define AUDIO_FRAME_LENGTH 1024
-#define SYNTH_UPDATE_PERIOD_IN_BITS 5
-
-#elif defined (_SAMPLE_RATE_16000)
-#define BUFFER_SIZE_IN_MONO_SAMPLES 64
-#define _OUTPUT_SAMPLE_RATE 16000
-#define AUDIO_FRAME_LENGTH 1024
-#define SYNTH_UPDATE_PERIOD_IN_BITS 6
-
-#elif defined (_SAMPLE_RATE_20000)
-#define BUFFER_SIZE_IN_MONO_SAMPLES 128
-#define _OUTPUT_SAMPLE_RATE 20000
-#define AUDIO_FRAME_LENGTH 1638
-#define SYNTH_UPDATE_PERIOD_IN_BITS 7
-
-#elif defined (_SAMPLE_RATE_22050)
-#define BUFFER_SIZE_IN_MONO_SAMPLES 128
-#define _OUTPUT_SAMPLE_RATE 22050
-#define AUDIO_FRAME_LENGTH 1486
-#define SYNTH_UPDATE_PERIOD_IN_BITS 7
-
-#elif defined (_SAMPLE_RATE_24000)
-#define BUFFER_SIZE_IN_MONO_SAMPLES 128
-#define _OUTPUT_SAMPLE_RATE 24000
-#define AUDIO_FRAME_LENGTH 1365
-#define SYNTH_UPDATE_PERIOD_IN_BITS 7
-
-#elif defined (_SAMPLE_RATE_32000)
-#define BUFFER_SIZE_IN_MONO_SAMPLES 128
-#define _OUTPUT_SAMPLE_RATE 32000
-#define AUDIO_FRAME_LENGTH 1024
-#define SYNTH_UPDATE_PERIOD_IN_BITS 7
-
-#elif defined (_SAMPLE_RATE_44100)
-#define BUFFER_SIZE_IN_MONO_SAMPLES 256
-#define _OUTPUT_SAMPLE_RATE 44100
-#define AUDIO_FRAME_LENGTH 1486
-#define SYNTH_UPDATE_PERIOD_IN_BITS 8
-
-#elif defined (_SAMPLE_RATE_48000)
-#define BUFFER_SIZE_IN_MONO_SAMPLES 256
-#define _OUTPUT_SAMPLE_RATE 48000
-#define AUDIO_FRAME_LENGTH 1365
-#define SYNTH_UPDATE_PERIOD_IN_BITS 8
-
-#else
-#error "_SAMPLE_RATE_XXXXX must be defined to valid rate"
-#endif
-
-#endif /* #ifndef _EAS_AUDIOCONST_H */
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 82 $
+ * $Date: 2006-07-10 11:45:19 -0700 (Mon, 10 Jul 2006) $
+ *----------------------------------------------------------------------------
+*/
+
+#ifndef _EAS_AUDIOCONST_H
+#define _EAS_AUDIOCONST_H
+
+/*----------------------------------------------------------------------------
+ * These macros define the various characteristics of the defined sample rates
+ *----------------------------------------------------------------------------
+ * BUFFER_SIZE_IN_MONO_SAMPLES size of buffer in samples
+ * _OUTPUT_SAMPLE_RATE compiled output sample rate
+ * AUDIO_FRAME_LENGTH length of an audio frame in 256ths of a millisecond
+ * SYNTH_UPDATE_PERIOD_IN_BITS length of an audio frame (2^x samples)
+ *----------------------------------------------------------------------------
+*/
+
+#if defined (_SAMPLE_RATE_8000)
+#define BUFFER_SIZE_IN_MONO_SAMPLES 32
+#define _OUTPUT_SAMPLE_RATE 8000
+#define AUDIO_FRAME_LENGTH 1024
+#define SYNTH_UPDATE_PERIOD_IN_BITS 5
+
+#elif defined (_SAMPLE_RATE_16000)
+#define BUFFER_SIZE_IN_MONO_SAMPLES 64
+#define _OUTPUT_SAMPLE_RATE 16000
+#define AUDIO_FRAME_LENGTH 1024
+#define SYNTH_UPDATE_PERIOD_IN_BITS 6
+
+#elif defined (_SAMPLE_RATE_20000)
+#define BUFFER_SIZE_IN_MONO_SAMPLES 128
+#define _OUTPUT_SAMPLE_RATE 20000
+#define AUDIO_FRAME_LENGTH 1638
+#define SYNTH_UPDATE_PERIOD_IN_BITS 7
+
+#elif defined (_SAMPLE_RATE_22050)
+#define BUFFER_SIZE_IN_MONO_SAMPLES 128
+#define _OUTPUT_SAMPLE_RATE 22050
+#define AUDIO_FRAME_LENGTH 1486
+#define SYNTH_UPDATE_PERIOD_IN_BITS 7
+
+#elif defined (_SAMPLE_RATE_24000)
+#define BUFFER_SIZE_IN_MONO_SAMPLES 128
+#define _OUTPUT_SAMPLE_RATE 24000
+#define AUDIO_FRAME_LENGTH 1365
+#define SYNTH_UPDATE_PERIOD_IN_BITS 7
+
+#elif defined (_SAMPLE_RATE_32000)
+#define BUFFER_SIZE_IN_MONO_SAMPLES 128
+#define _OUTPUT_SAMPLE_RATE 32000
+#define AUDIO_FRAME_LENGTH 1024
+#define SYNTH_UPDATE_PERIOD_IN_BITS 7
+
+#elif defined (_SAMPLE_RATE_44100)
+#define BUFFER_SIZE_IN_MONO_SAMPLES 256
+#define _OUTPUT_SAMPLE_RATE 44100
+#define AUDIO_FRAME_LENGTH 1486
+#define SYNTH_UPDATE_PERIOD_IN_BITS 8
+
+#elif defined (_SAMPLE_RATE_48000)
+#define BUFFER_SIZE_IN_MONO_SAMPLES 256
+#define _OUTPUT_SAMPLE_RATE 48000
+#define AUDIO_FRAME_LENGTH 1365
+#define SYNTH_UPDATE_PERIOD_IN_BITS 8
+
+#else
+#error "_SAMPLE_RATE_XXXXX must be defined to valid rate"
+#endif
+
+#endif /* #ifndef _EAS_AUDIOCONST_H */
+
diff --git a/arm-wt-22k/lib_src/eas_chorus.c b/arm-wt-22k/lib_src/eas_chorus.c
index bc42237..4a2c8d0 100644
--- a/arm-wt-22k/lib_src/eas_chorus.c
+++ b/arm-wt-22k/lib_src/eas_chorus.c
@@ -1,13 +1,13 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_chorus.c
- *
- * Contents and purpose:
- * Contains the implementation of the Chorus effect.
- *
- *
- * Copyright Sonic Network Inc. 2006
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_chorus.c
+ *
+ * Contents and purpose:
+ * Contains the implementation of the Chorus effect.
+ *
+ *
+ * Copyright Sonic Network Inc. 2006
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,585 +20,585 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 499 $
- * $Date: 2006-12-11 16:07:20 -0800 (Mon, 11 Dec 2006) $
- *----------------------------------------------------------------------------
-*/
-
-#include "eas_data.h"
-#include "eas_effects.h"
-#include "eas_math.h"
-#include "eas_chorusdata.h"
-#include "eas_chorus.h"
-#include "eas_config.h"
-#include "eas_host.h"
-#include "eas_report.h"
-
-/* prototypes for effects interface */
-static EAS_RESULT ChorusInit (EAS_DATA_HANDLE pEASData, EAS_VOID_PTR *pInstData);
-static void ChorusProcess (EAS_VOID_PTR pInstData, EAS_PCM *pSrc, EAS_PCM *pDst, EAS_I32 numSamples);
-static EAS_RESULT ChorusShutdown (EAS_DATA_HANDLE pEASData, EAS_VOID_PTR pInstData);
-static EAS_RESULT ChorusGetParam (EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue);
-static EAS_RESULT ChorusSetParam (EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value);
-
-/* common effects interface for configuration module */
-const S_EFFECTS_INTERFACE EAS_Chorus =
-{
- ChorusInit,
- ChorusProcess,
- ChorusShutdown,
- ChorusGetParam,
- ChorusSetParam
-};
-
-
-
-//LFO shape table used by the chorus, larger table would sound better
-//this is a sine wave, where 32767 = 1.0
-static const EAS_I16 EAS_chorusShape[CHORUS_SHAPE_SIZE] = {
- 0, 1608, 3212, 4808, 6393, 7962, 9512, 11309, 12539, 14010, 15446, 16846, 18204, 19519, 20787, 22005, 23170,
- 24279, 25329, 26319, 27245, 28105, 28898, 29621, 30273, 30852, 31356, 31785, 32137, 32412, 32609, 32728,
- 32767, 32728, 32609, 32412, 32137, 31785, 31356, 30852, 30273, 29621, 28898, 28105, 27245, 26319, 25329,
- 24279, 23170, 22005, 20787, 19519, 18204, 16846, 15446, 14010, 12539, 11039, 9512, 7962, 6393, 4808, 3212,
- 1608, 0, -1608, -3212, -4808, -6393, -7962, -9512, -11309, -12539, -14010, -15446, -16846, -18204, -19519,
- -20787, -22005, -23170, -24279, -25329, -26319, -27245, -28105, -28898, -29621, -30273, -30852, -31356, -31785,
- -32137, -32412, -32609, -32728, -32767, -32728, -32609, -32412, -32137, -31785, -31356, -30852, -30273, -29621,
- -28898, -28105, -27245, -26319, -25329, -24279, -23170, -22005, -20787, -19519, -18204, -16846, -15446, -14010,
- -12539, -11039, -9512, -7962, -6393, -4808, -3212, -1608
-};
-
-/*----------------------------------------------------------------------------
- * InitializeChorus()
- *----------------------------------------------------------------------------
- * Purpose: Initializes chorus parameters
- *
- *
- * Inputs:
- *
- * Outputs:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT ChorusInit (EAS_DATA_HANDLE pEASData, EAS_VOID_PTR *pInstData)
-{
- S_CHORUS_OBJECT *pChorusData;
- S_CHORUS_PRESET *pPreset;
- EAS_I32 index;
-
- /* check Configuration Module for data allocation */
- if (pEASData->staticMemoryModel)
- pChorusData = EAS_CMEnumFXData(EAS_MODULE_CHORUS);
-
- /* allocate dynamic memory */
- else
- pChorusData = EAS_HWMalloc(pEASData->hwInstData, sizeof(S_CHORUS_OBJECT));
-
- if (pChorusData == NULL)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_FATAL, "Failed to allocate Chorus memory\n"); */ }
- return EAS_ERROR_MALLOC_FAILED;
- }
-
- /* clear the structure */
- EAS_HWMemSet(pChorusData, 0, sizeof(S_CHORUS_OBJECT));
-
- ChorusReadInPresets(pChorusData);
-
- /* set some default values */
- pChorusData->bypass = EAS_CHORUS_BYPASS_DEFAULT;
- pChorusData->preset = EAS_CHORUS_PRESET_DEFAULT;
- pChorusData->m_nLevel = EAS_CHORUS_LEVEL_DEFAULT;
- pChorusData->m_nRate = EAS_CHORUS_RATE_DEFAULT;
- pChorusData->m_nDepth = EAS_CHORUS_DEPTH_DEFAULT;
-
- //chorus rate and depth need some massaging from preset value (which is sample rate independent)
-
- //convert rate from steps of .05 Hz to value which can be used as phase increment,
- //with current CHORUS_SHAPE_SIZE and rate limits, this fits into 16 bits
- //want to compute ((shapeSize * 65536) * (storedRate/20))/sampleRate;
- //computing it as below allows rate steps to be evenly spaced
- //uses 32 bit divide, but only once when new value is selected
- pChorusData->m_nRate = (EAS_I16)
- ((((EAS_I32)CHORUS_SHAPE_SIZE<<16)/(20*(EAS_I32)_OUTPUT_SAMPLE_RATE)) * pChorusData->m_nRate);
-
- //convert depth from steps of .05 ms, to samples, with 16 bit whole part, discard fraction
- //want to compute ((depth * sampleRate)/20000)
- //use the following approximation since 105/32 is roughly 65536/20000
- /*lint -e{704} use shift for performance */
- pChorusData->m_nDepth = (EAS_I16)
- (((((EAS_I32)pChorusData->m_nDepth * _OUTPUT_SAMPLE_RATE)>>5) * 105) >> 16);
-
- pChorusData->m_nLevel = pChorusData->m_nLevel;
-
- //zero delay memory for chorus
- for (index = CHORUS_L_SIZE - 1; index >= 0; index--)
- {
- pChorusData->chorusDelayL[index] = 0;
- }
- for (index = CHORUS_R_SIZE - 1; index >= 0; index--)
- {
- pChorusData->chorusDelayR[index] = 0;
- }
-
- //init delay line index, these are used to implement circular delay buffer
- pChorusData->chorusIndexL = 0;
- pChorusData->chorusIndexR = 0;
-
- //init LFO phase
- //16 bit whole part, 16 bit fraction
- pChorusData->lfoLPhase = 0;
- pChorusData->lfoRPhase = (CHORUS_SHAPE_SIZE << 16) >> 2; // 1/4 of total, i.e. 90 degrees out of phase;
-
- //init chorus delay position
- //right now chorus delay is a compile-time value, as is sample rate
- pChorusData->chorusTapPosition = (EAS_I16)((CHORUS_DELAY_MS * _OUTPUT_SAMPLE_RATE)/1000);
-
- //now copy from the new preset into Chorus
- pPreset = &pChorusData->m_sPreset.m_sPreset[pChorusData->m_nNextChorus];
-
- pChorusData->m_nLevel = pPreset->m_nLevel;
- pChorusData->m_nRate = pPreset->m_nRate;
- pChorusData->m_nDepth = pPreset->m_nDepth;
-
- pChorusData->m_nRate = (EAS_I16)
- ((((EAS_I32)CHORUS_SHAPE_SIZE<<16)/(20*(EAS_I32)_OUTPUT_SAMPLE_RATE)) * pChorusData->m_nRate);
-
- /*lint -e{704} use shift for performance */
- pChorusData->m_nDepth = (EAS_I16)
- (((((EAS_I32)pChorusData->m_nDepth * _OUTPUT_SAMPLE_RATE)>>5) * 105) >> 16);
-
- *pInstData = pChorusData;
-
- return EAS_SUCCESS;
-} /* end ChorusInit */
-
-/*----------------------------------------------------------------------------
- * WeightedTap()
- *----------------------------------------------------------------------------
- * Purpose: Does fractional array look-up using linear interpolation
- *
- * first convert indexDesired to actual desired index by taking into account indexReference
- * then do linear interpolation between two actual samples using fractional part
- *
- * Inputs:
- * array: pointer to array of signed 16 bit values, typically either PCM data or control data
- * indexReference: the circular buffer relative offset
- * indexDesired: the fractional index we are looking up (16 bits index + 16 bits fraction)
- * indexLimit: the total size of the array, used to compute buffer wrap
- *
- * Outputs:
- * Value from the input array, linearly interpolated between two actual data values
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_I16 WeightedTap(const EAS_I16 *array, EAS_I16 indexReference, EAS_I32 indexDesired, EAS_I16 indexLimit)
-{
- EAS_I16 index;
- EAS_I16 fraction;
- EAS_I16 val1;
- EAS_I16 val2;
-
- //separate indexDesired into whole and fractional parts
- /*lint -e{704} use shift for performance */
- index = (EAS_I16)(indexDesired >> 16);
- /*lint -e{704} use shift for performance */
- fraction = (EAS_I16)((indexDesired>>1) & 0x07FFF); //just use 15 bits of fractional part
-
- //adjust whole part by indexReference
- index = indexReference - index;
- //make sure we stay within array bounds, this implements circular buffer
- while (index < 0)
- {
- index += indexLimit;
- }
-
- //get two adjacent values from the array
- val1 = array[index];
-
- //handle special case when index == 0, else typical case
- if (index == 0)
- {
- val2 = array[indexLimit-1]; //get last value from array
- }
- else
- {
- val2 = array[index-1]; //get previous value from array
- }
-
- //compute linear interpolation as (val1 + ((val2-val1)*fraction))
- return(val1 + (EAS_I16)MULT_EG1_EG1(val2-val1,fraction));
-}
-
-/*----------------------------------------------------------------------------
- * ChorusProcess()
- *----------------------------------------------------------------------------
- * Purpose: compute the chorus on the input buffer, and mix into output buffer
- *
- *
- * Inputs:
- * src: pointer to input buffer of PCM values to be processed
- * dst: pointer to output buffer of PCM values we are to sume the result with
- * bufSize: the number of sample frames (i.e. stereo samples) in the buffer
- *
- * Outputs:
- * None
- *
- *----------------------------------------------------------------------------
-*/
-//compute the chorus, and mix into output buffer
-static void ChorusProcess (EAS_VOID_PTR pInstData, EAS_PCM *pSrc, EAS_PCM *pDst, EAS_I32 numSamples)
-{
- EAS_I32 ix;
- EAS_I32 nChannelNumber;
- EAS_I16 lfoValueLeft;
- EAS_I16 lfoValueRight;
- EAS_I32 positionOffsetL;
- EAS_I32 positionOffsetR;
- EAS_PCM tapL;
- EAS_PCM tapR;
- EAS_I32 tempValue;
- EAS_PCM nInputSample;
- EAS_I32 nOutputSample;
- EAS_PCM *pIn;
- EAS_PCM *pOut;
-
- S_CHORUS_OBJECT *pChorusData;
-
- pChorusData = (S_CHORUS_OBJECT*) pInstData;
-
- //if the chorus is disabled or turned all the way down
- if (pChorusData->bypass == EAS_TRUE || pChorusData->m_nLevel == 0)
- {
- if (pSrc != pDst)
- EAS_HWMemCpy(pSrc, pDst, numSamples * NUM_OUTPUT_CHANNELS * (EAS_I32) sizeof(EAS_PCM));
- return;
- }
-
- if (pChorusData->m_nNextChorus != pChorusData->m_nCurrentChorus)
- {
- ChorusUpdate(pChorusData);
- }
-
- for (nChannelNumber = 0; nChannelNumber < NUM_OUTPUT_CHANNELS; nChannelNumber++)
- {
-
- pIn = pSrc + nChannelNumber;
- pOut = pDst + nChannelNumber;
-
- if(nChannelNumber==0)
- {
- for (ix = 0; ix < numSamples; ix++)
- {
- nInputSample = *pIn;
- pIn += NUM_OUTPUT_CHANNELS;
-
- //feed input into chorus delay line
- pChorusData->chorusDelayL[pChorusData->chorusIndexL] = nInputSample;
-
- //compute chorus lfo value using phase as fractional index into chorus shape table
- //resulting value is between -1.0 and 1.0, expressed as signed 16 bit number
- lfoValueLeft = WeightedTap(EAS_chorusShape, 0, pChorusData->lfoLPhase, CHORUS_SHAPE_SIZE);
-
- //scale chorus depth by lfo value to get relative fractional sample index
- //index is expressed as 32 bit number with 16 bit fractional part
- /*lint -e{703} use shift for performance */
- positionOffsetL = pChorusData->m_nDepth * (((EAS_I32)lfoValueLeft) << 1);
-
- //add fixed chorus delay to get actual fractional sample index
- positionOffsetL += ((EAS_I32)pChorusData->chorusTapPosition) << 16;
-
- //get tap value from chorus delay using fractional sample index
- tapL = WeightedTap(pChorusData->chorusDelayL, pChorusData->chorusIndexL, positionOffsetL, CHORUS_L_SIZE);
-
- //scale by chorus level, then sum with input buffer contents and saturate
- tempValue = MULT_EG1_EG1(tapL, pChorusData->m_nLevel);
- nOutputSample = SATURATE(tempValue + nInputSample);
-
- *pOut = (EAS_I16)SATURATE(nOutputSample);
- pOut += NUM_OUTPUT_CHANNELS;
-
-
- //increment chorus delay index and make it wrap as needed
- //this implements circular buffer
- if ((pChorusData->chorusIndexL+=1) >= CHORUS_L_SIZE)
- pChorusData->chorusIndexL = 0;
-
- //increment fractional lfo phase, and make it wrap as needed
- pChorusData->lfoLPhase += pChorusData->m_nRate;
- while (pChorusData->lfoLPhase >= (CHORUS_SHAPE_SIZE<<16))
- {
- pChorusData->lfoLPhase -= (CHORUS_SHAPE_SIZE<<16);
- }
- }
- }
- else
- {
- for (ix = 0; ix < numSamples; ix++)
- {
- nInputSample = *pIn;
- pIn += NUM_OUTPUT_CHANNELS;
-
- //feed input into chorus delay line
- pChorusData->chorusDelayR[pChorusData->chorusIndexR] = nInputSample;
-
- //compute chorus lfo value using phase as fractional index into chorus shape table
- //resulting value is between -1.0 and 1.0, expressed as signed 16 bit number
- lfoValueRight = WeightedTap(EAS_chorusShape, 0, pChorusData->lfoRPhase, CHORUS_SHAPE_SIZE);
-
- //scale chorus depth by lfo value to get relative fractional sample index
- //index is expressed as 32 bit number with 16 bit fractional part
- /*lint -e{703} use shift for performance */
- positionOffsetR = pChorusData->m_nDepth * (((EAS_I32)lfoValueRight) << 1);
-
- //add fixed chorus delay to get actual fractional sample index
- positionOffsetR += ((EAS_I32)pChorusData->chorusTapPosition) << 16;
-
- //get tap value from chorus delay using fractional sample index
- tapR = WeightedTap(pChorusData->chorusDelayR, pChorusData->chorusIndexR, positionOffsetR, CHORUS_R_SIZE);
-
- //scale by chorus level, then sum with output buffer contents and saturate
- tempValue = MULT_EG1_EG1(tapR, pChorusData->m_nLevel);
- nOutputSample = SATURATE(tempValue + nInputSample);
-
- *pOut = (EAS_I16)SATURATE(nOutputSample);
- pOut += NUM_OUTPUT_CHANNELS;
-
- //increment chorus delay index and make it wrap as needed
- //this implements circular buffer
- if ((pChorusData->chorusIndexR+=1) >= CHORUS_R_SIZE)
- pChorusData->chorusIndexR = 0;
-
- //increment fractional lfo phase, and make it wrap as needed
- pChorusData->lfoRPhase += pChorusData->m_nRate;
- while (pChorusData->lfoRPhase >= (CHORUS_SHAPE_SIZE<<16))
- {
- pChorusData->lfoRPhase -= (CHORUS_SHAPE_SIZE<<16);
- }
- }
- }
-
- }
-} /* end ChorusProcess */
-
-
-
-/*----------------------------------------------------------------------------
- * ChorusShutdown()
- *----------------------------------------------------------------------------
- * Purpose:
- * Initializes the Chorus effect.
- *
- * Inputs:
- * pInstData - handle to instance data
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT ChorusShutdown (EAS_DATA_HANDLE pEASData, EAS_VOID_PTR pInstData)
-{
- /* check Configuration Module for static memory allocation */
- if (!pEASData->staticMemoryModel)
- EAS_HWFree(pEASData->hwInstData, pInstData);
- return EAS_SUCCESS;
-} /* end ChorusShutdown */
-
-/*----------------------------------------------------------------------------
- * ChorusGetParam()
- *----------------------------------------------------------------------------
- * Purpose:
- * Get a Chorus parameter
- *
- * Inputs:
- * pInstData - handle to instance data
- * param - parameter index
- * *pValue - pointer to variable to hold retrieved value
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT ChorusGetParam (EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue)
-{
- S_CHORUS_OBJECT *p;
-
- p = (S_CHORUS_OBJECT*) pInstData;
-
- switch (param)
- {
- case EAS_PARAM_CHORUS_BYPASS:
- *pValue = (EAS_I32) p->bypass;
- break;
- case EAS_PARAM_CHORUS_PRESET:
- *pValue = (EAS_I8) p->m_nCurrentChorus;
- break;
- case EAS_PARAM_CHORUS_RATE:
- *pValue = (EAS_I32) p->m_nRate;
- break;
- case EAS_PARAM_CHORUS_DEPTH:
- *pValue = (EAS_I32) p->m_nDepth;
- break;
- case EAS_PARAM_CHORUS_LEVEL:
- *pValue = (EAS_I32) p->m_nLevel;
- break;
- default:
- return EAS_ERROR_INVALID_PARAMETER;
- }
- return EAS_SUCCESS;
-} /* end ChorusGetParam */
-
-
-/*----------------------------------------------------------------------------
- * ChorusSetParam()
- *----------------------------------------------------------------------------
- * Purpose:
- * Set a Chorus parameter
- *
- * Inputs:
- * pInstData - handle to instance data
- * param - parameter index
- * *pValue - new paramter value
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT ChorusSetParam (EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value)
-{
- S_CHORUS_OBJECT *p;
-
- p = (S_CHORUS_OBJECT*) pInstData;
-
- switch (param)
- {
- case EAS_PARAM_CHORUS_BYPASS:
- p->bypass = (EAS_BOOL) value;
- break;
- case EAS_PARAM_CHORUS_PRESET:
- if(value!=EAS_PARAM_CHORUS_PRESET1 && value!=EAS_PARAM_CHORUS_PRESET2 &&
- value!=EAS_PARAM_CHORUS_PRESET3 && value!=EAS_PARAM_CHORUS_PRESET4)
- return EAS_ERROR_INVALID_PARAMETER;
- p->m_nNextChorus = (EAS_I8)value;
- break;
- case EAS_PARAM_CHORUS_RATE:
- if(value<EAS_CHORUS_RATE_MIN || value>EAS_CHORUS_RATE_MAX)
- return EAS_ERROR_INVALID_PARAMETER;
- p->m_nRate = (EAS_I16) value;
- break;
- case EAS_PARAM_CHORUS_DEPTH:
- if(value<EAS_CHORUS_DEPTH_MIN || value>EAS_CHORUS_DEPTH_MAX)
- return EAS_ERROR_INVALID_PARAMETER;
- p->m_nDepth = (EAS_I16) value;
- break;
- case EAS_PARAM_CHORUS_LEVEL:
- if(value<EAS_CHORUS_LEVEL_MIN || value>EAS_CHORUS_LEVEL_MAX)
- return EAS_ERROR_INVALID_PARAMETER;
- p->m_nLevel = (EAS_I16) value;
- break;
-
- default:
- return EAS_ERROR_INVALID_PARAMETER;
- }
- return EAS_SUCCESS;
-} /* end ChorusSetParam */
-
-
-/*----------------------------------------------------------------------------
- * ChorusReadInPresets()
- *----------------------------------------------------------------------------
- * Purpose: sets global Chorus preset bank to defaults
- *
- * Inputs:
- *
- * Outputs:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT ChorusReadInPresets(S_CHORUS_OBJECT *pChorusData)
-{
-
- int preset = 0;
- int defaultPreset = 0;
-
- //now init any remaining presets to defaults
- for (defaultPreset = preset; defaultPreset < CHORUS_MAX_TYPE; defaultPreset++)
- {
- S_CHORUS_PRESET *pPreset = &pChorusData->m_sPreset.m_sPreset[defaultPreset];
- if (defaultPreset == 0 || defaultPreset > CHORUS_MAX_TYPE-1)
- {
- pPreset->m_nDepth = 39;
- pPreset->m_nRate = 30;
- pPreset->m_nLevel = 32767;
- }
- else if (defaultPreset == 1)
- {
- pPreset->m_nDepth = 21;
- pPreset->m_nRate = 45;
- pPreset->m_nLevel = 25000;
- }
- else if (defaultPreset == 2)
- {
- pPreset->m_nDepth = 53;
- pPreset->m_nRate = 25;
- pPreset->m_nLevel = 32000;
- }
- else if (defaultPreset == 3)
- {
- pPreset->m_nDepth = 32;
- pPreset->m_nRate = 37;
- pPreset->m_nLevel = 29000;
- }
- }
-
- return EAS_SUCCESS;
-}
-
-
-/*----------------------------------------------------------------------------
- * ChorusUpdate
- *----------------------------------------------------------------------------
- * Purpose:
- * Update the Chorus preset parameters as required
- *
- * Inputs:
- *
- * Outputs:
- *
- *
- * Side Effects:
- * - chorus paramters will be changed
- * - m_nCurrentRoom := m_nNextRoom
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT ChorusUpdate(S_CHORUS_OBJECT *pChorusData)
-{
- S_CHORUS_PRESET *pPreset = &pChorusData->m_sPreset.m_sPreset[pChorusData->m_nNextChorus];
-
- pChorusData->m_nLevel = pPreset->m_nLevel;
- pChorusData->m_nRate = pPreset->m_nRate;
- pChorusData->m_nDepth = pPreset->m_nDepth;
-
- pChorusData->m_nRate = (EAS_I16)
- ((((EAS_I32)CHORUS_SHAPE_SIZE<<16)/(20*(EAS_I32)_OUTPUT_SAMPLE_RATE)) * pChorusData->m_nRate);
-
- /*lint -e{704} use shift for performance */
- pChorusData->m_nDepth = (EAS_I16)
- (((((EAS_I32)pChorusData->m_nDepth * _OUTPUT_SAMPLE_RATE)>>5) * 105) >> 16);
-
- pChorusData->m_nCurrentChorus = pChorusData->m_nNextChorus;
-
- return EAS_SUCCESS;
-
-} /* end ChorusUpdate */
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 499 $
+ * $Date: 2006-12-11 16:07:20 -0800 (Mon, 11 Dec 2006) $
+ *----------------------------------------------------------------------------
+*/
+
+#include "eas_data.h"
+#include "eas_effects.h"
+#include "eas_math.h"
+#include "eas_chorusdata.h"
+#include "eas_chorus.h"
+#include "eas_config.h"
+#include "eas_host.h"
+#include "eas_report.h"
+
+/* prototypes for effects interface */
+static EAS_RESULT ChorusInit (EAS_DATA_HANDLE pEASData, EAS_VOID_PTR *pInstData);
+static void ChorusProcess (EAS_VOID_PTR pInstData, EAS_PCM *pSrc, EAS_PCM *pDst, EAS_I32 numSamples);
+static EAS_RESULT ChorusShutdown (EAS_DATA_HANDLE pEASData, EAS_VOID_PTR pInstData);
+static EAS_RESULT ChorusGetParam (EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue);
+static EAS_RESULT ChorusSetParam (EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value);
+
+/* common effects interface for configuration module */
+const S_EFFECTS_INTERFACE EAS_Chorus =
+{
+ ChorusInit,
+ ChorusProcess,
+ ChorusShutdown,
+ ChorusGetParam,
+ ChorusSetParam
+};
+
+
+
+//LFO shape table used by the chorus, larger table would sound better
+//this is a sine wave, where 32767 = 1.0
+static const EAS_I16 EAS_chorusShape[CHORUS_SHAPE_SIZE] = {
+ 0, 1608, 3212, 4808, 6393, 7962, 9512, 11309, 12539, 14010, 15446, 16846, 18204, 19519, 20787, 22005, 23170,
+ 24279, 25329, 26319, 27245, 28105, 28898, 29621, 30273, 30852, 31356, 31785, 32137, 32412, 32609, 32728,
+ 32767, 32728, 32609, 32412, 32137, 31785, 31356, 30852, 30273, 29621, 28898, 28105, 27245, 26319, 25329,
+ 24279, 23170, 22005, 20787, 19519, 18204, 16846, 15446, 14010, 12539, 11039, 9512, 7962, 6393, 4808, 3212,
+ 1608, 0, -1608, -3212, -4808, -6393, -7962, -9512, -11309, -12539, -14010, -15446, -16846, -18204, -19519,
+ -20787, -22005, -23170, -24279, -25329, -26319, -27245, -28105, -28898, -29621, -30273, -30852, -31356, -31785,
+ -32137, -32412, -32609, -32728, -32767, -32728, -32609, -32412, -32137, -31785, -31356, -30852, -30273, -29621,
+ -28898, -28105, -27245, -26319, -25329, -24279, -23170, -22005, -20787, -19519, -18204, -16846, -15446, -14010,
+ -12539, -11039, -9512, -7962, -6393, -4808, -3212, -1608
+};
+
+/*----------------------------------------------------------------------------
+ * InitializeChorus()
+ *----------------------------------------------------------------------------
+ * Purpose: Initializes chorus parameters
+ *
+ *
+ * Inputs:
+ *
+ * Outputs:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT ChorusInit (EAS_DATA_HANDLE pEASData, EAS_VOID_PTR *pInstData)
+{
+ S_CHORUS_OBJECT *pChorusData;
+ S_CHORUS_PRESET *pPreset;
+ EAS_I32 index;
+
+ /* check Configuration Module for data allocation */
+ if (pEASData->staticMemoryModel)
+ pChorusData = EAS_CMEnumFXData(EAS_MODULE_CHORUS);
+
+ /* allocate dynamic memory */
+ else
+ pChorusData = EAS_HWMalloc(pEASData->hwInstData, sizeof(S_CHORUS_OBJECT));
+
+ if (pChorusData == NULL)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_FATAL, "Failed to allocate Chorus memory\n"); */ }
+ return EAS_ERROR_MALLOC_FAILED;
+ }
+
+ /* clear the structure */
+ EAS_HWMemSet(pChorusData, 0, sizeof(S_CHORUS_OBJECT));
+
+ ChorusReadInPresets(pChorusData);
+
+ /* set some default values */
+ pChorusData->bypass = EAS_CHORUS_BYPASS_DEFAULT;
+ pChorusData->preset = EAS_CHORUS_PRESET_DEFAULT;
+ pChorusData->m_nLevel = EAS_CHORUS_LEVEL_DEFAULT;
+ pChorusData->m_nRate = EAS_CHORUS_RATE_DEFAULT;
+ pChorusData->m_nDepth = EAS_CHORUS_DEPTH_DEFAULT;
+
+ //chorus rate and depth need some massaging from preset value (which is sample rate independent)
+
+ //convert rate from steps of .05 Hz to value which can be used as phase increment,
+ //with current CHORUS_SHAPE_SIZE and rate limits, this fits into 16 bits
+ //want to compute ((shapeSize * 65536) * (storedRate/20))/sampleRate;
+ //computing it as below allows rate steps to be evenly spaced
+ //uses 32 bit divide, but only once when new value is selected
+ pChorusData->m_nRate = (EAS_I16)
+ ((((EAS_I32)CHORUS_SHAPE_SIZE<<16)/(20*(EAS_I32)_OUTPUT_SAMPLE_RATE)) * pChorusData->m_nRate);
+
+ //convert depth from steps of .05 ms, to samples, with 16 bit whole part, discard fraction
+ //want to compute ((depth * sampleRate)/20000)
+ //use the following approximation since 105/32 is roughly 65536/20000
+ /*lint -e{704} use shift for performance */
+ pChorusData->m_nDepth = (EAS_I16)
+ (((((EAS_I32)pChorusData->m_nDepth * _OUTPUT_SAMPLE_RATE)>>5) * 105) >> 16);
+
+ pChorusData->m_nLevel = pChorusData->m_nLevel;
+
+ //zero delay memory for chorus
+ for (index = CHORUS_L_SIZE - 1; index >= 0; index--)
+ {
+ pChorusData->chorusDelayL[index] = 0;
+ }
+ for (index = CHORUS_R_SIZE - 1; index >= 0; index--)
+ {
+ pChorusData->chorusDelayR[index] = 0;
+ }
+
+ //init delay line index, these are used to implement circular delay buffer
+ pChorusData->chorusIndexL = 0;
+ pChorusData->chorusIndexR = 0;
+
+ //init LFO phase
+ //16 bit whole part, 16 bit fraction
+ pChorusData->lfoLPhase = 0;
+ pChorusData->lfoRPhase = (CHORUS_SHAPE_SIZE << 16) >> 2; // 1/4 of total, i.e. 90 degrees out of phase;
+
+ //init chorus delay position
+ //right now chorus delay is a compile-time value, as is sample rate
+ pChorusData->chorusTapPosition = (EAS_I16)((CHORUS_DELAY_MS * _OUTPUT_SAMPLE_RATE)/1000);
+
+ //now copy from the new preset into Chorus
+ pPreset = &pChorusData->m_sPreset.m_sPreset[pChorusData->m_nNextChorus];
+
+ pChorusData->m_nLevel = pPreset->m_nLevel;
+ pChorusData->m_nRate = pPreset->m_nRate;
+ pChorusData->m_nDepth = pPreset->m_nDepth;
+
+ pChorusData->m_nRate = (EAS_I16)
+ ((((EAS_I32)CHORUS_SHAPE_SIZE<<16)/(20*(EAS_I32)_OUTPUT_SAMPLE_RATE)) * pChorusData->m_nRate);
+
+ /*lint -e{704} use shift for performance */
+ pChorusData->m_nDepth = (EAS_I16)
+ (((((EAS_I32)pChorusData->m_nDepth * _OUTPUT_SAMPLE_RATE)>>5) * 105) >> 16);
+
+ *pInstData = pChorusData;
+
+ return EAS_SUCCESS;
+} /* end ChorusInit */
+
+/*----------------------------------------------------------------------------
+ * WeightedTap()
+ *----------------------------------------------------------------------------
+ * Purpose: Does fractional array look-up using linear interpolation
+ *
+ * first convert indexDesired to actual desired index by taking into account indexReference
+ * then do linear interpolation between two actual samples using fractional part
+ *
+ * Inputs:
+ * array: pointer to array of signed 16 bit values, typically either PCM data or control data
+ * indexReference: the circular buffer relative offset
+ * indexDesired: the fractional index we are looking up (16 bits index + 16 bits fraction)
+ * indexLimit: the total size of the array, used to compute buffer wrap
+ *
+ * Outputs:
+ * Value from the input array, linearly interpolated between two actual data values
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_I16 WeightedTap(const EAS_I16 *array, EAS_I16 indexReference, EAS_I32 indexDesired, EAS_I16 indexLimit)
+{
+ EAS_I16 index;
+ EAS_I16 fraction;
+ EAS_I16 val1;
+ EAS_I16 val2;
+
+ //separate indexDesired into whole and fractional parts
+ /*lint -e{704} use shift for performance */
+ index = (EAS_I16)(indexDesired >> 16);
+ /*lint -e{704} use shift for performance */
+ fraction = (EAS_I16)((indexDesired>>1) & 0x07FFF); //just use 15 bits of fractional part
+
+ //adjust whole part by indexReference
+ index = indexReference - index;
+ //make sure we stay within array bounds, this implements circular buffer
+ while (index < 0)
+ {
+ index += indexLimit;
+ }
+
+ //get two adjacent values from the array
+ val1 = array[index];
+
+ //handle special case when index == 0, else typical case
+ if (index == 0)
+ {
+ val2 = array[indexLimit-1]; //get last value from array
+ }
+ else
+ {
+ val2 = array[index-1]; //get previous value from array
+ }
+
+ //compute linear interpolation as (val1 + ((val2-val1)*fraction))
+ return(val1 + (EAS_I16)MULT_EG1_EG1(val2-val1,fraction));
+}
+
+/*----------------------------------------------------------------------------
+ * ChorusProcess()
+ *----------------------------------------------------------------------------
+ * Purpose: compute the chorus on the input buffer, and mix into output buffer
+ *
+ *
+ * Inputs:
+ * src: pointer to input buffer of PCM values to be processed
+ * dst: pointer to output buffer of PCM values we are to sume the result with
+ * bufSize: the number of sample frames (i.e. stereo samples) in the buffer
+ *
+ * Outputs:
+ * None
+ *
+ *----------------------------------------------------------------------------
+*/
+//compute the chorus, and mix into output buffer
+static void ChorusProcess (EAS_VOID_PTR pInstData, EAS_PCM *pSrc, EAS_PCM *pDst, EAS_I32 numSamples)
+{
+ EAS_I32 ix;
+ EAS_I32 nChannelNumber;
+ EAS_I16 lfoValueLeft;
+ EAS_I16 lfoValueRight;
+ EAS_I32 positionOffsetL;
+ EAS_I32 positionOffsetR;
+ EAS_PCM tapL;
+ EAS_PCM tapR;
+ EAS_I32 tempValue;
+ EAS_PCM nInputSample;
+ EAS_I32 nOutputSample;
+ EAS_PCM *pIn;
+ EAS_PCM *pOut;
+
+ S_CHORUS_OBJECT *pChorusData;
+
+ pChorusData = (S_CHORUS_OBJECT*) pInstData;
+
+ //if the chorus is disabled or turned all the way down
+ if (pChorusData->bypass == EAS_TRUE || pChorusData->m_nLevel == 0)
+ {
+ if (pSrc != pDst)
+ EAS_HWMemCpy(pSrc, pDst, numSamples * NUM_OUTPUT_CHANNELS * (EAS_I32) sizeof(EAS_PCM));
+ return;
+ }
+
+ if (pChorusData->m_nNextChorus != pChorusData->m_nCurrentChorus)
+ {
+ ChorusUpdate(pChorusData);
+ }
+
+ for (nChannelNumber = 0; nChannelNumber < NUM_OUTPUT_CHANNELS; nChannelNumber++)
+ {
+
+ pIn = pSrc + nChannelNumber;
+ pOut = pDst + nChannelNumber;
+
+ if(nChannelNumber==0)
+ {
+ for (ix = 0; ix < numSamples; ix++)
+ {
+ nInputSample = *pIn;
+ pIn += NUM_OUTPUT_CHANNELS;
+
+ //feed input into chorus delay line
+ pChorusData->chorusDelayL[pChorusData->chorusIndexL] = nInputSample;
+
+ //compute chorus lfo value using phase as fractional index into chorus shape table
+ //resulting value is between -1.0 and 1.0, expressed as signed 16 bit number
+ lfoValueLeft = WeightedTap(EAS_chorusShape, 0, pChorusData->lfoLPhase, CHORUS_SHAPE_SIZE);
+
+ //scale chorus depth by lfo value to get relative fractional sample index
+ //index is expressed as 32 bit number with 16 bit fractional part
+ /*lint -e{703} use shift for performance */
+ positionOffsetL = pChorusData->m_nDepth * (((EAS_I32)lfoValueLeft) << 1);
+
+ //add fixed chorus delay to get actual fractional sample index
+ positionOffsetL += ((EAS_I32)pChorusData->chorusTapPosition) << 16;
+
+ //get tap value from chorus delay using fractional sample index
+ tapL = WeightedTap(pChorusData->chorusDelayL, pChorusData->chorusIndexL, positionOffsetL, CHORUS_L_SIZE);
+
+ //scale by chorus level, then sum with input buffer contents and saturate
+ tempValue = MULT_EG1_EG1(tapL, pChorusData->m_nLevel);
+ nOutputSample = SATURATE(tempValue + nInputSample);
+
+ *pOut = (EAS_I16)SATURATE(nOutputSample);
+ pOut += NUM_OUTPUT_CHANNELS;
+
+
+ //increment chorus delay index and make it wrap as needed
+ //this implements circular buffer
+ if ((pChorusData->chorusIndexL+=1) >= CHORUS_L_SIZE)
+ pChorusData->chorusIndexL = 0;
+
+ //increment fractional lfo phase, and make it wrap as needed
+ pChorusData->lfoLPhase += pChorusData->m_nRate;
+ while (pChorusData->lfoLPhase >= (CHORUS_SHAPE_SIZE<<16))
+ {
+ pChorusData->lfoLPhase -= (CHORUS_SHAPE_SIZE<<16);
+ }
+ }
+ }
+ else
+ {
+ for (ix = 0; ix < numSamples; ix++)
+ {
+ nInputSample = *pIn;
+ pIn += NUM_OUTPUT_CHANNELS;
+
+ //feed input into chorus delay line
+ pChorusData->chorusDelayR[pChorusData->chorusIndexR] = nInputSample;
+
+ //compute chorus lfo value using phase as fractional index into chorus shape table
+ //resulting value is between -1.0 and 1.0, expressed as signed 16 bit number
+ lfoValueRight = WeightedTap(EAS_chorusShape, 0, pChorusData->lfoRPhase, CHORUS_SHAPE_SIZE);
+
+ //scale chorus depth by lfo value to get relative fractional sample index
+ //index is expressed as 32 bit number with 16 bit fractional part
+ /*lint -e{703} use shift for performance */
+ positionOffsetR = pChorusData->m_nDepth * (((EAS_I32)lfoValueRight) << 1);
+
+ //add fixed chorus delay to get actual fractional sample index
+ positionOffsetR += ((EAS_I32)pChorusData->chorusTapPosition) << 16;
+
+ //get tap value from chorus delay using fractional sample index
+ tapR = WeightedTap(pChorusData->chorusDelayR, pChorusData->chorusIndexR, positionOffsetR, CHORUS_R_SIZE);
+
+ //scale by chorus level, then sum with output buffer contents and saturate
+ tempValue = MULT_EG1_EG1(tapR, pChorusData->m_nLevel);
+ nOutputSample = SATURATE(tempValue + nInputSample);
+
+ *pOut = (EAS_I16)SATURATE(nOutputSample);
+ pOut += NUM_OUTPUT_CHANNELS;
+
+ //increment chorus delay index and make it wrap as needed
+ //this implements circular buffer
+ if ((pChorusData->chorusIndexR+=1) >= CHORUS_R_SIZE)
+ pChorusData->chorusIndexR = 0;
+
+ //increment fractional lfo phase, and make it wrap as needed
+ pChorusData->lfoRPhase += pChorusData->m_nRate;
+ while (pChorusData->lfoRPhase >= (CHORUS_SHAPE_SIZE<<16))
+ {
+ pChorusData->lfoRPhase -= (CHORUS_SHAPE_SIZE<<16);
+ }
+ }
+ }
+
+ }
+} /* end ChorusProcess */
+
+
+
+/*----------------------------------------------------------------------------
+ * ChorusShutdown()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Initializes the Chorus effect.
+ *
+ * Inputs:
+ * pInstData - handle to instance data
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT ChorusShutdown (EAS_DATA_HANDLE pEASData, EAS_VOID_PTR pInstData)
+{
+ /* check Configuration Module for static memory allocation */
+ if (!pEASData->staticMemoryModel)
+ EAS_HWFree(pEASData->hwInstData, pInstData);
+ return EAS_SUCCESS;
+} /* end ChorusShutdown */
+
+/*----------------------------------------------------------------------------
+ * ChorusGetParam()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Get a Chorus parameter
+ *
+ * Inputs:
+ * pInstData - handle to instance data
+ * param - parameter index
+ * *pValue - pointer to variable to hold retrieved value
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT ChorusGetParam (EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue)
+{
+ S_CHORUS_OBJECT *p;
+
+ p = (S_CHORUS_OBJECT*) pInstData;
+
+ switch (param)
+ {
+ case EAS_PARAM_CHORUS_BYPASS:
+ *pValue = (EAS_I32) p->bypass;
+ break;
+ case EAS_PARAM_CHORUS_PRESET:
+ *pValue = (EAS_I8) p->m_nCurrentChorus;
+ break;
+ case EAS_PARAM_CHORUS_RATE:
+ *pValue = (EAS_I32) p->m_nRate;
+ break;
+ case EAS_PARAM_CHORUS_DEPTH:
+ *pValue = (EAS_I32) p->m_nDepth;
+ break;
+ case EAS_PARAM_CHORUS_LEVEL:
+ *pValue = (EAS_I32) p->m_nLevel;
+ break;
+ default:
+ return EAS_ERROR_INVALID_PARAMETER;
+ }
+ return EAS_SUCCESS;
+} /* end ChorusGetParam */
+
+
+/*----------------------------------------------------------------------------
+ * ChorusSetParam()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Set a Chorus parameter
+ *
+ * Inputs:
+ * pInstData - handle to instance data
+ * param - parameter index
+ * *pValue - new paramter value
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT ChorusSetParam (EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value)
+{
+ S_CHORUS_OBJECT *p;
+
+ p = (S_CHORUS_OBJECT*) pInstData;
+
+ switch (param)
+ {
+ case EAS_PARAM_CHORUS_BYPASS:
+ p->bypass = (EAS_BOOL) value;
+ break;
+ case EAS_PARAM_CHORUS_PRESET:
+ if(value!=EAS_PARAM_CHORUS_PRESET1 && value!=EAS_PARAM_CHORUS_PRESET2 &&
+ value!=EAS_PARAM_CHORUS_PRESET3 && value!=EAS_PARAM_CHORUS_PRESET4)
+ return EAS_ERROR_INVALID_PARAMETER;
+ p->m_nNextChorus = (EAS_I8)value;
+ break;
+ case EAS_PARAM_CHORUS_RATE:
+ if(value<EAS_CHORUS_RATE_MIN || value>EAS_CHORUS_RATE_MAX)
+ return EAS_ERROR_INVALID_PARAMETER;
+ p->m_nRate = (EAS_I16) value;
+ break;
+ case EAS_PARAM_CHORUS_DEPTH:
+ if(value<EAS_CHORUS_DEPTH_MIN || value>EAS_CHORUS_DEPTH_MAX)
+ return EAS_ERROR_INVALID_PARAMETER;
+ p->m_nDepth = (EAS_I16) value;
+ break;
+ case EAS_PARAM_CHORUS_LEVEL:
+ if(value<EAS_CHORUS_LEVEL_MIN || value>EAS_CHORUS_LEVEL_MAX)
+ return EAS_ERROR_INVALID_PARAMETER;
+ p->m_nLevel = (EAS_I16) value;
+ break;
+
+ default:
+ return EAS_ERROR_INVALID_PARAMETER;
+ }
+ return EAS_SUCCESS;
+} /* end ChorusSetParam */
+
+
+/*----------------------------------------------------------------------------
+ * ChorusReadInPresets()
+ *----------------------------------------------------------------------------
+ * Purpose: sets global Chorus preset bank to defaults
+ *
+ * Inputs:
+ *
+ * Outputs:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT ChorusReadInPresets(S_CHORUS_OBJECT *pChorusData)
+{
+
+ int preset = 0;
+ int defaultPreset = 0;
+
+ //now init any remaining presets to defaults
+ for (defaultPreset = preset; defaultPreset < CHORUS_MAX_TYPE; defaultPreset++)
+ {
+ S_CHORUS_PRESET *pPreset = &pChorusData->m_sPreset.m_sPreset[defaultPreset];
+ if (defaultPreset == 0 || defaultPreset > CHORUS_MAX_TYPE-1)
+ {
+ pPreset->m_nDepth = 39;
+ pPreset->m_nRate = 30;
+ pPreset->m_nLevel = 32767;
+ }
+ else if (defaultPreset == 1)
+ {
+ pPreset->m_nDepth = 21;
+ pPreset->m_nRate = 45;
+ pPreset->m_nLevel = 25000;
+ }
+ else if (defaultPreset == 2)
+ {
+ pPreset->m_nDepth = 53;
+ pPreset->m_nRate = 25;
+ pPreset->m_nLevel = 32000;
+ }
+ else if (defaultPreset == 3)
+ {
+ pPreset->m_nDepth = 32;
+ pPreset->m_nRate = 37;
+ pPreset->m_nLevel = 29000;
+ }
+ }
+
+ return EAS_SUCCESS;
+}
+
+
+/*----------------------------------------------------------------------------
+ * ChorusUpdate
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Update the Chorus preset parameters as required
+ *
+ * Inputs:
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ * - chorus paramters will be changed
+ * - m_nCurrentRoom := m_nNextRoom
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT ChorusUpdate(S_CHORUS_OBJECT *pChorusData)
+{
+ S_CHORUS_PRESET *pPreset = &pChorusData->m_sPreset.m_sPreset[pChorusData->m_nNextChorus];
+
+ pChorusData->m_nLevel = pPreset->m_nLevel;
+ pChorusData->m_nRate = pPreset->m_nRate;
+ pChorusData->m_nDepth = pPreset->m_nDepth;
+
+ pChorusData->m_nRate = (EAS_I16)
+ ((((EAS_I32)CHORUS_SHAPE_SIZE<<16)/(20*(EAS_I32)_OUTPUT_SAMPLE_RATE)) * pChorusData->m_nRate);
+
+ /*lint -e{704} use shift for performance */
+ pChorusData->m_nDepth = (EAS_I16)
+ (((((EAS_I32)pChorusData->m_nDepth * _OUTPUT_SAMPLE_RATE)>>5) * 105) >> 16);
+
+ pChorusData->m_nCurrentChorus = pChorusData->m_nNextChorus;
+
+ return EAS_SUCCESS;
+
+} /* end ChorusUpdate */
diff --git a/arm-wt-22k/lib_src/eas_chorusdata.c b/arm-wt-22k/lib_src/eas_chorusdata.c
index caee1ed..ec71ff8 100644
--- a/arm-wt-22k/lib_src/eas_chorusdata.c
+++ b/arm-wt-22k/lib_src/eas_chorusdata.c
@@ -1,13 +1,13 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_chorusdata.c
- *
- * Contents and purpose:
- * Contains the static data allocation for the Chorus effect
- *
- *
- * Copyright Sonic Network Inc. 2006
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_chorusdata.c
+ *
+ * Contents and purpose:
+ * Contains the static data allocation for the Chorus effect
+ *
+ *
+ * Copyright Sonic Network Inc. 2006
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,15 +20,15 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 550 $
- * $Date: 2007-02-02 09:37:03 -0800 (Fri, 02 Feb 2007) $
- *----------------------------------------------------------------------------
-*/
-
-#include "eas_chorusdata.h"
-
-S_CHORUS_OBJECT eas_ChorusData;
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 550 $
+ * $Date: 2007-02-02 09:37:03 -0800 (Fri, 02 Feb 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+#include "eas_chorusdata.h"
+
+S_CHORUS_OBJECT eas_ChorusData;
+
diff --git a/arm-wt-22k/lib_src/eas_chorusdata.h b/arm-wt-22k/lib_src/eas_chorusdata.h
index 4420ddd..ec8daa4 100644
--- a/arm-wt-22k/lib_src/eas_chorusdata.h
+++ b/arm-wt-22k/lib_src/eas_chorusdata.h
@@ -1,13 +1,13 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_chorusdata.h
- *
- * Contents and purpose:
- * Contains the prototypes for the Chorus effect.
- *
- *
- * Copyright Sonic Network Inc. 2006
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_chorusdata.h
+ *
+ * Contents and purpose:
+ * Contains the prototypes for the Chorus effect.
+ *
+ *
+ * Copyright Sonic Network Inc. 2006
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,141 +20,141 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 309 $
- * $Date: 2006-09-12 18:52:45 -0700 (Tue, 12 Sep 2006) $
- *----------------------------------------------------------------------------
-*/
-
-#ifndef _EAS_CHORUS_H
-#define _EAS_CHORUS_H
-
-#include "eas_types.h"
-#include "eas_audioconst.h"
-
-//defines for chorus
-
-#define EAS_CHORUS_BYPASS_DEFAULT 1
-#define EAS_CHORUS_PRESET_DEFAULT 0
-#define EAS_CHORUS_RATE_DEFAULT 30
-#define EAS_CHORUS_DEPTH_DEFAULT 39
-#define EAS_CHORUS_LEVEL_DEFAULT 32767
-
-#define EAS_CHORUS_LEVEL_MIN 0
-#define EAS_CHORUS_LEVEL_MAX 32767
-
-#define EAS_CHORUS_RATE_MIN 10
-#define EAS_CHORUS_RATE_MAX 50
-
-#define EAS_CHORUS_DEPTH_MIN 15
-#define EAS_CHORUS_DEPTH_MAX 60
-
-#define CHORUS_SIZE_MS 20
-#define CHORUS_L_SIZE ((CHORUS_SIZE_MS*_OUTPUT_SAMPLE_RATE)/1000)
-#define CHORUS_R_SIZE CHORUS_L_SIZE
-#define CHORUS_SHAPE_SIZE 128
-#define CHORUS_DELAY_MS 10
-
-#define CHORUS_MAX_TYPE 4 // any Chorus numbers larger than this are invalid
-
-typedef struct
-{
- EAS_I16 m_nRate;
- EAS_I16 m_nDepth;
- EAS_I16 m_nLevel;
-
-} S_CHORUS_PRESET;
-
-typedef struct
-{
- S_CHORUS_PRESET m_sPreset[CHORUS_MAX_TYPE]; //array of presets
-
-} S_CHORUS_PRESET_BANK;
-
-/* parameters for each Chorus */
-typedef struct
-{
- EAS_I32 lfoLPhase;
- EAS_I32 lfoRPhase;
- EAS_I16 chorusIndexL;
- EAS_I16 chorusIndexR;
- EAS_U16 chorusTapPosition;
-
- EAS_I16 m_nRate;
- EAS_I16 m_nDepth;
- EAS_I16 m_nLevel;
-
- //delay lines used by the chorus, longer would sound better
- EAS_PCM chorusDelayL[CHORUS_L_SIZE];
- EAS_PCM chorusDelayR[CHORUS_R_SIZE];
-
- EAS_BOOL bypass;
- EAS_I8 preset;
-
- EAS_I16 m_nCurrentChorus; // preset number for current Chorus
- EAS_I16 m_nNextChorus; // preset number for next Chorus
-
- S_CHORUS_PRESET pPreset;
-
- S_CHORUS_PRESET_BANK m_sPreset;
-
-} S_CHORUS_OBJECT;
-
-
-/*----------------------------------------------------------------------------
- * WeightedTap()
- *----------------------------------------------------------------------------
- * Purpose: Does fractional array look-up using linear interpolation
- *
- * first convert indexDesired to actual desired index by taking into account indexReference
- * then do linear interpolation between two actual samples using fractional part
- *
- * Inputs:
- * array: pointer to array of signed 16 bit values, typically either PCM data or control data
- * indexReference: the circular buffer relative offset
- * indexDesired: the fractional index we are looking up (16 bits index + 16 bits fraction)
- * indexLimit: the total size of the array, used to compute buffer wrap
- *
- * Outputs:
- * Value from the input array, linearly interpolated between two actual data values
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_I16 WeightedTap(const EAS_I16 *array, EAS_I16 indexReference, EAS_I32 indexDesired, EAS_I16 indexLimit);
-
-/*----------------------------------------------------------------------------
- * ChorusReadInPresets()
- *----------------------------------------------------------------------------
- * Purpose: sets global Chorus preset bank to defaults
- *
- * Inputs:
- *
- * Outputs:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT ChorusReadInPresets(S_CHORUS_OBJECT *pChorusData);
-
-/*----------------------------------------------------------------------------
- * ChorusUpdate
- *----------------------------------------------------------------------------
- * Purpose:
- * Update the Chorus preset parameters as required
- *
- * Inputs:
- *
- * Outputs:
- *
- *
- * Side Effects:
- * - chorus paramters will be changed
- * - m_nCurrentChorus := m_nNextChorus
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT ChorusUpdate(S_CHORUS_OBJECT* pChorusData);
-
-#endif /* #ifndef _EAS_CHORUSDATA_H */
-
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 309 $
+ * $Date: 2006-09-12 18:52:45 -0700 (Tue, 12 Sep 2006) $
+ *----------------------------------------------------------------------------
+*/
+
+#ifndef _EAS_CHORUS_H
+#define _EAS_CHORUS_H
+
+#include "eas_types.h"
+#include "eas_audioconst.h"
+
+//defines for chorus
+
+#define EAS_CHORUS_BYPASS_DEFAULT 1
+#define EAS_CHORUS_PRESET_DEFAULT 0
+#define EAS_CHORUS_RATE_DEFAULT 30
+#define EAS_CHORUS_DEPTH_DEFAULT 39
+#define EAS_CHORUS_LEVEL_DEFAULT 32767
+
+#define EAS_CHORUS_LEVEL_MIN 0
+#define EAS_CHORUS_LEVEL_MAX 32767
+
+#define EAS_CHORUS_RATE_MIN 10
+#define EAS_CHORUS_RATE_MAX 50
+
+#define EAS_CHORUS_DEPTH_MIN 15
+#define EAS_CHORUS_DEPTH_MAX 60
+
+#define CHORUS_SIZE_MS 20
+#define CHORUS_L_SIZE ((CHORUS_SIZE_MS*_OUTPUT_SAMPLE_RATE)/1000)
+#define CHORUS_R_SIZE CHORUS_L_SIZE
+#define CHORUS_SHAPE_SIZE 128
+#define CHORUS_DELAY_MS 10
+
+#define CHORUS_MAX_TYPE 4 // any Chorus numbers larger than this are invalid
+
+typedef struct
+{
+ EAS_I16 m_nRate;
+ EAS_I16 m_nDepth;
+ EAS_I16 m_nLevel;
+
+} S_CHORUS_PRESET;
+
+typedef struct
+{
+ S_CHORUS_PRESET m_sPreset[CHORUS_MAX_TYPE]; //array of presets
+
+} S_CHORUS_PRESET_BANK;
+
+/* parameters for each Chorus */
+typedef struct
+{
+ EAS_I32 lfoLPhase;
+ EAS_I32 lfoRPhase;
+ EAS_I16 chorusIndexL;
+ EAS_I16 chorusIndexR;
+ EAS_U16 chorusTapPosition;
+
+ EAS_I16 m_nRate;
+ EAS_I16 m_nDepth;
+ EAS_I16 m_nLevel;
+
+ //delay lines used by the chorus, longer would sound better
+ EAS_PCM chorusDelayL[CHORUS_L_SIZE];
+ EAS_PCM chorusDelayR[CHORUS_R_SIZE];
+
+ EAS_BOOL bypass;
+ EAS_I8 preset;
+
+ EAS_I16 m_nCurrentChorus; // preset number for current Chorus
+ EAS_I16 m_nNextChorus; // preset number for next Chorus
+
+ S_CHORUS_PRESET pPreset;
+
+ S_CHORUS_PRESET_BANK m_sPreset;
+
+} S_CHORUS_OBJECT;
+
+
+/*----------------------------------------------------------------------------
+ * WeightedTap()
+ *----------------------------------------------------------------------------
+ * Purpose: Does fractional array look-up using linear interpolation
+ *
+ * first convert indexDesired to actual desired index by taking into account indexReference
+ * then do linear interpolation between two actual samples using fractional part
+ *
+ * Inputs:
+ * array: pointer to array of signed 16 bit values, typically either PCM data or control data
+ * indexReference: the circular buffer relative offset
+ * indexDesired: the fractional index we are looking up (16 bits index + 16 bits fraction)
+ * indexLimit: the total size of the array, used to compute buffer wrap
+ *
+ * Outputs:
+ * Value from the input array, linearly interpolated between two actual data values
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_I16 WeightedTap(const EAS_I16 *array, EAS_I16 indexReference, EAS_I32 indexDesired, EAS_I16 indexLimit);
+
+/*----------------------------------------------------------------------------
+ * ChorusReadInPresets()
+ *----------------------------------------------------------------------------
+ * Purpose: sets global Chorus preset bank to defaults
+ *
+ * Inputs:
+ *
+ * Outputs:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT ChorusReadInPresets(S_CHORUS_OBJECT *pChorusData);
+
+/*----------------------------------------------------------------------------
+ * ChorusUpdate
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Update the Chorus preset parameters as required
+ *
+ * Inputs:
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ * - chorus paramters will be changed
+ * - m_nCurrentChorus := m_nNextChorus
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT ChorusUpdate(S_CHORUS_OBJECT* pChorusData);
+
+#endif /* #ifndef _EAS_CHORUSDATA_H */
+
+
diff --git a/arm-wt-22k/lib_src/eas_ctype.h b/arm-wt-22k/lib_src/eas_ctype.h
index 8503870..14fa96f 100644
--- a/arm-wt-22k/lib_src/eas_ctype.h
+++ b/arm-wt-22k/lib_src/eas_ctype.h
@@ -1,14 +1,14 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_ctype.h
- *
- * Contents and purpose:
- * This is a replacement for the CRT ctype.h functions. These
- * functions are currently ASCII only, but eventually, we will want
- * to support wide-characters for localization.
- *
- * Copyright (c) 2005 Sonic Network Inc.
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_ctype.h
+ *
+ * Contents and purpose:
+ * This is a replacement for the CRT ctype.h functions. These
+ * functions are currently ASCII only, but eventually, we will want
+ * to support wide-characters for localization.
+ *
+ * Copyright (c) 2005 Sonic Network Inc.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,21 +21,21 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 429 $
- * $Date: 2006-10-19 23:50:15 -0700 (Thu, 19 Oct 2006) $
- *----------------------------------------------------------------------------
-*/
-
-#ifndef _EAS_CTYPE_H
-#define _EAS_CTYPE_H
-
-EAS_INLINE EAS_I8 IsDigit (EAS_I8 c) { return ((c >= '0') && (c <= '9')); }
-EAS_INLINE EAS_I8 IsSpace (EAS_I8 c) { return (((c >= 9) && (c <= 13)) || (c == ' ')); }
-EAS_INLINE EAS_I8 ToUpper (EAS_I8 c) { if ((c >= 'a') && (c <= 'z')) return c & ~0x20; else return c; }
-EAS_INLINE EAS_I8 ToLower (EAS_I8 c) { if ((c >= 'A') && (c <= 'Z')) return c |= 0x20; else return c; }
-
-#endif
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 429 $
+ * $Date: 2006-10-19 23:50:15 -0700 (Thu, 19 Oct 2006) $
+ *----------------------------------------------------------------------------
+*/
+
+#ifndef _EAS_CTYPE_H
+#define _EAS_CTYPE_H
+
+EAS_INLINE EAS_I8 IsDigit (EAS_I8 c) { return ((c >= '0') && (c <= '9')); }
+EAS_INLINE EAS_I8 IsSpace (EAS_I8 c) { return (((c >= 9) && (c <= 13)) || (c == ' ')); }
+EAS_INLINE EAS_I8 ToUpper (EAS_I8 c) { if ((c >= 'a') && (c <= 'z')) return c & ~0x20; else return c; }
+EAS_INLINE EAS_I8 ToLower (EAS_I8 c) { if ((c >= 'A') && (c <= 'Z')) return c |= 0x20; else return c; }
+
+#endif
+
diff --git a/arm-wt-22k/lib_src/eas_data.c b/arm-wt-22k/lib_src/eas_data.c
index bb60ef2..31a4e6a 100644
--- a/arm-wt-22k/lib_src/eas_data.c
+++ b/arm-wt-22k/lib_src/eas_data.c
@@ -1,12 +1,12 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_data.c
- *
- * Contents and purpose:
- * Contains a data allocation for synthesizer
- *
- * Copyright Sonic Network Inc. 2004
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_data.c
+ *
+ * Contents and purpose:
+ * Contains a data allocation for synthesizer
+ *
+ * Copyright Sonic Network Inc. 2004
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,19 +19,19 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 547 $
- * $Date: 2007-01-31 16:30:17 -0800 (Wed, 31 Jan 2007) $
- *----------------------------------------------------------------------------
-*/
-
-// includes
-#include "eas_data.h"
-
-// globals
-S_EAS_DATA eas_Data;
-S_VOICE_MGR eas_Synth;
-S_SYNTH eas_MIDI;
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 547 $
+ * $Date: 2007-01-31 16:30:17 -0800 (Wed, 31 Jan 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+// includes
+#include "eas_data.h"
+
+// globals
+S_EAS_DATA eas_Data;
+S_VOICE_MGR eas_Synth;
+S_SYNTH eas_MIDI;
+
diff --git a/arm-wt-22k/lib_src/eas_data.h b/arm-wt-22k/lib_src/eas_data.h
index 28957fd..7793fdb 100644
--- a/arm-wt-22k/lib_src/eas_data.h
+++ b/arm-wt-22k/lib_src/eas_data.h
@@ -1,13 +1,13 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_data.h
- *
- * Contents and purpose:
- * This header defines all types, to support dynamic allocation of the
- * memory resources needed for persistent EAS data.
- *
- * Copyright 2004 Sonic Network Inc.
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_data.h
+ *
+ * Contents and purpose:
+ * This header defines all types, to support dynamic allocation of the
+ * memory resources needed for persistent EAS data.
+ *
+ * Copyright 2004 Sonic Network Inc.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,114 +20,114 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 842 $
- * $Date: 2007-08-23 14:32:31 -0700 (Thu, 23 Aug 2007) $
- *----------------------------------------------------------------------------
-*/
-
-#ifndef _EAS_DATA_H
-#define _EAS_DATA_H
-
-#define JET_INTERFACE
-
-#include "eas_types.h"
-#include "eas_synthcfg.h"
-#include "eas.h"
-#include "eas_audioconst.h"
-#include "eas_sndlib.h"
-#include "eas_pcm.h"
-#include "eas_pcmdata.h"
-#include "eas_synth.h"
-#include "eas_miditypes.h"
-#include "eas_effects.h"
-
-#ifdef AUX_MIXER
-#include "eas_auxmixdata.h"
-#endif
-
-#ifdef JET_INTERFACE
-#include "jet.h"
-#endif
-
-#ifdef _METRICS_ENABLED
-#include "eas_perf.h"
-#endif
-
-#ifndef MAX_NUMBER_STREAMS
-#define MAX_NUMBER_STREAMS 4
-#endif
-
-/* flags for S_EAS_STREAM */
-#define STREAM_FLAGS_PARSED 1
-#define STREAM_FLAGS_PAUSE 2
-#define STREAM_FLAGS_LOCATE 4
-#define STREAM_FLAGS_RESUME 8
-
-/* structure for parsing a stream */
-typedef struct s_eas_stream_tag
-{
- void *pParserModule;
- EAS_U32 time;
- EAS_U32 frameLength;
- EAS_I32 repeatCount;
- EAS_VOID_PTR handle;
- EAS_U8 volume;
- EAS_BOOL8 streamFlags;
-} S_EAS_STREAM;
-
-/* default master volume is -10dB */
-#define DEFAULT_VOLUME 90
-#define DEFAULT_STREAM_VOLUME 100
-#define DEFAULT_STREAM_GAIN 14622
-
-/* 10 dB of boost available for individual parsers */
-#define STREAM_VOLUME_HEADROOM 10
-
-/* amalgamated persistent data type */
-typedef struct s_eas_data_tag
-{
-#ifdef _CHECKED_BUILD
- EAS_U32 handleCheck;
-#endif
- EAS_HW_DATA_HANDLE hwInstData;
-
- S_EFFECTS_MODULE effectsModules[NUM_EFFECTS_MODULES];
-
-#ifdef _METRICS_ENABLED
- S_METRICS_INTERFACE *pMetricsModule;
- EAS_VOID_PTR pMetricsData;
-#endif
-
- EAS_I32 *pMixBuffer;
- EAS_PCM *pOutputAudioBuffer;
-
-#ifdef AUX_MIXER
- S_EAS_AUX_MIXER auxMixer;
-#endif
-
-#ifdef _MAXIMIZER_ENABLED
- EAS_VOID_PTR pMaximizerData;
-#endif
-
- S_EAS_STREAM streams[MAX_NUMBER_STREAMS];
-
- S_PCM_STATE *pPCMStreams;
-
- S_VOICE_MGR *pVoiceMgr;
-
-#ifdef JET_INTERFACE
- JET_DATA_HANDLE jetHandle;
-#endif
-
- EAS_U32 renderTime;
- EAS_I16 masterGain;
- EAS_U8 masterVolume;
- EAS_BOOL8 staticMemoryModel;
- EAS_BOOL8 searchHeaderFlag;
-} S_EAS_DATA;
-
-#endif
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 842 $
+ * $Date: 2007-08-23 14:32:31 -0700 (Thu, 23 Aug 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+#ifndef _EAS_DATA_H
+#define _EAS_DATA_H
+
+#define JET_INTERFACE
+
+#include "eas_types.h"
+#include "eas_synthcfg.h"
+#include "eas.h"
+#include "eas_audioconst.h"
+#include "eas_sndlib.h"
+#include "eas_pcm.h"
+#include "eas_pcmdata.h"
+#include "eas_synth.h"
+#include "eas_miditypes.h"
+#include "eas_effects.h"
+
+#ifdef AUX_MIXER
+#include "eas_auxmixdata.h"
+#endif
+
+#ifdef JET_INTERFACE
+#include "jet.h"
+#endif
+
+#ifdef _METRICS_ENABLED
+#include "eas_perf.h"
+#endif
+
+#ifndef MAX_NUMBER_STREAMS
+#define MAX_NUMBER_STREAMS 4
+#endif
+
+/* flags for S_EAS_STREAM */
+#define STREAM_FLAGS_PARSED 1
+#define STREAM_FLAGS_PAUSE 2
+#define STREAM_FLAGS_LOCATE 4
+#define STREAM_FLAGS_RESUME 8
+
+/* structure for parsing a stream */
+typedef struct s_eas_stream_tag
+{
+ void *pParserModule;
+ EAS_U32 time;
+ EAS_U32 frameLength;
+ EAS_I32 repeatCount;
+ EAS_VOID_PTR handle;
+ EAS_U8 volume;
+ EAS_BOOL8 streamFlags;
+} S_EAS_STREAM;
+
+/* default master volume is -10dB */
+#define DEFAULT_VOLUME 90
+#define DEFAULT_STREAM_VOLUME 100
+#define DEFAULT_STREAM_GAIN 14622
+
+/* 10 dB of boost available for individual parsers */
+#define STREAM_VOLUME_HEADROOM 10
+
+/* amalgamated persistent data type */
+typedef struct s_eas_data_tag
+{
+#ifdef _CHECKED_BUILD
+ EAS_U32 handleCheck;
+#endif
+ EAS_HW_DATA_HANDLE hwInstData;
+
+ S_EFFECTS_MODULE effectsModules[NUM_EFFECTS_MODULES];
+
+#ifdef _METRICS_ENABLED
+ S_METRICS_INTERFACE *pMetricsModule;
+ EAS_VOID_PTR pMetricsData;
+#endif
+
+ EAS_I32 *pMixBuffer;
+ EAS_PCM *pOutputAudioBuffer;
+
+#ifdef AUX_MIXER
+ S_EAS_AUX_MIXER auxMixer;
+#endif
+
+#ifdef _MAXIMIZER_ENABLED
+ EAS_VOID_PTR pMaximizerData;
+#endif
+
+ S_EAS_STREAM streams[MAX_NUMBER_STREAMS];
+
+ S_PCM_STATE *pPCMStreams;
+
+ S_VOICE_MGR *pVoiceMgr;
+
+#ifdef JET_INTERFACE
+ JET_DATA_HANDLE jetHandle;
+#endif
+
+ EAS_U32 renderTime;
+ EAS_I16 masterGain;
+ EAS_U8 masterVolume;
+ EAS_BOOL8 staticMemoryModel;
+ EAS_BOOL8 searchHeaderFlag;
+} S_EAS_DATA;
+
+#endif
+
diff --git a/arm-wt-22k/lib_src/eas_dlssynth.c b/arm-wt-22k/lib_src/eas_dlssynth.c
index c1fa1ef..8606a29 100644
--- a/arm-wt-22k/lib_src/eas_dlssynth.c
+++ b/arm-wt-22k/lib_src/eas_dlssynth.c
@@ -52,19 +52,19 @@ static void DLS_UpdateEnvelope (S_SYNTH_VOICE *pVoice, S_SYNTH_CHANNEL *pChannel
*/
void DLS_MuteVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, EAS_I32 voiceNum)
{
- S_WT_VOICE *pWTVoice;
- const S_DLS_ARTICULATION *pDLSArt;
-
- pWTVoice = &pVoiceMgr->wtVoices[voiceNum];
- pDLSArt = &pSynth->pDLS->pDLSArticulations[pWTVoice->artIndex];
-
- /* clear deferred action flags */
- pVoice->voiceFlags &=
- ~(VOICE_FLAG_DEFER_MIDI_NOTE_OFF |
- VOICE_FLAG_SUSTAIN_PEDAL_DEFER_NOTE_OFF |
- VOICE_FLAG_DEFER_MUTE);
-
- /* set the envelope state */
+ S_WT_VOICE *pWTVoice;
+ const S_DLS_ARTICULATION *pDLSArt;
+
+ pWTVoice = &pVoiceMgr->wtVoices[voiceNum];
+ pDLSArt = &pSynth->pDLS->pDLSArticulations[pWTVoice->artIndex];
+
+ /* clear deferred action flags */
+ pVoice->voiceFlags &=
+ ~(VOICE_FLAG_DEFER_MIDI_NOTE_OFF |
+ VOICE_FLAG_SUSTAIN_PEDAL_DEFER_NOTE_OFF |
+ VOICE_FLAG_DEFER_MUTE);
+
+ /* set the envelope state */
pVoiceMgr->wtVoices[voiceNum].eg1State = eEnvelopeStateRelease;
pWTVoice->eg1Increment = pDLSArt->eg1ShutdownTime;
pVoiceMgr->wtVoices[voiceNum].eg2State = eEnvelopeStateRelease;
@@ -80,18 +80,18 @@ void DLS_MuteVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoi
/*lint -esym(715, pVoice) standard API, pVoice may be used by other synthesizers */
void DLS_ReleaseVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, EAS_I32 voiceNum)
{
- S_WT_VOICE *pWTVoice;
- const S_DLS_ARTICULATION *pDLSArt;
-
- pWTVoice = &pVoiceMgr->wtVoices[voiceNum];
- pDLSArt = &pSynth->pDLS->pDLSArticulations[pWTVoice->artIndex];
-
- /* if still in attack phase, convert units to log */
- /*lint -e{732} eg1Value is never negative */
- /*lint -e{703} use shift for performance */
- if (pWTVoice->eg1State == eEnvelopeStateAttack)
- pWTVoice->eg1Value = (EAS_I16) ((EAS_flog2(pWTVoice->eg1Value) << 1) + 2048);
-
+ S_WT_VOICE *pWTVoice;
+ const S_DLS_ARTICULATION *pDLSArt;
+
+ pWTVoice = &pVoiceMgr->wtVoices[voiceNum];
+ pDLSArt = &pSynth->pDLS->pDLSArticulations[pWTVoice->artIndex];
+
+ /* if still in attack phase, convert units to log */
+ /*lint -e{732} eg1Value is never negative */
+ /*lint -e{703} use shift for performance */
+ if (pWTVoice->eg1State == eEnvelopeStateAttack)
+ pWTVoice->eg1Value = (EAS_I16) ((EAS_flog2(pWTVoice->eg1Value) << 1) + 2048);
+
/* release EG1 */
pWTVoice->eg1State = eEnvelopeStateRelease;
pWTVoice->eg1Increment = pDLSArt->eg1.releaseTime;
@@ -111,19 +111,19 @@ void DLS_ReleaseVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *p
/*lint -esym(715, pChannel) pChannel reserved for future use */
void DLS_SustainPedal (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, S_SYNTH_CHANNEL *pChannel, EAS_I32 voiceNum)
{
- S_WT_VOICE *pWTVoice;
- const S_DLS_ARTICULATION *pDLSArt;
-
- pWTVoice = &pVoiceMgr->wtVoices[voiceNum];
- pDLSArt = &pSynth->pDLS->pDLSArticulations[pWTVoice->artIndex];
-
- /* don't catch the voice if below the sustain level */
- if (pWTVoice->eg1Value < pDLSArt->eg1.sustainLevel)
- return;
-
+ S_WT_VOICE *pWTVoice;
+ const S_DLS_ARTICULATION *pDLSArt;
+
+ pWTVoice = &pVoiceMgr->wtVoices[voiceNum];
+ pDLSArt = &pSynth->pDLS->pDLSArticulations[pWTVoice->artIndex];
+
+ /* don't catch the voice if below the sustain level */
+ if (pWTVoice->eg1Value < pDLSArt->eg1.sustainLevel)
+ return;
+
/* defer releasing this note until the damper pedal is off */
pWTVoice->eg1State = eEnvelopeStateDecay;
- pVoice->voiceState = eVoiceStatePlay;
+ pVoice->voiceState = eVoiceStatePlay;
pVoice->voiceFlags |= VOICE_FLAG_SUSTAIN_PEDAL_DEFER_NOTE_OFF;
#ifdef _DEBUG_SYNTH
@@ -139,41 +139,41 @@ void DLS_SustainPedal (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *p
*/
static EAS_I32 DLS_UpdatePhaseInc (S_WT_VOICE *pWTVoice, const S_DLS_ARTICULATION *pDLSArt, S_SYNTH_CHANNEL *pChannel, EAS_I32 pitchCents)
{
- EAS_I32 temp;
+ EAS_I32 temp;
- /* start with base mod LFO modulation */
- temp = pDLSArt->modLFOToPitch;
+ /* start with base mod LFO modulation */
+ temp = pDLSArt->modLFOToPitch;
- /* add mod wheel effect */
- /*lint -e{702} use shift for performance */
- temp += ((pDLSArt->modLFOCC1ToPitch * pChannel->modWheel) >> 7);
+ /* add mod wheel effect */
+ /*lint -e{702} use shift for performance */
+ temp += ((pDLSArt->modLFOCC1ToPitch * pChannel->modWheel) >> 7);
- /* add channel pressure effect */
- /*lint -e{702} use shift for performance */
- temp += ((pDLSArt->modLFOChanPressToPitch * pChannel->channelPressure) >> 7);
+ /* add channel pressure effect */
+ /*lint -e{702} use shift for performance */
+ temp += ((pDLSArt->modLFOChanPressToPitch * pChannel->channelPressure) >> 7);
- /* add total mod LFO effect */
- pitchCents += FMUL_15x15(temp, pWTVoice->modLFO.lfoValue);
+ /* add total mod LFO effect */
+ pitchCents += FMUL_15x15(temp, pWTVoice->modLFO.lfoValue);
- /* start with base vib LFO modulation */
- temp = pDLSArt->vibLFOToPitch;
+ /* start with base vib LFO modulation */
+ temp = pDLSArt->vibLFOToPitch;
- /* add mod wheel effect */
- /*lint -e{702} use shift for performance */
- temp += ((pDLSArt->vibLFOCC1ToPitch * pChannel->modWheel) >> 7);
+ /* add mod wheel effect */
+ /*lint -e{702} use shift for performance */
+ temp += ((pDLSArt->vibLFOCC1ToPitch * pChannel->modWheel) >> 7);
- /* add channel pressure effect */
- /*lint -e{702} use shift for performance */
- temp += ((pDLSArt->vibLFOChanPressToPitch * pChannel->channelPressure) >> 7);
+ /* add channel pressure effect */
+ /*lint -e{702} use shift for performance */
+ temp += ((pDLSArt->vibLFOChanPressToPitch * pChannel->channelPressure) >> 7);
- /* add total vibrato LFO effect */
- pitchCents += FMUL_15x15(temp, pWTVoice->vibLFO.lfoValue);
+ /* add total vibrato LFO effect */
+ pitchCents += FMUL_15x15(temp, pWTVoice->vibLFO.lfoValue);
- /* add EG2 effect */
- pitchCents += FMUL_15x15(pDLSArt->eg2ToPitch, pWTVoice->eg2Value);
+ /* add EG2 effect */
+ pitchCents += FMUL_15x15(pDLSArt->eg2ToPitch, pWTVoice->eg2Value);
- /* convert from cents to linear phase increment */
- return EAS_Calculate2toX(pitchCents);
+ /* convert from cents to linear phase increment */
+ return EAS_Calculate2toX(pitchCents);
}
/*----------------------------------------------------------------------------
@@ -184,58 +184,58 @@ static EAS_I32 DLS_UpdatePhaseInc (S_WT_VOICE *pWTVoice, const S_DLS_ARTICULATIO
*/
static EAS_I32 DLS_UpdateGain (S_WT_VOICE *pWTVoice, const S_DLS_ARTICULATION *pDLSArt, S_SYNTH_CHANNEL *pChannel, EAS_I32 gain, EAS_U8 velocity)
{
- EAS_I32 temp;
+ EAS_I32 temp;
- /* start with base mod LFO modulation */
- temp = pDLSArt->modLFOToGain;
+ /* start with base mod LFO modulation */
+ temp = pDLSArt->modLFOToGain;
- /* add mod wheel effect */
- /*lint -e{702} use shift for performance */
- temp += ((pDLSArt->modLFOCC1ToGain * pChannel->modWheel) >> 7);
+ /* add mod wheel effect */
+ /*lint -e{702} use shift for performance */
+ temp += ((pDLSArt->modLFOCC1ToGain * pChannel->modWheel) >> 7);
- /* add channel pressure effect */
- /*lint -e{702} use shift for performance */
- temp += ((pDLSArt->modLFOChanPressToGain * pChannel->channelPressure) >> 7);
+ /* add channel pressure effect */
+ /*lint -e{702} use shift for performance */
+ temp += ((pDLSArt->modLFOChanPressToGain * pChannel->channelPressure) >> 7);
- /* add total mod LFO effect */
- gain += FMUL_15x15(temp, pWTVoice->modLFO.lfoValue);
- if (gain > 0)
- gain = 0;
+ /* add total mod LFO effect */
+ gain += FMUL_15x15(temp, pWTVoice->modLFO.lfoValue);
+ if (gain > 0)
+ gain = 0;
- /* convert to linear gain including EG1 */
- if (pWTVoice->eg1State != eEnvelopeStateAttack)
- {
- gain = (DLS_GAIN_FACTOR * gain) >> DLS_GAIN_SHIFT;
- /*lint -e{702} use shift for performance */
+ /* convert to linear gain including EG1 */
+ if (pWTVoice->eg1State != eEnvelopeStateAttack)
+ {
+ gain = (DLS_GAIN_FACTOR * gain) >> DLS_GAIN_SHIFT;
+ /*lint -e{702} use shift for performance */
#if 1
- gain += (pWTVoice->eg1Value - 32767) >> 1;
- gain = EAS_LogToLinear16(gain);
+ gain += (pWTVoice->eg1Value - 32767) >> 1;
+ gain = EAS_LogToLinear16(gain);
#else
- gain = EAS_LogToLinear16(gain);
- temp = EAS_LogToLinear16((pWTVoice->eg1Value - 32767) >> 1);
- gain = FMUL_15x15(gain, temp);
+ gain = EAS_LogToLinear16(gain);
+ temp = EAS_LogToLinear16((pWTVoice->eg1Value - 32767) >> 1);
+ gain = FMUL_15x15(gain, temp);
#endif
- }
- else
- {
- gain = (DLS_GAIN_FACTOR * gain) >> DLS_GAIN_SHIFT;
- gain = EAS_LogToLinear16(gain);
- gain = FMUL_15x15(gain, pWTVoice->eg1Value);
- }
-
- /* include MIDI channel gain */
- gain = FMUL_15x15(gain, pChannel->staticGain);
-
- /* include velocity */
- if (pDLSArt->filterQandFlags & FLAG_DLS_VELOCITY_SENSITIVE)
- {
- temp = velocity << 8;
- temp = FMUL_15x15(temp, temp);
- gain = FMUL_15x15(gain, temp);
- }
-
- /* return gain */
- return gain;
+ }
+ else
+ {
+ gain = (DLS_GAIN_FACTOR * gain) >> DLS_GAIN_SHIFT;
+ gain = EAS_LogToLinear16(gain);
+ gain = FMUL_15x15(gain, pWTVoice->eg1Value);
+ }
+
+ /* include MIDI channel gain */
+ gain = FMUL_15x15(gain, pChannel->staticGain);
+
+ /* include velocity */
+ if (pDLSArt->filterQandFlags & FLAG_DLS_VELOCITY_SENSITIVE)
+ {
+ temp = velocity << 8;
+ temp = FMUL_15x15(temp, temp);
+ gain = FMUL_15x15(gain, temp);
+ }
+
+ /* return gain */
+ return gain;
}
/*----------------------------------------------------------------------------
@@ -246,54 +246,54 @@ static EAS_I32 DLS_UpdateGain (S_WT_VOICE *pWTVoice, const S_DLS_ARTICULATION *p
*/
static void DLS_UpdateFilter (S_SYNTH_VOICE *pVoice, S_WT_VOICE *pWTVoice, S_WT_INT_FRAME *pIntFrame, S_SYNTH_CHANNEL *pChannel, const S_DLS_ARTICULATION *pDLSArt)
{
- EAS_I32 cutoff;
- EAS_I32 temp;
-
- /* no need to calculate filter coefficients if it is bypassed */
- if (pDLSArt->filterCutoff == DEFAULT_DLS_FILTER_CUTOFF_FREQUENCY)
- {
- pIntFrame->frame.k = 0;
- return;
- }
-
- /* start with base cutoff frequency */
- cutoff = pDLSArt->filterCutoff;
-
- /* get base mod LFO modulation */
- temp = pDLSArt->modLFOToFc;
-
- /* add mod wheel effect */
- /*lint -e{702} use shift for performance */
- temp += ((pDLSArt->modLFOCC1ToFc * pChannel->modWheel) >> 7);
-
- /* add channel pressure effect */
- /*lint -e{702} use shift for performance */
- temp += ((pDLSArt->modLFOChanPressToFc* pChannel->channelPressure) >> 7);
-
- /* add total mod LFO effect */
- cutoff += FMUL_15x15(temp, pWTVoice->modLFO.lfoValue);
-
- /* add EG2 effect */
- cutoff += FMUL_15x15(pWTVoice->eg2Value, pDLSArt->eg2ToFc);
-
- /* add velocity effect */
- /*lint -e{702} use shift for performance */
- cutoff += (pVoice->velocity * pDLSArt->velToFc) >> 7;
-
- /* add velocity effect */
- /*lint -e{702} use shift for performance */
- cutoff += (pVoice->note * pDLSArt->keyNumToFc) >> 7;
-
- /* subtract the A5 offset and the sampling frequency */
- cutoff -= FILTER_CUTOFF_FREQ_ADJUST + A5_PITCH_OFFSET_IN_CENTS;
-
- /* limit the cutoff frequency */
- if (cutoff > FILTER_CUTOFF_MAX_PITCH_CENTS)
- cutoff = FILTER_CUTOFF_MAX_PITCH_CENTS;
- else if (cutoff < FILTER_CUTOFF_MIN_PITCH_CENTS)
- cutoff = FILTER_CUTOFF_MIN_PITCH_CENTS;
-
- WT_SetFilterCoeffs(pIntFrame, cutoff, pDLSArt->filterQandFlags & FILTER_Q_MASK);
+ EAS_I32 cutoff;
+ EAS_I32 temp;
+
+ /* no need to calculate filter coefficients if it is bypassed */
+ if (pDLSArt->filterCutoff == DEFAULT_DLS_FILTER_CUTOFF_FREQUENCY)
+ {
+ pIntFrame->frame.k = 0;
+ return;
+ }
+
+ /* start with base cutoff frequency */
+ cutoff = pDLSArt->filterCutoff;
+
+ /* get base mod LFO modulation */
+ temp = pDLSArt->modLFOToFc;
+
+ /* add mod wheel effect */
+ /*lint -e{702} use shift for performance */
+ temp += ((pDLSArt->modLFOCC1ToFc * pChannel->modWheel) >> 7);
+
+ /* add channel pressure effect */
+ /*lint -e{702} use shift for performance */
+ temp += ((pDLSArt->modLFOChanPressToFc* pChannel->channelPressure) >> 7);
+
+ /* add total mod LFO effect */
+ cutoff += FMUL_15x15(temp, pWTVoice->modLFO.lfoValue);
+
+ /* add EG2 effect */
+ cutoff += FMUL_15x15(pWTVoice->eg2Value, pDLSArt->eg2ToFc);
+
+ /* add velocity effect */
+ /*lint -e{702} use shift for performance */
+ cutoff += (pVoice->velocity * pDLSArt->velToFc) >> 7;
+
+ /* add velocity effect */
+ /*lint -e{702} use shift for performance */
+ cutoff += (pVoice->note * pDLSArt->keyNumToFc) >> 7;
+
+ /* subtract the A5 offset and the sampling frequency */
+ cutoff -= FILTER_CUTOFF_FREQ_ADJUST + A5_PITCH_OFFSET_IN_CENTS;
+
+ /* limit the cutoff frequency */
+ if (cutoff > FILTER_CUTOFF_MAX_PITCH_CENTS)
+ cutoff = FILTER_CUTOFF_MAX_PITCH_CENTS;
+ else if (cutoff < FILTER_CUTOFF_MIN_PITCH_CENTS)
+ cutoff = FILTER_CUTOFF_MIN_PITCH_CENTS;
+
+ WT_SetFilterCoeffs(pIntFrame, cutoff, pDLSArt->filterQandFlags & FILTER_Q_MASK);
}
/*----------------------------------------------------------------------------
@@ -304,69 +304,69 @@ static void DLS_UpdateFilter (S_SYNTH_VOICE *pVoice, S_WT_VOICE *pWTVoice, S_WT_
*/
EAS_RESULT DLS_StartVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, EAS_I32 voiceNum, EAS_U16 regionIndex)
{
- S_WT_VOICE *pWTVoice;
- const S_DLS_REGION *pDLSRegion;
- const S_DLS_ARTICULATION *pDLSArt;
- S_SYNTH_CHANNEL *pChannel;
-
+ S_WT_VOICE *pWTVoice;
+ const S_DLS_REGION *pDLSRegion;
+ const S_DLS_ARTICULATION *pDLSArt;
+ S_SYNTH_CHANNEL *pChannel;
+
#ifdef _DEBUG_SYNTH
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "DLS_StartVoice: Voice %ld; Region %d\n", (EAS_I32) (pVoice - pVoiceMgr->voices), regionIndex); */ }
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "DLS_StartVoice: Voice %ld; Region %d\n", (EAS_I32) (pVoice - pVoiceMgr->voices), regionIndex); */ }
#endif
- pWTVoice = &pVoiceMgr->wtVoices[voiceNum];
- pChannel = &pSynth->channels[pVoice->channel & 15];
- pDLSRegion = &pSynth->pDLS->pDLSRegions[regionIndex & REGION_INDEX_MASK];
- pWTVoice->artIndex = pDLSRegion->wtRegion.artIndex;
- pDLSArt = &pSynth->pDLS->pDLSArticulations[pWTVoice->artIndex];
-
- /* initialize the envelopes */
- pWTVoice->eg1State = eEnvelopeStateInit;
- DLS_UpdateEnvelope(pVoice, pChannel, &pDLSArt->eg1, &pWTVoice->eg1Value, &pWTVoice->eg1Increment, &pWTVoice->eg1State);
- pWTVoice->eg2State = eEnvelopeStateInit;
- DLS_UpdateEnvelope(pVoice, pChannel, &pDLSArt->eg2, &pWTVoice->eg2Value, &pWTVoice->eg2Increment, &pWTVoice->eg2State);
-
- /* initialize the LFOs */
- pWTVoice->modLFO.lfoValue = 0;
- pWTVoice->modLFO.lfoPhase = pDLSArt->modLFO.lfoDelay;
- pWTVoice->vibLFO.lfoValue = 0;
- pWTVoice->vibLFO.lfoPhase = pDLSArt->vibLFO.lfoDelay;
-
- /* initalize the envelopes and calculate initial gain */
- DLS_UpdateEnvelope(pVoice, pChannel, &pDLSArt->eg1, &pWTVoice->eg1Value, &pWTVoice->eg1Increment, &pWTVoice->eg1State);
- DLS_UpdateEnvelope(pVoice, pChannel, &pDLSArt->eg2, &pWTVoice->eg2Value, &pWTVoice->eg2Increment, &pWTVoice->eg2State);
- pVoice->gain = (EAS_I16) DLS_UpdateGain(pWTVoice, pDLSArt, pChannel, pDLSRegion->wtRegion.gain, pVoice->velocity);
+ pWTVoice = &pVoiceMgr->wtVoices[voiceNum];
+ pChannel = &pSynth->channels[pVoice->channel & 15];
+ pDLSRegion = &pSynth->pDLS->pDLSRegions[regionIndex & REGION_INDEX_MASK];
+ pWTVoice->artIndex = pDLSRegion->wtRegion.artIndex;
+ pDLSArt = &pSynth->pDLS->pDLSArticulations[pWTVoice->artIndex];
+
+ /* initialize the envelopes */
+ pWTVoice->eg1State = eEnvelopeStateInit;
+ DLS_UpdateEnvelope(pVoice, pChannel, &pDLSArt->eg1, &pWTVoice->eg1Value, &pWTVoice->eg1Increment, &pWTVoice->eg1State);
+ pWTVoice->eg2State = eEnvelopeStateInit;
+ DLS_UpdateEnvelope(pVoice, pChannel, &pDLSArt->eg2, &pWTVoice->eg2Value, &pWTVoice->eg2Increment, &pWTVoice->eg2State);
+
+ /* initialize the LFOs */
+ pWTVoice->modLFO.lfoValue = 0;
+ pWTVoice->modLFO.lfoPhase = pDLSArt->modLFO.lfoDelay;
+ pWTVoice->vibLFO.lfoValue = 0;
+ pWTVoice->vibLFO.lfoPhase = pDLSArt->vibLFO.lfoDelay;
+
+ /* initalize the envelopes and calculate initial gain */
+ DLS_UpdateEnvelope(pVoice, pChannel, &pDLSArt->eg1, &pWTVoice->eg1Value, &pWTVoice->eg1Increment, &pWTVoice->eg1State);
+ DLS_UpdateEnvelope(pVoice, pChannel, &pDLSArt->eg2, &pWTVoice->eg2Value, &pWTVoice->eg2Increment, &pWTVoice->eg2State);
+ pVoice->gain = (EAS_I16) DLS_UpdateGain(pWTVoice, pDLSArt, pChannel, pDLSRegion->wtRegion.gain, pVoice->velocity);
#if (NUM_OUTPUT_CHANNELS == 2)
- EAS_CalcPanControl((EAS_INT) pChannel->pan - 64 + (EAS_INT) pDLSArt->pan, &pWTVoice->gainLeft, &pWTVoice->gainRight);
-#endif
-
- /* initialize the filter states */
- pWTVoice->filter.z1 = 0;
- pWTVoice->filter.z2 = 0;
-
- /* initialize the oscillator */
- pWTVoice->phaseAccum = (EAS_U32) pSynth->pDLS->pDLSSamples + pSynth->pDLS->pDLSSampleOffsets[pDLSRegion->wtRegion.waveIndex];
- if (pDLSRegion->wtRegion.region.keyGroupAndFlags & REGION_FLAG_IS_LOOPED)
- {
- pWTVoice->loopStart = pWTVoice->phaseAccum + pDLSRegion->wtRegion.loopStart;
- pWTVoice->loopEnd = pWTVoice->phaseAccum + pDLSRegion->wtRegion.loopEnd - 1;
- }
- else
- pWTVoice->loopStart = pWTVoice->loopEnd = pWTVoice->phaseAccum + pSynth->pDLS->pDLSSampleLen[pDLSRegion->wtRegion.waveIndex] - 1;
-
- return EAS_SUCCESS;
+ EAS_CalcPanControl((EAS_INT) pChannel->pan - 64 + (EAS_INT) pDLSArt->pan, &pWTVoice->gainLeft, &pWTVoice->gainRight);
+#endif
+
+ /* initialize the filter states */
+ pWTVoice->filter.z1 = 0;
+ pWTVoice->filter.z2 = 0;
+
+ /* initialize the oscillator */
+ pWTVoice->phaseAccum = (EAS_U32) pSynth->pDLS->pDLSSamples + pSynth->pDLS->pDLSSampleOffsets[pDLSRegion->wtRegion.waveIndex];
+ if (pDLSRegion->wtRegion.region.keyGroupAndFlags & REGION_FLAG_IS_LOOPED)
+ {
+ pWTVoice->loopStart = pWTVoice->phaseAccum + pDLSRegion->wtRegion.loopStart;
+ pWTVoice->loopEnd = pWTVoice->phaseAccum + pDLSRegion->wtRegion.loopEnd - 1;
+ }
+ else
+ pWTVoice->loopStart = pWTVoice->loopEnd = pWTVoice->phaseAccum + pSynth->pDLS->pDLSSampleLen[pDLSRegion->wtRegion.waveIndex] - 1;
+
+ return EAS_SUCCESS;
}
/*----------------------------------------------------------------------------
* DLS_UpdateVoice()
*----------------------------------------------------------------------------
- * Purpose:
+ * Purpose:
* Synthesize a block of samples for the given voice.
* Use linear interpolation.
*
- * Inputs:
+ * Inputs:
* pEASData - pointer to overall EAS data structure
- *
+ *
* Outputs:
* number of samples actually written to buffer
*
@@ -377,84 +377,84 @@ EAS_RESULT DLS_StartVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOIC
*/
EAS_BOOL DLS_UpdateVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, EAS_I32 voiceNum, EAS_I32 *pMixBuffer, EAS_I32 numSamples)
{
- S_WT_VOICE *pWTVoice;
- S_SYNTH_CHANNEL *pChannel;
- const S_DLS_REGION *pDLSRegion;
- const S_DLS_ARTICULATION *pDLSArt;
- S_WT_INT_FRAME intFrame;
- EAS_I32 temp;
- EAS_BOOL done = EAS_FALSE;
-
- /* establish pointers to critical data */
- pWTVoice = &pVoiceMgr->wtVoices[voiceNum];
- pDLSRegion = &pSynth->pDLS->pDLSRegions[pVoice->regionIndex & REGION_INDEX_MASK];
- pChannel = &pSynth->channels[pVoice->channel & 15];
- pDLSArt = &pSynth->pDLS->pDLSArticulations[pWTVoice->artIndex];
-
- /* update the envelopes */
- DLS_UpdateEnvelope(pVoice, pChannel, &pDLSArt->eg1, &pWTVoice->eg1Value, &pWTVoice->eg1Increment, &pWTVoice->eg1State);
- DLS_UpdateEnvelope(pVoice, pChannel, &pDLSArt->eg2, &pWTVoice->eg2Value, &pWTVoice->eg2Increment, &pWTVoice->eg2State);
-
- /* update the LFOs using the EAS synth function */
- WT_UpdateLFO(&pWTVoice->modLFO, pDLSArt->modLFO.lfoFreq);
- WT_UpdateLFO(&pWTVoice->vibLFO, pDLSArt->vibLFO.lfoFreq);
-
- /* calculate base frequency */
- temp = pDLSArt->tuning + pChannel->staticPitch + pDLSRegion->wtRegion.tuning +
- (((EAS_I32) pVoice->note * (EAS_I32) pDLSArt->keyNumToPitch) >> 7);
-
- /* don't transpose rhythm channel */
- if ((pChannel ->channelFlags & CHANNEL_FLAG_RHYTHM_CHANNEL) == 0)
- temp += pSynth->globalTranspose * 100;
-
- /* calculate phase increment including modulation effects */
- intFrame.frame.phaseIncrement = DLS_UpdatePhaseInc(pWTVoice, pDLSArt, pChannel, temp);
-
- /* calculate gain including modulation effects */
- intFrame.frame.gainTarget = DLS_UpdateGain(pWTVoice, pDLSArt, pChannel, pDLSRegion->wtRegion.gain, pVoice->velocity);
- intFrame.prevGain = pVoice->gain;
-
- DLS_UpdateFilter(pVoice, pWTVoice, &intFrame, pChannel, pDLSArt);
-
- /* call into engine to generate samples */
- intFrame.pAudioBuffer = pVoiceMgr->voiceBuffer;
- intFrame.pMixBuffer = pMixBuffer;
- intFrame.numSamples = numSamples;
- if (numSamples < 0)
- return EAS_FALSE;
-
- /* check for end of sample */
- if ((pWTVoice->loopStart != WT_NOISE_GENERATOR) && (pWTVoice->loopStart == pWTVoice->loopEnd))
- done = WT_CheckSampleEnd(pWTVoice, &intFrame, EAS_FALSE);
-
- WT_ProcessVoice(pWTVoice, &intFrame);
-
- /* clear flag */
- pVoice->voiceFlags &= ~VOICE_FLAG_NO_SAMPLES_SYNTHESIZED_YET;
-
- /* if the update interval has elapsed, then force the current gain to the next
- * gain since we never actually reach the next gain when ramping -- we just get
- * very close to the target gain.
- */
- pVoice->gain = (EAS_I16) intFrame.frame.gainTarget;
+ S_WT_VOICE *pWTVoice;
+ S_SYNTH_CHANNEL *pChannel;
+ const S_DLS_REGION *pDLSRegion;
+ const S_DLS_ARTICULATION *pDLSArt;
+ S_WT_INT_FRAME intFrame;
+ EAS_I32 temp;
+ EAS_BOOL done = EAS_FALSE;
+
+ /* establish pointers to critical data */
+ pWTVoice = &pVoiceMgr->wtVoices[voiceNum];
+ pDLSRegion = &pSynth->pDLS->pDLSRegions[pVoice->regionIndex & REGION_INDEX_MASK];
+ pChannel = &pSynth->channels[pVoice->channel & 15];
+ pDLSArt = &pSynth->pDLS->pDLSArticulations[pWTVoice->artIndex];
+
+ /* update the envelopes */
+ DLS_UpdateEnvelope(pVoice, pChannel, &pDLSArt->eg1, &pWTVoice->eg1Value, &pWTVoice->eg1Increment, &pWTVoice->eg1State);
+ DLS_UpdateEnvelope(pVoice, pChannel, &pDLSArt->eg2, &pWTVoice->eg2Value, &pWTVoice->eg2Increment, &pWTVoice->eg2State);
+
+ /* update the LFOs using the EAS synth function */
+ WT_UpdateLFO(&pWTVoice->modLFO, pDLSArt->modLFO.lfoFreq);
+ WT_UpdateLFO(&pWTVoice->vibLFO, pDLSArt->vibLFO.lfoFreq);
+
+ /* calculate base frequency */
+ temp = pDLSArt->tuning + pChannel->staticPitch + pDLSRegion->wtRegion.tuning +
+ (((EAS_I32) pVoice->note * (EAS_I32) pDLSArt->keyNumToPitch) >> 7);
+
+ /* don't transpose rhythm channel */
+ if ((pChannel ->channelFlags & CHANNEL_FLAG_RHYTHM_CHANNEL) == 0)
+ temp += pSynth->globalTranspose * 100;
+
+ /* calculate phase increment including modulation effects */
+ intFrame.frame.phaseIncrement = DLS_UpdatePhaseInc(pWTVoice, pDLSArt, pChannel, temp);
+
+ /* calculate gain including modulation effects */
+ intFrame.frame.gainTarget = DLS_UpdateGain(pWTVoice, pDLSArt, pChannel, pDLSRegion->wtRegion.gain, pVoice->velocity);
+ intFrame.prevGain = pVoice->gain;
+
+ DLS_UpdateFilter(pVoice, pWTVoice, &intFrame, pChannel, pDLSArt);
+
+ /* call into engine to generate samples */
+ intFrame.pAudioBuffer = pVoiceMgr->voiceBuffer;
+ intFrame.pMixBuffer = pMixBuffer;
+ intFrame.numSamples = numSamples;
+ if (numSamples < 0)
+ return EAS_FALSE;
+
+ /* check for end of sample */
+ if ((pWTVoice->loopStart != WT_NOISE_GENERATOR) && (pWTVoice->loopStart == pWTVoice->loopEnd))
+ done = WT_CheckSampleEnd(pWTVoice, &intFrame, EAS_FALSE);
+
+ WT_ProcessVoice(pWTVoice, &intFrame);
+
+ /* clear flag */
+ pVoice->voiceFlags &= ~VOICE_FLAG_NO_SAMPLES_SYNTHESIZED_YET;
+
+ /* if the update interval has elapsed, then force the current gain to the next
+ * gain since we never actually reach the next gain when ramping -- we just get
+ * very close to the target gain.
+ */
+ pVoice->gain = (EAS_I16) intFrame.frame.gainTarget;
/* if voice has finished, set flag for voice manager */
- if ((pVoice->voiceState != eVoiceStateStolen) && (pWTVoice->eg1State == eEnvelopeStateMuted))
- done = EAS_TRUE;
+ if ((pVoice->voiceState != eVoiceStateStolen) && (pWTVoice->eg1State == eEnvelopeStateMuted))
+ done = EAS_TRUE;
- return done;
-}
+ return done;
+}
/*----------------------------------------------------------------------------
* DLS_UpdateEnvelope()
*----------------------------------------------------------------------------
- * Purpose:
+ * Purpose:
* Synthesize a block of samples for the given voice.
* Use linear interpolation.
*
- * Inputs:
+ * Inputs:
* pEASData - pointer to overall EAS data structure
- *
+ *
* Outputs:
* number of samples actually written to buffer
*
@@ -466,113 +466,113 @@ EAS_BOOL DLS_UpdateVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE
/*lint -esym(715, pChannel) pChannel not used in this instance */
static void DLS_UpdateEnvelope (S_SYNTH_VOICE *pVoice, S_SYNTH_CHANNEL *pChannel, const S_DLS_ENVELOPE *pEnvParams, EAS_I16 *pValue, EAS_I16 *pIncrement, EAS_U8 *pState)
{
- EAS_I32 temp;
-
- switch (*pState)
- {
- /* initial state */
- case eEnvelopeStateInit:
- *pState = eEnvelopeStateDelay;
- *pValue = 0;
- *pIncrement = pEnvParams->delayTime;
- if (*pIncrement != 0)
- return;
- /*lint -e{825} falls through to next case */
-
- case eEnvelopeStateDelay:
- if (*pIncrement)
- {
- *pIncrement = *pIncrement - 1;
- return;
- }
-
- /* calculate attack rate */
- *pState = eEnvelopeStateAttack;
- if (pEnvParams->attackTime != ZERO_TIME_IN_CENTS)
- {
- /*lint -e{702} use shift for performance */
- temp = pEnvParams->attackTime + ((pEnvParams->velToAttack * pVoice->velocity) >> 7);
- *pIncrement = ConvertRate(temp);
- return;
- }
-
- *pValue = SYNTH_FULL_SCALE_EG1_GAIN;
- /*lint -e{825} falls through to next case */
-
- case eEnvelopeStateAttack:
- if (*pValue < SYNTH_FULL_SCALE_EG1_GAIN)
- {
- temp = *pValue + *pIncrement;
- *pValue = (EAS_I16) (temp < SYNTH_FULL_SCALE_EG1_GAIN ? temp : SYNTH_FULL_SCALE_EG1_GAIN);
- return;
- }
-
- /* calculate hold time */
- *pState = eEnvelopeStateHold;
- if (pEnvParams->holdTime != ZERO_TIME_IN_CENTS)
- {
- /*lint -e{702} use shift for performance */
- temp = pEnvParams->holdTime + ((pEnvParams->keyNumToHold * pVoice->note) >> 7);
- *pIncrement = ConvertDelay(temp);
- return;
- }
- else
- *pIncrement = 0;
- /*lint -e{825} falls through to next case */
-
- case eEnvelopeStateHold:
- if (*pIncrement)
- {
- *pIncrement = *pIncrement - 1;
- return;
- }
-
- /* calculate decay rate */
- *pState = eEnvelopeStateDecay;
- if (pEnvParams->decayTime != ZERO_TIME_IN_CENTS)
- {
- /*lint -e{702} use shift for performance */
- temp = pEnvParams->decayTime + ((pEnvParams->keyNumToDecay * pVoice->note) >> 7);
- *pIncrement = ConvertRate(temp);
- return;
- }
-
-// *pValue = pEnvParams->sustainLevel;
- /*lint -e{825} falls through to next case */
-
- case eEnvelopeStateDecay:
- if (*pValue > pEnvParams->sustainLevel)
- {
- temp = *pValue - *pIncrement;
- *pValue = (EAS_I16) (temp > pEnvParams->sustainLevel ? temp : pEnvParams->sustainLevel);
- return;
- }
-
- *pState = eEnvelopeStateSustain;
- *pValue = pEnvParams->sustainLevel;
- /*lint -e{825} falls through to next case */
-
- case eEnvelopeStateSustain:
- return;
-
- case eEnvelopeStateRelease:
- temp = *pValue - *pIncrement;
- if (temp <= 0)
- {
- *pState = eEnvelopeStateMuted;
- *pValue = 0;
- }
- else
- *pValue = (EAS_I16) temp;
- break;
-
- case eEnvelopeStateMuted:
- *pValue = 0;
- return;
-
- default:
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Envelope in invalid state %d\n", *pState); */ }
- break;
- }
+ EAS_I32 temp;
+
+ switch (*pState)
+ {
+ /* initial state */
+ case eEnvelopeStateInit:
+ *pState = eEnvelopeStateDelay;
+ *pValue = 0;
+ *pIncrement = pEnvParams->delayTime;
+ if (*pIncrement != 0)
+ return;
+ /*lint -e{825} falls through to next case */
+
+ case eEnvelopeStateDelay:
+ if (*pIncrement)
+ {
+ *pIncrement = *pIncrement - 1;
+ return;
+ }
+
+ /* calculate attack rate */
+ *pState = eEnvelopeStateAttack;
+ if (pEnvParams->attackTime != ZERO_TIME_IN_CENTS)
+ {
+ /*lint -e{702} use shift for performance */
+ temp = pEnvParams->attackTime + ((pEnvParams->velToAttack * pVoice->velocity) >> 7);
+ *pIncrement = ConvertRate(temp);
+ return;
+ }
+
+ *pValue = SYNTH_FULL_SCALE_EG1_GAIN;
+ /*lint -e{825} falls through to next case */
+
+ case eEnvelopeStateAttack:
+ if (*pValue < SYNTH_FULL_SCALE_EG1_GAIN)
+ {
+ temp = *pValue + *pIncrement;
+ *pValue = (EAS_I16) (temp < SYNTH_FULL_SCALE_EG1_GAIN ? temp : SYNTH_FULL_SCALE_EG1_GAIN);
+ return;
+ }
+
+ /* calculate hold time */
+ *pState = eEnvelopeStateHold;
+ if (pEnvParams->holdTime != ZERO_TIME_IN_CENTS)
+ {
+ /*lint -e{702} use shift for performance */
+ temp = pEnvParams->holdTime + ((pEnvParams->keyNumToHold * pVoice->note) >> 7);
+ *pIncrement = ConvertDelay(temp);
+ return;
+ }
+ else
+ *pIncrement = 0;
+ /*lint -e{825} falls through to next case */
+
+ case eEnvelopeStateHold:
+ if (*pIncrement)
+ {
+ *pIncrement = *pIncrement - 1;
+ return;
+ }
+
+ /* calculate decay rate */
+ *pState = eEnvelopeStateDecay;
+ if (pEnvParams->decayTime != ZERO_TIME_IN_CENTS)
+ {
+ /*lint -e{702} use shift for performance */
+ temp = pEnvParams->decayTime + ((pEnvParams->keyNumToDecay * pVoice->note) >> 7);
+ *pIncrement = ConvertRate(temp);
+ return;
+ }
+
+// *pValue = pEnvParams->sustainLevel;
+ /*lint -e{825} falls through to next case */
+
+ case eEnvelopeStateDecay:
+ if (*pValue > pEnvParams->sustainLevel)
+ {
+ temp = *pValue - *pIncrement;
+ *pValue = (EAS_I16) (temp > pEnvParams->sustainLevel ? temp : pEnvParams->sustainLevel);
+ return;
+ }
+
+ *pState = eEnvelopeStateSustain;
+ *pValue = pEnvParams->sustainLevel;
+ /*lint -e{825} falls through to next case */
+
+ case eEnvelopeStateSustain:
+ return;
+
+ case eEnvelopeStateRelease:
+ temp = *pValue - *pIncrement;
+ if (temp <= 0)
+ {
+ *pState = eEnvelopeStateMuted;
+ *pValue = 0;
+ }
+ else
+ *pValue = (EAS_I16) temp;
+ break;
+
+ case eEnvelopeStateMuted:
+ *pValue = 0;
+ return;
+
+ default:
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Envelope in invalid state %d\n", *pState); */ }
+ break;
+ }
}
diff --git a/arm-wt-22k/lib_src/eas_dlssynth.h b/arm-wt-22k/lib_src/eas_dlssynth.h
index 0dab41e..17a635a 100644
--- a/arm-wt-22k/lib_src/eas_dlssynth.h
+++ b/arm-wt-22k/lib_src/eas_dlssynth.h
@@ -1,12 +1,12 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_dlssynth.h
- *
- * Contents and purpose:
- * Implements the Mobile DLS synthesizer.
- *
- * Copyright Sonic Network Inc. 2006
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_dlssynth.h
+ *
+ * Contents and purpose:
+ * Implements the Mobile DLS synthesizer.
+ *
+ * Copyright Sonic Network Inc. 2006
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,23 +19,23 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 143 $
- * $Date: 2006-07-17 14:09:35 -0700 (Mon, 17 Jul 2006) $
- *----------------------------------------------------------------------------
-*/
-
-#ifndef _EAS_DLSSYNTH_H
-#define _EAS_DLSSYNTH_H
-
-/* prototypes */
-void DLS_MuteVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, EAS_I32 voiceNum);
-void DLS_ReleaseVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, EAS_I32 voiceNum);
-void DLS_SustainPedal (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, S_SYNTH_CHANNEL *pChannel, EAS_I32 voiceNum);
-EAS_RESULT DLS_StartVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, EAS_I32 voiceNum, EAS_U16 regionIndex);
-EAS_BOOL DLS_UpdateVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, EAS_I32 voiceNum, EAS_I32 *pMixBuffer, EAS_I32 numSamples);
-
-#endif
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 143 $
+ * $Date: 2006-07-17 14:09:35 -0700 (Mon, 17 Jul 2006) $
+ *----------------------------------------------------------------------------
+*/
+
+#ifndef _EAS_DLSSYNTH_H
+#define _EAS_DLSSYNTH_H
+
+/* prototypes */
+void DLS_MuteVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, EAS_I32 voiceNum);
+void DLS_ReleaseVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, EAS_I32 voiceNum);
+void DLS_SustainPedal (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, S_SYNTH_CHANNEL *pChannel, EAS_I32 voiceNum);
+EAS_RESULT DLS_StartVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, EAS_I32 voiceNum, EAS_U16 regionIndex);
+EAS_BOOL DLS_UpdateVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, EAS_I32 voiceNum, EAS_I32 *pMixBuffer, EAS_I32 numSamples);
+
+#endif
+
diff --git a/arm-wt-22k/lib_src/eas_effects.h b/arm-wt-22k/lib_src/eas_effects.h
index 01e64c0..86dedac 100644
--- a/arm-wt-22k/lib_src/eas_effects.h
+++ b/arm-wt-22k/lib_src/eas_effects.h
@@ -1,12 +1,12 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_effects.h
- *
- * Contents and purpose:
- * Defines a generic effects interface.
- *
- * Copyright Sonic Network Inc. 2005
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_effects.h
+ *
+ * Contents and purpose:
+ * Defines a generic effects interface.
+ *
+ * Copyright Sonic Network Inc. 2005
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,43 +19,43 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 82 $
- * $Date: 2006-07-10 11:45:19 -0700 (Mon, 10 Jul 2006) $
- *----------------------------------------------------------------------------
-*/
-
-#ifndef _EAS_EFFECTS_H
-#define _EAS_EFFECTS_H
-
-#include "eas_types.h"
-
-typedef struct
-{
- EAS_RESULT (*pfInit)(EAS_DATA_HANDLE pEASData, EAS_VOID_PTR *pInstData);
- void (*pfProcess)(EAS_VOID_PTR pInstData, EAS_PCM *in, EAS_PCM *out, EAS_I32 numSamples);
- EAS_RESULT (*pfShutdown)(EAS_DATA_HANDLE pEASData, EAS_VOID_PTR pInstData);
- EAS_RESULT (*pFGetParam)(EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue);
- EAS_RESULT (*pFSetParam)(EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value);
-} S_EFFECTS_INTERFACE;
-
-typedef struct
-{
- EAS_RESULT (*pfInit)(EAS_DATA_HANDLE pEASData, EAS_VOID_PTR *pInstData);
- void (*pfProcess)(EAS_VOID_PTR pInstData, EAS_I32 *in, EAS_I32 *out, EAS_I32 numSamples);
- EAS_RESULT (*pfShutdown)(EAS_DATA_HANDLE pEASData, EAS_VOID_PTR pInstData);
- EAS_RESULT (*pFGetParam)(EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue);
- EAS_RESULT (*pFSetParam)(EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value);
-} S_EFFECTS32_INTERFACE;
-
-/* mixer instance data */
-typedef struct
-{
- S_EFFECTS_INTERFACE *effect;
- EAS_VOID_PTR effectData;
-} S_EFFECTS_MODULE;
-
-#endif /* end _EAS_EFFECTS_H */
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 82 $
+ * $Date: 2006-07-10 11:45:19 -0700 (Mon, 10 Jul 2006) $
+ *----------------------------------------------------------------------------
+*/
+
+#ifndef _EAS_EFFECTS_H
+#define _EAS_EFFECTS_H
+
+#include "eas_types.h"
+
+typedef struct
+{
+ EAS_RESULT (*pfInit)(EAS_DATA_HANDLE pEASData, EAS_VOID_PTR *pInstData);
+ void (*pfProcess)(EAS_VOID_PTR pInstData, EAS_PCM *in, EAS_PCM *out, EAS_I32 numSamples);
+ EAS_RESULT (*pfShutdown)(EAS_DATA_HANDLE pEASData, EAS_VOID_PTR pInstData);
+ EAS_RESULT (*pFGetParam)(EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue);
+ EAS_RESULT (*pFSetParam)(EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value);
+} S_EFFECTS_INTERFACE;
+
+typedef struct
+{
+ EAS_RESULT (*pfInit)(EAS_DATA_HANDLE pEASData, EAS_VOID_PTR *pInstData);
+ void (*pfProcess)(EAS_VOID_PTR pInstData, EAS_I32 *in, EAS_I32 *out, EAS_I32 numSamples);
+ EAS_RESULT (*pfShutdown)(EAS_DATA_HANDLE pEASData, EAS_VOID_PTR pInstData);
+ EAS_RESULT (*pFGetParam)(EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue);
+ EAS_RESULT (*pFSetParam)(EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value);
+} S_EFFECTS32_INTERFACE;
+
+/* mixer instance data */
+typedef struct
+{
+ S_EFFECTS_INTERFACE *effect;
+ EAS_VOID_PTR effectData;
+} S_EFFECTS_MODULE;
+
+#endif /* end _EAS_EFFECTS_H */
+
diff --git a/arm-wt-22k/lib_src/eas_flog.c b/arm-wt-22k/lib_src/eas_flog.c
index 647da2f..16539f5 100644
--- a/arm-wt-22k/lib_src/eas_flog.c
+++ b/arm-wt-22k/lib_src/eas_flog.c
@@ -1,13 +1,13 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_flog2.c
- *
- * Contents and purpose:
- * Fixed point square root
- *
- *
- * Copyright (c) 2006 Sonic Network Inc.
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_flog2.c
+ *
+ * Contents and purpose:
+ * Fixed point square root
+ *
+ *
+ * Copyright (c) 2006 Sonic Network Inc.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,77 +20,77 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision$
- * $Date$
- *----------------------------------------------------------------------------
-*/
-
-#include "eas_types.h"
-#include "eas_math.h"
-
-#define MANTISSA_SHIFT 27
-#define MANTISSA_MASK 0x0000000f
-#define MANTISSA_LSB_SHIFT 7
-#define MANTISSA_LSB_MASK 0x000fffff
-#define LOG_EXPONENT_SHIFT 10
-#define INTERPOLATION_SHIFT 20
-#define MAX_NEGATIVE (-2147483647-1)
-
-/* log lookup table */
-static const EAS_U16 eas_log2_table[] =
-{
- 0, 90, 174, 254, 330, 402, 470, 536,
- 599, 659, 717, 773, 827, 879, 929, 977,
- 1024
-};
-
-/*----------------------------------------------------------------------------
- * EAS_flog2()
- *----------------------------------------------------------------------------
- * Purpose:
- * Calculates the log2 of a 32-bit fixed point value
- *
- * Inputs:
- * n = value of interest
- *
- * Outputs:
- * returns the log2 of n
- *
- *----------------------------------------------------------------------------
-*/
-EAS_I32 EAS_flog2 (EAS_U32 n)
-{
- EAS_U32 exp;
- EAS_U32 interp;
-
- /* check for error condition */
- if (n == 0)
- return MAX_NEGATIVE;
-
- /* find exponent */
- for (exp = 31; exp > 0; exp--)
- {
- /* shift until we get a 1 bit in bit 31 */
- if ((n & (EAS_U32) MAX_NEGATIVE) != 0)
- break;
- n <<= 1;
- }
- /*lint -e{701} use shift for performance */
- exp <<= LOG_EXPONENT_SHIFT;
-
- /* get the least significant bits for interpolation */
- interp = (n >> MANTISSA_LSB_SHIFT) & MANTISSA_LSB_MASK;
-
- /* get the most significant bits for mantissa lookup */
- n = (n >> MANTISSA_SHIFT) & MANTISSA_MASK;
-
- /* interpolate mantissa */
- interp = ((eas_log2_table[n+1] - eas_log2_table[n]) * interp) >> INTERPOLATION_SHIFT;
- exp += eas_log2_table[n] + interp;
-
- return (EAS_I32) exp;
-}
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision$
+ * $Date$
+ *----------------------------------------------------------------------------
+*/
+
+#include "eas_types.h"
+#include "eas_math.h"
+
+#define MANTISSA_SHIFT 27
+#define MANTISSA_MASK 0x0000000f
+#define MANTISSA_LSB_SHIFT 7
+#define MANTISSA_LSB_MASK 0x000fffff
+#define LOG_EXPONENT_SHIFT 10
+#define INTERPOLATION_SHIFT 20
+#define MAX_NEGATIVE (-2147483647-1)
+
+/* log lookup table */
+static const EAS_U16 eas_log2_table[] =
+{
+ 0, 90, 174, 254, 330, 402, 470, 536,
+ 599, 659, 717, 773, 827, 879, 929, 977,
+ 1024
+};
+
+/*----------------------------------------------------------------------------
+ * EAS_flog2()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Calculates the log2 of a 32-bit fixed point value
+ *
+ * Inputs:
+ * n = value of interest
+ *
+ * Outputs:
+ * returns the log2 of n
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_I32 EAS_flog2 (EAS_U32 n)
+{
+ EAS_U32 exp;
+ EAS_U32 interp;
+
+ /* check for error condition */
+ if (n == 0)
+ return MAX_NEGATIVE;
+
+ /* find exponent */
+ for (exp = 31; exp > 0; exp--)
+ {
+ /* shift until we get a 1 bit in bit 31 */
+ if ((n & (EAS_U32) MAX_NEGATIVE) != 0)
+ break;
+ n <<= 1;
+ }
+ /*lint -e{701} use shift for performance */
+ exp <<= LOG_EXPONENT_SHIFT;
+
+ /* get the least significant bits for interpolation */
+ interp = (n >> MANTISSA_LSB_SHIFT) & MANTISSA_LSB_MASK;
+
+ /* get the most significant bits for mantissa lookup */
+ n = (n >> MANTISSA_SHIFT) & MANTISSA_MASK;
+
+ /* interpolate mantissa */
+ interp = ((eas_log2_table[n+1] - eas_log2_table[n]) * interp) >> INTERPOLATION_SHIFT;
+ exp += eas_log2_table[n] + interp;
+
+ return (EAS_I32) exp;
+}
+
diff --git a/arm-wt-22k/lib_src/eas_ima_tables.c b/arm-wt-22k/lib_src/eas_ima_tables.c
index 56bd1eb..b03b4d4 100644
--- a/arm-wt-22k/lib_src/eas_ima_tables.c
+++ b/arm-wt-22k/lib_src/eas_ima_tables.c
@@ -1,12 +1,12 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_ima_tables.c
- *
- * Contents and purpose:
- * Contains the constant tables for IMA encode/decode
- *
- * Copyright (c) 2005 Sonic Network Inc.
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_ima_tables.c
+ *
+ * Contents and purpose:
+ * Contains the constant tables for IMA encode/decode
+ *
+ * Copyright (c) 2005 Sonic Network Inc.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,36 +19,36 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 760 $
- * $Date: 2007-07-17 23:09:36 -0700 (Tue, 17 Jul 2007) $
- *----------------------------------------------------------------------------
-*/
-
-#include "eas_types.h"
-
-/*----------------------------------------------------------------------------
- * ADPCM decode tables
- *----------------------------------------------------------------------------
-*/
-const EAS_I16 imaIndexTable[16] =
-{
- -1, -1, -1, -1, 2, 4, 6, 8,
- -1, -1, -1, -1, 2, 4, 6, 8
-};
-
-const EAS_I16 imaStepSizeTable[89] =
-{
- 7, 8, 9, 10, 11, 12, 13, 14, 16, 17,
- 19, 21, 23, 25, 28, 31, 34, 37, 41, 45,
- 50, 55, 60, 66, 73, 80, 88, 97, 107, 118,
- 130, 143, 157, 173, 190, 209, 230, 253, 279, 307,
- 337, 371, 408, 449, 494, 544, 598, 658, 724, 796,
- 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066,
- 2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358,
- 5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,
- 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767
-};
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 760 $
+ * $Date: 2007-07-17 23:09:36 -0700 (Tue, 17 Jul 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+#include "eas_types.h"
+
+/*----------------------------------------------------------------------------
+ * ADPCM decode tables
+ *----------------------------------------------------------------------------
+*/
+const EAS_I16 imaIndexTable[16] =
+{
+ -1, -1, -1, -1, 2, 4, 6, 8,
+ -1, -1, -1, -1, 2, 4, 6, 8
+};
+
+const EAS_I16 imaStepSizeTable[89] =
+{
+ 7, 8, 9, 10, 11, 12, 13, 14, 16, 17,
+ 19, 21, 23, 25, 28, 31, 34, 37, 41, 45,
+ 50, 55, 60, 66, 73, 80, 88, 97, 107, 118,
+ 130, 143, 157, 173, 190, 209, 230, 253, 279, 307,
+ 337, 371, 408, 449, 494, 544, 598, 658, 724, 796,
+ 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066,
+ 2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358,
+ 5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,
+ 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767
+};
+
diff --git a/arm-wt-22k/lib_src/eas_imaadpcm.c b/arm-wt-22k/lib_src/eas_imaadpcm.c
index 68bf257..41280b5 100644
--- a/arm-wt-22k/lib_src/eas_imaadpcm.c
+++ b/arm-wt-22k/lib_src/eas_imaadpcm.c
@@ -1,12 +1,12 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_imaadpcm.c
- *
- * Contents and purpose:
- * Implements the IMA ADPCM decoder
- *
- * Copyright Sonic Network Inc. 2005
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_imaadpcm.c
+ *
+ * Contents and purpose:
+ * Implements the IMA ADPCM decoder
+ *
+ * Copyright Sonic Network Inc. 2005
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,350 +19,350 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 847 $
- * $Date: 2007-08-27 21:30:08 -0700 (Mon, 27 Aug 2007) $
- *----------------------------------------------------------------------------
-*/
-
-#include "eas_data.h"
-#include "eas_host.h"
-#include "eas_pcm.h"
-#include "eas_math.h"
-#include "eas_report.h"
-
-// #define _DEBUG_IMA_ADPCM_LOCATE
-
-/*----------------------------------------------------------------------------
- * externs
- *----------------------------------------------------------------------------
-*/
-extern const EAS_I16 imaIndexTable[];
-extern const EAS_I16 imaStepSizeTable[];
-
-/*----------------------------------------------------------------------------
- * prototypes
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT IMADecoderInit (EAS_DATA_HANDLE pEASData, S_PCM_STATE *pState);
-static EAS_RESULT IMADecoderSample (EAS_DATA_HANDLE pEASData, S_PCM_STATE *pState);
-static void IMADecoderADPCM (S_DECODER_STATE *pState, EAS_U8 nibble);
-static EAS_RESULT IMADecoderLocate (EAS_DATA_HANDLE pEASData, S_PCM_STATE *pState, EAS_I32 time);
-
-/*----------------------------------------------------------------------------
- * IMA ADPCM Decoder interface
- *----------------------------------------------------------------------------
-*/
-const S_DECODER_INTERFACE IMADecoder =
-{
- IMADecoderInit,
- IMADecoderSample,
- IMADecoderLocate
-};
-
-/*----------------------------------------------------------------------------
- * IMADecoderInit()
- *----------------------------------------------------------------------------
- * Purpose:
- * Initializes the IMA ADPCM decoder
- *
- * Inputs:
- *
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, pEASData) common decoder interface - pEASData not used */
-static EAS_RESULT IMADecoderInit (EAS_DATA_HANDLE pEASData, S_PCM_STATE *pState)
-{
- pState->decoderL.step = 0;
- pState->decoderR.step = 0;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * IMADecoderSample()
- *----------------------------------------------------------------------------
- * Purpose:
- * Decodes an IMA ADPCM sample
- *
- * Inputs:
- *
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT IMADecoderSample (EAS_DATA_HANDLE pEASData, S_PCM_STATE *pState)
-{
- EAS_RESULT result;
- EAS_I16 sTemp;
-
- /* if high nibble, decode */
- if (pState->hiNibble)
- {
- IMADecoderADPCM(&pState->decoderL, (EAS_U8)(pState->srcByte >> 4));
- pState->hiNibble = EAS_FALSE;
- }
-
- /* low nibble, need to fetch another byte */
- else
- {
- /* check for loop */
- if ((pState->bytesLeft == 0) && (pState->loopSamples != 0))
- {
- /* seek to start of loop */
- if ((result = EAS_HWFileSeek(pEASData->hwInstData, pState->fileHandle, (EAS_I32) (pState->startPos + pState->loopLocation))) != EAS_SUCCESS)
- return result;
- pState->bytesLeft = pState->byteCount = (EAS_I32) pState->bytesLeftLoop;
- pState->blockCount = 0;
- pState->flags &= ~PCM_FLAGS_EMPTY;
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMADecoderSample: Rewind file to %d, bytesLeft = %d\n", pState->startPos, pState->bytesLeft); */ }
- }
-
- /* if start of block, fetch new predictor and step index */
- if ((pState->blockSize != 0) && (pState->blockCount == 0) && (pState->bytesLeft != 0))
- {
-
- /* get predicted sample for left channel */
- if ((result = EAS_HWGetWord(pEASData->hwInstData, pState->fileHandle, &sTemp, EAS_FALSE)) != EAS_SUCCESS)
- return result;
-#ifdef _DEBUG_IMA_ADPCM
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Predictor: Was %d, now %d\n", pState->decoderL.acc, sTemp); */ }
-#endif
- pState->decoderL.acc = pState->decoderL.x1 = sTemp;
-
- /* get step index for left channel - upper 8 bits are reserved */
- if ((result = EAS_HWGetWord(pEASData->hwInstData, pState->fileHandle, &sTemp, EAS_FALSE)) != EAS_SUCCESS)
- return result;
-#ifdef _DEBUG_IMA_ADPCM
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Step: Was %d, now %d\n", pState->decoderL.step, sTemp); */ }
-#endif
- pState->decoderL.step = sTemp & 0xff;
-
- if (pState->flags & PCM_FLAGS_STEREO)
- {
- /* get predicted sample for right channel */
- if ((result = EAS_HWGetWord(pEASData->hwInstData, pState->fileHandle, &sTemp, EAS_FALSE)) != EAS_SUCCESS)
- return result;
- pState->decoderR.acc = pState->decoderR.x1 = sTemp;
-
- /* get step index for right channel - upper 8 bits are reserved */
- if ((result = EAS_HWGetWord(pEASData->hwInstData, pState->fileHandle, &sTemp, EAS_FALSE)) != EAS_SUCCESS)
- return result;
-#ifdef _DEBUG_IMA_ADPCM
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Step: Was %d, now %d\n", pState->decoderR.step, sTemp); */ }
-#endif
- pState->decoderR.step = sTemp & 0xff;
-
- pState->blockCount = pState->blockSize - 8;
- pState->bytesLeft -= 8;
- }
- else
- {
- pState->blockCount = pState->blockSize - 4;
- pState->bytesLeft -= 4;
- }
- }
- else
- {
-
- /* get another ADPCM data pair */
- if (pState->bytesLeft)
- {
-
- if ((result = EAS_HWGetByte(pEASData->hwInstData, pState->fileHandle, &pState->srcByte)) != EAS_SUCCESS)
- return result;
-
- /* decode the low nibble */
- pState->bytesLeft--;
- pState->blockCount--;
- IMADecoderADPCM(&pState->decoderL, (EAS_U8)(pState->srcByte & 0x0f));
-
- if (pState->flags & PCM_FLAGS_STEREO)
- IMADecoderADPCM(&pState->decoderR, (EAS_U8)(pState->srcByte >> 4));
- else
- pState->hiNibble = EAS_TRUE;
- }
-
- /* out of ADPCM data, generate enough samples to fill buffer */
- else
- {
- pState->decoderL.x1 = pState->decoderL.x0;
- pState->decoderR.x1 = pState->decoderR.x0;
- }
- }
- }
-
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * IMADecoderADPCM()
- *----------------------------------------------------------------------------
- * Purpose:
- * Decodes an IMA ADPCM sample
- *
- * Inputs:
- *
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static void IMADecoderADPCM (S_DECODER_STATE *pState, EAS_U8 nibble)
-{
- EAS_INT delta;
- EAS_INT stepSize;
-
- /* get stepsize from table */
- stepSize = imaStepSizeTable[pState->step];
-
- /* delta = (abs(delta) + 0.5) * step / 4 */
- delta = 0;
- if (nibble & 4)
- delta += stepSize;
-
- if (nibble & 2)
- /*lint -e{702} use shift for performance */
- delta += stepSize >> 1;
-
- if (nibble & 1)
- /*lint -e{702} use shift for performance */
- delta += stepSize >> 2;
-
- /*lint -e{702} use shift for performance */
- delta += stepSize >> 3;
-
- /* integrate the delta */
- if (nibble & 8)
- pState->acc -= delta;
- else
- pState->acc += delta;
-
- /* saturate */
- if (pState->acc > 32767)
- pState->acc = 32767;
- if (pState->acc < -32768)
- pState->acc = -32768;
- pState->x1 = (EAS_PCM) pState->acc;
-
- /* compute new step size */
- pState->step += imaIndexTable[nibble];
- if (pState->step < 0)
- pState->step = 0;
- if (pState->step > 88)
- pState->step = 88;
-
-#ifdef _DEBUG_IMA_ADPCM
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "In=%u, Pred=%d, Step=%d\n", nibble, pState->acc, imaStepSizeTable[pState->step]); */ }
-#endif
-}
-
-/*----------------------------------------------------------------------------
- * IMADecoderLocate()
- *----------------------------------------------------------------------------
- * Locate in an IMA ADPCM stream
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT IMADecoderLocate (EAS_DATA_HANDLE pEASData, S_PCM_STATE *pState, EAS_I32 time)
-{
- EAS_RESULT result;
- EAS_I32 temp;
- EAS_I32 samplesPerBlock;
- EAS_I32 secs, msecs;
-
- /* no need to calculate if time is zero */
- if (time == 0)
- temp = 0;
-
- /* not zero */
- else
- {
-
- /* can't seek if not a blocked file */
- if (pState->blockSize == 0)
- return EAS_ERROR_FEATURE_NOT_AVAILABLE;
-
- /* calculate number of samples per block */
- if (pState->flags & PCM_FLAGS_STEREO)
- samplesPerBlock = pState->blockSize - 7;
- else
- samplesPerBlock = (pState->blockSize << 1) - 7;
-
- /* break down into secs and msecs */
- secs = time / 1000;
- msecs = time - (secs * 1000);
-
- /* calculate sample number fraction from msecs */
- temp = (msecs * pState->sampleRate);
- temp = (temp >> 10) + ((temp * 49) >> 21);
-
- /* add integer sample count */
- temp += secs * pState->sampleRate;
-
-#ifdef _DEBUG_IMA_ADPCM_LOCATE
- EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x2380b977, 0x00000006 , time, temp);
-#endif
-
- /* for looped samples, calculate position in the loop */
- if ((temp > pState->byteCount) && (pState->loopSamples != 0))
- {
- EAS_I32 numBlocks;
- EAS_I32 samplesPerLoop;
- EAS_I32 samplesInLastBlock;
-
- numBlocks = (EAS_I32) (pState->loopStart / pState->blockSize);
- samplesInLastBlock = (EAS_I32) pState->loopStart - (numBlocks * pState->blockSize);
- if (samplesInLastBlock)
- {
- if (pState->flags & PCM_FLAGS_STEREO)
- samplesInLastBlock = samplesInLastBlock - 7;
- else
- /*lint -e{703} use shift for performance */
- samplesInLastBlock = (samplesInLastBlock << 1) - 7;
- }
- samplesPerLoop = numBlocks * samplesPerBlock + samplesInLastBlock;
- temp = temp % samplesPerLoop;
-#ifdef _DEBUG_IMA_ADPCM_LOCATE
- EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x2380b977, 0x00000007 , numBlocks, samplesPerLoop, samplesInLastBlock, temp);
-#endif
- }
-
- /* find start of block for requested sample */
- temp = (temp / samplesPerBlock) * pState->blockSize;
-#ifdef _DEBUG_IMA_ADPCM_LOCATE
- EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x2380b977, 0x00000008 , temp);
-#endif
-
- }
-
- /* seek to new location */
- if ((result = EAS_PESeek(pEASData, pState, &temp)) != EAS_SUCCESS)
- return result;
-
-#ifdef _DEBUG_IMA_ADPCM_LOCATE
- EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x2380b977, 0x00000009 , pState->bytesLeft);
-#endif
-
- /* reset state */
- pState->blockCount = 0;
- pState->hiNibble = EAS_FALSE;
- if ((pState->state != EAS_STATE_PAUSING) && (pState->state != EAS_STATE_PAUSED))
- pState->state = EAS_STATE_READY;
-
- return EAS_SUCCESS;
-}
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 847 $
+ * $Date: 2007-08-27 21:30:08 -0700 (Mon, 27 Aug 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+#include "eas_data.h"
+#include "eas_host.h"
+#include "eas_pcm.h"
+#include "eas_math.h"
+#include "eas_report.h"
+
+// #define _DEBUG_IMA_ADPCM_LOCATE
+
+/*----------------------------------------------------------------------------
+ * externs
+ *----------------------------------------------------------------------------
+*/
+extern const EAS_I16 imaIndexTable[];
+extern const EAS_I16 imaStepSizeTable[];
+
+/*----------------------------------------------------------------------------
+ * prototypes
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT IMADecoderInit (EAS_DATA_HANDLE pEASData, S_PCM_STATE *pState);
+static EAS_RESULT IMADecoderSample (EAS_DATA_HANDLE pEASData, S_PCM_STATE *pState);
+static void IMADecoderADPCM (S_DECODER_STATE *pState, EAS_U8 nibble);
+static EAS_RESULT IMADecoderLocate (EAS_DATA_HANDLE pEASData, S_PCM_STATE *pState, EAS_I32 time);
+
+/*----------------------------------------------------------------------------
+ * IMA ADPCM Decoder interface
+ *----------------------------------------------------------------------------
+*/
+const S_DECODER_INTERFACE IMADecoder =
+{
+ IMADecoderInit,
+ IMADecoderSample,
+ IMADecoderLocate
+};
+
+/*----------------------------------------------------------------------------
+ * IMADecoderInit()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Initializes the IMA ADPCM decoder
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pEASData) common decoder interface - pEASData not used */
+static EAS_RESULT IMADecoderInit (EAS_DATA_HANDLE pEASData, S_PCM_STATE *pState)
+{
+ pState->decoderL.step = 0;
+ pState->decoderR.step = 0;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * IMADecoderSample()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Decodes an IMA ADPCM sample
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT IMADecoderSample (EAS_DATA_HANDLE pEASData, S_PCM_STATE *pState)
+{
+ EAS_RESULT result;
+ EAS_I16 sTemp;
+
+ /* if high nibble, decode */
+ if (pState->hiNibble)
+ {
+ IMADecoderADPCM(&pState->decoderL, (EAS_U8)(pState->srcByte >> 4));
+ pState->hiNibble = EAS_FALSE;
+ }
+
+ /* low nibble, need to fetch another byte */
+ else
+ {
+ /* check for loop */
+ if ((pState->bytesLeft == 0) && (pState->loopSamples != 0))
+ {
+ /* seek to start of loop */
+ if ((result = EAS_HWFileSeek(pEASData->hwInstData, pState->fileHandle, (EAS_I32) (pState->startPos + pState->loopLocation))) != EAS_SUCCESS)
+ return result;
+ pState->bytesLeft = pState->byteCount = (EAS_I32) pState->bytesLeftLoop;
+ pState->blockCount = 0;
+ pState->flags &= ~PCM_FLAGS_EMPTY;
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMADecoderSample: Rewind file to %d, bytesLeft = %d\n", pState->startPos, pState->bytesLeft); */ }
+ }
+
+ /* if start of block, fetch new predictor and step index */
+ if ((pState->blockSize != 0) && (pState->blockCount == 0) && (pState->bytesLeft != 0))
+ {
+
+ /* get predicted sample for left channel */
+ if ((result = EAS_HWGetWord(pEASData->hwInstData, pState->fileHandle, &sTemp, EAS_FALSE)) != EAS_SUCCESS)
+ return result;
+#ifdef _DEBUG_IMA_ADPCM
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Predictor: Was %d, now %d\n", pState->decoderL.acc, sTemp); */ }
+#endif
+ pState->decoderL.acc = pState->decoderL.x1 = sTemp;
+
+ /* get step index for left channel - upper 8 bits are reserved */
+ if ((result = EAS_HWGetWord(pEASData->hwInstData, pState->fileHandle, &sTemp, EAS_FALSE)) != EAS_SUCCESS)
+ return result;
+#ifdef _DEBUG_IMA_ADPCM
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Step: Was %d, now %d\n", pState->decoderL.step, sTemp); */ }
+#endif
+ pState->decoderL.step = sTemp & 0xff;
+
+ if (pState->flags & PCM_FLAGS_STEREO)
+ {
+ /* get predicted sample for right channel */
+ if ((result = EAS_HWGetWord(pEASData->hwInstData, pState->fileHandle, &sTemp, EAS_FALSE)) != EAS_SUCCESS)
+ return result;
+ pState->decoderR.acc = pState->decoderR.x1 = sTemp;
+
+ /* get step index for right channel - upper 8 bits are reserved */
+ if ((result = EAS_HWGetWord(pEASData->hwInstData, pState->fileHandle, &sTemp, EAS_FALSE)) != EAS_SUCCESS)
+ return result;
+#ifdef _DEBUG_IMA_ADPCM
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Step: Was %d, now %d\n", pState->decoderR.step, sTemp); */ }
+#endif
+ pState->decoderR.step = sTemp & 0xff;
+
+ pState->blockCount = pState->blockSize - 8;
+ pState->bytesLeft -= 8;
+ }
+ else
+ {
+ pState->blockCount = pState->blockSize - 4;
+ pState->bytesLeft -= 4;
+ }
+ }
+ else
+ {
+
+ /* get another ADPCM data pair */
+ if (pState->bytesLeft)
+ {
+
+ if ((result = EAS_HWGetByte(pEASData->hwInstData, pState->fileHandle, &pState->srcByte)) != EAS_SUCCESS)
+ return result;
+
+ /* decode the low nibble */
+ pState->bytesLeft--;
+ pState->blockCount--;
+ IMADecoderADPCM(&pState->decoderL, (EAS_U8)(pState->srcByte & 0x0f));
+
+ if (pState->flags & PCM_FLAGS_STEREO)
+ IMADecoderADPCM(&pState->decoderR, (EAS_U8)(pState->srcByte >> 4));
+ else
+ pState->hiNibble = EAS_TRUE;
+ }
+
+ /* out of ADPCM data, generate enough samples to fill buffer */
+ else
+ {
+ pState->decoderL.x1 = pState->decoderL.x0;
+ pState->decoderR.x1 = pState->decoderR.x0;
+ }
+ }
+ }
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * IMADecoderADPCM()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Decodes an IMA ADPCM sample
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static void IMADecoderADPCM (S_DECODER_STATE *pState, EAS_U8 nibble)
+{
+ EAS_INT delta;
+ EAS_INT stepSize;
+
+ /* get stepsize from table */
+ stepSize = imaStepSizeTable[pState->step];
+
+ /* delta = (abs(delta) + 0.5) * step / 4 */
+ delta = 0;
+ if (nibble & 4)
+ delta += stepSize;
+
+ if (nibble & 2)
+ /*lint -e{702} use shift for performance */
+ delta += stepSize >> 1;
+
+ if (nibble & 1)
+ /*lint -e{702} use shift for performance */
+ delta += stepSize >> 2;
+
+ /*lint -e{702} use shift for performance */
+ delta += stepSize >> 3;
+
+ /* integrate the delta */
+ if (nibble & 8)
+ pState->acc -= delta;
+ else
+ pState->acc += delta;
+
+ /* saturate */
+ if (pState->acc > 32767)
+ pState->acc = 32767;
+ if (pState->acc < -32768)
+ pState->acc = -32768;
+ pState->x1 = (EAS_PCM) pState->acc;
+
+ /* compute new step size */
+ pState->step += imaIndexTable[nibble];
+ if (pState->step < 0)
+ pState->step = 0;
+ if (pState->step > 88)
+ pState->step = 88;
+
+#ifdef _DEBUG_IMA_ADPCM
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "In=%u, Pred=%d, Step=%d\n", nibble, pState->acc, imaStepSizeTable[pState->step]); */ }
+#endif
+}
+
+/*----------------------------------------------------------------------------
+ * IMADecoderLocate()
+ *----------------------------------------------------------------------------
+ * Locate in an IMA ADPCM stream
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT IMADecoderLocate (EAS_DATA_HANDLE pEASData, S_PCM_STATE *pState, EAS_I32 time)
+{
+ EAS_RESULT result;
+ EAS_I32 temp;
+ EAS_I32 samplesPerBlock;
+ EAS_I32 secs, msecs;
+
+ /* no need to calculate if time is zero */
+ if (time == 0)
+ temp = 0;
+
+ /* not zero */
+ else
+ {
+
+ /* can't seek if not a blocked file */
+ if (pState->blockSize == 0)
+ return EAS_ERROR_FEATURE_NOT_AVAILABLE;
+
+ /* calculate number of samples per block */
+ if (pState->flags & PCM_FLAGS_STEREO)
+ samplesPerBlock = pState->blockSize - 7;
+ else
+ samplesPerBlock = (pState->blockSize << 1) - 7;
+
+ /* break down into secs and msecs */
+ secs = time / 1000;
+ msecs = time - (secs * 1000);
+
+ /* calculate sample number fraction from msecs */
+ temp = (msecs * pState->sampleRate);
+ temp = (temp >> 10) + ((temp * 49) >> 21);
+
+ /* add integer sample count */
+ temp += secs * pState->sampleRate;
+
+#ifdef _DEBUG_IMA_ADPCM_LOCATE
+ EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x2380b977, 0x00000006 , time, temp);
+#endif
+
+ /* for looped samples, calculate position in the loop */
+ if ((temp > pState->byteCount) && (pState->loopSamples != 0))
+ {
+ EAS_I32 numBlocks;
+ EAS_I32 samplesPerLoop;
+ EAS_I32 samplesInLastBlock;
+
+ numBlocks = (EAS_I32) (pState->loopStart / pState->blockSize);
+ samplesInLastBlock = (EAS_I32) pState->loopStart - (numBlocks * pState->blockSize);
+ if (samplesInLastBlock)
+ {
+ if (pState->flags & PCM_FLAGS_STEREO)
+ samplesInLastBlock = samplesInLastBlock - 7;
+ else
+ /*lint -e{703} use shift for performance */
+ samplesInLastBlock = (samplesInLastBlock << 1) - 7;
+ }
+ samplesPerLoop = numBlocks * samplesPerBlock + samplesInLastBlock;
+ temp = temp % samplesPerLoop;
+#ifdef _DEBUG_IMA_ADPCM_LOCATE
+ EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x2380b977, 0x00000007 , numBlocks, samplesPerLoop, samplesInLastBlock, temp);
+#endif
+ }
+
+ /* find start of block for requested sample */
+ temp = (temp / samplesPerBlock) * pState->blockSize;
+#ifdef _DEBUG_IMA_ADPCM_LOCATE
+ EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x2380b977, 0x00000008 , temp);
+#endif
+
+ }
+
+ /* seek to new location */
+ if ((result = EAS_PESeek(pEASData, pState, &temp)) != EAS_SUCCESS)
+ return result;
+
+#ifdef _DEBUG_IMA_ADPCM_LOCATE
+ EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x2380b977, 0x00000009 , pState->bytesLeft);
+#endif
+
+ /* reset state */
+ pState->blockCount = 0;
+ pState->hiNibble = EAS_FALSE;
+ if ((pState->state != EAS_STATE_PAUSING) && (pState->state != EAS_STATE_PAUSED))
+ pState->state = EAS_STATE_READY;
+
+ return EAS_SUCCESS;
+}
+
diff --git a/arm-wt-22k/lib_src/eas_imelody.c b/arm-wt-22k/lib_src/eas_imelody.c
index 5b7e7b8..05380e5 100644
--- a/arm-wt-22k/lib_src/eas_imelody.c
+++ b/arm-wt-22k/lib_src/eas_imelody.c
@@ -1,12 +1,12 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_imelody.c
- *
- * Contents and purpose:
- * iMelody parser
- *
- * Copyright Sonic Network Inc. 2005
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_imelody.c
+ *
+ * Contents and purpose:
+ * iMelody parser
+ *
+ * Copyright Sonic Network Inc. 2005
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,1724 +19,1729 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 797 $
- * $Date: 2007-08-01 00:15:56 -0700 (Wed, 01 Aug 2007) $
- *----------------------------------------------------------------------------
-*/
-
-/* lint doesn't like the way some string.h files look */
-#ifdef _lint
-#include "lint_stdlib.h"
-#else
-#include <string.h>
-#endif
-
-#include "eas_data.h"
-#include "eas_miditypes.h"
-#include "eas_parser.h"
-#include "eas_report.h"
-#include "eas_host.h"
-#include "eas_midi.h"
-#include "eas_config.h"
-#include "eas_vm_protos.h"
-#include "eas_imelodydata.h"
-#include "eas_ctype.h"
-
-// #define _DEBUG_IMELODY
-
-/* increase gain for mono ringtones */
-#define IMELODY_GAIN_OFFSET 8
-
-/* length of 32nd note in 1/256ths of a msec for 120 BPM tempo */
-#define DEFAULT_TICK_CONV 16000
-#define TICK_CONVERT 1920000
-
-/* default channel and program for iMelody playback */
-#define IMELODY_CHANNEL 0
-#define IMELODY_PROGRAM 80
-#define IMELODY_VEL_MUL 4
-#define IMELODY_VEL_OFS 67
-
-/* multiplier for fixed point triplet conversion */
-#define TRIPLET_MULTIPLIER 683
-#define TRIPLET_SHIFT 10
-
-static const char* const tokens[] =
-{
- "BEGIN:IMELODY",
- "VERSION:",
- "FORMAT:CLASS",
- "NAME:",
- "COMPOSER:",
- "BEAT:",
- "STYLE:",
- "VOLUME:",
- "MELODY:",
- "END:IMELODY"
-};
-
-/* ledon or ledoff */
-static const char ledStr[] = "edo";
-
-/* vibeon or vibeoff */
-static const char vibeStr[] = "ibeo";
-
-/* backon or backoff */
-static const char backStr[] = "cko";
-
-typedef enum
-{
- TOKEN_BEGIN,
- TOKEN_VERSION,
- TOKEN_FORMAT,
- TOKEN_NAME,
- TOKEN_COMPOSER,
- TOKEN_BEAT,
- TOKEN_STYLE,
- TOKEN_VOLUME,
- TOKEN_MELODY,
- TOKEN_END,
- TOKEN_INVALID
-} ENUM_IMELODY_TOKENS;
-
-/* lookup table for note values */
-static const EAS_I8 noteTable[] = { 9, 11, 0, 2, 4, 5, 7 };
-
-/* inline functions */
-#ifdef _DEBUG_IMELODY
-static void PutBackChar (S_IMELODY_DATA *pData)
-{
- if (pData->index)
- pData->index--;
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "PutBackChar '%c'\n", pData->buffer[pData->index]); */ }
-}
-#else
-EAS_INLINE void PutBackChar (S_IMELODY_DATA *pData) { if (pData->index) pData->index--; }
-#endif
-
-
-/* local prototypes */
-static EAS_RESULT IMY_CheckFileType (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle, EAS_VOID_PTR *ppHandle, EAS_I32 offset);
-static EAS_RESULT IMY_Prepare (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
-static EAS_RESULT IMY_Time (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_U32 *pTime);
-static EAS_RESULT IMY_Event (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_INT parserMode);
-static EAS_RESULT IMY_State (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_STATE *pState);
-static EAS_RESULT IMY_Close (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
-static EAS_RESULT IMY_Reset (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
-static EAS_RESULT IMY_Pause (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
-static EAS_RESULT IMY_Resume (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
-static EAS_RESULT IMY_SetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value);
-static EAS_RESULT IMY_GetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue);
-static EAS_BOOL IMY_PlayNote (S_EAS_DATA *pEASData, S_IMELODY_DATA *pData, EAS_I8 note, EAS_INT parserMode);
-static EAS_BOOL IMY_PlayRest (S_EAS_DATA *pEASData, S_IMELODY_DATA *pData);
-static EAS_BOOL IMY_GetDuration (EAS_HW_DATA_HANDLE hwInstData, S_IMELODY_DATA *pData, EAS_I32 *pDuration);
-static EAS_BOOL IMY_GetLEDState (S_EAS_DATA *pEASData, S_IMELODY_DATA *pData);
-static EAS_BOOL IMY_GetVibeState (S_EAS_DATA *pEASData, S_IMELODY_DATA *pData);
-static EAS_BOOL IMY_GetBackState (S_EAS_DATA *pEASData, S_IMELODY_DATA *pData);
-static EAS_BOOL IMY_GetVolume (EAS_HW_DATA_HANDLE hwInstData, S_IMELODY_DATA *pData, EAS_BOOL inHeader);
-static EAS_BOOL IMY_GetNumber (EAS_HW_DATA_HANDLE hwInstData, S_IMELODY_DATA *pData, EAS_INT *temp, EAS_BOOL inHeader);
-static EAS_RESULT IMY_ParseHeader (S_EAS_DATA *pEASData, S_IMELODY_DATA* pData);
-static EAS_I8 IMY_GetNextChar (EAS_HW_DATA_HANDLE hwInstData, S_IMELODY_DATA *pData, EAS_BOOL inHeader);
-static EAS_RESULT IMY_ReadLine (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE fileHandle, EAS_I8 *buffer, EAS_I32 *pStartLine);
-static EAS_INT IMY_ParseLine (EAS_I8 *buffer, EAS_U8 *pIndex);
-
-
-/*----------------------------------------------------------------------------
- *
- * EAS_iMelody_Parser
- *
- * This structure contains the functional interface for the iMelody parser
- *----------------------------------------------------------------------------
-*/
-const S_FILE_PARSER_INTERFACE EAS_iMelody_Parser =
-{
- IMY_CheckFileType,
- IMY_Prepare,
- IMY_Time,
- IMY_Event,
- IMY_State,
- IMY_Close,
- IMY_Reset,
- IMY_Pause,
- IMY_Resume,
- NULL,
- IMY_SetData,
- IMY_GetData,
- NULL
-};
-
-/*----------------------------------------------------------------------------
- * IMY_CheckFileType()
- *----------------------------------------------------------------------------
- * Purpose:
- * Check the file type to see if we can parse it
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT IMY_CheckFileType (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle, EAS_VOID_PTR *ppHandle, EAS_I32 offset)
-{
- S_IMELODY_DATA* pData;
- EAS_I8 buffer[MAX_LINE_SIZE+1];
- EAS_U8 index;
-
-#ifdef _DEBUG_IMELODY
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Enter IMY_CheckFileType\n"); */ }
-#endif
-
- /* read the first line of the file */
- *ppHandle = NULL;
- if (IMY_ReadLine(pEASData->hwInstData, fileHandle, buffer, NULL) != EAS_SUCCESS)
- return EAS_SUCCESS;
-
- /* check for header string */
- if (IMY_ParseLine(buffer, &index) == TOKEN_BEGIN)
- {
-
- /* check for static memory allocation */
- if (pEASData->staticMemoryModel)
- pData = EAS_CMEnumData(EAS_CM_IMELODY_DATA);
- else
- pData = EAS_HWMalloc(pEASData->hwInstData, sizeof(S_IMELODY_DATA));
- if (!pData)
- return EAS_ERROR_MALLOC_FAILED;
- EAS_HWMemSet(pData, 0, sizeof(S_IMELODY_DATA));
-
- /* initialize */
- pData->fileHandle = fileHandle;
- pData->fileOffset = offset;
- pData->state = EAS_STATE_ERROR;
- pData->state = EAS_STATE_OPEN;
-
- /* return a pointer to the instance data */
- *ppHandle = pData;
- }
-
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * IMY_Prepare()
- *----------------------------------------------------------------------------
- * Purpose:
- * Prepare to parse the file. Allocates instance data (or uses static allocation for
- * static memory model).
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT IMY_Prepare (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
-{
- S_IMELODY_DATA* pData;
- EAS_RESULT result;
-
-#ifdef _DEBUG_IMELODY
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Enter IMY_Prepare\n"); */ }
-#endif
-
- /* check for valid state */
- pData = (S_IMELODY_DATA*) pInstData;
- if (pData->state != EAS_STATE_OPEN)
- return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
-
- /* instantiate a synthesizer */
- if ((result = VMInitMIDI(pEASData, &pData->pSynth)) != EAS_SUCCESS)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "VMInitMIDI returned %d\n", result); */ }
- return result;
- }
-
- /* parse the header */
- if ((result = IMY_ParseHeader(pEASData, pData)) != EAS_SUCCESS)
- return result;
-
-#ifdef _DEBUG_IMELODY
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_Prepare: state set to EAS_STATE_READY\n"); */ }
-#endif
-
- pData ->state = EAS_STATE_READY;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * IMY_Time()
- *----------------------------------------------------------------------------
- * Purpose:
- * Returns the time of the next event in msecs
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- * pTime - pointer to variable to hold time of next event (in msecs)
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, pEASData) common decoder interface - pEASData not used */
-static EAS_RESULT IMY_Time (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_U32 *pTime)
-{
- S_IMELODY_DATA *pData;
-
- pData = (S_IMELODY_DATA*) pInstData;
-
- /* return time in milliseconds */
- /*lint -e{704} use shift instead of division */
- *pTime = pData->time >> 8;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * IMY_Event()
- *----------------------------------------------------------------------------
- * Purpose:
- * Parse the next event in the file
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT IMY_Event (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_INT parserMode)
-{
- S_IMELODY_DATA* pData;
- EAS_RESULT result;
- EAS_I8 c;
- EAS_BOOL eof;
- EAS_INT temp;
-
- pData = (S_IMELODY_DATA*) pInstData;
- if (pData->state >= EAS_STATE_OPEN)
- return EAS_SUCCESS;
-
- if (pData->state == EAS_STATE_READY) {
- pData->state = EAS_STATE_PLAY;
- }
-
- /* initialize MIDI channel when the track starts playing */
- if (pData->time == 0)
- {
-
-#ifdef _DEBUG_IMELODY
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_Event: Reset\n"); */ }
-#endif
- /* set program to square lead */
- VMProgramChange(pEASData->pVoiceMgr, pData->pSynth, IMELODY_CHANNEL, IMELODY_PROGRAM);
-
- /* set channel volume to max */
- VMControlChange(pEASData->pVoiceMgr, pData->pSynth, IMELODY_CHANNEL, 7, 127);
- }
-
- /* check for end of note */
- if (pData->note)
- {
-
-#ifdef _DEBUG_IMELODY
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Stopping note %d\n", pData->note); */ }
-#endif
- /* stop the note */
- VMStopNote(pEASData->pVoiceMgr, pData->pSynth, IMELODY_CHANNEL, pData->note, 0);
- pData->note = 0;
-
- /* check for rest between notes */
- if (pData->restTicks)
- {
- pData->time += pData->restTicks;
- pData->restTicks = 0;
- return EAS_SUCCESS;
- }
- }
-
- /* parse the next event */
- eof = EAS_FALSE;
- while (!eof)
- {
-
- /* get next character */
- c = IMY_GetNextChar(pEASData->hwInstData, pData, EAS_FALSE);
-
- switch (c)
- {
- /* start repeat */
- case '(':
-
-#ifdef _DEBUG_IMELODY
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Enter repeat section\n", c); */ }
-#endif
-
- if (pData->repeatOffset < 0)
- {
- pData->repeatOffset = pData->startLine + (EAS_I32) pData->index;
-
-#ifdef _DEBUG_IMELODY
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Repeat offset = %d\n", pData->repeatOffset); */ }
-#endif
- }
- else
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Ignoring nested repeat section\n"); */ }
- break;
-
- /* end repeat */
- case ')':
-
-#ifdef _DEBUG_IMELODY
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "End repeat section, repeat offset = %d\n", pData->repeatOffset); */ }
-#endif
- /* ignore invalid repeats */
- if (pData->repeatCount >= 0)
- {
-
- /* decrement repeat count (repeatCount == 0 means infinite loop) */
- if (pData->repeatCount > 0)
- {
- if (--pData->repeatCount == 0)
- {
- pData->repeatCount = -1;
-#ifdef _DEBUG_IMELODY
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Repeat loop complete\n"); */ }
-#endif
- }
- }
-
-//2 TEMPORARY FIX: If locating, don't do infinite loops.
-//3 We need a different mode for metadata parsing where we don't loop at all
- if ((parserMode == eParserModePlay) || (pData->repeatCount != 0))
- {
-
-#ifdef _DEBUG_IMELODY
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Rewinding file for repeat\n"); */ }
-#endif
- /* rewind to start of loop */
- if ((result = EAS_HWFileSeek(pEASData->hwInstData, pData->fileHandle, pData->repeatOffset)) != EAS_SUCCESS)
- return result;
- IMY_ReadLine(pEASData->hwInstData, pData->fileHandle, pData->buffer, &pData->startLine);
- pData->index = 0;
-
- /* if last loop, prevent future loops */
- if (pData->repeatCount == -1)
- pData->repeatOffset = -1;
- }
- }
- break;
-
- /* repeat count */
- case '@':
- if (!IMY_GetNumber(pEASData->hwInstData, pData, &temp, EAS_FALSE))
- eof = EAS_TRUE;
- else if (pData->repeatOffset > 0)
- {
-
-#ifdef _DEBUG_IMELODY
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Repeat count = %dt", pData->repeatCount); */ }
-#endif
- if (pData->repeatCount < 0)
- pData->repeatCount = (EAS_I16) temp;
- }
- break;
-
- /* volume */
- case 'V':
- if (!IMY_GetVolume(pEASData->hwInstData, pData, EAS_FALSE))
- eof = EAS_TRUE;
- break;
-
- /* flat */
- case '&':
- pData->noteModifier = -1;
- break;
-
- /* sharp */
- case '#':
- pData->noteModifier = +1;
- break;
-
- /* octave */
- case '*':
- c = IMY_GetNextChar(pEASData->hwInstData, pData, EAS_FALSE);
- if (IsDigit(c))
- pData->octave = (EAS_U8) ((c - '0' + 1) * 12);
- else if (!c)
- eof = EAS_TRUE;
- break;
-
- /* ledon or ledoff */
- case 'l':
- if (!IMY_GetLEDState(pEASData, pData))
- eof = EAS_TRUE;
- break;
-
- /* vibeon or vibeoff */
- case 'v':
- if (!IMY_GetVibeState(pEASData, pData))
- eof = EAS_TRUE;
- break;
-
- /* either a B note or backon or backoff */
- case 'b':
- if (IMY_GetNextChar(pEASData->hwInstData, pData, EAS_FALSE) == 'a')
- {
- if (!IMY_GetBackState(pEASData, pData))
- eof = EAS_TRUE;
- }
- else
- {
- PutBackChar(pData);
- if (IMY_PlayNote(pEASData, pData, c, parserMode))
- return EAS_SUCCESS;
- eof = EAS_TRUE;
- }
- break;
-
- /* rest */
- case 'r':
- case 'R':
- if (IMY_PlayRest(pEASData, pData))
- return EAS_SUCCESS;
- eof = EAS_TRUE;
- break;
-
- /* EOF */
- case 0:
-#ifdef _DEBUG_IMELODY
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_Event: end of iMelody file detected\n"); */ }
-#endif
- eof = EAS_TRUE;
- break;
-
- /* must be a note */
- default:
- c = ToLower(c);
- if ((c >= 'a') && (c <= 'g'))
- {
- if (IMY_PlayNote(pEASData, pData, c, parserMode))
- return EAS_SUCCESS;
- eof = EAS_TRUE;
- }
- else
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Ignoring unexpected character '%c' [0x%02x]\n", c, c); */ }
- break;
- }
- }
-
- /* handle EOF */
-#ifdef _DEBUG_IMELODY
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_Event: state set to EAS_STATE_STOPPING\n"); */ }
-#endif
- pData->state = EAS_STATE_STOPPING;
- VMReleaseAllVoices(pEASData->pVoiceMgr, pData->pSynth);
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * IMY_State()
- *----------------------------------------------------------------------------
- * Purpose:
- * Returns the current state of the stream
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- * pState - pointer to variable to store state
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, pEASData) common decoder interface - pEASData not used */
-static EAS_RESULT IMY_State (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 *pState)
-{
- S_IMELODY_DATA* pData;
-
- /* establish pointer to instance data */
- pData = (S_IMELODY_DATA*) pInstData;
-
- /* if stopping, check to see if synth voices are active */
- if (pData->state == EAS_STATE_STOPPING)
- {
- if (VMActiveVoices(pData->pSynth) == 0)
- {
- pData->state = EAS_STATE_STOPPED;
-#ifdef _DEBUG_IMELODY
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_State: state set to EAS_STATE_STOPPED\n"); */ }
-#endif
- }
- }
-
- if (pData->state == EAS_STATE_PAUSING)
- {
- if (VMActiveVoices(pData->pSynth) == 0)
- {
-#ifdef _DEBUG_IMELODY
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_State: state set to EAS_STATE_PAUSED\n"); */ }
-#endif
- pData->state = EAS_STATE_PAUSED;
- }
- }
-
- /* return current state */
- *pState = pData->state;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * IMY_Close()
- *----------------------------------------------------------------------------
- * Purpose:
- * Close the file and clean up
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT IMY_Close (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
-{
- S_IMELODY_DATA* pData;
- EAS_RESULT result;
-
-#ifdef _DEBUG_IMELODY
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_Close: close file\n"); */ }
-#endif
-
- pData = (S_IMELODY_DATA*) pInstData;
-
- /* close the file */
- if ((result = EAS_HWCloseFile(pEASData->hwInstData, pData->fileHandle)) != EAS_SUCCESS)
- return result;
-
- /* free the synth */
- if (pData->pSynth != NULL)
- VMMIDIShutdown(pEASData, pData->pSynth);
-
- /* if using dynamic memory, free it */
- if (!pEASData->staticMemoryModel)
- EAS_HWFree(pEASData->hwInstData, pData);
-
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * IMY_Reset()
- *----------------------------------------------------------------------------
- * Purpose:
- * Reset the sequencer. Used for locating backwards in the file.
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT IMY_Reset (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
-{
- S_IMELODY_DATA* pData;
- EAS_RESULT result;
-
-#ifdef _DEBUG_IMELODY
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_Reset: reset file\n"); */ }
-#endif
- pData = (S_IMELODY_DATA*) pInstData;
-
- /* reset the synth */
- VMReset(pEASData->pVoiceMgr, pData->pSynth, EAS_TRUE);
-
- /* reset time to zero */
- pData->time = 0;
- pData->note = 0;
-
- /* reset file position and re-parse header */
- pData->state = EAS_STATE_ERROR;
- if ((result = EAS_HWFileSeek(pEASData->hwInstData, pData->fileHandle, pData->fileOffset)) != EAS_SUCCESS)
- return result;
- if ((result = IMY_ParseHeader (pEASData, pData)) != EAS_SUCCESS)
- return result;
-
-#ifdef _DEBUG_IMELODY
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_Reset: state set to EAS_STATE_ERROR\n"); */ }
-#endif
-
- pData->state = EAS_STATE_READY;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * IMY_Pause()
- *----------------------------------------------------------------------------
- * Purpose:
- * Pauses the sequencer. Mutes all voices and sets state to pause.
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT IMY_Pause (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
-{
- S_IMELODY_DATA *pData;
-
-#ifdef _DEBUG_IMELODY
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_Pause: pause file\n"); */ }
-#endif
-
- /* can't pause a stopped stream */
- pData = (S_IMELODY_DATA*) pInstData;
- if (pData->state == EAS_STATE_STOPPED)
- return EAS_ERROR_ALREADY_STOPPED;
-
- /* mute the synthesizer */
- VMMuteAllVoices(pEASData->pVoiceMgr, pData->pSynth);
- pData->state = EAS_STATE_PAUSING;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * IMY_Resume()
- *----------------------------------------------------------------------------
- * Purpose:
- * Resume playing after a pause, sets state back to playing.
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, pEASData) common decoder interface - pEASData not used */
-static EAS_RESULT IMY_Resume (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
-{
- S_IMELODY_DATA *pData;
-
-#ifdef _DEBUG_IMELODY
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_Resume: resume file\n"); */ }
-#endif
-
- /* can't resume a stopped stream */
- pData = (S_IMELODY_DATA*) pInstData;
- if (pData->state == EAS_STATE_STOPPED)
- return EAS_ERROR_ALREADY_STOPPED;
-
- /* nothing to do but resume playback */
- pData->state = EAS_STATE_PLAY;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * IMY_SetData()
- *----------------------------------------------------------------------------
- * Purpose:
- * Adjust tempo relative to song tempo
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * pInstData - pointer to iMelody instance data
- * rate - rate (28-bit fractional amount)
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, pEASData) common decoder interface - pEASData not used */
-static EAS_RESULT IMY_SetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value)
-{
- S_IMELODY_DATA *pData;
-
- pData = (S_IMELODY_DATA*) pInstData;
- switch (param)
- {
-
- /* set metadata callback */
- case PARSER_DATA_METADATA_CB:
- EAS_HWMemCpy(&pData->metadata, (void*) value, sizeof(S_METADATA_CB));
- break;
-
- default:
- return EAS_ERROR_INVALID_PARAMETER;
- }
-
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * IMY_GetData()
- *----------------------------------------------------------------------------
- * Purpose:
- * Return the file type
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * pInstData - pointer to iMelody instance data
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, pEASData) common decoder interface - pEASData not used */
-static EAS_RESULT IMY_GetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue)
-{
- S_IMELODY_DATA *pData;
-
- pData = (S_IMELODY_DATA*) pInstData;
-
- switch (param)
- {
- /* return file type as iMelody */
- case PARSER_DATA_FILE_TYPE:
- *pValue = EAS_FILE_IMELODY;
- break;
-
- case PARSER_DATA_SYNTH_HANDLE:
- *pValue = (EAS_I32) pData->pSynth;
- break;
-
- case PARSER_DATA_GAIN_OFFSET:
- *pValue = IMELODY_GAIN_OFFSET;
- break;
-
- default:
- return EAS_ERROR_INVALID_PARAMETER;
- }
-
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * IMY_PlayNote()
- *----------------------------------------------------------------------------
- * Purpose:
- *
- *
- * Inputs:
- *
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_BOOL IMY_PlayNote (S_EAS_DATA *pEASData, S_IMELODY_DATA *pData, EAS_I8 note, EAS_INT parserMode)
-{
- EAS_I32 duration;
- EAS_U8 velocity;
-
-
-#ifdef _DEBUG_IMELODY
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_PlayNote: start note %d\n", note); */ }
-#endif
-
- /* get the duration */
- if (!IMY_GetDuration(pEASData->hwInstData, pData, &duration))
- return EAS_FALSE;
-
- /* save note value */
- pData->note = (EAS_U8) (pData->octave + noteTable[note - 'a'] + pData->noteModifier);
- velocity = (EAS_U8) (pData->volume ? pData->volume * IMELODY_VEL_MUL + IMELODY_VEL_OFS : 0);
-
- /* start note only if in play mode */
- if (parserMode == eParserModePlay)
- VMStartNote(pEASData->pVoiceMgr, pData->pSynth, IMELODY_CHANNEL, pData->note, velocity);
-
-#ifdef _DEBUG_IMELODY
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_PlayNote: Start note %d, duration %d\n", pData->note, duration); */ }
-#endif
-
- /* determine note length */
- switch (pData->style)
- {
- case 0:
- /*lint -e{704} shift for performance */
- pData->restTicks = duration >> 4;
- break;
- case 1:
- pData->restTicks = 0;
- break;
- case 2:
- /*lint -e{704} shift for performance */
- pData->restTicks = duration >> 1;
- break;
- default:
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "IMY_PlayNote: Note style out of range: %d\n", pData->style); */ }
- /*lint -e{704} shift for performance */
- pData->restTicks = duration >> 4;
- break;
- }
-
- /* next event is at end of this note */
- pData->time += duration - pData->restTicks;
-
- /* reset the flat/sharp modifier */
- pData->noteModifier = 0;
-
- return EAS_TRUE;
-}
-
-/*----------------------------------------------------------------------------
- * IMY_PlayRest()
- *----------------------------------------------------------------------------
- * Purpose:
- *
- *
- * Inputs:
- *
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_BOOL IMY_PlayRest (S_EAS_DATA *pEASData, S_IMELODY_DATA *pData)
-{
- EAS_I32 duration;
-
-#ifdef _DEBUG_IMELODY
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Enter IMY_PlayRest]n"); */ }
-#endif
-
- /* get the duration */
- if (!IMY_GetDuration(pEASData->hwInstData, pData, &duration))
- return EAS_FALSE;
-
-#ifdef _DEBUG_IMELODY
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_PlayRest: note duration %d\n", duration); */ }
-#endif
-
- /* next event is at end of this note */
- pData->time += duration;
- return EAS_TRUE;
-}
-
-/*----------------------------------------------------------------------------
- * IMY_GetDuration()
- *----------------------------------------------------------------------------
- * Purpose:
- *
- *
- * Inputs:
- *
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-
-static EAS_BOOL IMY_GetDuration (EAS_HW_DATA_HANDLE hwInstData, S_IMELODY_DATA *pData, EAS_I32 *pDuration)
-{
- EAS_I32 duration;
- EAS_I8 c;
-
- /* get the duration */
- *pDuration = 0;
- c = IMY_GetNextChar(hwInstData, pData, EAS_FALSE);
- if (!c)
- return EAS_FALSE;
- if ((c < '0') || (c > '5'))
- {
-#ifdef _DEBUG_IMELODY
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_GetDuration: error in duration '%c'\n", c); */ }
-#endif
- return EAS_FALSE;
- }
-
- /* calculate total length of note */
- duration = pData->tick * (1 << ('5' - c));
-
- /* check for duration modifier */
- c = IMY_GetNextChar(hwInstData, pData, EAS_FALSE);
- if (c)
- {
- if (c == '.')
- /*lint -e{704} shift for performance */
- duration += duration >> 1;
- else if (c == ':')
- /*lint -e{704} shift for performance */
- duration += (duration >> 1) + (duration >> 2);
- else if (c == ';')
- /*lint -e{704} shift for performance */
- duration = (duration * TRIPLET_MULTIPLIER) >> TRIPLET_SHIFT;
- else
- PutBackChar(pData);
- }
-
- *pDuration = duration;
- return EAS_TRUE;
-}
-
-/*----------------------------------------------------------------------------
- * IMY_GetLEDState()
- *----------------------------------------------------------------------------
- * Purpose:
- *
- *
- * Inputs:
- *
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_BOOL IMY_GetLEDState (S_EAS_DATA *pEASData, S_IMELODY_DATA *pData)
-{
- EAS_I8 c;
- EAS_INT i;
-
-#ifdef _DEBUG_IMELODY
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Enter IMY_GetLEDState\n"); */ }
-#endif
-
- for (i = 0; i < 5; i++)
- {
- c = IMY_GetNextChar(pEASData->hwInstData, pData, EAS_FALSE);
- if (!c)
- return EAS_FALSE;
- switch (i)
- {
- case 3:
- if (c == 'n')
- {
-#ifdef _DEBUG_IMELODY
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_GetLEDState: LED on\n"); */ }
-#endif
- EAS_HWLED(pEASData->hwInstData, EAS_TRUE);
- return EAS_TRUE;
- }
- else if (c != 'f')
- return EAS_FALSE;
- break;
-
- case 4:
- if (c == 'f')
- {
-#ifdef _DEBUG_IMELODY
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_GetLEDState: LED off\n"); */ }
-#endif
- EAS_HWLED(pEASData->hwInstData, EAS_FALSE);
- return EAS_TRUE;
- }
- return EAS_FALSE;
-
- default:
- if (c != ledStr[i])
- return EAS_FALSE;
- break;
- }
- }
- return EAS_FALSE;
-}
-
-/*----------------------------------------------------------------------------
- * IMY_GetVibeState()
- *----------------------------------------------------------------------------
- * Purpose:
- *
- *
- * Inputs:
- *
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_BOOL IMY_GetVibeState (S_EAS_DATA *pEASData, S_IMELODY_DATA *pData)
-{
- EAS_I8 c;
- EAS_INT i;
-
-#ifdef _DEBUG_IMELODY
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Enter IMY_GetVibeState\n"); */ }
-#endif
-
- for (i = 0; i < 6; i++)
- {
- c = IMY_GetNextChar(pEASData->hwInstData, pData, EAS_FALSE);
- if (!c)
- return EAS_FALSE;
- switch (i)
- {
- case 4:
- if (c == 'n')
- {
-#ifdef _DEBUG_IMELODY
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_GetVibeState: vibrate on\n"); */ }
-#endif
- EAS_HWVibrate(pEASData->hwInstData, EAS_TRUE);
- return EAS_TRUE;
- }
- else if (c != 'f')
- return EAS_FALSE;
- break;
-
- case 5:
- if (c == 'f')
- {
-#ifdef _DEBUG_IMELODY
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_GetVibeState: vibrate off\n"); */ }
-#endif
- EAS_HWVibrate(pEASData->hwInstData, EAS_FALSE);
- return EAS_TRUE;
- }
- return EAS_FALSE;
-
- default:
- if (c != vibeStr[i])
- return EAS_FALSE;
- break;
- }
- }
- return EAS_FALSE;
-}
-
-/*----------------------------------------------------------------------------
- * IMY_GetBackState()
- *----------------------------------------------------------------------------
- * Purpose:
- *
- *
- * Inputs:
- *
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_BOOL IMY_GetBackState (S_EAS_DATA *pEASData, S_IMELODY_DATA *pData)
-{
- EAS_I8 c;
- EAS_INT i;
-
-#ifdef _DEBUG_IMELODY
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Enter IMY_GetBackState\n"); */ }
-#endif
-
- for (i = 0; i < 5; i++)
- {
- c = IMY_GetNextChar(pEASData->hwInstData, pData, EAS_FALSE);
- if (!c)
- return EAS_FALSE;
- switch (i)
- {
- case 3:
- if (c == 'n')
- {
-#ifdef _DEBUG_IMELODY
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_GetBackState: backlight on\n"); */ }
-#endif
- EAS_HWBackLight(pEASData->hwInstData, EAS_TRUE);
- return EAS_TRUE;
- }
- else if (c != 'f')
- return EAS_FALSE;
- break;
-
- case 4:
- if (c == 'f')
- {
-#ifdef _DEBUG_IMELODY
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_GetBackState: backlight off\n"); */ }
-#endif
- EAS_HWBackLight(pEASData->hwInstData, EAS_FALSE);
- return EAS_TRUE;
- }
- return EAS_FALSE;
-
- default:
- if (c != backStr[i])
- return EAS_FALSE;
- break;
- }
- }
- return EAS_FALSE;
-}
-
-/*----------------------------------------------------------------------------
- * IMY_GetVolume()
- *----------------------------------------------------------------------------
- * Purpose:
- *
- *
- * Inputs:
- *
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_BOOL IMY_GetVolume (EAS_HW_DATA_HANDLE hwInstData, S_IMELODY_DATA *pData, EAS_BOOL inHeader)
-{
- EAS_INT temp;
- EAS_I8 c;
-
-#ifdef _DEBUG_IMELODY
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Enter IMY_GetVolume\n"); */ }
-#endif
-
- c = IMY_GetNextChar(hwInstData, pData, inHeader);
- if (c == '+')
- {
- if (pData->volume < 15)
- pData->volume++;
- return EAS_TRUE;
- }
- else if (c == '-')
- {
- if (pData->volume > 0)
- pData->volume--;
- return EAS_TRUE;
- }
- else if (IsDigit(c))
- temp = c - '0';
- else
- return EAS_FALSE;
-
- c = IMY_GetNextChar(hwInstData, pData, inHeader);
- if (IsDigit(c))
- temp = temp * 10 + c - '0';
- else if (c)
- PutBackChar(pData);
- if ((temp >= 0) && (temp <= 15))
- {
- if (inHeader && (temp == 0))
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Ignoring V0 encountered in header\n"); */ }
- else
- pData->volume = (EAS_U8) temp;
- }
- return EAS_TRUE;
-}
-
-/*----------------------------------------------------------------------------
- * IMY_GetNumber()
- *----------------------------------------------------------------------------
- * Purpose:
- *
- *
- * Inputs:
- *
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_BOOL IMY_GetNumber (EAS_HW_DATA_HANDLE hwInstData, S_IMELODY_DATA *pData, EAS_INT *temp, EAS_BOOL inHeader)
-{
- EAS_BOOL ok;
- EAS_I8 c;
-
-#ifdef _DEBUG_IMELODY
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Enter IMY_GetNumber\n"); */ }
-#endif
-
- *temp = 0;
- ok = EAS_FALSE;
- for (;;)
- {
- c = IMY_GetNextChar(hwInstData, pData, inHeader);
- if (IsDigit(c))
- {
- *temp = *temp * 10 + c - '0';
- ok = EAS_TRUE;
- }
- else
- {
- if (c)
- PutBackChar(pData);
-
-#ifdef _DEBUG_IMELODY
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_GetNumber: value %d\n", *temp); */ }
-#endif
-
- return ok;
- }
- }
-}
-
-/*----------------------------------------------------------------------------
- * IMY_GetVersion()
- *----------------------------------------------------------------------------
- * Purpose:
- *
- *
- * Inputs:
- *
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_BOOL IMY_GetVersion (S_IMELODY_DATA *pData, EAS_INT *pVersion)
-{
- EAS_I8 c;
- EAS_INT temp;
- EAS_INT version;
-
- version = temp = 0;
- for (;;)
- {
- c = pData->buffer[pData->index++];
- if ((c == 0) || (c == '.'))
- {
- /*lint -e{701} use shift for performance */
- version = (version << 8) + temp;
- if (c == 0)
- {
-
-#ifdef _DEBUG_IMELODY
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_GetVersion: version 0x%04x\n", version); */ }
-#endif
-
- *pVersion = version;
- return EAS_TRUE;
- }
- temp = 0;
- }
- else if (IsDigit(c))
- temp = (temp * 10) + c - '0';
- }
-}
-
-/*----------------------------------------------------------------------------
- * IMY_MetaData()
- *----------------------------------------------------------------------------
- * Purpose:
- * Prepare to parse the file. Allocates instance data (or uses static allocation for
- * static memory model).
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static void IMY_MetaData (S_IMELODY_DATA *pData, E_EAS_METADATA_TYPE metaType, EAS_I8 *buffer)
-{
- EAS_I32 len;
-
- /* check for callback */
- if (!pData->metadata.callback)
- return;
-
- /* copy data to host buffer */
- len = (EAS_I32) strlen((char*) buffer);
- if (len >pData->metadata.bufferSize)
- len = pData->metadata.bufferSize;
- strncpy((char*) pData->metadata.buffer, (char*) buffer, (size_t) len);
- pData->metadata.buffer[len] = 0;
-
- /* callback to host */
- pData->metadata.callback(metaType, pData->metadata.buffer, pData->metadata.pUserData);
-}
-
-/*----------------------------------------------------------------------------
- * IMY_ParseHeader()
- *----------------------------------------------------------------------------
- * Purpose:
- * Prepare to parse the file. Allocates instance data (or uses static allocation for
- * static memory model).
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT IMY_ParseHeader (S_EAS_DATA *pEASData, S_IMELODY_DATA* pData)
-{
- EAS_RESULT result;
- EAS_INT token;
- EAS_INT temp;
- EAS_I8 c;
-
-#ifdef _DEBUG_IMELODY
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Enter IMY_ParseHeader\n"); */ }
-#endif
-
- /* initialize some defaults */
- pData->time = 0;
- pData->tick = DEFAULT_TICK_CONV;
- pData->note = 0;
- pData->noteModifier = 0;
- pData ->restTicks = 0;
- pData->volume = 7;
- pData->octave = 60;
- pData->repeatOffset = -1;
- pData->repeatCount = -1;
- pData->style = 0;
-
- /* force the read of the first line */
- pData->index = 1;
-
- /* read data until we get to melody */
- for (;;)
- {
- /* read a line from the file and parse the token */
- if (pData->index != 0)
- {
- if ((result = IMY_ReadLine(pEASData->hwInstData, pData->fileHandle, pData->buffer, &pData->startLine)) != EAS_SUCCESS)
- {
-#ifdef _DEBUG_IMELODY
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_ParseHeader: IMY_ReadLine returned %d\n", result); */ }
-#endif
- return result;
- }
- }
- token = IMY_ParseLine(pData->buffer, &pData->index);
-
- switch (token)
- {
- /* ignore these valid tokens */
- case TOKEN_BEGIN:
- break;
-
- case TOKEN_FORMAT:
- if (!IMY_GetVersion(pData, &temp))
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Invalid FORMAT field '%s'\n", pData->buffer); */ }
- return EAS_ERROR_FILE_FORMAT;
- }
- if ((temp != 0x0100) && (temp != 0x0200))
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Unsupported FORMAT %02x\n", temp); */ }
- return EAS_ERROR_UNRECOGNIZED_FORMAT;
- }
- break;
-
- case TOKEN_VERSION:
- if (!IMY_GetVersion(pData, &temp))
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Invalid VERSION field '%s'\n", pData->buffer); */ }
- return EAS_ERROR_FILE_FORMAT;
- }
- if ((temp != 0x0100) && (temp != 0x0102))
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Unsupported VERSION %02x\n", temp); */ }
- return EAS_ERROR_UNRECOGNIZED_FORMAT;
- }
- break;
-
- case TOKEN_NAME:
- IMY_MetaData(pData, EAS_METADATA_TITLE, pData->buffer + pData->index);
- break;
-
- case TOKEN_COMPOSER:
- IMY_MetaData(pData, EAS_METADATA_AUTHOR, pData->buffer + pData->index);
- break;
-
- /* handle beat */
- case TOKEN_BEAT:
- IMY_GetNumber(pEASData->hwInstData, pData, &temp, EAS_TRUE);
- if ((temp >= 25) && (temp <= 900))
- pData->tick = TICK_CONVERT / temp;
- break;
-
- /* handle style */
- case TOKEN_STYLE:
- c = IMY_GetNextChar(pEASData->hwInstData, pData, EAS_TRUE);
- if (c == 'S')
- c = IMY_GetNextChar(pEASData->hwInstData, pData, EAS_TRUE);
- if ((c >= '0') && (c <= '2'))
- pData->style = (EAS_U8) (c - '0');
- else
- {
- PutBackChar(pData);
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Error in style command: %s\n", pData->buffer); */ }
- }
- break;
-
- /* handle volume */
- case TOKEN_VOLUME:
- c = IMY_GetNextChar(pEASData->hwInstData, pData, EAS_TRUE);
- if (c != 'V')
- {
- PutBackChar(pData);
- if (!IsDigit(c))
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Error in volume command: %s\n", pData->buffer); */ }
- break;
- }
- }
- IMY_GetVolume(pEASData->hwInstData, pData, EAS_TRUE);
- break;
-
- case TOKEN_MELODY:
-#ifdef _DEBUG_IMELODY
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Header successfully parsed\n"); */ }
-#endif
- return EAS_SUCCESS;
-
- case TOKEN_END:
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Unexpected END:IMELODY encountered\n"); */ }
- return EAS_ERROR_FILE_FORMAT;
-
- default:
- /* force a read of the next line */
- pData->index = 1;
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Ignoring unrecognized token in iMelody file: %s\n", pData->buffer); */ }
- break;
- }
- }
-}
-
-/*----------------------------------------------------------------------------
- * IMY_GetNextChar()
- *----------------------------------------------------------------------------
- * Purpose:
- *
- *
- * Inputs:
- *
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_I8 IMY_GetNextChar (EAS_HW_DATA_HANDLE hwInstData, S_IMELODY_DATA *pData, EAS_BOOL inHeader)
-{
- EAS_I8 c;
- EAS_U8 index;
-
- for (;;)
- {
- /* get next character */
- c = pData->buffer[pData->index++];
-
- /* buffer empty, read more */
- if (!c)
- {
- /* don't read the next line in the header */
- if (inHeader)
- return 0;
-
- pData->index = 0;
- pData->buffer[0] = 0;
- if (IMY_ReadLine(hwInstData, pData->fileHandle, pData->buffer, &pData->startLine) != EAS_SUCCESS)
- {
-#ifdef _DEBUG_IMELODY
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_GetNextChar: EOF\n"); */ }
-#endif
- return 0;
- }
-
- /* check for END:IMELODY token */
- if (IMY_ParseLine(pData->buffer, &index) == TOKEN_END)
- {
-#ifdef _DEBUG_IMELODY
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_GetNextChar: found END:IMELODY\n"); */ }
-#endif
- pData->buffer[0] = 0;
- return 0;
- }
- continue;
- }
-
- /* ignore white space */
- if (!IsSpace(c))
- {
-
-#ifdef _DEBUG_IMELODY
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_GetNextChar returned '%c'\n", c); */ }
-#endif
- return c;
- }
- }
-}
-
-/*----------------------------------------------------------------------------
- * IMY_ReadLine()
- *----------------------------------------------------------------------------
- * Purpose:
- * Reads a line of input from the file, discarding the CR/LF
- *
- * Inputs:
- *
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT IMY_ReadLine (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE fileHandle, EAS_I8 *buffer, EAS_I32 *pStartLine)
-{
- EAS_RESULT result;
- EAS_INT i;
- EAS_I8 c;
-
- /* fetch current file position and save it */
- if (pStartLine != NULL)
- {
- if ((result = EAS_HWFilePos(hwInstData, fileHandle, pStartLine)) != EAS_SUCCESS)
- {
-#ifdef _DEBUG_IMELODY
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_ParseHeader: EAS_HWFilePos returned %d\n", result); */ }
-#endif
- return result;
- }
- }
-
- buffer[0] = 0;
- for (i = 0; i < MAX_LINE_SIZE; )
- {
- if ((result = EAS_HWGetByte(hwInstData, fileHandle, &c)) != EAS_SUCCESS)
- {
- if ((result == EAS_EOF) && (i > 0))
- break;
- return result;
- }
-
- /* return on LF or end of data */
- if (c == '\n')
- break;
-
- /* store characters in buffer */
- if (c != '\r')
- buffer[i++] = c;
- }
- buffer[i] = 0;
-
-#ifdef _DEBUG_IMELODY
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_ReadLine read %s\n", buffer); */ }
-#endif
-
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * IMY_ParseLine()
- *----------------------------------------------------------------------------
- * Purpose:
- *
- *
- * Inputs:
- *
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_INT IMY_ParseLine (EAS_I8 *buffer, EAS_U8 *pIndex)
-{
- EAS_INT i;
- EAS_INT j;
-
- /* there's no strnicmp() in stdlib, so we have to roll our own */
- for (i = 0; i < TOKEN_INVALID; i++)
- {
- for (j = 0; ; j++)
- {
- /* end of token, must be a match */
- if (tokens[i][j] == 0)
- {
-#ifdef _DEBUG_IMELODY
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_ParseLine found token %d\n", i); */ }
-#endif
- *pIndex = (EAS_U8) j;
- return i;
- }
- if (tokens[i][j] != ToUpper(buffer[j]))
- break;
- }
- }
-#ifdef _DEBUG_IMELODY
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_ParseLine: no token found\n"); */ }
-#endif
- return TOKEN_INVALID;
-}
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 797 $
+ * $Date: 2007-08-01 00:15:56 -0700 (Wed, 01 Aug 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+/* lint doesn't like the way some string.h files look */
+#ifdef _lint
+#include "lint_stdlib.h"
+#else
+#include <string.h>
+#endif
+
+#include "eas_data.h"
+#include "eas_miditypes.h"
+#include "eas_parser.h"
+#include "eas_report.h"
+#include "eas_host.h"
+#include "eas_midi.h"
+#include "eas_config.h"
+#include "eas_vm_protos.h"
+#include "eas_imelodydata.h"
+#include "eas_ctype.h"
+
+// #define _DEBUG_IMELODY
+
+/* increase gain for mono ringtones */
+#define IMELODY_GAIN_OFFSET 8
+
+/* length of 32nd note in 1/256ths of a msec for 120 BPM tempo */
+#define DEFAULT_TICK_CONV 16000
+#define TICK_CONVERT 1920000
+
+/* default channel and program for iMelody playback */
+#define IMELODY_CHANNEL 0
+#define IMELODY_PROGRAM 80
+#define IMELODY_VEL_MUL 4
+#define IMELODY_VEL_OFS 67
+
+/* multiplier for fixed point triplet conversion */
+#define TRIPLET_MULTIPLIER 683
+#define TRIPLET_SHIFT 10
+
+static const char* const tokens[] =
+{
+ "BEGIN:IMELODY",
+ "VERSION:",
+ "FORMAT:CLASS",
+ "NAME:",
+ "COMPOSER:",
+ "BEAT:",
+ "STYLE:",
+ "VOLUME:",
+ "MELODY:",
+ "END:IMELODY"
+};
+
+/* ledon or ledoff */
+static const char ledStr[] = "edo";
+
+/* vibeon or vibeoff */
+static const char vibeStr[] = "ibeo";
+
+/* backon or backoff */
+static const char backStr[] = "cko";
+
+typedef enum
+{
+ TOKEN_BEGIN,
+ TOKEN_VERSION,
+ TOKEN_FORMAT,
+ TOKEN_NAME,
+ TOKEN_COMPOSER,
+ TOKEN_BEAT,
+ TOKEN_STYLE,
+ TOKEN_VOLUME,
+ TOKEN_MELODY,
+ TOKEN_END,
+ TOKEN_INVALID
+} ENUM_IMELODY_TOKENS;
+
+/* lookup table for note values */
+static const EAS_I8 noteTable[] = { 9, 11, 0, 2, 4, 5, 7 };
+
+/* inline functions */
+#ifdef _DEBUG_IMELODY
+static void PutBackChar (S_IMELODY_DATA *pData)
+{
+ if (pData->index)
+ pData->index--;
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "PutBackChar '%c'\n", pData->buffer[pData->index]); */ }
+}
+#else
+EAS_INLINE void PutBackChar (S_IMELODY_DATA *pData) { if (pData->index) pData->index--; }
+#endif
+
+
+/* local prototypes */
+static EAS_RESULT IMY_CheckFileType (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle, EAS_VOID_PTR *ppHandle, EAS_I32 offset);
+static EAS_RESULT IMY_Prepare (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
+static EAS_RESULT IMY_Time (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_U32 *pTime);
+static EAS_RESULT IMY_Event (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_INT parserMode);
+static EAS_RESULT IMY_State (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_STATE *pState);
+static EAS_RESULT IMY_Close (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
+static EAS_RESULT IMY_Reset (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
+static EAS_RESULT IMY_Pause (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
+static EAS_RESULT IMY_Resume (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
+static EAS_RESULT IMY_SetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value);
+static EAS_RESULT IMY_GetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue);
+static EAS_BOOL IMY_PlayNote (S_EAS_DATA *pEASData, S_IMELODY_DATA *pData, EAS_I8 note, EAS_INT parserMode);
+static EAS_BOOL IMY_PlayRest (S_EAS_DATA *pEASData, S_IMELODY_DATA *pData);
+static EAS_BOOL IMY_GetDuration (EAS_HW_DATA_HANDLE hwInstData, S_IMELODY_DATA *pData, EAS_I32 *pDuration);
+static EAS_BOOL IMY_GetLEDState (S_EAS_DATA *pEASData, S_IMELODY_DATA *pData);
+static EAS_BOOL IMY_GetVibeState (S_EAS_DATA *pEASData, S_IMELODY_DATA *pData);
+static EAS_BOOL IMY_GetBackState (S_EAS_DATA *pEASData, S_IMELODY_DATA *pData);
+static EAS_BOOL IMY_GetVolume (EAS_HW_DATA_HANDLE hwInstData, S_IMELODY_DATA *pData, EAS_BOOL inHeader);
+static EAS_BOOL IMY_GetNumber (EAS_HW_DATA_HANDLE hwInstData, S_IMELODY_DATA *pData, EAS_INT *temp, EAS_BOOL inHeader);
+static EAS_RESULT IMY_ParseHeader (S_EAS_DATA *pEASData, S_IMELODY_DATA* pData);
+static EAS_I8 IMY_GetNextChar (EAS_HW_DATA_HANDLE hwInstData, S_IMELODY_DATA *pData, EAS_BOOL inHeader);
+static EAS_RESULT IMY_ReadLine (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE fileHandle, EAS_I8 *buffer, EAS_I32 *pStartLine);
+static EAS_INT IMY_ParseLine (EAS_I8 *buffer, EAS_U8 *pIndex);
+
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_iMelody_Parser
+ *
+ * This structure contains the functional interface for the iMelody parser
+ *----------------------------------------------------------------------------
+*/
+const S_FILE_PARSER_INTERFACE EAS_iMelody_Parser =
+{
+ IMY_CheckFileType,
+ IMY_Prepare,
+ IMY_Time,
+ IMY_Event,
+ IMY_State,
+ IMY_Close,
+ IMY_Reset,
+ IMY_Pause,
+ IMY_Resume,
+ NULL,
+ IMY_SetData,
+ IMY_GetData,
+ NULL
+};
+
+/*----------------------------------------------------------------------------
+ * IMY_CheckFileType()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Check the file type to see if we can parse it
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT IMY_CheckFileType (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle, EAS_VOID_PTR *ppHandle, EAS_I32 offset)
+{
+ S_IMELODY_DATA* pData;
+ EAS_I8 buffer[MAX_LINE_SIZE+1];
+ EAS_U8 index;
+
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Enter IMY_CheckFileType\n"); */ }
+#endif
+
+ /* read the first line of the file */
+ *ppHandle = NULL;
+ if (IMY_ReadLine(pEASData->hwInstData, fileHandle, buffer, NULL) != EAS_SUCCESS)
+ return EAS_SUCCESS;
+
+ /* check for header string */
+ if (IMY_ParseLine(buffer, &index) == TOKEN_BEGIN)
+ {
+
+ /* check for static memory allocation */
+ if (pEASData->staticMemoryModel)
+ pData = EAS_CMEnumData(EAS_CM_IMELODY_DATA);
+ else
+ pData = EAS_HWMalloc(pEASData->hwInstData, sizeof(S_IMELODY_DATA));
+ if (!pData)
+ return EAS_ERROR_MALLOC_FAILED;
+ EAS_HWMemSet(pData, 0, sizeof(S_IMELODY_DATA));
+
+ /* initialize */
+ pData->fileHandle = fileHandle;
+ pData->fileOffset = offset;
+ pData->state = EAS_STATE_ERROR;
+ pData->state = EAS_STATE_OPEN;
+
+ /* return a pointer to the instance data */
+ *ppHandle = pData;
+ }
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * IMY_Prepare()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Prepare to parse the file. Allocates instance data (or uses static allocation for
+ * static memory model).
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT IMY_Prepare (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
+{
+ S_IMELODY_DATA* pData;
+ EAS_RESULT result;
+
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Enter IMY_Prepare\n"); */ }
+#endif
+
+ /* check for valid state */
+ pData = (S_IMELODY_DATA*) pInstData;
+ if (pData->state != EAS_STATE_OPEN)
+ return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
+
+ /* instantiate a synthesizer */
+ if ((result = VMInitMIDI(pEASData, &pData->pSynth)) != EAS_SUCCESS)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "VMInitMIDI returned %d\n", result); */ }
+ return result;
+ }
+
+ /* parse the header */
+ if ((result = IMY_ParseHeader(pEASData, pData)) != EAS_SUCCESS)
+ return result;
+
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_Prepare: state set to EAS_STATE_READY\n"); */ }
+#endif
+
+ pData ->state = EAS_STATE_READY;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * IMY_Time()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Returns the time of the next event in msecs
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ * pTime - pointer to variable to hold time of next event (in msecs)
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pEASData) common decoder interface - pEASData not used */
+static EAS_RESULT IMY_Time (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_U32 *pTime)
+{
+ S_IMELODY_DATA *pData;
+
+ pData = (S_IMELODY_DATA*) pInstData;
+
+ /* return time in milliseconds */
+ /*lint -e{704} use shift instead of division */
+ *pTime = pData->time >> 8;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * IMY_Event()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Parse the next event in the file
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT IMY_Event (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_INT parserMode)
+{
+ S_IMELODY_DATA* pData;
+ EAS_RESULT result;
+ EAS_I8 c;
+ EAS_BOOL eof;
+ EAS_INT temp;
+
+ pData = (S_IMELODY_DATA*) pInstData;
+ if (pData->state >= EAS_STATE_OPEN)
+ return EAS_SUCCESS;
+
+ if (pData->state == EAS_STATE_READY) {
+ pData->state = EAS_STATE_PLAY;
+ }
+
+ /* initialize MIDI channel when the track starts playing */
+ if (pData->time == 0)
+ {
+
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_Event: Reset\n"); */ }
+#endif
+ /* set program to square lead */
+ VMProgramChange(pEASData->pVoiceMgr, pData->pSynth, IMELODY_CHANNEL, IMELODY_PROGRAM);
+
+ /* set channel volume to max */
+ VMControlChange(pEASData->pVoiceMgr, pData->pSynth, IMELODY_CHANNEL, 7, 127);
+ }
+
+ /* check for end of note */
+ if (pData->note)
+ {
+
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Stopping note %d\n", pData->note); */ }
+#endif
+ /* stop the note */
+ VMStopNote(pEASData->pVoiceMgr, pData->pSynth, IMELODY_CHANNEL, pData->note, 0);
+ pData->note = 0;
+
+ /* check for rest between notes */
+ if (pData->restTicks)
+ {
+ pData->time += pData->restTicks;
+ pData->restTicks = 0;
+ return EAS_SUCCESS;
+ }
+ }
+
+ /* parse the next event */
+ eof = EAS_FALSE;
+ while (!eof)
+ {
+
+ /* get next character */
+ c = IMY_GetNextChar(pEASData->hwInstData, pData, EAS_FALSE);
+
+ switch (c)
+ {
+ /* start repeat */
+ case '(':
+
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Enter repeat section\n", c); */ }
+#endif
+
+ if (pData->repeatOffset < 0)
+ {
+ pData->repeatOffset = pData->startLine + (EAS_I32) pData->index;
+
+ /* save current time and check it later to make sure the loop isn't zero length */
+ pData->repeatTime = pData->time;
+
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Repeat offset = %d\n", pData->repeatOffset); */ }
+#endif
+ }
+ else
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Ignoring nested repeat section\n"); */ }
+ break;
+
+ /* end repeat */
+ case ')':
+
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "End repeat section, repeat offset = %d\n", pData->repeatOffset); */ }
+#endif
+ /* ignore zero-length loops */
+ if (pData->repeatTime == pData->time) {
+ pData->repeatCount = -1;
+ pData->repeatOffset = -1;
+ } else if (pData->repeatCount >= 0) {
+
+ /* decrement repeat count (repeatCount == 0 means infinite loop) */
+ if (pData->repeatCount > 0)
+ {
+ if (--pData->repeatCount == 0)
+ {
+ pData->repeatCount = -1;
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Repeat loop complete\n"); */ }
+#endif
+ }
+ }
+
+//2 TEMPORARY FIX: If locating, don't do infinite loops.
+//3 We need a different mode for metadata parsing where we don't loop at all
+ if ((parserMode == eParserModePlay) || (pData->repeatCount != 0))
+ {
+
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Rewinding file for repeat\n"); */ }
+#endif
+ /* rewind to start of loop */
+ if ((result = EAS_HWFileSeek(pEASData->hwInstData, pData->fileHandle, pData->repeatOffset)) != EAS_SUCCESS)
+ return result;
+ IMY_ReadLine(pEASData->hwInstData, pData->fileHandle, pData->buffer, &pData->startLine);
+ pData->index = 0;
+
+ /* if last loop, prevent future loops */
+ if (pData->repeatCount == -1)
+ pData->repeatOffset = -1;
+ }
+ }
+ break;
+
+ /* repeat count */
+ case '@':
+ if (!IMY_GetNumber(pEASData->hwInstData, pData, &temp, EAS_FALSE))
+ eof = EAS_TRUE;
+ else if (pData->repeatOffset > 0)
+ {
+
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Repeat count = %dt", pData->repeatCount); */ }
+#endif
+ if (pData->repeatCount < 0)
+ pData->repeatCount = (EAS_I16) temp;
+ }
+ break;
+
+ /* volume */
+ case 'V':
+ if (!IMY_GetVolume(pEASData->hwInstData, pData, EAS_FALSE))
+ eof = EAS_TRUE;
+ break;
+
+ /* flat */
+ case '&':
+ pData->noteModifier = -1;
+ break;
+
+ /* sharp */
+ case '#':
+ pData->noteModifier = +1;
+ break;
+
+ /* octave */
+ case '*':
+ c = IMY_GetNextChar(pEASData->hwInstData, pData, EAS_FALSE);
+ if (IsDigit(c))
+ pData->octave = (EAS_U8) ((c - '0' + 1) * 12);
+ else if (!c)
+ eof = EAS_TRUE;
+ break;
+
+ /* ledon or ledoff */
+ case 'l':
+ if (!IMY_GetLEDState(pEASData, pData))
+ eof = EAS_TRUE;
+ break;
+
+ /* vibeon or vibeoff */
+ case 'v':
+ if (!IMY_GetVibeState(pEASData, pData))
+ eof = EAS_TRUE;
+ break;
+
+ /* either a B note or backon or backoff */
+ case 'b':
+ if (IMY_GetNextChar(pEASData->hwInstData, pData, EAS_FALSE) == 'a')
+ {
+ if (!IMY_GetBackState(pEASData, pData))
+ eof = EAS_TRUE;
+ }
+ else
+ {
+ PutBackChar(pData);
+ if (IMY_PlayNote(pEASData, pData, c, parserMode))
+ return EAS_SUCCESS;
+ eof = EAS_TRUE;
+ }
+ break;
+
+ /* rest */
+ case 'r':
+ case 'R':
+ if (IMY_PlayRest(pEASData, pData))
+ return EAS_SUCCESS;
+ eof = EAS_TRUE;
+ break;
+
+ /* EOF */
+ case 0:
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_Event: end of iMelody file detected\n"); */ }
+#endif
+ eof = EAS_TRUE;
+ break;
+
+ /* must be a note */
+ default:
+ c = ToLower(c);
+ if ((c >= 'a') && (c <= 'g'))
+ {
+ if (IMY_PlayNote(pEASData, pData, c, parserMode))
+ return EAS_SUCCESS;
+ eof = EAS_TRUE;
+ }
+ else
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Ignoring unexpected character '%c' [0x%02x]\n", c, c); */ }
+ break;
+ }
+ }
+
+ /* handle EOF */
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_Event: state set to EAS_STATE_STOPPING\n"); */ }
+#endif
+ pData->state = EAS_STATE_STOPPING;
+ VMReleaseAllVoices(pEASData->pVoiceMgr, pData->pSynth);
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * IMY_State()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Returns the current state of the stream
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ * pState - pointer to variable to store state
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pEASData) common decoder interface - pEASData not used */
+static EAS_RESULT IMY_State (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 *pState)
+{
+ S_IMELODY_DATA* pData;
+
+ /* establish pointer to instance data */
+ pData = (S_IMELODY_DATA*) pInstData;
+
+ /* if stopping, check to see if synth voices are active */
+ if (pData->state == EAS_STATE_STOPPING)
+ {
+ if (VMActiveVoices(pData->pSynth) == 0)
+ {
+ pData->state = EAS_STATE_STOPPED;
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_State: state set to EAS_STATE_STOPPED\n"); */ }
+#endif
+ }
+ }
+
+ if (pData->state == EAS_STATE_PAUSING)
+ {
+ if (VMActiveVoices(pData->pSynth) == 0)
+ {
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_State: state set to EAS_STATE_PAUSED\n"); */ }
+#endif
+ pData->state = EAS_STATE_PAUSED;
+ }
+ }
+
+ /* return current state */
+ *pState = pData->state;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * IMY_Close()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Close the file and clean up
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT IMY_Close (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
+{
+ S_IMELODY_DATA* pData;
+ EAS_RESULT result;
+
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_Close: close file\n"); */ }
+#endif
+
+ pData = (S_IMELODY_DATA*) pInstData;
+
+ /* close the file */
+ if ((result = EAS_HWCloseFile(pEASData->hwInstData, pData->fileHandle)) != EAS_SUCCESS)
+ return result;
+
+ /* free the synth */
+ if (pData->pSynth != NULL)
+ VMMIDIShutdown(pEASData, pData->pSynth);
+
+ /* if using dynamic memory, free it */
+ if (!pEASData->staticMemoryModel)
+ EAS_HWFree(pEASData->hwInstData, pData);
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * IMY_Reset()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Reset the sequencer. Used for locating backwards in the file.
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT IMY_Reset (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
+{
+ S_IMELODY_DATA* pData;
+ EAS_RESULT result;
+
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_Reset: reset file\n"); */ }
+#endif
+ pData = (S_IMELODY_DATA*) pInstData;
+
+ /* reset the synth */
+ VMReset(pEASData->pVoiceMgr, pData->pSynth, EAS_TRUE);
+
+ /* reset time to zero */
+ pData->time = 0;
+ pData->note = 0;
+
+ /* reset file position and re-parse header */
+ pData->state = EAS_STATE_ERROR;
+ if ((result = EAS_HWFileSeek(pEASData->hwInstData, pData->fileHandle, pData->fileOffset)) != EAS_SUCCESS)
+ return result;
+ if ((result = IMY_ParseHeader (pEASData, pData)) != EAS_SUCCESS)
+ return result;
+
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_Reset: state set to EAS_STATE_ERROR\n"); */ }
+#endif
+
+ pData->state = EAS_STATE_READY;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * IMY_Pause()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Pauses the sequencer. Mutes all voices and sets state to pause.
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT IMY_Pause (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
+{
+ S_IMELODY_DATA *pData;
+
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_Pause: pause file\n"); */ }
+#endif
+
+ /* can't pause a stopped stream */
+ pData = (S_IMELODY_DATA*) pInstData;
+ if (pData->state == EAS_STATE_STOPPED)
+ return EAS_ERROR_ALREADY_STOPPED;
+
+ /* mute the synthesizer */
+ VMMuteAllVoices(pEASData->pVoiceMgr, pData->pSynth);
+ pData->state = EAS_STATE_PAUSING;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * IMY_Resume()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Resume playing after a pause, sets state back to playing.
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pEASData) common decoder interface - pEASData not used */
+static EAS_RESULT IMY_Resume (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
+{
+ S_IMELODY_DATA *pData;
+
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_Resume: resume file\n"); */ }
+#endif
+
+ /* can't resume a stopped stream */
+ pData = (S_IMELODY_DATA*) pInstData;
+ if (pData->state == EAS_STATE_STOPPED)
+ return EAS_ERROR_ALREADY_STOPPED;
+
+ /* nothing to do but resume playback */
+ pData->state = EAS_STATE_PLAY;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * IMY_SetData()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Adjust tempo relative to song tempo
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * pInstData - pointer to iMelody instance data
+ * rate - rate (28-bit fractional amount)
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pEASData) common decoder interface - pEASData not used */
+static EAS_RESULT IMY_SetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value)
+{
+ S_IMELODY_DATA *pData;
+
+ pData = (S_IMELODY_DATA*) pInstData;
+ switch (param)
+ {
+
+ /* set metadata callback */
+ case PARSER_DATA_METADATA_CB:
+ EAS_HWMemCpy(&pData->metadata, (void*) value, sizeof(S_METADATA_CB));
+ break;
+
+ default:
+ return EAS_ERROR_INVALID_PARAMETER;
+ }
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * IMY_GetData()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Return the file type
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * pInstData - pointer to iMelody instance data
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pEASData) common decoder interface - pEASData not used */
+static EAS_RESULT IMY_GetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue)
+{
+ S_IMELODY_DATA *pData;
+
+ pData = (S_IMELODY_DATA*) pInstData;
+
+ switch (param)
+ {
+ /* return file type as iMelody */
+ case PARSER_DATA_FILE_TYPE:
+ *pValue = EAS_FILE_IMELODY;
+ break;
+
+ case PARSER_DATA_SYNTH_HANDLE:
+ *pValue = (EAS_I32) pData->pSynth;
+ break;
+
+ case PARSER_DATA_GAIN_OFFSET:
+ *pValue = IMELODY_GAIN_OFFSET;
+ break;
+
+ default:
+ return EAS_ERROR_INVALID_PARAMETER;
+ }
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * IMY_PlayNote()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ *
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_BOOL IMY_PlayNote (S_EAS_DATA *pEASData, S_IMELODY_DATA *pData, EAS_I8 note, EAS_INT parserMode)
+{
+ EAS_I32 duration;
+ EAS_U8 velocity;
+
+
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_PlayNote: start note %d\n", note); */ }
+#endif
+
+ /* get the duration */
+ if (!IMY_GetDuration(pEASData->hwInstData, pData, &duration))
+ return EAS_FALSE;
+
+ /* save note value */
+ pData->note = (EAS_U8) (pData->octave + noteTable[note - 'a'] + pData->noteModifier);
+ velocity = (EAS_U8) (pData->volume ? pData->volume * IMELODY_VEL_MUL + IMELODY_VEL_OFS : 0);
+
+ /* start note only if in play mode */
+ if (parserMode == eParserModePlay)
+ VMStartNote(pEASData->pVoiceMgr, pData->pSynth, IMELODY_CHANNEL, pData->note, velocity);
+
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_PlayNote: Start note %d, duration %d\n", pData->note, duration); */ }
+#endif
+
+ /* determine note length */
+ switch (pData->style)
+ {
+ case 0:
+ /*lint -e{704} shift for performance */
+ pData->restTicks = duration >> 4;
+ break;
+ case 1:
+ pData->restTicks = 0;
+ break;
+ case 2:
+ /*lint -e{704} shift for performance */
+ pData->restTicks = duration >> 1;
+ break;
+ default:
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "IMY_PlayNote: Note style out of range: %d\n", pData->style); */ }
+ /*lint -e{704} shift for performance */
+ pData->restTicks = duration >> 4;
+ break;
+ }
+
+ /* next event is at end of this note */
+ pData->time += duration - pData->restTicks;
+
+ /* reset the flat/sharp modifier */
+ pData->noteModifier = 0;
+
+ return EAS_TRUE;
+}
+
+/*----------------------------------------------------------------------------
+ * IMY_PlayRest()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ *
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_BOOL IMY_PlayRest (S_EAS_DATA *pEASData, S_IMELODY_DATA *pData)
+{
+ EAS_I32 duration;
+
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Enter IMY_PlayRest]n"); */ }
+#endif
+
+ /* get the duration */
+ if (!IMY_GetDuration(pEASData->hwInstData, pData, &duration))
+ return EAS_FALSE;
+
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_PlayRest: note duration %d\n", duration); */ }
+#endif
+
+ /* next event is at end of this note */
+ pData->time += duration;
+ return EAS_TRUE;
+}
+
+/*----------------------------------------------------------------------------
+ * IMY_GetDuration()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ *
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+
+static EAS_BOOL IMY_GetDuration (EAS_HW_DATA_HANDLE hwInstData, S_IMELODY_DATA *pData, EAS_I32 *pDuration)
+{
+ EAS_I32 duration;
+ EAS_I8 c;
+
+ /* get the duration */
+ *pDuration = 0;
+ c = IMY_GetNextChar(hwInstData, pData, EAS_FALSE);
+ if (!c)
+ return EAS_FALSE;
+ if ((c < '0') || (c > '5'))
+ {
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_GetDuration: error in duration '%c'\n", c); */ }
+#endif
+ return EAS_FALSE;
+ }
+
+ /* calculate total length of note */
+ duration = pData->tick * (1 << ('5' - c));
+
+ /* check for duration modifier */
+ c = IMY_GetNextChar(hwInstData, pData, EAS_FALSE);
+ if (c)
+ {
+ if (c == '.')
+ /*lint -e{704} shift for performance */
+ duration += duration >> 1;
+ else if (c == ':')
+ /*lint -e{704} shift for performance */
+ duration += (duration >> 1) + (duration >> 2);
+ else if (c == ';')
+ /*lint -e{704} shift for performance */
+ duration = (duration * TRIPLET_MULTIPLIER) >> TRIPLET_SHIFT;
+ else
+ PutBackChar(pData);
+ }
+
+ *pDuration = duration;
+ return EAS_TRUE;
+}
+
+/*----------------------------------------------------------------------------
+ * IMY_GetLEDState()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ *
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_BOOL IMY_GetLEDState (S_EAS_DATA *pEASData, S_IMELODY_DATA *pData)
+{
+ EAS_I8 c;
+ EAS_INT i;
+
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Enter IMY_GetLEDState\n"); */ }
+#endif
+
+ for (i = 0; i < 5; i++)
+ {
+ c = IMY_GetNextChar(pEASData->hwInstData, pData, EAS_FALSE);
+ if (!c)
+ return EAS_FALSE;
+ switch (i)
+ {
+ case 3:
+ if (c == 'n')
+ {
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_GetLEDState: LED on\n"); */ }
+#endif
+ EAS_HWLED(pEASData->hwInstData, EAS_TRUE);
+ return EAS_TRUE;
+ }
+ else if (c != 'f')
+ return EAS_FALSE;
+ break;
+
+ case 4:
+ if (c == 'f')
+ {
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_GetLEDState: LED off\n"); */ }
+#endif
+ EAS_HWLED(pEASData->hwInstData, EAS_FALSE);
+ return EAS_TRUE;
+ }
+ return EAS_FALSE;
+
+ default:
+ if (c != ledStr[i])
+ return EAS_FALSE;
+ break;
+ }
+ }
+ return EAS_FALSE;
+}
+
+/*----------------------------------------------------------------------------
+ * IMY_GetVibeState()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ *
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_BOOL IMY_GetVibeState (S_EAS_DATA *pEASData, S_IMELODY_DATA *pData)
+{
+ EAS_I8 c;
+ EAS_INT i;
+
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Enter IMY_GetVibeState\n"); */ }
+#endif
+
+ for (i = 0; i < 6; i++)
+ {
+ c = IMY_GetNextChar(pEASData->hwInstData, pData, EAS_FALSE);
+ if (!c)
+ return EAS_FALSE;
+ switch (i)
+ {
+ case 4:
+ if (c == 'n')
+ {
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_GetVibeState: vibrate on\n"); */ }
+#endif
+ EAS_HWVibrate(pEASData->hwInstData, EAS_TRUE);
+ return EAS_TRUE;
+ }
+ else if (c != 'f')
+ return EAS_FALSE;
+ break;
+
+ case 5:
+ if (c == 'f')
+ {
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_GetVibeState: vibrate off\n"); */ }
+#endif
+ EAS_HWVibrate(pEASData->hwInstData, EAS_FALSE);
+ return EAS_TRUE;
+ }
+ return EAS_FALSE;
+
+ default:
+ if (c != vibeStr[i])
+ return EAS_FALSE;
+ break;
+ }
+ }
+ return EAS_FALSE;
+}
+
+/*----------------------------------------------------------------------------
+ * IMY_GetBackState()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ *
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_BOOL IMY_GetBackState (S_EAS_DATA *pEASData, S_IMELODY_DATA *pData)
+{
+ EAS_I8 c;
+ EAS_INT i;
+
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Enter IMY_GetBackState\n"); */ }
+#endif
+
+ for (i = 0; i < 5; i++)
+ {
+ c = IMY_GetNextChar(pEASData->hwInstData, pData, EAS_FALSE);
+ if (!c)
+ return EAS_FALSE;
+ switch (i)
+ {
+ case 3:
+ if (c == 'n')
+ {
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_GetBackState: backlight on\n"); */ }
+#endif
+ EAS_HWBackLight(pEASData->hwInstData, EAS_TRUE);
+ return EAS_TRUE;
+ }
+ else if (c != 'f')
+ return EAS_FALSE;
+ break;
+
+ case 4:
+ if (c == 'f')
+ {
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_GetBackState: backlight off\n"); */ }
+#endif
+ EAS_HWBackLight(pEASData->hwInstData, EAS_FALSE);
+ return EAS_TRUE;
+ }
+ return EAS_FALSE;
+
+ default:
+ if (c != backStr[i])
+ return EAS_FALSE;
+ break;
+ }
+ }
+ return EAS_FALSE;
+}
+
+/*----------------------------------------------------------------------------
+ * IMY_GetVolume()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ *
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_BOOL IMY_GetVolume (EAS_HW_DATA_HANDLE hwInstData, S_IMELODY_DATA *pData, EAS_BOOL inHeader)
+{
+ EAS_INT temp;
+ EAS_I8 c;
+
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Enter IMY_GetVolume\n"); */ }
+#endif
+
+ c = IMY_GetNextChar(hwInstData, pData, inHeader);
+ if (c == '+')
+ {
+ if (pData->volume < 15)
+ pData->volume++;
+ return EAS_TRUE;
+ }
+ else if (c == '-')
+ {
+ if (pData->volume > 0)
+ pData->volume--;
+ return EAS_TRUE;
+ }
+ else if (IsDigit(c))
+ temp = c - '0';
+ else
+ return EAS_FALSE;
+
+ c = IMY_GetNextChar(hwInstData, pData, inHeader);
+ if (IsDigit(c))
+ temp = temp * 10 + c - '0';
+ else if (c)
+ PutBackChar(pData);
+ if ((temp >= 0) && (temp <= 15))
+ {
+ if (inHeader && (temp == 0))
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Ignoring V0 encountered in header\n"); */ }
+ else
+ pData->volume = (EAS_U8) temp;
+ }
+ return EAS_TRUE;
+}
+
+/*----------------------------------------------------------------------------
+ * IMY_GetNumber()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ *
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_BOOL IMY_GetNumber (EAS_HW_DATA_HANDLE hwInstData, S_IMELODY_DATA *pData, EAS_INT *temp, EAS_BOOL inHeader)
+{
+ EAS_BOOL ok;
+ EAS_I8 c;
+
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Enter IMY_GetNumber\n"); */ }
+#endif
+
+ *temp = 0;
+ ok = EAS_FALSE;
+ for (;;)
+ {
+ c = IMY_GetNextChar(hwInstData, pData, inHeader);
+ if (IsDigit(c))
+ {
+ *temp = *temp * 10 + c - '0';
+ ok = EAS_TRUE;
+ }
+ else
+ {
+ if (c)
+ PutBackChar(pData);
+
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_GetNumber: value %d\n", *temp); */ }
+#endif
+
+ return ok;
+ }
+ }
+}
+
+/*----------------------------------------------------------------------------
+ * IMY_GetVersion()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ *
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_BOOL IMY_GetVersion (S_IMELODY_DATA *pData, EAS_INT *pVersion)
+{
+ EAS_I8 c;
+ EAS_INT temp;
+ EAS_INT version;
+
+ version = temp = 0;
+ for (;;)
+ {
+ c = pData->buffer[pData->index++];
+ if ((c == 0) || (c == '.'))
+ {
+ /*lint -e{701} use shift for performance */
+ version = (version << 8) + temp;
+ if (c == 0)
+ {
+
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_GetVersion: version 0x%04x\n", version); */ }
+#endif
+
+ *pVersion = version;
+ return EAS_TRUE;
+ }
+ temp = 0;
+ }
+ else if (IsDigit(c))
+ temp = (temp * 10) + c - '0';
+ }
+}
+
+/*----------------------------------------------------------------------------
+ * IMY_MetaData()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Prepare to parse the file. Allocates instance data (or uses static allocation for
+ * static memory model).
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static void IMY_MetaData (S_IMELODY_DATA *pData, E_EAS_METADATA_TYPE metaType, EAS_I8 *buffer)
+{
+ EAS_I32 len;
+
+ /* check for callback */
+ if (!pData->metadata.callback)
+ return;
+
+ /* copy data to host buffer */
+ len = (EAS_I32) strlen((char*) buffer);
+ if (len >pData->metadata.bufferSize)
+ len = pData->metadata.bufferSize;
+ strncpy((char*) pData->metadata.buffer, (char*) buffer, (size_t) len);
+ pData->metadata.buffer[len] = 0;
+
+ /* callback to host */
+ pData->metadata.callback(metaType, pData->metadata.buffer, pData->metadata.pUserData);
+}
+
+/*----------------------------------------------------------------------------
+ * IMY_ParseHeader()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Prepare to parse the file. Allocates instance data (or uses static allocation for
+ * static memory model).
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT IMY_ParseHeader (S_EAS_DATA *pEASData, S_IMELODY_DATA* pData)
+{
+ EAS_RESULT result;
+ EAS_INT token;
+ EAS_INT temp;
+ EAS_I8 c;
+
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Enter IMY_ParseHeader\n"); */ }
+#endif
+
+ /* initialize some defaults */
+ pData->time = 0;
+ pData->tick = DEFAULT_TICK_CONV;
+ pData->note = 0;
+ pData->noteModifier = 0;
+ pData ->restTicks = 0;
+ pData->volume = 7;
+ pData->octave = 60;
+ pData->repeatOffset = -1;
+ pData->repeatCount = -1;
+ pData->style = 0;
+
+ /* force the read of the first line */
+ pData->index = 1;
+
+ /* read data until we get to melody */
+ for (;;)
+ {
+ /* read a line from the file and parse the token */
+ if (pData->index != 0)
+ {
+ if ((result = IMY_ReadLine(pEASData->hwInstData, pData->fileHandle, pData->buffer, &pData->startLine)) != EAS_SUCCESS)
+ {
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_ParseHeader: IMY_ReadLine returned %d\n", result); */ }
+#endif
+ return result;
+ }
+ }
+ token = IMY_ParseLine(pData->buffer, &pData->index);
+
+ switch (token)
+ {
+ /* ignore these valid tokens */
+ case TOKEN_BEGIN:
+ break;
+
+ case TOKEN_FORMAT:
+ if (!IMY_GetVersion(pData, &temp))
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Invalid FORMAT field '%s'\n", pData->buffer); */ }
+ return EAS_ERROR_FILE_FORMAT;
+ }
+ if ((temp != 0x0100) && (temp != 0x0200))
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Unsupported FORMAT %02x\n", temp); */ }
+ return EAS_ERROR_UNRECOGNIZED_FORMAT;
+ }
+ break;
+
+ case TOKEN_VERSION:
+ if (!IMY_GetVersion(pData, &temp))
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Invalid VERSION field '%s'\n", pData->buffer); */ }
+ return EAS_ERROR_FILE_FORMAT;
+ }
+ if ((temp != 0x0100) && (temp != 0x0102))
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Unsupported VERSION %02x\n", temp); */ }
+ return EAS_ERROR_UNRECOGNIZED_FORMAT;
+ }
+ break;
+
+ case TOKEN_NAME:
+ IMY_MetaData(pData, EAS_METADATA_TITLE, pData->buffer + pData->index);
+ break;
+
+ case TOKEN_COMPOSER:
+ IMY_MetaData(pData, EAS_METADATA_AUTHOR, pData->buffer + pData->index);
+ break;
+
+ /* handle beat */
+ case TOKEN_BEAT:
+ IMY_GetNumber(pEASData->hwInstData, pData, &temp, EAS_TRUE);
+ if ((temp >= 25) && (temp <= 900))
+ pData->tick = TICK_CONVERT / temp;
+ break;
+
+ /* handle style */
+ case TOKEN_STYLE:
+ c = IMY_GetNextChar(pEASData->hwInstData, pData, EAS_TRUE);
+ if (c == 'S')
+ c = IMY_GetNextChar(pEASData->hwInstData, pData, EAS_TRUE);
+ if ((c >= '0') && (c <= '2'))
+ pData->style = (EAS_U8) (c - '0');
+ else
+ {
+ PutBackChar(pData);
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Error in style command: %s\n", pData->buffer); */ }
+ }
+ break;
+
+ /* handle volume */
+ case TOKEN_VOLUME:
+ c = IMY_GetNextChar(pEASData->hwInstData, pData, EAS_TRUE);
+ if (c != 'V')
+ {
+ PutBackChar(pData);
+ if (!IsDigit(c))
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Error in volume command: %s\n", pData->buffer); */ }
+ break;
+ }
+ }
+ IMY_GetVolume(pEASData->hwInstData, pData, EAS_TRUE);
+ break;
+
+ case TOKEN_MELODY:
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Header successfully parsed\n"); */ }
+#endif
+ return EAS_SUCCESS;
+
+ case TOKEN_END:
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Unexpected END:IMELODY encountered\n"); */ }
+ return EAS_ERROR_FILE_FORMAT;
+
+ default:
+ /* force a read of the next line */
+ pData->index = 1;
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Ignoring unrecognized token in iMelody file: %s\n", pData->buffer); */ }
+ break;
+ }
+ }
+}
+
+/*----------------------------------------------------------------------------
+ * IMY_GetNextChar()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ *
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_I8 IMY_GetNextChar (EAS_HW_DATA_HANDLE hwInstData, S_IMELODY_DATA *pData, EAS_BOOL inHeader)
+{
+ EAS_I8 c;
+ EAS_U8 index;
+
+ for (;;)
+ {
+ /* get next character */
+ c = pData->buffer[pData->index++];
+
+ /* buffer empty, read more */
+ if (!c)
+ {
+ /* don't read the next line in the header */
+ if (inHeader)
+ return 0;
+
+ pData->index = 0;
+ pData->buffer[0] = 0;
+ if (IMY_ReadLine(hwInstData, pData->fileHandle, pData->buffer, &pData->startLine) != EAS_SUCCESS)
+ {
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_GetNextChar: EOF\n"); */ }
+#endif
+ return 0;
+ }
+
+ /* check for END:IMELODY token */
+ if (IMY_ParseLine(pData->buffer, &index) == TOKEN_END)
+ {
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_GetNextChar: found END:IMELODY\n"); */ }
+#endif
+ pData->buffer[0] = 0;
+ return 0;
+ }
+ continue;
+ }
+
+ /* ignore white space */
+ if (!IsSpace(c))
+ {
+
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_GetNextChar returned '%c'\n", c); */ }
+#endif
+ return c;
+ }
+ }
+}
+
+/*----------------------------------------------------------------------------
+ * IMY_ReadLine()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Reads a line of input from the file, discarding the CR/LF
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT IMY_ReadLine (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE fileHandle, EAS_I8 *buffer, EAS_I32 *pStartLine)
+{
+ EAS_RESULT result;
+ EAS_INT i;
+ EAS_I8 c;
+
+ /* fetch current file position and save it */
+ if (pStartLine != NULL)
+ {
+ if ((result = EAS_HWFilePos(hwInstData, fileHandle, pStartLine)) != EAS_SUCCESS)
+ {
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_ParseHeader: EAS_HWFilePos returned %d\n", result); */ }
+#endif
+ return result;
+ }
+ }
+
+ buffer[0] = 0;
+ for (i = 0; i < MAX_LINE_SIZE; )
+ {
+ if ((result = EAS_HWGetByte(hwInstData, fileHandle, &c)) != EAS_SUCCESS)
+ {
+ if ((result == EAS_EOF) && (i > 0))
+ break;
+ return result;
+ }
+
+ /* return on LF or end of data */
+ if (c == '\n')
+ break;
+
+ /* store characters in buffer */
+ if (c != '\r')
+ buffer[i++] = c;
+ }
+ buffer[i] = 0;
+
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_ReadLine read %s\n", buffer); */ }
+#endif
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * IMY_ParseLine()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ *
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_INT IMY_ParseLine (EAS_I8 *buffer, EAS_U8 *pIndex)
+{
+ EAS_INT i;
+ EAS_INT j;
+
+ /* there's no strnicmp() in stdlib, so we have to roll our own */
+ for (i = 0; i < TOKEN_INVALID; i++)
+ {
+ for (j = 0; ; j++)
+ {
+ /* end of token, must be a match */
+ if (tokens[i][j] == 0)
+ {
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_ParseLine found token %d\n", i); */ }
+#endif
+ *pIndex = (EAS_U8) j;
+ return i;
+ }
+ if (tokens[i][j] != ToUpper(buffer[j]))
+ break;
+ }
+ }
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_ParseLine: no token found\n"); */ }
+#endif
+ return TOKEN_INVALID;
+}
+
diff --git a/arm-wt-22k/lib_src/eas_imelodydata.c b/arm-wt-22k/lib_src/eas_imelodydata.c
index e72dc0b..9437e08 100644
--- a/arm-wt-22k/lib_src/eas_imelodydata.c
+++ b/arm-wt-22k/lib_src/eas_imelodydata.c
@@ -1,14 +1,14 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_imelodydata.c
- *
- * Contents and purpose:
- * SMF File Parser
- *
- * This file contains data definitions for the SMF parser.
- *
- * Copyright Sonic Network Inc. 2005
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_imelodydata.c
+ *
+ * Contents and purpose:
+ * SMF File Parser
+ *
+ * This file contains data definitions for the SMF parser.
+ *
+ * Copyright Sonic Network Inc. 2005
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,23 +21,23 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 547 $
- * $Date: 2007-01-31 16:30:17 -0800 (Wed, 31 Jan 2007) $
- *----------------------------------------------------------------------------
-*/
-
-#include "eas_types.h"
-#include "eas_imelodydata.h"
-
-/*----------------------------------------------------------------------------
- *
- * eas_iMelodyData
- *
- * Static memory allocation for iMelody parser
- *----------------------------------------------------------------------------
-*/
-S_IMELODY_DATA eas_iMelodyData;
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 547 $
+ * $Date: 2007-01-31 16:30:17 -0800 (Wed, 31 Jan 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+#include "eas_types.h"
+#include "eas_imelodydata.h"
+
+/*----------------------------------------------------------------------------
+ *
+ * eas_iMelodyData
+ *
+ * Static memory allocation for iMelody parser
+ *----------------------------------------------------------------------------
+*/
+S_IMELODY_DATA eas_iMelodyData;
+
diff --git a/arm-wt-22k/lib_src/eas_imelodydata.h b/arm-wt-22k/lib_src/eas_imelodydata.h
index 303b8f6..17d03dc 100644
--- a/arm-wt-22k/lib_src/eas_imelodydata.h
+++ b/arm-wt-22k/lib_src/eas_imelodydata.h
@@ -1,14 +1,14 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_imelodydata.h
- *
- * Contents and purpose:
- * SMF File Parser
- *
- * This file contains data declarations for the iMelody parser.
- *
- * Copyright Sonic Network Inc. 2005
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_imelodydata.h
+ *
+ * Contents and purpose:
+ * SMF File Parser
+ *
+ * This file contains data declarations for the iMelody parser.
+ *
+ * Copyright Sonic Network Inc. 2005
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,53 +21,54 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 778 $
- * $Date: 2007-07-23 16:45:17 -0700 (Mon, 23 Jul 2007) $
- *----------------------------------------------------------------------------
-*/
-
-#ifndef EAS_IMELODYDATA_H
-#define EAS_IMELODYDATA_H
-
-#include "eas_data.h"
-
-/* maximum line size as specified in iMelody V1.2 spec */
-#define MAX_LINE_SIZE 75
-
-/*----------------------------------------------------------------------------
- *
- * S_IMELODY_DATA
- *
- * This structure contains the state data for the iMelody parser
- *----------------------------------------------------------------------------
-*/
-
-typedef struct
-{
- EAS_FILE_HANDLE fileHandle; /* file handle */
- S_SYNTH *pSynth; /* pointer to synth */
- EAS_I32 fileOffset; /* offset to start of data */
- EAS_I32 time; /* current time in 256ths of a msec */
- EAS_I32 tickBase; /* basline length of 32nd note in 256th of a msec */
- EAS_I32 tick; /* actual length of 32nd note in 256th of a msec */
- EAS_I32 restTicks; /* ticks to rest after current note */
- EAS_I32 startLine; /* file offset at start of line (for repeats) */
- EAS_I32 repeatOffset; /* file offset to start of repeat section */
- S_METADATA_CB metadata; /* metadata callback */
- EAS_I16 repeatCount; /* repeat counter */
- EAS_U8 state; /* current state EAS_STATE_XXXX */
- EAS_U8 style; /* from STYLE */
- EAS_U8 index; /* index into buffer */
- EAS_U8 octave; /* octave prefix */
- EAS_U8 volume; /* current volume */
- EAS_U8 note; /* MIDI note number */
- EAS_I8 noteModifier; /* sharp or flat */
- EAS_I8 buffer[MAX_LINE_SIZE+1]; /* buffer for ASCII data */
-} S_IMELODY_DATA;
-
-#endif
-
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 778 $
+ * $Date: 2007-07-23 16:45:17 -0700 (Mon, 23 Jul 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+#ifndef EAS_IMELODYDATA_H
+#define EAS_IMELODYDATA_H
+
+#include "eas_data.h"
+
+/* maximum line size as specified in iMelody V1.2 spec */
+#define MAX_LINE_SIZE 75
+
+/*----------------------------------------------------------------------------
+ *
+ * S_IMELODY_DATA
+ *
+ * This structure contains the state data for the iMelody parser
+ *----------------------------------------------------------------------------
+*/
+
+typedef struct
+{
+ EAS_FILE_HANDLE fileHandle; /* file handle */
+ S_SYNTH *pSynth; /* pointer to synth */
+ EAS_I32 fileOffset; /* offset to start of data */
+ EAS_I32 time; /* current time in 256ths of a msec */
+ EAS_I32 tickBase; /* basline length of 32nd note in 256th of a msec */
+ EAS_I32 tick; /* actual length of 32nd note in 256th of a msec */
+ EAS_I32 restTicks; /* ticks to rest after current note */
+ EAS_I32 startLine; /* file offset at start of line (for repeats) */
+ EAS_I32 repeatOffset; /* file offset to start of repeat section */
+ EAS_I32 repeatTime; /* time at start of repeat section */
+ S_METADATA_CB metadata; /* metadata callback */
+ EAS_I16 repeatCount; /* repeat counter */
+ EAS_U8 state; /* current state EAS_STATE_XXXX */
+ EAS_U8 style; /* from STYLE */
+ EAS_U8 index; /* index into buffer */
+ EAS_U8 octave; /* octave prefix */
+ EAS_U8 volume; /* current volume */
+ EAS_U8 note; /* MIDI note number */
+ EAS_I8 noteModifier; /* sharp or flat */
+ EAS_I8 buffer[MAX_LINE_SIZE+1]; /* buffer for ASCII data */
+} S_IMELODY_DATA;
+
+#endif
+
+
diff --git a/arm-wt-22k/lib_src/eas_math.c b/arm-wt-22k/lib_src/eas_math.c
index 12d788e..dc85051 100644
--- a/arm-wt-22k/lib_src/eas_math.c
+++ b/arm-wt-22k/lib_src/eas_math.c
@@ -1,13 +1,13 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_math.c
- *
- * Contents and purpose:
- * Contains common math routines for the various audio engines.
- *
- *
- * Copyright Sonic Network Inc. 2005
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_math.c
+ *
+ * Contents and purpose:
+ * Contains common math routines for the various audio engines.
+ *
+ *
+ * Copyright Sonic Network Inc. 2005
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,149 +20,149 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 586 $
- * $Date: 2007-03-08 20:33:04 -0800 (Thu, 08 Mar 2007) $
- *----------------------------------------------------------------------------
-*/
-
-#include "eas.h"
-#include "eas_math.h"
-
-/* anything less than this converts to a fraction too small to represent in 32-bits */
-#define MIN_CENTS -18000
-
-/*----------------------------------------------------------------------------
- * EAS_Calculate2toX()
- *----------------------------------------------------------------------------
- * Purpose:
- * Calculate 2^x
- *
- * Inputs:
- * nCents - measured in cents
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- * nResult - int.frac result (where frac has NUM_DENTS_FRAC_BITS)
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_I32 EAS_Calculate2toX (EAS_I32 nCents)
-{
- EAS_I32 nDents;
- EAS_I32 nExponentInt, nExponentFrac;
- EAS_I32 nTemp1, nTemp2;
- EAS_I32 nResult;
-
- /* check for minimum value */
- if (nCents < MIN_CENTS)
- return 0;
-
- /* for the time being, convert cents to dents */
- nDents = FMUL_15x15(nCents, CENTS_TO_DENTS);
-
- nExponentInt = GET_DENTS_INT_PART(nDents);
- nExponentFrac = GET_DENTS_FRAC_PART(nDents);
-
- /*
- implement 2^(fracPart) as a power series
- */
- nTemp1 = GN2_TO_X2 + MULT_DENTS_COEF(nExponentFrac, GN2_TO_X3);
- nTemp2 = GN2_TO_X1 + MULT_DENTS_COEF(nExponentFrac, nTemp1);
- nTemp1 = GN2_TO_X0 + MULT_DENTS_COEF(nExponentFrac, nTemp2);
-
- /*
- implement 2^(intPart) as
- a left shift for intPart >= 0 or
- a left shift for intPart < 0
- */
- if (nExponentInt >= 0)
- {
- /* left shift for positive exponents */
- /*lint -e{703} <avoid multiply for performance>*/
- nResult = nTemp1 << nExponentInt;
- }
- else
- {
- /* right shift for negative exponents */
- nExponentInt = -nExponentInt;
- nResult = nTemp1 >> nExponentInt;
- }
-
- return nResult;
-}
-
-/*----------------------------------------------------------------------------
- * EAS_LogToLinear16()
- *----------------------------------------------------------------------------
- * Purpose:
- * Transform log value to linear gain multiplier using piece-wise linear
- * approximation
- *
- * Inputs:
- * nGain - log scale value in 20.10 format. Even though gain is normally
- * stored in 6.10 (16-bit) format we use 32-bit numbers here to eliminate
- * the need for saturation checking when combining gain values.
- *
- * Outputs:
- * Returns a 16-bit linear value approximately equal to 2^(nGain/1024)
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_U16 EAS_LogToLinear16 (EAS_I32 nGain)
-{
- EAS_INT nExp;
- EAS_U16 nTemp;
-
- /* bias to positive */
- nGain += 32767;
-
- /* check for infinite attenuation */
- if (nGain < 0)
- return 0;
-
- /* extract the exponent */
- nExp = 31 - (nGain >> 10);
-
- /* check for maximum output */
- if (nExp < 0)
- return 0x7fff;
-
- /* extract mantissa and restore implied 1 bit */
- nTemp = (EAS_U16)((((nGain & 0x3ff) << 4) | 0x4000) >> nExp);
-
- /* use shift to approximate power-of-2 operation */
- return nTemp;
-}
-
-/*----------------------------------------------------------------------------
- * EAS_VolumeToGain()
- *----------------------------------------------------------------------------
- * Purpose:
- * Transform volume control in 1dB increments to gain multiplier
- *
- * Inputs:
- * volume - 100 = 0dB, 99 = -1dB, 0 = -inf
- *
- * Outputs:
- * Returns a 16-bit linear value
- *----------------------------------------------------------------------------
-*/
-EAS_I16 EAS_VolumeToGain (EAS_INT volume)
-{
- /* check for limits */
- if (volume <= 0)
- return 0;
- if (volume >= 100)
- return 0x7fff;
-
- /*lint -e{702} use shift instead of division */
- return (EAS_I16) EAS_Calculate2toX((((volume - EAS_MAX_VOLUME) * 204099) >> 10) - 1);
-}
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 586 $
+ * $Date: 2007-03-08 20:33:04 -0800 (Thu, 08 Mar 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+#include "eas.h"
+#include "eas_math.h"
+
+/* anything less than this converts to a fraction too small to represent in 32-bits */
+#define MIN_CENTS -18000
+
+/*----------------------------------------------------------------------------
+ * EAS_Calculate2toX()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Calculate 2^x
+ *
+ * Inputs:
+ * nCents - measured in cents
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ * nResult - int.frac result (where frac has NUM_DENTS_FRAC_BITS)
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_I32 EAS_Calculate2toX (EAS_I32 nCents)
+{
+ EAS_I32 nDents;
+ EAS_I32 nExponentInt, nExponentFrac;
+ EAS_I32 nTemp1, nTemp2;
+ EAS_I32 nResult;
+
+ /* check for minimum value */
+ if (nCents < MIN_CENTS)
+ return 0;
+
+ /* for the time being, convert cents to dents */
+ nDents = FMUL_15x15(nCents, CENTS_TO_DENTS);
+
+ nExponentInt = GET_DENTS_INT_PART(nDents);
+ nExponentFrac = GET_DENTS_FRAC_PART(nDents);
+
+ /*
+ implement 2^(fracPart) as a power series
+ */
+ nTemp1 = GN2_TO_X2 + MULT_DENTS_COEF(nExponentFrac, GN2_TO_X3);
+ nTemp2 = GN2_TO_X1 + MULT_DENTS_COEF(nExponentFrac, nTemp1);
+ nTemp1 = GN2_TO_X0 + MULT_DENTS_COEF(nExponentFrac, nTemp2);
+
+ /*
+ implement 2^(intPart) as
+ a left shift for intPart >= 0 or
+ a left shift for intPart < 0
+ */
+ if (nExponentInt >= 0)
+ {
+ /* left shift for positive exponents */
+ /*lint -e{703} <avoid multiply for performance>*/
+ nResult = nTemp1 << nExponentInt;
+ }
+ else
+ {
+ /* right shift for negative exponents */
+ nExponentInt = -nExponentInt;
+ nResult = nTemp1 >> nExponentInt;
+ }
+
+ return nResult;
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_LogToLinear16()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Transform log value to linear gain multiplier using piece-wise linear
+ * approximation
+ *
+ * Inputs:
+ * nGain - log scale value in 20.10 format. Even though gain is normally
+ * stored in 6.10 (16-bit) format we use 32-bit numbers here to eliminate
+ * the need for saturation checking when combining gain values.
+ *
+ * Outputs:
+ * Returns a 16-bit linear value approximately equal to 2^(nGain/1024)
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_U16 EAS_LogToLinear16 (EAS_I32 nGain)
+{
+ EAS_INT nExp;
+ EAS_U16 nTemp;
+
+ /* bias to positive */
+ nGain += 32767;
+
+ /* check for infinite attenuation */
+ if (nGain < 0)
+ return 0;
+
+ /* extract the exponent */
+ nExp = 31 - (nGain >> 10);
+
+ /* check for maximum output */
+ if (nExp < 0)
+ return 0x7fff;
+
+ /* extract mantissa and restore implied 1 bit */
+ nTemp = (EAS_U16)((((nGain & 0x3ff) << 4) | 0x4000) >> nExp);
+
+ /* use shift to approximate power-of-2 operation */
+ return nTemp;
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_VolumeToGain()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Transform volume control in 1dB increments to gain multiplier
+ *
+ * Inputs:
+ * volume - 100 = 0dB, 99 = -1dB, 0 = -inf
+ *
+ * Outputs:
+ * Returns a 16-bit linear value
+ *----------------------------------------------------------------------------
+*/
+EAS_I16 EAS_VolumeToGain (EAS_INT volume)
+{
+ /* check for limits */
+ if (volume <= 0)
+ return 0;
+ if (volume >= 100)
+ return 0x7fff;
+
+ /*lint -e{702} use shift instead of division */
+ return (EAS_I16) EAS_Calculate2toX((((volume - EAS_MAX_VOLUME) * 204099) >> 10) - 1);
+}
+
diff --git a/arm-wt-22k/lib_src/eas_math.h b/arm-wt-22k/lib_src/eas_math.h
index 719270b..f240b51 100644
--- a/arm-wt-22k/lib_src/eas_math.h
+++ b/arm-wt-22k/lib_src/eas_math.h
@@ -1,13 +1,13 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_math.h
- *
- * Contents and purpose:
- * Contains common math routines for the various audio engines.
- *
- *
- * Copyright Sonic Network Inc. 2005
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_math.h
+ *
+ * Contents and purpose:
+ * Contains common math routines for the various audio engines.
+ *
+ *
+ * Copyright Sonic Network Inc. 2005
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,393 +20,393 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 584 $
- * $Date: 2007-03-08 09:49:24 -0800 (Thu, 08 Mar 2007) $
- *----------------------------------------------------------------------------
-*/
-
-#ifndef _EAS_MATH_H
-#define _EAS_MATH_H
-
-
-/** coefs for pan, generates sin, cos */
-#define COEFF_PAN_G2 -27146 /* -0.82842712474619 = 2 - 4/sqrt(2) */
-#define COEFF_PAN_G0 23170 /* 0.707106781186547 = 1/sqrt(2) */
-
-/*
-coefficients for approximating
-2^x = gn2toX0 + gn2toX1*x + gn2toX2*x^2 + gn2toX3*x^3
-where x is a int.frac number representing number of octaves.
-Actually, we approximate only the 2^(frac) using the power series
-and implement the 2^(int) as a shift, so that
-2^x == 2^(int.frac) == 2^(int) * 2^(fract)
- == (gn2toX0 + gn2toX1*x + gn2toX2*x^2 + gn2toX3*x^3) << (int)
-
-The gn2toX.. were generated using a best fit for a 3rd
-order polynomial, instead of taking the coefficients from
-a truncated Taylor (or Maclaurin?) series.
-*/
-
-#define GN2_TO_X0 32768 /* 1 */
-#define GN2_TO_X1 22833 /* 0.696807861328125 */
-#define GN2_TO_X2 7344 /* 0.22412109375 */
-#define GN2_TO_X3 2588 /* 0.0789794921875 */
-
-/*----------------------------------------------------------------------------
- * Fixed Point Math
- *----------------------------------------------------------------------------
- * These macros are used for fixed point multiplies. If the processor
- * supports fixed point multiplies, replace these macros with inline
- * assembly code to improve performance.
- *----------------------------------------------------------------------------
-*/
-
-/* Fixed point multiply 0.15 x 0.15 = 0.15 returned as 32-bits */
-#define FMUL_15x15(a,b) \
- /*lint -e(704) <avoid multiply for performance>*/ \
- (((EAS_I32)(a) * (EAS_I32)(b)) >> 15)
-
-/* Fixed point multiply 0.7 x 0.7 = 0.15 returned as 32-bits */
-#define FMUL_7x7(a,b) \
- /*lint -e(704) <avoid multiply for performance>*/ \
- (((EAS_I32)(a) * (EAS_I32)(b) ) << 1)
-
-/* Fixed point multiply 0.8 x 0.8 = 0.15 returned as 32-bits */
-#define FMUL_8x8(a,b) \
- /*lint -e(704) <avoid multiply for performance>*/ \
- (((EAS_I32)(a) * (EAS_I32)(b) ) >> 1)
-
-/* Fixed point multiply 0.8 x 1.15 = 0.15 returned as 32-bits */
-#define FMUL_8x15(a,b) \
- /*lint -e(704) <avoid divide for performance>*/ \
- (((EAS_I32)((a) << 7) * (EAS_I32)(b)) >> 15)
-
-/* macros for fractional phase accumulator */
-/*
-Note: changed the _U32 to _I32 on 03/14/02. This should not
-affect the phase calculations, and should allow us to reuse these
-macros for other audio sample related math.
-*/
-#define HARDWARE_BIT_WIDTH 32
-
-#define NUM_PHASE_INT_BITS 1
-#define NUM_PHASE_FRAC_BITS 15
-
-#define PHASE_FRAC_MASK (EAS_U32) ((0x1L << NUM_PHASE_FRAC_BITS) -1)
-
-#define GET_PHASE_INT_PART(x) (EAS_U32)((EAS_U32)(x) >> NUM_PHASE_FRAC_BITS)
-#define GET_PHASE_FRAC_PART(x) (EAS_U32)((EAS_U32)(x) & PHASE_FRAC_MASK)
-
-#define DEFAULT_PHASE_FRAC 0
-#define DEFAULT_PHASE_INT 0
-
-/*
-Linear interpolation calculates:
-output = (1-frac) * sample[n] + (frac) * sample[n+1]
-
-where conceptually 0 <= frac < 1
-
-For a fixed point implementation, frac is actually an integer value
-with an implied binary point one position to the left. The value of
-one (unity) is given by PHASE_ONE
-one half and one quarter are useful for 4-point linear interp.
-*/
-#define PHASE_ONE (EAS_I32) (0x1L << NUM_PHASE_FRAC_BITS)
-
-/*
- Multiply the signed audio sample by the unsigned fraction.
-- a is the signed audio sample
-- b is the unsigned fraction (cast to signed int as long as coef
- uses (n-1) or less bits, where n == hardware bit width)
-*/
-#define MULT_AUDIO_COEF(audio,coef) /*lint -e704 <avoid divide for performance>*/ \
- (EAS_I32)( \
- ( \
- ((EAS_I32)(audio)) * ((EAS_I32)(coef)) \
- ) \
- >> NUM_PHASE_FRAC_BITS \
- ) \
- /* lint +704 <restore checking>*/
-
-/* wet / dry calculation macros */
-#define NUM_WET_DRY_FRAC_BITS 7 // 15
-#define NUM_WET_DRY_INT_BITS 9 // 1
-
-/* define a 1.0 */
-#define WET_DRY_ONE (EAS_I32) ((0x1L << NUM_WET_DRY_FRAC_BITS))
-#define WET_DRY_MINUS_ONE (EAS_I32) (~WET_DRY_ONE)
-#define WET_DRY_FULL_SCALE (EAS_I32) (WET_DRY_ONE - 1)
-
-#define MULT_AUDIO_WET_DRY_COEF(audio,coef) /*lint -e(702) <avoid divide for performance>*/ \
- (EAS_I32)( \
- ( \
- ((EAS_I32)(audio)) * ((EAS_I32)(coef)) \
- ) \
- >> NUM_WET_DRY_FRAC_BITS \
- )
-
-/* Envelope 1 (EG1) calculation macros */
-#define NUM_EG1_INT_BITS 1
-#define NUM_EG1_FRAC_BITS 15
-
-/* the max positive gain used in the synth for EG1 */
-/* SYNTH_FULL_SCALE_EG1_GAIN must match the value in the dls2eas
-converter, otherwise, the values we read from the .eas file are bogus. */
-#define SYNTH_FULL_SCALE_EG1_GAIN (EAS_I32) ((0x1L << NUM_EG1_FRAC_BITS) -1)
-
-/* define a 1.0 */
-#define EG1_ONE (EAS_I32) ((0x1L << NUM_EG1_FRAC_BITS))
-#define EG1_MINUS_ONE (EAS_I32) (~SYNTH_FULL_SCALE_EG1_GAIN)
-
-#define EG1_HALF (EAS_I32) (EG1_ONE/2)
-#define EG1_MINUS_HALF (EAS_I32) (EG1_MINUS_ONE/2)
-
-/*
-We implement the EG1 using a linear gain value, which means that the
-attack segment is handled by incrementing (adding) the linear gain.
-However, EG1 treats the Decay, Sustain, and Release differently than
-the Attack portion. For Decay, Sustain, and Release, the gain is
-linear on dB scale, which is equivalent to exponential damping on
-a linear scale. Because we use a linear gain for EG1, we implement
-the Decay and Release as multiplication (instead of incrementing
-as we did for the attack segment).
-Therefore, we need the following macro to implement the multiplication
-(i.e., exponential damping) during the Decay and Release segments of
-the EG1
-*/
-#define MULT_EG1_EG1(gain,damping) /*lint -e(704) <avoid divide for performance>*/ \
- (EAS_I32)( \
- ( \
- ((EAS_I32)(gain)) * ((EAS_I32)(damping)) \
- ) \
- >> NUM_EG1_FRAC_BITS \
- )
-
-// Use the following macro specifically for the filter, when multiplying
-// the b1 coefficient. The 0 <= |b1| < 2, which therefore might overflow
-// in certain conditions because we store b1 as a 1.15 value.
-// Instead, we could store b1 as b1p (b1' == b1 "prime") where
-// b1p == b1/2, thus ensuring no potential overflow for b1p because
-// 0 <= |b1p| < 1
-// However, during the filter calculation, we must account for the fact
-// that we are using b1p instead of b1, and thereby multiply by
-// an extra factor of 2. Rather than multiply by an extra factor of 2,
-// we can instead shift the result right by one less, hence the
-// modified shift right value of (NUM_EG1_FRAC_BITS -1)
-#define MULT_EG1_EG1_X2(gain,damping) /*lint -e(702) <avoid divide for performance>*/ \
- (EAS_I32)( \
- ( \
- ((EAS_I32)(gain)) * ((EAS_I32)(damping)) \
- ) \
- >> (NUM_EG1_FRAC_BITS -1) \
- )
-
-#define SATURATE_EG1(x) /*lint -e{734} saturation operation */ \
- ((EAS_I32)(x) > SYNTH_FULL_SCALE_EG1_GAIN) ? (SYNTH_FULL_SCALE_EG1_GAIN) : \
- ((EAS_I32)(x) < EG1_MINUS_ONE) ? (EG1_MINUS_ONE) : (x);
-
-
-/* use "digital cents" == "dents" instead of cents */
-/* we coudl re-use the phase frac macros, but if we do,
-we must change the phase macros to cast to _I32 instead of _U32,
-because using a _U32 cast causes problems when shifting the exponent
-for the 2^x calculation, because right shift a negative values MUST
-be sign extended, or else the 2^x calculation is wrong */
-
-/* use "digital cents" == "dents" instead of cents */
-#define NUM_DENTS_FRAC_BITS 12
-#define NUM_DENTS_INT_BITS (HARDWARE_BIT_WIDTH - NUM_DENTS_FRAC_BITS)
-
-#define DENTS_FRAC_MASK (EAS_I32) ((0x1L << NUM_DENTS_FRAC_BITS) -1)
-
-#define GET_DENTS_INT_PART(x) /*lint -e(704) <avoid divide for performance>*/ \
- (EAS_I32)((EAS_I32)(x) >> NUM_DENTS_FRAC_BITS)
-
-#define GET_DENTS_FRAC_PART(x) (EAS_I32)((EAS_I32)(x) & DENTS_FRAC_MASK)
-
-#define DENTS_ONE (EAS_I32) (0x1L << NUM_DENTS_FRAC_BITS)
-
-/* use CENTS_TO_DENTS to convert a value in cents to dents */
-#define CENTS_TO_DENTS (EAS_I32) (DENTS_ONE * (0x1L << NUM_EG1_FRAC_BITS) / 1200L) \
-
-
-/*
-For gain, the LFO generates a value that modulates in terms
-of dB. However, we use a linear gain value, so we must convert
-the LFO value in dB to a linear gain. Normally, we would use
-linear gain = 10^x, where x = LFO value in dB / 20.
-Instead, we implement 10^x using our 2^x approximation.
-because
-
- 10^x = 2^(log2(10^x)) = 2^(x * log2(10))
-
-so we need to multiply by log2(10) which is just a constant.
-Ah, but just wait -- our 2^x actually doesn't exactly implement
-2^x, but it actually assumes that the input is in cents, and within
-the 2^x approximation converts its input from cents to octaves
-by dividing its input by 1200.
-
-So, in order to convert the LFO gain value in dB to something
-that our existing 2^x approximation can use, multiply the LFO gain
-by log2(10) * 1200 / 20
-
-The divide by 20 helps convert dB to linear gain, and we might
-as well incorporate that operation into this conversion.
-Of course, we need to keep some fractional bits, so multiply
-the constant by NUM_EG1_FRAC_BITS
-*/
-
-/* use LFO_GAIN_TO_CENTS to convert the LFO gain value to cents */
-#if 0
-#define DOUBLE_LOG2_10 (double) (3.32192809488736) /* log2(10) */
-
-#define DOUBLE_LFO_GAIN_TO_CENTS (double) \
- ( \
- (DOUBLE_LOG2_10) * \
- 1200.0 / \
- 20.0 \
- )
-
-#define LFO_GAIN_TO_CENTS (EAS_I32) \
- ( \
- DOUBLE_LFO_GAIN_TO_CENTS * \
- (0x1L << NUM_EG1_FRAC_BITS) \
- )
-#endif
-
-#define LFO_GAIN_TO_CENTS (EAS_I32) (1671981156L >> (23 - NUM_EG1_FRAC_BITS))
-
-
-#define MULT_DENTS_COEF(dents,coef) /*lint -e704 <avoid divide for performance>*/ \
- (EAS_I32)( \
- ( \
- ((EAS_I32)(dents)) * ((EAS_I32)(coef)) \
- ) \
- >> NUM_DENTS_FRAC_BITS \
- ) \
- /* lint +e704 <restore checking>*/
-
-/* we use 16-bits in the PC per audio sample */
-#define BITS_PER_AUDIO_SAMPLE 16
-
-/* we define 1 as 1.0 - 1 LSbit */
-#define DISTORTION_ONE (EAS_I32)((0x1L << (BITS_PER_AUDIO_SAMPLE-1)) -1)
-#define DISTORTION_MINUS_ONE (EAS_I32)(~DISTORTION_ONE)
-
-/* drive coef is given as int.frac */
-#define NUM_DRIVE_COEF_INT_BITS 1
-#define NUM_DRIVE_COEF_FRAC_BITS 4
-
-#define MULT_AUDIO_DRIVE(audio,drive) /*lint -e(702) <avoid divide for performance>*/ \
- (EAS_I32) ( \
- ( \
- ((EAS_I32)(audio)) * ((EAS_I32)(drive)) \
- ) \
- >> NUM_DRIVE_COEF_FRAC_BITS \
- )
-
-#define MULT_AUDIO_AUDIO(audio1,audio2) /*lint -e(702) <avoid divide for performance>*/ \
- (EAS_I32) ( \
- ( \
- ((EAS_I32)(audio1)) * ((EAS_I32)(audio2)) \
- ) \
- >> (BITS_PER_AUDIO_SAMPLE-1) \
- )
-
-#define SATURATE(x) \
- ((((EAS_I32)(x)) > DISTORTION_ONE) ? (DISTORTION_ONE) : \
- (((EAS_I32)(x)) < DISTORTION_MINUS_ONE) ? (DISTORTION_MINUS_ONE) : ((EAS_I32)(x)));
-
-
-
-/*----------------------------------------------------------------------------
- * EAS_Calculate2toX()
- *----------------------------------------------------------------------------
- * Purpose:
- * Calculate 2^x
- *
- * Inputs:
- * nCents - measured in cents
- *
- * Outputs:
- * nResult - int.frac result (where frac has NUM_DENTS_FRAC_BITS)
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_I32 EAS_Calculate2toX (EAS_I32 nCents);
-
-/*----------------------------------------------------------------------------
- * EAS_LogToLinear16()
- *----------------------------------------------------------------------------
- * Purpose:
- * Transform log value to linear gain multiplier using piece-wise linear
- * approximation
- *
- * Inputs:
- * nGain - log scale value in 20.10 format. Even though gain is normally
- * stored in 6.10 (16-bit) format we use 32-bit numbers here to eliminate
- * the need for saturation checking when combining gain values.
- *
- * Outputs:
- * Returns a 16-bit linear value approximately equal to 2^(nGain/1024)
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_U16 EAS_LogToLinear16 (EAS_I32 nGain);
-
-/*----------------------------------------------------------------------------
- * EAS_VolumeToGain()
- *----------------------------------------------------------------------------
- * Purpose:
- * Transform volume control in 1dB increments to gain multiplier
- *
- * Inputs:
- * volume - 100 = 0dB, 99 = -1dB, 0 = -inf
- *
- * Outputs:
- * Returns a 16-bit linear value
- *----------------------------------------------------------------------------
-*/
-EAS_I16 EAS_VolumeToGain (EAS_INT volume);
-
-/*----------------------------------------------------------------------------
- * EAS_fsqrt()
- *----------------------------------------------------------------------------
- * Purpose:
- * Calculates the square root of a 32-bit fixed point value
- *
- * Inputs:
- * n = value of interest
- *
- * Outputs:
- * returns the square root of n
- *
- *----------------------------------------------------------------------------
-*/
-EAS_U16 EAS_fsqrt (EAS_U32 n);
-
-/*----------------------------------------------------------------------------
- * EAS_flog2()
- *----------------------------------------------------------------------------
- * Purpose:
- * Calculates the log2 of a 32-bit fixed point value
- *
- * Inputs:
- * n = value of interest
- *
- * Outputs:
- * returns the log2 of n
- *
- *----------------------------------------------------------------------------
-*/
-EAS_I32 EAS_flog2 (EAS_U32 n);
-
-#endif
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 584 $
+ * $Date: 2007-03-08 09:49:24 -0800 (Thu, 08 Mar 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+#ifndef _EAS_MATH_H
+#define _EAS_MATH_H
+
+
+/** coefs for pan, generates sin, cos */
+#define COEFF_PAN_G2 -27146 /* -0.82842712474619 = 2 - 4/sqrt(2) */
+#define COEFF_PAN_G0 23170 /* 0.707106781186547 = 1/sqrt(2) */
+
+/*
+coefficients for approximating
+2^x = gn2toX0 + gn2toX1*x + gn2toX2*x^2 + gn2toX3*x^3
+where x is a int.frac number representing number of octaves.
+Actually, we approximate only the 2^(frac) using the power series
+and implement the 2^(int) as a shift, so that
+2^x == 2^(int.frac) == 2^(int) * 2^(fract)
+ == (gn2toX0 + gn2toX1*x + gn2toX2*x^2 + gn2toX3*x^3) << (int)
+
+The gn2toX.. were generated using a best fit for a 3rd
+order polynomial, instead of taking the coefficients from
+a truncated Taylor (or Maclaurin?) series.
+*/
+
+#define GN2_TO_X0 32768 /* 1 */
+#define GN2_TO_X1 22833 /* 0.696807861328125 */
+#define GN2_TO_X2 7344 /* 0.22412109375 */
+#define GN2_TO_X3 2588 /* 0.0789794921875 */
+
+/*----------------------------------------------------------------------------
+ * Fixed Point Math
+ *----------------------------------------------------------------------------
+ * These macros are used for fixed point multiplies. If the processor
+ * supports fixed point multiplies, replace these macros with inline
+ * assembly code to improve performance.
+ *----------------------------------------------------------------------------
+*/
+
+/* Fixed point multiply 0.15 x 0.15 = 0.15 returned as 32-bits */
+#define FMUL_15x15(a,b) \
+ /*lint -e(704) <avoid multiply for performance>*/ \
+ (((EAS_I32)(a) * (EAS_I32)(b)) >> 15)
+
+/* Fixed point multiply 0.7 x 0.7 = 0.15 returned as 32-bits */
+#define FMUL_7x7(a,b) \
+ /*lint -e(704) <avoid multiply for performance>*/ \
+ (((EAS_I32)(a) * (EAS_I32)(b) ) << 1)
+
+/* Fixed point multiply 0.8 x 0.8 = 0.15 returned as 32-bits */
+#define FMUL_8x8(a,b) \
+ /*lint -e(704) <avoid multiply for performance>*/ \
+ (((EAS_I32)(a) * (EAS_I32)(b) ) >> 1)
+
+/* Fixed point multiply 0.8 x 1.15 = 0.15 returned as 32-bits */
+#define FMUL_8x15(a,b) \
+ /*lint -e(704) <avoid divide for performance>*/ \
+ (((EAS_I32)((a) << 7) * (EAS_I32)(b)) >> 15)
+
+/* macros for fractional phase accumulator */
+/*
+Note: changed the _U32 to _I32 on 03/14/02. This should not
+affect the phase calculations, and should allow us to reuse these
+macros for other audio sample related math.
+*/
+#define HARDWARE_BIT_WIDTH 32
+
+#define NUM_PHASE_INT_BITS 1
+#define NUM_PHASE_FRAC_BITS 15
+
+#define PHASE_FRAC_MASK (EAS_U32) ((0x1L << NUM_PHASE_FRAC_BITS) -1)
+
+#define GET_PHASE_INT_PART(x) (EAS_U32)((EAS_U32)(x) >> NUM_PHASE_FRAC_BITS)
+#define GET_PHASE_FRAC_PART(x) (EAS_U32)((EAS_U32)(x) & PHASE_FRAC_MASK)
+
+#define DEFAULT_PHASE_FRAC 0
+#define DEFAULT_PHASE_INT 0
+
+/*
+Linear interpolation calculates:
+output = (1-frac) * sample[n] + (frac) * sample[n+1]
+
+where conceptually 0 <= frac < 1
+
+For a fixed point implementation, frac is actually an integer value
+with an implied binary point one position to the left. The value of
+one (unity) is given by PHASE_ONE
+one half and one quarter are useful for 4-point linear interp.
+*/
+#define PHASE_ONE (EAS_I32) (0x1L << NUM_PHASE_FRAC_BITS)
+
+/*
+ Multiply the signed audio sample by the unsigned fraction.
+- a is the signed audio sample
+- b is the unsigned fraction (cast to signed int as long as coef
+ uses (n-1) or less bits, where n == hardware bit width)
+*/
+#define MULT_AUDIO_COEF(audio,coef) /*lint -e704 <avoid divide for performance>*/ \
+ (EAS_I32)( \
+ ( \
+ ((EAS_I32)(audio)) * ((EAS_I32)(coef)) \
+ ) \
+ >> NUM_PHASE_FRAC_BITS \
+ ) \
+ /* lint +704 <restore checking>*/
+
+/* wet / dry calculation macros */
+#define NUM_WET_DRY_FRAC_BITS 7 // 15
+#define NUM_WET_DRY_INT_BITS 9 // 1
+
+/* define a 1.0 */
+#define WET_DRY_ONE (EAS_I32) ((0x1L << NUM_WET_DRY_FRAC_BITS))
+#define WET_DRY_MINUS_ONE (EAS_I32) (~WET_DRY_ONE)
+#define WET_DRY_FULL_SCALE (EAS_I32) (WET_DRY_ONE - 1)
+
+#define MULT_AUDIO_WET_DRY_COEF(audio,coef) /*lint -e(702) <avoid divide for performance>*/ \
+ (EAS_I32)( \
+ ( \
+ ((EAS_I32)(audio)) * ((EAS_I32)(coef)) \
+ ) \
+ >> NUM_WET_DRY_FRAC_BITS \
+ )
+
+/* Envelope 1 (EG1) calculation macros */
+#define NUM_EG1_INT_BITS 1
+#define NUM_EG1_FRAC_BITS 15
+
+/* the max positive gain used in the synth for EG1 */
+/* SYNTH_FULL_SCALE_EG1_GAIN must match the value in the dls2eas
+converter, otherwise, the values we read from the .eas file are bogus. */
+#define SYNTH_FULL_SCALE_EG1_GAIN (EAS_I32) ((0x1L << NUM_EG1_FRAC_BITS) -1)
+
+/* define a 1.0 */
+#define EG1_ONE (EAS_I32) ((0x1L << NUM_EG1_FRAC_BITS))
+#define EG1_MINUS_ONE (EAS_I32) (~SYNTH_FULL_SCALE_EG1_GAIN)
+
+#define EG1_HALF (EAS_I32) (EG1_ONE/2)
+#define EG1_MINUS_HALF (EAS_I32) (EG1_MINUS_ONE/2)
+
+/*
+We implement the EG1 using a linear gain value, which means that the
+attack segment is handled by incrementing (adding) the linear gain.
+However, EG1 treats the Decay, Sustain, and Release differently than
+the Attack portion. For Decay, Sustain, and Release, the gain is
+linear on dB scale, which is equivalent to exponential damping on
+a linear scale. Because we use a linear gain for EG1, we implement
+the Decay and Release as multiplication (instead of incrementing
+as we did for the attack segment).
+Therefore, we need the following macro to implement the multiplication
+(i.e., exponential damping) during the Decay and Release segments of
+the EG1
+*/
+#define MULT_EG1_EG1(gain,damping) /*lint -e(704) <avoid divide for performance>*/ \
+ (EAS_I32)( \
+ ( \
+ ((EAS_I32)(gain)) * ((EAS_I32)(damping)) \
+ ) \
+ >> NUM_EG1_FRAC_BITS \
+ )
+
+// Use the following macro specifically for the filter, when multiplying
+// the b1 coefficient. The 0 <= |b1| < 2, which therefore might overflow
+// in certain conditions because we store b1 as a 1.15 value.
+// Instead, we could store b1 as b1p (b1' == b1 "prime") where
+// b1p == b1/2, thus ensuring no potential overflow for b1p because
+// 0 <= |b1p| < 1
+// However, during the filter calculation, we must account for the fact
+// that we are using b1p instead of b1, and thereby multiply by
+// an extra factor of 2. Rather than multiply by an extra factor of 2,
+// we can instead shift the result right by one less, hence the
+// modified shift right value of (NUM_EG1_FRAC_BITS -1)
+#define MULT_EG1_EG1_X2(gain,damping) /*lint -e(702) <avoid divide for performance>*/ \
+ (EAS_I32)( \
+ ( \
+ ((EAS_I32)(gain)) * ((EAS_I32)(damping)) \
+ ) \
+ >> (NUM_EG1_FRAC_BITS -1) \
+ )
+
+#define SATURATE_EG1(x) /*lint -e{734} saturation operation */ \
+ ((EAS_I32)(x) > SYNTH_FULL_SCALE_EG1_GAIN) ? (SYNTH_FULL_SCALE_EG1_GAIN) : \
+ ((EAS_I32)(x) < EG1_MINUS_ONE) ? (EG1_MINUS_ONE) : (x);
+
+
+/* use "digital cents" == "dents" instead of cents */
+/* we coudl re-use the phase frac macros, but if we do,
+we must change the phase macros to cast to _I32 instead of _U32,
+because using a _U32 cast causes problems when shifting the exponent
+for the 2^x calculation, because right shift a negative values MUST
+be sign extended, or else the 2^x calculation is wrong */
+
+/* use "digital cents" == "dents" instead of cents */
+#define NUM_DENTS_FRAC_BITS 12
+#define NUM_DENTS_INT_BITS (HARDWARE_BIT_WIDTH - NUM_DENTS_FRAC_BITS)
+
+#define DENTS_FRAC_MASK (EAS_I32) ((0x1L << NUM_DENTS_FRAC_BITS) -1)
+
+#define GET_DENTS_INT_PART(x) /*lint -e(704) <avoid divide for performance>*/ \
+ (EAS_I32)((EAS_I32)(x) >> NUM_DENTS_FRAC_BITS)
+
+#define GET_DENTS_FRAC_PART(x) (EAS_I32)((EAS_I32)(x) & DENTS_FRAC_MASK)
+
+#define DENTS_ONE (EAS_I32) (0x1L << NUM_DENTS_FRAC_BITS)
+
+/* use CENTS_TO_DENTS to convert a value in cents to dents */
+#define CENTS_TO_DENTS (EAS_I32) (DENTS_ONE * (0x1L << NUM_EG1_FRAC_BITS) / 1200L) \
+
+
+/*
+For gain, the LFO generates a value that modulates in terms
+of dB. However, we use a linear gain value, so we must convert
+the LFO value in dB to a linear gain. Normally, we would use
+linear gain = 10^x, where x = LFO value in dB / 20.
+Instead, we implement 10^x using our 2^x approximation.
+because
+
+ 10^x = 2^(log2(10^x)) = 2^(x * log2(10))
+
+so we need to multiply by log2(10) which is just a constant.
+Ah, but just wait -- our 2^x actually doesn't exactly implement
+2^x, but it actually assumes that the input is in cents, and within
+the 2^x approximation converts its input from cents to octaves
+by dividing its input by 1200.
+
+So, in order to convert the LFO gain value in dB to something
+that our existing 2^x approximation can use, multiply the LFO gain
+by log2(10) * 1200 / 20
+
+The divide by 20 helps convert dB to linear gain, and we might
+as well incorporate that operation into this conversion.
+Of course, we need to keep some fractional bits, so multiply
+the constant by NUM_EG1_FRAC_BITS
+*/
+
+/* use LFO_GAIN_TO_CENTS to convert the LFO gain value to cents */
+#if 0
+#define DOUBLE_LOG2_10 (double) (3.32192809488736) /* log2(10) */
+
+#define DOUBLE_LFO_GAIN_TO_CENTS (double) \
+ ( \
+ (DOUBLE_LOG2_10) * \
+ 1200.0 / \
+ 20.0 \
+ )
+
+#define LFO_GAIN_TO_CENTS (EAS_I32) \
+ ( \
+ DOUBLE_LFO_GAIN_TO_CENTS * \
+ (0x1L << NUM_EG1_FRAC_BITS) \
+ )
+#endif
+
+#define LFO_GAIN_TO_CENTS (EAS_I32) (1671981156L >> (23 - NUM_EG1_FRAC_BITS))
+
+
+#define MULT_DENTS_COEF(dents,coef) /*lint -e704 <avoid divide for performance>*/ \
+ (EAS_I32)( \
+ ( \
+ ((EAS_I32)(dents)) * ((EAS_I32)(coef)) \
+ ) \
+ >> NUM_DENTS_FRAC_BITS \
+ ) \
+ /* lint +e704 <restore checking>*/
+
+/* we use 16-bits in the PC per audio sample */
+#define BITS_PER_AUDIO_SAMPLE 16
+
+/* we define 1 as 1.0 - 1 LSbit */
+#define DISTORTION_ONE (EAS_I32)((0x1L << (BITS_PER_AUDIO_SAMPLE-1)) -1)
+#define DISTORTION_MINUS_ONE (EAS_I32)(~DISTORTION_ONE)
+
+/* drive coef is given as int.frac */
+#define NUM_DRIVE_COEF_INT_BITS 1
+#define NUM_DRIVE_COEF_FRAC_BITS 4
+
+#define MULT_AUDIO_DRIVE(audio,drive) /*lint -e(702) <avoid divide for performance>*/ \
+ (EAS_I32) ( \
+ ( \
+ ((EAS_I32)(audio)) * ((EAS_I32)(drive)) \
+ ) \
+ >> NUM_DRIVE_COEF_FRAC_BITS \
+ )
+
+#define MULT_AUDIO_AUDIO(audio1,audio2) /*lint -e(702) <avoid divide for performance>*/ \
+ (EAS_I32) ( \
+ ( \
+ ((EAS_I32)(audio1)) * ((EAS_I32)(audio2)) \
+ ) \
+ >> (BITS_PER_AUDIO_SAMPLE-1) \
+ )
+
+#define SATURATE(x) \
+ ((((EAS_I32)(x)) > DISTORTION_ONE) ? (DISTORTION_ONE) : \
+ (((EAS_I32)(x)) < DISTORTION_MINUS_ONE) ? (DISTORTION_MINUS_ONE) : ((EAS_I32)(x)));
+
+
+
+/*----------------------------------------------------------------------------
+ * EAS_Calculate2toX()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Calculate 2^x
+ *
+ * Inputs:
+ * nCents - measured in cents
+ *
+ * Outputs:
+ * nResult - int.frac result (where frac has NUM_DENTS_FRAC_BITS)
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_I32 EAS_Calculate2toX (EAS_I32 nCents);
+
+/*----------------------------------------------------------------------------
+ * EAS_LogToLinear16()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Transform log value to linear gain multiplier using piece-wise linear
+ * approximation
+ *
+ * Inputs:
+ * nGain - log scale value in 20.10 format. Even though gain is normally
+ * stored in 6.10 (16-bit) format we use 32-bit numbers here to eliminate
+ * the need for saturation checking when combining gain values.
+ *
+ * Outputs:
+ * Returns a 16-bit linear value approximately equal to 2^(nGain/1024)
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_U16 EAS_LogToLinear16 (EAS_I32 nGain);
+
+/*----------------------------------------------------------------------------
+ * EAS_VolumeToGain()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Transform volume control in 1dB increments to gain multiplier
+ *
+ * Inputs:
+ * volume - 100 = 0dB, 99 = -1dB, 0 = -inf
+ *
+ * Outputs:
+ * Returns a 16-bit linear value
+ *----------------------------------------------------------------------------
+*/
+EAS_I16 EAS_VolumeToGain (EAS_INT volume);
+
+/*----------------------------------------------------------------------------
+ * EAS_fsqrt()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Calculates the square root of a 32-bit fixed point value
+ *
+ * Inputs:
+ * n = value of interest
+ *
+ * Outputs:
+ * returns the square root of n
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_U16 EAS_fsqrt (EAS_U32 n);
+
+/*----------------------------------------------------------------------------
+ * EAS_flog2()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Calculates the log2 of a 32-bit fixed point value
+ *
+ * Inputs:
+ * n = value of interest
+ *
+ * Outputs:
+ * returns the log2 of n
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_I32 EAS_flog2 (EAS_U32 n);
+
+#endif
+
diff --git a/arm-wt-22k/lib_src/eas_mdls.c b/arm-wt-22k/lib_src/eas_mdls.c
index 3da3b06..e8dc463 100644
--- a/arm-wt-22k/lib_src/eas_mdls.c
+++ b/arm-wt-22k/lib_src/eas_mdls.c
@@ -1,11 +1,11 @@
/*----------------------------------------------------------------------------
*
- * File:
+ * File:
* eas_mdls.c
*
* Contents and purpose:
* This file contains DLS to EAS converter.
- *
+ *
* Copyright (c) 2005 Sonic Network Inc.
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -133,11 +133,11 @@ extern double log10(double x);
// #define _DEBUG_DLS
-#define DLS_MAX_WAVE_COUNT 1024
-#define DLS_MAX_ART_COUNT 2048
-#define DLS_MAX_REGION_COUNT 2048
-#define DLS_MAX_INST_COUNT 256
-#define MAX_DLS_WAVE_SIZE (1024*1024)
+#define DLS_MAX_WAVE_COUNT 1024
+#define DLS_MAX_ART_COUNT 2048
+#define DLS_MAX_REGION_COUNT 2048
+#define DLS_MAX_INST_COUNT 256
+#define MAX_DLS_WAVE_SIZE (1024*1024)
/*------------------------------------
* typedefs
@@ -147,230 +147,230 @@ extern double log10(double x);
/* offsets to articulation data */
typedef enum
{
- PARAM_MODIFIED = 0,
- PARAM_MOD_LFO_FREQ,
- PARAM_MOD_LFO_DELAY,
-
- PARAM_VIB_LFO_FREQ,
- PARAM_VIB_LFO_DELAY,
-
- PARAM_VOL_EG_DELAY,
- PARAM_VOL_EG_ATTACK,
- PARAM_VOL_EG_HOLD,
- PARAM_VOL_EG_DECAY,
- PARAM_VOL_EG_SUSTAIN,
- PARAM_VOL_EG_RELEASE,
- PARAM_VOL_EG_SHUTDOWN,
- PARAM_VOL_EG_VEL_TO_ATTACK,
- PARAM_VOL_EG_KEY_TO_DECAY,
- PARAM_VOL_EG_KEY_TO_HOLD,
-
- PARAM_MOD_EG_DELAY,
- PARAM_MOD_EG_ATTACK,
- PARAM_MOD_EG_HOLD,
- PARAM_MOD_EG_DECAY,
- PARAM_MOD_EG_SUSTAIN,
- PARAM_MOD_EG_RELEASE,
- PARAM_MOD_EG_VEL_TO_ATTACK,
- PARAM_MOD_EG_KEY_TO_DECAY,
- PARAM_MOD_EG_KEY_TO_HOLD,
-
- PARAM_INITIAL_FC,
- PARAM_INITIAL_Q,
- PARAM_MOD_LFO_TO_FC,
- PARAM_MOD_LFO_CC1_TO_FC,
- PARAM_MOD_LFO_CHAN_PRESS_TO_FC,
- PARAM_MOD_EG_TO_FC,
- PARAM_VEL_TO_FC,
- PARAM_KEYNUM_TO_FC,
-
- PARAM_MOD_LFO_TO_GAIN,
- PARAM_MOD_LFO_CC1_TO_GAIN,
- PARAM_MOD_LFO_CHAN_PRESS_TO_GAIN,
- PARAM_VEL_TO_GAIN,
-
- PARAM_TUNING,
- PARAM_KEYNUM_TO_PITCH,
- PARAM_VIB_LFO_TO_PITCH,
- PARAM_VIB_LFO_CC1_TO_PITCH,
- PARAM_VIB_LFO_CHAN_PRESS_TO_PITCH,
- PARAM_MOD_LFO_TO_PITCH,
- PARAM_MOD_LFO_CC1_TO_PITCH,
- PARAM_MOD_LFO_CHAN_PRESS_TO_PITCH,
- PARAM_MOD_EG_TO_PITCH,
-
- PARAM_DEFAULT_PAN,
- PARAM_MIDI_CC91_TO_REVERB_SEND,
- PARAM_DEFAULT_REVERB_SEND,
- PARAM_MIDI_CC93_TO_CHORUS_SEND,
- PARAM_DEFAULT_CHORUS_SEND,
- PARAM_TABLE_SIZE
+ PARAM_MODIFIED = 0,
+ PARAM_MOD_LFO_FREQ,
+ PARAM_MOD_LFO_DELAY,
+
+ PARAM_VIB_LFO_FREQ,
+ PARAM_VIB_LFO_DELAY,
+
+ PARAM_VOL_EG_DELAY,
+ PARAM_VOL_EG_ATTACK,
+ PARAM_VOL_EG_HOLD,
+ PARAM_VOL_EG_DECAY,
+ PARAM_VOL_EG_SUSTAIN,
+ PARAM_VOL_EG_RELEASE,
+ PARAM_VOL_EG_SHUTDOWN,
+ PARAM_VOL_EG_VEL_TO_ATTACK,
+ PARAM_VOL_EG_KEY_TO_DECAY,
+ PARAM_VOL_EG_KEY_TO_HOLD,
+
+ PARAM_MOD_EG_DELAY,
+ PARAM_MOD_EG_ATTACK,
+ PARAM_MOD_EG_HOLD,
+ PARAM_MOD_EG_DECAY,
+ PARAM_MOD_EG_SUSTAIN,
+ PARAM_MOD_EG_RELEASE,
+ PARAM_MOD_EG_VEL_TO_ATTACK,
+ PARAM_MOD_EG_KEY_TO_DECAY,
+ PARAM_MOD_EG_KEY_TO_HOLD,
+
+ PARAM_INITIAL_FC,
+ PARAM_INITIAL_Q,
+ PARAM_MOD_LFO_TO_FC,
+ PARAM_MOD_LFO_CC1_TO_FC,
+ PARAM_MOD_LFO_CHAN_PRESS_TO_FC,
+ PARAM_MOD_EG_TO_FC,
+ PARAM_VEL_TO_FC,
+ PARAM_KEYNUM_TO_FC,
+
+ PARAM_MOD_LFO_TO_GAIN,
+ PARAM_MOD_LFO_CC1_TO_GAIN,
+ PARAM_MOD_LFO_CHAN_PRESS_TO_GAIN,
+ PARAM_VEL_TO_GAIN,
+
+ PARAM_TUNING,
+ PARAM_KEYNUM_TO_PITCH,
+ PARAM_VIB_LFO_TO_PITCH,
+ PARAM_VIB_LFO_CC1_TO_PITCH,
+ PARAM_VIB_LFO_CHAN_PRESS_TO_PITCH,
+ PARAM_MOD_LFO_TO_PITCH,
+ PARAM_MOD_LFO_CC1_TO_PITCH,
+ PARAM_MOD_LFO_CHAN_PRESS_TO_PITCH,
+ PARAM_MOD_EG_TO_PITCH,
+
+ PARAM_DEFAULT_PAN,
+ PARAM_MIDI_CC91_TO_REVERB_SEND,
+ PARAM_DEFAULT_REVERB_SEND,
+ PARAM_MIDI_CC93_TO_CHORUS_SEND,
+ PARAM_DEFAULT_CHORUS_SEND,
+ PARAM_TABLE_SIZE
} E_ART_INDEX;
/* temporary data structure combining region, articulation, and envelope data */
typedef struct s_art_dls_tag
{
- EAS_I16 values[PARAM_TABLE_SIZE];
+ EAS_I16 values[PARAM_TABLE_SIZE];
} S_DLS_ART_VALUES;
/* temporary data structure for wlnk chunk data */
typedef struct
{
- EAS_I32 gain;
- EAS_U32 loopStart;
- EAS_U32 loopLength;
- EAS_U32 sampleRate;
- EAS_U16 bitsPerSample;
- EAS_I16 fineTune;
- EAS_U8 unityNote;
+ EAS_I32 gain;
+ EAS_U32 loopStart;
+ EAS_U32 loopLength;
+ EAS_U32 sampleRate;
+ EAS_U16 bitsPerSample;
+ EAS_I16 fineTune;
+ EAS_U8 unityNote;
} S_WSMP_DATA;
/* temporary data structure used while parsing a DLS file */
typedef struct
{
- S_DLS *pDLS;
- EAS_HW_DATA_HANDLE hwInstData;
- EAS_FILE_HANDLE fileHandle;
- S_WSMP_DATA *wsmpData;
- EAS_U32 instCount;
- EAS_U32 regionCount;
- EAS_U32 artCount;
- EAS_U32 waveCount;
- EAS_U32 wavePoolSize;
- EAS_U32 wavePoolOffset;
- EAS_BOOL bigEndian;
- EAS_BOOL filterUsed;
+ S_DLS *pDLS;
+ EAS_HW_DATA_HANDLE hwInstData;
+ EAS_FILE_HANDLE fileHandle;
+ S_WSMP_DATA *wsmpData;
+ EAS_U32 instCount;
+ EAS_U32 regionCount;
+ EAS_U32 artCount;
+ EAS_U32 waveCount;
+ EAS_U32 wavePoolSize;
+ EAS_U32 wavePoolOffset;
+ EAS_BOOL bigEndian;
+ EAS_BOOL filterUsed;
} SDLS_SYNTHESIZER_DATA;
/* connection lookup table */
typedef struct s_connection_tag
{
- EAS_U16 source;
- EAS_U16 control;
- EAS_U16 destination;
- EAS_U16 connection;
+ EAS_U16 source;
+ EAS_U16 control;
+ EAS_U16 destination;
+ EAS_U16 connection;
} S_CONNECTION;
-static const S_CONNECTION connTable[] =
+static const S_CONNECTION connTable[] =
{
- { CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_LFO_FREQUENCY, PARAM_MOD_LFO_FREQ },
- { CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_LFO_STARTDELAY, PARAM_MOD_LFO_DELAY},
-
- { CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_VIB_FREQUENCY, PARAM_VIB_LFO_FREQ },
- { CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_VIB_STARTDELAY, PARAM_VIB_LFO_DELAY },
-
- { CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_EG1_DELAYTIME, PARAM_VOL_EG_DELAY },
- { CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_EG1_ATTACKTIME, PARAM_VOL_EG_ATTACK },
- { CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_EG1_HOLDTIME, PARAM_VOL_EG_HOLD },
- { CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_EG1_DECAYTIME, PARAM_VOL_EG_DECAY },
- { CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_EG1_SUSTAINLEVEL, PARAM_VOL_EG_SUSTAIN },
- { CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_EG1_RELEASETIME, PARAM_VOL_EG_RELEASE },
- { CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_EG1_SHUTDOWNTIME, PARAM_VOL_EG_SHUTDOWN },
- { CONN_SRC_KEYONVELOCITY, CONN_SRC_NONE, CONN_DST_EG1_ATTACKTIME, PARAM_VOL_EG_VEL_TO_ATTACK },
- { CONN_SRC_KEYNUMBER, CONN_SRC_NONE, CONN_DST_EG1_DECAYTIME, PARAM_VOL_EG_KEY_TO_DECAY },
- { CONN_SRC_KEYNUMBER, CONN_SRC_NONE, CONN_DST_EG1_HOLDTIME, PARAM_VOL_EG_KEY_TO_HOLD },
-
- { CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_EG2_DELAYTIME, PARAM_MOD_EG_DELAY },
- { CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_EG2_ATTACKTIME, PARAM_MOD_EG_ATTACK },
- { CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_EG2_HOLDTIME, PARAM_MOD_EG_HOLD },
- { CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_EG2_DECAYTIME, PARAM_MOD_EG_DECAY },
- { CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_EG2_SUSTAINLEVEL, PARAM_MOD_EG_SUSTAIN },
- { CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_EG2_RELEASETIME, PARAM_MOD_EG_RELEASE },
- { CONN_SRC_KEYONVELOCITY, CONN_SRC_NONE, CONN_DST_EG2_ATTACKTIME, PARAM_MOD_EG_VEL_TO_ATTACK },
- { CONN_SRC_KEYNUMBER, CONN_SRC_NONE, CONN_DST_EG2_DECAYTIME, PARAM_MOD_EG_KEY_TO_DECAY },
- { CONN_SRC_KEYNUMBER, CONN_SRC_NONE, CONN_DST_EG2_HOLDTIME, PARAM_MOD_EG_KEY_TO_HOLD },
-
- { CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_FILTER_CUTOFF, PARAM_INITIAL_FC },
- { CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_FILTER_Q, PARAM_INITIAL_Q },
- { CONN_SRC_LFO, CONN_SRC_NONE, CONN_DST_FILTER_CUTOFF, PARAM_MOD_LFO_TO_FC },
- { CONN_SRC_LFO, CONN_SRC_CC1, CONN_DST_FILTER_CUTOFF, PARAM_MOD_LFO_CC1_TO_FC },
- { CONN_SRC_LFO, CONN_SRC_CHANNELPRESSURE, CONN_DST_FILTER_CUTOFF, PARAM_MOD_LFO_CHAN_PRESS_TO_FC },
- { CONN_SRC_EG2, CONN_SRC_NONE, CONN_DST_FILTER_CUTOFF, PARAM_MOD_EG_TO_FC },
- { CONN_SRC_KEYONVELOCITY, CONN_SRC_NONE, CONN_DST_FILTER_CUTOFF, PARAM_VEL_TO_FC },
- { CONN_SRC_KEYNUMBER, CONN_SRC_NONE, CONN_DST_FILTER_CUTOFF, PARAM_KEYNUM_TO_FC },
-
- { CONN_SRC_LFO, CONN_SRC_NONE, CONN_DST_GAIN, PARAM_MOD_LFO_TO_GAIN },
- { CONN_SRC_LFO, CONN_SRC_CC1, CONN_DST_GAIN, PARAM_MOD_LFO_CC1_TO_GAIN },
- { CONN_SRC_LFO, CONN_SRC_CHANNELPRESSURE, CONN_DST_GAIN, PARAM_MOD_LFO_CHAN_PRESS_TO_GAIN },
- { CONN_SRC_KEYONVELOCITY, CONN_SRC_NONE, CONN_DST_GAIN, PARAM_VEL_TO_GAIN },
-
- { CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_PITCH, PARAM_TUNING },
- { CONN_SRC_KEYNUMBER, CONN_SRC_NONE, CONN_DST_PITCH, PARAM_KEYNUM_TO_PITCH },
- { CONN_SRC_VIBRATO, CONN_SRC_NONE, CONN_DST_PITCH, PARAM_VIB_LFO_TO_PITCH },
- { CONN_SRC_VIBRATO, CONN_SRC_CC1, CONN_DST_PITCH, PARAM_VIB_LFO_CC1_TO_PITCH },
- { CONN_SRC_VIBRATO, CONN_SRC_CHANNELPRESSURE, CONN_DST_PITCH, PARAM_VIB_LFO_CHAN_PRESS_TO_PITCH },
- { CONN_SRC_LFO, CONN_SRC_NONE, CONN_DST_PITCH, PARAM_MOD_LFO_TO_PITCH },
- { CONN_SRC_LFO, CONN_SRC_CC1, CONN_DST_PITCH, PARAM_MOD_LFO_CC1_TO_PITCH },
- { CONN_SRC_LFO, CONN_SRC_CHANNELPRESSURE, CONN_DST_PITCH, PARAM_MOD_LFO_CHAN_PRESS_TO_PITCH },
- { CONN_SRC_EG2, CONN_SRC_NONE, CONN_DST_PITCH, PARAM_MOD_EG_TO_PITCH },
-
- { CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_PAN, PARAM_DEFAULT_PAN },
- { CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_REVERB, PARAM_DEFAULT_REVERB_SEND },
- { CONN_SRC_CC91, CONN_SRC_NONE, CONN_DST_REVERB, PARAM_MIDI_CC91_TO_REVERB_SEND },
- { CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_CHORUS, PARAM_DEFAULT_CHORUS_SEND },
- { CONN_SRC_CC93, CONN_SRC_NONE, CONN_DST_REVERB, PARAM_MIDI_CC93_TO_CHORUS_SEND }
+ { CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_LFO_FREQUENCY, PARAM_MOD_LFO_FREQ },
+ { CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_LFO_STARTDELAY, PARAM_MOD_LFO_DELAY},
+
+ { CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_VIB_FREQUENCY, PARAM_VIB_LFO_FREQ },
+ { CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_VIB_STARTDELAY, PARAM_VIB_LFO_DELAY },
+
+ { CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_EG1_DELAYTIME, PARAM_VOL_EG_DELAY },
+ { CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_EG1_ATTACKTIME, PARAM_VOL_EG_ATTACK },
+ { CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_EG1_HOLDTIME, PARAM_VOL_EG_HOLD },
+ { CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_EG1_DECAYTIME, PARAM_VOL_EG_DECAY },
+ { CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_EG1_SUSTAINLEVEL, PARAM_VOL_EG_SUSTAIN },
+ { CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_EG1_RELEASETIME, PARAM_VOL_EG_RELEASE },
+ { CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_EG1_SHUTDOWNTIME, PARAM_VOL_EG_SHUTDOWN },
+ { CONN_SRC_KEYONVELOCITY, CONN_SRC_NONE, CONN_DST_EG1_ATTACKTIME, PARAM_VOL_EG_VEL_TO_ATTACK },
+ { CONN_SRC_KEYNUMBER, CONN_SRC_NONE, CONN_DST_EG1_DECAYTIME, PARAM_VOL_EG_KEY_TO_DECAY },
+ { CONN_SRC_KEYNUMBER, CONN_SRC_NONE, CONN_DST_EG1_HOLDTIME, PARAM_VOL_EG_KEY_TO_HOLD },
+
+ { CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_EG2_DELAYTIME, PARAM_MOD_EG_DELAY },
+ { CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_EG2_ATTACKTIME, PARAM_MOD_EG_ATTACK },
+ { CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_EG2_HOLDTIME, PARAM_MOD_EG_HOLD },
+ { CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_EG2_DECAYTIME, PARAM_MOD_EG_DECAY },
+ { CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_EG2_SUSTAINLEVEL, PARAM_MOD_EG_SUSTAIN },
+ { CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_EG2_RELEASETIME, PARAM_MOD_EG_RELEASE },
+ { CONN_SRC_KEYONVELOCITY, CONN_SRC_NONE, CONN_DST_EG2_ATTACKTIME, PARAM_MOD_EG_VEL_TO_ATTACK },
+ { CONN_SRC_KEYNUMBER, CONN_SRC_NONE, CONN_DST_EG2_DECAYTIME, PARAM_MOD_EG_KEY_TO_DECAY },
+ { CONN_SRC_KEYNUMBER, CONN_SRC_NONE, CONN_DST_EG2_HOLDTIME, PARAM_MOD_EG_KEY_TO_HOLD },
+
+ { CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_FILTER_CUTOFF, PARAM_INITIAL_FC },
+ { CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_FILTER_Q, PARAM_INITIAL_Q },
+ { CONN_SRC_LFO, CONN_SRC_NONE, CONN_DST_FILTER_CUTOFF, PARAM_MOD_LFO_TO_FC },
+ { CONN_SRC_LFO, CONN_SRC_CC1, CONN_DST_FILTER_CUTOFF, PARAM_MOD_LFO_CC1_TO_FC },
+ { CONN_SRC_LFO, CONN_SRC_CHANNELPRESSURE, CONN_DST_FILTER_CUTOFF, PARAM_MOD_LFO_CHAN_PRESS_TO_FC },
+ { CONN_SRC_EG2, CONN_SRC_NONE, CONN_DST_FILTER_CUTOFF, PARAM_MOD_EG_TO_FC },
+ { CONN_SRC_KEYONVELOCITY, CONN_SRC_NONE, CONN_DST_FILTER_CUTOFF, PARAM_VEL_TO_FC },
+ { CONN_SRC_KEYNUMBER, CONN_SRC_NONE, CONN_DST_FILTER_CUTOFF, PARAM_KEYNUM_TO_FC },
+
+ { CONN_SRC_LFO, CONN_SRC_NONE, CONN_DST_GAIN, PARAM_MOD_LFO_TO_GAIN },
+ { CONN_SRC_LFO, CONN_SRC_CC1, CONN_DST_GAIN, PARAM_MOD_LFO_CC1_TO_GAIN },
+ { CONN_SRC_LFO, CONN_SRC_CHANNELPRESSURE, CONN_DST_GAIN, PARAM_MOD_LFO_CHAN_PRESS_TO_GAIN },
+ { CONN_SRC_KEYONVELOCITY, CONN_SRC_NONE, CONN_DST_GAIN, PARAM_VEL_TO_GAIN },
+
+ { CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_PITCH, PARAM_TUNING },
+ { CONN_SRC_KEYNUMBER, CONN_SRC_NONE, CONN_DST_PITCH, PARAM_KEYNUM_TO_PITCH },
+ { CONN_SRC_VIBRATO, CONN_SRC_NONE, CONN_DST_PITCH, PARAM_VIB_LFO_TO_PITCH },
+ { CONN_SRC_VIBRATO, CONN_SRC_CC1, CONN_DST_PITCH, PARAM_VIB_LFO_CC1_TO_PITCH },
+ { CONN_SRC_VIBRATO, CONN_SRC_CHANNELPRESSURE, CONN_DST_PITCH, PARAM_VIB_LFO_CHAN_PRESS_TO_PITCH },
+ { CONN_SRC_LFO, CONN_SRC_NONE, CONN_DST_PITCH, PARAM_MOD_LFO_TO_PITCH },
+ { CONN_SRC_LFO, CONN_SRC_CC1, CONN_DST_PITCH, PARAM_MOD_LFO_CC1_TO_PITCH },
+ { CONN_SRC_LFO, CONN_SRC_CHANNELPRESSURE, CONN_DST_PITCH, PARAM_MOD_LFO_CHAN_PRESS_TO_PITCH },
+ { CONN_SRC_EG2, CONN_SRC_NONE, CONN_DST_PITCH, PARAM_MOD_EG_TO_PITCH },
+
+ { CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_PAN, PARAM_DEFAULT_PAN },
+ { CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_REVERB, PARAM_DEFAULT_REVERB_SEND },
+ { CONN_SRC_CC91, CONN_SRC_NONE, CONN_DST_REVERB, PARAM_MIDI_CC91_TO_REVERB_SEND },
+ { CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_CHORUS, PARAM_DEFAULT_CHORUS_SEND },
+ { CONN_SRC_CC93, CONN_SRC_NONE, CONN_DST_REVERB, PARAM_MIDI_CC93_TO_CHORUS_SEND }
};
#define ENTRIES_IN_CONN_TABLE (sizeof(connTable)/sizeof(S_CONNECTION))
static const S_DLS_ART_VALUES defaultArt =
{
- 0, /* not modified */
- -851, /* Mod LFO frequency: 5 Hz */
- -7973, /* Mod LFO delay: 10 milliseconds */
-
- -851, /* Vib LFO frequency: 5 Hz */
- -7973, /* Vib LFO delay: 10 milliseconds */
-
- -32768, /* EG1 delay time: 0 secs */
- -32768, /* EG1 attack time: 0 secs */
- -32768, /* EG1 hold time: 0 secs */
- -32768, /* EG1 decay time: 0 secs */
- 1000, /* EG1 sustain level: 100.0% */
- -32768, /* EG1 release time: 0 secs */
- -7271, /* EG1 shutdown time: 15 msecs */
- 0, /* EG1 velocity to attack: 0 time cents */
- 0, /* EG1 key number to decay: 0 time cents */
- 0, /* EG1 key number to hold: 0 time cents */
-
- -32768, /* EG2 delay time: 0 secs */
- -32768, /* EG2 attack time: 0 secs */
- -32768, /* EG2 hold time: 0 secs */
- -32768, /* EG2 decay time: 0 secs */
- 1000, /* EG2 sustain level: 100.0% */
- -32768, /* EG2 release time: 0 secs */
- 0, /* EG2 velocity to attack: 0 time cents */
- 0, /* EG2 key number to decay: 0 time cents */
- 0, /* EG2 key number to hold: 0 time cents */
-
- 0x7fff, /* Initial Fc: Disabled */
- 0, /* Initial Q: 0 dB */
- 0, /* Mod LFO to Fc: 0 cents */
- 0, /* Mod LFO CC1 to Fc: 0 cents */
- 0, /* Mod LFO channel pressure to Fc: 0 cents */
- 0, /* EG2 to Fc: 0 cents */
- 0, /* Velocity to Fc: 0 cents */
- 0, /* Key number to Fc: 0 cents */
-
- 0, /* Mod LFO to gain: 0 dB */
- 0, /* Mod LFO CC1 to gain: 0 dB */
- 0, /* Mod LFO channel pressure to gain: 0 dB */
- 960, /* Velocity to gain: 96 dB */
-
- 0, /* Tuning: 0 cents */
- 12800, /* Key number to pitch: 12,800 cents */
- 0, /* Vibrato to pitch: 0 cents */
- 0, /* Vibrato CC1 to pitch: 0 cents */
- 0, /* Vibrato channel pressure to pitch: 0 cents */
- 0, /* Mod LFO to pitch: 0 cents */
- 0, /* Mod LFO CC1 to pitch: 0 cents */
- 0, /* Mod LFO channel pressure to pitch: 0 cents */
- 0, /* Mod EG to pitch: 0 cents */
-
- 0, /* Default pan: 0.0% */
- 0, /* Default reverb send: 0.0% */
- 1000, /* Default CC91 to reverb send: 100.0% */
- 0, /* Default chorus send: 0.0% */
- 1000 /* Default CC93 to chorus send: 100.0% */
+ 0, /* not modified */
+ -851, /* Mod LFO frequency: 5 Hz */
+ -7973, /* Mod LFO delay: 10 milliseconds */
+
+ -851, /* Vib LFO frequency: 5 Hz */
+ -7973, /* Vib LFO delay: 10 milliseconds */
+
+ -32768, /* EG1 delay time: 0 secs */
+ -32768, /* EG1 attack time: 0 secs */
+ -32768, /* EG1 hold time: 0 secs */
+ -32768, /* EG1 decay time: 0 secs */
+ 1000, /* EG1 sustain level: 100.0% */
+ -32768, /* EG1 release time: 0 secs */
+ -7271, /* EG1 shutdown time: 15 msecs */
+ 0, /* EG1 velocity to attack: 0 time cents */
+ 0, /* EG1 key number to decay: 0 time cents */
+ 0, /* EG1 key number to hold: 0 time cents */
+
+ -32768, /* EG2 delay time: 0 secs */
+ -32768, /* EG2 attack time: 0 secs */
+ -32768, /* EG2 hold time: 0 secs */
+ -32768, /* EG2 decay time: 0 secs */
+ 1000, /* EG2 sustain level: 100.0% */
+ -32768, /* EG2 release time: 0 secs */
+ 0, /* EG2 velocity to attack: 0 time cents */
+ 0, /* EG2 key number to decay: 0 time cents */
+ 0, /* EG2 key number to hold: 0 time cents */
+
+ 0x7fff, /* Initial Fc: Disabled */
+ 0, /* Initial Q: 0 dB */
+ 0, /* Mod LFO to Fc: 0 cents */
+ 0, /* Mod LFO CC1 to Fc: 0 cents */
+ 0, /* Mod LFO channel pressure to Fc: 0 cents */
+ 0, /* EG2 to Fc: 0 cents */
+ 0, /* Velocity to Fc: 0 cents */
+ 0, /* Key number to Fc: 0 cents */
+
+ 0, /* Mod LFO to gain: 0 dB */
+ 0, /* Mod LFO CC1 to gain: 0 dB */
+ 0, /* Mod LFO channel pressure to gain: 0 dB */
+ 960, /* Velocity to gain: 96 dB */
+
+ 0, /* Tuning: 0 cents */
+ 12800, /* Key number to pitch: 12,800 cents */
+ 0, /* Vibrato to pitch: 0 cents */
+ 0, /* Vibrato CC1 to pitch: 0 cents */
+ 0, /* Vibrato channel pressure to pitch: 0 cents */
+ 0, /* Mod LFO to pitch: 0 cents */
+ 0, /* Mod LFO CC1 to pitch: 0 cents */
+ 0, /* Mod LFO channel pressure to pitch: 0 cents */
+ 0, /* Mod EG to pitch: 0 cents */
+
+ 0, /* Default pan: 0.0% */
+ 0, /* Default reverb send: 0.0% */
+ 1000, /* Default CC91 to reverb send: 100.0% */
+ 0, /* Default chorus send: 0.0% */
+ 1000 /* Default CC93 to chorus send: 100.0% */
};
/*------------------------------------
@@ -396,7 +396,7 @@ static const EAS_I32 dlsLFOFrequencyConvert = DLS_LFO_FREQUENCY_CONVERT;
*/
EAS_INLINE void *PtrOfs (void *p, EAS_I32 offset)
{
- return (void*) (((EAS_U8*) p) + offset);
+ return (void*) (((EAS_U8*) p) + offset);
}
/*------------------------------------
@@ -435,13 +435,13 @@ static void DumpDLS (S_EAS *pEAS);
/*----------------------------------------------------------------------------
* DLSParser ()
*----------------------------------------------------------------------------
- * Purpose:
- *
- * Inputs:
+ * Purpose:
+ *
+ * Inputs:
* pEASData - pointer to over EAS data instance
* fileHandle - file handle for input file
* offset - offset into file where DLS data starts
- *
+ *
* Outputs:
* EAS_RESULT
* ppEAS - address of pointer to alternate EAS wavetable
@@ -450,268 +450,268 @@ static void DumpDLS (S_EAS *pEAS);
*/
EAS_RESULT DLSParser (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE fileHandle, EAS_I32 offset, EAS_DLSLIB_HANDLE *ppDLS)
{
- EAS_RESULT result;
- SDLS_SYNTHESIZER_DATA dls;
- EAS_U32 temp;
- EAS_I32 pos;
- EAS_I32 chunkPos;
- EAS_I32 size;
- EAS_I32 instSize;
- EAS_I32 rgnPoolSize;
- EAS_I32 artPoolSize;
- EAS_I32 waveLenSize;
- EAS_I32 endDLS;
- EAS_I32 wvplPos;
- EAS_I32 wvplSize;
- EAS_I32 linsPos;
- EAS_I32 linsSize;
- EAS_I32 ptblPos;
- EAS_I32 ptblSize;
- void *p;
-
- /* zero counts and pointers */
- EAS_HWMemSet(&dls, 0, sizeof(dls));
-
- /* save file handle and hwInstData to save copying pointers around */
- dls.hwInstData = hwInstData;
- dls.fileHandle = fileHandle;
-
- /* NULL return value in case of error */
- *ppDLS = NULL;
-
- /* seek to start of DLS and read in RIFF tag and set processor endian flag */
- if ((result = EAS_HWFileSeek(dls.hwInstData, dls.fileHandle, offset)) != EAS_SUCCESS)
- return result;
- if ((result = EAS_HWReadFile(dls.hwInstData, dls.fileHandle, &temp, sizeof(temp), &size)) != EAS_SUCCESS)
- return result;
-
- /* check for processor endian-ness */
- dls.bigEndian = (temp == CHUNK_RIFF);
-
- /* first chunk should be DLS */
- pos = offset;
- if ((result = NextChunk(&dls, &pos, &temp, &size)) != EAS_SUCCESS)
- return result;
- if (temp != CHUNK_DLS)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Expected DLS chunk, got %08lx\n", temp); */ }
- return EAS_ERROR_FILE_FORMAT;
- }
-
- /* no instrument or wavepool chunks */
- linsSize = wvplSize = ptblSize = linsPos = wvplPos = ptblPos = 0;
-
- /* scan the chunks in the DLS list */
- endDLS = offset + size;
- pos = offset + 12;
- while (pos < endDLS)
- {
- chunkPos = pos;
-
- /* get the next chunk type */
- if ((result = NextChunk(&dls, &pos, &temp, &size)) != EAS_SUCCESS)
- return result;
-
- /* parse useful chunks */
- switch (temp)
- {
- case CHUNK_CDL:
- if ((result = Parse_cdl(&dls, size, &temp)) != EAS_SUCCESS)
- return result;
- if (!temp)
- return EAS_ERROR_UNRECOGNIZED_FORMAT;
- break;
-
- case CHUNK_LINS:
- linsPos = chunkPos + 12;
- linsSize = size - 4;
- break;
-
- case CHUNK_WVPL:
- wvplPos = chunkPos + 12;
- wvplSize = size - 4;
- break;
-
- case CHUNK_PTBL:
- ptblPos = chunkPos + 8;
- ptblSize = size - 4;
- break;
-
- default:
- break;
- }
- }
-
- /* must have a lins chunk */
- if (linsSize == 0)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "No lins chunk found"); */ }
- return EAS_ERROR_UNRECOGNIZED_FORMAT;
- }
-
- /* must have a wvpl chunk */
- if (wvplSize == 0)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "No wvpl chunk found"); */ }
- return EAS_ERROR_UNRECOGNIZED_FORMAT;
- }
-
- /* must have a ptbl chunk */
- if ((ptblSize == 0) || (ptblSize > DLS_MAX_WAVE_COUNT * sizeof(POOLCUE) + sizeof(POOLTABLE)))
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "No ptbl chunk found"); */ }
- return EAS_ERROR_UNRECOGNIZED_FORMAT;
- }
-
- /* pre-parse the wave pool chunk */
- if ((result = Parse_ptbl(&dls, ptblPos, wvplPos, wvplSize)) != EAS_SUCCESS)
- return result;
-
- /* limit check */
- if ((dls.waveCount == 0) || (dls.waveCount > DLS_MAX_WAVE_COUNT))
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "DLS file contains invalid #waves [%u]\n", dls.waveCount); */ }
- return EAS_ERROR_FILE_FORMAT;
- }
-
- /* allocate memory for wsmp data */
- dls.wsmpData = EAS_HWMalloc(dls.hwInstData, (EAS_I32) (sizeof(S_WSMP_DATA) * dls.waveCount));
- if (dls.wsmpData == NULL)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "EAS_HWMalloc for wsmp data failed\n"); */ }
- return EAS_ERROR_MALLOC_FAILED;
- }
- EAS_HWMemSet(dls.wsmpData, 0, (EAS_I32) (sizeof(S_WSMP_DATA) * dls.waveCount));
-
- /* pre-parse the lins chunk */
- result = Parse_lins(&dls, linsPos, linsSize);
- if (result == EAS_SUCCESS)
- {
-
- /* limit check */
- if ((dls.regionCount == 0) || (dls.regionCount > DLS_MAX_REGION_COUNT))
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "DLS file contains invalid #regions [%u]\n", dls.regionCount); */ }
- return EAS_ERROR_FILE_FORMAT;
- }
-
- /* limit check */
- if ((dls.artCount == 0) || (dls.artCount > DLS_MAX_ART_COUNT))
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "DLS file contains invalid #articulations [%u]\n", dls.regionCount); */ }
- return EAS_ERROR_FILE_FORMAT;
- }
-
- /* limit check */
- if ((dls.instCount == 0) || (dls.instCount > DLS_MAX_INST_COUNT))
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "DLS file contains invalid #instruments [%u]\n", dls.instCount); */ }
- return EAS_ERROR_FILE_FORMAT;
- }
-
- /* Allocate memory for the converted DLS data */
- /* calculate size of instrument data */
- instSize = (EAS_I32) (sizeof(S_PROGRAM) * dls.instCount);
-
- /* calculate size of region pool */
- rgnPoolSize = (EAS_I32) (sizeof(S_DLS_REGION) * dls.regionCount);
-
- /* calculate size of articulation pool, add one for default articulation */
- dls.artCount++;
- artPoolSize = (EAS_I32) (sizeof(S_DLS_ARTICULATION) * dls.artCount);
-
- /* calculate size of wave length and offset arrays */
- waveLenSize = (EAS_I32) (dls.waveCount * sizeof(EAS_U32));
-
- /* calculate final memory size */
- size = (EAS_I32) sizeof(S_EAS) + instSize + rgnPoolSize + artPoolSize + (2 * waveLenSize) + (EAS_I32) dls.wavePoolSize;
- if (size <= 0) {
- return EAS_ERROR_FILE_FORMAT;
- }
-
- /* allocate the main EAS chunk */
- dls.pDLS = EAS_HWMalloc(dls.hwInstData, size);
- if (dls.pDLS == NULL)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "EAS_HWMalloc failed for DLS memory allocation size %ld\n", size); */ }
- return EAS_ERROR_MALLOC_FAILED;
- }
- EAS_HWMemSet(dls.pDLS, 0, size);
- dls.pDLS->refCount = 1;
- p = PtrOfs(dls.pDLS, sizeof(S_EAS));
-
- /* setup pointer to programs */
- dls.pDLS->numDLSPrograms = (EAS_U16) dls.instCount;
- dls.pDLS->pDLSPrograms = p;
- p = PtrOfs(p, instSize);
-
- /* setup pointer to regions */
- dls.pDLS->pDLSRegions = p;
- dls.pDLS->numDLSRegions = (EAS_U16) dls.regionCount;
- p = PtrOfs(p, rgnPoolSize);
-
- /* setup pointer to articulations */
- dls.pDLS->numDLSArticulations = (EAS_U16) dls.artCount;
- dls.pDLS->pDLSArticulations = p;
- p = PtrOfs(p, artPoolSize);
-
- /* setup pointer to wave length table */
- dls.pDLS->numDLSSamples = (EAS_U16) dls.waveCount;
- dls.pDLS->pDLSSampleLen = p;
- p = PtrOfs(p, waveLenSize);
-
- /* setup pointer to wave offsets table */
- dls.pDLS->pDLSSampleOffsets = p;
- p = PtrOfs(p, waveLenSize);
-
- /* setup pointer to wave pool */
- dls.pDLS->pDLSSamples = p;
-
- /* clear filter flag */
- dls.filterUsed = EAS_FALSE;
-
- /* parse the wave pool and load samples */
- result = Parse_ptbl(&dls, ptblPos, wvplPos, wvplSize);
- }
-
- /* create the default articulation */
- Convert_art(&dls, &defaultArt, 0);
- dls.artCount = 1;
-
- /* parse the lins chunk and load instruments */
- dls.regionCount = dls.instCount = 0;
- if (result == EAS_SUCCESS)
- result = Parse_lins(&dls, linsPos, linsSize);
-
- /* clean up any temporary objects that were allocated */
- if (dls.wsmpData)
- EAS_HWFree(dls.hwInstData, dls.wsmpData);
-
- /* if successful, return a pointer to the EAS collection */
- if (result == EAS_SUCCESS)
- {
- *ppDLS = dls.pDLS;
+ EAS_RESULT result;
+ SDLS_SYNTHESIZER_DATA dls;
+ EAS_U32 temp;
+ EAS_I32 pos;
+ EAS_I32 chunkPos;
+ EAS_I32 size;
+ EAS_I32 instSize;
+ EAS_I32 rgnPoolSize;
+ EAS_I32 artPoolSize;
+ EAS_I32 waveLenSize;
+ EAS_I32 endDLS;
+ EAS_I32 wvplPos;
+ EAS_I32 wvplSize;
+ EAS_I32 linsPos;
+ EAS_I32 linsSize;
+ EAS_I32 ptblPos;
+ EAS_I32 ptblSize;
+ void *p;
+
+ /* zero counts and pointers */
+ EAS_HWMemSet(&dls, 0, sizeof(dls));
+
+ /* save file handle and hwInstData to save copying pointers around */
+ dls.hwInstData = hwInstData;
+ dls.fileHandle = fileHandle;
+
+ /* NULL return value in case of error */
+ *ppDLS = NULL;
+
+ /* seek to start of DLS and read in RIFF tag and set processor endian flag */
+ if ((result = EAS_HWFileSeek(dls.hwInstData, dls.fileHandle, offset)) != EAS_SUCCESS)
+ return result;
+ if ((result = EAS_HWReadFile(dls.hwInstData, dls.fileHandle, &temp, sizeof(temp), &size)) != EAS_SUCCESS)
+ return result;
+
+ /* check for processor endian-ness */
+ dls.bigEndian = (temp == CHUNK_RIFF);
+
+ /* first chunk should be DLS */
+ pos = offset;
+ if ((result = NextChunk(&dls, &pos, &temp, &size)) != EAS_SUCCESS)
+ return result;
+ if (temp != CHUNK_DLS)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Expected DLS chunk, got %08lx\n", temp); */ }
+ return EAS_ERROR_FILE_FORMAT;
+ }
+
+ /* no instrument or wavepool chunks */
+ linsSize = wvplSize = ptblSize = linsPos = wvplPos = ptblPos = 0;
+
+ /* scan the chunks in the DLS list */
+ endDLS = offset + size;
+ pos = offset + 12;
+ while (pos < endDLS)
+ {
+ chunkPos = pos;
+
+ /* get the next chunk type */
+ if ((result = NextChunk(&dls, &pos, &temp, &size)) != EAS_SUCCESS)
+ return result;
+
+ /* parse useful chunks */
+ switch (temp)
+ {
+ case CHUNK_CDL:
+ if ((result = Parse_cdl(&dls, size, &temp)) != EAS_SUCCESS)
+ return result;
+ if (!temp)
+ return EAS_ERROR_UNRECOGNIZED_FORMAT;
+ break;
+
+ case CHUNK_LINS:
+ linsPos = chunkPos + 12;
+ linsSize = size - 4;
+ break;
+
+ case CHUNK_WVPL:
+ wvplPos = chunkPos + 12;
+ wvplSize = size - 4;
+ break;
+
+ case CHUNK_PTBL:
+ ptblPos = chunkPos + 8;
+ ptblSize = size - 4;
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ /* must have a lins chunk */
+ if (linsSize == 0)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "No lins chunk found"); */ }
+ return EAS_ERROR_UNRECOGNIZED_FORMAT;
+ }
+
+ /* must have a wvpl chunk */
+ if (wvplSize == 0)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "No wvpl chunk found"); */ }
+ return EAS_ERROR_UNRECOGNIZED_FORMAT;
+ }
+
+ /* must have a ptbl chunk */
+ if ((ptblSize == 0) || (ptblSize > DLS_MAX_WAVE_COUNT * sizeof(POOLCUE) + sizeof(POOLTABLE)))
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "No ptbl chunk found"); */ }
+ return EAS_ERROR_UNRECOGNIZED_FORMAT;
+ }
+
+ /* pre-parse the wave pool chunk */
+ if ((result = Parse_ptbl(&dls, ptblPos, wvplPos, wvplSize)) != EAS_SUCCESS)
+ return result;
+
+ /* limit check */
+ if ((dls.waveCount == 0) || (dls.waveCount > DLS_MAX_WAVE_COUNT))
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "DLS file contains invalid #waves [%u]\n", dls.waveCount); */ }
+ return EAS_ERROR_FILE_FORMAT;
+ }
+
+ /* allocate memory for wsmp data */
+ dls.wsmpData = EAS_HWMalloc(dls.hwInstData, (EAS_I32) (sizeof(S_WSMP_DATA) * dls.waveCount));
+ if (dls.wsmpData == NULL)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "EAS_HWMalloc for wsmp data failed\n"); */ }
+ return EAS_ERROR_MALLOC_FAILED;
+ }
+ EAS_HWMemSet(dls.wsmpData, 0, (EAS_I32) (sizeof(S_WSMP_DATA) * dls.waveCount));
+
+ /* pre-parse the lins chunk */
+ result = Parse_lins(&dls, linsPos, linsSize);
+ if (result == EAS_SUCCESS)
+ {
+
+ /* limit check */
+ if ((dls.regionCount == 0) || (dls.regionCount > DLS_MAX_REGION_COUNT))
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "DLS file contains invalid #regions [%u]\n", dls.regionCount); */ }
+ return EAS_ERROR_FILE_FORMAT;
+ }
+
+ /* limit check */
+ if ((dls.artCount == 0) || (dls.artCount > DLS_MAX_ART_COUNT))
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "DLS file contains invalid #articulations [%u]\n", dls.regionCount); */ }
+ return EAS_ERROR_FILE_FORMAT;
+ }
+
+ /* limit check */
+ if ((dls.instCount == 0) || (dls.instCount > DLS_MAX_INST_COUNT))
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "DLS file contains invalid #instruments [%u]\n", dls.instCount); */ }
+ return EAS_ERROR_FILE_FORMAT;
+ }
+
+ /* Allocate memory for the converted DLS data */
+ /* calculate size of instrument data */
+ instSize = (EAS_I32) (sizeof(S_PROGRAM) * dls.instCount);
+
+ /* calculate size of region pool */
+ rgnPoolSize = (EAS_I32) (sizeof(S_DLS_REGION) * dls.regionCount);
+
+ /* calculate size of articulation pool, add one for default articulation */
+ dls.artCount++;
+ artPoolSize = (EAS_I32) (sizeof(S_DLS_ARTICULATION) * dls.artCount);
+
+ /* calculate size of wave length and offset arrays */
+ waveLenSize = (EAS_I32) (dls.waveCount * sizeof(EAS_U32));
+
+ /* calculate final memory size */
+ size = (EAS_I32) sizeof(S_EAS) + instSize + rgnPoolSize + artPoolSize + (2 * waveLenSize) + (EAS_I32) dls.wavePoolSize;
+ if (size <= 0) {
+ return EAS_ERROR_FILE_FORMAT;
+ }
+
+ /* allocate the main EAS chunk */
+ dls.pDLS = EAS_HWMalloc(dls.hwInstData, size);
+ if (dls.pDLS == NULL)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "EAS_HWMalloc failed for DLS memory allocation size %ld\n", size); */ }
+ return EAS_ERROR_MALLOC_FAILED;
+ }
+ EAS_HWMemSet(dls.pDLS, 0, size);
+ dls.pDLS->refCount = 1;
+ p = PtrOfs(dls.pDLS, sizeof(S_EAS));
+
+ /* setup pointer to programs */
+ dls.pDLS->numDLSPrograms = (EAS_U16) dls.instCount;
+ dls.pDLS->pDLSPrograms = p;
+ p = PtrOfs(p, instSize);
+
+ /* setup pointer to regions */
+ dls.pDLS->pDLSRegions = p;
+ dls.pDLS->numDLSRegions = (EAS_U16) dls.regionCount;
+ p = PtrOfs(p, rgnPoolSize);
+
+ /* setup pointer to articulations */
+ dls.pDLS->numDLSArticulations = (EAS_U16) dls.artCount;
+ dls.pDLS->pDLSArticulations = p;
+ p = PtrOfs(p, artPoolSize);
+
+ /* setup pointer to wave length table */
+ dls.pDLS->numDLSSamples = (EAS_U16) dls.waveCount;
+ dls.pDLS->pDLSSampleLen = p;
+ p = PtrOfs(p, waveLenSize);
+
+ /* setup pointer to wave offsets table */
+ dls.pDLS->pDLSSampleOffsets = p;
+ p = PtrOfs(p, waveLenSize);
+
+ /* setup pointer to wave pool */
+ dls.pDLS->pDLSSamples = p;
+
+ /* clear filter flag */
+ dls.filterUsed = EAS_FALSE;
+
+ /* parse the wave pool and load samples */
+ result = Parse_ptbl(&dls, ptblPos, wvplPos, wvplSize);
+ }
+
+ /* create the default articulation */
+ Convert_art(&dls, &defaultArt, 0);
+ dls.artCount = 1;
+
+ /* parse the lins chunk and load instruments */
+ dls.regionCount = dls.instCount = 0;
+ if (result == EAS_SUCCESS)
+ result = Parse_lins(&dls, linsPos, linsSize);
+
+ /* clean up any temporary objects that were allocated */
+ if (dls.wsmpData)
+ EAS_HWFree(dls.hwInstData, dls.wsmpData);
+
+ /* if successful, return a pointer to the EAS collection */
+ if (result == EAS_SUCCESS)
+ {
+ *ppDLS = dls.pDLS;
#ifdef _DEBUG_DLS
- DumpDLS(dls.pDLS);
+ DumpDLS(dls.pDLS);
#endif
- }
+ }
- /* something went wrong, deallocate the EAS collection */
- else
- DLSCleanup(dls.hwInstData, dls.pDLS);
+ /* something went wrong, deallocate the EAS collection */
+ else
+ DLSCleanup(dls.hwInstData, dls.pDLS);
- return result;
+ return result;
}
/*----------------------------------------------------------------------------
* DLSCleanup ()
*----------------------------------------------------------------------------
- * Purpose:
- *
- * Inputs:
+ * Purpose:
+ *
+ * Inputs:
* pEASData - pointer to over EAS data instance
* pEAS - pointer to alternate EAS wavetable
- *
+ *
* Outputs:
* EAS_RESULT
*
@@ -720,16 +720,16 @@ EAS_RESULT DLSParser (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE fileHandle,
EAS_RESULT DLSCleanup (EAS_HW_DATA_HANDLE hwInstData, S_DLS *pDLS)
{
- /* free the allocated memory */
- if (pDLS)
- {
- if (pDLS->refCount)
- {
- if (--pDLS->refCount == 0)
- EAS_HWFree(hwInstData, pDLS);
- }
- }
- return EAS_SUCCESS;
+ /* free the allocated memory */
+ if (pDLS)
+ {
+ if (pDLS->refCount)
+ {
+ if (--pDLS->refCount == 0)
+ EAS_HWFree(hwInstData, pDLS);
+ }
+ }
+ return EAS_SUCCESS;
}
/*----------------------------------------------------------------------------
@@ -740,18 +740,18 @@ EAS_RESULT DLSCleanup (EAS_HW_DATA_HANDLE hwInstData, S_DLS *pDLS)
*/
void DLSAddRef (S_DLS *pDLS)
{
- if (pDLS)
- pDLS->refCount++;
+ if (pDLS)
+ pDLS->refCount++;
}
/*----------------------------------------------------------------------------
* NextChunk ()
*----------------------------------------------------------------------------
- * Purpose:
+ * Purpose:
* Returns the type and size of the next chunk in the file
*
- * Inputs:
- *
+ * Inputs:
+ *
* Outputs:
*
* Side Effects:
@@ -759,522 +759,522 @@ void DLSAddRef (S_DLS *pDLS)
*/
static EAS_RESULT NextChunk (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 *pPos, EAS_U32 *pChunkType, EAS_I32 *pSize)
{
- EAS_RESULT result;
-
- /* seek to start of chunk */
- if ((result = EAS_HWFileSeek(pDLSData->hwInstData, pDLSData->fileHandle, *pPos)) != EAS_SUCCESS)
- return result;
-
- /* read the chunk type */
- if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, pChunkType, EAS_TRUE)) != EAS_SUCCESS)
- return result;
-
- /* read the chunk size */
- if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, pSize, EAS_FALSE)) != EAS_SUCCESS)
- return result;
-
- /* get form type for RIFF and LIST types */
- if ((*pChunkType == CHUNK_RIFF) || (*pChunkType == CHUNK_LIST))
- {
-
- /* read the form type */
- if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, pChunkType, EAS_TRUE)) != EAS_SUCCESS)
- return result;
-
- }
-
- /* calculate start of next chunk */
- *pPos += *pSize + 8;
-
- /* adjust to word boundary */
- if (*pPos & 1)
- (*pPos)++;
-
- return EAS_SUCCESS;
+ EAS_RESULT result;
+
+ /* seek to start of chunk */
+ if ((result = EAS_HWFileSeek(pDLSData->hwInstData, pDLSData->fileHandle, *pPos)) != EAS_SUCCESS)
+ return result;
+
+ /* read the chunk type */
+ if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, pChunkType, EAS_TRUE)) != EAS_SUCCESS)
+ return result;
+
+ /* read the chunk size */
+ if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, pSize, EAS_FALSE)) != EAS_SUCCESS)
+ return result;
+
+ /* get form type for RIFF and LIST types */
+ if ((*pChunkType == CHUNK_RIFF) || (*pChunkType == CHUNK_LIST))
+ {
+
+ /* read the form type */
+ if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, pChunkType, EAS_TRUE)) != EAS_SUCCESS)
+ return result;
+
+ }
+
+ /* calculate start of next chunk */
+ *pPos += *pSize + 8;
+
+ /* adjust to word boundary */
+ if (*pPos & 1)
+ (*pPos)++;
+
+ return EAS_SUCCESS;
}
/*----------------------------------------------------------------------------
* Parse_ptbl ()
*----------------------------------------------------------------------------
- * Purpose:
- *
+ * Purpose:
+ *
*
* Inputs:
- *
- *
+ *
+ *
* Outputs:
- *
+ *
*
*----------------------------------------------------------------------------
*/
static EAS_RESULT Parse_ptbl (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 pos, EAS_I32 wtblPos, EAS_I32 wtblSize)
{
- EAS_RESULT result;
- EAS_U32 temp;
- EAS_FILE_HANDLE tempFile;
- EAS_U16 waveIndex;
+ EAS_RESULT result;
+ EAS_U32 temp;
+ EAS_FILE_HANDLE tempFile;
+ EAS_U16 waveIndex;
- /* seek to start of chunk */
- if ((result = EAS_HWFileSeek(pDLSData->hwInstData, pDLSData->fileHandle, pos)) != EAS_SUCCESS)
- return result;
+ /* seek to start of chunk */
+ if ((result = EAS_HWFileSeek(pDLSData->hwInstData, pDLSData->fileHandle, pos)) != EAS_SUCCESS)
+ return result;
- /* get the structure size */
- if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, &temp, EAS_FALSE)) != EAS_SUCCESS)
- return result;
+ /* get the structure size */
+ if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, &temp, EAS_FALSE)) != EAS_SUCCESS)
+ return result;
- /* get the number of waves */
- if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, &pDLSData->waveCount, EAS_FALSE)) != EAS_SUCCESS)
- return result;
+ /* get the number of waves */
+ if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, &pDLSData->waveCount, EAS_FALSE)) != EAS_SUCCESS)
+ return result;
#if 0
- /* just need the wave count on the first pass */
- if (!pDLSData->pDLS)
- return EAS_SUCCESS;
+ /* just need the wave count on the first pass */
+ if (!pDLSData->pDLS)
+ return EAS_SUCCESS;
#endif
- /* open duplicate file handle */
- if ((result = EAS_HWDupHandle(pDLSData->hwInstData, pDLSData->fileHandle, &tempFile)) != EAS_SUCCESS)
- return result;
-
- /* read to end of chunk */
- for (waveIndex = 0; waveIndex < pDLSData->waveCount; waveIndex++)
- {
-
- /* get the offset to the wave and make sure it is within the wtbl chunk */
- if ((result = EAS_HWGetDWord(pDLSData->hwInstData, tempFile, &temp, EAS_FALSE)) != EAS_SUCCESS)
- return result;
- if (temp > (EAS_U32) wtblSize)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Ptbl offset exceeds size of wtbl\n"); */ }
- EAS_HWCloseFile(pDLSData->hwInstData, tempFile);
- return EAS_ERROR_FILE_FORMAT;
- }
-
- /* parse the wave */
- if ((result = Parse_wave(pDLSData, wtblPos +(EAS_I32) temp, waveIndex)) != EAS_SUCCESS)
- return result;
- }
-
- /* close the temporary handle and return */
- EAS_HWCloseFile(pDLSData->hwInstData, tempFile);
- return EAS_SUCCESS;
+ /* open duplicate file handle */
+ if ((result = EAS_HWDupHandle(pDLSData->hwInstData, pDLSData->fileHandle, &tempFile)) != EAS_SUCCESS)
+ return result;
+
+ /* read to end of chunk */
+ for (waveIndex = 0; waveIndex < pDLSData->waveCount; waveIndex++)
+ {
+
+ /* get the offset to the wave and make sure it is within the wtbl chunk */
+ if ((result = EAS_HWGetDWord(pDLSData->hwInstData, tempFile, &temp, EAS_FALSE)) != EAS_SUCCESS)
+ return result;
+ if (temp > (EAS_U32) wtblSize)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Ptbl offset exceeds size of wtbl\n"); */ }
+ EAS_HWCloseFile(pDLSData->hwInstData, tempFile);
+ return EAS_ERROR_FILE_FORMAT;
+ }
+
+ /* parse the wave */
+ if ((result = Parse_wave(pDLSData, wtblPos +(EAS_I32) temp, waveIndex)) != EAS_SUCCESS)
+ return result;
+ }
+
+ /* close the temporary handle and return */
+ EAS_HWCloseFile(pDLSData->hwInstData, tempFile);
+ return EAS_SUCCESS;
}
/*----------------------------------------------------------------------------
* Parse_wave ()
*----------------------------------------------------------------------------
- * Purpose:
- *
+ * Purpose:
+ *
*
* Inputs:
- *
- *
+ *
+ *
* Outputs:
- *
+ *
*
*----------------------------------------------------------------------------
*/
static EAS_RESULT Parse_wave (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 pos, EAS_U16 waveIndex)
{
- EAS_RESULT result;
- EAS_U32 temp;
- EAS_I32 size;
- EAS_I32 endChunk;
- EAS_I32 chunkPos;
- EAS_I32 wsmpPos = 0;
- EAS_I32 fmtPos = 0;
- EAS_I32 dataPos = 0;
- EAS_I32 dataSize = 0;
- S_WSMP_DATA *p;
- void *pSample;
- S_WSMP_DATA wsmp;
-
- /* seek to start of chunk */
- chunkPos = pos + 12;
- if ((result = EAS_HWFileSeek(pDLSData->hwInstData, pDLSData->fileHandle, pos)) != EAS_SUCCESS)
- return result;
-
- /* get the chunk type */
- if ((result = NextChunk(pDLSData, &pos, &temp, &size)) != EAS_SUCCESS)
- return result;
-
- /* make sure it is a wave chunk */
- if (temp != CHUNK_WAVE)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Offset in ptbl does not point to wave chunk\n"); */ }
- return EAS_ERROR_FILE_FORMAT;
- }
-
- /* read to end of chunk */
- pos = chunkPos;
- endChunk = pos + size;
- while (pos < endChunk)
- {
- chunkPos = pos;
-
- /* get the chunk type */
- if ((result = NextChunk(pDLSData, &pos, &temp, &size)) != EAS_SUCCESS)
- return result;
-
- /* parse useful chunks */
- switch (temp)
- {
- case CHUNK_WSMP:
- wsmpPos = chunkPos + 8;
- break;
-
- case CHUNK_FMT:
- fmtPos = chunkPos + 8;
- break;
-
- case CHUNK_DATA:
- dataPos = chunkPos + 8;
- dataSize = size;
- break;
-
- default:
- break;
- }
- }
-
- // limit to reasonable size
- if (dataSize > MAX_DLS_WAVE_SIZE)
- {
- return EAS_ERROR_SOUND_LIBRARY;
- }
-
- /* for first pass, use temporary variable */
- if (pDLSData->pDLS == NULL)
- p = &wsmp;
- else
- p = &pDLSData->wsmpData[waveIndex];
-
- /* set the defaults */
- p->fineTune = 0;
- p->unityNote = 60;
- p->gain = 0;
- p->loopStart = 0;
- p->loopLength = 0;
-
- /* must have a fmt chunk */
- if (!fmtPos)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "DLS wave chunk has no fmt chunk\n"); */ }
- return EAS_ERROR_UNRECOGNIZED_FORMAT;
- }
-
- /* must have a data chunk */
- if (!dataPos)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "DLS wave chunk has no data chunk\n"); */ }
- return EAS_ERROR_UNRECOGNIZED_FORMAT;
- }
-
- /* parse the wsmp chunk */
- if (wsmpPos)
- {
- if ((result = Parse_wsmp(pDLSData, wsmpPos, p)) != EAS_SUCCESS)
- return result;
- }
-
- /* parse the fmt chunk */
- if ((result = Parse_fmt(pDLSData, fmtPos, p)) != EAS_SUCCESS)
- return result;
-
- /* calculate the size of the wavetable needed. We need only half
- * the memory for 16-bit samples when in 8-bit mode, and we need
- * double the memory for 8-bit samples in 16-bit mode. For
- * unlooped samples, we may use ADPCM. If so, we need only 1/4
- * the memory.
- *
- * We also need to add one for looped samples to allow for
- * the first sample to be copied to the end of the loop.
- */
-
- /* use ADPCM encode for unlooped 16-bit samples if ADPCM is enabled */
- /*lint -e{506} -e{774} groundwork for future version to support 8 & 16 bit */
- if (bitDepth == 8)
- {
- if (p->bitsPerSample == 8)
- size = dataSize;
- else
- /*lint -e{704} use shift for performance */
- size = dataSize >> 1;
- if (p->loopLength)
- size++;
- }
-
- else
- {
- if (p->bitsPerSample == 16)
- size = dataSize;
- else
- /*lint -e{703} use shift for performance */
- size = dataSize << 1;
- if (p->loopLength)
- size += 2;
- }
-
- /* for first pass, add size to wave pool size and return */
- if (pDLSData->pDLS == NULL)
- {
- pDLSData->wavePoolSize += (EAS_U32) size;
- return EAS_SUCCESS;
- }
-
- /* allocate memory and read in the sample data */
- pSample = pDLSData->pDLS->pDLSSamples + pDLSData->wavePoolOffset;
- pDLSData->pDLS->pDLSSampleOffsets[waveIndex] = pDLSData->wavePoolOffset;
- pDLSData->pDLS->pDLSSampleLen[waveIndex] = (EAS_U32) size;
- pDLSData->wavePoolOffset += (EAS_U32) size;
- if (pDLSData->wavePoolOffset > pDLSData->wavePoolSize)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Wave pool exceeded allocation\n"); */ }
- return EAS_ERROR_SOUND_LIBRARY;
- }
-
- if ((result = Parse_data(pDLSData, dataPos, dataSize, p, pSample)) != EAS_SUCCESS)
- return result;
-
- return EAS_SUCCESS;
+ EAS_RESULT result;
+ EAS_U32 temp;
+ EAS_I32 size;
+ EAS_I32 endChunk;
+ EAS_I32 chunkPos;
+ EAS_I32 wsmpPos = 0;
+ EAS_I32 fmtPos = 0;
+ EAS_I32 dataPos = 0;
+ EAS_I32 dataSize = 0;
+ S_WSMP_DATA *p;
+ void *pSample;
+ S_WSMP_DATA wsmp;
+
+ /* seek to start of chunk */
+ chunkPos = pos + 12;
+ if ((result = EAS_HWFileSeek(pDLSData->hwInstData, pDLSData->fileHandle, pos)) != EAS_SUCCESS)
+ return result;
+
+ /* get the chunk type */
+ if ((result = NextChunk(pDLSData, &pos, &temp, &size)) != EAS_SUCCESS)
+ return result;
+
+ /* make sure it is a wave chunk */
+ if (temp != CHUNK_WAVE)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Offset in ptbl does not point to wave chunk\n"); */ }
+ return EAS_ERROR_FILE_FORMAT;
+ }
+
+ /* read to end of chunk */
+ pos = chunkPos;
+ endChunk = pos + size;
+ while (pos < endChunk)
+ {
+ chunkPos = pos;
+
+ /* get the chunk type */
+ if ((result = NextChunk(pDLSData, &pos, &temp, &size)) != EAS_SUCCESS)
+ return result;
+
+ /* parse useful chunks */
+ switch (temp)
+ {
+ case CHUNK_WSMP:
+ wsmpPos = chunkPos + 8;
+ break;
+
+ case CHUNK_FMT:
+ fmtPos = chunkPos + 8;
+ break;
+
+ case CHUNK_DATA:
+ dataPos = chunkPos + 8;
+ dataSize = size;
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ // limit to reasonable size
+ if (dataSize > MAX_DLS_WAVE_SIZE)
+ {
+ return EAS_ERROR_SOUND_LIBRARY;
+ }
+
+ /* for first pass, use temporary variable */
+ if (pDLSData->pDLS == NULL)
+ p = &wsmp;
+ else
+ p = &pDLSData->wsmpData[waveIndex];
+
+ /* set the defaults */
+ p->fineTune = 0;
+ p->unityNote = 60;
+ p->gain = 0;
+ p->loopStart = 0;
+ p->loopLength = 0;
+
+ /* must have a fmt chunk */
+ if (!fmtPos)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "DLS wave chunk has no fmt chunk\n"); */ }
+ return EAS_ERROR_UNRECOGNIZED_FORMAT;
+ }
+
+ /* must have a data chunk */
+ if (!dataPos)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "DLS wave chunk has no data chunk\n"); */ }
+ return EAS_ERROR_UNRECOGNIZED_FORMAT;
+ }
+
+ /* parse the wsmp chunk */
+ if (wsmpPos)
+ {
+ if ((result = Parse_wsmp(pDLSData, wsmpPos, p)) != EAS_SUCCESS)
+ return result;
+ }
+
+ /* parse the fmt chunk */
+ if ((result = Parse_fmt(pDLSData, fmtPos, p)) != EAS_SUCCESS)
+ return result;
+
+ /* calculate the size of the wavetable needed. We need only half
+ * the memory for 16-bit samples when in 8-bit mode, and we need
+ * double the memory for 8-bit samples in 16-bit mode. For
+ * unlooped samples, we may use ADPCM. If so, we need only 1/4
+ * the memory.
+ *
+ * We also need to add one for looped samples to allow for
+ * the first sample to be copied to the end of the loop.
+ */
+
+ /* use ADPCM encode for unlooped 16-bit samples if ADPCM is enabled */
+ /*lint -e{506} -e{774} groundwork for future version to support 8 & 16 bit */
+ if (bitDepth == 8)
+ {
+ if (p->bitsPerSample == 8)
+ size = dataSize;
+ else
+ /*lint -e{704} use shift for performance */
+ size = dataSize >> 1;
+ if (p->loopLength)
+ size++;
+ }
+
+ else
+ {
+ if (p->bitsPerSample == 16)
+ size = dataSize;
+ else
+ /*lint -e{703} use shift for performance */
+ size = dataSize << 1;
+ if (p->loopLength)
+ size += 2;
+ }
+
+ /* for first pass, add size to wave pool size and return */
+ if (pDLSData->pDLS == NULL)
+ {
+ pDLSData->wavePoolSize += (EAS_U32) size;
+ return EAS_SUCCESS;
+ }
+
+ /* allocate memory and read in the sample data */
+ pSample = pDLSData->pDLS->pDLSSamples + pDLSData->wavePoolOffset;
+ pDLSData->pDLS->pDLSSampleOffsets[waveIndex] = pDLSData->wavePoolOffset;
+ pDLSData->pDLS->pDLSSampleLen[waveIndex] = (EAS_U32) size;
+ pDLSData->wavePoolOffset += (EAS_U32) size;
+ if (pDLSData->wavePoolOffset > pDLSData->wavePoolSize)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Wave pool exceeded allocation\n"); */ }
+ return EAS_ERROR_SOUND_LIBRARY;
+ }
+
+ if ((result = Parse_data(pDLSData, dataPos, dataSize, p, pSample)) != EAS_SUCCESS)
+ return result;
+
+ return EAS_SUCCESS;
}
/*----------------------------------------------------------------------------
* Parse_wsmp ()
*----------------------------------------------------------------------------
- * Purpose:
- *
+ * Purpose:
+ *
*
* Inputs:
- *
- *
+ *
+ *
* Outputs:
- *
+ *
*
*----------------------------------------------------------------------------
*/
static EAS_RESULT Parse_wsmp (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 pos, S_WSMP_DATA *p)
{
- EAS_RESULT result;
- EAS_U16 wtemp;
- EAS_U32 ltemp;
- EAS_U32 cbSize;
-
- /* seek to start of chunk */
- if ((result = EAS_HWFileSeek(pDLSData->hwInstData, pDLSData->fileHandle, pos)) != EAS_SUCCESS)
- return result;
-
- /* get structure size */
- if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, &cbSize, EAS_FALSE)) != EAS_SUCCESS)
- return result;
-
- /* get unity note */
- if ((result = EAS_HWGetWord(pDLSData->hwInstData, pDLSData->fileHandle, &wtemp, EAS_FALSE)) != EAS_SUCCESS)
- return result;
- if (wtemp <= 127)
- p->unityNote = (EAS_U8) wtemp;
- else
- {
- p->unityNote = 60;
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Invalid unity note [%u] in DLS wsmp ignored, set to 60\n", wtemp); */ }
- }
-
- /* get fine tune */
- if ((result = EAS_HWGetWord(pDLSData->hwInstData, pDLSData->fileHandle, &p->fineTune, EAS_FALSE)) != EAS_SUCCESS)
- return result;
-
- /* get gain */
- if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, &p->gain, EAS_FALSE)) != EAS_SUCCESS)
- return result;
- if (p->gain > 0)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Positive gain [%ld] in DLS wsmp ignored, set to 0dB\n", p->gain); */ }
- p->gain = 0;
- }
-
- /* option flags */
- if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, &ltemp, EAS_FALSE)) != EAS_SUCCESS)
- return result;
-
- /* sample loops */
- if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, &ltemp, EAS_FALSE)) != EAS_SUCCESS)
- return result;
-
- /* if looped sample, get loop data */
- if (ltemp)
- {
-
- if (ltemp > 1)
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "DLS sample with %lu loops, ignoring extra loops\n", ltemp); */ }
-
- /* skip ahead to loop data */
- if ((result = EAS_HWFileSeek(pDLSData->hwInstData, pDLSData->fileHandle, pos + (EAS_I32) cbSize)) != EAS_SUCCESS)
- return result;
-
- /* get structure size */
- if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, &ltemp, EAS_FALSE)) != EAS_SUCCESS)
- return result;
-
- /* get loop type */
- if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, &ltemp, EAS_FALSE)) != EAS_SUCCESS)
- return result;
-
- /* get loop start */
- if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, &p->loopStart, EAS_FALSE)) != EAS_SUCCESS)
- return result;
-
- /* get loop length */
- if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, &p->loopLength, EAS_FALSE)) != EAS_SUCCESS)
- return result;
- }
-
- return EAS_SUCCESS;
+ EAS_RESULT result;
+ EAS_U16 wtemp;
+ EAS_U32 ltemp;
+ EAS_U32 cbSize;
+
+ /* seek to start of chunk */
+ if ((result = EAS_HWFileSeek(pDLSData->hwInstData, pDLSData->fileHandle, pos)) != EAS_SUCCESS)
+ return result;
+
+ /* get structure size */
+ if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, &cbSize, EAS_FALSE)) != EAS_SUCCESS)
+ return result;
+
+ /* get unity note */
+ if ((result = EAS_HWGetWord(pDLSData->hwInstData, pDLSData->fileHandle, &wtemp, EAS_FALSE)) != EAS_SUCCESS)
+ return result;
+ if (wtemp <= 127)
+ p->unityNote = (EAS_U8) wtemp;
+ else
+ {
+ p->unityNote = 60;
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Invalid unity note [%u] in DLS wsmp ignored, set to 60\n", wtemp); */ }
+ }
+
+ /* get fine tune */
+ if ((result = EAS_HWGetWord(pDLSData->hwInstData, pDLSData->fileHandle, &p->fineTune, EAS_FALSE)) != EAS_SUCCESS)
+ return result;
+
+ /* get gain */
+ if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, &p->gain, EAS_FALSE)) != EAS_SUCCESS)
+ return result;
+ if (p->gain > 0)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Positive gain [%ld] in DLS wsmp ignored, set to 0dB\n", p->gain); */ }
+ p->gain = 0;
+ }
+
+ /* option flags */
+ if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, &ltemp, EAS_FALSE)) != EAS_SUCCESS)
+ return result;
+
+ /* sample loops */
+ if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, &ltemp, EAS_FALSE)) != EAS_SUCCESS)
+ return result;
+
+ /* if looped sample, get loop data */
+ if (ltemp)
+ {
+
+ if (ltemp > 1)
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "DLS sample with %lu loops, ignoring extra loops\n", ltemp); */ }
+
+ /* skip ahead to loop data */
+ if ((result = EAS_HWFileSeek(pDLSData->hwInstData, pDLSData->fileHandle, pos + (EAS_I32) cbSize)) != EAS_SUCCESS)
+ return result;
+
+ /* get structure size */
+ if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, &ltemp, EAS_FALSE)) != EAS_SUCCESS)
+ return result;
+
+ /* get loop type */
+ if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, &ltemp, EAS_FALSE)) != EAS_SUCCESS)
+ return result;
+
+ /* get loop start */
+ if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, &p->loopStart, EAS_FALSE)) != EAS_SUCCESS)
+ return result;
+
+ /* get loop length */
+ if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, &p->loopLength, EAS_FALSE)) != EAS_SUCCESS)
+ return result;
+ }
+
+ return EAS_SUCCESS;
}
/*----------------------------------------------------------------------------
* Parse_fmt ()
*----------------------------------------------------------------------------
- * Purpose:
- *
+ * Purpose:
+ *
*
* Inputs:
- *
- *
+ *
+ *
* Outputs:
- *
+ *
*
*----------------------------------------------------------------------------
*/
static EAS_RESULT Parse_fmt (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 pos, S_WSMP_DATA *p)
{
- EAS_RESULT result;
- EAS_U16 wtemp;
- EAS_U32 ltemp;
-
- /* seek to start of chunk */
- if ((result = EAS_HWFileSeek(pDLSData->hwInstData, pDLSData->fileHandle, pos)) != EAS_SUCCESS)
- return result;
-
- /* get format tag */
- if ((result = EAS_HWGetWord(pDLSData->hwInstData, pDLSData->fileHandle, &wtemp, EAS_FALSE)) != EAS_SUCCESS)
- return result;
- if (wtemp != WAVE_FORMAT_PCM)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Unsupported DLS sample format %04x\n", wtemp); */ }
- return EAS_ERROR_UNRECOGNIZED_FORMAT;
- }
-
- /* get number of channels */
- if ((result = EAS_HWGetWord(pDLSData->hwInstData, pDLSData->fileHandle, &wtemp, EAS_FALSE)) != EAS_SUCCESS)
- return result;
- if (wtemp != 1)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "No support for DLS multi-channel samples\n"); */ }
- return EAS_ERROR_UNRECOGNIZED_FORMAT;
- }
-
- /* get sample rate */
- if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, &p->sampleRate, EAS_FALSE)) != EAS_SUCCESS)
- return result;
-
- /* bytes/sec */
- if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, &ltemp, EAS_FALSE)) != EAS_SUCCESS)
- return result;
-
- /* block align */
- if ((result = EAS_HWGetWord(pDLSData->hwInstData, pDLSData->fileHandle, &wtemp, EAS_FALSE)) != EAS_SUCCESS)
- return result;
-
- /* bits/sample */
- if ((result = EAS_HWGetWord(pDLSData->hwInstData, pDLSData->fileHandle, &p->bitsPerSample, EAS_FALSE)) != EAS_SUCCESS)
- return result;
-
- if ((p->bitsPerSample != 8) && (p->bitsPerSample != 16))
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Unsupported DLS bits-per-sample %d\n", p->bitsPerSample); */ }
- return EAS_ERROR_UNRECOGNIZED_FORMAT;
- }
-
- return EAS_SUCCESS;
+ EAS_RESULT result;
+ EAS_U16 wtemp;
+ EAS_U32 ltemp;
+
+ /* seek to start of chunk */
+ if ((result = EAS_HWFileSeek(pDLSData->hwInstData, pDLSData->fileHandle, pos)) != EAS_SUCCESS)
+ return result;
+
+ /* get format tag */
+ if ((result = EAS_HWGetWord(pDLSData->hwInstData, pDLSData->fileHandle, &wtemp, EAS_FALSE)) != EAS_SUCCESS)
+ return result;
+ if (wtemp != WAVE_FORMAT_PCM)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Unsupported DLS sample format %04x\n", wtemp); */ }
+ return EAS_ERROR_UNRECOGNIZED_FORMAT;
+ }
+
+ /* get number of channels */
+ if ((result = EAS_HWGetWord(pDLSData->hwInstData, pDLSData->fileHandle, &wtemp, EAS_FALSE)) != EAS_SUCCESS)
+ return result;
+ if (wtemp != 1)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "No support for DLS multi-channel samples\n"); */ }
+ return EAS_ERROR_UNRECOGNIZED_FORMAT;
+ }
+
+ /* get sample rate */
+ if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, &p->sampleRate, EAS_FALSE)) != EAS_SUCCESS)
+ return result;
+
+ /* bytes/sec */
+ if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, &ltemp, EAS_FALSE)) != EAS_SUCCESS)
+ return result;
+
+ /* block align */
+ if ((result = EAS_HWGetWord(pDLSData->hwInstData, pDLSData->fileHandle, &wtemp, EAS_FALSE)) != EAS_SUCCESS)
+ return result;
+
+ /* bits/sample */
+ if ((result = EAS_HWGetWord(pDLSData->hwInstData, pDLSData->fileHandle, &p->bitsPerSample, EAS_FALSE)) != EAS_SUCCESS)
+ return result;
+
+ if ((p->bitsPerSample != 8) && (p->bitsPerSample != 16))
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Unsupported DLS bits-per-sample %d\n", p->bitsPerSample); */ }
+ return EAS_ERROR_UNRECOGNIZED_FORMAT;
+ }
+
+ return EAS_SUCCESS;
}
#if defined( _8_BIT_SAMPLES)
/*----------------------------------------------------------------------------
* Parse_data ()
*----------------------------------------------------------------------------
- * Purpose:
- *
+ * Purpose:
+ *
* NOTE: The optimized assembly versions of the interpolator require
* an extra sample at the end of the loop - a copy of the first
* sample. This routine must allocate an extra sample of data and
* copy the first sample of the loop to the end.
*
* Inputs:
- *
- *
+ *
+ *
* Outputs:
- *
+ *
*
*----------------------------------------------------------------------------
*/
static EAS_RESULT Parse_data (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 pos, EAS_I32 size, S_WSMP_DATA *pWsmp, EAS_SAMPLE *pSample)
{
- EAS_RESULT result;
- EAS_U8 convBuf[SAMPLE_CONVERT_CHUNK_SIZE];
- EAS_I32 count;
- EAS_I32 i;
- EAS_I8 *p;
-
- /* seek to start of chunk */
- if ((result = EAS_HWFileSeek(pDLSData->hwInstData, pDLSData->fileHandle, pos)) != EAS_SUCCESS)
- return result;
-
- /* 8-bit samples in an 8-bit synth, just copy the data, and flip bit 7 */
- p = pSample;
- if (pWsmp->bitsPerSample == 8)
- {
- if ((result = EAS_HWReadFile(pDLSData->hwInstData, pDLSData->fileHandle, pSample, size, &count)) != EAS_SUCCESS)
- return result;
- for (i = 0; i < size; i++)
- /*lint -e{734} convert from unsigned to signed audio */
- *p++ ^= 0x80;
- }
-
- /* 16-bit samples, need to convert to 8-bit or ADPCM */
- else
- {
-
- while (size)
- {
- EAS_I8 *pInput;
-
- /* for undithered conversion, we're just copying the 8-bit data */
- if (pDLSData->bigEndian)
- pInput = (EAS_I8*) convBuf;
- else
- pInput = (EAS_I8*) convBuf + 1;
-
- /* read a small chunk of data and convert it */
- count = (size < SAMPLE_CONVERT_CHUNK_SIZE ? size : SAMPLE_CONVERT_CHUNK_SIZE);
- if ((result = EAS_HWReadFile(pDLSData->hwInstData, pDLSData->fileHandle, convBuf, count, &count)) != EAS_SUCCESS)
- return result;
- size -= count;
- /*lint -e{704} use shift for performance */
- count = count >> 1;
-
- while (count--)
- {
- *p++ = *pInput;
- pInput += 2;
- }
- }
- }
-
- /* for looped samples, copy the last sample to the end */
- if (pWsmp->loopLength)
- pSample[pWsmp->loopStart + pWsmp->loopLength] = pSample[pWsmp->loopStart];
-
- return EAS_SUCCESS;
+ EAS_RESULT result;
+ EAS_U8 convBuf[SAMPLE_CONVERT_CHUNK_SIZE];
+ EAS_I32 count;
+ EAS_I32 i;
+ EAS_I8 *p;
+
+ /* seek to start of chunk */
+ if ((result = EAS_HWFileSeek(pDLSData->hwInstData, pDLSData->fileHandle, pos)) != EAS_SUCCESS)
+ return result;
+
+ /* 8-bit samples in an 8-bit synth, just copy the data, and flip bit 7 */
+ p = pSample;
+ if (pWsmp->bitsPerSample == 8)
+ {
+ if ((result = EAS_HWReadFile(pDLSData->hwInstData, pDLSData->fileHandle, pSample, size, &count)) != EAS_SUCCESS)
+ return result;
+ for (i = 0; i < size; i++)
+ /*lint -e{734} convert from unsigned to signed audio */
+ *p++ ^= 0x80;
+ }
+
+ /* 16-bit samples, need to convert to 8-bit or ADPCM */
+ else
+ {
+
+ while (size)
+ {
+ EAS_I8 *pInput;
+
+ /* for undithered conversion, we're just copying the 8-bit data */
+ if (pDLSData->bigEndian)
+ pInput = (EAS_I8*) convBuf;
+ else
+ pInput = (EAS_I8*) convBuf + 1;
+
+ /* read a small chunk of data and convert it */
+ count = (size < SAMPLE_CONVERT_CHUNK_SIZE ? size : SAMPLE_CONVERT_CHUNK_SIZE);
+ if ((result = EAS_HWReadFile(pDLSData->hwInstData, pDLSData->fileHandle, convBuf, count, &count)) != EAS_SUCCESS)
+ return result;
+ size -= count;
+ /*lint -e{704} use shift for performance */
+ count = count >> 1;
+
+ while (count--)
+ {
+ *p++ = *pInput;
+ pInput += 2;
+ }
+ }
+ }
+
+ /* for looped samples, copy the last sample to the end */
+ if (pWsmp->loopLength)
+ pSample[pWsmp->loopStart + pWsmp->loopLength] = pSample[pWsmp->loopStart];
+
+ return EAS_SUCCESS;
}
#elif defined(_16_BIT_SAMPLES)
#error "16-bit DLS conversion not implemented yet"
@@ -1285,1134 +1285,1134 @@ static EAS_RESULT Parse_data (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 pos, EAS_
/*----------------------------------------------------------------------------
* Parse_lins ()
*----------------------------------------------------------------------------
- * Purpose:
- *
+ * Purpose:
+ *
*
* Inputs:
- *
- *
+ *
+ *
* Outputs:
- *
+ *
*
*----------------------------------------------------------------------------
*/
static EAS_RESULT Parse_lins (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 pos, EAS_I32 size)
{
- EAS_RESULT result;
- EAS_U32 temp;
- EAS_I32 endChunk;
- EAS_I32 chunkPos;
-
- /* seek to start of chunk */
- if ((result = EAS_HWFileSeek(pDLSData->hwInstData, pDLSData->fileHandle, pos)) != EAS_SUCCESS)
- return result;
-
- /* read to end of chunk */
- endChunk = pos + size;
- while (pos < endChunk)
- {
- chunkPos = pos;
-
- /* get the next chunk type */
- if ((result = NextChunk(pDLSData, &pos, &temp, &size)) != EAS_SUCCESS)
- return result;
-
- /* only instrument chunks are useful */
- if (temp != CHUNK_INS)
- continue;
-
- if ((result = Parse_ins(pDLSData, chunkPos + 12, size)) != EAS_SUCCESS)
- return result;
- }
-
- return EAS_SUCCESS;
+ EAS_RESULT result;
+ EAS_U32 temp;
+ EAS_I32 endChunk;
+ EAS_I32 chunkPos;
+
+ /* seek to start of chunk */
+ if ((result = EAS_HWFileSeek(pDLSData->hwInstData, pDLSData->fileHandle, pos)) != EAS_SUCCESS)
+ return result;
+
+ /* read to end of chunk */
+ endChunk = pos + size;
+ while (pos < endChunk)
+ {
+ chunkPos = pos;
+
+ /* get the next chunk type */
+ if ((result = NextChunk(pDLSData, &pos, &temp, &size)) != EAS_SUCCESS)
+ return result;
+
+ /* only instrument chunks are useful */
+ if (temp != CHUNK_INS)
+ continue;
+
+ if ((result = Parse_ins(pDLSData, chunkPos + 12, size)) != EAS_SUCCESS)
+ return result;
+ }
+
+ return EAS_SUCCESS;
}
/*----------------------------------------------------------------------------
* Parse_ins ()
*----------------------------------------------------------------------------
- * Purpose:
- *
+ * Purpose:
+ *
*
* Inputs:
- *
- *
+ *
+ *
* Outputs:
- *
+ *
*
*----------------------------------------------------------------------------
*/
static EAS_RESULT Parse_ins (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 pos, EAS_I32 size)
{
- EAS_RESULT result;
- EAS_U32 temp;
- EAS_I32 chunkPos;
- EAS_I32 endChunk;
- EAS_I32 lrgnPos;
- EAS_I32 lrgnSize;
- EAS_I32 lartPos;
- EAS_I32 lartSize;
- EAS_I32 lar2Pos;
- EAS_I32 lar2Size;
- EAS_I32 inshPos;
- EAS_U32 regionCount;
- EAS_U32 locale;
- S_DLS_ART_VALUES art;
- S_PROGRAM *pProgram;
- EAS_U16 artIndex;
-
- /* seek to start of chunk */
- if ((result = EAS_HWFileSeek(pDLSData->hwInstData, pDLSData->fileHandle, pos)) != EAS_SUCCESS)
- return result;
-
- /* no chunks yet */
- lrgnPos = lrgnSize = lartPos = lartSize = lar2Pos = lar2Size = inshPos = artIndex = 0;
-
- /* read to end of chunk */
- endChunk = pos + size;
- while (pos < endChunk)
- {
- chunkPos = pos;
-
- /* get the next chunk type */
- if ((result = NextChunk(pDLSData, &pos, &temp, &size)) != EAS_SUCCESS)
- return result;
-
- /* parse useful chunks */
- switch (temp)
- {
- case CHUNK_INSH:
- inshPos = chunkPos + 8;
- break;
-
- case CHUNK_LART:
- lartPos = chunkPos + 12;
- lartSize = size;
- break;
-
- case CHUNK_LAR2:
- lar2Pos = chunkPos + 12;
- lar2Size = size;
- break;
-
- case CHUNK_LRGN:
- lrgnPos = chunkPos + 12;
- lrgnSize = size;
- break;
-
- default:
- break;
- }
- }
-
- /* must have an lrgn to be useful */
- if (!lrgnPos)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "DLS ins chunk has no lrgn chunk\n"); */ }
- return EAS_ERROR_UNRECOGNIZED_FORMAT;
- }
-
- /* must have an insh to be useful */
- if (!inshPos)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "DLS ins chunk has no insh chunk\n"); */ }
- return EAS_ERROR_UNRECOGNIZED_FORMAT;
- }
-
- /* parse the instrument header */
- if ((result = Parse_insh(pDLSData, inshPos, &regionCount, &locale)) != EAS_SUCCESS)
- return result;
-
- /* initialize and parse the global data first */
- EAS_HWMemCpy(&art, &defaultArt, sizeof(S_DLS_ART_VALUES));
- if (lartPos)
- if ((result = Parse_lart(pDLSData, lartPos, lartSize, &art)) != EAS_SUCCESS)
- return result;
- if (lar2Pos)
- if ((result = Parse_lart(pDLSData, lar2Pos, lar2Size, &art)) != EAS_SUCCESS)
- return result;
-
- if (art.values[PARAM_MODIFIED])
- {
- artIndex = (EAS_U16) pDLSData->artCount;
- pDLSData->artCount++;
- }
-
- /* convert data on second pass */
- if (pDLSData->pDLS)
- {
-
- if (art.values[PARAM_MODIFIED])
- Convert_art(pDLSData, &art, artIndex);
-
- /* setup pointers */
- pProgram = &pDLSData->pDLS->pDLSPrograms[pDLSData->instCount];
-
- /* initialize instrument */
- pProgram->locale = locale;
- pProgram->regionIndex = (EAS_U16) pDLSData->regionCount | FLAG_RGN_IDX_DLS_SYNTH;
-
- }
-
- /* parse the region data */
- if ((result = Parse_lrgn(pDLSData, lrgnPos, lrgnSize, artIndex, regionCount)) != EAS_SUCCESS)
- return result;
-
- /* bump instrument count */
- pDLSData->instCount++;
- return EAS_SUCCESS;
+ EAS_RESULT result;
+ EAS_U32 temp;
+ EAS_I32 chunkPos;
+ EAS_I32 endChunk;
+ EAS_I32 lrgnPos;
+ EAS_I32 lrgnSize;
+ EAS_I32 lartPos;
+ EAS_I32 lartSize;
+ EAS_I32 lar2Pos;
+ EAS_I32 lar2Size;
+ EAS_I32 inshPos;
+ EAS_U32 regionCount;
+ EAS_U32 locale;
+ S_DLS_ART_VALUES art;
+ S_PROGRAM *pProgram;
+ EAS_U16 artIndex;
+
+ /* seek to start of chunk */
+ if ((result = EAS_HWFileSeek(pDLSData->hwInstData, pDLSData->fileHandle, pos)) != EAS_SUCCESS)
+ return result;
+
+ /* no chunks yet */
+ lrgnPos = lrgnSize = lartPos = lartSize = lar2Pos = lar2Size = inshPos = artIndex = 0;
+
+ /* read to end of chunk */
+ endChunk = pos + size;
+ while (pos < endChunk)
+ {
+ chunkPos = pos;
+
+ /* get the next chunk type */
+ if ((result = NextChunk(pDLSData, &pos, &temp, &size)) != EAS_SUCCESS)
+ return result;
+
+ /* parse useful chunks */
+ switch (temp)
+ {
+ case CHUNK_INSH:
+ inshPos = chunkPos + 8;
+ break;
+
+ case CHUNK_LART:
+ lartPos = chunkPos + 12;
+ lartSize = size;
+ break;
+
+ case CHUNK_LAR2:
+ lar2Pos = chunkPos + 12;
+ lar2Size = size;
+ break;
+
+ case CHUNK_LRGN:
+ lrgnPos = chunkPos + 12;
+ lrgnSize = size;
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ /* must have an lrgn to be useful */
+ if (!lrgnPos)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "DLS ins chunk has no lrgn chunk\n"); */ }
+ return EAS_ERROR_UNRECOGNIZED_FORMAT;
+ }
+
+ /* must have an insh to be useful */
+ if (!inshPos)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "DLS ins chunk has no insh chunk\n"); */ }
+ return EAS_ERROR_UNRECOGNIZED_FORMAT;
+ }
+
+ /* parse the instrument header */
+ if ((result = Parse_insh(pDLSData, inshPos, &regionCount, &locale)) != EAS_SUCCESS)
+ return result;
+
+ /* initialize and parse the global data first */
+ EAS_HWMemCpy(&art, &defaultArt, sizeof(S_DLS_ART_VALUES));
+ if (lartPos)
+ if ((result = Parse_lart(pDLSData, lartPos, lartSize, &art)) != EAS_SUCCESS)
+ return result;
+ if (lar2Pos)
+ if ((result = Parse_lart(pDLSData, lar2Pos, lar2Size, &art)) != EAS_SUCCESS)
+ return result;
+
+ if (art.values[PARAM_MODIFIED])
+ {
+ artIndex = (EAS_U16) pDLSData->artCount;
+ pDLSData->artCount++;
+ }
+
+ /* convert data on second pass */
+ if (pDLSData->pDLS)
+ {
+
+ if (art.values[PARAM_MODIFIED])
+ Convert_art(pDLSData, &art, artIndex);
+
+ /* setup pointers */
+ pProgram = &pDLSData->pDLS->pDLSPrograms[pDLSData->instCount];
+
+ /* initialize instrument */
+ pProgram->locale = locale;
+ pProgram->regionIndex = (EAS_U16) pDLSData->regionCount | FLAG_RGN_IDX_DLS_SYNTH;
+
+ }
+
+ /* parse the region data */
+ if ((result = Parse_lrgn(pDLSData, lrgnPos, lrgnSize, artIndex, regionCount)) != EAS_SUCCESS)
+ return result;
+
+ /* bump instrument count */
+ pDLSData->instCount++;
+ return EAS_SUCCESS;
}
/*----------------------------------------------------------------------------
* Parse_insh ()
*----------------------------------------------------------------------------
- * Purpose:
- *
+ * Purpose:
+ *
*
* Inputs:
- *
- *
+ *
+ *
* Outputs:
- *
+ *
*
*----------------------------------------------------------------------------
*/
static EAS_RESULT Parse_insh (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 pos, EAS_U32 *pRgnCount, EAS_U32 *pLocale)
{
- EAS_RESULT result;
- EAS_U32 bank;
- EAS_U32 program;
-
- /* seek to start of chunk */
- if ((result = EAS_HWFileSeek(pDLSData->hwInstData, pDLSData->fileHandle, pos)) != EAS_SUCCESS)
- return result;
-
- /* get the region count and locale */
- if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, pRgnCount, EAS_FALSE)) != EAS_SUCCESS)
- return result;
- if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, &bank, EAS_FALSE)) != EAS_SUCCESS)
- return result;
- if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, &program, EAS_FALSE)) != EAS_SUCCESS)
- return result;
-
- /* verify the parameters are valid */
- if (bank & 0x7fff8080)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "DLS bank number is out of range: %08lx\n", bank); */ }
- bank &= 0xff7f;
- }
- if (program > 127)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "DLS program number is out of range: %08lx\n", program); */ }
- program &= 0x7f;
- }
-
- /* save the program number */
- *pLocale = (bank << 8) | program;
- return EAS_SUCCESS;
+ EAS_RESULT result;
+ EAS_U32 bank;
+ EAS_U32 program;
+
+ /* seek to start of chunk */
+ if ((result = EAS_HWFileSeek(pDLSData->hwInstData, pDLSData->fileHandle, pos)) != EAS_SUCCESS)
+ return result;
+
+ /* get the region count and locale */
+ if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, pRgnCount, EAS_FALSE)) != EAS_SUCCESS)
+ return result;
+ if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, &bank, EAS_FALSE)) != EAS_SUCCESS)
+ return result;
+ if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, &program, EAS_FALSE)) != EAS_SUCCESS)
+ return result;
+
+ /* verify the parameters are valid */
+ if (bank & 0x7fff8080)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "DLS bank number is out of range: %08lx\n", bank); */ }
+ bank &= 0xff7f;
+ }
+ if (program > 127)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "DLS program number is out of range: %08lx\n", program); */ }
+ program &= 0x7f;
+ }
+
+ /* save the program number */
+ *pLocale = (bank << 8) | program;
+ return EAS_SUCCESS;
}
/*----------------------------------------------------------------------------
* Parse_lrgn ()
*----------------------------------------------------------------------------
- * Purpose:
- *
+ * Purpose:
+ *
*
* Inputs:
- *
- *
+ *
+ *
* Outputs:
- *
+ *
*
*----------------------------------------------------------------------------
*/
static EAS_RESULT Parse_lrgn (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 pos, EAS_I32 size, EAS_U16 artIndex, EAS_U32 numRegions)
{
- EAS_RESULT result;
- EAS_U32 temp;
- EAS_I32 chunkPos;
- EAS_I32 endChunk;
- EAS_U16 regionCount;
-
- /* seek to start of chunk */
- if ((result = EAS_HWFileSeek(pDLSData->hwInstData, pDLSData->fileHandle, pos)) != EAS_SUCCESS)
- return result;
-
- /* read to end of chunk */
- regionCount = 0;
- endChunk = pos + size;
- while (pos < endChunk)
- {
- chunkPos = pos;
-
- /* get the next chunk type */
- if ((result = NextChunk(pDLSData, &pos, &temp, &size)) != EAS_SUCCESS)
- return result;
-
- if ((temp == CHUNK_RGN) || (temp == CHUNK_RGN2))
- {
- if (regionCount == numRegions)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "DLS region count exceeded cRegions value in insh, extra region ignored\n"); */ }
- return EAS_SUCCESS;
- }
- if ((result = Parse_rgn(pDLSData, chunkPos + 12, size, artIndex)) != EAS_SUCCESS)
- return result;
- regionCount++;
- }
- }
-
- /* set a flag in the last region */
- if ((pDLSData->pDLS != NULL) && (regionCount > 0))
- pDLSData->pDLS->pDLSRegions[pDLSData->regionCount - 1].wtRegion.region.keyGroupAndFlags |= REGION_FLAG_LAST_REGION;
-
- return EAS_SUCCESS;
+ EAS_RESULT result;
+ EAS_U32 temp;
+ EAS_I32 chunkPos;
+ EAS_I32 endChunk;
+ EAS_U16 regionCount;
+
+ /* seek to start of chunk */
+ if ((result = EAS_HWFileSeek(pDLSData->hwInstData, pDLSData->fileHandle, pos)) != EAS_SUCCESS)
+ return result;
+
+ /* read to end of chunk */
+ regionCount = 0;
+ endChunk = pos + size;
+ while (pos < endChunk)
+ {
+ chunkPos = pos;
+
+ /* get the next chunk type */
+ if ((result = NextChunk(pDLSData, &pos, &temp, &size)) != EAS_SUCCESS)
+ return result;
+
+ if ((temp == CHUNK_RGN) || (temp == CHUNK_RGN2))
+ {
+ if (regionCount == numRegions)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "DLS region count exceeded cRegions value in insh, extra region ignored\n"); */ }
+ return EAS_SUCCESS;
+ }
+ if ((result = Parse_rgn(pDLSData, chunkPos + 12, size, artIndex)) != EAS_SUCCESS)
+ return result;
+ regionCount++;
+ }
+ }
+
+ /* set a flag in the last region */
+ if ((pDLSData->pDLS != NULL) && (regionCount > 0))
+ pDLSData->pDLS->pDLSRegions[pDLSData->regionCount - 1].wtRegion.region.keyGroupAndFlags |= REGION_FLAG_LAST_REGION;
+
+ return EAS_SUCCESS;
}
/*----------------------------------------------------------------------------
* Parse_rgn ()
*----------------------------------------------------------------------------
- * Purpose:
- *
+ * Purpose:
+ *
*
* Inputs:
- *
- *
+ *
+ *
* Outputs:
- *
+ *
*
*----------------------------------------------------------------------------
*/
static EAS_RESULT Parse_rgn (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 pos, EAS_I32 size, EAS_U16 artIndex)
{
- EAS_RESULT result;
- EAS_U32 temp;
- EAS_I32 chunkPos;
- EAS_I32 endChunk;
- EAS_I32 rgnhPos;
- EAS_I32 lartPos;
- EAS_I32 lartSize;
- EAS_I32 lar2Pos;
- EAS_I32 lar2Size;
- EAS_I32 wlnkPos;
- EAS_I32 wsmpPos;
- EAS_U32 waveIndex;
- S_DLS_ART_VALUES art;
- S_WSMP_DATA wsmp;
- S_WSMP_DATA *pWsmp;
- EAS_U16 regionIndex;
-
- /* seek to start of chunk */
- if ((result = EAS_HWFileSeek(pDLSData->hwInstData, pDLSData->fileHandle, pos)) != EAS_SUCCESS)
- return result;
-
- /* no chunks found yet */
- rgnhPos = lartPos = lartSize = lar2Pos = lar2Size = wsmpPos = wlnkPos = 0;
- regionIndex = (EAS_U16) pDLSData->regionCount;
-
- /* read to end of chunk */
- endChunk = pos + size;
- while (pos < endChunk)
- {
- chunkPos = pos;
-
- /* get the next chunk type */
- if ((result = NextChunk(pDLSData, &pos, &temp, &size)) != EAS_SUCCESS)
- return result;
-
- /* parse useful chunks */
- switch (temp)
- {
- case CHUNK_CDL:
- if ((result = Parse_cdl(pDLSData, size, &temp)) != EAS_SUCCESS)
- return result;
-
- /* if conditional chunk evaluates false, skip this list */
- if (!temp)
- return EAS_SUCCESS;
- break;
-
- case CHUNK_RGNH:
- rgnhPos = chunkPos + 8;
- break;
-
- case CHUNK_WLNK:
- wlnkPos = chunkPos + 8;
- break;
-
- case CHUNK_WSMP:
- wsmpPos = chunkPos + 8;
- break;
-
- case CHUNK_LART:
- lartPos = chunkPos + 12;
- lartSize = size;
- break;
-
- case CHUNK_LAR2:
- lar2Pos = chunkPos + 12;
- lar2Size = size;
- break;
-
- default:
- break;
- }
- }
-
- /* must have a rgnh chunk to be useful */
- if (!rgnhPos)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "DLS rgn chunk has no rgnh chunk\n"); */ }
- return EAS_ERROR_UNRECOGNIZED_FORMAT;
- }
-
- /* must have a wlnk chunk to be useful */
- if (!wlnkPos)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "DLS rgn chunk has no wlnk chunk\n"); */ }
- return EAS_ERROR_UNRECOGNIZED_FORMAT;
- }
-
- /* parse wlnk chunk */
- if ((result = Parse_wlnk(pDLSData, wlnkPos, &waveIndex)) != EAS_SUCCESS)
- return result;
- pWsmp = &pDLSData->wsmpData[waveIndex];
-
- /* if there is any articulation data, parse it */
- EAS_HWMemCpy(&art, &defaultArt, sizeof(S_DLS_ART_VALUES));
- if (lartPos)
- {
- if ((result = Parse_lart(pDLSData, lartPos, lartSize, &art)) != EAS_SUCCESS)
- return result;
- }
-
- if (lar2Pos)
- {
- if ((result = Parse_lart(pDLSData, lar2Pos, lar2Size, &art)) != EAS_SUCCESS)
- return result;
- }
-
- /* if second pass, process region header */
- if (pDLSData->pDLS)
- {
-
- /* if local data was found convert it */
- if (art.values[PARAM_MODIFIED] == EAS_TRUE)
- {
- Convert_art(pDLSData, &art, (EAS_U16) pDLSData->artCount);
- artIndex = (EAS_U16) pDLSData->artCount;
- }
-
- /* parse region header */
- if ((result = Parse_rgnh(pDLSData, rgnhPos, &pDLSData->pDLS->pDLSRegions[regionIndex & REGION_INDEX_MASK])) != EAS_SUCCESS)
- return result;
-
- /* parse wsmp chunk, copying parameters from original first */
- if (wsmpPos)
- {
- EAS_HWMemCpy(&wsmp, pWsmp, sizeof(wsmp));
- if ((result = Parse_wsmp(pDLSData, wsmpPos, &wsmp)) != EAS_SUCCESS)
- return result;
-
- pWsmp = &wsmp;
- }
-
- Convert_rgn(pDLSData, regionIndex, artIndex, (EAS_U16) waveIndex, pWsmp);
- }
-
- /* if local articulation, bump count */
- if (art.values[PARAM_MODIFIED])
- pDLSData->artCount++;
-
- /* increment region count */
- pDLSData->regionCount++;
- return EAS_SUCCESS;
+ EAS_RESULT result;
+ EAS_U32 temp;
+ EAS_I32 chunkPos;
+ EAS_I32 endChunk;
+ EAS_I32 rgnhPos;
+ EAS_I32 lartPos;
+ EAS_I32 lartSize;
+ EAS_I32 lar2Pos;
+ EAS_I32 lar2Size;
+ EAS_I32 wlnkPos;
+ EAS_I32 wsmpPos;
+ EAS_U32 waveIndex;
+ S_DLS_ART_VALUES art;
+ S_WSMP_DATA wsmp;
+ S_WSMP_DATA *pWsmp;
+ EAS_U16 regionIndex;
+
+ /* seek to start of chunk */
+ if ((result = EAS_HWFileSeek(pDLSData->hwInstData, pDLSData->fileHandle, pos)) != EAS_SUCCESS)
+ return result;
+
+ /* no chunks found yet */
+ rgnhPos = lartPos = lartSize = lar2Pos = lar2Size = wsmpPos = wlnkPos = 0;
+ regionIndex = (EAS_U16) pDLSData->regionCount;
+
+ /* read to end of chunk */
+ endChunk = pos + size;
+ while (pos < endChunk)
+ {
+ chunkPos = pos;
+
+ /* get the next chunk type */
+ if ((result = NextChunk(pDLSData, &pos, &temp, &size)) != EAS_SUCCESS)
+ return result;
+
+ /* parse useful chunks */
+ switch (temp)
+ {
+ case CHUNK_CDL:
+ if ((result = Parse_cdl(pDLSData, size, &temp)) != EAS_SUCCESS)
+ return result;
+
+ /* if conditional chunk evaluates false, skip this list */
+ if (!temp)
+ return EAS_SUCCESS;
+ break;
+
+ case CHUNK_RGNH:
+ rgnhPos = chunkPos + 8;
+ break;
+
+ case CHUNK_WLNK:
+ wlnkPos = chunkPos + 8;
+ break;
+
+ case CHUNK_WSMP:
+ wsmpPos = chunkPos + 8;
+ break;
+
+ case CHUNK_LART:
+ lartPos = chunkPos + 12;
+ lartSize = size;
+ break;
+
+ case CHUNK_LAR2:
+ lar2Pos = chunkPos + 12;
+ lar2Size = size;
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ /* must have a rgnh chunk to be useful */
+ if (!rgnhPos)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "DLS rgn chunk has no rgnh chunk\n"); */ }
+ return EAS_ERROR_UNRECOGNIZED_FORMAT;
+ }
+
+ /* must have a wlnk chunk to be useful */
+ if (!wlnkPos)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "DLS rgn chunk has no wlnk chunk\n"); */ }
+ return EAS_ERROR_UNRECOGNIZED_FORMAT;
+ }
+
+ /* parse wlnk chunk */
+ if ((result = Parse_wlnk(pDLSData, wlnkPos, &waveIndex)) != EAS_SUCCESS)
+ return result;
+ pWsmp = &pDLSData->wsmpData[waveIndex];
+
+ /* if there is any articulation data, parse it */
+ EAS_HWMemCpy(&art, &defaultArt, sizeof(S_DLS_ART_VALUES));
+ if (lartPos)
+ {
+ if ((result = Parse_lart(pDLSData, lartPos, lartSize, &art)) != EAS_SUCCESS)
+ return result;
+ }
+
+ if (lar2Pos)
+ {
+ if ((result = Parse_lart(pDLSData, lar2Pos, lar2Size, &art)) != EAS_SUCCESS)
+ return result;
+ }
+
+ /* if second pass, process region header */
+ if (pDLSData->pDLS)
+ {
+
+ /* if local data was found convert it */
+ if (art.values[PARAM_MODIFIED] == EAS_TRUE)
+ {
+ Convert_art(pDLSData, &art, (EAS_U16) pDLSData->artCount);
+ artIndex = (EAS_U16) pDLSData->artCount;
+ }
+
+ /* parse region header */
+ if ((result = Parse_rgnh(pDLSData, rgnhPos, &pDLSData->pDLS->pDLSRegions[regionIndex & REGION_INDEX_MASK])) != EAS_SUCCESS)
+ return result;
+
+ /* parse wsmp chunk, copying parameters from original first */
+ if (wsmpPos)
+ {
+ EAS_HWMemCpy(&wsmp, pWsmp, sizeof(wsmp));
+ if ((result = Parse_wsmp(pDLSData, wsmpPos, &wsmp)) != EAS_SUCCESS)
+ return result;
+
+ pWsmp = &wsmp;
+ }
+
+ Convert_rgn(pDLSData, regionIndex, artIndex, (EAS_U16) waveIndex, pWsmp);
+ }
+
+ /* if local articulation, bump count */
+ if (art.values[PARAM_MODIFIED])
+ pDLSData->artCount++;
+
+ /* increment region count */
+ pDLSData->regionCount++;
+ return EAS_SUCCESS;
}
/*----------------------------------------------------------------------------
* Parse_rgnh ()
*----------------------------------------------------------------------------
- * Purpose:
- *
+ * Purpose:
+ *
*
* Inputs:
- *
- *
+ *
+ *
* Outputs:
- *
+ *
*
*----------------------------------------------------------------------------
*/
static EAS_RESULT Parse_rgnh (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 pos, S_DLS_REGION *pRgn)
{
- EAS_RESULT result;
- EAS_U16 lowKey;
- EAS_U16 highKey;
- EAS_U16 lowVel;
- EAS_U16 highVel;
- EAS_U16 optionFlags;
- EAS_U16 keyGroup;
-
- /* seek to start of chunk */
- if ((result = EAS_HWFileSeek(pDLSData->hwInstData, pDLSData->fileHandle, pos)) != EAS_SUCCESS)
- return result;
-
- /* get the key range */
- if ((result = EAS_HWGetWord(pDLSData->hwInstData, pDLSData->fileHandle, &lowKey, EAS_FALSE)) != EAS_SUCCESS)
- return result;
- if ((result = EAS_HWGetWord(pDLSData->hwInstData, pDLSData->fileHandle, &highKey, EAS_FALSE)) != EAS_SUCCESS)
- return result;
-
- /* check the range */
- if (lowKey > 127)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "DLS rgnh: Low key out of range [%u]\n", lowKey); */ }
- lowKey = 127;
- }
- if (highKey > 127)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "DLS rgnh: High key out of range [%u]\n", lowKey); */ }
- highKey = 127;
- }
-
- /* get the velocity range */
- if ((result = EAS_HWGetWord(pDLSData->hwInstData, pDLSData->fileHandle, &lowVel, EAS_FALSE)) != EAS_SUCCESS)
- return result;
- if ((result = EAS_HWGetWord(pDLSData->hwInstData, pDLSData->fileHandle, &highVel, EAS_FALSE)) != EAS_SUCCESS)
- return result;
-
- /* check the range */
- if (lowVel > 127)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "DLS rgnh: Low velocity out of range [%u]\n", lowVel); */ }
- lowVel = 127;
- }
- if (highVel > 127)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "DLS rgnh: High velocity out of range [%u]\n", highVel); */ }
- highVel = 127;
- }
-
- /* get the option flags */
- if ((result = EAS_HWGetWord(pDLSData->hwInstData, pDLSData->fileHandle, &optionFlags, EAS_FALSE)) != EAS_SUCCESS)
- return result;
-
- /* get the key group */
- if ((result = EAS_HWGetWord(pDLSData->hwInstData, pDLSData->fileHandle, &keyGroup, EAS_FALSE)) != EAS_SUCCESS)
- return result;
-
- /* save the key range and key group */
- pRgn->wtRegion.region.rangeLow = (EAS_U8) lowKey;
- pRgn->wtRegion.region.rangeHigh = (EAS_U8) highKey;
-
- /*lint -e{734} keyGroup will always be from 0-15 */
- pRgn->wtRegion.region.keyGroupAndFlags = keyGroup << 8;
- pRgn->velLow = (EAS_U8) lowVel;
- pRgn->velHigh = (EAS_U8) highVel;
- if (optionFlags & F_RGN_OPTION_SELFNONEXCLUSIVE)
- pRgn->wtRegion.region.keyGroupAndFlags |= REGION_FLAG_NON_SELF_EXCLUSIVE;
-
- return EAS_SUCCESS;
+ EAS_RESULT result;
+ EAS_U16 lowKey;
+ EAS_U16 highKey;
+ EAS_U16 lowVel;
+ EAS_U16 highVel;
+ EAS_U16 optionFlags;
+ EAS_U16 keyGroup;
+
+ /* seek to start of chunk */
+ if ((result = EAS_HWFileSeek(pDLSData->hwInstData, pDLSData->fileHandle, pos)) != EAS_SUCCESS)
+ return result;
+
+ /* get the key range */
+ if ((result = EAS_HWGetWord(pDLSData->hwInstData, pDLSData->fileHandle, &lowKey, EAS_FALSE)) != EAS_SUCCESS)
+ return result;
+ if ((result = EAS_HWGetWord(pDLSData->hwInstData, pDLSData->fileHandle, &highKey, EAS_FALSE)) != EAS_SUCCESS)
+ return result;
+
+ /* check the range */
+ if (lowKey > 127)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "DLS rgnh: Low key out of range [%u]\n", lowKey); */ }
+ lowKey = 127;
+ }
+ if (highKey > 127)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "DLS rgnh: High key out of range [%u]\n", lowKey); */ }
+ highKey = 127;
+ }
+
+ /* get the velocity range */
+ if ((result = EAS_HWGetWord(pDLSData->hwInstData, pDLSData->fileHandle, &lowVel, EAS_FALSE)) != EAS_SUCCESS)
+ return result;
+ if ((result = EAS_HWGetWord(pDLSData->hwInstData, pDLSData->fileHandle, &highVel, EAS_FALSE)) != EAS_SUCCESS)
+ return result;
+
+ /* check the range */
+ if (lowVel > 127)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "DLS rgnh: Low velocity out of range [%u]\n", lowVel); */ }
+ lowVel = 127;
+ }
+ if (highVel > 127)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "DLS rgnh: High velocity out of range [%u]\n", highVel); */ }
+ highVel = 127;
+ }
+
+ /* get the option flags */
+ if ((result = EAS_HWGetWord(pDLSData->hwInstData, pDLSData->fileHandle, &optionFlags, EAS_FALSE)) != EAS_SUCCESS)
+ return result;
+
+ /* get the key group */
+ if ((result = EAS_HWGetWord(pDLSData->hwInstData, pDLSData->fileHandle, &keyGroup, EAS_FALSE)) != EAS_SUCCESS)
+ return result;
+
+ /* save the key range and key group */
+ pRgn->wtRegion.region.rangeLow = (EAS_U8) lowKey;
+ pRgn->wtRegion.region.rangeHigh = (EAS_U8) highKey;
+
+ /*lint -e{734} keyGroup will always be from 0-15 */
+ pRgn->wtRegion.region.keyGroupAndFlags = keyGroup << 8;
+ pRgn->velLow = (EAS_U8) lowVel;
+ pRgn->velHigh = (EAS_U8) highVel;
+ if (optionFlags & F_RGN_OPTION_SELFNONEXCLUSIVE)
+ pRgn->wtRegion.region.keyGroupAndFlags |= REGION_FLAG_NON_SELF_EXCLUSIVE;
+
+ return EAS_SUCCESS;
}
/*----------------------------------------------------------------------------
* Parse_lart ()
*----------------------------------------------------------------------------
- * Purpose:
- *
+ * Purpose:
+ *
*
* Inputs:
- *
- *
+ *
+ *
* Outputs:
- *
+ *
*
*----------------------------------------------------------------------------
*/
static EAS_RESULT Parse_lart (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 pos, EAS_I32 size, S_DLS_ART_VALUES *pArt)
{
- EAS_RESULT result;
- EAS_U32 temp;
- EAS_I32 endChunk;
- EAS_I32 chunkPos;
- EAS_I32 art1Pos;
- EAS_I32 art2Pos;
-
- /* seek to start of chunk */
- if ((result = EAS_HWFileSeek(pDLSData->hwInstData, pDLSData->fileHandle, pos)) != EAS_SUCCESS)
- return result;
-
- /* no articulation chunks yet */
- art1Pos = art2Pos = 0;
-
- /* read to end of chunk */
- endChunk = pos + size;
- while (pos < endChunk)
- {
- chunkPos = pos;
-
- /* get the next chunk type */
- if ((result = NextChunk(pDLSData, &pos, &temp, &size)) != EAS_SUCCESS)
- return result;
-
- /* parse useful chunks */
- switch (temp)
- {
- case CHUNK_CDL:
- if ((result = Parse_cdl(pDLSData, size, &temp)) != EAS_SUCCESS)
- return result;
-
- /* if conditional chunk evaluates false, skip this list */
- if (!temp)
- return EAS_SUCCESS;
- break;
-
- case CHUNK_ART1:
- art1Pos = chunkPos + 8;
- break;
-
- case CHUNK_ART2:
- art2Pos = chunkPos + 8;
- break;
-
- default:
- break;
-
- }
- }
-
- if (art1Pos)
- {
- if ((result = Parse_art(pDLSData, art1Pos, pArt)) != EAS_SUCCESS)
- return result;
- }
-
- if (art2Pos)
- {
- if ((result = Parse_art(pDLSData, art2Pos, pArt)) != EAS_SUCCESS)
- return result;
- }
-
- return EAS_SUCCESS;
+ EAS_RESULT result;
+ EAS_U32 temp;
+ EAS_I32 endChunk;
+ EAS_I32 chunkPos;
+ EAS_I32 art1Pos;
+ EAS_I32 art2Pos;
+
+ /* seek to start of chunk */
+ if ((result = EAS_HWFileSeek(pDLSData->hwInstData, pDLSData->fileHandle, pos)) != EAS_SUCCESS)
+ return result;
+
+ /* no articulation chunks yet */
+ art1Pos = art2Pos = 0;
+
+ /* read to end of chunk */
+ endChunk = pos + size;
+ while (pos < endChunk)
+ {
+ chunkPos = pos;
+
+ /* get the next chunk type */
+ if ((result = NextChunk(pDLSData, &pos, &temp, &size)) != EAS_SUCCESS)
+ return result;
+
+ /* parse useful chunks */
+ switch (temp)
+ {
+ case CHUNK_CDL:
+ if ((result = Parse_cdl(pDLSData, size, &temp)) != EAS_SUCCESS)
+ return result;
+
+ /* if conditional chunk evaluates false, skip this list */
+ if (!temp)
+ return EAS_SUCCESS;
+ break;
+
+ case CHUNK_ART1:
+ art1Pos = chunkPos + 8;
+ break;
+
+ case CHUNK_ART2:
+ art2Pos = chunkPos + 8;
+ break;
+
+ default:
+ break;
+
+ }
+ }
+
+ if (art1Pos)
+ {
+ if ((result = Parse_art(pDLSData, art1Pos, pArt)) != EAS_SUCCESS)
+ return result;
+ }
+
+ if (art2Pos)
+ {
+ if ((result = Parse_art(pDLSData, art2Pos, pArt)) != EAS_SUCCESS)
+ return result;
+ }
+
+ return EAS_SUCCESS;
}
/*----------------------------------------------------------------------------
* Parse_art()
*----------------------------------------------------------------------------
- * Purpose:
- *
+ * Purpose:
+ *
*
* Inputs:
- *
- *
+ *
+ *
* Outputs:
- *
+ *
*
*----------------------------------------------------------------------------
*/
static EAS_RESULT Parse_art (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 pos, S_DLS_ART_VALUES *pArt)
{
- EAS_RESULT result;
- EAS_U32 structSize;
- EAS_U32 numConnections;
- EAS_U16 source;
- EAS_U16 control;
- EAS_U16 destination;
- EAS_U16 transform;
- EAS_I32 scale;
- EAS_INT i;
-
- /* seek to start of data */
- if ((result = EAS_HWFileSeek(pDLSData->hwInstData, pDLSData->fileHandle, pos)) != EAS_SUCCESS)
- return result;
-
- /* get the structure size */
- if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, &structSize, EAS_FALSE)) != EAS_SUCCESS)
- return result;
- pos += (EAS_I32) structSize;
-
- /* get the number of connections */
- if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, &numConnections, EAS_FALSE)) != EAS_SUCCESS)
- return result;
-
- /* skip to start of connections */
- if ((result = EAS_HWFileSeek(pDLSData->hwInstData, pDLSData->fileHandle, pos)) != EAS_SUCCESS)
- return result;
-
- while (numConnections--)
- {
-
- /* read the connection data */
- if ((result = EAS_HWGetWord(pDLSData->hwInstData, pDLSData->fileHandle, &source, EAS_FALSE)) != EAS_SUCCESS)
- return result;
- if ((result = EAS_HWGetWord(pDLSData->hwInstData, pDLSData->fileHandle, &control, EAS_FALSE)) != EAS_SUCCESS)
- return result;
- if ((result = EAS_HWGetWord(pDLSData->hwInstData, pDLSData->fileHandle, &destination, EAS_FALSE)) != EAS_SUCCESS)
- return result;
- if ((result = EAS_HWGetWord(pDLSData->hwInstData, pDLSData->fileHandle, &transform, EAS_FALSE)) != EAS_SUCCESS)
- return result;
- if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, &scale, EAS_FALSE)) != EAS_SUCCESS)
- return result;
-
- /* look up the connection */
- for (i = 0; i < (EAS_INT) ENTRIES_IN_CONN_TABLE; i++)
- {
- if ((connTable[i].source == source) &&
- (connTable[i].destination == destination) &&
- (connTable[i].control == control))
- {
- /*lint -e{704} use shift for performance */
- pArt->values[connTable[i].connection] = (EAS_I16) (scale >> 16);
- pArt->values[PARAM_MODIFIED] = EAS_TRUE;
- break;
- }
- }
- if (i == PARAM_TABLE_SIZE)
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "WARN: Unsupported parameter in DLS file\n"); */ }
- }
-
- return EAS_SUCCESS;
+ EAS_RESULT result;
+ EAS_U32 structSize;
+ EAS_U32 numConnections;
+ EAS_U16 source;
+ EAS_U16 control;
+ EAS_U16 destination;
+ EAS_U16 transform;
+ EAS_I32 scale;
+ EAS_INT i;
+
+ /* seek to start of data */
+ if ((result = EAS_HWFileSeek(pDLSData->hwInstData, pDLSData->fileHandle, pos)) != EAS_SUCCESS)
+ return result;
+
+ /* get the structure size */
+ if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, &structSize, EAS_FALSE)) != EAS_SUCCESS)
+ return result;
+ pos += (EAS_I32) structSize;
+
+ /* get the number of connections */
+ if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, &numConnections, EAS_FALSE)) != EAS_SUCCESS)
+ return result;
+
+ /* skip to start of connections */
+ if ((result = EAS_HWFileSeek(pDLSData->hwInstData, pDLSData->fileHandle, pos)) != EAS_SUCCESS)
+ return result;
+
+ while (numConnections--)
+ {
+
+ /* read the connection data */
+ if ((result = EAS_HWGetWord(pDLSData->hwInstData, pDLSData->fileHandle, &source, EAS_FALSE)) != EAS_SUCCESS)
+ return result;
+ if ((result = EAS_HWGetWord(pDLSData->hwInstData, pDLSData->fileHandle, &control, EAS_FALSE)) != EAS_SUCCESS)
+ return result;
+ if ((result = EAS_HWGetWord(pDLSData->hwInstData, pDLSData->fileHandle, &destination, EAS_FALSE)) != EAS_SUCCESS)
+ return result;
+ if ((result = EAS_HWGetWord(pDLSData->hwInstData, pDLSData->fileHandle, &transform, EAS_FALSE)) != EAS_SUCCESS)
+ return result;
+ if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, &scale, EAS_FALSE)) != EAS_SUCCESS)
+ return result;
+
+ /* look up the connection */
+ for (i = 0; i < (EAS_INT) ENTRIES_IN_CONN_TABLE; i++)
+ {
+ if ((connTable[i].source == source) &&
+ (connTable[i].destination == destination) &&
+ (connTable[i].control == control))
+ {
+ /*lint -e{704} use shift for performance */
+ pArt->values[connTable[i].connection] = (EAS_I16) (scale >> 16);
+ pArt->values[PARAM_MODIFIED] = EAS_TRUE;
+ break;
+ }
+ }
+ if (i == PARAM_TABLE_SIZE)
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "WARN: Unsupported parameter in DLS file\n"); */ }
+ }
+
+ return EAS_SUCCESS;
}
/*----------------------------------------------------------------------------
* Parse_wlnk ()
*----------------------------------------------------------------------------
- * Purpose:
- *
+ * Purpose:
+ *
*
* Inputs:
- *
- *
+ *
+ *
* Outputs:
- *
+ *
*
*----------------------------------------------------------------------------
*/
static EAS_RESULT Parse_wlnk (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 pos, EAS_U32 *pWaveIndex)
{
- EAS_RESULT result;
+ EAS_RESULT result;
- /* we only care about the the index */
- if ((result = EAS_HWFileSeek(pDLSData->hwInstData, pDLSData->fileHandle, pos + 8)) != EAS_SUCCESS)
- return result;
+ /* we only care about the the index */
+ if ((result = EAS_HWFileSeek(pDLSData->hwInstData, pDLSData->fileHandle, pos + 8)) != EAS_SUCCESS)
+ return result;
- /* read the index */
- return EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle,pWaveIndex, EAS_FALSE);
+ /* read the index */
+ return EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle,pWaveIndex, EAS_FALSE);
}
/*----------------------------------------------------------------------------
* PopcdlStack ()
*----------------------------------------------------------------------------
- * Purpose:
- *
+ * Purpose:
+ *
*
* Inputs:
- *
- *
+ *
+ *
* Outputs:
- *
+ *
*
*----------------------------------------------------------------------------
*/
static EAS_RESULT PopcdlStack (EAS_U32 *pStack, EAS_INT *pStackPtr, EAS_U32 *pValue)
{
- /* stack underflow, cdl block has an errorr */
- if (*pStackPtr < 0)
- return EAS_ERROR_FILE_FORMAT;
+ /* stack underflow, cdl block has an errorr */
+ if (*pStackPtr < 0)
+ return EAS_ERROR_FILE_FORMAT;
- /* pop the value off the stack */
- *pValue = pStack[*pStackPtr];
- *pStackPtr = *pStackPtr - 1;
- return EAS_SUCCESS;
+ /* pop the value off the stack */
+ *pValue = pStack[*pStackPtr];
+ *pStackPtr = *pStackPtr - 1;
+ return EAS_SUCCESS;
}
/*----------------------------------------------------------------------------
* PushcdlStack ()
*----------------------------------------------------------------------------
- * Purpose:
- *
+ * Purpose:
+ *
*
* Inputs:
- *
- *
+ *
+ *
* Outputs:
- *
+ *
*
*----------------------------------------------------------------------------
*/
static EAS_RESULT PushcdlStack (EAS_U32 *pStack, EAS_INT *pStackPtr, EAS_U32 value)
{
- /* stack overflow, return an error */
- if (*pStackPtr >= CDL_STACK_SIZE)
- return EAS_ERROR_FILE_FORMAT;
+ /* stack overflow, return an error */
+ if (*pStackPtr >= CDL_STACK_SIZE)
+ return EAS_ERROR_FILE_FORMAT;
- /* push the value onto the stack */
- *pStackPtr = *pStackPtr + 1;
- pStack[*pStackPtr] = value;
- return EAS_SUCCESS;
+ /* push the value onto the stack */
+ *pStackPtr = *pStackPtr + 1;
+ pStack[*pStackPtr] = value;
+ return EAS_SUCCESS;
}
/*----------------------------------------------------------------------------
* QueryGUID ()
*----------------------------------------------------------------------------
- * Purpose:
- *
+ * Purpose:
+ *
*
* Inputs:
- *
- *
+ *
+ *
* Outputs:
- *
+ *
*
*----------------------------------------------------------------------------
*/
static EAS_BOOL QueryGUID (const DLSID *pGUID, EAS_U32 *pValue)
{
- /* assume false */
- *pValue = 0;
- if (EAS_HWMemCmp(&DLSID_GMInHardware, pGUID, sizeof(DLSID)) == 0)
- {
- *pValue = 0xffffffff;
- return EAS_TRUE;
- }
-
- if (EAS_HWMemCmp(&DLSID_GSInHardware, pGUID, sizeof(DLSID)) == 0)
- return EAS_TRUE;
-
- if (EAS_HWMemCmp(&DLSID_XGInHardware, pGUID, sizeof(DLSID)) == 0)
- return EAS_TRUE;
-
- if (EAS_HWMemCmp(&DLSID_SupportsDLS1, pGUID, sizeof(DLSID)) == 0)
- {
- *pValue = 0xffffffff;
- return EAS_TRUE;
- }
-
- if (EAS_HWMemCmp(&DLSID_SupportsDLS2, pGUID, sizeof(DLSID)) == 0)
- return EAS_TRUE;
-
- if (EAS_HWMemCmp(&DLSID_SampleMemorySize, pGUID, sizeof(DLSID)) == 0)
- {
- *pValue = MAX_DLS_MEMORY;
- return EAS_TRUE;
- }
-
- if (EAS_HWMemCmp(&DLSID_ManufacturersID, pGUID, sizeof(DLSID)) == 0)
- {
- *pValue = 0x0000013A;
- return EAS_TRUE;
- }
-
- if (EAS_HWMemCmp(&DLSID_ProductID, pGUID, sizeof(DLSID)) == 0)
- {
- *pValue = LIB_VERSION;
- return EAS_TRUE;
- }
-
- if (EAS_HWMemCmp(&DLSID_SamplePlaybackRate, pGUID, sizeof(DLSID)) == 0)
- {
- *pValue = (EAS_U32) outputSampleRate;
- return EAS_TRUE;
- }
-
- /* unrecognized DLSID */
- return EAS_FALSE;
+ /* assume false */
+ *pValue = 0;
+ if (EAS_HWMemCmp(&DLSID_GMInHardware, pGUID, sizeof(DLSID)) == 0)
+ {
+ *pValue = 0xffffffff;
+ return EAS_TRUE;
+ }
+
+ if (EAS_HWMemCmp(&DLSID_GSInHardware, pGUID, sizeof(DLSID)) == 0)
+ return EAS_TRUE;
+
+ if (EAS_HWMemCmp(&DLSID_XGInHardware, pGUID, sizeof(DLSID)) == 0)
+ return EAS_TRUE;
+
+ if (EAS_HWMemCmp(&DLSID_SupportsDLS1, pGUID, sizeof(DLSID)) == 0)
+ {
+ *pValue = 0xffffffff;
+ return EAS_TRUE;
+ }
+
+ if (EAS_HWMemCmp(&DLSID_SupportsDLS2, pGUID, sizeof(DLSID)) == 0)
+ return EAS_TRUE;
+
+ if (EAS_HWMemCmp(&DLSID_SampleMemorySize, pGUID, sizeof(DLSID)) == 0)
+ {
+ *pValue = MAX_DLS_MEMORY;
+ return EAS_TRUE;
+ }
+
+ if (EAS_HWMemCmp(&DLSID_ManufacturersID, pGUID, sizeof(DLSID)) == 0)
+ {
+ *pValue = 0x0000013A;
+ return EAS_TRUE;
+ }
+
+ if (EAS_HWMemCmp(&DLSID_ProductID, pGUID, sizeof(DLSID)) == 0)
+ {
+ *pValue = LIB_VERSION;
+ return EAS_TRUE;
+ }
+
+ if (EAS_HWMemCmp(&DLSID_SamplePlaybackRate, pGUID, sizeof(DLSID)) == 0)
+ {
+ *pValue = (EAS_U32) outputSampleRate;
+ return EAS_TRUE;
+ }
+
+ /* unrecognized DLSID */
+ return EAS_FALSE;
}
/*----------------------------------------------------------------------------
* ReadDLSID ()
*----------------------------------------------------------------------------
- * Purpose:
+ * Purpose:
* Reads a DLSID in a manner that is not sensitive to processor endian-ness
*
* Inputs:
- *
- *
+ *
+ *
* Outputs:
- *
+ *
*
*----------------------------------------------------------------------------
*/
static EAS_RESULT ReadDLSID (SDLS_SYNTHESIZER_DATA *pDLSData, DLSID *pDLSID)
{
- EAS_RESULT result;
- EAS_I32 n;
-
- if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, &pDLSID->Data1, EAS_FALSE)) != EAS_SUCCESS)
- return result;
- if ((result = EAS_HWGetWord(pDLSData->hwInstData, pDLSData->fileHandle, &pDLSID->Data2, EAS_FALSE)) != EAS_SUCCESS)
- return result;
- if ((result = EAS_HWGetWord(pDLSData->hwInstData, pDLSData->fileHandle, &pDLSID->Data3, EAS_FALSE)) != EAS_SUCCESS)
- return result;
- return EAS_HWReadFile(pDLSData->hwInstData, pDLSData->fileHandle, pDLSID->Data4, sizeof(pDLSID->Data4), &n);
+ EAS_RESULT result;
+ EAS_I32 n;
+
+ if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, &pDLSID->Data1, EAS_FALSE)) != EAS_SUCCESS)
+ return result;
+ if ((result = EAS_HWGetWord(pDLSData->hwInstData, pDLSData->fileHandle, &pDLSID->Data2, EAS_FALSE)) != EAS_SUCCESS)
+ return result;
+ if ((result = EAS_HWGetWord(pDLSData->hwInstData, pDLSData->fileHandle, &pDLSID->Data3, EAS_FALSE)) != EAS_SUCCESS)
+ return result;
+ return EAS_HWReadFile(pDLSData->hwInstData, pDLSData->fileHandle, pDLSID->Data4, sizeof(pDLSID->Data4), &n);
}
/*----------------------------------------------------------------------------
* Parse_cdl ()
*----------------------------------------------------------------------------
- * Purpose:
- *
+ * Purpose:
+ *
*
* Inputs:
- *
- *
+ *
+ *
* Outputs:
- *
+ *
*
*----------------------------------------------------------------------------
*/
static EAS_RESULT Parse_cdl (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 size, EAS_U32 *pValue)
{
- EAS_RESULT result;
- EAS_U32 stack[CDL_STACK_SIZE];
- EAS_U16 opcode;
- EAS_INT stackPtr;
- EAS_U32 x, y;
- DLSID dlsid;
-
- stackPtr = -1;
- *pValue = 0;
- x = 0;
- while (size)
- {
- /* read the opcode */
- if ((result = EAS_HWGetWord(pDLSData->hwInstData, pDLSData->fileHandle, &opcode, EAS_FALSE)) != EAS_SUCCESS)
- return result;
-
- /* handle binary opcodes */
- if (opcode <= DLS_CDL_EQ)
- {
- /* pop X and Y */
- if ((result = PopcdlStack(stack, &stackPtr, &x)) != EAS_SUCCESS)
- return result;
- if ((result = PopcdlStack(stack, &stackPtr, &y)) != EAS_SUCCESS)
- return result;
- switch (opcode)
- {
- case DLS_CDL_AND:
- x = x & y;
- break;
- case DLS_CDL_OR:
- x = x | y;
- break;
- case DLS_CDL_XOR:
- x = x ^ y;
- break;
- case DLS_CDL_ADD:
- x = x + y;
- break;
- case DLS_CDL_SUBTRACT:
- x = x - y;
- break;
- case DLS_CDL_MULTIPLY:
- x = x * y;
- break;
- case DLS_CDL_DIVIDE:
- if (!y)
- return EAS_ERROR_FILE_FORMAT;
- x = x / y;
- break;
- case DLS_CDL_LOGICAL_AND:
- x = (x && y);
- break;
- case DLS_CDL_LOGICAL_OR:
- x = (x || y);
- break;
- case DLS_CDL_LT:
- x = (x < y);
- break;
- case DLS_CDL_LE:
- x = (x <= y);
- break;
- case DLS_CDL_GT:
- x = (x > y);
- break;
- case DLS_CDL_GE:
- x = (x >= y);
- break;
- case DLS_CDL_EQ:
- x = (x == y);
- break;
- default:
- break;
- }
- }
-
- else if (opcode == DLS_CDL_NOT)
- {
- if ((result = PopcdlStack(stack, &stackPtr, &x)) != EAS_SUCCESS)
- return result;
- x = !x;
- }
-
- else if (opcode == DLS_CDL_CONST)
- {
- if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, &x, EAS_FALSE)) != EAS_SUCCESS)
- return result;
- }
-
- else if (opcode == DLS_CDL_QUERY)
- {
- if ((result = ReadDLSID(pDLSData, &dlsid)) != EAS_SUCCESS)
- return result;
- QueryGUID(&dlsid, &x);
- }
-
- else if (opcode == DLS_CDL_QUERYSUPPORTED)
- {
- if ((result = ReadDLSID(pDLSData, &dlsid)) != EAS_SUCCESS)
- return result;
- x = QueryGUID(&dlsid, &y);
- }
- else
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Unsupported opcode %d in DLS file\n", opcode); */ }
-
- /* push the result on the stack */
- if ((result = PushcdlStack(stack, &stackPtr, x)) != EAS_SUCCESS)
- return result;
- }
-
- /* pop the last result off the stack */
- return PopcdlStack(stack, &stackPtr, pValue);
+ EAS_RESULT result;
+ EAS_U32 stack[CDL_STACK_SIZE];
+ EAS_U16 opcode;
+ EAS_INT stackPtr;
+ EAS_U32 x, y;
+ DLSID dlsid;
+
+ stackPtr = -1;
+ *pValue = 0;
+ x = 0;
+ while (size)
+ {
+ /* read the opcode */
+ if ((result = EAS_HWGetWord(pDLSData->hwInstData, pDLSData->fileHandle, &opcode, EAS_FALSE)) != EAS_SUCCESS)
+ return result;
+
+ /* handle binary opcodes */
+ if (opcode <= DLS_CDL_EQ)
+ {
+ /* pop X and Y */
+ if ((result = PopcdlStack(stack, &stackPtr, &x)) != EAS_SUCCESS)
+ return result;
+ if ((result = PopcdlStack(stack, &stackPtr, &y)) != EAS_SUCCESS)
+ return result;
+ switch (opcode)
+ {
+ case DLS_CDL_AND:
+ x = x & y;
+ break;
+ case DLS_CDL_OR:
+ x = x | y;
+ break;
+ case DLS_CDL_XOR:
+ x = x ^ y;
+ break;
+ case DLS_CDL_ADD:
+ x = x + y;
+ break;
+ case DLS_CDL_SUBTRACT:
+ x = x - y;
+ break;
+ case DLS_CDL_MULTIPLY:
+ x = x * y;
+ break;
+ case DLS_CDL_DIVIDE:
+ if (!y)
+ return EAS_ERROR_FILE_FORMAT;
+ x = x / y;
+ break;
+ case DLS_CDL_LOGICAL_AND:
+ x = (x && y);
+ break;
+ case DLS_CDL_LOGICAL_OR:
+ x = (x || y);
+ break;
+ case DLS_CDL_LT:
+ x = (x < y);
+ break;
+ case DLS_CDL_LE:
+ x = (x <= y);
+ break;
+ case DLS_CDL_GT:
+ x = (x > y);
+ break;
+ case DLS_CDL_GE:
+ x = (x >= y);
+ break;
+ case DLS_CDL_EQ:
+ x = (x == y);
+ break;
+ default:
+ break;
+ }
+ }
+
+ else if (opcode == DLS_CDL_NOT)
+ {
+ if ((result = PopcdlStack(stack, &stackPtr, &x)) != EAS_SUCCESS)
+ return result;
+ x = !x;
+ }
+
+ else if (opcode == DLS_CDL_CONST)
+ {
+ if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, &x, EAS_FALSE)) != EAS_SUCCESS)
+ return result;
+ }
+
+ else if (opcode == DLS_CDL_QUERY)
+ {
+ if ((result = ReadDLSID(pDLSData, &dlsid)) != EAS_SUCCESS)
+ return result;
+ QueryGUID(&dlsid, &x);
+ }
+
+ else if (opcode == DLS_CDL_QUERYSUPPORTED)
+ {
+ if ((result = ReadDLSID(pDLSData, &dlsid)) != EAS_SUCCESS)
+ return result;
+ x = QueryGUID(&dlsid, &y);
+ }
+ else
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Unsupported opcode %d in DLS file\n", opcode); */ }
+
+ /* push the result on the stack */
+ if ((result = PushcdlStack(stack, &stackPtr, x)) != EAS_SUCCESS)
+ return result;
+ }
+
+ /* pop the last result off the stack */
+ return PopcdlStack(stack, &stackPtr, pValue);
}
/*----------------------------------------------------------------------------
* Convert_rgn()
*----------------------------------------------------------------------------
- * Purpose:
+ * Purpose:
* Convert region data from DLS to EAS
*
* Inputs:
- *
- *
+ *
+ *
* Outputs:
- *
+ *
*
*----------------------------------------------------------------------------
*/
static void Convert_rgn (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_U16 regionIndex, EAS_U16 artIndex, EAS_U16 waveIndex, S_WSMP_DATA *pWsmp)
{
- S_DLS_REGION *pRgn;
-
- /* setup pointers to data structures */
- pRgn = &pDLSData->pDLS->pDLSRegions[regionIndex];
-
- /* intiailize indices */
- pRgn->wtRegion.artIndex = artIndex;
- pRgn->wtRegion.waveIndex = waveIndex;
-
- /* convert region data */
- /*lint -e{704} use shift for performance */
- pRgn->wtRegion.gain = (EAS_I16) (pWsmp->gain >> 16);
- pRgn->wtRegion.loopStart = pWsmp->loopStart;
- pRgn->wtRegion.loopEnd = (pWsmp->loopStart + pWsmp->loopLength);
- pRgn->wtRegion.tuning = pWsmp->fineTune -(pWsmp->unityNote * 100) + ConvertSampleRate(pWsmp->sampleRate);
- if (pWsmp->loopLength != 0)
- pRgn->wtRegion.region.keyGroupAndFlags |= REGION_FLAG_IS_LOOPED;
+ S_DLS_REGION *pRgn;
+
+ /* setup pointers to data structures */
+ pRgn = &pDLSData->pDLS->pDLSRegions[regionIndex];
+
+ /* intiailize indices */
+ pRgn->wtRegion.artIndex = artIndex;
+ pRgn->wtRegion.waveIndex = waveIndex;
+
+ /* convert region data */
+ /*lint -e{704} use shift for performance */
+ pRgn->wtRegion.gain = (EAS_I16) (pWsmp->gain >> 16);
+ pRgn->wtRegion.loopStart = pWsmp->loopStart;
+ pRgn->wtRegion.loopEnd = (pWsmp->loopStart + pWsmp->loopLength);
+ pRgn->wtRegion.tuning = pWsmp->fineTune -(pWsmp->unityNote * 100) + ConvertSampleRate(pWsmp->sampleRate);
+ if (pWsmp->loopLength != 0)
+ pRgn->wtRegion.region.keyGroupAndFlags |= REGION_FLAG_IS_LOOPED;
}
/*----------------------------------------------------------------------------
* Convert_art()
*----------------------------------------------------------------------------
- * Purpose:
+ * Purpose:
* Convert articulation data from DLS to EAS
*
* Inputs:
- *
- *
+ *
+ *
* Outputs:
- *
+ *
*
*----------------------------------------------------------------------------
*/
static void Convert_art (SDLS_SYNTHESIZER_DATA *pDLSData, const S_DLS_ART_VALUES *pDLSArt, EAS_U16 artIndex)
{
- S_DLS_ARTICULATION *pArt;
-
- /* setup pointers to data structures */
- pArt = &pDLSData->pDLS->pDLSArticulations[artIndex];
-
- /* LFO parameters */
- pArt->modLFO.lfoFreq = ConvertLFOPhaseIncrement(pDLSArt->values[PARAM_MOD_LFO_FREQ]);
- pArt->modLFO.lfoDelay = -ConvertDelay(pDLSArt->values[PARAM_MOD_LFO_DELAY]);
- pArt->vibLFO.lfoFreq = ConvertLFOPhaseIncrement(pDLSArt->values[PARAM_VIB_LFO_FREQ]);
- pArt->vibLFO.lfoDelay = -ConvertDelay(pDLSArt->values[PARAM_VIB_LFO_DELAY]);
-
- /* EG1 parameters */
- pArt->eg1.delayTime = ConvertDelay(pDLSArt->values[PARAM_VOL_EG_DELAY]);
- pArt->eg1.attackTime = pDLSArt->values[PARAM_VOL_EG_ATTACK];
- pArt->eg1.holdTime = pDLSArt->values[PARAM_VOL_EG_HOLD];
- pArt->eg1.decayTime = pDLSArt->values[PARAM_VOL_EG_DECAY];
- pArt->eg1.sustainLevel = ConvertSustain(pDLSArt->values[PARAM_VOL_EG_SUSTAIN]);
- pArt->eg1.releaseTime = ConvertRate(pDLSArt->values[PARAM_VOL_EG_RELEASE]);
- pArt->eg1.velToAttack = pDLSArt->values[PARAM_VOL_EG_VEL_TO_ATTACK];
- pArt->eg1.keyNumToDecay = pDLSArt->values[PARAM_VOL_EG_KEY_TO_DECAY];
- pArt->eg1.keyNumToHold = pDLSArt->values[PARAM_VOL_EG_KEY_TO_HOLD];
- pArt->eg1ShutdownTime = ConvertRate(pDLSArt->values[PARAM_VOL_EG_SHUTDOWN]);
-
- /* EG2 parameters */
- pArt->eg2.delayTime = ConvertDelay(pDLSArt->values[PARAM_MOD_EG_DELAY]);
- pArt->eg2.attackTime = pDLSArt->values[PARAM_MOD_EG_ATTACK];
- pArt->eg2.holdTime = pDLSArt->values[PARAM_MOD_EG_HOLD];
- pArt->eg2.decayTime = pDLSArt->values[PARAM_MOD_EG_DECAY];
- pArt->eg2.sustainLevel = ConvertSustain(pDLSArt->values[PARAM_MOD_EG_SUSTAIN]);
- pArt->eg2.releaseTime = ConvertRate(pDLSArt->values[PARAM_MOD_EG_RELEASE]);
- pArt->eg2.velToAttack = pDLSArt->values[PARAM_MOD_EG_VEL_TO_ATTACK];
- pArt->eg2.keyNumToDecay = pDLSArt->values[PARAM_MOD_EG_KEY_TO_DECAY];
- pArt->eg2.keyNumToHold = pDLSArt->values[PARAM_MOD_EG_KEY_TO_HOLD];
-
- /* filter parameters */
- pArt->filterCutoff = pDLSArt->values[PARAM_INITIAL_FC];
- pArt->filterQandFlags = ConvertQ(pDLSArt->values[PARAM_INITIAL_Q]);
- pArt->modLFOToFc = pDLSArt->values[PARAM_MOD_LFO_TO_FC];
- pArt->modLFOCC1ToFc = pDLSArt->values[PARAM_MOD_LFO_CC1_TO_FC];
- pArt->modLFOChanPressToFc = pDLSArt->values[PARAM_MOD_LFO_CHAN_PRESS_TO_FC];
- pArt->eg2ToFc = pDLSArt->values[PARAM_MOD_EG_TO_FC];
- pArt->velToFc = pDLSArt->values[PARAM_VEL_TO_FC];
- pArt->keyNumToFc = pDLSArt->values[PARAM_KEYNUM_TO_FC];
-
- /* gain parameters */
- pArt->modLFOToGain = pDLSArt->values[PARAM_MOD_LFO_TO_GAIN];
- pArt->modLFOCC1ToGain = pDLSArt->values[PARAM_MOD_LFO_CC1_TO_GAIN];
- pArt->modLFOChanPressToGain = pDLSArt->values[PARAM_MOD_LFO_CHAN_PRESS_TO_GAIN];
-
- /* pitch parameters */
- pArt->tuning = pDLSArt->values[PARAM_TUNING];
- pArt->keyNumToPitch = pDLSArt->values[PARAM_KEYNUM_TO_PITCH];
- pArt->vibLFOToPitch = pDLSArt->values[PARAM_VIB_LFO_TO_PITCH];
- pArt->vibLFOCC1ToPitch = pDLSArt->values[PARAM_VIB_LFO_CC1_TO_PITCH];
- pArt->vibLFOChanPressToPitch = pDLSArt->values[PARAM_VIB_LFO_CHAN_PRESS_TO_PITCH];
- pArt->modLFOToPitch = pDLSArt->values[PARAM_MOD_LFO_TO_PITCH];
- pArt->modLFOCC1ToPitch = pDLSArt->values[PARAM_MOD_LFO_CC1_TO_PITCH];
- pArt->modLFOChanPressToPitch = pDLSArt->values[PARAM_MOD_LFO_CHAN_PRESS_TO_PITCH];
- pArt->eg2ToPitch = pDLSArt->values[PARAM_MOD_EG_TO_PITCH];
-
- /* output parameters */
- pArt->pan = ConvertPan(pDLSArt->values[PARAM_DEFAULT_PAN]);
-
- if (pDLSArt->values[PARAM_VEL_TO_GAIN] != 0)
- pArt->filterQandFlags |= FLAG_DLS_VELOCITY_SENSITIVE;
-
-#ifdef _REVERB
- pArt->reverbSend = pDLSArt->values[PARAM_DEFAULT_REVERB_SEND];
- pArt->cc91ToReverbSend = pDLSArt->values[PARAM_MIDI_CC91_TO_REVERB_SEND];
+ S_DLS_ARTICULATION *pArt;
+
+ /* setup pointers to data structures */
+ pArt = &pDLSData->pDLS->pDLSArticulations[artIndex];
+
+ /* LFO parameters */
+ pArt->modLFO.lfoFreq = ConvertLFOPhaseIncrement(pDLSArt->values[PARAM_MOD_LFO_FREQ]);
+ pArt->modLFO.lfoDelay = -ConvertDelay(pDLSArt->values[PARAM_MOD_LFO_DELAY]);
+ pArt->vibLFO.lfoFreq = ConvertLFOPhaseIncrement(pDLSArt->values[PARAM_VIB_LFO_FREQ]);
+ pArt->vibLFO.lfoDelay = -ConvertDelay(pDLSArt->values[PARAM_VIB_LFO_DELAY]);
+
+ /* EG1 parameters */
+ pArt->eg1.delayTime = ConvertDelay(pDLSArt->values[PARAM_VOL_EG_DELAY]);
+ pArt->eg1.attackTime = pDLSArt->values[PARAM_VOL_EG_ATTACK];
+ pArt->eg1.holdTime = pDLSArt->values[PARAM_VOL_EG_HOLD];
+ pArt->eg1.decayTime = pDLSArt->values[PARAM_VOL_EG_DECAY];
+ pArt->eg1.sustainLevel = ConvertSustain(pDLSArt->values[PARAM_VOL_EG_SUSTAIN]);
+ pArt->eg1.releaseTime = ConvertRate(pDLSArt->values[PARAM_VOL_EG_RELEASE]);
+ pArt->eg1.velToAttack = pDLSArt->values[PARAM_VOL_EG_VEL_TO_ATTACK];
+ pArt->eg1.keyNumToDecay = pDLSArt->values[PARAM_VOL_EG_KEY_TO_DECAY];
+ pArt->eg1.keyNumToHold = pDLSArt->values[PARAM_VOL_EG_KEY_TO_HOLD];
+ pArt->eg1ShutdownTime = ConvertRate(pDLSArt->values[PARAM_VOL_EG_SHUTDOWN]);
+
+ /* EG2 parameters */
+ pArt->eg2.delayTime = ConvertDelay(pDLSArt->values[PARAM_MOD_EG_DELAY]);
+ pArt->eg2.attackTime = pDLSArt->values[PARAM_MOD_EG_ATTACK];
+ pArt->eg2.holdTime = pDLSArt->values[PARAM_MOD_EG_HOLD];
+ pArt->eg2.decayTime = pDLSArt->values[PARAM_MOD_EG_DECAY];
+ pArt->eg2.sustainLevel = ConvertSustain(pDLSArt->values[PARAM_MOD_EG_SUSTAIN]);
+ pArt->eg2.releaseTime = ConvertRate(pDLSArt->values[PARAM_MOD_EG_RELEASE]);
+ pArt->eg2.velToAttack = pDLSArt->values[PARAM_MOD_EG_VEL_TO_ATTACK];
+ pArt->eg2.keyNumToDecay = pDLSArt->values[PARAM_MOD_EG_KEY_TO_DECAY];
+ pArt->eg2.keyNumToHold = pDLSArt->values[PARAM_MOD_EG_KEY_TO_HOLD];
+
+ /* filter parameters */
+ pArt->filterCutoff = pDLSArt->values[PARAM_INITIAL_FC];
+ pArt->filterQandFlags = ConvertQ(pDLSArt->values[PARAM_INITIAL_Q]);
+ pArt->modLFOToFc = pDLSArt->values[PARAM_MOD_LFO_TO_FC];
+ pArt->modLFOCC1ToFc = pDLSArt->values[PARAM_MOD_LFO_CC1_TO_FC];
+ pArt->modLFOChanPressToFc = pDLSArt->values[PARAM_MOD_LFO_CHAN_PRESS_TO_FC];
+ pArt->eg2ToFc = pDLSArt->values[PARAM_MOD_EG_TO_FC];
+ pArt->velToFc = pDLSArt->values[PARAM_VEL_TO_FC];
+ pArt->keyNumToFc = pDLSArt->values[PARAM_KEYNUM_TO_FC];
+
+ /* gain parameters */
+ pArt->modLFOToGain = pDLSArt->values[PARAM_MOD_LFO_TO_GAIN];
+ pArt->modLFOCC1ToGain = pDLSArt->values[PARAM_MOD_LFO_CC1_TO_GAIN];
+ pArt->modLFOChanPressToGain = pDLSArt->values[PARAM_MOD_LFO_CHAN_PRESS_TO_GAIN];
+
+ /* pitch parameters */
+ pArt->tuning = pDLSArt->values[PARAM_TUNING];
+ pArt->keyNumToPitch = pDLSArt->values[PARAM_KEYNUM_TO_PITCH];
+ pArt->vibLFOToPitch = pDLSArt->values[PARAM_VIB_LFO_TO_PITCH];
+ pArt->vibLFOCC1ToPitch = pDLSArt->values[PARAM_VIB_LFO_CC1_TO_PITCH];
+ pArt->vibLFOChanPressToPitch = pDLSArt->values[PARAM_VIB_LFO_CHAN_PRESS_TO_PITCH];
+ pArt->modLFOToPitch = pDLSArt->values[PARAM_MOD_LFO_TO_PITCH];
+ pArt->modLFOCC1ToPitch = pDLSArt->values[PARAM_MOD_LFO_CC1_TO_PITCH];
+ pArt->modLFOChanPressToPitch = pDLSArt->values[PARAM_MOD_LFO_CHAN_PRESS_TO_PITCH];
+ pArt->eg2ToPitch = pDLSArt->values[PARAM_MOD_EG_TO_PITCH];
+
+ /* output parameters */
+ pArt->pan = ConvertPan(pDLSArt->values[PARAM_DEFAULT_PAN]);
+
+ if (pDLSArt->values[PARAM_VEL_TO_GAIN] != 0)
+ pArt->filterQandFlags |= FLAG_DLS_VELOCITY_SENSITIVE;
+
+#ifdef _REVERB
+ pArt->reverbSend = pDLSArt->values[PARAM_DEFAULT_REVERB_SEND];
+ pArt->cc91ToReverbSend = pDLSArt->values[PARAM_MIDI_CC91_TO_REVERB_SEND];
#endif
#ifdef _CHORUS
- pArt->chorusSend = pDLSArt->values[PARAM_DEFAULT_CHORUS_SEND];
- pArt->cc93ToChorusSend = pDLSArt->values[PARAM_MIDI_CC93_TO_CHORUS_SEND];
-#endif
+ pArt->chorusSend = pDLSArt->values[PARAM_DEFAULT_CHORUS_SEND];
+ pArt->cc93ToChorusSend = pDLSArt->values[PARAM_MIDI_CC93_TO_CHORUS_SEND];
+#endif
}
/*----------------------------------------------------------------------------
* ConvertSampleRate()
*----------------------------------------------------------------------------
- * Purpose:
+ * Purpose:
*
- * Inputs:
+ * Inputs:
*
* Outputs:
*
@@ -2421,7 +2421,7 @@ static void Convert_art (SDLS_SYNTHESIZER_DATA *pDLSData, const S_DLS_ART_VALUES
*/
static EAS_I16 ConvertSampleRate (EAS_U32 sampleRate)
{
- return (EAS_I16) (1200.0 * log10((double) sampleRate / (double) outputSampleRate) / log10(2.0));
+ return (EAS_I16) (1200.0 * log10((double) sampleRate / (double) outputSampleRate) / log10(2.0));
}
/*----------------------------------------------------------------------------
@@ -2432,17 +2432,17 @@ static EAS_I16 ConvertSampleRate (EAS_U32 sampleRate)
*/
static EAS_I16 ConvertSustain (EAS_I32 sustain)
{
- /* check for sustain level of zero */
- if (sustain == 0)
- return 0;
+ /* check for sustain level of zero */
+ if (sustain == 0)
+ return 0;
- /* convert to log2 factor */
- /*lint -e{704} use shift for performance */
- sustain = (sustain * SUSTAIN_LINEAR_CONVERSION_FACTOR) >> 15;
+ /* convert to log2 factor */
+ /*lint -e{704} use shift for performance */
+ sustain = (sustain * SUSTAIN_LINEAR_CONVERSION_FACTOR) >> 15;
- if (sustain > SYNTH_FULL_SCALE_EG1_GAIN)
- return SYNTH_FULL_SCALE_EG1_GAIN;
- return (EAS_I16) sustain;
+ if (sustain > SYNTH_FULL_SCALE_EG1_GAIN)
+ return SYNTH_FULL_SCALE_EG1_GAIN;
+ return (EAS_I16) sustain;
}
/*----------------------------------------------------------------------------
@@ -2454,23 +2454,23 @@ static EAS_I16 ConvertSustain (EAS_I32 sustain)
*/
EAS_I16 ConvertDelay (EAS_I32 timeCents)
{
- EAS_I32 temp;
+ EAS_I32 temp;
+
+ if (timeCents == ZERO_TIME_IN_CENTS)
+ return 0;
- if (timeCents == ZERO_TIME_IN_CENTS)
- return 0;
+ /* divide time by secs per frame to get number of frames */
+ temp = timeCents - dlsRateConvert;
- /* divide time by secs per frame to get number of frames */
- temp = timeCents - dlsRateConvert;
+ /* convert from time cents to 10-bit fraction */
+ temp = FMUL_15x15(temp, TIME_CENTS_TO_LOG2);
- /* convert from time cents to 10-bit fraction */
- temp = FMUL_15x15(temp, TIME_CENTS_TO_LOG2);
-
- /* convert to frame count */
- temp = EAS_LogToLinear16(temp - (15 << 10));
+ /* convert to frame count */
+ temp = EAS_LogToLinear16(temp - (15 << 10));
- if (temp < SYNTH_FULL_SCALE_EG1_GAIN)
- return (EAS_I16) temp;
- return SYNTH_FULL_SCALE_EG1_GAIN;
+ if (temp < SYNTH_FULL_SCALE_EG1_GAIN)
+ return (EAS_I16) temp;
+ return SYNTH_FULL_SCALE_EG1_GAIN;
}
/*----------------------------------------------------------------------------
@@ -2481,36 +2481,36 @@ EAS_I16 ConvertDelay (EAS_I32 timeCents)
*/
EAS_I16 ConvertRate (EAS_I32 timeCents)
{
- EAS_I32 temp;
+ EAS_I32 temp;
- if (timeCents == ZERO_TIME_IN_CENTS)
- return SYNTH_FULL_SCALE_EG1_GAIN;
+ if (timeCents == ZERO_TIME_IN_CENTS)
+ return SYNTH_FULL_SCALE_EG1_GAIN;
- /* divide frame rate by time in log domain to get rate */
- temp = dlsRateConvert - timeCents;
+ /* divide frame rate by time in log domain to get rate */
+ temp = dlsRateConvert - timeCents;
#if 1
- temp = EAS_Calculate2toX(temp);
+ temp = EAS_Calculate2toX(temp);
#else
- /* convert from time cents to 10-bit fraction */
- temp = FMUL_15x15(temp, TIME_CENTS_TO_LOG2);
-
- /* convert to rate */
- temp = EAS_LogToLinear16(temp);
+ /* convert from time cents to 10-bit fraction */
+ temp = FMUL_15x15(temp, TIME_CENTS_TO_LOG2);
+
+ /* convert to rate */
+ temp = EAS_LogToLinear16(temp);
#endif
- if (temp < SYNTH_FULL_SCALE_EG1_GAIN)
- return (EAS_I16) temp;
- return SYNTH_FULL_SCALE_EG1_GAIN;
+ if (temp < SYNTH_FULL_SCALE_EG1_GAIN)
+ return (EAS_I16) temp;
+ return SYNTH_FULL_SCALE_EG1_GAIN;
}
/*----------------------------------------------------------------------------
* ConvertLFOPhaseIncrement()
*----------------------------------------------------------------------------
- * Purpose:
+ * Purpose:
*
- * Inputs:
+ * Inputs:
*
* Outputs:
*
@@ -2519,26 +2519,26 @@ EAS_I16 ConvertRate (EAS_I32 timeCents)
*/
static EAS_I16 ConvertLFOPhaseIncrement (EAS_I32 pitchCents)
{
-
- /* check range */
- if (pitchCents > MAX_LFO_FREQUENCY_IN_PITCHCENTS)
- pitchCents = MAX_LFO_FREQUENCY_IN_PITCHCENTS;
- if (pitchCents < MIN_LFO_FREQUENCY_IN_PITCHCENTS)
- pitchCents = MIN_LFO_FREQUENCY_IN_PITCHCENTS;
-
- /* double the rate and divide by frame rate by subtracting in log domain */
- pitchCents = pitchCents - dlsLFOFrequencyConvert;
-
- /* convert to phase increment */
- return (EAS_I16) EAS_Calculate2toX(pitchCents);
+
+ /* check range */
+ if (pitchCents > MAX_LFO_FREQUENCY_IN_PITCHCENTS)
+ pitchCents = MAX_LFO_FREQUENCY_IN_PITCHCENTS;
+ if (pitchCents < MIN_LFO_FREQUENCY_IN_PITCHCENTS)
+ pitchCents = MIN_LFO_FREQUENCY_IN_PITCHCENTS;
+
+ /* double the rate and divide by frame rate by subtracting in log domain */
+ pitchCents = pitchCents - dlsLFOFrequencyConvert;
+
+ /* convert to phase increment */
+ return (EAS_I16) EAS_Calculate2toX(pitchCents);
}
/*----------------------------------------------------------------------------
* ConvertPan()
*----------------------------------------------------------------------------
- * Purpose:
+ * Purpose:
*
- * Inputs:
+ * Inputs:
*
* Outputs:
*
@@ -2547,14 +2547,14 @@ static EAS_I16 ConvertLFOPhaseIncrement (EAS_I32 pitchCents)
*/
static EAS_I8 ConvertPan (EAS_I32 pan)
{
-
- /* multiply by conversion factor */
- pan = FMUL_15x15 (PAN_CONVERSION_FACTOR, pan);
- if (pan < MIN_PAN_VALUE)
- return MIN_PAN_VALUE;
- if (pan > MAX_PAN_VALUE)
- return MAX_PAN_VALUE;
- return (EAS_I8) pan;
+
+ /* multiply by conversion factor */
+ pan = FMUL_15x15 (PAN_CONVERSION_FACTOR, pan);
+ if (pan < MIN_PAN_VALUE)
+ return MIN_PAN_VALUE;
+ if (pan > MAX_PAN_VALUE)
+ return MAX_PAN_VALUE;
+ return (EAS_I8) pan;
}
/*----------------------------------------------------------------------------
@@ -2567,18 +2567,18 @@ static EAS_I8 ConvertPan (EAS_I32 pan)
static EAS_U8 ConvertQ (EAS_I32 q)
{
- /* apply limits */
- if (q <= 0)
- return 0;
+ /* apply limits */
+ if (q <= 0)
+ return 0;
- /* convert to table index */
- /*lint -e{704} use shift for performance */
- q = (FILTER_Q_CONVERSION_FACTOR * q + 0x4000) >> 15;
+ /* convert to table index */
+ /*lint -e{704} use shift for performance */
+ q = (FILTER_Q_CONVERSION_FACTOR * q + 0x4000) >> 15;
- /* apply upper limit */
- if (q >= FILTER_RESONANCE_NUM_ENTRIES)
- q = FILTER_RESONANCE_NUM_ENTRIES - 1;
- return (EAS_U8) q;
+ /* apply upper limit */
+ if (q >= FILTER_RESONANCE_NUM_ENTRIES)
+ q = FILTER_RESONANCE_NUM_ENTRIES - 1;
+ return (EAS_U8) q;
}
#ifdef _DEBUG_DLS
@@ -2588,80 +2588,80 @@ static EAS_U8 ConvertQ (EAS_I32 q)
*/
static void DumpDLS (S_EAS *pEAS)
{
- S_DLS_ARTICULATION *pArt;
- S_DLS_REGION *pRegion;
- EAS_INT i;
- EAS_INT j;
-
- EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000022 , pEAS->numPrograms);
- EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000023 , pEAS->numWTRegions);
- EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000024 , pEAS->numDLSArticulations);
- EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000025 , pEAS->numSamples);
-
- /* dump the instruments */
- for (i = 0; i < pEAS->numPrograms; i++)
- {
- EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000026 ,
- pEAS->pPrograms[i].locale >> 16,
- (pEAS->pPrograms[i].locale >> 8) & 0x7f,
- pEAS->pPrograms[i].locale & 0x7f);
-
- for (j = pEAS->pPrograms[i].regionIndex; ; j++)
- {
- EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000027 , j);
- pRegion = &pEAS->pWTRegions[j];
- EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000028 , pRegion->gain);
- EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000029 , pRegion->region.rangeLow, pRegion->region.rangeHigh);
- EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x0000002a , pRegion->region.keyGroupAndFlags);
- EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x0000002b , pRegion->loopStart);
- EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x0000002c , pRegion->loopEnd);
- EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x0000002d , pRegion->tuning);
- EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x0000002e , pRegion->artIndex);
- EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x0000002f , pRegion->waveIndex);
-
- if (pRegion->region.keyGroupAndFlags & REGION_FLAG_LAST_REGION)
- break;
- }
-
- }
-
- /* dump the articulation data */
- for (i = 0; i < pEAS->numDLSArticulations; i++)
- {
- /* articulation data */
- EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000030 , i);
- pArt = &pEAS->pDLSArticulations[i];
- EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000031 , pArt->m_nEG2toFilterDepth);
- EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000032 , pArt->m_nEG2toPitchDepth);
- EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000033 , pArt->m_nFilterCutoffFrequency);
- EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000034 , pArt->m_nFilterResonance);
- EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000035 , pArt->m_nLFOAmplitudeDepth);
- EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000036 , pArt->m_nLFODelayTime);
- EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000037 , pArt->m_nLFOFrequency);
- EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000038 , pArt->m_nLFOPitchDepth);
- EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000039 , pArt->m_nPan);
-
- /* EG1 data */
- EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x0000003a , pArt->m_sEG1.m_nAttack);
- EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x0000003b , pArt->m_sEG1.m_nDecay);
- EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x0000003c , pArt->m_sEG1.m_nSustain);
- EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x0000003d , pArt->m_sEG1.m_nRelease);
-
- /* EG2 data */
- EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x0000003e , pArt->m_sEG2.m_nAttack);
- EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x0000003f , pArt->m_sEG2.m_nDecay);
- EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000040 , pArt->m_sEG2.m_nSustain);
- EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000041 , pArt->m_sEG2.m_nRelease);
-
- }
-
- /* dump the waves */
- for (i = 0; i < pEAS->numSamples; i++)
- {
- EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000042 , i);
- EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000043 , pEAS->pSampleLen[i]);
- EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000044 , pEAS->ppSamples[i]);
- }
+ S_DLS_ARTICULATION *pArt;
+ S_DLS_REGION *pRegion;
+ EAS_INT i;
+ EAS_INT j;
+
+ EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000022 , pEAS->numPrograms);
+ EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000023 , pEAS->numWTRegions);
+ EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000024 , pEAS->numDLSArticulations);
+ EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000025 , pEAS->numSamples);
+
+ /* dump the instruments */
+ for (i = 0; i < pEAS->numPrograms; i++)
+ {
+ EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000026 ,
+ pEAS->pPrograms[i].locale >> 16,
+ (pEAS->pPrograms[i].locale >> 8) & 0x7f,
+ pEAS->pPrograms[i].locale & 0x7f);
+
+ for (j = pEAS->pPrograms[i].regionIndex; ; j++)
+ {
+ EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000027 , j);
+ pRegion = &pEAS->pWTRegions[j];
+ EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000028 , pRegion->gain);
+ EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000029 , pRegion->region.rangeLow, pRegion->region.rangeHigh);
+ EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x0000002a , pRegion->region.keyGroupAndFlags);
+ EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x0000002b , pRegion->loopStart);
+ EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x0000002c , pRegion->loopEnd);
+ EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x0000002d , pRegion->tuning);
+ EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x0000002e , pRegion->artIndex);
+ EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x0000002f , pRegion->waveIndex);
+
+ if (pRegion->region.keyGroupAndFlags & REGION_FLAG_LAST_REGION)
+ break;
+ }
+
+ }
+
+ /* dump the articulation data */
+ for (i = 0; i < pEAS->numDLSArticulations; i++)
+ {
+ /* articulation data */
+ EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000030 , i);
+ pArt = &pEAS->pDLSArticulations[i];
+ EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000031 , pArt->m_nEG2toFilterDepth);
+ EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000032 , pArt->m_nEG2toPitchDepth);
+ EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000033 , pArt->m_nFilterCutoffFrequency);
+ EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000034 , pArt->m_nFilterResonance);
+ EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000035 , pArt->m_nLFOAmplitudeDepth);
+ EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000036 , pArt->m_nLFODelayTime);
+ EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000037 , pArt->m_nLFOFrequency);
+ EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000038 , pArt->m_nLFOPitchDepth);
+ EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000039 , pArt->m_nPan);
+
+ /* EG1 data */
+ EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x0000003a , pArt->m_sEG1.m_nAttack);
+ EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x0000003b , pArt->m_sEG1.m_nDecay);
+ EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x0000003c , pArt->m_sEG1.m_nSustain);
+ EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x0000003d , pArt->m_sEG1.m_nRelease);
+
+ /* EG2 data */
+ EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x0000003e , pArt->m_sEG2.m_nAttack);
+ EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x0000003f , pArt->m_sEG2.m_nDecay);
+ EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000040 , pArt->m_sEG2.m_nSustain);
+ EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000041 , pArt->m_sEG2.m_nRelease);
+
+ }
+
+ /* dump the waves */
+ for (i = 0; i < pEAS->numSamples; i++)
+ {
+ EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000042 , i);
+ EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000043 , pEAS->pSampleLen[i]);
+ EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000044 , pEAS->ppSamples[i]);
+ }
}
#endif
diff --git a/arm-wt-22k/lib_src/eas_mdls.h b/arm-wt-22k/lib_src/eas_mdls.h
index f7dbf2f..16e6479 100644
--- a/arm-wt-22k/lib_src/eas_mdls.h
+++ b/arm-wt-22k/lib_src/eas_mdls.h
@@ -1,12 +1,12 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_mdls.h
- *
- * Contents and purpose:
- * Declarations, interfaces, and prototypes for eas_mdls.c
- *
- * Copyright Sonic Network Inc. 2004
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_mdls.h
+ *
+ * Contents and purpose:
+ * Declarations, interfaces, and prototypes for eas_mdls.c
+ *
+ * Copyright Sonic Network Inc. 2004
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,277 +19,277 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
-*/
-
-#ifndef _EAS_MDLS_H
-#define _EAS_MDLS_H
-
-/*------------------------------------
- * includes
- *------------------------------------
-*/
-#include "eas_data.h"
-
-
-/*------------------------------------
- * Some defines for dls.h
- *------------------------------------
-*/
-#ifndef DWORD
-#define DWORD EAS_I32
-#define FAR
-#define SHORT EAS_I16
-#define USHORT EAS_U16
-#define LONG EAS_I32
-#define ULONG EAS_U32
-#endif
-
-
-/* GUID struct (call it DLSID in case GUID is defined elsewhere) */
-typedef struct
-{
- EAS_U32 Data1;
- EAS_U16 Data2;
- EAS_U16 Data3;
- EAS_U8 Data4[8];
-} DLSID;
-
-#define DEFINE_DLSID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) const DLSID name = { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } }
-
-/*------------------------------------
- * defines
- *------------------------------------
-*/
-
-/* maximum sample memory for DLS query support */
-#ifndef MAX_DLS_MEMORY
-#define MAX_DLS_MEMORY 65536
-#endif
-
-/* size of conditional chunk stack */
-#ifndef CDL_STACK_SIZE
-#define CDL_STACK_SIZE 8
-#endif
-
-/* size of read buffer for sample conversion */
-#ifndef SAMPLE_CONVERT_CHUNK_SIZE
-#define SAMPLE_CONVERT_CHUNK_SIZE 32
-#endif
-
-
-#define ZERO_TIME_IN_CENTS -32768
-
-/* Pan calculation macros */
-#define PAN_CONVERSION_FACTOR 4129
-#define MAX_PAN_VALUE 63
-#define MIN_PAN_VALUE -63
-
-/* multiplier to convert time cents to 10-bit fraction log for EAS_LogToLinear16 */
-#define TIME_CENTS_TO_LOG2 27962
-
-/* conversion factor sustain level from percent to exponent for LogToLinear16 */
-#define SUSTAIN_LOG_CONVERSION_FACTOR 536871
-#define SUSTAIN_LOG_CONVERSION_SHIFT 15
-
-/* conversion factor sustain level from percent to EG full scale */
-#define SUSTAIN_LINEAR_CONVERSION_FACTOR 1073709
-
-/* conversion factor to convert frame period to decay rate */
-#define DECAY_CONVERSION_FACTOR -16
-
-/*----------------------------------------------------------------------------
- * These macros define the various characteristics of the defined sample rates
- *----------------------------------------------------------------------------
- * DLS_ATTACK_TIME_CONVERT log offset for conversion from time cents to attack rate
- * DLS_LFO_FREQUENCY_CONVERT pitch-cents offset for LFO frequency conversion
- *----------------------------------------------------------------------------
-*/
-
-#if defined (_SAMPLE_RATE_8000)
-#define DLS_RATE_CONVERT -9559
-#define DLS_LFO_FREQUENCY_CONVERT 5921
-
-#elif defined (_SAMPLE_RATE_16000)
-#define DLS_RATE_CONVERT -9559
-#define DLS_LFO_FREQUENCY_CONVERT 5921
-
-#elif defined (_SAMPLE_RATE_20000)
-#define DLS_RATE_CONVERT -8745
-#define DLS_LFO_FREQUENCY_CONVERT 5108
-
-#elif defined (_SAMPLE_RATE_22050)
-#define DLS_RATE_CONVERT -8914
-#define DLS_LFO_FREQUENCY_CONVERT 5277
-
-#elif defined (_SAMPLE_RATE_24000)
-#define DLS_RATE_CONVERT -9061
-#define DLS_LFO_FREQUENCY_CONVERT 5423
-
-#elif defined (_SAMPLE_RATE_32000)
-#define DLS_RATE_CONVERT -9559
-#define DLS_LFO_FREQUENCY_CONVERT 5921
-
-#elif defined (_SAMPLE_RATE_44100)
-#define DLS_RATE_CONVERT -8914
-#define DLS_LFO_FREQUENCY_CONVERT 5277
-
-#elif defined (_SAMPLE_RATE_48000)
-#define DLS_RATE_CONVERT -9061
-#define DLS_LFO_FREQUENCY_CONVERT 5423
-
-#else
-#error "_SAMPLE_RATE_XXXXX must be defined to valid rate"
-#endif
-
-/*
- * FILTER_Q_CONVERSION_FACTOR convers the 0.1dB steps in the DLS
- * file to our internal 0.75 dB steps. The value is calculated
- * as follows:
- *
- * 32768 / (10 * <step-size in dB>)
- *
- * FILTER_RESONANCE_NUM_ENTRIES is the number of entries in the table
-*/
-#define FILTER_Q_CONVERSION_FACTOR 4369
-#define FILTER_RESONANCE_NUM_ENTRIES 31
-
-/*
- * Multiplier to convert DLS gain units (10ths of a dB) to a
- * power-of-two exponent for conversion to linear gain using our
- * piece-wise linear approximator. Note that we ignore the lower
- * 16-bits of the DLS gain value. The result is a 10-bit fraction
- * that works with the EAS_LogToLinear16 function.
- *
- * DLS_GAIN_FACTOR = (2^18) / (200 * log10(2))
- */
-#define DLS_GAIN_FACTOR 4354
-#define DLS_GAIN_SHIFT 8
-
-/*
- * Reciprocal of 10 for quick divide by 10's
- *
- * DLS_GAIN_FACTOR = (2^18) / (200 * log10(2))
- */
-#define DLS_DIV_10_FACTOR 3277
-#define DLS_DIV_10_SHIFT 16
-
-/*
- * Multiplier to convert DLS time cents units to a power-of-two
- * exponent for conversion to absolute time units using our
- * piece-wise linear approximator.
- *
- * DLS_TIME_FACTOR = (2^22) / 1200
- */
-#define DLS_TIME_FACTOR 3495
-#define DLS_TIME_SHIFT 22
-
-
-/* LFO limits */
-#define MAX_LFO_FREQUENCY_IN_HERTZ 20
-#define MIN_LFO_FREQUENCY_IN_HERTZ 0.1
-#define MAX_LFO_FREQUENCY_IN_PITCHCENTS 1549
-#define MIN_LFO_FREQUENCY_IN_PITCHCENTS -7624
-#define MAX_LFO_AMPLITUDE_DEPTH 12 /* in dB, DLS2.1 p 31*/
-#define MIN_LFO_AMPLITUDE_DEPTH -12 /* in dB, DLS2.1 p 31*/
-
-/* add to pitch cents before pow(2.0, n) to convert to frequency */
-#define ABSOLUTE_PITCH_BIAS 238395828
-
-#define A5_PITCH_OFFSET 6900
-
-/*
-CHUNK_TYPE is a macro that converts the 4 input args into a 32-bit int
-where
-argument a is placed at the MSB location and
-argument d is placed at the LSB location.
-This is useful for determining the DLS chunk types
-*/
-#define CHUNK_TYPE(a,b,c,d) ( \
- ( ((EAS_U32)(a) & 0xFF) << 24 ) \
- + ( ((EAS_U32)(b) & 0xFF) << 16 ) \
- + ( ((EAS_U32)(c) & 0xFF) << 8 ) \
- + ( ((EAS_U32)(d) & 0xFF) ) )
-
-#define CHUNK_RIFF CHUNK_TYPE('R','I','F','F')
-#define CHUNK_DLS CHUNK_TYPE('D','L','S',' ')
-#define CHUNK_CDL CHUNK_TYPE('c','d','l',' ')
-#define CHUNK_VERS CHUNK_TYPE('v','e','r','s')
-#define CHUNK_DLID CHUNK_TYPE('d','l','i','d')
-#define CHUNK_LIST CHUNK_TYPE('L','I','S','T')
-#define CHUNK_COLH CHUNK_TYPE('c','o','l','h')
-#define CHUNK_LINS CHUNK_TYPE('l','i','n','s')
-#define CHUNK_PTBL CHUNK_TYPE('p','t','b','l')
-#define CHUNK_WVPL CHUNK_TYPE('w','v','p','l')
-#define CHUNK_INFO CHUNK_TYPE('I','N','F','O')
-#define CHUNK_INAM CHUNK_TYPE('I','N','A','M')
-#define CHUNK_INS CHUNK_TYPE('i','n','s',' ')
-#define CHUNK_INSH CHUNK_TYPE('i','n','s','h')
-#define CHUNK_LRGN CHUNK_TYPE('l','r','g','n')
-#define CHUNK_RGN CHUNK_TYPE('r','g','n',' ')
-#define CHUNK_RGN2 CHUNK_TYPE('r','g','n','2')
-#define CHUNK_RGNH CHUNK_TYPE('r','g','n','h')
-#define CHUNK_WSMP CHUNK_TYPE('w','s','m','p')
-#define CHUNK_WLNK CHUNK_TYPE('w','l','n','k')
-#define CHUNK_LART CHUNK_TYPE('l','a','r','t')
-#define CHUNK_LAR2 CHUNK_TYPE('l','a','r','2')
-#define CHUNK_ART1 CHUNK_TYPE('a','r','t','1')
-#define CHUNK_ART2 CHUNK_TYPE('a','r','t','2')
-#define CHUNK_WAVE CHUNK_TYPE('w','a','v','e')
-#define CHUNK_FMT CHUNK_TYPE('f','m','t',' ')
-#define CHUNK_DATA CHUNK_TYPE('d','a','t','a')
-#define CHUNK_DMPR CHUNK_TYPE('d','m','p','r')
-
-
-#define WAVE_FORMAT_PCM 0x0001 /* Microsoft PCM format, see DLS2.1 p60 */
-#define WAVE_FORMAT_EXTENSIBLE 0xffff
-
-/* defines for wave table structures */
-
-/* initialize each articulation structure to a harmless state */
-/* change art values after we've determined EAS internals */
-#define DEFAULT_DLS_FILTER_CUTOFF_FREQUENCY 0x7FFF /* DLS2.1, p 31 means leave filter off */
-
-/**********/
-
-/* define the waves that we expect to generate instead of store */
-/* NOTE: our comparison routine converts the input string
-to lowercase, so the following comparison values should all
-be in lowercase.
-*/
-#define STRING_NOISE "noise"
-
-
-/*------------------------------------
- * type definitions
- *------------------------------------
-*/
-#ifdef _STANDALONE_CONVERTER
-typedef struct s_dls_params
-{
- EAS_INT sampleRate;
- EAS_INT samplesPerFrame;
- EAS_INT bitDepth;
- double ditherLevel;
- double ditherFilterCoeff;
- EAS_BOOL compatibility;
- EAS_BOOL encodeADPCM;
-} S_DLS_PARAMS;
-#endif
-
-
-/* function prototypes */
-EAS_RESULT DLSParser (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE fileHandle, EAS_I32 offset, S_DLS **pDLS);
-EAS_RESULT DLSCleanup (EAS_HW_DATA_HANDLE hwInstData, S_DLS *pDLS);
-void DLSAddRef (S_DLS *pDLS);
-EAS_I16 ConvertDelay (EAS_I32 timeCents);
-EAS_I16 ConvertRate (EAS_I32 timeCents);
-
-
-#ifdef _STANDALONE_CONVERTER
-void DLSConvParams (S_DLS_PARAMS *pParams, EAS_BOOL set);
-#endif
-
-#endif
-
+ *
+ *----------------------------------------------------------------------------
+*/
+
+#ifndef _EAS_MDLS_H
+#define _EAS_MDLS_H
+
+/*------------------------------------
+ * includes
+ *------------------------------------
+*/
+#include "eas_data.h"
+
+
+/*------------------------------------
+ * Some defines for dls.h
+ *------------------------------------
+*/
+#ifndef DWORD
+#define DWORD EAS_I32
+#define FAR
+#define SHORT EAS_I16
+#define USHORT EAS_U16
+#define LONG EAS_I32
+#define ULONG EAS_U32
+#endif
+
+
+/* GUID struct (call it DLSID in case GUID is defined elsewhere) */
+typedef struct
+{
+ EAS_U32 Data1;
+ EAS_U16 Data2;
+ EAS_U16 Data3;
+ EAS_U8 Data4[8];
+} DLSID;
+
+#define DEFINE_DLSID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) const DLSID name = { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } }
+
+/*------------------------------------
+ * defines
+ *------------------------------------
+*/
+
+/* maximum sample memory for DLS query support */
+#ifndef MAX_DLS_MEMORY
+#define MAX_DLS_MEMORY 65536
+#endif
+
+/* size of conditional chunk stack */
+#ifndef CDL_STACK_SIZE
+#define CDL_STACK_SIZE 8
+#endif
+
+/* size of read buffer for sample conversion */
+#ifndef SAMPLE_CONVERT_CHUNK_SIZE
+#define SAMPLE_CONVERT_CHUNK_SIZE 32
+#endif
+
+
+#define ZERO_TIME_IN_CENTS -32768
+
+/* Pan calculation macros */
+#define PAN_CONVERSION_FACTOR 4129
+#define MAX_PAN_VALUE 63
+#define MIN_PAN_VALUE -63
+
+/* multiplier to convert time cents to 10-bit fraction log for EAS_LogToLinear16 */
+#define TIME_CENTS_TO_LOG2 27962
+
+/* conversion factor sustain level from percent to exponent for LogToLinear16 */
+#define SUSTAIN_LOG_CONVERSION_FACTOR 536871
+#define SUSTAIN_LOG_CONVERSION_SHIFT 15
+
+/* conversion factor sustain level from percent to EG full scale */
+#define SUSTAIN_LINEAR_CONVERSION_FACTOR 1073709
+
+/* conversion factor to convert frame period to decay rate */
+#define DECAY_CONVERSION_FACTOR -16
+
+/*----------------------------------------------------------------------------
+ * These macros define the various characteristics of the defined sample rates
+ *----------------------------------------------------------------------------
+ * DLS_ATTACK_TIME_CONVERT log offset for conversion from time cents to attack rate
+ * DLS_LFO_FREQUENCY_CONVERT pitch-cents offset for LFO frequency conversion
+ *----------------------------------------------------------------------------
+*/
+
+#if defined (_SAMPLE_RATE_8000)
+#define DLS_RATE_CONVERT -9559
+#define DLS_LFO_FREQUENCY_CONVERT 5921
+
+#elif defined (_SAMPLE_RATE_16000)
+#define DLS_RATE_CONVERT -9559
+#define DLS_LFO_FREQUENCY_CONVERT 5921
+
+#elif defined (_SAMPLE_RATE_20000)
+#define DLS_RATE_CONVERT -8745
+#define DLS_LFO_FREQUENCY_CONVERT 5108
+
+#elif defined (_SAMPLE_RATE_22050)
+#define DLS_RATE_CONVERT -8914
+#define DLS_LFO_FREQUENCY_CONVERT 5277
+
+#elif defined (_SAMPLE_RATE_24000)
+#define DLS_RATE_CONVERT -9061
+#define DLS_LFO_FREQUENCY_CONVERT 5423
+
+#elif defined (_SAMPLE_RATE_32000)
+#define DLS_RATE_CONVERT -9559
+#define DLS_LFO_FREQUENCY_CONVERT 5921
+
+#elif defined (_SAMPLE_RATE_44100)
+#define DLS_RATE_CONVERT -8914
+#define DLS_LFO_FREQUENCY_CONVERT 5277
+
+#elif defined (_SAMPLE_RATE_48000)
+#define DLS_RATE_CONVERT -9061
+#define DLS_LFO_FREQUENCY_CONVERT 5423
+
+#else
+#error "_SAMPLE_RATE_XXXXX must be defined to valid rate"
+#endif
+
+/*
+ * FILTER_Q_CONVERSION_FACTOR convers the 0.1dB steps in the DLS
+ * file to our internal 0.75 dB steps. The value is calculated
+ * as follows:
+ *
+ * 32768 / (10 * <step-size in dB>)
+ *
+ * FILTER_RESONANCE_NUM_ENTRIES is the number of entries in the table
+*/
+#define FILTER_Q_CONVERSION_FACTOR 4369
+#define FILTER_RESONANCE_NUM_ENTRIES 31
+
+/*
+ * Multiplier to convert DLS gain units (10ths of a dB) to a
+ * power-of-two exponent for conversion to linear gain using our
+ * piece-wise linear approximator. Note that we ignore the lower
+ * 16-bits of the DLS gain value. The result is a 10-bit fraction
+ * that works with the EAS_LogToLinear16 function.
+ *
+ * DLS_GAIN_FACTOR = (2^18) / (200 * log10(2))
+ */
+#define DLS_GAIN_FACTOR 4354
+#define DLS_GAIN_SHIFT 8
+
+/*
+ * Reciprocal of 10 for quick divide by 10's
+ *
+ * DLS_GAIN_FACTOR = (2^18) / (200 * log10(2))
+ */
+#define DLS_DIV_10_FACTOR 3277
+#define DLS_DIV_10_SHIFT 16
+
+/*
+ * Multiplier to convert DLS time cents units to a power-of-two
+ * exponent for conversion to absolute time units using our
+ * piece-wise linear approximator.
+ *
+ * DLS_TIME_FACTOR = (2^22) / 1200
+ */
+#define DLS_TIME_FACTOR 3495
+#define DLS_TIME_SHIFT 22
+
+
+/* LFO limits */
+#define MAX_LFO_FREQUENCY_IN_HERTZ 20
+#define MIN_LFO_FREQUENCY_IN_HERTZ 0.1
+#define MAX_LFO_FREQUENCY_IN_PITCHCENTS 1549
+#define MIN_LFO_FREQUENCY_IN_PITCHCENTS -7624
+#define MAX_LFO_AMPLITUDE_DEPTH 12 /* in dB, DLS2.1 p 31*/
+#define MIN_LFO_AMPLITUDE_DEPTH -12 /* in dB, DLS2.1 p 31*/
+
+/* add to pitch cents before pow(2.0, n) to convert to frequency */
+#define ABSOLUTE_PITCH_BIAS 238395828
+
+#define A5_PITCH_OFFSET 6900
+
+/*
+CHUNK_TYPE is a macro that converts the 4 input args into a 32-bit int
+where
+argument a is placed at the MSB location and
+argument d is placed at the LSB location.
+This is useful for determining the DLS chunk types
+*/
+#define CHUNK_TYPE(a,b,c,d) ( \
+ ( ((EAS_U32)(a) & 0xFF) << 24 ) \
+ + ( ((EAS_U32)(b) & 0xFF) << 16 ) \
+ + ( ((EAS_U32)(c) & 0xFF) << 8 ) \
+ + ( ((EAS_U32)(d) & 0xFF) ) )
+
+#define CHUNK_RIFF CHUNK_TYPE('R','I','F','F')
+#define CHUNK_DLS CHUNK_TYPE('D','L','S',' ')
+#define CHUNK_CDL CHUNK_TYPE('c','d','l',' ')
+#define CHUNK_VERS CHUNK_TYPE('v','e','r','s')
+#define CHUNK_DLID CHUNK_TYPE('d','l','i','d')
+#define CHUNK_LIST CHUNK_TYPE('L','I','S','T')
+#define CHUNK_COLH CHUNK_TYPE('c','o','l','h')
+#define CHUNK_LINS CHUNK_TYPE('l','i','n','s')
+#define CHUNK_PTBL CHUNK_TYPE('p','t','b','l')
+#define CHUNK_WVPL CHUNK_TYPE('w','v','p','l')
+#define CHUNK_INFO CHUNK_TYPE('I','N','F','O')
+#define CHUNK_INAM CHUNK_TYPE('I','N','A','M')
+#define CHUNK_INS CHUNK_TYPE('i','n','s',' ')
+#define CHUNK_INSH CHUNK_TYPE('i','n','s','h')
+#define CHUNK_LRGN CHUNK_TYPE('l','r','g','n')
+#define CHUNK_RGN CHUNK_TYPE('r','g','n',' ')
+#define CHUNK_RGN2 CHUNK_TYPE('r','g','n','2')
+#define CHUNK_RGNH CHUNK_TYPE('r','g','n','h')
+#define CHUNK_WSMP CHUNK_TYPE('w','s','m','p')
+#define CHUNK_WLNK CHUNK_TYPE('w','l','n','k')
+#define CHUNK_LART CHUNK_TYPE('l','a','r','t')
+#define CHUNK_LAR2 CHUNK_TYPE('l','a','r','2')
+#define CHUNK_ART1 CHUNK_TYPE('a','r','t','1')
+#define CHUNK_ART2 CHUNK_TYPE('a','r','t','2')
+#define CHUNK_WAVE CHUNK_TYPE('w','a','v','e')
+#define CHUNK_FMT CHUNK_TYPE('f','m','t',' ')
+#define CHUNK_DATA CHUNK_TYPE('d','a','t','a')
+#define CHUNK_DMPR CHUNK_TYPE('d','m','p','r')
+
+
+#define WAVE_FORMAT_PCM 0x0001 /* Microsoft PCM format, see DLS2.1 p60 */
+#define WAVE_FORMAT_EXTENSIBLE 0xffff
+
+/* defines for wave table structures */
+
+/* initialize each articulation structure to a harmless state */
+/* change art values after we've determined EAS internals */
+#define DEFAULT_DLS_FILTER_CUTOFF_FREQUENCY 0x7FFF /* DLS2.1, p 31 means leave filter off */
+
+/**********/
+
+/* define the waves that we expect to generate instead of store */
+/* NOTE: our comparison routine converts the input string
+to lowercase, so the following comparison values should all
+be in lowercase.
+*/
+#define STRING_NOISE "noise"
+
+
+/*------------------------------------
+ * type definitions
+ *------------------------------------
+*/
+#ifdef _STANDALONE_CONVERTER
+typedef struct s_dls_params
+{
+ EAS_INT sampleRate;
+ EAS_INT samplesPerFrame;
+ EAS_INT bitDepth;
+ double ditherLevel;
+ double ditherFilterCoeff;
+ EAS_BOOL compatibility;
+ EAS_BOOL encodeADPCM;
+} S_DLS_PARAMS;
+#endif
+
+
+/* function prototypes */
+EAS_RESULT DLSParser (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE fileHandle, EAS_I32 offset, S_DLS **pDLS);
+EAS_RESULT DLSCleanup (EAS_HW_DATA_HANDLE hwInstData, S_DLS *pDLS);
+void DLSAddRef (S_DLS *pDLS);
+EAS_I16 ConvertDelay (EAS_I32 timeCents);
+EAS_I16 ConvertRate (EAS_I32 timeCents);
+
+
+#ifdef _STANDALONE_CONVERTER
+void DLSConvParams (S_DLS_PARAMS *pParams, EAS_BOOL set);
+#endif
+
+#endif
+
diff --git a/arm-wt-22k/lib_src/eas_midi.c b/arm-wt-22k/lib_src/eas_midi.c
index 0c77aea..8cb043a 100644
--- a/arm-wt-22k/lib_src/eas_midi.c
+++ b/arm-wt-22k/lib_src/eas_midi.c
@@ -1,13 +1,13 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_midi.c
- *
- * Contents and purpose:
- * This file implements the MIDI stream parser. It is called by eas_smf.c to parse MIDI messages
- * that are streamed out of the file. It can also parse live MIDI streams.
- *
- * Copyright Sonic Network Inc. 2005
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_midi.c
+ *
+ * Contents and purpose:
+ * This file implements the MIDI stream parser. It is called by eas_smf.c to parse MIDI messages
+ * that are streamed out of the file. It can also parse live MIDI streams.
+ *
+ * Copyright Sonic Network Inc. 2005
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,550 +20,550 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 794 $
- * $Date: 2007-08-01 00:08:48 -0700 (Wed, 01 Aug 2007) $
- *----------------------------------------------------------------------------
-*/
-
-#include "eas_data.h"
-#include "eas_report.h"
-#include "eas_miditypes.h"
-#include "eas_midi.h"
-#include "eas_vm_protos.h"
-#include "eas_parser.h"
-
-#ifdef JET_INTERFACE
-#include "jet_data.h"
-#endif
-
-
-/* state enumerations for ProcessSysExMessage */
-typedef enum
-{
- eSysEx,
- eSysExUnivNonRealTime,
- eSysExUnivNrtTargetID,
- eSysExGMControl,
- eSysExUnivRealTime,
- eSysExUnivRtTargetID,
- eSysExDeviceControl,
- eSysExMasterVolume,
- eSysExMasterVolLSB,
- eSysExSPMIDI,
- eSysExSPMIDIchan,
- eSysExSPMIDIMIP,
- eSysExMfgID1,
- eSysExMfgID2,
- eSysExMfgID3,
- eSysExEnhancer,
- eSysExEnhancerSubID,
- eSysExEnhancerFeedback1,
- eSysExEnhancerFeedback2,
- eSysExEnhancerDrive,
- eSysExEnhancerWet,
- eSysExEOX,
- eSysExIgnore
-} E_SYSEX_STATES;
-
-/* local prototypes */
-static EAS_RESULT ProcessMIDIMessage (S_EAS_DATA *pEASData, S_SYNTH *pSynth, S_MIDI_STREAM *pMIDIStream, EAS_INT parserMode);
-static EAS_RESULT ProcessSysExMessage (S_EAS_DATA *pEASData, S_SYNTH *pSynth, S_MIDI_STREAM *pMIDIStream, EAS_U8 c, EAS_INT parserMode);
-
-/*----------------------------------------------------------------------------
- * EAS_InitMIDIStream()
- *----------------------------------------------------------------------------
- * Purpose:
- * Initializes the MIDI stream state for parsing.
- *
- * Inputs:
- *
- * Outputs:
- * returns EAS_RESULT (EAS_SUCCESS is OK)
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-void EAS_InitMIDIStream (S_MIDI_STREAM *pMIDIStream)
-{
- pMIDIStream->byte3 = EAS_FALSE;
- pMIDIStream->pending = EAS_FALSE;
- pMIDIStream->runningStatus = 0;
- pMIDIStream->status = 0;
-}
-
-/*----------------------------------------------------------------------------
- * EAS_ParseMIDIStream()
- *----------------------------------------------------------------------------
- * Purpose:
- * Parses a MIDI input stream character by character. Characters are pushed (rather than pulled)
- * so the interface works equally well for both file and stream I/O.
- *
- * Inputs:
- * c - character from MIDI stream
- *
- * Outputs:
- * returns EAS_RESULT (EAS_SUCCESS is OK)
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT EAS_ParseMIDIStream (S_EAS_DATA *pEASData, S_SYNTH *pSynth, S_MIDI_STREAM *pMIDIStream, EAS_U8 c, EAS_INT parserMode)
-{
-
- /* check for new status byte */
- if (c & 0x80)
- {
- /* save new running status */
- if (c < 0xf8)
- {
- pMIDIStream->runningStatus = c;
- pMIDIStream->byte3 = EAS_FALSE;
-
- /* deal with SysEx */
- if ((c == 0xf7) || (c == 0xf0))
- {
- if (parserMode == eParserModeMetaData)
- return EAS_SUCCESS;
- return ProcessSysExMessage(pEASData, pSynth, pMIDIStream, c, parserMode);
- }
-
- /* inform the file parser that we're in the middle of a message */
- if ((c < 0xf4) || (c > 0xf6))
- pMIDIStream->pending = EAS_TRUE;
- }
-
- /* real-time message - ignore it */
- return EAS_SUCCESS;
- }
-
- /* 3rd byte of a 3-byte message? */
- if (pMIDIStream->byte3)
- {
- pMIDIStream->d2 = c;
- pMIDIStream->byte3 = EAS_FALSE;
- pMIDIStream->pending = EAS_FALSE;
- if (parserMode == eParserModeMetaData)
- return EAS_SUCCESS;
- return ProcessMIDIMessage(pEASData, pSynth, pMIDIStream, parserMode);
- }
-
- /* check for status received */
- if (pMIDIStream->runningStatus)
- {
-
- /* save new status and data byte */
- pMIDIStream->status = pMIDIStream->runningStatus;
-
- /* check for 3-byte messages */
- if (pMIDIStream->status < 0xc0)
- {
- pMIDIStream->d1 = c;
- pMIDIStream->pending = EAS_TRUE;
- pMIDIStream->byte3 = EAS_TRUE;
- return EAS_SUCCESS;
- }
-
- /* check for 2-byte messages */
- if (pMIDIStream->status < 0xe0)
- {
- pMIDIStream->d1 = c;
- pMIDIStream->pending = EAS_FALSE;
- if (parserMode == eParserModeMetaData)
- return EAS_SUCCESS;
- return ProcessMIDIMessage(pEASData, pSynth, pMIDIStream, parserMode);
- }
-
- /* check for more 3-bytes message */
- if (pMIDIStream->status < 0xf0)
- {
- pMIDIStream->d1 = c;
- pMIDIStream->pending = EAS_TRUE;
- pMIDIStream->byte3 = EAS_TRUE;
- return EAS_SUCCESS;
- }
-
- /* SysEx message? */
- if (pMIDIStream->status == 0xF0)
- {
- if (parserMode == eParserModeMetaData)
- return EAS_SUCCESS;
- return ProcessSysExMessage(pEASData, pSynth, pMIDIStream, c, parserMode);
- }
-
- /* remaining messages all clear running status */
- pMIDIStream->runningStatus = 0;
-
- /* F2 is 3-byte message */
- if (pMIDIStream->status == 0xf2)
- {
- pMIDIStream->byte3 = EAS_TRUE;
- return EAS_SUCCESS;
- }
- }
-
- /* no status byte received, provide a warning, but we should be able to recover */
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Received MIDI data without a valid status byte: %d\n",c); */ }
- pMIDIStream->pending = EAS_FALSE;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * ProcessMIDIMessage()
- *----------------------------------------------------------------------------
- * Purpose:
- * This function processes a typical MIDI message. All of the data has been received, just need
- * to take appropriate action.
- *
- * Inputs:
- *
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT ProcessMIDIMessage (S_EAS_DATA *pEASData, S_SYNTH *pSynth, S_MIDI_STREAM *pMIDIStream, EAS_INT parserMode)
-{
- EAS_U8 channel;
-
- channel = pMIDIStream->status & 0x0f;
- switch (pMIDIStream->status & 0xf0)
- {
- case 0x80:
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL,"NoteOff: %02x %02x %02x\n",
- pMIDIStream->status, pMIDIStream->d1, pMIDIStream->d2); */ }
- if (parserMode <= eParserModeMute)
- VMStopNote(pEASData->pVoiceMgr, pSynth, channel, pMIDIStream->d1, pMIDIStream->d2);
- break;
-
- case 0x90:
- if (pMIDIStream->d2)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL,"NoteOn: %02x %02x %02x\n",
- pMIDIStream->status, pMIDIStream->d1, pMIDIStream->d2); */ }
- pMIDIStream->flags |= MIDI_FLAG_FIRST_NOTE;
- if (parserMode == eParserModePlay)
- VMStartNote(pEASData->pVoiceMgr, pSynth, channel, pMIDIStream->d1, pMIDIStream->d2);
- }
- else
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL,"NoteOff: %02x %02x %02x\n",
- pMIDIStream->status, pMIDIStream->d1, pMIDIStream->d2); */ }
- if (parserMode <= eParserModeMute)
- VMStopNote(pEASData->pVoiceMgr, pSynth, channel, pMIDIStream->d1, pMIDIStream->d2);
- }
- break;
-
- case 0xa0:
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL,"PolyPres: %02x %02x %02x\n",
- pMIDIStream->status, pMIDIStream->d1, pMIDIStream->d2); */ }
- break;
-
- case 0xb0:
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL,"Control: %02x %02x %02x\n",
- pMIDIStream->status, pMIDIStream->d1, pMIDIStream->d2); */ }
- if (parserMode <= eParserModeMute)
- VMControlChange(pEASData->pVoiceMgr, pSynth, channel, pMIDIStream->d1, pMIDIStream->d2);
-#ifdef JET_INTERFACE
- if (pMIDIStream->jetData & MIDI_FLAGS_JET_CB)
- {
- JET_Event(pEASData, pMIDIStream->jetData & (JET_EVENT_SEG_MASK | JET_EVENT_TRACK_MASK),
- channel, pMIDIStream->d1, pMIDIStream->d2);
- }
-#endif
- break;
-
- case 0xc0:
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL,"Program: %02x %02x\n",
- pMIDIStream->status, pMIDIStream->d1); */ }
- if (parserMode <= eParserModeMute)
- VMProgramChange(pEASData->pVoiceMgr, pSynth, channel, pMIDIStream->d1);
- break;
-
- case 0xd0:
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL,"ChanPres: %02x %02x\n",
- pMIDIStream->status, pMIDIStream->d1); */ }
- if (parserMode <= eParserModeMute)
- VMChannelPressure(pSynth, channel, pMIDIStream->d1);
- break;
-
- case 0xe0:
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL,"PBend: %02x %02x %02x\n",
- pMIDIStream->status, pMIDIStream->d1, pMIDIStream->d2); */ }
- if (parserMode <= eParserModeMute)
- VMPitchBend(pSynth, channel, pMIDIStream->d1, pMIDIStream->d2);
- break;
-
- default:
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL,"Unknown: %02x %02x %02x\n",
- pMIDIStream->status, pMIDIStream->d1, pMIDIStream->d2); */ }
- }
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * ProcessSysExMessage()
- *----------------------------------------------------------------------------
- * Purpose:
- * Process a SysEx character byte from the MIDI stream. Since we cannot
- * simply wait for the next character to arrive, we are forced to save
- * state after each character. It would be easier to parse at the file
- * level, but then we lose the nice feature of being able to support
- * these messages in a real-time MIDI stream.
- *
- * Inputs:
- * pEASData - pointer to synthesizer instance data
- * c - character to be processed
- * locating - if true, the sequencer is relocating to a new position
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- * Notes:
- * These are the SysEx messages we can receive:
- *
- * SysEx messages
- * { f0 7e 7f 09 01 f7 } GM 1 On
- * { f0 7e 7f 09 02 f7 } GM 1/2 Off
- * { f0 7e 7f 09 03 f7 } GM 2 On
- * { f0 7f 7f 04 01 lsb msb } Master Volume
- * { f0 7f 7f 0b 01 ch mip [ch mip ...] f7 } SP-MIDI
- * { f0 00 01 3a 04 01 fdbk1 fdbk2 drive wet dry f7 } Enhancer
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT ProcessSysExMessage (S_EAS_DATA *pEASData, S_SYNTH *pSynth, S_MIDI_STREAM *pMIDIStream, EAS_U8 c, EAS_INT parserMode)
-{
-
- /* check for start byte */
- if (c == 0xf0)
- {
- pMIDIStream->sysExState = eSysEx;
- }
- /* check for end byte */
- else if (c == 0xf7)
- {
- /* if this was a MIP message, update the MIP table */
- if ((pMIDIStream->sysExState == eSysExSPMIDIchan) && (parserMode != eParserModeMetaData))
- VMUpdateMIPTable(pEASData->pVoiceMgr, pSynth);
- pMIDIStream->sysExState = eSysExIgnore;
- }
-
- /* process SysEx message */
- else
- {
- switch (pMIDIStream->sysExState)
- {
- case eSysEx:
-
- /* first byte, determine message class */
- switch (c)
- {
- case 0x7e:
- pMIDIStream->sysExState = eSysExUnivNonRealTime;
- break;
- case 0x7f:
- pMIDIStream->sysExState = eSysExUnivRealTime;
- break;
- case 0x00:
- pMIDIStream->sysExState = eSysExMfgID1;
- break;
- default:
- pMIDIStream->sysExState = eSysExIgnore;
- break;
- }
- break;
-
- /* process GM message */
- case eSysExUnivNonRealTime:
- if (c == 0x7f)
- pMIDIStream->sysExState = eSysExUnivNrtTargetID;
- else
- pMIDIStream->sysExState = eSysExIgnore;
- break;
-
- case eSysExUnivNrtTargetID:
- if (c == 0x09)
- pMIDIStream->sysExState = eSysExGMControl;
- else
- pMIDIStream->sysExState = eSysExIgnore;
- break;
-
- case eSysExGMControl:
- if ((c == 1) || (c == 3))
- {
- /* GM 1 or GM2 On, reset synth */
- if (parserMode != eParserModeMetaData)
- {
- pMIDIStream->flags |= MIDI_FLAG_GM_ON;
- VMReset(pEASData->pVoiceMgr, pSynth, EAS_FALSE);
- VMInitMIPTable(pSynth);
- }
- pMIDIStream->sysExState = eSysExEOX;
- }
- else
- pMIDIStream->sysExState = eSysExIgnore;
- break;
-
- /* Process Master Volume and SP-MIDI */
- case eSysExUnivRealTime:
- if (c == 0x7f)
- pMIDIStream->sysExState = eSysExUnivRtTargetID;
- else
- pMIDIStream->sysExState = eSysExIgnore;
- break;
-
- case eSysExUnivRtTargetID:
- if (c == 0x04)
- pMIDIStream->sysExState = eSysExDeviceControl;
- else if (c == 0x0b)
- pMIDIStream->sysExState = eSysExSPMIDI;
- else
- pMIDIStream->sysExState = eSysExIgnore;
- break;
-
- /* process master volume */
- case eSysExDeviceControl:
- if (c == 0x01)
- pMIDIStream->sysExState = eSysExMasterVolume;
- else
- pMIDIStream->sysExState = eSysExIgnore;
- break;
-
- case eSysExMasterVolume:
- /* save LSB */
- pMIDIStream->d1 = c;
- pMIDIStream->sysExState = eSysExMasterVolLSB;
- break;
-
- case eSysExMasterVolLSB:
- if (parserMode != eParserModeMetaData)
- {
- EAS_I32 gain = ((EAS_I32) c << 8) | ((EAS_I32) pMIDIStream->d1 << 1);
- gain = (gain * gain) >> 15;
- VMSetVolume(pSynth, (EAS_U16) gain);
- }
- pMIDIStream->sysExState = eSysExEOX;
- break;
-
- /* process SP-MIDI MIP message */
- case eSysExSPMIDI:
- if (c == 0x01)
- {
- /* assume all channels are muted */
- if (parserMode != eParserModeMetaData)
- VMInitMIPTable(pSynth);
- pMIDIStream->d1 = 0;
- pMIDIStream->sysExState = eSysExSPMIDIchan;
- }
- else
- pMIDIStream->sysExState = eSysExIgnore;
- break;
-
- case eSysExSPMIDIchan:
- if (c < NUM_SYNTH_CHANNELS)
- {
- pMIDIStream->d2 = c;
- pMIDIStream->sysExState = eSysExSPMIDIMIP;
- }
- else
- {
- /* bad MIP message - unmute channels */
- if (parserMode != eParserModeMetaData)
- VMInitMIPTable(pSynth);
- pMIDIStream->sysExState = eSysExIgnore;
- }
- break;
-
- case eSysExSPMIDIMIP:
- /* process MIP entry here */
- if (parserMode != eParserModeMetaData)
- VMSetMIPEntry(pEASData->pVoiceMgr, pSynth, pMIDIStream->d2, pMIDIStream->d1, c);
- pMIDIStream->sysExState = eSysExSPMIDIchan;
-
- /* if 16 channels received, update MIP table */
- if (++pMIDIStream->d1 == NUM_SYNTH_CHANNELS)
- {
- if (parserMode != eParserModeMetaData)
- VMUpdateMIPTable(pEASData->pVoiceMgr, pSynth);
- pMIDIStream->sysExState = eSysExEOX;
- }
- break;
-
- /* process Enhancer */
- case eSysExMfgID1:
- if (c == 0x01)
- pMIDIStream->sysExState = eSysExMfgID1;
- else
- pMIDIStream->sysExState = eSysExIgnore;
- break;
-
- case eSysExMfgID2:
- if (c == 0x3a)
- pMIDIStream->sysExState = eSysExMfgID1;
- else
- pMIDIStream->sysExState = eSysExIgnore;
- break;
-
- case eSysExMfgID3:
- if (c == 0x04)
- pMIDIStream->sysExState = eSysExEnhancer;
- else
- pMIDIStream->sysExState = eSysExIgnore;
- break;
-
- case eSysExEnhancer:
- if (c == 0x01)
- pMIDIStream->sysExState = eSysExEnhancerSubID;
- else
- pMIDIStream->sysExState = eSysExIgnore;
- break;
-
- case eSysExEnhancerSubID:
- pMIDIStream->sysExState = eSysExEnhancerFeedback1;
- break;
-
- case eSysExEnhancerFeedback1:
- pMIDIStream->sysExState = eSysExEnhancerFeedback2;
- break;
-
- case eSysExEnhancerFeedback2:
- pMIDIStream->sysExState = eSysExEnhancerDrive;
- break;
-
- case eSysExEnhancerDrive:
- pMIDIStream->sysExState = eSysExEnhancerWet;
- break;
-
- case eSysExEnhancerWet:
- pMIDIStream->sysExState = eSysExEOX;
- break;
-
- case eSysExEOX:
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Expected F7, received %02x\n", c); */ }
- pMIDIStream->sysExState = eSysExIgnore;
- break;
-
- case eSysExIgnore:
- break;
-
- default:
- pMIDIStream->sysExState = eSysExIgnore;
- break;
- }
- }
-
- if (pMIDIStream->sysExState == eSysExIgnore)
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Ignoring SysEx byte %02x\n", c); */ }
- return EAS_SUCCESS;
-} /* end ProcessSysExMessage */
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 794 $
+ * $Date: 2007-08-01 00:08:48 -0700 (Wed, 01 Aug 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+#include "eas_data.h"
+#include "eas_report.h"
+#include "eas_miditypes.h"
+#include "eas_midi.h"
+#include "eas_vm_protos.h"
+#include "eas_parser.h"
+
+#ifdef JET_INTERFACE
+#include "jet_data.h"
+#endif
+
+
+/* state enumerations for ProcessSysExMessage */
+typedef enum
+{
+ eSysEx,
+ eSysExUnivNonRealTime,
+ eSysExUnivNrtTargetID,
+ eSysExGMControl,
+ eSysExUnivRealTime,
+ eSysExUnivRtTargetID,
+ eSysExDeviceControl,
+ eSysExMasterVolume,
+ eSysExMasterVolLSB,
+ eSysExSPMIDI,
+ eSysExSPMIDIchan,
+ eSysExSPMIDIMIP,
+ eSysExMfgID1,
+ eSysExMfgID2,
+ eSysExMfgID3,
+ eSysExEnhancer,
+ eSysExEnhancerSubID,
+ eSysExEnhancerFeedback1,
+ eSysExEnhancerFeedback2,
+ eSysExEnhancerDrive,
+ eSysExEnhancerWet,
+ eSysExEOX,
+ eSysExIgnore
+} E_SYSEX_STATES;
+
+/* local prototypes */
+static EAS_RESULT ProcessMIDIMessage (S_EAS_DATA *pEASData, S_SYNTH *pSynth, S_MIDI_STREAM *pMIDIStream, EAS_INT parserMode);
+static EAS_RESULT ProcessSysExMessage (S_EAS_DATA *pEASData, S_SYNTH *pSynth, S_MIDI_STREAM *pMIDIStream, EAS_U8 c, EAS_INT parserMode);
+
+/*----------------------------------------------------------------------------
+ * EAS_InitMIDIStream()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Initializes the MIDI stream state for parsing.
+ *
+ * Inputs:
+ *
+ * Outputs:
+ * returns EAS_RESULT (EAS_SUCCESS is OK)
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+void EAS_InitMIDIStream (S_MIDI_STREAM *pMIDIStream)
+{
+ pMIDIStream->byte3 = EAS_FALSE;
+ pMIDIStream->pending = EAS_FALSE;
+ pMIDIStream->runningStatus = 0;
+ pMIDIStream->status = 0;
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_ParseMIDIStream()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Parses a MIDI input stream character by character. Characters are pushed (rather than pulled)
+ * so the interface works equally well for both file and stream I/O.
+ *
+ * Inputs:
+ * c - character from MIDI stream
+ *
+ * Outputs:
+ * returns EAS_RESULT (EAS_SUCCESS is OK)
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_ParseMIDIStream (S_EAS_DATA *pEASData, S_SYNTH *pSynth, S_MIDI_STREAM *pMIDIStream, EAS_U8 c, EAS_INT parserMode)
+{
+
+ /* check for new status byte */
+ if (c & 0x80)
+ {
+ /* save new running status */
+ if (c < 0xf8)
+ {
+ pMIDIStream->runningStatus = c;
+ pMIDIStream->byte3 = EAS_FALSE;
+
+ /* deal with SysEx */
+ if ((c == 0xf7) || (c == 0xf0))
+ {
+ if (parserMode == eParserModeMetaData)
+ return EAS_SUCCESS;
+ return ProcessSysExMessage(pEASData, pSynth, pMIDIStream, c, parserMode);
+ }
+
+ /* inform the file parser that we're in the middle of a message */
+ if ((c < 0xf4) || (c > 0xf6))
+ pMIDIStream->pending = EAS_TRUE;
+ }
+
+ /* real-time message - ignore it */
+ return EAS_SUCCESS;
+ }
+
+ /* 3rd byte of a 3-byte message? */
+ if (pMIDIStream->byte3)
+ {
+ pMIDIStream->d2 = c;
+ pMIDIStream->byte3 = EAS_FALSE;
+ pMIDIStream->pending = EAS_FALSE;
+ if (parserMode == eParserModeMetaData)
+ return EAS_SUCCESS;
+ return ProcessMIDIMessage(pEASData, pSynth, pMIDIStream, parserMode);
+ }
+
+ /* check for status received */
+ if (pMIDIStream->runningStatus)
+ {
+
+ /* save new status and data byte */
+ pMIDIStream->status = pMIDIStream->runningStatus;
+
+ /* check for 3-byte messages */
+ if (pMIDIStream->status < 0xc0)
+ {
+ pMIDIStream->d1 = c;
+ pMIDIStream->pending = EAS_TRUE;
+ pMIDIStream->byte3 = EAS_TRUE;
+ return EAS_SUCCESS;
+ }
+
+ /* check for 2-byte messages */
+ if (pMIDIStream->status < 0xe0)
+ {
+ pMIDIStream->d1 = c;
+ pMIDIStream->pending = EAS_FALSE;
+ if (parserMode == eParserModeMetaData)
+ return EAS_SUCCESS;
+ return ProcessMIDIMessage(pEASData, pSynth, pMIDIStream, parserMode);
+ }
+
+ /* check for more 3-bytes message */
+ if (pMIDIStream->status < 0xf0)
+ {
+ pMIDIStream->d1 = c;
+ pMIDIStream->pending = EAS_TRUE;
+ pMIDIStream->byte3 = EAS_TRUE;
+ return EAS_SUCCESS;
+ }
+
+ /* SysEx message? */
+ if (pMIDIStream->status == 0xF0)
+ {
+ if (parserMode == eParserModeMetaData)
+ return EAS_SUCCESS;
+ return ProcessSysExMessage(pEASData, pSynth, pMIDIStream, c, parserMode);
+ }
+
+ /* remaining messages all clear running status */
+ pMIDIStream->runningStatus = 0;
+
+ /* F2 is 3-byte message */
+ if (pMIDIStream->status == 0xf2)
+ {
+ pMIDIStream->byte3 = EAS_TRUE;
+ return EAS_SUCCESS;
+ }
+ }
+
+ /* no status byte received, provide a warning, but we should be able to recover */
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Received MIDI data without a valid status byte: %d\n",c); */ }
+ pMIDIStream->pending = EAS_FALSE;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * ProcessMIDIMessage()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * This function processes a typical MIDI message. All of the data has been received, just need
+ * to take appropriate action.
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT ProcessMIDIMessage (S_EAS_DATA *pEASData, S_SYNTH *pSynth, S_MIDI_STREAM *pMIDIStream, EAS_INT parserMode)
+{
+ EAS_U8 channel;
+
+ channel = pMIDIStream->status & 0x0f;
+ switch (pMIDIStream->status & 0xf0)
+ {
+ case 0x80:
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL,"NoteOff: %02x %02x %02x\n",
+ pMIDIStream->status, pMIDIStream->d1, pMIDIStream->d2); */ }
+ if (parserMode <= eParserModeMute)
+ VMStopNote(pEASData->pVoiceMgr, pSynth, channel, pMIDIStream->d1, pMIDIStream->d2);
+ break;
+
+ case 0x90:
+ if (pMIDIStream->d2)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL,"NoteOn: %02x %02x %02x\n",
+ pMIDIStream->status, pMIDIStream->d1, pMIDIStream->d2); */ }
+ pMIDIStream->flags |= MIDI_FLAG_FIRST_NOTE;
+ if (parserMode == eParserModePlay)
+ VMStartNote(pEASData->pVoiceMgr, pSynth, channel, pMIDIStream->d1, pMIDIStream->d2);
+ }
+ else
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL,"NoteOff: %02x %02x %02x\n",
+ pMIDIStream->status, pMIDIStream->d1, pMIDIStream->d2); */ }
+ if (parserMode <= eParserModeMute)
+ VMStopNote(pEASData->pVoiceMgr, pSynth, channel, pMIDIStream->d1, pMIDIStream->d2);
+ }
+ break;
+
+ case 0xa0:
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL,"PolyPres: %02x %02x %02x\n",
+ pMIDIStream->status, pMIDIStream->d1, pMIDIStream->d2); */ }
+ break;
+
+ case 0xb0:
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL,"Control: %02x %02x %02x\n",
+ pMIDIStream->status, pMIDIStream->d1, pMIDIStream->d2); */ }
+ if (parserMode <= eParserModeMute)
+ VMControlChange(pEASData->pVoiceMgr, pSynth, channel, pMIDIStream->d1, pMIDIStream->d2);
+#ifdef JET_INTERFACE
+ if (pMIDIStream->jetData & MIDI_FLAGS_JET_CB)
+ {
+ JET_Event(pEASData, pMIDIStream->jetData & (JET_EVENT_SEG_MASK | JET_EVENT_TRACK_MASK),
+ channel, pMIDIStream->d1, pMIDIStream->d2);
+ }
+#endif
+ break;
+
+ case 0xc0:
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL,"Program: %02x %02x\n",
+ pMIDIStream->status, pMIDIStream->d1); */ }
+ if (parserMode <= eParserModeMute)
+ VMProgramChange(pEASData->pVoiceMgr, pSynth, channel, pMIDIStream->d1);
+ break;
+
+ case 0xd0:
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL,"ChanPres: %02x %02x\n",
+ pMIDIStream->status, pMIDIStream->d1); */ }
+ if (parserMode <= eParserModeMute)
+ VMChannelPressure(pSynth, channel, pMIDIStream->d1);
+ break;
+
+ case 0xe0:
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL,"PBend: %02x %02x %02x\n",
+ pMIDIStream->status, pMIDIStream->d1, pMIDIStream->d2); */ }
+ if (parserMode <= eParserModeMute)
+ VMPitchBend(pSynth, channel, pMIDIStream->d1, pMIDIStream->d2);
+ break;
+
+ default:
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL,"Unknown: %02x %02x %02x\n",
+ pMIDIStream->status, pMIDIStream->d1, pMIDIStream->d2); */ }
+ }
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * ProcessSysExMessage()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Process a SysEx character byte from the MIDI stream. Since we cannot
+ * simply wait for the next character to arrive, we are forced to save
+ * state after each character. It would be easier to parse at the file
+ * level, but then we lose the nice feature of being able to support
+ * these messages in a real-time MIDI stream.
+ *
+ * Inputs:
+ * pEASData - pointer to synthesizer instance data
+ * c - character to be processed
+ * locating - if true, the sequencer is relocating to a new position
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ * Notes:
+ * These are the SysEx messages we can receive:
+ *
+ * SysEx messages
+ * { f0 7e 7f 09 01 f7 } GM 1 On
+ * { f0 7e 7f 09 02 f7 } GM 1/2 Off
+ * { f0 7e 7f 09 03 f7 } GM 2 On
+ * { f0 7f 7f 04 01 lsb msb } Master Volume
+ * { f0 7f 7f 0b 01 ch mip [ch mip ...] f7 } SP-MIDI
+ * { f0 00 01 3a 04 01 fdbk1 fdbk2 drive wet dry f7 } Enhancer
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT ProcessSysExMessage (S_EAS_DATA *pEASData, S_SYNTH *pSynth, S_MIDI_STREAM *pMIDIStream, EAS_U8 c, EAS_INT parserMode)
+{
+
+ /* check for start byte */
+ if (c == 0xf0)
+ {
+ pMIDIStream->sysExState = eSysEx;
+ }
+ /* check for end byte */
+ else if (c == 0xf7)
+ {
+ /* if this was a MIP message, update the MIP table */
+ if ((pMIDIStream->sysExState == eSysExSPMIDIchan) && (parserMode != eParserModeMetaData))
+ VMUpdateMIPTable(pEASData->pVoiceMgr, pSynth);
+ pMIDIStream->sysExState = eSysExIgnore;
+ }
+
+ /* process SysEx message */
+ else
+ {
+ switch (pMIDIStream->sysExState)
+ {
+ case eSysEx:
+
+ /* first byte, determine message class */
+ switch (c)
+ {
+ case 0x7e:
+ pMIDIStream->sysExState = eSysExUnivNonRealTime;
+ break;
+ case 0x7f:
+ pMIDIStream->sysExState = eSysExUnivRealTime;
+ break;
+ case 0x00:
+ pMIDIStream->sysExState = eSysExMfgID1;
+ break;
+ default:
+ pMIDIStream->sysExState = eSysExIgnore;
+ break;
+ }
+ break;
+
+ /* process GM message */
+ case eSysExUnivNonRealTime:
+ if (c == 0x7f)
+ pMIDIStream->sysExState = eSysExUnivNrtTargetID;
+ else
+ pMIDIStream->sysExState = eSysExIgnore;
+ break;
+
+ case eSysExUnivNrtTargetID:
+ if (c == 0x09)
+ pMIDIStream->sysExState = eSysExGMControl;
+ else
+ pMIDIStream->sysExState = eSysExIgnore;
+ break;
+
+ case eSysExGMControl:
+ if ((c == 1) || (c == 3))
+ {
+ /* GM 1 or GM2 On, reset synth */
+ if (parserMode != eParserModeMetaData)
+ {
+ pMIDIStream->flags |= MIDI_FLAG_GM_ON;
+ VMReset(pEASData->pVoiceMgr, pSynth, EAS_FALSE);
+ VMInitMIPTable(pSynth);
+ }
+ pMIDIStream->sysExState = eSysExEOX;
+ }
+ else
+ pMIDIStream->sysExState = eSysExIgnore;
+ break;
+
+ /* Process Master Volume and SP-MIDI */
+ case eSysExUnivRealTime:
+ if (c == 0x7f)
+ pMIDIStream->sysExState = eSysExUnivRtTargetID;
+ else
+ pMIDIStream->sysExState = eSysExIgnore;
+ break;
+
+ case eSysExUnivRtTargetID:
+ if (c == 0x04)
+ pMIDIStream->sysExState = eSysExDeviceControl;
+ else if (c == 0x0b)
+ pMIDIStream->sysExState = eSysExSPMIDI;
+ else
+ pMIDIStream->sysExState = eSysExIgnore;
+ break;
+
+ /* process master volume */
+ case eSysExDeviceControl:
+ if (c == 0x01)
+ pMIDIStream->sysExState = eSysExMasterVolume;
+ else
+ pMIDIStream->sysExState = eSysExIgnore;
+ break;
+
+ case eSysExMasterVolume:
+ /* save LSB */
+ pMIDIStream->d1 = c;
+ pMIDIStream->sysExState = eSysExMasterVolLSB;
+ break;
+
+ case eSysExMasterVolLSB:
+ if (parserMode != eParserModeMetaData)
+ {
+ EAS_I32 gain = ((EAS_I32) c << 8) | ((EAS_I32) pMIDIStream->d1 << 1);
+ gain = (gain * gain) >> 15;
+ VMSetVolume(pSynth, (EAS_U16) gain);
+ }
+ pMIDIStream->sysExState = eSysExEOX;
+ break;
+
+ /* process SP-MIDI MIP message */
+ case eSysExSPMIDI:
+ if (c == 0x01)
+ {
+ /* assume all channels are muted */
+ if (parserMode != eParserModeMetaData)
+ VMInitMIPTable(pSynth);
+ pMIDIStream->d1 = 0;
+ pMIDIStream->sysExState = eSysExSPMIDIchan;
+ }
+ else
+ pMIDIStream->sysExState = eSysExIgnore;
+ break;
+
+ case eSysExSPMIDIchan:
+ if (c < NUM_SYNTH_CHANNELS)
+ {
+ pMIDIStream->d2 = c;
+ pMIDIStream->sysExState = eSysExSPMIDIMIP;
+ }
+ else
+ {
+ /* bad MIP message - unmute channels */
+ if (parserMode != eParserModeMetaData)
+ VMInitMIPTable(pSynth);
+ pMIDIStream->sysExState = eSysExIgnore;
+ }
+ break;
+
+ case eSysExSPMIDIMIP:
+ /* process MIP entry here */
+ if (parserMode != eParserModeMetaData)
+ VMSetMIPEntry(pEASData->pVoiceMgr, pSynth, pMIDIStream->d2, pMIDIStream->d1, c);
+ pMIDIStream->sysExState = eSysExSPMIDIchan;
+
+ /* if 16 channels received, update MIP table */
+ if (++pMIDIStream->d1 == NUM_SYNTH_CHANNELS)
+ {
+ if (parserMode != eParserModeMetaData)
+ VMUpdateMIPTable(pEASData->pVoiceMgr, pSynth);
+ pMIDIStream->sysExState = eSysExEOX;
+ }
+ break;
+
+ /* process Enhancer */
+ case eSysExMfgID1:
+ if (c == 0x01)
+ pMIDIStream->sysExState = eSysExMfgID1;
+ else
+ pMIDIStream->sysExState = eSysExIgnore;
+ break;
+
+ case eSysExMfgID2:
+ if (c == 0x3a)
+ pMIDIStream->sysExState = eSysExMfgID1;
+ else
+ pMIDIStream->sysExState = eSysExIgnore;
+ break;
+
+ case eSysExMfgID3:
+ if (c == 0x04)
+ pMIDIStream->sysExState = eSysExEnhancer;
+ else
+ pMIDIStream->sysExState = eSysExIgnore;
+ break;
+
+ case eSysExEnhancer:
+ if (c == 0x01)
+ pMIDIStream->sysExState = eSysExEnhancerSubID;
+ else
+ pMIDIStream->sysExState = eSysExIgnore;
+ break;
+
+ case eSysExEnhancerSubID:
+ pMIDIStream->sysExState = eSysExEnhancerFeedback1;
+ break;
+
+ case eSysExEnhancerFeedback1:
+ pMIDIStream->sysExState = eSysExEnhancerFeedback2;
+ break;
+
+ case eSysExEnhancerFeedback2:
+ pMIDIStream->sysExState = eSysExEnhancerDrive;
+ break;
+
+ case eSysExEnhancerDrive:
+ pMIDIStream->sysExState = eSysExEnhancerWet;
+ break;
+
+ case eSysExEnhancerWet:
+ pMIDIStream->sysExState = eSysExEOX;
+ break;
+
+ case eSysExEOX:
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Expected F7, received %02x\n", c); */ }
+ pMIDIStream->sysExState = eSysExIgnore;
+ break;
+
+ case eSysExIgnore:
+ break;
+
+ default:
+ pMIDIStream->sysExState = eSysExIgnore;
+ break;
+ }
+ }
+
+ if (pMIDIStream->sysExState == eSysExIgnore)
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Ignoring SysEx byte %02x\n", c); */ }
+ return EAS_SUCCESS;
+} /* end ProcessSysExMessage */
+
diff --git a/arm-wt-22k/lib_src/eas_midi.h b/arm-wt-22k/lib_src/eas_midi.h
index 37a03ee..10649a0 100644
--- a/arm-wt-22k/lib_src/eas_midi.h
+++ b/arm-wt-22k/lib_src/eas_midi.h
@@ -1,13 +1,13 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_midi.h
- *
- * Contents and purpose:
- * Prototypes for MIDI stream parsing functions
- *
- *
- * Copyright Sonic Network Inc. 2005
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_midi.h
+ *
+ * Contents and purpose:
+ * Prototypes for MIDI stream parsing functions
+ *
+ *
+ * Copyright Sonic Network Inc. 2005
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,52 +20,52 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 82 $
- * $Date: 2006-07-10 11:45:19 -0700 (Mon, 10 Jul 2006) $
- *----------------------------------------------------------------------------
-*/
-
-#ifndef _EAS_MIDI_H
-#define _EAS_MIDI_H
-
-/*----------------------------------------------------------------------------
- * EAS_InitMIDIStream()
- *----------------------------------------------------------------------------
- * Purpose:
- * Initializes the MIDI stream state for parsing.
- *
- * Inputs:
- *
- * Outputs:
- * returns EAS_RESULT (EAS_SUCCESS is OK)
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-void EAS_InitMIDIStream (S_MIDI_STREAM *pMIDIStream);
-
-/*----------------------------------------------------------------------------
- * EAS_ParseMIDIStream()
- *----------------------------------------------------------------------------
- * Purpose:
- * Parses a MIDI input stream character by character. Characters are pushed (rather than pulled)
- * so the interface works equally well for both file and stream I/O.
- *
- * Inputs:
- * c - character from MIDI stream
- *
- * Outputs:
- * returns EAS_RESULT (EAS_SUCCESS is OK)
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT EAS_ParseMIDIStream (S_EAS_DATA *pEASData, S_SYNTH *pSynth, S_MIDI_STREAM *pMIDIStream, EAS_U8 c, EAS_INT parserMode);
-
-#endif /* #define _EAS_MIDI_H */
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 82 $
+ * $Date: 2006-07-10 11:45:19 -0700 (Mon, 10 Jul 2006) $
+ *----------------------------------------------------------------------------
+*/
+
+#ifndef _EAS_MIDI_H
+#define _EAS_MIDI_H
+
+/*----------------------------------------------------------------------------
+ * EAS_InitMIDIStream()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Initializes the MIDI stream state for parsing.
+ *
+ * Inputs:
+ *
+ * Outputs:
+ * returns EAS_RESULT (EAS_SUCCESS is OK)
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+void EAS_InitMIDIStream (S_MIDI_STREAM *pMIDIStream);
+
+/*----------------------------------------------------------------------------
+ * EAS_ParseMIDIStream()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Parses a MIDI input stream character by character. Characters are pushed (rather than pulled)
+ * so the interface works equally well for both file and stream I/O.
+ *
+ * Inputs:
+ * c - character from MIDI stream
+ *
+ * Outputs:
+ * returns EAS_RESULT (EAS_SUCCESS is OK)
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_ParseMIDIStream (S_EAS_DATA *pEASData, S_SYNTH *pSynth, S_MIDI_STREAM *pMIDIStream, EAS_U8 c, EAS_INT parserMode);
+
+#endif /* #define _EAS_MIDI_H */
+
diff --git a/arm-wt-22k/lib_src/eas_midictrl.h b/arm-wt-22k/lib_src/eas_midictrl.h
index 0c4217d..46fdc4f 100644
--- a/arm-wt-22k/lib_src/eas_midictrl.h
+++ b/arm-wt-22k/lib_src/eas_midictrl.h
@@ -1,15 +1,15 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_midictrl.h
- *
- * Contents and purpose:
- * MIDI controller definitions
- *
- * This header only contains declarations that are specific
- * to this implementation.
- *
- * Copyright Sonic Network Inc. 2005
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_midictrl.h
+ *
+ * Contents and purpose:
+ * MIDI controller definitions
+ *
+ * This header only contains declarations that are specific
+ * to this implementation.
+ *
+ * Copyright Sonic Network Inc. 2005
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -22,43 +22,43 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 82 $
- * $Date: 2006-07-10 11:45:19 -0700 (Mon, 10 Jul 2006) $
- *----------------------------------------------------------------------------
-*/
-
-#ifndef _EAS_MIDICTRL_H
-#define _EAS_MIDICTRL_H
-
-/* define controller types */
-/*
- Note that these controller types are specified in base 10 (decimal)
- and not in hexadecimal. The above midi messages are specified
- in hexadecimal.
-*/
-#define MIDI_CONTROLLER_BANK_SELECT 0
-#define MIDI_CONTROLLER_BANK_SELECT_MSB 0
-#define MIDI_CONTROLLER_MOD_WHEEL 1
-#define MIDI_CONTROLLER_ENTER_DATA_MSB 6
-#define MIDI_CONTROLLER_VOLUME 7
-#define MIDI_CONTROLLER_PAN 10
-#define MIDI_CONTROLLER_EXPRESSION 11
-#define MIDI_CONTROLLER_BANK_SELECT_LSB 32
-#define MIDI_CONTROLLER_ENTER_DATA_LSB 38 /* 0x26 */
-#define MIDI_CONTROLLER_SUSTAIN_PEDAL 64
-#define MIDI_CONTROLLER_SELECT_NRPN_LSB 98
-#define MIDI_CONTROLLER_SELECT_NRPN_MSB 99
-#define MIDI_CONTROLLER_SELECT_RPN_LSB 100 /* 0x64 */
-#define MIDI_CONTROLLER_SELECT_RPN_MSB 101 /* 0x65 */
-#define MIDI_CONTROLLER_ALL_SOUND_OFF 120
-#define MIDI_CONTROLLER_RESET_CONTROLLERS 121
-#define MIDI_CONTROLLER_ALL_NOTES_OFF 123
-#define MIDI_CONTROLLER_OMNI_OFF 124
-#define MIDI_CONTROLLER_OMNI_ON 125
-#define MIDI_CONTROLLER_MONO_ON_POLY_OFF 126
-#define MIDI_CONTROLLER_POLY_ON_MONO_OFF 127
-
-#endif /* #ifndef _EAS_MIDICTRL_H */
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 82 $
+ * $Date: 2006-07-10 11:45:19 -0700 (Mon, 10 Jul 2006) $
+ *----------------------------------------------------------------------------
+*/
+
+#ifndef _EAS_MIDICTRL_H
+#define _EAS_MIDICTRL_H
+
+/* define controller types */
+/*
+ Note that these controller types are specified in base 10 (decimal)
+ and not in hexadecimal. The above midi messages are specified
+ in hexadecimal.
+*/
+#define MIDI_CONTROLLER_BANK_SELECT 0
+#define MIDI_CONTROLLER_BANK_SELECT_MSB 0
+#define MIDI_CONTROLLER_MOD_WHEEL 1
+#define MIDI_CONTROLLER_ENTER_DATA_MSB 6
+#define MIDI_CONTROLLER_VOLUME 7
+#define MIDI_CONTROLLER_PAN 10
+#define MIDI_CONTROLLER_EXPRESSION 11
+#define MIDI_CONTROLLER_BANK_SELECT_LSB 32
+#define MIDI_CONTROLLER_ENTER_DATA_LSB 38 /* 0x26 */
+#define MIDI_CONTROLLER_SUSTAIN_PEDAL 64
+#define MIDI_CONTROLLER_SELECT_NRPN_LSB 98
+#define MIDI_CONTROLLER_SELECT_NRPN_MSB 99
+#define MIDI_CONTROLLER_SELECT_RPN_LSB 100 /* 0x64 */
+#define MIDI_CONTROLLER_SELECT_RPN_MSB 101 /* 0x65 */
+#define MIDI_CONTROLLER_ALL_SOUND_OFF 120
+#define MIDI_CONTROLLER_RESET_CONTROLLERS 121
+#define MIDI_CONTROLLER_ALL_NOTES_OFF 123
+#define MIDI_CONTROLLER_OMNI_OFF 124
+#define MIDI_CONTROLLER_OMNI_ON 125
+#define MIDI_CONTROLLER_MONO_ON_POLY_OFF 126
+#define MIDI_CONTROLLER_POLY_ON_MONO_OFF 127
+
+#endif /* #ifndef _EAS_MIDICTRL_H */
diff --git a/arm-wt-22k/lib_src/eas_mididata.c b/arm-wt-22k/lib_src/eas_mididata.c
index 2ee907e..4463b7e 100644
--- a/arm-wt-22k/lib_src/eas_mididata.c
+++ b/arm-wt-22k/lib_src/eas_mididata.c
@@ -1,13 +1,13 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_mididata.c
- *
- * Contents and purpose:
- * Data module for MIDI stream interface
- *
- *
- * Copyright Sonic Network Inc. 2005
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_mididata.c
+ *
+ * Contents and purpose:
+ * Data module for MIDI stream interface
+ *
+ *
+ * Copyright Sonic Network Inc. 2005
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,15 +20,15 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 547 $
- * $Date: 2007-01-31 16:30:17 -0800 (Wed, 31 Jan 2007) $
- *----------------------------------------------------------------------------
-*/
-
-#include "eas_miditypes.h"
-
-S_INTERACTIVE_MIDI eas_MIDIData;
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 547 $
+ * $Date: 2007-01-31 16:30:17 -0800 (Wed, 31 Jan 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+#include "eas_miditypes.h"
+
+S_INTERACTIVE_MIDI eas_MIDIData;
+
diff --git a/arm-wt-22k/lib_src/eas_miditypes.h b/arm-wt-22k/lib_src/eas_miditypes.h
index 0b7f96e..015f08b 100644
--- a/arm-wt-22k/lib_src/eas_miditypes.h
+++ b/arm-wt-22k/lib_src/eas_miditypes.h
@@ -1,13 +1,13 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_miditypes.h
- *
- * Contents and purpose:
- * Contains declarations for the MIDI stream parser.
- *
- *
- * Copyright Sonic Network Inc. 2005
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_miditypes.h
+ *
+ * Contents and purpose:
+ * Contains declarations for the MIDI stream parser.
+ *
+ *
+ * Copyright Sonic Network Inc. 2005
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,119 +20,119 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 778 $
- * $Date: 2007-07-23 16:45:17 -0700 (Mon, 23 Jul 2007) $
- *----------------------------------------------------------------------------
-*/
-
-#ifndef _EAS_MIDITYPES_H
-#define _EAS_MIDITYPES_H
-
-#include "eas_data.h"
-#include "eas_parser.h"
-
-/*----------------------------------------------------------------------------
- * S_MIDI_STREAM
- *
- * Maintains parser state for the MIDI stream parser
- *
- *----------------------------------------------------------------------------
-*/
-
-typedef struct s_midi_stream_tag
-{
- EAS_BOOL8 byte3; /* flag indicates 3rd byte expected */
- EAS_BOOL8 pending; /* flag indicates more data expected */
- EAS_U8 sysExState; /* maintains the SysEx state */
- EAS_U8 runningStatus; /* last running status received */
- EAS_U8 status; /* status byte */
- EAS_U8 d1; /* first data byte */
- EAS_U8 d2; /* second data byte */
- EAS_U8 flags; /* flags - see below for definition */
-#ifdef JET_INTERFACE
- EAS_U32 jetData; /* JET data */
-#endif
-} S_MIDI_STREAM;
-
-/* flags for S_MIDI_STREAM.flags */
-#define MIDI_FLAG_GM_ON 0x01 /* GM System On message received */
-#define MIDI_FLAG_FIRST_NOTE 0x02 /* first note received */
-
-/* flags for S_MIDI_STREAM.jetFlags */
-#define MIDI_FLAGS_JET_MUTE 0x00000001 /* track is muted */
-#define MIDI_FLAGS_JET_CB 0x00000002 /* JET callback enabled */
-
-/*----------------------------------------------------------------------------
- *
- * S_SMF_STREAM
- *
- * This structure contains data required to parse an SMF stream. For SMF0 files, there
- * will be a single instance of this per file. For SMF1 files, there will be multiple instance,
- * one for each separate stream in the file.
- *
- *----------------------------------------------------------------------------
-*/
-
-typedef struct s_smf_stream_tag
-{
- EAS_FILE_HANDLE fileHandle; /* host wrapper file handle */
- EAS_U32 ticks; /* time of next event in stream */
- EAS_I32 startFilePos; /* start location of track within file */
- S_MIDI_STREAM midiStream; /* MIDI stream state */
-} S_SMF_STREAM;
-
-/*----------------------------------------------------------------------------
- *
- * S_SMF_DATA
- *
- * This structure contains the instance data required to parse an SMF stream.
- *
- *----------------------------------------------------------------------------
-*/
-
-typedef struct s_smf_data_tag
-{
-#ifdef _CHECKED_BUILD
- EAS_U32 handleCheck; /* signature check for checked build */
-#endif
- S_SMF_STREAM *streams; /* pointer to individual streams in file */
- S_SMF_STREAM *nextStream; /* pointer to next stream with event */
- S_SYNTH *pSynth; /* pointer to synth */
- EAS_FILE_HANDLE fileHandle; /* file handle */
- S_METADATA_CB metadata; /* metadata callback */
- EAS_I32 fileOffset; /* for embedded files */
- EAS_I32 time; /* current time in milliseconds/256 */
- EAS_U16 numStreams; /* actual number of streams */
- EAS_U16 tickConv; /* current MIDI tick to msec conversion */
- EAS_U16 ppqn; /* ticks per quarter note */
- EAS_U8 state; /* current state EAS_STATE_XXXX */
- EAS_U8 flags; /* flags - see definitions below */
-} S_SMF_DATA;
-
-#define SMF_FLAGS_CHASE_MODE 0x01 /* chase mode - skip to first note */
-#define SMF_FLAGS_HAS_TIME_SIG 0x02 /* time signature encountered at time 0 */
-#define SMF_FLAGS_HAS_TEMPO 0x04 /* tempo encountered at time 0 */
-#define SMF_FLAGS_HAS_GM_ON 0x08 /* GM System On encountered at time 0 */
-#define SMF_FLAGS_JET_STREAM 0x80 /* JET in use - keep strict timing */
-
-/* combo flags indicate setup bar */
-#define SMF_FLAGS_SETUP_BAR (SMF_FLAGS_HAS_TIME_SIG | SMF_FLAGS_HAS_TEMPO | SMF_FLAGS_HAS_GM_ON)
-
-/*----------------------------------------------------------------------------
- * Interactive MIDI structure
- *----------------------------------------------------------------------------
-*/
-typedef struct s_interactive_midi_tag
-{
-#ifdef _CHECKED_BUILD
- EAS_U32 handleCheck; /* signature check for checked build */
-#endif
- S_SYNTH *pSynth; /* pointer to synth */
- S_MIDI_STREAM stream; /* stream data */
-} S_INTERACTIVE_MIDI;
-
-#endif /* #ifndef _EAS_MIDITYPES_H */
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 778 $
+ * $Date: 2007-07-23 16:45:17 -0700 (Mon, 23 Jul 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+#ifndef _EAS_MIDITYPES_H
+#define _EAS_MIDITYPES_H
+
+#include "eas_data.h"
+#include "eas_parser.h"
+
+/*----------------------------------------------------------------------------
+ * S_MIDI_STREAM
+ *
+ * Maintains parser state for the MIDI stream parser
+ *
+ *----------------------------------------------------------------------------
+*/
+
+typedef struct s_midi_stream_tag
+{
+ EAS_BOOL8 byte3; /* flag indicates 3rd byte expected */
+ EAS_BOOL8 pending; /* flag indicates more data expected */
+ EAS_U8 sysExState; /* maintains the SysEx state */
+ EAS_U8 runningStatus; /* last running status received */
+ EAS_U8 status; /* status byte */
+ EAS_U8 d1; /* first data byte */
+ EAS_U8 d2; /* second data byte */
+ EAS_U8 flags; /* flags - see below for definition */
+#ifdef JET_INTERFACE
+ EAS_U32 jetData; /* JET data */
+#endif
+} S_MIDI_STREAM;
+
+/* flags for S_MIDI_STREAM.flags */
+#define MIDI_FLAG_GM_ON 0x01 /* GM System On message received */
+#define MIDI_FLAG_FIRST_NOTE 0x02 /* first note received */
+
+/* flags for S_MIDI_STREAM.jetFlags */
+#define MIDI_FLAGS_JET_MUTE 0x00000001 /* track is muted */
+#define MIDI_FLAGS_JET_CB 0x00000002 /* JET callback enabled */
+
+/*----------------------------------------------------------------------------
+ *
+ * S_SMF_STREAM
+ *
+ * This structure contains data required to parse an SMF stream. For SMF0 files, there
+ * will be a single instance of this per file. For SMF1 files, there will be multiple instance,
+ * one for each separate stream in the file.
+ *
+ *----------------------------------------------------------------------------
+*/
+
+typedef struct s_smf_stream_tag
+{
+ EAS_FILE_HANDLE fileHandle; /* host wrapper file handle */
+ EAS_U32 ticks; /* time of next event in stream */
+ EAS_I32 startFilePos; /* start location of track within file */
+ S_MIDI_STREAM midiStream; /* MIDI stream state */
+} S_SMF_STREAM;
+
+/*----------------------------------------------------------------------------
+ *
+ * S_SMF_DATA
+ *
+ * This structure contains the instance data required to parse an SMF stream.
+ *
+ *----------------------------------------------------------------------------
+*/
+
+typedef struct s_smf_data_tag
+{
+#ifdef _CHECKED_BUILD
+ EAS_U32 handleCheck; /* signature check for checked build */
+#endif
+ S_SMF_STREAM *streams; /* pointer to individual streams in file */
+ S_SMF_STREAM *nextStream; /* pointer to next stream with event */
+ S_SYNTH *pSynth; /* pointer to synth */
+ EAS_FILE_HANDLE fileHandle; /* file handle */
+ S_METADATA_CB metadata; /* metadata callback */
+ EAS_I32 fileOffset; /* for embedded files */
+ EAS_I32 time; /* current time in milliseconds/256 */
+ EAS_U16 numStreams; /* actual number of streams */
+ EAS_U16 tickConv; /* current MIDI tick to msec conversion */
+ EAS_U16 ppqn; /* ticks per quarter note */
+ EAS_U8 state; /* current state EAS_STATE_XXXX */
+ EAS_U8 flags; /* flags - see definitions below */
+} S_SMF_DATA;
+
+#define SMF_FLAGS_CHASE_MODE 0x01 /* chase mode - skip to first note */
+#define SMF_FLAGS_HAS_TIME_SIG 0x02 /* time signature encountered at time 0 */
+#define SMF_FLAGS_HAS_TEMPO 0x04 /* tempo encountered at time 0 */
+#define SMF_FLAGS_HAS_GM_ON 0x08 /* GM System On encountered at time 0 */
+#define SMF_FLAGS_JET_STREAM 0x80 /* JET in use - keep strict timing */
+
+/* combo flags indicate setup bar */
+#define SMF_FLAGS_SETUP_BAR (SMF_FLAGS_HAS_TIME_SIG | SMF_FLAGS_HAS_TEMPO | SMF_FLAGS_HAS_GM_ON)
+
+/*----------------------------------------------------------------------------
+ * Interactive MIDI structure
+ *----------------------------------------------------------------------------
+*/
+typedef struct s_interactive_midi_tag
+{
+#ifdef _CHECKED_BUILD
+ EAS_U32 handleCheck; /* signature check for checked build */
+#endif
+ S_SYNTH *pSynth; /* pointer to synth */
+ S_MIDI_STREAM stream; /* stream data */
+} S_INTERACTIVE_MIDI;
+
+#endif /* #ifndef _EAS_MIDITYPES_H */
+
diff --git a/arm-wt-22k/lib_src/eas_mixbuf.c b/arm-wt-22k/lib_src/eas_mixbuf.c
index 73e969a..db5bd02 100644
--- a/arm-wt-22k/lib_src/eas_mixbuf.c
+++ b/arm-wt-22k/lib_src/eas_mixbuf.c
@@ -1,12 +1,12 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_mixbuf.c
- *
- * Contents and purpose:
- * Contains a data allocation for synthesizer
- *
- * Copyright Sonic Network Inc. 2004
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_mixbuf.c
+ *
+ * Contents and purpose:
+ * Contains a data allocation for synthesizer
+ *
+ * Copyright Sonic Network Inc. 2004
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,18 +19,18 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 82 $
- * $Date: 2006-07-10 11:45:19 -0700 (Mon, 10 Jul 2006) $
- *----------------------------------------------------------------------------
-*/
-
-// includes
-#include "eas_data.h"
-#include "eas_mixer.h"
-
-// globals
-EAS_I32 eas_MixBuffer[BUFFER_SIZE_IN_MONO_SAMPLES * NUM_OUTPUT_CHANNELS];
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 82 $
+ * $Date: 2006-07-10 11:45:19 -0700 (Mon, 10 Jul 2006) $
+ *----------------------------------------------------------------------------
+*/
+
+// includes
+#include "eas_data.h"
+#include "eas_mixer.h"
+
+// globals
+EAS_I32 eas_MixBuffer[BUFFER_SIZE_IN_MONO_SAMPLES * NUM_OUTPUT_CHANNELS];
+
diff --git a/arm-wt-22k/lib_src/eas_mixer.c b/arm-wt-22k/lib_src/eas_mixer.c
index c4a2f9f..0a839a8 100644
--- a/arm-wt-22k/lib_src/eas_mixer.c
+++ b/arm-wt-22k/lib_src/eas_mixer.c
@@ -1,13 +1,13 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_mixer.c
- *
- * Contents and purpose:
- * This file contains the critical components of the mix engine that
- * must be optimized for best performance.
- *
- * Copyright Sonic Network Inc. 2005
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_mixer.c
+ *
+ * Contents and purpose:
+ * This file contains the critical components of the mix engine that
+ * must be optimized for best performance.
+ *
+ * Copyright Sonic Network Inc. 2005
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,445 +20,445 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 706 $
- * $Date: 2007-05-31 17:22:51 -0700 (Thu, 31 May 2007) $
- *----------------------------------------------------------------------------
-*/
-
-//3 dls: This module is in the midst of being converted from a synth
-//3 specific module to a general purpose mix engine
-
-/*------------------------------------
- * includes
- *------------------------------------
-*/
-#include "eas_data.h"
-#include "eas_host.h"
-#include "eas_math.h"
-#include "eas_mixer.h"
-#include "eas_config.h"
-#include "eas_report.h"
-
-#ifdef _MAXIMIZER_ENABLED
-EAS_I32 MaximizerProcess (EAS_VOID_PTR pInstData, EAS_I32 *pSrc, EAS_I32 *pDst, EAS_I32 numSamples);
-#endif
-
-/*------------------------------------
- * defines
- *------------------------------------
-*/
-
-/* need to boost stereo by ~3dB to compensate for the panner */
-#define STEREO_3DB_GAIN_BOOST 512
-
-/*----------------------------------------------------------------------------
- * EAS_MixEngineInit()
- *----------------------------------------------------------------------------
- * Purpose:
- * Prepares the mix engine for work, allocates buffers, locates effects modules, etc.
- *
- * Inputs:
- * pEASData - instance data
- * pInstData - pointer to variable to receive instance data handle
- *
- * Outputs:
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT EAS_MixEngineInit (S_EAS_DATA *pEASData)
-{
-
- /* check Configuration Module for mix buffer allocation */
- if (pEASData->staticMemoryModel)
- pEASData->pMixBuffer = EAS_CMEnumData(EAS_CM_MIX_BUFFER);
- else
- pEASData->pMixBuffer = EAS_HWMalloc(pEASData->hwInstData, BUFFER_SIZE_IN_MONO_SAMPLES * NUM_OUTPUT_CHANNELS * sizeof(EAS_I32));
- if (pEASData->pMixBuffer == NULL)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_FATAL, "Failed to allocate mix buffer memory\n"); */ }
- return EAS_ERROR_MALLOC_FAILED;
- }
- EAS_HWMemSet((void *)(pEASData->pMixBuffer), 0, BUFFER_SIZE_IN_MONO_SAMPLES * NUM_OUTPUT_CHANNELS * sizeof(EAS_I32));
-
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * EAS_MixEnginePrep()
- *----------------------------------------------------------------------------
- * Purpose:
- * Performs prep before synthesize a buffer of audio, such as clearing
- * audio buffers, etc.
- *
- * Inputs:
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-void EAS_MixEnginePrep (S_EAS_DATA *pEASData, EAS_I32 numSamples)
-{
-
- /* clear the mix buffer */
-#if (NUM_OUTPUT_CHANNELS == 2)
- EAS_HWMemSet(pEASData->pMixBuffer, 0, numSamples * (EAS_I32) sizeof(long) * 2);
-#else
- EAS_HWMemSet(pEASData->pMixBuffer, 0, (EAS_I32) numSamples * (EAS_I32) sizeof(long));
-#endif
-
- /* need to clear other side-chain effect buffers (chorus & reverb) */
-}
-
-/*----------------------------------------------------------------------------
- * EAS_MixEnginePost
- *----------------------------------------------------------------------------
- * Purpose:
- * This routine does the post-processing after all voices have been
- * synthesized. It calls any sweeteners and does the final mixdown to
- * the output buffer.
- *
- * Inputs:
- *
- * Outputs:
- *
- * Notes:
- *----------------------------------------------------------------------------
-*/
-void EAS_MixEnginePost (S_EAS_DATA *pEASData, EAS_I32 numSamples)
-{
- EAS_U16 gain;
-
-//3 dls: Need to restore the mix engine metrics
-
- /* calculate the gain multiplier */
-#ifdef _MAXIMIZER_ENABLED
- if (pEASData->effectsModules[EAS_MODULE_MAXIMIZER].effect)
- {
- EAS_I32 temp;
- temp = MaximizerProcess(pEASData->effectsModules[EAS_MODULE_MAXIMIZER].effectData, pEASData->pMixBuffer, pEASData->pMixBuffer, numSamples);
- temp = (temp * pEASData->masterGain) >> 15;
- if (temp > 32767)
- gain = 32767;
- else
- gain = (EAS_U16) temp;
- }
- else
- gain = (EAS_U16) pEASData->masterGain;
-#else
- gain = (EAS_U16) pEASData->masterGain;
-#endif
-
- /* Not using all the gain bits for now
- * Reduce the input to the compressor by 6dB to prevent saturation
- */
-#ifdef _COMPRESSOR_ENABLED
- if (pEASData->effectsModules[EAS_MODULE_COMPRESSOR].effectData)
- gain = gain >> 5;
- else
- gain = gain >> 4;
-#else
- gain = gain >> 4;
-#endif
-
- /* convert 32-bit mix buffer to 16-bit output format */
-#if (NUM_OUTPUT_CHANNELS == 2)
- SynthMasterGain(pEASData->pMixBuffer, pEASData->pOutputAudioBuffer, gain, (EAS_U16) ((EAS_U16) numSamples * 2));
-#else
- SynthMasterGain(pEASData->pMixBuffer, pEASData->pOutputAudioBuffer, gain, (EAS_U16) numSamples);
-#endif
-
-#ifdef _ENHANCER_ENABLED
- /* enhancer effect */
- if (pEASData->effectsModules[EAS_MODULE_ENHANCER].effectData)
- (*pEASData->effectsModules[EAS_MODULE_ENHANCER].effect->pfProcess)
- (pEASData->effectsModules[EAS_MODULE_ENHANCER].effectData,
- pEASData->pOutputAudioBuffer,
- pEASData->pOutputAudioBuffer,
- numSamples);
-#endif
-
-#ifdef _GRAPHIC_EQ_ENABLED
- /* graphic EQ effect */
- if (pEASData->effectsModules[EAS_MODULE_GRAPHIC_EQ].effectData)
- (*pEASData->effectsModules[EAS_MODULE_GRAPHIC_EQ].effect->pfProcess)
- (pEASData->effectsModules[EAS_MODULE_GRAPHIC_EQ].effectData,
- pEASData->pOutputAudioBuffer,
- pEASData->pOutputAudioBuffer,
- numSamples);
-#endif
-
-#ifdef _COMPRESSOR_ENABLED
- /* compressor effect */
- if (pEASData->effectsModules[EAS_MODULE_COMPRESSOR].effectData)
- (*pEASData->effectsModules[EAS_MODULE_COMPRESSOR].effect->pfProcess)
- (pEASData->effectsModules[EAS_MODULE_COMPRESSOR].effectData,
- pEASData->pOutputAudioBuffer,
- pEASData->pOutputAudioBuffer,
- numSamples);
-#endif
-
-#ifdef _WOW_ENABLED
- /* WOW requires a 32-bit buffer, borrow the mix buffer and
- * pass it as the destination buffer
- */
- /*lint -e{740} temporarily passing a parameter through an existing I/F */
- if (pEASData->effectsModules[EAS_MODULE_WOW].effectData)
- (*pEASData->effectsModules[EAS_MODULE_WOW].effect->pfProcess)
- (pEASData->effectsModules[EAS_MODULE_WOW].effectData,
- pEASData->pOutputAudioBuffer,
- (EAS_PCM*) pEASData->pMixBuffer,
- numSamples);
-#endif
-
-#ifdef _TONECONTROLEQ_ENABLED
- /* ToneControlEQ effect */
- if (pEASData->effectsModules[EAS_MODULE_TONECONTROLEQ].effectData)
- (*pEASData->effectsModules[EAS_MODULE_TONECONTROLEQ].effect->pfProcess)
- (pEASData->effectsModules[EAS_MODULE_TONECONTROLEQ].effectData,
- pEASData->pOutputAudioBuffer,
- pEASData->pOutputAudioBuffer,
- numSamples);
-#endif
-
-#ifdef _REVERB_ENABLED
- /* Reverb effect */
- if (pEASData->effectsModules[EAS_MODULE_REVERB].effectData)
- (*pEASData->effectsModules[EAS_MODULE_REVERB].effect->pfProcess)
- (pEASData->effectsModules[EAS_MODULE_REVERB].effectData,
- pEASData->pOutputAudioBuffer,
- pEASData->pOutputAudioBuffer,
- numSamples);
-#endif
-
-#ifdef _CHORUS_ENABLED
- /* Chorus effect */
- if (pEASData->effectsModules[EAS_MODULE_CHORUS].effectData)
- (*pEASData->effectsModules[EAS_MODULE_CHORUS].effect->pfProcess)
- (pEASData->effectsModules[EAS_MODULE_CHORUS].effectData,
- pEASData->pOutputAudioBuffer,
- pEASData->pOutputAudioBuffer,
- numSamples);
-#endif
-
-}
-
-#ifndef NATIVE_EAS_KERNEL
-/*----------------------------------------------------------------------------
- * SynthMasterGain
- *----------------------------------------------------------------------------
- * Purpose:
- * Mixes down audio from 32-bit to 16-bit target buffer
- *
- * Inputs:
- *
- * Outputs:
- *
- *----------------------------------------------------------------------------
-*/
-void SynthMasterGain (long *pInputBuffer, EAS_PCM *pOutputBuffer, EAS_U16 nGain, EAS_U16 numSamples) {
-
- /* loop through the buffer */
- while (numSamples--) {
- long s;
-
- /* read a sample from the input buffer and add some guard bits */
- s = *pInputBuffer++;
-
- /* add some guard bits */
- /*lint -e{704} <avoid divide for performance>*/
- s = s >> 7;
-
- /* apply master gain */
- s *= (long) nGain;
-
- /* shift to lower 16-bits */
- /*lint -e{704} <avoid divide for performance>*/
- s = s >> 9;
-
- /* saturate */
- s = SATURATE(s);
-
- *pOutputBuffer++ = (EAS_PCM)s;
- }
-}
-#endif
-
-/*----------------------------------------------------------------------------
- * EAS_MixEngineShutdown()
- *----------------------------------------------------------------------------
- * Purpose:
- * Shuts down effects modules and deallocates memory
- *
- * Inputs:
- * pEASData - instance data
- * pInstData - instance data handle
- *
- * Outputs:
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT EAS_MixEngineShutdown (S_EAS_DATA *pEASData)
-{
-
- /* check Configuration Module for static memory allocation */
- if (!pEASData->staticMemoryModel && (pEASData->pMixBuffer != NULL))
- EAS_HWFree(pEASData->hwInstData, pEASData->pMixBuffer);
-
- return EAS_SUCCESS;
-}
-
-#ifdef UNIFIED_MIXER
-#ifndef NATIVE_MIX_STREAM
-/*----------------------------------------------------------------------------
- * EAS_MixStream
- *----------------------------------------------------------------------------
- * Mix a 16-bit stream into a 32-bit buffer
- *
- * pInputBuffer 16-bit input buffer
- * pMixBuffer 32-bit mix buffer
- * numSamples number of samples to mix
- * gainLeft initial gain left or mono
- * gainRight initial gain right
- * gainLeft left gain increment per sample
- * gainRight right gain increment per sample
- * flags bit 0 = stereo source
- * bit 1 = stereo output
- *----------------------------------------------------------------------------
-*/
-void EAS_MixStream (EAS_PCM *pInputBuffer, EAS_I32 *pMixBuffer, EAS_I32 numSamples, EAS_I32 gainLeft, EAS_I32 gainRight, EAS_I32 gainIncLeft, EAS_I32 gainIncRight, EAS_I32 flags)
-{
- EAS_I32 temp;
- EAS_INT src, dest;
-
- /* NOTE: There are a lot of optimizations that can be done
- * in the native implementations based on register
- * availability, etc. For example, it may make sense to
- * break this down into 8 separate routines:
- *
- * 1. Mono source to mono output
- * 2. Mono source to stereo output
- * 3. Stereo source to mono output
- * 4. Stereo source to stereo output
- * 5. Mono source to mono output - no gain change
- * 6. Mono source to stereo output - no gain change
- * 7. Stereo source to mono output - no gain change
- * 8. Stereo source to stereo output - no gain change
- *
- * Other possibilities include loop unrolling, skipping
- * a gain calculation every 2 or 4 samples, etc.
- */
-
- /* no gain change, use fast loops */
- if ((gainIncLeft == 0) && (gainIncRight == 0))
- {
- switch (flags & (MIX_FLAGS_STEREO_SOURCE | MIX_FLAGS_STEREO_OUTPUT))
- {
- /* mono to mono */
- case 0:
- gainLeft >>= 15;
- for (src = dest = 0; src < numSamples; src++, dest++)
- {
-
- pMixBuffer[dest] += (pInputBuffer[src] * gainLeft) >> NUM_MIXER_GUARD_BITS;
- }
- break;
-
- /* mono to stereo */
- case MIX_FLAGS_STEREO_OUTPUT:
- gainLeft >>= 15;
- gainRight >>= 15;
- for (src = dest = 0; src < numSamples; src++, dest+=2)
- {
- pMixBuffer[dest] += (pInputBuffer[src] * gainLeft) >> NUM_MIXER_GUARD_BITS;
- pMixBuffer[dest+1] += (pInputBuffer[src] * gainRight) >> NUM_MIXER_GUARD_BITS;
- }
- break;
-
- /* stereo to mono */
- case MIX_FLAGS_STEREO_SOURCE:
- gainLeft >>= 15;
- gainRight >>= 15;
- for (src = dest = 0; src < numSamples; src+=2, dest++)
- {
- temp = (pInputBuffer[src] * gainLeft) >> NUM_MIXER_GUARD_BITS;
- temp += ((pInputBuffer[src+1] * gainRight) >> NUM_MIXER_GUARD_BITS);
- pMixBuffer[dest] += temp;
- }
- break;
-
- /* stereo to stereo */
- case MIX_FLAGS_STEREO_SOURCE | MIX_FLAGS_STEREO_OUTPUT:
- gainLeft >>= 15;
- gainRight >>= 15;
- for (src = dest = 0; src < numSamples; src+=2, dest+=2)
- {
- pMixBuffer[dest] += (pInputBuffer[src] * gainLeft) >> NUM_MIXER_GUARD_BITS;
- pMixBuffer[dest+1] += (pInputBuffer[src+1] * gainRight) >> NUM_MIXER_GUARD_BITS;
- }
- break;
- }
- }
-
- /* gain change - do gain increment */
- else
- {
- switch (flags & (MIX_FLAGS_STEREO_SOURCE | MIX_FLAGS_STEREO_OUTPUT))
- {
- /* mono to mono */
- case 0:
- for (src = dest = 0; src < numSamples; src++, dest++)
- {
- gainLeft += gainIncLeft;
- pMixBuffer[dest] += (pInputBuffer[src] * (gainLeft >> 15)) >> NUM_MIXER_GUARD_BITS;
- }
- break;
-
- /* mono to stereo */
- case MIX_FLAGS_STEREO_OUTPUT:
- for (src = dest = 0; src < numSamples; src++, dest+=2)
- {
- gainLeft += gainIncLeft;
- gainRight += gainIncRight;
- pMixBuffer[dest] += (pInputBuffer[src] * (gainLeft >> 15)) >> NUM_MIXER_GUARD_BITS;
- pMixBuffer[dest+1] += (pInputBuffer[src] * (gainRight >> 15)) >> NUM_MIXER_GUARD_BITS;
- }
- break;
-
- /* stereo to mono */
- case MIX_FLAGS_STEREO_SOURCE:
- for (src = dest = 0; src < numSamples; src+=2, dest++)
- {
- gainLeft += gainIncLeft;
- gainRight += gainIncRight;
- temp = (pInputBuffer[src] * (gainLeft >> 15)) >> NUM_MIXER_GUARD_BITS;
- temp += ((pInputBuffer[src+1] * (gainRight >> 15)) >> NUM_MIXER_GUARD_BITS);
- pMixBuffer[dest] += temp;
- }
- break;
-
- /* stereo to stereo */
- case MIX_FLAGS_STEREO_SOURCE | MIX_FLAGS_STEREO_OUTPUT:
- for (src = dest = 0; src < numSamples; src+=2, dest+=2)
- {
- gainLeft += gainIncLeft;
- gainRight += gainIncRight;
- pMixBuffer[dest] += (pInputBuffer[src] * (gainLeft >> 15)) >> NUM_MIXER_GUARD_BITS;
- pMixBuffer[dest+1] += (pInputBuffer[src+1] * (gainRight >> 15)) >> NUM_MIXER_GUARD_BITS;
- }
- break;
- }
- }
-}
-#endif
-#endif
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 706 $
+ * $Date: 2007-05-31 17:22:51 -0700 (Thu, 31 May 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+//3 dls: This module is in the midst of being converted from a synth
+//3 specific module to a general purpose mix engine
+
+/*------------------------------------
+ * includes
+ *------------------------------------
+*/
+#include "eas_data.h"
+#include "eas_host.h"
+#include "eas_math.h"
+#include "eas_mixer.h"
+#include "eas_config.h"
+#include "eas_report.h"
+
+#ifdef _MAXIMIZER_ENABLED
+EAS_I32 MaximizerProcess (EAS_VOID_PTR pInstData, EAS_I32 *pSrc, EAS_I32 *pDst, EAS_I32 numSamples);
+#endif
+
+/*------------------------------------
+ * defines
+ *------------------------------------
+*/
+
+/* need to boost stereo by ~3dB to compensate for the panner */
+#define STEREO_3DB_GAIN_BOOST 512
+
+/*----------------------------------------------------------------------------
+ * EAS_MixEngineInit()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Prepares the mix engine for work, allocates buffers, locates effects modules, etc.
+ *
+ * Inputs:
+ * pEASData - instance data
+ * pInstData - pointer to variable to receive instance data handle
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_MixEngineInit (S_EAS_DATA *pEASData)
+{
+
+ /* check Configuration Module for mix buffer allocation */
+ if (pEASData->staticMemoryModel)
+ pEASData->pMixBuffer = EAS_CMEnumData(EAS_CM_MIX_BUFFER);
+ else
+ pEASData->pMixBuffer = EAS_HWMalloc(pEASData->hwInstData, BUFFER_SIZE_IN_MONO_SAMPLES * NUM_OUTPUT_CHANNELS * sizeof(EAS_I32));
+ if (pEASData->pMixBuffer == NULL)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_FATAL, "Failed to allocate mix buffer memory\n"); */ }
+ return EAS_ERROR_MALLOC_FAILED;
+ }
+ EAS_HWMemSet((void *)(pEASData->pMixBuffer), 0, BUFFER_SIZE_IN_MONO_SAMPLES * NUM_OUTPUT_CHANNELS * sizeof(EAS_I32));
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_MixEnginePrep()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Performs prep before synthesize a buffer of audio, such as clearing
+ * audio buffers, etc.
+ *
+ * Inputs:
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+void EAS_MixEnginePrep (S_EAS_DATA *pEASData, EAS_I32 numSamples)
+{
+
+ /* clear the mix buffer */
+#if (NUM_OUTPUT_CHANNELS == 2)
+ EAS_HWMemSet(pEASData->pMixBuffer, 0, numSamples * (EAS_I32) sizeof(long) * 2);
+#else
+ EAS_HWMemSet(pEASData->pMixBuffer, 0, (EAS_I32) numSamples * (EAS_I32) sizeof(long));
+#endif
+
+ /* need to clear other side-chain effect buffers (chorus & reverb) */
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_MixEnginePost
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * This routine does the post-processing after all voices have been
+ * synthesized. It calls any sweeteners and does the final mixdown to
+ * the output buffer.
+ *
+ * Inputs:
+ *
+ * Outputs:
+ *
+ * Notes:
+ *----------------------------------------------------------------------------
+*/
+void EAS_MixEnginePost (S_EAS_DATA *pEASData, EAS_I32 numSamples)
+{
+ EAS_U16 gain;
+
+//3 dls: Need to restore the mix engine metrics
+
+ /* calculate the gain multiplier */
+#ifdef _MAXIMIZER_ENABLED
+ if (pEASData->effectsModules[EAS_MODULE_MAXIMIZER].effect)
+ {
+ EAS_I32 temp;
+ temp = MaximizerProcess(pEASData->effectsModules[EAS_MODULE_MAXIMIZER].effectData, pEASData->pMixBuffer, pEASData->pMixBuffer, numSamples);
+ temp = (temp * pEASData->masterGain) >> 15;
+ if (temp > 32767)
+ gain = 32767;
+ else
+ gain = (EAS_U16) temp;
+ }
+ else
+ gain = (EAS_U16) pEASData->masterGain;
+#else
+ gain = (EAS_U16) pEASData->masterGain;
+#endif
+
+ /* Not using all the gain bits for now
+ * Reduce the input to the compressor by 6dB to prevent saturation
+ */
+#ifdef _COMPRESSOR_ENABLED
+ if (pEASData->effectsModules[EAS_MODULE_COMPRESSOR].effectData)
+ gain = gain >> 5;
+ else
+ gain = gain >> 4;
+#else
+ gain = gain >> 4;
+#endif
+
+ /* convert 32-bit mix buffer to 16-bit output format */
+#if (NUM_OUTPUT_CHANNELS == 2)
+ SynthMasterGain(pEASData->pMixBuffer, pEASData->pOutputAudioBuffer, gain, (EAS_U16) ((EAS_U16) numSamples * 2));
+#else
+ SynthMasterGain(pEASData->pMixBuffer, pEASData->pOutputAudioBuffer, gain, (EAS_U16) numSamples);
+#endif
+
+#ifdef _ENHANCER_ENABLED
+ /* enhancer effect */
+ if (pEASData->effectsModules[EAS_MODULE_ENHANCER].effectData)
+ (*pEASData->effectsModules[EAS_MODULE_ENHANCER].effect->pfProcess)
+ (pEASData->effectsModules[EAS_MODULE_ENHANCER].effectData,
+ pEASData->pOutputAudioBuffer,
+ pEASData->pOutputAudioBuffer,
+ numSamples);
+#endif
+
+#ifdef _GRAPHIC_EQ_ENABLED
+ /* graphic EQ effect */
+ if (pEASData->effectsModules[EAS_MODULE_GRAPHIC_EQ].effectData)
+ (*pEASData->effectsModules[EAS_MODULE_GRAPHIC_EQ].effect->pfProcess)
+ (pEASData->effectsModules[EAS_MODULE_GRAPHIC_EQ].effectData,
+ pEASData->pOutputAudioBuffer,
+ pEASData->pOutputAudioBuffer,
+ numSamples);
+#endif
+
+#ifdef _COMPRESSOR_ENABLED
+ /* compressor effect */
+ if (pEASData->effectsModules[EAS_MODULE_COMPRESSOR].effectData)
+ (*pEASData->effectsModules[EAS_MODULE_COMPRESSOR].effect->pfProcess)
+ (pEASData->effectsModules[EAS_MODULE_COMPRESSOR].effectData,
+ pEASData->pOutputAudioBuffer,
+ pEASData->pOutputAudioBuffer,
+ numSamples);
+#endif
+
+#ifdef _WOW_ENABLED
+ /* WOW requires a 32-bit buffer, borrow the mix buffer and
+ * pass it as the destination buffer
+ */
+ /*lint -e{740} temporarily passing a parameter through an existing I/F */
+ if (pEASData->effectsModules[EAS_MODULE_WOW].effectData)
+ (*pEASData->effectsModules[EAS_MODULE_WOW].effect->pfProcess)
+ (pEASData->effectsModules[EAS_MODULE_WOW].effectData,
+ pEASData->pOutputAudioBuffer,
+ (EAS_PCM*) pEASData->pMixBuffer,
+ numSamples);
+#endif
+
+#ifdef _TONECONTROLEQ_ENABLED
+ /* ToneControlEQ effect */
+ if (pEASData->effectsModules[EAS_MODULE_TONECONTROLEQ].effectData)
+ (*pEASData->effectsModules[EAS_MODULE_TONECONTROLEQ].effect->pfProcess)
+ (pEASData->effectsModules[EAS_MODULE_TONECONTROLEQ].effectData,
+ pEASData->pOutputAudioBuffer,
+ pEASData->pOutputAudioBuffer,
+ numSamples);
+#endif
+
+#ifdef _REVERB_ENABLED
+ /* Reverb effect */
+ if (pEASData->effectsModules[EAS_MODULE_REVERB].effectData)
+ (*pEASData->effectsModules[EAS_MODULE_REVERB].effect->pfProcess)
+ (pEASData->effectsModules[EAS_MODULE_REVERB].effectData,
+ pEASData->pOutputAudioBuffer,
+ pEASData->pOutputAudioBuffer,
+ numSamples);
+#endif
+
+#ifdef _CHORUS_ENABLED
+ /* Chorus effect */
+ if (pEASData->effectsModules[EAS_MODULE_CHORUS].effectData)
+ (*pEASData->effectsModules[EAS_MODULE_CHORUS].effect->pfProcess)
+ (pEASData->effectsModules[EAS_MODULE_CHORUS].effectData,
+ pEASData->pOutputAudioBuffer,
+ pEASData->pOutputAudioBuffer,
+ numSamples);
+#endif
+
+}
+
+#ifndef NATIVE_EAS_KERNEL
+/*----------------------------------------------------------------------------
+ * SynthMasterGain
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Mixes down audio from 32-bit to 16-bit target buffer
+ *
+ * Inputs:
+ *
+ * Outputs:
+ *
+ *----------------------------------------------------------------------------
+*/
+void SynthMasterGain (long *pInputBuffer, EAS_PCM *pOutputBuffer, EAS_U16 nGain, EAS_U16 numSamples) {
+
+ /* loop through the buffer */
+ while (numSamples--) {
+ long s;
+
+ /* read a sample from the input buffer and add some guard bits */
+ s = *pInputBuffer++;
+
+ /* add some guard bits */
+ /*lint -e{704} <avoid divide for performance>*/
+ s = s >> 7;
+
+ /* apply master gain */
+ s *= (long) nGain;
+
+ /* shift to lower 16-bits */
+ /*lint -e{704} <avoid divide for performance>*/
+ s = s >> 9;
+
+ /* saturate */
+ s = SATURATE(s);
+
+ *pOutputBuffer++ = (EAS_PCM)s;
+ }
+}
+#endif
+
+/*----------------------------------------------------------------------------
+ * EAS_MixEngineShutdown()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Shuts down effects modules and deallocates memory
+ *
+ * Inputs:
+ * pEASData - instance data
+ * pInstData - instance data handle
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_MixEngineShutdown (S_EAS_DATA *pEASData)
+{
+
+ /* check Configuration Module for static memory allocation */
+ if (!pEASData->staticMemoryModel && (pEASData->pMixBuffer != NULL))
+ EAS_HWFree(pEASData->hwInstData, pEASData->pMixBuffer);
+
+ return EAS_SUCCESS;
+}
+
+#ifdef UNIFIED_MIXER
+#ifndef NATIVE_MIX_STREAM
+/*----------------------------------------------------------------------------
+ * EAS_MixStream
+ *----------------------------------------------------------------------------
+ * Mix a 16-bit stream into a 32-bit buffer
+ *
+ * pInputBuffer 16-bit input buffer
+ * pMixBuffer 32-bit mix buffer
+ * numSamples number of samples to mix
+ * gainLeft initial gain left or mono
+ * gainRight initial gain right
+ * gainLeft left gain increment per sample
+ * gainRight right gain increment per sample
+ * flags bit 0 = stereo source
+ * bit 1 = stereo output
+ *----------------------------------------------------------------------------
+*/
+void EAS_MixStream (EAS_PCM *pInputBuffer, EAS_I32 *pMixBuffer, EAS_I32 numSamples, EAS_I32 gainLeft, EAS_I32 gainRight, EAS_I32 gainIncLeft, EAS_I32 gainIncRight, EAS_I32 flags)
+{
+ EAS_I32 temp;
+ EAS_INT src, dest;
+
+ /* NOTE: There are a lot of optimizations that can be done
+ * in the native implementations based on register
+ * availability, etc. For example, it may make sense to
+ * break this down into 8 separate routines:
+ *
+ * 1. Mono source to mono output
+ * 2. Mono source to stereo output
+ * 3. Stereo source to mono output
+ * 4. Stereo source to stereo output
+ * 5. Mono source to mono output - no gain change
+ * 6. Mono source to stereo output - no gain change
+ * 7. Stereo source to mono output - no gain change
+ * 8. Stereo source to stereo output - no gain change
+ *
+ * Other possibilities include loop unrolling, skipping
+ * a gain calculation every 2 or 4 samples, etc.
+ */
+
+ /* no gain change, use fast loops */
+ if ((gainIncLeft == 0) && (gainIncRight == 0))
+ {
+ switch (flags & (MIX_FLAGS_STEREO_SOURCE | MIX_FLAGS_STEREO_OUTPUT))
+ {
+ /* mono to mono */
+ case 0:
+ gainLeft >>= 15;
+ for (src = dest = 0; src < numSamples; src++, dest++)
+ {
+
+ pMixBuffer[dest] += (pInputBuffer[src] * gainLeft) >> NUM_MIXER_GUARD_BITS;
+ }
+ break;
+
+ /* mono to stereo */
+ case MIX_FLAGS_STEREO_OUTPUT:
+ gainLeft >>= 15;
+ gainRight >>= 15;
+ for (src = dest = 0; src < numSamples; src++, dest+=2)
+ {
+ pMixBuffer[dest] += (pInputBuffer[src] * gainLeft) >> NUM_MIXER_GUARD_BITS;
+ pMixBuffer[dest+1] += (pInputBuffer[src] * gainRight) >> NUM_MIXER_GUARD_BITS;
+ }
+ break;
+
+ /* stereo to mono */
+ case MIX_FLAGS_STEREO_SOURCE:
+ gainLeft >>= 15;
+ gainRight >>= 15;
+ for (src = dest = 0; src < numSamples; src+=2, dest++)
+ {
+ temp = (pInputBuffer[src] * gainLeft) >> NUM_MIXER_GUARD_BITS;
+ temp += ((pInputBuffer[src+1] * gainRight) >> NUM_MIXER_GUARD_BITS);
+ pMixBuffer[dest] += temp;
+ }
+ break;
+
+ /* stereo to stereo */
+ case MIX_FLAGS_STEREO_SOURCE | MIX_FLAGS_STEREO_OUTPUT:
+ gainLeft >>= 15;
+ gainRight >>= 15;
+ for (src = dest = 0; src < numSamples; src+=2, dest+=2)
+ {
+ pMixBuffer[dest] += (pInputBuffer[src] * gainLeft) >> NUM_MIXER_GUARD_BITS;
+ pMixBuffer[dest+1] += (pInputBuffer[src+1] * gainRight) >> NUM_MIXER_GUARD_BITS;
+ }
+ break;
+ }
+ }
+
+ /* gain change - do gain increment */
+ else
+ {
+ switch (flags & (MIX_FLAGS_STEREO_SOURCE | MIX_FLAGS_STEREO_OUTPUT))
+ {
+ /* mono to mono */
+ case 0:
+ for (src = dest = 0; src < numSamples; src++, dest++)
+ {
+ gainLeft += gainIncLeft;
+ pMixBuffer[dest] += (pInputBuffer[src] * (gainLeft >> 15)) >> NUM_MIXER_GUARD_BITS;
+ }
+ break;
+
+ /* mono to stereo */
+ case MIX_FLAGS_STEREO_OUTPUT:
+ for (src = dest = 0; src < numSamples; src++, dest+=2)
+ {
+ gainLeft += gainIncLeft;
+ gainRight += gainIncRight;
+ pMixBuffer[dest] += (pInputBuffer[src] * (gainLeft >> 15)) >> NUM_MIXER_GUARD_BITS;
+ pMixBuffer[dest+1] += (pInputBuffer[src] * (gainRight >> 15)) >> NUM_MIXER_GUARD_BITS;
+ }
+ break;
+
+ /* stereo to mono */
+ case MIX_FLAGS_STEREO_SOURCE:
+ for (src = dest = 0; src < numSamples; src+=2, dest++)
+ {
+ gainLeft += gainIncLeft;
+ gainRight += gainIncRight;
+ temp = (pInputBuffer[src] * (gainLeft >> 15)) >> NUM_MIXER_GUARD_BITS;
+ temp += ((pInputBuffer[src+1] * (gainRight >> 15)) >> NUM_MIXER_GUARD_BITS);
+ pMixBuffer[dest] += temp;
+ }
+ break;
+
+ /* stereo to stereo */
+ case MIX_FLAGS_STEREO_SOURCE | MIX_FLAGS_STEREO_OUTPUT:
+ for (src = dest = 0; src < numSamples; src+=2, dest+=2)
+ {
+ gainLeft += gainIncLeft;
+ gainRight += gainIncRight;
+ pMixBuffer[dest] += (pInputBuffer[src] * (gainLeft >> 15)) >> NUM_MIXER_GUARD_BITS;
+ pMixBuffer[dest+1] += (pInputBuffer[src+1] * (gainRight >> 15)) >> NUM_MIXER_GUARD_BITS;
+ }
+ break;
+ }
+ }
+}
+#endif
+#endif
+
diff --git a/arm-wt-22k/lib_src/eas_mixer.h b/arm-wt-22k/lib_src/eas_mixer.h
index 2ba2d3d..b2eb33b 100644
--- a/arm-wt-22k/lib_src/eas_mixer.h
+++ b/arm-wt-22k/lib_src/eas_mixer.h
@@ -1,13 +1,13 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_mixer.h
- *
- * Contents and purpose:
- * This file contains the critical components of the mix engine that
- * must be optimized for best performance.
- *
- * Copyright Sonic Network Inc. 2005
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_mixer.h
+ *
+ * Contents and purpose:
+ * This file contains the critical components of the mix engine that
+ * must be optimized for best performance.
+ *
+ * Copyright Sonic Network Inc. 2005
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,118 +20,118 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 706 $
- * $Date: 2007-05-31 17:22:51 -0700 (Thu, 31 May 2007) $
- *----------------------------------------------------------------------------
-*/
-
-#ifndef _EAS_MIXER_H
-#define _EAS_MIXER_H
-
-//3 dls: This module is in the midst of being converted from a synth
-//3 specific module to a general purpose mix engine
-
-#define MIX_FLAGS_STEREO_SOURCE 1
-#define MIX_FLAGS_STEREO_OUTPUT 2
-#define NUM_MIXER_GUARD_BITS 4
-
-#include "eas_effects.h"
-
-extern void SynthMasterGain( long *pInputBuffer, EAS_PCM *pOutputBuffer, EAS_U16 nGain, EAS_U16 nNumLoopSamples);
-
-/*----------------------------------------------------------------------------
- * EAS_MixEngineInit()
- *----------------------------------------------------------------------------
- * Purpose:
- * Prepares the mix engine for work, allocates buffers, locates effects modules, etc.
- *
- * Inputs:
- * pEASData - instance data
- * pInstData - pointer to variable to receive instance data handle
- *
- * Outputs:
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT EAS_MixEngineInit (EAS_DATA_HANDLE pEASData);
-
-/*----------------------------------------------------------------------------
- * EAS_MixEnginePrep()
- *----------------------------------------------------------------------------
- * Purpose:
- * Performs prep before synthesize a buffer of audio, such as clearing
- * audio buffers, etc.
- *
- * Inputs:
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-void EAS_MixEnginePrep (EAS_DATA_HANDLE pEASData, EAS_I32 nNumSamplesToAdd);
-
-/*----------------------------------------------------------------------------
- * EAS_MixEnginePost
- *----------------------------------------------------------------------------
- * Purpose:
- * This routine does the post-processing after all voices have been
- * synthesized. It calls any sweeteners and does the final mixdown to
- * the output buffer.
- *
- * Inputs:
- *
- * Outputs:
- *
- * Notes:
- *----------------------------------------------------------------------------
-*/
-void EAS_MixEnginePost (EAS_DATA_HANDLE pEASData, EAS_I32 nNumSamplesToAdd);
-
-/*----------------------------------------------------------------------------
- * EAS_MixEngineShutdown()
- *----------------------------------------------------------------------------
- * Purpose:
- * Shuts down effects modules and deallocates memory
- *
- * Inputs:
- * pEASData - instance data
- * pInstData - instance data handle
- *
- * Outputs:
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT EAS_MixEngineShutdown (EAS_DATA_HANDLE pEASData);
-
-#ifdef UNIFIED_MIXER
-/*----------------------------------------------------------------------------
- * EAS_MixStream
- *----------------------------------------------------------------------------
- * Mix a 16-bit stream into a 32-bit buffer
- *
- * pInputBuffer 16-bit input buffer
- * pMixBuffer 32-bit mix buffer
- * numSamples number of samples to mix
- * gainLeft initial gain left or mono
- * gainRight initial gain right
- * gainLeft left gain increment per sample
- * gainRight right gain increment per sample
- * flags bit 0 = stereo source
- * bit 1 = stereo output
- *----------------------------------------------------------------------------
-*/
-void EAS_MixStream (EAS_PCM *pInputBuffer, EAS_I32 *pMixBuffer, EAS_I32 numSamples, EAS_I32 gainLeft, EAS_I32 gainRight, EAS_I32 gainIncLeft, EAS_I32 gainIncRight, EAS_I32 flags);
-#endif
-
-#endif /* #ifndef _EAS_MIXER_H */
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 706 $
+ * $Date: 2007-05-31 17:22:51 -0700 (Thu, 31 May 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+#ifndef _EAS_MIXER_H
+#define _EAS_MIXER_H
+
+//3 dls: This module is in the midst of being converted from a synth
+//3 specific module to a general purpose mix engine
+
+#define MIX_FLAGS_STEREO_SOURCE 1
+#define MIX_FLAGS_STEREO_OUTPUT 2
+#define NUM_MIXER_GUARD_BITS 4
+
+#include "eas_effects.h"
+
+extern void SynthMasterGain( long *pInputBuffer, EAS_PCM *pOutputBuffer, EAS_U16 nGain, EAS_U16 nNumLoopSamples);
+
+/*----------------------------------------------------------------------------
+ * EAS_MixEngineInit()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Prepares the mix engine for work, allocates buffers, locates effects modules, etc.
+ *
+ * Inputs:
+ * pEASData - instance data
+ * pInstData - pointer to variable to receive instance data handle
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_MixEngineInit (EAS_DATA_HANDLE pEASData);
+
+/*----------------------------------------------------------------------------
+ * EAS_MixEnginePrep()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Performs prep before synthesize a buffer of audio, such as clearing
+ * audio buffers, etc.
+ *
+ * Inputs:
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+void EAS_MixEnginePrep (EAS_DATA_HANDLE pEASData, EAS_I32 nNumSamplesToAdd);
+
+/*----------------------------------------------------------------------------
+ * EAS_MixEnginePost
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * This routine does the post-processing after all voices have been
+ * synthesized. It calls any sweeteners and does the final mixdown to
+ * the output buffer.
+ *
+ * Inputs:
+ *
+ * Outputs:
+ *
+ * Notes:
+ *----------------------------------------------------------------------------
+*/
+void EAS_MixEnginePost (EAS_DATA_HANDLE pEASData, EAS_I32 nNumSamplesToAdd);
+
+/*----------------------------------------------------------------------------
+ * EAS_MixEngineShutdown()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Shuts down effects modules and deallocates memory
+ *
+ * Inputs:
+ * pEASData - instance data
+ * pInstData - instance data handle
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_MixEngineShutdown (EAS_DATA_HANDLE pEASData);
+
+#ifdef UNIFIED_MIXER
+/*----------------------------------------------------------------------------
+ * EAS_MixStream
+ *----------------------------------------------------------------------------
+ * Mix a 16-bit stream into a 32-bit buffer
+ *
+ * pInputBuffer 16-bit input buffer
+ * pMixBuffer 32-bit mix buffer
+ * numSamples number of samples to mix
+ * gainLeft initial gain left or mono
+ * gainRight initial gain right
+ * gainLeft left gain increment per sample
+ * gainRight right gain increment per sample
+ * flags bit 0 = stereo source
+ * bit 1 = stereo output
+ *----------------------------------------------------------------------------
+*/
+void EAS_MixStream (EAS_PCM *pInputBuffer, EAS_I32 *pMixBuffer, EAS_I32 numSamples, EAS_I32 gainLeft, EAS_I32 gainRight, EAS_I32 gainIncLeft, EAS_I32 gainIncRight, EAS_I32 flags);
+#endif
+
+#endif /* #ifndef _EAS_MIXER_H */
+
diff --git a/arm-wt-22k/lib_src/eas_ota.c b/arm-wt-22k/lib_src/eas_ota.c
index fb81d62..5bc9062 100644
--- a/arm-wt-22k/lib_src/eas_ota.c
+++ b/arm-wt-22k/lib_src/eas_ota.c
@@ -1,12 +1,12 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_ota.c
- *
- * Contents and purpose:
- * OTA parser
- *
- * Copyright Sonic Network Inc. 2005
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_ota.c
+ *
+ * Contents and purpose:
+ * OTA parser
+ *
+ * Copyright Sonic Network Inc. 2005
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,1059 +19,1059 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 795 $
- * $Date: 2007-08-01 00:14:45 -0700 (Wed, 01 Aug 2007) $
- *----------------------------------------------------------------------------
-*/
-
-#include "eas_data.h"
-#include "eas_miditypes.h"
-#include "eas_parser.h"
-#include "eas_report.h"
-#include "eas_host.h"
-#include "eas_midi.h"
-#include "eas_config.h"
-#include "eas_vm_protos.h"
-#include "eas_otadata.h"
-
-/* increase gain for mono ringtones */
-#define OTA_GAIN_OFFSET 8
-
-/* file definitions */
-#define OTA_RINGTONE 0x25
-#define OTA_SOUND 0x1d
-#define OTA_UNICODE 0x22
-
-/* song type definitions */
-#define OTA_BASIC_SONG_TYPE 0x01
-#define OTA_TEMPORARY_SONG_TYPE 0x02
-
-/* instruction ID coding */
-#define OTA_PATTERN_HEADER_ID 0x00
-#define OTA_NOTE_INST_ID 0x01
-#define OTA_SCALE_INST_ID 0x02
-#define OTA_STYLE_INST_ID 0x03
-#define OTA_TEMPO_INST_ID 0x04
-#define OTA_VOLUME_INST_ID 0x05
-
-/* note durations */
-#define OTA_NORMAL_DURATION 0x00
-#define OTA_DOTTED_NOTE 0x01
-#define OTA_DOUBLE_DOTTED_NOTE 0x02
-#define OTA_TRIPLET_NOTE 0x03
-
-/* loop count value for infinite loop */
-#define OTA_INFINITE_LOOP 0x0f
-
-/* length of 32nd note in 1/256ths of a msec for 63 BPM tempo */
-#define DEFAULT_TICK_CONV 30476
-
-/* default channel and program for OTA playback */
-#define OTA_CHANNEL 0
-#define OTA_PROGRAM 80
-#define OTA_VEL_MUL 4
-#define OTA_VEL_OFS 67
-#define OTA_VEL_DEFAULT 95
-
-/* multiplier for fixed point triplet conversion */
-#define TRIPLET_MULTIPLIER 683
-#define TRIPLET_SHIFT 10
-
-/* local prototypes */
-static EAS_RESULT OTA_CheckFileType (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle, EAS_VOID_PTR *ppHandle, EAS_I32 offset);
-static EAS_RESULT OTA_Prepare (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
-static EAS_RESULT OTA_Time (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_U32 *pTime);
-static EAS_RESULT OTA_Event (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_INT parserMode);
-static EAS_RESULT OTA_State (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_STATE *pState);
-static EAS_RESULT OTA_Close (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
-static EAS_RESULT OTA_Reset (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
-static EAS_RESULT OTA_Pause (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
-static EAS_RESULT OTA_Resume (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
-static EAS_RESULT OTA_SetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value);
-static EAS_RESULT OTA_GetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue);
-static EAS_RESULT OTA_ParseHeader (S_EAS_DATA *pEASData, S_OTA_DATA* pData);
-static EAS_RESULT OTA_FetchBitField (EAS_HW_DATA_HANDLE hwInstData, S_OTA_DATA *pData, EAS_I32 numBits, EAS_U8 *pValue);
-static EAS_RESULT OTA_SavePosition (EAS_HW_DATA_HANDLE hwInstData, S_OTA_DATA *pData, S_OTA_LOC *pLoc);
-static EAS_RESULT OTA_RestorePosition (EAS_HW_DATA_HANDLE hwInstData, S_OTA_DATA *pData, S_OTA_LOC *pLoc);
-
-
-/*----------------------------------------------------------------------------
- *
- * EAS_OTA_Parser
- *
- * This structure contains the functional interface for the OTA parser
- *----------------------------------------------------------------------------
-*/
-const S_FILE_PARSER_INTERFACE EAS_OTA_Parser =
-{
- OTA_CheckFileType,
- OTA_Prepare,
- OTA_Time,
- OTA_Event,
- OTA_State,
- OTA_Close,
- OTA_Reset,
- OTA_Pause,
- OTA_Resume,
- NULL,
- OTA_SetData,
- OTA_GetData,
- NULL
-};
-
-/*----------------------------------------------------------------------------
- *
- * bpmTable
- *
- * BPM conversion table. Converts bpm values to 256ths of a millisecond for a 32nd note
- *----------------------------------------------------------------------------
-*/
-static const EAS_U32 bpmTable[32] =
-{
- 76800, 68571, 61935, 54857,
- 48000, 42667, 38400, 34286,
- 30476, 27429, 24000, 21333,
- 19200, 17143, 15360, 13714,
- 12000, 10667, 9600, 8533,
- 7680, 6737, 6000, 5408,
- 4800, 4267, 3840, 3398,
- 3024, 2685, 2400, 2133
-};
-
-/*----------------------------------------------------------------------------
- * OTA_CheckFileType()
- *----------------------------------------------------------------------------
- * Purpose:
- * Check the file type to see if we can parse it
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT OTA_CheckFileType (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle, EAS_VOID_PTR *ppHandle, EAS_I32 offset)
-{
- S_OTA_DATA* pData;
- EAS_RESULT result;
- EAS_INT cmdLen;
- EAS_INT state;
- EAS_U8 temp;
-
- /* read the first byte, should be command length */
- *ppHandle = NULL;
- if ((result = EAS_HWGetByte(pEASData->hwInstData, fileHandle, &temp)) != EAS_SUCCESS)
- return result;
-
- /* read all the commands */
- cmdLen = temp;
- state = 0;
- while (cmdLen--)
- {
-
- /* read the command, upper 7 bits */
- if ((result = EAS_HWGetByte(pEASData->hwInstData, fileHandle, &temp)) != EAS_SUCCESS)
- return result;
- temp = temp >> 1;
-
- if (state == 0)
- {
- if (temp != OTA_RINGTONE)
- break;
- state++;
- }
- else
- {
-
- if (temp == OTA_SOUND)
- {
-
- /* check for static memory allocation */
- if (pEASData->staticMemoryModel)
- pData = EAS_CMEnumData(EAS_CM_OTA_DATA);
- else
- pData = EAS_HWMalloc(pEASData->hwInstData, sizeof(S_OTA_DATA));
- if (!pData)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Malloc failed in OTA_Prepare\n"); */ }
- return EAS_ERROR_MALLOC_FAILED;
- }
- EAS_HWMemSet(pData, 0, sizeof(S_OTA_DATA));
-
- /* return a pointer to the instance data */
- pData->fileHandle = fileHandle;
- pData->fileOffset = offset;
- pData->state = EAS_STATE_OPEN;
- *ppHandle = pData;
- break;
- }
-
- if (temp != OTA_UNICODE)
- break;
- }
- }
-
- /* not recognized */
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * OTA_Prepare()
- *----------------------------------------------------------------------------
- * Purpose:
- * Prepare to parse the file. Allocates instance data (or uses static allocation for
- * static memory model).
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT OTA_Prepare (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
-{
- S_OTA_DATA* pData;
- EAS_RESULT result;
-
- /* check for valid state */
- pData = (S_OTA_DATA*) pInstData;
- if (pData->state != EAS_STATE_OPEN)
- return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
-
- /* instantiate a synthesizer */
- if ((result = VMInitMIDI(pEASData, &pData->pSynth)) != EAS_SUCCESS)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "VMInitMIDI returned %d\n", result); */ }
- return result;
- }
-
- pData->state = EAS_STATE_ERROR;
- if ((result = OTA_ParseHeader(pEASData, pData)) != EAS_SUCCESS)
- return result;
-
- pData->state = EAS_STATE_READY;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * OTA_Time()
- *----------------------------------------------------------------------------
- * Purpose:
- * Returns the time of the next event in msecs
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- * pTime - pointer to variable to hold time of next event (in msecs)
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, pEASData) common decoder interface - pEASData not used */
-static EAS_RESULT OTA_Time (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_U32 *pTime)
-{
- S_OTA_DATA *pData;
-
- pData = (S_OTA_DATA*) pInstData;
-
- /* return time in milliseconds */
- /*lint -e{704} use shift instead of division */
- *pTime = pData->time >> 8;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * OTA_Event()
- *----------------------------------------------------------------------------
- * Purpose:
- * Parse the next event in the file
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT OTA_Event (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_INT parserMode)
-{
- S_OTA_DATA* pData;
- EAS_RESULT result;
- EAS_U32 duration;
- EAS_U8 temp;
-
- pData = (S_OTA_DATA*) pInstData;
- if (pData->state >= EAS_STATE_OPEN)
- return EAS_SUCCESS;
-
- /* initialize MIDI channel when the track starts playing */
- if (pData->time == 0)
- {
- /* set program to square lead */
- if (parserMode != eParserModeMetaData)
- VMProgramChange(pEASData->pVoiceMgr, pData->pSynth, OTA_CHANNEL, OTA_PROGRAM);
-
- /* set channel volume to max */
- if (parserMode != eParserModeMetaData)
- VMControlChange(pEASData->pVoiceMgr, pData->pSynth, OTA_CHANNEL, 7, 127);
- }
-
- /* check for end of note */
- if (pData->note)
- {
- /* stop the note */
- VMStopNote(pEASData->pVoiceMgr, pData->pSynth, OTA_CHANNEL, pData->note, 0);
- pData->note = 0;
-
- /* check for rest between notes */
- if (pData->restTicks)
- {
- pData->time += (EAS_I32) pData->restTicks;
- pData->restTicks = 0;
- return EAS_SUCCESS;
- }
- }
-
- /* if not in a pattern, read the pattern header */
- while (pData->current.patternLen == 0)
- {
-
- /* check for loop - don't do infinite loops when locating */
- if (pData->loopCount && ((parserMode == eParserModePlay) || (pData->loopCount != OTA_INFINITE_LOOP)))
- {
- /* if not infinite loop, decrement loop count */
- if (pData->loopCount != OTA_INFINITE_LOOP)
- pData->loopCount--;
-
- /* back to start of pattern*/
- if ((result = OTA_RestorePosition(pEASData->hwInstData, pData, &pData->patterns[pData->currentPattern])) != EAS_SUCCESS)
- return result;
- }
-
- /* if no previous position to restore, continue forward */
- else if (pData->restore.fileOffset < 0)
- {
-
- /* check for end of song */
- if (pData->numPatterns == 0)
- {
- pData->state = EAS_STATE_STOPPING;
- VMReleaseAllVoices(pEASData->pVoiceMgr, pData->pSynth);
- return EAS_SUCCESS;
- }
-
- /* read the next pattern header */
- if ((result = OTA_FetchBitField(pEASData->hwInstData, pData, 3, &temp)) != EAS_SUCCESS)
- return result;
- if (temp != OTA_PATTERN_HEADER_ID)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Expected OTA pattern header\n"); */ }
- return EAS_ERROR_FILE_FORMAT;
- }
-
- /* get the pattern ID */
- if ((result = OTA_FetchBitField(pEASData->hwInstData, pData, 2, &pData->currentPattern)) != EAS_SUCCESS)
- return result;
-
- /* get the loop count */
- if ((result = OTA_FetchBitField(pEASData->hwInstData, pData, 4, &pData->loopCount)) != EAS_SUCCESS)
- return result;
-
- /* get the pattern length */
- if ((result = OTA_FetchBitField(pEASData->hwInstData, pData, 8, &pData->current.patternLen)) != EAS_SUCCESS)
- return result;
-
- /* if pattern definition, save the current position */
- if (pData->current.patternLen)
- {
- if ((result = OTA_SavePosition(pEASData->hwInstData, pData, &pData->patterns[pData->currentPattern])) != EAS_SUCCESS)
- return result;
- }
-
- /* if pattern length is zero, repeat a previous pattern */
- else
- {
- /* make sure it's a valid pattern */
- if (pData->patterns[pData->currentPattern].fileOffset < 0)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "OTA pattern error, invalid pattern specified\n"); */ }
- return EAS_ERROR_FILE_FORMAT;
- }
-
- /* save current position and data */
- if ((result = OTA_SavePosition(pEASData->hwInstData, pData, &pData->restore)) != EAS_SUCCESS)
- return result;
-
- /* seek to the pattern in the file */
- if ((result = OTA_RestorePosition(pEASData->hwInstData, pData, &pData->patterns[pData->currentPattern])) != EAS_SUCCESS)
- return result;
- }
-
- /* decrement pattern count */
- pData->numPatterns--;
- }
-
- /* restore previous position */
- else
- {
- if ((result = OTA_RestorePosition(pEASData->hwInstData, pData, &pData->restore)) != EAS_SUCCESS)
- return result;
- }
- }
-
- /* get the next event */
- if ((result = OTA_FetchBitField(pEASData->hwInstData, pData, 3, &temp)) != EAS_SUCCESS)
- return result;
-
- switch (temp)
- {
- case OTA_NOTE_INST_ID:
- /* fetch note value */
- if ((result = OTA_FetchBitField(pEASData->hwInstData, pData, 4, &pData->note)) != EAS_SUCCESS)
- return result;
-
- /* fetch note duration */
- if ((result = OTA_FetchBitField(pEASData->hwInstData, pData, 3, &temp)) != EAS_SUCCESS)
- return result;
- duration = pData->tick * (0x20 >> temp);
-
- /* fetch note duration modifier */
- if ((result = OTA_FetchBitField(pEASData->hwInstData, pData, 2, &temp)) != EAS_SUCCESS)
- return result;
- switch (temp)
- {
- case OTA_NORMAL_DURATION:
- break;
-
- case OTA_DOTTED_NOTE:
- duration += duration >> 1;
- break;
-
- case OTA_DOUBLE_DOTTED_NOTE:
- duration += (duration >> 1) + (duration >> 2);
- break;
-
- case OTA_TRIPLET_NOTE:
- duration = (duration * TRIPLET_MULTIPLIER) >> TRIPLET_SHIFT;
- break;
-
- default:
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Unrecognized note duration ignored\n"); */ }
- break;
- }
-
- /* check for note */
- if (pData->note)
- {
-
- /* determine note length based on style */
- switch (pData->style)
- {
- case 0:
- pData->restTicks = duration >> 4;
- break;
- case 1:
- pData->restTicks = 0;
- break;
- case 2:
- pData->restTicks = duration >> 1;
- break;
- default:
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Unrecognized note style ignored\n"); */ }
- }
-
- /* add octave */
- pData->note += pData->octave;
- if (parserMode == eParserModePlay)
- VMStartNote(pEASData->pVoiceMgr, pData->pSynth, OTA_CHANNEL, pData->note, pData->velocity);
- pData->time += (EAS_I32) duration - (EAS_I32) pData->restTicks;
- }
-
- /* this is a rest */
- else
- pData->time += (EAS_I32) duration;
- break;
-
- case OTA_SCALE_INST_ID:
- /* fetch octave */
- if ((result = OTA_FetchBitField(pEASData->hwInstData, pData, 2, &temp)) != EAS_SUCCESS)
- return result;
- pData->octave = (EAS_U8) (temp * 12 + 59);
- break;
-
- case OTA_STYLE_INST_ID:
- /* fetch note style */
- if ((result = OTA_FetchBitField(pEASData->hwInstData, pData, 2, &pData->style)) != EAS_SUCCESS)
- return result;
- break;
-
- case OTA_TEMPO_INST_ID:
- /* fetch tempo */
- if ((result = OTA_FetchBitField(pEASData->hwInstData, pData, 5, &temp)) != EAS_SUCCESS)
- return result;
- pData->tick = bpmTable[temp];
- break;
-
- case OTA_VOLUME_INST_ID:
- /* fetch volume */
- if ((result = OTA_FetchBitField(pEASData->hwInstData, pData, 4, &temp)) != EAS_SUCCESS)
- return result;
- pData->velocity = temp ? (EAS_U8) (temp * OTA_VEL_MUL + OTA_VEL_OFS) : 0;
- break;
-
- default:
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Unexpected instruction ID in OTA stream\n"); */ }
- return EAS_ERROR_FILE_FORMAT;
- }
-
- /* decrement pattern length */
- pData->current.patternLen--;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * OTA_State()
- *----------------------------------------------------------------------------
- * Purpose:
- * Returns the current state of the stream
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- * pState - pointer to variable to store state
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, pEASData) common decoder interface - pEASData not used */
-static EAS_RESULT OTA_State (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 *pState)
-{
- S_OTA_DATA* pData;
-
- /* establish pointer to instance data */
- pData = (S_OTA_DATA*) pInstData;
-
- /* if stopping, check to see if synth voices are active */
- if (pData->state == EAS_STATE_STOPPING)
- {
- if (VMActiveVoices(pData->pSynth) == 0)
- pData->state = EAS_STATE_STOPPED;
- }
-
- if (pData->state == EAS_STATE_PAUSING)
- {
- if (VMActiveVoices(pData->pSynth) == 0)
- pData->state = EAS_STATE_PAUSED;
- }
-
- /* return current state */
- *pState = pData->state;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * OTA_Close()
- *----------------------------------------------------------------------------
- * Purpose:
- * Close the file and clean up
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT OTA_Close (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
-{
- S_OTA_DATA* pData;
- EAS_RESULT result;
-
- pData = (S_OTA_DATA*) pInstData;
-
- /* close the file */
- if ((result = EAS_HWCloseFile(pEASData->hwInstData, pData->fileHandle)) != EAS_SUCCESS)
- return result;
-
- /* free the synth */
- if (pData->pSynth != NULL)
- VMMIDIShutdown(pEASData, pData->pSynth);
-
- /* if using dynamic memory, free it */
- if (!pEASData->staticMemoryModel)
- EAS_HWFree(pEASData->hwInstData, pData);
-
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * OTA_Reset()
- *----------------------------------------------------------------------------
- * Purpose:
- * Reset the sequencer. Used for locating backwards in the file.
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT OTA_Reset (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
-{
- S_OTA_DATA* pData;
- EAS_RESULT result;
-
- pData = (S_OTA_DATA*) pInstData;
-
- /* reset the synth */
- VMReset(pEASData->pVoiceMgr, pData->pSynth, EAS_TRUE);
- pData->note = 0;
-
- /* reset file position and re-parse header */
- pData->state = EAS_STATE_ERROR;
- if ((result = OTA_ParseHeader (pEASData, pData)) != EAS_SUCCESS)
- return result;
-
- pData->state = EAS_STATE_READY;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * OTA_Pause()
- *----------------------------------------------------------------------------
- * Purpose:
- * Pauses the sequencer. Mutes all voices and sets state to pause.
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT OTA_Pause (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
-{
- S_OTA_DATA *pData;
-
- /* can't pause a stopped stream */
- pData = (S_OTA_DATA*) pInstData;
- if (pData->state == EAS_STATE_STOPPED)
- return EAS_ERROR_ALREADY_STOPPED;
-
- /* mute the synthesizer */
- VMMuteAllVoices(pEASData->pVoiceMgr, pData->pSynth);
- pData->state = EAS_STATE_PAUSING;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * OTA_Resume()
- *----------------------------------------------------------------------------
- * Purpose:
- * Resume playing after a pause, sets state back to playing.
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, pEASData) common decoder interface - pEASData not used */
-static EAS_RESULT OTA_Resume (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
-{
- S_OTA_DATA *pData;
-
- /* can't resume a stopped stream */
- pData = (S_OTA_DATA*) pInstData;
- if (pData->state == EAS_STATE_STOPPED)
- return EAS_ERROR_ALREADY_STOPPED;
-
- /* nothing to do but resume playback */
- pData->state = EAS_STATE_PLAY;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * OTA_SetData()
- *----------------------------------------------------------------------------
- * Purpose:
- * Return file type
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, pEASData) common decoder interface - pEASData not used */
-static EAS_RESULT OTA_SetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value)
-{
- S_OTA_DATA *pData;
-
- pData = (S_OTA_DATA *) pInstData;
- switch (param)
- {
-
- /* set metadata callback */
- case PARSER_DATA_METADATA_CB:
- EAS_HWMemCpy(&pData->metadata, (void*) value, sizeof(S_METADATA_CB));
- break;
-
- default:
- return EAS_ERROR_INVALID_PARAMETER;
- }
-
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * OTA_GetData()
- *----------------------------------------------------------------------------
- * Purpose:
- * Return file type
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, pEASData) common decoder interface - pEASData not used */
-static EAS_RESULT OTA_GetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue)
-{
- S_OTA_DATA *pData;
-
- pData = (S_OTA_DATA*) pInstData;
- switch (param)
- {
- /* return file type as OTA */
- case PARSER_DATA_FILE_TYPE:
- *pValue = EAS_FILE_OTA;
- break;
-
-#if 0
- /* set transposition */
- case PARSER_DATA_TRANSPOSITION:
- *pValue = pData->transposition;
- break;
-#endif
-
- case PARSER_DATA_SYNTH_HANDLE:
- *pValue = (EAS_I32) pData->pSynth;
- break;
-
- case PARSER_DATA_GAIN_OFFSET:
- *pValue = OTA_GAIN_OFFSET;
- break;
-
- default:
- return EAS_ERROR_INVALID_PARAMETER;
- }
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * OTA_ParseHeader()
- *----------------------------------------------------------------------------
- * Purpose:
- * Prepare to parse the file. Allocates instance data (or uses static allocation for
- * static memory model).
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT OTA_ParseHeader (S_EAS_DATA *pEASData, S_OTA_DATA* pData)
-{
- EAS_RESULT result;
- EAS_INT i;
- EAS_INT state;
- EAS_U8 temp;
- EAS_U8 titleLen;
-
- /* initialize some data */
- pData->flags = 0;
- pData->time = 0;
- pData->tick = DEFAULT_TICK_CONV;
- pData->patterns[0].fileOffset = pData->patterns[1].fileOffset =
- pData->patterns[2].fileOffset = pData->patterns[3].fileOffset = -1;
- pData->current.bitCount = 0;
- pData->current.patternLen = 0;
- pData->loopCount = 0;
- pData->restore.fileOffset = -1;
- pData->note = 0;
- pData->restTicks = 0;
- pData->velocity = OTA_VEL_DEFAULT;
- pData->style = 0;
- pData->octave = 59;
-
- /* seek to start of data */
- if ((result = EAS_HWFileSeek(pEASData->hwInstData, pData->fileHandle, pData->fileOffset)) != EAS_SUCCESS)
- return result;
-
- /* read the first byte, should be command length */
- if ((result = EAS_HWGetByte(pEASData->hwInstData, pData->fileHandle, &temp)) != EAS_SUCCESS)
- return result;
-
- /* read all the commands */
- i = temp;
- state = 0;
- while (i--)
- {
-
- /* fetch command, always starts on byte boundary */
- pData->current.bitCount = 0;
- if ((result = OTA_FetchBitField(pEASData->hwInstData, pData, 7, &temp)) != EAS_SUCCESS)
- return result;
-
- if (state == 0)
- {
- if (temp != OTA_RINGTONE)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Expected OTA Ring Tone Programming type\n"); */ }
- return EAS_ERROR_FILE_FORMAT;
- }
- state++;
- }
- else
- {
-
- if (temp == OTA_SOUND)
- break;
-
- if (temp == OTA_UNICODE)
- pData->flags |= OTA_FLAGS_UNICODE;
- else
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Expected OTA Sound or Unicode type\n"); */ }
- return EAS_ERROR_FILE_FORMAT;
- }
- }
- }
-
- /* get song type */
- if ((result = OTA_FetchBitField(pEASData->hwInstData, pData, 3, &temp)) != EAS_SUCCESS)
- return result;
-
- /* check for basic song type */
- if (temp == OTA_BASIC_SONG_TYPE)
- {
- /* fetch title length */
- if ((result = OTA_FetchBitField(pEASData->hwInstData, pData, 4, &titleLen)) != EAS_SUCCESS)
- return result;
-
- /* if unicode, double the length */
- if (pData->flags & OTA_FLAGS_UNICODE)
- titleLen = (EAS_U8) (titleLen << 1);
-
- /* zero the metadata buffer */
- if (pData->metadata.buffer)
- EAS_HWMemSet(pData->metadata.buffer, 0, pData->metadata.bufferSize);
-
- /* read the song title */
- for (i = 0; i < titleLen; i++)
- {
- /* fetch character */
- if ((result = OTA_FetchBitField(pEASData->hwInstData, pData, 8, &temp)) != EAS_SUCCESS)
- return result;
-
- /* check for metadata callback */
- if (pData->metadata.callback)
- {
- if (i < (pData->metadata.bufferSize - 1))
- pData->metadata.buffer[i] = (char) temp;
- }
- }
-
- /* if host has registered callback, call it now */
- if (pData->metadata.callback)
- (*pData->metadata.callback)(EAS_METADATA_TITLE, pData->metadata.buffer, pData->metadata.pUserData);
- }
-
- /* must be temporary song */
- else if (temp != OTA_TEMPORARY_SONG_TYPE)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Expected OTA basic or temporary song type\n"); */ }
- return EAS_ERROR_FILE_FORMAT;
- }
-
- /* get the song length */
- if ((result = OTA_FetchBitField(pEASData->hwInstData, pData, 8, &pData->numPatterns)) != EAS_SUCCESS)
- return result;
-
- /* sanity check */
- if (pData->numPatterns == 0)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "OTA number of patterns is zero\n"); */ }
- return EAS_ERROR_FILE_FORMAT;
- }
-
- /* at start of first pattern */
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * OTA_FetchBitField()
- *----------------------------------------------------------------------------
- * Purpose:
- * Fetch a specified number of bits from the input stream
- *
- * Inputs:
- *
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT OTA_FetchBitField (EAS_HW_DATA_HANDLE hwInstData, S_OTA_DATA *pData, EAS_I32 numBits, EAS_U8 *pValue)
-{
- EAS_RESULT result;
- EAS_I32 bitsLeft;
- EAS_U8 value;
-
- value = 0;
-
- /* do we have enough bits? */
- bitsLeft = pData->current.bitCount - numBits;
-
- /* not enough bits, assemble them from 2 characters */
- if (bitsLeft < 0)
- {
- /* grab the remaining bits from the previous byte */
- if (pData->current.bitCount)
- /*lint -e{504,734} this is a legitimate shift operation */
- value = pData->current.dataByte << -bitsLeft;
-
- /* read the next byte */
- if ((result = EAS_HWGetByte(hwInstData, pData->fileHandle, &pData->current.dataByte)) != EAS_SUCCESS)
- return result;
- bitsLeft += 8;
- }
-
- /* more bits than needed? */
- if (bitsLeft > 0)
- {
- value |= pData->current.dataByte >> bitsLeft;
- pData->current.bitCount = (EAS_U8) bitsLeft;
- pData->current.dataByte = pData->current.dataByte & (0xff >> (8 - bitsLeft));
- }
-
- /* exactly the right number of bits */
- else
- {
- value |= pData->current.dataByte;
- pData->current.bitCount = 0;
- }
-
- *pValue = value;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * OTA_SavePosition()
- *----------------------------------------------------------------------------
- * Purpose:
- *
- *
- * Inputs:
- *
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT OTA_SavePosition (EAS_HW_DATA_HANDLE hwInstData, S_OTA_DATA *pData, S_OTA_LOC *pLoc)
-{
- EAS_HWMemCpy(pLoc, &pData->current, sizeof(S_OTA_LOC));
- return EAS_HWFilePos(hwInstData, pData->fileHandle, &pLoc->fileOffset);
-}
-
-/*----------------------------------------------------------------------------
- * OTA_RestorePosition()
- *----------------------------------------------------------------------------
- * Purpose:
- *
- *
- * Inputs:
- *
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT OTA_RestorePosition (EAS_HW_DATA_HANDLE hwInstData, S_OTA_DATA *pData, S_OTA_LOC *pLoc)
-{
- EAS_HWMemCpy(&pData->current, pLoc, sizeof(S_OTA_LOC));
- pData->restore.fileOffset = -1;
- return EAS_HWFileSeek(hwInstData, pData->fileHandle, pLoc->fileOffset);
-}
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 795 $
+ * $Date: 2007-08-01 00:14:45 -0700 (Wed, 01 Aug 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+#include "eas_data.h"
+#include "eas_miditypes.h"
+#include "eas_parser.h"
+#include "eas_report.h"
+#include "eas_host.h"
+#include "eas_midi.h"
+#include "eas_config.h"
+#include "eas_vm_protos.h"
+#include "eas_otadata.h"
+
+/* increase gain for mono ringtones */
+#define OTA_GAIN_OFFSET 8
+
+/* file definitions */
+#define OTA_RINGTONE 0x25
+#define OTA_SOUND 0x1d
+#define OTA_UNICODE 0x22
+
+/* song type definitions */
+#define OTA_BASIC_SONG_TYPE 0x01
+#define OTA_TEMPORARY_SONG_TYPE 0x02
+
+/* instruction ID coding */
+#define OTA_PATTERN_HEADER_ID 0x00
+#define OTA_NOTE_INST_ID 0x01
+#define OTA_SCALE_INST_ID 0x02
+#define OTA_STYLE_INST_ID 0x03
+#define OTA_TEMPO_INST_ID 0x04
+#define OTA_VOLUME_INST_ID 0x05
+
+/* note durations */
+#define OTA_NORMAL_DURATION 0x00
+#define OTA_DOTTED_NOTE 0x01
+#define OTA_DOUBLE_DOTTED_NOTE 0x02
+#define OTA_TRIPLET_NOTE 0x03
+
+/* loop count value for infinite loop */
+#define OTA_INFINITE_LOOP 0x0f
+
+/* length of 32nd note in 1/256ths of a msec for 63 BPM tempo */
+#define DEFAULT_TICK_CONV 30476
+
+/* default channel and program for OTA playback */
+#define OTA_CHANNEL 0
+#define OTA_PROGRAM 80
+#define OTA_VEL_MUL 4
+#define OTA_VEL_OFS 67
+#define OTA_VEL_DEFAULT 95
+
+/* multiplier for fixed point triplet conversion */
+#define TRIPLET_MULTIPLIER 683
+#define TRIPLET_SHIFT 10
+
+/* local prototypes */
+static EAS_RESULT OTA_CheckFileType (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle, EAS_VOID_PTR *ppHandle, EAS_I32 offset);
+static EAS_RESULT OTA_Prepare (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
+static EAS_RESULT OTA_Time (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_U32 *pTime);
+static EAS_RESULT OTA_Event (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_INT parserMode);
+static EAS_RESULT OTA_State (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_STATE *pState);
+static EAS_RESULT OTA_Close (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
+static EAS_RESULT OTA_Reset (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
+static EAS_RESULT OTA_Pause (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
+static EAS_RESULT OTA_Resume (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
+static EAS_RESULT OTA_SetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value);
+static EAS_RESULT OTA_GetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue);
+static EAS_RESULT OTA_ParseHeader (S_EAS_DATA *pEASData, S_OTA_DATA* pData);
+static EAS_RESULT OTA_FetchBitField (EAS_HW_DATA_HANDLE hwInstData, S_OTA_DATA *pData, EAS_I32 numBits, EAS_U8 *pValue);
+static EAS_RESULT OTA_SavePosition (EAS_HW_DATA_HANDLE hwInstData, S_OTA_DATA *pData, S_OTA_LOC *pLoc);
+static EAS_RESULT OTA_RestorePosition (EAS_HW_DATA_HANDLE hwInstData, S_OTA_DATA *pData, S_OTA_LOC *pLoc);
+
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_OTA_Parser
+ *
+ * This structure contains the functional interface for the OTA parser
+ *----------------------------------------------------------------------------
+*/
+const S_FILE_PARSER_INTERFACE EAS_OTA_Parser =
+{
+ OTA_CheckFileType,
+ OTA_Prepare,
+ OTA_Time,
+ OTA_Event,
+ OTA_State,
+ OTA_Close,
+ OTA_Reset,
+ OTA_Pause,
+ OTA_Resume,
+ NULL,
+ OTA_SetData,
+ OTA_GetData,
+ NULL
+};
+
+/*----------------------------------------------------------------------------
+ *
+ * bpmTable
+ *
+ * BPM conversion table. Converts bpm values to 256ths of a millisecond for a 32nd note
+ *----------------------------------------------------------------------------
+*/
+static const EAS_U32 bpmTable[32] =
+{
+ 76800, 68571, 61935, 54857,
+ 48000, 42667, 38400, 34286,
+ 30476, 27429, 24000, 21333,
+ 19200, 17143, 15360, 13714,
+ 12000, 10667, 9600, 8533,
+ 7680, 6737, 6000, 5408,
+ 4800, 4267, 3840, 3398,
+ 3024, 2685, 2400, 2133
+};
+
+/*----------------------------------------------------------------------------
+ * OTA_CheckFileType()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Check the file type to see if we can parse it
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT OTA_CheckFileType (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle, EAS_VOID_PTR *ppHandle, EAS_I32 offset)
+{
+ S_OTA_DATA* pData;
+ EAS_RESULT result;
+ EAS_INT cmdLen;
+ EAS_INT state;
+ EAS_U8 temp;
+
+ /* read the first byte, should be command length */
+ *ppHandle = NULL;
+ if ((result = EAS_HWGetByte(pEASData->hwInstData, fileHandle, &temp)) != EAS_SUCCESS)
+ return result;
+
+ /* read all the commands */
+ cmdLen = temp;
+ state = 0;
+ while (cmdLen--)
+ {
+
+ /* read the command, upper 7 bits */
+ if ((result = EAS_HWGetByte(pEASData->hwInstData, fileHandle, &temp)) != EAS_SUCCESS)
+ return result;
+ temp = temp >> 1;
+
+ if (state == 0)
+ {
+ if (temp != OTA_RINGTONE)
+ break;
+ state++;
+ }
+ else
+ {
+
+ if (temp == OTA_SOUND)
+ {
+
+ /* check for static memory allocation */
+ if (pEASData->staticMemoryModel)
+ pData = EAS_CMEnumData(EAS_CM_OTA_DATA);
+ else
+ pData = EAS_HWMalloc(pEASData->hwInstData, sizeof(S_OTA_DATA));
+ if (!pData)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Malloc failed in OTA_Prepare\n"); */ }
+ return EAS_ERROR_MALLOC_FAILED;
+ }
+ EAS_HWMemSet(pData, 0, sizeof(S_OTA_DATA));
+
+ /* return a pointer to the instance data */
+ pData->fileHandle = fileHandle;
+ pData->fileOffset = offset;
+ pData->state = EAS_STATE_OPEN;
+ *ppHandle = pData;
+ break;
+ }
+
+ if (temp != OTA_UNICODE)
+ break;
+ }
+ }
+
+ /* not recognized */
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * OTA_Prepare()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Prepare to parse the file. Allocates instance data (or uses static allocation for
+ * static memory model).
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT OTA_Prepare (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
+{
+ S_OTA_DATA* pData;
+ EAS_RESULT result;
+
+ /* check for valid state */
+ pData = (S_OTA_DATA*) pInstData;
+ if (pData->state != EAS_STATE_OPEN)
+ return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
+
+ /* instantiate a synthesizer */
+ if ((result = VMInitMIDI(pEASData, &pData->pSynth)) != EAS_SUCCESS)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "VMInitMIDI returned %d\n", result); */ }
+ return result;
+ }
+
+ pData->state = EAS_STATE_ERROR;
+ if ((result = OTA_ParseHeader(pEASData, pData)) != EAS_SUCCESS)
+ return result;
+
+ pData->state = EAS_STATE_READY;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * OTA_Time()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Returns the time of the next event in msecs
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ * pTime - pointer to variable to hold time of next event (in msecs)
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pEASData) common decoder interface - pEASData not used */
+static EAS_RESULT OTA_Time (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_U32 *pTime)
+{
+ S_OTA_DATA *pData;
+
+ pData = (S_OTA_DATA*) pInstData;
+
+ /* return time in milliseconds */
+ /*lint -e{704} use shift instead of division */
+ *pTime = pData->time >> 8;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * OTA_Event()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Parse the next event in the file
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT OTA_Event (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_INT parserMode)
+{
+ S_OTA_DATA* pData;
+ EAS_RESULT result;
+ EAS_U32 duration;
+ EAS_U8 temp;
+
+ pData = (S_OTA_DATA*) pInstData;
+ if (pData->state >= EAS_STATE_OPEN)
+ return EAS_SUCCESS;
+
+ /* initialize MIDI channel when the track starts playing */
+ if (pData->time == 0)
+ {
+ /* set program to square lead */
+ if (parserMode != eParserModeMetaData)
+ VMProgramChange(pEASData->pVoiceMgr, pData->pSynth, OTA_CHANNEL, OTA_PROGRAM);
+
+ /* set channel volume to max */
+ if (parserMode != eParserModeMetaData)
+ VMControlChange(pEASData->pVoiceMgr, pData->pSynth, OTA_CHANNEL, 7, 127);
+ }
+
+ /* check for end of note */
+ if (pData->note)
+ {
+ /* stop the note */
+ VMStopNote(pEASData->pVoiceMgr, pData->pSynth, OTA_CHANNEL, pData->note, 0);
+ pData->note = 0;
+
+ /* check for rest between notes */
+ if (pData->restTicks)
+ {
+ pData->time += (EAS_I32) pData->restTicks;
+ pData->restTicks = 0;
+ return EAS_SUCCESS;
+ }
+ }
+
+ /* if not in a pattern, read the pattern header */
+ while (pData->current.patternLen == 0)
+ {
+
+ /* check for loop - don't do infinite loops when locating */
+ if (pData->loopCount && ((parserMode == eParserModePlay) || (pData->loopCount != OTA_INFINITE_LOOP)))
+ {
+ /* if not infinite loop, decrement loop count */
+ if (pData->loopCount != OTA_INFINITE_LOOP)
+ pData->loopCount--;
+
+ /* back to start of pattern*/
+ if ((result = OTA_RestorePosition(pEASData->hwInstData, pData, &pData->patterns[pData->currentPattern])) != EAS_SUCCESS)
+ return result;
+ }
+
+ /* if no previous position to restore, continue forward */
+ else if (pData->restore.fileOffset < 0)
+ {
+
+ /* check for end of song */
+ if (pData->numPatterns == 0)
+ {
+ pData->state = EAS_STATE_STOPPING;
+ VMReleaseAllVoices(pEASData->pVoiceMgr, pData->pSynth);
+ return EAS_SUCCESS;
+ }
+
+ /* read the next pattern header */
+ if ((result = OTA_FetchBitField(pEASData->hwInstData, pData, 3, &temp)) != EAS_SUCCESS)
+ return result;
+ if (temp != OTA_PATTERN_HEADER_ID)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Expected OTA pattern header\n"); */ }
+ return EAS_ERROR_FILE_FORMAT;
+ }
+
+ /* get the pattern ID */
+ if ((result = OTA_FetchBitField(pEASData->hwInstData, pData, 2, &pData->currentPattern)) != EAS_SUCCESS)
+ return result;
+
+ /* get the loop count */
+ if ((result = OTA_FetchBitField(pEASData->hwInstData, pData, 4, &pData->loopCount)) != EAS_SUCCESS)
+ return result;
+
+ /* get the pattern length */
+ if ((result = OTA_FetchBitField(pEASData->hwInstData, pData, 8, &pData->current.patternLen)) != EAS_SUCCESS)
+ return result;
+
+ /* if pattern definition, save the current position */
+ if (pData->current.patternLen)
+ {
+ if ((result = OTA_SavePosition(pEASData->hwInstData, pData, &pData->patterns[pData->currentPattern])) != EAS_SUCCESS)
+ return result;
+ }
+
+ /* if pattern length is zero, repeat a previous pattern */
+ else
+ {
+ /* make sure it's a valid pattern */
+ if (pData->patterns[pData->currentPattern].fileOffset < 0)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "OTA pattern error, invalid pattern specified\n"); */ }
+ return EAS_ERROR_FILE_FORMAT;
+ }
+
+ /* save current position and data */
+ if ((result = OTA_SavePosition(pEASData->hwInstData, pData, &pData->restore)) != EAS_SUCCESS)
+ return result;
+
+ /* seek to the pattern in the file */
+ if ((result = OTA_RestorePosition(pEASData->hwInstData, pData, &pData->patterns[pData->currentPattern])) != EAS_SUCCESS)
+ return result;
+ }
+
+ /* decrement pattern count */
+ pData->numPatterns--;
+ }
+
+ /* restore previous position */
+ else
+ {
+ if ((result = OTA_RestorePosition(pEASData->hwInstData, pData, &pData->restore)) != EAS_SUCCESS)
+ return result;
+ }
+ }
+
+ /* get the next event */
+ if ((result = OTA_FetchBitField(pEASData->hwInstData, pData, 3, &temp)) != EAS_SUCCESS)
+ return result;
+
+ switch (temp)
+ {
+ case OTA_NOTE_INST_ID:
+ /* fetch note value */
+ if ((result = OTA_FetchBitField(pEASData->hwInstData, pData, 4, &pData->note)) != EAS_SUCCESS)
+ return result;
+
+ /* fetch note duration */
+ if ((result = OTA_FetchBitField(pEASData->hwInstData, pData, 3, &temp)) != EAS_SUCCESS)
+ return result;
+ duration = pData->tick * (0x20 >> temp);
+
+ /* fetch note duration modifier */
+ if ((result = OTA_FetchBitField(pEASData->hwInstData, pData, 2, &temp)) != EAS_SUCCESS)
+ return result;
+ switch (temp)
+ {
+ case OTA_NORMAL_DURATION:
+ break;
+
+ case OTA_DOTTED_NOTE:
+ duration += duration >> 1;
+ break;
+
+ case OTA_DOUBLE_DOTTED_NOTE:
+ duration += (duration >> 1) + (duration >> 2);
+ break;
+
+ case OTA_TRIPLET_NOTE:
+ duration = (duration * TRIPLET_MULTIPLIER) >> TRIPLET_SHIFT;
+ break;
+
+ default:
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Unrecognized note duration ignored\n"); */ }
+ break;
+ }
+
+ /* check for note */
+ if (pData->note)
+ {
+
+ /* determine note length based on style */
+ switch (pData->style)
+ {
+ case 0:
+ pData->restTicks = duration >> 4;
+ break;
+ case 1:
+ pData->restTicks = 0;
+ break;
+ case 2:
+ pData->restTicks = duration >> 1;
+ break;
+ default:
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Unrecognized note style ignored\n"); */ }
+ }
+
+ /* add octave */
+ pData->note += pData->octave;
+ if (parserMode == eParserModePlay)
+ VMStartNote(pEASData->pVoiceMgr, pData->pSynth, OTA_CHANNEL, pData->note, pData->velocity);
+ pData->time += (EAS_I32) duration - (EAS_I32) pData->restTicks;
+ }
+
+ /* this is a rest */
+ else
+ pData->time += (EAS_I32) duration;
+ break;
+
+ case OTA_SCALE_INST_ID:
+ /* fetch octave */
+ if ((result = OTA_FetchBitField(pEASData->hwInstData, pData, 2, &temp)) != EAS_SUCCESS)
+ return result;
+ pData->octave = (EAS_U8) (temp * 12 + 59);
+ break;
+
+ case OTA_STYLE_INST_ID:
+ /* fetch note style */
+ if ((result = OTA_FetchBitField(pEASData->hwInstData, pData, 2, &pData->style)) != EAS_SUCCESS)
+ return result;
+ break;
+
+ case OTA_TEMPO_INST_ID:
+ /* fetch tempo */
+ if ((result = OTA_FetchBitField(pEASData->hwInstData, pData, 5, &temp)) != EAS_SUCCESS)
+ return result;
+ pData->tick = bpmTable[temp];
+ break;
+
+ case OTA_VOLUME_INST_ID:
+ /* fetch volume */
+ if ((result = OTA_FetchBitField(pEASData->hwInstData, pData, 4, &temp)) != EAS_SUCCESS)
+ return result;
+ pData->velocity = temp ? (EAS_U8) (temp * OTA_VEL_MUL + OTA_VEL_OFS) : 0;
+ break;
+
+ default:
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Unexpected instruction ID in OTA stream\n"); */ }
+ return EAS_ERROR_FILE_FORMAT;
+ }
+
+ /* decrement pattern length */
+ pData->current.patternLen--;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * OTA_State()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Returns the current state of the stream
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ * pState - pointer to variable to store state
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pEASData) common decoder interface - pEASData not used */
+static EAS_RESULT OTA_State (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 *pState)
+{
+ S_OTA_DATA* pData;
+
+ /* establish pointer to instance data */
+ pData = (S_OTA_DATA*) pInstData;
+
+ /* if stopping, check to see if synth voices are active */
+ if (pData->state == EAS_STATE_STOPPING)
+ {
+ if (VMActiveVoices(pData->pSynth) == 0)
+ pData->state = EAS_STATE_STOPPED;
+ }
+
+ if (pData->state == EAS_STATE_PAUSING)
+ {
+ if (VMActiveVoices(pData->pSynth) == 0)
+ pData->state = EAS_STATE_PAUSED;
+ }
+
+ /* return current state */
+ *pState = pData->state;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * OTA_Close()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Close the file and clean up
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT OTA_Close (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
+{
+ S_OTA_DATA* pData;
+ EAS_RESULT result;
+
+ pData = (S_OTA_DATA*) pInstData;
+
+ /* close the file */
+ if ((result = EAS_HWCloseFile(pEASData->hwInstData, pData->fileHandle)) != EAS_SUCCESS)
+ return result;
+
+ /* free the synth */
+ if (pData->pSynth != NULL)
+ VMMIDIShutdown(pEASData, pData->pSynth);
+
+ /* if using dynamic memory, free it */
+ if (!pEASData->staticMemoryModel)
+ EAS_HWFree(pEASData->hwInstData, pData);
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * OTA_Reset()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Reset the sequencer. Used for locating backwards in the file.
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT OTA_Reset (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
+{
+ S_OTA_DATA* pData;
+ EAS_RESULT result;
+
+ pData = (S_OTA_DATA*) pInstData;
+
+ /* reset the synth */
+ VMReset(pEASData->pVoiceMgr, pData->pSynth, EAS_TRUE);
+ pData->note = 0;
+
+ /* reset file position and re-parse header */
+ pData->state = EAS_STATE_ERROR;
+ if ((result = OTA_ParseHeader (pEASData, pData)) != EAS_SUCCESS)
+ return result;
+
+ pData->state = EAS_STATE_READY;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * OTA_Pause()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Pauses the sequencer. Mutes all voices and sets state to pause.
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT OTA_Pause (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
+{
+ S_OTA_DATA *pData;
+
+ /* can't pause a stopped stream */
+ pData = (S_OTA_DATA*) pInstData;
+ if (pData->state == EAS_STATE_STOPPED)
+ return EAS_ERROR_ALREADY_STOPPED;
+
+ /* mute the synthesizer */
+ VMMuteAllVoices(pEASData->pVoiceMgr, pData->pSynth);
+ pData->state = EAS_STATE_PAUSING;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * OTA_Resume()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Resume playing after a pause, sets state back to playing.
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pEASData) common decoder interface - pEASData not used */
+static EAS_RESULT OTA_Resume (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
+{
+ S_OTA_DATA *pData;
+
+ /* can't resume a stopped stream */
+ pData = (S_OTA_DATA*) pInstData;
+ if (pData->state == EAS_STATE_STOPPED)
+ return EAS_ERROR_ALREADY_STOPPED;
+
+ /* nothing to do but resume playback */
+ pData->state = EAS_STATE_PLAY;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * OTA_SetData()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Return file type
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pEASData) common decoder interface - pEASData not used */
+static EAS_RESULT OTA_SetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value)
+{
+ S_OTA_DATA *pData;
+
+ pData = (S_OTA_DATA *) pInstData;
+ switch (param)
+ {
+
+ /* set metadata callback */
+ case PARSER_DATA_METADATA_CB:
+ EAS_HWMemCpy(&pData->metadata, (void*) value, sizeof(S_METADATA_CB));
+ break;
+
+ default:
+ return EAS_ERROR_INVALID_PARAMETER;
+ }
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * OTA_GetData()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Return file type
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pEASData) common decoder interface - pEASData not used */
+static EAS_RESULT OTA_GetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue)
+{
+ S_OTA_DATA *pData;
+
+ pData = (S_OTA_DATA*) pInstData;
+ switch (param)
+ {
+ /* return file type as OTA */
+ case PARSER_DATA_FILE_TYPE:
+ *pValue = EAS_FILE_OTA;
+ break;
+
+#if 0
+ /* set transposition */
+ case PARSER_DATA_TRANSPOSITION:
+ *pValue = pData->transposition;
+ break;
+#endif
+
+ case PARSER_DATA_SYNTH_HANDLE:
+ *pValue = (EAS_I32) pData->pSynth;
+ break;
+
+ case PARSER_DATA_GAIN_OFFSET:
+ *pValue = OTA_GAIN_OFFSET;
+ break;
+
+ default:
+ return EAS_ERROR_INVALID_PARAMETER;
+ }
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * OTA_ParseHeader()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Prepare to parse the file. Allocates instance data (or uses static allocation for
+ * static memory model).
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT OTA_ParseHeader (S_EAS_DATA *pEASData, S_OTA_DATA* pData)
+{
+ EAS_RESULT result;
+ EAS_INT i;
+ EAS_INT state;
+ EAS_U8 temp;
+ EAS_U8 titleLen;
+
+ /* initialize some data */
+ pData->flags = 0;
+ pData->time = 0;
+ pData->tick = DEFAULT_TICK_CONV;
+ pData->patterns[0].fileOffset = pData->patterns[1].fileOffset =
+ pData->patterns[2].fileOffset = pData->patterns[3].fileOffset = -1;
+ pData->current.bitCount = 0;
+ pData->current.patternLen = 0;
+ pData->loopCount = 0;
+ pData->restore.fileOffset = -1;
+ pData->note = 0;
+ pData->restTicks = 0;
+ pData->velocity = OTA_VEL_DEFAULT;
+ pData->style = 0;
+ pData->octave = 59;
+
+ /* seek to start of data */
+ if ((result = EAS_HWFileSeek(pEASData->hwInstData, pData->fileHandle, pData->fileOffset)) != EAS_SUCCESS)
+ return result;
+
+ /* read the first byte, should be command length */
+ if ((result = EAS_HWGetByte(pEASData->hwInstData, pData->fileHandle, &temp)) != EAS_SUCCESS)
+ return result;
+
+ /* read all the commands */
+ i = temp;
+ state = 0;
+ while (i--)
+ {
+
+ /* fetch command, always starts on byte boundary */
+ pData->current.bitCount = 0;
+ if ((result = OTA_FetchBitField(pEASData->hwInstData, pData, 7, &temp)) != EAS_SUCCESS)
+ return result;
+
+ if (state == 0)
+ {
+ if (temp != OTA_RINGTONE)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Expected OTA Ring Tone Programming type\n"); */ }
+ return EAS_ERROR_FILE_FORMAT;
+ }
+ state++;
+ }
+ else
+ {
+
+ if (temp == OTA_SOUND)
+ break;
+
+ if (temp == OTA_UNICODE)
+ pData->flags |= OTA_FLAGS_UNICODE;
+ else
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Expected OTA Sound or Unicode type\n"); */ }
+ return EAS_ERROR_FILE_FORMAT;
+ }
+ }
+ }
+
+ /* get song type */
+ if ((result = OTA_FetchBitField(pEASData->hwInstData, pData, 3, &temp)) != EAS_SUCCESS)
+ return result;
+
+ /* check for basic song type */
+ if (temp == OTA_BASIC_SONG_TYPE)
+ {
+ /* fetch title length */
+ if ((result = OTA_FetchBitField(pEASData->hwInstData, pData, 4, &titleLen)) != EAS_SUCCESS)
+ return result;
+
+ /* if unicode, double the length */
+ if (pData->flags & OTA_FLAGS_UNICODE)
+ titleLen = (EAS_U8) (titleLen << 1);
+
+ /* zero the metadata buffer */
+ if (pData->metadata.buffer)
+ EAS_HWMemSet(pData->metadata.buffer, 0, pData->metadata.bufferSize);
+
+ /* read the song title */
+ for (i = 0; i < titleLen; i++)
+ {
+ /* fetch character */
+ if ((result = OTA_FetchBitField(pEASData->hwInstData, pData, 8, &temp)) != EAS_SUCCESS)
+ return result;
+
+ /* check for metadata callback */
+ if (pData->metadata.callback)
+ {
+ if (i < (pData->metadata.bufferSize - 1))
+ pData->metadata.buffer[i] = (char) temp;
+ }
+ }
+
+ /* if host has registered callback, call it now */
+ if (pData->metadata.callback)
+ (*pData->metadata.callback)(EAS_METADATA_TITLE, pData->metadata.buffer, pData->metadata.pUserData);
+ }
+
+ /* must be temporary song */
+ else if (temp != OTA_TEMPORARY_SONG_TYPE)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Expected OTA basic or temporary song type\n"); */ }
+ return EAS_ERROR_FILE_FORMAT;
+ }
+
+ /* get the song length */
+ if ((result = OTA_FetchBitField(pEASData->hwInstData, pData, 8, &pData->numPatterns)) != EAS_SUCCESS)
+ return result;
+
+ /* sanity check */
+ if (pData->numPatterns == 0)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "OTA number of patterns is zero\n"); */ }
+ return EAS_ERROR_FILE_FORMAT;
+ }
+
+ /* at start of first pattern */
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * OTA_FetchBitField()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Fetch a specified number of bits from the input stream
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT OTA_FetchBitField (EAS_HW_DATA_HANDLE hwInstData, S_OTA_DATA *pData, EAS_I32 numBits, EAS_U8 *pValue)
+{
+ EAS_RESULT result;
+ EAS_I32 bitsLeft;
+ EAS_U8 value;
+
+ value = 0;
+
+ /* do we have enough bits? */
+ bitsLeft = pData->current.bitCount - numBits;
+
+ /* not enough bits, assemble them from 2 characters */
+ if (bitsLeft < 0)
+ {
+ /* grab the remaining bits from the previous byte */
+ if (pData->current.bitCount)
+ /*lint -e{504,734} this is a legitimate shift operation */
+ value = pData->current.dataByte << -bitsLeft;
+
+ /* read the next byte */
+ if ((result = EAS_HWGetByte(hwInstData, pData->fileHandle, &pData->current.dataByte)) != EAS_SUCCESS)
+ return result;
+ bitsLeft += 8;
+ }
+
+ /* more bits than needed? */
+ if (bitsLeft > 0)
+ {
+ value |= pData->current.dataByte >> bitsLeft;
+ pData->current.bitCount = (EAS_U8) bitsLeft;
+ pData->current.dataByte = pData->current.dataByte & (0xff >> (8 - bitsLeft));
+ }
+
+ /* exactly the right number of bits */
+ else
+ {
+ value |= pData->current.dataByte;
+ pData->current.bitCount = 0;
+ }
+
+ *pValue = value;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * OTA_SavePosition()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ *
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT OTA_SavePosition (EAS_HW_DATA_HANDLE hwInstData, S_OTA_DATA *pData, S_OTA_LOC *pLoc)
+{
+ EAS_HWMemCpy(pLoc, &pData->current, sizeof(S_OTA_LOC));
+ return EAS_HWFilePos(hwInstData, pData->fileHandle, &pLoc->fileOffset);
+}
+
+/*----------------------------------------------------------------------------
+ * OTA_RestorePosition()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ *
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT OTA_RestorePosition (EAS_HW_DATA_HANDLE hwInstData, S_OTA_DATA *pData, S_OTA_LOC *pLoc)
+{
+ EAS_HWMemCpy(&pData->current, pLoc, sizeof(S_OTA_LOC));
+ pData->restore.fileOffset = -1;
+ return EAS_HWFileSeek(hwInstData, pData->fileHandle, pLoc->fileOffset);
+}
+
diff --git a/arm-wt-22k/lib_src/eas_otadata.c b/arm-wt-22k/lib_src/eas_otadata.c
index 237f832..7463a0c 100644
--- a/arm-wt-22k/lib_src/eas_otadata.c
+++ b/arm-wt-22k/lib_src/eas_otadata.c
@@ -1,12 +1,12 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_otadata..c
- *
- * Contents and purpose:
- * OTA Stream Parser data module for static memory model
- *
- * Copyright Sonic Network Inc. 2005
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_otadata..c
+ *
+ * Contents and purpose:
+ * OTA Stream Parser data module for static memory model
+ *
+ * Copyright Sonic Network Inc. 2005
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,23 +19,23 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 547 $
- * $Date: 2007-01-31 16:30:17 -0800 (Wed, 31 Jan 2007) $
- *----------------------------------------------------------------------------
-*/
-
-#include "eas_types.h"
-#include "eas_otadata.h"
-
-/*----------------------------------------------------------------------------
- *
- * eas_OTAData
- *
- * Static memory allocation for OTA parser
- *----------------------------------------------------------------------------
-*/
-S_OTA_DATA eas_OTAData;
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 547 $
+ * $Date: 2007-01-31 16:30:17 -0800 (Wed, 31 Jan 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+#include "eas_types.h"
+#include "eas_otadata.h"
+
+/*----------------------------------------------------------------------------
+ *
+ * eas_OTAData
+ *
+ * Static memory allocation for OTA parser
+ *----------------------------------------------------------------------------
+*/
+S_OTA_DATA eas_OTAData;
+
diff --git a/arm-wt-22k/lib_src/eas_otadata.h b/arm-wt-22k/lib_src/eas_otadata.h
index 63e963f..c06e3d3 100644
--- a/arm-wt-22k/lib_src/eas_otadata.h
+++ b/arm-wt-22k/lib_src/eas_otadata.h
@@ -1,14 +1,14 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_otadata.h
- *
- * Contents and purpose:
- * OTA File Parser
- *
- * This file contains data declarations for the OTA parser.
- *
- * Copyright Sonic Network Inc. 2005
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_otadata.h
+ *
+ * Contents and purpose:
+ * OTA File Parser
+ *
+ * This file contains data declarations for the OTA parser.
+ *
+ * Copyright Sonic Network Inc. 2005
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,61 +21,61 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 82 $
- * $Date: 2006-07-10 11:45:19 -0700 (Mon, 10 Jul 2006) $
- *----------------------------------------------------------------------------
-*/
-
-#ifndef EAS_OTADATA_H
-#define EAS_OTADATA_H
-
-#include "eas_data.h"
-
-/* definition for state flags */
-#define OTA_FLAGS_UNICODE 0x01 /* unicode text */
-
-/*----------------------------------------------------------------------------
- *
- * S_OTA_DATA
- *
- * This structure contains the state data for the OTA parser
- *----------------------------------------------------------------------------
-*/
-
-typedef struct
-{
- EAS_I32 fileOffset; /* offset to location in file */
- EAS_U8 patternLen; /* length of current pattern */
- EAS_U8 dataByte; /* previous char from file */
- EAS_U8 bitCount; /* bit count in char */
-} S_OTA_LOC;
-
-typedef struct
-{
- EAS_FILE_HANDLE fileHandle; /* file handle */
- S_SYNTH *pSynth; /* synth handle */
- EAS_I32 fileOffset; /* offset to start of data */
- EAS_I32 time; /* current time in 256ths of a msec */
- EAS_U32 tick; /* length of 32nd note in 256th of a msec */
- EAS_U32 restTicks; /* ticks to rest after current note */
- S_OTA_LOC patterns[4]; /* pattern locations */
- S_OTA_LOC current; /* current location */
- S_OTA_LOC restore; /* previous location */
- S_METADATA_CB metadata; /* metadata callback */
- EAS_U8 flags; /* bit flags */
- EAS_U8 numPatterns; /* number of patterns left in song */
- EAS_U8 currentPattern; /* current pattern for loop */
- EAS_U8 note; /* MIDI note number */
- EAS_U8 octave; /* octave modifier */
- EAS_U8 style; /* from STYLE */
- EAS_U8 velocity; /* current volume */
- EAS_U8 state; /* current state EAS_STATE_XXXX */
- EAS_U8 loopCount; /* loop count for pattern */
-} S_OTA_DATA;
-
-#endif
-
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 82 $
+ * $Date: 2006-07-10 11:45:19 -0700 (Mon, 10 Jul 2006) $
+ *----------------------------------------------------------------------------
+*/
+
+#ifndef EAS_OTADATA_H
+#define EAS_OTADATA_H
+
+#include "eas_data.h"
+
+/* definition for state flags */
+#define OTA_FLAGS_UNICODE 0x01 /* unicode text */
+
+/*----------------------------------------------------------------------------
+ *
+ * S_OTA_DATA
+ *
+ * This structure contains the state data for the OTA parser
+ *----------------------------------------------------------------------------
+*/
+
+typedef struct
+{
+ EAS_I32 fileOffset; /* offset to location in file */
+ EAS_U8 patternLen; /* length of current pattern */
+ EAS_U8 dataByte; /* previous char from file */
+ EAS_U8 bitCount; /* bit count in char */
+} S_OTA_LOC;
+
+typedef struct
+{
+ EAS_FILE_HANDLE fileHandle; /* file handle */
+ S_SYNTH *pSynth; /* synth handle */
+ EAS_I32 fileOffset; /* offset to start of data */
+ EAS_I32 time; /* current time in 256ths of a msec */
+ EAS_U32 tick; /* length of 32nd note in 256th of a msec */
+ EAS_U32 restTicks; /* ticks to rest after current note */
+ S_OTA_LOC patterns[4]; /* pattern locations */
+ S_OTA_LOC current; /* current location */
+ S_OTA_LOC restore; /* previous location */
+ S_METADATA_CB metadata; /* metadata callback */
+ EAS_U8 flags; /* bit flags */
+ EAS_U8 numPatterns; /* number of patterns left in song */
+ EAS_U8 currentPattern; /* current pattern for loop */
+ EAS_U8 note; /* MIDI note number */
+ EAS_U8 octave; /* octave modifier */
+ EAS_U8 style; /* from STYLE */
+ EAS_U8 velocity; /* current volume */
+ EAS_U8 state; /* current state EAS_STATE_XXXX */
+ EAS_U8 loopCount; /* loop count for pattern */
+} S_OTA_DATA;
+
+#endif
+
+
diff --git a/arm-wt-22k/lib_src/eas_pan.c b/arm-wt-22k/lib_src/eas_pan.c
index 373d90e..ae4c69d 100644
--- a/arm-wt-22k/lib_src/eas_pan.c
+++ b/arm-wt-22k/lib_src/eas_pan.c
@@ -1,16 +1,16 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_pan.c
- *
- * Contents and purpose:
- * Calculates left and right gain multipliers based on a pan value from -63 to +63
- *
- * NOTES:
- * The _CMX_PARSER and _MFI_PARSER preprocessor symbols determine
- * whether the parser works for those particular file formats.
- *
- * Copyright Sonic Network Inc. 2005
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_pan.c
+ *
+ * Contents and purpose:
+ * Calculates left and right gain multipliers based on a pan value from -63 to +63
+ *
+ * NOTES:
+ * The _CMX_PARSER and _MFI_PARSER preprocessor symbols determine
+ * whether the parser works for those particular file formats.
+ *
+ * Copyright Sonic Network Inc. 2005
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -23,76 +23,76 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 82 $
- * $Date: 2006-07-10 11:45:19 -0700 (Mon, 10 Jul 2006) $
- *----------------------------------------------------------------------------
-*/
-
-#include "eas_pan.h"
-#include "eas_math.h"
-
-/*----------------------------------------------------------------------------
- * EAS_CalcPanControl()
- *----------------------------------------------------------------------------
- * Purpose:
- * Assign the left and right gain values corresponding to the given pan value.
- *
- * This routine uses sin/cos approximations for an equal power curve:
- *
- * sin(x) = (2-4*c)*x^2 + c + x
- * cos(x) = (2-4*c)*x^2 + c - x
- *
- * where c = 1/sqrt(2)
- * using the a0 + x*(a1 + x*a2) approach
- *
- * Inputs:
- * pan - pan value (-63 to + 63)
- *
- * Outputs:
- * pGainLeft linear gain multiplier for left channel (15-bit fraction)
- * pGainRight linear gain multiplier for left channel (15-bit fraction)
- *
- * Side Effects:
- *----------------------------------------------------------------------------
-*/
-void EAS_CalcPanControl (EAS_INT pan, EAS_I16 *pGainLeft, EAS_I16 *pGainRight)
-{
- EAS_INT temp;
- EAS_INT netAngle;
-
- /* impose hard limit */
- if (pan < -63)
- netAngle = -63;
- else if (pan > 63)
- netAngle = 63;
- else
- netAngle = pan;
-
- /*lint -e{701} <avoid multiply for performance reasons>*/
- netAngle = netAngle << 8;
-
- /* calculate sin */
- temp = EG1_ONE + FMUL_15x15(COEFF_PAN_G2, netAngle);
- temp = COEFF_PAN_G0 + FMUL_15x15(temp, netAngle);
-
- if (temp > SYNTH_FULL_SCALE_EG1_GAIN)
- temp = SYNTH_FULL_SCALE_EG1_GAIN;
- else if (temp < 0)
- temp = 0;
-
- *pGainRight = (EAS_I16) temp;
-
- /* calculate cos */
- temp = -EG1_ONE + FMUL_15x15(COEFF_PAN_G2, netAngle);
- temp = COEFF_PAN_G0 + FMUL_15x15(temp, netAngle);
- if (temp > SYNTH_FULL_SCALE_EG1_GAIN)
- temp = SYNTH_FULL_SCALE_EG1_GAIN;
- else if (temp < 0)
- temp = 0;
-
- *pGainLeft = (EAS_I16) temp;
-}
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 82 $
+ * $Date: 2006-07-10 11:45:19 -0700 (Mon, 10 Jul 2006) $
+ *----------------------------------------------------------------------------
+*/
+
+#include "eas_pan.h"
+#include "eas_math.h"
+
+/*----------------------------------------------------------------------------
+ * EAS_CalcPanControl()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Assign the left and right gain values corresponding to the given pan value.
+ *
+ * This routine uses sin/cos approximations for an equal power curve:
+ *
+ * sin(x) = (2-4*c)*x^2 + c + x
+ * cos(x) = (2-4*c)*x^2 + c - x
+ *
+ * where c = 1/sqrt(2)
+ * using the a0 + x*(a1 + x*a2) approach
+ *
+ * Inputs:
+ * pan - pan value (-63 to + 63)
+ *
+ * Outputs:
+ * pGainLeft linear gain multiplier for left channel (15-bit fraction)
+ * pGainRight linear gain multiplier for left channel (15-bit fraction)
+ *
+ * Side Effects:
+ *----------------------------------------------------------------------------
+*/
+void EAS_CalcPanControl (EAS_INT pan, EAS_I16 *pGainLeft, EAS_I16 *pGainRight)
+{
+ EAS_INT temp;
+ EAS_INT netAngle;
+
+ /* impose hard limit */
+ if (pan < -63)
+ netAngle = -63;
+ else if (pan > 63)
+ netAngle = 63;
+ else
+ netAngle = pan;
+
+ /*lint -e{701} <avoid multiply for performance reasons>*/
+ netAngle = netAngle << 8;
+
+ /* calculate sin */
+ temp = EG1_ONE + FMUL_15x15(COEFF_PAN_G2, netAngle);
+ temp = COEFF_PAN_G0 + FMUL_15x15(temp, netAngle);
+
+ if (temp > SYNTH_FULL_SCALE_EG1_GAIN)
+ temp = SYNTH_FULL_SCALE_EG1_GAIN;
+ else if (temp < 0)
+ temp = 0;
+
+ *pGainRight = (EAS_I16) temp;
+
+ /* calculate cos */
+ temp = -EG1_ONE + FMUL_15x15(COEFF_PAN_G2, netAngle);
+ temp = COEFF_PAN_G0 + FMUL_15x15(temp, netAngle);
+ if (temp > SYNTH_FULL_SCALE_EG1_GAIN)
+ temp = SYNTH_FULL_SCALE_EG1_GAIN;
+ else if (temp < 0)
+ temp = 0;
+
+ *pGainLeft = (EAS_I16) temp;
+}
+
diff --git a/arm-wt-22k/lib_src/eas_pan.h b/arm-wt-22k/lib_src/eas_pan.h
index cefa650..cb0a90d 100644
--- a/arm-wt-22k/lib_src/eas_pan.h
+++ b/arm-wt-22k/lib_src/eas_pan.h
@@ -1,16 +1,16 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_pan.h
- *
- * Contents and purpose:
- * Calculates left and right gain multipliers based on a pan value from -63 to +63
- *
- * NOTES:
- * The _CMX_PARSER and _MFI_PARSER preprocessor symbols determine
- * whether the parser works for those particular file formats.
- *
- * Copyright Sonic Network Inc. 2005
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_pan.h
+ *
+ * Contents and purpose:
+ * Calculates left and right gain multipliers based on a pan value from -63 to +63
+ *
+ * NOTES:
+ * The _CMX_PARSER and _MFI_PARSER preprocessor symbols determine
+ * whether the parser works for those particular file formats.
+ *
+ * Copyright Sonic Network Inc. 2005
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -23,44 +23,44 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 82 $
- * $Date: 2006-07-10 11:45:19 -0700 (Mon, 10 Jul 2006) $
- *----------------------------------------------------------------------------
-*/
-
-#ifndef EAS_PAN_H
-#define _EAS_PAN_H
-
-#include "eas_types.h"
-
-/*----------------------------------------------------------------------------
- * EAS_CalcPanControl()
- *----------------------------------------------------------------------------
- * Purpose:
- * Assign the left and right gain values corresponding to the given pan value.
- *
- * This routine uses sin/cos approximations for an equal power curve:
- *
- * sin(x) = (2-4*c)*x^2 + c + x
- * cos(x) = (2-4*c)*x^2 + c - x
- *
- * where c = 1/sqrt(2)
- * using the a0 + x*(a1 + x*a2) approach
- *
- * Inputs:
- * pan - pan value (-63 to + 63)
- *
- * Outputs:
- * pGainLeft linear gain multiplier for left channel (15-bit fraction)
- * pGainRight linear gain multiplier for left channel (15-bit fraction)
- *
- * Side Effects:
- *----------------------------------------------------------------------------
-*/
-void EAS_CalcPanControl (EAS_INT pan, EAS_I16 *pGainLeft, EAS_I16 *pGainRight);
-
-#endif
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 82 $
+ * $Date: 2006-07-10 11:45:19 -0700 (Mon, 10 Jul 2006) $
+ *----------------------------------------------------------------------------
+*/
+
+#ifndef EAS_PAN_H
+#define _EAS_PAN_H
+
+#include "eas_types.h"
+
+/*----------------------------------------------------------------------------
+ * EAS_CalcPanControl()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Assign the left and right gain values corresponding to the given pan value.
+ *
+ * This routine uses sin/cos approximations for an equal power curve:
+ *
+ * sin(x) = (2-4*c)*x^2 + c + x
+ * cos(x) = (2-4*c)*x^2 + c - x
+ *
+ * where c = 1/sqrt(2)
+ * using the a0 + x*(a1 + x*a2) approach
+ *
+ * Inputs:
+ * pan - pan value (-63 to + 63)
+ *
+ * Outputs:
+ * pGainLeft linear gain multiplier for left channel (15-bit fraction)
+ * pGainRight linear gain multiplier for left channel (15-bit fraction)
+ *
+ * Side Effects:
+ *----------------------------------------------------------------------------
+*/
+void EAS_CalcPanControl (EAS_INT pan, EAS_I16 *pGainLeft, EAS_I16 *pGainRight);
+
+#endif
+
diff --git a/arm-wt-22k/lib_src/eas_parser.h b/arm-wt-22k/lib_src/eas_parser.h
index 5512c82..96ec35b 100644
--- a/arm-wt-22k/lib_src/eas_parser.h
+++ b/arm-wt-22k/lib_src/eas_parser.h
@@ -1,15 +1,15 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_parser.h
- *
- * Contents and purpose:
- * Interface declarations for the generic parser interface
- *
- * This header only contains declarations that are specific
- * to this implementation.
- *
- * Copyright Sonic Network Inc. 2005
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_parser.h
+ *
+ * Contents and purpose:
+ * Interface declarations for the generic parser interface
+ *
+ * This header only contains declarations that are specific
+ * to this implementation.
+ *
+ * Copyright Sonic Network Inc. 2005
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -22,77 +22,77 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 767 $
- * $Date: 2007-07-19 13:47:31 -0700 (Thu, 19 Jul 2007) $
- *----------------------------------------------------------------------------
-*/
-
-#ifndef _EAS_PARSER_H
-#define _EAS_PARSER_H
-
-#include "eas_types.h"
-
-
-/* metadata callback */
-typedef struct s_metadata_cb_tag
-{
- EAS_METADATA_CBFUNC callback;
- char *buffer;
- EAS_VOID_PTR pUserData;
- EAS_I32 bufferSize;
-} S_METADATA_CB;
-
-/* generic parser interface */
-typedef struct
-{
- EAS_RESULT (* EAS_CONST pfCheckFileType)(struct s_eas_data_tag *pEASData, EAS_FILE_HANDLE fileHandle, EAS_VOID_PTR *ppHandle, EAS_I32 offset);
- EAS_RESULT (* EAS_CONST pfPrepare)(struct s_eas_data_tag *pEASData, EAS_VOID_PTR pInstData);
- EAS_RESULT (* EAS_CONST pfTime)(struct s_eas_data_tag *pEASData, EAS_VOID_PTR pInstData, EAS_U32 *pTime);
- EAS_RESULT (* EAS_CONST pfEvent)(struct s_eas_data_tag *pEASData, EAS_VOID_PTR pInstData, EAS_INT parseMode);
- EAS_RESULT (* EAS_CONST pfState)(struct s_eas_data_tag *pEASData, EAS_VOID_PTR pInstData, EAS_STATE *pState);
- EAS_RESULT (* EAS_CONST pfClose)(struct s_eas_data_tag *pEASData, EAS_VOID_PTR pInstData);
- EAS_RESULT (* EAS_CONST pfReset)(struct s_eas_data_tag *pEASData, EAS_VOID_PTR pInstData);
- EAS_RESULT (* EAS_CONST pfPause)(struct s_eas_data_tag *pEASData, EAS_VOID_PTR pInstData);
- EAS_RESULT (* EAS_CONST pfResume)(struct s_eas_data_tag *pEASData, EAS_VOID_PTR pInstData);
- EAS_RESULT (* EAS_CONST pfLocate)(struct s_eas_data_tag *pEASData, EAS_VOID_PTR pInstData, EAS_I32 time, EAS_BOOL *pParserLocate);
- EAS_RESULT (* EAS_CONST pfSetData)(struct s_eas_data_tag *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value);
- EAS_RESULT (* EAS_CONST pfGetData)(struct s_eas_data_tag *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue);
- EAS_RESULT (* EAS_CONST pfGetMetaData)(struct s_eas_data_tag *pEASData, EAS_VOID_PTR pInstData, EAS_I32 *pMediaLength);
-} S_FILE_PARSER_INTERFACE;
-
-typedef enum
-{
- eParserModePlay,
- eParserModeLocate,
- eParserModeMute,
- eParserModeMetaData
-} E_PARSE_MODE;
-
-typedef enum
-{
- PARSER_DATA_FILE_TYPE,
- PARSER_DATA_PLAYBACK_RATE,
- PARSER_DATA_TRANSPOSITION,
- PARSER_DATA_VOLUME,
- PARSER_DATA_SYNTH_HANDLE,
- PARSER_DATA_METADATA_CB,
- PARSER_DATA_DLS_COLLECTION,
- PARSER_DATA_EAS_LIBRARY,
- PARSER_DATA_POLYPHONY,
- PARSER_DATA_PRIORITY,
- PARSER_DATA_FORMAT,
- PARSER_DATA_MEDIA_LENGTH,
- PARSER_DATA_JET_CB,
- PARSER_DATA_MUTE_FLAGS,
- PARSER_DATA_SET_MUTE,
- PARSER_DATA_CLEAR_MUTE,
- PARSER_DATA_NOTE_COUNT,
- PARSER_DATA_MAX_PCM_STREAMS,
- PARSER_DATA_GAIN_OFFSET,
- PARSER_DATA_PLAY_MODE
-} E_PARSER_DATA;
-
-#endif /* #ifndef _EAS_PARSER_H */
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 767 $
+ * $Date: 2007-07-19 13:47:31 -0700 (Thu, 19 Jul 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+#ifndef _EAS_PARSER_H
+#define _EAS_PARSER_H
+
+#include "eas_types.h"
+
+
+/* metadata callback */
+typedef struct s_metadata_cb_tag
+{
+ EAS_METADATA_CBFUNC callback;
+ char *buffer;
+ EAS_VOID_PTR pUserData;
+ EAS_I32 bufferSize;
+} S_METADATA_CB;
+
+/* generic parser interface */
+typedef struct
+{
+ EAS_RESULT (* EAS_CONST pfCheckFileType)(struct s_eas_data_tag *pEASData, EAS_FILE_HANDLE fileHandle, EAS_VOID_PTR *ppHandle, EAS_I32 offset);
+ EAS_RESULT (* EAS_CONST pfPrepare)(struct s_eas_data_tag *pEASData, EAS_VOID_PTR pInstData);
+ EAS_RESULT (* EAS_CONST pfTime)(struct s_eas_data_tag *pEASData, EAS_VOID_PTR pInstData, EAS_U32 *pTime);
+ EAS_RESULT (* EAS_CONST pfEvent)(struct s_eas_data_tag *pEASData, EAS_VOID_PTR pInstData, EAS_INT parseMode);
+ EAS_RESULT (* EAS_CONST pfState)(struct s_eas_data_tag *pEASData, EAS_VOID_PTR pInstData, EAS_STATE *pState);
+ EAS_RESULT (* EAS_CONST pfClose)(struct s_eas_data_tag *pEASData, EAS_VOID_PTR pInstData);
+ EAS_RESULT (* EAS_CONST pfReset)(struct s_eas_data_tag *pEASData, EAS_VOID_PTR pInstData);
+ EAS_RESULT (* EAS_CONST pfPause)(struct s_eas_data_tag *pEASData, EAS_VOID_PTR pInstData);
+ EAS_RESULT (* EAS_CONST pfResume)(struct s_eas_data_tag *pEASData, EAS_VOID_PTR pInstData);
+ EAS_RESULT (* EAS_CONST pfLocate)(struct s_eas_data_tag *pEASData, EAS_VOID_PTR pInstData, EAS_I32 time, EAS_BOOL *pParserLocate);
+ EAS_RESULT (* EAS_CONST pfSetData)(struct s_eas_data_tag *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value);
+ EAS_RESULT (* EAS_CONST pfGetData)(struct s_eas_data_tag *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue);
+ EAS_RESULT (* EAS_CONST pfGetMetaData)(struct s_eas_data_tag *pEASData, EAS_VOID_PTR pInstData, EAS_I32 *pMediaLength);
+} S_FILE_PARSER_INTERFACE;
+
+typedef enum
+{
+ eParserModePlay,
+ eParserModeLocate,
+ eParserModeMute,
+ eParserModeMetaData
+} E_PARSE_MODE;
+
+typedef enum
+{
+ PARSER_DATA_FILE_TYPE,
+ PARSER_DATA_PLAYBACK_RATE,
+ PARSER_DATA_TRANSPOSITION,
+ PARSER_DATA_VOLUME,
+ PARSER_DATA_SYNTH_HANDLE,
+ PARSER_DATA_METADATA_CB,
+ PARSER_DATA_DLS_COLLECTION,
+ PARSER_DATA_EAS_LIBRARY,
+ PARSER_DATA_POLYPHONY,
+ PARSER_DATA_PRIORITY,
+ PARSER_DATA_FORMAT,
+ PARSER_DATA_MEDIA_LENGTH,
+ PARSER_DATA_JET_CB,
+ PARSER_DATA_MUTE_FLAGS,
+ PARSER_DATA_SET_MUTE,
+ PARSER_DATA_CLEAR_MUTE,
+ PARSER_DATA_NOTE_COUNT,
+ PARSER_DATA_MAX_PCM_STREAMS,
+ PARSER_DATA_GAIN_OFFSET,
+ PARSER_DATA_PLAY_MODE
+} E_PARSER_DATA;
+
+#endif /* #ifndef _EAS_PARSER_H */
diff --git a/arm-wt-22k/lib_src/eas_pcm.c b/arm-wt-22k/lib_src/eas_pcm.c
index 64b8f71..ff3f6f9 100644
--- a/arm-wt-22k/lib_src/eas_pcm.c
+++ b/arm-wt-22k/lib_src/eas_pcm.c
@@ -1,12 +1,12 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_pcm.c
- *
- * Contents and purpose:
- * Implements the PCM engine including ADPCM decode for SMAF and CMX audio playback.
- *
- * Copyright Sonic Network Inc. 2005
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_pcm.c
+ *
+ * Contents and purpose:
+ * Implements the PCM engine including ADPCM decode for SMAF and CMX audio playback.
+ *
+ * Copyright Sonic Network Inc. 2005
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,1464 +19,1464 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 849 $
- * $Date: 2007-08-28 08:59:11 -0700 (Tue, 28 Aug 2007) $
- *----------------------------------------------------------------------------
-*/
-
-#include "eas_data.h"
-#include "eas_report.h"
-#include "eas_host.h"
-#include "eas_config.h"
-#include "eas_parser.h"
-#include "eas_pcm.h"
-#include "eas_math.h"
-#include "eas_mixer.h"
-
-#define PCM_MIXER_GUARD_BITS (NUM_MIXER_GUARD_BITS + 1)
-
-/*----------------------------------------------------------------------------
- * Decoder interfaces
- *----------------------------------------------------------------------------
-*/
-
-static EAS_RESULT LinearPCMDecode (EAS_DATA_HANDLE pEASData, S_PCM_STATE *pState);
-static EAS_RESULT LinearPCMLocate (EAS_DATA_HANDLE pEASData, S_PCM_STATE *pState, EAS_I32 time);
-
-static const S_DECODER_INTERFACE PCMDecoder =
-{
- NULL,
- LinearPCMDecode,
- LinearPCMLocate,
-};
-
-/* SMAF ADPCM decoder */
-#ifdef _SMAF_PARSER
-extern S_DECODER_INTERFACE SmafDecoder;
-#define SMAF_DECODER &SmafDecoder
-extern S_DECODER_INTERFACE Smaf7BitDecoder;
-#define SMAF_7BIT_DECODER &Smaf7BitDecoder
-#else
-#define SMAF_DECODER NULL
-#define SMAF_7BIT_DECODER NULL
-#endif
-
-/* IMA ADPCM decoder */
-#ifdef _IMA_DECODER
-extern S_DECODER_INTERFACE IMADecoder;
-#define IMA_DECODER &IMADecoder
-#else
-#define IMA_DECODER NULL
-#endif
-
-static const S_DECODER_INTERFACE * const decoders[] =
-{
- &PCMDecoder,
- SMAF_DECODER,
- IMA_DECODER,
- SMAF_7BIT_DECODER
-};
-
-/*----------------------------------------------------------------------------
- * Sample rate conversion
- *----------------------------------------------------------------------------
-*/
-
-#define SRC_RATE_MULTIPLER (0x40000000 / _OUTPUT_SAMPLE_RATE)
-
-#ifdef _LOOKUP_SAMPLE_RATE
-static const EAS_U32 srcConvRate[][2] =
-{
- 4000L, (4000L << 15) / _OUTPUT_SAMPLE_RATE,
- 8000L, (8000L << 15) / _OUTPUT_SAMPLE_RATE,
- 11025L, (11025L << 15) / _OUTPUT_SAMPLE_RATE,
- 12000L, (12000L << 15) / _OUTPUT_SAMPLE_RATE,
- 16000L, (16000L << 15) / _OUTPUT_SAMPLE_RATE,
- 22050L, (22050L << 15) / _OUTPUT_SAMPLE_RATE,
- 24000L, (24000L << 15) / _OUTPUT_SAMPLE_RATE,
- 32000L, (32000L << 15) / _OUTPUT_SAMPLE_RATE
-};
-static EAS_U32 CalcBaseFreq (EAS_U32 sampleRate);
-#define SRC_CONV_RATE_ENTRIES (sizeof(srcConvRate)/sizeof(EAS_U32)/2)
-#endif
-
-
-/* interface prototypes */
-static EAS_RESULT RenderPCMStream (S_EAS_DATA *pEASData, S_PCM_STATE *pState, EAS_I32 numSamples);
-
-
-/* local prototypes */
-static S_PCM_STATE *FindSlot (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle, EAS_PCM_CALLBACK pCallbackFunc, EAS_VOID_PTR cbInstData);
-static EAS_RESULT InitPCMStream (S_EAS_DATA *pEASData, S_PCM_STATE *pState);
-
-/*----------------------------------------------------------------------------
- * EAS_PEInit()
- *----------------------------------------------------------------------------
- * Purpose:
- * Initializes the PCM engine
- *
- * Inputs:
- *
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT EAS_PEInit (S_EAS_DATA *pEASData)
-{
- S_PCM_STATE *pState;
- EAS_INT i;
-
- /* check for static memory allocation */
- if (pEASData->staticMemoryModel)
- pEASData->pPCMStreams = EAS_CMEnumData(EAS_CM_PCM_DATA);
- /* allocate dynamic memory */
- else
- pEASData->pPCMStreams = EAS_HWMalloc(pEASData->hwInstData, sizeof(S_PCM_STATE) * MAX_PCM_STREAMS);
-
- if (!pEASData->pPCMStreams)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_FATAL, "Failed to allocate memory for PCM streams\n"); */ }
- return EAS_ERROR_MALLOC_FAILED;
- }
-
- //zero the memory to insure complete initialization
- EAS_HWMemSet((void *)(pEASData->pPCMStreams),0, sizeof(S_PCM_STATE) * MAX_PCM_STREAMS);
-
- /* initialize the state data */
- for (i = 0, pState = pEASData->pPCMStreams; i < MAX_PCM_STREAMS; i++, pState++)
- pState->fileHandle = NULL;
-
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * EAS_PEShutdown()
- *----------------------------------------------------------------------------
- * Purpose:
- * Shuts down the PCM engine
- *
- * Inputs:
- *
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT EAS_PEShutdown (S_EAS_DATA *pEASData)
-{
-
- /* free any dynamic memory */
- if (!pEASData->staticMemoryModel)
- {
- if (pEASData->pPCMStreams)
- {
- EAS_HWFree(pEASData->hwInstData, pEASData->pPCMStreams);
- pEASData->pPCMStreams = NULL;
- }
- }
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * EAS_PERender()
- *----------------------------------------------------------------------------
- * Purpose:
- * Render a buffer of PCM audio
- *
- * Inputs:
- *
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT EAS_PERender (S_EAS_DATA* pEASData, EAS_I32 numSamples)
-{
- S_PCM_STATE *pState;
- EAS_RESULT result;
- EAS_INT i;
-
- /* render all the active streams */
- for (i = 0, pState = pEASData->pPCMStreams; i < MAX_PCM_STREAMS; i++, pState++)
- {
- if ((pState->fileHandle) && (pState->state != EAS_STATE_STOPPED) && (pState->state != EAS_STATE_PAUSED))
- if ((result = RenderPCMStream(pEASData, pState, numSamples)) != EAS_SUCCESS)
- return result;
- }
- return EAS_SUCCESS;
-}
-
-
-/*----------------------------------------------------------------------------
- * EAS_PEState()
- *----------------------------------------------------------------------------
- * Purpose:
- * Returns the current state of the stream
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- * pState - pointer to variable to store state
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- * Notes:
- * This interface is also exposed in the internal library for use by the other modules.
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, pEASData) reserved for future use */
-EAS_RESULT EAS_PEState (S_EAS_DATA *pEASData, EAS_PCM_HANDLE pInstData, EAS_STATE *pState)
-{
- /* return current state */
- *pState = pInstData->state;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * EAS_PEClose()
- *----------------------------------------------------------------------------
- * Purpose:
- * Close the file and clean up
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT EAS_PEClose (S_EAS_DATA *pEASData, EAS_PCM_HANDLE pState)
-{
- EAS_RESULT result;
-
- if ((result = EAS_HWCloseFile(pEASData->hwInstData, pState->fileHandle)) != EAS_SUCCESS)
- return result;
-
- pState->fileHandle = NULL;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * PCM_Reset()
- *----------------------------------------------------------------------------
- * Purpose:
- * Reset the sequencer. Used for locating backwards in the file.
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT EAS_PEReset (S_EAS_DATA *pEASData, EAS_PCM_HANDLE pState)
-{
- EAS_RESULT result;
-
- /* reset file position to first byte of data in the stream */
- if ((result = EAS_HWFileSeek(pEASData->hwInstData, pState->fileHandle, pState->startPos)) != EAS_SUCCESS)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Error %d seeking to start of PCM file\n", result); */ }
- return result;
- }
-
- /* re-initialize stream */
- return InitPCMStream(pEASData, pState);
-}
-
-/*----------------------------------------------------------------------------
- * EAS_PEOpenStream()
- *----------------------------------------------------------------------------
- * Purpose:
- * Starts up a PCM playback
- *
- * Inputs:
- *
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT EAS_PEOpenStream (S_EAS_DATA *pEASData, S_PCM_OPEN_PARAMS *pParams, EAS_PCM_HANDLE *pHandle)
-{
- EAS_RESULT result;
- S_PCM_STATE *pState;
- EAS_I32 filePos;
-
- /* make sure we support this decoder */
- if (pParams->decoder >= NUM_DECODER_MODULES)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Decoder selector out of range\n"); */ }
- return EAS_ERROR_PARAMETER_RANGE;
- }
- if (decoders[pParams->decoder] == NULL)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Decoder module not available\n"); */ }
- return EAS_ERROR_FEATURE_NOT_AVAILABLE;
- }
-
- /* find a slot for the new stream */
- if ((pState = FindSlot(pEASData, pParams->fileHandle, pParams->pCallbackFunc, pParams->cbInstData)) == NULL)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Unable to open ADPCM stream, too many streams open\n"); */ }
- return EAS_ERROR_MAX_PCM_STREAMS;
- }
-
- /* get the current file position */
- if ((result = EAS_HWFilePos(pEASData->hwInstData, pState->fileHandle, &filePos)) != EAS_SUCCESS)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "EAS_HWFilePos returned %ld\n",result); */ }
- pState->fileHandle = NULL;
- return result;
- }
-
- pState->pDecoder = decoders[pParams->decoder];
- pState->startPos = filePos;
- pState->bytesLeftLoop = pState->byteCount = pParams->size;
- pState->loopStart = pParams->loopStart;
- pState->samplesTilLoop = (EAS_I32) pState->loopStart;
- pState->loopSamples = pParams->loopSamples;
- pState->samplesInLoop = 0;
- pState->blockSize = (EAS_U16) pParams->blockSize;
- pState->flags = pParams->flags;
- pState->envData = pParams->envData;
- pState->volume = pParams->volume;
- pState->sampleRate = (EAS_U16) pParams->sampleRate;
-
- /* set the base frequency */
- pState->basefreq = (SRC_RATE_MULTIPLER * (EAS_U32) pParams->sampleRate) >> 15;
-
- /* calculate shift for frequencies > 1.0 */
- pState->rateShift = 0;
- while (pState->basefreq > 32767)
- {
- pState->basefreq = pState->basefreq >> 1;
- pState->rateShift++;
- }
-
- /* initialize */
- if ((result = InitPCMStream(pEASData, pState)) != EAS_SUCCESS)
- return result;
-
- *pHandle = pState;
-
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "EAS_PEOpenStream: StartPos=%d, byteCount = %d, loopSamples=%d\n",
- pState->startPos, pState->byteCount, pState->loopSamples); */ }
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * EAS_PEContinueStream()
- *----------------------------------------------------------------------------
- * Purpose:
- * Continues a PCM stream
- *
- * Inputs:
- *
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -e{715} reserved for future use */
-EAS_RESULT EAS_PEContinueStream (S_EAS_DATA *pEASData, EAS_PCM_HANDLE pState, EAS_I32 size)
-{
-
- /* add new samples to count */
- pState->bytesLeft += size;
- if (pState->bytesLeft > 0)
- pState->flags &= ~PCM_FLAGS_EMPTY;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * EAS_PEGetFileHandle()
- *----------------------------------------------------------------------------
- * Purpose:
- * Returns the file handle of a stream
- *
- * Inputs:
- *
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, pEASData) reserved for future use */
-EAS_RESULT EAS_PEGetFileHandle (S_EAS_DATA *pEASData, EAS_PCM_HANDLE pState, EAS_FILE_HANDLE *pFileHandle)
-{
- *pFileHandle = pState->fileHandle;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * EAS_PEUpdateParams()
- *----------------------------------------------------------------------------
- * Purpose:
- * Update the pitch and volume parameters for a PCM stream
- *
- * Inputs:
- * pEASData - pointer to EAS library instance data
- * handle - pointer to S_PCM_STATE for this stream
- * gainLeft - linear gain multipler in 1.15 fraction format
- * gainRight - linear gain multipler in 1.15 fraction format
- * pitch - pitch shift in cents
- * initial - initial settings, set current gain
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- * Notes
- * In mono mode, leftGain controls the output gain and rightGain is ignored
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, pEASData) reserved for future use */
-/*lint -esym(715, gainRight) used only in 2-channel version */
-EAS_RESULT EAS_PEUpdateParams (S_EAS_DATA* pEASData, EAS_PCM_HANDLE pState, EAS_I16 pitch, EAS_I16 gainLeft, EAS_I16 gainRight)
-{
-
- pState->gainLeft = gainLeft;
-
-#if (NUM_OUTPUT_CHANNELS == 2)
- pState->gainRight = gainRight;
-#endif
-
- pState->pitch = pitch;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * EAS_PELocate()
- *----------------------------------------------------------------------------
- * Purpose:
- * This function seeks to the requested place in the file. Accuracy
- * is dependent on the sample rate and block size.
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * pState - stream handle
- * time - media time in milliseconds
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT EAS_PELocate (S_EAS_DATA *pEASData, EAS_PCM_HANDLE pState, EAS_I32 time)
-{
- if (pState->pDecoder->pfLocate == NULL)
- return EAS_ERROR_FEATURE_NOT_AVAILABLE;
-
- return pState->pDecoder->pfLocate(pEASData, pState, time);
-}
-
-/*----------------------------------------------------------------------------
- * EAS_PEUpdateVolume()
- *----------------------------------------------------------------------------
- * Purpose:
- * Update the volume parameters for a PCM stream
- *
- * Inputs:
- * pEASData - pointer to EAS library instance data
- * handle - pointer to S_PCM_STATE for this stream
- * gainLeft - linear gain multipler in 1.15 fraction format
- * gainRight - linear gain multipler in 1.15 fraction format
- * initial - initial settings, set current gain
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- * Notes
- * In mono mode, leftGain controls the output gain and rightGain is ignored
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, pEASData) reserved for future use */
-EAS_RESULT EAS_PEUpdateVolume (S_EAS_DATA* pEASData, EAS_PCM_HANDLE pState, EAS_I16 volume)
-{
- pState->volume = volume;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * EAS_PEUpdatePitch()
- *----------------------------------------------------------------------------
- * Purpose:
- * Update the pitch parameter for a PCM stream
- *
- * Inputs:
- * pEASData - pointer to EAS library instance data
- * pState - pointer to S_PCM_STATE for this stream
- * pitch - new pitch value in pitch cents
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, pEASData) reserved for future use */
-EAS_RESULT EAS_PEUpdatePitch (S_EAS_DATA* pEASData, EAS_PCM_HANDLE pState, EAS_I16 pitch)
-{
- pState->pitch = pitch;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * EAS_PEPause()
- *----------------------------------------------------------------------------
- * Purpose:
- * Mute and stop rendering a PCM stream. Sets the gain target to zero and stops the playback
- * at the end of the next audio frame.
- *
- * Inputs:
- * pEASData - pointer to EAS library instance data
- * handle - pointer to S_PCM_STATE for this stream
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, pEASData) reserved for future use */
-EAS_RESULT EAS_PEPause (S_EAS_DATA *pEASData, EAS_PCM_HANDLE pState)
-{
- /* set state to stopping */
- pState->state = EAS_STATE_PAUSING;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * EAS_PEResume()
- *----------------------------------------------------------------------------
- * Purpose:
- * Resume rendering a PCM stream. Sets the gain target back to its
- * previous setting and restarts playback at the end of the next audio
- * frame.
- *
- * Inputs:
- * pEASData - pointer to EAS library instance data
- * handle - pointer to S_PCM_STATE for this stream
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, pEASData) reserved for future use */
-EAS_RESULT EAS_PEResume (S_EAS_DATA *pEASData, EAS_PCM_HANDLE pState)
-{
- /* set state to stopping */
- pState->state = EAS_STATE_PLAY;
- return EAS_SUCCESS;
-}
-
-EAS_U32 getDecayScale(EAS_U32 index)
-{
- EAS_U32 utemp;
-
- //envelope decay segment
- switch (index)
- {
- case 0: //no decay
- utemp = 512;//32768;
- break;
- case 1: //.0156 dB per update
- utemp = 511;//32709;
- break;
- case 2: //.03125
- utemp = 510;//32649;
- break;
- case 3: //.0625
- utemp = 508;//32532;
- break;
- case 4: //.125
- utemp = 505;//32298;
- break;
- case 5: //.25
- utemp = 497;//31835;
- break;
- case 6: //.5
- utemp = 483;//30929;
- break;
- case 7: //1.0
- utemp = 456;//29193;
- break;
- case 8: //2.0
- utemp = 406;//26008;
- break;
- case 9: //4.0
- utemp = 323;//20642;
- break;
- case 10: //8.0
- utemp = 203;//13004;
- break;
- case 11: //16.0
- utemp = 81;//5160;
- break;
- case 12: //32.0
- utemp = 13;//813;
- break;
- case 13: //64.0
- utemp = 0;//20;
- break;
- case 14: //128.0
- utemp = 0;
- break;
- case 15: //256.0
- default:
- utemp = 0;
- break;
- }
- //printf("getdecayscale returned %d\n",utemp);
- return utemp;
-}
-
-EAS_U32 getAttackIncrement(EAS_U32 index)
-{
- EAS_U32 utemp;
-
- //envelope decay segment
- switch (index)
- {
- case 0:
- utemp = 32;
- break;
- case 1:
- utemp = 64;
- break;
- case 2:
- utemp = 128;
- break;
- case 3:
- utemp = 256;
- break;
- case 4:
- utemp = 512;
- break;
- case 5:
- utemp = 1024;
- break;
- case 6:
- utemp = 2048;
- break;
- case 7:
- utemp = 4096;
- break;
- case 8:
- utemp = 8192;
- break;
- case 9:
- utemp = 16384;
- break;
- case 10:
- utemp = 32768;
- break;
- case 11:
- utemp = 65536;
- break;
- case 12:
- utemp = 65536;
- break;
- case 13:
- utemp = 65536;
- break;
- case 14:
- utemp = 65535;
- break;
- case 15:
- default:
- utemp = 0;
- break;
- }
- //printf("getattackincrement returned %d\n",utemp);
- return utemp;
-}
-
-/*----------------------------------------------------------------------------
- * EAS_PERelease()
- *----------------------------------------------------------------------------
- * Purpose:
- * Put the PCM stream envelope into release.
- *
- * Inputs:
- * pEASData - pointer to EAS library instance data
- * handle - pointer to S_PCM_STATE for this stream
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, pEASData) reserved for future use */
-EAS_RESULT EAS_PERelease (S_EAS_DATA *pEASData, EAS_PCM_HANDLE pState)
-{
- EAS_U32 utemp;
-
- //printf("handling note-off part of envelope\n");
- /*if the note is not ignore release or sustained*/
- if (((pState->envData >> 24) & 0x0F)==0)
- {
- /* set envelope state to release */
- pState->envState = PCM_ENV_RELEASE;
- utemp = ((pState->envData >> 20) & 0x0F);
- pState->envScale = getDecayScale(utemp); //getReleaseScale(utemp);
- }
- else
- {
- /*else change envelope state to sustain */
- pState->envState = PCM_ENV_SUSTAIN;
- utemp = ((pState->envData >> 28) & 0x0F);
- pState->envScale = getDecayScale(utemp); //getSustainScale(utemp);
- }
- //since we are in release, don't let anything hang around too long
- //printf("checking env scale, val = %d\n",((S_PCM_STATE*) handle)->envScale);
- if (pState->envScale > 505)
- pState->envScale = 505;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * FindSlot()
- *----------------------------------------------------------------------------
- * Purpose:
- * Locates an empty stream slot and assigns the file handle
- *
- * Inputs:
- * pEASData - pointer to EAS library instance data
- * fileHandle - file handle
- * pCallbackFunc - function to be called back upon EAS_STATE_STOPPED
- *
- * Outputs:
- * returns handle to slot or NULL if all slots are used
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static S_PCM_STATE *FindSlot (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle, EAS_PCM_CALLBACK pCallbackFunc, EAS_VOID_PTR cbInstData)
-{
- EAS_INT i;
- S_PCM_STATE *pState;
-
-#ifndef NO_PCM_STEAL
- S_PCM_STATE *foundState = NULL;
- EAS_INT count = 0;
- EAS_U32 startOrder = 0xFFFFFFFF;
- S_PCM_STATE *stealState = NULL;
- EAS_U32 youngest = 0;
-
- /* find an empty slot, count total in use, and find oldest in use (lowest start order) */
- for (i = 0, pState = pEASData->pPCMStreams; i < MAX_PCM_STREAMS; i++, pState++)
- {
- /* if this one is available */
- if (pState->fileHandle == NULL)
- {
- foundState = pState;
- }
- /* else this one is in use, so see if it is the oldest, and count total in use */
- /* also find youngest */
- else
- {
- /*one more voice in use*/
- count++;
- /* is this the oldest? (lowest start order) */
- if ((pState->state != EAS_STATE_STOPPING) && (pState->startOrder < startOrder))
- {
- /* remember this one */
- stealState = pState;
- /* remember the oldest so far */
- startOrder = pState->startOrder;
- }
- /* is this the youngest? (highest start order) */
- if (pState->startOrder >= youngest)
- {
- youngest = pState->startOrder;
- }
- }
- }
-
- /* if there are too many voices active, stop the oldest one */
- if (count > PCM_STREAM_THRESHOLD)
- {
- //printf("stealing!!!\n");
- /* make sure we got one, although we should always have one at this point */
- if (stealState != NULL)
- {
- //flag this as stopping, so it will get shut off
- stealState->state = EAS_STATE_STOPPING;
- }
- }
-
- /* if there are no available open streams (we won't likely see this, due to stealing) */
- if (foundState == NULL)
- return NULL;
-
- /* save info */
- foundState->startOrder = youngest + 1;
- foundState->fileHandle = fileHandle;
- foundState->pCallback = pCallbackFunc;
- foundState->cbInstData = cbInstData;
- return foundState;
-#else
- /* find an empty slot*/
- for (i = 0; i < MAX_PCM_STREAMS; i++)
- {
- pState = &pEASData->pPCMStreams[i];
- if (pState->fileHandle != NULL)
- continue;
-
- pState->fileHandle = fileHandle;
- pState->pCallback = pCallbackFunc;
- pState->cbInstData = cbInstData;
- return pState;
- }
- return NULL;
-#endif
-}
-
-#ifdef _LOOKUP_SAMPLE_RATE
-/*----------------------------------------------------------------------------
- * CalcBaseFreq()
- *----------------------------------------------------------------------------
- * Purpose:
- * Calculates the fractional phase increment for the sample rate converter
- *
- * Inputs:
- * sampleRate - sample rate in samples/sec
- *
- * Outputs:
- * Returns fractional sample rate with a 15-bit fraction
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_U32 CalcBaseFreq (EAS_U32 sampleRate)
-{
- EAS_INT i;
-
- /* look up the conversion rate */
- for (i = 0; i < (EAS_INT)(SRC_CONV_RATE_ENTRIES); i ++)
- {
- if (srcConvRate[i][0] == sampleRate)
- return srcConvRate[i][1];
- }
-
- /* if not found in table, do it the long way */
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Sample rate %u not in table, calculating by division\n", sampleRate); */ }
-
- return (SRC_RATE_MULTIPLER * (EAS_U32) sampleRate) >> 15;
-}
-#endif
-
-/*----------------------------------------------------------------------------
- * InitPCMStream()
- *----------------------------------------------------------------------------
- * Purpose:
- * Start an ADPCM stream playback. Decodes the header, preps the engine.
- *
- * Inputs:
- *
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT InitPCMStream (S_EAS_DATA *pEASData, S_PCM_STATE *pState)
-{
-
- /* initialize the data structure */
- pState->bytesLeft = pState->byteCount;
- pState->phase = 0;
- pState->srcByte = 0;
- pState->decoderL.acc = 0;
- pState->decoderL.output = 0;
- pState->decoderL.x0 = pState->decoderL.x1 = 0;
- pState->decoderL.step = 0;
- pState->decoderR.acc = 0;
- pState->decoderR.output = 0;
- pState->decoderR.x0 = pState->decoderR.x1 = 0;
- pState->decoderR.step = 0;
- pState->hiNibble = EAS_FALSE;
- pState->pitch = 0;
- pState->blockCount = 0;
- pState->gainLeft = PCM_DEFAULT_GAIN_SETTING;
-// pState->currentGainLeft = PCM_DEFAULT_GAIN_SETTING;
- pState->envValue = 0;
- pState->envState = PCM_ENV_START;
-
-#if (NUM_OUTPUT_CHANNELS == 2)
- pState->gainRight = PCM_DEFAULT_GAIN_SETTING;
-// pState->currentGainRight = PCM_DEFAULT_GAIN_SETTING;
-#endif
- pState->state = EAS_STATE_READY;
-
- /* initialize the decoder */
- if (pState->pDecoder->pfInit)
- return (*pState->pDecoder->pfInit)(pEASData, pState);
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * RenderPCMStream()
- *----------------------------------------------------------------------------
- * Purpose:
- * Decodes a buffer of ADPCM data.
- *
- * Inputs:
- *
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT RenderPCMStream (S_EAS_DATA *pEASData, S_PCM_STATE *pState, EAS_I32 numSamples)
-{
- EAS_RESULT result;
- EAS_U32 phaseInc;
- EAS_I32 gainLeft, gainIncLeft;
- EAS_I32 *pOut;
- EAS_I32 temp;
- EAS_U32 utemp;
-
-#if (NUM_OUTPUT_CHANNELS == 2)
- EAS_I32 gainRight, gainIncRight;
-#endif
-
-#if 0
- printf("env data: AR = %d, DR = %d, SL = %d, SR = %d, RR = %d\n",
- ((pState->envData >> 12) & 0x0F),
- ((pState->envData >> 16) & 0x0F),
- ((pState->envData >> 8) & 0x0F),
- ((pState->envData >> 28) & 0x0F),
- ((pState->envData >> 20) & 0x0F));
-#endif
-
- if (pState->envState == PCM_ENV_START)
- {
- //printf("env start\n");
- utemp = ((pState->envData >> 12) & 0x0F);
- //if fastest rate, attack is already completed
- //do the same for slowest rate, since that allows zero to be passed for default envelope
- if (utemp == 0x0F || utemp == 0x00)
- {
- //start envelope at full
- pState->envValue = (32768<<7);
- //jump right into decay
- utemp = ((pState->envData >> 16) & 0x0F);
- pState->envScale = getDecayScale(utemp);
- pState->envState = PCM_ENV_DECAY;
- pState->currentGainLeft = (EAS_I16) FMUL_15x15(pState->gainLeft, pState->volume);
- pState->currentGainRight = (EAS_I16) FMUL_15x15(pState->gainRight, pState->volume);
- }
- //else attack has a ramp
- else
- {
- //start the envelope very low
- pState->envValue = (2<<7);
- pState->currentGainLeft = 0;
- pState->currentGainRight = 0;
- //get envelope attack scaling value
- pState->envScale = getAttackIncrement(utemp);
- //go to attack state
- pState->envState = PCM_ENV_ATTACK;
- }
- }
- if (pState->envState == PCM_ENV_ATTACK)
- {
- //printf("env attack, env value = %d, env scale = %d\n",pState->envValue>>7,pState->envScale);
- //update envelope value
- pState->envValue = pState->envValue + (pState->envScale << 7);
- //check envelope level and update state if needed
- if (pState->envValue >= (32768<<7))
- {
- pState->envValue = (32768<<7);
- utemp = ((pState->envData >> 16) & 0x0F);
- pState->envScale = getDecayScale(utemp);
- pState->envState = PCM_ENV_DECAY;
- }
- }
- else if (pState->envState == PCM_ENV_DECAY)
- {
- //printf("env decay, env value = %d, env scale = %d\n",pState->envValue>>7,pState->envScale);
- //update envelope value
- pState->envValue = (pState->envValue * pState->envScale)>>9;
- //check envelope level against sustain level and update state if needed
- utemp = ((pState->envData >> 8) & 0x0F);
- if (utemp == (EAS_U32)0x0F)
- utemp = (2<<7);
- else
- {
- utemp = ((32769<<7) >> (utemp>>1));
- }
- if (pState->envValue <= utemp)
- {
- utemp = ((pState->envData >> 28) & 0x0F);
- pState->envScale = getDecayScale(utemp); //getSustainScale(utemp);
- pState->envState = PCM_ENV_SUSTAIN;
- }
- }
- else if (pState->envState == PCM_ENV_SUSTAIN)
- {
- //printf("env sustain, env value = %d, env scale = %d\n",pState->envValue>>7,pState->envScale);
- //update envelope value
- pState->envValue = (pState->envValue * pState->envScale)>>9;
- //check envelope level against bottom level and update state if needed
- if (pState->envValue <= (2<<7))
- {
- //no more decay
- pState->envScale = 512;
- pState->envState = PCM_ENV_END;
- }
- }
- else if (pState->envState == PCM_ENV_RELEASE)
- {
- //printf("env release, env value = %d, env scale = %d\n",pState->envValue>>7,pState->envScale);
- //update envelope value
- pState->envValue = (pState->envValue * pState->envScale)>>9;
- //check envelope level against bottom level and update state if needed
- if (pState->envValue <= (2<<7))
- {
- //no more decay
- pState->envScale = 512;
- pState->envState = PCM_ENV_END;
- }
- }
- else if (pState->envState == PCM_ENV_END)
- {
- //printf("env end\n");
- /* set state to stopping, already ramped down */
- pState->state = EAS_STATE_STOPPING;
- }
-
- //pState->gainLeft = (EAS_U16)((pState->gainLeft * (pState->envValue>>7))>>15);
- //pState->gainRight = (EAS_U16)((pState->gainRight * (pState->envValue>>7))>>15);
-
- /* gain to 32-bits to increase resolution on anti-zipper filter */
- /*lint -e{703} use shift for performance */
- gainLeft = (EAS_I32) pState->currentGainLeft << SYNTH_UPDATE_PERIOD_IN_BITS;
-#if (NUM_OUTPUT_CHANNELS == 2)
- /*lint -e{703} use shift for performance */
- gainRight = (EAS_I32) pState->currentGainRight << SYNTH_UPDATE_PERIOD_IN_BITS;
-#endif
-
- /* calculate a new gain increment, gain target is zero if pausing */
- if ((pState->state == EAS_STATE_PAUSING) || (pState->state == EAS_STATE_PAUSED))
- {
- gainIncLeft = -pState->currentGainLeft;
-#if (NUM_OUTPUT_CHANNELS == 2)
- gainIncRight= -pState->currentGainRight;
-#endif
- }
- else
- {
- EAS_I32 gain = FMUL_15x15(pState->envValue >> 7, pState->volume);
- gainIncLeft = FMUL_15x15(pState->gainLeft, gain) - pState->currentGainLeft;
-#if (NUM_OUTPUT_CHANNELS == 2)
- gainIncRight = FMUL_15x15(pState->gainRight, gain) - pState->currentGainRight;
-#endif
- }
-
- /* calculate phase increment */
- phaseInc = pState->basefreq;
-
- /* convert pitch cents to linear multiplier */
- if (pState->pitch)
- {
- temp = EAS_Calculate2toX(pState->pitch);
- phaseInc = FMUL_15x15(phaseInc, temp);
- }
- phaseInc = phaseInc << pState->rateShift;
-
- /* pointer to mix buffer */
- pOut = pEASData->pMixBuffer;
-
- /* render a buffer of samples */
- while (numSamples--)
- {
-
- /* interpolate an output sample */
- pState->decoderL.output = pState->decoderL.x0 + FMUL_15x15((pState->decoderL.x1 - pState->decoderL.x0), pState->phase & PHASE_FRAC_MASK);
-
- /* stereo output */
-#if (NUM_OUTPUT_CHANNELS == 2)
-
- /* stereo stream? */
- if (pState->flags & PCM_FLAGS_STEREO)
- pState->decoderR.output = pState->decoderR.x0 + FMUL_15x15((pState->decoderR.x1 - pState->decoderR.x0), pState->phase & PHASE_FRAC_MASK);
-
- /* gain scale and mix */
- /*lint -e{704} use shift instead of division */
- *pOut++ += (pState->decoderL.output * (gainLeft >> SYNTH_UPDATE_PERIOD_IN_BITS)) >> PCM_MIXER_GUARD_BITS;
- gainLeft += gainIncLeft;
-
- /*lint -e{704} use shift instead of division */
- if (pState->flags & PCM_FLAGS_STEREO)
- *pOut++ += (pState->decoderR.output * (gainRight >> SYNTH_UPDATE_PERIOD_IN_BITS)) >> PCM_MIXER_GUARD_BITS;
- else
- *pOut++ += (pState->decoderL.output * (gainRight >> SYNTH_UPDATE_PERIOD_IN_BITS)) >> PCM_MIXER_GUARD_BITS;
-
- gainRight += gainIncRight;
-
- /* mono output */
-#else
- /* if stereo stream, decode right channel and mix to mono */
- if (pState->flags & PCM_FLAGS_STEREO)
- {
- pState->decoderR.output= pState->decoderR.x0 + FMUL_15x15((pState->decoderR.x1 - pState->decoderR.x0), pState->phase & PHASE_FRAC_MASK);
-
- /* for mono, sum stereo ADPCM to mono */
- /*lint -e{704} use shift instead of division */
- *pOut++ += ((pState->decoderL.output + pState->decoderR.output) * (gainLeft >> SYNTH_UPDATE_PERIOD_IN_BITS)) >> PCM_MIXER_GUARD_BITS;
- }
- else
- /*lint -e{704} use shift instead of division */
- *pOut++ += (pState->decoderL.output * (gainLeft >> SYNTH_UPDATE_PERIOD_IN_BITS)) >> PCM_MIXER_GUARD_BITS;
-
- gainLeft += gainIncLeft;
-#endif
-
- /* advance phase accumulator */
- pState->phase += phaseInc;
-
- /* if integer part of phase accumulator is non-zero, advance to next sample */
- while (pState->phase & ~PHASE_FRAC_MASK)
- {
- pState->decoderL.x0 = pState->decoderL.x1;
- pState->decoderR.x0 = pState->decoderR.x1;
-
- /* give the source a chance to continue the stream */
- if (!pState->bytesLeft && pState->pCallback && ((pState->flags & PCM_FLAGS_EMPTY) == 0))
- {
- pState->flags |= PCM_FLAGS_EMPTY;
- (*pState->pCallback)(pEASData, pState->cbInstData, pState, EAS_STATE_EMPTY);
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "RenderPCMStream: After empty callback, bytesLeft = %d\n", pState->bytesLeft); */ }
- }
-
- /* decode the next sample */
- if ((result = (*pState->pDecoder->pfDecodeSample)(pEASData, pState)) != EAS_SUCCESS)
- return result;
-
- /* adjust phase by one sample */
- pState->phase -= (1L << NUM_PHASE_FRAC_BITS);
- }
-
- }
-
- /* save new gain */
- /*lint -e{704} use shift instead of division */
- pState->currentGainLeft = (EAS_I16) (gainLeft >> SYNTH_UPDATE_PERIOD_IN_BITS);
-
-#if (NUM_OUTPUT_CHANNELS == 2)
- /*lint -e{704} use shift instead of division */
- pState->currentGainRight = (EAS_I16) (gainRight >> SYNTH_UPDATE_PERIOD_IN_BITS);
-#endif
-
- /* if pausing, set new state and notify */
- if (pState->state == EAS_STATE_PAUSING)
- {
- pState->state = EAS_STATE_PAUSED;
- if (pState->pCallback)
- (*pState->pCallback)(pEASData, pState->cbInstData, pState, pState->state);
- }
-
- /* if out of data, set stopped state and notify */
- if (pState->bytesLeft == 0 || pState->state == EAS_STATE_STOPPING)
- {
- pState->state = EAS_STATE_STOPPED;
-
- /* do callback unless the file has already been closed */
- if (pState->pCallback && pState->fileHandle)
- (*pState->pCallback)(pEASData, pState->cbInstData, pState, pState->state);
- }
-
- if (pState->state == EAS_STATE_READY)
- pState->state = EAS_STATE_PLAY;
-
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * LinearPCMDecode()
- *----------------------------------------------------------------------------
- * Purpose:
- * Decodes a PCM sample
- *
- * Inputs:
- *
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT LinearPCMDecode (EAS_DATA_HANDLE pEASData, S_PCM_STATE *pState)
-{
- EAS_RESULT result;
- EAS_HW_DATA_HANDLE hwInstData;
-
- hwInstData = ((S_EAS_DATA*) pEASData)->hwInstData;
-
- /* if out of data, check for loop */
- if ((pState->bytesLeft == 0) && (pState->loopSamples != 0))
- {
- if ((result = EAS_HWFileSeek(pEASData->hwInstData, pState->fileHandle, (EAS_I32) (pState->startPos + pState->loopLocation))) != EAS_SUCCESS)
- return result;
- pState->bytesLeft = pState->byteCount = (EAS_I32) pState->bytesLeftLoop;
- pState->flags &= ~PCM_FLAGS_EMPTY;
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "LinearPCMDecode: Rewind file to %d, bytesLeft = %d\n", pState->startPos, pState->bytesLeft); */ }
- }
-
- if (pState->bytesLeft)
- {
-
- /* check format byte for 8-bit samples */
- if (pState->flags & PCM_FLAGS_8_BIT)
- {
- /* fetch left or mono sample */
- if ((result = EAS_HWGetByte(hwInstData, pState->fileHandle, &pState->srcByte)) != EAS_SUCCESS)
- return result;
-
- /* if unsigned */
- if (pState->flags & PCM_FLAGS_UNSIGNED)
- {
- /*lint -e{734} converting unsigned 8-bit to signed 16-bit */
- pState->decoderL.x1 = (EAS_PCM)(((EAS_PCM) pState->srcByte << 8) ^ 0x8000);
- }
- else
- {
- /*lint -e{734} converting signed 8-bit to signed 16-bit */
- pState->decoderL.x1 = (EAS_PCM)((EAS_PCM) pState->srcByte << 8);
- }
- pState->bytesLeft--;
-
- /* fetch right sample */
- if(pState->flags & PCM_FLAGS_STEREO)
- {
- if ((result = EAS_HWGetByte(hwInstData, pState->fileHandle, &pState->srcByte)) != EAS_SUCCESS)
- return result;
-
- /* if unsigned */
- if (pState->flags & PCM_FLAGS_UNSIGNED)
- {
- /*lint -e{734} converting unsigned 8-bit to signed 16-bit */
- pState->decoderR.x1 = (EAS_PCM)(((EAS_PCM) pState->srcByte << 8) ^ 0x8000);
- }
- else
- {
- /*lint -e{734} converting signed 8-bit to signed 16-bit */
- pState->decoderR.x1 = (EAS_PCM)((EAS_PCM) pState->srcByte << 8);
- }
- pState->bytesLeft--;
- }
- }
-
- /* must be 16-bit samples */
- else
- {
- //unsigned 16 bit currently not supported
- if (pState->flags & PCM_FLAGS_UNSIGNED)
- {
- return EAS_ERROR_INVALID_PCM_TYPE;
- }
-
- /* fetch left or mono sample */
- if ((result = EAS_HWGetWord(hwInstData, pState->fileHandle, &pState->decoderL.x1, EAS_FALSE)) != EAS_SUCCESS)
- return result;
- pState->bytesLeft -= 2;
-
- /* fetch right sample */
- if(pState->flags & PCM_FLAGS_STEREO)
- {
- if ((result = EAS_HWGetWord(hwInstData, pState->fileHandle, &pState->decoderR.x1, EAS_FALSE)) != EAS_SUCCESS)
- return result;
- pState->bytesLeft -= 2;
- }
- }
- }
-
- /* no more data, force zero samples */
- else
- pState->decoderL.x1 = pState->decoderR.x1 = 0;
-
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * LinearPCMLocate()
- *----------------------------------------------------------------------------
- * Purpose:
- * Locate in a linear PCM stream
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT LinearPCMLocate (EAS_DATA_HANDLE pEASData, S_PCM_STATE *pState, EAS_I32 time)
-{
- EAS_RESULT result;
- EAS_I32 temp;
- EAS_I32 secs, msecs;
- EAS_INT shift;
-
- /* calculate size of sample frame */
- if (pState->flags & PCM_FLAGS_8_BIT)
- shift = 0;
- else
- shift = 1;
- if (pState->flags & PCM_FLAGS_STEREO)
- shift++;
-
- /* break down into secs and msecs */
- secs = time / 1000;
- msecs = time - (secs * 1000);
-
- /* calculate sample number fraction from msecs */
- temp = (msecs * pState->sampleRate);
- temp = (temp >> 10) + ((temp * 49) >> 21);
-
- /* add integer sample count */
- temp += secs * pState->sampleRate;
-
- /* calculate the position based on sample frame size */
- /*lint -e{703} use shift for performance */
- temp <<= shift;
-
- /* past end of sample? */
- if (temp > (EAS_I32) pState->loopStart)
- {
- /* if not looped, flag error */
- if (pState->loopSamples == 0)
- {
- pState->bytesLeft = 0;
- pState->flags |= PCM_FLAGS_EMPTY;
- return EAS_ERROR_LOCATE_BEYOND_END;
- }
-
- /* looped sample - calculate position in loop */
- while (temp > (EAS_I32) pState->loopStart)
- temp -= (EAS_I32) pState->loopStart;
- }
-
- /* seek to new position */
- if ((result = EAS_PESeek(pEASData, pState, &temp)) != EAS_SUCCESS)
- return result;
-
- /* reset state */
- if ((pState->state != EAS_STATE_PAUSING) && (pState->state != EAS_STATE_PAUSED))
- pState->state = EAS_STATE_READY;
-
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * EAS_PESeek
- *----------------------------------------------------------------------------
- * Purpose:
- * Locate to a particular byte in a PCM stream
- *----------------------------------------------------------------------------
- * This bit is tricky because the chunks may not be contiguous,
- * so we have to rely on the parser to position in the file. We
- * do this by seeking to the end of each chunk and simulating an
- * empty buffer condition until we get to where we want to go.
- *
- * A better solution would be a parser API for re-positioning,
- * but there isn't time at the moment to re-factor all the
- * parsers to support a new API.
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT EAS_PESeek (S_EAS_DATA *pEASData, S_PCM_STATE *pState, EAS_I32 *pLocation)
-{
- EAS_RESULT result;
-
- /* seek to start of audio */
- if ((result = EAS_HWFileSeek(pEASData->hwInstData, pState->fileHandle, pState->startPos)) != EAS_SUCCESS)
- {
- pState->state = EAS_STATE_ERROR;
- return result;
- }
- pState->bytesLeft = pState->bytesLeftLoop;
-
- /* skip through chunks until we find the right chunk */
- while (*pLocation > (EAS_I32) pState->bytesLeft)
- {
- /* seek to end of audio chunk */
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "EAS_PESeek: Seek to offset = %d\n", pState->bytesLeft); */ }
- if ((result = EAS_HWFileSeekOfs(pEASData->hwInstData, pState->fileHandle, pState->bytesLeft)) != EAS_SUCCESS)
- {
- pState->state = EAS_STATE_ERROR;
- return result;
- }
- *pLocation -= pState->bytesLeft;
- pState->bytesLeft = 0;
- pState->flags |= PCM_FLAGS_EMPTY;
-
- /* retrieve more data */
- if (pState->pCallback)
- (*pState->pCallback)(pEASData, pState->cbInstData, pState, EAS_STATE_EMPTY);
-
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "EAS_PESeek: bytesLeft=%d, byte location = %d\n", pState->bytesLeft, *pLocation); */ }
-
- /* no more samples */
- if (pState->bytesLeft == 0)
- return EAS_ERROR_LOCATE_BEYOND_END;
- }
-
- /* seek to new offset in current chunk */
- if (*pLocation > 0)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "EAS_PESeek: Seek to offset = %d\n", *pLocation); */ }
- if ((result = EAS_HWFileSeekOfs(pEASData->hwInstData, pState->fileHandle, *pLocation)) != EAS_SUCCESS)
- {
- pState->state = EAS_STATE_ERROR;
- return result;
- }
-
- /* if not streamed, calculate number of bytes left */
- if (pState->flags & PCM_FLAGS_STREAMING)
- pState->bytesLeft = 0x7fffffff;
- else
- pState->bytesLeft -= *pLocation;
- }
- return EAS_SUCCESS;
-}
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 849 $
+ * $Date: 2007-08-28 08:59:11 -0700 (Tue, 28 Aug 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+#include "eas_data.h"
+#include "eas_report.h"
+#include "eas_host.h"
+#include "eas_config.h"
+#include "eas_parser.h"
+#include "eas_pcm.h"
+#include "eas_math.h"
+#include "eas_mixer.h"
+
+#define PCM_MIXER_GUARD_BITS (NUM_MIXER_GUARD_BITS + 1)
+
+/*----------------------------------------------------------------------------
+ * Decoder interfaces
+ *----------------------------------------------------------------------------
+*/
+
+static EAS_RESULT LinearPCMDecode (EAS_DATA_HANDLE pEASData, S_PCM_STATE *pState);
+static EAS_RESULT LinearPCMLocate (EAS_DATA_HANDLE pEASData, S_PCM_STATE *pState, EAS_I32 time);
+
+static const S_DECODER_INTERFACE PCMDecoder =
+{
+ NULL,
+ LinearPCMDecode,
+ LinearPCMLocate,
+};
+
+/* SMAF ADPCM decoder */
+#ifdef _SMAF_PARSER
+extern S_DECODER_INTERFACE SmafDecoder;
+#define SMAF_DECODER &SmafDecoder
+extern S_DECODER_INTERFACE Smaf7BitDecoder;
+#define SMAF_7BIT_DECODER &Smaf7BitDecoder
+#else
+#define SMAF_DECODER NULL
+#define SMAF_7BIT_DECODER NULL
+#endif
+
+/* IMA ADPCM decoder */
+#ifdef _IMA_DECODER
+extern S_DECODER_INTERFACE IMADecoder;
+#define IMA_DECODER &IMADecoder
+#else
+#define IMA_DECODER NULL
+#endif
+
+static const S_DECODER_INTERFACE * const decoders[] =
+{
+ &PCMDecoder,
+ SMAF_DECODER,
+ IMA_DECODER,
+ SMAF_7BIT_DECODER
+};
+
+/*----------------------------------------------------------------------------
+ * Sample rate conversion
+ *----------------------------------------------------------------------------
+*/
+
+#define SRC_RATE_MULTIPLER (0x40000000 / _OUTPUT_SAMPLE_RATE)
+
+#ifdef _LOOKUP_SAMPLE_RATE
+static const EAS_U32 srcConvRate[][2] =
+{
+ 4000L, (4000L << 15) / _OUTPUT_SAMPLE_RATE,
+ 8000L, (8000L << 15) / _OUTPUT_SAMPLE_RATE,
+ 11025L, (11025L << 15) / _OUTPUT_SAMPLE_RATE,
+ 12000L, (12000L << 15) / _OUTPUT_SAMPLE_RATE,
+ 16000L, (16000L << 15) / _OUTPUT_SAMPLE_RATE,
+ 22050L, (22050L << 15) / _OUTPUT_SAMPLE_RATE,
+ 24000L, (24000L << 15) / _OUTPUT_SAMPLE_RATE,
+ 32000L, (32000L << 15) / _OUTPUT_SAMPLE_RATE
+};
+static EAS_U32 CalcBaseFreq (EAS_U32 sampleRate);
+#define SRC_CONV_RATE_ENTRIES (sizeof(srcConvRate)/sizeof(EAS_U32)/2)
+#endif
+
+
+/* interface prototypes */
+static EAS_RESULT RenderPCMStream (S_EAS_DATA *pEASData, S_PCM_STATE *pState, EAS_I32 numSamples);
+
+
+/* local prototypes */
+static S_PCM_STATE *FindSlot (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle, EAS_PCM_CALLBACK pCallbackFunc, EAS_VOID_PTR cbInstData);
+static EAS_RESULT InitPCMStream (S_EAS_DATA *pEASData, S_PCM_STATE *pState);
+
+/*----------------------------------------------------------------------------
+ * EAS_PEInit()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Initializes the PCM engine
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_PEInit (S_EAS_DATA *pEASData)
+{
+ S_PCM_STATE *pState;
+ EAS_INT i;
+
+ /* check for static memory allocation */
+ if (pEASData->staticMemoryModel)
+ pEASData->pPCMStreams = EAS_CMEnumData(EAS_CM_PCM_DATA);
+ /* allocate dynamic memory */
+ else
+ pEASData->pPCMStreams = EAS_HWMalloc(pEASData->hwInstData, sizeof(S_PCM_STATE) * MAX_PCM_STREAMS);
+
+ if (!pEASData->pPCMStreams)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_FATAL, "Failed to allocate memory for PCM streams\n"); */ }
+ return EAS_ERROR_MALLOC_FAILED;
+ }
+
+ //zero the memory to insure complete initialization
+ EAS_HWMemSet((void *)(pEASData->pPCMStreams),0, sizeof(S_PCM_STATE) * MAX_PCM_STREAMS);
+
+ /* initialize the state data */
+ for (i = 0, pState = pEASData->pPCMStreams; i < MAX_PCM_STREAMS; i++, pState++)
+ pState->fileHandle = NULL;
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_PEShutdown()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Shuts down the PCM engine
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_PEShutdown (S_EAS_DATA *pEASData)
+{
+
+ /* free any dynamic memory */
+ if (!pEASData->staticMemoryModel)
+ {
+ if (pEASData->pPCMStreams)
+ {
+ EAS_HWFree(pEASData->hwInstData, pEASData->pPCMStreams);
+ pEASData->pPCMStreams = NULL;
+ }
+ }
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_PERender()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Render a buffer of PCM audio
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_PERender (S_EAS_DATA* pEASData, EAS_I32 numSamples)
+{
+ S_PCM_STATE *pState;
+ EAS_RESULT result;
+ EAS_INT i;
+
+ /* render all the active streams */
+ for (i = 0, pState = pEASData->pPCMStreams; i < MAX_PCM_STREAMS; i++, pState++)
+ {
+ if ((pState->fileHandle) && (pState->state != EAS_STATE_STOPPED) && (pState->state != EAS_STATE_PAUSED))
+ if ((result = RenderPCMStream(pEASData, pState, numSamples)) != EAS_SUCCESS)
+ return result;
+ }
+ return EAS_SUCCESS;
+}
+
+
+/*----------------------------------------------------------------------------
+ * EAS_PEState()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Returns the current state of the stream
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ * pState - pointer to variable to store state
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ * Notes:
+ * This interface is also exposed in the internal library for use by the other modules.
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pEASData) reserved for future use */
+EAS_RESULT EAS_PEState (S_EAS_DATA *pEASData, EAS_PCM_HANDLE pInstData, EAS_STATE *pState)
+{
+ /* return current state */
+ *pState = pInstData->state;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_PEClose()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Close the file and clean up
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_PEClose (S_EAS_DATA *pEASData, EAS_PCM_HANDLE pState)
+{
+ EAS_RESULT result;
+
+ if ((result = EAS_HWCloseFile(pEASData->hwInstData, pState->fileHandle)) != EAS_SUCCESS)
+ return result;
+
+ pState->fileHandle = NULL;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * PCM_Reset()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Reset the sequencer. Used for locating backwards in the file.
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_PEReset (S_EAS_DATA *pEASData, EAS_PCM_HANDLE pState)
+{
+ EAS_RESULT result;
+
+ /* reset file position to first byte of data in the stream */
+ if ((result = EAS_HWFileSeek(pEASData->hwInstData, pState->fileHandle, pState->startPos)) != EAS_SUCCESS)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Error %d seeking to start of PCM file\n", result); */ }
+ return result;
+ }
+
+ /* re-initialize stream */
+ return InitPCMStream(pEASData, pState);
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_PEOpenStream()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Starts up a PCM playback
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_PEOpenStream (S_EAS_DATA *pEASData, S_PCM_OPEN_PARAMS *pParams, EAS_PCM_HANDLE *pHandle)
+{
+ EAS_RESULT result;
+ S_PCM_STATE *pState;
+ EAS_I32 filePos;
+
+ /* make sure we support this decoder */
+ if (pParams->decoder >= NUM_DECODER_MODULES)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Decoder selector out of range\n"); */ }
+ return EAS_ERROR_PARAMETER_RANGE;
+ }
+ if (decoders[pParams->decoder] == NULL)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Decoder module not available\n"); */ }
+ return EAS_ERROR_FEATURE_NOT_AVAILABLE;
+ }
+
+ /* find a slot for the new stream */
+ if ((pState = FindSlot(pEASData, pParams->fileHandle, pParams->pCallbackFunc, pParams->cbInstData)) == NULL)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Unable to open ADPCM stream, too many streams open\n"); */ }
+ return EAS_ERROR_MAX_PCM_STREAMS;
+ }
+
+ /* get the current file position */
+ if ((result = EAS_HWFilePos(pEASData->hwInstData, pState->fileHandle, &filePos)) != EAS_SUCCESS)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "EAS_HWFilePos returned %ld\n",result); */ }
+ pState->fileHandle = NULL;
+ return result;
+ }
+
+ pState->pDecoder = decoders[pParams->decoder];
+ pState->startPos = filePos;
+ pState->bytesLeftLoop = pState->byteCount = pParams->size;
+ pState->loopStart = pParams->loopStart;
+ pState->samplesTilLoop = (EAS_I32) pState->loopStart;
+ pState->loopSamples = pParams->loopSamples;
+ pState->samplesInLoop = 0;
+ pState->blockSize = (EAS_U16) pParams->blockSize;
+ pState->flags = pParams->flags;
+ pState->envData = pParams->envData;
+ pState->volume = pParams->volume;
+ pState->sampleRate = (EAS_U16) pParams->sampleRate;
+
+ /* set the base frequency */
+ pState->basefreq = (SRC_RATE_MULTIPLER * (EAS_U32) pParams->sampleRate) >> 15;
+
+ /* calculate shift for frequencies > 1.0 */
+ pState->rateShift = 0;
+ while (pState->basefreq > 32767)
+ {
+ pState->basefreq = pState->basefreq >> 1;
+ pState->rateShift++;
+ }
+
+ /* initialize */
+ if ((result = InitPCMStream(pEASData, pState)) != EAS_SUCCESS)
+ return result;
+
+ *pHandle = pState;
+
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "EAS_PEOpenStream: StartPos=%d, byteCount = %d, loopSamples=%d\n",
+ pState->startPos, pState->byteCount, pState->loopSamples); */ }
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_PEContinueStream()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Continues a PCM stream
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -e{715} reserved for future use */
+EAS_RESULT EAS_PEContinueStream (S_EAS_DATA *pEASData, EAS_PCM_HANDLE pState, EAS_I32 size)
+{
+
+ /* add new samples to count */
+ pState->bytesLeft += size;
+ if (pState->bytesLeft > 0)
+ pState->flags &= ~PCM_FLAGS_EMPTY;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_PEGetFileHandle()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Returns the file handle of a stream
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pEASData) reserved for future use */
+EAS_RESULT EAS_PEGetFileHandle (S_EAS_DATA *pEASData, EAS_PCM_HANDLE pState, EAS_FILE_HANDLE *pFileHandle)
+{
+ *pFileHandle = pState->fileHandle;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_PEUpdateParams()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Update the pitch and volume parameters for a PCM stream
+ *
+ * Inputs:
+ * pEASData - pointer to EAS library instance data
+ * handle - pointer to S_PCM_STATE for this stream
+ * gainLeft - linear gain multipler in 1.15 fraction format
+ * gainRight - linear gain multipler in 1.15 fraction format
+ * pitch - pitch shift in cents
+ * initial - initial settings, set current gain
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ * Notes
+ * In mono mode, leftGain controls the output gain and rightGain is ignored
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pEASData) reserved for future use */
+/*lint -esym(715, gainRight) used only in 2-channel version */
+EAS_RESULT EAS_PEUpdateParams (S_EAS_DATA* pEASData, EAS_PCM_HANDLE pState, EAS_I16 pitch, EAS_I16 gainLeft, EAS_I16 gainRight)
+{
+
+ pState->gainLeft = gainLeft;
+
+#if (NUM_OUTPUT_CHANNELS == 2)
+ pState->gainRight = gainRight;
+#endif
+
+ pState->pitch = pitch;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_PELocate()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * This function seeks to the requested place in the file. Accuracy
+ * is dependent on the sample rate and block size.
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * pState - stream handle
+ * time - media time in milliseconds
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_PELocate (S_EAS_DATA *pEASData, EAS_PCM_HANDLE pState, EAS_I32 time)
+{
+ if (pState->pDecoder->pfLocate == NULL)
+ return EAS_ERROR_FEATURE_NOT_AVAILABLE;
+
+ return pState->pDecoder->pfLocate(pEASData, pState, time);
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_PEUpdateVolume()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Update the volume parameters for a PCM stream
+ *
+ * Inputs:
+ * pEASData - pointer to EAS library instance data
+ * handle - pointer to S_PCM_STATE for this stream
+ * gainLeft - linear gain multipler in 1.15 fraction format
+ * gainRight - linear gain multipler in 1.15 fraction format
+ * initial - initial settings, set current gain
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ * Notes
+ * In mono mode, leftGain controls the output gain and rightGain is ignored
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pEASData) reserved for future use */
+EAS_RESULT EAS_PEUpdateVolume (S_EAS_DATA* pEASData, EAS_PCM_HANDLE pState, EAS_I16 volume)
+{
+ pState->volume = volume;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_PEUpdatePitch()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Update the pitch parameter for a PCM stream
+ *
+ * Inputs:
+ * pEASData - pointer to EAS library instance data
+ * pState - pointer to S_PCM_STATE for this stream
+ * pitch - new pitch value in pitch cents
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pEASData) reserved for future use */
+EAS_RESULT EAS_PEUpdatePitch (S_EAS_DATA* pEASData, EAS_PCM_HANDLE pState, EAS_I16 pitch)
+{
+ pState->pitch = pitch;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_PEPause()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Mute and stop rendering a PCM stream. Sets the gain target to zero and stops the playback
+ * at the end of the next audio frame.
+ *
+ * Inputs:
+ * pEASData - pointer to EAS library instance data
+ * handle - pointer to S_PCM_STATE for this stream
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pEASData) reserved for future use */
+EAS_RESULT EAS_PEPause (S_EAS_DATA *pEASData, EAS_PCM_HANDLE pState)
+{
+ /* set state to stopping */
+ pState->state = EAS_STATE_PAUSING;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_PEResume()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Resume rendering a PCM stream. Sets the gain target back to its
+ * previous setting and restarts playback at the end of the next audio
+ * frame.
+ *
+ * Inputs:
+ * pEASData - pointer to EAS library instance data
+ * handle - pointer to S_PCM_STATE for this stream
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pEASData) reserved for future use */
+EAS_RESULT EAS_PEResume (S_EAS_DATA *pEASData, EAS_PCM_HANDLE pState)
+{
+ /* set state to stopping */
+ pState->state = EAS_STATE_PLAY;
+ return EAS_SUCCESS;
+}
+
+EAS_U32 getDecayScale(EAS_U32 index)
+{
+ EAS_U32 utemp;
+
+ //envelope decay segment
+ switch (index)
+ {
+ case 0: //no decay
+ utemp = 512;//32768;
+ break;
+ case 1: //.0156 dB per update
+ utemp = 511;//32709;
+ break;
+ case 2: //.03125
+ utemp = 510;//32649;
+ break;
+ case 3: //.0625
+ utemp = 508;//32532;
+ break;
+ case 4: //.125
+ utemp = 505;//32298;
+ break;
+ case 5: //.25
+ utemp = 497;//31835;
+ break;
+ case 6: //.5
+ utemp = 483;//30929;
+ break;
+ case 7: //1.0
+ utemp = 456;//29193;
+ break;
+ case 8: //2.0
+ utemp = 406;//26008;
+ break;
+ case 9: //4.0
+ utemp = 323;//20642;
+ break;
+ case 10: //8.0
+ utemp = 203;//13004;
+ break;
+ case 11: //16.0
+ utemp = 81;//5160;
+ break;
+ case 12: //32.0
+ utemp = 13;//813;
+ break;
+ case 13: //64.0
+ utemp = 0;//20;
+ break;
+ case 14: //128.0
+ utemp = 0;
+ break;
+ case 15: //256.0
+ default:
+ utemp = 0;
+ break;
+ }
+ //printf("getdecayscale returned %d\n",utemp);
+ return utemp;
+}
+
+EAS_U32 getAttackIncrement(EAS_U32 index)
+{
+ EAS_U32 utemp;
+
+ //envelope decay segment
+ switch (index)
+ {
+ case 0:
+ utemp = 32;
+ break;
+ case 1:
+ utemp = 64;
+ break;
+ case 2:
+ utemp = 128;
+ break;
+ case 3:
+ utemp = 256;
+ break;
+ case 4:
+ utemp = 512;
+ break;
+ case 5:
+ utemp = 1024;
+ break;
+ case 6:
+ utemp = 2048;
+ break;
+ case 7:
+ utemp = 4096;
+ break;
+ case 8:
+ utemp = 8192;
+ break;
+ case 9:
+ utemp = 16384;
+ break;
+ case 10:
+ utemp = 32768;
+ break;
+ case 11:
+ utemp = 65536;
+ break;
+ case 12:
+ utemp = 65536;
+ break;
+ case 13:
+ utemp = 65536;
+ break;
+ case 14:
+ utemp = 65535;
+ break;
+ case 15:
+ default:
+ utemp = 0;
+ break;
+ }
+ //printf("getattackincrement returned %d\n",utemp);
+ return utemp;
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_PERelease()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Put the PCM stream envelope into release.
+ *
+ * Inputs:
+ * pEASData - pointer to EAS library instance data
+ * handle - pointer to S_PCM_STATE for this stream
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pEASData) reserved for future use */
+EAS_RESULT EAS_PERelease (S_EAS_DATA *pEASData, EAS_PCM_HANDLE pState)
+{
+ EAS_U32 utemp;
+
+ //printf("handling note-off part of envelope\n");
+ /*if the note is not ignore release or sustained*/
+ if (((pState->envData >> 24) & 0x0F)==0)
+ {
+ /* set envelope state to release */
+ pState->envState = PCM_ENV_RELEASE;
+ utemp = ((pState->envData >> 20) & 0x0F);
+ pState->envScale = getDecayScale(utemp); //getReleaseScale(utemp);
+ }
+ else
+ {
+ /*else change envelope state to sustain */
+ pState->envState = PCM_ENV_SUSTAIN;
+ utemp = ((pState->envData >> 28) & 0x0F);
+ pState->envScale = getDecayScale(utemp); //getSustainScale(utemp);
+ }
+ //since we are in release, don't let anything hang around too long
+ //printf("checking env scale, val = %d\n",((S_PCM_STATE*) handle)->envScale);
+ if (pState->envScale > 505)
+ pState->envScale = 505;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * FindSlot()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Locates an empty stream slot and assigns the file handle
+ *
+ * Inputs:
+ * pEASData - pointer to EAS library instance data
+ * fileHandle - file handle
+ * pCallbackFunc - function to be called back upon EAS_STATE_STOPPED
+ *
+ * Outputs:
+ * returns handle to slot or NULL if all slots are used
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static S_PCM_STATE *FindSlot (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle, EAS_PCM_CALLBACK pCallbackFunc, EAS_VOID_PTR cbInstData)
+{
+ EAS_INT i;
+ S_PCM_STATE *pState;
+
+#ifndef NO_PCM_STEAL
+ S_PCM_STATE *foundState = NULL;
+ EAS_INT count = 0;
+ EAS_U32 startOrder = 0xFFFFFFFF;
+ S_PCM_STATE *stealState = NULL;
+ EAS_U32 youngest = 0;
+
+ /* find an empty slot, count total in use, and find oldest in use (lowest start order) */
+ for (i = 0, pState = pEASData->pPCMStreams; i < MAX_PCM_STREAMS; i++, pState++)
+ {
+ /* if this one is available */
+ if (pState->fileHandle == NULL)
+ {
+ foundState = pState;
+ }
+ /* else this one is in use, so see if it is the oldest, and count total in use */
+ /* also find youngest */
+ else
+ {
+ /*one more voice in use*/
+ count++;
+ /* is this the oldest? (lowest start order) */
+ if ((pState->state != EAS_STATE_STOPPING) && (pState->startOrder < startOrder))
+ {
+ /* remember this one */
+ stealState = pState;
+ /* remember the oldest so far */
+ startOrder = pState->startOrder;
+ }
+ /* is this the youngest? (highest start order) */
+ if (pState->startOrder >= youngest)
+ {
+ youngest = pState->startOrder;
+ }
+ }
+ }
+
+ /* if there are too many voices active, stop the oldest one */
+ if (count > PCM_STREAM_THRESHOLD)
+ {
+ //printf("stealing!!!\n");
+ /* make sure we got one, although we should always have one at this point */
+ if (stealState != NULL)
+ {
+ //flag this as stopping, so it will get shut off
+ stealState->state = EAS_STATE_STOPPING;
+ }
+ }
+
+ /* if there are no available open streams (we won't likely see this, due to stealing) */
+ if (foundState == NULL)
+ return NULL;
+
+ /* save info */
+ foundState->startOrder = youngest + 1;
+ foundState->fileHandle = fileHandle;
+ foundState->pCallback = pCallbackFunc;
+ foundState->cbInstData = cbInstData;
+ return foundState;
+#else
+ /* find an empty slot*/
+ for (i = 0; i < MAX_PCM_STREAMS; i++)
+ {
+ pState = &pEASData->pPCMStreams[i];
+ if (pState->fileHandle != NULL)
+ continue;
+
+ pState->fileHandle = fileHandle;
+ pState->pCallback = pCallbackFunc;
+ pState->cbInstData = cbInstData;
+ return pState;
+ }
+ return NULL;
+#endif
+}
+
+#ifdef _LOOKUP_SAMPLE_RATE
+/*----------------------------------------------------------------------------
+ * CalcBaseFreq()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Calculates the fractional phase increment for the sample rate converter
+ *
+ * Inputs:
+ * sampleRate - sample rate in samples/sec
+ *
+ * Outputs:
+ * Returns fractional sample rate with a 15-bit fraction
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_U32 CalcBaseFreq (EAS_U32 sampleRate)
+{
+ EAS_INT i;
+
+ /* look up the conversion rate */
+ for (i = 0; i < (EAS_INT)(SRC_CONV_RATE_ENTRIES); i ++)
+ {
+ if (srcConvRate[i][0] == sampleRate)
+ return srcConvRate[i][1];
+ }
+
+ /* if not found in table, do it the long way */
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Sample rate %u not in table, calculating by division\n", sampleRate); */ }
+
+ return (SRC_RATE_MULTIPLER * (EAS_U32) sampleRate) >> 15;
+}
+#endif
+
+/*----------------------------------------------------------------------------
+ * InitPCMStream()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Start an ADPCM stream playback. Decodes the header, preps the engine.
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT InitPCMStream (S_EAS_DATA *pEASData, S_PCM_STATE *pState)
+{
+
+ /* initialize the data structure */
+ pState->bytesLeft = pState->byteCount;
+ pState->phase = 0;
+ pState->srcByte = 0;
+ pState->decoderL.acc = 0;
+ pState->decoderL.output = 0;
+ pState->decoderL.x0 = pState->decoderL.x1 = 0;
+ pState->decoderL.step = 0;
+ pState->decoderR.acc = 0;
+ pState->decoderR.output = 0;
+ pState->decoderR.x0 = pState->decoderR.x1 = 0;
+ pState->decoderR.step = 0;
+ pState->hiNibble = EAS_FALSE;
+ pState->pitch = 0;
+ pState->blockCount = 0;
+ pState->gainLeft = PCM_DEFAULT_GAIN_SETTING;
+// pState->currentGainLeft = PCM_DEFAULT_GAIN_SETTING;
+ pState->envValue = 0;
+ pState->envState = PCM_ENV_START;
+
+#if (NUM_OUTPUT_CHANNELS == 2)
+ pState->gainRight = PCM_DEFAULT_GAIN_SETTING;
+// pState->currentGainRight = PCM_DEFAULT_GAIN_SETTING;
+#endif
+ pState->state = EAS_STATE_READY;
+
+ /* initialize the decoder */
+ if (pState->pDecoder->pfInit)
+ return (*pState->pDecoder->pfInit)(pEASData, pState);
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * RenderPCMStream()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Decodes a buffer of ADPCM data.
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT RenderPCMStream (S_EAS_DATA *pEASData, S_PCM_STATE *pState, EAS_I32 numSamples)
+{
+ EAS_RESULT result;
+ EAS_U32 phaseInc;
+ EAS_I32 gainLeft, gainIncLeft;
+ EAS_I32 *pOut;
+ EAS_I32 temp;
+ EAS_U32 utemp;
+
+#if (NUM_OUTPUT_CHANNELS == 2)
+ EAS_I32 gainRight, gainIncRight;
+#endif
+
+#if 0
+ printf("env data: AR = %d, DR = %d, SL = %d, SR = %d, RR = %d\n",
+ ((pState->envData >> 12) & 0x0F),
+ ((pState->envData >> 16) & 0x0F),
+ ((pState->envData >> 8) & 0x0F),
+ ((pState->envData >> 28) & 0x0F),
+ ((pState->envData >> 20) & 0x0F));
+#endif
+
+ if (pState->envState == PCM_ENV_START)
+ {
+ //printf("env start\n");
+ utemp = ((pState->envData >> 12) & 0x0F);
+ //if fastest rate, attack is already completed
+ //do the same for slowest rate, since that allows zero to be passed for default envelope
+ if (utemp == 0x0F || utemp == 0x00)
+ {
+ //start envelope at full
+ pState->envValue = (32768<<7);
+ //jump right into decay
+ utemp = ((pState->envData >> 16) & 0x0F);
+ pState->envScale = getDecayScale(utemp);
+ pState->envState = PCM_ENV_DECAY;
+ pState->currentGainLeft = (EAS_I16) FMUL_15x15(pState->gainLeft, pState->volume);
+ pState->currentGainRight = (EAS_I16) FMUL_15x15(pState->gainRight, pState->volume);
+ }
+ //else attack has a ramp
+ else
+ {
+ //start the envelope very low
+ pState->envValue = (2<<7);
+ pState->currentGainLeft = 0;
+ pState->currentGainRight = 0;
+ //get envelope attack scaling value
+ pState->envScale = getAttackIncrement(utemp);
+ //go to attack state
+ pState->envState = PCM_ENV_ATTACK;
+ }
+ }
+ if (pState->envState == PCM_ENV_ATTACK)
+ {
+ //printf("env attack, env value = %d, env scale = %d\n",pState->envValue>>7,pState->envScale);
+ //update envelope value
+ pState->envValue = pState->envValue + (pState->envScale << 7);
+ //check envelope level and update state if needed
+ if (pState->envValue >= (32768<<7))
+ {
+ pState->envValue = (32768<<7);
+ utemp = ((pState->envData >> 16) & 0x0F);
+ pState->envScale = getDecayScale(utemp);
+ pState->envState = PCM_ENV_DECAY;
+ }
+ }
+ else if (pState->envState == PCM_ENV_DECAY)
+ {
+ //printf("env decay, env value = %d, env scale = %d\n",pState->envValue>>7,pState->envScale);
+ //update envelope value
+ pState->envValue = (pState->envValue * pState->envScale)>>9;
+ //check envelope level against sustain level and update state if needed
+ utemp = ((pState->envData >> 8) & 0x0F);
+ if (utemp == (EAS_U32)0x0F)
+ utemp = (2<<7);
+ else
+ {
+ utemp = ((32769<<7) >> (utemp>>1));
+ }
+ if (pState->envValue <= utemp)
+ {
+ utemp = ((pState->envData >> 28) & 0x0F);
+ pState->envScale = getDecayScale(utemp); //getSustainScale(utemp);
+ pState->envState = PCM_ENV_SUSTAIN;
+ }
+ }
+ else if (pState->envState == PCM_ENV_SUSTAIN)
+ {
+ //printf("env sustain, env value = %d, env scale = %d\n",pState->envValue>>7,pState->envScale);
+ //update envelope value
+ pState->envValue = (pState->envValue * pState->envScale)>>9;
+ //check envelope level against bottom level and update state if needed
+ if (pState->envValue <= (2<<7))
+ {
+ //no more decay
+ pState->envScale = 512;
+ pState->envState = PCM_ENV_END;
+ }
+ }
+ else if (pState->envState == PCM_ENV_RELEASE)
+ {
+ //printf("env release, env value = %d, env scale = %d\n",pState->envValue>>7,pState->envScale);
+ //update envelope value
+ pState->envValue = (pState->envValue * pState->envScale)>>9;
+ //check envelope level against bottom level and update state if needed
+ if (pState->envValue <= (2<<7))
+ {
+ //no more decay
+ pState->envScale = 512;
+ pState->envState = PCM_ENV_END;
+ }
+ }
+ else if (pState->envState == PCM_ENV_END)
+ {
+ //printf("env end\n");
+ /* set state to stopping, already ramped down */
+ pState->state = EAS_STATE_STOPPING;
+ }
+
+ //pState->gainLeft = (EAS_U16)((pState->gainLeft * (pState->envValue>>7))>>15);
+ //pState->gainRight = (EAS_U16)((pState->gainRight * (pState->envValue>>7))>>15);
+
+ /* gain to 32-bits to increase resolution on anti-zipper filter */
+ /*lint -e{703} use shift for performance */
+ gainLeft = (EAS_I32) pState->currentGainLeft << SYNTH_UPDATE_PERIOD_IN_BITS;
+#if (NUM_OUTPUT_CHANNELS == 2)
+ /*lint -e{703} use shift for performance */
+ gainRight = (EAS_I32) pState->currentGainRight << SYNTH_UPDATE_PERIOD_IN_BITS;
+#endif
+
+ /* calculate a new gain increment, gain target is zero if pausing */
+ if ((pState->state == EAS_STATE_PAUSING) || (pState->state == EAS_STATE_PAUSED))
+ {
+ gainIncLeft = -pState->currentGainLeft;
+#if (NUM_OUTPUT_CHANNELS == 2)
+ gainIncRight= -pState->currentGainRight;
+#endif
+ }
+ else
+ {
+ EAS_I32 gain = FMUL_15x15(pState->envValue >> 7, pState->volume);
+ gainIncLeft = FMUL_15x15(pState->gainLeft, gain) - pState->currentGainLeft;
+#if (NUM_OUTPUT_CHANNELS == 2)
+ gainIncRight = FMUL_15x15(pState->gainRight, gain) - pState->currentGainRight;
+#endif
+ }
+
+ /* calculate phase increment */
+ phaseInc = pState->basefreq;
+
+ /* convert pitch cents to linear multiplier */
+ if (pState->pitch)
+ {
+ temp = EAS_Calculate2toX(pState->pitch);
+ phaseInc = FMUL_15x15(phaseInc, temp);
+ }
+ phaseInc = phaseInc << pState->rateShift;
+
+ /* pointer to mix buffer */
+ pOut = pEASData->pMixBuffer;
+
+ /* render a buffer of samples */
+ while (numSamples--)
+ {
+
+ /* interpolate an output sample */
+ pState->decoderL.output = pState->decoderL.x0 + FMUL_15x15((pState->decoderL.x1 - pState->decoderL.x0), pState->phase & PHASE_FRAC_MASK);
+
+ /* stereo output */
+#if (NUM_OUTPUT_CHANNELS == 2)
+
+ /* stereo stream? */
+ if (pState->flags & PCM_FLAGS_STEREO)
+ pState->decoderR.output = pState->decoderR.x0 + FMUL_15x15((pState->decoderR.x1 - pState->decoderR.x0), pState->phase & PHASE_FRAC_MASK);
+
+ /* gain scale and mix */
+ /*lint -e{704} use shift instead of division */
+ *pOut++ += (pState->decoderL.output * (gainLeft >> SYNTH_UPDATE_PERIOD_IN_BITS)) >> PCM_MIXER_GUARD_BITS;
+ gainLeft += gainIncLeft;
+
+ /*lint -e{704} use shift instead of division */
+ if (pState->flags & PCM_FLAGS_STEREO)
+ *pOut++ += (pState->decoderR.output * (gainRight >> SYNTH_UPDATE_PERIOD_IN_BITS)) >> PCM_MIXER_GUARD_BITS;
+ else
+ *pOut++ += (pState->decoderL.output * (gainRight >> SYNTH_UPDATE_PERIOD_IN_BITS)) >> PCM_MIXER_GUARD_BITS;
+
+ gainRight += gainIncRight;
+
+ /* mono output */
+#else
+ /* if stereo stream, decode right channel and mix to mono */
+ if (pState->flags & PCM_FLAGS_STEREO)
+ {
+ pState->decoderR.output= pState->decoderR.x0 + FMUL_15x15((pState->decoderR.x1 - pState->decoderR.x0), pState->phase & PHASE_FRAC_MASK);
+
+ /* for mono, sum stereo ADPCM to mono */
+ /*lint -e{704} use shift instead of division */
+ *pOut++ += ((pState->decoderL.output + pState->decoderR.output) * (gainLeft >> SYNTH_UPDATE_PERIOD_IN_BITS)) >> PCM_MIXER_GUARD_BITS;
+ }
+ else
+ /*lint -e{704} use shift instead of division */
+ *pOut++ += (pState->decoderL.output * (gainLeft >> SYNTH_UPDATE_PERIOD_IN_BITS)) >> PCM_MIXER_GUARD_BITS;
+
+ gainLeft += gainIncLeft;
+#endif
+
+ /* advance phase accumulator */
+ pState->phase += phaseInc;
+
+ /* if integer part of phase accumulator is non-zero, advance to next sample */
+ while (pState->phase & ~PHASE_FRAC_MASK)
+ {
+ pState->decoderL.x0 = pState->decoderL.x1;
+ pState->decoderR.x0 = pState->decoderR.x1;
+
+ /* give the source a chance to continue the stream */
+ if (!pState->bytesLeft && pState->pCallback && ((pState->flags & PCM_FLAGS_EMPTY) == 0))
+ {
+ pState->flags |= PCM_FLAGS_EMPTY;
+ (*pState->pCallback)(pEASData, pState->cbInstData, pState, EAS_STATE_EMPTY);
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "RenderPCMStream: After empty callback, bytesLeft = %d\n", pState->bytesLeft); */ }
+ }
+
+ /* decode the next sample */
+ if ((result = (*pState->pDecoder->pfDecodeSample)(pEASData, pState)) != EAS_SUCCESS)
+ return result;
+
+ /* adjust phase by one sample */
+ pState->phase -= (1L << NUM_PHASE_FRAC_BITS);
+ }
+
+ }
+
+ /* save new gain */
+ /*lint -e{704} use shift instead of division */
+ pState->currentGainLeft = (EAS_I16) (gainLeft >> SYNTH_UPDATE_PERIOD_IN_BITS);
+
+#if (NUM_OUTPUT_CHANNELS == 2)
+ /*lint -e{704} use shift instead of division */
+ pState->currentGainRight = (EAS_I16) (gainRight >> SYNTH_UPDATE_PERIOD_IN_BITS);
+#endif
+
+ /* if pausing, set new state and notify */
+ if (pState->state == EAS_STATE_PAUSING)
+ {
+ pState->state = EAS_STATE_PAUSED;
+ if (pState->pCallback)
+ (*pState->pCallback)(pEASData, pState->cbInstData, pState, pState->state);
+ }
+
+ /* if out of data, set stopped state and notify */
+ if (pState->bytesLeft == 0 || pState->state == EAS_STATE_STOPPING)
+ {
+ pState->state = EAS_STATE_STOPPED;
+
+ /* do callback unless the file has already been closed */
+ if (pState->pCallback && pState->fileHandle)
+ (*pState->pCallback)(pEASData, pState->cbInstData, pState, pState->state);
+ }
+
+ if (pState->state == EAS_STATE_READY)
+ pState->state = EAS_STATE_PLAY;
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * LinearPCMDecode()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Decodes a PCM sample
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT LinearPCMDecode (EAS_DATA_HANDLE pEASData, S_PCM_STATE *pState)
+{
+ EAS_RESULT result;
+ EAS_HW_DATA_HANDLE hwInstData;
+
+ hwInstData = ((S_EAS_DATA*) pEASData)->hwInstData;
+
+ /* if out of data, check for loop */
+ if ((pState->bytesLeft == 0) && (pState->loopSamples != 0))
+ {
+ if ((result = EAS_HWFileSeek(pEASData->hwInstData, pState->fileHandle, (EAS_I32) (pState->startPos + pState->loopLocation))) != EAS_SUCCESS)
+ return result;
+ pState->bytesLeft = pState->byteCount = (EAS_I32) pState->bytesLeftLoop;
+ pState->flags &= ~PCM_FLAGS_EMPTY;
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "LinearPCMDecode: Rewind file to %d, bytesLeft = %d\n", pState->startPos, pState->bytesLeft); */ }
+ }
+
+ if (pState->bytesLeft)
+ {
+
+ /* check format byte for 8-bit samples */
+ if (pState->flags & PCM_FLAGS_8_BIT)
+ {
+ /* fetch left or mono sample */
+ if ((result = EAS_HWGetByte(hwInstData, pState->fileHandle, &pState->srcByte)) != EAS_SUCCESS)
+ return result;
+
+ /* if unsigned */
+ if (pState->flags & PCM_FLAGS_UNSIGNED)
+ {
+ /*lint -e{734} converting unsigned 8-bit to signed 16-bit */
+ pState->decoderL.x1 = (EAS_PCM)(((EAS_PCM) pState->srcByte << 8) ^ 0x8000);
+ }
+ else
+ {
+ /*lint -e{734} converting signed 8-bit to signed 16-bit */
+ pState->decoderL.x1 = (EAS_PCM)((EAS_PCM) pState->srcByte << 8);
+ }
+ pState->bytesLeft--;
+
+ /* fetch right sample */
+ if(pState->flags & PCM_FLAGS_STEREO)
+ {
+ if ((result = EAS_HWGetByte(hwInstData, pState->fileHandle, &pState->srcByte)) != EAS_SUCCESS)
+ return result;
+
+ /* if unsigned */
+ if (pState->flags & PCM_FLAGS_UNSIGNED)
+ {
+ /*lint -e{734} converting unsigned 8-bit to signed 16-bit */
+ pState->decoderR.x1 = (EAS_PCM)(((EAS_PCM) pState->srcByte << 8) ^ 0x8000);
+ }
+ else
+ {
+ /*lint -e{734} converting signed 8-bit to signed 16-bit */
+ pState->decoderR.x1 = (EAS_PCM)((EAS_PCM) pState->srcByte << 8);
+ }
+ pState->bytesLeft--;
+ }
+ }
+
+ /* must be 16-bit samples */
+ else
+ {
+ //unsigned 16 bit currently not supported
+ if (pState->flags & PCM_FLAGS_UNSIGNED)
+ {
+ return EAS_ERROR_INVALID_PCM_TYPE;
+ }
+
+ /* fetch left or mono sample */
+ if ((result = EAS_HWGetWord(hwInstData, pState->fileHandle, &pState->decoderL.x1, EAS_FALSE)) != EAS_SUCCESS)
+ return result;
+ pState->bytesLeft -= 2;
+
+ /* fetch right sample */
+ if(pState->flags & PCM_FLAGS_STEREO)
+ {
+ if ((result = EAS_HWGetWord(hwInstData, pState->fileHandle, &pState->decoderR.x1, EAS_FALSE)) != EAS_SUCCESS)
+ return result;
+ pState->bytesLeft -= 2;
+ }
+ }
+ }
+
+ /* no more data, force zero samples */
+ else
+ pState->decoderL.x1 = pState->decoderR.x1 = 0;
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * LinearPCMLocate()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Locate in a linear PCM stream
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT LinearPCMLocate (EAS_DATA_HANDLE pEASData, S_PCM_STATE *pState, EAS_I32 time)
+{
+ EAS_RESULT result;
+ EAS_I32 temp;
+ EAS_I32 secs, msecs;
+ EAS_INT shift;
+
+ /* calculate size of sample frame */
+ if (pState->flags & PCM_FLAGS_8_BIT)
+ shift = 0;
+ else
+ shift = 1;
+ if (pState->flags & PCM_FLAGS_STEREO)
+ shift++;
+
+ /* break down into secs and msecs */
+ secs = time / 1000;
+ msecs = time - (secs * 1000);
+
+ /* calculate sample number fraction from msecs */
+ temp = (msecs * pState->sampleRate);
+ temp = (temp >> 10) + ((temp * 49) >> 21);
+
+ /* add integer sample count */
+ temp += secs * pState->sampleRate;
+
+ /* calculate the position based on sample frame size */
+ /*lint -e{703} use shift for performance */
+ temp <<= shift;
+
+ /* past end of sample? */
+ if (temp > (EAS_I32) pState->loopStart)
+ {
+ /* if not looped, flag error */
+ if (pState->loopSamples == 0)
+ {
+ pState->bytesLeft = 0;
+ pState->flags |= PCM_FLAGS_EMPTY;
+ return EAS_ERROR_LOCATE_BEYOND_END;
+ }
+
+ /* looped sample - calculate position in loop */
+ while (temp > (EAS_I32) pState->loopStart)
+ temp -= (EAS_I32) pState->loopStart;
+ }
+
+ /* seek to new position */
+ if ((result = EAS_PESeek(pEASData, pState, &temp)) != EAS_SUCCESS)
+ return result;
+
+ /* reset state */
+ if ((pState->state != EAS_STATE_PAUSING) && (pState->state != EAS_STATE_PAUSED))
+ pState->state = EAS_STATE_READY;
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_PESeek
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Locate to a particular byte in a PCM stream
+ *----------------------------------------------------------------------------
+ * This bit is tricky because the chunks may not be contiguous,
+ * so we have to rely on the parser to position in the file. We
+ * do this by seeking to the end of each chunk and simulating an
+ * empty buffer condition until we get to where we want to go.
+ *
+ * A better solution would be a parser API for re-positioning,
+ * but there isn't time at the moment to re-factor all the
+ * parsers to support a new API.
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_PESeek (S_EAS_DATA *pEASData, S_PCM_STATE *pState, EAS_I32 *pLocation)
+{
+ EAS_RESULT result;
+
+ /* seek to start of audio */
+ if ((result = EAS_HWFileSeek(pEASData->hwInstData, pState->fileHandle, pState->startPos)) != EAS_SUCCESS)
+ {
+ pState->state = EAS_STATE_ERROR;
+ return result;
+ }
+ pState->bytesLeft = pState->bytesLeftLoop;
+
+ /* skip through chunks until we find the right chunk */
+ while (*pLocation > (EAS_I32) pState->bytesLeft)
+ {
+ /* seek to end of audio chunk */
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "EAS_PESeek: Seek to offset = %d\n", pState->bytesLeft); */ }
+ if ((result = EAS_HWFileSeekOfs(pEASData->hwInstData, pState->fileHandle, pState->bytesLeft)) != EAS_SUCCESS)
+ {
+ pState->state = EAS_STATE_ERROR;
+ return result;
+ }
+ *pLocation -= pState->bytesLeft;
+ pState->bytesLeft = 0;
+ pState->flags |= PCM_FLAGS_EMPTY;
+
+ /* retrieve more data */
+ if (pState->pCallback)
+ (*pState->pCallback)(pEASData, pState->cbInstData, pState, EAS_STATE_EMPTY);
+
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "EAS_PESeek: bytesLeft=%d, byte location = %d\n", pState->bytesLeft, *pLocation); */ }
+
+ /* no more samples */
+ if (pState->bytesLeft == 0)
+ return EAS_ERROR_LOCATE_BEYOND_END;
+ }
+
+ /* seek to new offset in current chunk */
+ if (*pLocation > 0)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "EAS_PESeek: Seek to offset = %d\n", *pLocation); */ }
+ if ((result = EAS_HWFileSeekOfs(pEASData->hwInstData, pState->fileHandle, *pLocation)) != EAS_SUCCESS)
+ {
+ pState->state = EAS_STATE_ERROR;
+ return result;
+ }
+
+ /* if not streamed, calculate number of bytes left */
+ if (pState->flags & PCM_FLAGS_STREAMING)
+ pState->bytesLeft = 0x7fffffff;
+ else
+ pState->bytesLeft -= *pLocation;
+ }
+ return EAS_SUCCESS;
+}
+
diff --git a/arm-wt-22k/lib_src/eas_pcm.h b/arm-wt-22k/lib_src/eas_pcm.h
index c161757..4fc77e9 100644
--- a/arm-wt-22k/lib_src/eas_pcm.h
+++ b/arm-wt-22k/lib_src/eas_pcm.h
@@ -1,13 +1,13 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_pcm.h
- *
- * Contents and purpose:
- * External function prototypes for eas_pcm.c module
- *
- *
- * Copyright Sonic Network Inc. 2005
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_pcm.h
+ *
+ * Contents and purpose:
+ * External function prototypes for eas_pcm.c module
+ *
+ *
+ * Copyright Sonic Network Inc. 2005
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,340 +20,340 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 847 $
- * $Date: 2007-08-27 21:30:08 -0700 (Mon, 27 Aug 2007) $
- *----------------------------------------------------------------------------
-*/
-
-#ifndef _EAS_PCM_H
-#define _EAS_PCM_H
-
-/* default gain setting - roughly unity gain */
-#define PCM_DEFAULT_GAIN_SETTING 0x6000
-
-typedef struct s_pcm_state_tag *EAS_PCM_HANDLE;
-typedef void (*EAS_PCM_CALLBACK) (EAS_DATA_HANDLE pEASData, EAS_VOID_PTR cbInstData, EAS_PCM_HANDLE pcmHandle, EAS_STATE state);
-
-/* parameters for EAS_PEOpenStream */
-typedef struct s_pcm_open_params_tag
-{
- EAS_FILE_HANDLE fileHandle;
- EAS_I32 decoder;
- EAS_U32 sampleRate;
- EAS_I32 size;
- EAS_U32 loopStart;
- EAS_U32 loopSamples;
- EAS_I32 blockSize;
- EAS_U32 flags;
- EAS_U32 envData;
- EAS_I16 volume;
- EAS_PCM_CALLBACK pCallbackFunc;
- EAS_VOID_PTR cbInstData;
- } S_PCM_OPEN_PARAMS;
-
-/*----------------------------------------------------------------------------
- * EAS_PEInit()
- *----------------------------------------------------------------------------
- * Purpose:
- * Initializes the PCM engine
- *
- * Inputs:
- *
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT EAS_PEInit (EAS_DATA_HANDLE pEASData);
-
-/*----------------------------------------------------------------------------
- * EAS_PEShutdown()
- *----------------------------------------------------------------------------
- * Purpose:
- * Shuts down the PCM engine
- *
- * Inputs:
- *
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT EAS_PEShutdown (EAS_DATA_HANDLE pEASData);
-
-/*----------------------------------------------------------------------------
- * EAS_PEOpenStream()
- *----------------------------------------------------------------------------
- * Purpose:
- * Starts up a PCM playback
- *
- * Inputs:
- *
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT EAS_PEOpenStream (EAS_DATA_HANDLE pEASData, S_PCM_OPEN_PARAMS *pParams, EAS_PCM_HANDLE *pHandle);
-
-/*----------------------------------------------------------------------------
- * EAS_PEContinueStream()
- *----------------------------------------------------------------------------
- * Purpose:
- * Continues a PCM stream
- *
- * Inputs:
- *
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT EAS_PEContinueStream (EAS_DATA_HANDLE pEASData, EAS_PCM_HANDLE handle, EAS_I32 size);
-
-/*----------------------------------------------------------------------------
- * EAS_PEGetFileHandle()
- *----------------------------------------------------------------------------
- * Purpose:
- * Returns the file handle of a stream
- *
- * Inputs:
- *
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT EAS_PEGetFileHandle (EAS_DATA_HANDLE pEASData, EAS_PCM_HANDLE handle, EAS_FILE_HANDLE *pFileHandle);
-
-/*----------------------------------------------------------------------------
- * EAS_PERender()
- *----------------------------------------------------------------------------
- * Purpose:
- * Render a buffer of PCM audio
- *
- * Inputs:
- *
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT EAS_PERender (EAS_DATA_HANDLE pEASData, EAS_I32 numSamples);
-
-/*----------------------------------------------------------------------------
- * EAS_PEUpdateParams()
- *----------------------------------------------------------------------------
- * Purpose:
- * Update the pitch and volume parameters using MIDI controls
- *
- * Inputs:
- *
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT EAS_PEUpdateParams (EAS_DATA_HANDLE pEASData, EAS_PCM_HANDLE pState, EAS_I16 pitch, EAS_I16 gainLeft, EAS_I16 gainRight);
-
-/*----------------------------------------------------------------------------
- * EAS_PELocate()
- *----------------------------------------------------------------------------
- * Purpose:
- * This function seeks to the requested place in the file. Accuracy
- * is dependent on the sample rate and block size.
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * pState - stream handle
- * time - media time in milliseconds
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT EAS_PELocate (EAS_DATA_HANDLE pEASData, EAS_PCM_HANDLE pState, EAS_I32 time);
-
-/*----------------------------------------------------------------------------
- * EAS_PEUpdateVolume()
- *----------------------------------------------------------------------------
- * Purpose:
- * Update the volume parameters for a PCM stream
- *
- * Inputs:
- * pEASData - pointer to EAS library instance data
- * handle - pointer to S_PCM_STATE for this stream
- * gainLeft - linear gain multipler in 1.15 fraction format
- * gainRight - linear gain multipler in 1.15 fraction format
- * initial - initial settings, set current gain
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- * Notes
- * In mono mode, leftGain controls the output gain and rightGain is ignored
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, pEASData) reserved for future use */
-EAS_RESULT EAS_PEUpdateVolume (EAS_DATA_HANDLE pEASData, EAS_PCM_HANDLE pState, EAS_I16 volume);
-
-/*----------------------------------------------------------------------------
- * EAS_PEUpdatePitch()
- *----------------------------------------------------------------------------
- * Purpose:
- * Update the pitch parameter for a PCM stream
- *
- * Inputs:
- * pEASData - pointer to EAS library instance data
- * pState - pointer to S_PCM_STATE for this stream
- * pitch - new pitch value in pitch cents
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, pEASData) reserved for future use */
-EAS_RESULT EAS_PEUpdatePitch (EAS_DATA_HANDLE pEASData, EAS_PCM_HANDLE pState, EAS_I16 pitch);
-
-/*----------------------------------------------------------------------------
- * EAS_PEState()
- *----------------------------------------------------------------------------
- * Purpose:
- * Returns the current state of the stream
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- * pState - pointer to variable to store state
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- * Notes:
- * This interface is also exposed in the internal library for use by the other modules.
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT EAS_PEState (EAS_DATA_HANDLE pEASData, EAS_PCM_HANDLE handle, EAS_STATE *pState);
-
-/*----------------------------------------------------------------------------
- * EAS_PEClose()
- *----------------------------------------------------------------------------
- * Purpose:
- * Close the file and clean up
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT EAS_PEClose (EAS_DATA_HANDLE pEASData, EAS_PCM_HANDLE handle);
-
-/*----------------------------------------------------------------------------
- * EAS_PEReset()
- *----------------------------------------------------------------------------
- * Purpose:
- * Reset the sequencer. Used for locating backwards in the file.
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT EAS_PEReset (EAS_DATA_HANDLE pEASData, EAS_PCM_HANDLE handle);
-
-/*----------------------------------------------------------------------------
- * EAS_PEPause()
- *----------------------------------------------------------------------------
- * Purpose:
- * Mute and pause rendering a PCM stream. Sets the gain target to zero and stops the playback
- * at the end of the next audio frame.
- *
- * Inputs:
- * pEASData - pointer to EAS library instance data
- * handle - pointer to S_PCM_STATE for this stream
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT EAS_PEPause (EAS_DATA_HANDLE pEASData, EAS_PCM_HANDLE handle);
-
-/*----------------------------------------------------------------------------
- * EAS_PEResume()
- *----------------------------------------------------------------------------
- * Purpose:
- * Resume rendering a PCM stream. Sets the gain target back to its
- * previous setting and restarts playback at the end of the next audio
- * frame.
- *
- * Inputs:
- * pEASData - pointer to EAS library instance data
- * handle - pointer to S_PCM_STATE for this stream
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT EAS_PEResume (EAS_DATA_HANDLE pEASData, EAS_PCM_HANDLE handle);
-
-/*----------------------------------------------------------------------------
- * EAS_PERelease()
- *----------------------------------------------------------------------------
- * Purpose:
- * Put the PCM stream envelope into release.
- *
- * Inputs:
- * pEASData - pointer to EAS library instance data
- * handle - pointer to S_PCM_STATE for this stream
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT EAS_PERelease (EAS_DATA_HANDLE pEASData, EAS_PCM_HANDLE handle);
-
-#endif /* end _EAS_PCM_H */
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 847 $
+ * $Date: 2007-08-27 21:30:08 -0700 (Mon, 27 Aug 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+#ifndef _EAS_PCM_H
+#define _EAS_PCM_H
+
+/* default gain setting - roughly unity gain */
+#define PCM_DEFAULT_GAIN_SETTING 0x6000
+
+typedef struct s_pcm_state_tag *EAS_PCM_HANDLE;
+typedef void (*EAS_PCM_CALLBACK) (EAS_DATA_HANDLE pEASData, EAS_VOID_PTR cbInstData, EAS_PCM_HANDLE pcmHandle, EAS_STATE state);
+
+/* parameters for EAS_PEOpenStream */
+typedef struct s_pcm_open_params_tag
+{
+ EAS_FILE_HANDLE fileHandle;
+ EAS_I32 decoder;
+ EAS_U32 sampleRate;
+ EAS_I32 size;
+ EAS_U32 loopStart;
+ EAS_U32 loopSamples;
+ EAS_I32 blockSize;
+ EAS_U32 flags;
+ EAS_U32 envData;
+ EAS_I16 volume;
+ EAS_PCM_CALLBACK pCallbackFunc;
+ EAS_VOID_PTR cbInstData;
+ } S_PCM_OPEN_PARAMS;
+
+/*----------------------------------------------------------------------------
+ * EAS_PEInit()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Initializes the PCM engine
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_PEInit (EAS_DATA_HANDLE pEASData);
+
+/*----------------------------------------------------------------------------
+ * EAS_PEShutdown()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Shuts down the PCM engine
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_PEShutdown (EAS_DATA_HANDLE pEASData);
+
+/*----------------------------------------------------------------------------
+ * EAS_PEOpenStream()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Starts up a PCM playback
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_PEOpenStream (EAS_DATA_HANDLE pEASData, S_PCM_OPEN_PARAMS *pParams, EAS_PCM_HANDLE *pHandle);
+
+/*----------------------------------------------------------------------------
+ * EAS_PEContinueStream()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Continues a PCM stream
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_PEContinueStream (EAS_DATA_HANDLE pEASData, EAS_PCM_HANDLE handle, EAS_I32 size);
+
+/*----------------------------------------------------------------------------
+ * EAS_PEGetFileHandle()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Returns the file handle of a stream
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_PEGetFileHandle (EAS_DATA_HANDLE pEASData, EAS_PCM_HANDLE handle, EAS_FILE_HANDLE *pFileHandle);
+
+/*----------------------------------------------------------------------------
+ * EAS_PERender()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Render a buffer of PCM audio
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_PERender (EAS_DATA_HANDLE pEASData, EAS_I32 numSamples);
+
+/*----------------------------------------------------------------------------
+ * EAS_PEUpdateParams()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Update the pitch and volume parameters using MIDI controls
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_PEUpdateParams (EAS_DATA_HANDLE pEASData, EAS_PCM_HANDLE pState, EAS_I16 pitch, EAS_I16 gainLeft, EAS_I16 gainRight);
+
+/*----------------------------------------------------------------------------
+ * EAS_PELocate()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * This function seeks to the requested place in the file. Accuracy
+ * is dependent on the sample rate and block size.
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * pState - stream handle
+ * time - media time in milliseconds
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_PELocate (EAS_DATA_HANDLE pEASData, EAS_PCM_HANDLE pState, EAS_I32 time);
+
+/*----------------------------------------------------------------------------
+ * EAS_PEUpdateVolume()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Update the volume parameters for a PCM stream
+ *
+ * Inputs:
+ * pEASData - pointer to EAS library instance data
+ * handle - pointer to S_PCM_STATE for this stream
+ * gainLeft - linear gain multipler in 1.15 fraction format
+ * gainRight - linear gain multipler in 1.15 fraction format
+ * initial - initial settings, set current gain
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ * Notes
+ * In mono mode, leftGain controls the output gain and rightGain is ignored
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pEASData) reserved for future use */
+EAS_RESULT EAS_PEUpdateVolume (EAS_DATA_HANDLE pEASData, EAS_PCM_HANDLE pState, EAS_I16 volume);
+
+/*----------------------------------------------------------------------------
+ * EAS_PEUpdatePitch()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Update the pitch parameter for a PCM stream
+ *
+ * Inputs:
+ * pEASData - pointer to EAS library instance data
+ * pState - pointer to S_PCM_STATE for this stream
+ * pitch - new pitch value in pitch cents
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pEASData) reserved for future use */
+EAS_RESULT EAS_PEUpdatePitch (EAS_DATA_HANDLE pEASData, EAS_PCM_HANDLE pState, EAS_I16 pitch);
+
+/*----------------------------------------------------------------------------
+ * EAS_PEState()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Returns the current state of the stream
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ * pState - pointer to variable to store state
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ * Notes:
+ * This interface is also exposed in the internal library for use by the other modules.
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_PEState (EAS_DATA_HANDLE pEASData, EAS_PCM_HANDLE handle, EAS_STATE *pState);
+
+/*----------------------------------------------------------------------------
+ * EAS_PEClose()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Close the file and clean up
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_PEClose (EAS_DATA_HANDLE pEASData, EAS_PCM_HANDLE handle);
+
+/*----------------------------------------------------------------------------
+ * EAS_PEReset()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Reset the sequencer. Used for locating backwards in the file.
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_PEReset (EAS_DATA_HANDLE pEASData, EAS_PCM_HANDLE handle);
+
+/*----------------------------------------------------------------------------
+ * EAS_PEPause()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Mute and pause rendering a PCM stream. Sets the gain target to zero and stops the playback
+ * at the end of the next audio frame.
+ *
+ * Inputs:
+ * pEASData - pointer to EAS library instance data
+ * handle - pointer to S_PCM_STATE for this stream
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_PEPause (EAS_DATA_HANDLE pEASData, EAS_PCM_HANDLE handle);
+
+/*----------------------------------------------------------------------------
+ * EAS_PEResume()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Resume rendering a PCM stream. Sets the gain target back to its
+ * previous setting and restarts playback at the end of the next audio
+ * frame.
+ *
+ * Inputs:
+ * pEASData - pointer to EAS library instance data
+ * handle - pointer to S_PCM_STATE for this stream
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_PEResume (EAS_DATA_HANDLE pEASData, EAS_PCM_HANDLE handle);
+
+/*----------------------------------------------------------------------------
+ * EAS_PERelease()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Put the PCM stream envelope into release.
+ *
+ * Inputs:
+ * pEASData - pointer to EAS library instance data
+ * handle - pointer to S_PCM_STATE for this stream
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_PERelease (EAS_DATA_HANDLE pEASData, EAS_PCM_HANDLE handle);
+
+#endif /* end _EAS_PCM_H */
+
diff --git a/arm-wt-22k/lib_src/eas_pcmdata.c b/arm-wt-22k/lib_src/eas_pcmdata.c
index 5649f07..2d85ac2 100644
--- a/arm-wt-22k/lib_src/eas_pcmdata.c
+++ b/arm-wt-22k/lib_src/eas_pcmdata.c
@@ -1,12 +1,12 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_pcmdata.c
- *
- * Contents and purpose:
- * Contains the static data for the PCM engine.
- *
- * Copyright Sonic Network Inc. 2005
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_pcmdata.c
+ *
+ * Contents and purpose:
+ * Contains the static data for the PCM engine.
+ *
+ * Copyright Sonic Network Inc. 2005
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,17 +19,17 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 547 $
- * $Date: 2007-01-31 16:30:17 -0800 (Wed, 31 Jan 2007) $
- *----------------------------------------------------------------------------
-*/
-
-#include "eas_data.h"
-
-/* static data allocation */
-S_PCM_STATE eas_PCMData[MAX_PCM_STREAMS];
-
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 547 $
+ * $Date: 2007-01-31 16:30:17 -0800 (Wed, 31 Jan 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+#include "eas_data.h"
+
+/* static data allocation */
+S_PCM_STATE eas_PCMData[MAX_PCM_STREAMS];
+
+
diff --git a/arm-wt-22k/lib_src/eas_pcmdata.h b/arm-wt-22k/lib_src/eas_pcmdata.h
index be2f8e5..ae18d6d 100644
--- a/arm-wt-22k/lib_src/eas_pcmdata.h
+++ b/arm-wt-22k/lib_src/eas_pcmdata.h
@@ -1,13 +1,13 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_pcmdata.h
- *
- * Contents and purpose:
- * Data declarations for the PCM engine
- *
- *
- * Copyright Sonic Network Inc. 2005
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_pcmdata.h
+ *
+ * Contents and purpose:
+ * Data declarations for the PCM engine
+ *
+ *
+ * Copyright Sonic Network Inc. 2005
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,138 +20,138 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 847 $
- * $Date: 2007-08-27 21:30:08 -0700 (Mon, 27 Aug 2007) $
- *----------------------------------------------------------------------------
-*/
-
-#ifndef _EAS_PCMDATA_H
-#define _EAS_PCMDATA_H
-
-/* sets the maximum number of simultaneous PCM streams */
-#ifndef MAX_PCM_STREAMS
-#define MAX_PCM_STREAMS 16
-#define PCM_STREAM_THRESHOLD (MAX_PCM_STREAMS - 4)
-#endif
-
-/* coefficents for high-pass filter in ADPCM */
-#define INTEGRATOR_COEFFICIENT 100 /* coefficient for leaky integrator */
-
-/* additional flags in S_PCM_STATE.flags used internal to module */
-#define PCM_FLAGS_EMPTY 0x01000000 /* unsigned format */
-
-/*----------------------------------------------------------------------------
- * S_PCM_STATE
- *
- * Retains state information for PCM streams.
- *----------------------------------------------------------------------------
-*/
-typedef struct s_decoder_state_tag
-{
- EAS_I32 output; /* last output for DC offset filter */
- EAS_I32 acc; /* accumulator for DC offset filter */
- EAS_I32 step; /* current ADPCM step size */
- EAS_PCM x1; /* current generated sample */
- EAS_PCM x0; /* previous generated sample */
-} S_DECODER_STATE;
-
-typedef enum
-{
- PCM_ENV_START = 0,
- PCM_ENV_ATTACK,
- PCM_ENV_DECAY,
- PCM_ENV_SUSTAIN,
- PCM_ENV_RELEASE,
- PCM_ENV_END
-} E_PCM_ENV_STATE;
-
-typedef struct s_pcm_state_tag
-{
-#ifdef _CHECKED_BUILD
- EAS_U32 handleCheck; /* signature check for checked build */
-#endif
- EAS_FILE_HANDLE fileHandle; /* pointer to input file */
- EAS_PCM_CALLBACK pCallback; /* pointer to callback function */
- EAS_VOID_PTR cbInstData; /* instance data for callback function */
- struct s_decoder_interface_tag EAS_CONST * pDecoder; /* pointer to decoder interface */
- EAS_STATE state; /* stream state */
- EAS_I32 time; /* media time */
- EAS_I32 startPos; /* start of PCM stream */
- EAS_I32 loopLocation; /* file location where loop starts */
- EAS_I32 byteCount; /* size of file */
- EAS_U32 loopStart; /* loop start, offset in samples from startPos */
- /* NOTE: For CMF, we use this to store total sample size */
- EAS_U32 loopSamples; /* total loop length, in samples, 0 means no loop */
- /* NOTE: For CMF, non-zero means looped */
- EAS_U32 samplesInLoop; /* samples left in the loop to play back */
- EAS_I32 samplesTilLoop; /* samples left to play until top of loop */
- EAS_I32 bytesLeft; /* count of bytes left in stream */
- EAS_I32 bytesLeftLoop; /* count of bytes left in stream, value at start of loop */
- EAS_U32 phase; /* current phase for interpolator */
- EAS_U32 basefreq; /* frequency multiplier */
- EAS_U32 flags; /* stream flags */
- EAS_U32 envData; /* envelope data (and LFO data) */
- EAS_U32 envValue; /* current envelope value */
- EAS_U32 envScale; /* current envelope scale */
- EAS_U32 startOrder; /* start order index, first is 0, next is 1, etc. */
- S_DECODER_STATE decoderL; /* left (mono) ADPCM state */
- S_DECODER_STATE decoderR; /* right ADPCM state */
- S_DECODER_STATE decoderLLoop; /* left (mono) ADPCM state, value at start of loop */
- S_DECODER_STATE decoderRLoop; /* right ADPCM state, value at start of loop */
- E_PCM_ENV_STATE envState; /* current envelope state */
- EAS_I16 volume; /* volume for stream */
- EAS_I16 pitch; /* relative pitch in cents - zero is unity playback */
- EAS_I16 gainLeft; /* requested gain */
- EAS_I16 gainRight; /* requested gain */
- EAS_I16 currentGainLeft; /* current gain for anti-zipper filter */
- EAS_I16 currentGainRight; /* current gain for anti-zipper filter */
- EAS_U16 blockSize; /* block size for ADPCM decoder */
- EAS_U16 blockCount; /* block counter for ADPCM decoder */
- EAS_U16 sampleRate; /* input sample rate */
- EAS_U8 srcByte; /* source byte */
- EAS_U8 msBitCount; /* count keeps track of MS bits */
- EAS_U8 msBitMask; /* mask keeps track of MS bits */
- EAS_U8 msBitValue; /* value keeps track of MS bits */
- EAS_U8 msBitCountLoop; /* count keeps track of MS bits, value at loop start */
- EAS_U8 msBitMaskLoop; /* mask keeps track of MS bits, value at loop start */
- EAS_U8 msBitValueLoop; /* value keeps track of MS bits, value at loop start */
- EAS_BOOL8 hiNibble; /* indicates high/low nibble is next */
- EAS_BOOL8 hiNibbleLoop; /* indicates high/low nibble is next, value loop start */
- EAS_U8 rateShift; /* for playback rate greater than 1.0 */
-} S_PCM_STATE;
-
-/*----------------------------------------------------------------------------
- * S_DECODER_INTERFACE
- *
- * Generic interface for audio decoders
- *----------------------------------------------------------------------------
-*/
-typedef struct s_decoder_interface_tag
-{
- EAS_RESULT (* EAS_CONST pfInit)(EAS_DATA_HANDLE pEASData, S_PCM_STATE *pState);
- EAS_RESULT (* EAS_CONST pfDecodeSample)(EAS_DATA_HANDLE pEASData, S_PCM_STATE *pState);
- EAS_RESULT (* EAS_CONST pfLocate)(EAS_DATA_HANDLE pEASData, S_PCM_STATE *pState, EAS_I32 time);
-} S_DECODER_INTERFACE;
-
-
-/* header chunk for SMAF ADPCM */
-#define TAG_YAMAHA_ADPCM 0x4d776100
-#define TAG_MASK 0xffffff00
-#define TAG_RIFF_FILE 0x52494646
-#define TAG_WAVE_CHUNK 0x57415645
-#define TAG_FMT_CHUNK 0x666d7420
-
-/*----------------------------------------------------------------------------
- * EAS_PESeek
- *----------------------------------------------------------------------------
- * Purpose:
- * Locate to a particular byte in a PCM stream
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT EAS_PESeek (EAS_DATA_HANDLE pEASData, S_PCM_STATE *pState, EAS_I32 *pLocation);
-
-#endif /* _EAS_PCMDATA_H */
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 847 $
+ * $Date: 2007-08-27 21:30:08 -0700 (Mon, 27 Aug 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+#ifndef _EAS_PCMDATA_H
+#define _EAS_PCMDATA_H
+
+/* sets the maximum number of simultaneous PCM streams */
+#ifndef MAX_PCM_STREAMS
+#define MAX_PCM_STREAMS 16
+#define PCM_STREAM_THRESHOLD (MAX_PCM_STREAMS - 4)
+#endif
+
+/* coefficents for high-pass filter in ADPCM */
+#define INTEGRATOR_COEFFICIENT 100 /* coefficient for leaky integrator */
+
+/* additional flags in S_PCM_STATE.flags used internal to module */
+#define PCM_FLAGS_EMPTY 0x01000000 /* unsigned format */
+
+/*----------------------------------------------------------------------------
+ * S_PCM_STATE
+ *
+ * Retains state information for PCM streams.
+ *----------------------------------------------------------------------------
+*/
+typedef struct s_decoder_state_tag
+{
+ EAS_I32 output; /* last output for DC offset filter */
+ EAS_I32 acc; /* accumulator for DC offset filter */
+ EAS_I32 step; /* current ADPCM step size */
+ EAS_PCM x1; /* current generated sample */
+ EAS_PCM x0; /* previous generated sample */
+} S_DECODER_STATE;
+
+typedef enum
+{
+ PCM_ENV_START = 0,
+ PCM_ENV_ATTACK,
+ PCM_ENV_DECAY,
+ PCM_ENV_SUSTAIN,
+ PCM_ENV_RELEASE,
+ PCM_ENV_END
+} E_PCM_ENV_STATE;
+
+typedef struct s_pcm_state_tag
+{
+#ifdef _CHECKED_BUILD
+ EAS_U32 handleCheck; /* signature check for checked build */
+#endif
+ EAS_FILE_HANDLE fileHandle; /* pointer to input file */
+ EAS_PCM_CALLBACK pCallback; /* pointer to callback function */
+ EAS_VOID_PTR cbInstData; /* instance data for callback function */
+ struct s_decoder_interface_tag EAS_CONST * pDecoder; /* pointer to decoder interface */
+ EAS_STATE state; /* stream state */
+ EAS_I32 time; /* media time */
+ EAS_I32 startPos; /* start of PCM stream */
+ EAS_I32 loopLocation; /* file location where loop starts */
+ EAS_I32 byteCount; /* size of file */
+ EAS_U32 loopStart; /* loop start, offset in samples from startPos */
+ /* NOTE: For CMF, we use this to store total sample size */
+ EAS_U32 loopSamples; /* total loop length, in samples, 0 means no loop */
+ /* NOTE: For CMF, non-zero means looped */
+ EAS_U32 samplesInLoop; /* samples left in the loop to play back */
+ EAS_I32 samplesTilLoop; /* samples left to play until top of loop */
+ EAS_I32 bytesLeft; /* count of bytes left in stream */
+ EAS_I32 bytesLeftLoop; /* count of bytes left in stream, value at start of loop */
+ EAS_U32 phase; /* current phase for interpolator */
+ EAS_U32 basefreq; /* frequency multiplier */
+ EAS_U32 flags; /* stream flags */
+ EAS_U32 envData; /* envelope data (and LFO data) */
+ EAS_U32 envValue; /* current envelope value */
+ EAS_U32 envScale; /* current envelope scale */
+ EAS_U32 startOrder; /* start order index, first is 0, next is 1, etc. */
+ S_DECODER_STATE decoderL; /* left (mono) ADPCM state */
+ S_DECODER_STATE decoderR; /* right ADPCM state */
+ S_DECODER_STATE decoderLLoop; /* left (mono) ADPCM state, value at start of loop */
+ S_DECODER_STATE decoderRLoop; /* right ADPCM state, value at start of loop */
+ E_PCM_ENV_STATE envState; /* current envelope state */
+ EAS_I16 volume; /* volume for stream */
+ EAS_I16 pitch; /* relative pitch in cents - zero is unity playback */
+ EAS_I16 gainLeft; /* requested gain */
+ EAS_I16 gainRight; /* requested gain */
+ EAS_I16 currentGainLeft; /* current gain for anti-zipper filter */
+ EAS_I16 currentGainRight; /* current gain for anti-zipper filter */
+ EAS_U16 blockSize; /* block size for ADPCM decoder */
+ EAS_U16 blockCount; /* block counter for ADPCM decoder */
+ EAS_U16 sampleRate; /* input sample rate */
+ EAS_U8 srcByte; /* source byte */
+ EAS_U8 msBitCount; /* count keeps track of MS bits */
+ EAS_U8 msBitMask; /* mask keeps track of MS bits */
+ EAS_U8 msBitValue; /* value keeps track of MS bits */
+ EAS_U8 msBitCountLoop; /* count keeps track of MS bits, value at loop start */
+ EAS_U8 msBitMaskLoop; /* mask keeps track of MS bits, value at loop start */
+ EAS_U8 msBitValueLoop; /* value keeps track of MS bits, value at loop start */
+ EAS_BOOL8 hiNibble; /* indicates high/low nibble is next */
+ EAS_BOOL8 hiNibbleLoop; /* indicates high/low nibble is next, value loop start */
+ EAS_U8 rateShift; /* for playback rate greater than 1.0 */
+} S_PCM_STATE;
+
+/*----------------------------------------------------------------------------
+ * S_DECODER_INTERFACE
+ *
+ * Generic interface for audio decoders
+ *----------------------------------------------------------------------------
+*/
+typedef struct s_decoder_interface_tag
+{
+ EAS_RESULT (* EAS_CONST pfInit)(EAS_DATA_HANDLE pEASData, S_PCM_STATE *pState);
+ EAS_RESULT (* EAS_CONST pfDecodeSample)(EAS_DATA_HANDLE pEASData, S_PCM_STATE *pState);
+ EAS_RESULT (* EAS_CONST pfLocate)(EAS_DATA_HANDLE pEASData, S_PCM_STATE *pState, EAS_I32 time);
+} S_DECODER_INTERFACE;
+
+
+/* header chunk for SMAF ADPCM */
+#define TAG_YAMAHA_ADPCM 0x4d776100
+#define TAG_MASK 0xffffff00
+#define TAG_RIFF_FILE 0x52494646
+#define TAG_WAVE_CHUNK 0x57415645
+#define TAG_FMT_CHUNK 0x666d7420
+
+/*----------------------------------------------------------------------------
+ * EAS_PESeek
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Locate to a particular byte in a PCM stream
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_PESeek (EAS_DATA_HANDLE pEASData, S_PCM_STATE *pState, EAS_I32 *pLocation);
+
+#endif /* _EAS_PCMDATA_H */
+
diff --git a/arm-wt-22k/lib_src/eas_public.c b/arm-wt-22k/lib_src/eas_public.c
index d67ef7e..9ee6cf4 100644
--- a/arm-wt-22k/lib_src/eas_public.c
+++ b/arm-wt-22k/lib_src/eas_public.c
@@ -1,11 +1,11 @@
/*----------------------------------------------------------------------------
*
- * File:
+ * File:
* eas_public.c
*
* Contents and purpose:
* Contains EAS library public interface
- *
+ *
* Copyright Sonic Network Inc. 2004
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -50,7 +50,7 @@
#endif
/* number of events to parse before calling EAS_HWYield function */
-#define YIELD_EVENT_COUNT 10
+#define YIELD_EVENT_COUNT 10
/*----------------------------------------------------------------------------
* easLibConfig
@@ -61,23 +61,23 @@
*/
static const S_EAS_LIB_CONFIG easLibConfig =
{
- LIB_VERSION,
+ LIB_VERSION,
#ifdef _CHECKED_BUILD
- EAS_TRUE,
+ EAS_TRUE,
#else
- EAS_FALSE,
+ EAS_FALSE,
#endif
- MAX_SYNTH_VOICES,
- NUM_OUTPUT_CHANNELS,
- _OUTPUT_SAMPLE_RATE,
- BUFFER_SIZE_IN_MONO_SAMPLES,
+ MAX_SYNTH_VOICES,
+ NUM_OUTPUT_CHANNELS,
+ _OUTPUT_SAMPLE_RATE,
+ BUFFER_SIZE_IN_MONO_SAMPLES,
#ifdef _FILTER_ENABLED
- EAS_TRUE,
+ EAS_TRUE,
#else
- EAS_FALSE,
+ EAS_FALSE,
#endif
- _BUILD_TIME_,
- _BUILD_VERSION_
+ _BUILD_TIME_,
+ _BUILD_VERSION_
};
/* local prototypes */
@@ -89,20 +89,20 @@ static EAS_RESULT EAS_ParseEvents (S_EAS_DATA *pEASData, S_EAS_STREAM *pStream,
* Sets the specified parameter in the stream. Allows access to
* customizable settings within the individual file parsers.
*----------------------------------------------------------------------------
- * pEASData - pointer to EAS persistent data object
- * pStream - stream handle
- * param - enumerated parameter (see eas_parser.h)
- * value - new value
+ * pEASData - pointer to EAS persistent data object
+ * pStream - stream handle
+ * param - enumerated parameter (see eas_parser.h)
+ * value - new value
*----------------------------------------------------------------------------
*/
EAS_RESULT EAS_SetStreamParameter (S_EAS_DATA *pEASData, EAS_HANDLE pStream, EAS_I32 param, EAS_I32 value)
{
- S_FILE_PARSER_INTERFACE *pParserModule;
+ S_FILE_PARSER_INTERFACE *pParserModule;
- pParserModule = (S_FILE_PARSER_INTERFACE*) pStream->pParserModule;
- if (pParserModule->pfSetData)
- return (*pParserModule->pfSetData)(pEASData, pStream->handle, param, value);
- return EAS_ERROR_FEATURE_NOT_AVAILABLE;
+ pParserModule = (S_FILE_PARSER_INTERFACE*) pStream->pParserModule;
+ if (pParserModule->pfSetData)
+ return (*pParserModule->pfSetData)(pEASData, pStream->handle, param, value);
+ return EAS_ERROR_FEATURE_NOT_AVAILABLE;
}
/*----------------------------------------------------------------------------
@@ -111,20 +111,20 @@ EAS_RESULT EAS_SetStreamParameter (S_EAS_DATA *pEASData, EAS_HANDLE pStream, EAS
* Sets the specified parameter in the stream. Allows access to
* customizable settings within the individual file parsers.
*----------------------------------------------------------------------------
- * pEASData - pointer to EAS persistent data object
- * pStream - stream handle
- * param - enumerated parameter (see eas_parser.h)
- * pValue - pointer to variable to receive current setting
+ * pEASData - pointer to EAS persistent data object
+ * pStream - stream handle
+ * param - enumerated parameter (see eas_parser.h)
+ * pValue - pointer to variable to receive current setting
*----------------------------------------------------------------------------
*/
EAS_RESULT EAS_GetStreamParameter (S_EAS_DATA *pEASData, EAS_HANDLE pStream, EAS_I32 param, EAS_I32 *pValue)
{
- S_FILE_PARSER_INTERFACE *pParserModule;
+ S_FILE_PARSER_INTERFACE *pParserModule;
- pParserModule = (S_FILE_PARSER_INTERFACE*) pStream->pParserModule;
- if (pParserModule->pfGetData)
- return (*pParserModule->pfGetData)(pEASData, pStream->handle, param, pValue);
- return EAS_ERROR_FEATURE_NOT_AVAILABLE;
+ pParserModule = (S_FILE_PARSER_INTERFACE*) pStream->pParserModule;
+ if (pParserModule->pfGetData)
+ return (*pParserModule->pfGetData)(pEASData, pStream->handle, param, pValue);
+ return EAS_ERROR_FEATURE_NOT_AVAILABLE;
}
/*----------------------------------------------------------------------------
@@ -139,13 +139,13 @@ EAS_RESULT EAS_GetStreamParameter (S_EAS_DATA *pEASData, EAS_HANDLE pStream, EAS
*/
EAS_BOOL EAS_StreamReady (S_EAS_DATA *pEASData, EAS_HANDLE pStream)
{
- S_FILE_PARSER_INTERFACE *pParserModule;
- EAS_STATE state;
+ S_FILE_PARSER_INTERFACE *pParserModule;
+ EAS_STATE state;
- pParserModule = (S_FILE_PARSER_INTERFACE*) pStream->pParserModule;
- if (pParserModule->pfState(pEASData, pStream->handle, &state) != EAS_SUCCESS)
- return EAS_FALSE;
- return (state < EAS_STATE_OPEN);
+ pParserModule = (S_FILE_PARSER_INTERFACE*) pStream->pParserModule;
+ if (pParserModule->pfState(pEASData, pStream->handle, &state) != EAS_SUCCESS)
+ return EAS_FALSE;
+ return (state < EAS_STATE_OPEN);
}
/*----------------------------------------------------------------------------
@@ -160,59 +160,59 @@ EAS_BOOL EAS_StreamReady (S_EAS_DATA *pEASData, EAS_HANDLE pStream)
*/
EAS_RESULT EAS_IntSetStrmParam (S_EAS_DATA *pEASData, EAS_HANDLE pStream, EAS_INT param, EAS_I32 value)
{
- S_SYNTH *pSynth;
-
- /* try to set the parameter using stream interface */
- if (EAS_SetStreamParameter(pEASData, pStream, param, value) == EAS_SUCCESS)
- return EAS_SUCCESS;
-
- /* get a pointer to the synth object and set it directly */
- /*lint -e{740} we are cheating by passing a pointer through this interface */
- if (EAS_GetStreamParameter(pEASData, pStream, PARSER_DATA_SYNTH_HANDLE, (EAS_I32*) &pSynth) != EAS_SUCCESS)
- return EAS_ERROR_INVALID_PARAMETER;
-
- if (pSynth == NULL)
- return EAS_ERROR_INVALID_PARAMETER;
-
- switch (param)
- {
-
-#ifdef DLS_SYNTHESIZER
- case PARSER_DATA_DLS_COLLECTION:
- {
- EAS_RESULT result = VMSetDLSLib(pSynth, (EAS_DLSLIB_HANDLE) value);
- if (result == EAS_SUCCESS)
- {
- DLSAddRef((S_DLS*) value);
- VMInitializeAllChannels(pEASData->pVoiceMgr, pSynth);
- }
- return result;
- }
+ S_SYNTH *pSynth;
+
+ /* try to set the parameter using stream interface */
+ if (EAS_SetStreamParameter(pEASData, pStream, param, value) == EAS_SUCCESS)
+ return EAS_SUCCESS;
+
+ /* get a pointer to the synth object and set it directly */
+ /*lint -e{740} we are cheating by passing a pointer through this interface */
+ if (EAS_GetStreamParameter(pEASData, pStream, PARSER_DATA_SYNTH_HANDLE, (EAS_I32*) &pSynth) != EAS_SUCCESS)
+ return EAS_ERROR_INVALID_PARAMETER;
+
+ if (pSynth == NULL)
+ return EAS_ERROR_INVALID_PARAMETER;
+
+ switch (param)
+ {
+
+#ifdef DLS_SYNTHESIZER
+ case PARSER_DATA_DLS_COLLECTION:
+ {
+ EAS_RESULT result = VMSetDLSLib(pSynth, (EAS_DLSLIB_HANDLE) value);
+ if (result == EAS_SUCCESS)
+ {
+ DLSAddRef((S_DLS*) value);
+ VMInitializeAllChannels(pEASData->pVoiceMgr, pSynth);
+ }
+ return result;
+ }
#endif
- case PARSER_DATA_EAS_LIBRARY:
- return VMSetEASLib(pSynth, (EAS_SNDLIB_HANDLE) value);
-
- case PARSER_DATA_POLYPHONY:
- return VMSetPolyphony(pEASData->pVoiceMgr, pSynth, value);
-
- case PARSER_DATA_PRIORITY:
- return VMSetPriority(pEASData->pVoiceMgr, pSynth, value);
-
- case PARSER_DATA_TRANSPOSITION:
- VMSetTranposition(pSynth, value);
- break;
-
- case PARSER_DATA_VOLUME:
- VMSetVolume(pSynth, (EAS_U16) value);
- break;
-
- default:
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Invalid paramter %d in call to EAS_IntSetStrmParam", param); */ }
- return EAS_ERROR_INVALID_PARAMETER;
- }
-
- return EAS_SUCCESS;
+ case PARSER_DATA_EAS_LIBRARY:
+ return VMSetEASLib(pSynth, (EAS_SNDLIB_HANDLE) value);
+
+ case PARSER_DATA_POLYPHONY:
+ return VMSetPolyphony(pEASData->pVoiceMgr, pSynth, value);
+
+ case PARSER_DATA_PRIORITY:
+ return VMSetPriority(pEASData->pVoiceMgr, pSynth, value);
+
+ case PARSER_DATA_TRANSPOSITION:
+ VMSetTranposition(pSynth, value);
+ break;
+
+ case PARSER_DATA_VOLUME:
+ VMSetVolume(pSynth, (EAS_U16) value);
+ break;
+
+ default:
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Invalid paramter %d in call to EAS_IntSetStrmParam", param); */ }
+ return EAS_ERROR_INVALID_PARAMETER;
+ }
+
+ return EAS_SUCCESS;
}
/*----------------------------------------------------------------------------
@@ -226,42 +226,42 @@ EAS_RESULT EAS_IntSetStrmParam (S_EAS_DATA *pEASData, EAS_HANDLE pStream, EAS_IN
*/
EAS_RESULT EAS_IntGetStrmParam (S_EAS_DATA *pEASData, EAS_HANDLE pStream, EAS_INT param, EAS_I32 *pValue)
{
- S_SYNTH *pSynth;
-
- /* try to set the parameter */
- if (EAS_GetStreamParameter(pEASData, pStream, param, pValue) == EAS_SUCCESS)
- return EAS_SUCCESS;
-
- /* get a pointer to the synth object and retrieve data directly */
- /*lint -e{740} we are cheating by passing a pointer through this interface */
- if (EAS_GetStreamParameter(pEASData, pStream, PARSER_DATA_SYNTH_HANDLE, (EAS_I32*) &pSynth) != EAS_SUCCESS)
- return EAS_ERROR_INVALID_PARAMETER;
-
- if (pSynth == NULL)
- return EAS_ERROR_INVALID_PARAMETER;
-
- switch (param)
- {
- case PARSER_DATA_POLYPHONY:
- return VMGetPolyphony(pEASData->pVoiceMgr, pSynth, pValue);
-
- case PARSER_DATA_PRIORITY:
- return VMGetPriority(pEASData->pVoiceMgr, pSynth, pValue);
-
- case PARSER_DATA_TRANSPOSITION:
- VMGetTranposition(pSynth, pValue);
- break;
-
- case PARSER_DATA_NOTE_COUNT:
- *pValue = VMGetNoteCount(pSynth);
- break;
-
- default:
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Invalid paramter %d in call to EAS_IntSetStrmParam", param); */ }
- return EAS_ERROR_INVALID_PARAMETER;
- }
-
- return EAS_SUCCESS;
+ S_SYNTH *pSynth;
+
+ /* try to set the parameter */
+ if (EAS_GetStreamParameter(pEASData, pStream, param, pValue) == EAS_SUCCESS)
+ return EAS_SUCCESS;
+
+ /* get a pointer to the synth object and retrieve data directly */
+ /*lint -e{740} we are cheating by passing a pointer through this interface */
+ if (EAS_GetStreamParameter(pEASData, pStream, PARSER_DATA_SYNTH_HANDLE, (EAS_I32*) &pSynth) != EAS_SUCCESS)
+ return EAS_ERROR_INVALID_PARAMETER;
+
+ if (pSynth == NULL)
+ return EAS_ERROR_INVALID_PARAMETER;
+
+ switch (param)
+ {
+ case PARSER_DATA_POLYPHONY:
+ return VMGetPolyphony(pEASData->pVoiceMgr, pSynth, pValue);
+
+ case PARSER_DATA_PRIORITY:
+ return VMGetPriority(pEASData->pVoiceMgr, pSynth, pValue);
+
+ case PARSER_DATA_TRANSPOSITION:
+ VMGetTranposition(pSynth, pValue);
+ break;
+
+ case PARSER_DATA_NOTE_COUNT:
+ *pValue = VMGetNoteCount(pSynth);
+ break;
+
+ default:
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Invalid paramter %d in call to EAS_IntSetStrmParam", param); */ }
+ return EAS_ERROR_INVALID_PARAMETER;
+ }
+
+ return EAS_SUCCESS;
}
/*----------------------------------------------------------------------------
@@ -278,29 +278,29 @@ EAS_RESULT EAS_IntGetStrmParam (S_EAS_DATA *pEASData, EAS_HANDLE pStream, EAS_IN
*/
static EAS_INT EAS_AllocateStream (EAS_DATA_HANDLE pEASData)
{
- EAS_INT streamNum;
-
- /* check for static allocation, only one stream allowed */
- if (pEASData->staticMemoryModel)
- {
- if (pEASData->streams[0].handle != NULL)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Attempt to open multiple streams in static model\n"); */ }
- return -1;
- }
- return 0;
- }
-
- /* dynamic model */
- for (streamNum = 0; streamNum < MAX_NUMBER_STREAMS; streamNum++)
- if (pEASData->streams[streamNum].handle == NULL)
- break;
- if (streamNum == MAX_NUMBER_STREAMS)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Exceeded maximum number of open streams\n"); */ }
- return -1;
- }
- return streamNum;
+ EAS_INT streamNum;
+
+ /* check for static allocation, only one stream allowed */
+ if (pEASData->staticMemoryModel)
+ {
+ if (pEASData->streams[0].handle != NULL)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Attempt to open multiple streams in static model\n"); */ }
+ return -1;
+ }
+ return 0;
+ }
+
+ /* dynamic model */
+ for (streamNum = 0; streamNum < MAX_NUMBER_STREAMS; streamNum++)
+ if (pEASData->streams[streamNum].handle == NULL)
+ break;
+ if (streamNum == MAX_NUMBER_STREAMS)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Exceeded maximum number of open streams\n"); */ }
+ return -1;
+ }
+ return streamNum;
}
/*----------------------------------------------------------------------------
@@ -317,13 +317,13 @@ static EAS_INT EAS_AllocateStream (EAS_DATA_HANDLE pEASData)
*/
static void EAS_InitStream (S_EAS_STREAM *pStream, EAS_VOID_PTR pParserModule, EAS_VOID_PTR streamHandle)
{
- pStream->pParserModule = pParserModule;
- pStream->handle = streamHandle;
- pStream->time = 0;
- pStream->frameLength = AUDIO_FRAME_LENGTH;
- pStream->repeatCount = 0;
- pStream->volume = DEFAULT_STREAM_VOLUME;
- pStream->streamFlags = 0;
+ pStream->pParserModule = pParserModule;
+ pStream->handle = streamHandle;
+ pStream->time = 0;
+ pStream->frameLength = AUDIO_FRAME_LENGTH;
+ pStream->repeatCount = 0;
+ pStream->volume = DEFAULT_STREAM_VOLUME;
+ pStream->streamFlags = 0;
}
/*----------------------------------------------------------------------------
@@ -341,7 +341,7 @@ static void EAS_InitStream (S_EAS_STREAM *pStream, EAS_VOID_PTR pParserModule, E
*/
EAS_PUBLIC const S_EAS_LIB_CONFIG *EAS_Config (void)
{
- return &easLibConfig;
+ return &easLibConfig;
}
/*----------------------------------------------------------------------------
@@ -351,7 +351,7 @@ EAS_PUBLIC const S_EAS_LIB_CONFIG *EAS_Config (void)
* Initialize the synthesizer library
*
* Inputs:
- * ppEASData - pointer to data handle variable for this instance
+ * ppEASData - pointer to data handle variable for this instance
*
* Outputs:
*
@@ -359,95 +359,95 @@ EAS_PUBLIC const S_EAS_LIB_CONFIG *EAS_Config (void)
*/
EAS_PUBLIC EAS_RESULT EAS_Init (EAS_DATA_HANDLE *ppEASData)
{
- EAS_HW_DATA_HANDLE pHWInstData;
- EAS_RESULT result;
- S_EAS_DATA *pEASData;
- EAS_INT module;
- EAS_BOOL staticMemoryModel;
-
- /* get the memory model */
- staticMemoryModel = EAS_CMStaticMemoryModel();
-
- /* initialize the host wrapper interface */
- *ppEASData = NULL;
- if ((result = EAS_HWInit(&pHWInstData)) != EAS_SUCCESS)
- return result;
-
- /* check Configuration Module for S_EAS_DATA allocation */
- if (staticMemoryModel)
- pEASData = EAS_CMEnumData(EAS_CM_EAS_DATA);
- else
- pEASData = EAS_HWMalloc(pHWInstData, sizeof(S_EAS_DATA));
- if (!pEASData)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_FATAL, "Failed to allocate EAS library memory\n"); */ }
- return EAS_ERROR_MALLOC_FAILED;
- }
-
- /* initialize some data */
- EAS_HWMemSet(pEASData, 0, sizeof(S_EAS_DATA));
- pEASData->staticMemoryModel = (EAS_BOOL8) staticMemoryModel;
- pEASData->hwInstData = pHWInstData;
- pEASData->renderTime = 0;
-
- /* set header search flag */
-#ifdef FILE_HEADER_SEARCH
- pEASData->searchHeaderFlag = EAS_TRUE;
+ EAS_HW_DATA_HANDLE pHWInstData;
+ EAS_RESULT result;
+ S_EAS_DATA *pEASData;
+ EAS_INT module;
+ EAS_BOOL staticMemoryModel;
+
+ /* get the memory model */
+ staticMemoryModel = EAS_CMStaticMemoryModel();
+
+ /* initialize the host wrapper interface */
+ *ppEASData = NULL;
+ if ((result = EAS_HWInit(&pHWInstData)) != EAS_SUCCESS)
+ return result;
+
+ /* check Configuration Module for S_EAS_DATA allocation */
+ if (staticMemoryModel)
+ pEASData = EAS_CMEnumData(EAS_CM_EAS_DATA);
+ else
+ pEASData = EAS_HWMalloc(pHWInstData, sizeof(S_EAS_DATA));
+ if (!pEASData)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_FATAL, "Failed to allocate EAS library memory\n"); */ }
+ return EAS_ERROR_MALLOC_FAILED;
+ }
+
+ /* initialize some data */
+ EAS_HWMemSet(pEASData, 0, sizeof(S_EAS_DATA));
+ pEASData->staticMemoryModel = (EAS_BOOL8) staticMemoryModel;
+ pEASData->hwInstData = pHWInstData;
+ pEASData->renderTime = 0;
+
+ /* set header search flag */
+#ifdef FILE_HEADER_SEARCH
+ pEASData->searchHeaderFlag = EAS_TRUE;
#endif
- /* initalize parameters */
- EAS_SetVolume(pEASData, NULL, DEFAULT_VOLUME);
+ /* initalize parameters */
+ EAS_SetVolume(pEASData, NULL, DEFAULT_VOLUME);
#ifdef _METRICS_ENABLED
- /* initalize the metrics module */
- pEASData->pMetricsModule = EAS_CMEnumOptModules(EAS_MODULE_METRICS);
- if (pEASData->pMetricsModule != NULL)
- {
- if ((result = (*pEASData->pMetricsModule->pfInit)(pEASData, &pEASData->pMetricsData)) != EAS_SUCCESS)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Error %ld initializing metrics module\n", result); */ }
- return result;
- }
- }
-#endif
-
- /* initailize the voice manager & synthesizer */
- if ((result = VMInitialize(pEASData)) != EAS_SUCCESS)
- return result;
-
- /* initialize mix engine */
- if ((result = EAS_MixEngineInit(pEASData)) != EAS_SUCCESS)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Error %ld starting up mix engine\n", result); */ }
- return result;
- }
-
- /* initialize effects modules */
- for (module = 0; module < NUM_EFFECTS_MODULES; module++)
- {
- pEASData->effectsModules[module].effect = EAS_CMEnumFXModules(module);
- if (pEASData->effectsModules[module].effect != NULL)
- {
- if ((result = (*pEASData->effectsModules[module].effect->pfInit)(pEASData, &pEASData->effectsModules[module].effectData)) != EAS_SUCCESS)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_FATAL, "Initialization of effects module %d returned %d\n", module, result); */ }
- return result;
- }
- }
- }
-
- /* initialize PCM engine */
- if ((result = EAS_PEInit(pEASData)) != EAS_SUCCESS)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_FATAL, "EAS_PEInit failed with error code %ld\n", result); */ }
- return result;
- }
-
- /* return instance data pointer to host */
- *ppEASData = pEASData;
-
- return EAS_SUCCESS;
-}
+ /* initalize the metrics module */
+ pEASData->pMetricsModule = EAS_CMEnumOptModules(EAS_MODULE_METRICS);
+ if (pEASData->pMetricsModule != NULL)
+ {
+ if ((result = (*pEASData->pMetricsModule->pfInit)(pEASData, &pEASData->pMetricsData)) != EAS_SUCCESS)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Error %ld initializing metrics module\n", result); */ }
+ return result;
+ }
+ }
+#endif
+
+ /* initailize the voice manager & synthesizer */
+ if ((result = VMInitialize(pEASData)) != EAS_SUCCESS)
+ return result;
+
+ /* initialize mix engine */
+ if ((result = EAS_MixEngineInit(pEASData)) != EAS_SUCCESS)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Error %ld starting up mix engine\n", result); */ }
+ return result;
+ }
+
+ /* initialize effects modules */
+ for (module = 0; module < NUM_EFFECTS_MODULES; module++)
+ {
+ pEASData->effectsModules[module].effect = EAS_CMEnumFXModules(module);
+ if (pEASData->effectsModules[module].effect != NULL)
+ {
+ if ((result = (*pEASData->effectsModules[module].effect->pfInit)(pEASData, &pEASData->effectsModules[module].effectData)) != EAS_SUCCESS)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_FATAL, "Initialization of effects module %d returned %d\n", module, result); */ }
+ return result;
+ }
+ }
+ }
+
+ /* initialize PCM engine */
+ if ((result = EAS_PEInit(pEASData)) != EAS_SUCCESS)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_FATAL, "EAS_PEInit failed with error code %ld\n", result); */ }
+ return result;
+ }
+
+ /* return instance data pointer to host */
+ *ppEASData = pEASData;
+
+ return EAS_SUCCESS;
+}
/*----------------------------------------------------------------------------
* EAS_Shutdown()
@@ -457,7 +457,7 @@ EAS_PUBLIC EAS_RESULT EAS_Init (EAS_DATA_HANDLE *ppEASData)
* synthesizer (dynamic memory model only)
*
* Inputs:
- * pEASData - handle to data for this instance
+ * pEASData - handle to data for this instance
*
* Outputs:
*
@@ -465,93 +465,93 @@ EAS_PUBLIC EAS_RESULT EAS_Init (EAS_DATA_HANDLE *ppEASData)
*/
EAS_PUBLIC EAS_RESULT EAS_Shutdown (EAS_DATA_HANDLE pEASData)
{
- EAS_HW_DATA_HANDLE hwInstData;
- EAS_RESULT result, reportResult;
- EAS_INT i;
-
- /* establish pointers */
- hwInstData = pEASData->hwInstData;
-
- /* check for NULL handle */
- if (!pEASData)
- return EAS_ERROR_HANDLE_INTEGRITY;
-
- /* if there are streams open, close them */
- reportResult = EAS_SUCCESS;
- for (i = 0; i < MAX_NUMBER_STREAMS; i++)
- {
- if (pEASData->streams[i].pParserModule && pEASData->streams[i].handle)
- {
- if ((result = (*((S_FILE_PARSER_INTERFACE*)(pEASData->streams[i].pParserModule))->pfClose)(pEASData, pEASData->streams[i].handle)) != EAS_SUCCESS)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Error %ld shutting down parser module\n", result); */ }
- reportResult = result;
- }
- }
- }
-
- /* shutdown PCM engine */
- if ((result = EAS_PEShutdown(pEASData)) != EAS_SUCCESS)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Error %ld shutting down PCM engine\n", result); */ }
- if (reportResult == EAS_SUCCESS)
- reportResult = result;
- }
-
- /* shutdown mix engine */
- if ((result = EAS_MixEngineShutdown(pEASData)) != EAS_SUCCESS)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Error %ld shutting down mix engine\n", result); */ }
- if (reportResult == EAS_SUCCESS)
- reportResult = result;
- }
-
- /* shutdown effects modules */
- for (i = 0; i < NUM_EFFECTS_MODULES; i++)
- {
- if (pEASData->effectsModules[i].effect)
- {
- if ((result = (*pEASData->effectsModules[i].effect->pfShutdown)(pEASData, pEASData->effectsModules[i].effectData)) != EAS_SUCCESS)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_FATAL, "Shutdown of effects module %d returned %d\n", i, result); */ }
- if (reportResult == EAS_SUCCESS)
- reportResult = result;
- }
- }
- }
-
- /* shutdown the voice manager & synthesizer */
- VMShutdown(pEASData);
-
-#ifdef _METRICS_ENABLED
- /* shutdown the metrics module */
- if (pEASData->pMetricsModule != NULL)
- {
- if ((result = (*pEASData->pMetricsModule->pfShutdown)(pEASData, pEASData->pMetricsData)) != EAS_SUCCESS)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Error %ld shutting down metrics module\n", result); */ }
- if (reportResult == EAS_SUCCESS)
- reportResult = result;
- }
- }
-#endif
-
- /* release allocated memory */
- if (!pEASData->staticMemoryModel)
- EAS_HWFree(hwInstData, pEASData);
-
- /* shutdown host wrappers */
- if (hwInstData)
- {
- if ((result = EAS_HWShutdown(hwInstData)) != EAS_SUCCESS)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Error %ld shutting down host wrappers\n", result); */ }
- if (reportResult == EAS_SUCCESS)
- reportResult = result;
- }
- }
-
- return reportResult;
+ EAS_HW_DATA_HANDLE hwInstData;
+ EAS_RESULT result, reportResult;
+ EAS_INT i;
+
+ /* establish pointers */
+ hwInstData = pEASData->hwInstData;
+
+ /* check for NULL handle */
+ if (!pEASData)
+ return EAS_ERROR_HANDLE_INTEGRITY;
+
+ /* if there are streams open, close them */
+ reportResult = EAS_SUCCESS;
+ for (i = 0; i < MAX_NUMBER_STREAMS; i++)
+ {
+ if (pEASData->streams[i].pParserModule && pEASData->streams[i].handle)
+ {
+ if ((result = (*((S_FILE_PARSER_INTERFACE*)(pEASData->streams[i].pParserModule))->pfClose)(pEASData, pEASData->streams[i].handle)) != EAS_SUCCESS)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Error %ld shutting down parser module\n", result); */ }
+ reportResult = result;
+ }
+ }
+ }
+
+ /* shutdown PCM engine */
+ if ((result = EAS_PEShutdown(pEASData)) != EAS_SUCCESS)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Error %ld shutting down PCM engine\n", result); */ }
+ if (reportResult == EAS_SUCCESS)
+ reportResult = result;
+ }
+
+ /* shutdown mix engine */
+ if ((result = EAS_MixEngineShutdown(pEASData)) != EAS_SUCCESS)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Error %ld shutting down mix engine\n", result); */ }
+ if (reportResult == EAS_SUCCESS)
+ reportResult = result;
+ }
+
+ /* shutdown effects modules */
+ for (i = 0; i < NUM_EFFECTS_MODULES; i++)
+ {
+ if (pEASData->effectsModules[i].effect)
+ {
+ if ((result = (*pEASData->effectsModules[i].effect->pfShutdown)(pEASData, pEASData->effectsModules[i].effectData)) != EAS_SUCCESS)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_FATAL, "Shutdown of effects module %d returned %d\n", i, result); */ }
+ if (reportResult == EAS_SUCCESS)
+ reportResult = result;
+ }
+ }
+ }
+
+ /* shutdown the voice manager & synthesizer */
+ VMShutdown(pEASData);
+
+#ifdef _METRICS_ENABLED
+ /* shutdown the metrics module */
+ if (pEASData->pMetricsModule != NULL)
+ {
+ if ((result = (*pEASData->pMetricsModule->pfShutdown)(pEASData, pEASData->pMetricsData)) != EAS_SUCCESS)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Error %ld shutting down metrics module\n", result); */ }
+ if (reportResult == EAS_SUCCESS)
+ reportResult = result;
+ }
+ }
+#endif
+
+ /* release allocated memory */
+ if (!pEASData->staticMemoryModel)
+ EAS_HWFree(hwInstData, pEASData);
+
+ /* shutdown host wrappers */
+ if (hwInstData)
+ {
+ if ((result = EAS_HWShutdown(hwInstData)) != EAS_SUCCESS)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Error %ld shutting down host wrappers\n", result); */ }
+ if (reportResult == EAS_SUCCESS)
+ reportResult = result;
+ }
+ }
+
+ return reportResult;
}
#ifdef JET_INTERFACE
@@ -563,53 +563,53 @@ EAS_PUBLIC EAS_RESULT EAS_Shutdown (EAS_DATA_HANDLE pEASData)
*/
EAS_RESULT EAS_OpenJETStream (EAS_DATA_HANDLE pEASData, EAS_FILE_HANDLE fileHandle, EAS_I32 offset, EAS_HANDLE *ppStream)
{
- EAS_RESULT result;
- EAS_VOID_PTR streamHandle;
- S_FILE_PARSER_INTERFACE *pParserModule;
- EAS_INT streamNum;
-
- /* allocate a stream */
- if ((streamNum = EAS_AllocateStream(pEASData)) < 0)
- return EAS_ERROR_MAX_STREAMS_OPEN;
-
- /* check Configuration Module for SMF parser */
- *ppStream = NULL;
- streamHandle = NULL;
- pParserModule = (S_FILE_PARSER_INTERFACE *) EAS_CMEnumModules(0);
- if (pParserModule == NULL)
- return EAS_ERROR_UNRECOGNIZED_FORMAT;
-
- /* see if SMF parser recognizes the file */
- if ((result = (*pParserModule->pfCheckFileType)(pEASData, fileHandle, &streamHandle, offset)) != EAS_SUCCESS)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "CheckFileType returned error %ld\n", result); */ }
- return result;
- }
-
- /* parser recognized the file, return the handle */
- if (streamHandle)
- {
- EAS_InitStream(&pEASData->streams[streamNum], pParserModule, streamHandle);
- *ppStream = &pEASData->streams[streamNum];
- return EAS_SUCCESS;
- }
-
- return EAS_ERROR_UNRECOGNIZED_FORMAT;
+ EAS_RESULT result;
+ EAS_VOID_PTR streamHandle;
+ S_FILE_PARSER_INTERFACE *pParserModule;
+ EAS_INT streamNum;
+
+ /* allocate a stream */
+ if ((streamNum = EAS_AllocateStream(pEASData)) < 0)
+ return EAS_ERROR_MAX_STREAMS_OPEN;
+
+ /* check Configuration Module for SMF parser */
+ *ppStream = NULL;
+ streamHandle = NULL;
+ pParserModule = (S_FILE_PARSER_INTERFACE *) EAS_CMEnumModules(0);
+ if (pParserModule == NULL)
+ return EAS_ERROR_UNRECOGNIZED_FORMAT;
+
+ /* see if SMF parser recognizes the file */
+ if ((result = (*pParserModule->pfCheckFileType)(pEASData, fileHandle, &streamHandle, offset)) != EAS_SUCCESS)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "CheckFileType returned error %ld\n", result); */ }
+ return result;
+ }
+
+ /* parser recognized the file, return the handle */
+ if (streamHandle)
+ {
+ EAS_InitStream(&pEASData->streams[streamNum], pParserModule, streamHandle);
+ *ppStream = &pEASData->streams[streamNum];
+ return EAS_SUCCESS;
+ }
+
+ return EAS_ERROR_UNRECOGNIZED_FORMAT;
}
#endif
/*----------------------------------------------------------------------------
* EAS_OpenFile()
*----------------------------------------------------------------------------
- * Purpose:
+ * Purpose:
* Opens a file for audio playback.
*
* Inputs:
- * pEASData - pointer to overall EAS data structure
- * pHandle - pointer to file handle
- *
+ * pEASData - pointer to overall EAS data structure
+ * pHandle - pointer to file handle
+ *
* Outputs:
- *
+ *
*
* Side Effects:
*
@@ -617,72 +617,72 @@ EAS_RESULT EAS_OpenJETStream (EAS_DATA_HANDLE pEASData, EAS_FILE_HANDLE fileHand
*/
EAS_PUBLIC EAS_RESULT EAS_OpenFile (EAS_DATA_HANDLE pEASData, EAS_FILE_LOCATOR locator, EAS_HANDLE *ppStream)
{
- EAS_RESULT result;
- EAS_FILE_HANDLE fileHandle;
- EAS_VOID_PTR streamHandle;
- S_FILE_PARSER_INTERFACE *pParserModule;
- EAS_INT streamNum;
- EAS_INT moduleNum;
-
- /* open the file */
- if ((result = EAS_HWOpenFile(pEASData->hwInstData, locator, &fileHandle, EAS_FILE_READ)) != EAS_SUCCESS)
- return result;
-
- /* allocate a stream */
- if ((streamNum = EAS_AllocateStream(pEASData)) < 0)
- return EAS_ERROR_MAX_STREAMS_OPEN;
-
- /* check Configuration Module for file parsers */
- pParserModule = NULL;
- *ppStream = NULL;
- streamHandle = NULL;
- for (moduleNum = 0; ; moduleNum++)
- {
- pParserModule = (S_FILE_PARSER_INTERFACE *) EAS_CMEnumModules(moduleNum);
- if (pParserModule == NULL)
- break;
-
- /* see if this parser recognizes it */
- if ((result = (*pParserModule->pfCheckFileType)(pEASData, fileHandle, &streamHandle, 0L)) != EAS_SUCCESS)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "CheckFileType returned error %ld\n", result); */ }
- return result;
- }
-
- /* parser recognized the file, return the handle */
- if (streamHandle)
- {
-
- /* save the parser pointer and file handle */
- EAS_InitStream(&pEASData->streams[streamNum], pParserModule, streamHandle);
- *ppStream = &pEASData->streams[streamNum];
- return EAS_SUCCESS;
- }
-
- /* rewind the file for the next parser */
- if ((result = EAS_HWFileSeek(pEASData->hwInstData, fileHandle, 0L)) != EAS_SUCCESS)
- return result;
- }
-
- /* no parser was able to recognize the file, close it and return an error */
- EAS_HWCloseFile(pEASData->hwInstData, fileHandle);
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "No parser recognized the requested file\n"); */ }
- return EAS_ERROR_UNRECOGNIZED_FORMAT;
+ EAS_RESULT result;
+ EAS_FILE_HANDLE fileHandle;
+ EAS_VOID_PTR streamHandle;
+ S_FILE_PARSER_INTERFACE *pParserModule;
+ EAS_INT streamNum;
+ EAS_INT moduleNum;
+
+ /* open the file */
+ if ((result = EAS_HWOpenFile(pEASData->hwInstData, locator, &fileHandle, EAS_FILE_READ)) != EAS_SUCCESS)
+ return result;
+
+ /* allocate a stream */
+ if ((streamNum = EAS_AllocateStream(pEASData)) < 0)
+ return EAS_ERROR_MAX_STREAMS_OPEN;
+
+ /* check Configuration Module for file parsers */
+ pParserModule = NULL;
+ *ppStream = NULL;
+ streamHandle = NULL;
+ for (moduleNum = 0; ; moduleNum++)
+ {
+ pParserModule = (S_FILE_PARSER_INTERFACE *) EAS_CMEnumModules(moduleNum);
+ if (pParserModule == NULL)
+ break;
+
+ /* see if this parser recognizes it */
+ if ((result = (*pParserModule->pfCheckFileType)(pEASData, fileHandle, &streamHandle, 0L)) != EAS_SUCCESS)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "CheckFileType returned error %ld\n", result); */ }
+ return result;
+ }
+
+ /* parser recognized the file, return the handle */
+ if (streamHandle)
+ {
+
+ /* save the parser pointer and file handle */
+ EAS_InitStream(&pEASData->streams[streamNum], pParserModule, streamHandle);
+ *ppStream = &pEASData->streams[streamNum];
+ return EAS_SUCCESS;
+ }
+
+ /* rewind the file for the next parser */
+ if ((result = EAS_HWFileSeek(pEASData->hwInstData, fileHandle, 0L)) != EAS_SUCCESS)
+ return result;
+ }
+
+ /* no parser was able to recognize the file, close it and return an error */
+ EAS_HWCloseFile(pEASData->hwInstData, fileHandle);
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "No parser recognized the requested file\n"); */ }
+ return EAS_ERROR_UNRECOGNIZED_FORMAT;
}
#ifdef MMAPI_SUPPORT
/*----------------------------------------------------------------------------
* EAS_MMAPIToneControl()
*----------------------------------------------------------------------------
- * Purpose:
+ * Purpose:
* Opens a ToneControl file for audio playback.
*
* Inputs:
- * pEASData - pointer to overall EAS data structure
- * pHandle - pointer to file handle
- *
+ * pEASData - pointer to overall EAS data structure
+ * pHandle - pointer to file handle
+ *
* Outputs:
- *
+ *
*
* Side Effects:
*
@@ -690,51 +690,51 @@ EAS_PUBLIC EAS_RESULT EAS_OpenFile (EAS_DATA_HANDLE pEASData, EAS_FILE_LOCATOR l
*/
EAS_PUBLIC EAS_RESULT EAS_MMAPIToneControl (EAS_DATA_HANDLE pEASData, EAS_FILE_LOCATOR locator, EAS_HANDLE *ppStream)
{
- EAS_RESULT result;
- EAS_FILE_HANDLE fileHandle;
- EAS_VOID_PTR streamHandle;
- S_FILE_PARSER_INTERFACE *pParserModule;
- EAS_INT streamNum;
-
- /* check if the tone control parser is available */
- *ppStream = NULL;
- streamHandle = NULL;
- pParserModule = EAS_CMEnumOptModules(EAS_MODULE_MMAPI_TONE_CONTROL);
- if (pParserModule == NULL)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "EAS_MMAPIToneControl: ToneControl parser not available\n"); */ }
- return EAS_ERROR_FEATURE_NOT_AVAILABLE;
- }
-
- /* open the file */
- if ((result = EAS_HWOpenFile(pEASData->hwInstData, locator, &fileHandle, EAS_FILE_READ)) != EAS_SUCCESS)
- return result;
-
- /* allocate a stream */
- if ((streamNum = EAS_AllocateStream(pEASData)) < 0)
- return EAS_ERROR_MAX_STREAMS_OPEN;
-
- /* see if ToneControl parser recognizes it */
- if ((result = (*pParserModule->pfCheckFileType)(pEASData, fileHandle, &streamHandle, 0L)) != EAS_SUCCESS)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "CheckFileType returned error %ld\n", result); */ }
- return result;
- }
-
- /* parser accepted the file, return the handle */
- if (streamHandle)
- {
-
- /* save the parser pointer and file handle */
- EAS_InitStream(&pEASData->streams[streamNum], pParserModule, streamHandle);
- *ppStream = &pEASData->streams[streamNum];
- return EAS_SUCCESS;
- }
-
- /* parser did not recognize the file, close it and return an error */
- EAS_HWCloseFile(pEASData->hwInstData, fileHandle);
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "No parser recognized the requested file\n"); */ }
- return EAS_ERROR_UNRECOGNIZED_FORMAT;
+ EAS_RESULT result;
+ EAS_FILE_HANDLE fileHandle;
+ EAS_VOID_PTR streamHandle;
+ S_FILE_PARSER_INTERFACE *pParserModule;
+ EAS_INT streamNum;
+
+ /* check if the tone control parser is available */
+ *ppStream = NULL;
+ streamHandle = NULL;
+ pParserModule = EAS_CMEnumOptModules(EAS_MODULE_MMAPI_TONE_CONTROL);
+ if (pParserModule == NULL)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "EAS_MMAPIToneControl: ToneControl parser not available\n"); */ }
+ return EAS_ERROR_FEATURE_NOT_AVAILABLE;
+ }
+
+ /* open the file */
+ if ((result = EAS_HWOpenFile(pEASData->hwInstData, locator, &fileHandle, EAS_FILE_READ)) != EAS_SUCCESS)
+ return result;
+
+ /* allocate a stream */
+ if ((streamNum = EAS_AllocateStream(pEASData)) < 0)
+ return EAS_ERROR_MAX_STREAMS_OPEN;
+
+ /* see if ToneControl parser recognizes it */
+ if ((result = (*pParserModule->pfCheckFileType)(pEASData, fileHandle, &streamHandle, 0L)) != EAS_SUCCESS)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "CheckFileType returned error %ld\n", result); */ }
+ return result;
+ }
+
+ /* parser accepted the file, return the handle */
+ if (streamHandle)
+ {
+
+ /* save the parser pointer and file handle */
+ EAS_InitStream(&pEASData->streams[streamNum], pParserModule, streamHandle);
+ *ppStream = &pEASData->streams[streamNum];
+ return EAS_SUCCESS;
+ }
+
+ /* parser did not recognize the file, close it and return an error */
+ EAS_HWCloseFile(pEASData->hwInstData, fileHandle);
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "No parser recognized the requested file\n"); */ }
+ return EAS_ERROR_UNRECOGNIZED_FORMAT;
}
/*----------------------------------------------------------------------------
@@ -742,20 +742,20 @@ EAS_PUBLIC EAS_RESULT EAS_MMAPIToneControl (EAS_DATA_HANDLE pEASData, EAS_FILE_L
*----------------------------------------------------------------------------
* Helper function to retrieve WAVE file fmt chunk for MMAPI
*----------------------------------------------------------------------------
- * pEASData - pointer to EAS persistent data object
- * pStream - stream handle
- * pFmtChunk - pointer to variable to receive current setting
+ * pEASData - pointer to EAS persistent data object
+ * pStream - stream handle
+ * pFmtChunk - pointer to variable to receive current setting
*----------------------------------------------------------------------------
*/
EAS_PUBLIC EAS_RESULT EAS_GetWaveFmtChunk (S_EAS_DATA *pEASData, EAS_HANDLE pStream, EAS_VOID_PTR *ppFmtChunk)
{
- EAS_RESULT result;
- EAS_I32 value;
+ EAS_RESULT result;
+ EAS_I32 value;
- if ((result = EAS_GetStreamParameter(pEASData, pStream, PARSER_DATA_FORMAT, &value)) != EAS_SUCCESS)
- return result;
- *ppFmtChunk = (EAS_VOID_PTR) value;
- return EAS_SUCCESS;
+ if ((result = EAS_GetStreamParameter(pEASData, pStream, PARSER_DATA_FORMAT, &value)) != EAS_SUCCESS)
+ return result;
+ *ppFmtChunk = (EAS_VOID_PTR) value;
+ return EAS_SUCCESS;
}
#endif
@@ -764,31 +764,31 @@ EAS_PUBLIC EAS_RESULT EAS_GetWaveFmtChunk (S_EAS_DATA *pEASData, EAS_HANDLE pStr
*----------------------------------------------------------------------------
* Returns the file type (see eas_types.h for enumerations)
*----------------------------------------------------------------------------
- * pEASData - pointer to EAS persistent data object
- * pStream - stream handle
- * pFileType - pointer to variable to receive file type
+ * pEASData - pointer to EAS persistent data object
+ * pStream - stream handle
+ * pFileType - pointer to variable to receive file type
*----------------------------------------------------------------------------
*/
EAS_PUBLIC EAS_RESULT EAS_GetFileType (S_EAS_DATA *pEASData, EAS_HANDLE pStream, EAS_I32 *pFileType)
{
- if (!EAS_StreamReady (pEASData, pStream))
- return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
- return EAS_GetStreamParameter(pEASData, pStream, PARSER_DATA_FILE_TYPE, pFileType);
+ if (!EAS_StreamReady (pEASData, pStream))
+ return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
+ return EAS_GetStreamParameter(pEASData, pStream, PARSER_DATA_FILE_TYPE, pFileType);
}
/*----------------------------------------------------------------------------
* EAS_Prepare()
*----------------------------------------------------------------------------
- * Purpose:
+ * Purpose:
* Prepares the synthesizer to play the file or stream. Parses the first
* frame of data from the file and arms the synthesizer.
*
* Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - file or stream handle
- *
+ * pEASData - pointer to overall EAS data structure
+ * handle - file or stream handle
+ *
* Outputs:
- *
+ *
*
* Side Effects:
*
@@ -796,35 +796,35 @@ EAS_PUBLIC EAS_RESULT EAS_GetFileType (S_EAS_DATA *pEASData, EAS_HANDLE pStream,
*/
EAS_PUBLIC EAS_RESULT EAS_Prepare (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream)
{
- S_FILE_PARSER_INTERFACE *pParserModule;
- EAS_STATE state;
- EAS_RESULT result;
-
- pParserModule = (S_FILE_PARSER_INTERFACE*) pStream->pParserModule;
- if (pParserModule == NULL)
- return EAS_ERROR_FEATURE_NOT_AVAILABLE;
-
- /* check for valid state */
- result = pParserModule->pfState(pEASData, pStream->handle, &state);
- if (result == EAS_SUCCESS)
- {
- /* prepare the stream */
- if (state == EAS_STATE_OPEN)
- {
- pParserModule = (S_FILE_PARSER_INTERFACE*) pStream->pParserModule;
- result = (*pParserModule->pfPrepare)(pEASData, pStream->handle);
-
- /* set volume */
- if (result == EAS_SUCCESS)
- result = EAS_SetVolume(pEASData, pStream, pStream->volume);
- }
- else
- result = EAS_ERROR_NOT_VALID_IN_THIS_STATE;
-
- }
-
- return result;
-}
+ S_FILE_PARSER_INTERFACE *pParserModule;
+ EAS_STATE state;
+ EAS_RESULT result;
+
+ pParserModule = (S_FILE_PARSER_INTERFACE*) pStream->pParserModule;
+ if (pParserModule == NULL)
+ return EAS_ERROR_FEATURE_NOT_AVAILABLE;
+
+ /* check for valid state */
+ result = pParserModule->pfState(pEASData, pStream->handle, &state);
+ if (result == EAS_SUCCESS)
+ {
+ /* prepare the stream */
+ if (state == EAS_STATE_OPEN)
+ {
+ pParserModule = (S_FILE_PARSER_INTERFACE*) pStream->pParserModule;
+ result = (*pParserModule->pfPrepare)(pEASData, pStream->handle);
+
+ /* set volume */
+ if (result == EAS_SUCCESS)
+ result = EAS_SetVolume(pEASData, pStream, pStream->volume);
+ }
+ else
+ result = EAS_ERROR_NOT_VALID_IN_THIS_STATE;
+
+ }
+
+ return result;
+}
/*----------------------------------------------------------------------------
* EAS_Render()
@@ -834,323 +834,323 @@ EAS_PUBLIC EAS_RESULT EAS_Prepare (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream)
*
* Inputs:
* pEASData - buffer for internal EAS data
- * pOut - output buffer pointer
- * nNumRequested - requested num samples to generate
- * pnNumGenerated - actual number of samples generated
+ * pOut - output buffer pointer
+ * nNumRequested - requested num samples to generate
+ * pnNumGenerated - actual number of samples generated
*
* Outputs:
- * EAS_SUCCESS if PCM data was successfully rendered
+ * EAS_SUCCESS if PCM data was successfully rendered
*
*----------------------------------------------------------------------------
*/
EAS_PUBLIC EAS_RESULT EAS_Render (EAS_DATA_HANDLE pEASData, EAS_PCM *pOut, EAS_I32 numRequested, EAS_I32 *pNumGenerated)
{
- S_FILE_PARSER_INTERFACE *pParserModule;
- EAS_RESULT result;
- EAS_I32 voicesRendered;
- EAS_STATE parserState;
- EAS_INT streamNum;
-
- /* assume no samples generated and reset workload */
- *pNumGenerated = 0;
- VMInitWorkload(pEASData->pVoiceMgr);
-
- /* no support for other buffer sizes yet */
- if (numRequested != BUFFER_SIZE_IN_MONO_SAMPLES)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "This library supports only %ld samples in buffer, host requested %ld samples\n",
- (EAS_I32) BUFFER_SIZE_IN_MONO_SAMPLES, numRequested); */ }
- return EAS_BUFFER_SIZE_MISMATCH;
- }
-
-#ifdef _METRICS_ENABLED
- /* start performance counter */
- if (pEASData->pMetricsData)
- (*pEASData->pMetricsModule->pfStartTimer)(pEASData->pMetricsData, EAS_PM_TOTAL_TIME);
+ S_FILE_PARSER_INTERFACE *pParserModule;
+ EAS_RESULT result;
+ EAS_I32 voicesRendered;
+ EAS_STATE parserState;
+ EAS_INT streamNum;
+
+ /* assume no samples generated and reset workload */
+ *pNumGenerated = 0;
+ VMInitWorkload(pEASData->pVoiceMgr);
+
+ /* no support for other buffer sizes yet */
+ if (numRequested != BUFFER_SIZE_IN_MONO_SAMPLES)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "This library supports only %ld samples in buffer, host requested %ld samples\n",
+ (EAS_I32) BUFFER_SIZE_IN_MONO_SAMPLES, numRequested); */ }
+ return EAS_BUFFER_SIZE_MISMATCH;
+ }
+
+#ifdef _METRICS_ENABLED
+ /* start performance counter */
+ if (pEASData->pMetricsData)
+ (*pEASData->pMetricsModule->pfStartTimer)(pEASData->pMetricsData, EAS_PM_TOTAL_TIME);
#endif
- /* prep the frame buffer, do mix engine prep only if TRUE */
+ /* prep the frame buffer, do mix engine prep only if TRUE */
#ifdef _SPLIT_ARCHITECTURE
- if (VMStartFrame(pEASData))
- EAS_MixEnginePrep(pEASData, numRequested);
-#else
- /* prep the mix engine */
- EAS_MixEnginePrep(pEASData, numRequested);
+ if (VMStartFrame(pEASData))
+ EAS_MixEnginePrep(pEASData, numRequested);
+#else
+ /* prep the mix engine */
+ EAS_MixEnginePrep(pEASData, numRequested);
#endif
- /* save the output buffer pointer */
- pEASData->pOutputAudioBuffer = pOut;
-
-
-#ifdef _METRICS_ENABLED
- /* start performance counter */
- if (pEASData->pMetricsData)
- (*pEASData->pMetricsModule->pfStartTimer)(pEASData->pMetricsData, EAS_PM_PARSE_TIME);
-#endif
-
- /* if we haven't finished parsing from last time, do it now */
- /* need to parse another frame of events before we render again */
- for (streamNum = 0; streamNum < MAX_NUMBER_STREAMS; streamNum++)
- {
- /* clear the locate flag */
- pEASData->streams[streamNum].streamFlags &= ~STREAM_FLAGS_LOCATE;
-
- if (pEASData->streams[streamNum].pParserModule)
- {
-
- /* establish pointer to parser module */
- pParserModule = pEASData->streams[streamNum].pParserModule;
-
- /* handle pause */
- if (pEASData->streams[streamNum].streamFlags & STREAM_FLAGS_PAUSE)
- {
- if (pParserModule->pfPause)
- result = pParserModule->pfPause(pEASData, pEASData->streams[streamNum].handle);
- pEASData->streams[streamNum].streamFlags &= ~STREAM_FLAGS_PAUSE;
- }
-
- /* get current state */
- if ((result = (*pParserModule->pfState)(pEASData, pEASData->streams[streamNum].handle, &parserState)) != EAS_SUCCESS)
- return result;
-
- /* handle resume */
- if (parserState == EAS_STATE_PAUSED)
- {
- if (pEASData->streams[streamNum].streamFlags & STREAM_FLAGS_RESUME)
- {
- if (pParserModule->pfResume)
- result = pParserModule->pfResume(pEASData, pEASData->streams[streamNum].handle);
- pEASData->streams[streamNum].streamFlags &= ~STREAM_FLAGS_RESUME;
- }
- }
-
- /* if necessary, parse stream */
- if ((pEASData->streams[streamNum].streamFlags & STREAM_FLAGS_PARSED) == 0)
- if ((result = EAS_ParseEvents(pEASData, &pEASData->streams[streamNum], pEASData->streams[streamNum].time + pEASData->streams[streamNum].frameLength, eParserModePlay)) != EAS_SUCCESS)
- return result;
-
- /* check for an early abort */
- if ((pEASData->streams[streamNum].streamFlags) == 0)
- {
-
-#ifdef _METRICS_ENABLED
- /* stop performance counter */
- if (pEASData->pMetricsData)
- (*pEASData->pMetricsModule->pfStartTimer)(pEASData->pMetricsData, EAS_PM_TOTAL_TIME);
+ /* save the output buffer pointer */
+ pEASData->pOutputAudioBuffer = pOut;
+
+
+#ifdef _METRICS_ENABLED
+ /* start performance counter */
+ if (pEASData->pMetricsData)
+ (*pEASData->pMetricsModule->pfStartTimer)(pEASData->pMetricsData, EAS_PM_PARSE_TIME);
#endif
- return EAS_SUCCESS;
- }
-
- /* check for repeat */
- if (pEASData->streams[streamNum].repeatCount)
- {
-
- /* check for stopped state */
- if ((result = (*pParserModule->pfState)(pEASData, pEASData->streams[streamNum].handle, &parserState)) != EAS_SUCCESS)
- return result;
- if (parserState == EAS_STATE_STOPPED)
- {
-
- /* decrement repeat count, unless it is negative */
- if (pEASData->streams[streamNum].repeatCount > 0)
- pEASData->streams[streamNum].repeatCount--;
-
- /* reset the parser */
- if ((result = (*pParserModule->pfReset)(pEASData, pEASData->streams[streamNum].handle)) != EAS_SUCCESS)
- return result;
- pEASData->streams[streamNum].time = 0;
- }
- }
- }
- }
-
-#ifdef _METRICS_ENABLED
- /* stop performance counter */
- if (pEASData->pMetricsData)
- (void)(*pEASData->pMetricsModule->pfStopTimer)(pEASData->pMetricsData, EAS_PM_PARSE_TIME);
+ /* if we haven't finished parsing from last time, do it now */
+ /* need to parse another frame of events before we render again */
+ for (streamNum = 0; streamNum < MAX_NUMBER_STREAMS; streamNum++)
+ {
+ /* clear the locate flag */
+ pEASData->streams[streamNum].streamFlags &= ~STREAM_FLAGS_LOCATE;
+
+ if (pEASData->streams[streamNum].pParserModule)
+ {
+
+ /* establish pointer to parser module */
+ pParserModule = pEASData->streams[streamNum].pParserModule;
+
+ /* handle pause */
+ if (pEASData->streams[streamNum].streamFlags & STREAM_FLAGS_PAUSE)
+ {
+ if (pParserModule->pfPause)
+ result = pParserModule->pfPause(pEASData, pEASData->streams[streamNum].handle);
+ pEASData->streams[streamNum].streamFlags &= ~STREAM_FLAGS_PAUSE;
+ }
+
+ /* get current state */
+ if ((result = (*pParserModule->pfState)(pEASData, pEASData->streams[streamNum].handle, &parserState)) != EAS_SUCCESS)
+ return result;
+
+ /* handle resume */
+ if (parserState == EAS_STATE_PAUSED)
+ {
+ if (pEASData->streams[streamNum].streamFlags & STREAM_FLAGS_RESUME)
+ {
+ if (pParserModule->pfResume)
+ result = pParserModule->pfResume(pEASData, pEASData->streams[streamNum].handle);
+ pEASData->streams[streamNum].streamFlags &= ~STREAM_FLAGS_RESUME;
+ }
+ }
+
+ /* if necessary, parse stream */
+ if ((pEASData->streams[streamNum].streamFlags & STREAM_FLAGS_PARSED) == 0)
+ if ((result = EAS_ParseEvents(pEASData, &pEASData->streams[streamNum], pEASData->streams[streamNum].time + pEASData->streams[streamNum].frameLength, eParserModePlay)) != EAS_SUCCESS)
+ return result;
+
+ /* check for an early abort */
+ if ((pEASData->streams[streamNum].streamFlags) == 0)
+ {
+
+#ifdef _METRICS_ENABLED
+ /* stop performance counter */
+ if (pEASData->pMetricsData)
+ (*pEASData->pMetricsModule->pfStartTimer)(pEASData->pMetricsData, EAS_PM_TOTAL_TIME);
#endif
-
-#ifdef _METRICS_ENABLED
- /* start the render timer */
- if (pEASData->pMetricsData)
- (*pEASData->pMetricsModule->pfStartTimer)(pEASData->pMetricsData, EAS_PM_RENDER_TIME);
+
+ return EAS_SUCCESS;
+ }
+
+ /* check for repeat */
+ if (pEASData->streams[streamNum].repeatCount)
+ {
+
+ /* check for stopped state */
+ if ((result = (*pParserModule->pfState)(pEASData, pEASData->streams[streamNum].handle, &parserState)) != EAS_SUCCESS)
+ return result;
+ if (parserState == EAS_STATE_STOPPED)
+ {
+
+ /* decrement repeat count, unless it is negative */
+ if (pEASData->streams[streamNum].repeatCount > 0)
+ pEASData->streams[streamNum].repeatCount--;
+
+ /* reset the parser */
+ if ((result = (*pParserModule->pfReset)(pEASData, pEASData->streams[streamNum].handle)) != EAS_SUCCESS)
+ return result;
+ pEASData->streams[streamNum].time = 0;
+ }
+ }
+ }
+ }
+
+#ifdef _METRICS_ENABLED
+ /* stop performance counter */
+ if (pEASData->pMetricsData)
+ (void)(*pEASData->pMetricsModule->pfStopTimer)(pEASData->pMetricsData, EAS_PM_PARSE_TIME);
#endif
- /* render audio */
- if ((result = VMRender(pEASData->pVoiceMgr, BUFFER_SIZE_IN_MONO_SAMPLES, pEASData->pMixBuffer, &voicesRendered)) != EAS_SUCCESS)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "pfRender function returned error %ld\n", result); */ }
- return result;
- }
-
-#ifdef _METRICS_ENABLED
- /* stop the render timer */
- if (pEASData->pMetricsData) {
- (*pEASData->pMetricsModule->pfIncrementCounter)(pEASData->pMetricsData, EAS_PM_FRAME_COUNT, 1);
- (void)(*pEASData->pMetricsModule->pfStopTimer)(pEASData->pMetricsData, EAS_PM_RENDER_TIME);
- (*pEASData->pMetricsModule->pfIncrementCounter)(pEASData->pMetricsData, EAS_PM_TOTAL_VOICE_COUNT, (EAS_U32) voicesRendered);
- (void)(*pEASData->pMetricsModule->pfRecordMaxValue)(pEASData->pMetricsData, EAS_PM_MAX_VOICES, (EAS_U32) voicesRendered);
- }
+#ifdef _METRICS_ENABLED
+ /* start the render timer */
+ if (pEASData->pMetricsData)
+ (*pEASData->pMetricsModule->pfStartTimer)(pEASData->pMetricsData, EAS_PM_RENDER_TIME);
#endif
- //2 Do we really need frameParsed?
- /* need to parse another frame of events before we render again */
- for (streamNum = 0; streamNum < MAX_NUMBER_STREAMS; streamNum++)
- if (pEASData->streams[streamNum].pParserModule != NULL)
- pEASData->streams[streamNum].streamFlags &= ~STREAM_FLAGS_PARSED;
+ /* render audio */
+ if ((result = VMRender(pEASData->pVoiceMgr, BUFFER_SIZE_IN_MONO_SAMPLES, pEASData->pMixBuffer, &voicesRendered)) != EAS_SUCCESS)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "pfRender function returned error %ld\n", result); */ }
+ return result;
+ }
-#ifdef _METRICS_ENABLED
- /* start performance counter */
- if (pEASData->pMetricsData)
- (*pEASData->pMetricsModule->pfStartTimer)(pEASData->pMetricsData, EAS_PM_STREAM_TIME);
+#ifdef _METRICS_ENABLED
+ /* stop the render timer */
+ if (pEASData->pMetricsData) {
+ (*pEASData->pMetricsModule->pfIncrementCounter)(pEASData->pMetricsData, EAS_PM_FRAME_COUNT, 1);
+ (void)(*pEASData->pMetricsModule->pfStopTimer)(pEASData->pMetricsData, EAS_PM_RENDER_TIME);
+ (*pEASData->pMetricsModule->pfIncrementCounter)(pEASData->pMetricsData, EAS_PM_TOTAL_VOICE_COUNT, (EAS_U32) voicesRendered);
+ (void)(*pEASData->pMetricsModule->pfRecordMaxValue)(pEASData->pMetricsData, EAS_PM_MAX_VOICES, (EAS_U32) voicesRendered);
+ }
#endif
- /* render PCM audio */
- if ((result = EAS_PERender(pEASData, numRequested)) != EAS_SUCCESS)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "EAS_PERender returned error %ld\n", result); */ }
- return result;
- }
-
-#ifdef _METRICS_ENABLED
- /* stop the stream timer */
- if (pEASData->pMetricsData)
- (void)(*pEASData->pMetricsModule->pfStopTimer)(pEASData->pMetricsData, EAS_PM_STREAM_TIME);
+ //2 Do we really need frameParsed?
+ /* need to parse another frame of events before we render again */
+ for (streamNum = 0; streamNum < MAX_NUMBER_STREAMS; streamNum++)
+ if (pEASData->streams[streamNum].pParserModule != NULL)
+ pEASData->streams[streamNum].streamFlags &= ~STREAM_FLAGS_PARSED;
+
+#ifdef _METRICS_ENABLED
+ /* start performance counter */
+ if (pEASData->pMetricsData)
+ (*pEASData->pMetricsModule->pfStartTimer)(pEASData->pMetricsData, EAS_PM_STREAM_TIME);
#endif
-#ifdef _METRICS_ENABLED
- /* start the post timer */
- if (pEASData->pMetricsData)
- (*pEASData->pMetricsModule->pfStartTimer)(pEASData->pMetricsData, EAS_PM_POST_TIME);
+ /* render PCM audio */
+ if ((result = EAS_PERender(pEASData, numRequested)) != EAS_SUCCESS)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "EAS_PERender returned error %ld\n", result); */ }
+ return result;
+ }
+
+#ifdef _METRICS_ENABLED
+ /* stop the stream timer */
+ if (pEASData->pMetricsData)
+ (void)(*pEASData->pMetricsModule->pfStopTimer)(pEASData->pMetricsData, EAS_PM_STREAM_TIME);
+#endif
+
+#ifdef _METRICS_ENABLED
+ /* start the post timer */
+ if (pEASData->pMetricsData)
+ (*pEASData->pMetricsModule->pfStartTimer)(pEASData->pMetricsData, EAS_PM_POST_TIME);
#endif
- /* for split architecture, send DSP vectors. Do post only if return is TRUE */
+ /* for split architecture, send DSP vectors. Do post only if return is TRUE */
#ifdef _SPLIT_ARCHITECTURE
- if (VMEndFrame(pEASData))
- {
- /* now do post-processing */
- EAS_MixEnginePost(pEASData, numRequested);
- *pNumGenerated = numRequested;
- }
-#else
- /* now do post-processing */
- EAS_MixEnginePost(pEASData, numRequested);
- *pNumGenerated = numRequested;
+ if (VMEndFrame(pEASData))
+ {
+ /* now do post-processing */
+ EAS_MixEnginePost(pEASData, numRequested);
+ *pNumGenerated = numRequested;
+ }
+#else
+ /* now do post-processing */
+ EAS_MixEnginePost(pEASData, numRequested);
+ *pNumGenerated = numRequested;
#endif
-#ifdef _METRICS_ENABLED
- /* stop the post timer */
- if (pEASData->pMetricsData)
- (void)(*pEASData->pMetricsModule->pfStopTimer)(pEASData->pMetricsData, EAS_PM_POST_TIME);
+#ifdef _METRICS_ENABLED
+ /* stop the post timer */
+ if (pEASData->pMetricsData)
+ (void)(*pEASData->pMetricsModule->pfStopTimer)(pEASData->pMetricsData, EAS_PM_POST_TIME);
#endif
- /* advance render time */
- pEASData->renderTime += AUDIO_FRAME_LENGTH;
+ /* advance render time */
+ pEASData->renderTime += AUDIO_FRAME_LENGTH;
#if 0
- /* dump workload for debug */
- if (pEASData->pVoiceMgr->workload)
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Workload = %d\n", pEASData->pVoiceMgr->workload); */ }
-#endif
-
-#ifdef _METRICS_ENABLED
- /* stop performance counter */
- if (pEASData->pMetricsData)
- {
- PERF_TIMER temp;
- temp = (*pEASData->pMetricsModule->pfStopTimer)(pEASData->pMetricsData, EAS_PM_TOTAL_TIME);
-
- /* if max render time, record the number of voices and time */
- if ((*pEASData->pMetricsModule->pfRecordMaxValue)
- (pEASData->pMetricsData, EAS_PM_MAX_CYCLES, (EAS_U32) temp))
- {
- (*pEASData->pMetricsModule->pfRecordValue)(pEASData->pMetricsData, EAS_PM_MAX_CYCLES_VOICES, (EAS_U32) voicesRendered);
- (*pEASData->pMetricsModule->pfRecordValue)(pEASData->pMetricsData, EAS_PM_MAX_CYCLES_TIME, (EAS_I32) (pEASData->renderTime >> 8));
- }
- }
+ /* dump workload for debug */
+ if (pEASData->pVoiceMgr->workload)
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Workload = %d\n", pEASData->pVoiceMgr->workload); */ }
+#endif
+
+#ifdef _METRICS_ENABLED
+ /* stop performance counter */
+ if (pEASData->pMetricsData)
+ {
+ PERF_TIMER temp;
+ temp = (*pEASData->pMetricsModule->pfStopTimer)(pEASData->pMetricsData, EAS_PM_TOTAL_TIME);
+
+ /* if max render time, record the number of voices and time */
+ if ((*pEASData->pMetricsModule->pfRecordMaxValue)
+ (pEASData->pMetricsData, EAS_PM_MAX_CYCLES, (EAS_U32) temp))
+ {
+ (*pEASData->pMetricsModule->pfRecordValue)(pEASData->pMetricsData, EAS_PM_MAX_CYCLES_VOICES, (EAS_U32) voicesRendered);
+ (*pEASData->pMetricsModule->pfRecordValue)(pEASData->pMetricsData, EAS_PM_MAX_CYCLES_TIME, (EAS_I32) (pEASData->renderTime >> 8));
+ }
+ }
#endif
#ifdef JET_INTERFACE
- /* let JET to do its thing */
- if (pEASData->jetHandle != NULL)
- {
- result = JET_Process(pEASData);
- if (result != EAS_SUCCESS)
- return result;
- }
+ /* let JET to do its thing */
+ if (pEASData->jetHandle != NULL)
+ {
+ result = JET_Process(pEASData);
+ if (result != EAS_SUCCESS)
+ return result;
+ }
#endif
- return EAS_SUCCESS;
+ return EAS_SUCCESS;
}
/*----------------------------------------------------------------------------
* EAS_SetRepeat()
*----------------------------------------------------------------------------
- * Purpose:
+ * Purpose:
* Set the selected stream to repeat.
*
* Inputs:
- * pEASData - handle to data for this instance
- * handle - handle to stream
- * repeatCount - repeat count
- *
+ * pEASData - handle to data for this instance
+ * handle - handle to stream
+ * repeatCount - repeat count
+ *
* Outputs:
*
* Side Effects:
*
* Notes:
- * 0 = no repeat
- * 1 = repeat once, i.e. play through twice
+ * 0 = no repeat
+ * 1 = repeat once, i.e. play through twice
* -1 = repeat forever
*----------------------------------------------------------------------------
*/
/*lint -esym(715, pEASData) reserved for future use */
EAS_PUBLIC EAS_RESULT EAS_SetRepeat (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_I32 repeatCount)
{
- pStream->repeatCount = repeatCount;
- return EAS_SUCCESS;
+ pStream->repeatCount = repeatCount;
+ return EAS_SUCCESS;
}
/*----------------------------------------------------------------------------
* EAS_GetRepeat()
*----------------------------------------------------------------------------
- * Purpose:
+ * Purpose:
* Gets the current repeat count for the selected stream.
*
* Inputs:
- * pEASData - handle to data for this instance
- * handle - handle to stream
- * pRrepeatCount - pointer to variable to hold repeat count
- *
+ * pEASData - handle to data for this instance
+ * handle - handle to stream
+ * pRrepeatCount - pointer to variable to hold repeat count
+ *
* Outputs:
*
* Side Effects:
*
* Notes:
- * 0 = no repeat
- * 1 = repeat once, i.e. play through twice
+ * 0 = no repeat
+ * 1 = repeat once, i.e. play through twice
* -1 = repeat forever
*----------------------------------------------------------------------------
*/
/*lint -esym(715, pEASData) reserved for future use */
EAS_PUBLIC EAS_RESULT EAS_GetRepeat (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_I32 *pRepeatCount)
{
- *pRepeatCount = pStream->repeatCount;
- return EAS_SUCCESS;
+ *pRepeatCount = pStream->repeatCount;
+ return EAS_SUCCESS;
}
/*----------------------------------------------------------------------------
* EAS_SetPlaybackRate()
*----------------------------------------------------------------------------
- * Purpose:
+ * Purpose:
* Sets the playback rate.
*
* Inputs:
- * pEASData - handle to data for this instance
- * handle - handle to stream
- * rate - rate (28-bit fractional amount)
- *
+ * pEASData - handle to data for this instance
+ * handle - handle to stream
+ * rate - rate (28-bit fractional amount)
+ *
* Outputs:
*
* Side Effects:
@@ -1161,37 +1161,37 @@ EAS_PUBLIC EAS_RESULT EAS_GetRepeat (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStrea
EAS_PUBLIC EAS_RESULT EAS_SetPlaybackRate (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_U32 rate)
{
- /* check range */
- if ((rate < (1 << 27)) || (rate > (1 << 29)))
- return EAS_ERROR_INVALID_PARAMETER;
-
- /* calculate new frame length
- *
- * NOTE: The maximum frame length we can accomodate based on a
- * maximum rate of 2.0 (2^28) is 2047 (2^13-1). To accomodate a
- * longer frame length or a higher maximum rate, the fixed point
- * divide below will need to be adjusted
- */
- pStream->frameLength = (AUDIO_FRAME_LENGTH * (rate >> 8)) >> 20;
-
- /* notify stream of new playback rate */
- EAS_SetStreamParameter(pEASData, pStream, PARSER_DATA_PLAYBACK_RATE, (EAS_I32) rate);
- return EAS_SUCCESS;
+ /* check range */
+ if ((rate < (1 << 27)) || (rate > (1 << 29)))
+ return EAS_ERROR_INVALID_PARAMETER;
+
+ /* calculate new frame length
+ *
+ * NOTE: The maximum frame length we can accomodate based on a
+ * maximum rate of 2.0 (2^28) is 2047 (2^13-1). To accomodate a
+ * longer frame length or a higher maximum rate, the fixed point
+ * divide below will need to be adjusted
+ */
+ pStream->frameLength = (AUDIO_FRAME_LENGTH * (rate >> 8)) >> 20;
+
+ /* notify stream of new playback rate */
+ EAS_SetStreamParameter(pEASData, pStream, PARSER_DATA_PLAYBACK_RATE, (EAS_I32) rate);
+ return EAS_SUCCESS;
}
/*----------------------------------------------------------------------------
* EAS_SetTransposition)
*----------------------------------------------------------------------------
- * Purpose:
+ * Purpose:
* Sets the key tranposition for the synthesizer. Transposes all
* melodic instruments by the specified amount. Range is limited
* to +/-12 semitones.
*
* Inputs:
- * pEASData - handle to data for this instance
- * handle - handle to stream
- * transposition - +/-12 semitones
- *
+ * pEASData - handle to data for this instance
+ * handle - handle to stream
+ * transposition - +/-12 semitones
+ *
* Outputs:
*
* Side Effects:
@@ -1201,15 +1201,15 @@ EAS_PUBLIC EAS_RESULT EAS_SetPlaybackRate (EAS_DATA_HANDLE pEASData, EAS_HANDLE
EAS_PUBLIC EAS_RESULT EAS_SetTransposition (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_I32 transposition)
{
- /* check range */
- if ((transposition < -12) || (transposition > 12))
- return EAS_ERROR_INVALID_PARAMETER;
+ /* check range */
+ if ((transposition < -12) || (transposition > 12))
+ return EAS_ERROR_INVALID_PARAMETER;
- if (!EAS_StreamReady(pEASData, pStream))
- return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
- return EAS_IntSetStrmParam(pEASData, pStream, PARSER_DATA_TRANSPOSITION, transposition);
+ if (!EAS_StreamReady(pEASData, pStream))
+ return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
+ return EAS_IntSetStrmParam(pEASData, pStream, PARSER_DATA_TRANSPOSITION, transposition);
}
-
+
/*----------------------------------------------------------------------------
* EAS_ParseEvents()
*----------------------------------------------------------------------------
@@ -1218,204 +1218,204 @@ EAS_PUBLIC EAS_RESULT EAS_SetTransposition (EAS_DATA_HANDLE pEASData, EAS_HANDLE
*
* Inputs:
* pEASData - buffer for internal EAS data
- * endTime - stop parsing if this time is reached
- * parseMode - play, locate, or metadata
+ * endTime - stop parsing if this time is reached
+ * parseMode - play, locate, or metadata
*
* Outputs:
- * EAS_SUCCESS if PCM data was successfully rendered
+ * EAS_SUCCESS if PCM data was successfully rendered
*
*----------------------------------------------------------------------------
*/
static EAS_RESULT EAS_ParseEvents (S_EAS_DATA *pEASData, EAS_HANDLE pStream, EAS_U32 endTime, EAS_INT parseMode)
{
- S_FILE_PARSER_INTERFACE *pParserModule;
- EAS_RESULT result;
- EAS_I32 parserState;
- EAS_BOOL done;
- EAS_INT yieldCount = YIELD_EVENT_COUNT;
- EAS_U32 time = 0;
-
- /* does this parser have a time function? */
- pParserModule = pStream->pParserModule;
- if (pParserModule->pfTime == NULL)
- {
- /* check state */
- if ((result = (*pParserModule->pfState)(pEASData, pStream->handle, &parserState)) != EAS_SUCCESS)
- return result;
- /* if play state, advance time */
- if ((parserState >= EAS_STATE_READY) && (parserState <= EAS_STATE_PAUSING))
- pStream->time += pStream->frameLength;
- done = EAS_TRUE;
- }
-
- /* assume we're not done, in case we abort out */
- else
- {
- pStream->streamFlags &= ~STREAM_FLAGS_PARSED;
- done = EAS_FALSE;
- }
-
- while (!done)
- {
-
- /* check for stopped state */
- if ((result = (*pParserModule->pfState)(pEASData, pStream->handle, &parserState)) != EAS_SUCCESS)
- return result;
- if (parserState > EAS_STATE_PLAY)
- {
- /* save current time if we're not in play mode */
- if (parseMode != eParserModePlay)
- pStream->time = time << 8;
- done = EAS_TRUE;
- break;
- }
-
- /* get the next event time */
- if (pParserModule->pfTime)
- {
- if ((result = (*pParserModule->pfTime)(pEASData, pStream->handle, &time)) != EAS_SUCCESS)
- return result;
-
- /* if next event is within this frame, parse it */
- if (time < (endTime >> 8))
- {
-
- /* parse the next event */
- if (pParserModule->pfEvent)
- if ((result = (*pParserModule->pfEvent)(pEASData, pStream->handle, parseMode)) != EAS_SUCCESS)
- return result;
- }
-
- /* no more events in this frame, advance time */
- else
- {
- pStream->time = endTime;
- done = EAS_TRUE;
- }
- }
-
- /* check for max workload exceeded */
- if (VMCheckWorkload(pEASData->pVoiceMgr))
- {
- /* stop even though we may not have parsed
- * all the events in this frame. The parser will try to
- * catch up on the next frame.
- */
- break;
- }
-
- /* give host a chance for an early abort */
- if (--yieldCount == 0)
- {
- if (EAS_HWYield(pEASData->hwInstData))
- break;
- yieldCount = YIELD_EVENT_COUNT;
- }
- }
-
- /* if no early abort, parsing is complete for this frame */
- if (done)
- pStream->streamFlags |= STREAM_FLAGS_PARSED;
-
- return EAS_SUCCESS;
+ S_FILE_PARSER_INTERFACE *pParserModule;
+ EAS_RESULT result;
+ EAS_I32 parserState;
+ EAS_BOOL done;
+ EAS_INT yieldCount = YIELD_EVENT_COUNT;
+ EAS_U32 time = 0;
+
+ /* does this parser have a time function? */
+ pParserModule = pStream->pParserModule;
+ if (pParserModule->pfTime == NULL)
+ {
+ /* check state */
+ if ((result = (*pParserModule->pfState)(pEASData, pStream->handle, &parserState)) != EAS_SUCCESS)
+ return result;
+ /* if play state, advance time */
+ if ((parserState >= EAS_STATE_READY) && (parserState <= EAS_STATE_PAUSING))
+ pStream->time += pStream->frameLength;
+ done = EAS_TRUE;
+ }
+
+ /* assume we're not done, in case we abort out */
+ else
+ {
+ pStream->streamFlags &= ~STREAM_FLAGS_PARSED;
+ done = EAS_FALSE;
+ }
+
+ while (!done)
+ {
+
+ /* check for stopped state */
+ if ((result = (*pParserModule->pfState)(pEASData, pStream->handle, &parserState)) != EAS_SUCCESS)
+ return result;
+ if (parserState > EAS_STATE_PLAY)
+ {
+ /* save current time if we're not in play mode */
+ if (parseMode != eParserModePlay)
+ pStream->time = time << 8;
+ done = EAS_TRUE;
+ break;
+ }
+
+ /* get the next event time */
+ if (pParserModule->pfTime)
+ {
+ if ((result = (*pParserModule->pfTime)(pEASData, pStream->handle, &time)) != EAS_SUCCESS)
+ return result;
+
+ /* if next event is within this frame, parse it */
+ if (time < (endTime >> 8))
+ {
+
+ /* parse the next event */
+ if (pParserModule->pfEvent)
+ if ((result = (*pParserModule->pfEvent)(pEASData, pStream->handle, parseMode)) != EAS_SUCCESS)
+ return result;
+ }
+
+ /* no more events in this frame, advance time */
+ else
+ {
+ pStream->time = endTime;
+ done = EAS_TRUE;
+ }
+ }
+
+ /* check for max workload exceeded */
+ if (VMCheckWorkload(pEASData->pVoiceMgr))
+ {
+ /* stop even though we may not have parsed
+ * all the events in this frame. The parser will try to
+ * catch up on the next frame.
+ */
+ break;
+ }
+
+ /* give host a chance for an early abort */
+ if (--yieldCount == 0)
+ {
+ if (EAS_HWYield(pEASData->hwInstData))
+ break;
+ yieldCount = YIELD_EVENT_COUNT;
+ }
+ }
+
+ /* if no early abort, parsing is complete for this frame */
+ if (done)
+ pStream->streamFlags |= STREAM_FLAGS_PARSED;
+
+ return EAS_SUCCESS;
}
/*----------------------------------------------------------------------------
* EAS_ParseMetaData()
*----------------------------------------------------------------------------
- * Purpose:
- *
+ * Purpose:
+ *
*
* Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - file or stream handle
- * playLength - pointer to variable to store the play length (in msecs)
- *
+ * pEASData - pointer to overall EAS data structure
+ * handle - file or stream handle
+ * playLength - pointer to variable to store the play length (in msecs)
+ *
* Outputs:
- *
+ *
*
* Side Effects:
- * - resets the parser to the start of the file
+ * - resets the parser to the start of the file
*----------------------------------------------------------------------------
*/
EAS_PUBLIC EAS_RESULT EAS_ParseMetaData (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_I32 *playLength)
{
- S_FILE_PARSER_INTERFACE *pParserModule;
- EAS_RESULT result;
- EAS_STATE state;
-
- pParserModule = (S_FILE_PARSER_INTERFACE*) pStream->pParserModule;
- if (pParserModule == NULL)
- return EAS_ERROR_FEATURE_NOT_AVAILABLE;
-
- /* check parser state */
- if ((result = (*pParserModule->pfState)(pEASData, pStream->handle, &state)) != EAS_SUCCESS)
- return result;
- if (state >= EAS_STATE_OPEN)
- return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
-
- /* if parser has metadata function, use that */
- if (pParserModule->pfGetMetaData != NULL)
- return pParserModule->pfGetMetaData(pEASData, pStream->handle, playLength);
-
- /* reset the parser to the beginning */
- if ((result = (*pParserModule->pfReset)(pEASData, pStream->handle)) != EAS_SUCCESS)
- return result;
-
- /* parse the file to end */
- pStream->time = 0;
- VMInitWorkload(pEASData->pVoiceMgr);
- if ((result = EAS_ParseEvents(pEASData, pStream, 0x7fffffff, eParserModeMetaData)) != EAS_SUCCESS)
- return result;
-
- /* get the parser time */
- if ((result = EAS_GetLocation(pEASData, pStream, playLength)) != EAS_SUCCESS)
- return result;
-
- /* reset the parser to the beginning */
- pStream->time = 0;
- return (*pParserModule->pfReset)(pEASData, pStream->handle);
+ S_FILE_PARSER_INTERFACE *pParserModule;
+ EAS_RESULT result;
+ EAS_STATE state;
+
+ pParserModule = (S_FILE_PARSER_INTERFACE*) pStream->pParserModule;
+ if (pParserModule == NULL)
+ return EAS_ERROR_FEATURE_NOT_AVAILABLE;
+
+ /* check parser state */
+ if ((result = (*pParserModule->pfState)(pEASData, pStream->handle, &state)) != EAS_SUCCESS)
+ return result;
+ if (state >= EAS_STATE_OPEN)
+ return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
+
+ /* if parser has metadata function, use that */
+ if (pParserModule->pfGetMetaData != NULL)
+ return pParserModule->pfGetMetaData(pEASData, pStream->handle, playLength);
+
+ /* reset the parser to the beginning */
+ if ((result = (*pParserModule->pfReset)(pEASData, pStream->handle)) != EAS_SUCCESS)
+ return result;
+
+ /* parse the file to end */
+ pStream->time = 0;
+ VMInitWorkload(pEASData->pVoiceMgr);
+ if ((result = EAS_ParseEvents(pEASData, pStream, 0x7fffffff, eParserModeMetaData)) != EAS_SUCCESS)
+ return result;
+
+ /* get the parser time */
+ if ((result = EAS_GetLocation(pEASData, pStream, playLength)) != EAS_SUCCESS)
+ return result;
+
+ /* reset the parser to the beginning */
+ pStream->time = 0;
+ return (*pParserModule->pfReset)(pEASData, pStream->handle);
}
/*----------------------------------------------------------------------------
* EAS_RegisterMetaDataCallback()
*----------------------------------------------------------------------------
- * Purpose:
- * Registers a metadata callback function for parsed metadata.
+ * Purpose:
+ * Registers a metadata callback function for parsed metadata.
*
* Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - file or stream handle
- * cbFunc - pointer to host callback function
- * metaDataBuffer - pointer to metadata buffer
- * metaDataBufSize - maximum size of the metadata buffer
- *
+ * pEASData - pointer to overall EAS data structure
+ * handle - file or stream handle
+ * cbFunc - pointer to host callback function
+ * metaDataBuffer - pointer to metadata buffer
+ * metaDataBufSize - maximum size of the metadata buffer
+ *
* Outputs:
- *
+ *
*
* Side Effects:
*
*----------------------------------------------------------------------------
*/
EAS_PUBLIC EAS_RESULT EAS_RegisterMetaDataCallback (
- EAS_DATA_HANDLE pEASData,
- EAS_HANDLE pStream,
- EAS_METADATA_CBFUNC cbFunc,
- char *metaDataBuffer,
- EAS_I32 metaDataBufSize,
- EAS_VOID_PTR pUserData)
+ EAS_DATA_HANDLE pEASData,
+ EAS_HANDLE pStream,
+ EAS_METADATA_CBFUNC cbFunc,
+ char *metaDataBuffer,
+ EAS_I32 metaDataBufSize,
+ EAS_VOID_PTR pUserData)
{
- S_METADATA_CB metadata;
-
- if (!EAS_StreamReady(pEASData, pStream))
- return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
-
- /* register callback function */
- metadata.callback = cbFunc;
- metadata.buffer = metaDataBuffer;
- metadata.bufferSize = metaDataBufSize;
- metadata.pUserData = pUserData;
- return EAS_SetStreamParameter(pEASData, pStream, PARSER_DATA_METADATA_CB, (EAS_I32) &metadata);
+ S_METADATA_CB metadata;
+
+ if (!EAS_StreamReady(pEASData, pStream))
+ return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
+
+ /* register callback function */
+ metadata.callback = cbFunc;
+ metadata.buffer = metaDataBuffer;
+ metadata.bufferSize = metaDataBufSize;
+ metadata.pUserData = pUserData;
+ return EAS_SetStreamParameter(pEASData, pStream, PARSER_DATA_METADATA_CB, (EAS_I32) &metadata);
}
/*----------------------------------------------------------------------------
@@ -1426,24 +1426,24 @@ EAS_PUBLIC EAS_RESULT EAS_RegisterMetaDataCallback (
*/
EAS_PUBLIC EAS_RESULT EAS_GetNoteCount (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_I32 *pNoteCount)
{
- if (!EAS_StreamReady(pEASData, pStream))
- return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
- return EAS_IntGetStrmParam(pEASData, pStream, PARSER_DATA_NOTE_COUNT, pNoteCount);
+ if (!EAS_StreamReady(pEASData, pStream))
+ return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
+ return EAS_IntGetStrmParam(pEASData, pStream, PARSER_DATA_NOTE_COUNT, pNoteCount);
}
/*----------------------------------------------------------------------------
* EAS_CloseFile()
*----------------------------------------------------------------------------
- * Purpose:
+ * Purpose:
* Closes an audio file or stream. Playback should have either paused or
* completed (EAS_State returns EAS_PAUSED or EAS_STOPPED).
*
* Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - file or stream handle
- *
+ * pEASData - pointer to overall EAS data structure
+ * handle - file or stream handle
+ *
* Outputs:
- *
+ *
*
* Side Effects:
*
@@ -1451,34 +1451,34 @@ EAS_PUBLIC EAS_RESULT EAS_GetNoteCount (EAS_DATA_HANDLE pEASData, EAS_HANDLE pSt
*/
EAS_PUBLIC EAS_RESULT EAS_CloseFile (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream)
{
- S_FILE_PARSER_INTERFACE *pParserModule;
- EAS_RESULT result;
+ S_FILE_PARSER_INTERFACE *pParserModule;
+ EAS_RESULT result;
- /* call the close function */
- pParserModule = (S_FILE_PARSER_INTERFACE*) pStream->pParserModule;
- if (pParserModule == NULL)
- return EAS_ERROR_FEATURE_NOT_AVAILABLE;
+ /* call the close function */
+ pParserModule = (S_FILE_PARSER_INTERFACE*) pStream->pParserModule;
+ if (pParserModule == NULL)
+ return EAS_ERROR_FEATURE_NOT_AVAILABLE;
- result = (*pParserModule->pfClose)(pEASData, pStream->handle);
+ result = (*pParserModule->pfClose)(pEASData, pStream->handle);
- /* clear the handle and parser interface pointer */
- pStream->handle = NULL;
- pStream->pParserModule = NULL;
- return result;
-}
+ /* clear the handle and parser interface pointer */
+ pStream->handle = NULL;
+ pStream->pParserModule = NULL;
+ return result;
+}
/*----------------------------------------------------------------------------
* EAS_OpenMIDIStream()
*----------------------------------------------------------------------------
- * Purpose:
+ * Purpose:
* Opens a raw MIDI stream allowing the host to route MIDI cable data directly to the synthesizer
*
* Inputs:
- * pEASData - pointer to overall EAS data structure
- * pHandle - pointer to variable to hold file or stream handle
- *
+ * pEASData - pointer to overall EAS data structure
+ * pHandle - pointer to variable to hold file or stream handle
+ *
* Outputs:
- *
+ *
*
* Side Effects:
*
@@ -1486,75 +1486,75 @@ EAS_PUBLIC EAS_RESULT EAS_CloseFile (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStrea
*/
EAS_PUBLIC EAS_RESULT EAS_OpenMIDIStream (EAS_DATA_HANDLE pEASData, EAS_HANDLE *ppStream, EAS_HANDLE streamHandle)
{
- EAS_RESULT result;
- S_INTERACTIVE_MIDI *pMIDIStream;
- EAS_INT streamNum;
-
- /* initialize some pointers */
- *ppStream = NULL;
-
- /* allocate a stream */
- if ((streamNum = EAS_AllocateStream(pEASData)) < 0)
- return EAS_ERROR_MAX_STREAMS_OPEN;
-
- /* check Configuration Module for S_EAS_DATA allocation */
- if (pEASData->staticMemoryModel)
- pMIDIStream = EAS_CMEnumData(EAS_CM_MIDI_STREAM_DATA);
- else
- pMIDIStream = EAS_HWMalloc(pEASData->hwInstData, sizeof(S_INTERACTIVE_MIDI));
-
- /* allocate dynamic memory */
- if (!pMIDIStream)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_FATAL, "Failed to allocate MIDI stream data\n"); */ }
- return EAS_ERROR_MALLOC_FAILED;
- }
-
- /* zero the memory to insure complete initialization */
- EAS_HWMemSet(pMIDIStream, 0, sizeof(S_INTERACTIVE_MIDI));
- EAS_InitStream(&pEASData->streams[streamNum], NULL, pMIDIStream);
-
- /* instantiate a new synthesizer */
- if (streamHandle == NULL)
- {
- result = VMInitMIDI(pEASData, &pMIDIStream->pSynth);
- }
-
- /* use an existing synthesizer */
- else
- {
- EAS_I32 value;
- result = EAS_GetStreamParameter(pEASData, streamHandle, PARSER_DATA_SYNTH_HANDLE, &value);
- pMIDIStream->pSynth = (S_SYNTH*) value;
- VMIncRefCount(pMIDIStream->pSynth);
- }
- if (result != EAS_SUCCESS)
- {
- EAS_CloseMIDIStream(pEASData, &pEASData->streams[streamNum]);
- return result;
- }
-
- /* initialize the MIDI stream data */
- EAS_InitMIDIStream(&pMIDIStream->stream);
-
- *ppStream = (EAS_HANDLE) &pEASData->streams[streamNum];
- return EAS_SUCCESS;
-}
+ EAS_RESULT result;
+ S_INTERACTIVE_MIDI *pMIDIStream;
+ EAS_INT streamNum;
+
+ /* initialize some pointers */
+ *ppStream = NULL;
+
+ /* allocate a stream */
+ if ((streamNum = EAS_AllocateStream(pEASData)) < 0)
+ return EAS_ERROR_MAX_STREAMS_OPEN;
+
+ /* check Configuration Module for S_EAS_DATA allocation */
+ if (pEASData->staticMemoryModel)
+ pMIDIStream = EAS_CMEnumData(EAS_CM_MIDI_STREAM_DATA);
+ else
+ pMIDIStream = EAS_HWMalloc(pEASData->hwInstData, sizeof(S_INTERACTIVE_MIDI));
+
+ /* allocate dynamic memory */
+ if (!pMIDIStream)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_FATAL, "Failed to allocate MIDI stream data\n"); */ }
+ return EAS_ERROR_MALLOC_FAILED;
+ }
+
+ /* zero the memory to insure complete initialization */
+ EAS_HWMemSet(pMIDIStream, 0, sizeof(S_INTERACTIVE_MIDI));
+ EAS_InitStream(&pEASData->streams[streamNum], NULL, pMIDIStream);
+
+ /* instantiate a new synthesizer */
+ if (streamHandle == NULL)
+ {
+ result = VMInitMIDI(pEASData, &pMIDIStream->pSynth);
+ }
+
+ /* use an existing synthesizer */
+ else
+ {
+ EAS_I32 value;
+ result = EAS_GetStreamParameter(pEASData, streamHandle, PARSER_DATA_SYNTH_HANDLE, &value);
+ pMIDIStream->pSynth = (S_SYNTH*) value;
+ VMIncRefCount(pMIDIStream->pSynth);
+ }
+ if (result != EAS_SUCCESS)
+ {
+ EAS_CloseMIDIStream(pEASData, &pEASData->streams[streamNum]);
+ return result;
+ }
+
+ /* initialize the MIDI stream data */
+ EAS_InitMIDIStream(&pMIDIStream->stream);
+
+ *ppStream = (EAS_HANDLE) &pEASData->streams[streamNum];
+ return EAS_SUCCESS;
+}
/*----------------------------------------------------------------------------
* EAS_WriteMIDIStream()
*----------------------------------------------------------------------------
- * Purpose:
+ * Purpose:
* Send data to the MIDI stream device
*
* Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - stream handle
- * pBuffer - pointer to buffer
- * count - number of bytes to write
- *
+ * pEASData - pointer to overall EAS data structure
+ * handle - stream handle
+ * pBuffer - pointer to buffer
+ * count - number of bytes to write
+ *
* Outputs:
- *
+ *
*
* Side Effects:
*
@@ -1562,35 +1562,35 @@ EAS_PUBLIC EAS_RESULT EAS_OpenMIDIStream (EAS_DATA_HANDLE pEASData, EAS_HANDLE *
*/
EAS_PUBLIC EAS_RESULT EAS_WriteMIDIStream (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_U8 *pBuffer, EAS_I32 count)
{
- S_INTERACTIVE_MIDI *pMIDIStream;
- EAS_RESULT result;
+ S_INTERACTIVE_MIDI *pMIDIStream;
+ EAS_RESULT result;
- pMIDIStream = (S_INTERACTIVE_MIDI*) pStream->handle;
+ pMIDIStream = (S_INTERACTIVE_MIDI*) pStream->handle;
- if (count <= 0)
- return EAS_ERROR_PARAMETER_RANGE;
+ if (count <= 0)
+ return EAS_ERROR_PARAMETER_RANGE;
- /* send the entire buffer */
- while (count--)
- {
- if ((result = EAS_ParseMIDIStream(pEASData, pMIDIStream->pSynth, &pMIDIStream->stream, *pBuffer++, eParserModePlay)) != EAS_SUCCESS)
- return result;
- }
- return EAS_SUCCESS;
+ /* send the entire buffer */
+ while (count--)
+ {
+ if ((result = EAS_ParseMIDIStream(pEASData, pMIDIStream->pSynth, &pMIDIStream->stream, *pBuffer++, eParserModePlay)) != EAS_SUCCESS)
+ return result;
+ }
+ return EAS_SUCCESS;
}
/*----------------------------------------------------------------------------
* EAS_CloseMIDIStream()
*----------------------------------------------------------------------------
- * Purpose:
+ * Purpose:
* Closes a raw MIDI stream
*
* Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - stream handle
- *
+ * pEASData - pointer to overall EAS data structure
+ * handle - stream handle
+ *
* Outputs:
- *
+ *
*
* Side Effects:
*
@@ -1598,37 +1598,37 @@ EAS_PUBLIC EAS_RESULT EAS_WriteMIDIStream (EAS_DATA_HANDLE pEASData, EAS_HANDLE
*/
EAS_PUBLIC EAS_RESULT EAS_CloseMIDIStream (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream)
{
- S_INTERACTIVE_MIDI *pMIDIStream;
+ S_INTERACTIVE_MIDI *pMIDIStream;
- pMIDIStream = (S_INTERACTIVE_MIDI*) pStream->handle;
+ pMIDIStream = (S_INTERACTIVE_MIDI*) pStream->handle;
- /* close synth */
- if (pMIDIStream->pSynth != NULL)
- {
- VMMIDIShutdown(pEASData, pMIDIStream->pSynth);
- pMIDIStream->pSynth = NULL;
- }
+ /* close synth */
+ if (pMIDIStream->pSynth != NULL)
+ {
+ VMMIDIShutdown(pEASData, pMIDIStream->pSynth);
+ pMIDIStream->pSynth = NULL;
+ }
- /* release allocated memory */
- if (!pEASData->staticMemoryModel)
- EAS_HWFree(((S_EAS_DATA*) pEASData)->hwInstData, pMIDIStream);
+ /* release allocated memory */
+ if (!pEASData->staticMemoryModel)
+ EAS_HWFree(((S_EAS_DATA*) pEASData)->hwInstData, pMIDIStream);
- pStream->handle = NULL;
- return EAS_SUCCESS;
+ pStream->handle = NULL;
+ return EAS_SUCCESS;
}
/*----------------------------------------------------------------------------
* EAS_State()
*----------------------------------------------------------------------------
- * Purpose:
- * Returns the state of an audio file or stream.
+ * Purpose:
+ * Returns the state of an audio file or stream.
*
* Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - file or stream handle
- *
+ * pEASData - pointer to overall EAS data structure
+ * handle - file or stream handle
+ *
* Outputs:
- *
+ *
*
* Side Effects:
*
@@ -1636,53 +1636,53 @@ EAS_PUBLIC EAS_RESULT EAS_CloseMIDIStream (EAS_DATA_HANDLE pEASData, EAS_HANDLE
*/
EAS_PUBLIC EAS_RESULT EAS_State (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_STATE *pState)
{
- S_FILE_PARSER_INTERFACE *pParserModule;
- EAS_RESULT result;
-
- /* call the parser to return state */
- pParserModule = (S_FILE_PARSER_INTERFACE*) pStream->pParserModule;
- if (pParserModule == NULL)
- return EAS_ERROR_FEATURE_NOT_AVAILABLE;
-
- if ((result = (*pParserModule->pfState)(pEASData, pStream->handle, pState)) != EAS_SUCCESS)
- return result;
-
- /* if repeat count is set for this parser, mask the stopped state from the application */
- if (pStream->repeatCount && (*pState == EAS_STATE_STOPPED))
- *pState = EAS_STATE_PLAY;
-
- /* if we're not ready or playing, we don't need to hide state from host */
- if (*pState > EAS_STATE_PLAY)
- return EAS_SUCCESS;
-
- /* if stream is about to be paused, report it as paused */
- if (pStream->streamFlags & STREAM_FLAGS_PAUSE)
- {
- if (pStream->streamFlags & STREAM_FLAGS_LOCATE)
- *pState = EAS_STATE_PAUSED;
- else
- *pState = EAS_STATE_PAUSING;
- }
-
- /* if stream is about to resume, report it as playing */
- if (pStream->streamFlags & STREAM_FLAGS_RESUME)
- *pState = EAS_STATE_PLAY;
-
- return EAS_SUCCESS;
+ S_FILE_PARSER_INTERFACE *pParserModule;
+ EAS_RESULT result;
+
+ /* call the parser to return state */
+ pParserModule = (S_FILE_PARSER_INTERFACE*) pStream->pParserModule;
+ if (pParserModule == NULL)
+ return EAS_ERROR_FEATURE_NOT_AVAILABLE;
+
+ if ((result = (*pParserModule->pfState)(pEASData, pStream->handle, pState)) != EAS_SUCCESS)
+ return result;
+
+ /* if repeat count is set for this parser, mask the stopped state from the application */
+ if (pStream->repeatCount && (*pState == EAS_STATE_STOPPED))
+ *pState = EAS_STATE_PLAY;
+
+ /* if we're not ready or playing, we don't need to hide state from host */
+ if (*pState > EAS_STATE_PLAY)
+ return EAS_SUCCESS;
+
+ /* if stream is about to be paused, report it as paused */
+ if (pStream->streamFlags & STREAM_FLAGS_PAUSE)
+ {
+ if (pStream->streamFlags & STREAM_FLAGS_LOCATE)
+ *pState = EAS_STATE_PAUSED;
+ else
+ *pState = EAS_STATE_PAUSING;
+ }
+
+ /* if stream is about to resume, report it as playing */
+ if (pStream->streamFlags & STREAM_FLAGS_RESUME)
+ *pState = EAS_STATE_PLAY;
+
+ return EAS_SUCCESS;
}
/*----------------------------------------------------------------------------
* EAS_SetPolyphony()
*----------------------------------------------------------------------------
- * Purpose:
+ * Purpose:
* Set the polyphony of the stream. A value of 0 allows the stream
* to use all voices (set by EAS_SetSynthPolyphony).
*
* Inputs:
- * pEASData - pointer to overall EAS data structure
- * streamHandle - handle returned by EAS_OpenFile
- * polyphonyCount - the desired polyphony count
- *
+ * pEASData - pointer to overall EAS data structure
+ * streamHandle - handle returned by EAS_OpenFile
+ * polyphonyCount - the desired polyphony count
+ *
* Outputs:
*
* Side Effects:
@@ -1691,22 +1691,22 @@ EAS_PUBLIC EAS_RESULT EAS_State (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, E
*/
EAS_PUBLIC EAS_RESULT EAS_SetPolyphony (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_I32 polyphonyCount)
{
- if (!EAS_StreamReady(pEASData, pStream))
- return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
- return EAS_IntSetStrmParam(pEASData, pStream, PARSER_DATA_POLYPHONY, polyphonyCount);
+ if (!EAS_StreamReady(pEASData, pStream))
+ return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
+ return EAS_IntSetStrmParam(pEASData, pStream, PARSER_DATA_POLYPHONY, polyphonyCount);
}
/*----------------------------------------------------------------------------
* EAS_GetPolyphony()
*----------------------------------------------------------------------------
- * Purpose:
+ * Purpose:
* Returns the current polyphony setting of the stream
*
* Inputs:
- * pEASData - pointer to overall EAS data structure
- * streamHandle - handle returned by EAS_OpenFile
- * pPolyphonyCount - pointer to variable to receive polyphony count
- *
+ * pEASData - pointer to overall EAS data structure
+ * streamHandle - handle returned by EAS_OpenFile
+ * pPolyphonyCount - pointer to variable to receive polyphony count
+ *
* Outputs:
*
* Side Effects:
@@ -1715,24 +1715,24 @@ EAS_PUBLIC EAS_RESULT EAS_SetPolyphony (EAS_DATA_HANDLE pEASData, EAS_HANDLE pSt
*/
EAS_PUBLIC EAS_RESULT EAS_GetPolyphony (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_I32 *pPolyphonyCount)
{
- if (!EAS_StreamReady(pEASData, pStream))
- return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
- return EAS_IntGetStrmParam(pEASData, pStream, PARSER_DATA_POLYPHONY, pPolyphonyCount);
+ if (!EAS_StreamReady(pEASData, pStream))
+ return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
+ return EAS_IntGetStrmParam(pEASData, pStream, PARSER_DATA_POLYPHONY, pPolyphonyCount);
}
/*----------------------------------------------------------------------------
* EAS_SetSynthPolyphony()
*----------------------------------------------------------------------------
- * Purpose:
+ * Purpose:
* Set the polyphony of the synth . Value must be >= 1 and <= the
* maximum number of voices. This function will pin the polyphony
* at those limits
*
* Inputs:
- * pEASData - pointer to overall EAS data structure
- * synthNum - synthesizer number (0 = onboard, 1 = DSP)
- * polyphonyCount - the desired polyphony count
- *
+ * pEASData - pointer to overall EAS data structure
+ * synthNum - synthesizer number (0 = onboard, 1 = DSP)
+ * polyphonyCount - the desired polyphony count
+ *
* Outputs:
*
* Side Effects:
@@ -1741,20 +1741,20 @@ EAS_PUBLIC EAS_RESULT EAS_GetPolyphony (EAS_DATA_HANDLE pEASData, EAS_HANDLE pSt
*/
EAS_PUBLIC EAS_RESULT EAS_SetSynthPolyphony (EAS_DATA_HANDLE pEASData, EAS_I32 synthNum, EAS_I32 polyphonyCount)
{
- return VMSetSynthPolyphony(pEASData->pVoiceMgr, synthNum, polyphonyCount);
+ return VMSetSynthPolyphony(pEASData->pVoiceMgr, synthNum, polyphonyCount);
}
/*----------------------------------------------------------------------------
* EAS_GetSynthPolyphony()
*----------------------------------------------------------------------------
- * Purpose:
+ * Purpose:
* Returns the current polyphony setting of the synth
*
* Inputs:
- * pEASData - pointer to overall EAS data structure
- * synthNum - synthesizer number (0 = onboard, 1 = DSP)
- * pPolyphonyCount - pointer to variable to receive polyphony count
- *
+ * pEASData - pointer to overall EAS data structure
+ * synthNum - synthesizer number (0 = onboard, 1 = DSP)
+ * pPolyphonyCount - pointer to variable to receive polyphony count
+ *
* Outputs:
*
* Side Effects:
@@ -1763,23 +1763,23 @@ EAS_PUBLIC EAS_RESULT EAS_SetSynthPolyphony (EAS_DATA_HANDLE pEASData, EAS_I32 s
*/
EAS_PUBLIC EAS_RESULT EAS_GetSynthPolyphony (EAS_DATA_HANDLE pEASData, EAS_I32 synthNum, EAS_I32 *pPolyphonyCount)
{
- return VMGetSynthPolyphony(pEASData->pVoiceMgr, synthNum, pPolyphonyCount);
+ return VMGetSynthPolyphony(pEASData->pVoiceMgr, synthNum, pPolyphonyCount);
}
/*----------------------------------------------------------------------------
* EAS_SetPriority()
*----------------------------------------------------------------------------
- * Purpose:
+ * Purpose:
* Set the priority of the stream. Determines which stream's voices
* are stolen when there are insufficient voices for all notes.
* Value must be in the range of 1-15, lower values are higher
* priority.
*
* Inputs:
- * pEASData - pointer to overall EAS data structure
- * streamHandle - handle returned by EAS_OpenFile
- * polyphonyCount - the desired polyphony count
- *
+ * pEASData - pointer to overall EAS data structure
+ * streamHandle - handle returned by EAS_OpenFile
+ * polyphonyCount - the desired polyphony count
+ *
* Outputs:
*
* Side Effects:
@@ -1788,22 +1788,22 @@ EAS_PUBLIC EAS_RESULT EAS_GetSynthPolyphony (EAS_DATA_HANDLE pEASData, EAS_I32 s
*/
EAS_PUBLIC EAS_RESULT EAS_SetPriority (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_I32 priority)
{
- if (!EAS_StreamReady(pEASData, pStream))
- return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
- return EAS_IntSetStrmParam(pEASData, pStream, PARSER_DATA_PRIORITY, priority);
+ if (!EAS_StreamReady(pEASData, pStream))
+ return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
+ return EAS_IntSetStrmParam(pEASData, pStream, PARSER_DATA_PRIORITY, priority);
}
/*----------------------------------------------------------------------------
* EAS_GetPriority()
*----------------------------------------------------------------------------
- * Purpose:
+ * Purpose:
* Returns the current priority setting of the stream
*
* Inputs:
- * pEASData - pointer to overall EAS data structure
- * streamHandle - handle returned by EAS_OpenFile
- * pPriority - pointer to variable to receive priority
- *
+ * pEASData - pointer to overall EAS data structure
+ * streamHandle - handle returned by EAS_OpenFile
+ * pPriority - pointer to variable to receive priority
+ *
* Outputs:
*
* Side Effects:
@@ -1812,22 +1812,22 @@ EAS_PUBLIC EAS_RESULT EAS_SetPriority (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStr
*/
EAS_PUBLIC EAS_RESULT EAS_GetPriority (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_I32 *pPriority)
{
- if (!EAS_StreamReady(pEASData, pStream))
- return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
- return EAS_IntGetStrmParam(pEASData, pStream, PARSER_DATA_PRIORITY, pPriority);
+ if (!EAS_StreamReady(pEASData, pStream))
+ return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
+ return EAS_IntGetStrmParam(pEASData, pStream, PARSER_DATA_PRIORITY, pPriority);
}
/*----------------------------------------------------------------------------
* EAS_SetVolume()
*----------------------------------------------------------------------------
- * Purpose:
+ * Purpose:
* Set the master gain for the mix engine in 1dB increments
*
* Inputs:
- * pEASData - pointer to overall EAS data structure
- * volume - the desired master gain (100 is max)
- * handle - file or stream handle
- *
+ * pEASData - pointer to overall EAS data structure
+ * volume - the desired master gain (100 is max)
+ * handle - file or stream handle
+ *
* Outputs:
*
*
@@ -1838,58 +1838,58 @@ EAS_PUBLIC EAS_RESULT EAS_GetPriority (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStr
*/
EAS_PUBLIC EAS_RESULT EAS_SetVolume (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_I32 volume)
{
- EAS_I16 gain;
-
- /* check range */
- if ((volume < 0) || (volume > EAS_MAX_VOLUME))
- return EAS_ERROR_PARAMETER_RANGE;
-
- /* stream volume */
- if (pStream != NULL)
- {
- EAS_I32 gainOffset;
- EAS_RESULT result;
-
- if (!EAS_StreamReady(pEASData, pStream))
- return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
-
- /* get gain offset */
- pStream->volume = (EAS_U8) volume;
- result = EAS_GetStreamParameter(pEASData, pStream, PARSER_DATA_GAIN_OFFSET, &gainOffset);
- if (result == EAS_SUCCESS)
- volume += gainOffset;
-
- /* set stream volume */
- gain = EAS_VolumeToGain(volume - STREAM_VOLUME_HEADROOM);
-
- /* convert to linear scalar */
- return EAS_IntSetStrmParam(pEASData, pStream, PARSER_DATA_VOLUME, gain);
- }
-
- /* master volume */
- pEASData->masterVolume = (EAS_U8) volume;
+ EAS_I16 gain;
+
+ /* check range */
+ if ((volume < 0) || (volume > EAS_MAX_VOLUME))
+ return EAS_ERROR_PARAMETER_RANGE;
+
+ /* stream volume */
+ if (pStream != NULL)
+ {
+ EAS_I32 gainOffset;
+ EAS_RESULT result;
+
+ if (!EAS_StreamReady(pEASData, pStream))
+ return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
+
+ /* get gain offset */
+ pStream->volume = (EAS_U8) volume;
+ result = EAS_GetStreamParameter(pEASData, pStream, PARSER_DATA_GAIN_OFFSET, &gainOffset);
+ if (result == EAS_SUCCESS)
+ volume += gainOffset;
+
+ /* set stream volume */
+ gain = EAS_VolumeToGain(volume - STREAM_VOLUME_HEADROOM);
+
+ /* convert to linear scalar */
+ return EAS_IntSetStrmParam(pEASData, pStream, PARSER_DATA_VOLUME, gain);
+ }
+
+ /* master volume */
+ pEASData->masterVolume = (EAS_U8) volume;
#if (NUM_OUTPUT_CHANNELS == 1)
- /* leave 3dB headroom for mono output */
- volume -= 3;
+ /* leave 3dB headroom for mono output */
+ volume -= 3;
#endif
- gain = EAS_VolumeToGain(volume - STREAM_VOLUME_HEADROOM);
- pEASData->masterGain = gain;
- return EAS_SUCCESS;
+ gain = EAS_VolumeToGain(volume - STREAM_VOLUME_HEADROOM);
+ pEASData->masterGain = gain;
+ return EAS_SUCCESS;
}
/*----------------------------------------------------------------------------
* EAS_GetVolume()
*----------------------------------------------------------------------------
- * Purpose:
+ * Purpose:
* Returns the master volume for the synthesizer. The default volume setting is
* 50. The volume range is 0 to 100;
*
* Inputs:
- * pEASData - pointer to overall EAS data structure
- * volume - the desired master volume
- * handle - file or stream handle
- *
+ * pEASData - pointer to overall EAS data structure
+ * volume - the desired master volume
+ * handle - file or stream handle
+ *
* Outputs:
*
*
@@ -1900,28 +1900,28 @@ EAS_PUBLIC EAS_RESULT EAS_SetVolume (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStrea
*/
EAS_PUBLIC EAS_I32 EAS_GetVolume (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream)
{
- if (pStream == NULL)
- return pEASData->masterVolume;
-
- if (!EAS_StreamReady(pEASData, pStream))
- return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
- return pStream->volume;
+ if (pStream == NULL)
+ return pEASData->masterVolume;
+
+ if (!EAS_StreamReady(pEASData, pStream))
+ return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
+ return pStream->volume;
}
/*----------------------------------------------------------------------------
* EAS_SetMaxLoad()
*----------------------------------------------------------------------------
- * Purpose:
+ * Purpose:
* Sets the maximum workload the parsers will do in a single call to
* EAS_Render. The units are currently arbitrary, but should correlate
* well to the actual CPU cycles consumed. The primary effect is to
* reduce the occasional peaks in CPU cycles consumed when parsing
- * dense parts of a MIDI score.
+ * dense parts of a MIDI score.
*
* Inputs:
- * pEASData - handle to data for this instance
- * maxLoad - the desired maximum workload
- *
+ * pEASData - handle to data for this instance
+ * maxLoad - the desired maximum workload
+ *
* Outputs:
*
* Side Effects:
@@ -1930,8 +1930,8 @@ EAS_PUBLIC EAS_I32 EAS_GetVolume (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream)
*/
EAS_PUBLIC EAS_RESULT EAS_SetMaxLoad (EAS_DATA_HANDLE pEASData, EAS_I32 maxLoad)
{
- VMSetWorkload(pEASData->pVoiceMgr, maxLoad);
- return EAS_SUCCESS;
+ VMSetWorkload(pEASData->pVoiceMgr, maxLoad);
+ return EAS_SUCCESS;
}
/*----------------------------------------------------------------------------
@@ -1941,31 +1941,31 @@ EAS_PUBLIC EAS_RESULT EAS_SetMaxLoad (EAS_DATA_HANDLE pEASData, EAS_I32 maxLoad)
* use PCM streaming.
*
* Inputs:
- * pEASData - pointer to overall EAS data structure
- * streamHandle - handle returned by EAS_OpenFile
- * maxNumStreams - maximum number of PCM streams
+ * pEASData - pointer to overall EAS data structure
+ * streamHandle - handle returned by EAS_OpenFile
+ * maxNumStreams - maximum number of PCM streams
*----------------------------------------------------------------------------
*/
EAS_PUBLIC EAS_RESULT EAS_SetMaxPCMStreams (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_I32 maxNumStreams)
{
- if (!EAS_StreamReady(pEASData, pStream))
- return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
- return EAS_IntSetStrmParam(pEASData, pStream, PARSER_DATA_MAX_PCM_STREAMS, maxNumStreams);
+ if (!EAS_StreamReady(pEASData, pStream))
+ return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
+ return EAS_IntSetStrmParam(pEASData, pStream, PARSER_DATA_MAX_PCM_STREAMS, maxNumStreams);
}
/*----------------------------------------------------------------------------
* EAS_Locate()
*----------------------------------------------------------------------------
- * Purpose:
+ * Purpose:
* Locate into the file associated with the handle.
*
* Inputs:
* pEASData - pointer to overall EAS data structure
- * handle - file handle
- * milliseconds - playback offset from start of file in milliseconds
- *
+ * handle - file handle
+ * milliseconds - playback offset from start of file in milliseconds
+ *
* Outputs:
- *
+ *
*
* Side Effects:
* the actual offset will be quantized to the closest update period, typically
@@ -1976,75 +1976,75 @@ EAS_PUBLIC EAS_RESULT EAS_SetMaxPCMStreams (EAS_DATA_HANDLE pEASData, EAS_HANDLE
*/
EAS_PUBLIC EAS_RESULT EAS_Locate (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_I32 milliseconds, EAS_BOOL offset)
{
- S_FILE_PARSER_INTERFACE *pParserModule;
- EAS_RESULT result;
- EAS_U32 requestedTime;
- EAS_STATE state;
-
- /* get pointer to parser function table */
- pParserModule = (S_FILE_PARSER_INTERFACE*) pStream->pParserModule;
- if (pParserModule == NULL)
- return EAS_ERROR_FEATURE_NOT_AVAILABLE;
-
- if ((result = (*pParserModule->pfState)(pEASData, pStream->handle, &state)) != EAS_SUCCESS)
- return result;
- if (state >= EAS_STATE_OPEN)
- return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
-
- /* handle offset and limit to start of file */
- /*lint -e{704} use shift for performance*/
- if (offset)
- milliseconds += (EAS_I32) pStream->time >> 8;
- if (milliseconds < 0)
- milliseconds = 0;
-
- /* check to see if the request is different from the current time */
- requestedTime = (EAS_U32) milliseconds;
- if (requestedTime == (pStream->time >> 8))
- return EAS_SUCCESS;
-
- /* set the locate flag */
- pStream->streamFlags |= STREAM_FLAGS_LOCATE;
-
- /* use the parser locate function, if available */
- if (pParserModule->pfLocate != NULL)
- {
- EAS_BOOL parserLocate = EAS_FALSE;
- result = pParserModule->pfLocate(pEASData, pStream->handle, (EAS_I32) requestedTime, &parserLocate);
- if (!parserLocate)
- {
- if (result == EAS_SUCCESS)
- pStream->time = requestedTime << 8;
- return result;
- }
- }
-
- /* if we were paused and not going to resume, set pause request flag */
- if (((state == EAS_STATE_PAUSING) || (state == EAS_STATE_PAUSED)) && ((pStream->streamFlags & STREAM_FLAGS_RESUME) == 0))
- pStream->streamFlags |= STREAM_FLAGS_PAUSE;
-
- /* reset the synth and parser */
- if ((result = (*pParserModule->pfReset)(pEASData, pStream->handle)) != EAS_SUCCESS)
- return result;
- pStream->time = 0;
-
- /* locating forward, clear parsed flag and parse data until we get to the requested location */
- if ((result = EAS_ParseEvents(pEASData, pStream, requestedTime << 8, eParserModeLocate)) != EAS_SUCCESS)
- return result;
-
- return EAS_SUCCESS;
+ S_FILE_PARSER_INTERFACE *pParserModule;
+ EAS_RESULT result;
+ EAS_U32 requestedTime;
+ EAS_STATE state;
+
+ /* get pointer to parser function table */
+ pParserModule = (S_FILE_PARSER_INTERFACE*) pStream->pParserModule;
+ if (pParserModule == NULL)
+ return EAS_ERROR_FEATURE_NOT_AVAILABLE;
+
+ if ((result = (*pParserModule->pfState)(pEASData, pStream->handle, &state)) != EAS_SUCCESS)
+ return result;
+ if (state >= EAS_STATE_OPEN)
+ return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
+
+ /* handle offset and limit to start of file */
+ /*lint -e{704} use shift for performance*/
+ if (offset)
+ milliseconds += (EAS_I32) pStream->time >> 8;
+ if (milliseconds < 0)
+ milliseconds = 0;
+
+ /* check to see if the request is different from the current time */
+ requestedTime = (EAS_U32) milliseconds;
+ if (requestedTime == (pStream->time >> 8))
+ return EAS_SUCCESS;
+
+ /* set the locate flag */
+ pStream->streamFlags |= STREAM_FLAGS_LOCATE;
+
+ /* use the parser locate function, if available */
+ if (pParserModule->pfLocate != NULL)
+ {
+ EAS_BOOL parserLocate = EAS_FALSE;
+ result = pParserModule->pfLocate(pEASData, pStream->handle, (EAS_I32) requestedTime, &parserLocate);
+ if (!parserLocate)
+ {
+ if (result == EAS_SUCCESS)
+ pStream->time = requestedTime << 8;
+ return result;
+ }
+ }
+
+ /* if we were paused and not going to resume, set pause request flag */
+ if (((state == EAS_STATE_PAUSING) || (state == EAS_STATE_PAUSED)) && ((pStream->streamFlags & STREAM_FLAGS_RESUME) == 0))
+ pStream->streamFlags |= STREAM_FLAGS_PAUSE;
+
+ /* reset the synth and parser */
+ if ((result = (*pParserModule->pfReset)(pEASData, pStream->handle)) != EAS_SUCCESS)
+ return result;
+ pStream->time = 0;
+
+ /* locating forward, clear parsed flag and parse data until we get to the requested location */
+ if ((result = EAS_ParseEvents(pEASData, pStream, requestedTime << 8, eParserModeLocate)) != EAS_SUCCESS)
+ return result;
+
+ return EAS_SUCCESS;
}
/*----------------------------------------------------------------------------
* EAS_GetLocation()
*----------------------------------------------------------------------------
- * Purpose:
- * Returns the current playback offset
+ * Purpose:
+ * Returns the current playback offset
*
* Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - file handle
- *
+ * pEASData - pointer to overall EAS data structure
+ * handle - file handle
+ *
* Outputs:
* The offset in milliseconds from the start of the current sequence, quantized
* to the nearest update period. Actual resolution is typically 5.9 ms.
@@ -2056,22 +2056,22 @@ EAS_PUBLIC EAS_RESULT EAS_Locate (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream,
/*lint -esym(715, pEASData) reserved for future use */
EAS_PUBLIC EAS_RESULT EAS_GetLocation (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_I32 *pTime)
{
- if (!EAS_StreamReady(pEASData, pStream))
- return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
+ if (!EAS_StreamReady(pEASData, pStream))
+ return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
- *pTime = pStream->time >> 8;
- return EAS_SUCCESS;
+ *pTime = pStream->time >> 8;
+ return EAS_SUCCESS;
}
/*----------------------------------------------------------------------------
* EAS_GetRenderTime()
*----------------------------------------------------------------------------
- * Purpose:
- * Returns the current playback offset
+ * Purpose:
+ * Returns the current playback offset
*
* Inputs:
- * pEASData - pointer to overall EAS data structure
- *
+ * pEASData - pointer to overall EAS data structure
+ *
* Outputs:
* Gets the render time clock in msecs.
*
@@ -2081,24 +2081,24 @@ EAS_PUBLIC EAS_RESULT EAS_GetLocation (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStr
*/
EAS_PUBLIC EAS_RESULT EAS_GetRenderTime (EAS_DATA_HANDLE pEASData, EAS_I32 *pTime)
{
- *pTime = pEASData->renderTime >> 8;
- return EAS_SUCCESS;
+ *pTime = pEASData->renderTime >> 8;
+ return EAS_SUCCESS;
}
/*----------------------------------------------------------------------------
* EAS_Pause()
*----------------------------------------------------------------------------
- * Purpose:
+ * Purpose:
* Pauses the playback of the data associated with this handle. The audio
* is gracefully ramped down to prevent clicks and pops. It may take several
* buffers of audio before the audio is muted.
*
* Inputs:
- * psEASData - pointer to overall EAS data structure
- * handle - file or stream handle
- *
+ * psEASData - pointer to overall EAS data structure
+ * handle - file or stream handle
+ *
* Outputs:
- *
+ *
*
* Side Effects:
*
@@ -2107,56 +2107,56 @@ EAS_PUBLIC EAS_RESULT EAS_GetRenderTime (EAS_DATA_HANDLE pEASData, EAS_I32 *pTim
*/
EAS_PUBLIC EAS_RESULT EAS_Pause (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream)
{
- S_FILE_PARSER_INTERFACE *pParserModule;
- EAS_STATE state;
- EAS_RESULT result;
-
- pParserModule = (S_FILE_PARSER_INTERFACE*) pStream->pParserModule;
- if (pParserModule == NULL)
- return EAS_ERROR_FEATURE_NOT_AVAILABLE;
-
- /* check for valid state */
- result = pParserModule->pfState(pEASData, pStream->handle, &state);
- if (result == EAS_SUCCESS)
- {
- if ((state != EAS_STATE_PLAY) && (state != EAS_STATE_READY) && ((pStream->streamFlags & STREAM_FLAGS_RESUME) == 0))
- return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
-
- /* make sure parser implements pause */
- if (pParserModule->pfPause == NULL)
- result = EAS_ERROR_NOT_IMPLEMENTED;
-
- /* clear resume flag */
- pStream->streamFlags &= ~STREAM_FLAGS_RESUME;
-
- /* set pause flag */
- pStream->streamFlags |= STREAM_FLAGS_PAUSE;
-
-#if 0
- /* pause the stream */
- if (pParserModule->pfPause)
- result = pParserModule->pfPause(pEASData, pStream->handle);
- else
- result = EAS_ERROR_NOT_IMPLEMENTED;
-#endif
- }
-
- return result;
+ S_FILE_PARSER_INTERFACE *pParserModule;
+ EAS_STATE state;
+ EAS_RESULT result;
+
+ pParserModule = (S_FILE_PARSER_INTERFACE*) pStream->pParserModule;
+ if (pParserModule == NULL)
+ return EAS_ERROR_FEATURE_NOT_AVAILABLE;
+
+ /* check for valid state */
+ result = pParserModule->pfState(pEASData, pStream->handle, &state);
+ if (result == EAS_SUCCESS)
+ {
+ if ((state != EAS_STATE_PLAY) && (state != EAS_STATE_READY) && ((pStream->streamFlags & STREAM_FLAGS_RESUME) == 0))
+ return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
+
+ /* make sure parser implements pause */
+ if (pParserModule->pfPause == NULL)
+ result = EAS_ERROR_NOT_IMPLEMENTED;
+
+ /* clear resume flag */
+ pStream->streamFlags &= ~STREAM_FLAGS_RESUME;
+
+ /* set pause flag */
+ pStream->streamFlags |= STREAM_FLAGS_PAUSE;
+
+#if 0
+ /* pause the stream */
+ if (pParserModule->pfPause)
+ result = pParserModule->pfPause(pEASData, pStream->handle);
+ else
+ result = EAS_ERROR_NOT_IMPLEMENTED;
+#endif
+ }
+
+ return result;
}
/*----------------------------------------------------------------------------
* EAS_Resume()
*----------------------------------------------------------------------------
- * Purpose:
+ * Purpose:
* Resumes the playback of the data associated with this handle. The audio
* is gracefully ramped up to prevent clicks and pops.
*
* Inputs:
- * psEASData - pointer to overall EAS data structure
- * handle - file or stream handle
- *
+ * psEASData - pointer to overall EAS data structure
+ * handle - file or stream handle
+ *
* Outputs:
- *
+ *
*
* Side Effects:
*
@@ -2165,59 +2165,59 @@ EAS_PUBLIC EAS_RESULT EAS_Pause (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream)
*/
EAS_PUBLIC EAS_RESULT EAS_Resume (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream)
{
- S_FILE_PARSER_INTERFACE *pParserModule;
- EAS_STATE state;
- EAS_RESULT result;
-
- pParserModule = (S_FILE_PARSER_INTERFACE*) pStream->pParserModule;
- if (pParserModule == NULL)
- return EAS_ERROR_FEATURE_NOT_AVAILABLE;
-
- /* check for valid state */
- result = pParserModule->pfState(pEASData, pStream->handle, &state);
- if (result == EAS_SUCCESS)
- {
- if ((state != EAS_STATE_PAUSED) && (state != EAS_STATE_PAUSING) && ((pStream->streamFlags & STREAM_FLAGS_PAUSE) == 0))
- return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
-
- /* make sure parser implements this function */
- if (pParserModule->pfResume == NULL)
- result = EAS_ERROR_NOT_IMPLEMENTED;
-
- /* clear pause flag */
- pStream->streamFlags &= ~STREAM_FLAGS_PAUSE;
-
- /* set resume flag */
- pStream->streamFlags |= STREAM_FLAGS_RESUME;
-
-#if 0
- /* resume the stream */
- if (pParserModule->pfResume)
- result = pParserModule->pfResume(pEASData, pStream->handle);
- else
- result = EAS_ERROR_NOT_IMPLEMENTED;
-#endif
- }
-
- return result;
+ S_FILE_PARSER_INTERFACE *pParserModule;
+ EAS_STATE state;
+ EAS_RESULT result;
+
+ pParserModule = (S_FILE_PARSER_INTERFACE*) pStream->pParserModule;
+ if (pParserModule == NULL)
+ return EAS_ERROR_FEATURE_NOT_AVAILABLE;
+
+ /* check for valid state */
+ result = pParserModule->pfState(pEASData, pStream->handle, &state);
+ if (result == EAS_SUCCESS)
+ {
+ if ((state != EAS_STATE_PAUSED) && (state != EAS_STATE_PAUSING) && ((pStream->streamFlags & STREAM_FLAGS_PAUSE) == 0))
+ return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
+
+ /* make sure parser implements this function */
+ if (pParserModule->pfResume == NULL)
+ result = EAS_ERROR_NOT_IMPLEMENTED;
+
+ /* clear pause flag */
+ pStream->streamFlags &= ~STREAM_FLAGS_PAUSE;
+
+ /* set resume flag */
+ pStream->streamFlags |= STREAM_FLAGS_RESUME;
+
+#if 0
+ /* resume the stream */
+ if (pParserModule->pfResume)
+ result = pParserModule->pfResume(pEASData, pStream->handle);
+ else
+ result = EAS_ERROR_NOT_IMPLEMENTED;
+#endif
+ }
+
+ return result;
}
/*----------------------------------------------------------------------------
* EAS_GetParameter()
*----------------------------------------------------------------------------
- * Purpose:
+ * Purpose:
* Set the parameter of a module. See E_MODULES for a list of modules
* and the header files of the modules for a list of parameters.
*
* Inputs:
- * psEASData - pointer to overall EAS data structure
- * handle - file or stream handle
- * module - enumerated module number
- * param - enumerated parameter number
- * pValue - pointer to variable to receive parameter value
- *
+ * psEASData - pointer to overall EAS data structure
+ * handle - file or stream handle
+ * module - enumerated module number
+ * param - enumerated parameter number
+ * pValue - pointer to variable to receive parameter value
+ *
* Outputs:
- *
+ *
*
* Side Effects:
*
@@ -2227,32 +2227,32 @@ EAS_PUBLIC EAS_RESULT EAS_Resume (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream)
EAS_PUBLIC EAS_RESULT EAS_GetParameter (EAS_DATA_HANDLE pEASData, EAS_I32 module, EAS_I32 param, EAS_I32 *pValue)
{
- if (module >= NUM_EFFECTS_MODULES)
- return EAS_ERROR_INVALID_MODULE;
-
- if (pEASData->effectsModules[module].effectData == NULL)
- return EAS_ERROR_INVALID_MODULE;
-
- return (*pEASData->effectsModules[module].effect->pFGetParam)
- (pEASData->effectsModules[module].effectData, param, pValue);
+ if (module >= NUM_EFFECTS_MODULES)
+ return EAS_ERROR_INVALID_MODULE;
+
+ if (pEASData->effectsModules[module].effectData == NULL)
+ return EAS_ERROR_INVALID_MODULE;
+
+ return (*pEASData->effectsModules[module].effect->pFGetParam)
+ (pEASData->effectsModules[module].effectData, param, pValue);
}
/*----------------------------------------------------------------------------
* EAS_SetParameter()
*----------------------------------------------------------------------------
- * Purpose:
+ * Purpose:
* Set the parameter of a module. See E_MODULES for a list of modules
* and the header files of the modules for a list of parameters.
*
* Inputs:
- * psEASData - pointer to overall EAS data structure
- * handle - file or stream handle
- * module - enumerated module number
- * param - enumerated parameter number
- * value - new parameter value
- *
+ * psEASData - pointer to overall EAS data structure
+ * handle - file or stream handle
+ * module - enumerated module number
+ * param - enumerated parameter number
+ * value - new parameter value
+ *
* Outputs:
- *
+ *
*
* Side Effects:
*
@@ -2262,28 +2262,28 @@ EAS_PUBLIC EAS_RESULT EAS_GetParameter (EAS_DATA_HANDLE pEASData, EAS_I32 module
EAS_PUBLIC EAS_RESULT EAS_SetParameter (EAS_DATA_HANDLE pEASData, EAS_I32 module, EAS_I32 param, EAS_I32 value)
{
- if (module >= NUM_EFFECTS_MODULES)
- return EAS_ERROR_INVALID_MODULE;
-
- if (pEASData->effectsModules[module].effectData == NULL)
- return EAS_ERROR_INVALID_MODULE;
+ if (module >= NUM_EFFECTS_MODULES)
+ return EAS_ERROR_INVALID_MODULE;
- return (*pEASData->effectsModules[module].effect->pFSetParam)
- (pEASData->effectsModules[module].effectData, param, value);
+ if (pEASData->effectsModules[module].effectData == NULL)
+ return EAS_ERROR_INVALID_MODULE;
+
+ return (*pEASData->effectsModules[module].effect->pFSetParam)
+ (pEASData->effectsModules[module].effectData, param, value);
}
-#ifdef _METRICS_ENABLED
+#ifdef _METRICS_ENABLED
/*----------------------------------------------------------------------------
* EAS_MetricsReport()
*----------------------------------------------------------------------------
- * Purpose:
+ * Purpose:
* Displays the current metrics through the metrics interface.
*
* Inputs:
- * p - instance data handle
- *
+ * p - instance data handle
+ *
* Outputs:
- *
+ *
*
* Side Effects:
*
@@ -2291,23 +2291,23 @@ EAS_PUBLIC EAS_RESULT EAS_SetParameter (EAS_DATA_HANDLE pEASData, EAS_I32 module
*/
EAS_PUBLIC EAS_RESULT EAS_MetricsReport (EAS_DATA_HANDLE pEASData)
{
- if (!pEASData->pMetricsModule)
- return EAS_ERROR_INVALID_MODULE;
+ if (!pEASData->pMetricsModule)
+ return EAS_ERROR_INVALID_MODULE;
- return (*pEASData->pMetricsModule->pfReport)(pEASData->pMetricsData);
+ return (*pEASData->pMetricsModule->pfReport)(pEASData->pMetricsData);
}
/*----------------------------------------------------------------------------
* EAS_MetricsReset()
*----------------------------------------------------------------------------
- * Purpose:
+ * Purpose:
* Resets the metrics.
*
* Inputs:
- * p - instance data handle
- *
+ * p - instance data handle
+ *
* Outputs:
- *
+ *
*
* Side Effects:
*
@@ -2316,25 +2316,25 @@ EAS_PUBLIC EAS_RESULT EAS_MetricsReport (EAS_DATA_HANDLE pEASData)
EAS_PUBLIC EAS_RESULT EAS_MetricsReset (EAS_DATA_HANDLE pEASData)
{
- if (!pEASData->pMetricsModule)
- return EAS_ERROR_INVALID_MODULE;
+ if (!pEASData->pMetricsModule)
+ return EAS_ERROR_INVALID_MODULE;
- return (*pEASData->pMetricsModule->pfReset)(pEASData->pMetricsData);
+ return (*pEASData->pMetricsModule->pfReset)(pEASData->pMetricsData);
}
#endif
/*----------------------------------------------------------------------------
* EAS_SetSoundLibrary()
*----------------------------------------------------------------------------
- * Purpose:
+ * Purpose:
* Sets the location of the sound library.
*
* Inputs:
- * pEASData - instance data handle
- * pSoundLib - pointer to sound library
- *
+ * pEASData - instance data handle
+ * pSoundLib - pointer to sound library
+ *
* Outputs:
- *
+ *
*
* Side Effects:
*
@@ -2342,14 +2342,14 @@ EAS_PUBLIC EAS_RESULT EAS_MetricsReset (EAS_DATA_HANDLE pEASData)
*/
EAS_PUBLIC EAS_RESULT EAS_SetSoundLibrary (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_SNDLIB_HANDLE pSndLib)
{
- if (pStream)
- {
- if (!EAS_StreamReady(pEASData, pStream))
- return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
- return EAS_IntSetStrmParam(pEASData, pStream, PARSER_DATA_EAS_LIBRARY, (EAS_I32) pSndLib);
- }
-
- return VMSetGlobalEASLib(pEASData->pVoiceMgr, pSndLib);
+ if (pStream)
+ {
+ if (!EAS_StreamReady(pEASData, pStream))
+ return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
+ return EAS_IntSetStrmParam(pEASData, pStream, PARSER_DATA_EAS_LIBRARY, (EAS_I32) pSndLib);
+ }
+
+ return VMSetGlobalEASLib(pEASData->pVoiceMgr, pSndLib);
}
/*----------------------------------------------------------------------------
@@ -2365,14 +2365,14 @@ EAS_PUBLIC EAS_RESULT EAS_SetSoundLibrary (EAS_DATA_HANDLE pEASData, EAS_HANDLE
* it make take slightly longer to process the EAS_OpenFile request.
*
* Inputs:
- * pEASData - instance data handle
- * searchFlag - search flag (EAS_TRUE or EAS_FALSE)
+ * pEASData - instance data handle
+ * searchFlag - search flag (EAS_TRUE or EAS_FALSE)
*----------------------------------------------------------------------------
*/
EAS_PUBLIC EAS_RESULT EAS_SetHeaderSearchFlag (EAS_DATA_HANDLE pEASData, EAS_BOOL searchFlag)
{
- pEASData->searchHeaderFlag = (EAS_BOOL8) searchFlag;
- return EAS_SUCCESS;
+ pEASData->searchHeaderFlag = (EAS_BOOL8) searchFlag;
+ return EAS_SUCCESS;
}
/*----------------------------------------------------------------------------
@@ -2383,29 +2383,29 @@ EAS_PUBLIC EAS_RESULT EAS_SetHeaderSearchFlag (EAS_DATA_HANDLE pEASData, EAS_BOO
* default play mode (usually straight playback) is always zero.
*
* Inputs:
- * pEASData - instance data handle
- * handle - file or stream handle
- * playMode - play mode (see file parser for specifics)
+ * pEASData - instance data handle
+ * handle - file or stream handle
+ * playMode - play mode (see file parser for specifics)
*----------------------------------------------------------------------------
*/
EAS_PUBLIC EAS_RESULT EAS_SetPlayMode (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_I32 playMode)
{
- return EAS_IntSetStrmParam(pEASData, pStream, PARSER_DATA_PLAY_MODE, playMode);
+ return EAS_IntSetStrmParam(pEASData, pStream, PARSER_DATA_PLAY_MODE, playMode);
}
#ifdef DLS_SYNTHESIZER
/*----------------------------------------------------------------------------
* EAS_LoadDLSCollection()
*----------------------------------------------------------------------------
- * Purpose:
+ * Purpose:
* Sets the location of the sound library.
*
* Inputs:
- * pEASData - instance data handle
- * pSoundLib - pointer to sound library
- *
+ * pEASData - instance data handle
+ * pSoundLib - pointer to sound library
+ *
* Outputs:
- *
+ *
*
* Side Effects:
*
@@ -2413,37 +2413,37 @@ EAS_PUBLIC EAS_RESULT EAS_SetPlayMode (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStr
*/
EAS_PUBLIC EAS_RESULT EAS_LoadDLSCollection (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_FILE_LOCATOR locator)
{
- EAS_FILE_HANDLE fileHandle;
- EAS_RESULT result;
- EAS_DLSLIB_HANDLE pDLS;
-
- if (pStream != NULL)
- {
- if (!EAS_StreamReady(pEASData, pStream))
- return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
- }
-
- /* open the file */
- if ((result = EAS_HWOpenFile(pEASData->hwInstData, locator, &fileHandle, EAS_FILE_READ)) != EAS_SUCCESS)
- return result;
-
- /* parse the file */
- result = DLSParser(pEASData->hwInstData, fileHandle, 0, &pDLS);
- EAS_HWCloseFile(pEASData->hwInstData, fileHandle);
-
- if (result == EAS_SUCCESS)
- {
-
- /* if a stream pStream is specified, point it to the DLS collection */
- if (pStream)
- result = EAS_IntSetStrmParam(pEASData, pStream, PARSER_DATA_DLS_COLLECTION, (EAS_I32) pDLS);
-
- /* global DLS load */
- else
- result = VMSetGlobalDLSLib(pEASData, pDLS);
- }
-
- return result;
+ EAS_FILE_HANDLE fileHandle;
+ EAS_RESULT result;
+ EAS_DLSLIB_HANDLE pDLS;
+
+ if (pStream != NULL)
+ {
+ if (!EAS_StreamReady(pEASData, pStream))
+ return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
+ }
+
+ /* open the file */
+ if ((result = EAS_HWOpenFile(pEASData->hwInstData, locator, &fileHandle, EAS_FILE_READ)) != EAS_SUCCESS)
+ return result;
+
+ /* parse the file */
+ result = DLSParser(pEASData->hwInstData, fileHandle, 0, &pDLS);
+ EAS_HWCloseFile(pEASData->hwInstData, fileHandle);
+
+ if (result == EAS_SUCCESS)
+ {
+
+ /* if a stream pStream is specified, point it to the DLS collection */
+ if (pStream)
+ result = EAS_IntSetStrmParam(pEASData, pStream, PARSER_DATA_DLS_COLLECTION, (EAS_I32) pDLS);
+
+ /* global DLS load */
+ else
+ result = VMSetGlobalDLSLib(pEASData, pDLS);
+ }
+
+ return result;
}
#endif
@@ -2451,56 +2451,56 @@ EAS_PUBLIC EAS_RESULT EAS_LoadDLSCollection (EAS_DATA_HANDLE pEASData, EAS_HANDL
/*----------------------------------------------------------------------------
* EAS_RegExtAudioCallback()
*----------------------------------------------------------------------------
- * Purpose:
+ * Purpose:
* Registers callback functions for audio events.
*
* Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - file or stream handle
- * cbProgChgFunc - pointer to host callback function for program change
- * cbEventFunc - pointer to host callback functio for note events
- *
+ * pEASData - pointer to overall EAS data structure
+ * handle - file or stream handle
+ * cbProgChgFunc - pointer to host callback function for program change
+ * cbEventFunc - pointer to host callback functio for note events
+ *
* Outputs:
- *
+ *
*
* Side Effects:
*
*----------------------------------------------------------------------------
*/
EAS_PUBLIC EAS_RESULT EAS_RegExtAudioCallback (EAS_DATA_HANDLE pEASData,
- EAS_HANDLE pStream,
- EAS_VOID_PTR pInstData,
- EAS_EXT_PRG_CHG_FUNC cbProgChgFunc,
- EAS_EXT_EVENT_FUNC cbEventFunc)
+ EAS_HANDLE pStream,
+ EAS_VOID_PTR pInstData,
+ EAS_EXT_PRG_CHG_FUNC cbProgChgFunc,
+ EAS_EXT_EVENT_FUNC cbEventFunc)
{
- S_SYNTH *pSynth;
-
- if (!EAS_StreamReady(pEASData, pStream))
- return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
-
- if (EAS_GetStreamParameter(pEASData, pStream, PARSER_DATA_SYNTH_HANDLE, (EAS_I32*) &pSynth) != EAS_SUCCESS)
- return EAS_ERROR_INVALID_PARAMETER;
-
- if (pSynth == NULL)
- return EAS_ERROR_INVALID_PARAMETER;
-
- VMRegExtAudioCallback(pSynth, pInstData, cbProgChgFunc, cbEventFunc);
- return EAS_SUCCESS;
+ S_SYNTH *pSynth;
+
+ if (!EAS_StreamReady(pEASData, pStream))
+ return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
+
+ if (EAS_GetStreamParameter(pEASData, pStream, PARSER_DATA_SYNTH_HANDLE, (EAS_I32*) &pSynth) != EAS_SUCCESS)
+ return EAS_ERROR_INVALID_PARAMETER;
+
+ if (pSynth == NULL)
+ return EAS_ERROR_INVALID_PARAMETER;
+
+ VMRegExtAudioCallback(pSynth, pInstData, cbProgChgFunc, cbEventFunc);
+ return EAS_SUCCESS;
}
/*----------------------------------------------------------------------------
* EAS_GetMIDIControllers()
*----------------------------------------------------------------------------
- * Purpose:
+ * Purpose:
* Returns the current state of MIDI controllers on the requested channel.
*
* Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - file or stream handle
- * pControl - pointer to structure to receive data
- *
+ * pEASData - pointer to overall EAS data structure
+ * handle - file or stream handle
+ * pControl - pointer to structure to receive data
+ *
* Outputs:
- *
+ *
*
* Side Effects:
*
@@ -2508,19 +2508,19 @@ EAS_PUBLIC EAS_RESULT EAS_RegExtAudioCallback (EAS_DATA_HANDLE pEASData,
*/
EAS_PUBLIC EAS_RESULT EAS_GetMIDIControllers (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_U8 channel, S_MIDI_CONTROLLERS *pControl)
{
- S_SYNTH *pSynth;
-
- if (!EAS_StreamReady(pEASData, pStream))
- return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
-
- if (EAS_GetStreamParameter(pEASData, pStream, PARSER_DATA_SYNTH_HANDLE, (EAS_I32*) &pSynth) != EAS_SUCCESS)
- return EAS_ERROR_INVALID_PARAMETER;
-
- if (pSynth == NULL)
- return EAS_ERROR_INVALID_PARAMETER;
-
- VMGetMIDIControllers(pSynth, channel, pControl);
- return EAS_SUCCESS;
+ S_SYNTH *pSynth;
+
+ if (!EAS_StreamReady(pEASData, pStream))
+ return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
+
+ if (EAS_GetStreamParameter(pEASData, pStream, PARSER_DATA_SYNTH_HANDLE, (EAS_I32*) &pSynth) != EAS_SUCCESS)
+ return EAS_ERROR_INVALID_PARAMETER;
+
+ if (pSynth == NULL)
+ return EAS_ERROR_INVALID_PARAMETER;
+
+ VMGetMIDIControllers(pSynth, channel, pControl);
+ return EAS_SUCCESS;
}
#endif
@@ -2528,15 +2528,15 @@ EAS_PUBLIC EAS_RESULT EAS_GetMIDIControllers (EAS_DATA_HANDLE pEASData, EAS_HAND
/*----------------------------------------------------------------------------
* EAS_SetFrameBuffer()
*----------------------------------------------------------------------------
- * Purpose:
+ * Purpose:
* Sets the frame buffer pointer passed to the IPC communications functions
*
* Inputs:
- * pEASData - instance data handle
- * locator - file locator
- *
+ * pEASData - instance data handle
+ * locator - file locator
+ *
* Outputs:
- *
+ *
*
* Side Effects:
* May overlay instruments in the GM sound set
@@ -2545,9 +2545,9 @@ EAS_PUBLIC EAS_RESULT EAS_GetMIDIControllers (EAS_DATA_HANDLE pEASData, EAS_HAND
*/
EAS_PUBLIC EAS_RESULT EAS_SetFrameBuffer (EAS_DATA_HANDLE pEASData, EAS_FRAME_BUFFER_HANDLE pFrameBuffer)
{
- if (pEASData->pVoiceMgr)
- pEASData->pVoiceMgr->pFrameBuffer = pFrameBuffer;
- return EAS_SUCCESS;
+ if (pEASData->pVoiceMgr)
+ pEASData->pVoiceMgr->pFrameBuffer = pFrameBuffer;
+ return EAS_SUCCESS;
}
#endif
@@ -2558,44 +2558,44 @@ EAS_PUBLIC EAS_RESULT EAS_SetFrameBuffer (EAS_DATA_HANDLE pEASData, EAS_FRAME_BU
* position. Returns offset to start of sequence.
*
* Inputs:
- * pEASData - pointer to EAS persistent data object
- * fileHandle - file handle
- * searchString - pointer to search sequence
- * len - length of search sequence
- * pOffset - pointer to variable to store offset to sequence
+ * pEASData - pointer to EAS persistent data object
+ * fileHandle - file handle
+ * searchString - pointer to search sequence
+ * len - length of search sequence
+ * pOffset - pointer to variable to store offset to sequence
*
* Returns EAS_EOF if end-of-file is reached
*----------------------------------------------------------------------------
*/
EAS_RESULT EAS_SearchFile (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle, const EAS_U8 *searchString, EAS_I32 len, EAS_I32 *pOffset)
{
- EAS_RESULT result;
- EAS_INT index;
- EAS_U8 c;
-
- *pOffset = -1;
- index = 0;
- for (;;)
- {
- result = EAS_HWGetByte(pEASData->hwInstData, fileHandle, &c);
- if (result != EAS_SUCCESS)
- return result;
- if (c == searchString[index])
- {
- index++;
- if (index == 4)
- {
- result = EAS_HWFilePos(pEASData->hwInstData, fileHandle, pOffset);
- if (result != EAS_SUCCESS)
- return result;
- *pOffset -= len;
- break;
- }
- }
- else
- index = 0;
- }
- return EAS_SUCCESS;
+ EAS_RESULT result;
+ EAS_INT index;
+ EAS_U8 c;
+
+ *pOffset = -1;
+ index = 0;
+ for (;;)
+ {
+ result = EAS_HWGetByte(pEASData->hwInstData, fileHandle, &c);
+ if (result != EAS_SUCCESS)
+ return result;
+ if (c == searchString[index])
+ {
+ index++;
+ if (index == 4)
+ {
+ result = EAS_HWFilePos(pEASData->hwInstData, fileHandle, pOffset);
+ if (result != EAS_SUCCESS)
+ return result;
+ *pOffset -= len;
+ break;
+ }
+ }
+ else
+ index = 0;
+ }
+ return EAS_SUCCESS;
}
diff --git a/arm-wt-22k/lib_src/eas_reverb.c b/arm-wt-22k/lib_src/eas_reverb.c
index 6d99862..cd5befe 100644
--- a/arm-wt-22k/lib_src/eas_reverb.c
+++ b/arm-wt-22k/lib_src/eas_reverb.c
@@ -1,13 +1,13 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_reverb.c
- *
- * Contents and purpose:
- * Contains the implementation of the Reverb effect.
- *
- *
- * Copyright Sonic Network Inc. 2006
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_reverb.c
+ *
+ * Contents and purpose:
+ * Contains the implementation of the Reverb effect.
+ *
+ *
+ * Copyright Sonic Network Inc. 2006
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,1135 +20,1135 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 510 $
- * $Date: 2006-12-19 01:47:33 -0800 (Tue, 19 Dec 2006) $
- *----------------------------------------------------------------------------
-*/
-
-/*------------------------------------
- * includes
- *------------------------------------
-*/
-
-#include "eas_data.h"
-#include "eas_effects.h"
-#include "eas_math.h"
-#include "eas_reverbdata.h"
-#include "eas_reverb.h"
-#include "eas_config.h"
-#include "eas_host.h"
-#include "eas_report.h"
-
-/* prototypes for effects interface */
-static EAS_RESULT ReverbInit (EAS_DATA_HANDLE pEASData, EAS_VOID_PTR *pInstData);
-static void ReverbProcess (EAS_VOID_PTR pInstData, EAS_PCM *pSrc, EAS_PCM *pDst, EAS_I32 numSamples);
-static EAS_RESULT ReverbShutdown (EAS_DATA_HANDLE pEASData, EAS_VOID_PTR pInstData);
-static EAS_RESULT ReverbGetParam (EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue);
-static EAS_RESULT ReverbSetParam (EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value);
-
-/* common effects interface for configuration module */
-const S_EFFECTS_INTERFACE EAS_Reverb =
-{
- ReverbInit,
- ReverbProcess,
- ReverbShutdown,
- ReverbGetParam,
- ReverbSetParam
-};
-
-
-
-/*----------------------------------------------------------------------------
- * InitializeReverb()
- *----------------------------------------------------------------------------
- * Purpose:
- *
- * Inputs:
- *
- * Outputs:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT ReverbInit(EAS_DATA_HANDLE pEASData, EAS_VOID_PTR *pInstData)
-{
- EAS_I32 i;
- EAS_U16 nOffset;
- EAS_INT temp;
-
- S_REVERB_OBJECT *pReverbData;
- S_REVERB_PRESET *pPreset;
-
- /* check Configuration Module for data allocation */
- if (pEASData->staticMemoryModel)
- pReverbData = EAS_CMEnumFXData(EAS_MODULE_REVERB);
-
- /* allocate dynamic memory */
- else
- pReverbData = EAS_HWMalloc(pEASData->hwInstData, sizeof(S_REVERB_OBJECT));
-
- if (pReverbData == NULL)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_FATAL, "Failed to allocate Reverb memory\n"); */ }
- return EAS_ERROR_MALLOC_FAILED;
- }
-
- /* clear the structure */
- EAS_HWMemSet(pReverbData, 0, sizeof(S_REVERB_OBJECT));
-
- ReverbReadInPresets(pReverbData);
-
- pReverbData->m_nMinSamplesToAdd = REVERB_UPDATE_PERIOD_IN_SAMPLES;
-
- pReverbData->m_nRevOutFbkR = 0;
- pReverbData->m_nRevOutFbkL = 0;
-
- pReverbData->m_sAp0.m_zApIn = AP0_IN;
- pReverbData->m_sAp0.m_zApOut = AP0_IN + DEFAULT_AP0_LENGTH;
- pReverbData->m_sAp0.m_nApGain = DEFAULT_AP0_GAIN;
-
- pReverbData->m_zD0In = DELAY0_IN;
-
- pReverbData->m_sAp1.m_zApIn = AP1_IN;
- pReverbData->m_sAp1.m_zApOut = AP1_IN + DEFAULT_AP1_LENGTH;
- pReverbData->m_sAp1.m_nApGain = DEFAULT_AP1_GAIN;
-
- pReverbData->m_zD1In = DELAY1_IN;
-
- pReverbData->m_zLpf0 = 0;
- pReverbData->m_zLpf1 = 0;
- pReverbData->m_nLpfFwd = 8837;
- pReverbData->m_nLpfFbk = 6494;
-
- pReverbData->m_nSin = 0;
- pReverbData->m_nCos = 0;
- pReverbData->m_nSinIncrement = 0;
- pReverbData->m_nCosIncrement = 0;
-
- // set xfade parameters
- pReverbData->m_nXfadeInterval = (EAS_U16)REVERB_XFADE_PERIOD_IN_SAMPLES;
- pReverbData->m_nXfadeCounter = pReverbData->m_nXfadeInterval + 1; // force update on first iteration
- pReverbData->m_nPhase = -32768;
- pReverbData->m_nPhaseIncrement = REVERB_XFADE_PHASE_INCREMENT;
-
- pReverbData->m_nNoise = (EAS_I16)0xABCD;
-
- pReverbData->m_nMaxExcursion = 0x007F;
-
- // set delay tap lengths
- nOffset = ReverbCalculateNoise( pReverbData->m_nMaxExcursion,
- &pReverbData->m_nNoise );
-
- pReverbData->m_zD1Cross =
- DELAY1_OUT - pReverbData->m_nMaxExcursion + nOffset;
-
- nOffset = ReverbCalculateNoise( pReverbData->m_nMaxExcursion,
- &pReverbData->m_nNoise );
-
- pReverbData->m_zD0Cross =
- DELAY1_OUT - pReverbData->m_nMaxExcursion - nOffset;
-
- nOffset = ReverbCalculateNoise( pReverbData->m_nMaxExcursion,
- &pReverbData->m_nNoise );
-
- pReverbData->m_zD0Self =
- DELAY0_OUT - pReverbData->m_nMaxExcursion - nOffset;
-
- nOffset = ReverbCalculateNoise( pReverbData->m_nMaxExcursion,
- &pReverbData->m_nNoise );
-
- pReverbData->m_zD1Self =
- DELAY1_OUT - pReverbData->m_nMaxExcursion + nOffset;
-
- // for debugging purposes, allow noise generator
- pReverbData->m_bUseNoise = EAS_FALSE;
-
- // for debugging purposes, allow bypass
- pReverbData->m_bBypass = EAS_TRUE; //EAS_FALSE;
-
- pReverbData->m_nNextRoom = 1;
-
- pReverbData->m_nCurrentRoom = pReverbData->m_nNextRoom + 1; // force update on first iteration
-
- pReverbData->m_nWet = REVERB_DEFAULT_WET;
-
- pReverbData->m_nDry = REVERB_DEFAULT_DRY;
-
- // set base index into circular buffer
- pReverbData->m_nBaseIndex = 0;
-
- // set the early reflections, L
- pReverbData->m_sEarlyL.m_nLpfFbk = 4915;
- pReverbData->m_sEarlyL.m_nLpfFwd = 27852;
- pReverbData->m_sEarlyL.m_zLpf = 0;
-
- for (i=0; i < REVERB_MAX_NUM_REFLECTIONS; i++)
- {
- pReverbData->m_sEarlyL.m_nGain[i] = 0;
- pReverbData->m_sEarlyL.m_zDelay[i] = 0;
- }
-
- // set the early reflections, R
- pReverbData->m_sEarlyR.m_nLpfFbk = 4915;
- pReverbData->m_sEarlyR.m_nLpfFwd = 27852;
- pReverbData->m_sEarlyR.m_zLpf = 0;
-
- for (i=0; i < REVERB_MAX_NUM_REFLECTIONS; i++)
- {
- pReverbData->m_sEarlyR.m_nGain[i] = 0;
- pReverbData->m_sEarlyR.m_zDelay[i] = 0;
- }
-
- // clear the reverb delay line
- for (i=0; i < REVERB_BUFFER_SIZE_IN_SAMPLES; i++)
- {
- pReverbData->m_nDelayLine[i] = 0;
- }
-
- ////////////////////////////////
- ///code from the EAS DEMO Reverb
- //now copy from the new preset into the reverb
- pPreset = &pReverbData->m_sPreset.m_sPreset[pReverbData->m_nNextRoom];
-
- pReverbData->m_nLpfFbk = pPreset->m_nLpfFbk;
- pReverbData->m_nLpfFwd = pPreset->m_nLpfFwd;
-
- pReverbData->m_nEarly = pPreset->m_nEarly;
- pReverbData->m_nWet = pPreset->m_nWet;
- pReverbData->m_nDry = pPreset->m_nDry;
-
- pReverbData->m_nMaxExcursion = pPreset->m_nMaxExcursion;
- //stored as time based, convert to sample based
- temp = pPreset->m_nXfadeInterval;
- /*lint -e{702} shift for performance */
- temp = (temp * _OUTPUT_SAMPLE_RATE) >> 16;
- pReverbData->m_nXfadeInterval = (EAS_U16) temp;
- //gsReverbObject.m_nXfadeInterval = pPreset->m_nXfadeInterval;
-
- pReverbData->m_sAp0.m_nApGain = pPreset->m_nAp0_ApGain;
- //stored as time based, convert to absolute sample value
- temp = pPreset->m_nAp0_ApOut;
- /*lint -e{702} shift for performance */
- temp = (temp * _OUTPUT_SAMPLE_RATE) >> 16;
- pReverbData->m_sAp0.m_zApOut = (EAS_U16) (pReverbData->m_sAp0.m_zApIn + temp);
- //gsReverbObject.m_sAp0.m_zApOut = pPreset->m_nAp0_ApOut;
-
- pReverbData->m_sAp1.m_nApGain = pPreset->m_nAp1_ApGain;
- //stored as time based, convert to absolute sample value
- temp = pPreset->m_nAp1_ApOut;
- /*lint -e{702} shift for performance */
- temp = (temp * _OUTPUT_SAMPLE_RATE) >> 16;
- pReverbData->m_sAp1.m_zApOut = (EAS_U16) (pReverbData->m_sAp1.m_zApIn + temp);
- //gsReverbObject.m_sAp1.m_zApOut = pPreset->m_nAp1_ApOut;
- ///code from the EAS DEMO Reverb
- ////////////////////////////////
-
- *pInstData = pReverbData;
-
- return EAS_SUCCESS;
-
-} /* end InitializeReverb */
-
-
-
-/*----------------------------------------------------------------------------
- * ReverbProcess()
- *----------------------------------------------------------------------------
- * Purpose:
- * Reverberate the requested number of samples (block based processing)
- *
- * Inputs:
- * pInputBuffer - src buffer
- * pOutputBuffer - dst buffer
- * nNumSamplesToAdd - number of samples to write to buffer
- *
- * Outputs:
- * number of samples actually written to buffer
- *
- * Side Effects:
- * - samples are added to the presently free buffer
- *
- *----------------------------------------------------------------------------
-*/
-static void ReverbProcess(EAS_VOID_PTR pInstData, EAS_PCM *pSrc, EAS_PCM *pDst, EAS_I32 numSamples)
-{
- S_REVERB_OBJECT *pReverbData;
-
- pReverbData = (S_REVERB_OBJECT*) pInstData;
-
- //if bypassed or the preset forces the signal to be completely dry
- if (pReverbData->m_bBypass ||
- (pReverbData->m_nWet == 0 && pReverbData->m_nDry == 32767))
- {
- if (pSrc != pDst)
- EAS_HWMemCpy(pSrc, pDst, numSamples * NUM_OUTPUT_CHANNELS * (EAS_I32) sizeof(EAS_PCM));
- return;
- }
-
- if (pReverbData->m_nNextRoom != pReverbData->m_nCurrentRoom)
- {
- ReverbUpdateRoom(pReverbData);
- }
-
- ReverbUpdateXfade(pReverbData, numSamples);
-
- Reverb(pReverbData, numSamples, pDst, pSrc);
-
- /* check if update counter needs to be reset */
- if (pReverbData->m_nUpdateCounter >= REVERB_MODULO_UPDATE_PERIOD_IN_SAMPLES)
- {
- /* update interval has elapsed, so reset counter */
- pReverbData->m_nUpdateCounter = 0;
- } /* end if m_nUpdateCounter >= update interval */
-
- /* increment update counter */
- pReverbData->m_nUpdateCounter += (EAS_I16)numSamples;
-
-} /* end ComputeReverb */
-
-/*----------------------------------------------------------------------------
- * ReverbUpdateXfade
- *----------------------------------------------------------------------------
- * Purpose:
- * Update the xfade parameters as required
- *
- * Inputs:
- * nNumSamplesToAdd - number of samples to write to buffer
- *
- * Outputs:
- *
- *
- * Side Effects:
- * - xfade parameters will be changed
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT ReverbUpdateXfade(S_REVERB_OBJECT *pReverbData, EAS_INT nNumSamplesToAdd)
-{
- EAS_U16 nOffset;
- EAS_I16 tempCos;
- EAS_I16 tempSin;
-
- if (pReverbData->m_nXfadeCounter >= pReverbData->m_nXfadeInterval)
- {
- /* update interval has elapsed, so reset counter */
- pReverbData->m_nXfadeCounter = 0;
-
- // Pin the sin,cos values to min / max values to ensure that the
- // modulated taps' coefs are zero (thus no clicks)
- if (pReverbData->m_nPhaseIncrement > 0)
- {
- // if phase increment > 0, then sin -> 1, cos -> 0
- pReverbData->m_nSin = 32767;
- pReverbData->m_nCos = 0;
-
- // reset the phase to match the sin, cos values
- pReverbData->m_nPhase = 32767;
-
- // modulate the cross taps because their tap coefs are zero
- nOffset = ReverbCalculateNoise( pReverbData->m_nMaxExcursion, &pReverbData->m_nNoise );
-
- pReverbData->m_zD1Cross =
- DELAY1_OUT - pReverbData->m_nMaxExcursion + nOffset;
-
- nOffset = ReverbCalculateNoise( pReverbData->m_nMaxExcursion, &pReverbData->m_nNoise );
-
- pReverbData->m_zD0Cross =
- DELAY0_OUT - pReverbData->m_nMaxExcursion - nOffset;
- }
- else
- {
- // if phase increment < 0, then sin -> 0, cos -> 1
- pReverbData->m_nSin = 0;
- pReverbData->m_nCos = 32767;
-
- // reset the phase to match the sin, cos values
- pReverbData->m_nPhase = -32768;
-
- // modulate the self taps because their tap coefs are zero
- nOffset = ReverbCalculateNoise( pReverbData->m_nMaxExcursion, &pReverbData->m_nNoise );
-
- pReverbData->m_zD0Self =
- DELAY0_OUT - pReverbData->m_nMaxExcursion - nOffset;
-
- nOffset = ReverbCalculateNoise( pReverbData->m_nMaxExcursion, &pReverbData->m_nNoise );
-
- pReverbData->m_zD1Self =
- DELAY1_OUT - pReverbData->m_nMaxExcursion + nOffset;
-
- } // end if-else (pReverbData->m_nPhaseIncrement > 0)
-
- // Reverse the direction of the sin,cos so that the
- // tap whose coef was previously increasing now decreases
- // and vice versa
- pReverbData->m_nPhaseIncrement = -pReverbData->m_nPhaseIncrement;
-
- } // end if counter >= update interval
-
- //compute what phase will be next time
- pReverbData->m_nPhase += pReverbData->m_nPhaseIncrement;
-
- //calculate what the new sin and cos need to reach by the next update
- ReverbCalculateSinCos(pReverbData->m_nPhase, &tempSin, &tempCos);
-
- //calculate the per-sample increment required to get there by the next update
- /*lint -e{702} shift for performance */
- pReverbData->m_nSinIncrement =
- (tempSin - pReverbData->m_nSin) >> REVERB_UPDATE_PERIOD_IN_BITS;
-
- /*lint -e{702} shift for performance */
- pReverbData->m_nCosIncrement =
- (tempCos - pReverbData->m_nCos) >> REVERB_UPDATE_PERIOD_IN_BITS;
-
-
- /* increment update counter */
- pReverbData->m_nXfadeCounter += (EAS_U16) nNumSamplesToAdd;
-
- return EAS_SUCCESS;
-
-} /* end ReverbUpdateXfade */
-
-
-/*----------------------------------------------------------------------------
- * ReverbCalculateNoise
- *----------------------------------------------------------------------------
- * Purpose:
- * Calculate a noise sample and limit its value
- *
- * Inputs:
- * nMaxExcursion - noise value is limited to this value
- * pnNoise - return new noise sample in this (not limited)
- *
- * Outputs:
- * new limited noise value
- *
- * Side Effects:
- * - *pnNoise noise value is updated
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_U16 ReverbCalculateNoise(EAS_U16 nMaxExcursion, EAS_I16 *pnNoise)
-{
- // calculate new noise value
- *pnNoise = (EAS_I16) (*pnNoise * 5 + 1);
-
-#if 0 // 1xxx, test
- *pnNoise = 0;
-#endif // 1xxx, test
-
- // return the limited noise value
- return (nMaxExcursion & (*pnNoise));
-
-} /* end ReverbCalculateNoise */
-
-/*----------------------------------------------------------------------------
- * ReverbCalculateSinCos
- *----------------------------------------------------------------------------
- * Purpose:
- * Calculate a new sin and cosine value based on the given phase
- *
- * Inputs:
- * nPhase - phase angle
- * pnSin - input old value, output new value
- * pnCos - input old value, output new value
- *
- * Outputs:
- *
- * Side Effects:
- * - *pnSin, *pnCos are updated
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT ReverbCalculateSinCos(EAS_I16 nPhase, EAS_I16 *pnSin, EAS_I16 *pnCos)
-{
- EAS_I32 nTemp;
- EAS_I32 nNetAngle;
-
- // -1 <= nPhase < 1
- // However, for the calculation, we need a value
- // that ranges from -1/2 to +1/2, so divide the phase by 2
- /*lint -e{702} shift for performance */
- nNetAngle = nPhase >> 1;
-
- /*
- Implement the following
- sin(x) = (2-4*c)*x^2 + c + x
- cos(x) = (2-4*c)*x^2 + c - x
-
- where c = 1/sqrt(2)
- using the a0 + x*(a1 + x*a2) approach
- */
-
- /* limit the input "angle" to be between -0.5 and +0.5 */
- if (nNetAngle > EG1_HALF)
- {
- nNetAngle = EG1_HALF;
- }
- else if (nNetAngle < EG1_MINUS_HALF)
- {
- nNetAngle = EG1_MINUS_HALF;
- }
-
- /* calculate sin */
- nTemp = EG1_ONE + MULT_EG1_EG1(REVERB_PAN_G2, nNetAngle);
- nTemp = REVERB_PAN_G0 + MULT_EG1_EG1(nTemp, nNetAngle);
- *pnSin = (EAS_I16) SATURATE_EG1(nTemp);
-
- /* calculate cos */
- nTemp = -EG1_ONE + MULT_EG1_EG1(REVERB_PAN_G2, nNetAngle);
- nTemp = REVERB_PAN_G0 + MULT_EG1_EG1(nTemp, nNetAngle);
- *pnCos = (EAS_I16) SATURATE_EG1(nTemp);
-
- return EAS_SUCCESS;
-} /* end ReverbCalculateSinCos */
-
-/*----------------------------------------------------------------------------
- * Reverb
- *----------------------------------------------------------------------------
- * Purpose:
- * apply reverb to the given signal
- *
- * Inputs:
- * nNu
- * pnSin - input old value, output new value
- * pnCos - input old value, output new value
- *
- * Outputs:
- * number of samples actually reverberated
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT Reverb(S_REVERB_OBJECT *pReverbData, EAS_INT nNumSamplesToAdd, EAS_PCM *pOutputBuffer, EAS_PCM *pInputBuffer)
-{
- EAS_I32 i;
- EAS_I32 nDelayOut;
- EAS_U16 nBase;
-
- EAS_U32 nAddr;
- EAS_I32 nTemp1;
- EAS_I32 nTemp2;
- EAS_I32 nApIn;
- EAS_I32 nApOut;
-
- EAS_I32 j;
- EAS_I32 nEarlyOut;
-
- EAS_I32 tempValue;
-
-
- // get the base address
- nBase = pReverbData->m_nBaseIndex;
-
- for (i=0; i < nNumSamplesToAdd; i++)
- {
- // ********** Left Allpass - start
- // left input = (left dry/4) + right feedback from previous period
- /*lint -e{702} use shift for performance */
- nApIn = ((*pInputBuffer++)>>2) + pReverbData->m_nRevOutFbkR;
-// nApIn = *pInputBuffer++; // 1xxx test and debug ap
-
- // fetch allpass delay line out
- //nAddr = CIRCULAR(nBase, psAp0->m_zApOut, REVERB_BUFFER_MASK);
- nAddr = CIRCULAR(nBase, pReverbData->m_sAp0.m_zApOut, REVERB_BUFFER_MASK);
- nDelayOut = pReverbData->m_nDelayLine[nAddr];
-
- // calculate allpass feedforward; subtract the feedforward result
- nTemp1 = MULT_EG1_EG1(nApIn, pReverbData->m_sAp0.m_nApGain);
- nApOut = SATURATE(nDelayOut - nTemp1); // allpass output
-
- // calculate allpass feedback; add the feedback result
- nTemp1 = MULT_EG1_EG1(nApOut, pReverbData->m_sAp0.m_nApGain);
- nTemp1 = SATURATE(nApIn + nTemp1);
-
- // inject into allpass delay
- nAddr = CIRCULAR(nBase, pReverbData->m_sAp0.m_zApIn, REVERB_BUFFER_MASK);
- pReverbData->m_nDelayLine[nAddr] = (EAS_PCM) nTemp1;
-
- // inject allpass output into delay line
- nAddr = CIRCULAR(nBase, pReverbData->m_zD0In, REVERB_BUFFER_MASK);
- pReverbData->m_nDelayLine[nAddr] = (EAS_PCM) nApOut;
-
- // ********** Left Allpass - end
-
- // ********** Right Allpass - start
- // right input = (right dry/4) + left feedback from previous period
- /*lint -e{702} use shift for performance */
- nApIn = ((*pInputBuffer++)>>2) + pReverbData->m_nRevOutFbkL;
-// nApIn = *pInputBuffer++; // 1xxx test and debug ap
-
- // fetch allpass delay line out
- nAddr = CIRCULAR(nBase, pReverbData->m_sAp1.m_zApOut, REVERB_BUFFER_MASK);
- nDelayOut = pReverbData->m_nDelayLine[nAddr];
-
- // calculate allpass feedforward; subtract the feedforward result
- nTemp1 = MULT_EG1_EG1(nApIn, pReverbData->m_sAp1.m_nApGain);
- nApOut = SATURATE(nDelayOut - nTemp1); // allpass output
-
- // calculate allpass feedback; add the feedback result
- nTemp1 = MULT_EG1_EG1(nApOut, pReverbData->m_sAp1.m_nApGain);
- nTemp1 = SATURATE(nApIn + nTemp1);
-
- // inject into allpass delay
- nAddr = CIRCULAR(nBase, pReverbData->m_sAp1.m_zApIn, REVERB_BUFFER_MASK);
- pReverbData->m_nDelayLine[nAddr] = (EAS_PCM) nTemp1;
-
- // inject allpass output into delay line
- nAddr = CIRCULAR(nBase, pReverbData->m_zD1In, REVERB_BUFFER_MASK);
- pReverbData->m_nDelayLine[nAddr] = (EAS_PCM) nApOut;
-
- // ********** Right Allpass - end
-
- // ********** D0 output - start
- // fetch delay line self out
- nAddr = CIRCULAR(nBase, pReverbData->m_zD0Self, REVERB_BUFFER_MASK);
- nDelayOut = pReverbData->m_nDelayLine[nAddr];
-
- // calculate delay line self out
- nTemp1 = MULT_EG1_EG1(nDelayOut, pReverbData->m_nSin);
-
- // fetch delay line cross out
- nAddr = CIRCULAR(nBase, pReverbData->m_zD1Cross, REVERB_BUFFER_MASK);
- nDelayOut = pReverbData->m_nDelayLine[nAddr];
-
- // calculate delay line self out
- nTemp2 = MULT_EG1_EG1(nDelayOut, pReverbData->m_nCos);
-
- // calculate unfiltered delay out
- nDelayOut = SATURATE(nTemp1 + nTemp2);
-
- // calculate lowpass filter (mixer scale factor included in LPF feedforward)
- nTemp1 = MULT_EG1_EG1(nDelayOut, pReverbData->m_nLpfFwd);
-
- nTemp2 = MULT_EG1_EG1(pReverbData->m_zLpf0, pReverbData->m_nLpfFbk);
-
- // calculate filtered delay out and simultaneously update LPF state variable
- // filtered delay output is stored in m_zLpf0
- pReverbData->m_zLpf0 = (EAS_PCM) SATURATE(nTemp1 + nTemp2);
-
- // ********** D0 output - end
-
- // ********** D1 output - start
- // fetch delay line self out
- nAddr = CIRCULAR(nBase, pReverbData->m_zD1Self, REVERB_BUFFER_MASK);
- nDelayOut = pReverbData->m_nDelayLine[nAddr];
-
- // calculate delay line self out
- nTemp1 = MULT_EG1_EG1(nDelayOut, pReverbData->m_nSin);
-
- // fetch delay line cross out
- nAddr = CIRCULAR(nBase, pReverbData->m_zD0Cross, REVERB_BUFFER_MASK);
- nDelayOut = pReverbData->m_nDelayLine[nAddr];
-
- // calculate delay line self out
- nTemp2 = MULT_EG1_EG1(nDelayOut, pReverbData->m_nCos);
-
- // calculate unfiltered delay out
- nDelayOut = SATURATE(nTemp1 + nTemp2);
-
- // calculate lowpass filter (mixer scale factor included in LPF feedforward)
- nTemp1 = MULT_EG1_EG1(nDelayOut, pReverbData->m_nLpfFwd);
-
- nTemp2 = MULT_EG1_EG1(pReverbData->m_zLpf1, pReverbData->m_nLpfFbk);
-
- // calculate filtered delay out and simultaneously update LPF state variable
- // filtered delay output is stored in m_zLpf1
- pReverbData->m_zLpf1 = (EAS_PCM)SATURATE(nTemp1 + nTemp2);
-
- // ********** D1 output - end
-
- // ********** mixer and feedback - start
- // sum is fedback to right input (R + L)
- pReverbData->m_nRevOutFbkL =
- (EAS_PCM)SATURATE((EAS_I32)pReverbData->m_zLpf1 + (EAS_I32)pReverbData->m_zLpf0);
-
- // difference is feedback to left input (R - L)
- /*lint -e{685} lint complains that it can't saturate negative */
- pReverbData->m_nRevOutFbkR =
- (EAS_PCM)SATURATE((EAS_I32)pReverbData->m_zLpf1 - (EAS_I32)pReverbData->m_zLpf0);
-
- // ********** mixer and feedback - end
-
- // ********** start early reflection generator, left
- //psEarly = &(pReverbData->m_sEarlyL);
-
- nEarlyOut = 0;
-
- for (j=0; j < REVERB_MAX_NUM_REFLECTIONS; j++)
- {
- // fetch delay line out
- //nAddr = CIRCULAR(nBase, psEarly->m_zDelay[j], REVERB_BUFFER_MASK);
- nAddr = CIRCULAR(nBase, pReverbData->m_sEarlyL.m_zDelay[j], REVERB_BUFFER_MASK);
-
- nDelayOut = pReverbData->m_nDelayLine[nAddr];
-
- // calculate reflection
- //nTemp1 = MULT_EG1_EG1(nDelayOut, psEarly->m_nGain[j]);
- nTemp1 = MULT_EG1_EG1(nDelayOut, pReverbData->m_sEarlyL.m_nGain[j]);
-
- nEarlyOut = SATURATE(nEarlyOut + nTemp1);
-
- } // end for (j=0; j < REVERB_MAX_NUM_REFLECTIONS; j++)
-
- // apply lowpass to early reflections
- //nTemp1 = MULT_EG1_EG1(nEarlyOut, psEarly->m_nLpfFwd);
- nTemp1 = MULT_EG1_EG1(nEarlyOut, pReverbData->m_sEarlyL.m_nLpfFwd);
-
- //nTemp2 = MULT_EG1_EG1(psEarly->m_zLpf, psEarly->m_nLpfFbk);
- nTemp2 = MULT_EG1_EG1(pReverbData->m_sEarlyL.m_zLpf, pReverbData->m_sEarlyL.m_nLpfFbk);
-
-
- // calculate filtered out and simultaneously update LPF state variable
- // filtered output is stored in m_zLpf1
- //psEarly->m_zLpf = SATURATE(nTemp1 + nTemp2);
- pReverbData->m_sEarlyL.m_zLpf = (EAS_PCM) SATURATE(nTemp1 + nTemp2);
-
- // combine filtered early and late reflections for output
- //*pOutputBuffer++ = inL;
- //tempValue = SATURATE(psEarly->m_zLpf + pReverbData->m_nRevOutFbkL);
- tempValue = SATURATE((EAS_I32)pReverbData->m_sEarlyL.m_zLpf + (EAS_I32)pReverbData->m_nRevOutFbkL);
- //scale reverb output by wet level
- /*lint -e{701} use shift for performance */
- tempValue = MULT_EG1_EG1(tempValue, (pReverbData->m_nWet<<1));
- //sum with output buffer
- tempValue += *pOutputBuffer;
- *pOutputBuffer++ = (EAS_PCM)SATURATE(tempValue);
-
- // ********** end early reflection generator, left
-
- // ********** start early reflection generator, right
- //psEarly = &(pReverbData->m_sEarlyR);
-
- nEarlyOut = 0;
-
- for (j=0; j < REVERB_MAX_NUM_REFLECTIONS; j++)
- {
- // fetch delay line out
- nAddr = CIRCULAR(nBase, pReverbData->m_sEarlyR.m_zDelay[j], REVERB_BUFFER_MASK);
- nDelayOut = pReverbData->m_nDelayLine[nAddr];
-
- // calculate reflection
- nTemp1 = MULT_EG1_EG1(nDelayOut, pReverbData->m_sEarlyR.m_nGain[j]);
-
- nEarlyOut = SATURATE(nEarlyOut + nTemp1);
-
- } // end for (j=0; j < REVERB_MAX_NUM_REFLECTIONS; j++)
-
- // apply lowpass to early reflections
- nTemp1 = MULT_EG1_EG1(nEarlyOut, pReverbData->m_sEarlyR.m_nLpfFwd);
-
- nTemp2 = MULT_EG1_EG1(pReverbData->m_sEarlyR.m_zLpf, pReverbData->m_sEarlyR.m_nLpfFbk);
-
- // calculate filtered out and simultaneously update LPF state variable
- // filtered output is stored in m_zLpf1
- pReverbData->m_sEarlyR.m_zLpf = (EAS_PCM)SATURATE(nTemp1 + nTemp2);
-
- // combine filtered early and late reflections for output
- //*pOutputBuffer++ = inR;
- tempValue = SATURATE((EAS_I32)pReverbData->m_sEarlyR.m_zLpf + (EAS_I32)pReverbData->m_nRevOutFbkR);
- //scale reverb output by wet level
- /*lint -e{701} use shift for performance */
- tempValue = MULT_EG1_EG1(tempValue, (pReverbData->m_nWet << 1));
- //sum with output buffer
- tempValue = tempValue + *pOutputBuffer;
- *pOutputBuffer++ = (EAS_PCM)SATURATE(tempValue);
-
- // ********** end early reflection generator, right
-
- // decrement base addr for next sample period
- nBase--;
-
- pReverbData->m_nSin += pReverbData->m_nSinIncrement;
- pReverbData->m_nCos += pReverbData->m_nCosIncrement;
-
- } // end for (i=0; i < nNumSamplesToAdd; i++)
-
- // store the most up to date version
- pReverbData->m_nBaseIndex = nBase;
-
- return EAS_SUCCESS;
-} /* end Reverb */
-
-
-
-/*----------------------------------------------------------------------------
- * ReverbShutdown()
- *----------------------------------------------------------------------------
- * Purpose:
- * Initializes the Reverb effect.
- *
- * Inputs:
- * pInstData - handle to instance data
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT ReverbShutdown (EAS_DATA_HANDLE pEASData, EAS_VOID_PTR pInstData)
-{
- /* check Configuration Module for static memory allocation */
- if (!pEASData->staticMemoryModel)
- EAS_HWFree(pEASData->hwInstData, pInstData);
- return EAS_SUCCESS;
-} /* end ReverbShutdown */
-
-/*----------------------------------------------------------------------------
- * ReverbGetParam()
- *----------------------------------------------------------------------------
- * Purpose:
- * Get a Reverb parameter
- *
- * Inputs:
- * pInstData - handle to instance data
- * param - parameter index
- * *pValue - pointer to variable to hold retrieved value
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT ReverbGetParam (EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue)
-{
- S_REVERB_OBJECT *p;
-
- p = (S_REVERB_OBJECT*) pInstData;
-
- switch (param)
- {
- case EAS_PARAM_REVERB_BYPASS:
- *pValue = (EAS_I32) p->m_bBypass;
- break;
- case EAS_PARAM_REVERB_PRESET:
- *pValue = (EAS_I8) p->m_nCurrentRoom;
- break;
- case EAS_PARAM_REVERB_WET:
- *pValue = p->m_nWet;
- break;
- case EAS_PARAM_REVERB_DRY:
- *pValue = p->m_nDry;
- break;
- default:
- return EAS_ERROR_INVALID_PARAMETER;
- }
- return EAS_SUCCESS;
-} /* end ReverbGetParam */
-
-
-/*----------------------------------------------------------------------------
- * ReverbSetParam()
- *----------------------------------------------------------------------------
- * Purpose:
- * Set a Reverb parameter
- *
- * Inputs:
- * pInstData - handle to instance data
- * param - parameter index
- * *pValue - new paramter value
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT ReverbSetParam (EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value)
-{
- S_REVERB_OBJECT *p;
-
- p = (S_REVERB_OBJECT*) pInstData;
-
- switch (param)
- {
- case EAS_PARAM_REVERB_BYPASS:
- p->m_bBypass = (EAS_BOOL) value;
- break;
- case EAS_PARAM_REVERB_PRESET:
- if(value!=EAS_PARAM_REVERB_LARGE_HALL && value!=EAS_PARAM_REVERB_HALL &&
- value!=EAS_PARAM_REVERB_CHAMBER && value!=EAS_PARAM_REVERB_ROOM)
- return EAS_ERROR_INVALID_PARAMETER;
- p->m_nNextRoom = (EAS_I16)value;
- break;
- case EAS_PARAM_REVERB_WET:
- if(value>EAS_REVERB_WET_MAX || value<EAS_REVERB_WET_MIN)
- return EAS_ERROR_INVALID_PARAMETER;
- p->m_nWet = (EAS_I16)value;
- break;
- case EAS_PARAM_REVERB_DRY:
- if(value>EAS_REVERB_DRY_MAX || value<EAS_REVERB_DRY_MIN)
- return EAS_ERROR_INVALID_PARAMETER;
- p->m_nDry = (EAS_I16)value;
- break;
- default:
- return EAS_ERROR_INVALID_PARAMETER;
- }
- return EAS_SUCCESS;
-} /* end ReverbSetParam */
-
-
-/*----------------------------------------------------------------------------
- * ReverbUpdateRoom
- *----------------------------------------------------------------------------
- * Purpose:
- * Update the room's preset parameters as required
- *
- * Inputs:
- *
- * Outputs:
- *
- *
- * Side Effects:
- * - reverb paramters (fbk, fwd, etc) will be changed
- * - m_nCurrentRoom := m_nNextRoom
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT ReverbUpdateRoom(S_REVERB_OBJECT *pReverbData)
-{
- EAS_INT temp;
-
- S_REVERB_PRESET *pPreset = &pReverbData->m_sPreset.m_sPreset[pReverbData->m_nNextRoom];
-
- pReverbData->m_nLpfFwd = pPreset->m_nLpfFwd;
- pReverbData->m_nLpfFbk = pPreset->m_nLpfFbk;
-
- pReverbData->m_nEarly = pPreset->m_nEarly;
- pReverbData->m_nWet = pPreset->m_nWet;
- pReverbData->m_nDry = pPreset->m_nDry;
-
-
- pReverbData->m_nMaxExcursion = pPreset->m_nMaxExcursion;
- //stored as time based, convert to sample based
- temp = pPreset->m_nXfadeInterval;
- /*lint -e{702} shift for performance */
- temp = (temp * _OUTPUT_SAMPLE_RATE) >> 16;
- pReverbData->m_nXfadeInterval = (EAS_U16) temp;
- //gpsReverbObject->m_nXfadeInterval = pPreset->m_nXfadeInterval;
- pReverbData->m_sAp0.m_nApGain = pPreset->m_nAp0_ApGain;
- //stored as time based, convert to absolute sample value
- temp = pPreset->m_nAp0_ApOut;
- /*lint -e{702} shift for performance */
- temp = (temp * _OUTPUT_SAMPLE_RATE) >> 16;
- pReverbData->m_sAp0.m_zApOut = (EAS_U16) (pReverbData->m_sAp0.m_zApIn + temp);
- //gpsReverbObject->m_sAp0.m_zApOut = pPreset->m_nAp0_ApOut;
- pReverbData->m_sAp1.m_nApGain = pPreset->m_nAp1_ApGain;
- //stored as time based, convert to absolute sample value
- temp = pPreset->m_nAp1_ApOut;
- /*lint -e{702} shift for performance */
- temp = (temp * _OUTPUT_SAMPLE_RATE) >> 16;
- pReverbData->m_sAp1.m_zApOut = (EAS_U16) (pReverbData->m_sAp1.m_zApIn + temp);
- //gpsReverbObject->m_sAp1.m_zApOut = pPreset->m_nAp1_ApOut;
-
- pReverbData->m_nCurrentRoom = pReverbData->m_nNextRoom;
-
- return EAS_SUCCESS;
-
-} /* end ReverbUpdateRoom */
-
-
-/*----------------------------------------------------------------------------
- * ReverbReadInPresets()
- *----------------------------------------------------------------------------
- * Purpose: sets global reverb preset bank to defaults
- *
- * Inputs:
- *
- * Outputs:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT ReverbReadInPresets(S_REVERB_OBJECT *pReverbData)
-{
-
- int preset = 0;
- int defaultPreset = 0;
-
- //now init any remaining presets to defaults
- for (defaultPreset = preset; defaultPreset < REVERB_MAX_ROOM_TYPE; defaultPreset++)
- {
- S_REVERB_PRESET *pPreset = &pReverbData->m_sPreset.m_sPreset[defaultPreset];
- if (defaultPreset == 0 || defaultPreset > REVERB_MAX_ROOM_TYPE-1)
- {
- pPreset->m_nLpfFbk = 8307;
- pPreset->m_nLpfFwd = 14768;
- pPreset->m_nEarly = 0;
- pPreset->m_nWet = 27690;
- pPreset->m_nDry = 32767;
- pPreset->m_nEarlyL_LpfFbk = 3692;
- pPreset->m_nEarlyL_LpfFwd = 29075;
- pPreset->m_nEarlyL_Delay0 = 922;
- pPreset->m_nEarlyL_Gain0 = 22152;
- pPreset->m_nEarlyL_Delay1 = 1462;
- pPreset->m_nEarlyL_Gain1 = 17537;
- pPreset->m_nEarlyL_Delay2 = 0;
- pPreset->m_nEarlyL_Gain2 = 14768;
- pPreset->m_nEarlyL_Delay3 = 1221;
- pPreset->m_nEarlyL_Gain3 = 14307;
- pPreset->m_nEarlyL_Delay4 = 0;
- pPreset->m_nEarlyL_Gain4 = 13384;
- pPreset->m_nEarlyR_Delay0 = 502;
- pPreset->m_nEarlyR_Gain0 = 20306;
- pPreset->m_nEarlyR_Delay1 = 1762;
- pPreset->m_nEarlyR_Gain1 = 17537;
- pPreset->m_nEarlyR_Delay2 = 0;
- pPreset->m_nEarlyR_Gain2 = 14768;
- pPreset->m_nEarlyR_Delay3 = 0;
- pPreset->m_nEarlyR_Gain3 = 16153;
- pPreset->m_nEarlyR_Delay4 = 0;
- pPreset->m_nEarlyR_Gain4 = 13384;
- pPreset->m_nMaxExcursion = 127;
- pPreset->m_nXfadeInterval = 6388;
- pPreset->m_nAp0_ApGain = 15691;
- pPreset->m_nAp0_ApOut = 711;
- pPreset->m_nAp1_ApGain = 17999;
- pPreset->m_nAp1_ApOut = 1113;
- pPreset->m_rfu4 = 0;
- pPreset->m_rfu5 = 0;
- pPreset->m_rfu6 = 0;
- pPreset->m_rfu7 = 0;
- pPreset->m_rfu8 = 0;
- pPreset->m_rfu9 = 0;
- pPreset->m_rfu10 = 0;
- }
- else if (defaultPreset == 1)
- {
- pPreset->m_nLpfFbk = 6461;
- pPreset->m_nLpfFwd = 14307;
- pPreset->m_nEarly = 0;
- pPreset->m_nWet = 27690;
- pPreset->m_nDry = 32767;
- pPreset->m_nEarlyL_LpfFbk = 3692;
- pPreset->m_nEarlyL_LpfFwd = 29075;
- pPreset->m_nEarlyL_Delay0 = 922;
- pPreset->m_nEarlyL_Gain0 = 22152;
- pPreset->m_nEarlyL_Delay1 = 1462;
- pPreset->m_nEarlyL_Gain1 = 17537;
- pPreset->m_nEarlyL_Delay2 = 0;
- pPreset->m_nEarlyL_Gain2 = 14768;
- pPreset->m_nEarlyL_Delay3 = 1221;
- pPreset->m_nEarlyL_Gain3 = 14307;
- pPreset->m_nEarlyL_Delay4 = 0;
- pPreset->m_nEarlyL_Gain4 = 13384;
- pPreset->m_nEarlyR_Delay0 = 502;
- pPreset->m_nEarlyR_Gain0 = 20306;
- pPreset->m_nEarlyR_Delay1 = 1762;
- pPreset->m_nEarlyR_Gain1 = 17537;
- pPreset->m_nEarlyR_Delay2 = 0;
- pPreset->m_nEarlyR_Gain2 = 14768;
- pPreset->m_nEarlyR_Delay3 = 0;
- pPreset->m_nEarlyR_Gain3 = 16153;
- pPreset->m_nEarlyR_Delay4 = 0;
- pPreset->m_nEarlyR_Gain4 = 13384;
- pPreset->m_nMaxExcursion = 127;
- pPreset->m_nXfadeInterval = 6391;
- pPreset->m_nAp0_ApGain = 15230;
- pPreset->m_nAp0_ApOut = 708;
- pPreset->m_nAp1_ApGain = 9692;
- pPreset->m_nAp1_ApOut = 1113;
- pPreset->m_rfu4 = 0;
- pPreset->m_rfu5 = 0;
- pPreset->m_rfu6 = 0;
- pPreset->m_rfu7 = 0;
- pPreset->m_rfu8 = 0;
- pPreset->m_rfu9 = 0;
- pPreset->m_rfu10 = 0;
- }
- else if (defaultPreset == 2)
- {
- pPreset->m_nLpfFbk = 5077;
- pPreset->m_nLpfFwd = 12922;
- pPreset->m_nEarly = 0;
- pPreset->m_nWet = 24460;
- pPreset->m_nDry = 32767;
- pPreset->m_nEarlyL_LpfFbk = 3692;
- pPreset->m_nEarlyL_LpfFwd = 29075;
- pPreset->m_nEarlyL_Delay0 = 922;
- pPreset->m_nEarlyL_Gain0 = 22152;
- pPreset->m_nEarlyL_Delay1 = 1462;
- pPreset->m_nEarlyL_Gain1 = 17537;
- pPreset->m_nEarlyL_Delay2 = 0;
- pPreset->m_nEarlyL_Gain2 = 14768;
- pPreset->m_nEarlyL_Delay3 = 1221;
- pPreset->m_nEarlyL_Gain3 = 14307;
- pPreset->m_nEarlyL_Delay4 = 0;
- pPreset->m_nEarlyL_Gain4 = 13384;
- pPreset->m_nEarlyR_Delay0 = 502;
- pPreset->m_nEarlyR_Gain0 = 20306;
- pPreset->m_nEarlyR_Delay1 = 1762;
- pPreset->m_nEarlyR_Gain1 = 17537;
- pPreset->m_nEarlyR_Delay2 = 0;
- pPreset->m_nEarlyR_Gain2 = 14768;
- pPreset->m_nEarlyR_Delay3 = 0;
- pPreset->m_nEarlyR_Gain3 = 16153;
- pPreset->m_nEarlyR_Delay4 = 0;
- pPreset->m_nEarlyR_Gain4 = 13384;
- pPreset->m_nMaxExcursion = 127;
- pPreset->m_nXfadeInterval = 6449;
- pPreset->m_nAp0_ApGain = 15691;
- pPreset->m_nAp0_ApOut = 774;
- pPreset->m_nAp1_ApGain = 15691;
- pPreset->m_nAp1_ApOut = 1113;
- pPreset->m_rfu4 = 0;
- pPreset->m_rfu5 = 0;
- pPreset->m_rfu6 = 0;
- pPreset->m_rfu7 = 0;
- pPreset->m_rfu8 = 0;
- pPreset->m_rfu9 = 0;
- pPreset->m_rfu10 = 0;
- }
- else if (defaultPreset == 3)
- {
- pPreset->m_nLpfFbk = 5077;
- pPreset->m_nLpfFwd = 11076;
- pPreset->m_nEarly = 0;
- pPreset->m_nWet = 23075;
- pPreset->m_nDry = 32767;
- pPreset->m_nEarlyL_LpfFbk = 3692;
- pPreset->m_nEarlyL_LpfFwd = 29075;
- pPreset->m_nEarlyL_Delay0 = 922;
- pPreset->m_nEarlyL_Gain0 = 22152;
- pPreset->m_nEarlyL_Delay1 = 1462;
- pPreset->m_nEarlyL_Gain1 = 17537;
- pPreset->m_nEarlyL_Delay2 = 0;
- pPreset->m_nEarlyL_Gain2 = 14768;
- pPreset->m_nEarlyL_Delay3 = 1221;
- pPreset->m_nEarlyL_Gain3 = 14307;
- pPreset->m_nEarlyL_Delay4 = 0;
- pPreset->m_nEarlyL_Gain4 = 13384;
- pPreset->m_nEarlyR_Delay0 = 502;
- pPreset->m_nEarlyR_Gain0 = 20306;
- pPreset->m_nEarlyR_Delay1 = 1762;
- pPreset->m_nEarlyR_Gain1 = 17537;
- pPreset->m_nEarlyR_Delay2 = 0;
- pPreset->m_nEarlyR_Gain2 = 14768;
- pPreset->m_nEarlyR_Delay3 = 0;
- pPreset->m_nEarlyR_Gain3 = 16153;
- pPreset->m_nEarlyR_Delay4 = 0;
- pPreset->m_nEarlyR_Gain4 = 13384;
- pPreset->m_nMaxExcursion = 127;
- pPreset->m_nXfadeInterval = 6470; //6483;
- pPreset->m_nAp0_ApGain = 14768;
- pPreset->m_nAp0_ApOut = 792;
- pPreset->m_nAp1_ApGain = 15783;
- pPreset->m_nAp1_ApOut = 1113;
- pPreset->m_rfu4 = 0;
- pPreset->m_rfu5 = 0;
- pPreset->m_rfu6 = 0;
- pPreset->m_rfu7 = 0;
- pPreset->m_rfu8 = 0;
- pPreset->m_rfu9 = 0;
- pPreset->m_rfu10 = 0;
-
- }
- }
-
- return EAS_SUCCESS;
-}
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 510 $
+ * $Date: 2006-12-19 01:47:33 -0800 (Tue, 19 Dec 2006) $
+ *----------------------------------------------------------------------------
+*/
+
+/*------------------------------------
+ * includes
+ *------------------------------------
+*/
+
+#include "eas_data.h"
+#include "eas_effects.h"
+#include "eas_math.h"
+#include "eas_reverbdata.h"
+#include "eas_reverb.h"
+#include "eas_config.h"
+#include "eas_host.h"
+#include "eas_report.h"
+
+/* prototypes for effects interface */
+static EAS_RESULT ReverbInit (EAS_DATA_HANDLE pEASData, EAS_VOID_PTR *pInstData);
+static void ReverbProcess (EAS_VOID_PTR pInstData, EAS_PCM *pSrc, EAS_PCM *pDst, EAS_I32 numSamples);
+static EAS_RESULT ReverbShutdown (EAS_DATA_HANDLE pEASData, EAS_VOID_PTR pInstData);
+static EAS_RESULT ReverbGetParam (EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue);
+static EAS_RESULT ReverbSetParam (EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value);
+
+/* common effects interface for configuration module */
+const S_EFFECTS_INTERFACE EAS_Reverb =
+{
+ ReverbInit,
+ ReverbProcess,
+ ReverbShutdown,
+ ReverbGetParam,
+ ReverbSetParam
+};
+
+
+
+/*----------------------------------------------------------------------------
+ * InitializeReverb()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ *
+ * Inputs:
+ *
+ * Outputs:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT ReverbInit(EAS_DATA_HANDLE pEASData, EAS_VOID_PTR *pInstData)
+{
+ EAS_I32 i;
+ EAS_U16 nOffset;
+ EAS_INT temp;
+
+ S_REVERB_OBJECT *pReverbData;
+ S_REVERB_PRESET *pPreset;
+
+ /* check Configuration Module for data allocation */
+ if (pEASData->staticMemoryModel)
+ pReverbData = EAS_CMEnumFXData(EAS_MODULE_REVERB);
+
+ /* allocate dynamic memory */
+ else
+ pReverbData = EAS_HWMalloc(pEASData->hwInstData, sizeof(S_REVERB_OBJECT));
+
+ if (pReverbData == NULL)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_FATAL, "Failed to allocate Reverb memory\n"); */ }
+ return EAS_ERROR_MALLOC_FAILED;
+ }
+
+ /* clear the structure */
+ EAS_HWMemSet(pReverbData, 0, sizeof(S_REVERB_OBJECT));
+
+ ReverbReadInPresets(pReverbData);
+
+ pReverbData->m_nMinSamplesToAdd = REVERB_UPDATE_PERIOD_IN_SAMPLES;
+
+ pReverbData->m_nRevOutFbkR = 0;
+ pReverbData->m_nRevOutFbkL = 0;
+
+ pReverbData->m_sAp0.m_zApIn = AP0_IN;
+ pReverbData->m_sAp0.m_zApOut = AP0_IN + DEFAULT_AP0_LENGTH;
+ pReverbData->m_sAp0.m_nApGain = DEFAULT_AP0_GAIN;
+
+ pReverbData->m_zD0In = DELAY0_IN;
+
+ pReverbData->m_sAp1.m_zApIn = AP1_IN;
+ pReverbData->m_sAp1.m_zApOut = AP1_IN + DEFAULT_AP1_LENGTH;
+ pReverbData->m_sAp1.m_nApGain = DEFAULT_AP1_GAIN;
+
+ pReverbData->m_zD1In = DELAY1_IN;
+
+ pReverbData->m_zLpf0 = 0;
+ pReverbData->m_zLpf1 = 0;
+ pReverbData->m_nLpfFwd = 8837;
+ pReverbData->m_nLpfFbk = 6494;
+
+ pReverbData->m_nSin = 0;
+ pReverbData->m_nCos = 0;
+ pReverbData->m_nSinIncrement = 0;
+ pReverbData->m_nCosIncrement = 0;
+
+ // set xfade parameters
+ pReverbData->m_nXfadeInterval = (EAS_U16)REVERB_XFADE_PERIOD_IN_SAMPLES;
+ pReverbData->m_nXfadeCounter = pReverbData->m_nXfadeInterval + 1; // force update on first iteration
+ pReverbData->m_nPhase = -32768;
+ pReverbData->m_nPhaseIncrement = REVERB_XFADE_PHASE_INCREMENT;
+
+ pReverbData->m_nNoise = (EAS_I16)0xABCD;
+
+ pReverbData->m_nMaxExcursion = 0x007F;
+
+ // set delay tap lengths
+ nOffset = ReverbCalculateNoise( pReverbData->m_nMaxExcursion,
+ &pReverbData->m_nNoise );
+
+ pReverbData->m_zD1Cross =
+ DELAY1_OUT - pReverbData->m_nMaxExcursion + nOffset;
+
+ nOffset = ReverbCalculateNoise( pReverbData->m_nMaxExcursion,
+ &pReverbData->m_nNoise );
+
+ pReverbData->m_zD0Cross =
+ DELAY1_OUT - pReverbData->m_nMaxExcursion - nOffset;
+
+ nOffset = ReverbCalculateNoise( pReverbData->m_nMaxExcursion,
+ &pReverbData->m_nNoise );
+
+ pReverbData->m_zD0Self =
+ DELAY0_OUT - pReverbData->m_nMaxExcursion - nOffset;
+
+ nOffset = ReverbCalculateNoise( pReverbData->m_nMaxExcursion,
+ &pReverbData->m_nNoise );
+
+ pReverbData->m_zD1Self =
+ DELAY1_OUT - pReverbData->m_nMaxExcursion + nOffset;
+
+ // for debugging purposes, allow noise generator
+ pReverbData->m_bUseNoise = EAS_FALSE;
+
+ // for debugging purposes, allow bypass
+ pReverbData->m_bBypass = EAS_TRUE; //EAS_FALSE;
+
+ pReverbData->m_nNextRoom = 1;
+
+ pReverbData->m_nCurrentRoom = pReverbData->m_nNextRoom + 1; // force update on first iteration
+
+ pReverbData->m_nWet = REVERB_DEFAULT_WET;
+
+ pReverbData->m_nDry = REVERB_DEFAULT_DRY;
+
+ // set base index into circular buffer
+ pReverbData->m_nBaseIndex = 0;
+
+ // set the early reflections, L
+ pReverbData->m_sEarlyL.m_nLpfFbk = 4915;
+ pReverbData->m_sEarlyL.m_nLpfFwd = 27852;
+ pReverbData->m_sEarlyL.m_zLpf = 0;
+
+ for (i=0; i < REVERB_MAX_NUM_REFLECTIONS; i++)
+ {
+ pReverbData->m_sEarlyL.m_nGain[i] = 0;
+ pReverbData->m_sEarlyL.m_zDelay[i] = 0;
+ }
+
+ // set the early reflections, R
+ pReverbData->m_sEarlyR.m_nLpfFbk = 4915;
+ pReverbData->m_sEarlyR.m_nLpfFwd = 27852;
+ pReverbData->m_sEarlyR.m_zLpf = 0;
+
+ for (i=0; i < REVERB_MAX_NUM_REFLECTIONS; i++)
+ {
+ pReverbData->m_sEarlyR.m_nGain[i] = 0;
+ pReverbData->m_sEarlyR.m_zDelay[i] = 0;
+ }
+
+ // clear the reverb delay line
+ for (i=0; i < REVERB_BUFFER_SIZE_IN_SAMPLES; i++)
+ {
+ pReverbData->m_nDelayLine[i] = 0;
+ }
+
+ ////////////////////////////////
+ ///code from the EAS DEMO Reverb
+ //now copy from the new preset into the reverb
+ pPreset = &pReverbData->m_sPreset.m_sPreset[pReverbData->m_nNextRoom];
+
+ pReverbData->m_nLpfFbk = pPreset->m_nLpfFbk;
+ pReverbData->m_nLpfFwd = pPreset->m_nLpfFwd;
+
+ pReverbData->m_nEarly = pPreset->m_nEarly;
+ pReverbData->m_nWet = pPreset->m_nWet;
+ pReverbData->m_nDry = pPreset->m_nDry;
+
+ pReverbData->m_nMaxExcursion = pPreset->m_nMaxExcursion;
+ //stored as time based, convert to sample based
+ temp = pPreset->m_nXfadeInterval;
+ /*lint -e{702} shift for performance */
+ temp = (temp * _OUTPUT_SAMPLE_RATE) >> 16;
+ pReverbData->m_nXfadeInterval = (EAS_U16) temp;
+ //gsReverbObject.m_nXfadeInterval = pPreset->m_nXfadeInterval;
+
+ pReverbData->m_sAp0.m_nApGain = pPreset->m_nAp0_ApGain;
+ //stored as time based, convert to absolute sample value
+ temp = pPreset->m_nAp0_ApOut;
+ /*lint -e{702} shift for performance */
+ temp = (temp * _OUTPUT_SAMPLE_RATE) >> 16;
+ pReverbData->m_sAp0.m_zApOut = (EAS_U16) (pReverbData->m_sAp0.m_zApIn + temp);
+ //gsReverbObject.m_sAp0.m_zApOut = pPreset->m_nAp0_ApOut;
+
+ pReverbData->m_sAp1.m_nApGain = pPreset->m_nAp1_ApGain;
+ //stored as time based, convert to absolute sample value
+ temp = pPreset->m_nAp1_ApOut;
+ /*lint -e{702} shift for performance */
+ temp = (temp * _OUTPUT_SAMPLE_RATE) >> 16;
+ pReverbData->m_sAp1.m_zApOut = (EAS_U16) (pReverbData->m_sAp1.m_zApIn + temp);
+ //gsReverbObject.m_sAp1.m_zApOut = pPreset->m_nAp1_ApOut;
+ ///code from the EAS DEMO Reverb
+ ////////////////////////////////
+
+ *pInstData = pReverbData;
+
+ return EAS_SUCCESS;
+
+} /* end InitializeReverb */
+
+
+
+/*----------------------------------------------------------------------------
+ * ReverbProcess()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Reverberate the requested number of samples (block based processing)
+ *
+ * Inputs:
+ * pInputBuffer - src buffer
+ * pOutputBuffer - dst buffer
+ * nNumSamplesToAdd - number of samples to write to buffer
+ *
+ * Outputs:
+ * number of samples actually written to buffer
+ *
+ * Side Effects:
+ * - samples are added to the presently free buffer
+ *
+ *----------------------------------------------------------------------------
+*/
+static void ReverbProcess(EAS_VOID_PTR pInstData, EAS_PCM *pSrc, EAS_PCM *pDst, EAS_I32 numSamples)
+{
+ S_REVERB_OBJECT *pReverbData;
+
+ pReverbData = (S_REVERB_OBJECT*) pInstData;
+
+ //if bypassed or the preset forces the signal to be completely dry
+ if (pReverbData->m_bBypass ||
+ (pReverbData->m_nWet == 0 && pReverbData->m_nDry == 32767))
+ {
+ if (pSrc != pDst)
+ EAS_HWMemCpy(pSrc, pDst, numSamples * NUM_OUTPUT_CHANNELS * (EAS_I32) sizeof(EAS_PCM));
+ return;
+ }
+
+ if (pReverbData->m_nNextRoom != pReverbData->m_nCurrentRoom)
+ {
+ ReverbUpdateRoom(pReverbData);
+ }
+
+ ReverbUpdateXfade(pReverbData, numSamples);
+
+ Reverb(pReverbData, numSamples, pDst, pSrc);
+
+ /* check if update counter needs to be reset */
+ if (pReverbData->m_nUpdateCounter >= REVERB_MODULO_UPDATE_PERIOD_IN_SAMPLES)
+ {
+ /* update interval has elapsed, so reset counter */
+ pReverbData->m_nUpdateCounter = 0;
+ } /* end if m_nUpdateCounter >= update interval */
+
+ /* increment update counter */
+ pReverbData->m_nUpdateCounter += (EAS_I16)numSamples;
+
+} /* end ComputeReverb */
+
+/*----------------------------------------------------------------------------
+ * ReverbUpdateXfade
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Update the xfade parameters as required
+ *
+ * Inputs:
+ * nNumSamplesToAdd - number of samples to write to buffer
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ * - xfade parameters will be changed
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT ReverbUpdateXfade(S_REVERB_OBJECT *pReverbData, EAS_INT nNumSamplesToAdd)
+{
+ EAS_U16 nOffset;
+ EAS_I16 tempCos;
+ EAS_I16 tempSin;
+
+ if (pReverbData->m_nXfadeCounter >= pReverbData->m_nXfadeInterval)
+ {
+ /* update interval has elapsed, so reset counter */
+ pReverbData->m_nXfadeCounter = 0;
+
+ // Pin the sin,cos values to min / max values to ensure that the
+ // modulated taps' coefs are zero (thus no clicks)
+ if (pReverbData->m_nPhaseIncrement > 0)
+ {
+ // if phase increment > 0, then sin -> 1, cos -> 0
+ pReverbData->m_nSin = 32767;
+ pReverbData->m_nCos = 0;
+
+ // reset the phase to match the sin, cos values
+ pReverbData->m_nPhase = 32767;
+
+ // modulate the cross taps because their tap coefs are zero
+ nOffset = ReverbCalculateNoise( pReverbData->m_nMaxExcursion, &pReverbData->m_nNoise );
+
+ pReverbData->m_zD1Cross =
+ DELAY1_OUT - pReverbData->m_nMaxExcursion + nOffset;
+
+ nOffset = ReverbCalculateNoise( pReverbData->m_nMaxExcursion, &pReverbData->m_nNoise );
+
+ pReverbData->m_zD0Cross =
+ DELAY0_OUT - pReverbData->m_nMaxExcursion - nOffset;
+ }
+ else
+ {
+ // if phase increment < 0, then sin -> 0, cos -> 1
+ pReverbData->m_nSin = 0;
+ pReverbData->m_nCos = 32767;
+
+ // reset the phase to match the sin, cos values
+ pReverbData->m_nPhase = -32768;
+
+ // modulate the self taps because their tap coefs are zero
+ nOffset = ReverbCalculateNoise( pReverbData->m_nMaxExcursion, &pReverbData->m_nNoise );
+
+ pReverbData->m_zD0Self =
+ DELAY0_OUT - pReverbData->m_nMaxExcursion - nOffset;
+
+ nOffset = ReverbCalculateNoise( pReverbData->m_nMaxExcursion, &pReverbData->m_nNoise );
+
+ pReverbData->m_zD1Self =
+ DELAY1_OUT - pReverbData->m_nMaxExcursion + nOffset;
+
+ } // end if-else (pReverbData->m_nPhaseIncrement > 0)
+
+ // Reverse the direction of the sin,cos so that the
+ // tap whose coef was previously increasing now decreases
+ // and vice versa
+ pReverbData->m_nPhaseIncrement = -pReverbData->m_nPhaseIncrement;
+
+ } // end if counter >= update interval
+
+ //compute what phase will be next time
+ pReverbData->m_nPhase += pReverbData->m_nPhaseIncrement;
+
+ //calculate what the new sin and cos need to reach by the next update
+ ReverbCalculateSinCos(pReverbData->m_nPhase, &tempSin, &tempCos);
+
+ //calculate the per-sample increment required to get there by the next update
+ /*lint -e{702} shift for performance */
+ pReverbData->m_nSinIncrement =
+ (tempSin - pReverbData->m_nSin) >> REVERB_UPDATE_PERIOD_IN_BITS;
+
+ /*lint -e{702} shift for performance */
+ pReverbData->m_nCosIncrement =
+ (tempCos - pReverbData->m_nCos) >> REVERB_UPDATE_PERIOD_IN_BITS;
+
+
+ /* increment update counter */
+ pReverbData->m_nXfadeCounter += (EAS_U16) nNumSamplesToAdd;
+
+ return EAS_SUCCESS;
+
+} /* end ReverbUpdateXfade */
+
+
+/*----------------------------------------------------------------------------
+ * ReverbCalculateNoise
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Calculate a noise sample and limit its value
+ *
+ * Inputs:
+ * nMaxExcursion - noise value is limited to this value
+ * pnNoise - return new noise sample in this (not limited)
+ *
+ * Outputs:
+ * new limited noise value
+ *
+ * Side Effects:
+ * - *pnNoise noise value is updated
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_U16 ReverbCalculateNoise(EAS_U16 nMaxExcursion, EAS_I16 *pnNoise)
+{
+ // calculate new noise value
+ *pnNoise = (EAS_I16) (*pnNoise * 5 + 1);
+
+#if 0 // 1xxx, test
+ *pnNoise = 0;
+#endif // 1xxx, test
+
+ // return the limited noise value
+ return (nMaxExcursion & (*pnNoise));
+
+} /* end ReverbCalculateNoise */
+
+/*----------------------------------------------------------------------------
+ * ReverbCalculateSinCos
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Calculate a new sin and cosine value based on the given phase
+ *
+ * Inputs:
+ * nPhase - phase angle
+ * pnSin - input old value, output new value
+ * pnCos - input old value, output new value
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ * - *pnSin, *pnCos are updated
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT ReverbCalculateSinCos(EAS_I16 nPhase, EAS_I16 *pnSin, EAS_I16 *pnCos)
+{
+ EAS_I32 nTemp;
+ EAS_I32 nNetAngle;
+
+ // -1 <= nPhase < 1
+ // However, for the calculation, we need a value
+ // that ranges from -1/2 to +1/2, so divide the phase by 2
+ /*lint -e{702} shift for performance */
+ nNetAngle = nPhase >> 1;
+
+ /*
+ Implement the following
+ sin(x) = (2-4*c)*x^2 + c + x
+ cos(x) = (2-4*c)*x^2 + c - x
+
+ where c = 1/sqrt(2)
+ using the a0 + x*(a1 + x*a2) approach
+ */
+
+ /* limit the input "angle" to be between -0.5 and +0.5 */
+ if (nNetAngle > EG1_HALF)
+ {
+ nNetAngle = EG1_HALF;
+ }
+ else if (nNetAngle < EG1_MINUS_HALF)
+ {
+ nNetAngle = EG1_MINUS_HALF;
+ }
+
+ /* calculate sin */
+ nTemp = EG1_ONE + MULT_EG1_EG1(REVERB_PAN_G2, nNetAngle);
+ nTemp = REVERB_PAN_G0 + MULT_EG1_EG1(nTemp, nNetAngle);
+ *pnSin = (EAS_I16) SATURATE_EG1(nTemp);
+
+ /* calculate cos */
+ nTemp = -EG1_ONE + MULT_EG1_EG1(REVERB_PAN_G2, nNetAngle);
+ nTemp = REVERB_PAN_G0 + MULT_EG1_EG1(nTemp, nNetAngle);
+ *pnCos = (EAS_I16) SATURATE_EG1(nTemp);
+
+ return EAS_SUCCESS;
+} /* end ReverbCalculateSinCos */
+
+/*----------------------------------------------------------------------------
+ * Reverb
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * apply reverb to the given signal
+ *
+ * Inputs:
+ * nNu
+ * pnSin - input old value, output new value
+ * pnCos - input old value, output new value
+ *
+ * Outputs:
+ * number of samples actually reverberated
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT Reverb(S_REVERB_OBJECT *pReverbData, EAS_INT nNumSamplesToAdd, EAS_PCM *pOutputBuffer, EAS_PCM *pInputBuffer)
+{
+ EAS_I32 i;
+ EAS_I32 nDelayOut;
+ EAS_U16 nBase;
+
+ EAS_U32 nAddr;
+ EAS_I32 nTemp1;
+ EAS_I32 nTemp2;
+ EAS_I32 nApIn;
+ EAS_I32 nApOut;
+
+ EAS_I32 j;
+ EAS_I32 nEarlyOut;
+
+ EAS_I32 tempValue;
+
+
+ // get the base address
+ nBase = pReverbData->m_nBaseIndex;
+
+ for (i=0; i < nNumSamplesToAdd; i++)
+ {
+ // ********** Left Allpass - start
+ // left input = (left dry/4) + right feedback from previous period
+ /*lint -e{702} use shift for performance */
+ nApIn = ((*pInputBuffer++)>>2) + pReverbData->m_nRevOutFbkR;
+// nApIn = *pInputBuffer++; // 1xxx test and debug ap
+
+ // fetch allpass delay line out
+ //nAddr = CIRCULAR(nBase, psAp0->m_zApOut, REVERB_BUFFER_MASK);
+ nAddr = CIRCULAR(nBase, pReverbData->m_sAp0.m_zApOut, REVERB_BUFFER_MASK);
+ nDelayOut = pReverbData->m_nDelayLine[nAddr];
+
+ // calculate allpass feedforward; subtract the feedforward result
+ nTemp1 = MULT_EG1_EG1(nApIn, pReverbData->m_sAp0.m_nApGain);
+ nApOut = SATURATE(nDelayOut - nTemp1); // allpass output
+
+ // calculate allpass feedback; add the feedback result
+ nTemp1 = MULT_EG1_EG1(nApOut, pReverbData->m_sAp0.m_nApGain);
+ nTemp1 = SATURATE(nApIn + nTemp1);
+
+ // inject into allpass delay
+ nAddr = CIRCULAR(nBase, pReverbData->m_sAp0.m_zApIn, REVERB_BUFFER_MASK);
+ pReverbData->m_nDelayLine[nAddr] = (EAS_PCM) nTemp1;
+
+ // inject allpass output into delay line
+ nAddr = CIRCULAR(nBase, pReverbData->m_zD0In, REVERB_BUFFER_MASK);
+ pReverbData->m_nDelayLine[nAddr] = (EAS_PCM) nApOut;
+
+ // ********** Left Allpass - end
+
+ // ********** Right Allpass - start
+ // right input = (right dry/4) + left feedback from previous period
+ /*lint -e{702} use shift for performance */
+ nApIn = ((*pInputBuffer++)>>2) + pReverbData->m_nRevOutFbkL;
+// nApIn = *pInputBuffer++; // 1xxx test and debug ap
+
+ // fetch allpass delay line out
+ nAddr = CIRCULAR(nBase, pReverbData->m_sAp1.m_zApOut, REVERB_BUFFER_MASK);
+ nDelayOut = pReverbData->m_nDelayLine[nAddr];
+
+ // calculate allpass feedforward; subtract the feedforward result
+ nTemp1 = MULT_EG1_EG1(nApIn, pReverbData->m_sAp1.m_nApGain);
+ nApOut = SATURATE(nDelayOut - nTemp1); // allpass output
+
+ // calculate allpass feedback; add the feedback result
+ nTemp1 = MULT_EG1_EG1(nApOut, pReverbData->m_sAp1.m_nApGain);
+ nTemp1 = SATURATE(nApIn + nTemp1);
+
+ // inject into allpass delay
+ nAddr = CIRCULAR(nBase, pReverbData->m_sAp1.m_zApIn, REVERB_BUFFER_MASK);
+ pReverbData->m_nDelayLine[nAddr] = (EAS_PCM) nTemp1;
+
+ // inject allpass output into delay line
+ nAddr = CIRCULAR(nBase, pReverbData->m_zD1In, REVERB_BUFFER_MASK);
+ pReverbData->m_nDelayLine[nAddr] = (EAS_PCM) nApOut;
+
+ // ********** Right Allpass - end
+
+ // ********** D0 output - start
+ // fetch delay line self out
+ nAddr = CIRCULAR(nBase, pReverbData->m_zD0Self, REVERB_BUFFER_MASK);
+ nDelayOut = pReverbData->m_nDelayLine[nAddr];
+
+ // calculate delay line self out
+ nTemp1 = MULT_EG1_EG1(nDelayOut, pReverbData->m_nSin);
+
+ // fetch delay line cross out
+ nAddr = CIRCULAR(nBase, pReverbData->m_zD1Cross, REVERB_BUFFER_MASK);
+ nDelayOut = pReverbData->m_nDelayLine[nAddr];
+
+ // calculate delay line self out
+ nTemp2 = MULT_EG1_EG1(nDelayOut, pReverbData->m_nCos);
+
+ // calculate unfiltered delay out
+ nDelayOut = SATURATE(nTemp1 + nTemp2);
+
+ // calculate lowpass filter (mixer scale factor included in LPF feedforward)
+ nTemp1 = MULT_EG1_EG1(nDelayOut, pReverbData->m_nLpfFwd);
+
+ nTemp2 = MULT_EG1_EG1(pReverbData->m_zLpf0, pReverbData->m_nLpfFbk);
+
+ // calculate filtered delay out and simultaneously update LPF state variable
+ // filtered delay output is stored in m_zLpf0
+ pReverbData->m_zLpf0 = (EAS_PCM) SATURATE(nTemp1 + nTemp2);
+
+ // ********** D0 output - end
+
+ // ********** D1 output - start
+ // fetch delay line self out
+ nAddr = CIRCULAR(nBase, pReverbData->m_zD1Self, REVERB_BUFFER_MASK);
+ nDelayOut = pReverbData->m_nDelayLine[nAddr];
+
+ // calculate delay line self out
+ nTemp1 = MULT_EG1_EG1(nDelayOut, pReverbData->m_nSin);
+
+ // fetch delay line cross out
+ nAddr = CIRCULAR(nBase, pReverbData->m_zD0Cross, REVERB_BUFFER_MASK);
+ nDelayOut = pReverbData->m_nDelayLine[nAddr];
+
+ // calculate delay line self out
+ nTemp2 = MULT_EG1_EG1(nDelayOut, pReverbData->m_nCos);
+
+ // calculate unfiltered delay out
+ nDelayOut = SATURATE(nTemp1 + nTemp2);
+
+ // calculate lowpass filter (mixer scale factor included in LPF feedforward)
+ nTemp1 = MULT_EG1_EG1(nDelayOut, pReverbData->m_nLpfFwd);
+
+ nTemp2 = MULT_EG1_EG1(pReverbData->m_zLpf1, pReverbData->m_nLpfFbk);
+
+ // calculate filtered delay out and simultaneously update LPF state variable
+ // filtered delay output is stored in m_zLpf1
+ pReverbData->m_zLpf1 = (EAS_PCM)SATURATE(nTemp1 + nTemp2);
+
+ // ********** D1 output - end
+
+ // ********** mixer and feedback - start
+ // sum is fedback to right input (R + L)
+ pReverbData->m_nRevOutFbkL =
+ (EAS_PCM)SATURATE((EAS_I32)pReverbData->m_zLpf1 + (EAS_I32)pReverbData->m_zLpf0);
+
+ // difference is feedback to left input (R - L)
+ /*lint -e{685} lint complains that it can't saturate negative */
+ pReverbData->m_nRevOutFbkR =
+ (EAS_PCM)SATURATE((EAS_I32)pReverbData->m_zLpf1 - (EAS_I32)pReverbData->m_zLpf0);
+
+ // ********** mixer and feedback - end
+
+ // ********** start early reflection generator, left
+ //psEarly = &(pReverbData->m_sEarlyL);
+
+ nEarlyOut = 0;
+
+ for (j=0; j < REVERB_MAX_NUM_REFLECTIONS; j++)
+ {
+ // fetch delay line out
+ //nAddr = CIRCULAR(nBase, psEarly->m_zDelay[j], REVERB_BUFFER_MASK);
+ nAddr = CIRCULAR(nBase, pReverbData->m_sEarlyL.m_zDelay[j], REVERB_BUFFER_MASK);
+
+ nDelayOut = pReverbData->m_nDelayLine[nAddr];
+
+ // calculate reflection
+ //nTemp1 = MULT_EG1_EG1(nDelayOut, psEarly->m_nGain[j]);
+ nTemp1 = MULT_EG1_EG1(nDelayOut, pReverbData->m_sEarlyL.m_nGain[j]);
+
+ nEarlyOut = SATURATE(nEarlyOut + nTemp1);
+
+ } // end for (j=0; j < REVERB_MAX_NUM_REFLECTIONS; j++)
+
+ // apply lowpass to early reflections
+ //nTemp1 = MULT_EG1_EG1(nEarlyOut, psEarly->m_nLpfFwd);
+ nTemp1 = MULT_EG1_EG1(nEarlyOut, pReverbData->m_sEarlyL.m_nLpfFwd);
+
+ //nTemp2 = MULT_EG1_EG1(psEarly->m_zLpf, psEarly->m_nLpfFbk);
+ nTemp2 = MULT_EG1_EG1(pReverbData->m_sEarlyL.m_zLpf, pReverbData->m_sEarlyL.m_nLpfFbk);
+
+
+ // calculate filtered out and simultaneously update LPF state variable
+ // filtered output is stored in m_zLpf1
+ //psEarly->m_zLpf = SATURATE(nTemp1 + nTemp2);
+ pReverbData->m_sEarlyL.m_zLpf = (EAS_PCM) SATURATE(nTemp1 + nTemp2);
+
+ // combine filtered early and late reflections for output
+ //*pOutputBuffer++ = inL;
+ //tempValue = SATURATE(psEarly->m_zLpf + pReverbData->m_nRevOutFbkL);
+ tempValue = SATURATE((EAS_I32)pReverbData->m_sEarlyL.m_zLpf + (EAS_I32)pReverbData->m_nRevOutFbkL);
+ //scale reverb output by wet level
+ /*lint -e{701} use shift for performance */
+ tempValue = MULT_EG1_EG1(tempValue, (pReverbData->m_nWet<<1));
+ //sum with output buffer
+ tempValue += *pOutputBuffer;
+ *pOutputBuffer++ = (EAS_PCM)SATURATE(tempValue);
+
+ // ********** end early reflection generator, left
+
+ // ********** start early reflection generator, right
+ //psEarly = &(pReverbData->m_sEarlyR);
+
+ nEarlyOut = 0;
+
+ for (j=0; j < REVERB_MAX_NUM_REFLECTIONS; j++)
+ {
+ // fetch delay line out
+ nAddr = CIRCULAR(nBase, pReverbData->m_sEarlyR.m_zDelay[j], REVERB_BUFFER_MASK);
+ nDelayOut = pReverbData->m_nDelayLine[nAddr];
+
+ // calculate reflection
+ nTemp1 = MULT_EG1_EG1(nDelayOut, pReverbData->m_sEarlyR.m_nGain[j]);
+
+ nEarlyOut = SATURATE(nEarlyOut + nTemp1);
+
+ } // end for (j=0; j < REVERB_MAX_NUM_REFLECTIONS; j++)
+
+ // apply lowpass to early reflections
+ nTemp1 = MULT_EG1_EG1(nEarlyOut, pReverbData->m_sEarlyR.m_nLpfFwd);
+
+ nTemp2 = MULT_EG1_EG1(pReverbData->m_sEarlyR.m_zLpf, pReverbData->m_sEarlyR.m_nLpfFbk);
+
+ // calculate filtered out and simultaneously update LPF state variable
+ // filtered output is stored in m_zLpf1
+ pReverbData->m_sEarlyR.m_zLpf = (EAS_PCM)SATURATE(nTemp1 + nTemp2);
+
+ // combine filtered early and late reflections for output
+ //*pOutputBuffer++ = inR;
+ tempValue = SATURATE((EAS_I32)pReverbData->m_sEarlyR.m_zLpf + (EAS_I32)pReverbData->m_nRevOutFbkR);
+ //scale reverb output by wet level
+ /*lint -e{701} use shift for performance */
+ tempValue = MULT_EG1_EG1(tempValue, (pReverbData->m_nWet << 1));
+ //sum with output buffer
+ tempValue = tempValue + *pOutputBuffer;
+ *pOutputBuffer++ = (EAS_PCM)SATURATE(tempValue);
+
+ // ********** end early reflection generator, right
+
+ // decrement base addr for next sample period
+ nBase--;
+
+ pReverbData->m_nSin += pReverbData->m_nSinIncrement;
+ pReverbData->m_nCos += pReverbData->m_nCosIncrement;
+
+ } // end for (i=0; i < nNumSamplesToAdd; i++)
+
+ // store the most up to date version
+ pReverbData->m_nBaseIndex = nBase;
+
+ return EAS_SUCCESS;
+} /* end Reverb */
+
+
+
+/*----------------------------------------------------------------------------
+ * ReverbShutdown()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Initializes the Reverb effect.
+ *
+ * Inputs:
+ * pInstData - handle to instance data
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT ReverbShutdown (EAS_DATA_HANDLE pEASData, EAS_VOID_PTR pInstData)
+{
+ /* check Configuration Module for static memory allocation */
+ if (!pEASData->staticMemoryModel)
+ EAS_HWFree(pEASData->hwInstData, pInstData);
+ return EAS_SUCCESS;
+} /* end ReverbShutdown */
+
+/*----------------------------------------------------------------------------
+ * ReverbGetParam()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Get a Reverb parameter
+ *
+ * Inputs:
+ * pInstData - handle to instance data
+ * param - parameter index
+ * *pValue - pointer to variable to hold retrieved value
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT ReverbGetParam (EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue)
+{
+ S_REVERB_OBJECT *p;
+
+ p = (S_REVERB_OBJECT*) pInstData;
+
+ switch (param)
+ {
+ case EAS_PARAM_REVERB_BYPASS:
+ *pValue = (EAS_I32) p->m_bBypass;
+ break;
+ case EAS_PARAM_REVERB_PRESET:
+ *pValue = (EAS_I8) p->m_nCurrentRoom;
+ break;
+ case EAS_PARAM_REVERB_WET:
+ *pValue = p->m_nWet;
+ break;
+ case EAS_PARAM_REVERB_DRY:
+ *pValue = p->m_nDry;
+ break;
+ default:
+ return EAS_ERROR_INVALID_PARAMETER;
+ }
+ return EAS_SUCCESS;
+} /* end ReverbGetParam */
+
+
+/*----------------------------------------------------------------------------
+ * ReverbSetParam()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Set a Reverb parameter
+ *
+ * Inputs:
+ * pInstData - handle to instance data
+ * param - parameter index
+ * *pValue - new paramter value
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT ReverbSetParam (EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value)
+{
+ S_REVERB_OBJECT *p;
+
+ p = (S_REVERB_OBJECT*) pInstData;
+
+ switch (param)
+ {
+ case EAS_PARAM_REVERB_BYPASS:
+ p->m_bBypass = (EAS_BOOL) value;
+ break;
+ case EAS_PARAM_REVERB_PRESET:
+ if(value!=EAS_PARAM_REVERB_LARGE_HALL && value!=EAS_PARAM_REVERB_HALL &&
+ value!=EAS_PARAM_REVERB_CHAMBER && value!=EAS_PARAM_REVERB_ROOM)
+ return EAS_ERROR_INVALID_PARAMETER;
+ p->m_nNextRoom = (EAS_I16)value;
+ break;
+ case EAS_PARAM_REVERB_WET:
+ if(value>EAS_REVERB_WET_MAX || value<EAS_REVERB_WET_MIN)
+ return EAS_ERROR_INVALID_PARAMETER;
+ p->m_nWet = (EAS_I16)value;
+ break;
+ case EAS_PARAM_REVERB_DRY:
+ if(value>EAS_REVERB_DRY_MAX || value<EAS_REVERB_DRY_MIN)
+ return EAS_ERROR_INVALID_PARAMETER;
+ p->m_nDry = (EAS_I16)value;
+ break;
+ default:
+ return EAS_ERROR_INVALID_PARAMETER;
+ }
+ return EAS_SUCCESS;
+} /* end ReverbSetParam */
+
+
+/*----------------------------------------------------------------------------
+ * ReverbUpdateRoom
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Update the room's preset parameters as required
+ *
+ * Inputs:
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ * - reverb paramters (fbk, fwd, etc) will be changed
+ * - m_nCurrentRoom := m_nNextRoom
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT ReverbUpdateRoom(S_REVERB_OBJECT *pReverbData)
+{
+ EAS_INT temp;
+
+ S_REVERB_PRESET *pPreset = &pReverbData->m_sPreset.m_sPreset[pReverbData->m_nNextRoom];
+
+ pReverbData->m_nLpfFwd = pPreset->m_nLpfFwd;
+ pReverbData->m_nLpfFbk = pPreset->m_nLpfFbk;
+
+ pReverbData->m_nEarly = pPreset->m_nEarly;
+ pReverbData->m_nWet = pPreset->m_nWet;
+ pReverbData->m_nDry = pPreset->m_nDry;
+
+
+ pReverbData->m_nMaxExcursion = pPreset->m_nMaxExcursion;
+ //stored as time based, convert to sample based
+ temp = pPreset->m_nXfadeInterval;
+ /*lint -e{702} shift for performance */
+ temp = (temp * _OUTPUT_SAMPLE_RATE) >> 16;
+ pReverbData->m_nXfadeInterval = (EAS_U16) temp;
+ //gpsReverbObject->m_nXfadeInterval = pPreset->m_nXfadeInterval;
+ pReverbData->m_sAp0.m_nApGain = pPreset->m_nAp0_ApGain;
+ //stored as time based, convert to absolute sample value
+ temp = pPreset->m_nAp0_ApOut;
+ /*lint -e{702} shift for performance */
+ temp = (temp * _OUTPUT_SAMPLE_RATE) >> 16;
+ pReverbData->m_sAp0.m_zApOut = (EAS_U16) (pReverbData->m_sAp0.m_zApIn + temp);
+ //gpsReverbObject->m_sAp0.m_zApOut = pPreset->m_nAp0_ApOut;
+ pReverbData->m_sAp1.m_nApGain = pPreset->m_nAp1_ApGain;
+ //stored as time based, convert to absolute sample value
+ temp = pPreset->m_nAp1_ApOut;
+ /*lint -e{702} shift for performance */
+ temp = (temp * _OUTPUT_SAMPLE_RATE) >> 16;
+ pReverbData->m_sAp1.m_zApOut = (EAS_U16) (pReverbData->m_sAp1.m_zApIn + temp);
+ //gpsReverbObject->m_sAp1.m_zApOut = pPreset->m_nAp1_ApOut;
+
+ pReverbData->m_nCurrentRoom = pReverbData->m_nNextRoom;
+
+ return EAS_SUCCESS;
+
+} /* end ReverbUpdateRoom */
+
+
+/*----------------------------------------------------------------------------
+ * ReverbReadInPresets()
+ *----------------------------------------------------------------------------
+ * Purpose: sets global reverb preset bank to defaults
+ *
+ * Inputs:
+ *
+ * Outputs:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT ReverbReadInPresets(S_REVERB_OBJECT *pReverbData)
+{
+
+ int preset = 0;
+ int defaultPreset = 0;
+
+ //now init any remaining presets to defaults
+ for (defaultPreset = preset; defaultPreset < REVERB_MAX_ROOM_TYPE; defaultPreset++)
+ {
+ S_REVERB_PRESET *pPreset = &pReverbData->m_sPreset.m_sPreset[defaultPreset];
+ if (defaultPreset == 0 || defaultPreset > REVERB_MAX_ROOM_TYPE-1)
+ {
+ pPreset->m_nLpfFbk = 8307;
+ pPreset->m_nLpfFwd = 14768;
+ pPreset->m_nEarly = 0;
+ pPreset->m_nWet = 27690;
+ pPreset->m_nDry = 32767;
+ pPreset->m_nEarlyL_LpfFbk = 3692;
+ pPreset->m_nEarlyL_LpfFwd = 29075;
+ pPreset->m_nEarlyL_Delay0 = 922;
+ pPreset->m_nEarlyL_Gain0 = 22152;
+ pPreset->m_nEarlyL_Delay1 = 1462;
+ pPreset->m_nEarlyL_Gain1 = 17537;
+ pPreset->m_nEarlyL_Delay2 = 0;
+ pPreset->m_nEarlyL_Gain2 = 14768;
+ pPreset->m_nEarlyL_Delay3 = 1221;
+ pPreset->m_nEarlyL_Gain3 = 14307;
+ pPreset->m_nEarlyL_Delay4 = 0;
+ pPreset->m_nEarlyL_Gain4 = 13384;
+ pPreset->m_nEarlyR_Delay0 = 502;
+ pPreset->m_nEarlyR_Gain0 = 20306;
+ pPreset->m_nEarlyR_Delay1 = 1762;
+ pPreset->m_nEarlyR_Gain1 = 17537;
+ pPreset->m_nEarlyR_Delay2 = 0;
+ pPreset->m_nEarlyR_Gain2 = 14768;
+ pPreset->m_nEarlyR_Delay3 = 0;
+ pPreset->m_nEarlyR_Gain3 = 16153;
+ pPreset->m_nEarlyR_Delay4 = 0;
+ pPreset->m_nEarlyR_Gain4 = 13384;
+ pPreset->m_nMaxExcursion = 127;
+ pPreset->m_nXfadeInterval = 6388;
+ pPreset->m_nAp0_ApGain = 15691;
+ pPreset->m_nAp0_ApOut = 711;
+ pPreset->m_nAp1_ApGain = 17999;
+ pPreset->m_nAp1_ApOut = 1113;
+ pPreset->m_rfu4 = 0;
+ pPreset->m_rfu5 = 0;
+ pPreset->m_rfu6 = 0;
+ pPreset->m_rfu7 = 0;
+ pPreset->m_rfu8 = 0;
+ pPreset->m_rfu9 = 0;
+ pPreset->m_rfu10 = 0;
+ }
+ else if (defaultPreset == 1)
+ {
+ pPreset->m_nLpfFbk = 6461;
+ pPreset->m_nLpfFwd = 14307;
+ pPreset->m_nEarly = 0;
+ pPreset->m_nWet = 27690;
+ pPreset->m_nDry = 32767;
+ pPreset->m_nEarlyL_LpfFbk = 3692;
+ pPreset->m_nEarlyL_LpfFwd = 29075;
+ pPreset->m_nEarlyL_Delay0 = 922;
+ pPreset->m_nEarlyL_Gain0 = 22152;
+ pPreset->m_nEarlyL_Delay1 = 1462;
+ pPreset->m_nEarlyL_Gain1 = 17537;
+ pPreset->m_nEarlyL_Delay2 = 0;
+ pPreset->m_nEarlyL_Gain2 = 14768;
+ pPreset->m_nEarlyL_Delay3 = 1221;
+ pPreset->m_nEarlyL_Gain3 = 14307;
+ pPreset->m_nEarlyL_Delay4 = 0;
+ pPreset->m_nEarlyL_Gain4 = 13384;
+ pPreset->m_nEarlyR_Delay0 = 502;
+ pPreset->m_nEarlyR_Gain0 = 20306;
+ pPreset->m_nEarlyR_Delay1 = 1762;
+ pPreset->m_nEarlyR_Gain1 = 17537;
+ pPreset->m_nEarlyR_Delay2 = 0;
+ pPreset->m_nEarlyR_Gain2 = 14768;
+ pPreset->m_nEarlyR_Delay3 = 0;
+ pPreset->m_nEarlyR_Gain3 = 16153;
+ pPreset->m_nEarlyR_Delay4 = 0;
+ pPreset->m_nEarlyR_Gain4 = 13384;
+ pPreset->m_nMaxExcursion = 127;
+ pPreset->m_nXfadeInterval = 6391;
+ pPreset->m_nAp0_ApGain = 15230;
+ pPreset->m_nAp0_ApOut = 708;
+ pPreset->m_nAp1_ApGain = 9692;
+ pPreset->m_nAp1_ApOut = 1113;
+ pPreset->m_rfu4 = 0;
+ pPreset->m_rfu5 = 0;
+ pPreset->m_rfu6 = 0;
+ pPreset->m_rfu7 = 0;
+ pPreset->m_rfu8 = 0;
+ pPreset->m_rfu9 = 0;
+ pPreset->m_rfu10 = 0;
+ }
+ else if (defaultPreset == 2)
+ {
+ pPreset->m_nLpfFbk = 5077;
+ pPreset->m_nLpfFwd = 12922;
+ pPreset->m_nEarly = 0;
+ pPreset->m_nWet = 24460;
+ pPreset->m_nDry = 32767;
+ pPreset->m_nEarlyL_LpfFbk = 3692;
+ pPreset->m_nEarlyL_LpfFwd = 29075;
+ pPreset->m_nEarlyL_Delay0 = 922;
+ pPreset->m_nEarlyL_Gain0 = 22152;
+ pPreset->m_nEarlyL_Delay1 = 1462;
+ pPreset->m_nEarlyL_Gain1 = 17537;
+ pPreset->m_nEarlyL_Delay2 = 0;
+ pPreset->m_nEarlyL_Gain2 = 14768;
+ pPreset->m_nEarlyL_Delay3 = 1221;
+ pPreset->m_nEarlyL_Gain3 = 14307;
+ pPreset->m_nEarlyL_Delay4 = 0;
+ pPreset->m_nEarlyL_Gain4 = 13384;
+ pPreset->m_nEarlyR_Delay0 = 502;
+ pPreset->m_nEarlyR_Gain0 = 20306;
+ pPreset->m_nEarlyR_Delay1 = 1762;
+ pPreset->m_nEarlyR_Gain1 = 17537;
+ pPreset->m_nEarlyR_Delay2 = 0;
+ pPreset->m_nEarlyR_Gain2 = 14768;
+ pPreset->m_nEarlyR_Delay3 = 0;
+ pPreset->m_nEarlyR_Gain3 = 16153;
+ pPreset->m_nEarlyR_Delay4 = 0;
+ pPreset->m_nEarlyR_Gain4 = 13384;
+ pPreset->m_nMaxExcursion = 127;
+ pPreset->m_nXfadeInterval = 6449;
+ pPreset->m_nAp0_ApGain = 15691;
+ pPreset->m_nAp0_ApOut = 774;
+ pPreset->m_nAp1_ApGain = 15691;
+ pPreset->m_nAp1_ApOut = 1113;
+ pPreset->m_rfu4 = 0;
+ pPreset->m_rfu5 = 0;
+ pPreset->m_rfu6 = 0;
+ pPreset->m_rfu7 = 0;
+ pPreset->m_rfu8 = 0;
+ pPreset->m_rfu9 = 0;
+ pPreset->m_rfu10 = 0;
+ }
+ else if (defaultPreset == 3)
+ {
+ pPreset->m_nLpfFbk = 5077;
+ pPreset->m_nLpfFwd = 11076;
+ pPreset->m_nEarly = 0;
+ pPreset->m_nWet = 23075;
+ pPreset->m_nDry = 32767;
+ pPreset->m_nEarlyL_LpfFbk = 3692;
+ pPreset->m_nEarlyL_LpfFwd = 29075;
+ pPreset->m_nEarlyL_Delay0 = 922;
+ pPreset->m_nEarlyL_Gain0 = 22152;
+ pPreset->m_nEarlyL_Delay1 = 1462;
+ pPreset->m_nEarlyL_Gain1 = 17537;
+ pPreset->m_nEarlyL_Delay2 = 0;
+ pPreset->m_nEarlyL_Gain2 = 14768;
+ pPreset->m_nEarlyL_Delay3 = 1221;
+ pPreset->m_nEarlyL_Gain3 = 14307;
+ pPreset->m_nEarlyL_Delay4 = 0;
+ pPreset->m_nEarlyL_Gain4 = 13384;
+ pPreset->m_nEarlyR_Delay0 = 502;
+ pPreset->m_nEarlyR_Gain0 = 20306;
+ pPreset->m_nEarlyR_Delay1 = 1762;
+ pPreset->m_nEarlyR_Gain1 = 17537;
+ pPreset->m_nEarlyR_Delay2 = 0;
+ pPreset->m_nEarlyR_Gain2 = 14768;
+ pPreset->m_nEarlyR_Delay3 = 0;
+ pPreset->m_nEarlyR_Gain3 = 16153;
+ pPreset->m_nEarlyR_Delay4 = 0;
+ pPreset->m_nEarlyR_Gain4 = 13384;
+ pPreset->m_nMaxExcursion = 127;
+ pPreset->m_nXfadeInterval = 6470; //6483;
+ pPreset->m_nAp0_ApGain = 14768;
+ pPreset->m_nAp0_ApOut = 792;
+ pPreset->m_nAp1_ApGain = 15783;
+ pPreset->m_nAp1_ApOut = 1113;
+ pPreset->m_rfu4 = 0;
+ pPreset->m_rfu5 = 0;
+ pPreset->m_rfu6 = 0;
+ pPreset->m_rfu7 = 0;
+ pPreset->m_rfu8 = 0;
+ pPreset->m_rfu9 = 0;
+ pPreset->m_rfu10 = 0;
+
+ }
+ }
+
+ return EAS_SUCCESS;
+}
diff --git a/arm-wt-22k/lib_src/eas_reverbdata.c b/arm-wt-22k/lib_src/eas_reverbdata.c
index 5d48c1b..db34b48 100644
--- a/arm-wt-22k/lib_src/eas_reverbdata.c
+++ b/arm-wt-22k/lib_src/eas_reverbdata.c
@@ -1,13 +1,13 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_reverbdata.c
- *
- * Contents and purpose:
- * Contains the static data allocation for the Reverb effect
- *
- *
- * Copyright Sonic Network Inc. 2006
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_reverbdata.c
+ *
+ * Contents and purpose:
+ * Contains the static data allocation for the Reverb effect
+ *
+ *
+ * Copyright Sonic Network Inc. 2006
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,15 +20,15 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 550 $
- * $Date: 2007-02-02 09:37:03 -0800 (Fri, 02 Feb 2007) $
- *----------------------------------------------------------------------------
-*/
-
-#include "eas_reverbdata.h"
-
-S_REVERB_OBJECT eas_ReverbData;
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 550 $
+ * $Date: 2007-02-02 09:37:03 -0800 (Fri, 02 Feb 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+#include "eas_reverbdata.h"
+
+S_REVERB_OBJECT eas_ReverbData;
+
diff --git a/arm-wt-22k/lib_src/eas_reverbdata.h b/arm-wt-22k/lib_src/eas_reverbdata.h
index ef424da..926ea2e 100644
--- a/arm-wt-22k/lib_src/eas_reverbdata.h
+++ b/arm-wt-22k/lib_src/eas_reverbdata.h
@@ -1,13 +1,13 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_reverbdata.h
- *
- * Contents and purpose:
- * Contains the prototypes for the Reverb effect.
- *
- *
- * Copyright Sonic Network Inc. 2006
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_reverbdata.h
+ *
+ * Contents and purpose:
+ * Contains the prototypes for the Reverb effect.
+ *
+ *
+ * Copyright Sonic Network Inc. 2006
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,467 +20,467 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 499 $
- * $Date: 2006-12-11 16:07:20 -0800 (Mon, 11 Dec 2006) $
- *----------------------------------------------------------------------------
-*/
-
-#ifndef _EAS_REVERBDATA_H
-#define _EAS_REVERBDATA_H
-
-#include "eas_types.h"
-#include "eas_audioconst.h"
-
-/*------------------------------------
- * defines
- *------------------------------------
-*/
-
-/*
-CIRCULAR() calculates the array index using modulo arithmetic.
-The "trick" is that modulo arithmetic is simplified by masking
-the effective address where the mask is (2^n)-1. This only works
-if the buffer size is a power of two.
-*/
-#define CIRCULAR(base,offset,size) (EAS_U32)( \
- ( \
- ((EAS_I32)(base)) + ((EAS_I32)(offset)) \
- ) \
- & size \
- )
-
-/* reverb parameters are updated every 2^(REVERB_UPDATE_PERIOD_IN_BITS) samples */
-#if defined (_SAMPLE_RATE_8000)
-
-#define REVERB_UPDATE_PERIOD_IN_BITS 5
-#define REVERB_BUFFER_SIZE_IN_SAMPLES 2048
-
-#elif defined (_SAMPLE_RATE_16000)
-
-#define REVERB_UPDATE_PERIOD_IN_BITS 6
-#define REVERB_BUFFER_SIZE_IN_SAMPLES 4096
-
-#elif defined (_SAMPLE_RATE_22050)
-
-#define REVERB_UPDATE_PERIOD_IN_BITS 7
-#define REVERB_BUFFER_SIZE_IN_SAMPLES 4096
-
-#elif defined (_SAMPLE_RATE_32000)
-
-#define REVERB_UPDATE_PERIOD_IN_BITS 7
-#define REVERB_BUFFER_SIZE_IN_SAMPLES 8192
-
-#elif defined (_SAMPLE_RATE_44100)
-
-#define REVERB_UPDATE_PERIOD_IN_BITS 8
-#define REVERB_BUFFER_SIZE_IN_SAMPLES 8192
-
-#elif defined (_SAMPLE_RATE_48000)
-
-#define REVERB_UPDATE_PERIOD_IN_BITS 8
-#define REVERB_BUFFER_SIZE_IN_SAMPLES 8192
-
-#endif
-
-// Define a mask for circular addressing, so that array index
-// can wraparound and stay in array boundary of 0, 1, ..., (buffer size -1)
-// The buffer size MUST be a power of two
-#define REVERB_BUFFER_MASK (REVERB_BUFFER_SIZE_IN_SAMPLES -1)
-
-#define REVERB_MAX_ROOM_TYPE 4 // any room numbers larger than this are invalid
-#define REVERB_MAX_NUM_REFLECTIONS 5 // max num reflections per channel
-
-/* synth parameters are updated every SYNTH_UPDATE_PERIOD_IN_SAMPLES */
-#define REVERB_UPDATE_PERIOD_IN_SAMPLES (EAS_I32)(0x1L << REVERB_UPDATE_PERIOD_IN_BITS)
-
-/*
-calculate the update counter by bitwise ANDING with this value to
-generate a 2^n modulo value
-*/
-#define REVERB_MODULO_UPDATE_PERIOD_IN_SAMPLES (EAS_I32)(REVERB_UPDATE_PERIOD_IN_SAMPLES -1)
-
-/* synth parameters are updated every SYNTH_UPDATE_PERIOD_IN_SECONDS seconds */
-#define REVERB_UPDATE_PERIOD_IN_SECONDS (REVERB_UPDATE_PERIOD_IN_SAMPLES / _OUTPUT_SAMPLE_RATE)
-
-// xfade parameters
-#define REVERB_XFADE_PERIOD_IN_SECONDS (100.0 / 1000.0) // xfade once every this many seconds
-
-#define REVERB_XFADE_PERIOD_IN_SAMPLES (REVERB_XFADE_PERIOD_IN_SECONDS * _OUTPUT_SAMPLE_RATE)
-
-#define REVERB_XFADE_PHASE_INCREMENT (EAS_I16)(65536 / ((EAS_I16)REVERB_XFADE_PERIOD_IN_SAMPLES/(EAS_I16)REVERB_UPDATE_PERIOD_IN_SAMPLES))
-
-/**********/
-/* the entire synth uses various flags in a bit field */
-
-/* if flag is set, synth reset has been requested */
-#define REVERB_FLAG_RESET_IS_REQUESTED 0x01 /* bit 0 */
-#define MASK_REVERB_RESET_IS_REQUESTED 0x01
-#define MASK_REVERB_RESET_IS_NOT_REQUESTED (EAS_U32)(~MASK_REVERB_RESET_IS_REQUESTED)
-
-/*
-by default, we always want to update ALL channel parameters
-when we reset the synth (e.g., during GM ON)
-*/
-#define DEFAULT_REVERB_FLAGS 0x0
-
-/* coefficients for generating sin, cos */
-#define REVERB_PAN_G2 4294940151 /* -0.82842712474619 = 2 - 4/sqrt(2) */
-/*
-EAS_I32 nPanG1 = +1.0 for sin
-EAS_I32 nPanG1 = -1.0 for cos
-*/
-#define REVERB_PAN_G0 23170 /* 0.707106781186547 = 1/sqrt(2) */
-
-/*************************************************************/
-// define the input injection points
-#define GUARD 5 // safety guard of this many samples
-
-#define MAX_AP_TIME (double) (20.0/1000.0) // delay time in milliseconds
-#define MAX_DELAY_TIME (double) (65.0/1000.0) // delay time in milliseconds
-
-#define MAX_AP_SAMPLES (int)(((double) MAX_AP_TIME) * ((double) _OUTPUT_SAMPLE_RATE))
-#define MAX_DELAY_SAMPLES (int)(((double) MAX_DELAY_TIME) * ((double) _OUTPUT_SAMPLE_RATE))
-
-#define AP0_IN 0
-#define AP1_IN (AP0_IN + MAX_AP_SAMPLES + GUARD)
-#define DELAY0_IN (AP1_IN + MAX_AP_SAMPLES + GUARD)
-#define DELAY1_IN (DELAY0_IN + MAX_DELAY_SAMPLES + GUARD)
-
-// Define the max offsets for the end points of each section
-// i.e., we don't expect a given section's taps to go beyond
-// the following limits
-#define AP0_OUT (AP0_IN + MAX_AP_SAMPLES -1)
-#define AP1_OUT (AP1_IN + MAX_AP_SAMPLES -1)
-#define DELAY0_OUT (DELAY0_IN + MAX_DELAY_SAMPLES -1)
-#define DELAY1_OUT (DELAY1_IN + MAX_DELAY_SAMPLES -1)
-
-#define REVERB_DEFAULT_ROOM_NUMBER 1 // default preset number
-#define DEFAULT_AP0_LENGTH (int)(((double) (17.0/1000.0)) * ((double) _OUTPUT_SAMPLE_RATE))
-#define DEFAULT_AP0_GAIN 19400
-#define DEFAULT_AP1_LENGTH (int)(((double) (16.5/1000.0)) * ((double) _OUTPUT_SAMPLE_RATE))
-#define DEFAULT_AP1_GAIN -19400
-
-#define REVERB_DEFAULT_WET 32767
-#define REVERB_DEFAULT_DRY 0
-
-#define EAS_REVERB_WET_MAX 32767
-#define EAS_REVERB_WET_MIN 0
-#define EAS_REVERB_DRY_MAX 32767
-#define EAS_REVERB_DRY_MIN 0
-
-/* parameters for each allpass */
-typedef struct
-{
- EAS_U16 m_zApOut; // delay offset for ap out
-
- EAS_I16 m_nApGain; // gain for ap
-
- EAS_U16 m_zApIn; // delay offset for ap in
-
-} S_ALLPASS_OBJECT;
-
-
-/* parameters for each allpass */
-typedef struct
-{
- EAS_PCM m_zLpf; // actual state variable, not a length
-
- EAS_I16 m_nLpfFwd; // lpf forward gain
-
- EAS_I16 m_nLpfFbk; // lpf feedback gain
-
- EAS_U16 m_zDelay[REVERB_MAX_NUM_REFLECTIONS]; // delay offset for ap out
-
- EAS_I16 m_nGain[REVERB_MAX_NUM_REFLECTIONS]; // gain for ap
-
-} S_EARLY_REFLECTION_OBJECT;
-
-//demo
-typedef struct
-{
- EAS_I16 m_nLpfFbk;
- EAS_I16 m_nLpfFwd;
-
- EAS_I16 m_nEarly;
- EAS_I16 m_nWet;
- EAS_I16 m_nDry;
-
- EAS_I16 m_nEarlyL_LpfFbk;
- EAS_I16 m_nEarlyL_LpfFwd;
-
- EAS_I16 m_nEarlyL_Delay0; //8
- EAS_I16 m_nEarlyL_Gain0;
- EAS_I16 m_nEarlyL_Delay1;
- EAS_I16 m_nEarlyL_Gain1;
- EAS_I16 m_nEarlyL_Delay2;
- EAS_I16 m_nEarlyL_Gain2;
- EAS_I16 m_nEarlyL_Delay3;
- EAS_I16 m_nEarlyL_Gain3;
- EAS_I16 m_nEarlyL_Delay4;
- EAS_I16 m_nEarlyL_Gain4;
-
- EAS_I16 m_nEarlyR_Delay0; //18
- EAS_I16 m_nEarlyR_Gain0;
- EAS_I16 m_nEarlyR_Delay1;
- EAS_I16 m_nEarlyR_Gain1;
- EAS_I16 m_nEarlyR_Delay2;
- EAS_I16 m_nEarlyR_Gain2;
- EAS_I16 m_nEarlyR_Delay3;
- EAS_I16 m_nEarlyR_Gain3;
- EAS_I16 m_nEarlyR_Delay4;
- EAS_I16 m_nEarlyR_Gain4;
-
- EAS_U16 m_nMaxExcursion; //28
- EAS_I16 m_nXfadeInterval;
-
- EAS_I16 m_nAp0_ApGain; //30
- EAS_I16 m_nAp0_ApOut;
- EAS_I16 m_nAp1_ApGain;
- EAS_I16 m_nAp1_ApOut;
-
- EAS_I16 m_rfu4;
- EAS_I16 m_rfu5;
- EAS_I16 m_rfu6;
- EAS_I16 m_rfu7;
- EAS_I16 m_rfu8;
- EAS_I16 m_rfu9;
- EAS_I16 m_rfu10; //43
-
-} S_REVERB_PRESET;
-
-typedef struct
-{
- S_REVERB_PRESET m_sPreset[REVERB_MAX_ROOM_TYPE]; //array of presets
-
-} S_REVERB_PRESET_BANK;
-
-/* parameters for each reverb */
-typedef struct
-{
- /* controls entire reverb playback volume */
- /* to conserve memory, use the MSB and ignore the LSB */
- EAS_U8 m_nMasterVolume;
-
- /* update counter keeps track of when synth params need updating */
- /* only needs to be as large as REVERB_UPDATE_PERIOD_IN_SAMPLES */
- EAS_I16 m_nUpdateCounter;
-
- EAS_U16 m_nMinSamplesToAdd; /* ComputeReverb() generates this many samples */
-
- EAS_U8 m_nFlags; /* misc flags/bit fields */
-
- EAS_PCM *m_pOutputBuffer;
- EAS_PCM *m_pInputBuffer;
-
- EAS_U16 m_nNumSamplesInOutputBuffer;
- EAS_U16 m_nNumSamplesInInputBuffer;
-
- EAS_U16 m_nNumInputSamplesRead; // if m_nNumInputSamplesRead >= NumSamplesInInputBuffer
- // then get a new input buffer
- EAS_PCM *m_pNextInputSample;
-
- EAS_U16 m_nBaseIndex; // base index for circular buffer
-
- // reverb delay line offsets, allpass parameters, etc:
-
- EAS_PCM m_nRevOutFbkR; // combine feedback reverb right out with dry left in
-
- S_ALLPASS_OBJECT m_sAp0; // allpass 0 (left channel)
-
- EAS_U16 m_zD0In; // delay offset for delay line D0 in
-
- EAS_PCM m_nRevOutFbkL; // combine feedback reverb left out with dry right in
-
- S_ALLPASS_OBJECT m_sAp1; // allpass 1 (right channel)
-
- EAS_U16 m_zD1In; // delay offset for delay line D1 in
-
- // delay output taps, notice criss cross order
- EAS_U16 m_zD0Self; // self feeds forward d0 --> d0
-
- EAS_U16 m_zD1Cross; // cross feeds across d1 --> d0
-
- EAS_PCM m_zLpf0; // actual state variable, not a length
-
- EAS_U16 m_zD1Self; // self feeds forward d1 --> d1
-
- EAS_U16 m_zD0Cross; // cross feeds across d0 --> d1
-
- EAS_PCM m_zLpf1; // actual state variable, not a length
-
- EAS_I16 m_nSin; // gain for self taps
-
- EAS_I16 m_nCos; // gain for cross taps
-
- EAS_I16 m_nSinIncrement; // increment for gain
-
- EAS_I16 m_nCosIncrement; // increment for gain
-
- EAS_I16 m_nLpfFwd; // lpf forward gain (includes scaling for mixer)
-
- EAS_I16 m_nLpfFbk; // lpf feedback gain
-
- EAS_U16 m_nXfadeInterval; // update/xfade after this many samples
-
- EAS_U16 m_nXfadeCounter; // keep track of when to xfade
-
- EAS_I16 m_nPhase; // -1 <= m_nPhase < 1
- // but during sin,cos calculations
- // use m_nPhase/2
-
- EAS_I16 m_nPhaseIncrement; // add this to m_nPhase each frame
-
- EAS_I16 m_nNoise; // random noise sample
-
- EAS_U16 m_nMaxExcursion; // the taps can excurse +/- this amount
-
- EAS_BOOL m_bUseNoise; // if EAS_TRUE, use noise as input signal
-
- EAS_BOOL m_bBypass; // if EAS_TRUE, then bypass reverb and copy input to output
-
- EAS_I16 m_nCurrentRoom; // preset number for current room
-
- EAS_I16 m_nNextRoom; // preset number for next room
-
- EAS_I16 m_nWet; // gain for wet (processed) signal
-
- EAS_I16 m_nDry; // gain for dry (unprocessed) signal
-
- EAS_I16 m_nEarly; // gain for early (widen) signal
-
- S_EARLY_REFLECTION_OBJECT m_sEarlyL; // left channel early reflections
- S_EARLY_REFLECTION_OBJECT m_sEarlyR; // right channel early reflections
-
- EAS_PCM m_nDelayLine[REVERB_BUFFER_SIZE_IN_SAMPLES]; // one large delay line for all reverb elements
-
- S_REVERB_PRESET pPreset;
-
- S_REVERB_PRESET_BANK m_sPreset;
-
- //EAS_I8 preset;
-
-} S_REVERB_OBJECT;
-
-
-/*------------------------------------
- * prototypes
- *------------------------------------
-*/
-
-/*----------------------------------------------------------------------------
- * ReverbUpdateXfade
- *----------------------------------------------------------------------------
- * Purpose:
- * Update the xfade parameters as required
- *
- * Inputs:
- * nNumSamplesToAdd - number of samples to write to buffer
- *
- * Outputs:
- *
- *
- * Side Effects:
- * - xfade parameters will be changed
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT ReverbUpdateXfade(S_REVERB_OBJECT* pReverbData, EAS_INT nNumSamplesToAdd);
-
-/*----------------------------------------------------------------------------
- * ReverbCalculateNoise
- *----------------------------------------------------------------------------
- * Purpose:
- * Calculate a noise sample and limit its value
- *
- * Inputs:
- * nMaxExcursion - noise value is limited to this value
- * pnNoise - return new noise sample in this (not limited)
- *
- * Outputs:
- * new limited noise value
- *
- * Side Effects:
- * - *pnNoise noise value is updated
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_U16 ReverbCalculateNoise(EAS_U16 nMaxExcursion, EAS_I16 *pnNoise);
-
-/*----------------------------------------------------------------------------
- * ReverbCalculateSinCos
- *----------------------------------------------------------------------------
- * Purpose:
- * Calculate a new sin and cosine value based on the given phase
- *
- * Inputs:
- * nPhase - phase angle
- * pnSin - input old value, output new value
- * pnCos - input old value, output new value
- *
- * Outputs:
- *
- * Side Effects:
- * - *pnSin, *pnCos are updated
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT ReverbCalculateSinCos(EAS_I16 nPhase, EAS_I16 *pnSin, EAS_I16 *pnCos);
-
-/*----------------------------------------------------------------------------
- * Reverb
- *----------------------------------------------------------------------------
- * Purpose:
- * apply reverb to the given signal
- *
- * Inputs:
- * nNu
- * pnSin - input old value, output new value
- * pnCos - input old value, output new value
- *
- * Outputs:
- * number of samples actually reverberated
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT Reverb(S_REVERB_OBJECT* pReverbData, EAS_INT nNumSamplesToAdd, EAS_PCM *pOutputBuffer, EAS_PCM *pInputBuffer);
-
-/*----------------------------------------------------------------------------
- * ReverbReadInPresets()
- *----------------------------------------------------------------------------
- * Purpose: sets global reverb preset bank to defaults
- *
- * Inputs:
- *
- * Outputs:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT ReverbReadInPresets(S_REVERB_OBJECT* pReverbData);
-
-
-/*----------------------------------------------------------------------------
- * ReverbUpdateRoom
- *----------------------------------------------------------------------------
- * Purpose:
- * Update the room's preset parameters as required
- *
- * Inputs:
- *
- * Outputs:
- *
- *
- * Side Effects:
- * - reverb paramters (fbk, fwd, etc) will be changed
- * - m_nCurrentRoom := m_nNextRoom
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT ReverbUpdateRoom(S_REVERB_OBJECT* pReverbData);
-
-#endif /* #ifndef _EAS_REVERBDATA_H */
-
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 499 $
+ * $Date: 2006-12-11 16:07:20 -0800 (Mon, 11 Dec 2006) $
+ *----------------------------------------------------------------------------
+*/
+
+#ifndef _EAS_REVERBDATA_H
+#define _EAS_REVERBDATA_H
+
+#include "eas_types.h"
+#include "eas_audioconst.h"
+
+/*------------------------------------
+ * defines
+ *------------------------------------
+*/
+
+/*
+CIRCULAR() calculates the array index using modulo arithmetic.
+The "trick" is that modulo arithmetic is simplified by masking
+the effective address where the mask is (2^n)-1. This only works
+if the buffer size is a power of two.
+*/
+#define CIRCULAR(base,offset,size) (EAS_U32)( \
+ ( \
+ ((EAS_I32)(base)) + ((EAS_I32)(offset)) \
+ ) \
+ & size \
+ )
+
+/* reverb parameters are updated every 2^(REVERB_UPDATE_PERIOD_IN_BITS) samples */
+#if defined (_SAMPLE_RATE_8000)
+
+#define REVERB_UPDATE_PERIOD_IN_BITS 5
+#define REVERB_BUFFER_SIZE_IN_SAMPLES 2048
+
+#elif defined (_SAMPLE_RATE_16000)
+
+#define REVERB_UPDATE_PERIOD_IN_BITS 6
+#define REVERB_BUFFER_SIZE_IN_SAMPLES 4096
+
+#elif defined (_SAMPLE_RATE_22050)
+
+#define REVERB_UPDATE_PERIOD_IN_BITS 7
+#define REVERB_BUFFER_SIZE_IN_SAMPLES 4096
+
+#elif defined (_SAMPLE_RATE_32000)
+
+#define REVERB_UPDATE_PERIOD_IN_BITS 7
+#define REVERB_BUFFER_SIZE_IN_SAMPLES 8192
+
+#elif defined (_SAMPLE_RATE_44100)
+
+#define REVERB_UPDATE_PERIOD_IN_BITS 8
+#define REVERB_BUFFER_SIZE_IN_SAMPLES 8192
+
+#elif defined (_SAMPLE_RATE_48000)
+
+#define REVERB_UPDATE_PERIOD_IN_BITS 8
+#define REVERB_BUFFER_SIZE_IN_SAMPLES 8192
+
+#endif
+
+// Define a mask for circular addressing, so that array index
+// can wraparound and stay in array boundary of 0, 1, ..., (buffer size -1)
+// The buffer size MUST be a power of two
+#define REVERB_BUFFER_MASK (REVERB_BUFFER_SIZE_IN_SAMPLES -1)
+
+#define REVERB_MAX_ROOM_TYPE 4 // any room numbers larger than this are invalid
+#define REVERB_MAX_NUM_REFLECTIONS 5 // max num reflections per channel
+
+/* synth parameters are updated every SYNTH_UPDATE_PERIOD_IN_SAMPLES */
+#define REVERB_UPDATE_PERIOD_IN_SAMPLES (EAS_I32)(0x1L << REVERB_UPDATE_PERIOD_IN_BITS)
+
+/*
+calculate the update counter by bitwise ANDING with this value to
+generate a 2^n modulo value
+*/
+#define REVERB_MODULO_UPDATE_PERIOD_IN_SAMPLES (EAS_I32)(REVERB_UPDATE_PERIOD_IN_SAMPLES -1)
+
+/* synth parameters are updated every SYNTH_UPDATE_PERIOD_IN_SECONDS seconds */
+#define REVERB_UPDATE_PERIOD_IN_SECONDS (REVERB_UPDATE_PERIOD_IN_SAMPLES / _OUTPUT_SAMPLE_RATE)
+
+// xfade parameters
+#define REVERB_XFADE_PERIOD_IN_SECONDS (100.0 / 1000.0) // xfade once every this many seconds
+
+#define REVERB_XFADE_PERIOD_IN_SAMPLES (REVERB_XFADE_PERIOD_IN_SECONDS * _OUTPUT_SAMPLE_RATE)
+
+#define REVERB_XFADE_PHASE_INCREMENT (EAS_I16)(65536 / ((EAS_I16)REVERB_XFADE_PERIOD_IN_SAMPLES/(EAS_I16)REVERB_UPDATE_PERIOD_IN_SAMPLES))
+
+/**********/
+/* the entire synth uses various flags in a bit field */
+
+/* if flag is set, synth reset has been requested */
+#define REVERB_FLAG_RESET_IS_REQUESTED 0x01 /* bit 0 */
+#define MASK_REVERB_RESET_IS_REQUESTED 0x01
+#define MASK_REVERB_RESET_IS_NOT_REQUESTED (EAS_U32)(~MASK_REVERB_RESET_IS_REQUESTED)
+
+/*
+by default, we always want to update ALL channel parameters
+when we reset the synth (e.g., during GM ON)
+*/
+#define DEFAULT_REVERB_FLAGS 0x0
+
+/* coefficients for generating sin, cos */
+#define REVERB_PAN_G2 4294940151 /* -0.82842712474619 = 2 - 4/sqrt(2) */
+/*
+EAS_I32 nPanG1 = +1.0 for sin
+EAS_I32 nPanG1 = -1.0 for cos
+*/
+#define REVERB_PAN_G0 23170 /* 0.707106781186547 = 1/sqrt(2) */
+
+/*************************************************************/
+// define the input injection points
+#define GUARD 5 // safety guard of this many samples
+
+#define MAX_AP_TIME (double) (20.0/1000.0) // delay time in milliseconds
+#define MAX_DELAY_TIME (double) (65.0/1000.0) // delay time in milliseconds
+
+#define MAX_AP_SAMPLES (int)(((double) MAX_AP_TIME) * ((double) _OUTPUT_SAMPLE_RATE))
+#define MAX_DELAY_SAMPLES (int)(((double) MAX_DELAY_TIME) * ((double) _OUTPUT_SAMPLE_RATE))
+
+#define AP0_IN 0
+#define AP1_IN (AP0_IN + MAX_AP_SAMPLES + GUARD)
+#define DELAY0_IN (AP1_IN + MAX_AP_SAMPLES + GUARD)
+#define DELAY1_IN (DELAY0_IN + MAX_DELAY_SAMPLES + GUARD)
+
+// Define the max offsets for the end points of each section
+// i.e., we don't expect a given section's taps to go beyond
+// the following limits
+#define AP0_OUT (AP0_IN + MAX_AP_SAMPLES -1)
+#define AP1_OUT (AP1_IN + MAX_AP_SAMPLES -1)
+#define DELAY0_OUT (DELAY0_IN + MAX_DELAY_SAMPLES -1)
+#define DELAY1_OUT (DELAY1_IN + MAX_DELAY_SAMPLES -1)
+
+#define REVERB_DEFAULT_ROOM_NUMBER 1 // default preset number
+#define DEFAULT_AP0_LENGTH (int)(((double) (17.0/1000.0)) * ((double) _OUTPUT_SAMPLE_RATE))
+#define DEFAULT_AP0_GAIN 19400
+#define DEFAULT_AP1_LENGTH (int)(((double) (16.5/1000.0)) * ((double) _OUTPUT_SAMPLE_RATE))
+#define DEFAULT_AP1_GAIN -19400
+
+#define REVERB_DEFAULT_WET 32767
+#define REVERB_DEFAULT_DRY 0
+
+#define EAS_REVERB_WET_MAX 32767
+#define EAS_REVERB_WET_MIN 0
+#define EAS_REVERB_DRY_MAX 32767
+#define EAS_REVERB_DRY_MIN 0
+
+/* parameters for each allpass */
+typedef struct
+{
+ EAS_U16 m_zApOut; // delay offset for ap out
+
+ EAS_I16 m_nApGain; // gain for ap
+
+ EAS_U16 m_zApIn; // delay offset for ap in
+
+} S_ALLPASS_OBJECT;
+
+
+/* parameters for each allpass */
+typedef struct
+{
+ EAS_PCM m_zLpf; // actual state variable, not a length
+
+ EAS_I16 m_nLpfFwd; // lpf forward gain
+
+ EAS_I16 m_nLpfFbk; // lpf feedback gain
+
+ EAS_U16 m_zDelay[REVERB_MAX_NUM_REFLECTIONS]; // delay offset for ap out
+
+ EAS_I16 m_nGain[REVERB_MAX_NUM_REFLECTIONS]; // gain for ap
+
+} S_EARLY_REFLECTION_OBJECT;
+
+//demo
+typedef struct
+{
+ EAS_I16 m_nLpfFbk;
+ EAS_I16 m_nLpfFwd;
+
+ EAS_I16 m_nEarly;
+ EAS_I16 m_nWet;
+ EAS_I16 m_nDry;
+
+ EAS_I16 m_nEarlyL_LpfFbk;
+ EAS_I16 m_nEarlyL_LpfFwd;
+
+ EAS_I16 m_nEarlyL_Delay0; //8
+ EAS_I16 m_nEarlyL_Gain0;
+ EAS_I16 m_nEarlyL_Delay1;
+ EAS_I16 m_nEarlyL_Gain1;
+ EAS_I16 m_nEarlyL_Delay2;
+ EAS_I16 m_nEarlyL_Gain2;
+ EAS_I16 m_nEarlyL_Delay3;
+ EAS_I16 m_nEarlyL_Gain3;
+ EAS_I16 m_nEarlyL_Delay4;
+ EAS_I16 m_nEarlyL_Gain4;
+
+ EAS_I16 m_nEarlyR_Delay0; //18
+ EAS_I16 m_nEarlyR_Gain0;
+ EAS_I16 m_nEarlyR_Delay1;
+ EAS_I16 m_nEarlyR_Gain1;
+ EAS_I16 m_nEarlyR_Delay2;
+ EAS_I16 m_nEarlyR_Gain2;
+ EAS_I16 m_nEarlyR_Delay3;
+ EAS_I16 m_nEarlyR_Gain3;
+ EAS_I16 m_nEarlyR_Delay4;
+ EAS_I16 m_nEarlyR_Gain4;
+
+ EAS_U16 m_nMaxExcursion; //28
+ EAS_I16 m_nXfadeInterval;
+
+ EAS_I16 m_nAp0_ApGain; //30
+ EAS_I16 m_nAp0_ApOut;
+ EAS_I16 m_nAp1_ApGain;
+ EAS_I16 m_nAp1_ApOut;
+
+ EAS_I16 m_rfu4;
+ EAS_I16 m_rfu5;
+ EAS_I16 m_rfu6;
+ EAS_I16 m_rfu7;
+ EAS_I16 m_rfu8;
+ EAS_I16 m_rfu9;
+ EAS_I16 m_rfu10; //43
+
+} S_REVERB_PRESET;
+
+typedef struct
+{
+ S_REVERB_PRESET m_sPreset[REVERB_MAX_ROOM_TYPE]; //array of presets
+
+} S_REVERB_PRESET_BANK;
+
+/* parameters for each reverb */
+typedef struct
+{
+ /* controls entire reverb playback volume */
+ /* to conserve memory, use the MSB and ignore the LSB */
+ EAS_U8 m_nMasterVolume;
+
+ /* update counter keeps track of when synth params need updating */
+ /* only needs to be as large as REVERB_UPDATE_PERIOD_IN_SAMPLES */
+ EAS_I16 m_nUpdateCounter;
+
+ EAS_U16 m_nMinSamplesToAdd; /* ComputeReverb() generates this many samples */
+
+ EAS_U8 m_nFlags; /* misc flags/bit fields */
+
+ EAS_PCM *m_pOutputBuffer;
+ EAS_PCM *m_pInputBuffer;
+
+ EAS_U16 m_nNumSamplesInOutputBuffer;
+ EAS_U16 m_nNumSamplesInInputBuffer;
+
+ EAS_U16 m_nNumInputSamplesRead; // if m_nNumInputSamplesRead >= NumSamplesInInputBuffer
+ // then get a new input buffer
+ EAS_PCM *m_pNextInputSample;
+
+ EAS_U16 m_nBaseIndex; // base index for circular buffer
+
+ // reverb delay line offsets, allpass parameters, etc:
+
+ EAS_PCM m_nRevOutFbkR; // combine feedback reverb right out with dry left in
+
+ S_ALLPASS_OBJECT m_sAp0; // allpass 0 (left channel)
+
+ EAS_U16 m_zD0In; // delay offset for delay line D0 in
+
+ EAS_PCM m_nRevOutFbkL; // combine feedback reverb left out with dry right in
+
+ S_ALLPASS_OBJECT m_sAp1; // allpass 1 (right channel)
+
+ EAS_U16 m_zD1In; // delay offset for delay line D1 in
+
+ // delay output taps, notice criss cross order
+ EAS_U16 m_zD0Self; // self feeds forward d0 --> d0
+
+ EAS_U16 m_zD1Cross; // cross feeds across d1 --> d0
+
+ EAS_PCM m_zLpf0; // actual state variable, not a length
+
+ EAS_U16 m_zD1Self; // self feeds forward d1 --> d1
+
+ EAS_U16 m_zD0Cross; // cross feeds across d0 --> d1
+
+ EAS_PCM m_zLpf1; // actual state variable, not a length
+
+ EAS_I16 m_nSin; // gain for self taps
+
+ EAS_I16 m_nCos; // gain for cross taps
+
+ EAS_I16 m_nSinIncrement; // increment for gain
+
+ EAS_I16 m_nCosIncrement; // increment for gain
+
+ EAS_I16 m_nLpfFwd; // lpf forward gain (includes scaling for mixer)
+
+ EAS_I16 m_nLpfFbk; // lpf feedback gain
+
+ EAS_U16 m_nXfadeInterval; // update/xfade after this many samples
+
+ EAS_U16 m_nXfadeCounter; // keep track of when to xfade
+
+ EAS_I16 m_nPhase; // -1 <= m_nPhase < 1
+ // but during sin,cos calculations
+ // use m_nPhase/2
+
+ EAS_I16 m_nPhaseIncrement; // add this to m_nPhase each frame
+
+ EAS_I16 m_nNoise; // random noise sample
+
+ EAS_U16 m_nMaxExcursion; // the taps can excurse +/- this amount
+
+ EAS_BOOL m_bUseNoise; // if EAS_TRUE, use noise as input signal
+
+ EAS_BOOL m_bBypass; // if EAS_TRUE, then bypass reverb and copy input to output
+
+ EAS_I16 m_nCurrentRoom; // preset number for current room
+
+ EAS_I16 m_nNextRoom; // preset number for next room
+
+ EAS_I16 m_nWet; // gain for wet (processed) signal
+
+ EAS_I16 m_nDry; // gain for dry (unprocessed) signal
+
+ EAS_I16 m_nEarly; // gain for early (widen) signal
+
+ S_EARLY_REFLECTION_OBJECT m_sEarlyL; // left channel early reflections
+ S_EARLY_REFLECTION_OBJECT m_sEarlyR; // right channel early reflections
+
+ EAS_PCM m_nDelayLine[REVERB_BUFFER_SIZE_IN_SAMPLES]; // one large delay line for all reverb elements
+
+ S_REVERB_PRESET pPreset;
+
+ S_REVERB_PRESET_BANK m_sPreset;
+
+ //EAS_I8 preset;
+
+} S_REVERB_OBJECT;
+
+
+/*------------------------------------
+ * prototypes
+ *------------------------------------
+*/
+
+/*----------------------------------------------------------------------------
+ * ReverbUpdateXfade
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Update the xfade parameters as required
+ *
+ * Inputs:
+ * nNumSamplesToAdd - number of samples to write to buffer
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ * - xfade parameters will be changed
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT ReverbUpdateXfade(S_REVERB_OBJECT* pReverbData, EAS_INT nNumSamplesToAdd);
+
+/*----------------------------------------------------------------------------
+ * ReverbCalculateNoise
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Calculate a noise sample and limit its value
+ *
+ * Inputs:
+ * nMaxExcursion - noise value is limited to this value
+ * pnNoise - return new noise sample in this (not limited)
+ *
+ * Outputs:
+ * new limited noise value
+ *
+ * Side Effects:
+ * - *pnNoise noise value is updated
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_U16 ReverbCalculateNoise(EAS_U16 nMaxExcursion, EAS_I16 *pnNoise);
+
+/*----------------------------------------------------------------------------
+ * ReverbCalculateSinCos
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Calculate a new sin and cosine value based on the given phase
+ *
+ * Inputs:
+ * nPhase - phase angle
+ * pnSin - input old value, output new value
+ * pnCos - input old value, output new value
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ * - *pnSin, *pnCos are updated
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT ReverbCalculateSinCos(EAS_I16 nPhase, EAS_I16 *pnSin, EAS_I16 *pnCos);
+
+/*----------------------------------------------------------------------------
+ * Reverb
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * apply reverb to the given signal
+ *
+ * Inputs:
+ * nNu
+ * pnSin - input old value, output new value
+ * pnCos - input old value, output new value
+ *
+ * Outputs:
+ * number of samples actually reverberated
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT Reverb(S_REVERB_OBJECT* pReverbData, EAS_INT nNumSamplesToAdd, EAS_PCM *pOutputBuffer, EAS_PCM *pInputBuffer);
+
+/*----------------------------------------------------------------------------
+ * ReverbReadInPresets()
+ *----------------------------------------------------------------------------
+ * Purpose: sets global reverb preset bank to defaults
+ *
+ * Inputs:
+ *
+ * Outputs:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT ReverbReadInPresets(S_REVERB_OBJECT* pReverbData);
+
+
+/*----------------------------------------------------------------------------
+ * ReverbUpdateRoom
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Update the room's preset parameters as required
+ *
+ * Inputs:
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ * - reverb paramters (fbk, fwd, etc) will be changed
+ * - m_nCurrentRoom := m_nNextRoom
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT ReverbUpdateRoom(S_REVERB_OBJECT* pReverbData);
+
+#endif /* #ifndef _EAS_REVERBDATA_H */
+
+
diff --git a/arm-wt-22k/lib_src/eas_rtttl.c b/arm-wt-22k/lib_src/eas_rtttl.c
index 486ad60..d8253fb 100644
--- a/arm-wt-22k/lib_src/eas_rtttl.c
+++ b/arm-wt-22k/lib_src/eas_rtttl.c
@@ -1,12 +1,12 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_rtttl.c
- *
- * Contents and purpose:
- * RTTTL parser
- *
- * Copyright Sonic Network Inc. 2005
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_rtttl.c
+ *
+ * Contents and purpose:
+ * RTTTL parser
+ *
+ * Copyright Sonic Network Inc. 2005
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,1179 +19,1179 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 795 $
- * $Date: 2007-08-01 00:14:45 -0700 (Wed, 01 Aug 2007) $
- *----------------------------------------------------------------------------
-*/
-
-#include "eas_data.h"
-#include "eas_miditypes.h"
-#include "eas_parser.h"
-#include "eas_report.h"
-#include "eas_host.h"
-#include "eas_midi.h"
-#include "eas_config.h"
-#include "eas_vm_protos.h"
-#include "eas_rtttldata.h"
-#include "eas_ctype.h"
-
-/* increase gain for mono ringtones */
-#define RTTTL_GAIN_OFFSET 8
-
-/* maximum title length including colon separator */
-#define RTTTL_MAX_TITLE_LEN 32
-#define RTTTL_INFINITE_LOOP 15
-
-/* length of 32nd note in 1/256ths of a msec for 63 BPM tempo */
-#define DEFAULT_TICK_CONV 30476
-#define TICK_CONVERT 1920000
-
-/* default channel and program for RTTTL playback */
-#define RTTTL_CHANNEL 0
-#define RTTTL_PROGRAM 80
-#define RTTTL_VELOCITY 127
-
-/* note used for rest */
-#define RTTTL_REST 1
-
-/* multiplier for fixed point triplet conversion */
-#define TRIPLET_MULTIPLIER 683
-#define TRIPLET_SHIFT 10
-
-/* local prototypes */
-static EAS_RESULT RTTTL_CheckFileType (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle, EAS_VOID_PTR *ppHandle, EAS_I32 offset);
-static EAS_RESULT RTTTL_Prepare (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
-static EAS_RESULT RTTTL_Time (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_U32 *pTime);
-static EAS_RESULT RTTTL_Event (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_INT parserMode);
-static EAS_RESULT RTTTL_State (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_STATE *pState);
-static EAS_RESULT RTTTL_Close (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
-static EAS_RESULT RTTTL_Reset (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
-static EAS_RESULT RTTTL_Pause (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
-static EAS_RESULT RTTTL_Resume (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
-static EAS_RESULT RTTTL_SetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value);
-static EAS_RESULT RTTTL_GetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue);
-static EAS_RESULT RTTTL_GetStyle (EAS_HW_DATA_HANDLE hwInstData, S_RTTTL_DATA *pData);
-static EAS_RESULT RTTTL_GetDuration (EAS_HW_DATA_HANDLE hwInstData, S_RTTTL_DATA *pData, EAS_I8 *pDuration);
-static EAS_RESULT RTTTL_GetOctave (EAS_HW_DATA_HANDLE hwInstData, S_RTTTL_DATA *pData, EAS_U8 *pOctave);
-static EAS_RESULT RTTTL_GetTempo (EAS_HW_DATA_HANDLE hwInstData, S_RTTTL_DATA *pData);
-static EAS_RESULT RTTTL_GetNumber (EAS_HW_DATA_HANDLE hwInstData, S_RTTTL_DATA *pData, EAS_I32 *pValue);
-static EAS_RESULT RTTTL_ParseHeader (S_EAS_DATA *pEASData, S_RTTTL_DATA* pData, EAS_BOOL metaData);
-static EAS_RESULT RTTTL_GetNextChar (EAS_HW_DATA_HANDLE hwInstData, S_RTTTL_DATA *pData, EAS_I8 *pValue);
-static EAS_RESULT RTTTL_PeekNextChar (EAS_HW_DATA_HANDLE hwInstData, S_RTTTL_DATA *pData, EAS_I8 *pValue);
-
-/* inline functions */
-EAS_INLINE void RTTTL_PutBackChar (S_RTTTL_DATA *pData, EAS_I8 value) { pData->dataByte = value; }
-
-
-/* lookup table for note values */
-static const EAS_U8 noteTable[] = { 21, 23, 12, 14, 16, 17, 19, 23 };
-
-/*----------------------------------------------------------------------------
- *
- * EAS_RTTTL_Parser
- *
- * This structure contains the functional interface for the iMelody parser
- *----------------------------------------------------------------------------
-*/
-const S_FILE_PARSER_INTERFACE EAS_RTTTL_Parser =
-{
- RTTTL_CheckFileType,
- RTTTL_Prepare,
- RTTTL_Time,
- RTTTL_Event,
- RTTTL_State,
- RTTTL_Close,
- RTTTL_Reset,
- RTTTL_Pause,
- RTTTL_Resume,
- NULL,
- RTTTL_SetData,
- RTTTL_GetData,
- NULL
-};
-
-/*----------------------------------------------------------------------------
- * RTTTL_CheckFileType()
- *----------------------------------------------------------------------------
- * Purpose:
- * Check the file type to see if we can parse it
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT RTTTL_CheckFileType (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle, EAS_VOID_PTR *ppHandle, EAS_I32 offset)
-{
- S_RTTTL_DATA data;
- S_RTTTL_DATA *pData;
-
- /* see if we can parse the header */
- data.fileHandle = fileHandle;
- data.fileOffset = offset;
- *ppHandle= NULL;
- if (RTTTL_ParseHeader (pEASData, &data, EAS_FALSE) == EAS_SUCCESS)
- {
-
- /* check for static memory allocation */
- if (pEASData->staticMemoryModel)
- pData = EAS_CMEnumData(EAS_CM_RTTTL_DATA);
- else
- pData = EAS_HWMalloc(pEASData->hwInstData, sizeof(S_RTTTL_DATA));
- if (!pData)
- return EAS_ERROR_MALLOC_FAILED;
- EAS_HWMemSet(pData, 0, sizeof(S_RTTTL_DATA));
-
- /* return a pointer to the instance data */
- pData->fileHandle = fileHandle;
- pData->fileOffset = offset;
- pData->state = EAS_STATE_OPEN;
- *ppHandle = pData;
- }
-
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * RTTTL_Prepare()
- *----------------------------------------------------------------------------
- * Purpose:
- * Prepare to parse the file. Allocates instance data (or uses static allocation for
- * static memory model).
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT RTTTL_Prepare (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
-{
- S_RTTTL_DATA* pData;
- EAS_RESULT result;
-
- /* check for valid state */
- pData = (S_RTTTL_DATA*) pInstData;
- if (pData->state != EAS_STATE_OPEN)
- return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
-
- /* instantiate a synthesizer */
- if ((result = VMInitMIDI(pEASData, &pData->pSynth)) != EAS_SUCCESS)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "VMInitMIDI returned %d\n", result); */ }
- return result;
- }
-
- pData->state = EAS_STATE_ERROR;
- if ((result = RTTTL_ParseHeader (pEASData, pData, (EAS_BOOL) (pData->metadata.callback != NULL))) != EAS_SUCCESS)
- {
- /* if using dynamic memory, free it */
- if (!pEASData->staticMemoryModel)
- EAS_HWFree(pEASData->hwInstData, pData);
- return result;
- }
-
- pData->state = EAS_STATE_READY;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * RTTTL_Time()
- *----------------------------------------------------------------------------
- * Purpose:
- * Returns the time of the next event in msecs
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- * pTime - pointer to variable to hold time of next event (in msecs)
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, pEASData) reserved for future use */
-static EAS_RESULT RTTTL_Time (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_U32 *pTime)
-{
- S_RTTTL_DATA *pData;
-
- pData = (S_RTTTL_DATA*) pInstData;
-
- /* return time in milliseconds */
- /*lint -e{704} use shift instead of division */
- *pTime = pData->time >> 8;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * RTTTL_Event()
- *----------------------------------------------------------------------------
- * Purpose:
- * Parse the next event in the file
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT RTTTL_Event (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_INT parserMode)
-{
- S_RTTTL_DATA* pData;
- EAS_RESULT result;
- EAS_I32 ticks;
- EAS_I32 temp;
- EAS_I8 c;
- EAS_U8 note;
- EAS_U8 octave;
-
- pData = (S_RTTTL_DATA*) pInstData;
- if (pData->state >= EAS_STATE_OPEN)
- return EAS_SUCCESS;
-
- /* initialize MIDI channel when the track starts playing */
- if (pData->time == 0)
- {
- /* set program to square lead */
- VMProgramChange(pEASData->pVoiceMgr, pData->pSynth, RTTTL_CHANNEL, RTTTL_PROGRAM);
-
- /* set channel volume to max */
- VMControlChange(pEASData->pVoiceMgr, pData->pSynth, RTTTL_CHANNEL, 7, 127);
- }
-
- /* check for end of note */
- if (pData->note)
- {
- /* stop the note */
- VMStopNote(pEASData->pVoiceMgr, pData->pSynth, RTTTL_CHANNEL, pData->note, 0);
- pData->note = 0;
-
- /* check for rest between notes */
- if (pData->restTicks)
- {
- pData->time += pData->restTicks;
- pData->restTicks = 0;
- return EAS_SUCCESS;
- }
- }
-
- /* parse the next event */
- octave = pData->octave;
- note = 0;
- ticks = pData->duration * pData->tick;
- for (;;)
- {
-
- /* get next character */
- if ((result = RTTTL_GetNextChar(pEASData->hwInstData, pData, &c)) != EAS_SUCCESS)
- {
- if (result != EAS_EOF)
- return result;
-
- /* end of file, if no notes to process, check for looping */
- if (!note)
- {
- /* if no loop set state to stopping */
- if (pData->repeatCount == 0)
- {
- pData->state = EAS_STATE_STOPPING;
- VMReleaseAllVoices(pEASData->pVoiceMgr, pData->pSynth);
- return EAS_SUCCESS;
- }
-
- /* decrement loop count */
- if (pData->repeatCount != RTTTL_INFINITE_LOOP)
- pData->repeatCount--;
-
- /* if locating, ignore infinite loops */
- else if (parserMode != eParserModePlay)
- {
- pData->state = EAS_STATE_STOPPING;
- VMReleaseAllVoices(pEASData->pVoiceMgr, pData->pSynth);
- return EAS_SUCCESS;
- }
-
- /* loop back to start of notes */
- if ((result = EAS_HWFileSeek(pEASData->hwInstData, pData->fileHandle, pData->repeatOffset)) != EAS_SUCCESS)
- return result;
- continue;
- }
-
- /* still have a note to process */
- else
- c = ',';
- }
-
- /* bpm */
- if (c == 'b')
- {
- /* peek at next character */
- if ((result = RTTTL_PeekNextChar(pEASData->hwInstData, pData, &c)) != EAS_SUCCESS)
- return result;
-
- /* if a number, must be octave or tempo */
- if (IsDigit(c))
- {
- if ((result = RTTTL_GetNumber(pEASData->hwInstData, pData, &temp)) != EAS_SUCCESS)
- return result;
-
- /* check for octave first */
- if ((temp >= 4) && (temp <= 7))
- {
- octave = (EAS_U8) temp;
- }
-
- /* check for tempo */
- else if ((temp >= 25) && (temp <= 900))
- {
- pData->tick = TICK_CONVERT / (EAS_U32) temp;
- }
-
- /* don't know what it was */
- else
- return EAS_ERROR_FILE_FORMAT;
- }
-
- /* must be a note */
- else
- {
- note = noteTable[1];
- }
- }
-
- /* octave */
- else if (c == 'o')
- {
- if ((result = RTTTL_GetOctave(pEASData->hwInstData, pData, &pData->octave)) != EAS_SUCCESS)
- return result;
- }
-
- /* style */
- else if (c == 's')
- {
- if ((result = RTTTL_GetStyle(pEASData->hwInstData, pData)) != EAS_SUCCESS)
- return result;
- }
-
- /* duration or octave */
- else if (IsDigit(c))
- {
- RTTTL_PutBackChar(pData, c);
-
- /* duration comes before note */
- if (!note)
- {
- if ((result = RTTTL_GetDuration(pEASData->hwInstData, pData, &c)) != EAS_SUCCESS)
- return result;
- ticks = c * pData->tick;
- }
-
- /* octave comes after note */
- else
- {
- if ((result = RTTTL_GetOctave(pEASData->hwInstData, pData, &octave)) != EAS_SUCCESS)
- return result;
- }
- }
-
- /* note or rest */
- else if ((c >= 'a') && (c <= 'h'))
- {
- note = noteTable[c - 'a'];
- }
-
- else if (c == 'p')
- {
- note = RTTTL_REST;
- }
-
- /* dotted note */
- else if (c == '.')
- {
- /*lint -e{704} shift for performance */
- ticks += ticks >> 1;
- }
-
- /* accidental */
- else if (c == '#')
- {
- if (note)
- note++;
- }
-
- /* end of event */
- else if ((c == ',') && note)
- {
-
- /* handle note events */
- if (note != RTTTL_REST)
- {
-
- /* save note and start it */
- pData->note = note + octave;
- if (parserMode == eParserModePlay)
- VMStartNote(pEASData->pVoiceMgr, pData->pSynth, RTTTL_CHANNEL, pData->note, RTTTL_VELOCITY);
-
- /* determine note length */
- switch (pData->style)
- {
- /* natural */
- case 'n':
- /*lint -e{704} shift for performance */
- pData->restTicks = ticks >> 4;
- break;
- /* continuous */
-
- case 'c':
- pData->restTicks = 0;
- break;
-
- /* staccato */
- case 's':
- /*lint -e{704} shift for performance */
- pData->restTicks = ticks >> 1;
- break;
-
- default:
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "RTTTL_Event: Unexpected style type %c\n", pData->style); */ }
- break;
- }
-
- /* next event is at end of this note */
- pData->time += ticks - pData->restTicks;
- }
-
- /* rest */
- else
- pData->time += ticks;
-
- /* event found, return to caller */
- break;
- }
- }
-
- pData->state = EAS_STATE_PLAY;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * RTTTL_State()
- *----------------------------------------------------------------------------
- * Purpose:
- * Returns the current state of the stream
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- * pState - pointer to variable to store state
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, pEASData) reserved for future use */
-static EAS_RESULT RTTTL_State (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 *pState)
-{
- S_RTTTL_DATA* pData;
-
- /* establish pointer to instance data */
- pData = (S_RTTTL_DATA*) pInstData;
-
- /* if stopping, check to see if synth voices are active */
- if (pData->state == EAS_STATE_STOPPING)
- {
- if (VMActiveVoices(pData->pSynth) == 0)
- pData->state = EAS_STATE_STOPPED;
- }
-
- if (pData->state == EAS_STATE_PAUSING)
- {
- if (VMActiveVoices(pData->pSynth) == 0)
- pData->state = EAS_STATE_PAUSED;
- }
-
- /* return current state */
- *pState = pData->state;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * RTTTL_Close()
- *----------------------------------------------------------------------------
- * Purpose:
- * Close the file and clean up
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT RTTTL_Close (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
-{
- S_RTTTL_DATA* pData;
- EAS_RESULT result;
-
- pData = (S_RTTTL_DATA*) pInstData;
-
- /* close the file */
- if ((result = EAS_HWCloseFile(pEASData->hwInstData, pData->fileHandle)) != EAS_SUCCESS)
- return result;
-
- /* free the synth */
- if (pData->pSynth != NULL)
- VMMIDIShutdown(pEASData, pData->pSynth);
-
- /* if using dynamic memory, free it */
- if (!pEASData->staticMemoryModel)
- EAS_HWFree(pEASData->hwInstData, pData);
-
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * RTTTL_Reset()
- *----------------------------------------------------------------------------
- * Purpose:
- * Reset the sequencer. Used for locating backwards in the file.
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT RTTTL_Reset (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
-{
- S_RTTTL_DATA* pData;
- EAS_RESULT result;
-
- pData = (S_RTTTL_DATA*) pInstData;
-
- /* reset the synth */
- VMReset(pEASData->pVoiceMgr, pData->pSynth, EAS_TRUE);
-
- /* reset time to zero */
- pData->time = 0;
- pData->note = 0;
-
- /* reset file position and re-parse header */
- pData->state = EAS_STATE_ERROR;
- if ((result = EAS_HWFileSeek(pEASData->hwInstData, pData->fileHandle, pData->fileOffset)) != EAS_SUCCESS)
- return result;
- if ((result = RTTTL_ParseHeader (pEASData, pData, EAS_TRUE)) != EAS_SUCCESS)
- return result;
-
- pData->state = EAS_STATE_READY;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * RTTTL_Pause()
- *----------------------------------------------------------------------------
- * Purpose:
- * Pauses the sequencer. Mutes all voices and sets state to pause.
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT RTTTL_Pause (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
-{
- S_RTTTL_DATA *pData;
-
- /* can't pause a stopped stream */
- pData = (S_RTTTL_DATA*) pInstData;
- if (pData->state == EAS_STATE_STOPPED)
- return EAS_ERROR_ALREADY_STOPPED;
-
- /* mute the synthesizer */
- VMMuteAllVoices(pEASData->pVoiceMgr, pData->pSynth);
- pData->state = EAS_STATE_PAUSING;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * RTTTL_Resume()
- *----------------------------------------------------------------------------
- * Purpose:
- * Resume playing after a pause, sets state back to playing.
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, pEASData) reserved for future use */
-static EAS_RESULT RTTTL_Resume (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
-{
- S_RTTTL_DATA *pData;
-
- /* can't resume a stopped stream */
- pData = (S_RTTTL_DATA*) pInstData;
- if (pData->state == EAS_STATE_STOPPED)
- return EAS_ERROR_ALREADY_STOPPED;
-
- /* nothing to do but resume playback */
- pData->state = EAS_STATE_PLAY;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * RTTTL_SetData()
- *----------------------------------------------------------------------------
- * Purpose:
- * Return file type
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, pEASData) reserved for future use */
-static EAS_RESULT RTTTL_SetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value)
-{
- S_RTTTL_DATA *pData;
-
- pData = (S_RTTTL_DATA *) pInstData;
- switch (param)
- {
-
- /* set metadata callback */
- case PARSER_DATA_METADATA_CB:
- EAS_HWMemCpy(&pData->metadata, (void*) value, sizeof(S_METADATA_CB));
- break;
-
- default:
- return EAS_ERROR_INVALID_PARAMETER;
- }
-
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * RTTTL_GetData()
- *----------------------------------------------------------------------------
- * Purpose:
- * Return file type
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, pEASData) reserved for future use */
-static EAS_RESULT RTTTL_GetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue)
-{
- S_RTTTL_DATA *pData;
-
- pData = (S_RTTTL_DATA *) pInstData;
- switch (param)
- {
- /* return file type as RTTTL */
- case PARSER_DATA_FILE_TYPE:
- *pValue = EAS_FILE_RTTTL;
- break;
-
-#if 0
- /* set transposition */
- case PARSER_DATA_TRANSPOSITION:
- *pValue = pData->transposition;
- break;
-#endif
-
- case PARSER_DATA_SYNTH_HANDLE:
- *pValue = (EAS_I32) pData->pSynth;
- break;
-
- case PARSER_DATA_GAIN_OFFSET:
- *pValue = RTTTL_GAIN_OFFSET;
- break;
-
- default:
- return EAS_ERROR_INVALID_PARAMETER;
- }
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * RTTTL_GetStyle()
- *----------------------------------------------------------------------------
- * Purpose:
- *
- *
- * Inputs:
- *
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT RTTTL_GetStyle (EAS_HW_DATA_HANDLE hwInstData, S_RTTTL_DATA *pData)
-{
- EAS_RESULT result;
- EAS_I8 style;
-
- /* get style */
- if ((result = RTTTL_GetNextChar(hwInstData, pData, &style)) != EAS_SUCCESS)
- return result;
-
- if ((style != 's') && (style != 'n') && (style != 'c'))
- return EAS_ERROR_FILE_FORMAT;
-
- pData->style = style;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * RTTTL_GetDuration()
- *----------------------------------------------------------------------------
- * Purpose:
- *
- *
- * Inputs:
- *
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT RTTTL_GetDuration (EAS_HW_DATA_HANDLE hwInstData, S_RTTTL_DATA *pData, EAS_I8 *pDuration)
-{
- EAS_RESULT result;
- EAS_I32 duration;
- EAS_I8 temp;
-
- /* get the duration */
- if ((result = RTTTL_GetNumber(hwInstData, pData, &duration)) != EAS_SUCCESS)
- return result;
-
- if ((duration != 1) && (duration != 2) && (duration != 4) && (duration != 8) && (duration != 16) && (duration != 32))
- return EAS_ERROR_FILE_FORMAT;
-
- temp = 64;
- while (duration)
- {
- /*lint -e{704} shift for performance */
- duration = duration >> 1;
- /*lint -e{702} use shift for performance */
- temp = temp >> 1;
- }
-
- *pDuration = temp;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * RTTTL_GetOctave()
- *----------------------------------------------------------------------------
- * Purpose:
- *
- *
- * Inputs:
- *
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT RTTTL_GetOctave (EAS_HW_DATA_HANDLE hwInstData, S_RTTTL_DATA *pData, EAS_U8 *pOctave)
-{
- EAS_RESULT result;
- EAS_I32 octave;
-
- /* get the tempo */
- if ((result = RTTTL_GetNumber(hwInstData, pData, &octave)) != EAS_SUCCESS)
- return result;
-
- if ((octave < 4) || (octave > 7))
- return EAS_ERROR_FILE_FORMAT;
-
- *pOctave = (EAS_U8) (octave * 12);
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * RTTTL_GetTempo()
- *----------------------------------------------------------------------------
- * Purpose:
- *
- *
- * Inputs:
- *
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT RTTTL_GetTempo (EAS_HW_DATA_HANDLE hwInstData, S_RTTTL_DATA *pData)
-{
- EAS_RESULT result;
- EAS_I32 tempo;
-
- /* get the tempo */
- if ((result = RTTTL_GetNumber(hwInstData, pData, &tempo)) != EAS_SUCCESS)
- return result;
-
- if ((tempo < 25) || (tempo > 900))
- return EAS_ERROR_FILE_FORMAT;
-
- pData->tick = TICK_CONVERT / (EAS_U32) tempo;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * RTTTL_GetNumber()
- *----------------------------------------------------------------------------
- * Purpose:
- *
- *
- * Inputs:
- *
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT RTTTL_GetNumber (EAS_HW_DATA_HANDLE hwInstData, S_RTTTL_DATA *pData, EAS_I32 *pValue)
-{
- EAS_RESULT result;
- EAS_INT temp;
- EAS_I8 c;
-
- *pValue = -1;
- temp = 0;
- for (;;)
- {
- if ((result = RTTTL_PeekNextChar(hwInstData, pData, &c)) != EAS_SUCCESS)
- {
- if ((result == EAS_EOF) && (*pValue != -1))
- return EAS_SUCCESS;
- return result;
- }
-
- if (IsDigit(c))
- {
- pData->dataByte = 0;
- temp = temp * 10 + c - '0';
- *pValue = temp;
- }
- else
- return EAS_SUCCESS;
- }
-}
-
-/*----------------------------------------------------------------------------
- * RTTTL_ParseHeader()
- *----------------------------------------------------------------------------
- * Purpose:
- * Prepare to parse the file. Allocates instance data (or uses static allocation for
- * static memory model).
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT RTTTL_ParseHeader (S_EAS_DATA *pEASData, S_RTTTL_DATA* pData, EAS_BOOL metaData)
-{
- EAS_RESULT result;
- EAS_I32 i;
- EAS_I8 temp;
- EAS_I8 control;
-
- /* initialize some defaults */
- pData->time = 0;
- pData->tick = DEFAULT_TICK_CONV;
- pData->note = 0;
- pData->duration = 4;
- pData ->restTicks = 0;
- pData->octave = 60;
- pData->repeatOffset = -1;
- pData->repeatCount = 0;
- pData->style = 'n';
- pData->dataByte = 0;
-
- metaData = metaData && (pData->metadata.buffer != NULL) && (pData->metadata.callback != NULL);
-
- /* seek to start of data */
- if ((result = EAS_HWFileSeek(pEASData->hwInstData, pData->fileHandle, pData->fileOffset)) != EAS_SUCCESS)
- return result;
-
- /* zero the metadata buffer */
- if (metaData)
- EAS_HWMemSet(pData->metadata.buffer, 0, pData->metadata.bufferSize);
-
- /* read the title */
- for (i = 0; i < RTTTL_MAX_TITLE_LEN; i++)
- {
- if ((result = EAS_HWGetByte(pEASData->hwInstData, pData->fileHandle, &temp)) != EAS_SUCCESS)
- return result;
-
- if (temp == ':')
- break;
-
- /* pass along metadata */
- if (metaData)
- {
- if (i < (pData->metadata.bufferSize- 1))
- pData->metadata.buffer[i] = (char) temp;
- }
- }
-
- /* check for error in title */
- if (i == RTTTL_MAX_TITLE_LEN)
- return EAS_ERROR_FILE_FORMAT;
-
- /* pass along metadata */
- if (metaData)
- (*pData->metadata.callback)(EAS_METADATA_TITLE, pData->metadata.buffer, pData->metadata.pUserData);
-
- /* control fields */
- for (;;)
- {
-
- /* get control type */
- if ((result = RTTTL_GetNextChar(pEASData->hwInstData, pData, &control)) != EAS_SUCCESS)
- return result;
-
- /* next char should be equal sign */
- if ((result = RTTTL_GetNextChar(pEASData->hwInstData, pData, &temp)) != EAS_SUCCESS)
- return result;
- if (temp != '=')
- return EAS_ERROR_FILE_FORMAT;
-
- /* get the control value */
- switch (control)
- {
-
- /* bpm */
- case 'b':
- if ((result = RTTTL_GetTempo(pEASData->hwInstData, pData)) != EAS_SUCCESS)
- return result;
- break;
-
- /* duration */
- case 'd':
- if ((result = RTTTL_GetDuration(pEASData->hwInstData, pData, &temp)) != EAS_SUCCESS)
- return result;
- pData->duration = temp;
- break;
-
- /* loop */
- case 'l':
- if ((result = RTTTL_GetNumber(pEASData->hwInstData, pData, &i)) != EAS_SUCCESS)
- return result;
- if ((i < 0) || (i > 15))
- return EAS_ERROR_FILE_FORMAT;
- pData->repeatCount = (EAS_U8) i;
- break;
-
- /* octave */
- case 'o':
- if ((result = RTTTL_GetOctave(pEASData->hwInstData, pData, &pData->octave)) != EAS_SUCCESS)
- return result;
- break;
-
- /* get style */
- case 's':
- if ((result = RTTTL_GetStyle(pEASData->hwInstData, pData)) != EAS_SUCCESS)
- return result;
- break;
-
- /* unrecognized control */
- default:
- return EAS_ERROR_FILE_FORMAT;
- }
-
- /* next character should be comma or colon */
- if ((result = RTTTL_GetNextChar(pEASData->hwInstData, pData, &temp)) != EAS_SUCCESS)
- return result;
-
- /* check for end of control field */
- if (temp == ':')
- break;
-
- /* must be a comma */
- if (temp != ',')
- return EAS_ERROR_FILE_FORMAT;
- }
-
- /* should be at the start of the music block */
- if ((result = EAS_HWFilePos(pEASData->hwInstData, pData->fileHandle, &pData->repeatOffset)) != EAS_SUCCESS)
- return result;
-
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * RTTTL_GetNextChar()
- *----------------------------------------------------------------------------
- * Purpose:
- *
- *
- * Inputs:
- *
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT RTTTL_GetNextChar (EAS_HW_DATA_HANDLE hwInstData, S_RTTTL_DATA *pData, EAS_I8 *pValue)
-{
- EAS_RESULT result;
- EAS_I8 temp;
-
- *pValue = 0;
- for(;;)
- {
-
- /* check for character that has been put back */
- if (pData->dataByte)
- {
- temp = pData->dataByte;
- pData->dataByte = 0;
- }
- else
- {
- if ((result = EAS_HWGetByte(hwInstData, pData->fileHandle, &temp)) != EAS_SUCCESS)
- return result;
- }
-
- /* ignore white space */
- if (!IsSpace(temp))
- {
- *pValue = ToLower(temp);
- return EAS_SUCCESS;
- }
- }
-}
-
-/*----------------------------------------------------------------------------
- * RTTTL_PeekNextChar()
- *----------------------------------------------------------------------------
- * Purpose:
- *
- *
- * Inputs:
- *
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT RTTTL_PeekNextChar (EAS_HW_DATA_HANDLE hwInstData, S_RTTTL_DATA *pData, EAS_I8 *pValue)
-{
- EAS_RESULT result;
- EAS_I8 temp;
-
- *pValue = 0;
- for(;;)
- {
-
- /* read a character from the file, if necessary */
- if (!pData->dataByte)
- {
- if ((result = EAS_HWGetByte(hwInstData, pData->fileHandle, &pData->dataByte)) != EAS_SUCCESS)
- return result;
-
- }
- temp = pData->dataByte;
-
- /* ignore white space */
- if (!IsSpace(temp))
- {
- *pValue = ToLower(temp);
- return EAS_SUCCESS;
- }
- pData->dataByte = 0;
- }
-}
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 795 $
+ * $Date: 2007-08-01 00:14:45 -0700 (Wed, 01 Aug 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+#include "eas_data.h"
+#include "eas_miditypes.h"
+#include "eas_parser.h"
+#include "eas_report.h"
+#include "eas_host.h"
+#include "eas_midi.h"
+#include "eas_config.h"
+#include "eas_vm_protos.h"
+#include "eas_rtttldata.h"
+#include "eas_ctype.h"
+
+/* increase gain for mono ringtones */
+#define RTTTL_GAIN_OFFSET 8
+
+/* maximum title length including colon separator */
+#define RTTTL_MAX_TITLE_LEN 32
+#define RTTTL_INFINITE_LOOP 15
+
+/* length of 32nd note in 1/256ths of a msec for 63 BPM tempo */
+#define DEFAULT_TICK_CONV 30476
+#define TICK_CONVERT 1920000
+
+/* default channel and program for RTTTL playback */
+#define RTTTL_CHANNEL 0
+#define RTTTL_PROGRAM 80
+#define RTTTL_VELOCITY 127
+
+/* note used for rest */
+#define RTTTL_REST 1
+
+/* multiplier for fixed point triplet conversion */
+#define TRIPLET_MULTIPLIER 683
+#define TRIPLET_SHIFT 10
+
+/* local prototypes */
+static EAS_RESULT RTTTL_CheckFileType (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle, EAS_VOID_PTR *ppHandle, EAS_I32 offset);
+static EAS_RESULT RTTTL_Prepare (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
+static EAS_RESULT RTTTL_Time (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_U32 *pTime);
+static EAS_RESULT RTTTL_Event (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_INT parserMode);
+static EAS_RESULT RTTTL_State (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_STATE *pState);
+static EAS_RESULT RTTTL_Close (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
+static EAS_RESULT RTTTL_Reset (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
+static EAS_RESULT RTTTL_Pause (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
+static EAS_RESULT RTTTL_Resume (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
+static EAS_RESULT RTTTL_SetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value);
+static EAS_RESULT RTTTL_GetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue);
+static EAS_RESULT RTTTL_GetStyle (EAS_HW_DATA_HANDLE hwInstData, S_RTTTL_DATA *pData);
+static EAS_RESULT RTTTL_GetDuration (EAS_HW_DATA_HANDLE hwInstData, S_RTTTL_DATA *pData, EAS_I8 *pDuration);
+static EAS_RESULT RTTTL_GetOctave (EAS_HW_DATA_HANDLE hwInstData, S_RTTTL_DATA *pData, EAS_U8 *pOctave);
+static EAS_RESULT RTTTL_GetTempo (EAS_HW_DATA_HANDLE hwInstData, S_RTTTL_DATA *pData);
+static EAS_RESULT RTTTL_GetNumber (EAS_HW_DATA_HANDLE hwInstData, S_RTTTL_DATA *pData, EAS_I32 *pValue);
+static EAS_RESULT RTTTL_ParseHeader (S_EAS_DATA *pEASData, S_RTTTL_DATA* pData, EAS_BOOL metaData);
+static EAS_RESULT RTTTL_GetNextChar (EAS_HW_DATA_HANDLE hwInstData, S_RTTTL_DATA *pData, EAS_I8 *pValue);
+static EAS_RESULT RTTTL_PeekNextChar (EAS_HW_DATA_HANDLE hwInstData, S_RTTTL_DATA *pData, EAS_I8 *pValue);
+
+/* inline functions */
+EAS_INLINE void RTTTL_PutBackChar (S_RTTTL_DATA *pData, EAS_I8 value) { pData->dataByte = value; }
+
+
+/* lookup table for note values */
+static const EAS_U8 noteTable[] = { 21, 23, 12, 14, 16, 17, 19, 23 };
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_RTTTL_Parser
+ *
+ * This structure contains the functional interface for the iMelody parser
+ *----------------------------------------------------------------------------
+*/
+const S_FILE_PARSER_INTERFACE EAS_RTTTL_Parser =
+{
+ RTTTL_CheckFileType,
+ RTTTL_Prepare,
+ RTTTL_Time,
+ RTTTL_Event,
+ RTTTL_State,
+ RTTTL_Close,
+ RTTTL_Reset,
+ RTTTL_Pause,
+ RTTTL_Resume,
+ NULL,
+ RTTTL_SetData,
+ RTTTL_GetData,
+ NULL
+};
+
+/*----------------------------------------------------------------------------
+ * RTTTL_CheckFileType()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Check the file type to see if we can parse it
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT RTTTL_CheckFileType (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle, EAS_VOID_PTR *ppHandle, EAS_I32 offset)
+{
+ S_RTTTL_DATA data;
+ S_RTTTL_DATA *pData;
+
+ /* see if we can parse the header */
+ data.fileHandle = fileHandle;
+ data.fileOffset = offset;
+ *ppHandle= NULL;
+ if (RTTTL_ParseHeader (pEASData, &data, EAS_FALSE) == EAS_SUCCESS)
+ {
+
+ /* check for static memory allocation */
+ if (pEASData->staticMemoryModel)
+ pData = EAS_CMEnumData(EAS_CM_RTTTL_DATA);
+ else
+ pData = EAS_HWMalloc(pEASData->hwInstData, sizeof(S_RTTTL_DATA));
+ if (!pData)
+ return EAS_ERROR_MALLOC_FAILED;
+ EAS_HWMemSet(pData, 0, sizeof(S_RTTTL_DATA));
+
+ /* return a pointer to the instance data */
+ pData->fileHandle = fileHandle;
+ pData->fileOffset = offset;
+ pData->state = EAS_STATE_OPEN;
+ *ppHandle = pData;
+ }
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * RTTTL_Prepare()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Prepare to parse the file. Allocates instance data (or uses static allocation for
+ * static memory model).
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT RTTTL_Prepare (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
+{
+ S_RTTTL_DATA* pData;
+ EAS_RESULT result;
+
+ /* check for valid state */
+ pData = (S_RTTTL_DATA*) pInstData;
+ if (pData->state != EAS_STATE_OPEN)
+ return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
+
+ /* instantiate a synthesizer */
+ if ((result = VMInitMIDI(pEASData, &pData->pSynth)) != EAS_SUCCESS)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "VMInitMIDI returned %d\n", result); */ }
+ return result;
+ }
+
+ pData->state = EAS_STATE_ERROR;
+ if ((result = RTTTL_ParseHeader (pEASData, pData, (EAS_BOOL) (pData->metadata.callback != NULL))) != EAS_SUCCESS)
+ {
+ /* if using dynamic memory, free it */
+ if (!pEASData->staticMemoryModel)
+ EAS_HWFree(pEASData->hwInstData, pData);
+ return result;
+ }
+
+ pData->state = EAS_STATE_READY;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * RTTTL_Time()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Returns the time of the next event in msecs
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ * pTime - pointer to variable to hold time of next event (in msecs)
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pEASData) reserved for future use */
+static EAS_RESULT RTTTL_Time (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_U32 *pTime)
+{
+ S_RTTTL_DATA *pData;
+
+ pData = (S_RTTTL_DATA*) pInstData;
+
+ /* return time in milliseconds */
+ /*lint -e{704} use shift instead of division */
+ *pTime = pData->time >> 8;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * RTTTL_Event()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Parse the next event in the file
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT RTTTL_Event (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_INT parserMode)
+{
+ S_RTTTL_DATA* pData;
+ EAS_RESULT result;
+ EAS_I32 ticks;
+ EAS_I32 temp;
+ EAS_I8 c;
+ EAS_U8 note;
+ EAS_U8 octave;
+
+ pData = (S_RTTTL_DATA*) pInstData;
+ if (pData->state >= EAS_STATE_OPEN)
+ return EAS_SUCCESS;
+
+ /* initialize MIDI channel when the track starts playing */
+ if (pData->time == 0)
+ {
+ /* set program to square lead */
+ VMProgramChange(pEASData->pVoiceMgr, pData->pSynth, RTTTL_CHANNEL, RTTTL_PROGRAM);
+
+ /* set channel volume to max */
+ VMControlChange(pEASData->pVoiceMgr, pData->pSynth, RTTTL_CHANNEL, 7, 127);
+ }
+
+ /* check for end of note */
+ if (pData->note)
+ {
+ /* stop the note */
+ VMStopNote(pEASData->pVoiceMgr, pData->pSynth, RTTTL_CHANNEL, pData->note, 0);
+ pData->note = 0;
+
+ /* check for rest between notes */
+ if (pData->restTicks)
+ {
+ pData->time += pData->restTicks;
+ pData->restTicks = 0;
+ return EAS_SUCCESS;
+ }
+ }
+
+ /* parse the next event */
+ octave = pData->octave;
+ note = 0;
+ ticks = pData->duration * pData->tick;
+ for (;;)
+ {
+
+ /* get next character */
+ if ((result = RTTTL_GetNextChar(pEASData->hwInstData, pData, &c)) != EAS_SUCCESS)
+ {
+ if (result != EAS_EOF)
+ return result;
+
+ /* end of file, if no notes to process, check for looping */
+ if (!note)
+ {
+ /* if no loop set state to stopping */
+ if (pData->repeatCount == 0)
+ {
+ pData->state = EAS_STATE_STOPPING;
+ VMReleaseAllVoices(pEASData->pVoiceMgr, pData->pSynth);
+ return EAS_SUCCESS;
+ }
+
+ /* decrement loop count */
+ if (pData->repeatCount != RTTTL_INFINITE_LOOP)
+ pData->repeatCount--;
+
+ /* if locating, ignore infinite loops */
+ else if (parserMode != eParserModePlay)
+ {
+ pData->state = EAS_STATE_STOPPING;
+ VMReleaseAllVoices(pEASData->pVoiceMgr, pData->pSynth);
+ return EAS_SUCCESS;
+ }
+
+ /* loop back to start of notes */
+ if ((result = EAS_HWFileSeek(pEASData->hwInstData, pData->fileHandle, pData->repeatOffset)) != EAS_SUCCESS)
+ return result;
+ continue;
+ }
+
+ /* still have a note to process */
+ else
+ c = ',';
+ }
+
+ /* bpm */
+ if (c == 'b')
+ {
+ /* peek at next character */
+ if ((result = RTTTL_PeekNextChar(pEASData->hwInstData, pData, &c)) != EAS_SUCCESS)
+ return result;
+
+ /* if a number, must be octave or tempo */
+ if (IsDigit(c))
+ {
+ if ((result = RTTTL_GetNumber(pEASData->hwInstData, pData, &temp)) != EAS_SUCCESS)
+ return result;
+
+ /* check for octave first */
+ if ((temp >= 4) && (temp <= 7))
+ {
+ octave = (EAS_U8) temp;
+ }
+
+ /* check for tempo */
+ else if ((temp >= 25) && (temp <= 900))
+ {
+ pData->tick = TICK_CONVERT / (EAS_U32) temp;
+ }
+
+ /* don't know what it was */
+ else
+ return EAS_ERROR_FILE_FORMAT;
+ }
+
+ /* must be a note */
+ else
+ {
+ note = noteTable[1];
+ }
+ }
+
+ /* octave */
+ else if (c == 'o')
+ {
+ if ((result = RTTTL_GetOctave(pEASData->hwInstData, pData, &pData->octave)) != EAS_SUCCESS)
+ return result;
+ }
+
+ /* style */
+ else if (c == 's')
+ {
+ if ((result = RTTTL_GetStyle(pEASData->hwInstData, pData)) != EAS_SUCCESS)
+ return result;
+ }
+
+ /* duration or octave */
+ else if (IsDigit(c))
+ {
+ RTTTL_PutBackChar(pData, c);
+
+ /* duration comes before note */
+ if (!note)
+ {
+ if ((result = RTTTL_GetDuration(pEASData->hwInstData, pData, &c)) != EAS_SUCCESS)
+ return result;
+ ticks = c * pData->tick;
+ }
+
+ /* octave comes after note */
+ else
+ {
+ if ((result = RTTTL_GetOctave(pEASData->hwInstData, pData, &octave)) != EAS_SUCCESS)
+ return result;
+ }
+ }
+
+ /* note or rest */
+ else if ((c >= 'a') && (c <= 'h'))
+ {
+ note = noteTable[c - 'a'];
+ }
+
+ else if (c == 'p')
+ {
+ note = RTTTL_REST;
+ }
+
+ /* dotted note */
+ else if (c == '.')
+ {
+ /*lint -e{704} shift for performance */
+ ticks += ticks >> 1;
+ }
+
+ /* accidental */
+ else if (c == '#')
+ {
+ if (note)
+ note++;
+ }
+
+ /* end of event */
+ else if ((c == ',') && note)
+ {
+
+ /* handle note events */
+ if (note != RTTTL_REST)
+ {
+
+ /* save note and start it */
+ pData->note = note + octave;
+ if (parserMode == eParserModePlay)
+ VMStartNote(pEASData->pVoiceMgr, pData->pSynth, RTTTL_CHANNEL, pData->note, RTTTL_VELOCITY);
+
+ /* determine note length */
+ switch (pData->style)
+ {
+ /* natural */
+ case 'n':
+ /*lint -e{704} shift for performance */
+ pData->restTicks = ticks >> 4;
+ break;
+ /* continuous */
+
+ case 'c':
+ pData->restTicks = 0;
+ break;
+
+ /* staccato */
+ case 's':
+ /*lint -e{704} shift for performance */
+ pData->restTicks = ticks >> 1;
+ break;
+
+ default:
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "RTTTL_Event: Unexpected style type %c\n", pData->style); */ }
+ break;
+ }
+
+ /* next event is at end of this note */
+ pData->time += ticks - pData->restTicks;
+ }
+
+ /* rest */
+ else
+ pData->time += ticks;
+
+ /* event found, return to caller */
+ break;
+ }
+ }
+
+ pData->state = EAS_STATE_PLAY;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * RTTTL_State()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Returns the current state of the stream
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ * pState - pointer to variable to store state
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pEASData) reserved for future use */
+static EAS_RESULT RTTTL_State (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 *pState)
+{
+ S_RTTTL_DATA* pData;
+
+ /* establish pointer to instance data */
+ pData = (S_RTTTL_DATA*) pInstData;
+
+ /* if stopping, check to see if synth voices are active */
+ if (pData->state == EAS_STATE_STOPPING)
+ {
+ if (VMActiveVoices(pData->pSynth) == 0)
+ pData->state = EAS_STATE_STOPPED;
+ }
+
+ if (pData->state == EAS_STATE_PAUSING)
+ {
+ if (VMActiveVoices(pData->pSynth) == 0)
+ pData->state = EAS_STATE_PAUSED;
+ }
+
+ /* return current state */
+ *pState = pData->state;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * RTTTL_Close()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Close the file and clean up
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT RTTTL_Close (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
+{
+ S_RTTTL_DATA* pData;
+ EAS_RESULT result;
+
+ pData = (S_RTTTL_DATA*) pInstData;
+
+ /* close the file */
+ if ((result = EAS_HWCloseFile(pEASData->hwInstData, pData->fileHandle)) != EAS_SUCCESS)
+ return result;
+
+ /* free the synth */
+ if (pData->pSynth != NULL)
+ VMMIDIShutdown(pEASData, pData->pSynth);
+
+ /* if using dynamic memory, free it */
+ if (!pEASData->staticMemoryModel)
+ EAS_HWFree(pEASData->hwInstData, pData);
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * RTTTL_Reset()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Reset the sequencer. Used for locating backwards in the file.
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT RTTTL_Reset (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
+{
+ S_RTTTL_DATA* pData;
+ EAS_RESULT result;
+
+ pData = (S_RTTTL_DATA*) pInstData;
+
+ /* reset the synth */
+ VMReset(pEASData->pVoiceMgr, pData->pSynth, EAS_TRUE);
+
+ /* reset time to zero */
+ pData->time = 0;
+ pData->note = 0;
+
+ /* reset file position and re-parse header */
+ pData->state = EAS_STATE_ERROR;
+ if ((result = EAS_HWFileSeek(pEASData->hwInstData, pData->fileHandle, pData->fileOffset)) != EAS_SUCCESS)
+ return result;
+ if ((result = RTTTL_ParseHeader (pEASData, pData, EAS_TRUE)) != EAS_SUCCESS)
+ return result;
+
+ pData->state = EAS_STATE_READY;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * RTTTL_Pause()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Pauses the sequencer. Mutes all voices and sets state to pause.
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT RTTTL_Pause (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
+{
+ S_RTTTL_DATA *pData;
+
+ /* can't pause a stopped stream */
+ pData = (S_RTTTL_DATA*) pInstData;
+ if (pData->state == EAS_STATE_STOPPED)
+ return EAS_ERROR_ALREADY_STOPPED;
+
+ /* mute the synthesizer */
+ VMMuteAllVoices(pEASData->pVoiceMgr, pData->pSynth);
+ pData->state = EAS_STATE_PAUSING;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * RTTTL_Resume()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Resume playing after a pause, sets state back to playing.
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pEASData) reserved for future use */
+static EAS_RESULT RTTTL_Resume (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
+{
+ S_RTTTL_DATA *pData;
+
+ /* can't resume a stopped stream */
+ pData = (S_RTTTL_DATA*) pInstData;
+ if (pData->state == EAS_STATE_STOPPED)
+ return EAS_ERROR_ALREADY_STOPPED;
+
+ /* nothing to do but resume playback */
+ pData->state = EAS_STATE_PLAY;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * RTTTL_SetData()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Return file type
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pEASData) reserved for future use */
+static EAS_RESULT RTTTL_SetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value)
+{
+ S_RTTTL_DATA *pData;
+
+ pData = (S_RTTTL_DATA *) pInstData;
+ switch (param)
+ {
+
+ /* set metadata callback */
+ case PARSER_DATA_METADATA_CB:
+ EAS_HWMemCpy(&pData->metadata, (void*) value, sizeof(S_METADATA_CB));
+ break;
+
+ default:
+ return EAS_ERROR_INVALID_PARAMETER;
+ }
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * RTTTL_GetData()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Return file type
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pEASData) reserved for future use */
+static EAS_RESULT RTTTL_GetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue)
+{
+ S_RTTTL_DATA *pData;
+
+ pData = (S_RTTTL_DATA *) pInstData;
+ switch (param)
+ {
+ /* return file type as RTTTL */
+ case PARSER_DATA_FILE_TYPE:
+ *pValue = EAS_FILE_RTTTL;
+ break;
+
+#if 0
+ /* set transposition */
+ case PARSER_DATA_TRANSPOSITION:
+ *pValue = pData->transposition;
+ break;
+#endif
+
+ case PARSER_DATA_SYNTH_HANDLE:
+ *pValue = (EAS_I32) pData->pSynth;
+ break;
+
+ case PARSER_DATA_GAIN_OFFSET:
+ *pValue = RTTTL_GAIN_OFFSET;
+ break;
+
+ default:
+ return EAS_ERROR_INVALID_PARAMETER;
+ }
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * RTTTL_GetStyle()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ *
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT RTTTL_GetStyle (EAS_HW_DATA_HANDLE hwInstData, S_RTTTL_DATA *pData)
+{
+ EAS_RESULT result;
+ EAS_I8 style;
+
+ /* get style */
+ if ((result = RTTTL_GetNextChar(hwInstData, pData, &style)) != EAS_SUCCESS)
+ return result;
+
+ if ((style != 's') && (style != 'n') && (style != 'c'))
+ return EAS_ERROR_FILE_FORMAT;
+
+ pData->style = style;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * RTTTL_GetDuration()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ *
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT RTTTL_GetDuration (EAS_HW_DATA_HANDLE hwInstData, S_RTTTL_DATA *pData, EAS_I8 *pDuration)
+{
+ EAS_RESULT result;
+ EAS_I32 duration;
+ EAS_I8 temp;
+
+ /* get the duration */
+ if ((result = RTTTL_GetNumber(hwInstData, pData, &duration)) != EAS_SUCCESS)
+ return result;
+
+ if ((duration != 1) && (duration != 2) && (duration != 4) && (duration != 8) && (duration != 16) && (duration != 32))
+ return EAS_ERROR_FILE_FORMAT;
+
+ temp = 64;
+ while (duration)
+ {
+ /*lint -e{704} shift for performance */
+ duration = duration >> 1;
+ /*lint -e{702} use shift for performance */
+ temp = temp >> 1;
+ }
+
+ *pDuration = temp;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * RTTTL_GetOctave()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ *
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT RTTTL_GetOctave (EAS_HW_DATA_HANDLE hwInstData, S_RTTTL_DATA *pData, EAS_U8 *pOctave)
+{
+ EAS_RESULT result;
+ EAS_I32 octave;
+
+ /* get the tempo */
+ if ((result = RTTTL_GetNumber(hwInstData, pData, &octave)) != EAS_SUCCESS)
+ return result;
+
+ if ((octave < 4) || (octave > 7))
+ return EAS_ERROR_FILE_FORMAT;
+
+ *pOctave = (EAS_U8) (octave * 12);
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * RTTTL_GetTempo()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ *
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT RTTTL_GetTempo (EAS_HW_DATA_HANDLE hwInstData, S_RTTTL_DATA *pData)
+{
+ EAS_RESULT result;
+ EAS_I32 tempo;
+
+ /* get the tempo */
+ if ((result = RTTTL_GetNumber(hwInstData, pData, &tempo)) != EAS_SUCCESS)
+ return result;
+
+ if ((tempo < 25) || (tempo > 900))
+ return EAS_ERROR_FILE_FORMAT;
+
+ pData->tick = TICK_CONVERT / (EAS_U32) tempo;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * RTTTL_GetNumber()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ *
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT RTTTL_GetNumber (EAS_HW_DATA_HANDLE hwInstData, S_RTTTL_DATA *pData, EAS_I32 *pValue)
+{
+ EAS_RESULT result;
+ EAS_INT temp;
+ EAS_I8 c;
+
+ *pValue = -1;
+ temp = 0;
+ for (;;)
+ {
+ if ((result = RTTTL_PeekNextChar(hwInstData, pData, &c)) != EAS_SUCCESS)
+ {
+ if ((result == EAS_EOF) && (*pValue != -1))
+ return EAS_SUCCESS;
+ return result;
+ }
+
+ if (IsDigit(c))
+ {
+ pData->dataByte = 0;
+ temp = temp * 10 + c - '0';
+ *pValue = temp;
+ }
+ else
+ return EAS_SUCCESS;
+ }
+}
+
+/*----------------------------------------------------------------------------
+ * RTTTL_ParseHeader()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Prepare to parse the file. Allocates instance data (or uses static allocation for
+ * static memory model).
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT RTTTL_ParseHeader (S_EAS_DATA *pEASData, S_RTTTL_DATA* pData, EAS_BOOL metaData)
+{
+ EAS_RESULT result;
+ EAS_I32 i;
+ EAS_I8 temp;
+ EAS_I8 control;
+
+ /* initialize some defaults */
+ pData->time = 0;
+ pData->tick = DEFAULT_TICK_CONV;
+ pData->note = 0;
+ pData->duration = 4;
+ pData ->restTicks = 0;
+ pData->octave = 60;
+ pData->repeatOffset = -1;
+ pData->repeatCount = 0;
+ pData->style = 'n';
+ pData->dataByte = 0;
+
+ metaData = metaData && (pData->metadata.buffer != NULL) && (pData->metadata.callback != NULL);
+
+ /* seek to start of data */
+ if ((result = EAS_HWFileSeek(pEASData->hwInstData, pData->fileHandle, pData->fileOffset)) != EAS_SUCCESS)
+ return result;
+
+ /* zero the metadata buffer */
+ if (metaData)
+ EAS_HWMemSet(pData->metadata.buffer, 0, pData->metadata.bufferSize);
+
+ /* read the title */
+ for (i = 0; i < RTTTL_MAX_TITLE_LEN; i++)
+ {
+ if ((result = EAS_HWGetByte(pEASData->hwInstData, pData->fileHandle, &temp)) != EAS_SUCCESS)
+ return result;
+
+ if (temp == ':')
+ break;
+
+ /* pass along metadata */
+ if (metaData)
+ {
+ if (i < (pData->metadata.bufferSize- 1))
+ pData->metadata.buffer[i] = (char) temp;
+ }
+ }
+
+ /* check for error in title */
+ if (i == RTTTL_MAX_TITLE_LEN)
+ return EAS_ERROR_FILE_FORMAT;
+
+ /* pass along metadata */
+ if (metaData)
+ (*pData->metadata.callback)(EAS_METADATA_TITLE, pData->metadata.buffer, pData->metadata.pUserData);
+
+ /* control fields */
+ for (;;)
+ {
+
+ /* get control type */
+ if ((result = RTTTL_GetNextChar(pEASData->hwInstData, pData, &control)) != EAS_SUCCESS)
+ return result;
+
+ /* next char should be equal sign */
+ if ((result = RTTTL_GetNextChar(pEASData->hwInstData, pData, &temp)) != EAS_SUCCESS)
+ return result;
+ if (temp != '=')
+ return EAS_ERROR_FILE_FORMAT;
+
+ /* get the control value */
+ switch (control)
+ {
+
+ /* bpm */
+ case 'b':
+ if ((result = RTTTL_GetTempo(pEASData->hwInstData, pData)) != EAS_SUCCESS)
+ return result;
+ break;
+
+ /* duration */
+ case 'd':
+ if ((result = RTTTL_GetDuration(pEASData->hwInstData, pData, &temp)) != EAS_SUCCESS)
+ return result;
+ pData->duration = temp;
+ break;
+
+ /* loop */
+ case 'l':
+ if ((result = RTTTL_GetNumber(pEASData->hwInstData, pData, &i)) != EAS_SUCCESS)
+ return result;
+ if ((i < 0) || (i > 15))
+ return EAS_ERROR_FILE_FORMAT;
+ pData->repeatCount = (EAS_U8) i;
+ break;
+
+ /* octave */
+ case 'o':
+ if ((result = RTTTL_GetOctave(pEASData->hwInstData, pData, &pData->octave)) != EAS_SUCCESS)
+ return result;
+ break;
+
+ /* get style */
+ case 's':
+ if ((result = RTTTL_GetStyle(pEASData->hwInstData, pData)) != EAS_SUCCESS)
+ return result;
+ break;
+
+ /* unrecognized control */
+ default:
+ return EAS_ERROR_FILE_FORMAT;
+ }
+
+ /* next character should be comma or colon */
+ if ((result = RTTTL_GetNextChar(pEASData->hwInstData, pData, &temp)) != EAS_SUCCESS)
+ return result;
+
+ /* check for end of control field */
+ if (temp == ':')
+ break;
+
+ /* must be a comma */
+ if (temp != ',')
+ return EAS_ERROR_FILE_FORMAT;
+ }
+
+ /* should be at the start of the music block */
+ if ((result = EAS_HWFilePos(pEASData->hwInstData, pData->fileHandle, &pData->repeatOffset)) != EAS_SUCCESS)
+ return result;
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * RTTTL_GetNextChar()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ *
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT RTTTL_GetNextChar (EAS_HW_DATA_HANDLE hwInstData, S_RTTTL_DATA *pData, EAS_I8 *pValue)
+{
+ EAS_RESULT result;
+ EAS_I8 temp;
+
+ *pValue = 0;
+ for(;;)
+ {
+
+ /* check for character that has been put back */
+ if (pData->dataByte)
+ {
+ temp = pData->dataByte;
+ pData->dataByte = 0;
+ }
+ else
+ {
+ if ((result = EAS_HWGetByte(hwInstData, pData->fileHandle, &temp)) != EAS_SUCCESS)
+ return result;
+ }
+
+ /* ignore white space */
+ if (!IsSpace(temp))
+ {
+ *pValue = ToLower(temp);
+ return EAS_SUCCESS;
+ }
+ }
+}
+
+/*----------------------------------------------------------------------------
+ * RTTTL_PeekNextChar()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ *
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT RTTTL_PeekNextChar (EAS_HW_DATA_HANDLE hwInstData, S_RTTTL_DATA *pData, EAS_I8 *pValue)
+{
+ EAS_RESULT result;
+ EAS_I8 temp;
+
+ *pValue = 0;
+ for(;;)
+ {
+
+ /* read a character from the file, if necessary */
+ if (!pData->dataByte)
+ {
+ if ((result = EAS_HWGetByte(hwInstData, pData->fileHandle, &pData->dataByte)) != EAS_SUCCESS)
+ return result;
+
+ }
+ temp = pData->dataByte;
+
+ /* ignore white space */
+ if (!IsSpace(temp))
+ {
+ *pValue = ToLower(temp);
+ return EAS_SUCCESS;
+ }
+ pData->dataByte = 0;
+ }
+}
+
diff --git a/arm-wt-22k/lib_src/eas_rtttldata.c b/arm-wt-22k/lib_src/eas_rtttldata.c
index 7a500bd..708a1d9 100644
--- a/arm-wt-22k/lib_src/eas_rtttldata.c
+++ b/arm-wt-22k/lib_src/eas_rtttldata.c
@@ -1,12 +1,12 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_rtttldata.c
- *
- * Contents and purpose:
- * RTTTL File Parser data module for static memory models
- *
- * Copyright Sonic Network Inc. 2005
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_rtttldata.c
+ *
+ * Contents and purpose:
+ * RTTTL File Parser data module for static memory models
+ *
+ * Copyright Sonic Network Inc. 2005
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,23 +19,23 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 547 $
- * $Date: 2007-01-31 16:30:17 -0800 (Wed, 31 Jan 2007) $
- *----------------------------------------------------------------------------
-*/
-
-#include "eas_types.h"
-#include "eas_rtttldata.h"
-
-/*----------------------------------------------------------------------------
- *
- * eas_RTTTLData
- *
- * Static memory allocation for RTTTL parser
- *----------------------------------------------------------------------------
-*/
-S_RTTTL_DATA eas_RTTTLData;
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 547 $
+ * $Date: 2007-01-31 16:30:17 -0800 (Wed, 31 Jan 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+#include "eas_types.h"
+#include "eas_rtttldata.h"
+
+/*----------------------------------------------------------------------------
+ *
+ * eas_RTTTLData
+ *
+ * Static memory allocation for RTTTL parser
+ *----------------------------------------------------------------------------
+*/
+S_RTTTL_DATA eas_RTTTLData;
+
diff --git a/arm-wt-22k/lib_src/eas_rtttldata.h b/arm-wt-22k/lib_src/eas_rtttldata.h
index bf4c38b..31dd522 100644
--- a/arm-wt-22k/lib_src/eas_rtttldata.h
+++ b/arm-wt-22k/lib_src/eas_rtttldata.h
@@ -1,14 +1,14 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_rtttldata.h
- *
- * Contents and purpose:
- * SMF File Parser
- *
- * This file contains data declarations for the RTTTL parser.
- *
- * Copyright Sonic Network Inc. 2005
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_rtttldata.h
+ *
+ * Contents and purpose:
+ * SMF File Parser
+ *
+ * This file contains data declarations for the RTTTL parser.
+ *
+ * Copyright Sonic Network Inc. 2005
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,50 +21,50 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 82 $
- * $Date: 2006-07-10 11:45:19 -0700 (Mon, 10 Jul 2006) $
- *----------------------------------------------------------------------------
-*/
-
-#ifndef EAS_RTTTLDATA_H
-#define EAS_RTTTLDATA_H
-
-#include "eas_data.h"
-
-
-/* maximum line size as specified in iMelody V1.2 spec */
-#define MAX_LINE_SIZE 75
-
-/*----------------------------------------------------------------------------
- *
- * S_RTTTL_DATA
- *
- * This structure contains the state data for the iMelody parser
- *----------------------------------------------------------------------------
-*/
-
-typedef struct
-{
- EAS_FILE_HANDLE fileHandle; /* file handle */
- S_SYNTH *pSynth; /* synthesizer handle */
- S_METADATA_CB metadata; /* metadata callback */
- EAS_I32 fileOffset; /* offset to start of data */
- EAS_I32 time; /* current time in 256ths of a msec */
- EAS_I32 tick; /* length of 32nd note in 256th of a msec */
- EAS_I32 restTicks; /* ticks to rest after current note */
- EAS_I32 repeatOffset; /* file offset to start of repeat section */
- EAS_U8 repeatCount; /* repeat counter */
- EAS_I8 dataByte; /* storage for characters that are "put back" */
- EAS_U8 state; /* current state EAS_STATE_XXXX */
- EAS_I8 style; /* from STYLE */
- EAS_U8 note; /* MIDI note number */
- EAS_U8 octave; /* decault octave prefix */
- EAS_I8 duration; /* default note duration */
-} S_RTTTL_DATA;
-
-#endif
-
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 82 $
+ * $Date: 2006-07-10 11:45:19 -0700 (Mon, 10 Jul 2006) $
+ *----------------------------------------------------------------------------
+*/
+
+#ifndef EAS_RTTTLDATA_H
+#define EAS_RTTTLDATA_H
+
+#include "eas_data.h"
+
+
+/* maximum line size as specified in iMelody V1.2 spec */
+#define MAX_LINE_SIZE 75
+
+/*----------------------------------------------------------------------------
+ *
+ * S_RTTTL_DATA
+ *
+ * This structure contains the state data for the iMelody parser
+ *----------------------------------------------------------------------------
+*/
+
+typedef struct
+{
+ EAS_FILE_HANDLE fileHandle; /* file handle */
+ S_SYNTH *pSynth; /* synthesizer handle */
+ S_METADATA_CB metadata; /* metadata callback */
+ EAS_I32 fileOffset; /* offset to start of data */
+ EAS_I32 time; /* current time in 256ths of a msec */
+ EAS_I32 tick; /* length of 32nd note in 256th of a msec */
+ EAS_I32 restTicks; /* ticks to rest after current note */
+ EAS_I32 repeatOffset; /* file offset to start of repeat section */
+ EAS_U8 repeatCount; /* repeat counter */
+ EAS_I8 dataByte; /* storage for characters that are "put back" */
+ EAS_U8 state; /* current state EAS_STATE_XXXX */
+ EAS_I8 style; /* from STYLE */
+ EAS_U8 note; /* MIDI note number */
+ EAS_U8 octave; /* decault octave prefix */
+ EAS_I8 duration; /* default note duration */
+} S_RTTTL_DATA;
+
+#endif
+
+
diff --git a/arm-wt-22k/lib_src/eas_smf.c b/arm-wt-22k/lib_src/eas_smf.c
index af02c93..9e096b6 100644
--- a/arm-wt-22k/lib_src/eas_smf.c
+++ b/arm-wt-22k/lib_src/eas_smf.c
@@ -1,12 +1,12 @@
/*----------------------------------------------------------------------------
*
- * File:
+ * File:
* eas_smf.c
*
* Contents and purpose:
* SMF Type 0 and 1 File Parser
*
- * For SMF timebase analysis, see "MIDI Sequencer Analysis.xls".
+ * For SMF timebase analysis, see "MIDI Sequencer Analysis.xls".
*
* Copyright Sonic Network Inc. 2005
@@ -24,8 +24,8 @@
*
*----------------------------------------------------------------------------
* Revision Control:
- * $Revision: 803 $
- * $Date: 2007-08-01 09:57:00 -0700 (Wed, 01 Aug 2007) $
+ * $Revision: 803 $
+ * $Date: 2007-08-01 09:57:00 -0700 (Wed, 01 Aug 2007) $
*----------------------------------------------------------------------------
*/
@@ -64,38 +64,38 @@ static void SMF_UpdateTime (S_SMF_DATA *pSMFData, EAS_U32 ticks);
*
* SMF_Parser
*
- * This structure contains the functional interface for the SMF parser
+ * This structure contains the functional interface for the SMF parser
*----------------------------------------------------------------------------
*/
const S_FILE_PARSER_INTERFACE EAS_SMF_Parser =
{
- SMF_CheckFileType,
- SMF_Prepare,
- SMF_Time,
- SMF_Event,
- SMF_State,
- SMF_Close,
- SMF_Reset,
- SMF_Pause,
- SMF_Resume,
- NULL,
- SMF_SetData,
- SMF_GetData,
- NULL
+ SMF_CheckFileType,
+ SMF_Prepare,
+ SMF_Time,
+ SMF_Event,
+ SMF_State,
+ SMF_Close,
+ SMF_Reset,
+ SMF_Pause,
+ SMF_Resume,
+ NULL,
+ SMF_SetData,
+ SMF_GetData,
+ NULL
};
/*----------------------------------------------------------------------------
* SMF_CheckFileType()
*----------------------------------------------------------------------------
- * Purpose:
+ * Purpose:
* Check the file type to see if we can parse it
*
* Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
* Outputs:
- *
+ *
*
* Side Effects:
*
@@ -103,69 +103,69 @@ const S_FILE_PARSER_INTERFACE EAS_SMF_Parser =
*/
EAS_RESULT SMF_CheckFileType (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle, EAS_VOID_PTR *ppHandle, EAS_I32 offset)
{
- S_SMF_DATA* pSMFData;
- EAS_RESULT result;
-
- /* seek to starting offset - usually 0 */
- *ppHandle = NULL;
- if ((result = EAS_HWFileSeek(pEASData->hwInstData, fileHandle, offset)) != EAS_SUCCESS)
- return result;
-
- /* search through file for header - slow method */
- if (pEASData->searchHeaderFlag)
- {
- result = EAS_SearchFile(pEASData, fileHandle, smfHeader, sizeof(smfHeader), &offset);
- if (result != EAS_SUCCESS)
- return (result == EAS_EOF) ? EAS_SUCCESS : result;
- }
-
- /* read the first 4 bytes of the file - quick method */
- else {
- EAS_U8 header[4];
- EAS_I32 count;
- if ((result = EAS_HWReadFile(pEASData->hwInstData, fileHandle, header, sizeof(header), &count)) != EAS_SUCCESS)
- return result;
-
- /* check for 'MTrk' - return if no match */
- if ((header[0] != 'M') || (header[1] != 'T') || (header[2] != 'h') || (header[3] != 'd'))
- return EAS_SUCCESS;
- }
-
- /* check for static memory allocation */
- if (pEASData->staticMemoryModel)
- pSMFData = EAS_CMEnumData(EAS_CM_SMF_DATA);
- else
- {
- pSMFData = EAS_HWMalloc(pEASData->hwInstData, sizeof(S_SMF_DATA));
- EAS_HWMemSet((void *)pSMFData,0, sizeof(S_SMF_DATA));
- }
- if (!pSMFData)
- return EAS_ERROR_MALLOC_FAILED;
-
- /* initialize some critical data */
- pSMFData->fileHandle = fileHandle;
- pSMFData->fileOffset = offset;
- pSMFData->pSynth = NULL;
- pSMFData->time = 0;
- pSMFData->state = EAS_STATE_OPEN;
- *ppHandle = pSMFData;
-
- return EAS_SUCCESS;
+ S_SMF_DATA* pSMFData;
+ EAS_RESULT result;
+
+ /* seek to starting offset - usually 0 */
+ *ppHandle = NULL;
+ if ((result = EAS_HWFileSeek(pEASData->hwInstData, fileHandle, offset)) != EAS_SUCCESS)
+ return result;
+
+ /* search through file for header - slow method */
+ if (pEASData->searchHeaderFlag)
+ {
+ result = EAS_SearchFile(pEASData, fileHandle, smfHeader, sizeof(smfHeader), &offset);
+ if (result != EAS_SUCCESS)
+ return (result == EAS_EOF) ? EAS_SUCCESS : result;
+ }
+
+ /* read the first 4 bytes of the file - quick method */
+ else {
+ EAS_U8 header[4];
+ EAS_I32 count;
+ if ((result = EAS_HWReadFile(pEASData->hwInstData, fileHandle, header, sizeof(header), &count)) != EAS_SUCCESS)
+ return result;
+
+ /* check for 'MTrk' - return if no match */
+ if ((header[0] != 'M') || (header[1] != 'T') || (header[2] != 'h') || (header[3] != 'd'))
+ return EAS_SUCCESS;
+ }
+
+ /* check for static memory allocation */
+ if (pEASData->staticMemoryModel)
+ pSMFData = EAS_CMEnumData(EAS_CM_SMF_DATA);
+ else
+ {
+ pSMFData = EAS_HWMalloc(pEASData->hwInstData, sizeof(S_SMF_DATA));
+ EAS_HWMemSet((void *)pSMFData,0, sizeof(S_SMF_DATA));
+ }
+ if (!pSMFData)
+ return EAS_ERROR_MALLOC_FAILED;
+
+ /* initialize some critical data */
+ pSMFData->fileHandle = fileHandle;
+ pSMFData->fileOffset = offset;
+ pSMFData->pSynth = NULL;
+ pSMFData->time = 0;
+ pSMFData->state = EAS_STATE_OPEN;
+ *ppHandle = pSMFData;
+
+ return EAS_SUCCESS;
}
/*----------------------------------------------------------------------------
* SMF_Prepare()
*----------------------------------------------------------------------------
- * Purpose:
+ * Purpose:
* Prepare to parse the file. Allocates instance data (or uses static allocation for
- * static memory model).
+ * static memory model).
*
* Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
* Outputs:
- *
+ *
*
* Side Effects:
*
@@ -173,43 +173,43 @@ EAS_RESULT SMF_CheckFileType (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle,
*/
EAS_RESULT SMF_Prepare (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
{
- S_SMF_DATA* pSMFData;
- EAS_RESULT result;
-
- /* check for valid state */
- pSMFData = (S_SMF_DATA *) pInstData;
- if (pSMFData->state != EAS_STATE_OPEN)
- return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
-
- /* instantiate a synthesizer */
- if ((result = VMInitMIDI(pEASData, &pSMFData->pSynth)) != EAS_SUCCESS)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "VMInitMIDI returned %d\n", result); */ }
- return result;
- }
-
- /* parse the file header and setup the individual stream parsers */
- if ((result = SMF_ParseHeader(pEASData->hwInstData, pSMFData)) != EAS_SUCCESS)
- return result;
-
- /* ready to play */
- pSMFData->state = EAS_STATE_READY;
- return EAS_SUCCESS;
+ S_SMF_DATA* pSMFData;
+ EAS_RESULT result;
+
+ /* check for valid state */
+ pSMFData = (S_SMF_DATA *) pInstData;
+ if (pSMFData->state != EAS_STATE_OPEN)
+ return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
+
+ /* instantiate a synthesizer */
+ if ((result = VMInitMIDI(pEASData, &pSMFData->pSynth)) != EAS_SUCCESS)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "VMInitMIDI returned %d\n", result); */ }
+ return result;
+ }
+
+ /* parse the file header and setup the individual stream parsers */
+ if ((result = SMF_ParseHeader(pEASData->hwInstData, pSMFData)) != EAS_SUCCESS)
+ return result;
+
+ /* ready to play */
+ pSMFData->state = EAS_STATE_READY;
+ return EAS_SUCCESS;
}
/*----------------------------------------------------------------------------
* SMF_Time()
*----------------------------------------------------------------------------
- * Purpose:
+ * Purpose:
* Returns the time of the next event in msecs
*
* Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- * pTime - pointer to variable to hold time of next event (in msecs)
- *
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ * pTime - pointer to variable to hold time of next event (in msecs)
+ *
* Outputs:
- *
+ *
*
* Side Effects:
*
@@ -218,51 +218,51 @@ EAS_RESULT SMF_Prepare (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
/*lint -esym(715, pEASData) reserved for future use */
EAS_RESULT SMF_Time (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_U32 *pTime)
{
- S_SMF_DATA *pSMFData;
-
- pSMFData = (S_SMF_DATA*) pInstData;
+ S_SMF_DATA *pSMFData;
+
+ pSMFData = (S_SMF_DATA*) pInstData;
- /* sanity check */
+ /* sanity check */
#ifdef _CHECKED_BUILD
- if (pSMFData->state == EAS_STATE_STOPPED)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Can't ask for time on a stopped stream\n"); */ }
- }
-
- if (pSMFData->nextStream == NULL)
- {
- { /* dpp: EAS_ReportEx( _EAS_SEVERITY_ERROR, "no is NULL\n"); */ }
- }
+ if (pSMFData->state == EAS_STATE_STOPPED)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Can't ask for time on a stopped stream\n"); */ }
+ }
+
+ if (pSMFData->nextStream == NULL)
+ {
+ { /* dpp: EAS_ReportEx( _EAS_SEVERITY_ERROR, "no is NULL\n"); */ }
+ }
#endif
#if 0
- /* return time in milliseconds */
- /* if chase mode, lie about time */
- if (pSMFData->flags & SMF_FLAGS_CHASE_MODE)
- *pTime = 0;
+ /* return time in milliseconds */
+ /* if chase mode, lie about time */
+ if (pSMFData->flags & SMF_FLAGS_CHASE_MODE)
+ *pTime = 0;
- else
-#endif
+ else
+#endif
- /*lint -e{704} use shift instead of division */
- *pTime = pSMFData->time >> 8;
+ /*lint -e{704} use shift instead of division */
+ *pTime = pSMFData->time >> 8;
- *pTime = pSMFData->time >> 8;
- return EAS_SUCCESS;
+ *pTime = pSMFData->time >> 8;
+ return EAS_SUCCESS;
}
/*----------------------------------------------------------------------------
* SMF_Event()
*----------------------------------------------------------------------------
- * Purpose:
+ * Purpose:
* Parse the next event in the file
*
* Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
* Outputs:
- *
+ *
*
* Side Effects:
*
@@ -270,103 +270,103 @@ EAS_RESULT SMF_Time (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_U32 *pTim
*/
EAS_RESULT SMF_Event (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_INT parserMode)
{
- S_SMF_DATA* pSMFData;
- EAS_RESULT result;
- EAS_I32 i;
- EAS_U32 ticks;
- EAS_U32 temp;
+ S_SMF_DATA* pSMFData;
+ EAS_RESULT result;
+ EAS_I32 i;
+ EAS_U32 ticks;
+ EAS_U32 temp;
- /* establish pointer to instance data */
- pSMFData = (S_SMF_DATA*) pInstData;
- if (pSMFData->state >= EAS_STATE_OPEN)
- return EAS_SUCCESS;
+ /* establish pointer to instance data */
+ pSMFData = (S_SMF_DATA*) pInstData;
+ if (pSMFData->state >= EAS_STATE_OPEN)
+ return EAS_SUCCESS;
- /* get current ticks */
- ticks = pSMFData->nextStream->ticks;
+ /* get current ticks */
+ ticks = pSMFData->nextStream->ticks;
- /* assume that an error occurred */
- pSMFData->state = EAS_STATE_ERROR;
+ /* assume that an error occurred */
+ pSMFData->state = EAS_STATE_ERROR;
#ifdef JET_INTERFACE
- /* if JET has track muted, set parser mode to mute */
- if (pSMFData->nextStream->midiStream.jetData & MIDI_FLAGS_JET_MUTE)
- parserMode = eParserModeMute;
-#endif
-
- /* parse the next event from all the streams */
- if ((result = SMF_ParseEvent(pEASData, pSMFData, pSMFData->nextStream, parserMode)) != EAS_SUCCESS)
- {
- /* check for unexpected end-of-file */
- if (result != EAS_EOF)
- return result;
-
- /* indicate end of track for this stream */
- pSMFData->nextStream->ticks = SMF_END_OF_TRACK;
- }
-
- /* get next delta time, unless already at end of track */
- else if (pSMFData->nextStream->ticks != SMF_END_OF_TRACK)
- {
- if ((result = SMF_GetDeltaTime(pEASData->hwInstData, pSMFData->nextStream)) != EAS_SUCCESS)
- {
- /* check for unexpected end-of-file */
- if (result != EAS_EOF)
- return result;
-
- /* indicate end of track for this stream */
- pSMFData->nextStream->ticks = SMF_END_OF_TRACK;
- }
-
- /* if zero delta to next event, stay with this stream */
- else if (pSMFData->nextStream->ticks == ticks)
- {
- pSMFData->state = EAS_STATE_PLAY;
- return EAS_SUCCESS;
- }
- }
-
- /* find next event in all streams */
- temp = 0x7ffffff;
- pSMFData->nextStream = NULL;
- for (i = 0; i < pSMFData->numStreams; i++)
- {
- if (pSMFData->streams[i].ticks < temp)
- {
- temp = pSMFData->streams[i].ticks;
- pSMFData->nextStream = &pSMFData->streams[i];
- }
- }
-
- /* are there any more events to parse? */
- if (pSMFData->nextStream)
- {
- pSMFData->state = EAS_STATE_PLAY;
-
- /* update the time of the next event */
- SMF_UpdateTime(pSMFData, pSMFData->nextStream->ticks - ticks);
- }
- else
- {
- pSMFData->state = EAS_STATE_STOPPING;
- VMReleaseAllVoices(pEASData->pVoiceMgr, pSMFData->pSynth);
- }
-
- return EAS_SUCCESS;
+ /* if JET has track muted, set parser mode to mute */
+ if (pSMFData->nextStream->midiStream.jetData & MIDI_FLAGS_JET_MUTE)
+ parserMode = eParserModeMute;
+#endif
+
+ /* parse the next event from all the streams */
+ if ((result = SMF_ParseEvent(pEASData, pSMFData, pSMFData->nextStream, parserMode)) != EAS_SUCCESS)
+ {
+ /* check for unexpected end-of-file */
+ if (result != EAS_EOF)
+ return result;
+
+ /* indicate end of track for this stream */
+ pSMFData->nextStream->ticks = SMF_END_OF_TRACK;
+ }
+
+ /* get next delta time, unless already at end of track */
+ else if (pSMFData->nextStream->ticks != SMF_END_OF_TRACK)
+ {
+ if ((result = SMF_GetDeltaTime(pEASData->hwInstData, pSMFData->nextStream)) != EAS_SUCCESS)
+ {
+ /* check for unexpected end-of-file */
+ if (result != EAS_EOF)
+ return result;
+
+ /* indicate end of track for this stream */
+ pSMFData->nextStream->ticks = SMF_END_OF_TRACK;
+ }
+
+ /* if zero delta to next event, stay with this stream */
+ else if (pSMFData->nextStream->ticks == ticks)
+ {
+ pSMFData->state = EAS_STATE_PLAY;
+ return EAS_SUCCESS;
+ }
+ }
+
+ /* find next event in all streams */
+ temp = 0x7ffffff;
+ pSMFData->nextStream = NULL;
+ for (i = 0; i < pSMFData->numStreams; i++)
+ {
+ if (pSMFData->streams[i].ticks < temp)
+ {
+ temp = pSMFData->streams[i].ticks;
+ pSMFData->nextStream = &pSMFData->streams[i];
+ }
+ }
+
+ /* are there any more events to parse? */
+ if (pSMFData->nextStream)
+ {
+ pSMFData->state = EAS_STATE_PLAY;
+
+ /* update the time of the next event */
+ SMF_UpdateTime(pSMFData, pSMFData->nextStream->ticks - ticks);
+ }
+ else
+ {
+ pSMFData->state = EAS_STATE_STOPPING;
+ VMReleaseAllVoices(pEASData->pVoiceMgr, pSMFData->pSynth);
+ }
+
+ return EAS_SUCCESS;
}
/*----------------------------------------------------------------------------
* SMF_State()
*----------------------------------------------------------------------------
- * Purpose:
+ * Purpose:
* Returns the current state of the stream
*
* Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- * pState - pointer to variable to store state
- *
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ * pState - pointer to variable to store state
+ *
* Outputs:
- *
+ *
*
* Side Effects:
*
@@ -375,41 +375,41 @@ EAS_RESULT SMF_Event (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_INT pars
/*lint -esym(715, pEASData) reserved for future use */
EAS_RESULT SMF_State (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 *pState)
{
- S_SMF_DATA* pSMFData;
-
- /* establish pointer to instance data */
- pSMFData = (S_SMF_DATA*) pInstData;
-
- /* if stopping, check to see if synth voices are active */
- if (pSMFData->state == EAS_STATE_STOPPING)
- {
- if (VMActiveVoices(pSMFData->pSynth) == 0)
- pSMFData->state = EAS_STATE_STOPPED;
- }
-
- if (pSMFData->state == EAS_STATE_PAUSING)
- {
- if (VMActiveVoices(pSMFData->pSynth) == 0)
- pSMFData->state = EAS_STATE_PAUSED;
- }
-
- /* return current state */
- *pState = pSMFData->state;
- return EAS_SUCCESS;
+ S_SMF_DATA* pSMFData;
+
+ /* establish pointer to instance data */
+ pSMFData = (S_SMF_DATA*) pInstData;
+
+ /* if stopping, check to see if synth voices are active */
+ if (pSMFData->state == EAS_STATE_STOPPING)
+ {
+ if (VMActiveVoices(pSMFData->pSynth) == 0)
+ pSMFData->state = EAS_STATE_STOPPED;
+ }
+
+ if (pSMFData->state == EAS_STATE_PAUSING)
+ {
+ if (VMActiveVoices(pSMFData->pSynth) == 0)
+ pSMFData->state = EAS_STATE_PAUSED;
+ }
+
+ /* return current state */
+ *pState = pSMFData->state;
+ return EAS_SUCCESS;
}
/*----------------------------------------------------------------------------
* SMF_Close()
*----------------------------------------------------------------------------
- * Purpose:
+ * Purpose:
* Close the file and clean up
*
* Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
* Outputs:
- *
+ *
*
* Side Effects:
*
@@ -417,54 +417,54 @@ EAS_RESULT SMF_State (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 *pSt
*/
EAS_RESULT SMF_Close (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
{
- S_SMF_DATA* pSMFData;
- EAS_I32 i;
- EAS_RESULT result;
-
- pSMFData = (S_SMF_DATA*) pInstData;
-
- /* close all the streams */
- for (i = 0; i < pSMFData->numStreams; i++)
- {
- if (pSMFData->streams[i].fileHandle != NULL)
- {
- if ((result = EAS_HWCloseFile(pEASData->hwInstData, pSMFData->streams[i].fileHandle)) != EAS_SUCCESS)
- return result;
- }
- }
- if (pSMFData->fileHandle != NULL)
- if ((result = EAS_HWCloseFile(pEASData->hwInstData, pSMFData->fileHandle)) != EAS_SUCCESS)
- return result;
-
- /* free the synth */
- if (pSMFData->pSynth != NULL)
- VMMIDIShutdown(pEASData, pSMFData->pSynth);
-
- /* if using dynamic memory, free it */
- if (!pEASData->staticMemoryModel)
- {
- if (pSMFData->streams)
- EAS_HWFree(pEASData->hwInstData, pSMFData->streams);
-
- /* free the instance data */
- EAS_HWFree(pEASData->hwInstData, pSMFData);
- }
-
- return EAS_SUCCESS;
+ S_SMF_DATA* pSMFData;
+ EAS_I32 i;
+ EAS_RESULT result;
+
+ pSMFData = (S_SMF_DATA*) pInstData;
+
+ /* close all the streams */
+ for (i = 0; i < pSMFData->numStreams; i++)
+ {
+ if (pSMFData->streams[i].fileHandle != NULL)
+ {
+ if ((result = EAS_HWCloseFile(pEASData->hwInstData, pSMFData->streams[i].fileHandle)) != EAS_SUCCESS)
+ return result;
+ }
+ }
+ if (pSMFData->fileHandle != NULL)
+ if ((result = EAS_HWCloseFile(pEASData->hwInstData, pSMFData->fileHandle)) != EAS_SUCCESS)
+ return result;
+
+ /* free the synth */
+ if (pSMFData->pSynth != NULL)
+ VMMIDIShutdown(pEASData, pSMFData->pSynth);
+
+ /* if using dynamic memory, free it */
+ if (!pEASData->staticMemoryModel)
+ {
+ if (pSMFData->streams)
+ EAS_HWFree(pEASData->hwInstData, pSMFData->streams);
+
+ /* free the instance data */
+ EAS_HWFree(pEASData->hwInstData, pSMFData);
+ }
+
+ return EAS_SUCCESS;
}
/*----------------------------------------------------------------------------
* SMF_Reset()
*----------------------------------------------------------------------------
- * Purpose:
+ * Purpose:
* Reset the sequencer. Used for locating backwards in the file.
*
* Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
* Outputs:
- *
+ *
*
* Side Effects:
*
@@ -472,62 +472,62 @@ EAS_RESULT SMF_Close (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
*/
EAS_RESULT SMF_Reset (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
{
- S_SMF_DATA* pSMFData;
- EAS_I32 i;
- EAS_RESULT result;
- EAS_U32 ticks;
-
- pSMFData = (S_SMF_DATA*) pInstData;
-
- /* reset time to zero */
- pSMFData->time = 0;
-
- /* reset the synth */
- VMReset(pEASData->pVoiceMgr, pSMFData->pSynth, EAS_TRUE);
-
- /* find the start of each track */
- ticks = 0x7fffffffL;
- pSMFData->nextStream = NULL;
- for (i = 0; i < pSMFData->numStreams; i++)
- {
-
- /* reset file position to first byte of data in track */
- if ((result = EAS_HWFileSeek(pEASData->hwInstData, pSMFData->streams[i].fileHandle, pSMFData->streams[i].startFilePos)) != EAS_SUCCESS)
- return result;
-
- /* initalize some data */
- pSMFData->streams[i].ticks = 0;
-
- /* initalize the MIDI parser data */
- EAS_InitMIDIStream(&pSMFData->streams[i].midiStream);
-
- /* parse the first delta time in each stream */
- if ((result = SMF_GetDeltaTime(pEASData->hwInstData,&pSMFData->streams[i])) != EAS_SUCCESS)
- return result;
- if (pSMFData->streams[i].ticks < ticks)
- {
- ticks = pSMFData->streams[i].ticks;
- pSMFData->nextStream = &pSMFData->streams[i];
- }
- }
-
-
- pSMFData->state = EAS_STATE_READY;
- return EAS_SUCCESS;
+ S_SMF_DATA* pSMFData;
+ EAS_I32 i;
+ EAS_RESULT result;
+ EAS_U32 ticks;
+
+ pSMFData = (S_SMF_DATA*) pInstData;
+
+ /* reset time to zero */
+ pSMFData->time = 0;
+
+ /* reset the synth */
+ VMReset(pEASData->pVoiceMgr, pSMFData->pSynth, EAS_TRUE);
+
+ /* find the start of each track */
+ ticks = 0x7fffffffL;
+ pSMFData->nextStream = NULL;
+ for (i = 0; i < pSMFData->numStreams; i++)
+ {
+
+ /* reset file position to first byte of data in track */
+ if ((result = EAS_HWFileSeek(pEASData->hwInstData, pSMFData->streams[i].fileHandle, pSMFData->streams[i].startFilePos)) != EAS_SUCCESS)
+ return result;
+
+ /* initalize some data */
+ pSMFData->streams[i].ticks = 0;
+
+ /* initalize the MIDI parser data */
+ EAS_InitMIDIStream(&pSMFData->streams[i].midiStream);
+
+ /* parse the first delta time in each stream */
+ if ((result = SMF_GetDeltaTime(pEASData->hwInstData,&pSMFData->streams[i])) != EAS_SUCCESS)
+ return result;
+ if (pSMFData->streams[i].ticks < ticks)
+ {
+ ticks = pSMFData->streams[i].ticks;
+ pSMFData->nextStream = &pSMFData->streams[i];
+ }
+ }
+
+
+ pSMFData->state = EAS_STATE_READY;
+ return EAS_SUCCESS;
}
/*----------------------------------------------------------------------------
* SMF_Pause()
*----------------------------------------------------------------------------
- * Purpose:
+ * Purpose:
* Pauses the sequencer. Mutes all voices and sets state to pause.
*
* Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
* Outputs:
- *
+ *
*
* Side Effects:
*
@@ -535,31 +535,31 @@ EAS_RESULT SMF_Reset (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
*/
EAS_RESULT SMF_Pause (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
{
- S_SMF_DATA *pSMFData;
+ S_SMF_DATA *pSMFData;
- /* can't pause a stopped stream */
- pSMFData = (S_SMF_DATA*) pInstData;
- if (pSMFData->state == EAS_STATE_STOPPED)
- return EAS_ERROR_ALREADY_STOPPED;
+ /* can't pause a stopped stream */
+ pSMFData = (S_SMF_DATA*) pInstData;
+ if (pSMFData->state == EAS_STATE_STOPPED)
+ return EAS_ERROR_ALREADY_STOPPED;
- /* mute the synthesizer */
- VMMuteAllVoices(pEASData->pVoiceMgr, pSMFData->pSynth);
- pSMFData->state = EAS_STATE_PAUSING;
- return EAS_SUCCESS;
+ /* mute the synthesizer */
+ VMMuteAllVoices(pEASData->pVoiceMgr, pSMFData->pSynth);
+ pSMFData->state = EAS_STATE_PAUSING;
+ return EAS_SUCCESS;
}
/*----------------------------------------------------------------------------
* SMF_Resume()
*----------------------------------------------------------------------------
- * Purpose:
+ * Purpose:
* Resume playing after a pause, sets state back to playing.
*
* Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
* Outputs:
- *
+ *
*
* Side Effects:
*
@@ -568,30 +568,30 @@ EAS_RESULT SMF_Pause (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
/*lint -esym(715, pEASData) reserved for future use */
EAS_RESULT SMF_Resume (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
{
- S_SMF_DATA *pSMFData;
+ S_SMF_DATA *pSMFData;
- /* can't resume a stopped stream */
- pSMFData = (S_SMF_DATA*) pInstData;
- if (pSMFData->state == EAS_STATE_STOPPED)
- return EAS_ERROR_ALREADY_STOPPED;
+ /* can't resume a stopped stream */
+ pSMFData = (S_SMF_DATA*) pInstData;
+ if (pSMFData->state == EAS_STATE_STOPPED)
+ return EAS_ERROR_ALREADY_STOPPED;
- /* nothing to do but resume playback */
- pSMFData->state = EAS_STATE_PLAY;
- return EAS_SUCCESS;
+ /* nothing to do but resume playback */
+ pSMFData->state = EAS_STATE_PLAY;
+ return EAS_SUCCESS;
}
/*----------------------------------------------------------------------------
* SMF_SetData()
*----------------------------------------------------------------------------
- * Purpose:
+ * Purpose:
* Sets parser parameters
*
* Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
* Outputs:
- *
+ *
*
* Side Effects:
*
@@ -600,85 +600,85 @@ EAS_RESULT SMF_Resume (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
/*lint -esym(715, pEASData) reserved for future use */
EAS_RESULT SMF_SetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value)
{
- S_SMF_DATA *pSMFData;
+ S_SMF_DATA *pSMFData;
+
+ pSMFData = (S_SMF_DATA*) pInstData;
+ switch (param)
+ {
- pSMFData = (S_SMF_DATA*) pInstData;
- switch (param)
- {
-
- /* set metadata callback */
- case PARSER_DATA_METADATA_CB:
- EAS_HWMemCpy(&pSMFData->metadata, (void*) value, sizeof(S_METADATA_CB));
- break;
+ /* set metadata callback */
+ case PARSER_DATA_METADATA_CB:
+ EAS_HWMemCpy(&pSMFData->metadata, (void*) value, sizeof(S_METADATA_CB));
+ break;
#ifdef JET_INTERFACE
- /* set jet segment and track ID of all tracks for callback function */
- case PARSER_DATA_JET_CB:
- {
- EAS_U32 i;
- EAS_U32 bit = (EAS_U32) value;
- bit = (bit << JET_EVENT_SEG_SHIFT) & JET_EVENT_SEG_MASK;
- for (i = 0; i < pSMFData->numStreams; i++)
- pSMFData->streams[i].midiStream.jetData =
- (pSMFData->streams[i].midiStream.jetData &
- ~(JET_EVENT_TRACK_MASK | JET_EVENT_SEG_MASK)) |
- i << JET_EVENT_TRACK_SHIFT | bit | MIDI_FLAGS_JET_CB;
- pSMFData->flags |= SMF_FLAGS_JET_STREAM;
- }
- break;
-
- /* set state of all mute flags at once */
- case PARSER_DATA_MUTE_FLAGS:
- {
- EAS_INT i;
- EAS_U32 bit = (EAS_U32) value;
- for (i = 0; i < pSMFData->numStreams; i++)
- {
- if (bit & 1)
- pSMFData->streams[i].midiStream.jetData |= MIDI_FLAGS_JET_MUTE;
- else
- pSMFData->streams[i].midiStream.jetData &= ~MIDI_FLAGS_JET_MUTE;
- bit >>= 1;
- }
- }
- break;
-
- /* set track mute */
- case PARSER_DATA_SET_MUTE:
- if (value < pSMFData->numStreams)
- pSMFData->streams[value].midiStream.jetData |= MIDI_FLAGS_JET_MUTE;
- else
- return EAS_ERROR_PARAMETER_RANGE;
- break;
-
- /* clear track mute */
- case PARSER_DATA_CLEAR_MUTE:
- if (value < pSMFData->numStreams)
- pSMFData->streams[value].midiStream.jetData &= ~MIDI_FLAGS_JET_MUTE;
- else
- return EAS_ERROR_PARAMETER_RANGE;
- break;
-#endif
-
- default:
- return EAS_ERROR_INVALID_PARAMETER;
- }
-
- return EAS_SUCCESS;
+ /* set jet segment and track ID of all tracks for callback function */
+ case PARSER_DATA_JET_CB:
+ {
+ EAS_U32 i;
+ EAS_U32 bit = (EAS_U32) value;
+ bit = (bit << JET_EVENT_SEG_SHIFT) & JET_EVENT_SEG_MASK;
+ for (i = 0; i < pSMFData->numStreams; i++)
+ pSMFData->streams[i].midiStream.jetData =
+ (pSMFData->streams[i].midiStream.jetData &
+ ~(JET_EVENT_TRACK_MASK | JET_EVENT_SEG_MASK)) |
+ i << JET_EVENT_TRACK_SHIFT | bit | MIDI_FLAGS_JET_CB;
+ pSMFData->flags |= SMF_FLAGS_JET_STREAM;
+ }
+ break;
+
+ /* set state of all mute flags at once */
+ case PARSER_DATA_MUTE_FLAGS:
+ {
+ EAS_INT i;
+ EAS_U32 bit = (EAS_U32) value;
+ for (i = 0; i < pSMFData->numStreams; i++)
+ {
+ if (bit & 1)
+ pSMFData->streams[i].midiStream.jetData |= MIDI_FLAGS_JET_MUTE;
+ else
+ pSMFData->streams[i].midiStream.jetData &= ~MIDI_FLAGS_JET_MUTE;
+ bit >>= 1;
+ }
+ }
+ break;
+
+ /* set track mute */
+ case PARSER_DATA_SET_MUTE:
+ if (value < pSMFData->numStreams)
+ pSMFData->streams[value].midiStream.jetData |= MIDI_FLAGS_JET_MUTE;
+ else
+ return EAS_ERROR_PARAMETER_RANGE;
+ break;
+
+ /* clear track mute */
+ case PARSER_DATA_CLEAR_MUTE:
+ if (value < pSMFData->numStreams)
+ pSMFData->streams[value].midiStream.jetData &= ~MIDI_FLAGS_JET_MUTE;
+ else
+ return EAS_ERROR_PARAMETER_RANGE;
+ break;
+#endif
+
+ default:
+ return EAS_ERROR_INVALID_PARAMETER;
+ }
+
+ return EAS_SUCCESS;
}
/*----------------------------------------------------------------------------
* SMF_GetData()
*----------------------------------------------------------------------------
- * Purpose:
+ * Purpose:
* Retrieves parser parameters
*
* Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
* Outputs:
- *
+ *
*
* Side Effects:
*
@@ -687,61 +687,61 @@ EAS_RESULT SMF_SetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 pa
/*lint -esym(715, pEASData) reserved for future use */
EAS_RESULT SMF_GetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue)
{
- S_SMF_DATA *pSMFData;
-
- pSMFData = (S_SMF_DATA*) pInstData;
- switch (param)
- {
- /* return file type */
- case PARSER_DATA_FILE_TYPE:
- if (pSMFData->numStreams == 1)
- *pValue = EAS_FILE_SMF0;
- else
- *pValue = EAS_FILE_SMF1;
- break;
+ S_SMF_DATA *pSMFData;
+
+ pSMFData = (S_SMF_DATA*) pInstData;
+ switch (param)
+ {
+ /* return file type */
+ case PARSER_DATA_FILE_TYPE:
+ if (pSMFData->numStreams == 1)
+ *pValue = EAS_FILE_SMF0;
+ else
+ *pValue = EAS_FILE_SMF1;
+ break;
/* now handled in eas_public.c */
-#if 0
- case PARSER_DATA_POLYPHONY:
- if (pSMFData->pSynth)
- VMGetPolyphony(pEASData->pVoiceMgr, pSMFData->pSynth, pValue);
- else
- return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
- break;
-
- case PARSER_DATA_PRIORITY:
- if (pSMFData->pSynth)
- VMGetPriority(pEASData->pVoiceMgr, pSMFData->pSynth, pValue);
- break;
-
- /* set transposition */
- case PARSER_DATA_TRANSPOSITION:
- *pValue = pSMFData->transposition;
- break;
+#if 0
+ case PARSER_DATA_POLYPHONY:
+ if (pSMFData->pSynth)
+ VMGetPolyphony(pEASData->pVoiceMgr, pSMFData->pSynth, pValue);
+ else
+ return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
+ break;
+
+ case PARSER_DATA_PRIORITY:
+ if (pSMFData->pSynth)
+ VMGetPriority(pEASData->pVoiceMgr, pSMFData->pSynth, pValue);
+ break;
+
+ /* set transposition */
+ case PARSER_DATA_TRANSPOSITION:
+ *pValue = pSMFData->transposition;
+ break;
#endif
- case PARSER_DATA_SYNTH_HANDLE:
- *pValue = (EAS_I32) pSMFData->pSynth;
- break;
-
- default:
- return EAS_ERROR_INVALID_PARAMETER;
- }
-
- return EAS_SUCCESS;
+ case PARSER_DATA_SYNTH_HANDLE:
+ *pValue = (EAS_I32) pSMFData->pSynth;
+ break;
+
+ default:
+ return EAS_ERROR_INVALID_PARAMETER;
+ }
+
+ return EAS_SUCCESS;
}
/*----------------------------------------------------------------------------
* SMF_GetVarLenData()
*----------------------------------------------------------------------------
- * Purpose:
+ * Purpose:
* Reads a varible length quantity from an SMF file
*
* Inputs:
- *
- *
+ *
+ *
* Outputs:
- *
+ *
*
* Side Effects:
*
@@ -749,33 +749,33 @@ EAS_RESULT SMF_GetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 pa
*/
static EAS_RESULT SMF_GetVarLenData (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE fileHandle, EAS_U32 *pData)
{
- EAS_RESULT result;
- EAS_U32 data;
- EAS_U8 c;
-
- /* read until bit 7 is zero */
- data = 0;
- do
- {
- if ((result = EAS_HWGetByte(hwInstData, fileHandle,&c)) != EAS_SUCCESS)
- return result;
- data = (data << 7) | (c & 0x7f);
- } while (c & 0x80);
- *pData = data;
- return EAS_SUCCESS;
+ EAS_RESULT result;
+ EAS_U32 data;
+ EAS_U8 c;
+
+ /* read until bit 7 is zero */
+ data = 0;
+ do
+ {
+ if ((result = EAS_HWGetByte(hwInstData, fileHandle,&c)) != EAS_SUCCESS)
+ return result;
+ data = (data << 7) | (c & 0x7f);
+ } while (c & 0x80);
+ *pData = data;
+ return EAS_SUCCESS;
}
/*----------------------------------------------------------------------------
* SMF_GetDeltaTime()
*----------------------------------------------------------------------------
- * Purpose:
+ * Purpose:
* Reads a varible length quantity from an SMF file
*
* Inputs:
- *
- *
+ *
+ *
* Outputs:
- *
+ *
*
* Side Effects:
*
@@ -783,27 +783,27 @@ static EAS_RESULT SMF_GetVarLenData (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HAN
*/
static EAS_RESULT SMF_GetDeltaTime (EAS_HW_DATA_HANDLE hwInstData, S_SMF_STREAM *pSMFStream)
{
- EAS_RESULT result;
- EAS_U32 ticks;
+ EAS_RESULT result;
+ EAS_U32 ticks;
- if ((result = SMF_GetVarLenData(hwInstData, pSMFStream->fileHandle, &ticks)) != EAS_SUCCESS)
- return result;
+ if ((result = SMF_GetVarLenData(hwInstData, pSMFStream->fileHandle, &ticks)) != EAS_SUCCESS)
+ return result;
- pSMFStream->ticks += ticks;
- return EAS_SUCCESS;
+ pSMFStream->ticks += ticks;
+ return EAS_SUCCESS;
}
/*----------------------------------------------------------------------------
* SMF_ParseMetaEvent()
*----------------------------------------------------------------------------
- * Purpose:
+ * Purpose:
* Reads a varible length quantity from an SMF file
*
* Inputs:
- *
- *
+ *
+ *
* Outputs:
- *
+ *
*
* Side Effects:
*
@@ -811,103 +811,103 @@ static EAS_RESULT SMF_GetDeltaTime (EAS_HW_DATA_HANDLE hwInstData, S_SMF_STREAM
*/
static EAS_RESULT SMF_ParseMetaEvent (S_EAS_DATA *pEASData, S_SMF_DATA *pSMFData, S_SMF_STREAM *pSMFStream)
{
- EAS_RESULT result;
- EAS_U32 len;
- EAS_I32 pos;
- EAS_U32 temp;
- EAS_U8 c;
-
- /* get the meta-event type */
- if ((result = EAS_HWGetByte(pEASData->hwInstData, pSMFStream->fileHandle, &c)) != EAS_SUCCESS)
- return result;
-
- /* get the length */
- if ((result = SMF_GetVarLenData(pEASData->hwInstData, pSMFStream->fileHandle, &len)) != EAS_SUCCESS)
- return result;
-
- /* get the current file position so we can skip the event */
- if ((result = EAS_HWFilePos(pEASData->hwInstData, pSMFStream->fileHandle, &pos)) != EAS_SUCCESS)
- return result;
- pos += (EAS_I32) len;
-
- /* end of track? */
- if (c == SMF_META_END_OF_TRACK)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Meta-event: end of track\n", c, len); */ }
- pSMFStream->ticks = SMF_END_OF_TRACK;
- }
-
- /* tempo event? */
- else if (c == SMF_META_TEMPO)
- {
- /* read the 3-byte timebase value */
- temp = 0;
- while (len--)
- {
- if ((result = EAS_HWGetByte(pEASData->hwInstData, pSMFStream->fileHandle, &c)) != EAS_SUCCESS)
- return result;
- temp = (temp << 8) | c;
- }
-
- pSMFData->tickConv = (EAS_U16) (((temp * 1024) / pSMFData->ppqn + 500) / 1000);
- pSMFData->flags |= SMF_FLAGS_HAS_TEMPO;
- }
-
- /* check for time signature - see iMelody spec V1.4 section 4.1.2.2.3.6 */
- else if (c == SMF_META_TIME_SIGNATURE)
- {
- pSMFData->flags |= SMF_FLAGS_HAS_TIME_SIG;
- }
-
- /* if the host has registered a metadata callback return the metadata */
- else if (pSMFData->metadata.callback)
- {
- EAS_I32 readLen;
- E_EAS_METADATA_TYPE metaType;
-
- metaType = EAS_METADATA_UNKNOWN;
-
- /* only process title on the first track */
- if (c == SMF_META_SEQTRK_NAME)
- metaType = EAS_METADATA_TITLE;
- else if (c == SMF_META_TEXT)
- metaType = EAS_METADATA_TEXT;
- else if (c == SMF_META_COPYRIGHT)
- metaType = EAS_METADATA_COPYRIGHT;
- else if (c == SMF_META_LYRIC)
- metaType = EAS_METADATA_LYRIC;
-
- if (metaType != EAS_METADATA_UNKNOWN)
- {
- readLen = pSMFData->metadata.bufferSize - 1;
- if ((EAS_I32) len < readLen)
- readLen = (EAS_I32) len;
- if ((result = EAS_HWReadFile(pEASData->hwInstData, pSMFStream->fileHandle, pSMFData->metadata.buffer, readLen, &readLen)) != EAS_SUCCESS)
- return result;
- pSMFData->metadata.buffer[readLen] = 0;
- pSMFData->metadata.callback(metaType, pSMFData->metadata.buffer, pSMFData->metadata.pUserData);
- }
- }
-
- /* position file to next event - in case we ignored all or part of the meta-event */
- if ((result = EAS_HWFileSeek(pEASData->hwInstData, pSMFStream->fileHandle, pos)) != EAS_SUCCESS)
- return result;
-
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Meta-event: type=%02x, len=%d\n", c, len); */ }
- return EAS_SUCCESS;
+ EAS_RESULT result;
+ EAS_U32 len;
+ EAS_I32 pos;
+ EAS_U32 temp;
+ EAS_U8 c;
+
+ /* get the meta-event type */
+ if ((result = EAS_HWGetByte(pEASData->hwInstData, pSMFStream->fileHandle, &c)) != EAS_SUCCESS)
+ return result;
+
+ /* get the length */
+ if ((result = SMF_GetVarLenData(pEASData->hwInstData, pSMFStream->fileHandle, &len)) != EAS_SUCCESS)
+ return result;
+
+ /* get the current file position so we can skip the event */
+ if ((result = EAS_HWFilePos(pEASData->hwInstData, pSMFStream->fileHandle, &pos)) != EAS_SUCCESS)
+ return result;
+ pos += (EAS_I32) len;
+
+ /* end of track? */
+ if (c == SMF_META_END_OF_TRACK)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Meta-event: end of track\n", c, len); */ }
+ pSMFStream->ticks = SMF_END_OF_TRACK;
+ }
+
+ /* tempo event? */
+ else if (c == SMF_META_TEMPO)
+ {
+ /* read the 3-byte timebase value */
+ temp = 0;
+ while (len--)
+ {
+ if ((result = EAS_HWGetByte(pEASData->hwInstData, pSMFStream->fileHandle, &c)) != EAS_SUCCESS)
+ return result;
+ temp = (temp << 8) | c;
+ }
+
+ pSMFData->tickConv = (EAS_U16) (((temp * 1024) / pSMFData->ppqn + 500) / 1000);
+ pSMFData->flags |= SMF_FLAGS_HAS_TEMPO;
+ }
+
+ /* check for time signature - see iMelody spec V1.4 section 4.1.2.2.3.6 */
+ else if (c == SMF_META_TIME_SIGNATURE)
+ {
+ pSMFData->flags |= SMF_FLAGS_HAS_TIME_SIG;
+ }
+
+ /* if the host has registered a metadata callback return the metadata */
+ else if (pSMFData->metadata.callback)
+ {
+ EAS_I32 readLen;
+ E_EAS_METADATA_TYPE metaType;
+
+ metaType = EAS_METADATA_UNKNOWN;
+
+ /* only process title on the first track */
+ if (c == SMF_META_SEQTRK_NAME)
+ metaType = EAS_METADATA_TITLE;
+ else if (c == SMF_META_TEXT)
+ metaType = EAS_METADATA_TEXT;
+ else if (c == SMF_META_COPYRIGHT)
+ metaType = EAS_METADATA_COPYRIGHT;
+ else if (c == SMF_META_LYRIC)
+ metaType = EAS_METADATA_LYRIC;
+
+ if (metaType != EAS_METADATA_UNKNOWN)
+ {
+ readLen = pSMFData->metadata.bufferSize - 1;
+ if ((EAS_I32) len < readLen)
+ readLen = (EAS_I32) len;
+ if ((result = EAS_HWReadFile(pEASData->hwInstData, pSMFStream->fileHandle, pSMFData->metadata.buffer, readLen, &readLen)) != EAS_SUCCESS)
+ return result;
+ pSMFData->metadata.buffer[readLen] = 0;
+ pSMFData->metadata.callback(metaType, pSMFData->metadata.buffer, pSMFData->metadata.pUserData);
+ }
+ }
+
+ /* position file to next event - in case we ignored all or part of the meta-event */
+ if ((result = EAS_HWFileSeek(pEASData->hwInstData, pSMFStream->fileHandle, pos)) != EAS_SUCCESS)
+ return result;
+
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Meta-event: type=%02x, len=%d\n", c, len); */ }
+ return EAS_SUCCESS;
}
/*----------------------------------------------------------------------------
* SMF_ParseSysEx()
*----------------------------------------------------------------------------
- * Purpose:
+ * Purpose:
* Reads a varible length quantity from an SMF file
*
* Inputs:
- *
- *
+ *
+ *
* Outputs:
- *
+ *
*
* Side Effects:
*
@@ -915,48 +915,48 @@ static EAS_RESULT SMF_ParseMetaEvent (S_EAS_DATA *pEASData, S_SMF_DATA *pSMFData
*/
static EAS_RESULT SMF_ParseSysEx (S_EAS_DATA *pEASData, S_SMF_DATA *pSMFData, S_SMF_STREAM *pSMFStream, EAS_U8 f0, EAS_INT parserMode)
{
- EAS_RESULT result;
- EAS_U32 len;
- EAS_U8 c;
-
- /* get the length */
- if ((result = SMF_GetVarLenData(pEASData->hwInstData, pSMFStream->fileHandle, &len)) != EAS_SUCCESS)
- return result;
-
- /* start of SysEx message? */
- if (f0 == 0xf0)
- {
- if ((result = EAS_ParseMIDIStream(pEASData, pSMFData->pSynth, &pSMFStream->midiStream, f0, parserMode)) != EAS_SUCCESS)
- return result;
- }
-
- /* feed the SysEx to the stream parser */
- while (len--)
- {
- if ((result = EAS_HWGetByte(pEASData->hwInstData, pSMFStream->fileHandle, &c)) != EAS_SUCCESS)
- return result;
- if ((result = EAS_ParseMIDIStream(pEASData, pSMFData->pSynth, &pSMFStream->midiStream, c, parserMode)) != EAS_SUCCESS)
- return result;
-
- /* check for GM system ON */
- if (pSMFStream->midiStream.flags & MIDI_FLAG_GM_ON)
- pSMFData->flags |= SMF_FLAGS_HAS_GM_ON;
- }
-
- return EAS_SUCCESS;
+ EAS_RESULT result;
+ EAS_U32 len;
+ EAS_U8 c;
+
+ /* get the length */
+ if ((result = SMF_GetVarLenData(pEASData->hwInstData, pSMFStream->fileHandle, &len)) != EAS_SUCCESS)
+ return result;
+
+ /* start of SysEx message? */
+ if (f0 == 0xf0)
+ {
+ if ((result = EAS_ParseMIDIStream(pEASData, pSMFData->pSynth, &pSMFStream->midiStream, f0, parserMode)) != EAS_SUCCESS)
+ return result;
+ }
+
+ /* feed the SysEx to the stream parser */
+ while (len--)
+ {
+ if ((result = EAS_HWGetByte(pEASData->hwInstData, pSMFStream->fileHandle, &c)) != EAS_SUCCESS)
+ return result;
+ if ((result = EAS_ParseMIDIStream(pEASData, pSMFData->pSynth, &pSMFStream->midiStream, c, parserMode)) != EAS_SUCCESS)
+ return result;
+
+ /* check for GM system ON */
+ if (pSMFStream->midiStream.flags & MIDI_FLAG_GM_ON)
+ pSMFData->flags |= SMF_FLAGS_HAS_GM_ON;
+ }
+
+ return EAS_SUCCESS;
}
/*----------------------------------------------------------------------------
* SMF_ParseEvent()
*----------------------------------------------------------------------------
- * Purpose:
+ * Purpose:
* Reads a varible length quantity from an SMF file
*
* Inputs:
- *
- *
+ *
+ *
* Outputs:
- *
+ *
*
* Side Effects:
*
@@ -964,75 +964,75 @@ static EAS_RESULT SMF_ParseSysEx (S_EAS_DATA *pEASData, S_SMF_DATA *pSMFData, S_
*/
static EAS_RESULT SMF_ParseEvent (S_EAS_DATA *pEASData, S_SMF_DATA *pSMFData, S_SMF_STREAM *pSMFStream, EAS_INT parserMode)
{
- EAS_RESULT result;
- EAS_U8 c;
-
- /* get the event type */
- if ((result = EAS_HWGetByte(pEASData->hwInstData, pSMFStream->fileHandle, &c)) != EAS_SUCCESS)
- return result;
-
- /* parse meta-event */
- if (c == 0xff)
- {
- if ((result = SMF_ParseMetaEvent(pEASData, pSMFData, pSMFStream)) != EAS_SUCCESS)
- return result;
- }
-
- /* parse SysEx */
- else if ((c == 0xf0) || (c == 0xf7))
- {
- if ((result = SMF_ParseSysEx(pEASData, pSMFData, pSMFStream, c, parserMode)) != EAS_SUCCESS)
- return result;
- }
-
- /* parse MIDI message */
- else
- {
- if ((result = EAS_ParseMIDIStream(pEASData, pSMFData->pSynth, &pSMFStream->midiStream, c, parserMode)) != EAS_SUCCESS)
- return result;
-
- /* keep streaming data to the MIDI parser until the message is complete */
- while (pSMFStream->midiStream.pending)
- {
- if ((result = EAS_HWGetByte(pEASData->hwInstData, pSMFStream->fileHandle, &c)) != EAS_SUCCESS)
- return result;
- if ((result = EAS_ParseMIDIStream(pEASData, pSMFData->pSynth, &pSMFStream->midiStream, c, parserMode)) != EAS_SUCCESS)
- return result;
- }
-
- }
-
- /* chase mode logic */
- if (pSMFData->time == 0)
- {
- if (pSMFData->flags & SMF_FLAGS_CHASE_MODE)
- {
- if (pSMFStream->midiStream.flags & MIDI_FLAG_FIRST_NOTE)
- pSMFData->flags &= ~SMF_FLAGS_CHASE_MODE;
- }
- else if ((pSMFData->flags & SMF_FLAGS_SETUP_BAR) == SMF_FLAGS_SETUP_BAR)
- pSMFData->flags = (pSMFData->flags & ~SMF_FLAGS_SETUP_BAR) | SMF_FLAGS_CHASE_MODE;
- }
-
- return EAS_SUCCESS;
+ EAS_RESULT result;
+ EAS_U8 c;
+
+ /* get the event type */
+ if ((result = EAS_HWGetByte(pEASData->hwInstData, pSMFStream->fileHandle, &c)) != EAS_SUCCESS)
+ return result;
+
+ /* parse meta-event */
+ if (c == 0xff)
+ {
+ if ((result = SMF_ParseMetaEvent(pEASData, pSMFData, pSMFStream)) != EAS_SUCCESS)
+ return result;
+ }
+
+ /* parse SysEx */
+ else if ((c == 0xf0) || (c == 0xf7))
+ {
+ if ((result = SMF_ParseSysEx(pEASData, pSMFData, pSMFStream, c, parserMode)) != EAS_SUCCESS)
+ return result;
+ }
+
+ /* parse MIDI message */
+ else
+ {
+ if ((result = EAS_ParseMIDIStream(pEASData, pSMFData->pSynth, &pSMFStream->midiStream, c, parserMode)) != EAS_SUCCESS)
+ return result;
+
+ /* keep streaming data to the MIDI parser until the message is complete */
+ while (pSMFStream->midiStream.pending)
+ {
+ if ((result = EAS_HWGetByte(pEASData->hwInstData, pSMFStream->fileHandle, &c)) != EAS_SUCCESS)
+ return result;
+ if ((result = EAS_ParseMIDIStream(pEASData, pSMFData->pSynth, &pSMFStream->midiStream, c, parserMode)) != EAS_SUCCESS)
+ return result;
+ }
+
+ }
+
+ /* chase mode logic */
+ if (pSMFData->time == 0)
+ {
+ if (pSMFData->flags & SMF_FLAGS_CHASE_MODE)
+ {
+ if (pSMFStream->midiStream.flags & MIDI_FLAG_FIRST_NOTE)
+ pSMFData->flags &= ~SMF_FLAGS_CHASE_MODE;
+ }
+ else if ((pSMFData->flags & SMF_FLAGS_SETUP_BAR) == SMF_FLAGS_SETUP_BAR)
+ pSMFData->flags = (pSMFData->flags & ~SMF_FLAGS_SETUP_BAR) | SMF_FLAGS_CHASE_MODE;
+ }
+
+ return EAS_SUCCESS;
}
/*----------------------------------------------------------------------------
* SMF_ParseHeader()
*----------------------------------------------------------------------------
- * Purpose:
+ * Purpose:
* Parses the header of an SMF file, allocates memory the stream parsers and initializes the
* stream parsers.
*
* Inputs:
- * pEASData - pointer to overall EAS data structure
- * pSMFData - pointer to parser instance data
- * fileHandle - file handle
- * fileOffset - offset in the file where the header data starts, usually 0
- *
- *
+ * pEASData - pointer to overall EAS data structure
+ * pSMFData - pointer to parser instance data
+ * fileHandle - file handle
+ * fileOffset - offset in the file where the header data starts, usually 0
+ *
+ *
* Outputs:
- *
+ *
*
* Side Effects:
*
@@ -1041,153 +1041,153 @@ static EAS_RESULT SMF_ParseEvent (S_EAS_DATA *pEASData, S_SMF_DATA *pSMFData, S_
/*lint -e{801} we know that 'goto' is deprecated - but it's cleaner in this case */
EAS_RESULT SMF_ParseHeader (EAS_HW_DATA_HANDLE hwInstData, S_SMF_DATA *pSMFData)
{
- EAS_RESULT result;
- EAS_I32 i;
- EAS_U16 division;
- EAS_U32 chunkSize;
- EAS_U32 chunkStart;
- EAS_U32 temp;
- EAS_U32 ticks;
-
- /* rewind the file and find the end of the header chunk */
- if ((result = EAS_HWFileSeek(hwInstData, pSMFData->fileHandle, pSMFData->fileOffset + SMF_OFS_HEADER_SIZE)) != EAS_SUCCESS)
- goto ReadError;
- if ((result = EAS_HWGetDWord(hwInstData, pSMFData->fileHandle, &chunkSize, EAS_TRUE)) != EAS_SUCCESS)
- goto ReadError;
-
- /* determine the number of tracks */
- if ((result = EAS_HWFileSeek(hwInstData, pSMFData->fileHandle, pSMFData->fileOffset + SMF_OFS_NUM_TRACKS)) != EAS_SUCCESS)
- goto ReadError;
- if ((result = EAS_HWGetWord(hwInstData, pSMFData->fileHandle, &pSMFData->numStreams, EAS_TRUE)) != EAS_SUCCESS)
- goto ReadError;
-
- /* limit the number of tracks */
- if (pSMFData->numStreams > MAX_SMF_STREAMS)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "SMF file contains %u tracks, playing %d tracks\n", pSMFData->numStreams, MAX_SMF_STREAMS); */ }
- pSMFData->numStreams = MAX_SMF_STREAMS;
- } else if (pSMFData->numStreams == 0)
- {
- /* avoid 0 sized allocation */
- return EAS_ERROR_PARAMETER_RANGE;
- }
-
- /* get the time division */
- if ((result = EAS_HWGetWord(hwInstData, pSMFData->fileHandle, &division, EAS_TRUE)) != EAS_SUCCESS)
- goto ReadError;
-
- /* setup default timebase for 120 bpm */
- pSMFData->ppqn = 192;
- if (!division || division & 0x8000)
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING,"No support for SMPTE code timebase\n"); */ }
- else
- pSMFData->ppqn = (division & 0x7fff);
- pSMFData->tickConv = (EAS_U16) (((SMF_DEFAULT_TIMEBASE * 1024) / pSMFData->ppqn + 500) / 1000);
-
- /* dynamic memory allocation, allocate memory for streams */
- if (pSMFData->streams == NULL)
- {
- pSMFData->streams = EAS_HWMalloc(hwInstData,sizeof(S_SMF_STREAM) * pSMFData->numStreams);
- if (pSMFData->streams == NULL)
- return EAS_ERROR_MALLOC_FAILED;
-
- /* zero the memory to insure complete initialization */
- EAS_HWMemSet((void *)(pSMFData->streams), 0, sizeof(S_SMF_STREAM) * pSMFData->numStreams);
- }
-
- /* find the start of each track */
- chunkStart = (EAS_U32) pSMFData->fileOffset;
- ticks = 0x7fffffffL;
- pSMFData->nextStream = NULL;
- for (i = 0; i < pSMFData->numStreams; i++)
- {
-
- for (;;)
- {
-
- /* calculate start of next chunk - checking for errors */
- temp = chunkStart + SMF_CHUNK_INFO_SIZE + chunkSize;
- if (temp <= chunkStart)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING,"Error in chunk size at offset %d\n", chunkStart); */ }
- return EAS_ERROR_FILE_FORMAT;
- }
- chunkStart = temp;
-
- /* seek to the start of the next chunk */
- if ((result = EAS_HWFileSeek(hwInstData, pSMFData->fileHandle, (EAS_I32) chunkStart)) != EAS_SUCCESS)
- goto ReadError;
-
- /* read the chunk identifier */
- if ((result = EAS_HWGetDWord(hwInstData, pSMFData->fileHandle, &temp, EAS_TRUE)) != EAS_SUCCESS)
- goto ReadError;
-
- /* read the chunk size */
- if ((result = EAS_HWGetDWord(hwInstData, pSMFData->fileHandle, &chunkSize, EAS_TRUE)) != EAS_SUCCESS)
- goto ReadError;
-
- /* make sure this is an 'MTrk' chunk */
- if (temp == SMF_CHUNK_TYPE_TRACK)
- break;
-
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING,"Unexpected chunk type: 0x%08x\n", temp); */ }
- }
-
- /* initalize some data */
- pSMFData->streams[i].ticks = 0;
- pSMFData->streams[i].fileHandle = pSMFData->fileHandle;
-
- /* NULL the file handle so we don't try to close it twice */
- pSMFData->fileHandle = NULL;
-
- /* save this file position as the start of the track */
- pSMFData->streams[i].startFilePos = (EAS_I32) chunkStart + SMF_CHUNK_INFO_SIZE;
-
- /* initalize the MIDI parser data */
- EAS_InitMIDIStream(&pSMFData->streams[i].midiStream);
-
- /* parse the first delta time in each stream */
- if ((result = SMF_GetDeltaTime(hwInstData, &pSMFData->streams[i])) != EAS_SUCCESS)
- goto ReadError;
-
- if (pSMFData->streams[i].ticks < ticks)
- {
- ticks = pSMFData->streams[i].ticks;
- pSMFData->nextStream = &pSMFData->streams[i];
- }
-
- /* more tracks to do, create a duplicate file handle */
- if (i < (pSMFData->numStreams - 1))
- {
- if ((result = EAS_HWDupHandle(hwInstData, pSMFData->streams[i].fileHandle, &pSMFData->fileHandle)) != EAS_SUCCESS)
- goto ReadError;
- }
- }
-
- /* update the time of the next event */
- if (pSMFData->nextStream)
- SMF_UpdateTime(pSMFData, pSMFData->nextStream->ticks);
-
- return EAS_SUCCESS;
-
- /* ugly goto: but simpler than structured */
- ReadError:
- if (result == EAS_EOF)
- return EAS_ERROR_FILE_FORMAT;
- return result;
+ EAS_RESULT result;
+ EAS_I32 i;
+ EAS_U16 division;
+ EAS_U32 chunkSize;
+ EAS_U32 chunkStart;
+ EAS_U32 temp;
+ EAS_U32 ticks;
+
+ /* rewind the file and find the end of the header chunk */
+ if ((result = EAS_HWFileSeek(hwInstData, pSMFData->fileHandle, pSMFData->fileOffset + SMF_OFS_HEADER_SIZE)) != EAS_SUCCESS)
+ goto ReadError;
+ if ((result = EAS_HWGetDWord(hwInstData, pSMFData->fileHandle, &chunkSize, EAS_TRUE)) != EAS_SUCCESS)
+ goto ReadError;
+
+ /* determine the number of tracks */
+ if ((result = EAS_HWFileSeek(hwInstData, pSMFData->fileHandle, pSMFData->fileOffset + SMF_OFS_NUM_TRACKS)) != EAS_SUCCESS)
+ goto ReadError;
+ if ((result = EAS_HWGetWord(hwInstData, pSMFData->fileHandle, &pSMFData->numStreams, EAS_TRUE)) != EAS_SUCCESS)
+ goto ReadError;
+
+ /* limit the number of tracks */
+ if (pSMFData->numStreams > MAX_SMF_STREAMS)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "SMF file contains %u tracks, playing %d tracks\n", pSMFData->numStreams, MAX_SMF_STREAMS); */ }
+ pSMFData->numStreams = MAX_SMF_STREAMS;
+ } else if (pSMFData->numStreams == 0)
+ {
+ /* avoid 0 sized allocation */
+ return EAS_ERROR_PARAMETER_RANGE;
+ }
+
+ /* get the time division */
+ if ((result = EAS_HWGetWord(hwInstData, pSMFData->fileHandle, &division, EAS_TRUE)) != EAS_SUCCESS)
+ goto ReadError;
+
+ /* setup default timebase for 120 bpm */
+ pSMFData->ppqn = 192;
+ if (!division || division & 0x8000)
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING,"No support for SMPTE code timebase\n"); */ }
+ else
+ pSMFData->ppqn = (division & 0x7fff);
+ pSMFData->tickConv = (EAS_U16) (((SMF_DEFAULT_TIMEBASE * 1024) / pSMFData->ppqn + 500) / 1000);
+
+ /* dynamic memory allocation, allocate memory for streams */
+ if (pSMFData->streams == NULL)
+ {
+ pSMFData->streams = EAS_HWMalloc(hwInstData,sizeof(S_SMF_STREAM) * pSMFData->numStreams);
+ if (pSMFData->streams == NULL)
+ return EAS_ERROR_MALLOC_FAILED;
+
+ /* zero the memory to insure complete initialization */
+ EAS_HWMemSet((void *)(pSMFData->streams), 0, sizeof(S_SMF_STREAM) * pSMFData->numStreams);
+ }
+
+ /* find the start of each track */
+ chunkStart = (EAS_U32) pSMFData->fileOffset;
+ ticks = 0x7fffffffL;
+ pSMFData->nextStream = NULL;
+ for (i = 0; i < pSMFData->numStreams; i++)
+ {
+
+ for (;;)
+ {
+
+ /* calculate start of next chunk - checking for errors */
+ temp = chunkStart + SMF_CHUNK_INFO_SIZE + chunkSize;
+ if (temp <= chunkStart)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING,"Error in chunk size at offset %d\n", chunkStart); */ }
+ return EAS_ERROR_FILE_FORMAT;
+ }
+ chunkStart = temp;
+
+ /* seek to the start of the next chunk */
+ if ((result = EAS_HWFileSeek(hwInstData, pSMFData->fileHandle, (EAS_I32) chunkStart)) != EAS_SUCCESS)
+ goto ReadError;
+
+ /* read the chunk identifier */
+ if ((result = EAS_HWGetDWord(hwInstData, pSMFData->fileHandle, &temp, EAS_TRUE)) != EAS_SUCCESS)
+ goto ReadError;
+
+ /* read the chunk size */
+ if ((result = EAS_HWGetDWord(hwInstData, pSMFData->fileHandle, &chunkSize, EAS_TRUE)) != EAS_SUCCESS)
+ goto ReadError;
+
+ /* make sure this is an 'MTrk' chunk */
+ if (temp == SMF_CHUNK_TYPE_TRACK)
+ break;
+
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING,"Unexpected chunk type: 0x%08x\n", temp); */ }
+ }
+
+ /* initalize some data */
+ pSMFData->streams[i].ticks = 0;
+ pSMFData->streams[i].fileHandle = pSMFData->fileHandle;
+
+ /* NULL the file handle so we don't try to close it twice */
+ pSMFData->fileHandle = NULL;
+
+ /* save this file position as the start of the track */
+ pSMFData->streams[i].startFilePos = (EAS_I32) chunkStart + SMF_CHUNK_INFO_SIZE;
+
+ /* initalize the MIDI parser data */
+ EAS_InitMIDIStream(&pSMFData->streams[i].midiStream);
+
+ /* parse the first delta time in each stream */
+ if ((result = SMF_GetDeltaTime(hwInstData, &pSMFData->streams[i])) != EAS_SUCCESS)
+ goto ReadError;
+
+ if (pSMFData->streams[i].ticks < ticks)
+ {
+ ticks = pSMFData->streams[i].ticks;
+ pSMFData->nextStream = &pSMFData->streams[i];
+ }
+
+ /* more tracks to do, create a duplicate file handle */
+ if (i < (pSMFData->numStreams - 1))
+ {
+ if ((result = EAS_HWDupHandle(hwInstData, pSMFData->streams[i].fileHandle, &pSMFData->fileHandle)) != EAS_SUCCESS)
+ goto ReadError;
+ }
+ }
+
+ /* update the time of the next event */
+ if (pSMFData->nextStream)
+ SMF_UpdateTime(pSMFData, pSMFData->nextStream->ticks);
+
+ return EAS_SUCCESS;
+
+ /* ugly goto: but simpler than structured */
+ ReadError:
+ if (result == EAS_EOF)
+ return EAS_ERROR_FILE_FORMAT;
+ return result;
}
/*----------------------------------------------------------------------------
* SMF_UpdateTime()
*----------------------------------------------------------------------------
- * Purpose:
+ * Purpose:
* Update the millisecond time base by converting the ticks into millieconds
*
* Inputs:
- *
- *
+ *
+ *
* Outputs:
- *
+ *
*
* Side Effects:
*
@@ -1195,13 +1195,13 @@ EAS_RESULT SMF_ParseHeader (EAS_HW_DATA_HANDLE hwInstData, S_SMF_DATA *pSMFData)
*/
static void SMF_UpdateTime (S_SMF_DATA *pSMFData, EAS_U32 ticks)
{
- EAS_U32 temp1, temp2;
-
- if (pSMFData->flags & SMF_FLAGS_CHASE_MODE)
- return;
-
- temp1 = (ticks >> 10) * pSMFData->tickConv;
- temp2 = (ticks & 0x3ff) * pSMFData->tickConv;
- pSMFData->time += (EAS_I32)((temp1 << 8) + (temp2 >> 2));
+ EAS_U32 temp1, temp2;
+
+ if (pSMFData->flags & SMF_FLAGS_CHASE_MODE)
+ return;
+
+ temp1 = (ticks >> 10) * pSMFData->tickConv;
+ temp2 = (ticks & 0x3ff) * pSMFData->tickConv;
+ pSMFData->time += (EAS_I32)((temp1 << 8) + (temp2 >> 2));
}
diff --git a/arm-wt-22k/lib_src/eas_smf.h b/arm-wt-22k/lib_src/eas_smf.h
index 9f66ab9..37c0790 100644
--- a/arm-wt-22k/lib_src/eas_smf.h
+++ b/arm-wt-22k/lib_src/eas_smf.h
@@ -1,12 +1,12 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_smf.h
- *
- * Contents and purpose:
- * SMF Type 0 and 1 File Parser
- *
- * Copyright Sonic Network Inc. 2005
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_smf.h
+ *
+ * Contents and purpose:
+ * SMF Type 0 and 1 File Parser
+ *
+ * Copyright Sonic Network Inc. 2005
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,31 +19,31 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 82 $
- * $Date: 2006-07-10 11:45:19 -0700 (Mon, 10 Jul 2006) $
- *----------------------------------------------------------------------------
-*/
-
-#ifndef _EAS_SMF_H
-#define _EAS_SMF_H
-
-/* prototypes for private interface to SMF parser */
-EAS_RESULT SMF_CheckFileType (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle, EAS_VOID_PTR *ppHandle, EAS_I32 offset);
-EAS_RESULT SMF_Prepare (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
-EAS_RESULT SMF_Time (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_U32 *pTime);
-EAS_RESULT SMF_Event (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_INT parserMode);
-EAS_RESULT SMF_State (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_STATE *pState);
-EAS_RESULT SMF_Close (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
-EAS_RESULT SMF_Reset (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
-EAS_RESULT SMF_Pause (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
-EAS_RESULT SMF_Resume (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
-EAS_RESULT SMF_SetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value);
-EAS_RESULT SMF_GetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue);
-EAS_RESULT SMF_ParseHeader (EAS_HW_DATA_HANDLE hwInstData, S_SMF_DATA *pSMFData);
-
-#endif /* end _EAS_SMF_H */
-
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 82 $
+ * $Date: 2006-07-10 11:45:19 -0700 (Mon, 10 Jul 2006) $
+ *----------------------------------------------------------------------------
+*/
+
+#ifndef _EAS_SMF_H
+#define _EAS_SMF_H
+
+/* prototypes for private interface to SMF parser */
+EAS_RESULT SMF_CheckFileType (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle, EAS_VOID_PTR *ppHandle, EAS_I32 offset);
+EAS_RESULT SMF_Prepare (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
+EAS_RESULT SMF_Time (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_U32 *pTime);
+EAS_RESULT SMF_Event (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_INT parserMode);
+EAS_RESULT SMF_State (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_STATE *pState);
+EAS_RESULT SMF_Close (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
+EAS_RESULT SMF_Reset (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
+EAS_RESULT SMF_Pause (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
+EAS_RESULT SMF_Resume (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
+EAS_RESULT SMF_SetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value);
+EAS_RESULT SMF_GetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue);
+EAS_RESULT SMF_ParseHeader (EAS_HW_DATA_HANDLE hwInstData, S_SMF_DATA *pSMFData);
+
+#endif /* end _EAS_SMF_H */
+
+
diff --git a/arm-wt-22k/lib_src/eas_smfdata.c b/arm-wt-22k/lib_src/eas_smfdata.c
index 5c27551..383d7f3 100644
--- a/arm-wt-22k/lib_src/eas_smfdata.c
+++ b/arm-wt-22k/lib_src/eas_smfdata.c
@@ -1,14 +1,14 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_smfdata.c
- *
- * Contents and purpose:
- * SMF File Parser
- *
- * This file contains data definitions for the SMF parser.
- *
- * Copyright Sonic Network Inc. 2005
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_smfdata.c
+ *
+ * Contents and purpose:
+ * SMF File Parser
+ *
+ * This file contains data definitions for the SMF parser.
+ *
+ * Copyright Sonic Network Inc. 2005
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,46 +21,46 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 778 $
- * $Date: 2007-07-23 16:45:17 -0700 (Mon, 23 Jul 2007) $
- *----------------------------------------------------------------------------
-*/
-
-#include "eas_miditypes.h"
-#include "eas_smfdata.h"
-
-/*----------------------------------------------------------------------------
- *
- * S_SMF_STREAM
- *
- * Static memory allocation for SMF parser
- *----------------------------------------------------------------------------
-*/
-static S_SMF_STREAM eas_SMFStreams[MAX_SMF_STREAMS];
-
-/*----------------------------------------------------------------------------
- *
- * eas_SMFData
- *
- * Static memory allocation for SMF parser
- *----------------------------------------------------------------------------
-*/
-S_SMF_DATA eas_SMFData =
-{
- eas_SMFStreams, /* pointer to individual streams in file */
- 0, /* pointer to next stream with event */
- 0, /* pointer to synth */
- 0, /* file handle */
- { 0, 0, 0, 0}, /* metadata callback */
- 0, /* file offset */
- 0, /* current time in milliseconds/256 */
- 0, /* actual number of streams */
- 0, /* current MIDI tick to msec conversion */
- 0, /* ticks per quarter note */
- 0, /* current state EAS_STATE_XXXX */
- 0 /* flags */
-};
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 778 $
+ * $Date: 2007-07-23 16:45:17 -0700 (Mon, 23 Jul 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+#include "eas_miditypes.h"
+#include "eas_smfdata.h"
+
+/*----------------------------------------------------------------------------
+ *
+ * S_SMF_STREAM
+ *
+ * Static memory allocation for SMF parser
+ *----------------------------------------------------------------------------
+*/
+static S_SMF_STREAM eas_SMFStreams[MAX_SMF_STREAMS];
+
+/*----------------------------------------------------------------------------
+ *
+ * eas_SMFData
+ *
+ * Static memory allocation for SMF parser
+ *----------------------------------------------------------------------------
+*/
+S_SMF_DATA eas_SMFData =
+{
+ eas_SMFStreams, /* pointer to individual streams in file */
+ 0, /* pointer to next stream with event */
+ 0, /* pointer to synth */
+ 0, /* file handle */
+ { 0, 0, 0, 0}, /* metadata callback */
+ 0, /* file offset */
+ 0, /* current time in milliseconds/256 */
+ 0, /* actual number of streams */
+ 0, /* current MIDI tick to msec conversion */
+ 0, /* ticks per quarter note */
+ 0, /* current state EAS_STATE_XXXX */
+ 0 /* flags */
+};
+
diff --git a/arm-wt-22k/lib_src/eas_smfdata.h b/arm-wt-22k/lib_src/eas_smfdata.h
index fcbe639..8f08839 100644
--- a/arm-wt-22k/lib_src/eas_smfdata.h
+++ b/arm-wt-22k/lib_src/eas_smfdata.h
@@ -1,14 +1,14 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_smfdata.h
- *
- * Contents and purpose:
- * SMF File Parser
- *
- * This file contains data definitions for the SMF parser.
- *
- * Copyright Sonic Network Inc. 2005
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_smfdata.h
+ *
+ * Contents and purpose:
+ * SMF File Parser
+ *
+ * This file contains data definitions for the SMF parser.
+ *
+ * Copyright Sonic Network Inc. 2005
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,46 +21,46 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 686 $
- * $Date: 2007-05-03 14:10:54 -0700 (Thu, 03 May 2007) $
- *----------------------------------------------------------------------------
-*/
-
-#ifndef _EAS_SMF_DATA_H
-#define _EAS_SMF_DATA_H
-
-#ifndef MAX_SMF_STREAMS
-#define MAX_SMF_STREAMS 128
-#endif
-
-/* offsets in to the SMF file */
-#define SMF_OFS_HEADER_SIZE 4
-#define SMF_OFS_FILE_TYPE 8
-#define SMF_OFS_NUM_TRACKS 10
-
-/* size of chunk info (chunk ID + chunk size) */
-#define SMF_CHUNK_INFO_SIZE 8
-
-/* 'MTrk' track chunk ID */
-#define SMF_CHUNK_TYPE_TRACK 0x4d54726bL
-
-/* some useful meta-events */
-#define SMF_META_TEXT 0x01
-#define SMF_META_COPYRIGHT 0x02
-#define SMF_META_SEQTRK_NAME 0x03
-#define SMF_META_LYRIC 0x05
-#define SMF_META_END_OF_TRACK 0x2f
-#define SMF_META_TEMPO 0x51
-#define SMF_META_TIME_SIGNATURE 0x58
-
-/* default timebase (120BPM) */
-#define SMF_DEFAULT_TIMEBASE 500000L
-
-/* value for pSMFStream->ticks to signify end of track */
-#define SMF_END_OF_TRACK 0xffffffff
-
-#endif
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 686 $
+ * $Date: 2007-05-03 14:10:54 -0700 (Thu, 03 May 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+#ifndef _EAS_SMF_DATA_H
+#define _EAS_SMF_DATA_H
+
+#ifndef MAX_SMF_STREAMS
+#define MAX_SMF_STREAMS 128
+#endif
+
+/* offsets in to the SMF file */
+#define SMF_OFS_HEADER_SIZE 4
+#define SMF_OFS_FILE_TYPE 8
+#define SMF_OFS_NUM_TRACKS 10
+
+/* size of chunk info (chunk ID + chunk size) */
+#define SMF_CHUNK_INFO_SIZE 8
+
+/* 'MTrk' track chunk ID */
+#define SMF_CHUNK_TYPE_TRACK 0x4d54726bL
+
+/* some useful meta-events */
+#define SMF_META_TEXT 0x01
+#define SMF_META_COPYRIGHT 0x02
+#define SMF_META_SEQTRK_NAME 0x03
+#define SMF_META_LYRIC 0x05
+#define SMF_META_END_OF_TRACK 0x2f
+#define SMF_META_TEMPO 0x51
+#define SMF_META_TIME_SIGNATURE 0x58
+
+/* default timebase (120BPM) */
+#define SMF_DEFAULT_TIMEBASE 500000L
+
+/* value for pSMFStream->ticks to signify end of track */
+#define SMF_END_OF_TRACK 0xffffffff
+
+#endif
+
diff --git a/arm-wt-22k/lib_src/eas_sndlib.h b/arm-wt-22k/lib_src/eas_sndlib.h
index e05bee0..416be6e 100644
--- a/arm-wt-22k/lib_src/eas_sndlib.h
+++ b/arm-wt-22k/lib_src/eas_sndlib.h
@@ -1,12 +1,12 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_sndlib.h
- *
- * Contents and purpose:
- * Declarations for the sound library
- *
- * Copyright Sonic Network Inc. 2005
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_sndlib.h
+ *
+ * Contents and purpose:
+ * Declarations for the sound library
+ *
+ * Copyright Sonic Network Inc. 2005
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,388 +19,388 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 550 $
- * $Date: 2007-02-02 09:37:03 -0800 (Fri, 02 Feb 2007) $
- *----------------------------------------------------------------------------
-*/
-
-#ifndef _EAS_SNDLIB_H
-#define _EAS_SNDLIB_H
-
-#include "eas_types.h"
-#include "eas_synthcfg.h"
-
-#ifdef _WT_SYNTH
-#include "eas_wtengine.h"
-#endif
-
-/*----------------------------------------------------------------------------
- * This is bit of a hack to allow us to keep the same structure
- * declarations for the DLS parser. Normally, the data is located
- * in read-only memory, but for DLS, we store the data in RW
- * memory.
- *----------------------------------------------------------------------------
-*/
-#ifndef SCNST
-#define SCNST const
-#endif
-
-/*----------------------------------------------------------------------------
- * sample size
- *----------------------------------------------------------------------------
-*/
-#ifdef _16_BIT_SAMPLES
-typedef EAS_I16 EAS_SAMPLE;
-#else
-typedef EAS_I8 EAS_SAMPLE;
-#endif
-
-/*----------------------------------------------------------------------------
- * EAS Library ID - quick check for valid library and version
- *----------------------------------------------------------------------------
-*/
-#define _EAS_LIBRARY_VERSION 0x01534145
-
-#define NUM_PROGRAMS_IN_BANK 128
-#define INVALID_REGION_INDEX 0xffff
-
-/* this bit in region index indicates that region is for secondary synth */
-#define FLAG_RGN_IDX_FM_SYNTH 0x8000
-#define FLAG_RGN_IDX_DLS_SYNTH 0x4000
-#define REGION_INDEX_MASK 0x3fff
-
-/*----------------------------------------------------------------------------
- * Generic region data structure
- *
- * This must be the first element in each region structure
- *----------------------------------------------------------------------------
-*/
-typedef struct s_region_tag
-{
- EAS_U16 keyGroupAndFlags;
- EAS_U8 rangeLow;
- EAS_U8 rangeHigh;
-} S_REGION;
-
-/*
- * Bit fields for m_nKeyGroupAndFlags
- * Bits 0-2 are mode bits in FM synth
- * Bits 8-11 are the key group
- */
-#define REGION_FLAG_IS_LOOPED 0x01
-#define REGION_FLAG_USE_WAVE_GENERATOR 0x02
-#define REGION_FLAG_USE_ADPCM 0x04
-#define REGION_FLAG_ONE_SHOT 0x08
-#define REGION_FLAG_SQUARE_WAVE 0x10
-#define REGION_FLAG_OFF_CHIP 0x20
-#define REGION_FLAG_NON_SELF_EXCLUSIVE 0x40
-#define REGION_FLAG_LAST_REGION 0x8000
-
-/*----------------------------------------------------------------------------
- * Envelope data structure
- *----------------------------------------------------------------------------
-*/
-typedef struct s_envelope_tag
-{
- EAS_I16 attackTime;
- EAS_I16 decayTime;
- EAS_I16 sustainLevel;
- EAS_I16 releaseTime;
-} S_ENVELOPE;
-
-/*----------------------------------------------------------------------------
- * DLS envelope data structure
- *----------------------------------------------------------------------------
-*/
-typedef struct s_dls_envelope_tag
-{
- EAS_I16 delayTime;
- EAS_I16 attackTime;
- EAS_I16 holdTime;
- EAS_I16 decayTime;
- EAS_I16 sustainLevel;
- EAS_I16 releaseTime;
- EAS_I16 velToAttack;
- EAS_I16 keyNumToDecay;
- EAS_I16 keyNumToHold;
-} S_DLS_ENVELOPE;
-
-/*----------------------------------------------------------------------------
- * LFO data structure
- *----------------------------------------------------------------------------
-*/
-typedef struct s_lfo_params_tag
-{
- EAS_I16 lfoFreq;
- EAS_I16 lfoDelay;
-} S_LFO_PARAMS;
-
-/*----------------------------------------------------------------------------
- * Articulation data structure
- *----------------------------------------------------------------------------
-*/
-typedef struct s_articulation_tag
-{
- S_ENVELOPE eg1;
- S_ENVELOPE eg2;
- EAS_I16 lfoToPitch;
- EAS_I16 lfoDelay;
- EAS_I16 lfoFreq;
- EAS_I16 eg2ToPitch;
- EAS_I16 eg2ToFc;
- EAS_I16 filterCutoff;
- EAS_I8 lfoToGain;
- EAS_U8 filterQ;
- EAS_I8 pan;
-} S_ARTICULATION;
-
-/*----------------------------------------------------------------------------
- * DLS articulation data structure
- *----------------------------------------------------------------------------
-*/
-
-typedef struct s_dls_articulation_tag
-{
- S_LFO_PARAMS modLFO;
- S_LFO_PARAMS vibLFO;
-
- S_DLS_ENVELOPE eg1;
- S_DLS_ENVELOPE eg2;
-
- EAS_I16 eg1ShutdownTime;
-
- EAS_I16 filterCutoff;
- EAS_I16 modLFOToFc;
- EAS_I16 modLFOCC1ToFc;
- EAS_I16 modLFOChanPressToFc;
- EAS_I16 eg2ToFc;
- EAS_I16 velToFc;
- EAS_I16 keyNumToFc;
-
- EAS_I16 modLFOToGain;
- EAS_I16 modLFOCC1ToGain;
- EAS_I16 modLFOChanPressToGain;
-
- EAS_I16 tuning;
- EAS_I16 keyNumToPitch;
- EAS_I16 vibLFOToPitch;
- EAS_I16 vibLFOCC1ToPitch;
- EAS_I16 vibLFOChanPressToPitch;
- EAS_I16 modLFOToPitch;
- EAS_I16 modLFOCC1ToPitch;
- EAS_I16 modLFOChanPressToPitch;
- EAS_I16 eg2ToPitch;
-
- /* pad to 4-byte boundary */
- EAS_U16 pad;
-
- EAS_I8 pan;
- EAS_U8 filterQandFlags;
-
-#ifdef _REVERB
- EAS_I16 reverbSend;
- EAS_I16 cc91ToReverbSend;
-#endif
-
-#ifdef _CHORUS
- EAS_I16 chorusSend;
- EAS_I16 cc93ToChorusSend;
-#endif
-} S_DLS_ARTICULATION;
-
-/* flags in filterQandFlags
- * NOTE: Q is stored in bottom 5 bits
- */
-#define FLAG_DLS_VELOCITY_SENSITIVE 0x80
-#define FILTER_Q_MASK 0x1f
-
-/*----------------------------------------------------------------------------
- * Wavetable region data structure
- *----------------------------------------------------------------------------
-*/
-typedef struct s_wt_region_tag
-{
- S_REGION region;
- EAS_I16 tuning;
- EAS_I16 gain;
- EAS_U32 loopStart;
- EAS_U32 loopEnd;
- EAS_U16 waveIndex;
- EAS_U16 artIndex;
-} S_WT_REGION;
-
-/*----------------------------------------------------------------------------
- * DLS region data structure
- *----------------------------------------------------------------------------
-*/
-typedef struct s_dls_region_tag
-{
- S_WT_REGION wtRegion;
- EAS_U8 velLow;
- EAS_U8 velHigh;
-} S_DLS_REGION;
-
-/*----------------------------------------------------------------------------
- * FM synthesizer data structures
- *----------------------------------------------------------------------------
-*/
-typedef struct s_fm_oper_tag
-{
- EAS_I16 tuning;
- EAS_U8 attackDecay;
- EAS_U8 velocityRelease;
- EAS_U8 egKeyScale;
- EAS_U8 sustain;
- EAS_U8 gain;
- EAS_U8 flags;
-} S_FM_OPER;
-
-/* defines for S_FM_OPER.m_nFlags */
-#define FM_OPER_FLAG_MONOTONE 0x01
-#define FM_OPER_FLAG_NO_VIBRATO 0x02
-#define FM_OPER_FLAG_NOISE 0x04
-#define FM_OPER_FLAG_LINEAR_VELOCITY 0x08
-
-/* NOTE: The first two structure elements are common with S_WT_REGION
- * and we will rely on that in the voice management code and must
- * remain there unless the voice management code is revisited.
- */
-typedef struct s_fm_region_tag
-{
- S_REGION region;
- EAS_U8 vibTrem;
- EAS_U8 lfoFreqDelay;
- EAS_U8 feedback;
- EAS_I8 pan;
- S_FM_OPER oper[4];
-} S_FM_REGION;
-
-/*----------------------------------------------------------------------------
- * Common data structures
- *----------------------------------------------------------------------------
-*/
-
-/*----------------------------------------------------------------------------
- * Program data structure
- * Used for individual programs not stored as a complete bank.
- *----------------------------------------------------------------------------
-*/
-typedef struct s_program_tag
-{
- EAS_U32 locale;
- EAS_U16 regionIndex;
-} S_PROGRAM;
-
-/*----------------------------------------------------------------------------
- * Bank data structure
- *
- * A bank always consists of 128 programs. If a bank is less than 128
- * programs, it should be stored as a spare matrix in the pPrograms
- * array.
- *
- * bankNum: MSB/LSB of MIDI bank select controller
- * regionIndex: Index of first region in program
- *----------------------------------------------------------------------------
-*/
-typedef struct s_bank_tag
-{
- EAS_U16 locale;
- EAS_U16 regionIndex[NUM_PROGRAMS_IN_BANK];
-} S_BANK;
-
-
-/* defines for libFormat field
- * bits 0-17 are the sample rate
- * bit 18 is true if wavetable is present
- * bit 19 is true if FM is present
- * bit 20 is true if filter is enabled
- * bit 21 is sample depth (0 = 8-bits, 1 = 16-bits)
- * bits 22-31 are reserved
- */
-#define LIBFORMAT_SAMPLE_RATE_MASK 0x0003ffff
-#define LIB_FORMAT_TYPE_MASK 0x000c0000
-#define LIB_FORMAT_WAVETABLE 0x00000000
-#define LIB_FORMAT_FM 0x00040000
-#define LIB_FORMAT_HYBRID 0x00080000
-#define LIB_FORMAT_FILTER_ENABLED 0x00100000
-#define LIB_FORMAT_16_BIT_SAMPLES 0x00200000
-
-#ifdef DLS_SYNTHESIZER
-/*----------------------------------------------------------------------------
- * DLS data structure
- *
- * pDLSPrograms pointer to array of DLS programs
- * pDLSRegions pointer to array of DLS regions
- * pDLSArticulations pointer to array of DLS articulations
- * pSampleLen pointer to array of sample lengths
- * ppSamples pointer to array of sample pointers
- * numDLSPrograms number of DLS programs
- * numDLSRegions number of DLS regions
- * numDLSArticulations number of DLS articulations
- * numDLSSamples number of DLS samples
- *----------------------------------------------------------------------------
-*/
-typedef struct s_eas_dls_tag
-{
- S_PROGRAM *pDLSPrograms;
- S_DLS_REGION *pDLSRegions;
- S_DLS_ARTICULATION *pDLSArticulations;
- EAS_U32 *pDLSSampleLen;
- EAS_U32 *pDLSSampleOffsets;
- EAS_SAMPLE *pDLSSamples;
- EAS_U16 numDLSPrograms;
- EAS_U16 numDLSRegions;
- EAS_U16 numDLSArticulations;
- EAS_U16 numDLSSamples;
- EAS_U8 refCount;
-} S_DLS;
-#endif
-
-/*----------------------------------------------------------------------------
- * Sound library data structure
- *
- * pBanks pointer to array of banks
- * pPrograms pointer to array of programs
- * pWTRegions pointer to array of wavetable regions
- * pFMRegions pointer to array of FM regions
- * pArticulations pointer to array of articulations
- * pSampleLen pointer to array of sample lengths
- * ppSamples pointer to array of sample pointers
- * numBanks number of banks
- * numPrograms number of individual program
- * numRegions number of regions
- * numArticulations number of articulations
- * numSamples number of samples
- *----------------------------------------------------------------------------
-*/
-typedef struct s_eas_sndlib_tag
-{
- SCNST EAS_U32 identifier;
- SCNST EAS_U32 libAttr;
-
- SCNST S_BANK *pBanks;
- SCNST S_PROGRAM *pPrograms;
-
- SCNST S_WT_REGION *pWTRegions;
- SCNST S_ARTICULATION *pArticulations;
- SCNST EAS_U32 *pSampleLen;
- SCNST EAS_U32 *pSampleOffsets;
- SCNST EAS_SAMPLE *pSamples;
-
- SCNST S_FM_REGION *pFMRegions;
-
- SCNST EAS_U16 numBanks;
- SCNST EAS_U16 numPrograms;
-
- SCNST EAS_U16 numWTRegions;
- SCNST EAS_U16 numArticulations;
- SCNST EAS_U16 numSamples;
-
- SCNST EAS_U16 numFMRegions;
-} S_EAS;
-
-#endif
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 550 $
+ * $Date: 2007-02-02 09:37:03 -0800 (Fri, 02 Feb 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+#ifndef _EAS_SNDLIB_H
+#define _EAS_SNDLIB_H
+
+#include "eas_types.h"
+#include "eas_synthcfg.h"
+
+#ifdef _WT_SYNTH
+#include "eas_wtengine.h"
+#endif
+
+/*----------------------------------------------------------------------------
+ * This is bit of a hack to allow us to keep the same structure
+ * declarations for the DLS parser. Normally, the data is located
+ * in read-only memory, but for DLS, we store the data in RW
+ * memory.
+ *----------------------------------------------------------------------------
+*/
+#ifndef SCNST
+#define SCNST const
+#endif
+
+/*----------------------------------------------------------------------------
+ * sample size
+ *----------------------------------------------------------------------------
+*/
+#ifdef _16_BIT_SAMPLES
+typedef EAS_I16 EAS_SAMPLE;
+#else
+typedef EAS_I8 EAS_SAMPLE;
+#endif
+
+/*----------------------------------------------------------------------------
+ * EAS Library ID - quick check for valid library and version
+ *----------------------------------------------------------------------------
+*/
+#define _EAS_LIBRARY_VERSION 0x01534145
+
+#define NUM_PROGRAMS_IN_BANK 128
+#define INVALID_REGION_INDEX 0xffff
+
+/* this bit in region index indicates that region is for secondary synth */
+#define FLAG_RGN_IDX_FM_SYNTH 0x8000
+#define FLAG_RGN_IDX_DLS_SYNTH 0x4000
+#define REGION_INDEX_MASK 0x3fff
+
+/*----------------------------------------------------------------------------
+ * Generic region data structure
+ *
+ * This must be the first element in each region structure
+ *----------------------------------------------------------------------------
+*/
+typedef struct s_region_tag
+{
+ EAS_U16 keyGroupAndFlags;
+ EAS_U8 rangeLow;
+ EAS_U8 rangeHigh;
+} S_REGION;
+
+/*
+ * Bit fields for m_nKeyGroupAndFlags
+ * Bits 0-2 are mode bits in FM synth
+ * Bits 8-11 are the key group
+ */
+#define REGION_FLAG_IS_LOOPED 0x01
+#define REGION_FLAG_USE_WAVE_GENERATOR 0x02
+#define REGION_FLAG_USE_ADPCM 0x04
+#define REGION_FLAG_ONE_SHOT 0x08
+#define REGION_FLAG_SQUARE_WAVE 0x10
+#define REGION_FLAG_OFF_CHIP 0x20
+#define REGION_FLAG_NON_SELF_EXCLUSIVE 0x40
+#define REGION_FLAG_LAST_REGION 0x8000
+
+/*----------------------------------------------------------------------------
+ * Envelope data structure
+ *----------------------------------------------------------------------------
+*/
+typedef struct s_envelope_tag
+{
+ EAS_I16 attackTime;
+ EAS_I16 decayTime;
+ EAS_I16 sustainLevel;
+ EAS_I16 releaseTime;
+} S_ENVELOPE;
+
+/*----------------------------------------------------------------------------
+ * DLS envelope data structure
+ *----------------------------------------------------------------------------
+*/
+typedef struct s_dls_envelope_tag
+{
+ EAS_I16 delayTime;
+ EAS_I16 attackTime;
+ EAS_I16 holdTime;
+ EAS_I16 decayTime;
+ EAS_I16 sustainLevel;
+ EAS_I16 releaseTime;
+ EAS_I16 velToAttack;
+ EAS_I16 keyNumToDecay;
+ EAS_I16 keyNumToHold;
+} S_DLS_ENVELOPE;
+
+/*----------------------------------------------------------------------------
+ * LFO data structure
+ *----------------------------------------------------------------------------
+*/
+typedef struct s_lfo_params_tag
+{
+ EAS_I16 lfoFreq;
+ EAS_I16 lfoDelay;
+} S_LFO_PARAMS;
+
+/*----------------------------------------------------------------------------
+ * Articulation data structure
+ *----------------------------------------------------------------------------
+*/
+typedef struct s_articulation_tag
+{
+ S_ENVELOPE eg1;
+ S_ENVELOPE eg2;
+ EAS_I16 lfoToPitch;
+ EAS_I16 lfoDelay;
+ EAS_I16 lfoFreq;
+ EAS_I16 eg2ToPitch;
+ EAS_I16 eg2ToFc;
+ EAS_I16 filterCutoff;
+ EAS_I8 lfoToGain;
+ EAS_U8 filterQ;
+ EAS_I8 pan;
+} S_ARTICULATION;
+
+/*----------------------------------------------------------------------------
+ * DLS articulation data structure
+ *----------------------------------------------------------------------------
+*/
+
+typedef struct s_dls_articulation_tag
+{
+ S_LFO_PARAMS modLFO;
+ S_LFO_PARAMS vibLFO;
+
+ S_DLS_ENVELOPE eg1;
+ S_DLS_ENVELOPE eg2;
+
+ EAS_I16 eg1ShutdownTime;
+
+ EAS_I16 filterCutoff;
+ EAS_I16 modLFOToFc;
+ EAS_I16 modLFOCC1ToFc;
+ EAS_I16 modLFOChanPressToFc;
+ EAS_I16 eg2ToFc;
+ EAS_I16 velToFc;
+ EAS_I16 keyNumToFc;
+
+ EAS_I16 modLFOToGain;
+ EAS_I16 modLFOCC1ToGain;
+ EAS_I16 modLFOChanPressToGain;
+
+ EAS_I16 tuning;
+ EAS_I16 keyNumToPitch;
+ EAS_I16 vibLFOToPitch;
+ EAS_I16 vibLFOCC1ToPitch;
+ EAS_I16 vibLFOChanPressToPitch;
+ EAS_I16 modLFOToPitch;
+ EAS_I16 modLFOCC1ToPitch;
+ EAS_I16 modLFOChanPressToPitch;
+ EAS_I16 eg2ToPitch;
+
+ /* pad to 4-byte boundary */
+ EAS_U16 pad;
+
+ EAS_I8 pan;
+ EAS_U8 filterQandFlags;
+
+#ifdef _REVERB
+ EAS_I16 reverbSend;
+ EAS_I16 cc91ToReverbSend;
+#endif
+
+#ifdef _CHORUS
+ EAS_I16 chorusSend;
+ EAS_I16 cc93ToChorusSend;
+#endif
+} S_DLS_ARTICULATION;
+
+/* flags in filterQandFlags
+ * NOTE: Q is stored in bottom 5 bits
+ */
+#define FLAG_DLS_VELOCITY_SENSITIVE 0x80
+#define FILTER_Q_MASK 0x1f
+
+/*----------------------------------------------------------------------------
+ * Wavetable region data structure
+ *----------------------------------------------------------------------------
+*/
+typedef struct s_wt_region_tag
+{
+ S_REGION region;
+ EAS_I16 tuning;
+ EAS_I16 gain;
+ EAS_U32 loopStart;
+ EAS_U32 loopEnd;
+ EAS_U16 waveIndex;
+ EAS_U16 artIndex;
+} S_WT_REGION;
+
+/*----------------------------------------------------------------------------
+ * DLS region data structure
+ *----------------------------------------------------------------------------
+*/
+typedef struct s_dls_region_tag
+{
+ S_WT_REGION wtRegion;
+ EAS_U8 velLow;
+ EAS_U8 velHigh;
+} S_DLS_REGION;
+
+/*----------------------------------------------------------------------------
+ * FM synthesizer data structures
+ *----------------------------------------------------------------------------
+*/
+typedef struct s_fm_oper_tag
+{
+ EAS_I16 tuning;
+ EAS_U8 attackDecay;
+ EAS_U8 velocityRelease;
+ EAS_U8 egKeyScale;
+ EAS_U8 sustain;
+ EAS_U8 gain;
+ EAS_U8 flags;
+} S_FM_OPER;
+
+/* defines for S_FM_OPER.m_nFlags */
+#define FM_OPER_FLAG_MONOTONE 0x01
+#define FM_OPER_FLAG_NO_VIBRATO 0x02
+#define FM_OPER_FLAG_NOISE 0x04
+#define FM_OPER_FLAG_LINEAR_VELOCITY 0x08
+
+/* NOTE: The first two structure elements are common with S_WT_REGION
+ * and we will rely on that in the voice management code and must
+ * remain there unless the voice management code is revisited.
+ */
+typedef struct s_fm_region_tag
+{
+ S_REGION region;
+ EAS_U8 vibTrem;
+ EAS_U8 lfoFreqDelay;
+ EAS_U8 feedback;
+ EAS_I8 pan;
+ S_FM_OPER oper[4];
+} S_FM_REGION;
+
+/*----------------------------------------------------------------------------
+ * Common data structures
+ *----------------------------------------------------------------------------
+*/
+
+/*----------------------------------------------------------------------------
+ * Program data structure
+ * Used for individual programs not stored as a complete bank.
+ *----------------------------------------------------------------------------
+*/
+typedef struct s_program_tag
+{
+ EAS_U32 locale;
+ EAS_U16 regionIndex;
+} S_PROGRAM;
+
+/*----------------------------------------------------------------------------
+ * Bank data structure
+ *
+ * A bank always consists of 128 programs. If a bank is less than 128
+ * programs, it should be stored as a spare matrix in the pPrograms
+ * array.
+ *
+ * bankNum: MSB/LSB of MIDI bank select controller
+ * regionIndex: Index of first region in program
+ *----------------------------------------------------------------------------
+*/
+typedef struct s_bank_tag
+{
+ EAS_U16 locale;
+ EAS_U16 regionIndex[NUM_PROGRAMS_IN_BANK];
+} S_BANK;
+
+
+/* defines for libFormat field
+ * bits 0-17 are the sample rate
+ * bit 18 is true if wavetable is present
+ * bit 19 is true if FM is present
+ * bit 20 is true if filter is enabled
+ * bit 21 is sample depth (0 = 8-bits, 1 = 16-bits)
+ * bits 22-31 are reserved
+ */
+#define LIBFORMAT_SAMPLE_RATE_MASK 0x0003ffff
+#define LIB_FORMAT_TYPE_MASK 0x000c0000
+#define LIB_FORMAT_WAVETABLE 0x00000000
+#define LIB_FORMAT_FM 0x00040000
+#define LIB_FORMAT_HYBRID 0x00080000
+#define LIB_FORMAT_FILTER_ENABLED 0x00100000
+#define LIB_FORMAT_16_BIT_SAMPLES 0x00200000
+
+#ifdef DLS_SYNTHESIZER
+/*----------------------------------------------------------------------------
+ * DLS data structure
+ *
+ * pDLSPrograms pointer to array of DLS programs
+ * pDLSRegions pointer to array of DLS regions
+ * pDLSArticulations pointer to array of DLS articulations
+ * pSampleLen pointer to array of sample lengths
+ * ppSamples pointer to array of sample pointers
+ * numDLSPrograms number of DLS programs
+ * numDLSRegions number of DLS regions
+ * numDLSArticulations number of DLS articulations
+ * numDLSSamples number of DLS samples
+ *----------------------------------------------------------------------------
+*/
+typedef struct s_eas_dls_tag
+{
+ S_PROGRAM *pDLSPrograms;
+ S_DLS_REGION *pDLSRegions;
+ S_DLS_ARTICULATION *pDLSArticulations;
+ EAS_U32 *pDLSSampleLen;
+ EAS_U32 *pDLSSampleOffsets;
+ EAS_SAMPLE *pDLSSamples;
+ EAS_U16 numDLSPrograms;
+ EAS_U16 numDLSRegions;
+ EAS_U16 numDLSArticulations;
+ EAS_U16 numDLSSamples;
+ EAS_U8 refCount;
+} S_DLS;
+#endif
+
+/*----------------------------------------------------------------------------
+ * Sound library data structure
+ *
+ * pBanks pointer to array of banks
+ * pPrograms pointer to array of programs
+ * pWTRegions pointer to array of wavetable regions
+ * pFMRegions pointer to array of FM regions
+ * pArticulations pointer to array of articulations
+ * pSampleLen pointer to array of sample lengths
+ * ppSamples pointer to array of sample pointers
+ * numBanks number of banks
+ * numPrograms number of individual program
+ * numRegions number of regions
+ * numArticulations number of articulations
+ * numSamples number of samples
+ *----------------------------------------------------------------------------
+*/
+typedef struct s_eas_sndlib_tag
+{
+ SCNST EAS_U32 identifier;
+ SCNST EAS_U32 libAttr;
+
+ SCNST S_BANK *pBanks;
+ SCNST S_PROGRAM *pPrograms;
+
+ SCNST S_WT_REGION *pWTRegions;
+ SCNST S_ARTICULATION *pArticulations;
+ SCNST EAS_U32 *pSampleLen;
+ SCNST EAS_U32 *pSampleOffsets;
+ SCNST EAS_SAMPLE *pSamples;
+
+ SCNST S_FM_REGION *pFMRegions;
+
+ SCNST EAS_U16 numBanks;
+ SCNST EAS_U16 numPrograms;
+
+ SCNST EAS_U16 numWTRegions;
+ SCNST EAS_U16 numArticulations;
+ SCNST EAS_U16 numSamples;
+
+ SCNST EAS_U16 numFMRegions;
+} S_EAS;
+
+#endif
+
diff --git a/arm-wt-22k/lib_src/eas_synth.h b/arm-wt-22k/lib_src/eas_synth.h
index b242b03..6274b7d 100644
--- a/arm-wt-22k/lib_src/eas_synth.h
+++ b/arm-wt-22k/lib_src/eas_synth.h
@@ -1,12 +1,12 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_synth.h
- *
- * Contents and purpose:
- * Declarations, interfaces, and prototypes for synth.
- *
- * Copyright Sonic Network Inc. 2004, 2005
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_synth.h
+ *
+ * Contents and purpose:
+ * Declarations, interfaces, and prototypes for synth.
+ *
+ * Copyright Sonic Network Inc. 2004, 2005
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,377 +19,377 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 718 $
- * $Date: 2007-06-08 16:43:16 -0700 (Fri, 08 Jun 2007) $
- *----------------------------------------------------------------------------
-*/
-
-#ifndef _EAS_SYNTH_H
-#define _EAS_SYNTH_H
-
-#include "eas_types.h"
-#include "eas_sndlib.h"
-
-#ifdef _WT_SYNTH
-#include "eas_wtsynth.h"
-#endif
-
-#ifdef _FM_SYNTH
-#include "eas_fmsynth.h"
-#endif
-
-#ifndef NUM_OUTPUT_CHANNELS
-#define NUM_OUTPUT_CHANNELS 2
-#endif
-
-#ifndef MAX_SYNTH_VOICES
-#define MAX_SYNTH_VOICES 64
-#endif
-
-#ifndef MAX_VIRTUAL_SYNTHESIZERS
-#define MAX_VIRTUAL_SYNTHESIZERS 4
-#endif
-
-/* defines */
-#ifndef NUM_PRIMARY_VOICES
-#define NUM_PRIMARY_VOICES MAX_SYNTH_VOICES
-#elif !defined(NUM_SECONDARY_VOICES)
-#define NUM_SECONDARY_VOICES (MAX_SYNTH_VOICES - NUM_PRIMARY_VOICES)
-#endif
-
-#if defined(EAS_WT_SYNTH)
-#define NUM_WT_VOICES MAX_SYNTH_VOICES
-
-/* FM on MCU */
-#elif defined(EAS_FM_SYNTH)
-#define NUM_FM_VOICES MAX_SYNTH_VOICES
-
-/* wavetable drums on MCU, wavetable melodic on DSP */
-#elif defined(EAS_SPLIT_WT_SYNTH)
-#define NUM_WT_VOICES MAX_SYNTH_VOICES
-
-/* wavetable drums and FM melodic on MCU */
-#elif defined(EAS_HYBRID_SYNTH)
-#define NUM_WT_VOICES NUM_PRIMARY_VOICES
-#define NUM_FM_VOICES NUM_SECONDARY_VOICES
-
-/* wavetable drums on MCU, FM melodic on DSP */
-#elif defined(EAS_SPLIT_HYBRID_SYNTH)
-#define NUM_WT_VOICES NUM_PRIMARY_VOICES
-#define NUM_FM_VOICES NUM_SECONDARY_VOICES
-
-/* FM synth on DSP */
-#elif defined(EAS_SPLIT_FM_SYNTH)
-#define NUM_FM_VOICES MAX_SYNTH_VOICES
-
-#else
-#error "Unrecognized architecture option"
-#endif
-
-#define NUM_SYNTH_CHANNELS 16
-
-#define DEFAULT_SYNTH_VOICES MAX_SYNTH_VOICES
-
-/* use the following values to specify unassigned channels or voices */
-#define UNASSIGNED_SYNTH_CHANNEL NUM_SYNTH_CHANNELS
-#define UNASSIGNED_SYNTH_VOICE MAX_SYNTH_VOICES
-
-
-/* synth parameters are updated every SYNTH_UPDATE_PERIOD_IN_SAMPLES */
-#define SYNTH_UPDATE_PERIOD_IN_SAMPLES (EAS_I32)(0x1L << SYNTH_UPDATE_PERIOD_IN_BITS)
-
-/* stealing weighting factors */
-#define NOTE_AGE_STEAL_WEIGHT 1
-#define NOTE_GAIN_STEAL_WEIGHT 4
-#define CHANNEL_POLY_STEAL_WEIGHT 12
-#define CHANNEL_PRIORITY_STEAL_WEIGHT 2
-#define NOTE_MATCH_PENALTY 128
-#define SYNTH_PRIORITY_WEIGHT 8
-
-/* default synth master volume */
-#define DEFAULT_SYNTH_MASTER_VOLUME 0x7fff
-
-#define DEFAULT_SYNTH_PRIORITY 5
-
-/* default tuning values */
-#define DEFAULT_PITCH_BEND_SENSITIVITY 200 /* 2 semitones */
-#define DEFAULT_FINE_PITCH 0 /* 0 cents */
-#define DEFAULT_COARSE_PITCH 0 /* 0 semitones */
-
-/* default drum channel is 10, but is internally 9 due to unit offset */
-#define DEFAULT_DRUM_CHANNEL 9
-
-/* drum channel can simultaneously play this many voices at most */
-#define DEFAULT_CHANNEL_POLYPHONY_LIMIT 2
-
-/* default instrument is acoustic piano */
-#define DEFAULT_MELODY_BANK_MSB 0x79
-#define DEFAULT_RHYTHM_BANK_MSB 0x78
-#define DEFAULT_MELODY_BANK_NUMBER (DEFAULT_MELODY_BANK_MSB << 8)
-#define DEFAULT_RHYTHM_BANK_NUMBER (DEFAULT_RHYTHM_BANK_MSB << 8)
-#define DEFAULT_SYNTH_PROGRAM_NUMBER 0
-
-#define DEFAULT_PITCH_BEND 0x2000 /* 0x2000 == (0x40 << 7) | 0x00 */
-#define DEFAULT_MOD_WHEEL 0
-#define DEFAULT_CHANNEL_VOLUME 0x64
-#define DEFAULT_PAN 0x40 /* decimal 64, center */
-
-#ifdef _REVERB
-#define DEFAULT_REVERB_SEND 40 /* some reverb */
-#endif
-
-#ifdef _CHORUS
-#define DEFAULT_CHORUS_SEND 0 /* no chorus */
-#endif
-
-#define DEFAULT_EAS_FILTER_CUTOFF_FREQUENCY 0 /* EAS synth uses a different default */
-#define DEFAULT_FILTER_RESONANCE 0
-#define DEFAULT_EXPRESSION 0x7F
-
-#define DEFAULT_CHANNEL_PRESSURE 0
-
-#define DEFAULT_REGISTERED_PARAM 0x3FFF
-
-#define DEFAULT_CHANNEL_STATIC_GAIN 0
-#define DEFAULT_CHANNEL_STATIC_PITCH 0
-
-#define DEFAULT_LFO_MOD_WHEEL_TO_PITCH_CENTS 50
-#define DEFAULT_LFO_CHANNEL_PRESSURE_TO_PITCH_CENTS 50
-
-#define DEFAULT_KEY_NUMBER 0x69
-#define DEFAULT_VELOCITY 0x64
-#define DEFAULT_REGION_INDEX 0
-#define DEFAULT_ARTICULATION_INDEX 0
-#define DEFAULT_VOICE_GAIN 0
-#define DEFAULT_AGE 0
-#define DEFAULT_SP_MIDI_PRIORITY 16
-
-
-/* filter defines */
-#define DEFAULT_FILTER_ZERO 0
-#define FILTER_CUTOFF_MAX_PITCH_CENTS 1919
-#define FILTER_CUTOFF_MIN_PITCH_CENTS -4467
-#define A5_PITCH_OFFSET_IN_CENTS 6900
-
-/*------------------------------------
- * S_SYNTH_CHANNEL data structure
- *------------------------------------
-*/
-
-/* S_SYNTH_CHANNEL.m_nFlags */
-#define CHANNEL_FLAG_SUSTAIN_PEDAL 0x01
-#define CHANNEL_FLAG_MUTE 0x02
-#define CHANNEL_FLAG_UPDATE_CHANNEL_PARAMETERS 0x04
-#define CHANNEL_FLAG_RHYTHM_CHANNEL 0x08
-#define CHANNEL_FLAG_EXTERNAL_AUDIO 0x10
-#define DEFAULT_CHANNEL_FLAGS 0
-
-/* macros for extracting virtual synth and channel numbers */
-#define GET_VSYNTH(a) ((a) >> 4)
-#define GET_CHANNEL(a) ((a) & 15)
-
-typedef struct s_synth_channel_tag
-{
- /* use static channel parameters to reduce MIPs */
- /* parameters shared by multiple voices assigned to same channel */
- EAS_I32 staticPitch; /* (pitch bend * pitch sens) + fine pitch */
- EAS_I16 staticGain; /* (CC7 * CC11 * master vol)^2 */
-
- EAS_U16 regionIndex; /* index of first region in program */
-
- EAS_U16 bankNum; /* play programs from this bank */
- EAS_I16 pitchBend; /* pitch wheel value */
- EAS_I16 pitchBendSensitivity;
- EAS_I16 registeredParam; /* currently selected registered param */
-
-
-#if defined(_FM_SYNTH)
- EAS_I16 lfoAmt; /* amount of LFO to apply to voice */
-#endif
-
- EAS_U8 programNum; /* play this instrument number */
- EAS_U8 modWheel; /* CC1 */
- EAS_U8 volume; /* CC7 */
- EAS_U8 pan; /* CC10 */
-
- EAS_U8 expression; /* CC11 */
-
- /* the following parameters are controlled by RPNs */
- EAS_I8 finePitch;
- EAS_I8 coarsePitch;
-
- EAS_U8 channelPressure; /* applied to all voices on a given channel */
-
- EAS_U8 channelFlags; /* bit field channelFlags for */
- /* CC64, SP-MIDI channel masking */
-
- EAS_U8 pool; /* SPMIDI channel voice pool */
- EAS_U8 mip; /* SPMIDI MIP setting */
-
-#ifdef _REVERB
- EAS_U8 reverbSend; /* CC91 */
-#endif
-
-#ifdef _CHORUS
- EAS_U8 chorusSend; /* CC93 */
-#endif
-} S_SYNTH_CHANNEL;
-
-/*------------------------------------
- * S_SYNTH_VOICE data structure
- *------------------------------------
-*/
-
-/* S_SYNTH_VOICE.m_nFlags */
-#define VOICE_FLAG_UPDATE_VOICE_PARAMETERS 0x01
-#define VOICE_FLAG_SUSTAIN_PEDAL_DEFER_NOTE_OFF 0x02
-#define VOICE_FLAG_DEFER_MIDI_NOTE_OFF 0x04
-#define VOICE_FLAG_NO_SAMPLES_SYNTHESIZED_YET 0x08
-#define VOICE_FLAG_DEFER_MUTE 0x40
-#define DEFAULT_VOICE_FLAGS 0
-
-/* S_SYNTH_VOICE.m_eState */
-typedef enum {
-
- eVoiceStateFree = 0,
- eVoiceStateStart,
- eVoiceStatePlay,
- eVoiceStateRelease,
- eVoiceStateMuting,
- eVoiceStateStolen,
- eVoiceStateInvalid /* should never be in this state! */
-
-} E_VOICE_STATE;
-#define DEFAULT_VOICE_STATE eVoiceStateFree
-
-typedef struct s_synth_voice_tag
-{
-
-/* These parameters are common to both wavetable and FM
- * synthesizers. The voice manager should only access this data.
- * Any other data should be manipulated by the code that is
- * specific to that synthesizer and reflected back through the
- * common state data available here.
- */
- EAS_U16 regionIndex; /* index to wave and playback params */
- EAS_I16 gain; /* current gain */
- EAS_U16 age; /* large value means old note */
- EAS_U16 nextRegionIndex; /* index to wave and playback params */
- EAS_U8 voiceState; /* current voice state */
- EAS_U8 voiceFlags; /* misc flags/bit fields */
- EAS_U8 channel; /* this voice plays on this synth channel */
- EAS_U8 note; /* 12 <= key number <= 108 */
- EAS_U8 velocity; /* 0 <= velocity <= 127 */
- EAS_U8 nextChannel; /* play stolen voice on this channel */
- EAS_U8 nextNote; /* 12 <= key number <= 108 */
- EAS_U8 nextVelocity; /* 0 <= velocity <= 127 */
-} S_SYNTH_VOICE;
-
-/*------------------------------------
- * S_SYNTH data structure
- *
- * One instance for each MIDI stream
- *------------------------------------
-*/
-
-/* S_SYNTH.m_nFlags */
-#define SYNTH_FLAG_RESET_IS_REQUESTED 0x01
-#define SYNTH_FLAG_SP_MIDI_ON 0x02
-#define SYNTH_FLAG_UPDATE_ALL_CHANNEL_PARAMETERS 0x04
-#define SYNTH_FLAG_DEFERRED_MIDI_NOTE_OFF_PENDING 0x08
-#define DEFAULT_SYNTH_FLAGS SYNTH_FLAG_UPDATE_ALL_CHANNEL_PARAMETERS
-
-typedef struct s_synth_tag
-{
- struct s_eas_data_tag *pEASData;
- const S_EAS *pEAS;
-
-#ifdef DLS_SYNTHESIZER
- S_DLS *pDLS;
-#endif
-
-#ifdef EXTERNAL_AUDIO
- EAS_EXT_PRG_CHG_FUNC cbProgChgFunc;
- EAS_EXT_EVENT_FUNC cbEventFunc;
- EAS_VOID_PTR *pExtAudioInstData;
-#endif
-
- S_SYNTH_CHANNEL channels[NUM_SYNTH_CHANNELS];
- EAS_I32 totalNoteCount;
- EAS_U16 maxPolyphony;
- EAS_U16 numActiveVoices;
- EAS_U16 masterVolume;
- EAS_U8 channelsByPriority[NUM_SYNTH_CHANNELS];
- EAS_U8 poolCount[NUM_SYNTH_CHANNELS];
- EAS_U8 poolAlloc[NUM_SYNTH_CHANNELS];
- EAS_U8 synthFlags;
- EAS_I8 globalTranspose;
- EAS_U8 vSynthNum;
- EAS_U8 refCount;
- EAS_U8 priority;
-} S_SYNTH;
-
-/*------------------------------------
- * S_VOICE_MGR data structure
- *
- * One instance for each EAS library instance
- *------------------------------------
-*/
-typedef struct s_voice_mgr_tag
-{
- S_SYNTH *pSynth[MAX_VIRTUAL_SYNTHESIZERS];
- EAS_PCM voiceBuffer[SYNTH_UPDATE_PERIOD_IN_SAMPLES];
-
-#ifdef _FM_SYNTH
- EAS_PCM operMixBuffer[SYNTH_UPDATE_PERIOD_IN_SAMPLES];
- S_FM_VOICE fmVoices[NUM_FM_VOICES];
-#endif
-
-#ifdef _WT_SYNTH
- S_WT_VOICE wtVoices[NUM_WT_VOICES];
-#endif
-
-#ifdef _REVERB
- EAS_PCM reverbSendBuffer[NUM_OUTPUT_CHANNELS * SYNTH_UPDATE_PERIOD_IN_SAMPLES];
-#endif
-
-#ifdef _CHORUS
- EAS_PCM chorusSendBuffer[NUM_OUTPUT_CHANNELS * SYNTH_UPDATE_PERIOD_IN_SAMPLES];
-#endif
- S_SYNTH_VOICE voices[MAX_SYNTH_VOICES];
-
- EAS_SNDLIB_HANDLE pGlobalEAS;
-
-#ifdef DLS_SYNTHESIZER
- S_DLS *pGlobalDLS;
-#endif
-
-#ifdef _SPLIT_ARCHITECTURE
- EAS_FRAME_BUFFER_HANDLE pFrameBuffer;
-#endif
-
-#if defined(_SECONDARY_SYNTH) || defined(EAS_SPLIT_WT_SYNTH)
- EAS_U16 maxPolyphonyPrimary;
- EAS_U16 maxPolyphonySecondary;
-#endif
-
- EAS_I32 workload;
- EAS_I32 maxWorkLoad;
-
- EAS_U16 activeVoices;
- EAS_U16 maxPolyphony;
-
- EAS_U16 age;
-
-/* limits the number of voice starts in a frame for split architecture */
-#ifdef MAX_VOICE_STARTS
- EAS_U16 numVoiceStarts;
-#endif
-} S_VOICE_MGR;
-
-#endif /* #ifdef _EAS_SYNTH_H */
-
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 718 $
+ * $Date: 2007-06-08 16:43:16 -0700 (Fri, 08 Jun 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+#ifndef _EAS_SYNTH_H
+#define _EAS_SYNTH_H
+
+#include "eas_types.h"
+#include "eas_sndlib.h"
+
+#ifdef _WT_SYNTH
+#include "eas_wtsynth.h"
+#endif
+
+#ifdef _FM_SYNTH
+#include "eas_fmsynth.h"
+#endif
+
+#ifndef NUM_OUTPUT_CHANNELS
+#define NUM_OUTPUT_CHANNELS 2
+#endif
+
+#ifndef MAX_SYNTH_VOICES
+#define MAX_SYNTH_VOICES 64
+#endif
+
+#ifndef MAX_VIRTUAL_SYNTHESIZERS
+#define MAX_VIRTUAL_SYNTHESIZERS 4
+#endif
+
+/* defines */
+#ifndef NUM_PRIMARY_VOICES
+#define NUM_PRIMARY_VOICES MAX_SYNTH_VOICES
+#elif !defined(NUM_SECONDARY_VOICES)
+#define NUM_SECONDARY_VOICES (MAX_SYNTH_VOICES - NUM_PRIMARY_VOICES)
+#endif
+
+#if defined(EAS_WT_SYNTH)
+#define NUM_WT_VOICES MAX_SYNTH_VOICES
+
+/* FM on MCU */
+#elif defined(EAS_FM_SYNTH)
+#define NUM_FM_VOICES MAX_SYNTH_VOICES
+
+/* wavetable drums on MCU, wavetable melodic on DSP */
+#elif defined(EAS_SPLIT_WT_SYNTH)
+#define NUM_WT_VOICES MAX_SYNTH_VOICES
+
+/* wavetable drums and FM melodic on MCU */
+#elif defined(EAS_HYBRID_SYNTH)
+#define NUM_WT_VOICES NUM_PRIMARY_VOICES
+#define NUM_FM_VOICES NUM_SECONDARY_VOICES
+
+/* wavetable drums on MCU, FM melodic on DSP */
+#elif defined(EAS_SPLIT_HYBRID_SYNTH)
+#define NUM_WT_VOICES NUM_PRIMARY_VOICES
+#define NUM_FM_VOICES NUM_SECONDARY_VOICES
+
+/* FM synth on DSP */
+#elif defined(EAS_SPLIT_FM_SYNTH)
+#define NUM_FM_VOICES MAX_SYNTH_VOICES
+
+#else
+#error "Unrecognized architecture option"
+#endif
+
+#define NUM_SYNTH_CHANNELS 16
+
+#define DEFAULT_SYNTH_VOICES MAX_SYNTH_VOICES
+
+/* use the following values to specify unassigned channels or voices */
+#define UNASSIGNED_SYNTH_CHANNEL NUM_SYNTH_CHANNELS
+#define UNASSIGNED_SYNTH_VOICE MAX_SYNTH_VOICES
+
+
+/* synth parameters are updated every SYNTH_UPDATE_PERIOD_IN_SAMPLES */
+#define SYNTH_UPDATE_PERIOD_IN_SAMPLES (EAS_I32)(0x1L << SYNTH_UPDATE_PERIOD_IN_BITS)
+
+/* stealing weighting factors */
+#define NOTE_AGE_STEAL_WEIGHT 1
+#define NOTE_GAIN_STEAL_WEIGHT 4
+#define CHANNEL_POLY_STEAL_WEIGHT 12
+#define CHANNEL_PRIORITY_STEAL_WEIGHT 2
+#define NOTE_MATCH_PENALTY 128
+#define SYNTH_PRIORITY_WEIGHT 8
+
+/* default synth master volume */
+#define DEFAULT_SYNTH_MASTER_VOLUME 0x7fff
+
+#define DEFAULT_SYNTH_PRIORITY 5
+
+/* default tuning values */
+#define DEFAULT_PITCH_BEND_SENSITIVITY 200 /* 2 semitones */
+#define DEFAULT_FINE_PITCH 0 /* 0 cents */
+#define DEFAULT_COARSE_PITCH 0 /* 0 semitones */
+
+/* default drum channel is 10, but is internally 9 due to unit offset */
+#define DEFAULT_DRUM_CHANNEL 9
+
+/* drum channel can simultaneously play this many voices at most */
+#define DEFAULT_CHANNEL_POLYPHONY_LIMIT 2
+
+/* default instrument is acoustic piano */
+#define DEFAULT_MELODY_BANK_MSB 0x79
+#define DEFAULT_RHYTHM_BANK_MSB 0x78
+#define DEFAULT_MELODY_BANK_NUMBER (DEFAULT_MELODY_BANK_MSB << 8)
+#define DEFAULT_RHYTHM_BANK_NUMBER (DEFAULT_RHYTHM_BANK_MSB << 8)
+#define DEFAULT_SYNTH_PROGRAM_NUMBER 0
+
+#define DEFAULT_PITCH_BEND 0x2000 /* 0x2000 == (0x40 << 7) | 0x00 */
+#define DEFAULT_MOD_WHEEL 0
+#define DEFAULT_CHANNEL_VOLUME 0x64
+#define DEFAULT_PAN 0x40 /* decimal 64, center */
+
+#ifdef _REVERB
+#define DEFAULT_REVERB_SEND 40 /* some reverb */
+#endif
+
+#ifdef _CHORUS
+#define DEFAULT_CHORUS_SEND 0 /* no chorus */
+#endif
+
+#define DEFAULT_EAS_FILTER_CUTOFF_FREQUENCY 0 /* EAS synth uses a different default */
+#define DEFAULT_FILTER_RESONANCE 0
+#define DEFAULT_EXPRESSION 0x7F
+
+#define DEFAULT_CHANNEL_PRESSURE 0
+
+#define DEFAULT_REGISTERED_PARAM 0x3FFF
+
+#define DEFAULT_CHANNEL_STATIC_GAIN 0
+#define DEFAULT_CHANNEL_STATIC_PITCH 0
+
+#define DEFAULT_LFO_MOD_WHEEL_TO_PITCH_CENTS 50
+#define DEFAULT_LFO_CHANNEL_PRESSURE_TO_PITCH_CENTS 50
+
+#define DEFAULT_KEY_NUMBER 0x69
+#define DEFAULT_VELOCITY 0x64
+#define DEFAULT_REGION_INDEX 0
+#define DEFAULT_ARTICULATION_INDEX 0
+#define DEFAULT_VOICE_GAIN 0
+#define DEFAULT_AGE 0
+#define DEFAULT_SP_MIDI_PRIORITY 16
+
+
+/* filter defines */
+#define DEFAULT_FILTER_ZERO 0
+#define FILTER_CUTOFF_MAX_PITCH_CENTS 1919
+#define FILTER_CUTOFF_MIN_PITCH_CENTS -4467
+#define A5_PITCH_OFFSET_IN_CENTS 6900
+
+/*------------------------------------
+ * S_SYNTH_CHANNEL data structure
+ *------------------------------------
+*/
+
+/* S_SYNTH_CHANNEL.m_nFlags */
+#define CHANNEL_FLAG_SUSTAIN_PEDAL 0x01
+#define CHANNEL_FLAG_MUTE 0x02
+#define CHANNEL_FLAG_UPDATE_CHANNEL_PARAMETERS 0x04
+#define CHANNEL_FLAG_RHYTHM_CHANNEL 0x08
+#define CHANNEL_FLAG_EXTERNAL_AUDIO 0x10
+#define DEFAULT_CHANNEL_FLAGS 0
+
+/* macros for extracting virtual synth and channel numbers */
+#define GET_VSYNTH(a) ((a) >> 4)
+#define GET_CHANNEL(a) ((a) & 15)
+
+typedef struct s_synth_channel_tag
+{
+ /* use static channel parameters to reduce MIPs */
+ /* parameters shared by multiple voices assigned to same channel */
+ EAS_I32 staticPitch; /* (pitch bend * pitch sens) + fine pitch */
+ EAS_I16 staticGain; /* (CC7 * CC11 * master vol)^2 */
+
+ EAS_U16 regionIndex; /* index of first region in program */
+
+ EAS_U16 bankNum; /* play programs from this bank */
+ EAS_I16 pitchBend; /* pitch wheel value */
+ EAS_I16 pitchBendSensitivity;
+ EAS_I16 registeredParam; /* currently selected registered param */
+
+
+#if defined(_FM_SYNTH)
+ EAS_I16 lfoAmt; /* amount of LFO to apply to voice */
+#endif
+
+ EAS_U8 programNum; /* play this instrument number */
+ EAS_U8 modWheel; /* CC1 */
+ EAS_U8 volume; /* CC7 */
+ EAS_U8 pan; /* CC10 */
+
+ EAS_U8 expression; /* CC11 */
+
+ /* the following parameters are controlled by RPNs */
+ EAS_I8 finePitch;
+ EAS_I8 coarsePitch;
+
+ EAS_U8 channelPressure; /* applied to all voices on a given channel */
+
+ EAS_U8 channelFlags; /* bit field channelFlags for */
+ /* CC64, SP-MIDI channel masking */
+
+ EAS_U8 pool; /* SPMIDI channel voice pool */
+ EAS_U8 mip; /* SPMIDI MIP setting */
+
+#ifdef _REVERB
+ EAS_U8 reverbSend; /* CC91 */
+#endif
+
+#ifdef _CHORUS
+ EAS_U8 chorusSend; /* CC93 */
+#endif
+} S_SYNTH_CHANNEL;
+
+/*------------------------------------
+ * S_SYNTH_VOICE data structure
+ *------------------------------------
+*/
+
+/* S_SYNTH_VOICE.m_nFlags */
+#define VOICE_FLAG_UPDATE_VOICE_PARAMETERS 0x01
+#define VOICE_FLAG_SUSTAIN_PEDAL_DEFER_NOTE_OFF 0x02
+#define VOICE_FLAG_DEFER_MIDI_NOTE_OFF 0x04
+#define VOICE_FLAG_NO_SAMPLES_SYNTHESIZED_YET 0x08
+#define VOICE_FLAG_DEFER_MUTE 0x40
+#define DEFAULT_VOICE_FLAGS 0
+
+/* S_SYNTH_VOICE.m_eState */
+typedef enum {
+
+ eVoiceStateFree = 0,
+ eVoiceStateStart,
+ eVoiceStatePlay,
+ eVoiceStateRelease,
+ eVoiceStateMuting,
+ eVoiceStateStolen,
+ eVoiceStateInvalid /* should never be in this state! */
+
+} E_VOICE_STATE;
+#define DEFAULT_VOICE_STATE eVoiceStateFree
+
+typedef struct s_synth_voice_tag
+{
+
+/* These parameters are common to both wavetable and FM
+ * synthesizers. The voice manager should only access this data.
+ * Any other data should be manipulated by the code that is
+ * specific to that synthesizer and reflected back through the
+ * common state data available here.
+ */
+ EAS_U16 regionIndex; /* index to wave and playback params */
+ EAS_I16 gain; /* current gain */
+ EAS_U16 age; /* large value means old note */
+ EAS_U16 nextRegionIndex; /* index to wave and playback params */
+ EAS_U8 voiceState; /* current voice state */
+ EAS_U8 voiceFlags; /* misc flags/bit fields */
+ EAS_U8 channel; /* this voice plays on this synth channel */
+ EAS_U8 note; /* 12 <= key number <= 108 */
+ EAS_U8 velocity; /* 0 <= velocity <= 127 */
+ EAS_U8 nextChannel; /* play stolen voice on this channel */
+ EAS_U8 nextNote; /* 12 <= key number <= 108 */
+ EAS_U8 nextVelocity; /* 0 <= velocity <= 127 */
+} S_SYNTH_VOICE;
+
+/*------------------------------------
+ * S_SYNTH data structure
+ *
+ * One instance for each MIDI stream
+ *------------------------------------
+*/
+
+/* S_SYNTH.m_nFlags */
+#define SYNTH_FLAG_RESET_IS_REQUESTED 0x01
+#define SYNTH_FLAG_SP_MIDI_ON 0x02
+#define SYNTH_FLAG_UPDATE_ALL_CHANNEL_PARAMETERS 0x04
+#define SYNTH_FLAG_DEFERRED_MIDI_NOTE_OFF_PENDING 0x08
+#define DEFAULT_SYNTH_FLAGS SYNTH_FLAG_UPDATE_ALL_CHANNEL_PARAMETERS
+
+typedef struct s_synth_tag
+{
+ struct s_eas_data_tag *pEASData;
+ const S_EAS *pEAS;
+
+#ifdef DLS_SYNTHESIZER
+ S_DLS *pDLS;
+#endif
+
+#ifdef EXTERNAL_AUDIO
+ EAS_EXT_PRG_CHG_FUNC cbProgChgFunc;
+ EAS_EXT_EVENT_FUNC cbEventFunc;
+ EAS_VOID_PTR *pExtAudioInstData;
+#endif
+
+ S_SYNTH_CHANNEL channels[NUM_SYNTH_CHANNELS];
+ EAS_I32 totalNoteCount;
+ EAS_U16 maxPolyphony;
+ EAS_U16 numActiveVoices;
+ EAS_U16 masterVolume;
+ EAS_U8 channelsByPriority[NUM_SYNTH_CHANNELS];
+ EAS_U8 poolCount[NUM_SYNTH_CHANNELS];
+ EAS_U8 poolAlloc[NUM_SYNTH_CHANNELS];
+ EAS_U8 synthFlags;
+ EAS_I8 globalTranspose;
+ EAS_U8 vSynthNum;
+ EAS_U8 refCount;
+ EAS_U8 priority;
+} S_SYNTH;
+
+/*------------------------------------
+ * S_VOICE_MGR data structure
+ *
+ * One instance for each EAS library instance
+ *------------------------------------
+*/
+typedef struct s_voice_mgr_tag
+{
+ S_SYNTH *pSynth[MAX_VIRTUAL_SYNTHESIZERS];
+ EAS_PCM voiceBuffer[SYNTH_UPDATE_PERIOD_IN_SAMPLES];
+
+#ifdef _FM_SYNTH
+ EAS_PCM operMixBuffer[SYNTH_UPDATE_PERIOD_IN_SAMPLES];
+ S_FM_VOICE fmVoices[NUM_FM_VOICES];
+#endif
+
+#ifdef _WT_SYNTH
+ S_WT_VOICE wtVoices[NUM_WT_VOICES];
+#endif
+
+#ifdef _REVERB
+ EAS_PCM reverbSendBuffer[NUM_OUTPUT_CHANNELS * SYNTH_UPDATE_PERIOD_IN_SAMPLES];
+#endif
+
+#ifdef _CHORUS
+ EAS_PCM chorusSendBuffer[NUM_OUTPUT_CHANNELS * SYNTH_UPDATE_PERIOD_IN_SAMPLES];
+#endif
+ S_SYNTH_VOICE voices[MAX_SYNTH_VOICES];
+
+ EAS_SNDLIB_HANDLE pGlobalEAS;
+
+#ifdef DLS_SYNTHESIZER
+ S_DLS *pGlobalDLS;
+#endif
+
+#ifdef _SPLIT_ARCHITECTURE
+ EAS_FRAME_BUFFER_HANDLE pFrameBuffer;
+#endif
+
+#if defined(_SECONDARY_SYNTH) || defined(EAS_SPLIT_WT_SYNTH)
+ EAS_U16 maxPolyphonyPrimary;
+ EAS_U16 maxPolyphonySecondary;
+#endif
+
+ EAS_I32 workload;
+ EAS_I32 maxWorkLoad;
+
+ EAS_U16 activeVoices;
+ EAS_U16 maxPolyphony;
+
+ EAS_U16 age;
+
+/* limits the number of voice starts in a frame for split architecture */
+#ifdef MAX_VOICE_STARTS
+ EAS_U16 numVoiceStarts;
+#endif
+} S_VOICE_MGR;
+
+#endif /* #ifdef _EAS_SYNTH_H */
+
+
diff --git a/arm-wt-22k/lib_src/eas_synth_protos.h b/arm-wt-22k/lib_src/eas_synth_protos.h
index a2ef10d..b03af0f 100644
--- a/arm-wt-22k/lib_src/eas_synth_protos.h
+++ b/arm-wt-22k/lib_src/eas_synth_protos.h
@@ -1,12 +1,12 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_synth_protos.h
- *
- * Contents and purpose:
- * Declarations, interfaces, and prototypes for synth.
- *
- * Copyright Sonic Network Inc. 2004
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_synth_protos.h
+ *
+ * Contents and purpose:
+ * Declarations, interfaces, and prototypes for synth.
+ *
+ * Copyright Sonic Network Inc. 2004
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,42 +19,42 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 82 $
- * $Date: 2006-07-10 11:45:19 -0700 (Mon, 10 Jul 2006) $
- *----------------------------------------------------------------------------
-*/
-
-#ifndef _EAS_SYNTH_PROTOS_H
-#define _EAS_SYNTH_PROTOS_H
-
-/* includes */
-#include "eas_data.h"
-#include "eas_sndlib.h"
-
-#ifdef _SPLIT_ARCHITECTURE
-typedef struct s_frame_interface_tag
-{
- EAS_BOOL (* EAS_CONST pfStartFrame)(EAS_FRAME_BUFFER_HANDLE pFrameBuffer);
- EAS_BOOL (* EAS_CONST pfEndFrame)(EAS_FRAME_BUFFER_HANDLE pFrameBuffer, EAS_I32 *pMixBuffer, EAS_I16 masterGain);
-} S_FRAME_INTERFACE;
-#endif
-
-/* generic synthesizer interface */
-typedef struct
-{
- EAS_RESULT (* EAS_CONST pfInitialize)(S_VOICE_MGR *pVoiceMgr);
- EAS_RESULT (* EAS_CONST pfStartVoice)(S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, EAS_I32 voiceNum, EAS_U16 regionIndex);
- EAS_BOOL (* EAS_CONST pfUpdateVoice)(S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, EAS_I32 voiceNum, EAS_I32 *pMixBuffer, EAS_I32 numSamples);
- void (* EAS_CONST pfReleaseVoice)(S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, EAS_I32 voiceNum);
- void (* EAS_CONST pfMuteVoice)(S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, EAS_I32 voiceNum);
- void (* EAS_CONST pfSustainPedal)(S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, S_SYNTH_CHANNEL *pChannel, EAS_I32 voiceNum);
- void (* EAS_CONST pfUpdateChannel)(S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel);
-} S_SYNTH_INTERFACE;
-
-#endif
-
-
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 82 $
+ * $Date: 2006-07-10 11:45:19 -0700 (Mon, 10 Jul 2006) $
+ *----------------------------------------------------------------------------
+*/
+
+#ifndef _EAS_SYNTH_PROTOS_H
+#define _EAS_SYNTH_PROTOS_H
+
+/* includes */
+#include "eas_data.h"
+#include "eas_sndlib.h"
+
+#ifdef _SPLIT_ARCHITECTURE
+typedef struct s_frame_interface_tag
+{
+ EAS_BOOL (* EAS_CONST pfStartFrame)(EAS_FRAME_BUFFER_HANDLE pFrameBuffer);
+ EAS_BOOL (* EAS_CONST pfEndFrame)(EAS_FRAME_BUFFER_HANDLE pFrameBuffer, EAS_I32 *pMixBuffer, EAS_I16 masterGain);
+} S_FRAME_INTERFACE;
+#endif
+
+/* generic synthesizer interface */
+typedef struct
+{
+ EAS_RESULT (* EAS_CONST pfInitialize)(S_VOICE_MGR *pVoiceMgr);
+ EAS_RESULT (* EAS_CONST pfStartVoice)(S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, EAS_I32 voiceNum, EAS_U16 regionIndex);
+ EAS_BOOL (* EAS_CONST pfUpdateVoice)(S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, EAS_I32 voiceNum, EAS_I32 *pMixBuffer, EAS_I32 numSamples);
+ void (* EAS_CONST pfReleaseVoice)(S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, EAS_I32 voiceNum);
+ void (* EAS_CONST pfMuteVoice)(S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, EAS_I32 voiceNum);
+ void (* EAS_CONST pfSustainPedal)(S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, S_SYNTH_CHANNEL *pChannel, EAS_I32 voiceNum);
+ void (* EAS_CONST pfUpdateChannel)(S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel);
+} S_SYNTH_INTERFACE;
+
+#endif
+
+
+
diff --git a/arm-wt-22k/lib_src/eas_synthcfg.h b/arm-wt-22k/lib_src/eas_synthcfg.h
index 2491e6d..78a4178 100644
--- a/arm-wt-22k/lib_src/eas_synthcfg.h
+++ b/arm-wt-22k/lib_src/eas_synthcfg.h
@@ -1,12 +1,12 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_synthcfg.h
- *
- * Contents and purpose:
- * Defines for various synth configurations
- *
- * Copyright Sonic Network Inc. 2004, 2005
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_synthcfg.h
+ *
+ * Contents and purpose:
+ * Defines for various synth configurations
+ *
+ * Copyright Sonic Network Inc. 2004, 2005
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,52 +19,52 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 664 $
- * $Date: 2007-04-25 13:11:22 -0700 (Wed, 25 Apr 2007) $
- *----------------------------------------------------------------------------
-*/
-
-#ifndef _EAS_SYNTHCFG_H
-#define _EAS_SYNTHCFG_H
-
-#if defined(EAS_WT_SYNTH)
-#define _WT_SYNTH
-
-/* FM on MCU */
-#elif defined(EAS_FM_SYNTH)
-#define _FM_SYNTH
-
-/* wavetable drums and FM melodic on MCU */
-#elif defined(EAS_HYBRID_SYNTH)
-#define _WT_SYNTH
-#define _FM_SYNTH
-#define _SECONDARY_SYNTH
-#define _HYBRID_SYNTH
-
-/* wavetable drums on MCU, wavetable melodic on DSP */
-#elif defined(EAS_SPLIT_WT_SYNTH)
-#define _WT_SYNTH
-#define _SPLIT_ARCHITECTURE
-
-/* wavetable drums on MCU, FM melodic on DSP */
-#elif defined(EAS_SPLIT_HYBRID_SYNTH)
-#define _WT_SYNTH
-#define _FM_SYNTH
-#define _SECONDARY_SYNTH
-#define _SPLIT_ARCHITECTURE
-#define _HYBRID_SYNTH
-
-/* FM synth on DSP */
-#elif defined(EAS_SPLIT_FM_SYNTH)
-#define _FM_SYNTH
-#define _SPLIT_ARCHITECTURE
-
-#else
-#error "Unrecognized architecture option"
-#endif
-
-#endif
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 664 $
+ * $Date: 2007-04-25 13:11:22 -0700 (Wed, 25 Apr 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+#ifndef _EAS_SYNTHCFG_H
+#define _EAS_SYNTHCFG_H
+
+#if defined(EAS_WT_SYNTH)
+#define _WT_SYNTH
+
+/* FM on MCU */
+#elif defined(EAS_FM_SYNTH)
+#define _FM_SYNTH
+
+/* wavetable drums and FM melodic on MCU */
+#elif defined(EAS_HYBRID_SYNTH)
+#define _WT_SYNTH
+#define _FM_SYNTH
+#define _SECONDARY_SYNTH
+#define _HYBRID_SYNTH
+
+/* wavetable drums on MCU, wavetable melodic on DSP */
+#elif defined(EAS_SPLIT_WT_SYNTH)
+#define _WT_SYNTH
+#define _SPLIT_ARCHITECTURE
+
+/* wavetable drums on MCU, FM melodic on DSP */
+#elif defined(EAS_SPLIT_HYBRID_SYNTH)
+#define _WT_SYNTH
+#define _FM_SYNTH
+#define _SECONDARY_SYNTH
+#define _SPLIT_ARCHITECTURE
+#define _HYBRID_SYNTH
+
+/* FM synth on DSP */
+#elif defined(EAS_SPLIT_FM_SYNTH)
+#define _FM_SYNTH
+#define _SPLIT_ARCHITECTURE
+
+#else
+#error "Unrecognized architecture option"
+#endif
+
+#endif
+
diff --git a/arm-wt-22k/lib_src/eas_tcdata.c b/arm-wt-22k/lib_src/eas_tcdata.c
index 11ff9c7..65ba49e 100644
--- a/arm-wt-22k/lib_src/eas_tcdata.c
+++ b/arm-wt-22k/lib_src/eas_tcdata.c
@@ -1,14 +1,14 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_tcdata.c
- *
- * Contents and purpose:
- * ToneControl Parser data
- *
- * This file contains static data for the ToneControl parser.
- *
- * Copyright Sonic Network Inc. 2005
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_tcdata.c
+ *
+ * Contents and purpose:
+ * ToneControl Parser data
+ *
+ * This file contains static data for the ToneControl parser.
+ *
+ * Copyright Sonic Network Inc. 2005
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,23 +21,23 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 547 $
- * $Date: 2007-01-31 16:30:17 -0800 (Wed, 31 Jan 2007) $
- *----------------------------------------------------------------------------
-*/
-
-#include "eas_types.h"
-#include "eas_tcdata.h"
-
-/*----------------------------------------------------------------------------
- *
- * eas_iMelodyData
- *
- * Static memory allocation for iMelody parser
- *----------------------------------------------------------------------------
-*/
-S_TC_DATA eas_TCData;
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 547 $
+ * $Date: 2007-01-31 16:30:17 -0800 (Wed, 31 Jan 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+#include "eas_types.h"
+#include "eas_tcdata.h"
+
+/*----------------------------------------------------------------------------
+ *
+ * eas_iMelodyData
+ *
+ * Static memory allocation for iMelody parser
+ *----------------------------------------------------------------------------
+*/
+S_TC_DATA eas_TCData;
+
diff --git a/arm-wt-22k/lib_src/eas_tcdata.h b/arm-wt-22k/lib_src/eas_tcdata.h
index 51a60b2..8b9dec5 100644
--- a/arm-wt-22k/lib_src/eas_tcdata.h
+++ b/arm-wt-22k/lib_src/eas_tcdata.h
@@ -1,14 +1,14 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_tcdata.h
- *
- * Contents and purpose:
- * SMF File Parser
- *
- * This file contains data declarations for the ToneControl parser.
- *
- * Copyright Sonic Network Inc. 2006
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_tcdata.h
+ *
+ * Contents and purpose:
+ * SMF File Parser
+ *
+ * This file contains data declarations for the ToneControl parser.
+ *
+ * Copyright Sonic Network Inc. 2006
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,45 +21,45 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 82 $
- * $Date: 2006-07-10 11:45:19 -0700 (Mon, 10 Jul 2006) $
- *----------------------------------------------------------------------------
-*/
-
-#ifndef EAS_TFDATA_H
-#define EAS_TCDATA_H
-
-#include "eas_data.h"
-
-/*----------------------------------------------------------------------------
- *
- * S_TC_DATA
- *
- * This structure contains the state data for the ToneControl parser
- *----------------------------------------------------------------------------
-*/
-typedef struct
-{
- EAS_FILE_HANDLE fileHandle; /* file handle */
- S_SYNTH *pSynth; /* synthesizer handle */
- EAS_I32 fileOffset; /* offset to start of data */
- EAS_I32 time; /* current time in 256ths of a msec */
- EAS_I32 tick; /* tick based on current tempo and resolution */
- EAS_I32 length; /* length of current note */
- EAS_I32 restorePos; /* return to here after block */
- EAS_U8 state; /* current state EAS_STATE_XXXX */
- EAS_U8 volume; /* volume */
- EAS_I8 note; /* current note */
- EAS_I8 repeatCount; /* note repeat counter */
- EAS_I8 tempo; /* tempo from file (bpm = tempo * 4) */
- EAS_I8 resolution; /* resolution from file */
- EAS_I8 dataByte; /* storage for characters that are "put back" */
- EAS_BOOL8 byteAvail; /* char in "put back" buffer */
-} S_TC_DATA;
-
-#endif
-
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 82 $
+ * $Date: 2006-07-10 11:45:19 -0700 (Mon, 10 Jul 2006) $
+ *----------------------------------------------------------------------------
+*/
+
+#ifndef EAS_TFDATA_H
+#define EAS_TCDATA_H
+
+#include "eas_data.h"
+
+/*----------------------------------------------------------------------------
+ *
+ * S_TC_DATA
+ *
+ * This structure contains the state data for the ToneControl parser
+ *----------------------------------------------------------------------------
+*/
+typedef struct
+{
+ EAS_FILE_HANDLE fileHandle; /* file handle */
+ S_SYNTH *pSynth; /* synthesizer handle */
+ EAS_I32 fileOffset; /* offset to start of data */
+ EAS_I32 time; /* current time in 256ths of a msec */
+ EAS_I32 tick; /* tick based on current tempo and resolution */
+ EAS_I32 length; /* length of current note */
+ EAS_I32 restorePos; /* return to here after block */
+ EAS_U8 state; /* current state EAS_STATE_XXXX */
+ EAS_U8 volume; /* volume */
+ EAS_I8 note; /* current note */
+ EAS_I8 repeatCount; /* note repeat counter */
+ EAS_I8 tempo; /* tempo from file (bpm = tempo * 4) */
+ EAS_I8 resolution; /* resolution from file */
+ EAS_I8 dataByte; /* storage for characters that are "put back" */
+ EAS_BOOL8 byteAvail; /* char in "put back" buffer */
+} S_TC_DATA;
+
+#endif
+
+
diff --git a/arm-wt-22k/lib_src/eas_tonecontrol.c b/arm-wt-22k/lib_src/eas_tonecontrol.c
index 8231b83..cceb7f9 100644
--- a/arm-wt-22k/lib_src/eas_tonecontrol.c
+++ b/arm-wt-22k/lib_src/eas_tonecontrol.c
@@ -1,12 +1,12 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_tonecontrol.c
- *
- * Contents and purpose:
- * MMAPI ToneControl parser
- *
- * Copyright Sonic Network Inc. 2006
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_tonecontrol.c
+ *
+ * Contents and purpose:
+ * MMAPI ToneControl parser
+ *
+ * Copyright Sonic Network Inc. 2006
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,923 +19,923 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 795 $
- * $Date: 2007-08-01 00:14:45 -0700 (Wed, 01 Aug 2007) $
- *----------------------------------------------------------------------------
-*/
-
-#include "eas_data.h"
-#include "eas_miditypes.h"
-#include "eas_parser.h"
-#include "eas_report.h"
-#include "eas_host.h"
-#include "eas_midi.h"
-#include "eas_config.h"
-#include "eas_vm_protos.h"
-#include "eas_tcdata.h"
-
-
-/* default channel and program for TC playback */
-#define TC_CHANNEL 0
-#define TC_PROGRAM 80
-#define TC_VELOCITY 127
-
-#define TC_FIELD_SILENCE -1
-#define TC_FIELD_VERSION -2
-#define TC_FIELD_TEMPO -3
-#define TC_FIELD_RESOLUTION -4
-#define TC_FIELD_BLOCK_START -5
-#define TC_FIELD_BLOCK_END -6
-#define TC_FIELD_PLAY_BLOCK -7
-#define TC_FIELD_SET_VOLUME -8
-#define TC_FIELD_REPEAT -9
-#define TC_FIELD_INVALID -10
-
-/* convert 0-100 volume to 0-127 velocity using fixed point */
-#define TC_VOLUME_CONV 21307064
-#define TC_VOLUME_SHIFT 24
-
-
-/* local prototypes */
-static EAS_RESULT TC_CheckFileType (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle, EAS_VOID_PTR *ppHandle, EAS_I32 offset);
-static EAS_RESULT TC_Prepare (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
-static EAS_RESULT TC_Time (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_U32 *pTime);
-static EAS_RESULT TC_Event (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_INT parserMode);
-static EAS_RESULT TC_State (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_STATE *pState);
-static EAS_RESULT TC_Close (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
-static EAS_RESULT TC_Reset (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
-static EAS_RESULT TC_Pause (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
-static EAS_RESULT TC_Resume (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
-static EAS_RESULT TC_SetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value);
-static EAS_RESULT TC_GetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue);
-static EAS_RESULT TC_ParseHeader (S_EAS_DATA *pEASData, S_TC_DATA* pData);
-static EAS_RESULT TC_StartNote (S_EAS_DATA *pEASData, S_TC_DATA* pData, EAS_INT parserMode, EAS_I8 note);
-static EAS_RESULT TC_GetRepeat (S_EAS_DATA *pEASData, S_TC_DATA* pData, EAS_INT parserMode);
-static EAS_RESULT TC_PlayBlock (S_EAS_DATA *pEASData, S_TC_DATA* pData);
-static EAS_RESULT TC_BlockEnd (S_EAS_DATA *pEASData, S_TC_DATA* pData);
-static EAS_RESULT TC_GetVolume (S_EAS_DATA *pEASData, S_TC_DATA* pData);
-static EAS_RESULT TC_GetTempo (S_EAS_DATA *pEASData, S_TC_DATA* pData);
-static EAS_RESULT TC_GetResolution (S_EAS_DATA *pEASData, S_TC_DATA* pData);
-static EAS_RESULT TC_GetNextChar (EAS_HW_DATA_HANDLE hwInstData, S_TC_DATA *pData, EAS_I8 *pValue);
-static void TC_PutBackChar (S_TC_DATA *pData, EAS_I8 value);
-
-/* calculate a new tick time based on resolution & tempo */
-EAS_INLINE void TC_CalcTimeBase (S_TC_DATA *pData)
-{
-
- /* ticks in 256ths of a millisecond */
- pData->tick = ((60 * 1000) << 8) / (pData->tempo * pData->resolution);
-}
-
-/*----------------------------------------------------------------------------
- *
- * EAS_TC_Parser
- *
- * This structure contains the functional interface for the iMelody parser
- *----------------------------------------------------------------------------
-*/
-const S_FILE_PARSER_INTERFACE EAS_TC_Parser =
-{
- TC_CheckFileType,
- TC_Prepare,
- TC_Time,
- TC_Event,
- TC_State,
- TC_Close,
- TC_Reset,
- TC_Pause,
- TC_Resume,
- NULL,
- TC_SetData,
- TC_GetData,
- NULL
-};
-
-/*----------------------------------------------------------------------------
- * TC_CheckFileType()
- *----------------------------------------------------------------------------
- * Purpose:
- * Check the file type to see if we can parse it
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT TC_CheckFileType (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle, EAS_VOID_PTR *ppHandle, EAS_I32 offset)
-{
- S_TC_DATA data;
- S_TC_DATA *pData;
-
- /* init data */
- EAS_HWMemSet(&data, 0, sizeof(S_TC_DATA));
- data.fileHandle = fileHandle;
- data.fileOffset = offset;
- *ppHandle= NULL;
-
- /* see if we can parse the header */
- if (TC_ParseHeader(pEASData, &data) == EAS_SUCCESS)
- {
-
- /* check for static memory allocation */
- if (pEASData->staticMemoryModel)
- pData = EAS_CMEnumOptData(EAS_MODULE_MMAPI_TONE_CONTROL);
- else
- pData = EAS_HWMalloc(pEASData->hwInstData, sizeof(S_TC_DATA));
- if (!pData)
- return EAS_ERROR_MALLOC_FAILED;
-
- /* copy data to persistent storage */
- EAS_HWMemCpy(pData, &data, sizeof(S_TC_DATA));
-
- /* return a pointer to the instance data */
- pData->state = EAS_STATE_OPEN;
- *ppHandle = pData;
- }
-
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * TC_Prepare()
- *----------------------------------------------------------------------------
- * Purpose:
- * Prepare to parse the file. Allocates instance data (or uses static allocation for
- * static memory model).
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT TC_Prepare (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
-{
- S_TC_DATA* pData;
- EAS_RESULT result;
-
- /* check for valid state */
- pData = (S_TC_DATA*) pInstData;
- if (pData->state != EAS_STATE_OPEN)
- return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
-
- /* instantiate a synthesizer */
- if ((result = VMInitMIDI(pEASData, &pData->pSynth)) != EAS_SUCCESS)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "VMInitMIDI returned %d\n", result); */ }
- return result;
- }
-
- /* set to ready state */
- pData->state = EAS_STATE_READY;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * TC_Time()
- *----------------------------------------------------------------------------
- * Purpose:
- * Returns the time of the next event in msecs
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- * pTime - pointer to variable to hold time of next event (in msecs)
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, pEASData) reserved for future use */
-static EAS_RESULT TC_Time (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_U32 *pTime)
-{
- S_TC_DATA *pData;
-
- pData = (S_TC_DATA*) pInstData;
-
- /* return time in milliseconds */
- /*lint -e{704} use shift instead of division */
- *pTime = pData->time >> 8;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * TC_Event()
- *----------------------------------------------------------------------------
- * Purpose:
- * Parse the next event in the file
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT TC_Event (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_INT parserMode)
-{
- S_TC_DATA* pData;
- EAS_RESULT result;
- EAS_I8 temp;
-
- pData = (S_TC_DATA*) pInstData;
- if (pData->state >= EAS_STATE_OPEN)
- return EAS_SUCCESS;
-
- /* initialize MIDI channel when the track starts playing */
- if (pData->time == 0)
- {
- /* set program to square lead */
- VMProgramChange(pEASData->pVoiceMgr, pData->pSynth, TC_CHANNEL, TC_PROGRAM);
-
- /* set channel volume to max */
- VMControlChange(pEASData->pVoiceMgr, pData->pSynth, TC_CHANNEL, 7, 127);
- }
-
- /* check for end of note */
- if (pData->note >= 0)
- {
- /* stop the note */
- VMStopNote(pEASData->pVoiceMgr, pData->pSynth, TC_CHANNEL, (EAS_U8) pData->note, 0);
-
- /* check for repeat note */
- if (pData->repeatCount)
- {
- pData->repeatCount--;
- pData->time += pData->length;
- if ((pData->note >= 0) && (parserMode == eParserModePlay))
- VMStartNote(pEASData->pVoiceMgr, pData->pSynth, TC_CHANNEL, (EAS_U8) pData->note, pData->volume);
- return EAS_SUCCESS;
- }
-
- pData->note = TC_FIELD_SILENCE;
- }
-
- /* parse stream until we get a note or rest */
- for (;;)
- {
-
- /* get next byte from stream */
- if ((result = TC_GetNextChar(pEASData->hwInstData, pData, &temp)) != EAS_SUCCESS)
- {
- if (result == EAS_EOF)
- {
- pData->state = EAS_STATE_STOPPING;
- return EAS_SUCCESS;
- }
- break;
- }
-
- /* check for musical events */
- if (temp >= TC_FIELD_SILENCE)
- {
- result = TC_StartNote(pEASData, pData, parserMode, temp);
- break;
- }
-
- /* must be a control field */
- switch (temp)
- {
- case TC_FIELD_TEMPO:
- result = TC_GetTempo(pEASData, pData);
- break;
-
- case TC_FIELD_RESOLUTION:
- result = TC_GetResolution(pEASData, pData);
- break;
-
- case TC_FIELD_SET_VOLUME:
- result = TC_GetVolume(pEASData, pData);
- break;
-
- case TC_FIELD_REPEAT:
- result = TC_GetRepeat(pEASData, pData, parserMode);
- break;
-
- case TC_FIELD_PLAY_BLOCK:
- result = TC_PlayBlock(pEASData, pData);
- break;
-
- case TC_FIELD_BLOCK_START:
- result = TC_GetNextChar(pEASData->hwInstData, pData, &temp);
- break;
-
- case TC_FIELD_BLOCK_END:
- result = TC_BlockEnd(pEASData, pData);
- break;
-
- default:
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Unexpected byte 0x%02x in ToneControl stream\n", temp); */ }
- result = EAS_ERROR_FILE_FORMAT;
- }
-
- /* check for error */
- if (result != EAS_SUCCESS)
- break;
- }
-
- /* check for error */
- if (result != EAS_SUCCESS)
- {
- if (result == EAS_EOF)
- result = EAS_ERROR_FILE_FORMAT;
- pData->state = EAS_STATE_ERROR;
- }
- else
- pData->state = EAS_STATE_PLAY;
- return result;
-}
-
-/*----------------------------------------------------------------------------
- * TC_State()
- *----------------------------------------------------------------------------
- * Purpose:
- * Returns the current state of the stream
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- * pState - pointer to variable to store state
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, pEASData) reserved for future use */
-static EAS_RESULT TC_State (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 *pState)
-{
- S_TC_DATA* pData;
-
- /* establish pointer to instance data */
- pData = (S_TC_DATA*) pInstData;
-
- /* if stopping, check to see if synth voices are active */
- if (pData->state == EAS_STATE_STOPPING)
- {
- if (VMActiveVoices(pData->pSynth) == 0)
- pData->state = EAS_STATE_STOPPED;
- }
-
- if (pData->state == EAS_STATE_PAUSING)
- {
- if (VMActiveVoices(pData->pSynth) == 0)
- pData->state = EAS_STATE_PAUSED;
- }
-
- /* return current state */
- *pState = pData->state;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * TC_Close()
- *----------------------------------------------------------------------------
- * Purpose:
- * Close the file and clean up
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT TC_Close (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
-{
- S_TC_DATA* pData;
- EAS_RESULT result;
-
- pData = (S_TC_DATA*) pInstData;
-
- /* close the file */
- if ((result = EAS_HWCloseFile(pEASData->hwInstData, pData->fileHandle)) != EAS_SUCCESS)
- return result;
-
- /* free the synth */
- if (pData->pSynth != NULL)
- VMMIDIShutdown(pEASData, pData->pSynth);
-
- /* if using dynamic memory, free it */
- if (!pEASData->staticMemoryModel)
- EAS_HWFree(pEASData->hwInstData, pData);
-
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * TC_Reset()
- *----------------------------------------------------------------------------
- * Purpose:
- * Reset the sequencer. Used for locating backwards in the file.
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT TC_Reset (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
-{
- S_TC_DATA* pData;
- EAS_RESULT result;
-
- pData = (S_TC_DATA*) pInstData;
-
- /* reset the synth */
- VMReset(pEASData->pVoiceMgr, pData->pSynth, EAS_TRUE);
-
- /* reset time to zero */
- pData->time = 0;
-
- /* reset file position and re-parse header */
- pData->state = EAS_STATE_ERROR;
- if ((result = EAS_HWFileSeek(pEASData->hwInstData, pData->fileHandle, pData->fileOffset)) != EAS_SUCCESS)
- return result;
- if ((result = TC_ParseHeader (pEASData, pData)) != EAS_SUCCESS)
- return result;
-
- pData->state = EAS_STATE_READY;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * TC_Pause()
- *----------------------------------------------------------------------------
- * Purpose:
- * Pauses the sequencer. Mutes all voices and sets state to pause.
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT TC_Pause (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
-{
- S_TC_DATA *pData;
-
- /* can't pause a stopped stream */
- pData = (S_TC_DATA*) pInstData;
- if (pData->state == EAS_STATE_STOPPED)
- return EAS_ERROR_ALREADY_STOPPED;
-
- /* mute the synthesizer */
- VMMuteAllVoices(pEASData->pVoiceMgr, pData->pSynth);
- pData->state = EAS_STATE_PAUSING;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * TC_Resume()
- *----------------------------------------------------------------------------
- * Purpose:
- * Resume playing after a pause, sets state back to playing.
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, pEASData) reserved for future use */
-static EAS_RESULT TC_Resume (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
-{
- S_TC_DATA *pData;
-
- /* can't resume a stopped stream */
- pData = (S_TC_DATA*) pInstData;
- if (pData->state == EAS_STATE_STOPPED)
- return EAS_ERROR_ALREADY_STOPPED;
-
- /* nothing to do but resume playback */
- pData->state = EAS_STATE_PLAY;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * TC_SetData()
- *----------------------------------------------------------------------------
- * Purpose:
- * Return file type
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, pEASData, pInstData, value) reserved for future use */
-static EAS_RESULT TC_SetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value)
-{
- /* we don't parse any metadata, but we need to return success here */
- if (param == PARSER_DATA_METADATA_CB)
- return EAS_SUCCESS;
-
- return EAS_ERROR_INVALID_PARAMETER;
-}
-
-/*----------------------------------------------------------------------------
- * TC_GetData()
- *----------------------------------------------------------------------------
- * Purpose:
- * Return file type
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -e{715} common with other parsers */
-static EAS_RESULT TC_GetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue)
-{
- S_TC_DATA *pData;
-
- pData = (S_TC_DATA *) pInstData;
- switch (param)
- {
- /* return file type as TC */
- case PARSER_DATA_FILE_TYPE:
- *pValue = EAS_FILE_MMAPI_TONE_CONTROL;
- break;
-
- case PARSER_DATA_SYNTH_HANDLE:
- *pValue = (EAS_I32) pData->pSynth;
- break;
-
- default:
- return EAS_ERROR_INVALID_PARAMETER;
- }
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * TC_ParseHeader()
- *----------------------------------------------------------------------------
- * Purpose:
- * Prepare to parse the file. Allocates instance data (or uses static allocation for
- * static memory model).
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT TC_ParseHeader (S_EAS_DATA *pEASData, S_TC_DATA* pData)
-{
- EAS_RESULT result;
- EAS_I8 temp;
-
- /* initialize some defaults */
- pData->time = 0;
- pData->tempo = 120;
- pData->resolution = 64;
- pData->volume = 127;
- pData->repeatCount = 0;
- pData->note = TC_FIELD_SILENCE;
- pData->byteAvail = EAS_FALSE;
-
- /* set default timebase */
- TC_CalcTimeBase(pData);
-
- /* seek to start of data */
- if ((result = EAS_HWFileSeek(pEASData->hwInstData, pData->fileHandle, pData->fileOffset)) != EAS_SUCCESS)
- return result;
-
- /* get version */
- if ((result = TC_GetNextChar(pEASData->hwInstData, pData, &temp)) != EAS_SUCCESS)
- return result;
-
- /* check for version number */
- if (temp == TC_FIELD_VERSION)
- {
- TC_GetNextChar(pEASData->hwInstData, pData, &temp);
-// { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "ToneControl sequence version %d\n", temp); */ }
- }
- else
- return EAS_ERROR_FILE_FORMAT;
-
- /* parse the header data until we find the first note or block */
- for (;;)
- {
-
- /* get next byte from stream */
- if ((result = TC_GetNextChar(pEASData->hwInstData, pData, &temp)) != EAS_SUCCESS)
- return result;
-
- /* check for tempo */
- if (temp == TC_FIELD_TEMPO)
- {
- if ((result = TC_GetTempo(pEASData, pData)) != EAS_SUCCESS)
- return result;
- }
-
- /* or resolution */
- else if (temp == TC_FIELD_TEMPO)
- {
- if ((result = TC_GetResolution(pEASData, pData)) != EAS_SUCCESS)
- return result;
- }
-
- /* must be music data */
- else if (temp > TC_FIELD_INVALID)
- {
- TC_PutBackChar(pData, temp);
- return EAS_SUCCESS;
- }
-
- /* unknown codes */
- else
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Unexpected byte 0x%02x in ToneControl stream\n", temp); */ }
- return EAS_ERROR_FILE_FORMAT;
- }
- }
-}
-
-/*----------------------------------------------------------------------------
- * TC_StartNote()
- *----------------------------------------------------------------------------
- * Process a note or silence event
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT TC_StartNote (S_EAS_DATA *pEASData, S_TC_DATA* pData, EAS_INT parserMode, EAS_I8 note)
-{
- EAS_I8 duration;
-
- /* get the duration */
- if (TC_GetNextChar(pEASData->hwInstData, pData, &duration) != EAS_SUCCESS)
- return EAS_ERROR_FILE_FORMAT;
-
- /* calculate time of next event */
- pData->length = (EAS_I32) duration * pData->tick;
- pData->time += pData->length;
-
- /* start the note */
- if ((note >= 0) && (parserMode == eParserModePlay))
- {
- VMStartNote(pEASData->pVoiceMgr, pData->pSynth, TC_CHANNEL, (EAS_U8) note, pData->volume);
- pData->note = note;
- }
-
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * TC_GetRepeat()
- *----------------------------------------------------------------------------
- * Process a repeat code
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT TC_GetRepeat (S_EAS_DATA *pEASData, S_TC_DATA* pData, EAS_INT parserMode)
-{
- EAS_I8 count;
-
- /* get the repeat count */
- if (TC_GetNextChar(pEASData->hwInstData, pData, &count) != EAS_SUCCESS)
- return EAS_ERROR_FILE_FORMAT;
-
- /* validiate it */
- if (count < 2)
- return EAS_ERROR_FILE_FORMAT;
-
- /* calculate time of next event */
- pData->time += pData->length;
- pData->repeatCount = count - 2;
-
- /* start the note */
- if ((pData->note >= 0) && (parserMode == eParserModePlay))
- VMStartNote(pEASData->pVoiceMgr, pData->pSynth, TC_CHANNEL, (EAS_U8) pData->note, pData->volume);
-
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * TC_PlayBlock()
- *----------------------------------------------------------------------------
- * Play a block of notes
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT TC_PlayBlock (S_EAS_DATA *pEASData, S_TC_DATA* pData)
-{
- EAS_RESULT result;
- EAS_I8 blockNum;
- EAS_I8 temp;
- EAS_I8 temp2;
-
- /* get the block number */
- if (TC_GetNextChar(pEASData->hwInstData, pData, &blockNum) != EAS_SUCCESS)
- return EAS_ERROR_FILE_FORMAT;
-
- /* validiate it */
- if (blockNum < 0)
- return EAS_ERROR_FILE_FORMAT;
-
- /* save the current position */
- if ((result = EAS_HWFilePos(pEASData->hwInstData, pData->fileHandle, &pData->restorePos)) != EAS_SUCCESS)
- return result;
-
- /* return to start of file */
- pData->byteAvail = EAS_FALSE;
- if ((result = EAS_HWFileSeek(pEASData->hwInstData, pData->fileHandle, pData->fileOffset)) != EAS_SUCCESS)
- return result;
-
- /* find the block */
- for (;;)
- {
- if (TC_GetNextChar(pEASData->hwInstData, pData, &temp) != EAS_SUCCESS)
- return EAS_ERROR_FILE_FORMAT;
-
- if (TC_GetNextChar(pEASData->hwInstData, pData, &temp2) != EAS_SUCCESS)
- return EAS_ERROR_FILE_FORMAT;
-
- if ((temp == TC_FIELD_BLOCK_START) && (temp2 == blockNum))
- return EAS_SUCCESS;
- }
-}
-
-/*----------------------------------------------------------------------------
- * TC_BlockEnd()
- *----------------------------------------------------------------------------
- * Handle end of block
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT TC_BlockEnd (S_EAS_DATA *pEASData, S_TC_DATA* pData)
-{
- EAS_I8 blockNum;
-
- /* get the block number */
- if (TC_GetNextChar(pEASData->hwInstData, pData, &blockNum) != EAS_SUCCESS)
- return EAS_ERROR_FILE_FORMAT;
-
- /* validiate it */
- if (blockNum < 0)
- return EAS_ERROR_FILE_FORMAT;
-
- /* if we were playing this block, restore to previous position */
- pData->byteAvail = EAS_FALSE;
- return EAS_HWFileSeek(pEASData->hwInstData, pData->fileHandle, pData->restorePos);
-}
-
-/*----------------------------------------------------------------------------
- * TC_GetVolume()
- *----------------------------------------------------------------------------
- * Get the volume field and process it
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT TC_GetVolume (S_EAS_DATA *pEASData, S_TC_DATA* pData)
-{
- EAS_I8 volume;
-
- /* get volume */
- if (TC_GetNextChar(pEASData->hwInstData, pData, &volume) != EAS_SUCCESS)
- return EAS_ERROR_FILE_FORMAT;
- if ((volume < 0) || (volume > 100))
- return EAS_ERROR_FILE_FORMAT;
-
- /* save volume */
- pData->volume = (EAS_U8) ((EAS_I32) (volume * TC_VOLUME_CONV + 1) >> TC_VOLUME_SHIFT);
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * TC_GetTempo()
- *----------------------------------------------------------------------------
- * Get the tempo field and process it
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT TC_GetTempo (S_EAS_DATA *pEASData, S_TC_DATA* pData)
-{
- EAS_I8 tempo;
-
- /* get tempo */
- if (TC_GetNextChar(pEASData->hwInstData, pData, &tempo) != EAS_SUCCESS)
- return EAS_ERROR_FILE_FORMAT;
- if (tempo < 5)
- return EAS_ERROR_FILE_FORMAT;
-
- /* save tempo */
- pData->tempo = tempo;
-
- /* calculate new timebase */
- TC_CalcTimeBase(pData);
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * TC_GetResolution()
- *----------------------------------------------------------------------------
- * Get the resolution field and process it
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT TC_GetResolution (S_EAS_DATA *pEASData, S_TC_DATA* pData)
-{
- EAS_I8 resolution;
-
- /* get resolution */
- if (TC_GetNextChar(pEASData->hwInstData, pData, &resolution) != EAS_SUCCESS)
- return EAS_ERROR_FILE_FORMAT;
- if (resolution < 0)
- return EAS_ERROR_FILE_FORMAT;
-
- /* save tempo */
- pData->resolution = resolution;
-
- /* calculate new timebase */
- TC_CalcTimeBase(pData);
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * TC_GetNextChar()
- *----------------------------------------------------------------------------
- * Fetch the next character from the stream
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT TC_GetNextChar (EAS_HW_DATA_HANDLE hwInstData, S_TC_DATA *pData, EAS_I8 *pValue)
-{
-
- /* get character from "put back" buffer */
- if (pData->byteAvail)
- {
- pData->byteAvail = EAS_FALSE;
- *pValue = pData->dataByte;
- return EAS_SUCCESS;
- }
-
- /* get character from file */
- return EAS_HWGetByte(hwInstData, pData->fileHandle, pValue);
-}
-
-/*----------------------------------------------------------------------------
- * TC_PutBackChar()
- *----------------------------------------------------------------------------
- * Put back the character
- *----------------------------------------------------------------------------
-*/
-static void TC_PutBackChar (S_TC_DATA *pData, EAS_I8 value)
-{
-
- pData->dataByte = value;
- pData->byteAvail = EAS_TRUE;
-}
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 795 $
+ * $Date: 2007-08-01 00:14:45 -0700 (Wed, 01 Aug 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+#include "eas_data.h"
+#include "eas_miditypes.h"
+#include "eas_parser.h"
+#include "eas_report.h"
+#include "eas_host.h"
+#include "eas_midi.h"
+#include "eas_config.h"
+#include "eas_vm_protos.h"
+#include "eas_tcdata.h"
+
+
+/* default channel and program for TC playback */
+#define TC_CHANNEL 0
+#define TC_PROGRAM 80
+#define TC_VELOCITY 127
+
+#define TC_FIELD_SILENCE -1
+#define TC_FIELD_VERSION -2
+#define TC_FIELD_TEMPO -3
+#define TC_FIELD_RESOLUTION -4
+#define TC_FIELD_BLOCK_START -5
+#define TC_FIELD_BLOCK_END -6
+#define TC_FIELD_PLAY_BLOCK -7
+#define TC_FIELD_SET_VOLUME -8
+#define TC_FIELD_REPEAT -9
+#define TC_FIELD_INVALID -10
+
+/* convert 0-100 volume to 0-127 velocity using fixed point */
+#define TC_VOLUME_CONV 21307064
+#define TC_VOLUME_SHIFT 24
+
+
+/* local prototypes */
+static EAS_RESULT TC_CheckFileType (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle, EAS_VOID_PTR *ppHandle, EAS_I32 offset);
+static EAS_RESULT TC_Prepare (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
+static EAS_RESULT TC_Time (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_U32 *pTime);
+static EAS_RESULT TC_Event (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_INT parserMode);
+static EAS_RESULT TC_State (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_STATE *pState);
+static EAS_RESULT TC_Close (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
+static EAS_RESULT TC_Reset (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
+static EAS_RESULT TC_Pause (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
+static EAS_RESULT TC_Resume (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
+static EAS_RESULT TC_SetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value);
+static EAS_RESULT TC_GetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue);
+static EAS_RESULT TC_ParseHeader (S_EAS_DATA *pEASData, S_TC_DATA* pData);
+static EAS_RESULT TC_StartNote (S_EAS_DATA *pEASData, S_TC_DATA* pData, EAS_INT parserMode, EAS_I8 note);
+static EAS_RESULT TC_GetRepeat (S_EAS_DATA *pEASData, S_TC_DATA* pData, EAS_INT parserMode);
+static EAS_RESULT TC_PlayBlock (S_EAS_DATA *pEASData, S_TC_DATA* pData);
+static EAS_RESULT TC_BlockEnd (S_EAS_DATA *pEASData, S_TC_DATA* pData);
+static EAS_RESULT TC_GetVolume (S_EAS_DATA *pEASData, S_TC_DATA* pData);
+static EAS_RESULT TC_GetTempo (S_EAS_DATA *pEASData, S_TC_DATA* pData);
+static EAS_RESULT TC_GetResolution (S_EAS_DATA *pEASData, S_TC_DATA* pData);
+static EAS_RESULT TC_GetNextChar (EAS_HW_DATA_HANDLE hwInstData, S_TC_DATA *pData, EAS_I8 *pValue);
+static void TC_PutBackChar (S_TC_DATA *pData, EAS_I8 value);
+
+/* calculate a new tick time based on resolution & tempo */
+EAS_INLINE void TC_CalcTimeBase (S_TC_DATA *pData)
+{
+
+ /* ticks in 256ths of a millisecond */
+ pData->tick = ((60 * 1000) << 8) / (pData->tempo * pData->resolution);
+}
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_TC_Parser
+ *
+ * This structure contains the functional interface for the iMelody parser
+ *----------------------------------------------------------------------------
+*/
+const S_FILE_PARSER_INTERFACE EAS_TC_Parser =
+{
+ TC_CheckFileType,
+ TC_Prepare,
+ TC_Time,
+ TC_Event,
+ TC_State,
+ TC_Close,
+ TC_Reset,
+ TC_Pause,
+ TC_Resume,
+ NULL,
+ TC_SetData,
+ TC_GetData,
+ NULL
+};
+
+/*----------------------------------------------------------------------------
+ * TC_CheckFileType()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Check the file type to see if we can parse it
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT TC_CheckFileType (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle, EAS_VOID_PTR *ppHandle, EAS_I32 offset)
+{
+ S_TC_DATA data;
+ S_TC_DATA *pData;
+
+ /* init data */
+ EAS_HWMemSet(&data, 0, sizeof(S_TC_DATA));
+ data.fileHandle = fileHandle;
+ data.fileOffset = offset;
+ *ppHandle= NULL;
+
+ /* see if we can parse the header */
+ if (TC_ParseHeader(pEASData, &data) == EAS_SUCCESS)
+ {
+
+ /* check for static memory allocation */
+ if (pEASData->staticMemoryModel)
+ pData = EAS_CMEnumOptData(EAS_MODULE_MMAPI_TONE_CONTROL);
+ else
+ pData = EAS_HWMalloc(pEASData->hwInstData, sizeof(S_TC_DATA));
+ if (!pData)
+ return EAS_ERROR_MALLOC_FAILED;
+
+ /* copy data to persistent storage */
+ EAS_HWMemCpy(pData, &data, sizeof(S_TC_DATA));
+
+ /* return a pointer to the instance data */
+ pData->state = EAS_STATE_OPEN;
+ *ppHandle = pData;
+ }
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * TC_Prepare()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Prepare to parse the file. Allocates instance data (or uses static allocation for
+ * static memory model).
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT TC_Prepare (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
+{
+ S_TC_DATA* pData;
+ EAS_RESULT result;
+
+ /* check for valid state */
+ pData = (S_TC_DATA*) pInstData;
+ if (pData->state != EAS_STATE_OPEN)
+ return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
+
+ /* instantiate a synthesizer */
+ if ((result = VMInitMIDI(pEASData, &pData->pSynth)) != EAS_SUCCESS)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "VMInitMIDI returned %d\n", result); */ }
+ return result;
+ }
+
+ /* set to ready state */
+ pData->state = EAS_STATE_READY;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * TC_Time()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Returns the time of the next event in msecs
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ * pTime - pointer to variable to hold time of next event (in msecs)
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pEASData) reserved for future use */
+static EAS_RESULT TC_Time (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_U32 *pTime)
+{
+ S_TC_DATA *pData;
+
+ pData = (S_TC_DATA*) pInstData;
+
+ /* return time in milliseconds */
+ /*lint -e{704} use shift instead of division */
+ *pTime = pData->time >> 8;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * TC_Event()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Parse the next event in the file
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT TC_Event (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_INT parserMode)
+{
+ S_TC_DATA* pData;
+ EAS_RESULT result;
+ EAS_I8 temp;
+
+ pData = (S_TC_DATA*) pInstData;
+ if (pData->state >= EAS_STATE_OPEN)
+ return EAS_SUCCESS;
+
+ /* initialize MIDI channel when the track starts playing */
+ if (pData->time == 0)
+ {
+ /* set program to square lead */
+ VMProgramChange(pEASData->pVoiceMgr, pData->pSynth, TC_CHANNEL, TC_PROGRAM);
+
+ /* set channel volume to max */
+ VMControlChange(pEASData->pVoiceMgr, pData->pSynth, TC_CHANNEL, 7, 127);
+ }
+
+ /* check for end of note */
+ if (pData->note >= 0)
+ {
+ /* stop the note */
+ VMStopNote(pEASData->pVoiceMgr, pData->pSynth, TC_CHANNEL, (EAS_U8) pData->note, 0);
+
+ /* check for repeat note */
+ if (pData->repeatCount)
+ {
+ pData->repeatCount--;
+ pData->time += pData->length;
+ if ((pData->note >= 0) && (parserMode == eParserModePlay))
+ VMStartNote(pEASData->pVoiceMgr, pData->pSynth, TC_CHANNEL, (EAS_U8) pData->note, pData->volume);
+ return EAS_SUCCESS;
+ }
+
+ pData->note = TC_FIELD_SILENCE;
+ }
+
+ /* parse stream until we get a note or rest */
+ for (;;)
+ {
+
+ /* get next byte from stream */
+ if ((result = TC_GetNextChar(pEASData->hwInstData, pData, &temp)) != EAS_SUCCESS)
+ {
+ if (result == EAS_EOF)
+ {
+ pData->state = EAS_STATE_STOPPING;
+ return EAS_SUCCESS;
+ }
+ break;
+ }
+
+ /* check for musical events */
+ if (temp >= TC_FIELD_SILENCE)
+ {
+ result = TC_StartNote(pEASData, pData, parserMode, temp);
+ break;
+ }
+
+ /* must be a control field */
+ switch (temp)
+ {
+ case TC_FIELD_TEMPO:
+ result = TC_GetTempo(pEASData, pData);
+ break;
+
+ case TC_FIELD_RESOLUTION:
+ result = TC_GetResolution(pEASData, pData);
+ break;
+
+ case TC_FIELD_SET_VOLUME:
+ result = TC_GetVolume(pEASData, pData);
+ break;
+
+ case TC_FIELD_REPEAT:
+ result = TC_GetRepeat(pEASData, pData, parserMode);
+ break;
+
+ case TC_FIELD_PLAY_BLOCK:
+ result = TC_PlayBlock(pEASData, pData);
+ break;
+
+ case TC_FIELD_BLOCK_START:
+ result = TC_GetNextChar(pEASData->hwInstData, pData, &temp);
+ break;
+
+ case TC_FIELD_BLOCK_END:
+ result = TC_BlockEnd(pEASData, pData);
+ break;
+
+ default:
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Unexpected byte 0x%02x in ToneControl stream\n", temp); */ }
+ result = EAS_ERROR_FILE_FORMAT;
+ }
+
+ /* check for error */
+ if (result != EAS_SUCCESS)
+ break;
+ }
+
+ /* check for error */
+ if (result != EAS_SUCCESS)
+ {
+ if (result == EAS_EOF)
+ result = EAS_ERROR_FILE_FORMAT;
+ pData->state = EAS_STATE_ERROR;
+ }
+ else
+ pData->state = EAS_STATE_PLAY;
+ return result;
+}
+
+/*----------------------------------------------------------------------------
+ * TC_State()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Returns the current state of the stream
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ * pState - pointer to variable to store state
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pEASData) reserved for future use */
+static EAS_RESULT TC_State (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 *pState)
+{
+ S_TC_DATA* pData;
+
+ /* establish pointer to instance data */
+ pData = (S_TC_DATA*) pInstData;
+
+ /* if stopping, check to see if synth voices are active */
+ if (pData->state == EAS_STATE_STOPPING)
+ {
+ if (VMActiveVoices(pData->pSynth) == 0)
+ pData->state = EAS_STATE_STOPPED;
+ }
+
+ if (pData->state == EAS_STATE_PAUSING)
+ {
+ if (VMActiveVoices(pData->pSynth) == 0)
+ pData->state = EAS_STATE_PAUSED;
+ }
+
+ /* return current state */
+ *pState = pData->state;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * TC_Close()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Close the file and clean up
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT TC_Close (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
+{
+ S_TC_DATA* pData;
+ EAS_RESULT result;
+
+ pData = (S_TC_DATA*) pInstData;
+
+ /* close the file */
+ if ((result = EAS_HWCloseFile(pEASData->hwInstData, pData->fileHandle)) != EAS_SUCCESS)
+ return result;
+
+ /* free the synth */
+ if (pData->pSynth != NULL)
+ VMMIDIShutdown(pEASData, pData->pSynth);
+
+ /* if using dynamic memory, free it */
+ if (!pEASData->staticMemoryModel)
+ EAS_HWFree(pEASData->hwInstData, pData);
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * TC_Reset()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Reset the sequencer. Used for locating backwards in the file.
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT TC_Reset (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
+{
+ S_TC_DATA* pData;
+ EAS_RESULT result;
+
+ pData = (S_TC_DATA*) pInstData;
+
+ /* reset the synth */
+ VMReset(pEASData->pVoiceMgr, pData->pSynth, EAS_TRUE);
+
+ /* reset time to zero */
+ pData->time = 0;
+
+ /* reset file position and re-parse header */
+ pData->state = EAS_STATE_ERROR;
+ if ((result = EAS_HWFileSeek(pEASData->hwInstData, pData->fileHandle, pData->fileOffset)) != EAS_SUCCESS)
+ return result;
+ if ((result = TC_ParseHeader (pEASData, pData)) != EAS_SUCCESS)
+ return result;
+
+ pData->state = EAS_STATE_READY;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * TC_Pause()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Pauses the sequencer. Mutes all voices and sets state to pause.
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT TC_Pause (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
+{
+ S_TC_DATA *pData;
+
+ /* can't pause a stopped stream */
+ pData = (S_TC_DATA*) pInstData;
+ if (pData->state == EAS_STATE_STOPPED)
+ return EAS_ERROR_ALREADY_STOPPED;
+
+ /* mute the synthesizer */
+ VMMuteAllVoices(pEASData->pVoiceMgr, pData->pSynth);
+ pData->state = EAS_STATE_PAUSING;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * TC_Resume()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Resume playing after a pause, sets state back to playing.
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pEASData) reserved for future use */
+static EAS_RESULT TC_Resume (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
+{
+ S_TC_DATA *pData;
+
+ /* can't resume a stopped stream */
+ pData = (S_TC_DATA*) pInstData;
+ if (pData->state == EAS_STATE_STOPPED)
+ return EAS_ERROR_ALREADY_STOPPED;
+
+ /* nothing to do but resume playback */
+ pData->state = EAS_STATE_PLAY;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * TC_SetData()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Return file type
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pEASData, pInstData, value) reserved for future use */
+static EAS_RESULT TC_SetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value)
+{
+ /* we don't parse any metadata, but we need to return success here */
+ if (param == PARSER_DATA_METADATA_CB)
+ return EAS_SUCCESS;
+
+ return EAS_ERROR_INVALID_PARAMETER;
+}
+
+/*----------------------------------------------------------------------------
+ * TC_GetData()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Return file type
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -e{715} common with other parsers */
+static EAS_RESULT TC_GetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue)
+{
+ S_TC_DATA *pData;
+
+ pData = (S_TC_DATA *) pInstData;
+ switch (param)
+ {
+ /* return file type as TC */
+ case PARSER_DATA_FILE_TYPE:
+ *pValue = EAS_FILE_MMAPI_TONE_CONTROL;
+ break;
+
+ case PARSER_DATA_SYNTH_HANDLE:
+ *pValue = (EAS_I32) pData->pSynth;
+ break;
+
+ default:
+ return EAS_ERROR_INVALID_PARAMETER;
+ }
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * TC_ParseHeader()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Prepare to parse the file. Allocates instance data (or uses static allocation for
+ * static memory model).
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT TC_ParseHeader (S_EAS_DATA *pEASData, S_TC_DATA* pData)
+{
+ EAS_RESULT result;
+ EAS_I8 temp;
+
+ /* initialize some defaults */
+ pData->time = 0;
+ pData->tempo = 120;
+ pData->resolution = 64;
+ pData->volume = 127;
+ pData->repeatCount = 0;
+ pData->note = TC_FIELD_SILENCE;
+ pData->byteAvail = EAS_FALSE;
+
+ /* set default timebase */
+ TC_CalcTimeBase(pData);
+
+ /* seek to start of data */
+ if ((result = EAS_HWFileSeek(pEASData->hwInstData, pData->fileHandle, pData->fileOffset)) != EAS_SUCCESS)
+ return result;
+
+ /* get version */
+ if ((result = TC_GetNextChar(pEASData->hwInstData, pData, &temp)) != EAS_SUCCESS)
+ return result;
+
+ /* check for version number */
+ if (temp == TC_FIELD_VERSION)
+ {
+ TC_GetNextChar(pEASData->hwInstData, pData, &temp);
+// { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "ToneControl sequence version %d\n", temp); */ }
+ }
+ else
+ return EAS_ERROR_FILE_FORMAT;
+
+ /* parse the header data until we find the first note or block */
+ for (;;)
+ {
+
+ /* get next byte from stream */
+ if ((result = TC_GetNextChar(pEASData->hwInstData, pData, &temp)) != EAS_SUCCESS)
+ return result;
+
+ /* check for tempo */
+ if (temp == TC_FIELD_TEMPO)
+ {
+ if ((result = TC_GetTempo(pEASData, pData)) != EAS_SUCCESS)
+ return result;
+ }
+
+ /* or resolution */
+ else if (temp == TC_FIELD_TEMPO)
+ {
+ if ((result = TC_GetResolution(pEASData, pData)) != EAS_SUCCESS)
+ return result;
+ }
+
+ /* must be music data */
+ else if (temp > TC_FIELD_INVALID)
+ {
+ TC_PutBackChar(pData, temp);
+ return EAS_SUCCESS;
+ }
+
+ /* unknown codes */
+ else
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Unexpected byte 0x%02x in ToneControl stream\n", temp); */ }
+ return EAS_ERROR_FILE_FORMAT;
+ }
+ }
+}
+
+/*----------------------------------------------------------------------------
+ * TC_StartNote()
+ *----------------------------------------------------------------------------
+ * Process a note or silence event
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT TC_StartNote (S_EAS_DATA *pEASData, S_TC_DATA* pData, EAS_INT parserMode, EAS_I8 note)
+{
+ EAS_I8 duration;
+
+ /* get the duration */
+ if (TC_GetNextChar(pEASData->hwInstData, pData, &duration) != EAS_SUCCESS)
+ return EAS_ERROR_FILE_FORMAT;
+
+ /* calculate time of next event */
+ pData->length = (EAS_I32) duration * pData->tick;
+ pData->time += pData->length;
+
+ /* start the note */
+ if ((note >= 0) && (parserMode == eParserModePlay))
+ {
+ VMStartNote(pEASData->pVoiceMgr, pData->pSynth, TC_CHANNEL, (EAS_U8) note, pData->volume);
+ pData->note = note;
+ }
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * TC_GetRepeat()
+ *----------------------------------------------------------------------------
+ * Process a repeat code
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT TC_GetRepeat (S_EAS_DATA *pEASData, S_TC_DATA* pData, EAS_INT parserMode)
+{
+ EAS_I8 count;
+
+ /* get the repeat count */
+ if (TC_GetNextChar(pEASData->hwInstData, pData, &count) != EAS_SUCCESS)
+ return EAS_ERROR_FILE_FORMAT;
+
+ /* validiate it */
+ if (count < 2)
+ return EAS_ERROR_FILE_FORMAT;
+
+ /* calculate time of next event */
+ pData->time += pData->length;
+ pData->repeatCount = count - 2;
+
+ /* start the note */
+ if ((pData->note >= 0) && (parserMode == eParserModePlay))
+ VMStartNote(pEASData->pVoiceMgr, pData->pSynth, TC_CHANNEL, (EAS_U8) pData->note, pData->volume);
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * TC_PlayBlock()
+ *----------------------------------------------------------------------------
+ * Play a block of notes
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT TC_PlayBlock (S_EAS_DATA *pEASData, S_TC_DATA* pData)
+{
+ EAS_RESULT result;
+ EAS_I8 blockNum;
+ EAS_I8 temp;
+ EAS_I8 temp2;
+
+ /* get the block number */
+ if (TC_GetNextChar(pEASData->hwInstData, pData, &blockNum) != EAS_SUCCESS)
+ return EAS_ERROR_FILE_FORMAT;
+
+ /* validiate it */
+ if (blockNum < 0)
+ return EAS_ERROR_FILE_FORMAT;
+
+ /* save the current position */
+ if ((result = EAS_HWFilePos(pEASData->hwInstData, pData->fileHandle, &pData->restorePos)) != EAS_SUCCESS)
+ return result;
+
+ /* return to start of file */
+ pData->byteAvail = EAS_FALSE;
+ if ((result = EAS_HWFileSeek(pEASData->hwInstData, pData->fileHandle, pData->fileOffset)) != EAS_SUCCESS)
+ return result;
+
+ /* find the block */
+ for (;;)
+ {
+ if (TC_GetNextChar(pEASData->hwInstData, pData, &temp) != EAS_SUCCESS)
+ return EAS_ERROR_FILE_FORMAT;
+
+ if (TC_GetNextChar(pEASData->hwInstData, pData, &temp2) != EAS_SUCCESS)
+ return EAS_ERROR_FILE_FORMAT;
+
+ if ((temp == TC_FIELD_BLOCK_START) && (temp2 == blockNum))
+ return EAS_SUCCESS;
+ }
+}
+
+/*----------------------------------------------------------------------------
+ * TC_BlockEnd()
+ *----------------------------------------------------------------------------
+ * Handle end of block
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT TC_BlockEnd (S_EAS_DATA *pEASData, S_TC_DATA* pData)
+{
+ EAS_I8 blockNum;
+
+ /* get the block number */
+ if (TC_GetNextChar(pEASData->hwInstData, pData, &blockNum) != EAS_SUCCESS)
+ return EAS_ERROR_FILE_FORMAT;
+
+ /* validiate it */
+ if (blockNum < 0)
+ return EAS_ERROR_FILE_FORMAT;
+
+ /* if we were playing this block, restore to previous position */
+ pData->byteAvail = EAS_FALSE;
+ return EAS_HWFileSeek(pEASData->hwInstData, pData->fileHandle, pData->restorePos);
+}
+
+/*----------------------------------------------------------------------------
+ * TC_GetVolume()
+ *----------------------------------------------------------------------------
+ * Get the volume field and process it
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT TC_GetVolume (S_EAS_DATA *pEASData, S_TC_DATA* pData)
+{
+ EAS_I8 volume;
+
+ /* get volume */
+ if (TC_GetNextChar(pEASData->hwInstData, pData, &volume) != EAS_SUCCESS)
+ return EAS_ERROR_FILE_FORMAT;
+ if ((volume < 0) || (volume > 100))
+ return EAS_ERROR_FILE_FORMAT;
+
+ /* save volume */
+ pData->volume = (EAS_U8) ((EAS_I32) (volume * TC_VOLUME_CONV + 1) >> TC_VOLUME_SHIFT);
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * TC_GetTempo()
+ *----------------------------------------------------------------------------
+ * Get the tempo field and process it
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT TC_GetTempo (S_EAS_DATA *pEASData, S_TC_DATA* pData)
+{
+ EAS_I8 tempo;
+
+ /* get tempo */
+ if (TC_GetNextChar(pEASData->hwInstData, pData, &tempo) != EAS_SUCCESS)
+ return EAS_ERROR_FILE_FORMAT;
+ if (tempo < 5)
+ return EAS_ERROR_FILE_FORMAT;
+
+ /* save tempo */
+ pData->tempo = tempo;
+
+ /* calculate new timebase */
+ TC_CalcTimeBase(pData);
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * TC_GetResolution()
+ *----------------------------------------------------------------------------
+ * Get the resolution field and process it
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT TC_GetResolution (S_EAS_DATA *pEASData, S_TC_DATA* pData)
+{
+ EAS_I8 resolution;
+
+ /* get resolution */
+ if (TC_GetNextChar(pEASData->hwInstData, pData, &resolution) != EAS_SUCCESS)
+ return EAS_ERROR_FILE_FORMAT;
+ if (resolution < 0)
+ return EAS_ERROR_FILE_FORMAT;
+
+ /* save tempo */
+ pData->resolution = resolution;
+
+ /* calculate new timebase */
+ TC_CalcTimeBase(pData);
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * TC_GetNextChar()
+ *----------------------------------------------------------------------------
+ * Fetch the next character from the stream
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT TC_GetNextChar (EAS_HW_DATA_HANDLE hwInstData, S_TC_DATA *pData, EAS_I8 *pValue)
+{
+
+ /* get character from "put back" buffer */
+ if (pData->byteAvail)
+ {
+ pData->byteAvail = EAS_FALSE;
+ *pValue = pData->dataByte;
+ return EAS_SUCCESS;
+ }
+
+ /* get character from file */
+ return EAS_HWGetByte(hwInstData, pData->fileHandle, pValue);
+}
+
+/*----------------------------------------------------------------------------
+ * TC_PutBackChar()
+ *----------------------------------------------------------------------------
+ * Put back the character
+ *----------------------------------------------------------------------------
+*/
+static void TC_PutBackChar (S_TC_DATA *pData, EAS_I8 value)
+{
+
+ pData->dataByte = value;
+ pData->byteAvail = EAS_TRUE;
+}
+
diff --git a/arm-wt-22k/lib_src/eas_vm_protos.h b/arm-wt-22k/lib_src/eas_vm_protos.h
index eb49ba8..20f7c09 100644
--- a/arm-wt-22k/lib_src/eas_vm_protos.h
+++ b/arm-wt-22k/lib_src/eas_vm_protos.h
@@ -1,12 +1,12 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_vm_protos.h
- *
- * Contents and purpose:
- * Declarations, interfaces, and prototypes for voice manager.
- *
- * Copyright Sonic Network Inc. 2004
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_vm_protos.h
+ *
+ * Contents and purpose:
+ * Declarations, interfaces, and prototypes for voice manager.
+ *
+ * Copyright Sonic Network Inc. 2004
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,1068 +19,1068 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 736 $
- * $Date: 2007-06-22 13:51:24 -0700 (Fri, 22 Jun 2007) $
- *----------------------------------------------------------------------------
-*/
-
-#ifndef _EAS_VM_PROTOS_H
-#define _EAS_VM_PROTOS_H
-
-// includes
-#include "eas_data.h"
-#include "eas_sndlib.h"
-
-/*----------------------------------------------------------------------------
- * VMInitialize()
- *----------------------------------------------------------------------------
- * Purpose:
- *
- * Inputs:
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT VMInitialize (S_EAS_DATA *pEASData);
-
-/*----------------------------------------------------------------------------
- * VMInitMIDI()
- *----------------------------------------------------------------------------
- * Purpose:
- *
- * Inputs:
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT VMInitMIDI (S_EAS_DATA *pEASData, S_SYNTH **ppSynth);
-
-/*----------------------------------------------------------------------------
- * VMInitializeAllChannels()
- *----------------------------------------------------------------------------
- * Purpose:
- *
- * Inputs:
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- *
- *----------------------------------------------------------------------------
-*/
-void VMInitializeAllChannels (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth);
-
-/*----------------------------------------------------------------------------
- * VMResetControllers()
- *----------------------------------------------------------------------------
- * Purpose:
- *
- * Inputs:
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- *
- *----------------------------------------------------------------------------
-*/
-void VMResetControllers (S_SYNTH *pSynth);
-
-/*----------------------------------------------------------------------------
- * VMInitMIPTable()
- *----------------------------------------------------------------------------
- * Purpose:
- * Initialize the SP-MIDI MIP table
- *
- * Inputs:
- * pEASData - pointer to synthesizer instance data
- * mute - EAS_FALSE to unmute channels, EAS_TRUE to mute
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-void VMInitMIPTable (S_SYNTH *pSynth);
-
-/*----------------------------------------------------------------------------
- * VMSetMIPEntry()
- *----------------------------------------------------------------------------
- * Purpose:
- * Sets the priority and MIP level for a MIDI channel
- *
- * Inputs:
- * pEASData - pointer to synthesizer instance data
- * channel - MIDI channel number
- * priority - priority (0-15 with 0 = highest priority)
- * mip - maximum instantaneous polyphony
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-void VMSetMIPEntry (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel, EAS_U8 priority, EAS_U8 mip);
-
-/*----------------------------------------------------------------------------
- * VMUpdateMIPTable()
- *----------------------------------------------------------------------------
- * Purpose:
- * This routine is called when the polyphony count in the synthesizer changes
- *
- * Inputs:
- * pEASData - pointer to synthesizer instance data
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-void VMUpdateMIPTable (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth);
-
-/*----------------------------------------------------------------------------
- * VMInitializeAllVoices()
- *----------------------------------------------------------------------------
- * Purpose:
- *
- * Inputs:
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- *
- *----------------------------------------------------------------------------
-*/
-void VMInitializeAllVoices (S_VOICE_MGR *pVoiceMgr, EAS_INT vSynthNum);
-
-/*----------------------------------------------------------------------------
- * VMStartNote()
- *----------------------------------------------------------------------------
- * Purpose:
- * Update the synth's state to play the requested note on the requested
- * channel if possible.
- *
- * Inputs:
- * nChannel - the MIDI channel
- * nKeyNumber - the MIDI key number for this note
- * nNoteVelocity - the key velocity for this note
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- *
- *----------------------------------------------------------------------------
-*/
-void VMStartNote (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel, EAS_U8 note, EAS_U8 velocity);
-
-/*----------------------------------------------------------------------------
- * VMCheckKeyGroup()
- *----------------------------------------------------------------------------
- * Purpose:
- * If the note that we've been asked to start is in the same key group as
- * any currently playing notes, then we must shut down the currently playing
- * note in the same key group and then start the newly requested note.
- *
- * Inputs:
- * nChannel - synth channel that wants to start a new note
- * nKeyNumber - new note's midi note number
- * nRegionIndex - calling routine finds this index and gives to us
- * nNoteVelocity - new note's velocity
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- * pbVoiceStealingRequired - flag: this routine sets true if we needed to
- * steal a voice
- *
- * Side Effects:
- * gsSynthObject.m_sVoice[free voice num].m_nKeyNumber may be assigned
- * gsSynthObject.m_sVoice[free voice num].m_nVelocity may be assigned
- *----------------------------------------------------------------------------
-*/
-void VMCheckKeyGroup (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U16 keyGroup, EAS_U8 channel);
-
-/*----------------------------------------------------------------------------
- * VMCheckPolyphonyLimiting()
- *----------------------------------------------------------------------------
- * Purpose:
- * We only play at most 2 of the same note on a MIDI channel.
- * E.g., if we are asked to start note 36, and there are already two voices
- * that are playing note 36, then we must steal the voice playing
- * the oldest note 36 and use that stolen voice to play the new note 36.
- *
- * Inputs:
- * nChannel - synth channel that wants to start a new note
- * nKeyNumber - new note's midi note number
- * nNoteVelocity - new note's velocity
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- * pbVoiceStealingRequired - flag: this routine sets true if we needed to
- * steal a voice
- * *
- * Side Effects:
- * psSynthObject->m_sVoice[free voice num].m_nKeyNumber may be assigned
- * psSynthObject->m_sVoice[free voice num].m_nVelocity may be assigned
- *----------------------------------------------------------------------------
-*/
-EAS_BOOL VMCheckPolyphonyLimiting (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel, EAS_U8 note, EAS_U8 velocity, EAS_U16 regionIndex, EAS_I32 lowVoice, EAS_I32 highVoice);
-
-/*----------------------------------------------------------------------------
- * VMStopNote()
- *----------------------------------------------------------------------------
- * Purpose:
- * Update the synth's state to end the requested note on the requested
- * channel.
- *
- * Inputs:
- * nChannel - the MIDI channel
- * nKeyNumber - the key number of the note to stop
- * nNoteVelocity - the note-off velocity
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- * Side Effects:
- * gsSynthObject.m_sVoice[free voice num].m_nSynthChannel may be assigned
- * gsSynthObject.m_sVoice[free voice num].m_nKeyNumber is assigned
- * gsSynthObject.m_sVoice[free voice num].m_nVelocity is assigned
- *----------------------------------------------------------------------------
-*/
-void VMStopNote (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel, EAS_U8 key, EAS_U8 velocity);
-
-/*----------------------------------------------------------------------------
- * VMFindAvailableVoice()
- *----------------------------------------------------------------------------
- * Purpose:
- * Find an available voice and return the voice number if available.
- *
- * Inputs:
- * pnVoiceNumber - really an output, see below
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- * pnVoiceNumber - returns the voice number of available voice if found
- * success - if there is an available voice
- * failure - otherwise
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT VMFindAvailableVoice (S_VOICE_MGR *pVoiceMgr, EAS_INT *pVoiceNumber, EAS_I32 lowVoice, EAS_I32 highVoice);
-
-/*----------------------------------------------------------------------------
- * VMStealVoice()
- *----------------------------------------------------------------------------
- * Purpose:
- * Steal a voice and return the voice number
- *
- * Stealing algorithm: steal the best choice with minimal work, taking into
- * account SP-Midi channel priorities and polyphony allocation.
- *
- * In one pass through all the voices, figure out which voice to steal
- * taking into account a number of different factors:
- * Priority of the voice's MIDI channel
- * Number of voices over the polyphony allocation for voice's MIDI channel
- * Amplitude of the voice
- * Note age
- * Key velocity (for voices that haven't been started yet)
- * If any matching notes are found
- *
- * Inputs:
- * nChannel - the channel that this voice wants to be started on
- * nKeyNumber - the key number for this new voice
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- * pnVoiceNumber - voice stolen
- * EAS_RESULT EAS_SUCCESS - always successful
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT VMStealVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_INT *pVoiceNumber, EAS_U8 channel, EAS_U8 note, EAS_I32 lowVoice, EAS_I32 highVoice);
-
-/*----------------------------------------------------------------------------
- * VMAddSamples()
- *----------------------------------------------------------------------------
- * Purpose:
- * Synthesize the requested number of samples.
- *
- * Inputs:
- * nNumSamplesToAdd - number of samples to write to buffer
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- * number of samples actually written to buffer
- *
- * Side Effects:
- * - samples are added to the presently free buffer
- *
- *----------------------------------------------------------------------------
-*/
-EAS_I32 VMAddSamples (S_VOICE_MGR *pVoiceMgr, EAS_I32 *pMixBuffer, EAS_I32 numSamplesToAdd);
-
-/*----------------------------------------------------------------------------
- * VMProgramChange()
- *----------------------------------------------------------------------------
- * Purpose:
- * Change the instrument (program) for the given channel.
- *
- * Depending on the program number, and the bank selected for this channel, the
- * program may be in ROM, RAM (from SMAF or CMX related RAM wavetable), or
- * Alternate wavetable (from mobile DLS or other DLS file)
- *
- * This function figures out what wavetable should be used, and sets it up as the
- * wavetable to use for this channel. Also the channel may switch from a melodic
- * channel to a rhythm channel, or vice versa.
- *
- * Inputs:
- *
- * Outputs:
- * Side Effects:
- * gsSynthObject.m_sChannel[nChannel].m_nProgramNumber is likely changed
- * gsSynthObject.m_sChannel[nChannel].m_psEAS may be changed
- * gsSynthObject.m_sChannel[nChannel].m_bRhythmChannel may be changed
- *
- *----------------------------------------------------------------------------
-*/
-void VMProgramChange (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel, EAS_U8 program);
-
-/*----------------------------------------------------------------------------
- * VMChannelPressure()
- *----------------------------------------------------------------------------
- * Purpose:
- * Change the channel pressure for the given channel
- *
- * Inputs:
- * nChannel - the MIDI channel
- * nVelocity - the channel pressure value
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- * Side Effects:
- * gsSynthObject.m_sChannel[nChannel].m_nChannelPressure is updated
- *----------------------------------------------------------------------------
-*/
-void VMChannelPressure (S_SYNTH *pSynth, EAS_U8 channel, EAS_U8 value);
-
-/*----------------------------------------------------------------------------
- * VMPitchBend()
- *----------------------------------------------------------------------------
- * Purpose:
- * Change the pitch wheel value for the given channel.
- * This routine constructs the proper 14-bit argument when the calling routine
- * passes the pitch LSB and MSB.
- *
- * Note: some midi disassemblers display a bipolar pitch bend value.
- * We can display the bipolar value using
- * if m_nPitchBend >= 0x2000
- * bipolar pitch bend = postive (m_nPitchBend - 0x2000)
- * else
- * bipolar pitch bend = negative (0x2000 - m_nPitchBend)
- *
- * Inputs:
- * nChannel - the MIDI channel
- * nPitchLSB - the LSB byte from the pitch bend message
- * nPitchMSB - the MSB byte from the message
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- *
- * Side Effects:
- * gsSynthObject.m_sChannel[nChannel].m_nPitchBend is changed
- *
- *----------------------------------------------------------------------------
-*/
-void VMPitchBend (S_SYNTH *pSynth, EAS_U8 channel, EAS_U8 pitchLSB, EAS_U8 pitchMSB);
-
-/*----------------------------------------------------------------------------
- * VMControlChange()
- *----------------------------------------------------------------------------
- * Purpose:
- * Change the controller (or mode) for the given channel.
- *
- * Inputs:
- * nChannel - the MIDI channel
- * nControllerNumber - the controller number
- * nControlValue - the controller number for this control change
- * nControlValue - the value for this control change
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- * Side Effects:
- * gsSynthObject.m_sChannel[nChannel] controller is changed
- *
- *----------------------------------------------------------------------------
-*/
-void VMControlChange (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel, EAS_U8 controller, EAS_U8 value);
-
-/*----------------------------------------------------------------------------
- * VMUpdateRPNStateMachine()
- *----------------------------------------------------------------------------
- * Purpose:
- * Call this function when we want to parse a stream of RPN messages.
- * NOTE: The synth has only one set of global RPN data instead of RPN data
- * per channel.
- * So actually, we don't really need to look at the nChannel parameter,
- * but we pass it to facilitate future upgrades. Furthermore, we only
- * support RPN0 (pitch bend sensitivity), RPN1 (fine tuning) and
- * RPN2 (coarse tuning). Any other RPNs are rejected.
- *
- * Inputs:
- * nChannel - the MIDI channel
- * nControllerNumber - the RPN controller number
- * nControlValue - the value for this control change
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- *
- * Side Effects:
- * gsSynthObject.m_RPN0 (or m_RPN1 or m_RPN2) may be updated if the
- * proper RPN message sequence is parsed.
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT VMUpdateRPNStateMachine (S_SYNTH *pSynth, EAS_U8 channel, EAS_U8 controller, EAS_U8 value);
-
-/*----------------------------------------------------------------------------
- * VMUpdateStaticChannelParameters()
- *----------------------------------------------------------------------------
- * Purpose:
- * Update all of the static channel parameters for channels that have had
- * a controller change values
- * Or if the synth has signalled that all channels must forcibly
- * be updated
- *
- * Inputs:
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- * none
- *
- * Side Effects:
- * - psSynthObject->m_sChannel[].m_nStaticGain and m_nStaticPitch
- * are updated for channels whose controller values have changed
- * or if the synth has signalled that all channels must forcibly
- * be updated
- *----------------------------------------------------------------------------
-*/
-void VMUpdateStaticChannelParameters (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth);
-
-/*----------------------------------------------------------------------------
- * VMReleaseAllDeferredNoteOffs()
- *----------------------------------------------------------------------------
- * Purpose:
- * Call this functin when the sustain flag is presently set but
- * we are now transitioning from damper pedal on to
- * damper pedal off. This means all notes in this channel
- * that received a note off while the damper pedal was on, and
- * had their note-off requests deferred, should now proceed to
- * the release state.
- *
- * Inputs:
- * nChannel - this channel has its sustain pedal transitioning from on to off
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- * Side Effects:
- * any voice with deferred note offs on this channel are updated such that
- *
- *
- *----------------------------------------------------------------------------
-*/
-void VMReleaseAllDeferredNoteOffs (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel);
-
-/*----------------------------------------------------------------------------
- * VMCatchNotesForSustainPedal()
- *----------------------------------------------------------------------------
- * Purpose:
- * Call this function when the sustain flag is presently clear and
- * the damper pedal is off and we are transitioning from damper pedal OFF to
- * damper pedal ON. Currently sounding notes should be left
- * unchanged. However, we should try to "catch" notes if possible.
- * If any notes have levels >= sustain level, catch them,
- * otherwise, let them continue to release.
- *
- * Inputs:
- * nChannel - this channel has its sustain pedal transitioning from on to off
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- * Side Effects:
- * any voice with deferred note offs on this channel are updated such that
- * psVoice->m_sEG1.m_eState = eEnvelopeStateSustainPedal
- *----------------------------------------------------------------------------
-*/
-void VMCatchNotesForSustainPedal (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel);
-
-/*----------------------------------------------------------------------------
- * VMUpdateAllNotesAge()
- *----------------------------------------------------------------------------
- * Purpose:
- * Increment the note age for all voices older than the age of the voice
- * that is stopping, effectively making the voices "younger".
- *
- * Inputs:
- * nAge - age of voice that is going away
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- *
- * Side Effects:
- * m_nAge for some voices is incremented
- *----------------------------------------------------------------------------
-*/
-void VMUpdateAllNotesAge (S_VOICE_MGR *pVoiceMgr, EAS_U16 nAge);
-
-/*----------------------------------------------------------------------------
- * VMFindRegionIndex()
- *----------------------------------------------------------------------------
- * Purpose:
- * Find the region index for the given instrument using the midi key number
- * and the RPN2 (coarse tuning) value. By using RPN2 as part of the
- * region selection process, we reduce the amount a given sample has
- * to be transposed by selecting the closest recorded root instead.
- *
- * Inputs:
- * nChannel - current channel for this note
- * nKeyNumber - current midi note number
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- * pnRegionIndex - valid only if we returned success
- * success if we found the region index number, otherwise
- * failure
- *
- * Side Effects:
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT VMFindRegionIndex (S_VOICE_MGR *pVoiceMgr, EAS_U8 channel, EAS_U8 note, EAS_U16 *pRegionIndex);
-
-/*----------------------------------------------------------------------------
- * VMIncRefCount()
- *----------------------------------------------------------------------------
- * Increment reference count for virtual synth
- *----------------------------------------------------------------------------
-*/
-void VMIncRefCount (S_SYNTH *pSynth);
-
-/*----------------------------------------------------------------------------
- * VMReset()
- *----------------------------------------------------------------------------
- * Purpose:
- * We call this routine to start the process of reseting the synth.
- * This routine sets a flag for the entire synth indicating that we want
- * to reset.
- * We also force all voices to mute quickly.
- * However, we do not actually perform any synthesis in this routine. That
- * is, we do not ramp the voices down from this routine, but instead, we
- * let the "regular" synth processing steps take care of adding the ramp
- * down samples to the output buffer. After we are sure that all voices
- * have completed ramping down, we continue the process of resetting the
- * synth (from another routine).
- *
- * Inputs:
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- *
- * Side Effects:
- * - set a flag (in gsSynthObject.m_nFlags) indicating synth reset requested.
- * - force all voices to update their envelope states to mute
- *
- *----------------------------------------------------------------------------
-*/
-void VMReset (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_BOOL force);
-
-/*----------------------------------------------------------------------------
- * VMMuteAllVoices()
- *----------------------------------------------------------------------------
- * Purpose:
- * We call this in an emergency reset situation.
- * This forces all voices to mute quickly.
- *
- * Inputs:
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- *
- * Side Effects:
- * - forces all voices to update their envelope states to mute
- *
- *----------------------------------------------------------------------------
-*/
-void VMMuteVoice (S_VOICE_MGR *pVoiceMgr, EAS_I32 voiceNum);
-void VMMuteAllVoices (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth);
-
-/*----------------------------------------------------------------------------
- * VMReleaseAllVoices()
- *----------------------------------------------------------------------------
- * Purpose:
- * We call this after we've encountered the end of the Midi file.
- * This ensures all voice are either in release (because we received their
- * note off already) or forces them to mute quickly.
- * We use this as a safety to prevent bad midi files from playing forever.
- *
- * Inputs:
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- *
- * Side Effects:
- * - forces all voices to update their envelope states to release or mute
- *
- *----------------------------------------------------------------------------
-*/
-void VMReleaseAllVoices (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth);
-
-/*----------------------------------------------------------------------------
- * VMAllNotesOff()
- *----------------------------------------------------------------------------
- * Purpose:
- * Quickly mute all notes on the given channel.
- *
- * Inputs:
- * nChannel - quickly turn off all notes on this channel
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- *
- * Side Effects:
- * - forces all voices on this channel to update their envelope states to mute
- *
- *----------------------------------------------------------------------------
-*/
-void VMAllNotesOff (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel);
-
-/*----------------------------------------------------------------------------
- * VMDeferredStopNote()
- *----------------------------------------------------------------------------
- * Purpose:
- * Stop the notes that had deferred note-off requests.
- *
- * Inputs:
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- * None.
- *
- * Side Effects:
- * voices that have had deferred note-off requests are now put into release
- * gsSynthObject.m_sVoice[i].m_nFlags has the VOICE_FLAG_DEFER_MIDI_NOTE_OFF
- * cleared
- *----------------------------------------------------------------------------
-*/
-void VMDeferredStopNote (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth);
-
-/*----------------------------------------------------------------------------
- * VMSetSynthPolyphony()
- *----------------------------------------------------------------------------
- * Purpose:
- * Set the synth to a new polyphony value. Value must be >= 1 and
- * <= MAX_SYNTH_VOICES. This function will pin the polyphony at those limits
- *
- * Inputs:
- * pVoiceMgr pointer to synthesizer data
- * synth synthesizer number (0 = onboard, 1 = DSP)
- * polyphonyCount desired polyphony count
- *
- * Outputs:
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT VMSetSynthPolyphony (S_VOICE_MGR *pVoiceMgr, EAS_I32 synth, EAS_I32 polyphonyCount);
-
-/*----------------------------------------------------------------------------
- * VMGetSynthPolyphony()
- *----------------------------------------------------------------------------
- * Purpose:
- * Set the synth to a new polyphony value. Value must be >= 1 and
- * <= MAX_SYNTH_VOICES. This function will pin the polyphony at those limits
- *
- * Inputs:
- * pVoiceMgr pointer to synthesizer data
- * synth synthesizer number (0 = onboard, 1 = DSP)
- * polyphonyCount desired polyphony count
- *
- * Outputs:
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT VMGetSynthPolyphony (S_VOICE_MGR *pVoiceMgr, EAS_I32 synth, EAS_I32 *pPolyphonyCount);
-
-/*----------------------------------------------------------------------------
- * VMSetPolyphony()
- *----------------------------------------------------------------------------
- * Purpose:
- * Set the virtual synth polyphony. 0 = no limit (i.e. can use
- * all available voices).
- *
- * Inputs:
- * pVoiceMgr pointer to synthesizer data
- * polyphonyCount desired polyphony count
- * pSynth pointer to virtual synth
- *
- * Outputs:
- * Returns error code
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT VMSetPolyphony (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_I32 polyphonyCount);
-
-/*----------------------------------------------------------------------------
- * VMGetPolyphony()
- *----------------------------------------------------------------------------
- * Purpose:
- * Returns the current polyphony setting
- *
- * Inputs:
- * pVoiceMgr pointer to synthesizer data
- * pSynth pointer to virtual synth
- * pPolyphonyCount pointer to variable to receive data
- *
- * Outputs:
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT VMGetPolyphony (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_I32 *pPolyphonyCount);
-
-/*----------------------------------------------------------------------------
- * VMSetPriority()
- *----------------------------------------------------------------------------
- * Purpose:
- * Set the virtual synth priority
- *
- * Inputs:
- * pVoiceMgr pointer to synthesizer data
- * priority new priority
- * pSynth pointer to virtual synth
- *
- * Outputs:
- * Returns error code
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT VMSetPriority (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_I32 priority);
-
-/*----------------------------------------------------------------------------
- * VMGetPriority()
- *----------------------------------------------------------------------------
- * Purpose:
- * Get the virtual synth priority
- *
- * Inputs:
- * pVoiceMgr pointer to synthesizer data
- * pPriority pointer to variable to hold priority
- * pSynth pointer to virtual synth
- *
- * Outputs:
- * Returns error code
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT VMGetPriority (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_I32 *pPriority);
-
-/*----------------------------------------------------------------------------
- * VMSetVolume()
- *----------------------------------------------------------------------------
- * Purpose:
- * Set the master volume for this sequence
- *
- * Inputs:
- * nSynthVolume - the desired master volume
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- *
- *
- * Side Effects:
- * overrides any previously set master volume from sysex
- *
- *----------------------------------------------------------------------------
-*/
-void VMSetVolume (S_SYNTH *pSynth, EAS_U16 masterVolume);
-
-/*----------------------------------------------------------------------------
- * VMSetPitchBendRange()
- *----------------------------------------------------------------------------
- * Set the pitch bend range for the given channel.
- *----------------------------------------------------------------------------
-*/
-void VMSetPitchBendRange (S_SYNTH *pSynth, EAS_INT channel, EAS_I16 pitchBendRange);
-
-/*----------------------------------------------------------------------------
- * VMSetEASLib()
- *----------------------------------------------------------------------------
- * Purpose:
- * Sets the pointer to the sound library
- *
- * Inputs:
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT VMSetGlobalEASLib (S_VOICE_MGR *pVoiceMgr, EAS_SNDLIB_HANDLE pEAS);
-EAS_RESULT VMSetEASLib (S_SYNTH *pSynth, EAS_SNDLIB_HANDLE pEAS);
-
-#ifdef DLS_SYNTHESIZER
-/*----------------------------------------------------------------------------
- * VMSetDLSLib()
- *----------------------------------------------------------------------------
- * Purpose:
- * Sets the pointer to the sound library
- *
- * Inputs:
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT VMSetGlobalDLSLib (EAS_DATA_HANDLE pEASData, EAS_DLSLIB_HANDLE pDLS);
-EAS_RESULT VMSetDLSLib (S_SYNTH *pSynth, EAS_DLSLIB_HANDLE pDLS);
-#endif
-
-/*----------------------------------------------------------------------------
- * VMSetTranposition()
- *----------------------------------------------------------------------------
- * Purpose:
- * Sets the global key transposition used by the synthesizer.
- * Transposes all melodic instruments up or down by the specified
- * amount. Range is limited to +/-12 semitones.
- *
- * Inputs:
- * psEASData - pointer to overall EAS data structure
- * transposition - transpose amount (+/-12)
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-void VMSetTranposition (S_SYNTH *pSynth, EAS_I32 transposition);
-
-/*----------------------------------------------------------------------------
- * VMGetTranposition()
- *----------------------------------------------------------------------------
- * Purpose:
- * Gets the global key transposition used by the synthesizer.
- * Transposes all melodic instruments up or down by the specified
- * amount. Range is limited to +/-12 semitones.
- *
- * Inputs:
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-void VMGetTranposition (S_SYNTH *pSynth, EAS_I32 *pTransposition);
-
-/*----------------------------------------------------------------------------
- * VMGetNoteCount()
- *----------------------------------------------------------------------------
-* Returns the total note count
-*----------------------------------------------------------------------------
-*/
-EAS_I32 VMGetNoteCount (S_SYNTH *pSynth);
-
-/*----------------------------------------------------------------------------
- * VMRender()
- *----------------------------------------------------------------------------
- * Purpose:
- * This routine renders a frame of audio
- *
- * Inputs:
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- * pVoicesRendered - number of voices rendered this frame
- *
- * Side Effects:
- * sets psMidiObject->m_nMaxWorkloadPerFrame
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT VMRender (S_VOICE_MGR *pVoiceMgr, EAS_I32 numSamples, EAS_I32 *pMixBuffer, EAS_I32 *pVoicesRendered);
-
-/*----------------------------------------------------------------------------
- * VMInitWorkload()
- *----------------------------------------------------------------------------
- * Purpose:
- * Clears the workload counter
- *
- * Inputs:
- * pVoiceMgr - pointer to instance data
- *
- * Outputs:
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-void VMInitWorkload (S_VOICE_MGR *pVoiceMgr);
-
-/*----------------------------------------------------------------------------
- * VMSetWorkload()
- *----------------------------------------------------------------------------
- * Purpose:
- * Sets the max workload for a single frame.
- *
- * Inputs:
- * pVoiceMgr - pointer to instance data
- *
- * Outputs:
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-void VMSetWorkload (S_VOICE_MGR *pVoiceMgr, EAS_I32 maxWorkLoad);
-
-/*----------------------------------------------------------------------------
- * VMCheckWorkload()
- *----------------------------------------------------------------------------
- * Purpose:
- * Checks to see if work load has been exceeded on this frame.
- *
- * Inputs:
- * pVoiceMgr - pointer to instance data
- *
- * Outputs:
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_BOOL VMCheckWorkload (S_VOICE_MGR *pVoiceMgr);
-
-/*----------------------------------------------------------------------------
- * VMActiveVoices()
- *----------------------------------------------------------------------------
- * Purpose:
- * Returns the number of active voices in the synthesizer.
- *
- * Inputs:
- * pEASData - pointer to instance data
- *
- * Outputs:
- * Returns the number of active voices
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_I32 VMActiveVoices (S_SYNTH *pSynth);
-
-/*----------------------------------------------------------------------------
- * VMMIDIShutdown()
- *----------------------------------------------------------------------------
- * Purpose:
- * Clean up any Synth related system issues.
- *
- * Inputs:
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- * None
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-void VMMIDIShutdown (S_EAS_DATA *pEASData, S_SYNTH *pSynth);
-
-/*----------------------------------------------------------------------------
- * VMShutdown()
- *----------------------------------------------------------------------------
- * Purpose:
- * Clean up any Synth related system issues.
- *
- * Inputs:
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- * None
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-void VMShutdown (S_EAS_DATA *pEASData);
-
-#ifdef EXTERNAL_AUDIO
-/*----------------------------------------------------------------------------
- * EAS_RegExtAudioCallback()
- *----------------------------------------------------------------------------
- * Register a callback for external audio processing
- *----------------------------------------------------------------------------
-*/
-void VMRegExtAudioCallback (S_SYNTH *pSynth, EAS_VOID_PTR pInstData, EAS_EXT_PRG_CHG_FUNC cbProgChgFunc, EAS_EXT_EVENT_FUNC cbEventFunc);
-
-/*----------------------------------------------------------------------------
- * VMGetMIDIControllers()
- *----------------------------------------------------------------------------
- * Returns the MIDI controller values on the specified channel
- *----------------------------------------------------------------------------
-*/
-void VMGetMIDIControllers (S_SYNTH *pSynth, EAS_U8 channel, S_MIDI_CONTROLLERS *pControl);
-#endif
-
-#ifdef _SPLIT_ARCHITECTURE
-/*----------------------------------------------------------------------------
- * VMStartFrame()
- *----------------------------------------------------------------------------
- * Purpose:
- * Starts an audio frame
- *
- * Inputs:
- *
- * Outputs:
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_BOOL VMStartFrame (S_EAS_DATA *pEASData);
-
-/*----------------------------------------------------------------------------
- * VMEndFrame()
- *----------------------------------------------------------------------------
- * Purpose:
- * Stops an audio frame
- *
- * Inputs:
- *
- * Outputs:
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_BOOL VMEndFrame (S_EAS_DATA *pEASData);
-#endif
-
-#endif /* #ifdef _EAS_VM_PROTOS_H */
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 736 $
+ * $Date: 2007-06-22 13:51:24 -0700 (Fri, 22 Jun 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+#ifndef _EAS_VM_PROTOS_H
+#define _EAS_VM_PROTOS_H
+
+// includes
+#include "eas_data.h"
+#include "eas_sndlib.h"
+
+/*----------------------------------------------------------------------------
+ * VMInitialize()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ *
+ * Inputs:
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT VMInitialize (S_EAS_DATA *pEASData);
+
+/*----------------------------------------------------------------------------
+ * VMInitMIDI()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ *
+ * Inputs:
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT VMInitMIDI (S_EAS_DATA *pEASData, S_SYNTH **ppSynth);
+
+/*----------------------------------------------------------------------------
+ * VMInitializeAllChannels()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ *
+ * Inputs:
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ *
+ *----------------------------------------------------------------------------
+*/
+void VMInitializeAllChannels (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth);
+
+/*----------------------------------------------------------------------------
+ * VMResetControllers()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ *
+ * Inputs:
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ *
+ *----------------------------------------------------------------------------
+*/
+void VMResetControllers (S_SYNTH *pSynth);
+
+/*----------------------------------------------------------------------------
+ * VMInitMIPTable()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Initialize the SP-MIDI MIP table
+ *
+ * Inputs:
+ * pEASData - pointer to synthesizer instance data
+ * mute - EAS_FALSE to unmute channels, EAS_TRUE to mute
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+void VMInitMIPTable (S_SYNTH *pSynth);
+
+/*----------------------------------------------------------------------------
+ * VMSetMIPEntry()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Sets the priority and MIP level for a MIDI channel
+ *
+ * Inputs:
+ * pEASData - pointer to synthesizer instance data
+ * channel - MIDI channel number
+ * priority - priority (0-15 with 0 = highest priority)
+ * mip - maximum instantaneous polyphony
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+void VMSetMIPEntry (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel, EAS_U8 priority, EAS_U8 mip);
+
+/*----------------------------------------------------------------------------
+ * VMUpdateMIPTable()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * This routine is called when the polyphony count in the synthesizer changes
+ *
+ * Inputs:
+ * pEASData - pointer to synthesizer instance data
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+void VMUpdateMIPTable (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth);
+
+/*----------------------------------------------------------------------------
+ * VMInitializeAllVoices()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ *
+ * Inputs:
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ *
+ *----------------------------------------------------------------------------
+*/
+void VMInitializeAllVoices (S_VOICE_MGR *pVoiceMgr, EAS_INT vSynthNum);
+
+/*----------------------------------------------------------------------------
+ * VMStartNote()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Update the synth's state to play the requested note on the requested
+ * channel if possible.
+ *
+ * Inputs:
+ * nChannel - the MIDI channel
+ * nKeyNumber - the MIDI key number for this note
+ * nNoteVelocity - the key velocity for this note
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ *
+ *----------------------------------------------------------------------------
+*/
+void VMStartNote (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel, EAS_U8 note, EAS_U8 velocity);
+
+/*----------------------------------------------------------------------------
+ * VMCheckKeyGroup()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * If the note that we've been asked to start is in the same key group as
+ * any currently playing notes, then we must shut down the currently playing
+ * note in the same key group and then start the newly requested note.
+ *
+ * Inputs:
+ * nChannel - synth channel that wants to start a new note
+ * nKeyNumber - new note's midi note number
+ * nRegionIndex - calling routine finds this index and gives to us
+ * nNoteVelocity - new note's velocity
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ * pbVoiceStealingRequired - flag: this routine sets true if we needed to
+ * steal a voice
+ *
+ * Side Effects:
+ * gsSynthObject.m_sVoice[free voice num].m_nKeyNumber may be assigned
+ * gsSynthObject.m_sVoice[free voice num].m_nVelocity may be assigned
+ *----------------------------------------------------------------------------
+*/
+void VMCheckKeyGroup (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U16 keyGroup, EAS_U8 channel);
+
+/*----------------------------------------------------------------------------
+ * VMCheckPolyphonyLimiting()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * We only play at most 2 of the same note on a MIDI channel.
+ * E.g., if we are asked to start note 36, and there are already two voices
+ * that are playing note 36, then we must steal the voice playing
+ * the oldest note 36 and use that stolen voice to play the new note 36.
+ *
+ * Inputs:
+ * nChannel - synth channel that wants to start a new note
+ * nKeyNumber - new note's midi note number
+ * nNoteVelocity - new note's velocity
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ * pbVoiceStealingRequired - flag: this routine sets true if we needed to
+ * steal a voice
+ * *
+ * Side Effects:
+ * psSynthObject->m_sVoice[free voice num].m_nKeyNumber may be assigned
+ * psSynthObject->m_sVoice[free voice num].m_nVelocity may be assigned
+ *----------------------------------------------------------------------------
+*/
+EAS_BOOL VMCheckPolyphonyLimiting (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel, EAS_U8 note, EAS_U8 velocity, EAS_U16 regionIndex, EAS_I32 lowVoice, EAS_I32 highVoice);
+
+/*----------------------------------------------------------------------------
+ * VMStopNote()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Update the synth's state to end the requested note on the requested
+ * channel.
+ *
+ * Inputs:
+ * nChannel - the MIDI channel
+ * nKeyNumber - the key number of the note to stop
+ * nNoteVelocity - the note-off velocity
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ * Side Effects:
+ * gsSynthObject.m_sVoice[free voice num].m_nSynthChannel may be assigned
+ * gsSynthObject.m_sVoice[free voice num].m_nKeyNumber is assigned
+ * gsSynthObject.m_sVoice[free voice num].m_nVelocity is assigned
+ *----------------------------------------------------------------------------
+*/
+void VMStopNote (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel, EAS_U8 key, EAS_U8 velocity);
+
+/*----------------------------------------------------------------------------
+ * VMFindAvailableVoice()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Find an available voice and return the voice number if available.
+ *
+ * Inputs:
+ * pnVoiceNumber - really an output, see below
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ * pnVoiceNumber - returns the voice number of available voice if found
+ * success - if there is an available voice
+ * failure - otherwise
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT VMFindAvailableVoice (S_VOICE_MGR *pVoiceMgr, EAS_INT *pVoiceNumber, EAS_I32 lowVoice, EAS_I32 highVoice);
+
+/*----------------------------------------------------------------------------
+ * VMStealVoice()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Steal a voice and return the voice number
+ *
+ * Stealing algorithm: steal the best choice with minimal work, taking into
+ * account SP-Midi channel priorities and polyphony allocation.
+ *
+ * In one pass through all the voices, figure out which voice to steal
+ * taking into account a number of different factors:
+ * Priority of the voice's MIDI channel
+ * Number of voices over the polyphony allocation for voice's MIDI channel
+ * Amplitude of the voice
+ * Note age
+ * Key velocity (for voices that haven't been started yet)
+ * If any matching notes are found
+ *
+ * Inputs:
+ * nChannel - the channel that this voice wants to be started on
+ * nKeyNumber - the key number for this new voice
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ * pnVoiceNumber - voice stolen
+ * EAS_RESULT EAS_SUCCESS - always successful
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT VMStealVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_INT *pVoiceNumber, EAS_U8 channel, EAS_U8 note, EAS_I32 lowVoice, EAS_I32 highVoice);
+
+/*----------------------------------------------------------------------------
+ * VMAddSamples()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Synthesize the requested number of samples.
+ *
+ * Inputs:
+ * nNumSamplesToAdd - number of samples to write to buffer
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ * number of samples actually written to buffer
+ *
+ * Side Effects:
+ * - samples are added to the presently free buffer
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_I32 VMAddSamples (S_VOICE_MGR *pVoiceMgr, EAS_I32 *pMixBuffer, EAS_I32 numSamplesToAdd);
+
+/*----------------------------------------------------------------------------
+ * VMProgramChange()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Change the instrument (program) for the given channel.
+ *
+ * Depending on the program number, and the bank selected for this channel, the
+ * program may be in ROM, RAM (from SMAF or CMX related RAM wavetable), or
+ * Alternate wavetable (from mobile DLS or other DLS file)
+ *
+ * This function figures out what wavetable should be used, and sets it up as the
+ * wavetable to use for this channel. Also the channel may switch from a melodic
+ * channel to a rhythm channel, or vice versa.
+ *
+ * Inputs:
+ *
+ * Outputs:
+ * Side Effects:
+ * gsSynthObject.m_sChannel[nChannel].m_nProgramNumber is likely changed
+ * gsSynthObject.m_sChannel[nChannel].m_psEAS may be changed
+ * gsSynthObject.m_sChannel[nChannel].m_bRhythmChannel may be changed
+ *
+ *----------------------------------------------------------------------------
+*/
+void VMProgramChange (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel, EAS_U8 program);
+
+/*----------------------------------------------------------------------------
+ * VMChannelPressure()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Change the channel pressure for the given channel
+ *
+ * Inputs:
+ * nChannel - the MIDI channel
+ * nVelocity - the channel pressure value
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ * Side Effects:
+ * gsSynthObject.m_sChannel[nChannel].m_nChannelPressure is updated
+ *----------------------------------------------------------------------------
+*/
+void VMChannelPressure (S_SYNTH *pSynth, EAS_U8 channel, EAS_U8 value);
+
+/*----------------------------------------------------------------------------
+ * VMPitchBend()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Change the pitch wheel value for the given channel.
+ * This routine constructs the proper 14-bit argument when the calling routine
+ * passes the pitch LSB and MSB.
+ *
+ * Note: some midi disassemblers display a bipolar pitch bend value.
+ * We can display the bipolar value using
+ * if m_nPitchBend >= 0x2000
+ * bipolar pitch bend = postive (m_nPitchBend - 0x2000)
+ * else
+ * bipolar pitch bend = negative (0x2000 - m_nPitchBend)
+ *
+ * Inputs:
+ * nChannel - the MIDI channel
+ * nPitchLSB - the LSB byte from the pitch bend message
+ * nPitchMSB - the MSB byte from the message
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ * gsSynthObject.m_sChannel[nChannel].m_nPitchBend is changed
+ *
+ *----------------------------------------------------------------------------
+*/
+void VMPitchBend (S_SYNTH *pSynth, EAS_U8 channel, EAS_U8 pitchLSB, EAS_U8 pitchMSB);
+
+/*----------------------------------------------------------------------------
+ * VMControlChange()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Change the controller (or mode) for the given channel.
+ *
+ * Inputs:
+ * nChannel - the MIDI channel
+ * nControllerNumber - the controller number
+ * nControlValue - the controller number for this control change
+ * nControlValue - the value for this control change
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ * Side Effects:
+ * gsSynthObject.m_sChannel[nChannel] controller is changed
+ *
+ *----------------------------------------------------------------------------
+*/
+void VMControlChange (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel, EAS_U8 controller, EAS_U8 value);
+
+/*----------------------------------------------------------------------------
+ * VMUpdateRPNStateMachine()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Call this function when we want to parse a stream of RPN messages.
+ * NOTE: The synth has only one set of global RPN data instead of RPN data
+ * per channel.
+ * So actually, we don't really need to look at the nChannel parameter,
+ * but we pass it to facilitate future upgrades. Furthermore, we only
+ * support RPN0 (pitch bend sensitivity), RPN1 (fine tuning) and
+ * RPN2 (coarse tuning). Any other RPNs are rejected.
+ *
+ * Inputs:
+ * nChannel - the MIDI channel
+ * nControllerNumber - the RPN controller number
+ * nControlValue - the value for this control change
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ * gsSynthObject.m_RPN0 (or m_RPN1 or m_RPN2) may be updated if the
+ * proper RPN message sequence is parsed.
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT VMUpdateRPNStateMachine (S_SYNTH *pSynth, EAS_U8 channel, EAS_U8 controller, EAS_U8 value);
+
+/*----------------------------------------------------------------------------
+ * VMUpdateStaticChannelParameters()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Update all of the static channel parameters for channels that have had
+ * a controller change values
+ * Or if the synth has signalled that all channels must forcibly
+ * be updated
+ *
+ * Inputs:
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ * none
+ *
+ * Side Effects:
+ * - psSynthObject->m_sChannel[].m_nStaticGain and m_nStaticPitch
+ * are updated for channels whose controller values have changed
+ * or if the synth has signalled that all channels must forcibly
+ * be updated
+ *----------------------------------------------------------------------------
+*/
+void VMUpdateStaticChannelParameters (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth);
+
+/*----------------------------------------------------------------------------
+ * VMReleaseAllDeferredNoteOffs()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Call this functin when the sustain flag is presently set but
+ * we are now transitioning from damper pedal on to
+ * damper pedal off. This means all notes in this channel
+ * that received a note off while the damper pedal was on, and
+ * had their note-off requests deferred, should now proceed to
+ * the release state.
+ *
+ * Inputs:
+ * nChannel - this channel has its sustain pedal transitioning from on to off
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ * Side Effects:
+ * any voice with deferred note offs on this channel are updated such that
+ *
+ *
+ *----------------------------------------------------------------------------
+*/
+void VMReleaseAllDeferredNoteOffs (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel);
+
+/*----------------------------------------------------------------------------
+ * VMCatchNotesForSustainPedal()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Call this function when the sustain flag is presently clear and
+ * the damper pedal is off and we are transitioning from damper pedal OFF to
+ * damper pedal ON. Currently sounding notes should be left
+ * unchanged. However, we should try to "catch" notes if possible.
+ * If any notes have levels >= sustain level, catch them,
+ * otherwise, let them continue to release.
+ *
+ * Inputs:
+ * nChannel - this channel has its sustain pedal transitioning from on to off
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ * Side Effects:
+ * any voice with deferred note offs on this channel are updated such that
+ * psVoice->m_sEG1.m_eState = eEnvelopeStateSustainPedal
+ *----------------------------------------------------------------------------
+*/
+void VMCatchNotesForSustainPedal (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel);
+
+/*----------------------------------------------------------------------------
+ * VMUpdateAllNotesAge()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Increment the note age for all voices older than the age of the voice
+ * that is stopping, effectively making the voices "younger".
+ *
+ * Inputs:
+ * nAge - age of voice that is going away
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ * m_nAge for some voices is incremented
+ *----------------------------------------------------------------------------
+*/
+void VMUpdateAllNotesAge (S_VOICE_MGR *pVoiceMgr, EAS_U16 nAge);
+
+/*----------------------------------------------------------------------------
+ * VMFindRegionIndex()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Find the region index for the given instrument using the midi key number
+ * and the RPN2 (coarse tuning) value. By using RPN2 as part of the
+ * region selection process, we reduce the amount a given sample has
+ * to be transposed by selecting the closest recorded root instead.
+ *
+ * Inputs:
+ * nChannel - current channel for this note
+ * nKeyNumber - current midi note number
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ * pnRegionIndex - valid only if we returned success
+ * success if we found the region index number, otherwise
+ * failure
+ *
+ * Side Effects:
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT VMFindRegionIndex (S_VOICE_MGR *pVoiceMgr, EAS_U8 channel, EAS_U8 note, EAS_U16 *pRegionIndex);
+
+/*----------------------------------------------------------------------------
+ * VMIncRefCount()
+ *----------------------------------------------------------------------------
+ * Increment reference count for virtual synth
+ *----------------------------------------------------------------------------
+*/
+void VMIncRefCount (S_SYNTH *pSynth);
+
+/*----------------------------------------------------------------------------
+ * VMReset()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * We call this routine to start the process of reseting the synth.
+ * This routine sets a flag for the entire synth indicating that we want
+ * to reset.
+ * We also force all voices to mute quickly.
+ * However, we do not actually perform any synthesis in this routine. That
+ * is, we do not ramp the voices down from this routine, but instead, we
+ * let the "regular" synth processing steps take care of adding the ramp
+ * down samples to the output buffer. After we are sure that all voices
+ * have completed ramping down, we continue the process of resetting the
+ * synth (from another routine).
+ *
+ * Inputs:
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ * - set a flag (in gsSynthObject.m_nFlags) indicating synth reset requested.
+ * - force all voices to update their envelope states to mute
+ *
+ *----------------------------------------------------------------------------
+*/
+void VMReset (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_BOOL force);
+
+/*----------------------------------------------------------------------------
+ * VMMuteAllVoices()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * We call this in an emergency reset situation.
+ * This forces all voices to mute quickly.
+ *
+ * Inputs:
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ * - forces all voices to update their envelope states to mute
+ *
+ *----------------------------------------------------------------------------
+*/
+void VMMuteVoice (S_VOICE_MGR *pVoiceMgr, EAS_I32 voiceNum);
+void VMMuteAllVoices (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth);
+
+/*----------------------------------------------------------------------------
+ * VMReleaseAllVoices()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * We call this after we've encountered the end of the Midi file.
+ * This ensures all voice are either in release (because we received their
+ * note off already) or forces them to mute quickly.
+ * We use this as a safety to prevent bad midi files from playing forever.
+ *
+ * Inputs:
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ * - forces all voices to update their envelope states to release or mute
+ *
+ *----------------------------------------------------------------------------
+*/
+void VMReleaseAllVoices (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth);
+
+/*----------------------------------------------------------------------------
+ * VMAllNotesOff()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Quickly mute all notes on the given channel.
+ *
+ * Inputs:
+ * nChannel - quickly turn off all notes on this channel
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ * - forces all voices on this channel to update their envelope states to mute
+ *
+ *----------------------------------------------------------------------------
+*/
+void VMAllNotesOff (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel);
+
+/*----------------------------------------------------------------------------
+ * VMDeferredStopNote()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Stop the notes that had deferred note-off requests.
+ *
+ * Inputs:
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ * None.
+ *
+ * Side Effects:
+ * voices that have had deferred note-off requests are now put into release
+ * gsSynthObject.m_sVoice[i].m_nFlags has the VOICE_FLAG_DEFER_MIDI_NOTE_OFF
+ * cleared
+ *----------------------------------------------------------------------------
+*/
+void VMDeferredStopNote (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth);
+
+/*----------------------------------------------------------------------------
+ * VMSetSynthPolyphony()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Set the synth to a new polyphony value. Value must be >= 1 and
+ * <= MAX_SYNTH_VOICES. This function will pin the polyphony at those limits
+ *
+ * Inputs:
+ * pVoiceMgr pointer to synthesizer data
+ * synth synthesizer number (0 = onboard, 1 = DSP)
+ * polyphonyCount desired polyphony count
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT VMSetSynthPolyphony (S_VOICE_MGR *pVoiceMgr, EAS_I32 synth, EAS_I32 polyphonyCount);
+
+/*----------------------------------------------------------------------------
+ * VMGetSynthPolyphony()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Set the synth to a new polyphony value. Value must be >= 1 and
+ * <= MAX_SYNTH_VOICES. This function will pin the polyphony at those limits
+ *
+ * Inputs:
+ * pVoiceMgr pointer to synthesizer data
+ * synth synthesizer number (0 = onboard, 1 = DSP)
+ * polyphonyCount desired polyphony count
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT VMGetSynthPolyphony (S_VOICE_MGR *pVoiceMgr, EAS_I32 synth, EAS_I32 *pPolyphonyCount);
+
+/*----------------------------------------------------------------------------
+ * VMSetPolyphony()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Set the virtual synth polyphony. 0 = no limit (i.e. can use
+ * all available voices).
+ *
+ * Inputs:
+ * pVoiceMgr pointer to synthesizer data
+ * polyphonyCount desired polyphony count
+ * pSynth pointer to virtual synth
+ *
+ * Outputs:
+ * Returns error code
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT VMSetPolyphony (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_I32 polyphonyCount);
+
+/*----------------------------------------------------------------------------
+ * VMGetPolyphony()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Returns the current polyphony setting
+ *
+ * Inputs:
+ * pVoiceMgr pointer to synthesizer data
+ * pSynth pointer to virtual synth
+ * pPolyphonyCount pointer to variable to receive data
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT VMGetPolyphony (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_I32 *pPolyphonyCount);
+
+/*----------------------------------------------------------------------------
+ * VMSetPriority()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Set the virtual synth priority
+ *
+ * Inputs:
+ * pVoiceMgr pointer to synthesizer data
+ * priority new priority
+ * pSynth pointer to virtual synth
+ *
+ * Outputs:
+ * Returns error code
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT VMSetPriority (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_I32 priority);
+
+/*----------------------------------------------------------------------------
+ * VMGetPriority()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Get the virtual synth priority
+ *
+ * Inputs:
+ * pVoiceMgr pointer to synthesizer data
+ * pPriority pointer to variable to hold priority
+ * pSynth pointer to virtual synth
+ *
+ * Outputs:
+ * Returns error code
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT VMGetPriority (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_I32 *pPriority);
+
+/*----------------------------------------------------------------------------
+ * VMSetVolume()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Set the master volume for this sequence
+ *
+ * Inputs:
+ * nSynthVolume - the desired master volume
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ * overrides any previously set master volume from sysex
+ *
+ *----------------------------------------------------------------------------
+*/
+void VMSetVolume (S_SYNTH *pSynth, EAS_U16 masterVolume);
+
+/*----------------------------------------------------------------------------
+ * VMSetPitchBendRange()
+ *----------------------------------------------------------------------------
+ * Set the pitch bend range for the given channel.
+ *----------------------------------------------------------------------------
+*/
+void VMSetPitchBendRange (S_SYNTH *pSynth, EAS_INT channel, EAS_I16 pitchBendRange);
+
+/*----------------------------------------------------------------------------
+ * VMSetEASLib()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Sets the pointer to the sound library
+ *
+ * Inputs:
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT VMSetGlobalEASLib (S_VOICE_MGR *pVoiceMgr, EAS_SNDLIB_HANDLE pEAS);
+EAS_RESULT VMSetEASLib (S_SYNTH *pSynth, EAS_SNDLIB_HANDLE pEAS);
+
+#ifdef DLS_SYNTHESIZER
+/*----------------------------------------------------------------------------
+ * VMSetDLSLib()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Sets the pointer to the sound library
+ *
+ * Inputs:
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT VMSetGlobalDLSLib (EAS_DATA_HANDLE pEASData, EAS_DLSLIB_HANDLE pDLS);
+EAS_RESULT VMSetDLSLib (S_SYNTH *pSynth, EAS_DLSLIB_HANDLE pDLS);
+#endif
+
+/*----------------------------------------------------------------------------
+ * VMSetTranposition()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Sets the global key transposition used by the synthesizer.
+ * Transposes all melodic instruments up or down by the specified
+ * amount. Range is limited to +/-12 semitones.
+ *
+ * Inputs:
+ * psEASData - pointer to overall EAS data structure
+ * transposition - transpose amount (+/-12)
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+void VMSetTranposition (S_SYNTH *pSynth, EAS_I32 transposition);
+
+/*----------------------------------------------------------------------------
+ * VMGetTranposition()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Gets the global key transposition used by the synthesizer.
+ * Transposes all melodic instruments up or down by the specified
+ * amount. Range is limited to +/-12 semitones.
+ *
+ * Inputs:
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+void VMGetTranposition (S_SYNTH *pSynth, EAS_I32 *pTransposition);
+
+/*----------------------------------------------------------------------------
+ * VMGetNoteCount()
+ *----------------------------------------------------------------------------
+* Returns the total note count
+*----------------------------------------------------------------------------
+*/
+EAS_I32 VMGetNoteCount (S_SYNTH *pSynth);
+
+/*----------------------------------------------------------------------------
+ * VMRender()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * This routine renders a frame of audio
+ *
+ * Inputs:
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ * pVoicesRendered - number of voices rendered this frame
+ *
+ * Side Effects:
+ * sets psMidiObject->m_nMaxWorkloadPerFrame
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT VMRender (S_VOICE_MGR *pVoiceMgr, EAS_I32 numSamples, EAS_I32 *pMixBuffer, EAS_I32 *pVoicesRendered);
+
+/*----------------------------------------------------------------------------
+ * VMInitWorkload()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Clears the workload counter
+ *
+ * Inputs:
+ * pVoiceMgr - pointer to instance data
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+void VMInitWorkload (S_VOICE_MGR *pVoiceMgr);
+
+/*----------------------------------------------------------------------------
+ * VMSetWorkload()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Sets the max workload for a single frame.
+ *
+ * Inputs:
+ * pVoiceMgr - pointer to instance data
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+void VMSetWorkload (S_VOICE_MGR *pVoiceMgr, EAS_I32 maxWorkLoad);
+
+/*----------------------------------------------------------------------------
+ * VMCheckWorkload()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Checks to see if work load has been exceeded on this frame.
+ *
+ * Inputs:
+ * pVoiceMgr - pointer to instance data
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_BOOL VMCheckWorkload (S_VOICE_MGR *pVoiceMgr);
+
+/*----------------------------------------------------------------------------
+ * VMActiveVoices()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Returns the number of active voices in the synthesizer.
+ *
+ * Inputs:
+ * pEASData - pointer to instance data
+ *
+ * Outputs:
+ * Returns the number of active voices
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_I32 VMActiveVoices (S_SYNTH *pSynth);
+
+/*----------------------------------------------------------------------------
+ * VMMIDIShutdown()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Clean up any Synth related system issues.
+ *
+ * Inputs:
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ * None
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+void VMMIDIShutdown (S_EAS_DATA *pEASData, S_SYNTH *pSynth);
+
+/*----------------------------------------------------------------------------
+ * VMShutdown()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Clean up any Synth related system issues.
+ *
+ * Inputs:
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ * None
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+void VMShutdown (S_EAS_DATA *pEASData);
+
+#ifdef EXTERNAL_AUDIO
+/*----------------------------------------------------------------------------
+ * EAS_RegExtAudioCallback()
+ *----------------------------------------------------------------------------
+ * Register a callback for external audio processing
+ *----------------------------------------------------------------------------
+*/
+void VMRegExtAudioCallback (S_SYNTH *pSynth, EAS_VOID_PTR pInstData, EAS_EXT_PRG_CHG_FUNC cbProgChgFunc, EAS_EXT_EVENT_FUNC cbEventFunc);
+
+/*----------------------------------------------------------------------------
+ * VMGetMIDIControllers()
+ *----------------------------------------------------------------------------
+ * Returns the MIDI controller values on the specified channel
+ *----------------------------------------------------------------------------
+*/
+void VMGetMIDIControllers (S_SYNTH *pSynth, EAS_U8 channel, S_MIDI_CONTROLLERS *pControl);
+#endif
+
+#ifdef _SPLIT_ARCHITECTURE
+/*----------------------------------------------------------------------------
+ * VMStartFrame()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Starts an audio frame
+ *
+ * Inputs:
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_BOOL VMStartFrame (S_EAS_DATA *pEASData);
+
+/*----------------------------------------------------------------------------
+ * VMEndFrame()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Stops an audio frame
+ *
+ * Inputs:
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_BOOL VMEndFrame (S_EAS_DATA *pEASData);
+#endif
+
+#endif /* #ifdef _EAS_VM_PROTOS_H */
+
diff --git a/arm-wt-22k/lib_src/eas_voicemgt.c b/arm-wt-22k/lib_src/eas_voicemgt.c
index 873f29d..ab0b776 100644
--- a/arm-wt-22k/lib_src/eas_voicemgt.c
+++ b/arm-wt-22k/lib_src/eas_voicemgt.c
@@ -1,12 +1,12 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_voicemgt.c
- *
- * Contents and purpose:
- * Implements the synthesizer functions.
- *
- * Copyright Sonic Network Inc. 2004
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_voicemgt.c
+ *
+ * Contents and purpose:
+ * Implements the synthesizer functions.
+ *
+ * Copyright Sonic Network Inc. 2004
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,3953 +19,3953 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 794 $
- * $Date: 2007-08-01 00:08:48 -0700 (Wed, 01 Aug 2007) $
- *----------------------------------------------------------------------------
-*/
-
-/* includes */
-#include "eas.h"
-#include "eas_data.h"
-#include "eas_config.h"
-#include "eas_report.h"
-#include "eas_midictrl.h"
-#include "eas_host.h"
-#include "eas_synth_protos.h"
-#include "eas_vm_protos.h"
-
-#ifdef DLS_SYNTHESIZER
-#include "eas_mdls.h"
-#endif
-
-// #define _DEBUG_VM
-
-/* some defines for workload */
-#define WORKLOAD_AMOUNT_SMALL_INCREMENT 5
-#define WORKLOAD_AMOUNT_START_NOTE 10
-#define WORKLOAD_AMOUNT_STOP_NOTE 10
-#define WORKLOAD_AMOUNT_KEY_GROUP 10
-#define WORKLOAD_AMOUNT_POLY_LIMIT 10
-
-/* pointer to base sound library */
-extern S_EAS easSoundLib;
-
-#ifdef TEST_HARNESS
-extern S_EAS easTestLib;
-EAS_SNDLIB_HANDLE VMGetLibHandle(EAS_INT libNum)
-{
- switch (libNum)
- {
- case 0:
- return &easSoundLib;
-#ifdef _WT_SYNTH
- case 1:
- return &easTestLib;
-#endif
- default:
- return NULL;
- }
-}
-#endif
-
-/* pointer to synthesizer interface(s) */
-#ifdef _WT_SYNTH
-extern const S_SYNTH_INTERFACE wtSynth;
-#endif
-
-#ifdef _FM_SYNTH
-extern const S_SYNTH_INTERFACE fmSynth;
-#endif
-
-typedef S_SYNTH_INTERFACE *S_SYNTH_INTERFACE_HANDLE;
-
-/* wavetable on MCU */
-#if defined(EAS_WT_SYNTH)
-const S_SYNTH_INTERFACE *const pPrimarySynth = &wtSynth;
-
-/* FM on MCU */
-#elif defined(EAS_FM_SYNTH)
-const S_SYNTH_INTERFACE *const pPrimarySynth = &fmSynth;
-
-/* wavetable drums on MCU, FM melodic on DSP */
-#elif defined(EAS_HYBRID_SYNTH)
-const S_SYNTH_INTERFACE *const pPrimarySynth = &wtSynth;
-const S_SYNTH_INTERFACE *const pSecondarySynth = &fmSynth;
-
-/* wavetable drums on MCU, wavetable melodic on DSP */
-#elif defined(EAS_SPLIT_WT_SYNTH)
-const S_SYNTH_INTERFACE *const pPrimarySynth = &wtSynth;
-extern const S_FRAME_INTERFACE wtFrameInterface;
-const S_FRAME_INTERFACE *const pFrameInterface = &wtFrameInterface;
-
-/* wavetable drums on MCU, FM melodic on DSP */
-#elif defined(EAS_SPLIT_HYBRID_SYNTH)
-const S_SYNTH_INTERFACE *const pPrimarySynth = &wtSynth;
-const S_SYNTH_INTERFACE *const pSecondarySynth = &fmSynth;
-extern const S_FRAME_INTERFACE fmFrameInterface;
-const S_FRAME_INTERFACE *const pFrameInterface = &fmFrameInterface;
-
-/* FM on DSP */
-#elif defined(EAS_SPLIT_FM_SYNTH)
-const S_SYNTH_INTERFACE *const pPrimarySynth = &fmSynth;
-extern const S_FRAME_INTERFACE fmFrameInterface;
-const S_FRAME_INTERFACE *const pFrameInterface = &fmFrameInterface;
-
-#else
-#error "Undefined architecture option"
-#endif
-
-/*----------------------------------------------------------------------------
- * inline functions
- *----------------------------------------------------------------------------
-*/
-EAS_INLINE const S_REGION* GetRegionPtr (S_SYNTH *pSynth, EAS_U16 regionIndex)
-{
-#if defined(DLS_SYNTHESIZER)
- if (regionIndex & FLAG_RGN_IDX_DLS_SYNTH)
- return &pSynth->pDLS->pDLSRegions[regionIndex & REGION_INDEX_MASK].wtRegion.region;
-#endif
-#if defined(_HYBRID_SYNTH)
- if (regionIndex & FLAG_RGN_IDX_FM_SYNTH)
- return &pSynth->pEAS->pFMRegions[regionIndex & REGION_INDEX_MASK].region;
- else
- return &pSynth->pEAS->pWTRegions[regionIndex].region;
-#elif defined(_WT_SYNTH)
- return &pSynth->pEAS->pWTRegions[regionIndex].region;
-#elif defined(_FM_SYNTH)
- return &pSynth->pEAS->pFMRegions[regionIndex].region;
-#endif
-}
-
-/*lint -esym(715, voiceNum) used in some implementation */
-EAS_INLINE const S_SYNTH_INTERFACE* GetSynthPtr (EAS_INT voiceNum)
-{
-#if defined(_HYBRID_SYNTH)
- if (voiceNum < NUM_PRIMARY_VOICES)
- return pPrimarySynth;
- else
- return pSecondarySynth;
-#else
- return pPrimarySynth;
-#endif
-}
-
-EAS_INLINE EAS_INT GetAdjustedVoiceNum (EAS_INT voiceNum)
-{
-#if defined(_HYBRID_SYNTH)
- if (voiceNum >= NUM_PRIMARY_VOICES)
- return voiceNum - NUM_PRIMARY_VOICES;
-#endif
- return voiceNum;
-}
-
-EAS_INLINE EAS_U8 VSynthToChannel (S_SYNTH *pSynth, EAS_U8 channel)
-{
- /*lint -e{734} synthNum is always 0-15 */
- return channel | (pSynth->vSynthNum << 4);
-}
-
-/*----------------------------------------------------------------------------
- * InitVoice()
- *----------------------------------------------------------------------------
- * Initialize a synthesizer voice
- *----------------------------------------------------------------------------
-*/
-void InitVoice (S_SYNTH_VOICE *pVoice)
-{
- pVoice->channel = UNASSIGNED_SYNTH_CHANNEL;
- pVoice->nextChannel = UNASSIGNED_SYNTH_CHANNEL;
- pVoice->note = pVoice->nextNote = DEFAULT_KEY_NUMBER;
- pVoice->velocity = pVoice->nextVelocity = DEFAULT_VELOCITY;
- pVoice->regionIndex = DEFAULT_REGION_INDEX;
- pVoice->age = DEFAULT_AGE;
- pVoice->voiceFlags = DEFAULT_VOICE_FLAGS;
- pVoice->voiceState = DEFAULT_VOICE_STATE;
-}
-
-/*----------------------------------------------------------------------------
- * IncVoicePoolCount()
- *----------------------------------------------------------------------------
- * Updates the voice pool count when a voice changes state
- *----------------------------------------------------------------------------
-*/
-static void IncVoicePoolCount (S_VOICE_MGR *pVoiceMgr, S_SYNTH_VOICE *pVoice)
-{
- S_SYNTH *pSynth;
- EAS_INT pool;
-
- /* ignore muting voices */
- if (pVoice->voiceState == eVoiceStateMuting)
- return;
-
- if (pVoice->voiceState == eVoiceStateStolen)
- {
- pSynth = pVoiceMgr->pSynth[GET_VSYNTH(pVoice->nextChannel)];
- pool = pSynth->channels[GET_CHANNEL(pVoice->nextChannel)].pool;
- }
- else
- {
- pSynth = pVoiceMgr->pSynth[GET_VSYNTH(pVoice->channel)];
- pool = pSynth->channels[GET_CHANNEL(pVoice->channel)].pool;
- }
-
- pSynth->poolCount[pool]++;
-
-#ifdef _DEBUG_VM
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IncVoicePoolCount: Synth=%d pool=%d\n", pSynth->vSynthNum, pool); */ }
-#endif
-}
-
-/*----------------------------------------------------------------------------
- * DecVoicePoolCount()
- *----------------------------------------------------------------------------
- * Updates the voice pool count when a voice changes state
- *----------------------------------------------------------------------------
-*/
-static void DecVoicePoolCount (S_VOICE_MGR *pVoiceMgr, S_SYNTH_VOICE *pVoice)
-{
- S_SYNTH *pSynth;
- EAS_INT pool;
-
- /* ignore muting voices */
- if (pVoice->voiceState == eVoiceStateMuting)
- return;
-
- if (pVoice->voiceState == eVoiceStateStolen)
- {
- pSynth = pVoiceMgr->pSynth[GET_VSYNTH(pVoice->nextChannel)];
- pool = pSynth->channels[GET_CHANNEL(pVoice->nextChannel)].pool;
- }
- else
- {
- pSynth = pVoiceMgr->pSynth[GET_VSYNTH(pVoice->channel)];
- pool = pSynth->channels[GET_CHANNEL(pVoice->channel)].pool;
- }
-
- pSynth->poolCount[pool]--;
-
-#ifdef _DEBUG_VM
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "DecVoicePoolCount: Synth=%d pool=%d\n", pSynth->vSynthNum, pool); */ }
-#endif
-}
-
-/*----------------------------------------------------------------------------
- * VMInitialize()
- *----------------------------------------------------------------------------
- * Purpose:
- *
- * Inputs:
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT VMInitialize (S_EAS_DATA *pEASData)
-{
- S_VOICE_MGR *pVoiceMgr;
- EAS_INT i;
-
- /* check Configuration Module for data allocation */
- if (pEASData->staticMemoryModel)
- pVoiceMgr = EAS_CMEnumData(EAS_CM_SYNTH_DATA);
- else
- pVoiceMgr = EAS_HWMalloc(pEASData->hwInstData, sizeof(S_VOICE_MGR));
- if (!pVoiceMgr)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "VMInitialize: Failed to allocate synthesizer memory\n"); */ }
- return EAS_ERROR_MALLOC_FAILED;
- }
- EAS_HWMemSet(pVoiceMgr, 0, sizeof(S_VOICE_MGR));
-
- /* initialize non-zero variables */
- pVoiceMgr->pGlobalEAS = (S_EAS*) &easSoundLib;
- pVoiceMgr->maxPolyphony = (EAS_U16) MAX_SYNTH_VOICES;
-
-#if defined(_SECONDARY_SYNTH) || defined(EAS_SPLIT_WT_SYNTH)
- pVoiceMgr->maxPolyphonyPrimary = NUM_PRIMARY_VOICES;
- pVoiceMgr->maxPolyphonySecondary = NUM_SECONDARY_VOICES;
-#endif
-
- /* set max workload to zero */
- pVoiceMgr->maxWorkLoad = 0;
-
- /* initialize the voice manager parameters */
- for (i = 0; i < MAX_SYNTH_VOICES; i++)
- InitVoice(&pVoiceMgr->voices[i]);
-
- /* initialize the synth */
- /*lint -e{522} return unused at this time */
- pPrimarySynth->pfInitialize(pVoiceMgr);
-
- /* initialize the off-chip synth */
-#ifdef _HYBRID_SYNTH
- /*lint -e{522} return unused at this time */
- pSecondarySynth->pfInitialize(pVoiceMgr);
-#endif
-
- pEASData->pVoiceMgr = pVoiceMgr;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * VMInitMIDI()
- *----------------------------------------------------------------------------
- * Purpose:
- *
- * Inputs:
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT VMInitMIDI (S_EAS_DATA *pEASData, S_SYNTH **ppSynth)
-{
- EAS_RESULT result;
- S_SYNTH *pSynth;
- EAS_INT virtualSynthNum;
-
- *ppSynth = NULL;
-
- /* static memory model only allows one synth */
- if (pEASData->staticMemoryModel)
- {
- if (pEASData->pVoiceMgr->pSynth[0] != NULL)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "VMInitMIDI: No virtual synthesizer support for static memory model\n"); */ }
- return EAS_ERROR_NO_VIRTUAL_SYNTHESIZER;
- }
-
- /* check Configuration Module for data allocation */
- pSynth = EAS_CMEnumData(EAS_CM_MIDI_DATA);
- virtualSynthNum = 0;
- }
-
- /* dynamic memory model */
- else
- {
- for (virtualSynthNum = 0; virtualSynthNum < MAX_VIRTUAL_SYNTHESIZERS; virtualSynthNum++)
- if (pEASData->pVoiceMgr->pSynth[virtualSynthNum] == NULL)
- break;
- if (virtualSynthNum == MAX_VIRTUAL_SYNTHESIZERS)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "VMInitMIDI: Exceeded number of active virtual synthesizers"); */ }
- return EAS_ERROR_NO_VIRTUAL_SYNTHESIZER;
- }
- pSynth = EAS_HWMalloc(pEASData->hwInstData, sizeof(S_SYNTH));
- }
-
- /* make sure we have a valid memory pointer */
- if (pSynth == NULL)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "VMInitMIDI: Failed to allocate synthesizer memory\n"); */ }
- return EAS_ERROR_MALLOC_FAILED;
- }
- EAS_HWMemSet(pSynth, 0, sizeof(S_SYNTH));
-
- /* set the sound library pointer */
- if ((result = VMSetEASLib(pSynth, pEASData->pVoiceMgr->pGlobalEAS)) != EAS_SUCCESS)
- {
- VMMIDIShutdown(pEASData, pSynth);
- return result;
- }
-
- /* link in DLS bank if downloaded */
-#ifdef DLS_SYNTHESIZER
- if (pEASData->pVoiceMgr->pGlobalDLS)
- {
- pSynth->pDLS = pEASData->pVoiceMgr->pGlobalDLS;
- DLSAddRef(pSynth->pDLS);
- }
-#endif
-
- /* initialize MIDI state variables */
- pSynth->synthFlags = DEFAULT_SYNTH_FLAGS;
- pSynth->masterVolume = DEFAULT_SYNTH_MASTER_VOLUME;
- pSynth->refCount = 1;
- pSynth->priority = DEFAULT_SYNTH_PRIORITY;
- pSynth->poolAlloc[0] = (EAS_U8) pEASData->pVoiceMgr->maxPolyphony;
-
- VMInitializeAllChannels(pEASData->pVoiceMgr, pSynth);
-
- pSynth->vSynthNum = (EAS_U8) virtualSynthNum;
- pEASData->pVoiceMgr->pSynth[virtualSynthNum] = pSynth;
-
- *ppSynth = pSynth;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * VMIncRefCount()
- *----------------------------------------------------------------------------
- * Increment reference count for virtual synth
- *----------------------------------------------------------------------------
-*/
-void VMIncRefCount (S_SYNTH *pSynth)
-{
- pSynth->refCount++;
-}
-
-/*----------------------------------------------------------------------------
- * VMReset()
- *----------------------------------------------------------------------------
- * Purpose:
- * We call this routine to start the process of reseting the synth.
- * This routine sets a flag for the entire synth indicating that we want
- * to reset.
- * We also force all voices to mute quickly.
- * However, we do not actually perform any synthesis in this routine. That
- * is, we do not ramp the voices down from this routine, but instead, we
- * let the "regular" synth processing steps take care of adding the ramp
- * down samples to the output buffer. After we are sure that all voices
- * have completed ramping down, we continue the process of resetting the
- * synth (from another routine).
- *
- * Inputs:
- * psEASData - pointer to overall EAS data structure
- * force - force reset even if voices are active
- *
- * Outputs:
- *
- * Side Effects:
- * - set a flag (in psSynthObject->m_nFlags) indicating synth reset requested.
- * - force all voices to update their envelope states to mute
- *
- *----------------------------------------------------------------------------
-*/
-void VMReset (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_BOOL force)
-{
-
-#ifdef _DEBUG_VM
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMReset: request to reset synth. Force = %d\n", force); */ }
-#endif
-
- /* force voices to off state - may cause audio artifacts */
- if (force)
- {
- pVoiceMgr->activeVoices -= pSynth->numActiveVoices;
- pSynth->numActiveVoices = 0;
- VMInitializeAllVoices(pVoiceMgr, pSynth->vSynthNum);
- }
- else
- VMMuteAllVoices(pVoiceMgr, pSynth);
-
- /* don't reset if voices are still playing */
- if (pSynth->numActiveVoices == 0)
- {
- EAS_INT i;
-
-#ifdef _DEBUG_VM
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMReset: complete the reset process\n"); */ }
-#endif
-
- VMInitializeAllChannels(pVoiceMgr, pSynth);
- for (i = 0; i < NUM_SYNTH_CHANNELS; i++)
- pSynth->poolCount[i] = 0;
-
- /* set polyphony */
- if (pSynth->maxPolyphony < pVoiceMgr->maxPolyphony)
- pSynth->poolAlloc[0] = (EAS_U8) pVoiceMgr->maxPolyphony;
- else
- pSynth->poolAlloc[0] = (EAS_U8) pSynth->maxPolyphony;
-
- /* clear reset flag */
- pSynth->synthFlags &= ~SYNTH_FLAG_RESET_IS_REQUESTED;
- }
-
- /* handle reset after voices are muted */
- else
- pSynth->synthFlags |= SYNTH_FLAG_RESET_IS_REQUESTED;
-}
-
-/*----------------------------------------------------------------------------
- * VMInitializeAllChannels()
- *----------------------------------------------------------------------------
- * Purpose:
- *
- * Inputs:
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- *
- *----------------------------------------------------------------------------
-*/
-void VMInitializeAllChannels (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth)
-{
- S_SYNTH_CHANNEL *pChannel;
- EAS_INT i;
-
- VMResetControllers(pSynth);
-
- /* init each channel */
- pChannel = pSynth->channels;
-
- for (i = 0; i < NUM_SYNTH_CHANNELS; i++, pChannel++)
- {
- pChannel->channelFlags = DEFAULT_CHANNEL_FLAGS;
- pChannel->staticGain = DEFAULT_CHANNEL_STATIC_GAIN;
- pChannel->staticPitch = DEFAULT_CHANNEL_STATIC_PITCH;
- pChannel->pool = 0;
-
- /* the drum channel needs a different init */
- if (i == DEFAULT_DRUM_CHANNEL)
- {
- pChannel->bankNum = DEFAULT_RHYTHM_BANK_NUMBER;
- pChannel->channelFlags |= CHANNEL_FLAG_RHYTHM_CHANNEL;
- }
- else
- pChannel->bankNum = DEFAULT_MELODY_BANK_NUMBER;
-
- VMProgramChange(pVoiceMgr, pSynth, (EAS_U8) i, DEFAULT_SYNTH_PROGRAM_NUMBER);
- }
-
-}
-
-/*----------------------------------------------------------------------------
- * VMResetControllers()
- *----------------------------------------------------------------------------
- * Purpose:
- *
- * Inputs:
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- *
- *----------------------------------------------------------------------------
-*/
-void VMResetControllers (S_SYNTH *pSynth)
-{
- S_SYNTH_CHANNEL *pChannel;
- EAS_INT i;
-
- pChannel = pSynth->channels;
-
- for (i = 0; i < NUM_SYNTH_CHANNELS; i++, pChannel++)
- {
- pChannel->pitchBend = DEFAULT_PITCH_BEND;
- pChannel->modWheel = DEFAULT_MOD_WHEEL;
- pChannel->volume = DEFAULT_CHANNEL_VOLUME;
- pChannel->pan = DEFAULT_PAN;
- pChannel->expression = DEFAULT_EXPRESSION;
-
-#ifdef _REVERB
- pSynth->channels[i].reverbSend = DEFAULT_REVERB_SEND;
-#endif
-
-#ifdef _CHORUS
- pSynth->channels[i].chorusSend = DEFAULT_CHORUS_SEND;
-#endif
-
- pChannel->channelPressure = DEFAULT_CHANNEL_PRESSURE;
- pChannel->registeredParam = DEFAULT_REGISTERED_PARAM;
- pChannel->pitchBendSensitivity = DEFAULT_PITCH_BEND_SENSITIVITY;
- pChannel->finePitch = DEFAULT_FINE_PITCH;
- pChannel->coarsePitch = DEFAULT_COARSE_PITCH;
-
- /* update all voices on this channel */
- pChannel->channelFlags |= CHANNEL_FLAG_UPDATE_CHANNEL_PARAMETERS;
- }
-}
-
-/*----------------------------------------------------------------------------
- * VMInitializeAllVoices()
- *----------------------------------------------------------------------------
- * Purpose:
- *
- * Inputs:
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- *
- *----------------------------------------------------------------------------
-*/
-void VMInitializeAllVoices (S_VOICE_MGR *pVoiceMgr, EAS_INT vSynthNum)
-{
- EAS_INT i;
-
- /* initialize the voice manager parameters */
- for (i = 0; i < MAX_SYNTH_VOICES; i++)
- {
- if (pVoiceMgr->voices[i].voiceState != eVoiceStateStolen)
- {
- if (GET_VSYNTH(pVoiceMgr->voices[i].channel) == vSynthNum)
- InitVoice(&pVoiceMgr->voices[i]);
- }
- else
- {
- if (GET_VSYNTH(pVoiceMgr->voices[i].nextChannel) == vSynthNum)
- InitVoice(&pVoiceMgr->voices[i]);
- }
- }
-}
-
-/*----------------------------------------------------------------------------
- * VMMuteVoice()
- *----------------------------------------------------------------------------
- * Mute the selected voice
- *----------------------------------------------------------------------------
-*/
-void VMMuteVoice (S_VOICE_MGR *pVoiceMgr, EAS_I32 voiceNum)
-{
- S_SYNTH *pSynth;
- S_SYNTH_VOICE *pVoice;
-
- /* take no action if voice is already muted */
- pVoice = &pVoiceMgr->voices[voiceNum];
- if ((pVoice->voiceState == eVoiceStateMuting) || (pVoice->voiceState == eVoiceStateFree))
- return;
-
- /* one less voice in pool */
- DecVoicePoolCount(pVoiceMgr, pVoice);
-
- pSynth = pVoiceMgr->pSynth[GET_VSYNTH(pVoice->channel)];
- GetSynthPtr(voiceNum)->pfMuteVoice(pVoiceMgr, pSynth, pVoice, GetAdjustedVoiceNum(voiceNum));
- pVoice->voiceState = eVoiceStateMuting;
-
-}
-
-/*----------------------------------------------------------------------------
- * VMReleaseVoice()
- *----------------------------------------------------------------------------
- * Release the selected voice
- *----------------------------------------------------------------------------
-*/
-void VMReleaseVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_I32 voiceNum)
-{
- S_SYNTH_VOICE *pVoice = &pVoiceMgr->voices[voiceNum];
-
- /* take no action if voice is already free, muting, or releasing */
- if (( pVoice->voiceState == eVoiceStateMuting) ||
- (pVoice->voiceState == eVoiceStateFree) ||
- (pVoice->voiceState == eVoiceStateRelease))
- return;
-
- /* stolen voices should just be muted */
- if (pVoice->voiceState == eVoiceStateStolen)
- VMMuteVoice(pVoiceMgr, voiceNum);
-
- /* release this voice */
- GetSynthPtr(voiceNum)->pfReleaseVoice(pVoiceMgr, pSynth, &pVoiceMgr->voices[voiceNum], GetAdjustedVoiceNum(voiceNum));
- pVoice->voiceState = eVoiceStateRelease;
-}
-
-/*----------------------------------------------------------------------------
- * VMInitMIPTable()
- *----------------------------------------------------------------------------
- * Initialize the SP-MIDI MIP table in preparation for receiving MIP message
- *----------------------------------------------------------------------------
-*/
-void VMInitMIPTable (S_SYNTH *pSynth)
-{
- EAS_INT i;
-
-#ifdef _DEBUG_VM
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMInitMIPTable\n"); */ }
-#endif
-
- /* clear SP-MIDI flag */
- pSynth->synthFlags &= ~SYNTH_FLAG_SP_MIDI_ON;
- for (i = 0; i < NUM_SYNTH_CHANNELS; i++)
- {
- pSynth->channels[i].pool = 0;
- pSynth->channels[i].mip = 0;
- }
-}
-
-/*----------------------------------------------------------------------------
- * VMSetMIPEntry()
- *----------------------------------------------------------------------------
- * Sets the priority and MIP level for a MIDI channel
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, pVoiceMgr) reserved for future use */
-void VMSetMIPEntry (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel, EAS_U8 priority, EAS_U8 mip)
-{
-
-#ifdef _DEBUG_VM
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMSetMIPEntry: channel=%d, priority=%d, MIP=%d\n", channel, priority, mip); */ }
-#endif
-
- /* save data for use by MIP message processing */
- if (priority < NUM_SYNTH_CHANNELS)
- {
- pSynth->channels[channel].pool = priority;
- pSynth->channels[channel].mip = mip;
- }
-}
-
-/*----------------------------------------------------------------------------
- * VMMIPUpdateChannelMuting()
- *----------------------------------------------------------------------------
- * This routine is called after an SP-MIDI message is received and
- * any time the allocated polyphony changes. It mutes or unmutes
- * channels based on polyphony.
- *----------------------------------------------------------------------------
-*/
-void VMMIPUpdateChannelMuting (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth)
-{
- EAS_INT i;
- EAS_INT maxPolyphony;
- EAS_INT channel;
- EAS_INT vSynthNum;
- EAS_INT pool;
-
-#ifdef _DEBUG_VM
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMUpdateMIPTable\n"); */ }
-#endif
-
- /* determine max polyphony */
- if (pSynth->maxPolyphony)
- maxPolyphony = pSynth->maxPolyphony;
- else
- maxPolyphony = pVoiceMgr->maxPolyphony;
-
- /* process channels */
- for (i = 0; i < NUM_SYNTH_CHANNELS; i++)
- {
-
- /* channel must be in MIP message and must meet allocation target */
- if ((pSynth->channels[i].mip != 0) && (pSynth->channels[i].mip <= maxPolyphony))
- pSynth->channels[i].channelFlags &= ~CHANNEL_FLAG_MUTE;
- else
- pSynth->channels[i].channelFlags |= CHANNEL_FLAG_MUTE;
-
- /* reset voice pool count */
- pSynth->poolCount[i] = 0;
- }
-
- /* mute any voices on muted channels, and count unmuted voices */
- for (i = 0; i < MAX_SYNTH_VOICES; i++)
- {
-
- /* ignore free voices */
- if (pVoiceMgr->voices[i].voiceState == eVoiceStateFree)
- continue;
-
- /* get channel and virtual synth */
- if (pVoiceMgr->voices[i].voiceState != eVoiceStateStolen)
- {
- vSynthNum = GET_VSYNTH(pVoiceMgr->voices[i].channel);
- channel = GET_CHANNEL(pVoiceMgr->voices[i].channel);
- }
- else
- {
- vSynthNum = GET_VSYNTH(pVoiceMgr->voices[i].nextChannel);
- channel = GET_CHANNEL(pVoiceMgr->voices[i].nextChannel);
- }
-
- /* ignore voices on other synths */
- if (vSynthNum != pSynth->vSynthNum)
- continue;
-
- /* count voices */
- pool = pSynth->channels[channel].pool;
-
- /* deal with muted channels */
- if (pSynth->channels[channel].channelFlags & CHANNEL_FLAG_MUTE)
- {
- /* mute stolen voices scheduled to play on this channel */
- if (pVoiceMgr->voices[i].voiceState == eVoiceStateStolen)
- pVoiceMgr->voices[i].voiceState = eVoiceStateMuting;
-
- /* release voices that aren't already muting */
- else if (pVoiceMgr->voices[i].voiceState != eVoiceStateMuting)
- {
- VMReleaseVoice(pVoiceMgr, pSynth, i);
- pSynth->poolCount[pool]++;
- }
- }
-
- /* not muted, count this voice */
- else
- pSynth->poolCount[pool]++;
- }
-}
-
-/*----------------------------------------------------------------------------
- * VMUpdateMIPTable()
- *----------------------------------------------------------------------------
- * This routine is called at the end of the SysEx message to allow
- * the Voice Manager to complete the initialization of the MIP
- * table. It assigns channels to the appropriate voice pool based
- * on the MIP setting and calculates the voices allocated for each
- * pool.
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, pVoiceMgr) reserved for future use */
-void VMUpdateMIPTable (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth)
-{
- S_SYNTH_CHANNEL *pChannel;
- EAS_INT i;
- EAS_INT currentMIP;
- EAS_INT currentPool;
- EAS_INT priority[NUM_SYNTH_CHANNELS];
-
-#ifdef _DEBUG_VM
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMUpdateMIPTable\n"); */ }
-#endif
-
- /* set SP-MIDI flag */
- pSynth->synthFlags |= SYNTH_FLAG_SP_MIDI_ON;
-
- /* sort channels into priority order */
- for (i = 0; i < NUM_SYNTH_CHANNELS; i++)
- priority[i] = -1;
- for (i = 0; i < NUM_SYNTH_CHANNELS; i++)
- {
- if (pSynth->channels[i].pool != DEFAULT_SP_MIDI_PRIORITY)
- priority[pSynth->channels[i].pool] = i;
- }
-
- /* process channels in priority order */
- currentMIP = 0;
- currentPool = -1;
- for (i = 0; i < NUM_SYNTH_CHANNELS; i++)
- {
- /* stop when we run out of channels */
- if (priority[i] == -1)
- break;
-
- pChannel = &pSynth->channels[priority[i]];
-
- /* when 2 or more channels have the same MIP setting, they
- * share a common voice pool
- */
- if (pChannel->mip == currentMIP)
- pChannel->pool = (EAS_U8) currentPool;
-
- /* new voice pool */
- else
- {
- currentPool++;
- pSynth->poolAlloc[currentPool] = (EAS_U8) (pChannel->mip - currentMIP);
- currentMIP = pChannel->mip;
- }
- }
-
- /* set SP-MIDI flag */
- pSynth->synthFlags |= SYNTH_FLAG_SP_MIDI_ON;
-
- /* update channel muting */
- VMMIPUpdateChannelMuting (pVoiceMgr, pSynth);
-}
-
-/*----------------------------------------------------------------------------
- * VMMuteAllVoices()
- *----------------------------------------------------------------------------
- * Purpose:
- * We call this in an emergency reset situation.
- * This forces all voices to mute quickly.
- *
- * Inputs:
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- *
- * Side Effects:
- * - forces all voices to update their envelope states to mute
- *
- *----------------------------------------------------------------------------
-*/
-void VMMuteAllVoices (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth)
-{
- EAS_INT i;
-
-#ifdef _DEBUG_VM
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMMuteAllVoices: about to mute all voices!!\n"); */ }
-#endif
-
- for (i = 0; i < MAX_SYNTH_VOICES; i++)
- {
- /* for stolen voices, check new channel */
- if (pVoiceMgr->voices[i].voiceState == eVoiceStateStolen)
- {
- if (GET_VSYNTH(pVoiceMgr->voices[i].nextChannel) == pSynth->vSynthNum)
- VMMuteVoice(pVoiceMgr, i);
- }
-
- else if (pSynth->vSynthNum == GET_VSYNTH(pVoiceMgr->voices[i].channel))
- VMMuteVoice(pVoiceMgr, i);
- }
-}
-
-/*----------------------------------------------------------------------------
- * VMReleaseAllVoices()
- *----------------------------------------------------------------------------
- * Purpose:
- * We call this after we've encountered the end of the Midi file.
- * This ensures all voices are either in release (because we received their
- * note off already) or forces them to mute quickly.
- * We use this as a safety to prevent bad midi files from playing forever.
- *
- * Inputs:
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- *
- * Side Effects:
- * - forces all voices to update their envelope states to release or mute
- *
- *----------------------------------------------------------------------------
-*/
-void VMReleaseAllVoices (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth)
-{
- EAS_INT i;
-
- /* release sustain pedal on all channels */
- for (i = 0; i < NUM_SYNTH_CHANNELS; i++)
- {
- if (pSynth->channels[ i ].channelFlags & CHANNEL_FLAG_SUSTAIN_PEDAL)
- {
- VMReleaseAllDeferredNoteOffs(pVoiceMgr, pSynth, (EAS_U8) i);
- pSynth->channels[i].channelFlags &= ~CHANNEL_FLAG_SUSTAIN_PEDAL;
- }
- }
-
- /* release all voices */
- for (i = 0; i < MAX_SYNTH_VOICES; i++)
- {
-
- switch (pVoiceMgr->voices[i].voiceState)
- {
- case eVoiceStateStart:
- case eVoiceStatePlay:
- /* only release voices on this synth */
- if (GET_VSYNTH(pVoiceMgr->voices[i].channel) == pSynth->vSynthNum)
- VMReleaseVoice(pVoiceMgr, pSynth, i);
- break;
-
- case eVoiceStateStolen:
- if (GET_VSYNTH(pVoiceMgr->voices[i].nextChannel) == pSynth->vSynthNum)
- VMMuteVoice(pVoiceMgr, i);
- break;
-
- case eVoiceStateFree:
- case eVoiceStateRelease:
- case eVoiceStateMuting:
- break;
-
- case eVoiceStateInvalid:
- default:
-#ifdef _DEBUG_VM
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMReleaseAllVoices: error, %d is an unrecognized state\n",
- pVoiceMgr->voices[i].voiceState); */ }
-#endif
- break;
- }
- }
-}
-
-/*----------------------------------------------------------------------------
- * VMAllNotesOff()
- *----------------------------------------------------------------------------
- * Purpose:
- * Quickly mute all notes on the given channel.
- *
- * Inputs:
- * nChannel - quickly turn off all notes on this channel
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- *
- * Side Effects:
- * - forces all voices on this channel to update their envelope states to mute
- *
- *----------------------------------------------------------------------------
-*/
-void VMAllNotesOff (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel)
-{
- EAS_INT voiceNum;
- S_SYNTH_VOICE *pVoice;
-
-#ifdef _DEBUG_VM
- if (channel >= NUM_SYNTH_CHANNELS)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMAllNotesOff: error, %d invalid channel number\n",
- channel); */ }
- return;
- }
-#endif
-
- /* increment workload */
- pVoiceMgr->workload += WORKLOAD_AMOUNT_SMALL_INCREMENT;
-
- /* check each voice */
- channel = VSynthToChannel(pSynth, channel);
- for (voiceNum = 0; voiceNum < MAX_SYNTH_VOICES; voiceNum++)
- {
- pVoice = &pVoiceMgr->voices[voiceNum];
- if (pVoice->voiceState != eVoiceStateFree)
- {
- if (((pVoice->voiceState != eVoiceStateStolen) && (channel == pVoice->channel)) ||
- ((pVoice->voiceState == eVoiceStateStolen) && (channel == pVoice->nextChannel)))
- {
- /* this voice is assigned to the requested channel */
- GetSynthPtr(voiceNum)->pfMuteVoice(pVoiceMgr, pSynth, pVoice, GetAdjustedVoiceNum(voiceNum));
- pVoice->voiceState = eVoiceStateMuting;
- }
- }
- }
-}
-
-/*----------------------------------------------------------------------------
- * VMDeferredStopNote()
- *----------------------------------------------------------------------------
- * Purpose:
- * Stop the notes that had deferred note-off requests.
- *
- * Inputs:
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- * None.
- *
- * Side Effects:
- * voices that have had deferred note-off requests are now put into release
- * psSynthObject->m_sVoice[i].m_nFlags has the VOICE_FLAG_DEFER_MIDI_NOTE_OFF
- * cleared
- *----------------------------------------------------------------------------
-*/
-void VMDeferredStopNote (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth)
-{
- EAS_INT voiceNum;
- EAS_INT channel;
- EAS_BOOL deferredNoteOff;
-
- deferredNoteOff = EAS_FALSE;
-
- /* check each voice to see if it requires a deferred note off */
- for (voiceNum=0; voiceNum < MAX_SYNTH_VOICES; voiceNum++)
- {
- if (pVoiceMgr->voices[voiceNum].voiceFlags & VOICE_FLAG_DEFER_MIDI_NOTE_OFF)
- {
- /* check if this voice was stolen */
- if (pVoiceMgr->voices[voiceNum].voiceState == eVoiceStateStolen)
- {
- /*
- This voice was stolen, AND it also has a deferred note-off.
- The stolen note must be completely ramped down at this point.
- The note that caused the stealing to occur, however, must
- have received a note-off request before the note that caused
- stealing ever had a chance to even start. We want to give
- the note that caused the stealing a chance to play, so we
- start it on the next update interval, and we defer sending
- the note-off request until the subsequent update interval.
- So do not send the note-off request for this voice because
- this voice was stolen and should have completed ramping down,
- Also, do not clear the global flag nor this voice's flag
- because we must indicate that the subsequent update interval,
- after the note that caused stealing has started, should
- then send the deferred note-off request.
- */
- deferredNoteOff = EAS_TRUE;
-
-#ifdef _DEBUG_VM
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMDeferredStopNote: defer request to stop voice %d (channel=%d note=%d) - voice not started\n",
- voiceNum,
- pVoiceMgr->voices[voiceNum].nextChannel,
- pVoiceMgr->voices[voiceNum].note); */ }
-
- /* sanity check: this stolen voice better be ramped to zero */
- if (0 != pVoiceMgr->voices[voiceNum].gain)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMDeferredStopNote: warning, this voice did not complete its ramp to zero\n"); */ }
- }
-#endif // #ifdef _DEBUG_VM
-
- }
- else
- {
- /* clear the flag using exor */
- pVoiceMgr->voices[voiceNum].voiceFlags ^=
- VOICE_FLAG_DEFER_MIDI_NOTE_OFF;
-
-#ifdef _DEBUG_VM
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMDeferredStopNote: Stop voice %d (channel=%d note=%d)\n",
- voiceNum,
- pVoiceMgr->voices[voiceNum].nextChannel,
- pVoiceMgr->voices[voiceNum].note); */ }
-#endif
-
- channel = pVoiceMgr->voices[voiceNum].channel & 15;
-
- /* check if sustain pedal is on */
- if (pSynth->channels[channel].channelFlags & CHANNEL_FLAG_SUSTAIN_PEDAL)
- {
- GetSynthPtr(voiceNum)->pfSustainPedal(pVoiceMgr, pSynth, &pVoiceMgr->voices[voiceNum], &pSynth->channels[channel], GetAdjustedVoiceNum(voiceNum));
- }
-
- /* release this voice */
- else
- VMReleaseVoice(pVoiceMgr, pSynth, voiceNum);
-
- }
-
- }
-
- }
-
- /* clear the deferred note-off flag, unless there's another one pending */
- if (deferredNoteOff == EAS_FALSE)
- pSynth->synthFlags ^= SYNTH_FLAG_DEFERRED_MIDI_NOTE_OFF_PENDING;
-}
-
-/*----------------------------------------------------------------------------
- * VMReleaseAllDeferredNoteOffs()
- *----------------------------------------------------------------------------
- * Purpose:
- * Call this functin when the sustain flag is presently set but
- * we are now transitioning from damper pedal on to
- * damper pedal off. This means all notes in this channel
- * that received a note off while the damper pedal was on, and
- * had their note-off requests deferred, should now proceed to
- * the release state.
- *
- * Inputs:
- * nChannel - this channel has its sustain pedal transitioning from on to off
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- * Side Effects:
- * any voice with deferred note offs on this channel are updated such that
- * pVoice->m_sEG1.m_eState = eEnvelopeStateRelease
- * pVoice->m_sEG1.m_nIncrement = release increment
- * pVoice->m_nFlags = clear the deferred note off flag
- *----------------------------------------------------------------------------
-*/
-void VMReleaseAllDeferredNoteOffs (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel)
-{
- S_SYNTH_VOICE *pVoice;
- EAS_INT voiceNum;
-
-#ifdef _DEBUG_VM
- if (channel >= NUM_SYNTH_CHANNELS)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMReleaseAllDeferredNoteOffs: error, %d invalid channel number\n",
- channel); */ }
- return;
- }
-#endif /* #ifdef _DEBUG_VM */
-
- /* increment workload */
- pVoiceMgr->workload += WORKLOAD_AMOUNT_SMALL_INCREMENT;
-
- /* find all the voices assigned to this channel */
- channel = VSynthToChannel(pSynth, channel);
- for (voiceNum = 0; voiceNum < MAX_SYNTH_VOICES; voiceNum++)
- {
-
- pVoice = &pVoiceMgr->voices[voiceNum];
- if (channel == pVoice->channel)
- {
-
- /* does this voice have a deferred note off? */
- if (pVoice->voiceFlags & VOICE_FLAG_SUSTAIN_PEDAL_DEFER_NOTE_OFF)
- {
- /* release voice */
- VMReleaseVoice(pVoiceMgr, pSynth, voiceNum);
-
- /* use exor to flip bit, clear the flag */
- pVoice->voiceFlags &= ~VOICE_FLAG_SUSTAIN_PEDAL_DEFER_NOTE_OFF;
-
- }
-
- }
- }
-
- return;
-}
-
-/*----------------------------------------------------------------------------
- * VMCatchNotesForSustainPedal()
- *----------------------------------------------------------------------------
- * Purpose:
- * Call this function when the sustain flag is presently clear and
- * the damper pedal is off and we are transitioning from damper pedal OFF to
- * damper pedal ON. Currently sounding notes should be left
- * unchanged. However, we should try to "catch" notes if possible.
- * If any notes are in release and have levels >= sustain level, catch them,
- * otherwise, let them continue to release.
- *
- * Inputs:
- * nChannel - this channel has its sustain pedal transitioning from on to off
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- *----------------------------------------------------------------------------
-*/
-void VMCatchNotesForSustainPedal (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel)
-{
- EAS_INT voiceNum;
-
-#ifdef _DEBUG_VM
- if (channel >= NUM_SYNTH_CHANNELS)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMCatchNotesForSustainPedal: error, %d invalid channel number\n",
- channel); */ }
- return;
- }
-#endif
-
- pVoiceMgr->workload += WORKLOAD_AMOUNT_SMALL_INCREMENT;
- channel = VSynthToChannel(pSynth, channel);
-
- /* find all the voices assigned to this channel */
- for (voiceNum = 0; voiceNum < MAX_SYNTH_VOICES; voiceNum++)
- {
- if (channel == pVoiceMgr->voices[voiceNum].channel)
- {
- if (eVoiceStateRelease == pVoiceMgr->voices[voiceNum].voiceState)
- GetSynthPtr(voiceNum)->pfSustainPedal(pVoiceMgr, pSynth, &pVoiceMgr->voices[voiceNum], &pSynth->channels[channel], GetAdjustedVoiceNum(voiceNum));
- }
- }
-}
-
-/*----------------------------------------------------------------------------
- * VMUpdateAllNotesAge()
- *----------------------------------------------------------------------------
- * Purpose:
- * Increment the note age for all of the active voices.
- *
- * Inputs:
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- *
- * Side Effects:
- * m_nAge for all voices is incremented
- *----------------------------------------------------------------------------
-*/
-void VMUpdateAllNotesAge (S_VOICE_MGR *pVoiceMgr, EAS_U16 age)
-{
- EAS_INT i;
-
- for (i = 0; i < MAX_SYNTH_VOICES; i++)
- {
- if (age - pVoiceMgr->voices[i].age > 0)
- pVoiceMgr->voices[i].age++;
- }
-}
-
-/*----------------------------------------------------------------------------
- * VMStolenVoice()
- *----------------------------------------------------------------------------
- * Purpose:
- * The selected voice is being stolen. Sets the parameters so that the
- * voice will begin playing the new sound on the next buffer.
- *
- * Inputs:
- * pVoice - pointer to voice to steal
- * nChannel - the channel to start a note on
- * nKeyNumber - the key number to start a note for
- * nNoteVelocity - the key velocity from this note
- *
- * Outputs:
- * None
- *----------------------------------------------------------------------------
-*/
-static void VMStolenVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_I32 voiceNum, EAS_U8 channel, EAS_U8 note, EAS_U8 velocity, EAS_U16 regionIndex)
-{
- S_SYNTH_VOICE *pVoice = &pVoiceMgr->voices[voiceNum];
-
- /* one less voice in old pool */
- DecVoicePoolCount(pVoiceMgr, pVoice);
-
- /* mute the sound that is currently playing */
- GetSynthPtr(voiceNum)->pfMuteVoice(pVoiceMgr, pVoiceMgr->pSynth[GET_VSYNTH(pVoice->channel)], &pVoiceMgr->voices[voiceNum], GetAdjustedVoiceNum(voiceNum));
- pVoice->voiceState = eVoiceStateStolen;
-
- /* set new note data */
- pVoice->nextChannel = VSynthToChannel(pSynth, channel);
- pVoice->nextNote = note;
- pVoice->nextVelocity = velocity;
- pVoice->nextRegionIndex = regionIndex;
-
- /* one more voice in new pool */
- IncVoicePoolCount(pVoiceMgr, pVoice);
-
- /* clear the deferred flags */
- pVoice->voiceFlags &=
- ~(VOICE_FLAG_DEFER_MIDI_NOTE_OFF |
- VOICE_FLAG_DEFER_MUTE |
- VOICE_FLAG_SUSTAIN_PEDAL_DEFER_NOTE_OFF);
-
- /* all notes older than this one get "younger" */
- VMUpdateAllNotesAge(pVoiceMgr, pVoice->age);
-
- /* assign current age to this note and increment for the next note */
- pVoice->age = pVoiceMgr->age++;
-}
-
-/*----------------------------------------------------------------------------
- * VMFreeVoice()
- *----------------------------------------------------------------------------
- * Purpose:
- * The selected voice is done playing and being returned to the
- * pool of free voices
- *
- * Inputs:
- * pVoice - pointer to voice to free
- *
- * Outputs:
- * None
- *----------------------------------------------------------------------------
-*/
-static void VMFreeVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice)
-{
-
- /* do nothing if voice is already free */
- if (pVoice->voiceState == eVoiceStateFree)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "VMFreeVoice: Attempt to free voice that is already free\n"); */ }
- return;
- }
-
- /* if we jump directly to free without passing muting stage,
- * we need to adjust the voice count */
- DecVoicePoolCount(pVoiceMgr, pVoice);
-
-
-#ifdef _DEBUG_VM
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "VMFreeVoice: Synth=%d\n", pSynth->vSynthNum); */ }
-#endif
-
- /* return to free voice pool */
- pVoiceMgr->activeVoices--;
- pSynth->numActiveVoices--;
- InitVoice(pVoice);
-
-#ifdef _DEBUG_VM
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMFreeVoice: free voice %d\n", pVoice - pVoiceMgr->voices); */ }
-#endif
-
- /* all notes older than this one get "younger" */
- VMUpdateAllNotesAge(pVoiceMgr, pVoice->age);
- }
-
-/*----------------------------------------------------------------------------
- * VMRetargetStolenVoice()
- *----------------------------------------------------------------------------
- * Purpose:
- * The selected voice has been stolen and needs to be initalized with
- * the paramters of its new note.
- *
- * Inputs:
- * pVoice - pointer to voice to retarget
- *
- * Outputs:
- * None
- *----------------------------------------------------------------------------
-*/
-static EAS_BOOL VMRetargetStolenVoice (S_VOICE_MGR *pVoiceMgr, EAS_I32 voiceNum)
-{
- EAS_U8 flags;
- S_SYNTH_CHANNEL *pMIDIChannel;
- S_SYNTH_VOICE *pVoice;
- S_SYNTH *pSynth;
- S_SYNTH *pNextSynth;
-
- /* establish some pointers */
- pVoice = &pVoiceMgr->voices[voiceNum];
- pSynth = pVoiceMgr->pSynth[GET_VSYNTH(pVoice->channel)];
- pMIDIChannel = &pSynth->channels[pVoice->channel & 15];
- pNextSynth = pVoiceMgr->pSynth[GET_VSYNTH(pVoice->nextChannel)];
-
-#ifdef _DEBUG_VM
-{ /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMRetargetStolenVoice: retargeting stolen voice %d on channel %d\n",
- voiceNum, pVoice->channel); */ }
-
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "\to channel %d note: %d velocity: %d\n",
- pVoice->nextChannel, pVoice->nextNote, pVoice->nextVelocity); */ }
-#endif
-
- /* make sure new channel hasn't been muted by SP-MIDI since the voice was stolen */
- if ((pSynth->synthFlags & SYNTH_FLAG_SP_MIDI_ON) &&
- (pMIDIChannel->channelFlags & CHANNEL_FLAG_MUTE))
- {
- VMFreeVoice(pVoiceMgr, pSynth, &pVoiceMgr->voices[voiceNum]);
- return EAS_FALSE;
- }
-
- /* if assigned to a new synth, correct the active voice count */
- if (pVoice->channel != pVoice->nextChannel)
- {
-#ifdef _DEBUG_VM
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMRetargetStolenVoice: Note assigned to different virtual synth, adjusting numActiveVoices\n"); */ }
-#endif
- pSynth->numActiveVoices--;
- pNextSynth->numActiveVoices++;
- }
-
- /* assign new channel number, and increase channel voice count */
- pVoice->channel = pVoice->nextChannel;
- pMIDIChannel = &pNextSynth->channels[pVoice->channel & 15];
-
- /* assign other data */
- pVoice->note = pVoice->nextNote;
- pVoice->velocity = pVoice->nextVelocity;
- pVoice->nextChannel = UNASSIGNED_SYNTH_CHANNEL;
- pVoice->regionIndex = pVoice->nextRegionIndex;
-
- /* save the flags, pfStartVoice() will clear them */
- flags = pVoice->voiceFlags;
-
- /* keep track of the note-start related workload */
- pVoiceMgr->workload += WORKLOAD_AMOUNT_START_NOTE;
-
- /* setup the voice parameters */
- pVoice->voiceState = eVoiceStateStart;
-
- /*lint -e{522} return not used at this time */
- GetSynthPtr(voiceNum)->pfStartVoice(pVoiceMgr, pNextSynth, &pVoiceMgr->voices[voiceNum], GetAdjustedVoiceNum(voiceNum), pVoice->regionIndex);
-
- /* did the new note already receive a MIDI note-off request? */
- if (flags & VOICE_FLAG_DEFER_MIDI_NOTE_OFF)
- {
-#ifdef _DEBUG_VM
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMRetargetVoice: stolen note note-off request deferred\n"); */ }
-#endif
- pVoice->voiceFlags |= VOICE_FLAG_DEFER_MIDI_NOTE_OFF;
- pNextSynth->synthFlags |= SYNTH_FLAG_DEFERRED_MIDI_NOTE_OFF_PENDING;
- }
-
- return EAS_TRUE;
-}
-
-/*----------------------------------------------------------------------------
- * VMCheckKeyGroup()
- *----------------------------------------------------------------------------
- * If the note that we've been asked to start is in the same key group as
- * any currently playing notes, then we must shut down the currently playing
- * note in the same key group
- *----------------------------------------------------------------------------
-*/
-void VMCheckKeyGroup (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U16 keyGroup, EAS_U8 channel)
-{
- const S_REGION *pRegion;
- EAS_INT voiceNum;
-
- /* increment frame workload */
- pVoiceMgr->workload += WORKLOAD_AMOUNT_KEY_GROUP;
-
- /* need to check all voices in case this is a layered sound */
- channel = VSynthToChannel(pSynth, channel);
- for (voiceNum = 0; voiceNum < MAX_SYNTH_VOICES; voiceNum++)
- {
- if (pVoiceMgr->voices[voiceNum].voiceState != eVoiceStateStolen)
- {
- /* voice must be on the same channel */
- if (channel == pVoiceMgr->voices[voiceNum].channel)
- {
- /* check key group */
- pRegion = GetRegionPtr(pSynth, pVoiceMgr->voices[voiceNum].regionIndex);
- if (keyGroup == (pRegion->keyGroupAndFlags & 0x0f00))
- {
-#ifdef _DEBUG_VM
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMCheckKeyGroup: voice %d matches key group %d\n", voiceNum, keyGroup >> 8); */ }
-#endif
-
- /* if this voice was just started, set it to mute on the next buffer */
- if (pVoiceMgr->voices[voiceNum].voiceFlags & VOICE_FLAG_NO_SAMPLES_SYNTHESIZED_YET)
- pVoiceMgr->voices[voiceNum].voiceFlags |= VOICE_FLAG_DEFER_MUTE;
-
- /* mute immediately */
- else
- VMMuteVoice(pVoiceMgr, voiceNum);
- }
- }
- }
-
- /* for stolen voice, check new values */
- else
- {
- /* voice must be on the same channel */
- if (channel == pVoiceMgr->voices[voiceNum].nextChannel)
- {
- /* check key group */
- pRegion = GetRegionPtr(pSynth, pVoiceMgr->voices[voiceNum].nextRegionIndex);
- if (keyGroup == (pRegion->keyGroupAndFlags & 0x0f00))
- {
-#ifdef _DEBUG_VM
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMCheckKeyGroup: voice %d matches key group %d\n", voiceNum, keyGroup >> 8); */ }
-#endif
-
- /* if this voice was just started, set it to mute on the next buffer */
- if (pVoiceMgr->voices[voiceNum].voiceFlags & VOICE_FLAG_NO_SAMPLES_SYNTHESIZED_YET)
- pVoiceMgr->voices[voiceNum].voiceFlags |= VOICE_FLAG_DEFER_MUTE;
-
- /* mute immediately */
- else
- VMMuteVoice(pVoiceMgr, voiceNum);
- }
- }
-
- }
- }
-}
-
-/*----------------------------------------------------------------------------
- * VMCheckPolyphonyLimiting()
- *----------------------------------------------------------------------------
- * Purpose:
- * We only play at most 2 of the same note on a MIDI channel.
- * E.g., if we are asked to start note 36, and there are already two voices
- * that are playing note 36, then we must steal the voice playing
- * the oldest note 36 and use that stolen voice to play the new note 36.
- *
- * Inputs:
- * nChannel - synth channel that wants to start a new note
- * nKeyNumber - new note's midi note number
- * nNoteVelocity - new note's velocity
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- * pbVoiceStealingRequired - flag: this routine sets true if we needed to
- * steal a voice
- * *
- * Side Effects:
- * psSynthObject->m_sVoice[free voice num].m_nKeyNumber may be assigned
- * psSynthObject->m_sVoice[free voice num].m_nVelocity may be assigned
- *----------------------------------------------------------------------------
-*/
-EAS_BOOL VMCheckPolyphonyLimiting (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel, EAS_U8 note, EAS_U8 velocity, EAS_U16 regionIndex, EAS_I32 lowVoice, EAS_I32 highVoice)
-{
- EAS_INT voiceNum;
- EAS_INT oldestVoiceNum;
- EAS_INT numVoicesPlayingNote;
- EAS_U16 age;
- EAS_U16 oldestNoteAge;
-
- pVoiceMgr->workload += WORKLOAD_AMOUNT_POLY_LIMIT;
-
- numVoicesPlayingNote = 0;
- oldestVoiceNum = MAX_SYNTH_VOICES;
- oldestNoteAge = 0;
- channel = VSynthToChannel(pSynth, channel);
-
- /* examine each voice on this channel playing this note */
- for (voiceNum = lowVoice; voiceNum <= highVoice; voiceNum++)
- {
- /* check stolen notes separately */
- if (pVoiceMgr->voices[voiceNum].voiceState != eVoiceStateStolen)
- {
-
- /* same channel and note ? */
- if ((channel == pVoiceMgr->voices[voiceNum].channel) && (note == pVoiceMgr->voices[voiceNum].note))
- {
- numVoicesPlayingNote++;
- age = pVoiceMgr->age - pVoiceMgr->voices[voiceNum].age;
-
- /* is this the oldest voice for this note? */
- if (age >= oldestNoteAge)
- {
- oldestNoteAge = age;
- oldestVoiceNum = voiceNum;
- }
- }
- }
-
- /* handle stolen voices */
- else
- {
- /* same channel and note ? */
- if ((channel == pVoiceMgr->voices[voiceNum].nextChannel) && (note == pVoiceMgr->voices[voiceNum].nextNote))
- {
- numVoicesPlayingNote++;
- }
- }
- }
-
- /* check to see if we exceeded poly limit */
- if (numVoicesPlayingNote < DEFAULT_CHANNEL_POLYPHONY_LIMIT)
- return EAS_FALSE;
-
- /* make sure we have a voice to steal */
- if (oldestVoiceNum != MAX_SYNTH_VOICES)
- {
-#ifdef _DEBUG_VM
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMCheckPolyphonyLimiting: voice %d has the oldest note\n", oldestVoiceNum); */ }
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "VMCheckPolyphonyLimiting: polyphony limiting requires shutting down note %d \n", pVoiceMgr->voices[oldestVoiceNum].note); */ }
-#endif
- VMStolenVoice(pVoiceMgr, pSynth, oldestVoiceNum, channel, note, velocity, regionIndex);
- return EAS_TRUE;
- }
-
-#ifdef _DEBUG_VM
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "VMCheckPolyphonyLimiting: No oldest voice to steal\n"); */ }
-#endif
- return EAS_FALSE;
-}
-
-/*----------------------------------------------------------------------------
- * VMStartVoice()
- *----------------------------------------------------------------------------
- * Starts a voice given a region index
- *----------------------------------------------------------------------------
-*/
-void VMStartVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel, EAS_U8 note, EAS_U8 velocity, EAS_U16 regionIndex)
-{
- const S_REGION *pRegion;
- S_SYNTH_CHANNEL *pChannel;
- EAS_INT voiceNum;
- EAS_INT maxSynthPoly;
- EAS_I32 lowVoice, highVoice;
- EAS_U16 keyGroup;
-
- pChannel = &pSynth->channels[channel];
- pRegion = GetRegionPtr(pSynth, regionIndex);
-
- /* select correct synth */
-#if defined(_SECONDARY_SYNTH) || defined(EAS_SPLIT_WT_SYNTH)
- {
-#ifdef EAS_SPLIT_WT_SYNTH
- if ((pRegion->keyGroupAndFlags & REGION_FLAG_OFF_CHIP) == 0)
-#else
- if ((regionIndex & FLAG_RGN_IDX_FM_SYNTH) == 0)
-#endif
- {
- lowVoice = 0;
- highVoice = NUM_PRIMARY_VOICES - 1;
- }
- else
- {
- lowVoice = NUM_PRIMARY_VOICES;
- highVoice = MAX_SYNTH_VOICES - 1;
- }
- }
-#else
- lowVoice = 0;
- highVoice = MAX_SYNTH_VOICES - 1;
-#endif
-
- /* keep track of the note-start related workload */
- pVoiceMgr->workload+= WORKLOAD_AMOUNT_START_NOTE;
-
- /* other voices in pool, check for key group and poly limiting */
- if (pSynth->poolCount[pChannel->pool] != 0)
- {
-
- /* check for key group exclusivity */
- keyGroup = pRegion->keyGroupAndFlags & 0x0f00;
- if (keyGroup!= 0)
- VMCheckKeyGroup(pVoiceMgr, pSynth, keyGroup, channel);
-
- /* check polyphony limit and steal a voice if necessary */
- if ((pRegion->keyGroupAndFlags & REGION_FLAG_NON_SELF_EXCLUSIVE) == 0)
- {
- if (VMCheckPolyphonyLimiting(pVoiceMgr, pSynth, channel, note, velocity, regionIndex, lowVoice, highVoice) == EAS_TRUE)
- return;
- }
- }
-
- /* check max poly allocation */
- if ((pSynth->maxPolyphony == 0) || (pVoiceMgr->maxPolyphony < pSynth->maxPolyphony))
- maxSynthPoly = pVoiceMgr->maxPolyphony;
- else
- maxSynthPoly = pSynth->maxPolyphony;
-
- /* any free voices? */
- if ((pVoiceMgr->activeVoices < pVoiceMgr->maxPolyphony) &&
- (pSynth->numActiveVoices < maxSynthPoly) &&
- (EAS_SUCCESS == VMFindAvailableVoice(pVoiceMgr, &voiceNum, lowVoice, highVoice)))
- {
- S_SYNTH_VOICE *pVoice = &pVoiceMgr->voices[voiceNum];
-
-#ifdef _DEBUG_VM
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "VMStartVoice: Synth=%d\n", pSynth->vSynthNum); */ }
-#endif
-
- /* bump voice counts */
- pVoiceMgr->activeVoices++;
- pSynth->numActiveVoices++;
-
-#ifdef _DEBUG_VM
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMStartVoice: voice %d assigned to channel %d note %d velocity %d\n",
- voiceNum, channel, note, velocity); */ }
-#endif
-
- /* save parameters */
- pVoiceMgr->voices[voiceNum].channel = VSynthToChannel(pSynth, channel);
- pVoiceMgr->voices[voiceNum].note = note;
- pVoiceMgr->voices[voiceNum].velocity = velocity;
-
- /* establish note age for voice stealing */
- pVoiceMgr->voices[voiceNum].age = pVoiceMgr->age++;
-
- /* setup the synthesis parameters */
- pVoiceMgr->voices[voiceNum].voiceState = eVoiceStateStart;
-
- /* increment voice pool count */
- IncVoicePoolCount(pVoiceMgr, pVoice);
-
- /* start voice on correct synth */
- /*lint -e{522} return not used at this time */
- GetSynthPtr(voiceNum)->pfStartVoice(pVoiceMgr, pSynth, &pVoiceMgr->voices[voiceNum], GetAdjustedVoiceNum(voiceNum), regionIndex);
- return;
- }
-
- /* no free voices, we have to steal one using appropriate algorithm */
- if (VMStealVoice(pVoiceMgr, pSynth, &voiceNum, channel, note, lowVoice, highVoice) == EAS_SUCCESS)
- VMStolenVoice(pVoiceMgr, pSynth, voiceNum, channel, note, velocity, regionIndex);
-
-#ifdef _DEBUG_VM
- else
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMStartVoice: Could not steal a voice for channel %d note %d velocity %d\n",
- channel, note, velocity); */ }
- }
-#endif
-
- return;
-}
-
-/*----------------------------------------------------------------------------
- * VMStartNote()
- *----------------------------------------------------------------------------
- * Purpose:
- * Update the synth's state to play the requested note on the requested
- * channel if possible.
- *
- * Inputs:
- * nChannel - the channel to start a note on
- * nKeyNumber - the key number to start a note for
- * nNoteVelocity - the key velocity from this note
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- * Side Effects:
- * psSynthObject->m_nNumActiveVoices may be incremented
- * psSynthObject->m_sVoice[free voice num].m_nSynthChannel may be assigned
- * psSynthObject->m_sVoice[free voice num].m_nKeyNumber is assigned
- * psSynthObject->m_sVoice[free voice num].m_nVelocity is assigned
- *----------------------------------------------------------------------------
-*/
-void VMStartNote (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel, EAS_U8 note, EAS_U8 velocity)
-{
- S_SYNTH_CHANNEL *pChannel;
- EAS_U16 regionIndex;
- EAS_I16 adjustedNote;
-
- /* bump note count */
- pSynth->totalNoteCount++;
-
- pChannel = &pSynth->channels[channel];
-
- /* check channel mute */
- if (pChannel->channelFlags & CHANNEL_FLAG_MUTE)
- return;
-
-#ifdef EXTERNAL_AUDIO
- /* pass event to external audio when requested */
- if ((pChannel->channelFlags & CHANNEL_FLAG_EXTERNAL_AUDIO) && (pSynth->cbEventFunc != NULL))
- {
- S_EXT_AUDIO_EVENT event;
- event.channel = channel;
- event.note = note;
- event.velocity = velocity;
- event.noteOn = EAS_TRUE;
- if (pSynth->cbEventFunc(pSynth->pExtAudioInstData, &event))
- return;
- }
-#endif
-
- /* start search at first region */
- regionIndex = pChannel->regionIndex;
-
- /* handle transposition */
- adjustedNote = note;
- if (pChannel->channelFlags & CHANNEL_FLAG_RHYTHM_CHANNEL)
- adjustedNote += pChannel->coarsePitch;
- else
- adjustedNote += pChannel->coarsePitch + pSynth->globalTranspose;
-
- /* limit adjusted key number so it does not wraparound, over/underflow */
- if (adjustedNote < 0)
- {
- adjustedNote = 0;
- }
- else if (adjustedNote > 127)
- {
- adjustedNote = 127;
- }
-
-#if defined(DLS_SYNTHESIZER)
- if (regionIndex & FLAG_RGN_IDX_DLS_SYNTH)
- {
- /* DLS voice */
- for (;;)
- {
- /*lint -e{740,826} cast OK, we know this is actually a DLS region */
- const S_DLS_REGION *pDLSRegion = (S_DLS_REGION*) GetRegionPtr(pSynth, regionIndex);
-
- /* check key against this region's key and velocity range */
- if (((adjustedNote >= pDLSRegion->wtRegion.region.rangeLow) && (adjustedNote <= pDLSRegion->wtRegion.region.rangeHigh)) &&
- ((velocity >= pDLSRegion->velLow) && (velocity <= pDLSRegion->velHigh)))
- {
- VMStartVoice(pVoiceMgr, pSynth, channel, note, velocity, regionIndex);
- }
-
- /* last region in program? */
- if (pDLSRegion->wtRegion.region.keyGroupAndFlags & REGION_FLAG_LAST_REGION)
- break;
-
- /* advance to next region */
- regionIndex++;
- }
- }
- else
-#endif
-
- /* braces here for #if clause */
- {
- /* EAS voice */
- for (;;)
- {
- const S_REGION *pRegion = GetRegionPtr(pSynth, regionIndex);
-
- /* check key against this region's keyrange */
- if ((adjustedNote >= pRegion->rangeLow) && (adjustedNote <= pRegion->rangeHigh))
- {
- VMStartVoice(pVoiceMgr, pSynth, channel, note, velocity, regionIndex);
- break;
- }
-
- /* last region in program? */
- if (pRegion->keyGroupAndFlags & REGION_FLAG_LAST_REGION)
- break;
-
- /* advance to next region */
- regionIndex++;
- }
- }
-}
-
-/*----------------------------------------------------------------------------
- * VMStopNote()
- *----------------------------------------------------------------------------
- * Purpose:
- * Update the synth's state to end the requested note on the requested
- * channel.
- *
- * Inputs:
- * nChannel - the channel to stop a note on
- * nKeyNumber - the key number for this note off
- * nNoteVelocity - the note-off velocity
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- * Side Effects:
- * psSynthObject->m_sVoice[free voice num].m_nSynthChannel may be assigned
- * psSynthObject->m_sVoice[free voice num].m_nKeyNumber is assigned
- * psSynthObject->m_sVoice[free voice num].m_nVelocity is assigned
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, velocity) reserved for future use */
-void VMStopNote (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel, EAS_U8 note, EAS_U8 velocity)
-{
- S_SYNTH_CHANNEL *pChannel;
- EAS_INT voiceNum;
-
- pChannel = &(pSynth->channels[channel]);
-
-#ifdef EXTERNAL_AUDIO
- if ((pChannel->channelFlags & CHANNEL_FLAG_EXTERNAL_AUDIO) && (pSynth->cbEventFunc != NULL))
- {
- S_EXT_AUDIO_EVENT event;
- event.channel = channel;
- event.note = note;
- event.velocity = velocity;
- event.noteOn = EAS_FALSE;
- if (pSynth->cbEventFunc(pSynth->pExtAudioInstData, &event))
- return;
- }
-#endif
-
- /* keep track of the note-start workload */
- pVoiceMgr->workload += WORKLOAD_AMOUNT_STOP_NOTE;
-
- channel = VSynthToChannel(pSynth, channel);
-
- for (voiceNum=0; voiceNum < MAX_SYNTH_VOICES; voiceNum++)
- {
-
- /* stolen notes are handled separately */
- if (eVoiceStateStolen != pVoiceMgr->voices[voiceNum].voiceState)
- {
-
- /* channel and key number must match */
- if ((channel == pVoiceMgr->voices[voiceNum].channel) && (note == pVoiceMgr->voices[voiceNum].note))
- {
-#ifdef _DEBUG_VM
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMStopNote: voice %d channel %d note %d\n",
- voiceNum, channel, note); */ }
-#endif
-
- /* if sustain pedal is down, set deferred note-off flag */
- if (pChannel->channelFlags & CHANNEL_FLAG_SUSTAIN_PEDAL)
- {
- pVoiceMgr->voices[voiceNum].voiceFlags |= VOICE_FLAG_SUSTAIN_PEDAL_DEFER_NOTE_OFF;
- continue;
- }
-
- /* if this note just started, wait before we stop it */
- if (pVoiceMgr->voices[voiceNum].voiceFlags & VOICE_FLAG_NO_SAMPLES_SYNTHESIZED_YET)
- {
-#ifdef _DEBUG_VM
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "\tDeferred: Not started yet\n"); */ }
-#endif
- pVoiceMgr->voices[voiceNum].voiceFlags |= VOICE_FLAG_DEFER_MIDI_NOTE_OFF;
- pSynth->synthFlags |= SYNTH_FLAG_DEFERRED_MIDI_NOTE_OFF_PENDING;
- }
-
- /* release voice */
- else
- VMReleaseVoice(pVoiceMgr, pSynth, voiceNum);
-
- }
- }
-
- /* process stolen notes, new channel and key number must match */
- else if ((channel == pVoiceMgr->voices[voiceNum].nextChannel) && (note == pVoiceMgr->voices[voiceNum].nextNote))
- {
-
-#ifdef _DEBUG_VM
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMStopNote: voice %d channel %d note %d\n\tDeferred: Stolen voice\n",
- voiceNum, channel, note); */ }
-#endif
- pVoiceMgr->voices[voiceNum].voiceFlags |= VOICE_FLAG_DEFER_MIDI_NOTE_OFF;
- }
- }
-}
-
-/*----------------------------------------------------------------------------
- * VMFindAvailableVoice()
- *----------------------------------------------------------------------------
- * Purpose:
- * Find an available voice and return the voice number if available.
- *
- * Inputs:
- * pnVoiceNumber - really an output, returns the voice number found
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- * success - if there is an available voice
- * failure - otherwise
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT VMFindAvailableVoice (S_VOICE_MGR *pVoiceMgr, EAS_INT *pVoiceNumber, EAS_I32 lowVoice, EAS_I32 highVoice)
-{
- EAS_INT voiceNum;
-
- /* Check each voice to see if it has been assigned to a synth channel */
- for (voiceNum = lowVoice; voiceNum <= highVoice; voiceNum++)
- {
- /* check if this voice has been assigned to a synth channel */
- if ( pVoiceMgr->voices[voiceNum].voiceState == eVoiceStateFree)
- {
- *pVoiceNumber = voiceNum; /* this voice is available */
- return EAS_SUCCESS;
- }
- }
-
- /* if we reach here, we have not found a free voice */
- *pVoiceNumber = UNASSIGNED_SYNTH_VOICE;
-
-#ifdef _DEBUG_VM
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMFindAvailableVoice: error, could not find an available voice\n"); */ }
-#endif
- return EAS_FAILURE;
-}
-
-/*----------------------------------------------------------------------------
- * VMStealVoice()
- *----------------------------------------------------------------------------
- * Purpose:
- * Steal a voice and return the voice number
- *
- * Stealing algorithm: steal the best choice with minimal work, taking into
- * account SP-Midi channel priorities and polyphony allocation.
- *
- * In one pass through all the voices, figure out which voice to steal
- * taking into account a number of different factors:
- * Priority of the voice's MIDI channel
- * Number of voices over the polyphony allocation for voice's MIDI channel
- * Amplitude of the voice
- * Note age
- * Key velocity (for voices that haven't been started yet)
- * If any matching notes are found
- *
- * Inputs:
- * pnVoiceNumber - really an output, see below
- * nChannel - the channel that this voice wants to be started on
- * nKeyNumber - the key number for this new voice
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- * pnVoiceNumber - voice number of the voice that was stolen
- * EAS_RESULT EAS_SUCCESS - always successful
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT VMStealVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_INT *pVoiceNumber, EAS_U8 channel, EAS_U8 note, EAS_I32 lowVoice, EAS_I32 highVoice)
-{
- S_SYNTH_VOICE *pCurrVoice;
- S_SYNTH *pCurrSynth;
- EAS_INT voiceNum;
- EAS_INT bestCandidate;
- EAS_U8 currChannel;
- EAS_U8 currNote;
- EAS_I32 bestPriority;
- EAS_I32 currentPriority;
-
- /* determine which voice to steal */
- bestPriority = 0;
- bestCandidate = MAX_SYNTH_VOICES;
-
- for (voiceNum = lowVoice; voiceNum <= highVoice; voiceNum++)
- {
- pCurrVoice = &pVoiceMgr->voices[voiceNum];
-
- /* ignore free voices */
- if (pCurrVoice->voiceState == eVoiceStateFree)
- continue;
-
- /* for stolen voices, use the new parameters, not the old */
- if (pCurrVoice->voiceState == eVoiceStateStolen)
- {
- pCurrSynth = pVoiceMgr->pSynth[GET_VSYNTH(pCurrVoice->nextChannel)];
- currChannel = pCurrVoice->nextChannel;
- currNote = pCurrVoice->nextNote;
- }
- else
- {
- pCurrSynth = pVoiceMgr->pSynth[GET_VSYNTH(pCurrVoice->channel)];
- currChannel = pCurrVoice->channel;
- currNote = pCurrVoice->note;
- }
-
- /* ignore voices that are higher priority */
- if (pSynth->priority > pCurrSynth->priority)
- continue;
-#ifdef _DEBUG_VM
-// { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMStealVoice: New priority = %d exceeds old priority = %d\n", pSynth->priority, pCurrSynth->priority); */ }
-#endif
-
- /* if voice is stolen or just started, reduce the likelihood it will be stolen */
- if (( pCurrVoice->voiceState == eVoiceStateStolen) || (pCurrVoice->voiceFlags & VOICE_FLAG_NO_SAMPLES_SYNTHESIZED_YET))
- {
- currentPriority = 128 - pCurrVoice->nextVelocity;
- }
- else
- {
- /* compute the priority of this voice, higher means better for stealing */
- /* use not age */
- currentPriority = (EAS_I32) pCurrVoice->age << NOTE_AGE_STEAL_WEIGHT;
-
- /* include note gain -higher gain is lower steal value */
- /*lint -e{704} use shift for performance */
- currentPriority += ((32768 >> (12 - NOTE_GAIN_STEAL_WEIGHT)) + 256) -
- ((EAS_I32) pCurrVoice->gain >> (12 - NOTE_GAIN_STEAL_WEIGHT));
- }
-
- /* in SP-MIDI mode, include over poly allocation and channel priority */
- if (pSynth->synthFlags & SYNTH_FLAG_SP_MIDI_ON)
- {
- S_SYNTH_CHANNEL *pChannel = &pCurrSynth->channels[GET_CHANNEL(currChannel)];
- /*lint -e{701} use shift for performance */
- if (pSynth->poolCount[pChannel->pool] >= pSynth->poolAlloc[pChannel->pool])
- currentPriority += (pSynth->poolCount[pChannel->pool] -pSynth->poolAlloc[pChannel->pool] + 1) << CHANNEL_POLY_STEAL_WEIGHT;
-
- /* include channel priority */
- currentPriority += (EAS_I32)(pChannel->pool << CHANNEL_PRIORITY_STEAL_WEIGHT);
- }
-
- /* if a note is already playing that matches this note, consider stealing it more readily */
- if ((note == currNote) && (channel == currChannel))
- currentPriority += NOTE_MATCH_PENALTY;
-
- /* is this the best choice so far? */
- if (currentPriority >= bestPriority)
- {
- bestPriority = currentPriority;
- bestCandidate = voiceNum;
- }
- }
-
- /* may happen if all voices are allocated to a higher priority virtual synth */
- if (bestCandidate == MAX_SYNTH_VOICES)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMStealVoice: Unable to allocate a voice\n"); */ }
- return EAS_ERROR_NO_VOICE_ALLOCATED;
- }
-
-#ifdef _DEBUG_VM
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMStealVoice: Voice %d stolen\n", bestCandidate); */ }
-
- /* are we stealing a stolen voice? */
- if (pVoiceMgr->voices[bestCandidate].voiceState == eVoiceStateStolen)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "VMStealVoice: Voice %d is already marked as stolen and was scheduled to play ch: %d note: %d vel: %d\n",
- bestCandidate,
- pVoiceMgr->voices[bestCandidate].nextChannel,
- pVoiceMgr->voices[bestCandidate].nextNote,
- pVoiceMgr->voices[bestCandidate].nextVelocity); */ }
- }
-#endif
-
- *pVoiceNumber = (EAS_U16) bestCandidate;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * VMChannelPressure()
- *----------------------------------------------------------------------------
- * Purpose:
- * Change the channel pressure for the given channel
- *
- * Inputs:
- * nChannel - the MIDI channel
- * nVelocity - the channel pressure value
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- * Side Effects:
- * psSynthObject->m_sChannel[nChannel].m_nChannelPressure is updated
- *----------------------------------------------------------------------------
-*/
-void VMChannelPressure (S_SYNTH *pSynth, EAS_U8 channel, EAS_U8 value)
-{
- S_SYNTH_CHANNEL *pChannel;
-
- pChannel = &(pSynth->channels[channel]);
- pChannel->channelPressure = value;
-
- /*
- set a channel flag to request parameter updates
- for all the voices associated with this channel
- */
- pChannel->channelFlags |= CHANNEL_FLAG_UPDATE_CHANNEL_PARAMETERS;
-}
-
-/*----------------------------------------------------------------------------
- * VMPitchBend()
- *----------------------------------------------------------------------------
- * Purpose:
- * Change the pitch wheel value for the given channel.
- * This routine constructs the proper 14-bit argument when the calling routine
- * passes the pitch LSB and MSB.
- *
- * Note: some midi disassemblers display a bipolar pitch bend value.
- * We can display the bipolar value using
- * if m_nPitchBend >= 0x2000
- * bipolar pitch bend = postive (m_nPitchBend - 0x2000)
- * else
- * bipolar pitch bend = negative (0x2000 - m_nPitchBend)
- *
- * Inputs:
- * nChannel - the MIDI channel
- * nPitchLSB - the LSB byte of the pitch bend message
- * nPitchMSB - the MSB byte of the pitch bend message
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- *
- * Side Effects:
- * psSynthObject->m_sChannel[nChannel].m_nPitchBend is changed
- *
- *----------------------------------------------------------------------------
-*/
-void VMPitchBend (S_SYNTH *pSynth, EAS_U8 channel, EAS_U8 nPitchLSB, EAS_U8 nPitchMSB)
-{
- S_SYNTH_CHANNEL *pChannel;
-
- pChannel = &(pSynth->channels[channel]);
- pChannel->pitchBend = (EAS_I16) ((nPitchMSB << 7) | nPitchLSB);
-
- /*
- set a channel flag to request parameter updates
- for all the voices associated with this channel
- */
- pChannel->channelFlags |= CHANNEL_FLAG_UPDATE_CHANNEL_PARAMETERS;
-}
-
-/*----------------------------------------------------------------------------
- * VMControlChange()
- *----------------------------------------------------------------------------
- * Purpose:
- * Change the controller (or mode) for the given channel.
- *
- * Inputs:
- * nChannel - the MIDI channel
- * nControllerNumber - the MIDI controller number
- * nControlValue - the value for this controller message
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- * Side Effects:
- * psSynthObject->m_sChannel[nChannel] controller is changed
- *
- *----------------------------------------------------------------------------
-*/
-void VMControlChange (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel, EAS_U8 controller, EAS_U8 value)
-{
- S_SYNTH_CHANNEL *pChannel;
-
- pChannel = &(pSynth->channels[channel]);
-
- /*
- set a channel flag to request parameter updates
- for all the voices associated with this channel
- */
- pChannel->channelFlags |= CHANNEL_FLAG_UPDATE_CHANNEL_PARAMETERS;
-
- switch ( controller )
- {
- case MIDI_CONTROLLER_BANK_SELECT_MSB:
-#ifdef _DEBUG_VM
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMControlChange: Bank Select MSB: msb 0x%X\n", value); */ }
-#endif
- /* use this MSB with a zero LSB, until we get an LSB message */
- pChannel->bankNum = value << 8;
- break;
-
- case MIDI_CONTROLLER_MOD_WHEEL:
- /* we treat mod wheel as a 7-bit controller and only use the MSB */
- pChannel->modWheel = value;
- break;
-
- case MIDI_CONTROLLER_VOLUME:
- /* we treat volume as a 7-bit controller and only use the MSB */
- pChannel->volume = value;
- break;
-
- case MIDI_CONTROLLER_PAN:
- /* we treat pan as a 7-bit controller and only use the MSB */
- pChannel->pan = value;
- break;
-
- case MIDI_CONTROLLER_EXPRESSION:
- /* we treat expression as a 7-bit controller and only use the MSB */
- pChannel->expression = value;
- break;
-
- case MIDI_CONTROLLER_BANK_SELECT_LSB:
-#ifdef _DEBUG_VM
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMControlChange: Bank Select LSB: lsb 0x%X\n", value); */ }
-#endif
- /*
- construct bank number as 7-bits (stored as 8) of existing MSB
- and 7-bits of new LSB (also stored as 8(
- */
- pChannel->bankNum =
- (pChannel->bankNum & 0xFF00) | value;
-
- break;
-
- case MIDI_CONTROLLER_SUSTAIN_PEDAL:
- /* we treat sustain pedal as a boolean on/off bit flag */
- if (value < 64)
- {
- /*
- we are requested to turn the pedal off, but first check
- if the pedal is already on
- */
- if (0 !=
- (pChannel->channelFlags & CHANNEL_FLAG_SUSTAIN_PEDAL)
- )
- {
- /*
- The sustain flag is presently set and the damper pedal is on.
- We are therefore transitioning from damper pedal ON to
- damper pedal OFF. This means all notes in this channel
- that received a note off while the damper pedal was on, and
- had their note-off requests deferred, should now proceed to
- the release state.
- */
- VMReleaseAllDeferredNoteOffs(pVoiceMgr, pSynth, channel);
- } /* end if sustain pedal is already on */
-
- /* turn the sustain pedal off */
- pChannel->channelFlags &= ~CHANNEL_FLAG_SUSTAIN_PEDAL;
- }
- else
- {
- /*
- we are requested to turn the pedal on, but first check
- if the pedal is already off
- */
- if (0 ==
- (pChannel->channelFlags & CHANNEL_FLAG_SUSTAIN_PEDAL)
- )
- {
- /*
- The sustain flag is presently clear and the damper pedal is off.
- We are therefore transitioning from damper pedal OFF to
- damper pedal ON. Currently sounding notes should be left
- unchanged. However, we should try to "catch" notes if possible.
- If any notes have levels >= sustain level, catch them,
- otherwise, let them continue to release.
- */
- VMCatchNotesForSustainPedal(pVoiceMgr, pSynth, channel);
- }
-
- /* turn the sustain pedal on */
- pChannel->channelFlags |= CHANNEL_FLAG_SUSTAIN_PEDAL;
- }
-
- break;
-#ifdef _REVERB
- case MIDI_CONTROLLER_REVERB_SEND:
- /* we treat send as a 7-bit controller and only use the MSB */
- pSynth->channels[channel].reverbSend = value;
- break;
-#endif
-#ifdef _CHORUS
- case MIDI_CONTROLLER_CHORUS_SEND:
- /* we treat send as a 7-bit controller and only use the MSB */
- pSynth->channels[channel].chorusSend = value;
- break;
-#endif
- case MIDI_CONTROLLER_RESET_CONTROLLERS:
- /* despite the Midi message name, not ALL controllers are reset */
- pChannel->modWheel = DEFAULT_MOD_WHEEL;
- pChannel->expression = DEFAULT_EXPRESSION;
-
- /* turn the sustain pedal off as default/reset */
- pChannel->channelFlags &= ~CHANNEL_FLAG_SUSTAIN_PEDAL;
- pChannel->pitchBend = DEFAULT_PITCH_BEND;
-
- /* reset channel pressure */
- pChannel->channelPressure = DEFAULT_CHANNEL_PRESSURE;
-
- /* reset RPN values */
- pChannel->registeredParam = DEFAULT_REGISTERED_PARAM;
- pChannel->pitchBendSensitivity = DEFAULT_PITCH_BEND_SENSITIVITY;
- pChannel->finePitch = DEFAULT_FINE_PITCH;
- pChannel->coarsePitch = DEFAULT_COARSE_PITCH;
-
- /*
- program change, bank select, channel volume CC7, pan CC10
- are NOT reset
- */
- break;
-
- /*
- For logical reasons, the RPN data entry are grouped together.
- However, keep in mind that these cases are not necessarily in
- ascending order.
- e.g., MIDI_CONTROLLER_DATA_ENTRY_MSB == 6,
- whereas MIDI_CONTROLLER_SUSTAIN_PEDAL == 64.
- So arrange these case statements in whatever manner is more efficient for
- the processor / compiler.
- */
- case MIDI_CONTROLLER_ENTER_DATA_MSB:
- case MIDI_CONTROLLER_ENTER_DATA_LSB:
- case MIDI_CONTROLLER_SELECT_RPN_LSB:
- case MIDI_CONTROLLER_SELECT_RPN_MSB:
- case MIDI_CONTROLLER_SELECT_NRPN_MSB:
- case MIDI_CONTROLLER_SELECT_NRPN_LSB:
- VMUpdateRPNStateMachine(pSynth, channel, controller, value);
- break;
-
- case MIDI_CONTROLLER_ALL_SOUND_OFF:
- case MIDI_CONTROLLER_ALL_NOTES_OFF:
- case MIDI_CONTROLLER_OMNI_OFF:
- case MIDI_CONTROLLER_OMNI_ON:
- case MIDI_CONTROLLER_MONO_ON_POLY_OFF:
- case MIDI_CONTROLLER_POLY_ON_MONO_OFF:
- /* NOTE: we treat all sounds off the same as all notes off */
- VMAllNotesOff(pVoiceMgr, pSynth, channel);
- break;
-
- default:
-#ifdef _DEBUG_VM
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMControlChange: controller %d not yet implemented\n", controller); */ }
-#endif
- break;
-
- }
-
- return;
-}
-
-/*----------------------------------------------------------------------------
- * VMUpdateRPNStateMachine()
- *----------------------------------------------------------------------------
- * Purpose:
- * Call this function when we want to parse RPN related controller messages.
- * We only support RPN0 (pitch bend sensitivity), RPN1 (fine tuning) and
- * RPN2 (coarse tuning). Any other RPNs or NRPNs are ignored for now.
- *.
- * Supports any order, so not a state machine anymore. This function was
- * rewritten to work correctly regardless of order.
- *
- * Inputs:
- * nChannel - the channel this controller message is coming from
- * nControllerNumber - which RPN related controller
- * nControlValue - the value of the RPN related controller
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- * returns EAS_RESULT, which is typically EAS_SUCCESS, since there are
- * few possible errors
- *
- * Side Effects:
- * gsSynthObject.m_sChannel[nChannel].m_nPitchBendSensitivity
- * (or m_nFinePitch or m_nCoarsePitch)
- * will be updated if the proper RPN message is received.
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT VMUpdateRPNStateMachine (S_SYNTH *pSynth, EAS_U8 channel, EAS_U8 controller, EAS_U8 value)
-{
- S_SYNTH_CHANNEL *pChannel;
-
-#ifdef _DEBUG_VM
- if (channel >= NUM_SYNTH_CHANNELS)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMUpdateRPNStateMachines: error, %d invalid channel number\n",
- channel); */ }
- return EAS_FAILURE;
- }
-#endif
-
- pChannel = &(pSynth->channels[channel]);
-
- switch (controller)
- {
- case MIDI_CONTROLLER_SELECT_NRPN_MSB:
- case MIDI_CONTROLLER_SELECT_NRPN_LSB:
- pChannel->registeredParam = DEFAULT_REGISTERED_PARAM;
- break;
- case MIDI_CONTROLLER_SELECT_RPN_MSB:
- pChannel->registeredParam =
- (pChannel->registeredParam & 0x7F) | (value<<7);
- break;
- case MIDI_CONTROLLER_SELECT_RPN_LSB:
- pChannel->registeredParam =
- (pChannel->registeredParam & 0x7F00) | value;
- break;
- case MIDI_CONTROLLER_ENTER_DATA_MSB:
- switch (pChannel->registeredParam)
- {
- case 0:
- pChannel->pitchBendSensitivity = value * 100;
- break;
- case 1:
- /*lint -e{702} <avoid division for performance reasons>*/
- pChannel->finePitch = (EAS_I8)((((value << 7) - 8192) * 100) >> 13);
- break;
- case 2:
- pChannel->coarsePitch = (EAS_I8)(value - 64);
- break;
- default:
- break;
- }
- break;
- case MIDI_CONTROLLER_ENTER_DATA_LSB:
- switch (pChannel->registeredParam)
- {
- case 0:
- //ignore lsb
- break;
- case 1:
- //ignore lsb
- break;
- case 2:
- //ignore lsb
- break;
- default:
- break;
- }
- break;
- default:
- return EAS_FAILURE; //not a RPN related controller
- }
-
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * VMUpdateStaticChannelParameters()
- *----------------------------------------------------------------------------
- * Purpose:
- * Update all of the static channel parameters for channels that have had
- * a controller change values
- * Or if the synth has signalled that all channels must forcibly
- * be updated
- *
- * Inputs:
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- * none
- *
- * Side Effects:
- * - psSynthObject->m_sChannel[].m_nStaticGain and m_nStaticPitch
- * are updated for channels whose controller values have changed
- * or if the synth has signalled that all channels must forcibly
- * be updated
- *----------------------------------------------------------------------------
-*/
-void VMUpdateStaticChannelParameters (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth)
-{
- EAS_INT channel;
-
- if (pSynth->synthFlags & SYNTH_FLAG_UPDATE_ALL_CHANNEL_PARAMETERS)
- {
- /*
- the synth wants us to forcibly update all channel
- parameters. This event occurs when we are about to
- finish resetting the synth
- */
- for (channel = 0; channel < NUM_SYNTH_CHANNELS; channel++)
- {
-#ifdef _HYBRID_SYNTH
- if (pSynth->channels[channel].regionIndex & FLAG_RGN_IDX_FM_SYNTH)
- pSecondarySynth->pfUpdateChannel(pVoiceMgr, pSynth, (EAS_U8) channel);
- else
- pPrimarySynth->pfUpdateChannel(pVoiceMgr, pSynth, (EAS_U8) channel);
-#else
- pPrimarySynth->pfUpdateChannel(pVoiceMgr, pSynth, (EAS_U8) channel);
-#endif
- }
-
- /*
- clear the flag to indicates we have now forcibly
- updated all channel parameters
- */
- pSynth->synthFlags &= ~SYNTH_FLAG_UPDATE_ALL_CHANNEL_PARAMETERS;
- }
- else
- {
-
- /* only update channel params if signalled by a channel flag */
- for (channel = 0; channel < NUM_SYNTH_CHANNELS; channel++)
- {
- if ( 0 != (pSynth->channels[channel].channelFlags & CHANNEL_FLAG_UPDATE_CHANNEL_PARAMETERS))
- {
-#ifdef _HYBRID_SYNTH
- if (pSynth->channels[channel].regionIndex & FLAG_RGN_IDX_FM_SYNTH)
- pSecondarySynth->pfUpdateChannel(pVoiceMgr, pSynth, (EAS_U8) channel);
- else
- pPrimarySynth->pfUpdateChannel(pVoiceMgr, pSynth, (EAS_U8) channel);
-#else
- pPrimarySynth->pfUpdateChannel(pVoiceMgr, pSynth, (EAS_U8) channel);
-#endif
- }
- }
-
- }
-
- return;
-}
-
-/*----------------------------------------------------------------------------
- * VMFindProgram()
- *----------------------------------------------------------------------------
- * Purpose:
- * Look up an individual program in sound library. This function
- * searches the bank list for a program, then the individual program
- * list.
- *
- * Inputs:
- *
- * Outputs:
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT VMFindProgram (const S_EAS *pEAS, EAS_U32 bank, EAS_U8 programNum, EAS_U16 *pRegionIndex)
-{
- EAS_U32 locale;
- const S_PROGRAM *p;
- EAS_U16 i;
- EAS_U16 regionIndex;
-
- /* make sure we have a valid sound library */
- if (pEAS == NULL)
- return EAS_FAILURE;
-
- /* search the banks */
- for (i = 0; i < pEAS->numBanks; i++)
- {
- if (bank == (EAS_U32) pEAS->pBanks[i].locale)
- {
- regionIndex = pEAS->pBanks[i].regionIndex[programNum];
- if (regionIndex != INVALID_REGION_INDEX)
- {
- *pRegionIndex = regionIndex;
- return EAS_SUCCESS;
- }
- break;
- }
- }
-
- /* establish locale */
- locale = ( bank << 8) | programNum;
-
- /* search for program */
- for (i = 0, p = pEAS->pPrograms; i < pEAS->numPrograms; i++, p++)
- {
- if (p->locale == locale)
- {
- *pRegionIndex = p->regionIndex;
- return EAS_SUCCESS;
- }
- }
-
- return EAS_FAILURE;
-}
-
-#ifdef DLS_SYNTHESIZER
-/*----------------------------------------------------------------------------
- * VMFindDLSProgram()
- *----------------------------------------------------------------------------
- * Purpose:
- * Look up an individual program in sound library. This function
- * searches the bank list for a program, then the individual program
- * list.
- *
- * Inputs:
- *
- * Outputs:
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT VMFindDLSProgram (const S_DLS *pDLS, EAS_U32 bank, EAS_U8 programNum, EAS_U16 *pRegionIndex)
-{
- EAS_U32 locale;
- const S_PROGRAM *p;
- EAS_U16 i;
-
- /* make sure we have a valid sound library */
- if (pDLS == NULL)
- return EAS_FAILURE;
-
- /* establish locale */
- locale = (bank << 8) | programNum;
-
- /* search for program */
- for (i = 0, p = pDLS->pDLSPrograms; i < pDLS->numDLSPrograms; i++, p++)
- {
- if (p->locale == locale)
- {
- *pRegionIndex = p->regionIndex;
- return EAS_SUCCESS;
- }
- }
-
- return EAS_FAILURE;
-}
-#endif
-
-/*----------------------------------------------------------------------------
- * VMProgramChange()
- *----------------------------------------------------------------------------
- * Purpose:
- * Change the instrument (program) for the given channel.
- *
- * Depending on the program number, and the bank selected for this channel, the
- * program may be in ROM, RAM (from SMAF or CMX related RAM wavetable), or
- * Alternate wavetable (from mobile DLS or other DLS file)
- *
- * This function figures out what wavetable should be used, and sets it up as the
- * wavetable to use for this channel. Also the channel may switch from a melodic
- * channel to a rhythm channel, or vice versa.
- *
- * Inputs:
- *
- * Outputs:
- * Side Effects:
- * gsSynthObject.m_sChannel[nChannel].m_nProgramNumber is likely changed
- * gsSynthObject.m_sChannel[nChannel].m_psEAS may be changed
- * gsSynthObject.m_sChannel[nChannel].m_bRhythmChannel may be changed
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, pVoiceMgr) reserved for future use */
-void VMProgramChange (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel, EAS_U8 program)
-{
- S_SYNTH_CHANNEL *pChannel;
- EAS_U32 bank;
- EAS_U16 regionIndex;
-
-#ifdef _DEBUG_VM
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "VMProgramChange: vSynthNum=%d, channel=%d, program=%d\n", pSynth->vSynthNum, channel, program); */ }
-#endif
-
- /* setup pointer to MIDI channel data */
- pChannel = &pSynth->channels[channel];
- bank = pChannel->bankNum;
-
- /* allow channels to switch between being melodic or rhythm channels, using GM2 CC values */
- if ((bank & 0xFF00) == DEFAULT_RHYTHM_BANK_NUMBER)
- {
- /* make it a rhythm channel */
- pChannel->channelFlags |= CHANNEL_FLAG_RHYTHM_CHANNEL;
- }
- else if ((bank & 0xFF00) == DEFAULT_MELODY_BANK_NUMBER)
- {
- /* make it a melody channel */
- pChannel->channelFlags &= ~CHANNEL_FLAG_RHYTHM_CHANNEL;
- }
-
- regionIndex = DEFAULT_REGION_INDEX;
-
-#ifdef EXTERNAL_AUDIO
- /* give the external audio interface a chance to handle it */
- if (pSynth->cbProgChgFunc != NULL)
- {
- S_EXT_AUDIO_PRG_CHG prgChg;
- prgChg.channel = channel;
- prgChg.bank = (EAS_U16) bank;
- prgChg.program = program;
- if (pSynth->cbProgChgFunc(pSynth->pExtAudioInstData, &prgChg))
- pChannel->channelFlags |= CHANNEL_FLAG_EXTERNAL_AUDIO;
- }
-
-#endif
-
-
-#ifdef DLS_SYNTHESIZER
- /* first check for DLS program that may overlay the internal instrument */
- if (VMFindDLSProgram(pSynth->pDLS, bank, program, &regionIndex) != EAS_SUCCESS)
-#endif
-
- /* braces to support 'if' clause above */
- {
-
- /* look in the internal banks */
- if (VMFindProgram(pSynth->pEAS, bank, program, &regionIndex) != EAS_SUCCESS)
-
- /* fall back to default bank */
- {
- if (pSynth->channels[channel].channelFlags & CHANNEL_FLAG_RHYTHM_CHANNEL)
- bank = DEFAULT_RHYTHM_BANK_NUMBER;
- else
- bank = DEFAULT_MELODY_BANK_NUMBER;
-
- if (VMFindProgram(pSynth->pEAS, bank, program, &regionIndex) != EAS_SUCCESS)
-
- /* switch to program 0 in the default bank */
- {
- if (VMFindProgram(pSynth->pEAS, bank, 0, &regionIndex) != EAS_SUCCESS)
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "VMProgramChange: No program @ %03d:%03d:%03d\n",
- (bank >> 8) & 0x7f, bank & 0x7f, program); */ }
- }
- }
- }
-
- /* we have our new program change for this channel */
- pChannel->programNum = program;
- pChannel->regionIndex = regionIndex;
-
- /*
- set a channel flag to request parameter updates
- for all the voices associated with this channel
- */
- pChannel->channelFlags |= CHANNEL_FLAG_UPDATE_CHANNEL_PARAMETERS;
-
- return;
-}
-
-/*----------------------------------------------------------------------------
- * VMAddSamples()
- *----------------------------------------------------------------------------
- * Purpose:
- * Synthesize the requested number of samples (block based processing)
- *
- * Inputs:
- * nNumSamplesToAdd - number of samples to write to buffer
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- * number of voices rendered
- *
- * Side Effects:
- * - samples are added to the presently free buffer
- *
- *----------------------------------------------------------------------------
-*/
-EAS_I32 VMAddSamples (S_VOICE_MGR *pVoiceMgr, EAS_I32 *pMixBuffer, EAS_I32 numSamples)
-{
- S_SYNTH *pSynth;
- EAS_INT voicesRendered;
- EAS_INT voiceNum;
- EAS_BOOL done;
-
-#ifdef _REVERB
- EAS_PCM *pReverbSendBuffer;
-#endif // ifdef _REVERB
-
-#ifdef _CHORUS
- EAS_PCM *pChorusSendBuffer;
-#endif // ifdef _CHORUS
-
- voicesRendered = 0;
- for (voiceNum = 0; voiceNum < MAX_SYNTH_VOICES; voiceNum++)
- {
-
- /* retarget stolen voices */
- if ((pVoiceMgr->voices[voiceNum].voiceState == eVoiceStateStolen) && (pVoiceMgr->voices[voiceNum].gain <= 0))
- VMRetargetStolenVoice(pVoiceMgr, voiceNum);
-
- /* get pointer to virtual synth */
- pSynth = pVoiceMgr->pSynth[pVoiceMgr->voices[voiceNum].channel >> 4];
-
- /* synthesize active voices */
- if (pVoiceMgr->voices[voiceNum].voiceState != eVoiceStateFree)
- {
- done = GetSynthPtr(voiceNum)->pfUpdateVoice(pVoiceMgr, pSynth, &pVoiceMgr->voices[voiceNum], GetAdjustedVoiceNum(voiceNum), pMixBuffer, numSamples);
- voicesRendered++;
-
- /* voice is finished */
- if (done == EAS_TRUE)
- {
- /* set gain of stolen voice to zero so it will be restarted */
- if (pVoiceMgr->voices[voiceNum].voiceState == eVoiceStateStolen)
- pVoiceMgr->voices[voiceNum].gain = 0;
-
- /* or return it to the free voice pool */
- else
- VMFreeVoice(pVoiceMgr, pSynth, &pVoiceMgr->voices[voiceNum]);
- }
-
- /* if this voice is scheduled to be muted, set the mute flag */
- if (pVoiceMgr->voices[voiceNum].voiceFlags & VOICE_FLAG_DEFER_MUTE)
- {
- pVoiceMgr->voices[voiceNum].voiceFlags &= ~(VOICE_FLAG_DEFER_MUTE | VOICE_FLAG_DEFER_MIDI_NOTE_OFF);
- VMMuteVoice(pVoiceMgr, voiceNum);
- }
-
- /* if voice just started, advance state to play */
- if (pVoiceMgr->voices[voiceNum].voiceState == eVoiceStateStart)
- pVoiceMgr->voices[voiceNum].voiceState = eVoiceStatePlay;
- }
- }
-
- return voicesRendered;
-}
-
-/*----------------------------------------------------------------------------
- * VMRender()
- *----------------------------------------------------------------------------
- * Purpose:
- * This routine renders a frame of audio
- *
- * Inputs:
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- * pVoicesRendered - number of voices rendered this frame
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT VMRender (S_VOICE_MGR *pVoiceMgr, EAS_I32 numSamples, EAS_I32 *pMixBuffer, EAS_I32 *pVoicesRendered)
-{
- S_SYNTH *pSynth;
- EAS_INT i;
- EAS_INT channel;
-
-#ifdef _CHECKED_BUILD
- SanityCheck(pVoiceMgr);
-#endif
-
- /* update MIDI channel parameters */
- *pVoicesRendered = 0;
- for (i = 0; i < MAX_VIRTUAL_SYNTHESIZERS; i++)
- {
- if (pVoiceMgr->pSynth[i] != NULL)
- VMUpdateStaticChannelParameters(pVoiceMgr, pVoiceMgr->pSynth[i]);
- }
-
- /* synthesize a buffer of audio */
- *pVoicesRendered = VMAddSamples(pVoiceMgr, pMixBuffer, numSamples);
-
- /*
- * check for deferred note-off messages
- * If flag is set, that means one or more voices are expecting deferred
- * midi note-off messages because the midi note-on and corresponding midi
- * note-off requests occurred during the same update interval. The goal
- * is the defer the note-off request so that the note can at least start.
- */
- for (i = 0; i < MAX_VIRTUAL_SYNTHESIZERS; i++)
- {
- pSynth = pVoiceMgr->pSynth[i];
-
- if (pSynth== NULL)
- continue;
-
- if (pSynth->synthFlags & SYNTH_FLAG_DEFERRED_MIDI_NOTE_OFF_PENDING)
- VMDeferredStopNote(pVoiceMgr, pSynth);
-
- /* check if we need to reset the synth */
- if ((pSynth->synthFlags & SYNTH_FLAG_RESET_IS_REQUESTED) &&
- (pSynth->numActiveVoices == 0))
- {
- /*
- complete the process of resetting the synth now that
- all voices have muted
- */
-#ifdef _DEBUG_VM
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMAddSamples: complete the reset process\n"); */ }
-#endif
-
- VMInitializeAllChannels(pVoiceMgr, pSynth);
- VMInitializeAllVoices(pVoiceMgr, pSynth->vSynthNum);
-
- /* clear the reset flag */
- pSynth->synthFlags &= ~SYNTH_FLAG_RESET_IS_REQUESTED;
- }
-
- /* clear channel update flags */
- for (channel = 0; channel < NUM_SYNTH_CHANNELS; channel++)
- pSynth->channels[channel].channelFlags &= ~CHANNEL_FLAG_UPDATE_CHANNEL_PARAMETERS;
-
- }
-
-#ifdef _CHECKED_BUILD
- SanityCheck(pVoiceMgr);
-#endif
-
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * VMInitWorkload()
- *----------------------------------------------------------------------------
- * Purpose:
- * Clears the workload counter
- *
- * Inputs:
- * pVoiceMgr - pointer to instance data
- *
- * Outputs:
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-void VMInitWorkload (S_VOICE_MGR *pVoiceMgr)
-{
- pVoiceMgr->workload = 0;
-}
-
-/*----------------------------------------------------------------------------
- * VMSetWorkload()
- *----------------------------------------------------------------------------
- * Purpose:
- * Sets the max workload for a single frame.
- *
- * Inputs:
- * pVoiceMgr - pointer to instance data
- *
- * Outputs:
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-void VMSetWorkload (S_VOICE_MGR *pVoiceMgr, EAS_I32 maxWorkLoad)
-{
- pVoiceMgr->maxWorkLoad = maxWorkLoad;
-}
-
-/*----------------------------------------------------------------------------
- * VMCheckWorkload()
- *----------------------------------------------------------------------------
- * Purpose:
- * Checks to see if work load has been exceeded on this frame.
- *
- * Inputs:
- * pVoiceMgr - pointer to instance data
- *
- * Outputs:
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_BOOL VMCheckWorkload (S_VOICE_MGR *pVoiceMgr)
-{
- if (pVoiceMgr->maxWorkLoad > 0)
- return (EAS_BOOL) (pVoiceMgr->workload >= pVoiceMgr->maxWorkLoad);
- return EAS_FALSE;
-}
-
-/*----------------------------------------------------------------------------
- * VMActiveVoices()
- *----------------------------------------------------------------------------
- * Purpose:
- * Returns the number of active voices in the synthesizer.
- *
- * Inputs:
- * pEASData - pointer to instance data
- *
- * Outputs:
- * Returns the number of active voices
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_I32 VMActiveVoices (S_SYNTH *pSynth)
-{
- return pSynth->numActiveVoices;
-}
-
-/*----------------------------------------------------------------------------
- * VMSetSynthPolyphony()
- *----------------------------------------------------------------------------
- * Purpose:
- * Set the synth to a new polyphony value. Value must be >= 1 and
- * <= MAX_SYNTH_VOICES. This function will pin the polyphony at those limits
- *
- * Inputs:
- * pVoiceMgr pointer to synthesizer data
- * polyphonyCount desired polyphony count
- * synth synthesizer number (0 = onboard, 1 = DSP)
- *
- * Outputs:
- * Returns error code
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT VMSetSynthPolyphony (S_VOICE_MGR *pVoiceMgr, EAS_I32 synth, EAS_I32 polyphonyCount)
-{
- EAS_INT i;
- EAS_INT activeVoices;
-
- /* lower limit */
- if (polyphonyCount < 1)
- polyphonyCount = 1;
-
- /* split architecture */
-#if defined(_SECONDARY_SYNTH) || defined(EAS_SPLIT_WT_SYNTH)
- if (synth == EAS_MCU_SYNTH)
- {
- if (polyphonyCount > NUM_PRIMARY_VOICES)
- polyphonyCount = NUM_PRIMARY_VOICES;
- if (pVoiceMgr->maxPolyphonyPrimary == polyphonyCount)
- return EAS_SUCCESS;
- pVoiceMgr->maxPolyphonyPrimary = (EAS_U16) polyphonyCount;
- }
- else if (synth == EAS_DSP_SYNTH)
- {
- if (polyphonyCount > NUM_SECONDARY_VOICES)
- polyphonyCount = NUM_SECONDARY_VOICES;
- if (pVoiceMgr->maxPolyphonySecondary == polyphonyCount)
- return EAS_SUCCESS;
- pVoiceMgr->maxPolyphonySecondary = (EAS_U16) polyphonyCount;
- }
- else
- return EAS_ERROR_PARAMETER_RANGE;
-
- /* setting for SP-MIDI */
- pVoiceMgr->maxPolyphony = pVoiceMgr->maxPolyphonyPrimary + pVoiceMgr->maxPolyphonySecondary;
-
- /* standard architecture */
-#else
- if (synth != EAS_MCU_SYNTH)
- return EAS_ERROR_PARAMETER_RANGE;
-
- /* pin desired value to possible limits */
- if (polyphonyCount > MAX_SYNTH_VOICES)
- polyphonyCount = MAX_SYNTH_VOICES;
-
- /* set polyphony, if value is different than current value */
- if (pVoiceMgr->maxPolyphony == polyphonyCount)
- return EAS_SUCCESS;
-
- pVoiceMgr->maxPolyphony = (EAS_U16) polyphonyCount;
-#endif
-
- /* if SPMIDI enabled, update channel masking based on new polyphony */
- for (i = 0; i < MAX_VIRTUAL_SYNTHESIZERS; i++)
- {
- if (pVoiceMgr->pSynth[i])
- {
- if (pVoiceMgr->pSynth[i]->synthFlags & SYNTH_FLAG_SP_MIDI_ON)
- VMMIPUpdateChannelMuting(pVoiceMgr, pVoiceMgr->pSynth[i]);
- else
- pVoiceMgr->pSynth[i]->poolAlloc[0] = (EAS_U8) polyphonyCount;
- }
- }
-
- /* are we under polyphony limit? */
- if (pVoiceMgr->activeVoices <= polyphonyCount)
- return EAS_SUCCESS;
-
- /* count the number of active voices */
- activeVoices = 0;
- for (i = 0; i < MAX_SYNTH_VOICES; i++)
- {
-
- /* is voice active? */
- if ((pVoiceMgr->voices[i].voiceState != eVoiceStateFree) && (pVoiceMgr->voices[i].voiceState != eVoiceStateMuting))
- activeVoices++;
- }
-
- /* we may have to mute voices to reach new target */
- while (activeVoices > polyphonyCount)
- {
- S_SYNTH *pSynth;
- S_SYNTH_VOICE *pVoice;
- EAS_I32 currentPriority, bestPriority;
- EAS_INT bestCandidate;
-
- /* find the lowest priority voice */
- bestPriority = bestCandidate = -1;
- for (i = 0; i < MAX_SYNTH_VOICES; i++)
- {
-
- pVoice = &pVoiceMgr->voices[i];
-
- /* ignore free and muting voices */
- if ((pVoice->voiceState == eVoiceStateFree) || (pVoice->voiceState == eVoiceStateMuting))
- continue;
-
- pSynth = pVoiceMgr->pSynth[GET_VSYNTH(pVoice->channel)];
-
- /* if voice is stolen or just started, reduce the likelihood it will be stolen */
- if (( pVoice->voiceState == eVoiceStateStolen) || (pVoice->voiceFlags & VOICE_FLAG_NO_SAMPLES_SYNTHESIZED_YET))
- {
- /* include velocity */
- currentPriority = 128 - pVoice->nextVelocity;
-
- /* include channel priority */
- currentPriority += pSynth->channels[GET_CHANNEL(pVoice->nextChannel)].pool << CHANNEL_PRIORITY_STEAL_WEIGHT;
- }
- else
- {
- /* include age */
- currentPriority = (EAS_I32) pVoice->age << NOTE_AGE_STEAL_WEIGHT;
-
- /* include note gain -higher gain is lower steal value */
- /*lint -e{704} use shift for performance */
- currentPriority += ((32768 >> (12 - NOTE_GAIN_STEAL_WEIGHT)) + 256) -
- ((EAS_I32) pVoice->gain >> (12 - NOTE_GAIN_STEAL_WEIGHT));
-
- /* include channel priority */
- currentPriority += pSynth->channels[GET_CHANNEL(pVoice->channel)].pool << CHANNEL_PRIORITY_STEAL_WEIGHT;
- }
-
- /* include synth priority */
- currentPriority += pSynth->priority << SYNTH_PRIORITY_WEIGHT;
-
- /* is this the best choice so far? */
- if (currentPriority > bestPriority)
- {
- bestPriority = currentPriority;
- bestCandidate = i;
- }
- }
-
- /* shutdown best candidate */
- if (bestCandidate < 0)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "VMSetPolyphony: Unable to reduce polyphony\n"); */ }
- break;
- }
-
- /* shut down this voice */
- /*lint -e{771} pSynth is initialized if bestCandidate >= 0 */
- VMMuteVoice(pVoiceMgr, bestCandidate);
- activeVoices--;
- }
-
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * VMGetSynthPolyphony()
- *----------------------------------------------------------------------------
- * Purpose:
- * Returns the current polyphony setting
- *
- * Inputs:
- * pVoiceMgr pointer to synthesizer data
- * synth synthesizer number (0 = onboard, 1 = DSP)
- *
- * Outputs:
- * Returns actual polyphony value set, as pinned by limits
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT VMGetSynthPolyphony (S_VOICE_MGR *pVoiceMgr, EAS_I32 synth, EAS_I32 *pPolyphonyCount)
-{
-
-#if defined(_SECONDARY_SYNTH) || defined(EAS_SPLIT_WT_SYNTH)
- if (synth == EAS_MCU_SYNTH)
- *pPolyphonyCount = pVoiceMgr->maxPolyphonyPrimary;
- else if (synth == EAS_DSP_SYNTH)
- *pPolyphonyCount = pVoiceMgr->maxPolyphonySecondary;
- else
- return EAS_ERROR_PARAMETER_RANGE;
-#else
- if (synth != EAS_MCU_SYNTH)
- return EAS_ERROR_PARAMETER_RANGE;
- *pPolyphonyCount = pVoiceMgr->maxPolyphony;
-#endif
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * VMSetPolyphony()
- *----------------------------------------------------------------------------
- * Purpose:
- * Set the virtual synth polyphony. 0 = no limit (i.e. can use
- * all available voices).
- *
- * Inputs:
- * pVoiceMgr pointer to synthesizer data
- * polyphonyCount desired polyphony count
- * pSynth pointer to virtual synth
- *
- * Outputs:
- * Returns error code
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT VMSetPolyphony (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_I32 polyphonyCount)
-{
- EAS_INT i;
- EAS_INT activeVoices;
-
- /* check limits */
- if (polyphonyCount < 0)
- return EAS_ERROR_PARAMETER_RANGE;
-
- /* zero is max polyphony */
- if ((polyphonyCount == 0) || (polyphonyCount > MAX_SYNTH_VOICES))
- {
- pSynth->maxPolyphony = 0;
- return EAS_SUCCESS;
- }
-
- /* set new polyphony */
- pSynth->maxPolyphony = (EAS_U16) polyphonyCount;
-
- /* max polyphony is minimum of virtual synth and actual synth */
- if (polyphonyCount > pVoiceMgr->maxPolyphony)
- polyphonyCount = pVoiceMgr->maxPolyphony;
-
- /* if SP-MIDI mode, update the channel muting */
- if (pSynth->synthFlags & SYNTH_FLAG_SP_MIDI_ON)
- VMMIPUpdateChannelMuting(pVoiceMgr, pSynth);
- else
- pSynth->poolAlloc[0] = (EAS_U8) polyphonyCount;
-
- /* are we under polyphony limit? */
- if (pSynth->numActiveVoices <= polyphonyCount)
- return EAS_SUCCESS;
-
- /* count the number of active voices */
- activeVoices = 0;
- for (i = 0; i < MAX_SYNTH_VOICES; i++)
- {
- /* this synth? */
- if (GET_VSYNTH(pVoiceMgr->voices[i].nextChannel) != pSynth->vSynthNum)
- continue;
-
- /* is voice active? */
- if ((pVoiceMgr->voices[i].voiceState != eVoiceStateFree) && (pVoiceMgr->voices[i].voiceState != eVoiceStateMuting))
- activeVoices++;
- }
-
- /* we may have to mute voices to reach new target */
- while (activeVoices > polyphonyCount)
- {
- S_SYNTH_VOICE *pVoice;
- EAS_I32 currentPriority, bestPriority;
- EAS_INT bestCandidate;
-
- /* find the lowest priority voice */
- bestPriority = bestCandidate = -1;
- for (i = 0; i < MAX_SYNTH_VOICES; i++)
- {
- pVoice = &pVoiceMgr->voices[i];
-
- /* this synth? */
- if (GET_VSYNTH(pVoice->nextChannel) != pSynth->vSynthNum)
- continue;
-
- /* if voice is stolen or just started, reduce the likelihood it will be stolen */
- if (( pVoice->voiceState == eVoiceStateStolen) || (pVoice->voiceFlags & VOICE_FLAG_NO_SAMPLES_SYNTHESIZED_YET))
- {
- /* include velocity */
- currentPriority = 128 - pVoice->nextVelocity;
-
- /* include channel priority */
- currentPriority += pSynth->channels[GET_CHANNEL(pVoice->nextChannel)].pool << CHANNEL_PRIORITY_STEAL_WEIGHT;
- }
- else
- {
- /* include age */
- currentPriority = (EAS_I32) pVoice->age << NOTE_AGE_STEAL_WEIGHT;
-
- /* include note gain -higher gain is lower steal value */
- /*lint -e{704} use shift for performance */
- currentPriority += ((32768 >> (12 - NOTE_GAIN_STEAL_WEIGHT)) + 256) -
- ((EAS_I32) pVoice->gain >> (12 - NOTE_GAIN_STEAL_WEIGHT));
-
- /* include channel priority */
- currentPriority += pSynth->channels[GET_CHANNEL(pVoice->nextChannel)].pool << CHANNEL_PRIORITY_STEAL_WEIGHT;
- }
-
- /* is this the best choice so far? */
- if (currentPriority > bestPriority)
- {
- bestPriority = currentPriority;
- bestCandidate = i;
- }
- }
-
- /* shutdown best candidate */
- if (bestCandidate < 0)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "VMSetPolyphony: Unable to reduce polyphony\n"); */ }
- break;
- }
-
- /* shut down this voice */
- VMMuteVoice(pVoiceMgr, bestCandidate);
- activeVoices--;
- }
-
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * VMGetPolyphony()
- *----------------------------------------------------------------------------
- * Purpose:
- * Get the virtual synth polyphony
- *
- * Inputs:
- * pVoiceMgr pointer to synthesizer data
- * pPolyphonyCount pointer to variable to hold polyphony count
- * pSynth pointer to virtual synth
- *
- * Outputs:
- * Returns error code
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, pVoiceMgr) reserved for future use */
-EAS_RESULT VMGetPolyphony (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_I32 *pPolyphonyCount)
-{
- *pPolyphonyCount = (EAS_U16) pSynth->maxPolyphony;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * VMSetPriority()
- *----------------------------------------------------------------------------
- * Purpose:
- * Set the virtual synth priority
- *
- * Inputs:
- * pVoiceMgr pointer to synthesizer data
- * priority new priority
- * pSynth pointer to virtual synth
- *
- * Outputs:
- * Returns error code
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, pVoiceMgr) reserved for future use */
-EAS_RESULT VMSetPriority (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_I32 priority)
-{
- pSynth->priority = (EAS_U8) priority ;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * VMGetPriority()
- *----------------------------------------------------------------------------
- * Purpose:
- * Get the virtual synth priority
- *
- * Inputs:
- * pVoiceMgr pointer to synthesizer data
- * pPriority pointer to variable to hold priority
- * pSynth pointer to virtual synth
- *
- * Outputs:
- * Returns error code
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, pVoiceMgr) reserved for future use */
-EAS_RESULT VMGetPriority (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_I32 *pPriority)
-{
- *pPriority = pSynth->priority;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * VMSetVolume()
- *----------------------------------------------------------------------------
- * Purpose:
- * Set the master volume for this synthesizer for this sequence.
- *
- * Inputs:
- * nSynthVolume - the desired master volume
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- *
- *
- * Side Effects:
- * overrides any previously set master volume from sysex
- *
- *----------------------------------------------------------------------------
-*/
-void VMSetVolume (S_SYNTH *pSynth, EAS_U16 masterVolume)
-{
- pSynth->masterVolume = masterVolume;
- pSynth->synthFlags |= SYNTH_FLAG_UPDATE_ALL_CHANNEL_PARAMETERS;
-}
-
-/*----------------------------------------------------------------------------
- * VMSetPitchBendRange()
- *----------------------------------------------------------------------------
- * Set the pitch bend range for the given channel.
- *----------------------------------------------------------------------------
-*/
-void VMSetPitchBendRange (S_SYNTH *pSynth, EAS_INT channel, EAS_I16 pitchBendRange)
-{
- pSynth->channels[channel].pitchBendSensitivity = pitchBendRange;
-}
-
-/*----------------------------------------------------------------------------
- * VMValidateEASLib()
- *----------------------------------------------------------------------------
- * Validates an EAS library
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT VMValidateEASLib (EAS_SNDLIB_HANDLE pEAS)
-{
- /* validate the sound library */
- if (pEAS)
- {
- if (pEAS->identifier != _EAS_LIBRARY_VERSION)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "VMValidateEASLib: Sound library mismatch in sound library: Read 0x%08x, expected 0x%08x\n",
- pEAS->identifier, _EAS_LIBRARY_VERSION); */ }
- return EAS_ERROR_SOUND_LIBRARY;
- }
-
- /* check sample rate */
- if ((pEAS->libAttr & LIBFORMAT_SAMPLE_RATE_MASK) != _OUTPUT_SAMPLE_RATE)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "VMValidateEASLib: Sample rate mismatch in sound library: Read %lu, expected %lu\n",
- pEAS->libAttr & LIBFORMAT_SAMPLE_RATE_MASK, _OUTPUT_SAMPLE_RATE); */ }
- return EAS_ERROR_SOUND_LIBRARY;
- }
-
-#ifdef _WT_SYNTH
- /* check sample bit depth */
-#ifdef _8_BIT_SAMPLES
- if (pEAS->libAttr & LIB_FORMAT_16_BIT_SAMPLES)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "VMValidateEASLib: Expected 8-bit samples and found 16-bit\n",
- pEAS->libAttr & LIBFORMAT_SAMPLE_RATE_MASK, _OUTPUT_SAMPLE_RATE); */ }
- return EAS_ERROR_SOUND_LIBRARY;
- }
-#endif
-#ifdef _16_BIT_SAMPLES
- if ((pEAS->libAttr & LIB_FORMAT_16_BIT_SAMPLES) == 0)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "VMValidateEASLib: Expected 16-bit samples and found 8-bit\n",
- pEAS->libAttr & LIBFORMAT_SAMPLE_RATE_MASK, _OUTPUT_SAMPLE_RATE); */ }
- return EAS_ERROR_SOUND_LIBRARY;
- }
-#endif
-#endif
- }
-
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * VMSetGlobalEASLib()
- *----------------------------------------------------------------------------
- * Purpose:
- * Sets the EAS library to be used by the synthesizer
- *
- * Inputs:
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT VMSetGlobalEASLib (S_VOICE_MGR *pVoiceMgr, EAS_SNDLIB_HANDLE pEAS)
-{
- EAS_RESULT result;
-
- result = VMValidateEASLib(pEAS);
- if (result != EAS_SUCCESS)
- return result;
-
- pVoiceMgr->pGlobalEAS = pEAS;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * VMSetEASLib()
- *----------------------------------------------------------------------------
- * Purpose:
- * Sets the EAS library to be used by the synthesizer
- *
- * Inputs:
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT VMSetEASLib (S_SYNTH *pSynth, EAS_SNDLIB_HANDLE pEAS)
-{
- EAS_RESULT result;
-
- result = VMValidateEASLib(pEAS);
- if (result != EAS_SUCCESS)
- return result;
-
- pSynth->pEAS = pEAS;
- return EAS_SUCCESS;
-}
-
-#ifdef DLS_SYNTHESIZER
-/*----------------------------------------------------------------------------
- * VMSetGlobalDLSLib()
- *----------------------------------------------------------------------------
- * Purpose:
- * Sets the DLS library to be used by the synthesizer
- *
- * Inputs:
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT VMSetGlobalDLSLib (EAS_DATA_HANDLE pEASData, EAS_DLSLIB_HANDLE pDLS)
-{
-
- if (pEASData->pVoiceMgr->pGlobalDLS)
- DLSCleanup(pEASData->hwInstData, pEASData->pVoiceMgr->pGlobalDLS);
-
- pEASData->pVoiceMgr->pGlobalDLS = pDLS;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * VMSetDLSLib()
- *----------------------------------------------------------------------------
- * Purpose:
- * Sets the DLS library to be used by the synthesizer
- *
- * Inputs:
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT VMSetDLSLib (S_SYNTH *pSynth, EAS_DLSLIB_HANDLE pDLS)
-{
- pSynth->pDLS = pDLS;
- return EAS_SUCCESS;
-}
-#endif
-
-/*----------------------------------------------------------------------------
- * VMSetTranposition()
- *----------------------------------------------------------------------------
- * Purpose:
- * Sets the global key transposition used by the synthesizer.
- * Transposes all melodic instruments up or down by the specified
- * amount. Range is limited to +/-12 semitones.
- *
- * Inputs:
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-void VMSetTranposition (S_SYNTH *pSynth, EAS_I32 transposition)
-{
- pSynth->globalTranspose = (EAS_I8) transposition;
-}
-
-/*----------------------------------------------------------------------------
- * VMGetTranposition()
- *----------------------------------------------------------------------------
- * Purpose:
- * Gets the global key transposition used by the synthesizer.
- * Transposes all melodic instruments up or down by the specified
- * amount. Range is limited to +/-12 semitones.
- *
- * Inputs:
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-void VMGetTranposition (S_SYNTH *pSynth, EAS_I32 *pTransposition)
-{
- *pTransposition = pSynth->globalTranspose;
-}
-
-/*----------------------------------------------------------------------------
- * VMGetNoteCount()
- *----------------------------------------------------------------------------
-* Returns the total note count
-*----------------------------------------------------------------------------
-*/
-EAS_I32 VMGetNoteCount (S_SYNTH *pSynth)
-{
- return pSynth->totalNoteCount;
-}
-
-/*----------------------------------------------------------------------------
- * VMMIDIShutdown()
- *----------------------------------------------------------------------------
- * Purpose:
- * Clean up any Synth related system issues.
- *
- * Inputs:
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- * None
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-void VMMIDIShutdown (S_EAS_DATA *pEASData, S_SYNTH *pSynth)
-{
- EAS_INT vSynthNum;
-
- /* decrement reference count, free if all references are gone */
- if (--pSynth->refCount > 0)
- return;
-
- vSynthNum = pSynth->vSynthNum;
-
- /* cleanup DLS load */
-#ifdef DLS_SYNTHESIZER
- /*lint -e{550} result used only in debugging code */
- if (pSynth->pDLS != NULL)
- {
- EAS_RESULT result;
- if ((result = DLSCleanup(pEASData->hwInstData, pSynth->pDLS)) != EAS_SUCCESS)
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "VMMIDIShutdown: Error %ld cleaning up DLS collection\n", result); */ }
- pSynth->pDLS = NULL;
- }
-#endif
-
- VMReset(pEASData->pVoiceMgr, pSynth, EAS_TRUE);
-
- /* check Configuration Module for static memory allocation */
- if (!pEASData->staticMemoryModel)
- EAS_HWFree(pEASData->hwInstData, pSynth);
-
- /* clear pointer to MIDI state */
- pEASData->pVoiceMgr->pSynth[vSynthNum] = NULL;
-}
-
-/*----------------------------------------------------------------------------
- * VMShutdown()
- *----------------------------------------------------------------------------
- * Purpose:
- * Clean up any Synth related system issues.
- *
- * Inputs:
- * psEASData - pointer to overall EAS data structure
- *
- * Outputs:
- * None
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-void VMShutdown (S_EAS_DATA *pEASData)
-{
-
- /* don't free a NULL pointer */
- if (pEASData->pVoiceMgr == NULL)
- return;
-
-#ifdef DLS_SYNTHESIZER
- /* if we have a global DLS collection, clean it up */
- if (pEASData->pVoiceMgr->pGlobalDLS)
- {
- DLSCleanup(pEASData->hwInstData, pEASData->pVoiceMgr->pGlobalDLS);
- pEASData->pVoiceMgr->pGlobalDLS = NULL;
- }
-#endif
-
- /* check Configuration Module for static memory allocation */
- if (!pEASData->staticMemoryModel)
- EAS_HWFree(pEASData->hwInstData, pEASData->pVoiceMgr);
- pEASData->pVoiceMgr = NULL;
-}
-
-#ifdef EXTERNAL_AUDIO
-/*----------------------------------------------------------------------------
- * EAS_RegExtAudioCallback()
- *----------------------------------------------------------------------------
- * Register a callback for external audio processing
- *----------------------------------------------------------------------------
-*/
-void VMRegExtAudioCallback (S_SYNTH *pSynth, EAS_VOID_PTR pInstData, EAS_EXT_PRG_CHG_FUNC cbProgChgFunc, EAS_EXT_EVENT_FUNC cbEventFunc)
-{
- pSynth->pExtAudioInstData = pInstData;
- pSynth->cbProgChgFunc = cbProgChgFunc;
- pSynth->cbEventFunc = cbEventFunc;
-}
-
-/*----------------------------------------------------------------------------
- * VMGetMIDIControllers()
- *----------------------------------------------------------------------------
- * Returns the MIDI controller values on the specified channel
- *----------------------------------------------------------------------------
-*/
-void VMGetMIDIControllers (S_SYNTH *pSynth, EAS_U8 channel, S_MIDI_CONTROLLERS *pControl)
-{
- pControl->modWheel = pSynth->channels[channel].modWheel;
- pControl->volume = pSynth->channels[channel].volume;
- pControl->pan = pSynth->channels[channel].pan;
- pControl->expression = pSynth->channels[channel].expression;
- pControl->channelPressure = pSynth->channels[channel].channelPressure;
-
-#ifdef _REVERB
- pControl->reverbSend = pSynth->channels[channel].reverbSend;
-#endif
-
-#ifdef _CHORUSE
- pControl->chorusSend = pSynth->channels[channel].chorusSend;
-#endif
-}
-#endif
-
-#ifdef _SPLIT_ARCHITECTURE
-/*----------------------------------------------------------------------------
- * VMStartFrame()
- *----------------------------------------------------------------------------
- * Purpose:
- * Starts an audio frame
- *
- * Inputs:
- *
- * Outputs:
- * Returns true if EAS_MixEnginePrep should be called (onboard mixing)
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_BOOL VMStartFrame (S_EAS_DATA *pEASData)
-{
-
- /* init counter for voices starts in split architecture */
-#ifdef MAX_VOICE_STARTS
- pVoiceMgr->numVoiceStarts = 0;
-#endif
-
- return pFrameInterface->pfStartFrame(pEASData->pVoiceMgr->pFrameBuffer);
-}
-
-/*----------------------------------------------------------------------------
- * VMEndFrame()
- *----------------------------------------------------------------------------
- * Purpose:
- * Stops an audio frame
- *
- * Inputs:
- *
- * Outputs:
- * Returns true if EAS_MixEnginePost should be called (onboard mixing)
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_BOOL VMEndFrame (S_EAS_DATA *pEASData)
-{
-
- return pFrameInterface->pfEndFrame(pEASData->pVoiceMgr->pFrameBuffer, pEASData->pMixBuffer, pEASData->masterGain);
-}
-#endif
-
-#ifdef TEST_HARNESS
-/*----------------------------------------------------------------------------
- * SanityCheck()
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT VMSanityCheck (EAS_DATA_HANDLE pEASData)
-{
- S_SYNTH_VOICE *pVoice;
- S_SYNTH *pSynth;
- EAS_INT i;
- EAS_INT j;
- EAS_INT freeVoices;
- EAS_INT activeVoices;
- EAS_INT playingVoices;
- EAS_INT stolenVoices;
- EAS_INT releasingVoices;
- EAS_INT mutingVoices;
- EAS_INT poolCount[MAX_VIRTUAL_SYNTHESIZERS][NUM_SYNTH_CHANNELS];
- EAS_INT vSynthNum;
- EAS_RESULT result = EAS_SUCCESS;
-
- /* initialize counts */
- EAS_HWMemSet(poolCount, 0, sizeof(poolCount));
- freeVoices = activeVoices = playingVoices = stolenVoices = releasingVoices = mutingVoices = 0;
-
- /* iterate through all voices */
- for (i = 0; i < MAX_SYNTH_VOICES; i++)
- {
- pVoice = &pEASData->pVoiceMgr->voices[i];
- if (pVoice->voiceState != eVoiceStateFree)
- {
- vSynthNum = GET_VSYNTH(pVoice->channel);
- if (vSynthNum >= MAX_VIRTUAL_SYNTHESIZERS)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "VMSanityCheck: Voice %d has invalid virtual synth number %d\n", i, vSynthNum); */ }
- result = EAS_FAILURE;
- continue;
- }
- pSynth = pEASData->pVoiceMgr->pSynth[vSynthNum];
-
- switch (pVoice->voiceState)
- {
- case eVoiceStateMuting:
- activeVoices++;
- mutingVoices++;
- break;
-
- case eVoiceStateStolen:
- vSynthNum = GET_VSYNTH(pVoice->nextChannel);
- if (vSynthNum >= MAX_VIRTUAL_SYNTHESIZERS)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "VMSanityCheck: Voice %d has invalid virtual synth number %d\n", i, vSynthNum); */ }
- result = EAS_FAILURE;
- continue;
- }
- pSynth = pEASData->pVoiceMgr->pSynth[vSynthNum];
- activeVoices++;
- stolenVoices++;
- poolCount[vSynthNum][pSynth->channels[GET_CHANNEL(pVoice->nextChannel)].pool]++;
- break;
-
- case eVoiceStateStart:
- case eVoiceStatePlay:
- activeVoices++;
- playingVoices++;
- poolCount[vSynthNum][pSynth->channels[GET_CHANNEL(pVoice->channel)].pool]++;
- break;
-
- case eVoiceStateRelease:
- activeVoices++;
- releasingVoices++;
- poolCount[vSynthNum][pSynth->channels[GET_CHANNEL(pVoice->channel)].pool]++;
- break;
-
- default:
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "VMSanityCheck : voice %d in invalid state\n", i); */ }
- result = EAS_FAILURE;
- break;
- }
- }
-
- /* count free voices */
- else
- freeVoices++;
- }
-
- /* dump state info */
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "%d free\n", freeVoices); */ }
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "%d active\n", activeVoices); */ }
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "%d playing\n", playingVoices); */ }
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "%d releasing\n", releasingVoices); */ }
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "%d muting\n", mutingVoices); */ }
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "%d stolen\n", stolenVoices); */ }
-
- if (pEASData->pVoiceMgr->activeVoices != activeVoices)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Active voice mismatch was %d should be %d\n",
- pEASData->pVoiceMgr->activeVoices, activeVoices); */ }
- result = EAS_FAILURE;
- }
-
- /* check virtual synth status */
- for (i = 0; i < MAX_VIRTUAL_SYNTHESIZERS; i++)
- {
- if (pEASData->pVoiceMgr->pSynth[i] == NULL)
- continue;
-
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Synth %d numActiveVoices: %d\n", i, pEASData->pVoiceMgr->pSynth[i]->numActiveVoices); */ }
- if (pEASData->pVoiceMgr->pSynth[i]->numActiveVoices > MAX_SYNTH_VOICES)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "VMSanityCheck: Synth %d illegal count for numActiveVoices: %d\n", i, pEASData->pVoiceMgr->pSynth[i]->numActiveVoices); */ }
- result = EAS_FAILURE;
- }
- for (j = 0; j < NUM_SYNTH_CHANNELS; j++)
- {
- if (poolCount[i][j] != pEASData->pVoiceMgr->pSynth[i]->poolCount[j])
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Pool count mismatch synth %d pool %d, was %d, should be %d\n",
- i, j, pEASData->pVoiceMgr->pSynth[i]->poolCount[j], poolCount[i][j]); */ }
- result = EAS_FAILURE;
- }
- }
- }
-
- return result;
-}
-#endif
-
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 794 $
+ * $Date: 2007-08-01 00:08:48 -0700 (Wed, 01 Aug 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+/* includes */
+#include "eas.h"
+#include "eas_data.h"
+#include "eas_config.h"
+#include "eas_report.h"
+#include "eas_midictrl.h"
+#include "eas_host.h"
+#include "eas_synth_protos.h"
+#include "eas_vm_protos.h"
+
+#ifdef DLS_SYNTHESIZER
+#include "eas_mdls.h"
+#endif
+
+// #define _DEBUG_VM
+
+/* some defines for workload */
+#define WORKLOAD_AMOUNT_SMALL_INCREMENT 5
+#define WORKLOAD_AMOUNT_START_NOTE 10
+#define WORKLOAD_AMOUNT_STOP_NOTE 10
+#define WORKLOAD_AMOUNT_KEY_GROUP 10
+#define WORKLOAD_AMOUNT_POLY_LIMIT 10
+
+/* pointer to base sound library */
+extern S_EAS easSoundLib;
+
+#ifdef TEST_HARNESS
+extern S_EAS easTestLib;
+EAS_SNDLIB_HANDLE VMGetLibHandle(EAS_INT libNum)
+{
+ switch (libNum)
+ {
+ case 0:
+ return &easSoundLib;
+#ifdef _WT_SYNTH
+ case 1:
+ return &easTestLib;
+#endif
+ default:
+ return NULL;
+ }
+}
+#endif
+
+/* pointer to synthesizer interface(s) */
+#ifdef _WT_SYNTH
+extern const S_SYNTH_INTERFACE wtSynth;
+#endif
+
+#ifdef _FM_SYNTH
+extern const S_SYNTH_INTERFACE fmSynth;
+#endif
+
+typedef S_SYNTH_INTERFACE *S_SYNTH_INTERFACE_HANDLE;
+
+/* wavetable on MCU */
+#if defined(EAS_WT_SYNTH)
+const S_SYNTH_INTERFACE *const pPrimarySynth = &wtSynth;
+
+/* FM on MCU */
+#elif defined(EAS_FM_SYNTH)
+const S_SYNTH_INTERFACE *const pPrimarySynth = &fmSynth;
+
+/* wavetable drums on MCU, FM melodic on DSP */
+#elif defined(EAS_HYBRID_SYNTH)
+const S_SYNTH_INTERFACE *const pPrimarySynth = &wtSynth;
+const S_SYNTH_INTERFACE *const pSecondarySynth = &fmSynth;
+
+/* wavetable drums on MCU, wavetable melodic on DSP */
+#elif defined(EAS_SPLIT_WT_SYNTH)
+const S_SYNTH_INTERFACE *const pPrimarySynth = &wtSynth;
+extern const S_FRAME_INTERFACE wtFrameInterface;
+const S_FRAME_INTERFACE *const pFrameInterface = &wtFrameInterface;
+
+/* wavetable drums on MCU, FM melodic on DSP */
+#elif defined(EAS_SPLIT_HYBRID_SYNTH)
+const S_SYNTH_INTERFACE *const pPrimarySynth = &wtSynth;
+const S_SYNTH_INTERFACE *const pSecondarySynth = &fmSynth;
+extern const S_FRAME_INTERFACE fmFrameInterface;
+const S_FRAME_INTERFACE *const pFrameInterface = &fmFrameInterface;
+
+/* FM on DSP */
+#elif defined(EAS_SPLIT_FM_SYNTH)
+const S_SYNTH_INTERFACE *const pPrimarySynth = &fmSynth;
+extern const S_FRAME_INTERFACE fmFrameInterface;
+const S_FRAME_INTERFACE *const pFrameInterface = &fmFrameInterface;
+
+#else
+#error "Undefined architecture option"
+#endif
+
+/*----------------------------------------------------------------------------
+ * inline functions
+ *----------------------------------------------------------------------------
+*/
+EAS_INLINE const S_REGION* GetRegionPtr (S_SYNTH *pSynth, EAS_U16 regionIndex)
+{
+#if defined(DLS_SYNTHESIZER)
+ if (regionIndex & FLAG_RGN_IDX_DLS_SYNTH)
+ return &pSynth->pDLS->pDLSRegions[regionIndex & REGION_INDEX_MASK].wtRegion.region;
+#endif
+#if defined(_HYBRID_SYNTH)
+ if (regionIndex & FLAG_RGN_IDX_FM_SYNTH)
+ return &pSynth->pEAS->pFMRegions[regionIndex & REGION_INDEX_MASK].region;
+ else
+ return &pSynth->pEAS->pWTRegions[regionIndex].region;
+#elif defined(_WT_SYNTH)
+ return &pSynth->pEAS->pWTRegions[regionIndex].region;
+#elif defined(_FM_SYNTH)
+ return &pSynth->pEAS->pFMRegions[regionIndex].region;
+#endif
+}
+
+/*lint -esym(715, voiceNum) used in some implementation */
+EAS_INLINE const S_SYNTH_INTERFACE* GetSynthPtr (EAS_INT voiceNum)
+{
+#if defined(_HYBRID_SYNTH)
+ if (voiceNum < NUM_PRIMARY_VOICES)
+ return pPrimarySynth;
+ else
+ return pSecondarySynth;
+#else
+ return pPrimarySynth;
+#endif
+}
+
+EAS_INLINE EAS_INT GetAdjustedVoiceNum (EAS_INT voiceNum)
+{
+#if defined(_HYBRID_SYNTH)
+ if (voiceNum >= NUM_PRIMARY_VOICES)
+ return voiceNum - NUM_PRIMARY_VOICES;
+#endif
+ return voiceNum;
+}
+
+EAS_INLINE EAS_U8 VSynthToChannel (S_SYNTH *pSynth, EAS_U8 channel)
+{
+ /*lint -e{734} synthNum is always 0-15 */
+ return channel | (pSynth->vSynthNum << 4);
+}
+
+/*----------------------------------------------------------------------------
+ * InitVoice()
+ *----------------------------------------------------------------------------
+ * Initialize a synthesizer voice
+ *----------------------------------------------------------------------------
+*/
+void InitVoice (S_SYNTH_VOICE *pVoice)
+{
+ pVoice->channel = UNASSIGNED_SYNTH_CHANNEL;
+ pVoice->nextChannel = UNASSIGNED_SYNTH_CHANNEL;
+ pVoice->note = pVoice->nextNote = DEFAULT_KEY_NUMBER;
+ pVoice->velocity = pVoice->nextVelocity = DEFAULT_VELOCITY;
+ pVoice->regionIndex = DEFAULT_REGION_INDEX;
+ pVoice->age = DEFAULT_AGE;
+ pVoice->voiceFlags = DEFAULT_VOICE_FLAGS;
+ pVoice->voiceState = DEFAULT_VOICE_STATE;
+}
+
+/*----------------------------------------------------------------------------
+ * IncVoicePoolCount()
+ *----------------------------------------------------------------------------
+ * Updates the voice pool count when a voice changes state
+ *----------------------------------------------------------------------------
+*/
+static void IncVoicePoolCount (S_VOICE_MGR *pVoiceMgr, S_SYNTH_VOICE *pVoice)
+{
+ S_SYNTH *pSynth;
+ EAS_INT pool;
+
+ /* ignore muting voices */
+ if (pVoice->voiceState == eVoiceStateMuting)
+ return;
+
+ if (pVoice->voiceState == eVoiceStateStolen)
+ {
+ pSynth = pVoiceMgr->pSynth[GET_VSYNTH(pVoice->nextChannel)];
+ pool = pSynth->channels[GET_CHANNEL(pVoice->nextChannel)].pool;
+ }
+ else
+ {
+ pSynth = pVoiceMgr->pSynth[GET_VSYNTH(pVoice->channel)];
+ pool = pSynth->channels[GET_CHANNEL(pVoice->channel)].pool;
+ }
+
+ pSynth->poolCount[pool]++;
+
+#ifdef _DEBUG_VM
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IncVoicePoolCount: Synth=%d pool=%d\n", pSynth->vSynthNum, pool); */ }
+#endif
+}
+
+/*----------------------------------------------------------------------------
+ * DecVoicePoolCount()
+ *----------------------------------------------------------------------------
+ * Updates the voice pool count when a voice changes state
+ *----------------------------------------------------------------------------
+*/
+static void DecVoicePoolCount (S_VOICE_MGR *pVoiceMgr, S_SYNTH_VOICE *pVoice)
+{
+ S_SYNTH *pSynth;
+ EAS_INT pool;
+
+ /* ignore muting voices */
+ if (pVoice->voiceState == eVoiceStateMuting)
+ return;
+
+ if (pVoice->voiceState == eVoiceStateStolen)
+ {
+ pSynth = pVoiceMgr->pSynth[GET_VSYNTH(pVoice->nextChannel)];
+ pool = pSynth->channels[GET_CHANNEL(pVoice->nextChannel)].pool;
+ }
+ else
+ {
+ pSynth = pVoiceMgr->pSynth[GET_VSYNTH(pVoice->channel)];
+ pool = pSynth->channels[GET_CHANNEL(pVoice->channel)].pool;
+ }
+
+ pSynth->poolCount[pool]--;
+
+#ifdef _DEBUG_VM
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "DecVoicePoolCount: Synth=%d pool=%d\n", pSynth->vSynthNum, pool); */ }
+#endif
+}
+
+/*----------------------------------------------------------------------------
+ * VMInitialize()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ *
+ * Inputs:
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT VMInitialize (S_EAS_DATA *pEASData)
+{
+ S_VOICE_MGR *pVoiceMgr;
+ EAS_INT i;
+
+ /* check Configuration Module for data allocation */
+ if (pEASData->staticMemoryModel)
+ pVoiceMgr = EAS_CMEnumData(EAS_CM_SYNTH_DATA);
+ else
+ pVoiceMgr = EAS_HWMalloc(pEASData->hwInstData, sizeof(S_VOICE_MGR));
+ if (!pVoiceMgr)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "VMInitialize: Failed to allocate synthesizer memory\n"); */ }
+ return EAS_ERROR_MALLOC_FAILED;
+ }
+ EAS_HWMemSet(pVoiceMgr, 0, sizeof(S_VOICE_MGR));
+
+ /* initialize non-zero variables */
+ pVoiceMgr->pGlobalEAS = (S_EAS*) &easSoundLib;
+ pVoiceMgr->maxPolyphony = (EAS_U16) MAX_SYNTH_VOICES;
+
+#if defined(_SECONDARY_SYNTH) || defined(EAS_SPLIT_WT_SYNTH)
+ pVoiceMgr->maxPolyphonyPrimary = NUM_PRIMARY_VOICES;
+ pVoiceMgr->maxPolyphonySecondary = NUM_SECONDARY_VOICES;
+#endif
+
+ /* set max workload to zero */
+ pVoiceMgr->maxWorkLoad = 0;
+
+ /* initialize the voice manager parameters */
+ for (i = 0; i < MAX_SYNTH_VOICES; i++)
+ InitVoice(&pVoiceMgr->voices[i]);
+
+ /* initialize the synth */
+ /*lint -e{522} return unused at this time */
+ pPrimarySynth->pfInitialize(pVoiceMgr);
+
+ /* initialize the off-chip synth */
+#ifdef _HYBRID_SYNTH
+ /*lint -e{522} return unused at this time */
+ pSecondarySynth->pfInitialize(pVoiceMgr);
+#endif
+
+ pEASData->pVoiceMgr = pVoiceMgr;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * VMInitMIDI()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ *
+ * Inputs:
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT VMInitMIDI (S_EAS_DATA *pEASData, S_SYNTH **ppSynth)
+{
+ EAS_RESULT result;
+ S_SYNTH *pSynth;
+ EAS_INT virtualSynthNum;
+
+ *ppSynth = NULL;
+
+ /* static memory model only allows one synth */
+ if (pEASData->staticMemoryModel)
+ {
+ if (pEASData->pVoiceMgr->pSynth[0] != NULL)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "VMInitMIDI: No virtual synthesizer support for static memory model\n"); */ }
+ return EAS_ERROR_NO_VIRTUAL_SYNTHESIZER;
+ }
+
+ /* check Configuration Module for data allocation */
+ pSynth = EAS_CMEnumData(EAS_CM_MIDI_DATA);
+ virtualSynthNum = 0;
+ }
+
+ /* dynamic memory model */
+ else
+ {
+ for (virtualSynthNum = 0; virtualSynthNum < MAX_VIRTUAL_SYNTHESIZERS; virtualSynthNum++)
+ if (pEASData->pVoiceMgr->pSynth[virtualSynthNum] == NULL)
+ break;
+ if (virtualSynthNum == MAX_VIRTUAL_SYNTHESIZERS)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "VMInitMIDI: Exceeded number of active virtual synthesizers"); */ }
+ return EAS_ERROR_NO_VIRTUAL_SYNTHESIZER;
+ }
+ pSynth = EAS_HWMalloc(pEASData->hwInstData, sizeof(S_SYNTH));
+ }
+
+ /* make sure we have a valid memory pointer */
+ if (pSynth == NULL)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "VMInitMIDI: Failed to allocate synthesizer memory\n"); */ }
+ return EAS_ERROR_MALLOC_FAILED;
+ }
+ EAS_HWMemSet(pSynth, 0, sizeof(S_SYNTH));
+
+ /* set the sound library pointer */
+ if ((result = VMSetEASLib(pSynth, pEASData->pVoiceMgr->pGlobalEAS)) != EAS_SUCCESS)
+ {
+ VMMIDIShutdown(pEASData, pSynth);
+ return result;
+ }
+
+ /* link in DLS bank if downloaded */
+#ifdef DLS_SYNTHESIZER
+ if (pEASData->pVoiceMgr->pGlobalDLS)
+ {
+ pSynth->pDLS = pEASData->pVoiceMgr->pGlobalDLS;
+ DLSAddRef(pSynth->pDLS);
+ }
+#endif
+
+ /* initialize MIDI state variables */
+ pSynth->synthFlags = DEFAULT_SYNTH_FLAGS;
+ pSynth->masterVolume = DEFAULT_SYNTH_MASTER_VOLUME;
+ pSynth->refCount = 1;
+ pSynth->priority = DEFAULT_SYNTH_PRIORITY;
+ pSynth->poolAlloc[0] = (EAS_U8) pEASData->pVoiceMgr->maxPolyphony;
+
+ VMInitializeAllChannels(pEASData->pVoiceMgr, pSynth);
+
+ pSynth->vSynthNum = (EAS_U8) virtualSynthNum;
+ pEASData->pVoiceMgr->pSynth[virtualSynthNum] = pSynth;
+
+ *ppSynth = pSynth;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * VMIncRefCount()
+ *----------------------------------------------------------------------------
+ * Increment reference count for virtual synth
+ *----------------------------------------------------------------------------
+*/
+void VMIncRefCount (S_SYNTH *pSynth)
+{
+ pSynth->refCount++;
+}
+
+/*----------------------------------------------------------------------------
+ * VMReset()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * We call this routine to start the process of reseting the synth.
+ * This routine sets a flag for the entire synth indicating that we want
+ * to reset.
+ * We also force all voices to mute quickly.
+ * However, we do not actually perform any synthesis in this routine. That
+ * is, we do not ramp the voices down from this routine, but instead, we
+ * let the "regular" synth processing steps take care of adding the ramp
+ * down samples to the output buffer. After we are sure that all voices
+ * have completed ramping down, we continue the process of resetting the
+ * synth (from another routine).
+ *
+ * Inputs:
+ * psEASData - pointer to overall EAS data structure
+ * force - force reset even if voices are active
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ * - set a flag (in psSynthObject->m_nFlags) indicating synth reset requested.
+ * - force all voices to update their envelope states to mute
+ *
+ *----------------------------------------------------------------------------
+*/
+void VMReset (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_BOOL force)
+{
+
+#ifdef _DEBUG_VM
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMReset: request to reset synth. Force = %d\n", force); */ }
+#endif
+
+ /* force voices to off state - may cause audio artifacts */
+ if (force)
+ {
+ pVoiceMgr->activeVoices -= pSynth->numActiveVoices;
+ pSynth->numActiveVoices = 0;
+ VMInitializeAllVoices(pVoiceMgr, pSynth->vSynthNum);
+ }
+ else
+ VMMuteAllVoices(pVoiceMgr, pSynth);
+
+ /* don't reset if voices are still playing */
+ if (pSynth->numActiveVoices == 0)
+ {
+ EAS_INT i;
+
+#ifdef _DEBUG_VM
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMReset: complete the reset process\n"); */ }
+#endif
+
+ VMInitializeAllChannels(pVoiceMgr, pSynth);
+ for (i = 0; i < NUM_SYNTH_CHANNELS; i++)
+ pSynth->poolCount[i] = 0;
+
+ /* set polyphony */
+ if (pSynth->maxPolyphony < pVoiceMgr->maxPolyphony)
+ pSynth->poolAlloc[0] = (EAS_U8) pVoiceMgr->maxPolyphony;
+ else
+ pSynth->poolAlloc[0] = (EAS_U8) pSynth->maxPolyphony;
+
+ /* clear reset flag */
+ pSynth->synthFlags &= ~SYNTH_FLAG_RESET_IS_REQUESTED;
+ }
+
+ /* handle reset after voices are muted */
+ else
+ pSynth->synthFlags |= SYNTH_FLAG_RESET_IS_REQUESTED;
+}
+
+/*----------------------------------------------------------------------------
+ * VMInitializeAllChannels()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ *
+ * Inputs:
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ *
+ *----------------------------------------------------------------------------
+*/
+void VMInitializeAllChannels (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth)
+{
+ S_SYNTH_CHANNEL *pChannel;
+ EAS_INT i;
+
+ VMResetControllers(pSynth);
+
+ /* init each channel */
+ pChannel = pSynth->channels;
+
+ for (i = 0; i < NUM_SYNTH_CHANNELS; i++, pChannel++)
+ {
+ pChannel->channelFlags = DEFAULT_CHANNEL_FLAGS;
+ pChannel->staticGain = DEFAULT_CHANNEL_STATIC_GAIN;
+ pChannel->staticPitch = DEFAULT_CHANNEL_STATIC_PITCH;
+ pChannel->pool = 0;
+
+ /* the drum channel needs a different init */
+ if (i == DEFAULT_DRUM_CHANNEL)
+ {
+ pChannel->bankNum = DEFAULT_RHYTHM_BANK_NUMBER;
+ pChannel->channelFlags |= CHANNEL_FLAG_RHYTHM_CHANNEL;
+ }
+ else
+ pChannel->bankNum = DEFAULT_MELODY_BANK_NUMBER;
+
+ VMProgramChange(pVoiceMgr, pSynth, (EAS_U8) i, DEFAULT_SYNTH_PROGRAM_NUMBER);
+ }
+
+}
+
+/*----------------------------------------------------------------------------
+ * VMResetControllers()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ *
+ * Inputs:
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ *
+ *----------------------------------------------------------------------------
+*/
+void VMResetControllers (S_SYNTH *pSynth)
+{
+ S_SYNTH_CHANNEL *pChannel;
+ EAS_INT i;
+
+ pChannel = pSynth->channels;
+
+ for (i = 0; i < NUM_SYNTH_CHANNELS; i++, pChannel++)
+ {
+ pChannel->pitchBend = DEFAULT_PITCH_BEND;
+ pChannel->modWheel = DEFAULT_MOD_WHEEL;
+ pChannel->volume = DEFAULT_CHANNEL_VOLUME;
+ pChannel->pan = DEFAULT_PAN;
+ pChannel->expression = DEFAULT_EXPRESSION;
+
+#ifdef _REVERB
+ pSynth->channels[i].reverbSend = DEFAULT_REVERB_SEND;
+#endif
+
+#ifdef _CHORUS
+ pSynth->channels[i].chorusSend = DEFAULT_CHORUS_SEND;
+#endif
+
+ pChannel->channelPressure = DEFAULT_CHANNEL_PRESSURE;
+ pChannel->registeredParam = DEFAULT_REGISTERED_PARAM;
+ pChannel->pitchBendSensitivity = DEFAULT_PITCH_BEND_SENSITIVITY;
+ pChannel->finePitch = DEFAULT_FINE_PITCH;
+ pChannel->coarsePitch = DEFAULT_COARSE_PITCH;
+
+ /* update all voices on this channel */
+ pChannel->channelFlags |= CHANNEL_FLAG_UPDATE_CHANNEL_PARAMETERS;
+ }
+}
+
+/*----------------------------------------------------------------------------
+ * VMInitializeAllVoices()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ *
+ * Inputs:
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ *
+ *----------------------------------------------------------------------------
+*/
+void VMInitializeAllVoices (S_VOICE_MGR *pVoiceMgr, EAS_INT vSynthNum)
+{
+ EAS_INT i;
+
+ /* initialize the voice manager parameters */
+ for (i = 0; i < MAX_SYNTH_VOICES; i++)
+ {
+ if (pVoiceMgr->voices[i].voiceState != eVoiceStateStolen)
+ {
+ if (GET_VSYNTH(pVoiceMgr->voices[i].channel) == vSynthNum)
+ InitVoice(&pVoiceMgr->voices[i]);
+ }
+ else
+ {
+ if (GET_VSYNTH(pVoiceMgr->voices[i].nextChannel) == vSynthNum)
+ InitVoice(&pVoiceMgr->voices[i]);
+ }
+ }
+}
+
+/*----------------------------------------------------------------------------
+ * VMMuteVoice()
+ *----------------------------------------------------------------------------
+ * Mute the selected voice
+ *----------------------------------------------------------------------------
+*/
+void VMMuteVoice (S_VOICE_MGR *pVoiceMgr, EAS_I32 voiceNum)
+{
+ S_SYNTH *pSynth;
+ S_SYNTH_VOICE *pVoice;
+
+ /* take no action if voice is already muted */
+ pVoice = &pVoiceMgr->voices[voiceNum];
+ if ((pVoice->voiceState == eVoiceStateMuting) || (pVoice->voiceState == eVoiceStateFree))
+ return;
+
+ /* one less voice in pool */
+ DecVoicePoolCount(pVoiceMgr, pVoice);
+
+ pSynth = pVoiceMgr->pSynth[GET_VSYNTH(pVoice->channel)];
+ GetSynthPtr(voiceNum)->pfMuteVoice(pVoiceMgr, pSynth, pVoice, GetAdjustedVoiceNum(voiceNum));
+ pVoice->voiceState = eVoiceStateMuting;
+
+}
+
+/*----------------------------------------------------------------------------
+ * VMReleaseVoice()
+ *----------------------------------------------------------------------------
+ * Release the selected voice
+ *----------------------------------------------------------------------------
+*/
+void VMReleaseVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_I32 voiceNum)
+{
+ S_SYNTH_VOICE *pVoice = &pVoiceMgr->voices[voiceNum];
+
+ /* take no action if voice is already free, muting, or releasing */
+ if (( pVoice->voiceState == eVoiceStateMuting) ||
+ (pVoice->voiceState == eVoiceStateFree) ||
+ (pVoice->voiceState == eVoiceStateRelease))
+ return;
+
+ /* stolen voices should just be muted */
+ if (pVoice->voiceState == eVoiceStateStolen)
+ VMMuteVoice(pVoiceMgr, voiceNum);
+
+ /* release this voice */
+ GetSynthPtr(voiceNum)->pfReleaseVoice(pVoiceMgr, pSynth, &pVoiceMgr->voices[voiceNum], GetAdjustedVoiceNum(voiceNum));
+ pVoice->voiceState = eVoiceStateRelease;
+}
+
+/*----------------------------------------------------------------------------
+ * VMInitMIPTable()
+ *----------------------------------------------------------------------------
+ * Initialize the SP-MIDI MIP table in preparation for receiving MIP message
+ *----------------------------------------------------------------------------
+*/
+void VMInitMIPTable (S_SYNTH *pSynth)
+{
+ EAS_INT i;
+
+#ifdef _DEBUG_VM
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMInitMIPTable\n"); */ }
+#endif
+
+ /* clear SP-MIDI flag */
+ pSynth->synthFlags &= ~SYNTH_FLAG_SP_MIDI_ON;
+ for (i = 0; i < NUM_SYNTH_CHANNELS; i++)
+ {
+ pSynth->channels[i].pool = 0;
+ pSynth->channels[i].mip = 0;
+ }
+}
+
+/*----------------------------------------------------------------------------
+ * VMSetMIPEntry()
+ *----------------------------------------------------------------------------
+ * Sets the priority and MIP level for a MIDI channel
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pVoiceMgr) reserved for future use */
+void VMSetMIPEntry (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel, EAS_U8 priority, EAS_U8 mip)
+{
+
+#ifdef _DEBUG_VM
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMSetMIPEntry: channel=%d, priority=%d, MIP=%d\n", channel, priority, mip); */ }
+#endif
+
+ /* save data for use by MIP message processing */
+ if (priority < NUM_SYNTH_CHANNELS)
+ {
+ pSynth->channels[channel].pool = priority;
+ pSynth->channels[channel].mip = mip;
+ }
+}
+
+/*----------------------------------------------------------------------------
+ * VMMIPUpdateChannelMuting()
+ *----------------------------------------------------------------------------
+ * This routine is called after an SP-MIDI message is received and
+ * any time the allocated polyphony changes. It mutes or unmutes
+ * channels based on polyphony.
+ *----------------------------------------------------------------------------
+*/
+void VMMIPUpdateChannelMuting (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth)
+{
+ EAS_INT i;
+ EAS_INT maxPolyphony;
+ EAS_INT channel;
+ EAS_INT vSynthNum;
+ EAS_INT pool;
+
+#ifdef _DEBUG_VM
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMUpdateMIPTable\n"); */ }
+#endif
+
+ /* determine max polyphony */
+ if (pSynth->maxPolyphony)
+ maxPolyphony = pSynth->maxPolyphony;
+ else
+ maxPolyphony = pVoiceMgr->maxPolyphony;
+
+ /* process channels */
+ for (i = 0; i < NUM_SYNTH_CHANNELS; i++)
+ {
+
+ /* channel must be in MIP message and must meet allocation target */
+ if ((pSynth->channels[i].mip != 0) && (pSynth->channels[i].mip <= maxPolyphony))
+ pSynth->channels[i].channelFlags &= ~CHANNEL_FLAG_MUTE;
+ else
+ pSynth->channels[i].channelFlags |= CHANNEL_FLAG_MUTE;
+
+ /* reset voice pool count */
+ pSynth->poolCount[i] = 0;
+ }
+
+ /* mute any voices on muted channels, and count unmuted voices */
+ for (i = 0; i < MAX_SYNTH_VOICES; i++)
+ {
+
+ /* ignore free voices */
+ if (pVoiceMgr->voices[i].voiceState == eVoiceStateFree)
+ continue;
+
+ /* get channel and virtual synth */
+ if (pVoiceMgr->voices[i].voiceState != eVoiceStateStolen)
+ {
+ vSynthNum = GET_VSYNTH(pVoiceMgr->voices[i].channel);
+ channel = GET_CHANNEL(pVoiceMgr->voices[i].channel);
+ }
+ else
+ {
+ vSynthNum = GET_VSYNTH(pVoiceMgr->voices[i].nextChannel);
+ channel = GET_CHANNEL(pVoiceMgr->voices[i].nextChannel);
+ }
+
+ /* ignore voices on other synths */
+ if (vSynthNum != pSynth->vSynthNum)
+ continue;
+
+ /* count voices */
+ pool = pSynth->channels[channel].pool;
+
+ /* deal with muted channels */
+ if (pSynth->channels[channel].channelFlags & CHANNEL_FLAG_MUTE)
+ {
+ /* mute stolen voices scheduled to play on this channel */
+ if (pVoiceMgr->voices[i].voiceState == eVoiceStateStolen)
+ pVoiceMgr->voices[i].voiceState = eVoiceStateMuting;
+
+ /* release voices that aren't already muting */
+ else if (pVoiceMgr->voices[i].voiceState != eVoiceStateMuting)
+ {
+ VMReleaseVoice(pVoiceMgr, pSynth, i);
+ pSynth->poolCount[pool]++;
+ }
+ }
+
+ /* not muted, count this voice */
+ else
+ pSynth->poolCount[pool]++;
+ }
+}
+
+/*----------------------------------------------------------------------------
+ * VMUpdateMIPTable()
+ *----------------------------------------------------------------------------
+ * This routine is called at the end of the SysEx message to allow
+ * the Voice Manager to complete the initialization of the MIP
+ * table. It assigns channels to the appropriate voice pool based
+ * on the MIP setting and calculates the voices allocated for each
+ * pool.
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pVoiceMgr) reserved for future use */
+void VMUpdateMIPTable (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth)
+{
+ S_SYNTH_CHANNEL *pChannel;
+ EAS_INT i;
+ EAS_INT currentMIP;
+ EAS_INT currentPool;
+ EAS_INT priority[NUM_SYNTH_CHANNELS];
+
+#ifdef _DEBUG_VM
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMUpdateMIPTable\n"); */ }
+#endif
+
+ /* set SP-MIDI flag */
+ pSynth->synthFlags |= SYNTH_FLAG_SP_MIDI_ON;
+
+ /* sort channels into priority order */
+ for (i = 0; i < NUM_SYNTH_CHANNELS; i++)
+ priority[i] = -1;
+ for (i = 0; i < NUM_SYNTH_CHANNELS; i++)
+ {
+ if (pSynth->channels[i].pool != DEFAULT_SP_MIDI_PRIORITY)
+ priority[pSynth->channels[i].pool] = i;
+ }
+
+ /* process channels in priority order */
+ currentMIP = 0;
+ currentPool = -1;
+ for (i = 0; i < NUM_SYNTH_CHANNELS; i++)
+ {
+ /* stop when we run out of channels */
+ if (priority[i] == -1)
+ break;
+
+ pChannel = &pSynth->channels[priority[i]];
+
+ /* when 2 or more channels have the same MIP setting, they
+ * share a common voice pool
+ */
+ if (pChannel->mip == currentMIP)
+ pChannel->pool = (EAS_U8) currentPool;
+
+ /* new voice pool */
+ else
+ {
+ currentPool++;
+ pSynth->poolAlloc[currentPool] = (EAS_U8) (pChannel->mip - currentMIP);
+ currentMIP = pChannel->mip;
+ }
+ }
+
+ /* set SP-MIDI flag */
+ pSynth->synthFlags |= SYNTH_FLAG_SP_MIDI_ON;
+
+ /* update channel muting */
+ VMMIPUpdateChannelMuting (pVoiceMgr, pSynth);
+}
+
+/*----------------------------------------------------------------------------
+ * VMMuteAllVoices()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * We call this in an emergency reset situation.
+ * This forces all voices to mute quickly.
+ *
+ * Inputs:
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ * - forces all voices to update their envelope states to mute
+ *
+ *----------------------------------------------------------------------------
+*/
+void VMMuteAllVoices (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth)
+{
+ EAS_INT i;
+
+#ifdef _DEBUG_VM
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMMuteAllVoices: about to mute all voices!!\n"); */ }
+#endif
+
+ for (i = 0; i < MAX_SYNTH_VOICES; i++)
+ {
+ /* for stolen voices, check new channel */
+ if (pVoiceMgr->voices[i].voiceState == eVoiceStateStolen)
+ {
+ if (GET_VSYNTH(pVoiceMgr->voices[i].nextChannel) == pSynth->vSynthNum)
+ VMMuteVoice(pVoiceMgr, i);
+ }
+
+ else if (pSynth->vSynthNum == GET_VSYNTH(pVoiceMgr->voices[i].channel))
+ VMMuteVoice(pVoiceMgr, i);
+ }
+}
+
+/*----------------------------------------------------------------------------
+ * VMReleaseAllVoices()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * We call this after we've encountered the end of the Midi file.
+ * This ensures all voices are either in release (because we received their
+ * note off already) or forces them to mute quickly.
+ * We use this as a safety to prevent bad midi files from playing forever.
+ *
+ * Inputs:
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ * - forces all voices to update their envelope states to release or mute
+ *
+ *----------------------------------------------------------------------------
+*/
+void VMReleaseAllVoices (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth)
+{
+ EAS_INT i;
+
+ /* release sustain pedal on all channels */
+ for (i = 0; i < NUM_SYNTH_CHANNELS; i++)
+ {
+ if (pSynth->channels[ i ].channelFlags & CHANNEL_FLAG_SUSTAIN_PEDAL)
+ {
+ VMReleaseAllDeferredNoteOffs(pVoiceMgr, pSynth, (EAS_U8) i);
+ pSynth->channels[i].channelFlags &= ~CHANNEL_FLAG_SUSTAIN_PEDAL;
+ }
+ }
+
+ /* release all voices */
+ for (i = 0; i < MAX_SYNTH_VOICES; i++)
+ {
+
+ switch (pVoiceMgr->voices[i].voiceState)
+ {
+ case eVoiceStateStart:
+ case eVoiceStatePlay:
+ /* only release voices on this synth */
+ if (GET_VSYNTH(pVoiceMgr->voices[i].channel) == pSynth->vSynthNum)
+ VMReleaseVoice(pVoiceMgr, pSynth, i);
+ break;
+
+ case eVoiceStateStolen:
+ if (GET_VSYNTH(pVoiceMgr->voices[i].nextChannel) == pSynth->vSynthNum)
+ VMMuteVoice(pVoiceMgr, i);
+ break;
+
+ case eVoiceStateFree:
+ case eVoiceStateRelease:
+ case eVoiceStateMuting:
+ break;
+
+ case eVoiceStateInvalid:
+ default:
+#ifdef _DEBUG_VM
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMReleaseAllVoices: error, %d is an unrecognized state\n",
+ pVoiceMgr->voices[i].voiceState); */ }
+#endif
+ break;
+ }
+ }
+}
+
+/*----------------------------------------------------------------------------
+ * VMAllNotesOff()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Quickly mute all notes on the given channel.
+ *
+ * Inputs:
+ * nChannel - quickly turn off all notes on this channel
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ * - forces all voices on this channel to update their envelope states to mute
+ *
+ *----------------------------------------------------------------------------
+*/
+void VMAllNotesOff (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel)
+{
+ EAS_INT voiceNum;
+ S_SYNTH_VOICE *pVoice;
+
+#ifdef _DEBUG_VM
+ if (channel >= NUM_SYNTH_CHANNELS)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMAllNotesOff: error, %d invalid channel number\n",
+ channel); */ }
+ return;
+ }
+#endif
+
+ /* increment workload */
+ pVoiceMgr->workload += WORKLOAD_AMOUNT_SMALL_INCREMENT;
+
+ /* check each voice */
+ channel = VSynthToChannel(pSynth, channel);
+ for (voiceNum = 0; voiceNum < MAX_SYNTH_VOICES; voiceNum++)
+ {
+ pVoice = &pVoiceMgr->voices[voiceNum];
+ if (pVoice->voiceState != eVoiceStateFree)
+ {
+ if (((pVoice->voiceState != eVoiceStateStolen) && (channel == pVoice->channel)) ||
+ ((pVoice->voiceState == eVoiceStateStolen) && (channel == pVoice->nextChannel)))
+ {
+ /* this voice is assigned to the requested channel */
+ GetSynthPtr(voiceNum)->pfMuteVoice(pVoiceMgr, pSynth, pVoice, GetAdjustedVoiceNum(voiceNum));
+ pVoice->voiceState = eVoiceStateMuting;
+ }
+ }
+ }
+}
+
+/*----------------------------------------------------------------------------
+ * VMDeferredStopNote()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Stop the notes that had deferred note-off requests.
+ *
+ * Inputs:
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ * None.
+ *
+ * Side Effects:
+ * voices that have had deferred note-off requests are now put into release
+ * psSynthObject->m_sVoice[i].m_nFlags has the VOICE_FLAG_DEFER_MIDI_NOTE_OFF
+ * cleared
+ *----------------------------------------------------------------------------
+*/
+void VMDeferredStopNote (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth)
+{
+ EAS_INT voiceNum;
+ EAS_INT channel;
+ EAS_BOOL deferredNoteOff;
+
+ deferredNoteOff = EAS_FALSE;
+
+ /* check each voice to see if it requires a deferred note off */
+ for (voiceNum=0; voiceNum < MAX_SYNTH_VOICES; voiceNum++)
+ {
+ if (pVoiceMgr->voices[voiceNum].voiceFlags & VOICE_FLAG_DEFER_MIDI_NOTE_OFF)
+ {
+ /* check if this voice was stolen */
+ if (pVoiceMgr->voices[voiceNum].voiceState == eVoiceStateStolen)
+ {
+ /*
+ This voice was stolen, AND it also has a deferred note-off.
+ The stolen note must be completely ramped down at this point.
+ The note that caused the stealing to occur, however, must
+ have received a note-off request before the note that caused
+ stealing ever had a chance to even start. We want to give
+ the note that caused the stealing a chance to play, so we
+ start it on the next update interval, and we defer sending
+ the note-off request until the subsequent update interval.
+ So do not send the note-off request for this voice because
+ this voice was stolen and should have completed ramping down,
+ Also, do not clear the global flag nor this voice's flag
+ because we must indicate that the subsequent update interval,
+ after the note that caused stealing has started, should
+ then send the deferred note-off request.
+ */
+ deferredNoteOff = EAS_TRUE;
+
+#ifdef _DEBUG_VM
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMDeferredStopNote: defer request to stop voice %d (channel=%d note=%d) - voice not started\n",
+ voiceNum,
+ pVoiceMgr->voices[voiceNum].nextChannel,
+ pVoiceMgr->voices[voiceNum].note); */ }
+
+ /* sanity check: this stolen voice better be ramped to zero */
+ if (0 != pVoiceMgr->voices[voiceNum].gain)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMDeferredStopNote: warning, this voice did not complete its ramp to zero\n"); */ }
+ }
+#endif // #ifdef _DEBUG_VM
+
+ }
+ else
+ {
+ /* clear the flag using exor */
+ pVoiceMgr->voices[voiceNum].voiceFlags ^=
+ VOICE_FLAG_DEFER_MIDI_NOTE_OFF;
+
+#ifdef _DEBUG_VM
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMDeferredStopNote: Stop voice %d (channel=%d note=%d)\n",
+ voiceNum,
+ pVoiceMgr->voices[voiceNum].nextChannel,
+ pVoiceMgr->voices[voiceNum].note); */ }
+#endif
+
+ channel = pVoiceMgr->voices[voiceNum].channel & 15;
+
+ /* check if sustain pedal is on */
+ if (pSynth->channels[channel].channelFlags & CHANNEL_FLAG_SUSTAIN_PEDAL)
+ {
+ GetSynthPtr(voiceNum)->pfSustainPedal(pVoiceMgr, pSynth, &pVoiceMgr->voices[voiceNum], &pSynth->channels[channel], GetAdjustedVoiceNum(voiceNum));
+ }
+
+ /* release this voice */
+ else
+ VMReleaseVoice(pVoiceMgr, pSynth, voiceNum);
+
+ }
+
+ }
+
+ }
+
+ /* clear the deferred note-off flag, unless there's another one pending */
+ if (deferredNoteOff == EAS_FALSE)
+ pSynth->synthFlags ^= SYNTH_FLAG_DEFERRED_MIDI_NOTE_OFF_PENDING;
+}
+
+/*----------------------------------------------------------------------------
+ * VMReleaseAllDeferredNoteOffs()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Call this functin when the sustain flag is presently set but
+ * we are now transitioning from damper pedal on to
+ * damper pedal off. This means all notes in this channel
+ * that received a note off while the damper pedal was on, and
+ * had their note-off requests deferred, should now proceed to
+ * the release state.
+ *
+ * Inputs:
+ * nChannel - this channel has its sustain pedal transitioning from on to off
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ * Side Effects:
+ * any voice with deferred note offs on this channel are updated such that
+ * pVoice->m_sEG1.m_eState = eEnvelopeStateRelease
+ * pVoice->m_sEG1.m_nIncrement = release increment
+ * pVoice->m_nFlags = clear the deferred note off flag
+ *----------------------------------------------------------------------------
+*/
+void VMReleaseAllDeferredNoteOffs (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel)
+{
+ S_SYNTH_VOICE *pVoice;
+ EAS_INT voiceNum;
+
+#ifdef _DEBUG_VM
+ if (channel >= NUM_SYNTH_CHANNELS)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMReleaseAllDeferredNoteOffs: error, %d invalid channel number\n",
+ channel); */ }
+ return;
+ }
+#endif /* #ifdef _DEBUG_VM */
+
+ /* increment workload */
+ pVoiceMgr->workload += WORKLOAD_AMOUNT_SMALL_INCREMENT;
+
+ /* find all the voices assigned to this channel */
+ channel = VSynthToChannel(pSynth, channel);
+ for (voiceNum = 0; voiceNum < MAX_SYNTH_VOICES; voiceNum++)
+ {
+
+ pVoice = &pVoiceMgr->voices[voiceNum];
+ if (channel == pVoice->channel)
+ {
+
+ /* does this voice have a deferred note off? */
+ if (pVoice->voiceFlags & VOICE_FLAG_SUSTAIN_PEDAL_DEFER_NOTE_OFF)
+ {
+ /* release voice */
+ VMReleaseVoice(pVoiceMgr, pSynth, voiceNum);
+
+ /* use exor to flip bit, clear the flag */
+ pVoice->voiceFlags &= ~VOICE_FLAG_SUSTAIN_PEDAL_DEFER_NOTE_OFF;
+
+ }
+
+ }
+ }
+
+ return;
+}
+
+/*----------------------------------------------------------------------------
+ * VMCatchNotesForSustainPedal()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Call this function when the sustain flag is presently clear and
+ * the damper pedal is off and we are transitioning from damper pedal OFF to
+ * damper pedal ON. Currently sounding notes should be left
+ * unchanged. However, we should try to "catch" notes if possible.
+ * If any notes are in release and have levels >= sustain level, catch them,
+ * otherwise, let them continue to release.
+ *
+ * Inputs:
+ * nChannel - this channel has its sustain pedal transitioning from on to off
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ *----------------------------------------------------------------------------
+*/
+void VMCatchNotesForSustainPedal (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel)
+{
+ EAS_INT voiceNum;
+
+#ifdef _DEBUG_VM
+ if (channel >= NUM_SYNTH_CHANNELS)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMCatchNotesForSustainPedal: error, %d invalid channel number\n",
+ channel); */ }
+ return;
+ }
+#endif
+
+ pVoiceMgr->workload += WORKLOAD_AMOUNT_SMALL_INCREMENT;
+ channel = VSynthToChannel(pSynth, channel);
+
+ /* find all the voices assigned to this channel */
+ for (voiceNum = 0; voiceNum < MAX_SYNTH_VOICES; voiceNum++)
+ {
+ if (channel == pVoiceMgr->voices[voiceNum].channel)
+ {
+ if (eVoiceStateRelease == pVoiceMgr->voices[voiceNum].voiceState)
+ GetSynthPtr(voiceNum)->pfSustainPedal(pVoiceMgr, pSynth, &pVoiceMgr->voices[voiceNum], &pSynth->channels[channel], GetAdjustedVoiceNum(voiceNum));
+ }
+ }
+}
+
+/*----------------------------------------------------------------------------
+ * VMUpdateAllNotesAge()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Increment the note age for all of the active voices.
+ *
+ * Inputs:
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ * m_nAge for all voices is incremented
+ *----------------------------------------------------------------------------
+*/
+void VMUpdateAllNotesAge (S_VOICE_MGR *pVoiceMgr, EAS_U16 age)
+{
+ EAS_INT i;
+
+ for (i = 0; i < MAX_SYNTH_VOICES; i++)
+ {
+ if (age - pVoiceMgr->voices[i].age > 0)
+ pVoiceMgr->voices[i].age++;
+ }
+}
+
+/*----------------------------------------------------------------------------
+ * VMStolenVoice()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * The selected voice is being stolen. Sets the parameters so that the
+ * voice will begin playing the new sound on the next buffer.
+ *
+ * Inputs:
+ * pVoice - pointer to voice to steal
+ * nChannel - the channel to start a note on
+ * nKeyNumber - the key number to start a note for
+ * nNoteVelocity - the key velocity from this note
+ *
+ * Outputs:
+ * None
+ *----------------------------------------------------------------------------
+*/
+static void VMStolenVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_I32 voiceNum, EAS_U8 channel, EAS_U8 note, EAS_U8 velocity, EAS_U16 regionIndex)
+{
+ S_SYNTH_VOICE *pVoice = &pVoiceMgr->voices[voiceNum];
+
+ /* one less voice in old pool */
+ DecVoicePoolCount(pVoiceMgr, pVoice);
+
+ /* mute the sound that is currently playing */
+ GetSynthPtr(voiceNum)->pfMuteVoice(pVoiceMgr, pVoiceMgr->pSynth[GET_VSYNTH(pVoice->channel)], &pVoiceMgr->voices[voiceNum], GetAdjustedVoiceNum(voiceNum));
+ pVoice->voiceState = eVoiceStateStolen;
+
+ /* set new note data */
+ pVoice->nextChannel = VSynthToChannel(pSynth, channel);
+ pVoice->nextNote = note;
+ pVoice->nextVelocity = velocity;
+ pVoice->nextRegionIndex = regionIndex;
+
+ /* one more voice in new pool */
+ IncVoicePoolCount(pVoiceMgr, pVoice);
+
+ /* clear the deferred flags */
+ pVoice->voiceFlags &=
+ ~(VOICE_FLAG_DEFER_MIDI_NOTE_OFF |
+ VOICE_FLAG_DEFER_MUTE |
+ VOICE_FLAG_SUSTAIN_PEDAL_DEFER_NOTE_OFF);
+
+ /* all notes older than this one get "younger" */
+ VMUpdateAllNotesAge(pVoiceMgr, pVoice->age);
+
+ /* assign current age to this note and increment for the next note */
+ pVoice->age = pVoiceMgr->age++;
+}
+
+/*----------------------------------------------------------------------------
+ * VMFreeVoice()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * The selected voice is done playing and being returned to the
+ * pool of free voices
+ *
+ * Inputs:
+ * pVoice - pointer to voice to free
+ *
+ * Outputs:
+ * None
+ *----------------------------------------------------------------------------
+*/
+static void VMFreeVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice)
+{
+
+ /* do nothing if voice is already free */
+ if (pVoice->voiceState == eVoiceStateFree)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "VMFreeVoice: Attempt to free voice that is already free\n"); */ }
+ return;
+ }
+
+ /* if we jump directly to free without passing muting stage,
+ * we need to adjust the voice count */
+ DecVoicePoolCount(pVoiceMgr, pVoice);
+
+
+#ifdef _DEBUG_VM
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "VMFreeVoice: Synth=%d\n", pSynth->vSynthNum); */ }
+#endif
+
+ /* return to free voice pool */
+ pVoiceMgr->activeVoices--;
+ pSynth->numActiveVoices--;
+ InitVoice(pVoice);
+
+#ifdef _DEBUG_VM
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMFreeVoice: free voice %d\n", pVoice - pVoiceMgr->voices); */ }
+#endif
+
+ /* all notes older than this one get "younger" */
+ VMUpdateAllNotesAge(pVoiceMgr, pVoice->age);
+ }
+
+/*----------------------------------------------------------------------------
+ * VMRetargetStolenVoice()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * The selected voice has been stolen and needs to be initalized with
+ * the paramters of its new note.
+ *
+ * Inputs:
+ * pVoice - pointer to voice to retarget
+ *
+ * Outputs:
+ * None
+ *----------------------------------------------------------------------------
+*/
+static EAS_BOOL VMRetargetStolenVoice (S_VOICE_MGR *pVoiceMgr, EAS_I32 voiceNum)
+{
+ EAS_U8 flags;
+ S_SYNTH_CHANNEL *pMIDIChannel;
+ S_SYNTH_VOICE *pVoice;
+ S_SYNTH *pSynth;
+ S_SYNTH *pNextSynth;
+
+ /* establish some pointers */
+ pVoice = &pVoiceMgr->voices[voiceNum];
+ pSynth = pVoiceMgr->pSynth[GET_VSYNTH(pVoice->channel)];
+ pMIDIChannel = &pSynth->channels[pVoice->channel & 15];
+ pNextSynth = pVoiceMgr->pSynth[GET_VSYNTH(pVoice->nextChannel)];
+
+#ifdef _DEBUG_VM
+{ /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMRetargetStolenVoice: retargeting stolen voice %d on channel %d\n",
+ voiceNum, pVoice->channel); */ }
+
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "\to channel %d note: %d velocity: %d\n",
+ pVoice->nextChannel, pVoice->nextNote, pVoice->nextVelocity); */ }
+#endif
+
+ /* make sure new channel hasn't been muted by SP-MIDI since the voice was stolen */
+ if ((pSynth->synthFlags & SYNTH_FLAG_SP_MIDI_ON) &&
+ (pMIDIChannel->channelFlags & CHANNEL_FLAG_MUTE))
+ {
+ VMFreeVoice(pVoiceMgr, pSynth, &pVoiceMgr->voices[voiceNum]);
+ return EAS_FALSE;
+ }
+
+ /* if assigned to a new synth, correct the active voice count */
+ if (pVoice->channel != pVoice->nextChannel)
+ {
+#ifdef _DEBUG_VM
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMRetargetStolenVoice: Note assigned to different virtual synth, adjusting numActiveVoices\n"); */ }
+#endif
+ pSynth->numActiveVoices--;
+ pNextSynth->numActiveVoices++;
+ }
+
+ /* assign new channel number, and increase channel voice count */
+ pVoice->channel = pVoice->nextChannel;
+ pMIDIChannel = &pNextSynth->channels[pVoice->channel & 15];
+
+ /* assign other data */
+ pVoice->note = pVoice->nextNote;
+ pVoice->velocity = pVoice->nextVelocity;
+ pVoice->nextChannel = UNASSIGNED_SYNTH_CHANNEL;
+ pVoice->regionIndex = pVoice->nextRegionIndex;
+
+ /* save the flags, pfStartVoice() will clear them */
+ flags = pVoice->voiceFlags;
+
+ /* keep track of the note-start related workload */
+ pVoiceMgr->workload += WORKLOAD_AMOUNT_START_NOTE;
+
+ /* setup the voice parameters */
+ pVoice->voiceState = eVoiceStateStart;
+
+ /*lint -e{522} return not used at this time */
+ GetSynthPtr(voiceNum)->pfStartVoice(pVoiceMgr, pNextSynth, &pVoiceMgr->voices[voiceNum], GetAdjustedVoiceNum(voiceNum), pVoice->regionIndex);
+
+ /* did the new note already receive a MIDI note-off request? */
+ if (flags & VOICE_FLAG_DEFER_MIDI_NOTE_OFF)
+ {
+#ifdef _DEBUG_VM
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMRetargetVoice: stolen note note-off request deferred\n"); */ }
+#endif
+ pVoice->voiceFlags |= VOICE_FLAG_DEFER_MIDI_NOTE_OFF;
+ pNextSynth->synthFlags |= SYNTH_FLAG_DEFERRED_MIDI_NOTE_OFF_PENDING;
+ }
+
+ return EAS_TRUE;
+}
+
+/*----------------------------------------------------------------------------
+ * VMCheckKeyGroup()
+ *----------------------------------------------------------------------------
+ * If the note that we've been asked to start is in the same key group as
+ * any currently playing notes, then we must shut down the currently playing
+ * note in the same key group
+ *----------------------------------------------------------------------------
+*/
+void VMCheckKeyGroup (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U16 keyGroup, EAS_U8 channel)
+{
+ const S_REGION *pRegion;
+ EAS_INT voiceNum;
+
+ /* increment frame workload */
+ pVoiceMgr->workload += WORKLOAD_AMOUNT_KEY_GROUP;
+
+ /* need to check all voices in case this is a layered sound */
+ channel = VSynthToChannel(pSynth, channel);
+ for (voiceNum = 0; voiceNum < MAX_SYNTH_VOICES; voiceNum++)
+ {
+ if (pVoiceMgr->voices[voiceNum].voiceState != eVoiceStateStolen)
+ {
+ /* voice must be on the same channel */
+ if (channel == pVoiceMgr->voices[voiceNum].channel)
+ {
+ /* check key group */
+ pRegion = GetRegionPtr(pSynth, pVoiceMgr->voices[voiceNum].regionIndex);
+ if (keyGroup == (pRegion->keyGroupAndFlags & 0x0f00))
+ {
+#ifdef _DEBUG_VM
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMCheckKeyGroup: voice %d matches key group %d\n", voiceNum, keyGroup >> 8); */ }
+#endif
+
+ /* if this voice was just started, set it to mute on the next buffer */
+ if (pVoiceMgr->voices[voiceNum].voiceFlags & VOICE_FLAG_NO_SAMPLES_SYNTHESIZED_YET)
+ pVoiceMgr->voices[voiceNum].voiceFlags |= VOICE_FLAG_DEFER_MUTE;
+
+ /* mute immediately */
+ else
+ VMMuteVoice(pVoiceMgr, voiceNum);
+ }
+ }
+ }
+
+ /* for stolen voice, check new values */
+ else
+ {
+ /* voice must be on the same channel */
+ if (channel == pVoiceMgr->voices[voiceNum].nextChannel)
+ {
+ /* check key group */
+ pRegion = GetRegionPtr(pSynth, pVoiceMgr->voices[voiceNum].nextRegionIndex);
+ if (keyGroup == (pRegion->keyGroupAndFlags & 0x0f00))
+ {
+#ifdef _DEBUG_VM
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMCheckKeyGroup: voice %d matches key group %d\n", voiceNum, keyGroup >> 8); */ }
+#endif
+
+ /* if this voice was just started, set it to mute on the next buffer */
+ if (pVoiceMgr->voices[voiceNum].voiceFlags & VOICE_FLAG_NO_SAMPLES_SYNTHESIZED_YET)
+ pVoiceMgr->voices[voiceNum].voiceFlags |= VOICE_FLAG_DEFER_MUTE;
+
+ /* mute immediately */
+ else
+ VMMuteVoice(pVoiceMgr, voiceNum);
+ }
+ }
+
+ }
+ }
+}
+
+/*----------------------------------------------------------------------------
+ * VMCheckPolyphonyLimiting()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * We only play at most 2 of the same note on a MIDI channel.
+ * E.g., if we are asked to start note 36, and there are already two voices
+ * that are playing note 36, then we must steal the voice playing
+ * the oldest note 36 and use that stolen voice to play the new note 36.
+ *
+ * Inputs:
+ * nChannel - synth channel that wants to start a new note
+ * nKeyNumber - new note's midi note number
+ * nNoteVelocity - new note's velocity
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ * pbVoiceStealingRequired - flag: this routine sets true if we needed to
+ * steal a voice
+ * *
+ * Side Effects:
+ * psSynthObject->m_sVoice[free voice num].m_nKeyNumber may be assigned
+ * psSynthObject->m_sVoice[free voice num].m_nVelocity may be assigned
+ *----------------------------------------------------------------------------
+*/
+EAS_BOOL VMCheckPolyphonyLimiting (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel, EAS_U8 note, EAS_U8 velocity, EAS_U16 regionIndex, EAS_I32 lowVoice, EAS_I32 highVoice)
+{
+ EAS_INT voiceNum;
+ EAS_INT oldestVoiceNum;
+ EAS_INT numVoicesPlayingNote;
+ EAS_U16 age;
+ EAS_U16 oldestNoteAge;
+
+ pVoiceMgr->workload += WORKLOAD_AMOUNT_POLY_LIMIT;
+
+ numVoicesPlayingNote = 0;
+ oldestVoiceNum = MAX_SYNTH_VOICES;
+ oldestNoteAge = 0;
+ channel = VSynthToChannel(pSynth, channel);
+
+ /* examine each voice on this channel playing this note */
+ for (voiceNum = lowVoice; voiceNum <= highVoice; voiceNum++)
+ {
+ /* check stolen notes separately */
+ if (pVoiceMgr->voices[voiceNum].voiceState != eVoiceStateStolen)
+ {
+
+ /* same channel and note ? */
+ if ((channel == pVoiceMgr->voices[voiceNum].channel) && (note == pVoiceMgr->voices[voiceNum].note))
+ {
+ numVoicesPlayingNote++;
+ age = pVoiceMgr->age - pVoiceMgr->voices[voiceNum].age;
+
+ /* is this the oldest voice for this note? */
+ if (age >= oldestNoteAge)
+ {
+ oldestNoteAge = age;
+ oldestVoiceNum = voiceNum;
+ }
+ }
+ }
+
+ /* handle stolen voices */
+ else
+ {
+ /* same channel and note ? */
+ if ((channel == pVoiceMgr->voices[voiceNum].nextChannel) && (note == pVoiceMgr->voices[voiceNum].nextNote))
+ {
+ numVoicesPlayingNote++;
+ }
+ }
+ }
+
+ /* check to see if we exceeded poly limit */
+ if (numVoicesPlayingNote < DEFAULT_CHANNEL_POLYPHONY_LIMIT)
+ return EAS_FALSE;
+
+ /* make sure we have a voice to steal */
+ if (oldestVoiceNum != MAX_SYNTH_VOICES)
+ {
+#ifdef _DEBUG_VM
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMCheckPolyphonyLimiting: voice %d has the oldest note\n", oldestVoiceNum); */ }
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "VMCheckPolyphonyLimiting: polyphony limiting requires shutting down note %d \n", pVoiceMgr->voices[oldestVoiceNum].note); */ }
+#endif
+ VMStolenVoice(pVoiceMgr, pSynth, oldestVoiceNum, channel, note, velocity, regionIndex);
+ return EAS_TRUE;
+ }
+
+#ifdef _DEBUG_VM
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "VMCheckPolyphonyLimiting: No oldest voice to steal\n"); */ }
+#endif
+ return EAS_FALSE;
+}
+
+/*----------------------------------------------------------------------------
+ * VMStartVoice()
+ *----------------------------------------------------------------------------
+ * Starts a voice given a region index
+ *----------------------------------------------------------------------------
+*/
+void VMStartVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel, EAS_U8 note, EAS_U8 velocity, EAS_U16 regionIndex)
+{
+ const S_REGION *pRegion;
+ S_SYNTH_CHANNEL *pChannel;
+ EAS_INT voiceNum;
+ EAS_INT maxSynthPoly;
+ EAS_I32 lowVoice, highVoice;
+ EAS_U16 keyGroup;
+
+ pChannel = &pSynth->channels[channel];
+ pRegion = GetRegionPtr(pSynth, regionIndex);
+
+ /* select correct synth */
+#if defined(_SECONDARY_SYNTH) || defined(EAS_SPLIT_WT_SYNTH)
+ {
+#ifdef EAS_SPLIT_WT_SYNTH
+ if ((pRegion->keyGroupAndFlags & REGION_FLAG_OFF_CHIP) == 0)
+#else
+ if ((regionIndex & FLAG_RGN_IDX_FM_SYNTH) == 0)
+#endif
+ {
+ lowVoice = 0;
+ highVoice = NUM_PRIMARY_VOICES - 1;
+ }
+ else
+ {
+ lowVoice = NUM_PRIMARY_VOICES;
+ highVoice = MAX_SYNTH_VOICES - 1;
+ }
+ }
+#else
+ lowVoice = 0;
+ highVoice = MAX_SYNTH_VOICES - 1;
+#endif
+
+ /* keep track of the note-start related workload */
+ pVoiceMgr->workload+= WORKLOAD_AMOUNT_START_NOTE;
+
+ /* other voices in pool, check for key group and poly limiting */
+ if (pSynth->poolCount[pChannel->pool] != 0)
+ {
+
+ /* check for key group exclusivity */
+ keyGroup = pRegion->keyGroupAndFlags & 0x0f00;
+ if (keyGroup!= 0)
+ VMCheckKeyGroup(pVoiceMgr, pSynth, keyGroup, channel);
+
+ /* check polyphony limit and steal a voice if necessary */
+ if ((pRegion->keyGroupAndFlags & REGION_FLAG_NON_SELF_EXCLUSIVE) == 0)
+ {
+ if (VMCheckPolyphonyLimiting(pVoiceMgr, pSynth, channel, note, velocity, regionIndex, lowVoice, highVoice) == EAS_TRUE)
+ return;
+ }
+ }
+
+ /* check max poly allocation */
+ if ((pSynth->maxPolyphony == 0) || (pVoiceMgr->maxPolyphony < pSynth->maxPolyphony))
+ maxSynthPoly = pVoiceMgr->maxPolyphony;
+ else
+ maxSynthPoly = pSynth->maxPolyphony;
+
+ /* any free voices? */
+ if ((pVoiceMgr->activeVoices < pVoiceMgr->maxPolyphony) &&
+ (pSynth->numActiveVoices < maxSynthPoly) &&
+ (EAS_SUCCESS == VMFindAvailableVoice(pVoiceMgr, &voiceNum, lowVoice, highVoice)))
+ {
+ S_SYNTH_VOICE *pVoice = &pVoiceMgr->voices[voiceNum];
+
+#ifdef _DEBUG_VM
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "VMStartVoice: Synth=%d\n", pSynth->vSynthNum); */ }
+#endif
+
+ /* bump voice counts */
+ pVoiceMgr->activeVoices++;
+ pSynth->numActiveVoices++;
+
+#ifdef _DEBUG_VM
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMStartVoice: voice %d assigned to channel %d note %d velocity %d\n",
+ voiceNum, channel, note, velocity); */ }
+#endif
+
+ /* save parameters */
+ pVoiceMgr->voices[voiceNum].channel = VSynthToChannel(pSynth, channel);
+ pVoiceMgr->voices[voiceNum].note = note;
+ pVoiceMgr->voices[voiceNum].velocity = velocity;
+
+ /* establish note age for voice stealing */
+ pVoiceMgr->voices[voiceNum].age = pVoiceMgr->age++;
+
+ /* setup the synthesis parameters */
+ pVoiceMgr->voices[voiceNum].voiceState = eVoiceStateStart;
+
+ /* increment voice pool count */
+ IncVoicePoolCount(pVoiceMgr, pVoice);
+
+ /* start voice on correct synth */
+ /*lint -e{522} return not used at this time */
+ GetSynthPtr(voiceNum)->pfStartVoice(pVoiceMgr, pSynth, &pVoiceMgr->voices[voiceNum], GetAdjustedVoiceNum(voiceNum), regionIndex);
+ return;
+ }
+
+ /* no free voices, we have to steal one using appropriate algorithm */
+ if (VMStealVoice(pVoiceMgr, pSynth, &voiceNum, channel, note, lowVoice, highVoice) == EAS_SUCCESS)
+ VMStolenVoice(pVoiceMgr, pSynth, voiceNum, channel, note, velocity, regionIndex);
+
+#ifdef _DEBUG_VM
+ else
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMStartVoice: Could not steal a voice for channel %d note %d velocity %d\n",
+ channel, note, velocity); */ }
+ }
+#endif
+
+ return;
+}
+
+/*----------------------------------------------------------------------------
+ * VMStartNote()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Update the synth's state to play the requested note on the requested
+ * channel if possible.
+ *
+ * Inputs:
+ * nChannel - the channel to start a note on
+ * nKeyNumber - the key number to start a note for
+ * nNoteVelocity - the key velocity from this note
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ * Side Effects:
+ * psSynthObject->m_nNumActiveVoices may be incremented
+ * psSynthObject->m_sVoice[free voice num].m_nSynthChannel may be assigned
+ * psSynthObject->m_sVoice[free voice num].m_nKeyNumber is assigned
+ * psSynthObject->m_sVoice[free voice num].m_nVelocity is assigned
+ *----------------------------------------------------------------------------
+*/
+void VMStartNote (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel, EAS_U8 note, EAS_U8 velocity)
+{
+ S_SYNTH_CHANNEL *pChannel;
+ EAS_U16 regionIndex;
+ EAS_I16 adjustedNote;
+
+ /* bump note count */
+ pSynth->totalNoteCount++;
+
+ pChannel = &pSynth->channels[channel];
+
+ /* check channel mute */
+ if (pChannel->channelFlags & CHANNEL_FLAG_MUTE)
+ return;
+
+#ifdef EXTERNAL_AUDIO
+ /* pass event to external audio when requested */
+ if ((pChannel->channelFlags & CHANNEL_FLAG_EXTERNAL_AUDIO) && (pSynth->cbEventFunc != NULL))
+ {
+ S_EXT_AUDIO_EVENT event;
+ event.channel = channel;
+ event.note = note;
+ event.velocity = velocity;
+ event.noteOn = EAS_TRUE;
+ if (pSynth->cbEventFunc(pSynth->pExtAudioInstData, &event))
+ return;
+ }
+#endif
+
+ /* start search at first region */
+ regionIndex = pChannel->regionIndex;
+
+ /* handle transposition */
+ adjustedNote = note;
+ if (pChannel->channelFlags & CHANNEL_FLAG_RHYTHM_CHANNEL)
+ adjustedNote += pChannel->coarsePitch;
+ else
+ adjustedNote += pChannel->coarsePitch + pSynth->globalTranspose;
+
+ /* limit adjusted key number so it does not wraparound, over/underflow */
+ if (adjustedNote < 0)
+ {
+ adjustedNote = 0;
+ }
+ else if (adjustedNote > 127)
+ {
+ adjustedNote = 127;
+ }
+
+#if defined(DLS_SYNTHESIZER)
+ if (regionIndex & FLAG_RGN_IDX_DLS_SYNTH)
+ {
+ /* DLS voice */
+ for (;;)
+ {
+ /*lint -e{740,826} cast OK, we know this is actually a DLS region */
+ const S_DLS_REGION *pDLSRegion = (S_DLS_REGION*) GetRegionPtr(pSynth, regionIndex);
+
+ /* check key against this region's key and velocity range */
+ if (((adjustedNote >= pDLSRegion->wtRegion.region.rangeLow) && (adjustedNote <= pDLSRegion->wtRegion.region.rangeHigh)) &&
+ ((velocity >= pDLSRegion->velLow) && (velocity <= pDLSRegion->velHigh)))
+ {
+ VMStartVoice(pVoiceMgr, pSynth, channel, note, velocity, regionIndex);
+ }
+
+ /* last region in program? */
+ if (pDLSRegion->wtRegion.region.keyGroupAndFlags & REGION_FLAG_LAST_REGION)
+ break;
+
+ /* advance to next region */
+ regionIndex++;
+ }
+ }
+ else
+#endif
+
+ /* braces here for #if clause */
+ {
+ /* EAS voice */
+ for (;;)
+ {
+ const S_REGION *pRegion = GetRegionPtr(pSynth, regionIndex);
+
+ /* check key against this region's keyrange */
+ if ((adjustedNote >= pRegion->rangeLow) && (adjustedNote <= pRegion->rangeHigh))
+ {
+ VMStartVoice(pVoiceMgr, pSynth, channel, note, velocity, regionIndex);
+ break;
+ }
+
+ /* last region in program? */
+ if (pRegion->keyGroupAndFlags & REGION_FLAG_LAST_REGION)
+ break;
+
+ /* advance to next region */
+ regionIndex++;
+ }
+ }
+}
+
+/*----------------------------------------------------------------------------
+ * VMStopNote()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Update the synth's state to end the requested note on the requested
+ * channel.
+ *
+ * Inputs:
+ * nChannel - the channel to stop a note on
+ * nKeyNumber - the key number for this note off
+ * nNoteVelocity - the note-off velocity
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ * Side Effects:
+ * psSynthObject->m_sVoice[free voice num].m_nSynthChannel may be assigned
+ * psSynthObject->m_sVoice[free voice num].m_nKeyNumber is assigned
+ * psSynthObject->m_sVoice[free voice num].m_nVelocity is assigned
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, velocity) reserved for future use */
+void VMStopNote (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel, EAS_U8 note, EAS_U8 velocity)
+{
+ S_SYNTH_CHANNEL *pChannel;
+ EAS_INT voiceNum;
+
+ pChannel = &(pSynth->channels[channel]);
+
+#ifdef EXTERNAL_AUDIO
+ if ((pChannel->channelFlags & CHANNEL_FLAG_EXTERNAL_AUDIO) && (pSynth->cbEventFunc != NULL))
+ {
+ S_EXT_AUDIO_EVENT event;
+ event.channel = channel;
+ event.note = note;
+ event.velocity = velocity;
+ event.noteOn = EAS_FALSE;
+ if (pSynth->cbEventFunc(pSynth->pExtAudioInstData, &event))
+ return;
+ }
+#endif
+
+ /* keep track of the note-start workload */
+ pVoiceMgr->workload += WORKLOAD_AMOUNT_STOP_NOTE;
+
+ channel = VSynthToChannel(pSynth, channel);
+
+ for (voiceNum=0; voiceNum < MAX_SYNTH_VOICES; voiceNum++)
+ {
+
+ /* stolen notes are handled separately */
+ if (eVoiceStateStolen != pVoiceMgr->voices[voiceNum].voiceState)
+ {
+
+ /* channel and key number must match */
+ if ((channel == pVoiceMgr->voices[voiceNum].channel) && (note == pVoiceMgr->voices[voiceNum].note))
+ {
+#ifdef _DEBUG_VM
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMStopNote: voice %d channel %d note %d\n",
+ voiceNum, channel, note); */ }
+#endif
+
+ /* if sustain pedal is down, set deferred note-off flag */
+ if (pChannel->channelFlags & CHANNEL_FLAG_SUSTAIN_PEDAL)
+ {
+ pVoiceMgr->voices[voiceNum].voiceFlags |= VOICE_FLAG_SUSTAIN_PEDAL_DEFER_NOTE_OFF;
+ continue;
+ }
+
+ /* if this note just started, wait before we stop it */
+ if (pVoiceMgr->voices[voiceNum].voiceFlags & VOICE_FLAG_NO_SAMPLES_SYNTHESIZED_YET)
+ {
+#ifdef _DEBUG_VM
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "\tDeferred: Not started yet\n"); */ }
+#endif
+ pVoiceMgr->voices[voiceNum].voiceFlags |= VOICE_FLAG_DEFER_MIDI_NOTE_OFF;
+ pSynth->synthFlags |= SYNTH_FLAG_DEFERRED_MIDI_NOTE_OFF_PENDING;
+ }
+
+ /* release voice */
+ else
+ VMReleaseVoice(pVoiceMgr, pSynth, voiceNum);
+
+ }
+ }
+
+ /* process stolen notes, new channel and key number must match */
+ else if ((channel == pVoiceMgr->voices[voiceNum].nextChannel) && (note == pVoiceMgr->voices[voiceNum].nextNote))
+ {
+
+#ifdef _DEBUG_VM
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMStopNote: voice %d channel %d note %d\n\tDeferred: Stolen voice\n",
+ voiceNum, channel, note); */ }
+#endif
+ pVoiceMgr->voices[voiceNum].voiceFlags |= VOICE_FLAG_DEFER_MIDI_NOTE_OFF;
+ }
+ }
+}
+
+/*----------------------------------------------------------------------------
+ * VMFindAvailableVoice()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Find an available voice and return the voice number if available.
+ *
+ * Inputs:
+ * pnVoiceNumber - really an output, returns the voice number found
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ * success - if there is an available voice
+ * failure - otherwise
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT VMFindAvailableVoice (S_VOICE_MGR *pVoiceMgr, EAS_INT *pVoiceNumber, EAS_I32 lowVoice, EAS_I32 highVoice)
+{
+ EAS_INT voiceNum;
+
+ /* Check each voice to see if it has been assigned to a synth channel */
+ for (voiceNum = lowVoice; voiceNum <= highVoice; voiceNum++)
+ {
+ /* check if this voice has been assigned to a synth channel */
+ if ( pVoiceMgr->voices[voiceNum].voiceState == eVoiceStateFree)
+ {
+ *pVoiceNumber = voiceNum; /* this voice is available */
+ return EAS_SUCCESS;
+ }
+ }
+
+ /* if we reach here, we have not found a free voice */
+ *pVoiceNumber = UNASSIGNED_SYNTH_VOICE;
+
+#ifdef _DEBUG_VM
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMFindAvailableVoice: error, could not find an available voice\n"); */ }
+#endif
+ return EAS_FAILURE;
+}
+
+/*----------------------------------------------------------------------------
+ * VMStealVoice()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Steal a voice and return the voice number
+ *
+ * Stealing algorithm: steal the best choice with minimal work, taking into
+ * account SP-Midi channel priorities and polyphony allocation.
+ *
+ * In one pass through all the voices, figure out which voice to steal
+ * taking into account a number of different factors:
+ * Priority of the voice's MIDI channel
+ * Number of voices over the polyphony allocation for voice's MIDI channel
+ * Amplitude of the voice
+ * Note age
+ * Key velocity (for voices that haven't been started yet)
+ * If any matching notes are found
+ *
+ * Inputs:
+ * pnVoiceNumber - really an output, see below
+ * nChannel - the channel that this voice wants to be started on
+ * nKeyNumber - the key number for this new voice
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ * pnVoiceNumber - voice number of the voice that was stolen
+ * EAS_RESULT EAS_SUCCESS - always successful
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT VMStealVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_INT *pVoiceNumber, EAS_U8 channel, EAS_U8 note, EAS_I32 lowVoice, EAS_I32 highVoice)
+{
+ S_SYNTH_VOICE *pCurrVoice;
+ S_SYNTH *pCurrSynth;
+ EAS_INT voiceNum;
+ EAS_INT bestCandidate;
+ EAS_U8 currChannel;
+ EAS_U8 currNote;
+ EAS_I32 bestPriority;
+ EAS_I32 currentPriority;
+
+ /* determine which voice to steal */
+ bestPriority = 0;
+ bestCandidate = MAX_SYNTH_VOICES;
+
+ for (voiceNum = lowVoice; voiceNum <= highVoice; voiceNum++)
+ {
+ pCurrVoice = &pVoiceMgr->voices[voiceNum];
+
+ /* ignore free voices */
+ if (pCurrVoice->voiceState == eVoiceStateFree)
+ continue;
+
+ /* for stolen voices, use the new parameters, not the old */
+ if (pCurrVoice->voiceState == eVoiceStateStolen)
+ {
+ pCurrSynth = pVoiceMgr->pSynth[GET_VSYNTH(pCurrVoice->nextChannel)];
+ currChannel = pCurrVoice->nextChannel;
+ currNote = pCurrVoice->nextNote;
+ }
+ else
+ {
+ pCurrSynth = pVoiceMgr->pSynth[GET_VSYNTH(pCurrVoice->channel)];
+ currChannel = pCurrVoice->channel;
+ currNote = pCurrVoice->note;
+ }
+
+ /* ignore voices that are higher priority */
+ if (pSynth->priority > pCurrSynth->priority)
+ continue;
+#ifdef _DEBUG_VM
+// { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMStealVoice: New priority = %d exceeds old priority = %d\n", pSynth->priority, pCurrSynth->priority); */ }
+#endif
+
+ /* if voice is stolen or just started, reduce the likelihood it will be stolen */
+ if (( pCurrVoice->voiceState == eVoiceStateStolen) || (pCurrVoice->voiceFlags & VOICE_FLAG_NO_SAMPLES_SYNTHESIZED_YET))
+ {
+ currentPriority = 128 - pCurrVoice->nextVelocity;
+ }
+ else
+ {
+ /* compute the priority of this voice, higher means better for stealing */
+ /* use not age */
+ currentPriority = (EAS_I32) pCurrVoice->age << NOTE_AGE_STEAL_WEIGHT;
+
+ /* include note gain -higher gain is lower steal value */
+ /*lint -e{704} use shift for performance */
+ currentPriority += ((32768 >> (12 - NOTE_GAIN_STEAL_WEIGHT)) + 256) -
+ ((EAS_I32) pCurrVoice->gain >> (12 - NOTE_GAIN_STEAL_WEIGHT));
+ }
+
+ /* in SP-MIDI mode, include over poly allocation and channel priority */
+ if (pSynth->synthFlags & SYNTH_FLAG_SP_MIDI_ON)
+ {
+ S_SYNTH_CHANNEL *pChannel = &pCurrSynth->channels[GET_CHANNEL(currChannel)];
+ /*lint -e{701} use shift for performance */
+ if (pSynth->poolCount[pChannel->pool] >= pSynth->poolAlloc[pChannel->pool])
+ currentPriority += (pSynth->poolCount[pChannel->pool] -pSynth->poolAlloc[pChannel->pool] + 1) << CHANNEL_POLY_STEAL_WEIGHT;
+
+ /* include channel priority */
+ currentPriority += (EAS_I32)(pChannel->pool << CHANNEL_PRIORITY_STEAL_WEIGHT);
+ }
+
+ /* if a note is already playing that matches this note, consider stealing it more readily */
+ if ((note == currNote) && (channel == currChannel))
+ currentPriority += NOTE_MATCH_PENALTY;
+
+ /* is this the best choice so far? */
+ if (currentPriority >= bestPriority)
+ {
+ bestPriority = currentPriority;
+ bestCandidate = voiceNum;
+ }
+ }
+
+ /* may happen if all voices are allocated to a higher priority virtual synth */
+ if (bestCandidate == MAX_SYNTH_VOICES)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMStealVoice: Unable to allocate a voice\n"); */ }
+ return EAS_ERROR_NO_VOICE_ALLOCATED;
+ }
+
+#ifdef _DEBUG_VM
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMStealVoice: Voice %d stolen\n", bestCandidate); */ }
+
+ /* are we stealing a stolen voice? */
+ if (pVoiceMgr->voices[bestCandidate].voiceState == eVoiceStateStolen)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "VMStealVoice: Voice %d is already marked as stolen and was scheduled to play ch: %d note: %d vel: %d\n",
+ bestCandidate,
+ pVoiceMgr->voices[bestCandidate].nextChannel,
+ pVoiceMgr->voices[bestCandidate].nextNote,
+ pVoiceMgr->voices[bestCandidate].nextVelocity); */ }
+ }
+#endif
+
+ *pVoiceNumber = (EAS_U16) bestCandidate;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * VMChannelPressure()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Change the channel pressure for the given channel
+ *
+ * Inputs:
+ * nChannel - the MIDI channel
+ * nVelocity - the channel pressure value
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ * Side Effects:
+ * psSynthObject->m_sChannel[nChannel].m_nChannelPressure is updated
+ *----------------------------------------------------------------------------
+*/
+void VMChannelPressure (S_SYNTH *pSynth, EAS_U8 channel, EAS_U8 value)
+{
+ S_SYNTH_CHANNEL *pChannel;
+
+ pChannel = &(pSynth->channels[channel]);
+ pChannel->channelPressure = value;
+
+ /*
+ set a channel flag to request parameter updates
+ for all the voices associated with this channel
+ */
+ pChannel->channelFlags |= CHANNEL_FLAG_UPDATE_CHANNEL_PARAMETERS;
+}
+
+/*----------------------------------------------------------------------------
+ * VMPitchBend()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Change the pitch wheel value for the given channel.
+ * This routine constructs the proper 14-bit argument when the calling routine
+ * passes the pitch LSB and MSB.
+ *
+ * Note: some midi disassemblers display a bipolar pitch bend value.
+ * We can display the bipolar value using
+ * if m_nPitchBend >= 0x2000
+ * bipolar pitch bend = postive (m_nPitchBend - 0x2000)
+ * else
+ * bipolar pitch bend = negative (0x2000 - m_nPitchBend)
+ *
+ * Inputs:
+ * nChannel - the MIDI channel
+ * nPitchLSB - the LSB byte of the pitch bend message
+ * nPitchMSB - the MSB byte of the pitch bend message
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ * psSynthObject->m_sChannel[nChannel].m_nPitchBend is changed
+ *
+ *----------------------------------------------------------------------------
+*/
+void VMPitchBend (S_SYNTH *pSynth, EAS_U8 channel, EAS_U8 nPitchLSB, EAS_U8 nPitchMSB)
+{
+ S_SYNTH_CHANNEL *pChannel;
+
+ pChannel = &(pSynth->channels[channel]);
+ pChannel->pitchBend = (EAS_I16) ((nPitchMSB << 7) | nPitchLSB);
+
+ /*
+ set a channel flag to request parameter updates
+ for all the voices associated with this channel
+ */
+ pChannel->channelFlags |= CHANNEL_FLAG_UPDATE_CHANNEL_PARAMETERS;
+}
+
+/*----------------------------------------------------------------------------
+ * VMControlChange()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Change the controller (or mode) for the given channel.
+ *
+ * Inputs:
+ * nChannel - the MIDI channel
+ * nControllerNumber - the MIDI controller number
+ * nControlValue - the value for this controller message
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ * Side Effects:
+ * psSynthObject->m_sChannel[nChannel] controller is changed
+ *
+ *----------------------------------------------------------------------------
+*/
+void VMControlChange (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel, EAS_U8 controller, EAS_U8 value)
+{
+ S_SYNTH_CHANNEL *pChannel;
+
+ pChannel = &(pSynth->channels[channel]);
+
+ /*
+ set a channel flag to request parameter updates
+ for all the voices associated with this channel
+ */
+ pChannel->channelFlags |= CHANNEL_FLAG_UPDATE_CHANNEL_PARAMETERS;
+
+ switch ( controller )
+ {
+ case MIDI_CONTROLLER_BANK_SELECT_MSB:
+#ifdef _DEBUG_VM
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMControlChange: Bank Select MSB: msb 0x%X\n", value); */ }
+#endif
+ /* use this MSB with a zero LSB, until we get an LSB message */
+ pChannel->bankNum = value << 8;
+ break;
+
+ case MIDI_CONTROLLER_MOD_WHEEL:
+ /* we treat mod wheel as a 7-bit controller and only use the MSB */
+ pChannel->modWheel = value;
+ break;
+
+ case MIDI_CONTROLLER_VOLUME:
+ /* we treat volume as a 7-bit controller and only use the MSB */
+ pChannel->volume = value;
+ break;
+
+ case MIDI_CONTROLLER_PAN:
+ /* we treat pan as a 7-bit controller and only use the MSB */
+ pChannel->pan = value;
+ break;
+
+ case MIDI_CONTROLLER_EXPRESSION:
+ /* we treat expression as a 7-bit controller and only use the MSB */
+ pChannel->expression = value;
+ break;
+
+ case MIDI_CONTROLLER_BANK_SELECT_LSB:
+#ifdef _DEBUG_VM
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMControlChange: Bank Select LSB: lsb 0x%X\n", value); */ }
+#endif
+ /*
+ construct bank number as 7-bits (stored as 8) of existing MSB
+ and 7-bits of new LSB (also stored as 8(
+ */
+ pChannel->bankNum =
+ (pChannel->bankNum & 0xFF00) | value;
+
+ break;
+
+ case MIDI_CONTROLLER_SUSTAIN_PEDAL:
+ /* we treat sustain pedal as a boolean on/off bit flag */
+ if (value < 64)
+ {
+ /*
+ we are requested to turn the pedal off, but first check
+ if the pedal is already on
+ */
+ if (0 !=
+ (pChannel->channelFlags & CHANNEL_FLAG_SUSTAIN_PEDAL)
+ )
+ {
+ /*
+ The sustain flag is presently set and the damper pedal is on.
+ We are therefore transitioning from damper pedal ON to
+ damper pedal OFF. This means all notes in this channel
+ that received a note off while the damper pedal was on, and
+ had their note-off requests deferred, should now proceed to
+ the release state.
+ */
+ VMReleaseAllDeferredNoteOffs(pVoiceMgr, pSynth, channel);
+ } /* end if sustain pedal is already on */
+
+ /* turn the sustain pedal off */
+ pChannel->channelFlags &= ~CHANNEL_FLAG_SUSTAIN_PEDAL;
+ }
+ else
+ {
+ /*
+ we are requested to turn the pedal on, but first check
+ if the pedal is already off
+ */
+ if (0 ==
+ (pChannel->channelFlags & CHANNEL_FLAG_SUSTAIN_PEDAL)
+ )
+ {
+ /*
+ The sustain flag is presently clear and the damper pedal is off.
+ We are therefore transitioning from damper pedal OFF to
+ damper pedal ON. Currently sounding notes should be left
+ unchanged. However, we should try to "catch" notes if possible.
+ If any notes have levels >= sustain level, catch them,
+ otherwise, let them continue to release.
+ */
+ VMCatchNotesForSustainPedal(pVoiceMgr, pSynth, channel);
+ }
+
+ /* turn the sustain pedal on */
+ pChannel->channelFlags |= CHANNEL_FLAG_SUSTAIN_PEDAL;
+ }
+
+ break;
+#ifdef _REVERB
+ case MIDI_CONTROLLER_REVERB_SEND:
+ /* we treat send as a 7-bit controller and only use the MSB */
+ pSynth->channels[channel].reverbSend = value;
+ break;
+#endif
+#ifdef _CHORUS
+ case MIDI_CONTROLLER_CHORUS_SEND:
+ /* we treat send as a 7-bit controller and only use the MSB */
+ pSynth->channels[channel].chorusSend = value;
+ break;
+#endif
+ case MIDI_CONTROLLER_RESET_CONTROLLERS:
+ /* despite the Midi message name, not ALL controllers are reset */
+ pChannel->modWheel = DEFAULT_MOD_WHEEL;
+ pChannel->expression = DEFAULT_EXPRESSION;
+
+ /* turn the sustain pedal off as default/reset */
+ pChannel->channelFlags &= ~CHANNEL_FLAG_SUSTAIN_PEDAL;
+ pChannel->pitchBend = DEFAULT_PITCH_BEND;
+
+ /* reset channel pressure */
+ pChannel->channelPressure = DEFAULT_CHANNEL_PRESSURE;
+
+ /* reset RPN values */
+ pChannel->registeredParam = DEFAULT_REGISTERED_PARAM;
+ pChannel->pitchBendSensitivity = DEFAULT_PITCH_BEND_SENSITIVITY;
+ pChannel->finePitch = DEFAULT_FINE_PITCH;
+ pChannel->coarsePitch = DEFAULT_COARSE_PITCH;
+
+ /*
+ program change, bank select, channel volume CC7, pan CC10
+ are NOT reset
+ */
+ break;
+
+ /*
+ For logical reasons, the RPN data entry are grouped together.
+ However, keep in mind that these cases are not necessarily in
+ ascending order.
+ e.g., MIDI_CONTROLLER_DATA_ENTRY_MSB == 6,
+ whereas MIDI_CONTROLLER_SUSTAIN_PEDAL == 64.
+ So arrange these case statements in whatever manner is more efficient for
+ the processor / compiler.
+ */
+ case MIDI_CONTROLLER_ENTER_DATA_MSB:
+ case MIDI_CONTROLLER_ENTER_DATA_LSB:
+ case MIDI_CONTROLLER_SELECT_RPN_LSB:
+ case MIDI_CONTROLLER_SELECT_RPN_MSB:
+ case MIDI_CONTROLLER_SELECT_NRPN_MSB:
+ case MIDI_CONTROLLER_SELECT_NRPN_LSB:
+ VMUpdateRPNStateMachine(pSynth, channel, controller, value);
+ break;
+
+ case MIDI_CONTROLLER_ALL_SOUND_OFF:
+ case MIDI_CONTROLLER_ALL_NOTES_OFF:
+ case MIDI_CONTROLLER_OMNI_OFF:
+ case MIDI_CONTROLLER_OMNI_ON:
+ case MIDI_CONTROLLER_MONO_ON_POLY_OFF:
+ case MIDI_CONTROLLER_POLY_ON_MONO_OFF:
+ /* NOTE: we treat all sounds off the same as all notes off */
+ VMAllNotesOff(pVoiceMgr, pSynth, channel);
+ break;
+
+ default:
+#ifdef _DEBUG_VM
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMControlChange: controller %d not yet implemented\n", controller); */ }
+#endif
+ break;
+
+ }
+
+ return;
+}
+
+/*----------------------------------------------------------------------------
+ * VMUpdateRPNStateMachine()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Call this function when we want to parse RPN related controller messages.
+ * We only support RPN0 (pitch bend sensitivity), RPN1 (fine tuning) and
+ * RPN2 (coarse tuning). Any other RPNs or NRPNs are ignored for now.
+ *.
+ * Supports any order, so not a state machine anymore. This function was
+ * rewritten to work correctly regardless of order.
+ *
+ * Inputs:
+ * nChannel - the channel this controller message is coming from
+ * nControllerNumber - which RPN related controller
+ * nControlValue - the value of the RPN related controller
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ * returns EAS_RESULT, which is typically EAS_SUCCESS, since there are
+ * few possible errors
+ *
+ * Side Effects:
+ * gsSynthObject.m_sChannel[nChannel].m_nPitchBendSensitivity
+ * (or m_nFinePitch or m_nCoarsePitch)
+ * will be updated if the proper RPN message is received.
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT VMUpdateRPNStateMachine (S_SYNTH *pSynth, EAS_U8 channel, EAS_U8 controller, EAS_U8 value)
+{
+ S_SYNTH_CHANNEL *pChannel;
+
+#ifdef _DEBUG_VM
+ if (channel >= NUM_SYNTH_CHANNELS)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMUpdateRPNStateMachines: error, %d invalid channel number\n",
+ channel); */ }
+ return EAS_FAILURE;
+ }
+#endif
+
+ pChannel = &(pSynth->channels[channel]);
+
+ switch (controller)
+ {
+ case MIDI_CONTROLLER_SELECT_NRPN_MSB:
+ case MIDI_CONTROLLER_SELECT_NRPN_LSB:
+ pChannel->registeredParam = DEFAULT_REGISTERED_PARAM;
+ break;
+ case MIDI_CONTROLLER_SELECT_RPN_MSB:
+ pChannel->registeredParam =
+ (pChannel->registeredParam & 0x7F) | (value<<7);
+ break;
+ case MIDI_CONTROLLER_SELECT_RPN_LSB:
+ pChannel->registeredParam =
+ (pChannel->registeredParam & 0x7F00) | value;
+ break;
+ case MIDI_CONTROLLER_ENTER_DATA_MSB:
+ switch (pChannel->registeredParam)
+ {
+ case 0:
+ pChannel->pitchBendSensitivity = value * 100;
+ break;
+ case 1:
+ /*lint -e{702} <avoid division for performance reasons>*/
+ pChannel->finePitch = (EAS_I8)((((value << 7) - 8192) * 100) >> 13);
+ break;
+ case 2:
+ pChannel->coarsePitch = (EAS_I8)(value - 64);
+ break;
+ default:
+ break;
+ }
+ break;
+ case MIDI_CONTROLLER_ENTER_DATA_LSB:
+ switch (pChannel->registeredParam)
+ {
+ case 0:
+ //ignore lsb
+ break;
+ case 1:
+ //ignore lsb
+ break;
+ case 2:
+ //ignore lsb
+ break;
+ default:
+ break;
+ }
+ break;
+ default:
+ return EAS_FAILURE; //not a RPN related controller
+ }
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * VMUpdateStaticChannelParameters()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Update all of the static channel parameters for channels that have had
+ * a controller change values
+ * Or if the synth has signalled that all channels must forcibly
+ * be updated
+ *
+ * Inputs:
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ * none
+ *
+ * Side Effects:
+ * - psSynthObject->m_sChannel[].m_nStaticGain and m_nStaticPitch
+ * are updated for channels whose controller values have changed
+ * or if the synth has signalled that all channels must forcibly
+ * be updated
+ *----------------------------------------------------------------------------
+*/
+void VMUpdateStaticChannelParameters (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth)
+{
+ EAS_INT channel;
+
+ if (pSynth->synthFlags & SYNTH_FLAG_UPDATE_ALL_CHANNEL_PARAMETERS)
+ {
+ /*
+ the synth wants us to forcibly update all channel
+ parameters. This event occurs when we are about to
+ finish resetting the synth
+ */
+ for (channel = 0; channel < NUM_SYNTH_CHANNELS; channel++)
+ {
+#ifdef _HYBRID_SYNTH
+ if (pSynth->channels[channel].regionIndex & FLAG_RGN_IDX_FM_SYNTH)
+ pSecondarySynth->pfUpdateChannel(pVoiceMgr, pSynth, (EAS_U8) channel);
+ else
+ pPrimarySynth->pfUpdateChannel(pVoiceMgr, pSynth, (EAS_U8) channel);
+#else
+ pPrimarySynth->pfUpdateChannel(pVoiceMgr, pSynth, (EAS_U8) channel);
+#endif
+ }
+
+ /*
+ clear the flag to indicates we have now forcibly
+ updated all channel parameters
+ */
+ pSynth->synthFlags &= ~SYNTH_FLAG_UPDATE_ALL_CHANNEL_PARAMETERS;
+ }
+ else
+ {
+
+ /* only update channel params if signalled by a channel flag */
+ for (channel = 0; channel < NUM_SYNTH_CHANNELS; channel++)
+ {
+ if ( 0 != (pSynth->channels[channel].channelFlags & CHANNEL_FLAG_UPDATE_CHANNEL_PARAMETERS))
+ {
+#ifdef _HYBRID_SYNTH
+ if (pSynth->channels[channel].regionIndex & FLAG_RGN_IDX_FM_SYNTH)
+ pSecondarySynth->pfUpdateChannel(pVoiceMgr, pSynth, (EAS_U8) channel);
+ else
+ pPrimarySynth->pfUpdateChannel(pVoiceMgr, pSynth, (EAS_U8) channel);
+#else
+ pPrimarySynth->pfUpdateChannel(pVoiceMgr, pSynth, (EAS_U8) channel);
+#endif
+ }
+ }
+
+ }
+
+ return;
+}
+
+/*----------------------------------------------------------------------------
+ * VMFindProgram()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Look up an individual program in sound library. This function
+ * searches the bank list for a program, then the individual program
+ * list.
+ *
+ * Inputs:
+ *
+ * Outputs:
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT VMFindProgram (const S_EAS *pEAS, EAS_U32 bank, EAS_U8 programNum, EAS_U16 *pRegionIndex)
+{
+ EAS_U32 locale;
+ const S_PROGRAM *p;
+ EAS_U16 i;
+ EAS_U16 regionIndex;
+
+ /* make sure we have a valid sound library */
+ if (pEAS == NULL)
+ return EAS_FAILURE;
+
+ /* search the banks */
+ for (i = 0; i < pEAS->numBanks; i++)
+ {
+ if (bank == (EAS_U32) pEAS->pBanks[i].locale)
+ {
+ regionIndex = pEAS->pBanks[i].regionIndex[programNum];
+ if (regionIndex != INVALID_REGION_INDEX)
+ {
+ *pRegionIndex = regionIndex;
+ return EAS_SUCCESS;
+ }
+ break;
+ }
+ }
+
+ /* establish locale */
+ locale = ( bank << 8) | programNum;
+
+ /* search for program */
+ for (i = 0, p = pEAS->pPrograms; i < pEAS->numPrograms; i++, p++)
+ {
+ if (p->locale == locale)
+ {
+ *pRegionIndex = p->regionIndex;
+ return EAS_SUCCESS;
+ }
+ }
+
+ return EAS_FAILURE;
+}
+
+#ifdef DLS_SYNTHESIZER
+/*----------------------------------------------------------------------------
+ * VMFindDLSProgram()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Look up an individual program in sound library. This function
+ * searches the bank list for a program, then the individual program
+ * list.
+ *
+ * Inputs:
+ *
+ * Outputs:
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT VMFindDLSProgram (const S_DLS *pDLS, EAS_U32 bank, EAS_U8 programNum, EAS_U16 *pRegionIndex)
+{
+ EAS_U32 locale;
+ const S_PROGRAM *p;
+ EAS_U16 i;
+
+ /* make sure we have a valid sound library */
+ if (pDLS == NULL)
+ return EAS_FAILURE;
+
+ /* establish locale */
+ locale = (bank << 8) | programNum;
+
+ /* search for program */
+ for (i = 0, p = pDLS->pDLSPrograms; i < pDLS->numDLSPrograms; i++, p++)
+ {
+ if (p->locale == locale)
+ {
+ *pRegionIndex = p->regionIndex;
+ return EAS_SUCCESS;
+ }
+ }
+
+ return EAS_FAILURE;
+}
+#endif
+
+/*----------------------------------------------------------------------------
+ * VMProgramChange()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Change the instrument (program) for the given channel.
+ *
+ * Depending on the program number, and the bank selected for this channel, the
+ * program may be in ROM, RAM (from SMAF or CMX related RAM wavetable), or
+ * Alternate wavetable (from mobile DLS or other DLS file)
+ *
+ * This function figures out what wavetable should be used, and sets it up as the
+ * wavetable to use for this channel. Also the channel may switch from a melodic
+ * channel to a rhythm channel, or vice versa.
+ *
+ * Inputs:
+ *
+ * Outputs:
+ * Side Effects:
+ * gsSynthObject.m_sChannel[nChannel].m_nProgramNumber is likely changed
+ * gsSynthObject.m_sChannel[nChannel].m_psEAS may be changed
+ * gsSynthObject.m_sChannel[nChannel].m_bRhythmChannel may be changed
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pVoiceMgr) reserved for future use */
+void VMProgramChange (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel, EAS_U8 program)
+{
+ S_SYNTH_CHANNEL *pChannel;
+ EAS_U32 bank;
+ EAS_U16 regionIndex;
+
+#ifdef _DEBUG_VM
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "VMProgramChange: vSynthNum=%d, channel=%d, program=%d\n", pSynth->vSynthNum, channel, program); */ }
+#endif
+
+ /* setup pointer to MIDI channel data */
+ pChannel = &pSynth->channels[channel];
+ bank = pChannel->bankNum;
+
+ /* allow channels to switch between being melodic or rhythm channels, using GM2 CC values */
+ if ((bank & 0xFF00) == DEFAULT_RHYTHM_BANK_NUMBER)
+ {
+ /* make it a rhythm channel */
+ pChannel->channelFlags |= CHANNEL_FLAG_RHYTHM_CHANNEL;
+ }
+ else if ((bank & 0xFF00) == DEFAULT_MELODY_BANK_NUMBER)
+ {
+ /* make it a melody channel */
+ pChannel->channelFlags &= ~CHANNEL_FLAG_RHYTHM_CHANNEL;
+ }
+
+ regionIndex = DEFAULT_REGION_INDEX;
+
+#ifdef EXTERNAL_AUDIO
+ /* give the external audio interface a chance to handle it */
+ if (pSynth->cbProgChgFunc != NULL)
+ {
+ S_EXT_AUDIO_PRG_CHG prgChg;
+ prgChg.channel = channel;
+ prgChg.bank = (EAS_U16) bank;
+ prgChg.program = program;
+ if (pSynth->cbProgChgFunc(pSynth->pExtAudioInstData, &prgChg))
+ pChannel->channelFlags |= CHANNEL_FLAG_EXTERNAL_AUDIO;
+ }
+
+#endif
+
+
+#ifdef DLS_SYNTHESIZER
+ /* first check for DLS program that may overlay the internal instrument */
+ if (VMFindDLSProgram(pSynth->pDLS, bank, program, &regionIndex) != EAS_SUCCESS)
+#endif
+
+ /* braces to support 'if' clause above */
+ {
+
+ /* look in the internal banks */
+ if (VMFindProgram(pSynth->pEAS, bank, program, &regionIndex) != EAS_SUCCESS)
+
+ /* fall back to default bank */
+ {
+ if (pSynth->channels[channel].channelFlags & CHANNEL_FLAG_RHYTHM_CHANNEL)
+ bank = DEFAULT_RHYTHM_BANK_NUMBER;
+ else
+ bank = DEFAULT_MELODY_BANK_NUMBER;
+
+ if (VMFindProgram(pSynth->pEAS, bank, program, &regionIndex) != EAS_SUCCESS)
+
+ /* switch to program 0 in the default bank */
+ {
+ if (VMFindProgram(pSynth->pEAS, bank, 0, &regionIndex) != EAS_SUCCESS)
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "VMProgramChange: No program @ %03d:%03d:%03d\n",
+ (bank >> 8) & 0x7f, bank & 0x7f, program); */ }
+ }
+ }
+ }
+
+ /* we have our new program change for this channel */
+ pChannel->programNum = program;
+ pChannel->regionIndex = regionIndex;
+
+ /*
+ set a channel flag to request parameter updates
+ for all the voices associated with this channel
+ */
+ pChannel->channelFlags |= CHANNEL_FLAG_UPDATE_CHANNEL_PARAMETERS;
+
+ return;
+}
+
+/*----------------------------------------------------------------------------
+ * VMAddSamples()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Synthesize the requested number of samples (block based processing)
+ *
+ * Inputs:
+ * nNumSamplesToAdd - number of samples to write to buffer
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ * number of voices rendered
+ *
+ * Side Effects:
+ * - samples are added to the presently free buffer
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_I32 VMAddSamples (S_VOICE_MGR *pVoiceMgr, EAS_I32 *pMixBuffer, EAS_I32 numSamples)
+{
+ S_SYNTH *pSynth;
+ EAS_INT voicesRendered;
+ EAS_INT voiceNum;
+ EAS_BOOL done;
+
+#ifdef _REVERB
+ EAS_PCM *pReverbSendBuffer;
+#endif // ifdef _REVERB
+
+#ifdef _CHORUS
+ EAS_PCM *pChorusSendBuffer;
+#endif // ifdef _CHORUS
+
+ voicesRendered = 0;
+ for (voiceNum = 0; voiceNum < MAX_SYNTH_VOICES; voiceNum++)
+ {
+
+ /* retarget stolen voices */
+ if ((pVoiceMgr->voices[voiceNum].voiceState == eVoiceStateStolen) && (pVoiceMgr->voices[voiceNum].gain <= 0))
+ VMRetargetStolenVoice(pVoiceMgr, voiceNum);
+
+ /* get pointer to virtual synth */
+ pSynth = pVoiceMgr->pSynth[pVoiceMgr->voices[voiceNum].channel >> 4];
+
+ /* synthesize active voices */
+ if (pVoiceMgr->voices[voiceNum].voiceState != eVoiceStateFree)
+ {
+ done = GetSynthPtr(voiceNum)->pfUpdateVoice(pVoiceMgr, pSynth, &pVoiceMgr->voices[voiceNum], GetAdjustedVoiceNum(voiceNum), pMixBuffer, numSamples);
+ voicesRendered++;
+
+ /* voice is finished */
+ if (done == EAS_TRUE)
+ {
+ /* set gain of stolen voice to zero so it will be restarted */
+ if (pVoiceMgr->voices[voiceNum].voiceState == eVoiceStateStolen)
+ pVoiceMgr->voices[voiceNum].gain = 0;
+
+ /* or return it to the free voice pool */
+ else
+ VMFreeVoice(pVoiceMgr, pSynth, &pVoiceMgr->voices[voiceNum]);
+ }
+
+ /* if this voice is scheduled to be muted, set the mute flag */
+ if (pVoiceMgr->voices[voiceNum].voiceFlags & VOICE_FLAG_DEFER_MUTE)
+ {
+ pVoiceMgr->voices[voiceNum].voiceFlags &= ~(VOICE_FLAG_DEFER_MUTE | VOICE_FLAG_DEFER_MIDI_NOTE_OFF);
+ VMMuteVoice(pVoiceMgr, voiceNum);
+ }
+
+ /* if voice just started, advance state to play */
+ if (pVoiceMgr->voices[voiceNum].voiceState == eVoiceStateStart)
+ pVoiceMgr->voices[voiceNum].voiceState = eVoiceStatePlay;
+ }
+ }
+
+ return voicesRendered;
+}
+
+/*----------------------------------------------------------------------------
+ * VMRender()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * This routine renders a frame of audio
+ *
+ * Inputs:
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ * pVoicesRendered - number of voices rendered this frame
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT VMRender (S_VOICE_MGR *pVoiceMgr, EAS_I32 numSamples, EAS_I32 *pMixBuffer, EAS_I32 *pVoicesRendered)
+{
+ S_SYNTH *pSynth;
+ EAS_INT i;
+ EAS_INT channel;
+
+#ifdef _CHECKED_BUILD
+ SanityCheck(pVoiceMgr);
+#endif
+
+ /* update MIDI channel parameters */
+ *pVoicesRendered = 0;
+ for (i = 0; i < MAX_VIRTUAL_SYNTHESIZERS; i++)
+ {
+ if (pVoiceMgr->pSynth[i] != NULL)
+ VMUpdateStaticChannelParameters(pVoiceMgr, pVoiceMgr->pSynth[i]);
+ }
+
+ /* synthesize a buffer of audio */
+ *pVoicesRendered = VMAddSamples(pVoiceMgr, pMixBuffer, numSamples);
+
+ /*
+ * check for deferred note-off messages
+ * If flag is set, that means one or more voices are expecting deferred
+ * midi note-off messages because the midi note-on and corresponding midi
+ * note-off requests occurred during the same update interval. The goal
+ * is the defer the note-off request so that the note can at least start.
+ */
+ for (i = 0; i < MAX_VIRTUAL_SYNTHESIZERS; i++)
+ {
+ pSynth = pVoiceMgr->pSynth[i];
+
+ if (pSynth== NULL)
+ continue;
+
+ if (pSynth->synthFlags & SYNTH_FLAG_DEFERRED_MIDI_NOTE_OFF_PENDING)
+ VMDeferredStopNote(pVoiceMgr, pSynth);
+
+ /* check if we need to reset the synth */
+ if ((pSynth->synthFlags & SYNTH_FLAG_RESET_IS_REQUESTED) &&
+ (pSynth->numActiveVoices == 0))
+ {
+ /*
+ complete the process of resetting the synth now that
+ all voices have muted
+ */
+#ifdef _DEBUG_VM
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMAddSamples: complete the reset process\n"); */ }
+#endif
+
+ VMInitializeAllChannels(pVoiceMgr, pSynth);
+ VMInitializeAllVoices(pVoiceMgr, pSynth->vSynthNum);
+
+ /* clear the reset flag */
+ pSynth->synthFlags &= ~SYNTH_FLAG_RESET_IS_REQUESTED;
+ }
+
+ /* clear channel update flags */
+ for (channel = 0; channel < NUM_SYNTH_CHANNELS; channel++)
+ pSynth->channels[channel].channelFlags &= ~CHANNEL_FLAG_UPDATE_CHANNEL_PARAMETERS;
+
+ }
+
+#ifdef _CHECKED_BUILD
+ SanityCheck(pVoiceMgr);
+#endif
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * VMInitWorkload()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Clears the workload counter
+ *
+ * Inputs:
+ * pVoiceMgr - pointer to instance data
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+void VMInitWorkload (S_VOICE_MGR *pVoiceMgr)
+{
+ pVoiceMgr->workload = 0;
+}
+
+/*----------------------------------------------------------------------------
+ * VMSetWorkload()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Sets the max workload for a single frame.
+ *
+ * Inputs:
+ * pVoiceMgr - pointer to instance data
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+void VMSetWorkload (S_VOICE_MGR *pVoiceMgr, EAS_I32 maxWorkLoad)
+{
+ pVoiceMgr->maxWorkLoad = maxWorkLoad;
+}
+
+/*----------------------------------------------------------------------------
+ * VMCheckWorkload()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Checks to see if work load has been exceeded on this frame.
+ *
+ * Inputs:
+ * pVoiceMgr - pointer to instance data
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_BOOL VMCheckWorkload (S_VOICE_MGR *pVoiceMgr)
+{
+ if (pVoiceMgr->maxWorkLoad > 0)
+ return (EAS_BOOL) (pVoiceMgr->workload >= pVoiceMgr->maxWorkLoad);
+ return EAS_FALSE;
+}
+
+/*----------------------------------------------------------------------------
+ * VMActiveVoices()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Returns the number of active voices in the synthesizer.
+ *
+ * Inputs:
+ * pEASData - pointer to instance data
+ *
+ * Outputs:
+ * Returns the number of active voices
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_I32 VMActiveVoices (S_SYNTH *pSynth)
+{
+ return pSynth->numActiveVoices;
+}
+
+/*----------------------------------------------------------------------------
+ * VMSetSynthPolyphony()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Set the synth to a new polyphony value. Value must be >= 1 and
+ * <= MAX_SYNTH_VOICES. This function will pin the polyphony at those limits
+ *
+ * Inputs:
+ * pVoiceMgr pointer to synthesizer data
+ * polyphonyCount desired polyphony count
+ * synth synthesizer number (0 = onboard, 1 = DSP)
+ *
+ * Outputs:
+ * Returns error code
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT VMSetSynthPolyphony (S_VOICE_MGR *pVoiceMgr, EAS_I32 synth, EAS_I32 polyphonyCount)
+{
+ EAS_INT i;
+ EAS_INT activeVoices;
+
+ /* lower limit */
+ if (polyphonyCount < 1)
+ polyphonyCount = 1;
+
+ /* split architecture */
+#if defined(_SECONDARY_SYNTH) || defined(EAS_SPLIT_WT_SYNTH)
+ if (synth == EAS_MCU_SYNTH)
+ {
+ if (polyphonyCount > NUM_PRIMARY_VOICES)
+ polyphonyCount = NUM_PRIMARY_VOICES;
+ if (pVoiceMgr->maxPolyphonyPrimary == polyphonyCount)
+ return EAS_SUCCESS;
+ pVoiceMgr->maxPolyphonyPrimary = (EAS_U16) polyphonyCount;
+ }
+ else if (synth == EAS_DSP_SYNTH)
+ {
+ if (polyphonyCount > NUM_SECONDARY_VOICES)
+ polyphonyCount = NUM_SECONDARY_VOICES;
+ if (pVoiceMgr->maxPolyphonySecondary == polyphonyCount)
+ return EAS_SUCCESS;
+ pVoiceMgr->maxPolyphonySecondary = (EAS_U16) polyphonyCount;
+ }
+ else
+ return EAS_ERROR_PARAMETER_RANGE;
+
+ /* setting for SP-MIDI */
+ pVoiceMgr->maxPolyphony = pVoiceMgr->maxPolyphonyPrimary + pVoiceMgr->maxPolyphonySecondary;
+
+ /* standard architecture */
+#else
+ if (synth != EAS_MCU_SYNTH)
+ return EAS_ERROR_PARAMETER_RANGE;
+
+ /* pin desired value to possible limits */
+ if (polyphonyCount > MAX_SYNTH_VOICES)
+ polyphonyCount = MAX_SYNTH_VOICES;
+
+ /* set polyphony, if value is different than current value */
+ if (pVoiceMgr->maxPolyphony == polyphonyCount)
+ return EAS_SUCCESS;
+
+ pVoiceMgr->maxPolyphony = (EAS_U16) polyphonyCount;
+#endif
+
+ /* if SPMIDI enabled, update channel masking based on new polyphony */
+ for (i = 0; i < MAX_VIRTUAL_SYNTHESIZERS; i++)
+ {
+ if (pVoiceMgr->pSynth[i])
+ {
+ if (pVoiceMgr->pSynth[i]->synthFlags & SYNTH_FLAG_SP_MIDI_ON)
+ VMMIPUpdateChannelMuting(pVoiceMgr, pVoiceMgr->pSynth[i]);
+ else
+ pVoiceMgr->pSynth[i]->poolAlloc[0] = (EAS_U8) polyphonyCount;
+ }
+ }
+
+ /* are we under polyphony limit? */
+ if (pVoiceMgr->activeVoices <= polyphonyCount)
+ return EAS_SUCCESS;
+
+ /* count the number of active voices */
+ activeVoices = 0;
+ for (i = 0; i < MAX_SYNTH_VOICES; i++)
+ {
+
+ /* is voice active? */
+ if ((pVoiceMgr->voices[i].voiceState != eVoiceStateFree) && (pVoiceMgr->voices[i].voiceState != eVoiceStateMuting))
+ activeVoices++;
+ }
+
+ /* we may have to mute voices to reach new target */
+ while (activeVoices > polyphonyCount)
+ {
+ S_SYNTH *pSynth;
+ S_SYNTH_VOICE *pVoice;
+ EAS_I32 currentPriority, bestPriority;
+ EAS_INT bestCandidate;
+
+ /* find the lowest priority voice */
+ bestPriority = bestCandidate = -1;
+ for (i = 0; i < MAX_SYNTH_VOICES; i++)
+ {
+
+ pVoice = &pVoiceMgr->voices[i];
+
+ /* ignore free and muting voices */
+ if ((pVoice->voiceState == eVoiceStateFree) || (pVoice->voiceState == eVoiceStateMuting))
+ continue;
+
+ pSynth = pVoiceMgr->pSynth[GET_VSYNTH(pVoice->channel)];
+
+ /* if voice is stolen or just started, reduce the likelihood it will be stolen */
+ if (( pVoice->voiceState == eVoiceStateStolen) || (pVoice->voiceFlags & VOICE_FLAG_NO_SAMPLES_SYNTHESIZED_YET))
+ {
+ /* include velocity */
+ currentPriority = 128 - pVoice->nextVelocity;
+
+ /* include channel priority */
+ currentPriority += pSynth->channels[GET_CHANNEL(pVoice->nextChannel)].pool << CHANNEL_PRIORITY_STEAL_WEIGHT;
+ }
+ else
+ {
+ /* include age */
+ currentPriority = (EAS_I32) pVoice->age << NOTE_AGE_STEAL_WEIGHT;
+
+ /* include note gain -higher gain is lower steal value */
+ /*lint -e{704} use shift for performance */
+ currentPriority += ((32768 >> (12 - NOTE_GAIN_STEAL_WEIGHT)) + 256) -
+ ((EAS_I32) pVoice->gain >> (12 - NOTE_GAIN_STEAL_WEIGHT));
+
+ /* include channel priority */
+ currentPriority += pSynth->channels[GET_CHANNEL(pVoice->channel)].pool << CHANNEL_PRIORITY_STEAL_WEIGHT;
+ }
+
+ /* include synth priority */
+ currentPriority += pSynth->priority << SYNTH_PRIORITY_WEIGHT;
+
+ /* is this the best choice so far? */
+ if (currentPriority > bestPriority)
+ {
+ bestPriority = currentPriority;
+ bestCandidate = i;
+ }
+ }
+
+ /* shutdown best candidate */
+ if (bestCandidate < 0)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "VMSetPolyphony: Unable to reduce polyphony\n"); */ }
+ break;
+ }
+
+ /* shut down this voice */
+ /*lint -e{771} pSynth is initialized if bestCandidate >= 0 */
+ VMMuteVoice(pVoiceMgr, bestCandidate);
+ activeVoices--;
+ }
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * VMGetSynthPolyphony()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Returns the current polyphony setting
+ *
+ * Inputs:
+ * pVoiceMgr pointer to synthesizer data
+ * synth synthesizer number (0 = onboard, 1 = DSP)
+ *
+ * Outputs:
+ * Returns actual polyphony value set, as pinned by limits
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT VMGetSynthPolyphony (S_VOICE_MGR *pVoiceMgr, EAS_I32 synth, EAS_I32 *pPolyphonyCount)
+{
+
+#if defined(_SECONDARY_SYNTH) || defined(EAS_SPLIT_WT_SYNTH)
+ if (synth == EAS_MCU_SYNTH)
+ *pPolyphonyCount = pVoiceMgr->maxPolyphonyPrimary;
+ else if (synth == EAS_DSP_SYNTH)
+ *pPolyphonyCount = pVoiceMgr->maxPolyphonySecondary;
+ else
+ return EAS_ERROR_PARAMETER_RANGE;
+#else
+ if (synth != EAS_MCU_SYNTH)
+ return EAS_ERROR_PARAMETER_RANGE;
+ *pPolyphonyCount = pVoiceMgr->maxPolyphony;
+#endif
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * VMSetPolyphony()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Set the virtual synth polyphony. 0 = no limit (i.e. can use
+ * all available voices).
+ *
+ * Inputs:
+ * pVoiceMgr pointer to synthesizer data
+ * polyphonyCount desired polyphony count
+ * pSynth pointer to virtual synth
+ *
+ * Outputs:
+ * Returns error code
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT VMSetPolyphony (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_I32 polyphonyCount)
+{
+ EAS_INT i;
+ EAS_INT activeVoices;
+
+ /* check limits */
+ if (polyphonyCount < 0)
+ return EAS_ERROR_PARAMETER_RANGE;
+
+ /* zero is max polyphony */
+ if ((polyphonyCount == 0) || (polyphonyCount > MAX_SYNTH_VOICES))
+ {
+ pSynth->maxPolyphony = 0;
+ return EAS_SUCCESS;
+ }
+
+ /* set new polyphony */
+ pSynth->maxPolyphony = (EAS_U16) polyphonyCount;
+
+ /* max polyphony is minimum of virtual synth and actual synth */
+ if (polyphonyCount > pVoiceMgr->maxPolyphony)
+ polyphonyCount = pVoiceMgr->maxPolyphony;
+
+ /* if SP-MIDI mode, update the channel muting */
+ if (pSynth->synthFlags & SYNTH_FLAG_SP_MIDI_ON)
+ VMMIPUpdateChannelMuting(pVoiceMgr, pSynth);
+ else
+ pSynth->poolAlloc[0] = (EAS_U8) polyphonyCount;
+
+ /* are we under polyphony limit? */
+ if (pSynth->numActiveVoices <= polyphonyCount)
+ return EAS_SUCCESS;
+
+ /* count the number of active voices */
+ activeVoices = 0;
+ for (i = 0; i < MAX_SYNTH_VOICES; i++)
+ {
+ /* this synth? */
+ if (GET_VSYNTH(pVoiceMgr->voices[i].nextChannel) != pSynth->vSynthNum)
+ continue;
+
+ /* is voice active? */
+ if ((pVoiceMgr->voices[i].voiceState != eVoiceStateFree) && (pVoiceMgr->voices[i].voiceState != eVoiceStateMuting))
+ activeVoices++;
+ }
+
+ /* we may have to mute voices to reach new target */
+ while (activeVoices > polyphonyCount)
+ {
+ S_SYNTH_VOICE *pVoice;
+ EAS_I32 currentPriority, bestPriority;
+ EAS_INT bestCandidate;
+
+ /* find the lowest priority voice */
+ bestPriority = bestCandidate = -1;
+ for (i = 0; i < MAX_SYNTH_VOICES; i++)
+ {
+ pVoice = &pVoiceMgr->voices[i];
+
+ /* this synth? */
+ if (GET_VSYNTH(pVoice->nextChannel) != pSynth->vSynthNum)
+ continue;
+
+ /* if voice is stolen or just started, reduce the likelihood it will be stolen */
+ if (( pVoice->voiceState == eVoiceStateStolen) || (pVoice->voiceFlags & VOICE_FLAG_NO_SAMPLES_SYNTHESIZED_YET))
+ {
+ /* include velocity */
+ currentPriority = 128 - pVoice->nextVelocity;
+
+ /* include channel priority */
+ currentPriority += pSynth->channels[GET_CHANNEL(pVoice->nextChannel)].pool << CHANNEL_PRIORITY_STEAL_WEIGHT;
+ }
+ else
+ {
+ /* include age */
+ currentPriority = (EAS_I32) pVoice->age << NOTE_AGE_STEAL_WEIGHT;
+
+ /* include note gain -higher gain is lower steal value */
+ /*lint -e{704} use shift for performance */
+ currentPriority += ((32768 >> (12 - NOTE_GAIN_STEAL_WEIGHT)) + 256) -
+ ((EAS_I32) pVoice->gain >> (12 - NOTE_GAIN_STEAL_WEIGHT));
+
+ /* include channel priority */
+ currentPriority += pSynth->channels[GET_CHANNEL(pVoice->nextChannel)].pool << CHANNEL_PRIORITY_STEAL_WEIGHT;
+ }
+
+ /* is this the best choice so far? */
+ if (currentPriority > bestPriority)
+ {
+ bestPriority = currentPriority;
+ bestCandidate = i;
+ }
+ }
+
+ /* shutdown best candidate */
+ if (bestCandidate < 0)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "VMSetPolyphony: Unable to reduce polyphony\n"); */ }
+ break;
+ }
+
+ /* shut down this voice */
+ VMMuteVoice(pVoiceMgr, bestCandidate);
+ activeVoices--;
+ }
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * VMGetPolyphony()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Get the virtual synth polyphony
+ *
+ * Inputs:
+ * pVoiceMgr pointer to synthesizer data
+ * pPolyphonyCount pointer to variable to hold polyphony count
+ * pSynth pointer to virtual synth
+ *
+ * Outputs:
+ * Returns error code
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pVoiceMgr) reserved for future use */
+EAS_RESULT VMGetPolyphony (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_I32 *pPolyphonyCount)
+{
+ *pPolyphonyCount = (EAS_U16) pSynth->maxPolyphony;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * VMSetPriority()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Set the virtual synth priority
+ *
+ * Inputs:
+ * pVoiceMgr pointer to synthesizer data
+ * priority new priority
+ * pSynth pointer to virtual synth
+ *
+ * Outputs:
+ * Returns error code
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pVoiceMgr) reserved for future use */
+EAS_RESULT VMSetPriority (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_I32 priority)
+{
+ pSynth->priority = (EAS_U8) priority ;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * VMGetPriority()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Get the virtual synth priority
+ *
+ * Inputs:
+ * pVoiceMgr pointer to synthesizer data
+ * pPriority pointer to variable to hold priority
+ * pSynth pointer to virtual synth
+ *
+ * Outputs:
+ * Returns error code
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pVoiceMgr) reserved for future use */
+EAS_RESULT VMGetPriority (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_I32 *pPriority)
+{
+ *pPriority = pSynth->priority;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * VMSetVolume()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Set the master volume for this synthesizer for this sequence.
+ *
+ * Inputs:
+ * nSynthVolume - the desired master volume
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ * overrides any previously set master volume from sysex
+ *
+ *----------------------------------------------------------------------------
+*/
+void VMSetVolume (S_SYNTH *pSynth, EAS_U16 masterVolume)
+{
+ pSynth->masterVolume = masterVolume;
+ pSynth->synthFlags |= SYNTH_FLAG_UPDATE_ALL_CHANNEL_PARAMETERS;
+}
+
+/*----------------------------------------------------------------------------
+ * VMSetPitchBendRange()
+ *----------------------------------------------------------------------------
+ * Set the pitch bend range for the given channel.
+ *----------------------------------------------------------------------------
+*/
+void VMSetPitchBendRange (S_SYNTH *pSynth, EAS_INT channel, EAS_I16 pitchBendRange)
+{
+ pSynth->channels[channel].pitchBendSensitivity = pitchBendRange;
+}
+
+/*----------------------------------------------------------------------------
+ * VMValidateEASLib()
+ *----------------------------------------------------------------------------
+ * Validates an EAS library
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT VMValidateEASLib (EAS_SNDLIB_HANDLE pEAS)
+{
+ /* validate the sound library */
+ if (pEAS)
+ {
+ if (pEAS->identifier != _EAS_LIBRARY_VERSION)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "VMValidateEASLib: Sound library mismatch in sound library: Read 0x%08x, expected 0x%08x\n",
+ pEAS->identifier, _EAS_LIBRARY_VERSION); */ }
+ return EAS_ERROR_SOUND_LIBRARY;
+ }
+
+ /* check sample rate */
+ if ((pEAS->libAttr & LIBFORMAT_SAMPLE_RATE_MASK) != _OUTPUT_SAMPLE_RATE)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "VMValidateEASLib: Sample rate mismatch in sound library: Read %lu, expected %lu\n",
+ pEAS->libAttr & LIBFORMAT_SAMPLE_RATE_MASK, _OUTPUT_SAMPLE_RATE); */ }
+ return EAS_ERROR_SOUND_LIBRARY;
+ }
+
+#ifdef _WT_SYNTH
+ /* check sample bit depth */
+#ifdef _8_BIT_SAMPLES
+ if (pEAS->libAttr & LIB_FORMAT_16_BIT_SAMPLES)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "VMValidateEASLib: Expected 8-bit samples and found 16-bit\n",
+ pEAS->libAttr & LIBFORMAT_SAMPLE_RATE_MASK, _OUTPUT_SAMPLE_RATE); */ }
+ return EAS_ERROR_SOUND_LIBRARY;
+ }
+#endif
+#ifdef _16_BIT_SAMPLES
+ if ((pEAS->libAttr & LIB_FORMAT_16_BIT_SAMPLES) == 0)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "VMValidateEASLib: Expected 16-bit samples and found 8-bit\n",
+ pEAS->libAttr & LIBFORMAT_SAMPLE_RATE_MASK, _OUTPUT_SAMPLE_RATE); */ }
+ return EAS_ERROR_SOUND_LIBRARY;
+ }
+#endif
+#endif
+ }
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * VMSetGlobalEASLib()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Sets the EAS library to be used by the synthesizer
+ *
+ * Inputs:
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT VMSetGlobalEASLib (S_VOICE_MGR *pVoiceMgr, EAS_SNDLIB_HANDLE pEAS)
+{
+ EAS_RESULT result;
+
+ result = VMValidateEASLib(pEAS);
+ if (result != EAS_SUCCESS)
+ return result;
+
+ pVoiceMgr->pGlobalEAS = pEAS;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * VMSetEASLib()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Sets the EAS library to be used by the synthesizer
+ *
+ * Inputs:
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT VMSetEASLib (S_SYNTH *pSynth, EAS_SNDLIB_HANDLE pEAS)
+{
+ EAS_RESULT result;
+
+ result = VMValidateEASLib(pEAS);
+ if (result != EAS_SUCCESS)
+ return result;
+
+ pSynth->pEAS = pEAS;
+ return EAS_SUCCESS;
+}
+
+#ifdef DLS_SYNTHESIZER
+/*----------------------------------------------------------------------------
+ * VMSetGlobalDLSLib()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Sets the DLS library to be used by the synthesizer
+ *
+ * Inputs:
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT VMSetGlobalDLSLib (EAS_DATA_HANDLE pEASData, EAS_DLSLIB_HANDLE pDLS)
+{
+
+ if (pEASData->pVoiceMgr->pGlobalDLS)
+ DLSCleanup(pEASData->hwInstData, pEASData->pVoiceMgr->pGlobalDLS);
+
+ pEASData->pVoiceMgr->pGlobalDLS = pDLS;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * VMSetDLSLib()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Sets the DLS library to be used by the synthesizer
+ *
+ * Inputs:
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT VMSetDLSLib (S_SYNTH *pSynth, EAS_DLSLIB_HANDLE pDLS)
+{
+ pSynth->pDLS = pDLS;
+ return EAS_SUCCESS;
+}
+#endif
+
+/*----------------------------------------------------------------------------
+ * VMSetTranposition()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Sets the global key transposition used by the synthesizer.
+ * Transposes all melodic instruments up or down by the specified
+ * amount. Range is limited to +/-12 semitones.
+ *
+ * Inputs:
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+void VMSetTranposition (S_SYNTH *pSynth, EAS_I32 transposition)
+{
+ pSynth->globalTranspose = (EAS_I8) transposition;
+}
+
+/*----------------------------------------------------------------------------
+ * VMGetTranposition()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Gets the global key transposition used by the synthesizer.
+ * Transposes all melodic instruments up or down by the specified
+ * amount. Range is limited to +/-12 semitones.
+ *
+ * Inputs:
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+void VMGetTranposition (S_SYNTH *pSynth, EAS_I32 *pTransposition)
+{
+ *pTransposition = pSynth->globalTranspose;
+}
+
+/*----------------------------------------------------------------------------
+ * VMGetNoteCount()
+ *----------------------------------------------------------------------------
+* Returns the total note count
+*----------------------------------------------------------------------------
+*/
+EAS_I32 VMGetNoteCount (S_SYNTH *pSynth)
+{
+ return pSynth->totalNoteCount;
+}
+
+/*----------------------------------------------------------------------------
+ * VMMIDIShutdown()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Clean up any Synth related system issues.
+ *
+ * Inputs:
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ * None
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+void VMMIDIShutdown (S_EAS_DATA *pEASData, S_SYNTH *pSynth)
+{
+ EAS_INT vSynthNum;
+
+ /* decrement reference count, free if all references are gone */
+ if (--pSynth->refCount > 0)
+ return;
+
+ vSynthNum = pSynth->vSynthNum;
+
+ /* cleanup DLS load */
+#ifdef DLS_SYNTHESIZER
+ /*lint -e{550} result used only in debugging code */
+ if (pSynth->pDLS != NULL)
+ {
+ EAS_RESULT result;
+ if ((result = DLSCleanup(pEASData->hwInstData, pSynth->pDLS)) != EAS_SUCCESS)
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "VMMIDIShutdown: Error %ld cleaning up DLS collection\n", result); */ }
+ pSynth->pDLS = NULL;
+ }
+#endif
+
+ VMReset(pEASData->pVoiceMgr, pSynth, EAS_TRUE);
+
+ /* check Configuration Module for static memory allocation */
+ if (!pEASData->staticMemoryModel)
+ EAS_HWFree(pEASData->hwInstData, pSynth);
+
+ /* clear pointer to MIDI state */
+ pEASData->pVoiceMgr->pSynth[vSynthNum] = NULL;
+}
+
+/*----------------------------------------------------------------------------
+ * VMShutdown()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Clean up any Synth related system issues.
+ *
+ * Inputs:
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ * None
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+void VMShutdown (S_EAS_DATA *pEASData)
+{
+
+ /* don't free a NULL pointer */
+ if (pEASData->pVoiceMgr == NULL)
+ return;
+
+#ifdef DLS_SYNTHESIZER
+ /* if we have a global DLS collection, clean it up */
+ if (pEASData->pVoiceMgr->pGlobalDLS)
+ {
+ DLSCleanup(pEASData->hwInstData, pEASData->pVoiceMgr->pGlobalDLS);
+ pEASData->pVoiceMgr->pGlobalDLS = NULL;
+ }
+#endif
+
+ /* check Configuration Module for static memory allocation */
+ if (!pEASData->staticMemoryModel)
+ EAS_HWFree(pEASData->hwInstData, pEASData->pVoiceMgr);
+ pEASData->pVoiceMgr = NULL;
+}
+
+#ifdef EXTERNAL_AUDIO
+/*----------------------------------------------------------------------------
+ * EAS_RegExtAudioCallback()
+ *----------------------------------------------------------------------------
+ * Register a callback for external audio processing
+ *----------------------------------------------------------------------------
+*/
+void VMRegExtAudioCallback (S_SYNTH *pSynth, EAS_VOID_PTR pInstData, EAS_EXT_PRG_CHG_FUNC cbProgChgFunc, EAS_EXT_EVENT_FUNC cbEventFunc)
+{
+ pSynth->pExtAudioInstData = pInstData;
+ pSynth->cbProgChgFunc = cbProgChgFunc;
+ pSynth->cbEventFunc = cbEventFunc;
+}
+
+/*----------------------------------------------------------------------------
+ * VMGetMIDIControllers()
+ *----------------------------------------------------------------------------
+ * Returns the MIDI controller values on the specified channel
+ *----------------------------------------------------------------------------
+*/
+void VMGetMIDIControllers (S_SYNTH *pSynth, EAS_U8 channel, S_MIDI_CONTROLLERS *pControl)
+{
+ pControl->modWheel = pSynth->channels[channel].modWheel;
+ pControl->volume = pSynth->channels[channel].volume;
+ pControl->pan = pSynth->channels[channel].pan;
+ pControl->expression = pSynth->channels[channel].expression;
+ pControl->channelPressure = pSynth->channels[channel].channelPressure;
+
+#ifdef _REVERB
+ pControl->reverbSend = pSynth->channels[channel].reverbSend;
+#endif
+
+#ifdef _CHORUSE
+ pControl->chorusSend = pSynth->channels[channel].chorusSend;
+#endif
+}
+#endif
+
+#ifdef _SPLIT_ARCHITECTURE
+/*----------------------------------------------------------------------------
+ * VMStartFrame()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Starts an audio frame
+ *
+ * Inputs:
+ *
+ * Outputs:
+ * Returns true if EAS_MixEnginePrep should be called (onboard mixing)
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_BOOL VMStartFrame (S_EAS_DATA *pEASData)
+{
+
+ /* init counter for voices starts in split architecture */
+#ifdef MAX_VOICE_STARTS
+ pVoiceMgr->numVoiceStarts = 0;
+#endif
+
+ return pFrameInterface->pfStartFrame(pEASData->pVoiceMgr->pFrameBuffer);
+}
+
+/*----------------------------------------------------------------------------
+ * VMEndFrame()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Stops an audio frame
+ *
+ * Inputs:
+ *
+ * Outputs:
+ * Returns true if EAS_MixEnginePost should be called (onboard mixing)
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_BOOL VMEndFrame (S_EAS_DATA *pEASData)
+{
+
+ return pFrameInterface->pfEndFrame(pEASData->pVoiceMgr->pFrameBuffer, pEASData->pMixBuffer, pEASData->masterGain);
+}
+#endif
+
+#ifdef TEST_HARNESS
+/*----------------------------------------------------------------------------
+ * SanityCheck()
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT VMSanityCheck (EAS_DATA_HANDLE pEASData)
+{
+ S_SYNTH_VOICE *pVoice;
+ S_SYNTH *pSynth;
+ EAS_INT i;
+ EAS_INT j;
+ EAS_INT freeVoices;
+ EAS_INT activeVoices;
+ EAS_INT playingVoices;
+ EAS_INT stolenVoices;
+ EAS_INT releasingVoices;
+ EAS_INT mutingVoices;
+ EAS_INT poolCount[MAX_VIRTUAL_SYNTHESIZERS][NUM_SYNTH_CHANNELS];
+ EAS_INT vSynthNum;
+ EAS_RESULT result = EAS_SUCCESS;
+
+ /* initialize counts */
+ EAS_HWMemSet(poolCount, 0, sizeof(poolCount));
+ freeVoices = activeVoices = playingVoices = stolenVoices = releasingVoices = mutingVoices = 0;
+
+ /* iterate through all voices */
+ for (i = 0; i < MAX_SYNTH_VOICES; i++)
+ {
+ pVoice = &pEASData->pVoiceMgr->voices[i];
+ if (pVoice->voiceState != eVoiceStateFree)
+ {
+ vSynthNum = GET_VSYNTH(pVoice->channel);
+ if (vSynthNum >= MAX_VIRTUAL_SYNTHESIZERS)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "VMSanityCheck: Voice %d has invalid virtual synth number %d\n", i, vSynthNum); */ }
+ result = EAS_FAILURE;
+ continue;
+ }
+ pSynth = pEASData->pVoiceMgr->pSynth[vSynthNum];
+
+ switch (pVoice->voiceState)
+ {
+ case eVoiceStateMuting:
+ activeVoices++;
+ mutingVoices++;
+ break;
+
+ case eVoiceStateStolen:
+ vSynthNum = GET_VSYNTH(pVoice->nextChannel);
+ if (vSynthNum >= MAX_VIRTUAL_SYNTHESIZERS)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "VMSanityCheck: Voice %d has invalid virtual synth number %d\n", i, vSynthNum); */ }
+ result = EAS_FAILURE;
+ continue;
+ }
+ pSynth = pEASData->pVoiceMgr->pSynth[vSynthNum];
+ activeVoices++;
+ stolenVoices++;
+ poolCount[vSynthNum][pSynth->channels[GET_CHANNEL(pVoice->nextChannel)].pool]++;
+ break;
+
+ case eVoiceStateStart:
+ case eVoiceStatePlay:
+ activeVoices++;
+ playingVoices++;
+ poolCount[vSynthNum][pSynth->channels[GET_CHANNEL(pVoice->channel)].pool]++;
+ break;
+
+ case eVoiceStateRelease:
+ activeVoices++;
+ releasingVoices++;
+ poolCount[vSynthNum][pSynth->channels[GET_CHANNEL(pVoice->channel)].pool]++;
+ break;
+
+ default:
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "VMSanityCheck : voice %d in invalid state\n", i); */ }
+ result = EAS_FAILURE;
+ break;
+ }
+ }
+
+ /* count free voices */
+ else
+ freeVoices++;
+ }
+
+ /* dump state info */
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "%d free\n", freeVoices); */ }
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "%d active\n", activeVoices); */ }
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "%d playing\n", playingVoices); */ }
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "%d releasing\n", releasingVoices); */ }
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "%d muting\n", mutingVoices); */ }
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "%d stolen\n", stolenVoices); */ }
+
+ if (pEASData->pVoiceMgr->activeVoices != activeVoices)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Active voice mismatch was %d should be %d\n",
+ pEASData->pVoiceMgr->activeVoices, activeVoices); */ }
+ result = EAS_FAILURE;
+ }
+
+ /* check virtual synth status */
+ for (i = 0; i < MAX_VIRTUAL_SYNTHESIZERS; i++)
+ {
+ if (pEASData->pVoiceMgr->pSynth[i] == NULL)
+ continue;
+
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Synth %d numActiveVoices: %d\n", i, pEASData->pVoiceMgr->pSynth[i]->numActiveVoices); */ }
+ if (pEASData->pVoiceMgr->pSynth[i]->numActiveVoices > MAX_SYNTH_VOICES)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "VMSanityCheck: Synth %d illegal count for numActiveVoices: %d\n", i, pEASData->pVoiceMgr->pSynth[i]->numActiveVoices); */ }
+ result = EAS_FAILURE;
+ }
+ for (j = 0; j < NUM_SYNTH_CHANNELS; j++)
+ {
+ if (poolCount[i][j] != pEASData->pVoiceMgr->pSynth[i]->poolCount[j])
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Pool count mismatch synth %d pool %d, was %d, should be %d\n",
+ i, j, pEASData->pVoiceMgr->pSynth[i]->poolCount[j], poolCount[i][j]); */ }
+ result = EAS_FAILURE;
+ }
+ }
+ }
+
+ return result;
+}
+#endif
+
+
diff --git a/arm-wt-22k/lib_src/eas_wavefile.c b/arm-wt-22k/lib_src/eas_wavefile.c
index d3f3ba0..f24bde2 100644
--- a/arm-wt-22k/lib_src/eas_wavefile.c
+++ b/arm-wt-22k/lib_src/eas_wavefile.c
@@ -1,12 +1,12 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_wavefile.c
- *
- * Contents and purpose:
- * This file implements the wave file parser.
- *
- * Copyright Sonic Network Inc. 2005
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_wavefile.c
+ *
+ * Contents and purpose:
+ * This file implements the wave file parser.
+ *
+ * Copyright Sonic Network Inc. 2005
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,849 +19,849 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 852 $
- * $Date: 2007-09-04 11:43:49 -0700 (Tue, 04 Sep 2007) $
- *----------------------------------------------------------------------------
-*/
-
-#include "eas_data.h"
-#include "eas_report.h"
-#include "eas_host.h"
-#include "eas_config.h"
-#include "eas_parser.h"
-#include "eas_pcm.h"
-#include "eas_wavefile.h"
-
-/* lint is choking on the ARM math.h file, so we declare the log10 function here */
-extern double log10(double x);
-
-/* increase gain to compensate for loss in mixer */
-#define WAVE_GAIN_OFFSET 6
-
-/* constant for 1200 / log10(2.0) */
-#define PITCH_CENTS_CONVERSION 3986.313714
-
-/*----------------------------------------------------------------------------
- * WAVE file defines
- *----------------------------------------------------------------------------
-*/
-/* RIFF chunks */
-#define CHUNK_TYPE(a,b,c,d) ( \
- ( ((EAS_U32)(a) & 0xFF) << 24 ) \
- + ( ((EAS_U32)(b) & 0xFF) << 16 ) \
- + ( ((EAS_U32)(c) & 0xFF) << 8 ) \
- + ( ((EAS_U32)(d) & 0xFF) ) )
-
-#define CHUNK_RIFF CHUNK_TYPE('R','I','F','F')
-#define CHUNK_WAVE CHUNK_TYPE('W','A','V','E')
-#define CHUNK_FMT CHUNK_TYPE('f','m','t',' ')
-#define CHUNK_DATA CHUNK_TYPE('d','a','t','a')
-#define CHUNK_LIST CHUNK_TYPE('L','I','S','T')
-#define CHUNK_INFO CHUNK_TYPE('I','N','F','O')
-#define CHUNK_INAM CHUNK_TYPE('I','N','A','M')
-#define CHUNK_ICOP CHUNK_TYPE('I','C','O','P')
-#define CHUNK_IART CHUNK_TYPE('I','A','R','T')
-
-/* wave file format identifiers */
-#define WAVE_FORMAT_PCM 0x0001
-#define WAVE_FORMAT_IMA_ADPCM 0x0011
-
-/* file size for streamed file */
-#define FILE_SIZE_STREAMING 0x80000000
-
-/*----------------------------------------------------------------------------
- * prototypes
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT WaveCheckFileType (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle, EAS_VOID_PTR *pHandle, EAS_I32 offset);
-static EAS_RESULT WavePrepare (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
-static EAS_RESULT WaveState (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_STATE *pState);
-static EAS_RESULT WaveClose (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
-static EAS_RESULT WaveReset (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
-static EAS_RESULT WaveLocate (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 time, EAS_BOOL *pParserLocate);
-static EAS_RESULT WavePause (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
-static EAS_RESULT WaveResume (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
-static EAS_RESULT WaveSetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value);
-static EAS_RESULT WaveGetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue);
-static EAS_RESULT WaveParseHeader (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle, S_WAVE_STATE *pWaveData);
-static EAS_RESULT WaveGetMetaData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 *pMediaLength);
-
-#ifdef MMAPI_SUPPORT
-static EAS_RESULT SaveFmtChunk (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle, S_WAVE_STATE *pWaveData, EAS_I32 size);
-#endif
-
-/*----------------------------------------------------------------------------
- *
- * EAS_Wave_Parser
- *
- * This structure contains the functional interface for the Wave file parser
- *----------------------------------------------------------------------------
-*/
-const S_FILE_PARSER_INTERFACE EAS_Wave_Parser =
-{
- WaveCheckFileType,
- WavePrepare,
- NULL,
- NULL,
- WaveState,
- WaveClose,
- WaveReset,
- WavePause,
- WaveResume,
- WaveLocate,
- WaveSetData,
- WaveGetData,
- WaveGetMetaData
-};
-
-/*----------------------------------------------------------------------------
- * WaveCheckFileType()
- *----------------------------------------------------------------------------
- * Purpose:
- * Check the file type to see if we can parse it
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT WaveCheckFileType (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle, EAS_VOID_PTR *pHandle, EAS_I32 offset)
-{
- S_WAVE_STATE *pWaveData;
-
- /* zero the memory to insure complete initialization */
- *pHandle = NULL;
-
- /* read the file header */
- if (WaveParseHeader(pEASData, fileHandle, NULL) == EAS_SUCCESS)
- {
-
- /* check for static memory allocation */
- if (pEASData->staticMemoryModel)
- pWaveData = EAS_CMEnumData(EAS_CM_WAVE_DATA);
- else
- pWaveData = EAS_HWMalloc(pEASData->hwInstData, sizeof(S_WAVE_STATE));
- if (!pWaveData)
- return EAS_ERROR_MALLOC_FAILED;
- EAS_HWMemSet(pWaveData, 0, sizeof(S_WAVE_STATE));
-
- /* return a pointer to the instance data */
- pWaveData->fileHandle = fileHandle;
- pWaveData->fileOffset = offset;
- *pHandle = pWaveData;
- }
-
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * WavePrepare()
- *----------------------------------------------------------------------------
- * Purpose:
- * Prepare to parse the file.
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT WavePrepare (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
-{
- S_WAVE_STATE *pWaveData;
- EAS_RESULT result;
-
- /* validate parser state */
- pWaveData = (S_WAVE_STATE*) pInstData;
- if (pWaveData->streamHandle != NULL)
- return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
-
- /* back to start of file */
- pWaveData->time = 0;
- if ((result = EAS_HWFileSeek(pEASData->hwInstData, pWaveData->fileHandle, pWaveData->fileOffset)) != EAS_SUCCESS)
- return result;
-
- /* parse the file header */
- if ((result = WaveParseHeader(pEASData, pWaveData->fileHandle, pWaveData)) != EAS_SUCCESS)
- return result;
-
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * WaveState()
- *----------------------------------------------------------------------------
- * Purpose:
- * Returns the current state of the stream
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- * pState - pointer to variable to store state
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- * Notes:
- * This interface is also exposed in the internal library for use by the other modules.
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT WaveState (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_STATE *pState)
-{
- S_WAVE_STATE *pWaveData;
-
- /* return current state */
- pWaveData = (S_WAVE_STATE*) pInstData;
- if (pWaveData->streamHandle)
- return EAS_PEState(pEASData, pWaveData->streamHandle, pState);
-
- /* if no stream handle, and time is not zero, we are done */
- if (pWaveData->time > 0)
- *pState = EAS_STATE_STOPPED;
- else
- *pState = EAS_STATE_OPEN;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * WaveClose()
- *----------------------------------------------------------------------------
- * Purpose:
- * Close the file and clean up
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT WaveClose (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
-{
- S_WAVE_STATE *pWaveData;
- EAS_RESULT result;
-
- pWaveData = (S_WAVE_STATE*) pInstData;
-
- /* close the stream */
- if (pWaveData->streamHandle)
- {
- if ((result = EAS_PEClose(pEASData, pWaveData->streamHandle)) != EAS_SUCCESS)
- return result;
- pWaveData->streamHandle = NULL;
- }
-
- /* if using dynamic memory, free it */
- if (!pEASData->staticMemoryModel)
- {
-
-#ifdef MMAPI_SUPPORT
- /* need to free the fmt chunk */
- if (pWaveData->fmtChunk != NULL)
- EAS_HWFree(pEASData->hwInstData, pWaveData->fmtChunk);
-#endif
-
- /* free the instance data */
- EAS_HWFree(pEASData->hwInstData, pWaveData);
-
- }
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * WaveReset()
- *----------------------------------------------------------------------------
- * Purpose:
- * Reset the sequencer. Used for locating backwards in the file.
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT WaveReset (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
-{
- EAS_PCM_HANDLE streamHandle;
-
- /* reset to first byte of data in the stream */
- streamHandle = ((S_WAVE_STATE*)pInstData)->streamHandle;
- if (streamHandle)
- return EAS_PEReset(pEASData, streamHandle);
- return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
-}
-
-/*----------------------------------------------------------------------------
- * WaveLocate()
- *----------------------------------------------------------------------------
- * Purpose:
- * Rewind/fast-forward in file.
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- * time - time (in msecs)
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, pParserLocate) reserved for future use */
-static EAS_RESULT WaveLocate (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 time, EAS_BOOL *pParserLocate)
-{
- EAS_PCM_HANDLE streamHandle;
-
- /* reset to first byte of data in the stream */
- streamHandle = ((S_WAVE_STATE*)pInstData)->streamHandle;
- if (streamHandle)
- return EAS_PELocate(pEASData, streamHandle, time);
- return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
-}
-
-/*----------------------------------------------------------------------------
- * WavePause()
- *----------------------------------------------------------------------------
- * Purpose:
- * Mute and stop rendering a PCM stream. Sets the gain target to zero and stops the playback
- * at the end of the next audio frame.
- *
- * Inputs:
- * pEASData - pointer to EAS library instance data
- * handle - pointer to S_WAVE_STATE for this stream
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, pEASData) reserved for future use */
-static EAS_RESULT WavePause (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
-{
- EAS_PCM_HANDLE streamHandle;
-
- /* pause the stream */
- streamHandle = ((S_WAVE_STATE*)pInstData)->streamHandle;
- if (streamHandle)
- return EAS_PEPause(pEASData, streamHandle);
- return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
-}
-
-/*----------------------------------------------------------------------------
- * WaveResume()
- *----------------------------------------------------------------------------
- * Purpose:
- * Resume rendering a PCM stream. Sets the gain target back to its
- * previous setting and restarts playback at the end of the next audio
- * frame.
- *
- * Inputs:
- * pEASData - pointer to EAS library instance data
- * handle - pointer to S_WAVE_STATE for this stream
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, pEASData) reserved for future use */
-static EAS_RESULT WaveResume (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
-{
- EAS_PCM_HANDLE streamHandle;
-
- /* resume the stream */
- streamHandle = ((S_WAVE_STATE*)pInstData)->streamHandle;
- if (streamHandle)
- return EAS_PEResume(pEASData, streamHandle);
- return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
-}
-
-/*----------------------------------------------------------------------------
- * WaveSetData()
- *----------------------------------------------------------------------------
- * Purpose:
- *
- * Inputs:
- * pEASData - pointer to EAS library instance data
- * handle - pointer to S_WAVE_STATE for this stream
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT WaveSetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value)
-{
- S_WAVE_STATE *pWaveData = (S_WAVE_STATE*) pInstData;
-
- switch (param)
- {
- /* set metadata callback */
- case PARSER_DATA_METADATA_CB:
- EAS_HWMemCpy(&pWaveData->metadata, (void*) value, sizeof(S_METADATA_CB));
- return EAS_SUCCESS;
-
- case PARSER_DATA_PLAYBACK_RATE:
- value = (EAS_I32) (PITCH_CENTS_CONVERSION * log10((double) value / (double) (1 << 28)));
- return EAS_PEUpdatePitch(pEASData, pWaveData->streamHandle, (EAS_I16) value);
-
- case PARSER_DATA_VOLUME:
- return EAS_PEUpdateVolume(pEASData, pWaveData->streamHandle, (EAS_I16) value);
-
- default:
- return EAS_ERROR_INVALID_PARAMETER;
- }
-}
-
-/*----------------------------------------------------------------------------
- * WaveGetData()
- *----------------------------------------------------------------------------
- * Purpose:
- *
- * Inputs:
- * pEASData - pointer to EAS library instance data
- * handle - pointer to S_WAVE_STATE for this stream
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, pEASData) reserved for future use */
-static EAS_RESULT WaveGetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue)
-{
- S_WAVE_STATE *pWaveData;
-
- pWaveData = (S_WAVE_STATE*) pInstData;
- switch (param)
- {
- /* return file type as WAVE */
- case PARSER_DATA_FILE_TYPE:
- *pValue = pWaveData->fileType;
- break;
-
-#ifdef MMAPI_SUPPORT
- /* return pointer to 'fmt' chunk */
- case PARSER_DATA_FORMAT:
- *pValue = (EAS_I32) pWaveData->fmtChunk;
- break;
-#endif
-
- case PARSER_DATA_GAIN_OFFSET:
- *pValue = WAVE_GAIN_OFFSET;
- break;
-
- default:
- return EAS_ERROR_INVALID_PARAMETER;
- }
-
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * WaveParseHeader()
- *----------------------------------------------------------------------------
- * Purpose:
- * Parse the WAVE file header.
- *
- * Inputs:
- * pEASData - pointer to EAS library instance data
- * handle - pointer to S_WAVE_STATE for this stream
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT WaveParseHeader (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle, S_WAVE_STATE *pWaveData)
-{
- S_PCM_OPEN_PARAMS params;
- EAS_RESULT result;
- EAS_U32 tag;
- EAS_U32 fileSize;
- EAS_U32 size;
- EAS_I32 pos;
- EAS_I32 audioOffset;
- EAS_U16 usTemp;
- EAS_BOOL parseDone;
- EAS_U32 avgBytesPerSec;
-
- /* init some data (and keep lint happy) */
- params.sampleRate = 0;
- params.size = 0;
- audioOffset = 0;
- params.decoder = 0;
- params.blockSize = 0;
- params.pCallbackFunc = NULL;
- params.cbInstData = NULL;
- params.loopSamples = 0;
- params.fileHandle = fileHandle;
- params.volume = 0x7fff;
- params.envData = 0;
- avgBytesPerSec = 8000;
-
- /* check for 'RIFF' tag */
- if ((result = EAS_HWGetDWord(pEASData->hwInstData, fileHandle, &tag, EAS_TRUE)) != EAS_FALSE)
- return result;
- if (tag != CHUNK_RIFF)
- return EAS_ERROR_UNRECOGNIZED_FORMAT;
-
- /* get size */
- if ((result = EAS_HWGetDWord(pEASData->hwInstData, fileHandle, &fileSize, EAS_FALSE)) != EAS_FALSE)
- return result;
-
- /* check for 'WAVE' tag */
- if ((result = EAS_HWGetDWord(pEASData->hwInstData, fileHandle, &tag, EAS_TRUE)) != EAS_FALSE)
- return result;
- if (tag != CHUNK_WAVE)
- return EAS_ERROR_UNRECOGNIZED_FORMAT;
-
- /* this is enough to say we recognize the file */
- if (pWaveData == NULL)
- return EAS_SUCCESS;
-
- /* check for streaming mode */
- pWaveData->flags = 0;
- pWaveData->mediaLength = -1;
- pWaveData->infoChunkPos = -1;
- pWaveData->infoChunkSize = -1;
- if (fileSize== FILE_SIZE_STREAMING)
- {
- pWaveData->flags |= PCM_FLAGS_STREAMING;
- fileSize = 0x7fffffff;
- }
-
- /* find out where we're at */
- if ((result = EAS_HWFilePos(pEASData->hwInstData, fileHandle, &pos)) != EAS_SUCCESS)
- return result;
- fileSize -= 4;
-
- parseDone = EAS_FALSE;
- for (;;)
- {
- /* get tag and size for next chunk */
- if ((result = EAS_HWGetDWord(pEASData->hwInstData, fileHandle, &tag, EAS_TRUE)) != EAS_FALSE)
- return result;
- if ((result = EAS_HWGetDWord(pEASData->hwInstData, fileHandle, &size, EAS_FALSE)) != EAS_FALSE)
- return result;
-
- /* process chunk */
- pos += 8;
- switch (tag)
- {
- case CHUNK_FMT:
-
-#ifdef MMAPI_SUPPORT
- if ((result = SaveFmtChunk(pEASData, fileHandle, pWaveData, (EAS_I32) size)) != EAS_SUCCESS)
- return result;
-#endif
-
- /* get audio format */
- if ((result = EAS_HWGetWord(pEASData->hwInstData, fileHandle, &usTemp, EAS_FALSE)) != EAS_FALSE)
- return result;
- if (usTemp == WAVE_FORMAT_PCM)
- {
- params.decoder = EAS_DECODER_PCM;
- pWaveData->fileType = EAS_FILE_WAVE_PCM;
- }
- else if (usTemp == WAVE_FORMAT_IMA_ADPCM)
- {
- params.decoder = EAS_DECODER_IMA_ADPCM;
- pWaveData->fileType = EAS_FILE_WAVE_IMA_ADPCM;
- }
- else
- return EAS_ERROR_UNRECOGNIZED_FORMAT;
-
- /* get number of channels */
- if ((result = EAS_HWGetWord(pEASData->hwInstData, fileHandle, &usTemp, EAS_FALSE)) != EAS_FALSE)
- return result;
- if (usTemp == 2)
- pWaveData->flags |= PCM_FLAGS_STEREO;
- else if (usTemp != 1)
- return EAS_ERROR_UNRECOGNIZED_FORMAT;
-
- /* get sample rate */
- if ((result = EAS_HWGetDWord(pEASData->hwInstData, fileHandle, &params.sampleRate, EAS_FALSE)) != EAS_FALSE)
- return result;
-
- /* get stream rate */
- if ((result = EAS_HWGetDWord(pEASData->hwInstData, fileHandle, &avgBytesPerSec, EAS_FALSE)) != EAS_FALSE)
- return result;
-
- /* get block alignment */
- if ((result = EAS_HWGetWord(pEASData->hwInstData, fileHandle, &usTemp, EAS_FALSE)) != EAS_FALSE)
- return result;
- params.blockSize = usTemp;
-
- /* get bits per sample */
- if ((result = EAS_HWGetWord(pEASData->hwInstData, fileHandle, &usTemp, EAS_FALSE)) != EAS_FALSE)
- return result;
-
- /* PCM, must be 8 or 16 bit samples */
- if (params.decoder == EAS_DECODER_PCM)
- {
- if (usTemp == 8)
- pWaveData->flags |= PCM_FLAGS_8_BIT | PCM_FLAGS_UNSIGNED;
- else if (usTemp != 16)
- return EAS_ERROR_UNRECOGNIZED_FORMAT;
- }
-
- /* for IMA ADPCM, we only support mono 4-bit ADPCM */
- else
- {
- if ((usTemp != 4) || (pWaveData->flags & PCM_FLAGS_STEREO))
- return EAS_ERROR_UNRECOGNIZED_FORMAT;
- }
-
- break;
-
- case CHUNK_DATA:
- audioOffset = pos;
- if (pWaveData->flags & PCM_FLAGS_STREAMING)
- {
- params.size = 0x7fffffff;
- parseDone = EAS_TRUE;
- }
- else
- {
- params.size = (EAS_I32) size;
- params.loopStart = size;
- /* use more accurate method if possible */
- if (size <= (0x7fffffff / 1000))
- pWaveData->mediaLength = (EAS_I32) ((size * 1000) / avgBytesPerSec);
- else
- pWaveData->mediaLength = (EAS_I32) (size / (avgBytesPerSec / 1000));
- }
- break;
-
- case CHUNK_LIST:
- /* get the list type */
- if ((result = EAS_HWGetDWord(pEASData->hwInstData, fileHandle, &tag, EAS_TRUE)) != EAS_FALSE)
- return result;
- if (tag == CHUNK_INFO)
- {
- pWaveData->infoChunkPos = pos + 4;
- pWaveData->infoChunkSize = (EAS_I32) size - 4;
- }
- break;
-
- default:
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "WaveParseHeader: %c%c%c%c chunk - %d byte(s) ignored\n",
- (char) (tag >> 24), (char) (tag >> 16), (char) (tag >> 8), (char) tag, size); */ }
- break;
- }
-
- if (parseDone)
- break;
-
- /* subtract header size */
- fileSize -= 8;
-
- /* account for zero-padding on odd length chunks */
- if (size & 1)
- size++;
-
- /* this check works for files with odd length last chunk and no zero-pad */
- if (size >= fileSize)
- {
- if (size > fileSize)
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "WaveParseHeader: '%c%c%c%c' chunk size exceeds length of file or is not zero-padded\n",
- (char) (tag >> 24), (char) (tag >> 16), (char) (tag >> 8), (char) tag, size); */ }
- break;
- }
-
- /* subtract size of data chunk (including any zero-pad) */
- fileSize -= size;
-
- /* seek to next chunk */
- pos += (EAS_I32) size;
- if ((result = EAS_HWFileSeek(pEASData->hwInstData, fileHandle, pos)) != EAS_SUCCESS)
- return result;
- }
-
- /* check for valid header */
- if ((params.sampleRate == 0) || (params.size == 0))
- return EAS_ERROR_UNRECOGNIZED_FORMAT;
-
- /* save the pertinent information */
- pWaveData->audioOffset = audioOffset;
- params.flags = pWaveData->flags;
-
- /* seek to data */
- if ((result = EAS_HWFileSeek(pEASData->hwInstData, fileHandle, audioOffset)) != EAS_SUCCESS)
- return result;
-
- /* open a stream in the PCM engine */
- return EAS_PEOpenStream(pEASData, &params, &pWaveData->streamHandle);
-}
-
-/*----------------------------------------------------------------------------
- * WaveGetMetaData()
- *----------------------------------------------------------------------------
- * Purpose:
- * Process the INFO chunk and return metadata to host
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT WaveGetMetaData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 *pMediaLength)
-{
- S_WAVE_STATE *pWaveData;
- EAS_RESULT result;
- EAS_I32 pos;
- EAS_U32 size;
- EAS_I32 infoSize;
- EAS_U32 tag;
- EAS_I32 restorePos;
- E_EAS_METADATA_TYPE metaType;
- EAS_I32 metaLen;
-
- /* get current position so we can restore it */
- pWaveData = (S_WAVE_STATE*) pInstData;
-
- /* return media length */
- *pMediaLength = pWaveData->mediaLength;
-
- /* did we encounter an INFO chunk? */
- if (pWaveData->infoChunkPos < 0)
- return EAS_SUCCESS;
-
- if ((result = EAS_HWFilePos(pEASData->hwInstData, pWaveData->fileHandle, &restorePos)) != EAS_SUCCESS)
- return result;
-
- /* offset to start of first chunk in INFO chunk */
- pos = pWaveData->infoChunkPos;
- infoSize = pWaveData->infoChunkSize;
-
- /* read all the chunks in the INFO chunk */
- for (;;)
- {
-
- /* seek to next chunk */
- if ((result = EAS_HWFileSeek(pEASData->hwInstData, pWaveData->fileHandle, pos)) != EAS_SUCCESS)
- return result;
-
- /* get tag and size for next chunk */
- if ((result = EAS_HWGetDWord(pEASData->hwInstData, pWaveData->fileHandle, &tag, EAS_TRUE)) != EAS_FALSE)
- return result;
- if ((result = EAS_HWGetDWord(pEASData->hwInstData, pWaveData->fileHandle, &size, EAS_FALSE)) != EAS_FALSE)
- return result;
-
- /* process chunk */
- pos += 8;
- metaType = EAS_METADATA_UNKNOWN;
- switch (tag)
- {
- case CHUNK_INAM:
- metaType = EAS_METADATA_TITLE;
- break;
-
- case CHUNK_IART:
- metaType = EAS_METADATA_AUTHOR;
- break;
-
- case CHUNK_ICOP:
- metaType = EAS_METADATA_COPYRIGHT;
- break;
-
- default:
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "WaveParseHeader: %c%c%c%c chunk - %d byte(s) ignored\n",
- (char) (tag >> 24), (char) (tag >> 16), (char) (tag >> 8), (char) tag, size); */ }
- break;
- }
-
- /* process known metadata */
- if (metaType != EAS_METADATA_UNKNOWN)
- {
- metaLen = pWaveData->metadata.bufferSize - 1;
- if (metaLen > (EAS_I32) size)
- metaLen = (EAS_I32) size;
- if ((result = EAS_HWReadFile(pEASData->hwInstData, pWaveData->fileHandle, pWaveData->metadata.buffer, metaLen, &metaLen)) != EAS_SUCCESS)
- return result;
- pWaveData->metadata.buffer[metaLen] = 0;
- pWaveData->metadata.callback(metaType, pWaveData->metadata.buffer, pWaveData->metadata.pUserData);
- }
-
- /* subtract this block */
- if (size & 1)
- size++;
- infoSize -= (EAS_I32) size + 8;
- if (infoSize == 0)
- break;
- pos += (EAS_I32) size;
- }
-
-
- /* restore original position */
- return EAS_HWFileSeek(pEASData->hwInstData, pWaveData->fileHandle, restorePos);
-}
-
-#ifdef MMAPI_SUPPORT
-/*----------------------------------------------------------------------------
- * SaveFmtChunk()
- *----------------------------------------------------------------------------
- * Purpose:
- * Save the fmt chunk for the MMAPI library
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT SaveFmtChunk (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle, S_WAVE_STATE *pWaveData, EAS_I32 fmtSize)
-{
- EAS_RESULT result;
- EAS_I32 pos;
- EAS_I32 count;
-
- /* save current file position */
- if ((result = EAS_HWFilePos(pEASData->hwInstData, fileHandle, &pos)) != EAS_SUCCESS)
- return result;
-
- /* allocate a chunk of memory */
- pWaveData->fmtChunk = EAS_HWMalloc(pEASData->hwInstData, fmtSize);
- if (!pWaveData->fmtChunk)
- return EAS_ERROR_MALLOC_FAILED;
-
- /* read the fmt chunk into memory */
- if ((result = EAS_HWReadFile(pEASData->hwInstData, fileHandle, pWaveData->fmtChunk, fmtSize, &count)) != EAS_SUCCESS)
- return result;
- if (count != fmtSize)
- return EAS_ERROR_FILE_READ_FAILED;
-
- /* restore file position */
- return EAS_HWFileSeek(pEASData->hwInstData, fileHandle, pos);
-}
-#endif
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 852 $
+ * $Date: 2007-09-04 11:43:49 -0700 (Tue, 04 Sep 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+#include "eas_data.h"
+#include "eas_report.h"
+#include "eas_host.h"
+#include "eas_config.h"
+#include "eas_parser.h"
+#include "eas_pcm.h"
+#include "eas_wavefile.h"
+
+/* lint is choking on the ARM math.h file, so we declare the log10 function here */
+extern double log10(double x);
+
+/* increase gain to compensate for loss in mixer */
+#define WAVE_GAIN_OFFSET 6
+
+/* constant for 1200 / log10(2.0) */
+#define PITCH_CENTS_CONVERSION 3986.313714
+
+/*----------------------------------------------------------------------------
+ * WAVE file defines
+ *----------------------------------------------------------------------------
+*/
+/* RIFF chunks */
+#define CHUNK_TYPE(a,b,c,d) ( \
+ ( ((EAS_U32)(a) & 0xFF) << 24 ) \
+ + ( ((EAS_U32)(b) & 0xFF) << 16 ) \
+ + ( ((EAS_U32)(c) & 0xFF) << 8 ) \
+ + ( ((EAS_U32)(d) & 0xFF) ) )
+
+#define CHUNK_RIFF CHUNK_TYPE('R','I','F','F')
+#define CHUNK_WAVE CHUNK_TYPE('W','A','V','E')
+#define CHUNK_FMT CHUNK_TYPE('f','m','t',' ')
+#define CHUNK_DATA CHUNK_TYPE('d','a','t','a')
+#define CHUNK_LIST CHUNK_TYPE('L','I','S','T')
+#define CHUNK_INFO CHUNK_TYPE('I','N','F','O')
+#define CHUNK_INAM CHUNK_TYPE('I','N','A','M')
+#define CHUNK_ICOP CHUNK_TYPE('I','C','O','P')
+#define CHUNK_IART CHUNK_TYPE('I','A','R','T')
+
+/* wave file format identifiers */
+#define WAVE_FORMAT_PCM 0x0001
+#define WAVE_FORMAT_IMA_ADPCM 0x0011
+
+/* file size for streamed file */
+#define FILE_SIZE_STREAMING 0x80000000
+
+/*----------------------------------------------------------------------------
+ * prototypes
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT WaveCheckFileType (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle, EAS_VOID_PTR *pHandle, EAS_I32 offset);
+static EAS_RESULT WavePrepare (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
+static EAS_RESULT WaveState (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_STATE *pState);
+static EAS_RESULT WaveClose (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
+static EAS_RESULT WaveReset (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
+static EAS_RESULT WaveLocate (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 time, EAS_BOOL *pParserLocate);
+static EAS_RESULT WavePause (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
+static EAS_RESULT WaveResume (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
+static EAS_RESULT WaveSetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value);
+static EAS_RESULT WaveGetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue);
+static EAS_RESULT WaveParseHeader (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle, S_WAVE_STATE *pWaveData);
+static EAS_RESULT WaveGetMetaData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 *pMediaLength);
+
+#ifdef MMAPI_SUPPORT
+static EAS_RESULT SaveFmtChunk (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle, S_WAVE_STATE *pWaveData, EAS_I32 size);
+#endif
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_Wave_Parser
+ *
+ * This structure contains the functional interface for the Wave file parser
+ *----------------------------------------------------------------------------
+*/
+const S_FILE_PARSER_INTERFACE EAS_Wave_Parser =
+{
+ WaveCheckFileType,
+ WavePrepare,
+ NULL,
+ NULL,
+ WaveState,
+ WaveClose,
+ WaveReset,
+ WavePause,
+ WaveResume,
+ WaveLocate,
+ WaveSetData,
+ WaveGetData,
+ WaveGetMetaData
+};
+
+/*----------------------------------------------------------------------------
+ * WaveCheckFileType()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Check the file type to see if we can parse it
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT WaveCheckFileType (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle, EAS_VOID_PTR *pHandle, EAS_I32 offset)
+{
+ S_WAVE_STATE *pWaveData;
+
+ /* zero the memory to insure complete initialization */
+ *pHandle = NULL;
+
+ /* read the file header */
+ if (WaveParseHeader(pEASData, fileHandle, NULL) == EAS_SUCCESS)
+ {
+
+ /* check for static memory allocation */
+ if (pEASData->staticMemoryModel)
+ pWaveData = EAS_CMEnumData(EAS_CM_WAVE_DATA);
+ else
+ pWaveData = EAS_HWMalloc(pEASData->hwInstData, sizeof(S_WAVE_STATE));
+ if (!pWaveData)
+ return EAS_ERROR_MALLOC_FAILED;
+ EAS_HWMemSet(pWaveData, 0, sizeof(S_WAVE_STATE));
+
+ /* return a pointer to the instance data */
+ pWaveData->fileHandle = fileHandle;
+ pWaveData->fileOffset = offset;
+ *pHandle = pWaveData;
+ }
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * WavePrepare()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Prepare to parse the file.
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT WavePrepare (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
+{
+ S_WAVE_STATE *pWaveData;
+ EAS_RESULT result;
+
+ /* validate parser state */
+ pWaveData = (S_WAVE_STATE*) pInstData;
+ if (pWaveData->streamHandle != NULL)
+ return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
+
+ /* back to start of file */
+ pWaveData->time = 0;
+ if ((result = EAS_HWFileSeek(pEASData->hwInstData, pWaveData->fileHandle, pWaveData->fileOffset)) != EAS_SUCCESS)
+ return result;
+
+ /* parse the file header */
+ if ((result = WaveParseHeader(pEASData, pWaveData->fileHandle, pWaveData)) != EAS_SUCCESS)
+ return result;
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * WaveState()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Returns the current state of the stream
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ * pState - pointer to variable to store state
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ * Notes:
+ * This interface is also exposed in the internal library for use by the other modules.
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT WaveState (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_STATE *pState)
+{
+ S_WAVE_STATE *pWaveData;
+
+ /* return current state */
+ pWaveData = (S_WAVE_STATE*) pInstData;
+ if (pWaveData->streamHandle)
+ return EAS_PEState(pEASData, pWaveData->streamHandle, pState);
+
+ /* if no stream handle, and time is not zero, we are done */
+ if (pWaveData->time > 0)
+ *pState = EAS_STATE_STOPPED;
+ else
+ *pState = EAS_STATE_OPEN;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * WaveClose()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Close the file and clean up
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT WaveClose (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
+{
+ S_WAVE_STATE *pWaveData;
+ EAS_RESULT result;
+
+ pWaveData = (S_WAVE_STATE*) pInstData;
+
+ /* close the stream */
+ if (pWaveData->streamHandle)
+ {
+ if ((result = EAS_PEClose(pEASData, pWaveData->streamHandle)) != EAS_SUCCESS)
+ return result;
+ pWaveData->streamHandle = NULL;
+ }
+
+ /* if using dynamic memory, free it */
+ if (!pEASData->staticMemoryModel)
+ {
+
+#ifdef MMAPI_SUPPORT
+ /* need to free the fmt chunk */
+ if (pWaveData->fmtChunk != NULL)
+ EAS_HWFree(pEASData->hwInstData, pWaveData->fmtChunk);
+#endif
+
+ /* free the instance data */
+ EAS_HWFree(pEASData->hwInstData, pWaveData);
+
+ }
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * WaveReset()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Reset the sequencer. Used for locating backwards in the file.
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT WaveReset (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
+{
+ EAS_PCM_HANDLE streamHandle;
+
+ /* reset to first byte of data in the stream */
+ streamHandle = ((S_WAVE_STATE*)pInstData)->streamHandle;
+ if (streamHandle)
+ return EAS_PEReset(pEASData, streamHandle);
+ return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
+}
+
+/*----------------------------------------------------------------------------
+ * WaveLocate()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Rewind/fast-forward in file.
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ * time - time (in msecs)
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pParserLocate) reserved for future use */
+static EAS_RESULT WaveLocate (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 time, EAS_BOOL *pParserLocate)
+{
+ EAS_PCM_HANDLE streamHandle;
+
+ /* reset to first byte of data in the stream */
+ streamHandle = ((S_WAVE_STATE*)pInstData)->streamHandle;
+ if (streamHandle)
+ return EAS_PELocate(pEASData, streamHandle, time);
+ return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
+}
+
+/*----------------------------------------------------------------------------
+ * WavePause()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Mute and stop rendering a PCM stream. Sets the gain target to zero and stops the playback
+ * at the end of the next audio frame.
+ *
+ * Inputs:
+ * pEASData - pointer to EAS library instance data
+ * handle - pointer to S_WAVE_STATE for this stream
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pEASData) reserved for future use */
+static EAS_RESULT WavePause (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
+{
+ EAS_PCM_HANDLE streamHandle;
+
+ /* pause the stream */
+ streamHandle = ((S_WAVE_STATE*)pInstData)->streamHandle;
+ if (streamHandle)
+ return EAS_PEPause(pEASData, streamHandle);
+ return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
+}
+
+/*----------------------------------------------------------------------------
+ * WaveResume()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Resume rendering a PCM stream. Sets the gain target back to its
+ * previous setting and restarts playback at the end of the next audio
+ * frame.
+ *
+ * Inputs:
+ * pEASData - pointer to EAS library instance data
+ * handle - pointer to S_WAVE_STATE for this stream
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pEASData) reserved for future use */
+static EAS_RESULT WaveResume (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
+{
+ EAS_PCM_HANDLE streamHandle;
+
+ /* resume the stream */
+ streamHandle = ((S_WAVE_STATE*)pInstData)->streamHandle;
+ if (streamHandle)
+ return EAS_PEResume(pEASData, streamHandle);
+ return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
+}
+
+/*----------------------------------------------------------------------------
+ * WaveSetData()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ *
+ * Inputs:
+ * pEASData - pointer to EAS library instance data
+ * handle - pointer to S_WAVE_STATE for this stream
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT WaveSetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value)
+{
+ S_WAVE_STATE *pWaveData = (S_WAVE_STATE*) pInstData;
+
+ switch (param)
+ {
+ /* set metadata callback */
+ case PARSER_DATA_METADATA_CB:
+ EAS_HWMemCpy(&pWaveData->metadata, (void*) value, sizeof(S_METADATA_CB));
+ return EAS_SUCCESS;
+
+ case PARSER_DATA_PLAYBACK_RATE:
+ value = (EAS_I32) (PITCH_CENTS_CONVERSION * log10((double) value / (double) (1 << 28)));
+ return EAS_PEUpdatePitch(pEASData, pWaveData->streamHandle, (EAS_I16) value);
+
+ case PARSER_DATA_VOLUME:
+ return EAS_PEUpdateVolume(pEASData, pWaveData->streamHandle, (EAS_I16) value);
+
+ default:
+ return EAS_ERROR_INVALID_PARAMETER;
+ }
+}
+
+/*----------------------------------------------------------------------------
+ * WaveGetData()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ *
+ * Inputs:
+ * pEASData - pointer to EAS library instance data
+ * handle - pointer to S_WAVE_STATE for this stream
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pEASData) reserved for future use */
+static EAS_RESULT WaveGetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue)
+{
+ S_WAVE_STATE *pWaveData;
+
+ pWaveData = (S_WAVE_STATE*) pInstData;
+ switch (param)
+ {
+ /* return file type as WAVE */
+ case PARSER_DATA_FILE_TYPE:
+ *pValue = pWaveData->fileType;
+ break;
+
+#ifdef MMAPI_SUPPORT
+ /* return pointer to 'fmt' chunk */
+ case PARSER_DATA_FORMAT:
+ *pValue = (EAS_I32) pWaveData->fmtChunk;
+ break;
+#endif
+
+ case PARSER_DATA_GAIN_OFFSET:
+ *pValue = WAVE_GAIN_OFFSET;
+ break;
+
+ default:
+ return EAS_ERROR_INVALID_PARAMETER;
+ }
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * WaveParseHeader()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Parse the WAVE file header.
+ *
+ * Inputs:
+ * pEASData - pointer to EAS library instance data
+ * handle - pointer to S_WAVE_STATE for this stream
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT WaveParseHeader (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle, S_WAVE_STATE *pWaveData)
+{
+ S_PCM_OPEN_PARAMS params;
+ EAS_RESULT result;
+ EAS_U32 tag;
+ EAS_U32 fileSize;
+ EAS_U32 size;
+ EAS_I32 pos;
+ EAS_I32 audioOffset;
+ EAS_U16 usTemp;
+ EAS_BOOL parseDone;
+ EAS_U32 avgBytesPerSec;
+
+ /* init some data (and keep lint happy) */
+ params.sampleRate = 0;
+ params.size = 0;
+ audioOffset = 0;
+ params.decoder = 0;
+ params.blockSize = 0;
+ params.pCallbackFunc = NULL;
+ params.cbInstData = NULL;
+ params.loopSamples = 0;
+ params.fileHandle = fileHandle;
+ params.volume = 0x7fff;
+ params.envData = 0;
+ avgBytesPerSec = 8000;
+
+ /* check for 'RIFF' tag */
+ if ((result = EAS_HWGetDWord(pEASData->hwInstData, fileHandle, &tag, EAS_TRUE)) != EAS_FALSE)
+ return result;
+ if (tag != CHUNK_RIFF)
+ return EAS_ERROR_UNRECOGNIZED_FORMAT;
+
+ /* get size */
+ if ((result = EAS_HWGetDWord(pEASData->hwInstData, fileHandle, &fileSize, EAS_FALSE)) != EAS_FALSE)
+ return result;
+
+ /* check for 'WAVE' tag */
+ if ((result = EAS_HWGetDWord(pEASData->hwInstData, fileHandle, &tag, EAS_TRUE)) != EAS_FALSE)
+ return result;
+ if (tag != CHUNK_WAVE)
+ return EAS_ERROR_UNRECOGNIZED_FORMAT;
+
+ /* this is enough to say we recognize the file */
+ if (pWaveData == NULL)
+ return EAS_SUCCESS;
+
+ /* check for streaming mode */
+ pWaveData->flags = 0;
+ pWaveData->mediaLength = -1;
+ pWaveData->infoChunkPos = -1;
+ pWaveData->infoChunkSize = -1;
+ if (fileSize== FILE_SIZE_STREAMING)
+ {
+ pWaveData->flags |= PCM_FLAGS_STREAMING;
+ fileSize = 0x7fffffff;
+ }
+
+ /* find out where we're at */
+ if ((result = EAS_HWFilePos(pEASData->hwInstData, fileHandle, &pos)) != EAS_SUCCESS)
+ return result;
+ fileSize -= 4;
+
+ parseDone = EAS_FALSE;
+ for (;;)
+ {
+ /* get tag and size for next chunk */
+ if ((result = EAS_HWGetDWord(pEASData->hwInstData, fileHandle, &tag, EAS_TRUE)) != EAS_FALSE)
+ return result;
+ if ((result = EAS_HWGetDWord(pEASData->hwInstData, fileHandle, &size, EAS_FALSE)) != EAS_FALSE)
+ return result;
+
+ /* process chunk */
+ pos += 8;
+ switch (tag)
+ {
+ case CHUNK_FMT:
+
+#ifdef MMAPI_SUPPORT
+ if ((result = SaveFmtChunk(pEASData, fileHandle, pWaveData, (EAS_I32) size)) != EAS_SUCCESS)
+ return result;
+#endif
+
+ /* get audio format */
+ if ((result = EAS_HWGetWord(pEASData->hwInstData, fileHandle, &usTemp, EAS_FALSE)) != EAS_FALSE)
+ return result;
+ if (usTemp == WAVE_FORMAT_PCM)
+ {
+ params.decoder = EAS_DECODER_PCM;
+ pWaveData->fileType = EAS_FILE_WAVE_PCM;
+ }
+ else if (usTemp == WAVE_FORMAT_IMA_ADPCM)
+ {
+ params.decoder = EAS_DECODER_IMA_ADPCM;
+ pWaveData->fileType = EAS_FILE_WAVE_IMA_ADPCM;
+ }
+ else
+ return EAS_ERROR_UNRECOGNIZED_FORMAT;
+
+ /* get number of channels */
+ if ((result = EAS_HWGetWord(pEASData->hwInstData, fileHandle, &usTemp, EAS_FALSE)) != EAS_FALSE)
+ return result;
+ if (usTemp == 2)
+ pWaveData->flags |= PCM_FLAGS_STEREO;
+ else if (usTemp != 1)
+ return EAS_ERROR_UNRECOGNIZED_FORMAT;
+
+ /* get sample rate */
+ if ((result = EAS_HWGetDWord(pEASData->hwInstData, fileHandle, &params.sampleRate, EAS_FALSE)) != EAS_FALSE)
+ return result;
+
+ /* get stream rate */
+ if ((result = EAS_HWGetDWord(pEASData->hwInstData, fileHandle, &avgBytesPerSec, EAS_FALSE)) != EAS_FALSE)
+ return result;
+
+ /* get block alignment */
+ if ((result = EAS_HWGetWord(pEASData->hwInstData, fileHandle, &usTemp, EAS_FALSE)) != EAS_FALSE)
+ return result;
+ params.blockSize = usTemp;
+
+ /* get bits per sample */
+ if ((result = EAS_HWGetWord(pEASData->hwInstData, fileHandle, &usTemp, EAS_FALSE)) != EAS_FALSE)
+ return result;
+
+ /* PCM, must be 8 or 16 bit samples */
+ if (params.decoder == EAS_DECODER_PCM)
+ {
+ if (usTemp == 8)
+ pWaveData->flags |= PCM_FLAGS_8_BIT | PCM_FLAGS_UNSIGNED;
+ else if (usTemp != 16)
+ return EAS_ERROR_UNRECOGNIZED_FORMAT;
+ }
+
+ /* for IMA ADPCM, we only support mono 4-bit ADPCM */
+ else
+ {
+ if ((usTemp != 4) || (pWaveData->flags & PCM_FLAGS_STEREO))
+ return EAS_ERROR_UNRECOGNIZED_FORMAT;
+ }
+
+ break;
+
+ case CHUNK_DATA:
+ audioOffset = pos;
+ if (pWaveData->flags & PCM_FLAGS_STREAMING)
+ {
+ params.size = 0x7fffffff;
+ parseDone = EAS_TRUE;
+ }
+ else
+ {
+ params.size = (EAS_I32) size;
+ params.loopStart = size;
+ /* use more accurate method if possible */
+ if (size <= (0x7fffffff / 1000))
+ pWaveData->mediaLength = (EAS_I32) ((size * 1000) / avgBytesPerSec);
+ else
+ pWaveData->mediaLength = (EAS_I32) (size / (avgBytesPerSec / 1000));
+ }
+ break;
+
+ case CHUNK_LIST:
+ /* get the list type */
+ if ((result = EAS_HWGetDWord(pEASData->hwInstData, fileHandle, &tag, EAS_TRUE)) != EAS_FALSE)
+ return result;
+ if (tag == CHUNK_INFO)
+ {
+ pWaveData->infoChunkPos = pos + 4;
+ pWaveData->infoChunkSize = (EAS_I32) size - 4;
+ }
+ break;
+
+ default:
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "WaveParseHeader: %c%c%c%c chunk - %d byte(s) ignored\n",
+ (char) (tag >> 24), (char) (tag >> 16), (char) (tag >> 8), (char) tag, size); */ }
+ break;
+ }
+
+ if (parseDone)
+ break;
+
+ /* subtract header size */
+ fileSize -= 8;
+
+ /* account for zero-padding on odd length chunks */
+ if (size & 1)
+ size++;
+
+ /* this check works for files with odd length last chunk and no zero-pad */
+ if (size >= fileSize)
+ {
+ if (size > fileSize)
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "WaveParseHeader: '%c%c%c%c' chunk size exceeds length of file or is not zero-padded\n",
+ (char) (tag >> 24), (char) (tag >> 16), (char) (tag >> 8), (char) tag, size); */ }
+ break;
+ }
+
+ /* subtract size of data chunk (including any zero-pad) */
+ fileSize -= size;
+
+ /* seek to next chunk */
+ pos += (EAS_I32) size;
+ if ((result = EAS_HWFileSeek(pEASData->hwInstData, fileHandle, pos)) != EAS_SUCCESS)
+ return result;
+ }
+
+ /* check for valid header */
+ if ((params.sampleRate == 0) || (params.size == 0))
+ return EAS_ERROR_UNRECOGNIZED_FORMAT;
+
+ /* save the pertinent information */
+ pWaveData->audioOffset = audioOffset;
+ params.flags = pWaveData->flags;
+
+ /* seek to data */
+ if ((result = EAS_HWFileSeek(pEASData->hwInstData, fileHandle, audioOffset)) != EAS_SUCCESS)
+ return result;
+
+ /* open a stream in the PCM engine */
+ return EAS_PEOpenStream(pEASData, &params, &pWaveData->streamHandle);
+}
+
+/*----------------------------------------------------------------------------
+ * WaveGetMetaData()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Process the INFO chunk and return metadata to host
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT WaveGetMetaData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 *pMediaLength)
+{
+ S_WAVE_STATE *pWaveData;
+ EAS_RESULT result;
+ EAS_I32 pos;
+ EAS_U32 size;
+ EAS_I32 infoSize;
+ EAS_U32 tag;
+ EAS_I32 restorePos;
+ E_EAS_METADATA_TYPE metaType;
+ EAS_I32 metaLen;
+
+ /* get current position so we can restore it */
+ pWaveData = (S_WAVE_STATE*) pInstData;
+
+ /* return media length */
+ *pMediaLength = pWaveData->mediaLength;
+
+ /* did we encounter an INFO chunk? */
+ if (pWaveData->infoChunkPos < 0)
+ return EAS_SUCCESS;
+
+ if ((result = EAS_HWFilePos(pEASData->hwInstData, pWaveData->fileHandle, &restorePos)) != EAS_SUCCESS)
+ return result;
+
+ /* offset to start of first chunk in INFO chunk */
+ pos = pWaveData->infoChunkPos;
+ infoSize = pWaveData->infoChunkSize;
+
+ /* read all the chunks in the INFO chunk */
+ for (;;)
+ {
+
+ /* seek to next chunk */
+ if ((result = EAS_HWFileSeek(pEASData->hwInstData, pWaveData->fileHandle, pos)) != EAS_SUCCESS)
+ return result;
+
+ /* get tag and size for next chunk */
+ if ((result = EAS_HWGetDWord(pEASData->hwInstData, pWaveData->fileHandle, &tag, EAS_TRUE)) != EAS_FALSE)
+ return result;
+ if ((result = EAS_HWGetDWord(pEASData->hwInstData, pWaveData->fileHandle, &size, EAS_FALSE)) != EAS_FALSE)
+ return result;
+
+ /* process chunk */
+ pos += 8;
+ metaType = EAS_METADATA_UNKNOWN;
+ switch (tag)
+ {
+ case CHUNK_INAM:
+ metaType = EAS_METADATA_TITLE;
+ break;
+
+ case CHUNK_IART:
+ metaType = EAS_METADATA_AUTHOR;
+ break;
+
+ case CHUNK_ICOP:
+ metaType = EAS_METADATA_COPYRIGHT;
+ break;
+
+ default:
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "WaveParseHeader: %c%c%c%c chunk - %d byte(s) ignored\n",
+ (char) (tag >> 24), (char) (tag >> 16), (char) (tag >> 8), (char) tag, size); */ }
+ break;
+ }
+
+ /* process known metadata */
+ if (metaType != EAS_METADATA_UNKNOWN)
+ {
+ metaLen = pWaveData->metadata.bufferSize - 1;
+ if (metaLen > (EAS_I32) size)
+ metaLen = (EAS_I32) size;
+ if ((result = EAS_HWReadFile(pEASData->hwInstData, pWaveData->fileHandle, pWaveData->metadata.buffer, metaLen, &metaLen)) != EAS_SUCCESS)
+ return result;
+ pWaveData->metadata.buffer[metaLen] = 0;
+ pWaveData->metadata.callback(metaType, pWaveData->metadata.buffer, pWaveData->metadata.pUserData);
+ }
+
+ /* subtract this block */
+ if (size & 1)
+ size++;
+ infoSize -= (EAS_I32) size + 8;
+ if (infoSize == 0)
+ break;
+ pos += (EAS_I32) size;
+ }
+
+
+ /* restore original position */
+ return EAS_HWFileSeek(pEASData->hwInstData, pWaveData->fileHandle, restorePos);
+}
+
+#ifdef MMAPI_SUPPORT
+/*----------------------------------------------------------------------------
+ * SaveFmtChunk()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Save the fmt chunk for the MMAPI library
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT SaveFmtChunk (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle, S_WAVE_STATE *pWaveData, EAS_I32 fmtSize)
+{
+ EAS_RESULT result;
+ EAS_I32 pos;
+ EAS_I32 count;
+
+ /* save current file position */
+ if ((result = EAS_HWFilePos(pEASData->hwInstData, fileHandle, &pos)) != EAS_SUCCESS)
+ return result;
+
+ /* allocate a chunk of memory */
+ pWaveData->fmtChunk = EAS_HWMalloc(pEASData->hwInstData, fmtSize);
+ if (!pWaveData->fmtChunk)
+ return EAS_ERROR_MALLOC_FAILED;
+
+ /* read the fmt chunk into memory */
+ if ((result = EAS_HWReadFile(pEASData->hwInstData, fileHandle, pWaveData->fmtChunk, fmtSize, &count)) != EAS_SUCCESS)
+ return result;
+ if (count != fmtSize)
+ return EAS_ERROR_FILE_READ_FAILED;
+
+ /* restore file position */
+ return EAS_HWFileSeek(pEASData->hwInstData, fileHandle, pos);
+}
+#endif
+
diff --git a/arm-wt-22k/lib_src/eas_wavefile.h b/arm-wt-22k/lib_src/eas_wavefile.h
index b8b76df..f8814a8 100644
--- a/arm-wt-22k/lib_src/eas_wavefile.h
+++ b/arm-wt-22k/lib_src/eas_wavefile.h
@@ -1,12 +1,12 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_wavefile.h
- *
- * Contents and purpose:
- * Static data block for wave file parser.
- *
- * Copyright Sonic Network Inc. 2005
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_wavefile.h
+ *
+ * Contents and purpose:
+ * Static data block for wave file parser.
+ *
+ * Copyright Sonic Network Inc. 2005
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,45 +19,45 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 439 $
- * $Date: 2006-10-26 11:53:18 -0700 (Thu, 26 Oct 2006) $
- *----------------------------------------------------------------------------
-*/
-
-#ifndef _EAS_WAVEFILE_H
-#define _EAS_WAVEFILE_H
-
-#include "eas_data.h"
-#include "eas_pcm.h"
-
-/*----------------------------------------------------------------------------
- *
- * S_WAVE_STATE
- *
- * This structure contains the WAVE file parser state information
- *----------------------------------------------------------------------------
-*/
-typedef struct s_wave_state_tag
-{
- EAS_FILE_HANDLE fileHandle;
- EAS_PCM_HANDLE streamHandle;
- S_METADATA_CB metadata;
- EAS_U32 time;
- EAS_I32 fileOffset;
- EAS_I32 audioOffset;
- EAS_I32 mediaLength;
- EAS_U32 audioSize;
- EAS_U32 flags;
- EAS_I16 fileType;
-#ifdef MMAPI_SUPPORT
- EAS_VOID_PTR fmtChunk;
-#endif
- EAS_I32 infoChunkPos;
- EAS_I32 infoChunkSize;
-} S_WAVE_STATE;
-
-#endif
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 439 $
+ * $Date: 2006-10-26 11:53:18 -0700 (Thu, 26 Oct 2006) $
+ *----------------------------------------------------------------------------
+*/
+
+#ifndef _EAS_WAVEFILE_H
+#define _EAS_WAVEFILE_H
+
+#include "eas_data.h"
+#include "eas_pcm.h"
+
+/*----------------------------------------------------------------------------
+ *
+ * S_WAVE_STATE
+ *
+ * This structure contains the WAVE file parser state information
+ *----------------------------------------------------------------------------
+*/
+typedef struct s_wave_state_tag
+{
+ EAS_FILE_HANDLE fileHandle;
+ EAS_PCM_HANDLE streamHandle;
+ S_METADATA_CB metadata;
+ EAS_U32 time;
+ EAS_I32 fileOffset;
+ EAS_I32 audioOffset;
+ EAS_I32 mediaLength;
+ EAS_U32 audioSize;
+ EAS_U32 flags;
+ EAS_I16 fileType;
+#ifdef MMAPI_SUPPORT
+ EAS_VOID_PTR fmtChunk;
+#endif
+ EAS_I32 infoChunkPos;
+ EAS_I32 infoChunkSize;
+} S_WAVE_STATE;
+
+#endif
+
diff --git a/arm-wt-22k/lib_src/eas_wavefiledata.c b/arm-wt-22k/lib_src/eas_wavefiledata.c
index 3742aa6..c224a6c 100644
--- a/arm-wt-22k/lib_src/eas_wavefiledata.c
+++ b/arm-wt-22k/lib_src/eas_wavefiledata.c
@@ -1,12 +1,12 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_wavefiledata.c
- *
- * Contents and purpose:
- * Static data block for wave file parser.
- *
- * Copyright Sonic Network Inc. 2005
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_wavefiledata.c
+ *
+ * Contents and purpose:
+ * Static data block for wave file parser.
+ *
+ * Copyright Sonic Network Inc. 2005
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,15 +19,15 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 547 $
- * $Date: 2007-01-31 16:30:17 -0800 (Wed, 31 Jan 2007) $
- *----------------------------------------------------------------------------
-*/
-
-#include "eas_wavefile.h"
-
-S_WAVE_STATE eas_WaveData;
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 547 $
+ * $Date: 2007-01-31 16:30:17 -0800 (Wed, 31 Jan 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+#include "eas_wavefile.h"
+
+S_WAVE_STATE eas_WaveData;
+
diff --git a/arm-wt-22k/lib_src/eas_wt_IPC_frame.h b/arm-wt-22k/lib_src/eas_wt_IPC_frame.h
index 376fd3a..29d77aa 100644
--- a/arm-wt-22k/lib_src/eas_wt_IPC_frame.h
+++ b/arm-wt-22k/lib_src/eas_wt_IPC_frame.h
@@ -1,21 +1,21 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_wt_IPC_frame.h
- *
- * Contents and purpose:
- * This module contains data definitions for the interprocessor
- * communications framework for a split-architecture synthesizer.
- *
- * This sample version writes IPC data to a file that can be used
- * as a test vector for the DSP simulator. For a real-time system
- * the file I/O is replaced with an IPC protocol in the hardware.
- *
- * Synchronization with the DSP is accomplished at the API level,
- * i.e. the host code should call EAS_Render when it is ready to
- * buffer another block of data for transmission to the DSP.
- *
- * Copyright Sonic Network Inc. 2005
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_wt_IPC_frame.h
+ *
+ * Contents and purpose:
+ * This module contains data definitions for the interprocessor
+ * communications framework for a split-architecture synthesizer.
+ *
+ * This sample version writes IPC data to a file that can be used
+ * as a test vector for the DSP simulator. For a real-time system
+ * the file I/O is replaced with an IPC protocol in the hardware.
+ *
+ * Synchronization with the DSP is accomplished at the API level,
+ * i.e. the host code should call EAS_Render when it is ready to
+ * buffer another block of data for transmission to the DSP.
+ *
+ * Copyright Sonic Network Inc. 2005
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -28,55 +28,55 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 818 $
- * $Date: 2007-08-02 15:19:41 -0700 (Thu, 02 Aug 2007) $
- *----------------------------------------------------------------------------
-*/
-
-#ifndef _EAS_WT_IPC_FRAME_H
-#define _EAS_WT_IPC_FRAME_H
-
-/*----------------------------------------------------------------------------
- * S_WT_FRAME
- *
- * This structure contains the common parameters that are updated
- *for each frame of audio.
- *----------------------------------------------------------------------------
-*/
-typedef struct s_wt_frame_tag
-{
- EAS_I32 gainTarget;
- EAS_I32 phaseIncrement;
-
-#if defined(_FILTER_ENABLED)
- EAS_I32 k;
- EAS_I32 b1;
- EAS_I32 b2;
-#endif
-} S_WT_FRAME;
-
-/*----------------------------------------------------------------------------
- * S_WT_CONFIG
- *
- * This structure contains state data for the wavetable engine
- *----------------------------------------------------------------------------
-*/
-typedef struct s_wt_config_tag
-{
- EAS_U32 loopEnd; /* points to last PCM sample (not 1 beyond last) */
- EAS_U32 loopStart; /* points to first sample at start of loop */
- EAS_U32 phaseAccum; /* current sample, integer portion of phase */
-
-#if (NUM_OUTPUT_CHANNELS == 2)
- EAS_I16 gainLeft; /* left channel gain */
- EAS_I16 gainRight; /* right channel gain */
-#endif
-
- EAS_I16 gain; /* current voice gain */
-} S_WT_CONFIG;
-
-#endif
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 818 $
+ * $Date: 2007-08-02 15:19:41 -0700 (Thu, 02 Aug 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+#ifndef _EAS_WT_IPC_FRAME_H
+#define _EAS_WT_IPC_FRAME_H
+
+/*----------------------------------------------------------------------------
+ * S_WT_FRAME
+ *
+ * This structure contains the common parameters that are updated
+ *for each frame of audio.
+ *----------------------------------------------------------------------------
+*/
+typedef struct s_wt_frame_tag
+{
+ EAS_I32 gainTarget;
+ EAS_I32 phaseIncrement;
+
+#if defined(_FILTER_ENABLED)
+ EAS_I32 k;
+ EAS_I32 b1;
+ EAS_I32 b2;
+#endif
+} S_WT_FRAME;
+
+/*----------------------------------------------------------------------------
+ * S_WT_CONFIG
+ *
+ * This structure contains state data for the wavetable engine
+ *----------------------------------------------------------------------------
+*/
+typedef struct s_wt_config_tag
+{
+ EAS_U32 loopEnd; /* points to last PCM sample (not 1 beyond last) */
+ EAS_U32 loopStart; /* points to first sample at start of loop */
+ EAS_U32 phaseAccum; /* current sample, integer portion of phase */
+
+#if (NUM_OUTPUT_CHANNELS == 2)
+ EAS_I16 gainLeft; /* left channel gain */
+ EAS_I16 gainRight; /* right channel gain */
+#endif
+
+ EAS_I16 gain; /* current voice gain */
+} S_WT_CONFIG;
+
+#endif
+
diff --git a/arm-wt-22k/lib_src/eas_wtengine.c b/arm-wt-22k/lib_src/eas_wtengine.c
index dd46f22..224f60d 100644
--- a/arm-wt-22k/lib_src/eas_wtengine.c
+++ b/arm-wt-22k/lib_src/eas_wtengine.c
@@ -1,12 +1,12 @@
/*----------------------------------------------------------------------------
*
- * File:
+ * File:
* eas_wtengine.c
*
* Contents and purpose:
* This file contains the critical synthesizer components that need to
* be optimized for best performance.
- *
+ *
* Copyright Sonic Network Inc. 2004-2005
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -55,17 +55,17 @@ extern void WT_Interpolate (S_WT_VOICE *pWTVoice, S_WT_INT_FRAME *pWTIntFrame);
#if defined(_FILTER_ENABLED)
extern void WT_VoiceFilter (S_FILTER_CONTROL*pFilter, S_WT_INT_FRAME *pWTIntFrame);
-#endif
+#endif
#if defined(_OPTIMIZED_MONO) || !defined(NATIVE_EAS_KERNEL)
/*----------------------------------------------------------------------------
* WT_VoiceGain
*----------------------------------------------------------------------------
- * Purpose:
- * Output gain for individual voice
- *
- * Inputs:
- *
+ * Purpose:
+ * Output gain for individual voice
+ *
+ * Inputs:
+ *
* Outputs:
*
*----------------------------------------------------------------------------
@@ -73,85 +73,85 @@ extern void WT_VoiceFilter (S_FILTER_CONTROL*pFilter, S_WT_INT_FRAME *pWTIntFram
/*lint -esym(715, pWTVoice) reserved for future use */
void WT_VoiceGain (S_WT_VOICE *pWTVoice, S_WT_INT_FRAME *pWTIntFrame)
{
- EAS_I32 *pMixBuffer;
- EAS_PCM *pInputBuffer;
- EAS_I32 gain;
- EAS_I32 gainIncrement;
- EAS_I32 tmp0;
- EAS_I32 tmp1;
- EAS_I32 tmp2;
- EAS_I32 numSamples;
-
+ EAS_I32 *pMixBuffer;
+ EAS_PCM *pInputBuffer;
+ EAS_I32 gain;
+ EAS_I32 gainIncrement;
+ EAS_I32 tmp0;
+ EAS_I32 tmp1;
+ EAS_I32 tmp2;
+ EAS_I32 numSamples;
+
#if (NUM_OUTPUT_CHANNELS == 2)
- EAS_I32 gainLeft, gainRight;
+ EAS_I32 gainLeft, gainRight;
#endif
-
- /* initialize some local variables */
- numSamples = pWTIntFrame->numSamples;
- pMixBuffer = pWTIntFrame->pMixBuffer;
- pInputBuffer = pWTIntFrame->pAudioBuffer;
-
- /*lint -e{703} <avoid multiply for performance>*/
- gainIncrement = (pWTIntFrame->frame.gainTarget - pWTIntFrame->prevGain) << (16 - SYNTH_UPDATE_PERIOD_IN_BITS);
- if (gainIncrement < 0)
- gainIncrement++;
- /*lint -e{703} <avoid multiply for performance>*/
- gain = pWTIntFrame->prevGain << 16;
-
-#if (NUM_OUTPUT_CHANNELS == 2)
- gainLeft = pWTVoice->gainLeft;
- gainRight = pWTVoice->gainRight;
+
+ /* initialize some local variables */
+ numSamples = pWTIntFrame->numSamples;
+ pMixBuffer = pWTIntFrame->pMixBuffer;
+ pInputBuffer = pWTIntFrame->pAudioBuffer;
+
+ /*lint -e{703} <avoid multiply for performance>*/
+ gainIncrement = (pWTIntFrame->frame.gainTarget - pWTIntFrame->prevGain) << (16 - SYNTH_UPDATE_PERIOD_IN_BITS);
+ if (gainIncrement < 0)
+ gainIncrement++;
+ /*lint -e{703} <avoid multiply for performance>*/
+ gain = pWTIntFrame->prevGain << 16;
+
+#if (NUM_OUTPUT_CHANNELS == 2)
+ gainLeft = pWTVoice->gainLeft;
+ gainRight = pWTVoice->gainRight;
#endif
-
- while (numSamples--) {
-
- /* incremental gain step to prevent zipper noise */
- tmp0 = *pInputBuffer++;
- gain += gainIncrement;
- /*lint -e{704} <avoid divide>*/
- tmp2 = gain >> 16;
-
- /* scale sample by gain */
- tmp2 *= tmp0;
-
-
- /* stereo output */
-#if (NUM_OUTPUT_CHANNELS == 2)
- /*lint -e{704} <avoid divide>*/
- tmp2 = tmp2 >> 14;
-
- /* get the current sample in the final mix buffer */
- tmp1 = *pMixBuffer;
-
- /* left channel */
- tmp0 = tmp2 * gainLeft;
- /*lint -e{704} <avoid divide>*/
- tmp0 = tmp0 >> NUM_MIXER_GUARD_BITS;
- tmp1 += tmp0;
- *pMixBuffer++ = tmp1;
-
- /* get the current sample in the final mix buffer */
- tmp1 = *pMixBuffer;
-
- /* right channel */
- tmp0 = tmp2 * gainRight;
- /*lint -e{704} <avoid divide>*/
- tmp0 = tmp0 >> NUM_MIXER_GUARD_BITS;
- tmp1 += tmp0;
- *pMixBuffer++ = tmp1;
-
- /* mono output */
+
+ while (numSamples--) {
+
+ /* incremental gain step to prevent zipper noise */
+ tmp0 = *pInputBuffer++;
+ gain += gainIncrement;
+ /*lint -e{704} <avoid divide>*/
+ tmp2 = gain >> 16;
+
+ /* scale sample by gain */
+ tmp2 *= tmp0;
+
+
+ /* stereo output */
+#if (NUM_OUTPUT_CHANNELS == 2)
+ /*lint -e{704} <avoid divide>*/
+ tmp2 = tmp2 >> 14;
+
+ /* get the current sample in the final mix buffer */
+ tmp1 = *pMixBuffer;
+
+ /* left channel */
+ tmp0 = tmp2 * gainLeft;
+ /*lint -e{704} <avoid divide>*/
+ tmp0 = tmp0 >> NUM_MIXER_GUARD_BITS;
+ tmp1 += tmp0;
+ *pMixBuffer++ = tmp1;
+
+ /* get the current sample in the final mix buffer */
+ tmp1 = *pMixBuffer;
+
+ /* right channel */
+ tmp0 = tmp2 * gainRight;
+ /*lint -e{704} <avoid divide>*/
+ tmp0 = tmp0 >> NUM_MIXER_GUARD_BITS;
+ tmp1 += tmp0;
+ *pMixBuffer++ = tmp1;
+
+ /* mono output */
#else
- /* get the current sample in the final mix buffer */
- tmp1 = *pMixBuffer;
- /*lint -e{704} <avoid divide>*/
- tmp2 = tmp2 >> (NUM_MIXER_GUARD_BITS - 1);
- tmp1 += tmp2;
- *pMixBuffer++ = tmp1;
+ /* get the current sample in the final mix buffer */
+ tmp1 = *pMixBuffer;
+ /*lint -e{704} <avoid divide>*/
+ tmp2 = tmp2 >> (NUM_MIXER_GUARD_BITS - 1);
+ tmp1 += tmp2;
+ *pMixBuffer++ = tmp1;
#endif
- }
+ }
}
#endif
@@ -159,180 +159,180 @@ void WT_VoiceGain (S_WT_VOICE *pWTVoice, S_WT_INT_FRAME *pWTIntFrame)
/*----------------------------------------------------------------------------
* WT_Interpolate
*----------------------------------------------------------------------------
- * Purpose:
+ * Purpose:
* Interpolation engine for wavetable synth
- *
- * Inputs:
- *
+ *
+ * Inputs:
+ *
* Outputs:
*
*----------------------------------------------------------------------------
*/
void WT_Interpolate (S_WT_VOICE *pWTVoice, S_WT_INT_FRAME *pWTIntFrame)
{
- EAS_PCM *pOutputBuffer;
- EAS_I32 phaseInc;
- EAS_I32 phaseFrac;
- EAS_I32 acc0;
- const EAS_SAMPLE *pSamples;
- const EAS_SAMPLE *loopEnd;
- EAS_I32 samp1;
- EAS_I32 samp2;
- EAS_I32 numSamples;
-
- /* initialize some local variables */
- numSamples = pWTIntFrame->numSamples;
- pOutputBuffer = pWTIntFrame->pAudioBuffer;
-
- loopEnd = (const EAS_SAMPLE*) pWTVoice->loopEnd + 1;
- pSamples = (const EAS_SAMPLE*) pWTVoice->phaseAccum;
- /*lint -e{713} truncation is OK */
- phaseFrac = pWTVoice->phaseFrac;
- phaseInc = pWTIntFrame->frame.phaseIncrement;
-
- /* fetch adjacent samples */
+ EAS_PCM *pOutputBuffer;
+ EAS_I32 phaseInc;
+ EAS_I32 phaseFrac;
+ EAS_I32 acc0;
+ const EAS_SAMPLE *pSamples;
+ const EAS_SAMPLE *loopEnd;
+ EAS_I32 samp1;
+ EAS_I32 samp2;
+ EAS_I32 numSamples;
+
+ /* initialize some local variables */
+ numSamples = pWTIntFrame->numSamples;
+ pOutputBuffer = pWTIntFrame->pAudioBuffer;
+
+ loopEnd = (const EAS_SAMPLE*) pWTVoice->loopEnd + 1;
+ pSamples = (const EAS_SAMPLE*) pWTVoice->phaseAccum;
+ /*lint -e{713} truncation is OK */
+ phaseFrac = pWTVoice->phaseFrac;
+ phaseInc = pWTIntFrame->frame.phaseIncrement;
+
+ /* fetch adjacent samples */
#if defined(_8_BIT_SAMPLES)
- /*lint -e{701} <avoid multiply for performance>*/
- samp1 = pSamples[0] << 8;
- /*lint -e{701} <avoid multiply for performance>*/
- samp2 = pSamples[1] << 8;
-#else
- samp1 = pSamples[0];
- samp2 = pSamples[1];
-#endif
-
- while (numSamples--) {
-
- /* linear interpolation */
- acc0 = samp2 - samp1;
- acc0 = acc0 * phaseFrac;
- /*lint -e{704} <avoid divide>*/
- acc0 = samp1 + (acc0 >> NUM_PHASE_FRAC_BITS);
-
- /* save new output sample in buffer */
- /*lint -e{704} <avoid divide>*/
- *pOutputBuffer++ = (EAS_I16)(acc0 >> 2);
-
- /* increment phase */
- phaseFrac += phaseInc;
- /*lint -e{704} <avoid divide>*/
- acc0 = phaseFrac >> NUM_PHASE_FRAC_BITS;
-
- /* next sample */
- if (acc0 > 0) {
-
- /* advance sample pointer */
- pSamples += acc0;
- phaseFrac = (EAS_I32)((EAS_U32)phaseFrac & PHASE_FRAC_MASK);
-
- /* check for loop end */
- acc0 = (EAS_I32) (pSamples - loopEnd);
- if (acc0 >= 0)
- pSamples = (const EAS_SAMPLE*) pWTVoice->loopStart + acc0;
-
- /* fetch new samples */
+ /*lint -e{701} <avoid multiply for performance>*/
+ samp1 = pSamples[0] << 8;
+ /*lint -e{701} <avoid multiply for performance>*/
+ samp2 = pSamples[1] << 8;
+#else
+ samp1 = pSamples[0];
+ samp2 = pSamples[1];
+#endif
+
+ while (numSamples--) {
+
+ /* linear interpolation */
+ acc0 = samp2 - samp1;
+ acc0 = acc0 * phaseFrac;
+ /*lint -e{704} <avoid divide>*/
+ acc0 = samp1 + (acc0 >> NUM_PHASE_FRAC_BITS);
+
+ /* save new output sample in buffer */
+ /*lint -e{704} <avoid divide>*/
+ *pOutputBuffer++ = (EAS_I16)(acc0 >> 2);
+
+ /* increment phase */
+ phaseFrac += phaseInc;
+ /*lint -e{704} <avoid divide>*/
+ acc0 = phaseFrac >> NUM_PHASE_FRAC_BITS;
+
+ /* next sample */
+ if (acc0 > 0) {
+
+ /* advance sample pointer */
+ pSamples += acc0;
+ phaseFrac = (EAS_I32)((EAS_U32)phaseFrac & PHASE_FRAC_MASK);
+
+ /* check for loop end */
+ acc0 = (EAS_I32) (pSamples - loopEnd);
+ if (acc0 >= 0)
+ pSamples = (const EAS_SAMPLE*) pWTVoice->loopStart + acc0;
+
+ /* fetch new samples */
#if defined(_8_BIT_SAMPLES)
- /*lint -e{701} <avoid multiply for performance>*/
- samp1 = pSamples[0] << 8;
- /*lint -e{701} <avoid multiply for performance>*/
- samp2 = pSamples[1] << 8;
-#else
- samp1 = pSamples[0];
- samp2 = pSamples[1];
-#endif
- }
- }
-
- /* save pointer and phase */
- pWTVoice->phaseAccum = (EAS_U32) pSamples;
- pWTVoice->phaseFrac = (EAS_U32) phaseFrac;
-}
+ /*lint -e{701} <avoid multiply for performance>*/
+ samp1 = pSamples[0] << 8;
+ /*lint -e{701} <avoid multiply for performance>*/
+ samp2 = pSamples[1] << 8;
+#else
+ samp1 = pSamples[0];
+ samp2 = pSamples[1];
+#endif
+ }
+ }
+
+ /* save pointer and phase */
+ pWTVoice->phaseAccum = (EAS_U32) pSamples;
+ pWTVoice->phaseFrac = (EAS_U32) phaseFrac;
+}
#endif
#ifndef NATIVE_EAS_KERNEL
/*----------------------------------------------------------------------------
* WT_InterpolateNoLoop
*----------------------------------------------------------------------------
- * Purpose:
+ * Purpose:
* Interpolation engine for wavetable synth
- *
- * Inputs:
- *
+ *
+ * Inputs:
+ *
* Outputs:
*
*----------------------------------------------------------------------------
*/
void WT_InterpolateNoLoop (S_WT_VOICE *pWTVoice, S_WT_INT_FRAME *pWTIntFrame)
{
- EAS_PCM *pOutputBuffer;
- EAS_I32 phaseInc;
- EAS_I32 phaseFrac;
- EAS_I32 acc0;
- const EAS_SAMPLE *pSamples;
- EAS_I32 samp1;
- EAS_I32 samp2;
- EAS_I32 numSamples;
-
- /* initialize some local variables */
- numSamples = pWTIntFrame->numSamples;
- pOutputBuffer = pWTIntFrame->pAudioBuffer;
-
- phaseInc = pWTIntFrame->frame.phaseIncrement;
- pSamples = (const EAS_SAMPLE*) pWTVoice->phaseAccum;
- phaseFrac = (EAS_I32)pWTVoice->phaseFrac;
-
- /* fetch adjacent samples */
+ EAS_PCM *pOutputBuffer;
+ EAS_I32 phaseInc;
+ EAS_I32 phaseFrac;
+ EAS_I32 acc0;
+ const EAS_SAMPLE *pSamples;
+ EAS_I32 samp1;
+ EAS_I32 samp2;
+ EAS_I32 numSamples;
+
+ /* initialize some local variables */
+ numSamples = pWTIntFrame->numSamples;
+ pOutputBuffer = pWTIntFrame->pAudioBuffer;
+
+ phaseInc = pWTIntFrame->frame.phaseIncrement;
+ pSamples = (const EAS_SAMPLE*) pWTVoice->phaseAccum;
+ phaseFrac = (EAS_I32)pWTVoice->phaseFrac;
+
+ /* fetch adjacent samples */
#if defined(_8_BIT_SAMPLES)
- /*lint -e{701} <avoid multiply for performance>*/
- samp1 = pSamples[0] << 8;
- /*lint -e{701} <avoid multiply for performance>*/
- samp2 = pSamples[1] << 8;
-#else
- samp1 = pSamples[0];
- samp2 = pSamples[1];
-#endif
-
- while (numSamples--) {
-
-
- /* linear interpolation */
- acc0 = samp2 - samp1;
- acc0 = acc0 * phaseFrac;
- /*lint -e{704} <avoid divide>*/
- acc0 = samp1 + (acc0 >> NUM_PHASE_FRAC_BITS);
-
- /* save new output sample in buffer */
- /*lint -e{704} <avoid divide>*/
- *pOutputBuffer++ = (EAS_I16)(acc0 >> 2);
-
- /* increment phase */
- phaseFrac += phaseInc;
- /*lint -e{704} <avoid divide>*/
- acc0 = phaseFrac >> NUM_PHASE_FRAC_BITS;
-
- /* next sample */
- if (acc0 > 0) {
-
- /* advance sample pointer */
- pSamples += acc0;
- phaseFrac = (EAS_I32)((EAS_U32)phaseFrac & PHASE_FRAC_MASK);
-
- /* fetch new samples */
+ /*lint -e{701} <avoid multiply for performance>*/
+ samp1 = pSamples[0] << 8;
+ /*lint -e{701} <avoid multiply for performance>*/
+ samp2 = pSamples[1] << 8;
+#else
+ samp1 = pSamples[0];
+ samp2 = pSamples[1];
+#endif
+
+ while (numSamples--) {
+
+
+ /* linear interpolation */
+ acc0 = samp2 - samp1;
+ acc0 = acc0 * phaseFrac;
+ /*lint -e{704} <avoid divide>*/
+ acc0 = samp1 + (acc0 >> NUM_PHASE_FRAC_BITS);
+
+ /* save new output sample in buffer */
+ /*lint -e{704} <avoid divide>*/
+ *pOutputBuffer++ = (EAS_I16)(acc0 >> 2);
+
+ /* increment phase */
+ phaseFrac += phaseInc;
+ /*lint -e{704} <avoid divide>*/
+ acc0 = phaseFrac >> NUM_PHASE_FRAC_BITS;
+
+ /* next sample */
+ if (acc0 > 0) {
+
+ /* advance sample pointer */
+ pSamples += acc0;
+ phaseFrac = (EAS_I32)((EAS_U32)phaseFrac & PHASE_FRAC_MASK);
+
+ /* fetch new samples */
#if defined(_8_BIT_SAMPLES)
- /*lint -e{701} <avoid multiply for performance>*/
- samp1 = pSamples[0] << 8;
- /*lint -e{701} <avoid multiply for performance>*/
- samp2 = pSamples[1] << 8;
-#else
- samp1 = pSamples[0];
- samp2 = pSamples[1];
-#endif
- }
- }
-
- /* save pointer and phase */
- pWTVoice->phaseAccum = (EAS_U32) pSamples;
- pWTVoice->phaseFrac = (EAS_U32) phaseFrac;
+ /*lint -e{701} <avoid multiply for performance>*/
+ samp1 = pSamples[0] << 8;
+ /*lint -e{701} <avoid multiply for performance>*/
+ samp2 = pSamples[1] << 8;
+#else
+ samp1 = pSamples[0];
+ samp2 = pSamples[1];
+#endif
+ }
+ }
+
+ /* save pointer and phase */
+ pWTVoice->phaseAccum = (EAS_U32) pSamples;
+ pWTVoice->phaseFrac = (EAS_U32) phaseFrac;
}
#endif
@@ -340,70 +340,70 @@ void WT_InterpolateNoLoop (S_WT_VOICE *pWTVoice, S_WT_INT_FRAME *pWTIntFrame)
/*----------------------------------------------------------------------------
* WT_VoiceFilter
*----------------------------------------------------------------------------
- * Purpose:
+ * Purpose:
* Implements a 2-pole filter
- *
- * Inputs:
- *
+ *
+ * Inputs:
+ *
* Outputs:
*
*----------------------------------------------------------------------------
*/
void WT_VoiceFilter (S_FILTER_CONTROL *pFilter, S_WT_INT_FRAME *pWTIntFrame)
{
- EAS_PCM *pAudioBuffer;
- EAS_I32 k;
- EAS_I32 b1;
- EAS_I32 b2;
- EAS_I32 z1;
- EAS_I32 z2;
- EAS_I32 acc0;
- EAS_I32 acc1;
- EAS_I32 numSamples;
-
- /* initialize some local variables */
- numSamples = pWTIntFrame->numSamples;
- pAudioBuffer = pWTIntFrame->pAudioBuffer;
-
- z1 = pFilter->z1;
- z2 = pFilter->z2;
- b1 = -pWTIntFrame->frame.b1;
-
- /*lint -e{702} <avoid divide> */
- b2 = -pWTIntFrame->frame.b2 >> 1;
-
- /*lint -e{702} <avoid divide> */
- k = pWTIntFrame->frame.k >> 1;
-
- while (numSamples--)
- {
-
- /* do filter calculations */
- acc0 = *pAudioBuffer;
- acc1 = z1 * b1;
- acc1 += z2 * b2;
- acc0 = acc1 + k * acc0;
- z2 = z1;
-
- /*lint -e{702} <avoid divide> */
- z1 = acc0 >> 14;
- *pAudioBuffer++ = (EAS_I16) z1;
- }
-
- /* save delay values */
- pFilter->z1 = (EAS_I16) z1;
- pFilter->z2 = (EAS_I16) z2;
+ EAS_PCM *pAudioBuffer;
+ EAS_I32 k;
+ EAS_I32 b1;
+ EAS_I32 b2;
+ EAS_I32 z1;
+ EAS_I32 z2;
+ EAS_I32 acc0;
+ EAS_I32 acc1;
+ EAS_I32 numSamples;
+
+ /* initialize some local variables */
+ numSamples = pWTIntFrame->numSamples;
+ pAudioBuffer = pWTIntFrame->pAudioBuffer;
+
+ z1 = pFilter->z1;
+ z2 = pFilter->z2;
+ b1 = -pWTIntFrame->frame.b1;
+
+ /*lint -e{702} <avoid divide> */
+ b2 = -pWTIntFrame->frame.b2 >> 1;
+
+ /*lint -e{702} <avoid divide> */
+ k = pWTIntFrame->frame.k >> 1;
+
+ while (numSamples--)
+ {
+
+ /* do filter calculations */
+ acc0 = *pAudioBuffer;
+ acc1 = z1 * b1;
+ acc1 += z2 * b2;
+ acc0 = acc1 + k * acc0;
+ z2 = z1;
+
+ /*lint -e{702} <avoid divide> */
+ z1 = acc0 >> 14;
+ *pAudioBuffer++ = (EAS_I16) z1;
+ }
+
+ /* save delay values */
+ pFilter->z1 = (EAS_I16) z1;
+ pFilter->z2 = (EAS_I16) z2;
}
#endif
/*----------------------------------------------------------------------------
* WT_NoiseGenerator
*----------------------------------------------------------------------------
- * Purpose:
+ * Purpose:
* Generate pseudo-white noise using PRNG and interpolation engine
- *
- * Inputs:
- *
+ *
+ * Inputs:
+ *
* Outputs:
*
* Notes:
@@ -417,55 +417,55 @@ void WT_VoiceFilter (S_FILTER_CONTROL *pFilter, S_WT_INT_FRAME *pWTIntFrame)
*/
void WT_NoiseGenerator (S_WT_VOICE *pWTVoice, S_WT_INT_FRAME *pWTIntFrame)
{
- EAS_PCM *pOutputBuffer;
- EAS_I32 phaseInc;
- EAS_I32 tmp0;
- EAS_I32 tmp1;
- EAS_I32 nInterpolatedSample;
- EAS_I32 numSamples;
-
- /* initialize some local variables */
- numSamples = pWTIntFrame->numSamples;
- pOutputBuffer = pWTIntFrame->pAudioBuffer;
- phaseInc = pWTIntFrame->frame.phaseIncrement;
-
- /* get last two samples generated */
- /*lint -e{704} <avoid divide for performance>*/
- tmp0 = (EAS_I32) (pWTVoice->phaseAccum) >> 18;
- /*lint -e{704} <avoid divide for performance>*/
- tmp1 = (EAS_I32) (pWTVoice->loopEnd) >> 18;
-
- /* generate a buffer of noise */
- while (numSamples--) {
- nInterpolatedSample = MULT_AUDIO_COEF( tmp0, (PHASE_ONE - pWTVoice->phaseFrac));
- nInterpolatedSample += MULT_AUDIO_COEF( tmp1, pWTVoice->phaseFrac);
- *pOutputBuffer++ = (EAS_PCM) nInterpolatedSample;
-
- /* update PRNG */
- pWTVoice->phaseFrac += (EAS_U32) phaseInc;
- if (GET_PHASE_INT_PART(pWTVoice->phaseFrac)) {
- tmp0 = tmp1;
- pWTVoice->phaseAccum = pWTVoice->loopEnd;
- pWTVoice->loopEnd = (5 * pWTVoice->loopEnd + 1);
- tmp1 = (EAS_I32) (pWTVoice->loopEnd) >> 18;
- pWTVoice->phaseFrac = GET_PHASE_FRAC_PART(pWTVoice->phaseFrac);
- }
-
- }
+ EAS_PCM *pOutputBuffer;
+ EAS_I32 phaseInc;
+ EAS_I32 tmp0;
+ EAS_I32 tmp1;
+ EAS_I32 nInterpolatedSample;
+ EAS_I32 numSamples;
+
+ /* initialize some local variables */
+ numSamples = pWTIntFrame->numSamples;
+ pOutputBuffer = pWTIntFrame->pAudioBuffer;
+ phaseInc = pWTIntFrame->frame.phaseIncrement;
+
+ /* get last two samples generated */
+ /*lint -e{704} <avoid divide for performance>*/
+ tmp0 = (EAS_I32) (pWTVoice->phaseAccum) >> 18;
+ /*lint -e{704} <avoid divide for performance>*/
+ tmp1 = (EAS_I32) (pWTVoice->loopEnd) >> 18;
+
+ /* generate a buffer of noise */
+ while (numSamples--) {
+ nInterpolatedSample = MULT_AUDIO_COEF( tmp0, (PHASE_ONE - pWTVoice->phaseFrac));
+ nInterpolatedSample += MULT_AUDIO_COEF( tmp1, pWTVoice->phaseFrac);
+ *pOutputBuffer++ = (EAS_PCM) nInterpolatedSample;
+
+ /* update PRNG */
+ pWTVoice->phaseFrac += (EAS_U32) phaseInc;
+ if (GET_PHASE_INT_PART(pWTVoice->phaseFrac)) {
+ tmp0 = tmp1;
+ pWTVoice->phaseAccum = pWTVoice->loopEnd;
+ pWTVoice->loopEnd = (5 * pWTVoice->loopEnd + 1);
+ tmp1 = (EAS_I32) (pWTVoice->loopEnd) >> 18;
+ pWTVoice->phaseFrac = GET_PHASE_FRAC_PART(pWTVoice->phaseFrac);
+ }
+
+ }
}
#ifndef _OPTIMIZED_MONO
/*----------------------------------------------------------------------------
* WT_ProcessVoice
*----------------------------------------------------------------------------
- * Purpose:
+ * Purpose:
* This routine does the block processing for one voice. It is isolated
* from the main synth code to allow for various implementation-specific
* optimizations. It calls the interpolator, filter, and gain routines
* appropriate for a particular configuration.
- *
- * Inputs:
- *
+ *
+ * Inputs:
+ *
* Outputs:
*
* Notes:
@@ -474,66 +474,66 @@ void WT_VoiceFilter (S_FILTER_CONTROL *pFilter, S_WT_INT_FRAME *pWTIntFrame)
void WT_ProcessVoice (S_WT_VOICE *pWTVoice, S_WT_INT_FRAME *pWTIntFrame)
{
- /* use noise generator */
- if (pWTVoice->loopStart == WT_NOISE_GENERATOR)
- WT_NoiseGenerator(pWTVoice, pWTIntFrame);
-
- /* generate interpolated samples for looped waves */
- else if (pWTVoice->loopStart != pWTVoice->loopEnd)
- WT_Interpolate(pWTVoice, pWTIntFrame);
+ /* use noise generator */
+ if (pWTVoice->loopStart == WT_NOISE_GENERATOR)
+ WT_NoiseGenerator(pWTVoice, pWTIntFrame);
- /* generate interpolated samples for unlooped waves */
- else
- {
- WT_InterpolateNoLoop(pWTVoice, pWTIntFrame);
- }
+ /* generate interpolated samples for looped waves */
+ else if (pWTVoice->loopStart != pWTVoice->loopEnd)
+ WT_Interpolate(pWTVoice, pWTIntFrame);
+
+ /* generate interpolated samples for unlooped waves */
+ else
+ {
+ WT_InterpolateNoLoop(pWTVoice, pWTIntFrame);
+ }
#ifdef _FILTER_ENABLED
- if (pWTIntFrame->frame.k != 0)
- WT_VoiceFilter(&pWTVoice->filter, pWTIntFrame);
-#endif
+ if (pWTIntFrame->frame.k != 0)
+ WT_VoiceFilter(&pWTVoice->filter, pWTIntFrame);
+#endif
//2 TEST NEW MIXER FUNCTION
#ifdef UNIFIED_MIXER
- {
- EAS_I32 gainLeft, gainIncLeft;
+ {
+ EAS_I32 gainLeft, gainIncLeft;
#if (NUM_OUTPUT_CHANNELS == 2)
- EAS_I32 gainRight, gainIncRight;
+ EAS_I32 gainRight, gainIncRight;
#endif
- gainLeft = (pWTIntFrame->prevGain * pWTVoice->gainLeft) << 1;
- gainIncLeft = (((pWTIntFrame->frame.gainTarget * pWTVoice->gainLeft) << 1) - gainLeft) >> SYNTH_UPDATE_PERIOD_IN_BITS;
-
+ gainLeft = (pWTIntFrame->prevGain * pWTVoice->gainLeft) << 1;
+ gainIncLeft = (((pWTIntFrame->frame.gainTarget * pWTVoice->gainLeft) << 1) - gainLeft) >> SYNTH_UPDATE_PERIOD_IN_BITS;
+
#if (NUM_OUTPUT_CHANNELS == 2)
- gainRight = (pWTIntFrame->prevGain * pWTVoice->gainRight) << 1;
- gainIncRight = (((pWTIntFrame->frame.gainTarget * pWTVoice->gainRight) << 1) - gainRight) >> SYNTH_UPDATE_PERIOD_IN_BITS;
- EAS_MixStream(
- pWTIntFrame->pAudioBuffer,
- pWTIntFrame->pMixBuffer,
- pWTIntFrame->numSamples,
- gainLeft,
- gainRight,
- gainIncLeft,
- gainIncRight,
- MIX_FLAGS_STEREO_OUTPUT);
-
-#else
- EAS_MixStream(
- pWTIntFrame->pAudioBuffer,
- pWTIntFrame->pMixBuffer,
- pWTIntFrame->numSamples,
- gainLeft,
- 0,
- gainIncLeft,
- 0,
- 0);
+ gainRight = (pWTIntFrame->prevGain * pWTVoice->gainRight) << 1;
+ gainIncRight = (((pWTIntFrame->frame.gainTarget * pWTVoice->gainRight) << 1) - gainRight) >> SYNTH_UPDATE_PERIOD_IN_BITS;
+ EAS_MixStream(
+ pWTIntFrame->pAudioBuffer,
+ pWTIntFrame->pMixBuffer,
+ pWTIntFrame->numSamples,
+ gainLeft,
+ gainRight,
+ gainIncLeft,
+ gainIncRight,
+ MIX_FLAGS_STEREO_OUTPUT);
+
+#else
+ EAS_MixStream(
+ pWTIntFrame->pAudioBuffer,
+ pWTIntFrame->pMixBuffer,
+ pWTIntFrame->numSamples,
+ gainLeft,
+ 0,
+ gainIncLeft,
+ 0,
+ 0);
#endif
- }
+ }
#else
- /* apply gain, and left and right gain */
- WT_VoiceGain(pWTVoice, pWTIntFrame);
+ /* apply gain, and left and right gain */
+ WT_VoiceGain(pWTVoice, pWTIntFrame);
#endif
}
#endif
@@ -542,12 +542,12 @@ void WT_ProcessVoice (S_WT_VOICE *pWTVoice, S_WT_INT_FRAME *pWTIntFrame)
/*----------------------------------------------------------------------------
* WT_InterpolateMono
*----------------------------------------------------------------------------
- * Purpose:
+ * Purpose:
* A C version of the sample interpolation + gain routine, optimized for mono.
* It's not pretty, but it matches the assembly code exactly.
- *
- * Inputs:
- *
+ *
+ * Inputs:
+ *
* Outputs:
*
* Notes:
@@ -555,70 +555,70 @@ void WT_ProcessVoice (S_WT_VOICE *pWTVoice, S_WT_INT_FRAME *pWTIntFrame)
*/
void WT_InterpolateMono (S_WT_VOICE *pWTVoice, S_WT_INT_FRAME *pWTIntFrame)
{
- EAS_I32 *pMixBuffer;
- const EAS_I8 *pLoopEnd;
- const EAS_I8 *pCurrentPhaseInt;
- EAS_I32 numSamples;
- EAS_I32 gain;
- EAS_I32 gainIncrement;
- EAS_I32 currentPhaseFrac;
- EAS_I32 phaseInc;
- EAS_I32 tmp0;
- EAS_I32 tmp1;
- EAS_I32 tmp2;
- EAS_I8 *pLoopStart;
-
- numSamples = pWTIntFrame->numSamples;
- pMixBuffer = pWTIntFrame->pMixBuffer;
-
- /* calculate gain increment */
- gainIncrement = (pWTIntFrame->gainTarget - pWTIntFrame->prevGain) << (16 - SYNTH_UPDATE_PERIOD_IN_BITS);
- if (gainIncrement < 0)
- gainIncrement++;
- gain = pWTIntFrame->prevGain << 16;
-
- pCurrentPhaseInt = pWTVoice->pPhaseAccum;
- currentPhaseFrac = pWTVoice->phaseFrac;
- phaseInc = pWTIntFrame->phaseIncrement;
-
- pLoopStart = pWTVoice->pLoopStart;
- pLoopEnd = pWTVoice->pLoopEnd + 1;
-
+ EAS_I32 *pMixBuffer;
+ const EAS_I8 *pLoopEnd;
+ const EAS_I8 *pCurrentPhaseInt;
+ EAS_I32 numSamples;
+ EAS_I32 gain;
+ EAS_I32 gainIncrement;
+ EAS_I32 currentPhaseFrac;
+ EAS_I32 phaseInc;
+ EAS_I32 tmp0;
+ EAS_I32 tmp1;
+ EAS_I32 tmp2;
+ EAS_I8 *pLoopStart;
+
+ numSamples = pWTIntFrame->numSamples;
+ pMixBuffer = pWTIntFrame->pMixBuffer;
+
+ /* calculate gain increment */
+ gainIncrement = (pWTIntFrame->gainTarget - pWTIntFrame->prevGain) << (16 - SYNTH_UPDATE_PERIOD_IN_BITS);
+ if (gainIncrement < 0)
+ gainIncrement++;
+ gain = pWTIntFrame->prevGain << 16;
+
+ pCurrentPhaseInt = pWTVoice->pPhaseAccum;
+ currentPhaseFrac = pWTVoice->phaseFrac;
+ phaseInc = pWTIntFrame->phaseIncrement;
+
+ pLoopStart = pWTVoice->pLoopStart;
+ pLoopEnd = pWTVoice->pLoopEnd + 1;
+
InterpolationLoop:
- tmp0 = (EAS_I32)(pCurrentPhaseInt - pLoopEnd);
- if (tmp0 >= 0)
- pCurrentPhaseInt = pLoopStart + tmp0;
-
- tmp0 = *pCurrentPhaseInt;
- tmp1 = *(pCurrentPhaseInt + 1);
-
- tmp2 = phaseInc + currentPhaseFrac;
-
- tmp1 = tmp1 - tmp0;
- tmp1 = tmp1 * currentPhaseFrac;
-
- tmp1 = tmp0 + (tmp1 >> NUM_EG1_FRAC_BITS);
-
- pCurrentPhaseInt += (tmp2 >> NUM_PHASE_FRAC_BITS);
- currentPhaseFrac = tmp2 & PHASE_FRAC_MASK;
-
- gain += gainIncrement;
- tmp2 = (gain >> SYNTH_UPDATE_PERIOD_IN_BITS);
-
- tmp0 = *pMixBuffer;
- tmp2 = tmp1 * tmp2;
- tmp2 = (tmp2 >> 9);
- tmp0 = tmp2 + tmp0;
- *pMixBuffer++ = tmp0;
-
- numSamples--;
- if (numSamples > 0)
- goto InterpolationLoop;
-
- pWTVoice->pPhaseAccum = pCurrentPhaseInt;
- pWTVoice->phaseFrac = currentPhaseFrac;
- /*lint -e{702} <avoid divide>*/
- pWTVoice->gain = (EAS_I16)(gain >> SYNTH_UPDATE_PERIOD_IN_BITS);
+ tmp0 = (EAS_I32)(pCurrentPhaseInt - pLoopEnd);
+ if (tmp0 >= 0)
+ pCurrentPhaseInt = pLoopStart + tmp0;
+
+ tmp0 = *pCurrentPhaseInt;
+ tmp1 = *(pCurrentPhaseInt + 1);
+
+ tmp2 = phaseInc + currentPhaseFrac;
+
+ tmp1 = tmp1 - tmp0;
+ tmp1 = tmp1 * currentPhaseFrac;
+
+ tmp1 = tmp0 + (tmp1 >> NUM_EG1_FRAC_BITS);
+
+ pCurrentPhaseInt += (tmp2 >> NUM_PHASE_FRAC_BITS);
+ currentPhaseFrac = tmp2 & PHASE_FRAC_MASK;
+
+ gain += gainIncrement;
+ tmp2 = (gain >> SYNTH_UPDATE_PERIOD_IN_BITS);
+
+ tmp0 = *pMixBuffer;
+ tmp2 = tmp1 * tmp2;
+ tmp2 = (tmp2 >> 9);
+ tmp0 = tmp2 + tmp0;
+ *pMixBuffer++ = tmp0;
+
+ numSamples--;
+ if (numSamples > 0)
+ goto InterpolationLoop;
+
+ pWTVoice->pPhaseAccum = pCurrentPhaseInt;
+ pWTVoice->phaseFrac = currentPhaseFrac;
+ /*lint -e{702} <avoid divide>*/
+ pWTVoice->gain = (EAS_I16)(gain >> SYNTH_UPDATE_PERIOD_IN_BITS);
}
#endif
@@ -626,14 +626,14 @@ InterpolationLoop:
/*----------------------------------------------------------------------------
* WT_ProcessVoice
*----------------------------------------------------------------------------
- * Purpose:
+ * Purpose:
* This routine does the block processing for one voice. It is isolated
* from the main synth code to allow for various implementation-specific
* optimizations. It calls the interpolator, filter, and gain routines
* appropriate for a particular configuration.
- *
- * Inputs:
- *
+ *
+ * Inputs:
+ *
* Outputs:
*
* Notes:
@@ -643,19 +643,19 @@ InterpolationLoop:
*/
void WT_ProcessVoice (S_WT_VOICE *pWTVoice, S_WT_INT_FRAME *pWTIntFrame)
{
-
- /* use noise generator */
- if (pWTVoice->loopStart== WT_NOISE_GENERATOR)
- {
- WT_NoiseGenerator(pWTVoice, pWTIntFrame);
- WT_VoiceGain(pWTVoice, pWTIntFrame);
- }
-
- /* or generate interpolated samples */
- else
- {
- WT_InterpolateMono(pWTVoice, pWTIntFrame);
- }
+
+ /* use noise generator */
+ if (pWTVoice->loopStart== WT_NOISE_GENERATOR)
+ {
+ WT_NoiseGenerator(pWTVoice, pWTIntFrame);
+ WT_VoiceGain(pWTVoice, pWTIntFrame);
+ }
+
+ /* or generate interpolated samples */
+ else
+ {
+ WT_InterpolateMono(pWTVoice, pWTIntFrame);
+ }
}
#endif
diff --git a/arm-wt-22k/lib_src/eas_wtengine.h b/arm-wt-22k/lib_src/eas_wtengine.h
index 6401322..bba7a5e 100644
--- a/arm-wt-22k/lib_src/eas_wtengine.h
+++ b/arm-wt-22k/lib_src/eas_wtengine.h
@@ -1,12 +1,12 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_wtengine.h
- *
- * Contents and purpose:
- * This file defines the interface for wavetable synthesis engine
- *
- * Copyright Sonic Network Inc. 2004
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_wtengine.h
+ *
+ * Contents and purpose:
+ * This file defines the interface for wavetable synthesis engine
+ *
+ * Copyright Sonic Network Inc. 2004
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,153 +19,153 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 818 $
- * $Date: 2007-08-02 15:19:41 -0700 (Thu, 02 Aug 2007) $
- *----------------------------------------------------------------------------
-*/
-
-#ifndef _EAS_WTENGINE_H
-#define _EAS_WTENGINE_H
-
-/* option sanity check */
-#if defined(_OPTIMIZED_MONO) && defined(_FILTER_ENABLED)
-#error "Incompatible build settings: _OPTIMIZED_MONO cannot be used with _FILTER_ENABLED"
-#endif
-
-#if defined(_OPTIMIZED_MONO) && (NUM_OUTPUT_CHANNELS != 1)
-#error "Incompatible build settings: _OPTIMIZED_MONO can only be used with NUM_OUTPUT_CHANNELS = 1"
-#endif
-
-#include "eas_wt_IPC_frame.h"
-
-/*----------------------------------------------------------------------------
- * defines
- *----------------------------------------------------------------------------
-*/
-#define WT_NOISE_GENERATOR 0xffffffff
-
-/*----------------------------------------------------------------------------
- * typedefs
- *----------------------------------------------------------------------------
-*/
-
-/*----------------------------------------------------------------------------
- * S_WT_INT_FRAME
- *
- * This structure includes S_WT_FRAME plus the bus mixing
- * parameters for the internal voices.
- *----------------------------------------------------------------------------
-*/
-typedef struct s_wt_int_frame_tag
-{
- S_WT_FRAME frame;
- EAS_PCM *pAudioBuffer;
- EAS_I32 *pMixBuffer;
- EAS_I32 numSamples;
- EAS_I32 prevGain;
-} S_WT_INT_FRAME;
-
-#if defined(_FILTER_ENABLED)
-/*----------------------------------------------------------------------------
- * S_FILTER_CONTROL data structure
- *----------------------------------------------------------------------------
-*/
-typedef struct s_filter_control_tag
-{
- EAS_I16 z1; /* 1 sample delay state variable */
- EAS_I16 z2; /* 2 sample delay state variable */
-} S_FILTER_CONTROL;
-#endif
-
-/*------------------------------------
- * S_LFO_CONTROL data structure
- *------------------------------------
-*/
-typedef struct s_lfo_control_tag
-{
- EAS_I16 lfoValue; /* LFO current output value */
- EAS_I16 lfoPhase; /* LFO current phase */
-} S_LFO_CONTROL;
-
-/* bit definitions for S_WT_VOICE:flags */
-#define WT_FLAGS_ADPCM_NIBBLE 1 /* high/low nibble flag */
-#define WT_FLAGS_ADPCM_READY 2 /* first 2 samples are decoded */
-#define WT_FLAGS_USE_ADPCM 4 /* sample is ADPCM encoded */
-
-/* eg1State and eg2State */
-typedef enum {
- eEnvelopeStateInit = 0,
- eEnvelopeStateDelay,
- eEnvelopeStateAttack,
- eEnvelopeStateHold,
- eEnvelopeStateDecay,
- eEnvelopeStateSustain,
- eEnvelopeStateRelease,
- eEnvelopeStateMuting,
- eEnvelopeStateMuted,
- eEnvelopeStateInvalid /* should never be in this state! */
-} E_ENVELOPE_STATE;
-
-#define DEFAULT_EG1_STATE eEnvelopeStateAttack
-#define DEFAULT_EG1_VALUE 0
-#define DEFAULT_EG1_INCREMENT 0
-#define DEFAULT_EG2_STATE eEnvelopeStateAttack
-#define DEFAULT_EG2_VALUE 0
-#define DEFAULT_EG2_INCREMENT 0
-
-/*----------------------------------------------------------------------------
- * S_WT_VOICE
- *
- * This structure contains state data for the wavetable engine
- *----------------------------------------------------------------------------
-*/
-typedef struct s_wt_voice_tag
-{
- EAS_U32 loopEnd; /* points to last PCM sample (not 1 beyond last) */
- EAS_U32 loopStart; /* points to first sample at start of loop */
- EAS_U32 phaseAccum; /* current sample, integer portion of phase */
- EAS_U32 phaseFrac; /* fractional portion of phase */
-
-#if (NUM_OUTPUT_CHANNELS == 2)
- EAS_I16 gainLeft; /* current gain, left ch */
- EAS_I16 gainRight; /* current gain, right ch */
-#endif
-
-#if defined(_FILTER_ENABLED)
- S_FILTER_CONTROL filter; /* low pass filter */
-#endif
-
- S_LFO_CONTROL modLFO; /* modulator LFO */
-
-#ifdef DLS_SYNTHESIZER
- S_LFO_CONTROL vibLFO; /* vibrato LFO */
-#endif
-
- /* envelope control */
- EAS_I16 eg1Value;
- EAS_I16 eg2Value;
- EAS_I16 eg1Increment;
- EAS_I16 eg2Increment;
- EAS_U8 eg1State;
- EAS_U8 eg2State;
-
- EAS_U16 artIndex; /* index to articulation params */
-
-} S_WT_VOICE;
-
-/*----------------------------------------------------------------------------
- * prototypes
- *----------------------------------------------------------------------------
-*/
-EAS_BOOL WT_CheckSampleEnd (S_WT_VOICE *pWTVoice, S_WT_INT_FRAME *pWTIntFrame, EAS_BOOL update);
-void WT_ProcessVoice (S_WT_VOICE *pWTVoice, S_WT_INT_FRAME *pWTIntFrame);
-
-#ifdef EAS_SPLIT_WT_SYNTH
-void WTE_ConfigVoice (EAS_I32 voiceNum, S_WT_CONFIG *pWTConfig, EAS_FRAME_BUFFER_HANDLE pFrameBuffer);
-void WTE_ProcessVoice (EAS_I32 voiceNum, S_WT_FRAME *pWTParams, EAS_FRAME_BUFFER_HANDLE pFrameBuffer);
-#endif
-
-#endif
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 818 $
+ * $Date: 2007-08-02 15:19:41 -0700 (Thu, 02 Aug 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+#ifndef _EAS_WTENGINE_H
+#define _EAS_WTENGINE_H
+
+/* option sanity check */
+#if defined(_OPTIMIZED_MONO) && defined(_FILTER_ENABLED)
+#error "Incompatible build settings: _OPTIMIZED_MONO cannot be used with _FILTER_ENABLED"
+#endif
+
+#if defined(_OPTIMIZED_MONO) && (NUM_OUTPUT_CHANNELS != 1)
+#error "Incompatible build settings: _OPTIMIZED_MONO can only be used with NUM_OUTPUT_CHANNELS = 1"
+#endif
+
+#include "eas_wt_IPC_frame.h"
+
+/*----------------------------------------------------------------------------
+ * defines
+ *----------------------------------------------------------------------------
+*/
+#define WT_NOISE_GENERATOR 0xffffffff
+
+/*----------------------------------------------------------------------------
+ * typedefs
+ *----------------------------------------------------------------------------
+*/
+
+/*----------------------------------------------------------------------------
+ * S_WT_INT_FRAME
+ *
+ * This structure includes S_WT_FRAME plus the bus mixing
+ * parameters for the internal voices.
+ *----------------------------------------------------------------------------
+*/
+typedef struct s_wt_int_frame_tag
+{
+ S_WT_FRAME frame;
+ EAS_PCM *pAudioBuffer;
+ EAS_I32 *pMixBuffer;
+ EAS_I32 numSamples;
+ EAS_I32 prevGain;
+} S_WT_INT_FRAME;
+
+#if defined(_FILTER_ENABLED)
+/*----------------------------------------------------------------------------
+ * S_FILTER_CONTROL data structure
+ *----------------------------------------------------------------------------
+*/
+typedef struct s_filter_control_tag
+{
+ EAS_I16 z1; /* 1 sample delay state variable */
+ EAS_I16 z2; /* 2 sample delay state variable */
+} S_FILTER_CONTROL;
+#endif
+
+/*------------------------------------
+ * S_LFO_CONTROL data structure
+ *------------------------------------
+*/
+typedef struct s_lfo_control_tag
+{
+ EAS_I16 lfoValue; /* LFO current output value */
+ EAS_I16 lfoPhase; /* LFO current phase */
+} S_LFO_CONTROL;
+
+/* bit definitions for S_WT_VOICE:flags */
+#define WT_FLAGS_ADPCM_NIBBLE 1 /* high/low nibble flag */
+#define WT_FLAGS_ADPCM_READY 2 /* first 2 samples are decoded */
+#define WT_FLAGS_USE_ADPCM 4 /* sample is ADPCM encoded */
+
+/* eg1State and eg2State */
+typedef enum {
+ eEnvelopeStateInit = 0,
+ eEnvelopeStateDelay,
+ eEnvelopeStateAttack,
+ eEnvelopeStateHold,
+ eEnvelopeStateDecay,
+ eEnvelopeStateSustain,
+ eEnvelopeStateRelease,
+ eEnvelopeStateMuting,
+ eEnvelopeStateMuted,
+ eEnvelopeStateInvalid /* should never be in this state! */
+} E_ENVELOPE_STATE;
+
+#define DEFAULT_EG1_STATE eEnvelopeStateAttack
+#define DEFAULT_EG1_VALUE 0
+#define DEFAULT_EG1_INCREMENT 0
+#define DEFAULT_EG2_STATE eEnvelopeStateAttack
+#define DEFAULT_EG2_VALUE 0
+#define DEFAULT_EG2_INCREMENT 0
+
+/*----------------------------------------------------------------------------
+ * S_WT_VOICE
+ *
+ * This structure contains state data for the wavetable engine
+ *----------------------------------------------------------------------------
+*/
+typedef struct s_wt_voice_tag
+{
+ EAS_U32 loopEnd; /* points to last PCM sample (not 1 beyond last) */
+ EAS_U32 loopStart; /* points to first sample at start of loop */
+ EAS_U32 phaseAccum; /* current sample, integer portion of phase */
+ EAS_U32 phaseFrac; /* fractional portion of phase */
+
+#if (NUM_OUTPUT_CHANNELS == 2)
+ EAS_I16 gainLeft; /* current gain, left ch */
+ EAS_I16 gainRight; /* current gain, right ch */
+#endif
+
+#if defined(_FILTER_ENABLED)
+ S_FILTER_CONTROL filter; /* low pass filter */
+#endif
+
+ S_LFO_CONTROL modLFO; /* modulator LFO */
+
+#ifdef DLS_SYNTHESIZER
+ S_LFO_CONTROL vibLFO; /* vibrato LFO */
+#endif
+
+ /* envelope control */
+ EAS_I16 eg1Value;
+ EAS_I16 eg2Value;
+ EAS_I16 eg1Increment;
+ EAS_I16 eg2Increment;
+ EAS_U8 eg1State;
+ EAS_U8 eg2State;
+
+ EAS_U16 artIndex; /* index to articulation params */
+
+} S_WT_VOICE;
+
+/*----------------------------------------------------------------------------
+ * prototypes
+ *----------------------------------------------------------------------------
+*/
+EAS_BOOL WT_CheckSampleEnd (S_WT_VOICE *pWTVoice, S_WT_INT_FRAME *pWTIntFrame, EAS_BOOL update);
+void WT_ProcessVoice (S_WT_VOICE *pWTVoice, S_WT_INT_FRAME *pWTIntFrame);
+
+#ifdef EAS_SPLIT_WT_SYNTH
+void WTE_ConfigVoice (EAS_I32 voiceNum, S_WT_CONFIG *pWTConfig, EAS_FRAME_BUFFER_HANDLE pFrameBuffer);
+void WTE_ProcessVoice (EAS_I32 voiceNum, S_WT_FRAME *pWTParams, EAS_FRAME_BUFFER_HANDLE pFrameBuffer);
+#endif
+
+#endif
diff --git a/arm-wt-22k/lib_src/eas_wtsynth.c b/arm-wt-22k/lib_src/eas_wtsynth.c
index 3eadf2d..45cf4b1 100644
--- a/arm-wt-22k/lib_src/eas_wtsynth.c
+++ b/arm-wt-22k/lib_src/eas_wtsynth.c
@@ -79,22 +79,22 @@ extern long statsSampleCount;
*----------------------------------------------------------------------------
*/
-const S_SYNTH_INTERFACE wtSynth =
+const S_SYNTH_INTERFACE wtSynth =
{
- WT_Initialize,
- WT_StartVoice,
- WT_UpdateVoice,
- WT_ReleaseVoice,
- WT_MuteVoice,
- WT_SustainPedal,
- WT_UpdateChannel
+ WT_Initialize,
+ WT_StartVoice,
+ WT_UpdateVoice,
+ WT_ReleaseVoice,
+ WT_MuteVoice,
+ WT_SustainPedal,
+ WT_UpdateChannel
};
#ifdef EAS_SPLIT_WT_SYNTH
const S_FRAME_INTERFACE wtFrameInterface =
{
- WTE_StartFrame,
- WTE_EndFrame
+ WTE_StartFrame,
+ WTE_EndFrame
};
#endif
@@ -112,37 +112,37 @@ const S_FRAME_INTERFACE wtFrameInterface =
*/
static EAS_RESULT WT_Initialize (S_VOICE_MGR *pVoiceMgr)
{
- EAS_INT i;
+ EAS_INT i;
- for (i = 0; i < NUM_WT_VOICES; i++)
- {
+ for (i = 0; i < NUM_WT_VOICES; i++)
+ {
- pVoiceMgr->wtVoices[i].artIndex = DEFAULT_ARTICULATION_INDEX;
+ pVoiceMgr->wtVoices[i].artIndex = DEFAULT_ARTICULATION_INDEX;
- pVoiceMgr->wtVoices[i].eg1State = DEFAULT_EG1_STATE;
- pVoiceMgr->wtVoices[i].eg1Value = DEFAULT_EG1_VALUE;
- pVoiceMgr->wtVoices[i].eg1Increment = DEFAULT_EG1_INCREMENT;
+ pVoiceMgr->wtVoices[i].eg1State = DEFAULT_EG1_STATE;
+ pVoiceMgr->wtVoices[i].eg1Value = DEFAULT_EG1_VALUE;
+ pVoiceMgr->wtVoices[i].eg1Increment = DEFAULT_EG1_INCREMENT;
- pVoiceMgr->wtVoices[i].eg2State = DEFAULT_EG2_STATE;
- pVoiceMgr->wtVoices[i].eg2Value = DEFAULT_EG2_VALUE;
- pVoiceMgr->wtVoices[i].eg2Increment = DEFAULT_EG2_INCREMENT;
+ pVoiceMgr->wtVoices[i].eg2State = DEFAULT_EG2_STATE;
+ pVoiceMgr->wtVoices[i].eg2Value = DEFAULT_EG2_VALUE;
+ pVoiceMgr->wtVoices[i].eg2Increment = DEFAULT_EG2_INCREMENT;
- /* left and right gain values are needed only if stereo output */
-#if (NUM_OUTPUT_CHANNELS == 2)
- pVoiceMgr->wtVoices[i].gainLeft = DEFAULT_VOICE_GAIN;
- pVoiceMgr->wtVoices[i].gainRight = DEFAULT_VOICE_GAIN;
+ /* left and right gain values are needed only if stereo output */
+#if (NUM_OUTPUT_CHANNELS == 2)
+ pVoiceMgr->wtVoices[i].gainLeft = DEFAULT_VOICE_GAIN;
+ pVoiceMgr->wtVoices[i].gainRight = DEFAULT_VOICE_GAIN;
#endif
- pVoiceMgr->wtVoices[i].phaseFrac = DEFAULT_PHASE_FRAC;
- pVoiceMgr->wtVoices[i].phaseAccum = DEFAULT_PHASE_INT;
+ pVoiceMgr->wtVoices[i].phaseFrac = DEFAULT_PHASE_FRAC;
+ pVoiceMgr->wtVoices[i].phaseAccum = DEFAULT_PHASE_INT;
#ifdef _FILTER_ENABLED
- pVoiceMgr->wtVoices[i].filter.z1 = DEFAULT_FILTER_ZERO;
- pVoiceMgr->wtVoices[i].filter.z2 = DEFAULT_FILTER_ZERO;
+ pVoiceMgr->wtVoices[i].filter.z1 = DEFAULT_FILTER_ZERO;
+ pVoiceMgr->wtVoices[i].filter.z2 = DEFAULT_FILTER_ZERO;
#endif
- }
+ }
- return EAS_TRUE;
+ return EAS_TRUE;
}
/*----------------------------------------------------------------------------
@@ -162,20 +162,20 @@ static EAS_RESULT WT_Initialize (S_VOICE_MGR *pVoiceMgr)
/*lint -esym(715, pVoice) used in some implementations */
static void WT_ReleaseVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, EAS_I32 voiceNum)
{
- S_WT_VOICE *pWTVoice;
- const S_ARTICULATION *pArticulation;
-
+ S_WT_VOICE *pWTVoice;
+ const S_ARTICULATION *pArticulation;
+
#ifdef DLS_SYNTHESIZER
- if (pVoice->regionIndex & FLAG_RGN_IDX_DLS_SYNTH)
- {
- DLS_ReleaseVoice(pVoiceMgr, pSynth, pVoice, voiceNum);
- return;
- }
+ if (pVoice->regionIndex & FLAG_RGN_IDX_DLS_SYNTH)
+ {
+ DLS_ReleaseVoice(pVoiceMgr, pSynth, pVoice, voiceNum);
+ return;
+ }
#endif
- pWTVoice = &pVoiceMgr->wtVoices[voiceNum];
- pArticulation = &pSynth->pEAS->pArticulations[pWTVoice->artIndex];
-
+ pWTVoice = &pVoiceMgr->wtVoices[voiceNum];
+ pArticulation = &pSynth->pEAS->pArticulations[pWTVoice->artIndex];
+
/* release EG1 */
pWTVoice->eg1State = eEnvelopeStateRelease;
pWTVoice->eg1Increment = pArticulation->eg1.releaseTime;
@@ -209,20 +209,20 @@ static void WT_MuteVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE
{
#ifdef DLS_SYNTHESIZER
- if (pVoice->regionIndex & FLAG_RGN_IDX_DLS_SYNTH)
- {
- DLS_MuteVoice(pVoiceMgr, pSynth, pVoice, voiceNum);
- return;
- }
+ if (pVoice->regionIndex & FLAG_RGN_IDX_DLS_SYNTH)
+ {
+ DLS_MuteVoice(pVoiceMgr, pSynth, pVoice, voiceNum);
+ return;
+ }
#endif
- /* clear deferred action flags */
- pVoice->voiceFlags &=
- ~(VOICE_FLAG_DEFER_MIDI_NOTE_OFF |
- VOICE_FLAG_SUSTAIN_PEDAL_DEFER_NOTE_OFF |
- VOICE_FLAG_DEFER_MUTE);
-
- /* set the envelope state */
+ /* clear deferred action flags */
+ pVoice->voiceFlags &=
+ ~(VOICE_FLAG_DEFER_MIDI_NOTE_OFF |
+ VOICE_FLAG_SUSTAIN_PEDAL_DEFER_NOTE_OFF |
+ VOICE_FLAG_DEFER_MUTE);
+
+ /* set the envelope state */
pVoiceMgr->wtVoices[voiceNum].eg1State = eEnvelopeStateMuted;
pVoiceMgr->wtVoices[voiceNum].eg2State = eEnvelopeStateMuted;
}
@@ -243,25 +243,25 @@ static void WT_MuteVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE
/*lint -esym(715, pChannel) used in some implementations */
static void WT_SustainPedal (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, S_SYNTH_CHANNEL *pChannel, EAS_I32 voiceNum)
{
- S_WT_VOICE *pWTVoice;
+ S_WT_VOICE *pWTVoice;
#ifdef DLS_SYNTHESIZER
- if (pVoice->regionIndex & FLAG_RGN_IDX_DLS_SYNTH)
- {
- DLS_SustainPedal(pVoiceMgr, pSynth, pVoice, pChannel, voiceNum);
- return;
- }
+ if (pVoice->regionIndex & FLAG_RGN_IDX_DLS_SYNTH)
+ {
+ DLS_SustainPedal(pVoiceMgr, pSynth, pVoice, pChannel, voiceNum);
+ return;
+ }
#endif
- /* don't catch the voice if below the sustain level */
- pWTVoice = &pVoiceMgr->wtVoices[voiceNum];
- if (pWTVoice->eg1Value < pSynth->pEAS->pArticulations[pWTVoice->artIndex].eg1.sustainLevel)
- return;
-
+ /* don't catch the voice if below the sustain level */
+ pWTVoice = &pVoiceMgr->wtVoices[voiceNum];
+ if (pWTVoice->eg1Value < pSynth->pEAS->pArticulations[pWTVoice->artIndex].eg1.sustainLevel)
+ return;
+
/* sustain flag is set, damper pedal is on */
/* defer releasing this note until the damper pedal is off */
pWTVoice->eg1State = eEnvelopeStateDecay;
- pVoice->voiceState = eVoiceStatePlay;
+ pVoice->voiceState = eVoiceStatePlay;
/*
because sustain pedal is on, this voice
@@ -277,9 +277,9 @@ static void WT_SustainPedal (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VO
/*----------------------------------------------------------------------------
* WT_StartVoice()
*----------------------------------------------------------------------------
- * Purpose:
+ * Purpose:
* Assign the region for the given instrument using the midi key number
- * and the RPN2 (coarse tuning) value. By using RPN2 as part of the
+ * and the RPN2 (coarse tuning) value. By using RPN2 as part of the
* region selection process, we reduce the amount a given sample has
* to be transposed by selecting the closest recorded root instead.
*
@@ -290,14 +290,14 @@ static void WT_SustainPedal (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VO
* Setup and initialize the following voice parameters:
* m_nRegionIndex
*
- * Inputs:
+ * Inputs:
* pVoice - ptr to the voice we have assigned for this channel
* nRegionIndex - index of the region
* pEASData - pointer to overall EAS data structure
- *
+ *
* Outputs:
* success - could find and assign the region for this voice's note otherwise
- * failure - could not find nor assign the region for this voice's note
+ * failure - could not find nor assign the region for this voice's note
*
* Side Effects:
* psSynthObject->m_sVoice[].m_nRegionIndex is assigned
@@ -306,137 +306,137 @@ static void WT_SustainPedal (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VO
*/
static EAS_RESULT WT_StartVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, EAS_I32 voiceNum, EAS_U16 regionIndex)
{
- S_WT_VOICE *pWTVoice;
- const S_WT_REGION *pRegion;
- const S_ARTICULATION *pArt;
- S_SYNTH_CHANNEL *pChannel;
-
+ S_WT_VOICE *pWTVoice;
+ const S_WT_REGION *pRegion;
+ const S_ARTICULATION *pArt;
+ S_SYNTH_CHANNEL *pChannel;
+
#if (NUM_OUTPUT_CHANNELS == 2)
- EAS_INT pan;
+ EAS_INT pan;
#endif
#ifdef EAS_SPLIT_WT_SYNTH
- S_WT_CONFIG wtConfig;
+ S_WT_CONFIG wtConfig;
#endif
-
- /* no samples have been synthesized for this note yet */
- pVoice->regionIndex = regionIndex;
- pVoice->voiceFlags = VOICE_FLAG_NO_SAMPLES_SYNTHESIZED_YET;
- /* get the articulation index for this region */
- pWTVoice = &pVoiceMgr->wtVoices[voiceNum];
- pChannel = &pSynth->channels[pVoice->channel & 15];
+ /* no samples have been synthesized for this note yet */
+ pVoice->regionIndex = regionIndex;
+ pVoice->voiceFlags = VOICE_FLAG_NO_SAMPLES_SYNTHESIZED_YET;
+
+ /* get the articulation index for this region */
+ pWTVoice = &pVoiceMgr->wtVoices[voiceNum];
+ pChannel = &pSynth->channels[pVoice->channel & 15];
- /* update static channel parameters */
- if (pChannel->channelFlags & CHANNEL_FLAG_UPDATE_CHANNEL_PARAMETERS)
- WT_UpdateChannel(pVoiceMgr, pSynth, pVoice->channel & 15);
+ /* update static channel parameters */
+ if (pChannel->channelFlags & CHANNEL_FLAG_UPDATE_CHANNEL_PARAMETERS)
+ WT_UpdateChannel(pVoiceMgr, pSynth, pVoice->channel & 15);
#ifdef DLS_SYNTHESIZER
- if (pVoice->regionIndex & FLAG_RGN_IDX_DLS_SYNTH)
- return DLS_StartVoice(pVoiceMgr, pSynth, pVoice, voiceNum, regionIndex);
+ if (pVoice->regionIndex & FLAG_RGN_IDX_DLS_SYNTH)
+ return DLS_StartVoice(pVoiceMgr, pSynth, pVoice, voiceNum, regionIndex);
#endif
- pRegion = &(pSynth->pEAS->pWTRegions[regionIndex]);
- pWTVoice->artIndex = pRegion->artIndex;
+ pRegion = &(pSynth->pEAS->pWTRegions[regionIndex]);
+ pWTVoice->artIndex = pRegion->artIndex;
#ifdef _DEBUG_SYNTH
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "WT_StartVoice: Voice %ld; Region %d\n", (EAS_I32) (pVoice - pVoiceMgr->voices), regionIndex); */ }
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "WT_StartVoice: Voice %ld; Region %d\n", (EAS_I32) (pVoice - pVoiceMgr->voices), regionIndex); */ }
#endif
- pArt = &pSynth->pEAS->pArticulations[pWTVoice->artIndex];
+ pArt = &pSynth->pEAS->pArticulations[pWTVoice->artIndex];
- /* MIDI note on puts this voice into attack state */
- pWTVoice->eg1State = eEnvelopeStateAttack;
- pWTVoice->eg1Value = 0;
- pWTVoice->eg1Increment = pArt->eg1.attackTime;
- pWTVoice->eg2State = eEnvelopeStateAttack;
- pWTVoice->eg2Value = 0;
- pWTVoice->eg2Increment = pArt->eg2.attackTime;
+ /* MIDI note on puts this voice into attack state */
+ pWTVoice->eg1State = eEnvelopeStateAttack;
+ pWTVoice->eg1Value = 0;
+ pWTVoice->eg1Increment = pArt->eg1.attackTime;
+ pWTVoice->eg2State = eEnvelopeStateAttack;
+ pWTVoice->eg2Value = 0;
+ pWTVoice->eg2Increment = pArt->eg2.attackTime;
- /* init the LFO */
- pWTVoice->modLFO.lfoValue = 0;
- pWTVoice->modLFO.lfoPhase = -pArt->lfoDelay;
+ /* init the LFO */
+ pWTVoice->modLFO.lfoValue = 0;
+ pWTVoice->modLFO.lfoPhase = -pArt->lfoDelay;
- pVoice->gain = 0;
+ pVoice->gain = 0;
#if (NUM_OUTPUT_CHANNELS == 2)
- /*
- Get the Midi CC10 pan value for this voice's channel
- convert the pan value to an "angle" representation suitable for
- our sin, cos calculator. This representation is NOT necessarily the same
- as the transform in the GM manuals because of our sin, cos calculator.
- "angle" = (CC10 - 64)/128
- */
- pan = (EAS_INT) pSynth->channels[pVoice->channel & 15].pan - 64;
- pan += pArt->pan;
- EAS_CalcPanControl(pan, &pWTVoice->gainLeft, &pWTVoice->gainRight);
-#endif
-
-#ifdef _FILTER_ENABLED
- /* clear out the filter states */
- pWTVoice->filter.z1 = 0;
- pWTVoice->filter.z2 = 0;
+ /*
+ Get the Midi CC10 pan value for this voice's channel
+ convert the pan value to an "angle" representation suitable for
+ our sin, cos calculator. This representation is NOT necessarily the same
+ as the transform in the GM manuals because of our sin, cos calculator.
+ "angle" = (CC10 - 64)/128
+ */
+ pan = (EAS_INT) pSynth->channels[pVoice->channel & 15].pan - 64;
+ pan += pArt->pan;
+ EAS_CalcPanControl(pan, &pWTVoice->gainLeft, &pWTVoice->gainRight);
+#endif
+
+#ifdef _FILTER_ENABLED
+ /* clear out the filter states */
+ pWTVoice->filter.z1 = 0;
+ pWTVoice->filter.z2 = 0;
#endif
- /* if this wave is to be generated using noise generator */
- if (pRegion->region.keyGroupAndFlags & REGION_FLAG_USE_WAVE_GENERATOR)
- {
- pWTVoice->phaseAccum = 4574296;
- pWTVoice->loopStart = WT_NOISE_GENERATOR;
- pWTVoice->loopEnd = 4574295;
- }
-
- /* normal sample */
- else
- {
-
+ /* if this wave is to be generated using noise generator */
+ if (pRegion->region.keyGroupAndFlags & REGION_FLAG_USE_WAVE_GENERATOR)
+ {
+ pWTVoice->phaseAccum = 4574296;
+ pWTVoice->loopStart = WT_NOISE_GENERATOR;
+ pWTVoice->loopEnd = 4574295;
+ }
+
+ /* normal sample */
+ else
+ {
+
#ifdef EAS_SPLIT_WT_SYNTH
- if (voiceNum < NUM_PRIMARY_VOICES)
- pWTVoice->phaseAccum = (EAS_U32) pSynth->pEAS->pSamples + pSynth->pEAS->pSampleOffsets[pRegion->waveIndex];
- else
- pWTVoice->phaseAccum = pSynth->pEAS->pSampleOffsets[pRegion->waveIndex];
+ if (voiceNum < NUM_PRIMARY_VOICES)
+ pWTVoice->phaseAccum = (EAS_U32) pSynth->pEAS->pSamples + pSynth->pEAS->pSampleOffsets[pRegion->waveIndex];
+ else
+ pWTVoice->phaseAccum = pSynth->pEAS->pSampleOffsets[pRegion->waveIndex];
#else
- pWTVoice->phaseAccum = (EAS_U32) pSynth->pEAS->pSamples + pSynth->pEAS->pSampleOffsets[pRegion->waveIndex];
+ pWTVoice->phaseAccum = (EAS_U32) pSynth->pEAS->pSamples + pSynth->pEAS->pSampleOffsets[pRegion->waveIndex];
#endif
- if (pRegion->region.keyGroupAndFlags & REGION_FLAG_IS_LOOPED)
- {
- pWTVoice->loopStart = pWTVoice->phaseAccum + pRegion->loopStart;
- pWTVoice->loopEnd = pWTVoice->phaseAccum + pRegion->loopEnd - 1;
- }
- else
- pWTVoice->loopStart = pWTVoice->loopEnd = pWTVoice->phaseAccum + pSynth->pEAS->pSampleLen[pRegion->waveIndex] - 1;
- }
+ if (pRegion->region.keyGroupAndFlags & REGION_FLAG_IS_LOOPED)
+ {
+ pWTVoice->loopStart = pWTVoice->phaseAccum + pRegion->loopStart;
+ pWTVoice->loopEnd = pWTVoice->phaseAccum + pRegion->loopEnd - 1;
+ }
+ else
+ pWTVoice->loopStart = pWTVoice->loopEnd = pWTVoice->phaseAccum + pSynth->pEAS->pSampleLen[pRegion->waveIndex] - 1;
+ }
#ifdef EAS_SPLIT_WT_SYNTH
- /* configure off-chip voices */
- if (voiceNum >= NUM_PRIMARY_VOICES)
- {
- wtConfig.phaseAccum = pWTVoice->phaseAccum;
- wtConfig.loopStart = pWTVoice->loopStart;
- wtConfig.loopEnd = pWTVoice->loopEnd;
- wtConfig.gain = pVoice->gain;
-
+ /* configure off-chip voices */
+ if (voiceNum >= NUM_PRIMARY_VOICES)
+ {
+ wtConfig.phaseAccum = pWTVoice->phaseAccum;
+ wtConfig.loopStart = pWTVoice->loopStart;
+ wtConfig.loopEnd = pWTVoice->loopEnd;
+ wtConfig.gain = pVoice->gain;
+
#if (NUM_OUTPUT_CHANNELS == 2)
- wtConfig.gainLeft = pWTVoice->gainLeft;
- wtConfig.gainRight = pWTVoice->gainRight;
+ wtConfig.gainLeft = pWTVoice->gainLeft;
+ wtConfig.gainRight = pWTVoice->gainRight;
#endif
- WTE_ConfigVoice(voiceNum - NUM_PRIMARY_VOICES, &wtConfig, pVoiceMgr->pFrameBuffer);
- }
+ WTE_ConfigVoice(voiceNum - NUM_PRIMARY_VOICES, &wtConfig, pVoiceMgr->pFrameBuffer);
+ }
#endif
- return EAS_SUCCESS;
+ return EAS_SUCCESS;
}
/*----------------------------------------------------------------------------
* WT_CheckSampleEnd
*----------------------------------------------------------------------------
- * Purpose:
+ * Purpose:
* Check for end of sample and calculate number of samples to synthesize
- *
- * Inputs:
- *
+ *
+ * Inputs:
+ *
* Outputs:
*
* Notes:
@@ -445,53 +445,53 @@ static EAS_RESULT WT_StartVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNT
*/
EAS_BOOL WT_CheckSampleEnd (S_WT_VOICE *pWTVoice, S_WT_INT_FRAME *pWTIntFrame, EAS_BOOL update)
{
- EAS_U32 endPhaseAccum;
- EAS_U32 endPhaseFrac;
- EAS_I32 numSamples;
- EAS_BOOL done = EAS_FALSE;
-
- /* check to see if we hit the end of the waveform this time */
- /*lint -e{703} use shift for performance */
- endPhaseFrac = pWTVoice->phaseFrac + (pWTIntFrame->frame.phaseIncrement << SYNTH_UPDATE_PERIOD_IN_BITS);
- endPhaseAccum = pWTVoice->phaseAccum + GET_PHASE_INT_PART(endPhaseFrac);
- if (endPhaseAccum >= pWTVoice->loopEnd)
- {
- /* calculate how far current ptr is from end */
- numSamples = (EAS_I32) (pWTVoice->loopEnd - pWTVoice->phaseAccum);
-
- /* now account for the fractional portion */
- /*lint -e{703} use shift for performance */
- numSamples = (EAS_I32) ((numSamples << NUM_PHASE_FRAC_BITS) - pWTVoice->phaseFrac);
- if (pWTIntFrame->frame.phaseIncrement) {
- pWTIntFrame->numSamples = 1 + (numSamples / pWTIntFrame->frame.phaseIncrement);
- } else {
- pWTIntFrame->numSamples = numSamples;
- }
-
- /* sound will be done this frame */
- done = EAS_TRUE;
- }
-
- /* update data for off-chip synth */
- if (update)
- {
- pWTVoice->phaseFrac = endPhaseFrac;
- pWTVoice->phaseAccum = endPhaseAccum;
- }
-
- return done;
+ EAS_U32 endPhaseAccum;
+ EAS_U32 endPhaseFrac;
+ EAS_I32 numSamples;
+ EAS_BOOL done = EAS_FALSE;
+
+ /* check to see if we hit the end of the waveform this time */
+ /*lint -e{703} use shift for performance */
+ endPhaseFrac = pWTVoice->phaseFrac + (pWTIntFrame->frame.phaseIncrement << SYNTH_UPDATE_PERIOD_IN_BITS);
+ endPhaseAccum = pWTVoice->phaseAccum + GET_PHASE_INT_PART(endPhaseFrac);
+ if (endPhaseAccum >= pWTVoice->loopEnd)
+ {
+ /* calculate how far current ptr is from end */
+ numSamples = (EAS_I32) (pWTVoice->loopEnd - pWTVoice->phaseAccum);
+
+ /* now account for the fractional portion */
+ /*lint -e{703} use shift for performance */
+ numSamples = (EAS_I32) ((numSamples << NUM_PHASE_FRAC_BITS) - pWTVoice->phaseFrac);
+ if (pWTIntFrame->frame.phaseIncrement) {
+ pWTIntFrame->numSamples = 1 + (numSamples / pWTIntFrame->frame.phaseIncrement);
+ } else {
+ pWTIntFrame->numSamples = numSamples;
+ }
+
+ /* sound will be done this frame */
+ done = EAS_TRUE;
+ }
+
+ /* update data for off-chip synth */
+ if (update)
+ {
+ pWTVoice->phaseFrac = endPhaseFrac;
+ pWTVoice->phaseAccum = endPhaseAccum;
+ }
+
+ return done;
}
/*----------------------------------------------------------------------------
* WT_UpdateVoice()
*----------------------------------------------------------------------------
- * Purpose:
+ * Purpose:
* Synthesize a block of samples for the given voice.
* Use linear interpolation.
*
- * Inputs:
+ * Inputs:
* pEASData - pointer to overall EAS data structure
- *
+ *
* Outputs:
* number of samples actually written to buffer
*
@@ -502,108 +502,108 @@ EAS_BOOL WT_CheckSampleEnd (S_WT_VOICE *pWTVoice, S_WT_INT_FRAME *pWTIntFrame, E
*/
static EAS_BOOL WT_UpdateVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, EAS_I32 voiceNum, EAS_I32 *pMixBuffer, EAS_I32 numSamples)
{
- S_WT_VOICE *pWTVoice;
- S_WT_INT_FRAME intFrame;
- S_SYNTH_CHANNEL *pChannel;
- const S_WT_REGION *pWTRegion;
- const S_ARTICULATION *pArt;
- EAS_I32 temp;
- EAS_BOOL done;
+ S_WT_VOICE *pWTVoice;
+ S_WT_INT_FRAME intFrame;
+ S_SYNTH_CHANNEL *pChannel;
+ const S_WT_REGION *pWTRegion;
+ const S_ARTICULATION *pArt;
+ EAS_I32 temp;
+ EAS_BOOL done;
#ifdef DLS_SYNTHESIZER
- if (pVoice->regionIndex & FLAG_RGN_IDX_DLS_SYNTH)
- return DLS_UpdateVoice(pVoiceMgr, pSynth, pVoice, voiceNum, pMixBuffer, numSamples);
-#endif
+ if (pVoice->regionIndex & FLAG_RGN_IDX_DLS_SYNTH)
+ return DLS_UpdateVoice(pVoiceMgr, pSynth, pVoice, voiceNum, pMixBuffer, numSamples);
+#endif
- /* establish pointers to critical data */
- pWTVoice = &pVoiceMgr->wtVoices[voiceNum];
- pWTRegion = &pSynth->pEAS->pWTRegions[pVoice->regionIndex & REGION_INDEX_MASK];
- pArt = &pSynth->pEAS->pArticulations[pWTVoice->artIndex];
- pChannel = &pSynth->channels[pVoice->channel & 15];
- intFrame.prevGain = pVoice->gain;
+ /* establish pointers to critical data */
+ pWTVoice = &pVoiceMgr->wtVoices[voiceNum];
+ pWTRegion = &pSynth->pEAS->pWTRegions[pVoice->regionIndex & REGION_INDEX_MASK];
+ pArt = &pSynth->pEAS->pArticulations[pWTVoice->artIndex];
+ pChannel = &pSynth->channels[pVoice->channel & 15];
+ intFrame.prevGain = pVoice->gain;
- /* update the envelopes */
- WT_UpdateEG1(pWTVoice, &pArt->eg1);
- WT_UpdateEG2(pWTVoice, &pArt->eg2);
+ /* update the envelopes */
+ WT_UpdateEG1(pWTVoice, &pArt->eg1);
+ WT_UpdateEG2(pWTVoice, &pArt->eg2);
- /* update the LFO */
- WT_UpdateLFO(&pWTVoice->modLFO, pArt->lfoFreq);
+ /* update the LFO */
+ WT_UpdateLFO(&pWTVoice->modLFO, pArt->lfoFreq);
#ifdef _FILTER_ENABLED
- /* calculate filter if library uses filter */
- if (pSynth->pEAS->libAttr & LIB_FORMAT_FILTER_ENABLED)
- WT_UpdateFilter(pWTVoice, &intFrame, pArt);
- else
- intFrame.frame.k = 0;
+ /* calculate filter if library uses filter */
+ if (pSynth->pEAS->libAttr & LIB_FORMAT_FILTER_ENABLED)
+ WT_UpdateFilter(pWTVoice, &intFrame, pArt);
+ else
+ intFrame.frame.k = 0;
#endif
- /* update the gain */
- intFrame.frame.gainTarget = WT_UpdateGain(pVoice, pWTVoice, pArt, pChannel, pWTRegion->gain);
+ /* update the gain */
+ intFrame.frame.gainTarget = WT_UpdateGain(pVoice, pWTVoice, pArt, pChannel, pWTRegion->gain);
- /* calculate base pitch*/
- temp = pChannel->staticPitch + pWTRegion->tuning;
+ /* calculate base pitch*/
+ temp = pChannel->staticPitch + pWTRegion->tuning;
- /* include global transpose */
- if (pChannel->channelFlags & CHANNEL_FLAG_RHYTHM_CHANNEL)
- temp += pVoice->note * 100;
- else
- temp += (pVoice->note + pSynth->globalTranspose) * 100;
- intFrame.frame.phaseIncrement = WT_UpdatePhaseInc(pWTVoice, pArt, pChannel, temp);
+ /* include global transpose */
+ if (pChannel->channelFlags & CHANNEL_FLAG_RHYTHM_CHANNEL)
+ temp += pVoice->note * 100;
+ else
+ temp += (pVoice->note + pSynth->globalTranspose) * 100;
+ intFrame.frame.phaseIncrement = WT_UpdatePhaseInc(pWTVoice, pArt, pChannel, temp);
- /* call into engine to generate samples */
- intFrame.pAudioBuffer = pVoiceMgr->voiceBuffer;
- intFrame.pMixBuffer = pMixBuffer;
- intFrame.numSamples = numSamples;
+ /* call into engine to generate samples */
+ intFrame.pAudioBuffer = pVoiceMgr->voiceBuffer;
+ intFrame.pMixBuffer = pMixBuffer;
+ intFrame.numSamples = numSamples;
- /* check for end of sample */
- if ((pWTVoice->loopStart != WT_NOISE_GENERATOR) && (pWTVoice->loopStart == pWTVoice->loopEnd))
- done = WT_CheckSampleEnd(pWTVoice, &intFrame, (EAS_BOOL) (voiceNum >= NUM_PRIMARY_VOICES));
- else
- done = EAS_FALSE;
+ /* check for end of sample */
+ if ((pWTVoice->loopStart != WT_NOISE_GENERATOR) && (pWTVoice->loopStart == pWTVoice->loopEnd))
+ done = WT_CheckSampleEnd(pWTVoice, &intFrame, (EAS_BOOL) (voiceNum >= NUM_PRIMARY_VOICES));
+ else
+ done = EAS_FALSE;
- if (intFrame.numSamples < 0) intFrame.numSamples = 0;
+ if (intFrame.numSamples < 0) intFrame.numSamples = 0;
#ifdef EAS_SPLIT_WT_SYNTH
- if (voiceNum < NUM_PRIMARY_VOICES)
- {
-#ifndef _SPLIT_WT_TEST_HARNESS
- WT_ProcessVoice(pWTVoice, &intFrame);
+ if (voiceNum < NUM_PRIMARY_VOICES)
+ {
+#ifndef _SPLIT_WT_TEST_HARNESS
+ WT_ProcessVoice(pWTVoice, &intFrame);
#endif
- }
- else
- WTE_ProcessVoice(voiceNum - NUM_PRIMARY_VOICES, &intFrame.frame, pVoiceMgr->pFrameBuffer);
+ }
+ else
+ WTE_ProcessVoice(voiceNum - NUM_PRIMARY_VOICES, &intFrame.frame, pVoiceMgr->pFrameBuffer);
#else
- WT_ProcessVoice(pWTVoice, &intFrame);
+ WT_ProcessVoice(pWTVoice, &intFrame);
#endif
- /* clear flag */
- pVoice->voiceFlags &= ~VOICE_FLAG_NO_SAMPLES_SYNTHESIZED_YET;
+ /* clear flag */
+ pVoice->voiceFlags &= ~VOICE_FLAG_NO_SAMPLES_SYNTHESIZED_YET;
/* if voice has finished, set flag for voice manager */
- if ((pVoice->voiceState != eVoiceStateStolen) && (pWTVoice->eg1State == eEnvelopeStateMuted))
- done = EAS_TRUE;
+ if ((pVoice->voiceState != eVoiceStateStolen) && (pWTVoice->eg1State == eEnvelopeStateMuted))
+ done = EAS_TRUE;
- /* if the update interval has elapsed, then force the current gain to the next
- * gain since we never actually reach the next gain when ramping -- we just get
- * very close to the target gain.
- */
- pVoice->gain = (EAS_I16) intFrame.frame.gainTarget;
+ /* if the update interval has elapsed, then force the current gain to the next
+ * gain since we never actually reach the next gain when ramping -- we just get
+ * very close to the target gain.
+ */
+ pVoice->gain = (EAS_I16) intFrame.frame.gainTarget;
- return done;
-}
+ return done;
+}
/*----------------------------------------------------------------------------
* WT_UpdatePhaseInc()
*----------------------------------------------------------------------------
- * Purpose:
+ * Purpose:
* Calculate the phase increment
*
- * Inputs:
+ * Inputs:
* pVoice - pointer to the voice being updated
* psRegion - pointer to the region
* psArticulation - pointer to the articulation
* nChannelPitchForThisVoice - the portion of the pitch that is fixed for this
- * voice during the duration of this synthesis
+ * voice during the duration of this synthesis
* pEASData - pointer to overall EAS data structure
*
* Outputs:
@@ -614,45 +614,45 @@ static EAS_BOOL WT_UpdateVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH
*/
static EAS_I32 WT_UpdatePhaseInc (S_WT_VOICE *pWTVoice, const S_ARTICULATION *pArt, S_SYNTH_CHANNEL *pChannel, EAS_I32 pitchCents)
{
- EAS_I32 temp;
-
- /*pitchCents due to CC1 = LFO * (CC1 / 128) * DEFAULT_LFO_MOD_WHEEL_TO_PITCH_CENTS */
- temp = MULT_EG1_EG1(DEFAULT_LFO_MOD_WHEEL_TO_PITCH_CENTS,
- ((pChannel->modWheel) << (NUM_EG1_FRAC_BITS -7)));
-
- /* pitchCents due to channel pressure = LFO * (channel pressure / 128) * DEFAULT_LFO_CHANNEL_PRESSURE_TO_PITCH_CENTS */
- temp += MULT_EG1_EG1(DEFAULT_LFO_CHANNEL_PRESSURE_TO_PITCH_CENTS,
- ((pChannel->channelPressure) << (NUM_EG1_FRAC_BITS -7)));
-
- /* now multiply the (channel pressure + CC1) pitch values by the LFO value */
- temp = MULT_EG1_EG1(pWTVoice->modLFO.lfoValue, temp);
-
- /*
- add in the LFO pitch due to
- channel pressure and CC1 along with
- the LFO pitch, the EG2 pitch, and the
- "static" pitch for this voice on this channel
- */
- temp += pitchCents +
- (MULT_EG1_EG1(pWTVoice->eg2Value, pArt->eg2ToPitch)) +
- (MULT_EG1_EG1(pWTVoice->modLFO.lfoValue, pArt->lfoToPitch));
-
- /* convert from cents to linear phase increment */
- return EAS_Calculate2toX(temp);
+ EAS_I32 temp;
+
+ /*pitchCents due to CC1 = LFO * (CC1 / 128) * DEFAULT_LFO_MOD_WHEEL_TO_PITCH_CENTS */
+ temp = MULT_EG1_EG1(DEFAULT_LFO_MOD_WHEEL_TO_PITCH_CENTS,
+ ((pChannel->modWheel) << (NUM_EG1_FRAC_BITS -7)));
+
+ /* pitchCents due to channel pressure = LFO * (channel pressure / 128) * DEFAULT_LFO_CHANNEL_PRESSURE_TO_PITCH_CENTS */
+ temp += MULT_EG1_EG1(DEFAULT_LFO_CHANNEL_PRESSURE_TO_PITCH_CENTS,
+ ((pChannel->channelPressure) << (NUM_EG1_FRAC_BITS -7)));
+
+ /* now multiply the (channel pressure + CC1) pitch values by the LFO value */
+ temp = MULT_EG1_EG1(pWTVoice->modLFO.lfoValue, temp);
+
+ /*
+ add in the LFO pitch due to
+ channel pressure and CC1 along with
+ the LFO pitch, the EG2 pitch, and the
+ "static" pitch for this voice on this channel
+ */
+ temp += pitchCents +
+ (MULT_EG1_EG1(pWTVoice->eg2Value, pArt->eg2ToPitch)) +
+ (MULT_EG1_EG1(pWTVoice->modLFO.lfoValue, pArt->lfoToPitch));
+
+ /* convert from cents to linear phase increment */
+ return EAS_Calculate2toX(temp);
}
/*----------------------------------------------------------------------------
* WT_UpdateChannel()
*----------------------------------------------------------------------------
- * Purpose:
+ * Purpose:
* Calculate and assign static channel parameters
* These values only need to be updated if one of the controller values
* for this channel changes
*
- * Inputs:
+ * Inputs:
* nChannel - channel to update
* pEASData - pointer to overall EAS data structure
- *
+ *
* Outputs:
*
* Side Effects:
@@ -662,59 +662,59 @@ static EAS_I32 WT_UpdatePhaseInc (S_WT_VOICE *pWTVoice, const S_ARTICULATION *pA
/*lint -esym(715, pVoiceMgr) reserved for future use */
static void WT_UpdateChannel (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel)
{
- EAS_I32 staticGain;
- EAS_I32 pitchBend;
- S_SYNTH_CHANNEL *pChannel;
-
- pChannel = &pSynth->channels[channel];
-
- /*
- nChannelGain = (CC7 * CC11)^2 * master volume
- where CC7 == 100 by default, CC11 == 127, master volume == 32767
- */
- staticGain = MULT_EG1_EG1((pChannel->volume) << (NUM_EG1_FRAC_BITS - 7),
- (pChannel->expression) << (NUM_EG1_FRAC_BITS - 7));
-
- /* staticGain has to be squared */
- staticGain = MULT_EG1_EG1(staticGain, staticGain);
-
- pChannel->staticGain = (EAS_I16) MULT_EG1_EG1(staticGain, pSynth->masterVolume);
-
- /*
- calculate pitch bend: RPN0 * ((2*pitch wheel)/16384 -1)
- However, if we use the EG1 macros, remember that EG1 has a full
- scale value of 32768 (instead of 16384). So instead of multiplying
- by 2, multiply by 4 (left shift by 2), and subtract by 32768 instead
- of 16384. This utilizes the fact that the EG1 macro places a binary
- point 15 places to the left instead of 14 places.
- */
- /*lint -e{703} <avoid multiply for performance>*/
- pitchBend =
- (((EAS_I32)(pChannel->pitchBend) << 2)
- - 32768);
-
- pChannel->staticPitch =
- MULT_EG1_EG1(pitchBend, pChannel->pitchBendSensitivity);
-
- /* if this is not a drum channel, then add in the per-channel tuning */
- if (!(pChannel->channelFlags & CHANNEL_FLAG_RHYTHM_CHANNEL))
- pChannel->staticPitch += pChannel->finePitch + (pChannel->coarsePitch * 100);
-
- /* clear update flag */
- pChannel->channelFlags &= ~CHANNEL_FLAG_UPDATE_CHANNEL_PARAMETERS;
- return;
+ EAS_I32 staticGain;
+ EAS_I32 pitchBend;
+ S_SYNTH_CHANNEL *pChannel;
+
+ pChannel = &pSynth->channels[channel];
+
+ /*
+ nChannelGain = (CC7 * CC11)^2 * master volume
+ where CC7 == 100 by default, CC11 == 127, master volume == 32767
+ */
+ staticGain = MULT_EG1_EG1((pChannel->volume) << (NUM_EG1_FRAC_BITS - 7),
+ (pChannel->expression) << (NUM_EG1_FRAC_BITS - 7));
+
+ /* staticGain has to be squared */
+ staticGain = MULT_EG1_EG1(staticGain, staticGain);
+
+ pChannel->staticGain = (EAS_I16) MULT_EG1_EG1(staticGain, pSynth->masterVolume);
+
+ /*
+ calculate pitch bend: RPN0 * ((2*pitch wheel)/16384 -1)
+ However, if we use the EG1 macros, remember that EG1 has a full
+ scale value of 32768 (instead of 16384). So instead of multiplying
+ by 2, multiply by 4 (left shift by 2), and subtract by 32768 instead
+ of 16384. This utilizes the fact that the EG1 macro places a binary
+ point 15 places to the left instead of 14 places.
+ */
+ /*lint -e{703} <avoid multiply for performance>*/
+ pitchBend =
+ (((EAS_I32)(pChannel->pitchBend) << 2)
+ - 32768);
+
+ pChannel->staticPitch =
+ MULT_EG1_EG1(pitchBend, pChannel->pitchBendSensitivity);
+
+ /* if this is not a drum channel, then add in the per-channel tuning */
+ if (!(pChannel->channelFlags & CHANNEL_FLAG_RHYTHM_CHANNEL))
+ pChannel->staticPitch += pChannel->finePitch + (pChannel->coarsePitch * 100);
+
+ /* clear update flag */
+ pChannel->channelFlags &= ~CHANNEL_FLAG_UPDATE_CHANNEL_PARAMETERS;
+ return;
}
/*----------------------------------------------------------------------------
* WT_UpdateGain()
*----------------------------------------------------------------------------
- * Purpose:
+ * Purpose:
* Calculate and assign static voice parameters as part of WT_UpdateVoice()
*
- * Inputs:
- * pVoice - ptr to the synth voice that we want to synthesize
+ * Inputs:
+ * pVoice - ptr to the synth voice that we want to synthesize
* pEASData - pointer to overall EAS data structure
- *
+ *
* Outputs:
*
* Side Effects:
@@ -724,48 +724,48 @@ static void WT_UpdateChannel (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 ch
*/
static EAS_I32 WT_UpdateGain (S_SYNTH_VOICE *pVoice, S_WT_VOICE *pWTVoice, const S_ARTICULATION *pArt, S_SYNTH_CHANNEL *pChannel, EAS_I32 gain)
{
- EAS_I32 lfoGain;
- EAS_I32 temp;
-
- /*
- If this voice was stolen, then the velocity is actually
- for the new note, not the note that we are currently ramping down.
- So we really shouldn't use this velocity. However, that would require
- more memory to store the velocity value, and the improvement may
- not be sufficient to warrant the added memory.
- */
- /* velocity is fixed at note start for a given voice and must be squared */
- temp = (pVoice->velocity) << (NUM_EG1_FRAC_BITS - 7);
- temp = MULT_EG1_EG1(temp, temp);
-
- /* region gain is fixed as part of the articulation */
- temp = MULT_EG1_EG1(temp, gain);
-
- /* include the channel gain */
- temp = MULT_EG1_EG1(temp, pChannel->staticGain);
-
- /* calculate LFO gain using an approximation for 10^x */
- lfoGain = MULT_EG1_EG1(pWTVoice->modLFO.lfoValue, pArt->lfoToGain);
- lfoGain = MULT_EG1_EG1(lfoGain, LFO_GAIN_TO_CENTS);
-
- /* convert from a dB-like value to linear gain */
- lfoGain = EAS_Calculate2toX(lfoGain);
- temp = MULT_EG1_EG1(temp, lfoGain);
-
- /* calculate the voice's gain */
- temp = (EAS_I16)MULT_EG1_EG1(temp, pWTVoice->eg1Value);
-
- return temp;
+ EAS_I32 lfoGain;
+ EAS_I32 temp;
+
+ /*
+ If this voice was stolen, then the velocity is actually
+ for the new note, not the note that we are currently ramping down.
+ So we really shouldn't use this velocity. However, that would require
+ more memory to store the velocity value, and the improvement may
+ not be sufficient to warrant the added memory.
+ */
+ /* velocity is fixed at note start for a given voice and must be squared */
+ temp = (pVoice->velocity) << (NUM_EG1_FRAC_BITS - 7);
+ temp = MULT_EG1_EG1(temp, temp);
+
+ /* region gain is fixed as part of the articulation */
+ temp = MULT_EG1_EG1(temp, gain);
+
+ /* include the channel gain */
+ temp = MULT_EG1_EG1(temp, pChannel->staticGain);
+
+ /* calculate LFO gain using an approximation for 10^x */
+ lfoGain = MULT_EG1_EG1(pWTVoice->modLFO.lfoValue, pArt->lfoToGain);
+ lfoGain = MULT_EG1_EG1(lfoGain, LFO_GAIN_TO_CENTS);
+
+ /* convert from a dB-like value to linear gain */
+ lfoGain = EAS_Calculate2toX(lfoGain);
+ temp = MULT_EG1_EG1(temp, lfoGain);
+
+ /* calculate the voice's gain */
+ temp = (EAS_I16)MULT_EG1_EG1(temp, pWTVoice->eg1Value);
+
+ return temp;
}
/*----------------------------------------------------------------------------
* WT_UpdateEG1()
*----------------------------------------------------------------------------
- * Purpose:
+ * Purpose:
* Calculate the EG1 envelope for the given voice (but do not update any
* state)
*
- * Inputs:
+ * Inputs:
* pVoice - ptr to the voice whose envelope we want to update
* nVoice - this voice's number - used only for debug
* pEASData - pointer to overall EAS data structure
@@ -779,88 +779,88 @@ static EAS_I32 WT_UpdateGain (S_SYNTH_VOICE *pVoice, S_WT_VOICE *pWTVoice, const
*/
static void WT_UpdateEG1 (S_WT_VOICE *pWTVoice, const S_ENVELOPE *pEnv)
{
- EAS_I32 temp;
-
- switch (pWTVoice->eg1State)
- {
- case eEnvelopeStateAttack:
- temp = pWTVoice->eg1Value + pWTVoice->eg1Increment;
-
- /* check if we have reached peak amplitude */
- if (temp >= SYNTH_FULL_SCALE_EG1_GAIN)
- {
- /* limit the volume */
- temp = SYNTH_FULL_SCALE_EG1_GAIN;
-
- /* prepare to move to decay state */
- pWTVoice->eg1State = eEnvelopeStateDecay;
- pWTVoice->eg1Increment = pEnv->decayTime;
- }
-
- break;
-
- /* exponential decay */
- case eEnvelopeStateDecay:
- temp = MULT_EG1_EG1(pWTVoice->eg1Value, pWTVoice->eg1Increment);
-
- /* check if we have reached sustain level */
- if (temp <= pEnv->sustainLevel)
- {
- /* enforce the sustain level */
- temp = pEnv->sustainLevel;
-
- /* if sustain level is zero, skip sustain & release the voice */
- if (temp > 0)
- pWTVoice->eg1State = eEnvelopeStateSustain;
-
- /* move to sustain state */
- else
- pWTVoice->eg1State = eEnvelopeStateMuted;
- }
-
- break;
-
- case eEnvelopeStateSustain:
- return;
-
- case eEnvelopeStateRelease:
- temp = MULT_EG1_EG1(pWTVoice->eg1Value, pWTVoice->eg1Increment);
-
- /* if we hit zero, this voice isn't contributing any audio */
- if (temp <= 0)
- {
- temp = 0;
- pWTVoice->eg1State = eEnvelopeStateMuted;
- }
- break;
-
- /* voice is muted, set target to zero */
- case eEnvelopeStateMuted:
- temp = 0;
- break;
-
- case eEnvelopeStateInvalid:
- default:
- temp = 0;
-#ifdef _DEBUG_SYNTH
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "WT_UpdateEG1: error, %d is an unrecognized state\n",
- pWTVoice->eg1State); */ }
+ EAS_I32 temp;
+
+ switch (pWTVoice->eg1State)
+ {
+ case eEnvelopeStateAttack:
+ temp = pWTVoice->eg1Value + pWTVoice->eg1Increment;
+
+ /* check if we have reached peak amplitude */
+ if (temp >= SYNTH_FULL_SCALE_EG1_GAIN)
+ {
+ /* limit the volume */
+ temp = SYNTH_FULL_SCALE_EG1_GAIN;
+
+ /* prepare to move to decay state */
+ pWTVoice->eg1State = eEnvelopeStateDecay;
+ pWTVoice->eg1Increment = pEnv->decayTime;
+ }
+
+ break;
+
+ /* exponential decay */
+ case eEnvelopeStateDecay:
+ temp = MULT_EG1_EG1(pWTVoice->eg1Value, pWTVoice->eg1Increment);
+
+ /* check if we have reached sustain level */
+ if (temp <= pEnv->sustainLevel)
+ {
+ /* enforce the sustain level */
+ temp = pEnv->sustainLevel;
+
+ /* if sustain level is zero, skip sustain & release the voice */
+ if (temp > 0)
+ pWTVoice->eg1State = eEnvelopeStateSustain;
+
+ /* move to sustain state */
+ else
+ pWTVoice->eg1State = eEnvelopeStateMuted;
+ }
+
+ break;
+
+ case eEnvelopeStateSustain:
+ return;
+
+ case eEnvelopeStateRelease:
+ temp = MULT_EG1_EG1(pWTVoice->eg1Value, pWTVoice->eg1Increment);
+
+ /* if we hit zero, this voice isn't contributing any audio */
+ if (temp <= 0)
+ {
+ temp = 0;
+ pWTVoice->eg1State = eEnvelopeStateMuted;
+ }
+ break;
+
+ /* voice is muted, set target to zero */
+ case eEnvelopeStateMuted:
+ temp = 0;
+ break;
+
+ case eEnvelopeStateInvalid:
+ default:
+ temp = 0;
+#ifdef _DEBUG_SYNTH
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "WT_UpdateEG1: error, %d is an unrecognized state\n",
+ pWTVoice->eg1State); */ }
#endif
- break;
+ break;
- }
+ }
- pWTVoice->eg1Value = (EAS_I16) temp;
+ pWTVoice->eg1Value = (EAS_I16) temp;
}
/*----------------------------------------------------------------------------
* WT_UpdateEG2()
*----------------------------------------------------------------------------
- * Purpose:
+ * Purpose:
* Update the EG2 envelope for the given voice
*
- * Inputs:
- * pVoice - ptr to the voice whose envelope we want to update
+ * Inputs:
+ * pVoice - ptr to the voice whose envelope we want to update
* pEASData - pointer to overall EAS data structure
*
* Outputs:
@@ -872,83 +872,83 @@ static void WT_UpdateEG1 (S_WT_VOICE *pWTVoice, const S_ENVELOPE *pEnv)
static void WT_UpdateEG2 (S_WT_VOICE *pWTVoice, const S_ENVELOPE *pEnv)
{
- EAS_I32 temp;
-
- switch (pWTVoice->eg2State)
- {
- case eEnvelopeStateAttack:
- temp = pWTVoice->eg2Value + pWTVoice->eg2Increment;
-
- /* check if we have reached peak amplitude */
- if (temp >= SYNTH_FULL_SCALE_EG1_GAIN)
- {
- /* limit the volume */
- temp = SYNTH_FULL_SCALE_EG1_GAIN;
-
- /* prepare to move to decay state */
- pWTVoice->eg2State = eEnvelopeStateDecay;
-
- pWTVoice->eg2Increment = pEnv->decayTime;
- }
-
- break;
-
- /* implement linear pitch decay in cents */
- case eEnvelopeStateDecay:
- temp = pWTVoice->eg2Value -pWTVoice->eg2Increment;
-
- /* check if we have reached sustain level */
- if (temp <= pEnv->sustainLevel)
- {
- /* enforce the sustain level */
- temp = pEnv->sustainLevel;
-
- /* prepare to move to sustain state */
- pWTVoice->eg2State = eEnvelopeStateSustain;
- }
- break;
-
- case eEnvelopeStateSustain:
- return;
-
- case eEnvelopeStateRelease:
- temp = pWTVoice->eg2Value - pWTVoice->eg2Increment;
-
- if (temp <= 0)
- {
- temp = 0;
- pWTVoice->eg2State = eEnvelopeStateMuted;
- }
-
- break;
-
- /* voice is muted, set target to zero */
- case eEnvelopeStateMuted:
- temp = 0;
- break;
-
- case eEnvelopeStateInvalid:
- default:
- temp = 0;
-#ifdef _DEBUG_SYNTH
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "WT_UpdateEG2: error, %d is an unrecognized state\n",
- pWTVoice->eg2State); */ }
+ EAS_I32 temp;
+
+ switch (pWTVoice->eg2State)
+ {
+ case eEnvelopeStateAttack:
+ temp = pWTVoice->eg2Value + pWTVoice->eg2Increment;
+
+ /* check if we have reached peak amplitude */
+ if (temp >= SYNTH_FULL_SCALE_EG1_GAIN)
+ {
+ /* limit the volume */
+ temp = SYNTH_FULL_SCALE_EG1_GAIN;
+
+ /* prepare to move to decay state */
+ pWTVoice->eg2State = eEnvelopeStateDecay;
+
+ pWTVoice->eg2Increment = pEnv->decayTime;
+ }
+
+ break;
+
+ /* implement linear pitch decay in cents */
+ case eEnvelopeStateDecay:
+ temp = pWTVoice->eg2Value -pWTVoice->eg2Increment;
+
+ /* check if we have reached sustain level */
+ if (temp <= pEnv->sustainLevel)
+ {
+ /* enforce the sustain level */
+ temp = pEnv->sustainLevel;
+
+ /* prepare to move to sustain state */
+ pWTVoice->eg2State = eEnvelopeStateSustain;
+ }
+ break;
+
+ case eEnvelopeStateSustain:
+ return;
+
+ case eEnvelopeStateRelease:
+ temp = pWTVoice->eg2Value - pWTVoice->eg2Increment;
+
+ if (temp <= 0)
+ {
+ temp = 0;
+ pWTVoice->eg2State = eEnvelopeStateMuted;
+ }
+
+ break;
+
+ /* voice is muted, set target to zero */
+ case eEnvelopeStateMuted:
+ temp = 0;
+ break;
+
+ case eEnvelopeStateInvalid:
+ default:
+ temp = 0;
+#ifdef _DEBUG_SYNTH
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "WT_UpdateEG2: error, %d is an unrecognized state\n",
+ pWTVoice->eg2State); */ }
#endif
- break;
- }
-
- pWTVoice->eg2Value = (EAS_I16) temp;
+ break;
+ }
+
+ pWTVoice->eg2Value = (EAS_I16) temp;
}
/*----------------------------------------------------------------------------
* WT_UpdateLFO ()
*----------------------------------------------------------------------------
- * Purpose:
+ * Purpose:
* Calculate the LFO for the given voice
*
- * Inputs:
- * pLFO - ptr to the LFO data
- * phaseInc - phase increment
+ * Inputs:
+ * pLFO - ptr to the LFO data
+ * phaseInc - phase increment
*
* Outputs:
*
@@ -959,36 +959,36 @@ static void WT_UpdateEG2 (S_WT_VOICE *pWTVoice, const S_ENVELOPE *pEnv)
void WT_UpdateLFO (S_LFO_CONTROL *pLFO, EAS_I16 phaseInc)
{
- /* To save memory, if m_nPhaseValue is negative, we are in the
- * delay phase, and m_nPhaseValue represents the time left
- * in the delay.
- */
- if (pLFO->lfoPhase < 0)
- {
- pLFO->lfoPhase++;
- return;
- }
-
- /* calculate LFO output from phase value */
- /*lint -e{701} Use shift for performance */
- pLFO->lfoValue = (EAS_I16) (pLFO->lfoPhase << 2);
- /*lint -e{502} <shortcut to turn sawtooth into triangle wave> */
- if ((pLFO->lfoPhase > 0x1fff) && (pLFO->lfoPhase < 0x6000))
- pLFO->lfoValue = ~pLFO->lfoValue;
-
- /* update LFO phase */
- pLFO->lfoPhase = (pLFO->lfoPhase + phaseInc) & 0x7fff;
+ /* To save memory, if m_nPhaseValue is negative, we are in the
+ * delay phase, and m_nPhaseValue represents the time left
+ * in the delay.
+ */
+ if (pLFO->lfoPhase < 0)
+ {
+ pLFO->lfoPhase++;
+ return;
+ }
+
+ /* calculate LFO output from phase value */
+ /*lint -e{701} Use shift for performance */
+ pLFO->lfoValue = (EAS_I16) (pLFO->lfoPhase << 2);
+ /*lint -e{502} <shortcut to turn sawtooth into triangle wave> */
+ if ((pLFO->lfoPhase > 0x1fff) && (pLFO->lfoPhase < 0x6000))
+ pLFO->lfoValue = ~pLFO->lfoValue;
+
+ /* update LFO phase */
+ pLFO->lfoPhase = (pLFO->lfoPhase + phaseInc) & 0x7fff;
}
#ifdef _FILTER_ENABLED
/*----------------------------------------------------------------------------
* WT_UpdateFilter()
*----------------------------------------------------------------------------
- * Purpose:
+ * Purpose:
* Update the Filter parameters
*
- * Inputs:
- * pVoice - ptr to the voice whose filter we want to update
+ * Inputs:
+ * pVoice - ptr to the voice whose filter we want to update
* pEASData - pointer to overall EAS data structure
*
* Outputs:
@@ -999,29 +999,29 @@ void WT_UpdateLFO (S_LFO_CONTROL *pLFO, EAS_I16 phaseInc)
*/
static void WT_UpdateFilter (S_WT_VOICE *pWTVoice, S_WT_INT_FRAME *pIntFrame, const S_ARTICULATION *pArt)
{
- EAS_I32 cutoff;
+ EAS_I32 cutoff;
- /* no need to calculate filter coefficients if it is bypassed */
- if (pArt->filterCutoff == DEFAULT_EAS_FILTER_CUTOFF_FREQUENCY)
- {
- pIntFrame->frame.k = 0;
- return;
- }
+ /* no need to calculate filter coefficients if it is bypassed */
+ if (pArt->filterCutoff == DEFAULT_EAS_FILTER_CUTOFF_FREQUENCY)
+ {
+ pIntFrame->frame.k = 0;
+ return;
+ }
- /* determine the dynamic cutoff frequency */
- cutoff = MULT_EG1_EG1(pWTVoice->eg2Value, pArt->eg2ToFc);
- cutoff += pArt->filterCutoff;
+ /* determine the dynamic cutoff frequency */
+ cutoff = MULT_EG1_EG1(pWTVoice->eg2Value, pArt->eg2ToFc);
+ cutoff += pArt->filterCutoff;
- /* subtract the A5 offset and the sampling frequency */
- cutoff -= FILTER_CUTOFF_FREQ_ADJUST + A5_PITCH_OFFSET_IN_CENTS;
+ /* subtract the A5 offset and the sampling frequency */
+ cutoff -= FILTER_CUTOFF_FREQ_ADJUST + A5_PITCH_OFFSET_IN_CENTS;
- /* limit the cutoff frequency */
- if (cutoff > FILTER_CUTOFF_MAX_PITCH_CENTS)
- cutoff = FILTER_CUTOFF_MAX_PITCH_CENTS;
- else if (cutoff < FILTER_CUTOFF_MIN_PITCH_CENTS)
- cutoff = FILTER_CUTOFF_MIN_PITCH_CENTS;
+ /* limit the cutoff frequency */
+ if (cutoff > FILTER_CUTOFF_MAX_PITCH_CENTS)
+ cutoff = FILTER_CUTOFF_MAX_PITCH_CENTS;
+ else if (cutoff < FILTER_CUTOFF_MIN_PITCH_CENTS)
+ cutoff = FILTER_CUTOFF_MIN_PITCH_CENTS;
- WT_SetFilterCoeffs(pIntFrame, cutoff, pArt->filterQ);
+ WT_SetFilterCoeffs(pIntFrame, cutoff, pArt->filterQ);
}
#endif
@@ -1060,7 +1060,7 @@ static void WT_UpdateFilter (S_WT_VOICE *pWTVoice, S_WT_INT_FRAME *pIntFrame, co
* n1g2*k^2
* n1g3*k^3
*
- * NOTE that n1g0 == n1g1 == 0, always, so we only need to store n1g2 and n1g3
+ * NOTE that n1g0 == n1g1 == 0, always, so we only need to store n1g2 and n1g3
*----------------------------------------------------------------------------
*/
@@ -1068,154 +1068,154 @@ static const EAS_I16 nk1g0 = -32768;
static const EAS_I16 nk1g2 = 1580;
static const EAS_I16 k2g0 = 32767;
-static const EAS_I16 k2g1[] =
+static const EAS_I16 k2g1[] =
{
- -11324, /* k2g1[0] = -0.3455751918948761 */
- -10387, /* k2g1[1] = -0.3169878073928751 */
- -9528, /* k2g1[2] = -0.29076528753345476 */
- -8740, /* k2g1[3] = -0.2667120011011279 */
- -8017, /* k2g1[4] = -0.24464850028971705 */
- -7353, /* k2g1[5] = -0.22441018194495696 */
- -6745, /* k2g1[6] = -0.20584605955455101 */
- -6187, /* k2g1[7] = -0.18881763682420102 */
- -5675, /* k2g1[8] = -0.1731978744360067 */
- -5206, /* k2g1[9] = -0.15887024228080968 */
- -4775, /* k2g1[10] = -0.14572785009373057 */
- -4380, /* k2g1[11] = -0.13367265000706827 */
- -4018, /* k2g1[12] = -0.1226147050712642 */
- -3685, /* k2g1[13] = -0.11247151828678581 */
- -3381, /* k2g1[14] = -0.10316741714122014 */
- -3101, /* k2g1[15] = -0.0946329890599603 */
- -2844, /* k2g1[16] = -0.08680456355870586 */
- -2609, /* k2g1[17] = -0.07962373723441349 */
- -2393, /* k2g1[18] = -0.07303693805092666 */
- -2195, /* k2g1[19] = -0.06699502566866912 */
- -2014, /* k2g1[20] = -0.06145292483669077 */
- -1847, /* k2g1[21] = -0.056369289112013346 */
- -1694, /* k2g1[22] = -0.05170619239747895 */
- -1554, /* k2g1[23] = -0.04742884599684141 */
- -1426, /* k2g1[24] = -0.043505339076210514 */
- -1308, /* k2g1[25] = -0.03990640059558053 */
- -1199, /* k2g1[26] = -0.03660518093435039 */
- -1100, /* k2g1[27] = -0.03357705158166837 */
- -1009, /* k2g1[28] = -0.030799421397205727 */
- -926, /* k2g1[29] = -0.028251568071585884 */
- -849 /* k2g1[30] = -0.025914483529091967 */
+ -11324, /* k2g1[0] = -0.3455751918948761 */
+ -10387, /* k2g1[1] = -0.3169878073928751 */
+ -9528, /* k2g1[2] = -0.29076528753345476 */
+ -8740, /* k2g1[3] = -0.2667120011011279 */
+ -8017, /* k2g1[4] = -0.24464850028971705 */
+ -7353, /* k2g1[5] = -0.22441018194495696 */
+ -6745, /* k2g1[6] = -0.20584605955455101 */
+ -6187, /* k2g1[7] = -0.18881763682420102 */
+ -5675, /* k2g1[8] = -0.1731978744360067 */
+ -5206, /* k2g1[9] = -0.15887024228080968 */
+ -4775, /* k2g1[10] = -0.14572785009373057 */
+ -4380, /* k2g1[11] = -0.13367265000706827 */
+ -4018, /* k2g1[12] = -0.1226147050712642 */
+ -3685, /* k2g1[13] = -0.11247151828678581 */
+ -3381, /* k2g1[14] = -0.10316741714122014 */
+ -3101, /* k2g1[15] = -0.0946329890599603 */
+ -2844, /* k2g1[16] = -0.08680456355870586 */
+ -2609, /* k2g1[17] = -0.07962373723441349 */
+ -2393, /* k2g1[18] = -0.07303693805092666 */
+ -2195, /* k2g1[19] = -0.06699502566866912 */
+ -2014, /* k2g1[20] = -0.06145292483669077 */
+ -1847, /* k2g1[21] = -0.056369289112013346 */
+ -1694, /* k2g1[22] = -0.05170619239747895 */
+ -1554, /* k2g1[23] = -0.04742884599684141 */
+ -1426, /* k2g1[24] = -0.043505339076210514 */
+ -1308, /* k2g1[25] = -0.03990640059558053 */
+ -1199, /* k2g1[26] = -0.03660518093435039 */
+ -1100, /* k2g1[27] = -0.03357705158166837 */
+ -1009, /* k2g1[28] = -0.030799421397205727 */
+ -926, /* k2g1[29] = -0.028251568071585884 */
+ -849 /* k2g1[30] = -0.025914483529091967 */
};
-static const EAS_I16 k2g2[] =
+static const EAS_I16 k2g2[] =
{
- 1957, /* k2g2[0] = 0.059711106626580836 */
- 1646, /* k2g2[1] = 0.05024063501786333 */
- 1385, /* k2g2[2] = 0.042272226217199664 */
- 1165, /* k2g2[3] = 0.03556764576567844 */
- 981, /* k2g2[4] = 0.029926444346999134 */
- 825, /* k2g2[5] = 0.025179964880280382 */
- 694, /* k2g2[6] = 0.02118630011706455 */
- 584, /* k2g2[7] = 0.01782604998793514 */
- 491, /* k2g2[8] = 0.014998751854573014 */
- 414, /* k2g2[9] = 0.012619876941179595 */
- 348, /* k2g2[10] = 0.010618303146468736 */
- 293, /* k2g2[11] = 0.008934188679954682 */
- 246, /* k2g2[12] = 0.007517182949855368 */
- 207, /* k2g2[13] = 0.006324921212866403 */
- 174, /* k2g2[14] = 0.005321757979794424 */
- 147, /* k2g2[15] = 0.004477701309210577 */
- 123, /* k2g2[16] = 0.00376751612730811 */
- 104, /* k2g2[17] = 0.0031699697655869644 */
- 87, /* k2g2[18] = 0.00266719715992703 */
- 74, /* k2g2[19] = 0.0022441667321724647 */
- 62, /* k2g2[20] = 0.0018882309854916855 */
- 52, /* k2g2[21] = 0.0015887483774966232 */
- 44, /* k2g2[22] = 0.0013367651661223448 */
- 37, /* k2g2[23] = 0.0011247477162958733 */
- 31, /* k2g2[24] = 0.0009463572640678758 */
- 26, /* k2g2[25] = 0.0007962604042473498 */
- 22, /* k2g2[26] = 0.0006699696356181593 */
- 18, /* k2g2[27] = 0.0005637091964589207 */
- 16, /* k2g2[28] = 0.00047430217920125243 */
- 13, /* k2g2[29] = 0.00039907554925166274 */
- 11 /* k2g2[30] = 0.00033578022828973666 */
+ 1957, /* k2g2[0] = 0.059711106626580836 */
+ 1646, /* k2g2[1] = 0.05024063501786333 */
+ 1385, /* k2g2[2] = 0.042272226217199664 */
+ 1165, /* k2g2[3] = 0.03556764576567844 */
+ 981, /* k2g2[4] = 0.029926444346999134 */
+ 825, /* k2g2[5] = 0.025179964880280382 */
+ 694, /* k2g2[6] = 0.02118630011706455 */
+ 584, /* k2g2[7] = 0.01782604998793514 */
+ 491, /* k2g2[8] = 0.014998751854573014 */
+ 414, /* k2g2[9] = 0.012619876941179595 */
+ 348, /* k2g2[10] = 0.010618303146468736 */
+ 293, /* k2g2[11] = 0.008934188679954682 */
+ 246, /* k2g2[12] = 0.007517182949855368 */
+ 207, /* k2g2[13] = 0.006324921212866403 */
+ 174, /* k2g2[14] = 0.005321757979794424 */
+ 147, /* k2g2[15] = 0.004477701309210577 */
+ 123, /* k2g2[16] = 0.00376751612730811 */
+ 104, /* k2g2[17] = 0.0031699697655869644 */
+ 87, /* k2g2[18] = 0.00266719715992703 */
+ 74, /* k2g2[19] = 0.0022441667321724647 */
+ 62, /* k2g2[20] = 0.0018882309854916855 */
+ 52, /* k2g2[21] = 0.0015887483774966232 */
+ 44, /* k2g2[22] = 0.0013367651661223448 */
+ 37, /* k2g2[23] = 0.0011247477162958733 */
+ 31, /* k2g2[24] = 0.0009463572640678758 */
+ 26, /* k2g2[25] = 0.0007962604042473498 */
+ 22, /* k2g2[26] = 0.0006699696356181593 */
+ 18, /* k2g2[27] = 0.0005637091964589207 */
+ 16, /* k2g2[28] = 0.00047430217920125243 */
+ 13, /* k2g2[29] = 0.00039907554925166274 */
+ 11 /* k2g2[30] = 0.00033578022828973666 */
};
-static const EAS_I16 n1g2[] =
+static const EAS_I16 n1g2[] =
{
- 3170, /* n1g2[0] = 0.0967319927350769 */
- 3036, /* n1g2[1] = 0.0926446051254155 */
- 2908, /* n1g2[2] = 0.08872992911818503 */
- 2785, /* n1g2[3] = 0.08498066682523227 */
- 2667, /* n1g2[4] = 0.08138982872895201 */
- 2554, /* n1g2[5] = 0.07795072065216213 */
- 2446, /* n1g2[6] = 0.0746569312785634 */
- 2343, /* n1g2[7] = 0.07150232020051943 */
- 2244, /* n1g2[8] = 0.06848100647187474 */
- 2149, /* n1g2[9] = 0.06558735764447099 */
- 2058, /* n1g2[10] = 0.06281597926792246 */
- 1971, /* n1g2[11] = 0.06016170483307614 */
- 1888, /* n1g2[12] = 0.05761958614040857 */
- 1808, /* n1g2[13] = 0.05518488407540374 */
- 1732, /* n1g2[14] = 0.052853059773715245 */
- 1659, /* n1g2[15] = 0.05061976615964251 */
- 1589, /* n1g2[16] = 0.04848083984214659 */
- 1521, /* n1g2[17] = 0.046432293353298 */
- 1457, /* n1g2[18] = 0.04447030771468711 */
- 1396, /* n1g2[19] = 0.04259122531793907 */
- 1337, /* n1g2[20] = 0.040791543106060944 */
- 1280, /* n1g2[21] = 0.03906790604290942 */
- 1226, /* n1g2[22] = 0.037417100858604564 */
- 1174, /* n1g2[23] = 0.035836050059229754 */
- 1125, /* n1g2[24] = 0.03432180618965023 */
- 1077, /* n1g2[25] = 0.03287154633875494 */
- 1032, /* n1g2[26] = 0.03148256687687814 */
- 988, /* n1g2[27] = 0.030152278415589925 */
- 946, /* n1g2[28] = 0.028878200980459685 */
- 906, /* n1g2[29] = 0.02765795938779331 */
- 868 /* n1g2[30] = 0.02648927881672521 */
+ 3170, /* n1g2[0] = 0.0967319927350769 */
+ 3036, /* n1g2[1] = 0.0926446051254155 */
+ 2908, /* n1g2[2] = 0.08872992911818503 */
+ 2785, /* n1g2[3] = 0.08498066682523227 */
+ 2667, /* n1g2[4] = 0.08138982872895201 */
+ 2554, /* n1g2[5] = 0.07795072065216213 */
+ 2446, /* n1g2[6] = 0.0746569312785634 */
+ 2343, /* n1g2[7] = 0.07150232020051943 */
+ 2244, /* n1g2[8] = 0.06848100647187474 */
+ 2149, /* n1g2[9] = 0.06558735764447099 */
+ 2058, /* n1g2[10] = 0.06281597926792246 */
+ 1971, /* n1g2[11] = 0.06016170483307614 */
+ 1888, /* n1g2[12] = 0.05761958614040857 */
+ 1808, /* n1g2[13] = 0.05518488407540374 */
+ 1732, /* n1g2[14] = 0.052853059773715245 */
+ 1659, /* n1g2[15] = 0.05061976615964251 */
+ 1589, /* n1g2[16] = 0.04848083984214659 */
+ 1521, /* n1g2[17] = 0.046432293353298 */
+ 1457, /* n1g2[18] = 0.04447030771468711 */
+ 1396, /* n1g2[19] = 0.04259122531793907 */
+ 1337, /* n1g2[20] = 0.040791543106060944 */
+ 1280, /* n1g2[21] = 0.03906790604290942 */
+ 1226, /* n1g2[22] = 0.037417100858604564 */
+ 1174, /* n1g2[23] = 0.035836050059229754 */
+ 1125, /* n1g2[24] = 0.03432180618965023 */
+ 1077, /* n1g2[25] = 0.03287154633875494 */
+ 1032, /* n1g2[26] = 0.03148256687687814 */
+ 988, /* n1g2[27] = 0.030152278415589925 */
+ 946, /* n1g2[28] = 0.028878200980459685 */
+ 906, /* n1g2[29] = 0.02765795938779331 */
+ 868 /* n1g2[30] = 0.02648927881672521 */
};
-static const EAS_I16 n1g3[] =
+static const EAS_I16 n1g3[] =
{
- -548, /* n1g3[0] = -0.016714088475899017 */
- -481, /* n1g3[1] = -0.014683605122742116 */
- -423, /* n1g3[2] = -0.012899791676436092 */
- -371, /* n1g3[3] = -0.01133268185193299 */
- -326, /* n1g3[4] = -0.00995594976868754 */
- -287, /* n1g3[5] = -0.008746467702146129 */
- -252, /* n1g3[6] = -0.00768391756106361 */
- -221, /* n1g3[7] = -0.006750449563854721 */
- -194, /* n1g3[8] = -0.005930382380083576 */
- -171, /* n1g3[9] = -0.005209939699767622 */
- -150, /* n1g3[10] = -0.004577018805123356 */
- -132, /* n1g3[11] = -0.004020987256990177 */
- -116, /* n1g3[12] = -0.003532504280467257 */
- -102, /* n1g3[13] = -0.00310336384922047 */
- -89, /* n1g3[14] = -0.002726356832432369 */
- -78, /* n1g3[15] = -0.002395149888601605 */
- -69, /* n1g3[16] = -0.0021041790717285314 */
- -61, /* n1g3[17] = -0.0018485563625771063 */
- -53, /* n1g3[18] = -0.001623987554831628 */
- -47, /* n1g3[19] = -0.0014267001167177025 */
- -41, /* n1g3[20] = -0.0012533798162347005 */
- -36, /* n1g3[21] = -0.0011011150453668693 */
- -32, /* n1g3[22] = -0.0009673479079754438 */
- -28, /* n1g3[23] = -0.0008498312496971563 */
- -24, /* n1g3[24] = -0.0007465909079943587 */
- -21, /* n1g3[25] = -0.0006558925481952733 */
- -19, /* n1g3[26] = -0.0005762125284029567 */
- -17, /* n1g3[27] = -0.0005062123038325457 */
- -15, /* n1g3[28] = -0.0004447159405951901 */
- -13, /* n1g3[29] = -0.00039069036118270117 */
- -11 /* n1g3[30] = -0.00034322798979677605 */
+ -548, /* n1g3[0] = -0.016714088475899017 */
+ -481, /* n1g3[1] = -0.014683605122742116 */
+ -423, /* n1g3[2] = -0.012899791676436092 */
+ -371, /* n1g3[3] = -0.01133268185193299 */
+ -326, /* n1g3[4] = -0.00995594976868754 */
+ -287, /* n1g3[5] = -0.008746467702146129 */
+ -252, /* n1g3[6] = -0.00768391756106361 */
+ -221, /* n1g3[7] = -0.006750449563854721 */
+ -194, /* n1g3[8] = -0.005930382380083576 */
+ -171, /* n1g3[9] = -0.005209939699767622 */
+ -150, /* n1g3[10] = -0.004577018805123356 */
+ -132, /* n1g3[11] = -0.004020987256990177 */
+ -116, /* n1g3[12] = -0.003532504280467257 */
+ -102, /* n1g3[13] = -0.00310336384922047 */
+ -89, /* n1g3[14] = -0.002726356832432369 */
+ -78, /* n1g3[15] = -0.002395149888601605 */
+ -69, /* n1g3[16] = -0.0021041790717285314 */
+ -61, /* n1g3[17] = -0.0018485563625771063 */
+ -53, /* n1g3[18] = -0.001623987554831628 */
+ -47, /* n1g3[19] = -0.0014267001167177025 */
+ -41, /* n1g3[20] = -0.0012533798162347005 */
+ -36, /* n1g3[21] = -0.0011011150453668693 */
+ -32, /* n1g3[22] = -0.0009673479079754438 */
+ -28, /* n1g3[23] = -0.0008498312496971563 */
+ -24, /* n1g3[24] = -0.0007465909079943587 */
+ -21, /* n1g3[25] = -0.0006558925481952733 */
+ -19, /* n1g3[26] = -0.0005762125284029567 */
+ -17, /* n1g3[27] = -0.0005062123038325457 */
+ -15, /* n1g3[28] = -0.0004447159405951901 */
+ -13, /* n1g3[29] = -0.00039069036118270117 */
+ -11 /* n1g3[30] = -0.00034322798979677605 */
};
/*----------------------------------------------------------------------------
* WT_SetFilterCoeffs()
*----------------------------------------------------------------------------
- * Purpose:
+ * Purpose:
* Update the Filter parameters
*
- * Inputs:
- * pVoice - ptr to the voice whose filter we want to update
+ * Inputs:
+ * pVoice - ptr to the voice whose filter we want to update
* pEASData - pointer to overall EAS data structure
*
* Outputs:
@@ -1226,32 +1226,32 @@ static const EAS_I16 n1g3[] =
*/
void WT_SetFilterCoeffs (S_WT_INT_FRAME *pIntFrame, EAS_I32 cutoff, EAS_I32 resonance)
{
- EAS_I32 temp;
-
- /*
- Convert the cutoff, which has had A5 subtracted, using the 2^x approx
- Note, this cutoff is related to theta cutoff by
- theta = k * 2^x
- We use 2^x and incorporate k in the power series coefs instead
- */
- cutoff = EAS_Calculate2toX(cutoff);
-
- /* calculate b2 coef */
- temp = k2g1[resonance] + MULT_AUDIO_COEF(cutoff, k2g2[resonance]);
- temp = k2g0 + MULT_AUDIO_COEF(cutoff, temp);
- pIntFrame->frame.b2 = temp;
-
- /* calculate b1 coef */
- temp = MULT_AUDIO_COEF(cutoff, nk1g2);
- temp = nk1g0 + MULT_AUDIO_COEF(cutoff, temp);
- temp += MULT_AUDIO_COEF(temp, pIntFrame->frame.b2);
- pIntFrame->frame.b1 = temp >> 1;
-
- /* calculate K coef */
- temp = n1g2[resonance] + MULT_AUDIO_COEF(cutoff, n1g3[resonance]);
- temp = MULT_AUDIO_COEF(cutoff, temp);
- temp = MULT_AUDIO_COEF(cutoff, temp);
- pIntFrame->frame.k = temp;
+ EAS_I32 temp;
+
+ /*
+ Convert the cutoff, which has had A5 subtracted, using the 2^x approx
+ Note, this cutoff is related to theta cutoff by
+ theta = k * 2^x
+ We use 2^x and incorporate k in the power series coefs instead
+ */
+ cutoff = EAS_Calculate2toX(cutoff);
+
+ /* calculate b2 coef */
+ temp = k2g1[resonance] + MULT_AUDIO_COEF(cutoff, k2g2[resonance]);
+ temp = k2g0 + MULT_AUDIO_COEF(cutoff, temp);
+ pIntFrame->frame.b2 = temp;
+
+ /* calculate b1 coef */
+ temp = MULT_AUDIO_COEF(cutoff, nk1g2);
+ temp = nk1g0 + MULT_AUDIO_COEF(cutoff, temp);
+ temp += MULT_AUDIO_COEF(temp, pIntFrame->frame.b2);
+ pIntFrame->frame.b1 = temp >> 1;
+
+ /* calculate K coef */
+ temp = n1g2[resonance] + MULT_AUDIO_COEF(cutoff, n1g3[resonance]);
+ temp = MULT_AUDIO_COEF(cutoff, temp);
+ temp = MULT_AUDIO_COEF(cutoff, temp);
+ pIntFrame->frame.k = temp;
}
#endif
diff --git a/arm-wt-22k/lib_src/eas_wtsynth.h b/arm-wt-22k/lib_src/eas_wtsynth.h
index 106ab40..90a7ad8 100644
--- a/arm-wt-22k/lib_src/eas_wtsynth.h
+++ b/arm-wt-22k/lib_src/eas_wtsynth.h
@@ -1,12 +1,12 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_wtsynth.h
- *
- * Contents and purpose:
- * This file defines the interface for synthesizer engine
- *
- * Copyright Sonic Network Inc. 2004
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_wtsynth.h
+ *
+ * Contents and purpose:
+ * This file defines the interface for synthesizer engine
+ *
+ * Copyright Sonic Network Inc. 2004
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,48 +19,48 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 82 $
- * $Date: 2006-07-10 11:45:19 -0700 (Mon, 10 Jul 2006) $
- *----------------------------------------------------------------------------
-*/
-
-#ifndef _EAS_WTSYNTH_H
-#define _EAS_WTSYNTH_H
-
-#include "eas_sndlib.h"
-#include "eas_wtengine.h"
-
-/* adjust the filter cutoff frequency to the sample rate */
-#if defined (_SAMPLE_RATE_8000)
-#define FILTER_CUTOFF_FREQ_ADJUST 0
-#elif defined (_SAMPLE_RATE_16000)
-#define FILTER_CUTOFF_FREQ_ADJUST 1200
-#elif defined (_SAMPLE_RATE_20000)
-#define FILTER_CUTOFF_FREQ_ADJUST 1586
-#elif defined (_SAMPLE_RATE_22050)
-#define FILTER_CUTOFF_FREQ_ADJUST 1756
-#elif defined (_SAMPLE_RATE_24000)
-#define FILTER_CUTOFF_FREQ_ADJUST 1902
-#elif defined (_SAMPLE_RATE_32000)
-#define FILTER_CUTOFF_FREQ_ADJUST 2400
-#elif defined (_SAMPLE_RATE_44100)
-#define FILTER_CUTOFF_FREQ_ADJUST 2956
-#elif defined (_SAMPLE_RATE_48000)
-#define FILTER_CUTOFF_FREQ_ADJUST 3102
-#else
-#error "_SAMPLE_RATE_XXXXX must be defined to valid rate"
-#endif
-
-/* function prototypes */
-void WT_UpdateLFO (S_LFO_CONTROL *pLFO, EAS_I16 phaseInc);
-
-#if defined(_FILTER_ENABLED) || defined(DLS_SYNTHESIZER)
-void WT_SetFilterCoeffs (S_WT_INT_FRAME *pIntFrame, EAS_I32 cutoff, EAS_I32 resonance);
-#endif
-
-#endif
-
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 82 $
+ * $Date: 2006-07-10 11:45:19 -0700 (Mon, 10 Jul 2006) $
+ *----------------------------------------------------------------------------
+*/
+
+#ifndef _EAS_WTSYNTH_H
+#define _EAS_WTSYNTH_H
+
+#include "eas_sndlib.h"
+#include "eas_wtengine.h"
+
+/* adjust the filter cutoff frequency to the sample rate */
+#if defined (_SAMPLE_RATE_8000)
+#define FILTER_CUTOFF_FREQ_ADJUST 0
+#elif defined (_SAMPLE_RATE_16000)
+#define FILTER_CUTOFF_FREQ_ADJUST 1200
+#elif defined (_SAMPLE_RATE_20000)
+#define FILTER_CUTOFF_FREQ_ADJUST 1586
+#elif defined (_SAMPLE_RATE_22050)
+#define FILTER_CUTOFF_FREQ_ADJUST 1756
+#elif defined (_SAMPLE_RATE_24000)
+#define FILTER_CUTOFF_FREQ_ADJUST 1902
+#elif defined (_SAMPLE_RATE_32000)
+#define FILTER_CUTOFF_FREQ_ADJUST 2400
+#elif defined (_SAMPLE_RATE_44100)
+#define FILTER_CUTOFF_FREQ_ADJUST 2956
+#elif defined (_SAMPLE_RATE_48000)
+#define FILTER_CUTOFF_FREQ_ADJUST 3102
+#else
+#error "_SAMPLE_RATE_XXXXX must be defined to valid rate"
+#endif
+
+/* function prototypes */
+void WT_UpdateLFO (S_LFO_CONTROL *pLFO, EAS_I16 phaseInc);
+
+#if defined(_FILTER_ENABLED) || defined(DLS_SYNTHESIZER)
+void WT_SetFilterCoeffs (S_WT_INT_FRAME *pIntFrame, EAS_I32 cutoff, EAS_I32 resonance);
+#endif
+
+#endif
+
+
diff --git a/arm-wt-22k/lib_src/eas_xmf.c b/arm-wt-22k/lib_src/eas_xmf.c
index b498b42..0a92425 100644
--- a/arm-wt-22k/lib_src/eas_xmf.c
+++ b/arm-wt-22k/lib_src/eas_xmf.c
@@ -1,12 +1,12 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_xmf.c
- * 5
- * Contents and purpose:
- * XMF File Parser
- *
- * Copyright Sonic Network Inc. 2005
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_xmf.c
+ * 5
+ * Contents and purpose:
+ * XMF File Parser
+ *
+ * Copyright Sonic Network Inc. 2005
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,832 +19,832 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 501 $
- * $Date: 2006-12-11 17:53:36 -0800 (Mon, 11 Dec 2006) $
- *----------------------------------------------------------------------------
-*/
-
-#include "eas_data.h"
-#include "eas_miditypes.h"
-#include "eas_parser.h"
-#include "eas_report.h"
-#include "eas_host.h"
-#include "eas_midi.h"
-#include "eas_xmf.h"
-#include "eas_xmfdata.h"
-#include "eas_config.h"
-#include "eas_vm_protos.h"
-#include "eas_mdls.h"
-#include "eas_smf.h"
-
-
-/* XMF header file type */
-#define XMF_IDENTIFIER 0x584d465f
-#define XMF_VERSION_2_00 0x322e3030
-#define XMF_FILE_TYPE 0x00000002
-#define XMF_SPEC_LEVEL 0x00000001
-#define XMF_RIFF_CHUNK 0x52494646
-#define XMF_RIFF_DLS 0x444c5320
-#define XMF_SMF_CHUNK 0x4d546864
-
-/* local prototypes */
-static EAS_RESULT XMF_CheckFileType (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle, EAS_VOID_PTR *ppHandle, EAS_I32 offset);
-static EAS_RESULT XMF_Prepare (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
-static EAS_RESULT XMF_Time (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_U32 *pTime);
-static EAS_RESULT XMF_Event (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_INT parserMode);
-static EAS_RESULT XMF_State (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_STATE *pState);
-static EAS_RESULT XMF_Close (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
-static EAS_RESULT XMF_Reset (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
-static EAS_RESULT XMF_Pause (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
-static EAS_RESULT XMF_Resume (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
-static EAS_RESULT XMF_SetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value);
-static EAS_RESULT XMF_GetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue);
-static EAS_RESULT XMF_FindFileContents (EAS_HW_DATA_HANDLE hwInstData, S_XMF_DATA *pXMFData);
-static EAS_RESULT XMF_ReadNode (EAS_HW_DATA_HANDLE hwInstData, S_XMF_DATA *pXMFData, EAS_I32 nodeOffset, EAS_I32 *pLength);
-static EAS_RESULT XMF_ReadVLQ (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE fileHandle, EAS_I32 *value);
-
-
-/*----------------------------------------------------------------------------
- *
- * XMF_Parser
- *
- * This structure contains the functional interface for the XMF parser
- *----------------------------------------------------------------------------
-*/
-const S_FILE_PARSER_INTERFACE EAS_XMF_Parser =
-{
- XMF_CheckFileType,
- XMF_Prepare,
- XMF_Time,
- XMF_Event,
- XMF_State,
- XMF_Close,
- XMF_Reset,
- XMF_Pause,
- XMF_Resume,
- NULL,
- XMF_SetData,
- XMF_GetData,
- NULL
-};
-
-/*----------------------------------------------------------------------------
- * XMF_CheckFileType()
- *----------------------------------------------------------------------------
- * Purpose:
- * Check the file type to see if we can parse it
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT XMF_CheckFileType (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle, EAS_VOID_PTR *ppHandle, EAS_I32 offset)
-{
- S_XMF_DATA *pXMFData;
- EAS_RESULT result;
- EAS_U32 temp;
-
- /* assume we don't recognize it initially */
- *ppHandle = NULL;
-
- /* read the file identifier */
- if ((result = EAS_HWGetDWord(pEASData->hwInstData, fileHandle, &temp, EAS_TRUE)) != EAS_SUCCESS)
- return result;
- if (temp != XMF_IDENTIFIER)
- return EAS_SUCCESS;
-
- /* read the version */
- if ((result = EAS_HWGetDWord(pEASData->hwInstData, fileHandle, &temp, EAS_TRUE)) != EAS_SUCCESS)
- return result;
- if (temp != XMF_VERSION_2_00)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "XMF file version was 0x%08x, expected 0x%08x\n", temp, XMF_VERSION_2_00); */ }
- return EAS_SUCCESS;
- }
-
- /* read the file type */
- if ((result = EAS_HWGetDWord(pEASData->hwInstData, fileHandle, &temp, EAS_TRUE)) != EAS_SUCCESS)
- return result;
- if (temp != XMF_FILE_TYPE)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "XMF file type was 0x%08x, expected 0x%08x\n", temp, XMF_FILE_TYPE); */ }
- return EAS_SUCCESS;
- }
-
- /* read the spec level */
- if ((result = EAS_HWGetDWord(pEASData->hwInstData, fileHandle, &temp, EAS_TRUE)) != EAS_SUCCESS)
- return result;
- if (temp != XMF_SPEC_LEVEL)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "XMF file spec was 0x%08x, expected 0x%08x\n", temp, XMF_SPEC_LEVEL); */ }
- return EAS_SUCCESS;
- }
-
- /* check for static memory allocation */
- if (pEASData->staticMemoryModel)
- pXMFData = EAS_CMEnumData(EAS_CM_XMF_DATA);
- else
- pXMFData = EAS_HWMalloc(pEASData->hwInstData, sizeof(S_XMF_DATA));
- if (!pXMFData)
- return EAS_ERROR_MALLOC_FAILED;
-
- /* zero the memory to insure complete initialization */
- EAS_HWMemSet((void *)pXMFData,0, sizeof(S_XMF_DATA));
-
- pXMFData->fileHandle = fileHandle;
- pXMFData->fileOffset = offset;
- *ppHandle = pXMFData;
-
- /* locate the SMF and DLS contents */
- if ((result = XMF_FindFileContents(pEASData->hwInstData, pXMFData)) != EAS_SUCCESS)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "No SMF data found in XMF file\n"); */ }
- return result;
- }
-
- /* let the SMF parser take over */
- if ((result = EAS_HWFileSeek(pEASData->hwInstData, fileHandle, pXMFData->midiOffset)) != EAS_SUCCESS)
- return result;
- return SMF_CheckFileType(pEASData, fileHandle, &pXMFData->pSMFData, pXMFData->midiOffset);
-}
-
-/*----------------------------------------------------------------------------
- * XMF_Prepare()
- *----------------------------------------------------------------------------
- * Purpose:
- * Prepare to parse the file. Allocates instance data (or uses static allocation for
- * static memory model).
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT XMF_Prepare (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
-{
- S_XMF_DATA* pXMFData;
- EAS_RESULT result;
-
- /* parse DLS collection */
- pXMFData = (S_XMF_DATA*) pInstData;
- if (pXMFData->dlsOffset != 0)
- {
- if ((result = DLSParser(pEASData->hwInstData, pXMFData->fileHandle, pXMFData->dlsOffset, &pXMFData->pDLS)) != EAS_SUCCESS)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Error converting XMF DLS data\n"); */ }
- return result;
- }
- }
-
- /* Prepare the SMF parser */
- if ((result = SMF_Prepare(pEASData, pXMFData->pSMFData)) != EAS_SUCCESS)
- return result;
-
- /* if no DLS file, skip this step */
- if (pXMFData->pDLS == NULL)
- return EAS_SUCCESS;
-
- /* tell the synth to use the DLS collection */
- result = VMSetDLSLib(((S_SMF_DATA*) pXMFData->pSMFData)->pSynth, pXMFData->pDLS);
- if (result == EAS_SUCCESS)
- {
- DLSAddRef(pXMFData->pDLS);
- VMInitializeAllChannels(pEASData->pVoiceMgr, ((S_SMF_DATA*) pXMFData->pSMFData)->pSynth);
- }
- return result;
-}
-
-/*----------------------------------------------------------------------------
- * XMF_Time()
- *----------------------------------------------------------------------------
- * Purpose:
- * Returns the time of the next event in msecs
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- * pTime - pointer to variable to hold time of next event (in msecs)
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT XMF_Time (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_U32 *pTime)
-{
- return SMF_Time(pEASData, ((S_XMF_DATA*) pInstData)->pSMFData, pTime);
-}
-
-/*----------------------------------------------------------------------------
- * XMF_Event()
- *----------------------------------------------------------------------------
- * Purpose:
- * Parse the next event in the file
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT XMF_Event (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_INT parserMode)
-{
- return SMF_Event(pEASData, ((S_XMF_DATA*) pInstData)->pSMFData, parserMode);
-}
-
-/*----------------------------------------------------------------------------
- * XMF_State()
- *----------------------------------------------------------------------------
- * Purpose:
- * Returns the current state of the stream
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- * pState - pointer to variable to store state
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT XMF_State (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 *pState)
-{
- return SMF_State(pEASData, ((S_XMF_DATA*) pInstData)->pSMFData, pState);
-}
-
-/*----------------------------------------------------------------------------
- * XMF_Close()
- *----------------------------------------------------------------------------
- * Purpose:
- * Close the file and clean up
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT XMF_Close (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
-{
- S_XMF_DATA* pXMFData;
- EAS_RESULT result;
-
- pXMFData = (S_XMF_DATA *)pInstData;
-
- /* close the SMF stream, it will close the file handle */
- if ((result = SMF_Close(pEASData, pXMFData->pSMFData)) != EAS_SUCCESS)
- return result;
-
- if (pXMFData->pDLS)
- DLSCleanup(pEASData->hwInstData, pXMFData->pDLS);
-
- /* if using dynamic memory, free it */
- if (!pEASData->staticMemoryModel)
- {
- /* free the instance data */
- EAS_HWFree(pEASData->hwInstData, pXMFData);
- }
-
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * XMF_Reset()
- *----------------------------------------------------------------------------
- * Purpose:
- * Reset the sequencer. Used for locating backwards in the file.
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT XMF_Reset (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
-{
- return SMF_Reset(pEASData, ((S_XMF_DATA*) pInstData)->pSMFData);
-}
-
-/*----------------------------------------------------------------------------
- * XMF_Pause()
- *----------------------------------------------------------------------------
- * Purpose:
- * Pauses the sequencer. Mutes all voices and sets state to pause.
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT XMF_Pause (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
-{
- return SMF_Pause(pEASData, ((S_XMF_DATA*) pInstData)->pSMFData);
-}
-
-/*----------------------------------------------------------------------------
- * XMF_Resume()
- *----------------------------------------------------------------------------
- * Purpose:
- * Resume playing after a pause, sets state back to playing.
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT XMF_Resume (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
-{
- return SMF_Resume(pEASData, ((S_XMF_DATA*) pInstData)->pSMFData);
-}
-
-/*----------------------------------------------------------------------------
- * XMF_SetData()
- *----------------------------------------------------------------------------
- * Purpose:
- * Sets the playback rate of the underlying SMF file
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- * rate - rate (28-bit fraction)
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT XMF_SetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value)
-{
- return SMF_SetData(pEASData, ((S_XMF_DATA*) pInstData)->pSMFData, param, value);
-}
-
-/*----------------------------------------------------------------------------
- * XMF_GetData()
- *----------------------------------------------------------------------------
- * Purpose:
- * Gets the file type
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- * rate - rate (28-bit fraction)
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT XMF_GetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue)
-{
- EAS_RESULT result;
-
- /* call SMF parser to get value */
- if ((result = SMF_GetData(pEASData, ((S_XMF_DATA*) pInstData)->pSMFData, param, pValue)) != EAS_SUCCESS)
- return result;
-
- /* special case for file type */
- if (param == PARSER_DATA_FILE_TYPE)
- {
- if (*pValue == EAS_FILE_SMF0)
- *pValue = EAS_FILE_XMF0;
- else if (*pValue == EAS_FILE_SMF1)
- *pValue = EAS_FILE_XMF1;
- }
-
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * XMF_FindFileContents()
- *----------------------------------------------------------------------------
- * Purpose:
- * Finds SMF data and DLS data in XMF file, and remembers offset for each.
- * If more than one is found, uses the first one found of each.
- * Makes assumptions about the format of a mobile XMF file
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * pXMFData - pointer to XMF parser instance data
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT XMF_FindFileContents (EAS_HW_DATA_HANDLE hwInstData, S_XMF_DATA *pXMFData)
-{
- EAS_RESULT result;
- EAS_I32 value;
- EAS_I32 length;
-
- /* initialize offsets */
- pXMFData->dlsOffset = pXMFData->midiOffset = 0;
-
- /* read file length, ignore it for now */
- if ((result = XMF_ReadVLQ(hwInstData, pXMFData->fileHandle, &value)) != EAS_SUCCESS)
- return result;
-
- /* read MetaDataTypesTable length and skip over it */
- if ((result = XMF_ReadVLQ(hwInstData, pXMFData->fileHandle, &value)) != EAS_SUCCESS)
- return result;
- if ((result = EAS_HWFileSeekOfs(hwInstData, pXMFData->fileHandle, value)) != EAS_SUCCESS)
- return result;
-
- /* get TreeStart offset and jump to it */
- if ((result = XMF_ReadVLQ(hwInstData, pXMFData->fileHandle, &value)) != EAS_SUCCESS)
- return result;
- if ((result = XMF_ReadNode(hwInstData, pXMFData, value, &length)) != EAS_SUCCESS)
- return result;
-
- /* check for SMF data */
- if (pXMFData->midiOffset == 0)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "No SMF data found in XMF file\n"); */ }
- return EAS_ERROR_FILE_FORMAT;
- }
-
- /* check for SFM in wrong order */
- if ((pXMFData->dlsOffset > 0) && (pXMFData->midiOffset < pXMFData->dlsOffset))
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "DLS data must precede SMF data in Mobile XMF file\n"); */ }
-
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * XMF_ReadNode()
- *----------------------------------------------------------------------------
- * Purpose:
- *
- * Inputs:
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT XMF_ReadNode (EAS_HW_DATA_HANDLE hwInstData, S_XMF_DATA *pXMFData, EAS_I32 nodeOffset, EAS_I32 *pLength)
-{
- EAS_RESULT result;
- EAS_I32 refType;
- EAS_I32 numItems;
- EAS_I32 offset;
- EAS_I32 length;
- EAS_I32 headerLength;
- EAS_U32 chunkType;
-
- /* seek to start of node */
- if ((result = EAS_HWFileSeek(hwInstData, pXMFData->fileHandle, nodeOffset)) != EAS_SUCCESS)
- return result;
-
- /* get node length */
- if ((result = XMF_ReadVLQ(hwInstData, pXMFData->fileHandle, pLength)) != EAS_SUCCESS)
- return result;
-
- /* get number of contained items */
- if ((result = XMF_ReadVLQ(hwInstData, pXMFData->fileHandle, &numItems)) != EAS_SUCCESS)
- return result;
-
- /* get node header length */
- if ((result = XMF_ReadVLQ(hwInstData, pXMFData->fileHandle, &headerLength)) != EAS_SUCCESS)
- return result;
-
- /* get metadata length */
- if ((result = XMF_ReadVLQ(hwInstData, pXMFData->fileHandle, &length)) != EAS_SUCCESS)
- return result;
-
- /* get the current location */
- if ((result = EAS_HWFilePos(hwInstData, pXMFData->fileHandle, &offset)) != EAS_SUCCESS)
- return result;
-
- /* skip to node contents */
- if ((result = EAS_HWFileSeek(hwInstData, pXMFData->fileHandle, nodeOffset + headerLength)) != EAS_SUCCESS)
- return result;
-
- /* get reference type */
- if ((result = XMF_ReadVLQ(hwInstData, pXMFData->fileHandle, &refType)) != EAS_SUCCESS)
- return result;
-
- /* get the current location */
- if ((result = EAS_HWFilePos(hwInstData, pXMFData->fileHandle, &offset)) != EAS_SUCCESS)
- return result;
-
- /* process file node */
- if (numItems == 0)
-
- {
- /* if in-file resource, find out where it is and jump to it */
- if (refType == 2)
- {
- if ((result = XMF_ReadVLQ(hwInstData, pXMFData->fileHandle, &offset)) != EAS_SUCCESS)
- return result;
- offset += pXMFData->fileOffset;
- if ((result = EAS_HWFileSeek(hwInstData, pXMFData->fileHandle, offset)) != EAS_SUCCESS)
- return result;
- }
-
- /* or else it must be an inline resource */
- else if (refType != 1)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Unexpected reference type %d\n", refType); */ }
- return EAS_ERROR_FILE_FORMAT;
- }
-
- /* get the chunk type */
- if ((result = EAS_HWGetDWord(hwInstData, pXMFData->fileHandle, &chunkType, EAS_TRUE)) != EAS_SUCCESS)
- return result;
-
- /* found a RIFF chunk, check for DLS type */
- if (chunkType == XMF_RIFF_CHUNK)
- {
- /* skip length */
- if ((result = EAS_HWFileSeekOfs(hwInstData, pXMFData->fileHandle, sizeof(EAS_I32))) != EAS_SUCCESS)
- return result;
-
- /* get RIFF file type */
- if ((result = EAS_HWGetDWord(hwInstData, pXMFData->fileHandle, &chunkType, EAS_TRUE)) != EAS_SUCCESS)
- return result;
- if (chunkType == XMF_RIFF_DLS)
- pXMFData->dlsOffset = offset;
- }
-
- /* found an SMF chunk */
- else if (chunkType == XMF_SMF_CHUNK)
- pXMFData->midiOffset = offset;
- }
-
- /* folder node, process the items in the list */
- else
- {
- for ( ; numItems > 0; numItems--)
- {
- /* process this item */
- if ((result = XMF_ReadNode(hwInstData, pXMFData, offset, &length)) != EAS_SUCCESS)
- return result;
-
- /* seek to start of next item */
- offset += length;
- if ((result = EAS_HWFileSeek(hwInstData, pXMFData->fileHandle, offset)) != EAS_SUCCESS)
- return result;
- }
- }
-
- return EAS_SUCCESS;
-}
-
-#if 0
-/*----------------------------------------------------------------------------
- * XMF_FindFileContents()
- *----------------------------------------------------------------------------
- * Purpose:
- * Finds SMF data and DLS data in XMF file, and remembers offset for each.
- * If more than one is found, uses the first one found of each.
- * Makes assumptions about the format of a mobile XMF file
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * pXMFData - pointer to XMF parser instance data
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT XMF_FindFileContents(S_EAS_DATA *pEASData, S_XMF_DATA *pXMFData, EAS_FILE_HANDLE fileHandle)
-{
- EAS_RESULT result;
- EAS_I32 offset;
- EAS_I32 value;
- EAS_I32 numItems;
- EAS_I32 length;
- EAS_CHAR id[4];
- EAS_I32 location;
-
- /* init dls offset, so that we know we haven't found a dls chunk yet */
- pXMFData->dlsOffset = 0;
-
- /* read file length, ignore it for now */
- if ((result = XMF_ReadVLQ(pEASData, fileHandle, &value)) != EAS_SUCCESS)
- return result;
-
- /* read MetaDataTypesTable length and skip over it */
- if ((result = XMF_ReadVLQ(pEASData, fileHandle, &value)) != EAS_SUCCESS)
- return result;
- if ((result = EAS_HWFileSeekOfs(pEASData, fileHandle, value)) != EAS_SUCCESS)
- return result;
-
- /* get TreeStart offset and jump to it */
- if ((result = XMF_ReadVLQ(pEASData, fileHandle, &offset)) != EAS_SUCCESS)
- return result;
- if ((result = EAS_HWFileSeek(pEASData->hwInstData, fileHandle, offset)) != EAS_SUCCESS)
- return result;
-
- /* read node length, ignore it for now */
- if ((result = XMF_ReadVLQ(pEASData, fileHandle, &value)) != EAS_SUCCESS)
- return result;
-
- /* read number of contained items */
- if ((result = XMF_ReadVLQ(pEASData, fileHandle, &numItems)) != EAS_SUCCESS)
- return result;
-
- /*read node header length */
- if ((result = XMF_ReadVLQ(pEASData, fileHandle, &value)) != EAS_SUCCESS)
- return result;
-
- /*go to the node offset */
- if ((result = EAS_HWFileSeek(pEASData->hwInstData, fileHandle, offset + value)) != EAS_SUCCESS)
- return result;
-
- /* read Reference Type */
- if ((result = XMF_ReadVLQ(pEASData, fileHandle, &value)) != EAS_SUCCESS)
- return result;
-
- /* make sure it is an in-line resource, for now */
- if (value != 1)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Problem parsing XMF file tree\n"); */ }
- return EAS_FAILURE;
- }
-
- /* parse through the list of items */
- while (numItems > 0)
- {
- /*get current offset */
- if ((result = EAS_HWFilePos(pEASData->hwInstData, fileHandle, &offset)) != EAS_SUCCESS)
- return result;
-
- /*read node length */
- if ((result = XMF_ReadVLQ(pEASData, fileHandle, &length)) != EAS_SUCCESS)
- return result;
-
- /* read number of items */
- if ((result = XMF_ReadVLQ(pEASData, fileHandle, &value)) != EAS_SUCCESS)
- return result;
-
- /* make sure not a folder */
- if (value != 0)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Problem parsing XMF file node\n"); */ }
- return EAS_FAILURE;
- }
-
- /* read offset to resource and jump to it */
- if ((result = XMF_ReadVLQ(pEASData, fileHandle, &value)) != EAS_SUCCESS)
- return result;
- if ((result = EAS_HWFileSeek(pEASData->hwInstData, fileHandle, offset + value)) != EAS_SUCCESS)
- return result;
-
- /* read Reference Type */
- if ((result = XMF_ReadVLQ(pEASData, fileHandle, &value)) != EAS_SUCCESS)
- return result;
-
- /* make sure it is an in-line resource */
- if (value != 1)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Problem parsing XMF file node\n"); */ }
- return EAS_FAILURE;
- }
-
- /* get current offset as a possible location for SMF file or DLS file */
- if ((result = EAS_HWFilePos(pEASData->hwInstData, fileHandle, &location)) != EAS_SUCCESS)
- return result;
-
- /* read four bytes */
- if ((result = EAS_HWReadFile(pEASData->hwInstData, fileHandle, id, sizeof(id), &value)) != EAS_SUCCESS)
- return result;
-
- /* check if DLS */
- if (pXMFData->dlsOffset == 0 && id[0] == 'R' && id[1] == 'I' && id[2] == 'F' && id[3] == 'F')
- {
- //remember offset
- pXMFData->dlsOffset = location;
- }
-
- /* else check if SMF */
- else if (id[0] == 'M' && id[1] == 'T' && id[2] == 'h' && id[3] == 'd')
- {
- //remember offset
- pXMFData->midiOffset = location;
-
- //we are done
- return EAS_SUCCESS;
- }
-
- //one less item
- numItems--;
-
- //if more data, go to the next item
- if (numItems >0)
- {
- if ((result = EAS_HWFileSeek(pEASData->hwInstData, fileHandle, offset + length)) != EAS_SUCCESS)
- return result;
- }
- }
-
- return EAS_FAILURE;
-
-}
-#endif
-
-/*----------------------------------------------------------------------------
- * XMF_ReadVLQ()
- *----------------------------------------------------------------------------
- * Purpose:
- * Reads a VLQ encoded value from the file referenced by fileHandle
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * fileHandle - pointer to file handle
- *
- * Outputs:
- * value - pointer to the value decoded from the VLQ data
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT XMF_ReadVLQ (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE fileHandle, EAS_I32 *value)
-{
- EAS_RESULT result;
- EAS_U8 c;
-
- *value = 0;
-
- if ((result = EAS_HWGetByte(hwInstData, fileHandle, &c)) != EAS_SUCCESS)
- return result;
-
- while (c > 0x7F)
- {
- /*lint -e{703} shift for performance */
- *value = (*value << 7) | (c & 0x7F);
-
- if ((result = EAS_HWGetByte(hwInstData, fileHandle, &c)) != EAS_SUCCESS)
- return result;
- }
-
- /*lint -e{703} shift for performance */
- *value = (*value << 7) | c;
-
- return EAS_SUCCESS;
-}
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 501 $
+ * $Date: 2006-12-11 17:53:36 -0800 (Mon, 11 Dec 2006) $
+ *----------------------------------------------------------------------------
+*/
+
+#include "eas_data.h"
+#include "eas_miditypes.h"
+#include "eas_parser.h"
+#include "eas_report.h"
+#include "eas_host.h"
+#include "eas_midi.h"
+#include "eas_xmf.h"
+#include "eas_xmfdata.h"
+#include "eas_config.h"
+#include "eas_vm_protos.h"
+#include "eas_mdls.h"
+#include "eas_smf.h"
+
+
+/* XMF header file type */
+#define XMF_IDENTIFIER 0x584d465f
+#define XMF_VERSION_2_00 0x322e3030
+#define XMF_FILE_TYPE 0x00000002
+#define XMF_SPEC_LEVEL 0x00000001
+#define XMF_RIFF_CHUNK 0x52494646
+#define XMF_RIFF_DLS 0x444c5320
+#define XMF_SMF_CHUNK 0x4d546864
+
+/* local prototypes */
+static EAS_RESULT XMF_CheckFileType (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle, EAS_VOID_PTR *ppHandle, EAS_I32 offset);
+static EAS_RESULT XMF_Prepare (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
+static EAS_RESULT XMF_Time (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_U32 *pTime);
+static EAS_RESULT XMF_Event (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_INT parserMode);
+static EAS_RESULT XMF_State (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_STATE *pState);
+static EAS_RESULT XMF_Close (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
+static EAS_RESULT XMF_Reset (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
+static EAS_RESULT XMF_Pause (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
+static EAS_RESULT XMF_Resume (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
+static EAS_RESULT XMF_SetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value);
+static EAS_RESULT XMF_GetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue);
+static EAS_RESULT XMF_FindFileContents (EAS_HW_DATA_HANDLE hwInstData, S_XMF_DATA *pXMFData);
+static EAS_RESULT XMF_ReadNode (EAS_HW_DATA_HANDLE hwInstData, S_XMF_DATA *pXMFData, EAS_I32 nodeOffset, EAS_I32 *pLength);
+static EAS_RESULT XMF_ReadVLQ (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE fileHandle, EAS_I32 *value);
+
+
+/*----------------------------------------------------------------------------
+ *
+ * XMF_Parser
+ *
+ * This structure contains the functional interface for the XMF parser
+ *----------------------------------------------------------------------------
+*/
+const S_FILE_PARSER_INTERFACE EAS_XMF_Parser =
+{
+ XMF_CheckFileType,
+ XMF_Prepare,
+ XMF_Time,
+ XMF_Event,
+ XMF_State,
+ XMF_Close,
+ XMF_Reset,
+ XMF_Pause,
+ XMF_Resume,
+ NULL,
+ XMF_SetData,
+ XMF_GetData,
+ NULL
+};
+
+/*----------------------------------------------------------------------------
+ * XMF_CheckFileType()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Check the file type to see if we can parse it
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT XMF_CheckFileType (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle, EAS_VOID_PTR *ppHandle, EAS_I32 offset)
+{
+ S_XMF_DATA *pXMFData;
+ EAS_RESULT result;
+ EAS_U32 temp;
+
+ /* assume we don't recognize it initially */
+ *ppHandle = NULL;
+
+ /* read the file identifier */
+ if ((result = EAS_HWGetDWord(pEASData->hwInstData, fileHandle, &temp, EAS_TRUE)) != EAS_SUCCESS)
+ return result;
+ if (temp != XMF_IDENTIFIER)
+ return EAS_SUCCESS;
+
+ /* read the version */
+ if ((result = EAS_HWGetDWord(pEASData->hwInstData, fileHandle, &temp, EAS_TRUE)) != EAS_SUCCESS)
+ return result;
+ if (temp != XMF_VERSION_2_00)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "XMF file version was 0x%08x, expected 0x%08x\n", temp, XMF_VERSION_2_00); */ }
+ return EAS_SUCCESS;
+ }
+
+ /* read the file type */
+ if ((result = EAS_HWGetDWord(pEASData->hwInstData, fileHandle, &temp, EAS_TRUE)) != EAS_SUCCESS)
+ return result;
+ if (temp != XMF_FILE_TYPE)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "XMF file type was 0x%08x, expected 0x%08x\n", temp, XMF_FILE_TYPE); */ }
+ return EAS_SUCCESS;
+ }
+
+ /* read the spec level */
+ if ((result = EAS_HWGetDWord(pEASData->hwInstData, fileHandle, &temp, EAS_TRUE)) != EAS_SUCCESS)
+ return result;
+ if (temp != XMF_SPEC_LEVEL)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "XMF file spec was 0x%08x, expected 0x%08x\n", temp, XMF_SPEC_LEVEL); */ }
+ return EAS_SUCCESS;
+ }
+
+ /* check for static memory allocation */
+ if (pEASData->staticMemoryModel)
+ pXMFData = EAS_CMEnumData(EAS_CM_XMF_DATA);
+ else
+ pXMFData = EAS_HWMalloc(pEASData->hwInstData, sizeof(S_XMF_DATA));
+ if (!pXMFData)
+ return EAS_ERROR_MALLOC_FAILED;
+
+ /* zero the memory to insure complete initialization */
+ EAS_HWMemSet((void *)pXMFData,0, sizeof(S_XMF_DATA));
+
+ pXMFData->fileHandle = fileHandle;
+ pXMFData->fileOffset = offset;
+ *ppHandle = pXMFData;
+
+ /* locate the SMF and DLS contents */
+ if ((result = XMF_FindFileContents(pEASData->hwInstData, pXMFData)) != EAS_SUCCESS)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "No SMF data found in XMF file\n"); */ }
+ return result;
+ }
+
+ /* let the SMF parser take over */
+ if ((result = EAS_HWFileSeek(pEASData->hwInstData, fileHandle, pXMFData->midiOffset)) != EAS_SUCCESS)
+ return result;
+ return SMF_CheckFileType(pEASData, fileHandle, &pXMFData->pSMFData, pXMFData->midiOffset);
+}
+
+/*----------------------------------------------------------------------------
+ * XMF_Prepare()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Prepare to parse the file. Allocates instance data (or uses static allocation for
+ * static memory model).
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT XMF_Prepare (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
+{
+ S_XMF_DATA* pXMFData;
+ EAS_RESULT result;
+
+ /* parse DLS collection */
+ pXMFData = (S_XMF_DATA*) pInstData;
+ if (pXMFData->dlsOffset != 0)
+ {
+ if ((result = DLSParser(pEASData->hwInstData, pXMFData->fileHandle, pXMFData->dlsOffset, &pXMFData->pDLS)) != EAS_SUCCESS)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Error converting XMF DLS data\n"); */ }
+ return result;
+ }
+ }
+
+ /* Prepare the SMF parser */
+ if ((result = SMF_Prepare(pEASData, pXMFData->pSMFData)) != EAS_SUCCESS)
+ return result;
+
+ /* if no DLS file, skip this step */
+ if (pXMFData->pDLS == NULL)
+ return EAS_SUCCESS;
+
+ /* tell the synth to use the DLS collection */
+ result = VMSetDLSLib(((S_SMF_DATA*) pXMFData->pSMFData)->pSynth, pXMFData->pDLS);
+ if (result == EAS_SUCCESS)
+ {
+ DLSAddRef(pXMFData->pDLS);
+ VMInitializeAllChannels(pEASData->pVoiceMgr, ((S_SMF_DATA*) pXMFData->pSMFData)->pSynth);
+ }
+ return result;
+}
+
+/*----------------------------------------------------------------------------
+ * XMF_Time()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Returns the time of the next event in msecs
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ * pTime - pointer to variable to hold time of next event (in msecs)
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT XMF_Time (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_U32 *pTime)
+{
+ return SMF_Time(pEASData, ((S_XMF_DATA*) pInstData)->pSMFData, pTime);
+}
+
+/*----------------------------------------------------------------------------
+ * XMF_Event()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Parse the next event in the file
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT XMF_Event (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_INT parserMode)
+{
+ return SMF_Event(pEASData, ((S_XMF_DATA*) pInstData)->pSMFData, parserMode);
+}
+
+/*----------------------------------------------------------------------------
+ * XMF_State()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Returns the current state of the stream
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ * pState - pointer to variable to store state
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT XMF_State (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 *pState)
+{
+ return SMF_State(pEASData, ((S_XMF_DATA*) pInstData)->pSMFData, pState);
+}
+
+/*----------------------------------------------------------------------------
+ * XMF_Close()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Close the file and clean up
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT XMF_Close (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
+{
+ S_XMF_DATA* pXMFData;
+ EAS_RESULT result;
+
+ pXMFData = (S_XMF_DATA *)pInstData;
+
+ /* close the SMF stream, it will close the file handle */
+ if ((result = SMF_Close(pEASData, pXMFData->pSMFData)) != EAS_SUCCESS)
+ return result;
+
+ if (pXMFData->pDLS)
+ DLSCleanup(pEASData->hwInstData, pXMFData->pDLS);
+
+ /* if using dynamic memory, free it */
+ if (!pEASData->staticMemoryModel)
+ {
+ /* free the instance data */
+ EAS_HWFree(pEASData->hwInstData, pXMFData);
+ }
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * XMF_Reset()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Reset the sequencer. Used for locating backwards in the file.
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT XMF_Reset (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
+{
+ return SMF_Reset(pEASData, ((S_XMF_DATA*) pInstData)->pSMFData);
+}
+
+/*----------------------------------------------------------------------------
+ * XMF_Pause()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Pauses the sequencer. Mutes all voices and sets state to pause.
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT XMF_Pause (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
+{
+ return SMF_Pause(pEASData, ((S_XMF_DATA*) pInstData)->pSMFData);
+}
+
+/*----------------------------------------------------------------------------
+ * XMF_Resume()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Resume playing after a pause, sets state back to playing.
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT XMF_Resume (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
+{
+ return SMF_Resume(pEASData, ((S_XMF_DATA*) pInstData)->pSMFData);
+}
+
+/*----------------------------------------------------------------------------
+ * XMF_SetData()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Sets the playback rate of the underlying SMF file
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ * rate - rate (28-bit fraction)
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT XMF_SetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value)
+{
+ return SMF_SetData(pEASData, ((S_XMF_DATA*) pInstData)->pSMFData, param, value);
+}
+
+/*----------------------------------------------------------------------------
+ * XMF_GetData()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Gets the file type
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ * rate - rate (28-bit fraction)
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT XMF_GetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue)
+{
+ EAS_RESULT result;
+
+ /* call SMF parser to get value */
+ if ((result = SMF_GetData(pEASData, ((S_XMF_DATA*) pInstData)->pSMFData, param, pValue)) != EAS_SUCCESS)
+ return result;
+
+ /* special case for file type */
+ if (param == PARSER_DATA_FILE_TYPE)
+ {
+ if (*pValue == EAS_FILE_SMF0)
+ *pValue = EAS_FILE_XMF0;
+ else if (*pValue == EAS_FILE_SMF1)
+ *pValue = EAS_FILE_XMF1;
+ }
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * XMF_FindFileContents()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Finds SMF data and DLS data in XMF file, and remembers offset for each.
+ * If more than one is found, uses the first one found of each.
+ * Makes assumptions about the format of a mobile XMF file
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * pXMFData - pointer to XMF parser instance data
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT XMF_FindFileContents (EAS_HW_DATA_HANDLE hwInstData, S_XMF_DATA *pXMFData)
+{
+ EAS_RESULT result;
+ EAS_I32 value;
+ EAS_I32 length;
+
+ /* initialize offsets */
+ pXMFData->dlsOffset = pXMFData->midiOffset = 0;
+
+ /* read file length, ignore it for now */
+ if ((result = XMF_ReadVLQ(hwInstData, pXMFData->fileHandle, &value)) != EAS_SUCCESS)
+ return result;
+
+ /* read MetaDataTypesTable length and skip over it */
+ if ((result = XMF_ReadVLQ(hwInstData, pXMFData->fileHandle, &value)) != EAS_SUCCESS)
+ return result;
+ if ((result = EAS_HWFileSeekOfs(hwInstData, pXMFData->fileHandle, value)) != EAS_SUCCESS)
+ return result;
+
+ /* get TreeStart offset and jump to it */
+ if ((result = XMF_ReadVLQ(hwInstData, pXMFData->fileHandle, &value)) != EAS_SUCCESS)
+ return result;
+ if ((result = XMF_ReadNode(hwInstData, pXMFData, value, &length)) != EAS_SUCCESS)
+ return result;
+
+ /* check for SMF data */
+ if (pXMFData->midiOffset == 0)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "No SMF data found in XMF file\n"); */ }
+ return EAS_ERROR_FILE_FORMAT;
+ }
+
+ /* check for SFM in wrong order */
+ if ((pXMFData->dlsOffset > 0) && (pXMFData->midiOffset < pXMFData->dlsOffset))
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "DLS data must precede SMF data in Mobile XMF file\n"); */ }
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * XMF_ReadNode()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ *
+ * Inputs:
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT XMF_ReadNode (EAS_HW_DATA_HANDLE hwInstData, S_XMF_DATA *pXMFData, EAS_I32 nodeOffset, EAS_I32 *pLength)
+{
+ EAS_RESULT result;
+ EAS_I32 refType;
+ EAS_I32 numItems;
+ EAS_I32 offset;
+ EAS_I32 length;
+ EAS_I32 headerLength;
+ EAS_U32 chunkType;
+
+ /* seek to start of node */
+ if ((result = EAS_HWFileSeek(hwInstData, pXMFData->fileHandle, nodeOffset)) != EAS_SUCCESS)
+ return result;
+
+ /* get node length */
+ if ((result = XMF_ReadVLQ(hwInstData, pXMFData->fileHandle, pLength)) != EAS_SUCCESS)
+ return result;
+
+ /* get number of contained items */
+ if ((result = XMF_ReadVLQ(hwInstData, pXMFData->fileHandle, &numItems)) != EAS_SUCCESS)
+ return result;
+
+ /* get node header length */
+ if ((result = XMF_ReadVLQ(hwInstData, pXMFData->fileHandle, &headerLength)) != EAS_SUCCESS)
+ return result;
+
+ /* get metadata length */
+ if ((result = XMF_ReadVLQ(hwInstData, pXMFData->fileHandle, &length)) != EAS_SUCCESS)
+ return result;
+
+ /* get the current location */
+ if ((result = EAS_HWFilePos(hwInstData, pXMFData->fileHandle, &offset)) != EAS_SUCCESS)
+ return result;
+
+ /* skip to node contents */
+ if ((result = EAS_HWFileSeek(hwInstData, pXMFData->fileHandle, nodeOffset + headerLength)) != EAS_SUCCESS)
+ return result;
+
+ /* get reference type */
+ if ((result = XMF_ReadVLQ(hwInstData, pXMFData->fileHandle, &refType)) != EAS_SUCCESS)
+ return result;
+
+ /* get the current location */
+ if ((result = EAS_HWFilePos(hwInstData, pXMFData->fileHandle, &offset)) != EAS_SUCCESS)
+ return result;
+
+ /* process file node */
+ if (numItems == 0)
+
+ {
+ /* if in-file resource, find out where it is and jump to it */
+ if (refType == 2)
+ {
+ if ((result = XMF_ReadVLQ(hwInstData, pXMFData->fileHandle, &offset)) != EAS_SUCCESS)
+ return result;
+ offset += pXMFData->fileOffset;
+ if ((result = EAS_HWFileSeek(hwInstData, pXMFData->fileHandle, offset)) != EAS_SUCCESS)
+ return result;
+ }
+
+ /* or else it must be an inline resource */
+ else if (refType != 1)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Unexpected reference type %d\n", refType); */ }
+ return EAS_ERROR_FILE_FORMAT;
+ }
+
+ /* get the chunk type */
+ if ((result = EAS_HWGetDWord(hwInstData, pXMFData->fileHandle, &chunkType, EAS_TRUE)) != EAS_SUCCESS)
+ return result;
+
+ /* found a RIFF chunk, check for DLS type */
+ if (chunkType == XMF_RIFF_CHUNK)
+ {
+ /* skip length */
+ if ((result = EAS_HWFileSeekOfs(hwInstData, pXMFData->fileHandle, sizeof(EAS_I32))) != EAS_SUCCESS)
+ return result;
+
+ /* get RIFF file type */
+ if ((result = EAS_HWGetDWord(hwInstData, pXMFData->fileHandle, &chunkType, EAS_TRUE)) != EAS_SUCCESS)
+ return result;
+ if (chunkType == XMF_RIFF_DLS)
+ pXMFData->dlsOffset = offset;
+ }
+
+ /* found an SMF chunk */
+ else if (chunkType == XMF_SMF_CHUNK)
+ pXMFData->midiOffset = offset;
+ }
+
+ /* folder node, process the items in the list */
+ else
+ {
+ for ( ; numItems > 0; numItems--)
+ {
+ /* process this item */
+ if ((result = XMF_ReadNode(hwInstData, pXMFData, offset, &length)) != EAS_SUCCESS)
+ return result;
+
+ /* seek to start of next item */
+ offset += length;
+ if ((result = EAS_HWFileSeek(hwInstData, pXMFData->fileHandle, offset)) != EAS_SUCCESS)
+ return result;
+ }
+ }
+
+ return EAS_SUCCESS;
+}
+
+#if 0
+/*----------------------------------------------------------------------------
+ * XMF_FindFileContents()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Finds SMF data and DLS data in XMF file, and remembers offset for each.
+ * If more than one is found, uses the first one found of each.
+ * Makes assumptions about the format of a mobile XMF file
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * pXMFData - pointer to XMF parser instance data
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT XMF_FindFileContents(S_EAS_DATA *pEASData, S_XMF_DATA *pXMFData, EAS_FILE_HANDLE fileHandle)
+{
+ EAS_RESULT result;
+ EAS_I32 offset;
+ EAS_I32 value;
+ EAS_I32 numItems;
+ EAS_I32 length;
+ EAS_CHAR id[4];
+ EAS_I32 location;
+
+ /* init dls offset, so that we know we haven't found a dls chunk yet */
+ pXMFData->dlsOffset = 0;
+
+ /* read file length, ignore it for now */
+ if ((result = XMF_ReadVLQ(pEASData, fileHandle, &value)) != EAS_SUCCESS)
+ return result;
+
+ /* read MetaDataTypesTable length and skip over it */
+ if ((result = XMF_ReadVLQ(pEASData, fileHandle, &value)) != EAS_SUCCESS)
+ return result;
+ if ((result = EAS_HWFileSeekOfs(pEASData, fileHandle, value)) != EAS_SUCCESS)
+ return result;
+
+ /* get TreeStart offset and jump to it */
+ if ((result = XMF_ReadVLQ(pEASData, fileHandle, &offset)) != EAS_SUCCESS)
+ return result;
+ if ((result = EAS_HWFileSeek(pEASData->hwInstData, fileHandle, offset)) != EAS_SUCCESS)
+ return result;
+
+ /* read node length, ignore it for now */
+ if ((result = XMF_ReadVLQ(pEASData, fileHandle, &value)) != EAS_SUCCESS)
+ return result;
+
+ /* read number of contained items */
+ if ((result = XMF_ReadVLQ(pEASData, fileHandle, &numItems)) != EAS_SUCCESS)
+ return result;
+
+ /*read node header length */
+ if ((result = XMF_ReadVLQ(pEASData, fileHandle, &value)) != EAS_SUCCESS)
+ return result;
+
+ /*go to the node offset */
+ if ((result = EAS_HWFileSeek(pEASData->hwInstData, fileHandle, offset + value)) != EAS_SUCCESS)
+ return result;
+
+ /* read Reference Type */
+ if ((result = XMF_ReadVLQ(pEASData, fileHandle, &value)) != EAS_SUCCESS)
+ return result;
+
+ /* make sure it is an in-line resource, for now */
+ if (value != 1)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Problem parsing XMF file tree\n"); */ }
+ return EAS_FAILURE;
+ }
+
+ /* parse through the list of items */
+ while (numItems > 0)
+ {
+ /*get current offset */
+ if ((result = EAS_HWFilePos(pEASData->hwInstData, fileHandle, &offset)) != EAS_SUCCESS)
+ return result;
+
+ /*read node length */
+ if ((result = XMF_ReadVLQ(pEASData, fileHandle, &length)) != EAS_SUCCESS)
+ return result;
+
+ /* read number of items */
+ if ((result = XMF_ReadVLQ(pEASData, fileHandle, &value)) != EAS_SUCCESS)
+ return result;
+
+ /* make sure not a folder */
+ if (value != 0)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Problem parsing XMF file node\n"); */ }
+ return EAS_FAILURE;
+ }
+
+ /* read offset to resource and jump to it */
+ if ((result = XMF_ReadVLQ(pEASData, fileHandle, &value)) != EAS_SUCCESS)
+ return result;
+ if ((result = EAS_HWFileSeek(pEASData->hwInstData, fileHandle, offset + value)) != EAS_SUCCESS)
+ return result;
+
+ /* read Reference Type */
+ if ((result = XMF_ReadVLQ(pEASData, fileHandle, &value)) != EAS_SUCCESS)
+ return result;
+
+ /* make sure it is an in-line resource */
+ if (value != 1)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Problem parsing XMF file node\n"); */ }
+ return EAS_FAILURE;
+ }
+
+ /* get current offset as a possible location for SMF file or DLS file */
+ if ((result = EAS_HWFilePos(pEASData->hwInstData, fileHandle, &location)) != EAS_SUCCESS)
+ return result;
+
+ /* read four bytes */
+ if ((result = EAS_HWReadFile(pEASData->hwInstData, fileHandle, id, sizeof(id), &value)) != EAS_SUCCESS)
+ return result;
+
+ /* check if DLS */
+ if (pXMFData->dlsOffset == 0 && id[0] == 'R' && id[1] == 'I' && id[2] == 'F' && id[3] == 'F')
+ {
+ //remember offset
+ pXMFData->dlsOffset = location;
+ }
+
+ /* else check if SMF */
+ else if (id[0] == 'M' && id[1] == 'T' && id[2] == 'h' && id[3] == 'd')
+ {
+ //remember offset
+ pXMFData->midiOffset = location;
+
+ //we are done
+ return EAS_SUCCESS;
+ }
+
+ //one less item
+ numItems--;
+
+ //if more data, go to the next item
+ if (numItems >0)
+ {
+ if ((result = EAS_HWFileSeek(pEASData->hwInstData, fileHandle, offset + length)) != EAS_SUCCESS)
+ return result;
+ }
+ }
+
+ return EAS_FAILURE;
+
+}
+#endif
+
+/*----------------------------------------------------------------------------
+ * XMF_ReadVLQ()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Reads a VLQ encoded value from the file referenced by fileHandle
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * fileHandle - pointer to file handle
+ *
+ * Outputs:
+ * value - pointer to the value decoded from the VLQ data
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT XMF_ReadVLQ (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE fileHandle, EAS_I32 *value)
+{
+ EAS_RESULT result;
+ EAS_U8 c;
+
+ *value = 0;
+
+ if ((result = EAS_HWGetByte(hwInstData, fileHandle, &c)) != EAS_SUCCESS)
+ return result;
+
+ while (c > 0x7F)
+ {
+ /*lint -e{703} shift for performance */
+ *value = (*value << 7) | (c & 0x7F);
+
+ if ((result = EAS_HWGetByte(hwInstData, fileHandle, &c)) != EAS_SUCCESS)
+ return result;
+ }
+
+ /*lint -e{703} shift for performance */
+ *value = (*value << 7) | c;
+
+ return EAS_SUCCESS;
+}
+
diff --git a/arm-wt-22k/lib_src/eas_xmf.h b/arm-wt-22k/lib_src/eas_xmf.h
index 970d00c..b8f7a24 100644
--- a/arm-wt-22k/lib_src/eas_xmf.h
+++ b/arm-wt-22k/lib_src/eas_xmf.h
@@ -1,12 +1,12 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_xmf.h
- *
- * Contents and purpose:
- * XMF Type 0 and 1 File Parser
- *
- * Copyright Sonic Network Inc. 2005
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_xmf.h
+ *
+ * Contents and purpose:
+ * XMF Type 0 and 1 File Parser
+ *
+ * Copyright Sonic Network Inc. 2005
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,42 +19,42 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 82 $
- * $Date: 2006-07-10 11:45:19 -0700 (Mon, 10 Jul 2006) $
- *----------------------------------------------------------------------------
-*/
-
-#ifndef _EAS_XMF_H
-#define _EAS_XMF_H
-
-#ifndef MAX_XMF_STREAMS
-#define MAX_XMF_STREAMS 16
-#endif
-
-/* offsets in to the XMF file */
-#define XMF_OFS_HEADER_SIZE 4
-#define XMF_OFS_FILE_TYPE 8
-#define XMF_OFS_NUM_TRACKS 10
-
-/* size of chunk info (chunk ID + chunk size) */
-#define XMF_CHUNK_INFO_SIZE 8
-
-/* 'MTrk' track chunk ID */
-#define XMF_CHUNK_TYPE_TRACK 0x4d54726bL
-
-/* some useful meta-events */
-#define XMF_META_END_OF_TRACK 0x2f
-#define XMF_META_TEMPO 0x51
-
-/* default timebase (120BPM) */
-#define XMF_DEFAULT_TIMEBASE 500000L
-
-/* value for pXMFStream->ticks to signify end of track */
-#define XMF_END_OF_TRACK 0xffffffff
-
-#endif /* end _EAS_XMF_H */
-
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 82 $
+ * $Date: 2006-07-10 11:45:19 -0700 (Mon, 10 Jul 2006) $
+ *----------------------------------------------------------------------------
+*/
+
+#ifndef _EAS_XMF_H
+#define _EAS_XMF_H
+
+#ifndef MAX_XMF_STREAMS
+#define MAX_XMF_STREAMS 16
+#endif
+
+/* offsets in to the XMF file */
+#define XMF_OFS_HEADER_SIZE 4
+#define XMF_OFS_FILE_TYPE 8
+#define XMF_OFS_NUM_TRACKS 10
+
+/* size of chunk info (chunk ID + chunk size) */
+#define XMF_CHUNK_INFO_SIZE 8
+
+/* 'MTrk' track chunk ID */
+#define XMF_CHUNK_TYPE_TRACK 0x4d54726bL
+
+/* some useful meta-events */
+#define XMF_META_END_OF_TRACK 0x2f
+#define XMF_META_TEMPO 0x51
+
+/* default timebase (120BPM) */
+#define XMF_DEFAULT_TIMEBASE 500000L
+
+/* value for pXMFStream->ticks to signify end of track */
+#define XMF_END_OF_TRACK 0xffffffff
+
+#endif /* end _EAS_XMF_H */
+
+
diff --git a/arm-wt-22k/lib_src/eas_xmfdata.c b/arm-wt-22k/lib_src/eas_xmfdata.c
index ed2e84a..f305c12 100644
--- a/arm-wt-22k/lib_src/eas_xmfdata.c
+++ b/arm-wt-22k/lib_src/eas_xmfdata.c
@@ -1,14 +1,14 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_xmfdata.c
- *
- * Contents and purpose:
- * XMF File Parser
- *
- * This file contains data definitions for the XMF parser.
- *
- * Copyright Sonic Network Inc. 2005
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_xmfdata.c
+ *
+ * Contents and purpose:
+ * XMF File Parser
+ *
+ * This file contains data definitions for the XMF parser.
+ *
+ * Copyright Sonic Network Inc. 2005
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,24 +21,24 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 547 $
- * $Date: 2007-01-31 16:30:17 -0800 (Wed, 31 Jan 2007) $
- *----------------------------------------------------------------------------
-*/
-
-#include "eas_miditypes.h"
-#include "eas_xmf.h"
-#include "eas_xmfdata.h"
-
-/*----------------------------------------------------------------------------
- *
- * eas_XMFData
- *
- * Static memory allocation for XMF parser
- *----------------------------------------------------------------------------
-*/
-S_XMF_DATA eas_XMFData;
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 547 $
+ * $Date: 2007-01-31 16:30:17 -0800 (Wed, 31 Jan 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+#include "eas_miditypes.h"
+#include "eas_xmf.h"
+#include "eas_xmfdata.h"
+
+/*----------------------------------------------------------------------------
+ *
+ * eas_XMFData
+ *
+ * Static memory allocation for XMF parser
+ *----------------------------------------------------------------------------
+*/
+S_XMF_DATA eas_XMFData;
+
diff --git a/arm-wt-22k/lib_src/eas_xmfdata.h b/arm-wt-22k/lib_src/eas_xmfdata.h
index c535d55..fce02a1 100644
--- a/arm-wt-22k/lib_src/eas_xmfdata.h
+++ b/arm-wt-22k/lib_src/eas_xmfdata.h
@@ -1,13 +1,13 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_xmfdata.h
- *
- * Contents and purpose:
- * Contains declarations for the XMF file parser.
- *
- *
- * Copyright Sonic Network Inc. 2005
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_xmfdata.h
+ *
+ * Contents and purpose:
+ * Contains declarations for the XMF file parser.
+ *
+ *
+ * Copyright Sonic Network Inc. 2005
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,36 +20,36 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 82 $
- * $Date: 2006-07-10 11:45:19 -0700 (Mon, 10 Jul 2006) $
- *----------------------------------------------------------------------------
-*/
-
-#ifndef _EAS_XMFDATA_H
-#define _EAS_XMFDATA_H
-
-#include "eas_data.h"
-
-/*----------------------------------------------------------------------------
- *
- * S_XMF_DATA
- *
- * This structure contains the instance data required to parse an XMF file.
- *
- *----------------------------------------------------------------------------
-*/
-
-typedef struct
-{
- EAS_FILE_HANDLE fileHandle;
- EAS_I32 fileOffset;
- EAS_VOID_PTR pSMFData;
- EAS_I32 midiOffset;
- EAS_I32 dlsOffset;
- S_DLS *pDLS;
-} S_XMF_DATA;
-
-#endif
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 82 $
+ * $Date: 2006-07-10 11:45:19 -0700 (Mon, 10 Jul 2006) $
+ *----------------------------------------------------------------------------
+*/
+
+#ifndef _EAS_XMFDATA_H
+#define _EAS_XMFDATA_H
+
+#include "eas_data.h"
+
+/*----------------------------------------------------------------------------
+ *
+ * S_XMF_DATA
+ *
+ * This structure contains the instance data required to parse an XMF file.
+ *
+ *----------------------------------------------------------------------------
+*/
+
+typedef struct
+{
+ EAS_FILE_HANDLE fileHandle;
+ EAS_I32 fileOffset;
+ EAS_VOID_PTR pSMFData;
+ EAS_I32 midiOffset;
+ EAS_I32 dlsOffset;
+ S_DLS *pDLS;
+} S_XMF_DATA;
+
+#endif
diff --git a/arm-wt-22k/lib_src/jet.c b/arm-wt-22k/lib_src/jet.c
index cc180af..97672cf 100644
--- a/arm-wt-22k/lib_src/jet.c
+++ b/arm-wt-22k/lib_src/jet.c
@@ -1,1129 +1,1129 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * jet.c
- *
- * Contents and purpose:
- * Implementation for JET sound engine
- *
- * Copyright (c) 2006 Sonic Network Inc.
-
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 563 $
- * $Date: 2007-02-13 20:26:23 -0800 (Tue, 13 Feb 2007) $
- *----------------------------------------------------------------------------
-*/
-
-//#define LOG_NDEBUG 0
-#define LOG_TAG "JET_C"
-
-//#define DEBUG_JET
-
-#include "eas_data.h"
-#include "eas_smf.h"
-#include "jet_data.h"
-#include "eas_host.h"
-#include "eas_report.h"
-
-
-/* default configuration */
-static const S_JET_CONFIG jetDefaultConfig =
-{
- JET_EVENT_APP_LOW,
- JET_EVENT_APP_HIGH
-};
-
-/* function prototypes */
-extern EAS_RESULT EAS_IntSetStrmParam (S_EAS_DATA *pEASData, EAS_HANDLE pStream, EAS_INT param, EAS_I32 value);
-extern EAS_RESULT EAS_OpenJETStream (EAS_DATA_HANDLE pEASData, EAS_FILE_HANDLE fileHandle, EAS_I32 offset, EAS_HANDLE *ppStream);
-extern EAS_RESULT DLSParser (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE fileHandle, EAS_I32 offset, EAS_DLSLIB_HANDLE *ppDLS);
-
-/*----------------------------------------------------------------------------
- * JET_ParseEvent()
- *----------------------------------------------------------------------------
- * Returns current status
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC void JET_ParseEvent (EAS_U32 event, S_JET_EVENT *pEvent)
-{
- pEvent->segment = (EAS_U8) ((event & JET_EVENT_SEG_MASK) >> JET_EVENT_SEG_SHIFT);
- pEvent->track = (EAS_U8) ((event & JET_EVENT_TRACK_MASK) >> JET_EVENT_TRACK_SHIFT);
- pEvent->channel = (EAS_U8) ((event & JET_EVENT_CHAN_MASK) >> JET_EVENT_CHAN_SHIFT);
- pEvent->controller = (EAS_U8) ((event & JET_EVENT_CTRL_MASK) >> JET_EVENT_CTRL_SHIFT);
- pEvent->value = (EAS_U8) (event & JET_EVENT_VAL_MASK);
-}
-
-#ifdef DEBUG_JET
-/*----------------------------------------------------------------------------
- * JET_DumpEvent
- *----------------------------------------------------------------------------
- * Advances queue read/write index
- *----------------------------------------------------------------------------
-*/
-static void JET_DumpEvent (const char *procName, EAS_U32 event)
-{
- S_JET_EVENT sEvent;
- JET_ParseEvent(event, &sEvent);
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "%s: SegID=%d, TrkID=%d, channel=%d, ctrl=%d, val=%d\n",
- procName, sEvent.segment, sEvent.track, sEvent.channel, sEvent.controller, sEvent.value); */ }
-}
-#endif
-
-/*----------------------------------------------------------------------------
- * JET_IncQueueIndex
- *----------------------------------------------------------------------------
- * Advances queue read/write index
- *----------------------------------------------------------------------------
-*/
-EAS_INLINE EAS_U8 JET_IncQueueIndex (EAS_U8 index, EAS_U8 queueSize)
-{
- if (++index == queueSize)
- index = 0;
- return index;
-}
-
-/*----------------------------------------------------------------------------
- * JET_WriteQueue
- *----------------------------------------------------------------------------
- * Save event to queue
- *----------------------------------------------------------------------------
-*/
-EAS_INLINE void JET_WriteQueue (EAS_U32 *pEventQueue, EAS_U8 *pWriteIndex, EAS_U8 readIndex, EAS_U8 queueSize, EAS_U32 event)
-{
- EAS_U8 temp;
-
- /* check for queue overflow */
- temp = JET_IncQueueIndex(*pWriteIndex, queueSize);
- if (temp == readIndex)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "JET_Event: Event queue overflow --- event ignored!\n"); */ }
- return;
- }
-
- /* save in queue and advance write index */
- pEventQueue[*pWriteIndex] = event;
- *pWriteIndex = temp;
-}
-
-/*----------------------------------------------------------------------------
- * JET_ReadQueue
- *----------------------------------------------------------------------------
- * Read event to queue
- *----------------------------------------------------------------------------
-*/
-EAS_INLINE EAS_BOOL JET_ReadQueue (EAS_U32 *pEventQueue, EAS_U8 *pReadIndex, EAS_U8 writeIndex, EAS_U8 queueSize, EAS_U32 *pEvent)
-{
-
- /* check for empty queue */
- if (*pReadIndex == writeIndex)
- return EAS_FALSE;
-
- /* save in queue and advance write index */
- *pEvent = pEventQueue[*pReadIndex];
- *pReadIndex = JET_IncQueueIndex(*pReadIndex, queueSize);
- return EAS_TRUE;
-}
-
-/*----------------------------------------------------------------------------
- * JET_NextSegment
- *----------------------------------------------------------------------------
- * Advances segment number
- *----------------------------------------------------------------------------
-*/
-EAS_INLINE EAS_INT JET_NextSegment (EAS_INT seg_num)
-{
- if (++seg_num == SEG_QUEUE_DEPTH)
- seg_num = 0;
- return seg_num;
-}
-
-/*----------------------------------------------------------------------------
- * JET_PrepareSegment()
- *----------------------------------------------------------------------------
- * Prepare a segment for playback
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT JET_PrepareSegment (EAS_DATA_HANDLE easHandle, EAS_I32 queueNum)
-{
- EAS_RESULT result;
- S_JET_SEGMENT *p;
-
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "JET_PrepareSegment: %d\n", queueNum); */ }
-
- p = &easHandle->jetHandle->segQueue[queueNum];
- result = EAS_Prepare(easHandle, p->streamHandle);
- if (result != EAS_SUCCESS)
- return result;
-
- /* pause segment - must be triggered by play or end of previous segment */
- result = EAS_Pause(easHandle, p->streamHandle);
- if (result != EAS_SUCCESS)
- return result;
- p->state = JET_STATE_READY;
-
- /* set calback data */
- result = EAS_IntSetStrmParam(easHandle, p->streamHandle, PARSER_DATA_JET_CB, queueNum);
- if (result != EAS_SUCCESS)
- return result;
-
- /* set DLS collection */
- if (p->libNum >= 0)
- {
- result = EAS_IntSetStrmParam(easHandle, p->streamHandle,
- PARSER_DATA_DLS_COLLECTION, (EAS_I32) easHandle->jetHandle->libHandles[p->libNum]);
- if (result != EAS_SUCCESS)
- return result;
- }
-
- /* set transposition */
- if (p->transpose)
- {
- result = EAS_SetTransposition(easHandle, p->streamHandle, p->transpose);
- if (result != EAS_SUCCESS)
- return result;
- }
-
- return result;
-}
-
-/*----------------------------------------------------------------------------
- * JET_StartPlayback()
- *----------------------------------------------------------------------------
- * Start segment playback
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT JET_StartPlayback (EAS_DATA_HANDLE easHandle, EAS_I32 queueNum)
-{
- EAS_RESULT result = EAS_SUCCESS;
- S_JET_SEGMENT *pSeg;
-
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "JET_StartPlayback %d\n", queueNum); */ }
-
- /* if next segment is queued, start playback */
- pSeg = &easHandle->jetHandle->segQueue[queueNum];
- if (pSeg->streamHandle != NULL)
- {
- result = EAS_Resume(easHandle, pSeg->streamHandle);
- easHandle->jetHandle->segQueue[queueNum].state = JET_STATE_PLAYING;
-
- /* set mute flags */
- if ((result == EAS_SUCCESS) && (pSeg->muteFlags != 0))
- result = EAS_IntSetStrmParam(easHandle, pSeg->streamHandle, PARSER_DATA_MUTE_FLAGS, (EAS_I32) pSeg->muteFlags);
- }
- return result;
-}
-
-/*----------------------------------------------------------------------------
- * JET_CloseSegment
- *----------------------------------------------------------------------------
- * Closes stream associated with a segment
- *----------------------------------------------------------------------------
-*/
-EAS_INLINE EAS_INT JET_CloseSegment (EAS_DATA_HANDLE easHandle, EAS_INT queueNum)
-{
- EAS_RESULT result;
-
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "JET_CloseSegment %d\n", queueNum); */ }
-
- /* close the segment */
- result = EAS_CloseFile(easHandle, easHandle->jetHandle->segQueue[queueNum].streamHandle);
- if (result != EAS_SUCCESS)
- return result;
-
- easHandle->jetHandle->segQueue[queueNum].streamHandle = NULL;
- easHandle->jetHandle->segQueue[queueNum].state = JET_STATE_CLOSED;
- easHandle->jetHandle->numQueuedSegments--;
- return result;
-}
-
-/*----------------------------------------------------------------------------
- * JetParseInfoChunk()
- *----------------------------------------------------------------------------
- * Parses the JET info chunk
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT JetParseInfoChunk (EAS_DATA_HANDLE easHandle, EAS_I32 pos, EAS_I32 chunkSize)
-{
- EAS_RESULT result;
- EAS_U32 infoType;
- EAS_U32 temp;
-
- /* offset to data */
- result = EAS_HWFileSeek(easHandle->hwInstData, easHandle->jetHandle->jetFileHandle, pos);
- if (result != EAS_SUCCESS)
- return result;
-
- /* read the entire chunk */
- result = EAS_SUCCESS;
- while ((result == EAS_SUCCESS) && (chunkSize > 0))
- {
-
- /* get info infoType */
- result = EAS_HWGetDWord(easHandle->hwInstData, easHandle->jetHandle->jetFileHandle, &infoType, EAS_TRUE);
- if (result != EAS_SUCCESS)
- break;
-
- /* get info field */
- result = EAS_HWGetDWord(easHandle->hwInstData, easHandle->jetHandle->jetFileHandle, &temp, EAS_FALSE);
- if (result == EAS_SUCCESS)
-
- switch (infoType)
- {
- case INFO_NUM_SMF_CHUNKS:
- easHandle->jetHandle->numSegments = (EAS_U8) temp;
- break;
-
- case INFO_NUM_DLS_CHUNKS:
- easHandle->jetHandle->numLibraries = (EAS_U8) temp;
- break;
-
- case INFO_JET_VERSION:
- /* check major version number */
- if ((temp & 0xff000000) != (JET_VERSION & 0xff000000))
- return EAS_ERROR_INCOMPATIBLE_VERSION;
- break;
-
- default:
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Ignoring unrecognized JET info type 0x%08x", infoType); */ }
- break;
- }
-
- chunkSize -= 8;
- }
-
- /* allocate pointers for chunks to follow */
-
- return result;
-}
-
-/*----------------------------------------------------------------------------
- * JET_OpenFile()
- *----------------------------------------------------------------------------
- * Opens a JET content file for playback
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT JET_OpenFile (EAS_DATA_HANDLE easHandle, EAS_FILE_LOCATOR locator)
-{
- EAS_RESULT result;
- EAS_U32 chunkType;
- EAS_I32 pos;
- EAS_I32 chunkSize;
- EAS_INT smfChunkNum;
- EAS_INT dlsChunkNum;
- EAS_I32 dataSize = 0; /* make lint happy */
-
- /* make sure that we don't have an open file */
- if (easHandle->jetHandle->jetFileHandle != NULL)
- return EAS_ERROR_FILE_ALREADY_OPEN;
-
- /* open the media file */
- result = EAS_HWOpenFile(easHandle->hwInstData, locator, &easHandle->jetHandle->jetFileHandle, EAS_FILE_READ);
- if (result != EAS_SUCCESS)
- return result;
-
- /* check header */
- result = EAS_HWGetDWord(easHandle->hwInstData, easHandle->jetHandle->jetFileHandle, &chunkType, EAS_TRUE);
- if (result == EAS_SUCCESS)
- {
- if (chunkType != JET_HEADER_TAG)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "File is not JET format\n"); */ }
- result = EAS_ERROR_UNRECOGNIZED_FORMAT;
- }
- }
- /* get the file data size */
- if (result == EAS_SUCCESS)
- result = EAS_HWGetDWord(easHandle->hwInstData, easHandle->jetHandle->jetFileHandle, &dataSize, EAS_FALSE);
-
- /* parse through the file to find contents */
- smfChunkNum = dlsChunkNum = 0;
- pos = chunkSize = 8;
- while ((result == EAS_SUCCESS) && (pos < dataSize))
- {
-
- /* offset to chunk data */
- result = EAS_HWFileSeek(easHandle->hwInstData, easHandle->jetHandle->jetFileHandle, pos);
- if (result != EAS_SUCCESS)
- break;
-
- /* get chunk size and type */
- result = EAS_HWGetDWord(easHandle->hwInstData, easHandle->jetHandle->jetFileHandle, &chunkType, EAS_TRUE);
- if (result != EAS_SUCCESS)
- break;
-
- result = EAS_HWGetDWord(easHandle->hwInstData, easHandle->jetHandle->jetFileHandle, &chunkSize, EAS_FALSE);
- if (result != EAS_SUCCESS)
- break;
- pos += 8;
-
- switch (chunkType)
- {
- case JET_INFO_CHUNK:
- result = JetParseInfoChunk(easHandle, pos, chunkSize);
- break;
-
- case JET_SMF_CHUNK:
- if (smfChunkNum < easHandle->jetHandle->numSegments)
- easHandle->jetHandle->segmentOffsets[smfChunkNum++] = pos;
- else
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Ignoring extraneous SMF chunk"); */ }
- break;
-
- case JET_DLS_CHUNK:
- if (dlsChunkNum < easHandle->jetHandle->numLibraries)
- result = DLSParser(easHandle->hwInstData, easHandle->jetHandle->jetFileHandle, pos, &easHandle->jetHandle->libHandles[dlsChunkNum++]);
- else
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Ignoring extraneous DLS chunk"); */ }
- break;
-
- case JET_APP_DATA_CHUNK:
- easHandle->jetHandle->appDataOffset = pos;
- easHandle->jetHandle->appDataSize = chunkSize;
- break;
-
- case INFO_JET_COPYRIGHT:
- break;
-
- default:
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Ignoring unrecognized JET chunk type 0x%08x", chunkType); */ }
- break;
- }
-
- /* offset to next chunk */
- pos += chunkSize;
- }
-
- /* close file if something went wrong */
- if (result != EAS_SUCCESS)
- EAS_HWCloseFile(easHandle->hwInstData, easHandle->jetHandle->jetFileHandle);
-
- return result;
-}
-
-/*----------------------------------------------------------------------------
- * JET_GetAppData()
- *----------------------------------------------------------------------------
- * Returns location and size of application data in the JET file
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT JET_GetAppData (EAS_DATA_HANDLE easHandle, EAS_I32 *pAppDataOffset, EAS_I32 *pAppDataSize)
-{
-
- /* check for app chunk */
- if (easHandle->jetHandle->appDataSize == 0)
- {
- *pAppDataOffset = *pAppDataSize = 0;
- return EAS_FAILURE;
- }
-
- /* return app data */
- *pAppDataOffset = easHandle->jetHandle->appDataOffset;
- *pAppDataSize = easHandle->jetHandle->appDataSize;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * JET_CloseFile()
- *----------------------------------------------------------------------------
- * Closes a JET content file and releases associated resources
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT JET_CloseFile (EAS_DATA_HANDLE easHandle)
-{
- EAS_INT index;
- EAS_RESULT result = EAS_SUCCESS;
-
- /* close open streams */
- for (index = 0; index < SEG_QUEUE_DEPTH; index++)
- {
- if (easHandle->jetHandle->segQueue[index].streamHandle != NULL)
- {
- result = JET_CloseSegment(easHandle, index);
- if (result != EAS_SUCCESS)
- break;
- }
- }
-
- /* close the main file handle */
- if ((result == EAS_SUCCESS) && (easHandle->jetHandle->jetFileHandle != NULL))
- {
- result = EAS_HWCloseFile(easHandle->hwInstData, easHandle->jetHandle->jetFileHandle);
- if (result == EAS_SUCCESS)
- easHandle->jetHandle->jetFileHandle = NULL;
- }
- return result;
-}
-
-/*----------------------------------------------------------------------------
- * JET_Init()
- *----------------------------------------------------------------------------
- * Initializes the JET library, allocates memory, etc. Call
- * JET_Shutdown to de-allocate memory.
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT JET_Init (EAS_DATA_HANDLE easHandle, const S_JET_CONFIG *pConfig, EAS_INT configSize)
-{
- S_JET_DATA *pJet;
- EAS_U8 flags = 0;
-
- /* sanity check */
- if (easHandle == NULL)
- return EAS_ERROR_HANDLE_INTEGRITY;
- if (easHandle->jetHandle != NULL)
- return EAS_ERROR_FEATURE_ALREADY_ACTIVE;
- if (pConfig == NULL)
- pConfig = &jetDefaultConfig;
-
- /* allocate the JET data object */
- pJet = EAS_HWMalloc(easHandle->hwInstData, sizeof(S_JET_DATA));
- if (pJet == NULL)
- return EAS_ERROR_MALLOC_FAILED;
-
- /* initialize JET data structure */
- EAS_HWMemSet(pJet, 0, sizeof(S_JET_DATA));
- easHandle->jetHandle = pJet;
- pJet->flags = flags;
-
- /* copy config data */
- if (configSize > (EAS_INT) sizeof(S_JET_CONFIG))
- configSize = sizeof(S_JET_CONFIG);
- EAS_HWMemCpy(&pJet->config, pConfig, configSize);
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * JET_Shutdown()
- *----------------------------------------------------------------------------
- * Frees any memory used by the JET library
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT JET_Shutdown (EAS_DATA_HANDLE easHandle)
-{
- EAS_RESULT result;
-
- /* close any open files */
- result = JET_CloseFile(easHandle);
-
- /* free allocated data */
- EAS_HWFree(easHandle->hwInstData, easHandle->jetHandle);
- easHandle->jetHandle = NULL;
- return result;
-}
-
-/*----------------------------------------------------------------------------
- * JET_Status()
- *----------------------------------------------------------------------------
- * Returns current status
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT JET_Status (EAS_DATA_HANDLE easHandle, S_JET_STATUS *pStatus)
-{
- S_JET_SEGMENT *pSeg;
-
- pSeg = &easHandle->jetHandle->segQueue[easHandle->jetHandle->playSegment];
- if (pSeg->streamHandle != NULL)
- {
- pStatus->currentUserID = pSeg->userID;
- pStatus->segmentRepeatCount = pSeg->repeatCount;
- }
- else
- {
- pStatus->currentUserID = -1;
- pStatus->segmentRepeatCount = 0;
- }
-
- pStatus->paused = !(easHandle->jetHandle->flags & JET_FLAGS_PLAYING);
- pStatus->numQueuedSegments = easHandle->jetHandle->numQueuedSegments;
- pStatus->currentPlayingSegment = easHandle->jetHandle->playSegment;
- pStatus->currentQueuedSegment = easHandle->jetHandle->queueSegment;
- if (pSeg->streamHandle != NULL)
- {
- EAS_RESULT result;
- EAS_I32 location ;
- if ((result = EAS_GetLocation(easHandle, pSeg->streamHandle, &location)) == EAS_SUCCESS)
- if(location != 0)
- {
- pStatus->location = location;
- }
- }
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * JET_GetEvent()
- *----------------------------------------------------------------------------
- * Checks for application events
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_BOOL JET_GetEvent (EAS_DATA_HANDLE easHandle, EAS_U32 *pEventRaw, S_JET_EVENT *pEvent)
-{
- EAS_U32 jetEvent;
- EAS_BOOL gotEvent;
-
- /* process event queue */
- gotEvent = JET_ReadQueue(easHandle->jetHandle->appEventQueue,
- &easHandle->jetHandle->appEventQueueRead,
- easHandle->jetHandle->appEventQueueWrite,
- APP_EVENT_QUEUE_SIZE, &jetEvent);
-
- if (gotEvent)
- {
- if (pEventRaw != NULL)
- *pEventRaw = jetEvent;
-
- if (pEvent != NULL)
- JET_ParseEvent(jetEvent, pEvent);
- }
-
- return gotEvent;
-}
-
-/*----------------------------------------------------------------------------
- * JET_QueueSegment()
- *----------------------------------------------------------------------------
- * Queue a segment for playback
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT JET_QueueSegment (EAS_DATA_HANDLE easHandle, EAS_INT segmentNum, EAS_INT libNum, EAS_INT repeatCount, EAS_INT transpose, EAS_U32 muteFlags, EAS_U8 userID)
-{
- EAS_FILE_HANDLE fileHandle;
- EAS_RESULT result;
- S_JET_SEGMENT *p;
-
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "JET_QueueSegment segNum=%d, queue=%d\n", segmentNum, easHandle->jetHandle->queueSegment); */ }
-
- /* make sure it's a valid segment */
- if (segmentNum >= easHandle->jetHandle->numSegments)
- return EAS_ERROR_PARAMETER_RANGE;
-
- /* make sure it's a valid DLS */
- if (libNum >= easHandle->jetHandle->numLibraries)
- return EAS_ERROR_PARAMETER_RANGE;
-
- /* check to see if queue is full */
- p = &easHandle->jetHandle->segQueue[easHandle->jetHandle->queueSegment];
- if (p->streamHandle != NULL)
- return EAS_ERROR_QUEUE_IS_FULL;
-
- /* initialize data */
- p->userID = userID;
- p->repeatCount = (EAS_I16) repeatCount;
- p->transpose = (EAS_I8) transpose;
- p->libNum = (EAS_I8) libNum;
- p->muteFlags = muteFlags;
- p->state = JET_STATE_CLOSED;
-
- /* open the file */
- result = EAS_OpenJETStream(easHandle, easHandle->jetHandle->jetFileHandle, easHandle->jetHandle->segmentOffsets[segmentNum], &p->streamHandle);
- if (result != EAS_SUCCESS)
- return result;
- p->state = JET_STATE_OPEN;
-
- /* if less than SEG_QUEUE_DEPTH segments queued up, prepare file for playback */
- if (++easHandle->jetHandle->numQueuedSegments < SEG_QUEUE_DEPTH)
- {
- result = JET_PrepareSegment(easHandle, easHandle->jetHandle->queueSegment);
- if (result != EAS_SUCCESS)
- return result;
- }
-
- /* create duplicate file handle */
- result = EAS_HWDupHandle(easHandle->hwInstData, easHandle->jetHandle->jetFileHandle, &fileHandle);
- if (result != EAS_SUCCESS)
- return result;
-
- easHandle->jetHandle->jetFileHandle = fileHandle;
- easHandle->jetHandle->queueSegment = (EAS_U8) JET_NextSegment(easHandle->jetHandle->queueSegment);
- return result;
-}
-
-/*----------------------------------------------------------------------------
- * JET_Play()
- *----------------------------------------------------------------------------
- * Starts playback of the file
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT JET_Play (EAS_DATA_HANDLE easHandle)
-{
- EAS_RESULT result;
- EAS_INT index;
- EAS_INT count = 0;
-
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "JET_Play\n"); */ }
-
- /* sanity check */
- if (easHandle->jetHandle->flags & JET_FLAGS_PLAYING)
- return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
-
- /* resume all paused streams */
- for (index = 0; index < SEG_QUEUE_DEPTH; index++)
- {
- if (((index == easHandle->jetHandle->playSegment) && (easHandle->jetHandle->segQueue[index].state == JET_STATE_READY)) ||
- (easHandle->jetHandle->segQueue[index].state == JET_STATE_PAUSED))
- {
- result = JET_StartPlayback(easHandle, index);
- if (result != EAS_SUCCESS)
- return result;
- count++;
- }
- }
-
- /* if no streams are playing, return error */
- if (!count)
- return EAS_ERROR_QUEUE_IS_EMPTY;
-
- easHandle->jetHandle->flags |= JET_FLAGS_PLAYING;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * JET_Pause()
- *----------------------------------------------------------------------------
- * Pauses playback of the file
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT JET_Pause (EAS_DATA_HANDLE easHandle)
-{
- EAS_RESULT result;
- EAS_INT index;
- EAS_INT count = 0;
-
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "JET_Pause\n"); */ }
-
- /* sanity check */
- if ((easHandle->jetHandle->flags & JET_FLAGS_PLAYING) == 0)
- return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
-
- /* pause all playing streams */
- for (index = 0; index < SEG_QUEUE_DEPTH; index++)
- {
- if (easHandle->jetHandle->segQueue[index].state == JET_STATE_PLAYING)
- {
- result = EAS_Pause(easHandle, easHandle->jetHandle->segQueue[easHandle->jetHandle->playSegment].streamHandle);
- if (result != EAS_SUCCESS)
- return result;
- easHandle->jetHandle->segQueue[easHandle->jetHandle->playSegment].state = JET_STATE_PAUSED;
- count++;
- }
- }
-
- /* if no streams are paused, return error */
- if (!count)
- return EAS_ERROR_QUEUE_IS_EMPTY;
-
- easHandle->jetHandle->flags &= ~JET_FLAGS_PLAYING;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * JET_SetMuteFlags()
- *----------------------------------------------------------------------------
- * Change the state of the mute flags
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT JET_SetMuteFlags (EAS_DATA_HANDLE easHandle, EAS_U32 muteFlags, EAS_BOOL sync)
-{
- S_JET_SEGMENT *pSeg;
-
- /* get pointer to current segment */
- pSeg = &easHandle->jetHandle->segQueue[easHandle->jetHandle->playSegment];
-
- /* unsynchronized mute, set flags and return */
- if (!sync)
- {
- if (pSeg->streamHandle == NULL)
- return EAS_ERROR_QUEUE_IS_EMPTY;
- pSeg->muteFlags = muteFlags;
- return EAS_IntSetStrmParam(easHandle, pSeg->streamHandle, PARSER_DATA_MUTE_FLAGS, (EAS_I32) muteFlags);
- }
-
-
- /* check for valid stream state */
- if (pSeg->state == JET_STATE_CLOSED)
- return EAS_ERROR_QUEUE_IS_EMPTY;
-
- /* save mute flags */
- pSeg->muteFlags = muteFlags;
-
- /* if repeating segment, set mute update flag */
- if (sync)
- pSeg->flags |= JET_SEG_FLAG_MUTE_UPDATE;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * JET_SetMuteFlag()
- *----------------------------------------------------------------------------
- * Change the state of a single mute flag
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT JET_SetMuteFlag (EAS_DATA_HANDLE easHandle, EAS_INT trackNum, EAS_BOOL muteFlag, EAS_BOOL sync)
-{
- S_JET_SEGMENT *pSeg;
- EAS_U32 trackMuteFlag;
-
-
- /* setup flag */
- if ((trackNum < 0) || (trackNum > 31))
- return EAS_ERROR_PARAMETER_RANGE;
- trackMuteFlag = (1 << trackNum);
-
- /* get pointer to current segment */
- pSeg = &easHandle->jetHandle->segQueue[easHandle->jetHandle->playSegment];
-
- /* unsynchronized mute, set flags and return */
- if (!sync)
- {
- if (pSeg->streamHandle == NULL)
- return EAS_ERROR_QUEUE_IS_EMPTY;
- if (muteFlag)
- pSeg->muteFlags |= trackMuteFlag;
- else
- pSeg->muteFlags &= ~trackMuteFlag;
- return EAS_IntSetStrmParam(easHandle, pSeg->streamHandle, PARSER_DATA_MUTE_FLAGS, (EAS_I32) pSeg->muteFlags);
- }
-
-
- /* check for valid stream state */
- if (pSeg->state == JET_STATE_CLOSED)
- return EAS_ERROR_QUEUE_IS_EMPTY;
-
- /* save mute flags and set mute update flag */
- if (muteFlag)
- pSeg->muteFlags |= trackMuteFlag;
- else
- pSeg->muteFlags &= ~trackMuteFlag;
- pSeg->flags |= JET_SEG_FLAG_MUTE_UPDATE;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * JET_TriggerClip()
- *----------------------------------------------------------------------------
- * Unmute a track and then mute it when it is complete. If a clip
- * is already playing, change mute event to a trigger event. The
- * JET_Event function will not mute the clip, but will allow it
- * to continue playing through the next clip.
- *
- * NOTE: We use bit 7 to indicate an entry in the queue. For a
- * small queue, it is cheaper in both memory and CPU cycles to
- * scan the entire queue for non-zero events than keep enqueue
- * and dequeue indices.
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT JET_TriggerClip (EAS_DATA_HANDLE easHandle, EAS_INT clipID)
-{
- EAS_INT i;
- EAS_INT index = -1;
-
- /* check for valid clipID */
- if ((clipID < 0) || (clipID > 63))
- return EAS_ERROR_PARAMETER_RANGE;
-
- /* set active flag */
- clipID |= JET_CLIP_ACTIVE_FLAG;
-
- /* Reverse the search so that we get the first empty element */
- for (i = JET_MUTE_QUEUE_SIZE-1; i >= 0 ; i--)
- {
- if (easHandle->jetHandle->muteQueue[i] == clipID)
- {
- index = i;
- break;
- }
- if (easHandle->jetHandle->muteQueue[i] == 0)
- index = i;
- }
- if (index < 0)
- return EAS_ERROR_QUEUE_IS_FULL;
-
- easHandle->jetHandle->muteQueue[index] = (EAS_U8) clipID | JET_CLIP_TRIGGER_FLAG;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * JET_Process()
- *----------------------------------------------------------------------------
- * Called during EAS_Render to process stream states
- *----------------------------------------------------------------------------
-*/
-EAS_PUBLIC EAS_RESULT JET_Process (EAS_DATA_HANDLE easHandle)
-{
- S_JET_SEGMENT *pSeg;
- EAS_STATE state;
- EAS_INT index;
- EAS_INT playIndex;
- EAS_RESULT result = EAS_SUCCESS;
- EAS_BOOL endOfLoop = EAS_FALSE;
- EAS_BOOL startNextSegment = EAS_FALSE;
- EAS_BOOL prepareNextSegment = EAS_FALSE;
- EAS_U32 jetEvent;
-
- /* process event queue */
- while (JET_ReadQueue(easHandle->jetHandle->jetEventQueue,
- &easHandle->jetHandle->jetEventQueueRead,
- easHandle->jetHandle->jetEventQueueWrite,
- JET_EVENT_QUEUE_SIZE, &jetEvent))
- {
- S_JET_EVENT event;
-#ifdef DEBUG_JET
- JET_DumpEvent("JET_Process", jetEvent);
-#endif
- JET_ParseEvent(jetEvent, &event);
-
- /* check for end of loop */
- if ((event.controller == JET_EVENT_MARKER) &&
- (event.value == JET_MARKER_LOOP_END) &&
- (easHandle->jetHandle->segQueue[easHandle->jetHandle->playSegment].streamHandle != NULL))
- endOfLoop = EAS_TRUE;
- }
-
- /* check state of all streams */
- index = playIndex = easHandle->jetHandle->playSegment;
- for (;;)
- {
- pSeg = &easHandle->jetHandle->segQueue[index];
- if (pSeg->state != JET_STATE_CLOSED)
- {
-
- /* get playback state */
- result = EAS_State(easHandle, pSeg->streamHandle, &state);
- if (result != EAS_SUCCESS)
- return result;
-
- /* process state */
- switch (pSeg->state)
- {
- /* take action if this segment is stopping */
- case JET_STATE_PLAYING:
- if (endOfLoop || (state == EAS_STATE_STOPPING) || (state == EAS_STATE_STOPPED))
- {
- /* handle repeats */
- if (pSeg->repeatCount != 0)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "JET_Render repeating segment %d\n", index); */ }
- result = EAS_Locate(easHandle, pSeg->streamHandle, 0, EAS_FALSE);
- if (result != EAS_SUCCESS)
- return result;
- if (pSeg->repeatCount > 0)
- pSeg->repeatCount--;
-
- /* update mute flags if necessary */
- if (pSeg->flags & JET_SEG_FLAG_MUTE_UPDATE)
- {
- result = EAS_IntSetStrmParam(easHandle, pSeg->streamHandle, PARSER_DATA_MUTE_FLAGS, (EAS_I32) pSeg->muteFlags);
- if (result != EAS_SUCCESS)
- return result;
- pSeg->flags &= ~JET_SEG_FLAG_MUTE_UPDATE;
- }
-
- }
- /* no repeat, start next segment */
- else
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "JET_Render stopping queue %d\n", index); */ }
- startNextSegment = EAS_TRUE;
- pSeg->state = JET_STATE_STOPPING;
- easHandle->jetHandle->playSegment = (EAS_U8) JET_NextSegment(index);
- }
- }
- break;
-
- /* if playback has stopped, close the segment */
- case JET_STATE_STOPPING:
- if (state == EAS_STATE_STOPPED)
- {
- result = JET_CloseSegment(easHandle, index);
- if (result != EAS_SUCCESS)
- return result;
- }
- break;
-
- case JET_STATE_READY:
- if (startNextSegment)
- {
- result = JET_StartPlayback(easHandle, index);
- if (result != EAS_SUCCESS)
- return result;
- startNextSegment = EAS_FALSE;
- prepareNextSegment = EAS_TRUE;
- }
- break;
-
- case JET_STATE_OPEN:
- if (prepareNextSegment)
- {
- result = JET_PrepareSegment(easHandle, index);
- if (result != EAS_SUCCESS)
- return result;
- prepareNextSegment = EAS_FALSE;
- }
- break;
-
- case JET_STATE_PAUSED:
- break;
-
- default:
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "JET_Render: Unexpected segment state %d\n", pSeg->state); */ }
- break;
- }
- }
-
- /* increment index */
- index = JET_NextSegment(index);
- if (index == playIndex)
- break;
- }
-
- /* if out of segments, clear playing flag */
- if (easHandle->jetHandle->numQueuedSegments == 0)
- easHandle->jetHandle->flags &= ~JET_FLAGS_PLAYING;
-
- return result;
-}
-
-/*----------------------------------------------------------------------------
- * JET_Event()
- *----------------------------------------------------------------------------
- * Called from MIDI parser when data of interest is received
- *----------------------------------------------------------------------------
-*/
-void JET_Event (EAS_DATA_HANDLE easHandle, EAS_U32 segTrack, EAS_U8 channel, EAS_U8 controller, EAS_U8 value)
-{
- EAS_U32 event;
-
- if (easHandle->jetHandle == NULL)
- return;
-
- /* handle triggers */
- if (controller == JET_EVENT_TRIGGER_CLIP)
- {
- S_JET_SEGMENT *pSeg;
- EAS_INT i;
- EAS_U32 muteFlag;
-
- for (i = 0; i < JET_MUTE_QUEUE_SIZE; i++)
- {
- /* search for event in queue */
- if ((easHandle->jetHandle->muteQueue[i] & JET_CLIP_ID_MASK) == (value & JET_CLIP_ID_MASK))
- {
- /* get segment pointer and mute flag */
- pSeg = &easHandle->jetHandle->segQueue[segTrack >> JET_EVENT_SEG_SHIFT];
- muteFlag = 1 << ((segTrack & JET_EVENT_TRACK_MASK) >> JET_EVENT_TRACK_SHIFT);
-
- /* un-mute the track */
- if ((easHandle->jetHandle->muteQueue[i] & JET_CLIP_TRIGGER_FLAG) && ((value & 0x40) > 0))
- {
- pSeg->muteFlags &= ~muteFlag;
- easHandle->jetHandle->muteQueue[i] &= ~JET_CLIP_TRIGGER_FLAG;
- }
-
- /* mute the track */
- else
- {
- EAS_U32 beforeMute ;
- beforeMute = pSeg->muteFlags ;
- pSeg->muteFlags |= muteFlag;
- if (beforeMute != pSeg->muteFlags)
- easHandle->jetHandle->muteQueue[i] = 0;
- }
- EAS_IntSetStrmParam(easHandle, pSeg->streamHandle, PARSER_DATA_MUTE_FLAGS, (EAS_I32) pSeg->muteFlags);
- return;
- }
- }
- return;
- }
-
- /* generic event stuff */
- event = (channel << JET_EVENT_CHAN_SHIFT) | (controller << JET_EVENT_CTRL_SHIFT) | value;
-
- /* write to app queue, translate queue index to segment number */
- if ((controller >= easHandle->jetHandle->config.appEventRangeLow) && (controller <= easHandle->jetHandle->config.appEventRangeHigh))
- {
-
- event |= easHandle->jetHandle->segQueue[(segTrack & JET_EVENT_SEG_MASK) >> JET_EVENT_SEG_SHIFT].userID << JET_EVENT_SEG_SHIFT;
-#ifdef DEBUG_JET
- JET_DumpEvent("JET_Event[app]", event);
-#endif
- JET_WriteQueue(easHandle->jetHandle->appEventQueue,
- &easHandle->jetHandle->appEventQueueWrite,
- easHandle->jetHandle->appEventQueueRead,
- APP_EVENT_QUEUE_SIZE,
- event);
- }
-
- /* write to JET queue */
- else if ((controller >= JET_EVENT_LOW) && (controller <= JET_EVENT_HIGH))
- {
- event |= segTrack;
-#ifdef DEBUG_JET
- JET_DumpEvent("JET_Event[jet]", event);
-#endif
- JET_WriteQueue(easHandle->jetHandle->jetEventQueue,
- &easHandle->jetHandle->jetEventQueueWrite,
- easHandle->jetHandle->jetEventQueueRead,
- JET_EVENT_QUEUE_SIZE,
- event);
- }
-}
-
-/*----------------------------------------------------------------------------
- * JET_Clear_Queue()
- *----------------------------------------------------------------------------
- * Clears the queue and stops play without a complete shutdown
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT JET_Clear_Queue(EAS_DATA_HANDLE easHandle)
-{
- EAS_INT index;
- EAS_RESULT result = EAS_SUCCESS;
-
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "JET_Clear_Queue\n"); */ }
-
- /* pause all playing streams */
- for (index = 0; index < SEG_QUEUE_DEPTH; index++)
- {
- if (easHandle->jetHandle->segQueue[index].state == JET_STATE_PLAYING)
- {
- result = EAS_Pause(easHandle, easHandle->jetHandle->segQueue[index].streamHandle);
- if (result != EAS_SUCCESS)
- return result;
-
- easHandle->jetHandle->segQueue[index].state = JET_STATE_PAUSED;
- }
- }
-
- /* close all streams */
- for (index = 0; index < SEG_QUEUE_DEPTH; index++)
- {
- if (easHandle->jetHandle->segQueue[index].streamHandle != NULL)
- {
- result = JET_CloseSegment(easHandle, index);
- if (result != EAS_SUCCESS)
- return result;
- }
- }
-
- /* clear all clips */
- for (index = 0; index < JET_MUTE_QUEUE_SIZE ; index++)
- {
- easHandle->jetHandle->muteQueue[index] = 0;
- }
-
- easHandle->jetHandle->flags &= ~JET_FLAGS_PLAYING;
- easHandle->jetHandle->playSegment = easHandle->jetHandle->queueSegment = 0;
- return result;
-}
-
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * jet.c
+ *
+ * Contents and purpose:
+ * Implementation for JET sound engine
+ *
+ * Copyright (c) 2006 Sonic Network Inc.
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 563 $
+ * $Date: 2007-02-13 20:26:23 -0800 (Tue, 13 Feb 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "JET_C"
+
+//#define DEBUG_JET
+
+#include "eas_data.h"
+#include "eas_smf.h"
+#include "jet_data.h"
+#include "eas_host.h"
+#include "eas_report.h"
+
+
+/* default configuration */
+static const S_JET_CONFIG jetDefaultConfig =
+{
+ JET_EVENT_APP_LOW,
+ JET_EVENT_APP_HIGH
+};
+
+/* function prototypes */
+extern EAS_RESULT EAS_IntSetStrmParam (S_EAS_DATA *pEASData, EAS_HANDLE pStream, EAS_INT param, EAS_I32 value);
+extern EAS_RESULT EAS_OpenJETStream (EAS_DATA_HANDLE pEASData, EAS_FILE_HANDLE fileHandle, EAS_I32 offset, EAS_HANDLE *ppStream);
+extern EAS_RESULT DLSParser (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE fileHandle, EAS_I32 offset, EAS_DLSLIB_HANDLE *ppDLS);
+
+/*----------------------------------------------------------------------------
+ * JET_ParseEvent()
+ *----------------------------------------------------------------------------
+ * Returns current status
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC void JET_ParseEvent (EAS_U32 event, S_JET_EVENT *pEvent)
+{
+ pEvent->segment = (EAS_U8) ((event & JET_EVENT_SEG_MASK) >> JET_EVENT_SEG_SHIFT);
+ pEvent->track = (EAS_U8) ((event & JET_EVENT_TRACK_MASK) >> JET_EVENT_TRACK_SHIFT);
+ pEvent->channel = (EAS_U8) ((event & JET_EVENT_CHAN_MASK) >> JET_EVENT_CHAN_SHIFT);
+ pEvent->controller = (EAS_U8) ((event & JET_EVENT_CTRL_MASK) >> JET_EVENT_CTRL_SHIFT);
+ pEvent->value = (EAS_U8) (event & JET_EVENT_VAL_MASK);
+}
+
+#ifdef DEBUG_JET
+/*----------------------------------------------------------------------------
+ * JET_DumpEvent
+ *----------------------------------------------------------------------------
+ * Advances queue read/write index
+ *----------------------------------------------------------------------------
+*/
+static void JET_DumpEvent (const char *procName, EAS_U32 event)
+{
+ S_JET_EVENT sEvent;
+ JET_ParseEvent(event, &sEvent);
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "%s: SegID=%d, TrkID=%d, channel=%d, ctrl=%d, val=%d\n",
+ procName, sEvent.segment, sEvent.track, sEvent.channel, sEvent.controller, sEvent.value); */ }
+}
+#endif
+
+/*----------------------------------------------------------------------------
+ * JET_IncQueueIndex
+ *----------------------------------------------------------------------------
+ * Advances queue read/write index
+ *----------------------------------------------------------------------------
+*/
+EAS_INLINE EAS_U8 JET_IncQueueIndex (EAS_U8 index, EAS_U8 queueSize)
+{
+ if (++index == queueSize)
+ index = 0;
+ return index;
+}
+
+/*----------------------------------------------------------------------------
+ * JET_WriteQueue
+ *----------------------------------------------------------------------------
+ * Save event to queue
+ *----------------------------------------------------------------------------
+*/
+EAS_INLINE void JET_WriteQueue (EAS_U32 *pEventQueue, EAS_U8 *pWriteIndex, EAS_U8 readIndex, EAS_U8 queueSize, EAS_U32 event)
+{
+ EAS_U8 temp;
+
+ /* check for queue overflow */
+ temp = JET_IncQueueIndex(*pWriteIndex, queueSize);
+ if (temp == readIndex)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "JET_Event: Event queue overflow --- event ignored!\n"); */ }
+ return;
+ }
+
+ /* save in queue and advance write index */
+ pEventQueue[*pWriteIndex] = event;
+ *pWriteIndex = temp;
+}
+
+/*----------------------------------------------------------------------------
+ * JET_ReadQueue
+ *----------------------------------------------------------------------------
+ * Read event to queue
+ *----------------------------------------------------------------------------
+*/
+EAS_INLINE EAS_BOOL JET_ReadQueue (EAS_U32 *pEventQueue, EAS_U8 *pReadIndex, EAS_U8 writeIndex, EAS_U8 queueSize, EAS_U32 *pEvent)
+{
+
+ /* check for empty queue */
+ if (*pReadIndex == writeIndex)
+ return EAS_FALSE;
+
+ /* save in queue and advance write index */
+ *pEvent = pEventQueue[*pReadIndex];
+ *pReadIndex = JET_IncQueueIndex(*pReadIndex, queueSize);
+ return EAS_TRUE;
+}
+
+/*----------------------------------------------------------------------------
+ * JET_NextSegment
+ *----------------------------------------------------------------------------
+ * Advances segment number
+ *----------------------------------------------------------------------------
+*/
+EAS_INLINE EAS_INT JET_NextSegment (EAS_INT seg_num)
+{
+ if (++seg_num == SEG_QUEUE_DEPTH)
+ seg_num = 0;
+ return seg_num;
+}
+
+/*----------------------------------------------------------------------------
+ * JET_PrepareSegment()
+ *----------------------------------------------------------------------------
+ * Prepare a segment for playback
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT JET_PrepareSegment (EAS_DATA_HANDLE easHandle, EAS_I32 queueNum)
+{
+ EAS_RESULT result;
+ S_JET_SEGMENT *p;
+
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "JET_PrepareSegment: %d\n", queueNum); */ }
+
+ p = &easHandle->jetHandle->segQueue[queueNum];
+ result = EAS_Prepare(easHandle, p->streamHandle);
+ if (result != EAS_SUCCESS)
+ return result;
+
+ /* pause segment - must be triggered by play or end of previous segment */
+ result = EAS_Pause(easHandle, p->streamHandle);
+ if (result != EAS_SUCCESS)
+ return result;
+ p->state = JET_STATE_READY;
+
+ /* set calback data */
+ result = EAS_IntSetStrmParam(easHandle, p->streamHandle, PARSER_DATA_JET_CB, queueNum);
+ if (result != EAS_SUCCESS)
+ return result;
+
+ /* set DLS collection */
+ if (p->libNum >= 0)
+ {
+ result = EAS_IntSetStrmParam(easHandle, p->streamHandle,
+ PARSER_DATA_DLS_COLLECTION, (EAS_I32) easHandle->jetHandle->libHandles[p->libNum]);
+ if (result != EAS_SUCCESS)
+ return result;
+ }
+
+ /* set transposition */
+ if (p->transpose)
+ {
+ result = EAS_SetTransposition(easHandle, p->streamHandle, p->transpose);
+ if (result != EAS_SUCCESS)
+ return result;
+ }
+
+ return result;
+}
+
+/*----------------------------------------------------------------------------
+ * JET_StartPlayback()
+ *----------------------------------------------------------------------------
+ * Start segment playback
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT JET_StartPlayback (EAS_DATA_HANDLE easHandle, EAS_I32 queueNum)
+{
+ EAS_RESULT result = EAS_SUCCESS;
+ S_JET_SEGMENT *pSeg;
+
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "JET_StartPlayback %d\n", queueNum); */ }
+
+ /* if next segment is queued, start playback */
+ pSeg = &easHandle->jetHandle->segQueue[queueNum];
+ if (pSeg->streamHandle != NULL)
+ {
+ result = EAS_Resume(easHandle, pSeg->streamHandle);
+ easHandle->jetHandle->segQueue[queueNum].state = JET_STATE_PLAYING;
+
+ /* set mute flags */
+ if ((result == EAS_SUCCESS) && (pSeg->muteFlags != 0))
+ result = EAS_IntSetStrmParam(easHandle, pSeg->streamHandle, PARSER_DATA_MUTE_FLAGS, (EAS_I32) pSeg->muteFlags);
+ }
+ return result;
+}
+
+/*----------------------------------------------------------------------------
+ * JET_CloseSegment
+ *----------------------------------------------------------------------------
+ * Closes stream associated with a segment
+ *----------------------------------------------------------------------------
+*/
+EAS_INLINE EAS_INT JET_CloseSegment (EAS_DATA_HANDLE easHandle, EAS_INT queueNum)
+{
+ EAS_RESULT result;
+
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "JET_CloseSegment %d\n", queueNum); */ }
+
+ /* close the segment */
+ result = EAS_CloseFile(easHandle, easHandle->jetHandle->segQueue[queueNum].streamHandle);
+ if (result != EAS_SUCCESS)
+ return result;
+
+ easHandle->jetHandle->segQueue[queueNum].streamHandle = NULL;
+ easHandle->jetHandle->segQueue[queueNum].state = JET_STATE_CLOSED;
+ easHandle->jetHandle->numQueuedSegments--;
+ return result;
+}
+
+/*----------------------------------------------------------------------------
+ * JetParseInfoChunk()
+ *----------------------------------------------------------------------------
+ * Parses the JET info chunk
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT JetParseInfoChunk (EAS_DATA_HANDLE easHandle, EAS_I32 pos, EAS_I32 chunkSize)
+{
+ EAS_RESULT result;
+ EAS_U32 infoType;
+ EAS_U32 temp;
+
+ /* offset to data */
+ result = EAS_HWFileSeek(easHandle->hwInstData, easHandle->jetHandle->jetFileHandle, pos);
+ if (result != EAS_SUCCESS)
+ return result;
+
+ /* read the entire chunk */
+ result = EAS_SUCCESS;
+ while ((result == EAS_SUCCESS) && (chunkSize > 0))
+ {
+
+ /* get info infoType */
+ result = EAS_HWGetDWord(easHandle->hwInstData, easHandle->jetHandle->jetFileHandle, &infoType, EAS_TRUE);
+ if (result != EAS_SUCCESS)
+ break;
+
+ /* get info field */
+ result = EAS_HWGetDWord(easHandle->hwInstData, easHandle->jetHandle->jetFileHandle, &temp, EAS_FALSE);
+ if (result == EAS_SUCCESS)
+
+ switch (infoType)
+ {
+ case INFO_NUM_SMF_CHUNKS:
+ easHandle->jetHandle->numSegments = (EAS_U8) temp;
+ break;
+
+ case INFO_NUM_DLS_CHUNKS:
+ easHandle->jetHandle->numLibraries = (EAS_U8) temp;
+ break;
+
+ case INFO_JET_VERSION:
+ /* check major version number */
+ if ((temp & 0xff000000) != (JET_VERSION & 0xff000000))
+ return EAS_ERROR_INCOMPATIBLE_VERSION;
+ break;
+
+ default:
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Ignoring unrecognized JET info type 0x%08x", infoType); */ }
+ break;
+ }
+
+ chunkSize -= 8;
+ }
+
+ /* allocate pointers for chunks to follow */
+
+ return result;
+}
+
+/*----------------------------------------------------------------------------
+ * JET_OpenFile()
+ *----------------------------------------------------------------------------
+ * Opens a JET content file for playback
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT JET_OpenFile (EAS_DATA_HANDLE easHandle, EAS_FILE_LOCATOR locator)
+{
+ EAS_RESULT result;
+ EAS_U32 chunkType;
+ EAS_I32 pos;
+ EAS_I32 chunkSize;
+ EAS_INT smfChunkNum;
+ EAS_INT dlsChunkNum;
+ EAS_I32 dataSize = 0; /* make lint happy */
+
+ /* make sure that we don't have an open file */
+ if (easHandle->jetHandle->jetFileHandle != NULL)
+ return EAS_ERROR_FILE_ALREADY_OPEN;
+
+ /* open the media file */
+ result = EAS_HWOpenFile(easHandle->hwInstData, locator, &easHandle->jetHandle->jetFileHandle, EAS_FILE_READ);
+ if (result != EAS_SUCCESS)
+ return result;
+
+ /* check header */
+ result = EAS_HWGetDWord(easHandle->hwInstData, easHandle->jetHandle->jetFileHandle, &chunkType, EAS_TRUE);
+ if (result == EAS_SUCCESS)
+ {
+ if (chunkType != JET_HEADER_TAG)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "File is not JET format\n"); */ }
+ result = EAS_ERROR_UNRECOGNIZED_FORMAT;
+ }
+ }
+ /* get the file data size */
+ if (result == EAS_SUCCESS)
+ result = EAS_HWGetDWord(easHandle->hwInstData, easHandle->jetHandle->jetFileHandle, &dataSize, EAS_FALSE);
+
+ /* parse through the file to find contents */
+ smfChunkNum = dlsChunkNum = 0;
+ pos = chunkSize = 8;
+ while ((result == EAS_SUCCESS) && (pos < dataSize))
+ {
+
+ /* offset to chunk data */
+ result = EAS_HWFileSeek(easHandle->hwInstData, easHandle->jetHandle->jetFileHandle, pos);
+ if (result != EAS_SUCCESS)
+ break;
+
+ /* get chunk size and type */
+ result = EAS_HWGetDWord(easHandle->hwInstData, easHandle->jetHandle->jetFileHandle, &chunkType, EAS_TRUE);
+ if (result != EAS_SUCCESS)
+ break;
+
+ result = EAS_HWGetDWord(easHandle->hwInstData, easHandle->jetHandle->jetFileHandle, &chunkSize, EAS_FALSE);
+ if (result != EAS_SUCCESS)
+ break;
+ pos += 8;
+
+ switch (chunkType)
+ {
+ case JET_INFO_CHUNK:
+ result = JetParseInfoChunk(easHandle, pos, chunkSize);
+ break;
+
+ case JET_SMF_CHUNK:
+ if (smfChunkNum < easHandle->jetHandle->numSegments)
+ easHandle->jetHandle->segmentOffsets[smfChunkNum++] = pos;
+ else
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Ignoring extraneous SMF chunk"); */ }
+ break;
+
+ case JET_DLS_CHUNK:
+ if (dlsChunkNum < easHandle->jetHandle->numLibraries)
+ result = DLSParser(easHandle->hwInstData, easHandle->jetHandle->jetFileHandle, pos, &easHandle->jetHandle->libHandles[dlsChunkNum++]);
+ else
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Ignoring extraneous DLS chunk"); */ }
+ break;
+
+ case JET_APP_DATA_CHUNK:
+ easHandle->jetHandle->appDataOffset = pos;
+ easHandle->jetHandle->appDataSize = chunkSize;
+ break;
+
+ case INFO_JET_COPYRIGHT:
+ break;
+
+ default:
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Ignoring unrecognized JET chunk type 0x%08x", chunkType); */ }
+ break;
+ }
+
+ /* offset to next chunk */
+ pos += chunkSize;
+ }
+
+ /* close file if something went wrong */
+ if (result != EAS_SUCCESS)
+ EAS_HWCloseFile(easHandle->hwInstData, easHandle->jetHandle->jetFileHandle);
+
+ return result;
+}
+
+/*----------------------------------------------------------------------------
+ * JET_GetAppData()
+ *----------------------------------------------------------------------------
+ * Returns location and size of application data in the JET file
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT JET_GetAppData (EAS_DATA_HANDLE easHandle, EAS_I32 *pAppDataOffset, EAS_I32 *pAppDataSize)
+{
+
+ /* check for app chunk */
+ if (easHandle->jetHandle->appDataSize == 0)
+ {
+ *pAppDataOffset = *pAppDataSize = 0;
+ return EAS_FAILURE;
+ }
+
+ /* return app data */
+ *pAppDataOffset = easHandle->jetHandle->appDataOffset;
+ *pAppDataSize = easHandle->jetHandle->appDataSize;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * JET_CloseFile()
+ *----------------------------------------------------------------------------
+ * Closes a JET content file and releases associated resources
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT JET_CloseFile (EAS_DATA_HANDLE easHandle)
+{
+ EAS_INT index;
+ EAS_RESULT result = EAS_SUCCESS;
+
+ /* close open streams */
+ for (index = 0; index < SEG_QUEUE_DEPTH; index++)
+ {
+ if (easHandle->jetHandle->segQueue[index].streamHandle != NULL)
+ {
+ result = JET_CloseSegment(easHandle, index);
+ if (result != EAS_SUCCESS)
+ break;
+ }
+ }
+
+ /* close the main file handle */
+ if ((result == EAS_SUCCESS) && (easHandle->jetHandle->jetFileHandle != NULL))
+ {
+ result = EAS_HWCloseFile(easHandle->hwInstData, easHandle->jetHandle->jetFileHandle);
+ if (result == EAS_SUCCESS)
+ easHandle->jetHandle->jetFileHandle = NULL;
+ }
+ return result;
+}
+
+/*----------------------------------------------------------------------------
+ * JET_Init()
+ *----------------------------------------------------------------------------
+ * Initializes the JET library, allocates memory, etc. Call
+ * JET_Shutdown to de-allocate memory.
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT JET_Init (EAS_DATA_HANDLE easHandle, const S_JET_CONFIG *pConfig, EAS_INT configSize)
+{
+ S_JET_DATA *pJet;
+ EAS_U8 flags = 0;
+
+ /* sanity check */
+ if (easHandle == NULL)
+ return EAS_ERROR_HANDLE_INTEGRITY;
+ if (easHandle->jetHandle != NULL)
+ return EAS_ERROR_FEATURE_ALREADY_ACTIVE;
+ if (pConfig == NULL)
+ pConfig = &jetDefaultConfig;
+
+ /* allocate the JET data object */
+ pJet = EAS_HWMalloc(easHandle->hwInstData, sizeof(S_JET_DATA));
+ if (pJet == NULL)
+ return EAS_ERROR_MALLOC_FAILED;
+
+ /* initialize JET data structure */
+ EAS_HWMemSet(pJet, 0, sizeof(S_JET_DATA));
+ easHandle->jetHandle = pJet;
+ pJet->flags = flags;
+
+ /* copy config data */
+ if (configSize > (EAS_INT) sizeof(S_JET_CONFIG))
+ configSize = sizeof(S_JET_CONFIG);
+ EAS_HWMemCpy(&pJet->config, pConfig, configSize);
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * JET_Shutdown()
+ *----------------------------------------------------------------------------
+ * Frees any memory used by the JET library
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT JET_Shutdown (EAS_DATA_HANDLE easHandle)
+{
+ EAS_RESULT result;
+
+ /* close any open files */
+ result = JET_CloseFile(easHandle);
+
+ /* free allocated data */
+ EAS_HWFree(easHandle->hwInstData, easHandle->jetHandle);
+ easHandle->jetHandle = NULL;
+ return result;
+}
+
+/*----------------------------------------------------------------------------
+ * JET_Status()
+ *----------------------------------------------------------------------------
+ * Returns current status
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT JET_Status (EAS_DATA_HANDLE easHandle, S_JET_STATUS *pStatus)
+{
+ S_JET_SEGMENT *pSeg;
+
+ pSeg = &easHandle->jetHandle->segQueue[easHandle->jetHandle->playSegment];
+ if (pSeg->streamHandle != NULL)
+ {
+ pStatus->currentUserID = pSeg->userID;
+ pStatus->segmentRepeatCount = pSeg->repeatCount;
+ }
+ else
+ {
+ pStatus->currentUserID = -1;
+ pStatus->segmentRepeatCount = 0;
+ }
+
+ pStatus->paused = !(easHandle->jetHandle->flags & JET_FLAGS_PLAYING);
+ pStatus->numQueuedSegments = easHandle->jetHandle->numQueuedSegments;
+ pStatus->currentPlayingSegment = easHandle->jetHandle->playSegment;
+ pStatus->currentQueuedSegment = easHandle->jetHandle->queueSegment;
+ if (pSeg->streamHandle != NULL)
+ {
+ EAS_RESULT result;
+ EAS_I32 location ;
+ if ((result = EAS_GetLocation(easHandle, pSeg->streamHandle, &location)) == EAS_SUCCESS)
+ if(location != 0)
+ {
+ pStatus->location = location;
+ }
+ }
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * JET_GetEvent()
+ *----------------------------------------------------------------------------
+ * Checks for application events
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_BOOL JET_GetEvent (EAS_DATA_HANDLE easHandle, EAS_U32 *pEventRaw, S_JET_EVENT *pEvent)
+{
+ EAS_U32 jetEvent;
+ EAS_BOOL gotEvent;
+
+ /* process event queue */
+ gotEvent = JET_ReadQueue(easHandle->jetHandle->appEventQueue,
+ &easHandle->jetHandle->appEventQueueRead,
+ easHandle->jetHandle->appEventQueueWrite,
+ APP_EVENT_QUEUE_SIZE, &jetEvent);
+
+ if (gotEvent)
+ {
+ if (pEventRaw != NULL)
+ *pEventRaw = jetEvent;
+
+ if (pEvent != NULL)
+ JET_ParseEvent(jetEvent, pEvent);
+ }
+
+ return gotEvent;
+}
+
+/*----------------------------------------------------------------------------
+ * JET_QueueSegment()
+ *----------------------------------------------------------------------------
+ * Queue a segment for playback
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT JET_QueueSegment (EAS_DATA_HANDLE easHandle, EAS_INT segmentNum, EAS_INT libNum, EAS_INT repeatCount, EAS_INT transpose, EAS_U32 muteFlags, EAS_U8 userID)
+{
+ EAS_FILE_HANDLE fileHandle;
+ EAS_RESULT result;
+ S_JET_SEGMENT *p;
+
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "JET_QueueSegment segNum=%d, queue=%d\n", segmentNum, easHandle->jetHandle->queueSegment); */ }
+
+ /* make sure it's a valid segment */
+ if (segmentNum >= easHandle->jetHandle->numSegments)
+ return EAS_ERROR_PARAMETER_RANGE;
+
+ /* make sure it's a valid DLS */
+ if (libNum >= easHandle->jetHandle->numLibraries)
+ return EAS_ERROR_PARAMETER_RANGE;
+
+ /* check to see if queue is full */
+ p = &easHandle->jetHandle->segQueue[easHandle->jetHandle->queueSegment];
+ if (p->streamHandle != NULL)
+ return EAS_ERROR_QUEUE_IS_FULL;
+
+ /* initialize data */
+ p->userID = userID;
+ p->repeatCount = (EAS_I16) repeatCount;
+ p->transpose = (EAS_I8) transpose;
+ p->libNum = (EAS_I8) libNum;
+ p->muteFlags = muteFlags;
+ p->state = JET_STATE_CLOSED;
+
+ /* open the file */
+ result = EAS_OpenJETStream(easHandle, easHandle->jetHandle->jetFileHandle, easHandle->jetHandle->segmentOffsets[segmentNum], &p->streamHandle);
+ if (result != EAS_SUCCESS)
+ return result;
+ p->state = JET_STATE_OPEN;
+
+ /* if less than SEG_QUEUE_DEPTH segments queued up, prepare file for playback */
+ if (++easHandle->jetHandle->numQueuedSegments < SEG_QUEUE_DEPTH)
+ {
+ result = JET_PrepareSegment(easHandle, easHandle->jetHandle->queueSegment);
+ if (result != EAS_SUCCESS)
+ return result;
+ }
+
+ /* create duplicate file handle */
+ result = EAS_HWDupHandle(easHandle->hwInstData, easHandle->jetHandle->jetFileHandle, &fileHandle);
+ if (result != EAS_SUCCESS)
+ return result;
+
+ easHandle->jetHandle->jetFileHandle = fileHandle;
+ easHandle->jetHandle->queueSegment = (EAS_U8) JET_NextSegment(easHandle->jetHandle->queueSegment);
+ return result;
+}
+
+/*----------------------------------------------------------------------------
+ * JET_Play()
+ *----------------------------------------------------------------------------
+ * Starts playback of the file
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT JET_Play (EAS_DATA_HANDLE easHandle)
+{
+ EAS_RESULT result;
+ EAS_INT index;
+ EAS_INT count = 0;
+
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "JET_Play\n"); */ }
+
+ /* sanity check */
+ if (easHandle->jetHandle->flags & JET_FLAGS_PLAYING)
+ return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
+
+ /* resume all paused streams */
+ for (index = 0; index < SEG_QUEUE_DEPTH; index++)
+ {
+ if (((index == easHandle->jetHandle->playSegment) && (easHandle->jetHandle->segQueue[index].state == JET_STATE_READY)) ||
+ (easHandle->jetHandle->segQueue[index].state == JET_STATE_PAUSED))
+ {
+ result = JET_StartPlayback(easHandle, index);
+ if (result != EAS_SUCCESS)
+ return result;
+ count++;
+ }
+ }
+
+ /* if no streams are playing, return error */
+ if (!count)
+ return EAS_ERROR_QUEUE_IS_EMPTY;
+
+ easHandle->jetHandle->flags |= JET_FLAGS_PLAYING;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * JET_Pause()
+ *----------------------------------------------------------------------------
+ * Pauses playback of the file
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT JET_Pause (EAS_DATA_HANDLE easHandle)
+{
+ EAS_RESULT result;
+ EAS_INT index;
+ EAS_INT count = 0;
+
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "JET_Pause\n"); */ }
+
+ /* sanity check */
+ if ((easHandle->jetHandle->flags & JET_FLAGS_PLAYING) == 0)
+ return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
+
+ /* pause all playing streams */
+ for (index = 0; index < SEG_QUEUE_DEPTH; index++)
+ {
+ if (easHandle->jetHandle->segQueue[index].state == JET_STATE_PLAYING)
+ {
+ result = EAS_Pause(easHandle, easHandle->jetHandle->segQueue[easHandle->jetHandle->playSegment].streamHandle);
+ if (result != EAS_SUCCESS)
+ return result;
+ easHandle->jetHandle->segQueue[easHandle->jetHandle->playSegment].state = JET_STATE_PAUSED;
+ count++;
+ }
+ }
+
+ /* if no streams are paused, return error */
+ if (!count)
+ return EAS_ERROR_QUEUE_IS_EMPTY;
+
+ easHandle->jetHandle->flags &= ~JET_FLAGS_PLAYING;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * JET_SetMuteFlags()
+ *----------------------------------------------------------------------------
+ * Change the state of the mute flags
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT JET_SetMuteFlags (EAS_DATA_HANDLE easHandle, EAS_U32 muteFlags, EAS_BOOL sync)
+{
+ S_JET_SEGMENT *pSeg;
+
+ /* get pointer to current segment */
+ pSeg = &easHandle->jetHandle->segQueue[easHandle->jetHandle->playSegment];
+
+ /* unsynchronized mute, set flags and return */
+ if (!sync)
+ {
+ if (pSeg->streamHandle == NULL)
+ return EAS_ERROR_QUEUE_IS_EMPTY;
+ pSeg->muteFlags = muteFlags;
+ return EAS_IntSetStrmParam(easHandle, pSeg->streamHandle, PARSER_DATA_MUTE_FLAGS, (EAS_I32) muteFlags);
+ }
+
+
+ /* check for valid stream state */
+ if (pSeg->state == JET_STATE_CLOSED)
+ return EAS_ERROR_QUEUE_IS_EMPTY;
+
+ /* save mute flags */
+ pSeg->muteFlags = muteFlags;
+
+ /* if repeating segment, set mute update flag */
+ if (sync)
+ pSeg->flags |= JET_SEG_FLAG_MUTE_UPDATE;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * JET_SetMuteFlag()
+ *----------------------------------------------------------------------------
+ * Change the state of a single mute flag
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT JET_SetMuteFlag (EAS_DATA_HANDLE easHandle, EAS_INT trackNum, EAS_BOOL muteFlag, EAS_BOOL sync)
+{
+ S_JET_SEGMENT *pSeg;
+ EAS_U32 trackMuteFlag;
+
+
+ /* setup flag */
+ if ((trackNum < 0) || (trackNum > 31))
+ return EAS_ERROR_PARAMETER_RANGE;
+ trackMuteFlag = (1 << trackNum);
+
+ /* get pointer to current segment */
+ pSeg = &easHandle->jetHandle->segQueue[easHandle->jetHandle->playSegment];
+
+ /* unsynchronized mute, set flags and return */
+ if (!sync)
+ {
+ if (pSeg->streamHandle == NULL)
+ return EAS_ERROR_QUEUE_IS_EMPTY;
+ if (muteFlag)
+ pSeg->muteFlags |= trackMuteFlag;
+ else
+ pSeg->muteFlags &= ~trackMuteFlag;
+ return EAS_IntSetStrmParam(easHandle, pSeg->streamHandle, PARSER_DATA_MUTE_FLAGS, (EAS_I32) pSeg->muteFlags);
+ }
+
+
+ /* check for valid stream state */
+ if (pSeg->state == JET_STATE_CLOSED)
+ return EAS_ERROR_QUEUE_IS_EMPTY;
+
+ /* save mute flags and set mute update flag */
+ if (muteFlag)
+ pSeg->muteFlags |= trackMuteFlag;
+ else
+ pSeg->muteFlags &= ~trackMuteFlag;
+ pSeg->flags |= JET_SEG_FLAG_MUTE_UPDATE;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * JET_TriggerClip()
+ *----------------------------------------------------------------------------
+ * Unmute a track and then mute it when it is complete. If a clip
+ * is already playing, change mute event to a trigger event. The
+ * JET_Event function will not mute the clip, but will allow it
+ * to continue playing through the next clip.
+ *
+ * NOTE: We use bit 7 to indicate an entry in the queue. For a
+ * small queue, it is cheaper in both memory and CPU cycles to
+ * scan the entire queue for non-zero events than keep enqueue
+ * and dequeue indices.
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT JET_TriggerClip (EAS_DATA_HANDLE easHandle, EAS_INT clipID)
+{
+ EAS_INT i;
+ EAS_INT index = -1;
+
+ /* check for valid clipID */
+ if ((clipID < 0) || (clipID > 63))
+ return EAS_ERROR_PARAMETER_RANGE;
+
+ /* set active flag */
+ clipID |= JET_CLIP_ACTIVE_FLAG;
+
+ /* Reverse the search so that we get the first empty element */
+ for (i = JET_MUTE_QUEUE_SIZE-1; i >= 0 ; i--)
+ {
+ if (easHandle->jetHandle->muteQueue[i] == clipID)
+ {
+ index = i;
+ break;
+ }
+ if (easHandle->jetHandle->muteQueue[i] == 0)
+ index = i;
+ }
+ if (index < 0)
+ return EAS_ERROR_QUEUE_IS_FULL;
+
+ easHandle->jetHandle->muteQueue[index] = (EAS_U8) clipID | JET_CLIP_TRIGGER_FLAG;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * JET_Process()
+ *----------------------------------------------------------------------------
+ * Called during EAS_Render to process stream states
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT JET_Process (EAS_DATA_HANDLE easHandle)
+{
+ S_JET_SEGMENT *pSeg;
+ EAS_STATE state;
+ EAS_INT index;
+ EAS_INT playIndex;
+ EAS_RESULT result = EAS_SUCCESS;
+ EAS_BOOL endOfLoop = EAS_FALSE;
+ EAS_BOOL startNextSegment = EAS_FALSE;
+ EAS_BOOL prepareNextSegment = EAS_FALSE;
+ EAS_U32 jetEvent;
+
+ /* process event queue */
+ while (JET_ReadQueue(easHandle->jetHandle->jetEventQueue,
+ &easHandle->jetHandle->jetEventQueueRead,
+ easHandle->jetHandle->jetEventQueueWrite,
+ JET_EVENT_QUEUE_SIZE, &jetEvent))
+ {
+ S_JET_EVENT event;
+#ifdef DEBUG_JET
+ JET_DumpEvent("JET_Process", jetEvent);
+#endif
+ JET_ParseEvent(jetEvent, &event);
+
+ /* check for end of loop */
+ if ((event.controller == JET_EVENT_MARKER) &&
+ (event.value == JET_MARKER_LOOP_END) &&
+ (easHandle->jetHandle->segQueue[easHandle->jetHandle->playSegment].streamHandle != NULL))
+ endOfLoop = EAS_TRUE;
+ }
+
+ /* check state of all streams */
+ index = playIndex = easHandle->jetHandle->playSegment;
+ for (;;)
+ {
+ pSeg = &easHandle->jetHandle->segQueue[index];
+ if (pSeg->state != JET_STATE_CLOSED)
+ {
+
+ /* get playback state */
+ result = EAS_State(easHandle, pSeg->streamHandle, &state);
+ if (result != EAS_SUCCESS)
+ return result;
+
+ /* process state */
+ switch (pSeg->state)
+ {
+ /* take action if this segment is stopping */
+ case JET_STATE_PLAYING:
+ if (endOfLoop || (state == EAS_STATE_STOPPING) || (state == EAS_STATE_STOPPED))
+ {
+ /* handle repeats */
+ if (pSeg->repeatCount != 0)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "JET_Render repeating segment %d\n", index); */ }
+ result = EAS_Locate(easHandle, pSeg->streamHandle, 0, EAS_FALSE);
+ if (result != EAS_SUCCESS)
+ return result;
+ if (pSeg->repeatCount > 0)
+ pSeg->repeatCount--;
+
+ /* update mute flags if necessary */
+ if (pSeg->flags & JET_SEG_FLAG_MUTE_UPDATE)
+ {
+ result = EAS_IntSetStrmParam(easHandle, pSeg->streamHandle, PARSER_DATA_MUTE_FLAGS, (EAS_I32) pSeg->muteFlags);
+ if (result != EAS_SUCCESS)
+ return result;
+ pSeg->flags &= ~JET_SEG_FLAG_MUTE_UPDATE;
+ }
+
+ }
+ /* no repeat, start next segment */
+ else
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "JET_Render stopping queue %d\n", index); */ }
+ startNextSegment = EAS_TRUE;
+ pSeg->state = JET_STATE_STOPPING;
+ easHandle->jetHandle->playSegment = (EAS_U8) JET_NextSegment(index);
+ }
+ }
+ break;
+
+ /* if playback has stopped, close the segment */
+ case JET_STATE_STOPPING:
+ if (state == EAS_STATE_STOPPED)
+ {
+ result = JET_CloseSegment(easHandle, index);
+ if (result != EAS_SUCCESS)
+ return result;
+ }
+ break;
+
+ case JET_STATE_READY:
+ if (startNextSegment)
+ {
+ result = JET_StartPlayback(easHandle, index);
+ if (result != EAS_SUCCESS)
+ return result;
+ startNextSegment = EAS_FALSE;
+ prepareNextSegment = EAS_TRUE;
+ }
+ break;
+
+ case JET_STATE_OPEN:
+ if (prepareNextSegment)
+ {
+ result = JET_PrepareSegment(easHandle, index);
+ if (result != EAS_SUCCESS)
+ return result;
+ prepareNextSegment = EAS_FALSE;
+ }
+ break;
+
+ case JET_STATE_PAUSED:
+ break;
+
+ default:
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "JET_Render: Unexpected segment state %d\n", pSeg->state); */ }
+ break;
+ }
+ }
+
+ /* increment index */
+ index = JET_NextSegment(index);
+ if (index == playIndex)
+ break;
+ }
+
+ /* if out of segments, clear playing flag */
+ if (easHandle->jetHandle->numQueuedSegments == 0)
+ easHandle->jetHandle->flags &= ~JET_FLAGS_PLAYING;
+
+ return result;
+}
+
+/*----------------------------------------------------------------------------
+ * JET_Event()
+ *----------------------------------------------------------------------------
+ * Called from MIDI parser when data of interest is received
+ *----------------------------------------------------------------------------
+*/
+void JET_Event (EAS_DATA_HANDLE easHandle, EAS_U32 segTrack, EAS_U8 channel, EAS_U8 controller, EAS_U8 value)
+{
+ EAS_U32 event;
+
+ if (easHandle->jetHandle == NULL)
+ return;
+
+ /* handle triggers */
+ if (controller == JET_EVENT_TRIGGER_CLIP)
+ {
+ S_JET_SEGMENT *pSeg;
+ EAS_INT i;
+ EAS_U32 muteFlag;
+
+ for (i = 0; i < JET_MUTE_QUEUE_SIZE; i++)
+ {
+ /* search for event in queue */
+ if ((easHandle->jetHandle->muteQueue[i] & JET_CLIP_ID_MASK) == (value & JET_CLIP_ID_MASK))
+ {
+ /* get segment pointer and mute flag */
+ pSeg = &easHandle->jetHandle->segQueue[segTrack >> JET_EVENT_SEG_SHIFT];
+ muteFlag = 1 << ((segTrack & JET_EVENT_TRACK_MASK) >> JET_EVENT_TRACK_SHIFT);
+
+ /* un-mute the track */
+ if ((easHandle->jetHandle->muteQueue[i] & JET_CLIP_TRIGGER_FLAG) && ((value & 0x40) > 0))
+ {
+ pSeg->muteFlags &= ~muteFlag;
+ easHandle->jetHandle->muteQueue[i] &= ~JET_CLIP_TRIGGER_FLAG;
+ }
+
+ /* mute the track */
+ else
+ {
+ EAS_U32 beforeMute ;
+ beforeMute = pSeg->muteFlags ;
+ pSeg->muteFlags |= muteFlag;
+ if (beforeMute != pSeg->muteFlags)
+ easHandle->jetHandle->muteQueue[i] = 0;
+ }
+ EAS_IntSetStrmParam(easHandle, pSeg->streamHandle, PARSER_DATA_MUTE_FLAGS, (EAS_I32) pSeg->muteFlags);
+ return;
+ }
+ }
+ return;
+ }
+
+ /* generic event stuff */
+ event = (channel << JET_EVENT_CHAN_SHIFT) | (controller << JET_EVENT_CTRL_SHIFT) | value;
+
+ /* write to app queue, translate queue index to segment number */
+ if ((controller >= easHandle->jetHandle->config.appEventRangeLow) && (controller <= easHandle->jetHandle->config.appEventRangeHigh))
+ {
+
+ event |= easHandle->jetHandle->segQueue[(segTrack & JET_EVENT_SEG_MASK) >> JET_EVENT_SEG_SHIFT].userID << JET_EVENT_SEG_SHIFT;
+#ifdef DEBUG_JET
+ JET_DumpEvent("JET_Event[app]", event);
+#endif
+ JET_WriteQueue(easHandle->jetHandle->appEventQueue,
+ &easHandle->jetHandle->appEventQueueWrite,
+ easHandle->jetHandle->appEventQueueRead,
+ APP_EVENT_QUEUE_SIZE,
+ event);
+ }
+
+ /* write to JET queue */
+ else if ((controller >= JET_EVENT_LOW) && (controller <= JET_EVENT_HIGH))
+ {
+ event |= segTrack;
+#ifdef DEBUG_JET
+ JET_DumpEvent("JET_Event[jet]", event);
+#endif
+ JET_WriteQueue(easHandle->jetHandle->jetEventQueue,
+ &easHandle->jetHandle->jetEventQueueWrite,
+ easHandle->jetHandle->jetEventQueueRead,
+ JET_EVENT_QUEUE_SIZE,
+ event);
+ }
+}
+
+/*----------------------------------------------------------------------------
+ * JET_Clear_Queue()
+ *----------------------------------------------------------------------------
+ * Clears the queue and stops play without a complete shutdown
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT JET_Clear_Queue(EAS_DATA_HANDLE easHandle)
+{
+ EAS_INT index;
+ EAS_RESULT result = EAS_SUCCESS;
+
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "JET_Clear_Queue\n"); */ }
+
+ /* pause all playing streams */
+ for (index = 0; index < SEG_QUEUE_DEPTH; index++)
+ {
+ if (easHandle->jetHandle->segQueue[index].state == JET_STATE_PLAYING)
+ {
+ result = EAS_Pause(easHandle, easHandle->jetHandle->segQueue[index].streamHandle);
+ if (result != EAS_SUCCESS)
+ return result;
+
+ easHandle->jetHandle->segQueue[index].state = JET_STATE_PAUSED;
+ }
+ }
+
+ /* close all streams */
+ for (index = 0; index < SEG_QUEUE_DEPTH; index++)
+ {
+ if (easHandle->jetHandle->segQueue[index].streamHandle != NULL)
+ {
+ result = JET_CloseSegment(easHandle, index);
+ if (result != EAS_SUCCESS)
+ return result;
+ }
+ }
+
+ /* clear all clips */
+ for (index = 0; index < JET_MUTE_QUEUE_SIZE ; index++)
+ {
+ easHandle->jetHandle->muteQueue[index] = 0;
+ }
+
+ easHandle->jetHandle->flags &= ~JET_FLAGS_PLAYING;
+ easHandle->jetHandle->playSegment = easHandle->jetHandle->queueSegment = 0;
+ return result;
+}
+
diff --git a/arm-wt-22k/lib_src/jet_data.h b/arm-wt-22k/lib_src/jet_data.h
index 27b9cb1..6bd72e0 100644
--- a/arm-wt-22k/lib_src/jet_data.h
+++ b/arm-wt-22k/lib_src/jet_data.h
@@ -1,12 +1,12 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * jet_data.h
- *
- * Contents and purpose:
- * Internal data structures and interfaces for JET
- *
- * Copyright (c) 2006 Sonic Network Inc.
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * jet_data.h
+ *
+ * Contents and purpose:
+ * Internal data structures and interfaces for JET
+ *
+ * Copyright (c) 2006 Sonic Network Inc.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,165 +19,165 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 554 $
- * $Date: 2007-02-02 11:06:10 -0800 (Fri, 02 Feb 2007) $
- *----------------------------------------------------------------------------
-*/
-
-#ifndef _JET_DATA_H
-#define _JET_DATA_H
-
-#include "eas.h"
-#include "jet.h"
-
-/* maximum number of segments allowed in a JET file */
-#ifndef JET_MAX_SEGMENTS
-#define JET_MAX_SEGMENTS 32
-#endif
-
-/* maximum number of DLS collections allowed in a JET file */
-#ifndef JET_MAX_DLS_COLLECTIONS
-#define JET_MAX_DLS_COLLECTIONS 4
-#endif
-
-/* maximum number of JET events in internal queue */
-#ifndef JET_EVENT_QUEUE_SIZE
-#define JET_EVENT_QUEUE_SIZE 32
-#endif
-
-/* maximum number of JET events in application queue */
-#ifndef APP_EVENT_QUEUE_SIZE
-#define APP_EVENT_QUEUE_SIZE 32
-#endif
-
-/* maximum number of active mute events */
-#ifndef JET_MUTE_QUEUE_SIZE
-#define JET_MUTE_QUEUE_SIZE 8
-#endif
-
-/*----------------------------------------------------------------------------
- * JET event definitions
- *----------------------------------------------------------------------------
-*/
-#define JET_EVENT_APP_LOW 80
-#define JET_EVENT_APP_HIGH 83
-#define JET_EVENT_LOW 102
-#define JET_EVENT_HIGH 119
-#define JET_EVENT_MARKER 102
-#define JET_EVENT_TRIGGER_CLIP 103
-
-#define JET_MARKER_LOOP_END 0
-
-#define JET_CLIP_ACTIVE_FLAG 0x80
-#define JET_CLIP_TRIGGER_FLAG 0x40
-#define JET_CLIP_ID_MASK 0x3f
-
-/*----------------------------------------------------------------------------
- * JET file definitions
- *----------------------------------------------------------------------------
-*/
-#define JET_TAG(a,b,c,d) (\
- ( ((EAS_U32)(a) & 0xFF) << 24 ) \
- + ( ((EAS_U32)(b) & 0xFF) << 16 ) \
- + ( ((EAS_U32)(c) & 0xFF) << 8 ) \
- + ( ((EAS_U32)(d) & 0xFF)))
-
-#define JET_VERSION 0x01000000
-#define JET_HEADER_TAG JET_TAG('J','E','T',' ')
-#define JET_INFO_CHUNK JET_TAG('J','I','N','F')
-#define JET_SMF_CHUNK JET_TAG('J','S','M','F')
-#define JET_DLS_CHUNK JET_TAG('J','D','L','S')
-#define INFO_JET_COPYRIGHT JET_TAG('J','C','O','P')
-#define JET_APP_DATA_CHUNK JET_TAG('J','A','P','P')
-
-#define INFO_NUM_SMF_CHUNKS JET_TAG('S','M','F','#')
-#define INFO_NUM_DLS_CHUNKS JET_TAG('D','L','S','#')
-#define INFO_JET_VERSION JET_TAG('J','V','E','R')
-
-/*----------------------------------------------------------------------------
- * S_JET_SEGMENT
- *
- * JET segment data
- *----------------------------------------------------------------------------
-*/
-typedef struct s_jet_segment_tag
-{
- EAS_HANDLE streamHandle;
- EAS_U32 muteFlags;
- EAS_I16 repeatCount;
- EAS_U8 userID;
- EAS_I8 transpose;
- EAS_I8 libNum;
- EAS_U8 state;
- EAS_U8 flags;
-} S_JET_SEGMENT;
-
-/* S_JET_SEGMENT.state */
-typedef enum
-{
- JET_STATE_CLOSED,
- JET_STATE_OPEN,
- JET_STATE_READY,
- JET_STATE_PLAYING,
- JET_STATE_PAUSED,
- JET_STATE_STOPPING
-} E_JET_SEGMENT_STATE;
-
-/* S_JEG_SEGMENT.flags */
-#define JET_SEG_FLAG_MUTE_UPDATE 0x01
-
-/*----------------------------------------------------------------------------
- * S_JET_DATA
- *
- * Main JET data structure
- *----------------------------------------------------------------------------
-*/
-#define SEG_QUEUE_DEPTH 3
-typedef struct s_jet_data_tag
-{
- EAS_FILE_HANDLE jetFileHandle;
- S_JET_SEGMENT segQueue[SEG_QUEUE_DEPTH];
- EAS_I32 segmentOffsets[JET_MAX_SEGMENTS];
- EAS_I32 appDataOffset;
- EAS_I32 appDataSize;
- EAS_DLSLIB_HANDLE libHandles[JET_MAX_DLS_COLLECTIONS];
- EAS_U32 jetEventQueue[JET_EVENT_QUEUE_SIZE];
- EAS_U32 appEventQueue[APP_EVENT_QUEUE_SIZE];
- S_JET_CONFIG config;
- EAS_U32 segmentTime;
- EAS_U8 muteQueue[JET_MUTE_QUEUE_SIZE];
- EAS_U8 numSegments;
- EAS_U8 numLibraries;
- EAS_U8 flags;
- EAS_U8 playSegment;
- EAS_U8 queueSegment;
- EAS_U8 numQueuedSegments;
- EAS_U8 jetEventQueueRead;
- EAS_U8 jetEventQueueWrite;
- EAS_U8 appEventQueueRead;
- EAS_U8 appEventQueueWrite;
-} S_JET_DATA;
-
-/* flags for S_JET_DATA.flags */
-#define JET_FLAGS_PLAYING 1
-
-#define JET_EVENT_VAL_MASK 0x0000007f /* mask for value */
-#define JET_EVENT_CTRL_MASK 0x00003f80 /* mask for controller */
-#define JET_EVENT_CHAN_MASK 0x0003c000 /* mask for channel */
-#define JET_EVENT_TRACK_MASK 0x00fc0000 /* mask for track number */
-#define JET_EVENT_SEG_MASK 0xff000000 /* mask for segment ID */
-#define JET_EVENT_CTRL_SHIFT 7 /* shift for controller number */
-#define JET_EVENT_CHAN_SHIFT 14 /* shift to for MIDI channel */
-#define JET_EVENT_TRACK_SHIFT 18 /* shift to get track ID to bit 0 */
-#define JET_EVENT_SEG_SHIFT 24 /* shift to get segment ID to bit 0 */
-
-/* prototype for callback function */
-extern void JET_Event (EAS_DATA_HANDLE easHandle, EAS_U32 segTrack, EAS_U8 channel, EAS_U8 controller, EAS_U8 value);
-
-/* prototype for JET render function */
-extern EAS_PUBLIC EAS_RESULT JET_Process (EAS_DATA_HANDLE easHandle);
-
-#endif
-
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 554 $
+ * $Date: 2007-02-02 11:06:10 -0800 (Fri, 02 Feb 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+#ifndef _JET_DATA_H
+#define _JET_DATA_H
+
+#include "eas.h"
+#include "jet.h"
+
+/* maximum number of segments allowed in a JET file */
+#ifndef JET_MAX_SEGMENTS
+#define JET_MAX_SEGMENTS 32
+#endif
+
+/* maximum number of DLS collections allowed in a JET file */
+#ifndef JET_MAX_DLS_COLLECTIONS
+#define JET_MAX_DLS_COLLECTIONS 4
+#endif
+
+/* maximum number of JET events in internal queue */
+#ifndef JET_EVENT_QUEUE_SIZE
+#define JET_EVENT_QUEUE_SIZE 32
+#endif
+
+/* maximum number of JET events in application queue */
+#ifndef APP_EVENT_QUEUE_SIZE
+#define APP_EVENT_QUEUE_SIZE 32
+#endif
+
+/* maximum number of active mute events */
+#ifndef JET_MUTE_QUEUE_SIZE
+#define JET_MUTE_QUEUE_SIZE 8
+#endif
+
+/*----------------------------------------------------------------------------
+ * JET event definitions
+ *----------------------------------------------------------------------------
+*/
+#define JET_EVENT_APP_LOW 80
+#define JET_EVENT_APP_HIGH 83
+#define JET_EVENT_LOW 102
+#define JET_EVENT_HIGH 119
+#define JET_EVENT_MARKER 102
+#define JET_EVENT_TRIGGER_CLIP 103
+
+#define JET_MARKER_LOOP_END 0
+
+#define JET_CLIP_ACTIVE_FLAG 0x80
+#define JET_CLIP_TRIGGER_FLAG 0x40
+#define JET_CLIP_ID_MASK 0x3f
+
+/*----------------------------------------------------------------------------
+ * JET file definitions
+ *----------------------------------------------------------------------------
+*/
+#define JET_TAG(a,b,c,d) (\
+ ( ((EAS_U32)(a) & 0xFF) << 24 ) \
+ + ( ((EAS_U32)(b) & 0xFF) << 16 ) \
+ + ( ((EAS_U32)(c) & 0xFF) << 8 ) \
+ + ( ((EAS_U32)(d) & 0xFF)))
+
+#define JET_VERSION 0x01000000
+#define JET_HEADER_TAG JET_TAG('J','E','T',' ')
+#define JET_INFO_CHUNK JET_TAG('J','I','N','F')
+#define JET_SMF_CHUNK JET_TAG('J','S','M','F')
+#define JET_DLS_CHUNK JET_TAG('J','D','L','S')
+#define INFO_JET_COPYRIGHT JET_TAG('J','C','O','P')
+#define JET_APP_DATA_CHUNK JET_TAG('J','A','P','P')
+
+#define INFO_NUM_SMF_CHUNKS JET_TAG('S','M','F','#')
+#define INFO_NUM_DLS_CHUNKS JET_TAG('D','L','S','#')
+#define INFO_JET_VERSION JET_TAG('J','V','E','R')
+
+/*----------------------------------------------------------------------------
+ * S_JET_SEGMENT
+ *
+ * JET segment data
+ *----------------------------------------------------------------------------
+*/
+typedef struct s_jet_segment_tag
+{
+ EAS_HANDLE streamHandle;
+ EAS_U32 muteFlags;
+ EAS_I16 repeatCount;
+ EAS_U8 userID;
+ EAS_I8 transpose;
+ EAS_I8 libNum;
+ EAS_U8 state;
+ EAS_U8 flags;
+} S_JET_SEGMENT;
+
+/* S_JET_SEGMENT.state */
+typedef enum
+{
+ JET_STATE_CLOSED,
+ JET_STATE_OPEN,
+ JET_STATE_READY,
+ JET_STATE_PLAYING,
+ JET_STATE_PAUSED,
+ JET_STATE_STOPPING
+} E_JET_SEGMENT_STATE;
+
+/* S_JEG_SEGMENT.flags */
+#define JET_SEG_FLAG_MUTE_UPDATE 0x01
+
+/*----------------------------------------------------------------------------
+ * S_JET_DATA
+ *
+ * Main JET data structure
+ *----------------------------------------------------------------------------
+*/
+#define SEG_QUEUE_DEPTH 3
+typedef struct s_jet_data_tag
+{
+ EAS_FILE_HANDLE jetFileHandle;
+ S_JET_SEGMENT segQueue[SEG_QUEUE_DEPTH];
+ EAS_I32 segmentOffsets[JET_MAX_SEGMENTS];
+ EAS_I32 appDataOffset;
+ EAS_I32 appDataSize;
+ EAS_DLSLIB_HANDLE libHandles[JET_MAX_DLS_COLLECTIONS];
+ EAS_U32 jetEventQueue[JET_EVENT_QUEUE_SIZE];
+ EAS_U32 appEventQueue[APP_EVENT_QUEUE_SIZE];
+ S_JET_CONFIG config;
+ EAS_U32 segmentTime;
+ EAS_U8 muteQueue[JET_MUTE_QUEUE_SIZE];
+ EAS_U8 numSegments;
+ EAS_U8 numLibraries;
+ EAS_U8 flags;
+ EAS_U8 playSegment;
+ EAS_U8 queueSegment;
+ EAS_U8 numQueuedSegments;
+ EAS_U8 jetEventQueueRead;
+ EAS_U8 jetEventQueueWrite;
+ EAS_U8 appEventQueueRead;
+ EAS_U8 appEventQueueWrite;
+} S_JET_DATA;
+
+/* flags for S_JET_DATA.flags */
+#define JET_FLAGS_PLAYING 1
+
+#define JET_EVENT_VAL_MASK 0x0000007f /* mask for value */
+#define JET_EVENT_CTRL_MASK 0x00003f80 /* mask for controller */
+#define JET_EVENT_CHAN_MASK 0x0003c000 /* mask for channel */
+#define JET_EVENT_TRACK_MASK 0x00fc0000 /* mask for track number */
+#define JET_EVENT_SEG_MASK 0xff000000 /* mask for segment ID */
+#define JET_EVENT_CTRL_SHIFT 7 /* shift for controller number */
+#define JET_EVENT_CHAN_SHIFT 14 /* shift to for MIDI channel */
+#define JET_EVENT_TRACK_SHIFT 18 /* shift to get track ID to bit 0 */
+#define JET_EVENT_SEG_SHIFT 24 /* shift to get segment ID to bit 0 */
+
+/* prototype for callback function */
+extern void JET_Event (EAS_DATA_HANDLE easHandle, EAS_U32 segTrack, EAS_U8 channel, EAS_U8 controller, EAS_U8 value);
+
+/* prototype for JET render function */
+extern EAS_PUBLIC EAS_RESULT JET_Process (EAS_DATA_HANDLE easHandle);
+
+#endif
+
diff --git a/arm-wt-22k/lib_src/wt_22khz.c b/arm-wt-22k/lib_src/wt_22khz.c
index 0593dca..6d2c24c 100644
--- a/arm-wt-22k/lib_src/wt_22khz.c
+++ b/arm-wt-22k/lib_src/wt_22khz.c
@@ -2,7 +2,7 @@
*
* Filename: wt_200k_G.c
* Source: wt_200k_G.dls
- * CmdLine: -w wt_200k_G.c -l wt_200k_G.log -ce -cf wt_200k_G.dls -w -l -ce -cf wt_200k_G.dls
+ * CmdLine: -w wt_200k_G.c -l wt_200k_G.log -ce -cf wt_200k_G.dls -w -l -ce -cf wt_200k_G.dls
* Purpose: Wavetable sound libary
*
* Copyright (c) 2009 Sonic Network Inc.
@@ -32,1327 +32,1327 @@
* Articulations
*----------------------------------------------------------------------------
*/
-const S_ARTICULATION eas_articulations[] =
+const S_ARTICULATION eas_articulations[] =
{
- { /* articulation 0 */
- { 32767, 30725, 0, 30725 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 951, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 1 */
- { 32767, 26863, 0, 26863 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 951, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 2 */
- { 32767, 30484, 0, 30668 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 951, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 3 */
- { 32767, 26439, 0, 26439 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 951, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 4 */
- { 32767, 0, 32767, 32715 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 951, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 5 */
- { 32767, 21333, 0, 21333 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 951, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 6 */
- { 32767, 31882, 0, 31938 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 951, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 7 */
- { 32767, 32663, 32767, 32663 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 951, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 8 */
- { 32767, 0, 32767, 0 },
- { 32767, 1902, 0, 0 },
- 0, 0, 951, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 9 */
- { 32767, 32349, 0, 32349 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 951, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 10 */
- { 32767, 0, 32767, 17213 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 951, 0, 0, 0, 0, 0, -1
- },
- { /* articulation 11 */
- { 32767, 31730, 0, 31730 },
- { 32767, 761, 0, 0 },
- 0, 0, 951, 0, 0, 0, 0, 0, -44
- },
- { /* articulation 12 */
- { 32767, 23749, 0, 23749 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 951, 0, 0, 0, 0, 0, 56
- },
- { /* articulation 13 */
- { 32767, 31730, 0, 31730 },
- { 32767, 761, 0, 0 },
- 0, 0, 951, 0, 0, 0, 0, 0, -31
- },
- { /* articulation 14 */
- { 9511, 21333, 0, 21333 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 951, 0, 0, 0, 0, 0, 56
- },
- { /* articulation 15 */
- { 32767, 31617, 0, 31617 },
- { 32767, 761, 0, 0 },
- 0, 0, 951, 0, 0, 0, 0, 0, -6
- },
- { /* articulation 16 */
- { 32767, 32123, 0, 32194 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 951, 0, 0, 0, 0, 0, 56
- },
- { /* articulation 17 */
- { 32767, 31550, 0, 31550 },
- { 32767, 761, 0, 0 },
- 0, 0, 951, 0, 0, 0, 0, 0, 6
- },
- { /* articulation 18 */
- { 32767, 31391, 0, 31391 },
- { 32767, 951, 0, 0 },
- 0, 0, 951, 0, 0, 0, 0, 0, 31
- },
- { /* articulation 19 */
- { 32767, 31964, 0, 31964 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 951, 0, 0, 0, 0, 0, 25
- },
- { /* articulation 20 */
- { 32767, 31056, 0, 31056 },
- { 32767, 951, 0, 0 },
- 0, 0, 951, 0, 0, 0, 0, 0, 63
- },
- { /* articulation 21 */
- { 32767, 32289, 0, 32271 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 951, 0, 0, 0, 0, 0, -37
- },
- { /* articulation 22 */
- { 19021, 31882, 0, 31911 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 951, 0, 0, 0, 0, 0, -37
- },
- { /* articulation 23 */
- { 32767, 31988, 0, 32032 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 951, 0, 0, 0, 0, 0, -37
- },
- { /* articulation 24 */
- { 32767, 0, 32767, 32663 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 951, 0, 0, 0, 0, 0, 12
- },
- { /* articulation 25 */
- { 32767, 31352, 0, 31352 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 951, 0, 0, 0, 0, 0, -25
- },
- { /* articulation 26 */
- { 32767, 0, 32767, 32663 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 951, 0, 0, 0, 0, 0, 25
- },
- { /* articulation 27 */
- { 32767, 31817, 0, 31781 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 951, 0, 0, 0, 0, 0, -25
- },
- { /* articulation 28 */
- { 32767, 30725, 0, 30725 },
- { 32767, 95, 0, 0 },
- 0, 0, 951, 240, 0, 0, 0, 0, -56
- },
- { /* articulation 29 */
- { 32767, 32230, 0, 32218 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 951, 0, 0, 0, 0, 0, -37
- },
- { /* articulation 30 */
- { 32767, 26439, 0, 26439 },
- { 32767, 3804, 0, 0 },
- 0, 0, 951, 0, 0, 0, 0, 0, 50
- },
- { /* articulation 31 */
- { 32767, 23749, 0, 23749 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 951, 0, 0, 0, 0, 0, -50
- },
- { /* articulation 32 */
- { 32767, 29434, 0, 29434 },
- { 32767, 3804, 0, 0 },
- 0, 0, 951, 0, 0, 0, 0, 0, -50
- },
- { /* articulation 33 */
- { 32767, 30240, 0, 30234 },
- { 32767, 3804, 0, 0 },
- 0, 0, 951, 0, 0, 0, 0, 0, -44
- },
- { /* articulation 34 */
- { 32767, 32558, 0, 32558 },
- { 32767, 254, 0, 0 },
- 0, 0, 951, 0, 0, 0, 0, 0, 25
- },
- { /* articulation 35 */
- { 32767, 0, 32767, 32663 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 951, 0, 0, 0, 0, 0, -63
- },
- { /* articulation 36 */
- { 3804, 23749, 0, 23749 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 951, 0, 0, 0, 0, 0, -63
- },
- { /* articulation 37 */
- { 32767, 23749, 0, 23749 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 951, 0, 0, 0, 0, 0, -59
- },
- { /* articulation 38 */
- { 32767, 30725, 0, 30725 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 951, 0, 0, 0, 0, 0, 50
- },
- { /* articulation 39 */
- { 32767, 28809, 0, 28809 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 951, 0, 0, 0, 0, 0, 44
- },
- { /* articulation 40 */
- { 1902, 30725, 0, 30725 },
- { 32767, 380, 0, 0 },
- 0, 0, 951, -100, 0, 0, 0, 0, 44
- },
- { /* articulation 41 */
- { 32767, 9042, 0, 9042 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 951, 0, 0, 0, 0, 0, 25
- },
- { /* articulation 42 */
- { 32767, 29889, 0, 29889 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 951, 0, 0, 0, 0, 0, 63
- },
- { /* articulation 43 */
- { 32767, 30240, 0, 30234 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 951, 0, 0, 0, 0, 0, 63
- },
- { /* articulation 44 */
- { 19021, 19970, 0, 19970 },
- { 951, 32767, 32767, 0 },
- 0, 0, 951, 100, 0, 0, 0, 0, -25
- },
- { /* articulation 45 */
- { 3804, 17213, 0, 17213 },
- { 951, 32767, 32767, 0 },
- 0, 0, 951, 500, 0, 0, 0, 0, -25
- },
- { /* articulation 46 */
- { 32767, 17213, 0, 17213 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 951, 0, 0, 0, 0, 0, -56
- },
- { /* articulation 47 */
- { 32767, 30725, 0, 30725 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 951, 0, 0, 0, 0, 0, -56
- },
- { /* articulation 48 */
- { 32767, 0, 32767, 0 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 951, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 49 */
- { 32767, 31180, 0, 31180 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 951, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 50 */
- { 19021, 31964, 0, 32071 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 951, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 51 */
- { 32767, 29669, 0, 29669 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 951, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 52 */
- { 32767, 31742, 0, 31352 },
- { 32767, 294, 0, 0 },
- 0, 0, 951, 0, 10000, 7121, 0, 0, 0
- },
- { /* articulation 53 */
- { 32767, 0, 32767, 31391 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 1555, 0, -2300, 11920, 0, 0, 0
- },
- { /* articulation 54 */
- { 1174, 0, 32767, 31988 },
- { 32767, 127, 0, 0 },
- 0, 0, 1555, 0, 2000, 10721, 0, 8, 15
- },
- { /* articulation 55 */
- { 1174, 0, 32767, 31988 },
- { 951, 127, 0, 0 },
- 0, 0, 1555, 0, 2000, 9023, 0, 5, 15
- },
- { /* articulation 56 */
- { 7608, 0, 32767, 30237 },
- { 32767, 69, 5898, 0 },
- 0, 0, 1555, 0, 6000, 9080, 0, 0, -2
- },
- { /* articulation 57 */
- { 32767, 0, 32767, 29337 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 1555, 0, 0, 0, 0, 0, 1
- },
- { /* articulation 58 */
- { 5141, 0, 32767, 30194 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 1555, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 59 */
- { 32767, 32558, 0, 26439 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 951, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 60 */
- { 32767, 32349, 0, 26439 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 951, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 61 */
- { 32767, 32072, 0, 32072 },
- { 32767, 95, 0, 0 },
- 0, 34, 989, 0, 2400, 9521, 0, 0, 0
- },
- { /* articulation 62 */
- { 32767, 30234, 0, 30234 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 951, 0, 0, 11738, 0, 16, 0
- },
- { /* articulation 63 */
- { 32767, 32349, 0, 30073 },
- { 32767, 634, 0, 0 },
- 0, 34, 951, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 64 */
- { 32767, 31730, 0, 31476 },
- { 32767, 634, 0, 0 },
- 0, 34, 951, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 65 */
- { 32767, 32418, 0, 25329 },
- { 32767, 95, 0, 0 },
- 0, 34, 989, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 66 */
- { 32767, 32052, 0, 31964 },
- { 32767, 634, 0, 0 },
- 0, 34, 951, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 67 */
- { 32767, 31938, 0, 31938 },
- { 32767, 634, 0, 0 },
- 0, 34, 951, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 68 */
- { 9511, 32663, 18820, 23749 },
- { 1902, 57, 13107, 0 },
- 0, 0, 989, 0, 6000, 5535, 0, 4, 0
- },
- { /* articulation 69 */
- { 32767, 31754, 0, 31730 },
- { 32767, 1902, 0, 0 },
- 0, 52, 989, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 70 */
- { 127, 32686, 3811, 32349 },
- { 95, 38, 32767, 0 },
- 0, 0, 989, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 71 */
- { 4755, 32663, 3566, 28809 },
- { 3804, 32767, 32767, 0 },
- 0, 0, 989, 100, 0, 11919, 0, 0, 0
- },
- { /* articulation 72 */
- { 32767, 31935, 0, 31935 },
- { 32767, 335, 0, 0 },
- 0, 17, 989, 0, 7000, 9023, 0, 0, 0
- },
- { /* articulation 73 */
- { 32767, 31391, 0, 31391 },
- { 32767, 335, 0, 0 },
- 0, 2, 951, 0, 7000, 9023, 0, 0, 0
- },
- { /* articulation 74 */
- { 32767, 32628, 6208, 31935 },
- { 380, 95, 0, 0 },
- 0, 0, 989, 0, 3840, 8302, 0, 8, 0
- },
- { /* articulation 75 */
- { 32767, 32072, 0, 32171 },
- { 32767, 380, 0, 0 },
- 0, 0, 989, 0, 5000, 8321, 0, 0, 0
- },
- { /* articulation 76 */
- { 32767, 31935, 0, 31935 },
- { 32767, 380, 0, 0 },
- 0, 0, 951, 0, 5000, 7934, 0, 0, 0
- },
- { /* articulation 77 */
- { 32767, 32117, 0, 30685 },
- { 32767, 63, 0, 0 },
- 0, 17, 989, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 78 */
- { 32767, 32245, 0, 23749 },
- { 32767, 1902, 0, 0 },
- 0, 172, 989, 0, 1000, 11107, 0, 0, 0
- },
- { /* articulation 79 */
- { 32767, 32663, 6208, 31935 },
- { 95, 95, 0, 0 },
- 0, 34, 1622, 0, 3560, 8834, 1, 8, 0
- },
- { /* articulation 80 */
- { 32767, 32362, 0, 26439 },
- { 32767, 190, 0, 0 },
- 0, 17, 989, 0, 6000, 9907, 0, 0, 0
- },
- { /* articulation 81 */
- { 32767, 32245, 0, 23749 },
- { 32767, 63, 0, 0 },
- 0, 17, 989, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 82 */
- { 32767, 31730, 18820, 9042 },
- { 32767, 32767, 32767, 0 },
- 0, 17, 989, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 83 */
- { 32767, 32715, 128, 32168 },
- { 32767, 127, 0, 0 },
- 0, 0, 989, 0, 0, 11920, 0, 8, 0
- },
- { /* articulation 84 */
- { 32767, 32072, 0, 32072 },
- { 32767, 67, 0, 0 },
- 3, 0, 572, 0, 5000, 5535, 0, 0, 0
- },
- { /* articulation 85 */
- { 3804, 32663, 18820, 23749 },
- { 32767, 2024, 0, 0 },
- 10, 34, 1008, -30, 0, 0, 0, 0, 0
- },
- { /* articulation 86 */
- { 19021, 32663, 18820, 23749 },
- { 761, 95, 0, 0 },
- 0, 34, 989, 0, 4473, 7131, 0, 8, 0
- },
- { /* articulation 87 */
- { 1902, 32628, 6208, 32171 },
- { 634, 38, 16384, 0 },
- 0, 0, 989, 0, 2987, 7877, 0, 12, 0
- },
- { /* articulation 88 */
- { 32767, 32593, 0, 31935 },
- { 32767, 95, 0, 0 },
- 0, 0, 1162, 0, 4053, 7930, 2, 12, 0
- },
- { /* articulation 89 */
- { 380, 32684, 6208, 31935 },
- { 32767, 112, 0, 0 },
- 0, 0, 989, 0, 0, 8887, 0, 0, 0
- },
- { /* articulation 90 */
- { 19021, 32663, 18820, 23749 },
- { 1268, 95, 0, 0 },
- 0, 34, 989, 0, 5113, 7981, 0, 4, 0
- },
- { /* articulation 91 */
- { 1902, 32663, 6208, 30725 },
- { 1902, 127, 0, 0 },
- 0, 34, 989, 0, 3500, 7877, 0, 5, 0
- },
- { /* articulation 92 */
- { 1902, 32663, 6208, 30725 },
- { 1268, 95, 0, 0 },
- 0, 34, 951, 0, 4773, 8355, 0, 5, 0
- },
- { /* articulation 93 */
- { 476, 32663, 10809, 31935 },
- { 32767, 32767, 32767, 0 },
- 0, 34, 989, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 94 */
- { 3804, 32663, 18820, 30234 },
- { 32767, 32767, 32767, 0 },
- 0, 34, 989, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 95 */
- { 7608, 32663, 18820, 17213 },
- { 2536, 261, 0, 0 },
- 0, 34, 989, 0, 1200, 11690, 0, 4, 0
- },
- { /* articulation 96 */
- { 32767, 32468, 15076, 30234 },
- { 32767, 32767, 32767, 0 },
- 0, 36, 2183, 0, 0, 11919, 1, 0, 0
- },
- { /* articulation 97 */
- { 32767, 0, 32767, 32663 },
- { 380, 32767, 32767, 0 },
- 0, 0, 989, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 98 */
- { 32767, 31391, 0, 31391 },
- { 32767, 634, 0, 0 },
- 0, 0, 989, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 99 */
- { 32767, 32558, 0, 23749 },
- { 1268, 190, 13107, 0 },
- 0, 34, 989, 0, 3200, 8321, 0, 0, 0
- },
- { /* articulation 100 */
- { 32767, 0, 32767, 0 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 989, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 101 */
- { 32767, 32072, 0, 23749 },
- { 32767, 1087, 0, 0 },
- 0, 34, 989, 0, 8187, 5535, 0, 5, 0
- },
- { /* articulation 102 */
- { 32767, 32558, 0, 29434 },
- { 32767, 190, 7667, 0 },
- 5, 0, 989, 0, 6053, 5535, 0, 5, 0
- },
- { /* articulation 103 */
- { 32767, 32663, 18820, 23749 },
- { 1902, 95, 0, 0 },
- 0, 0, 989, 0, 2700, 9852, 0, 0, 0
- },
- { /* articulation 104 */
- { 32767, 32663, 18820, 27897 },
- { 1902, 95, 0, 0 },
- 0, 0, 989, 0, 2700, 9852, 0, 0, 0
- },
- { /* articulation 105 */
- { 32767, 32663, 18820, 23749 },
- { 32767, 1268, 0, 0 },
- 0, 52, 951, 0, 2500, 10490, 1, 8, 0
- },
- { /* articulation 106 */
- { 32767, 32663, 23493, 23749 },
- { 32767, 380, 0, 0 },
- 0, 34, 988, 0, 4000, 10223, 1, 4, 0
- },
- { /* articulation 107 */
- { 32767, 32663, 18820, 27897 },
- { 32767, 126, 7667, 0 },
- 0, 0, 989, 0, 1813, 9154, 0, 0, 0
- },
- { /* articulation 108 */
- { 32767, 31730, 0, 31730 },
- { 32767, 380, 0, 0 },
- 0, 0, 951, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 109 */
- { 32767, 31180, 0, 30484 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 951, 0, 0, 11690, 0, 0, 0
- },
- { /* articulation 110 */
- { 32767, 30725, 0, 30725 },
- { 32767, 380, 0, 0 },
- 0, 0, 951, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 111 */
- { 32767, 32349, 18820, 27897 },
- { 32767, 95, 0, 0 },
- 12, 34, 951, 0, 3000, 10223, 0, 0, 0
- },
- { /* articulation 112 */
- { 32767, 32349, 18820, 27897 },
- { 32767, 63, 0, 0 },
- 12, 34, 951, 0, 1900, 10031, 0, 0, 0
- },
- { /* articulation 113 */
- { 32767, 32663, 18820, 26439 },
- { 32767, 63, 0, 0 },
- 12, 34, 988, 0, 1000, 11107, 0, 0, 0
- },
- { /* articulation 114 */
- { 32767, 32663, 18820, 26439 },
- { 32767, 63, 0, 0 },
- 12, 34, 988, 0, 2000, 11107, 0, 0, 0
- },
- { /* articulation 115 */
- { 32767, 32505, 0, 26439 },
- { 32767, 190, 0, 0 },
- 0, 17, 989, 0, 4000, 8321, 0, 0, 0
- },
- { /* articulation 116 */
- { 32767, 31832, 19893, 9042 },
- { 32767, 476, 0, 0 },
- 0, 34, 1452, 0, 0, 11919, 0, 0, 0
- },
- { /* articulation 117 */
- { 19021, 32072, 23493, 9042 },
- { 32767, 32767, 32767, 0 },
- 0, 34, 1355, 0, 0, 11877, 1, 0, 0
- },
- { /* articulation 118 */
- { 32767, 32468, 0, 23749 },
- { 32767, 190, 0, 0 },
- 0, 34, 989, 0, 3500, 9023, 0, 0, 0
- },
- { /* articulation 119 */
- { 32767, 17213, 23493, 0 },
- { 32767, 32767, 32767, 0 },
- 0, 17, 1521, 0, 0, 10925, 1, 0, 0
- },
- { /* articulation 120 */
- { 32767, 32505, 0, 26439 },
- { 32767, 190, 0, 0 },
- 0, 52, 989, 0, 3200, 8721, 0, 4, 0
- },
- { /* articulation 121 */
- { 3804, 32663, 18820, 23749 },
- { 32767, 32767, 32767, 0 },
- 0, 34, 989, 0, 0, 0, 1, 0, 0
- },
- { /* articulation 122 */
- { 9511, 32663, 18820, 25329 },
- { 32767, 32767, 32767, 0 },
- 0, 34, 989, 0, 0, 11877, 0, 8, 0
- },
- { /* articulation 123 */
- { 32767, 32663, 18820, 23749 },
- { 32767, 32, 0, 0 },
- 0, 17, 989, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 124 */
- { 32767, 32558, 0, 23749 },
- { 32767, 380, 0, 0 },
- 0, 34, 989, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 125 */
- { 32767, 32663, 18820, 23749 },
- { 32767, 24, 0, 0 },
- 0, 17, 989, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 126 */
- { 32767, 30725, 0, 30725 },
- { 32767, 761, 0, 0 },
- 0, 0, 989, 0, 3000, 10223, 0, 8, 0
- },
- { /* articulation 127 */
- { 127, 0, 32767, 32349 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 1522, 0, 0, 11423, 4, 0, 0
- },
- { /* articulation 128 */
- { 951, 32422, 0, 32387 },
- { 32767, 19, 0, 0 },
- 0, 0, 989, 0, 0, 11423, 0, 0, 0
- },
- { /* articulation 129 */
- { 391, 0, 0, 31180 },
- { 190, 32767, 32767, 0 },
- 0, 0, 989, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 130 */
- { 32767, 30725, 0, 30725 },
- { 32767, 761, 0, 0 },
- 0, 0, 989, 1200, 0, 0, 0, 0, 0
- },
- { /* articulation 131 */
- { 32767, 31730, 0, 31935 },
- { 32767, 380, 0, 0 },
- 0, 0, 989, 50, 0, 0, 0, 0, 0
- },
- { /* articulation 132 */
- { 32767, 32072, 0, 32072 },
- { 32767, 19021, 0, 0 },
- 0, 0, 989, 0, 4700, 7769, 0, 0, 0
- },
- { /* articulation 133 */
- { 32767, 30073, 0, 30073 },
- { 32767, 32767, 0, 0 },
- 0, 0, 989, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 134 */
- { 32767, 32558, 32767, 32558 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 951, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 135 */
- { 32767, 32663, 18820, 17213 },
- { 32767, 190, 0, 0 },
- 10, 34, 951, 0, 2000, 10696, 0, 0, 0
- },
- { /* articulation 136 */
- { 32767, 32663, 10809, 17213 },
- { 32767, 190, 0, 0 },
- 12, 34, 982, 0, 0, 10910, 0, 0, 0
- },
- { /* articulation 137 */
- { 32767, 32663, 18820, 17213 },
- { 32767, 190, 0, 0 },
- 10, 34, 951, 0, 1200, 10218, 0, 0, 0
- },
- { /* articulation 138 */
- { 32767, 32663, 18820, 17213 },
- { 32767, 190, 0, 0 },
- 10, 34, 951, 0, 1100, 9525, 0, 0, 0
- },
- { /* articulation 139 */
- { 19021, 32558, 18820, 23749 },
- { 32767, 19, 0, 0 },
- 10, 34, 988, 0, 2000, 10962, 0, 0, 0
- },
- { /* articulation 140 */
- { 32767, 32349, 18820, 23749 },
- { 19021, 634, 0, 0 },
- 10, 32, 1008, 0, 1200, 10090, 0, 0, 0
- },
- { /* articulation 141 */
- { 2536, 0, 32767, 27897 },
- { 1902, 380, 0, 0 },
- 7, 34, 988, 0, 1620, 8933, 0, 0, 0
- },
- { /* articulation 142 */
- { 32767, 32349, 10809, 23749 },
- { 32767, 380, 0, 0 },
- 7, 34, 988, 0, 2200, 8994, 0, 0, 0
- },
- { /* articulation 143 */
- { 32767, 32663, 15076, 23749 },
- { 32767, 1902, 0, 0 },
- 10, 34, 982, 0, 2500, 9525, 0, 0, 0
- },
- { /* articulation 144 */
- { 32767, 32663, 15076, 23749 },
- { 32767, 190, 0, 0 },
- 10, 34, 951, 0, 1500, 11423, 0, 0, 0
- },
- { /* articulation 145 */
- { 32767, 32663, 18820, 23749 },
- { 32767, 1902, 0, 0 },
- 9, 34, 982, 0, 1500, 9521, 0, 0, 0
- },
- { /* articulation 146 */
- { 3804, 0, 32767, 28809 },
- { 32767, 32767, 32767, 0 },
- 0, 0, 1521, 0, 0, 9521, 0, 0, 0
- },
- { /* articulation 147 */
- { 32767, 32558, 0, 23749 },
- { 32767, 19021, 0, 0 },
- 0, 17, 989, 0, 5000, 10223, 0, 0, 0
- },
- { /* articulation 148 */
- { 32767, 32663, 18820, 23749 },
- { 32767, 63, 0, 0 },
- 10, 34, 951, 0, 1500, 9907, 0, 0, 0
- },
- { /* articulation 149 */
- { 32767, 32698, 11682, 23749 },
- { 32767, 1902, 0, 0 },
- 0, 34, 951, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 150 */
- { 32767, 32072, 0, 32072 },
- { 32767, 380, 0, 0 },
- 0, 17, 989, 0, 3440, 9260, 0, 0, 0
- },
- { /* articulation 151 */
- { 32767, 30234, 0, 30725 },
- { 32767, 1902, 0, 0 },
- 0, 17, 989, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 152 */
- { 32767, 31730, 0, 30725 },
- { 32767, 380, 0, 0 },
- 0, 17, 989, 0, 4000, 7823, 0, 0, 0
- },
- { /* articulation 153 */
- { 32767, 32558, 3566, 23749 },
- { 783, 32767, 32767, 0 },
- 100, 0, 1522, 500, 0, 11877, 0, 0, 0
- },
- { /* articulation 154 */
- { 32767, 32663, 18820, 17213 },
- { 32767, 1902, 0, 0 },
- 8, 34, 989, -22, 0, 0, 0, 0, 0
- },
- { /* articulation 155 */
- { 19021, 29007, 6784, 23749 },
- { 32767, 1902, 0, 0 },
- 0, 34, 951, 0, 5000, 9521, 1, 0, 0
- },
- { /* articulation 156 */
- { 32767, 32558, 0, 31935 },
- { 1902, 254, 16384, 0 },
- 0, 52, 989, 0, 3627, 10547, 0, 5, 0
- },
- { /* articulation 157 */
- { 3804, 0, 32767, 23749 },
- { 1902, 1902, 0, 0 },
- 0, 34, 989, 27, 0, 11919, 0, 0, 0
- },
- { /* articulation 158 */
- { 32767, 0, 32767, 31730 },
- { 76, 66, 10092, 0 },
- 5, 0, 989, 0, 8007, 5535, 0, 8, 0
- },
- { /* articulation 159 */
- { 32767, 32468, 0, 29434 },
- { 32767, 127, 0, 0 },
- 0, 52, 989, 0, 2500, 9032, 0, 0, 0
- },
- { /* articulation 160 */
- { 9511, 32663, 10809, 25329 },
- { 32767, 32767, 32767, 0 },
- 0, 34, 989, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 161 */
- { 19021, 32558, 18820, 23749 },
- { 32767, 190, 0, 0 },
- 10, 34, 988, 0, 2600, 9513, 0, 0, 0
- },
- { /* articulation 162 */
- { 32767, 32106, 9568, 23749 },
- { 2348, 391, 0, 0 },
- 10, 52, 980, 0, 6500, 9023, 0, 0, 0
- },
- { /* articulation 163 */
- { 32767, 32558, 0, 26439 },
- { 32767, 63, 0, 0 },
- 0, 34, 989, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 164 */
- { 32767, 32072, 15076, 17213 },
- { 32767, 1268, 0, 0 },
- 0, 0, 951, 0, 2000, 10223, 0, 0, 0
- },
- { /* articulation 165 */
- { 32767, 32558, 0, 23749 },
- { 32767, 380, 0, 0 },
- 0, 34, 989, 0, 3000, 9366, 0, 0, 0
- },
- { /* articulation 166 */
- { 32767, 32663, 18820, 23749 },
- { 1902, 127, 10879, 0 },
- 0, 0, 989, 0, 6000, 7121, 0, 4, 0
- },
- { /* articulation 167 */
- { 32767, 32505, 0, 26439 },
- { 32767, 21, 0, 0 },
- 0, 52, 989, 0, 3500, 6236, 0, 5, 0
- },
- { /* articulation 168 */
- { 32767, 32505, 0, 26439 },
- { 32767, 190, 0, 0 },
- 0, 52, 989, 0, 2800, 7121, 0, 0, 0
- },
- { /* articulation 169 */
- { 32767, 32418, 0, 29434 },
- { 32767, 127, 0, 0 },
- 0, 52, 989, 0, 2100, 9626, 0, 0, 0
- },
- { /* articulation 170 */
- { 32767, 32349, 0, 30234 },
- { 32767, 127, 0, 0 },
- 0, 52, 989, 0, 3000, 9626, 0, 0, 0
- },
- { /* articulation 171 */
- { 32767, 32288, 0, 28400 },
- { 32767, 127, 0, 0 },
- 0, 52, 989, 0, 1000, 9032, 0, 0, 0
- },
- { /* articulation 172 */
- { 32767, 32072, 0, 28809 },
- { 32767, 127, 0, 0 },
- 0, 52, 989, 0, 1000, 9032, 0, 0, 0
- },
- { /* articulation 173 */
- { 3804, 32072, 15076, 17213 },
- { 32767, 1268, 0, 0 },
- 0, 52, 991, 0, 0, 11107, 0, 8, 0
- },
- { /* articulation 174 */
- { 32767, 32349, 15076, 23749 },
- { 7608, 147, 0, 0 },
- 0, 0, 989, 0, 4500, 9521, 0, 8, 0
- },
- { /* articulation 175 */
- { 32767, 32663, 18820, 23749 },
- { 32767, 95, 0, 0 },
- 0, 0, 989, 0, 2000, 8321, 0, 8, 0
- },
- { /* articulation 176 */
- { 32767, 32715, 128, 29669 },
- { 32767, 1729, 0, 0 },
- 0, 0, 989, 0, 6000, 7823, 0, 8, 0
- },
- { /* articulation 177 */
- { 19021, 32448, 0, 31882 },
- { 32767, 95, 0, 0 },
- 0, 0, 989, 0, 4500, 7121, 0, 8, 0
- },
- { /* articulation 178 */
- { 32767, 32560, 3646, 32107 },
- { 32767, 190, 0, 0 },
- 0, 0, 989, 0, 4000, 8321, 0, 8, 0
- },
- { /* articulation 179 */
- { 32767, 32602, 13644, 26439 },
- { 32767, 63, 0, 0 },
- 12, 34, 988, 0, 2000, 11107, 0, 0, 0
- },
- { /* articulation 180 */
- { 19021, 30484, 0, 23749 },
- { 32767, 1902, 0, 0 },
- 0, 0, 989, 0, 5000, 8321, 1, 0, 0
- },
- { /* articulation 181 */
- { 261, 32466, 0, 31938 },
- { 32767, 634, 0, 0 },
- 0, 34, 951, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 182 */
- { 32767, 32418, 0, 31742 },
- { 2348, 39, 0, 0 },
- 0, 34, 989, 0, 3600, 7121, 0, 4, 0
- },
- { /* articulation 183 */
- { 32767, 32090, 0, 32090 },
- { 32767, 634, 0, 0 },
- 0, 34, 951, 0, 0, 0, 0, 0, 0
- },
- { /* articulation 184 */
- { 1669, 32715, 19242, 30194 },
- { 32767, 296, 0, 0 },
- 0, 0, 1555, 0, 3000, 9907, 0, 4, 0
- }
+ { /* articulation 0 */
+ { 32767, 30725, 0, 30725 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 951, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 1 */
+ { 32767, 26863, 0, 26863 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 951, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 2 */
+ { 32767, 30484, 0, 30668 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 951, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 3 */
+ { 32767, 26439, 0, 26439 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 951, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 4 */
+ { 32767, 0, 32767, 32715 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 951, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 5 */
+ { 32767, 21333, 0, 21333 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 951, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 6 */
+ { 32767, 31882, 0, 31938 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 951, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 7 */
+ { 32767, 32663, 32767, 32663 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 951, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 8 */
+ { 32767, 0, 32767, 0 },
+ { 32767, 1902, 0, 0 },
+ 0, 0, 951, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 9 */
+ { 32767, 32349, 0, 32349 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 951, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 10 */
+ { 32767, 0, 32767, 17213 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 951, 0, 0, 0, 0, 0, -1
+ },
+ { /* articulation 11 */
+ { 32767, 31730, 0, 31730 },
+ { 32767, 761, 0, 0 },
+ 0, 0, 951, 0, 0, 0, 0, 0, -44
+ },
+ { /* articulation 12 */
+ { 32767, 23749, 0, 23749 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 951, 0, 0, 0, 0, 0, 56
+ },
+ { /* articulation 13 */
+ { 32767, 31730, 0, 31730 },
+ { 32767, 761, 0, 0 },
+ 0, 0, 951, 0, 0, 0, 0, 0, -31
+ },
+ { /* articulation 14 */
+ { 9511, 21333, 0, 21333 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 951, 0, 0, 0, 0, 0, 56
+ },
+ { /* articulation 15 */
+ { 32767, 31617, 0, 31617 },
+ { 32767, 761, 0, 0 },
+ 0, 0, 951, 0, 0, 0, 0, 0, -6
+ },
+ { /* articulation 16 */
+ { 32767, 32123, 0, 32194 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 951, 0, 0, 0, 0, 0, 56
+ },
+ { /* articulation 17 */
+ { 32767, 31550, 0, 31550 },
+ { 32767, 761, 0, 0 },
+ 0, 0, 951, 0, 0, 0, 0, 0, 6
+ },
+ { /* articulation 18 */
+ { 32767, 31391, 0, 31391 },
+ { 32767, 951, 0, 0 },
+ 0, 0, 951, 0, 0, 0, 0, 0, 31
+ },
+ { /* articulation 19 */
+ { 32767, 31964, 0, 31964 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 951, 0, 0, 0, 0, 0, 25
+ },
+ { /* articulation 20 */
+ { 32767, 31056, 0, 31056 },
+ { 32767, 951, 0, 0 },
+ 0, 0, 951, 0, 0, 0, 0, 0, 63
+ },
+ { /* articulation 21 */
+ { 32767, 32289, 0, 32271 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 951, 0, 0, 0, 0, 0, -37
+ },
+ { /* articulation 22 */
+ { 19021, 31882, 0, 31911 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 951, 0, 0, 0, 0, 0, -37
+ },
+ { /* articulation 23 */
+ { 32767, 31988, 0, 32032 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 951, 0, 0, 0, 0, 0, -37
+ },
+ { /* articulation 24 */
+ { 32767, 0, 32767, 32663 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 951, 0, 0, 0, 0, 0, 12
+ },
+ { /* articulation 25 */
+ { 32767, 31352, 0, 31352 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 951, 0, 0, 0, 0, 0, -25
+ },
+ { /* articulation 26 */
+ { 32767, 0, 32767, 32663 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 951, 0, 0, 0, 0, 0, 25
+ },
+ { /* articulation 27 */
+ { 32767, 31817, 0, 31781 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 951, 0, 0, 0, 0, 0, -25
+ },
+ { /* articulation 28 */
+ { 32767, 30725, 0, 30725 },
+ { 32767, 95, 0, 0 },
+ 0, 0, 951, 240, 0, 0, 0, 0, -56
+ },
+ { /* articulation 29 */
+ { 32767, 32230, 0, 32218 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 951, 0, 0, 0, 0, 0, -37
+ },
+ { /* articulation 30 */
+ { 32767, 26439, 0, 26439 },
+ { 32767, 3804, 0, 0 },
+ 0, 0, 951, 0, 0, 0, 0, 0, 50
+ },
+ { /* articulation 31 */
+ { 32767, 23749, 0, 23749 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 951, 0, 0, 0, 0, 0, -50
+ },
+ { /* articulation 32 */
+ { 32767, 29434, 0, 29434 },
+ { 32767, 3804, 0, 0 },
+ 0, 0, 951, 0, 0, 0, 0, 0, -50
+ },
+ { /* articulation 33 */
+ { 32767, 30240, 0, 30234 },
+ { 32767, 3804, 0, 0 },
+ 0, 0, 951, 0, 0, 0, 0, 0, -44
+ },
+ { /* articulation 34 */
+ { 32767, 32558, 0, 32558 },
+ { 32767, 254, 0, 0 },
+ 0, 0, 951, 0, 0, 0, 0, 0, 25
+ },
+ { /* articulation 35 */
+ { 32767, 0, 32767, 32663 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 951, 0, 0, 0, 0, 0, -63
+ },
+ { /* articulation 36 */
+ { 3804, 23749, 0, 23749 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 951, 0, 0, 0, 0, 0, -63
+ },
+ { /* articulation 37 */
+ { 32767, 23749, 0, 23749 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 951, 0, 0, 0, 0, 0, -59
+ },
+ { /* articulation 38 */
+ { 32767, 30725, 0, 30725 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 951, 0, 0, 0, 0, 0, 50
+ },
+ { /* articulation 39 */
+ { 32767, 28809, 0, 28809 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 951, 0, 0, 0, 0, 0, 44
+ },
+ { /* articulation 40 */
+ { 1902, 30725, 0, 30725 },
+ { 32767, 380, 0, 0 },
+ 0, 0, 951, -100, 0, 0, 0, 0, 44
+ },
+ { /* articulation 41 */
+ { 32767, 9042, 0, 9042 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 951, 0, 0, 0, 0, 0, 25
+ },
+ { /* articulation 42 */
+ { 32767, 29889, 0, 29889 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 951, 0, 0, 0, 0, 0, 63
+ },
+ { /* articulation 43 */
+ { 32767, 30240, 0, 30234 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 951, 0, 0, 0, 0, 0, 63
+ },
+ { /* articulation 44 */
+ { 19021, 19970, 0, 19970 },
+ { 951, 32767, 32767, 0 },
+ 0, 0, 951, 100, 0, 0, 0, 0, -25
+ },
+ { /* articulation 45 */
+ { 3804, 17213, 0, 17213 },
+ { 951, 32767, 32767, 0 },
+ 0, 0, 951, 500, 0, 0, 0, 0, -25
+ },
+ { /* articulation 46 */
+ { 32767, 17213, 0, 17213 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 951, 0, 0, 0, 0, 0, -56
+ },
+ { /* articulation 47 */
+ { 32767, 30725, 0, 30725 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 951, 0, 0, 0, 0, 0, -56
+ },
+ { /* articulation 48 */
+ { 32767, 0, 32767, 0 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 951, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 49 */
+ { 32767, 31180, 0, 31180 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 951, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 50 */
+ { 19021, 31964, 0, 32071 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 951, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 51 */
+ { 32767, 29669, 0, 29669 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 951, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 52 */
+ { 32767, 31742, 0, 31352 },
+ { 32767, 294, 0, 0 },
+ 0, 0, 951, 0, 10000, 7121, 0, 0, 0
+ },
+ { /* articulation 53 */
+ { 32767, 0, 32767, 31391 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 1555, 0, -2300, 11920, 0, 0, 0
+ },
+ { /* articulation 54 */
+ { 1174, 0, 32767, 31988 },
+ { 32767, 127, 0, 0 },
+ 0, 0, 1555, 0, 2000, 10721, 0, 8, 15
+ },
+ { /* articulation 55 */
+ { 1174, 0, 32767, 31988 },
+ { 951, 127, 0, 0 },
+ 0, 0, 1555, 0, 2000, 9023, 0, 5, 15
+ },
+ { /* articulation 56 */
+ { 7608, 0, 32767, 30237 },
+ { 32767, 69, 5898, 0 },
+ 0, 0, 1555, 0, 6000, 9080, 0, 0, -2
+ },
+ { /* articulation 57 */
+ { 32767, 0, 32767, 29337 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 1555, 0, 0, 0, 0, 0, 1
+ },
+ { /* articulation 58 */
+ { 5141, 0, 32767, 30194 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 1555, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 59 */
+ { 32767, 32558, 0, 26439 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 951, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 60 */
+ { 32767, 32349, 0, 26439 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 951, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 61 */
+ { 32767, 32072, 0, 32072 },
+ { 32767, 95, 0, 0 },
+ 0, 34, 989, 0, 2400, 9521, 0, 0, 0
+ },
+ { /* articulation 62 */
+ { 32767, 30234, 0, 30234 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 951, 0, 0, 11738, 0, 16, 0
+ },
+ { /* articulation 63 */
+ { 32767, 32349, 0, 30073 },
+ { 32767, 634, 0, 0 },
+ 0, 34, 951, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 64 */
+ { 32767, 31730, 0, 31476 },
+ { 32767, 634, 0, 0 },
+ 0, 34, 951, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 65 */
+ { 32767, 32418, 0, 25329 },
+ { 32767, 95, 0, 0 },
+ 0, 34, 989, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 66 */
+ { 32767, 32052, 0, 31964 },
+ { 32767, 634, 0, 0 },
+ 0, 34, 951, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 67 */
+ { 32767, 31938, 0, 31938 },
+ { 32767, 634, 0, 0 },
+ 0, 34, 951, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 68 */
+ { 9511, 32663, 18820, 23749 },
+ { 1902, 57, 13107, 0 },
+ 0, 0, 989, 0, 6000, 5535, 0, 4, 0
+ },
+ { /* articulation 69 */
+ { 32767, 31754, 0, 31730 },
+ { 32767, 1902, 0, 0 },
+ 0, 52, 989, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 70 */
+ { 127, 32686, 3811, 32349 },
+ { 95, 38, 32767, 0 },
+ 0, 0, 989, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 71 */
+ { 4755, 32663, 3566, 28809 },
+ { 3804, 32767, 32767, 0 },
+ 0, 0, 989, 100, 0, 11919, 0, 0, 0
+ },
+ { /* articulation 72 */
+ { 32767, 31935, 0, 31935 },
+ { 32767, 335, 0, 0 },
+ 0, 17, 989, 0, 7000, 9023, 0, 0, 0
+ },
+ { /* articulation 73 */
+ { 32767, 31391, 0, 31391 },
+ { 32767, 335, 0, 0 },
+ 0, 2, 951, 0, 7000, 9023, 0, 0, 0
+ },
+ { /* articulation 74 */
+ { 32767, 32628, 6208, 31935 },
+ { 380, 95, 0, 0 },
+ 0, 0, 989, 0, 3840, 8302, 0, 8, 0
+ },
+ { /* articulation 75 */
+ { 32767, 32072, 0, 32171 },
+ { 32767, 380, 0, 0 },
+ 0, 0, 989, 0, 5000, 8321, 0, 0, 0
+ },
+ { /* articulation 76 */
+ { 32767, 31935, 0, 31935 },
+ { 32767, 380, 0, 0 },
+ 0, 0, 951, 0, 5000, 7934, 0, 0, 0
+ },
+ { /* articulation 77 */
+ { 32767, 32117, 0, 30685 },
+ { 32767, 63, 0, 0 },
+ 0, 17, 989, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 78 */
+ { 32767, 32245, 0, 23749 },
+ { 32767, 1902, 0, 0 },
+ 0, 172, 989, 0, 1000, 11107, 0, 0, 0
+ },
+ { /* articulation 79 */
+ { 32767, 32663, 6208, 31935 },
+ { 95, 95, 0, 0 },
+ 0, 34, 1622, 0, 3560, 8834, 1, 8, 0
+ },
+ { /* articulation 80 */
+ { 32767, 32362, 0, 26439 },
+ { 32767, 190, 0, 0 },
+ 0, 17, 989, 0, 6000, 9907, 0, 0, 0
+ },
+ { /* articulation 81 */
+ { 32767, 32245, 0, 23749 },
+ { 32767, 63, 0, 0 },
+ 0, 17, 989, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 82 */
+ { 32767, 31730, 18820, 9042 },
+ { 32767, 32767, 32767, 0 },
+ 0, 17, 989, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 83 */
+ { 32767, 32715, 128, 32168 },
+ { 32767, 127, 0, 0 },
+ 0, 0, 989, 0, 0, 11920, 0, 8, 0
+ },
+ { /* articulation 84 */
+ { 32767, 32072, 0, 32072 },
+ { 32767, 67, 0, 0 },
+ 3, 0, 572, 0, 5000, 5535, 0, 0, 0
+ },
+ { /* articulation 85 */
+ { 3804, 32663, 18820, 23749 },
+ { 32767, 2024, 0, 0 },
+ 10, 34, 1008, -30, 0, 0, 0, 0, 0
+ },
+ { /* articulation 86 */
+ { 19021, 32663, 18820, 23749 },
+ { 761, 95, 0, 0 },
+ 0, 34, 989, 0, 4473, 7131, 0, 8, 0
+ },
+ { /* articulation 87 */
+ { 1902, 32628, 6208, 32171 },
+ { 634, 38, 16384, 0 },
+ 0, 0, 989, 0, 2987, 7877, 0, 12, 0
+ },
+ { /* articulation 88 */
+ { 32767, 32593, 0, 31935 },
+ { 32767, 95, 0, 0 },
+ 0, 0, 1162, 0, 4053, 7930, 2, 12, 0
+ },
+ { /* articulation 89 */
+ { 380, 32684, 6208, 31935 },
+ { 32767, 112, 0, 0 },
+ 0, 0, 989, 0, 0, 8887, 0, 0, 0
+ },
+ { /* articulation 90 */
+ { 19021, 32663, 18820, 23749 },
+ { 1268, 95, 0, 0 },
+ 0, 34, 989, 0, 5113, 7981, 0, 4, 0
+ },
+ { /* articulation 91 */
+ { 1902, 32663, 6208, 30725 },
+ { 1902, 127, 0, 0 },
+ 0, 34, 989, 0, 3500, 7877, 0, 5, 0
+ },
+ { /* articulation 92 */
+ { 1902, 32663, 6208, 30725 },
+ { 1268, 95, 0, 0 },
+ 0, 34, 951, 0, 4773, 8355, 0, 5, 0
+ },
+ { /* articulation 93 */
+ { 476, 32663, 10809, 31935 },
+ { 32767, 32767, 32767, 0 },
+ 0, 34, 989, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 94 */
+ { 3804, 32663, 18820, 30234 },
+ { 32767, 32767, 32767, 0 },
+ 0, 34, 989, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 95 */
+ { 7608, 32663, 18820, 17213 },
+ { 2536, 261, 0, 0 },
+ 0, 34, 989, 0, 1200, 11690, 0, 4, 0
+ },
+ { /* articulation 96 */
+ { 32767, 32468, 15076, 30234 },
+ { 32767, 32767, 32767, 0 },
+ 0, 36, 2183, 0, 0, 11919, 1, 0, 0
+ },
+ { /* articulation 97 */
+ { 32767, 0, 32767, 32663 },
+ { 380, 32767, 32767, 0 },
+ 0, 0, 989, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 98 */
+ { 32767, 31391, 0, 31391 },
+ { 32767, 634, 0, 0 },
+ 0, 0, 989, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 99 */
+ { 32767, 32558, 0, 23749 },
+ { 1268, 190, 13107, 0 },
+ 0, 34, 989, 0, 3200, 8321, 0, 0, 0
+ },
+ { /* articulation 100 */
+ { 32767, 0, 32767, 0 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 989, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 101 */
+ { 32767, 32072, 0, 23749 },
+ { 32767, 1087, 0, 0 },
+ 0, 34, 989, 0, 8187, 5535, 0, 5, 0
+ },
+ { /* articulation 102 */
+ { 32767, 32558, 0, 29434 },
+ { 32767, 190, 7667, 0 },
+ 5, 0, 989, 0, 6053, 5535, 0, 5, 0
+ },
+ { /* articulation 103 */
+ { 32767, 32663, 18820, 23749 },
+ { 1902, 95, 0, 0 },
+ 0, 0, 989, 0, 2700, 9852, 0, 0, 0
+ },
+ { /* articulation 104 */
+ { 32767, 32663, 18820, 27897 },
+ { 1902, 95, 0, 0 },
+ 0, 0, 989, 0, 2700, 9852, 0, 0, 0
+ },
+ { /* articulation 105 */
+ { 32767, 32663, 18820, 23749 },
+ { 32767, 1268, 0, 0 },
+ 0, 52, 951, 0, 2500, 10490, 1, 8, 0
+ },
+ { /* articulation 106 */
+ { 32767, 32663, 23493, 23749 },
+ { 32767, 380, 0, 0 },
+ 0, 34, 988, 0, 4000, 10223, 1, 4, 0
+ },
+ { /* articulation 107 */
+ { 32767, 32663, 18820, 27897 },
+ { 32767, 126, 7667, 0 },
+ 0, 0, 989, 0, 1813, 9154, 0, 0, 0
+ },
+ { /* articulation 108 */
+ { 32767, 31730, 0, 31730 },
+ { 32767, 380, 0, 0 },
+ 0, 0, 951, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 109 */
+ { 32767, 31180, 0, 30484 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 951, 0, 0, 11690, 0, 0, 0
+ },
+ { /* articulation 110 */
+ { 32767, 30725, 0, 30725 },
+ { 32767, 380, 0, 0 },
+ 0, 0, 951, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 111 */
+ { 32767, 32349, 18820, 27897 },
+ { 32767, 95, 0, 0 },
+ 12, 34, 951, 0, 3000, 10223, 0, 0, 0
+ },
+ { /* articulation 112 */
+ { 32767, 32349, 18820, 27897 },
+ { 32767, 63, 0, 0 },
+ 12, 34, 951, 0, 1900, 10031, 0, 0, 0
+ },
+ { /* articulation 113 */
+ { 32767, 32663, 18820, 26439 },
+ { 32767, 63, 0, 0 },
+ 12, 34, 988, 0, 1000, 11107, 0, 0, 0
+ },
+ { /* articulation 114 */
+ { 32767, 32663, 18820, 26439 },
+ { 32767, 63, 0, 0 },
+ 12, 34, 988, 0, 2000, 11107, 0, 0, 0
+ },
+ { /* articulation 115 */
+ { 32767, 32505, 0, 26439 },
+ { 32767, 190, 0, 0 },
+ 0, 17, 989, 0, 4000, 8321, 0, 0, 0
+ },
+ { /* articulation 116 */
+ { 32767, 31832, 19893, 9042 },
+ { 32767, 476, 0, 0 },
+ 0, 34, 1452, 0, 0, 11919, 0, 0, 0
+ },
+ { /* articulation 117 */
+ { 19021, 32072, 23493, 9042 },
+ { 32767, 32767, 32767, 0 },
+ 0, 34, 1355, 0, 0, 11877, 1, 0, 0
+ },
+ { /* articulation 118 */
+ { 32767, 32468, 0, 23749 },
+ { 32767, 190, 0, 0 },
+ 0, 34, 989, 0, 3500, 9023, 0, 0, 0
+ },
+ { /* articulation 119 */
+ { 32767, 17213, 23493, 0 },
+ { 32767, 32767, 32767, 0 },
+ 0, 17, 1521, 0, 0, 10925, 1, 0, 0
+ },
+ { /* articulation 120 */
+ { 32767, 32505, 0, 26439 },
+ { 32767, 190, 0, 0 },
+ 0, 52, 989, 0, 3200, 8721, 0, 4, 0
+ },
+ { /* articulation 121 */
+ { 3804, 32663, 18820, 23749 },
+ { 32767, 32767, 32767, 0 },
+ 0, 34, 989, 0, 0, 0, 1, 0, 0
+ },
+ { /* articulation 122 */
+ { 9511, 32663, 18820, 25329 },
+ { 32767, 32767, 32767, 0 },
+ 0, 34, 989, 0, 0, 11877, 0, 8, 0
+ },
+ { /* articulation 123 */
+ { 32767, 32663, 18820, 23749 },
+ { 32767, 32, 0, 0 },
+ 0, 17, 989, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 124 */
+ { 32767, 32558, 0, 23749 },
+ { 32767, 380, 0, 0 },
+ 0, 34, 989, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 125 */
+ { 32767, 32663, 18820, 23749 },
+ { 32767, 24, 0, 0 },
+ 0, 17, 989, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 126 */
+ { 32767, 30725, 0, 30725 },
+ { 32767, 761, 0, 0 },
+ 0, 0, 989, 0, 3000, 10223, 0, 8, 0
+ },
+ { /* articulation 127 */
+ { 127, 0, 32767, 32349 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 1522, 0, 0, 11423, 4, 0, 0
+ },
+ { /* articulation 128 */
+ { 951, 32422, 0, 32387 },
+ { 32767, 19, 0, 0 },
+ 0, 0, 989, 0, 0, 11423, 0, 0, 0
+ },
+ { /* articulation 129 */
+ { 391, 0, 0, 31180 },
+ { 190, 32767, 32767, 0 },
+ 0, 0, 989, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 130 */
+ { 32767, 30725, 0, 30725 },
+ { 32767, 761, 0, 0 },
+ 0, 0, 989, 1200, 0, 0, 0, 0, 0
+ },
+ { /* articulation 131 */
+ { 32767, 31730, 0, 31935 },
+ { 32767, 380, 0, 0 },
+ 0, 0, 989, 50, 0, 0, 0, 0, 0
+ },
+ { /* articulation 132 */
+ { 32767, 32072, 0, 32072 },
+ { 32767, 19021, 0, 0 },
+ 0, 0, 989, 0, 4700, 7769, 0, 0, 0
+ },
+ { /* articulation 133 */
+ { 32767, 30073, 0, 30073 },
+ { 32767, 32767, 0, 0 },
+ 0, 0, 989, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 134 */
+ { 32767, 32558, 32767, 32558 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 951, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 135 */
+ { 32767, 32663, 18820, 17213 },
+ { 32767, 190, 0, 0 },
+ 10, 34, 951, 0, 2000, 10696, 0, 0, 0
+ },
+ { /* articulation 136 */
+ { 32767, 32663, 10809, 17213 },
+ { 32767, 190, 0, 0 },
+ 12, 34, 982, 0, 0, 10910, 0, 0, 0
+ },
+ { /* articulation 137 */
+ { 32767, 32663, 18820, 17213 },
+ { 32767, 190, 0, 0 },
+ 10, 34, 951, 0, 1200, 10218, 0, 0, 0
+ },
+ { /* articulation 138 */
+ { 32767, 32663, 18820, 17213 },
+ { 32767, 190, 0, 0 },
+ 10, 34, 951, 0, 1100, 9525, 0, 0, 0
+ },
+ { /* articulation 139 */
+ { 19021, 32558, 18820, 23749 },
+ { 32767, 19, 0, 0 },
+ 10, 34, 988, 0, 2000, 10962, 0, 0, 0
+ },
+ { /* articulation 140 */
+ { 32767, 32349, 18820, 23749 },
+ { 19021, 634, 0, 0 },
+ 10, 32, 1008, 0, 1200, 10090, 0, 0, 0
+ },
+ { /* articulation 141 */
+ { 2536, 0, 32767, 27897 },
+ { 1902, 380, 0, 0 },
+ 7, 34, 988, 0, 1620, 8933, 0, 0, 0
+ },
+ { /* articulation 142 */
+ { 32767, 32349, 10809, 23749 },
+ { 32767, 380, 0, 0 },
+ 7, 34, 988, 0, 2200, 8994, 0, 0, 0
+ },
+ { /* articulation 143 */
+ { 32767, 32663, 15076, 23749 },
+ { 32767, 1902, 0, 0 },
+ 10, 34, 982, 0, 2500, 9525, 0, 0, 0
+ },
+ { /* articulation 144 */
+ { 32767, 32663, 15076, 23749 },
+ { 32767, 190, 0, 0 },
+ 10, 34, 951, 0, 1500, 11423, 0, 0, 0
+ },
+ { /* articulation 145 */
+ { 32767, 32663, 18820, 23749 },
+ { 32767, 1902, 0, 0 },
+ 9, 34, 982, 0, 1500, 9521, 0, 0, 0
+ },
+ { /* articulation 146 */
+ { 3804, 0, 32767, 28809 },
+ { 32767, 32767, 32767, 0 },
+ 0, 0, 1521, 0, 0, 9521, 0, 0, 0
+ },
+ { /* articulation 147 */
+ { 32767, 32558, 0, 23749 },
+ { 32767, 19021, 0, 0 },
+ 0, 17, 989, 0, 5000, 10223, 0, 0, 0
+ },
+ { /* articulation 148 */
+ { 32767, 32663, 18820, 23749 },
+ { 32767, 63, 0, 0 },
+ 10, 34, 951, 0, 1500, 9907, 0, 0, 0
+ },
+ { /* articulation 149 */
+ { 32767, 32698, 11682, 23749 },
+ { 32767, 1902, 0, 0 },
+ 0, 34, 951, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 150 */
+ { 32767, 32072, 0, 32072 },
+ { 32767, 380, 0, 0 },
+ 0, 17, 989, 0, 3440, 9260, 0, 0, 0
+ },
+ { /* articulation 151 */
+ { 32767, 30234, 0, 30725 },
+ { 32767, 1902, 0, 0 },
+ 0, 17, 989, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 152 */
+ { 32767, 31730, 0, 30725 },
+ { 32767, 380, 0, 0 },
+ 0, 17, 989, 0, 4000, 7823, 0, 0, 0
+ },
+ { /* articulation 153 */
+ { 32767, 32558, 3566, 23749 },
+ { 783, 32767, 32767, 0 },
+ 100, 0, 1522, 500, 0, 11877, 0, 0, 0
+ },
+ { /* articulation 154 */
+ { 32767, 32663, 18820, 17213 },
+ { 32767, 1902, 0, 0 },
+ 8, 34, 989, -22, 0, 0, 0, 0, 0
+ },
+ { /* articulation 155 */
+ { 19021, 29007, 6784, 23749 },
+ { 32767, 1902, 0, 0 },
+ 0, 34, 951, 0, 5000, 9521, 1, 0, 0
+ },
+ { /* articulation 156 */
+ { 32767, 32558, 0, 31935 },
+ { 1902, 254, 16384, 0 },
+ 0, 52, 989, 0, 3627, 10547, 0, 5, 0
+ },
+ { /* articulation 157 */
+ { 3804, 0, 32767, 23749 },
+ { 1902, 1902, 0, 0 },
+ 0, 34, 989, 27, 0, 11919, 0, 0, 0
+ },
+ { /* articulation 158 */
+ { 32767, 0, 32767, 31730 },
+ { 76, 66, 10092, 0 },
+ 5, 0, 989, 0, 8007, 5535, 0, 8, 0
+ },
+ { /* articulation 159 */
+ { 32767, 32468, 0, 29434 },
+ { 32767, 127, 0, 0 },
+ 0, 52, 989, 0, 2500, 9032, 0, 0, 0
+ },
+ { /* articulation 160 */
+ { 9511, 32663, 10809, 25329 },
+ { 32767, 32767, 32767, 0 },
+ 0, 34, 989, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 161 */
+ { 19021, 32558, 18820, 23749 },
+ { 32767, 190, 0, 0 },
+ 10, 34, 988, 0, 2600, 9513, 0, 0, 0
+ },
+ { /* articulation 162 */
+ { 32767, 32106, 9568, 23749 },
+ { 2348, 391, 0, 0 },
+ 10, 52, 980, 0, 6500, 9023, 0, 0, 0
+ },
+ { /* articulation 163 */
+ { 32767, 32558, 0, 26439 },
+ { 32767, 63, 0, 0 },
+ 0, 34, 989, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 164 */
+ { 32767, 32072, 15076, 17213 },
+ { 32767, 1268, 0, 0 },
+ 0, 0, 951, 0, 2000, 10223, 0, 0, 0
+ },
+ { /* articulation 165 */
+ { 32767, 32558, 0, 23749 },
+ { 32767, 380, 0, 0 },
+ 0, 34, 989, 0, 3000, 9366, 0, 0, 0
+ },
+ { /* articulation 166 */
+ { 32767, 32663, 18820, 23749 },
+ { 1902, 127, 10879, 0 },
+ 0, 0, 989, 0, 6000, 7121, 0, 4, 0
+ },
+ { /* articulation 167 */
+ { 32767, 32505, 0, 26439 },
+ { 32767, 21, 0, 0 },
+ 0, 52, 989, 0, 3500, 6236, 0, 5, 0
+ },
+ { /* articulation 168 */
+ { 32767, 32505, 0, 26439 },
+ { 32767, 190, 0, 0 },
+ 0, 52, 989, 0, 2800, 7121, 0, 0, 0
+ },
+ { /* articulation 169 */
+ { 32767, 32418, 0, 29434 },
+ { 32767, 127, 0, 0 },
+ 0, 52, 989, 0, 2100, 9626, 0, 0, 0
+ },
+ { /* articulation 170 */
+ { 32767, 32349, 0, 30234 },
+ { 32767, 127, 0, 0 },
+ 0, 52, 989, 0, 3000, 9626, 0, 0, 0
+ },
+ { /* articulation 171 */
+ { 32767, 32288, 0, 28400 },
+ { 32767, 127, 0, 0 },
+ 0, 52, 989, 0, 1000, 9032, 0, 0, 0
+ },
+ { /* articulation 172 */
+ { 32767, 32072, 0, 28809 },
+ { 32767, 127, 0, 0 },
+ 0, 52, 989, 0, 1000, 9032, 0, 0, 0
+ },
+ { /* articulation 173 */
+ { 3804, 32072, 15076, 17213 },
+ { 32767, 1268, 0, 0 },
+ 0, 52, 991, 0, 0, 11107, 0, 8, 0
+ },
+ { /* articulation 174 */
+ { 32767, 32349, 15076, 23749 },
+ { 7608, 147, 0, 0 },
+ 0, 0, 989, 0, 4500, 9521, 0, 8, 0
+ },
+ { /* articulation 175 */
+ { 32767, 32663, 18820, 23749 },
+ { 32767, 95, 0, 0 },
+ 0, 0, 989, 0, 2000, 8321, 0, 8, 0
+ },
+ { /* articulation 176 */
+ { 32767, 32715, 128, 29669 },
+ { 32767, 1729, 0, 0 },
+ 0, 0, 989, 0, 6000, 7823, 0, 8, 0
+ },
+ { /* articulation 177 */
+ { 19021, 32448, 0, 31882 },
+ { 32767, 95, 0, 0 },
+ 0, 0, 989, 0, 4500, 7121, 0, 8, 0
+ },
+ { /* articulation 178 */
+ { 32767, 32560, 3646, 32107 },
+ { 32767, 190, 0, 0 },
+ 0, 0, 989, 0, 4000, 8321, 0, 8, 0
+ },
+ { /* articulation 179 */
+ { 32767, 32602, 13644, 26439 },
+ { 32767, 63, 0, 0 },
+ 12, 34, 988, 0, 2000, 11107, 0, 0, 0
+ },
+ { /* articulation 180 */
+ { 19021, 30484, 0, 23749 },
+ { 32767, 1902, 0, 0 },
+ 0, 0, 989, 0, 5000, 8321, 1, 0, 0
+ },
+ { /* articulation 181 */
+ { 261, 32466, 0, 31938 },
+ { 32767, 634, 0, 0 },
+ 0, 34, 951, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 182 */
+ { 32767, 32418, 0, 31742 },
+ { 2348, 39, 0, 0 },
+ 0, 34, 989, 0, 3600, 7121, 0, 4, 0
+ },
+ { /* articulation 183 */
+ { 32767, 32090, 0, 32090 },
+ { 32767, 634, 0, 0 },
+ 0, 34, 951, 0, 0, 0, 0, 0, 0
+ },
+ { /* articulation 184 */
+ { 1669, 32715, 19242, 30194 },
+ { 32767, 296, 0, 0 },
+ 0, 0, 1555, 0, 3000, 9907, 0, 4, 0
+ }
}; /*end Articulations */
/*----------------------------------------------------------------------------
* Regions
*----------------------------------------------------------------------------
*/
-const S_WT_REGION eas_regions[] =
+const S_WT_REGION eas_regions[] =
{
- { { 0, 27, 27 }, -2868, 16422, 0, 0, 81, 0 }, /* region 0 */
- { { 0, 28, 28 }, -3568, 32767, 0, 0, 40, 0 }, /* region 1 */
- { { 0, 29, 29 }, -4553, 32767, 0, 0, 32, 1 }, /* region 2 */
- { { 0, 30, 30 }, -4853, 32767, 0, 0, 32, 2 }, /* region 3 */
- { { 0, 31, 31 }, -3868, 23197, 0, 0, 48, 3 }, /* region 4 */
- { { 1536, 32, 32 }, -3200, 20675, 0, 0, 137, 4 }, /* region 5 */
- { { 1537, 33, 33 }, -3703, 20675, 792, 879, 50, 5 }, /* region 6 */
- { { 1537, 34, 34 }, -3803, 16422, 792, 879, 50, 6 }, /* region 7 */
- { { 0, 35, 35 }, -4968, 32767, 0, 0, 83, 7 }, /* region 8 */
- { { 0, 36, 36 }, -4968, 32767, 0, 0, 83, 7 }, /* region 9 */
- { { 0, 37, 37 }, -4051, 18426, 0, 0, 53, 8 }, /* region 10 */
- { { 0, 38, 38 }, -4151, 23197, 0, 0, 16, 9 }, /* region 11 */
- { { 0, 39, 39 }, -3568, 32767, 0, 0, 40, 10 }, /* region 12 */
- { { 0, 40, 40 }, -4151, 23197, 0, 0, 16, 4 }, /* region 13 */
- { { 1, 41, 41 }, -5855, 26028, 798, 993, 45, 11 }, /* region 14 */
- { { 257, 42, 42 }, -4200, 26028, 4288, 7488, 7, 12 }, /* region 15 */
- { { 1, 43, 43 }, -5755, 26028, 798, 993, 45, 13 }, /* region 16 */
- { { 257, 44, 44 }, -4400, 26028, 4288, 7488, 7, 14 }, /* region 17 */
- { { 1, 45, 45 }, -5755, 26028, 798, 993, 45, 15 }, /* region 18 */
- { { 257, 46, 46 }, -4600, 26028, 4288, 7488, 7, 16 }, /* region 19 */
- { { 1, 47, 47 }, -5455, 26028, 798, 993, 45, 17 }, /* region 20 */
- { { 1, 48, 48 }, -5355, 26028, 798, 993, 45, 18 }, /* region 21 */
- { { 1, 49, 49 }, -5200, 16422, 1294, 5778, 8, 19 }, /* region 22 */
- { { 1, 50, 50 }, -5255, 26028, 798, 993, 45, 20 }, /* region 23 */
- { { 1, 51, 51 }, -5268, 16422, 6592, 9921, 6, 21 }, /* region 24 */
- { { 1, 52, 52 }, -5600, 32767, 1294, 5778, 8, 22 }, /* region 25 */
- { { 1, 53, 53 }, -5418, 14636, 6592, 9921, 6, 23 }, /* region 26 */
- { { 0, 54, 54 }, -5751, 26028, 0, 0, 39, 24 }, /* region 27 */
- { { 1, 55, 55 }, -5300, 32767, 1294, 5778, 8, 25 }, /* region 28 */
- { { 0, 56, 56 }, -7255, 32767, 0, 0, 90, 26 }, /* region 29 */
- { { 1, 57, 57 }, -5700, 32767, 1294, 5778, 8, 27 }, /* region 30 */
- { { 1, 58, 58 }, -7053, 23197, 0, 166, 113, 28 }, /* region 31 */
- { { 1, 59, 59 }, -5968, 16422, 6592, 9921, 6, 29 }, /* region 32 */
- { { 1, 60, 60 }, -6453, 23197, 432, 582, 63, 30 }, /* region 33 */
- { { 1, 61, 61 }, -6853, 16422, 432, 582, 63, 30 }, /* region 34 */
- { { 1, 62, 62 }, -7253, 20675, 432, 582, 63, 31 }, /* region 35 */
- { { 1, 63, 63 }, -7353, 23197, 432, 582, 63, 32 }, /* region 36 */
- { { 1, 64, 64 }, -7953, 23197, 432, 582, 63, 33 }, /* region 37 */
- { { 0, 65, 65 }, -7555, 32767, 0, 0, 14, 34 }, /* region 38 */
- { { 0, 66, 66 }, -7955, 20675, 0, 0, 14, 34 }, /* region 39 */
- { { 512, 67, 67 }, -7155, 18426, 0, 0, 90, 35 }, /* region 40 */
- { { 512, 68, 68 }, -7755, 18426, 0, 0, 90, 35 }, /* region 41 */
- { { 0, 69, 69 }, -7755, 32767, 0, 0, 86, 36 }, /* region 42 */
- { { 0, 70, 70 }, -6855, 21900, 0, 0, 86, 37 }, /* region 43 */
- { { 769, 71, 71 }, -6355, 23197, 0, 1226, 35, 38 }, /* region 44 */
- { { 769, 72, 72 }, -6955, 26028, 0, 1226, 35, 38 }, /* region 45 */
- { { 1024, 73, 73 }, -7955, 32767, 0, 0, 22, 39 }, /* region 46 */
- { { 1024, 74, 74 }, -8455, 32767, 0, 0, 22, 40 }, /* region 47 */
- { { 1, 75, 75 }, -7900, 23197, 0, 31, 139, 41 }, /* region 48 */
- { { 0, 76, 76 }, -10455, 23197, 0, 0, 134, 42 }, /* region 49 */
- { { 0, 77, 77 }, -10055, 23197, 0, 0, 134, 43 }, /* region 50 */
- { { 0, 78, 78 }, -8853, 16422, 0, 0, 89, 44 }, /* region 51 */
- { { 0, 79, 79 }, -10253, 16422, 0, 0, 89, 45 }, /* region 52 */
- { { 1281, 80, 80 }, -6300, 13045, 209, 230, 103, 46 }, /* region 53 */
- { { 1281, 81, 81 }, -6400, 16422, 209, 230, 103, 47 }, /* region 54 */
- { { 0, 82, 82 }, -8455, 20675, 0, 0, 87, 48 }, /* region 55 */
- { { 0, 83, 83 }, -8900, 32767, 0, 0, 13, 49 }, /* region 56 */
- { { 1, 84, 84 }, -8400, 23197, 0, 10294, 5, 50 }, /* region 57 */
- { { 0, 85, 85 }, -9655, 32767, 0, 0, 135, 4 }, /* region 58 */
- { { 0, 86, 86 }, -9068, 16422, 0, 0, 24, 51 }, /* region 59 */
- { { 32769, 87, 87 }, -9168, 32767, 1335, 1603, 24, 52 }, /* region 60 */
- { { 1, 12, 67 }, -6605, 23197, 437, 16584, 2, 48 }, /* region 61 */
- { { 1, 68, 73 }, -7196, 23197, 452, 16803, 0, 48 }, /* region 62 */
- { { 32769, 74, 108 }, -8467, 23197, 404, 16698, 1, 48 }, /* region 63 */
- { { 1, 12, 78 }, -6605, 16422, 437, 16584, 2, 48 }, /* region 64 */
- { { 1, 79, 91 }, -7196, 16422, 452, 16803, 0, 48 }, /* region 65 */
- { { 32769, 92, 108 }, -8467, 16422, 404, 16698, 1, 48 }, /* region 66 */
- { { 1, 12, 78 }, -6605, 16422, 437, 16584, 2, 48 }, /* region 67 */
- { { 1, 79, 91 }, -7196, 16422, 452, 16803, 0, 48 }, /* region 68 */
- { { 32769, 92, 108 }, -8467, 16422, 404, 16698, 1, 48 }, /* region 69 */
- { { 1, 12, 70 }, -6600, 23197, 437, 16584, 2, 48 }, /* region 70 */
- { { 1, 71, 88 }, -7191, 23197, 452, 16803, 0, 48 }, /* region 71 */
- { { 32769, 89, 108 }, -8462, 23197, 404, 16698, 1, 48 }, /* region 72 */
- { { 1, 12, 54 }, -5956, 13045, 639, 4368, 10, 48 }, /* region 73 */
- { { 32769, 55, 108 }, -6351, 18426, 702, 3112, 12, 48 }, /* region 74 */
- { { 1, 12, 66 }, -6611, 23197, 437, 16584, 2, 48 }, /* region 75 */
- { { 1, 67, 87 }, -7202, 23197, 452, 16803, 0, 48 }, /* region 76 */
- { { 32769, 88, 108 }, -8473, 16422, 404, 16698, 1, 48 }, /* region 77 */
- { { 1, 12, 43 }, -3055, 23197, 920, 1383, 30, 59 }, /* region 78 */
- { { 32769, 44, 96 }, -5060, 18426, 885, 1176, 37, 59 }, /* region 79 */
- { { 1, 12, 48 }, -3461, 18426, 1148, 1514, 26, 60 }, /* region 80 */
- { { 32769, 49, 96 }, -6253, 16422, 1347, 1420, 29, 60 }, /* region 81 */
- { { 1, 33, 56 }, -5600, 26028, 1064, 1170, 38, 61 }, /* region 82 */
- { { 1, 57, 72 }, -6000, 26028, 930, 1014, 44, 61 }, /* region 83 */
- { { 32769, 73, 108 }, -7600, 26028, 726, 826, 52, 61 }, /* region 84 */
- { { 1, 36, 96 }, -7600, 20675, 635, 735, 58, 62 }, /* region 85 */
- { { 32769, 97, 108 }, -10108, 13045, 0, 31, 139, 62 }, /* region 86 */
- { { 1, 36, 96 }, -7600, 14636, 635, 735, 58, 0 }, /* region 87 */
- { { 32769, 97, 108 }, -10108, 13045, 0, 31, 139, 0 }, /* region 88 */
- { { 1, 36, 83 }, -6006, 13045, 838, 922, 47, 63 }, /* region 89 */
- { { 1, 84, 93 }, -8406, 14636, 209, 230, 103, 63 }, /* region 90 */
- { { 32769, 94, 108 }, -10108, 13045, 0, 31, 139, 63 }, /* region 91 */
- { { 1, 36, 83 }, -6006, 13045, 838, 922, 47, 64 }, /* region 92 */
- { { 1, 84, 93 }, -8406, 13045, 209, 230, 103, 64 }, /* region 93 */
- { { 32769, 94, 108 }, -10108, 13045, 0, 31, 139, 64 }, /* region 94 */
- { { 1, 21, 56 }, -5595, 23197, 1064, 1170, 38, 65 }, /* region 95 */
- { { 1, 57, 72 }, -5995, 23197, 930, 1014, 44, 65 }, /* region 96 */
- { { 32769, 73, 108 }, -7598, 23197, 726, 826, 52, 65 }, /* region 97 */
- { { 1, 12, 83 }, -6006, 16422, 838, 922, 47, 66 }, /* region 98 */
- { { 1, 84, 93 }, -8406, 16422, 209, 230, 103, 66 }, /* region 99 */
- { { 32769, 94, 108 }, -10108, 16422, 0, 31, 139, 66 }, /* region 100 */
- { { 1, 24, 83 }, -6006, 16422, 838, 922, 47, 67 }, /* region 101 */
- { { 1, 84, 93 }, -8406, 16422, 209, 230, 103, 67 }, /* region 102 */
- { { 32769, 94, 108 }, -10108, 16422, 0, 31, 139, 67 }, /* region 103 */
- { { 1, 12, 83 }, -6020, 16422, 0, 83, 126, 68 }, /* region 104 */
- { { 1, 84, 90 }, -8482, 16422, 0, 20, 145, 68 }, /* region 105 */
- { { 32769, 91, 108 }, -9101, 16422, 6, 20, 147, 68 }, /* region 106 */
- { { 1, 21, 75 }, -7241, 16422, 419, 460, 76, 69 }, /* region 107 */
- { { 32769, 76, 108 }, -9690, 14636, 254, 264, 101, 69 }, /* region 108 */
- { { 32769, 36, 84 }, -7755, 16422, 0, 2775, 17, 70 }, /* region 109 */
- { { 32769, 12, 108 }, -6655, 23197, 30, 276, 100, 71 }, /* region 110 */
- { { 0, 12, 60 }, -7914, 26028, 0, 0, 15, 72 }, /* region 111 */
- { { 32768, 61, 96 }, -7914, 26028, 0, 0, 15, 73 }, /* region 112 */
- { { 1, 12, 65 }, -7053, 16422, 23, 10953, 4, 74 }, /* region 113 */
- { { 32769, 66, 108 }, -7755, 20675, 11, 11753, 3, 74 }, /* region 114 */
- { { 1, 12, 35 }, -5355, 16422, 2869, 3778, 11, 75 }, /* region 115 */
- { { 1, 36, 48 }, -6555, 20675, 2869, 3778, 11, 75 }, /* region 116 */
- { { 32769, 49, 72 }, -6555, 20675, 2869, 3778, 11, 76 }, /* region 117 */
- { { 1, 16, 55 }, -6224, 20675, 1045, 1119, 41, 77 }, /* region 118 */
- { { 32769, 56, 96 }, -6718, 20675, 907, 963, 46, 77 }, /* region 119 */
- { { 1, 16, 53 }, -5994, 29204, 1140, 1479, 27, 78 }, /* region 120 */
- { { 1, 54, 70 }, -7171, 29204, 726, 812, 55, 78 }, /* region 121 */
- { { 32769, 71, 108 }, -7788, 29204, 718, 748, 56, 78 }, /* region 122 */
- { { 1, 12, 65 }, -7053, 16422, 23, 10953, 4, 79 }, /* region 123 */
- { { 32769, 66, 108 }, -7755, 20675, 11, 11753, 3, 79 }, /* region 124 */
- { { 1, 16, 54 }, -5727, 20675, 5362, 5461, 9, 80 }, /* region 125 */
- { { 1, 55, 63 }, -5851, 26028, 1362, 1454, 28, 80 }, /* region 126 */
- { { 32769, 64, 108 }, -6744, 16422, 311, 366, 88, 80 }, /* region 127 */
- { { 1, 16, 48 }, -4798, 20675, 1132, 1301, 31, 81 }, /* region 128 */
- { { 32769, 49, 108 }, -5988, 20675, 1099, 1184, 36, 81 }, /* region 129 */
- { { 1, 21, 68 }, -8458, 20675, 87, 2170, 18, 82 }, /* region 130 */
- { { 1, 69, 82 }, -8960, 20675, 120, 2167, 19, 82 }, /* region 131 */
- { { 32769, 83, 108 }, -10160, 20675, 376, 2041, 20, 82 }, /* region 132 */
- { { 1, 12, 65 }, -7053, 16422, 23, 10953, 4, 83 }, /* region 133 */
- { { 32769, 66, 108 }, -7755, 20675, 11, 11753, 3, 83 }, /* region 134 */
- { { 32769, 55, 108 }, -7368, 20675, 0, 477, 75, 84 }, /* region 135 */
- { { 32769, 36, 96 }, -6900, 14636, 101, 151, 116, 85 }, /* region 136 */
- { { 1, 24, 83 }, -6020, 13045, 0, 83, 126, 86 }, /* region 137 */
- { { 1, 84, 90 }, -8482, 13045, 0, 20, 145, 86 }, /* region 138 */
- { { 32769, 91, 108 }, -9101, 13045, 6, 20, 147, 86 }, /* region 139 */
- { { 1, 12, 65 }, -7053, 16422, 23, 10953, 4, 87 }, /* region 140 */
- { { 32769, 66, 108 }, -7755, 20675, 11, 11753, 3, 87 }, /* region 141 */
- { { 1, 12, 65 }, -7053, 16422, 23, 10953, 4, 88 }, /* region 142 */
- { { 32769, 66, 108 }, -7755, 20675, 11, 11753, 3, 88 }, /* region 143 */
- { { 1, 12, 65 }, -7053, 16422, 23, 10953, 4, 89 }, /* region 144 */
- { { 32769, 66, 108 }, -7755, 20675, 11, 11753, 3, 89 }, /* region 145 */
- { { 1, 24, 83 }, -6020, 13045, 0, 83, 126, 90 }, /* region 146 */
- { { 1, 84, 90 }, -8482, 13045, 0, 20, 145, 90 }, /* region 147 */
- { { 32769, 91, 108 }, -9101, 13045, 6, 20, 147, 90 }, /* region 148 */
- { { 1, 12, 65 }, -7053, 16422, 23, 10953, 4, 91 }, /* region 149 */
- { { 32769, 66, 108 }, -7755, 20675, 11, 11753, 3, 91 }, /* region 150 */
- { { 1, 12, 65 }, -7053, 16422, 23, 10953, 4, 92 }, /* region 151 */
- { { 32769, 66, 108 }, -7755, 20675, 11, 11753, 3, 92 }, /* region 152 */
- { { 1, 12, 62 }, -7053, 16422, 23, 10953, 4, 93 }, /* region 153 */
- { { 32769, 63, 108 }, -7755, 20675, 11, 11753, 3, 93 }, /* region 154 */
- { { 1, 12, 62 }, -7053, 16422, 23, 10953, 4, 94 }, /* region 155 */
- { { 32769, 63, 108 }, -7755, 16422, 11, 11753, 3, 94 }, /* region 156 */
- { { 1, 24, 79 }, -6020, 13045, 0, 83, 126, 95 }, /* region 157 */
- { { 1, 80, 90 }, -8482, 13045, 0, 20, 145, 95 }, /* region 158 */
- { { 32769, 91, 108 }, -9101, 13045, 6, 20, 147, 95 }, /* region 159 */
- { { 1, 12, 65 }, -7053, 13045, 23, 10953, 4, 96 }, /* region 160 */
- { { 32769, 66, 108 }, -7755, 16422, 11, 11753, 3, 96 }, /* region 161 */
- { { 32768, 36, 84 }, -7500, 20675, 0, 0, 25, 97 }, /* region 162 */
- { { 32769, 36, 96 }, -8855, 20675, 1482, 1613, 23, 98 }, /* region 163 */
- { { 32769, 12, 96 }, -4366, 32767, 818, 1033, 42, 99 }, /* region 164 */
- { { 32769, 36, 84 }, -8568, 18426, 0, 293, 98, 100 }, /* region 165 */
- { { 32769, 12, 96 }, -6020, 26028, 0, 83, 125, 101 }, /* region 166 */
- { { 32769, 12, 96 }, -6020, 20675, 0, 83, 125, 102 }, /* region 167 */
- { { 1, 12, 83 }, -6020, 13045, 0, 83, 125, 104 }, /* region 168 */
- { { 1, 84, 90 }, -8482, 13045, 0, 20, 146, 104 }, /* region 169 */
- { { 32769, 91, 108 }, -9101, 13045, 6, 20, 148, 104 }, /* region 170 */
- { { 32769, 36, 108 }, -8570, 32767, 472, 491, 74, 105 }, /* region 171 */
- { { 32769, 36, 108 }, -8570, 20675, 472, 491, 74, 106 }, /* region 172 */
- { { 1, 12, 72 }, -6012, 7336, 2, 86, 124, 107 }, /* region 173 */
- { { 1, 73, 101 }, -8500, 8231, 2, 22, 143, 107 }, /* region 174 */
- { { 32769, 102, 108 }, -9683, 20675, 173, 183, 110, 107 }, /* region 175 */
- { { 1, 21, 96 }, -7768, 13045, 477, 507, 73, 108 }, /* region 176 */
- { { 32769, 97, 108 }, -9683, 13045, 173, 183, 110, 109 }, /* region 177 */
- { { 32769, 12, 108 }, -7771, 16422, 477, 507, 73, 110 }, /* region 178 */
- { { 1, 12, 53 }, -4971, 16422, 388, 541, 68, 111 }, /* region 179 */
- { { 32769, 54, 60 }, -5949, 11626, 473, 560, 65, 111 }, /* region 180 */
- { { 32769, 36, 72 }, -5949, 16422, 473, 560, 65, 112 }, /* region 181 */
- { { 1, 48, 58 }, -7053, 16422, 356, 402, 82, 113 }, /* region 182 */
- { { 1, 59, 65 }, -7574, 16422, 514, 548, 67, 113 }, /* region 183 */
- { { 1, 66, 78 }, -8174, 16422, 505, 529, 71, 113 }, /* region 184 */
- { { 32769, 79, 96 }, -9233, 16422, 178, 191, 109, 113 }, /* region 185 */
- { { 1, 55, 60 }, -7053, 16422, 356, 402, 82, 114 }, /* region 186 */
- { { 1, 61, 69 }, -7574, 16422, 514, 548, 67, 114 }, /* region 187 */
- { { 1, 70, 79 }, -8174, 16422, 505, 529, 71, 114 }, /* region 188 */
- { { 32769, 80, 108 }, -9233, 16422, 178, 191, 109, 114 }, /* region 189 */
- { { 1, 16, 82 }, -8029, 23197, 180, 206, 106, 115 }, /* region 190 */
- { { 32769, 83, 108 }, -7240, 18426, 3, 44, 131, 115 }, /* region 191 */
- { { 32769, 21, 108 }, -8869, 20675, 483, 515, 72, 116 }, /* region 192 */
- { { 1, 21, 89 }, -7205, 18426, 3, 45, 130, 117 }, /* region 193 */
- { { 32769, 90, 108 }, -9101, 10362, 6, 20, 148, 117 }, /* region 194 */
- { { 1, 21, 42 }, -4686, 20675, 0, 180, 111, 118 }, /* region 195 */
- { { 1, 43, 51 }, -5286, 23197, 0, 127, 120, 118 }, /* region 196 */
- { { 1, 52, 58 }, -6292, 26028, 0, 71, 127, 118 }, /* region 197 */
- { { 1, 59, 68 }, -7468, 23197, 0, 36, 136, 118 }, /* region 198 */
- { { 32769, 69, 108 }, -8574, 20675, 0, 19, 149, 118 }, /* region 199 */
- { { 1, 21, 89 }, -7199, 20675, 3, 45, 130, 119 }, /* region 200 */
- { { 32769, 90, 108 }, -9101, 14636, 6, 20, 148, 119 }, /* region 201 */
- { { 1, 21, 46 }, -5651, 26028, 236, 340, 92, 120 }, /* region 202 */
- { { 1, 47, 71 }, -6563, 20675, 824, 885, 49, 120 }, /* region 203 */
- { { 1, 72, 88 }, -7907, 18426, 719, 747, 57, 120 }, /* region 204 */
- { { 1, 89, 93 }, -8876, 16422, 83, 99, 122, 120 }, /* region 205 */
- { { 32769, 94, 108 }, -9689, 16422, 173, 183, 110, 120 }, /* region 206 */
- { { 1, 60, 71 }, -7205, 16422, 0, 42, 132, 121 }, /* region 207 */
- { { 1, 72, 78 }, -7903, 16422, 0, 28, 141, 121 }, /* region 208 */
- { { 32769, 79, 96 }, -8405, 16422, 0, 21, 144, 121 }, /* region 209 */
- { { 1, 48, 65 }, -6316, 11626, 0, 70, 128, 122 }, /* region 210 */
- { { 1, 66, 79 }, -7724, 14636, 0, 31, 138, 122 }, /* region 211 */
- { { 32769, 80, 96 }, -8030, 11626, 0, 26, 142, 122 }, /* region 212 */
- { { 1, 16, 44 }, -5868, 14636, 163, 254, 102, 123 }, /* region 213 */
- { { 1, 45, 51 }, -6418, 16422, 261, 393, 85, 123 }, /* region 214 */
- { { 1, 52, 58 }, -7333, 18426, 190, 229, 104, 123 }, /* region 215 */
- { { 1, 59, 66 }, -8100, 18426, 168, 193, 108, 123 }, /* region 216 */
- { { 1, 67, 70 }, -8576, 18426, 138, 157, 115, 123 }, /* region 217 */
- { { 1, 71, 80 }, -9103, 18426, 166, 180, 112, 123 }, /* region 218 */
- { { 32769, 81, 108 }, -10074, 18426, 135, 151, 117, 123 }, /* region 219 */
- { { 32769, 12, 96 }, -5004, 23197, 570, 719, 59, 124 }, /* region 220 */
- { { 1, 12, 48 }, -5868, 14636, 163, 254, 102, 125 }, /* region 221 */
- { { 1, 49, 54 }, -6418, 16422, 261, 393, 85, 125 }, /* region 222 */
- { { 1, 55, 63 }, -7333, 18426, 190, 229, 104, 125 }, /* region 223 */
- { { 1, 64, 70 }, -8100, 18426, 168, 193, 108, 125 }, /* region 224 */
- { { 1, 71, 75 }, -8576, 18426, 138, 157, 115, 125 }, /* region 225 */
- { { 1, 76, 82 }, -9103, 18426, 166, 180, 112, 125 }, /* region 226 */
- { { 32769, 83, 108 }, -10074, 18426, 135, 151, 117, 125 }, /* region 227 */
- { { 32770, 36, 84 }, -7200, 29204, 0, 0, 0, 126 }, /* region 228 */
- { { 32770, 36, 84 }, -7600, 8231, 0, 0, 0, 127 }, /* region 229 */
- { { 32770, 36, 84 }, -7200, 20675, 0, 0, 0, 128 }, /* region 230 */
- { { 32769, 36, 84 }, -6000, -24285, 1294, 5778, 8, 129 }, /* region 231 */
- { { 32769, 36, 84 }, -6555, 29204, 798, 993, 45, 130 }, /* region 232 */
- { { 32769, 36, 84 }, -6855, 20675, 798, 993, 45, 131 }, /* region 233 */
- { { 32769, 36, 84 }, -7755, 29204, 798, 993, 45, 132 }, /* region 234 */
- { { 32768, 36, 84 }, -8155, 32767, 0, 0, 133, 133 }, /* region 235 */
- { { 32768, 36, 84 }, -6555, 20675, 0, 0, 91, 134 }, /* region 236 */
- { { 1, 24, 62 }, -7000, 23197, 286, 333, 94, 135 }, /* region 237 */
- { { 1, 63, 66 }, -7364, 26028, 297, 335, 93, 135 }, /* region 238 */
- { { 1, 67, 72 }, -7722, 23197, 368, 399, 84, 135 }, /* region 239 */
- { { 32769, 73, 96 }, -8310, 23197, 116, 138, 119, 135 }, /* region 240 */
- { { 1, 24, 48 }, -5141, 23197, 309, 447, 77, 136 }, /* region 241 */
- { { 1, 49, 56 }, -6266, 26028, 211, 283, 99, 136 }, /* region 242 */
- { { 1, 57, 63 }, -7000, 26028, 286, 333, 94, 136 }, /* region 243 */
- { { 32769, 64, 84 }, -7722, 23197, 368, 399, 84, 136 }, /* region 244 */
- { { 1, 24, 56 }, -6266, 29204, 211, 283, 99, 137 }, /* region 245 */
- { { 1, 57, 63 }, -7000, 29204, 286, 333, 94, 137 }, /* region 246 */
- { { 1, 64, 69 }, -7722, 29204, 368, 399, 84, 137 }, /* region 247 */
- { { 32769, 70, 96 }, -8310, 29204, 116, 138, 119, 137 }, /* region 248 */
- { { 1, 24, 68 }, -7722, 18426, 368, 399, 84, 138 }, /* region 249 */
- { { 1, 69, 76 }, -8310, 26028, 116, 138, 119, 138 }, /* region 250 */
- { { 32769, 77, 108 }, -8758, 23197, 127, 144, 118, 138 }, /* region 251 */
- { { 1, 24, 82 }, -7613, 23197, 389, 422, 80, 139 }, /* region 252 */
- { { 32769, 83, 108 }, -8764, 26028, 146, 163, 114, 139 }, /* region 253 */
- { { 1, 12, 58 }, -6898, 29204, 386, 436, 78, 140 }, /* region 254 */
- { { 32769, 59, 96 }, -7371, 26028, 290, 328, 95, 140 }, /* region 255 */
- { { 1, 12, 58 }, -6898, 16422, 386, 436, 78, 141 }, /* region 256 */
- { { 32769, 59, 96 }, -7371, 18426, 290, 328, 95, 141 }, /* region 257 */
- { { 1, 12, 48 }, -6898, -28771, 386, 436, 78, 142 }, /* region 258 */
- { { 32769, 49, 84 }, -7371, 29204, 290, 328, 95, 142 }, /* region 259 */
- { { 1, 12, 60 }, -5453, 20675, 314, 430, 79, 143 }, /* region 260 */
- { { 32769, 61, 84 }, -6553, 18426, 263, 324, 96, 143 }, /* region 261 */
- { { 1, 24, 60 }, -6553, 16422, 263, 324, 96, 144 }, /* region 262 */
- { { 1, 61, 70 }, -7669, 20675, 279, 311, 97, 144 }, /* region 263 */
- { { 32769, 71, 96 }, -8098, 23197, 179, 204, 107, 144 }, /* region 264 */
- { { 1, 24, 84 }, -8483, 20675, 191, 211, 105, 145 }, /* region 265 */
- { { 32769, 85, 108 }, -9683, 20675, 92, 102, 121, 145 }, /* region 266 */
- { { 1, 21, 69 }, -6553, 13045, 263, 324, 96, 146 }, /* region 267 */
- { { 1, 70, 94 }, -7669, 20675, 279, 311, 97, 146 }, /* region 268 */
- { { 1, 95, 96 }, -8098, -24285, 179, 204, 107, 146 }, /* region 269 */
- { { 32769, 97, 108 }, -9683, -24285, 173, 183, 110, 146 }, /* region 270 */
- { { 1, 16, 55 }, -8100, 20675, 168, 193, 108, 147 }, /* region 271 */
- { { 1, 56, 74 }, -8576, 26028, 138, 157, 115, 147 }, /* region 272 */
- { { 32769, 75, 96 }, -10074, 26028, 135, 151, 117, 147 }, /* region 273 */
- { { 1, 24, 72 }, -8098, 26028, 179, 204, 107, 148 }, /* region 274 */
- { { 1, 73, 85 }, -8483, 20675, 191, 211, 105, 148 }, /* region 275 */
- { { 32769, 86, 108 }, -9683, 18426, 92, 102, 121, 148 }, /* region 276 */
- { { 32769, 36, 108 }, -7730, 18426, 1839, 1901, 21, 149 }, /* region 277 */
- { { 32769, 24, 108 }, -7273, 20675, 494, 534, 69, 150 }, /* region 278 */
- { { 32769, 12, 108 }, -7273, 20675, 494, 534, 69, 151 }, /* region 279 */
- { { 32769, 24, 108 }, -7273, 20675, 494, 534, 69, 152 }, /* region 280 */
- { { 1, 36, 60 }, -4900, 5193, 2, 22, 143, 153 }, /* region 281 */
- { { 32769, 61, 84 }, -6083, 20675, 173, 183, 110, 153 }, /* region 282 */
- { { 32769, 24, 96 }, -6553, 14636, 263, 324, 96, 154 }, /* region 283 */
- { { 32769, 36, 96 }, -7730, 26028, 1839, 1901, 21, 155 }, /* region 284 */
- { { 32769, 24, 108 }, -7273, 20675, 494, 534, 69, 156 }, /* region 285 */
- { { 1, 24, 58 }, -7851, 14636, 0, 29, 140, 157 }, /* region 286 */
- { { 32769, 59, 96 }, -7851, 14636, 0, 29, 140, 157 }, /* region 287 */
- { { 1, 12, 83 }, -6020, 13045, 0, 83, 125, 158 }, /* region 288 */
- { { 1, 84, 90 }, -8482, 13045, 0, 20, 146, 158 }, /* region 289 */
- { { 32769, 91, 108 }, -9101, 13045, 6, 20, 148, 158 }, /* region 290 */
- { { 1, 21, 42 }, -4663, 26028, 1047, 1229, 34, 159 }, /* region 291 */
- { { 1, 43, 48 }, -5456, 29204, 1138, 1253, 33, 159 }, /* region 292 */
- { { 1, 49, 53 }, -5845, 26028, 559, 651, 60, 159 }, /* region 293 */
- { { 1, 54, 60 }, -6732, 26028, 508, 563, 64, 159 }, /* region 294 */
- { { 1, 61, 65 }, -7080, 32767, 819, 864, 51, 159 }, /* region 295 */
- { { 1, 66, 70 }, -6866, 26942, 981, 1032, 43, 159 }, /* region 296 */
- { { 1, 71, 76 }, -8166, 26028, 790, 814, 54, 159 }, /* region 297 */
- { { 1, 77, 82 }, -8766, 26028, 592, 609, 61, 159 }, /* region 298 */
- { { 1, 83, 87 }, -9517, 23197, 543, 554, 66, 159 }, /* region 299 */
- { { 1, 88, 96 }, -10071, 18426, 601, 609, 62, 159 }, /* region 300 */
- { { 32769, 97, 108 }, -10566, 18426, 523, 529, 70, 159 }, /* region 301 */
- { { 1, 48, 69 }, -6313, 14636, 0, 70, 128, 160 }, /* region 302 */
- { { 1, 70, 79 }, -7724, 18426, 0, 31, 138, 160 }, /* region 303 */
- { { 32769, 80, 96 }, -8030, 14636, 0, 26, 142, 160 }, /* region 304 */
- { { 1, 36, 72 }, -7134, 29204, 0, 87, 123, 161 }, /* region 305 */
- { { 32769, 73, 96 }, -7960, 29204, 0, 54, 129, 161 }, /* region 306 */
- { { 32769, 36, 96 }, -7730, 26028, 1839, 1901, 21, 162 }, /* region 307 */
- { { 32769, 12, 96 }, -4372, 32767, 818, 1033, 42, 163 }, /* region 308 */
- { { 32769, 36, 108 }, -8570, 26028, 472, 491, 74, 164 }, /* region 309 */
- { { 32769, 12, 96 }, -5004, 29204, 570, 719, 59, 165 }, /* region 310 */
- { { 1, 12, 83 }, -6020, 13045, 0, 83, 125, 166 }, /* region 311 */
- { { 1, 84, 90 }, -8482, 13045, 0, 20, 146, 166 }, /* region 312 */
- { { 32769, 91, 108 }, -9101, 13045, 6, 20, 148, 166 }, /* region 313 */
- { { 1, 21, 46 }, -5651, 32767, 236, 340, 92, 167 }, /* region 314 */
- { { 1, 47, 75 }, -6563, 26028, 824, 885, 49, 167 }, /* region 315 */
- { { 1, 76, 84 }, -7907, 23197, 719, 747, 57, 167 }, /* region 316 */
- { { 1, 85, 93 }, -8876, 20675, 83, 99, 122, 167 }, /* region 317 */
- { { 32769, 94, 108 }, -9689, 20675, 173, 183, 110, 167 }, /* region 318 */
- { { 1, 21, 46 }, -5651, 26028, 236, 340, 92, 168 }, /* region 319 */
- { { 1, 47, 71 }, -6563, 20675, 824, 885, 49, 168 }, /* region 320 */
- { { 1, 72, 88 }, -7907, 18426, 719, 747, 57, 168 }, /* region 321 */
- { { 1, 89, 93 }, -8876, 16422, 83, 99, 122, 168 }, /* region 322 */
- { { 32769, 94, 108 }, -9689, 16422, 173, 183, 110, 168 }, /* region 323 */
- { { 1, 21, 45 }, -4663, 26028, 1047, 1229, 34, 169 }, /* region 324 */
- { { 1, 46, 51 }, -5456, 29204, 1138, 1253, 33, 169 }, /* region 325 */
- { { 1, 52, 54 }, -5845, 26028, 559, 651, 60, 169 }, /* region 326 */
- { { 1, 55, 63 }, -6732, 26028, 508, 563, 64, 169 }, /* region 327 */
- { { 1, 64, 68 }, -7080, 32767, 819, 864, 51, 169 }, /* region 328 */
- { { 1, 69, 73 }, -6866, 26942, 981, 1032, 43, 169 }, /* region 329 */
- { { 1, 74, 79 }, -8166, 26028, 790, 814, 54, 169 }, /* region 330 */
- { { 1, 80, 88 }, -8766, 23197, 592, 609, 61, 169 }, /* region 331 */
- { { 1, 89, 99 }, -10071, 18426, 601, 609, 62, 169 }, /* region 332 */
- { { 32769, 100, 108 }, -10566, 18426, 523, 529, 70, 169 }, /* region 333 */
- { { 1, 21, 45 }, -4663, 26028, 1047, 1229, 34, 170 }, /* region 334 */
- { { 1, 46, 51 }, -5456, 29204, 1138, 1253, 33, 170 }, /* region 335 */
- { { 1, 52, 54 }, -5845, 26028, 559, 651, 60, 170 }, /* region 336 */
- { { 1, 55, 63 }, -6732, 26028, 508, 563, 64, 170 }, /* region 337 */
- { { 1, 64, 68 }, -7080, 32767, 819, 864, 51, 170 }, /* region 338 */
- { { 1, 69, 73 }, -6866, 26942, 981, 1032, 43, 170 }, /* region 339 */
- { { 1, 74, 79 }, -8166, 26028, 790, 814, 54, 170 }, /* region 340 */
- { { 1, 80, 88 }, -8766, 23197, 592, 609, 61, 170 }, /* region 341 */
- { { 1, 89, 99 }, -10071, 18426, 601, 609, 62, 171 }, /* region 342 */
- { { 32769, 100, 108 }, -10566, 18426, 523, 529, 70, 172 }, /* region 343 */
- { { 32769, 36, 108 }, -8570, 20675, 472, 491, 74, 173 }, /* region 344 */
- { { 32769, 12, 108 }, -7730, 20675, 1839, 1901, 21, 174 }, /* region 345 */
- { { 1, 12, 44 }, -5868, 18426, 163, 254, 102, 175 }, /* region 346 */
- { { 1, 45, 51 }, -6418, 20675, 261, 393, 85, 175 }, /* region 347 */
- { { 1, 52, 58 }, -7333, 23197, 190, 229, 104, 175 }, /* region 348 */
- { { 1, 59, 66 }, -8100, 23197, 168, 193, 108, 175 }, /* region 349 */
- { { 1, 67, 70 }, -8576, 23197, 138, 157, 115, 175 }, /* region 350 */
- { { 1, 71, 80 }, -9103, 23197, 166, 180, 112, 175 }, /* region 351 */
- { { 32769, 81, 108 }, -10074, 23197, 135, 151, 117, 175 }, /* region 352 */
- { { 1, 12, 65 }, -7053, 16422, 23, 10953, 4, 176 }, /* region 353 */
- { { 32769, 66, 108 }, -7755, 20675, 11, 11753, 3, 176 }, /* region 354 */
- { { 1, 12, 48 }, -4798, 29204, 1132, 1301, 31, 177 }, /* region 355 */
- { { 32769, 49, 108 }, -5988, 29204, 1099, 1184, 36, 177 }, /* region 356 */
- { { 1, 12, 83 }, -7241, 20675, 419, 460, 76, 178 }, /* region 357 */
- { { 32769, 84, 108 }, -10123, 20675, 0, 31, 139, 178 }, /* region 358 */
- { { 1, 55, 60 }, -7053, 18426, 356, 402, 82, 179 }, /* region 359 */
- { { 1, 61, 69 }, -7574, 18426, 514, 548, 67, 179 }, /* region 360 */
- { { 1, 70, 79 }, -8174, 18426, 505, 529, 71, 179 }, /* region 361 */
- { { 32769, 80, 108 }, -9233, 23197, 178, 191, 109, 179 }, /* region 362 */
- { { 32769, 36, 96 }, -7730, -24285, 1839, 1901, 21, 180 }, /* region 363 */
- { { 1, 12, 83 }, -6006, 16422, 838, 922, 47, 181 }, /* region 364 */
- { { 1, 84, 93 }, -8406, 18426, 209, 230, 103, 181 }, /* region 365 */
- { { 32769, 94, 108 }, -10108, 16422, 0, 31, 139, 181 }, /* region 366 */
- { { 1, 12, 56 }, -5595, 23197, 1064, 1170, 38, 182 }, /* region 367 */
- { { 1, 57, 72 }, -5995, 23197, 930, 1014, 44, 182 }, /* region 368 */
- { { 32769, 73, 108 }, -7598, 23197, 726, 826, 52, 182 }, /* region 369 */
- { { 32769, 24, 108 }, -7600, 23197, 635, 735, 58, 62 }, /* region 370 */
- { { 1, 36, 83 }, -6006, 13045, 838, 922, 47, 183 }, /* region 371 */
- { { 1, 84, 93 }, -8406, 13045, 209, 230, 103, 183 }, /* region 372 */
- { { 32769, 94, 108 }, -10108, 13045, 0, 31, 139, 183 }, /* region 373 */
- { { 1, 12, 66 }, -6611, 23197, 437, 16584, 2, 184 }, /* region 374 */
- { { 1, 67, 87 }, -7202, 23197, 452, 16803, 0, 184 }, /* region 375 */
- { { 32769, 88, 108 }, -8473, 16422, 404, 16698, 1, 184 } /* region 376 */
+ { { 0, 27, 27 }, -2868, 16422, 0, 0, 81, 0 }, /* region 0 */
+ { { 0, 28, 28 }, -3568, 32767, 0, 0, 40, 0 }, /* region 1 */
+ { { 0, 29, 29 }, -4553, 32767, 0, 0, 32, 1 }, /* region 2 */
+ { { 0, 30, 30 }, -4853, 32767, 0, 0, 32, 2 }, /* region 3 */
+ { { 0, 31, 31 }, -3868, 23197, 0, 0, 48, 3 }, /* region 4 */
+ { { 1536, 32, 32 }, -3200, 20675, 0, 0, 137, 4 }, /* region 5 */
+ { { 1537, 33, 33 }, -3703, 20675, 792, 879, 50, 5 }, /* region 6 */
+ { { 1537, 34, 34 }, -3803, 16422, 792, 879, 50, 6 }, /* region 7 */
+ { { 0, 35, 35 }, -4968, 32767, 0, 0, 83, 7 }, /* region 8 */
+ { { 0, 36, 36 }, -4968, 32767, 0, 0, 83, 7 }, /* region 9 */
+ { { 0, 37, 37 }, -4051, 18426, 0, 0, 53, 8 }, /* region 10 */
+ { { 0, 38, 38 }, -4151, 23197, 0, 0, 16, 9 }, /* region 11 */
+ { { 0, 39, 39 }, -3568, 32767, 0, 0, 40, 10 }, /* region 12 */
+ { { 0, 40, 40 }, -4151, 23197, 0, 0, 16, 4 }, /* region 13 */
+ { { 1, 41, 41 }, -5855, 26028, 798, 993, 45, 11 }, /* region 14 */
+ { { 257, 42, 42 }, -4200, 26028, 4288, 7488, 7, 12 }, /* region 15 */
+ { { 1, 43, 43 }, -5755, 26028, 798, 993, 45, 13 }, /* region 16 */
+ { { 257, 44, 44 }, -4400, 26028, 4288, 7488, 7, 14 }, /* region 17 */
+ { { 1, 45, 45 }, -5755, 26028, 798, 993, 45, 15 }, /* region 18 */
+ { { 257, 46, 46 }, -4600, 26028, 4288, 7488, 7, 16 }, /* region 19 */
+ { { 1, 47, 47 }, -5455, 26028, 798, 993, 45, 17 }, /* region 20 */
+ { { 1, 48, 48 }, -5355, 26028, 798, 993, 45, 18 }, /* region 21 */
+ { { 1, 49, 49 }, -5200, 16422, 1294, 5778, 8, 19 }, /* region 22 */
+ { { 1, 50, 50 }, -5255, 26028, 798, 993, 45, 20 }, /* region 23 */
+ { { 1, 51, 51 }, -5268, 16422, 6592, 9921, 6, 21 }, /* region 24 */
+ { { 1, 52, 52 }, -5600, 32767, 1294, 5778, 8, 22 }, /* region 25 */
+ { { 1, 53, 53 }, -5418, 14636, 6592, 9921, 6, 23 }, /* region 26 */
+ { { 0, 54, 54 }, -5751, 26028, 0, 0, 39, 24 }, /* region 27 */
+ { { 1, 55, 55 }, -5300, 32767, 1294, 5778, 8, 25 }, /* region 28 */
+ { { 0, 56, 56 }, -7255, 32767, 0, 0, 90, 26 }, /* region 29 */
+ { { 1, 57, 57 }, -5700, 32767, 1294, 5778, 8, 27 }, /* region 30 */
+ { { 1, 58, 58 }, -7053, 23197, 0, 166, 113, 28 }, /* region 31 */
+ { { 1, 59, 59 }, -5968, 16422, 6592, 9921, 6, 29 }, /* region 32 */
+ { { 1, 60, 60 }, -6453, 23197, 432, 582, 63, 30 }, /* region 33 */
+ { { 1, 61, 61 }, -6853, 16422, 432, 582, 63, 30 }, /* region 34 */
+ { { 1, 62, 62 }, -7253, 20675, 432, 582, 63, 31 }, /* region 35 */
+ { { 1, 63, 63 }, -7353, 23197, 432, 582, 63, 32 }, /* region 36 */
+ { { 1, 64, 64 }, -7953, 23197, 432, 582, 63, 33 }, /* region 37 */
+ { { 0, 65, 65 }, -7555, 32767, 0, 0, 14, 34 }, /* region 38 */
+ { { 0, 66, 66 }, -7955, 20675, 0, 0, 14, 34 }, /* region 39 */
+ { { 512, 67, 67 }, -7155, 18426, 0, 0, 90, 35 }, /* region 40 */
+ { { 512, 68, 68 }, -7755, 18426, 0, 0, 90, 35 }, /* region 41 */
+ { { 0, 69, 69 }, -7755, 32767, 0, 0, 86, 36 }, /* region 42 */
+ { { 0, 70, 70 }, -6855, 21900, 0, 0, 86, 37 }, /* region 43 */
+ { { 769, 71, 71 }, -6355, 23197, 0, 1226, 35, 38 }, /* region 44 */
+ { { 769, 72, 72 }, -6955, 26028, 0, 1226, 35, 38 }, /* region 45 */
+ { { 1024, 73, 73 }, -7955, 32767, 0, 0, 22, 39 }, /* region 46 */
+ { { 1024, 74, 74 }, -8455, 32767, 0, 0, 22, 40 }, /* region 47 */
+ { { 1, 75, 75 }, -7900, 23197, 0, 31, 139, 41 }, /* region 48 */
+ { { 0, 76, 76 }, -10455, 23197, 0, 0, 134, 42 }, /* region 49 */
+ { { 0, 77, 77 }, -10055, 23197, 0, 0, 134, 43 }, /* region 50 */
+ { { 0, 78, 78 }, -8853, 16422, 0, 0, 89, 44 }, /* region 51 */
+ { { 0, 79, 79 }, -10253, 16422, 0, 0, 89, 45 }, /* region 52 */
+ { { 1281, 80, 80 }, -6300, 13045, 209, 230, 103, 46 }, /* region 53 */
+ { { 1281, 81, 81 }, -6400, 16422, 209, 230, 103, 47 }, /* region 54 */
+ { { 0, 82, 82 }, -8455, 20675, 0, 0, 87, 48 }, /* region 55 */
+ { { 0, 83, 83 }, -8900, 32767, 0, 0, 13, 49 }, /* region 56 */
+ { { 1, 84, 84 }, -8400, 23197, 0, 10294, 5, 50 }, /* region 57 */
+ { { 0, 85, 85 }, -9655, 32767, 0, 0, 135, 4 }, /* region 58 */
+ { { 0, 86, 86 }, -9068, 16422, 0, 0, 24, 51 }, /* region 59 */
+ { { 32769, 87, 87 }, -9168, 32767, 1335, 1603, 24, 52 }, /* region 60 */
+ { { 1, 12, 67 }, -6605, 23197, 437, 16584, 2, 48 }, /* region 61 */
+ { { 1, 68, 73 }, -7196, 23197, 452, 16803, 0, 48 }, /* region 62 */
+ { { 32769, 74, 108 }, -8467, 23197, 404, 16698, 1, 48 }, /* region 63 */
+ { { 1, 12, 78 }, -6605, 16422, 437, 16584, 2, 48 }, /* region 64 */
+ { { 1, 79, 91 }, -7196, 16422, 452, 16803, 0, 48 }, /* region 65 */
+ { { 32769, 92, 108 }, -8467, 16422, 404, 16698, 1, 48 }, /* region 66 */
+ { { 1, 12, 78 }, -6605, 16422, 437, 16584, 2, 48 }, /* region 67 */
+ { { 1, 79, 91 }, -7196, 16422, 452, 16803, 0, 48 }, /* region 68 */
+ { { 32769, 92, 108 }, -8467, 16422, 404, 16698, 1, 48 }, /* region 69 */
+ { { 1, 12, 70 }, -6600, 23197, 437, 16584, 2, 48 }, /* region 70 */
+ { { 1, 71, 88 }, -7191, 23197, 452, 16803, 0, 48 }, /* region 71 */
+ { { 32769, 89, 108 }, -8462, 23197, 404, 16698, 1, 48 }, /* region 72 */
+ { { 1, 12, 54 }, -5956, 13045, 639, 4368, 10, 48 }, /* region 73 */
+ { { 32769, 55, 108 }, -6351, 18426, 702, 3112, 12, 48 }, /* region 74 */
+ { { 1, 12, 66 }, -6611, 23197, 437, 16584, 2, 48 }, /* region 75 */
+ { { 1, 67, 87 }, -7202, 23197, 452, 16803, 0, 48 }, /* region 76 */
+ { { 32769, 88, 108 }, -8473, 16422, 404, 16698, 1, 48 }, /* region 77 */
+ { { 1, 12, 43 }, -3055, 23197, 920, 1383, 30, 59 }, /* region 78 */
+ { { 32769, 44, 96 }, -5060, 18426, 885, 1176, 37, 59 }, /* region 79 */
+ { { 1, 12, 48 }, -3461, 18426, 1148, 1514, 26, 60 }, /* region 80 */
+ { { 32769, 49, 96 }, -6253, 16422, 1347, 1420, 29, 60 }, /* region 81 */
+ { { 1, 33, 56 }, -5600, 26028, 1064, 1170, 38, 61 }, /* region 82 */
+ { { 1, 57, 72 }, -6000, 26028, 930, 1014, 44, 61 }, /* region 83 */
+ { { 32769, 73, 108 }, -7600, 26028, 726, 826, 52, 61 }, /* region 84 */
+ { { 1, 36, 96 }, -7600, 20675, 635, 735, 58, 62 }, /* region 85 */
+ { { 32769, 97, 108 }, -10108, 13045, 0, 31, 139, 62 }, /* region 86 */
+ { { 1, 36, 96 }, -7600, 14636, 635, 735, 58, 0 }, /* region 87 */
+ { { 32769, 97, 108 }, -10108, 13045, 0, 31, 139, 0 }, /* region 88 */
+ { { 1, 36, 83 }, -6006, 13045, 838, 922, 47, 63 }, /* region 89 */
+ { { 1, 84, 93 }, -8406, 14636, 209, 230, 103, 63 }, /* region 90 */
+ { { 32769, 94, 108 }, -10108, 13045, 0, 31, 139, 63 }, /* region 91 */
+ { { 1, 36, 83 }, -6006, 13045, 838, 922, 47, 64 }, /* region 92 */
+ { { 1, 84, 93 }, -8406, 13045, 209, 230, 103, 64 }, /* region 93 */
+ { { 32769, 94, 108 }, -10108, 13045, 0, 31, 139, 64 }, /* region 94 */
+ { { 1, 21, 56 }, -5595, 23197, 1064, 1170, 38, 65 }, /* region 95 */
+ { { 1, 57, 72 }, -5995, 23197, 930, 1014, 44, 65 }, /* region 96 */
+ { { 32769, 73, 108 }, -7598, 23197, 726, 826, 52, 65 }, /* region 97 */
+ { { 1, 12, 83 }, -6006, 16422, 838, 922, 47, 66 }, /* region 98 */
+ { { 1, 84, 93 }, -8406, 16422, 209, 230, 103, 66 }, /* region 99 */
+ { { 32769, 94, 108 }, -10108, 16422, 0, 31, 139, 66 }, /* region 100 */
+ { { 1, 24, 83 }, -6006, 16422, 838, 922, 47, 67 }, /* region 101 */
+ { { 1, 84, 93 }, -8406, 16422, 209, 230, 103, 67 }, /* region 102 */
+ { { 32769, 94, 108 }, -10108, 16422, 0, 31, 139, 67 }, /* region 103 */
+ { { 1, 12, 83 }, -6020, 16422, 0, 83, 126, 68 }, /* region 104 */
+ { { 1, 84, 90 }, -8482, 16422, 0, 20, 145, 68 }, /* region 105 */
+ { { 32769, 91, 108 }, -9101, 16422, 6, 20, 147, 68 }, /* region 106 */
+ { { 1, 21, 75 }, -7241, 16422, 419, 460, 76, 69 }, /* region 107 */
+ { { 32769, 76, 108 }, -9690, 14636, 254, 264, 101, 69 }, /* region 108 */
+ { { 32769, 36, 84 }, -7755, 16422, 0, 2775, 17, 70 }, /* region 109 */
+ { { 32769, 12, 108 }, -6655, 23197, 30, 276, 100, 71 }, /* region 110 */
+ { { 0, 12, 60 }, -7914, 26028, 0, 0, 15, 72 }, /* region 111 */
+ { { 32768, 61, 96 }, -7914, 26028, 0, 0, 15, 73 }, /* region 112 */
+ { { 1, 12, 65 }, -7053, 16422, 23, 10953, 4, 74 }, /* region 113 */
+ { { 32769, 66, 108 }, -7755, 20675, 11, 11753, 3, 74 }, /* region 114 */
+ { { 1, 12, 35 }, -5355, 16422, 2869, 3778, 11, 75 }, /* region 115 */
+ { { 1, 36, 48 }, -6555, 20675, 2869, 3778, 11, 75 }, /* region 116 */
+ { { 32769, 49, 72 }, -6555, 20675, 2869, 3778, 11, 76 }, /* region 117 */
+ { { 1, 16, 55 }, -6224, 20675, 1045, 1119, 41, 77 }, /* region 118 */
+ { { 32769, 56, 96 }, -6718, 20675, 907, 963, 46, 77 }, /* region 119 */
+ { { 1, 16, 53 }, -5994, 29204, 1140, 1479, 27, 78 }, /* region 120 */
+ { { 1, 54, 70 }, -7171, 29204, 726, 812, 55, 78 }, /* region 121 */
+ { { 32769, 71, 108 }, -7788, 29204, 718, 748, 56, 78 }, /* region 122 */
+ { { 1, 12, 65 }, -7053, 16422, 23, 10953, 4, 79 }, /* region 123 */
+ { { 32769, 66, 108 }, -7755, 20675, 11, 11753, 3, 79 }, /* region 124 */
+ { { 1, 16, 54 }, -5727, 20675, 5362, 5461, 9, 80 }, /* region 125 */
+ { { 1, 55, 63 }, -5851, 26028, 1362, 1454, 28, 80 }, /* region 126 */
+ { { 32769, 64, 108 }, -6744, 16422, 311, 366, 88, 80 }, /* region 127 */
+ { { 1, 16, 48 }, -4798, 20675, 1132, 1301, 31, 81 }, /* region 128 */
+ { { 32769, 49, 108 }, -5988, 20675, 1099, 1184, 36, 81 }, /* region 129 */
+ { { 1, 21, 68 }, -8458, 20675, 87, 2170, 18, 82 }, /* region 130 */
+ { { 1, 69, 82 }, -8960, 20675, 120, 2167, 19, 82 }, /* region 131 */
+ { { 32769, 83, 108 }, -10160, 20675, 376, 2041, 20, 82 }, /* region 132 */
+ { { 1, 12, 65 }, -7053, 16422, 23, 10953, 4, 83 }, /* region 133 */
+ { { 32769, 66, 108 }, -7755, 20675, 11, 11753, 3, 83 }, /* region 134 */
+ { { 32769, 55, 108 }, -7368, 20675, 0, 477, 75, 84 }, /* region 135 */
+ { { 32769, 36, 96 }, -6900, 14636, 101, 151, 116, 85 }, /* region 136 */
+ { { 1, 24, 83 }, -6020, 13045, 0, 83, 126, 86 }, /* region 137 */
+ { { 1, 84, 90 }, -8482, 13045, 0, 20, 145, 86 }, /* region 138 */
+ { { 32769, 91, 108 }, -9101, 13045, 6, 20, 147, 86 }, /* region 139 */
+ { { 1, 12, 65 }, -7053, 16422, 23, 10953, 4, 87 }, /* region 140 */
+ { { 32769, 66, 108 }, -7755, 20675, 11, 11753, 3, 87 }, /* region 141 */
+ { { 1, 12, 65 }, -7053, 16422, 23, 10953, 4, 88 }, /* region 142 */
+ { { 32769, 66, 108 }, -7755, 20675, 11, 11753, 3, 88 }, /* region 143 */
+ { { 1, 12, 65 }, -7053, 16422, 23, 10953, 4, 89 }, /* region 144 */
+ { { 32769, 66, 108 }, -7755, 20675, 11, 11753, 3, 89 }, /* region 145 */
+ { { 1, 24, 83 }, -6020, 13045, 0, 83, 126, 90 }, /* region 146 */
+ { { 1, 84, 90 }, -8482, 13045, 0, 20, 145, 90 }, /* region 147 */
+ { { 32769, 91, 108 }, -9101, 13045, 6, 20, 147, 90 }, /* region 148 */
+ { { 1, 12, 65 }, -7053, 16422, 23, 10953, 4, 91 }, /* region 149 */
+ { { 32769, 66, 108 }, -7755, 20675, 11, 11753, 3, 91 }, /* region 150 */
+ { { 1, 12, 65 }, -7053, 16422, 23, 10953, 4, 92 }, /* region 151 */
+ { { 32769, 66, 108 }, -7755, 20675, 11, 11753, 3, 92 }, /* region 152 */
+ { { 1, 12, 62 }, -7053, 16422, 23, 10953, 4, 93 }, /* region 153 */
+ { { 32769, 63, 108 }, -7755, 20675, 11, 11753, 3, 93 }, /* region 154 */
+ { { 1, 12, 62 }, -7053, 16422, 23, 10953, 4, 94 }, /* region 155 */
+ { { 32769, 63, 108 }, -7755, 16422, 11, 11753, 3, 94 }, /* region 156 */
+ { { 1, 24, 79 }, -6020, 13045, 0, 83, 126, 95 }, /* region 157 */
+ { { 1, 80, 90 }, -8482, 13045, 0, 20, 145, 95 }, /* region 158 */
+ { { 32769, 91, 108 }, -9101, 13045, 6, 20, 147, 95 }, /* region 159 */
+ { { 1, 12, 65 }, -7053, 13045, 23, 10953, 4, 96 }, /* region 160 */
+ { { 32769, 66, 108 }, -7755, 16422, 11, 11753, 3, 96 }, /* region 161 */
+ { { 32768, 36, 84 }, -7500, 20675, 0, 0, 25, 97 }, /* region 162 */
+ { { 32769, 36, 96 }, -8855, 20675, 1482, 1613, 23, 98 }, /* region 163 */
+ { { 32769, 12, 96 }, -4366, 32767, 818, 1033, 42, 99 }, /* region 164 */
+ { { 32769, 36, 84 }, -8568, 18426, 0, 293, 98, 100 }, /* region 165 */
+ { { 32769, 12, 96 }, -6020, 26028, 0, 83, 125, 101 }, /* region 166 */
+ { { 32769, 12, 96 }, -6020, 20675, 0, 83, 125, 102 }, /* region 167 */
+ { { 1, 12, 83 }, -6020, 13045, 0, 83, 125, 104 }, /* region 168 */
+ { { 1, 84, 90 }, -8482, 13045, 0, 20, 146, 104 }, /* region 169 */
+ { { 32769, 91, 108 }, -9101, 13045, 6, 20, 148, 104 }, /* region 170 */
+ { { 32769, 36, 108 }, -8570, 32767, 472, 491, 74, 105 }, /* region 171 */
+ { { 32769, 36, 108 }, -8570, 20675, 472, 491, 74, 106 }, /* region 172 */
+ { { 1, 12, 72 }, -6012, 7336, 2, 86, 124, 107 }, /* region 173 */
+ { { 1, 73, 101 }, -8500, 8231, 2, 22, 143, 107 }, /* region 174 */
+ { { 32769, 102, 108 }, -9683, 20675, 173, 183, 110, 107 }, /* region 175 */
+ { { 1, 21, 96 }, -7768, 13045, 477, 507, 73, 108 }, /* region 176 */
+ { { 32769, 97, 108 }, -9683, 13045, 173, 183, 110, 109 }, /* region 177 */
+ { { 32769, 12, 108 }, -7771, 16422, 477, 507, 73, 110 }, /* region 178 */
+ { { 1, 12, 53 }, -4971, 16422, 388, 541, 68, 111 }, /* region 179 */
+ { { 32769, 54, 60 }, -5949, 11626, 473, 560, 65, 111 }, /* region 180 */
+ { { 32769, 36, 72 }, -5949, 16422, 473, 560, 65, 112 }, /* region 181 */
+ { { 1, 48, 58 }, -7053, 16422, 356, 402, 82, 113 }, /* region 182 */
+ { { 1, 59, 65 }, -7574, 16422, 514, 548, 67, 113 }, /* region 183 */
+ { { 1, 66, 78 }, -8174, 16422, 505, 529, 71, 113 }, /* region 184 */
+ { { 32769, 79, 96 }, -9233, 16422, 178, 191, 109, 113 }, /* region 185 */
+ { { 1, 55, 60 }, -7053, 16422, 356, 402, 82, 114 }, /* region 186 */
+ { { 1, 61, 69 }, -7574, 16422, 514, 548, 67, 114 }, /* region 187 */
+ { { 1, 70, 79 }, -8174, 16422, 505, 529, 71, 114 }, /* region 188 */
+ { { 32769, 80, 108 }, -9233, 16422, 178, 191, 109, 114 }, /* region 189 */
+ { { 1, 16, 82 }, -8029, 23197, 180, 206, 106, 115 }, /* region 190 */
+ { { 32769, 83, 108 }, -7240, 18426, 3, 44, 131, 115 }, /* region 191 */
+ { { 32769, 21, 108 }, -8869, 20675, 483, 515, 72, 116 }, /* region 192 */
+ { { 1, 21, 89 }, -7205, 18426, 3, 45, 130, 117 }, /* region 193 */
+ { { 32769, 90, 108 }, -9101, 10362, 6, 20, 148, 117 }, /* region 194 */
+ { { 1, 21, 42 }, -4686, 20675, 0, 180, 111, 118 }, /* region 195 */
+ { { 1, 43, 51 }, -5286, 23197, 0, 127, 120, 118 }, /* region 196 */
+ { { 1, 52, 58 }, -6292, 26028, 0, 71, 127, 118 }, /* region 197 */
+ { { 1, 59, 68 }, -7468, 23197, 0, 36, 136, 118 }, /* region 198 */
+ { { 32769, 69, 108 }, -8574, 20675, 0, 19, 149, 118 }, /* region 199 */
+ { { 1, 21, 89 }, -7199, 20675, 3, 45, 130, 119 }, /* region 200 */
+ { { 32769, 90, 108 }, -9101, 14636, 6, 20, 148, 119 }, /* region 201 */
+ { { 1, 21, 46 }, -5651, 26028, 236, 340, 92, 120 }, /* region 202 */
+ { { 1, 47, 71 }, -6563, 20675, 824, 885, 49, 120 }, /* region 203 */
+ { { 1, 72, 88 }, -7907, 18426, 719, 747, 57, 120 }, /* region 204 */
+ { { 1, 89, 93 }, -8876, 16422, 83, 99, 122, 120 }, /* region 205 */
+ { { 32769, 94, 108 }, -9689, 16422, 173, 183, 110, 120 }, /* region 206 */
+ { { 1, 60, 71 }, -7205, 16422, 0, 42, 132, 121 }, /* region 207 */
+ { { 1, 72, 78 }, -7903, 16422, 0, 28, 141, 121 }, /* region 208 */
+ { { 32769, 79, 96 }, -8405, 16422, 0, 21, 144, 121 }, /* region 209 */
+ { { 1, 48, 65 }, -6316, 11626, 0, 70, 128, 122 }, /* region 210 */
+ { { 1, 66, 79 }, -7724, 14636, 0, 31, 138, 122 }, /* region 211 */
+ { { 32769, 80, 96 }, -8030, 11626, 0, 26, 142, 122 }, /* region 212 */
+ { { 1, 16, 44 }, -5868, 14636, 163, 254, 102, 123 }, /* region 213 */
+ { { 1, 45, 51 }, -6418, 16422, 261, 393, 85, 123 }, /* region 214 */
+ { { 1, 52, 58 }, -7333, 18426, 190, 229, 104, 123 }, /* region 215 */
+ { { 1, 59, 66 }, -8100, 18426, 168, 193, 108, 123 }, /* region 216 */
+ { { 1, 67, 70 }, -8576, 18426, 138, 157, 115, 123 }, /* region 217 */
+ { { 1, 71, 80 }, -9103, 18426, 166, 180, 112, 123 }, /* region 218 */
+ { { 32769, 81, 108 }, -10074, 18426, 135, 151, 117, 123 }, /* region 219 */
+ { { 32769, 12, 96 }, -5004, 23197, 570, 719, 59, 124 }, /* region 220 */
+ { { 1, 12, 48 }, -5868, 14636, 163, 254, 102, 125 }, /* region 221 */
+ { { 1, 49, 54 }, -6418, 16422, 261, 393, 85, 125 }, /* region 222 */
+ { { 1, 55, 63 }, -7333, 18426, 190, 229, 104, 125 }, /* region 223 */
+ { { 1, 64, 70 }, -8100, 18426, 168, 193, 108, 125 }, /* region 224 */
+ { { 1, 71, 75 }, -8576, 18426, 138, 157, 115, 125 }, /* region 225 */
+ { { 1, 76, 82 }, -9103, 18426, 166, 180, 112, 125 }, /* region 226 */
+ { { 32769, 83, 108 }, -10074, 18426, 135, 151, 117, 125 }, /* region 227 */
+ { { 32770, 36, 84 }, -7200, 29204, 0, 0, 0, 126 }, /* region 228 */
+ { { 32770, 36, 84 }, -7600, 8231, 0, 0, 0, 127 }, /* region 229 */
+ { { 32770, 36, 84 }, -7200, 20675, 0, 0, 0, 128 }, /* region 230 */
+ { { 32769, 36, 84 }, -6000, -24285, 1294, 5778, 8, 129 }, /* region 231 */
+ { { 32769, 36, 84 }, -6555, 29204, 798, 993, 45, 130 }, /* region 232 */
+ { { 32769, 36, 84 }, -6855, 20675, 798, 993, 45, 131 }, /* region 233 */
+ { { 32769, 36, 84 }, -7755, 29204, 798, 993, 45, 132 }, /* region 234 */
+ { { 32768, 36, 84 }, -8155, 32767, 0, 0, 133, 133 }, /* region 235 */
+ { { 32768, 36, 84 }, -6555, 20675, 0, 0, 91, 134 }, /* region 236 */
+ { { 1, 24, 62 }, -7000, 23197, 286, 333, 94, 135 }, /* region 237 */
+ { { 1, 63, 66 }, -7364, 26028, 297, 335, 93, 135 }, /* region 238 */
+ { { 1, 67, 72 }, -7722, 23197, 368, 399, 84, 135 }, /* region 239 */
+ { { 32769, 73, 96 }, -8310, 23197, 116, 138, 119, 135 }, /* region 240 */
+ { { 1, 24, 48 }, -5141, 23197, 309, 447, 77, 136 }, /* region 241 */
+ { { 1, 49, 56 }, -6266, 26028, 211, 283, 99, 136 }, /* region 242 */
+ { { 1, 57, 63 }, -7000, 26028, 286, 333, 94, 136 }, /* region 243 */
+ { { 32769, 64, 84 }, -7722, 23197, 368, 399, 84, 136 }, /* region 244 */
+ { { 1, 24, 56 }, -6266, 29204, 211, 283, 99, 137 }, /* region 245 */
+ { { 1, 57, 63 }, -7000, 29204, 286, 333, 94, 137 }, /* region 246 */
+ { { 1, 64, 69 }, -7722, 29204, 368, 399, 84, 137 }, /* region 247 */
+ { { 32769, 70, 96 }, -8310, 29204, 116, 138, 119, 137 }, /* region 248 */
+ { { 1, 24, 68 }, -7722, 18426, 368, 399, 84, 138 }, /* region 249 */
+ { { 1, 69, 76 }, -8310, 26028, 116, 138, 119, 138 }, /* region 250 */
+ { { 32769, 77, 108 }, -8758, 23197, 127, 144, 118, 138 }, /* region 251 */
+ { { 1, 24, 82 }, -7613, 23197, 389, 422, 80, 139 }, /* region 252 */
+ { { 32769, 83, 108 }, -8764, 26028, 146, 163, 114, 139 }, /* region 253 */
+ { { 1, 12, 58 }, -6898, 29204, 386, 436, 78, 140 }, /* region 254 */
+ { { 32769, 59, 96 }, -7371, 26028, 290, 328, 95, 140 }, /* region 255 */
+ { { 1, 12, 58 }, -6898, 16422, 386, 436, 78, 141 }, /* region 256 */
+ { { 32769, 59, 96 }, -7371, 18426, 290, 328, 95, 141 }, /* region 257 */
+ { { 1, 12, 48 }, -6898, -28771, 386, 436, 78, 142 }, /* region 258 */
+ { { 32769, 49, 84 }, -7371, 29204, 290, 328, 95, 142 }, /* region 259 */
+ { { 1, 12, 60 }, -5453, 20675, 314, 430, 79, 143 }, /* region 260 */
+ { { 32769, 61, 84 }, -6553, 18426, 263, 324, 96, 143 }, /* region 261 */
+ { { 1, 24, 60 }, -6553, 16422, 263, 324, 96, 144 }, /* region 262 */
+ { { 1, 61, 70 }, -7669, 20675, 279, 311, 97, 144 }, /* region 263 */
+ { { 32769, 71, 96 }, -8098, 23197, 179, 204, 107, 144 }, /* region 264 */
+ { { 1, 24, 84 }, -8483, 20675, 191, 211, 105, 145 }, /* region 265 */
+ { { 32769, 85, 108 }, -9683, 20675, 92, 102, 121, 145 }, /* region 266 */
+ { { 1, 21, 69 }, -6553, 13045, 263, 324, 96, 146 }, /* region 267 */
+ { { 1, 70, 94 }, -7669, 20675, 279, 311, 97, 146 }, /* region 268 */
+ { { 1, 95, 96 }, -8098, -24285, 179, 204, 107, 146 }, /* region 269 */
+ { { 32769, 97, 108 }, -9683, -24285, 173, 183, 110, 146 }, /* region 270 */
+ { { 1, 16, 55 }, -8100, 20675, 168, 193, 108, 147 }, /* region 271 */
+ { { 1, 56, 74 }, -8576, 26028, 138, 157, 115, 147 }, /* region 272 */
+ { { 32769, 75, 96 }, -10074, 26028, 135, 151, 117, 147 }, /* region 273 */
+ { { 1, 24, 72 }, -8098, 26028, 179, 204, 107, 148 }, /* region 274 */
+ { { 1, 73, 85 }, -8483, 20675, 191, 211, 105, 148 }, /* region 275 */
+ { { 32769, 86, 108 }, -9683, 18426, 92, 102, 121, 148 }, /* region 276 */
+ { { 32769, 36, 108 }, -7730, 18426, 1839, 1901, 21, 149 }, /* region 277 */
+ { { 32769, 24, 108 }, -7273, 20675, 494, 534, 69, 150 }, /* region 278 */
+ { { 32769, 12, 108 }, -7273, 20675, 494, 534, 69, 151 }, /* region 279 */
+ { { 32769, 24, 108 }, -7273, 20675, 494, 534, 69, 152 }, /* region 280 */
+ { { 1, 36, 60 }, -4900, 5193, 2, 22, 143, 153 }, /* region 281 */
+ { { 32769, 61, 84 }, -6083, 20675, 173, 183, 110, 153 }, /* region 282 */
+ { { 32769, 24, 96 }, -6553, 14636, 263, 324, 96, 154 }, /* region 283 */
+ { { 32769, 36, 96 }, -7730, 26028, 1839, 1901, 21, 155 }, /* region 284 */
+ { { 32769, 24, 108 }, -7273, 20675, 494, 534, 69, 156 }, /* region 285 */
+ { { 1, 24, 58 }, -7851, 14636, 0, 29, 140, 157 }, /* region 286 */
+ { { 32769, 59, 96 }, -7851, 14636, 0, 29, 140, 157 }, /* region 287 */
+ { { 1, 12, 83 }, -6020, 13045, 0, 83, 125, 158 }, /* region 288 */
+ { { 1, 84, 90 }, -8482, 13045, 0, 20, 146, 158 }, /* region 289 */
+ { { 32769, 91, 108 }, -9101, 13045, 6, 20, 148, 158 }, /* region 290 */
+ { { 1, 21, 42 }, -4663, 26028, 1047, 1229, 34, 159 }, /* region 291 */
+ { { 1, 43, 48 }, -5456, 29204, 1138, 1253, 33, 159 }, /* region 292 */
+ { { 1, 49, 53 }, -5845, 26028, 559, 651, 60, 159 }, /* region 293 */
+ { { 1, 54, 60 }, -6732, 26028, 508, 563, 64, 159 }, /* region 294 */
+ { { 1, 61, 65 }, -7080, 32767, 819, 864, 51, 159 }, /* region 295 */
+ { { 1, 66, 70 }, -6866, 26942, 981, 1032, 43, 159 }, /* region 296 */
+ { { 1, 71, 76 }, -8166, 26028, 790, 814, 54, 159 }, /* region 297 */
+ { { 1, 77, 82 }, -8766, 26028, 592, 609, 61, 159 }, /* region 298 */
+ { { 1, 83, 87 }, -9517, 23197, 543, 554, 66, 159 }, /* region 299 */
+ { { 1, 88, 96 }, -10071, 18426, 601, 609, 62, 159 }, /* region 300 */
+ { { 32769, 97, 108 }, -10566, 18426, 523, 529, 70, 159 }, /* region 301 */
+ { { 1, 48, 69 }, -6313, 14636, 0, 70, 128, 160 }, /* region 302 */
+ { { 1, 70, 79 }, -7724, 18426, 0, 31, 138, 160 }, /* region 303 */
+ { { 32769, 80, 96 }, -8030, 14636, 0, 26, 142, 160 }, /* region 304 */
+ { { 1, 36, 72 }, -7134, 29204, 0, 87, 123, 161 }, /* region 305 */
+ { { 32769, 73, 96 }, -7960, 29204, 0, 54, 129, 161 }, /* region 306 */
+ { { 32769, 36, 96 }, -7730, 26028, 1839, 1901, 21, 162 }, /* region 307 */
+ { { 32769, 12, 96 }, -4372, 32767, 818, 1033, 42, 163 }, /* region 308 */
+ { { 32769, 36, 108 }, -8570, 26028, 472, 491, 74, 164 }, /* region 309 */
+ { { 32769, 12, 96 }, -5004, 29204, 570, 719, 59, 165 }, /* region 310 */
+ { { 1, 12, 83 }, -6020, 13045, 0, 83, 125, 166 }, /* region 311 */
+ { { 1, 84, 90 }, -8482, 13045, 0, 20, 146, 166 }, /* region 312 */
+ { { 32769, 91, 108 }, -9101, 13045, 6, 20, 148, 166 }, /* region 313 */
+ { { 1, 21, 46 }, -5651, 32767, 236, 340, 92, 167 }, /* region 314 */
+ { { 1, 47, 75 }, -6563, 26028, 824, 885, 49, 167 }, /* region 315 */
+ { { 1, 76, 84 }, -7907, 23197, 719, 747, 57, 167 }, /* region 316 */
+ { { 1, 85, 93 }, -8876, 20675, 83, 99, 122, 167 }, /* region 317 */
+ { { 32769, 94, 108 }, -9689, 20675, 173, 183, 110, 167 }, /* region 318 */
+ { { 1, 21, 46 }, -5651, 26028, 236, 340, 92, 168 }, /* region 319 */
+ { { 1, 47, 71 }, -6563, 20675, 824, 885, 49, 168 }, /* region 320 */
+ { { 1, 72, 88 }, -7907, 18426, 719, 747, 57, 168 }, /* region 321 */
+ { { 1, 89, 93 }, -8876, 16422, 83, 99, 122, 168 }, /* region 322 */
+ { { 32769, 94, 108 }, -9689, 16422, 173, 183, 110, 168 }, /* region 323 */
+ { { 1, 21, 45 }, -4663, 26028, 1047, 1229, 34, 169 }, /* region 324 */
+ { { 1, 46, 51 }, -5456, 29204, 1138, 1253, 33, 169 }, /* region 325 */
+ { { 1, 52, 54 }, -5845, 26028, 559, 651, 60, 169 }, /* region 326 */
+ { { 1, 55, 63 }, -6732, 26028, 508, 563, 64, 169 }, /* region 327 */
+ { { 1, 64, 68 }, -7080, 32767, 819, 864, 51, 169 }, /* region 328 */
+ { { 1, 69, 73 }, -6866, 26942, 981, 1032, 43, 169 }, /* region 329 */
+ { { 1, 74, 79 }, -8166, 26028, 790, 814, 54, 169 }, /* region 330 */
+ { { 1, 80, 88 }, -8766, 23197, 592, 609, 61, 169 }, /* region 331 */
+ { { 1, 89, 99 }, -10071, 18426, 601, 609, 62, 169 }, /* region 332 */
+ { { 32769, 100, 108 }, -10566, 18426, 523, 529, 70, 169 }, /* region 333 */
+ { { 1, 21, 45 }, -4663, 26028, 1047, 1229, 34, 170 }, /* region 334 */
+ { { 1, 46, 51 }, -5456, 29204, 1138, 1253, 33, 170 }, /* region 335 */
+ { { 1, 52, 54 }, -5845, 26028, 559, 651, 60, 170 }, /* region 336 */
+ { { 1, 55, 63 }, -6732, 26028, 508, 563, 64, 170 }, /* region 337 */
+ { { 1, 64, 68 }, -7080, 32767, 819, 864, 51, 170 }, /* region 338 */
+ { { 1, 69, 73 }, -6866, 26942, 981, 1032, 43, 170 }, /* region 339 */
+ { { 1, 74, 79 }, -8166, 26028, 790, 814, 54, 170 }, /* region 340 */
+ { { 1, 80, 88 }, -8766, 23197, 592, 609, 61, 170 }, /* region 341 */
+ { { 1, 89, 99 }, -10071, 18426, 601, 609, 62, 171 }, /* region 342 */
+ { { 32769, 100, 108 }, -10566, 18426, 523, 529, 70, 172 }, /* region 343 */
+ { { 32769, 36, 108 }, -8570, 20675, 472, 491, 74, 173 }, /* region 344 */
+ { { 32769, 12, 108 }, -7730, 20675, 1839, 1901, 21, 174 }, /* region 345 */
+ { { 1, 12, 44 }, -5868, 18426, 163, 254, 102, 175 }, /* region 346 */
+ { { 1, 45, 51 }, -6418, 20675, 261, 393, 85, 175 }, /* region 347 */
+ { { 1, 52, 58 }, -7333, 23197, 190, 229, 104, 175 }, /* region 348 */
+ { { 1, 59, 66 }, -8100, 23197, 168, 193, 108, 175 }, /* region 349 */
+ { { 1, 67, 70 }, -8576, 23197, 138, 157, 115, 175 }, /* region 350 */
+ { { 1, 71, 80 }, -9103, 23197, 166, 180, 112, 175 }, /* region 351 */
+ { { 32769, 81, 108 }, -10074, 23197, 135, 151, 117, 175 }, /* region 352 */
+ { { 1, 12, 65 }, -7053, 16422, 23, 10953, 4, 176 }, /* region 353 */
+ { { 32769, 66, 108 }, -7755, 20675, 11, 11753, 3, 176 }, /* region 354 */
+ { { 1, 12, 48 }, -4798, 29204, 1132, 1301, 31, 177 }, /* region 355 */
+ { { 32769, 49, 108 }, -5988, 29204, 1099, 1184, 36, 177 }, /* region 356 */
+ { { 1, 12, 83 }, -7241, 20675, 419, 460, 76, 178 }, /* region 357 */
+ { { 32769, 84, 108 }, -10123, 20675, 0, 31, 139, 178 }, /* region 358 */
+ { { 1, 55, 60 }, -7053, 18426, 356, 402, 82, 179 }, /* region 359 */
+ { { 1, 61, 69 }, -7574, 18426, 514, 548, 67, 179 }, /* region 360 */
+ { { 1, 70, 79 }, -8174, 18426, 505, 529, 71, 179 }, /* region 361 */
+ { { 32769, 80, 108 }, -9233, 23197, 178, 191, 109, 179 }, /* region 362 */
+ { { 32769, 36, 96 }, -7730, -24285, 1839, 1901, 21, 180 }, /* region 363 */
+ { { 1, 12, 83 }, -6006, 16422, 838, 922, 47, 181 }, /* region 364 */
+ { { 1, 84, 93 }, -8406, 18426, 209, 230, 103, 181 }, /* region 365 */
+ { { 32769, 94, 108 }, -10108, 16422, 0, 31, 139, 181 }, /* region 366 */
+ { { 1, 12, 56 }, -5595, 23197, 1064, 1170, 38, 182 }, /* region 367 */
+ { { 1, 57, 72 }, -5995, 23197, 930, 1014, 44, 182 }, /* region 368 */
+ { { 32769, 73, 108 }, -7598, 23197, 726, 826, 52, 182 }, /* region 369 */
+ { { 32769, 24, 108 }, -7600, 23197, 635, 735, 58, 62 }, /* region 370 */
+ { { 1, 36, 83 }, -6006, 13045, 838, 922, 47, 183 }, /* region 371 */
+ { { 1, 84, 93 }, -8406, 13045, 209, 230, 103, 183 }, /* region 372 */
+ { { 32769, 94, 108 }, -10108, 13045, 0, 31, 139, 183 }, /* region 373 */
+ { { 1, 12, 66 }, -6611, 23197, 437, 16584, 2, 184 }, /* region 374 */
+ { { 1, 67, 87 }, -7202, 23197, 452, 16803, 0, 184 }, /* region 375 */
+ { { 32769, 88, 108 }, -8473, 16422, 404, 16698, 1, 184 } /* region 376 */
}; /* end Regions */
/*----------------------------------------------------------------------------
* Programs
*----------------------------------------------------------------------------
*/
-const S_PROGRAM eas_programs[] =
+const S_PROGRAM eas_programs[] =
{
- { 7864320, 0 } /* program 0 */
+ { 7864320, 0 } /* program 0 */
}; /* end Programs */
/*----------------------------------------------------------------------------
@@ -1361,27 +1361,27 @@ const S_PROGRAM eas_programs[] =
*/
const S_BANK eas_banks[] =
{
- { /* bank 0 */
- 30976,
- {
- 291, 324, 314, 334, 202, 319, 95, 195,
- 107, 92, 371, 89, 87, 85, 135, 82,
- 200, 192, 130, 267, 193, 302, 207, 210,
- 128, 125, 190, 120, 118, 213, 221, 271,
- 80, 78, 308, 164, 220, 310, 166, 167,
- 186, 182, 181, 179, 160, 178, 176, 115,
- 155, 153, 151, 149, 75, 73, 374, 111,
- 252, 254, 258, 305, 256, 157, 146, 137,
- 249, 237, 245, 241, 274, 262, 260, 265,
- 172, 171, 309, 277, 284, 307, 136, 344,
- 173, 168, 345, 353, 346, 70, 110, 311,
- 357, 144, 104, 67, 364, 367, 64, 288,
- 142, 140, 98, 355, 133, 123, 61, 113,
- 285, 280, 279, 278, 370, 286, 359, 283,
- 101, 236, 163, 235, 234, 233, 232, 231,
- 162, 363, 230, 281, 165, 229, 109, 228
- }
- }
+ { /* bank 0 */
+ 30976,
+ {
+ 291, 324, 314, 334, 202, 319, 95, 195,
+ 107, 92, 371, 89, 87, 85, 135, 82,
+ 200, 192, 130, 267, 193, 302, 207, 210,
+ 128, 125, 190, 120, 118, 213, 221, 271,
+ 80, 78, 308, 164, 220, 310, 166, 167,
+ 186, 182, 181, 179, 160, 178, 176, 115,
+ 155, 153, 151, 149, 75, 73, 374, 111,
+ 252, 254, 258, 305, 256, 157, 146, 137,
+ 249, 237, 245, 241, 274, 262, 260, 265,
+ 172, 171, 309, 277, 284, 307, 136, 344,
+ 173, 168, 345, 353, 346, 70, 110, 311,
+ 357, 144, 104, 67, 364, 367, 64, 288,
+ 142, 140, 98, 355, 133, 123, 61, 113,
+ 285, 280, 279, 278, 370, 286, 359, 283,
+ 101, 236, 163, 235, 234, 233, 232, 231,
+ 162, 363, 230, 281, 165, 229, 109, 228
+ }
+ }
}; /* end Banks */
/*----------------------------------------------------------------------------
@@ -1389,13332 +1389,13332 @@ const S_BANK eas_banks[] =
*----------------------------------------------------------------------------
*/
-const EAS_SAMPLE eas_samples[] =
+const EAS_SAMPLE eas_samples[] =
{
- 0, 0, -3, -4, -6, -8, -10, -12, -12, -11, -8, -3, 3, 7, 10, 14,
- 16, 16, 15, 12, 9, 4, -4, -12, -18, -21, -21, -19, -18, -15, -10, -3,
- 10, 20, 34, 44, 51, 52, 48, 43, 38, 26, 8, -15, -37, -52, -61, -64,
- -66, -64, -59, -47, -31, -13, 4, 18, 30, 37, 40, 36, 30, 24, 19, 11,
- -2, -17, -24, -28, -28, -21, -18, -16, -10, -3, 12, 27, 39, 49, 53, 53,
- 50, 43, 37, 25, 11, -11, -31, -46, -57, -63, -66, -63, -57, -46, -34, -19,
- -3, 13, 27, 35, 39, 37, 32, 26, 20, 11, 0, -13, -20, -24, -25, -21,
- -19, -14, -8, -2, 9, 23, 37, 47, 53, 52, 49, 42, 35, 25, 13, -6,
- -28, -48, -60, -67, -67, -64, -60, -51, -39, -23, -7, 10, 23, 35, 39, 38,
- 32, 26, 21, 15, 4, -9, -20, -22, -21, -19, -14, -11, -5, 1, 9, 19,
- 31, 45, 51, 52, 47, 39, 35, 25, 15, -3, -23, -42, -58, -70, -71, -66,
- -60, -51, -43, -30, -13, 6, 22, 32, 40, 40, 38, 33, 27, 19, 9, -5,
- -17, -25, -26, -22, -16, -11, -8, -4, 7, 21, 35, 48, 53, 56, 50, 43,
- 34, 22, 13, -2, -22, -44, -63, -75, -76, -69, -61, -51, -43, -29, -13, 6,
- 23, 32, 41, 43, 41, 37, 26, 18, 7, -8, -19, -25, -25, -22, -15, -9,
- -5, 0, 10, 24, 37, 44, 48, 52, 52, 46, 33, 20, 8, -5, -20, -38,
- -59, -74, -79, -73, -67, -55, -43, -26, -11, 4, 18, 29, 41, 45, 45, 38,
- 29, 21, 11, -3, -15, -25, -27, -22, -16, -11, -8, 0, 10, 25, 38, 44,
- 47, 50, 53, 49, 37, 20, 7, -5, -17, -34, -58, -74, -82, -76, -67, -59,
- -47, -29, -12, 3, 14, 25, 38, 50, 52, 46, 33, 23, 14, 3, -11, -25,
- -28, -27, -21, -16, -13, -7, 8, 27, 41, 44, 45, 47, 54, 55, 44, 25,
- 7, -7, -18, -32, -53, -71, -81, -81, -72, -67, -55, -37, -16, 3, 15, 23,
- 34, 48, 57, 56, 44, 30, 19, 5, -12, -26, -33, -31, -25, -19, -16, -11,
- 7, 25, 45, 49, 49, 52, 57, 59, 48, 32, 11, -5, -22, -39, -56, -73,
- -82, -88, -84, -75, -60, -38, -16, 5, 21, 30, 39, 52, 59, 61, 53, 37,
- 22, 7, -12, -28, -35, -36, -30, -22, -19, -16, -2, 21, 41, 52, 51, 52,
- 57, 62, 54, 40, 18, -2, -18, -36, -54, -70, -80, -86, -87, -81, -69, -48,
- -23, 0, 18, 28, 35, 45, 57, 64, 59, 46, 27, 9, -11, -24, -30, -32,
- -29, -25, -20, -16, -5, 15, 36, 47, 50, 49, 53, 57, 54, 43, 24, 5,
- -14, -32, -50, -65, -75, -82, -86, -86, -77, -58, -32, -8, 14, 25, 30, 41,
- 56, 69, 69, 57, 36, 17, -4, -20, -29, -32, -27, -28, -27, -23, -13, 10,
- 33, 46, 50, 48, 50, 54, 55, 48, 34, 16, -6, -29, -50, -68, -75, -78,
- -82, -86, -84, -72, -47, -16, 11, 28, 34, 41, 51, 64, 70, 64, 49, 27,
- 5, -17, -30, -33, -29, -29, -30, -30, -22, -2, 23, 41, 49, 51, 51, 54,
- 56, 50, 42, 25, 4, -20, -44, -62, -70, -76, -83, -87, -89, -78, -56, -29,
- 0, 19, 31, 38, 48, 63, 72, 71, 60, 40, 14, -12, -25, -29, -26, -27,
- -33, -37, -30, -12, 11, 31, 41, 48, 51, 53, 55, 55, 51, 39, 17, -12,
- -38, -58, -67, -74, -82, -92, -98, -89, -69, -41, -13, 10, 29, 41, 50, 64,
- 72, 78, 74, 57, 29, 0, -18, -26, -28, -32, -38, -42, -38, -23, -3, 18,
- 30, 42, 52, 58, 60, 61, 57, 48, 28, 2, -30, -51, -62, -70, -81, -94,
- -101, -93, -75, -49, -23, -2, 18, 36, 50, 61, 69, 77, 78, 66, 42, 11,
- -11, -22, -27, -32, -39, -46, -46, -36, -14, 8, 25, 41, 52, 59, 62, 63,
- 62, 57, 38, 11, -20, -47, -61, -69, -78, -89, -98, -94, -80, -60, -37, -12,
- 13, 33, 48, 62, 70, 78, 81, 72, 52, 23, 0, -14, -24, -33, -43, -49,
- -49, -39, -23, -2, 15, 33, 47, 57, 63, 62, 62, 57, 40, 20, -7, -34,
- -52, -65, -74, -83, -94, -92, -81, -63, -42, -22, 0, 21, 39, 54, 63, 73,
- 79, 76, 61, 37, 12, -5, -19, -28, -37, -46, -51, -47, -32, -13, 7, 25,
- 43, 54, 58, 60, 60, 61, 48, 27, 3, -25, -45, -60, -72, -81, -90, -92,
- -84, -71, -52, -32, -9, 14, 33, 50, 61, 74, 80, 78, 67, 47, 24, 6,
- -12, -26, -37, -50, -56, -52, -37, -19, -2, 16, 35, 52, 61, 63, 61, 59,
- 51, 35, 12, -15, -38, -55, -66, -77, -83, -83, -80, -68, -55, -39, -19, 4,
- 25, 41, 54, 66, 73, 75, 68, 52, 31, 11, -7, -22, -33, -46, -54, -51,
- -39, -24, -5, 12, 32, 48, 56, 60, 61, 58, 50, 36, 17, -8, -30, -46,
- -63, -74, -80, -80, -74, -69, -58, -43, -27, -5, 15, 31, 48, 60, 68, 72,
- 68, 57, 39, 20, 2, -16, -30, -44, -51, -50, -41, -27, -10, 9, 28, 43,
- 53, 57, 57, 54, 48, 37, 19, -3, -25, -41, -56, -69, -75, -73, -69, -63,
- -59, -49, -32, -13, 9, 25, 37, 48, 58, 66, 65, 58, 42, 25, 8, -9,
- -22, -36, -41, -43, -37, -26, -14, 4, 21, 37, 48, 52, 53, 47, 42, 34,
- 21, 3, -18, -39, -51, -64, -67, -62, -60, -60, -58, -50, -36, -16, 3, 17,
- 29, 41, 49, 58, 61, 60, 49, 29, 11, -7, -19, -28, -32, -33, -30, -25,
- -14, 2, 19, 33, 41, 45, 42, 38, 36, 29, 20, 6, -14, -28, -43, -54,
- -58, -55, -50, -51, -54, -51, -41, -22, -4, 11, 19, 30, 37, 47, 55, 56,
- 51, 34, 16, 0, -15, -19, -23, -22, -22, -21, -14, 0, 15, 29, 39, 43,
- 37, 31, 25, 21, 18, 6, -11, -28, -42, -50, -51, -48, -44, -41, -44, -43,
- -41, -25, -8, 9, 16, 22, 26, 35, 43, 50, 48, 33, 16, -3, -13, -16,
- -16, -15, -13, -11, -6, 5, 16, 28, 38, 41, 35, 24, 15, 12, 10, 4,
- -11, -27, -39, -46, -46, -45, -40, -36, -36, -37, -38, -29, -13, 6, 16, 19,
- 22, 27, 37, 43, 42, 32, 19, 2, -10, -13, -12, -7, -4, -2, 2, 10,
- 18, 27, 36, 38, 32, 20, 9, 4, -2, -4, -11, -23, -34, -42, -42, -38,
- -31, -28, -29, -32, -33, -30, -18, 0, 10, 12, 12, 17, 26, 35, 36, 31,
- 19, 5, -6, -11, -9, -2, 7, 14, 13, 13, 16, 23, 31, 34, 29, 15,
- -3, -8, -10, -10, -14, -20, -26, -30, -32, -30, -25, -18, -17, -24, -31, -32,
- -26, -11, 2, 7, 8, 9, 17, 25, 29, 28, 21, 9, -2, -7, -5, 4,
- 12, 21, 24, 23, 25, 26, 29, 31, 27, 15, -2, -15, -21, -23, -23, -23,
- -28, -30, -31, -27, -19, -10, -9, -13, -21, -22, -20, -11, -4, -3, -5, -2,
- 5, 13, 17, 17, 16, 10, 6, 0, 3, 11, 23, 32, 33, 30, 28, 27,
- 24, 24, 19, 9, -6, -19, -29, -29, -26, -20, -19, -22, -24, -23, -16, -10,
- -9, -14, -20, -24, -21, -16, -10, -6, -5, 1, 5, 11, 12, 13, 11, 8,
- 6, 1, 4, 9, 23, 33, 39, 36, 32, 32, 28, 22, 17, 7, -7, -22,
- -31, -33, -31, -24, -19, -18, -18, -16, -13, -7, -6, -8, -14, -21, -24, -20,
- -15, -12, -9, -6, 0, 4, 6, 8, 8, 5, 5, 2, 7, 15, 27, 37,
- 42, 45, 41, 39, 32, 22, 13, 3, -11, -26, -37, -41, -37, -29, -21, -18,
- -15, -11, -6, -2, -2, -4, -7, -13, -16, -20, -21, -16, -14, -10, -6, -3,
- -3, 0, 3, 2, 3, 3, 9, 18, 32, 41, 46, 49, 44, 43, 35, 24,
- 12, 1, -14, -27, -39, -40, -36, -31, -22, -16, -13, -6, -3, -3, -4, -9,
- -9, -13, -16, -20, -21, -16, -15, -11, -6, -4, -4, -5, -5, -3, -3, 0,
- 10, 19, 33, 44, 51, 56, 52, 50, 40, 23, 11, -6, -19, -30, -40, -43,
- -40, -35, -24, -16, -7, 2, 6, 5, 1, -6, -9, -9, -9, -12, -19, -21,
- -21, -17, -9, -7, -9, -11, -15, -14, -9, -7, 7, 19, 36, 51, 57, 61,
- 59, 56, 48, 33, 13, -8, -24, -35, -45, -51, -46, -38, -26, -14, -7, 3,
- 11, 15, 12, 3, -5, -7, -6, -9, -15, -22, -25, -23, -17, -13, -12, -16,
- -19, -21, -18, -12, 3, 21, 38, 50, 58, 67, 65, 64, 55, 41, 21, -4,
- -25, -38, -46, -50, -49, -43, -33, -23, -11, 3, 14, 19, 16, 8, 0, -2,
- -2, 0, -8, -19, -27, -30, -25, -22, -20, -20, -22, -25, -24, -16, 1, 22,
- 43, 56, 62, 67, 68, 65, 60, 46, 24, -3, -25, -40, -45, -49, -50, -46,
- -37, -23, -10, 1, 12, 20, 20, 14, 7, 2, 3, 3, -4, -15, -26, -31,
- -30, -27, -26, -26, -29, -33, -33, -25, -8, 17, 41, 57, 65, 71, 73, 73,
- 66, 53, 33, 5, -23, -41, -48, -50, -48, -48, -40, -30, -14, 1, 12, 21,
- 24, 18, 13, 6, 5, 5, 0, -11, -25, -37, -39, -35, -31, -31, -33, -38,
- -37, -29, -12, 15, 40, 59, 67, 71, 72, 73, 69, 59, 39, 14, -16, -38,
- -50, -51, -50, -48, -45, -36, -21, -4, 12, 25, 30, 25, 18, 11, 11, 10,
- 6, -8, -25, -39, -46, -42, -38, -37, -37, -40, -42, -34, -15, 13, 40, 57,
- 66, 71, 72, 72, 69, 61, 45, 19, -10, -34, -46, -48, -47, -45, -45, -41,
- -28, -12, 7, 23, 27, 25, 18, 15, 17, 17, 12, 1, -20, -37, -47, -50,
- -46, -45, -44, -45, -46, -41, -21, 7, 37, 60, 69, 73, 72, 72, 72, 67,
- 52, 25, -6, -33, -47, -50, -47, -47, -47, -45, -35, -16, 6, 23, 31, 30,
- 24, 23, 24, 25, 18, 4, -15, -33, -50, -56, -57, -53, -48, -49, -49, -45,
- -29, 2, 35, 58, 68, 71, 72, 74, 73, 68, 56, 34, 5, -26, -43, -48,
- -45, -42, -46, -46, -41, -24, 0, 21, 33, 34, 31, 25, 27, 27, 19, 6,
- -14, -36, -55, -64, -64, -60, -50, -47, -45, -44, -31, -4, 32, 58, 71, 72,
- 68, 70, 70, 66, 57, 36, 11, -20, -43, -50, -48, -41, -37, -42, -40, -28,
- -5, 21, 36, 38, 34, 26, 29, 28, 20, 8, -13, -33, -52, -68, -69, -65,
- -55, -49, -47, -44, -31, -3, 30, 55, 67, 70, 68, 70, 70, 65, 57, 39,
- 15, -13, -38, -49, -47, -40, -35, -39, -41, -30, -9, 17, 37, 44, 45, 38,
- 32, 29, 22, 9, -10, -34, -54, -70, -75, -73, -64, -52, -45, -43, -31, -7,
- 25, 53, 67, 72, 70, 72, 70, 62, 53, 38, 16, -10, -32, -49, -50, -43,
- -35, -33, -36, -29, -10, 16, 35, 46, 46, 41, 35, 30, 23, 10, -10, -34,
- -53, -69, -75, -74, -66, -53, -45, -42, -34, -13, 17, 46, 63, 68, 66, 63,
- 65, 63, 54, 43, 24, 0, -20, -40, -43, -42, -36, -32, -32, -28, -16, 7,
- 29, 47, 52, 47, 39, 31, 21, 10, -9, -30, -50, -66, -78, -77, -71, -59,
- -49, -42, -34, -17, 9, 37, 56, 66, 66, 62, 62, 61, 56, 45, 30, 7,
- -13, -31, -39, -40, -36, -33, -32, -28, -18, 1, 21, 41, 54, 52, 44, 36,
- 26, 13, -8, -29, -48, -66, -76, -80, -74, -64, -55, -45, -34, -18, 5, 29,
- 50, 65, 68, 66, 64, 60, 59, 47, 33, 15, -5, -23, -37, -43, -41, -37,
- -35, -31, -21, -4, 16, 36, 52, 59, 54, 45, 33, 17, -5, -25, -45, -60,
- -74, -83, -82, -71, -59, -49, -37, -23, -2, 22, 43, 59, 66, 65, 64, 60,
- 58, 50, 39, 23, 2, -17, -32, -39, -40, -38, -35, -32, -23, -6, 14, 33,
- 49, 59, 58, 49, 34, 16, -5, -25, -43, -60, -74, -83, -83, -76, -63, -53,
- -40, -24, -5, 16, 36, 54, 65, 67, 65, 61, 57, 52, 43, 27, 9, -12,
- -26, -37, -40, -39, -36, -32, -28, -13, 6, 27, 46, 58, 60, 52, 39, 23,
- 5, -16, -36, -53, -66, -77, -84, -81, -72, -60, -45, -32, -15, 5, 25, 48,
- 62, 69, 71, 69, 65, 58, 50, 34, 16, -6, -24, -36, -42, -45, -44, -39,
- -33, -21, -2, 22, 43, 59, 64, 60, 47, 34, 17, -6, -28, -50, -66, -76,
- -84, -86, -82, -72, -57, -40, -21, -2, 21, 42, 58, 66, 73, 76, 71, 64,
- 53, 40, 26, 4, -17, -34, -45, -49, -48, -43, -38, -28, -10, 15, 40, 58,
- 66, 64, 56, 42, 25, 4, -21, -44, -62, -73, -81, -87, -86, -78, -65, -47,
- -31, -9, 15, 34, 52, 62, 72, 79, 80, 72, 61, 49, 34, 12, -12, -32,
- -43, -49, -54, -55, -48, -36, -16, 10, 35, 56, 67, 71, 67, 54, 38, 15,
- -10, -34, -57, -72, -85, -93, -97, -89, -76, -59, -40, -20, 8, 32, 50, 67,
- 77, 87, 89, 81, 66, 52, 35, 16, -6, -30, -47, -58, -61, -57, -50, -37,
- -19, 6, 29, 51, 65, 73, 73, 62, 44, 18, -6, -28, -49, -67, -81, -93,
- -97, -94, -83, -65, -47, -28, -5, 19, 42, 61, 76, 87, 90, 88, 80, 66,
- 48, 27, 3, -17, -40, -56, -65, -66, -58, -49, -30, -6, 17, 41, 59, 71,
- 77, 70, 56, 36, 11, -13, -34, -53, -71, -89, -98, -100, -94, -79, -62, -44,
- -21, 3, 27, 52, 74, 90, 98, 95, 86, 75, 59, 37, 12, -14, -35, -54,
- -64, -67, -64, -51, -34, -10, 11, 32, 50, 65, 73, 71, 58, 37, 14, -10,
- -29, -48, -64, -81, -93, -98, -94, -82, -63, -45, -26, -5, 16, 40, 65, 83,
- 94, 94, 84, 75, 63, 46, 23, -3, -27, -47, -58, -64, -64, -56, -39, -17,
- 3, 20, 38, 57, 71, 72, 61, 45, 24, 1, -19, -37, -56, -73, -91, -99,
- -100, -92, -74, -53, -34, -16, 7, 31, 59, 82, 97, 101, 92, 78, 65, 48,
- 29, 6, -21, -43, -55, -64, -66, -58, -40, -18, 3, 17, 32, 51, 69, 71,
- 62, 45, 27, 6, -15, -34, -50, -64, -81, -93, -99, -96, -80, -59, -40, -23,
- -4, 21, 50, 77, 94, 100, 93, 81, 67, 53, 36, 14, -12, -36, -53, -58,
- -63, -56, -42, -22, -5, 10, 23, 42, 63, 70, 62, 47, 29, 13, -6, -27,
- -43, -57, -72, -84, -98, -99, -87, -66, -44, -27, -11, 10, 38, 67, 91, 99,
- 92, 82, 70, 57, 41, 21, -3, -27, -47, -58, -63, -58, -44, -23, -5, 7,
- 17, 35, 55, 66, 61, 46, 29, 13, -4, -22, -39, -51, -65, -78, -90, -95,
- -85, -69, -47, -30, -12, 9, 30, 57, 83, 96, 91, 81, 67, 57, 42, 26,
- 6, -18, -39, -55, -62, -58, -43, -24, -8, 2, 14, 30, 47, 60, 60, 49,
- 34, 17, 0, -16, -31, -43, -58, -71, -86, -93, -86, -72, -52, -32, -15, 3,
- 22, 48, 76, 90, 89, 78, 69, 59, 46, 32, 14, -6, -27, -47, -57, -56,
- -45, -29, -12, -5, 4, 18, 37, 54, 58, 51, 36, 21, 6, -8, -20, -33,
- -52, -68, -84, -90, -85, -74, -58, -42, -22, 0, 20, 42, 67, 83, 87, 80,
- 68, 58, 47, 34, 19, 0, -20, -40, -52, -53, -45, -27, -13, -4, 6, 17,
- 33, 47, 53, 52, 38, 21, 3, -11, -24, -35, -50, -65, -80, -89, -85, -71,
- -55, -39, -21, -2, 20, 39, 59, 74, 81, 75, 67, 57, 47, 38, 23, 4,
- -17, -32, -43, -45, -39, -26, -14, -4, 4, 12, 26, 38, 47, 48, 35, 19,
- 4, -10, -20, -29, -41, -56, -71, -78, -81, -71, -56, -43, -23, -6, 15, 35,
- 49, 62, 72, 69, 63, 54, 45, 41, 28, 11, -11, -27, -37, -40, -35, -24,
- -17, -7, 2, 9, 22, 35, 46, 49, 37, 21, 4, -9, -18, -27, -41, -55,
- -71, -79, -79, -70, -53, -38, -23, -8, 9, 31, 46, 58, 63, 63, 59, 52,
- 45, 40, 32, 14, -6, -24, -32, -31, -30, -23, -18, -12, 1, 9, 21, 31,
- 41, 44, 33, 21, 5, -6, -20, -29, -43, -57, -69, -77, -73, -65, -52, -41,
- -27, -8, 11, 32, 49, 57, 64, 61, 55, 47, 39, 36, 29, 13, -8, -25,
- -36, -35, -26, -16, -9, -5, 1, 9, 22, 36, 45, 43, 33, 17, 1, -11,
- -21, -32, -45, -57, -71, -78, -73, -61, -45, -33, -23, -8, 11, 31, 46, 53,
- 57, 54, 48, 40, 34, 31, 27, 14, -4, -20, -29, -28, -22, -12, -4, 1,
- 4, 8, 21, 34, 43, 43, 31, 17, 1, -11, -22, -31, -44, -59, -72, -78,
- -70, -54, -40, -28, -19, -8, 10, 28, 45, 53, 57, 53, 43, 34, 28, 27,
- 26, 18, 0, -18, -31, -29, -20, -11, -3, 2, 5, 10, 19, 31, 43, 44,
- 34, 19, 2, -13, -23, -32, -43, -55, -68, -77, -73, -57, -41, -26, -15, -6,
- 11, 28, 43, 52, 52, 49, 41, 33, 24, 22, 21, 14, 1, -14, -25, -24,
- -18, -7, -2, 2, 7, 10, 20, 31, 40, 43, 33, 18, 3, -13, -24, -35,
- -44, -55, -70, -78, -74, -59, -40, -26, -11, 1, 13, 29, 44, 53, 57, 54,
- 45, 32, 24, 18, 13, 9, -4, -16, -26, -29, -22, -10, 1, 8, 13, 18,
- 23, 35, 42, 45, 37, 21, 5, -14, -30, -41, -49, -57, -69, -77, -76, -61,
- -39, -20, -5, 9, 20, 34, 47, 53, 55, 48, 39, 27, 14, 8, 3, 2,
- -4, -15, -23, -24, -16, -3, 6, 11, 19, 24, 30, 34, 41, 43, 35, 18,
- 1, -17, -31, -44, -52, -59, -68, -75, -73, -61, -38, -19, 1, 13, 23, 30,
- 42, 52, 52, 47, 36, 23, 14, 7, 4, 0, -6, -11, -20, -24, -18, -5,
- 7, 15, 18, 22, 28, 36, 43, 43, 38, 24, 4, -13, -30, -44, -55, -64,
- -69, -77, -76, -65, -44, -19, 1, 15, 27, 35, 46, 53, 53, 46, 36, 23,
- 11, 3, -5, -7, -9, -14, -20, -23, -19, -7, 11, 18, 21, 25, 30, 40,
- 43, 43, 38, 24, 7, -14, -30, -41, -55, -65, -73, -77, -74, -66, -49, -24,
- -2, 17, 29, 35, 44, 51, 54, 49, 35, 23, 11, 1, -6, -12, -15, -16,
- -20, -24, -21, -10, 8, 21, 27, 33, 35, 42, 48, 47, 37, 23, 7, -12,
- -28, -44, -60, -69, -75, -78, -74, -65, -49, -25, -2, 17, 30, 40, 48, 54,
- 55, 48, 36, 20, 6, -4, -9, -14, -20, -22, -24, -21, -15, -6, 7, 21,
- 32, 39, 43, 44, 49, 50, 38, 21, 4, -13, -28, -47, -62, -74, -77, -78,
- -77, -65, -48, -26, -4, 15, 28, 40, 50, 56, 54, 46, 33, 20, 9, -2,
- -10, -16, -21, -21, -23, -21, -15, -5, 9, 19, 30, 38, 42, 44, 46, 47,
- 36, 22, 6, -10, -23, -39, -57, -74, -78, -79, -75, -65, -51, -33, -11, 9,
- 25, 37, 46, 55, 56, 48, 34, 21, 10, 4, -4, -14, -20, -25, -24, -21,
- -12, -3, 8, 17, 26, 36, 47, 50, 50, 47, 36, 25, 10, -5, -21, -40,
- -57, -75, -82, -79, -75, -64, -51, -37, -16, 5, 25, 40, 48, 55, 55, 49,
- 37, 25, 15, 6, -6, -18, -26, -29, -25, -20, -16, -7, 5, 17, 29, 39,
- 49, 56, 56, 51, 39, 28, 15, 0, -17, -38, -58, -75, -86, -86, -80, -70,
- -54, -37, -16, 7, 25, 42, 50, 55, 58, 52, 40, 25, 11, 2, -5, -14,
- -21, -26, -26, -18, -12, -5, 4, 13, 25, 34, 45, 53, 55, 48, 39, 25,
- 16, 3, -13, -31, -54, -70, -83, -85, -78, -68, -55, -38, -20, 1, 20, 36,
- 46, 51, 55, 48, 39, 27, 17, 7, -5, -13, -20, -23, -23, -18, -10, -4,
- 3, 10, 21, 29, 40, 48, 52, 50, 40, 28, 20, 10, -5, -24, -48, -67,
- -82, -87, -81, -73, -56, -44, -25, -5, 15, 34, 46, 52, 55, 51, 39, 27,
- 18, 7, -2, -13, -22, -25, -24, -16, -9, 1, 8, 13, 22, 30, 42, 48,
- 50, 47, 38, 26, 15, 6, -8, -22, -41, -61, -77, -86, -81, -70, -54, -40,
- -27, -8, 12, 31, 42, 49, 50, 48, 38, 26, 16, 7, -4, -11, -18, -22,
- -21, -16, -9, 0, 9, 15, 21, 26, 35, 47, 50, 46, 36, 28, 18, 7,
- -7, -22, -37, -53, -70, -81, -83, -72, -58, -43, -30, -14, 5, 22, 37, 44,
- 46, 44, 37, 26, 17, 8, 2, -7, -12, -17, -16, -12, -6, 3, 8, 13,
- 17, 22, 31, 42, 43, 43, 35, 29, 25, 14, 2, -17, -35, -51, -65, -77,
- -80, -75, -63, -47, -34, -18, 4, 21, 32, 38, 41, 41, 36, 28, 17, 8,
- 1, -9, -12, -16, -15, -9, -2, 8, 13, 15, 17, 23, 28, 39, 43, 38,
- 30, 21, 17, 11, 4, -12, -28, -45, -60, -68, -71, -66, -58, -49, -38, -23,
- -5, 15, 27, 34, 34, 32, 28, 23, 18, 13, 4, -2, -7, -9, -7, -4,
- 5, 14, 16, 16, 14, 15, 24, 35, 39, 35, 23, 17, 15, 11, 8, -4,
- -19, -37, -53, -62, -65, -62, -57, -53, -43, -31, -14, 5, 19, 27, 31, 28,
- 26, 23, 20, 18, 11, 5, -2, -5, 0, 3, 8, 14, 16, 15, 11, 7,
- 12, 23, 32, 32, 21, 12, 10, 13, 12, 6, -9, -27, -43, -50, -55, -53,
- -51, -52, -44, -38, -23, -6, 7, 18, 22, 19, 16, 15, 16, 19, 17, 12,
- 6, 3, 7, 10, 16, 20, 23, 20, 14, 8, 9, 17, 27, 26, 17, 6,
- 3, 7, 10, 7, -5, -18, -32, -41, -46, -45, -45, -45, -44, -40, -30, -16,
- -3, 8, 15, 12, 10, 11, 16, 19, 19, 16, 12, 10, 11, 15, 20, 25,
- 26, 24, 18, 11, 6, 11, 17, 21, 15, 3, -6, -2, 4, 7, 2, -14,
- -25, -32, -36, -38, -37, -37, -35, -33, -33, -25, -15, -4, 3, 4, 0, -3,
- 2, 13, 21, 21, 20, 17, 19, 23, 27, 31, 33, 31, 24, 16, 4, 2,
- 7, 13, 13, 3, -10, -9, 0, 8, 7, -3, -15, -22, -24, -30, -32, -37,
- -39, -38, -37, -34, -28, -17, -8, -2, -4, -4, 4, 16, 26, 30, 26, 22,
- 22, 25, 29, 31, 30, 29, 24, 17, 6, -2, 7, 10, 13, 4, -11, -15,
- -10, 3, 8, 2, -10, -17, -17, -17, -23, -29, -35, -37, -34, -36, -35, -28,
- -19, -10, -11, -14, -8, 8, 21, 26, 26, 21, 24, 31, 38, 40, 38, 37,
- 33, 26, 15, 4, 1, 2, 1, -6, -19, -24, -18, -7, 2, 5, -4, -10,
- -9, -6, -7, -16, -27, -33, -35, -38, -41, -38, -32, -22, -20, -18, -10, 4,
- 20, 29, 31, 30, 28, 32, 38, 43, 42, 39, 34, 28, 14, 4, 1, 3,
- 4, -5, -21, -30, -26, -14, 1, 3, -4, -8, -8, 0, 0, -8, -15, -26,
- -29, -35, -40, -40, -36, -30, -28, -29, -22, -10, 9, 22, 28, 28, 27, 30,
- 39, 46, 50, 50, 43, 33, 21, 9, 3, 3, 1, -10, -22, -35, -34, -22,
- -8, 2, 0, -6, -7, 0, 5, -2, -9, -18, -28, -34, -41, -43, -39, -35,
- -33, -33, -25, -12, 5, 19, 26, 29, 31, 31, 39, 46, 51, 52, 47, 38,
- 27, 18, 10, 5, -3, -13, -22, -33, -36, -28, -16, -4, -2, -4, -6, 0,
- 8, 7, 0, -12, -22, -33, -40, -42, -39, -37, -38, -39, -32, -17, 2, 15,
- 24, 25, 28, 33, 39, 47, 51, 53, 51, 44, 35, 23, 15, 8, 1, -12,
- -25, -37, -41, -33, -22, -11, -4, -5, -3, 3, 10, 13, 6, -5, -17, -28,
- -38, -43, -44, -44, -44, -43, -36, -23, -7, 7, 20, 26, 29, 35, 43, 51,
- 54, 58, 56, 52, 44, 29, 18, 9, -2, -12, -28, -39, -45, -38, -26, -16,
- -7, -3, 1, 6, 12, 15, 12, 3, -11, -25, -37, -41, -43, -46, -47, -46,
- -39, -28, -15, 0, 11, 21, 25, 31, 38, 46, 53, 60, 62, 59, 53, 42,
- 32, 19, 6, -10, -27, -41, -47, -47, -39, -31, -21, -9, -2, 5, 11, 16,
- 19, 13, 2, -15, -30, -35, -37, -43, -47, -49, -42, -32, -21, -11, 0, 8,
- 19, 27, 38, 47, 51, 58, 63, 63, 59, 50, 41, 28, 10, -9, -26, -37,
- -43, -44, -40, -33, -23, -11, 0, 6, 9, 14, 15, 13, 1, -15, -25, -32,
- -34, -43, -49, -50, -43, -30, -20, -13, -9, 0, 10, 23, 36, 46, 52, 55,
- 62, 65, 66, 61, 51, 36, 15, -7, -24, -34, -42, -45, -46, -42, -34, -20,
- -5, 5, 11, 14, 16, 13, 2, -10, -18, -24, -31, -39, -49, -48, -42, -34,
- -24, -18, -15, -8, 2, 13, 29, 42, 51, 57, 62, 65, 70, 69, 60, 45,
- 20, -3, -24, -37, -43, -46, -49, -48, -39, -24, -6, 5, 12, 17, 20, 16,
- 6, -9, -15, -21, -26, -38, -50, -56, -50, -37, -26, -23, -19, -14, -4, 11,
- 27, 42, 54, 58, 63, 65, 68, 70, 63, 50, 26, 1, -21, -37, -43, -44,
- -44, -44, -40, -28, -11, 5, 10, 16, 18, 14, 5, -12, -19, -22, -24, -33,
- -47, -52, -52, -38, -25, -17, -17, -16, -10, 4, 22, 39, 53, 59, 62, 63,
- 66, 68, 66, 55, 32, 9, -17, -34, -43, -42, -39, -38, -38, -31, -19, -3,
- 10, 17, 19, 12, 3, -12, -21, -24, -24, -31, -40, -49, -52, -41, -30, -18,
- -15, -17, -10, 0, 16, 33, 47, 59, 65, 64, 65, 67, 63, 56, 38, 13,
- -12, -32, -41, -39, -35, -33, -32, -27, -17, -4, 8, 15, 16, 13, 4, -11,
- -20, -25, -27, -32, -40, -48, -52, -46, -37, -25, -18, -16, -10, 1, 16, 33,
- 49, 59, 66, 67, 65, 66, 62, 51, 38, 15, -9, -30, -38, -41, -33, -29,
- -26, -23, -17, -5, 7, 16, 15, 14, 5, -9, -19, -27, -31, -34, -40, -47,
- -52, -49, -40, -30, -22, -16, -8, 4, 19, 32, 46, 59, 67, 71, 69, 64,
- 57, 49, 36, 17, -7, -27, -38, -40, -35, -28, -23, -19, -12, -5, 6, 12,
- 16, 15, 10, -5, -19, -28, -32, -36, -39, -46, -53, -52, -45, -34, -25, -18,
- -7, 6, 20, 33, 46, 60, 67, 74, 71, 65, 56, 46, 37, 18, -2, -20,
- -33, -38, -38, -30, -22, -16, -12, -6, 2, 6, 15, 15, 11, 1, -11, -19,
- -31, -37, -42, -46, -51, -54, -53, -46, -35, -26, -14, 3, 17, 33, 45, 57,
- 67, 75, 77, 71, 62, 50, 36, 18, 0, -19, -31, -36, -37, -31, -23, -17,
- -11, -6, 1, 6, 11, 15, 14, 8, -3, -16, -27, -37, -41, -47, -52, -58,
- -60, -55, -46, -32, -16, 0, 17, 32, 46, 59, 70, 79, 80, 75, 65, 51,
- 35, 20, 2, -15, -27, -38, -42, -36, -27, -17, -10, -4, 3, 7, 12, 18,
- 19, 14, 5, -7, -22, -37, -46, -53, -57, -62, -67, -65, -58, -43, -22, 1,
- 20, 35, 48, 60, 69, 79, 82, 79, 68, 53, 36, 21, 4, -11, -24, -36,
- -40, -38, -31, -21, -14, -5, 1, 5, 11, 17, 22, 19, 14, -2, -17, -35,
- -48, -55, -63, -67, -73, -72, -64, -49, -27, -4, 19, 36, 52, 64, 73, 81,
- 85, 82, 72, 56, 36, 20, 3, -14, -24, -33, -36, -35, -32, -22, -13, -6,
- 2, 7, 10, 15, 19, 19, 17, 6, -10, -29, -48, -58, -67, -71, -75, -78,
- -72, -58, -35, -10, 16, 35, 52, 65, 74, 80, 86, 87, 79, 62, 39, 21,
- 5, -11, -22, -33, -39, -39, -34, -25, -15, -7, 3, 8, 16, 17, 21, 22,
- 19, 9, -6, -27, -47, -60, -71, -77, -80, -81, -73, -61, -39, -12, 16, 36,
- 52, 63, 73, 80, 85, 87, 76, 59, 41, 23, 8, -7, -18, -29, -36, -38,
- -33, -23, -13, -8, 1, 6, 14, 18, 19, 23, 23, 17, 1, -20, -43, -57,
- -67, -78, -83, -89, -81, -67, -45, -19, 9, 35, 55, 67, 74, 80, 87, 91,
- 83, 68, 44, 24, 6, -9, -21, -29, -36, -39, -39, -31, -20, -10, 1, 13,
- 20, 26, 26, 27, 28, 22, 8, -16, -40, -60, -75, -86, -93, -95, -89, -75,
- -52, -24, 7, 37, 57, 69, 77, 83, 90, 93, 85, 70, 48, 27, 8, -8,
- -19, -26, -32, -35, -39, -37, -28, -17, -2, 9, 19, 21, 27, 31, 32, 29,
- 12, -9, -32, -54, -71, -86, -94, -96, -90, -82, -62, -33, 2, 34, 56, 69,
- 78, 87, 94, 94, 85, 69, 49, 29, 9, -10, -21, -27, -30, -33, -37, -36,
- -29, -17, -5, 9, 19, 25, 27, 31, 33, 33, 21, -2, -25, -51, -71, -86,
- -95, -95, -92, -85, -69, -42, -8, 27, 52, 67, 74, 83, 92, 95, 89, 75,
- 56, 35, 16, -6, -17, -26, -28, -34, -41, -39, -37, -25, -9, 6, 20, 28,
- 31, 37, 37, 34, 24, 3, -20, -46, -69, -85, -96, -99, -97, -89, -73, -47,
- -11, 21, 45, 61, 73, 84, 92, 95, 89, 77, 61, 41, 20, -2, -13, -20,
- -28, -36, -43, -46, -40, -30, -16, 0, 12, 24, 30, 38, 43, 41, 33, 13,
- -14, -39, -63, -80, -93, -98, -100, -94, -76, -52, -19, 14, 38, 56, 70, 80,
- 90, 94, 88, 75, 58, 40, 22, 6, -8, -19, -25, -33, -39, -41, -38, -31,
- -19, -5, 7, 21, 31, 39, 45, 42, 32, 15, -8, -32, -55, -77, -93, -102,
- -101, -94, -80, -57, -29, 5, 34, 54, 70, 78, 88, 96, 92, 80, 62, 41,
- 24, 8, -9, -21, -32, -35, -38, -41, -39, -35, -22, -6, 6, 21, 31, 39,
- 46, 44, 35, 18, -5, -27, -49, -70, -86, -97, -102, -96, -84, -58, -30, -2,
- 26, 45, 62, 74, 82, 89, 89, 80, 66, 46, 28, 12, -3, -14, -26, -36,
- -39, -42, -40, -36, -28, -15, 0, 17, 30, 37, 45, 48, 40, 23, 3, -20,
- -43, -64, -81, -93, -98, -96, -85, -65, -38, -8, 20, 40, 55, 68, 80, 88,
- 88, 82, 68, 54, 35, 18, 2, -12, -24, -35, -40, -45, -45, -41, -33, -20,
- -4, 15, 31, 41, 49, 52, 48, 32, 13, -14, -38, -59, -77, -92, -101, -102,
- -91, -70, -45, -15, 15, 38, 53, 65, 77, 89, 91, 85, 71, 52, 38, 21,
- 5, -12, -26, -36, -42, -45, -45, -43, -34, -22, -7, 9, 26, 39, 50, 56,
- 50, 34, 14, -7, -29, -50, -69, -84, -96, -98, -90, -72, -50, -24, 7, 32,
- 48, 57, 68, 84, 91, 88, 74, 58, 44, 30, 11, -9, -26, -38, -41, -46,
- -45, -44, -38, -23, -7, 9, 24, 36, 49, 55, 51, 35, 18, -3, -24, -45,
- -64, -78, -89, -93, -90, -75, -54, -29, 0, 23, 42, 54, 67, 80, 90, 91,
- 81, 65, 48, 31, 13, -5, -24, -41, -50, -53, -51, -46, -42, -28, -10, 8,
- 23, 36, 50, 59, 56, 44, 26, 8, -13, -35, -56, -77, -89, -94, -92, -80,
- -61, -39, -11, 14, 33, 50, 63, 77, 88, 89, 81, 67, 54, 38, 21, 1,
- -23, -39, -50, -54, -53, -46, -42, -31, -17, 1, 17, 33, 46, 56, 56, 46,
- 33, 16, -4, -24, -46, -67, -82, -92, -94, -87, -67, -45, -19, 4, 22, 43,
- 62, 76, 87, 90, 87, 76, 59, 40, 20, 1, -22, -40, -55, -62, -58, -50,
- -40, -29, -17, -3, 14, 33, 49, 59, 58, 49, 35, 21, 2, -17, -39, -59,
- -76, -90, -93, -86, -70, -49, -29, -8, 12, 33, 57, 75, 84, 87, 84, 78,
- 65, 47, 28, 6, -18, -39, -58, -65, -64, -57, -44, -33, -22, -10, 6, 26,
- 44, 56, 56, 48, 40, 27, 11, -8, -30, -49, -65, -80, -86, -87, -72, -51,
- -31, -13, 5, 24, 48, 70, 81, 86, 83, 79, 69, 51, 30, 8, -16, -37,
- -55, -65, -67, -61, -48, -36, -21, -10, 5, 22, 40, 55, 58, 53, 43, 31,
- 16, -2, -23, -45, -60, -74, -82, -86, -75, -56, -36, -16, 1, 21, 44, 65,
- 81, 88, 85, 81, 72, 54, 33, 8, -18, -41, -58, -71, -74, -70, -56, -41,
- -23, -6, 8, 23, 38, 53, 60, 59, 50, 37, 22, 1, -20, -41, -56, -69,
- -79, -83, -78, -62, -42, -20, 2, 22, 41, 59, 77, 86, 87, 79, 67, 50,
- 31, 10, -15, -36, -52, -63, -69, -69, -59, -41, -23, -9, 4, 15, 29, 44,
- 55, 56, 53, 43, 27, 12, -8, -27, -44, -57, -68, -78, -77, -67, -48, -29,
- -12, 12, 32, 52, 70, 79, 84, 82, 73, 59, 38, 15, -9, -33, -52, -63,
- -71, -72, -66, -50, -30, -13, 2, 12, 27, 42, 50, 54, 54, 46, 34, 19,
- -2, -19, -35, -47, -61, -71, -72, -66, -51, -36, -19, 5, 27, 46, 63, 74,
- 79, 79, 70, 58, 41, 21, 3, -24, -44, -58, -66, -66, -65, -52, -36, -22,
- -10, 4, 18, 34, 43, 49, 52, 48, 43, 31, 14, -4, -21, -35, -51, -61,
- -66, -64, -56, -43, -29, -8, 16, 37, 54, 67, 72, 74, 70, 61, 46, 27,
- 7, -19, -40, -56, -62, -62, -63, -55, -43, -26, -10, 3, 13, 26, 38, 44,
- 47, 43, 39, 30, 19, 5, -12, -24, -40, -47, -51, -53, -51, -44, -32, -14,
- 6, 24, 41, 54, 61, 63, 61, 56, 47, 32, 13, -9, -31, -46, -56, -53,
- -54, -54, -48, -37, -18, -3, 8, 17, 27, 33, 38, 39, 39, 37, 30, 18,
- 1, -16, -29, -35, -39, -42, -47, -47, -39, -22, -3, 14, 29, 42, 51, 57,
- 56, 54, 45, 36, 20, -2, -23, -41, -50, -51, -52, -53, -51, -42, -27, -8,
- 5, 12, 19, 28, 35, 40, 39, 40, 37, 28, 12, -7, -23, -28, -30, -37,
- -43, -49, -45, -32, -15, 3, 19, 34, 45, 49, 49, 51, 47, 41, 26, 6,
- -18, -34, -43, -45, -45, -48, -51, -49, -33, -15, -2, 8, 12, 19, 26, 33,
- 38, 38, 38, 34, 25, 8, -11, -19, -20, -23, -32, -43, -48, -41, -24, -8,
- 10, 21, 31, 38, 43, 47, 48, 45, 34, 16, -9, -31, -41, -42, -42, -46,
- -52, -52, -40, -23, -6, 6, 11, 17, 24, 30, 35, 38, 39, 40, 29, 14,
- -3, -14, -14, -15, -24, -36, -47, -45, -33, -15, 3, 14, 23, 29, 35, 39,
- 44, 45, 38, 22, -3, -26, -38, -37, -37, -41, -50, -56, -45, -26, -8, 5,
- 12, 16, 22, 27, 32, 39, 41, 41, 33, 17, 1, -9, -8, -8, -16, -30,
- -41, -45, -35, -21, -5, 10, 18, 24, 28, 31, 38, 42, 39, 25, 2, -23,
- -36, -36, -37, -39, -47, -53, -47, -31, -11, 3, 12, 16, 23, 27, 32, 37,
- 40, 41, 33, 18, 2, -7, -8, -6, -10, -23, -36, -41, -35, -20, -6, 7,
- 14, 17, 24, 29, 36, 42, 40, 28, 5, -20, -35, -38, -38, -39, -45, -51,
- -46, -33, -15, 2, 13, 22, 27, 28, 27, 30, 37, 41, 35, 20, 5, -4,
- -4, -2, -3, -13, -28, -35, -32, -23, -10, 3, 11, 14, 14, 20, 28, 37,
- 40, 27, 7, -16, -31, -36, -37, -36, -41, -44, -45, -35, -18, 1, 12, 19,
- 25, 26, 27, 31, 34, 39, 34, 20, 8, 0, 0, 1, 0, -9, -23, -33,
- -34, -24, -10, 2, 8, 8, 10, 16, 27, 34, 35, 27, 10, -10, -27, -35,
- -35, -34, -39, -46, -47, -38, -22, -3, 10, 19, 26, 31, 32, 32, 35, 41,
- 39, 25, 9, -2, -3, -2, -2, -7, -19, -30, -33, -26, -14, -3, 6, 6,
- 7, 12, 26, 37, 37, 26, 10, -8, -25, -35, -39, -39, -42, -47, -49, -42,
- -27, -4, 12, 20, 29, 33, 36, 35, 35, 38, 37, 27, 10, -3, -6, -3,
- -2, -7, -16, -24, -28, -24, -13, -4, 4, 5, 7, 9, 19, 30, 33, 28,
- 12, -6, -24, -35, -40, -39, -42, -47, -47, -41, -26, -8, 10, 22, 31, 36,
- 41, 39, 34, 33, 33, 29, 15, 2, -7, -8, -6, -6, -10, -18, -24, -24,
- -15, -5, 6, 7, 7, 10, 17, 23, 23, 18, 9, -7, -23, -36, -42, -41,
- -41, -45, -45, -39, -28, -11, 7, 21, 31, 36, 39, 39, 34, 31, 33, 29,
- 19, 7, -5, -6, -6, -4, -6, -13, -17, -20, -16, -8, 1, 6, 7, 7,
- 11, 16, 20, 18, 9, -7, -24, -37, -43, -42, -42, -42, -45, -41, -28, -11,
- 7, 19, 28, 35, 40, 42, 38, 33, 29, 27, 21, 10, -2, -8, -8, -6,
- -8, -11, -13, -16, -14, -8, 1, 5, 8, 9, 15, 19, 20, 18, 9, -4,
- -18, -34, -42, -46, -47, -45, -47, -45, -36, -20, 0, 13, 26, 36, 45, 48,
- 42, 35, 29, 28, 26, 20, 6, -6, -10, -10, -6, -7, -8, -10, -14, -10,
- -7, 0, 6, 8, 13, 14, 16, 13, 7, -3, -13, -27, -37, -44, -49, -44,
- -42, -40, -37, -25, -9, 9, 23, 31, 41, 44, 44, 37, 30, 27, 28, 27,
- 15, 2, -7, -9, -6, -7, -9, -8, -13, -12, -8, -3, 4, 9, 13, 14,
- 14, 11, 6, 0, -9, -23, -34, -43, -49, -46, -42, -40, -35, -29, -13, 3,
- 19, 31, 41, 45, 43, 37, 31, 29, 30, 28, 19, 4, -5, -7, -7, -5,
- -8, -7, -9, -11, -9, -4, 0, 6, 12, 14, 13, 9, 5, -3, -9, -19,
- -28, -37, -48, -48, -45, -39, -34, -30, -18, -5, 12, 23, 34, 42, 44, 39,
- 34, 32, 31, 33, 30, 18, 8, 1, -5, -6, -5, -5, -8, -13, -16, -14,
- -7, 2, 7, 11, 10, 7, 4, -2, -7, -12, -22, -32, -45, -50, -45, -38,
- -33, -30, -24, -13, 2, 20, 31, 39, 43, 42, 38, 36, 33, 33, 33, 24,
- 14, 1, -8, -9, -7, -4, -5, -11, -16, -16, -11, -4, 2, 9, 8, 7,
- 3, -3, -6, -9, -15, -24, -38, -47, -48, -42, -35, -32, -29, -21, -9, 11,
- 27, 35, 42, 42, 42, 40, 40, 38, 36, 30, 19, 8, -4, -9, -8, -5,
- -5, -12, -18, -20, -15, -5, -2, 3, 4, 5, 6, 1, -3, -8, -12, -19,
- -31, -43, -47, -43, -36, -35, -36, -32, -19, 2, 19, 30, 38, 42, 46, 49,
- 50, 47, 43, 39, 28, 16, 1, -10, -13, -11, -9, -14, -21, -25, -20, -10,
- -4, 1, 3, 4, 7, 4, -3, -7, -7, -10, -23, -38, -47, -46, -41, -37,
- -38, -37, -27, -11, 11, 24, 33, 38, 45, 50, 53, 52, 48, 43, 37, 25,
- 10, -3, -11, -11, -11, -13, -20, -27, -29, -22, -14, -7, -2, 2, 6, 3,
- -2, -3, 0, 0, -11, -28, -41, -45, -39, -35, -36, -39, -37, -24, -7, 11,
- 22, 32, 41, 51, 55, 56, 54, 53, 50, 40, 23, 6, -5, -10, -11, -14,
- -20, -28, -34, -33, -25, -16, -10, -5, 0, 0, 1, 2, 4, 5, -4, -16,
- -29, -35, -37, -37, -35, -39, -39, -32, -19, 0, 13, 23, 36, 46, 54, 58,
- 57, 59, 56, 47, 33, 16, 3, -5, -9, -11, -19, -29, -36, -39, -33, -26,
- -18, -12, -7, -5, -2, 4, 11, 15, 10, -3, -18, -29, -32, -35, -36, -41,
- -44, -40, -30, -18, 0, 13, 28, 41, 50, 59, 63, 66, 66, 60, 44, 26,
- 11, 2, -6, -12, -19, -29, -38, -44, -41, -33, -25, -16, -9, -8, -6, 1,
- 11, 18, 16, 8, -6, -17, -27, -32, -36, -39, -43, -44, -37, -30, -12, 8,
- 26, 39, 46, 56, 64, 70, 72, 66, 51, 36, 18, 7, -4, -11, -18, -29,
- -42, -50, -51, -45, -35, -23, -14, -10, -9, 0, 14, 27, 29, 20, 7, -5,
- -15, -23, -30, -38, -45, -50, -49, -43, -30, -9, 13, 31, 41, 52, 65, 75,
- 79, 77, 66, 50, 30, 13, 3, -6, -14, -26, -41, -53, -57, -54, -44, -32,
- -23, -17, -13, -5, 10, 24, 31, 28, 20, 9, -5, -17, -26, -35, -40, -48,
- -54, -53, -44, -23, 0, 21, 35, 46, 60, 73, 81, 83, 77, 60, 42, 25,
- 11, 1, -11, -25, -42, -57, -64, -62, -54, -43, -33, -24, -17, -6, 9, 23,
- 37, 37, 33, 19, 6, -9, -20, -30, -41, -49, -57, -59, -54, -38, -16, 10,
- 31, 46, 58, 70, 78, 85, 84, 73, 54, 32, 16, 5, -5, -22, -41, -60,
- -72, -71, -66, -54, -43, -30, -19, -6, 10, 25, 41, 47, 43, 32, 20, 7,
- -10, -25, -40, -52, -61, -68, -65, -54, -34, -11, 16, 39, 57, 72, 80, 88,
- 91, 83, 67, 46, 28, 13, 1, -18, -40, -62, -77, -77, -70, -63, -54, -43,
- -30, -12, 7, 25, 40, 51, 51, 42, 31, 19, 3, -13, -32, -48, -60, -68,
- -71, -63, -49, -28, -2, 23, 46, 66, 77, 86, 92, 89, 82, 62, 43, 22,
- 7, -12, -39, -59, -74, -80, -78, -72, -63, -50, -35, -17, 5, 22, 35, 45,
- 49, 49, 42, 31, 13, -7, -25, -38, -49, -59, -66, -65, -57, -42, -20, 8,
- 34, 55, 69, 79, 84, 84, 84, 77, 64, 42, 18, -6, -29, -49, -69, -82,
- -87, -87, -78, -66, -48, -27, -4, 17, 33, 47, 56, 60, 58, 49, 31, 8,
- -18, -36, -47, -57, -67, -75, -74, -60, -36, -3, 25, 48, 65, 76, 83, 87,
- 90, 88, 77, 52, 24, -4, -26, -42, -61, -77, -91, -94, -85, -70, -54, -34,
- -11, 12, 30, 44, 56, 63, 66, 61, 43, 19, -8, -27, -39, -49, -62, -74,
- -80, -71, -49, -20, 9, 34, 56, 70, 79, 86, 93, 96, 91, 70, 41, 11,
- -18, -39, -58, -77, -91, -99, -95, -83, -65, -42, -17, 7, 27, 43, 57, 66,
- 69, 67, 55, 32, 5, -21, -32, -42, -56, -73, -84, -79, -60, -33, -5, 21,
- 44, 61, 72, 80, 92, 100, 99, 82, 54, 23, -10, -31, -51, -71, -87, -101,
- -101, -92, -76, -49, -24, 1, 21, 37, 52, 66, 72, 72, 64, 44, 18, -7,
- -23, -31, -45, -64, -79, -83, -71, -46, -18, 7, 27, 46, 62, 72, 85, 97,
- 100, 92, 65, 35, 2, -22, -40, -60, -78, -92, -100, -96, -82, -59, -29, -6,
- 15, 28, 44, 57, 65, 67, 65, 49, 27, 2, -17, -23, -35, -53, -70, -79,
- -73, -52, -27, -4, 16, 35, 54, 65, 77, 88, 95, 93, 73, 44, 12, -17,
- -38, -54, -74, -86, -97, -98, -89, -69, -37, -11, 9, 27, 42, 56, 65, 68,
- 71, 59, 39, 13, -9, -20, -30, -45, -62, -74, -75, -60, -41, -18, 3, 23,
- 43, 60, 74, 83, 91, 91, 78, 52, 22, -8, -30, -46, -66, -82, -90, -92,
- -85, -70, -44, -17, 5, 22, 33, 45, 56, 60, 63, 56, 39, 21, 5, -9,
- -20, -33, -49, -62, -70, -62, -47, -28, -9, 11, 29, 47, 60, 73, 83, 87,
- 81, 62, 32, 4, -21, -39, -60, -78, -88, -90, -86, -73, -55, -28, -2, 18,
- 30, 42, 50, 57, 58, 53, 44, 27, 15, 4, -10, -24, -40, -53, -59, -57,
- -49, -38, -21, -3, 17, 34, 49, 62, 75, 81, 76, 63, 39, 15, -11, -31,
- -50, -69, -79, -84, -82, -73, -57, -34, -7, 12, 26, 35, 42, 50, 56, 53,
- 42, 31, 20, 13, 1, -16, -30, -43, -50, -51, -49, -42, -28, -11, 7, 23,
- 38, 52, 65, 75, 73, 62, 43, 20, -2, -24, -43, -60, -69, -74, -74, -69,
- -59, -42, -19, 2, 19, 27, 34, 41, 48, 50, 45, 39, 33, 25, 13, -3,
- -18, -32, -42, -47, -49, -47, -40, -27, -8, 11, 28, 43, 57, 69, 73, 65,
- 50, 31, 8, -16, -36, -53, -63, -70, -72, -70, -62, -46, -25, -6, 11, 23,
- 30, 38, 45, 49, 50, 46, 42, 33, 22, 6, -13, -25, -37, -43, -48, -50,
- -45, -35, -18, 2, 21, 39, 51, 61, 64, 63, 53, 38, 19, -6, -30, -49,
- -59, -63, -65, -66, -64, -52, -31, -14, 2, 13, 25, 35, 42, 46, 46, 47,
- 48, 44, 33, 15, -6, -21, -32, -37, -42, -48, -46, -39, -26, -8, 12, 31,
- 45, 55, 58, 57, 51, 39, 22, 2, -21, -39, -49, -56, -59, -62, -59, -52,
- -38, -22, -9, 5, 16, 25, 32, 40, 46, 51, 54, 52, 40, 24, 5, -11,
- -20, -28, -35, -44, -48, -43, -33, -17, 0, 18, 32, 44, 48, 49, 48, 40,
- 28, 11, -10, -26, -37, -45, -52, -58, -57, -51, -41, -29, -19, -10, 3, 15,
- 27, 36, 40, 50, 59, 60, 51, 33, 15, 2, -11, -21, -34, -45, -49, -45,
- -36, -25, -11, 8, 26, 38, 43, 42, 41, 39, 31, 16, -5, -24, -31, -37,
- -43, -51, -54, -49, -40, -31, -24, -13, -3, 12, 22, 29, 33, 43, 55, 60,
- 53, 37, 18, 5, -4, -12, -23, -35, -44, -42, -35, -26, -15, -2, 15, 26,
- 33, 31, 31, 29, 28, 21, 6, -13, -27, -30, -37, -44, -48, -45, -39, -34,
- -28, -18, -8, 4, 17, 23, 31, 40, 51, 58, 56, 42, 25, 12, 2, -7,
- -16, -27, -36, -39, -37, -31, -21, -12, 3, 14, 21, 25, 23, 23, 25, 23,
- 11, -4, -16, -21, -26, -34, -39, -40, -34, -31, -30, -23, -17, -3, 9, 16,
- 23, 31, 42, 54, 57, 49, 29, 14, 7, 4, -3, -15, -26, -32, -32, -31,
- -24, -16, -5, 5, 8, 10, 9, 10, 16, 19, 14, 4, -8, -14, -16, -21,
- -29, -34, -33, -30, -29, -26, -20, -10, 2, 11, 20, 28, 40, 51, 55, 51,
- 33, 17, 9, 6, 4, -9, -20, -28, -32, -29, -25, -20, -11, -2, 3, 4,
- 1, 6, 12, 18, 16, 8, -5, -10, -14, -17, -20, -23, -25, -26, -28, -26,
- -21, -12, -2, 6, 13, 20, 29, 40, 48, 48, 37, 23, 13, 8, 7, 3,
- -6, -15, -22, -24, -24, -21, -16, -10, -6, -11, -15, -10, 1, 12, 15, 9,
- 4, 3, 1, -5, -11, -18, -18, -22, -25, -29, -27, -19, -7, 4, 10, 14,
- 21, 35, 46, 48, 40, 27, 16, 13, 11, 11, 5, -5, -14, -19, -21, -24,
- -19, -14, -13, -17, -21, -21, -11, 1, 11, 12, 5, 3, 2, 5, 6, 0,
- -6, -16, -20, -25, -26, -20, -12, -4, 1, 5, 11, 25, 38, 46, 41, 33,
- 21, 17, 15, 15, 14, 8, -3, -14, -23, -27, -26, -21, -20, -22, -26, -25,
- -20, -7, 5, 10, 10, 8, 5, 6, 6, 5, 1, -7, -14, -20, -23, -21,
- -17, -11, -4, 2, 7, 17, 29, 38, 40, 37, 30, 23, 21, 20, 17, 14,
- 5, -6, -19, -26, -29, -25, -24, -27, -28, -28, -26, -18, -4, 6, 9, 8,
- 4, 5, 10, 12, 11, 3, -8, -15, -18, -18, -15, -11, -10, -5, 1, 8,
- 16, 26, 35, 35, 31, 24, 22, 21, 22, 21, 16, 5, -12, -24, -30, -31,
- -29, -31, -32, -31, -32, -22, -12, 0, 7, 11, 12, 10, 11, 15, 13, 10,
- 2, -10, -13, -16, -17, -14, -14, -12, -6, 0, 10, 20, 26, 32, 30, 29,
- 27, 26, 28, 26, 22, 13, -2, -16, -25, -30, -32, -33, -35, -35, -34, -28,
- -19, -12, -5, 1, 5, 9, 11, 16, 17, 18, 11, 3, -4, -10, -12, -13,
- -12, -13, -14, -10, -4, 8, 20, 27, 31, 31, 28, 29, 31, 30, 26, 17,
- 5, -9, -23, -32, -37, -36, -34, -35, -34, -32, -24, -16, -7, 2, 4, 6,
- 10, 16, 17, 15, 12, 8, 3, -5, -11, -11, -10, -11, -12, -11, -5, 3,
- 13, 22, 30, 32, 27, 25, 25, 28, 27, 19, 7, -8, -22, -31, -34, -32,
- -30, -28, -31, -31, -29, -21, -12, -4, 1, 1, 3, 10, 16, 18, 18, 14,
- 12, 3, -5, -8, -7, -8, -10, -12, -12, -5, 6, 16, 26, 30, 29, 24,
- 25, 26, 29, 23, 13, -2, -16, -26, -32, -33, -30, -30, -30, -30, -29, -25,
- -18, -12, -5, -2, 2, 8, 14, 18, 16, 18, 14, 10, 4, 0, -5, -4,
- -7, -9, -14, -10, -3, 9, 19, 26, 26, 23, 23, 26, 29, 28, 21, 7,
- -10, -19, -25, -26, -27, -27, -29, -30, -32, -31, -27, -19, -13, -9, -7, 0,
- 9, 18, 24, 26, 21, 13, 9, 8, 4, -2, -6, -9, -11, -11, -7, 4,
- 16, 24, 26, 21, 19, 22, 26, 29, 23, 7, -10, -17, -19, -19, -23, -25,
- -25, -25, -26, -26, -29, -26, -17, -14, -9, -7, 1, 12, 21, 26, 23, 18,
- 13, 11, 11, 6, -4, -6, -10, -10, -9, -2, 9, 20, 25, 23, 18, 18,
- 23, 26, 24, 10, -5, -13, -17, -14, -15, -17, -20, -24, -25, -29, -31, -32,
- -28, -22, -16, -13, -8, 2, 14, 25, 27, 27, 22, 17, 15, 13, 10, 5,
- -3, -6, -8, -6, 1, 11, 18, 20, 13, 11, 15, 19, 20, 14, 4, -4,
- -12, -12, -12, -12, -14, -17, -23, -30, -35, -37, -31, -26, -20, -16, -12, -4,
- 9, 22, 28, 26, 22, 17, 14, 15, 11, 8, 6, 2, 0, -2, 4, 11,
- 16, 16, 12, 7, 8, 13, 13, 10, 1, -5, -8, -8, -8, -7, -7, -10,
- -20, -26, -34, -36, -33, -31, -29, -25, -19, -12, 4, 18, 27, 28, 23, 22,
- 18, 19, 17, 14, 9, 7, 4, 0, 2, 8, 14, 16, 12, 2, 0, 2,
- 5, 6, 2, -4, -7, -6, -2, -2, -3, -5, -11, -19, -28, -37, -37, -37,
- -34, -29, -24, -18, -8, 7, 20, 25, 25, 25, 22, 21, 21, 21, 19, 15,
- 11, 6, 6, 6, 10, 11, 6, -2, -5, -5, -2, 0, 0, 0, -4, 0,
- 2, 4, 2, -2, -8, -16, -25, -34, -39, -42, -39, -33, -26, -21, -16, -4,
- 11, 22, 25, 27, 25, 23, 23, 24, 25, 22, 17, 13, 10, 9, 12, 10,
- 4, -5, -12, -12, -11, -9, -8, -6, -5, 1, 4, 8, 10, 7, 4, -7,
- -18, -26, -34, -39, -43, -42, -34, -28, -22, -13, 2, 14, 18, 21, 23, 27,
- 30, 32, 31, 28, 23, 20, 20, 15, 14, 10, 2, -5, -13, -15, -16, -16,
- -12, -12, -5, 1, 5, 8, 8, 10, 8, 0, -13, -23, -27, -33, -40, -44,
- -41, -32, -24, -17, -6, 3, 9, 17, 22, 25, 29, 34, 39, 36, 32, 26,
- 25, 23, 19, 11, 1, -9, -16, -18, -17, -19, -21, -17, -8, 0, 4, 7,
- 8, 10, 11, 6, -4, -13, -21, -25, -35, -40, -41, -37, -26, -21, -13, -8,
- -3, 6, 15, 23, 27, 35, 40, 41, 38, 33, 31, 29, 24, 16, 5, -5,
- -16, -23, -23, -23, -18, -14, -6, 2, 3, 4, 7, 11, 13, 7, -5, -13,
- -21, -25, -32, -40, -42, -37, -28, -21, -14, -13, -9, 1, 11, 22, 27, 33,
- 39, 43, 42, 41, 33, 29, 25, 18, 7, -6, -17, -25, -24, -23, -21, -16,
- -9, 2, 6, 5, 5, 10, 15, 12, 3, -8, -16, -22, -29, -39, -44, -42,
- -34, -27, -22, -21, -17, -8, 4, 19, 29, 40, 48, 53, 51, 49, 43, 38,
- 28, 19, 6, -9, -19, -27, -30, -30, -24, -16, -10, -3, 3, 6, 5, 6,
- 9, 11, 7, 2, -7, -16, -25, -34, -37, -37, -33, -31, -28, -27, -24, -20,
- -10, 8, 22, 35, 46, 52, 53, 54, 49, 46, 37, 23, 9, -7, -18, -24,
- -30, -32, -28, -22, -12, -5, 1, 6, 4, 8, 9, 11, 9, 3, -3, -13,
- -21, -32, -37, -38, -35, -34, -32, -32, -32, -27, -14, 5, 24, 38, 48, 55,
- 56, 56, 54, 50, 40, 23, 4, -10, -18, -24, -26, -29, -29, -24, -17, -5,
- 2, 9, 9, 6, 6, 7, 12, 11, 6, -7, -18, -30, -36, -36, -37, -35,
- -38, -40, -41, -36, -24, -2, 20, 35, 47, 55, 60, 62, 62, 61, 47, 26,
- 7, -12, -18, -22, -24, -28, -33, -31, -24, -12, -2, 7, 9, 5, 4, 5,
- 11, 14, 13, 7, -8, -24, -37, -41, -38, -34, -37, -44, -50, -46, -33, -10,
- 16, 36, 49, 57, 61, 64, 66, 65, 55, 34, 11, -14, -24, -26, -26, -24,
- -30, -34, -33, -24, -7, 5, 12, 10, 5, 6, 9, 16, 22, 21, 10, -10,
- -32, -45, -44, -38, -38, -47, -61, -60, -48, -21, 11, 34, 51, 60, 63, 66,
- 70, 69, 63, 45, 18, -10, -27, -27, -23, -20, -28, -36, -37, -32, -17, -2,
- 8, 9, 5, 6, 8, 15, 24, 30, 25, 5, -22, -41, -44, -40, -38, -50,
- -64, -72, -62, -37, -3, 29, 52, 62, 66, 69, 73, 78, 72, 54, 26, -5,
- -25, -32, -29, -24, -27, -34, -37, -36, -26, -11, 5, 15, 15, 11, 9, 15,
- 26, 35, 33, 14, -14, -37, -49, -47, -45, -51, -63, -72, -66, -42, -10, 22,
- 49, 64, 69, 69, 70, 75, 73, 59, 34, 4, -20, -30, -30, -25, -24, -29,
- -36, -40, -35, -22, -2, 16, 20, 17, 14, 15, 27, 39, 41, 27, -4, -32,
- -48, -54, -53, -59, -65, -73, -71, -55, -23, 16, 49, 67, 70, 68, 71, 77,
- 78, 65, 40, 10, -17, -31, -34, -28, -24, -26, -31, -40, -40, -30, -10, 10,
- 21, 18, 15, 16, 26, 40, 48, 40, 13, -20, -44, -55, -61, -63, -69, -76,
- -76, -63, -35, 6, 41, 66, 75, 71, 71, 75, 77, 67, 44, 17, -10, -25,
- -34, -35, -29, -27, -28, -35, -40, -35, -18, 1, 16, 21, 20, 19, 25, 38,
- 47, 43, 23, -9, -34, -50, -59, -65, -72, -76, -74, -66, -43, -9, 27, 58,
- 71, 69, 70, 71, 73, 67, 48, 25, 2, -18, -28, -33, -29, -25, -25, -31,
- -39, -41, -28, -10, 8, 19, 20, 23, 27, 36, 45, 45, 31, 4, -22, -45,
- -58, -67, -74, -75, -73, -66, -50, -21, 16, 49, 67, 73, 72, 72, 74, 69,
- 53, 33, 9, -11, -25, -34, -35, -31, -27, -30, -38, -43, -33, -16, 6, 18,
- 24, 27, 30, 38, 45, 46, 34, 10, -16, -40, -61, -70, -77, -76, -72, -66,
- -52, -31, 2, 36, 60, 71, 72, 69, 71, 68, 57, 44, 20, 2, -17, -32,
- -36, -33, -31, -31, -40, -46, -41, -29, -5, 16, 27, 34, 35, 41, 49, 51,
- 41, 17, -11, -34, -56, -71, -79, -80, -76, -68, -57, -36, -10, 21, 48, 64,
- 71, 71, 73, 69, 61, 48, 32, 11, -5, -21, -31, -34, -34, -37, -43, -48,
- -45, -34, -14, 8, 25, 34, 41, 43, 49, 51, 43, 26, -2, -27, -49, -65,
- -74, -77, -74, -70, -58, -42, -20, 9, 38, 56, 64, 67, 69, 71, 66, 53,
- 37, 16, 1, -15, -30, -33, -39, -38, -41, -45, -42, -35, -15, 7, 25, 36,
- 41, 45, 49, 49, 40, 23, 1, -20, -41, -59, -71, -75, -73, -65, -57, -45,
- -28, -6, 22, 42, 56, 63, 67, 71, 70, 59, 44, 28, 12, -3, -19, -32,
- -40, -41, -46, -47, -46, -37, -20, -2, 20, 34, 45, 48, 52, 53, 42, 26,
- 4, -15, -35, -51, -65, -70, -70, -68, -61, -50, -34, -15, 9, 28, 45, 54,
- 64, 71, 72, 67, 53, 40, 24, 8, -10, -27, -37, -41, -49, -53, -53, -42,
- -25, -8, 14, 31, 43, 52, 56, 56, 46, 30, 11, -8, -26, -43, -59, -70,
- -69, -68, -62, -55, -44, -25, -4, 17, 36, 48, 62, 69, 69, 67, 57, 47,
- 33, 17, -2, -21, -33, -41, -47, -52, -53, -43, -25, -10, 9, 23, 36, 46,
- 52, 54, 47, 31, 14, -4, -19, -32, -49, -57, -62, -60, -57, -58, -51, -39,
- -19, 6, 23, 38, 51, 60, 68, 71, 67, 58, 44, 27, 7, -17, -32, -41,
- -47, -52, -54, -46, -31, -12, 7, 22, 35, 45, 51, 53, 46, 33, 18, 2,
- -12, -26, -42, -55, -61, -60, -56, -57, -55, -46, -29, -8, 10, 27, 42, 55,
- 65, 70, 69, 61, 49, 34, 16, -5, -23, -36, -45, -51, -54, -50, -35, -17,
- 3, 17, 29, 37, 44, 51, 47, 39, 21, 6, -8, -20, -31, -44, -52, -58,
- -60, -58, -58, -51, -39, -22, -4, 14, 31, 48, 62, 70, 69, 65, 57, 45,
- 28, 7, -15, -31, -44, -50, -53, -50, -39, -24, -6, 11, 24, 33, 43, 46,
- 45, 35, 25, 14, 1, -13, -23, -35, -44, -53, -57, -59, -59, -57, -47, -33,
- -15, 3, 21, 39, 56, 69, 72, 69, 60, 49, 36, 17, -5, -25, -42, -52,
- -52, -48, -40, -26, -9, 9, 20, 29, 34, 39, 40, 34, 25, 16, 6, -6,
- -16, -27, -34, -44, -50, -55, -58, -57, -52, -41, -27, -11, 11, 31, 51, 67,
- 70, 68, 61, 53, 43, 30, 7, -14, -35, -49, -54, -50, -40, -26, -13, -2,
- 9, 22, 30, 38, 41, 36, 28, 20, 12, 4, -5, -15, -26, -41, -52, -58,
- -60, -60, -59, -55, -41, -25, -5, 19, 42, 62, 74, 75, 70, 63, 55, 43,
- 22, -3, -24, -42, -51, -50, -45, -32, -22, -14, -2, 14, 28, 35, 34, 33,
- 30, 25, 21, 11, 4, -6, -18, -32, -46, -56, -61, -61, -62, -60, -51, -39,
- -16, 11, 37, 58, 70, 75, 72, 67, 58, 46, 31, 10, -17, -35, -48, -49,
- -41, -28, -17, -14, -7, 4, 18, 28, 32, 29, 27, 21, 19, 16, 7, 2,
- -11, -22, -35, -48, -57, -61, -60, -60, -56, -47, -30, -5, 23, 48, 63, 72,
- 75, 71, 64, 53, 39, 20, -2, -22, -40, -48, -45, -34, -21, -17, -10, -4,
- 10, 22, 27, 28, 29, 26, 26, 22, 14, 7, -3, -14, -30, -46, -59, -65,
- -65, -65, -64, -56, -41, -17, 15, 42, 62, 73, 77, 75, 69, 57, 43, 25,
- 6, -12, -31, -44, -46, -37, -24, -16, -11, -3, 6, 20, 24, 23, 24, 23,
- 25, 23, 16, 9, 1, -10, -23, -41, -56, -63, -67, -67, -66, -59, -47, -25,
- 3, 32, 54, 70, 75, 76, 70, 62, 47, 32, 15, -3, -21, -38, -44, -41,
- -31, -21, -15, -11, -2, 8, 18, 24, 27, 28, 29, 29, 24, 17, 8, -2,
- -17, -35, -54, -66, -73, -74, -71, -66, -55, -35, -6, 24, 50, 69, 77, 79,
- 74, 63, 51, 38, 22, 2, -17, -35, -42, -39, -32, -24, -17, -11, -5, 6,
- 13, 20, 28, 31, 33, 29, 23, 15, 10, 3, -12, -30, -51, -65, -73, -75,
- -71, -67, -58, -41, -18, 11, 38, 60, 75, 77, 74, 64, 53, 42, 31, 15,
- -7, -25, -38, -40, -37, -29, -24, -15, -11, -2, 9, 17, 28, 33, 36, 33,
- 27, 18, 13, 4, -8, -26, -48, -65, -75, -76, -72, -68, -58, -43, -18, 11,
- 37, 58, 72, 76, 73, 63, 51, 40, 28, 13, -6, -23, -35, -41, -40, -33,
- -24, -16, -9, -2, 7, 18, 29, 38, 42, 38, 31, 21, 11, 3, -10, -26,
- -47, -65, -75, -79, -75, -69, -58, -39, -19, 7, 33, 54, 71, 77, 75, 66,
- 52, 39, 27, 15, -2, -22, -35, -41, -41, -36, -27, -17, -8, 1, 11, 22,
- 33, 41, 47, 45, 35, 21, 11, 4, -7, -24, -46, -66, -77, -81, -79, -73,
- -62, -44, -24, -2, 23, 47, 69, 79, 79, 70, 57, 45, 33, 20, 5, -18,
- -36, -43, -41, -37, -32, -23, -14, -3, 8, 20, 34, 45, 53, 52, 41, 27,
- 16, 7, -5, -24, -47, -69, -83, -86, -84, -74, -62, -44, -22, 1, 24, 47,
- 66, 78, 76, 69, 57, 43, 31, 17, 5, -13, -33, -43, -46, -41, -31, -22,
- -12, 0, 11, 24, 39, 49, 57, 58, 48, 30, 15, 4, -8, -26, -52, -74,
- -86, -89, -83, -74, -60, -43, -21, 1, 22, 45, 65, 78, 79, 68, 54, 40,
- 26, 17, 7, -9, -31, -45, -46, -40, -31, -21, -11, 0, 8, 21, 39, 51,
- 60, 60, 52, 36, 19, 4, -9, -25, -49, -71, -87, -92, -89, -79, -63, -45,
- -24, 0, 22, 43, 65, 75, 80, 70, 57, 44, 30, 16, 2, -14, -31, -46,
- -52, -47, -35, -21, -9, 1, 12, 26, 44, 59, 68, 68, 59, 42, 22, 6,
- -11, -29, -49, -72, -87, -96, -95, -86, -67, -46, -23, -4, 16, 38, 59, 76,
- 82, 74, 61, 45, 31, 20, 3, -14, -30, -44, -51, -51, -41, -26, -11, 3,
- 13, 25, 44, 61, 71, 72, 59, 45, 28, 9, -10, -33, -53, -70, -83, -93,
- -96, -91, -74, -53, -27, -6, 15, 35, 53, 71, 80, 77, 66, 51, 34, 20,
- 3, -15, -30, -45, -53, -55, -48, -32, -17, 1, 16, 29, 47, 62, 73, 77,
- 67, 50, 30, 9, -10, -32, -55, -73, -86, -93, -94, -90, -76, -54, -27, -4,
- 17, 32, 48, 64, 74, 78, 68, 55, 38, 17, 1, -15, -28, -39, -47, -52,
- -49, -37, -21, -3, 16, 31, 46, 61, 70, 75, 70, 55, 36, 13, -9, -32,
- -56, -72, -84, -89, -93, -91, -81, -61, -30, -5, 18, 32, 45, 58, 71, 76,
- 70, 57, 40, 18, 1, -17, -28, -35, -45, -52, -50, -39, -25, -7, 15, 33,
- 48, 60, 67, 73, 70, 60, 42, 19, -8, -34, -57, -69, -77, -83, -87, -92,
- -85, -66, -39, -10, 12, 27, 39, 52, 62, 73, 72, 61, 46, 25, 4, -14,
- -27, -34, -41, -46, -48, -43, -30, -11, 14, 38, 53, 63, 66, 69, 72, 65,
- 48, 23, -4, -31, -56, -72, -81, -83, -87, -91, -87, -72, -46, -15, 11, 28,
- 40, 50, 60, 71, 75, 69, 54, 32, 8, -13, -29, -39, -45, -48, -50, -48,
- -40, -21, 9, 37, 57, 66, 71, 74, 75, 71, 55, 32, 2, -29, -55, -73,
- -81, -84, -87, -89, -88, -75, -49, -19, 10, 29, 39, 48, 53, 62, 72, 68,
- 58, 35, 9, -11, -27, -34, -39, -42, -44, -46, -41, -26, 5, 35, 56, 65,
- 69, 72, 73, 72, 59, 37, 9, -22, -50, -71, -83, -83, -83, -86, -88, -81,
- -55, -24, 5, 24, 37, 48, 54, 59, 64, 66, 59, 41, 17, -9, -27, -36,
- -38, -39, -42, -45, -41, -28, -2, 28, 53, 65, 68, 71, 71, 70, 58, 40,
- 16, -14, -46, -67, -79, -81, -80, -83, -87, -83, -64, -36, -4, 19, 35, 46,
- 51, 58, 65, 69, 64, 49, 26, -2, -25, -38, -41, -39, -40, -43, -45, -33,
- -8, 24, 52, 65, 72, 74, 72, 66, 55, 40, 20, -7, -38, -65, -80, -85,
- -80, -82, -84, -82, -65, -38, -9, 13, 29, 41, 49, 57, 62, 64, 59, 48,
- 29, 6, -19, -36, -39, -37, -35, -38, -39, -31, -11, 19, 47, 63, 70, 71,
- 71, 65, 55, 38, 17, -4, -33, -58, -76, -83, -79, -79, -80, -82, -70, -46,
- -19, 8, 25, 36, 43, 51, 59, 63, 62, 50, 34, 14, -9, -27, -35, -38,
- -36, -38, -39, -30, -15, 10, 34, 52, 67, 73, 74, 68, 54, 37, 21, 2,
- -21, -45, -68, -78, -81, -81, -80, -79, -70, -51, -28, -4, 17, 32, 40, 48,
- 56, 59, 57, 46, 34, 18, 3, -20, -34, -39, -35, -31, -30, -26, -13, 8,
- 31, 48, 61, 67, 69, 66, 53, 38, 16, -4, -23, -41, -58, -72, -78, -80,
- -76, -74, -64, -50, -33, -8, 12, 28, 35, 41, 50, 57, 53, 44, 31, 20,
- 10, -8, -24, -34, -34, -30, -25, -21, -13, 5, 22, 38, 52, 61, 66, 65,
- 53, 36, 15, -4, -18, -33, -45, -61, -73, -79, -78, -72, -62, -49, -33, -13,
- 3, 19, 29, 38, 48, 52, 49, 41, 29, 22, 14, 2, -11, -25, -27, -25,
- -20, -15, -8, 4, 19, 30, 42, 53, 57, 61, 50, 32, 15, -7, -18, -27,
- -37, -50, -65, -73, -72, -66, -57, -49, -37, -19, -3, 13, 23, 32, 41, 44,
- 41, 35, 29, 26, 21, 10, -2, -13, -21, -18, -14, -8, -4, 3, 12, 21,
- 29, 42, 51, 54, 49, 32, 14, -5, -15, -22, -28, -39, -55, -69, -68, -62,
- -52, -44, -37, -25, -11, 4, 16, 24, 32, 37, 35, 28, 23, 23, 23, 18,
- 8, -4, -12, -12, -8, -2, 5, 9, 14, 18, 23, 31, 41, 45, 43, 29,
- 11, -8, -18, -23, -21, -29, -43, -60, -65, -58, -50, -39, -32, -26, -17, -6,
- 8, 18, 25, 31, 29, 24, 17, 20, 24, 25, 19, 8, 0, -5, -3, 4,
- 11, 13, 12, 14, 16, 22, 31, 38, 37, 27, 9, -11, -22, -24, -22, -25,
- -36, -50, -57, -53, -46, -37, -30, -24, -17, -9, 1, 10, 16, 20, 19, 17,
- 13, 14, 21, 24, 24, 19, 10, 8, 9, 13, 18, 20, 15, 12, 11, 14,
- 21, 27, 30, 21, 8, -12, -23, -24, -22, -20, -29, -40, -49, -47, -41, -33,
- -26, -23, -20, -16, -11, -2, 7, 12, 14, 14, 13, 14, 19, 26, 30, 26,
- 20, 11, 11, 16, 21, 26, 22, 18, 15, 14, 15, 19, 20, 16, 4, -15,
- -29, -32, -27, -21, -24, -34, -40, -41, -33, -28, -24, -21, -20, -15, -14, -10,
- -5, 1, 7, 10, 10, 12, 18, 26, 36, 34, 27, 21, 17, 20, 23, 25,
- 24, 19, 11, 10, 9, 12, 16, 14, 3, -16, -32, -34, -27, -19, -20, -27,
- -34, -35, -31, -27, -22, -18, -18, -19, -19, -20, -15, -7, 2, 6, 8, 9,
- 18, 26, 38, 41, 37, 28, 21, 23, 25, 27, 25, 20, 13, 7, 3, 5,
- 9, 11, 4, -14, -31, -35, -29, -20, -18, -23, -26, -32, -29, -25, -23, -15,
- -17, -18, -21, -25, -23, -15, -6, 0, 5, 6, 16, 25, 37, 45, 43, 36,
- 27, 25, 28, 30, 29, 26, 16, 7, -2, -2, 2, 3, -2, -15, -31, -38,
- -35, -23, -15, -15, -19, -23, -26, -23, -21, -15, -12, -18, -24, -27, -25, -19,
- -9, -3, 2, 5, 12, 19, 32, 42, 45, 41, 31, 28, 31, 33, 37, 33,
- 26, 14, 4, -2, -3, -3, -5, -18, -34, -43, -42, -31, -20, -18, -17, -19,
- -18, -16, -13, -9, -8, -13, -22, -32, -32, -28, -19, -11, -6, -2, 7, 18,
- 31, 42, 46, 46, 41, 36, 32, 35, 39, 39, 30, 17, 5, -3, -3, -3,
- -7, -19, -32, -39, -41, -36, -26, -17, -12, -13, -18, -20, -14, -7, -6, -11,
- -23, -32, -34, -28, -23, -15, -9, -2, 9, 17, 28, 37, 44, 48, 45, 38,
- 32, 35, 41, 45, 37, 23, 10, 1, -3, -5, -8, -20, -35, -44, -44, -42,
- -34, -24, -14, -10, -12, -14, -11, -6, -2, -5, -15, -25, -32, -29, -24, -19,
- -15, -10, 1, 10, 20, 31, 40, 45, 48, 43, 39, 39, 45, 51, 43, 28,
- 15, 2, -4, -8, -13, -20, -34, -42, -45, -45, -36, -26, -13, -8, -11, -13,
- -8, -2, 1, -4, -13, -22, -30, -33, -28, -25, -18, -12, -5, 3, 13, 25,
- 37, 46, 47, 45, 40, 41, 47, 53, 49, 35, 21, 10, 2, -6, -11, -22,
- -32, -43, -50, -50, -47, -34, -17, -9, -9, -12, -9, 3, 7, 4, -8, -18,
- -25, -31, -31, -27, -21, -16, -11, -8, 2, 17, 31, 45, 47, 44, 40, 43,
- 54, 60, 58, 42, 26, 14, 4, -5, -14, -26, -37, -47, -54, -53, -49, -38,
- -22, -13, -9, -7, -3, 6, 11, 6, -5, -14, -22, -28, -31, -30, -29, -24,
- -18, -15, -2, 14, 29, 42, 45, 47, 45, 48, 56, 63, 59, 46, 29, 17,
- 5, -4, -11, -23, -36, -49, -53, -52, -48, -40, -29, -21, -16, -11, -2, 5,
- 6, 3, -5, -10, -13, -17, -21, -25, -26, -23, -19, -15, -8, 5, 20, 31,
- 38, 42, 41, 46, 55, 62, 63, 50, 36, 24, 12, 5, -7, -20, -33, -46,
- -51, -51, -48, -40, -33, -27, -20, -15, 0, 9, 7, 1, -6, -10, -11, -16,
- -22, -25, -30, -28, -25, -21, -11, 2, 17, 28, 32, 41, 47, 55, 64, 66,
- 64, 54, 41, 32, 19, 4, -9, -24, -37, -48, -54, -55, -51, -41, -33, -29,
- -24, -15, 0, 13, 14, 8, 1, -5, -6, -10, -17, -24, -30, -32, -33, -32,
- -22, -9, 9, 21, 25, 35, 45, 56, 67, 71, 71, 63, 49, 37, 25, 11,
- -5, -19, -32, -45, -54, -59, -54, -43, -36, -31, -27, -18, -3, 11, 13, 9,
- 2, -3, -6, -9, -13, -20, -25, -29, -33, -30, -23, -9, 2, 11, 19, 28,
- 40, 51, 63, 68, 71, 66, 55, 44, 31, 16, 1, -15, -30, -41, -50, -57,
- -56, -46, -37, -32, -30, -21, -7, 8, 17, 12, 5, 3, -2, -6, -11, -19,
- -23, -27, -33, -34, -28, -19, -6, 3, 13, 24, 38, 51, 62, 70, 72, 68,
- 60, 48, 38, 22, 6, -13, -27, -39, -46, -53, -52, -48, -42, -37, -36, -25,
- -9, 4, 11, 9, 7, 8, 6, 2, -6, -13, -20, -24, -28, -31, -30, -27,
- -19, -10, 4, 19, 33, 45, 57, 67, 74, 74, 70, 60, 47, 31, 10, -8,
- -25, -36, -42, -51, -56, -56, -51, -40, -35, -28, -16, -4, 7, 7, 10, 12,
- 13, 11, 3, -8, -18, -21, -25, -29, -33, -33, -30, -20, -8, 11, 27, 42,
- 54, 64, 72, 77, 76, 69, 56, 34, 14, -5, -20, -32, -43, -50, -57, -59,
- -57, -47, -39, -31, -17, -5, 6, 8, 9, 17, 19, 16, 5, -9, -13, -18,
- -21, -26, -33, -37, -35, -28, -15, 1, 18, 34, 47, 58, 68, 76, 77, 76,
- 65, 47, 25, 6, -12, -24, -37, -49, -57, -62, -64, -58, -50, -40, -24, -12,
- 3, 9, 13, 22, 26, 26, 17, 4, -9, -21, -25, -30, -36, -41, -44, -41,
- -27, -8, 12, 31, 44, 57, 68, 77, 81, 80, 72, 56, 34, 12, -6, -19,
- -30, -41, -53, -65, -68, -65, -56, -44, -30, -17, -8, 2, 10, 23, 31, 32,
- 25, 10, -4, -14, -20, -25, -31, -39, -45, -45, -35, -17, 2, 22, 37, 51,
- 63, 72, 79, 78, 74, 62, 43, 20, 2, -12, -24, -34, -49, -61, -69, -70,
- -63, -48, -35, -23, -11, 0, 9, 20, 31, 36, 32, 20, 7, -9, -18, -24,
- -30, -38, -47, -50, -44, -29, -9, 10, 27, 45, 60, 71, 78, 80, 78, 68,
- 54, 33, 13, -5, -18, -29, -44, -57, -68, -74, -66, -54, -41, -30, -18, -5,
- 8, 19, 26, 33, 32, 24, 13, -4, -15, -22, -24, -29, -40, -44, -42, -29,
- -14, 0, 15, 31, 48, 63, 69, 74, 74, 72, 64, 47, 27, 11, -4, -17,
- -33, -50, -66, -78, -78, -68, -54, -38, -25, -11, 4, 18, 31, 38, 40, 34,
- 21, 5, -12, -23, -28, -34, -43, -50, -51, -39, -22, -6, 10, 26, 46, 61,
- 70, 75, 79, 76, 67, 52, 34, 18, 4, -11, -27, -45, -63, -76, -78, -70,
- -57, -44, -29, -15, 0, 14, 26, 35, 39, 34, 23, 9, -7, -18, -23, -30,
- -40, -49, -51, -41, -24, -9, 5, 19, 39, 55, 67, 74, 77, 79, 72, 56,
- 39, 24, 12, -5, -23, -42, -60, -73, -78, -74, -62, -48, -33, -18, -6, 10,
- 25, 34, 37, 34, 26, 16, -2, -15, -23, -28, -32, -42, -46, -44, -31, -16,
- -4, 11, 28, 44, 56, 64, 69, 75, 73, 63, 50, 37, 22, 6, -10, -27,
- -47, -68, -81, -80, -68, -52, -39, -25, -13, 2, 17, 29, 36, 37, 32, 23,
- 4, -14, -24, -26, -26, -36, -44, -45, -36, -20, -7, 9, 25, 38, 49, 58,
- 66, 75, 77, 67, 52, 39, 26, 14, -3, -21, -43, -65, -81, -84, -74, -56,
- -40, -27, -15, -2, 15, 27, 37, 38, 35, 26, 8, -11, -23, -26, -27, -34,
- -42, -45, -40, -27, -13, 4, 19, 33, 45, 54, 60, 67, 72, 67, 57, 44,
- 32, 20, 5, -11, -32, -55, -72, -82, -76, -62, -46, -31, -21, -5, 6, 19,
- 29, 34, 33, 26, 12, -6, -17, -22, -23, -28, -38, -42, -38, -27, -14, 1,
- 14, 27, 40, 48, 53, 62, 68, 67, 58, 44, 32, 21, 9, -5, -22, -43,
- -63, -76, -75, -62, -46, -30, -24, -13, 0, 10, 20, 28, 31, 27, 12, -5,
- -16, -20, -19, -21, -29, -35, -35, -27, -16, -6, 9, 21, 33, 41, 47, 53,
- 61, 63, 60, 51, 39, 27, 15, 3, -13, -33, -55, -72, -75, -67, -52, -37,
- -26, -18, -7, 4, 15, 26, 27, 25, 14, 0, -10, -15, -16, -19, -24, -31,
- -32, -27, -17, -5, 5, 15, 26, 35, 43, 49, 54, 57, 57, 52, 42, 29,
- 18, 10, -3, -23, -46, -64, -71, -66, -53, -39, -27, -19, -11, 0, 5, 16,
- 22, 23, 15, 1, -10, -15, -18, -17, -17, -20, -24, -22, -14, -4, 7, 16,
- 25, 31, 36, 41, 47, 49, 49, 46, 41, 32, 21, 13, 3, -14, -33, -51,
- -60, -60, -52, -39, -28, -20, -14, -7, 1, 9, 14, 16, 10, 1, -10, -15,
- -14, -15, -15, -15, -17, -14, -11, -4, 5, 13, 22, 29, 33, 35, 39, 43,
- 45, 45, 42, 35, 26, 17, 7, -10, -25, -38, -48, -53, -53, -46, -33, -23,
- -16, -13, -8, -3, 4, 9, 7, 1, -6, -10, -13, -12, -12, -8, -7, -6,
- -2, 3, 6, 10, 14, 23, 28, 29, 30, 29, 34, 39, 40, 36, 30, 21,
- 13, 1, -15, -27, -36, -44, -48, -45, -36, -26, -17, -13, -10, -6, -2, 2,
- 3, -3, -6, -10, -14, -13, -12, -7, -3, 1, 2, 5, 6, 10, 15, 19,
- 25, 25, 26, 26, 29, 34, 35, 32, 29, 20, 13, 4, -12, -20, -27, -33,
- -38, -41, -36, -27, -19, -13, -10, -8, -8, -7, -5, -5, -7, -9, -13, -18,
- -15, -12, -5, 3, 7, 10, 10, 11, 13, 20, 27, 27, 23, 20, 20, 24,
- 27, 25, 26, 23, 17, 7, -6, -13, -16, -20, -26, -32, -33, -28, -20, -13,
- -12, -12, -16, -15, -15, -12, -10, -13, -13, -16, -12, -7, 0, 9, 14, 18,
- 18, 14, 11, 14, 18, 21, 17, 10, 11, 15, 20, 21, 20, 20, 17, 9,
- 2, -5, -10, -14, -21, -25, -29, -27, -23, -17, -13, -13, -16, -18, -20, -20,
- -12, -8, -9, -15, -16, -10, -2, 9, 14, 18, 18, 18, 14, 14, 17, 20,
- 18, 12, 8, 11, 13, 16, 18, 19, 16, 9, 3, 1, 1, -6, -13, -20,
- -23, -21, -19, -15, -15, -14, -17, -21, -22, -22, -17, -11, -11, -13, -18, -14,
- -4, 12, 21, 22, 23, 21, 20, 17, 16, 16, 12, 7, 1, 5, 7, 8,
- 12, 15, 15, 10, 3, 0, 3, 1, -5, -12, -19, -19, -16, -11, -9, -11,
- -14, -23, -28, -29, -24, -17, -13, -15, -19, -18, -10, 7, 22, 29, 30, 24,
- 22, 18, 17, 17, 11, 4, -2, -3, 2, 4, 8, 13, 16, 13, 7, 4,
- 9, 8, 2, -7, -16, -15, -14, -12, -10, -12, -12, -19, -25, -29, -25, -18,
- -15, -18, -21, -19, -12, 1, 16, 28, 34, 32, 29, 23, 18, 15, 11, 4,
- -3, -10, -8, -5, 0, 7, 12, 14, 10, 6, 10, 15, 13, 3, -7, -11,
- -13, -13, -13, -12, -14, -20, -28, -31, -29, -20, -13, -14, -18, -18, -15, -3,
- 12, 24, 33, 32, 29, 25, 22, 16, 11, 3, -3, -6, -7, -8, -3, 2,
- 8, 11, 11, 9, 10, 13, 13, 8, 0, -6, -9, -9, -9, -10, -11, -18,
- -26, -30, -29, -22, -17, -18, -20, -21, -17, -7, 6, 21, 34, 38, 34, 29,
- 21, 17, 13, 8, 1, -8, -13, -15, -10, -3, 5, 10, 11, 10, 11, 15,
- 16, 11, 3, -4, -7, -9, -8, -10, -13, -19, -26, -26, -23, -17, -15, -16,
- -17, -17, -15, -9, -2, 10, 26, 31, 31, 24, 21, 18, 13, 6, 1, -6,
- -8, -9, -8, -4, 0, 6, 10, 12, 15, 14, 13, 9, 5, -2, -7, -8,
- -9, -8, -10, -18, -25, -25, -23, -18, -16, -19, -22, -18, -16, -10, 0, 10,
- 24, 33, 35, 29, 22, 17, 13, 7, -3, -8, -12, -14, -12, -7, -3, 4,
- 10, 14, 16, 17, 16, 16, 11, 3, -7, -11, -10, -7, -10, -19, -26, -27,
- -23, -17, -14, -14, -17, -18, -16, -12, -3, 7, 20, 26, 28, 24, 20, 16,
- 15, 10, 2, -8, -13, -11, -7, -2, -2, 4, 6, 9, 14, 17, 19, 15,
- 8, -4, -12, -15, -11, -5, -8, -18, -25, -24, -17, -9, -6, -7, -11, -15,
- -15, -13, -6, 4, 11, 15, 16, 15, 16, 13, 9, 5, 1, -3, -7, -5,
- -2, 3, 5, 6, 8, 10, 14, 17, 18, 14, 3, -8, -15, -13, -9, -6,
- -9, -19, -22, -19, -13, -6, -4, -5, -8, -13, -15, -10, -5, 5, 8, 8,
- 8, 11, 14, 14, 8, 2, 1, 1, 2, -2, 1, 5, 6, 7, 7, 6,
- 11, 13, 16, 13, 3, -6, -13, -14, -8, -5, -6, -15, -20, -15, -10, -5,
- -2, -6, -6, -8, -12, -10, -8, -3, 5, 3, 3, 5, 7, 10, 6, 2,
- -3, -2, 2, 8, 9, 12, 11, 8, 9, 8, 11, 13, 11, 10, 0, -12,
- -20, -21, -13, -10, -11, -14, -16, -10, -3, 4, 8, 5, 2, -2, -4, -4,
- -7, -4, -4, -5, -7, -8, -5, 0, 2, 2, 0, 1, 6, 11, 15, 19,
- 19, 18, 14, 10, 12, 12, 11, 6, -6, -16, -23, -23, -17, -13, -12, -12,
- -13, -8, -2, 8, 13, 13, 8, 4, 1, -3, -3, -3, -4, -11, -16, -16,
- -13, -9, -5, -4, -2, 1, 6, 13, 17, 21, 24, 23, 18, 14, 10, 11,
- 12, 8, -3, -16, -26, -27, -20, -17, -21, -21, -17, -7, 2, 10, 16, 19,
- 18, 13, 10, 5, 2, -2, -5, -14, -22, -26, -21, -15, -11, -11, -6, -2,
- 6, 16, 22, 27, 28, 28, 23, 17, 13, 10, 12, 7, -4, -18, -29, -32,
- -24, -20, -21, -22, -18, -5, 5, 14, 19, 21, 20, 17, 13, 8, 5, -2,
- -9, -18, -26, -26, -21, -14, -12, -11, -8, -2, 10, 16, 21, 24, 25, 27,
- 24, 16, 11, 6, 7, 6, -4, -16, -25, -29, -25, -19, -19, -22, -18, -7,
- 6, 15, 17, 18, 19, 18, 15, 10, 8, 3, -5, -15, -24, -30, -27, -19,
- -15, -15, -13, -8, 5, 14, 20, 25, 28, 31, 30, 26, 18, 11, 9, 7,
- -2, -14, -27, -33, -30, -25, -25, -27, -26, -15, 2, 17, 22, 23, 23, 22,
- 22, 18, 14, 7, -4, -14, -24, -31, -30, -25, -19, -16, -16, -11, -3, 8,
- 17, 24, 29, 31, 31, 29, 22, 17, 12, 8, 2, -12, -26, -36, -35, -30,
- -26, -26, -29, -20, -5, 13, 24, 26, 26, 26, 28, 23, 19, 11, 1, -9,
- -24, -34, -33, -30, -24, -21, -21, -17, -11, 1, 9, 19, 27, 33, 34, 30,
- 28, 24, 21, 16, 7, -6, -23, -35, -40, -36, -33, -31, -32, -27, -13, 3,
- 17, 25, 29, 34, 34, 30, 23, 17, 11, 0, -14, -27, -32, -33, -30, -26,
- -21, -18, -15, -9, 1, 11, 22, 29, 32, 33, 30, 28, 23, 21, 13, 3,
- -15, -30, -37, -38, -35, -35, -33, -28, -18, -5, 10, 22, 30, 37, 36, 32,
- 26, 21, 14, 7, -6, -19, -28, -34, -32, -27, -21, -20, -21, -20, -11, 5,
- 17, 25, 29, 30, 33, 35, 31, 27, 19, 8, -7, -25, -37, -42, -41, -39,
- -35, -30, -22, -11, 4, 21, 32, 38, 39, 36, 29, 22, 15, 9, -4, -15,
- -24, -32, -35, -31, -24, -18, -18, -19, -14, -3, 11, 21, 27, 31, 32, 34,
- 34, 31, 27, 18, 1, -19, -33, -39, -38, -40, -39, -35, -28, -17, -3, 14,
- 28, 37, 41, 40, 34, 30, 24, 18, 7, -6, -20, -30, -36, -34, -30, -26,
- -26, -27, -26, -16, 0, 16, 26, 30, 33, 36, 42, 43, 38, 27, 10, -10,
- -27, -39, -43, -43, -43, -40, -34, -26, -14, 2, 21, 36, 42, 40, 36, 33,
- 30, 24, 16, 5, -11, -25, -34, -35, -32, -29, -30, -31, -31, -27, -15, 5,
- 21, 27, 30, 34, 42, 51, 48, 40, 20, -3, -21, -32, -38, -40, -43, -42,
- -38, -30, -18, -3, 15, 29, 40, 41, 39, 34, 31, 28, 20, 10, -4, -18,
- -29, -33, -34, -34, -35, -37, -38, -34, -21, -6, 12, 22, 26, 33, 44, 55,
- 56, 46, 26, 5, -11, -25, -36, -42, -47, -47, -43, -37, -24, -11, 9, 25,
- 36, 38, 38, 40, 39, 39, 28, 17, 3, -10, -23, -30, -37, -38, -42, -44,
- -43, -40, -30, -16, 3, 17, 26, 34, 44, 57, 61, 52, 34, 9, -7, -21,
- -30, -38, -46, -49, -48, -39, -27, -13, 5, 22, 32, 35, 35, 37, 41, 43,
- 33, 19, 4, -8, -16, -25, -32, -39, -42, -44, -42, -41, -33, -20, -4, 11,
- 21, 28, 38, 49, 58, 54, 36, 16, -6, -16, -21, -28, -36, -46, -49, -42,
- -29, -17, 0, 13, 26, 30, 30, 35, 41, 47, 41, 25, 9, -4, -12, -17,
- -28, -38, -46, -52, -51, -49, -39, -23, -9, 4, 12, 23, 39, 54, 66, 62,
- 43, 23, 2, -10, -16, -26, -36, -45, -51, -50, -37, -20, 0, 16, 27, 28,
- 29, 38, 47, 50, 44, 28, 13, -2, -10, -16, -26, -35, -45, -55, -57, -56,
- -44, -27, -13, -4, 5, 17, 34, 53, 64, 64, 46, 29, 13, 1, -8, -17,
- -28, -39, -48, -51, -42, -26, -8, 9, 18, 20, 24, 34, 46, 53, 47, 33,
- 15, 4, -4, -13, -22, -35, -47, -56, -59, -56, -48, -32, -18, -8, 3, 14,
- 33, 52, 65, 64, 49, 31, 17, 5, -3, -13, -25, -36, -45, -49, -44, -31,
- -14, 7, 16, 21, 21, 31, 48, 57, 53, 38, 20, 8, -3, -9, -21, -35,
- -47, -57, -62, -62, -54, -38, -22, -12, -5, 7, 26, 49, 66, 69, 56, 37,
- 24, 15, 6, -4, -17, -30, -43, -53, -47, -34, -18, -2, 9, 14, 17, 29,
- 46, 58, 56, 43, 25, 13, 2, -5, -15, -30, -45, -59, -66, -65, -57, -43,
- -28, -16, -10, 2, 21, 44, 66, 71, 62, 43, 28, 19, 13, 3, -12, -25,
- -42, -51, -50, -38, -18, -3, 5, 12, 17, 30, 48, 59, 58, 45, 26, 11,
- 0, -6, -15, -29, -45, -63, -71, -68, -58, -41, -28, -19, -12, -4, 16, 42,
- 62, 70, 61, 43, 29, 21, 16, 8, -6, -20, -35, -45, -45, -37, -21, -6,
- 3, 8, 14, 24, 42, 54, 58, 47, 29, 16, 3, -3, -12, -27, -42, -62,
- -73, -74, -66, -52, -34, -23, -14, -5, 12, 38, 60, 72, 68, 49, 34, 23,
- 17, 10, -3, -18, -31, -42, -42, -36, -20, -4, 5, 9, 11, 22, 37, 51,
- 55, 46, 29, 13, 2, -9, -14, -25, -38, -53, -67, -72, -67, -53, -35, -23,
- -17, -10, 6, 32, 55, 69, 67, 53, 36, 26, 19, 12, 2, -13, -26, -37,
- -40, -36, -24, -7, 3, 9, 13, 20, 36, 49, 52, 47, 32, 17, 3, -12,
- -19, -29, -38, -52, -66, -75, -72, -56, -36, -20, -15, -10, 2, 25, 48, 63,
- 63, 52, 39, 28, 20, 14, 5, -6, -19, -30, -38, -35, -25, -8, 4, 8,
- 11, 17, 33, 47, 54, 47, 34, 18, 4, -9, -19, -28, -40, -53, -65, -75,
- -74, -60, -41, -22, -15, -12, -2, 18, 43, 59, 63, 55, 41, 31, 27, 20,
- 13, 3, -11, -24, -35, -34, -26, -11, 2, 8, 9, 11, 22, 37, 47, 49,
- 39, 22, 6, -7, -19, -26, -36, -48, -60, -74, -77, -66, -47, -26, -13, -8,
- 1, 15, 36, 53, 63, 56, 45, 30, 22, 16, 10, 5, -7, -19, -32, -34,
- -25, -7, 8, 16, 17, 17, 23, 37, 48, 51, 40, 22, 4, -14, -24, -33,
- -39, -49, -61, -72, -77, -66, -47, -27, -13, -5, 1, 13, 30, 47, 59, 57,
- 47, 31, 23, 17, 15, 6, -5, -18, -26, -30, -24, -10, 8, 19, 21, 20,
- 22, 30, 40, 48, 41, 25, 3, -17, -29, -32, -37, -46, -59, -70, -73, -65,
- -46, -27, -14, -4, 3, 15, 29, 41, 52, 54, 45, 31, 19, 15, 15, 9,
- 1, -14, -26, -27, -21, -8, 10, 17, 23, 23, 23, 32, 39, 45, 44, 29,
- 7, -16, -32, -40, -42, -49, -61, -72, -76, -69, -50, -28, -12, -2, 5, 17,
- 31, 43, 48, 49, 44, 34, 24, 15, 13, 9, 5, -8, -24, -27, -21, -7,
- 10, 20, 25, 29, 29, 32, 36, 41, 41, 34, 14, -12, -35, -46, -49, -52,
- -61, -74, -78, -73, -56, -31, -14, 2, 10, 19, 31, 44, 54, 53, 47, 34,
- 24, 16, 9, 4, -2, -12, -25, -28, -22, -7, 9, 23, 32, 36, 36, 36,
- 37, 42, 42, 33, 15, -14, -36, -50, -57, -56, -62, -74, -81, -77, -59, -36,
- -15, 2, 11, 20, 31, 44, 56, 56, 51, 39, 26, 15, 7, 1, -3, -13,
- -26, -33, -31, -14, 9, 25, 36, 41, 40, 41, 40, 44, 44, 35, 17, -13,
- -39, -54, -61, -64, -69, -76, -81, -78, -63, -39, -15, 4, 14, 24, 35, 45,
- 54, 56, 53, 41, 25, 14, 7, 3, -4, -14, -26, -34, -31, -15, 9, 25,
- 36, 41, 43, 44, 43, 46, 45, 35, 16, -9, -31, -49, -63, -69, -75, -78,
- -84, -79, -66, -45, -22, 0, 13, 23, 35, 48, 56, 58, 53, 43, 30, 19,
- 10, 4, -7, -18, -26, -33, -30, -17, 4, 24, 37, 44, 50, 50, 49, 46,
- 43, 35, 16, -7, -30, -52, -65, -75, -78, -83, -85, -82, -70, -50, -26, -4,
- 14, 26, 39, 53, 63, 64, 59, 49, 35, 18, 6, -2, -13, -25, -35, -40,
- -36, -22, 3, 26, 38, 47, 54, 60, 61, 57, 50, 39, 20, -5, -26, -49,
- -66, -80, -87, -91, -93, -88, -74, -54, -34, -12, 8, 24, 40, 55, 68, 70,
- 66, 55, 41, 26, 14, 6, -9, -25, -37, -43, -39, -28, -9, 15, 32, 41,
- 48, 59, 65, 65, 58, 45, 25, 5, -17, -38, -61, -77, -91, -97, -100, -94,
- -79, -64, -44, -23, -2, 24, 42, 57, 72, 77, 74, 63, 48, 33, 21, 10,
- -7, -27, -43, -45, -41, -29, -14, 4, 26, 40, 49, 58, 66, 69, 64, 48,
- 29, 7, -13, -31, -53, -73, -89, -100, -102, -95, -83, -67, -51, -29, -7, 17,
- 37, 55, 72, 81, 77, 67, 55, 40, 25, 12, -4, -22, -40, -45, -42, -31,
- -19, -4, 15, 34, 48, 55, 63, 67, 66, 57, 41, 20, -4, -25, -46, -69,
- -88, -104, -110, -106, -95, -79, -63, -39, -13, 15, 39, 60, 75, 88, 91, 81,
- 66, 44, 27, 13, -3, -22, -41, -50, -48, -38, -26, -13, 6, 29, 46, 55,
- 62, 66, 69, 63, 48, 26, 5, -14, -33, -57, -84, -105, -115, -113, -102, -88,
- -73, -53, -26, 1, 31, 57, 78, 91, 95, 88, 75, 60, 41, 22, 1, -19,
- -38, -51, -53, -48, -36, -22, -6, 19, 39, 53, 62, 65, 69, 67, 55, 36,
- 14, -6, -28, -54, -79, -100, -111, -116, -110, -98, -83, -61, -35, -6, 26, 53,
- 75, 89, 96, 96, 87, 71, 50, 29, 10, -9, -30, -44, -53, -50, -45, -32,
- -19, 2, 23, 43, 55, 62, 66, 66, 62, 49, 30, 11, -12, -39, -70, -95,
- -112, -118, -118, -109, -94, -74, -48, -18, 17, 47, 70, 88, 98, 99, 95, 80,
- 61, 37, 14, -9, -26, -43, -51, -52, -48, -40, -25, -6, 17, 37, 52, 57,
- 63, 64, 62, 55, 36, 17, -8, -34, -62, -86, -106, -117, -118, -110, -99, -83,
- -57, -27, 10, 42, 67, 85, 96, 101, 101, 91, 69, 46, 21, 1, -21, -38,
- -49, -54, -49, -44, -35, -18, 2, 24, 44, 55, 64, 67, 63, 59, 46, 29,
- 7, -21, -51, -79, -104, -117, -122, -117, -108, -94, -70, -40, 0, 34, 63, 85,
- 96, 104, 105, 99, 82, 59, 31, 4, -20, -37, -46, -51, -51, -50, -44, -28,
- -8, 17, 38, 53, 60, 65, 67, 64, 54, 40, 18, -10, -40, -71, -98, -115,
- -121, -118, -113, -103, -82, -52, -14, 22, 53, 77, 94, 106, 109, 104, 93, 76,
- 50, 21, -11, -33, -43, -48, -53, -56, -56, -46, -27, 2, 29, 48, 58, 62,
- 63, 62, 58, 49, 33, 5, -27, -57, -87, -108, -119, -118, -114, -106, -91, -68,
- -31, 8, 42, 69, 88, 102, 110, 110, 100, 83, 60, 33, 3, -23, -39, -46,
- -52, -57, -57, -51, -35, -14, 15, 38, 54, 63, 65, 66, 58, 51, 40, 17,
- -11, -44, -76, -101, -114, -116, -111, -106, -96, -77, -47, -11, 28, 58, 81, 97,
- 109, 112, 105, 95, 77, 53, 23, -9, -30, -45, -52, -58, -64, -61, -52, -35,
- -9, 20, 44, 62, 67, 67, 65, 62, 54, 35, 7, -24, -60, -91, -110, -119,
- -116, -112, -105, -90, -65, -31, 8, 43, 73, 94, 109, 117, 113, 105, 91, 68,
- 39, 4, -24, -43, -56, -64, -67, -67, -61, -47, -21, 9, 35, 55, 63, 66,
- 66, 61, 56, 46, 23, -10, -46, -81, -100, -111, -115, -112, -107, -94, -75, -48,
- -12, 28, 59, 84, 103, 116, 120, 114, 103, 81, 56, 22, -10, -35, -53, -64,
- -71, -73, -71, -59, -39, -10, 19, 43, 60, 66, 68, 67, 64, 53, 33, 7,
- -27, -64, -91, -108, -115, -113, -108, -97, -82, -59, -27, 11, 46, 75, 98, 112,
- 119, 117, 109, 89, 64, 34, 4, -24, -50, -62, -69, -69, -70, -65, -49, -23,
- 8, 32, 52, 61, 64, 65, 64, 55, 39, 15, -16, -46, -76, -97, -109, -110,
- -107, -102, -91, -71, -42, -4, 34, 66, 90, 106, 116, 121, 118, 101, 78, 47,
- 15, -15, -44, -60, -70, -73, -75, -74, -63, -39, -7, 23, 45, 60, 66, 69,
- 69, 62, 49, 29, 1, -32, -65, -94, -108, -112, -109, -102, -97, -83, -58, -22,
- 18, 54, 84, 103, 116, 121, 120, 112, 91, 63, 29, -6, -34, -54, -66, -75,
- -79, -81, -72, -50, -22, 9, 33, 50, 59, 67, 70, 70, 60, 43, 13, -20,
- -51, -78, -97, -107, -111, -109, -105, -94, -72, -37, 5, 42, 72, 96, 114, 124,
- 127, 118, 100, 75, 42, 10, -22, -47, -62, -72, -79, -84, -82, -64, -35, -2,
- 23, 39, 50, 61, 69, 71, 66, 51, 27, -6, -36, -62, -81, -96, -104, -105,
- -106, -101, -83, -52, -11, 27, 57, 82, 103, 120, 127, 122, 107, 82, 53, 19,
- -12, -39, -55, -65, -73, -81, -81, -67, -40, -8, 16, 30, 41, 52, 62, 68,
- 66, 56, 34, 3, -28, -53, -71, -86, -96, -102, -106, -103, -88, -62, -25, 15,
- 47, 72, 90, 109, 120, 123, 115, 93, 63, 31, 1, -24, -40, -52, -64, -76,
- -82, -73, -50, -22, 1, 18, 27, 39, 51, 63, 67, 61, 44, 18, -13, -38,
- -53, -69, -83, -96, -105, -103, -93, -69, -36, -3, 30, 56, 77, 95, 111, 116,
- 113, 97, 72, 42, 13, -12, -25, -38, -54, -70, -79, -74, -57, -32, -11, 4,
- 15, 26, 40, 55, 65, 62, 51, 28, 1, -24, -40, -56, -73, -89, -101, -102,
- -95, -79, -50, -17, 16, 47, 68, 88, 104, 114, 115, 102, 80, 53, 24, 0,
- -18, -31, -45, -60, -73, -74, -63, -42, -21, -6, 6, 16, 28, 45, 56, 59,
- 51, 35, 14, -9, -26, -41, -57, -73, -87, -97, -95, -85, -62, -32, -2, 26,
- 50, 71, 91, 105, 111, 105, 89, 64, 40, 16, -4, -20, -35, -49, -64, -70,
- -68, -53, -35, -18, -6, 5, 14, 29, 45, 55, 54, 39, 21, 4, -13, -25,
- -42, -63, -77, -89, -90, -80, -66, -44, -19, 10, 35, 57, 76, 93, 104, 104,
- 91, 68, 48, 29, 13, -6, -24, -42, -56, -63, -61, -54, -42, -27, -17, -6,
- 5, 18, 33, 44, 47, 39, 25, 10, 0, -14, -29, -50, -67, -79, -85, -81,
- -70, -53, -32, -5, 24, 47, 67, 84, 98, 103, 95, 77, 56, 37, 22, 6,
- -14, -34, -48, -56, -57, -52, -48, -37, -28, -17, -6, 8, 23, 34, 41, 38,
- 28, 15, 4, -4, -16, -38, -59, -73, -78, -75, -66, -54, -37, -19, 7, 32,
- 53, 72, 87, 95, 92, 78, 58, 44, 32, 20, 2, -21, -38, -47, -48, -47,
- -46, -42, -36, -26, -14, -5, 9, 20, 32, 35, 30, 19, 12, 8, -5, -25,
- -48, -63, -71, -70, -63, -58, -44, -26, -6, 20, 40, 59, 79, 92, 93, 83,
- 60, 47, 37, 29, 13, -10, -28, -40, -44, -44, -48, -47, -41, -33, -22, -13,
- 0, 14, 29, 36, 34, 24, 18, 15, 4, -13, -39, -60, -69, -72, -68, -62,
- -51, -34, -13, 9, 31, 52, 73, 88, 95, 87, 70, 55, 45, 35, 20, -2,
- -23, -36, -42, -47, -48, -51, -50, -40, -30, -17, -8, 7, 23, 36, 37, 30,
- 22, 19, 13, -3, -24, -49, -65, -71, -71, -64, -54, -40, -20, -3, 21, 44,
- 65, 85, 92, 87, 72, 57, 48, 39, 29, 11, -12, -27, -36, -41, -42, -47,
- -49, -45, -37, -28, -17, -4, 13, 28, 33, 29, 26, 23, 17, 6, -11, -33,
- -53, -64, -66, -62, -55, -44, -29, -12, 10, 31, 51, 71, 84, 85, 77, 61,
- 50, 41, 36, 22, 2, -17, -33, -38, -42, -45, -48, -46, -41, -34, -23, -9,
- 7, 24, 35, 32, 28, 23, 17, 10, -4, -26, -49, -64, -68, -64, -58, -46,
- -32, -13, 8, 28, 45, 65, 78, 82, 76, 62, 52, 45, 37, 23, 6, -10,
- -26, -35, -41, -45, -46, -48, -48, -39, -27, -11, 3, 14, 23, 27, 28, 25,
- 23, 15, 2, -17, -34, -52, -60, -61, -56, -44, -32, -17, -3, 16, 34, 54,
- 66, 73, 68, 58, 47, 42, 37, 29, 17, 3, -14, -25, -31, -36, -39, -44,
- -48, -44, -33, -20, -9, 2, 13, 22, 26, 24, 20, 14, 5, -7, -22, -39,
- -50, -55, -51, -43, -32, -20, -7, 10, 28, 44, 57, 65, 67, 64, 54, 44,
- 36, 28, 18, 4, -9, -23, -32, -39, -42, -46, -44, -38, -29, -19, -12, -4,
- 10, 22, 27, 22, 14, 8, 1, -6, -17, -30, -43, -49, -47, -38, -26, -18,
- -10, 3, 17, 34, 45, 54, 59, 57, 53, 45, 37, 30, 22, 11, -3, -14,
- -24, -34, -40, -45, -43, -39, -29, -21, -14, -6, 3, 16, 20, 17, 10, 3,
- 0, -6, -15, -25, -33, -38, -37, -31, -21, -12, -6, 5, 15, 27, 39, 46,
- 50, 51, 47, 44, 36, 29, 20, 10, 1, -10, -18, -27, -36, -40, -42, -37,
- -29, -21, -14, -7, 1, 10, 16, 10, 3, -2, -3, -6, -12, -22, -28, -30,
- -28, -23, -16, -11, -7, 0, 7, 19, 31, 42, 47, 47, 46, 46, 40, 33,
- 21, 10, 2, -6, -12, -24, -33, -37, -38, -36, -31, -21, -14, -7, -2, 2,
- 7, 8, 4, -2, -7, -12, -14, -19, -23, -24, -20, -16, -11, -6, -2, 3,
- 9, 16, 24, 33, 37, 40, 44, 44, 40, 33, 22, 13, 5, -3, -8, -21,
- -30, -35, -34, -32, -30, -23, -13, -6, -3, -3, -2, -2, -4, -7, -9, -12,
- -13, -13, -14, -14, -11, -12, -4, -2, 2, 0, 3, 10, 18, 27, 32, 35,
- 38, 40, 37, 32, 23, 13, 8, 2, -4, -11, -22, -27, -31, -30, -29, -24,
- -14, -7, -8, -7, -10, -10, -10, -10, -11, -12, -13, -12, -11, -11, -7, -2,
- 4, 5, 3, -2, 0, 8, 15, 21, 26, 30, 32, 37, 37, 32, 26, 16,
- 10, 4, -4, -9, -16, -21, -26, -29, -28, -23, -15, -11, -9, -11, -13, -14,
- -14, -13, -13, -12, -13, -12, -8, -3, 3, 6, 8, 10, 7, 1, -3, 2,
- 8, 17, 22, 22, 27, 32, 37, 35, 29, 18, 11, 2, -4, -8, -14, -17,
- -21, -23, -25, -22, -17, -11, -9, -11, -16, -16, -16, -16, -14, -15, -14, -11,
- -5, 0, 4, 5, 6, 7, 6, 4, 0, 3, 8, 16, 21, 20, 24, 28,
- 34, 35, 29, 17, 8, 3, 1, -3, -9, -15, -20, -21, -23, -22, -21, -17,
- -13, -14, -18, -23, -22, -17, -13, -10, -9, -8, 0, 6, 9, 10, 8, 6,
- 6, 4, 0, -2, 1, 10, 17, 20, 22, 25, 29, 31, 29, 20, 10, 2,
- -2, 0, -5, -11, -18, -20, -19, -19, -19, -18, -16, -14, -18, -26, -26, -22,
- -16, -13, -9, -6, 1, 7, 10, 10, 7, 7, 7, 5, 0, -4, -2, 7,
- 14, 19, 22, 26, 30, 32, 30, 22, 13, 6, 1, -2, -7, -13, -16, -18,
- -19, -19, -21, -21, -19, -17, -16, -23, -25, -23, -17, -10, -9, -4, 2, 8,
- 10, 12, 9, 7, 5, 4, 2, -3, -2, 3, 9, 18, 23, 28, 29, 28,
- 27, 26, 19, 12, 6, 0, -7, -11, -15, -17, -20, -21, -20, -22, -23, -25,
- -24, -26, -27, -25, -20, -13, -5, 3, 9, 11, 15, 17, 15, 10, 4, 0,
- -4, -5, -4, 2, 5, 13, 19, 25, 29, 28, 26, 25, 20, 16, 11, 2,
- -5, -10, -10, -10, -14, -17, -21, -24, -26, -29, -27, -28, -28, -26, -23, -17,
- -8, 1, 12, 15, 16, 14, 13, 10, 6, 0, -5, -6, -5, 1, 6, 12,
- 20, 27, 30, 28, 24, 23, 21, 17, 11, 4, -6, -9, -10, -10, -11, -16,
- -18, -21, -24, -26, -29, -28, -27, -25, -23, -18, -11, -2, 11, 15, 15, 12,
- 11, 9, 6, 1, -6, -6, -2, 3, 7, 11, 19, 26, 28, 26, 22, 21,
- 23, 24, 17, 10, 4, 0, -2, -5, -10, -15, -20, -25, -32, -36, -36, -35,
- -32, -30, -26, -19, -10, 2, 14, 21, 21, 17, 13, 10, 7, 1, -5, -5,
- -6, -4, 0, 6, 12, 19, 22, 24, 20, 21, 24, 29, 28, 20, 13, 8,
- 3, 2, -4, -9, -16, -27, -34, -41, -44, -41, -38, -35, -31, -27, -18, -3,
- 13, 26, 29, 23, 18, 14, 11, 8, 4, -2, -8, -11, -9, -6, 4, 9,
- 16, 17, 16, 16, 23, 33, 37, 33, 26, 19, 12, 8, 1, -7, -15, -30,
- -41, -50, -53, -50, -43, -38, -34, -28, -17, -3, 13, 26, 30, 26, 19, 14,
- 12, 9, 4, -2, -10, -14, -13, -7, 4, 9, 12, 13, 13, 17, 25, 32,
- 40, 39, 32, 24, 15, 11, 8, 1, -10, -27, -43, -51, -55, -52, -49, -45,
- -40, -32, -21, -8, 9, 23, 31, 30, 24, 19, 17, 16, 11, 4, -7, -15,
- -18, -14, -6, 2, 5, 7, 9, 14, 24, 35, 45, 48, 45, 34, 25, 16,
- 8, 2, -11, -27, -46, -59, -64, -61, -53, -46, -40, -35, -24, -9, 8, 23,
- 30, 31, 27, 24, 21, 17, 12, 4, -6, -15, -19, -17, -12, -3, 3, 4,
- 6, 12, 25, 37, 45, 47, 47, 43, 35, 23, 12, 2, -10, -24, -42, -60,
- -71, -71, -63, -55, -45, -36, -22, -7, 9, 22, 30, 35, 34, 31, 24, 19,
- 13, 6, -3, -13, -20, -21, -16, -9, -3, -2, 4, 11, 26, 38, 45, 50,
- 49, 48, 42, 31, 16, 4, -9, -21, -38, -59, -72, -77, -70, -61, -53, -41,
- -26, -9, 7, 17, 26, 34, 41, 41, 35, 25, 17, 9, 0, -10, -21, -24,
- -22, -15, -9, -7, -2, 10, 25, 39, 44, 47, 49, 52, 50, 39, 22, 6,
- -8, -20, -34, -54, -70, -78, -77, -68, -61, -49, -33, -15, 3, 16, 25, 32,
- 43, 49, 47, 37, 25, 16, 3, -10, -22, -29, -27, -22, -15, -12, -7, 7,
- 25, 42, 47, 50, 53, 57, 57, 46, 31, 11, -5, -22, -39, -56, -72, -81,
- -85, -81, -71, -56, -36, -16, 4, 19, 29, 37, 48, 55, 56, 48, 34, 20,
- 7, -10, -25, -32, -34, -28, -21, -17, -14, 0, 20, 40, 50, 51, 53, 58,
- 61, 53, 39, 18, -2, -18, -36, -53, -70, -80, -85, -86, -79, -67, -46, -23,
- -2, 17, 27, 35, 44, 55, 62, 57, 44, 26, 9, -10, -23, -29, -32, -28,
- -24, -20, -15, -4, 15, 35, 47, 50, 49, 53, 57, 53, 43, 24, 5, -14,
- -32, -50, -64, -5, 0, -2, -3, -3, -3, -3, -2, -2, 1, 2, 3, 5,
- 8, 11, 11, 10, 8, 5, 1, -6, -13, -19, -21, -18, -15, -13, -10, -7,
- -2, 4, 8, 12, 17, 28, 33, 29, 23, 14, 7, -5, -19, -33, -42, -36,
- -28, -24, -17, -13, -8, 1, 7, 15, 23, 33, 42, 42, 35, 26, 15, 0,
- -16, -30, -44, -45, -34, -27, -20, -16, -13, -4, 4, 12, 21, 29, 40, 45,
- 40, 30, 20, 6, -13, -25, -38, -45, -38, -31, -24, -18, -15, -10, -4, 5,
- 17, 27, 35, 44, 43, 37, 27, 15, -4, -19, -31, -44, -44, -35, -30, -22,
- -19, -16, -8, 2, 15, 25, 32, 42, 47, 42, 32, 18, 0, -16, -26, -39,
- -45, -38, -31, -25, -19, -18, -14, -5, 11, 23, 29, 39, 46, 45, 38, 25,
- 7, -8, -18, -31, -44, -43, -35, -30, -25, -25, -20, -9, 7, 21, 27, 36,
- 48, 51, 44, 32, 14, -3, -16, -28, -42, -46, -41, -33, -27, -24, -23, -15,
- 1, 16, 27, 33, 42, 47, 46, 38, 21, 5, -9, -21, -34, -44, -45, -39,
- -31, -28, -26, -20, -8, 9, 25, 34, 41, 49, 51, 47, 31, 11, -6, -18,
- -30, -42, -48, -45, -36, -28, -26, -23, -12, 6, 23, 33, 38, 43, 51, 50,
- 36, 15, 0, -12, -22, -35, -50, -50, -40, -31, -29, -27, -18, 1, 20, 32,
- 36, 43, 52, 56, 45, 23, 2, -10, -20, -33, -48, -56, -49, -36, -30, -26,
- -18, -5, 17, 33, 39, 40, 46, 52, 49, 32, 9, -8, -18, -26, -40, -54,
- -53, -39, -30, -28, -23, -12, 10, 31, 39, 38, 42, 54, 54, 41, 17, -5,
- -15, -22, -35, -53, -59, -47, -36, -30, -24, -14, 6, 27, 40, 42, 43, 51,
- 56, 46, 26, 3, -13, -22, -33, -49, -61, -55, -41, -32, -26, -18, 0, 22,
- 38, 45, 43, 48, 55, 50, 33, 11, -10, -21, -29, -43, -59, -60, -46, -35,
- -28, -18, -6, 15, 35, 45, 46, 45, 52, 53, 41, 20, -6, -19, -26, -38,
- -54, -62, -53, -39, -29, -19, -11, 6, 29, 44, 48, 45, 47, 52, 49, 32,
- 5, -18, -26, -32, -45, -61, -61, -48, -35, -23, -14, -2, 22, 42, 52, 50,
- 46, 50, 50, 38, 12, -15, -26, -31, -43, -59, -65, -53, -37, -25, -16, -6,
- 16, 40, 53, 53, 47, 49, 51, 42, 22, -10, -27, -31, -38, -54, -67, -63,
- -46, -27, -18, -7, 10, 31, 52, 59, 53, 48, 50, 46, 32, 3, -24, -34,
- -39, -50, -66, -68, -54, -35, -20, -8, 6, 23, 47, 62, 59, 52, 50, 48,
- 37, 13, -18, -35, -40, -46, -62, -72, -63, -43, -25, -10, 6, 20, 41, 59,
- 63, 55, 49, 46, 39, 21, -9, -31, -39, -42, -52, -68, -68, -52, -32, -17,
- -4, 9, 31, 54, 66, 63, 54, 51, 44, 32, 6, -26, -40, -44, -51, -65,
- -72, -61, -41, -23, -5, 9, 25, 48, 64, 66, 59, 54, 46, 33, 12, -17,
- -36, -45, -51, -62, -73, -67, -48, -31, -11, 8, 21, 44, 64, 70, 64, 57,
- 49, 36, 20, -8, -34, -47, -52, -58, -68, -73, -59, -40, -19, 4, 17, 36,
- 58, 72, 73, 65, 56, 41, 26, 4, -24, -44, -55, -63, -69, -73, -66, -51,
- -28, -2, 18, 32, 51, 67, 75, 72, 62, 46, 29, 11, -13, -37, -54, -64,
- -70, -71, -70, -58, -38, -13, 14, 30, 48, 64, 73, 76, 69, 52, 34, 15,
- -7, -31, -50, -62, -69, -71, -71, -66, -47, -19, 8, 26, 40, 58, 73, 81,
- 76, 57, 39, 23, 2, -22, -45, -62, -71, -73, -71, -69, -57, -32, 0, 26,
- 41, 55, 70, 81, 83, 64, 41, 24, 6, -15, -39, -60, -71, -73, -69, -69,
- -62, -40, -11, 20, 39, 51, 65, 78, 86, 75, 50, 29, 11, -8, -30, -53,
- -70, -77, -71, -66, -67, -53, -22, 13, 37, 49, 60, 75, 89, 84, 58, 33,
- 16, -2, -22, -47, -68, -77, -72, -67, -68, -60, -34, 0, 29, 47, 56, 69,
- 85, 88, 69, 40, 20, 4, -13, -35, -61, -76, -74, -65, -66, -65, -47, -15,
- 20, 43, 53, 64, 81, 89, 77, 50, 26, 9, -10, -29, -51, -71, -78, -71,
- -66, -64, -52, -27, 9, 38, 54, 62, 73, 85, 82, 60, 34, 13, -3, -19,
- -40, -65, -80, -74, -68, -69, -61, -40, -4, 29, 49, 61, 72, 86, 86, 70,
- 45, 21, 3, -16, -33, -56, -80, -78, -70, -70, -65, -50, -18, 20, 48, 62,
- 68, 80, 88, 78, 53, 26, 5, -12, -26, -45, -72, -81, -71, -67, -64, -56,
- -34, 4, 37, 57, 63, 73, 85, 83, 63, 37, 16, 0, -17, -36, -63, -79,
- -74, -70, -69, -63, -44, -10, 26, 52, 62, 69, 81, 84, 69, 45, 22, 3,
- -15, -28, -52, -75, -76, -69, -67, -64, -52, -24, 14, 45, 60, 65, 74, 82,
- 75, 54, 32, 12, -6, -21, -44, -68, -78, -74, -71, -69, -60, -34, 2, 34,
- 55, 66, 73, 79, 78, 61, 39, 20, 2, -16, -34, -56, -72, -74, -70, -71,
- -66, -47, -14, 21, 48, 61, 68, 76, 80, 69, 46, 27, 11, -7, -26, -50,
- -68, -72, -70, -70, -69, -54, -24, 10, 39, 57, 66, 72, 76, 70, 52, 33,
- 16, -4, -20, -39, -59, -70, -71, -69, -67, -60, -37, -6, 27, 50, 62, 67,
- 72, 74, 61, 41, 25, 10, -10, -31, -51, -67, -74, -73, -73, -68, -48, -16,
- 17, 45, 60, 66, 73, 75, 66, 48, 29, 15, -3, -24, -45, -62, -70, -72,
- -74, -70, -55, -26, 7, 32, 51, 63, 70, 73, 67, 51, 35, 24, 9, -16,
- -38, -54, -64, -68, -75, -75, -62, -36, -5, 22, 45, 60, 69, 74, 68, 57,
- 43, 29, 15, -9, -29, -45, -60, -67, -75, -76, -64, -44, -16, 10, 32, 52,
- 63, 68, 66, 59, 48, 36, 24, 6, -17, -35, -51, -60, -70, -78, -72, -55,
- -27, 1, 20, 39, 56, 65, 68, 60, 51, 41, 31, 15, -9, -27, -44, -58,
- -67, -75, -73, -58, -35, -8, 11, 32, 50, 60, 61, 57, 53, 47, 37, 25,
- 4, -19, -35, -48, -60, -73, -76, -67, -46, -18, 2, 20, 40, 56, 64, 62,
- 56, 49, 43, 34, 15, -10, -31, -45, -57, -70, -78, -69, -52, -27, -4, 13,
- 34, 52, 60, 57, 53, 52, 46, 36, 22, 1, -19, -35, -50, -65, -73, -70,
- -58, -41, -17, 4, 22, 42, 55, 58, 57, 55, 50, 43, 32, 12, -11, -30,
- -47, -61, -71, -72, -63, -46, -26, -6, 13, 30, 47, 53, 54, 56, 52, 46,
- 38, 24, 5, -20, -39, -52, -63, -67, -66, -57, -37, -15, 3, 18, 37, 50,
- 55, 59, 55, 49, 45, 32, 15, -10, -34, -50, -61, -66, -66, -58, -42, -24,
- -4, 11, 27, 44, 50, 54, 57, 53, 49, 39, 23, 2, -23, -43, -57, -64,
- -67, -62, -50, -33, -14, 4, 18, 37, 48, 53, 57, 55, 52, 44, 30, 13,
- -14, -38, -54, -62, -65, -62, -54, -42, -24, -2, 13, 28, 41, 48, 56, 57,
- 52, 45, 37, 23, 0, -28, -47, -57, -62, -63, -59, -50, -34, -14, 1, 16,
- 35, 48, 56, 59, 59, 54, 45, 31, 8, -20, -42, -56, -62, -64, -60, -52,
- -40, -23, -5, 10, 28, 43, 52, 56, 57, 56, 49, 38, 21, -8, -33, -46,
- -56, -60, -59, -56, -47, -32, -15, 0, 17, 34, 47, 55, 58, 57, 53, 43,
- 30, 8, -24, -42, -52, -59, -58, -57, -51, -42, -26, -8, 11, 29, 42, 50,
- 57, 59, 55, 48, 34, 15, -15, -36, -45, -52, -55, -58, -55, -43, -31, -17,
- -2, 16, 37, 50, 56, 58, 58, 54, 43, 23, -8, -33, -40, -47, -54, -57,
- -58, -48, -34, -23, -10, 9, 31, 48, 54, 55, 55, 57, 50, 32, 3, -28,
- -37, -41, -49, -55, -58, -49, -36, -27, -17, 1, 21, 41, 50, 52, 51, 54,
- 55, 41, 13, -18, -32, -35, -42, -50, -57, -55, -41, -32, -24, -10, 10, 33,
- 47, 50, 51, 54, 59, 49, 24, -8, -26, -30, -37, -46, -56, -59, -46, -35,
- -29, -18, 2, 25, 44, 48, 47, 51, 57, 56, 36, 5, -20, -28, -31, -40,
- -51, -58, -52, -39, -33, -25, -8, 15, 38, 49, 47, 50, 56, 60, 46, 15,
- -11, -25, -30, -36, -49, -60, -54, -39, -33, -30, -14, 8, 32, 47, 44, 44,
- 51, 59, 52, 26, -4, -20, -24, -29, -41, -54, -55, -43, -34, -33, -26, -8,
- 17, 37, 43, 42, 48, 59, 60, 42, 13, -11, -21, -25, -36, -51, -59, -51,
- -38, -34, -32, -17, 10, 33, 43, 43, 44, 55, 60, 46, 21, -6, -18, -22,
- -28, -42, -54, -52, -39, -30, -32, -25, -4, 20, 36, 39, 39, 48, 60, 57,
- 36, 10, -11, -19, -22, -34, -51, -58, -48, -35, -36, -34, -13, 13, 35, 41,
- 38, 46, 59, 61, 44, 20, -5, -20, -22, -30, -46, -56, -53, -39, -34, -36,
- -22, 1, 25, 39, 39, 42, 53, 60, 54, 34, 10, -10, -17, -21, -39, -57,
- -59, -48, -38, -43, -35, -11, 16, 37, 43, 42, 52, 61, 58, 41, 19, -3,
- -16, -21, -31, -50, -59, -53, -40, -39, -39, -22, 5, 30, 40, 38, 45, 58,
- 64, 52, 28, 5, -12, -17, -23, -44, -58, -56, -46, -40, -43, -33, -7, 22,
- 39, 41, 44, 55, 64, 60, 40, 13, -7, -16, -21, -35, -56, -60, -52, -44,
- -43, -40, -21, 11, 34, 40, 40, 50, 61, 64, 53, 29, 6, -10, -16, -25,
- -47, -62, -61, -53, -49, -47, -35, -5, 26, 42, 45, 49, 58, 65, 59, 39,
- 15, -5, -16, -22, -37, -56, -61, -56, -50, -47, -42, -21, 11, 33, 40, 44,
- 53, 63, 66, 54, 29, 8, -6, -15, -28, -52, -64, -60, -57, -53, -49, -31,
- 1, 28, 40, 42, 51, 63, 66, 56, 36, 14, -3, -13, -25, -45, -61, -61,
- -58, -54, -47, -38, -11, 20, 36, 41, 44, 55, 64, 60, 47, 28, 9, -4,
- -15, -32, -56, -67, -64, -62, -55, -48, -27, 8, 29, 41, 47, 57, 66, 65,
- 56, 39, 17, 0, -13, -27, -49, -66, -68, -67, -58, -48, -36, -8, 22, 38,
- 45, 53, 63, 65, 61, 51, 28, 11, -4, -20, -40, -62, -70, -71, -68, -55,
- -44, -24, 9, 30, 42, 52, 66, 69, 64, 58, 42, 20, 4, -14, -34, -57,
- -71, -73, -73, -63, -51, -35, -5, 23, 38, 48, 62, 71, 69, 65, 54, 32,
- 14, -6, -26, -48, -68, -79, -82, -72, -57, -42, -18, 11, 33, 48, 63, 73,
- 72, 68, 62, 46, 22, 0, -21, -42, -63, -76, -83, -80, -65, -49, -28, -2,
- 23, 42, 58, 71, 75, 72, 68, 56, 33, 10, -12, -32, -54, -73, -84, -87,
- -73, -54, -36, -15, 11, 34, 52, 67, 73, 73, 72, 66, 48, 21, -6, -26,
- -47, -67, -80, -88, -81, -62, -41, -23, 0, 27, 47, 65, 74, 74, 71, 67,
- 57, 33, 4, -20, -42, -64, -77, -88, -88, -72, -49, -27, -7, 16, 40, 63,
- 75, 75, 74, 69, 64, 46, 16, -13, -35, -57, -74, -87, -93, -81, -58, -35,
- -17, 6, 33, 59, 73, 76, 76, 71, 68, 58, 29, -4, -29, -48, -68, -83,
- -94, -92, -70, -42, -22, -4, 21, 51, 73, 78, 76, 73, 70, 63, 40, 7,
- -24, -42, -60, -79, -91, -92, -76, -52, -30, -12, 9, 39, 66, 76, 76, 75,
- 74, 70, 54, 24, -12, -36, -52, -72, -93, -100, -90, -64, -38, -21, -5, 25,
- 61, 81, 81, 77, 78, 76, 63, 33, -5, -33, -49, -67, -90, -100, -92, -71,
- -44, -21, -8, 14, 49, 75, 82, 77, 76, 75, 66, 45, 10, -27, -45, -59,
- -80, -98, -98, -81, -52, -26, -12, 2, 34, 71, 86, 80, 75, 77, 71, 54,
- 23, -17, -44, -57, -74, -93, -99, -87, -65, -36, -14, -4, 20, 55, 79, 82,
- 78, 78, 75, 65, 41, 1, -34, -52, -67, -88, -104, -98, -76, -47, -23, -12,
- 6, 45, 81, 90, 81, 79, 81, 72, 50, 11, -28, -50, -61, -81, -102, -103,
- -84, -57, -30, -13, 1, 30, 70, 92, 88, 81, 80, 75, 59, 27, -15, -48,
- -62, -76, -97, -106, -94, -69, -39, -16, -4, 17, 59, 92, 94, 87, 86, 83,
- 67, 36, -4, -38, -61, -77, -96, -111, -102, -80, -53, -26, -8, 14, 50, 89,
- 101, 93, 87, 83, 73, 46, 7, -31, -58, -72, -87, -106, -106, -88, -59, -31,
- -12, 5, 33, 74, 99, 99, 90, 84, 78, 57, 22, -18, -49, -70, -84, -100,
- -108, -96, -72, -43, -21, -3, 24, 61, 95, 106, 99, 90, 82, 65, 34, -6,
- -40, -66, -83, -96, -106, -102, -82, -52, -27, -8, 15, 48, 86, 107, 105, 94,
- 85, 73, 45, 6, -32, -61, -80, -91, -102, -106, -92, -63, -35, -15, 8, 37,
- 74, 102, 109, 98, 87, 76, 54, 21, -16, -50, -76, -89, -98, -104, -98, -76,
- -46, -23, -2, 25, 60, 93, 111, 106, 92, 82, 65, 35, -5, -39, -66, -83,
- -95, -105, -105, -86, -57, -33, -11, 15, 50, 86, 111, 115, 102, 88, 71, 43,
- 7, -32, -64, -86, -96, -100, -102, -92, -67, -40, -13, 13, 42, 75, 103, 116,
- 106, 90, 74, 49, 16, -21, -54, -80, -94, -98, -100, -94, -75, -50, -23, 4,
- 30, 62, 95, 117, 115, 100, 81, 57, 28, -10, -46, -75, -95, -102, -101, -97,
- -83, -61, -32, -2, 24, 55, 87, 111, 118, 106, 88, 65, 35, 0, -36, -67,
- -89, -101, -102, -98, -89, -68, -43, -13, 16, 46, 80, 107, 121, 116, 98, 75,
- 47, 11, -27, -62, -87, -101, -104, -100, -93, -77, -51, -18, 13, 36, 67, 99,
- 119, 119, 103, 81, 53, 21, -16, -52, -79, -96, -106, -102, -93, -82, -60, -30,
- 3, 30, 59, 88, 111, 121, 111, 89, 61, 30, -4, -41, -74, -94, -106, -104,
- -95, -87, -70, -41, -8, 22, 49, 81, 106, 120, 118, 98, 73, 41, 8, -30,
- -64, -87, -104, -111, -100, -91, -77, -51, -21, 13, 41, 73, 100, 117, 122, 107,
- 83, 52, 19, -18, -55, -82, -101, -111, -105, -93, -83, -60, -29, 5, 35, 64,
- 92, 112, 121, 112, 88, 61, 29, -7, -45, -75, -94, -108, -108, -96, -87, -67,
- -37, -5, 26, 52, 83, 105, 116, 116, 97, 70, 41, 7, -33, -67, -91, -105,
- -110, -99, -88, -73, -48, -18, 15, 45, 74, 98, 114, 118, 104, 79, 51, 17,
- -21, -58, -86, -102, -109, -103, -90, -77, -54, -23, 9, 36, 62, 88, 107, 114,
- 107, 88, 63, 30, -8, -46, -77, -96, -107, -108, -97, -81, -63, -36, -4, 30,
- 59, 84, 104, 115, 112, 95, 69, 38, 5, -33, -69, -94, -104, -105, -99, -87,
- -72, -44, -11, 21, 47, 71, 97, 113, 113, 99, 77, 49, 17, -19, -57, -87,
- -101, -105, -103, -90, -72, -54, -24, 10, 41, 64, 86, 104, 111, 104, 85, 57,
- 25, -7, -42, -75, -96, -101, -98, -92, -79, -61, -36, -4, 28, 51, 74, 98,
- 110, 107, 94, 70, 38, 5, -30, -64, -89, -101, -101, -95, -79, -63, -43, -14,
- 21, 48, 68, 90, 105, 108, 97, 74, 44, 12, -20, -52, -83, -96, -96, -92,
- -82, -67, -49, -24, 10, 39, 59, 79, 99, 107, 101, 83, 54, 21, -11, -41,
- -71, -92, -98, -95, -84, -68, -54, -35, -5, 28, 54, 73, 92, 103, 103, 90,
- 64, 31, -4, -34, -63, -85, -94, -92, -84, -70, -56, -38, -11, 19, 44, 64,
- 83, 95, 98, 90, 66, 39, 9, -22, -50, -73, -86, -89, -84, -72, -59, -45,
- -23, 6, 35, 58, 75, 89, 96, 92, 75, 49, 19, -14, -42, -63, -80, -88,
- -84, -74, -60, -48, -30, -5, 23, 52, 70, 82, 91, 91, 79, 57, 29, -3,
- -33, -54, -70, -84, -87, -79, -65, -50, -35, -16, 10, 41, 68, 80, 85, 88,
- 82, 64, 36, 3, -28, -49, -60, -72, -83, -81, -66, -49, -37, -22, -2, 28,
- 58, 74, 78, 83, 81, 69, 45, 14, -18, -42, -55, -66, -77, -79, -68, -53,
- -39, -25, -8, 17, 46, 67, 72, 75, 74, 70, 53, 24, -9, -34, -48, -55,
- -64, -74, -70, -55, -40, -28, -17, 3, 33, 61, 70, 71, 69, 68, 61, 37,
- 3, -28, -44, -50, -57, -70, -73, -58, -41, -30, -21, -8, 21, 52, 67, 69,
- 66, 66, 64, 44, 10, -22, -39, -48, -52, -61, -72, -62, -43, -29, -20, -12,
- 7, 38, 62, 68, 61, 56, 60, 51, 23, -12, -36, -43, -44, -49, -65, -65,
- -45, -29, -22, -19, -7, 24, 52, 65, 57, 52, 58, 57, 36, 0, -30, -38,
- -37, -39, -55, -66, -52, -33, -23, -21, -14, 10, 40, 60, 59, 49, 51, 54,
- 43, 11, -21, -35, -37, -33, -42, -55, -49, -29, -19, -20, -19, -5, 23, 49,
- 54, 43, 42, 50, 49, 23, -12, -30, -34, -29, -31, -49, -54, -35, -19, -16,
- -18, -11, 10, 39, 55, 45, 35, 41, 47, 31, -3, -26, -33, -28, -23, -36,
- -47, -36, -18, -11, -16, -16, -3, 21, 42, 42, 32, 32, 40, 35, 13, -13,
- -25, -24, -17, -22, -37, -38, -25, -16, -16, -19, -11, 7, 30, 42, 34, 27,
- 33, 35, 19, -6, -21, -23, -17, -14, -23, -29, -21, -11, -10, -17, -16, -4,
- 14, 30, 31, 20, 21, 29, 24, 6, -11, -16, -11, -5, -10, -20, -22, -15,
- -12, -17, -21, -15, 0, 20, 29, 22, 17, 23, 25, 16, -2, -14, -14, -7,
- -2, -9, -14, -12, -9, -11, -17, -17, -11, 3, 18, 17, 9, 13, 19, 17,
- 7, -5, -5, 3, 8, 3, -7, -10, -12, -14, -20, -22, -17, -7, 9, 17,
- 10, 8, 15, 18, 11, 2, -3, 1, 8, 9, 5, -3, -9, -12, -18, -21,
- -21, -19, -4, 10, 9, 2, 5, 14, 16, 11, 4, 5, 13, 16, 14, 6,
- -8, -14, -19, -23, -24, -21, -13, -2, 7, 3, -2, 8, 12, 11, 9, 10,
- 14, 19, 20, 16, 4, -9, -17, -23, -26, -27, -24, -14, -2, 1, -5, 3,
- 15, 17, 14, 14, 17, 22, 25, 20, 9, -8, -19, -25, -30, -29, -26, -22,
- -11, 0, -3, -3, 9, 16, 19, 20, 21, 24, 28, 28, 20, 2, -16, -25,
- -30, -34, -33, -32, -23, -9, -6, -8, 2, 15, 21, 24, 26, 29, 33, 34,
- 30, 14, -11, -26, -33, -38, -38, -37, -34, -23, -12, -7, 0, 11, 21, 29,
- 34, 35, 37, 39, 35, 21, -5, -26, -34, -39, -40, -42, -42, -31, -17, -9,
- -4, 7, 19, 31, 38, 38, 41, 42, 40, 28, 3, -22, -36, -42, -45, -46,
- -46, -37, -23, -14, -6, 6, 20, 32, 40, 40, 44, 46, 41, 31, 13, -12,
- -32, -44, -47, -48, -49, -44, -32, -20, -8, 3, 15, 27, 40, 45, 47, 50,
- 47, 39, 21, -6, -29, -42, -46, -51, -56, -52, -41, -24, -13, -4, 11, 27,
- 41, 51, 52, 53, 52, 45, 29, 2, -25, -45, -50, -52, -57, -56, -49, -32,
- -16, -4, 9, 22, 36, 49, 55, 56, 56, 50, 35, 11, -14, -37, -51, -57,
- -61, -61, -56, -41, -23, -8, 8, 21, 33, 48, 61, 64, 60, 54, 40, 17,
- -8, -34, -52, -59, -62, -63, -60, -49, -30, -14, 2, 19, 33, 47, 60, 66,
- 67, 65, 50, 25, -3, -26, -47, -59, -68, -72, -66, -57, -38, -20, -5, 14,
- 30, 44, 61, 71, 71, 68, 57, 34, 7, -20, -43, -58, -68, -72, -69, -62,
- -45, -25, -10, 7, 24, 42, 59, 70, 74, 73, 65, 46, 16, -15, -38, -53,
- -65, -77, -77, -70, -54, -34, -19, 0, 20, 41, 60, 74, 82, 80, 71, 54,
- 27, -8, -36, -55, -68, -78, -82, -76, -61, -40, -20, -2, 17, 36, 57, 74,
- 83, 82, 74, 62, 39, 3, -31, -49, -62, -75, -84, -84, -69, -47, -27, -13,
- 6, 31, 56, 73, 82, 86, 80, 68, 49, 14, -24, -46, -60, -74, -83, -86,
- -76, -54, -32, -15, 3, 23, 48, 71, 85, 87, 80, 71, 57, 27, -12, -41,
- -57, -68, -78, -88, -84, -64, -41, -23, -5, 16, 40, 65, 84, 90, 87, 77,
- 63, 36, -3, -34, -57, -69, -76, -85, -87, -73, -48, -27, -8, 13, 34, 60,
- 83, 91, 86, 77, 66, 44, 9, -26, -53, -68, -74, -83, -88, -80, -56, -33,
- -13, 9, 29, 55, 79, 93, 89, 76, 67, 52, 21, -15, -46, -69, -74, -77,
- -84, -86, -67, -42, -20, 4, 23, 43, 71, 94, 95, 80, 67, 56, 32, 0,
- -37, -66, -74, -73, -78, -87, -76, -50, -25, 1, 21, 37, 61, 88, 97, 84,
- 67, 57, 38, 8, -25, -59, -77, -77, -76, -81, -80, -61, -34, -6, 20, 36,
- 55, 80, 96, 91, 70, 54, 39, 17, -14, -51, -75, -79, -75, -77, -80, -68,
- -40, -11, 15, 33, 48, 71, 92, 91, 73, 57, 45, 24, -3, -38, -68, -79,
- -77, -76, -80, -74, -51, -19, 12, 32, 46, 65, 88, 96, 83, 59, 40, 24,
- 4, -31, -67, -83, -80, -73, -73, -72, -55, -24, 9, 31, 44, 58, 78, 90,
- 84, 63, 42, 28, 10, -18, -53, -77, -82, -76, -73, -74, -65, -37, -2, 27,
- 42, 55, 73, 88, 90, 72, 47, 28, 13, -12, -45, -74, -84, -78, -70, -68,
- -63, -43, -9, 23, 42, 52, 64, 78, 84, 75, 52, 32, 17, -3, -32, -62,
- -79, -78, -71, -67, -65, -52, -19, 15, 38, 50, 61, 73, 80, 79, 59, 34,
- 18, 3, -21, -51, -75, -81, -72, -64, -61, -54, -31, 4, 31, 48, 55, 63,
- 73, 78, 67, 40, 21, 8, -12, -39, -65, -80, -76, -65, -58, -52, -38, -8,
- 25, 45, 56, 61, 67, 74, 69, 47, 22, 7, -10, -31, -56, -75, -77, -66,
- -57, -49, -37, -14, 16, 40, 53, 57, 61, 67, 69, 55, 30, 11, -6, -25,
- -47, -69, -78, -70, -59, -51, -40, -20, 10, 34, 51, 58, 59, 63, 66, 59,
- 36, 14, -2, -19, -40, -61, -75, -71, -59, -51, -41, -27, -2, 26, 47, 58,
- 58, 59, 64, 63, 46, 19, -2, -17, -35, -56, -71, -75, -64, -50, -40, -26,
- -6, 21, 43, 55, 57, 56, 58, 59, 47, 23, 1, -13, -29, -48, -63, -69,
- -61, -48, -40, -29, -11, 13, 35, 48, 53, 51, 53, 57, 50, 33, 9, -10,
- -25, -42, -56, -65, -64, -51, -40, -29, -13, 9, 30, 44, 50, 48, 47, 50,
- 46, 35, 13, -8, -20, -33, -47, -57, -56, -48, -38, -30, -16, 1, 21, 35,
- 44, 46, 42, 44, 44, 39, 21, -3, -18, -30, -40, -51, -57, -51, -37, -26,
- -14, 0, 16, 33, 42, 43, 37, 34, 37, 35, 22, 1, -17, -27, -34, -41,
- -48, -45, -36, -25, -11, 0, 11, 24, 34, 38, 35, 30, 29, 30, 24, 8,
- -11, -24, -31, -36, -42, -42, -35, -25, -12, -2, 9, 21, 29, 33, 32, 27,
- 25, 26, 23, 9, -8, -21, -31, -34, -36, -37, -33, -26, -13, -2, 8, 18,
- 24, 28, 29, 27, 22, 20, 21, 14, -2, -17, -27, -30, -31, -33, -32, -26,
- -14, -3, 6, 15, 22, 27, 26, 25, 22, 17, 17, 13, 3, -12, -25, -30,
- -31, -30, -27, -24, -14, 0, 8, 16, 20, 22, 22, 21, 16, 11, 13, 13,
- 3, -8, -21, -27, -26, -25, -25, -23, -12, 0, 6, 12, 18, 20, 22, 20,
- 15, 9, 9, 10, 3, -9, -21, -29, -28, -23, -20, -19, -10, 3, 13, 17,
- 19, 19, 21, 17, 11, 4, 1, 4, 0, -8, -17, -25, -24, -21, -19, -16,
- -9, 4, 13, 17, 19, 20, 22, 19, 11, 3, -4, -3, -4, -12, -18, -26,
- -28, -23, -16, -10, -5, 5, 18, 25, 25, 22, 21, 19, 9, 0, -9, -11,
- -10, -13, -16, -24, -27, -22, -14, -8, -2, 7, 17, 25, 25, 22, 20, 17,
- 10, -2, -10, -12, -13, -15, -18, -20, -24, -22, -16, -8, 3, 11, 17, 25,
- 27, 23, 21, 17, 9, 0, -10, -12, -13, -18, -19, -20, -24, -23, -17, -10,
- 0, 11, 19, 26, 30, 26, 24, 20, 12, 3, -8, -15, -18, -22, -25, -25,
- -25, -24, -20, -12, 2, 15, 20, 25, 31, 33, 29, 23, 12, 3, -5, -15,
- -23, -28, -28, -25, -22, -22, -18, -10, 2, 15, 19, 23, 30, 32, 28, 24,
- 15, 7, 1, -13, -23, -27, -29, -28, -26, -24, -20, -14, -2, 13, 20, 24,
- 32, 34, 32, 29, 22, 9, -2, -10, -21, -30, -34, -34, -29, -22, -20, -18,
- -5, 14, 23, 25, 31, 36, 35, 30, 22, 10, 0, -8, -21, -34, -39, -36,
- -32, -27, -20, -15, -5, 14, 27, 28, 32, 36, 35, 33, 25, 14, 0, -11,
- -21, -34, -40, -41, -39, -30, -20, -13, -6, 10, 27, 30, 32, 35, 34, 36,
- 29, 17, 5, -7, -16, -33, -45, -45, -43, -33, -24, -18, -9, 8, 26, 32,
- 33, 39, 38, 36, 31, 20, 10, -6, -19, -32, -45, -47, -46, -39, -25, -12,
- -3, 8, 22, 32, 32, 35, 35, 32, 31, 23, 14, 0, -15, -26, -43, -51,
- -50, -43, -29, -17, -6, 5, 19, 34, 36, 33, 37, 37, 34, 25, 16, 5,
- -11, -26, -41, -51, -55, -51, -36, -21, -7, 7, 16, 28, 37, 35, 35, 36,
- 34, 30, 20, 9, -7, -22, -37, -49, -56, -54, -42, -25, -11, 2, 13, 24,
- 35, 38, 37, 38, 37, 32, 25, 16, 1, -21, -38, -47, -56, -58, -50, -34,
- -14, 4, 13, 20, 31, 40, 39, 35, 36, 34, 28, 20, 5, -15, -33, -44,
- -55, -63, -54, -38, -19, -2, 10, 17, 30, 40, 41, 36, 38, 41, 33, 22,
- 9, -13, -36, -50, -55, -63, -61, -44, -22, 2, 18, 22, 28, 38, 42, 39,
- 34, 35, 34, 27, 14, -7, -29, -43, -51, -60, -63, -50, -30, -10, 8, 16,
- 21, 32, 40, 40, 38, 39, 41, 35, 24, 6, -20, -41, -54, -62, -65, -58,
- -39, -16, 7, 18, 22, 29, 39, 43, 40, 35, 38, 37, 27, 12, -14, -37,
- -51, -58, -64, -64, -47, -22, -2, 14, 18, 24, 36, 44, 45, 41, 43, 43,
- 32, 17, -8, -35, -54, -63, -67, -68, -56, -29, -4, 16, 24, 26, 35, 44,
- 47, 43, 38, 38, 36, 24, 0, -30, -50, -57, -59, -63, -61, -40, -11, 11,
- 20, 20, 26, 39, 48, 46, 40, 39, 42, 33, 12, -20, -47, -58, -60, -62,
- -61, -49, -23, 2, 17, 21, 22, 33, 48, 51, 45, 43, 43, 38, 20, -10,
- -41, -58, -61, -64, -62, -55, -35, -9, 10, 21, 23, 32, 50, 57, 49, 45,
- 45, 43, 26, -6, -38, -58, -62, -65, -67, -61, -44, -15, 10, 23, 26, 28,
- 44, 59, 55, 46, 42, 41, 33, 6, -30, -57, -64, -62, -64, -62, -50, -26,
- 2, 18, 26, 28, 39, 59, 60, 48, 43, 43, 37, 14, -22, -53, -67, -63,
- -65, -66, -55, -33, -2, 19, 28, 31, 37, 55, 64, 53, 41, 39, 37, 20,
- -16, -48, -66, -65, -62, -66, -60, -43, -12, 15, 26, 31, 37, 53, 69, 63,
- 46, 39, 38, 27, -5, -44, -72, -73, -65, -65, -63, -52, -24, 11, 31, 36,
- 38, 48, 65, 70, 53, 38, 34, 28, 5, -35, -69, -78, -70, -65, -63, -53,
- -30, 2, 26, 38, 43, 49, 62, 69, 58, 40, 33, 28, 9, -25, -61, -78,
- -75, -69, -64, -55, -37, -7, 22, 36, 43, 49, 57, 66, 62, 44, 31, 29,
- 15, -16, -52, -76, -77, -69, -63, -57, -44, -16, 14, 33, 42, 48, 54, 65,
- 68, 52, 33, 27, 19, -6, -41, -72, -82, -74, -65, -59, -48, -24, 7, 29,
- 43, 50, 53, 60, 67, 58, 39, 28, 22, 2, -31, -64, -82, -79, -71, -61,
- -49, -31, -2, 22, 40, 51, 55, 58, 65, 63, 46, 29, 21, 9, -21, -56,
- -79, -83, -77, -65, -54, -37, -10, 16, 36, 50, 57, 60, 65, 64, 50, 33,
- 22, 11, -13, -47, -73, -82, -80, -70, -57, -42, -19, 8, 30, 49, 58, 61,
- 62, 64, 56, 41, 24, 11, -6, -35, -66, -80, -82, -75, -61, -45, -25, -2,
- 22, 43, 57, 63, 64, 63, 58, 49, 31, 15, -2, -26, -58, -79, -85, -81,
- -66, -49, -31, -9, 17, 39, 55, 64, 69, 67, 61, 53, 35, 16, 1, -20,
- -49, -75, -86, -85, -74, -54, -34, -11, 11, 33, 53, 64, 70, 68, 59, 51,
- 40, 22, 5, -15, -40, -66, -79, -81, -78, -63, -41, -19, 4, 25, 44, 58,
- 67, 72, 65, 57, 47, 29, 11, -8, -31, -61, -81, -85, -82, -68, -47, -25,
- -3, 21, 44, 59, 68, 73, 68, 56, 47, 33, 15, -7, -27, -52, -76, -82,
- -82, -72, -52, -30, -7, 13, 36, 57, 67, 74, 72, 61, 48, 36, 20, -4,
- -25, -47, -71, -81, -81, -75, -56, -33, -10, 11, 30, 49, 63, 73, 74, 63,
- 48, 37, 25, 6, -20, -41, -63, -79, -81, -77, -65, -43, -19, 4, 25, 45,
- 63, 73, 76, 70, 55, 41, 28, 10, -15, -38, -59, -77, -83, -79, -70, -49,
- -25, -4, 20, 40, 59, 74, 76, 73, 62, 46, 33, 16, -10, -34, -51, -68,
- -83, -85, -75, -58, -34, -11, 14, 35, 55, 73, 79, 76, 69, 51, 33, 20,
- -2, -30, -53, -67, -81, -84, -76, -61, -39, -14, 11, 32, 49, 67, 77, 74,
- 68, 55, 37, 23, 5, -22, -45, -59, -73, -84, -82, -68, -46, -24, 3, 26,
- 43, 62, 75, 74, 72, 61, 42, 25, 10, -15, -40, -57, -70, -83, -84, -71,
- -49, -28, -6, 20, 41, 59, 72, 72, 69, 63, 48, 29, 13, -8, -31, -51,
- -66, -79, -84, -75, -56, -37, -16, 12, 36, 55, 71, 74, 72, 69, 54, 34,
- 16, -5, -28, -47, -61, -75, -85, -80, -60, -38, -20, 4, 30, 53, 68, 71,
- 69, 67, 57, 39, 20, 0, -21, -41, -58, -71, -79, -79, -66, -45, -25, -3,
- 23, 45, 61, 68, 69, 70, 63, 47, 29, 8, -16, -37, -56, -71, -80, -81,
- -71, -52, -30, -7, 17, 41, 60, 67, 67, 68, 65, 50, 30, 10, -14, -31,
- -47, -65, -77, -79, -70, -53, -33, -14, 8, 34, 56, 62, 62, 66, 64, 54,
- 36, 15, -8, -27, -42, -61, -73, -75, -70, -56, -36, -14, 5, 26, 49, 60,
- 59, 61, 60, 54, 42, 23, -2, -22, -35, -53, -69, -75, -70, -58, -41, -20,
- -3, 18, 43, 59, 57, 57, 60, 56, 44, 28, 7, -17, -32, -47, -63, -73,
- -72, -62, -46, -23, -6, 12, 35, 55, 60, 57, 59, 56, 49, 35, 14, -13,
- -28, -40, -58, -72, -73, -62, -50, -31, -13, 5, 30, 51, 59, 56, 58, 61,
- 56, 38, 17, -9, -26, -37, -52, -68, -74, -63, -50, -32, -14, 1, 22, 45,
- 57, 56, 51, 54, 54, 41, 21, -4, -22, -31, -44, -59, -69, -63, -48, -36,
- -21, -7, 11, 35, 52, 56, 53, 54, 58, 48, 30, 8, -17, -32, -43, -57,
- -68, -69, -56, -39, -22, -8, 6, 28, 49, 57, 54, 51, 55, 52, 35, 13,
- -13, -29, -36, -49, -64, -70, -58, -39, -23, -11, 0, 19, 43, 57, 55, 47,
- 49, 55, 43, 18, -9, -28, -35, -42, -57, -69, -65, -45, -25, -11, 1, 14,
- 37, 55, 60, 50, 45, 48, 42, 21, -4, -25, -35, -40, -50, -60, -61, -46,
- -27, -15, -6, 6, 25, 46, 56, 50, 43, 45, 47, 33, 9, -15, -30, -37,
- -45, -58, -64, -56, -36, -18, -8, 4, 18, 40, 58, 59, 47, 39, 41, 35,
- 12, -15, -32, -38, -39, -46, -57, -55, -37, -17, -7, 1, 11, 27, 48, 56,
- 47, 37, 38, 38, 21, -6, -24, -32, -37, -43, -54, -57, -44, -25, -9, 2,
- 11, 24, 44, 57, 51, 38, 32, 31, 21, -5, -28, -35, -36, -36, -45, -51,
- -41, -25, -8, 3, 8, 17, 33, 48, 49, 37, 31, 30, 25, 7, -18, -30,
- -34, -37, -40, -48, -47, -33, -16, 1, 11, 16, 28, 42, 50, 43, 30, 25,
- 22, 10, -12, -28, -33, -34, -35, -41, -44, -33, -18, -2, 9, 12, 20, 32,
- 43, 41, 29, 24, 22, 14, -3, -21, -29, -30, -31, -35, -41, -35, -21, -6,
- 9, 13, 18, 27, 38, 42, 29, 18, 16, 13, 4, -15, -27, -28, -27, -28,
- -34, -34, -23, -10, 5, 11, 14, 22, 32, 37, 31, 20, 16, 12, 6, -9,
- -22, -25, -27, -26, -32, -34, -27, -15, 0, 10, 12, 18, 28, 36, 35, 23,
- 14, 11, 8, -3, -19, -28, -28, -25, -27, -32, -28, -16, -2, 11, 14, 14,
- 22, 30, 31, 24, 15, 11, 8, 2, -11, -22, -25, -25, -26, -30, -28, -18,
- -7, 5, 12, 14, 19, 27, 30, 26, 19, 13, 9, 4, -6, -20, -26, -23,
- -24, -27, -27, -19, -6, 4, 12, 12, 13, 22, 26, 22, 15, 11, 10, 6,
- -2, -12, -19, -19, -21, -25, -25, -20, -11, -3, 5, 9, 13, 19, 24, 24,
- 21, 15, 12, 7, 2, -9, -20, -22, -22, -23, -24, -22, -11, -2, 7, 11,
- 13, 17, 21, 21, 18, 13, 11, 7, 1, -7, -15, -19, -19, -21, -20, -18,
- -12, -4, 2, 8, 11, 15, 17, 16, 15, 13, 11, 8, 4, -3, -11, -16,
- -15, -19, -20, -16, -12, -5, 2, 5, 8, 14, 17, 15, 11, 10, 9, 8,
- 4, -2, -6, -11, -12, -14, -18, -13, -7, -6, -3, 2, 6, 10, 13, 13,
- 9, 8, 9, 6, 1, 0, -5, -9, -12, -12, -13, -12, -4, 1, 3, 4,
- 4, 7, 11, 10, 7, 3, 3, 4, 2, -2, -3, -6, -7, -6, -6, -8,
- -5, 2, 1, 1, 0, 1, 5, 5, 3, 0, 0, 5, 5, 2, 3, 0,
- -3, -5, -6, -8, -7, -2, -3, -4, -2, -2, 3, 6, 4, 1, -3, 1,
- 5, 3, 2, 0, -2, -3, -4, -5, -5, 1, 2, -3, -3, -4, -3, 4,
- 4, 0, -5, -3, 3, 3, 2, 1, 1, 0, 0, 0, -3, -2, 1, -2,
- -4, -3, -4, 1, 5, 2, -5, -7, -2, 2, -2, -2, 0, 2, 3, 2,
- 2, 3, 6, 4, -2, -5, -6, -2, 3, -2, -9, -11, -5, 0, -3, -4,
- -2, 3, 7, 8, 4, 2, 4, 3, 0, -6, -8, -6, 2, 4, -3, -10,
- -10, -5, -2, -4, -5, -3, 5, 11, 11, 8, 5, 5, 4, -2, -9, -9,
- -2, 0, -5, -13, -14, -10, -5, -4, -2, 2, 6, 14, 15, 11, 8, 6,
- 1, -5, -10, -12, -6, 1, -2, -10, -15, -11, -4, -3, -6, -5, 2, 14,
- 19, 14, 10, 10, 8, 3, -6, -15, -12, -4, -4, -12, -18, -17, -10, -2,
- 0, 1, 6, 16, 25, 21, 12, 8, 4, -2, -8, -18, -20, -11, -6, -9,
- -14, -14, -10, -3, 0, 1, 6, 13, 23, 25, 17, 13, 9, 1, -6, -13,
- -18, -14, -11, -13, -17, -19, -14, -8, -3, 1, 7, 14, 24, 30, 24, 16,
- 12, 4, -5, -11, -18, -19, -15, -12, -14, -19, -18, -14, -9, 0, 8, 13,
- 19, 27, 28, 22, 18, 9, -4, -11, -14, -16, -15, -16, -16, -17, -16, -14,
- -13, -6, 4, 12, 19, 26, 31, 27, 19, 13, 3, -8, -12, -16, -18, -19,
- -17, -16, -20, -18, -15, -10, 1, 10, 18, 24, 31, 30, 22, 18, 9, -4,
- -10, -14, -17, -20, -22, -19, -19, -22, -18, -13, -2, 9, 16, 21, 29, 36,
- 29, 19, 12, 1, -7, -10, -15, -22, -24, -20, -18, -21, -21, -17, -8, 7,
- 16, 23, 27, 33, 35, 26, 17, 7, -5, -11, -14, -22, -27, -24, -19, -22,
- -25, -19, -11, 5, 16, 21, 25, 33, 38, 31, 18, 9, -2, -10, -13, -22,
- -29, -28, -21, -18, -24, -22, -15, -3, 14, 21, 24, 30, 38, 36, 24, 13,
- 4, -5, -9, -16, -28, -32, -25, -21, -25, -27, -18, -7, 8, 18, 24, 31,
- 40, 40, 29, 16, 6, -3, -8, -16, -27, -31, -27, -22, -24, -27, -21, -10,
- 4, 16, 22, 28, 37, 40, 33, 19, 7, 1, -5, -12, -23, -32, -28, -23,
- -23, -27, -26, -15, -2, 13, 21, 25, 34, 41, 38, 28, 14, 4, -3, -11,
- -22, -34, -35, -30, -26, -28, -29, -20, -3, 14, 24, 27, 32, 41, 42, 34,
- 17, 4, -4, -11, -20, -32, -38, -33, -28, -27, -27, -22, -9, 7, 20, 29,
- 34, 39, 40, 37, 24, 10, 2, -7, -16, -28, -40, -40, -33, -29, -28, -27,
- -16, 5, 21, 28, 32, 36, 41, 40, 30, 12, 1, -6, -11, -22, -37, -42,
- -34, -30, -29, -27, -20, -3, 16, 27, 32, 34, 39, 41, 35, 20, 6, -4,
- -11, -16, -32, -45, -41, -33, -31, -27, -23, -10, 13, 28, 33, 35, 38, 39,
- 36, 25, 8, -6, -11, -14, -26, -42, -45, -34, -29, -25, -23, -15, 6, 26,
- 36, 36, 36, 37, 36, 29, 14, -2, -12, -14, -23, -42, -50, -42, -32, -23,
- -18, -15, 3, 25, 38, 39, 35, 35, 37, 33, 18, -3, -15, -18, -20, -34,
- -48, -47, -34, -22, -14, -12, -4, 17, 35, 41, 37, 34, 33, 33, 24, 6,
- -13, -22, -22, -30, -45, -51, -39, -23, -10, -6, -3, 13, 32, 41, 37, 30,
- 29, 31, 27, 10, -10, -22, -23, -26, -38, -48, -44, -28, -12, -5, -3, 9,
- 27, 38, 38, 32, 28, 29, 27, 17, -4, -21, -26, -27, -35, -47, -49, -33,
- -12, 2, 5, 9, 23, 35, 40, 34, 21, 23, 25, 22, 5, -20, -28, -28,
- -29, -39, -50, -43, -19, 3, 10, 7, 15, 29, 41, 43, 28, 22, 23, 22,
- 12, -16, -33, -32, -32, -38, -46, -43, -21, 3, 15, 13, 16, 29, 35, 35,
- 27, 19, 19, 19, 15, -8, -30, -31, -30, -32, -40, -44, -29, -2, 18, 17,
- 11, 22, 34, 37, 32, 21, 18, 20, 17, -2, -28, -37, -34, -34, -38, -42,
- -30, -7, 16, 22, 16, 20, 31, 31, 29, 23, 17, 18, 19, 6, -21, -37,
- -35, -34, -35, -38, -35, -15, 14, 27, 21, 13, 23, 31, 31, 26, 16, 12,
- 16, 12, -10, -35, -39, -35, -36, -36, -34, -21, 6, 24, 24, 16, 20, 29,
- 28, 27, 22, 16, 17, 15, -4, -29, -41, -39, -40, -39, -36, -29, -6, 20,
- 27, 21, 19, 28, 33, 31, 27, 18, 14, 13, 2, -22, -41, -43, -40, -39,
- -34, -28, -12, 16, 28, 24, 19, 25, 29, 27, 24, 19, 15, 12, 4, -15,
- -34, -41, -40, -37, -32, -26, -18, 5, 24, 24, 20, 21, 26, 27, 26, 24,
- 18, 12, 6, -9, -30, -44, -45, -41, -33, -26, -19, -2, 23, 29, 24, 22,
- 24, 28, 25, 22, 18, 13, 7, -7, -24, -40, -46, -42, -36, -28, -21, -6,
- 15, 28, 25, 22, 25, 29, 28, 23, 20, 14, 6, -6, -22, -40, -47, -42,
- -36, -28, -23, -10, 13, 30, 28, 21, 23, 27, 28, 21, 18, 16, 9, -2,
- -17, -33, -44, -44, -38, -31, -23, -14, 5, 25, 32, 25, 23, 26, 29, 24,
- 16, 13, 8, -2, -15, -31, -43, -44, -37, -30, -23, -14, 1, 21, 31, 27,
- 22, 24, 28, 25, 17, 13, 10, 3, -10, -27, -40, -44, -38, -32, -26, -17,
- -3, 16, 31, 31, 25, 25, 30, 29, 17, 8, 7, 3, -8, -25, -39, -43,
- -37, -31, -27, -18, -4, 13, 29, 32, 26, 24, 27, 27, 17, 9, 8, 6,
- -5, -20, -34, -39, -37, -34, -30, -21, -8, 6, 23, 34, 31, 29, 28, 27,
- 22, 13, 6, 5, -4, -18, -34, -40, -37, -34, -29, -23, -10, 5, 21, 32,
- 29, 27, 29, 26, 20, 12, 4, 3, 0, -12, -28, -37, -35, -31, -29, -23,
- -13, 1, 16, 30, 33, 29, 27, 25, 21, 15, 5, -2, -3, -9, -22, -35,
- -36, -31, -29, -24, -14, 0, 12, 27, 35, 31, 29, 26, 21, 16, 8, -2,
- -3, -7, -19, -34, -36, -32, -31, -28, -18, -3, 11, 22, 32, 32, 30, 29,
- 23, 16, 11, 2, -3, -6, -17, -32, -37, -32, -30, -31, -23, -6, 9, 18,
- 30, 36, 32, 31, 25, 17, 13, 4, -6, -8, -14, -26, -36, -34, -31, -31,
- -25, -11, 6, 16, 24, 34, 35, 33, 28, 17, 16, 10, -3, -9, -13, -23,
- -34, -36, -32, -31, -27, -16, 2, 16, 22, 30, 35, 33, 30, 21, 15, 11,
- 0, -7, -11, -20, -31, -35, -31, -31, -29, -21, -6, 13, 21, 25, 32, 34,
- 33, 26, 18, 13, 4, -6, -10, -19, -29, -34, -34, -29, -27, -24, -12, 7,
- 20, 25, 30, 33, 32, 29, 21, 13, 7, -5, -11, -18, -28, -35, -36, -29,
- -25, -24, -16, 3, 21, 26, 28, 34, 37, 34, 26, 12, 4, -5, -13, -20,
- -30, -35, -39, -35, -24, -19, -13, -2, 15, 27, 30, 32, 34, 31, 28, 18,
- 5, -6, -15, -20, -24, -31, -37, -35, -24, -19, -16, -9, 8, 24, 30, 30,
- 33, 35, 35, 24, 5, -5, -11, -20, -27, -34, -40, -39, -30, -21, -16, -9,
- 4, 20, 32, 36, 36, 36, 35, 31, 13, -3, -13, -23, -27, -29, -41, -44,
- -33, -19, -11, -10, -4, 14, 32, 38, 34, 33, 36, 33, 18, -4, -13, -20,
- -25, -28, -37, -43, -34, -22, -14, -8, -4, 9, 26, 39, 38, 35, 35, 34,
- 23, 3, -12, -21, -28, -28, -31, -41, -40, -27, -15, -7, -6, 2, 20, 37,
- 42, 36, 34, 35, 28, 9, -10, -18, -24, -26, -29, -38, -42, -32, -21, -11,
- -6, -3, 12, 33, 45, 41, 37, 37, 29, 13, -4, -17, -26, -28, -28, -33,
- -39, -37, -26, -15, -8, -7, 6, 29, 47, 46, 39, 34, 30, 20, 1, -18,
- -26, -26, -25, -29, -37, -40, -31, -17, -8, -7, 0, 20, 42, 51, 45, 38,
- 30, 18, 7, -10, -24, -27, -26, -24, -29, -38, -37, -27, -14, -9, -6, 11,
- 36, 51, 47, 42, 34, 24, 14, -3, -20, -25, -23, -22, -26, -37, -42, -33,
- -17, -8, -7, 4, 28, 50, 54, 45, 35, 24, 15, 3, -16, -24, -25, -22,
- -23, -32, -41, -37, -22, -11, -8, 0, 21, 44, 54, 46, 34, 26, 18, 7,
- -11, -22, -21, -20, -21, -28, -40, -43, -30, -15, -10, -3, 16, 40, 56, 52,
- 37, 24, 16, 9, -6, -21, -22, -18, -17, -22, -35, -43, -34, -21, -14, -9,
- 7, 34, 53, 54, 40, 29, 21, 14, 4, -14, -21, -17, -17, -22, -33, -46,
- -45, -31, -16, -8, 4, 25, 50, 60, 49, 31, 20, 15, 9, -5, -17, -18,
- -15, -17, -26, -42, -50, -40, -24, -11, -2, 18, 43, 56, 52, 35, 21, 17,
- 11, 0, -12, -18, -14, -15, -22, -36, -50, -46, -30, -15, -3, 12, 35, 53,
- 55, 41, 24, 18, 12, 5, -4, -15, -18, -15, -20, -33, -46, -49, -37, -21,
- -7, 7, 25, 46, 54, 45, 27, 18, 14, 10, 3, -8, -15, -16, -18, -28,
- -41, -49, -44, -29, -12, 4, 17, 35, 49, 49, 34, 19, 16, 15, 9, 1,
- -10, -14, -16, -24, -38, -50, -49, -36, -18, -3, 10, 26, 43, 49, 38, 22,
- 18, 20, 16, 9, -5, -13, -16, -23, -36, -50, -53, -43, -25, -8, 6, 21,
- 38, 48, 44, 27, 19, 21, 19, 13, -2, -13, -17, -21, -30, -45, -52, -46,
- -29, -10, 3, 14, 29, 42, 44, 30, 17, 19, 21, 17, 6, -8, -14, -19,
- -26, -39, -49, -48, -36, -18, -2, 11, 27, 37, 42, 37, 22, 18, 21, 19,
- 9, -5, -13, -18, -24, -33, -45, -46, -39, -24, -8, 6, 20, 33, 40, 38,
- 27, 19, 22, 23, 17, 4, -8, -14, -22, -29, -43, -48, -43, -32, -16, -2,
- 13, 25, 34, 39, 33, 23, 21, 23, 20, 9, -4, -11, -19, -25, -33, -43,
- -42, -34, -20, -7, 3, 14, 24, 32, 31, 22, 20, 26, 28, 20, 6, -5,
- -11, -18, -28, -42, -44, -38, -28, -15, -5, 8, 19, 28, 31, 24, 21, 25,
- 27, 22, 10, 0, -6, -12, -22, -34, -38, -34, -30, -20, -11, 0, 11, 20,
- 26, 23, 19, 22, 27, 25, 17, 7, -2, -7, -17, -29, -35, -35, -34, -26,
- -16, -5, 7, 15, 23, 28, 24, 21, 22, 24, 20, 11, -2, -8, -14, -24,
- -29, -31, -31, -27, -18, -9, 0, 8, 15, 22, 23, 20, 21, 24, 24, 19,
- 7, -4, -10, -19, -26, -32, -34, -33, -24, -12, -2, 6, 14, 22, 26, 23,
- 22, 22, 22, 21, 10, 0, -6, -15, -21, -24, -28, -31, -28, -17, -7, 2,
- 7, 13, 19, 23, 23, 21, 19, 21, 18, 8, -2, -11, -17, -21, -24, -30,
- -33, -25, -11, 0, 4, 9, 16, 20, 21, 20, 18, 18, 20, 14, 4, -6,
- -12, -15, -17, -25, -32, -32, -20, -6, -3, -3, 7, 18, 23, 19, 16, 19,
- 26, 24, 11, 0, -6, -9, -15, -25, -33, -35, -26, -15, -9, -6, 5, 17,
- 22, 21, 17, 18, 25, 26, 16, 4, -5, -7, -9, -18, -29, -38, -35, -21,
- -11, -9, -4, 9, 22, 25, 20, 16, 22, 30, 24, 8, -4, -5, -5, -13,
- -25, -36, -38, -26, -16, -11, -10, 2, 19, 25, 18, 12, 19, 30, 28, 14,
- 1, -2, 3, -3, -17, -31, -36, -29, -21, -18, -19, -11, 7, 20, 16, 10,
- 16, 30, 36, 24, 8, 4, 8, 6, -12, -32, -40, -35, -26, -21, -20, -14,
- 2, 19, 20, 10, 12, 24, 35, 29, 13, 5, 7, 9, -3, -23, -37, -37,
- -31, -23, -21, -19, -8, 12, 19, 10, 6, 19, 36, 37, 23, 11, 12, 16,
- 7, -15, -35, -43, -38, -30, -27, -23, -16, 2, 18, 16, 7, 13, 30, 38,
- 29, 17, 12, 16, 15, -4, -27, -40, -39, -32, -28, -28, -24, -8, 12, 14,
- 5, 7, 26, 40, 36, 24, 18, 21, 21, 4, -20, -38, -41, -37, -34, -30,
- -26, -15, 4, 14, 7, 3, 18, 37, 41, 33, 24, 22, 25, 14, -10, -33,
- -44, -42, -36, -32, -29, -22, -6, 10, 9, 2, 9, 29, 40, 37, 32, 28,
- 29, 21, 0, -24, -39, -44, -44, -38, -31, -24, -16, 0, 7, 3, 8, 24,
- 38, 43, 41, 32, 28, 25, 9, -15, -34, -44, -44, -39, -31, -26, -20, -10,
- 3, 2, 1, 14, 32, 44, 46, 39, 33, 31, 20, -7, -31, -45, -47, -44,
- -38, -30, -26, -16, 0, 5, 4, 12, 30, 45, 52, 47, 36, 30, 22, 0,
- -24, -40, -50, -49, -42, -31, -24, -19, -10, -3, 3, 11, 24, 39, 51, 55,
- 49, 37, 27, 8, -18, -36, -50, -54, -47, -36, -29, -25, -16, -6, 4, 10,
- 18, 34, 52, 59, 53, 39, 28, 15, -8, -29, -45, -53, -51, -43, -34, -29,
- -23, -14, -4, 7, 17, 33, 52, 62, 61, 50, 37, 23, -4, -28, -44, -55,
- -55, -48, -38, -30, -25, -18, -8, 5, 13, 25, 46, 61, 65, 57, 43, 30,
- 8, -17, -36, -50, -55, -53, -47, -39, -32, -24, -15, -3, 11, 25, 45, 62,
- 68, 63, 51, 37, 14, -14, -34, -46, -56, -57, -51, -44, -33, -25, -18, -6,
- 8, 19, 36, 55, 67, 65, 53, 42, 23, -4, -26, -40, -50, -56, -54, -49,
- -41, -31, -23, -12, 1, 15, 34, 53, 65, 68, 59, 49, 33, 6, -21, -37,
- -47, -57, -60, -56, -48, -38, -28, -16, -2, 14, 33, 51, 64, 70, 63, 53,
- 38, 13, -14, -34, -44, -53, -59, -59, -53, -42, -30, -19, -8, 5, 26, 47,
- 61, 68, 64, 57, 48, 26, -3, -26, -39, -49, -58, -63, -59, -49, -37, -24,
- -13, 1, 20, 42, 55, 65, 69, 64, 54, 34, 7, -18, -34, -44, -55, -65,
- -64, -54, -42, -31, -19, -8, 12, 37, 54, 61, 67, 67, 60, 46, 22, -8,
- -29, -40, -50, -64, -70, -63, -50, -34, -21, -13, 2, 28, 51, 62, 68, 68,
- 61, 51, 32, 3, -23, -36, -47, -60, -70, -67, -58, -44, -27, -14, -2, 22,
- 45, 58, 65, 70, 68, 56, 38, 16, -11, -32, -45, -58, -69, -70, -62, -52,
- -34, -17, -6, 13, 38, 54, 64, 70, 67, 59, 47, 29, -2, -28, -40, -51,
- -65, -74, -67, -54, -37, -20, -11, 5, 33, 53, 59, 63, 67, 62, 51, 34,
- 7, -20, -35, -46, -59, -72, -70, -60, -46, -27, -12, 1, 24, 47, 60, 64,
- 69, 66, 54, 39, 15, -13, -32, -44, -54, -68, -71, -60, -48, -32, -18, -7,
- 14, 38, 54, 61, 68, 70, 60, 46, 26, -2, -23, -38, -50, -63, -72, -68,
- -55, -39, -24, -13, 5, 31, 52, 61, 67, 71, 64, 53, 34, 7, -21, -36,
- -46, -57, -69, -72, -60, -42, -27, -17, -2, 21, 45, 58, 65, 69, 66, 57,
- 42, 15, -13, -30, -43, -54, -66, -72, -65, -47, -30, -18, -5, 15, 40, 57,
- 64, 67, 62, 56, 46, 23, -6, -27, -39, -50, -58, -67, -67, -51, -32, -20,
- -9, 9, 31, 51, 60, 64, 64, 58, 48, 27, 1, -20, -34, -46, -56, -65,
- -70, -57, -37, -22, -14, 2, 26, 48, 62, 66, 64, 59, 51, 34, 8, -18,
- -31, -42, -52, -61, -70, -63, -42, -24, -15, -3, 19, 43, 60, 63, 60, 57,
- 52, 39, 14, -14, -28, -36, -46, -54, -65, -66, -49, -29, -17, -9, 10, 33,
- 54, 64, 62, 58, 53, 42, 23, -5, -25, -35, -46, -54, -63, -67, -54, -33,
- -17, -7, 7, 30, 51, 61, 58, 55, 51, 43, 28, 3, -21, -30, -37, -46,
- -56, -63, -56, -39, -22, -12, -5, 16, 40, 57, 58, 55, 53, 48, 38, 19,
- -10, -27, -35, -45, -56, -66, -65, -49, -28, -14, -6, 8, 34, 57, 60, 55,
- 54, 50, 42, 26, -4, -28, -35, -42, -52, -62, -63, -51, -32, -14, -5, 3,
- 24, 47, 57, 53, 50, 47, 41, 33, 11, -20, -35, -40, -46, -56, -65, -58,
- -38, -17, -4, 1, 15, 41, 57, 55, 47, 45, 42, 35, 17, -13, -33, -38,
- -41, -49, -58, -55, -41, -21, -4, 0, 7, 29, 50, 52, 45, 42, 40, 37,
- 25, 0, -28, -38, -38, -44, -53, -58, -46, -26, -6, 3, 4, 18, 42, 53,
- 47, 41, 39, 37, 30, 10, -21, -41, -43, -41, -47, -54, -46, -29, -8, 7,
- 9, 13, 31, 46, 45, 37, 33, 33, 28, 15, -10, -35, -42, -38, -39, -45,
- -46, -32, -10, 6, 9, 8, 19, 38, 44, 38, 30, 29, 30, 19, -3, -29,
- -42, -38, -34, -40, -43, -32, -14, 3, 11, 11, 15, 30, 41, 39, 30, 25,
- 25, 19, 4, -21, -40, -42, -32, -30, -33, -29, -15, 2, 11, 10, 8, 17,
- 30, 35, 30, 23, 24, 23, 11, -11, -32, -43, -34, -26, -29, -29, -18, -3,
- 9, 12, 9, 12, 26, 35, 32, 21, 18, 18, 12, -6, -29, -43, -36, -22,
- -22, -25, -15, 1, 10, 11, 10, 8, 17, 29, 29, 21, 16, 17, 15, 2,
- -21, -39, -39, -24, -17, -20, -16, -5, 9, 13, 10, 7, 12, 24, 28, 23,
- 14, 12, 11, 4, -14, -33, -39, -28, -15, -14, -12, -6, 5, 11, 9, 7,
- 7, 16, 26, 25, 16, 10, 11, 6, -8, -24, -37, -32, -17, -12, -11, -5,
- 5, 11, 11, 10, 7, 12, 21, 21, 16, 7, 4, 3, -6, -20, -32, -32,
- -20, -8, -5, 0, 5, 11, 11, 9, 8, 8, 13, 17, 16, 9, 3, 2,
- -3, -13, -25, -31, -23, -9, -4, -2, 5, 11, 14, 11, 7, 6, 12, 15,
- 12, 5, -2, -2, -3, -11, -22, -29, -24, -9, 0, 3, 8, 13, 13, 12,
- 8, 4, 5, 7, 9, 6, -3, -5, -4, -5, -14, -24, -23, -13, 0, 4,
- 6, 10, 14, 14, 9, 3, 3, 5, 6, 4, -4, -6, -5, -5, -9, -18,
- -20, -15, -4, 6, 9, 11, 13, 13, 10, 5, 1, 0, -3, 0, -4, -6,
- -6, -5, -4, -11, -16, -16, -9, 3, 8, 11, 11, 10, 11, 8, 3, -2,
- -5, -4, -3, -5, -6, -6, -2, -5, -12, -15, -13, -2, 8, 9, 11, 11,
- 11, 7, 4, 0, -6, -6, -4, -4, -6, -6, -2, 0, -7, -13, -15, -5,
- 8, 13, 12, 9, 11, 9, 4, -5, -11, -11, -8, -5, -5, -5, 0, 4,
- 3, -4, -11, -8, 3, 11, 12, 8, 7, 4, 2, -2, -10, -14, -13, -7,
- -3, -4, -2, 3, 4, 1, -8, -8, 3, 13, 17, 12, 11, 7, 1, -6,
- -16, -21, -19, -13, -7, -2, 3, 7, 10, 10, 1, -6, -2, 8, 14, 12,
- 10, 4, -2, -6, -15, -21, -20, -15, -8, -2, 3, 5, 9, 14, 5, -6,
- 1, 12, 18, 14, 9, 7, 2, -4, -18, -28, -27, -22, -12, -5, 3, 9,
- 13, 18, 16, 5, 1, 7, 14, 13, 8, 5, -5, -9, -17, -26, -26, -23,
- -15, -4, 5, 8, 11, 17, 17, 7, 2, 7, 16, 18, 10, 4, -2, -6,
- -16, -31, -33, -27, -18, -9, 0, 7, 12, 18, 22, 16, 9, 9, 16, 20,
- 13, 5, -2, -9, -18, -33, -37, -29, -22, -13, -4, 7, 15, 21, 25, 21,
- 15, 13, 17, 20, 14, 5, -3, -8, -18, -35, -42, -36, -24, -16, -6, 5,
- 13, 23, 27, 25, 20, 17, 19, 20, 15, 5, -3, -8, -21, -35, -45, -39,
- -25, -18, -11, 3, 16, 25, 29, 27, 26, 24, 23, 21, 17, 8, -4, -12,
- -23, -35, -46, -46, -34, -22, -15, -3, 13, 25, 31, 33, 34, 31, 28, 25,
- 20, 11, -4, -12, -22, -38, -49, -51, -39, -26, -21, -11, 8, 24, 34, 35,
- 36, 37, 35, 29, 21, 13, 0, -11, -20, -36, -48, -52, -46, -31, -22, -14,
- 1, 19, 34, 38, 39, 40, 38, 34, 24, 15, 0, -14, -21, -34, -47, -53,
- -50, -35, -22, -17, -5, 13, 31, 37, 38, 42, 41, 37, 28, 21, 9, -8,
- -19, -30, -44, -50, -53, -46, -32, -23, -11, 7, 26, 39, 43, 49, 48, 42,
- 32, 20, 9, -9, -21, -31, -46, -52, -54, -50, -35, -24, -13, 4, 23, 40,
- 46, 48, 49, 46, 37, 26, 13, -4, -20, -29, -42, -50, -53, -54, -43, -31,
- -21, -2, 17, 36, 47, 53, 56, 51, 42, 29, 17, 3, -16, -30, -41, -51,
- -55, -57, -51, -35, -24, -9, 11, 30, 47, 53, 57, 55, 46, 34, 20, 6,
- -12, -29, -43, -52, -55, -55, -55, -42, -29, -12, 8, 25, 41, 55, 62, 59,
- 51, 37, 23, 10, -6, -24, -40, -51, -56, -58, -58, -48, -33, -19, 2, 22,
- 41, 55, 61, 61, 56, 45, 28, 11, -3, -19, -37, -51, -57, -58, -58, -54,
- -39, -23, -2, 20, 36, 52, 64, 65, 58, 48, 33, 19, 4, -13, -35, -51,
- -58, -61, -62, -60, -47, -29, -7, 17, 34, 50, 67, 70, 62, 50, 35, 20,
- 6, -8, -29, -47, -57, -62, -61, -60, -54, -37, -15, 10, 29, 44, 60, 68,
- 66, 56, 42, 24, 12, 1, -19, -41, -55, -60, -62, -61, -57, -43, -21, 7,
- 24, 36, 53, 66, 67, 59, 46, 30, 15, 5, -11, -32, -48, -58, -63, -62,
- -59, -50, -32, -3, 22, 35, 49, 60, 66, 63, 53, 38, 19, 8, -5, -25,
- -43, -57, -64, -64, -62, -54, -39, -13, 16, 32, 46, 59, 65, 66, 56, 45,
- 26, 11, 3, -17, -39, -56, -65, -67, -62, -56, -44, -21, 10, 29, 40, 54,
- 63, 68, 61, 49, 33, 13, 2, -14, -34, -50, -64, -67, -63, -56, -44, -26,
- 2, 27, 38, 49, 57, 64, 61, 50, 36, 17, 6, -7, -27, -44, -60, -67,
- -63, -57, -48, -32, -7, 22, 36, 44, 53, 60, 62, 55, 41, 21, 7, -3,
- -20, -40, -58, -68, -65, -57, -47, -34, -14, 16, 37, 42, 47, 55, 59, 53,
- 42, 27, 10, -2, -14, -30, -47, -60, -63, -57, -49, -38, -20, 5, 30, 40,
- 44, 52, 57, 57, 46, 31, 13, -2, -12, -27, -44, -57, -64, -61, -50, -38,
- -20, 2, 25, 39, 41, 49, 55, 54, 45, 32, 17, 0, -12, -23, -37, -50,
- -59, -61, -52, -38, -22, -6, 17, 35, 39, 42, 48, 53, 48, 36, 22, 4,
- -9, -18, -30, -45, -56, -59, -54, -42, -27, -10, 12, 29, 37, 38, 44, 50,
- 47, 37, 25, 9, -5, -13, -23, -38, -50, -55, -54, -45, -32, -17, 5, 25,
- 34, 35, 39, 46, 48, 40, 29, 13, -3, -11, -21, -33, -44, -51, -54, -47,
- -34, -17, 2, 21, 32, 34, 34, 38, 42, 39, 27, 15, 1, -7, -13, -25,
- -36, -45, -49, -46, -36, -23, -6, 15, 27, 31, 31, 34, 39, 38, 30, 18,
- 3, -6, -10, -19, -32, -40, -46, -45, -36, -24, -11, 8, 24, 29, 27, 29,
- 34, 36, 30, 18, 4, -5, -5, -12, -25, -34, -39, -41, -37, -24, -11, 4,
- 18, 24, 25, 25, 29, 29, 26, 19, 5, -6, -6, -6, -18, -28, -33, -37,
- -34, -24, -11, 2, 15, 24, 23, 20, 24, 27, 22, 14, 4, -4, -4, -5,
- -15, -24, -26, -29, -32, -27, -13, 2, 14, 21, 21, 18, 21, 23, 20, 13,
- 5, -3, -5, -4, -9, -16, -21, -25, -28, -25, -14, 1, 10, 16, 19, 16,
- 16, 18, 16, 11, 5, -2, -5, -4, -6, -12, -17, -20, -22, -22, -17, -4,
- 8, 13, 16, 15, 13, 15, 14, 10, 4, -4, -6, -6, -5, -7, -11, -15,
- -17, -17, -15, -3, 10, 13, 14, 11, 7, 8, 9, 5, -3, -8, -7, -4,
- -2, -2, -6, -10, -9, -10, -12, -5, 11, 15, 13, 11, 5, 6, 7, 3,
- -6, -10, -8, -6, -6, -2, 1, -2, -6, -6, -7, -5, 8, 14, 10, 7,
- 4, 0, 1, -2, -6, -12, -11, -6, -2, 4, 8, 4, -2, -2, -4, -5,
- 3, 12, 8, 5, 4, 0, 0, -2, -8, -13, -15, -12, -7, -3, 6, 10,
- 7, 5, 6, 4, 6, 14, 10, 3, 0, -6, -10, -7, -10, -16, -19, -15,
- -8, 0, 11, 17, 13, 10, 11, 7, 5, 8, 9, 2, -4, -7, -12, -10,
- -10, -16, -21, -19, -13, -4, 10, 21, 22, 17, 17, 14, 9, 9, 9, 3,
- -7, -12, -17, -16, -14, -20, -25, -21, -15, -5, 10, 23, 27, 25, 22, 18,
- 11, 8, 4, -2, -9, -14, -18, -19, -14, -15, -23, -25, -20, -10, 9, 22,
- 29, 29, 26, 23, 16, 12, 6, 1, -6, -14, -18, -22, -20, -19, -27, -28,
- -25, -18, 0, 19, 32, 36, 33, 31, 23, 14, 7, 1, -4, -15, -23, -25,
- -24, -19, -25, -32, -29, -20, -3, 16, 31, 40, 38, 36, 29, 16, 9, 1,
- -4, -12, -23, -26, -28, -24, -26, -34, -33, -24, -8, 12, 29, 41, 44, 44,
- 37, 22, 11, 4, -4, -11, -24, -31, -32, -31, -30, -36, -39, -30, -11, 11,
- 29, 43, 51, 50, 44, 32, 15, 4, -4, -11, -24, -32, -33, -33, -34, -38,
- -42, -35, -17, 4, 24, 42, 56, 60, 52, 38, 19, 7, 1, -13, -28, -37,
- -37, -35, -37, -39, -43, -37, -19, 3, 22, 41, 57, 64, 57, 44, 26, 7,
- -2, -11, -24, -35, -41, -40, -38, -39, -43, -40, -24, 0, 20, 37, 55, 65,
- 63, 50, 32, 9, -4, -10, -24, -36, -42, -42, -41, -41, -41, -39, -26, -2,
- 19, 34, 51, 64, 66, 55, 38, 15, -3, -8, -20, -34, -42, -44, -43, -44,
- -45, -45, -35, -12, 14, 31, 50, 66, 73, 65, 49, 28, 7, -6, -18, -35,
- -45, -49, -51, -53, -51, -47, -37, -16, 10, 30, 49, 69, 78, 72, 56, 35,
- 14, -4, -17, -33, -46, -51, -55, -56, -54, -51, -40, -20, 5, 26, 44, 64,
- 76, 77, 64, 41, 19, 1, -14, -30, -43, -50, -57, -60, -58, -54, -43, -24,
- -2, 21, 39, 61, 76, 79, 72, 52, 28, 9, -10, -26, -41, -49, -54, -61,
- -62, -59, -51, -33, -10, 14, 34, 55, 75, 81, 79, 63, 39, 19, -2, -23,
- -40, -51, -56, -64, -67, -64, -56, -39, -16, 9, 29, 51, 73, 83, 82, 73,
- 50, 27, 9, -18, -40, -52, -56, -63, -69, -69, -61, -43, -20, 2, 21, 42,
- 66, 81, 82, 76, 59, 36, 19, -6, -33, -50, -57, -61, -71, -76, -68, -52,
- -28, -2, 17, 36, 62, 83, 86, 82, 69, 43, 22, 2, -28, -51, -60, -63,
- -67, -76, -74, -57, -34, -7, 14, 29, 53, 76, 87, 84, 75, 54, 33, 14,
- -18, -46, -58, -62, -69, -80, -84, -68, -44, -18, 7, 26, 49, 75, 91, 92,
- 82, 64, 42, 21, -8, -43, -63, -68, -68, -75, -86, -76, -48, -22, 4, 23,
- 41, 66, 87, 92, 83, 69, 51, 31, 6, -31, -59, -67, -69, -74, -88, -87,
- -62, -34, -7, 17, 36, 62, 87, 96, 90, 76, 60, 39, 14, -23, -58, -70,
- -71, -73, -83, -89, -68, -37, -13, 9, 26, 51, 79, 94, 91, 80, 68, 52,
- 28, -8, -48, -67, -70, -73, -84, -96, -83, -49, -22, 0, 20, 44, 75, 96,
- 98, 88, 75, 61, 40, 6, -39, -67, -72, -75, -83, -95, -91, -60, -29, -7,
- 13, 36, 66, 89, 97, 92, 78, 65, 50, 22, -21, -58, -71, -73, -78, -91,
- -98, -79, -45, -15, 4, 25, 56, 84, 101, 99, 86, 73, 60, 35, -9, -53,
- -72, -77, -80, -90, -98, -85, -51, -20, -2, 18, 48, 77, 96, 99, 87, 75,
- 62, 46, 9, -39, -68, -75, -75, -83, -95, -94, -67, -30, -7, 8, 34, 68,
- 92, 102, 93, 82, 72, 58, 26, -24, -61, -75, -78, -85, -97, -99, -78, -42,
- -12, 6, 28, 59, 87, 102, 99, 86, 74, 62, 38, -7, -52, -76, -81, -83,
- -93, -100, -90, -57, -23, -2, 18, 48, 80, 102, 103, 92, 81, 71, 51, 9,
- -41, -72, -83, -85, -93, -100, -92, -65, -32, -7, 13, 39, 72, 97, 103, 95,
- 85, 73, 55, 25, -21, -61, -79, -83, -90, -99, -97, -77, -45, -17, 1, 24,
- 59, 93, 107, 103, 92, 85, 72, 42, -6, -54, -80, -86, -91, -104, -105, -87,
- -56, -23, 0, 18, 48, 85, 106, 106, 96, 87, 77, 52, 13, -35, -71, -84,
- -88, -98, -106, -96, -70, -40, -14, 6, 31, 70, 103, 111, 103, 95, 88, 68,
- 29, -19, -61, -84, -91, -99, -106, -101, -80, -51, -22, 2, 23, 56, 91, 109,
- 108, 98, 89, 76, 45, 1, -44, -76, -87, -92, -102, -104, -90, -64, -34, -11,
- 8, 37, 78, 108, 113, 106, 96, 85, 61, 19, -29, -68, -88, -94, -102, -104,
- -93, -73, -46, -21, 2, 28, 63, 98, 113, 109, 100, 89, 70, 33, -14, -55,
- -81, -91, -98, -104, -98, -79, -54, -30, -9, 18, 52, 89, 108, 110, 104, 96,
- 79, 46, 2, -40, -71, -90, -100, -104, -100, -86, -67, -44, -19, 7, 40, 77,
- 105, 115, 109, 99, 86, 58, 17, -29, -63, -86, -97, -101, -101, -92, -74, -50,
- -26, -4, 28, 66, 98, 114, 113, 102, 90, 68, 33, -15, -53, -76, -93, -101,
- -104, -96, -79, -57, -34, -15, 15, 56, 90, 110, 115, 105, 93, 75, 44, 0,
- -43, -68, -86, -98, -101, -98, -83, -65, -42, -22, 4, 41, 79, 104, 113, 107,
- 96, 81, 57, 16, -31, -59, -79, -95, -101, -100, -90, -71, -49, -30, -9, 28,
- 67, 97, 110, 107, 97, 86, 65, 30, -14, -47, -67, -84, -98, -102, -96, -79,
- -59, -41, -22, 14, 53, 90, 110, 111, 101, 90, 75, 45, 2, -39, -64, -79,
- -93, -102, -101, -87, -64, -44, -28, 0, 39, 81, 108, 110, 102, 93, 82, 58,
- 18, -25, -54, -70, -85, -101, -103, -94, -72, -53, -39, -14, 25, 70, 104, 112,
- 103, 96, 88, 70, 34, -13, -48, -65, -78, -97, -108, -101, -79, -55, -42, -24,
- 11, 56, 96, 111, 103, 94, 90, 77, 46, 5, -34, -56, -71, -92, -109, -109,
- -91, -64, -46, -30, 0, 44, 89, 112, 108, 95, 88, 80, 57, 16, -27, -54,
- -66, -82, -104, -112, -100, -71, -46, -34, -13, 29, 80, 111, 112, 97, 86, 84,
- 69, 32, -15, -48, -61, -72, -94, -109, -106, -82, -54, -37, -23, 11, 61, 101,
- 113, 101, 85, 80, 75, 48, 4, -37, -56, -64, -84, -107, -112, -90, -60, -37,
- -29, -7, 43, 91, 111, 103, 86, 80, 77, 58, 20, -24, -52, -61, -75, -100,
- -111, -99, -72, -44, -27, -12, 29, 77, 105, 106, 91, 80, 75, 64, 33, -9,
- -43, -58, -69, -94, -111, -104, -78, -49, -28, -18, 11, 62, 97, 107, 94, 80,
- 75, 69, 47, 6, -36, -55, -62, -81, -105, -108, -87, -59, -33, -18, 1, 46,
- 86, 103, 97, 83, 75, 69, 52, 19, -23, -50, -59, -74, -97, -106, -91, -64,
- -38, -21, -9, 26, 70, 95, 95, 80, 71, 69, 60, 35, -6, -40, -53, -64,
- -87, -102, -96, -72, -45, -25, -14, 13, 56, 87, 95, 86, 75, 69, 60, 41,
- 6, -32, -54, -62, -77, -95, -99, -79, -51, -23, -8, 6, 39, 75, 92, 87,
- 72, 64, 62, 49, 21, -17, -47, -57, -67, -86, -97, -87, -59, -32, -16, -4,
- 25, 63, 89, 92, 78, 67, 63, 53, 27, -10, -40, -55, -63, -78, -93, -89,
- -65, -36, -17, -7, 11, 44, 77, 89, 79, 65, 61, 58, 41, 8, -26, -50,
- -59, -67, -83, -90, -76, -47, -25, -13, 3, 30, 63, 85, 82, 70, 63, 58,
- 45, 14, -18, -43, -56, -63, -74, -84, -78, -52, -26, -13, -2, 19, 46, 73,
- 81, 68, 57, 55, 49, 27, -5, -32, -48, -54, -63, -77, -80, -60, -34, -17,
- -5, 10, 34, 62, 79, 71, 57, 52, 48, 31, 2, -26, -45, -50, -53, -65,
- -75, -63, -37, -16, -6, 4, 19, 45, 68, 70, 57, 49, 49, 39, 16, -11,
- -33, -45, -49, -56, -70, -71, -51, -26, -8, 2, 13, 35, 63, 76, 63, 48,
- 43, 38, 23, -7, -32, -45, -47, -47, -58, -67, -55, -30, -8, 0, 4, 20,
- 46, 68, 65, 47, 38, 38, 31, 8, -19, -37, -44, -42, -48, -63, -62, -41,
- -16, -2, 5, 16, 37, 61, 68, 53, 38, 34, 31, 14, -14, -33, -40, -38,
- -41, -54, -60, -46, -20, -5, -3, 6, 25, 49, 63, 55, 38, 32, 33, 24,
- 1, -23, -34, -35, -36, -45, -59, -55, -30, -9, -3, 2, 16, 39, 59, 59,
- 44, 32, 30, 26, 7, -20, -33, -33, -32, -40, -53, -54, -35, -12, -3, -2,
- 10, 29, 48, 55, 45, 32, 28, 27, 14, -10, -27, -30, -28, -34, -46, -53,
- -41, -17, -5, -5, 5, 24, 44, 54, 46, 32, 25, 25, 18, -4, -25, -31,
- -24, -27, -39, -47, -42, -21, -4, -2, 1, 15, 35, 46, 44, 31, 22, 23,
- 20, 6, -15, -26, -23, -20, -29, -41, -42, -29, -11, -4, -4, 7, 26, 42,
- 47, 37, 25, 21, 19, 9, -10, -25, -25, -18, -24, -38, -40, -29, -11, 1,
- 0, 3, 19, 34, 42, 33, 19, 14, 15, 10, -5, -21, -24, -15, -13, -26,
- -35, -31, -17, -2, 0, -2, 11, 26, 37, 34, 20, 14, 13, 12, 2, -17,
- -25, -17, -12, -21, -31, -30, -19, -4, 4, 1, 9, 22, 32, 32, 19, 9,
- 9, 10, 4, -11, -21, -16, -9, -14, -23, -26, -20, -8, 0, -2, 3, 15,
- 26, 31, 24, 12, 9, 10, 6, -5, -17, -19, -12, -11, -18, -25, -22, -10,
- 1, 2, 2, 11, 22, 29, 24, 10, 3, 5, 4, -4, -13, -15, -8, -5,
- -10, -16, -18, -14, -5, -2, 0, 6, 13, 20, 23, 16, 6, 5, 5, 0,
- -7, -12, -12, -8, -7, -12, -19, -18, -7, 0, 2, 7, 13, 18, 20, 13,
- 3, -2, 1, -2, -6, -8, -6, -3, -2, -2, -10, -14, -10, -6, -4, 0,
- 4, 9, 14, 15, 6, -2, -2, -2, -4, -4, -5, -3, 2, 3, -3, -10,
- -9, -5, 0, 0, 0, 3, 8, 10, 3, -5, -7, -6, -4, 0, -2, -2,
- 3, 7, 7, 2, -5, -6, -3, 2, 2, 0, 0, 2, 2, -4, -9, -9,
- -7, -3, 2, 4, 8, 9, 6, 2, -3, -4, -3, -2, -2, -2, 0, 1,
- -3, -8, -11, -8, -6, -4, 2, 6, 9, 10, 9, 8, 5, -4, -7, -3,
- 1, 1, -6, -7, -6, -6, -11, -14, -10, -5, 3, 9, 12, 14, 13, 10,
- 9, 1, -6, -5, -4, -3, -4, -6, -8, -12, -12, -13, -13, -11, -3, 9,
- 16, 18, 15, 13, 14, 11, -2, -6, -4, -3, -5, -11, -13, -12, -14, -15,
- -14, -10, -4, 6, 15, 22, 21, 16, 13, 12, 3, -7, -8, -7, -7, -10,
- -14, -17, -16, -13, -12, -10, -7, 3, 15, 24, 26, 19, 16, 18, 12, -3,
- -9, -10, -9, -11, -18, -22, -21, -17, -14, -14, -10, 0, 14, 26, 32, 28,
- 23, 22, 21, 5, -9, -12, -16, -18, -22, -27, -27, -23, -17, -13, -8, 2,
- 12, 25, 35, 36, 29, 21, 20, 11, -6, -14, -17, -19, -22, -27, -28, -24,
- -20, -15, -11, -4, 7, 19, 32, 39, 35, 28, 25, 19, 4, -10, -17, -24,
- -28, -31, -33, -30, -26, -19, -11, -3, 8, 19, 31, 42, 42, 34, 27, 21,
- 9, -9, -19, -26, -31, -35, -34, -30, -26, -23, -13, -4, 4, 14, 25, 42,
- 49, 41, 31, 27, 20, 3, -15, -28, -37, -38, -39, -38, -35, -29, -16, 0,
- 9, 17, 26, 41, 52, 48, 36, 26, 19, 6, -16, -30, -39, -43, -41, -39,
- -33, -29, -22, -5, 7, 13, 21, 36, 55, 56, 46, 34, 24, 15, -8, -29,
- -44, -54, -50, -44, -39, -35, -27, -7, 11, 20, 25, 34, 54, 63, 53, 38,
- 22, 14, 0, -27, -45, -56, -56, -46, -39, -36, -31, -14, 8, 19, 23, 29,
- 46, 63, 61, 47, 30, 20, 8, -15, -39, -56, -62, -54, -44, -41, -38, -23,
- -2, 16, 23, 28, 42, 63, 69, 58, 41, 25, 13, -7, -34, -56, -68, -64,
- -50, -45, -43, -29, -7, 15, 26, 29, 40, 58, 72, 67, 48, 30, 16, 0,
- -26, -53, -68, -69, -57, -47, -46, -36, -16, 9, 25, 30, 38, 53, 71, 74,
- 58, 37, 17, 2, -21, -49, -70, -76, -64, -49, -43, -38, -21, 3, 25, 33,
- 37, 49, 65, 74, 65, 45, 24, 8, -11, -40, -68, -79, -72, -57, -48, -42,
- -29, -6, 20, 34, 39, 48, 63, 77, 74, 56, 31, 11, -8, -33, -61, -79,
- -80, -68, -53, -45, -34, -16, 11, 31, 41, 51, 61, 75, 78, 64, 42, 19,
- -3, -27, -55, -78, -84, -73, -59, -48, -37, -20, 5, 27, 40, 49, 58, 71,
- 80, 71, 49, 23, 2, -20, -47, -72, -86, -82, -66, -52, -39, -26, -5, 20,
- 39, 51, 59, 69, 79, 77, 61, 34, 7, -16, -42, -68, -88, -90, -75, -58,
- -41, -26, -8, 17, 39, 52, 59, 65, 74, 77, 65, 41, 12, -12, -35, -60,
- -81, -89, -79, -60, -45, -33, -17, 6, 31, 49, 59, 64, 73, 80, 74, 51,
- 22, -5, -29, -54, -78, -92, -90, -70, -49, -35, -18, 3, 26, 48, 60, 64,
- 68, 75, 75, 58, 31, 1, -25, -48, -73, -88, -90, -77, -56, -41, -23, -3,
- 21, 43, 58, 64, 70, 75, 77, 64, 40, 12, -18, -44, -70, -87, -94, -87,
- -64, -42, -22, -4, 16, 39, 58, 65, 66, 67, 74, 68, 46, 18, -12, -38,
- -62, -82, -92, -89, -67, -45, -28, -9, 13, 31, 52, 64, 67, 66, 72, 71,
- 53, 29, -3, -34, -59, -79, -94, -96, -77, -50, -29, -8, 12, 30, 49, 63,
- 68, 67, 68, 70, 56, 34, 6, -29, -57, -77, -92, -99, -84, -56, -32, -10,
- 11, 29, 45, 61, 69, 69, 68, 70, 60, 37, 12, -20, -50, -73, -90, -100,
- -91, -64, -37, -14, 7, 25, 42, 57, 66, 67, 65, 67, 64, 45, 21, -9,
- -41, -66, -84, -98, -95, -74, -47, -21, 3, 23, 39, 54, 64, 69, 69, 67,
- 63, 50, 27, 0, -33, -63, -83, -94, -95, -79, -54, -26, -2, 18, 35, 49,
- 61, 67, 67, 65, 64, 55, 33, 6, -25, -55, -82, -95, -98, -84, -60, -32,
- -6, 17, 36, 48, 56, 64, 66, 65, 62, 55, 39, 14, -16, -46, -76, -92,
- -96, -88, -69, -41, -9, 15, 33, 46, 54, 62, 68, 66, 59, 54, 44, 20,
- -12, -41, -72, -92, -97, -90, -71, -46, -14, 15, 34, 48, 55, 59, 62, 63,
- 60, 51, 42, 24, -6, -34, -63, -87, -95, -89, -75, -52, -23, 10, 31, 45,
- 54, 58, 62, 66, 63, 51, 42, 30, 1, -32, -59, -84, -96, -93, -80, -58,
- -28, 7, 32, 45, 53, 60, 64, 67, 62, 52, 41, 31, 9, -25, -55, -78,
- -92, -91, -82, -65, -39, -2, 30, 43, 49, 56, 61, 65, 63, 54, 44, 33,
- 16, -15, -47, -72, -88, -91, -84, -70, -45, -12, 22, 42, 48, 54, 58, 61,
- 63, 56, 43, 32, 20, -4, -36, -65, -82, -87, -82, -72, -53, -23, 15, 40,
- 46, 48, 55, 61, 62, 55, 43, 32, 21, 4, -26, -57, -75, -82, -80, -73,
- -58, -30, 5, 35, 46, 47, 51, 57, 61, 57, 46, 34, 22, 9, -15, -47,
- -71, -81, -80, -75, -62, -36, -4, 28, 46, 47, 49, 56, 60, 57, 48, 35,
- 23, 12, -9, -39, -67, -78, -76, -71, -65, -45, -13, 21, 45, 50, 46, 50,
- 58, 59, 49, 35, 23, 12, -4, -31, -62, -78, -74, -70, -65, -49, -18, 18,
- 43, 51, 45, 48, 56, 56, 45, 30, 20, 12, 0, -24, -53, -71, -69, -63,
- -60, -51, -25, 9, 36, 50, 47, 44, 50, 52, 45, 32, 21, 12, 1, -18,
- -44, -66, -70, -64, -59, -51, -31, 2, 32, 50, 51, 46, 47, 52, 47, 32,
- 17, 9, 0, -14, -34, -57, -67, -62, -56, -50, -33, -6, 24, 44, 51, 48,
- 47, 48, 46, 34, 21, 12, 2, -13, -32, -51, -62, -62, -56, -51, -38, -13,
- 18, 40, 51, 50, 45, 47, 46, 36, 20, 9, -2, -14, -28, -45, -59, -61,
- -54, -48, -37, -15, 14, 36, 49, 52, 48, 44, 42, 33, 19, 10, 0, -13,
- -26, -39, -52, -58, -54, -47, -37, -19, 9, 30, 44, 52, 48, 40, 38, 31,
- 19, 7, -3, -12, -22, -31, -42, -51, -49, -43, -36, -22, 1, 22, 35, 45,
- 47, 41, 37, 31, 23, 13, 3, -11, -22, -28, -36, -48, -53, -46, -35, -23,
- -4, 17, 31, 45, 49, 41, 33, 29, 23, 13, 2, -11, -22, -26, -29, -38,
- -46, -45, -34, -21, -6, 14, 25, 38, 46, 43, 35, 27, 19, 10, 3, -7,
- -20, -28, -28, -32, -38, -41, -35, -23, -8, 10, 23, 33, 44, 44, 36, 27,
- 18, 10, 0, -9, -22, -28, -28, -28, -33, -37, -32, -21, -7, 8, 20, 28,
- 38, 41, 36, 27, 17, 8, -2, -6, -17, -28, -31, -28, -27, -30, -30, -22,
- -7, 9, 19, 26, 35, 41, 37, 26, 16, 6, -5, -11, -18, -28, -31, -28,
- -22, -23, -23, -18, -4, 11, 19, 24, 27, 33, 33, 24, 14, 3, -8, -11,
- -15, -23, -29, -29, -21, -18, -19, -15, -5, 9, 16, 21, 26, 30, 32, 25,
- 13, 2, -9, -13, -16, -21, -27, -27, -20, -12, -13, -14, -7, 9, 17, 20,
- 24, 25, 26, 27, 15, 2, -9, -17, -17, -20, -25, -28, -23, -11, -6, -8,
- -5, 7, 19, 23, 24, 24, 24, 25, 16, 0, -13, -22, -22, -22, -26, -28,
- -22, -8, 2, 1, 0, 8, 18, 24, 24, 20, 18, 20, 15, 1, -12, -22,
- -24, -22, -23, -25, -22, -13, 2, 7, 3, 8, 16, 25, 28, 21, 15, 15,
- 15, 4, -13, -25, -29, -24, -20, -24, -21, -12, 1, 12, 10, 9, 16, 23,
- 27, 21, 14, 12, 10, 3, -10, -21, -28, -27, -22, -22, -20, -14, -4, 10,
- 14, 11, 17, 23, 29, 26, 15, 11, 10, 4, -12, -25, -33, -33, -26, -23,
- -22, -12, 0, 13, 22, 19, 20, 25, 29, 25, 12, 5, 3, 0, -12, -25,
- -32, -34, -27, -21, -20, -11, -2, 7, 18, 21, 22, 26, 30, 29, 21, 11,
- 4, -5, -14, -29, -38, -38, -33, -27, -23, -10, 4, 12, 22, 29, 30, 30,
- 31, 30, 21, 10, 0, -11, -19, -30, -39, -40, -36, -28, -20, -9, 4, 12,
- 20, 29, 32, 30, 32, 32, 23, 12, 3, -8, -18, -27, -39, -44, -40, -32,
- -25, -15, 1, 13, 22, 30, 37, 38, 36, 34, 26, 14, 2, -11, -22, -31,
- -40, -45, -42, -35, -26, -14, 0, 12, 19, 26, 35, 39, 36, 33, 28, 18,
- 6, -7, -18, -28, -37, -43, -43, -37, -30, -19, -6, 8, 20, 25, 34, 42,
- 41, 37, 32, 22, 8, -7, -19, -32, -40, -44, -44, -38, -30, -20, -6, 8,
- 19, 24, 30, 40, 41, 36, 29, 23, 13, -3, -16, -28, -39, -43, -44, -41,
- -34, -23, -11, 2, 16, 25, 32, 41, 46, 42, 34, 26, 15, 0, -16, -29,
- -40, -45, -45, -40, -32, -24, -12, -2, 12, 22, 26, 37, 45, 44, 34, 24,
- 18, 6, -12, -24, -37, -41, -40, -40, -36, -30, -17, -4, 9, 18, 25, 37,
- 45, 45, 40, 29, 19, 8, -8, -22, -38, -43, -42, -42, -35, -28, -17, -4,
- 7, 17, 23, 33, 43, 43, 38, 28, 19, 12, -3, -19, -34, -40, -38, -40,
- -38, -31, -22, -8, 5, 14, 21, 31, 44, 47, 41, 31, 20, 13, 3, -15,
- -33, -45, -45, -41, -38, -31, -24, -10, 4, 15, 21, 29, 42, 47, 41, 33,
- 22, 13, 4, -13, -29, -40, -41, -41, -41, -36, -26, -14, -2, 8, 17, 29,
- 42, 50, 46, 37, 27, 17, 7, -9, -27, -41, -48, -45, -42, -38, -29, -15,
- -2, 10, 18, 26, 38, 50, 51, 40, 28, 17, 6, -7, -24, -36, -43, -45,
- -41, -38, -31, -18, -8, 2, 13, 26, 38, 44, 49, 42, 33, 22, 8, -4,
- -20, -32, -41, -46, -44, -37, -32, -21, -8, 2, 14, 25, 35, 42, 47, 44,
- 31, 19, 7, -4, -15, -28, -36, -42, -40, -34, -31, -24, -9, 0, 7, 18,
- 30, 40, 44, 42, 32, 22, 12, 2, -10, -23, -31, -38, -42, -38, -31, -26,
- -13, -3, 2, 14, 29, 40, 41, 40, 36, 26, 13, 1, -10, -19, -26, -35,
- -43, -41, -33, -27, -17, -6, 1, 12, 27, 43, 47, 42, 37, 29, 14, 0,
- -10, -21, -29, -34, -40, -42, -33, -26, -18, -5, 3, 10, 23, 39, 45, 39,
- 33, 30, 18, 3, -8, -15, -22, -29, -37, -43, -36, -27, -22, -13, -4, 6,
- 19, 36, 47, 47, 37, 33, 25, 6, -8, -15, -25, -31, -36, -43, -42, -32,
- -21, -11, 0, 5, 15, 32, 46, 45, 35, 31, 28, 12, -6, -13, -20, -24,
- -31, -41, -46, -38, -26, -18, -9, 1, 14, 31, 43, 48, 42, 33, 28, 15,
- -5, -15, -18, -24, -31, -38, -41, -34, -26, -19, -8, 1, 10, 23, 37, 43,
- 41, 32, 26, 19, 3, -12, -15, -18, -24, -34, -42, -38, -28, -20, -13, -4,
- 6, 21, 37, 44, 43, 36, 28, 21, 8, -9, -16, -19, -25, -34, -42, -39,
- -29, -21, -13, -3, 8, 19, 34, 42, 41, 36, 28, 20, 8, -7, -15, -16,
- -19, -30, -41, -42, -31, -23, -15, -8, 3, 19, 36, 43, 39, 36, 30, 23,
- 13, -6, -19, -21, -20, -26, -38, -43, -35, -25, -15, -7, 3, 14, 30, 42,
- 40, 35, 28, 23, 16, 0, -14, -20, -19, -22, -34, -42, -37, -26, -15, -8,
- 0, 12, 27, 40, 41, 35, 29, 22, 16, 4, -9, -19, -20, -20, -29, -39,
- -39, -30, -19, -10, -3, 10, 24, 37, 42, 37, 31, 25, 18, 7, -7, -17,
- -21, -20, -28, -38, -40, -33, -22, -11, -5, 9, 25, 37, 44, 40, 32, 24,
- 17, 10, -5, -18, -24, -23, -28, -35, -38, -35, -26, -14, -5, 5, 19, 34,
- 44, 42, 33, 23, 18, 13, 0, -15, -20, -22, -26, -33, -39, -35, -28, -18,
- -10, 1, 18, 33, 43, 45, 38, 28, 20, 11, 2, -12, -22, -24, -28, -31,
- -36, -35, -29, -21, -11, 0, 15, 30, 40, 44, 39, 31, 21, 13, 8, -5,
- -17, -20, -25, -28, -32, -36, -34, -27, -18, -7, 9, 26, 39, 46, 45, 36,
- 25, 14, 10, -2, -16, -24, -29, -31, -31, -36, -36, -27, -16, -7, 6, 23,
- 37, 45, 44, 36, 26, 14, 8, 1, -14, -22, -23, -29, -32, -35, -36, -29,
- -21, -14, 0, 16, 35, 46, 45, 39, 33, 20, 8, 3, -9, -21, -28, -32,
- -34, -35, -36, -32, -25, -15, 1, 17, 32, 45, 49, 44, 35, 23, 7, 0,
- -7, -17, -25, -30, -31, -32, -34, -31, -25, -18, -7, 10, 27, 43, 50, 45,
- 35, 24, 13, 3, -7, -17, -24, -28, -30, -30, -33, -34, -26, -19, -11, 5,
- 22, 39, 50, 48, 37, 26, 16, 5, -7, -18, -23, -27, -28, -28, -33, -34,
- -24, -16, -11, 2, 17, 33, 48, 48, 37, 27, 18, 7, -5, -14, -20, -25,
- -30, -31, -32, -37, -31, -20, -15, -3, 15, 30, 46, 53, 43, 31, 20, 11,
- 0, -12, -21, -27, -31, -30, -30, -36, -33, -20, -10, -5, 9, 25, 41, 52,
- 46, 34, 23, 15, 6, -9, -21, -27, -30, -31, -31, -37, -39, -25, -12, -7,
- 1, 18, 36, 52, 53, 40, 28, 22, 13, -2, -18, -29, -32, -35, -34, -39,
- -40, -28, -13, -7, -2, 12, 33, 50, 56, 44, 30, 24, 18, 4, -15, -29,
- -32, -33, -33, -35, -40, -35, -20, -7, -2, 8, 25, 43, 54, 49, 35, 25,
- 18, 8, -7, -23, -32, -32, -34, -34, -37, -36, -24, -11, -5, 2, 18, 36,
- 51, 51, 39, 30, 24, 14, 0, -19, -32, -35, -35, -37, -38, -39, -29, -12,
- -2, 3, 14, 29, 47, 54, 45, 33, 26, 17, 5, -12, -31, -37, -36, -38,
- -38, -38, -32, -17, -3, 3, 9, 25, 42, 53, 49, 39, 31, 23, 10, -9,
- -27, -38, -40, -41, -41, -41, -36, -23, -5, 5, 8, 18, 36, 51, 51, 43,
- 34, 26, 16, 1, -20, -36, -40, -41, -42, -40, -38, -28, -10, 4, 7, 14,
- 30, 48, 51, 45, 39, 31, 21, 4, -16, -33, -41, -43, -43, -39, -38, -32,
- -15, 1, 7, 13, 25, 42, 52, 48, 39, 31, 22, 9, -10, -29, -40, -40,
- -40, -38, -35, -34, -20, -2, 5, 9, 17, 33, 49, 50, 43, 34, 25, 13,
- -4, -21, -36, -44, -44, -40, -35, -34, -26, -8, 5, 11, 17, 26, 43, 51,
- 46, 36, 27, 16, 1, -16, -31, -42, -46, -43, -37, -35, -29, -12, 3, 11,
- 17, 23, 37, 50, 52, 41, 29, 20, 4, -15, -30, -43, -49, -46, -39, -37,
- -33, -15, 3, 13, 19, 23, 35, 52, 55, 44, 29, 20, 8, -12, -28, -40,
- -48, -45, -39, -35, -32, -20, -2, 12, 16, 19, 28, 45, 55, 49, 35, 24,
- 14, -3, -20, -36, -49, -53, -45, -38, -35, -27, -9, 8, 19, 23, 26, 40,
- 55, 55, 41, 25, 15, -2, -19, -33, -46, -53, -47, -39, -35, -29, -14, 6,
- 19, 24, 25, 35, 53, 59, 47, 29, 17, 7, -12, -30, -47, -58, -56, -47,
- -39, -35, -22, -2, 17, 28, 30, 34, 50, 63, 56, 35, 19, 8, -9, -26,
- -43, -56, -58, -49, -42, -38, -27, -9, 12, 26, 33, 34, 44, 60, 62, 44,
- 23, 9, -4, -20, -40, -56, -63, -56, -44, -39, -30, -14, 8, 26, 35, 35,
- 43, 60, 64, 50, 28, 13, 2, -16, -37, -53, -62, -61, -50, -42, -32, -17,
- 2, 18, 32, 40, 44, 54, 63, 55, 37, 17, 4, -10, -31, -48, -61, -67,
- -59, -45, -36, -24, -5, 17, 33, 43, 47, 54, 64, 59, 42, 20, 3, -10,
- -28, -49, -63, -68, -63, -50, -37, -25, -7, 13, 31, 44, 48, 54, 61, 59,
- 48, 27, 6, -10, -24, -43, -59, -67, -67, -56, -39, -28, -13, 8, 24, 42,
- 51, 54, 58, 58, 52, 37, 14, -6, -20, -38, -54, -65, -70, -63, -45, -29,
- -17, 2, 18, 37, 52, 56, 58, 56, 51, 42, 23, -2, -19, -34, -50, -62,
- -70, -69, -52, -30, -17, -3, 15, 33, 50, 58, 58, 56, 52, 46, 29, 3,
- -15, -31, -45, -58, -68, -71, -60, -38, -20, -5, 11, 25, 42, 58, 62, 58,
- 51, 44, 36, 15, -10, -29, -43, -53, -64, -72, -67, -45, -21, -8, 4, 20,
- 40, 60, 65, 57, 53, 48, 42, 21, -8, -27, -40, -50, -62, -71, -71, -54,
- -29, -9, 3, 18, 34, 54, 68, 65, 57, 48, 40, 28, 2, -23, -41, -52,
- -60, -71, -75, -60, -34, -12, 0, 13, 31, 52, 69, 66, 56, 50, 44, 33,
- 7, -21, -38, -47, -55, -65, -75, -67, -41, -15, 2, 11, 23, 41, 61, 68,
- 59, 49, 40, 34, 17, -11, -35, -47, -48, -55, -69, -72, -50, -21, 0, 8,
- 15, 33, 56, 69, 62, 52, 44, 40, 26, -4, -30, -44, -48, -56, -69, -77,
- -59, -28, -7, 7, 15, 30, 52, 68, 66, 55, 45, 38, 30, 6, -24, -43,
- -49, -52, -64, -75, -65, -35, -10, 4, 11, 25, 45, 65, 67, 55, 48, 43,
- 34, 13, -18, -39, -45, -49, -61, -75, -72, -45, -17, -2, 9, 20, 39, 61,
- 70, 62, 52, 45, 36, 18, -9, -34, -47, -52, -58, -69, -72, -52, -23, -5,
- 7, 17, 35, 54, 65, 63, 55, 45, 37, 23, 0, -27, -45, -49, -53, -63,
- -71, -59, -31, -8, 7, 15, 28, 47, 61, 65, 58, 47, 38, 27, 6, -21,
- -41, -49, -53, -62, -69, -62, -39, -14, 3, 14, 28, 46, 59, 64, 62, 51,
- 39, 29, 11, -16, -40, -52, -55, -58, -65, -65, -47, -20, 1, 14, 24, 39,
- 52, 59, 64, 56, 43, 33, 16, -8, -32, -49, -55, -58, -63, -65, -54, -29,
- -3, 12, 21, 36, 51, 60, 65, 59, 46, 35, 21, -4, -28, -48, -56, -57,
- -59, -60, -55, -37, -12, 9, 19, 32, 46, 54, 58, 58, 48, 36, 26, 7,
- -18, -41, -53, -53, -52, -57, -58, -45, -19, 6, 15, 26, 42, 54, 59, 59,
- 52, 39, 28, 10, -16, -40, -56, -56, -52, -51, -53, -45, -22, 4, 17, 24,
- 35, 46, 56, 57, 52, 40, 30, 18, -7, -33, -54, -58, -52, -49, -53, -51,
- -33, -5, 17, 26, 34, 43, 54, 58, 53, 42, 31, 19, 0, -24, -47, -60,
- -55, -46, -46, -50, -39, -13, 13, 25, 32, 38, 48, 56, 52, 41, 30, 20,
- 7, -15, -41, -58, -55, -44, -41, -44, -40, -19, 10, 25, 28, 32, 41, 53,
- 52, 42, 31, 21, 13, -5, -32, -55, -60, -47, -36, -38, -40, -26, 2, 24,
- 29, 28, 32, 46, 48, 40, 29, 21, 14, 1, -23, -48, -56, -46, -34, -33,
- -36, -29, -7, 20, 28, 25, 26, 37, 46, 42, 30, 19, 15, 7, -13, -39,
- -58, -54, -37, -27, -27, -29, -17, 13, 29, 28, 24, 31, 42, 42, 34, 21,
- 11, 5, -10, -32, -51, -52, -40, -28, -24, -24, -18, 6, 27, 30, 26, 28,
- 36, 38, 33, 22, 11, 6, -7, -26, -44, -49, -42, -30, -21, -17, -16, -5,
- 18, 29, 26, 25, 29, 33, 33, 25, 13, 7, 0, -18, -36, -46, -45, -31,
- -20, -16, -16, -9, 12, 28, 29, 24, 25, 29, 31, 26, 13, 2, -5, -15,
- -26, -39, -46, -37, -19, -9, -9, -11, 1, 21, 31, 26, 21, 23, 26, 25,
- 15, 4, -4, -10, -20, -32, -41, -38, -22, -10, -7, -9, -6, 11, 26, 29,
- 22, 20, 21, 24, 19, 7, -6, -12, -17, -23, -30, -36, -27, -12, -3, 0,
- -5, 3, 18, 28, 25, 18, 15, 16, 15, 7, -4, -10, -14, -19, -24, -30,
- -26, -13, -3, 2, -3, -2, 12, 23, 26, 18, 13, 13, 14, 9, 0, -11,
- -14, -15, -18, -24, -26, -16, -4, 4, 0, -5, 6, 17, 25, 21, 11, 7,
- 8, 8, 1, -11, -14, -11, -10, -13, -20, -18, -7, 5, 7, -3, -2, 8,
- 21, 23, 12, 4, 4, 8, 7, -5, -15, -14, -11, -9, -15, -20, -13, 1,
- 8, 3, 0, 6, 17, 24, 16, 3, -2, 1, 0, -10, -17, -14, -8, -4,
- -5, -11, -12, 0, 9, 6, -3, 1, 10, 18, 16, 5, -3, 0, 3, -4,
- -13, -15, -10, -6, -4, -8, -13, -8, 5, 8, 5, 3, 9, 17, 18, 13,
- 0, -7, -5, -5, -11, -14, -11, -6, 2, 2, -6, -9, 1, 8, 5, -2,
- 1, 8, 14, 12, 2, -6, -5, -2, -6, -12, -10, -2, 3, 4, -5, -11,
- -6, 5, 6, 0, 0, 7, 12, 14, 6, -7, -8, -6, -6, -9, -10, -5,
- 4, 8, 4, -7, -11, -2, 6, 3, -2, 2, 9, 15, 12, -2, -8, -6,
- -3, -5, -11, -9, 2, 10, 7, -5, -15, -10, 4, 6, -2, -2, 8, 14,
- 14, 3, -9, -8, -5, -4, -8, -10, 0, 8, 9, 3, -9, -12, -3, 6,
- 3, -3, 1, 8, 13, 5, -9, -13, -7, -2, -2, -6, -2, 9, 13, 6,
- -6, -13, -10, 2, 4, -3, -2, 7, 13, 9, -6, -12, -11, -6, 0, -5,
- -5, 7, 15, 13, 1, -10, -13, -4, 5, -2, -7, -2, 9, 9, -3, -11,
- -11, -8, 2, 1, -3, 7, 15, 12, 4, -7, -13, -11, -2, 1, -4, -3,
- 7, 11, 3, -8, -11, -10, 0, 1, -5, 2, 12, 17, 11, -2, -11, -11,
- -3, 4, -4, -9, 1, 10, 3, -9, -11, -8, 0, 5, 1, 2, 11, 14,
- 9, 1, -11, -15, -11, -3, 1, -3, 3, 12, 11, 1, -7, -9, -6, -3,
- -5, -5, 5, 12, 9, 4, -3, -8, -8, -5, 0, -4, -3, 5, 6, -3,
- -10, -7, -3, 0, 2, 3, 10, 14, 11, 4, -3, -11, -15, -15, -9, -5,
- -5, 5, 13, 5, -2, 0, 2, 4, 1, -3, 4, 12, 11, 2, -5, -10,
- -13, -13, -11, -6, -4, 3, 13, 9, 1, -2, 4, 5, 1, -5, 3, 12,
- 13, 4, -9, -12, -14, -16, -17, -12, -5, 5, 16, 17, 6, 3, 9, 9,
- 2, -8, -7, 2, 7, 4, -8, -12, -10, -13, -14, -13, -6, 4, 13, 19,
- 10, 0, 6, 14, 8, -6, -9, 0, 7, 5, -8, -17, -13, -9, -14, -18,
- -13, 2, 15, 23, 16, 4, 5, 16, 15, 0, -10, -6, 3, 6, -4, -15,
- -15, -10, -11, -16, -16, -5, 10, 21, 18, 7, 2, 12, 18, 6, -7, -9,
- 1, 7, 1, -14, -19, -15, -13, -16, -18, -8, 7, 19, 24, 16, 5, 8,
- 16, 9, -4, -9, -5, 3, 4, -9, -19, -18, -13, -12, -17, -12, 2, 16,
- 22, 17, 6, 4, 14, 13, 1, -8, -6, 2, 6, -5, -18, -20, -16, -14,
- -18, -17, -5, 12, 23, 24, 14, 9, 15, 19, 9, -5, -8, -3, 2, -6,
- -17, -23, -19, -14, -16, -17, -8, 7, 19, 24, 19, 10, 11, 17, 13, 3,
- -5, -3, -2, -4, -14, -24, -25, -20, -18, -16, -10, 3, 16, 26, 28, 18,
- 11, 15, 17, 9, -4, -7, -6, -6, -12, -24, -29, -22, -16, -15, -10, 0,
- 13, 24, 27, 22, 14, 13, 16, 13, 2, -6, -7, -9, -12, -21, -29, -27,
- -21, -15, -10, -3, 8, 21, 29, 26, 17, 13, 17, 19, 9, -5, -10, -9,
- -12, -21, -30, -29, -22, -14, -10, -4, 7, 17, 26, 23, 17, 13, 12, 18,
- 16, 5, -6, -10, -11, -19, -29, -32, -27, -18, -10, -4, 4, 13, 25, 26,
- 21, 16, 11, 16, 17, 8, -5, -12, -12, -16, -25, -30, -27, -19, -10, -6,
- 0, 10, 21, 24, 18, 15, 13, 16, 20, 14, 1, -10, -12, -15, -26, -31,
- -29, -22, -12, -5, 0, 8, 19, 25, 22, 17, 14, 14, 19, 17, 4, -10,
- -15, -15, -22, -30, -30, -26, -16, -6, 1, 7, 15, 23, 23, 18, 17, 17,
- 17, 17, 8, -6, -15, -18, -24, -31, -29, -26, -19, -8, 2, 7, 15, 23,
- 24, 21, 17, 15, 15, 17, 13, -4, -16, -20, -23, -30, -32, -27, -19, -8,
- 3, 7, 14, 23, 24, 20, 16, 16, 15, 14, 10, 0, -12, -20, -24, -31,
- -32, -25, -19, -10, 0, 9, 14, 22, 27, 23, 17, 17, 18, 12, 8, 1,
- -12, -18, -23, -31, -34, -26, -17, -9, -2, 6, 14, 22, 27, 22, 16, 15,
- 18, 17, 10, 3, -9, -17, -21, -31, -38, -32, -23, -13, -5, 4, 14, 21,
- 30, 30, 21, 17, 18, 17, 10, 3, -8, -20, -23, -29, -38, -34, -25, -12,
- 0, 3, 11, 17, 26, 31, 23, 15, 13, 16, 14, 5, -4, -15, -19, -23,
- -35, -38, -32, -19, -7, -5, 6, 16, 25, 36, 32, 22, 19, 19, 15, 3,
- -7, -16, -23, -26, -35, -42, -34, -19, -3, 1, 6, 18, 26, 37, 34, 20,
- 15, 14, 14, 5, -7, -15, -21, -23, -28, -39, -37, -22, -5, 1, 3, 15,
- 25, 35, 40, 27, 14, 14, 14, 6, -7, -14, -20, -25, -27, -36, -41, -28,
- -8, 2, 4, 14, 24, 33, 40, 32, 17, 13, 12, 5, -7, -14, -17, -24,
- -28, -34, -40, -32, -14, 1, 4, 13, 26, 33, 41, 40, 26, 15, 12, 4,
- -9, -17, -20, -25, -31, -34, -41, -38, -20, 0, 7, 12, 24, 32, 40, 41,
- 30, 17, 11, 4, -10, -18, -19, -21, -27, -31, -35, -36, -24, -5, 5, 9,
- 21, 31, 37, 41, 36, 21, 11, 4, -8, -15, -18, -21, -26, -31, -34, -37,
- -30, -12, 3, 9, 18, 30, 38, 44, 42, 29, 15, 7, -6, -18, -23, -24,
- -25, -31, -34, -36, -33, -15, 3, 9, 17, 28, 38, 44, 42, 34, 20, 8,
- -5, -18, -23, -22, -24, -30, -35, -35, -35, -24, -6, 6, 14, 25, 36, 42,
- 45, 42, 28, 13, 1, -15, -26, -27, -26, -29, -35, -39, -38, -28, -10, 5,
- 13, 21, 36, 47, 48, 45, 36, 21, 6, -11, -25, -31, -30, -29, -35, -41,
- -41, -34, -18, 1, 15, 24, 35, 47, 52, 51, 42, 26, 8, -9, -25, -32,
- -34, -32, -34, -40, -41, -35, -22, -5, 11, 21, 30, 44, 52, 51, 45, 32,
- 15, -3, -19, -28, -33, -34, -36, -42, -44, -41, -30, -13, 6, 20, 29, 43,
- 54, 56, 50, 37, 22, 4, -17, -31, -39, -39, -38, -40, -44, -41, -31, -14,
- 4, 18, 26, 37, 52, 57, 54, 44, 29, 11, -9, -26, -38, -42, -40, -41,
- -45, -46, -39, -24, -2, 17, 25, 35, 49, 59, 59, 52, 36, 19, -2, -22,
- -38, -46, -45, -43, -44, -47, -41, -28, -7, 12, 22, 32, 45, 58, 60, 52,
- 40, 26, 9, -14, -36, -46, -47, -44, -44, -50, -47, -34, -14, 8, 21, 30,
- 42, 58, 65, 58, 46, 32, 14, -7, -30, -47, -51, -50, -45, -50, -51, -38,
- -20, 4, 19, 28, 38, 53, 67, 63, 50, 40, 23, 2, -22, -43, -54, -55,
- -50, -53, -57, -48, -31, -6, 17, 28, 39, 53, 69, 72, 60, 47, 29, 7,
- -18, -39, -54, -59, -56, -53, -55, -52, -37, -16, 10, 25, 36, 48, 65, 75,
- 68, 54, 40, 20, -6, -31, -52, -61, -61, -59, -63, -62, -46, -24, 2, 20,
- 33, 50, 67, 79, 75, 62, 49, 30, 2, -29, -50, -63, -66, -65, -64, -64,
- -50, -28, -6, 18, 34, 48, 62, 74, 79, 70, 54, 38, 14, -19, -45, -62,
- -70, -71, -67, -68, -61, -39, -15, 10, 28, 45, 63, 77, 82, 77, 62, 47,
- 25, -9, -40, -61, -70, -73, -69, -70, -66, -47, -23, 2, 23, 41, 57, 71,
- 79, 83, 72, 55, 37, 6, -27, -51, -67, -76, -78, -77, -75, -60, -35, -12,
- 13, 37, 59, 75, 82, 86, 81, 66, 48, 17, -23, -50, -66, -77, -83, -83,
- -78, -66, -43, -18, 7, 31, 54, 73, 83, 87, 87, 74, 55, 29, -10, -41,
- -61, -76, -85, -88, -84, -72, -53, -28, -3, 22, 51, 75, 84, 88, 92, 87,
- 67, 40, 0, -38, -60, -77, -89, -94, -89, -77, -59, -34, -7, 17, 44, 73,
- 88, 90, 91, 88, 74, 49, 12, -29, -57, -73, -84, -93, -94, -84, -68, -44,
- -17, 8, 33, 64, 85, 90, 92, 91, 83, 63, 30, -15, -50, -71, -82, -92,
- -96, -90, -74, -52, -26, 0, 24, 56, 82, 92, 93, 92, 89, 74, 42, 0,
- -41, -67, -80, -93, -100, -97, -83, -62, -35, -8, 16, 43, 74, 91, 96, 96,
- 93, 83, 56, 16, -28, -61, -79, -92, -99, -99, -90, -71, -45, -16, 9, 36,
- 66, 88, 98, 97, 93, 87, 68, 31, -16, -52, -75, -89, -98, -103, -98, -81,
- -54, -23, 1, 25, 56, 83, 97, 98, 92, 88, 76, 46, 1, -42, -68, -81,
- -91, -99, -97, -82, -58, -30, -6, 15, 44, 73, 91, 94, 89, 85, 78, 55,
- 16, -28, -59, -77, -87, -93, -95, -85, -65, -40, -16, 6, 33, 62, 85, 94,
- 90, 86, 81, 66, 32, -15, -52, -73, -84, -90, -93, -87, -69, -45, -22, 0,
- 22, 48, 75, 88, 88, 85, 80, 67, 42, 4, -36, -62, -77, -87, -90, -85,
- -72, -52, -30, -11, 11, 36, 63, 83, 86, 86, 82, 74, 54, 17, -25, -55,
- -72, -81, -88, -87, -77, -57, -34, -16, 4, 26, 54, 77, 84, 84, 82, 75,
- 58, 27, -12, -45, -65, -76, -84, -84, -76, -61, -41, -24, -7, 15, 41, 67,
- 78, 81, 80, 76, 67, 42, 5, -30, -54, -67, -79, -85, -79, -67, -50, -32,
- -16, 6, 32, 58, 73, 77, 81, 78, 68, 49, 16, -19, -45, -63, -74, -80,
- -77, -67, -53, -35, -20, -3, 20, 45, 65, 72, 76, 75, 68, 56, 29, -6,
- -33, -52, -65, -75, -77, -70, -57, -42, -28, -13, 9, 34, 57, 70, 73, 75,
- 72, 63, 41, 7, -24, -46, -60, -70, -75, -72, -59, -45, -31, -18, 0, 25,
- 48, 63, 68, 70, 71, 65, 47, 17, -13, -33, -49, -62, -73, -73, -61, -48,
- -37, -25, -10, 14, 39, 57, 64, 67, 70, 69, 54, 28, -3, -27, -44, -57,
- -68, -74, -66, -50, -39, -26, -13, 5, 30, 50, 60, 62, 64, 65, 58, 38,
- 9, -17, -35, -46, -59, -69, -67, -52, -40, -31, -20, -6, 18, 42, 55, 58,
- 60, 65, 62, 47, 20, -10, -28, -39, -51, -66, -70, -58, -44, -34, -23, -10,
- 11, 34, 51, 57, 58, 62, 63, 51, 29, 2, -21, -34, -46, -60, -69, -63,
- -49, -37, -27, -15, 3, 26, 45, 55, 56, 58, 62, 55, 37, 11, -14, -29,
- -39, -52, -65, -66, -52, -40, -30, -18, -5, 17, 39, 52, 54, 55, 58, 57,
- 44, 21, -8, -24, -33, -45, -59, -66, -57, -43, -31, -20, -11, 7, 30, 47,
- 53, 51, 52, 55, 51, 33, 4, -20, -29, -36, -49, -64, -63, -50, -36, -24,
- -14, 0, 22, 43, 55, 53, 49, 52, 51, 39, 12, -16, -27, -33, -45, -60,
- -66, -53, -37, -25, -16, -6, 16, 40, 53, 53, 47, 49, 51, 43, 22, 0,
- 0, 0, 0, 0, 0, 0, 0, 22, 0, 0, -2, -2, -2, -2, 0, -2,
- 0, 0, 1, 2, 3, 4, 4, 4, 5, 6, 7, 6, 3, 1, 0, -3,
- -5, -11, -17, -20, -20, -18, -16, -17, -17, -14, -10, -9, -13, -18, -19, -15,
- -13, -12, -13, -8, 1, 12, 25, 32, 40, 45, 50, 49, 41, 32, 24, 16,
- 9, 1, -12, -20, -23, -24, -20, -20, -18, -12, -11, -12, -7, 0, 10, 17,
- 23, 25, 24, 21, 22, 23, 21, 10, 1, -5, -8, -11, -19, -29, -33, -32,
- -26, -19, -16, -14, -12, -8, -7, -11, -19, -27, -29, -27, -25, -25, -24, -17,
- -4, 13, 26, 34, 43, 54, 59, 56, 46, 33, 23, 15, 5, -11, -23, -32,
- -35, -32, -30, -27, -23, -16, -11, -5, 3, 11, 23, 31, 36, 33, 28, 27,
- 26, 21, 11, 1, -9, -14, -18, -23, -28, -35, -33, -26, -18, -12, -11, -7,
- -4, -2, 0, -8, -19, -29, -33, -32, -30, -30, -25, -17, -4, 13, 26, 36,
- 47, 55, 59, 53, 43, 32, 23, 12, 0, -14, -23, -30, -35, -35, -35, -33,
- -28, -19, -11, -6, 3, 11, 22, 33, 39, 38, 34, 30, 27, 20, 11, 0,
- -9, -17, -21, -26, -31, -34, -29, -19, -8, -3, 0, -3, 1, 4, 1, -11,
- -25, -35, -37, -39, -35, -32, -27, -17, 0, 15, 29, 42, 55, 63, 62, 55,
- 47, 38, 27, 14, -4, -20, -31, -40, -44, -46, -45, -41, -34, -25, -14, -3,
- 8, 22, 32, 43, 44, 40, 36, 34, 26, 18, 8, -2, -11, -20, -25, -29,
- -33, -31, -21, -10, -2, -2, -2, 4, 6, 9, 0, -14, -28, -35, -39, -38,
- -38, -36, -30, -16, 0, 16, 29, 41, 55, 65, 67, 59, 49, 39, 28, 13,
- -3, -19, -32, -42, -48, -51, -53, -47, -36, -22, -12, 0, 10, 24, 38, 46,
- 48, 43, 39, 32, 26, 17, 6, -7, -16, -21, -26, -31, -34, -28, -16, -2,
- 3, 1, 2, 8, 16, 12, 2, -15, -27, -34, -37, -41, -47, -44, -33, -16,
- 1, 16, 31, 47, 65, 75, 73, 63, 52, 41, 27, 9, -14, -34, -47, -54,
- -55, -58, -57, -50, -35, -17, 0, 8, 20, 34, 47, 54, 49, 42, 36, 29,
- 21, 9, -4, -14, -21, -26, -30, -33, -28, -18, -5, 4, 6, 6, 8, 13,
- 17, 12, -4, -21, -33, -39, -44, -49, -50, -46, -35, -15, 4, 22, 36, 55,
- 72, 81, 78, 69, 54, 42, 27, 6, -19, -38, -52, -57, -62, -65, -64, -52,
- -35, -17, -3, 8, 19, 33, 45, 50, 48, 42, 35, 29, 18, 7, -5, -11,
- -20, -26, -29, -27, -20, -13, -4, 3, 8, 9, 11, 12, 12, 5, -8, -22,
- -33, -42, -50, -53, -51, -42, -27, -11, 9, 27, 45, 62, 75, 78, 73, 60,
- 48, 32, 14, -8, -30, -46, -54, -60, -64, -62, -53, -39, -23, -8, 5, 17,
- 30, 41, 46, 44, 38, 30, 22, 11, 4, -5, -12, -20, -25, -26, -24, -17,
- -7, 3, 8, 11, 12, 14, 15, 14, 9, -4, -17, -32, -44, -54, -57, -56,
- -48, -36, -22, -5, 18, 41, 61, 74, 79, 75, 67, 55, 39, 20, -2, -20,
- -37, -47, -56, -62, -63, -57, -44, -31, -18, -5, 7, 16, 28, 35, 38, 37,
- 32, 25, 16, 8, 3, -2, -5, -11, -19, -21, -16, -7, 3, 6, 8, 7,
- 8, 10, 9, 5, -4, -13, -23, -37, -49, -54, -54, -47, -38, -25, -9, 9,
- 30, 50, 67, 77, 75, 69, 58, 42, 26, 7, -12, -31, -46, -52, -56, -59,
- -58, -49, -36, -19, -5, 8, 14, 22, 28, 33, 35, 30, 23, 13, 4, 3,
- 3, 0, -8, -12, -13, -10, -6, 2, 8, 11, 12, 11, 9, 4, -2, -5,
- -12, -23, -35, -46, -52, -54, -48, -36, -22, -8, 9, 28, 46, 61, 70, 72,
- 68, 58, 45, 27, 9, -8, -22, -35, -43, -48, -48, -46, -39, -33, -23, -12,
- 1, 8, 11, 14, 16, 19, 19, 17, 11, 7, 8, 11, 13, 7, 5, 2,
- 2, 2, 4, 6, 6, 5, 2, -3, -5, -9, -11, -17, -23, -29, -34, -40,
- -45, -41, -32, -18, -5, 7, 19, 36, 54, 64, 67, 61, 55, 48, 36, 18,
- 3, -11, -23, -36, -45, -46, -42, -39, -34, -27, -20, -11, 0, 10, 13, 14,
- 12, 13, 13, 10, 7, 6, 9, 11, 11, 11, 10, 10, 8, 9, 9, 9,
- 6, 1, -4, -12, -16, -22, -25, -28, -29, -30, -39, -43, -39, -26, -11, 0,
- 8, 19, 33, 48, 58, 63, 61, 56, 50, 40, 25, 8, -5, -15, -24, -35,
- -41, -42, -39, -32, -29, -25, -21, -13, -6, 0, 4, 2, 2, 3, 6, 6,
- 7, 11, 17, 20, 22, 23, 24, 23, 21, 17, 12, 4, -5, -13, -22, -29,
- -37, -41, -40, -36, -31, -32, -34, -34, -22, -6, 8, 14, 20, 29, 41, 50,
- 56, 56, 49, 45, 39, 30, 17, 5, -8, -19, -28, -34, -35, -32, -27, -25,
- -25, -23, -19, -12, -7, -4, -6, -10, -11, -7, 0, 4, 10, 14, 19, 26,
- 32, 35, 34, 31, 25, 16, 6, -5, -17, -29, -39, -47, -51, -50, -44, -35,
- -28, -27, -25, -18, -6, 10, 18, 21, 25, 31, 40, 46, 49, 48, 44, 42,
- 37, 29, 19, 8, -5, -14, -21, -29, -30, -30, -27, -28, -32, -33, -31, -22,
- -17, -15, -17, -19, -19, -9, 5, 16, 22, 25, 31, 38, 44, 47, 43, 34,
- 20, 6, -9, -21, -35, -49, -59, -62, -60, -53, -42, -30, -22, -15, -6, 4,
- 14, 23, 27, 28, 27, 30, 35, 38, 39, 42, 38, 35, 30, 25, 20, 12,
- 4, -6, -18, -23, -22, -20, -22, -30, -37, -39, -34, -29, -27, -27, -26, -23,
- -16, -3, 10, 21, 29, 35, 43, 46, 50, 49, 41, 28, 15, -2, -19, -35,
- -50, -62, -67, -67, -60, -50, -36, -23, -14, -6, 3, 11, 21, 27, 27, 24,
- 25, 27, 29, 31, 36, 41, 42, 39, 33, 27, 22, 17, 8, -3, -11, -15,
- -15, -18, -25, -35, -42, -45, -42, -41, -41, -40, -38, -28, -12, 7, 22, 34,
- 43, 51, 59, 62, 59, 49, 37, 20, 1, -19, -38, -54, -65, -73, -74, -69,
- -55, -35, -19, -10, -2, 8, 18, 23, 25, 25, 22, 20, 19, 20, 22, 30,
- 39, 44, 42, 39, 35, 32, 29, 18, 4, -8, -13, -15, -17, -24, -33, -43,
- -47, -44, -42, -40, -40, -39, -32, -17, 3, 16, 28, 39, 47, 53, 56, 56,
- 52, 40, 24, 5, -12, -29, -43, -54, -65, -72, -71, -56, -36, -20, -13, -4,
- 5, 12, 18, 21, 23, 20, 18, 14, 16, 19, 27, 38, 45, 45, 42, 41,
- 42, 37, 27, 15, 1, -8, -12, -13, -17, -30, -40, -47, -48, -47, -46, -46,
- -45, -41, -28, -9, 11, 26, 38, 45, 51, 55, 58, 55, 47, 31, 10, -12,
- -27, -39, -49, -58, -67, -69, -62, -46, -26, -13, -4, 2, 7, 14, 18, 21,
- 20, 15, 11, 12, 14, 21, 32, 40, 44, 42, 42, 40, 37, 33, 22, 11,
- 1, -7, -11, -11, -19, -30, -39, -43, -43, -42, -43, -44, -44, -36, -20, 0,
- 14, 25, 35, 42, 46, 50, 50, 48, 36, 17, -3, -18, -30, -36, -43, -52,
- -59, -60, -49, -35, -20, -12, -7, -4, 2, 8, 12, 12, 9, 9, 12, 16,
- 23, 29, 39, 45, 46, 46, 43, 41, 37, 30, 20, 7, -5, -10, -11, -15,
- -25, -39, -46, -45, -43, -42, -45, -46, -39, -26, -8, 8, 20, 31, 41, 45,
- 48, 46, 44, 36, 21, 1, -20, -31, -33, -36, -44, -53, -59, -54, -41, -26,
- -17, -12, -6, -3, 5, 7, 9, 11, 11, 12, 15, 20, 29, 36, 42, 46,
- 45, 42, 40, 38, 33, 25, 13, 4, -7, -10, -11, -17, -29, -38, -38, -34,
- -35, -39, -41, -39, -31, -16, -6, 4, 14, 24, 30, 34, 34, 35, 32, 22,
- 8, -9, -16, -16, -17, -22, -33, -43, -46, -41, -34, -30, -25, -19, -14, -9,
- -6, -2, 5, 9, 13, 15, 21, 29, 36, 43, 47, 46, 46, 42, 39, 37,
- 31, 20, 10, 0, -6, -9, -14, -22, -29, -33, -31, -30, -34, -37, -37, -30,
- -21, -12, -5, 1, 10, 20, 28, 31, 31, 28, 20, 12, 0, -8, -10, -10,
- -16, -24, -33, -39, -44, -42, -35, -28, -23, -18, -14, -10, -4, 6, 12, 16,
- 17, 22, 29, 33, 35, 38, 41, 43, 41, 38, 34, 30, 24, 16, 9, 3,
- -4, -10, -15, -21, -23, -23, -23, -24, -28, -32, -31, -28, -22, -15, -10, -6,
- 2, 11, 20, 23, 25, 19, 14, 9, 5, 3, 2, -2, -8, -19, -28, -36,
- -42, -44, -39, -33, -28, -26, -20, -11, 0, 8, 15, 22, 28, 33, 35, 36,
- 37, 38, 41, 40, 38, 32, 27, 21, 17, 11, 4, -3, -8, -12, -17, -18,
- -16, -16, -15, -18, -22, -25, -26, -25, -23, -19, -15, -9, -2, 8, 13, 17,
- 18, 17, 16, 15, 13, 10, 6, 0, -9, -21, -32, -42, -47, -46, -43, -36,
- -30, -22, -15, -6, 4, 14, 22, 28, 33, 36, 37, 36, 35, 37, 36, 36,
- 32, 27, 23, 16, 10, 5, 0, -7, -10, -12, -11, -11, -11, -10, -9, -11,
- -16, -22, -27, -30, -30, -30, -25, -19, -9, 0, 7, 13, 18, 23, 27, 27,
- 26, 20, 12, 1, -13, -27, -40, -50, -54, -54, -49, -42, -33, -21, -10, 1,
- 14, 24, 30, 39, 44, 43, 38, 36, 38, 37, 34, 31, 28, 22, 13, 7,
- 5, -2, -7, -11, -14, -13, -13, -8, -6, -6, -10, -12, -14, -19, -26, -34,
- -38, -33, -26, -15, -7, 2, 7, 17, 26, 35, 40, 37, 29, 19, 7, -12,
- -31, -44, -53, -56, -61, -62, -59, -46, -27, -9, 5, 14, 25, 36, 47, 53,
- 51, 45, 37, 34, 32, 29, 26, 23, 18, 13, 5, 0, -3, -4, -6, -10,
- -12, -12, -6, 2, 6, 2, -6, -12, -17, -21, -31, -41, -47, -43, -32, -20,
- -11, -4, 9, 21, 40, 50, 48, 42, 34, 22, 5, -16, -36, -53, -58, -63,
- -69, -73, -63, -43, -19, -2, 9, 19, 34, 50, 60, 61, 53, 42, 37, 32,
- 30, 24, 21, 16, 11, 4, -4, -7, -6, -5, -5, -10, -14, -11, -4, 3,
- 2, -2, -8, -13, -19, -26, -36, -42, -40, -33, -21, -9, 1, 10, 22, 36,
- 49, 53, 47, 36, 19, 1, -18, -36, -51, -60, -65, -67, -67, -63, -47, -24,
- -4, 11, 20, 33, 48, 57, 57, 52, 42, 33, 30, 28, 25, 19, 16, 12,
- 8, 3, -2, -2, -2, -2, -5, -8, -10, -5, -2, 0, 0, -5, -8, -15,
- -23, -32, -39, -38, -33, -24, -15, -7, 5, 16, 30, 45, 52, 49, 40, 23,
- 4, -14, -29, -42, -55, -63, -67, -67, -61, -50, -35, -19, 0, 16, 31, 46,
- 56, 59, 56, 47, 38, 34, 31, 28, 23, 16, 10, 4, 0, -2, -2, 0,
- -5, -9, -12, -11, -7, -3, -3, -4, -5, -4, -7, -14, -26, -33, -32, -27,
- -20, -15, -7, 2, 13, 21, 34, 42, 46, 40, 25, 7, -13, -27, -35, -44,
- -54, -62, -64, -60, -51, -39, -26, -10, 8, 24, 40, 51, 58, 60, 54, 44,
- 36, 29, 24, 19, 13, 8, 0, -6, -5, 0, 1, 0, -4, -3, -2, 0,
- 1, -2, -5, -5, -4, -7, -17, -27, -31, -29, -24, -19, -15, -9, -3, 7,
- 18, 27, 34, 39, 37, 26, 9, -9, -24, -32, -39, -47, -55, -60, -57, -51,
- -42, -32, -20, -6, 14, 31, 48, 57, 60, 58, 52, 45, 35, 25, 21, 17,
- 9, 0, -8, -10, -8, -7, -6, -9, -9, -6, -2, 0, -3, -6, -6, -2,
- 1, -6, -15, -25, -25, -20, -17, -13, -11, -7, 1, 8, 16, 24, 31, 34,
- 29, 16, -3, -17, -28, -35, -41, -47, -54, -56, -54, -46, -37, -27, -15, 4,
- 23, 40, 50, 58, 60, 58, 50, 42, 34, 26, 19, 14, 4, -6, -13, -13,
- -13, -14, -16, -15, -12, -9, -7, -7, -4, -4, 2, 7, 5, 0, -8, -11,
- -13, -13, -11, -10, -11, -11, -9, 0, 8, 14, 22, 24, 19, 9, -3, -14,
- -23, -29, -32, -38, -47, -54, -52, -44, -32, -23, -9, 8, 23, 39, 52, 59,
- 58, 51, 46, 43, 33, 25, 16, 9, 4, -4, -11, -15, -16, -16, -15, -14,
- -15, -16, -13, -7, -5, 2, 5, 5, 5, 6, 3, -4, -6, -4, -5, -10,
- -16, -16, -13, -6, 4, 12, 15, 17, 14, 10, 4, -8, -17, -23, -30, -38,
- -46, -52, -51, -41, -30, -20, -8, 9, 29, 47, 56, 57, 55, 52, 50, 45,
- 34, 20, 10, 2, -2, -9, -16, -22, -24, -22, -21, -22, -19, -14, -7, -4,
- 1, 5, 11, 15, 20, 17, 9, 3, 3, 0, -6, -15, -21, -23, -16, -9,
- -3, 4, 10, 13, 15, 13, 4, -9, -15, -20, -27, -39, -48, -51, -47, -38,
- -29, -21, -7, 16, 36, 48, 51, 52, 55, 60, 59, 49, 33, 20, 12, 7,
- -2, -13, -24, -28, -27, -26, -30, -32, -29, -20, -9, 0, 3, 8, 16, 25,
- 28, 23, 17, 12, 6, -2, -14, -26, -31, -27, -18, -10, -3, 7, 15, 22,
- 24, 18, 9, 0, -9, -19, -34, -46, -57, -57, -51, -44, -38, -26, -5, 21,
- 42, 48, 53, 58, 67, 75, 71, 57, 37, 23, 12, 3, -12, -27, -39, -43,
- -43, -45, -47, -42, -28, -12, 2, 7, 12, 20, 32, 38, 37, 30, 21, 13,
- 1, -13, -26, -34, -33, -26, -17, -10, -3, 9, 20, 25, 22, 13, 5, -3,
- -13, -28, -43, -53, -56, -51, -46, -40, -31, -14, 10, 31, 41, 47, 56, 67,
- 76, 73, 63, 46, 30, 19, 9, -7, -25, -39, -47, -50, -54, -52, -50, -38,
- -22, -9, 4, 12, 22, 30, 39, 41, 39, 31, 22, 12, -3, -19, -30, -32,
- -29, -23, -17, -9, 1, 12, 20, 24, 18, 10, 2, -7, -19, -35, -50, -59,
- -59, -54, -49, -43, -31, -9, 15, 32, 41, 53, 70, 85, 87, 80, 64, 49,
- 37, 23, 2, -23, -42, -52, -59, -66, -69, -68, -56, -38, -18, -2, 9, 19,
- 31, 41, 49, 51, 44, 35, 21, 5, -9, -22, -29, -30, -26, -20, -14, -7,
- 5, 15, 17, 14, 9, 2, -4, -16, -29, -45, -55, -56, -50, -46, -44, -36,
- -19, 1, 19, 33, 46, 63, 79, 86, 84, 73, 60, 47, 32, 12, -10, -30,
- -48, -59, -68, -72, -73, -64, -49, -30, -12, 2, 12, 26, 35, 45, 51, 51,
- 44, 30, 15, 3, -9, -17, -20, -21, -19, -18, -14, 0, 10, 16, 15, 7,
- -4, -10, -14, -24, -38, -51, -58, -55, -50, -44, -36, -23, -7, 10, 26, 41,
- 57, 76, 89, 89, 81, 70, 59, 45, 25, 0, -24, -41, -56, -67, -75, -80,
- -76, -63, -45, -26, -9, 6, 20, 32, 44, 52, 54, 53, 47, 35, 18, 3,
- -6, -11, -14, -16, -19, -19, -12, -4, 5, 5, 0, -8, -12, -15, -21, -34,
- -47, -51, -45, -39, -34, -30, -23, -12, 4, 17, 31, 45, 60, 72, 78, 75,
- 69, 62, 53, 40, 18, -5, -24, -38, -50, -62, -73, -78, -74, -59, -41, -28,
- -17, -4, 14, 33, 47, 55, 58, 55, 48, 39, 29, 16, 4, -5, -11, -18,
- -21, -20, -15, -8, -7, -9, -13, -15, -16, -17, -23, -33, -43, -44, -41, -34,
- -28, -23, -16, -8, 5, 21, 36, 50, 62, 73, 76, 73, 68, 59, 48, 30,
- 9, -16, -35, -48, -59, -70, -77, -79, -72, -54, -38, -24, -8, 8, 29, 45,
- 56, 61, 62, 56, 51, 39, 27, 16, 4, -8, -16, -22, -23, -25, -19, -16,
- -17, -19, -20, -21, -18, -19, -25, -32, -38, -34, -24, -19, -15, -12, -7, 3,
- 15, 28, 39, 48, 56, 63, 63, 63, 57, 47, 32, 14, -5, -22, -36, -46,
- -58, -68, -73, -71, -61, -47, -35, -23, -9, 10, 29, 43, 52, 56, 56, 56,
- 52, 45, 33, 19, 6, -5, -15, -22, -25, -26, -26, -29, -29, -26, -24, -20,
- -19, -23, -27, -30, -27, -21, -18, -14, -10, -7, 0, 8, 18, 30, 40, 47,
- 52, 54, 54, 55, 49, 39, 22, 7, -9, -24, -37, -50, -58, -65, -71, -67,
- -59, -50, -39, -23, -6, 15, 32, 43, 51, 57, 61, 64, 61, 52, 37, 21,
- 4, -11, -20, -26, -30, -35, -37, -39, -35, -29, -22, -17, -20, -22, -20, -18,
- -17, -16, -13, -8, -3, 2, 7, 10, 17, 27, 35, 42, 43, 44, 45, 44,
- 38, 28, 16, 3, -10, -22, -33, -46, -57, -64, -64, -59, -53, -46, -34, -17,
- 3, 21, 32, 41, 48, 55, 60, 60, 54, 44, 31, 18, 3, -10, -19, -27,
- -30, -32, -34, -35, -30, -23, -17, -17, -20, -20, -20, -17, -15, -13, -11, -8,
- 1, 8, 12, 17, 23, 30, 39, 39, 37, 36, 35, 34, 27, 14, 0, -10,
- -15, -23, -34, -46, -56, -60, -56, -49, -39, -32, -23, -8, 8, 23, 32, 38,
- 44, 54, 58, 57, 48, 37, 29, 17, 4, -11, -21, -28, -29, -31, -34, -35,
- -27, -20, -15, -16, -16, -17, -13, -10, -10, -11, -10, -4, 5, 11, 13, 15,
- 21, 29, 33, 32, 28, 25, 25, 23, 16, 5, -6, -10, -16, -21, -30, -42,
- -48, -48, -43, -34, -29, -21, -13, -3, 11, 22, 27, 34, 39, 48, 53, 48,
- 42, 32, 23, 16, 4, -7, -18, -24, -24, -26, -28, -24, -19, -14, -13, -16,
- -18, -18, -16, -14, -15, -16, -15, -7, 3, 11, 14, 21, 27, 33, 36, 33,
- 30, 25, 22, 17, 9, -4, -15, -21, -24, -31, -39, -44, -44, -39, -30, -23,
- -16, -8, 4, 14, 21, 23, 25, 29, 37, 43, 42, 36, 31, 25, 18, 11,
- 4, -7, -11, -13, -16, -21, -22, -18, -14, -13, -16, -19, -21, -21, -19, -19,
- -20, -18, -11, -2, 8, 14, 18, 23, 30, 34, 35, 31, 27, 21, 13, 2,
- -11, -17, -23, -28, -36, -39, -40, -37, -31, -23, -14, -9, 0, 7, 13, 15,
- 15, 16, 22, 27, 30, 28, 29, 32, 29, 23, 16, 9, 4, 1, -2, -7,
- -14, -19, -14, -10, -10, -14, -18, -22, -24, -23, -26, -28, -27, -18, -8, -3,
- 2, 9, 22, 33, 40, 40, 36, 30, 25, 20, 8, -8, -22, -29, -32, -39,
- -48, -50, -42, -30, -19, -13, -8, 2, 11, 22, 25, 21, 17, 15, 20, 23,
- 21, 20, 20, 19, 19, 16, 11, 9, 7, 7, 3, 0, -3, -5, -5, -5,
- -7, -12, -22, -28, -32, -35, -35, -36, -30, -21, -12, -4, 3, 16, 29, 39,
- 46, 45, 40, 34, 26, 13, -2, -17, -28, -37, -48, -57, -60, -52, -36, -19,
- -12, -8, 2, 16, 28, 33, 28, 23, 21, 22, 21, 19, 18, 16, 14, 12,
- 8, 6, 5, 5, 7, 5, 4, 5, 7, 9, 7, 3, -5, -13, -22, -28,
- -35, -44, -49, -48, -38, -26, -14, -7, 4, 20, 38, 49, 54, 53, 49, 40,
- 26, 8, -11, -24, -33, -46, -61, -70, -67, -52, -31, -14, -5, 4, 14, 27,
- 36, 36, 33, 29, 26, 25, 21, 14, 10, 7, 8, 6, 5, 5, 6, 8,
- 9, 10, 14, 18, 17, 13, 5, -4, -12, -20, -28, -37, -49, -56, -56, -48,
- -36, -25, -15, -2, 16, 36, 51, 55, 57, 55, 48, 37, 20, 1, -17, -30,
- -43, -60, -73, -76, -63, -43, -24, -14, -6, 7, 23, 39, 44, 38, 34, 31,
- 32, 30, 24, 16, 8, 5, 6, 6, 5, 5, 6, 10, 10, 13, 16, 19,
- 19, 14, 5, -7, -18, -25, -34, -45, -55, -61, -59, -51, -39, -25, -12, 5,
- 27, 48, 58, 60, 61, 58, 49, 32, 14, -4, -20, -36, -54, -69, -79, -75,
- -57, -35, -21, -15, -4, 12, 28, 39, 42, 41, 38, 38, 38, 33, 23, 13,
- 8, 9, 11, 9, 5, 3, 6, 10, 13, 14, 15, 17, 16, 9, -6, -16,
- -21, -27, -40, -56, -65, -67, -57, -45, -33, -23, -5, 21, 44, 60, 66, 67,
- 65, 61, 47, 25, 2, -16, -34, -53, -72, -83, -82, -70, -51, -33, -20, -8,
- 8, 25, 39, 46, 43, 43, 43, 43, 38, 27, 17, 9, 8, 10, 11, 9,
- 5, 5, 8, 13, 14, 18, 20, 18, 12, -2, -13, -19, -25, -34, -48, -62,
- -69, -67, -58, -46, -32, -14, 9, 30, 48, 60, 69, 72, 69, 57, 36, 13,
- -6, -27, -47, -66, -79, -83, -77, -64, -46, -29, -13, 4, 17, 30, 39, 41,
- 46, 48, 45, 40, 31, 20, 12, 10, 13, 14, 12, 11, 10, 10, 15, 17,
- 20, 20, 17, 12, 0, -14, -24, -30, -37, -47, -60, -69, -68, -62, -51, -36,
- -18, 5, 25, 45, 58, 65, 68, 67, 59, 42, 20, -2, -22, -42, -61, -75,
- -81, -77, -66, -51, -35, -20, -4, 14, 28, 37, 38, 38, 42, 47, 43, 35,
- 24, 17, 14, 14, 17, 20, 20, 17, 13, 14, 17, 18, 18, 17, 11, -2,
- -15, -24, -31, -38, -46, -52, -58, -62, -61, -52, -38, -22, -4, 16, 35, 48,
- 55, 60, 62, 57, 46, 26, 6, -17, -35, -53, -68, -76, -75, -66, -51, -38,
- -23, -7, 10, 25, 35, 38, 37, 39, 40, 39, 30, 21, 16, 15, 15, 16,
- 20, 24, 26, 27, 27, 26, 24, 21, 19, 11, -3, -16, -29, -40, -44, -50,
- -54, -57, -58, -55, -48, -36, -21, -5, 13, 29, 41, 48, 52, 53, 50, 41,
- 26, 7, -14, -33, -49, -62, -70, -69, -61, -48, -36, -21, -5, 16, 30, 35,
- 35, 35, 32, 31, 29, 24, 17, 13, 13, 14, 15, 18, 26, 34, 39, 37,
- 32, 29, 26, 22, 13, 1, -15, -29, -40, -46, -51, -54, -55, -52, -46, -40,
- -32, -22, -10, 5, 19, 28, 33, 35, 37, 38, 33, 21, 8, -7, -20, -35,
- -50, -57, -57, -49, -37, -28, -21, -8, 10, 25, 32, 32, 31, 27, 24, 22,
- 20, 15, 13, 13, 15, 15, 19, 26, 36, 42, 43, 40, 33, 27, 22, 16,
- 3, -13, -26, -37, -44, -50, -55, -54, -48, -42, -32, -24, -18, -10, -3, 8,
- 20, 30, 31, 26, 22, 20, 15, 7, -7, -20, -32, -43, -52, -52, -46, -36,
- -25, -16, -5, 9, 24, 38, 42, 39, 30, 23, 19, 15, 11, 8, 6, 6,
- 6, 9, 18, 30, 42, 47, 45, 43, 38, 31, 22, 8, -9, -21, -33, -45,
- -55, -59, -56, -47, -37, -29, -21, -13, -5, 2, 8, 13, 19, 22, 20, 15,
- 9, 5, -3, -9, -20, -30, -39, -46, -45, -40, -31, -24, -16, -6, 7, 21,
- 35, 39, 36, 31, 24, 22, 15, 10, 8, 5, 6, 3, 4, 12, 25, 40,
- 48, 50, 48, 43, 37, 30, 17, -2, -18, -33, -45, -57, -64, -62, -53, -40,
- -31, -23, -13, -3, 4, 11, 16, 19, 18, 17, 13, 7, -3, -10, -16, -22,
- -31, -40, -45, -45, -41, -32, -24, -15, -5, 8, 24, 39, 47, 44, 38, 32,
- 26, 20, 12, 3, -4, -4, -5, -4, 1, 11, 29, 41, 49, 51, 49, 45,
- 38, 27, 9, -11, -27, -38, -52, -60, -64, -58, -45, -32, -21, -14, -5, 3,
- 10, 13, 13, 14, 14, 12, 4, -6, -12, -17, -21, -25, -31, -35, -40, -39,
- -33, -27, -19, -12, 1, 16, 29, 38, 42, 40, 36, 33, 30, 22, 11, 1,
- -2, -2, -3, -2, 2, 16, 32, 44, 48, 46, 44, 39, 31, 19, 1, -21,
- -36, -48, -58, -62, -59, -49, -38, -28, -20, -12, -2, 9, 16, 16, 15, 16,
- 14, 9, 2, -7, -14, -19, -25, -31, -36, -38, -38, -36, -34, -28, -20, -7,
- 8, 22, 33, 41, 46, 46, 42, 39, 33, 25, 14, 4, -4, -8, -8, -4,
- 4, 16, 30, 38, 42, 46, 45, 38, 25, 10, -7, -24, -39, -51, -58, -59,
- -53, -43, -34, -28, -21, -9, 5, 15, 17, 16, 15, 16, 15, 10, 2, -10,
- -17, -21, -26, -33, -38, -40, -37, -34, -33, -28, -17, 0, 15, 29, 40, 48,
- 50, 48, 44, 40, 34, 26, 15, 3, -6, -11, -11, -4, 7, 18, 24, 30,
- 36, 38, 35, 31, 24, 13, -7, -25, -40, -50, -53, -51, -47, -41, -38, -33,
- -25, -10, 4, 14, 19, 21, 22, 19, 19, 17, 7, -5, -15, -23, -31, -39,
- -46, -49, -49, -46, -41, -33, -19, 0, 21, 39, 53, 61, 64, 63, 56, 50,
- 42, 31, 15, -2, -13, -19, -19, -11, 0, 10, 15, 19, 27, 33, 37, 35,
- 25, 9, -13, -28, -38, -44, -46, -50, -53, -51, -46, -38, -23, -7, 10, 20,
- 21, 24, 25, 28, 28, 19, 8, -7, -18, -28, -36, -43, -52, -56, -57, -51,
- -44, -31, -13, 7, 29, 46, 60, 66, 71, 68, 61, 54, 45, 32, 13, -5,
- -17, -22, -20, -15, -8, -2, 8, 14, 24, 31, 35, 32, 21, 4, -13, -24,
- -34, -42, -49, -55, -58, -54, -48, -38, -23, -4, 14, 26, 32, 31, 32, 36,
- 34, 23, 7, -12, -25, -35, -47, -61, -68, -68, -61, -53, -42, -26, -7, 22,
- 45, 61, 71, 75, 78, 74, 66, 56, 42, 24, 7, -13, -24, -29, -25, -18,
- -11, -7, 2, 14, 27, 36, 38, 32, 19, 1, -14, -22, -33, -44, -56, -64,
- -65, -60, -47, -32, -16, 3, 18, 31, 37, 37, 38, 41, 35, 20, 0, -18,
- -31, -43, -56, -64, -69, -68, -60, -50, -36, -15, 6, 31, 50, 62, 71, 77,
- 78, 74, 66, 54, 38, 20, 2, -15, -23, -26, -24, -22, -17, -7, 8, 20,
- 29, 35, 33, 25, 13, -2, -14, -29, -42, -57, -67, -72, -67, -57, -42, -24,
- -5, 13, 31, 43, 46, 47, 48, 43, 32, 14, -5, -22, -40, -55, -63, -68,
- -69, -66, -57, -44, -25, -5, 18, 37, 55, 66, 75, 78, 75, 70, 62, 47,
- 28, 9, -7, -19, -27, -30, -27, -21, -11, 5, 18, 28, 34, 36, 32, 24,
- 12, -4, -20, -38, -55, -68, -75, -71, -65, -53, -35, -14, 6, 24, 39, 47,
- 50, 48, 44, 36, 22, 5, -16, -34, -47, -56, -60, -60, -59, -54, -45, -28,
- -9, 9, 25, 41, 53, 63, 67, 66, 65, 62, 54, 40, 22, 6, -8, -16,
- -22, -23, -20, -11, 1, 13, 22, 27, 29, 26, 24, 15, 2, -15, -33, -49,
- -64, -74, -74, -67, -55, -39, -20, -2, 16, 32, 45, 50, 49, 43, 35, 26,
- 11, -9, -25, -35, -44, -49, -52, -54, -50, -39, -26, -12, 1, 14, 27, 39,
- 48, 53, 55, 57, 56, 48, 36, 25, 15, 6, -5, -12, -17, -14, -8, 3,
- 14, 21, 26, 23, 21, 21, 14, 3, -11, -26, -44, -61, -72, -72, -68, -56,
- -42, -25, -11, 7, 24, 37, 44, 44, 40, 33, 25, 13, 0, -12, -24, -32,
- -39, -41, -39, -36, -30, -24, -18, -10, 1, 11, 21, 29, 36, 41, 47, 51,
- 51, 42, 35, 27, 19, 10, 1, -6, -10, -9, -2, 6, 11, 13, 13, 15,
- 14, 10, 4, -9, -19, -31, -45, -58, -67, -68, -56, -43, -31, -20, -9, 7,
- 21, 31, 35, 35, 33, 27, 18, 7, -3, -9, -13, -20, -27, -32, -33, -29,
- -23, -19, -16, -12, -4, 6, 15, 23, 30, 39, 47, 49, 42, 35, 31, 27,
- 22, 14, 2, -8, -9, -4, 5, 8, 8, 9, 7, 6, 3, 0, -5, -12,
- -22, -35, -50, -58, -58, -50, -39, -32, -26, -19, -8, 7, 21, 26, 27, 25,
- 22, 18, 11, 5, 2, 1, -3, -10, -19, -24, -23, -16, -15, -17, -20, -17,
- -10, -2, 6, 12, 21, 32, 44, 45, 38, 30, 27, 31, 31, 21, 8, 1,
- 0, 2, 8, 10, 7, 1, -3, -2, -4, -9, -12, -17, -25, -37, -47, -53,
- -50, -42, -32, -27, -26, -22, -11, 5, 15, 18, 20, 22, 23, 22, 18, 15,
- 14, 11, 7, -3, -14, -18, -17, -18, -22, -27, -27, -21, -14, -6, 3, 12,
- 24, 34, 40, 39, 35, 32, 31, 34, 30, 19, 10, 4, 2, 5, 7, 7,
- 1, -6, -10, -9, -8, -8, -11, -16, -25, -34, -41, -41, -36, -32, -33, -33,
- -29, -22, -11, -2, 6, 13, 17, 22, 23, 22, 22, 24, 23, 20, 12, 0,
- -7, -11, -14, -20, -26, -28, -26, -22, -15, -9, 2, 13, 25, 32, 33, 35,
- 36, 37, 38, 35, 29, 19, 9, 5, 7, 6, 4, -3, -9, -12, -11, -6,
- -4, -5, -10, -17, -26, -33, -37, -38, -38, -38, -41, -39, -31, -20, -9, -2,
- 6, 15, 23, 31, 31, 31, 30, 29, 28, 21, 13, 2, -9, -17, -20, -23,
- -26, -27, -26, -20, -14, -6, 6, 14, 22, 26, 32, 34, 35, 37, 37, 36,
- 27, 15, 6, 6, 7, 5, -3, -13, -17, -17, -11, -5, -5, -6, -11, -18,
- -24, -27, -30, -35, -40, -44, -44, -39, -28, -16, -6, 1, 9, 20, 31, 34,
- 36, 37, 36, 33, 23, 14, 5, -3, -10, -17, -23, -30, -34, -31, -22, -14,
- -8, 0, 7, 15, 20, 26, 30, 35, 40, 40, 34, 27, 18, 14, 9, 8,
- 5, -2, -11, -15, -13, -8, -4, 0, 1, -6, -12, -18, -23, -29, -38, -45,
- -52, -53, -47, -37, -28, -16, -5, 6, 17, 28, 37, 42, 43, 40, 37, 31,
- 19, 8, 1, -7, -14, -22, -27, -33, -34, -28, -18, -8, 0, 5, 10, 14,
- 19, 25, 33, 38, 39, 35, 27, 18, 13, 9, 8, 4, -3, -8, -12, -13,
- -10, -4, 4, 4, -2, -7, -14, -21, -28, -36, -45, -53, -54, -50, -44, -34,
- -20, -5, 7, 18, 28, 37, 39, 42, 40, 35, 28, 17, 7, 0, -7, -12,
- -18, -23, -28, -28, -23, -17, -8, 2, 8, 9, 10, 12, 17, 25, 32, 33,
- 28, 20, 13, 10, 10, 8, 6, 5, 1, -5, -6, -3, 3, 10, 10, 5,
- -6, -15, -21, -28, -38, -49, -59, -62, -59, -51, -39, -25, -8, 7, 17, 28,
- 37, 42, 44, 43, 38, 30, 17, 7, 0, -4, -10, -16, -24, -26, -27, -21,
- -14, -9, -2, 5, 11, 14, 12, 13, 19, 26, 29, 26, 19, 13, 8, 8,
- 9, 5, 2, 2, 4, 3, 1, 1, 5, 8, 7, 0, -10, -18, -25, -32,
- -42, -52, -56, -53, -48, -38, -29, -14, 1, 14, 23, 30, 33, 33, 35, 33,
- 26, 17, 9, 2, 1, 0, -5, -12, -19, -22, -21, -13, -8, -4, 5, 10,
- 12, 10, 10, 14, 21, 25, 24, 15, 5, 3, 5, 7, 5, 2, 5, 10,
- 12, 10, 9, 11, 13, 10, 2, -8, -18, -25, -32, -40, -50, -55, -53, -45,
- -35, -27, -17, -4, 11, 20, 28, 30, 28, 29, 30, 28, 19, 10, 6, 6,
- 5, 0, -10, -18, -20, -18, -14, -11, -10, -4, 6, 13, 13, 11, 13, 20,
- 25, 24, 15, 7, 3, 4, 5, 4, 0, 3, 9, 14, 15, 11, 9, 8,
- 8, 6, -5, -16, -24, -29, -35, -43, -48, -47, -42, -31, -23, -17, -7, 5,
- 17, 24, 26, 22, 19, 19, 20, 17, 11, 5, 2, 2, 0, -4, -10, -14,
- -14, -10, -8, -6, 1, 10, 19, 23, 22, 17, 16, 19, 18, 11, 1, -8,
- -11, -10, -7, -4, 1, 7, 15, 22, 22, 18, 17, 16, 12, 4, -8, -21,
- -29, -34, -39, -46, -49, -46, -37, -28, -19, -9, -2, 8, 19, 22, 20, 18,
- 18, 19, 19, 12, 6, 3, 2, 0, -5, -10, -16, -18, -14, -9, -8, -3,
- 6, 17, 25, 27, 26, 24, 25, 22, 15, 3, -8, -13, -13, -12, -11, -6,
- 0, 9, 16, 19, 19, 16, 13, 10, 6, -5, -14, -22, -26, -32, -37, -41,
- -39, -32, -23, -17, -14, -10, -3, 9, 17, 18, 10, 7, 10, 16, 18, 12,
- 5, 1, 1, -4, -13, -18, -18, -15, -12, -11, -10, 1, 15, 29, 37, 35,
- 31, 30, 30, 24, 11, -8, -18, -18, -15, -17, -20, -17, -6, 8, 15, 18,
- 16, 15, 11, 12, 8, 0, -10, -16, -20, -28, -35, -38, -33, -27, -23, -21,
- -19, -13, 0, 11, 14, 12, 9, 11, 18, 21, 19, 10, 2, -3, -5, -12,
- -21, -28, -26, -20, -15, -12, -6, 9, 25, 38, 43, 42, 40, 38, 34, 23,
- 6, -12, -18, -18, -18, -23, -25, -22, -13, 0, 7, 9, 8, 8, 11, 12,
- 9, 6, 2, -5, -14, -21, -24, -24, -22, -22, -21, -22, -20, -12, -3, 4,
- 5, 5, 6, 11, 15, 16, 10, 4, -2, -7, -11, -20, -25, -27, -21, -13,
- -11, -5, 6, 22, 37, 46, 50, 49, 44, 39, 31, 16, -3, -15, -21, -24,
- -27, -32, -33, -28, -17, -5, 5, 7, 7, 10, 15, 16, 15, 10, 4, -4,
- -11, -18, -22, -22, -20, -22, -21, -21, -17, -10, 1, 6, 9, 10, 15, 19,
- 18, 12, 5, 0, -9, -15, -23, -31, -36, -32, -24, -17, -11, -4, 12, 31,
- 47, 53, 58, 60, 56, 49, 35, 15, -4, -16, -21, -25, -32, -42, -45, -35,
- -23, -14, -8, 0, 6, 13, 20, 21, 19, 15, 9, 1, -6, -11, -13, -16,
- -18, -20, -23, -20, -14, -8, 0, 2, 5, 11, 18, 18, 14, 6, -2, -10,
- -18, -27, -34, -41, -40, -31, -20, -12, -7, 4, 23, 47, 64, 71, 71, 63,
- 56, 46, 30, 12, -7, -22, -35, -42, -49, -52, -48, -34, -22, -14, -7, 3,
- 15, 24, 27, 27, 24, 15, 6, -4, -8, -11, -13, -13, -15, -16, -14, -12,
- -7, -2, 3, 10, 12, 14, 15, 7, 0, -7, -16, -25, -32, -40, -44, -44,
- -36, -24, -11, 0, 6, 16, 36, 58, 72, 76, 71, 62, 51, 38, 24, 5,
- -13, -30, -42, -50, -52, -53, -46, -33, -21, -15, -6, 7, 20, 25, 25, 21,
- 18, 14, 7, 2, -5, -9, -9, -7, -8, -9, -10, -7, -3, 1, 6, 7,
- 8, 9, 6, -2, -13, -23, -30, -35, -41, -45, -44, -38, -26, -15, -3, 11,
- 19, 33, 52, 69, 75, 72, 65, 54, 42, 29, 13, -6, -25, -41, -49, -54,
- -55, -48, -38, -26, -18, -8, 1, 13, 24, 29, 26, 19, 11, 5, 2, -2,
- -6, -6, -6, -5, -7, -5, 1, 5, 9, 11, 8, 8, 7, 4, -6, -17,
- -28, -35, -42, -47, -48, -45, -39, -29, -16, -5, 7, 18, 32, 45, 57, 64,
- 67, 62, 54, 45, 35, 22, 5, -13, -28, -40, -47, -49, -46, -42, -32, -21,
- -11, -4, 6, 15, 21, 21, 16, 12, 6, 1, -3, -5, -3, 3, 8, 9,
- 8, 7, 7, 11, 12, 11, 6, -2, -9, -13, -20, -29, -40, -47, -47, -45,
- -42, -37, -29, -16, -5, 7, 17, 27, 38, 48, 56, 59, 53, 44, 40, 37,
- 30, 17, -2, -16, -25, -32, -35, -36, -35, -31, -23, -16, -10, -3, 4, 10,
- 11, 8, 1, 0, 0, 0, 0, 1, 6, 14, 20, 21, 19, 15, 14, 13,
- 11, 7, 0, -13, -21, -28, -37, -46, -51, -48, -43, -37, -32, -28, -21, -9,
- 4, 17, 27, 32, 40, 45, 50, 51, 46, 40, 38, 35, 27, 12, -3, -13,
- -23, -27, -29, -30, -29, -28, -23, -15, -10, -5, 2, 5, 5, 1, -2, -2,
- 1, 4, 4, 8, 14, 19, 25, 26, 21, 15, 13, 12, 12, 5, -9, -21,
- -30, -37, -43, -50, -51, -47, -42, -38, -34, -27, -17, -5, 10, 22, 30, 38,
- 44, 49, 50, 46, 40, 37, 38, 33, 19, 4, -8, -14, -18, -22, -24, -24,
- -22, -18, -16, -14, -10, -6, 1, 1, -6, -8, -9, -6, 0, 2, 8, 14,
- 21, 28, 31, 27, 24, 21, 20, 16, 9, -3, -16, -26, -33, -42, -50, -55,
- -56, -50, -43, -39, -38, -29, -13, 6, 18, 27, 33, 42, 51, 54, 53, 48,
- 41, 39, 38, 29, 12, -5, -15, -19, -20, -23, -24, -22, -18, -17, -13, -12,
- -10, -4, -3, -4, -7, -8, -9, -9, -7, 2, 9, 14, 21, 26, 27, 27,
- 22, 20, 19, 17, 12, 1, -14, -25, -35, -41, -45, -50, -53, -54, -51, -47,
- -41, -31, -18, -3, 12, 24, 35, 47, 55, 58, 57, 55, 49, 46, 40, 26,
- 11, -5, -17, -22, -23, -23, -22, -21, -21, -18, -15, -9, -5, -3, -4, -6,
- -7, -9, -12, -12, -8, 1, 7, 13, 14, 19, 23, 27, 26, 25, 25, 20,
- 13, 4, -9, -22, -36, -42, -48, -55, -61, -62, -59, -54, -43, -32, -18, 0,
- 18, 35, 49, 57, 60, 62, 63, 61, 57, 48, 33, 15, -2, -15, -24, -28,
- -27, -22, -23, -24, -21, -13, -4, 3, 3, 1, -2, -4, -4, -9, -15, -16,
- -13, -9, -5, 2, 7, 11, 19, 24, 28, 31, 29, 28, 24, 12, -4, -21,
- -33, -38, -48, -61, -72, -76, -71, -61, -47, -34, -20, 2, 26, 45, 58, 65,
- 69, 74, 75, 68, 55, 41, 28, 13, -7, -22, -32, -32, -29, -24, -23, -22,
- -19, -7, 6, 7, 2, -2, -3, 0, -3, -10, -20, -24, -19, -12, -5, 1,
- 5, 14, 23, 30, 33, 37, 39, 36, 24, 8, -10, -25, -33, -43, -55, -71,
- -82, -82, -71, -57, -44, -29, -11, 13, 34, 52, 64, 70, 73, 77, 76, 65,
- 50, 35, 20, 4, -13, -26, -31, -32, -27, -26, -25, -21, -10, 2, 8, 5,
- 3, 0, 1, 2, -3, -12, -22, -24, -21, -16, -9, -3, 6, 14, 22, 28,
- 34, 41, 42, 35, 23, 6, -10, -21, -32, -45, -61, -76, -85, -82, -70, -54,
- -43, -29, -7, 18, 40, 55, 64, 71, 77, 81, 76, 62, 48, 32, 19, 6,
- -10, -23, -30, -29, -28, -30, -27, -20, -10, -2, 3, 1, 0, 3, 6, 4,
- -9, -18, -24, -22, -18, -14, -8, 0, 8, 16, 24, 32, 38, 42, 42, 31,
- 15, -2, -14, -25, -38, -52, -67, -81, -85, -76, -63, -49, -37, -19, 3, 26,
- 43, 57, 67, 75, 82, 79, 70, 56, 41, 28, 15, 1, -12, -22, -27, -27,
- -28, -26, -21, -12, -3, 3, -2, -2, 1, 3, 1, -12, -22, -28, -29, -27,
- -23, -18, -11, 3, 16, 25, 34, 44, 51, 52, 43, 27, 12, -2, -17, -34,
- -51, -71, -82, -86, -83, -75, -61, -45, -27, -7, 16, 37, 53, 63, 72, 78,
- 77, 68, 60, 45, 33, 20, 10, -2, -9, -15, -18, -22, -23, -19, -15, -8,
- -5, -7, -8, -7, -4, -3, -10, -22, -29, -29, -24, -21, -18, -14, -3, 12,
- 23, 27, 35, 44, 49, 47, 34, 18, 1, -11, -23, -40, -57, -73, -81, -80,
- -74, -64, -50, -36, -19, 2, 22, 38, 49, 61, 69, 74, 69, 60, 50, 40,
- 29, 20, 10, 2, -5, -9, -12, -16, -18, -14, -9, -6, -10, -13, -12, -10,
- -11, -15, -23, -30, -31, -27, -25, -23, -19, -8, 8, 20, 28, 36, 45, 49,
- 49, 41, 29, 15, -2, -15, -31, -49, -65, -76, -79, -77, -67, -55, -43, -30,
- -13, 7, 25, 40, 51, 60, 66, 66, 62, 54, 45, 37, 29, 22, 14, 7,
- 3, -3, -7, -10, -12, -10, -8, -12, -18, -19, -16, -13, -15, -23, -31, -33,
- -29, -26, -25, -23, -15, 1, 14, 23, 31, 40, 50, 52, 46, 36, 21, 7,
- -8, -24, -41, -58, -70, -75, -74, -67, -57, -43, -30, -18, -3, 13, 26, 39,
- 48, 56, 60, 58, 51, 45, 42, 36, 29, 25, 20, 14, 9, 6, 3, 0,
- -5, -6, -12, -17, -22, -21, -20, -24, -33, -37, -38, -35, -30, -28, -24, -17,
- -3, 12, 24, 33, 43, 50, 52, 49, 40, 28, 13, -3, -18, -34, -51, -63,
- -71, -72, -67, -59, -49, -37, -24, -10, 3, 16, 27, 37, 46, 50, 53, 51,
- 49, 46, 43, 37, 32, 29, 25, 21, 17, 10, 4, -3, -8, -10, -11, -18,
- -25, -29, -31, -34, -37, -40, -40, -37, -31, -25, -20, -13, 0, 17, 31, 41,
- 48, 50, 49, 46, 36, 22, 8, -5, -20, -36, -49, -61, -67, -67, -61, -51,
- -44, -36, -23, -9, 4, 13, 20, 30, 38, 46, 48, 47, 44, 44, 44, 46,
- 42, 35, 31, 28, 24, 15, 5, -3, -6, -10, -18, -28, -35, -39, -41, -41,
- -43, -45, -42, -36, -29, -23, -15, 1, 15, 28, 40, 47, 51, 51, 46, 37,
- 27, 14, 2, -14, -29, -42, -49, -54, -62, -63, -57, -49, -41, -31, -21, -12,
- -3, 6, 17, 25, 32, 40, 45, 49, 50, 48, 49, 49, 48, 44, 39, 34,
- 26, 13, 4, -4, -11, -17, -23, -32, -41, -48, -48, -49, -48, -44, -39, -36,
- -31, -21, -5, 13, 24, 35, 44, 51, 52, 47, 39, 30, 21, 8, -6, -18,
- -34, -44, -50, -54, -59, -58, -53, -46, -38, -28, -18, -10, -4, 6, 16, 24,
- 30, 37, 42, 48, 49, 47, 48, 51, 51, 49, 45, 35, 27, 17, 9, 0,
- -12, -23, -32, -41, -48, -53, -55, -54, -53, -49, -43, -38, -27, -13, 5, 20,
- 33, 44, 52, 58, 57, 50, 40, 29, 16, 5, -11, -29, -43, -53, -56, -62,
- -65, -63, -54, -42, -33, -24, -16, -8, 3, 16, 23, 29, 33, 38, 44, 46,
- 45, 43, 45, 49, 52, 48, 42, 37, 28, 19, 10, 0, -13, -25, -36, -42,
- -47, -56, -58, -56, -53, -49, -48, -40, -26, -6, 13, 27, 39, 49, 59, 64,
- 62, 53, 42, 29, 16, 2, -18, -37, -52, -60, -65, -71, -75, -68, -55, -41,
- -30, -19, -10, 0, 14, 24, 33, 37, 38, 39, 42, 45, 45, 43, 45, 48,
- 47, 46, 41, 35, 28, 19, 8, -6, -20, -30, -38, -44, -50, -55, -57, -59,
- -57, -53, -46, -35, -19, 0, 17, 32, 45, 59, 66, 66, 59, 54, 46, 32,
- 15, -5, -24, -43, -57, -65, -71, -76, -78, -71, -58, -41, -27, -16, -5, 5,
- 15, 27, 37, 43, 43, 42, 42, 42, 43, 46, 46, 46, 45, 42, 41, 35,
- 28, 18, 7, -6, -18, -29, -37, -44, -51, -56, -59, -61, -60, -55, -45, -33,
- -18, -2, 18, 37, 50, 61, 67, 68, 65, 59, 47, 31, 10, -11, -32, -47,
- -58, -71, -81, -86, -83, -70, -52, -36, -21, -9, 2, 13, 25, 35, 41, 44,
- 43, 40, 39, 39, 40, 43, 43, 40, 39, 40, 40, 36, 28, 18, 9, -5,
- -18, -28, -36, -44, -52, -57, -61, -64, -63, -56, -43, -27, -13, 6, 26, 44,
- 56, 66, 71, 71, 64, 55, 42, 23, 3, -19, -38, -52, -66, -76, -82, -86,
- -81, -67, -49, -32, -19, -8, 3, 15, 28, 36, 42, 43, 43, 41, 41, 40,
- 40, 41, 40, 40, 41, 41, 36, 30, 24, 17, 10, -5, -19, -29, -37, -43,
- -50, -57, -64, -66, -60, -50, -40, -28, -10, 12, 32, 45, 54, 59, 64, 67,
- 63, 54, 35, 14, -6, -22, -35, -50, -64, -75, -82, -81, -73, -59, -46, -33,
- -21, -8, 5, 19, 27, 33, 40, 44, 44, 42, 40, 42, 41, 40, 38, 39,
- 38, 38, 35, 30, 21, 13, 4, -8, -16, -25, -35, -45, -53, -62, -65, -63,
- -56, -47, -39, -25, -6, 15, 32, 45, 53, 58, 64, 65, 60, 48, 30, 9,
- -7, -19, -31, -47, -60, -72, -79, -79, -73, -61, -50, -37, -24, -10, 3, 12,
- 22, 33, 43, 47, 46, 44, 43, 45, 46, 45, 45, 43, 41, 38, 34, 26,
- 16, 7, -2, -10, -19, -29, -39, -50, -59, -64, -62, -58, -51, -44, -34, -22,
- -2, 16, 30, 41, 52, 56, 57, 58, 54, 42, 29, 13, 2, -12, -27, -42,
- -56, -67, -71, -73, -70, -63, -55, -42, -26, -10, 2, 11, 20, 33, 41, 46,
- 45, 43, 49, 53, 52, 48, 44, 43, 42, 38, 33, 22, 12, 4, -5, -13,
- -23, -34, -43, -50, -57, -61, -60, -55, -49, -40, -29, -14, -2, 12, 25, 35,
- 44, 51, 56, 56, 49, 39, 30, 20, 10, -2, -17, -32, -48, -60, -67, -74,
- -77, -74, -66, -50, -36, -21, -9, 0, 14, 30, 43, 51, 53, 57, 62, 64,
- 62, 58, 53, 48, 42, 36, 25, 12, 4, -4, -12, -21, -31, -38, -43, -45,
- -47, -49, -47, -44, -40, -34, -28, -22, -11, 1, 11, 21, 28, 39, 49, 53,
- 52, 49, 44, 38, 29, 16, -4, -24, -41, -57, -74, -86, -90, -86, -73, -59,
- -44, -30, -16, 1, 21, 40, 54, 61, 66, 67, 71, 72, 65, 57, 49, 41,
- 33, 24, 12, 1, -8, -12, -15, -22, -31, -37, -35, -31, -33, -36, -39, -40,
- -38, -34, -32, -29, -24, -14, -2, 11, 24, 36, 48, 56, 61, 63, 59, 54,
- 44, 27, 6, -19, -46, -68, -84, -94, -99, -98, -90, -72, -51, -30, -15, 1,
- 22, 46, 64, 76, 78, 80, 81, 78, 72, 60, 45, 34, 24, 13, 0, -13,
- -18, -18, -18, -22, -28, -29, -24, -19, -19, -26, -33, -38, -40, -40, -41, -42,
- -41, -32, -15, 6, 22, 37, 50, 62, 74, 79, 76, 65, 50, 30, 6, -24,
- -54, -78, -94, -106, -110, -103, -89, -69, -49, -29, -10, 11, 36, 57, 73, 78,
- 80, 82, 83, 77, 66, 51, 37, 24, 14, 5, -5, -12, -17, -17, -17, -18,
- -19, -17, -13, -13, -19, -28, -37, -44, -44, -48, -53, -59, -54, -35, -12, 11,
- 29, 46, 61, 78, 88, 90, 84, 68, 49, 24, -6, -39, -71, -92, -104, -115,
- -116, -108, -89, -66, -43, -21, 1, 24, 49, 68, 78, 82, 81, 81, 79, 71,
- 56, 37, 24, 15, 6, -4, -9, -11, -9, -6, -6, -10, -11, -6, -4, -8,
- -20, -33, -44, -55, -61, -65, -70, -68, -55, -31, -6, 15, 38, 61, 82, 97,
- 101, 94, 80, 61, 37, 9, -25, -60, -88, -107, -119, -123, -116, -99, -77, -53,
- -30, -5, 20, 47, 68, 80, 82, 82, 80, 77, 70, 57, 40, 23, 10, 3,
- -2, -3, -4, -3, 2, 5, 7, 5, 5, 4, -4, -17, -32, -45, -60, -69,
- -74, -79, -80, -70, -47, -20, 9, 32, 55, 76, 94, 104, 103, 91, 71, 46,
- 16, -16, -48, -75, -97, -115, -121, -117, -101, -80, -57, -32, -8, 15, 39, 58,
- 68, 73, 73, 73, 69, 61, 50, 39, 26, 15, 7, 4, 7, 12, 18, 19,
- 20, 18, 17, 15, 10, -4, -20, -41, -57, -68, -77, -85, -91, -90, -76, -53,
- -25, 2, 28, 55, 79, 97, 106, 104, 94, 77, 52, 22, -9, -39, -67, -92,
- -111, -119, -115, -99, -79, -55, -33, -11, 15, 37, 55, 67, 71, 68, 61, 51,
- 44, 40, 35, 24, 10, 3, 4, 13, 25, 36, 42, 41, 34, 29, 20, 12,
- -2, -21, -43, -66, -84, -94, -96, -96, -93, -81, -55, -26, 4, 30, 56, 80,
- 98, 107, 106, 95, 77, 53, 24, -8, -38, -64, -85, -101, -109, -109, -100, -80,
- -55, -31, -8, 13, 31, 46, 56, 61, 59, 52, 43, 36, 30, 25, 16, 8,
- 7, 11, 23, 37, 48, 56, 59, 56, 48, 33, 17, -5, -29, -54, -79, -96,
- -106, -109, -105, -96, -82, -57, -25, 8, 38, 61, 79, 94, 103, 102, 92, 73,
- 46, 19, -10, -36, -62, -81, -95, -101, -100, -90, -71, -47, -25, -3, 18, 31,
- 41, 49, 53, 50, 42, 32, 21, 13, 9, 7, 8, 8, 12, 30, 49, 63,
- 71, 76, 75, 67, 48, 25, -3, -30, -59, -87, -107, -120, -124, -117, -105, -89,
- -63, -31, 5, 40, 63, 81, 92, 100, 100, 88, 69, 46, 20, -6, -31, -55,
- -73, -87, -91, -88, -80, -64, -45, -22, 1, 16, 27, 34, 39, 45, 41, 31,
- 20, 9, 4, 3, 1, 3, 6, 15, 32, 53, 71, 81, 85, 86, 78, 61,
- 35, 3, -29, -63, -93, -113, -124, -128, -124, -110, -89, -64, -32, 5, 38, 62,
- 80, 91, 98, 93, 80, 63, 42, 19, -5, -29, -51, -68, -78, -81, -79, -72,
- -58, -40, -19, 0, 13, 21, 29, 35, 35, 29, 21, 14, 8, 2, -2, -3,
- 1, 10, 20, 36, 56, 73, 84, 89, 89, 81, 65, 41, 6, -32, -63, -90,
- -110, -124, -127, -123, -110, -89, -61, -30, 2, 33, 56, 71, 81, 86, 85, 74,
- 58, 38, 17, -5, -21, -38, -52, -62, -69, -69, -64, -50, -34, -18, -5, 5,
- 13, 23, 28, 27, 22, 15, 10, 6, 1, 0, -2, 2, 9, 23, 41, 56,
- 72, 84, 88, 89, 81, 66, 45, 15, -20, -55, -84, -106, -119, -121, -116, -105,
- -89, -67, -38, -7, 21, 44, 58, 69, 75, 74, 64, 50, 36, 22, 8, -10,
- -26, -39, -47, -54, -56, -53, -47, -36, -25, -11, -2, 5, 14, 23, 24, 20,
- 12, 7, 6, 6, 6, 4, 5, 10, 22, 39, 57, 72, 80, 82, 80, 73,
- 62, 45, 18, -13, -48, -78, -96, -105, -105, -104, -97, -81, -64, -40, -15, 10,
- 28, 40, 49, 54, 53, 49, 42, 31, 22, 13, 2, -9, -17, -22, -30, -38,
- -40, -37, -33, -28, -22, -16, -10, -5, 5, 11, 11, 6, 3, 5, 11, 16,
- 16, 18, 22, 29, 40, 54, 68, 75, 74, 72, 63, 49, 35, 15, -10, -37,
- -63, -83, -94, -95, -89, -82, -73, -63, -46, -24, -2, 16, 25, 31, 35, 39,
- 41, 37, 30, 22, 15, 11, 4, -3, -11, -18, -25, -31, -35, -33, -28, -22,
- -18, -16, -13, -4, 5, 10, 11, 10, 5, 6, 14, 21, 23, 24, 27, 33,
- 45, 59, 68, 72, 67, 57, 46, 34, 19, 0, -24, -49, -70, -81, -82, -77,
- -70, -65, -60, -49, -34, -15, 2, 9, 13, 14, 18, 20, 21, 19, 18, 17,
- 16, 15, 13, 10, 5, -3, -12, -20, -26, -28, -27, -24, -26, -25, -18, -9,
- 3, 9, 10, 10, 11, 18, 27, 32, 33, 33, 35, 42, 51, 58, 59, 55,
- 46, 36, 25, 16, 3, -15, -33, -50, -61, -65, -64, -59, -57, -56, -52, -42,
- -29, -14, -5, -2, -3, 1, 8, 12, 13, 13, 16, 16, 18, 19, 19, 14,
- 4, -3, -10, -19, -24, -24, -22, -20, -24, -23, -16, -2, 10, 16, 14, 13,
- 16, 28, 35, 36, 35, 32, 33, 40, 45, 49, 47, 41, 31, 20, 12, 4,
- -8, -16, -29, -41, -50, -53, -50, -49, -51, -51, -48, -40, -30, -20, -13, -13,
- -12, -6, 2, 8, 12, 13, 16, 21, 26, 27, 23, 15, 8, 0, -10, -19,
- -23, -24, -24, -26, -25, -21, -9, 5, 15, 19, 20, 22, 28, 36, 39, 38,
- 36, 33, 33, 35, 37, 38, 36, 30, 20, 9, 4, -3, -10, -17, -26, -35,
- -40, -45, -47, -51, -52, -49, -46, -39, -30, -23, -19, -17, -12, -5, 1, 4,
- 7, 11, 18, 22, 22, 22, 20, 17, 12, 3, -8, -16, -18, -16, -17, -19,
- -18, -12, 3, 13, 19, 20, 24, 29, 34, 35, 33, 32, 31, 31, 30, 26,
- 24, 24, 25, 21, 14, 6, 0, -4, -5, -10, -19, -31, -37, -40, -47, -51,
- -50, -49, -45, -39, -31, -25, -19, -12, -6, -3, 0, 2, 6, 13, 17, 18,
- 16, 15, 16, 14, 7, -3, -10, -12, -13, -13, -14, -13, -6, 6, 18, 24,
- 25, 26, 29, 33, 32, 26, 24, 23, 23, 22, 18, 14, 15, 21, 24, 22,
- 14, 6, 4, 4, 1, -9, -21, -32, -41, -47, -50, -54, -54, -51, -47, -37,
- -30, -21, -10, -3, 1, 4, 6, 7, 8, 7, 7, 7, 7, 6, 6, 5,
- 2, -3, -8, -8, -6, -3, 1, 3, 9, 17, 25, 29, 32, 33, 29, 26,
- 24, 23, 20, 17, 14, 11, 8, 8, 14, 21, 22, 17, 13, 9, 9, 7,
- 1, -11, -25, -37, -44, -52, -53, -55, -55, -51, -43, -35, -24, -14, -4, 3,
- 4, 4, 6, 7, 6, 3, -2, -2, 2, 6, 5, 1, -4, -8, -7, -5,
- 3, 9, 9, 12, 17, 25, 32, 37, 37, 32, 25, 21, 19, 17, 15, 9,
- 6, 6, 6, 8, 14, 23, 24, 20, 15, 14, 11, 3, -6, -18, -31, -44,
- -53, -54, -57, -58, -55, -47, -37, -26, -16, -4, 7, 10, 10, 9, 7, 3,
- -2, -6, -8, -6, -5, -4, -7, -10, -8, -6, 0, 6, 12, 16, 20, 27,
- 33, 35, 35, 36, 34, 28, 21, 16, 10, 7, 7, 5, 3, 1, 5, 12,
- 21, 25, 23, 17, 14, 13, 9, -3, -17, -30, -41, -50, -54, -59, -61, -55,
- -46, -37, -26, -15, -4, 7, 14, 15, 12, 6, 1, -3, -7, -12, -14, -15,
- -13, -12, -12, -12, -8, 0, 8, 15, 20, 25, 31, 36, 40, 41, 41, 38,
- 33, 27, 21, 12, 4, 1, 0, -4, -5, -2, 5, 12, 17, 19, 19, 18,
- 14, 11, 2, -9, -21, -32, -42, -49, -55, -57, -56, -49, -39, -30, -20, -8,
- 3, 12, 17, 18, 12, 5, -2, -8, -14, -18, -21, -22, -21, -21, -19, -13,
- -7, 4, 14, 24, 32, 39, 44, 48, 47, 44, 41, 38, 33, 27, 17, 7,
- -3, -5, -5, -5, -5, -5, 3, 12, 17, 19, 16, 11, 7, 3, -6, -15,
- -26, -36, -42, -48, -53, -54, -50, -40, -31, -22, -12, -2, 11, 19, 20, 13,
- 6, 2, -5, -12, -21, -26, -29, -31, -30, -27, -21, -13, -2, 12, 25, 36,
- 48, 57, 62, 60, 51, 46, 43, 37, 28, 15, 3, -8, -12, -14, -12, -10,
- -7, -4, 8, 16, 20, 17, 14, 10, 6, -2, -12, -24, -32, -39, -45, -51,
- -54, -52, -43, -32, -21, -12, -2, 11, 22, 28, 24, 13, 4, -6, -14, -23,
- -32, -38, -41, -42, -39, -31, -20, -8, 6, 21, 37, 50, 63, 69, 68, 61,
- 55, 48, 39, 29, 20, 9, -6, -15, -17, -13, -11, -7, -4, 3, 11, 13,
- 16, 15, 10, 5, 0, -8, -15, -25, -31, -37, -42, -49, -52, -46, -37, -30,
- -21, -12, 0, 14, 25, 28, 25, 15, 2, -11, -22, -29, -36, -44, -49, -49,
- -43, -32, -18, -5, 13, 30, 50, 66, 74, 75, 71, 68, 61, 50, 37, 26,
- 15, 3, -13, -22, -22, -20, -16, -14, -9, 1, 9, 11, 11, 9, 9, 9,
- 6, -3, -15, -25, -32, -37, -41, -50, -53, -50, -41, -30, -20, -8, 6, 21,
- 31, 33, 26, 15, 0, -12, -23, -34, -46, -56, -60, -54, -44, -31, -19, -2,
- 21, 44, 66, 77, 81, 79, 75, 72, 63, 51, 35, 23, 10, -4, -16, -25,
- -28, -26, -22, -16, -12, -7, -2, 4, 8, 10, 14, 14, 7, -3, -12, -20,
- -28, -36, -42, -48, -53, -53, -43, -31, -19, -6, 12, 25, 31, 30, 26, 15,
- -2, -17, -28, -40, -52, -60, -61, -53, -40, -25, -9, 11, 32, 56, 74, 84,
- 85, 81, 76, 72, 61, 46, 29, 13, -2, -16, -23, -29, -33, -31, -25, -19,
- -14, -8, 2, 10, 14, 18, 19, 17, 8, 1, -12, -24, -35, -42, -49, -54,
- -57, -53, -43, -30, -13, 7, 22, 32, 34, 32, 26, 11, -8, -24, -40, -50,
- -60, -66, -63, -53, -36, -17, 2, 23, 45, 67, 84, 90, 91, 85, 78, 72,
- 62, 44, 24, 4, -9, -21, -32, -39, -41, -36, -30, -23, -17, -9, 2, 13,
- 23, 27, 26, 19, 12, 2, -12, -26, -38, -47, -54, -59, -59, -53, -41, -23,
- -5, 14, 28, 36, 36, 31, 21, 6, -13, -31, -46, -58, -66, -70, -65, -50,
- -28, -7, 14, 35, 58, 76, 89, 96, 94, 90, 82, 72, 54, 35, 16, -5,
- -21, -31, -40, -48, -47, -38, -28, -20, -13, 1, 15, 28, 33, 33, 27, 18,
- 8, -6, -21, -37, -52, -64, -66, -65, -58, -47, -30, -9, 13, 28, 38, 43,
- 40, 31, 15, -5, -24, -40, -57, -69, -75, -74, -65, -48, -26, -2, 24, 47,
- 66, 83, 97, 102, 102, 101, 91, 73, 51, 28, 7, -15, -33, -45, -56, -60,
- -54, -42, -28, -17, -4, 13, 26, 36, 38, 36, 29, 16, 2, -14, -34, -52,
- -62, -66, -65, -63, -53, -36, -15, 9, 27, 36, 41, 40, 35, 25, 8, -16,
- -37, -55, -68, -77, -81, -75, -60, -37, -12, 12, 35, 57, 75, 94, 105, 107,
- 103, 97, 84, 64, 41, 18, -6, -25, -40, -51, -57, -56, -46, -32, -19, -6,
- 7, 20, 30, 34, 32, 24, 12, 0, -17, -33, -47, -60, -65, -64, -58, -46,
- -31, -12, 8, 26, 37, 43, 44, 41, 28, 11, -12, -31, -49, -67, -81, -87,
- -85, -72, -52, -30, -6, 21, 45, 69, 87, 101, 110, 113, 110, 100, 77, 51,
- 27, 8, -11, -32, -49, -59, -59, -53, -41, -27, -11, 3, 14, 24, 28, 28,
- 24, 17, 5, -15, -32, -45, -54, -61, -58, -54, -44, -32, -13, 8, 26, 37,
- 41, 40, 36, 29, 16, -3, -24, -47, -66, -81, -89, -88, -76, -58, -37, -16,
- 10, 34, 58, 78, 94, 106, 111, 107, 97, 81, 58, 37, 17, 0, -17, -33,
- -45, -51, -48, -38, -26, -14, -3, 9, 16, 19, 17, 14, 10, 0, -15, -30,
- -42, -49, -52, -49, -44, -37, -25, -8, 9, 21, 29, 32, 35, 33, 29, 19,
- 1, -18, -38, -58, -75, -85, -85, -79, -70, -52, -29, -6, 20, 44, 67, 89,
- 101, 110, 114, 107, 93, 72, 49, 28, 10, -9, -25, -38, -48, -49, -42, -31,
- -20, -11, 0, 9, 13, 12, 7, 5, 0, -11, -24, -36, -42, -44, -43, -38,
- -28, -16, -4, 8, 16, 22, 29, 30, 29, 24, 13, 2, -14, -32, -51, -68,
- -79, -83, -77, -69, -56, -41, -19, 6, 31, 53, 74, 90, 101, 108, 109, 101,
- 83, 60, 38, 24, 9, -10, -25, -36, -40, -37, -29, -21, -13, -8, 0, 3,
- 0, -5, -6, -8, -16, -27, -35, -39, -40, -33, -27, -21, -11, 3, 14, 21,
- 24, 27, 26, 22, 19, 13, 3, -14, -32, -53, -66, -74, -80, -80, -75, -63,
- -47, -28, -4, 19, 41, 66, 85, 99, 105, 106, 104, 95, 76, 51, 29, 13,
- 2, -12, -27, -36, -38, -32, -22, -15, -12, -8, -3, -4, -9, -12, -14, -18,
- -26, -31, -35, -36, -29, -20, -10, -2, 7, 16, 25, 25, 24, 19, 15, 10,
- 4, -4, -16, -30, -44, -57, -67, -73, -75, -70, -60, -48, -34, -16, 5, 27,
- 51, 71, 85, 92, 99, 101, 95, 82, 64, 44, 28, 14, 1, -12, -22, -28,
- -27, -22, -18, -17, -15, -15, -15, -21, -23, -25, -24, -27, -31, -34, -30, -21,
- -6, 7, 13, 17, 22, 27, 28, 24, 16, 7, -3, -10, -17, -27, -35, -43,
- -50, -58, -68, -70, -65, -53, -42, -32, -22, -4, 15, 36, 54, 70, 83, 89,
- 92, 91, 82, 68, 54, 42, 29, 14, 2, -9, -17, -21, -22, -20, -21, -20,
- -23, -26, -30, -32, -32, -29, -27, -28, -30, -26, -15, 0, 15, 25, 25, 25,
- 26, 27, 21, 11, 0, -9, -17, -24, -30, -38, -45, -47, -49, -55, -59, -56,
- -48, -39, -28, -20, -9, 7, 26, 44, 55, 65, 72, 79, 80, 77, 66, 57,
- 49, 41, 30, 19, 7, -2, -7, -12, -17, -22, -25, -29, -33, -36, -39, -41,
- -36, -29, -26, -26, -22, -11, 2, 17, 28, 32, 31, 29, 28, 23, 11, -2,
- -9, -17, -24, -36, -44, -48, -49, -50, -53, -54, -54, -47, -36, -25, -17, -7,
- 7, 21, 36, 47, 55, 63, 70, 72, 69, 60, 52, 46, 42, 34, 23, 15,
- 8, 3, 0, -7, -14, -21, -24, -27, -32, -39, -44, -43, -37, -29, -25, -23,
- -16, -2, 14, 26, 32, 33, 32, 30, 25, 16, 4, -6, -16, -25, -36, -45,
- -50, -54, -51, -51, -54, -54, -48, -36, -23, -15, -6, 5, 17, 31, 42, 51,
- 59, 62, 63, 61, 56, 51, 43, 40, 38, 28, 20, 13, 9, 7, 2, -8,
- -16, -23, -27, -31, -36, -40, -43, -39, -31, -23, -20, -15, -4, 11, 24, 31,
- 32, 31, 30, 25, 17, 7, -3, -13, -23, -36, -48, -56, -58, -57, -53, -50,
- -52, -51, -40, -25, -12, 0, 7, 16, 25, 36, 49, 58, 60, 59, 57, 54,
- 49, 43, 36, 31, 26, 18, 13, 10, 6, 4, 0, -6, -12, -19, -22, -26,
- -31, -35, -35, -32, -27, -22, -16, -7, 4, 13, 21, 26, 30, 29, 27, 22,
- 15, 4, -7, -19, -31, -44, -55, -59, -59, -58, -54, -52, -49, -41, -28, -14,
- 0, 10, 18, 26, 33, 44, 50, 53, 51, 50, 48, 46, 41, 37, 30, 24,
- 21, 18, 15, 13, 8, 4, 0, -6, -9, -14, -19, -23, -27, -33, -33, -31,
- -25, -19, -11, -3, 3, 11, 20, 28, 31, 28, 22, 14, 8, -3, -15, -29,
- -40, -49, -57, -62, -60, -56, -50, -47, -42, -32, -18, -3, 11, 20, 25, 29,
- 35, 43, 49, 51, 47, 43, 41, 37, 33, 29, 24, 18, 15, 14, 13, 11,
- 8, 5, 1, 0, -5, -11, -19, -23, -24, -25, -25, -26, -22, -15, -9, -3,
- 4, 12, 19, 25, 26, 24, 17, 11, 2, -11, -26, -37, -45, -53, -58, -59,
- -57, -53, -47, -42, -35, -25, -10, 5, 15, 19, 22, 29, 37, 45, 48, 47,
- 44, 44, 43, 40, 33, 24, 19, 14, 13, 12, 8, 2, -2, 1, 1, 1,
- -4, -12, -15, -14, -13, -14, -18, -18, -15, -12, -8, -5, 2, 10, 18, 21,
- 20, 15, 10, 3, -7, -18, -31, -42, -47, -50, -53, -57, -57, -51, -42, -34,
- -25, -15, -5, 7, 16, 22, 30, 35, 40, 43, 42, 39, 39, 38, 38, 31,
- 22, 16, 14, 15, 17, 16, 12, 6, 4, 5, 7, 6, 0, -8, -12, -13,
- -15, -19, -21, -20, -17, -14, -11, -6, 2, 10, 18, 21, 21, 19, 11, -2,
- -17, -29, -37, -42, -46, -52, -55, -58, -52, -42, -34, -24, -15, -5, 5, 12,
- 17, 24, 32, 37, 37, 36, 33, 33, 35, 35, 32, 26, 22, 16, 17, 19,
- 19, 14, 7, 5, 5, 6, 5, 0, -7, -10, -9, -6, -7, -13, -17, -15,
- -11, -8, -7, -6, 1, 7, 12, 13, 11, 7, 0, -12, -25, -35, -40, -42,
- -43, -44, -47, -49, -43, -34, -22, -12, -7, 0, 4, 9, 17, 25, 31, 33,
- 33, 31, 30, 27, 28, 30, 29, 25, 20, 17, 20, 24, 22, 17, 11, 10,
- 9, 9, 5, -6, -11, -13, -9, -5, -9, -16, -19, -16, -9, -6, -6, -2,
- 4, 8, 11, 11, 6, -4, -11, -21, -34, -39, -41, -40, -38, -40, -44, -38,
- -28, -17, -10, -6, -5, -3, 3, 10, 15, 17, 20, 23, 26, 25, 24, 26,
- 28, 30, 30, 28, 25, 24, 23, 25, 22, 18, 14, 9, 5, 0, -7, -12,
- -13, -12, -7, -6, -9, -12, -10, -4, 2, 2, 3, 3, 3, 6, 7, 3,
- -9, -21, -28, -35, -40, -40, -37, -37, -36, -36, -29, -22, -11, -3, 2, 3,
- 0, 1, 3, 6, 9, 10, 10, 10, 13, 16, 21, 24, 29, 31, 33, 33,
- 33, 32, 30, 27, 23, 16, 12, 7, -2, -7, -14, -19, -16, -10, -5, -7,
- -9, -9, -6, 2, 6, 8, 7, 4, 3, 1, -3, -9, -16, -25, -34, -39,
- -41, -37, -33, -31, -31, -29, -22, -12, -4, 2, 7, 5, 1, -2, 0, 4,
- 4, 2, 2, 5, 10, 14, 19, 24, 28, 32, 36, 38, 36, 34, 31, 27,
- 23, 18, 11, 3, -5, -12, -15, -15, -11, -6, -5, -6, -8, -7, -3, 1,
- 4, 6, 3, -2, -7, -9, -12, -19, -24, -30, -34, -36, -35, -32, -29, -26,
- -22, -16, -10, -3, 4, 8, 9, 4, 0, -3, 0, 1, -5, -7, -5, 1,
- 7, 13, 14, 17, 27, 35, 38, 37, 35, 33, 31, 29, 25, 19, 11, 3,
- 0, -6, -10, -10, -7, -5, -5, -7, -7, -6, -3, 1, 4, 3, 0, -8,
- -15, -18, -20, -23, -27, -30, -32, -33, -29, -28, -25, -20, -16, -13, -6, 1,
- 6, 7, 4, 0, -5, -5, -5, -6, -7, -6, -2, 5, 10, 15, 20, 25,
- 32, 34, 34, 34, 32, 29, 24, 22, 19, 14, 9, 6, 4, 2, 0, 0,
- 2, 2, -2, -4, -6, -5, -5, -4, -4, -7, -12, -19, -25, -26, -26, -26,
- -26, -29, -28, -28, -25, -22, -18, -14, -10, -5, 0, 3, 4, 5, 4, 3,
- -2, -7, -10, -12, -9, -6, 0, 6, 11, 14, 16, 22, 30, 33, 34, 29,
- 25, 23, 21, 22, 22, 20, 18, 16, 14, 13, 11, 11, 11, 6, -4, -12,
- -16, -17, -16, -13, -16, -22, -26, -30, -30, -25, -21, -18, -17, -19, -18, -20,
- -19, -15, -13, -9, -7, -6, -5, -2, 3, 5, 4, 0, -5, -8, -6, -6,
- -6, -2, 4, 9, 11, 13, 15, 19, 23, 25, 22, 19, 16, 17, 20, 21,
- 22, 23, 24, 25, 24, 23, 22, 21, 16, 7, -4, -14, -21, -23, -24, -24,
- -28, -34, -38, -36, -31, -21, -13, -9, -8, -10, -11, -12, -14, -13, -12, -9,
- -10, -12, -11, -9, -4, 3, 4, 1, -3, -4, 1, 4, 7, 10, 10, 11,
- 12, 11, 8, 9, 11, 13, 11, 5, 4, 11, 20, 26, 29, 32, 35, 39,
- 39, 34, 30, 23, 15, 5, -10, -23, -31, -34, -32, -33, -37, -42, -41, -32,
- -21, -11, -6, -3, -3, -6, -8, -11, -14, -15, -14, -14, -14, -19, -20, -15,
- -7, 0, -2, -3, 0, 4, 10, 17, 19, 18, 18, 20, 18, 11, 5, 1,
- -2, -4, -7, -8, -4, 4, 14, 24, 32, 38, 46, 51, 52, 46, 37, 28,
- 19, 5, -12, -29, -39, -44, -46, -46, -50, -48, -39, -29, -14, -4, 6, 9,
- 8, 6, 0, -8, -13, -15, -18, -22, -28, -30, -26, -18, -9, -7, -4, 2,
- 10, 18, 24, 26, 26, 23, 22, 21, 14, 3, -5, -9, -14, -16, -16, -11,
- -4, 6, 14, 24, 37, 50, 58, 58, 53, 45, 36, 28, 17, 1, -18, -36,
- -47, -53, -54, -53, -51, -43, -33, -20, -8, 5, 15, 17, 13, 5, -4, -12,
- -14, -18, -23, -30, -34, -32, -24, -15, -10, -6, -3, 7, 18, 27, 32, 33,
- 30, 28, 24, 19, 12, 2, -10, -18, -24, -26, -23, -16, -6, 4, 12, 25,
- 39, 53, 60, 60, 58, 51, 42, 30, 16, 0, -20, -37, -49, -57, -61, -57,
- -50, -40, -29, -17, -4, 9, 17, 17, 11, 5, -3, -8, -13, -21, -30, -35,
- -34, -29, -22, -16, -11, -6, 1, 12, 24, 34, 39, 39, 35, 28, 21, 16,
- 8, -3, -16, -29, -35, -34, -26, -16, -9, 1, 14, 30, 46, 56, 60, 62,
- 59, 57, 46, 32, 15, -2, -17, -35, -51, -61, -61, -55, -46, -39, -30, -19,
- -4, 10, 14, 13, 7, 3, -2, -6, -15, -24, -31, -33, -31, -26, -23, -19,
- -11, -2, 6, 17, 30, 38, 41, 39, 34, 25, 18, 14, 6, -9, -24, -34,
- -38, -34, -28, -18, -9, 0, 14, 32, 44, 52, 58, 63, 66, 59, 45, 31,
- 18, 4, -17, -36, -53, -60, -59, -54, -46, -39, -30, -18, -3, 6, 8, 6,
- 3, 1, -3, -11, -22, -29, -28, -23, -20, -20, -18, -10, -2, 7, 17, 27,
- 34, 37, 38, 33, 26, 19, 15, 11, 0, -17, -31, -39, -40, -34, -27, -20,
- -11, 1, 16, 31, 43, 52, 59, 67, 70, 62, 47, 32, 19, 4, -18, -39,
- -53, -60, -57, -51, -44, -37, -30, -17, -6, 1, 2, 1, 0, -2, -7, -15,
- -23, -27, -25, -19, -16, -15, -12, -4, 5, 15, 25, 33, 37, 34, 31, 27,
- 22, 17, 11, 2, -11, -25, -35, -41, -41, -34, -23, -13, -4, 6, 18, 31,
- 43, 54, 61, 65, 62, 53, 44, 34, 22, 2, -20, -38, -47, -50, -47, -43,
- -42, -41, -32, -19, -13, -11, -10, -7, -5, -5, -9, -14, -18, -17, -12, -9,
- -8, -6, 1, 6, 12, 16, 21, 25, 25, 23, 19, 18, 14, 11, 8, 0,
- -10, -23, -34, -36, -32, -24, -16, -12, -6, 4, 15, 30, 42, 52, 59, 60,
- 58, 53, 46, 39, 27, 5, -19, -35, -43, -44, -43, -45, -49, -48, -39, -31,
- -27, -24, -19, -11, -6, -3, -4, -6, -8, -5, 3, 5, 7, 6, 7, 9,
- 12, 13, 15, 14, 12, 11, 11, 9, 8, 5, 4, 0, -12, -22, -28, -26,
- -21, -17, -13, -10, -5, 4, 14, 22, 32, 44, 56, 61, 59, 56, 48, 38,
- 25, 7, -10, -24, -33, -38, -44, -50, -51, -47, -41, -41, -41, -37, -26, -14,
- -6, 0, -2, -3, 5, 13, 19, 21, 16, 12, 9, 9, 10, 7, 3, 2,
- 2, 1, -2, 0, 3, 4, 1, -4, -12, -16, -16, -9, -9, -10, -9, -5,
- 2, 7, 11, 17, 27, 39, 51, 54, 52, 52, 49, 42, 28, 10, -4, -15,
- -25, -36, -48, -56, -58, -56, -52, -53, -54, -45, -28, -11, -2, 3, 8, 15,
- 24, 30, 34, 30, 22, 16, 12, 6, -4, -9, -9, -8, -12, -14, -12, -5,
- 3, 4, 2, -3, -4, 0, 3, 2, -4, -6, -6, -5, -4, -5, -3, 8,
- 21, 36, 44, 50, 55, 58, 55, 45, 33, 20, 5, -11, -27, -43, -55, -60,
- -61, -62, -64, -66, -58, -40, -20, -6, 3, 8, 16, 26, 34, 39, 38, 30,
- 21, 11, 2, -9, -14, -13, -13, -15, -16, -14, -6, 1, 4, 4, 3, 4,
- 7, 10, 10, 5, -3, -7, -8, -9, -12, -14, -11, 0, 13, 28, 40, 51,
- 58, 61, 60, 56, 47, 33, 15, -8, -28, -44, -55, -62, -72, -81, -83, -74,
- -58, -39, -21, -6, 8, 18, 30, 40, 47, 49, 44, 33, 19, 6, -6, -14,
- -19, -23, -26, -24, -19, -13, -5, -2, 2, 5, 8, 11, 14, 13, 9, 2,
- -4, -8, -12, -15, -19, -18, -13, -3, 14, 30, 44, 53, 62, 66, 66, 59,
- 48, 33, 12, -10, -31, -46, -58, -71, -79, -84, -81, -71, -54, -34, -14, 1,
- 14, 26, 37, 44, 48, 49, 41, 29, 12, -3, -13, -17, -19, -24, -26, -22,
- -16, -8, -3, -2, 3, 6, 10, 13, 12, 10, 6, 2, -4, -11, -18, -22,
- -22, -19, -14, -3, 13, 30, 46, 61, 68, 71, 70, 64, 52, 32, 10, -12,
- -31, -51, -67, -81, -88, -91, -84, -69, -51, -32, -12, 8, 25, 37, 43, 47,
- 52, 50, 40, 23, 5, -8, -13, -18, -23, -28, -26, -19, -12, -6, -4, -2,
- 2, 6, 11, 11, 5, 3, 4, 1, -9, -17, -21, -23, -22, -19, -14, 0,
- 17, 37, 54, 65, 70, 75, 76, 67, 50, 30, 6, -15, -35, -56, -75, -88,
- -93, -88, -78, -64, -47, -26, -3, 17, 31, 37, 42, 46, 48, 42, 27, 10,
- 0, -3, -7, -14, -21, -21, -13, -4, 1, -2, -3, 1, 5, 7, 4, -3,
- -8, -7, -7, -14, -19, -22, -23, -21, -20, -16, -6, 12, 32, 51, 63, 70,
- 76, 78, 75, 63, 44, 20, -5, -26, -46, -67, -83, -94, -93, -83, -69, -55,
- -40, -17, 8, 25, 34, 38, 43, 48, 45, 35, 20, 8, 2, 3, -2, -12,
- -18, -15, -8, 0, 0, -5, -6, -4, -3, -5, -11, -15, -14, -12, -13, -16,
- -19, -20, -20, -16, -10, -2, 11, 24, 42, 57, 64, 70, 73, 72, 64, 48,
- 26, 4, -15, -35, -50, -68, -81, -88, -81, -68, -55, -44, -29, -10, 9, 22,
- 25, 30, 37, 38, 35, 24, 14, 11, 13, 14, 9, 0, -5, -3, 3, 4,
- -2, -10, -15, -15, -15, -19, -25, -24, -20, -18, -19, -20, -18, -16, -13, -9,
- 1, 12, 25, 37, 53, 63, 69, 74, 73, 69, 56, 37, 15, -6, -25, -42,
- -59, -75, -82, -81, -72, -61, -50, -35, -17, -2, 13, 20, 27, 31, 34, 34,
- 28, 19, 14, 13, 15, 14, 8, 4, 3, 5, 5, 1, -6, -15, -18, -22,
- -27, -33, -34, -31, -25, -24, -20, -19, -17, -10, -2, 9, 18, 28, 39, 51,
- 60, 67, 71, 72, 67, 53, 35, 16, -4, -21, -40, -57, -70, -76, -74, -65,
- -55, -44, -34, -21, -7, 6, 15, 18, 20, 24, 24, 21, 16, 15, 16, 17,
- 17, 16, 13, 12, 13, 13, 9, 0, -12, -17, -22, -31, -40, -43, -40, -35,
- -30, -26, -24, -20, -11, -2, 9, 19, 29, 39, 46, 54, 60, 66, 67, 66,
- 58, 41, 21, 5, -11, -29, -47, -62, -68, -68, -65, -57, -49, -39, -27, -13,
- -2, 6, 11, 18, 23, 24, 21, 19, 19, 21, 21, 18, 15, 11, 13, 15,
- 15, 10, -2, -8, -14, -21, -30, -39, -44, -44, -40, -33, -29, -27, -21, -12,
- -3, 6, 16, 28, 40, 48, 54, 56, 59, 61, 62, 57, 44, 28, 12, -3,
- -22, -40, -55, -64, -63, -61, -56, -51, -41, -29, -15, -6, 1, 8, 15, 20,
- 20, 18, 17, 18, 23, 23, 20, 17, 15, 18, 20, 20, 15, 4, -5, -11,
- -20, -32, -43, -49, -48, -43, -36, -32, -29, -21, -13, 0, 11, 20, 30, 38,
- 46, 50, 51, 53, 56, 53, 48, 41, 30, 19, 5, -10, -26, -42, -50, -56,
- -57, -56, -53, -46, -38, -27, -18, -10, -2, 8, 16, 19, 24, 24, 22, 23,
- 25, 23, 17, 16, 15, 16, 14, 10, 3, -5, -11, -20, -28, -35, -42, -44,
- -42, -35, -29, -25, -19, -11, 0, 10, 20, 26, 31, 38, 45, 48, 46, 46,
- 44, 41, 37, 30, 22, 13, 1, -15, -27, -36, -44, -49, -51, -52, -49, -44,
- -37, -27, -20, -12, 1, 10, 19, 23, 28, 29, 28, 28, 24, 19, 17, 16,
- 15, 14, 10, 4, -3, -10, -15, -23, -31, -36, -41, -41, -39, -32, -24, -19,
- -11, -3, 5, 15, 24, 31, 36, 42, 45, 44, 41, 37, 33, 31, 29, 23,
- 14, 2, -8, -16, -22, -31, -40, -44, -46, -46, -46, -44, -37, -28, -20, -10,
- 2, 11, 20, 28, 32, 32, 29, 26, 22, 19, 17, 14, 12, 11, 8, 2,
- -5, -14, -20, -24, -30, -34, -37, -38, -36, -30, -21, -14, -6, 2, 11, 19,
- 26, 30, 34, 41, 44, 42, 38, 32, 27, 25, 24, 21, 11, 1, -9, -16,
- -25, -34, -40, -43, -45, -48, -50, -49, -40, -27, -15, -6, 4, 15, 27, 36,
- 40, 37, 32, 27, 22, 15, 11, 10, 8, 6, 0, -8, -14, -16, -17, -18,
- -24, -31, -33, -33, -27, -22, -17, -10, -4, 6, 13, 17, 22, 27, 33, 38,
- 39, 37, 35, 33, 31, 27, 23, 19, 11, 3, -7, -20, -30, -38, -42, -42,
- -46, -53, -58, -53, -41, -27, -13, -2, 10, 19, 30, 39, 43, 38, 29, 23,
- 18, 12, 8, 6, 6, 4, -3, -8, -12, -13, -10, -12, -17, -24, -25, -23,
- -23, -23, -19, -12, -4, 2, 5, 9, 14, 22, 32, 37, 39, 39, 37, 37,
- 33, 28, 27, 21, 12, 0, -14, -25, -33, -38, -43, -48, -54, -60, -59, -48,
- -36, -20, -8, 2, 12, 26, 39, 44, 40, 32, 27, 23, 16, 8, 3, 3,
- 2, 1, -4, -9, -9, -6, -6, -8, -13, -16, -18, -21, -22, -21, -16, -7,
- -2, 0, -2, 2, 13, 25, 30, 34, 34, 34, 34, 33, 33, 31, 26, 21,
- 11, -3, -15, -25, -31, -37, -48, -57, -62, -63, -56, -46, -35, -25, -12, 5,
- 18, 32, 40, 40, 36, 32, 29, 22, 15, 7, 3, 0, 0, 0, 1, -2,
- -2, 0, 0, -3, -4, -7, -13, -22, -28, -25, -17, -10, -10, -11, -10, -4,
- 12, 26, 36, 39, 40, 41, 40, 37, 35, 33, 28, 19, 3, -11, -22, -30,
- -37, -46, -56, -63, -65, -59, -52, -43, -29, -17, -4, 10, 23, 32, 36, 36,
- 34, 29, 24, 19, 12, 5, -2, 0, 4, 7, 10, 9, 6, 5, 5, 5,
- 0, -10, -20, -26, -29, -26, -20, -18, -19, -17, -9, 3, 16, 28, 36, 40,
- 42, 43, 41, 40, 36, 33, 26, 16, 3, -10, -21, -31, -42, -53, -61, -65,
- -63, -58, -52, -41, -31, -18, -4, 9, 21, 26, 29, 30, 31, 31, 28, 21,
- 12, 6, 5, 10, 13, 13, 14, 9, 8, 7, 5, 0, -8, -17, -24, -28,
- -27, -23, -17, -14, -12, -8, 2, 15, 26, 32, 36, 39, 38, 37, 36, 33,
- 28, 21, 16, 10, 1, -13, -25, -34, -41, -50, -59, -62, -62, -53, -44, -37,
- -28, -19, -6, 7, 14, 18, 22, 26, 28, 28, 21, 13, 6, 6, 15, 19,
- 21, 20, 20, 18, 16, 13, 7, -3, -12, -21, -27, -31, -30, -24, -15, -11,
- -8, 0, 10, 23, 29, 32, 34, 34, 34, 33, 32, 27, 23, 20, 17, 10,
- -2, -15, -25, -34, -43, -52, -61, -63, -58, -49, -43, -41, -33, -22, -9, 3,
- 11, 17, 21, 26, 30, 28, 23, 17, 15, 18, 22, 22, 20, 21, 21, 18,
- 12, 4, -5, -11, -16, -22, -28, -32, -24, -14, -7, -5, 1, 11, 20, 27,
- 30, 26, 25, 29, 30, 29, 22, 17, 18, 22, 20, 9, -8, -18, -25, -31,
- -40, -53, -60, -58, -54, -46, -45, -42, -32, -20, -10, -2, 5, 12, 19, 25,
- 27, 22, 18, 18, 21, 24, 25, 22, 24, 26, 27, 22, 10, 0, -7, -9,
- -12, -21, -28, -28, -20, -9, -4, -2, 5, 14, 22, 24, 21, 15, 18, 24,
- 28, 24, 19, 21, 26, 30, 22, 7, -6, -15, -23, -34, -50, -61, -66, -61,
- -52, -50, -49, -45, -36, -22, -10, 1, 11, 15, 20, 26, 26, 24, 21, 21,
- 27, 28, 24, 21, 22, 26, 24, 16, 5, -5, -7, -5, -11, -17, -22, -17,
- -7, 0, 1, 4, 9, 16, 19, 18, 13, 12, 16, 22, 24, 23, 23, 28,
- 33, 27, 16, 2, -12, -23, -33, -45, -57, -64, -64, -55, -51, -52, -49, -39,
- -25, -13, -6, 1, 6, 12, 16, 18, 20, 18, 20, 25, 28, 28, 29, 31,
- 36, 37, 28, 15, 7, 3, 0, -4, -14, -21, -23, -16, -7, -4, -3, 1,
- 10, 16, 17, 10, 7, 9, 18, 24, 24, 24, 28, 34, 34, 26, 12, -3,
- -15, -26, -40, -53, -61, -65, -62, -59, -57, -55, -49, -39, -27, -18, -6, 3,
- 8, 14, 17, 21, 25, 26, 27, 28, 30, 32, 32, 31, 32, 28, 22, 14,
- 6, 3, 0, -3, -8, -12, -12, -5, 0, 2, 1, 3, 6, 11, 11, 7,
- 4, 6, 13, 20, 24, 28, 31, 32, 28, 19, 7, -7, -20, -32, -44, -53,
- -58, -58, -55, -54, -53, -50, -46, -40, -27, -14, -6, -6, -5, 0, 8, 16,
- 20, 23, 25, 30, 37, 42, 43, 41, 39, 34, 28, 18, 9, 4, 3, 0,
- -10, -13, -12, -10, -5, 1, 1, 0, 4, 8, 7, 5, 6, 11, 19, 23,
- 27, 32, 33, 27, 20, 10, 0, -15, -30, -41, -49, -52, -54, -55, -55, -53,
- -50, -45, -40, -32, -24, -16, -11, -10, -8, -3, 6, 13, 17, 21, 29, 37,
- 43, 48, 47, 43, 38, 35, 30, 19, 11, 7, 2, -5, -9, -9, -5, 1,
- 1, 0, -2, 1, 3, 6, 5, 4, 5, 10, 16, 20, 24, 27, 25, 18,
- 10, 3, -9, -21, -31, -39, -44, -47, -47, -44, -46, -48, -48, -45, -39, -36,
- -30, -26, -25, -23, -19, -9, 4, 14, 24, 32, 41, 48, 54, 56, 57, 52,
- 47, 40, 28, 17, 10, 4, -3, -8, -10, -8, -6, -5, -5, -5, -3, 0,
- 3, 4, 4, 5, 7, 12, 19, 26, 27, 24, 18, 12, 5, -3, -12, -24,
- -34, -43, -46, -48, -48, -46, -46, -45, -44, -42, -38, -33, -29, -26, -26, -22,
- -14, -5, 5, 13, 23, 32, 40, 47, 52, 56, 57, 55, 52, 47, 36, 27,
- 19, 11, 3, -5, -6, -8, -10, -13, -15, -14, -13, -11, -6, 1, 4, 7,
- 11, 17, 21, 26, 28, 26, 19, 10, 2, -7, -17, -26, -36, -41, -45, -47,
- -45, -44, -44, -41, -39, -40, -40, -37, -33, -34, -32, -26, -18, -9, 2, 12,
- 26, 40, 47, 56, 63, 66, 66, 63, 60, 53, 40, 27, 14, 3, -8, -11,
- -12, -15, -19, -19, -18, -15, -12, -8, 0, 6, 11, 13, 14, 17, 23, 29,
- 27, 18, 9, 1, -7, -16, -25, -35, -43, -49, -47, -44, -43, -42, -40, -36,
- -34, -33, -33, -33, -35, -34, -30, -23, -16, -9, 2, 14, 27, 39, 49, 58,
- 66, 69, 68, 66, 61, 53, 45, 32, 18, 1, -11, -14, -17, -17, -20, -23,
- -21, -17, -13, -3, 4, 10, 13, 14, 17, 18, 21, 24, 22, 15, 6, -4,
- -12, -22, -28, -38, -49, -51, -48, -45, -43, -40, -38, -36, -35, -34, -33, -33,
- -34, -35, -33, -29, -18, -6, 6, 19, 33, 46, 59, 71, 78, 78, 78, 74,
- 67, 54, 39, 22, 6, -8, -16, -22, -25, -25, -26, -22, -17, -12, -3, 6,
- 15, 17, 16, 14, 14, 16, 17, 16, 13, 6, -2, -11, -20, -27, -34, -43,
- -49, -48, -44, -41, -39, -36, -33, -34, -33, -34, -32, -33, -35, -35, -30, -21,
- -11, 0, 9, 23, 38, 52, 65, 74, 76, 76, 74, 70, 62, 47, 28, 13,
- 2, -6, -14, -21, -23, -20, -18, -16, -13, -7, 1, 8, 10, 11, 9, 11,
- 11, 13, 15, 16, 13, 8, -2, -11, -19, -27, -37, -47, -52, -51, -48, -46,
- -43, -40, -38, -36, -35, -35, -38, -38, -33, -27, -21, -16, -7, 6, 21, 36,
- 49, 61, 70, 75, 79, 78, 73, 62, 49, 35, 22, 8, -3, -12, -17, -20,
- -18, -14, -13, -15, -12, -5, 4, 7, 8, 8, 9, 8, 9, 11, 14, 14,
- 10, 4, -6, -15, -25, -35, -41, -48, -54, -53, -47, -42, -38, -37, -35, -31,
- -31, -30, -30, -29, -26, -24, -19, -12, -2, 10, 22, 35, 48, 60, 70, 76,
- 76, 73, 67, 57, 44, 28, 14, 5, -3, -8, -13, -14, -13, -10, -11, -11,
- -8, -2, 4, 6, 5, 5, 5, 6, 10, 11, 10, 8, 4, -2, -9, -15,
- -24, -35, -44, -50, -52, -49, -45, -42, -42, -40, -37, -37, -37, -33, -29, -26,
- -24, -21, -16, -7, 6, 18, 30, 41, 54, 66, 75, 77, 79, 76, 67, 53,
- 37, 21, 8, 2, -5, -10, -14, -14, -12, -12, -11, -10, -5, 4, 7, 4,
- 1, 2, 6, 9, 9, 7, 5, 4, 0, -7, -14, -23, -32, -37, -43, -48,
- -50, -51, -47, -42, -34, -32, -32, -34, -32, -26, -21, -18, -17, -14, -11, -4,
- 5, 13, 24, 40, 55, 67, 72, 74, 76, 75, 67, 51, 37, 23, 11, 4,
- -4, -11, -15, -17, -17, -16, -14, -13, -8, -2, 1, 1, 1, 3, 5, 9,
- 7, 5, 4, 4, 3, -5, -14, -24, -32, -38, -41, -47, -52, -53, -49, -41,
- -35, -34, -35, -33, -29, -24, -19, -13, -10, -9, -7, -2, 8, 17, 29, 43,
- 56, 67, 74, 75, 75, 72, 64, 53, 38, 23, 13, 4, -5, -12, -16, -20,
- -21, -18, -16, -14, -11, -8, -5, -3, 0, 2, 6, 6, 6, 5, 5, 6,
- 3, -6, -19, -31, -37, -41, -45, -50, -52, -53, -48, -39, -32, -30, -26, -25,
- -22, -16, -10, -7, -11, -10, -8, -2, 6, 17, 31, 45, 58, 68, 78, 80,
- 76, 70, 65, 55, 37, 18, 5, -4, -10, -19, -25, -26, -24, -18, -13, -11,
- -9, -6, -2, 4, 6, 5, 4, 3, 4, 2, 1, -3, -4, -11, -20, -29,
- -38, -43, -45, -48, -51, -48, -44, -39, -35, -34, -31, -30, -25, -15, -8, -8,
- -10, -8, 1, 11, 22, 33, 42, 54, 66, 76, 80, 75, 70, 66, 59, 42,
- 23, 6, -4, -9, -17, -22, -27, -25, -19, -9, -7, -8, -5, 0, 4, 5,
- 2, -2, -5, -5, -4, -6, -7, -6, -10, -16, -21, -29, -34, -37, -38, -41,
- -44, -42, -36, -32, -33, -37, -39, -35, -27, -17, -12, -13, -12, -6, 6, 22,
- 36, 44, 54, 66, 77, 82, 80, 75, 68, 59, 47, 29, 10, -3, -13, -18,
- -23, -26, -27, -24, -16, -9, -5, -4, -2, 3, 6, 4, -2, -6, -8, -7,
- -8, -8, -9, -10, -13, -16, -22, -29, -31, -30, -34, -36, -36, -32, -28, -30,
- -36, -39, -38, -33, -28, -24, -24, -22, -15, -2, 13, 26, 38, 53, 67, 78,
- 84, 88, 85, 81, 71, 59, 39, 13, -5, -14, -19, -26, -32, -34, -30, -22,
- -13, -5, 0, 6, 7, 10, 8, 2, -4, -10, -12, -15, -18, -20, -20, -20,
- -22, -24, -26, -26, -23, -23, -23, -24, -21, -17, -18, -25, -31, -35, -37, -37,
- -36, -33, -29, -22, -10, 5, 19, 31, 45, 62, 75, 84, 86, 88, 87, 80,
- 66, 45, 22, 4, -9, -18, -26, -34, -37, -33, -24, -15, -9, -3, 6, 13,
- 15, 11, 2, -5, -10, -13, -20, -25, -27, -26, -25, -26, -29, -29, -23, -18,
- -16, -19, -18, -15, -9, -6, -12, -21, -32, -36, -36, -40, -39, -36, -30, -21,
- -10, 6, 20, 36, 55, 69, 79, 85, 90, 92, 88, 75, 56, 33, 12, -3,
- -15, -24, -33, -37, -35, -28, -20, -12, -4, 6, 14, 18, 16, 9, 0, -8,
- -15, -19, -27, -33, -35, -34, -34, -36, -36, -29, -19, -10, -10, -10, -8, -4,
- -2, -2, -8, -18, -28, -36, -43, -48, -46, -36, -25, -14, -4, 10, 27, 46,
- 65, 78, 86, 89, 87, 85, 78, 64, 42, 19, 0, -12, -20, -29, -34, -36,
- -30, -22, -12, -6, 1, 8, 16, 18, 13, 2, -7, -12, -17, -24, -33, -38,
- -39, -36, -36, -36, -34, -26, -18, -11, -7, -6, -5, -5, 1, 1, -5, -14,
- -24, -33, -41, -42, -37, -28, -19, -10, 3, 16, 30, 47, 64, 76, 83, 85,
- 83, 78, 69, 54, 37, 17, -2, -14, -21, -28, -32, -32, -27, -18, -11, -6,
- 2, 12, 18, 16, 5, -5, -11, -14, -19, -30, -40, -47, -45, -38, -36, -34,
- -33, -26, -15, -6, -2, 1, 1, 3, 5, 4, -3, -13, -26, -35, -41, -39,
- -33, -23, -13, -5, 7, 21, 36, 53, 68, 79, 82, 78, 72, 66, 59, 47,
- 30, 10, -6, -16, -21, -22, -25, -27, -25, -18, -10, -4, 4, 10, 11, 6,
- -4, -11, -13, -18, -25, -34, -43, -45, -41, -36, -34, -32, -27, -19, -10, -5,
- 0, 2, 5, 5, 5, 1, -7, -16, -25, -33, -38, -35, -25, -13, -6, 0,
- 11, 27, 46, 60, 69, 70, 68, 69, 68, 62, 52, 39, 22, 8, -2, -11,
- -18, -21, -22, -23, -24, -17, -10, -5, 1, 5, 5, 2, -3, -5, -9, -17,
- -28, -41, -46, -48, -43, -42, -42, -39, -30, -19, -9, -3, 6, 11, 15, 16,
- 12, 5, -2, -12, -23, -33, -37, -34, -25, -18, -8, 1, 15, 32, 48, 62,
- 69, 68, 67, 63, 62, 58, 50, 34, 15, -2, -8, -10, -11, -16, -24, -24,
- -19, -12, -6, -2, 2, 3, 1, 0, -6, -10, -17, -26, -37, -46, -48, -45,
- -44, -42, -38, -32, -22, -12, -6, 4, 10, 14, 16, 15, 11, 5, -2, -11,
- -23, -31, -29, -22, -18, -16, -11, 3, 17, 34, 50, 56, 59, 61, 63, 62,
- 59, 53, 44, 32, 16, 3, -8, -9, -13, -20, -26, -27, -21, -16, -11, -9,
- -6, 1, 7, 7, 0, -10, -15, -20, -30, -39, -45, -48, -48, -46, -41, -36,
- -29, -20, -11, 3, 11, 14, 19, 21, 19, 15, 6, -3, -13, -18, -18, -17,
- -20, -19, -12, 2, 15, 26, 36, 43, 51, 59, 61, 61, 57, 54, 49, 37,
- 21, 9, 1, -8, -17, -25, -29, -28, -27, -23, -19, -13, -5, 2, 8, 5,
- -4, -11, -13, -17, -27, -40, -49, -53, -53, -50, -44, -37, -28, -19, -7, 8,
- 18, 22, 26, 26, 23, 17, 10, 0, -8, -15, -20, -25, -23, -19, -11, 0,
- 13, 25, 34, 44, 54, 60, 62, 60, 58, 56, 52, 38, 21, 6, -6, -16,
- -26, -32, -33, -30, -26, -24, -17, -8, 3, 13, 16, 10, 1, -7, -12, -18,
- -34, -50, -61, -63, -58, -54, -50, -45, -33, -13, 6, 21, 27, 34, 37, 36,
- 30, 20, 11, -2, -13, -24, -32, -37, -34, -24, -10, 2, 12, 25, 41, 55,
- 61, 64, 65, 67, 64, 59, 48, 32, 16, 0, -12, -20, -27, -33, -33, -31,
- -28, -23, -12, 0, 10, 13, 9, 2, -2, -7, -13, -25, -41, -56, -65, -66,
- -62, -56, -53, -42, -25, -5, 13, 24, 34, 39, 42, 39, 32, 22, 11, -2,
- -15, -27, -36, -37, -31, -22, -13, 0, 12, 27, 43, 55, 61, 64, 65, 63,
- 60, 53, 42, 28, 10, -6, -20, -27, -28, -28, -25, -23, -20, -13, -2, 11,
- 16, 14, 8, 2, -6, -14, -25, -38, -53, -67, -73, -73, -67, -58, -46, -32,
- -14, 6, 24, 36, 43, 45, 44, 39, 30, 18, 5, -11, -25, -35, -39, -37,
- -28, -17, -7, 4, 16, 32, 48, 58, 64, 66, 63, 61, 56, 46, 31, 18,
- 3, -13, -21, -25, -23, -19, -15, -11, -7, -2, 6, 13, 14, 8, -3, -12,
- -21, -32, -40, -55, -70, -78, -75, -67, -56, -47, -29, -12, 10, 29, 40, 47,
- 49, 48, 43, 31, 15, 0, -16, -29, -39, -45, -41, -32, -18, -6, 3, 13,
- 27, 43, 57, 64, 65, 61, 58, 52, 43, 32, 18, 6, -9, -18, -20, -17,
- -12, -4, 1, 3, 7, 12, 17, 16, 9, -3, -15, -27, -39, -48, -60, -72,
- -82, -82, -73, -58, -45, -33, -14, 7, 28, 42, 49, 51, 51, 48, 38, 22,
- 2, -16, -30, -37, -42, -45, -40, -26, -11, 3, 11, 20, 34, 52, 65, 69,
- 64, 54, 46, 38, 28, 16, 4, -11, -18, -16, -10, -4, 3, 13, 21, 23,
- 22, 20, 18, 11, -2, -16, -34, -47, -59, -70, -76, -83, -83, -76, -64, -48,
- -31, -12, 10, 30, 42, 50, 53, 51, 46, 37, 25, 8, -13, -30, -41, -45,
- -43, -35, -23, -15, -5, 8, 17, 28, 40, 56, 64, 63, 55, 45, 34, 24,
- 14, 7, -4, -12, -13, -9, -2, 11, 23, 31, 33, 33, 31, 26, 17, 4,
- -14, -31, -48, -62, -75, -86, -90, -87, -79, -68, -54, -39, -18, 4, 23, 39,
- 47, 52, 52, 47, 39, 29, 15, -5, -23, -35, -41, -40, -34, -26, -16, -8,
- 2, 12, 22, 30, 43, 52, 58, 54, 45, 36, 25, 16, 7, -2, -7, -8,
- -3, 4, 13, 24, 32, 39, 42, 39, 30, 19, 6, -10, -25, -44, -62, -79,
- -88, -90, -85, -78, -70, -59, -45, -24, 0, 20, 35, 43, 48, 48, 46, 42,
- 33, 20, 2, -19, -32, -38, -41, -37, -29, -19, -8, 1, 11, 19, 26, 35,
- 43, 48, 48, 41, 35, 26, 16, 7, 0, 0, 3, 6, 10, 16, 24, 32,
- 40, 44, 43, 33, 21, 8, -5, -19, -37, -54, -72, -84, -87, -81, -75, -68,
- -61, -50, -33, -12, 8, 22, 29, 34, 40, 42, 41, 35, 24, 13, -2, -16,
- -27, -33, -33, -27, -22, -17, -13, -4, 9, 18, 25, 31, 36, 42, 44, 40,
- 32, 21, 12, 9, 7, 8, 9, 13, 17, 23, 29, 35, 40, 40, 35, 26,
- 13, 0, -11, -24, -41, -60, -74, -80, -79, -73, -68, -63, -56, -43, -27, -10,
- 6, 18, 24, 29, 34, 38, 37, 30, 20, 9, -3, -14, -24, -27, -27, -25,
- -23, -18, -9, 2, 10, 19, 25, 30, 37, 40, 41, 33, 22, 16, 10, 6,
- 6, 10, 16, 21, 28, 31, 35, 38, 44, 45, 34, 19, 5, -5, -17, -33,
- -52, -68, -76, -78, -75, -71, -67, -62, -51, -37, -20, -7, 4, 13, 21, 29,
- 34, 36, 33, 26, 17, 10, 0, -8, -13, -19, -21, -21, -17, -11, -6, 4,
- 10, 13, 19, 25, 30, 31, 28, 20, 14, 10, 7, 7, 11, 20, 26, 32,
- 36, 39, 41, 44, 46, 41, 30, 13, 0, -13, -27, -44, -62, -72, -74, -74,
- -74, -71, -66, -57, -47, -32, -19, -9, 2, 14, 24, 28, 32, 34, 33, 25,
- 17, 9, 2, -5, -10, -17, -22, -18, -13, -7, 0, 4, 10, 17, 23, 26,
- 25, 21, 15, 9, 9, 7, 4, 7, 16, 27, 34, 39, 43, 48, 49, 52,
- 49, 39, 24, 9, -3, -17, -32, -52, -67, -75, -75, -71, -70, -70, -66, -56,
- -43, -31, -21, -12, -2, 11, 21, 27, 30, 33, 31, 29, 22, 15, 8, 0,
- -6, -13, -14, -14, -11, -5, 0, 4, 8, 13, 16, 18, 15, 12, 10, 7,
- 7, 6, 7, 14, 24, 36, 44, 46, 46, 49, 52, 53, 47, 35, 21, 9,
- -6, -23, -43, -59, -68, -71, -74, -74, -76, -73, -64, -52, -39, -31, -25, -15,
- 0, 12, 20, 24, 29, 32, 30, 26, 21, 16, 10, 4, -2, -7, -7, -5,
- -3, 0, 3, 5, 6, 9, 8, 8, 6, 3, 2, 4, 5, 7, 14, 22,
- 34, 43, 49, 57, 57, 55, 52, 48, 43, 31, 17, 2, -13, -33, -49, -59,
- -63, -66, -72, -75, -76, -70, -61, -52, -44, -37, -30, -18, -4, 11, 20, 25,
- 28, 32, 32, 30, 26, 19, 13, 5, 0, -4, -5, -3, 1, 2, 1, -3,
- -2, 2, 6, 4, 2, -3, -2, 3, 10, 13, 18, 27, 40, 49, 56, 59,
- 60, 56, 52, 47, 41, 30, 17, 1, -19, -39, -55, -64, -67, -70, -76, -81,
- -78, -69, -56, -46, -40, -33, -24, -12, 3, 15, 22, 25, 26, 29, 27, 23,
- 19, 14, 9, 4, 0, -2, 1, 5, 9, 7, 2, -3, -3, 3, 3, -2,
- -10, -13, -10, -2, 7, 14, 22, 31, 45, 59, 65, 68, 65, 62, 58, 50,
- 41, 28, 12, -9, -31, -49, -59, -65, -70, -76, -84, -84, -77, -63, -50, -45,
- -40, -32, -21, -7, 7, 16, 24, 28, 29, 28, 23, 18, 15, 11, 6, 0,
- -4, -3, 4, 11, 14, 11, 6, 5, 7, 7, 2, -7, -12, -16, -13, -6,
- 1, 8, 17, 32, 50, 63, 68, 68, 69, 70, 65, 56, 43, 27, 7, -17,
- -38, -52, -62, -71, -78, -86, -88, -84, -73, -59, -50, -43, -34, -25, -11, 2,
- 11, 19, 23, 26, 26, 21, 17, 12, 9, 7, 5, 2, 2, 4, 11, 16,
- 14, 10, 9, 10, 9, 1, -8, -16, -19, -16, -11, -6, 0, 8, 24, 43,
- 57, 66, 70, 72, 72, 67, 63, 52, 37, 18, -5, -23, -41, -54, -62, -70,
- -78, -81, -82, -76, -67, -56, -45, -36, -31, -22, -12, 0, 10, 16, 20, 21,
- 17, 13, 7, 3, 3, 6, 6, 6, 9, 14, 20, 21, 20, 17, 17, 15,
- 9, -3, -15, -23, -27, -20, -14, -9, -4, 9, 31, 49, 64, 70, 75, 78,
- 76, 70, 60, 45, 31, 12, -11, -31, -46, -58, -66, -70, -73, -77, -74, -67,
- -59, -52, -44, -36, -29, -22, -14, -6, 1, 11, 14, 14, 11, 6, 6, 7,
- 10, 11, 12, 15, 18, 24, 23, 21, 19, 20, 18, 12, 0, -13, -20, -27,
- -27, -22, -16, -11, 1, 19, 36, 52, 64, 73, 79, 81, 77, 69, 56, 43,
- 26, 5, -16, -37, -54, -62, -66, -69, -72, -71, -65, -62, -56, -47, -39, -33,
- -26, -19, -14, -12, -3, 9, 9, 3, -6, -4, 5, 11, 12, 11, 12, 20,
- 29, 31, 29, 25, 25, 27, 24, 11, -6, -17, -25, -31, -32, -30, -26, -16,
- 0, 17, 35, 51, 66, 78, 87, 88, 84, 73, 57, 40, 23, 3, -20, -42,
- -57, -65, -69, -71, -70, -68, -63, -58, -52, -45, -38, -30, -26, -24, -23, -16,
- -8, -2, -5, -9, -6, 1, 9, 12, 13, 17, 24, 32, 37, 37, 34, 32,
- 33, 31, 19, 2, -15, -25, -31, -36, -38, -35, -27, -13, 4, 23, 40, 59,
- 76, 91, 96, 91, 80, 69, 55, 35, 13, -12, -35, -52, -61, -66, -71, -70,
- -63, -54, -48, -44, -42, -36, -31, -30, -34, -36, -33, -26, -20, -20, -21, -18,
- -9, 5, 13, 18, 21, 29, 40, 47, 50, 49, 44, 40, 34, 23, 6, -14,
- -27, -39, -45, -48, -45, -35, -23, -7, 11, 30, 51, 73, 89, 97, 96, 89,
- 80, 63, 44, 25, 4, -18, -39, -53, -59, -63, -61, -58, -55, -52, -49, -45,
- -39, -35, -37, -41, -46, -43, -38, -33, -29, -25, -18, -11, 3, 13, 20, 25,
- 30, 38, 46, 51, 50, 47, 43, 37, 26, 9, -7, -19, -32, -45, -52, -51,
- -40, -28, -12, 4, 19, 38, 61, 83, 94, 95, 89, 82, 67, 50, 30, 12,
- -8, -26, -40, -52, -57, -56, -52, -48, -46, -44, -40, -34, -32, -32, -37, -44,
- -47, -45, -41, -39, -35, -28, -17, -6, 7, 15, 23, 32, 40, 47, 52, 52,
- 51, 46, 39, 32, 17, 1, -14, -26, -37, -46, -50, -45, -35, -25, -11, 5,
- 24, 44, 62, 79, 88, 86, 79, 70, 59, 45, 25, 7, -13, -25, -36, -46,
- -50, -51, -50, -46, -43, -41, -37, -34, -33, -36, -40, -43, -46, -46, -41, -36,
- -31, -22, -10, 4, 13, 21, 30, 40, 47, 50, 53, 52, 47, 39, 30, 18,
- 3, -12, -22, -33, -42, -47, -45, -36, -25, -14, -2, 14, 34, 52, 67, 76,
- 77, 72, 65, 55, 43, 27, 12, -7, -21, -29, -36, -41, -44, -43, -39, -36,
- -32, -27, -26, -26, -29, -33, -36, -43, -49, -48, -44, -38, -32, -22, -11, 4,
- 15, 25, 34, 44, 50, 53, 54, 52, 44, 35, 23, 9, -4, -15, -27, -37,
- -43, -45, -42, -34, -21, -9, 5, 19, 34, 50, 63, 70, 69, 63, 54, 46,
- 35, 20, 4, -11, -23, -29, -33, -37, -41, -40, -33, -25, -20, -19, -21, -22,
- -23, -26, -34, -42, -47, -46, -43, -36, -30, -22, -11, 5, 17, 28, 37, 45,
- 52, 55, 53, 49, 41, 30, 19, 4, -12, -23, -33, -41, -45, -45, -40, -31,
- -18, -3, 11, 23, 38, 51, 63, 64, 58, 51, 45, 36, 25, 10, -4, -15,
- -24, -28, -32, -36, -35, -29, -19, -13, -13, -14, -13, -13, -13, -21, -33, -43,
- -45, -45, -41, -38, -34, -25, -11, 4, 17, 29, 39, 49, 57, 60, 55, 48,
- 39, 29, 16, 1, -14, -27, -35, -42, -47, -48, -42, -29, -15, -3, 10, 20,
- 34, 48, 56, 57, 51, 45, 38, 30, 20, 7, -7, -17, -22, -26, -32, -36,
- -31, -21, -9, -6, -8, -8, -4, 1, -4, -13, -26, -35, -39, -40, -42, -44,
- -40, -29, -13, 3, 16, 29, 43, 58, 67, 67, 59, 49, 39, 27, 11, -9,
- -28, -39, -47, -50, -53, -52, -44, -29, -12, 5, 13, 25, 38, 51, 57, 52,
- 45, 38, 30, 21, 9, -4, -14, -21, -26, -29, -33, -28, -18, -7, 2, 2,
- 2, 4, 8, 10, 5, -10, -25, -36, -42, -45, -49, -49, -45, -33, -14, 5,
- 22, 35, 54, 69, 78, 76, 67, 53, 41, 27, 6, -17, -36, -50, -55, -60,
- -63, -62, -51, -34, -16, -2, 9, 20, 34, 45, 50, 48, 42, 35, 29, 18,
- 7, 0, 0, 0, 0, 0, 0, 7, 0, -1, -7, -18, -16, 3, 6, -18,
- -29, -21, 6, 6, -12, -10, -10, -2, 4, 15, 21, 14, 4, 9, 29, 27,
- 15, 9, 13, 20, 0, -21, -11, 3, -11, -37, -36, -7, 11, -4, -26, -23,
- -4, 15, -4, -15, -11, -10, -1, 9, 23, 15, 8, 6, 24, 35, 19, 14,
- 6, 17, 10, -15, -26, -7, -1, -23, -40, -24, 4, 10, -16, -25, -13, 11,
- 10, -14, -15, -12, -6, 1, 19, 22, 6, 7, 15, 40, 31, 22, 7, 7,
- 15, 5, -22, -21, -5, -9, -33, -32, -15, 5, -4, -19, -20, 1, 17, -4,
- -15, -11, -12, -4, 9, 27, 13, 7, 11, 32, 44, 30, 14, 2, 7, 9,
- -8, -25, -18, -9, -19, -30, -21, -4, 2, -10, -21, -13, 15, 8, -11, -13,
- -16, -12, 0, 20, 24, 9, 9, 19, 44, 47, 25, 6, 2, 11, -1, -21,
- -27, -19, -17, -20, -23, -17, -5, -5, -14, -20, 0, 15, -4, -7, -17, -17,
- -8, 7, 25, 18, 7, 11, 31, 54, 41, 14, -1, 10, 3, -14, -27, -29,
- -21, -16, -16, -18, -17, -11, -10, -16, -16, 10, 6, -3, -9, -19, -16, -2,
- 18, 27, 16, 8, 19, 45, 54, 29, 5, 6, 4, -9, -18, -29, -30, -18,
- -10, -9, -14, -20, -12, -13, -17, -5, 12, 7, 2, -16, -22, -13, 8, 25,
- 23, 12, 11, 32, 53, 48, 17, 9, 9, -7, -16, -24, -37, -28, -12, -4,
- -2, -18, -21, -18, -23, -17, 7, 11, 10, -4, -16, -22, -7, 21, 28, 18,
- 9, 20, 43, 55, 37, 11, 11, 1, -14, -17, -31, -34, -21, -10, 4, -2,
- -20, -23, -26, -29, -3, 6, 13, 8, -5, -23, -27, 7, 28, 27, 15, 12,
- 32, 48, 50, 24, 9, 8, -12, -19, -26, -37, -35, -19, 3, 6, -12, -21,
- -31, -38, -17, 6, 4, 14, 6, -8, -35, -15, 19, 26, 21, 7, 23, 43,
- 52, 42, 14, 9, -2, -16, -21, -25, -33, -33, -4, 13, 3, -13, -30, -47,
- -37, 1, 6, 7, 12, 6, -15, -31, -1, 22, 30, 14, 9, 37, 48, 50,
- 26, 8, 6, -11, -22, -22, -25, -45, -22, 13, 15, 1, -22, -43, -56, -21,
- 7, 6, 10, 15, -7, -25, -21, 7, 28, 21, 2, 25, 47, 53, 39, 11,
- 10, 1, -20, -22, -18, -37, -42, 2, 15, 15, -8, -32, -57, -48, -9, 9,
- 5, 14, 8, -14, -20, -13, 17, 33, 8, 9, 37, 52, 55, 25, 7, 8,
- -11, -23, -15, -23, -47, -20, 12, 21, 10, -23, -50, -57, -31, 2, 10, 9,
- 11, -8, -10, -18, -3, 30, 22, 1, 22, 45, 57, 45, 11, 11, 0, -23,
- -22, -16, -36, -36, -6, 15, 18, -3, -43, -56, -49, -21, 5, 11, 12, -2,
- -8, -9, -15, 12, 31, 9, 10, 34, 48, 60, 29, 16, 10, -17, -24, -21,
- -27, -31, -17, 5, 14, 12, -22, -50, -48, -41, -9, 7, 13, -1, -8, -2,
- -11, -5, 26, 19, 6, 21, 37, 55, 49, 25, 22, -5, -20, -24, -26, -29,
- -23, -9, 8, 13, -1, -41, -48, -47, -30, -3, 12, 7, -12, -2, 1, -8,
- 10, 20, 11, 16, 26, 40, 54, 42, 36, 7, -13, -18, -26, -29, -26, -14,
- -2, 7, 8, -18, -45, -48, -45, -19, 6, 11, -10, -8, 5, -7, 2, 12,
- 17, 15, 16, 23, 45, 55, 48, 27, -7, -12, -18, -30, -31, -17, -5, -3,
- 4, 5, -24, -40, -50, -38, -8, 8, 1, -13, 1, -1, 3, 8, 15, 18,
- 15, 15, 28, 52, 59, 47, 9, -9, -10, -25, -40, -29, -3, -5, -13, 1,
- 3, -26, -47, -53, -23, -2, 5, -11, -6, 4, 6, 10, 10, 19, 11, 13,
- 15, 42, 61, 61, 32, 3, -5, -12, -35, -43, -14, 1, -16, -13, 9, -1,
- -33, -57, -46, -19, -3, -1, -16, -2, 5, 15, 6, 17, 9, 5, 9, 26,
- 54, 65, 52, 21, 3, -6, -21, -48, -33, -4, -7, -22, -2, 18, -4, -47,
- -58, -33, -11, 2, -13, -15, 3, 16, 15, 9, 15, -1, 5, 14, 48, 66,
- 65, 37, 23, 2, -11, -42, -48, -20, -4, -23, -18, 18, 19, -17, -61, -52,
- -27, -2, -5, -24, -7, 9, 20, 14, 18, 2, -3, 7, 34, 63, 68, 50,
- 37, 19, -9, -25, -49, -38, -14, -14, -28, 6, 25, 9, -40, -62, -45, -17,
- 3, -21, -16, -3, 12, 18, 18, 10, -6, 0, 16, 56, 69, 63, 43, 38,
- 2, -20, -42, -44, -33, -14, -25, -10, 22, 18, -11, -55, -57, -37, -3, -10,
- -26, -10, 2, 17, 21, 20, -3, -2, 5, 39, 67, 73, 56, 47, 22, -17,
- -35, -43, -36, -28, -18, -20, 9, 22, 8, -33, -56, -53, -26, -2, -23, -24,
- -11, 4, 23, 30, 4, -3, 0, 27, 60, 71, 69, 58, 43, -6, -35, -43,
- -35, -36, -27, -18, -2, 19, 17, -9, -41, -51, -45, -10, -12, -31, -21, -9,
- 8, 33, 17, 0, 2, 8, 50, 69, 75, 70, 64, 16, -31, -47, -35, -32,
- -34, -25, -14, 10, 16, 5, -26, -42, -50, -32, -8, -22, -31, -22, -8, 22,
- 32, 7, 6, 4, 28, 63, 69, 71, 78, 43, -20, -51, -41, -23, -34, -30,
- -22, 2, 13, 9, -10, -31, -45, -44, -21, -19, -27, -36, -26, 2, 29, 24,
- 12, 11, 13, 45, 69, 68, 81, 70, 6, -47, -52, -28, -23, -27, -26, -14,
- 11, 10, -2, -18, -33, -43, -34, -25, -22, -36, -44, -14, 14, 29, 27, 22,
- 18, 29, 60, 65, 71, 86, 41, -32, -57, -41, -23, -22, -22, -24, -4, 10,
- 0, -11, -21, -31, -37, -37, -29, -29, -53, -33, -3, 16, 33, 31, 27, 23,
- 46, 64, 65, 85, 71, -4, -48, -47, -31, -20, -15, -15, -19, 1, 0, -5,
- -14, -21, -26, -40, -39, -28, -51, -50, -18, 4, 26, 38, 36, 30, 32, 61,
- 64, 70, 80, 31, -35, -43, -40, -25, -19, -6, -17, -11, 0, -6, -11, -17,
- -15, -31, -47, -39, -45, -62, -34, -8, 12, 36, 38, 41, 37, 51, 65, 60,
- 71, 56, -7, -36, -38, -35, -27, -11, -5, -17, -8, -8, -9, -17, -13, -20,
- -37, -47, -50, -62, -49, -16, 1, 25, 34, 43, 53, 49, 62, 58, 62, 65,
- 22, -23, -31, -34, -35, -19, -3, -8, -18, -7, -4, -14, -17, -9, -27, -40,
- -56, -68, -64, -27, -4, 9, 28, 37, 54, 60, 61, 59, 54, 63, 43, -1,
- -25, -23, -37, -28, -8, 4, -10, -15, -3, -7, -26, -15, -11, -29, -51, -71,
- -71, -49, -8, 5, 14, 30, 48, 66, 68, 63, 51, 56, 51, 18, -18, -20,
- -25, -39, -23, -5, 3, -13, -6, -5, -21, -28, -10, -18, -43, -67, -78, -64,
- -25, 1, 8, 15, 38, 60, 75, 74, 58, 54, 57, 28, -7, -18, -8, -31,
- -34, -15, 4, -2, -4, 0, -15, -32, -21, -8, -28, -57, -77, -75, -44, -12,
- 6, 8, 20, 49, 68, 77, 71, 53, 61, 41, 3, -18, -4, -14, -36, -28,
- -7, 1, 7, 6, -8, -34, -35, -16, -15, -41, -66, -75, -59, -31, -4, 10,
- 11, 31, 56, 72, 85, 63, 58, 55, 14, -17, -10, -1, -24, -30, -22, -6,
- 11, 16, 9, -27, -43, -27, -15, -26, -53, -63, -66, -46, -21, 3, 13, 15,
- 40, 63, 83, 78, 60, 67, 38, -9, -20, 4, -7, -23, -25, -22, 6, 24,
- 20, -8, -48, -43, -24, -16, -39, -55, -57, -57, -36, -10, 9, 11, 22, 50,
- 73, 88, 71, 65, 59, 14, -24, -9, -3, -15, -18, -31, -14, 25, 28, 10,
- -36, -56, -41, -21, -29, -48, -47, -51, -50, -26, -2, 11, 6, 30, 57, 82,
- 83, 69, 65, 35, -12, -16, -3, -10, -12, -21, -26, 11, 33, 26, -7, -56,
- -54, -32, -26, -41, -39, -37, -52, -41, -16, 5, 7, 11, 37, 72, 91, 78,
- 66, 55, 11, -19, -14, -15, -9, -7, -19, -8, 22, 30, 13, -32, -62, -44,
- -31, -34, -40, -29, -40, -46, -29, -8, 2, 1, 18, 49, 84, 86, 72, 67,
- 39, -6, -21, -25, -16, 2, -6, -12, 6, 23, 18, -7, -51, -56, -39, -33,
- -41, -30, -24, -41, -36, -17, -8, -5, 7, 32, 66, 84, 78, 75, 58, 20,
- -15, -29, -33, 2, 4, -1, 1, 11, 17, 4, -27, -56, -46, -36, -37, -39,
- -22, -24, -38, -23, -16, -16, -7, 18, 46, 72, 82, 81, 72, 44, -1, -25,
- -41, -18, 14, 8, 10, 0, 5, 2, -11, -40, -50, -42, -38, -37, -33, -11,
- -27, -26, -20, -22, -13, 0, 31, 52, 73, 82, 80, 61, 26, -16, -37, -40,
- 0, 18, 17, 12, -5, -8, -10, -21, -41, -43, -44, -36, -35, -20, -12, -23,
- -14, -32, -21, -12, 15, 38, 58, 76, 82, 72, 46, 4, -26, -41, -23, 14,
- 25, 18, 2, -23, -18, -14, -29, -35, -45, -42, -35, -29, -15, -19, -3, -23,
- -32, -19, -1, 27, 40, 67, 81, 76, 61, 26, -11, -33, -36, -6, 28, 28,
- 13, -15, -38, -19, -20, -26, -36, -46, -35, -32, -20, -21, -4, -4, -28, -25,
- -16, 13, 31, 49, 74, 79, 69, 48, 8, -16, -33, -21, 7, 33, 24, 5,
- -32, -38, -22, -21, -22, -41, -43, -32, -25, -23, -16, 6, -9, -29, -28, -5,
- 20, 39, 58, 75, 71, 60, 22, 0, -18, -27, -10, 16, 30, 15, -14, -49,
- -34, -19, -16, -27, -43, -31, -25, -27, -24, -1, 7, -15, -32, -22, 3, 28,
- 50, 61, 67, 59, 38, 13, 5, -17, -16, -3, 21, 23, 3, -34, -49, -28,
- -17, -19, -34, -34, -18, -26, -32, -16, 14, 6, -23, -34, -11, 14, 44, 54,
- 56, 60, 44, 25, 18, 2, -18, -9, 3, 21, 9, -14, -45, -39, -24, -22,
- -28, -32, -18, -17, -36, -30, 5, 21, -5, -31, -27, 1, 30, 56, 46, 50,
- 47, 32, 29, 20, -4, -9, -9, 4, 10, -2, -28, -38, -31, -33, -26, -26,
- -19, -9, -24, -38, -11, 24, 10, -17, -36, -14, 14, 48, 49, 37, 43, 39,
- 33, 32, 11, 1, -5, -11, -6, -3, -16, -29, -28, -40, -38, -27, -20, -6,
- -11, -31, -29, 15, 22, 0, -25, -25, 2, 31, 51, 38, 35, 41, 41, 34,
- 27, 8, 6, -7, -20, -14, -7, -20, -19, -34, -52, -35, -23, -11, -5, -18,
- -33, -5, 26, 5, -11, -27, -11, 17, 43, 43, 30, 29, 46, 45, 38, 17,
- 6, 2, -22, -27, -16, -16, -18, -18, -53, -48, -23, -19, -3, -10, -21, -19,
- 18, 12, -6, -20, -21, 6, 29, 42, 31, 23, 37, 54, 48, 31, 13, 13,
- -13, -31, -25, -16, -16, -11, -38, -62, -33, -28, -7, -3, -12, -17, 6, 16,
- 2, -11, -17, -5, 15, 35, 34, 25, 23, 44, 55, 41, 22, 14, 2, -29,
- -32, -23, -11, -13, -18, -60, -50, -32, -16, -6, -11, -4, 3, 11, 3, -1,
- -14, -8, 5, 20, 39, 31, 24, 26, 54, 57, 37, 16, 8, -19, -32, -27,
- -17, -17, -17, -36, -58, -40, -32, -11, -11, -2, 6, 10, 2, 0, -4, -12,
- 1, 8, 33, 42, 26, 17, 35, 63, 53, 26, 6, -9, -27, -30, -25, -17,
- -23, -24, -47, -51, -38, -17, -11, -6, 12, 17, 8, -8, -1, -10, -7, 4,
- 18, 40, 33, 18, 22, 49, 70, 46, 12, -11, -16, -23, -27, -19, -28, -26,
- -36, -50, -48, -31, -13, -13, 10, 20, 21, 0, -6, -1, -7, 3, 15, 32,
- 40, 24, 17, 31, 58, 67, 28, -2, -21, -14, -31, -18, -24, -33, -33, -49,
- -49, -41, -18, -20, -2, 20, 23, 19, -12, -7, -2, -3, 10, 22, 33, 37,
- 21, 23, 39, 72, 51, 10, -17, -18, -20, -29, -17, -33, -36, -49, -48, -47,
- -24, -16, -15, 11, 24, 30, 6, -12, -2, -2, -1, 18, 29, 35, 27, 25,
- 25, 56, 63, 23, -5, -19, -14, -23, -21, -21, -38, -52, -54, -40, -32, -15,
- -23, -7, 18, 31, 22, -2, -7, 3, 0, 12, 21, 34, 31, 28, 22, 35,
- 66, 40, 2, -19, -19, -15, -21, -16, -30, -60, -62, -42, -33, -18, -18, -22,
- 4, 29, 29, 14, -2, -4, 5, 6, 16, 28, 36, 24, 29, 26, 52, 49,
- 14, -13, -24, -19, -14, -15, -17, -53, -75, -54, -32, -18, -11, -26, -18, 18,
- 28, 25, 13, -6, 4, 13, 9, 17, 37, 24, 28, 33, 37, 49, 26, 1,
- -19, -26, -16, -11, -7, -33, -77, -71, -45, -15, -8, -18, -30, 1, 25, 21,
- 26, 3, 5, 17, 14, 11, 33, 27, 17, 34, 38, 42, 33, 6, -11, -28,
- -22, -12, -3, -16, -60, -81, -62, -25, -2, -14, -27, -17, 20, 18, 24, 18,
- 6, 16, 21, 12, 24, 28, 12, 26, 44, 42, 35, 13, -5, -21, -31, -18,
- -2, -2, -42, -77, -76, -47, -10, -6, -22, -24, 4, 16, 18, 25, 18, 18,
- 24, 20, 20, 32, 14, 11, 40, 49, 41, 21, -6, -13, -27, -28, -5, 5,
- -18, -59, -79, -63, -30, -6, -11, -28, -11, 8, 10, 23, 27, 17, 24, 25,
- 25, 28, 19, 8, 25, 47, 46, 27, -5, -15, -18, -33, -20, -5, -3, -35,
- -70, -66, -51, -22, -7, -21, -19, -3, 6, 17, 29, 26, 23, 28, 25, 32,
- 23, 14, 11, 39, 50, 38, 3, -19, -10, -21, -29, -12, -3, -12, -55, -65,
- -56, -42, -14, -10, -23, -11, -3, 10, 23, 32, 26, 28, 28, 35, 29, 22,
- 13, 18, 41, 43, 18, -16, -18, -14, -29, -21, -11, -8, -32, -61, -52, -52,
- -30, -11, -18, -16, -10, 2, 22, 35, 30, 25, 32, 34, 40, 27, 19, 11,
- 23, 39, 32, -1, -22, -14, -22, -23, -14, -11, -17, -45, -52, -51, -51, -22,
- -17, -19, -17, -10, 11, 35, 39, 29, 26, 34, 43, 43, 27, 16, 12, 25,
- 31, 18, -13, -20, -19, -22, -12, -14, -15, -28, -44, -47, -53, -33, -15, -22,
- -24, -20, 5, 27, 38, 31, 21, 27, 46, 51, 40, 18, 8, 13, 23, 24,
- 3, -21, -22, -22, -8, -9, -22, -26, -31, -40, -51, -44, -17, -15, -26, -31,
- -10, 24, 35, 37, 25, 21, 42, 57, 53, 30, 11, 7, 11, 21, 12, -11,
- -23, -25, -12, 0, -18, -32, -31, -30, -45, -46, -26, -13, -25, -39, -25, 15,
- 36, 29, 25, 20, 37, 58, 63, 46, 15, 3, -2, 19, 16, -2, -19, -25,
- -23, 4, -4, -31, -36, -29, -32, -43, -37, -17, -16, -39, -43, -2, 34, 31,
- 21, 17, 30, 62, 67, 62, 27, 9, -9, 3, 26, 8, -18, -26, -26, -5,
- 9, -23, -44, -33, -26, -33, -40, -28, -12, -30, -52, -24, 23, 33, 15, 14,
- 22, 54, 75, 68, 47, 14, -9, -12, 19, 23, -12, -20, -20, -13, 11, -6,
- -40, -41, -19, -23, -34, -34, -14, -13, -48, -48, 4, 35, 23, 7, 13, 40,
- 77, 78, 57, 31, -3, -18, 3, 27, 7, -24, -19, -16, 1, 5, -29, -49,
- -28, -13, -26, -34, -26, -4, -30, -57, -24, 22, 30, 6, 7, 31, 63, 86,
- 68, 42, 10, -19, -13, 15, 25, -10, -22, -14, -7, 6, -11, -45, -40, -14,
- -24, -35, -31, -12, -8, -51, -44, -2, 29, 11, -1, 22, 47, 74, 78, 49,
- 25, -8, -26, -4, 26, 12, -16, -19, -11, -1, -1, -28, -45, -22, -13, -29,
- -29, -23, -1, -26, -55, -26, 14, 20, -3, 13, 39, 63, 80, 61, 33, 8,
- -22, -25, 10, 22, -1, -14, -15, -7, -1, -14, -37, -26, -13, -25, -28, -26,
- -2, -5, -48, -44, -7, 18, 3, 9, 30, 49, 71, 70, 45, 23, -13, -33,
- -5, 22, 11, -7, -17, -14, -6, -8, -29, -29, -15, -19, -26, -31, -15, 6,
- -25, -52, -30, 7, 7, 2, 21, 40, 60, 67, 52, 33, 7, -29, -19, 16,
- 22, 4, -8, -15, -11, -6, -23, -24, -10, -11, -23, -27, -22, 1, 0, -34,
- -45, -14, 2, 1, 15, 35, 52, 62, 49, 36, 21, -16, -26, 1, 20, 12,
- -7, -10, -20, -10, -19, -28, -9, -8, -15, -26, -27, -11, 2, -15, -41, -34,
- -10, -7, 6, 32, 48, 56, 51, 35, 26, 1, -24, -10, 15, 18, 2, -9,
- -17, -18, -11, -32, -6, 2, -9, -18, -22, -17, -3, -2, -21, -34, -26, -13,
- -8, 20, 47, 53, 52, 38, 24, 5, -14, -15, 9, 14, 4, -6, -14, -21,
- -14, -28, -22, 12, 0, -10, -23, -24, -13, 2, -10, -23, -34, -26, -13, 4,
- 39, 58, 51, 45, 28, 6, -9, -11, 3, 17, 7, -3, -10, -18, -15, -22,
- -35, 2, 18, 2, -11, -23, -20, -1, 0, -15, -24, -39, -25, -6, 17, 52,
- 56, 47, 35, 6, -10, -8, 0, 13, 13, -2, -9, -13, -13, -25, -43, -16,
- 21, 19, -3, -21, -25, -10, 2, -5, -14, -30, -40, -13, -1, 34, 58, 51,
- 44, 18, -10, -9, -2, 6, 12, 7, -7, -12, -12, -18, -40, -33, 9, 32,
- 19, -9, -23, -15, 1, 3, -9, -18, -40, -28, -4, 7, 47, 59, 49, 24,
- 1, -13, -5, 1, 10, 11, 5, -12, -12, -15, -35, -42, -9, 23, 33, 9,
- -22, -24, -5, 1, -5, -12, -30, -40, -7, -3, 22, 56, 58, 35, 11, -12,
- -9, -5, -1, 7, 13, -4, -13, -13, -25, -43, -29, 10, 34, 32, -6, -27,
- -8, 3, -5, -13, -22, -40, -18, -3, -1, 37, 61, 46, 23, -5, -13, -4,
- -4, -7, 12, 14, -10, -18, -22, -34, -35, -10, 22, 39, 23, -15, -14, 5,
- 3, -8, -15, -36, -23, -1, -7, 14, 51, 57, 37, 8, -13, -7, -2, -14,
- -6, 20, 3, -21, -26, -27, -30, -27, 1, 28, 36, 7, -10, 0, 5, -8,
- -14, -30, -29, -3, -10, -5, 31, 56, 46, 19, -7, -10, 3, -11, -21, 9,
- 19, -10, -30, -29, -19, -24, -20, 10, 35, 29, 8, -1, 5, -2, -13, -28,
- -33, -3, -1, -13, 12, 49, 55, 31, -1, -12, 2, -3, -26, -2, 21, 2,
- -28, -34, -21, -17, -29, -12, 23, 34, 19, 6, 7, 4, -4, -23, -40, -10,
- 7, -12, -2, 34, 55, 36, 8, -10, 1, 3, -19, -18, 15, 15, -10, -33,
- -30, -9, -19, -25, 4, 32, 30, 16, 11, 10, 3, -15, -35, -27, 9, -4,
- -10, 16, 52, 42, 12, -7, -6, 4, -6, -21, -2, 17, 0, -20, -41, -13,
- -9, -31, -16, 18, 34, 23, 14, 9, 10, -7, -26, -34, -3, 10, -10, 2,
- 42, 51, 16, -8, -11, -2, -2, -11, -9, 9, 2, -8, -36, -31, 3, -23,
- -30, -1, 27, 27, 23, 15, 18, 3, -17, -31, -19, 8, 1, -4, 24, 51,
- 30, -11, -16, -6, -3, -5, -10, 3, 1, -10, -22, -41, -4, -6, -29, -18,
- 12, 25, 26, 23, 20, 11, -10, -21, -27, -4, 7, 0, 13, 41, 40, 3,
- -24, -11, -1, -2, -3, 5, 5, -14, -15, -35, -20, 0, -19, -24, -4, 11,
- 23, 31, 24, 16, -3, -13, -23, -14, 2, 3, 18, 32, 38, 21, -20, -29,
- -5, -2, 0, 5, 11, -14, -22, -25, -26, -3, -11, -26, -11, -2, 8, 32,
- 34, 24, 2, -8, -16, -13, 1, 1, 10, 31, 31, 33, 1, -36, -22, 0,
- 0, 8, 18, -3, -27, -22, -22, -10, -9, -24, -16, -5, -16, 16, 40, 34,
- 8, -3, -13, -12, 1, 1, 3, 30, 30, 24, 18, -28, -35, -13, -2, 6,
- 19, 10, -25, -28, -15, -9, -10, -19, -20, -3, -15, -8, 27, 42, 25, 1,
- -14, -18, 7, 9, -1, 19, 37, 19, 23, -10, -41, -26, -9, 2, 20, 19,
- -17, -35, -21, 0, -9, -18, -20, -7, -8, -24, 6, 37, 43, 14, -10, -22,
- 3, 18, 4, 6, 36, 23, 16, 4, -32, -37, -19, -3, 17, 27, 0, -37,
- -34, -3, 7, -17, -27, -19, -1, -20, -13, 17, 44, 35, 2, -22, -9, 19,
- 20, 2, 26, 32, 15, 5, -17, -40, -29, -9, 10, 28, 17, -23, -41, -21,
- 9, -2, -27, -30, -5, -7, -21, -4, 27, 47, 27, -14, -21, 11, 29, 14,
- 15, 32, 20, 4, -11, -31, -38, -15, 2, 22, 22, -3, -32, -34, -6, 8,
- -13, -38, -19, 0, -16, -14, 6, 37, 39, 11, -18, -4, 25, 25, 16, 24,
- 27, 7, -10, -24, -38, -25, 0, 12, 23, 8, -16, -31, -23, 0, 0, -27,
- -33, -2, -9, -16, -11, 17, 41, 32, 5, -15, 12, 25, 24, 21, 27, 14,
- -4, -21, -31, -29, -4, 9, 19, 9, -9, -19, -25, -10, -5, -15, -38, -13,
- -6, -13, -17, -1, 30, 36, 27, -2, 2, 20, 24, 25, 24, 19, 2, -16,
- -32, -29, -13, 8, 18, 16, -6, -13, -21, -15, -14, -13, -26, -22, -6, -11,
- -14, -14, 11, 30, 37, 17, 1, 13, 20, 23, 24, 21, 5, -10, -32, -31,
- -15, 0, 17, 22, -3, -15, -17, -11, -15, -19, -23, -22, -8, -8, -13, -18,
- -8, 18, 40, 38, 12, 12, 15, 21, 23, 24, 7, -9, -22, -34, -19, -6,
- 11, 30, 9, -17, -20, -16, -11, -22, -30, -27, -8, -7, -10, -19, -16, -2,
- 32, 52, 31, 17, 16, 13, 21, 19, 19, -9, -17, -30, -25, -7, 3, 29,
- 25, -9, -21, -20, -11, -14, -29, -37, -14, 2, -5, -14, -22, -12, 13, 50,
- 49, 27, 23, 15, 13, 9, 18, 7, -22, -22, -28, -11, -5, 19, 35, 13,
- -20, -24, -18, -8, -22, -38, -31, 2, 3, -6, -26, -22, -3, 38, 56, 42,
- 34, 21, 12, 6, 11, 17, -15, -24, -20, -15, -6, 9, 29, 29, -4, -28,
- -23, -14, -13, -30, -39, -16, 9, 6, -12, -33, -16, 19, 57, 49, 41, 30,
- 13, 4, -1, 6, -4, -27, -21, -13, -6, 2, 12, 34, 12, -24, -24, -20,
- -16, -24, -38, -33, 2, 12, -2, -30, -31, 2, 45, 59, 46, 41, 24, 8,
- -3, -6, 1, -15, -25, -16, -3, 5, 2, 21, 28, -11, -26, -23, -18, -20,
- -32, -40, -14, 14, 11, -10, -40, -20, 30, 60, 55, 42, 34, 15, 6, -12,
- -12, -4, -19, -21, -9, 8, 4, 10, 28, 6, -25, -22, -20, -22, -29, -38,
- -27, 5, 16, 4, -24, -39, 12, 51, 61, 51, 41, 27, 10, -7, -25, -9,
- -10, -17, -15, 0, 9, 5, 21, 15, -13, -27, -17, -21, -23, -38, -33, -11,
- 10, 6, -4, -38, -17, 36, 55, 55, 45, 35, 21, 4, -27, -25, -2, -10,
- -14, -13, 3, 5, 14, 16, 0, -24, -21, -18, -22, -36, -39, -17, -3, 5,
- 3, -15, -28, 16, 50, 53, 52, 43, 29, 13, -14, -36, -10, -1, -15, -15,
- -6, 6, 5, 13, 4, -11, -24, -17, -18, -27, -43, -18, -12, -7, 4, 3,
- -17, -4, 38, 53, 52, 48, 41, 23, 0, -31, -30, 2, -7, -14, -13, -5,
- 3, 11, 7, -4, -21, -25, -21, -19, -39, -23, -9, -19, -8, 5, -1, -10,
- 24, 46, 48, 46, 44, 32, 10, -18, -37, -7, 0, -12, -14, -13, -4, 8,
- 9, 1, -16, -29, -28, -17, -33, -31, -6, -21, -21, -4, 12, 3, 13, 41,
- 46, 44, 46, 44, 20, -7, -36, -27, 6, -3, -18, -21, -12, 2, 12, 6,
- -5, -27, -36, -21, -20, -34, -12, -8, -29, -16, 11, 15, 10, 28, 47, 46,
- 41, 45, 35, 5, -24, -30, -5, 3, -14, -26, -16, -7, 7, 8, -3, -18,
- -39, -32, -16, -28, -26, -8, -23, -26, 0, 19, 16, 20, 42, 55, 45, 38,
- 39, 20, -11, -24, -13, -2, -6, -25, -22, -7, -5, 13, 0, -11, -36, -41,
- -20, -16, -29, -16, -14, -28, -12, 13, 17, 15, 32, 50, 57, 41, 38, 30,
- 2, -14, -9, -3, -3, -19, -33, -10, -7, 7, 7, -13, -30, -42, -28, -13,
- -17, -26, -14, -22, -15, 7, 19, 15, 26, 46, 59, 51, 34, 33, 12, -7,
- -11, -4, -5, -13, -38, -23, -3, 3, 15, -7, -32, -45, -34, -21, -11, -27,
- -25, -21, -19, -1, 13, 15, 22, 37, 53, 62, 46, 34, 15, -2, 0, -4,
- -8, -9, -34, -38, -8, 4, 17, 3, -25, -50, -44, -26, -12, -13, -32, -24,
- -20, -7, 11, 18, 17, 33, 50, 65, 57, 41, 24, 0, 5, 5, -9, -11,
- -25, -44, -25, -1, 17, 13, -18, -42, -51, -33, -20, -7, -27, -29, -23, -16,
- 0, 14, 14, 28, 48, 60, 66, 51, 34, 4, 0, 15, -3, -14, -20, -35,
- -37, -12, 12, 27, -7, -37, -50, -40, -29, -15, -15, -30, -24, -15, -7, 6,
- 17, 25, 46, 59, 68, 63, 43, 20, -6, 14, 10, -8, -20, -30, -34, -22,
- -2, 24, 15, -30, -49, -49, -37, -28, -15, -26, -28, -18, -11, -7, 7, 27,
- 42, 58, 70, 70, 53, 35, 4, 0, 18, -1, -15, -32, -31, -26, -12, 12,
- 28, -4, -44, -53, -44, -39, -25, -23, -28, -19, -11, -12, -16, 13, 42, 56,
- 71, 71, 57, 45, 23, -3, 10, 11, -6, -27, -35, -25, -22, -1, 23, 17,
- -29, -54, -46, -44, -39, -29, -28, -21, -15, -15, -26, -12, 39, 57, 70, 73,
- 60, 49, 41, 13, 1, 11, 0, -16, -32, -25, -15, -14, 10, 23, -5, -48,
- -46, -42, -49, -43, -31, -24, -15, -13, -24, -32, 18, 59, 71, 77, 67, 57,
- 47, 33, 3, 5, 5, -9, -23, -33, -16, -14, -5, 17, 12, -29, -44, -35,
- -50, -57, -43, -30, -18, -11, -22, -39, -9, 44, 68, 82, 69, 61, 49, 42,
- 18, 5, 5, -8, -12, -26, -14, -7, -9, 5, 16, -6, -36, -32, -42, -62,
- -55, -39, -29, -15, -14, -34, -30, 20, 59, 82, 79, 66, 58, 45, 38, 9,
- 1, -7, -11, -16, -19, -3, -6, -6, 9, 5, -22, -32, -32, -58, -70, -56,
- -42, -24, -16, -25, -39, -9, 41, 72, 86, 73, 65, 46, 40, 30, -4, -7,
- -14, -12, -20, -3, 4, -5, 1, 8, -9, -27, -25, -40, -67, -67, -55, -38,
- -24, -17, -25, -28, 16, 61, 81, 82, 71, 60, 37, 42, 17, -14, -17, -11,
- -13, -8, 10, 2, -2, 1, -1, -17, -20, -26, -54, -69, -70, -58, -34, -25,
- -16, -23, -9, 37, 70, 87, 80, 68, 44, 38, 39, -5, -27, -19, -12, -6,
- 13, 10, 4, 1, 1, -5, -19, -20, -37, -59, -71, -71, -54, -35, -17, -9,
- -20, 11, 49, 80, 86, 72, 54, 36, 45, 23, -25, -34, -16, -9, 11, 17,
- 8, 5, -4, -2, -15, -19, -26, -50, -69, -77, -71, -51, -29, -7, -11, -6,
- 26, 64, 87, 78, 60, 40, 42, 45, 2, -38, -34, -12, 10, 24, 10, 11,
- 3, -1, -6, -20, -16, -31, -61, -81, -80, -69, -41, -16, -5, -8, 10, 47,
- 81, 86, 70, 44, 36, 48, 32, -21, -48, -31, -3, 24, 24, 10, 15, 0,
- 2, -17, -21, -18, -45, -81, -87, -80, -57, -33, -11, -6, 2, 30, 74, 86,
- 77, 55, 34, 42, 48, 13, -39, -50, -20, 15, 34, 14, 16, 12, 4, -5,
- -26, -16, -19, -64, -92, -91, -65, -43, -26, -12, -1, 16, 47, 83, 76, 66,
- 40, 33, 45, 33, -8, -52, -41, -5, 32, 30, 15, 25, 13, 8, -22, -28,
- -11, -34, -85, -101, -86, -52, -36, -25, -13, 15, 32, 69, 80, 69, 52, 32,
- 37, 39, 19, -30, -54, -24, 10, 38, 25, 25, 22, 18, -6, -35, -20, -14,
- -59, -98, -99, -68, -41, -30, -23, 5, 28, 52, 74, 67, 59, 43, 32, 35,
- 32, -2, -47, -38, -13, 23, 33, 31, 26, 27, 16, -29, -37, -15, -33, -80,
- -104, -89, -54, -35, -31, -11, 17, 42, 63, 68, 60, 59, 37, 27, 33, 22,
- -28, -37, -26, 3, 32, 38, 30, 25, 30, -3, -41, -29, -23, -55, -90, -98,
- -76, -39, -32, -21, 4, 36, 52, 61, 61, 63, 48, 24, 28, 34, -10, -31,
- -29, -14, 15, 37, 37, 28, 31, 19, -27, -40, -24, -38, -69, -95, -96, -60,
- -32, -26, -10, 19, 45, 53, 58, 59, 58, 29, 23, 39, 14, -21, -25, -23,
- 1, 27, 43, 34, 34, 21, 0, -36, -32, -31, -49, -84, -102, -83, -41, -22,
- -19, -1, 35, 49, 52, 53, 56, 39, 23, 34, 33, -3, -23, -22, -10, 17,
- 36, 36, 39, 26, 8, -16, -34, -29, -36, -61, -93, -95, -58, -26, -18, -11,
- 22, 48, 53, 53, 51, 41, 31, 33, 37, 16, -15, -24, -14, 4, 29, 34,
- 41, 32, 8, -7, -19, -28, -30, -54, -83, -101, -76, -40, -20, -21, 1, 36,
- 54, 55, 44, 33, 32, 35, 36, 30, 7, -26, -19, -5, 22, 36, 37, 37,
- 15, -3, -5, -15, -24, -43, -75, -94, -87, -47, -29, -25, -14, 26, 48, 62,
- 49, 29, 23, 35, 45, 38, 19, -16, -28, -7, 10, 29, 32, 38, 23, -2,
- -10, -6, -12, -28, -67, -90, -98, -59, -32, -28, -25, 3, 43, 56, 59, 25,
- 16, 24, 46, 43, 31, 0, -31, -14, 5, 25, 29, 32, 29, 6, -13, -6,
- -3, -8, -49, -85, -97, -75, -31, -30, -30, -12, 31, 50, 61, 40, 12, 14,
- 34, 53, 43, 20, -23, -20, -3, 21, 29, 23, 24, 15, -10, -8, -1, 2,
- -25, -75, -98, -92, -42, -31, -35, -24, 14, 41, 50, 49, 22, 11, 20, 45,
- 52, 39, 0, -26, -12, 9, 35, 25, 18, 14, 1, -13, -6, 4, 3, -49,
- -89, -102, -61, -27, -30, -27, -4, 34, 46, 46, 32, 17, 13, 26, 47, 50,
- 29, -19, -22, -4, 30, 37, 15, 7, 7, -5, -10, -4, 9, -20, -72, -100,
- -86, -41, -33, -31, -16, 18, 43, 34, 32, 27, 23, 15, 31, 47, 48, 9,
- -24, -16, 12, 43, 25, -2, 0, 9, -9, -15, 2, 8, -40, -87, -99, -69,
- -37, -31, -19, 6, 38, 35, 25, 31, 35, 26, 18, 36, 49, 40, -10, -22,
- -9, 29, 40, 6, -12, 6, 6, -16, -11, 9, -6, -61, -95, -90, -58, -35,
- -26, -5, 23, 36, 18, 21, 36, 41, 28, 22, 38, 52, 23, -17, -17, 7,
- 39, 21, -12, -13, 16, -8, -22, -5, 6, -25, -77, -93, -79, -46, -30, -11,
- 15, 36, 22, 5, 29, 47, 47, 24, 22, 41, 48, 7, -15, -4, 22, 33,
- 6, -23, 4, 8, -21, -15, -1, -5, -49, -79, -92, -71, -43, -20, 11, 31,
- 29, 4, 16, 40, 55, 41, 22, 31, 50, 25, -9, -2, 8, 23, 16, -17,
- -6, 8, -10, -15, -6, -4, -29, -56, -80, -86, -61, -42, 0, 30, 33, 12,
- 2, 24, 47, 55, 37, 28, 39, 40, 4, -1, 6, 6, 16, -4, -13, 1,
- -2, -9, -11, -11, -21, -35, -55, -82, -80, -64, -24, 27, 36, 23, 3, 10,
- 35, 61, 55, 40, 35, 35, 19, 6, 12, 4, 1, 3, -12, -3, -2, -4,
- -4, -14, -23, -30, -37, -58, -83, -84, -58, 8, 37, 33, 11, 3, 20, 46,
- 62, 55, 50, 28, 16, 12, 15, 9, -4, -9, -9, -4, -5, -7, 2, -7,
- -28, -35, -31, -36, -67, -90, -86, -23, 28, 38, 25, 5, 13, 34, 58, 58,
- 69, 50, 15, 10, 20, 16, -3, -14, -14, -2, 1, -12, -3, 3, -20, -36,
- -39, -26, -46, -81, -98, -61, 6, 27, 30, 16, 12, 25, 50, 57, 66, 74,
- 31, 4, 16, 21, 8, -13, -21, -10, 8, -5, -11, 6, -8, -31, -40, -29,
- -30, -66, -93, -84, -22, 17, 22, 26, 16, 20, 43, 56, 56, 70, 60, 17,
- 8, 18, 15, -10, -26, -21, 6, 7, -12, -1, 1, -20, -33, -34, -31, -51,
- -79, -92, -52, -6, 9, 19, 23, 21, 40, 57, 59, 60, 72, 43, 17, 13,
- 18, 3, -23, -32, -5, 14, -7, -11, 7, -12, -26, -31, -37, -46, -66, -85,
- -67, -21, -5, 3, 16, 22, 37, 54, 59, 55, 60, 58, 30, 16, 13, 11,
- -15, -34, -23, 9, 7, -12, -2, -4, -19, -16, -31, -49, -64, -76, -72, -35,
- -12, -14, 0, 15, 34, 53, 60, 58, 53, 57, 43, 30, 18, 12, -4, -27,
- -28, -8, 14, -3, -9, -2, -13, -9, -17, -49, -66, -70, -69, -44, -15, -19,
- -11, 2, 21, 53, 64, 68, 55, 48, 44, 36, 28, 15, -1, -18, -23, -19,
- -4, 5, -3, 1, -9, -7, -1, -35, -70, -74, -70, -50, -21, -14, -22, -7,
- -1, 39, 66, 77, 69, 46, 38, 36, 38, 22, 5, -12, -16, -12, -17, -8,
- -5, 2, 1, -6, 5, -13, -64, -78, -73, -60, -31, -14, -17, -16, -10, 7,
- 61, 79, 81, 57, 38, 28, 32, 24, 9, -4, -10, -4, -11, -20, -13, -2,
- 11, 4, 4, -2, -41, -76, -76, -69, -43, -22, -12, -17, -14, -14, 25, 74,
- 92, 79, 47, 31, 26, 26, 11, 3, -5, 0, 0, -20, -26, -11, 9, 14,
- 9, 4, -24, -61, -76, -74, -53, -30, -13, -8, -12, -25, -8, 51, 90, 93,
- 63, 42, 21, 18, 13, 6, 2, 1, 8, -12, -30, -27, -2, 14, 18, 11,
- -13, -48, -68, -79, -70, -44, -19, -2, -5, -21, -31, 18, 77, 100, 81, 55,
- 29, 7, 8, 6, 7, 4, 14, 0, -26, -34, -13, 9, 16, 17, 1, -35,
- -58, -70, -82, -62, -29, -2, 1, -14, -36, -15, 50, 89, 95, 71, 46, 5,
- -6, 4, 11, 3, 11, 14, -12, -31, -22, -2, 8, 16, 16, -15, -53, -56,
- -80, -81, -41, -5, 9, -3, -30, -34, 17, 73, 97, 86, 63, 25, -12, -6,
- 11, 13, 1, 15, 4, -19, -25, -5, 2, 9, 19, 10, -39, -48, -61, -95,
- -67, -17, 12, 8, -23, -43, -9, 49, 85, 91, 76, 50, 1, -23, 2, 22,
- 5, 2, 14, -5, -23, -12, 0, -2, 13, 17, -15, -48, -43, -83, -88, -38,
- 5, 17, -11, -41, -28, 27, 67, 83, 82, 65, 29, -21, -18, 21, 19, -7,
- 3, 6, -8, -14, 1, 0, 0, 13, 2, -34, -42, -59, -99, -63, -12, 17,
- 0, -35, -42, 1, 53, 69, 79, 72, 53, -1, -34, 2, 32, 3, -8, 1,
- 2, -2, -3, 8, -2, 3, 7, -18, -40, -39, -76, -81, -35, 9, 17, -22,
- -46, -24, 34, 59, 68, 74, 66, 27, -26, -22, 31, 24, -10, -11, 0, 14,
- 1, 5, 8, -5, -2, -10, -34, -35, -48, -77, -59, -13, 20, -4, -37, -35,
- 8, 47, 55, 68, 74, 49, -4, -34, 10, 39, 1, -13, -11, 14, 14, 3,
- 20, 6, -9, -14, -29, -37, -28, -56, -66, -42, 9, 9, -25, -38, -14, 27,
- 45, 54, 72, 61, 21, -25, -14, 31, 19, -10, -15, -2, 22, 6, 22, 24,
- -4, -20, -28, -38, -24, -28, -54, -57, -20, 14, -10, -29, -26, 2, 29, 39,
- 61, 66, 39, -6, -25, 16, 30, 0, -16, -8, 12, 13, 18, 38, 10, -20,
- -36, -34, -31, -16, -33, -56, -42, 0, 0, -21, -22, -12, 11, 25, 49, 68,
- 53, 14, -20, -3, 29, 15, -11, -12, 3, 13, 13, 42, 34, -12, -39, -37,
- -27, -22, -18, -44, -50, -21, 3, -12, -15, -18, -5, 9, 27, 60, 60, 32,
- -6, -12, 21, 25, -4, -12, -2, 7, 8, 33, 53, 8, -37, -41, -25, -22,
- -16, -27, -47, -34, -10, -10, -15, -15, -15, -5, 5, 41, 63, 44, 12, -11,
- 10, 32, 10, -14, -8, 8, 5, 19, 53, 34, -24, -43, -25, -14, -15, -19,
- -35, -35, -20, -12, -8, -14, -17, -19, -13, 19, 55, 53, 22, -8, 4, 31,
- 26, -8, -13, 6, 10, 7, 39, 50, -2, -41, -31, -10, -13, -23, -31, -33,
- -24, -15, -7, -13, -16, -22, -23, -6, 38, 55, 34, 1, -1, 23, 34, 9,
- -18, -3, 14, 9, 20, 51, 24, -28, -37, -6, 2, -20, -30, -27, -21, -22,
- -6, -12, -17, -21, -32, -27, 9, 49, 43, 12, -4, 14, 34, 24, -9, -12,
- 12, 19, 13, 30, 37, -3, -35, -15, 12, -10, -31, -30, -15, -18, -13, -3,
- -19, -20, -31, -35, -17, 28, 44, 22, 0, 7, 28, 27, 5, -15, 1, 20,
- 20, 17, 28, 19, -21, -23, 12, 8, -22, -32, -20, -8, -15, 0, -13, -23,
- -25, -43, -36, 4, 37, 30, 11, 4, 22, 28, 15, 0, -10, 9, 23, 14,
- 11, 24, 5, -21, 2, 17, -8, -27, -27, -7, -10, -6, -1, -20, -26, -39,
- -53, -20, 23, 36, 17, 7, 14, 28, 16, 12, -3, 2, 19, 16, 2, 14,
- 19, -8, -5, 17, 4, -15, -26, -10, -4, -12, 1, -8, -23, -38, -58, -41,
- 0, 29, 23, 11, 16, 21, 15, 9, 11, -6, 11, 20, 4, 3, 24, 5,
- -5, 10, 17, -6, -15, -15, 6, -15, -8, 0, -11, -37, -54, -56, -24, 13,
- 29, 12, 15, 20, 19, 6, 16, 5, -2, 10, 11, -3, 22, 18, 0, 6,
- 20, 10, -6, -12, 1, -6, -23, 0, 1, -23, -56, -60, -43, -10, 19, 22,
- 15, 22, 18, 6, 11, 17, -2, -5, 10, 4, 7, 23, 1, 3, 16, 22,
- 5, -1, 0, 5, -21, -14, 6, -6, -46, -64, -54, -29, 1, 17, 18, 24,
- 25, 10, 1, 17, 9, -8, -1, 15, 6, 20, 11, 2, 14, 25, 16, 9,
- 5, 7, -11, -26, -5, 4, -27, -62, -62, -40, -17, 8, 11, 21, 29, 17,
- -2, 10, 17, -8, -16, 6, 13, 11, 15, 3, 8, 24, 26, 14, 12, 12,
- 4, -26, -15, 1, -12, -50, -64, -48, -27, -10, 5, 8, 32, 31, 1, -1,
- 18, 0, -23, -6, 18, 14, 11, 5, 3, 17, 35, 25, 16, 18, 14, -11,
- -27, -8, -6, -30, -55, -53, -36, -20, -5, 5, 14, 43, 13, -6, 11, 11,
- -22, -22, 7, 19, 13, 10, 1, 7, 30, 36, 22, 23, 23, 6, -28, -20,
- -6, -23, -43, -49, -43, -29, -19, 3, 1, 34, 29, -4, 3, 13, -13, -32,
- -3, 20, 14, 11, 5, 2, 23, 42, 34, 22, 23, 21, -13, -26, -14, -19,
- -32, -38, -43, -32, -29, -6, 4, 16, 35, 9, -4, 11, 0, -33, -22, 9,
- 13, 12, 9, 3, 14, 35, 47, 34, 23, 27, 8, -22, -19, -16, -30, -29,
- -42, -33, -32, -23, 4, 9, 24, 20, -1, 3, 10, -20, -36, -5, 13, 9,
- 11, 8, 8, 21, 43, 48, 27, 22, 23, -7, -25, -20, -28, -25, -31, -36,
- -28, -33, -8, 11, 14, 14, 6, -8, 7, -5, -39, -25, 7, 14, 9, 10,
- 12, 15, 29, 55, 41, 23, 22, 9, -12, -23, -28, -24, -23, -34, -26, -31,
- -21, 9, 19, 9, 1, -3, -1, 7, -32, -38, -9, 13, 11, 9, 11, 14,
- 21, 46, 53, 32, 24, 12, -2, -16, -26, -24, -17, -34, -33, -25, -24, -4,
- 17, 14, -3, -4, -7, 3, -13, -46, -25, 2, 17, 5, 8, 12, 18, 32,
- 56, 38, 29, 15, 8, -4, -22, -30, -14, -22, -42, -25, -15, -10, 6, 17,
- 1, -5, -7, -10, -2, -38, -37, -7, 15, 9, 2, 8, 21, 26, 43, 44,
- 29, 18, 7, 12, -9, -25, -24, -11, -35, -43, -17, -5, 3, 10, 9, -3,
- -3, -23, -9, -23, -45, -22, 7, 15, 2, 4, 17, 33, 31, 45, 35, 23,
- 8, 17, 6, -16, -26, -14, -20, -48, -27, -2, 6, 11, 9, -1, 6, -15,
- -28, -18, -39, -32, -7, 11, 7, 6, 7, 33, 30, 31, 41, 27, 7, 13,
- 24, -3, -18, -22, -9, -40, -41, -10, 4, 9, 17, 3, 5, -4, -37, -29,
- -29, -35, -19, 1, 10, 3, 7, 25, 41, 19, 31, 32, 13, 5, 27, 14,
- -6, -19, -12, -23, -48, -22, 7, 8, 16, 11, 1, 6, -29, -46, -32, -32,
- -20, -5, 7, 4, 3, 21, 43, 32, 15, 29, 16, 8, 19, 26, 3, -9,
- -22, -13, -42, -37, -8, 11, 14, 25, 9, 4, -17, -50, -44, -30, -25, -14,
- -1, 11, 1, 18, 36, 41, 12, 14, 18, 14, 15, 20, 17, 6, -14, -18,
- -27, -39, -19, 5, 12, 24, 27, 8, -13, -49, -53, -32, -27, -19, -12, 7,
- 7, 12, 31, 43, 26, 2, 8, 14, 22, 13, 17, 18, 6, -17, -26, -36,
- -28, -6, 14, 25, 35, 20, -6, -42, -57, -37, -23, -23, -20, 0, 9, 8,
- 25, 41, 40, 7, -4, 1, 23, 21, 14, 22, 20, -2, -24, -34, -31, -13,
- 8, 24, 37, 33, 8, -32, -62, -44, -20, -22, -27, -9, 9, 7, 16, 31,
- 42, 20, -10, -13, 10, 26, 7, 13, 25, 18, -11, -35, -39, -20, 0, 17,
- 37, 37, 19, -17, -58, -55, -26, -18, -25, -21, 0, 14, 12, 20, 38, 35,
- 0, -19, -9, 24, 19, 3, 21, 31, 17, -24, -42, -30, -3, 13, 34, 42,
- 28, -2, -45, -62, -38, -22, -19, -20, -12, 12, 17, 11, 29, 42, 18, -16,
- -20, 3, 24, 2, 4, 26, 36, 0, -38, -45, -13, 12, 27, 41, 34, 14,
- -27, -62, -55, -30, -19, -15, -16, -2, 18, 11, 14, 37, 31, -6, -22, -12,
- 15, 10, -10, 12, 36, 30, -19, -46, -33, 11, 24, 28, 35, 28, -5, -44,
- -65, -44, -23, -11, -9, -8, 5, 14, 10, 25, 37, 14, -17, -18, -2, 14,
- -7, -6, 23, 43, 10, -33, -38, -9, 24, 24, 28, 30, 11, -21, -57, -61,
- -39, -12, -5, -5, -3, 7, 10, 17, 31, 30, -3, -20, -14, 6, 1, -16,
- 2, 38, 38, -5, -30, -24, 13, 25, 21, 28, 15, 1, -34, -64, -62, -23,
- 0, 2, -1, -1, 5, 14, 24, 33, 14, -12, -23, -4, 7, -18, -18, 18,
- 43, 25, -9, -22, -2, 21, 19, 24, 20, 11, -13, -47, -69, -46, -7, 5,
- 6, -1, -4, 9, 21, 31, 25, 5, -15, -20, 3, -8, -33, -7, 29, 37,
- 20, -10, -10, 9, 15, 17, 14, 12, 1, -23, -55, -70, -30, 5, 13, 2,
- -8, -1, 15, 25, 30, 15, -1, -20, -8, -3, -31, -28, 8, 31, 41, 15,
- -6, 0, 9, 14, 12, 9, 8, -10, -28, -63, -55, -12, 17, 11, -7, -13,
- 8, 22, 26, 19, 9, -7, -13, -5, -23, -39, -10, 17, 41, 38, 8, 0,
- 5, 7, 12, 5, 7, -6, -8, -39, -60, -35, 7, 19, 6, -10, -6, 15,
- 26, 22, 15, 9, -8, -13, -24, -45, -29, -1, 29, 48, 30, 2, 6, 5,
- 9, 5, -1, -5, -4, -13, -51, -51, -16, 20, 13, 0, -11, 7, 25, 22,
- 18, 17, 10, -8, -22, -50, -43, -13, 15, 46, 42, 16, 7, 8, 7, 7,
- -1, -6, -10, -4, -27, -45, -36, 5, 16, 7, -5, -5, 20, 22, 19, 19,
- 22, 7, -15, -43, -62, -29, 3, 35, 43, 27, 11, 9, 8, 4, 2, -9,
- -13, -7, -15, -30, -43, -16, 12, 13, 4, -8, 12, 24, 17, 16, 24, 25,
- -3, -38, -72, -52, -9, 25, 42, 30, 21, 8, 14, 4, 6, -3, -13, -12,
- -13, -18, -36, -34, 3, 14, 9, -9, 5, 26, 18, 13, 26, 34, 13, -31,
- -69, -68, -16, 19, 35, 29, 22, 6, 16, 3, 2, 6, -5, -15, -20, -19,
- -21, -34, -17, 8, 16, -2, -3, 24, 27, 16, 23, 34, 32, -10, -56, -80,
- -45, 6, 29, 29, 22, 10, 14, 13, -4, 6, 7, -8, -27, -27, -18, -20,
- -28, -8, 14, 8, -7, 11, 29, 21, 17, 25, 35, 16, -36, -77, -67, -14,
- 25, 30, 22, 11, 10, 19, 5, 2, 6, 5, -18, -34, -25, -13, -23, -19,
- 4, 13, 0, 7, 24, 32, 24, 22, 31, 30, -12, -62, -76, -41, 9, 28,
- 24, 15, 6, 18, 16, 6, 6, 7, -7, -32, -37, -16, -18, -24, -8, 11,
- 7, 7, 20, 31, 35, 25, 24, 33, 9, -40, -72, -58, -16, 17, 27, 16,
- 6, 10, 22, 12, 8, 8, 2, -23, -43, -26, -16, -24, -18, 2, 6, 7,
- 21, 29, 36, 32, 21, 27, 22, -21, -57, -67, -38, -4, 26, 21, 9, 3,
- 18, 25, 18, 10, 2, -11, -42, -36, -24, -27, -23, -9, 5, 2, 17, 32,
- 42, 36, 27, 18, 25, -2, -39, -58, -51, -27, 11, 27, 11, 1, 9, 24,
- 25, 21, 5, -8, -31, -37, -30, -33, -24, -15, 0, -2, 13, 31, 48, 47,
- 33, 15, 18, 10, -27, -50, -52, -44, -12, 21, 21, 5, -1, 13, 33, 30,
- 16, -6, -26, -39, -33, -35, -28, -20, -10, -8, 4, 27, 51, 61, 45, 21,
- 13, 14, -11, -39, -40, -44, -36, 1, 25, 16, 1, 2, 27, 40, 28, 3,
- -22, -38, -38, -32, -33, -21, -18, -14, -8, 18, 50, 66, 60, 27, 7, 12,
- -3, -31, -36, -37, -46, -27, 18, 26, 5, -3, 8, 35, 43, 16, -14, -36,
- -43, -32, -32, -25, -16, -23, -14, 6, 46, 64, 74, 49, 9, 4, 7, -23,
- -37, -34, -41, -44, -8, 31, 19, -5, 0, 21, 47, 33, -2, -33, -43, -43,
- -32, -29, -14, -22, -23, -6, 34, 62, 75, 71, 30, 0, 8, -13, -37, -34,
- -35, -45, -34, 18, 31, 5, -5, 7, 35, 44, 12, -23, -45, -49, -40, -29,
- -18, -18, -27, -15, 22, 57, 74, 80, 57, 15, 4, -1, -39, -34, -34, -40,
- -46, -4, 25, 13, -3, 2, 22, 44, 25, -10, -38, -44, -50, -34, -20, -14,
- -31, -21, 5, 47, 63, 81, 76, 38, 8, 9, -30, -45, -35, -36, -43, -20,
- 9, 14, 5, 3, 7, 36, 32, 3, -32, -43, -50, -40, -28, -13, -24, -28,
- -2, 35, 56, 73, 86, 58, 23, 21, -10, -49, -45, -33, -39, -25, -3, 5,
- 5, 8, 5, 18, 32, 17, -19, -45, -49, -41, -35, -22, -19, -31, -12, 28,
- 52, 59, 76, 74, 41, 31, 10, -39, -58, -41, -32, -27, -5, -3, 3, 8,
- 8, 10, 24, 22, -4, -39, -52, -42, -35, -30, -18, -28, -22, 20, 53, 52,
- 60, 73, 62, 43, 31, -18, -56, -61, -35, -28, -9, -6, -3, 3, 9, 10,
- 12, 18, 8, -23, -53, -50, -31, -35, -24, -28, -26, 3, 48, 55, 52, 59,
- 66, 57, 46, 7, -37, -67, -53, -24, -11, -4, -6, 0, 3, 13, 10, 7,
- 10, -6, -38, -58, -36, -30, -30, -26, -26, -11, 33, 60, 56, 49, 59, 67,
- 58, 32, -15, -58, -69, -34, -14, -8, -6, 1, -4, 7, 8, 2, 4, 4,
- -21, -54, -49, -30, -30, -28, -29, -18, 13, 53, 60, 50, 44, 63, 61, 49,
- 11, -33, -71, -49, -19, -9, -10, 5, 2, -1, 4, -1, 4, 5, -5, -38,
- -55, -40, -28, -21, -25, -26, -2, 40, 61, 56, 39, 53, 66, 54, 33, -4,
- -55, -63, -29, -18, -12, 3, 11, -4, -4, -9, -3, 4, 4, -18, -49, -49,
- -35, -18, -18, -25, -16, 24, 51, 60, 42, 43, 66, 57, 42, 21, -23, -63,
- -44, -26, -18, -10, 13, 9, -8, -18, -17, 5, 5, -4, -35, -47, -42, -24,
- -11, -20, -21, 5, 36, 56, 53, 37, 60, 59, 40, 34, 11, -34, -52, -33,
- -21, -15, 1, 21, 2, -19, -33, -10, 8, 3, -20, -42, -41, -33, -14, -16,
- -18, -7, 21, 43, 54, 39, 47, 61, 44, 31, 27, -4, -41, -47, -28, -23,
- -9, 11, 15, -9, -34, -34, 1, 10, -2, -30, -38, -34, -18, -15, -17, -10,
- 10, 27, 43, 42, 42, 53, 54, 36, 24, 14, -15, -42, -36, -32, -22, 1,
- 13, 7, -26, -48, -24, 11, 10, -14, -35, -32, -19, -16, -15, -11, 5, 18,
- 31, 34, 41, 48, 51, 46, 28, 26, 8, -26, -36, -33, -35, -12, 7, 12,
- -8, -45, -47, -9, 13, 5, -24, -32, -17, -14, -16, -11, 6, 14, 20, 26,
- 27, 47, 49, 49, 34, 25, 22, -6, -31, -27, -39, -30, -10, 13, 6, -28,
- -57, -31, -3, 12, -7, -28, -19, -8, -21, -18, -2, 18, 17, 17, 19, 34,
- 47, 53, 42, 34, 30, 13, -22, -20, -30, -44, -32, -4, 15, -7, -45, -49,
- -18, 4, 10, -14, -18, 0, -11, -26, -7, 15, 23, 10, 10, 20, 34, 51,
- 49, 38, 41, 30, -8, -28, -15, -39, -47, -28, 5, 10, -26, -55, -34, -9,
- 10, 3, -13, -4, 1, -21, -19, 3, 25, 13, 5, 9, 18, 36, 54, 39,
- 40, 46, 16, -27, -17, -23, -47, -47, -18, 9, -2, -47, -51, -23, 0, 4,
- 0, 1, 9, -11, -20, -9, 20, 23, 4, 2, 8, 20, 45, 46, 38, 53,
- 41, -13, -30, -19, -36, -52, -40, -9, 5, -23, -53, -35, -6, 4, 3, 6,
- 10, 5, -16, -17, 6, 30, 12, 0, -4, 9, 32, 47, 43, 55, 57, 16,
- -27, -30, -28, -44, -52, -31, -6, -8, -43, -43, -15, -1, -1, 8, 10, 13,
- 2, -18, -11, 21, 23, 6, -5, 0, 19, 33, 41, 56, 67, 44, -5, -34,
- -35, -32, -46, -47, -27, -7, -30, -44, -23, -2, -2, 3, 7, 14, 18, -1,
- -19, 4, 20, 16, -5, -9, 10, 27, 30, 46, 65, 63, 26, -22, -42, -34,
- -41, -46, -40, -18, -25, -39, -28, -4, 1, -1, 5, 10, 24, 19, -8, -6,
- 11, 20, 4, -13, 2, 22, 24, 36, 59, 70, 51, 5, -39, -39, -43, -47,
- -45, -31, -30, -39, -33, -7, 1, -2, 1, 4, 19, 25, 5, -5, 1, 12,
- 13, -12, -12, 18, 25, 21, 46, 68, 69, 36, -17, -39, -44, -51, -43, -33,
- -35, -41, -38, -15, 8, 0, 0, 0, 13, 26, 19, 5, 0, -1, 10, -2,
- -14, 5, 25, 19, 29, 54, 71, 59, 9, -31, -43, -56, -50, -32, -38, -47,
- -42, -26, 8, 10, -3, -3, 7, 20, 23, 16, 8, -5, 3, 2, -17, -6,
- 22, 20, 18, 40, 66, 71, 37, -13, -36, -52, -61, -38, -32, -47, -51, -38,
- -7, 19, 6, -6, 4, 14, 19, 21, 19, 2, -5, 0, -13, -12, 14, 21,
- 13, 27, 53, 71, 57, 12, -25, -42, -61, -54, -33, -38, -52, -50, -22, 13,
- 17, -4, 1, 16, 17, 19, 25, 11, -2, -2, -11, -18, 6, 21, 15, 18,
- 43, 66, 67, 34, -7, -30, -49, -58, -42, -36, -42, -54, -36, -2, 20, 4,
- -4, 11, 16, 17, 26, 17, 4, 1, -8, -22, -8, 17, 16, 17, 27, 55,
- 66, 48, 10, -25, -36, -49, -52, -42, -39, -47, -46, -18, 13, 14, -1, 3,
- 13, 19, 27, 18, 2, 5, 1, -14, -17, 6, 13, 16, 26, 44, 64, 54,
- 27, -15, -30, -33, -49, -50, -43, -44, -45, -30, -1, 13, 3, 6, 10, 22,
- 30, 21, 3, 2, 2, -3, -18, -9, 8, 11, 23, 35, 55, 58, 37, 1,
- -25, -18, -33, -51, -48, -46, -41, -30, -17, 6, 3, 7, 9, 16, 30, 27,
- 9, 3, 3, 1, -10, -18, 0, 3, 12, 37, 46, 52, 40, 15, -23, -16,
- -14, -39, -48, -48, -45, -31, -20, -7, 1, 4, 14, 13, 21, 26, 16, 2,
- 1, 1, 1, -16, -12, 1, 5, 29, 50, 47, 39, 21, -11, -21, -3, -23,
- -41, -45, -47, -37, -21, -13, -6, 1, 16, 20, 22, 22, 18, 10, 2, 1,
- 6, -7, -16, -10, 0, 16, 51, 53, 38, 22, -1, -21, -1, -4, -30, -41,
- -45, -45, -28, -13, -13, -8, 13, 24, 26, 15, 13, 15, 8, -4, 1, -2,
- -11, -15, -11, 2, 40, 56, 44, 21, 1, -16, -10, 5, -16, -32, -38, -41,
- -36, -22, -14, -15, 4, 24, 32, 18, 7, 14, 14, 4, -2, -1, -8, -12,
- -15, -6, 24, 50, 51, 28, 1, -13, -14, 4, 1, -18, -31, -35, -36, -33,
- -21, -21, -5, 19, 38, 23, 3, 5, 17, 15, 2, -3, -7, -8, -18, -14,
- 12, 39, 50, 35, 2, -14, -14, -3, 6, -6, -24, -27, -32, -40, -25, -22,
- -12, 8, 35, 34, 10, 2, 5, 19, 9, -6, -4, -3, -15, -18, 4, 30,
- 42, 40, 13, -17, -16, -7, 3, 5, -14, -21, -24, -41, -37, -23, -18, -1,
- 22, 37, 17, 4, -1, 11, 17, 1, -7, -4, -12, -22, -6, 24, 35, 33,
- 25, -7, -26, -15, 2, 14, 3, -16, -19, -33, -42, -27, -23, -10, 15, 28,
- 27, 8, 2, 5, 20, 11, -4, -6, -7, -19, -11, 17, 31, 26, 25, 6,
- -24, -25, -6, 11, 14, -3, -13, -25, -39, -33, -23, -17, 7, 19, 26, 19,
- 4, 1, 15, 14, -1, -5, -10, -14, -22, 8, 33, 28, 20, 16, -13, -26,
- -17, 9, 22, 5, -8, -18, -37, -35, -28, -23, -4, 12, 16, 28, 12, 1,
- 12, 18, 3, -2, -9, -10, -27, -10, 29, 34, 18, 16, 2, -26, -29, -3,
- 27, 19, -4, -10, -29, -36, -30, -29, -12, 9, 3, 18, 21, 7, 12, 17,
- 3, -2, -7, -7, -19, -26, 15, 36, 21, 12, 9, -15, -30, -18, 19, 30,
- 6, -5, -21, -32, -25, -29, -22, 6, 0, 3, 20, 14, 12, 18, 12, 0,
- -9, -12, -9, -26, -4, 31, 28, 11, 10, -6, -24, -29, 3, 35, 19, -3,
- -15, -26, -19, -23, -31, -6, 4, -7, 13, 19, 17, 20, 18, 9, -9, -19,
- -5, -17, -20, 16, 34, 18, 9, 0, -16, -25, -10, 30, 29, 3, -10, -19,
- -19, -16, -29, -19, 3, -9, -5, 13, 21, 24, 16, 13, 1, -23, -14, -12,
- -19, -2, 28, 21, 8, 1, -11, -23, -19, 16, 41, 14, -8, -13, -9, -13,
- -18, -27, -4, -5, -12, -1, 19, 31, 18, 10, 16, -20, -22, -13, -14, -12,
- 18, 26, 12, 4, -4, -17, -18, -1, 38, 31, -5, -14, -7, -7, -14, -24,
- -13, -3, -13, -12, 7, 30, 34, 14, 18, -5, -33, -18, -10, -14, 1, 19,
- 14, 6, -8, -13, -15, -2, 19, 40, 8, -13, -9, -4, -8, -18, -20, -9,
- -14, -16, -7, 22, 37, 23, 16, 10, -26, -28, -13, -9, -5, 14, 14, 9,
- -9, -17, -13, -1, 8, 31, 26, -6, -10, -4, -2, -12, -19, -11, -11, -17,
- -12, 6, 34, 29, 15, 16, -7, -35, -25, -9, -6, 8, 14, 12, 1, -15,
- -14, 3, 10, 19, 29, 8, -10, -9, 1, -7, -20, -10, -9, -17, -17, -1,
- 30, 35, 18, 15, 5, -28, -33, -17, -6, -4, 8, 13, 5, -14, -19, 1,
- 14, 14, 20, 17, 0, -8, -2, -3, -14, -18, -9, -12, -18, -6, 21, 37,
- 26, 7, 10, -13, -33, -24, -6, -2, 0, 9, 11, -5, -19, -7, 16, 18,
- 13, 18, 11, -2, -6, -3, -6, -22, -10, -11, -16, -11, 17, 34, 32, 9,
- 9, 2, -26, -30, -14, -2, -5, 3, 8, 3, -16, -12, 8, 21, 13, 13,
- 15, 2, -3, -5, -5, -20, -16, -8, -16, -20, 6, 32, 34, 14, -4, 6,
- -12, -26, -20, -7, -6, -4, 4, 7, -2, -15, 1, 17, 15, 9, 15, 10,
- 0, -3, -7, -15, -22, -4, -7, -19, -7, 29, 36, 20, -6, -1, 0, -17,
- -19, -12, -9, -7, -1, 2, 6, -3, -8, 10, 18, 9, 8, 21, 4, -2,
- -8, -13, -20, -12, -2, -16, -14, 14, 39, 26, -3, -17, 1, -6, -16, -12,
- -7, -9, -9, 0, 3, 11, -3, 0, 15, 13, 3, 19, 12, -8, -6, -14,
- -19, -16, 0, -6, -17, 3, 33, 35, 5, -18, -9, 1, -15, -11, -8, -8,
- -16, -8, 1, 15, 15, 3, 11, 19, 2, 12, 26, 0, -10, -13, -21, -11,
- 1, -1, -18, -2, 23, 35, 17, -12, -21, -2, -8, -9, -8, -9, -12, -17,
- -5, 10, 22, 8, 7, 18, 7, -1, 23, 13, -13, -19, -23, -14, 5, 2,
- -15, -13, 17, 30, 22, -3, -24, -7, -2, -9, -6, -10, -8, -21, -19, 5,
- 22, 22, 13, 15, 13, -3, 11, 18, -4, -20, -28, -20, 4, 11, -10, -18,
- 6, 26, 17, 3, -20, -12, -2, -11, -7, -8, -8, -16, -27, -7, 19, 30,
- 21, 19, 15, 4, 3, 18, 2, -17, -33, -24, 0, 17, 1, -16, -6, 24,
- 19, 5, -17, -18, 1, -8, -12, -7, -11, -10, -22, -14, 10, 29, 29, 32,
- 23, 13, 0, 9, 6, -12, -28, -36, -7, 13, 12, -8, -17, 12, 24, 6,
- -10, -20, 1, 1, -13, -9, -12, -16, -20, -17, 0, 21, 27, 31, 35, 20,
- 7, 0, 2, -13, -19, -37, -19, 8, 18, 9, -16, -9, 20, 11, -2, -25,
- -13, 8, -4, -16, -13, -18, -23, -17, 0, 14, 29, 27, 43, 35, 17, -1,
- -4, -13, -22, -29, -31, -2, 17, 20, -5, -21, 6, 16, 5, -16, -25, 4,
- 11, -12, -17, -20, -27, -19, -2, 13, 26, 27, 36, 46, 32, 7, -8, -18,
- -26, -25, -32, -16, 12, 26, 11, -18, -11, 4, 13, -1, -27, -12, 14, 2,
- -21, -23, -31, -26, -11, 10, 24, 30, 29, 43, 50, 24, -4, -16, -34, -28,
- -28, -27, -1, 27, 24, -5, -21, -12, 6, 16, -13, -28, 1, 13, -9, -23,
- -33, -32, -18, 2, 24, 34, 33, 34, 50, 49, 12, -11, -34, -37, -28, -25,
- -14, 14, 28, 10, -10, -25, -9, 21, 15, -27, -15, 12, 2, -18, -33, -36,
- -24, -7, 13, 30, 39, 42, 35, 54, 36, 1, -29, -45, -35, -26, -17, -1,
- 20, 19, 2, -23, -30, 1, 30, -5, -32, 1, 7, -8, -27, -37, -25, -12,
- -1, 23, 37, 51, 38, 41, 49, 16, -15, -41, -40, -31, -21, -11, 4, 19,
- 15, -8, -33, -19, 22, 20, -21, -13, 2, -6, -17, -36, -32, -11, -8, 9,
- 28, 48, 54, 36, 48, 30, 3, -30, -41, -34, -24, -15, -6, 2, 17, 8,
- -19, -37, 0, 31, 3, -20, -6, -4, -7, -31, -35, -9, -3, -4, 16, 37,
- 62, 44, 41, 33, 13, -11, -36, -39, -29, -21, -11, -11, 6, 14, -2, -28,
- -24, 15, 22, -5, -10, -11, -10, -20, -35, -13, 2, -5, 2, 21, 55, 64,
- 46, 37, 19, 2, -23, -36, -28, -23, -17, -18, -17, 10, 11, -12, -32, -7,
- 23, 16, -7, -14, -17, -8, -27, -23, 1, 1, 0, 6, 31, 63, 60, 46,
- 21, 7, -12, -29, -24, -18, -24, -23, -27, -11, 11, 5, -16, -19, 11, 21,
- 4, -9, -21, -15, -17, -30, -5, 7, 2, -1, 9, 48, 65, 59, 30, 13,
- -4, -25, -19, -6, -22, -33, -32, -31, -3, 7, -3, -20, -4, 14, 11, -1,
- -11, -19, -13, -20, -16, 9, 7, 2, -3, 27, 60, 69, 44, 12, 7, -18,
- -20, 1, -4, -35, -38, -34, -22, -9, 4, -2, -11, 8, 8, 2, -6, -19,
- -23, -14, -16, 3, 13, 2, 2, 12, 47, 65, 62, 22, 10, -3, -21, -9,
- 9, -17, -46, -40, -34, -23, -6, 4, -1, 3, 7, 2, -4, -13, -25, -18,
- -11, -4, 18, 3, -2, 5, 30, 58, 66, 39, 12, 9, -10, -18, 8, 5,
- -41, -49, -38, -33, -18, -4, 2, 7, 8, 2, -7, -12, -18, -23, -12, -6,
- 18, 15, -8, 0, 21, 44, 62, 48, 22, 14, 7, -16, -7, 18, -18, -52,
- -44, -42, -32, -18, -1, 12, 10, 6, -8, -20, -11, -18, -19, -10, 14, 24,
- 2, -5, 14, 34, 57, 51, 27, 19, 20, -1, -13, 15, -1, -42, -45, -49,
- -38, -28, -15, 13, 19, 10, -1, -23, -16, -11, -24, -10, 6, 21, 14, -5,
- 3, 24, 48, 58, 29, 17, 24, 18, -6, 4, 8, -28, -38, -46, -50, -36,
- -29, 3, 22, 15, 4, -18, -31, -7, -20, -17, 5, 11, 18, 4, -2, 15,
- 37, 58, 35, 11, 26, 31, 11, -2, 6, -13, -32, -39, -55, -45, -38, -17,
- 21, 23, 11, -10, -31, -18, -11, -25, 1, 9, 14, 15, 0, 7, 26, 49,
- 49, 13, 10, 33, 26, 8, 4, -5, -25, -35, -46, -53, -41, -35, 5, 24,
- 17, 0, -25, -26, -14, -24, -9, 6, 5, 17, 6, 6, 20, 38, 55, 30,
- 3, 25, 38, 18, 10, -4, -16, -30, -42, -51, -46, -41, -16, 21, 23, 14,
- -16, -30, -16, -17, -17, 0, 2, 12, 16, 3, 17, 28, 46, 49, 14, 13,
- 39, 30, 17, 4, -9, -20, -38, -49, -50, -50, -34, 4, 21, 20, 4, -29,
- -23, -15, -15, -8, -3, 7, 19, 8, 9, 26, 35, 47, 29, 6, 29, 35,
- 26, 13, -5, -18, -29, -42, -49, -51, -50, -16, 11, 23, 18, -17, -34, -14,
- -15, -9, -10, -2, 17, 14, 5, 21, 33, 44, 38, 14, 23, 37, 30, 20,
- 6, -8, -26, -34, -47, -52, -54, -34, 0, 16, 19, 5, -29, -20, -13, -10,
- -9, -10, 4, 19, 11, 13, 29, 37, 36, 22, 22, 39, 32, 23, 10, 2,
- -18, -32, -40, -54, -56, -49, -23, 8, 17, 11, -15, -26, -11, -13, -9, -15,
- -11, 14, 17, 10, 23, 34, 36, 24, 21, 35, 42, 26, 12, 2, -4, -23,
- -31, -47, -57, -50, -33, -7, 17, 11, -2, -18, -12, -12, -11, -10, -21, -6,
- 18, 19, 21, 33, 35, 28, 23, 34, 51, 40, 12, -2, 1, -9, -27, -43,
- -59, -53, -39, -23, 4, 15, 1, -10, -14, -9, -8, -10, -22, -18, 5, 19,
- 16, 27, 34, 28, 23, 27, 47, 53, 27, -3, -4, -1, -13, -33, -53, -57,
- -45, -31, -13, 14, 4, -4, -11, -9, -9, -11, -19, -28, -16, 10, 24, 23,
- 35, 24, 26, 26, 38, 60, 44, 2, -13, -3, -5, -19, -44, -58, -49, -33,
- -26, 1, 14, 1, -4, -5, 0, -7, -14, -29, -26, -11, 20, 27, 30, 32,
- 21, 27, 34, 59, 58, 22, -11, -10, -6, -10, -29, -55, -53, -38, -34, -16,
- 12, 9, -5, -8, 5, 1, -16, -31, -32, -28, 0, 26, 26, 33, 23, 24,
- 33, 49, 61, 37, 3, -15, -8, -11, -19, -43, -56, -44, -34, -25, -2, 17,
- 5, -11, 2, 12, -2, -23, -32, -35, -23, 14, 26, 27, 35, 23, 32, 45,
- 58, 47, 19, -5, -9, -10, -16, -27, -46, -48, -41, -34, -18, 11, 20, -6,
- -10, 12, 9, -18, -34, -38, -29, -7, 17, 27, 32, 30, 30, 46, 52, 51,
- 28, 6, -8, -9, -15, -24, -32, -41, -45, -40, -30, -1, 23, 10, -12, 2,
- 17, -2, -31, -39, -32, -18, -6, 18, 29, 38, 32, 45, 54, 54, 33, 11,
- 2, -9, -11, -19, -32, -33, -41, -45, -40, -18, 16, 19, 2, -6, 13, 12,
- -20, -43, -35, -21, -18, -5, 21, 35, 36, 46, 58, 52, 38, 17, 9, -5,
- -9, -13, -29, -32, -28, -41, -43, -36, 0, 22, 18, -4, -3, 17, 2, -33,
- -43, -25, -18, -16, 4, 27, 38, 47, 64, 57, 40, 18, 10, 5, -7, -10,
- -22, -39, -24, -30, -42, -39, -22, 13, 28, 14, -9, 3, 17, -16, -51, -36,
- -17, -23, -18, 8, 35, 50, 66, 68, 43, 23, 12, 13, -1, -11, -17, -32,
- -27, -22, -40, -38, -37, -10, 22, 34, 1, -10, 8, 6, -39, -48, -27, -19,
- -25, -10, 18, 49, 66, 78, 54, 26, 17, 16, 3, -7, -15, -25, -29, -12,
- -32, -37, -35, -28, 3, 38, 26, -7, -4, 11, -15, -46, -42, -26, -23, -24,
- -2, 34, 66, 81, 70, 30, 19, 21, 10, -5, -11, -25, -29, -12, -20, -37,
- -33, -39, -17, 25, 46, 6, -11, 2, 0, -29, -44, -41, -30, -27, -17, 12,
- 58, 79, 84, 46, 19, 22, 19, 2, -7, -26, -35, -12, -1, -29, -33, -39,
- -36, 3, 46, 31, -11, -6, -1, -14, -38, -46, -39, -32, -22, -5, 40, 76,
- 88, 64, 23, 22, 30, 12, -8, -20, -39, -22, 0, -13, -29, -33, -43, -20,
- 24, 49, 13, -12, 2, -6, -26, -45, -45, -39, -32, -15, 19, 68, 85, 77,
- 32, 22, 35, 27, 0, -18, -36, -38, -6, 3, -17, -29, -44, -37, -2, 40,
- 34, -8, -6, 3, -18, -44, -47, -44, -43, -21, 3, 49, 76, 80, 53, 21,
- 35, 39, 15, -18, -35, -42, -23, 2, -3, -19, -33, -42, -23, 16, 46, 16,
- -8, 2, -6, -37, -45, -47, -51, -33, -8, 31, 68, 74, 66, 33, 35, 45,
- 36, -3, -33, -40, -34, -7, 5, -8, -18, -35, -39, -13, 32, 32, 3, -1,
- 5, -26, -46, -50, -52, -44, -20, 15, 59, 68, 69, 50, 32, 42, 48, 21,
- -26, -42, -42, -24, 2, 2, -8, -20, -38, -35, 6, 33, 17, -2, 5, -6,
- -41, -55, -57, -46, -33, -6, 40, 64, 62, 63, 45, 38, 54, 40, -4, -42,
- -50, -40, -11, 6, -2, -8, -24, -41, -19, 17, 28, 10, 0, 1, -26, -52,
- -64, -51, -40, -23, 19, 54, 56, 61, 60, 38, 52, 55, 24, -30, -50, -47,
- -27, 4, 8, -6, -11, -30, -36, -6, 19, 25, 4, 1, -9, -38, -64, -61,
- -42, -36, 0, 44, 55, 51, 66, 50, 49, 62, 46, -5, -48, -51, -40, -11,
- 11, 4, -14, -15, -36, -25, 1, 19, 15, -1, -2, -18, -53, -69, -48, -42,
- -20, 21, 51, 45, 56, 62, 51, 60, 59, 23, -32, -53, -49, -28, 5, 17,
- -12, -18, -22, -32, -12, 9, 20, 1, -6, -5, -29, -70, -62, -48, -32, 2,
- 36, 45, 44, 62, 62, 60, 64, 47, -10, -45, -54, -42, -11, 21, 5, -19,
- -18, -23, -20, -1, 15, 4, -6, -2, -6, -51, -72, -57, -44, -13, 19, 40,
- 41, 51, 65, 66, 69, 63, 14, -32, -47, -50, -30, 10, 14, -12, -16, -18,
- -16, -14, 7, 8, -6, -8, -1, -21, -65, -67, -54, -29, 1, 26, 38, 44,
- 53, 69, 77, 73, 37, -17, -41, -46, -37, -10, 13, -1, -11, -14, -14, -10,
- -6, 9, -5, -6, -11, -3, -43, -67, -68, -42, -15, 12, 27, 40, 47, 65,
- 80, 83, 55, 7, -34, -43, -34, -22, -5, 2, -3, -2, -13, -10, -11, 3,
- -2, -4, -13, -5, -15, -51, -72, -63, -31, -3, 16, 29, 42, 55, 78, 91,
- 68, 25, -11, -40, -32, -22, -21, -9, -1, 8, -1, -19, -11, -3, 1, -5,
- -11, -12, -3, -29, -58, -70, -48, -18, 6, 15, 35, 50, 68, 89, 84, 37,
- 11, -27, -38, -19, -20, -23, -8, 10, 18, -10, -19, -8, 4, 0, -11, -14,
- -7, -20, -42, -63, -60, -37, -4, 7, 23, 41, 67, 82, 90, 53, 19, -4,
- -34, -23, -20, -31, -22, 5, 25, 8, -17, -20, 0, 10, -5, -20, -9, -12,
- -31, -47, -60, -53, -26, -3, 12, 32, 58, 81, 85, 70, 27, 9, -19, -26,
- -19, -28, -31, -8, 24, 21, -2, -26, -11, 14, 10, -20, -18, -8, -24, -33,
- -53, -56, -44, -23, 3, 22, 44, 77, 85, 74, 40, 17, -3, -21, -21, -24,
- -36, -25, 11, 22, 15, -13, -28, 5, 23, 0, -28, -12, -19, -26, -42, -56,
- -48, -39, -17, 12, 34, 62, 84, 73, 52, 26, 9, -12, -21, -22, -31, -30,
- -1, 15, 16, 6, -25, -14, 23, 19, -17, -21, -13, -24, -34, -54, -44, -39,
- -36, -9, 27, 46, 79, 79, 59, 38, 16, -2, -17, -25, -25, -27, -10, 5,
- 10, 15, -4, -24, 5, 29, 5, -24, -18, -19, -28, -48, -50, -35, -38, -28,
- 10, 33, 62, 82, 62, 46, 27, 4, -8, -23, -24, -25, -15, -3, 0, 8,
- 6, -12, -9, 22, 25, -6, -21, -22, -28, -45, -53, -39, -30, -37, -11, 20,
- 43, 75, 66, 53, 41, 10, -8, -16, -25, -23, -15, -2, -4, -5, 4, 1,
- -7, 8, 29, 19, -9, -21, -24, -42, -55, -48, -30, -31, -19, 5, 23, 61,
- 74, 58, 53, 26, -7, -11, -18, -25, -14, 0, 1, -16, -8, 4, 0, 3,
- 20, 28, 11, -16, -19, -38, -58, -55, -35, -27, -16, -1, 5, 32, 63, 61,
- 56, 44, 3, -17, -13, -22, -19, -4, 5, -8, -21, -6, 7, 8, 12, 25,
- 25, 2, -17, -26, -54, -64, -47, -32, -11, 5, 3, 16, 40, 60, 58, 56,
- 26, -16, -19, -16, -20, -8, 0, -4, -20, -22, 1, 12, 9, 17, 30, 20,
- -2, -15, -42, -68, -57, -44, -19, 11, 6, 10, 19, 42, 58, 58, 45, 6,
- -23, -18, -13, -13, -3, -3, -10, -26, -14, 9, 15, 12, 26, 27, 10, -7,
- -25, -61, -68, -54, -36, 10, 15, 13, 16, 19, 42, 55, 52, 31, -9, -25,
- -18, -15, -7, -3, -9, -23, -26, -2, 15, 19, 19, 26, 18, 7, -10, -41,
- -72, -60, -51, -8, 25, 22, 20, 13, 19, 45, 51, 44, 19, -15, -28, -15,
- -7, -4, -9, -19, -28, -14, 6, 18, 18, 24, 22, 12, 1, -17, -55, -67,
- -56, -35, 19, 33, 30, 20, 9, 23, 44, 48, 39, 6, -22, -25, -9, -8,
- -9, -15, -29, -21, -3, 10, 16, 20, 23, 13, 7, -4, -31, -63, -61, -50,
- -11, 33, 37, 30, 12, 7, 24, 44, 48, 28, -4, -28, -14, -4, -14, -14,
- -27, -27, -8, 5, 13, 15, 19, 19, 11, 3, -12, -44, -64, -58, -31, 17,
- 40, 39, 24, 8, 3, 30, 46, 42, 16, -18, -21, -6, -16, -18, -26, -32,
- -15, 1, 6, 10, 10, 15, 12, 10, -3, -23, -51, -63, -50, -4, 34, 41,
- 33, 17, -4, 10, 35, 42, 32, 5, -15, -8, -10, -18, -21, -30, -22, 0,
- 3, -2, -2, 6, 5, 4, 3, -7, -25, -45, -45, -18, 25, 33, 32, 21,
- 7, 8, 20, 30, 31, 20, 3, -7, -10, -14, -17, -23, -29, -12, 6, -2,
- -11, -11, -4, 2, 3, -7, -10, -27, -33, -21, 13, 27, 23, 19, 8, 15,
- 17, 18, 21, 23, 19, 2, -12, -10, -9, -15, -27, -28, -2, 9, -8, -18,
- -17, -4, 9, -6, -7, -10, -17, -13, 2, 21, 20, 14, 4, 15, 25, 15,
- 11, 14, 19, 13, -13, -17, -6, -5, -20, -36, -23, 4, 6, -18, -28, -20,
- 6, 6, 0, 3, 5, 5, 28, 31, 31, 49, 55, 35, 11, 27, 26, 4,
- 7, 11, 31, 54, 38, 26, 34, 35, 20, -10, -32, -43, -47, -43, -20, -7,
- -37, -55, -62, -61, -63, -34, -21, -35, -28, -10, 15, 24, 23, 5, -31, -38,
- -6, 23, 19, 15, 24, 20, 31, 57, 54, 28, 13, 33, 20, 1, 4, 17,
- 38, 44, 33, 31, 43, 36, 10, -14, -34, -53, -53, -46, -22, -22, -38, -46,
- -54, -60, -58, -29, -25, -39, -29, -12, 11, 25, 27, 6, -31, -33, -3, 27,
- 32, 21, 13, 16, 38, 60, 53, 26, 18, 28, 11, -2, 8, 26, 37, 34,
- 36, 42, 47, 31, 6, -14, -41, -61, -54, -49, -26, -30, -41, -40, -44, -54,
- -48, -23, -28, -41, -33, -7, 14, 26, 29, 3, -32, -27, 6, 33, 35, 18,
- 5, 21, 45, 61, 49, 25, 30, 22, 0, -5, 9, 37, 39, 27, 33, 47,
- 50, 31, 1, -22, -51, -65, -59, -45, -31, -40, -36, -29, -35, -49, -41, -28,
- -39, -44, -26, -8, 6, 27, 31, -5, -31, -18, 14, 33, 31, 17, 4, 25,
- 48, 57, 45, 32, 27, 9, -6, -5, 14, 43, 36, 29, 39, 51, 50, 31,
- 0, -32, -65, -73, -62, -37, -36, -46, -36, -23, -26, -37, -32, -35, -46, -42,
- -22, -11, 2, 30, 28, -8, -29, -12, 22, 33, 32, 15, 4, 25, 49, 58,
- 50, 36, 20, 2, -9, -3, 21, 43, 37, 32, 44, 55, 53, 33, -7, -42,
- -67, -72, -64, -43, -43, -46, -35, -17, -17, -24, -31, -40, -47, -39, -18, -15,
- 0, 33, 22, -14, -22, 5, 29, 29, 28, 11, 7, 23, 49, 54, 50, 37,
- 13, -6, -11, -6, 25, 44, 38, 26, 40, 57, 54, 28, -12, -48, -70, -73,
- -66, -43, -43, -43, -29, -12, -15, -16, -32, -48, -51, -38, -24, -19, 4, 31,
- 12, -16, -14, 21, 34, 24, 24, 13, 10, 27, 49, 53, 53, 33, 6, -9,
- -16, -4, 33, 48, 37, 24, 45, 61, 54, 23, -15, -60, -76, -76, -60, -48,
- -45, -38, -26, -11, -3, -5, -33, -49, -52, -35, -25, -21, 7, 24, 1, -15,
- -1, 34, 30, 23, 29, 17, 5, 26, 49, 55, 53, 26, -3, -16, -16, 4,
- 38, 43, 33, 33, 49, 59, 45, 19, -18, -63, -78, -79, -58, -50, -39, -31,
- -21, -11, -2, -3, -30, -49, -51, -35, -29, -20, 8, 12, -10, -11, 17, 37,
- 27, 29, 29, 13, 2, 33, 56, 55, 38, 18, -7, -19, -17, 13, 40, 42,
- 33, 35, 52, 58, 40, 10, -28, -68, -84, -78, -56, -47, -36, -30, -17, -7,
- 5, -4, -30, -49, -51, -34, -30, -18, 10, 1, -18, -9, 30, 39, 26, 32,
- 28, 9, 7, 38, 51, 45, 35, 16, -13, -28, -11, 27, 41, 41, 34, 45,
- 58, 54, 29, 7, -33, -69, -80, -78, -59, -43, -31, -24, -15, -3, 9, -4,
- -29, -51, -51, -33, -27, -8, 8, -13, -24, -1, 40, 41, 29, 31, 22, 7,
- 15, 46, 48, 38, 33, 11, -19, -28, -7, 26, 42, 36, 39, 54, 54, 48,
- 20, 3, -39, -68, -79, -78, -54, -37, -32, -27, -16, 5, 11, -6, -31, -50,
- -49, -33, -24, -3, -3, -29, -26, 13, 44, 36, 30, 32, 17, 7, 28, 43,
- 37, 31, 28, 4, -17, -27, -5, 24, 46, 43, 48, 56, 50, 41, 20, -1,
- -47, -64, -82, -78, -48, -35, -34, -26, -14, 6, 9, -10, -31, -46, -43, -33,
- -21, 1, -16, -38, -15, 24, 38, 35, 44, 33, 10, 15, 37, 43, 30, 22,
- 18, 4, -20, -29, 0, 30, 43, 48, 54, 52, 46, 35, 19, -9, -41, -60,
- -83, -73, -44, -29, -37, -27, -12, 6, 8, -10, -28, -45, -43, -25, -9, -3,
- -33, -43, -4, 32, 35, 37, 49, 24, 7, 26, 47, 35, 17, 11, 14, 3,
- -21, -30, 6, 30, 44, 60, 56, 44, 37, 33, 15, -11, -40, -63, -82, -61,
- -36, -33, -39, -26, -13, 0, 4, -9, -29, -42, -37, -18, -7, -13, -39, -34,
- 2, 30, 34, 45, 49, 16, 11, 37, 45, 26, 11, 8, 9, -1, -26, -25,
- 17, 31, 46, 62, 52, 42, 29, 26, 15, -12, -45, -64, -71, -48, -34, -35,
- -33, -27, -16, 1, 2, -10, -23, -41, -32, -12, -6, -29, -46, -28, 12, 26,
- 36, 54, 43, 10, 23, 52, 43, 18, -2, 5, 5, -7, -25, -11, 19, 22,
- 49, 61, 50, 40, 24, 20, 15, -10, -47, -62, -62, -45, -34, -30, -30, -23,
- -16, -6, -1, -8, -25, -38, -29, -9, -10, -39, -42, -19, 5, 23, 48, 57,
- 33, 7, 32, 57, 39, 8, -7, 3, -2, -16, -16, 1, 20, 22, 48, 55,
- 46, 39, 17, 16, 17, -9, -48, -58, -54, -40, -37, -28, -26, -22, -23, -5,
- 2, -11, -28, -37, -27, -10, -18, -44, -35, -18, 3, 31, 54, 52, 25, 13,
- 45, 61, 29, -4, -10, 0, -5, -16, -8, 4, 21, 21, 50, 54, 45, 31,
- 4, 20, 18, -15, -43, -48, -48, -39, -33, -28, -25, -22, -21, 0, -1, -19,
- -29, -29, -22, -11, -29, -42, -30, -17, 3, 38, 61, 46, 24, 25, 53, 58,
- 20, -10, -9, -5, -16, -12, 4, 11, 22, 17, 48, 51, 43, 16, 2, 18,
- 13, -15, -35, -46, -43, -38, -31, -23, -27, -24, -13, 3, -8, -25, -29, -27,
- -22, -18, -36, -38, -31, -19, 6, 46, 60, 36, 24, 33, 56, 44, 10, -8,
- -9, -12, -24, -7, 14, 23, 18, 11, 45, 47, 39, 13, 5, 16, 1, -19,
- -22, -39, -45, -45, -31, -20, -24, -16, -6, -3, -19, -24, -25, -26, -22, -24,
- -39, -35, -25, -13, 8, 54, 64, 36, 29, 41, 56, 36, 5, -12, -11, -14,
- -26, -6, 24, 33, 7, 12, 45, 44, 30, 13, 10, 17, -4, -17, -16, -34,
- -46, -50, -30, -20, -23, -12, 1, -11, -26, -27, -24, -21, -19, -34, -48, -32,
- -23, -10, 13, 66, 65, 33, 32, 48, 55, 25, 0, -8, -1, -18, -36, -4,
- 40, 33, -1, 17, 37, 35, 25, 10, 14, 10, -13, -15, -9, -26, -46, -51,
- -32, -18, -15, -4, 3, -17, -31, -28, -25, -20, -26, -48, -48, -27, -20, -13,
- 19, 71, 61, 28, 33, 56, 50, 12, -8, -2, 5, -24, -41, 2, 52, 29,
- -1, 24, 36, 26, 16, 14, 19, 6, -19, -12, 1, -21, -49, -50, -28, -12,
- -3, 2, -2, -25, -32, -29, -24, -14, -31, -61, -44, -17, -15, -9, 28, 72,
- 61, 25, 38, 61, 41, 7, -7, 4, 3, -32, -36, 9, 45, 21, 4, 30,
- 33, 15, 11, 18, 17, -1, -18, -7, -4, -22, -47, -45, -24, -6, 2, 5,
- -7, -27, -34, -28, -21, -14, -42, -69, -40, -11, -16, -3, 41, 68, 53, 29,
- 48, 61, 32, 0, -5, 8, 2, -33, -28, 9, 31, 16, 16, 34, 22, 0,
- 10, 24, 10, -9, -19, -6, -8, -26, -38, -34, -20, -10, 1, 11, -9, -33,
- -31, -32, -25, -18, -50, -65, -40, -15, -8, 13, 47, 65, 50, 33, 54, 62,
- 24, -2, 2, 12, -6, -31, -20, 12, 21, 10, 28, 34, 9, -5, 20, 20,
- -2, -13, -10, -4, -18, -33, -26, -16, -19, -14, 6, 8, -14, -31, -32, -29,
- -29, -31, -51, -69, -47, -12, 2, 21, 49, 56, 43, 45, 62, 54, 16, -2,
- 7, 9, -13, -22, -4, 12, 7, 13, 37, 33, 7, -4, 23, 9, -8, -8,
- -2, -8, -33, -38, -7, -1, -22, -19, 11, 7, -21, -29, -29, -29, -31, -32,
- -55, -80, -49, -7, 16, 31, 43, 45, 44, 56, 66, 45, 12, 2, 10, 3,
- -18, -13, 7, 9, -2, 17, 38, 22, 1, 5, 17, 4, -14, -12, -1, -11,
- -43, -38, 6, 5, -22, -15, 12, 0, -23, -26, -28, -31, -32, -36, -60, -82,
- -46, 3, 24, 35, 38, 41, 46, 59, 62, 41, 13, -1, 3, -6, -18, 3,
- 22, 2, -9, 20, 36, 18, 10, 7, 4, -5, -17, -9, -2, -18, -55, -30,
- 17, 6, -20, -10, 6, -5, -16, -26, -32, -27, -30, -42, -69, -84, -41, 13,
- 31, 42, 37, 38, 45, 63, 65, 41, 12, 3, 1, -18, -10, 23, 27, -2,
- -12, 17, 36, 26, 13, 4, -2, -5, -14, -14, -11, -26, -54, -19, 21, 8,
- -16, -8, 6, -7, -20, -30, -33, -24, -33, -50, -74, -82, -32, 18, 34, 42,
- 38, 34, 50, 69, 58, 34, 16, 7, -9, -29, -2, 41, 32, -7, -15, 11,
- 34, 30, 9, 2, -3, -7, -23, -21, -15, -30, -52, -10, 18, 10, -8, -4,
- 5, -4, -25, -33, -26, -22, -42, -59, -79, -72, -20, 23, 36, 41, 37, 34,
- 54, 74, 53, 22, 17, 15, -17, -34, 10, 52, 37, -8, -11, 12, 33, 23,
- 8, 4, -1, -16, -31, -25, -18, -38, -49, -3, 19, 11, -4, 0, 7, -8,
- -34, -31, -19, -26, -52, -62, -79, -55, -7, 23, 41, 47, 41, 33, 61, 75,
- 43, 22, 21, 13, -26, -33, 17, 58, 39, -6, -8, 13, 27, 10, 5, 13,
- -2, -32, -43, -32, -19, -38, -36, -3, 12, 4, 4, 13, 6, -22, -41, -31,
- -13, -33, -59, -71, -76, -35, 2, 20, 39, 53, 47, 39, 60, 62, 37, 26,
- 22, 5, -33, -29, 26, 64, 40, 0, -5, 12, 21, 8, 16, 10, -13, -39,
- -49, -37, -25, -41, -30, -6, 9, 9, 13, 23, 0, -30, -44, -26, -13, -45,
- -67, -76, -68, -20, 10, 19, 39, 55, 50, 46, 57, 50, 37, 30, 16, -3,
- -34, -22, 34, 65, 40, 13, -2, 6, 19, 12, 21, 5, -23, -49, -52, -38,
- -33, -36, -24, -9, 10, 12, 25, 23, -11, -29, -43, -27, -21, -55, -73, -77,
- -50, -2, 19, 19, 35, 59, 59, 49, 45, 40, 36, 27, 4, -10, -24, -12,
- 31, 59, 44, 22, -5, 4, 19, 20, 12, -4, -27, -52, -50, -45, -39, -24,
- -23, -13, 16, 20, 30, 15, -16, -28, -37, -30, -36, -64, -79, -73, -28, 17,
- 24, 14, 36, 65, 68, 45, 33, 39, 40, 22, -2, -5, -11, -11, 28, 58,
- 57, 20, -13, 0, 27, 23, 1, -15, -35, -58, -55, -52, -39, -20, -22, -9,
- 20, 29, 30, 10, -15, -31, -39, -32, -48, -72, -86, -59, -4, 27, 19, 17,
- 44, 77, 69, 31, 26, 40, 38, 14, -6, 0, 1, -11, 26, 67, 62, 10,
- -18, 6, 31, 20, -5, -22, -44, -66, -61, -50, -31, -17, -24, -7, 24, 34,
- 31, 3, -17, -31, -36, -40, -61, -73, -76, -46, 11, 34, 20, 22, 56, 83,
- 60, 22, 24, 46, 32, 5, -4, 9, 0, -8, 31, 73, 53, 0, -13, 16,
- 28, 14, -15, -31, -51, -74, -64, -43, -25, -22, -25, -1, 30, 37, 20, -2,
- -20, -36, -39, -55, -69, -75, -69, -32, 21, 36, 22, 31, 63, 76, 50, 22,
- 25, 49, 29, 3, 4, 9, 2, 0, 43, 74, 37, -8, -1, 28, 24, 8,
- -22, -42, -65, -80, -60, -31, -25, -31, -24, 8, 41, 37, 10, -3, -22, -40,
- -45, -60, -69, -69, -55, -15, 32, 37, 25, 42, 72, 70, 37, 21, 32, 41,
- 20, 5, 15, 8, 0, 9, 46, 62, 26, -7, 8, 28, 21, 4, -29, -53,
- -79, -82, -57, -25, -27, -32, -21, 14, 48, 35, -1, -7, -24, -44, -52, -70,
- -69, -60, -38, 1, 34, 33, 32, 57, 70, 58, 34, 26, 31, 31, 16, 14,
- 14, 3, 8, 25, 47, 47, 18, -2, 13, 25, 19, -2, -33, -64, -87, -83,
- -53, -24, -29, -32, -17, 21, 46, 27, -4, -12, -30, -51, -61, -73, -60, -46,
- -17, 9, 25, 32, 47, 69, 61, 48, 41, 30, 26, 24, 18, 24, 15, 2,
- 14, 37, 42, 34, 17, 9, 19, 20, 11, -7, -35, -79, -97, -79, -45, -21,
- -29, -33, -12, 26, 43, 27, -3, -15, -43, -58, -66, -69, -52, -37, -2, 16,
- 24, 38, 61, 72, 56, 43, 41, 32, 28, 22, 22, 26, 12, 1, 23, 45,
- 34, 21, 8, 17, 22, 19, 4, -18, -47, -93, -97, -70, -40, -29, -33, -22,
- -5, 24, 44, 19, -6, -23, -53, -60, -74, -63, -41, -20, 10, 18, 19, 40,
- 70, 70, 47, 41, 43, 37, 27, 14, 24, 32, 10, 1, 29, 44, 27, 12,
- 7, 28, 32, 9, -11, -27, -56, -100, -94, -64, -43, -38, -31, -7, 0, 27,
- 41, 11, -7, -35, -60, -62, -75, -54, -29, -5, 17, 22, 14, 46, 80, 72,
- 46, 42, 44, 42, 24, 16, 31, 32, 9, 4, 33, 45, 22, 5, 8, 41,
- 34, 0, -22, -36, -69, -100, -92, -65, -40, -44, -25, 0, 5, 28, 36, 4,
- -12, -50, -64, -64, -68, -46, -19, 2, 25, 28, 19, 44, 72, 67, 46, 45,
- 44, 39, 21, 21, 38, 29, 1, 9, 39, 39, 13, -4, 9, 54, 41, -11,
- -38, -51, -76, -91, -92, -65, -44, -47, -17, 12, 11, 21, 27, 6, -24, -59,
- -65, -67, -61, -40, -17, 8, 31, 26, 20, 49, 74, 65, 45, 48, 47, 36,
- 25, 28, 36, 25, 5, 19, 42, 28, 6, -2, 21, 56, 27, -22, -45, -62,
- -83, -92, -84, -65, -49, -37, -8, 15, 16, 22, 23, -1, -38, -65, -66, -65,
- -51, -35, -15, 20, 42, 26, 25, 51, 70, 60, 45, 52, 47, 25, 25, 39,
- 33, 24, 16, 31, 37, 14, 3, 2, 33, 55, 14, -35, -55, -67, -84, -88,
- -84, -68, -47, -28, -1, 17, 22, 24, 17, -14, -54, -66, -64, -61, -46, -32,
- -10, 26, 45, 24, 29, 52, 66, 57, 49, 56, 41, 16, 29, 46, 31, 22,
- 24, 37, 30, 12, -1, 5, 40, 39, 1, -41, -63, -72, -89, -89, -77, -62,
- -48, -17, 5, 13, 26, 31, 10, -29, -62, -64, -65, -54, -41, -25, -4, 32,
- 52, 29, 32, 55, 61, 55, 56, 57, 35, 17, 33, 40, 28, 27, 37, 36,
- 26, 14, -3, 13, 41, 22, -13, -45, -65, -78, -90, -87, -70, -56, -47, -12,
- 9, 18, 35, 27, -5, -41, -63, -61, -65, -52, -37, -17, 5, 35, 52, 34,
- 38, 55, 58, 53, 60, 54, 31, 21, 33, 34, 30, 35, 40, 32, 29, 15,
- -4, 18, 30, 11, -25, -53, -69, -85, -91, -82, -66, -54, -36, -7, 6, 20,
- 40, 19, -17, -52, -63, -60, -65, -50, -32, -11, 9, 34, 50, 40, 46, 51,
- 56, 60, 60, 50, 28, 23, 33, 33, 31, 40, 43, 38, 38, 13, -6, 13,
- 19, -2, -34, -57, -78, -91, -85, -73, -63, -55, -28, -1, 6, 26, 39, 13,
- -28, -56, -61, -55, -61, -43, -27, -13, 12, 38, 48, 49, 54, 46, 52, 64,
- 64, 48, 27, 22, 28, 33, 36, 44, 42, 39, 44, 15, -3, 10, 6, -19,
- -46, -60, -81, -92, -83, -73, -52, -44, -22, -5, 5, 38, 37, -6, -41, -55,
- -54, -49, -53, -45, -28, -9, 19, 41, 47, 56, 57, 41, 56, 69, 64, 42,
- 26, 23, 27, 36, 39, 44, 39, 48, 53, 12, -4, 2, -8, -33, -61, -72,
- -84, -87, -80, -73, -49, -36, -12, -5, 9, 42, 24, -15, -44, -50, -51, -51,
- -51, -45, -26, -4, 20, 40, 47, 64, 58, 38, 61, 71, 55, 37, 32, 23,
- 30, 34, 39, 50, 43, 58, 53, 9, 4, -3, -27, -49, -71, -79, -79, -79,
- -82, -70, -44, -26, -7, -5, 16, 36, 9, -18, -40, -47, -49, -45, -42, -43,
- -20, 1, 21, 40, 53, 72, 54, 36, 64, 66, 41, 30, 36, 26, 28, 31,
- 44, 57, 48, 62, 45, 13, 3, -14, -47, -65, -77, -87, -78, -71, -75, -68,
- -43, -16, -2, -1, 18, 20, -4, -18, -37, -46, -50, -36, -39, -46, -15, 7,
- 23, 41, 62, 72, 49, 41, 69, 59, 33, 29, 38, 24, 28, 31, 52, 59,
- 49, 61, 45, 21, 2, -31, -64, -73, -78, -89, -79, -71, -77, -62, -36, -8,
- 3, 5, 15, 5, -10, -17, -34, -49, -50, -27, -37, -43, -12, 14, 25, 45,
- 67, 68, 48, 48, 64, 48, 27, 33, 41, 25, 24, 32, 64, 66, 51, 62,
- 41, 21, -7, -43, -77, -81, -83, -87, -74, -71, -77, -54, -29, -1, 7, 13,
- 12, -6, -9, -18, -38, -54, -44, -21, -37, -41, -8, 16, 28, 53, 73, 61,
- 46, 52, 60, 35, 25, 34, 38, 20, 25, 42, 73, 62, 60, 58, 39, 22,
- -19, -54, -85, -88, -95, -88, -65, -69, -73, -47, -22, 3, 14, 15, -5, -14,
- -6, -23, -42, -52, -34, -19, -42, -38, 0, 18, 30, 62, 76, 61, 49, 52,
- 49, 26, 23, 34, 33, 22, 21, 50, 78, 68, 66, 47, 40, 22, -23, -66,
- -95, -102, -97, -74, -61, -77, -68, -36, -12, 9, 15, 13, -18, -14, -5, -31,
- -50, -44, -21, -25, -49, -25, 8, 16, 30, 70, 82, 56, 45, 55, 39, 21,
- 25, 31, 24, 21, 28, 64, 81, 68, 64, 47, 44, 15, -30, -77, -101, -104,
- -96, -71, -66, -76, -53, -22, -9, 6, 22, 10, -22, -15, -13, -38, -48, -32,
- -9, -33, -49, -14, 10, 11, 37, 77, 85, 51, 44, 48, 30, 18, 21, 26,
- 16, 21, 36, 71, 76, 73, 68, 48, 35, 4, -38, -81, -103, -109, -91, -67,
- -71, -69, -40, -15, -12, 3, 23, 7, -23, -17, -24, -41, -45, -24, -11, -46,
- -46, -1, 10, 8, 49, 84, 83, 48, 50, 48, 27, 16, 18, 20, 14, 26,
- 44, 72, 75, 82, 71, 47, 26, -6, -45, -80, -107, -110, -88, -70, -69, -58,
- -28, -9, -12, 2, 23, 2, -21, -19, -35, -38, -33, -13, -17, -50, -35, 8,
- 9, 10, 57, 89, 74, 45, 52, 41, 24, 15, 11, 14, 13, 22, 54, 72,
- 74, 86, 72, 41, 13, -14, -47, -86, -113, -111, -88, -72, -67, -42, -18, -11,
- -11, 2, 18, -2, -17, -27, -44, -37, -28, -12, -26, -49, -22, 9, 3, 21,
- 69, 87, 63, 46, 49, 36, 24, 13, 11, 11, 8, 26, 64, 68, 76, 89,
- 74, 38, 3, -17, -44, -86, -117, -114, -86, -65, -58, -38, -19, -7, 0, 8,
- 9, -5, -20, -37, -45, -29, -19, -15, -36, -39, -10, 6, 4, 33, 79, 81,
- 55, 48, 42, 30, 23, 10, 13, 10, 3, 27, 62, 60, 76, 88, 68, 30,
- -5, -21, -49, -89, -120, -115, -81, -54, -46, -34, -14, -1, 7, 9, 1, -6,
- -18, -45, -52, -29, -16, -17, -35, -36, -12, 5, 11, 47, 81, 72, 53, 51,
- 39, 28, 24, 9, 13, 7, 5, 36, 57, 55, 82, 90, 62, 31, -10, -29,
- -55, -91, -121, -115, -76, -47, -38, -34, -13, 1, 13, 9, -4, -9, -17, -49,
- -56, -26, -9, -12, -33, -40, -17, 12, 25, 57, 71, 62, 52, 50, 35, 22,
- 21, 14, 11, -2, 10, 41, 50, 48, 85, 87, 66, 29, -15, -34, -64, -97,
- -121, -108, -73, -43, -37, -28, -7, 7, 16, 6, -7, -5, -15, -59, -56, -19,
- -4, -14, -37, -42, -10, 21, 38, 66, 63, 57, 52, 49, 28, 22, 28, 16,
- 5, -3, 22, 47, 38, 45, 79, 85, 68, 23, -16, -34, -70, -100, -122, -107,
- -62, -39, -38, -25, -4, 15, 18, 2, -3, 0, -27, -70, -51, -17, -3, -16,
- -44, -40, -1, 27, 45, 67, 57, 54, 48, 39, 17, 18, 28, 17, 3, -3,
- 27, 49, 37, 42, 69, 86, 66, 16, -17, -37, -72, -99, -117, -101, -55, -39,
- -36, -24, 1, 20, 13, 4, 4, -5, -46, -74, -43, -9, -4, -28, -49, -33,
- 6, 33, 63, 68, 54, 53, 49, 33, 18, 21, 24, 15, 7, 9, 33, 42,
- 35, 39, 70, 85, 55, 10, -16, -40, -75, -98, -113, -92, -47, -38, -35, -21,
- 1, 21, 15, 8, 7, -14, -62, -70, -30, -11, -15, -34, -49, -23, 9, 39,
- 64, 58, 51, 56, 42, 20, 16, 19, 16, 16, 4, 13, 40, 46, 33, 31,
- 65, 83, 49, 3, -24, -41, -73, -98, -105, -77, -45, -41, -30, -13, 7, 19,
- 12, 13, 8, -26, -68, -61, -22, -14, -25, -38, -40, -18, 12, 47, 68, 59,
- 49, 51, 42, 19, 17, 17, 12, 13, 5, 18, 41, 47, 26, 26, 67, 78,
- 44, -2, -31, -47, -71, -97, -96, -67, -44, -42, -29, -11, 13, 21, 13, 17,
- 8, -34, -68, -54, -17, -18, -36, -43, -35, -12, 14, 50, 69, 56, 49, 44,
- 35, 16, 13, 17, 13, 13, 6, 27, 46, 50, 24, 28, 66, 64, 28, 0,
- -25, -49, -75, -99, -87, -54, -42, -38, -28, -8, 20, 19, 11, 17, 1, -41,
- -62, -49, -18, -27, -41, -39, -29, -8, 15, 55, 73, 55, 42, 42, 33, 16,
- 12, 12, 9, 6, 14, 40, 52, 48, 21, 31, 60, 50, 23, 0, -32, -60,
- -76, -90, -73, -44, -39, -36, -32, 1, 29, 20, 6, 13, -3, -41, -53, -43,
- -21, -34, -47, -38, -22, -2, 22, 54, 65, 49, 38, 42, 32, 17, 12, 7,
- 6, 3, 21, 48, 53, 42, 24, 39, 53, 38, 15, -3, -38, -65, -76, -85,
- -59, -36, -35, -40, -26, 15, 26, 12, 6, 10, -12, -40, -49, -33, -26, -41,
- -53, -36, -12, 5, 28, 50, 61, 46, 34, 37, 31, 20, 12, 1, 0, 5,
- 32, 53, 56, 41, 23, 39, 48, 35, 13, -10, -44, -72, -81, -79, -50, -27,
- -34, -41, -18, 20, 27, 12, 5, 1, -19, -36, -40, -22, -34, -50, -55, -33,
- -3, 14, 33, 52, 54, 35, 27, 36, 37, 25, 7, -13, 1, 19, 41, 50,
- 50, 38, 32, 43, 41, 32, 6, -17, -46, -69, -79, -75, -43, -20, -34, -38,
- -8, 23, 26, 12, 6, -8, -23, -30, -30, -23, -46, -56, -52, -29, 6, 23,
- 35, 44, 47, 31, 25, 33, 40, 26, -4, -22, 3, 28, 39, 40, 50, 40,
- 28, 34, 37, 28, 0, -22, -50, -70, -81, -72, -34, -22, -36, -33, 2, 24,
- 25, 12, 4, -15, -24, -26, -25, -23, -46, -56, -50, -24, 10, 33, 36, 40,
- 35, 21, 25, 43, 47, 25, -13, -25, 11, 40, 36, 40, 56, 38, 27, 31,
- 33, 24, -4, -24, -53, -71, -80, -59, -34, -27, -31, -27, 8, 24, 25, 17,
- 2, -22, -25, -26, -19, -24, -51, -58, -40, -9, 14, 37, 36, 35, 27, 14,
- 28, 48, 46, 19, -19, -24, 18, 40, 29, 41, 50, 29, 29, 27, 33, 18,
- -12, -29, -53, -71, -75, -48, -33, -32, -25, -14, 13, 24, 19, 17, 2, -25,
- -28, -28, -18, -28, -55, -59, -30, -3, 20, 41, 34, 24, 15, 15, 36, 49,
- 39, 17, -17, -17, 22, 41, 33, 45, 38, 26, 30, 24, 27, 10, -11, -34,
- -58, -70, -66, -38, -32, -36, -21, -2, 14, 28, 19, 14, 0, -25, -29, -28,
- -17, -30, -57, -51, -22, 3, 23, 39, 34, 15, 11, 17, 38, 46, 39, 15,
- -18, -14, 27, 40, 37, 45, 32, 28, 30, 29, 28, 1, -16, -38, -55, -65,
- -62, -37, -31, -34, -17, 9, 18, 27, 18, 9, -1, -22, -35, -29, -17, -32,
- -57, -45, -17, 15, 30, 30, 25, 8, 10, 19, 35, 46, 37, 4, -19, -8,
- 31, 33, 33, 42, 28, 22, 24, 29, 23, -6, -21, -43, -54, -59, -55, -32,
- -34, -39, -10, 19, 30, 25, 9, 2, -2, -20, -38, -30, -23, -41, -51, -35,
- -12, 24, 32, 22, 12, 8, 16, 23, 32, 48, 33, 1, -16, 0, 29, 30,
- 33, 36, 24, 23, 22, 33, 14, -14, -20, -42, -55, -50, -44, -27, -38, -41,
- -3, 31, 35, 23, 5, -2, -4, -15, -34, -33, -38, -47, -40, -26, -3, 31,
- 31, 9, 2, 13, 14, 20, 38, 53, 27, -6, -14, 11, 30, 23, 32, 28,
- 25, 22, 24, 32, 5, -20, -26, -45, -49, -40, -36, -37, -48, -40, 8, 40,
- 37, 16, -3, -6, -2, -9, -27, -42, -52, -48, -32, -21, 8, 39, 28, -2,
- -5, 13, 17, 23, 40, 45, 19, -4, -3, 18, 15, 19, 33, 30, 29, 22,
- 21, 22, 0, -17, -27, -46, -48, -33, -31, -38, -53, -33, 23, 43, 31, 11,
- -7, -5, -3, -8, -26, -49, -59, -48, -25, -14, 15, 41, 23, -8, -6, 11,
- 10, 26, 49, 41, 12, 0, 10, 19, 4, 22, 31, 25, 25, 24, 20, 12,
- -4, -10, -37, -50, -37, -23, -26, -43, -55, -18, 34, 41, 28, 10, -9, -6,
- -3, -8, -27, -57, -62, -37, -15, -8, 24, 44, 23, -10, -6, 3, 8, 39,
- 55, 30, 12, 11, 20, 8, 3, 27, 26, 20, 21, 24, 19, -1, -10, -14,
- -42, -47, -25, -14, -28, -49, -50, -5, 38, 38, 23, 9, -11, -9, -1, -5,
- -33, -64, -59, -34, -14, -2, 32, 49, 17, -11, -6, -2, 11, 46, 46, 19,
- 16, 23, 24, -3, 3, 29, 29, 16, 17, 22, 11, -12, -12, -18, -50, -43,
- -15, -11, -30, -53, -38, 10, 31, 31, 25, 3, -16, -3, 3, -8, -41, -67,
- -53, -24, -14, 3, 35, 46, 17, -2, -7, -9, 16, 49, 41, 20, 22, 34,
- 21, -5, 5, 31, 29, 12, 14, 18, 8, -22, -17, -20, -52, -38, -13, -19,
- -32, -48, -25, 11, 23, 29, 26, 1, -14, 1, 1, -18, -47, -60, -47, -31,
- -11, 13, 45, 39, 8, -2, -2, -11, 16, 43, 35, 25, 34, 40, 18, -7,
- 6, 34, 28, 14, 7, 11, 2, -23, -25, -29, -51, -30, -11, -24, -38, -40,
- -15, 9, 18, 29, 32, -1, -10, 0, -9, -27, -48, -52, -46, -30, -2, 27,
- 47, 30, 10, 7, -6, -15, 12, 35, 28, 30, 45, 42, 19, -4, 11, 29,
- 21, 6, 1, 3, -3, -27, -31, -34, -40, -22, -18, -31, -35, -30, -18, 5,
- 19, 32, 28, -9, -7, 1, -14, -30, -42, -45, -47, -28, 7, 38, 45, 23,
- 14, 20, -2, -24, 7, 32, 30, 37, 43, 41, 22, 7, 18, 22, 14, 4,
- -7, 4, -7, -36, -37, -37, -27, -15, -26, -34, -34, -29, -18, 4, 19, 31,
- 20, -4, 0, -3, -21, -32, -37, -41, -40, -25, 14, 49, 44, 18, 19, 25,
- -1, -19, 5, 26, 35, 38, 46, 41, 18, 18, 16, 13, 12, 2, -5, -3,
- -23, -44, -37, -32, -20, -20, -33, -28, -32, -32, -16, 1, 17, 31, 17, -2,
- 2, -3, -22, -33, -39, -40, -34, -23, 15, 56, 44, 15, 27, 23, -4, -14,
- 2, 22, 38, 37, 48, 40, 25, 24, 15, 11, 2, -2, -3, -15, -31, -40,
- -37, -33, -17, -17, -28, -29, -41, -34, -7, 1, 13, 31, 17, -2, 4, 1,
- -20, -35, -47, -37, -24, -10, 22, 52, 38, 26, 35, 26, -2, -9, 4, 23,
- 40, 38, 46, 39, 32, 31, 16, 2, -7, -8, -2, -21, -38, -44, -38, -31,
- -18, -15, -29, -35, -45, -32, -1, -3, 4, 30, 16, 3, 8, 4, -20, -42,
- -48, -30, -17, -8, 21, 49, 41, 30, 38, 23, -2, -5, 1, 21, 35, 37,
- 44, 40, 40, 33, 17, 1, -13, -10, -9, -35, -41, -41, -39, -33, -19, -12,
- -27, -40, -48, -28, -4, -10, 10, 28, 15, 9, 12, 5, -24, -43, -43, -23,
- -18, 0, 26, 47, 43, 35, 40, 20, -1, 1, 4, 20, 28, 37, 42, 42,
- 46, 31, 22, 8, -17, -15, -15, -42, -41, -37, -44, -37, -16, -13, -33, -41,
- -41, -20, -11, -17, 10, 18, 13, 16, 17, 1, -24, -38, -38, -27, -21, 9,
- 29, 46, 44, 43, 38, 18, 3, 6, 6, 12, 19, 38, 41, 47, 44, 28,
- 29, 11, -26, -25, -27, -45, -39, -39, -48, -41, -18, -13, -33, -38, -36, -21,
- -19, -14, 13, 11, 11, 26, 17, -6, -25, -32, -32, -35, -14, 21, 31, 38,
- 49, 49, 34, 19, 13, 10, 4, 9, 20, 37, 41, 45, 39, 29, 35, 6,
- -28, -28, -35, -43, -37, -42, -50, -44, -20, -20, -37, -37, -27, -16, -23, -11,
- 10, 5, 17, 36, 16, -16, -23, -21, -33, -38, -5, 23, 28, 35, 55, 55,
- 31, 17, 18, 12, 3, 4, 21, 33, 41, 45, 31, 32, 39, 3, -29, -35,
- -41, -40, -38, -45, -55, -45, -26, -31, -36, -26, -22, -22, -29, 1, 9, -1,
- 24, 39, 8, -19, -17, -14, -32, -34, 5, 29, 29, 35, 58, 51, 32, 29,
- 23, 11, 1, 6, 29, 37, 38, 36, 24, 43, 39, -2, -32, -44, -45, -36,
- -36, -45, -55, -51, -37, -35, -30, -22, -20, -32, -24, 6, 2, 3, 30, 36,
- 3, -17, -16, -18, -29, -24, 10, 31, 25, 34, 58, 44, 33, 37, 26, 8,
- 5, 10, 37, 36, 35, 29, 22, 47, 36, -6, -36, -51, -49, -34, -38, -48,
- -58, -53, -46, -42, -24, -23, -22, -32, -13, 4, -7, 8, 35, 30, 6, -14,
- -20, -19, -21, -20, 14, 34, 29, 43, 52, 37, 39, 43, 24, 8, 7, 15,
- 45, 33, 36, 24, 25, 43, 25, -10, -39, -53, -47, -34, -39, -53, -56, -54,
- -56, -42, -21, -23, -29, -25, -5, 1, -10, 12, 35, 27, 7, -14, -25, -19,
- -11, -10, 13, 31, 37, 44, 42, 37, 45, 44, 24, 14, 13, 24, 40, 28,
- 35, 23, 31, 35, 15, -16, -38, -53, -45, -37, -48, -56, -54, -63, -63, -40,
- -23, -24, -27, -19, 3, 1, -11, 14, 33, 24, 5, -16, -28, -17, -6, -1,
- 15, 38, 39, 38, 29, 36, 54, 42, 20, 20, 19, 32, 38, 30, 31, 23,
- 33, 23, -1, -17, -35, -44, -43, -47, -51, -51, -56, -71, -67, -45, -28, -23,
- -23, -13, 12, -1, -15, 15, 33, 20, -2, -22, -25, -17, -3, 10, 24, 46,
- 44, 31, 26, 41, 53, 42, 23, 23, 26, 39, 37, 32, 24, 28, 36, 11,
- -7, -19, -38, -39, -37, -49, -54, -51, -62, -76, -68, -51, -28, -19, -21, 1,
- 22, -3, -11, 14, 25, 16, -5, -25, -25, -15, -2, 20, 36, 51, 42, 19,
- 19, 43, 58, 43, 25, 21, 35, 46, 41, 34, 17, 26, 33, 5, -15, -25,
- -39, -34, -37, -55, -50, -49, -69, -80, -67, -50, -31, -18, -12, 12, 17, -5,
- -5, 14, 17, 6, -15, -27, -22, -14, 3, 37, 49, 48, 40, 22, 22, 36,
- 51, 44, 29, 22, 42, 49, 41, 29, 16, 29, 31, -9, -30, -33, -35, -29,
- -38, -55, -45, -54, -79, -80, -65, -51, -34, -16, -2, 18, 18, 5, 7, 8,
- 6, 3, -19, -21, -22, -19, 12, 51, 53, 48, 39, 22, 18, 36, 46, 42,
- 35, 31, 44, 46, 42, 31, 24, 35, 21, -25, -39, -33, -30, -24, -41, -53,
- -47, -60, -81, -81, -63, -53, -40, -14, 6, 24, 20, 8, 7, 0, -1, -4,
- -21, -23, -29, -16, 30, 60, 55, 50, 37, 19, 19, 35, 43, 46, 37, 29,
- 43, 49, 43, 32, 27, 31, 13, -35, -46, -36, -26, -28, -44, -52, -47, -65,
- -84, -84, -68, -49, -27, 0, 10, 15, 19, 15, 9, -3, -10, -16, -20, -26,
- -28, -2, 41, 59, 62, 56, 37, 16, 15, 31, 43, 50, 42, 30, 41, 49,
- 49, 38, 28, 23, 5, -42, -55, -42, -21, -22, -40, -49, -54, -71, -86, -81,
- -62, -44, -21, 5, 17, 16, 25, 23, 0, -13, -17, -17, -24, -32, -21, 15,
- 45, 58, 66, 52, 33, 15, 9, 35, 42, 44, 44, 36, 38, 50, 52, 40,
- 28, 16, -11, -48, -60, -43, -22, -21, -40, -53, -58, -78, -90, -79, -61, -42,
- -9, 14, 15, 16, 22, 21, -4, -20, -21, -19, -30, -31, -10, 26, 54, 63,
- 69, 51, 33, 12, 13, 40, 42, 45, 42, 33, 36, 53, 57, 44, 24, 3,
- -24, -53, -63, -45, -21, -15, -39, -57, -63, -78, -89, -76, -55, -34, 3, 18,
- 9, 16, 21, 15, -8, -26, -28, -25, -32, -24, 4, 34, 56, 67, 75, 48,
- 22, 7, 23, 44, 39, 40, 40, 35, 40, 59, 59, 44, 18, -6, -31, -54,
- -58, -44, -20, -13, -43, -63, -69, -80, -88, -71, -48, -21, 12, 16, 12, 18,
- 13, 6, -12, -27, -32, -30, -34, -20, 13, 46, 63, 74, 73, 40, 15, 13,
- 39, 46, 33, 32, 35, 36, 48, 58, 61, 43, 16, -13, -36, -57, -62, -41,
- -22, -16, -42, -66, -73, -79, -85, -65, -38, -7, 13, 9, 7, 16, 11, -2,
- -18, -36, -39, -26, -25, -16, 21, 53, 64, 74, 68, 36, 19, 22, 38, 44,
- 32, 28, 32, 38, 52, 60, 56, 43, 13, -25, -39, -54, -52, -35, -30, -27,
- -46, -70, -79, -80, -79, -58, -26, 3, 15, 6, 0, 12, 6, -8, -27, -45,
- -39, -17, -16, -13, 28, 57, 67, 71, 57, 37, 22, 25, 41, 46, 29, 24,
- 34, 44, 56, 55, 52, 44, 7, -27, -38, -48, -44, -35, -31, -29, -46, -77,
- -83, -73, -70, -48, -15, 6, 9, 1, 1, 9, -3, -20, -41, -48, -30, -5,
- -14, -9, 39, 63, 70, 66, 47, 36, 25, 32, 40, 43, 26, 21, 36, 47,
- 59, 50, 49, 35, 0, -26, -36, -44, -41, -36, -35, -33, -50, -79, -79, -66,
- -63, -36, -8, 6, -3, -9, 2, 3, -13, -30, -49, -46, -18, -2, -15, 4,
- 42, 58, 65, 61, 50, 38, 28, 37, 40, 38, 28, 30, 38, 48, 50, 42,
- 46, 28, -3, -28, -37, -36, -36, -39, -36, -37, -59, -79, -69, -62, -52, -24,
- -2, 3, -12, -11, 4, -5, -29, -42, -53, -39, -12, -4, -4, 14, 37, 52,
- 63, 58, 50, 37, 34, 37, 36, 37, 38, 36, 35, 47, 46, 44, 42, 18,
- -7, -30, -34, -32, -34, -41, -37, -45, -66, -74, -64, -57, -36, -12, 1, -8,
- -23, -7, 6, -18, -39, -49, -53, -29, -5, -1, 10, 19, 30, 46, 59, 58,
- 50, 36, 37, 37, 32, 40, 46, 38, 34, 44, 42, 41, 36, 9, -9, -27,
- -29, -26, -34, -40, -40, -56, -69, -66, -56, -46, -22, -7, -7, -19, -21, 3,
- 1, -35, -48, -53, -49, -22, -3, 12, 23, 18, 22, 46, 66, 59, 47, 38,
- 43, 35, 30, 46, 51, 39, 33, 41, 37, 42, 24, 2, -8, -22, -23, -24,
- -33, -39, -50, -66, -69, -59, -49, -31, -13, -10, -17, -25, -16, 1, -17, -50,
- -55, -58, -42, -17, -1, 20, 31, 14, 15, 48, 70, 59, 42, 38, 45, 33,
- 33, 51, 53, 36, 35, 37, 36, 37, 12, 0, -9, -16, -18, -22, -33, -42,
- -59, -67, -62, -52, -40, -20, -11, -15, -23, -23, -11, -3, -28, -51, -59, -61,
- -38, -14, 4, 26, 30, 10, 18, 53, 71, 56, 40, 42, 45, 32, 34, 53,
- 52, 37, 36, 32, 37, 32, 10, -3, -10, -10, -11, -17, -31, -46, -62, -63,
- -54, -44, -30, -14, -14, -23, -27, -22, -11, -11, -35, -51, -65, -59, -32, -11,
- 11, 29, 25, 8, 24, 63, 73, 51, 38, 46, 44, 29, 34, 51, 51, 39,
- 34, 27, 34, 23, 3, -5, -9, -6, -10, -18, -33, -51, -66, -60, -50, -35,
- -20, -10, -21, -33, -29, -17, -9, -20, -39, -55, -71, -57, -26, -7, 11, 23,
- 22, 11, 35, 70, 71, 46, 39, 48, 42, 29, 33, 51, 47, 38, 31, 28,
- 35, 17, 0, -12, -7, 0, -4, -15, -36, -56, -67, -56, -42, -26, -15, -12,
- -29, -36, -28, -15, -13, -25, -40, -58, -70, -49, -23, -6, 8, 19, 17, 18,
- 49, 76, 66, 40, 42, 49, 39, 25, 35, 51, 43, 40, 30, 31, 32, 15,
- -1, -14, -7, 1, -2, -17, -40, -59, -61, -51, -38, -21, -10, -17, -34, -35,
- -28, -18, -17, -24, -40, -64, -65, -40, -18, -8, 5, 13, 17, 31, 61, 75,
- 60, 41, 43, 47, 34, 20, 36, 47, 43, 41, 31, 32, 26, 7, -7, -16,
- -6, 0, -3, -22, -44, -60, -56, -47, -34, -19, -8, -20, -39, -40, -27, -18,
- -20, -29, -44, -63, -56, -38, -23, -11, 4, 14, 21, 42, 65, 71, 59, 45,
- 42, 34, 21, 20, 42, 48, 44, 41, 31, 34, 24, 6, -10, -20, -11, 4,
- 0, -20, -48, -57, -47, -39, -30, -17, -4, -24, -43, -40, -26, -19, -24, -29,
- -45, -59, -51, -37, -25, -14, 3, 15, 27, 51, 72, 76, 61, 44, 38, 23,
- 12, 21, 43, 46, 45, 40, 31, 35, 21, 5, -17, -22, -13, 3, 1, -24,
- -51, -52, -43, -37, -28, -8, -7, -38, -46, -36, -21, -21, -31, -33, -45, -51,
- -47, -40, -30, -13, 4, 14, 33, 60, 76, 76, 61, 47, 30, 16, 8, 20,
- 40, 45, 48, 37, 37, 37, 22, 3, -19, -20, -10, 4, -6, -30, -49, -44,
- -41, -38, -23, -1, -14, -41, -44, -36, -22, -26, -35, -33, -45, -52, -48, -40,
- -32, -9, 6, 18, 35, 65, 85, 80, 62, 46, 24, 6, -1, 23, 41, 48,
- 45, 31, 42, 40, 23, -6, -21, -15, -6, 0, -13, -31, -44, -41, -38, -32,
- -15, 0, -22, -40, -41, -36, -24, -31, -28, -32, -46, -49, -47, -43, -30, -6,
- 9, 19, 46, 77, 87, 77, 61, 42, 18, -2, -7, 22, 39, 51, 41, 32,
- 43, 35, 13, -18, -18, -10, -5, -8, -21, -29, -39, -42, -41, -23, -3, -3,
- -32, -39, -38, -34, -31, -35, -23, -32, -46, -50, -51, -46, -26, 0, 12, 20,
- 54, 87, 91, 72, 60, 38, 13, -10, -11, 24, 44, 52, 43, 39, 45, 34,
- 2, -19, -8, -1, -8, -19, -19, -25, -35, -42, -39, -17, 7, -7, -38, -36,
- -36, -37, -37, -31, -20, -34, -49, -53, -50, -43, -19, 6, 10, 25, 66, 91,
- 84, 67, 60, 36, 1, -18, -10, 27, 48, 52, 42, 42, 38, 25, -3, -18,
- -5, -2, -13, -22, -24, -28, -35, -45, -35, -4, 14, -17, -41, -36, -33, -35,
- -41, -29, -20, -38, -51, -54, -46, -33, -14, 6, 14, 37, 74, 87, 76, 65,
- 64, 29, -9, -22, -7, 23, 52, 55, 46, 42, 25, 17, -5, -12, -4, -3,
- -17, -25, -33, -36, -33, -39, -30, 5, 12, -25, -37, -33, -34, -42, -41, -25,
- -22, -41, -52, -53, -40, -25, -10, 11, 21, 43, 72, 78, 74, 69, 58, 15,
- -13, -15, -4, 22, 54, 58, 53, 41, 15, 6, -2, -1, -3, -6, -18, -24,
- -42, -40, -29, -32, -20, 13, 8, -25, -35, -34, -29, -42, -43, -27, -27, -42,
- -51, -50, -30, -14, -5, 17, 26, 46, 70, 72, 72, 69, 48, 2, -13, -9,
- -3, 19, 55, 59, 53, 30, 1, -1, 5, 8, -7, -15, -19, -25, -48, -45,
- -31, -28, -10, 15, 1, -24, -35, -35, -22, -37, -43, -36, -35, -41, -47, -45,
- -18, -6, -1, 24, 32, 51, 65, 65, 67, 63, 37, -3, -13, -9, 1, 29,
- 54, 60, 50, 18, -4, -4, 13, 9, -10, -15, -17, -30, -54, -47, -29, -20,
- -8, 4, -8, -15, -29, -35, -21, -37, -43, -46, -37, -33, -48, -39, -10, 3,
- 13, 31, 34, 54, 56, 57, 63, 56, 32, -3, -16, -6, 14, 38, 48, 53,
- 40, 11, -3, 1, 6, -2, -11, -9, -11, -28, -54, -54, -29, -8, 2, -8,
- -16, -13, -27, -31, -21, -32, -45, -54, -36, -27, -44, -33, 1, 16, 25, 29,
- 39, 56, 48, 51, 57, 48, 22, 3, -14, 0, 22, 39, 42, 46, 36, 7,
- -7, 0, 0, -3, -8, -8, -15, -34, -50, -49, -27, -3, 0, -15, -14, -16,
- -28, -26, -21, -34, -56, -55, -32, -30, -41, -23, 8, 20, 31, 33, 45, 53,
- 38, 42, 54, 40, 18, -3, -9, 14, 33, 37, 34, 34, 27, 8, -5, -1,
- -9, -3, -1, -8, -19, -35, -43, -42, -28, -7, 1, -18, -13, -17, -29, -24,
- -21, -34, -55, -52, -34, -30, -26, -9, 15, 28, 28, 32, 55, 50, 29, 38,
- 45, 35, 17, -3, -1, 18, 36, 40, 27, 24, 19, 0, -5, -1, -14, -7,
- -2, -12, -20, -30, -40, -42, -25, -5, -5, -24, -14, -16, -25, -20, -26, -38,
- -52, -49, -35, -31, -13, 8, 16, 28, 29, 42, 57, 40, 23, 32, 35, 30,
- 12, -5, 9, 22, 40, 38, 19, 17, 16, -1, -9, -7, -12, -6, -5, -13,
- -18, -29, -39, -39, -18, -3, -19, -26, -11, -18, -24, -19, -30, -40, -51, -45,
- -30, -24, 0, 19, 22, 28, 36, 49, 54, 41, 22, 30, 31, 26, 10, 2,
- 10, 26, 43, 28, 14, 16, 7, -6, -12, -9, -9, -5, -12, -19, -16, -29,
- -35, -34, -8, -8, -35, -20, -7, -26, -23, -23, -30, -39, -53, -38, -25, -12,
- 11, 24, 24, 29, 47, 50, 48, 36, 20, 29, 24, 15, 5, 8, 12, 32,
- 40, 21, 17, 11, 0, -3, -15, -14, -7, -4, -13, -17, -16, -28, -31, -23,
- -6, -20, -37, -15, -12, -29, -22, -28, -30, -38, -54, -34, -20, -4, 21, 33,
- 24, 33, 50, 45, 40, 33, 27, 28, 14, 8, 8, 11, 11, 30, 33, 26,
- 20, -1, -8, -4, -17, -16, -2, -7, -22, -20, -20, -26, -26, -15, -10, -27,
- -35, -12, -19, -31, -21, -23, -23, -42, -57, -31, -11, 9, 35, 33, 23, 39,
- 53, 47, 40, 31, 31, 21, 10, 9, 11, 10, 13, 26, 35, 33, 13, -11,
- -10, -4, -19, -22, 3, -2, -28, -26, -16, -21, -24, -12, -12, -31, -34, -17,
- -27, -34, -25, -17, -19, -48, -59, -29, -2, 27, 46, 26, 22, 43, 54, 44,
- 38, 30, 29, 16, 6, 15, 15, 6, 9, 22, 36, 37, 9, -20, -10, -5,
- -21, -21, 2, -5, -29, -31, -18, -11, -17, -11, -15, -32, -34, -23, -30, -30,
- -25, -15, -22, -52, -50, -17, 9, 36, 42, 26, 29, 50, 53, 40, 33, 32,
- 27, 14, 7, 9, 7, 4, 12, 22, 36, 36, 3, -27, -16, -9, -20, -21,
- -1, -12, -31, -27, -13, -12, -18, -12, -17, -33, -39, -29, -34, -35, -23, -7,
- -25, -55, -42, -10, 20, 43, 40, 27, 33, 51, 51, 37, 34, 31, 21, 9,
- 8, 5, 2, 11, 16, 18, 34, 35, 3, -22, -17, -16, -20, -17, -7, -20,
- -32, -28, -14, -12, -10, -8, -17, -34, -41, -35, -34, -31, -19, -8, -27, -48,
- -29, -4, 26, 50, 44, 32, 37, 50, 49, 40, 36, 22, 11, 11, 12, 5,
- 3, 14, 12, 13, 34, 37, 9, -23, -24, -16, -21, -16, -17, -30, -27, -27,
- -20, -10, -10, -9, -18, -39, -46, -42, -35, -31, -14, -9, -33, -42, -19, 1,
- 36, 55, 41, 32, 46, 55, 47, 35, 32, 18, 6, 7, 9, -2, 7, 17,
- 8, 13, 34, 32, 10, -22, -27, -14, -20, -21, -26, -31, -23, -27, -22, -6,
- -5, -11, -21, -39, -46, -46, -37, -30, -14, -12, -33, -31, -8, 6, 41, 55,
- 40, 38, 54, 57, 39, 30, 33, 17, 2, 1, 4, 7, 14, 14, -2, 11,
- 37, 31, 11, -26, -30, -16, -20, -18, -21, -27, -32, -28, -12, 0, -4, -11,
- -23, -40, -46, -43, -33, -26, -16, -15, -29, -19, -1, 13, 44, 58, 41, 49,
- 68, 59, 36, 28, 36, 18, -9, -9, 4, 17, 20, 7, -6, 18, 36, 22,
- -1, -30, -26, -19, -25, -26, -31, -35, -33, -21, -3, -8, -10, -14, -24, -40,
- -45, -43, -35, -20, -18, -20, -22, -12, 0, 15, 48, 58, 41, 58, 77, 57,
- 30, 27, 33, 7, -23, -16, 11, 23, 21, 2, -5, 24, 33, 10, -10, -24,
- -19, -25, -37, -30, -30, -34, -29, -14, -5, -16, -8, -8, -26, -50, -47, -41,
- -30, -16, -25, -24, -14, -6, 3, 23, 50, 51, 49, 69, 81, 56, 29, 33,
- 30, -2, -29, -14, 15, 26, 18, 2, -1, 31, 28, 0, -20, -21, -21, -32,
- -43, -34, -33, -36, -23, -4, -8, -20, -8, -11, -25, -44, -41, -39, -32, -17,
- -30, -22, -4, 1, 6, 31, 48, 47, 63, 80, 82, 52, 31, 38, 23, -13,
- -33, -11, 20, 29, 14, -1, 9, 34, 19, -12, -26, -13, -23, -46, -46, -38,
- -39, -35, -24, -3, -7, -17, -15, -16, -25, -45, -37, -37, -33, -26, -36, -20,
- 5, 3, 4, 32, 42, 50, 76, 83, 75, 49, 34, 36, 17, -24, -33, -12,
- 23, 32, 10, 1, 23, 30, 7, -17, -22, -8, -27, -49, -50, -42, -38, -28,
- -18, -3, -8, -13, -14, -15, -24, -43, -35, -33, -29, -27, -34, -15, 16, 8,
- 5, 32, 43, 62, 84, 84, 73, 53, 40, 30, 6, -26, -34, -15, 25, 28,
- 8, 9, 38, 27, -4, -26, -21, -12, -33, -54, -47, -48, -38, -21, -14, -2,
- -3, -11, -25, -18, -26, -32, -34, -34, -29, -31, -35, -10, 18, 11, 7, 33,
- 47, 68, 83, 81, 71, 58, 42, 20, -5, -25, -36, -15, 23, 23, 7, 20,
- 40, 21, -14, -35, -21, -16, -40, -58, -52, -52, -31, -11, -9, -6, -1, -15,
- -26, -15, -29, -31, -36, -31, -29, -36, -32, -4, 17, 8, 15, 36, 48, 66,
- 77, 83, 77, 59, 38, 9, -11, -20, -34, -12, 22, 20, 14, 33, 39, 16,
- -22, -36, -23, -21, -40, -56, -52, -47, -24, -10, -4, 3, 1, -17, -22, -18,
- -28, -26, -32, -30, -32, -30, -22, 1, 15, 15, 27, 42, 52, 62, 75, 85,
- 80, 59, 35, 1, -16, -20, -35, -12, 18, 17, 18, 40, 34, 5, -34, -38,
- -27, -28, -42, -60, -58, -48, -18, -4, 0, 3, -4, -18, -20, -22, -35, -29,
- -27, -34, -42, -28, -12, 3, 8, 19, 31, 40, 45, 60, 75, 79, 76, 62,
- 37, -2, -20, -22, -31, -11, 13, 15, 31, 43, 27, 0, -28, -33, -36, -37,
- -43, -58, -61, -47, -13, 1, 1, 3, -5, -12, -17, -25, -36, -27, -25, -39,
- -45, -24, 1, 0, 8, 25, 43, 45, 42, 57, 76, 76, 73, 60, 37, -8,
- -25, -22, -25, -6, 9, 21, 41, 41, 15, -6, -18, -33, -48, -40, -38, -57,
- -64, -46, -6, 9, -4, 1, -1, -9, -18, -28, -33, -24, -27, -42, -45, -18,
- 2, 3, 13, 31, 49, 43, 37, 60, 74, 68, 68, 60, 30, -12, -28, -23,
- -19, -8, 5, 26, 48, 37, 11, -12, -17, -37, -54, -40, -41, -58, -65, -42,
- 5, 12, -8, 0, 2, -6, -22, -29, -30, -28, -37, -44, -42, -9, 6, 7,
- 17, 33, 44, 42, 40, 61, 72, 57, 63, 61, 24, -16, -34, -21, -15, -12,
- 3, 31, 47, 28, 7, -10, -15, -43, -51, -38, -45, -61, -61, -31, 10, 8,
- -3, 6, 5, -8, -24, -27, -28, -31, -44, -42, -29, -3, 6, 10, 24, 40,
- 44, 45, 46, 57, 62, 56, 65, 56, 16, -13, -32, -18, -12, -10, 11, 32,
- 39, 25, 6, -10, -19, -48, -44, -38, -49, -63, -61, -19, 12, 3, 4, 6,
- 3, -9, -25, -26, -27, -38, -46, -39, -18, 1, 12, 20, 29, 33, 36, 49,
- 47, 54, 59, 49, 63, 51, 8, -12, -25, -18, -18, -6, 20, 33, 28, 19,
- 4, -9, -27, -43, -41, -45, -55, -64, -51, -13, 7, -3, 0, 7, 3, -12,
- -28, -27, -33, -46, -51, -33, -10, -5, 15, 31, 34, 26, 32, 47, 51, 53,
- 47, 50, 61, 41, 1, -8, -12, -21, -20, 5, 27, 29, 16, 13, 8, -9,
- -28, -40, -40, -44, -55, -62, -40, -8, 5, -2, 4, 11, 4, -15, -26, -26,
- -37, -49, -47, -27, -8, -3, 22, 45, 38, 22, 34, 47, 55, 52, 39, 44,
- 58, 32, 2, 0, -7, -25, -21, 10, 29, 30, 9, 0, 0, -7, -26, -38,
- -40, -53, -61, -53, -30, -5, 1, -2, 5, 10, 3, -18, -25, -33, -43, -51,
- -46, -20, -10, -8, 26, 52, 35, 19, 32, 47, 56, 46, 33, 44, 48, 20,
- 10, 11, -7, -29, -20, 15, 35, 28, 2, -9, -8, -6, -26, -32, -36, -54,
- -64, -52, -22, 1, 3, 2, 3, 15, 2, -22, -24, -34, -41, -45, -39, -19,
- -9, 1, 35, 57, 37, 18, 27, 46, 52, 41, 37, 44, 40, 18, 16, 13,
- -7, -29, -14, 23, 36, 17, -6, -17, -2, 1, -24, -38, -43, -59, -62, -44,
- -22, -4, 7, 2, 5, 16, -2, -24, -27, -36, -43, -48, -37, -20, -5, 14,
- 40, 52, 36, 20, 26, 43, 46, 40, 41, 42, 28, 19, 19, 9, -4, -21,
- -10, 27, 32, 10, -6, -16, -4, -5, -14, -37, -48, -59, -58, -36, -24, -1,
- 13, -3, 7, 16, -5, -19, -32, -38, -46, -43, -32, -22, -7, 22, 49, 57,
- 37, 22, 20, 37, 41, 36, 46, 41, 21, 19, 16, 9, -2, -25, -9, 27,
- 24, 8, -12, -11, -2, -9, -10, -39, -51, -59, -59, -35, -21, 2, 15, -5,
- 10, 11, -12, -19, -35, -39, -46, -35, -29, -26, -5, 37, 60, 53, 36, 26,
- 19, 33, 37, 33, 48, 41, 18, 17, 19, 11, -8, -23, -3, 30, 21, -5,
- -14, -2, -6, -9, -9, -42, -59, -64, -54, -33, -16, 6, 14, 0, 15, 4,
- -14, -17, -35, -45, -46, -33, -27, -22, 2, 42, 56, 49, 37, 26, 19, 26,
- 23, 36, 58, 44, 11, 8, 23, 10, -7, -15, 3, 26, 12, -10, -8, 3,
- -10, -7, -13, -46, -58, -60, -57, -40, -11, 9, 9, 3, 13, -6, -12, -17,
- -42, -53, -45, -28, -23, -14, 11, 49, 60, 49, 40, 27, 14, 16, 13, 43,
- 62, 46, 6, 8, 22, 7, -9, -10, 11, 23, 4, -17, 2, 6, -6, -7,
- -21, -51, -58, -58, -55, -38, -12, 12, 10, 13, 1, -15, -7, -14, -47, -62,
- -45, -29, -19, -2, 21, 51, 63, 46, 37, 31, 16, 0, 4, 43, 64, 43,
- 6, 9, 24, 4, -15, -2, 14, 9, -9, -15, 14, 7, -11, -10, -29, -53,
- -54, -57, -48, -35, -9, 13, 9, 11, -5, -6, -2, -22, -57, -60, -39, -24,
- -11, 5, 30, 52, 62, 49, 42, 38, 11, -9, 7, 45, 61, 44, 10, 15,
- 21, -4, -15, 3, 13, 1, -13, -9, 13, 7, -9, -13, -32, -51, -53, -56,
- -44, -35, -9, 15, 11, 7, -8, 0, -2, -34, -65, -56, -31, -24, -7, 20,
- 37, 49, 56, 47, 47, 39, -3, -16, 12, 40, 53, 45, 16, 23, 17, -7,
- -8, 7, 8, -5, -12, -7, 7, 7, -4, -17, -38, -56, -60, -50, -37, -33,
- -8, 7, 9, 0, -6, 7, -8, -47, -71, -50, -25, -23, 0, 33, 41, 46,
- 52, 53, 54, 35, -6, -9, 13, 32, 50, 48, 23, 25, 13, -4, -3, 0,
- -1, -7, -7, -8, 3, 6, -3, -22, -41, -55, -62, -46, -30, -24, -5, 0,
- 5, 2, 3, 10, -20, -57, -69, -41, -19, -16, 5, 37, 47, 46, 49, 54,
- 58, 29, -4, -6, 7, 21, 49, 49, 24, 24, 12, -2, -5, -9, 0, 0,
- -10, -15, 2, 8, -4, -23, -42, -57, -66, -43, -22, -16, -11, -8, 3, 5,
- 7, 4, -28, -61, -61, -36, -19, -11, 10, 45, 51, 43, 46, 52, 54, 26,
- 3, -8, -3, 15, 52, 48, 27, 30, 15, -1, -9, -14, 0, -2, -15, -17,
- -2, -1, -5, -23, -37, -62, -64, -34, -17, -15, -19, -8, 4, 7, 8, -8,
- -37, -55, -50, -33, -19, -5, 16, 49, 54, 44, 45, 52, 53, 32, 3, -12,
- -5, 14, 46, 46, 38, 34, 21, 6, -13, -21, -2, -3, -18, -19, -14, -9,
- -2, -14, -44, -74, -56, -26, -15, -16, -18, -6, -1, 7, 6, -20, -43, -48,
- -35, -32, -24, 1, 23, 51, 54, 41, 42, 52, 49, 32, 3, -14, -5, 19,
- 42, 47, 43, 38, 27, 10, -18, -19, -5, -7, -18, -27, -23, -9, 2, -8,
- -51, -75, -41, -19, -15, -13, -15, -11, -5, 10, 1, -30, -37, -40, -30, -33,
- -24, 6, 30, 49, 49, 45, 43, 52, 39, 24, 7, -10, -7, 12, 33, 44,
- 48, 43, 36, 7, -29, -18, -6, -14, -23, -36, -32, -12, 2, -16, -60, -65,
- -27, -22, -22, -9, -6, -14, -6, 11, -10, -38, -35, -27, -26, -35, -15, 18,
- 39, 47, 48, 51, 55, 51, 28, 22, 13, -5, -6, 5, 27, 46, 57, 49,
- 39, 1, -29, -12, -7, -15, -28, -48, -39, -11, -1, -28, -61, -51, -22, -30,
- -22, -3, -4, -21, -6, 8, -23, -45, -29, -18, -27, -32, -11, 24, 44, 40,
- 46, 56, 61, 44, 17, 18, 19, 1, -11, -2, 24, 48, 57, 54, 45, 2,
- -27, -12, -11, -18, -32, -49, -41, -16, -10, -32, -47, -33, -25, -34, -13, 6,
- -5, -24, -13, -4, -29, -43, -29, -18, -25, -21, -1, 25, 44, 40, 49, 67,
- 60, 31, 12, 18, 24, -2, -18, -5, 22, 45, 62, 65, 46, -5, -21, -12,
- -12, -17, -36, -57, -48, -23, -15, -29, -35, -28, -33, -31, -3, 12, -16, -32,
- -12, -19, -36, -33, -25, -22, -29, -10, 14, 30, 41, 35, 51, 73, 57, 27,
- 16, 21, 14, -4, -12, -2, 21, 41, 62, 71, 43, -7, -12, -19, -22, -23,
- -46, -57, -51, -35, -20, -17, -22, -26, -37, -27, 7, 12, -24, -31, -14, -29,
- -34, -30, -22, -20, -21, 2, 15, 26, 40, 45, 55, 66, 52, 28, 20, 17,
- 10, -1, -12, -4, 21, 43, 65, 74, 39, 1, -9, -25, -27, -24, -45, -61,
- -55, -43, -22, -9, -12, -24, -32, -26, 9, 7, -25, -31, -30, -40, -31, -26,
- -19, -20, -11, 14, 18, 27, 45, 54, 52, 61, 49, 33, 24, 15, 5, 0,
- -14, -2, 24, 44, 62, 67, 37, 12, -9, -30, -29, -33, -49, -66, -58, -51,
- -25, -2, -6, -19, -31, -24, 6, 3, -21, -37, -43, -42, -31, -25, -17, -19,
- -5, 15, 19, 30, 52, 56, 45, 54, 52, 38, 22, 11, 8, 0, -16, 2,
- 27, 44, 63, 60, 34, 16, -10, -25, -31, -38, -55, -68, -62, -53, -18, 5,
- -2, -17, -31, -16, 5, -4, -22, -43, -50, -38, -32, -21, -16, -11, 8, 10,
- 19, 32, 60, 60, 43, 46, 51, 37, 24, 13, 8, -6, -17, 4, 32, 52,
- 56, 52, 39, 23, -5, -23, -41, -48, -64, -65, -63, -57, -14, 9, 3, -18,
- -28, -9, 0, -11, -25, -47, -53, -38, -30, -19, -11, 0, 10, 11, 23, 42,
- 66, 60, 42, 49, 53, 36, 24, 20, 9, -17, -18, 3, 39, 59, 49, 41,
- 39, 26, 1, -24, -53, -59, -70, -61, -66, -58, -12, 17, 7, -20, -26, -7,
- -7, -16, -30, -51, -60, -45, -26, -11, -5, 5, 8, 10, 23, 48, 66, 55,
- 40, 48, 48, 33, 30, 25, 2, -21, -15, 10, 41, 51, 44, 37, 41, 27,
- 6, -28, -60, -65, -70, -63, -70, -55, -6, 21, 1, -20, -15, -2, -15, -24,
- -32, -54, -66, -45, -22, -8, 6, 13, 5, 15, 31, 51, 64, 58, 41, 42,
- 44, 35, 36, 29, 0, -20, -9, 14, 43, 53, 46, 39, 39, 24, 7, -33,
- -69, -75, -73, -70, -75, -46, 4, 17, -2, -18, -6, 3, -18, -32, -38, -61,
- -65, -39, -17, -2, 10, 10, 5, 19, 33, 55, 61, 54, 39, 40, 41, 41,
- 40, 30, -6, -25, -6, 22, 44, 48, 42, 42, 37, 23, 11, -42, -73, -77,
- -75, -74, -75, -39, 4, 8, -5, -15, 1, -1, -30, -33, -38, -69, -66, -40,
- -14, 3, 16, 8, 5, 21, 39, 60, 59, 48, 40, 38, 39, 42, 42, 30,
- -8, -20, 0, 26, 48, 51, 48, 43, 29, 21, 1, -47, -70, -80, -83, -80,
- -70, -25, 0, -2, -9, -6, 9, -7, -29, -33, -49, -72, -59, -29, -3, 3,
- 11, 6, 14, 27, 47, 61, 54, 47, 43, 34, 42, 45, 39, 21, -10, -17,
- 4, 29, 53, 54, 47, 39, 29, 22, -11, -53, -70, -83, -86, -77, -61, -19,
- -6, -7, -12, -2, 9, -14, -29, -35, -61, -70, -54, -25, -8, 2, 11, 8,
- 17, 27, 54, 60, 50, 45, 42, 40, 43, 39, 35, 18, -9, -7, 8, 28,
- 55, 56, 49, 32, 30, 15, -21, -53, -71, -88, -87, -74, -45, -12, -11, -15,
- -14, 6, 12, -12, -30, -48, -66, -60, -44, -18, -8, 5, 13, 15, 21, 31,
- 51, 57, 48, 43, 42, 40, 43, 37, 29, 16, -3, -1, 7, 35, 60, 54,
- 38, 26, 29, 5, -30, -54, -72, -93, -87, -69, -34, -14, -19, -25, -12, 13,
- 6, -17, -37, -56, -66, -49, -38, -18, -11, 1, 17, 24, 26, 32, 47, 52,
- 50, 49, 45, 39, 40, 33, 32, 13, 4, 3, 3, 47, 65, 52, 29, 27,
- 20, -5, -35, -56, -76, -90, -79, -63, -27, -17, -26, -24, 0, 12, -2, -16,
- -33, -61, -61, -42, -33, -17, -16, -6, 22, 30, 25, 29, 45, 50, 46, 53,
- 41, 37, 37, 33, 28, 17, 15, 2, 15, 54, 64, 46, 21, 25, 9, -12,
- -39, -58, -77, -87, -75, -46, -21, -23, -34, -24, 9, 9, -7, -17, -40, -67,
- -53, -33, -27, -22, -26, -4, 34, 34, 25, 27, 46, 44, 52, 59, 37, 30,
- 35, 32, 26, 25, 16, 2, 30, 62, 57, 33, 19, 17, -7, -25, -43, -58,
- -80, -82, -64, -36, -26, -26, -33, -17, 11, 4, -9, -18, -45, -62, -44, -30,
- -24, -28, -29, 5, 38, 32, 25, 30, 48, 41, 53, 57, 35, 28, 26, 27,
- 31, 29, 14, 12, 47, 63, 48, 35, 24, 4, -19, -32, -46, -55, -76, -77,
- -58, -31, -30, -33, -36, -8, 12, -4, -9, -22, -51, -57, -30, -23, -27, -40,
- -31, 18, 36, 31, 30, 33, 39, 36, 56, 51, 32, 27, 20, 24, 39, 30,
- 16, 29, 55, 53, 43, 36, 21, -5, -28, -39, -45, -55, -71, -70, -47, -27,
- -35, -36, -25, -2, 1, -4, -6, -23, -48, -48, -25, -16, -25, -46, -23, 24,
- 30, 35, 34, 29, 33, 37, 51, 41, 30, 21, 12, 27, 47, 33, 19, 38,
- 51, 43, 39, 36, 15, -17, -35, -35, -42, -55, -68, -62, -45, -33, -40, -36,
- -19, -5, -4, -3, -6, -24, -47, -38, -17, -13, -37, -48, -13, 26, 30, 36,
- 32, 27, 29, 36, 48, 38, 27, 9, 5, 34, 47, 31, 30, 49, 47, 36,
- 38, 28, 11, -21, -32, -32, -47, -56, -60, -54, -40, -39, -42, -31, -12, -5,
- -7, -1, -4, -21, -39, -28, -11, -13, -45, -42, -2, 23, 25, 42, 33, 26,
- 26, 33, 44, 34, 20, 1, 5, 36, 47, 38, 40, 47, 37, 35, 38, 20,
- 1, -23, -26, -35, -49, -56, -55, -48, -40, -46, -42, -28, -12, -12, -10, 2,
- -6, -25, -32, -25, -13, -22, -43, -30, 5, 18, 24, 45, 35, 29, 21, 27,
- 39, 28, 16, 2, 9, 39, 40, 44, 55, 45, 25, 31, 34, 15, -1, -18,
- -25, -41, -49, -50, -52, -46, -42, -48, -40, -23, -9, -18, -13, 9, -1, -24,
- -27, -22, -14, -30, -41, -26, 8, 15, 25, 40, 36, 26, 15, 26, 35, 21,
- 11, 2, 17, 44, 37, 54, 63, 37, 16, 31, 27, 12, -3, -12, -24, -45,
- -47, -46, -45, -40, -44, -55, -40, -17, -12, -22, -7, 19, -2, -22, -24, -15,
- -17, -36, -36, -11, 16, 10, 17, 38, 43, 25, 15, 25, 26, 14, 7, 2,
- 25, 39, 38, 63, 67, 30, 16, 25, 18, 14, -5, -9, -26, -43, -45, -47,
- -42, -38, -52, -57, -35, -14, -22, -27, 0, 23, -5, -24, -22, -12, -21, -40,
- -31, 1, 19, 6, 11, 35, 44, 22, 18, 28, 14, 4, 4, 11, 32, 34,
- 38, 70, 68, 22, 18, 17, 15, 17, 0, -10, -31, -45, -43, -42, -34, -36,
- -62, -61, -25, -11, -28, -29, 3, 25, -3, -26, -15, -12, -28, -34, -21, 9,
- 17, 2, 10, 31, 40, 24, 23, 28, 5, -3, 6, 19, 35, 33, 42, 72,
- 59, 22, 22, 12, 17, 17, 2, -11, -31, -40, -40, -36, -28, -40, -66, -57,
- -18, -15, -32, -22, 9, 22, -3, -23, -8, -12, -31, -32, -12, 18, 15, -1,
- 9, 25, 36, 26, 27, 20, -7, -5, 12, 23, 29, 33, 45, 70, 48, 25,
- 20, 8, 16, 9, 4, -11, -33, -39, -37, -34, -30, -46, -65, -50, -23, -22,
- -30, -19, 13, 22, -4, -21, -6, -15, -32, -28, -3, 18, 9, 0, 9, 21,
- 30, 28, 30, 12, -14, -1, 17, 19, 27, 41, 51, 63, 35, 28, 22, 12,
- 10, 6, 9, -14, -31, -36, -31, -27, -38, -49, -62, -48, -29, -25, -27, -13,
- 13, 13, -3, -9, -9, -21, -30, -20, 4, 12, 4, 5, 12, 19, 27, 33,
- 29, 6, -12, 2, 21, 17, 31, 45, 54, 55, 31, 31, 25, 14, 3, 5,
- 11, -14, -27, -33, -24, -27, -41, -49, -63, -53, -37, -26, -22, -7, 11, 8,
- 0, -3, -14, -19, -27, -14, 8, 5, 2, 9, 12, 20, 25, 31, 18, 0,
- -6, 8, 20, 14, 27, 43, 59, 48, 24, 28, 25, 14, 2, 8, 6, -15,
- -26, -30, -16, -28, -44, -53, -61, -58, -37, -27, -21, -4, 8, 3, 1, -2,
- -18, -21, -24, -11, 3, -4, 3, 15, 17, 20, 22, 29, 15, 3, -2, 8,
- 17, 18, 30, 46, 56, 40, 21, 29, 26, 14, -1, 5, 4, -6, -22, -29,
- -13, -27, -46, -51, -62, -61, -37, -28, -14, 2, 7, 0, 5, -2, -16, -17,
- -19, -10, -7, -9, 11, 20, 22, 18, 17, 25, 19, 4, -1, 10, 19, 25,
- 32, 44, 53, 36, 19, 29, 24, 10, -4, 5, 4, -2, -22, -24, -13, -31,
- -48, -56, -63, -60, -40, -31, -11, 8, 8, 2, 8, -6, -20, -17, -12, -10,
- -20, -12, 14, 30, 26, 10, 14, 24, 24, -1, -7, 12, 25, 27, 30, 40,
- 52, 34, 17, 28, 24, 7, -9, 1, 8, 3, -20, -20, -16, -33, -53, -59,
- -62, -61, -47, -29, -5, 15, 5, 1, 9, -8, -20, -14, -5, -12, -30, -11,
- 20, 37, 25, 10, 19, 25, 19, -5, -2, 18, 28, 26, 29, 41, 49, 31,
- 20, 30, 24, 1, -8, 4, 10, 3, -17, -12, -18, -40, -57, -61, -62, -59,
- -48, -23, 0, 18, 5, 5, 12, -9, -19, -9, -2, -20, -37, -7, 25, 39,
- 23, 11, 25, 26, 10, -10, 5, 23, 24, 26, 30, 40, 42, 27, 23, 31,
- 18, -7, -5, 2, 7, -1, -10, -10, -22, -45, -59, -63, -62, -58, -45, -21,
- -1, 17, 10, 13, 7, -18, -21, -5, -3, -27, -38, -7, 26, 38, 21, 20,
- 31, 23, 0, -9, 15, 25, 21, 28, 33, 35, 35, 29, 28, 31, 12, -5,
- 0, 0, 4, 0, -3, -14, -27, -48, -57, -69, -66, -61, -40, -19, 1, 16,
- 13, 16, -3, -18, -17, -4, -9, -30, -33, -1, 24, 35, 28, 34, 31, 16,
- -4, -2, 22, 29, 20, 27, 38, 33, 30, 30, 31, 33, 9, 1, -3, -7,
- 2, 6, -1, -22, -31, -50, -61, -74, -67, -52, -34, -25, 1, 19, 21, 14,
- -8, -18, -14, -10, -14, -27, -26, -5, 21, 35, 38, 40, 31, 12, -1, 5,
- 22, 29, 19, 31, 41, 28, 30, 28, 31, 28, 12, 7, -13, -11, -2, 13,
- -5, -26, -32, -52, -67, -80, -65, -46, -34, -26, 2, 15, 25, 9, -8, -14,
- -16, -10, -18, -25, -25, -9, 20, 37, 46, 35, 26, 10, 7, 8, 18, 27,
- 18, 31, 39, 25, 29, 29, 34, 26, 20, 2, -18, -10, -5, 12, -9, -22,
- -31, -48, -74, -79, -66, -42, -34, -22, -1, 14, 25, 13, -6, -19, -16, -8,
- -19, -22, -21, -5, 21, 41, 51, 32, 25, 14, 19, 13, 14, 21, 21, 32,
- 34, 26, 26, 30, 32, 25, 25, -3, -19, -13, -2, 8, -12, -24, -32, -46,
- -75, -79, -67, -43, -33, -18, -7, 12, 25, 18, 0, -23, -13, -7, -23, -18,
- -15, -4, 21, 48, 51, 27, 27, 23, 22, 12, 12, 19, 22, 28, 28, 28,
- 28, 31, 28, 23, 28, -3, -20, -22, -5, 0, -14, -23, -28, -50, -78, -81,
- -63, -44, -34, -19, -14, 10, 25, 18, -6, -19, -5, -11, -30, -17, -8, 2,
- 21, 54, 45, 25, 28, 33, 25, 9, 12, 21, 26, 23, 24, 33, 37, 35,
- 20, 23, 32, -1, -21, -25, -12, -11, -12, -19, -27, -53, -78, -79, -55, -42,
- -31, -26, -18, 12, 24, 13, -9, -12, 0, -20, -33, -13, 1, 6, 26, 55,
- 38, 25, 33, 45, 26, 7, 13, 21, 26, 16, 18, 38, 44, 33, 14, 25,
- 30, 4, -24, -32, -21, -18, -19, -19, -25, -54, -79, -78, -53, -43, -29, -28,
- -20, 6, 20, 12, -3, 0, -3, -35, -28, 1, 9, 8, 25, 46, 34, 30,
- 37, 44, 19, 13, 20, 17, 20, 12, 18, 49, 49, 23, 13, 28, 33, 3,
- -34, -37, -28, -30, -21, -10, -26, -57, -77, -74, -52, -40, -25, -32, -22, 3,
- 17, 12, 3, 8, -15, -40, -18, 10, 10, 4, 32, 39, 27, 38, 48, 39,
- 11, 18, 28, 17, 15, 5, 23, 61, 46, 21, 23, 35, 26, -3, -31, -37,
- -39, -38, -23, -3, -29, -60, -74, -68, -58, -37, -27, -35, -22, -7, 15, 23,
- 14, 8, -27, -41, -6, 19, 14, 9, 35, 31, 31, 48, 54, 35, 11, 27,
- 26, 4, 7, 11, 31, 54, 38, 25, 34, 35, 20, -10, 19, 3, -8, -45,
- 64, -15, -41, 23, 40, -58, 22, 29, -27, -28, 42, -36, 21, -12, -19, 39,
- -14, 3, -18, 32, -27, 18, -8, -43, 43, 25, -52, 6, 19, 13, -7, -50,
- 55, 5, -46, -22, 94, -53, -33, 35, 27, -45, -2, 20, 19, -30, -23, 47,
- 8, -58, 5, 76, -67, -22, 42, 30, -54, 8, 23, 11, -51, 3, 47, -33,
- -7, 5, 27, -33, 34, -35, 17, 4, -26, 5, 17, -30, 33, 5, -29, -5,
- 44, -18, -50, 60, -33, 10, -5, 10, -7, 1, -5, 19, -36, 3, 37, -17,
- -51, 52, 37, -64, 9, 4, 37, -44, -13, 25, 45, -75, -9, 79, -34, -57,
- 53, 24, -59, 18, 22, -3, -24, 10, -2, 18, -53, 29, 35, -20, -43, 37,
- 18, -17, -31, 8, 45, -49, 8, 11, 9, -23, 30, -24, -22, 29, 14, -43,
- 27, 13, -22, -1, 2, 22, -37, 5, -5, 38, -43, 6, 36, -21, -20, 20,
- 0, -5, -27, 27, 21, -53, 4, 52, -2, -84, 70, 5, -29, -19, 36, -6,
- -8, -12, 3, 35, -32, -25, 48, 6, -60, 49, 4, -27, -13, 31, -15, -9,
- -4, 31, -13, -25, 29, 12, -34, -6, 30, -41, 36, -23, 6, 31, -30, 0,
- 17, -45, 47, -5, -47, 19, 28, -8, -30, 27, -6, 15, -54, 34, 21, -27,
- -9, 25, 3, -45, 26, 27, -52, 22, 20, -29, 34, -46, 22, 40, -69, -27,
- 108, -49, -54, 69, -11, -3, -18, 3, 15, -12, -23, 29, -8, 4, -23, 50,
- -38, -8, 33, -32, -2, 26, -27, 12, 13, -39, 56, -31, -22, 28, 2, -39,
- 54, -20, -36, 51, -6, -34, 15, 2, 1, 2, -36, 42, 2, -10, -39, 64,
- -36, -16, 24, 1, -1, -18, -10, 54, -27, -54, 80, -18, -61, 51, 27, -76,
- 64, -30, -1, 9, -19, 24, 13, -29, -13, 49, -18, -46, 43, 6, -47, 42,
- -28, 14, 18, -18, 2, 14, -39, 25, 16, -58, 33, 29, -49, 16, 41, -62,
- 43, -17, -17, 25, -10, -28, 41, -5, -30, 27, 14, -53, 27, 35, -63, 16,
- 30, 0, -30, -10, 22, 31, -57, 0, 68, -59, 2, 37, -30, 6, -3, -19,
- 35, -29, 1, 20, 22, -68, 33, 39, -71, 21, 27, -22, -1, 3, 0, 18,
- -16, -13, 17, 4, -37, 44, -15, -26, 48, -29, -11, 34, -25, -4, 25, -48,
- 43, 4, -49, 28, 42, -72, 7, 59, -36, -28, 45, -9, -28, 25, -19, 23,
- -9, -40, 47, 18, -85, 78, -2, -53, 39, -17, 2, 14, -36, 10, 63, -78,
- 17, 59, -66, -8, 54, -49, 14, 1, 5, 2, -18, 16, -12, 30, -58, 22,
- 53, -83, 17, 79, -84, 19, 17, -34, 44, -33, -27, 82, -62, -19, 91, -93,
- 22, 49, -51, -25, 48, -12, -6, 1, -2, -1, 22, -32, -1, 59, -78, 12,
- 58, -49, -26, 70, -40, -8, 16, -8, 12, 10, -65, 74, -1, -97, 90, 0,
- -56, 23, 25, -17, 11, -23, 14, 9, -24, -31, 77, -41, -48, 95, -38, -46,
- 59, -1, -57, 49, -33, 19, 18, -46, 34, 31, -79, 47, 11, -38, 10, 19,
- -14, -10, 26, -29, 28, -17, -27, 48, -15, -51, 78, -14, -73, 64, 12, -55,
- 29, 3, -24, 52, -65, 26, 50, -75, -5, 81, -76, 0, 42, -6, -26, 10,
- 18, -14, 4, -24, 33, 2, -69, 61, 43, -101, 40, 54, -73, 22, 18, -41,
- 44, -19, -43, 94, -69, -13, 65, -26, -46, 35, 24, -34, -2, 23, -13, 6,
- -19, 4, 38, -56, 14, 40, -37, -19, 66, -57, -9, 50, -47, 21, 6, -31,
- 55, -34, -50, 98, -44, -47, 44, 28, -51, 6, 31, -3, -34, 8, 11, 6,
- -18, -27, 78, -48, -28, 55, -2, -60, 57, -37, 14, 15, -48, 49, 22, -96,
- 74, 23, -83, 36, 18, -17, -25, 41, -12, -4, -2, 1, 9, -14, -18, 36,
- 12, -77, 54, 32, -67, 20, 38, -67, 61, -53, 32, 21, -60, 27, 41, -74,
- 27, 33, -30, -6, 22, -1, -30, 20, 1, -4, -22, 9, 8, 37, -65, 18,
- 61, -69, -3, 37, -19, -15, 15, -16, 57, -78, 20, 66, -67, -27, 76, -37,
- -16, 11, 11, -5, -18, 10, 16, -5, -38, 36, 9, -20, -32, 73, -41, -36,
- 62, -33, -9, 34, -41, 35, -7, -40, 65, -35, -26, 33, 2, -43, 42, -4,
- -9, 5, -11, 19, -10, -16, 11, 16, -28, -9, 41, 2, -70, 67, -3, -55,
- 23, 33, -26, 6, -29, 43, 16, -85, 51, 28, -54, 7, 27, -9, 2, -18,
- 27, -4, -42, 31, 10, -19, -9, 18, 8, -24, -3, 45, -57, 25, 0, -7,
- 15, -28, 10, 33, -46, -6, 52, -36, -15, 46, -29, -4, 12, -14, 34, -57,
- 16, 40, -41, 3, 16, 8, -32, 16, 15, -17, -27, 47, -30, -1, 14, -5,
- 16, -17, -33, 70, -44, -42, 84, -34, -27, 18, 15, 3, -20, -22, 55, -35,
- -22, 31, 10, -11, -27, 27, 13, -28, -10, 41, -21, -3, -22, 41, -21, -13,
- 6, 34, -68, 46, 25, -65, 50, -21, -1, 10, -33, 34, 1, -43, 58, -34,
- -2, 13, 8, -25, 0, -2, 34, -29, -26, 45, -12, 4, -34, 32, 15, -54,
- 17, 53, -76, 41, 4, -17, 13, -26, 13, 31, -47, 1, 52, -53, 11, 8,
- 14, -31, -7, 19, 30, -60, 26, 27, -22, -10, 0, 18, -13, -24, 52, -38,
- -17, 68, -60, 26, -9, -25, 41, -29, -8, 40, -25, -9, 26, -28, 15, -9,
- -3, 11, -21, -1, 44, -47, 19, 0, 3, -14, -12, 38, -22, -23, 37, -10,
- -13, 9, -6, 21, -14, -39, 61, -4, -68, 60, 6, -43, 28, -14, 21, -22,
- -13, 36, -7, -40, 46, -14, -5, -18, 20, 22, -49, 22, 10, -18, 21, -30,
- 9, 34, -54, 19, 22, -34, 27, 7, -45, 30, 0, -20, 23, -23, 29, -10,
- -21, 25, 3, -23, -1, 5, 16, -33, 14, 25, -21, -11, 16, 3, -22, 5,
- 6, 32, -73, 27, 62, -72, 5, 26, -21, 30, -37, 4, 40, -45, 5, 18,
- -18, -1, 12, -3, 0, -18, 28, -8, -14, 11, -11, 13, -15, -3, 27, -17,
- -30, 65, -45, -5, 28, -25, 1, 20, -36, 38, -11, -20, 35, -23, -20, 27,
- 11, -42, 13, 17, 1, -25, 20, 10, -33, 10, 6, -7, 9, -26, 40, -3,
- -63, 74, -30, -11, 10, -10, 5, 17, -47, 53, -10, -47, 29, 31, -45, 4,
- 16, 14, -15, -33, 40, -11, -3, -10, 2, 18, -20, 9, 22, -44, 19, 20,
- -42, 25, -5, -11, 25, -25, -3, 47, -63, 28, 20, -42, 7, 39, -41, 2,
- 13, 10, -24, -8, 41, -26, -1, -13, 9, 42, -60, 0, 61, -54, -4, 19,
- -6, 11, -19, -13, 52, -37, -26, 66, -38, -30, 49, -18, -11, 5, 7, 10,
- -30, 4, 17, 2, -12, -15, 38, -19, -20, 30, -16, -23, 38, -13, -16, 29,
- -22, 26, -17, -35, 62, -30, -35, 51, -16, -27, 40, -16, 3, -8, -4, 9,
- 4, -26, 11, 20, -11, -38, 56, -19, -29, 31, 7, -39, 17, 10, 6, -8,
- -41, 45, 26, -79, 36, 42, -58, 21, 6, -10, 7, -19, 17, -1, -15, -12,
- 53, -22, -32, 24, 25, -59, 24, 22, -36, 10, 18, -27, 44, -45, 0, 42,
- -45, -2, 30, -27, 12, 23, -38, 13, 5, 4, -4, -20, 1, 43, -27, -36,
- 43, 14, -51, 12, 40, -41, 5, 18, -11, -1, -5, -11, 53, -56, -29, 91,
- -41, -45, 57, -7, -18, -3, -4, 29, -20, -19, 20, 26, -57, 31, 17, -22,
- -13, 28, -31, 3, 36, -33, 9, 17, -39, 42, -9, -54, 58, 6, -69, 44,
- 30, -50, 24, 3, -17, 9, -20, 17, 8, -23, 1, 46, -50, 1, 27, 1,
- -49, 37, 5, -17, 4, -5, 7, 18, -55, 39, 36, -85, 37, 48, -63, 5,
- 27, -13, -6, -4, 5, 24, -26, -12, 42, -25, -34, 33, 20, -33, -13, 29,
- -2, 7, -34, 12, 37, -50, 1, 47, -46, -1, 56, -54, -18, 59, -35, -6,
- 12, -16, 20, -2, -27, 43, -12, -34, 22, 25, -41, -7, 43, -20, -18, 19,
- -1, 1, -6, -20, 54, -55, -12, 67, -24, -56, 56, -8, -12, -7, -3, 16,
- 20, -48, 20, 32, -46, 8, 23, -17, -38, 54, 1, -34, 2, 30, -1, -21,
- -18, 38, -14, -35, 41, 3, -36, 19, 22, -45, 40, -32, 12, 12, -26, 2,
- 35, -54, 34, 14, -25, -30, 47, 10, -53, 24, 13, -4, -18, 3, 5, 27,
- -61, 38, 15, -39, 6, 40, -36, 0, 2, -6, 28, -40, 7, 46, -37, -30,
- 59, -21, -29, 6, 48, -55, 12, 30, -21, -6, 5, -2, 1, -14, -7, 46,
- -41, -4, 35, -8, -33, 29, -20, 26, -31, -10, 63, -46, -4, 12, 7, -11,
- -15, 26, -14, -22, 54, -47, 12, 9, -1, -8, -7, -8, 41, -12, -60, 77,
- -21, -26, 11, 13, 1, -26, -9, 59, -45, -16, 38, -3, -27, -1, 28, -8,
- -19, 11, 20, -41, 34, -23, 22, -20, -9, 6, 51, -79, 40, 18, -40, 23,
- -5, -19, 13, 2, 3, -4, -35, 71, -39, 5, -30, 33, 6, -29, -3, 38,
- -29, -5, 18, -9, -4, -11, 16, 15, -32, -14, 77, -83, 30, 10, -10, -19,
- 20, 15, -17, -19, 29, 7, -32, 6, -1, 14, -14, -6, 5, 36, -58, 47,
- -18, -14, 4, 8, 8, -24, -15, 60, -36, -20, 43, -32, 3, -2, 1, 9,
- -5, -8, 30, -33, 6, 6, 2, -12, -11, 24, 1, -22, 9, 34, -61, 25,
- 11, -5, -18, -1, 38, -19, -33, 49, -19, -21, 18, -7, 1, 5, -4, -3,
- 13, -30, 25, -5, -12, 2, 8, 17, -37, 0, 50, -38, -26, 40, -15, 7,
- -24, 31, -11, -8, 6, -6, -3, 1, 9, -8, 6, -20, 25, 0, -21, 7,
- 22, -48, 29, -4, 10, -22, 7, 22, -9, -34, 45, -15, -31, 30, -2, 0,
- -30, 46, -18, -6, -17, 31, -6, -7, -21, 8, 45, -47, -7, 31, -17, -11,
- 25, -20, 17, -30, 47, -38, -2, 5, 16, -36, 24, -2, 3, -7, 6, 10,
- -23, 5, -11, 35, -42, 17, 0, 21, -35, 11, 16, -18, -15, 36, -24, -3,
- 9, 5, 13, -49, 36, -11, -2, -14, 37, -32, 13, -1, 0, -2, -2, -8,
- 17, -11, -21, 30, -1, -1, -41, 72, -65, 14, 14, 12, -41, 21, 4, 15,
- -32, -1, 25, -9, -18, 3, 29, -38, 35, -22, 14, -20, 16, -6, -6, -13,
- 29, -4, -17, 7, 14, -6, -38, 54, -32, 3, -16, 36, -39, 42, -40, 36,
- -22, -13, 17, 14, -36, 12, 23, -25, 6, -25, 53, -33, -12, 5, 37, -46,
- 6, 20, 9, -53, 52, -16, -22, 24, -9, 10, -17, 12, -20, 48, -73, 40,
- 18, -30, -20, 52, -34, 11, -6, 0, 1, -15, 24, -16, 16, -30, 44, -27,
- -10, 0, 34, -52, 24, 3, 2, -6, 12, -25, 35, -38, -14, 72, -73, 7,
- 31, 15, -50, 20, 12, -5, -25, 23, 3, -10, -9, 15, 9, -41, 28, 6,
- -5, -36, 44, -13, 10, -19, 2, 14, -10, -29, 56, -27, -35, 58, -19, -27,
- 17, 16, -30, 10, -7, 15, -12, -3, 11, 18, -30, -13, 38, -17, -16, 3,
- 32, -37, 23, -24, 30, -12, -26, 40, -14, -52, 59, 12, -55, 16, 35, -20,
- -30, 39, -24, 21, -26, 12, 13, -10, -19, 23, 2, -35, 17, 33, -30, -17,
- 39, -15, 12, -53, 50, -13, -25, 2, 50, -42, -1, 25, -22, 6, -5, 3,
- -4, 2, -18, 39, -25, -3, 1, 29, -57, 22, 26, -22, -18, 34, -10, -10,
- -11, 13, 31, -77, 46, 23, -22, -35, 61, -24, -13, 7, -3, 0, 4, -24,
- 27, 12, -50, 35, 13, -19, -37, 69, -46, -4, 13, 5, -8, 6, -25, 40,
- -26, -13, 38, -12, -28, 21, 22, -57, 40, -15, 11, -19, 4, 19, 9, -36,
- 3, 42, -35, -30, 46, 0, -50, 59, -26, 9, -16, 12, -10, 10, -33, 44,
- -8, -29, 8, 42, -43, -6, 26, -19, 14, -30, 34, 4, -21, -17, 49, -31,
- -24, 34, 14, -53, 32, 13, -26, 12, -22, 26, -3, -22, -11, 66, -59, 0,
- 43, -27, -23, 42, -32, 7, -7, 11, 9, -19, -1, 15, 16, -58, 43, 1,
- -32, 11, 36, -44, 18, 0, 4, -4, -7, -22, 50, -22, -44, 67, -14, -43,
- 37, 2, -32, 15, 7, 8, -22, -1, 14, 19, -43, 0, 40, -30, -14, 28,
- 10, -32, 11, 1, 21, -33, -9, 31, 15, -72, 61, 4, -40, 21, 14, -37,
- 22, 4, -4, -9, 5, -8, 23, -16, -22, 35, -24, 0, 12, 3, -17, 15,
- 2, -10, -6, -8, 21, 7, -58, 40, 43, -75, 25, 28, -25, -18, 28, -15,
- 6, -5, -4, 22, -5, -39, 37, 1, -30, 12, 23, -27, -8, 34, -22, 0,
- -12, 15, 10, -28, 2, 45, -45, -9, 36, -22, -7, 13, -7, 6, 2, -18,
- 17, 10, -34, 9, 18, -22, -1, 22, -9, -17, 23, -1, -22, 21, -20, 20,
- -17, -6, 38, -33, -18, 55, -32, -21, 26, -5, -9, 5, -8, 16, 9, -47,
- 36, 11, -36, -3, 38, -7, -48, 44, -2, -11, 2, -16, 15, 11, -36, 33,
- -3, -18, 9, 19, -46, 26, -1, -11, 20, -24, 12, 16, -16, -17, 37, -32,
- -6, 13, 13, -33, 25, 14, -27, 8, 1, -18, 22, -5, -15, 32, -46, 37,
- -2, -19, -13, 38, -32, 8, 2, -4, 15, -12, -4, 19, -25, -10, 37, -19,
- -11, -10, 57, -54, 19, -17, 18, 3, -18, -9, 27, -6, -36, 57, -23, -21,
- 14, 11, -23, 32, -53, 56, -24, -5, -3, 11, -16, 16, -7, -20, 17, 11,
- -3, -31, 42, -33, 14, -6, -2, -8, 39, -56, 48, -21, -20, 30, -8, -20,
- 12, 15, -32, 41, -36, 29, -25, 14, -22, 22, -19, 9, 4, 10, -31, 17,
- 11, -14, -1, -7, 17, -16, 6, -18, 64, -88, 47, 6, -20, -5, 22, -13,
- 18, -28, 2, 25, -19, -10, -3, 29, -23, 11, -22, 39, -25, 13, -27, 20,
- -2, -18, 15, -3, 3, 9, -17, -8, 38, -57, 35, 1, -9, -24, 43, -32,
- 30, -30, -3, 19, -3, -21, 12, 14, -12, 2, -5, 11, -37, 37, -3, -13,
- -4, 10, 11, -4, -38, 41, -9, -27, 37, -37, 16, 17, -7, -15, 22, -40,
- 33, -2, -16, 4, 3, 8, -4, -20, 21, -3, -10, 8, -26, 37, -21, 8,
- 0, -3, -3, 0, -8, 20, -15, -32, 54, -10, -26, 17, -12, 10, 24, -71,
- 51, 3, -21, 9, -3, 17, -22, 2, 15, -21, -11, 39, -25, 11, -27, 28,
- 3, -11, -26, 45, -43, 24, 7, -39, 47, -24, -15, 27, -13, -15, 35, -27,
- 15, -17, 9, 0, -7, 0, 4, -9, 13, -3, -16, 28, -29, 21, -23, 11,
- -4, 10, -30, 64, -63, 13, 28, -30, 16, -13, 0, 25, -39, -2, 53, -40,
- 5, -19, 41, -25, -6, -3, 37, -40, 6, 8, 0, 6, -34, 32, 4, -27,
- 13, 15, -34, 52, -63, 40, -5, -22, 5, 24, -32, 22, 11, -26, 14, -22,
- 26, -21, 10, -8, 5, -10, 46, -66, 44, -20, 14, -7, -27, 23, 30, -53,
- 24, 10, -37, 44, -40, 21, -11, 3, 6, 20, -47, 27, 5, -2, -18, -4,
- 29, -13, -20, 27, 9, -47, 43, -37, 55, -62, 14, 33, -13, -28, 24, -9,
- 23, -35, -4, 32, -14, -13, 28, -10, -30, 46, -43, 43, -46, 13, 13, -10,
- 7, -3, -20, 39, -19, -19, 14, -15, 39, -31, -10, 25, 2, -34, 41, -35,
- 15, -4, -3, 22, -18, -27, 46, -1, -36, 10, -4, 42, -56, 13, 31, -19,
- -18, 28, -29, 27, -32, 24, 10, -44, 20, 32, -32, -17, 32, -13, 13, -35,
- 20, 32, -53, 20, 9, -16, 16, -36, 39, -3, -33, 43, -26, 2, 2, 2,
- -17, 24, -22, 14, -3, -12, 31, -28, -8, 26, -29, 19, -4, -15, 33, -39,
- 22, 16, -37, 6, 17, -4, -13, -12, 37, 9, -65, 34, 25, -27, -9, 7,
- 5, 10, -36, 45, -11, -41, 42, -6, -21, 7, -5, 31, -5, -57, 62, -12,
- -15, -16, 23, 4, -24, 12, 26, -35, -11, 44, -25, -8, -1, -4, 28, -11,
- -37, 61, -48, 23, -1, -30, 29, -8, -2, 6, -19, 18, 15, -41, 30, -4,
- -11, -11, 28, -10, -4, -37, 81, -45, -43, 61, -19, 1, -11, 0, 31, -30,
- -25, 68, -43, -11, 0, 27, -1, -33, -7, 77, -54, -30, 44, -6, -5, -14,
- 17, -6, -10, 6, 30, -68, 50, -16, 5, 5, -30, 30, 26, -69, 36, 8,
- -34, 37, -28, 11, 0, -1, 9, 1, -41, 53, -22, -24, 23, 5, -9, -11,
- 12, 28, -61, 28, 36, -68, 51, -33, 25, -6, -26, 7, 53, -65, 2, 47,
- -25, -23, 17, 20, -4, -51, 38, 29, -67, 31, 1, 22, -35, -8, 40, -9,
- -46, 47, -13, -8, 5, -15, 37, -27, -20, 45, -16, -45, 59, -37, 19, -6,
- 2, 1, -11, -3, 34, -42, 0, 33, -30, 16, -13, 13, 2, -23, 18, -5,
- -26, 43, -24, 15, -26, 4, 35, -15, -62, 64, 19, -75, 50, -8, 8, -14,
- -12, 31, -19, -30, 45, -10, -12, -10, 36, 3, -53, 14, 45, -37, -22, 42,
- -25, 21, -36, 21, 37, -61, 5, 47, -49, 19, -4, 5, 1, -12, 7, 3,
- -11, 2, 18, -28, 13, -4, 18, -13, -20, 33, -22, -8, 21, -12, -10, 24,
- -9, 2, -27, 15, 33, -41, -18, 56, -40, 9, -5, 6, 20, -44, 11, 39,
- -35, -22, 50, -7, -36, -6, 41, -10, -30, 15, 20, -22, 7, -11, 16, 6,
- -51, 59, -21, -26, 24, 12, -24, 8, -7, 12, 3, -36, 27, 18, -42, 22,
- 9, -22, 11, -2, 15, -40, 38, -13, -16, 8, 24, -33, 15, -13, 4, 23,
- -42, 17, 30, -34, -5, 28, -22, 11, -23, 30, -14, -28, 37, 12, -46, 11,
- 31, -23, -12, -7, 36, -17, -6, -4, 25, -18, 4, -29, 53, -48, 4, 24,
- -9, -21, 30, -1, -20, 2, -13, 51, -51, -1, 39, -23, -18, 33, -23, 3,
- 3, 2, -13, 11, 4, -13, 15, -14, -3, 1, 24, -53, 55, -24, -17, 36,
- -1, -49, 45, -7, -12, -2, -4, 24, -23, 1, 6, 23, -51, 30, -8, 14,
- -29, 17, 12, -9, -21, 21, 1, 3, -32, 21, 30, -59, 27, 25, -21, -26,
- 36, -24, 16, -23, 15, 10, -15, 11, -11, -3, 14, 1, -30, 32, -24, 27,
- -25, 10, -12, 29, -33, 7, -5, 25, -29, 14, 15, -42, 20, 18, -27, 1,
- 21, -19, 17, -18, 2, 19, -12, -34, 47, -21, -6, 9, -2, 14, -32, 32,
- -23, 14, -21, 21, 0, -13, -8, 42, -35, -19, 33, 4, -34, 23, -5, -6,
- 22, -31, 21, -8, -5, -3, 15, -22, 10, 2, 7, -17, 11, 3, -10, 2,
- -1, -2, -9, 25, -20, 11, -18, 17, -3, -12, 2, 9, -1, -10, 5, 0,
- 15, -40, 36, -5, -28, 16, 24, -34, 16, -1, 13, -32, 11, 9, 5, -26,
- 5, 32, -32, 4, -1, 29, -38, 8, 7, -6, 5, -2, -5, 18, -26, -2,
- 39, -42, 0, 26, 2, -43, 45, -30, 20, -11, -6, -3, 16, -7, -6, 3,
- 12, -13, 5, -7, -21, 47, -29, -11, 9, 36, -45, 8, 0, 22, -28, -7,
- 32, -22, -9, 20, 12, -40, 24, -8, 14, -28, 10, 9, 12, -29, 15, -7,
- 15, -23, 5, 14, -24, 12, 8, 4, -38, 36, -4, -7, -30, 47, -13, -24,
- 16, 23, -46, 29, -3, -10, 20, -43, 35, 0, -4, -30, 47, -18, -21, 16,
- 19, -35, 11, 19, -21, -11, 27, -12, -9, 16, -21, 23, -32, 30, 3, -22,
- -15, 51, -38, -1, -2, 11, 15, -28, -1, 16, 13, -42, 23, 4, -6, -32,
- 61, -24, -35, 34, 29, -55, 4, 13, 9, -6, -26, 35, -6, -11, -11, 19,
- -6, -3, -15, 43, -41, 4, 22, -1, -34, 18, 15, -35, 18, -1, 23, -35,
- 18, -2, -9, 1, 10, -18, 17, -18, 21, -8, -17, 24, -1, -20, -7, 26,
- -11, 6, -33, 42, 0, -40, 9, 46, -48, -6, 24, 13, -39, 8, 41, -43,
- 3, 6, 6, -7, -6, -8, 42, -37, -11, 39, -16, -26, 25, 3, -24, 9,
- 11, 6, -34, 17, 14, -12, -22, 20, 0, 14, -38, 27, 10, -37, 22, -1,
- -5, -7, 11, 4, -3, -29, 38, -5, -26, 4, 20, -17, 6, 2, 11, -17,
- -10, 40, -49, 10, 26, -8, -24, 11, 12, 5, -36, 21, 20, -22, -29, 28,
- 30, -30, -24, 31, 25, -70, 39, 4, -16, 3, 9, -13, 16, -26, 23, 19,
- -46, 1, 29, 6, -37, 8, 27, -8, -33, 36, -24, 5, 14, -8, -8, 1,
- 4, 15, -27, -11, 44, -38, 6, 12, -3, -12, 20, -17, 16, -35, 28, -4,
- 0, -13, 8, 23, -24, -16, 28, 11, -58, 48, 6, -39, 11, 24, -9, -8,
- -25, 42, -16, -14, 12, 2, 13, -31, 6, 26, -10, -48, 64, -22, -21, 6,
- 28, -15, -11, -2, 22, -30, 11, 15, -25, 13, 2, -1, -7, -4, 6, 17,
- -37, 17, 0, 1, 14, -23, 4, 16, -23, 6, 12, -31, 30, 6, -18, -25,
- 45, -7, -20, -15, 44, -38, 9, 22, -37, 24, 6, -20, 14, -17, -8, 44,
- -27, -22, 16, 30, -33, -18, 20, 31, -50, 11, 27, -21, -4, -3, 26, -15,
- -24, 15, 20, -27, 16, -12, 9, 5, -24, 3, 26, -27, 5, 15, -19, 9,
- -9, 26, -25, -5, 10, -4, -6, 31, -45, 18, 24, -23, -23, 27, -3, 2,
- -18, 9, 13, -18, 19, -17, 7, -1, -24, 31, 5, -49, 31, 32, -40, -7,
- 10, 14, -12, -12, 5, 21, -30, 25, -12, 4, -18, 9, 11, -13, -20, 37,
- -8, -3, -13, -3, 33, -21, -32, 44, -7, -22, 28, -24, 5, 12, -19, 2,
- 6, 2, -16, 11, 10, -6, -23, 31, -25, 7, 6, -16, 18, 1, -35, 40,
- -9, -18, 12, 4, -2, -25, 20, 19, -16, -35, 46, -14, -8, -3, -1, 24,
- -12, -25, 26, -4, -6, 3, -12, 20, -24, 18, 9, -20, -2, 18, -13, -1,
- -16, 8, 26, -35, 12, 10, -11, 6, 2, -30, 46, -43, 16, 6, 1, -20,
- 26, -18, 8, -13, 9, -3, 3, 1, -25, 29, 13, -50, 12, 41, -47, 15,
- 14, -12, 2, -3, -1, 14, -25, -3, 26, -23, 19, -35, 41, -5, -23, -1,
- 31, -30, 8, -15, 32, -29, -7, 22, 10, -35, 12, 6, -2, 20, -50, 36,
- 7, -17, -4, -1, 7, 2, -21, 19, -12, 1, 28, -25, -5, 9, -3, -12,
- 32, -45, 16, 21, 0, -43, 21, 28, -19, -38, 45, -15, -8, 28, -43, 39,
- -12, -23, 13, 19, -39, 23, -3, 17, -32, 6, 20, -5, -32, 23, 8, -15,
- -1, 11, 9, -28, 5, 20, -18, -6, 9, -18, 50, -50, -8, 49, -30, -5,
- -4, 14, -19, 28, -21, 2, 4, 11, -20, 6, 3, -5, -24, 54, -34, -14,
- 26, -4, -2, -16, 5, 20, -23, 1, 6, -9, 32, -37, 1, 25, -22, -8,
- 31, -6, -37, 31, 0, 3, -37, 24, 25, -27, -20, 27, 1, 4, -26, 13,
- 3, -14, 12, -6, 6, -3, -6, 18, -14, -27, 38, 5, -36, 14, 13, -22,
- 26, -13, -22, 36, -23, -5, 3, 18, -12, -23, 31, -5, -24, 23, -15, 17,
- -7, -23, 20, 6, -4, -19, 20, -8, 15, -32, 13, 17, -30, 17, 13, -19,
- -8, 4, 24, -18, -29, 36, 7, -21, -20, 28, 13, -17, -31, 36, -9, -7,
- 7, 6, -9, -4, 7, -6, 10, -32, 41, -26, 12, -10, -12, 35, -10, -39,
- 36, -9, -7, 7, 6, -9, -4, 11, -14, 5, -7, 9, -13, 24, -27, 4,
- 14, 7, -31, 19, -14, 17, -5, -34, 57, -31, -7, -6, 28, -15, -11, 2,
- 25, -21, -14, 15, 18, -35, 12, 1, 9, -20, -2, 32, -37, 26, -17, 7,
- 1, -10, -18, 54, -37, -16, 23, 11, -13, -23, 34, -5, -16, -10, 25, -28,
- 30, -10, -7, -5, 18, -24, 25, -24, 18, -11, 0, 3, -19, 34, -12, -12,
- 2, 3, -13, 32, -37, 20, 4, -6, -25, 29, -3, -2, -11, -2, 28, -38,
- 18, 7, -5, -7, 0, -4, 21, -36, 30, -19, 25, -29, -15, 48, -11, -43,
- 33, 33, -64, 17, 26, -12, -18, 9, -1, 18, -33, 23, -13, 21, -18, -13,
- 18, -2, -20, 20, 6, -15, 4, -12, 28, -27, 1, 10, -5, 3, 0, -17,
- 15, 17, -30, 2, 5, -8, 17, -11, -2, 9, -20, 23, -27, 23, -10, -3,
- 7, -3, -25, 31, 9, -28, -9, 30, -5, -28, 15, 29, -36, -9, 29, -11,
- -20, 33, -27, 21, -14, -12, 21, -3, -9, -2, 12, -5, -27, 27, 7, -20,
- -11, 32, -9, -15, -1, 9, 20, -42, 12, 9, -4, 3, -6, -3, 6, 0,
- -12, 15, -25, 27, -6, -6, -6, 6, -2, -4, 5, 9, -20, 12, 8, -17,
- -10, 30, -12, -24, 25, -15, 18, -21, 21, -8, -6, -9, 12, -6, 15, -33,
- 26, 8, -32, 13, 21, -12, -28, 20, 11, -6, -28, 27, 11, -21, -10, 22,
- -1, -11, -7, 24, -12, -27, 35, -8, 0, -20, 23, -10, 9, -30, 32, -15,
- 3, -7, 6, -2, 10, -17, 1, 8, -4, -5, -3, 14, -9, 1, -11, 18,
- -13, 15, -33, 22, 14, -32, 11, 9, -1, -17, 14, 0, -3, -16, 29, -21,
- -4, -1, 28, -24, -2, -11, 41, -25, -23, 24, 6, -18, -13, 37, -21, -2,
- -4, 29, -40, 11, 12, 4, -25, 12, -9, 23, -17, -14, 27, -2, -26, 9,
- 18, -14, -1, -15, 29, -18, -4, 5, 12, -26, 18, -3, -7, 3, 13, -10,
- -25, 44, -38, 11, 8, -2, -25, 28, -9, 12, -13, -13, 10, 27, -53, 19,
- 16, -4, -20, 12, 12, -21, 5, 12, 3, -35, 22, 8, 0, -28, 18, 16,
- -25, -3, 9, 8, -3, -19, 8, 24, -34, -4, 38, -16, -30, 29, -1, -2,
- -25, 28, -1, -21, 11, 10, -18, -1, 10, 1, -7, 0, 1, -7, 15, -15,
- -5, 16, 2, -22, 8, 0, -1, 26, -34, -22, 56, -26, -11, 12, 9, -9,
- -9, 4, 7, -8, -1, 8, 0, -21, 10, 19, -8, -25, 17, 10, -18, 3,
- -4, 26, -15, -29, 30, 9, -46, 36, 12, -33, 1, 18, -2, -16, 4, 16,
- -10, -16, 11, 2, 8, -19, 5, 1, 10, -21, 20, -8, -1, -3, 1, 7,
- -19, 7, 11, -12, 5, 5, -26, 29, -11, -5, -2, 12, -13, 9, -22, 23,
- 3, -20, 4, 17, -16, -13, 17, 15, -16, -34, 37, -5, 8, -32, 23, 17,
- -36, -2, 36, -25, -4, 28, -18, -20, 15, 4, 7, -12, -24, 43, -19, 0,
- -11, 25, -9, -12, -7, 10, -1, 11, -2, -12, 13, -27, 30, -9, -15, 8,
- 17, -28, 18, -9, 3, 7, -8, -10, 16, -26, 35, -22, -10, 37, -35, 1,
- 11, 11, -19, -2, 9, 17, -37, 11, 10, 9, -16, -12, 27, -11, -22, 16,
- 24, -48, 25, -1, -3, 4, -20, 13, 39, -72, 34, 1, 2, -6, 4, -1,
- -8, 2, -8, 18, -10, -1, -5, 19, -30, 5, 30, -16, -26, 36, -26, 3,
- 21, -27, 10, 4, -10, 0, -4, 15, 9, -41, 32, -11, 2, -11, 15, -3,
- -7, -8, 16, -3, -21, 23, -2, -9, -4, -2, 20, -5, -37, 49, -20, -6,
- -9, 17, 17, -36, -8, 40, -24, -5, 3, 8, 5, -12, -6, 15, 2, -27,
- 28, -4, -23, 16, 5, -1, -26, 29, 11, -38, 22, -12, -8, 38, -34, -3,
- 10, 4, -2, -5, -8, 24, -16, -20, 21, 1, -7, 11, -7, -4, -15, 15,
- 15, -21, -6, 10, -1, 17, -45, 23, 29, -42, 2, 18, -5, -6, -1, 22,
- -20, -19, 16, 21, -20, -18, 23, 2, 5, -41, 36, 10, -34, 12, 12, -25,
- 11, 1, 6, -6, -11, 20, -11, 10, -11, -12, 13, 8, -21, 5, -1, 14,
- 3, -26, 5, 27, -39, 18, 7, -27, 34, -20, 13, -20, 7, -4, 25, -23,
- -16, 7, 47, -35, -29, 37, 10, -35, 4, 12, -1, 0, -15, 25, -23, -12,
- 35, 7, -51, 28, -1, 16, -33, 5, 27, -21, 2, -5, 13, -3, 0, -20,
- 27, -30, 8, 16, -4, -13, 14, -15, 19, -12, -6, 8, -9, 19, -27, 4,
- 20, -9, -12, 21, -37, 41, -22, 1, 1, 13, -33, 20, 14, -30, -2, 22,
- 21, -51, 3, 38, -7, -35, 17, 6, 11, -43, 33, 9, -36, 10, 31, -24,
- -13, 16, -6, 24, -36, -1, 16, 19, -45, 20, 11, 2, -30, 31, -21, -14,
- 29, -4, -12, 3, -6, 9, 15, -37, 20, -4, 8, -18, 12, -7, 17, -8,
- -12, -9, 23, 8, -28, 1, 29, -19, -18, 27, -2, -8, -28, 44, -4, -36,
- 15, 33, -30, -13, 13, 14, -20, -7, 25, -11, -5, -8, 21, -1, -8, -37,
- 50, 1, -53, 27, 28, -21, -10, 4, 16, -24, 10, 6, -12, 0, 2, 6,
- 1, -13, 2, 21, -26, 3, 13, -19, 10, 9, -18, -3, 22, -18, -1, -2,
- 14, -1, -23, 21, -6, -2, -9, 20, 5, -35, 1, 34, -21, -16, 22, 1,
- -8, -5, 1, 18, -12, -23, 18, 5, -17, -7, 37, -6, -35, 6, 47, -44,
- -7, 20, 5, -10, -23, 35, -6, -12, -12, 39, -27, -10, 9, 21, -21, -6,
- 2, 5, 1, 6, -28, 17, 20, -31, -3, 15, 7, -26, 31, -40, 43, -32,
- 23, -19, 11, -22, 26, -6, -1, -25, 33, 2, -25, -7, 9, 26, -16, -30,
- 29, 20, -47, 13, 16, -9, -19, 18, 23, -32, -17, 32, 21, -38, -13, 14,
- 43, -66, 19, 23, 5, -50, 47, -20, 2, -11, 22, -5, -6, -21, 4, 38,
- -15, -32, 12, 35, -35, -4, 7, 18, -17, -1, -7, 6, 5, 0, 0, -7,
- 0, -8, 21, -10, 5, -28, 30, 3, -17, -29, 57, -16, -17, -10, 28, -9,
- -20, 26, -12, 3, -20, 27, -3, -7, -42, 65, -9, -45, -3, 63, -33, -11,
- -6, 28, -17, -1, -6, 6, 7, -12, 0, 25, -21, -30, 54, -9, -37, 1,
- 28, 7, -42, 18, 11, 17, -46, 24, -9, 27, -38, 22, -20, 23, -21, 11,
- -6, 42, -71, 20, 32, -11, -43, 44, -3, -4, -27, 12, 24, -8, -18, -8,
- 30, -19, -23, 44, -8, -30, 0, 45, -39, 0, -1, 28, -16, -17, -15, 44,
- -13, -11, -13, 36, -24, -11, 12, 17, -30, 8, 17, -10, -18, 9, 22, -18,
- -15, 3, 25, -25, 11, -6, 5, 7, -18, -3, 15, -1, -17, 8, 28, -32,
- -17, 36, 8, -41, 12, 7, 13, -22, -14, 18, 41, -57, -1, 25, 10, -40,
- 18, 11, -8, -23, 25, -16, 37, -45, 17, 10, 2, -60, 64, -15, -3, -16,
- 22, -9, 9, -27, 30, -7, -21, 3, 20, -10, 6, -12, 15, -19, 14, -19,
- 3, 22, -8, -29, 37, -28, 29, -26, 11, -15, 15, -17, 21, -26, 18, 5,
- -5, -11, 2, 16, -10, -10, -5, 29, -30, 4, 3, 18, -21, 4, 1, 8,
- -13, -10, 1, 40, -35, -26, 44, 5, -38, 8, 30, -24, 0, -1, 0, 12,
- -18, -1, 18, -8, -28, 39, -18, 24, -35, 24, -36, 46, -41, 12, -3, 24,
- -37, 31, -28, 32, -16, 2, -27, 39, -34, 7, 24, -19, -6, 14, -10, -1,
- 14, -16, -4, 25, -26, -4, 8, 22, -40, 33, -30, 22, -15, 36, -63, 39,
- 1, 10, -54, 36, 9, 5, -51, 49, -13, 5, -7, -7, 15, -9, -10, 2,
- 12, -18, 6, 3, 18, -29, 9, 10, -10, 1, -20, 20, -3, -1, -13, 21,
- -26, 41, -36, 2, 23, -23, -10, 39, -41, 17, -10, 8, 7, -13, 23, -54,
- 66, -26, -50, 54, 17, -66, 59, -46, 30, -10, 6, -8, -18, 19, 16, -32,
- 12, 6, -2, 3, -36, 33, -6, -7, 12, -16, 6, 14, -21, 14, 16, -58,
- 37, 3, 0, -35, 44, -16, 17, -38, 28, -14, 25, -45, 28, -21, 32, -31,
- 11, 17, -24, 11, 5, -24, 18, -6, -3, 0, -3, 21, -33, 24, 20, -78,
- 66, -8, -24, 3, 17, -14, 24, -41, 34, -25, 27, -32, 17, -5, 13, -26,
- 28, -29, 22, -8, -16, 33, -30, 2, 25, -27, 1, 31, -36, -7, 31, -8,
- -12, -5, 17, -7, 5, -26, 32, 1, -18, -16, 27, -7, -10, 2, 21, -42,
- 30, -3, -19, 33, -40, 19, 6, -13, -5, 17, -10, 28, -63, 40, 6, -10,
- -9, 7, -3, 12, -20, -1, 17, -1, -6, -14, 18, 1, -19, 12, 5, -9,
- -2, -14, 33, -3, -44, 51, -17, -6, -16, 36, -35, 29, -31, 31, -24, 15,
- -23, 33, -35, 20, -4, -1, -19, 27, -1, -29, 25, 1, -20, 25, -23, -13,
- 62, -50, -18, 43, -20, 1, -4, 16, -18, 4, -16, 36, -42, 42, -42, 38,
- -28, 9, -10, 31, -40, 30, -39, 30, 8, -28, 11, 9, -7, -6, -8, 10,
- 22, -36, -5, 26, 4, -41, 30, 12, -11, -10, -14, 37, -29, 3, -6, 9,
- -5, 15, -30, 40, -26, 12, -25, 25, -21, -12, 46, -17, -39, 47, 7, -57,
- 45, -14, 1, -13, 21, -21, 14, -7, 7, -11, 18, -34, 25, 7, -28, 22,
- 1, -12, 11, -24, 4, 38, -44, 17, 2, -12, 19, -17, 0, 9, 17, -55,
- 29, 3, 3, -27, 48, -38, 16, -17, 24, -19, 26, -49, 29, 9, -18, -25,
- 50, 2, -31, -20, 43, -3, -35, 23, 13, -34, 9, 20, -15, -8, 29, -37,
- 29, -21, 4, -8, 36, -52, 29, -8, 6, -18, 35, -34, 22, -21, 10, 5,
- -11, -13, 35, -26, -3, 12, -17, 13, 1, -12, -4, 24, -18, -6, 18, -7,
- -13, 17, -4, -30, 48, -41, 10, 34, -39, -22, 73, -48, -12, 12, 22, -14,
- -31, 18, 29, -17, -21, 22, -3, -8, -12, 25, -11, 13, -41, 36, -3, -2,
- -27, 37, -6, -36, 17, 18, -7, -10, 4, -5, 10, -21, 13, 15, -21, 2,
- -1, -5, 8, -1, -16, 29, -24, 14, -18, 26, -24, 17, -26, 21, -18, 24,
- -49, 82, -52, -11, 36, -22, -17, 30, -21, 1, 1, -1, 8, -2, -7, 2,
- 17, -9, -36, 37, -5, -15, -4, 27, -20, 11, -31, 46, -18, -13, -11, 58,
- -67, 19, -4, 40, -43, 9, -14, 41, -32, -16, 46, -19, -13, 5, -5, 6,
- 2, -16, 10, -9, 18, -13, 3, 24, -37, 11, 1, 0, -8, -9, 28, -1,
- -41, 40, -10, 6, -13, 1, -11, 30, -28, -10, 30, 1, -36, 17, 28, -54,
- 51, -24, 1, -6, 6, -12, 33, -48, 23, 18, -17, -23, 27, 11, -23, -13,
- 27, -7, -1, -24, 35, 3, -48, 35, 8, -20, -3, 3, 16, -11, 8, -35,
- 32, 7, -27, -22, 81, -85, 36, -7, 16, -16, 2, 0, 13, -28, 12, -16,
- 24, 6, -25, -14, 47, -15, -25, 3, 37, -41, -5, 32, -25, 11, 6, -16,
- 25, -34, 14, 8, 13, -52, 30, 6, 13, -56, 56, -27, 13, -11, -6, 16,
- -12, -1, 18, -40, 18, 19, -13, -11, 7, -2, 9, 10, -39, 9, 46, -48,
- -18, 59, -32, -3, 14, -10, 10, -13, 10, -13, 14, -11, -10, 5, 31, -43,
- 10, 23, -16, 3, -29, 50, -23, -19, 16, 15, -19, 3, -20, 39, -19, -14,
- -6, 54, -44, -12, 18, 30, -56, 28, -15, 22, -16, -15, 31, -8, -9, -1,
- 1, 1, 2, -8, 9, 10, -43, 41, -9, 8, -48, 62, -30, -9, 13, 6,
- -24, 32, -31, 8, -4, 16, -27, 27, -19, -1, -6, 37, -40, 14, -3, 0,
- 25, -59, 34, 18, -18, -21, 17, 13, -11, -8, -11, 43, -40, 1, 6, 24,
- -37, 10, 14, -4, -12, -2, 17, 11, -40, 10, 16, 17, -51, 24, 14, -4,
- -31, 22, 18, -32, 15, -24, 46, -38, 9, 2, -2, 14, -15, -12, 15, 3,
- -28, 29, -7, -6, 13, -7, -6, 2, 3, -17, 28, -28, -9, 37, -17, 0,
- 3, 10, -19, -5, 19, -17, 12, -25, 30, -19, 8, -27, 49, -15, -27, 9,
- 10, 7, -31, 6, 30, -12, -45, 41, 24, -42, -1, 28, -2, -38, 29, -18,
- 23, -4, -43, 35, 26, -54, 23, 7, 6, -30, 17, -14, 32, -40, 24, -13,
- 17, -15, -11, 16, 16, -20, -26, 47, -10, -26, -6, 41, -19, -22, 36, -41,
- 33, 5, -32, 12, 28, -51, 19, 27, -40, 7, 35, -34, 9, -22, 42, -20,
- -15, -3, 43, -55, 15, 23, -10, -11, 3, 14, -32, 31, -26, 21, 7, -44,
- 15, 40, -22, -41, 54, -17, -17, 8, -6, 10, 11, -17, -6, 15, -2, -20,
- 31, -19, 4, -17, 22, 0, 2, -36, 39, 0, -31, 23, -38, 59, -15, -29,
- -13, 69, -50, -22, 43, -11, -16, 0, 16, -9, -10, 13, 5, -8, -18, 27,
- -8, -2, -12, 13, -1, -16, 16, -18, 27, -11, -19, 39, -28, -26, 28, 36,
- -85, 72, -40, 24, -10, 0, -9, 30, -29, -11, 22, -13, -7, 23, -10, -14,
- 6, 13, -15, 22, -31, 12, 0, 0, -3, -15, 19, 14, -21, -22, 27, 35,
- -72, 36, -3, 18, -54, 50, -29, 38, -47, 14, 19, -11, -25, 27, 9, -23,
- -2, 2, 16, -6, -24, 22, 10, -27, 7, 16, -30, 11, 24, -40, 31, -28,
- 29, 1, -28, 7, 17, 3, -45, 40, -11, -7, 4, 19, -45, 24, 24, -50,
- 48, -35, 11, 9, -12, -14, 30, -23, 8, 7, -15, -7, 53, -59, 13, 5,
- 15, -46, 49, -48, 57, -36, -20, 34, 1, -10, -15, 15, 20, -36, -9, 35,
- 6, -39, 7, 14, 27, -81, 70, -21, 5, -22, 21, -6, 1, -13, 19, -19,
- 4, -10, 35, -43, 31, -3, -7, -15, 40, -56, 33, -1, -33, 51, -35, -2,
- 24, -18, 5, 0, 4, -16, 10, -6, 9, -28, 37, -38, 45, -35, 0, 37,
- -38, 7, 19, -32, 3, 17, -2, -23, 19, 15, -23, 5, -2, 13, 1, -37,
- 8, 59, -80, 26, 13, 15, -31, -8, 30, -7, -7, -19, 22, -2, -9, -2,
- 12, -7, 3, 1, -25, 47, -53, 35, -5, -27, 21, 15, -25, 13, -24, 42,
- -41, 19, 2, -13, 1, 23, -40, 37, -45, 46, -8, -41, 44, -11, -17, 23,
- -9, -20, 22, -3, -15, 22, -23, 19, -7, 2, -34, 65, -56, 7, 28, -8,
- -37, 37, 3, -8, -34, 39, -11, 9, -29, 6, 35, -14, -49, 48, 5, -25,
- 5, -25, 66, -47, -9, 28, -7, -12, 0, 17, -20, -2, 21, -12, -23, 54,
- -50, 20, 7, -20, 7, -2, 3, 4, -26, 26, -6, -14, 15, -3, -10, 12,
- -10, -4, 23, -33, 14, -12, 38, -55, 36, 0, -6, -5, 0, -4, 7, 0,
- -14, 2, 8, -11, 13, 5, -33, 41, 4, -62, 40, 8, -6, -8, -31, 52,
- -4, -44, 25, 20, -18, -24, 32, -11, -9, -4, 30, -37, 34, -31, 7, 30,
- -29, -14, 28, -10, -9, 6, 0, -5, 14, -9, -3, -2, 10, -22, 29, -22,
- -2, 6, -5, 16, -25, 6, 27, -19, -9, -11, 29, -13, -5, -6, 16, 5,
- -20, -1, 30, -20, -8, 7, -8, -2, 3, 14, -9, -24, 35, -7, -14, -12,
- 32, -5, -18, -15, 35, -7, -13, -1, -4, 27, -20, -30, 58, -15, -29, 9,
- 15, -16, -3, 1, 4, 5, -4, -11, 17, 3, -29, 28, -10, -18, 20, -7,
- -2, 4, 2, -17, 22, -3, -31, 23, 23, -32, -14, 34, -3, -14, -13, 11,
- 21, -26, -16, 36, -7, -13, 15, -8, -3, -1, -11, 15, -8, -4, -4, 24,
- -21, 1, 11, 3, -22, 5, 15, -24, 0, 37, -31, 7, -18, 15, 16, -15,
- -19, 26, 0, -10, -26, 31, 6, -19, -6, 21, -19, 20, -13, -3, 13, -2,
- -32, 24, 2, -8, -10, 36, -29, -10, 19, 10, -25, 5, -9, 31, -23, -21,
- 21, 26, -25, -9, -5, 35, -17, -34, 17, 42, -44, -11, 30, 11, -40, 18,
- 8, -6, -11, 11, -26, 39, -18, -23, 37, -12, -32, 45, -8, -22, 5, 16,
- -15, -10, 6, 17, -15, -3, 9, -22, 41, -22, -25, 29, 5, -30, 6, 12,
- 17, -32, 7, 20, -26, 9, 9, -10, 7, -17, 10, 11, -16, -7, 12, 5,
- -4, -26, 25, 24, -46, -4, 50, -39, -11, 8, 35, -36, 2, -9, 33, -7,
- -22, -26, 76, -37, -41, 33, 28, -43, 14, 6, 2, -8, 2, -20, 34, -19,
- -2, -4, 15, -6, -23, 28, -3, -32, 33, -16, 7, -11, 14, 9, -10, -30,
- 35, -25, 17, -14, 1, 14, 12, -38, 16, 15, -7, -30, 15, 18, -24, -6,
- 47, -38, 6, 7, -9, -2, -3, 1, 12, -8, -23, 20, 35, -47, -14, 51,
- -9, -48, 19, 20, 0, -25, -2, 20, 16, -29, -25, 60, -17, -23, -8, 31,
- -4, -30, 12, 20, -14, -4, -1, 17, -11, -9, 7, 7, -17, 1, -12, 25,
- -5, -20, 15, 19, -29, 2, 5, 11, -19, -18, 31, 1, -27, 18, -17, 51,
- -53, -2, 29, 4, -37, 17, 11, -11, -23, 41, -17, -10, 13, -4, -8, 18,
- -27, 17, 1, -19, -7, 51, -37, -28, 53, 4, -47, 5, 18, 17, -32, -8,
- 14, 36, -46, 3, 11, 11, -24, 4, 0, 16, -7, -26, 25, 20, -44, 7,
- 20, -12, 2, -14, 4, 33, -38, 1, 8, 20, -34, -12, 61, -46, -19, 44,
- -10, -4, -18, 12, 12, -8, -26, 16, 22, 2, -51, 18, 53, -56, -5, 30,
- -9, -22, 32, -11, -18, 18, 13, -25, -7, 8, 9, 3, -20, 1, 32, -27,
- -9, 5, 19, -20, -13, 18, 8, 3, -35, 22, 31, -47, -2, 16, -8, 15,
- -10, -22, 54, -20, -23, -6, 51, -52, -13, 48, -23, -11, 28, -30, 38, -6,
- -50, 28, 33, -58, 2, 34, 16, -53, -1, 55, -13, -42, 15, 23, -7, -33,
- 13, 21, -14, -6, 2, -2, 27, -43, 27, 11, -19, -16, 26, -16, -4, 16,
- -17, 1, 20, -17, 8, -17, 6, 26, -25, -24, 40, -13, 6, -14, -14, 29,
- 3, -32, -5, 46, -21, -28, 38, -30, 6, 28, -47, 3, 65, -67, -5, 61,
- -34, -27, 31, 12, -30, -7, 11, 19, 0, -43, 18, 47, -52, -20, 52, -14,
- -9, -10, -5, 55, -45, -29, 55, 16, -83, 28, 36, -23, 6, -8, -13, 37,
- -17, -30, 32, -9, -6, 10, -19, 16, 4, 9, -35, 22, -1, -17, 3, 8,
- 10, -10, -21, 40, -27, -5, 16, -6, -27, 47, -23, -26, 48, -18, -19, 14,
- -1, -9, 5, 1, -20, 58, -57, -14, 55, -16, -40, 37, -6, 11, -19, -22,
- 43, 2, -55, 27, 37, -38, -29, 58, -6, -11, -22, 4, 26, -7, -67, 67,
- 21, -56, 19, 15, -5, 0, 2, -41, 37, 10, -65, 49, 8, 1, -19, 1,
- 9, 8, -20, -9, 22, -14, -3, 4, -1, 13, -6, -11, 15, -8, -15, 13,
- 16, -38, 14, 24, -39, 20, 9, -17, 14, -15, 7, 3, -12, -3, 30, -25,
- -24, 43, -1, -40, 18, 17, 0, -22, -14, 31, 20, -68, 35, 32, -43, -9,
- 35, -16, 4, 2, -35, 35, 27, -81, 40, 31, -21, -30, 29, -12, 13, 10,
- -42, 26, 17, -33, -1, 16, 12, -29, 6, 4, 21, -27, -9, 39, -6, -54,
- 40, -14, 15, -4, -17, 20, 4, -18, -4, 23, -24, -3, 30, -41, 15, 17,
- -4, -29, 19, 4, -9, -10, 12, 17, -21, -7, 26, -19, -17, 17, 3, 1,
- -3, -30, 47, 16, -62, -4, 68, -29, -54, 43, -1, -4, 20, -42, 22, 34,
- -32, -43, 63, -12, -26, 8, -6, 10, 22, -66, 55, 25, -65, 15, 9, 21,
- -22, -28, 36, 5, -16, -51, 102, -49, -12, 6, 21, -12, -23, 24, -15, 11,
- -14, -8, 31, 4, -53, 64, -35, 13, -28, 23, -23, 22, -16, 13, -22, 23,
- 27, -51, -8, 41, 6, -66, 36, 13, 4, -26, 7, 11, 9, -34, 0, 35,
- -21, -15, 10, 34, -57, 60, -69, 60, -22, 1, -27, 27, 14, -27, 1, -13,
- 35, -2, -51, 36, 35, -49, 5, -1, 31, -42, 25, -26, 34, -7, -60, 98,
- -46, -22, -1, 49, -45, -2, 10, 26, -33, 25, -36, 37, -19, 4, -3, -7,
- 9, 7, -8, -29, 48, -23, 0, -33, 45, 0, -23, -16, 47, -7, -31, -9,
- 38, -2, -36, 18, -8, 43, -55, 16, -1, 41, -72, 54, -35, 24, 4, -46,
- 47, -11, 6, -40, 24, 10, 8, -38, 16, 16, 24, -98, 80, 2, -28, -28,
- 44, 11, -47, 31, -7, 35, -42, -25, 41, 12, -64, 34, 14, -2, -21, 24,
- -14, 11, -3, -24, 22, -28, 46, -51, 38, -22, 35, -40, 2, 11, 22, -48,
- 23, -9, 34, -35, -24, 52, -7, -37, 9, 36, -21, 0, -32, 61, -44, 6,
- -1, -16, 41, -28, 19, -37, 49, -11, -38, -8, 65, -53, 9, -21, 59, -37,
- 8, -33, 59, -13, -80, 67, 19, -39, -28, 70, -21, -25, -3, 23, 17, -29,
- -44, 83, -41, 0, -23, 53, -27, -12, 21, -19, 21, -21, 13, -4, -12, -5,
- 38, -58, 34, 10, -22, -16, 47, -8, -39, 19, 12, 4, -46, 39, -24, 48,
- -69, 45, -18, 10, -5, -2, -4, 10, -5, 7, -17, -3, 20, 0, -40, 26,
- 40, -64, 11, 34, 1, -49, 11, 35, -22, -14, -32, 98, -47, -37, 9, 76,
- -70, -8, 7, 63, -92, 56, -49, 77, -64, 2, 41, -28, -25, 37, 0, -26,
- 35, -40, 16, 3, 14, -46, 22, 18, -6, -9, -11, 22, 26, -44, -46, 94,
- -60, 18, -37, 69, -33, 5, -20, 42, -32, -20, 24, -1, -10, -12, 39, -31,
- 13, 1, 9, -47, 42, -26, 39, -73, 48, 48, -73, -13, 56, 14, -78, 38,
- 11, 12, -50, 8, 39, 3, -79, 73, 2, -25, -17, 23, 27, -58, 26, -37,
- 67, -49, 11, -12, 62, -82, 64, -41, 3, 26, -17, -45, 55, -4, -22, 10,
- -2, 38, -54, 8, 5, 47, -79, 7, 54, -7, -64, 41, 49, -73, 29, -24,
- 54, -51, -4, 14, 33, -84, 82, -46, 17, -25, 57, -44, -2, 11, 8, 15,
- -66, 46, 19, -25, -44, 58, 10, -38, -23, 77, -48, -3, -12, 24, 24, -70,
- 37, 21, -15, -48, 81, -66, 44, -29, 6, 4, 9, -30, 31, -24, 5, 19,
- -51, 34, 21, 11, -92, 78, 19, -44, -54, 104, -47, -8, -19, 29, 45, -78,
- 6, 55, -11, -75, 66, -10, 8, -38, 24, 10, 4, -57, 66, -20, -25, 20,
- 6, 9, -71, 100, -60, -6, 8, 28, -37, 29, -42, 78, -58, -22, 42, 10,
- -69, 34, 33, -36, 29, -54, 81, -54, 0, 7, 1, -19, 22, -14, 4, -3,
- 32, -13, -59, 86, -54, 4, 0, 21, -35, 43, -68, 91, -31, -53, 38, 48,
- -72, -15, 50, 3, -11, -72, 96, -1, -49, -23, 81, -21, -57, 15, 63, -67,
- 5, 25, -27, 34, -48, 49, -26, 12, -33, 66, -73, 14, 35, -20, -27, 45,
- -24, 12, -12, 0, 24, -50, 33, -26, 45, -65, 47, -7, -4, -9, 19, -19,
- -2, 15, -17, 30, -39, 25, 2, -3, -57, 109, -86, 10, 14, 31, -53, 7,
- 32, 5, -44, -20, 84, -35, -34, -6, 99, -97, 1, 23, 40, -65, 15, 9,
- 36, -45, -22, 55, 4, -55, -3, 73, -80, 63, -49, 28, 2, -10, -19, 24,
- -13, 8, 1, -15, 5, 22, -4, -57, 72, -41, 16, -45, 76, -57, 30, -26,
- 38, -16, -34, 32, 12, -53, 22, 47, -46, -4, 6, 45, -65, 32, -21, 45,
- -44, -22, 69, -44, -16, 29, 19, -59, 40, -7, 42, -77, 39, -4, 29, -74,
- 27, 38, -12, -60, 69, 7, -32, 1, -9, 50, -56, -15, 19, 47, -75, 44,
- 5, -22, 27, -7, -22, 0, 23, -30, 1, 4, 33, -44, 29, -24, 57, -67,
- 17, 18, 4, -59, 32, 48, -72, 28, -2, 13, -10, -21, 16, 58, -117, 85,
- -14, -5, -34, 21, 29, -27, -20, 31, 23, -49, 16, -14, 51, -74, 24, 38,
- -38, -16, 56, -33, -7, 3, 0, 36, -80, 49, 23, -19, -48, 76, -61, 43,
- -41, 27, -11, 23, -30, 8, 3, 15, -14, -22, 16, 3, 15, -39, 11, 38,
- -13, -70, 88, -41, 2, 4, -30, 80, -84, 15, 37, -6, -61, 58, -19, 27,
- -72, 64, -6, -16, -30, 59, -21, -21, -12, 44, 22, -101, 78, -10, -16, -11,
- 20, -21, 31, -36, 37, -18, -20, 46, -24, -23, 10, 21, -36, 32, -38, 68,
- -50, 12, -6, 19, -33, 14, -16, 20, -11, -14, 47, -59, 56, -14, -27, 5,
- 29, -43, 49, -96, 106, -35, -41, 28, 35, -30, -29, 37, 12, -11, -58, 79,
- -31, -16, -11, 43, -13, -25, 3, 71, -76, -13, 64, -39, 3, -45, 66, -13,
- -1, -45, 80, -40, 6, -29, 26, -12, 6, -19, 21, -4, 9, 0, -37, 44,
- -28, 11, -22, 19, 7, 1, -45, 60, -13, -42, 32, -16, 31, -50, 35, 10,
- -22, -23, 60, -62, 21, -2, 39, -49, -4, 24, 30, -53, -23, 66, -33, 2,
- -34, 69, -33, -10, 7, 24, -51, 28, 0, 9, -24, -3, 38, -24, -16, -9,
- 68, -81, 38, -16, 35, -34, -4, 16, 20, -43, 10, 7, -3, 14, -30, 38,
- -39, 38, -20, -12, -20, 78, -79, 22, -4, 44, -48, -6, 37, -2, -25, -24,
- 60, -41, 15, -30, 50, -43, 7, 9, 27, -64, 45, 5, -15, -17, 1, 49,
- -56, 3, -11, 69, -78, 37, -5, 38, -60, 26, -2, 9, -51, 53, -20, -3,
- 9, -1, 38, -74, 40, 6, -13, -54, 69, -24, 6, -22, 31, 0, -17, 12,
- -13, 8, -9, 20, -53, 56, -27, 29, -63, 41, 8, 11, -73, 59, 15, -25,
- -21, -1, 61, -69, 10, 17, 28, -59, 34, -14, 32, -54, 17, 22, -11, -47,
- 63, 7, -56, 46, -28, 50, -96, 60, 2, 0, -37, 36, -11, 15, -38, 41,
- -19, -31, 46, -12, -25, 9, 49, -67, 47, -48, 51, -30, -15, 23, 19, -43,
- 8, 17, 4, -11, -29, 54, -48, 38, -28, 10, -9, 38, -48, 27, -47, 55,
- 3, -59, 22, 41, -5, -59, 38, 5, 31, -101, 72, 11, -36, -18, 54, -25,
- -1, -30, 54, -28, -34, 61, -27, 13, -46, 55, -21, -10, -21, 52, -34, -8,
- 30, -21, 20, -11, -21, 22, -2, -46, 79, -84, 60, -9, 13, -57, 51, 2,
- -16, -38, 34, 15, -23, -7, -6, 53, -38, -22, 29, 23, -63, 65, -34, -21,
- 34, -7, -19, -8, 24, 13, -8, -63, 110, -56, -8, -37, 79, -56, -3, -3,
- 62, -57, 19, 9, 8, -20, -29, 27, 13, -28, -19, 79, -80, 58, -31, 24,
- -16, -35, 46, 0, -52, 36, 21, -29, 16, -23, 26, -29, 38, -42, 26, -41,
- 60, -29, -16, -4, 42, 7, -85, 53, 47, -54, -29, 67, -53, 39, -58, 45,
- -5, 5, -37, 61, -56, 27, 17, -40, 1, 15, 17, -43, 19, 4, 30, -49,
- 12, -1, 49, -64, -27, 96, -41, -47, 45, 8, -38, 35, -50, 74, -81, 54,
- -14, 24, -64, 57, -5, -25, -19, 27, 16, -27, 4, 16, 2, -25, 26, -31,
- 22, -35, 56, -54, 0, 55, -23, -29, 9, 38, -38, 12, -41, 74, -28, -29,
- -3, 61, -71, 36, -32, 43, -19, -14, 21, 0, -10, -19, 32, -42, 20, 11,
- 23, -94, 107, -13, -53, 5, 35, -17, -11, -25, 32, 40, -76, 29, 32, -9,
- -65, 80, -42, 6, -22, 42, -27, -2, 10, -2, 13, -41, 32, 10, -17, -26,
- 53, -50, 40, -42, 30, -19, 41, -50, 33, -20, -1, 40, -67, 8, 29, 15,
- -58, 25, 32, 15, -81, 46, 14, -8, -51, 24, 40, -44, 17, 10, 2, -26,
- 47, -68, 49, -49, 50, -27, -3, -20, 84, -62, -32, 52, 12, -52, 0, 42,
- -30, 24, -47, 45, -16, 11, -51, 74, -47, -9, 45, -19, -18, -5, 41, -39,
- 11, -33, 56, -20, -14, -8, 64, -85, 60, -23, -13, -3, 33, -20, -25, 57,
- -34, 2, -23, 42, -21, 3, -49, 85, -35, -27, 1, 54, -34, -31, 24, 15,
- 6, -45, 54, -30, 12, -27, 40, -61, 39, 1, -5, -18, 17, 14, 7, -33,
- -27, 83, -44, -40, 21, 66, -82, 32, -7, 33, -54, 27, 3, 2, -13, -15,
- 52, -57, 14, 14, -6, -27, 54, -45, 23, -11, 16, -27, 27, -33, -3, 36,
- -46, 47, -15, -8, -7, 67, -93, 12, 34, 17, -73, 32, 15, 29, -44, -17,
- 47, 2, -40, -31, 81, -43, 3, -24, 52, -32, 4, 1, 20, -48, 20, 40,
- -68, 23, 14, 19, -64, 46, -8, 17, -48, 55, -29, 23, -59, 48, -2, -27,
- 11, 1, 21, -30, 25, -24, 29, -41, 21, 0, -15, -17, 64, -47, 1, 31,
- -22, 2, -11, 22, -56, 69, -53, 32, -30, 31, -16, 32, -68, 29, 42, -39,
- -49, 80, 17, -74, 17, 0, 55, -88, 25, 29, 14, -72, 56, 0, 0, -33,
- 20, 5, -34, 35, -33, 45, -37, 23, -9, 10, -54, 67, -22, -13, -15, 41,
- -14, -16, 8, 0, 19, -51, 56, -51, 39, -20, 19, -34, 26, -18, 19, -31,
- 23, 0, 12, -31, 7, 45, -65, 22, 4, 24, -73, 74, -13, -34, 18, 23,
- -16, -25, -2, 40, 5, -84, 76, -4, 6, -74, 75, -7, -10, -51, 60, -13,
- 0, -45, 50, 18, -57, 20, 21, -7, -26, 47, -51, 28, -19, 12, -13, 3,
- -1, 20, -23, 1, 28, -18, 3, -41, 67, -72, 34, -11, 33, -47, 47, -9,
- -20, -2, 28, -21, -27, 11, 26, -15, -25, 57, -44, 46, -67, 49, -5, -30,
- 1, 42, -36, -9, 22, 7, -13, -34, 67, -29, -16, -26, 84, -49, -21, -11,
- 77, -53, -43, 62, 0, -3, -32, 23, 13, -5, -69, 88, -42, 7, -17, 37,
- -35, 27, -6, -13, -11, 31, -17, -28, 45, -17, 8, -32, 41, -48, 39, -35,
- 41, -16, -28, 41, -3, -13, -26, 23, 12, -22, -50, 104, -57, 9, -28, 67,
- -53, -7, 0, 45, -41, -22, 50, -8, -21, -9, 38, -19, -18, -2, 55, -76,
- 38, -12, 39, -49, -14, 64, -24, -45, 25, 50, -66, 23, -15, 32, -36, 32,
- -46, 44, -14, 2, -16, 22, -7, -11, 14, -28, 21, 4, -10, -18, 63, -66,
- 30, -20, 36, -35, -16, 26, 12, -37, 6, 50, -35, -15, 6, 48, -64, 4,
- 12, 46, -85, 33, 12, 25, -49, -11, 77, -53, -18, 19, 29, -41, -1, 3,
- 39, -70, 55, -6, -1, -23, 38, -22, -12, 1, -11, 36, -39, 5, 15, 33,
- -55, 32, -8, 6, -37, 39, -32, 4, 27, -23, 11, -1, 10, -28, 19, -24,
- 52, -69, 27, 21, 11, -72, 52, 17, -35, -13, 16, 33, -44, 4, 19, 18,
- -60, 13, 35, 12, -93, 82, 9, -35, -20, 26, 40, -74, 14, 18, 28, -66,
- 37, 4, 9, -43, 34, -15, 17, -35, 38, -11, -14, 14, -5, 2, -36, 54,
- -35, 2, 1, 29, -35, 9, -4, 24, -32, -5, 31, -19, -17, 28, 34, -86,
- 49, 13, -16, -52, 71, -29, 3, -30, 51, -1, -36, 6, 25, 4, -75, 56,
- 10, -21, -18, 37, -16, 17, -53, 60, -7, -38, -9, 63, -18, -70, 67, 1,
- -19, -32, 50, -20, 11, -23, 24, -10, -3, -21, 32, -26, 7, 12, -19, 35,
- -29, 26, -41, 32, -22, 14, -43, 41, 7, -16, -24, 57, -20, -35, 25, 7,
- -11, -20, 31, -18, 10, -34, 44, -7, -22, -9, 49, -33, -18, 26, -4, 12,
- -63, 51, 11, -16, -40, 80, -28, -37, 5, 61, -78, 22, 16, -3, -10, -5,
- 26, -8, -2, -43, 68, -42, -24, 39, 11, -31, 15, -9, 18, -20, -1, 7,
- -17, 26, -30, 31, -31, 42, -28, -1, -15, 49, -51, -2, 26, 3, -12, -11,
- 7, 22, -9, -51, 70, -27, -14, -13, 53, -37, -12, 9, 44, -57, -14, 51,
- -6, -27, -10, 60, -55, 2, 14, 18, -45, 32, -19, 29, -27, -12, 31, 14,
- -54, 17, 41, -62, 51, -40, 40, -40, 12, -8, 28, -39, 16, 10, 10, -46,
- 37, 12, -42, 17, -4, 2, -17, 35, -34, 38, -30, 21, -6, -36, 36, 13,
- -56, 14, 53, -36, -13, -1, 61, -64, 7, -3, 54, -63, 5, 14, 34, -67,
- 10, 46, -27, -18, 26, 20, -41, 14, -13, 40, -66, 20, 38, -34, -11, 39,
- -16, 11, -26, 7, 28, -58, 26, 0, 30, -61, 44, 11, -30, -17, 66, -40,
- -33, 35, 6, -21, -2, 9, 16, -13, -39, 79, -71, 27, 9, -9, -29, 28,
- 4, -17, 1, 14, 2, -20, -2, 16, 24, -67, 20, 37, -4, -80, 75, 18,
- -46, 2, 10, 25, -31, -28, 43, 19, -75, 59, -13, 14, -40, 29, 7, -22,
- -20, 44, -20, -16, 10, 32, -21, -42, 61, -19, -29, 12, 39, -55, 32, -4,
- 0, -2, -24, 40, -19, -38, 34, 22, -33, 11, -3, 31, -49, 21, -16, 40,
- -54, 12, 29, -19, -8, 17, 17, -52, 28, 22, -39, -2, 45, -42, 23, -46,
- 51, 11, -68, 26, 55, -34, -44, 45, 9, -19, -43, 57, -16, -5, -9, 40,
- -24, -12, 8, 29, -54, -4, 50, -37, 0, 11, 7, -4, 0, -25, 57, -62,
- 19, 18, -7, -22, 12, 19, -27, 9, -5, 15, -19, 2, 15, 4, -45, 36,
- -5, 8, -48, 60, -13, -35, 36, -19, 21, -24, -7, 23, -24, -22, 73, -58,
- -5, 34, 25, -71, 19, 30, 0, -43, -4, 50, -9, -21, -21, 69, -28, -46,
- 24, 29, -45, 12, 3, 21, -13, -28, 47, -9, -37, 21, 22, -46, 21, 8,
- -1, -32, 42, -22, 14, -27, 19, 16, -29, 3, 17, -1, -39, 28, 21, -42,
- 8, 47, -45, 2, -16, 50, -20, -54, 50, 9, -25, -12, 41, -29, 8, -3,
- -5, -13, 25, -16, 19, -30, 15, 15, -2, -52, 38, 38, -69, 12, 37, 9,
- -54, 10, 36, 5, -79, 27, 57, -35, -40, 48, 21, -41, 13, -3, 10, -29,
- 4, 18, 4, -50, 52, 1, -28, -6, 41, -25, -22, 34, -22, 10, -5, 3,
- -6, -1, 2, 26, -48, 24, 12, 5, -54, 36, 18, -32, -6, -3, 48, -28,
- -21, 22, 35, -63, 6, 43, -28, -27, 42, -7, -22, 6, 21, 8, -56, 31,
- 23, -10, -73, 76, 18, -49, -26, 70, -21, -23, -8, 35, 0, -42, 7, 42,
- -26, -28, 47, -31, 0, 13, 11, -25, 14, -6, 10, -13, -26, 40, -14, -5,
- -8, 42, -36, 1, 15, -10, -34, 47, -24, 5, -22, 38, 14, -39, -10, 53,
- -26, -67, 72, 0, -15, -25, 29, 19, -29, -25, 50, -14, -31, 10, 42, -44,
- -24, 81, -40, -32, 12, 45, -41, -5, -1, 47, -27, -54, 54, 32, -64, 4,
- 26, 1, -1, -41, 44, 4, -22, -22, 47, -30, 7, 5, 3, -37, 45, 1,
- -53, 44, -1, -20, 7, 12, -13, 9, -23, 26, -2, -47, 32, 37, -61, 6,
- 42, 0, -25, -43, 76, -23, -38, -10, 73, -24, -57, 47, 45, -70, 3, 19,
- 7, -19, -8, 10, 24, -12, -36, 66, -60, -1, 50, -32, -19, 8, 26, 2,
- -44, 11, 53, -42, -26, 20, 42, -52, 14, 16, -26, -11, 42, -41, 16, 16,
- -23, 13, 1, -6, 17, -18, -41, 71, -39, -23, 40, 13, -30, 2, 19, 0,
- -39, 10, 24, -15, -25, 12, 66, -81, 6, 47, 9, -69, 12, 47, -9, -36,
- -27, 76, 9, -107, 58, 53, -68, 19, -10, 39, -49, 8, 14, -11, -17, 21,
- 18, -25, -17, 47, -4, -48, 32, -9, -4, -3, 8, -5, 29, -40, 13, 14,
- -31, 24, 7, -48, 27, 37, -61, 22, 15, 7, -46, 17, 10, 22, -45, -9,
- 56, 1, -73, 43, 34, -51, -15, 40, 2, -47, 35, 8, 27, -87, 31, 86,
- -94, -27, 67, 10, -44, -15, 43, 11, -46, 6, 9, 33, -71, 35, 26, -30,
- -18, 37, -18, -9, 20, -15, 1, 5, 9, -2, -23, -11, 50, -42, -3, 24,
- 6, -21, 17, -5, -8, 11, -26, 24, -19, -9, 33, 22, -78, 38, 44, -48,
- -53, 80, 6, -66, 14, 36, 8, -37, -15, 66, -24, -75, 87, -14, -27, -10,
- 45, -12, -38, 13, 33, 7, -67, 20, 75, -55, -67, 85, 8, -52, -11, 45,
- -10, 13, -34, 12, 26, -36, 7, -1, -1, -7, 23, -27, 18, 15, -12, -28,
- 27, -6, 9, -52, 40, 26, -50, 3, 51, -10, -71, 67, 10, -59, 4, 56,
- -27, -20, -19, 58, 6, -81, 38, 49, -39, -39, 47, 14, -25, -40, 54, -2,
- -20, -38, 82, -25, -51, 44, 24, -60, 8, 51, -47, -2, 6, 22, 9, -34,
- -20, 78, -56, -25, 36, 19, -49, 17, 32, -50, 44, -29, 4, -11, 14, 3,
- -13, -11, 19, 13, -24, 28, -32, 33, -37, 39, -61, 119, -76, 120, -70, 99,
- -122, 89, -113, 91, -123, 122, -123, 77, 86, -116, 6, -118, 123, -23, 64, -93,
- 17, 24, -125, 124, -125, 124, -24, -12, 56, 87, -54, 38, -91, 64, -2, -41,
- 126, -127, 20, 8, -48, -62, 127, -128, 88, -43, -18, 86, -100, 44, -32, -26,
- 71, -13, 6, 51, -33, -50, 106, -59, 33, 5, -20, 69, -56, 54, -48, -6,
- 38, -5, -38, 35, -1, 12, -1, 4, 23, -56, 19, -7, 5, -4, 31, -38,
- 3, -12, -9, -25, -7, 24, -32, 17, -21, -22, 24, -20, 6, -18, 0, -15,
- 5, -16, 15, 3, 2, -10, 3, 27, -31, 37, -12, 32, -5, 2, -21, 27,
- -14, 20, -8, 5, 15, -7, -11, 20, -37, 7, -23, 17, -22, 11, -14, 8,
- -44, 39, -52, 26, 3, 14, -10, 51, -45, 29, -19, 19, -3, 41, -21, 46,
- -23, 10, 16, -25, 3, 7, -30, 19, -9, -5, -1, 1, -19, 1, -24, -23,
- 51, -48, -10, 17, -34, -38, 60, -71, 26, -43, 65, -59, 70, -26, 61, -51,
- 63, -51, 42, -25, 58, -36, 31, 10, -14, -9, 8, -18, 8, 4, 8, 7,
- 31, -52, 39, -53, 53, -56, 24, 11, 1, -20, -8, -32, -18, -10, -25, 4,
- 1, 37, -37, 42, -42, 53, -57, 52, -18, 30, 11, 20, -52, 55, -61, 56,
- -50, 24, -26, 38, -42, 36, -1, -43, 58, -46, 6, 18, -35, 31, -36, 28,
- -55, 55, -98, 52, -41, 26, -24, 48, -31, 48, -26, 30, 19, -17, 23, -8,
- 13, 15, 19, -7, -23, 41, -36, 20, -39, 65, -64, 66, -38, -9, 7, -14,
- -10, -3, 6, 15, -19, -40, 53, -67, -11, -12, -25, 23, -11, -12, 46, -48,
- 39, -20, 20, -14, 31, -54, 71, -25, 2, -8, -5, -9, 1, 7, 27, 17,
- -14, 43, -31, 27, 11, -33, 20, -2, -33, 45, -38, 17, -9, -11, -17, -22,
- -19, 20, -25, 4, 29, -35, 14, -17, 1, -7, 19, 2, 16, 32, -3, -17,
- 4, 0, -9, 17, 5, -8, 52, -32, 40, -39, -5, -18, 14, -21, 31, 10,
- -17, 8, -34, -7, 1, -44, 7, 10, -8, -6, -18, -25, -1, -19, 16, -29,
- 62, 6, 9, 21, 0, -14, 4, 5, 20, 13, 27, -1, 18, -5, 21, -31,
- 11, 2, -9, -4, 21, -27, 8, -21, -28, -19, 14, -12, 5, -20, 20, -36,
- 4, -18, -27, -4, -4, 15, 4, 48, -7, -11, 20, -6, 7, 20, 1, 20,
- 0, 35, -35, 28, -37, 7, -43, 21, -22, 23, -18, 12, -22, -13, -20, -11,
- 7, 23, -10, 19, -18, 17, -41, 4, -16, -8, 21, 11, -4, 10, 30, -24,
- 32, -15, 15, -13, 28, -5, 38, -10, 0, -22, -13, -12, 24, -18, 30, -7,
- 4, -16, 27, -28, -3, -1, 18, -14, 31, -24, -3, -13, -19, -36, -2, -31,
- 9, -2, -12, 17, 12, -50, 46, -49, 43, -15, 13, 22, 15, -25, 10, -8,
- -6, 14, -2, 24, 15, 9, 17, -13, 5, 14, -15, 7, 20, 4, 4, 18,
- -16, 3, -47, 31, -46, 19, -24, 5, -19, -1, -42, 14, -44, 18, -7, -1,
- 15, 9, -35, 32, -44, 39, -46, 23, -16, 36, -25, 45, -34, 32, -8, 10,
- 5, 28, 0, 12, 11, 3, 20, -23, 6, -8, 16, 7, 17, -19, 32, -44,
- 3, -8, -21, -8, -5, 2, -29, 2, -3, -19, -14, 3, 7, -23, 10, 1,
- 3, 8, 13, -44, 20, 21, -16, 23, 3, 5, 10, -11, 32, -11, 13, -7,
- 30, 4, 16, -7, -6, -7, 14, -40, 4, -16, -26, 3, -1, 0, -6, 5,
- -50, 37, -27, 18, -16, -14, 6, -1, -4, -15, 8, -12, 14, 9, -22, 42,
- -10, 23, -11, 36, -15, 13, 30, 1, 47, -20, 33, -14, -12, 1, -20, -9,
- -9, -11, -13, 7, -37, 25, -47, 14, -13, 4, -12, 9, -32, 18, -48, -1,
- -35, -1, -7, 35, -20, 53, -4, 34, -7, 13, 19, 9, 30, 6, 45, -22,
- 23, -18, -6, -1, 3, -30, 14, -15, 9, -39, 10, -33, -13, -24, 10, 14,
- 14, -10, 2, -34, -4, -20, -21, -14, 40, -10, 17, -14, 28, -17, 37, -26,
- 69, -15, 38, 2, 21, -25, 37, -61, 13, -9, 5, -17, 18, -41, 22, -57,
- -1, -9, -13, 24, -10, 38, -5, 8, -16, -2, 1, 12, -25, -2, -13, 2,
- 2, -16, -19, 32, -30, 22, 20, -4, 12, 11, -17, 19, -17, -3, 20, -33,
- 65, -27, 32, -14, 8, -8, 13, -19, 9, -2, 7, 33, -40, 18, -18, -18,
- 6, -23, -11, -11, -28, 4, -11, -15, -14, -8, -5, 34, -6, 19, 1, -3,
- 9, -1, 5, 5, 14, -11, 40, -3, 18, -20, 16, -7, 2, -5, 9, -16,
- 9, -17, 0, -17, 4, -17, -3, 3, 8, -14, -19, 12, -21, -7, 1, -2,
- -8, 16, 3, -6, 35, -23, 33, -13, 11, 12, 3, -7, 26, -11, 19, -18,
- 23, -22, 39, -49, 39, -50, 11, -38, 26, -29, 10, -6, -22, 15, -8, 15,
- -37, 36, -43, 39, -43, 18, -26, 1, 11, 4, -2, 9, 7, 2, 7, 19,
- 1, 1, -4, 16, -5, 16, -9, -3, 4, -4, -1, -17, 0, 11, 16, -27,
- 12, -15, 15, -3, 0, 10, -3, -5, 12, -13, -7, -13, -31, -1, -3, -17,
- 15, -31, 25, -10, 15, -1, 2, 4, 10, 7, 32, -13, 7, -22, 2, -10,
- 16, 1, -15, 19, -24, 16, -18, -12, 18, -9, 9, 24, -8, 8, 11, 0,
- -31, 17, -55, 21, -43, 40, -40, 29, -54, 44, -34, 22, 11, 16, 7, 19,
- 21, -6, 2, -7, -16, 22, 0, -1, -4, 5, -8, 26, -42, 4, -6, -21,
- 35, -16, 8, 0, -22, -13, 11, -31, 7, -28, 4, 17, -12, -18, -2, -23,
- 23, -1, 19, 34, 7, 7, 35, -19, 11, -8, -17, 8, 4, 16, -16, -13,
- 9, -15, -5, -1, -6, 7, 3, 11, 1, -7, -24, 21, -31, 36, -3, -10,
- 8, 2, -17, 12, -24, 6, -3, 9, 15, 3, 13, -8, -13, -3, 6, -19,
- 14, -33, 16, -17, -5, -31, 3, -29, 24, -7, -6, 35, -20, -5, 34, -20,
- 25, -3, 10, 25, 8, 14, -13, 0, 1, 17, -33, 51, -38, 45, -32, 39,
- -3, -2, -24, 3, -18, 14, -4, -44, 2, -25, -15, -2, -23, 3, -2, -2,
- 20, -14, 8, -10, -4, 21, 11, -13, 32, -4, 8, 19, -16, -2, -2, -2,
- 14, -2, -1, 27, -26, 20, 11, -13, 10, -3, -7, 12, -13, -3, -30, -16,
- 10, -26, -3, -10, -2, -9, 15, -17, 1, -2, -7, 14, -8, 12, -3, -1,
- 2, 47, -26, 22, -19, 16, 2, 13, -3, 21, -10, 22, -32, 43, -24, 16,
- 0, 5, -2, 12, -44, -12, 1, -26, 1, -36, 5, 2, 9, -17, 20, -37,
- 14, -9, -5, 6, -3, -13, 23, -19, 25, -33, 6, 17, 10, 19, 15, -4,
- 12, 5, -9, 33, -20, 26, -9, 11, -2, 11, -21, -7, -13, -4, -8, -12,
- 0, -10, -9, 8, -33, 9, -26, 8, 6, -8, 12, 7, -8, 0, 7, -16,
- 25, -8, 27, 12, 0, 9, -9, 4, -17, 14, -16, 11, -8, 18, -2, 4,
- 2, -20, -18, 22, -16, -5, 3, -24, 13, -10, -12, -10, 2, -16, 33, -15,
- 21, -15, -4, -19, 29, -22, 18, 2, 20, 12, 18, -22, -7, -16, 7, -19,
- 14, 1, -17, 33, -22, 38, -8, 3, -3, 21, -17, 51, -43, 15, -22, -23,
- -6, -12, -14, 14, 9, 6, 4, -31, 3, -16, -14, 22, -22, 5, 13, -25,
- 17, -2, -18, 7, 1, 5, 36, -16, 23, 4, -15, 29, -20, 10, 1, 24,
- 17, 16, -4, -16, -37, -11, 1, -33, 27, -36, 17, -22, 2, -33, 16, -29,
- 32, -7, 24, -12, 14, -12, 22, -16, 15, -20, 19, 9, 14, 12, -1, -24,
- 13, -6, -1, 32, -19, 24, 12, -26, 4, -31, -38, 18, -16, -13, 3, -14,
- -1, 11, -15, 15, 0, -2, 30, -6, 35, -23, 10, -35, 5, -14, 17, -21,
- 20, 4, 7, 8, -5, -15, 20, -25, 26, 6, -3, 3, 5, -24, 26, -35,
- 4, 0, -6, 13, -23, 8, -25, 1, -2, 9, 3, 17, 4, 0, 13, -15,
- 3, -21, -16, 4, -5, -10, 11, -2, 7, 23, -22, 25, -19, 18, 25, -9,
- 14, -21, -7, 11, -24, 22, -12, -7, 6, 9, -33, 11, -20, 2, -9, 2,
- 3, -13, 12, -15, 23, -21, 16, -16, -2, 8, 13, -12, 18, -10, 16, -12,
- 20, -18, 18, -1, 21, -21, 20, -30, -6, 10, -2, 13, -6, -15, 6, 2,
- -1, 1, -19, 9, -15, -3, -11, 0, -5, 1, 5, 1, -4, -8, 1, -16,
- 23, 0, -23, 2, 8, -6, 38, -4, 2, 13, -17, 31, -4, -8, 22, -14,
- 0, 12, -22, 7, -7, 11, 4, -4, -12, -9, -22, 2, -17, -17, -11, 7,
- -17, 19, -24, 9, -8, -6, 29, -4, 10, 4, 4, 23, -1, 9, -6, -12,
- 23, 16, -6, 33, -29, 12, -7, -10, 17, -4, -18, 21, 0, -14, -2, -20,
- -21, 10, -28, 5, -18, -4, 0, -11, 1, 5, -17, 3, 9, 20, 6, 1,
- -7, 2, -7, 3, 9, -22, 29, 6, -1, 25, -10, 6, -1, 4, 12, 18,
- -13, 28, -11, 6, -15, -14, -22, -7, 5, -14, 1, -16, -12, -5, 5, -9,
- 4, -1, -14, 21, -10, -5, 0, -17, -7, 2, -10, 6, 11, 1, 37, -17,
- 6, 21, -24, 41, 2, 23, 0, 10, -18, 16, -26, 14, -21, -19, 18, -9,
- -14, -1, -9, -14, -3, -7, -10, 7, -7, 19, -11, 15, -25, -3, -6, 2,
- 8, -10, 4, 12, -3, 11, -2, -2, 5, 31, -9, 39, -21, 14, -23, 18,
- -16, -1, -3, -6, 0, 22, -9, -5, -17, -4, -12, 2, -3, -7, 10, -10,
- 7, -20, -19, -10, 0, -14, 32, -15, -18, 13, -9, 2, 17, -14, 6, 36,
- -9, 28, 1, 0, 17, -10, 5, 17, -8, 12, -2, 3, 2, -22, -6, -14,
- 6, 8, -11, -14, 2, -23, 25, -35, 3, -18, 1, -14, 22, -1, -12, -7,
- -9, 13, -4, 12, 4, -3, 18, 0, 1, 8, -14, 14, -2, 1, 17, -3,
- -14, 35, -17, 19, -14, -6, 1, -9, 18, -17, -4, -13, -2, -14, 10, -10,
- -6, 0, 3, 5, -12, -13, -3, -6, -6, 11, -13, -7, 13, -2, 6, 13,
- -7, 11, -5, 23, 1, 29, -17, 23, -10, 18, -16, 12, -20, 10, 7, -9,
- -5, -21, -9, 5, -13, -2, 0, -15, -11, 3, 0, -18, 5, -25, -2, 3,
- -2, -3, 4, 8, 14, -7, 15, 4, 8, 19, 9, 11, 7, -3, 14, -11,
- 1, 15, -35, 3, 3, -10, -16, 0, -15, 2, 3, -12, 27, -23, 32, -15,
- 10, -14, 3, -27, 10, -15, 12, -24, 7, 2, 9, -2, -2, -1, 3, 1,
- 1, 8, -4, 0, 6, -6, 1, 1, -1, 8, -11, 31, -27, 13, 4, -3,
- 5, -1, 0, 2, 9, 0, 12, -31, 4, -27, 1, -25, 20, -21, -14, 12,
- -14, 0, -5, -23, 18, -1, 15, 19, -5, 20, -8, 14, -7, 16, 3, 0,
- 8, 10, 0, -8, -10, 3, -8, 9, -12, 4, 15, -6, 2, -12, -29, -3,
- -16, -11, 35, -18, -1, -28, 7, -12, 0, 7, -5, 22, 10, 10, -4, 6,
- -13, 21, -23, 20, 8, -13, 11, 15, -6, -6, -22, -1, 3, 14, 7, 11,
- -27, 12, -17, -12, 8, -15, 3, -8, 12, -12, 5, -30, 12, -18, 9, -2,
- 3, 4, 15, 1, 5, -9, 0, -8, 24, -2, 21, 5, -4, -4, 14, -15,
- 0, -1, 3, 17, -5, 13, -19, -10, -4, -6, -4, -7, 18, -27, 8, 1,
- -12, -21, -13, 1, -9, 11, 1, -3, -1, 22, -21, 9, 6, -3, 20, -2,
- 17, 7, -12, 1, 4, 4, -9, 9, -20, 24, 7, -9, -3, -7, -6, 10,
- 7, 3, 9, -2, -3, -4, 1, -19, -8, -16, 0, -12, 0, -25, 4, -22,
- 10, -9, 0, -3, 15, -1, 8, 11, -15, 10, 13, 1, 22, -5, 15, 1,
- 24, 6, 0, -6, 5, 5, 10, 8, -1, -11, -14, 3, -31, 2, -22, -4,
- -8, -15, -2, -31, -12, 6, -7, 5, 2, 3, -4, 19, 3, 4, 7, 7,
- -8, 31, -6, 26, 1, -2, 2, -3, -10, -4, -4, 9, 3, 12, -16, 16,
- -9, -1, 5, 4, -7, 13, -17, 0, -11, -13, -22, 1, -9, 4, -7, 7,
- -10, 5, -1, -6, -3, -21, 7, -10, 18, -3, 1, -7, -11, 11, -8, 12,
- 20, 3, 13, 16, -1, 3, 13, -3, 23, 16, -3, 15, -14, 12, -6, -8,
- -28, 0, -33, 4, -11, -12, -13, -21, -17, -16, -5, -12, 16, -7, 15, -6,
- -5, 3, -9, 21, 17, 13, 14, 11, 21, -12, 31, -18, 7, 12, 8, 9,
- 7, 1, -3, -7, -14, 17, -35, -10, -2, -18, -8, -10, -20, -22, 2, -10,
- -3, 1, -1, 4, -5, 11, -20, 11, -6, 27, 7, 18, 8, -1, 2, 3,
- 11, -9, 5, 5, -7, 29, -6, 20, -21, 23, -15, 19, -19, 2, -22, 11,
- -26, -7, -10, -30, -1, -3, -6, 15, -22, 16, -7, -9, -2, -7, -5, 11,
- 17, -13, 2, 8, -5, 6, 27, -6, 12, -6, 4, 15, 3, 14, -3, -12,
- 11, -2, 6, 5, 4, -6, -12, 0, -32, 2, -22, 22, -12, -5, -7, -11,
- -7, 6, -1, -3, -3, -16, 2, -1, 0, 0, -7, -2, 1, 12, -4, 5,
- 20, 1, 16, -2, 14, -1, 19, 8, 29, -8, 7, -14, -2, 3, -13, 8,
- -40, 22, -18, 2, -14, -8, -11, -8, 12, -21, -1, -10, -12, -6, -4, -14,
- 6, -19, 7, 14, 1, 11, 11, -11, 25, 1, 14, -5, 31, 0, 22, 4,
- 1, 3, 6, -3, 4, -2, -20, -7, -26, 1, -12, -7, -10, 2, -1, -5,
- -7, -8, -10, 6, -7, -6, 10, -17, 6, 3, 15, -8, 15, -7, 12, 1,
- 9, -4, -2, 10, 9, -1, 10, -4, 9, -8, 17, 0, -13, -7, -2, -11,
- 3, -2, -15, -4, -11, -5, -9, 1, 8, -10, 8, -8, -6, -18, 21, -19,
- 26, -19, -1, -11, 10, 4, 12, -10, 16, -10, 17, 8, 13, -1, 17, 1,
- 5, -1, 11, -8, 9, 16, -17, 3, -26, -17, -14, 6, -17, 4, -20, 0,
- -1, -6, -4, 2, -15, 13, -3, -1, 0, -2, -8, 11, 7, -3, -8, 5,
- 14, -1, 28, -19, 13, -4, 8, 1, 11, 7, 6, -8, -2, -13, -10, -22,
- 6, 11, -1, -1, -5, -13, 18, 3, -10, 9, -17, -8, 9, -9, 1, -17,
- -4, -16, 18, -6, 15, -10, 17, 5, 0, -5, 0, -11, 12, 15, 4, 8,
- 5, -4, 0, -2, 3, -17, -2, -1, 11, -6, -7, 2, -33, 23, -6, -1,
- -2, -2, -1, -8, 3, -29, -2, -34, 16, -3, 16, 1, 10, -12, 23, 0,
- -3, 16, 12, 19, 23, -1, 8, -26, 16, -32, 26, -13, 2, -11, 5, -1,
- -15, -9, -16, 7, -6, 14, -15, 5, -10, -7, -9, -9, 6, -17, 13, 18,
- -5, -3, -4, -4, -18, 28, -6, 13, 17, 24, -2, 9, -14, 1, -11, 7,
- 17, 1, -15, 10, -23, -4, -12, 5, -20, 17, -10, 6, 0, -9, 4, -8,
- -15, 6, -16, 7, 9, 3, 6, -12, -17, 0, 4, 13, 22, -4, 10, -8,
- 7, -12, 5, 5, 1, 11, 2, 10, -3, -2, 3, -10, -5, -7, -4, -18,
- 17, -2, -14, -16, -7, -10, -3, 6, -1, 14, -11, 15, -18, 2, -6, 0,
- -1, 0, 20, -17, 1, 6, 2, 6, 12, -3, 7, 25, -5, 17, -14, 0,
- -6, 0, -2, -5, -1, -10, 8, 2, -9, -19, -7, -17, 5, 3, -7, 4,
- -15, -5, 9, -12, -1, -5, 3, -5, 26, -2, 3, -4, 5, 3, 7, 10,
- 5, 6, 6, 26, -17, 0, -1, 3, -3, 10, -7, -7, -9, 11, -18, 0,
- -16, -6, -5, 3, 7, -14, -14, 0, -21, 14, -8, -1, -12, 2, 1, 2,
- -3, -1, -3, 18, 5, 5, 9, 12, 7, 18, 8, 5, -25, 16, -15, 16,
- -7, 9, -22, 1, 14, -13, -5, 2, -6, -8, 13, -17, 6, -16, 1, -5,
- -14, -6, -6, -15, -2, 9, -9, -18, 15, -19, 12, 7, 4, 8, 14, 15,
- 6, 10, -3, 9, -7, 23, -17, 21, -20, 7, 0, -9, 8, -10, 1, 4,
- 2, 3, -9, -9, -15, -6, -21, -16, -6, 0, -11, 19, -8, -9, 5, -6,
- 0, 5, 14, 7, 1, 12, 8, 7, -5, 12, 8, -4, 19, 4, -7, 2,
- 3, -12, -8, -1, 0, 5, 7, -5, -8, -22, -8, -21, -2, -9, 10, -20,
- 13, -6, 8, -17, -9, -6, 2, 5, 8, 6, -3, 10, -9, -2, 15, -6,
- 20, 7, 11, 10, -3, -4, -8, 25, -25, 18, -12, 17, -6, 20, -22, -1,
- -17, -10, 5, -10, 9, -13, -9, -6, 10, -25, -5, -2, -5, 13, 2, -5,
- -8, -10, 11, -27, 10, -4, 11, 0, 33, -4, 10, -14, 1, 12, -2, 27,
- -8, 6, 11, 9, -12, -4, -10, -13, 12, 5, 1, -10, -14, -15, -8, -7,
- -9, 3, -5, 10, 3, -11, -12, -13, -3, -3, 3, 2, 9, 17, -6, 25,
- -3, -3, -8, 19, 3, 30, -10, 12, -22, 7, -5, -10, -3, 21, -8, 12,
- 6, -5, -13, -13, -9, -9, -1, -23, 13, -17, 15, -22, -11, -18, 8, -14,
- 20, 1, 4, -5, 3, 3, 5, 11, 1, 2, 27, 1, 10, -7, -8, -2,
- -2, 7, -1, 17, -5, 24, -7, 5, -10, -20, -6, 5, -4, -5, -1, -18,
- -5, -14, -1, -20, 1, 7, -7, 12, -4, -2, -4, 2, 8, 0, 7, 1,
- 6, -2, 18, -5, -7, 4, 3, -2, 13, 4, 0, 2, -3, 2, -10, -6,
- 1, -6, 6, -7, -3, -21, -2, -12, 5, -1, -9, 7, -3, 13, 5, 5,
- -8, 0, -8, 19, -5, 13, 13, -7, 3, 0, -10, 0, -8, 20, -8, 13,
- -20, -5, -7, 3, 5, -7, 2, -5, -4, -14, 11, -23, -13, 2, -1, 12,
- 13, 5, -6, 23, -9, 9, -6, -9, 18, -13, 16, -3, -7, -17, 3, -13,
- 12, -9, 4, 0, 0, 13, -18, -1, 3, -13, 20, -5, 1, -20, 15, -23,
- 18, -4, -8, 5, -7, 16, 4, 6, -3, 7, -21, 19, -17, -7, 9, 5,
- 3, -5, -3, -16, -9, 25, -9, 12, -5, 10, -5, 9, -4, -6, -3, 4,
- 10, -2, 11, -12, -2, -14, 8, -23, -5, 0, -8, 9, -2, -11, -3, -9,
- 9, 2, 2, 4, -5, 7, 11, -16, 0, -6, 7, 6, 25, 5, 6, -4,
- 3, 4, 3, 2, -8, -3, 5, -1, -11, -4, -9, -3, -15, 10, -12, -5,
- 11, -4, -7, 6, -29, -5, 6, 11, 3, 9, -18, 13, -14, 19, -1, -2,
- 4, 5, 12, 1, 5, -8, 3, 1, 20, -6, 2, 3, -16, 10, -10, -18,
- -11, -7, -7, 9, -4, -8, 9, -15, 13, -13, -3, -7, 3, 8, 11, -6,
- -16, 1, -8, 20, 4, 15, -5, -3, 11, -5, 6, 0, -5, 10, 13, 0,
- -6, -11, 0, 11, -11, 10, -7, -8, 1, 16, -9, 2, -22, -9, 0, 4,
- 5, -12, -22, 2, -8, -8, 14, -16, 0, 13, 0, 9, -7, 2, -1, 7,
- 8, -3, -3, 2, 15, 5, 10, -7, 12, -4, 22, -4, -3, -12, -2, -15,
- 8, -2, -22, 7, -10, 5, 12, -20, -9, -11, -2, -12, 2, -9, 5, -3,
- 11, 7, -9, 4, -4, 24, -7, 21, -15, -3, 2, 14, -1, 5, 18, -12,
- 13, 3, 5, -10, -11, 0, -8, -2, -4, 2, -15, 9, -10, -16, -9, -7,
- 0, -1, 3, -8, -10, 5, -8, 4, -3, 8, -2, 20, 1, 6, -4, -9,
- 4, 14, 7, -1, 3, -5, 18, -7, 20, -6, -10, 8, 1, -2, 3, -4,
- -5, -3, -6, 0, -16, -7, 12, 0, -17, 4, -31, -7, 1, 1, -4, 8,
- -11, 6, -1, 11, -5, -7, -4, 2, 4, 15, -3, 21, -5, 20, 3, -12,
- 21, -1, 10, 5, 6, -20, -1, -18, 2, 3, -4, -5, -1, 6, -2, -11,
- -17, -15, -13, 0, 6, -18, 7, -18, 7, -7, 6, 7, -10, 18, 16, 2,
- -1, 3, -11, 6, 14, 1, 15, -2, 29, -8, 17, -14, 2, -19, 12, 8,
- -6, -1, -23, 6, -11, 7, -19, -18, 0, 1, -8, -8, -4, -20, 8, -8,
- 4, 10, -12, 13, 0, 18, -10, -3, -4, 6, 4, 17, 7, -2, 18, -9,
- 14, -10, -4, -11, 4, 3, 23, -17, -6, -2, -7, -7, 9, -10, 1, 2,
- -4, -14, -7, -6, -8, -4, 7, 2, -3, 3, 0, 13, -10, -4, -9, -6,
- 18, 11, -4, 16, -8, -4, 1, -1, 7, 3, 3, 3, 10, -15, -2, -9,
- 9, 0, 2, 2, -9, 12, -7, 0, -23, -7, -19, 2, -1, 0, 4, -15,
- 7, 3, -3, 0, 9, -12, 19, 4, 8, -13, -6, 5, -1, 14, 10, 9,
- 13, -3, 16, -18, 13, -18, 7, -10, 13, -6, -11, -3, 7, -23, -6, -11,
- -21, 9, -1, 4, -3, -16, 0, -12, 7, 14, -5, 15, 0, 6, -5, -3,
- -9, 9, 4, 10, 4, -2, -7, 10, -1, 10, -6, -14, 15, -4, 13, -4,
- -4, -14, 5, -2, 4, -9, 3, -14, 2, 3, -10, -1, -9, 0, 3, -6,
- 12, -16, 0, 4, 10, -25, 6, -5, 2, 8, 3, -2, -4, 15, 4, 7,
- 2, -1, -6, 10, 11, 2, -2, -14, 6, -3, 0, -3, -9, -10, 1, -1,
- -15, 9, -29, 9, -10, 7, -3, -3, -10, -2, 14, 4, -6, 0, 1, 12,
- 4, 18, -15, 19, 1, 15, 1, 1, 3, -10, 8, -1, 7, -30, 8, -19,
- -2, -5, -9, -10, 0, -1, 6, -4, -12, 1, -18, 10, -1, -12, 2, 7,
- 12, 11, 0, -4, -1, 6, 10, 17, -8, 1, -12, 5, -2, 1, -7, -1,
- 4, 3, -3, -1, -18, 8, -9, 0, -2, 8, -12, 12, 7, -5, -2, -16,
- -7, 9, -5, 11, -9, -4, 3, 1, -9, -1, -2, -6, 7, 12, 0, -8,
- 9, -10, 3, 0, 2, -3, 11, 14, 4, 3, -12, 3, -3, 2, 12, -4,
- -2, -2, 9, -21, -5, -28, -6, -10, 6, 7, -6, -3, -24, 7, -11, 10,
- 0, 8, 13, 10, 6, -7, -2, -5, 7, -1, 9, 18, -2, 12, -4, 7,
- -26, 13, -6, 19, 6, 6, -5, -16, -6, -8, -18, -2, 1, -11, 3, 4,
- -16, -8, -10, -3, 2, -3, 5, 5, 0, 11, 0, -14, 0, 1, 14, 11,
- 13, 0, -2, 5, -1, -4, -2, -4, 5, 21, 3, 14, -5, -22, 5, -11,
- -3, -6, -3, -11, 0, -5, -13, -10, -18, 3, 9, -10, 2, 3, -11, 11,
- -11, 5, -19, 23, -1, 20, 18, 4, -3, -6, 9, 4, -3, 8, 4, 6,
- 2, 5, -14, -6, -3, 2, -6, -4, -3, -11, 0, -5, 0, -21, -2, -10,
- 11, 5, -4, -5, -5, -8, 10, -10, 4, -1, 6, 12, 9, 2, 8, -20,
- 8, -2, 11, -11, 1, -4, 5, 6, -6, 6, -14, 14, 4, -2, 12, -3,
- -10, 8, -5, -15, -9, -1, 5, 8, -3, 0, -23, -9, -11, 4, -12, 3,
- -4, 4, 1, 15, -12, 3, 13, 2, 5, 8, -8, 7, 11, -3, 17, -11,
- 5, 3, 19, 13, 3, -11, -11, -2, -9, -7, -4, -24, -1, -17, -3, -17,
- 0, -15, 2, -1, -5, -4, 3, 2, 2, 11, -4, 3, -6, 11, 8, 3,
- 6, 3, 7, 7, 6, -6, 2, 0, 14, 14, 3, 8, -6, 4, -3, 6,
- -13, -2, -9, -4, 5, -13, -5, -21, -1, -6, -1, -5, -14, 8, -7, 5,
- -7, -17, -11, 7, 3, 20, 7, 1, -3, 4, 5, 14, -3, 5, 3, 10,
- 8, 6, -6, -2, 6, 3, 7, -6, -3, -3, -6, -1, -27, -11, -17, 0,
- 11, 7, 1, -7, -9, -13, 5, -11, 0, -10, 15, 2, 5, -2, -5, 1,
- 6, 6, -6, -5, 6, 2, 5, 3, 10, -16, 11, 8, 18, 3, 13, -11,
- 7, 5, -7, -6, -20, 15, -1, 10, -1, -13, -17, -11, -3, -13, -4, -14,
- -3, -2, -6, 6, -28, 9, -8, 10, 0, 12, -2, 10, 9, 1, 3, -6,
- 5, 17, 24, 18, 3, 4, -9, -4, 2, -8, -4, -2, -11, 1, -8, -12,
- -9, -10, 5, 0, -7, -9, 7, -18, 6, -10, -12, -1, -1, 13, 1, 18,
- 2, -3, 4, 3, 3, -3, 3, 10, 9, 7, 5, -8, -7, 0, 3, -7,
- 7, -2, -2, 5, -10, 2, -5, -3, -1, 4, 1, -2, -10, 4, -9, -5,
- -12, -18, 3, 6, -3, 3, -15, -1, -13, 6, -2, 8, 0, 8, 16, -2,
- 17, -4, 8, 3, 23, -1, 11, -8, 10, -4, -5, -3, -13, -2, -1, -2,
- 2, -9, -13, -13, -2, -11, -2, -20, -5, 0, 3, 2, -1, -10, 1, 8,
- 3, 9, 6, 4, -3, 13, 3, 4, 11, 2, 11, 8, -2, -1, -2, -2,
- -2, -1, -21, -1, -14, 8, 6, -8, -10, 2, -16, 4, -3, -1, -10, 7,
- -1, 4, -4, -12, 3, -2, 13, 2, -3, -9, -2, 6, -7, 8, -8, -5,
- 12, 7, 8, -3, 6, -1, 16, 0, 7, -8, 3, -7, -1, 0, -6, -4,
- -8, 6, -1, 4, -19, 2, -3, -8, -3, -12, 4, -6, 2, -7, 1, -13,
- 2, 9, -1, 17, -19, 3, -3, 23, 9, 6, 3, 6, 6, -5, 11, -11,
- 1, 0, -5, 6, -6, -4, -5, -7, 3, -4, -14, -9, -7, -1, 5, -11,
- 4, -19, 14, -4, 3, 4, 2, 0, 9, -2, -3, 2, -2, 10, 15, -3,
- 14, -6, -4, 6, 1, -8, 11, -9, 4, 3, -9, 2, 2, -2, 2, -2,
- -9, -2, -2, 1, -6, -6, -22, -16, -10, 12, 0, 5, -8, -2, -4, -2,
- 5, -1, 7, 7, 9, 1, 7, 6, -1, 10, 11, 5, -3, 8, 1, -1,
- 8, -15, -6, -10, 12, 0, 2, -5, -9, -12, -7, -4, -14, -4, 0, -1,
- 5, -7, -8, -12, 0, 2, 16, -3, 11, -4, 16, 11, 2, -3, 2, 8,
- -1, 7, -13, 4, -3, -1, 3, -10, -2, -11, 3, 2, 3, -7, -10, -5,
- -10, 12, -8, 5, -7, 15, 1, -10, 7, -16, 1, 3, 4, -5, 7, -7,
- 4, -2, -1, -8, 0, -2, 17, 10, -2, 6, -5, 3, 10, -7, 2, -3,
- 4, 5, 5, -3, -8, -8, -1, 1, 7, -5, -11, -2, -10, -4, -15, -7,
- -10, -2, 2, -4, -10, -8, 0, 2, 6, 3, 2, 3, 10, 14, 8, 7,
- 3, 5, -5, 20, -6, -1, -2, 0, 1, -2, -2, -8, 3, -3, 10, -14,
- 3, -3, -2, 0, -5, 0, -15, 4, -2, 0, 4, -7, 3, -8, 7, -14,
- -2, -6, 4, 2, 3, -10, -2, 5, -3, 12, -2, -5, -9, 1, 4, 1,
- 11, -12, 15, 5, 20, 10, -5, 1, 5, 3, -13, 6, -16, 5, 1, -5,
- -8, -3, -14, -6, -2, -5, -8, -17, -9, 3, -6, -2, -3, -3, 1, 14,
- 2, 4, 5, 3, 8, 7, 12, 0, 11, 4, 16, 2, -3, -9, -1, 1,
- -1, -3, -6, -14, 4, -6, 2, -14, -9, -11, -1, 0, 0, -5, -6, -10,
- 5, -5, 2, -3, 2, 2, 17, -2, -1, -3, 3, 11, 1, 10, 2, 7,
- 6, 5, -5, -3, -3, -2, 7, 2, 1, -18, -5, -2, -3, -5, 0, -2,
- 0, 8, -9, -10, -15, -7, -2, -1, 6, -8, 16, -10, 13, -4, 2, -4,
- 4, 7, 9, 6, -5, -2, 8, -1, 11, -6, -1, 5, 8, 0, 9, -20,
- 0, -9, 4, -3, 1, -4, -11, 2, -6, 0, -12, 0, 1, 5, -2, 1,
- -7, -4, 3, -1, -10, 3, -3, 7, 4, 8, -9, -6, -10, 0, 0, 2,
- -4, 6, 9, 10, 2, 0, -1, 2, 14, 3, 7, -7, 2, -2, -2, -6,
- -9, 2, -3, 6, -3, -7, -9, -10, -2, 2, -1, -11, 2, 1, 7, -4,
- -7, -19, 3, -1, 6, 6, 6, 6, 0, 6, 7, 3, -1, 3, 8, 3,
- 4, -10, -5, -7, 5, -4, -14, 2, -8, 5, -2, 2, -16, -4, -11, 2,
- 4, -1, 2, -1, 0, 5, 4, -12, 3, 9, 7, 13, -3, -7, 2, 6,
- -1, 7, -1, -1, 5, -5, 7, -11, -9, -13, 2, 5, 2, -2, -7, 5,
- 4, -4, -2, -15, -4, 3, 0, 0, -5, 2, -7, -1, 9, -2, -1, 5,
- 1, 1, -4, -5, -4, 6, 8, 7, -5, 4, -7, 4, 0, 1, -6, -5,
- -2, 5, -1, 0, 1, 1, 3, 9, -4, -2, -4, -9, -1, 4, -17, 1,
- -13, 11, -1, 6, -9, -1, 5, 1, 8, -3, 4, -5, 1, 7, -5, 1,
- -3, 5, 3, 4, -7, -11, -7, 1, 5, -13, 11, -11, 1, 3, 6, -9,
- 6, -5, -7, 4, -13, 5, -7, 10, 5, 6, -15, -1, 6, 4, 18, -7,
- -7, -3, -4, 2, -5, 3, -4, 9, -4, 3, 3, -3, -10, 0, -1, 2,
- 5, -3, 7, 3, 2, -6, -11, -2, -1, 4, -5, 4, -5, 0, -5, 5,
- -5, -4, 2, 4, 2, 5, -8, -13, -3, 0, -1, -2, 4, 6, 9, 1,
- 3, -7, -1, 1, 12, 1, 1, -1, -5, -1, 2, -8, -9, -7, -2, 3,
- 10, -6, -7, -12, -7, -4, -5, 6, 0, 10, 5, 7, -4, -2, -8, 10,
- 5, 9, 4, -1, -1, -1, -1, -1, -2, -3, 3, 9, -2, 9, -14, -13,
- -8, -10, 1, 1, 3, 3, 1, -3, -12, -5, -7, 1, 6, 6, -2, -7,
- -3, -3, 2, 2, 4, -9, 14, 8, 11, -3, 5, -11, 1, -1, 5, 3,
- 8, 2, 8, -2, -6, -13, -10, 0, 4, 3, 4, -3, -9, 1, -5, -5,
- -6, 1, -2, 2, -10, -6, -15, 1, -5, 4, -1, 2, 2, 4, 10, 4,
- 2, -13, 0, 4, 8, 17, 2, 5, 4, 2, -6, 5, -5, 0, 8, -2,
- -1, -5, -4, -5, -1, -5, -4, -5, 0, 0, 1, -9, -15, -3, -12, 1,
- -1, -7, 10, 2, 5, -1, 2, -6, 2, 2, 10, 10, -1, 2, -2, 4,
- 5, 0, -6, 12, 5, 3, -1, -8, -8, -4, -4, 3, -11, 0, -1, -1,
- 0, -2, -14, -6, -9, 2, 1, 7, -4, 3, -1, 0, -3, 1, 2, 7,
- 5, 4, 3, -2, -3, 1, 6, -1, 6, -11, 7, 2, -6, 2, -4, 0,
- 2, 3, -7, -9, 3, 0, 4, -6, 0, -21, 0, -5, -1, 0, -1, 1,
- -6, -1, -1, 0, -7, 5, 7, -2, 8, -4, -1, 3, 9, -6, 10, -6,
- 7, 9, 10, 9, -6, 5, -14, 6, -5, 1, 2, -3, 0, -9, -10, -14,
- -2, -3, 6, -8, -15, 3, -9, 0, -3, 0, -6, -1, 3, 9, 10, 3,
- 3, -10, 6, 1, 3, -1, 9, 12, 4, 4, -9, -7, -5, 8, 6, 1,
- 1, -4, -5, -5, -1, -11, -3, -4, 1, -1, 1, -10, -7, -2, -3, -4,
- -3, -6, 11, 5, 3, 2, -8, -5, -2, 3, 9, 13, 5, 4, 4, 0,
- -5, -1, -5, 9, 2, 3, -9, -4, 3, -6, 2, 1, -9, 5, -2, 3,
- -2, -9, -8, -15, -5, -3, 3, -13, 11, 6, -3, 1, -6, -6, -1, 6,
- 4, 6, 7, 1, 5, 0, 8, -6, 7, 2, 6, 2, -5, 0, -3, -1,
- 3, -7, -1, -3, 5, 7, 6, -18, -10, -11, -7, -3, 10, -4, 3, -4,
- -8, -5, -12, -3, -4, 12, 10, 2, -4, 6, 3, 1, 2, 0, -3, 3,
- 7, 7, -5, 2, -4, 1, 3, 11, 2, 3, 4, -2, -7, -5, -17, -11,
- 4, -3, 5, -7, -7, -6, -1, -8, -5, -5, 1, 7, 1, 2, -1, -9,
- 7, 1, 7, 3, 3, 6, 9, 6, 1, -6, -4, 2, 5, 7, 4, -2,
- 1, 3, -11, -1, -16, -2, -6, 1, 3, -8, -15, -11, 4, -1, 9, -2,
- -5, 0, 6, 0, -7, 0, -8, 4, 2, 6, 2, 0, 2, 6, 2, -2,
- 4, -2, 4, 14, 2, 2, -6, -6, -3, 4, -4, -1, -4, 1, -3, -6,
- -1, -13, -1, -2, 7, -8, -7, -10, 0, 4, 3, -8, -3, 1, 4, 6,
- 4, 6, -3, 5, 3, 4, 0, 6, 1, 4, 7, -3, -10, 8, -1, 9,
- -1, 1, -11, -7, -3, -3, -6, -8, -9, -6, 1, -3, -6, -6, -5, 0,
- 0, 2, -3, 0, 6, 4, 3, 2, 7, 4, 11, 14, 5, -1, -5, 1,
- -2, 7, 3, 0, 1, 2, -5, -7, -10, -12, -10, -5, -5, -6, -6, -9,
- 1, -8, -2, -1, -9, 1, 8, 2, -5, -2, -5, 0, 5, 6, 6, 7,
- 8, 10, 2, 0, -3, -1, 2, 13, 3, 0, -6, 0, 1, -3, 0, -12,
- -2, 4, -4, 4, -8, -11, -1, -2, 1, -1, 2, -12, 3, -6, 1, -12,
- -7, -7, 3, 0, 9, 0, 1, 6, 1, -1, 2, 1, 2, 8, 9, -3,
- -1, 0, 7, 3, 8, -1, -4, -1, 1, 3, -9, -1, -17, -3, -2, -4,
- -4, -3, -4, -6, -11, -15, -2, -5, 6, 10, 1, 3, -1, -3, 13, 7,
- 1, 6, 4, 4, 9, 5, -3, -5, 9, 3, 5, -3, 1, -3, 3, 0,
- -7, -5, -7, 0, -5, 0, -1, -15, -11, -4, -5, -10, 2, -7, 5, -4,
- 1, -9, 2, 1, 8, 7, 10, 2, 2, 0, 4, 3, -2, 0, 4, 2,
- 6, 8, -2, 4, 4, -2, 5, -3, -6, 3, -3, -5, -9, -8, -11, -5,
- -1, -1, -5, -7, -5, -8, 0, -3, 5, -7, 11, 1, 0, 2, -3, -1,
- 3, 9, 6, -3, 8, 1, 11, 2, 8, -3, -3, 6, 2, 1, 2, -7,
- -3, -2, -4, -8, -3, -3, 5, -10, -10, -4, -12, -2, 3, -5, 3, -6,
- -8, -2, 5, -3, 0, 1, 4, 8, 4, 5, 0, 4, 8, 1, 7, -3,
- 0, 3, 4, 4, -5, -2, -7, -3, 0, 5, -5, -9, 3, -2, -1, -2,
- -5, -1, -4, -3, -11, -4, -5, -6, 0, 5, 0, -5, 5, 3, 8, -1,
- 3, 3, 2, 5, 7, -4, 3, 1, 3, 10, 2, -7, 1, 0, 6, -4,
- -3, -5, -7, -2, -4, -3, -6, 0, -10, 4, -6, -4, -7, -2, 1, -4,
- -1, -3, -1, 2, 6, 2, 4, -2, 2, 4, 2, 5, -3, 4, 2, 1,
- 0, 8, -3, 2, 5, -5, 3, -5, -2, 5, -5, 3, -1, -4, -3, 4,
- -10, -5, -7, -4, -4, 0, 0, -7, -1, -1, 2, 1, -2, -12, -4, -1,
- 0, 4, -5, 2, 0, 3, 12, 11, 3, 11, -1, -3, 6, -6, 1, 1,
- 7, 6, -7, -1, -7, -4, -4, -7, -8, -1, -6, -6, -2, -3, -5, 0,
- -4, 8, -7, 1, 4, -3, 6, 1, -7, 3, 5, 6, 5, 13, 2, 2,
- -4, 4, -3, 1, 4, -4, 2, -3, -10, -10, -7, -2, -2, -2, 0, -6,
- -2, 1, -3, -4, -2, -5, -2, 7, 1, 6, -5, 6, -1, -1, 2, -3,
- 4, 11, 2, -1, 2, -7, -5, 8, 0, 3, -3, -5, -1, -2, 3, 1,
- -4, 4, 7, 0, 2, 3, -3, 0, 1, -5, -15, -5, -3, 1, 3, -3,
- -11, -4, -7, 1, -2, -1, -1, 0, 1, 1, -5, -1, 3, -2, 7, 1,
- -4, -1, 0, 4, 5, 3, 3, -1, 8, 11, 1, 4, 1, -5, 7, -6,
- -4, -2, -4, -2, 3, -8, -3, -13, -6, 3, -3, -7, -4, -7, 3, 3,
- -3, 2, -1, 1, -4, -2, -2, -5, 1, 11, 9, -2, 6, -3, 7, 7,
- 1, 1, -7, 2, -3, 1, 4, -4, -4, 5, 1, 0, -3, -6, 2, -3,
- 0, -8, -12, -6, -2, -3, 6, -1, -9, 0, -1, 1, 3, -2, -1, 0,
- 1, 6, 0, -3, 5, 1, 6, 1, -1, 4, 1, 7, -3, -1, -1, -4,
- 4, 14, -1, -1, 2, -4, -1, -6, -8, -8, -3, -2, 2, -9, -5, -7,
- -12, 5, 0, -3, -4, -3, 5, 4, 3, -2, -6, 4, 7, 3, 5, 7,
- -3, 8, 0, -5, -1, -1, 11, 10, 3, 4, -8, -3, -3, 1, -3, 0,
- -4, -3, 1, -7, -8, -16, -7, -6, -2, 3, -7, -2, 1, -4, 0, -5,
- -5, 1, 5, 10, 5, 0, 3, 0, 1, 13, 0, 5, 9, 6, 8, -1,
- -4, 0, -3, 6, 4, -4, 0, -3, -15, -2, -12, -15, -3, -6, 2, 1,
- -3, -4, -9, -9, -3, -3, -2, 3, 4, 9, 0, 2, 1, 2, 14, 5,
- 3, 8, 2, 7, 4, -4, -4, -1, -9, 9, -5, -1, -7, -10, -2, -7,
- -4, 0, -5, 2, 5, 1, 0, -5, -5, -1, -1, -3, 4, -8, 5, 3,
- -4, 4, -5, -3, 9, 4, 8, 0, 0, 2, 0, -2, 0, -2, -7, 12,
- -1, 5, -4, 2, -3, 0, 2, -2, -4, -2, 2, -5, 3, -7, -9, -4,
- -3, -2, -6, -6, -2, -6, -1, -7, -8, 1, 3, 6, 10, 4, 5, 0,
- 5, 8, 1, 3, 8, 5, 11, 12, -7, 4, 0, -3, 2, -1, -8, -7,
- -4, -2, -6, -9, -6, -13, -4, -1, 0, -9, -5, -3, -4, -2, 3, 1,
- 1, 9, 4, 2, 6, -1, 3, 6, 2, 0, -3, 3, 2, 6, 3, -1,
- -4, 4, 1, 2, 2, -5, -8, -1, -3, -1, -9, -4, 1, -5, 5, -7,
- -4, 0, 3, -10, 3, -3, -5, 1, 5, 4, 1, -5, 1, -5, 4, 1,
- -6, 0, 5, 8, 8, 1, 6, 0, 3, 4, 2, -3, 1, -3, -3, 3,
- -10, -6, -8, -2, -1, -3, -6, -6, -5, -6, -6, -5, 5, -3, 5, 6,
- -2, -1, -1, -4, 6, -2, 6, 6, 2, 12, 8, -2, 3, -6, -2, 5,
- 4, -3, -2, -5, -4, -7, -6, 1, -5, 2, 2, 0, 1, -7, 0, -4,
- -2, -1, -2, -5, 7, -5, -2, -3, -2, -3, 4, 4, 9, 0, 1, 1,
- -5, -3, -4, -4, 4, 3, 6, 1, -2, -2, -7, 4, 1, 1, -3, 3,
- -1, 2, 0, -7, 0, 0, -1, -3, -2, -1, -5, -2, -3, -8, -5, -5,
- -1, 5, 5, 2, 2, -3, 4, 3, 4, 6, 3, -1, 10, -4, -3, -2,
- -3, 0, -4, 0, -2, -2, 0, 2, -5, -2, -5, -9, 8, -2, -1, -1,
- -3, -3, -2, -6, 2, 1, 2, 9, 0, 1, 4, -5, 2, 4, -6, -1,
- 2, -1, 6, 3, 0, -5, -3, -1, 0, 3, -3, 0, -6, -2, -3, -4,
- -2, 0, 3, 2, 2, 0, -10, 1, -6, -5, -1, -2, 5, 3, 6, -2,
- -6, -1, -3, 2, 4, 1, -1, 0, 1, 1, 3, -1, 5, -1, 7, 6,
- 1, -2, 0, -6, -2, -2, -8, -2, -2, -3, -5, -5, -8, -3, -1, 5,
- -3, 1, 2, 1, 2, -3, -2, -3, 2, 6, 2, 6, 0, 0, -2, 9,
- -1, 3, -2, 3, 0, 0, 0, -6, -6, -1, -5, -7, 1, -3, -6, 2,
- -2, -1, -5, -2, 1, 4, 2, 2, -3, -1, 6, -2, 2, 4, -3, 2,
- 2, 2, -3, 1, 0, -4, 2, -1, -2, 3, 1, 1, -1, -5, -8, -2,
- -5, 0, 1, -6, 3, -4, 2, 3, -6, 3, 0, 2, -2, -1, -4, -2,
- -4, 4, 0, -3, 0, -6, -3, 10, -3, 3, 0, 4, 7, 3, 0, 5,
- 1, 5, 1, -3, -2, 0, -6, 3, -1, -7, -5, -7, -1, -2, -2, -2,
- -3, -2, 2, -2, -1, -3, -3, 2, -2, -6, -3, -3, 4, 3, 2, 0,
- -1, 5, 5, 8, 2, 2, -2, 4, 0, 5, -5, -3, -1, -3, -3, -6,
- -4, -2, 3, 0, -2, -2, -5, 5, -1, 3, -1, -1, -3, 0, 0, -5,
- -4, -3, -2, 5, 0, -4, -4, 1, 2, 6, 0, -3, -1, 2, 3, 7,
- -3, 0, -4, -2, 4, 3, 0, 1, 3, -3, 1, -7, -4, 0, 1, 1,
- -4, -4, -4, -9, -1, -2, -3, -2, -3, -3, 4, 3, -1, -4, 2, 4,
- 4, 3, 2, -1, 0, 9, -1, 4, 2, 7, -1, 6, -2, -2, -5, -1,
- -9, -2, -2, -6, -1, -1, 1, -8, -6, -5, -1, -1, 1, -4, -5, 3,
- 1, 5, 3, -3, 0, -2, 7, 0, 1, -2, 3, -1, 5, -1, -5, 7,
- -1, 3, 2, -5, -6, -2, 4, 2, -1, -3, -1, -1, -1, -1, -2, -4,
- 1, -5, 3, -1, -3, -5, 2, 6, -6, -1, -5, -4, 4, -1, -1, -2,
- -1, 2, 0, 3, 1, 4, 2, 7, -1, 2, 0, -2, 1, 4, -5, -3,
- -7, -2, 0, -1, -1, -3, 0, 0, -2, -6, 2, -4, 2, -4, 1, -7,
- -2, -1, 5, 3, -2, -7, -4, 1, 6, 4, 5, 1, 4, 0, 5, 1,
- -1, 2, 0, -3, -3, -5, -6, 3, -1, 5, -1, -2, 1, 1, 4, 2,
- -6, -3, -4, -3, 2, -2, -8, -3, -6, -4, -2, -11, 0, 0, 1, 6,
- -3, -2, 1, 2, 10, 8, 4, -2, -1, 2, 2, 1, -2, 3, 1, 5,
- 3, -1, 0, -4, 4, -7, -2, -7, -8, -4, -3, -2, -7, -7, -3, -1,
- 5, -2, 0, -7, 2, -1, 3, 1, 4, 6, 5, 8, 3, 2, -1, 3,
- -3, 0, 0, -5, -1, 1, 1, -5, -3, -2, 6, 4, 5, -4, -8, -4,
- -3, -2, -5, -4, -4, -4, 2, -3, -2, -4, -4, -4, 6, 1, 0, 1,
- 3, 3, 5, 2, 1, 0, 6, 2, -1, 1, -3, -3, 2, -1, 0, 1,
- 3, 1, 4, -4, -5, -10, -8, 1, -6, -3, -4, -6, -3, 0, 2, -3,
- -1, 2, 0, 8, 1, 4, 4, 3, 6, 3, 1, 3, 5, 1, 2, -4,
- -7, -3, -3, 3, 0, -7, -5, 0, -3, -1, -2, -4, 0, -5, 1, -6,
- -1, -5, -3, 1, 4, -1, -3, 3, 3, 5, -1, -2, 2, -1, 2, 1,
- -1, -5, 5, 1, 2, 2, -4, 0, -1, 3, 0, -2, -1, 2, 1, 5,
- 4, -3, -5, 0, -2, -2, -6, -3, -3, -4, -1, -5, -4, -1, -2, 0,
- 2, -2, -6, -3, 1, 1, 1, -1, 3, 4, 7, 2, 3, 4, -1, 7,
- 2, 3, 1, -1, 1, -2, 0, -4, -5, -6, 0, -2, -7, -2, -5, -5,
- 1, -4, -5, -5, 3, -1, 1, 2, -2, 0, 1, 4, 1, -4, 2, 2,
- 0, 9, 2, 0, 4, 3, 1, 2, -4, -2, -4, 3, -4, -2, -6, 0,
- -1, 5, 2, -4, 0, -4, -4, -1, -5, -4, -7, -3, 1, 0, -2, -1,
- -5, 1, 0, -1, 0, 2, 4, 0, 3, -2, 1, 2, 6, 0, 1, 5,
- 0, 3, 3, 2, -5, -2, 1, 5, 2, -2, -5, -9, 0, -6, -1, -6,
- -7, -5, -4, 0, -2, -5, -3, 2, -2, 3, 2, 0, 9, 2, 0, 4,
- -3, 4, 5, 8, 6, -2, -4, -1, 0, -2, -2, 1, -5, 2, -5, -1,
- -4, -3, -4, 0, -2, -7, -3, -1, 0, -1, 0, -6, 3, -2, 5, 2,
- -1, -2, 1, 0, 1, -1, -3, 2, 3, 1, 2, -4, -3, -1, 5, 5,
- 3, -4, 0, 1, 2, 5, -5, 1, -5, 2, -2, 2, -4, -3, 0, -4,
- -3, -9, -7, -4, 2, -2, 1, -6, -3, 0, 1, 5, 1, -5, 0, 0,
- 2, 1, 2, 0, 6, 4, 6, 3, 2, 3, 1, -2, -2, -9, -4, -1,
- 4, 0, -1, -5, -8, -5, -4, 0, -4, -1, -3, 0, 0, -4, -3, -1,
- 1, 2, 0, -2, -3, 1, 3, 2, 3, 3, 0, 8, 2, 7, -1, 3,
- -2, 4, 0, 0, 1, -4, 5, -1, -3, -3, -6, -4, 2, 1, -5, -4,
- -7, -4, -4, -7, -2, -10, 1, 0, 1, -3, 4, -2, 5, 2, 1, -3,
- -1, 2, 8, 4, 5, 0, 1, 4, 5, 2, 2, -2, 1, -4, 0, -3,
- -3, -1, 0, 2, -4, -4, -5, -1, -7, 0, -4, -5, -1, -3, 2, -2,
- 0, 3, 0, 2, 0, 1, -2, 2, 4, -1, 0, -3, -1, 1, 3, 2,
- -3, 2, 0, 2, 2, -1, 2, -2, -3, 0, 0, -2, 2, -2, 4, -3,
- -6, -7, -6, 2, -1, -4, -1, -7, -1, -3, 3, -1, 0, -2, 2, 2,
- -3, 3, -4, 5, 7, 6, 3, 1, -1, 6, 2, 1, 0, -1, -1, 1,
- -3, 1, -3, -5, -5, -3, -8, -3, -11, -1, -1, 0, -8, -2, -5, 3,
- 4, 0, 1, -2, 2, 0, 6, 4, 1, 4, 1, 5, 0, 0, 1, 2,
- 5, 0, 1, -10, 0, -5, 2, 0, -6, -6, -2, -2, 2, -3, 0, -4,
- 2, -4, 1, -3, -4, 1, -2, 2, 1, -2, 0, 3, 2, -3, -1, -5,
- -3, 4, 2, 3, -1, 4, 1, 5, -1, 2, -3, 2, -3, 0, -3, -2,
- 1, 1, 5, 1, -2, -5, 1, -1, -4, -3, -7, 0, -5, -4, -4, 0,
- -4, 4, 0, -1, 1, -8, 1, 0, 9, 1, 2, -2, 5, 5, 1, 6,
- -1, 6, 3, 1, 1, -2, -2, -4, -3, -2, -3, -7, -4, -4, -1, -3,
- -8, -1, -8, 4, -5, 0, -3, 1, 0, 4, -1, 0, 1, 3, 3, 4,
- -4, 6, -2, 2, 5, 4, -3, 4, -3, 5, 0, -4, 0, 0, -1, 0,
- -4, -4, 3, -1, -2, -4, -8, -9, -5, -4, 4, -4, 1, -4, 1, 1,
- -1, -1, -1, 3, 2, 3, 0, 1, 2, 1, 5, 3, 1, 0, 5, 3,
- 3, 0, -5, -4, -2, 5, 0, -2, -5, -2, -6, -2, -5, -8, -2, 1,
- -1, -3, -7, -8, -6, 0, 4, 7, -2, 7, -1, 7, 3, 2, -5, 0,
- 2, 0, 1, -3, 2, 2, 3, 3, -3, 0, -2, 3, -1, -1, -4, -6,
- -2, -3, 4, -4, 0, -4, 6, -2, -6, -2, -7, 1, 2, -1, -3, -2,
- -2, 3, -1, 0, -3, -1, 4, 7, 4, 0, 2, -1, 0, 6, -2, 1,
- 1, 5, 4, 1, -3, -3, -2, 2, 2, 1, -6, -6, -3, -4, -2, -6,
- -5, -4, -5, -2, -8, -8, -3, 0, 4, 0, 1, -1, 2, 5, 4, 2,
- 2, 3, 3, 4, 10, 0, 2, 0, 3, 1, 1, 0, -3, 1, -3, 1,
- -7, 0, 1, -2, 1, -6, -4, -10, -1, -4, -2, -2, -3, 2, -4, 1,
- -5, -4, -4, 2, 1, 1, -4, -1, 3, 1, 6, 2, -2, -2, 3, 3,
- 2, 7, -5, 5, 0, 8, 1, -1, 2, 3, -1, -6, 0, -10, 3, -1,
- -1, -5, -6, -8, -2, 0, -3, -5, -8, -4, 2, -3, -1, -2, 0, -1,
- 7, -1, 3, 2, 4, 7, 3, 4, -1, 5, 1, 9, 1, -2, -1, -1,
- 1, -3, -2, -6, -7, 1, -3, -1, -9, -4, -6, 0, 2, -3, -2, -4,
- -3, 0, -4, -1, -4, 0, 1, 6, -1, 1, -1, 3, 5, -1, 3, 4,
- 5, 7, 4, -2, 0, -2, 0, 3, 1, -1, -8, -2, -1, -2, -5, -1,
- -2, -2, 2, -5, -7, -9, -2, -3, -2, 1, -5, 4, -4, 5, -1, -1,
- -3, 2, 3, 7, 3, -1, 3, 4, -1, 5, -4, 0, 4, 4, 3, 4,
- -9, 1, -5, 2, -2, -2, -3, -7, -1, -2, -2, -5, -3, -1, 1, -2,
- -1, -4, -4, 1, -1, -7, 0, -1, 2, 5, 4, -4, -5, -4, 0, 2,
- 1, -1, 3, 5, 4, 0, 0, -1, 3, 8, 3, 3, -4, 0, 1, 0,
- -2, -6, -2, -4, 3, -2, -3, -5, -6, -3, -1, -1, -7, 0, 0, 3,
- -5, -4, -11, 0, 0, 3, 3, 1, 1, 1, 4, 6, 1, 1, 2, 9,
- 3, 3, -4, -4, -3, 2, -1, -6, 1, -5, 2, 0, -1, -8, -5, -6,
- 1, 0, -2, -1, -2, -1, 2, 0, -9, 0, 5, 4, 7, -3, -3, 3,
- 4, 2, 4, 0, -1, 3, 1, 5, -5, -6, -7, 0, 3, 0, -2, -4,
- 3, 3, -3, -4, -7, -2, 4, 1, -1, -4, -1, -6, -2, 3, -2, -3,
- 1, 4, 1, -1, -4, -3, 3, 4, 5, -2, 2, -3, 4, 0, 3, -3,
- -3, 0, 3, 1, -2, -1, -3, 2, 4, -2, -2, -3, -1, -1, 3, -11,
- -2, -8, 5, -1, 3, -5, -2, 2, -1, 3, -3, 0, -1, -1, 5, -2,
- 0, -2, 3, 2, 3, -2, -6, -3, 2, 4, -6, 5, -6, 1, 2, 3,
- -6, 2, -3, -4, 3, -9, 2, -6, 3, 4, 2, -9, -1, 1, 2, 8,
- -3, -4, -1, -2, 2, -2, 2, -3, 3, -1, 1, 2, -1, -6, 1, 2,
- 2, 1, -2, 2, 3, 1, -3, -6, -3, 0, 1, -3, 0, -3, -1, -4,
- 2, -4, -3, -1, 4, 0, 5, -6, -7, -1, 0, 0, -3, -1, 2, 4,
- 0, 3, -4, -1, 1, 7, 4, 2, -1, -4, 0, 2, -4, -5, -5, -1,
- 1, 4, -5, -4, -6, -3, -2, -3, 2, -2, 5, 2, 3, -4, -2, -5,
- 6, 3, 4, 2, -3, 1, 0, 0, 1, -3, -1, 1, 7, 0, 6, -6,
- -7, -2, -7, 0, -1, 0, 2, 1, -2, -7, -2, -5, 0, 2, 0, -3,
- -5, -1, -3, 0, -1, 0, -6, 8, 4, 5, -1, 1, -4, 1, 1, 4,
- 2, 5, 3, 6, 0, -2, -9, -4, -1, 0, 0, 1, -1, -4, -1, -5,
- -5, -5, 0, 0, 1, -6, -5, -9, 0, -3, 0, -2, 0, 0, 3, 4,
- 2, 1, -7, 1, 3, 4, 9, 1, 4, 4, 2, -4, 2, -2, 1, 5,
- -2, 0, -3, -4, -3, -2, -4, -4, -4, 1, -1, 2, -6, -8, -3, -8,
- -1, -2, -4, 5, 2, 3, -1, 0, -4, 2, -1, 5, 5, -1, 3, 0,
- 3, 3, 0, -4, 9, 4, 2, -1, -6, -4, -2, -2, 2, -7, 0, 0,
- -2, -2, -2, -10, -4, -7, 0, -2, 2, -2, 2, 1, 0, -3, 0, 1,
- 6, 3, 2, 0, 0, -1, 2, 3, -1, 4, -5, 6, 2, -3, 0, -3,
- 0, 1, 0, -5, -6, 1, 0, 1, -5, -2, -14, 0, -4, -1, -1, -1,
- 1, -3, 0, -2, -1, -4, 4, 5, -1, 5, -1, 3, 3, 5, -3, 5,
- -3, 5, 5, 6, 4, -6, 2, -9, 4, -4, 0, 1, -2, -1, -8, -6,
- -11, -2, -3, 3, -6, -8, 3, -5, 1, -3, 1, -3, 1, 3, 5, 6,
- 2, 1, -6, 4, -1, 1, 0, 7, 7, 2, 3, -6, -4, -4, 3, 3,
- 0, 1, -1, -2, -4, 0, -8, -2, -3, 1, -2, 1, -5, -2, -1, -3,
- -3, -4, -3, 7, 4, 1, -1, -6, -5, -3, 2, 5, 8, 3, 3, 2,
- 1, -4, -1, -2, 6, 3, 2, -4, -1, 1, -5, -1, -1, -5, 2, -2,
- 1, -2, -7, -5, -11, -4, -3, 3, -8, 8, 4, -2, -2, -4, -4, -1,
- 4, 3, 5, 5, 2, 4, -1, 6, -3, 6, 2, 3, 0, -4, 0, -2,
- -2, 0, -5, -2, -1, 4, 3, 1, -13, -8, -8, -5, -3, 7, -2, 3,
- -2, -5, -3, -8, -2, -3, 8, 6, 1, -2, 5, 3, 1, 2, 0, -1,
- 2, 4, 3, -5, 1, -3, 0, 1, 7, 1, 2, 3, -1, -4, -4, -10,
- -7, 3, 0, 2, -5, -5, -4, -1, -7, -3, -3, 1, 3, 0, 0, -1,
- -6, 6, 1, 4, 1, 2, 5, 6, 4, -1, -4, -3, 1, 2, 5, 2,
- -1, 1, 3, -8, -1, -10, -2, -5, 0, -1, -6, -10, -7, 2, -2, 6,
- -1, -2, 1, 4, -1, -5, -1, -5, 4, 1, 4, 2, 1, 3, 4, 0,
- -2, 1, -1, 3, 8, 2, 1, -4, -3, -3, 3, -3, -1, -4, 0, -4,
- -6, -2, -8, 1, -2, 5, -6, -5, -6, 0, 3, 1, -6, -3, 1, 2,
- 4, 2, 4, -2, 3, 3, 3, 1, 5, 1, 2, 3, -2, -6, 6, -1,
- 6, -2, 1, -7, -5, -2, -3, -6, -6, -6, -4, 0, -2, -4, -4, -3,
- 0, -1, 1, -3, -1, 3, 1, 1, 0, 6, 4, 8, 10, 5, 0, -3,
- 1, -2, 5, 2, 1, 1, 1, -4, -6, -8, -8, -8, -5, -4, -5, -4,
- -5, 0, -5, -3, 0, -7, 0, 4, 1, -4, -1, -4, -2, 4, 4, 5,
- 6, 6, 7, 0, 0, -1, 0, 2, 9, 2, 1, -3, 0, 1, -3, 1,
- -9, -1, 3, -4, 3, -6, -7, -2, -1, -1, -1, 1, -9, 2, -5, 1,
- -8, -6, -6, 1, -1, 6, 0, 2, 5, 2, 0, 2, 1, 2, 6, 5,
- -2, -1, 0, 4, 1, 6, 0, -2, 1, 0, 3, -7, -1, -13, -4, -3,
- -3, -3, -2, -3, -5, -9, -11, -2, -3, 4, 7, -1, 2, 0, -2, 8,
- 5, 1, 4, 3, 2, 7, 3, -2, -4, 7, 2, 3, -2, 1, -1, 2,
- 0, -5, -4, -4, 0, -4, 0, -1, -10, -9, -3, -5, -8, 1, -5, 3,
- -3, 0, -7, 1, 0, 5, 4, 7, 1, 1, 0, 2, 2, -2, -1, 2,
- 1, 4, 6, -1, 4, 3, -1, 4, -2, -3, 3, -1, -2, -6, -6, -7,
- -3, -1, 0, -4, -6, -5, -6, 0, -3, 3, -5, 7, 0, -1, 1, -3,
- -1, 1, 6, 3, -3, 7, 1, 10, 1, 6, -1, -2, 5, 2, 1, 1,
- -4, -2, 0, -3, -7, -2, -4, 4, -8, -8, -4, -10, -2, 2, -4, 1,
- -5, -7, -1, 3, -1, 1, 1, 4, 6, 2, 2, 0, 4, 7, 0, 5,
- -2, 0, 3, 3, 3, -3, -1, -5, -2, 0, 3, -4, -6, 2, -1, 0,
- -2, -4, 0, -4, -3, -9, -3, -4, -4, 0, 3, -1, -4, 3, 1, 5,
- -2, 1, 2, 2, 4, 5, -3, 2, 1, 3, 7, 1, -5, 1, 0, 5,
- -3, -2, -3, -4, 0, -3, -2, -5, 0, -8, 3, -6, -4, -6, -2, 2,
- -4, -2, -3, -2, 1, 4, 2, 3, -2, 2, 4, 1, 4, -2, 3, 2,
- 1, 1, 7, -1, 2, 4, -4, 2, -4, -2, 5, -4, 3, -1, -3, -2,
- 3, -8, -4, -6, -3, -3, -1, 0, -6, -1, 0, 1, 1, -2, -10, -3,
- -1, 0, 2, -5, 1, 1, 2, 10, 8, 2, 8, -1, -2, 4, -5, 2,
- 2, 7, 6, -6, -1, -5, -4, -3, -6, -7, 0, -5, -5, -1, -2, -5,
- 0, -4, 6, -6, 0, 3, -3, 4, 0, -6, 2, 5, 5, 4, 10, 0,
- 2, -3, 3, -2, 0, 3, -3, 2, -3, -8, -8, -5, -1, -1, -1, 0,
- -5, -2, 0, -3, -4, -1, -5, -2, 5, 0, 5, -4, 4, -1, -1, 1,
- -3, 3, 9, 2, -1, 1, -6, -3, 7, 1, 3, -2, -4, 0, -1, 3,
- 1, -3, 4, 6, 0, 1, 2, -3, 0, 0, -5, -13, -4, -2, 1, 2,
- -3, -10, -4, -7, 1, -2, -2, -1, 0, 1, 1, -4, -1, 2, -2, 7,
- 1, -3, 0, 0, 4, 5, 2, 2, -1, 6, 9, 1, 3, 1, -5, 5,
- -6, -5, -2, -4, -2, 2, -7, -4, -11, -5, 3, -3, -6, -4, -6, 3,
- 3, -3, 2, 0, 1, -3, -1, -2, -4, 1, 10, 8, -2, 4, -3, 6,
- 6, 1, 0, -7, 2, -2, 1, 3, -4, -4, 4, 1, 0, -2, -5, 2,
- -2, 0, -7, -11, -5, -2, -2, 5, -1, -8, -1, -1, 1, 2, -2, -1,
- 1, 1, 5, 0, -3, 5, 1, 6, 1, -1, 3, 1, 6, -3, -1, -1,
- -3, 4, 12, -1, -1, 2, -4, -1, -6, -8, -7, -3, -2, 1, -9, -5,
- -6, -10, 5, 1, -2, -3, -2, 5, 4, 3, -1, -5, 4, 6, 3, 4,
- 6, -2, 7, 0, -4, -1, -1, 9, 8, 2, 2, -8, -3, -3, 0, -2,
- 0, -4, -2, 0, -6, -7, -14, -6, -5, -1, 3, -6, -2, 1, -3, 0,
- -4, -5, 1, 5, 9, 4, 0, 3, 0, 1, 12, 0, 4, 8, 5, 7,
- -1, -4, 0, -3, 5, 4, -4, 0, -3, -13, -2, -10, -14, -3, -5, 2,
- 1, -3, -4, -8, -8, -3, -2, -2, 3, 4, 8, 0, 2, 1, 2, 12,
- 5, 3, 8, 2, 6, 3, -4, -4, -2, -8, 8, -5, -2, -6, -10, -2,
- -6, -4, 0, -4, 2, 5, 1, 0, -4, -4, -1, -1, -3, 4, -7, 4,
- 3, -3, 4, -4, -3, 8, 4, 7, 0, 0, 2, -1, -2, -1, -2, -7,
- 11, -1, 5, -4, 2, -2, 0, 2, -2, -4, -2, 1, -5, 3, -6, -9,
- -3, -3, -2, -5, -5, -2, -6, -2, -7, -8, 1, 3, 5, 9, 4, 4,
- 0, 5, 8, 1, 3, 7, 5, 10, 11, -7, 3, 0, -3, 1, -1, -7,
- -7, -3, -2, -6, -9, -6, -12, -4, -1, 0, -8, -5, -3, -3, -2, 3,
- 1, 1, 9, 4, 2, 5, -1, 2, 6, 2, 0, -3, 2, 2, 5, 2,
- -1, -4, 4, 1, 1, 2, -5, -8, -1, -3, -1, -9, -4, 1, -4, 5,
- -6, -4, 0, 3, -9, 3, -3, -5, 1, 4, 4, 1, -4, 1, -4, 4,
- 1, -6, 0, 5, 7, 8, 1, 6, 0, 3, 4, 2, -3, 1, -3, -3,
- 3, -9, -6, -7, -2, -1, -3, -5, -6, -5, -5, -6, -5, 4, -3, 5,
- 5, -2, -1, -1, -3, 6, -2, 5, 6, 2, 11, 8, -1, 3, -6, -2,
- 5, 4, -3, -3, -5, -3, -7, -5, 0, -5, 2, 1, 0, 1, -7, 0,
- -3, -2, -1, -2, -5, 7, -4, -2, -3, -2, -3, 4, 4, 9, 0, 1,
- 1, -5, -3, -4, -4, 4, 3, 6, 0, -2, -2, -6, 4, 1, 1, -3,
- 3, -1, 2, 0, -7, 0, 0, -1, -3, -2, -1, -5, -2, -3, -8, -5,
- -5, -1, 5, 5, 2, 2, -3, 4, 3, 3, 6, 3, -1, 10, -4, -3,
- -2, -3, 0, -4, 0, -2, -2, 0, 1, -4, -2, -5, -9, 8, -2, -1,
- -1, -3, -3, -2, -6, 2, 1, 2, 9, 0, 1, 3, -4, 2, 4, -6,
- -1, 2, -1, 6, 3, 0, -5, -3, -1, 0, 3, -3, 0, -6, -2, -3,
- -4, -2, 0, 3, 2, 2, 0, -10, 1, -6, -5, -1, -2, 5, 3, 6,
- -2, -6, -1, -3, 2, -1, 0, 0, -1, 0, 0, 0, 1, -2, 2, -2,
- -5, -1, -2, 16, 12, -18, -10, 3, -14, -10, 16, -1, -3, -16, 28, 3,
- -1, -1, 12, -5, -6, 6, 7, -7, -18, -28, 11, 0, 6, -2, 26, -21,
- -10, -1, 24, -3, 20, -19, 15, -14, -3, -3, 15, -35, -2, 6, -14, 30,
- 6, -36, -8, 17, 0, -27, 26, 16, -38, 8, -14, 57, 3, -31, -14, 34,
- -20, 33, 2, -6, -7, -28, 20, -24, 8, 13, 8, -39, 17, 40, -42, -11,
- 13, -46, 1, 28, -22, 11, -3, -14, 5, 20, -12, -4, 49, -22, -24, 39,
- -11, -1, -9, 37, -30, 13, 34, 4, -11, -25, 18, -22, 1, 29, -17, -3,
- -26, -16, -21, 12, -18, 7, -17, -6, 51, 0, -21, 10, 24, -45, 8, 14,
- 31, -10, -37, 6, 0, 24, 3, -18, -13, 14, 11, 0, 7, -1, -38, -29,
- -21, 32, -30, 22, -26, 14, -40, 55, -36, 30, -12, 8, 31, -16, 19, -15,
- 23, -48, 36, 1, 63, 3, 24, 0, -3, 14, 26, -21, 15, 47, -21, -80,
- 14, -4, -25, -33, 11, 25, -35, -44, 13, -2, -48, -11, -23, -7, 27, -4,
- -15, -22, 5, 26, -36, 50, 23, 11, -23, -14, 19, 32, 14, 38, -66, 56,
- -11, 26, 18, -12, 17, -30, -6, -54, 22, 77, -62, -12, -16, 34, -25, 2,
- 14, -62, 12, 20, -22, -50, 58, -29, -58, 4, 28, 30, 13, 25, -78, 38,
- 45, -19, -7, 52, -61, 27, 17, -21, -4, 6, 37, -24, -38, 73, 8, -16,
- 21, -2, -15, -19, -19, 18, 3, 7, -48, -10, -10, 10, 4, 13, -13, -4,
- 0, 46, -12, 6, -18, -25, 4, 14, 27, -22, -37, 14, -6, -17, 55, 40,
- -111, 63, 9, -38, -16, 46, -35, 4, 0, -10, -8, -12, 58, -69, 1, 66,
- -38, 21, -33, -6, 10, 0, 10, -11, 18, -16, 32, -7, -10, -25, 65, -42,
- 42, -62, 18, -3, -2, -8, 21, 4, -71, 13, 40, -3, 18, -19, -29, 15,
- -66, 60, -50, -6, 67, -80, 17, 66, -21, -20, -15, 68, -16, 72, -4, -23,
- 4, 53, -8, 8, -4, 0, 27, -26, -22, 25, -31, 7, -39, -18, 27, -43,
- -25, -33, -6, 17, -16, 0, -55, 6, 26, -3, -67, 7, 60, -83, 25, 15,
- 45, -8, 51, -55, 28, 42, 42, -17, 37, -6, 17, 8, 11, -1, 59, -7,
- -45, 14, -41, 107, -49, -50, -25, 63, -58, -27, -57, 19, 13, -13, -27, 19,
- -42, 63, -113, -1, 44, 8, 1, -10, -33, 0, 55, -41, 15, 0, 76, -17,
- -39, 60, -20, 28, 54, -93, 15, 83, -30, 4, -56, 49, -58, 30, -28, 2,
- 54, -64, 83, -128, 86, 24, -40, -27, -66, 51, 11, -51, 59, 6, 20, -58,
- -24, 78, -7, -23, -27, 1, -3, -24, 10, -6, -16, 34, 39, -37, -17, 26,
- 52, -69, -7, 11, 24, -62, 38, -13, 41, 5, -2, -5, -12, 15, 77, -49,
- -10, 74, -12, -11, -38, 32, -24, 25, -6, 19, -24, -2, -38, 63, -91, 64,
- -27, -11, -56, -43, 27, -41, -55, -15, 1, -4, 27, 8, 37, -57, 3, 28,
- -11, -4, 46, -39, 3, 12, 100, -33, 39, 17, 6, 49, 5, 38, -12, 10,
- 21, -35, 23, -6, -36, 10, -9, 3, -1, 13, -65, -40, 36, -25, -28, 5,
- -37, -20, -14, 31, -16, -32, -16, 4, 15, -11, 26, -16, 29, -42, 46, 7,
- 39, -1, -5, -9, 33, -31, 35, -33, -7, 17, 56, -24, 22, 14, -22, -34,
- 44, 16, 11, -46, 43, -48, -27, 43, 36, -45, 21, 11, 0, -98, -22, 87,
- -126, 52, -45, 34, -28, -17, -31, 23, -38, 23, 25, -11, 25, -63, 21, 13,
- 19, 47, 28, -23, 20, 21, -5, -14, 112, -30, -67, 37, 43, -12, -57, 34,
- -9, -29, 52, -19, 14, -51, 0, 26, -69, 3, -18, -24, -34, 31, -15, -33,
- -36, 10, -20, -38, 63, 0, 44, -50, 72, 25, -16, -6, 6, 15, 23, 31,
- 3, -20, -9, 19, 63, 17, -18, -5, -12, -87, 31, 26, -37, -29, 49, -42,
- -15, 14, 11, -16, -31, 46, -19, -13, -37, 59, -91, 47, 4, -11, -26, 39,
- -29, -24, 48, 10, 39, -11, 45, -51, -1, -24, 47, -19, 39, -34, -29, -17,
- 1, 56, -25, -16, -13, 0, 48, -71, 49, 2, -2, -45, -10, 59, -17, -25,
- 9, 9, 44, 42, -32, -23, -49, 46, -11, -50, 76, -43, -45, -1, 41, -8,
- 2, 71, -36, -61, 35, 21, -13, -36, 44, -45, 26, -45, -21, 28, -37, 39,
- -29, 15, 4, -5, 24, -7, 7, 3, 68, -80, 26, 24, -22, 8, 26, 28,
- 10, -26, -3, 16, -51, 85, -8, -14, -54, 39, -28, -9, -25, 46, -39, -20,
- 34, 11, -25, -7, -12, -41, 12, -17, -5, -43, -8, 0, 18, 13, 9, 28,
- -40, 34, 0, 13, 40, -20, 5, 22, -25, -13, 51, 9, -34, 43, -16, -18,
- 2, 35, -4, -28, 14, -37, 6, -8, 31, -49, 9, -31, 61, -55, 35, -46,
- -37, -12, 32, 74, -59, -30, -21, 5, 38, 3, 48, -35, -42, 2, 29, 81,
- -8, -37, 24, 42, -31, 18, -11, -21, -67, 98, -18, 11, -26, -14, -76, 11,
- 71, -70, 30, -52, 37, -45, 61, 6, -33, -44, 58, 24, -16, -51, 49, -28,
- 51, -6, -15, 46, 10, -24, 36, -4, 6, -30, 46, -66, 54, 27, -16, -34,
- -23, 90, -61, -49, 22, -3, -22, 17, -35, -11, -59, 23, 2, -25, 69, -24,
- -26, -28, 37, 12, 11, -63, 27, 18, 3, 34, -25, 9, -14, 29, 4, 24,
- 21, -77, 12, 14, 37, 1, 45, -63, 1, 49, -14, -23, -7, -4, -42, 48,
- -57, 18, -36, 17, 15, -37, 47, 1, -41, -14, 11, 49, -32, 32, -36, -19,
- 21, -11, 39, -31, 43, 0, -24, 15, 6, 9, -46, 5, 21, -23, 2, -28,
- -15, 59, -13, -29, 50, -7, -45, -12, 23, -1, 27, 6, -17, 7, -4, -3,
- -3, 53, -10, 17, -52, 19, 24, -8, -7, 19, -51, -30, 55, -22, -22, 29,
- -38, -25, 39, 3, 34, -84, 26, -37, 42, 15, 4, -4, -16, -33, 29, 17,
- 43, -93, 24, -6, -20, -14, 107, -29, -36, 69, -21, 10, -7, 74, -67, 38,
- -23, -8, 27, -35, -49, 29, -8, -4, 7, -8, 5, -38, -28, -33, 22, 70,
- -37, -10, -56, 26, 5, 7, 59, -21, -58, 10, -2, 6, 49, -16, -9, -38,
- 60, 13, 43, -43, 23, -14, -9, 38, 17, -38, -15, 29, 6, -5, -11, -3,
- -4, -65, 45, -13, 26, -13, -4, -5, -38, 48, 0, 4, -40, 40, -48, 23,
- 21, 23, -42, 5, -17, 13, -9, 12, -3, 5, -25, 34, -24, -3, -18, 16,
- -44, 13, 27, -30, 44, -54, 6, -18, -3, 4, 21, -25, -13, 22, -20, -12,
- 37, -10, -10, 5, 24, -17, 23, 9, 0, 4, 3, 12, 26, -27, 17, 9,
- -41, 69, -1, 15, -37, 15, -6, 0, -1, 3, -13, -23, -18, 27, -5, 21,
- -16, -41, -2, 20, 13, -27, 6, -21, 8, 6, 0, 6, -5, -21, -22, 73,
- -40, 4, 6, 21, -8, -5, 29, -47, -1, 1, 19, 3, -10, -1, 2, -48,
- -11, 45, -27, 11, -33, -21, 21, 7, 12, -22, 21, -40, 13, 27, -20, 37,
- 5, -18, -18, 35, 40, -11, 20, -25, 10, -4, 33, 12, -29, 9, -20, -30,
- 34, 24, -9, -10, -24, -16, 8, 22, 6, -58, -5, -13, 18, 5, -43, 10,
- -16, -25, 13, 70, -25, -7, -25, -19, 16, 58, -46, -5, 6, -5, 40, -24,
- 22, 50, -73, -7, 7, 32, 39, -27, -23, -23, 56, -35, 21, 17, -40, 40,
- -52, 4, 0, 49, -29, -42, 24, 9, 31, 2, -46, 0, -9, -5, 9, -31,
- 64, -5, -45, -26, 42, -4, -34, -8, -3, 32, -15, -8, 22, -24, 13, -31,
- -2, 31, 10, -10, -18, 8, 24, 20, -29, 2, 14, 23, 25, -4, -19, 20,
- -25, -5, -3, 23, -8, 52, -42, -17, -7, 29, -26, 2, -19, 55, -50, -28,
- 1, -10, -7, 7, -41, 16, 21, 1, -20, 0, 16, -19, 14, -39, 86, -17,
- -34, -64, 73, 0, 20, -28, 30, -22, 9, 58, -4, -8, -18, -20, 31, -21,
- 1, 26, -49, 5, 41, -25, -13, -6, -7, 6, 10, 42, -30, -26, -43, 11,
- 44, -54, 31, -10, -11, -17, 25, 32, -43, 64, -23, 3, -37, 33, -30, -4,
- -35, 47, -29, 9, 23, -34, -5, 64, -37, 32, -11, -44, 21, 25, -19, 8,
- 6, -25, 34, 2, -18, -23, 38, 20, 7, 21, 1, -32, -37, 50, -9, -25,
- 34, -61, 55, -32, 7, -48, 20, 13, 0, -35, 17, 9, -42, -28, 14, 42,
- -33, -25, -5, 21, 41, -60, 32, -7, 38, -9, -3, 20, -4, 29, -69, 62,
- -16, 35, -64, 45, 10, 5, -1, -18, -18, -1, 5, 32, 0, -21, -12, -23,
- 29, -15, 13, -39, -3, -3, 6, 35, -24, -23, -7, -2, 44, -10, -37, 25,
- 25, -25, -23, 7, 40, 4, -40, -18, 21, -2, -3, 1, -16, 45, -26, -2,
- -16, 18, 41, -64, 8, -26, 40, 5, -32, 8, 18, -1, 15, -1, 9, 2,
- 2, -13, -12, 35, -9, 13, -62, -29, 72, 18, 7, -30, 26, -7, -29, 39,
- -38, 31, -56, -25, -3, 17, 2, -3, -46, 35, 6, 27, -39, -3, 3, 31,
- -25, -19, -2, 38, 26, -77, 22, 18, 40, 3, -22, 65, -48, 33, -16, -37,
- 78, -34, 1, -52, 23, 16, 1, -37, 17, 12, 1, -4, 8, -27, -1, -11,
- -18, 27, -23, -10, -11, -19, -6, -7, 51, -74, 16, 20, 17, -14, 7, 7,
- -13, -8, -5, -11, 39, 21, -5, -44, 31, 64, -38, -18, 20, 40, -4, -10,
- 10, -23, 23, -6, -20, 11, 9, 10, 6, -23, -11, 1, 17, -56, 56, -40,
- 0, -17, -60, 84, -80, 16, -13, 4, -25, 12, 17, -42, -26, 54, -29, 12,
- -5, 37, 16, -62, 94, -5, -2, -2, -2, -9, 5, 51, -25, -5, -11, 5,
- 16, -14, -9, 43, -44, -8, 27, 2, -1, 9, -18, -6, 5, 23, -46, -9,
- 13, 16, -10, -10, -23, 59, -47, -14, 23, 29, -15, -14, -30, 21, -21, 0,
- 14, -3, 25, -16, -35, -2, -8, 32, -19, 22, -23, -37, 30, -33, -19, 11,
- 12, -32, 47, -4, 27, 11, 9, -35, 39, 29, -18, -2, -11, 27, -2, 13,
- 0, 18, -26, 15, -25, 26, -4, 21, -29, -33, 18, -8, -31, -5, 21, -1,
- -38, -28, 41, -18, -4, -22, 47, -12, -44, 55, -79, -5, 19, -10, 25, 4,
- 21, 15, -28, 13, -6, 45, -24, 25, 10, -26, 4, 2, 31, 3, -7, 3,
- 5, -23, 51, -9, -32, -5, 35, -32, -21, -20, 35, -40, -10, 20, -8, 7,
- -5, -38, -1, -24, 39, -26, 20, -16, -9, -27, 25, 34, -32, 1, 12, -13,
- 3, 37, 13, 3, -31, 27, 30, 5, -15, -21, 2, 10, -13, 16, 36, -9,
- -59, 41, -10, 61, -60, -35, -11, 7, 5, -28, 30, 5, -23, -66, 34, 50,
- -26, -19, -10, 11, 8, 8, -35, -5, -11, 56, -24, 10, 35, 16, -10, -19,
- 30, 4, -11, 23, 0, -6, 6, 36, -15, 0, 15, -14, -26, -8, -5, 15,
- -31, -45, 42, -30, 0, -9, 6, -22, 9, -22, 7, -8, 15, -19, -3, -13,
- 29, -14, 9, -16, 3, -5, -10, 63, 0, 4, 4, 20, 16, -21, 18, 31,
- -24, -19, 31, 54, -39, -7, -16, 5, -3, 0, -29, 16, 6, -29, -25, -52,
- 49, -9, -66, -3, 50, -3, -2, -14, 4, -8, 33, -40, 2, 15, -6, -17,
- -4, 10, 48, -16, 14, -9, 27, 10, 2, 2, 40, -35, 5, -10, 7, 28,
- 1, 4, -30, -4, 0, 1, -14, -13, -11, 26, -17, 13, -44, -9, -6, -23,
- 17, 11, 11, -21, -11, 0, 9, 8, 8, -30, 29, 10, -26, -12, 15, 17,
- 4, -26, 14, 19, 20, -9, -24, 39, 23, -10, -35, 8, -6, 18, -25, 15,
- -17, 41, -48, -31, -5, 47, -14, -20, -4, -7, 5, -19, 3, 21, 12, -23,
- 15, -24, 8, 3, -25, 2, 28, 14, 21, 25, -72, 15, 26, -6, 45, -27,
- 29, -30, -17, 23, 6, -2, 27, -46, 13, 9, 15, -57, 27, 1, -18, 1,
- -11, -2, -20, -16, -23, 24, 18, -21, -5, -15, -14, 26, -12, 30, -48, 37,
- -24, -3, 23, 9, -5, 9, 8, -43, 23, 26, 6, 28, -29, 30, -8, -12,
- 25, -18, 33, -48, -4, 29, 1, -8, -4, -20, 41, -22, 1, 12, -33, 0,
- -17, -16, 29, -3, -2, -36, 6, -1, -11, 4, -24, 40, -24, -5, 26, -2,
- -28, 13, -11, 35, -9, -2, -3, -6, 13, 10, 1, 11, -22, 22, -27, -5,
- 20, 11, -1, 8, -23, 8, 7, -7, 17, -6, 16, -9, -10, 3, 13, -3,
- -17, 19, -21, 6, -13, -15, -7, 22, -15, -7, 11, -20, -19, -6, 0, 28,
- -10, -7, -13, 9, 7, 1, -11, -6, 21, -33, -4, 52, -11, -1, -2, -2,
- -4, 32, 17, -31, 7, 12, 2, -5, 11, -1, -6, 1, 3, -11, 5, 4,
- -15, -8, 10, 5, -18, 5, -26, -11, 22, -15, -23, 22, 19, -30, 3, 1,
- -5, 10, -17, 10, -2, 10, 7, -17, -5, 36, -12, -24, 27, 22, -3, -11,
- -6, -7, 20, 5, -21, 0, 23, -31, -27, 14, 2, 8, 7, -15, 0, 13,
- -7, -3, -21, 33, -4, -26, 7, 5, -7, -7, 1, 3, 4, 11, -24, 6,
- 11, -7, 14, -9, -11, -1, 34, -22, 11, 1, -18, 17, 4, -19, 28, -15,
- -7, -11, 12, 1, -7, -9, -12, 17, -20, 6, 5, 2, -10, 12, -23, -3,
- 26, -1, 4, 6, -25, 12, -3, -26, 2, 15, 14, -18, -6, -17, 14, 4,
- -10, 21, -13, 5, -15, -20, 27, 6, 8, -11, 18, 15, -34, 17, -2, -13,
- 41, -9, -10, -6, -2, 7, -11, -4, 28, -26, -6, 25, 17, -36, -2, 33,
- -39, -15, 11, -2, 26, -32, -31, 21, 26, -11, -24, 12, -17, 4, -33, 24,
- 14, -10, 12, -19, -3, 28, 11, -8, 0, 26, -17, -7, 8, -6, 20, 26,
- -29, -27, 25, -14, -2, 10, -16, 39, -24, -17, -4, -13, 24, -10, -3, -20,
- 25, -1, -24, 24, -20, -5, 21, -26, 7, 21, -26, 15, 17, 6, -34, 5,
- 11, -27, 20, 17, -13, -8, -16, 9, 33, -36, 19, 5, 4, -2, -33, -12,
- 38, -17, -10, -4, 19, 14, -4, -32, -41, 64, 5, -38, 28, 6, -2, -11,
- -22, 11, 17, 17, -24, 23, -7, 9, 10, -38, 0, 25, -9, -6, -27, 20,
- 2, -27, 34, -23, 17, -22, 4, 12, -43, 29, -8, 25, -19, 13, -17, -11,
- 27, -8, 14, -19, 12, 9, -22, -6, 11, -10, 17, -4, 2, -3, 15, -47,
- 32, -18, 11, 14, 0, 8, -33, -14, -12, 23, 17, -12, -4, 13, -27, 10,
- -17, 20, -2, -11, -11, 27, 18, -21, -6, 26, -18, 9, -7, 27, -12, 3,
- -9, -9, 22, 7, -38, -2, 14, -16, 12, -21, -10, 22, 1, -28, 20, 31,
- -11, -49, 9, 16, -4, -7, -4, -5, 46, -39, 9, -18, 16, 22, -24, -13,
- 14, 29, -10, 3, -23, 4, 11, -33, 30, 18, -9, 5, -11, 4, -20, 30,
- -9, -14, -7, -9, 4, 0, 4, -15, -11, 23, 5, -24, 26, -6, -8, -17,
- 21, 0, 3, 13, -10, -13, 19, -16, -10, -5, 10, 8, 22, -19, 4, -8,
- 0, -24, 38, 12, -33, 10, -9, 5, -13, 11, 3, 7, -18, -12, 11, -4,
- 8, -17, -7, 16, -9, -2, -9, 0, 10, -2, -1, -1, 12, -6, 13, -18,
- 18, -6, 10, 1, -3, 9, -2, -30, 23, -9, 29, -11, -31, 10, 6, -21,
- -19, 54, -30, 18, -12, -26, 23, -10, -31, 23, -5, 49, -34, 4, -18, 3,
- 11, -24, 27, 12, -24, 3, -13, 3, 16, -6, -7, 1, 19, -8, -3, -11,
- 13, -14, 19, 10, 17, -21, 14, -40, 12, 13, -5, -3, 21, -14, -29, 16,
- -24, 1, 10, -1, -3, 6, -15, -16, 16, -4, 2, 23, -32, -1, 7, -5,
- 13, 4, -15, 33, 1, -7, -7, -12, 13, 6, -8, 2, 21, 2, -21, 17,
- -14, -19, 36, -2, -16, -4, 3, 9, 15, -39, 3, 9, -10, -3, -12, -7,
- 28, -19, 8, -18, 22, -18, -11, -2, 17, 23, -15, -24, 11, 13, -14, -10,
- 9, 4, 14, -10, -13, 13, -3, -12, 25, 6, -12, 12, -19, -3, 19, -10,
- -13, 19, 10, 18, -31, -15, 19, -9, -14, -6, 25, -18, 2, 17, -41, 11,
- 16, -20, 3, -10, 16, 9, 14, -27, -1, -3, 9, -19, 36, -6, -4, -4,
- -16, 5, -7, 24, -1, -30, 13, -8, -4, -9, 47, -37, 3, 21, -24, 1,
- 3, 11, 5, -10, -8, 20, -31, 16, 10, -1, 0, -9, -1, -6, 14, -6,
- 6, -17, 20, 3, -23, 10, -14, 17, -16, -2, 26, 7, -20, -10, 9, -18,
- 31, -35, 3, 14, -8, 13, -27, -4, -4, 26, -20, -9, 14, 22, -27, -4,
- 18, 9, 9, 3, -13, -20, 15, -13, 6, 12, -5, -6, -12, 0, 4, -10,
- 18, -7, -8, -15, 1, -11, 17, 5, -11, 14, -6, -11, 4, 10, -5, 13,
- 0, -7, 15, -2, -16, 2, -3, 9, -6, 2, 34, -11, -17, -8, 21, 13,
- -21, -4, 14, -7, -7, -19, 13, -7, 4, -25, 7, 16, -14, -40, -11, 36,
- 3, -10, 4, -10, 7, -1, -1, 4, 14, 6, -14, -14, 17, 23, -13, -2,
- -1, -12, 9, 8, 1, -7, 22, -29, 7, 7, 0, -24, 13, -10, 18, -1,
- -3, 13, -24, 30, -32, -5, 18, -2, -6, -8, 11, -18, -12, 17, -11, 0,
- 5, -4, -14, 31, -15, -16, 13, 12, -4, 4, -4, -1, -11, -15, 26, -18,
- 29, -15, -3, -8, 6, 6, -34, 22, 0, 11, -18, 16, 20, -19, -21, -5,
- 11, 21, 10, 10, -27, -5, 3, 2, -5, 9, -9, -1, 1, -11, -3, 8,
- 4, 1, -1, -11, 19, -1, -21, -5, -2, 11, -2, -8, 10, -7, -1, 2,
- -18, 3, 0, 7, 2, 7, 1, 1, -28, -14, 10, 19, 12, -21, 7, -19,
- 20, -2, -3, -1, 17, -11, -13, -16, 32, 4, -5, -3, 4, -4, 18, -2,
- -17, -6, 16, -3, 4, -12, 4, -2, 2, 6, -18, 20, -24, 17, -10, 19,
- -16, -17, 8, -7, -5, 16, -12, -18, 11, 9, 2, -8, 17, -9, -3, -13,
- 7, -6, 30, -15, -11, 5, 14, -2, -15, -5, 14, 13, -12, -24, -10, 22,
- -2, -8, -1, 21, -5, -19, -16, 8, 42, -6, -27, -12, 23, 10, -17, -14,
- 16, 14, -16, -2, 9, -2, 16, -9, -31, 22, 0, -2, 3, 4, -5, 20,
- -24, -5, 13, -1, -5, -10, -6, 8, -11, 2, 8, -8, -5, -9, 1, -6,
- 16, -1, -18, 4, 9, -3, 6, -4, 6, 9, -7, -9, -1, 10, -7, 4,
- 3, -3, 4, -8, -5, 3, -4, 10, 6, -15, 2, 3, -5, -2, -3, -12,
- 18, 2, -16, 7, 13, 0, -19, -8, 11, -6, -1, -9, 5, 13, -8, -6,
- 6, 7, 11, -11, -6, 13, -2, -5, -1, 9, -2, -7, -15, 10, 5, -1,
- -13, 8, 0, -6, -2, -2, 18, -16, -7, 2, 3, -4, 6, -11, 4, 6,
- 1, -5, 22, -11, -5, -6, -3, 11, -1, -1, 4, 1, -4, -13, -4, 11,
- -9, 1, 9, -1, -8, 1, -5, -7, 5, -14, 18, -1, -12, 11, -12, 16,
- -5, -11, 11, -2, 15, -7, -18, -10, 0, 18, -12, 8, 3, 6, -16, -3,
- 3, 6, 0, -1, -3, 4, 9, 3, -17, -7, 11, 11, -19, 5, 15, -12,
- -3, -12, 4, 11, -19, 0, 0, -14, 21, -15, 2, 8, 3, 8, -8, 5,
- -18, 9, -2, -8, 23, -5, -16, 5, 3, -20, 13, 11, -6, -15, 5, 4,
- -12, 2, 10, -5, -12, 5, -14, -2, 18, 11, -14, 0, 28, -10, -20, 4,
- 7, 9, -13, -6, 15, 11, -9, -6, 14, -8, 10, 4, -12, 11, -18, 13,
- -17, -9, 16, -4, -14, -7, 17, -24, -5, 4, 6, -6, 14, 2, -24, -22,
- 11, 13, 8, -16, 6, 13, -28, 10, -2, 11, 8, -1, -8, -14, 22, 3,
- -5, -13, 18, 7, -26, 15, 20, -6, -10, 4, 11, 5, -8, -3, -5, 0,
- -1, -6, 0, 4, 4, -14, -1, 1, 8, -14, -10, -4, 6, 4, -8, 3,
- -9, 0, 11, -4, -7, 5, 4, 6, -29, 18, 22, -19, -16, -11, 17, 7,
- -4, 3, -23, 20, 8, -19, 3, 13, 13, -16, -18, 15, -6, 0, 3, 17,
- -7, -4, 2, -22, 21, -1, -2, -1, -15, 13, 3, -7, 4, 0, -7, 8,
- -7, 11, 3, -2, -8, 10, -15, 0, 9, -14, -8, 8, -2, -9, 10, -13,
- 9, 7, -6, 2, -12, -4, 6, -12, 8, 12, 3, -10, 6, 7, 1, -2,
- -11, -1, 7, -7, 8, -13, -10, 11, -9, -10, -8, 20, 9, -11, 8, -5,
- -4, 6, -3, 5, 13, -13, -7, -7, 6, 19, 0, -9, 9, -1, -3, 4,
- -7, 0, -2, -4, -5, 5, 0, -5, 14, -19, -14, 18, -1, -5, 3, -12,
- 18, -19, 4, -15, -10, 10, 10, -17, -4, 19, -6, -2, 5, 11, -4, -3,
- 9, -22, 28, -6, -5, 0, -1, 11, -11, -13, 22, 3, -8, -9, 1, 3,
- 0, 1, 2, 7, -5, -25, 10, 6, 6, 2, -11, 8, -16, 15, -20, 5,
- 9, -6, -13, -5, 14, 6, -21, 22, -7, -14, 4, 26, -8, -13, 8, 1,
- -10, -13, 11, 10, -10, 2, -13, -9, 15, 0, 10, -30, 14, 7, -13, -5,
- -12, 8, 10, -4, 10, 12, -15, -7, 5, 2, 2, 10, -13, -3, 0, 21,
- -2, -16, 9, 3, -1, 6, 15, -3, -21, 10, -8, 5, 1, 1, 2, -19,
- 10, -7, -3, -1, 8, 6, -26, -10, 18, -28, -3, -3, 4, 0, -7, 6,
- -10, -2, 25, -19, 5, -11, -2, 14, 4, -5, -3, 4, -5, 6, -2, -3,
- 11, -1, 13, -12, 5, 20, -15, -3, 17, 4, -14, -5, 11, 3, 1, 6,
- 11, -20, 10, -4, -4, -4, -4, -18, -7, 5, 10, -25, 7, -9, -15, 1,
- -4, 4, 4, -4, -1, -18, 9, -6, 4, 7, -19, 10, 0, 3, -6, 12,
- 18, -5, 2, 4, -4, 11, 2, 5, 2, 1, 3, -4, 3, 4, -3, -2,
- -8, 11, 5, -10, -12, 12, -6, 6, -9, -6, 4, 9, 0, -9, 4, 3,
- -7, -5, -12, 19, 2, -28, 1, 0, 9, -10, -6, 3, 3, -11, -4, 6,
- 7, -7, -3, 5, -12, 9, 10, -12, 7, 5, 5, -6, -9, 16, 6, -16,
- 3, 8, -17, 12, -5, 2, 1, 21, -25, -10, 5, -2, 15, -6, 1, 3,
- 5, -16, -2, -16, 32, -17, 7, -13, 6, -1, -4, 0, -4, 10, -2, -17,
- -7, 29, 0, -13, -1, -1, 2, 12, -4, 3, -2, 4, -19, -1, 18, 2,
- -3, -15, -2, 10, -4, 1, -2, -5, 20, -5, -6, -7, 9, 0, -2, -24,
- 5, 15, -2, -11, 1, 0, -2, -14, -2, -4, 7, 4, -4, -9, 2, 4,
- -8, 8, -1, 2, 10, -13, 4, 10, -4, 27, -22, 17, -18, -2, 5, 8,
- -1, 4, -6, 2, -1, 9, 1, -3, 16, -21, -18, 2, 10, -14, 9, 3,
- -14, -9, 0, -16, 9, -10, 11, -12, -3, 1, -10, 3, -2, 2, -13, 13,
- 10, -1, 4, 4, 1, -3, 9, 0, 4, 8, -14, 10, -4, 0, 8, 11,
- -2, 2, -11, 3, -13, -8, 11, 4, 1, -7, 4, -21, 0, 1, -4, -22,
- 17, -8, -16, 10, 4, -2, 0, -4, 2, -2, 2, -6, 10, 3, 3, 5,
- -1, 6, 5, 2, -6, -3, -2, 7, -4, -4, 12, 1, -30, 12, -7, 3,
- 4, -6, -7, -9, 9, -1, 7, -10, 12, -16, 2, -8, 23, -5, -5, -1,
- -8, 10, 3, -14, -12, 25, 7, -13, -6, 4, 15, -3, -23, 9, 12, -9,
- -13, 18, -9, 5, 1, -17, -4, 13, -10, 11, -10, -1, 6, 0, -7, -2,
- 9, -4, 9, -24, 7, 6, -5, 4, 15, -15, 11, -5, -24, 9, 11, -16,
- 2, 0, -9, -2, 10, 7, -12, 8, -12, -6, 10, 6, 10, -14, -5, 20,
- -16, 7, 8, -1, -19, 24, 2, -10, 15, 6, -6, -21, 3, -3, 15, -9,
- -3, 3, -2, -4, -3, -9, 5, 0, -5, -3, -15, -4, -1, 1, -14, 33,
- -12, -18, 9, -2, -10, 9, 9, -1, -1, -5, 10, -3, 2, 4, 2, -9,
- -1, 25, -2, -3, 15, -17, -7, 8, -7, 0, 10, -13, 9, -11, 0, -3,
- 18, -15, -11, 5, 0, -12, -2, 7, -6, -4, -9, 11, -6, 8, 1, -14,
- 3, 16, -10, -3, 2, 6, 4, 9, -9, -2, 0, 2, -3, 15, 3, -10,
- -4, -8, -1, 10, -13, -9, 16, -9, -3, -2, 5, -6, -6, -9, 10, 8,
- -4, 14, -7, -19, 12, 1, 2, 1, 4, -1, -6, -3, -3, 5, 7, -2,
- 0, 0, -5, 0, -6, 1, 6, -5, -4, 5, -6, 5, -4, -8, 15, -5,
- -7, 0, 3, -8, 0, 3, -8, -4, 6, -4, -4, 15, -5, -8, -7, 4,
- 7, -10, -6, 15, -4, -13, 7, 2, 2, 1, -4, 5, 0, 0, 1, 4,
- -7, 4, 4, -2, 4, 5, 1, -18, 12, 4, -3, -6, 11, 0, -13, -1,
- 1, -12, 3, 13, -9, -15, 7, 0, -4, -8, 0, 5, 0, -9, 1, 1,
- -3, 0, 3, 5, -10, 6, -1, -4, 4, 15, -15, -5, -9, 18, -2, 0,
- 15, -11, -9, 0, 6, -2, 8, 1, -8, -9, 7, 3, -7, -3, 6, 1,
- -5, 0, -5, -5, 0, -3, 11, 1, -3, -8, -4, -4, 5, 9, -6, -7,
- 4, 15, -13, 5, -4, 2, -6, -2, 0, 5, 4, -4, 0, -6, 8, 3,
- -2, -4, -4, -11, 4, 10, -1, -4, -2, -1, -3, 1, -4, -2, 3, 1,
- -4, -11, 12, -4, 5, -2, 7, -12, -2, 4, -4, 5, 8, 1, -8, 14,
- -11, -1, 1, 4, 0, 5, -5, 2, -7, -7, 10, 3, 1, -13, 0, -4,
- 5, -9, -1, 1, -11, -5, 5, 2, -6, 5, -5, -8, 12, -2, 7, -1,
- -10, -5, -7, 14, 9, 3, -5, -2, 5, 4, -2, 0, -5, 2, 3, 3,
- -12, 6, 3, 2, -9, -1, 24, -13, -9, -1, -2, 0, 7, -6, -17, 14,
- -12, -5, 10, 1, -4, -1, -1, 1, -3, 2, -2, -11, 1, -1, -1, 1,
- 10, -3, 2, 1, 5, -7, 1, -1, -5, 7, 1, 7, -4, 5, -11, -8,
- -8, 7, 8, 6, 0, -15, -1, 7, 0, -6, -3, 7, -4, -3, -2, 1,
- 5, 8, -6, -4, 11, 3, -14, -6, -3, -6, 9, -5, 4, -5, 2, 3,
- -13, -3, 1, -4, -3, 11, -1, 0, 7, -16, -6, 11, 5, 0, 4, 5,
- -2, -3, -2, 8, 7, -16, 1, 2, 6, 3, -17, 11, -2, -2, -9, 6,
- 0, -7, 6, -22, -2, 14, 3, -11, 0, -6, -2, -7, -7, 1, 4, 14,
- -1, -6, 0, 7, 3, -14, 4, 15, -4, -9, -2, 12, 14, -10, 5, 9,
- -11, -2, -9, 2, -9, 11, 2, -21, 7, 6, -11, -1, 0, 0, 1, -9,
- 4, 0, -10, 1, 3, -3, -7, 12, -9, -2, 4, 6, 3, -8, 0, 1,
- -2, -14, 12, 11, -5, 10, -3, -1, 3, -6, 1, 0, -3, 8, -1, -18,
- 12, 5, -13, -4, 17, -1, -6, 1, -11, 0, -6, 2, -2, -2, 5, 3,
- -17, 2, -5, 11, -4, 8, 8, -19, -6, 14, -6, -6, 0, 5, 0, -8,
- 7, 13, -6, -5, 6, -2, -9, -1, 8, 3, -4, -4, 10, -10, -9, 7,
- 2, -6, 14, 0, -15, 3, 5, -4, -10, 8, 0, -6, -11, 3, 10, -9,
- 1, 8, -7, 2, -1, -6, -8, 6, 2, -8, -2, 16, -3, -3, -1, 5,
- -3, -8, 6, 9, -6, 1, -1, -1, 2, -6, 6, -1, -9, 3, 9, -10,
- 1, 5, -4, -14, 2, 1, 7, -5, 3, -2, -13, 5, 10, -9, -8, 14,
- -6, -19, -3, 19, -3, -3, 6, -4, -10, 3, -1, -4, 5, 5, 1, 0,
- -1, 11, 4, -10, 3, -5, 4, -7, 1, 8, -3, 1, 2, 0, -10, 2,
- 5, -15, -3, 8, -8, -6, 5, -2, -5, -5, 11, 0, -12, -7, 5, 2,
- -5, 2, -1, -4, 2, 7, -12, 5, 6, -3, 5, -1, 12, 7, -13, -3,
- 0, 3, 0, 13, -1, -4, 0, -9, 5, -6, 5, -2, -10, -6, -2, 9,
- -8, 5, -6, -10, 5, 4, -6, -2, 1, 1, 6, -14, 10, -3, -4, -5,
- 1, 8, -16, 7, 7, -1, 0, 3, -5, 2, -1, -3, 11, -11, 9, 8,
- -18, 3, 8, 13, -4, -5, -9, 4, -2, -4, 9, 5, -6, -5, -15, -3,
- 17, -6, 2, -8, 4, 4, -4, -12, -3, -2, -2, -4, 5, -4, 1, 7,
- -12, -6, 8, 6, -2, 1, -3, 3, 10, -3, 7, -11, 12, 4, -1, -1,
- 1, 0, -11, 11, 4, 0, -2, -9, -2, -2, -8, -1, 5, -4, -5, -5,
- 1, 10, -8, -11, -5, -4, 5, -1, 1, 6, -2, -5, -5, 3, 6, -2,
- 6, -3, 0, 4, 5, 2, 4, -2, 1, 5, -2, -6, 11, -1, -5, 8,
- -14, 6, -2, -6, -11, 4, 2, -14, 6, -9, 5, -4, -3, 4, -12, -2,
- 2, -5, 4, 7, -5, 3, 6, -1, -3, -6, 0, 7, 0, 1, 6, 9,
- 4, -2, -7, -4, 7, 4, 4, -5, -5, 0, 3, -6, -1, 7, -2, -18,
- -1, 3, -15, 5, -2, -2, 0, 4, -10, -4, 3, 4, -10, 4, -1, 5,
- 4, -7, 8, -7, 0, 3, 2, -7, 13, 0, -2, -6, -6, 5, 10, -10,
- 4, -1, 2, -1, -5, 7, 5, -3, -7, 1, -5, 10, 1, -11, 7, 6,
- -10, -15, 12, 2, -4, 1, 0, -5, 3, 0, -2, 6, -5, -4, -13, -2,
- 3, 1, 4, 3, 3, -10, -7, -7, 11, -2, 2, 2, -7, 4, -1, 6,
- 2, 0, 8, 3, 0, -7, 8, 3, 5, -8, -3, -2, 2, 3, -12, -4,
- -3, 12, -12, -4, 7, -3, -10, -10, -4, 6, -2, -8, 9, 1, 1, 1,
- -3, -6, 12, -5, -6, -1, 11, -7, 5, 6, 2, 9, -11, 6, -2, 8,
- 1, -6, 4, 3, -6, -3, 5, -4, 4, 1, -19, -1, 3, 4, 0, 0,
- -10, -1, -3, -5, -3, 0, 11, -1, -12, -2, 6, 0, -3, 3, 4, -1,
- -7, 1, -2, -1, 2, -1, 0, 2, -2, 4, -5, -4, 11, -4, -5, -3,
- 7, 5, -8, 3, 6, -9, 0, 9, -5, -2, 5, -4, -6, 0, 7, -1,
- -2, 0, -1, -6, -9, -6, -1, 8, 4, -1, -9, -5, 13, 2, -11, -5,
- 9, 0, -8, -1, 5, -2, -5, -3, -2, 7, 5, -4, -13, 3, 11, -8,
- 3, 0, 2, 5, -12, -6, 6, 3, -4, -1, 8, 1, -5, -7, -6, 2,
- 8, 5, -2, -9, 7, -6, -2, 13, -7, 2, 1, -1, -5, 3, 7, -1,
- -11, 9, -6, -4, -2, -5, -1, 2, -1, 3, 8, -7, -1, -9, 0, 0,
- -1, 2, 5, -2, 1, -2, -3, 6, 6, -3, -6, -5, 4, -1, 1, 5,
- 1, -1, -2, -3, -4, 4, 3, 1, -7, 5, -1, 0, -8, -6, 1, 7,
- -3, -6, -2, 3, -1, -3, 2, 2, 0, -9, 1, -2, 4, 4, -5, 1,
- -1, 1, 6, -2, 2, -5, -4, -1, 14, -3, 2, -9, 1, -2, -4, 1,
- -1, 7, -9, 5, 2, -3, 2, -2, -9, -2, 4, -1, 2, -2, -2, 0,
- -1, -1, -2, 3, 1, -1, -3, -6, 3, 7, -5, -3, 9, -5, -4, -5,
- 8, -4, 2, 2, 8, -10, -1, 8, -14, 0, 6, -7, -1, 2, -3, 2,
- -4, 5, 2, -5, -4, 5, 1, -6, 3, 6, -4, -1, -3, 3, -7, 0,
- 1, 0, -4, 7, 6, -13, -3, 3, 2, -15, 8, 3, -3, -6, 9, -4,
- -1, 9, 1, -6, -6, 7, 1, 1, -2, 6, -1, -4, -1, -1, -7, 5,
- 3, 0, -5, -2, 8, -2, -8, 6, 7, -16, -5, 6, -6, -1, 1, 7,
- -4, -3, -6, 3, -10, -3, 8, -9, -1, 5, -1, -7, 5, 2, -1, 1,
- 5, 1, 2, -4, -5, 1, 1, 3, 1, -5, -2, 3, 2, -7, -1, 7,
- 5, -5, -7, 5, 0, 3, -1, -4, -4, 4, 0, -4, 1, 6, -3, -7,
- 0, -3, -3, -1, 0, -2, -4, 2, 1, -2, 3, -1, 0, -1, -6, 9,
- -5, 4, -1, -1, 4, -2, 5, -8, 2, -3, -2, 2, -3, 10, 2, -3,
- -5, 2, -4, -1, -3, -7, 9, 1, 0, 0, -5, 1, -2, -12, 6, 8,
- -18, 4, -1, 4, -1, 5, -5, -3, 3, -1, 4, -5, 9, -5, -4, -5,
- 2, 5, -1, -4, 0, -3, -2, 8, -5, 2, 1, -13, 3, 1, 4, 5,
- -8, 2, 8, 1, -1, 1, -9, 1, -2, -4, 1, 4, -3, 4, -4, -5,
- 6, 5, -6, -3, -3, 1, 1, -7, 1, 2, 1, -5, -4, -2, 2, -6,
- 6, 3, 7, -10, -9, 4, 1, -5, 6, 9, 3, 1, -2, -4, 3, 4,
- -1, -6, 3, 1, -2, -9, 4, 4, -5, 4, -10, 2, -4, -5, -1, 1,
- 2, 0, 2, -8, 1, 3, -4, -13, 0, 10, -1, -4, 5, 0, -4, 5,
- -3, 2, -5, 2, 1, 2, 4, 2, 2, -10, 5, 3, -11, -2, 3, 3,
- 0, -6, -2, 1, 1, 2, -1, -8, -1, -5, -4, -3, 5, 8, -4, -4,
- 2, 0, -2, -2, 1, -5, 0, 13, -8, -6, 4, 8, -6, -1, 6, -2,
- 4, -5, 3, 5, -7, -8, -2, -3, 7, 8, -8, -3, 1, 5, -5, -5,
- 9, -4, -7, -5, 4, 3, -6, 5, 1, -1, 3, 0, -6, -9, 0, -6,
- 1, 4, 10, 5, -13, 0, 6, -2, -4, 2, -2, 6, -1, -4, 0, -11,
- 6, 3, -1, -3, 14, -1, -15, 1, 2, 3, -1, 4, -3, -6, 0, 3,
- 0, -6, 10, -3, -14, -2, 10, -3, -9, -4, 0, 6, -1, 7, -3, -5,
- -6, 1, 0, -5, 11, -2, 1, -2, 5, -1, -4, -1, -3, -4, 2, 11,
- 2, -4, 1, 2, -12, 7, 3, -1, -11, 3, 15, -8, -11, 0, 0, 2,
- -7, 1, -3, -4, -3, -5, -4, 6, 11, -7, -8, -1, 6, -5, -3, 6,
- 8, 3, -6, 1, -1, -1, -1, -5, -3, 8, 7, 4, -9, 1, -2, -4,
- -6, 9, -4, 3, -8, 0, 6, -2, -4, -2, -2, -6, 8, -7, 3, 1,
- 3, -1, -3, 2, 1, -6, -9, 3, -5, 8, 5, -10, 7, 5, -3, -2,
- -1, -3, -1, -4, -7, 6, 6, 3, -7, 0, 0, 1, 0, -7, 3, -1,
- 0, 1, 2, 2, 2, -11, -8, 9, 6, 2, -6, -1, 1, -3, 3, 1,
- -6, 2, -3, -2, -1, 2, -4, 0, -4, -2, 0, -3, -2, -6, 5, 2,
- 0, -1, -3, -1, 3, 1, -2, 0, 2, 2, 0, 1, 7, 1, -4, -2,
- -6, 4, 3, -1, -4, -1, 3, 3, -9, -2, 0, -2, -1, -5, 6, 1,
- -5, 1, -5, 9, -10, -4, 0, -4, 6, 1, -3, -5, 9, -2, -5, 2,
- 0, 6, -6, 2, 5, 10, -8, -3, -2, -1, 4, -3, -1, -4, 0, -1,
- 1, -4, 0, 5, -8, -1, -5, -1, -1, 3, 3, 3, 2, -14, -5, 1,
- 2, 3, 1, -1, 2, 5, -2, 2, -5, 2, 3, -2, -2, -3, 4, 4,
- 4, -6, 3, 1, -10, 1, -6, 6, -2, -3, 0, -3, 1, -3, 1, -1,
- -4, -5, -4, 7, -2, -2, -3, 6, -5, -5, 2, -6, 1, 4, 3, -8,
- 11, 4, -4, -1, 2, 3, -5, -2, 1, 7, -4, 2, 4, -10, 7, -7,
- -1, 0, -3, 5, -4, -1, -4, 5, -7, 3, 3, -11, -2, -1, 5, 1,
- -1, 0, 6, -11, 0, 1, -2, 1, 0, -1, -4, 2, 9, -2, -9, -4,
- 2, 0, 2, -1, 1, 1, -7, 5, -3, 4, -1, -3, -8, 5, 7, -1,
- -1, -3, 3, -7, 0, 4, -3, -3, 1, 6, 0, -1, 0, -5, -1, 0,
- -4, 0, 0, -3, 1, -4, 1, 7, -3, -13, -2, -2, -1, 3, 5, 2,
- -6, 1, 6, -2, -6, 8, -1, -6, 0, 4, 6, -2, 0, -2, -4, 3,
- 5, -4, -7, 2, 5, -3, -3, 3, 1, -10, -7, 3, 1, -3, 2, 4,
- -7, -3, 0, 2, -5, -3, 3, -2, 0, 3, 5, -6, -1, 4, -2, 0,
- 5, 1, -2, -2, 3, 2, -1, -3, -3, -7, 7, 3, -1, -2, 0, 0,
- 1, -2, 1, 0, -15, -1, 3, 2, -3, 4, 0, -7, 0, -1, -1, -4,
- -3, 2, -1, -1, 11, -3, -1, -5, -1, 2, 2, 0, 1, 2, 3, 4,
- -6, -3, -2, 1, 0, -4, 2, 1, -1, -5, 1, -1, -7, 2, -2, -5,
- 0, 2, -2, 3, 5, 0, -2, -6, 6, -7, 3, -4, -6, 1, 6, 3,
- 1, -2, -3, -4, -6, -1, 7, -2, 0, -3, 0, 9, -3, -5, -1, 3,
- 0, -1, -3, 6, 1, -6, -3, 3, 6, 0, -6, -4, 2, 1, -1, 2,
- -5, 4, 1, -2, -5, 0, 7, -9, 3, -1, 1, -6, 0, -5, -1, 1,
- -1, 0, -4, 2, -2, -2, 1, 6, -1, -5, 0, 0, 0, 1, 3, 2,
- 2, -1, -3, 0, 1, 5, 1, -5, -7, 2, 6, -3, -3, -3, 2, -7,
- -5, 5, 0, 0, -3, -4, -1, 3, -4, -5, 1, 5, -1, -2, -4, 0,
- 5, 2, 0, 2, 2, -1, -1, -5, 5, 3, -1, -4, 1, 0, -1, -2,
- -1, 2, 2, -4, -4, 2, -2, -3, -4, -3, 0, 3, -3, -2, -2, 4,
- 1, -2, -2, 1, 2, -6, -1, 2, 6, 1, -2, 0, 4, -3, -1, -2,
- -1, 5, 1, -11, 4, 3, -1, -6, 2, -2, 3, -4, -8, -2, -1, 4,
- 0, 3, -2, -1, -2, -2, 1, 3, 3, -7, 0, 2, 10, 0, -4, 3,
- -3, 0, 0, 3, -4, 6, -4, -8, 2, 1, 3, -14, 1, -1, -2, 0,
- 0, -5, -1, 2, -6, -1, 3, 0, -5, -3, 3, 1, 6, -2, 0, 6,
- 2, -7, 1, 3, -5, 5, 8, 0, -1, 1, -4, -6, -2, 6, 4, -4,
- -1, 1, -10, 0, -4, 0, -3, 2, 0, -8, 3, -3, 0, 2, -1, 1,
- -8, -1, -1, -3, -1, 4, 1, 6, 1, 0, 0, -2, 0, -2, 7, -4,
- 3, -1, 2, 0, -2, -2, -8, 3, 2, -1, -4, 3, 0, -3, -5, 2,
- -3, -3, -2, 5, 2, 1, 1, -4, 1, -1, 4, 6, -4, 0, -6, -4,
- 1, 3, 3, -1, -2, -7, -1, -3, 6, -6, 2, 1, 5, -8, -5, -1,
- 2, -1, -3, -1, -1, 5, -7, 3, 3, 1, 4, -4, -3, -3, 8, 1,
- -2, 4, 4, -2, -8, 2, 1, 0, 2, 0, -6, 3, -2, -8, -2, 5,
- -1, -6, 0, 2, -1, -5, -2, -2, 6, 0, -5, -2, 3, 0, -5, -1,
- 6, 7, 2, -8, -4, 6, 2, -6, -4, 12, 2, -5, -2, -6, 1, 1,
- -3, -7, -3, 11, -3, -6, -1, 3, -2, -4, -4, 4, -3, 4, -2, -3,
- 1, 7, 0, -8, 7, 1, -2, -4, -6, 13, 0, -3, 1, 2, -1, -4,
- -3, 1, 3, -2, -3, -1, 0, 3, -1, -10, -1, 2, -8, -3, 3, 2,
- 1, 4, -6, -2, 1, -3, -1, -4, 6, 5, -1, -5, -1, 9, -2, 0,
- -4, 0, 1, -3, 4, -5, 1, 3, -4, -6, 0, 4, -2, -6, 9, -1,
- -3, 2, -4, 0, 4, -7, -4, -1, 1, 4, 0, -1, 6, -2, -2, 4,
- -3, -1, -6, -2, 2, 3, 1, -3, 8, -10, -10, 7, 0, -2, -1, -4,
- 3, -6, 0, -5, -5, 5, 3, -6, 1, 5, 0, -1, 1, -1, 0, 0,
- 0, -5, 7, -2, -1, 2, -1, 3, 0, -6, 4, -3, -2, -3, -2, 1,
- 3, 3, 0, -2, -1, -9, 2, 2, -1, 4, -4, 4, -10, 7, -8, 2,
- 1, -1, 0, -1, 4, 2, -7, 7, -6, -4, 3, 11, -5, -6, 1, 3,
- -4, -6, 2, 2, -2, -3, -7, -4, 6, 0, 7, -13, 6, 2, -9, -2,
- -5, 3, 8, 0, 0, 5, -5, -4, 3, 0, 2, 4, -7, 0, -1, 10,
- -3, -6, 7, 2, -1, 0, 6, -2, -7, 4, -2, -1, -2, 1, -3, -9,
- 6, 0, -4, 0, 3, 3, -11, -4, 7, -16, -2, 0, 2, 1, -2, 2,
- -5, -1, 12, -6, 2, -7, 2, 6, 0, -4, -1, 1, -3, 2, -1, 0,
- 7, -2, 2, -6, 2, 7, -9, -4, 8, 2, -9, -3, 8, 1, -1, 4,
- 5, -11, 2, 1, -1, 0, 0, -6, -2, 2, 6, -13, 2, -3, -8, 1,
- 1, 3, -2, -3, -2, -7, 4, -6, -2, 3, -10, 5, -2, 1, -3, 5,
- 8, -4, -1, 2, -1, 6, 2, 3, 2, -2, 0, -1, 0, 4, 1, -1,
- -2, 7, 1, -7, -5, 7, -5, 2, -5, -4, 0, 3, 3, -2, 0, -1,
- -9, -4, -9, 10, 1, -14, 0, -1, 6, -8, -3, 3, -1, -6, -1, 5,
- 3, -5, -1, 3, -6, 5, 7, -10, 5, 5, 2, -4, -3, 9, 4, -11,
- 0, 5, -11, 7, -6, 2, 2, 12, -15, -8, 2, -3, 7, -5, 3, 3,
- 1, -10, 0, -9, 17, -11, 7, -6, 2, 1, -3, 0, -1, 5, -2, -10,
- -4, 16, -1, -7, -1, -3, 1, 11, -3, 1, -3, 2, -12, -2, 12, 3,
- -1, -10, -2, 6, -3, 1, -1, -4, 12, -1, -2, -7, 6, -1, -1, -16,
- 5, 11, -3, -7, 1, -1, -2, -6, -4, -5, 3, 4, -3, -8, -1, 3,
- -5, 3, 1, 2, 6, -10, 1, 7, 0, 21, -15, 11, -12, 0, 1, 4,
- 1, 4, -4, -1, 3, 7, 0, -5, 10, -15, -14, 2, 6, -11, 5, 3,
- -10, -6, -1, -11, 4, -9, 6, -9, -2, 2, -8, 3, 0, 2, -9, 7,
- 7, 2, 2, 0, 3, 1, 6, 0, 3, 6, -10, 6, -4, 1, 7, 9,
- -1, 0, -7, 1, -11, -8, 9, 4, 0, -6, 2, -16, 0, 1, -2, -16,
- 10, -7, -12, 7, 4, -1, -1, -4, 2, -1, 2, -5, 8, 3, 3, 4,
- -2, 4, 3, 2, -4, -2, -1, 5, -5, -3, 9, 2, -22, 8, -6, 1,
- 3, -5, -4, -6, 7, 0, 5, -8, 9, -13, 0, -6, 18, -3, -3, -1,
- -6, 7, 3, -11, -9, 19, 6, -10, -6, 3, 12, -2, -18, 7, 8, -7,
- -10, 14, -8, 5, 1, -15, -4, 11, -6, 9, -8, -1, 5, 1, -6, -2,
- 7, -3, 7, -20, 6, 5, -4, 3, 12, -12, 11, -4, -22, 7, 9, -13,
- 1, 0, -8, -1, 9, 6, -10, 5, -9, -5, 8, 5, 8, -12, -4, 16,
- -14, 7, 6, -1, -16, 21, 2, -9, 13, 5, -4, -19, 2, -3, 12, -7,
- -2, 3, -2, -4, -3, -8, 4, 1, -4, -4, -14, -3, -1, 1, -11, 30,
- -11, -16, 8, -2, -9, 8, 8, -1, -1, -5, 10, -4, 1, 4, 3, -8,
- -1, 23, -2, -2, 14, -15, -7, 7, -7, 0, 9, -12, 8, -10, 0, -3,
- 16, -13, -11, 5, -1, -10, -2, 6, -5, -4, -9, 10, -6, 7, 1, -13,
- 2, 14, -9, -3, 2, 6, 4, 8, -8, -2, 0, 2, -3, 14, 3, -10,
- -4, -8, -1, 10, -13, -8, 15, -9, -3, -2, 5, -5, -6, -9, 9, 7,
- -4, 14, -7, -18, 12, 1, 2, 1, 4, -2, -6, -3, -2, 5, 7, -2,
- 0, 0, -4, 0, -6, 1, 5, -5, -4, 5, -6, 5, -4, -8, 15, -5,
- -6, 0, 3, -8, 0, 3, 0, -1, 0, -4, 6, -16, 22, -7, 3, -5,
- 2, 2, 1, -3, 4, -8, 4, 4, 0, -5, -9, 4, -5, -4, 3, 2,
- 1, 3, -4, 6, -15, -1, 4, 1, -9, 3, 1, -8, 3, -6, 11, -5,
- 6, -11, 17, -15, -2, -19, -11, 1, -4, 8, 0, 5, 18, -11, 0, 13,
- -4, 6, -13, 4, -11, -1, -7, -7, 11, 10, -9, 17, -11, 20, -6, 7,
- -14, 23, -7, -2, -2, 7, -10, 2, 0, 2, 5, 6, -8, 5, -4, -10,
- 9, -4, 6, 0, -7, 8, -7, 1, -20, -4, -1, -3, 6, -10, -6, -15,
- -11, 10, -5, 19, 3, 1, -19, -11, -1, -9, 9, 22, 24, 10, -5, -18,
- -8, -23, 14, 11, 0, 31, 43, -9, 0, -7, -15, -28, -35, -30, 3, 5,
- -5, 11, 52, 55, 7, -5, -10, -12, -25, -43, -12, 4, -37, -47, -21, -5,
- 4, -11, 1, 31, 27, 34, 46, 48, 61, 10, 16, 8, 7, -14, -40, -47,
- -36, -51, -42, -15, 4, 12, -32, -42, -10, -4, 10, 1, 15, 50, 31, 5,
- 15, 38, 37, 29, 15, 22, 11, -4, -35, 10, 3, -18, 1, -14, -33, -5,
- -47, -25, -13, -2, 15, -6, 5, -29, -17, -19, -1, 3, 7, 2, 17, 28,
- -8, -23, 7, 7, 36, 15, 2, 1, -2, -9, 1, 6, 20, 6, 14, -3,
- 21, -11, -12, -35, 11, -20, -18, -36, -23, -27, -19, 1, 10, 14, 27, 6,
- 44, 14, -9, 3, 20, 27, 45, -8, -13, 16, -16, 24, -10, -9, -3, -38,
- -19, -14, -38, -38, -41, 13, 40, -37, 5, -7, -7, -4, 4, -31, 32, 22,
- 15, 9, 13, 10, 10, -17, 22, 30, 9, -6, 27, 66, 47, -17, -21, -20,
- -9, -36, -73, -3, 22, -35, -12, 6, 7, 4, -17, -45, 22, 17, -17, 3,
- -9, -4, 11, -10, 13, -4, 8, 38, 3, 20, 42, -22, 9, 23, -28, -21,
- 3, 10, 1, 26, -28, -18, -9, 7, -30, -41, -24, -9, 10, -6, 31, -5,
- 2, 29, -9, 1, -27, -24, 7, -19, -5, 10, -13, 21, 21, 3, 30, -11,
- -17, 34, -11, 8, 7, -8, 1, 11, -1, 7, -13, 1, -3, 23, -12, 8,
- -19, -3, 20, -78, 42, -23, 4, -29, -16, -5, 38, -49, 30, -26, 26, 16,
- 8, -33, 53, 19, -20, 12, 5, 23, -11, 4, -6, 42, -111, 67, -40, 29,
- -32, -20, -77, 113, -46, -12, 8, -5, -14, 35, -52, 94, -5, -61, 58, -36,
- 41, -83, 21, -19, 61, -68, 37, -37, 12, 66, -69, -16, 100, -88, 48, 21,
- -39, 73, -24, -2, 45, 65, -59, 53, -103, 95, -97, 1, -14, -4, -41, 9,
- -13, -18, 16, -26, 9, 26, -15, 25, -16, 6, 8, 26, -52, 35, -21, 4,
- -2, -11, -4, 22, 0, 21, -40, 65, -6, -13, -11, -7, 32, -46, -48, 16,
- -26, -3, 0, -42, 87, -68, 34, 17, -14, 43, 23, -15, 30, 20, 47, -19,
- -33, -12, 15, 1, -37, 15, -12, -11, -7, 15, -75, 36, -41, 27, -8, -7,
- -12, 10, -4, 49, -6, 42, -32, 4, 20, 33, -65, 24, -52, 10, 13, -17,
- -15, 60, -14, -55, 35, -16, 50, -83, -3, 29, 58, -75, 71, -46, 47, -32,
- 44, -57, 10, -43, 33, 22, -48, 51, -41, 6, 7, 39, -3, -41, 7, -9,
- 37, -66, 22, 26, -13, 74, -87, 127, -39, -16, -29, -11, -8, -57, -15, -45,
- 52, -74, -5, -2, 103, -126, 85, 20, 28, -7, 53, -38, 58, -10, -11, 33,
- -70, 20, 1, 40, -36, 26, -58, 58, -23, 61, -71, -7, -39, 43, 22, -18,
- -1, -61, 90, -37, 35, -58, 30, -62, 27, -45, 47, -59, -6, -35, 70, -49,
- 9, -30, 92, -15, 21, 1, 26, 6, -19, 90, -43, 49, -46, 10, 6, 15,
- -90, 67, -51, -11, 4, 28, -36, 24, 41, -68, 24, -34, 63, -40, 17, -30,
- 18, -39, 14, -38, 15, 9, -54, 54, -20, 36, -21, -14, -13, 11, 23, 11,
- -54, 56, -25, 37, -46, 49, -74, 81, -40, 51, -44, 57, -69, 51, -50, 61,
- 27, -112, 111, -114, 106, -85, 49, -61, 75, -18, 26, -68, 32, -15, -25, 21,
- -15, 38, -46, 80, -119, 126, -85, 41, -40, 77, -65, 28, -6, -39, 45, -87,
- 39, -63, 81, -32, 4, -32, 44, -25, 42, -12, -15, 21, -1, -56, 21, 23,
- -30, 33, -28, -3, 32, 4, -36, 60, -20, 13, -3, 22, -43, 101, -88, 59,
- -53, 18, 8, 22, -33, -52, 34, -32, 35, -90, 112, -107, 56, -59, 43, -60,
- -18, -4, -21, 45, 11, -48, 11, 38, -27, 58, -49, 65, 19, 54, -38, 35,
- -37, 24, -11, 44, -62, 41, -16, -48, -8, 31, -68, 17, -3, -5, 52, -51,
- -10, 16, -26, 18, -29, 56, -41, 3, 5, -10, -37, 61, -14, -10, -9, 20,
- -8, 8, -2, -16, 44, -17, 14, -33, 30, -2, -27, 16, 3, 0, 51, -42,
- 32, -20, 8, -11, -24, 10, 12, -15, 6, -32, 10, 21, -38, -11, -12, 23,
- 13, -64, 19, 34, -23, -23, 16, 10, 39, 2, -36, 55, -31, 0, -29, 18,
- 8, 12, -61, 73, -28, 54, -34, 21, 9, 7, 53, -34, -29, 19, -7, -44,
- 7, 15, -16, -18, -31, 10, -29, 36, -69, 7, 4, 33, -72, 45, 14, 0,
- -8, 35, -13, 26, 16, -28, -3, -32, 45, -4, 8, -20, 65, -24, 2, -24,
- 40, -16, -16, 20, 8, 2, -3, -2, 23, -15, -11, -30, 19, -51, -19, -5,
- -36, 18, 24, -4, -1, 46, -90, 60, 4, 23, -17, 16, 60, -24, 0, 18,
- 0, 5, -6, -24, 27, -34, -28, -7, -4, 22, -30, -11, -3, -1, -44, 36,
- -38, -6, -9, 55, -34, 16, 27, 28, -65, 62, 22, -32, 36, 7, 2, 27,
- -19, 50, -71, 44, -19, -67, 13, -3, -14, -30, 33, 5, -12, -48, 60, -47,
- -28, 9, -6, 24, -11, -1, 13, 62, -53, 26, 7, -9, 6, 58, -38, -10,
- 0, 5, -23, 23, 8, -14, -19, 21, -9, 35, -17, -28, 14, 27, -17, -14,
- -29, 24, 6, -85, 74, -16, -18, -2, -19, 47, -29, -18, -15, 52, 0, 7,
- -10, -23, 45, 13, -11, 12, -28, 27, -26, 19, -69, 74, -55, 35, -21, 41,
- -24, -11, 39, -19, 7, 0, 7, -31, 10, 7, -45, -17, 25, -12, 9, -19,
- 3, 28, -53, 76, -19, -25, 49, -2, 6, -11, 24, -12, -23, 17, -1, -15,
- -10, -36, 26, -25, 0, -44, 59, -67, 45, -31, 5, 15, 56, -12, -14, 12,
- 10, 24, -52, 37, 5, -35, 52, 23, -55, -6, 24, -49, 26, 31, -24, 10,
- -33, 33, -11, 1, -49, 8, 7, 6, -78, 12, -22, 10, -11, 13, 13, -18,
- 38, 50, -18, -5, 64, -52, 59, 33, 3, -9, -6, -6, 26, -64, 18, -38,
- -47, 18, -33, 4, -39, 40, -31, -1, -23, 48, -30, 18, 17, 32, -20, 32,
- 19, 24, -58, 49, -38, -9, 15, -28, 16, -3, -2, -28, 33, -22, 23, -1,
- -34, 33, -48, 67, -55, 21, 51, -66, -2, 21, -5, -17, 24, -63, 53, 8,
- -19, 9, -11, 36, -37, -35, 43, -35, -3, -44, 68, -43, 53, -24, -5, 45,
- -16, -7, 14, 49, 3, -16, 22, -10, 2, -28, -9, -6, -5, 32, -76, -22,
- 35, -26, -35, -12, 0, 3, 13, 6, 36, 7, -32, 69, -15, 45, -20, -21,
- 35, 35, 1, -25, 11, 34, -24, -33, -9, 5, -25, -49, 31, -41, 15, -42,
- 25, -30, 42, -80, 32, 2, -18, 33, -12, -9, 43, -1, 4, -12, 54, -51,
- 22, -1, 18, 28, -29, 18, 7, 10, -19, 8, -1, 12, -21, -6, -11, 4,
- 4, -28, -8, 22, -27, -5, 9, -25, 20, -19, -36, 41, -8, 20, -32, 16,
- -29, 29, -13, 13, 4, 1, 17, 8, 0, 9, 22, -1, -3, 28, -11, -39,
- 36, -31, 5, -11, -27, 22, -39, 7, 15, -24, 19, 8, -37, 75, -52, 54,
- -65, 22, -13, 23, -26, 32, -19, 10, -8, -3, 12, 16, -44, 25, -23, 14,
- 9, -46, 20, 2, -4, -8, -6, 18, 4, -2, -3, -15, 4, 16, -9, -5,
- 34, -29, 27, -54, 98, -65, 11, -18, 16, -13, 0, -2, 0, 22, -43, 31,
- -46, 58, 2, -25, -2, 16, -2, -29, 17, 18, -26, 21, -17, 5, -4, -9,
- 0, -34, 50, -27, -3, 4, 31, -3, -47, 32, -25, 36, 6, -47, 33, -28,
- 39, -36, 42, -28, 5, -3, -2, 25, 27, -47, 20, 22, -5, -15, 1, -9,
- 16, -25, -10, -43, 40, -12, -19, 22, -24, -5, 14, -44, 42, -32, 32, -45,
- 40, 41, -17, 27, -44, 38, -16, 15, -36, 39, -13, -19, -4, 34, 1, -9,
- 9, -16, -2, -29, 31, -31, -4, 35, -21, -52, 63, -41, 2, -7, 30, -35,
- 13, 9, 15, -4, 14, -36, 18, -14, 55, -50, -6, 22, -23, -11, -5, 12,
- 17, -13, -43, 44, -33, 41, -42, 45, 3, -12, 26, 11, -11, 35, -76, 39,
- 2, 0, 3, -4, 15, -19, -6, -33, 11, 5, 16, -25, -2, 19, -7, -43,
- 30, 20, -27, -18, 12, 14, 33, -50, 14, -15, 23, 8, 2, -10, -4, 53,
- -86, 24, -9, 41, -34, -21, 22, 24, -54, 27, 13, 2, -9, 14, -29, 21,
- 40, -43, -9, -3, 27, -3, -22, 18, 10, -23, -15, 1, 14, -12, 3, -30,
- 30, -22, -28, 36, -15, 39, -57, 21, 3, -3, 33, -13, -2, 6, 20, -6,
- 4, -13, -5, -18, 13, -7, 7, 26, -26, 16, 7, -64, 37, -7, 10, -20,
- 12, -11, 7, -34, 37, -12, -24, 34, -18, -18, 39, 9, -42, -24, 43, 2,
- -16, 25, 12, -16, 8, 12, -44, 32, -9, 23, 1, -37, 40, -23, -17, 18,
- -42, 23, -12, -7, 10, -6, 6, -13, -13, 30, -23, 36, -4, 7, 17, -18,
- 18, -3, 8, 5, -1, -13, -15, 2, -5, -16, 7, -52, 23, -38, 30, -30,
- 16, -26, 21, -22, 24, 3, 20, -28, 22, 22, -31, 42, -16, -11, 32, -26,
- 0, 31, -14, 11, -15, 14, -17, -9, 10, 11, 27, -38, -4, 14, -18, 36,
- -44, 0, -11, 16, -14, -2, 16, -34, -23, 22, 4, -24, 14, -13, 16, 31,
- -28, -10, -6, 51, -27, 13, -49, 3, 68, -38, 1, 8, -27, 26, -16, 0,
- 15, -36, 7, -6, 38, -11, 0, -14, 10, -4, 22, -48, 31, -1, 23, -38,
- 1, 15, -7, 10, -1, -3, 4, -1, 10, -2, -12, 3, -22, 5, 9, 8,
- 4, -14, 12, -3, -7, 22, -20, 3, -6, 13, -15, -8, -7, 16, -14, -1,
- -3, 6, -17, 12, 22, -44, 68, -67, 50, 13, -20, -11, -4, -20, -3, 22,
- -13, -20, 28, -7, 2, 11, -9, -23, 5, 5, -26, 24, -31, 2, 20, 15,
- 2, -7, 4, 19, -6, 41, -51, -3, 24, 27, -30, 25, -37, 1, -7, -2,
- -4, -26, -1, 12, 5, -12, 9, -30, 5, 11, 26, -18, -32, 42, 7, 0,
- -23, 10, 10, -20, 53, -49, 6, -39, 18, 3, -27, 41, -21, 16, 28, 14,
- -24, -15, 19, 5, 16, -31, -1, 45, -25, -6, -16, -4, -19, 37, -47, 21,
- 2, -14, -7, 30, -35, 13, -30, 14, 21, 11, -18, -28, 37, 12, -18, 9,
- 5, -1, 33, -41, 3, -7, -19, 8, -14, 12, 15, -18, -4, 44, -25, 22,
- -46, 19, 40, -25, -12, -5, 17, 7, -53, 25, 4, -10, 14, 16, -31, 40,
- -27, -11, -4, 28, -40, -5, -9, -3, 34, -47, 33, -5, 11, -33, 33, 0,
- -14, 35, -18, -27, 11, 14, -37, 35, -20, 7, 15, 2, 27, -17, 15, -31,
- -1, 11, -27, 24, -26, 14, 13, -35, 20, -13, -2, 16, 16, -6, 2, 15,
- -7, -22, 51, -36, -2, 20, -19, 23, -20, -19, -9, -14, 8, -4, -13, 35,
- -66, 36, -37, 3, 19, -1, 15, 32, -45, 71, -15, -5, 12, 34, -33, 24,
- -5, 20, -43, 42, -59, 13, -12, -69, 66, -29, -34, 17, 7, -28, 24, 5,
- -27, 51, -40, -9, 46, 3, -17, 36, -56, 63, -7, -31, -19, 53, -12, -10,
- 4, 19, -47, 35, 0, -40, 17, -14, 13, -11, 11, 3, -39, 22, 5, 21,
- -19, -11, 25, -4, -5, 20, -13, 25, -6, -16, -16, 29, -61, 25, -33, 12,
- -17, 7, -19, 34, -27, 15, -19, 32, -26, 54, -46, 6, 9, 14, -6, -6,
- 23, -32, 58, -19, -5, 15, 46, -42, 39, -7, -23, -7, -14, -22, 42, -66,
- 0, 4, -8, -11, -4, -3, -7, 7, -23, 30, -14, 19, 8, -9, 20, 36,
- 5, -24, 25, 12, -20, 16, -53, 60, -49, -26, 24, -87, 67, -49, 13, -7,
- 5, -14, 5, 11, 38, -3, -15, 27, 26, -36, 20, 30, -47, 29, -5, 9,
- -10, 38, -65, 47, -49, -4, -10, -6, 1, -1, -28, 16, -14, 3, -14, 27,
- -8, 1, 2, 23, 21, -53, 40, 24, -16, -12, -2, 11, 17, -8, -18, 8,
- -25, 28, -10, -12, 13, -51, 10, 35, -10, -8, -9, 8, 10, 14, -20, 4,
- -9, 37, -5, -2, 2, 4, -9, -5, 16, -16, -23, 13, 7, -9, 14, -49,
- 13, 8, -3, -13, -9, 22, -8, 12, -13, 36, -36, 35, -17, 23, -12, 0,
- -37, 50, -31, -8, -31, 43, -4, -11, 0, 3, -7, -19, 16, -16, -28, 46,
- -28, 27, -13, 33, -21, -1, 39, -13, 3, -4, 4, -39, 74, -30, -17, 33,
- -3, -20, -12, 24, -94, 75, -63, 54, -62, 23, 4, 12, -33, 22, -35, 16,
- 12, -28, 34, 2, -12, -3, 22, 23, -31, -6, 26, 4, -41, 8, 37, -15,
- 21, -7, 18, -51, 42, -27, 35, -45, 35, -30, 18, 9, -20, 1, 18, -12,
- -51, 61, -61, 24, -20, 1, 11, -5, -2, -12, 11, 20, -35, -2, 37, -21,
- 23, -15, -2, 19, -51, 82, -50, 20, 29, -26, -34, 49, -2, -16, 11, -17,
- -4, 6, 15, -35, 13, -15, -10, -17, 15, 4, -42, 43, -31, 34, -30, 53,
- -43, 40, -22, 9, 9, -24, 64, -41, 29, -17, 8, -15, 8, 2, -27, 7,
- 10, -28, 0, 30, -50, 6, -13, -14, -21, 11, 9, 13, -47, 35, -11, 32,
- 28, -28, 1, 32, 2, -19, 28, -24, 9, 0, 19, -6, 16, -33, 6, -23,
- 33, -31, -1, -4, 26, -22, -22, -10, -11, 18, -26, 19, -8, -4, 21, -14,
- 36, -2, 12, -48, 49, -1, -13, -5, 8, -3, 9, -4, -18, 15, 28, -50,
- 10, 4, -7, 4, -39, 37, -39, 11, 2, -20, 13, 4, -6, 0, 35, -17,
- -9, 6, 38, -21, -1, -1, 12, -2, -16, 15, 7, -22, 18, -23, 11, 3,
- -9, -39, 29, -31, 44, -41, 0, 5, 21, -9, -25, 25, -6, 38, -55, 38,
- -14, 6, -26, 38, -24, 39, -39, -15, 17, 16, -20, -27, 17, 24, -20, -20,
- 33, 8, -31, 2, 2, 27, 11, -4, -7, 31, -20, -9, 4, -4, 17, -32,
- 2, -18, 31, -35, 38, -52, 42, -1, -28, -26, 25, 3, -51, 42, -35, 35,
- -39, 44, -38, 20, 20, -51, 34, 45, -10, -7, 27, -19, 33, -49, 22, 2,
- -7, -5, -27, 59, -24, -20, 21, -8, -15, 24, -51, 3, 9, -23, 24, -30,
- 2, 29, -26, -2, 4, 10, 0, -18, 50, 3, 9, -14, 17, -18, 24, -13,
- -33, 7, 25, -50, 2, -2, 30, -58, 31, -8, 23, -11, -1, -24, 21, 1,
- -41, 47, -30, 28, -39, 56, -16, -20, 51, -45, 33, 6, 23, -12, -19, -2,
- 7, 1, -14, -5, -11, -20, 25, -17, 7, -22, 21, -19, 34, -47, -2, 1,
- 33, -30, 14, 20, 6, -9, 17, 13, -22, 19, -58, 23, 26, -15, -52, 2,
- 18, 10, -13, 46, -5, -8, -6, 4, -14, 5, 11, -13, -7, 42, -25, 8,
- -37, 35, -10, 6, -25, 16, 15, -15, -9, -20, 18, -23, 26, -34, 35, -22,
- -10, 9, 14, -6, -21, 27, -8, 4, 1, 3, -19, 28, 2, -7, 30, -8,
- -13, 11, -9, -9, -19, 12, 0, -23, -1, -23, -6, 27, -31, 41, -28, 13,
- 5, 9, -21, 6, 2, -2, 18, -16, 31, -25, 40, -38, 39, -13, 8, 14,
- -3, 9, -30, 6, -12, -7, -15, 30, -64, 6, -22, 13, -8, 14, -40, 9,
- 32, -35, 14, -1, 12, -25, 63, -25, 35, -2, 19, -5, -3, 20, -29, -1,
- 35, -37, 53, -46, 4, -14, 22, -27, 23, -64, 8, 5, -25, 41, -18, 14,
- -42, 53, -56, 35, -42, 71, -63, 45, -38, 29, -12, 33, -22, 0, 24, -13,
- 3, 13, 1, -10, -19, 11, 19, -38, 5, -2, -18, -21, 33, -54, 41, 9,
- 4, -1, -21, 3, 3, 37, -31, 34, -40, 34, -19, 30, -26, 23, -53, 55,
- -8, -13, -16, 7, -13, 46, -38, 2, -3, 17, -1, -26, 18, -57, 68, -27,
- 23, -19, 32, -39, 2, 2, -18, 12, -16, 4, -23, 38, -65, 40, -5, 13,
- 19, -26, -13, 60, -25, 7, 1, 10, 22, -24, 23, -20, -16, -17, 14, -32,
- 26, -4, 17, -15, 9, -29, 4, -29, 11, 36, -18, -19, -2, 5, 28, -23,
- 31, 6, 4, 18, -14, 4, -7, 0, -45, 61, -31, 5, -15, -23, -21, 52,
- -62, 4, 22, 1, -9, 15, -24, -27, 60, -49, 38, 0, -6, 1, 13, 7,
- 4, 19, 6, 0, 27, -28, -14, -21, 17, -1, -30, 23, 10, -36, 18, -19,
- 2, -18, 0, 6, -1, 7, -1, -37, 26, 15, -35, 41, -24, 10, 10, -9,
- -12, 12, 7, 3, 10, -11, 11, -14, 27, -49, 71, -55, 25, 8, -11, 11,
- -5, -22, 7, 15, -17, -11, 18, 4, -54, 43, -38, 27, -1, 7, -13, 19,
- 10, -41, 50, -41, 13, 9, 10, -41, 38, -13, 13, -2, -2, -4, 9, -36,
- -5, 22, -31, -18, 8, 21, -22, 21, -24, 12, 3, 16, -24, 25, -16, 22,
- -35, 14, 3, 11, 12, -22, 40, -11, -25, 14, 0, 14, -2, 2, -10, -12,
- 14, -51, 11, -21, 55, -27, 9, 3, 38, 7, -25, 5, -19, 6, -14, 0,
- -10, 21, -57, 35, 18, -21, 21, -40, -13, 24, -24, -12, 10, -1, 11, 10,
- -12, -5, 38, -45, 23, 26, -13, -9, 32, 6, -3, 30, -28, -28, 27, 3,
- -10, -11, -10, 16, -28, 21, -12, -3, -1, -33, 14, -30, 12, -20, 40, -15,
- 7, 19, -18, -1, -1, 9, 4, -23, 32, 17, -19, 12, 16, -45, 4, -6,
- 18, -28, 36, -44, 44, -29, 10, 4, 14, -8, -13, 9, -30, 39, -17, -5,
- 10, -10, 5, -1, -16, 17, -7, -9, -10, 15, -21, 9, 10, 8, -10, -6,
- 3, -21, 34, -3, 6, -4, 15, 3, -2, 4, 26, -44, 30, -43, 2, 9,
- -5, -7, -18, 16, -28, 0, 5, -7, 0, 7, 0, -7, 21, -14, 17, 15,
- 2, -40, 7, 44, -30, 55, -33, -19, 40, -30, 17, -1, -20, -20, -20, 5,
- 14, 1, -7, -32, 26, -11, -11, 24, -23, 17, 17, 8, -19, 18, 11, -6,
- 17, -4, -13, 14, -9, 21, 9, -16, -8, 2, -16, 3, -9, -32, 6, -36,
- -4, 0, 10, -36, 26, -11, 3, 31, -20, 1, 7, 4, 45, -35, 39, 0,
- 4, 28, -21, 29, -39, 27, 15, -6, -14, 17, -25, -33, 16, -15, 18, -43,
- 28, -61, 33, 1, -27, 13, -19, -20, 26, 11, -27, 16, -21, 33, -13, 43,
- -44, 13, 24, -10, 35, -39, 36, 20, -39, 68, -68, 23, -16, -7, 0, 36,
- -30, -13, -27, 42, -21, -4, -23, -2, 23, 0, -3, -3, 2, 4, -15, -5,
- 28, -10, -20, 24, -7, 27, -58, 31, -7, -29, 39, -40, 41, -35, 8, -25,
- 30, 31, -17, -9, 3, 36, -8, -18, -11, 29, -2, 6, -25, 21, -5, -8,
- -17, -24, 20, -26, 20, -23, 46, -26, -13, 8, 13, 2, -15, 4, -9, 28,
- -25, -19, 49, 18, -50, 45, -11, -17, 5, -61, 15, 4, -22, -1, 22, 23,
- 33, -55, 46, -25, 37, 18, 2, -9, 11, -47, 23, -8, -25, 37, -32, 2,
- 5, 12, -18, -5, 19, -27, -7, 20, -40, 32, -44, -21, -29, 58, 8, -9,
- 57, -28, 29, -32, 14, -14, 4, 23, -33, 16, -4, -16, 21, 38, -37, 23,
- 10, -32, 17, 17, -12, -59, 9, -3, -12, 22, -13, -8, -26, 16, 1, 33,
- -9, -17, 16, -7, 21, -44, 26, 5, 35, -36, -1, 13, 36, -36, 39, -36,
- 17, -13, 2, -33, 20, -13, -51, -2, 9, -2, 35, -21, 19, -20, 18, -19,
- -5, 30, -39, 30, 22, -35, 74, -52, 33, -15, 17, -21, -13, 11, 6, -25,
- 25, -31, 29, -18, 18, -52, 40, -11, -17, -26, 56, -56, 69, -53, -14, 32,
- -10, -8, -2, 18, -14, 20, -18, 20, 22, -27, 0, -25, 56, -46, 16, -28,
- 52, -5, -33, 76, -75, 36, -1, -42, 42, -46, 13, -13, 25, -7, 35, -55,
- 5, 63, -56, 11, -24, 13, -8, -10, -27, 15, -15, 44, -66, 52, -3, -6,
- 0, 23, -33, 79, -55, 30, -27, 37, -18, -6, -2, -19, 52, -22, -50, 60,
- -32, 28, -56, 44, -28, 15, -37, -9, -28, 63, -75, 9, 39, 28, -21, 5,
- -17, 15, 2, -13, 30, 13, -14, 10, -12, 30, -22, -10, 4, -8, -9, 14,
- 6, -39, 34, -6, 4, 1, -5, 0, 33, -73, 34, -12, 23, -9, 53, -47,
- 17, 3, -18, -6, 2, -19, -12, -7, -45, 72, -9, -71, 55, -58, 50, -18,
- -36, 37, 19, -11, 13, -35, 32, 6, 5, 18, -6, 19, -26, 32, 16, 20,
- -43, 20, -10, -7, 16, -7, -68, 21, -36, 7, 19, -22, 19, -3, -35, -37,
- 25, 21, -57, 67, -9, 9, 32, -11, 28, -18, 35, -41, 60, -19, 29, 0,
- -38, 29, -6, -35, 0, 25, -37, -1, -31, -42, 30, -19, -21, 36, -66, 53,
- -33, 15, 16, -13, 20, -35, 73, -4, 18, 39, 4, 1, 3, 21, -2, -12,
- -18, -51, 44, -17, -50, 48, -30, -16, -13, -35, -7, 25, -33, -14, 14, 0,
- 8, -30, 45, -13, 50, -53, 28, 60, -33, 23, -7, -2, 15, 36, -11, 9,
- 19, -44, 4, -21, 19, -5, -27, -45, 48, 9, -47, -23, 12, 3, -25, -8,
- -21, 63, 1, -29, 31, -18, 19, 16, -24, -17, 50, -65, 65, -56, 93, -45,
- -17, -25, 45, -18, 23, -53, 50, -15, -12, -39, 51, -11, 11, 13, -31, 54,
- -14, -29, 22, -11, 10, -41, -19, 52, 10, -51, -60, 72, -13, 12, -38, 19,
- -2, 31, -56, 37, -4, -10, 22, -14, -33, 48, -40, 38, -14, 27, -24, 19,
- 29, 17, -31, -2, -41, 34, -17, 2, 5, 5, -13, -30, 14, 9, -9, 7,
- -11, 15, 5, -28, -2, 0, 45, -30, -25, 1, 10, 29, -55, -24, 52, -5,
- 5, 20, -25, 20, -15, 14, -64, 95, -53, 32, 13, -26, 31, -8, -27, 18,
- 48, -57, -3, -10, 25, -24, -32, -9, 18, 18, -33, -15, 27, -22, 14, -5,
- 10, 51, -21, -25, 19, 5, -15, -29, 16, 1, 33, -39, -12, 56, 14, -63,
- 36, -2, -17, 52, -11, -37, 5, 19, -52, 38, -23, -60, 93, -75, 52, -30,
- -2, -11, 49, -11, -25, 1, 42, -35, 26, -35, -9, 24, -1, 10, -6, -12,
- 7, 4, 22, -10, 41, -25, -8, -4, -2, 28, -43, 19, -32, 4, -27, 9,
- -47, 51, -16, 12, -52, 49, 8, 7, -37, 27, -33, 80, -44, 6, 5, 28,
- -15, 16, 15, 2, -12, 50, -77, 38, -38, -45, 30, 8, -37, -13, -8, -18,
- 50, 3, -54, 29, 29, -20, 4, 52, -57, 62, -52, -2, -9, 62, -64, -5,
- 24, 23, 0, -7, -23, 48, 25, -78, -9, 38, 18, -46, 30, -51, 39, 4,
- -48, 22, 15, 13, -39, 8, 10, 31, -20, -22, 21, -17, 17, -23, 22, 22,
- -24, -36, 11, 31, -16, -28, 34, -4, 0, -20, 6, -2, 35, -13, -60, 36,
- 24, -45, 21, -2, 36, 0, -73, 66, -37, 39, -66, -18, 22, 17, -17, -25,
- 24, 36, -47, 3, 25, 7, 8, 0, 1, 14, 20, -21, 4, 21, 12, -77,
- 17, -4, -12, 31, -57, 38, -11, -4, -31, -6, 29, -34, 11, 13, -20, 82,
- -36, -36, 40, -28, 77, -68, 12, 2, 34, -23, 5, -31, 11, -5, 44, -105,
- 79, -31, -29, -16, 37, 8, 18, -14, -9, 32, -10, -11, -7, 0, 41, 34,
- -56, 7, 13, -2, -31, 33, -67, 42, -31, -2, 22, -49, 18, -34, -11, 38,
- -40, 56, -16, 14, -2, 24, 0, 0, 41, -21, -8, 6, -11, 11, 11, -45,
- 26, 4, -17, -7, -26, -30, 7, -21, -29, 56, -29, 37, -3, 2, -8, -3,
- 22, 11, 40, -13, 58, -6, -38, 48, -23, 15, -52, -14, -6, 49, -66, -20,
- -11, 34, -32, -44, 41, 4, 20, -59, -24, 77, 23, -24, -17, 42, 19, -3,
- -19, -34, 54, 17, -22, -17, 46, -24, -9, 3, -22, 40, -47, -49, 72, 4,
- -18, -48, -33, 55, -4, -41, -51, 105, -26, -3, -22, 64, 28, -51, 31, 2,
- 15, 27, -62, 18, 21, 6, -15, -54, 52, -14, -46, 7, -30, 32, -1, 6,
- -37, 39, -3, -23, -20, 24, 23, 17, -25, -6, 67, -36, -11, -37, 56, -79,
- 3, 30, 45, -39, -17, -2, 21, 2, -4, -3, 3, 1, 16, -16, 9, 30,
- -37, 8, -6, 46, -65, 3, 14, -59, 104, -60, 2, 46, -29, -30, -2, -10,
- 24, -52, 63, -31, 81, -85, 18, 35, 16, -32, -18, -24, 45, -16, -15, -13,
- 37, -15, -20, -42, 91, -45, -15, -9, -16, 64, -11, -23, 31, -18, 38, -42,
- 3, 12, 1, 5, -5, 22, -44, 69, -31, -18, 15, 21, -64, -13, 34, -37,
- 30, -26, -15, 6, -3, 44, -28, 11, -3, -1, 16, -18, 25, -14, -26, 69,
- -56, -5, 31, -51, 24, 3, -36, 9, 52, -34, 31, 21, -11, -68, 31, -24,
- 53, -25, -29, 31, 23, -20, 9, -15, -11, 19, 12, -47, 84, -60, -16, -11,
- 17, -4, -15, 30, -45, 32, 34, -63, -7, 68, 0, -35, 17, 7, 33, -31,
- -8, 7, -32, 43, -13, -18, 15, 31, -32, -34, 5, 8, -16, 20, -26, -29,
- 32, -9, -20, 17, 33, -31, -13, -5, 86, -52, 23, -19, 2, 13, 14, -7,
- -20, 36, -16, -3, 8, 0, 14, -69, 76, -77, 25, -14, -17, 3, 39, -14,
- -46, 31, -2, -7, 37, -45, -6, 24, 28, -37, 22, 13, -35, 4, 8, 23,
- 7, -43, 53, -59, 23, 16, 4, -25, -15, 23, -9, -20, 26, -18, -1, 25,
- -3, -48, 53, 2, -43, 7, 14, -34, 15, 28, -33, 53, -2, -59, 31, -34,
- 40, 19, -27, 20, -2, 8, 2, 3, -8, -8, 4, -57, 62, 24, -72, -4,
- 17, -17, -3, -10, -26, 42, -30, 12, -29, 31, -10, 3, 24, 2, 21, -1,
- -36, 52, -7, 21, 14, -32, -18, 73, -45, -6, 8, -12, -66, 21, 25, -17,
- -6, -35, -14, 27, 26, -47, 40, -51, 56, -19, -24, 31, 6, 4, 11, -3,
- 37, -47, 41, -32, 50, 0, -72, 25, 16, -19, -1, -2, -4, -41, 20, 6,
- 9, -3, -44, 32, -54, 83, -30, -26, -8, 46, -47, 29, 5, -19, 37, -9,
- -20, 65, -14, -21, -4, 10, 28, -28, 18, -29, 35, -25, 3, -17, -31, 4,
- -4, 0, -9, 41, -42, -34, 40, -15, 8, -24, -8, 36, 22, -18, -27, 70,
- -39, 39, 1, -5, 57, -54, 12, 36, 3, -13, -1, -32, 69, 6, -64, -50,
- 13, -13, -34, 22, -13, 0, -10, -38, 41, -11, -22, -3, 11, 4, 38, 22,
- -10, 24, 32, -23, 23, -6, 8, -4, 21, -61, 66, -35, -41, 7, 5, -29,
- -19, -45, 23, -2, 46, -84, 78, -59, 40, -10, -18, 79, -35, -5, -1, 36,
- 16, 13, -21, -31, 52, 2, -50, 34, -5, -36, -37, 65, -42, 1, 16, -42,
- 35, -8, -50, -6, 41, -16, 27, -41, 22, 64, -50, -11, 31, -18, -17, 5,
- -3, 34, 34, -40, -41, 66, -37, 20, -11, -20, 29, -5, -14, -15, 45, -33,
- -37, -11, 36, -25, 18, -8, 20, 1, -23, 60, -32, 0, 34, -24, -32, 64,
- -39, -35, 48, -7, -13, 4, -39, 32, 0, 1, -31, 2, -12, 43, -38, -8,
- 26, 0, -57, 53, 19, -22, -10, 17, -30, 57, 6, -31, 33, 10, 0, -48,
- 29, -4, -23, 6, -7, 31, -39, 15, -41, 38, -19, 5, -37, 23, 11, -28,
- -14, 59, -48, 8, 22, -20, 50, 15, -34, -26, 67, -8, -15, -21, 53, -27,
- -9, 13, -24, -35, -10, 9, -15, -13, 18, -38, 28, 22, -14, 2, -22, 42,
- -20, 22, 12, -20, 45, -16, 17, -16, 22, 34, -27, -13, -7, 1, -21, -1,
- 13, -44, 36, -51, -8, 16, -7, -30, -46, 90, -54, 35, 1, 11, 9, 5,
- 1, -19, 20, 11, 21, -1, -49, 41, -6, 0, 37, -74, 9, 20, -12, -47,
- 65, -68, 28, -5, -26, 15, 14, -3, -23, 8, 18, -22, 13, 3, 31, -21,
- -5, 8, 24, -21, 48, -20, -21, 41, -43, 4, 18, 21, -60, 9, -27, 1,
- 13, -15, -33, 15, 23, -48, -8, 53, -50, 1, 6, -40, 90, -10, -15, 51,
- -52, 53, 29, -68, 50, 52, -30, -21, 7, -1, -8, -29, 11, -47, 6, 18,
- -12, -25, 53, -34, -23, -6, 19, -7, -13, 7, 5, -2, 14, 11, -15, 51,
- -29, 6, 12, 20, -27, 29, -12, 4, -18, -5, 2, -17, 10, -19, 2, -8,
- -5, 56, -82, 49, 0, -42, 48, -25, 19, 6, -41, 17, 35, -18, -17, -29,
- 26, 10, 4, -24, 26, -35, 47, -36, 2, 2, -23, 27, -42, 55, 0, -21,
- 19, 21, -8, 1, -3, -15, 7, 12, -23, -29, 47, -12, 4, -28, 17, 16,
- -7, -31, -8, 25, -6, 0, 13, -20, 6, 3, -7, 19, -21, -37, 27, 41,
- 7, -14, 12, -59, 57, 6, -49, -2, -8, 0, 19, 13, -20, -5, 16, 23,
- 4, -15, -33, 14, 2, 15, -26, -28, 10, 45, -17, -24, 14, 17, -39, 22,
- -8, 48, -51, -1, -16, 52, -34, -21, 11, 13, 18, -57, 26, 15, 27, -36,
- -12, 40, -7, -14, 15, -86, 91, -20, -13, -7, 53, -43, 33, -25, 13, 3,
- -38, -19, 28, 28, -18, -74, 58, -3, 40, -27, -34, 30, 28, -1, -22, 2,
- 9, -8, -12, 12, 21, -35, -2, -17, 17, 2, -27, 22, -36, 38, -11, 2,
- -20, 7, 20, -29, 39, 11, -3, 9, -24, 47, -36, 28, -14, -16, 38, -37,
- 12, -15, 18, -69, 56, -31, 17, -16, -18, -13, 21, -6, -9, -25, 37, 6,
- -1, -2, 5, -1, -26, 39, 6, -3, -10, 0, 12, 30, -12, -31, 24, 13,
- -14, 9, -23, 31, -43, -17, -2, 13, -23, -14, -21, 21, 19, -22, -12, 24,
- 41, -26, 10, 12, 19, -3, 9, -12, 26, 12, -52, -4, 16, -3, 0, -43,
- 7, 5, -14, -9, 12, -28, 15, -23, -2, 35, -12, -8, -10, 24, 57, -55,
- 26, -18, 19, 44, -30, 0, -5, 50, -56, -1, 8, -5, -39, 9, 19, -39,
- 38, -73, 30, -1, 2, 16, -24, 6, 29, -71, 70, -18, -6, 8, 31, 4,
- -13, 23, -11, 31, -56, 57, -25, 10, 15, -44, -10, 16, -17, -44, 18, -28,
- 10, 8, -21, -4, -9, 28, 20, -16, 17, -17, -6, 30, 0, 11, -21, 25,
- 25, -1, 31, -56, 31, 14, -32, 2, -19, 4, -17, -26, -13, 42, -59, 15,
- -29, 53, -4, 1, -23, 13, 31, 5, -22, 3, 30, -28, 2, -24, 37, 1,
- -3, -18, 18, 41, -40, 3, -40, 48, -31, -5, -20, 5, 9, 0, -30, -1,
- 26, -15, -5, -6, 51, -25, -27, 7, 44, -11, 10, -32, 14, 46, -31, 6,
- -11, 37, -33, -14, 19, -4, 22, -50, 26, -45, 21, 1, -23, 10, -15, 17,
- -63, 53, -14, -18, 56, -49, 21, 25, -7, 4, -21, 52, -33, 19, 3, 11,
- -9, -7, 0, -49, 22, -17, 25, -10, -11, 5, -19, 35, -26, 20, -7, -21,
- 37, -25, 29, -23, 3, 6, 17, -26, 27, 5, -16, 10, -9, -24, 11, -4,
- -17, 9, -5, -13, 1, -2, 10, 5, -13, 21, 0, 8, 9, -22, 12, 13,
- -24, -3, -22, 42, -18, 3, -4, -15, 1, -2, 8, -17, -13, -2, 1, 23,
- 10, -2, -31, 23, 17, -15, -9, -24, 31, 2, 19, -24, 4, -22, 28, -5,
- -20, 34, -57, 26, 71, -51, 28, -24, -12, 28, 10, -35, -4, -6, 7, -7,
- 8, -52, 61, -52, 7, -9, -21, 9, 18, -19, 3, 34, -53, 56, -29, 20,
- -11, 22, 4, -1, 23, 2, 1, 24, -15, 3, -32, 13, 21, -37, 6, -11,
- -25, 22, 7, -2, -41, 4, 10, -30, 39, -24, -7, 8, 12, 9, -1, -35,
- 13, 3, 9, -18, 21, 26, -14, 41, -8, -35, 31, -29, 17, -20, -12, 20,
- -30, 27, -26, 21, -9, -6, 5, -14, 3, -11, 15, 2, 8, -14, -5, 20,
- 4, 0, -31, 9, 4, 25, -24, 5, -5, -13, 27, -7, -32, 1, -5, -10,
- 28, 7, -4, 11, 10, 22, -3, -22, -15, 6, -3, -3, -27, -25, 5, 8,
- -10, -17, 18, -18, 12, 32, -18, 1, 25, -25, 50, 7, 2, 0, -3, -3,
- 16, -20, 9, -14, -15, 21, -27, -3, -17, 23, -31, -4, -18, 31, -21, 6,
- 0, 18, -16, 27, 3, -7, -17, 17, -15, -11, 19, -16, 6, 1, 12, -18,
- 5, -6, 24, 0, -19, 22, -23, 43, -35, 18, 22, -40, 1, 12, -4, -18,
- 26, -53, 34, 1, -10, 1, -18, 27, -25, -24, 33, -31, 9, -43, 53, -29,
- 33, -17, 5, 23, -7, 2, 23, 29, 1, -8, 20, -10, -1, -22, -3, -17,
- 4, 22, -61, -23, 31, -26, -29, -12, 2, -3, 12, 10, 26, 5, -29, 61,
- -9, 32, -18, -14, 29, 31, 2, -19, 9, 31, -20, -31, -7, 5, -22, -47,
- 31, -40, 15, -39, 22, -27, 40, -78, 31, 4, -19, 33, -13, -8, 41, -1,
- 5, -12, 53, -51, 22, -1, 18, 28, -29, -1, 0, 0, 11, 13, -2, -7,
- -5, -3, -3, 1, 2, -6, 0, 3, 8, 9, 5, 0, 14, -5, -28, -39,
- -39, -36, -37, -27, -43, -49, -13, 4, 6, -7, 0, -1, 3, 23, 39, 29,
- 35, 41, 21, 35, 0, 0, 21, 59, 67, 31, 21, 13, -3, 18, 34, 28,
- 5, 3, 13, 3, 0, 12, -7, -33, -27, -39, -14, -34, -50, -30, -37, -35,
- -53, -74, -70, -61, -62, -62, -50, -44, -61, -36, -3, -23, -15, -12, -17, -20,
- -6, 11, -6, -12, -6, -17, 7, 46, 71, 87, 79, 70, 77, 104, 109, 66,
- 37, 34, 27, 31, 40, 43, 31, 23, 17, 2, 10, 24, 32, 66, 56, 17,
- -13, -55, -54, -21, 19, -19, -56, -77, -37, -27, -10, -6, -38, -36, -37, -3,
- 23, 25, 25, 19, 35, 34, -7, -5, 28, 60, 66, 65, 51, 34, 22, 53,
- 51, 15, 20, 11, 21, 21, 16, 24, -2, -23, -36, -35, -21, -29, -51, -51,
- -47, -57, -85, -80, -70, -100, -97, -82, -78, -76, -64, -51, -56, -54, -49, -70,
- -62, -53, -54, -60, -57, -65, -78, -76, -62, -39, 0, 31, 13, 6, 31, 54,
- 55, 43, 30, 13, 9, 31, 23, 43, 28, 24, 36, 36, 24, 30, 54, 70,
- 113, 103, 75, 4, -3, 40, 55, 50, 23, 9, 25, 29, 48, 41, 29, 14,
- 6, 40, 63, 49, 39, 71, 80, 64, 21, 12, 17, 29, 68, 71, 52, 36,
- 24, 37, 24, 1, 5, 3, -6, -4, 1, 13, -3, -22, -35, -31, -27, -58,
- -59, -43, -55, -71, -76, -71, -88, -103, -95, -98, -85, -77, -68, -71, -58, -50,
- -47, -52, -46, -40, -47, -44, -48, -56, -60, -91, -96, -68, -15, -6, -16, 9,
- 3, 29, 31, 29, 8, 10, -6, 5, 10, -6, -4, -6, 15, 7, -2, 2,
- -5, 30, 91, 107, 74, 8, -3, 14, 27, 32, 26, 17, 21, 18, 34, 49,
- 20, -3, 2, 30, 42, 20, 36, 68, 79, 81, 52, 27, 22, 37, 80, 95,
- 77, 77, 72, 74, 57, 55, 56, 41, 35, 22, 40, 58, 32, 23, 24, 26,
- 0, -7, 6, -2, -16, -26, -31, -45, -46, -64, -77, -79, -73, -72, -75, -59,
- -49, -56, -35, -48, -44, -50, -43, -59, -58, -40, -78, -119, -123, -95, -73, -40,
- -52, -45, -29, -18, -3, -1, -11, -21, -28, -12, -24, -29, -21, -29, -16, -3,
- -5, -30, -40, 1, 69, 96, 78, 31, 14, 23, 17, 19, 33, 20, 9, 9,
- 45, 50, 14, 3, 12, 13, 16, 7, 14, 35, 54, 75, 56, 24, 1, 18,
- 47, 47, 60, 62, 66, 69, 46, 54, 53, 38, 11, 18, 44, 41, 28, 33,
- 37, 22, 14, 15, 13, 13, 1, -1, -13, -6, -11, -38, -33, -47, -40, -46,
- -31, -29, -22, -9, -5, -9, 9, 4, -23, -14, -4, -3, -26, -69, -87, -74,
- -60, -42, -49, -33, -28, -16, 9, 2, -16, -22, -25, -25, -33, -32, -44, -58,
- -41, -11, -19, -51, -77, -43, 24, 47, 49, 34, 21, 5, -9, 5, 18, -10,
- -14, 2, 23, 26, -3, -7, -4, 2, -3, -10, -4, -6, 38, 64, 50, 25,
- 1, 11, 17, 21, 36, 58, 62, 46, 46, 61, 56, 27, 11, 20, 18, 27,
- 15, 31, 26, 23, 17, 7, 16, 0, -9, -10, -3, -8, -14, -25, -36, -56,
- -41, -39, -50, -30, -12, -23, -8, 10, 23, 17, -2, 3, 14, 26, 7, -33,
- -48, -53, -52, -35, -30, -30, -23, 3, 21, 17, 8, 7, -8, -1, 0, -6,
- -29, -50, -26, 10, 5, -38, -64, -41, 5, 22, 49, 63, 38, 20, 13, 26,
- 15, -7, -9, -1, 28, 9, 1, -4, -12, -1, -5, -20, -38, -32, 6, 38,
- 36, 16, 10, 0, -8, -13, 15, 41, 25, 30, 30, 52, 35, 17, 8, 3,
- -5, -5, -6, 4, 7, 4, 4, 3, 3, -20, -25, -23, -28, -22, -18, -47,
- -50, -54, -62, -67, -62, -48, -43, -44, -31, -10, 17, 10, -8, 1, 22, 24,
- 17, -1, -21, -40, -39, -26, -38, -32, -21, 2, 17, 26, 29, 18, 5, 15,
- 35, 19, -11, -37, -9, 33, 17, -6, -30, -23, -10, 22, 65, 73, 71, 47,
- 57, 66, 38, 15, 16, 23, 34, 35, 27, 10, 11, 21, 32, -4, -26, -29,
- 4, 29, 28, 38, 32, 17, -6, -6, 17, 32, 21, 31, 39, 49, 36, 27,
- 25, 13, -1, -11, -8, -1, -15, -11, 4, -7, -9, -14, -38, -46, -35, -31,
- -43, -53, -54, -72, -84, -88, -86, -79, -73, -86, -69, -40, -16, -23, -28, -13,
- -9, 5, 5, -10, -34, -45, -48, -52, -61, -59, -42, -38, -9, 13, 19, 8,
- -14, 18, 42, 28, -18, -31, -3, 11, 21, 13, -9, -17, -22, 9, 57, 71,
- 62, 68, 83, 82, 65, 38, 38, 31, 52, 57, 45, 23, 25, 51, 56, 21,
- -2, -8, 7, 21, 28, 55, 55, 37, 15, 17, 30, 30, 30, 48, 55, 65,
- 55, 54, 61, 42, 24, 22, 13, 6, 6, 4, 4, 17, 19, 1, -20, -23,
- -25, -27, -26, -44, -44, -62, -79, -91, -83, -76, -99, -104, -87, -63, -51, -40,
- -42, -40, -29, -16, -6, -31, -40, -47, -63, -68, -81, -76, -81, -75, -49, -15,
- -5, -34, -38, 2, 15, 8, -29, -43, -33, -18, -11, 8, -9, -42, -45, -14,
- 25, 33, 41, 54, 67, 75, 71, 46, 30, 23, 52, 55, 38, 20, 25, 53,
- 59, 35, 17, 6, 3, 5, 27, 64, 61, 49, 40, 40, 45, 36, 38, 63,
- 69, 69, 77, 85, 78, 76, 63, 48, 38, 42, 28, 15, 30, 35, 41, 27,
- 14, 0, -4, -2, -14, -16, -15, -35, -65, -63, -56, -64, -80, -94, -77, -71,
- -46, -34, -42, -37, -21, -6, -5, -16, -20, -35, -44, -62, -66, -66, -96, -94,
- -58, -26, -32, -44, -50, -14, 2, -9, -26, -41, -53, -49, -27, -5, -28, -59,
- -65, -47, -20, -11, 7, 15, 28, 51, 57, 32, 7, 2, 30, 32, 15, 0,
- 7, 30, 30, 24, 21, -2, -19, -20, 6, 37, 40, 31, 40, 45, 30, 29,
- 35, 49, 52, 69, 74, 78, 89, 79, 72, 62, 60, 51, 37, 29, 29, 42,
- 51, 46, 30, 32, 18, 2, 8, 13, 15, -13, -35, -35, -38, -40, -53, -71,
- -70, -58, -34, -38, -32, -28, -9, 10, 10, 7, 11, -7, -28, -21, -26, -47,
- -80, -84, -49, -18, -28, -38, -32, -8, -4, 4, 3, -23, -46, -44, -19, -5,
- -22, -42, -55, -56, -35, -25, -12, -8, 11, 43, 51, 33, 1, 0, 24, 18,
- 1, -5, 0, 1, 9, 15, 21, -2, -38, -36, -19, 2, 2, 19, 26, 19,
- 20, 10, 11, 20, 31, 37, 49, 62, 64, 61, 60, 61, 50, 51, 32, 10,
- 16, 27, 31, 33, 33, 36, 7, -6, 3, 14, 12, -10, -21, -40, -34, -33,
- -47, -65, -67, -60, -40, -40, -44, -25, -10, -4, 14, 26, 22, 4, -7, 8,
- 8, -22, -67, -65, -33, -19, -24, -20, -18, -8, 1, 26, 30, -2, -22, -25,
- -6, 5, -1, -13, -38, -43, -31, -21, -16, -16, 9, 47, 61, 35, 22, 22,
- 31, 24, 10, 13, 5, -2, 0, 28, 34, 1, -21, -30, -28, -18, -5, 5,
- 18, 20, 14, 6, 6, 12, 9, 20, 33, 39, 51, 51, 42, 51, 51, 48,
- 20, 9, 7, 5, 7, 15, 28, 19, -1, -16, -15, -4, 4, -16, -30, -41,
- -45, -41, -50, -79, -77, -69, -65, -64, -56, -45, -40, -28, -4, 21, 17, -8,
- -9, 21, 16, -18, -56, -58, -44, -39, -24, -22, -28, -22, -4, 29, 31, 13,
- -9, -16, -3, 11, 13, 1, -18, -33, -15, -11, -23, -22, 11, 52, 58, 50,
- 46, 50, 49, 36, 40, 40, 17, 6, 20, 37, 45, 29, 9, -7, -12, -11,
- -6, 9, 30, 25, 26, 26, 17, 19, 15, 21, 24, 46, 55, 47, 43, 56,
- 64, 52, 33, 25, 13, -3, 2, 10, 21, 26, 4, -15, -16, -13, -2, -11,
- -32, -43, -37, -44, -61, -77, -78, -82, -82, -80, -71, -61, -72, -59, -21, 5,
- -2, -27, -10, 15, 7, -14, -44, -59, -67, -55, -37, -38, -50, -45, -23, 5,
- 23, 9, -6, -19, -15, 5, 14, 2, -22, -22, -10, -17, -35, -38, -3, 35,
- 38, 43, 57, 51, 44, 49, 57, 46, 25, 14, 24, 35, 54, 41, 31, 22,
- 1, -7, -4, 12, 23, 34, 37, 35, 35, 36, 26, 24, 33, 55, 62, 53,
- 58, 70, 70, 73, 62, 51, 38, 14, 6, 20, 31, 32, 27, 4, -9, -1,
- 9, -8, -21, -22, -27, -33, -53, -64, -67, -82, -86, -83, -67, -75, -97, -77,
- -36, -15, -27, -32, -18, -1, -1, -6, -31, -62, -73, -68, -52, -52, -68, -69,
- -50, -21, -2, 4, -10, -33, -29, -4, 2, -10, -29, -22, -8, -27, -55, -49,
- -27, -6, 12, 31, 43, 31, 38, 44, 54, 48, 25, 11, 19, 30, 36, 41,
- 41, 29, 11, -1, -9, 0, 15, 27, 34, 36, 46, 46, 26, 27, 39, 51,
- 59, 62, 62, 73, 76, 77, 85, 78, 58, 35, 23, 21, 37, 53, 37, 22,
- 15, 16, 20, 3, 0, -2, -2, -14, -33, -35, -45, -69, -77, -59, -53, -76,
- -96, -74, -41, -30, -25, -26, -19, -4, 7, 11, -8, -40, -62, -62, -51, -55,
- -69, -74, -71, -44, -15, -2, -14, -36, -38, -8, -7, -27, -33, -17, -12, -38,
- -51, -57, -58, -41, -14, 8, 19, 15, 15, 31, 46, 40, 21, 9, 7, 10,
- 20, 25, 33, 28, 16, 1, -18, -13, 0, 6, 12, 30, 39, 39, 26, 20,
- 32, 41, 45, 53, 64, 63, 62, 80, 84, 87, 81, 51, 29, 21, 44, 52,
- 41, 33, 29, 31, 27, 12, 8, 16, 10, -4, -7, -7, -29, -62, -57, -37,
- -44, -68, -81, -70, -48, -33, -23, -22, -17, -5, 16, 31, 14, -15, -33, -42,
- -41, -37, -53, -65, -74, -54, -16, 2, -12, -33, -19, -1, -10, -22, -17, -8,
- -8, -18, -33, -48, -62, -57, -31, -1, 7, 0, 9, 22, 40, 40, 27, 14,
- 4, 3, 10, 14, 21, 31, 20, 0, -13, -19, -17, -15, -7, 12, 29, 28,
- 13, 20, 18, 18, 31, 38, 47, 49, 51, 56, 67, 87, 84, 56, 30, 20,
- 31, 41, 31, 24, 32, 33, 20, 7, 14, 15, -2, -1, 13, 4, -28, -53,
- -45, -34, -38, -59, -75, -72, -58, -44, -26, -26, -29, -8, 14, 34, 28, 10,
- -9, -22, -26, -24, -30, -54, -78, -56, -13, -4, -17, -16, -5, 1, -6, -9,
- -8, -1, 3, -2, -4, -28, -53, -58, -37, -10, 1, -1, 6, 20, 34, 46,
- 40, 25, 19, 11, 7, 10, 23, 33, 28, 16, -3, -3, -17, -31, -14, 4,
- 15, 20, 20, 16, 10, 14, 19, 23, 37, 45, 35, 37, 53, 76, 83, 62,
- 34, 20, 27, 28, 13, 17, 29, 21, 7, 9, 13, -4, -17, -4, 13, 2,
- -27, -53, -47, -39, -46, -56, -77, -87, -77, -58, -45, -46, -47, -33, -6, 17,
- 22, 16, 1, -20, -25, -10, -21, -57, -79, -57, -32, -24, -23, -18, -3, -1,
- -6, -4, -4, -5, 3, 13, 14, -6, -38, -51, -39, -22, -4, -1, 3, 14,
- 32, 45, 46, 46, 33, 25, 15, 9, 28, 38, 32, 28, 26, 14, -9, -21,
- -15, -5, 10, 24, 22, 22, 21, 15, 15, 23, 36, 42, 35, 31, 41, 72,
- 87, 68, 46, 42, 34, 19, 14, 25, 25, 11, 14, 18, 14, -7, -24, -7,
- 12, 4, -19, -41, -47, -44, -41, -52, -74, -92, -88, -72, -59, -63, -68, -53,
- -34, -11, 12, 19, -7, -27, -15, -5, -22, -54, -76, -66, -52, -47, -41, -29,
- -17, -12, -12, -10, -11, -19, -7, 12, 19, 3, -23, -42, -48, -31, -19, -14,
- -6, 1, 20, 35, 39, 50, 51, 33, 16, 17, 30, 31, 32, 41, 39, 28,
- 14, -7, -14, -5, 8, 18, 27, 34, 29, 22, 21, 26, 38, 51, 39, 27,
- 43, 75, 84, 73, 75, 68, 46, 32, 31, 35, 27, 15, 23, 36, 26, 0,
- -13, -4, 12, 14, 1, -23, -36, -36, -32, -36, -60, -83, -84, -70, -67, -70,
- -66, -67, -62, -27, 8, 13, -11, -22, -7, 4, -16, -44, -63, -67, -63, -63,
- -53, -42, -33, -25, -15, -10, -22, -27, -18, -1, 16, 9, -13, -32, -46, -42,
- -31, -30, -24, -8, 5, 11, 25, 49, 50, 33, 25, 20, 21, 24, 29, 34,
- 41, 41, 26, 5, -5, -7, -4, 12, 23, 33, 37, 29, 19, 24, 49, 53,
- 33, 33, 49, 65, 73, 80, 89, 85, 63, 48, 50, 46, 30, 20, 35, 46,
- 39, 17, 0, 2, 15, 23, 18, -2, -20, -24, -12, -19, -45, -60, -66, -70,
- -66, -56, -61, -74, -74, -38, 0, 6, -8, -15, 3, 13, -1, -24, -42, -52,
- -65, -64, -54, -54, -47, -31, -19, -12, -21, -32, -27, -12, 7, 13, -2, -24,
- -36, -37, -44, -47, -32, -20, -18, -9, 12, 30, 38, 35, 26, 18, 17, 16,
- 13, 25, 36, 37, 32, 18, 2, -11, -10, -5, 3, 28, 38, 20, 8, 25,
- 42, 40, 28, 30, 40, 46, 54, 70, 87, 82, 66, 61, 59, 48, 28, 20,
- 32, 43, 43, 24, 8, 1, 7, 23, 25, 3, -13, -9, -8, -15, -28, -40,
- -58, -71, -60, -49, -58, -80, -82, -50, -17, -5, -13, -12, 6, 13, 8, -3,
- -24, -42, -54, -59, -57, -60, -59, -43, -24, -15, -20, -30, -35, -25, 1, 11,
- -2, -12, -18, -33, -48, -49, -41, -37, -32, -21, -8, 13, 27, 27, 27, 23,
- 16, 8, 7, 15, 22, 32, 35, 22, 9, 0, -18, -26, -8, 20, 25, 11,
- 4, 18, 32, 29, 22, 29, 30, 27, 38, 60, 75, 70, 68, 69, 67, 52,
- 30, 19, 27, 36, 40, 34, 10, -2, 6, 21, 20, 4, -2, -4, -7, -9,
- -12, -25, -52, -66, -53, -42, -53, -79, -86, -58, -33, -23, -16, -12, 0, 12,
- 17, 13, -5, -24, -38, -44, -50, -59, -61, -51, -33, -15, -11, -28, -36, -23,
- -4, 5, 5, 7, -3, -17, -31, -40, -38, -37, -36, -29, -14, 4, 15, 25,
- 34, 30, 24, 19, 9, 8, 22, 33, 31, 30, 31, 16, -14, -26, -13, 14,
- 17, 7, 8, 18, 24, 23, 28, 31, 23, 18, 30, 50, 62, 61, 63, 75,
- 73, 59, 40, 23, 20, 30, 43, 35, 11, 0, 8, 15, 12, 6, 3, -6,
- -10, -3, -1, -15, -46, -62, -47, -38, -54, -77, -84, -70, -53, -40, -30, -21,
- -12, 1, 16, 20, 5, -12, -21, -33, -44, -52, -64, -64, -44, -17, -15, -27,
- -30, -26, -15, -3, 6, 12, 9, -2, -17, -26, -29, -36, -41, -32, -21, -10,
- 6, 18, 27, 34, 37, 25, 11, 14, 21, 26, 27, 37, 48, 33, -1, -19,
- -8, 7, 8, 8, 16, 16, 17, 25, 34, 36, 23, 16, 28, 44, 53, 54,
- 61, 74, 79, 75, 56, 30, 19, 31, 45, 35, 15, 9, 9, 9, 11, 9,
- 5, -8, -14, 0, 9, -10, -40, -53, -44, -38, -51, -72, -84, -80, -69, -58,
- -45, -38, -30, -13, 5, 13, 8, 0, -14, -25, -30, -46, -67, -72, -55, -34,
- -26, -28, -31, -31, -26, -17, -4, 9, 11, 2, -4, -12, -22, -33, -38, -40,
- -34, -18, -7, 2, 17, 33, 38, 29, 19, 20, 22, 17, 19, 38, 57, 43,
- 15, 2, -1, 1, 3, 10, 18, 15, 14, 25, 38, 40, 27, 21, 28, 38,
- 46, 50, 55, 66, 81, 90, 71, 40, 30, 37, 44, 39, 26, 18, 12, 8,
- 14, 19, 8, -11, -13, 5, 15, -2, -28, -42, -36, -34, -45, -60, -76, -83,
- -77, -65, -59, -55, -43, -28, -13, 5, 11, 2, -9, -11, -17, -37, -61, -71,
- -65, -49, -38, -36, -34, -35, -36, -32, -16, -2, 1, 3, 0, -7, -13, -25,
- -39, -46, -42, -30, -22, -15, 2, 21, 30, 24, 22, 28, 19, 5, 11, 33,
- 50, 45, 31, 17, 6, -1, 0, 8, 16, 12, 11, 23, 37, 40, 33, 29,
- 29, 33, 45, 48, 46, 58, 83, 97, 84, 59, 45, 46, 47, 46, 42, 31,
- 16, 12, 23, 29, 16, -5, -9, 10, 21, 10, -12, -24, -25, -25, -29, -42,
- -64, -73, -70, -66, -63, -58, -52, -42, -22, 0, 8, 4, 1, 3, -1, -19,
- -44, -61, -63, -57, -50, -39, -33, -37, -39, -36, -27, -14, -4, 0, 0, 0,
- -1, -13, -30, -42, -43, -37, -36, -30, -10, 8, 12, 15, 26, 31, 16, 1,
- 4, 21, 37, 41, 38, 29, 13, 0, -1, 6, 8, 3, 7, 17, 26, 34,
- 35, 27, 24, 32, 40, 37, 32, 45, 72, 89, 86, 70, 57, 48, 45, 49,
- 50, 37, 16, 11, 25, 34, 20, -3, -7, 7, 18, 15, 2, -14, -20, -15,
- -17, -32, -49, -61, -67, -65, -60, -61, -63, -54, -33, -12, -1, 1, 2, 10,
- 12, -3, -26, -43, -57, -60, -54, -45, -38, -38, -39, -39, -35, -23, -13, -6,
- -3, 2, 7, -2, -20, -30, -34, -42, -47, -38, -19, -9, -5, 7, 24, 31,
- 19, 3, 0, 10, 23, 33, 40, 36, 18, 5, 4, 4, 0, 0, 0, 5,
- 16, 29, 30, 22, 22, 31, 36, 27, 21, 32, 54, 74, 81, 77, 65, 49,
- 44, 50, 55, 40, 16, 10, 24, 31, 20, 3, -6, -1, 11, 16, 5, -9,
- -13, -12, -14, -22, -36, -53, -63, -62, -59, -63, -69, -67, -48, -25, -14, -10,
- -1, 10, 16, 10, -6, -26, -45, -54, -55, -50, -42, -39, -39, -40, -39, -29,
- -19, -15, -8, 4, 11, 3, -6, -11, -21, -38, -48, -40, -26, -21, -16, -3,
- 18, 30, 24, 12, 6, 4, 11, 29, 41, 39, 28, 18, 11, 8, 5, 1,
- -4, -2, 11, 25, 25, 19, 23, 33, 35, 25, 17, 23, 39, 57, 74, 81,
- 72, 53, 47, 56, 60, 44, 23, 16, 22, 29, 25, 10, -4, -3, 7, 11,
- 6, -3, -9, -11, -9, -12, -26, -42, -56, -59, -55, -61, -73, -75, -60, -42,
- -32, -23, -12, 0, 12, 15, 7, -10, -30, -46, -53, -53, -46, -41, -43, -45,
- -41, -32, -30, -26, -14, -1, 5, 2, 3, 3, -9, -30, -43, -40, -31, -31,
- -28, -12, 8, 20, 25, 22, 9, 0, 6, 21, 34, 39, 35, 26, 18, 16,
- 14, 4, -7, -5, 9, 21, 19, 16, 23, 35, 37, 28, 20, 20, 26, 43,
- 67, 82, 74, 57, 54, 62, 63, 52, 33, 21, 23, 30, 28, 14, 1, -1,
- 3, 8, 7, -1, -7, -9, -6, -5, -15, -34, -49, -51, -51, -60, -72, -76,
- -70, -57, -46, -37, -25, -13, 3, 14, 14, 3, -15, -33, -48, -52, -47, -45,
- -49, -49, -41, -37, -39, -35, -21, -10, -5, -2, 6, 12, 1, -19, -32, -34,
- -36, -39, -34, -23, -9, 9, 23, 25, 14, 3, 2, 12, 25, 36, 37, 30,
- 24, 25, 24, 10, -5, -4, 9, 18, 15, 14, 23, 34, 38, 36, 30, 19,
- 15, 32, 61, 78, 75, 63, 60, 67, 71, 62, 42, 29, 30, 33, 32, 20,
- 8, 4, 6, 8, 8, 3, -5, -9, -2, 3, -7, -25, -37, -42, -45, -54,
- -66, -74, -74, -67, -58, -49, -40, -27, -9, 5, 13, 13, 0, -21, -39, -45,
- -44, -49, -54, -50, -44, -44, -47, -42, -29, -21, -19, -11, 5, 12, 4, -8,
- -18, -28, -36, -40, -40, -36, -24, -4, 14, 21, 17, 7, 0, 3, 17, 32,
- 34, 29, 28, 34, 33, 17, 0, 0, 9, 13, 12, 14, 20, 27, 38, 46,
- 39, 21, 11, 24, 51, 71, 74, 66, 64, 73, 78, 71, 54, 40, 38, 41,
- 38, 28, 17, 11, 9, 12, 14, 7, -3, -5, 3, 9, 2, -12, -23, -28,
- -35, -45, -55, -65, -71, -68, -62, -57, -50, -37, -22, -7, 10, 20, 12, -8,
- -24, -32, -39, -48, -52, -49, -45, -49, -52, -44, -34, -33, -30, -18, -3, 5,
- 5, 1, -8, -19, -29, -37, -43, -45, -37, -18, 0, 13, 18, 10, -1, -3,
- 10, 24, 26, 23, 29, 38, 37, 21, 8, 5, 6, 8, 10, 12, 11, 16,
- 34, 49, 46, 27, 10, 15, 38, 59, 67, 63, 63, 72, 81, 77, 61, 48,
- 45, 45, 42, 35, 23, 13, 11, 17, 18, 9, -3, -5, 3, 10, 6, -3,
- -12, -19, -24, -34, -46, -57, -64, -65, -66, -63, -56, -48, -39, -22, 1, 17,
- 16, 3, -8, -17, -30, -44, -47, -44, -47, -53, -52, -44, -41, -41, -38, -28,
- -14, -3, 3, 3, -2, -9, -17, -28, -42, -49, -46, -34, -17, 3, 14, 9,
- -3, -6, 5, 15, 13, 15, 26, 36, 35, 25, 16, 8, 2, 4, 9, 6,
- 1, 4, 22, 43, 48, 31, 11, 7, 24, 45, 55, 54, 55, 68, 79, 77,
- 66, 54, 48, 47, 47, 41, 27, 14, 11, 18, 20, 10, -2, -6, 0, 7,
- 8, 2, -6, -12, -14, -23, -38, -49, -55, -62, -66, -63, -60, -59, -53, -37,
- -12, 8, 13, 10, 7, -4, -21, -35, -37, -39, -47, -53, -51, -45, -44, -44,
- -42, -36, -24, -10, 0, 2, 1, 1, -3, -15, -30, -42, -49, -45, -30, -6,
- 10, 7, -2, -3, 5, 9, 6, 11, 23, 32, 35, 33, 25, 14, 6, 9,
- 12, 8, -2, -4, 13, 36, 48, 39, 18, 7, 17, 34, 43, 45, 50, 62,
- 74, 78, 71, 59, 51, 49, 52, 48, 32, 16, 12, 19, 21, 13, 1, -6,
- -5, 2, 6, 2, -4, -6, -9, -18, -29, -40, -51, -60, -65, -63, -63, -68,
- -68, -53, -30, -12, 0, 10, 13, 3, -14, -25, -29, -35, -45, -52, -52, -49,
- -47, -47, -47, -46, -35, -20, -10, -5, -1, 4, 4, -4, -15, -30, -47, -54,
- -41, -15, 1, 0, -2, 2, 6, 4, 3, 7, 16, 26, 35, 38, 32, 20,
- 12, 14, 18, 12, -1, -8, 3, 27, 46, 44, 26, 14, 17, 28, 35, 38,
- 44, 55, 69, 78, 77, 66, 55, 54, 60, 58, 41, 24, 17, 19, 23, 20,
- 7, -4, -4, 0, 2, 1, 0, -2, -4, -10, -17, -28, -42, -55, -59, -56,
- -61, -72, -74, -63, -47, -32, -14, 5, 13, 7, -4, -12, -19, -28, -38, -46,
- -51, -50, -46, -47, -51, -52, -43, -30, -20, -13, -5, 0, 4, 4, 2, -13,
- -40, -55, -47, -25, -12, -8, -3, 3, 5, 4, 2, 3, 7, 18, 32, 41,
- 36, 25, 18, 21, 25, 21, 5, -9, -3, 19, 41, 45, 34, 24, 23, 27,
- 30, 33, 38, 47, 62, 78, 82, 72, 61, 61, 67, 66, 54, 37, 24, 23,
- 28, 25, 15, 5, 0, 0, 0, 1, 2, 2, -1, -4, -5, -15, -34, -47,
- -49, -49, -58, -69, -73, -70, -63, -51, -30, -8, 5, 7, 3, -4, -11, -20,
- -29, -41, -49, -50, -46, -49, -54, -56, -50, -42, -33, -22, -13, -10, -6, 5,
- 12, -1, -30, -50, -50, -38, -27, -18, -10, -3, 1, 2, 2, -2, -4, 6,
- 24, 36, 36, 27, 19, 22, 30, 28, 10, -8, -10, 9, 30, 39, 35, 30,
- 26, 26, 28, 29, 29, 35, 53, 73, 80, 74, 65, 63, 69, 72, 64, 47,
- 33, 28, 29, 28, 21, 12, 6, 2, -2, 1, 4, 1, -2, 2, 6, -4,
- -23, -35, -38, -42, -51, -60, -66, -70, -71, -63, -45, -23, -5, 4, 6, 3,
- -2, -7, -18, -32, -42, -43, -43, -47, -52, -54, -53, -51, -42, -27, -20, -21,
- -14, 4, 17, 10, -13, -35, -45, -44, -37, -26, -17, -11, -3, 3, 3, -3,
- -9, -4, 13, 31, 35, 27, 19, 23, 34, 36, 19, -3, -10, 2, 19, 31,
- 35, 33, 29, 30, 32, 28, 22, 26, 43, 63, 76, 75, 67, 65, 71, 75,
- 70, 57, 43, 36, 34, 30, 26, 21, 14, 5, 1, 4, 3, -2, -2, 6,
- 11, 3, -11, -22, -29, -36, -43, -50, -57, -67, -74, -72, -60, -40, -19, -5,
- 2, 4, 6, 3, -8, -23, -32, -35, -40, -45, -47, -51, -57, -58, -47, -33,
- -30, -32, -24, -5, 13, 14, 1, -18, -36, -45, -42, -35, -27, -20, -11, 0,
- 3, -3, -12, -12, 1, 21, 31, 25, 16, 20, 34, 40, 26, 5, -7, -6,
- 7, 21, 27, 26, 27, 31, 33, 27, 17, 15, 28, 50, 65, 68, 64, 62,
- 68, 74, 72, 61, 51, 44, 35, 29, 28, 25, 15, 7, 5, 5, -1, -8,
- -5, 3, 8, 4, -4, -12, -22, -32, -38, -42, -50, -61, -72, -77, -73, -57,
- -36, -20, -11, -2, 7, 8, -3, -14, -22, -30, -38, -41, -42, -49, -60, -62,
- -52, -41, -40, -41, -34, -18, 0, 11, 10, -3, -23, -38, -42, -40, -36, -31,
- -20, -6, 2, -1, -13, -19, -9, 12, 25, 20, 12, 17, 30, 39, 34, 17,
- -2, -8, 1, 13, 19, 21, 23, 31, 37, 32, 18, 10, 18, 36, 55, 62,
- 60, 60, 67, 73, 72, 68, 61, 51, 41, 35, 34, 28, 18, 12, 11, 8,
- -2, -9, -7, 0, 4, 5, 3, -3, -14, -24, -31, -36, -41, -50, -64, -77,
- -80, -68, -51, -37, -26, -11, 3, 6, 2, -3, -13, -24, -32, -33, -34, -46,
- -60, -62, -54, -47, -46, -47, -43, -31, -13, 4, 12, 6, -9, -23, -34, -39,
- -40, -38, -29, -14, 0, 2, -11, -22, -15, 4, 17, 16, 11, 13, 25, 39,
- 41, 28, 9, -3, 0, 9, 15, 15, 19, 30, 40, 39, 26, 12, 11, 28,
- 45, 54, 56, 60, 66, 70, 73, 74, 69, 58, 49, 45, 42, 32, 22, 18,
- 19, 14, 3, -6, -7, -4, 0, 5, 6, 3, -5, -14, -24, -30, -32, -38,
- -53, -71, -78, -72, -63, -54, -39, -22, -8, 1, 6, 6, -4, -18, -25, -23,
- -25, -39, -54, -58, -54, -49, -49, -50, -49, -42, -26, -7, 7, 9, 2, -9,
- -20, -30, -38, -43, -39, -22, -2, 3, -9, -20, -16, -2, 11, 14, 10, 10,
- 20, 36, 46, 40, 22, 8, 6, 11, 13, 12, 15, 26, 41, 46, 36, 20,
- 14, 24, 38, 47, 54, 60, 64, 69, 76, 81, 76, 66, 60, 58, 53, 40,
- 30, 27, 27, 22, 12, 3, -3, -4, -1, 4, 8, 8, 5, -4, -15, -21,
- -21, -25, -41, -58, -69, -71, -70, -64, -51, -35, -23, -9, 5, 10, 1, -13,
- -17, -15, -19, -32, -46, -54, -54, -51, -50, -52, -55, -53, -40, -22, -6, 3,
- 4, -2, -10, -19, -32, -47, -49, -32, -11, -3, -10, -20, -20, -10, 2, 7,
- 5, 2, 10, 28, 42, 41, 29, 16, 10, 11, 11, 7, 6, 17, 35, 45,
- 39, 26, 18, 19, 26, 37, 47, 53, 56, 61, 73, 81, 76, 68, 65, 65,
- 59, 46, 36, 31, 28, 25, 19, 9, -1, -6, -4, -1, 2, 8, 9, 0,
- -10, -15, -14, -18, -32, -46, -57, -68, -74, -71, -61, -51, -41, -23, -2, 8,
- 2, -8, -11, -10, -13, -23, -37, -48, -53, -51, -49, -53, -59, -60, -53, -37,
- -19, -7, -3, -2, -1, -6, -22, -43, -52, -42, -21, -9, -12, -20, -23, -16,
- -4, 3, -1, -6, 0, 18, 34, 40, 33, 22, 16, 16, 13, 5, 0, 9,
- 27, 39, 40, 32, 24, 18, 19, 29, 40, 44, 46, 55, 69, 77, 75, 71,
- 70, 70, 65, 55, 45, 37, 32, 30, 26, 17, 7, 0, -5, -6, -1, 8,
- 11, 4, -5, -7, -7, -13, -21, -30, -44, -59, -69, -69, -65, -63, -56, -36,
- -13, 1, 1, -4, -6, -5, -6, -12, -25, -40, -47, -47, -46, -50, -56, -62,
- -61, -48, -30, -18, -12, -6, 4, 6, -7, -32, -49, -46, -30, -16, -12, -19,
- -25, -20, -7, 0, -3, -9, -7, 8, 26, 36, 34, 27, 24, 24, 19, 7,
- -2, 4, 18, 31, 38, 38, 30, 20, 18, 26, 34, 35, 38, 48, 62, 71,
- 73, 72, 73, 72, 70, 64, 53, 43, 38, 35, 30, 23, 16, 7, -4, -10,
- -4, 6, 8, 3, -1, -2, -4, -9, -12, -19, -33, -51, -61, -65, -69, -73,
- -70, -52, -30, -13, -6, -5, -7, -5, -2, -5, -17, -31, -41, -45, -44, -45,
- -53, -64, -67, -58, -43, -31, -26, -17, -1, 10, 3, -19, -41, -48, -39, -23,
- -16, -21, -27, -24, -12, -3, -5, -13, -15, -3, 16, 28, 29, 26, 28, 31,
- 24, 10, 0, 0, 8, 20, 33, 38, 32, 22, 19, 24, 28, 28, 30, 40,
- 52, 61, 68, 71, 72, 73, 73, 69, 59, 51, 45, 39, 32, 28, 26, 15,
- 0, -9, -5, 2, 4, 2, 1, -1, -4, -6, -5, -10, -24, -41, -50, -56,
- -66, -76, -77, -66, -47, -27, -15, -11, -10, -5, 0, -1, -8, -20, -33, -40,
- -40, -40, -48, -62, -70, -64, -51, -43, -39, -29, -11, 7, 10, -5, -28, -43,
- -41, -28, -20, -22, -29, -28, -17, -6, -5, -14, -20, -12, 6, 19, 22, 23,
- 30, 35, 31, 20, 8, 0, 1, 13, 29, 37, 33, 26, 25, 27, 27, 25,
- 26, 33, 43, 54, 63, 67, 70, 74, 76, 72, 66, 61, 54, 44, 37, 36,
- 34, 24, 8, -3, -4, -2, 0, 2, 3, -1, -5, -3, 2, -2, -16, -29,
- -36, -44, -57, -70, -79, -76, -60, -41, -27, -19, -14, -8, -1, 3, 0, -10,
- -24, -33, -33, -32, -40, -55, -65, -63, -56, -51, -48, -40, -23, -1, 12, 7,
- -13, -32, -37, -29, -21, -21, -28, -29, -19, -6, -2, -12, -20, -14, 0, 11,
- 16, 22, 30, 37, 38, 33, 21, 7, 0, 9, 26, 36, 35, 32, 32, 32,
- 31, 28, 27, 30, 38, 50, 58, 63, 70, 78, 79, 76, 74, 72, 64, 53,
- 46, 45, 44, 34, 20, 9, 3, -1, 1, 7, 7, 0, -4, 2, 8, 5,
- -5, -15, -23, -30, -41, -58, -73, -77, -68, -53, -38, -28, -21, -14, -5, 4,
- 7, -1, -15, -25, -25, -24, -32, -48, -59, -61, -59, -57, -57, -54, -39, -16,
- 4, 8, -5, -24, -33, -30, -24, -24, -32, -35, -26, -11, -6, -14, -20, -19,
- -10, -2, 5, 13, 21, 29, 37, 40, 30, 11, 0, 4, 17, 27, 30, 31,
- 31, 32, 32, 29, 23, 23, 31, 40, 45, 52, 63, 72, 74, 73, 75, 75,
- 67, 56, 51, 50, 46, 38, 29, 18, 6, -3, -1, 5, 3, -4, -7, -2,
- 4, 5, -2, -11, -17, -21, -30, -47, -66, -78, -77, -66, -53, -42, -34, -27,
- -16, -3, 6, 1, -12, -21, -21, -21, -28, -42, -54, -60, -60, -61, -65, -67,
- -57, -35, -11, 1, -3, -18, -30, -30, -25, -27, -36, -41, -32, -19, -13, -17,
- -22, -22, -19, -14, -6, 2, 7, 17, 31, 41, 34, 17, 3, 1, 8, 17,
- 23, 25, 26, 30, 32, 28, 22, 21, 25, 30, 34, 42, 54, 63, 66, 70,
- 77, 77, 69, 61, 57, 55, 49, 44, 39, 28, 11, 2, 2, 5, 3, -3,
- -8, -4, 3, 6, 2, -4, -9, -11, -16, -31, -52, -68, -75, -71, -61, -50,
- -43, -38, -26, -8, 5, 4, -6, -13, -14, -13, -19, -31, -44, -51, -52, -55,
- -64, -71, -67, -49, -24, -4, -1, -12, -22, -21, -18, -22, -33, -39, -33, -22,
- -16, -16, -17, -19, -20, -16, -9, -4, -2, 5, 18, 31, 37, 32, 21, 11,
- 9, 12, 17, 20, 24, 28, 32, 31, 28, 26, 26, 26, 28, 34, 43, 51,
- 57, 65, 74, 77, 75, 72, 68, 63, 59, 56, 53, 44, 31, 19, 12, 11,
- 8, 3, -2, -3, 0, 4, 5, 2, 0, -1, -3, -11, -25, -42, -58, -66,
- -65, -59, -54, -51, -42, -27, -11, -2, -3, -6, -7, -7, -9, -16, -27, -36,
- -40, -44, -52, -63, -70, -66, -49, -28, -15, -13, -16, -16, -13, -16, -24, -31,
- -33, -29, -24, -19, -17, -19, -20, -18, -14, -13, -12, -6, 7, 22, 33, 35,
- 28, 18, 12, 12, 14, 17, 21, 27, 31, 31, 30, 30, 28, 25, 25, 30,
- 36, 42, 49, 58, 67, 74, 76, 75, 71, 66, 62, 60, 59, 53, 41, 29,
- 19, 14, 11, 7, 1, -3, -2, 1, 3, 3, 1, 0, 0, -3, -11, -26,
- -44, -59, -65, -63, -60, -57, -52, -41, -25, -11, -4, -4, -6, -6, -6, -9,
- -17, -27, -35, -39, -44, -53, -65, -71, -65, -47, -28, -16, -15, -16, -15, -14,
- -17, -25, -32, -33, -29, -24, -19, -17, -19, -20, -18, -14, -13, -12, -6, -2,
- 1, 6, 5, 21, 46, 42, 15, 0, 5, 34, 48, 29, -4, -31, -33, -17,
- 26, 49, 32, 0, -21, -15, 14, 24, 24, 16, 0, 3, 11, 11, 11, 5,
- 9, 9, 8, 11, 30, 27, 22, 7, -3, -3, 10, 2, -2, -4, -13, -4,
- -4, -2, -2, -3, -7, -6, -14, -15, -14, -14, -13, -3, -14, -16, -18, -13,
- -15, -16, -22, -20, -14, -3, -6, -4, -14, -11, -6, -10, -15, -15, -16, -9,
- -10, -19, -3, -5, -17, -15, -18, -16, -14, -14, -12, -15, -7, -22, -19, -17,
- -20, -11, -17, -14, -11, -8, -10, -13, -12, -11, -6, -6, -9, 1, 1, -3,
- 0, 6, -2, -9, 7, -8, 8, 4, 3, 1, -6, -2, -2, 2, -5, -7,
- -4, -7, -8, -9, -6, -6, 0, -8, -12, -12, -13, -8, -4, -7, -3, -11,
- -6, -15, -7, -9, -9, -3, -10, -8, -9, -15, -10, -2, 2, -7, -16, -17,
- -15, -13, -9, -6, -5, -7, -9, -15, -17, -12, -19, -12, -8, -8, -4, -6,
- -3, 0, -4, -11, -13, -7, -6, -2, 4, 4, 8, 10, 4, 3, 3, 4,
- 7, 12, 11, 14, 15, 20, 20, 18, 16, 17, 15, 14, 15, 22, 23, 28,
- 34, 29, 28, 17, 22, 24, 23, 25, 28, 28, 30, 24, 19, 16, 13, 18,
- 20, 15, 8, 2, 3, 0, 2, 0, -3, -2, -9, -20, -23, -25, -24, -23,
- -27, -33, -38, -39, -44, -36, -42, -44, -48, -53, -54, -56, -52, -50, -40, -35,
- -44, -43, -44, -39, -28, -24, -23, -22, -15, -9, 2, 11, 19, 28, 31, 31,
- 32, 35, 43, 61, 70, 78, 81, 73, 78, 78, 78, 85, 82, 85, 88, 87,
- 84, 83, 83, 79, 74, 62, 49, 45, 42, 43, 44, 38, 30, 18, 6, -5,
- -15, -17, -15, -22, -28, -38, -46, -48, -50, -58, -59, -72, -80, -83, -89, -88,
- -89, -87, -81, -84, -93, -105, -110, -109, -110, -102, -96, -82, -65, -62, -60, -60,
- -60, -51, -43, -37, -28, -16, 1, 15, 28, 35, 41, 46, 53, 56, 60, 66,
- 77, 91, 101, 102, 101, 99, 104, 103, 97, 91, 86, 90, 91, 86, 85, 79,
- 75, 71, 59, 48, 39, 35, 33, 32, 28, 22, 15, 13, 7, 3, -7, -15,
- -16, -18, -19, -23, -28, -29, -33, -37, -47, -52, -56, -63, -61, -70, -67, -70,
- -72, -72, -80, -93, -91, -99, -103, -96, -108, -105, -109, -112, -94, -81, -73, -67,
- -71, -77, -69, -63, -57, -38, -27, -15, 0, 4, 6, 19, 26, 41, 53, 49,
- 56, 58, 69, 84, 91, 95, 101, 103, 98, 93, 85, 87, 102, 102, 103, 95,
- 81, 78, 78, 71, 66, 60, 51, 50, 44, 39, 34, 34, 32, 27, 15, 0,
- -6, -8, -3, -3, -11, -10, -18, -21, -26, -35, -39, -38, -44, -48, -53, -63,
- -61, -61, -71, -63, -86, -89, -86, -107, -99, -109, -108, -109, -108, -121, -128, -105,
- -102, -83, -67, -88, -82, -76, -78, -62, -47, -41, -19, -6, 1, 7, 13, 33,
- 44, 64, 61, 59, 68, 73, 93, 98, 107, 114, 109, 123, 107, 100, 105, 100,
- 111, 117, 100, 93, 92, 86, 85, 80, 70, 59, 58, 47, 38, 41, 33, 40,
- 38, 25, 16, 1, -2, -3, -3, -4, -10, -16, -12, -21, -28, -28, -36, -38,
- -39, -52, -61, -61, -67, -63, -65, -76, -77, -86, -95, -95, -107, -109, -112, -112,
- -121, -121, -122, -105, -79, -80, -71, -80, -84, -73, -70, -56, -43, -28, -10, 6,
- 11, 17, 31, 43, 63, 69, 69, 65, 77, 88, 101, 113, 112, 127, 122, 122,
- 115, 104, 112, 116, 122, 117, 106, 99, 97, 96, 94, 86, 75, 70, 61, 53,
- 44, 41, 46, 47, 45, 28, 19, 9, 5, 9, 1, -8, -14, -20, -24, -26,
- -28, -29, -36, -39, -42, -45, -41, -42, -45, -46, -49, -47, -50, -55, -53, -61,
- -63, -67, -83, -78, -89, -91, -88, -100, -93, -108, -110, -110, -115, -90, -100, -91,
- -80, -91, -73, -62, -60, -41, -33, -36, -25, -16, -9, 8, 18, 35, 40, 57,
- 61, 66, 95, 94, 106, 114, 105, 117, 111, 117, 118, 115, 120, 111, 109, 111,
- 104, 102, 106, 93, 88, 76, 66, 63, 52, 53, 31, 27, 25, 5, 12, 1,
- -5, 0, -15, -17, -23, -27, -27, -31, -31, -37, -44, -41, -43, -43, -35, -45,
- -43, -41, -50, -49, -51, -57, -58, -62, -72, -76, -79, -81, -82, -86, -92, -94,
- -100, -109, -110, -102, -99, -96, -83, -96, -83, -67, -73, -45, -41, -42, -27, -27,
- -19, -5, 7, 14, 30, 44, 46, 57, 75, 84, 98, 108, 102, 112, 114, 110,
- 120, 115, 116, 117, 108, 112, 107, 104, 108, 99, 96, 90, 73, 69, 66, 57,
- 48, 36, 26, 18, 13, 6, -3, 3, -8, -14, -15, -26, -25, -26, -33, -33,
- -40, -45, -45, -45, -42, -43, -44, -45, -48, -46, -55, -57, -58, -62, -67, -73,
- -78, -80, -81, -82, -89, -93, -99, -106, -108, -115, -100, -95, -103, -77, -91, -85,
- -59, -63, -48, -32, -36, -33, -18, -14, -6, 11, 21, 27, 47, 55, 56, 81,
- 92, 96, 114, 106, 111, 116, 110, 121, 113, 115, 115, 105, 111, 106, 101, 103,
- 100, 92, 84, 74, 66, 60, 58, 43, 29, 29, 13, 9, 10, -6, -2, -6,
- -16, -18, -22, -27, -30, -30, -35, -44, -43, -46, -46, -42, -44, -48, -45, -46,
- -50, -54, -51, -61, -63, -61, -85, -76, -80, -94, -75, -98, -97, -93, -111, -103,
- -106, -97, -97, -90, -79, -93, -73, -64, -67, -39, -38, -41, -20, -20, -12, 11,
- 10, 30, 40, 48, 62, 62, 85, 91, 99, 111, 101, 112, 111, 113, 120, 112,
- 119, 111, 108, 114, 101, 102, 104, 89, 91, 79, 63, 67, 56, 52, 41, 29,
- 26, 12, 14, 3, -5, 1, -14, -15, -19, -27, -24, -30, -31, -34, -43, -43,
- -45, -48, -40, -48, -48, -45, -51, -49, -53, -56, -57, -63, -69, -76, -86, -80,
- -86, -90, -87, -98, -101, -101, -108, -103, -88, -96, -88, -77, -89, -70, -60, -56,
- -39, -34, -30, -26, -11, -4, 6, 26, 27, 42, 54, 57, 72, 86, 95, 105,
- 107, 108, 112, 109, 116, 118, 112, 117, 108, 109, 107, 104, 103, 99, 97, 83,
- 77, 71, 57, 60, 49, 35, 30, 21, 11, 11, 4, -2, -3, -13, -17, -22,
- -24, -28, -29, -29, -39, -39, -44, -44, -41, -45, -44, -50, -49, -49, -56, -50,
- -60, -62, -55, -82, -70, -82, -90, -80, -95, -95, -100, -105, -112, -112, -93, -102,
- -91, -81, -91, -77, -60, -65, -45, -33, -40, -25, -21, -14, 5, 10, 30, 35,
- 49, 61, 61, 87, 94, 102, 109, 109, 112, 112, 116, 117, 116, 118, 116, 106,
- 113, 108, 101, 110, 96, 91, 84, 69, 66, 58, 54, 38, 29, 26, 12, 11,
- 6, -2, -2, -8, -16, -20, -23, -27, -28, -33, -34, -44, -43, -43, -47, -39,
- -44, -47, -43, -47, -49, -50, -52, -57, -58, -68, -75, -76, -83, -86, -86, -91,
- -97, -98, -103, -109, -102, -91, -99, -84, -81, -93, -65, -66, -60, -37, -42, -33,
- -25, -18, -9, 6, 16, 28, 41, 49, 57, 68, 84, 93, 102, 106, 106, 110,
- 107, 116, 114, 111, 119, 106, 111, 108, 101, 104, 99, 94, 85, 76, 68, 61,
- 56, 49, 34, 28, 21, 10, 10, 2, -3, -3, -13, -15, -24, -26, -28, -34,
- -31, -42, -45, -43, -48, -44, -43, -47, -47, -47, -48, -51, -57, -57, -63, -70,
- -72, -80, -86, -81, -92, -88, -96, -103, -100, -113, -110, -96, -101, -96, -79, -91,
- -82, -59, -68, -47, -34, -39, -29, -18, -13, -5, 18, 22, 32, 54, 52, 64,
- 83, 90, 100, 108, 109, 110, 113, 113, 116, 113, 117, 113, 106, 111, 103, 100,
- 101, 98, 86, 82, 73, 59, 61, 53, 36, 34, 24, 12, 10, 5, -5, -3,
- -8, -17, -18, -24, -27, -29, -30, -35, -40, -41, -45, -43, -43, -42, -45, -46,
- -44, -50, -49, -55, -58, -55, -71, -70, -79, -87, -77, -92, -88, -95, -104, -100,
- -115, -107, -91, -105, -85, -83, -97, -67, -68, -65, -37, -43, -33, -29, -21, -9,
- 0, 18, 23, 35, 55, 48, 69, 87, 86, 108, 107, 103, 117, 106, 117, 118,
- 113, 122, 109, 111, 111, 102, 110, 101, 98, 92, 77, 73, 62, 59, 54, 34,
- 34, 21, 11, 15, 2, 2, 2, -14, -12, -23, -26, -26, -33, -30, -40, -44,
- -42, -49, -41, -41, -44, -43, -46, -49, -51, -59, -54, -63, -67, -64, -84, -79,
- -76, -91, -82, -87, -100, -100, -101, -118, -101, -89, -107, -81, -82, -93, -65, -57,
- -57, -36, -26, -39, -17, -9, -13, 14, 21, 26, 45, 53, 54, 76, 88, 95,
- 111, 106, 111, 114, 109, 120, 115, 115, 116, 110, 105, 109, 104, 98, 105, 94,
- 83, 81, 68, 60, 62, 49, 32, 33, 18, 9, 12, 0, -3, -3, -13, -18,
- -20, -24, -27, -26, -31, -37, -40, -42, -42, -43, -42, -44, -48, -48, -47, -51,
- -54, -52, -56, -64, -68, -75, -84, -79, -89, -91, -93, -104, -105, -110, -114, -97,
- -97, -96, -78, -89, -81, -58, -66, -47, -34, -40, -31, -23, -14, -6, 14, 22,
- 31, 54, 55, 63, 87, 91, 103, 113, 105, 111, 113, 109, 119, 112, 117, 114,
- 106, 113, 106, 105, 105, 99, 93, 81, 74, 61, 58, 55, 36, 30, 25, 10,
- 11, 6, -5, 1, -8, -16, -19, -25, -27, -32, -32, -37, -44, -41, -47, -43,
- -39, -43, -44, -45, -46, -46, -56, -53, -55, -72, -64, -74, -91, -72, -88, -97,
- -80, -100, -105, -100, -111, -111, -88, -100, -99, -74, -97, -79, -54, -68, -43, -32,
- -41, -26, -10, -16, 6, 22, 19, 41, 51, 49, 69, 86, 88, 103, 107, 100,
- 119, 110, 111, 125, 110, 115, 115, 104, 108, 106, 99, 98, 98, 82, 76, 71,
- 60, 60, 52, 34, 30, 25, 9, 11, 3, -6, 0, -15, -18, -21, -27, -27,
- -30, -31, -38, -39, -43, -43, -39, -43, -44, -46, -47, -47, -54, -53, -59, -58,
- -65, -71, -75, -81, -75, -90, -83, -90, -100, -95, -111, -109, -101, -97, -100, -84,
- -86, -89, -62, -64, -50, -34, -37, -30, -21, -11, -8, 10, 19, 26, 47, 49,
- 59, 76, 89, 99, 107, 109, 110, 115, 113, 119, 115, 114, 115, 106, 111, 103,
- 103, 101, 98, 94, 81, 78, 65, 63, 59, 43, 34, 25, 17, 10, 7, -4,
- -3, -6, -14, -16, -23, -24, -28, -29, -33, -41, -41, -46, -43, -40, -44, -44,
- -46, -46, -47, -50, -54, -56, -58, -69, -70, -76, -83, -75, -87, -87, -91, -100,
- -100, -109, -108, -97, -98, -93, -83, -88, -76, -61, -59, -43, -36, -33, -28, -18,
- -11, -4, 14, 21, 31, 52, 51, 63, 84, 90, 101, 111, 104, 113, 113, 111,
- 118, 112, 114, 109, 108, 109, 102, 106, 101, 98, 94, 79, 74, 66, 58, 55,
- 39, 29, 24, 13, 11, 5, -4, 0, -10, -15, -17, -24, -25, -28, -29, -34,
- -41, -41, -47, -42, -44, -46, -45, -50, -45, -50, -55, -48, -60, -60, -65, -76,
- -77, -83, -84, -91, -92, -94, -106, -103, -109, -106, -89, -101, -82, -81, -88, -63,
- -66, -54, -36, -40, -31, -25, -16, -7, 6, 17, 30, 41, 55, 56, 73, 89,
- 92, 109, 104, 106, 114, 104, 117, 113, 110, 116, 105, 108, 106, 100, 102, 98,
- 94, 85, 74, 67, 59, 55, 48, 31, 28, 19, 10, 12, 0, 2, -2, -11,
- -11, -21, -21, -26, -30, -30, -40, -43, -43, -44, -40, -39, -41, -43, -42, -46,
- -52, -52, -58, -63, -65, -75, -79, -83, -80, -89, -85, -88, -101, -94, -104, -114,
- -93, -97, -104, -78, -92, -89, -60, -68, -48, -36, -36, -26, -21, -8, -5, 12,
- 23, 26, 47, 50, 54, 77, 85, 96, 109, 102, 114, 112, 109, 125, 112, 114,
- 118, 102, 110, 103, 99, 101, 96, 92, 79, 76, 66, 59, 61, 43, 32, 31,
- 14, 10, 9, -5, -2, -9, -17, -18, -28, -25, -31, -31, -31, -42, -38, -43,
- -41, -39, -43, -44, -47, -45, -48, -51, -53, -54, -61, -64, -67, -77, -76, -82,
- -81, -89, -93, -97, -106, -108, -105, -96, -99, -88, -82, -92, -67, -64, -60, -38,
- -38, -36, -24, -20, -16, 4, 11, 21, 36, 46, 53, 66, 85, 88, 103, 108,
- 102, 115, 107, 112, 115, 109, 114, 104, 106, 106, 99, 102, 101, 92, 89, 81,
- 67, 66, 58, 47, 39, 28, 21, 11, 12, 2, -2, 2, -12, -12, -17, -25,
- -24, -29, -30, -36, -39, -41, -41, -41, -39, -41, -44, -44, -47, -51, -52, -54,
- -59, -63, -65, -75, -79, -75, -90, -81, -89, -99, -92, -109, -109, -105, -99, -97,
- -92, -80, -90, -71, -58, -60, -37, -32, -37, -19, -15, -14, 9, 14, 23, 42,
- 46, 56, 67, 83, 96, 100, 111, 106, 111, 114, 111, 117, 111, 112, 109, 103,
- 107, 100, 99, 103, 92, 88, 82, 65, 66, 59, 48, 39, 27, 22, 12, 9,
- 5, -5, 0, -12, -16, -17, -26, -25, -26, -31, -34, -40, -41, -41, -41, -40,
- -42, -47, -43, -46, -46, -52, -50, -52, -61, -59, -74, -75, -77, -83, -84, -91,
- -92, -105, -100, -106, -109, -81, -103, -86, -73, -96, -64, -62, -59, -38, -39, -36,
- -28, -15, -11, 3, 18, 25, 37, 53, 53, 67, 89, 85, 106, 103, 98, 115,
- 99, 114, 115, 103, 116, 103, 104, 109, 98, 101, 98, 91, 84, 75, 67, 60,
- 55, 50, 31, 28, 20, 7, 15, 0, -3, 2, -15, -12, -19, -25, -24, -32,
- -32, -38, -44, -44, -45, -42, -41, -44, -43, -46, -44, -44, -58, -48, -63, -67,
- -63, -87, -75, -83, -90, -81, -94, -95, -95, -107, -109, -99, -95, -99, -85, -85,
- -90, -68, -62, -60, -36, -34, -39, -15, -13, -9, 14, 15, 29, 42, 50, 55,
- 68, 87, 91, 101, 107, 106, 110, 113, 114, 115, 114, 112, 108, 105, 106, 98,
- 98, 100, 88, 84, 75, 63, 63, 57, 46, 34, 28, 18, 10, 8, 0, -5,
- -5, -15, -19, -20, -26, -26, -26, -31, -36, -40, -42, -43, -42, -39, -44, -44,
- -42, -44, -47, -51, -52, -54, -65, -63, -76, -81, -68, -93, -84, -85, -104, -92,
- -105, -109, -95, -95, -96, -84, -82, -84, -64, -64, -52, -39, -37, -33, -23, -11,
- -9, 10, 20, 25, 49, 46, 60, 76, 82, 98, 101, 104, 110, 108, 108, 116,
- 111, 111, 113, 104, 108, 106, 101, 98, 99, 92, 80, 79, 63, 61, 59, 41,
- 35, 27, 18, 13, 9, 2, 0, -5, -12, -15, -20, -22, -26, -27, -30, -38,
- -39, -42, -40, -39, -40, -40, -45, -43, -47, -49, -54, -53, -57, -70, -59, -80,
- -77, -72, -93, -75, -91, -99, -93, -105, -108, -97, -92, -99, -80, -84, -84, -61,
- -59, -49, -35, -28, -34, -14, -9, -10, 19, 17, 27, 47, 47, 61, 72, 87,
- 95, 105, 104, 110, 111, 109, 117, 109, 111, 109, 103, 103, 102, 97, 95, 100,
- 85, 81, 77, 61, 64, 55, 42, 34, 26, 17, 10, 9, -3, -2, -5, -13,
- -15, -20, -23, -27, -27, -32, -37, -38, -41, -40, -41, -39, -43, -43, -40, -48,
- -47, -49, -55, -61, -59, -70, -80, -69, -87, -83, -79, -97, -89, -98, -101, -107,
- -96, -93, -101, -77, -90, -84, -62, -63, -49, -36, -34, -30, -15, -12, -2, 11,
- 20, 32, 39, 53, 56, 71, 87, 89, 103, 101, 109, 109, 109, 118, 106, 114,
- 111, 101, 107, 102, 93, 99, 94, 84, 85, 71, 65, 62, 54, 45, 32, 30,
- 16, 12, 8, -5, -2, -9, -14, -16, -24, -22, -27, -29, -31, -38, -41, -38,
- -44, -42, -41, -47, -45, -44, -48, -50, -50, -52, -62, -57, -69, -79, -69, -83,
- -88, -78, -99, -97, -92, -109, -106, -91, -100, -93, -76, -91, -80, -60, -66, -48,
- -37, -38, -32, -18, -15, -4, 11, 14, 31, 42, 48, 60, 69, 85, 94, 96,
- 102, 107, 103, 109, 115, 104, 112, 109, 100, 106, 103, 95, 97, 96, 84, 82,
- 73, 60, 62, 54, 41, 33, 27, 17, 14, 7, 0, 0, -8, -11, -16, -23,
- -23, -29, -29, -32, -39, -40, -40, -40, -41, -40, -46, -48, -45, -50, -51, -54,
- -56, -64, -63, -71, -78, -73, -84, -82, -87, -95, -93, -102, -102, -108, -95, -96,
- -95, -76, -90, -77, -57, -61, -42, -33, -35, -26, -13, -14, 3, 15, 17, 36,
- 45, 54, 60, 80, 89, 96, 108, 101, 111, 110, 109, 118, 107, 110, 109, 102,
- 103, 103, 95, 97, 96, 83, 82, 70, 60, 61, 51, 38, 28, 23, 11, 8,
- 4, -7, -3, -10, -16, -17, -22, -25, -27, -29, -35, -38, -43, -42, -41, -40,
- -39, -43, -42, -44, -45, -46, -53, -51, -55, -68, -65, -75, -79, -77, -88, -83,
- -94, -93, -101, -105, -96, -96, -92, -85, -85, -83, -71, -64, -57, -41, -41, -31,
- -27, -17, -7, 2, 18, 23, 38, 48, 51, 68, 78, 91, 98, 102, 106, 108,
- 110, 112, 115, 110, 115, 107, 107, 108, 99, 102, 97, 94, 87, 76, 70, 63,
- 60, 49, 39, 30, 22, 16, 8, 4, 0, -4, -10, -14, -20, -24, -25, -31,
- -30, -37, -41, -40, -41, -38, -39, -40, -42, -41, -43, -48, -44, -55, -58, -57,
- -71, -71, -73, -78, -79, -80, -88, -89, -95, -99, -103, -101, -88, -98, -85, -79,
- -90, -62, -60, -54, -35, -35, -27, -21, -9, -3, 7, 22, 26, 38, 52, 54,
- 67, 87, 89, 101, 105, 103, 114, 107, 117, 112, 107, 116, 100, 105, 103, 94,
- 98, 93, 87, 80, 73, 65, 59, 56, 45, 31, 28, 19, 6, 10, -3, -5,
- -4, -17, -16, -22, -24, -25, -30, -28, -39, -37, -40, -44, -40, -44, -46, -46,
- -47, -51, -50, -55, -55, -60, -67, -65, -81, -75, -78, -93, -78, -97, -101, -94,
- -113, -104, -92, -96, -91, -79, -86, -79, -58, -58, -49, -34, -34, -33, -14, -12,
- -5, 20, 19, 34, 49, 49, 66, 76, 91, 98, 98, 105, 104, 107, 111, 110,
- 109, 108, 108, 103, 101, 102, 97, 95, 96, 80, 75, 71, 56, 58, 49, 33,
- 28, 20, 13, 7, 4, -4, -7, -9, -18, -22, -22, -28, -30, -30, -38, -41,
- -41, -43, -40, -41, -40, -44, -43, -45, -48, -49, -55, -55, -59, -67, -66, -82,
- -70, -81, -86, -78, -101, -92, -98, -111, -98, -95, -95, -89, -76, -91, -70, -56,
- -61, -38, -34, -33, -25, -12, -10, 1, 21, 15, 39, 47, 48, 68, 75, 90,
- 97, 101, 103, 106, 106, 110, 111, 104, 111, 101, 99, 103, 96, 94, 95, 92,
- 75, 79, 64, 55, 64, 43, 36, 30, 17, 13, 9, 3, -4, -3, -12, -16,
- -18, -23, -25, -26, -29, -35, -38, -42, -40, -39, -41, -38, -48, -42, -45, -50,
- -49, -52, -57, -63, -57, -78, -76, -67, -94, -75, -88, -100, -92, -103, -106, -97,
- -88, -96, -81, -77, -85, -60, -55, -51, -35, -30, -33, -19, -9, -10, 17, 16,
- 30, 46, 48, 64, 72, 86, 96, 101, 104, 105, 111, 104, 116, 109, 107, 110,
- 104, 101, 104, 100, 93, 100, 86, 77, 78, 59, 60, 54, 40, 32, 23, 18,
- 9, 9, 0, -5, -6, -14, -17, -20, -23, -25, -26, -31, -35, -39, -40, -36,
- -40, -37, -40, -45, -42, -45, -48, -51, -50, -57, -64, -62, -76, -78, -71, -90,
- -84, -88, -101, -97, -105, -108, -94, -97, -92, -81, -87, -76, -63, -58, -42, -36,
- -33, -27, -15, -10, -2, 18, 19, 34, 49, 47, 66, 78, 86, 102, 104, 104,
- 111, 109, 112, 115, 112, 110, 108, 106, 101, 102, 98, 96, 97, 86, 79, 72,
- 62, 61, 51, 39, 32, 20, 15, 10, 2, 1, -4, -9, -13, -18, -22, -24,
- -25, -29, -33, -37, -41, -39, -37, -39, -39, -43, -46, -46, -49, -49, -56, -54,
- -57, -68, -66, -73, -77, -79, -83, -90, -96, -95, -107, -110, -98, -97, -98, -76,
- -87, -83, -56, -68, -49, -34, -43, -28, -26, -18, -8, 3, 14, 22, 39, 47,
- 54, 70, 83, 90, 101, 100, 104, 107, 102, 113, 103, 106, 109, 95, 106, 99,
- 95, 101, 92, 93, 83, 74, 66, 60, 56, 44, 33, 26, 17, 12, 8, 1,
- 2, -4, -11, -10, -21, -19, -25, -29, -28, -39, -38, -41, -41, -37, -40, -42,
- -43, -42, -45, -47, -48, -56, -52, -59, -69, -67, -78, -78, -79, -88, -86, -95,
- -100, -99, -112, -95, -92, -101, -77, -86, -86, -62, -65, -51, -39, -35, -31, -26,
- -8, -11, 7, 26, 21, 45, 53, 50, 76, 86, 90, 105, 102, 105, 109, 108,
- 115, 107, 112, 110, 100, 108, 100, 96, 100, 93, 89, 79, 72, 64, 58, 56,
- 42, 31, 28, 14, 10, 9, -5, -2, -6, -14, -15, -22, -22, -27, -28, -31,
- -41, -37, -41, -42, -37, -41, -45, -43, -45, -47, -48, -49, -58, -53, -64, -71,
- -68, -82, -75, -83, -91, -87, -103, -97, -104, -111, -90, -98, -95, -77, -91, -76,
- -61, -63, -43, -41, -35, -29, -23, -7, -7, 13, 22, 24, 50, 50, 59, 82,
- 82, 99, 102, 100, 110, 105, 111, 113, 104, 114, 103, 104, 107, 96, 102, 97,
- 92, 90, 77, 73, 64, 58, 53, 38, 31, 23, 13, 12, 3, 0, -2, -11,
- -10, -17, -21, -20, -29, -27, -33, -40, -38, -44, -39, -39, -43, -41, -42, -42,
- -46, -42, -53, -53, -52, -71, -67, -73, -83, -80, -81, -89, -93, -91, -100, -106,
- -97, -96, -93, -88, -81, -85, -79, -59, -58, -48, -30, -36, -28, -11, -9, -2,
- 21, 22, 32, 50, 52, 58, 79, 89, 90, 104, 104, 100, 113, 111, 109, 114,
- 109, 107, 103, 104, 99, 94, 97, 91, 78, 79, 65, 58, 61, 47, 37, 30,
- 23, 14, 10, 7, -7, -4, -8, -21, -17, -23, -30, -26, -30, -36, -37, -39,
- -38, -38, -36, -38, -45, -41, -45, -49, -51, -56, -57, -63, -64, -69, -78, -70,
- -80, -84, -84, -91, -100, -98, -106, -108, -90, -103, -90, -80, -93, -65, -64, -52,
- -38, -37, -27, -26, -12, -6, 3, 18, 22, 36, 48, 54, 69, 84, 89, 105,
- 103, 106, 117, 105, 117, 113, 106, 113, 101, 105, 101, 99, 98, 93, 94, 83,
- 75, 70, 60, 55, 49, 33, 27, 19, 10, 8, -2, -2, -7, -13, -12, -22,
- -20, -23, -28, -28, -35, -39, -40, -41, -40, -42, -40, -43, -42, -42, -44, -46,
- -49, -52, -59, -60, -70, -74, -71, -84, -82, -88, -96, -98, -100, -105, -102, -88,
- -95, -83, -79, -87, -62, -62, -52, -40, -39, -31, -27, -14, -10, 7, 17, 25,
- 42, 49, 59, 72, 85, 92, 103, 103, 102, 111, 104, 113, 110, 104, 112, 102,
- 107, 103, 101, 99, 97, 92, 81, 76, 64, 61, 54, 42, 33, 24, 17, 11,
- 8, -2, -2, -5, -13, -12, -22, -23, -26, -31, -32, -38, -40, -43, -39, -40,
- -41, -40, -44, -41, -44, -47, -51, -49, -62, -55, -68, -78, -68, -89, -79, -81,
- -96, -85, -101, -100, -103, -98, -91, -97, -79, -83, -87, -61, -64, -55, -31, -41,
- -29, -15, -19, 3, 9, 18, 33, 36, 56, 54, 71, 87, 87, 103, 103, 103,
- 110, 107, 113, 112, 108, 111, 101, 104, 103, 92, 101, 92, 84, 84, 66, 65,
- 59, 51, 45, 31, 27, 16, 10, 6, -3, -3, -9, -15, -16, -22, -24, -25,
- -30, -28, -36, -40, -36, -42, -38, -41, -45, -44, -47, -47, -49, -51, -52, -54,
- -62, -68, -73, -78, -81, -84, -83, -97, -94, -101, -113, -100, -99, -96, -87, -83,
- -85, -75, -60, -60, -43, -36, -38, -27, -20, -15, 0, 14, 19, 33, 47, 49,
- 67, 78, 90, 100, 103, 105, 107, 108, 110, 112, 109, 109, 107, 102, 105, 100,
- 99, 98, 95, 84, 80, 69, 59, 60, 48, 36, 31, 18, 14, 9, 3, -2,
- -5, -10, -15, -19, -24, -25, -28, -31, -34, -39, -41, -40, -38, -40, -38, -43,
- -43, -42, -48, -47, -53, -54, -58, -67, -63, -79, -73, -78, -90, -80, -98, -97,
- -101, -109, -105, -93, -98, -90, -76, -93, -66, -60, -59, -33, -42, -32, -26, -18,
- -9, 0, 17, 21, 38, 48, 53, 69, 82, 93, 101, 107, 102, 112, 108, 111,
- 115, 105, 112, 103, 105, 104, 96, 103, 95, 95, 85, 76, 68, 63, 59, 47,
- 38, 26, 19, 13, 7, 1, -3, -4, -14, -12, -19, -23, -21, -29, -29, -35,
- -40, -41, -42, -39, -43, -42, -46, -43, -47, -45, -48, -54, -47, -66, -61, -68,
- -85, -66, -90, -84, -84, -103, -91, -106, -105, -96, -90, -92, -81, -79, -86, -59,
- -59, -53, -34, -36, -33, -19, -10, -10, 17, 20, 26, 52, 48, 60, 75, 85,
- 95, 102, 104, 102, 111, 107, 113, 110, 109, 111, 103, 107, 102, 97, 96, 95,
- 85, 77, 73, 56, 60, 52, 37, 33, 22, 16, 11, 7, -3, -4, -6, -16,
- -14, -21, -24, -24, -28, -32, -37, -38, -42, -36, -37, -39, -39, -43, -40, -42,
- -48, -50, -50, -64, -57, -70, -84, -63, -90, -81, -77, -101, -85, -99, -105, -102,
- -100, -92, -99, -79, -89, -86, -58, -65, -49, -29, -41, -26, -11, -19, 6, 12,
- 14, 39, 37, 52, 60, 68, 90, 90, 104, 102, 106, 111, 108, 118, 109, 109,
- 111, 98, 106, 101, 90, 101, 90, 82, 86, 63, 65, 63, 48, 47, 29, 25,
- 16, 10, 6, -6, -3, -13, -18, -16, -26, -25, -25, -32, -30, -39, -43, -37,
- -43, -39, -39, -48, -44, -46, -53, -50, -56, -59, -59, -67, -72, -77, -76, -84,
- -83, -84, -100, -95, -103, -115, -98, -93, -103, -82, -82, -91, -60, -62, -54, -34,
- -35, -31, -23, -13, -11, 7, 19, 21, 43, 48, 55, 73, 85, 94, 104, 102,
- 109, 110, 105, 118, 107, 109, 113, 98, 106, 103, 96, 99, 98, 90, 82, 79,
- 62, 62, 58, 41, 34, 26, 14, 10, 8, -3, -2, -5, -14, -13, -20, -20,
- -24, -26, -28, -38, -39, -42, -42, -41, -41, -42, -48, -41, -43, -50, -41, -49,
- -59, -50, -68, -74, -67, -82, -80, -89, -87, -101, -101, -93, -121, -85, -90, -105,
- -65, -93, -82, -55, -69, -49, -38, -46, -32, -27, -19, -5, 3, 19, 26, 41,
- 53, 52, 81, 81, 95, 104, 90, 113, 101, 105, 118, 99, 113, 109, 100, 109,
- 104, 98, 104, 96, 89, 83, 71, 66, 57, 56, 38, 28, 29, 8, 17, 6,
- -2, 3, -24, -13, -79, -103, -120, -116, -104, -87, -76, -63, 63, 82, 97, 108,
- 119, 99, 70, 69, 80, 91, 92, 98, 115, 124, 127, 113, 82, 42, 4, -44,
- -70, -82, -100, -87, -62, -58, -71, -65, -79, -60, -102, -113, -62, -44, -31, -31,
- -22, -18, -3, 4, 11, 20, 28, 11, 15, 18, 27, 18, 7, 13, 26, 11,
- -19, -69, -108, -84, -51, -21, -3, -6, -18, -17, -31, -33, -18, 2, 4, 26,
- 47, 48, 77, 117, 127, 127, 127, 121, 110, 86, 72, 62, 46, 11, 17, -2,
- -7, -13, -44, -60, -61, -61, -63, -72, -79, -99, -116, -127, -128, -128, -124, -81,
- -51, -4, 5, -6, 7, 8, 9, 31, 31, 16, 34, 28, 34, 34, 46, 78,
- 84, 93, 69, 47, 40, 64, 44, 27, 22, 0, -29, -8, 15, -6, -36, -66,
- -68, -42, 0, 6, 1, 13, 24, 41, 64, 58, 50, 40, 4, 0, 3, -24,
- -3, 21, 28, 26, 9, -30, -42, -61, -85, -92, -91, -96, -87, -74, -31, -20,
- -38, -14, -44, -17, 18, -25, -9, 7, 1, 11, -2, -19, 12, 47, 76, 72,
- 58, 68, 69, 82, 86, 76, 58, 9, -23, -12, -7, -22, -2, 0, -9, -2,
- -15, -10, -3, -22, -17, -38, -44, -33, -24, -27, -16, 0, -15, 20, 19, 18,
- 1, 10, 41, -1, -25, -25, -11, 30, 37, 9, 45, 37, -30, -30, 21, 5,
- -26, -43, -56, -42, -48, -48, -29, -62, -76, -42, -23, -12, -14, 8, 45, 36,
- 40, 25, 14, 11, 40, 46, 55, 65, 30, 17, 30, 36, 33, 18, 13, 16,
- 15, 46, 37, 2, -1, -26, -36, -19, -21, -36, -62, -51, -48, -20, -2, 3,
- -12, -12, -10, -35, -37, -49, -22, 14, 61, 40, 60, 75, 33, 41, 48, 38,
- 29, -32, -45, -56, -64, -61, -30, -20, 30, 10, -46, -37, -35, -30, -24, -12,
- -23, -34, -29, -22, -20, -14, 4, 44, 77, 49, 10, 8, 24, 20, 28, 31,
- 27, 40, 35, 69, 39, 54, 38, 26, 22, 43, 36, 7, 14, 2, -25, -50,
- -51, -56, -42, -55, -46, -36, -44, -36, -35, 1, 23, 11, -3, -34, -66, -33,
- -12, -31, -27, -13, -1, 21, 31, 23, 0, -11, -3, -2, 9, 27, 5, -8,
- -2, -17, -13, 10, 9, 3, 35, 32, 43, 24, 15, 2, -15, -9, -5, 2,
- 5, 27, 25, 42, 76, 61, 17, 25, 14, -5, -17, -24, -6, 11, 23, 7,
- -8, 5, -11, -23, -27, -48, -30, -12, -26, -36, -37, -39, -46, -61, -55, -23,
- -20, -22, -14, -10, -16, -16, -22, -11, -3, -14, -34, -16, 9, 28, 25, 50,
- 63, 52, 56, 46, 50, 54, 56, 45, 54, 29, 20, 21, 0, 0, 6, 16,
- 28, 14, -1, -9, -10, -4, -9, -13, -7, -21, -27, -29, -40, -41, -35, -42,
- -64, -11, 9, 2, -12, -24, -37, -40, -34, -29, -34, -12, -26, -20, -6, -4,
- 5, 5, 27, 1, -17, 2, 21, 12, 8, 9, 15, 23, 24, 1, 5, 22,
- 25, 28, 57, 55, 41, 33, 36, 27, 5, 1, 15, 34, 23, 4, 20, 18,
- -1, -21, -22, -15, -17, -8, -6, -6, -12, -15, -26, 1, 29, -8, -40, -52,
- -55, -19, -21, -36, -48, -56, -29, -15, -29, -39, -46, -35, -14, -11, -16, 1,
- 27, 22, -10, -14, -7, -12, -12, 23, 55, 48, 65, 42, 20, 46, 45, 49,
- 42, 38, 34, 25, 33, 21, 10, 38, 40, 26, 22, 37, 33, 12, 4, 7,
- -14, -49, -41, -36, -53, -40, -35, -44, -31, -22, -19, -50, -78, -80, -78, -48,
- -31, -18, -27, -28, -7, -17, -11, 5, 32, 39, 19, 14, 22, 34, 37, 23,
- 20, 40, 40, 27, 14, 11, 7, 29, 34, 19, 32, 7, -15, -12, -24, -12,
- 8, 6, 21, 34, 29, -6, -22, -15, 1, -1, 24, 27, 20, 36, 42, 45,
- 27, -14, -50, -34, -14, -26, -25, -10, 10, -4, -28, -30, -34, -69, -91, -85,
- -74, -51, -38, -24, -19, -9, -7, -30, -35, -30, -36, -12, 25, 32, 44, 50,
- 45, 51, 68, 94, 90, 74, 60, 52, 64, 48, 30, 11, 11, 11, 2, 14,
- 24, 16, 13, -7, -17, -9, -12, -20, -32, -45, -54, -58, -35, -23, -46, -51,
- -33, -28, -29, -24, -36, -30, -24, -22, -20, -13, -9, -14, -7, 10, 26, 22,
- 9, 9, 10, -2, -9, -15, -11, -1, 19, 27, 33, 28, 5, 3, 5, 6,
- 10, 14, 24, 32, 36, 40, 41, 37, 19, 11, 3, -7, -10, -7, 6, 27,
- 38, 28, 23, 16, 18, 15, -7, -33, -20, -13, -24, -25, -19, -15, -26, -52,
- -56, -48, -41, -36, -30, -32, -30, -15, -38, -49, -47, -32, -17, -17, -11, -3,
- 3, 8, 24, 28, 16, 6, 1, 7, 28, 41, 42, 69, 87, 78, 73, 62,
- 30, 14, 9, 7, 15, 32, 20, 10, -8, -20, 2, 9, -2, 5, 12, -4,
- -12, -19, -32, -37, -29, -24, -28, -39, -43, -40, -44, -28, -25, -33, -39, -37,
- -34, -29, -28, -25, -19, -1, -5, -22, -12, 2, 6, 38, 46, 25, 30, 41,
- 47, 37, 21, 7, -7, -8, 11, 39, 48, 43, 35, 27, 25, 22, -1, -22,
- -11, 13, -4, -13, -3, -8, -7, -11, -17, -5, 5, 9, 8, 15, 25, 16,
- 22, 20, 5, -16, -27, -29, -30, -9, 9, 9, 3, -14, -50, -56, -56, -79,
- -92, -80, -57, -24, 12, 10, 11, 4, -22, -21, -13, -2, 4, 10, 15, 8,
- 35, 72, 53, 44, 25, 25, 48, 56, 69, 53, 50, 75, 85, 71, 33, 12,
- -16, -32, -25, -14, -5, -16, -23, -19, -22, -39, -41, -47, -45, -33, -35, -39,
- -38, -35, -34, -29, -28, -28, -23, -10, -7, -9, -11, -18, -5, 13, 1, -13,
- -8, -5, 6, 27, 46, 43, 25, 8, 11, 16, 18, 23, 30, 12, 5, 10,
- 7, 5, -6, -4, -5, 1, 10, 9, 15, 21, 17, 10, -8, -16, 10, 33,
- 34, 23, 13, 17, 17, 9, 11, 7, -4, -8, -8, -22, -27, -26, -19, -7,
- -18, -16, -16, -47, -62, -55, -36, -16, -25, -33, -30, -34, -42, -49, -41, -43,
- -31, -20, -3, 28, 48, 66, 64, 36, 20, 26, 21, 22, 39, 51, 45, 39,
- 40, 53, 56, 39, 24, 16, 12, 16, 24, 27, 16, 13, 7, -18, -33, -50,
- -47, -33, -24, -20, -26, -32, -31, -46, -53, -58, -56, -29, -13, -11, -2, 8,
- -11, -24, -11, -9, -6, -2, -6, 1, 4, 5, 11, 6, 7, 16, 30, 28,
- 19, 15, 7, 4, 11, 27, 22, 6, 9, 11, 3, 4, 17, 27, 18, 11,
- 12, 5, 2, -2, -6, -7, -2, 10, 12, 9, 1, -2, 3, 4, 11, 21,
- 30, 28, 6, -9, -18, -22, -22, -38, -41, -27, -18, -18, -27, -27, -23, -32,
- -35, -32, -34, -30, -25, -24, -18, -9, -5, 5, -5, -26, -19, -11, -4, 11,
- 37, 48, 46, 50, 53, 50, 45, 45, 37, 18, 24, 44, 38, 43, 47, 29,
- 15, 11, 10, 12, 4, -8, -6, -4, -17, -27, -28, -36, -34, -37, -53, -53,
- -46, -38, -38, -37, -28, -24, -23, -37, -42, -30, 0, 20, 18, 12, 14, 9,
- 2, 6, 15, 13, 10, 14, 12, 2, 12, 29, 21, 1, 7, 21, 19, 14,
- 15, 15, 4, -1, 5, -1, -4, 0, -2, 3, 6, 6, 13, 21, 15, 7,
- 3, 5, 2, -3, 3, 3, 5, 8, 10, 16, 14, -1, -7, 2, 11, 12,
- -10, -35, -42, -26, -21, -37, -44, -44, -47, -42, -27, -27, -23, -15, -16, -20,
- -21, -14, -12, -9, -7, -6, 0, 13, 30, 32, 37, 38, 31, 24, 25, 43,
- 54, 49, 46, 44, 40, 41, 30, 9, -1, 6, 22, 31, 22, 9, 0, -14,
- -23, -29, -29, -28, -35, -39, -39, -39, -33, -25, -30, -44, -49, -45, -45, -35,
- -19, 2, 16, 16, 9, 0, 0, 6, 2, -1, 11, 27, 40, 32, 16, -2,
- -2, 1, 3, 1, 7, 12, 6, 8, 11, 5, -1, -2, -1, 1, 8, 10,
- 5, 4, 14, 17, 6, -1, 0, 4, 4, 17, 23, 19, 25, 20, 5, -8,
- -9, -2, -1, -6, -3, 13, 16, 1, -13, -19, -21, -26, -34, -37, -23, -13,
- -13, -24, -40, -42, -40, -39, -29, -22, -21, -18, -12, -2, 18, 24, 10, 0,
- -6, -4, 15, 33, 34, 34, 44, 41, 31, 33, 44, 43, 31, 22, 20, 17,
- 16, 23, 22, 19, 21, 10, -5, -6, -9, -8, -2, -5, -16, -28, -36, -47,
- -53, -39, -23, -21, -24, -32, -43, -39, -34, -24, -18, -14, -11, -12, -6, 10,
- 29, 41, 40, 27, 14, 10, 4, 1, 3, 2, 9, 19, 21, 9, -10, -16,
- -10, 8, 18, 20, 13, -3, -8, -4, -1, 2, 5, 5, -1, 3, 9, 12,
- 16, 16, 14, 9, 3, 5, 10, 4, -6, 1, 6, 5, 13, 20, 11, 1,
- -7, -21, -30, -25, -12, -9, -13, -19, -24, -29, -34, -30, -32, -39, -33, -24,
- -20, -22, -24, -13, 3, 6, 2, 1, 3, 5, 16, 30, 35, 35, 24, 16,
- 15, 19, 31, 37, 33, 28, 29, 29, 30, 26, 20, 15, 13, 10, 10, 12,
- 9, 7, -3, -21, -39, -44, -43, -42, -34, -26, -23, -18, -12, -18, -32, -36,
- -31, -27, -20, -10, -7, -9, -11, -5, 2, 12, 19, 19, 25, 24, 11, 3,
- 15, 29, 30, 20, 9, 1, -1, 1, 5, 2, -3, -2, 0, -6, -18, -27,
- -20, -3, 8, 13, 15, 11, 7, 10, 18, 16, 10, 6, 3, -1, 1, 11,
- 19, 19, 15, 14, 5, -2, -2, -7, -12, -15, -20, -16, -10, -5, 2, 1,
- -13, -29, -33, -24, -10, -6, -13, -18, -23, -31, -32, -26, -22, -18, -13, -3,
- 2, 3, 7, 8, 10, 19, 27, 32, 33, 33, 35, 38, 43, 41, 29, 9,
- -4, -9, 2, 16, 17, 13, 15, 17, 13, 10, 5, -1, -8, -18, -29, -32,
- -27, -21, -22, -30, -31, -31, -33, -31, -27, -18, -7, -6, -15, -16, -8, -1,
- 4, 12, 18, 22, 20, 16, 11, 10, 14, 18, 16, 15, 14, 9, 6, 4,
- 3, 3, 0, -5, -13, -18, -15, -13, -9, -7, -8, -5, -2, -5, -1, 5,
- 8, 10, 11, 12, 17, 19, 16, 10, 4, 4, 8, 8, 8, 13, 14, 9,
- 3, 0, -1, 0, 0, -7, -19, -24, -20, -15, -12, -15, -21, -23, -24, -26,
- -28, -29, -28, -21, -10, -1, 5, 6, -3, -12, -14, -11, -1, 12, 16, 17,
- 28, 36, 28, 20, 25, 27, 24, 25, 28, 21, 15, 11, 3, 4, 12, 11,
- 0, -7, -5, -1, -1, -5, -8, -11, -17, -23, -22, -19, -21, -20, -20, -22,
- -24, -22, -17, -20, -24, -20, -10, 2, 10, 13, 14, 14, 11, 8, 8, 12,
- 17, 18, 20, 20, 14, 4, -1, -2, -1, 3, 11, 12, 6, 0, -9, -20,
- -25, -18, -9, -8, -13, -18, -19, -14, -6, 0, 4, 11, 19, 22, 20, 19,
- 15, 13, 14, 18, 17, 12, 7, 9, 14, 9, -1, -4, -1, -5, -10, -12,
- -16, -23, -19, -7, -5, -10, -10, -11, -19, -27, -24, -14, -6, -3, -10, -21,
- -24, -15, -6, 0, 9, 15, 12, 8, 6, 9, 9, 11, 20, 26, 31, 35,
- 30, 21, 16, 16, 13, 6, 2, 4, 5, 3, -2, -10, -13, -11, -8, -9,
- -13, -16, -18, -18, -19, -22, -18, -8, -3, -1, 0, -5, -11, -10, -9, -11,
- -9, -2, 2, 4, 10, 15, 18, 19, 21, 21, 22, 22, 15, 4, -4, -8,
- -7, -6, -10, -14, -18, -23, -20, -15, -8, -1, 0, -4, -7, -9, -9, -6,
- -2, 2, 6, 7, 4, 1, 0, 7, 13, 11, 14, 22, 22, 15, 8, 2,
- 4, 10, 16, 17, 13, 10, 9, 6, -3, -13, -23, -26, -21, -17, -14, -12,
- -13, -16, -14, -9, -8, -8, -11, -18, -18, -12, -4, 0, 2, 6, 6, -1,
- -6, 0, 8, 11, 13, 11, 6, 6, 9, 13, 16, 16, 15, 10, 7, 10,
- 10, 4, 0, -2, -3, -1, 2, 2, -1, -5, -13, -21, -27, -30, -26, -16,
- -4, 5, 8, 6, 2, -3, -5, -1, 4, 8, 9, 11, 11, 6, 0, 0,
- 7, 12, 13, 11, 7, 1, -4, -3, 0, 5, 6, 5, -2, -10, -13, -13,
- -10, -5, -4, -9, -18, -28, -31, -24, -14, -10, -4, 2, 5, 4, 2, 4,
- 13, 20, 21, 19, 14, 11, 11, 12, 13, 14, 15, 17, 18, 18, 14, 5,
- -3, -5, -8, -11, -11, -12, -15, -15, -13, -13, -15, -13, -12, -15, -16, -11,
- -7, -6, -4, -1, 4, 6, -1, -10, -11, -7, -4, -1, 4, 9, 11, 12,
- 9, 7, 8, 8, 7, 9, 13, 15, 12, 4, 1, 1, -2, -9, -10, -7,
- -1, 3, 3, -1, -9, -12, -9, -5, 1, 3, -2, -10, -10, -7, -4, 2,
- 8, 6, 4, 6, 5, -1, -1, 7, 17, 20, 17, 16, 19, 16, 7, -3,
- -8, -9, -9, -11, -15, -24, -27, -20, -15, -12, -11, -7, -3, -4, -6, -7,
- -6, -8, -14, -18, -18, -15, -10, -5, 3, 12, 18, 20, 17, 11, 10, 16,
- 21, 22, 23, 23, 22, 17, 9, 0, -3, 2, 10, 15, 16, 11, 2, -9,
- -19, -23, -22, -15, -10, -8, -11, -13, -15, -17, -19, -18, -15, -10, -3, 1,
- -2, -6, -3, 0, -3, -3, 0, 6, 10, 9, 7, 4, -1, -4, 0, 10,
- 17, 16, 11, 5, 0, -1, 2, 5, 1, -6, -10, -10, -8, -6, -4, -2,
- -4, -7, -9, -9, -6, 2, 12, 17, 16, 11, 8, 7, 6, 5, 7, 9,
- 12, 14, 14, 9, 3, -1, -3, -5, -4, 0, 4, -1, -10, -18, -24, -29,
- -28, -20, -14, -13, -12, -8, -5, -5, -9, -13, -14, -11, -10, -9, -4, 1,
- 3, 2, 3, 8, 16, 20, 18, 13, 10, 14, 24, 29, 29, 27, 23, 17,
- 14, 16, 17, 15, 9, -1, -7, -10, -14, -18, -16, -11, -8, -7, -8, -12,
- -18, -26, -29, -26, -19, -11, -5, -3, -3, -2, 0, 2, 0, -3, -3, -2,
- -3, -4, -2, -1, 3, 7, 9, 8, 7, 3, 1, 4, 5, 2, 3, 5,
- 5, 0, -7, -9, -6, -1, 5, 9, 8, 3, -2, -6, -5, 3, 9, 12,
- 11, 8, 4, 3, 4, 6, 11, 13, 8, 1, 0, 4, 9, 13, 12, 5,
- 2, 3, 3, 0, -6, -16, -26, -30, -28, -26, -22, -18, -17, -19, -22, -24,
- -19, -12, -7, -2, 1, 0, -2, -4, -5, -2, 4, 10, 14, 15, 15, 16,
- 16, 17, 19, 22, 26, 25, 19, 13, 10, 7, 9, 11, 10, 7, 4, 1,
- -5, -8, -8, -4, 0, 1, -4, -11, -16, -17, -16, -14, -12, -10, -11, -14,
- -15, -16, -13, -9, -3, 1, 2, 1, 0, 0, -3, -9, -13, -10, -8, -7,
- -4, 0, 3, 6, 9, 9, 5, 3, 3, 5, 8, 12, 12, 6, -1, -2,
- 2, 8, 8, 4, -2, -5, -1, 4, 10, 13, 14, 13, 13, 14, 14, 12,
- 10, 8, 8, 8, 6, 6, 9, 6, -1, -9, -15, -19, -22, -24, -23, -25,
- -25, -23, -20, -19, -19, -21, -20, -20, -21, -19, -11, -2, 2, 1, 0, 3,
- 9, 13, 15, 16, 14, 10, 5, 3, 8, 14, 16, 18, 20, 22, 24, 21,
- 15, 9, 6, 8, 14, 18, 15, 9, 4, 1, 0, -2, -4, -4, -3, -3,
- -4, -7, -11, -13, -12, -11, -15, -19, -22, -25, -25, -21, -14, -11, -15, -19,
- -18, -14, -7, -1, 4, 2, -3, -6, -4, 0, 5, 10, 16, 17, 12, 7,
- 2, -1, -3, 0, 3, 6, 10, 14, 12, 6, 2, 5, 10, 15, 18, 18,
- 16, 14, 11, 6, 4, 3, 1, 1, 2, 6, 9, 9, 3, -2, -3, -4,
- -6, -8, -10, -15, -19, -20, -19, -18, -17, -15, -16, -17, -18, -20, -22, -21,
- -16, -11, -4, 1, 0, -4, -4, -1, 1, 2, 4, 4, 3, 3, 4, 7,
- 11, 16, 21, 20, 15, 11, 9, 12, 16, 21, 24, 23, 21, 17, 13, 11,
- 9, 4, 0, 0, 1, 3, 4, 0, -4, -7, -7, -9, -13, -17, -20, -22,
- -23, -21, -16, -12, -12, -15, -17, -17, -15, -12, -10, -10, -11, -12, -15, -15,
- -10, -4, 0, -1, -1, 1, 4, 7, 13, 19, 22, 23, 21, 19, 18, 17,
- 11, 5, 2, 5, 10, 13, 15, 15, 14, 13, 10, 5, 1, 0, 2, 5,
- 8, 10, 9, 6, 4, 2, -1, -5, -7, -8, -7, -8, -11, -13, -14, -16,
- -19, -21, -22, -22, -24, -23, -20, -17, -16, -16, -15, -16, -16, -15, -13, -11,
- -9, -5, 0, 6, 12, 15, 18, 18, 17, 17, 19, 20, 19, 19, 20, 23,
- 25, 25, 23, 20, 17, 13, 11, 9, 9, 8, 6, 3, 1, -2, -5, -5,
- -2, -1, -3, -7, -6, -3, 0, -2, -9, -21, -29, -32, -32, -30, -27, -27,
- -29, -30, -28, -24, -23, -21, -16, -7, 0, 1, 2, 2, 4, 7, 10, 14,
- 16, 14, 12, 13, 15, 18, 20, 22, 23, 20, 15, 8, 3, 2, 7, 13,
- 15, 13, 7, 2, 0, 0, -1, -2, -1, 1, 2, 1, 0, 2, 3, 4,
- 4, 6, 7, 5, 0, -10, -21, -30, -36, -36, -33, -28, -23, -18, -15, -14,
- -17, -19, -19, -17, -12, -5, -2, -2, -3, -1, 2, 6, 10, 12, 14, 13,
- 12, 13, 18, 25, 29, 28, 24, 19, 14, 10, 6, 6, 9, 12, 13, 15,
- 17, 18, 18, 14, 7, 0, -1, 1, 1, -2, -6, -8, -10, -11, -13, -17,
- -19, -18, -17, -16, -14, -14, -15, -17, -19, -22, -26, -26, -24, -20, -17, -14,
- -13, -12, -10, -7, -4, 1, 5, 7, 9, 10, 13, 15, 17, 18, 21, 24,
- 22, 21, 19, 17, 15, 13, 14, 14, 16, 17, 18, 16, 12, 10, 8, 6,
- 5, 3, 0, -3, -6, -7, -5, -4, -4, -5, -5, -4, -4, -4, -8, -13,
- -19, -24, -27, -28, -27, -25, -25, -27, -27, -25, -19, -14, -8, -3, 1, 6,
- 9, 8, 3, -3, -6, -4, -1, 4, 9, 14, 18, 20, 22, 22, 23, 23,
- 22, 21, 20, 20, 21, 21, 19, 15, 9, 3, -2, -4, -3, 0, 2, 2,
- 2, 3, 3, 1, -4, -10, -15, -19, -19, -16, -11, -7, -7, -9, -13, -17,
- -23, -28, -30, -29, -24, -20, -18, -19, -20, -19, -18, -19, -18, -13, -5, 1,
- 6, 9, 11, 13, 16, 21, 26, 29, 30, 29, 29, 28, 26, 23, 20, 20,
- 21, 21, 20, 18, 15, 9, 2, -4, -6, -5, -3, -3, -4, -6, -7, -9,
- -10, -10, -10, -10, -11, -13, -12, -11, -8, -6, -6, -10, -17, -26, -32, -35,
- -35, -34, -32, -27, -19, -9, -3, -1, -2, -5, -7, -6, -1, 7, 14, 18,
- 21, 23, 25, 26, 26, 23, 20, 20, 23, 24, 24, 21, 19, 14, 8, 2,
- -1, 0, 1, 2, 3, 6, 8, 8, 5, 2, -2, -5, -5, -4, -1, 1,
- 1, -1, -6, -9, -11, -13, -17, -20, -24, -26, -27, -26, -23, -21, -20, -23,
- -26, -27, -26, -24, -20, -15, -9, -2, 4, 8, 10, 13, 16, 19, 21, 23,
- 25, 28, 33, 36, 38, 38, 35, 32, 29, 24, 16, 11, 6, 2, -2, -6,
- -6, -5, -4, -4, -7, -11, -14, -13, -10, -8, -8, -8, -9, -11, -12, -12,
- -11, -11, -12, -14, -17, -19, -19, -18, -18, -20, -22, -23, -21, -18, -14, -11,
- -8, -4, -1, 5, 11, 13, 11, 8, 6, 7, 9, 11, 13, 15, 19, 22,
- 23, 25, 27, 27, 22, 17, 11, 6, 4, 5, 9, 13, 15, 15, 11, 6,
- 0, -4, -7, -8, -6, -3, -2, -3, -6, -9, -13, -18, -22, -23, -20, -15,
- -11, -10, -11, -14, -19, -24, -27, -28, -28, -27, -26, -23, -19, -15, -10, -6,
- -1, 4, 8, 10, 11, 11, 13, 15, 17, 20, 23, 24, 24, 26, 28, 28,
- 28, 27, 26, 24, 22, 20, 16, 13, 10, 8, 6, 3, -3, -9, -15, -17,
- -16, -15, -13, -13, -14, -17, -19, -20, -20, -17, -14, -12, -13, -14, -13, -13,
- -14, -15, -14, -13, -12, -12, -12, -10, -8, -7, -8, -9, -9, -7, -4, 0,
- 3, 6, 8, 10, 12, 14, 18, 22, 25, 26, 27, 28, 28, 27, 24, 20,
- 16, 13, 11, 9, 6, 3, 0, -3, -3, -2, 1, 3, 5, 3, 0, -4,
- -8, -12, -17, -21, -22, -20, -17, -15, -14, -14, -13, -15, -19, -22, -21, -18,
- -14, -13, -15, -16, -17, -17, -19, -19, -16, -11, -4, 1, 6, 10, 13, 17,
- 20, 23, 24, 24, 24, 25, 28, 33, 37, 38, 35, 30, 24, 20, 16, 13,
- 9, 2, -4, -8, -8, -8, -7, -7, -9, -12, -16, -18, -18, -16, -15, -16,
- -16, -16, -13, -10, -10, -11, -13, -15, -15, -15, -15, -16, -17, -16, -14, -13,
- -13, -13, -13, -12, -9, -5, -2, 1, 3, 6, 12, 18, 22, 22, 21, 18,
- 16, 16, 19, 23, 29, 32, 30, 24, 18, 13, 9, 6, 3, 0, -2, -4,
- -6, -8, -10, -11, -10, -6, -3, -2, -3, -5, -5, -6, -6, -7, -6, -5,
- -4, -5, -8, -10, -11, -12, -14, -16, -18, -20, -21, -21, -22, -23, -24, -24,
- -22, -18, -11, -4, 1, 4, 5, 6, 8, 11, 15, 20, 24, 26, 27, 28,
- 31, 32, 31, 30, 28, 27, 24, 20, 17, 14, 12, 9, 3, -3, -9, -12,
- -15, -16, -17, -15, -13, -10, -10, -11, -13, -14, -15, -17, -19, -21, -23, -24,
- -22, -18, -13, -9, -8, -8, -8, -9, -9, -9, -7, -4, 0, 2, 3, 5,
- 5, 3, 3, 4, 5, 6, 7, 10, 14, 17, 20, 20, 20, 21, 22, 20,
- 18, 16, 15, 14, 12, 9, 7, 6, 4, 2, -2, -5, -7, -9, -9, -8,
- -5, -2, 0, 0, -1, -3, -7, -12, -16, -16, -15, -13, -12, -13, -13, -12,
- -11, -11, -12, -15, -19, -23, -24, -22, -19, -16, -13, -10, -5, -1, 3, 6,
- 7, 8, 8, 10, 13, 17, 21, 25, 27, 28, 28, 26, 24, 24, 25, 27,
- 28, 29, 28, 25, 19, 12, 4, -3, -10, -15, -19, -22, -24, -25, -26, -25,
- -23, -21, -20, -18, -17, -16, -14, -12, -11, -12, -14, -14, -13, -13, -15, -16,
- -16, -16, -15, -11, -4, 0, -2, 0, 0, 3, 14, 34, 24, -3, -14, -12,
- 6, 6, -11, -23, -5, 15, 20, 15, -19, -12, 3, 19, 11, -5, 1, 4,
- 7, -13, -3, 5, -13, 0, -2, 8, 0, -6, 16, 23, 13, 6, 2, 14,
- 25, 2, 11, 3, -7, -8, -24, -6, -4, -18, 6, 30, 14, 9, 0, 0,
- 13, -7, 0, -3, 9, 8, -6, -14, -15, -23, -19, -7, 0, -3, 1, -8,
- -10, -10, -17, -12, -7, -10, 1, -12, -13, 0, -15, -20, -25, -16, -6, -7,
- -6, -6, -2, -4, -13, -12, -6, -6, -5, 2, 8, -5, -13, -3, -4, -11,
- -16, -3, 12, -2, -8, -4, -4, 4, -15, -17, -6, -2, 5, -4, 3, -2,
- -10, -4, -5, -7, -8, 4, 17, 1, -3, -14, -4, -2, -7, -4, -6, 10,
- 5, -6, -7, -8, 10, -5, -3, 3, -8, 11, 7, -5, -3, -13, -7, 0,
- -6, 4, 0, -7, 12, -9, -17, -7, 5, 2, -3, -4, -7, 7, -2, -13,
- -5, -2, 5, 4, 0, 7, -3, 4, 1, -2, -4, 6, 8, 8, 0, -2,
- 2, 3, 2, 1, -2, 5, 12, 6, 3, 2, -3, 2, 3, 1, 8, 6,
- 7, 2, -5, -3, 1, 5, 2, 0, -3, 2, 7, 2, 0, -9, 0, 5,
- 1, 3, 1, 4, 6, -5, -3, -2, 2, 6, 4, 6, 1, 2, 4, 4,
- -2, 2, 5, 5, 7, 7, 2, 6, 0, 3, 0, -3, 8, 4, 4, 9,
- -3, 2, 1, 1, 2, 1, 5, 5, 4, 6, 1, -6, -2, 3, 5, 6,
- 4, 3, 4, 1, 2, -4, 0, 6, 2, 2, 4, 3, 5, -3, -2, -5,
- -3, 5, 2, 1, 3, 1, -2, -3, -4, -6, 3, 5, 1, -2, 1, 2,
- -2, -2, -2, -3, 3, 5, 3, 4, 2, 2, 1, 0, 1, 4, 9, 9,
- 5, 2, 1, 6, 4, 4, 5, 5, 7, 8, 4, 5, 1, 2, 3, 1,
- 1, 4, 2, 3, 0, -4, -7, -5, 0, -3, -3, -3, -5, 0, -8, -7,
- -8, -5, -3, -6, -3, -4, -5, 0, -7, -4, -5, -3, 1, 1, -2, 1,
- -2, 2, 0, 0, -2, 3, 5, 4, 5, 4, 2, 4, 2, 4, 5, 6,
- 5, 6, 4, 4, 4, 4, 3, 4, 2, 4, 4, 2, -2, -2, 0, -3,
- -3, -3, -4, -2, -7, -6, -7, -9, -7, -10, -9, -10, -10, -8, -11, -9,
- -9, -12, -10, -13, -12, -7, -8, -6, -6, -9, -6, -5, -3, 0, 0, 1,
- 1, 4, 3, 4, 8, 6, 8, 7, 6, 10, 9, 12, 12, 11, 12, 8,
- 13, 10, 11, 10, 8, 9, 8, 6, 9, 4, 5, 0, -3, -5, -5, -6,
- -7, -9, -12, -15, -17, -21, -18, -22, -21, -23, -25, -24, -27, -27, -26, -30,
- -27, -27, -28, -20, -22, -19, -14, -15, -12, -10, -10, -2, 3, 4, 12, 12,
- 14, 20, 17, 25, 27, 29, 33, 35, 35, 40, 38, 41, 39, 36, 38, 36,
- 36, 38, 31, 33, 25, 21, 14, 8, 1, 2, 0, -3, -5, -15, -23, -28,
- -40, -39, -43, -46, -43, -52, -53, -59, -66, -62, -69, -63, -64, -64, -50, -56,
- -44, -45, -43, -38, -36, -31, -20, -8, 4, 12, 19, 18, 28, 31, 40, 52,
- 57, 68, 73, 73, 77, 73, 81, 79, 82, 82, 77, 82, 77, 75, 69, 59,
- 53, 42, 33, 24, 22, 17, 11, 1, -17, -25, -36, -42, -46, -55, -60, -64,
- -73, -77, -88, -90, -92, -97, -98, -100, -100, -92, -85, -79, -80, -76, -79, -69,
- -56, -50, -32, -24, -15, 0, -2, 11, 15, 29, 45, 55, 67, 72, 82, 88,
- 95, 101, 102, 109, 109, 112, 109, 110, 110, 106, 104, 91, 81, 77, 68, 66,
- 54, 42, 32, 14, 6, -6, -12, -20, -29, -43, -55, -65, -76, -76, -85, -89,
- -97, -105, -107, -114, -115, -117, -117, -113, -112, -104, -101, -91, -85, -84, -70, -72,
- -55, -42, -34, -14, -8, 5, 16, 22, 35, 44, 57, 69, 78, 89, 94, 101,
- 104, 109, 109, 119, 118, 117, 120, 110, 114, 114, 99, 102, 84, 74, 72, 57,
- 52, 43, 32, 22, 10, -7, -20, -28, -34, -47, -54, -60, -67, -71, -80, -87,
- -90, -105, -105, -110, -120, -115, -120, -123, -113, -111, -109, -97, -98, -92, -83, -82,
- -76, -63, -61, -48, -39, -30, -16, -3, 10, 22, 32, 42, 49, 61, 67, 76,
- 84, 91, 101, 105, 115, 116, 117, 125, 115, 119, 116, 106, 111, 102, 97, 92,
- 84, 79, 70, 64, 50, 45, 31, 19, 14, -2, -9, -19, -30, -35, -47, -54,
- -62, -67, -73, -82, -86, -96, -100, -105, -109, -116, -118, -120, -120, -117, -111, -110,
- -97, -96, -90, -84, -78, -73, -64, -55, -50, -39, -25, -20, 1, 11, 19, 37,
- 40, 51, 61, 68, 76, 85, 94, 97, 105, 114, 112, 120, 122, 119, 121, 117,
- 110, 106, 105, 92, 90, 84, 69, 71, 57, 48, 45, 29, 22, 14, -2, -9,
- -22, -31, -40, -47, -59, -62, -68, -76, -80, -87, -97, -96, -111, -111, -116, -124,
- -119, -123, -120, -109, -109, -98, -95, -93, -84, -81, -75, -66, -55, -51, -37, -28,
- -16, 1, 12, 23, 39, 40, 55, 59, 68, 77, 86, 94, 103, 104, 116, 117,
- 118, 125, 122, 117, 120, 107, 108, 104, 95, 92, 85, 72, 70, 60, 48, 43,
- 29, 18, 10, -7, -12, -22, -30, -38, -49, -58, -63, -72, -75, -84, -90, -93,
- -100, -110, -103, -121, -115, -115, -124, -110, -112, -111, -92, -98, -86, -81, -77, -69,
- -61, -53, -48, -34, -27, -13, 1, 9, 28, 37, 45, 58, 59, 76, 78, 85,
- 97, 98, 109, 114, 111, 123, 120, 119, 121, 116, 111, 110, 101, 93, 92, 79,
- 73, 68, 55, 52, 40, 30, 21, 10, 0, -13, -23, -29, -41, -47, -58, -64,
- -69, -75, -84, -89, -93, -103, -105, -110, -120, -115, -117, -128, -105, -114, -109, -88,
- -102, -86, -76, -84, -64, -63, -56, -43, -37, -25, -10, 4, 11, 31, 36, 46,
- 56, 58, 74, 78, 84, 100, 95, 110, 114, 110, 124, 120, 116, 121, 110, 105,
- 108, 97, 96, 91, 79, 75, 66, 57, 51, 38, 29, 17, 5, -3, -13, -20,
- -28, -40, -46, -55, -66, -68, -76, -85, -88, -97, -102, -106, -110, -117, -115, -120,
- -122, -108, -117, -103, -98, -96, -86, -79, -77, -66, -59, -54, -46, -33, -31, -10,
- -2, 11, 27, 36, 47, 58, 62, 74, 78, 86, 94, 96, 106, 109, 115, 120,
- 118, 121, 119, 112, 114, 104, 98, 94, 85, 77, 72, 63, 56, 49, 37, 31,
- 20, 6, -2, -15, -24, -33, -44, -50, -58, -63, -68, -76, -82, -89, -95, -105,
- -105, -116, -118, -117, -126, -114, -111, -118, -92, -105, -92, -83, -88, -72, -71, -65,
- -51, -50, -31, -25, -9, 2, 16, 29, 35, 50, 53, 67, 73, 75, 92, 88,
- 104, 112, 108, 122, 117, 119, 123, 114, 116, 110, 104, 98, 94, 86, 80, 75,
- 63, 59, 47, 36, 29, 13, 9, -5, -16, -21, -36, -40, -50, -61, -61, -73,
- -77, -85, -93, -95, -103, -108, -117, -120, -118, -125, -117, -108, -116, -96, -98, -97,
- -83, -82, -78, -66, -61, -54, -43, -32, -25, -2, 3, 16, 33, 36, 52, 56,
- 66, 75, 78, 94, 91, 103, 113, 108, 122, 119, 119, 121, 116, 112, 110, 106,
- 93, 96, 83, 76, 74, 59, 58, 47, 34, 28, 14, 6, -6, -17, -27, -36,
- -44, -54, -61, -63, -70, -76, -86, -90, -99, -102, -108, -117, -115, -121, -123, -111,
- -120, -102, -100, -101, -84, -91, -76, -74, -70, -54, -56, -41, -30, -20, -3, 8,
- 23, 31, 46, 47, 59, 70, 71, 83, 89, 90, 108, 108, 115, 120, 121, 122,
- 118, 118, 109, 110, 102, 93, 93, 82, 78, 72, 62, 57, 45, 37, 22, 15,
- 4, -10, -18, -30, -36, -42, -54, -57, -63, -68, -77, -86, -91, -102, -103, -108,
- -117, -114, -119, -117, -115, -110, -106, -100, -91, -99, -79, -81, -77, -59, -61, -50,
- -36, -33, -16, -4, 10, 16, 35, 39, 48, 62, 64, 76, 85, 89, 98, 105,
- 110, 113, 120, 119, 118, 123, 112, 111, 110, 100, 98, 93, 82, 78, 70, 58,
- 54, 45, 30, 24, 12, 0, -7, -20, -28, -36, -45, -55, -61, -66, -73, -79,
- -88, -93, -103, -105, -112, -119, -115, -124, -123, -109, -119, -103, -98, -102, -92, -84,
- -83, -75, -62, -59, -50, -34, -34, -12, 1, 7, 26, 33, 42, 50, 62, 67,
- 76, 88, 90, 101, 110, 108, 118, 121, 119, 122, 121, 111, 113, 110, 98, 98,
- 91, 80, 78, 66, 58, 53, 40, 29, 20, 8, -4, -11, -22, -33, -37, -49,
- -57, -61, -68, -77, -81, -90, -96, -101, -110, -112, -116, -120, -116, -121, -119, -104,
- -111, -96, -91, -96, -79, -79, -76, -59, -57, -46, -33, -25, -14, 5, 11, 26,
- 39, 42, 55, 61, 70, 81, 86, 94, 101, 105, 114, 116, 120, 121, 119, 119,
- 115, 111, 107, 102, 94, 90, 82, 73, 68, 59, 50, 41, 28, 20, 7, -4,
- -12, -22, -30, -41, -48, -56, -62, -69, -75, -83, -90, -98, -100, -107, -111, -119,
- -112, -124, -120, -107, -119, -101, -93, -104, -80, -85, -83, -61, -65, -55, -40, -38,
- -25, -7, -3, 13, 29, 34, 45, 57, 59, 74, 79, 87, 98, 98, 108, 111,
- 112, 122, 117, 119, 119, 111, 110, 107, 96, 96, 89, 76, 74, 63, 54, 51,
- 35, 27, 19, 5, -3, -12, -25, -29, -43, -52, -58, -64, -71, -78, -82, -92,
- -98, -101, -108, -110, -114, -120, -119, -118, -115, -110, -106, -95, -97, -82, -84, -76,
- -62, -63, -51, -42, -39, -20, -12, 2, 15, 29, 36, 47, 58, 62, 74, 80,
- 85, 95, 101, 106, 111, 116, 118, 117, 122, 113, 115, 111, 99, 103, 90, 85,
- 80, 68, 63, 56, 46, 36, 28, 17, 5, -5, -19, -25, -35, -43, -52, -58,
- -62, -72, -75, -83, -94, -94, -105, -105, -115, -115, -116, -122, -114, -112, -108, -98,
- -99, -89, -86, -82, -72, -69, -58, -52, -44, -31, -21, -6, 4, 17, 28, 39,
- 48, 53, 66, 72, 80, 88, 92, 104, 108, 113, 116, 119, 121, 116, 119, 112,
- 108, 107, 94, 94, 85, 79, 72, 62, 57, 48, 37, 25, 17, 8, -8, -15,
- -26, -35, -42, -55, -59, -65, -73, -75, -87, -89, -97, -104, -109, -116, -116, -121,
- -120, -120, -109, -108, -103, -90, -97, -78, -78, -77, -60, -64, -50, -41, -34, -16,
- -7, 9, 19, 33, 42, 52, 60, 65, 77, 79, 87, 96, 99, 109, 113, 118,
- 124, 117, 121, 117, 109, 110, 99, 94, 93, 83, 77, 73, 63, 55, 50, 32,
- 26, 18, 0, -6, -20, -29, -34, -49, -53, -57, -63, -71, -76, -83, -91, -97,
- -108, -112, -114, -122, -115, -124, -112, -105, -112, -89, -99, -90, -78, -89, -72, -66,
- -61, -49, -41, -28, -16, 2, 6, 25, 35, 36, 53, 54, 67, 77, 79, 93,
- 97, 105, 112, 111, 122, 118, 119, 117, 112, 109, 108, 99, 95, 92, 82, 76,
- 71, 59, 56, 43, 30, 24, 10, 0, -9, -18, -26, -36, -45, -55, -59, -68,
- -75, -81, -88, -94, -99, -106, -109, -110, -119, -117, -119, -116, -111, -105, -101, -91,
- -92, -83, -75, -75, -61, -52, -52, -35, -29, -18, 0, 9, 22, 36, 41, 51,
- 64, 68, 78, 88, 90, 101, 103, 109, 113, 115, 121, 117, 118, 116, 109, 109,
- 102, 94, 90, 80, 71, 67, 57, 47, 42, 30, 19, 14, -4, -9, -19, -31,
- -36, -50, -55, -61, -68, -74, -79, -87, -93, -101, -107, -107, -115, -118, -118, -123,
- -112, -110, -109, -92, -93, -94, -74, -83, -71, -57, -61, -45, -34, -31, -10, 0,
- 12, 27, 37, 42, 55, 61, 70, 77, 87, 95, 96, 106, 112, 113, 123, 122,
- 117, 122, 112, 109, 110, 96, 96, 92, 76, 74, 68, 55, 50, 40, 28, 20,
- 7, -6, -10, -23, -31, -42, -51, -59, -65, -70, -76, -82, -88, -92, -104, -104,
- -105, -122, -113, -122, -126, -106, -119, -103, -91, -99, -82, -80, -76, -66, -59, -54,
- -46, -34, -30, -9, 1, 13, 33, 34, 51, 57, 63, 76, 77, 91, 95, 95,
- 110, 108, 115, 122, 120, 120, 123, 112, 110, 110, 94, 95, 87, 70, 74, 62,
- 55, 50, 39, 29, 20, 7, -5, -13, -26, -35, -44, -56, -61, -65, -69, -75,
- -83, -86, -98, -104, -104, -121, -115, -119, -128, -110, -117, -116, -92, -100, -90, -78,
- -83, -75, -63, -64, -55, -41, -39, -20, -7, 1, 21, 31, 40, 51, 55, 67,
- 72, 77, 91, 93, 99, 110, 109, 118, 125, 118, 124, 119, 108, 114, 101, 93,
- 96, 81, 75, 73, 59, 57, 48, 35, 27, 15, 1, -7, -20, -29, -37, -49,
- -56, -61, -65, -69, -74, -83, -91, -98, -107, -113, -117, -120, -122, -118, -115, -111,
- -103, -101, -92, -89, -85, -80, -77, -65, -61, -51, -41, -33, -16, -4, 8, 21,
- 34, 40, 49, 57, 63, 73, 82, 89, 98, 104, 109, 117, 118, 123, 122, 119,
- 116, 110, 108, 100, 97, 93, 83, 80, 70, 64, 55, 45, 34, 22, 12, -2,
- -10, -20, -30, -35, -48, -55, -62, -67, -71, -78, -86, -91, -101, -104, -110, -117,
- -117, -120, -123, -111, -111, -110, -90, -99, -90, -76, -85, -71, -58, -63, -45, -37,
- -33, -14, 1, 4, 27, 34, 41, 53, 59, 66, 79, 84, 92, 100, 103, 110,
- 115, 116, 123, 118, 118, 117, 107, 110, 101, 95, 93, 79, 76, 68, 57, 52,
- 43, 30, 23, 11, -3, -8, -20, -30, -34, -48, -55, -60, -69, -74, -81, -89,
- -92, -101, -105, -108, -114, -117, -118, -122, -112, -113, -108, -95, -101, -87, -82, -83,
- -68, -60, -56, -45, -38, -28, -17, -2, 6, 23, 33, 40, 54, 60, 68, 80,
- 85, 94, 96, 103, 109, 110, 119, 118, 118, 121, 113, 112, 110, 100, 98, 90,
- 77, 73, 66, 55, 51, 41, 29, 25, 8, 1, -9, -23, -28, -42, -51, -59,
- -64, -67, -75, -79, -86, -94, -98, -105, -111, -115, -117, -121, -123, -111, -120, -102,
- -95, -100, -79, -84, -81, -61, -69, -55, -46, -42, -27, -14, -3, 11, 30, 35,
- 49, 57, 60, 76, 76, 86, 95, 95, 109, 108, 116, 122, 121, 123, 120, 116,
- 114, 106, 100, 94, 88, 78, 73, 65, 59, 52, 38, 33, 20, 10, -2, -15,
- -22, -32, -42, -51, -58, -62, -67, -77, -80, -86, -94, -100, -106, -113, -115, -119,
- -122, -118, -117, -107, -106, -98, -89, -89, -78, -76, -71, -57, -56, -46, -36, -25,
- -12, 0, 16, 26, 39, 49, 54, 67, 72, 80, 88, 94, 101, 104, 115, 113,
- 121, 125, 116, 123, 116, 110, 109, 98, 93, 88, 78, 69, 65, 56, 47, 42,
- 27, 20, 8, -6, -15, -27, -33, -43, -53, -58, -64, -68, -74, -86, -87, -96,
- -106, -103, -117, -116, -117, -123, -117, -106, -114, -97, -96, -96, -81, -81, -80, -62,
- -64, -49, -45, -34, -19, -8, 4, 17, 28, 40, 47, 54, 66, 73, 79, 93,
- 95, 102, 113, 110, 117, 123, 119, 121, 117, 113, 111, 106, 96, 95, 88, 78,
- 72, 63, 55, 47, 35, 26, 14, 4, -9, -19, -24, -35, -43, -51, -61, -65,
- -72, -79, -88, -88, -99, -107, -107, -120, -114, -120, -122, -113, -116, -102, -106, -95,
- -89, -95, -72, -80, -70, -50, -58, -37, -30, -20, -5, 6, 18, 29, 44, 45,
- 57, 72, 68, 89, 89, 97, 109, 104, 120, 113, 118, 124, 112, 120, 112, 107,
- 106, 96, 91, 87, 78, 66, 65, 52, 40, 39, 17, 17, 4, -13, -13, -30,
- -35, -44, -58, -59, -66, -72, -78, -85, -93, -97, -106, -114, -110, -120, -120, -118,
- -120, -109, -110, -98, -100, -89, -81, -87, -68, -68, -59, -44, -46, -29, -18, -5,
- 5, 22, 32, 39, 54, 56, 68, 79, 79, 94, 98, 102, 110, 112, 117, 119,
- 124, 117, 116, 116, 104, 106, 97, 89, 86, 74, 67, 60, 53, 41, 34, 24,
- 12, 4, -9, -19, -28, -38, -47, -58, -60, -68, -73, -77, -88, -93, -96, -111,
- -109, -115, -124, -118, -122, -120, -107, -109, -102, -91, -95, -82, -78, -78, -60, -59,
- -51, -36, -35, -14, -3, 6, 24, 34, 41, 56, 59, 67, 81, 82, 92, 103,
- 102, 112, 119, 114, 123, 123, 116, 121, 112, 106, 107, 93, 91, 84, 74, 69,
- 61, 52, 43, 32, 21, 13, -2, -10, -22, -31, -38, -51, -56, -59, -69, -71,
- -76, -87, -90, -100, -107, -110, -119, -118, -120, -123, -108, -118, -101, -92, -102, -77,
- -85, -83, -63, -71, -58, -45, -44, -27, -15, -2, 10, 30, 32, 46, 57, 56,
- 74, 73, 84, 93, 95, 109, 108, 117, 117, 124, 119, 119, 119, 112, 109, 100,
- 96, 90, 81, 75, 65, 59, 51, 41, 33, 22, 12, 0, -12, -23, -30, -40,
- -51, -57, -64, -71, -73, -83, -84, -95, -102, -102, -116, -117, -118, -128, -116, -114,
- -116, -102, -99, -95, -86, -80, -80, -71, -58, -61, -46, -38, -30, -10, -4, 12,
- 26, 37, 47, 54, 67, 68, 79, 89, 86, 104, 104, 111, 118, 118, 123, 121,
- 119, 116, 112, 109, 99, 96, 88, 80, 75, 66, 58, 49, 41, 29, 19, 10,
- -5, -10, -25, -35, -39, -53, -58, -64, -69, -75, -81, -87, -100, -99, -112, -116,
- -118, -126, -123, -115, -120, -111, -102, -100, -93, -86, -85, -76, -69, -64, -56, -47,
- -38, -25, -10, 4, 16, 31, 40, 46, 61, 65, 70, 83, 86, 93, 103, 105,
- 114, 125, 118, 124, 125, 112, 120, 111, 98, 103, 91, 86, 83, 71, 66, 61,
- 49, 38, 32, 16, 7, -4, -17, -26, -36, -44, -54, -60, -59, -71, -75, -79,
- -94, -95, -103, -117, -112, -120, -127, -120, -118, -117, -104, -102, -99, -88, -84, -86,
- -73, -70, -64, -51, -47, -37, -17, -10, 7, 19, 32, 40, 52, 56, 67, 73,
- 80, 87, 92, 103, 109, 110, 123, 119, 121, 126, 111, 113, 112, 98, 98, 91,
- 80, 80, 71, 60, 61, 47, 36, 30, 13, 5, -5, -19, -27, -35, -43, -52,
- -58, -62, -71, -76, -84, -96, -100, -105, -118, -115, -121, -123, -121, -114, -117, -110,
- -98, -105, -91, -83, -90, -71, -68, -64, -48, -43, -33, -17, -5, 3, 23, 32,
- 38, 54, 59, 66, 79, 82, 92, 100, 105, 108, 116, 119, 117, 126, 116, 115,
- 118, 106, 105, 99, 91, 85, 78, 67, 60, 54, 41, 33, 24, 11, 0, 3,
- 10, 14, -8, 46, 7, -20, -23, -28, 17, 9, 47, -7, -15, -35, -1, -26,
- 44, 34, -31, 31, -47, -32, 30, -2, 32, 15, -15, -17, -39, 16, -2, 26,
- 23, 3, -43, 11, -37, 14, 37, 7, 4, -21, -30, -9, 14, 18, 38, -13,
- -16, -21, -24, 8, 38, 3, 16, -29, -11, -26, 20, 15, 24, -9, 0, -34,
- -21, 32, -16, 41, -1, -20, -7, -7, -7, 27, 0, -2, -2, -11, -11, 19,
- -16, 32, -19, -4, 11, -40, 49, -13, -12, 12, -32, 12, 17, 1, 23, -34,
- -20, 14, -20, 33, 44, -51, 7, -21, -38, 46, 19, 37, -28, -29, -17, -40,
- 63, 36, -33, 42, -45, -57, 16, 37, -3, 54, 0, -64, -25, -7, 15, 37,
- 34, -2, -65, -12, -3, -7, 76, -2, -6, -28, -22, -30, 40, 11, 12, 21,
- -43, -6, -1, -31, 73, -35, 33, -1, -67, 29, -24, 16, 42, 4, -26, 17,
- -71, 32, 0, 0, 72, -56, 4, -2, -75, 76, -25, 39, 24, -42, -6, -20,
- -31, 56, 1, 3, 49, -63, -12, -16, -10, 49, 12, 29, -32, -59, 35, -39,
- 35, 45, -33, -21, 46, -68, 13, 16, 12, 0, 2, 32, -70, 12, 30, -62,
- 64, 5, -31, 22, -30, 11, -30, 43, 2, -8, 16, -3, -60, 39, -11, -13,
- 63, -32, 8, -6, -45, 39, -38, 30, 49, -89, 96, -84, 0, 43, -51, 52,
- -4, -6, 7, -31, -10, 12, -22, 62, 8, -57, 65, -101, 1, 69, -46, 76,
- -18, -34, -24, -33, 50, -6, 55, 16, -70, -19, 2, -33, 59, 61, -40, 7,
- -44, -33, -7, 61, 31, -15, 5, -32, -70, 47, 34, 8, 22, -16, -44, -47,
- 56, -6, 12, 56, -46, -32, -3, 7, -4, 42, 19, -41, -35, 41, -59, 43,
- 45, -44, 9, -9, -7, -19, 36, 2, -50, 49, -6, -34, 33, -1, -38, 17,
- 44, -33, 5, 28, -68, -13, 62, -25, 15, 45, -57, -32, 23, -14, 37, 11,
- 29, -56, -48, 46, -55, 48, 94, -74, 22, -40, -59, 36, 9, 75, -19, -31,
- 6, -104, 39, 80, -23, 59, -12, -104, 10, -12, 24, 59, 5, 9, -78, -12,
- 24, -47, 116, -6, -51, 34, -71, -26, 55, 3, 11, 38, -31, -9, -45, 21,
- -11, 4, 92, -79, 16, -16, -41, 29, 27, 19, -5, -19, -13, -35, 29, 22,
- -7, 20, -35, 6, -21, 30, -2, 6, -8, -20, -12, 30, -13, 8, 23, -52,
- 21, 8, -16, 40, -20, -7, -15, -38, 62, -33, 48, 5, -66, 28, -25, 15,
- 39, 5, -46, 8, -46, 32, 12, 37, -9, -49, 43, -78, 43, 46, -43, 39,
- -41, -36, 13, 19, 48, -21, 9, -37, -54, 45, 32, -14, 41, -32, -66, 42,
- -8, 37, 12, -10, -12, -74, 71, -30, 16, 65, -64, -1, -13, -12, 17, 24,
- 10, -16, -31, -1, -3, 1, 68, -47, -7, -8, -41, 74, -16, 32, -27, -42,
- 22, -49, 80, -11, 0, 23, -84, 34, -24, 31, 48, -37, 23, -55, -25, 22,
- 14, 22, 59, -78, -11, -1, -45, 90, -35, 32, 0, -75, 63, -65, 34, 52,
- -71, 70, -56, -14, 30, -22, 10, 55, -74, 41, -19, -47, 88, -62, 50, -11,
- -57, 44, -54, 59, 17, -23, 12, -40, -41, 60, 3, 15, 28, -71, -1, -17,
- 11, 61, -28, 47, -59, -48, 35, -18, 51, 27, -20, -35, -36, 14, 6, 44,
- 23, -30, -33, -17, -1, 14, 49, -2, -32, -12, -20, 5, 29, 34, -33, 9,
- -34, -26, 36, -2, 40, -28, 5, -26, -39, 65, -27, 19, 31, -54, 0, -8,
- 12, 2, 30, -5, -25, -22, 24, -29, 26, 52, -57, 7, 5, -56, 46, 1,
- 8, 4, -5, 1, -51, 28, 14, -21, 48, -17, -46, 4, 11, -6, 35, 7,
- -16, -31, -10, 25, -49, 95, -28, -29, 19, -46, -5, 32, 21, 8, -1, -24,
- -36, -17, 59, -7, 33, 10, -76, -14, 19, -1, 56, 16, -23, -64, -8, 7,
- 8, 85, 0, -57, -21, -35, -7, 72, 23, 28, -66, -16, -47, 2, 68, 24,
- 5, 0, -69, -26, 22, -7, 72, 0, -12, -20, -51, 15, -11, 44, 44, -46,
- 36, -59, -38, 32, 19, -3, 71, -45, -28, -29, -17, 36, 8, 79, -47, -53,
- 18, -65, 38, 75, -24, 20, -36, -34, -26, 38, 39, -7, -3, 7, -85, 44,
- 26, -17, 42, -20, -29, -26, 26, 18, -8, 36, -17, -73, 40, 4, -1, 52,
- -16, -47, -15, 14, 4, 29, 30, -41, -44, 15, -2, 16, 60, -26, -54, 17,
- -33, 22, 48, -5, -15, -20, -13, -15, 31, 37, -28, 6, -17, -22, -10, 64,
- -43, 16, 22, -71, 41, 3, -1, 6, -12, 12, -38, 11, 38, -49, 37, 24,
- -64, 27, 18, -73, 81, -33, 14, -3, -32, 43, -60, 53, 24, -76, 70, -29,
- -33, 50, -18, -34, 48, -38, 37, -15, -5, 25, -80, 70, -4, -45, 89, -72,
- -3, 13, -23, 28, 21, -9, -9, -25, -11, 24, -26, 62, -14, -49, 67, -97,
- 57, 12, -23, 46, -46, 9, -20, -4, 25, -1, 5, 18, -31, -25, 38, -43,
- 44, 17, -42, 37, -66, 37, -16, 26, 18, -16, -17, -4, -17, 7, 38, -11,
- 4, -3, -51, 32, -17, 38, 18, -34, 23, -58, 4, 25, 0, 26, 3, -35,
- -11, -10, 16, 24, 8, 4, -33, -30, 22, -2, 14, 52, -61, 10, -23, -4,
- 20, 10, 32, -44, -2, 1, -36, 37, 32, -25, 2, 0, -40, 14, 24, -5,
- 13, -28, 20, -51, 41, 15, -23, 25, -12, -41, 30, -2, -11, 40, -34, 14,
- -24, 3, 22, -31, 44, -22, -31, 57, -55, 28, 0, -9, 1, 11, -10, 8,
- -13, 3, -2, -23, 60, -49, 23, 10, -59, 36, -3, -3, 35, -23, 5, -42,
- 15, 7, -2, 35, 0, -45, 8, -4, -27, 63, -4, -14, 9, -39, 1, 1,
- 27, 19, -27, 24, -49, -6, 34, -5, 10, 19, -32, -20, 14, -12, 16, 26,
- -9, -19, -9, -8, 8, 7, 40, -29, -14, -4, -25, 7, 56, -15, 6, -20,
- -36, 3, 10, 33, 20, -23, -5, -42, -18, 54, -17, 63, -5, -59, 2, -44,
- 12, 57, 17, 15, -33, -44, -16, -17, 65, 40, -9, 10, -72, -51, 39, 10,
- 65, 19, -25, -47, -51, 17, 20, 53, 30, -35, -35, -34, -16, 36, 48, 12,
- -3, -35, -42, -9, 28, 34, 12, 15, -42, -39, 7, 8, 24, 28, 1, -31,
- -36, 9, -1, 28, 29, -14, -34, 14, -43, 23, 34, -7, 24, -44, 10, -28,
- -5, 53, -29, 29, -7, -33, 2, -1, 5, 19, 10, -17, 2, -33, 14, 1,
- 8, 32, -36, 17, -28, -18, 36, -22, 29, 2, -25, 5, -17, 13, 1, 16,
- -1, -10, -12, 3, -9, 10, 19, -22, 16, -3, -20, 24, -22, 15, -3, -14,
- 22, -30, 31, -14, -11, 12, -11, 8, 17, -9, -4, -13, -13, 7, 10, 19,
- -6, -7, -2, -32, 24, 8, 0, 17, -20, -10, -15, 13, 10, 11, 4, -1,
- -40, 19, -4, -6, 42, -31, -1, -5, -12, 19, 6, 7, -5, -26, 10, -12,
- 15, 20, -8, -19, 12, -40, 31, 15, -3, 16, -23, -27, 7, -5, 31, 6,
- 3, -6, -41, 14, -2, 7, 38, -10, -29, 11, -44, 17, 29, 6, 20, -26,
- 1, -45, 9, 31, -18, 40, -1, -47, 8, -10, -4, 29, 33, -25, 1, -31,
- -12, -9, 35, 30, -25, 31, -48, -28, 20, 17, 9, 30, -19, -39, -13, 6,
- 8, 38, 15, -10, -42, 0, -24, 15, 49, -9, -12, 5, -44, -5, 42, 4,
- 6, 8, -27, -29, 5, 24, -2, 10, 28, -56, 1, 23, -29, 29, 15, -19,
- -11, 1, -4, -8, 24, 6, -15, 2, 7, -27, 12, 21, -40, 36, -15, -12,
- 22, -16, 17, -17, 15, -6, -18, 23, -3, -26, 39, -27, -5, 26, -20, 8,
- 5, -11, 7, -21, 19, -11, -8, 35, -25, 2, 18, -35, 9, 16, -21, 29,
- -16, 1, -13, -13, 28, -18, 23, 13, -36, 6, -1, -23, 26, 12, -15, 17,
- -20, -2, -7, 3, 22, -22, 27, -11, -34, 36, -30, 11, 17, 2, -12, 13,
- -22, -11, 11, -5, 26, -17, 26, -25, -32, 44, -47, 39, 25, -31, 16, -35,
- -1, -4, 26, 16, 3, -16, -10, -23, -8, 55, -27, 26, 0, -63, 41, -26,
- 28, 22, -23, 14, -42, 5, 20, -13, 28, 3, -42, 20, -6, -17, 52, -32,
- 6, -2, -37, 42, -27, 29, 15, -51, 40, -38, 2, 33, -19, 6, 11, -43,
- 25, 0, -19, 57, -54, 31, -9, -43, 58, -52, 36, 11, -44, 50, -44, 8,
- 23, -24, 12, 6, -34, 25, -9, -15, 50, -55, 35, -7, -25, 49, -48, 32,
- -23, -18, 37, -30, 28, 8, -27, 7, -2, -19, 22, 10, -11, 10, -27, 4,
- -16, 18, 29, -19, 20, -22, -36, 16, -2, 18, 14, 3, -24, -15, -5, 12,
- 13, 20, 4, -40, 2, -23, 8, 29, 7, 9, -23, -10, -13, 5, 19, 9,
- -3, -14, -7, -19, 21, 6, 5, 10, -20, 0, -14, 12, 0, 2, 5, -13,
- 1, -3, 12, -12, 20, -13, -7, 6, -11, 5, 0, 5, -5, -4, 10, -10,
- 2, 6, -5, -12, 18, -13, -9, 19, -17, 11, -1, 8, -5, -22, 26, -26,
- 1, 29, -17, -7, 16, -22, -8, 23, -3, 4, -3, -2, -15, -20, 42, -21,
- 4, 40, -55, 8, 8, -22, 21, 20, -17, 2, -14, -7, -2, 10, 31, -25,
- 10, -3, -54, 40, 5, -12, 42, -17, -37, 13, -12, 7, 24, 10, -6, -36,
- 12, -9, -25, 74, -24, -19, 38, -64, 5, 25, 0, 16, 1, -9, -25, -23,
- 36, -8, 6, 50, -58, -12, 22, -53, 52, 18, -12, 16, -51, 15, -30, 25,
- 46, -37, 31, -26, -49, 30, 9, -1, 42, -19, -28, -13, -5, 16, 4, 42,
- -18, -40, 20, -30, 1, 49, -4, -15, 0, -21, -19, 21, 26, 0, -9, 9,
- -43, -1, 26, -5, 21, -7, -6, -32, 9, 12, -3, 34, -17, -12, -17, -4,
- 9, 7, 28, -19, -3, -13, -11, 7, 15, 15, -19, 15, -38, -5, 17, -1,
- 29, -20, 15, -39, -11, 41, -33, 45, -8, -21, -11, -3, 7, 0, 28, -7,
- -19, -8, 7, -20, 23, 24, -40, 24, -17, -16, 26, -9, 21, -27, 13, -11,
- -22, 29, -7, 0, 22, -22, -16, 14, -12, 12, 11, -5, -6, -17, 14, -15,
- 9, 30, -28, 5, 1, -26, 8, 18, -7, 1, 6, -12, -15, 9, 13, -13,
- 13, 13, -42, 14, 3, -16, 20, 7, -3, -22, 25, -26, 4, 16, -7, 3,
- -8, 17, -33, 14, 9, -21, 25, -3, -11, -1, 1, -13, 1, 23, -20, 26,
- -18, 0, -18, 3, 24, -25, 36, -15, -29, 22, -22, 3, 24, -5, -1, 0,
- -18, 2, -11, 20, 10, -17, 30, -37, -15, 29, -33, 39, 11, -23, 7, -34,
- 8, 0, 11, 36, -27, -12, 9, -47, 29, 31, -29, 40, -37, -14, 3, -17,
- 45, -11, 8, 12, -60, 20, -2, -2, 41, -12, -18, 3, -37, 27, 12, -4,
- 37, -56, 17, -21, -5, 44, -20, 14, -2, -40, 20, 0, 3, 22, -13, -10,
- -6, -16, 29, -12, 14, 15, -49, 24, -11, -7, 39, -18, 3, -20, -12, 19,
- -10, 32, 2, -34, 10, -13, -13, 37, 1, -7, 3, -33, 4, 2, 18, 25,
- -25, 8, -33, -13, 34, -7, 24, 4, -33, -10, -2, 2, 25, 12, -1, -25,
- -12, 3, -18, 34, 12, -15, 4, -9, -25, 10, 17, -3, 9, 2, -13, -23,
- 9, 8, -13, 37, -10, -15, 1, -13, -1, 0, 31, -15, 0, 5, -29, 6,
- 5, 15, -9, 16, -9, -29, 15, -10, 3, 15, 9, -11, -12, 11, -29, 17,
- 14, -7, 6, -6, -7, -24, 30, -11, 9, 18, -20, -8, -6, 6, -10, 22,
- 10, -29, 14, -13, -8, 13, 17, -13, 2, 1, -24, 5, 5, 12, -10, 15,
- -7, -28, 21, -2, -8, 22, -9, -14, -2, 6, -5, 5, 12, -7, -15, 14,
- -4, -16, 27, -10, -14, 13, -5, -9, 10, 5, -8, -5, 16, -20, 2, 13,
- -14, -3, 17, -18, 2, 10, -12, 9, -6, -2, -16, 13, 10, -15, 33, -24,
- -17, 10, -4, 15, 1, 9, -23, -9, 6, -5, 5, 21, -10, -13, 11, -21,
- -2, 19, -10, 23, -20, 10, -16, -21, 33, -17, 17, 18, -30, 1, -14, -1,
- 20, -2, 18, -15, -24, 6, -5, 6, 36, -26, 6, -18, -23, 34, -12, 25,
- 1, -30, -1, -11, 10, 22, -1, 4, -19, -28, 21, -11, 22, 25, -33, 4,
- -21, -7, 22, 7, 19, -23, -13, -3, -13, 21, 17, -11, 7, -19, -12, 12,
- -10, 30, -13, -5, 4, -30, 27, -9, 17, -3, -25, 13, -23, 13, 27, -15,
- -5, 3, -35, 17, 19, -8, 29, -37, 1, -15, -10, 48, -20, 26, -7, -49,
- 22, -23, 21, 33, -10, -8, -17, -34, 11, 19, 12, 40, -39, -14, -13, -36,
- 64, -4, 20, 9, -55, 3, -24, 21, 31, 10, -1, -22, -30, -7, 12, 18,
- 29, -10, -7, -28, -22, 22, 3, 26, 4, -13, -18, -16, 21, -9, 28, -1,
- -21, 0, -12, 5, 6, 5, 10, -20, 1, 3, -20, 21, 7, -23, 24, -25,
- -6, 21, -13, 25, -19, -8, 2, -14, 20, 13, -23, 25, -31, -7, 24, -16,
- 20, 6, -25, 8, -24, 12, 15, -10, 24, -25, -2, 0, -12, 14, 10, -13,
- 4, 1, -17, 9, 6, -9, 9, 0, -3, -8, 11, -10, -2, 7, -1, -6,
- 6, 1, -12, 1, 18, -31, 23, -2, -21, 21, -6, -8, 15, -14, 4, -6,
- -1, 17, -22, 20, -6, -35, 37, -17, -6, 47, -41, 6, -6, -16, 12, 16,
- 6, 1, -36, 18, -26, 4, 59, -36, -1, 16, -64, 30, 14, 1, 16, -13,
- 0, -35, 17, 13, -8, 12, 14, -45, 11, 12, -24, 27, 12, -27, 10, -6,
- -9, 1, 14, -7, -6, 8, -4, -8, 8, 8, -24, 13, 7, -27, 28, -1,
- -28, 27, -19, -2, 17, -5, 6, -10, -5, 4, -25, 32, 2, -22, 32, -28,
- -20, 35, -20, 16, 7, -18, 1, -22, 20, 0, 2, 20, -15, -25, 24, -25,
- 12, 25, -23, 10, -19, -5, 8, 2, 20, -6, -13, 0, -22, 12, 15, -3,
- 13, -13, -25, 12, -6, 18, 13, -3, -14, -22, 3, -2, 14, 25, -10, -16,
- -5, -13, 2, 22, 9, -2, -11, -12, -20, 15, 20, 1, 14, -19, -17, -9,
- 1, 19, 5, 0, 4, -35, 17, -7, 5, 20, -16, 2, -8, -11, 11, -2,
- 2, 7, -19, 15, -10, 2, 12, -14, -3, 2, -9, 17, -3, 2, -7, -16,
- 10, 2, 9, 10, -14, -9, -6, -11, 21, 5, 4, 6, -24, -5, -4, 6,
- 18, 0, 8, -21, -18, 8, -8, 21, 16, -11, -9, -12, -15, 15, 3, 27,
- -9, -16, 5, -30, 13, 23, -11, 21, -19, -15, -3, -9, 30, -9, 14, -6,
- -22, -5, 15, -11, 23, -1, -14, -4, -9, 8, 4, 1, 20, -34, 9, 1,
- -17, 24, -6, 1, -9, 1, -4, 3, 6, 8, -16, 0, 2, -13, 11, 21,
- -31, 24, -21, -4, 13, -2, 7, -9, -3, 0, -18, 29, -4, -9, 16, -19,
- -13, 25, -5, -1, 15, -24, 4, -15, 22, 4, -11, 20, -21, -25, 39, -23,
- 14, 14, -23, 1, -8, 3, 12, -9, 23, -19, -18, 24, -22, 5, 30, -32,
- 11, 2, -21, 18, -6, 5, 1, -9, 13, -22, 4, 19, -28, 26, 3, -28,
- 21, -4, -25, 32, -15, 5, 0, -2, -4, -9, 15, 0, -13, 21, -14, -20,
- 31, -19, 2, 17, -14, -9, 12, -6, 4, -1, 4, -17, -1, 12, -2, 0,
- 20, -31, -8, 12, -8, 17, 14, -13, -16, -9, -7, 20, 11, 18, -13, -28,
- -3, -12, 13, 40, -12, 4, -20, -32, 8, 17, 14, 21, -10, -28, -18, -2,
- 11, 22, 17, 0, -34, -6, -3, -17, 50, 1, -13, 4, -22, -21, 17, 16,
- 4, 7, 0, -27, -11, 4, 10, 2, 24, -6, -28, 7, -12, -2, 33, -3,
- -6, 2, -37, 3, 9, 7, 24, -4, -14, -6, -24, 25, -1, 11, 16, -36,
- -9, 12, -25, 45, 5, -20, 11, -36, 11, 7, 0, 30, -32, -1, 7, -33,
- 37, 0, -9, 15, -21, -10, 12, -15, 24, -8, 3, 4, -20, 7, 3, -15,
- 28, -14, -7, 13, -23, 2, 11, 0, 4, 7, -9, -16, 1, 7, -7, 19,
- -3, -12, -14, 15, -10, 7, 30, -26, -13, 15, -30, 15, 26, -12, -1, -8,
- -9, -5, 13, 22, -12, -12, 7, -36, 17, 31, -24, 27, -21, -24, 15, -10,
- 26, 4, -12, 4, -36, 13, 14, -5, 27, -14, -22, 7, -12, 6, 23, -13,
- 7, -19, -2, 7, -8, 25, -5, -17, 18, -25, 3, 14, -8, 4, 0, -1,
- -11, 4, 12, -18, 15, 2, -23, 12, -2, -7, 12, 1, -1, -15, 11, -3,
- -17, 41, -24, -7, 13, -25, 3, 22, -9, 15, -12, -9, 0, -17, 32, -5,
- -5, 19, -49, 19, 3, -11, 45, -30, 2, -4, -28, 29, 0, 7, 12, -34,
- 6, -10, 1, 33, -9, -6, 4, -41, 25, 2, 4, 29, -40, 8, -17, -9,
- 42, -16, 16, -10, -33, 11, -7, 22, 12, -6, -6, -25, -4, 18, -3, 25,
- -4, -29, 5, -17, 8, 22, 1, 4, -22, 1, -13, 2, 31, -19, 9, 2,
- -36, 17, 5, -7, 20, -11, -2, -13, 4, 9, -18, 24, -3, -30, 33, -19,
- -11, 31, -21, 6, 0, -5, 3, -10, 17, -7, -19, 30, -24, 0, 26, -23,
- 3, 7, -17, 9, -3, 9, -1, -17, 23, -25, -3, 34, -27, 10, 15, -34,
- 9, 1, 1, 7, -1, 12, -31, 4, 16, -27, 32, 10, -33, 10, -1, -27,
- 29, 9, -9, 0, -1, -16, -6, 24, 2, -17, 23, -20, -24, 33, -11, -2,
- 17, -7, -21, 13, 1, -7, 10, 1, -12, -9, 13, -1, -5, 20, -16, -15,
- 15, -8, 5, 13, -10, -7, -9, 5, 2, 10, 7, -7, -22, 12, -13, 6,
- 26, -14, -6, 0, -17, 3, 16, 6, 0, -11, 3, -26, 13, 15, -6, 7,
- 4, -29, 6, 7, -3, 13, 1, -11, -9, 2, -1, 3, 9, -3, -8, 1,
- -4, 0, 5, 0, 0, -2, 0, -1, 0, 0, -2, 11, 23, 22, 24, 25,
- 20, 21, 15, 40, -1, -24, -42, -5, -19, -11, -8, 4, -46, -31, -14, -33,
- -40, -44, -48, -89, -63, -47, -33, -27, -10, -6, 22, 25, 26, 28, 37, 11,
- 15, 51, 44, 54, 66, 66, 71, 111, 84, 70, 63, 47, 39, 22, 47, -28,
- -79, -111, -90, -91, -112, -81, -87, -49, -46, -5, -24, 26, 24, 47, 29, 23,
- 30, 30, 13, -1, 4, -14, 17, 35, 62, 31, 53, 59, 72, 64, 27, 26,
- 9, 9, -61, -44, -88, -74, -81, -83, -124, -96, -37, -78, -48, -56, -68, -60,
- 7, 44, 39, 54, 77, 102, 110, 108, 89, 101, 100, 105, 64, 22, -1, 44,
- 40, -19, -29, -35, -16, -27, -40, -77, -82, -113, -104, -93, -57, -72, -56, -3,
- 1, 7, -1, 49, 39, 30, 31, 23, 10, 31, 11, 7, -19, -2, -2, 28,
- 62, 92, 75, 33, 34, -20, -47, -61, -85, -105, -93, -119, -112, -54, -70, -67,
- -32, -1, 4, 4, 20, 29, 62, 70, 54, 62, 78, 115, 92, 85, 78, 52,
- 21, 19, 27, 2, -8, 13, 0, 5, 3, 9, 18, 0, -59, -61, -45, -57,
- -65, -76, -89, -102, -48, -24, 17, 6, 26, 33, 35, 26, 41, 63, 20, 12,
- 29, 34, 8, 7, 31, 21, 31, 39, 33, -5, -8, -55, -57, -98, -94, -88,
- -64, -82, -74, -39, -14, 3, 16, 22, 8, 2, 17, 5, 36, 76, 74, 71,
- 57, 73, 62, 47, 30, 32, 19, 4, 7, -14, -18, -2, 17, -5, 13, 22,
- 31, 10, 8, -13, -47, -80, -85, -86, -71, -73, -60, -35, -10, 9, 19, 49,
- 53, 47, 60, 73, 43, 33, 20, 13, -1, -7, -7, 7, 9, -2, 5, -14,
- -40, -69, -61, -66, -67, -84, -58, -58, -33, 2, -7, -5, 12, 32, 18, 25,
- 19, 24, 65, 59, 62, 64, 63, 55, 60, 52, 31, 19, -12, -26, -4, -7,
- -10, -3, 6, -22, -14, 12, 19, 4, -26, -38, -40, -56, -61, -66, -59, -65,
- -51, -20, 29, 40, 51, 52, 62, 61, 53, 26, 20, 6, 8, 6, 9, -14,
- -14, -15, -2, -11, -23, -36, -38, -60, -77, -69, -60, -51, -56, -44, -27, 10,
- -2, 14, 10, 22, 16, 41, 60, 39, 35, 60, 62, 43, 45, 63, 52, 17,
- 12, 15, -1, -2, 0, -38, -48, -32, -22, -7, 3, 13, 10, -2, -1, -8,
- -12, -25, -48, -46, -52, -49, -36, -17, 9, 17, 26, 48, 57, 55, 69, 60,
- 32, 6, 4, -6, -20, -24, -9, -21, -25, -14, -18, -38, -38, -32, -51, -52,
- -60, -34, -6, -6, -16, -11, -2, -1, 17, 19, 3, 11, 25, 31, 41, 39,
- 33, 33, 41, 34, 34, 23, 21, 15, 6, -13, -24, -28, -20, -8, -12, -19,
- -12, -5, 9, 14, 2, -12, -25, -28, -21, -28, -23, -22, -18, -26, -5, 24,
- 45, 46, 47, 39, 33, 36, 42, 29, 7, -5, -10, -21, -29, -39, -39, -31,
- -24, -29, -39, -51, -43, -27, -22, -18, -25, -26, -20, 9, 19, 18, 4, -2,
- 19, 30, 38, 25, 24, 28, 33, 41, 38, 34, 32, 38, 24, 8, 4, -8,
- -11, -15, -25, -31, -25, -20, -22, -15, -11, -9, -12, -17, -20, -20, -15, -6,
- -11, -8, 0, 11, 29, 19, 17, 17, 18, 28, 31, 25, 18, 23, 18, 10,
- 1, -7, -18, -26, -24, -30, -41, -38, -44, -32, -31, -31, -35, -25, -12, -2,
- -8, -11, -13, -13, -2, 8, 15, 19, 29, 35, 37, 39, 43, 42, 40, 35,
- 27, 25, 18, 15, 9, 4, -4, -15, -28, -28, -26, -28, -18, -15, -25, -23,
- -12, -11, -14, -10, -2, -4, -1, 8, 15, 19, 22, 25, 16, 16, 17, 5,
- 7, 13, 18, 13, 9, 6, 6, 4, -4, -21, -31, -28, -37, -39, -34, -38,
- -38, -32, -17, -6, -4, -14, -19, -9, 3, -2, 3, 4, 7, 8, 13, 23,
- 35, 38, 43, 42, 31, 25, 23, 17, 8, 3, 4, -7, -7, -10, -13, -20,
- -19, -28, -33, -30, -23, -18, -13, -17, -12, 3, 14, 23, 31, 27, 23, 21,
- 22, 19, 12, 4, 2, 2, -2, 0, 4, 11, 11, 6, 4, -2, -5, -14,
- -17, -30, -38, -44, -42, -28, -21, -23, -21, -15, -15, -4, 8, 11, 4, -7,
- -15, -7, 5, 10, 21, 26, 28, 27, 34, 37, 36, 28, 19, 10, 11, 8,
- -2, -18, -17, -19, -19, -22, -24, -21, -24, -18, -17, -13, -19, -13, -1, 12,
- 19, 22, 21, 19, 19, 30, 34, 24, 13, 7, 2, 1, 1, 2, -1, -2,
- -6, 0, 0, -2, -15, -21, -17, -21, -28, -32, -31, -31, -32, -27, -24, -17,
- -4, 1, -3, -1, 1, 4, 7, 8, 15, 16, 15, 15, 20, 32, 36, 38,
- 32, 19, 12, 3, 2, -2, -4, -11, -19, -17, -15, -11, -16, -20, -27, -30,
- -28, -22, -13, -6, -2, 2, 12, 23, 29, 45, 44, 36, 32, 21, 16, 14,
- 10, 1, -9, -8, -2, -1, -7, -13, -13, -12, -9, -11, -18, -24, -26, -28,
- -30, -24, -21, -21, -21, -11, -11, -10, 0, -2, 0, 4, 12, 13, 14, 12,
- 17, 22, 28, 30, 28, 20, 16, 13, 8, 2, -2, -6, -15, -14, -18, -15,
- -15, -16, -18, -18, -16, -19, -18, -17, -10, 0, -1, 4, 13, 22, 37, 39,
- 36, 27, 27, 32, 26, 15, 6, -1, -4, -5, -7, -11, -11, -9, -15, -15,
- -14, -18, -21, -19, -17, -21, -19, -15, -15, -10, -15, -14, -12, -11, -6, -2,
- 1, -2, 1, 5, 14, 22, 33, 35, 23, 18, 16, 13, 11, 6, 1, -9,
- -18, -11, -6, -7, -8, -9, -11, -11, -12, -13, -17, -21, -24, -24, -15, -4,
- 7, 12, 17, 25, 30, 28, 31, 32, 31, 27, 22, 15, 12, 3, -2, -8,
- -6, -3, -9, -13, -22, -24, -20, -18, -22, -24, -18, -14, -13, -10, -11, -9,
- -3, -2, -3, -5, -10, -10, -5, -1, 4, 11, 15, 19, 22, 27, 23, 20,
- 16, 14, 5, -3, -11, -15, -16, -12, -12, -11, -5, 1, -3, -10, -13, -15,
- -11, -10, -10, -11, -8, -3, 2, 7, 9, 15, 25, 30, 33, 31, 25, 21,
- 20, 16, 13, 7, -2, -8, -5, -4, -11, -20, -21, -22, -21, -17, -20, -21,
- -22, -19, -19, -11, -4, -2, -2, -2, 2, 5, 2, 0, 0, -3, 1, 8,
- 16, 13, 14, 17, 15, 13, 8, 5, -1, -6, -10, -13, -14, -14, -13, -10,
- -7, -8, -8, -6, -6, -3, -1, -1, -9, -12, -7, 3, 13, 17, 14, 13,
- 17, 22, 23, 24, 18, 15, 18, 18, 18, 15, 8, 0, -5, -8, -11, -15,
- -17, -21, -26, -26, -24, -26, -24, -13, -9, -6, -3, -2, 3, 4, 6, 7,
- 5, 2, 4, 2, -2, -4, -3, 5, 13, 17, 10, 3, -1, -2, -4, -5,
- -11, -14, -13, -11, -8, -8, -8, -6, -3, 0, -1, -5, -5, 0, 4, 3,
- 1, 2, 0, 0, 6, 13, 20, 17, 17, 18, 21, 18, 14, 13, 11, 11,
- 7, 9, 3, -5, -12, -14, -18, -21, -23, -26, -26, -13, -3, -6, -13, -14,
- -5, 5, 8, 3, 0, 1, 3, 6, 4, -1, -1, 1, 3, 7, 5, 3,
- 0, 1, -1, 3, 0, -3, -11, -11, -9, -10, -9, -8, -5, -7, -7, -10,
- -9, -6, -1, 4, 6, 4, 2, 5, 10, 13, 9, 12, 13, 14, 15, 16,
- 13, 12, 10, 13, 14, 13, 8, 2, -1, -4, -6, -9, -15, -20, -21, -19,
- -14, -16, -22, -21, -13, -5, -3, -3, -1, 3, 5, 10, 9, 9, 6, 8,
- 7, 7, 7, 3, -4, -6, -4, -1, -4, -8, -10, -11, -8, -4, -6, -10,
- -7, -8, -11, -11, -8, -5, -4, 0, 3, 3, 8, 10, 10, 12, 12, 11,
- 10, 13, 12, 10, 6, 8, 9, 9, 11, 13, 11, 9, 10, 7, 2, -3,
- -8, -9, -14, -16, -16, -19, -18, -14, -13, -11, -11, -10, -5, -1, 3, 5,
- 2, 2, 9, 14, 11, 9, 10, 7, 2, 0, 2, -2, -9, -13, -15, -18,
- -17, -15, -13, -10, -5, -5, -7, -7, -4, -1, 0, -2, -4, -2, 1, 4,
- 9, 10, 10, 11, 11, 13, 14, 10, 11, 9, 9, 4, 6, 5, 4, 5,
- 7, 8, 10, 9, 4, -4, -8, -9, -10, -11, -12, -14, -15, -17, -15, -9,
- -4, -1, -6, -5, 2, 8, 8, 6, 5, 3, 4, 5, 9, 10, 10, 5,
- -1, -5, -10, -12, -14, -16, -18, -17, -11, -10, -11, -8, -5, -2, -2, 0,
- 3, 4, 5, 3, 2, 3, 5, 9, 12, 12, 11, 10, 12, 14, 12, 8,
- 5, 0, -1, 1, 3, 0, 1, 3, 5, 6, 5, 0, -5, -11, -10, -13,
- -12, -13, -15, -14, -8, -4, -3, -3, -4, 0, 4, 5, 3, 6, 4, 4,
- 7, 10, 9, 9, 8, 5, 5, 2, -4, -10, -15, -17, -20, -22, -22, -19,
- -14, -11, -10, -8, -6, 0, 3, 5, 3, 4, 8, 11, 11, 12, 13, 12,
- 12, 15, 15, 16, 16, 13, 11, 6, 3, -2, -5, -5, -3, -2, -1, 2,
- 0, -3, -4, -5, -7, -10, -12, -11, -12, -11, -8, -4, -2, 0, 1, 2,
- 2, 2, 4, 3, 3, 4, 5, 9, 10, 6, 2, 1, 2, 0, -3, -7,
- -13, -18, -19, -18, -16, -18, -20, -19, -14, -8, -4, -1, 3, 3, 5, 7,
- 9, 9, 10, 12, 13, 13, 13, 13, 16, 15, 13, 9, 6, 3, 2, 1,
- 0, -3, -5, -6, -4, -2, -2, -4, -4, -5, -5, -3, -3, -4, -6, -6,
- -7, -4, 0, 2, 3, 2, 2, 1, 2, 2, 1, 4, 5, 4, 1, 0,
- 2, 2, 0, -2, -6, -8, -6, -7, -9, -11, -15, -18, -19, -18, -18, -17,
- -13, -9, -2, 2, 3, 5, 10, 12, 13, 14, 14, 15, 17, 17, 16, 16,
- 15, 13, 11, 7, 2, -6, -10, -8, -6, -8, -8, -7, -6, -6, -3, -4,
- -6, -5, -3, -2, -2, 0, 1, 0, 2, 2, 3, 2, 3, 2, 3, 3,
- 5, 2, 0, 4, 6, 5, -1, -4, -2, -1, -2, -6, -8, -9, -10, -12,
- -10, -14, -17, -22, -22, -21, -19, -15, -8, -3, 1, 7, 12, 12, 15, 19,
- 22, 21, 18, 16, 16, 16, 13, 12, 6, 3, 3, 2, -3, -6, -7, -12,
- -12, -11, -8, -9, -8, -7, -3, 0, 0, 0, 0, -2, -2, 0, 1, 2,
- 2, 4, 6, 6, 7, 5, 4, 3, 4, 5, 3, 0, -2, -2, -4, -6,
- -10, -8, -8, -10, -11, -12, -12, -12, -13, -16, -16, -16, -14, -11, -8, -4,
- -2, 1, 6, 12, 17, 19, 20, 20, 21, 21, 19, 13, 10, 9, 5, 0,
- -3, -4, -4, -5, -6, -6, -4, -7, -10, -12, -12, -12, -10, -7, -4, -2,
- 4, 6, 8, 7, 7, 7, 7, 8, 8, 7, 5, 6, 6, 4, 1, -1,
- -1, 0, -3, -7, -10, -10, -8, -11, -14, -14, -12, -11, -9, -6, -8, -8,
- -8, -11, -13, -12, -9, -8, -5, 0, 4, 8, 11, 14, 18, 18, 20, 23,
- 23, 20, 14, 9, 4, 0, -3, -6, -8, -8, -8, -8, -9, -10, -11, -10,
- -9, -8, -8, -7, -6, -3, 0, 3, 6, 12, 16, 16, 14, 10, 8, 9,
- 7, 4, 1, 0, 0, -2, -1, 0, 0, -3, -7, -10, -13, -13, -12, -13,
- -15, -14, -13, -9, -6, -5, -5, -7, -8, -9, -7, -6, -5, -7, -5, 1,
- 8, 13, 17, 19, 20, 21, 22, 22, 18, 12, 9, 5, -1, -5, -9, -11,
- -13, -12, -12, -11, -10, -8, -7, -7, -6, -7, -6, -3, 0, 1, 3, 7,
- 10, 11, 12, 15, 15, 14, 9, 6, 3, 1, 0, -2, -2, -2, -3, -6,
- -8, -10, -11, -13, -15, -15, -15, -13, -12, -12, -7, -5, -5, -5, -4, -3,
- -3, -4, -4, -1, -1, 1, 4, 7, 10, 12, 14, 17, 20, 22, 19, 14,
- 8, 5, 2, -2, -5, -10, -14, -13, -11, -10, -10, -10, -10, -8, -6, -3,
- -3, -3, -1, -1, 2, 6, 10, 13, 14, 15, 15, 15, 13, 11, 8, 5,
- 1, -1, -3, -3, -6, -10, -12, -12, -12, -12, -13, -15, -18, -19, -15, -11,
- -6, -4, -3, -4, -4, -2, 1, 4, 2, -1, -2, 1, 4, 6, 8, 7,
- 7, 11, 14, 15, 15, 15, 13, 10, 6, 1, -3, -6, -9, -13, -15, -15,
- -13, -11, -9, -9, -9, -7, -3, 0, 2, 2, 4, 7, 11, 15, 16, 14,
- 11, 12, 13, 15, 13, 9, 4, 1, -1, -4, -6, -8, -11, -15, -17, -17,
- -17, -17, -15, -13, -13, -12, -10, -7, -6, -4, 1, 2, 2, 3, 4, 5,
- 4, 4, 3, 5, 6, 6, 8, 7, 7, 9, 11, 10, 9, 8, 5, 2,
- 0, -2, -6, -10, -13, -13, -14, -14, -13, -11, -9, -4, -1, -1, -1, 2,
- 6, 8, 10, 11, 12, 14, 14, 14, 13, 11, 10, 7, 4, 2, 3, 1,
- -3, -6, -10, -14, -17, -18, -18, -19, -19, -17, -15, -13, -9, -5, -1, 1,
- 0, 1, 3, 5, 6, 6, 6, 7, 8, 9, 8, 4, 1, 0, 2, 4,
- 5, 6, 5, 4, 4, 4, 3, 1, -3, -7, -9, -11, -12, -12, -12, -11,
- -10, -7, -4, -2, 1, 4, 5, 8, 11, 13, 14, 14, 11, 11, 11, 10,
- 10, 9, 6, 5, 3, 1, -2, -5, -10, -14, -16, -17, -18, -19, -20, -19,
- -17, -14, -10, -5, -1, 1, 3, 5, 6, 6, 6, 6, 6, 6, 6, 6,
- 8, 7, 6, 4, 2, 0, -1, 0, 0, 1, 2, 1, 1, 2, 1, -2,
- -5, -8, -9, -10, -11, -12, -12, -10, -7, -4, -1, 2, 8, 11, 13, 15,
- 15, 13, 12, 11, 10, 9, 8, 6, 5, 4, 4, 3, 0, -3, -6, -10,
- -14, -18, -21, -22, -21, -18, -16, -13, -10, -6, -3, 0, 3, 5, 5, 5,
- 6, 7, 8, 8, 8, 7, 8, 7, 6, 5, 4, 1, 0, -2, -4, -4,
- -5, -4, -4, -3, -2, -1, -2, -3, -4, -7, -8, -9, -9, -9, -8, -5,
- -2, 2, 4, 8, 11, 14, 15, 15, 14, 12, 10, 7, 5, 4, 4, 2,
- 1, 1, 2, -1, -3, -7, -10, -15, -18, -18, -18, -18, -17, -15, -11, -7,
- -3, 1, 3, 4, 5, 6, 7, 7, 8, 8, 9, 10, 10, 9, 6, 4,
- 2, 0, -3, -4, -6, -7, -7, -6, -5, -3, -2, -2, -2, -2, -3, -4,
- -5, -6, -6, -6, -6, -5, -4, -1, 4, 7, 9, 11, 12, 12, 11, 10,
- 9, 8, 7, 5, 3, 3, 2, 1, 0, -1, -4, -7, -8, -10, -13, -14,
- -15, -15, -15, -14, -11, -9, -6, -3, 0, 2, 4, 5, 6, 7, 8, 9,
- 10, 10, 9, 8, 6, 5, 3, 1, -3, -6, -8, -8, -7, -7, -7, -6,
- -4, -2, 0, -1, -2, -3, -3, -3, -3, -4, -3, -3, -1, 1, 3, 4,
- 6, 7, 8, 9, 10, 10, 9, 7, 6, 6, 4, 3, 2, 1, -1, -2,
- -4, -6, -9, -11, -12, -12, -12, -11, -11, -10, -9, -8, -7, -5, -4, -1,
- 1, 3, 5, 7, 9, 10, 11, 10, 9, 8, 7, 6, 2, -1, -3, -4,
- -6, -7, -7, -7, -7, -6, -5, -5, -4, -3, -3, -4, -4, -4, -3, -2,
- 0, 0, 1, 1, 2, 4, 6, 6, 7, 7, 8, 7, 7, 7, 7, 7,
- 6, 5, 2, 0, -2, -4, -5, -7, -8, -8, -8, -9, -10, -10, -9, -8,
- -7, -7, -7, -5, -3, -2, 0, 1, 2, 4, 6, 9, 10, 11, 12, 10,
- 8, 6, 3, 1, -2, -4, -6, -7, -7, -7, -7, -8, -7, -7, -6, -6,
- -5, -4, -3, -3, -2, -1, 1, 2, 2, 3, 4, 5, 5, 5, 6, 6,
- 6, 5, 5, 6, 6, 6, 4, 3, 2, 1, -1, -3, -4, -6, -8, -9,
- -9, -8, -8, -6, -5, -5, -5, -6, -6, -6, -5, -4, -2, 0, 2, 4,
- 6, 7, 8, 9, 9, 9, 9, 6, 4, 1, -1, -3, -5, -6, -7, -7,
- -7, -6, -6, -6, -6, -6, -5, -4, -3, -3, -2, -1, 1, 3, 4, 5,
- 5, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 1,
- -1, -3, -4, -5, -6, -7, -7, -7, -7, -7, -6, -5, -4, -4, -3, -3,
- -3, -3, -2, -1, 0, 1, 3, 5, 7, 8, 8, 8, 7, 6, 4, 2,
- 0, -2, -3, -4, -5, -6, -7, -7, -7, -7, -6, -6, -5, -5, -5, -3,
- -2, 0, 1, 2, 3, 4, 5, 6, 6, 6, 5, 5, 4, 3, 3, 3,
- 3, 3, 3, 2, 1, 1, -1, -2, -3, -4, -5, -6, -6, -7, -6, -5,
- -4, -3, -3, -3, -3, -3, -2, -1, -1, 0, 1, 1, 1, 2, 3, 5,
- 6, 6, 6, 5, 4, 2, 1, 0, -2, -4, -5, -5, -6, -6, -6, -7,
- -7, -7, -6, -5, -4, -3, -2, -1, 0, 2, 3, 3, 4, 4, 5, 5,
- 5, 4, 4, 4, 4, 3, 3, 2, 1, 1, 0, 0, -1, -1, -2, -3,
- -4, -5, -5, -5, -5, -5, -4, -4, -3, -3, -2, -1, -1, -1, -1, 0,
- 0, 0, 1, 2, 3, 3, 4, 4, 4, 4, 4, 3, 1, 0, 0, -2,
- -3, -4, -5, -5, -6, -6, -6, -5, -4, -4, -4, -3, -2, -2, -1, 0,
- 2, 3, 3, 4, 4, 4, 4, 3, 3, 3, 3, 2, 2, 1, 1, 1,
- 0, -1, -1, -2, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -2, -2,
- -2, -1, -1, -1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2,
- 2, 1, 1, 0, 0, -1, -1, -2, -3, -3, -3, -4, -4, -4, -4, -3,
- -3, -2, -1, -1, -1, 0, 1, 1, 1, 2, 2, 2, 3, 3, 2, 2,
- 1, 1, 1, 0, 0, 0, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -5, -41, -25, -37, -9, 28, 14, 6, 1,
- 19, 16, -83, -53, -35, -44, -29, 8, -23, -29, -6, -20, -22, -19, -40, -2,
- 14, 34, 78, 59, 73, 93, 73, 83, 124, 94, 87, 61, 98, 80, 29, 27,
- 6, 8, -9, -8, -26, -33, -35, -32, -25, -32, -28, -59, -46, -31, -19, -12,
- -12, 14, 14, -41, -59, -46, -33, -32, -52, -31, -29, -49, -51, -53, -85, -53,
- -60, -100, -85, -84, -66, -37, -26, -11, -8, 22, 41, 33, 39, 27, 29, 75,
- 59, 45, 52, 69, 66, 73, 90, 91, 103, 81, 46, 16, -21, -32, -13, -34,
- -22, -42, -51, -35, -53, -62, -45, -35, -34, -29, 25, 62, 61, 39, -8, -20,
- -5, -7, 2, 28, 1, -24, 8, 29, 11, -9, -54, -34, -35, -57, -41, -63,
- -50, -16, -18, 26, 23, -2, 38, 9, 17, 41, 39, 82, 64, 64, 103, 64,
- 43, 43, 51, 26, -3, 30, 1, 9, 14, -26, 20, -27, -50, -39, -47, -31,
- -23, -33, 25, 56, 51, 20, -19, -60, -41, -27, -10, 3, -36, -30, -22, -46,
- -5, -12, -7, -4, -54, 3, -25, -10, -1, -42, -75, -27, -84, -60, -88, -107,
- -73, -29, -67, -53, 9, -10, 17, -29, -33, 55, 12, 7, 121, 70, 42, 123,
- 96, 127, 74, 28, 51, 21, 60, 23, -10, 25, 103, 113, 65, 45, 15, -1,
- 10, 2, -26, 1, -16, 19, 27, -8, -8, -24, -20, -17, -35, -86, -87, -32,
- -51, -26, -60, -60, -50, -15, -31, -30, -50, -55, -19, 22, 14, 30, 49, 42,
- 15, -11, -57, -15, -29, -65, -37, -56, -29, 15, 70, 69, 36, 24, 19, 21,
- 19, 4, 60, 55, 18, -17, 0, -2, -21, 51, 49, -6, 22, 14, -24, -63,
- -5, 4, -53, -33, -1, -37, -34, 40, 30, 12, -6, -1, 12, 12, 23, 20,
- 43, 34, 11, -26, -40, 25, 56, -1, -41, -50, -37, -10, 20, -58, -65, -43,
- -26, 42, 57, 77, 57, 26, -4, -10, -57, -45, -23, -49, -1, -59, -41, -26,
- -27, 24, 52, -3, -12, 19, -44, -31, 33, 11, -14, 43, 31, 7, 58, 84,
- 45, 35, 18, -5, 6, -21, -6, -20, -7, 41, 53, 29, 25, 55, 68, 37,
- -29, -17, -41, -67, -76, -90, -112, -104, -60, -21, 25, 16, -23, -9, 30, 47,
- 17, 3, 19, 4, -2, 30, 24, 1, 26, 33, 34, 10, 14, 1, -5, 16,
- -2, -60, -32, -51, -48, -38, -34, -42, -20, 16, 17, -16, -32, -6, 4, -39,
- -18, 1, -20, -22, 55, 70, 34, 5, -1, 13, 2, 1, 28, 20, -31, -2,
- 51, 26, 24, 19, 11, -1, 2, 30, 13, 2, 70, 36, 15, 24, 5, 9,
- 14, 48, 43, 8, 2, -10, 18, 33, 22, -27, -19, -17, -22, 11, 19, -5,
- 0, -55, -60, -49, -63, -72, -45, -80, -55, -18, -8, 32, 52, 22, 0, -40,
- -42, -30, -68, -51, -9, -67, -52, -10, 7, 35, 12, 36, 64, 23, 13, 64,
- 39, 32, 73, 3, 6, -10, -6, 16, 18, 53, 51, 21, -20, -15, 13, -3,
- 2, -39, -30, -7, -3, 6, 10, -4, -25, -7, -10, -10, -18, -31, -23, -38,
- -48, -3, -26, -43, -7, 11, 31, 62, 41, -7, -34, -42, -24, 17, 12, 44,
- 25, 24, 18, 11, 32, 51, 46, 46, 51, 33, 24, 32, 30, 40, 8, -30,
- -39, -30, -44, -19, -33, -55, -41, -36, -70, -67, -64, -34, -37, -46, 1, 19,
- 27, 81, 23, 13, 10, -5, -18, -19, -51, -14, -48, -75, 11, 51, 43, 63,
- 37, 20, 19, 4, -23, 27, 47, 71, 29, 16, 15, -17, -11, 32, 40, 22,
- 6, 16, -7, 5, 34, 61, 12, -21, -24, -13, -38, -41, -36, -33, 2, 9,
- -45, -54, -36, 12, -18, -41, -25, -18, 19, 31, -11, -16, -22, -62, -65, -68,
- -42, -4, -48, -49, 4, 38, 65, 47, 12, -20, -20, -8, 3, 32, 69, 84,
- 44, 28, 31, 18, 36, 57, 74, 35, 19, 6, 24, 29, 36, 35, 6, -13,
- -25, -43, -45, -35, -33, -44, -23, -41, -57, -52, -41, -35, -21, -16, -22, -11,
- 33, 42, 14, 19, 16, 0, -6, -34, -17, -37, -25, -7, 6, 48, 47, 3,
- -14, -17, -19, -11, -9, -11, 42, 42, 16, 1, 6, 15, 51, 42, 33, 29,
- 20, -5, -3, 4, 54, 42, 8, -30, -19, -15, -15, -20, -6, -7, -24, -32,
- -24, -17, -1, -16, -18, -36, -55, -38, -2, 8, 16, 7, -21, -35, -56, -67,
- -17, -58, -67, -36, 21, 67, 48, 15, 8, 13, -9, -8, -1, 21, 107, 56,
- 40, 56, 32, 33, 71, 60, 36, 30, 3, 31, 15, 4, 21, 2, -2, -25,
- -30, -26, -13, -9, -26, -20, -34, -34, -51, -28, 6, -9, -24, -49, -67, -54,
- -54, -52, -41, -42, -58, -37, 16, 39, 31, 16, 19, 11, -4, -23, -5, 24,
- 1, 10, 24, 26, 15, 34, 70, 77, 56, 33, 43, 28, 17, 25, 12, 2,
- 0, -12, -15, -2, 10, -19, -28, -45, -41, -28, -17, -3, -2, -9, -3, -25,
- -45, -14, 23, 10, -5, -19, -32, -22, -10, -1, -15, -16, -6, 13, 48, 70,
- 55, 23, 23, 10, -8, -14, 6, 8, -12, -5, 13, 10, -14, 0, 33, 23,
- 18, 43, 21, 26, 33, 13, -14, -7, -3, -31, -29, -5, -5, -25, -27, -35,
- -56, -45, -21, -17, -40, -14, 2, -23, -38, -9, 8, -16, -16, -7, -13, -25,
- -4, -12, -21, -14, 3, 13, 44, 65, 60, 40, 15, 5, -20, -22, -3, 3,
- 20, 39, 39, 9, 6, 21, 48, 24, 25, 25, 11, 0, 4, -5, -31, -34,
- -22, -45, -40, -24, -24, -41, -38, -47, -54, -45, -16, -22, -32, -7, 16, -1,
- -11, 23, 31, -1, -10, -20, -19, -9, 15, -10, -28, -21, 4, 24, 45, 60,
- 56, 46, 30, 26, 23, 36, 48, 33, 46, 40, 34, 19, 12, 23, 43, 37,
- 41, 43, 22, 24, 11, -11, -2, -5, 8, -28, -33, -11, -5, -26, -30, -25,
- -45, -21, -8, -26, -35, -37, -39, -54, -56, -20, -23, -42, -52, -49, -63, -47,
- -31, -29, -16, -21, -7, 14, 26, 48, 32, 12, -10, -22, -24, -6, 0, 33,
- 44, 31, 25, 15, 10, 34, 48, 38, 14, 9, 16, 12, -23, -15, -15, -8,
- -9, -19, -22, -2, -8, -10, -32, -27, 4, 12, -5, 1, -1, 4, -5, -3,
- -5, 10, 37, 18, -8, -19, -3, 0, -10, -5, -31, -32, -29, -2, 18, 32,
- 33, 14, -12, -15, 6, 8, 36, 66, 48, 38, 37, 42, 29, 49, 50, 42,
- 28, 25, 33, 15, 2, 4, 2, 4, 2, -11, -1, 6, 3, 9, -14, -12,
- -5, -12, -33, -36, -29, -26, -38, -44, -42, -38, -38, -52, -67, -70, -50, -32,
- -27, -29, -38, -26, -27, 1, 21, 23, 16, -17, -34, -26, -18, -20, 2, 11,
- 13, 5, 10, 13, 12, 28, 33, 35, 14, 14, 14, -8, -24, -25, -8, -16,
- -23, -14, 12, 8, 21, 25, 13, 25, 29, 25, 6, 3, 36, 26, 34, 11,
- 30, 29, 34, 23, 0, 1, 7, 8, 1, -10, -9, -13, 5, 17, 30, 26,
- 25, 3, -11, -4, -4, 9, 13, 17, 6, 4, 17, -1, -4, 9, 16, 22,
- 3, -2, -4, -16, -28, -22, -13, -34, -37, -31, -9, -7, -12, -16, -26, -12,
- -14, -11, -23, -16, -24, -33, -24, -30, -17, -28, -34, -44, -51, -34, -24, -22,
- -25, -2, 14, 23, 38, 46, 43, 28, 10, -6, -11, 1, 0, 5, 18, 16,
- -3, 12, 27, 23, 32, 48, 42, 34, 21, 21, 10, -3, -10, -10, -20, -38,
- -34, -29, -22, -16, -15, -17, -9, 7, 6, 6, -6, 1, 7, 6, 3, 11,
- 30, 30, 15, 11, 11, 10, 17, 22, 23, 24, 9, 15, 5, -2, 4, 3,
- -17, -21, -4, -21, -6, 8, -9, -1, 0, 8, -7, -18, -16, -3, -14, -13,
- -8, -17, -10, -8, -26, -37, -28, -17, -35, -17, -10, 1, -6, 1, 25, 32,
- 26, 9, -18, -19, 1, -12, -20, 2, 12, 5, -4, 15, 14, 15, 15, 17,
- 14, 2, 6, 3, -18, -21, -9, -1, -15, -11, -15, -22, -1, 3, -7, 0,
- 14, 14, -4, -13, 4, 18, 12, 15, 19, 25, 28, 27, 12, 9, 9, -10,
- -17, -4, -5, -4, -20, -19, 11, 20, 13, 0, -19, -8, 6, -9, 6, 26,
- 18, 14, 17, 22, 24, 18, 21, 37, 20, 7, 11, -8, -11, -4, -3, -8,
- -22, -16, -18, -15, -4, -9, -21, -10, 5, -8, -7, -17, -7, -9, -20, -28,
- -35, -31, -23, -23, -29, -28, -28, -33, -28, -24, -6, 0, -4, 7, 29, 25,
- 15, -6, -19, 1, -2, -22, 4, 10, 1, 9, 10, 13, 4, 6, 21, 15,
- 5, 21, 11, -18, -21, -15, -3, -4, -15, -15, -19, 4, 19, 11, 2, 17,
- 16, 2, 14, 14, 17, 20, 22, 20, 10, 16, 27, 12, 8, 11, 5, -9,
- -10, -6, -1, -7, -12, -3, 3, 8, 9, -5, -3, 6, -5, -6, 23, 14,
- 11, 12, 21, 21, 4, 18, 30, 7, 12, 25, 3, -11, -16, -15, -10, -13,
- -8, -6, -21, 2, -2, -25, -18, -8, -22, -22, -17, -12, -7, -12, -15, -20,
- -41, -28, -24, -23, -12, -12, -15, -10, -7, 2, 1, 6, 18, 29, 23, 21,
- 20, 9, -3, -9, -9, -10, -15, -8, -11, -2, 6, 14, 7, 7, 11, 9,
- 14, 2, 3, 7, 6, 6, -21, -20, -10, -12, -15, -16, -18, -14, -11, -14,
- 0, 0, -5, 3, 14, 12, 9, 0, -11, 5, 5, 12, 11, -1, 5, 3,
- 1, 4, -1, -1, 13, 16, 8, 14, 9, -2, -7, -11, -17, -12, -5, -9,
- -10, -13, -4, 1, 0, 4, 5, 0, 2, 3, 5, 14, 18, 9, -3, 2,
- 15, 14, 6, 2, 1, -1, -5, -6, 0, 0, 0, 7, 20, 22, 23, 13,
- 13, 17, 20, 35, 25, 20, 20, 14, 17, 16, 3, 7, 18, 15, 13, 17,
- 6, -5, -6, -13, -23, -19, -19, -22, -22, -24, -17, -18, -22, -27, -31, -30,
- -29, -30, -33, -36, -34, -37, -47, -38, -24, -28, -27, -31, -30, -28, -26, -20,
- -14, -14, -9, 4, 17, 21, 15, 12, 25, 29, 33, 33, 30, 30, 31, 19,
- 20, 14, 4, 10, 17, 18, 21, 28, 19, 20, 20, 5, -2, -3, -7, -10,
- -2, 1, 4, 6, 4, 5, 3, 2, -1, -4, -7, -10, -3, -6, -16, -5,
- -1, -8, -7, -6, -9, -10, -11, -7, -6, -10, -11, 2, 11, 7, 1, 6,
- 12, 16, 18, 15, 11, 14, 16, 9, 11, 6, 5, 13, 14, 13, 11, 0,
- -11, -4, -4, -8, -7, -5, -6, -3, -1, 2, -1, -6, -7, -9, -9, -9,
- -15, -11, -14, -17, -16, -18, -17, -12, -7, -8, -7, -6, -2, -3, -12, -15,
- -15, -18, -13, -19, -23, -24, -21, -21, -13, -12, -7, -3, -7, -6, -4, 2,
- 1, 1, 3, 9, 23, 28, 23, 17, 24, 27, 22, 19, 16, 19, 10, 9,
- 10, 10, 19, 8, 11, 16, 15, 11, 13, 14, 7, 5, -3, -7, -12, -15,
- -16, -17, -10, -5, 4, -2, -2, -9, -13, -9, -8, -10, -10, -12, -5, 3,
- 7, 3, 9, 3, 4, -1, -2, 2, -4, -9, -4, 0, 4, 4, -6, -3,
- 12, 10, 15, 12, 7, 7, 1, -1, 8, 11, 9, 9, 13, 17, 17, 9,
- 11, 4, 0, -3, -6, -8, -9, -10, -17, -20, -24, -17, -19, -22, -20, -21,
- -15, -16, -19, -23, -21, -28, -26, -15, -14, -4, -1, -6, -3, -1, 4, 9,
- 2, 4, 7, 7, 11, 15, 6, 17, 24, 16, 15, 9, 6, 6, 3, 1,
- 3, 2, -2, 6, 6, 6, 3, -6, -3, -8, -7, -10, -13, -17, -18, -16,
- -19, -13, -9, -3, 4, 10, 7, 7, 12, 11, 13, 10, 6, 1, 2, 4,
- 4, 10, 10, 7, 4, 1, 4, -5, -12, -3, 1, 10, 7, 6, 4, 19,
- 22, 20, 23, 16, 15, 19, 17, 14, 9, 7, 4, 4, 2, 5, 3, 0,
- 0, -7, -7, -8, -7, -14, -15, -18, -25, -21, -21, -16, -13, -14, -17, -18,
- -23, -21, -23, -29, -32, -33, -30, -23, -13, -11, -10, -8, -7, -2, 1, -3,
- -1, 5, 13, 17, 13, 11, 13, 16, 14, 10, 11, 8, 16, 13, 4, 0,
- 7, 13, 14, 15, 15, 17, 17, 9, 8, 9, 9, 2, 5, 11, 14, 7,
- 4, 11, 10, 5, 7, 2, -1, -4, -9, -16, -15, -12, -9, -15, -23, -21,
- -22, -22, -20, -22, -22, -21, -22, -22, -13, -6, 4, 2, -2, 2, 7, 6,
- 10, 8, 9, 12, 21, 16, 11, 7, 11, 13, 11, 10, 11, 13, 9, 6,
- 6, 5, 4, -5, 1, 4, 5, -1, -2, 6, 3, 3, -3, -10, -14, -14,
- -14, -16, -8, -6, -1, -6, -7, -5, -7, -6, -9, -8, -8, -4, -5, -8,
- -6, 3, 12, 4, -2, 3, 1, 1, -1, -4, -4, 5, 6, 1, -4, -3,
- 5, 9, 8, 18, 20, 22, 15, 11, 11, 15, 12, 9, 11, 11, 11, 5,
- 10, 12, 5, 3, -2, -4, -9, -9, -16, -17, -14, -12, -14, -20, -15, -16,
- -17, -17, -19, -20, -19, -15, -17, -15, -13, -2, -3, -13, -8, 0, 4, 7,
- 6, 4, 11, 13, 14, 11, 5, 6, 3, -1, -2, 2, 3, -1, -2, -6,
- -4, -1, -3, 0, 3, 1, -2, -5, -5, -3, -6, -9, -7, -15, -13, -10,
- -8, -4, 1, 9, 7, 2, 8, 8, 9, 12, 14, 7, 12, 12, 12, 8,
- 14, 19, 11, 7, 10, 13, 10, 2, -2, -6, -1, 2, 6, 3, 1, 4,
- 2, 2, 5, 8, 8, 7, 7, 2, 0, -3, -6, -3, -1, -6, -12, -9,
- -6, -7, -9, -10, -14, -16, -12, -12, -11, -13, -16, -16, -20, -18, -14, -10,
- -8, -9, -13, -9, -8, -9, -7, -9, -8, -3, -4, -3, -6, 0, 2, 3,
- -3, 2, 5, 1, 6, 5, 5, 10, 11, 17, 15, 20, 25, 20, 15, 17,
- 13, 12, 11, 7, 4, -1, -2, 6, 7, 7, 9, 10, 7, 9, 7, 5,
- 5, 1, -6, -2, -5, -6, -3, -3, -1, -3, -5, -3, -6, -8, -7, -8,
- -11, -12, -16, -19, -19, -14, -14, -17, -17, -11, -12, -15, -6, -8, -12, -12,
- -9, -7, -6, 2, 9, 6, 8, 11, 13, 15, 14, 11, 7, 3, 3, 4,
- 7, 9, 10, 6, 6, 5, 7, 11, 11, 4, 1, 1, -3, -5, -1, -1,
- -1, -5, -2, -1, -1, 1, 1, -3, -7, -7, -9, -12, -11, -3, -3, -7,
- -6, -6, -5, -5, 0, -3, -4, -2, 2, -1, 0, 6, 7, 7, 4, 3,
- 5, -1, 0, -1, -7, -9, -8, -11, -5, 0, -1, 0, 2, 2, 5, 10,
- 10, 7, 7, 7, 8, 8, 9, 11, 9, 8, 9, 6, 4, 2, 0, -3,
- -5, -8, -8, -12, -8, -1, -4, -4, -5, -7, -9, -6, -5, -6, -8, -6,
- -3, -7, 0, 5, 6, 3, 1, 6, 6, 4, 3, 1, -2, -4, -6, -4,
- 3, 7, 3, 0, -1, -3, -2, -1, -2, -5, -8, -9, -7, -9, -8, -6,
- -9, -7, -9, -7, -6, -7, -6, -7, -7, -7, -7, -8, -2, 1, 2, 4,
- 3, 5, 6, 10, 11, 9, 10, 12, 9, 9, 11, 9, 10, 8, 7, 7,
- 6, 7, 5, 4, 5, 4, -1, -4, -3, -5, -1, -2, -4, -4, -4, -4,
- -2, -2, -3, -4, -2, -1, 0, 1, 8, 8, 4, 4, 4, 2, -2, -3,
- -5, -6, -9, -10, -8, -5, 2, 1, -2, -2, -2, -2, -2, -5, -5, -7,
- -7, -3, -4, -6, -4, -3, -5, -7, -5, -4, -7, -9, -6, -6, -9, -7,
- -6, -2, 3, 3, 4, 5, 3, 4, 5, 2, 0, 2, 3, 2, 5, 7,
- 10, 9, 7, 7, 6, 4, 1, -2, -5, -6, -10, -10, -8, 2, 8, 7,
- 6, 7, 5, 5, 7, 6, 3, 4, 3, 4, 1, 3, 2, 4, 2, 1,
- 1, -1, -3, -3, -4, -6, -9, -9, -9, -7, -6, -5, -5, -4, -5, -2,
- -1, -2, -3, -1, -1, -3, -2, 2, 2, 3, 4, 4, 2, 0, -1, -3,
- -4, -4, -5, -7, -2, 2, 2, -1, -3, -1, -4, -3, -2, -4, -4, -2,
- -1, -2, -4, -2, -2, -1, -2, -2, -2, -3, -2, 0, 2, 0, -2, -2,
- 0, 2, 3, 5, 4, 4, 4, 6, 3, 1, 0, 0, 0, 0, 5, 5,
- 4, 6, 4, 2, 0, -2, -3, -6, -9, -8, -10, -10, -2, 3, 4, 4,
- 4, 5, 4, 4, 5, 4, 4, 4, 4, 2, 3, 2, 2, 2, 1, 1,
- 0, -2, -3, -3, -4, -6, -8, -7, -4, -6, -3, -3, -3, -2, 1, 0,
- -1, -2, -2, -1, -1, 0, 1, 0, 0, 1, 0, 0, 0, -1, -2, -3,
- -3, -4, -5, -4, -3, -3, -3, -3, -3, -3, -2, -1, 0, -1, 0, 0,
- 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 2, 3,
- 3, 2, 2, 0, -1, -1, -2, -3, -3, -4, -5, -4, 0, 3, 3, 3,
- 3, 2, 3, 4, 6, 4, 4, 3, 2, 1, 2, 1, 0, 0, -1, -2,
- -3, -3, -2, -2, -3, -3, -3, -3, -3, -2, -2, -2, -2, -2, -2, -2,
- -2, -3, -2, -3, -2, -2, 0, 0, 0, 0, 0, -1, -1, -2, -2, -3,
- -2, -4, -4, -3, 0, -1, 0, 0, 0, 0, 0, 1, 2, 1, 1, 1,
- 0, 0, 0, -1, 0, -1, -1, -1, -1, -1, 0, 0, -1, 0, 0, 0,
- 1, 1, 1, 1, 1, 1, 0, 0, 0, -1, 0, -1, 0, 0, 0, 0,
- 0, 0, -1, -1, -2, -2, -2, -2, -2, -3, -3, -1, 0, 0, 0, 0,
- 0, 0, 0, 1, 1, 1, 0, 0, 0, -8, -33, -24, -25, -25, -26, -27,
- -32, -28, -36, -31, -36, -22, -34, 11, -74, -14, 94, 41, 28, 33, 30, 40,
- 34, 23, 41, 40, 60, 56, 59, 60, 44, 39, 54, 45, 52, 17, 44, 62,
- 34, 33, 19, 18, 43, 35, 22, 36, -15, -10, 32, -7, -12, -6, -8, -50,
- -47, -44, -4, -25, -48, -76, -58, -75, -96, -85, -118, -114, -63, -106, -103, -83,
- -110, -99, -84, -76, -58, -63, -61, -51, -53, -36, -32, -41, -27, -11, 11, 8,
- 27, 19, 30, 35, 28, 57, 53, 38, 71, 51, 68, 110, 78, 89, 109, 97,
- 82, 94, 115, 114, 79, 70, 79, 94, 85, 76, 84, 95, 83, 82, 55, 54,
- 54, 41, 41, 27, 20, 6, -11, -21, -16, -14, -33, -33, -52, -54, -59, -62,
- -71, -79, -88, -88, -78, -78, -72, -71, -94, -99, -93, -90, -78, -87, -105, -103,
- -79, -62, -71, -78, -63, -61, -66, -49, -23, -10, -11, -24, -20, -4, -22, 9,
- 8, 27, 43, 34, 38, 51, 83, 65, 58, 74, 75, 70, 73, 71, 65, 100,
- 89, 94, 65, 84, 49, 49, 61, 54, 43, 51, 58, 53, 35, 40, 36, 38,
- 34, 23, 14, -12, -10, -1, -1, -11, -12, -19, -33, -66, -52, -42, -37, -55,
- -42, -28, -32, -29, -35, -41, -28, -25, -46, -85, -64, -62, -55, -49, -68, -55,
- -53, -52, -47, -43, -26, -32, -41, -34, -35, -40, -26, -8, -1, -6, -11, 5,
- -2, 8, 3, 8, 6, 4, 20, 29, 43, 24, 33, 20, 30, 24, 39, 38,
- 40, 29, 37, 36, 39, 61, 58, 41, 51, 59, 51, 55, 58, 48, 32, 45,
- 40, 27, 30, 41, 44, 26, 19, 23, -3, 7, 0, -3, 2, 3, -6, -5,
- -14, -6, -10, -27, -45, -47, -41, -38, -50, -51, -46, -43, -45, -65, -65, -80,
- -95, -82, -74, -66, -69, -67, -33, -31, -53, -48, -51, -43, -18, -24, -24, -33,
- -26, -10, 0, -17, -6, 17, 31, 2, 23, 45, 46, 12, 75, 38, 63, 69,
- 31, 38, 80, 57, 48, 59, 81, 74, 32, 52, 72, 24, 60, 44, 55, 40,
- 28, 48, 33, 24, 10, -2, 21, 34, 13, 18, 7, -1, -12, -20, -18, -30,
- -9, -7, -30, -27, -26, -38, -20, -54, -55, -64, -53, -36, -62, -37, -71, -47,
- -42, -71, -45, -55, -50, -54, -56, -36, -37, -54, -36, -12, -38, -33, -26, -7,
- -22, -44, -10, 2, 3, 15, 8, 18, 6, 12, 8, 15, 28, 22, 50, 35,
- 55, 42, 36, 49, 52, 64, 48, 60, 49, 60, 62, 40, 47, 68, 52, 59,
- 61, 44, 53, 44, 35, 31, 31, 47, 22, 6, 4, -7, 5, -4, -21, -13,
- -9, -10, -27, -46, -32, -44, -46, -62, -44, -51, -67, -53, -59, -63, -74, -67,
- -61, -61, -65, -47, -58, -57, -45, -41, -46, -41, -38, -22, -25, -34, -16, -10,
- -18, 0, 1, -6, 5, 17, 15, 10, 23, 38, 28, 28, 54, 40, 19, 55,
- 55, 41, 46, 53, 40, 49, 51, 52, 41, 56, 39, 53, 38, 33, 35, 18,
- 15, 38, 30, 23, 27, 13, 11, 7, 16, -1, 0, 0, 13, -6, -10, -15,
- -10, -10, -24, -20, -16, -38, -36, -21, -40, -32, -42, -38, -52, -53, -41, -48,
- -58, -50, -47, -37, -41, -45, -29, -41, -6, -48, -24, -25, -15, -9, -10, -10,
- -10, -1, -17, 4, 3, 10, -4, 9, 15, 25, 24, 19, 23, 34, 28, 33,
- 37, 38, 26, 36, 47, 35, 46, 45, 28, 35, 32, 32, 24, 21, 26, 23,
- 19, 37, 20, 9, 29, -2, 26, 24, 8, 4, 14, 21, 11, -9, -8, 4,
- -9, -31, -11, -15, -21, -24, -29, -22, -33, -26, -29, -48, -32, -44, -28, -22,
- -35, -30, -38, -31, -46, -44, -36, -27, -23, -29, -24, -11, -20, -28, -13, -34,
- -19, -1, 7, -3, -1, 6, -3, 5, 4, 8, 17, 26, 19, 33, 27, 16,
- 35, 14, 36, 39, 22, 32, 31, 19, 32, 23, 29, 21, 30, 29, 23, 31,
- 13, 24, 17, 11, 26, 18, 12, 5, 23, 16, 9, 15, -10, 3, 18, -15,
- -4, -4, 6, -14, -15, -5, -34, -11, -20, -18, -8, -17, -29, -30, -29, -19,
- -34, -35, -20, -36, -20, -16, -21, -38, -16, -30, -24, -25, -19, -18, -15, -7,
- -5, -5, -10, -23, -3, -14, 0, -1, -12, -9, 7, 7, 2, 12, 5, 7,
- 19, 10, 21, 21, 27, 30, 22, 18, 34, 22, 11, 26, 24, 20, 21, 25,
- 29, 22, 27, 27, 20, 10, 20, 16, 22, 15, 16, 16, 5, 19, 10, 3,
- 22, -5, -5, -7, -16, -4, -11, -22, -7, -16, -11, -23, -16, -30, -24, -28,
- -20, -29, -24, -32, -22, -22, -30, -17, -23, -28, -22, -20, -21, -21, -17, -30,
- -15, -14, -20, -9, 3, 6, 5, -20, 10, 13, -2, 11, 8, -1, 7, 16,
- 5, 22, 23, 13, 22, 13, 22, 25, 15, 16, 11, 15, 13, 7, 12, 19,
- 18, 20, 12, 23, 11, 6, 10, 1, 11, 19, 5, 20, 0, 11, 11, 1,
- 14, 15, -3, -1, -7, 6, -6, -9, -9, 4, -3, -10, -20, -14, -9, -14,
- -7, -10, -5, -4, -29, -14, -12, -26, -21, -27, -18, -10, -19, -27, -18, -8,
- -25, -8, -13, -15, -14, -15, 5, -13, -7, -11, -4, -12, 0, 15, 5, 4,
- 1, 11, 6, 4, 3, 6, 21, 19, 8, 15, 13, 6, 14, 16, 18, 17,
- 20, 15, 11, 15, 24, 13, 11, 19, 7, 17, 14, 6, 17, 7, 7, 6,
- 6, 5, 11, 0, 6, 0, -6, 5, 1, -11, -6, -1, -8, -9, -15, -7,
- -4, -16, -17, -13, -13, -17, -14, -12, -12, -28, -13, -19, -25, -31, -24, -17,
- -17, -16, -7, -15, -12, -8, -15, -8, -16, -10, -4, -1, -2, 3, 5, 2,
- -2, 5, 3, 6, 10, 8, 11, 14, 14, 13, 15, 22, 16, 14, 18, 13,
- 17, 19, 16, 10, 17, 8, 17, 14, 3, 14, 7, 10, 10, 7, 6, 6,
- -1, 6, 1, 0, 12, -6, 6, 12, -4, -5, -4, -2, -2, -1, -2, -8,
- -11, -9, -11, -11, -18, -6, -5, -16, -9, -14, -10, -13, -10, -11, -15, -14,
- -14, -12, -17, -17, -17, -7, -11, -14, -15, -12, -6, -15, -5, -13, -9, 0,
- 12, -2, -2, 6, 2, -7, 4, 10, 2, 9, 8, 7, 4, 5, 11, 15,
- 11, 10, 18, 9, 13, 13, 13, 21, 11, 18, 19, 13, 14, 16, 6, 8,
- 1, 19, 11, 10, 11, 1, 3, -1, -1, 5, -11, 5, -1, -5, -3, -13,
- -10, -6, -7, -5, -15, -10, -11, -18, -8, -16, -20, -18, -9, -12, -17, -21,
- -21, -13, -21, -8, -10, -10, -5, -16, -7, 2, -6, -6, -9, -7, -2, -9,
- -5, 6, -7, 1, 3, -1, 2, 1, 2, 9, 8, 5, 15, 12, 1, 11,
- 9, 8, 10, 15, 14, 5, 13, 17, 14, 15, 10, 7, 16, 5, 5, 5,
- 8, 9, 10, 10, 7, 0, 4, 6, 9, -10, -4, 5, 2, -1, 0, -3,
- -4, -5, -10, -5, -8, -9, -10, -3, -13, -6, -9, -20, -15, -11, -18, -14,
- -10, -12, -20, -14, -14, -7, -12, -21, -14, -9, -8, -11, -5, -2, -7, -4,
- 4, -2, -3, -1, 0, -1, 8, 6, 9, 7, 10, 6, 3, 4, 7, 10,
- 11, 6, 9, 17, 11, 9, 7, -2, 16, 13, 12, 18, 5, 16, 9, 4,
- 9, 6, 8, 9, 4, 4, 3, -2, -3, 2, -6, -3, 1, -7, -6, -3,
- -6, -14, -8, -9, -4, -13, -9, -8, -16, -10, -12, -13, -11, -7, -8, -12,
- -9, -8, -7, -11, -4, -8, -7, -8, -3, -13, -10, -3, 6, -5, -5, 0,
- -5, -3, 6, -2, -2, 4, -2, 6, 2, -2, 5, 5, -2, 5, 15, 13,
- 4, 6, 6, 14, 9, 4, 8, 7, 3, 11, 12, 2, 10, 7, 10, 8,
- 4, 6, 2, 0, 3, 2, 4, 2, -6, -2, 2, -4, 3, -5, -6, -5,
- -5, -5, -4, -8, -7, -4, -4, -7, -8, -7, -13, -10, -10, -11, -9, -8,
- -8, -7, -11, -7, -3, -9, -6, -7, -3, -4, -5, 3, -3, -1, -2, -4,
- 1, 4, 0, 3, 0, 5, 2, 0, 5, 4, 1, 3, 1, 0, 1, 7,
- 3, 0, 4, 3, 6, 5, 0, 9, 5, 7, 6, 3, 6, 2, 3, 5,
- -4, 9, 0, 4, 10, 0, 5, 1, -2, 4, -3, -3, -2, 0, 2, -7,
- 3, -10, -1, -6, -9, -2, -4, -10, -3, -7, -6, -4, -10, -6, -6, -11,
- -6, 0, -6, -8, -4, -1, -9, -10, 0, -6, -7, -2, -7, 1, -5, -5,
- -1, 1, -6, 2, 0, -3, -1, 7, -4, 0, 7, 0, 8, 2, 3, 4,
- 4, 2, 5, -1, 6, 7, 5, 6, 4, 2, 4, 6, 8, 6, 3, 1,
- 8, 9, 2, -1, 4, 3, 4, 3, -3, 7, 4, 3, -2, 2, -4, -6,
- -2, -5, -2, -3, 0, -5, -6, -13, -5, -6, -11, -9, -10, -5, -4, -9,
- -9, -7, -7, -8, -8, -6, -5, -7, -5, -1, -3, -4, -2, -2, 2, -3,
- 1, 2, -3, 1, 2, 1, 0, 1, 5, 0, 2, 5, 2, 0, 4, 1,
- 7, 3, 2, 6, 0, 5, 7, 5, 5, 1, 3, 3, 5, 10, 3, 4,
- 8, 2, 7, 3, -2, 3, 0, -1, -1, 1, 0, 1, -3, -2, -5, -4,
- -3, -1, -7, -8, -4, -4, -10, -2, -8, -8, -8, -8, -9, -6, -8, -9,
- -4, -2, -7, -5, -2, -7, -6, -9, -2, 0, -4, 4, -6, -3, -4, -1,
- 2, 1, 2, 9, 0, 3, 0, 6, 4, 0, 5, 6, 2, 7, 7, 5,
- 7, 6, 8, 6, 6, 5, 5, 1, 6, 5, -1, 3, 4, -1, 4, 1,
- 4, 3, -5, 0, 4, 1, 4, -2, -3, -4, 0, -4, -8, -2, -5, -4,
- -8, -6, -5, -3, -3, -7, -9, -6, -10, -10, -6, -6, -5, -4, -7, -6,
- -4, -10, -3, -10, 0, -2, -2, -6, -1, 3, -3, -3, 1, 2, 1, 4,
- 3, 4, 3, 4, 1, 2, 6, 5, 5, 5, 7, 9, 1, 5, 4, 4,
- 7, 2, 9, 2, 4, 8, 2, 5, 6, 3, -2, -2, -1, -2, -1, 1,
- -2, -4, 1, -6, -2, -5, -3, -5, -5, -6, -4, -3, -4, -10, -4, -3,
- -8, -4, 0, -3, -5, -6, -6, -3, -1, -7, -3, 1, -1, -4, -2, 1,
- -2, 0, -1, -2, 0, 0, 5, -2, 0, 3, 3, 1, 5, 2, 4, 1,
- 4, 1, 2, 3, 3, 3, 4, 3, 3, 5, 1, 4, 2, 3, 1, 2,
- 0, 2, 1, -2, -2, -1, 0, -2, -1, -1, -3, -5, -2, 0, -5, -1,
- 0, -5, -2, -2, -2, -3, -3, -1, -4, -1, -2, -4, -2, -1, -2, -1,
- 0, -3, -1, -1, 0, 1, -1, -1, 3, -4, -2, -2, 4, -2, -1, -1,
- -1, 0, 0, -1, -1, -1, -1, 2, 0, -1, 2, -1, 0, -1, 2, 0,
- 3, 5, -2, 1, 2, 0, 5, 0, -3, 4, -3, 1, 2, 0, 4, -1,
- -2, 1, 0, 0, 0, -1, 1, -2, 0, 1, 1, 0, -5, 1, -2, -1,
- 0, -2, -3, -1, -3, 0, -2, -3, -4, 1, -2, -3, -2, -2, -1, -1,
- -2, -1, -4, -5, 2, -4, 0, 1, -1, 2, -2, -1, 0, 0, 1, -3,
- 3, 2, 0, -2, 2, 1, 2, -2, 5, 3, -2, -2, -1, 1, 0, 0,
- 1, 3, 2, 0, 0, -1, -2, 1, 1, 2, 1, 1, -1, 0, -1, -1,
- -1, -3, 1, 1, 2, -2, -1, 0, 0, -2, 0, -1, -1, 2, -2, 1,
- -1, 0, 0, -1, -1, -2, 0, -1, 1, -1, -1, 2, -2, 0, -1, -1,
- 2, -1, 0, -3, -1, 0, 0, 0, -3, -3, -2, 0, 0, -1, -1, 0,
- -4, 2, 0, -2, 0, 1, -3, -1, 2, 1, 0, -1, 0, 0, -1, 0,
- 2, -1, -1, 0, 0, -2, 1, 1, 0, 1, 0, 2, -3, -2, 2, -1,
- -1, 2, -2, 1, 1, 0, 0, 1, 1, 0, -4, 3, -1, 2, 0, 2,
- -1, -2, 0, 1, 1, -1, -1, -1, -1, -1, -2, -2, -2, -2, -2, -1,
- -1, 1, 0, -5, 0, -1, -1, -1, 1, -1, 1, -1, 1, 0, -2, 0,
- -2, 1, -1, 1, 0, -1, -2, 0, -1, 0, 0, 2, 0, 0, 0, 1,
- 0, 0, 2, 0, -1, 0, 0, 0, 2, -1, 1, 1, -1, -1, 0, 0,
- 1, 1, 0, 0, 0, 0, -1, 0, 0, -2, 0, 0, -1, 1, -2, -1,
- -1, -1, -2, -1, -2, 1, -1, 0, -2, -2, 1, -2, -1, 1, 0, 1,
- 1, -1, -1, 0, -1, 0, 0, 0, -2, 0, -1, 0, 0, -1, -2, -2,
- -2, 1, -1, 0, 0, -1, 1, 1, -2, -1, -2, -1, 1, -1, -1, -2,
- -2, 0, 0, 1, -1, -1, -1, -1, -2, 2, 0, 0, 1, 1, 1, -2,
- 0, -1, 0, -1, -1, 2, 0, -1, -1, -1, 1, -1, 2, 0, -1, 1,
- 1, 0, 1, 0, -1, -1, -1, -1, -3, 0, 0, -1, 1, 0, 0, -2,
- -2, -2, 0, -1, 0, 0, -1, 0, -1, -2, -1, -2, 0, -2, 0, 0,
- -1, -2, 1, -2, 0, -1, -2, 2, 0, -1, 2, -1, 1, -1, 0, 0,
- -1, 0, 0, 0, -1, 0, 1, 0, 0, 1, 0, -1, -1, 0, -2, -1,
- 0, 0, 1, 0, 0, 0, 0, -1, -1, 1, -1, -2, -1, 0, 0, -2,
- 0, -1, 0, 0, 0, 1, 0, 0, -1, 1, 0, -1, 0, 1, -1, 0,
- -1, -2, 0, -1, 0, -1, -1, -1, 0, -1, 0, 0, 0, -1, -1, 0,
- -2, 0, 0, 0, -2, -2, 0, -2, -1, -1, -1, -2, 0, -1, -1, -1,
- 0, 0, -1, -1, 0, 1, -1, -1, 0, -1, 0, 0, 1, 1, 0, 0,
- -1, 0, 0, 0, 0, 0, 1, -1, 0, 0, 0, 1, 0, 0, -1, 0,
- 0, -1, -1, 0, -1, -1, 0, -1, 0, -1, -1, 0, -2, -1, 0, -1,
- -1, -1, -1, 0, -1, 0, 0, 0, 0, -1, 1, 0, 0, 0, -1, -1,
- 0, -1, -1, 0, 0, 0, 0, 0, -1, -1, 0, -1, -1, 0, 0, -1,
- 0, -2, 0, -1, -1, -1, 0, -1, -1, 0, -1, 0, 0, 0, -2, -1,
- 0, -1, -1, 0, 1, -1, -1, 0, 0, 0, 0, -1, -1, -1, -1, 0,
- 1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, -1, 0, 0,
- -1, 0, 0, -1, -1, -1, 0, 0, -1, -1, 0, -1, 0, 0, 0, -1,
- 0, -1, -1, 0, -2, -1, -1, -1, 0, -1, 0, -1, -1, 0, 0, -1,
- 0, -1, 0, -1, -1, -1, 0, -1, 0, -1, 0, 0, -1, 0, -1, 0,
- 0, -1, -1, 0, 0, 0, -1, 0, -1, 0, 1, -1, 0, 0, 0, 0,
- 0, -1, 0, 0, 0, -1, 0, 0, -1, -1, 0, 0, 0, -1, 0, 1,
- -1, -1, -1, 0, 0, -1, -1, -1, -1, 0, -1, 0, 0, 0, 0, 0,
- 0, -1, -1, 0, -1, -1, 0, -1, 0, -1, -1, -1, -1, 0, -1, -1,
- -1, -1, -1, -1, -1, 0, -1, 0, -1, 0, 0, -1, -1, 0, -1, 0,
- -1, 0, 0, -1, 0, -1, -1, -1, 0, -1, 0, 0, 0, 0, 0, -1,
- -1, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, -1, 0, 0, 0,
- 0, -1, 0, -1, 0, 0, 0, -1, -1, 0, 0, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, 0, 0, -1, -1, -1, 0, 0, 0, -1, 0, -1, -1,
- 0, -1, 0, 0, -1, -1, -1, -1, -1, 0, 0, -1, 0, 0, -1, 0,
- 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, -1, 0, 0, 0, 0,
- -1, 0, 0, 0, 0, -1, 0, 0, -1, 0, -1, 0, 0, -1, -1, -1,
- 0, -1, -1, 0, -1, -1, 0, 0, -1, -1, -1, -1, 0, -1, -1, 0,
- 0, -1, 0, 0, 0, -1, -1, 0, -1, -1, -1, 0, 0, -1, -1, -1,
- -1, -1, 0, -1, 0, 0, -1, -1, 0, 0, -1, 0, 0, -1, -1, -1,
- 0, -1, 0, 0, -1, -1, 0, 0, -1, -1, 0, 0, 0, -1, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1,
- 0, 0, 0, -1, 0, -1, 0, -1, -1, -1, -1, -1, -1, 0, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, 0, -4, 11, 6, 16, 10, -16, -48,
- -44, 2, 67, 42, -17, -51, 15, 71, 12, -22, -14, -44, -35, 11, 17, -18,
- 2, -15, 19, 12, -1, -44, -15, 50, 45, -25, -61, 17, 10, -10, 31, 18,
- -72, -27, 57, 26, -13, -17, -2, 6, -1, -23, -54, 17, 39, 8, 30, 28,
- -6, -71, -5, 33, 27, -5, 17, 10, -23, -6, 12, -26, -6, -7, -9, -14,
- 11, 37, 41, 8, -33, -14, 8, -31, -38, 13, 9, 15, 35, 33, 11, 17,
- -41, -48, -33, 29, 25, 16, -9, -9, -17, -19, -29, 43, 64, -2, -55, -42,
- -1, -21, -4, 29, 34, -25, -67, -29, 1, 51, 49, 25, -6, -15, -48, -76,
- -3, 60, 78, 33, 19, 13, -38, -35, -35, -2, 62, 19, -4, -12, -4, -4,
- -32, -30, 8, 68, -43, -66, -28, 55, 51, 20, -28, -29, -19, 20, -2, 8,
- 21, -15, -43, 24, 22, -7, -2, 35, 15, -2, -24, -12, 3, 31, 13, -15,
- -20, -17, -17, 26, -26, 24, -3, 7, 21, 26, -3, -17, -26, -50, -26, 33,
- 58, 49, -22, -67, -17, 24, 7, -57, 5, 42, -11, -3, 32, -3, 7, 13,
- -11, -9, 27, 17, 1, -5, -9, -18, -19, -3, -23, -5, 7, -8, 9, 13,
- 12, -5, 7, -37, 22, 26, 21, 24, -20, -35, 23, 24, -35, -15, 46, -38,
- -48, -14, -4, 0, -22, 3, 43, 38, -1, -14, -8, -5, -14, 1, 21, 23,
- 29, -19, -47, -42, -49, -10, 66, 77, 48, -29, -32, 1, -11, 8, 17, -17,
- 3, 43, 33, -22, -19, -41, 29, 22, -42, 9, 63, 28, -23, -59, -65, 7,
- 53, -22, -10, -27, -30, 36, 48, -4, -6, -22, -16, 10, 14, -7, 22, 50,
- -4, -25, -41, -55, -62, 23, 68, -16, -31, 49, 57, 21, -38, 14, 12, -43,
- -49, -16, 28, 7, -12, -50, -17, 49, 65, 18, 1, -8, 28, 2, -27, -13,
- 12, -11, -52, 4, 31, -32, -39, 15, 8, -19, 6, 25, -1, -23, 13, 34,
- 59, 36, -16, -5, -7, -28, -30, 1, -14, -42, 10, 43, 26, -25, -37, -61,
- 1, 63, 62, 1, -36, -24, 38, -7, -26, 27, 10, 4, 2, -19, -22, -27,
- -24, 0, 33, -8, -57, -12, 62, 77, 51, -10, -42, -27, -28, -31, -3, 5,
- 21, 10, 15, -27, -18, -18, -10, 3, 17, 19, 18, -16, -20, 25, -3, -19,
- -5, 32, 17, -3, -32, -8, 2, -11, -24, -17, -11, 3, 42, 15, -12, -2,
- 26, 9, -4, -30, -3, 16, 7, 13, 34, 40, 114, 11, -104, -71, 7, -14,
- -34, -26, 35, 45, 47, 7, -7, -16, 11, -6, -29, -32, 1, 24, 32, 10,
- 29, -10, -74, -80, -20, 18, 9, 18, 61, 38, -27, -44, 13, 16, -26, 20,
- 69, 14, -14, -46, -7, -6, -35, 0, 9, 5, 58, 71, -36, -78, -15, 43,
- 34, -61, -101, -27, 45, 26, -10, 23, 69, 69, 5, -72, -62, 19, 16, -37,
- -60, 37, 60, 10, -49, -10, -2, -1, 43, 44, 10, -50, -5, 19, 8, -43,
- -58, -17, 32, 28, 4, -1, -18, -10, 13, 8, 1, 1, 22, -3, -4, 9,
- -8, -9, 17, 3, -15, -8, 14, 11, -14, -11, -5, 13, -24, -34, -1, -16,
- -4, 32, 35, -32, 9, 22, 12, -27, -16, 14, 15, 0, -2, -12, -31, -24,
- 14, 48, 10, -14, -7, -22, 4, -8, -14, 19, 21, -21, -25, -12, 19, 24,
- 19, 27, -3, -15, -16, 10, 21, -14, 3, 8, 3, -11, -33, -16, 7, 5,
- -8, 2, -3, 12, 5, -34, -19, -6, 26, 19, 0, -4, -12, 5, 12, 20,
- 16, 19, 18, -13, -42, -26, -1, 0, -18, -16, 10, 27, 23, -5, -7, 9,
- -8, 7, 22, 10, -28, -51, -26, 13, 44, 17, 16, 25, 14, -32, -45, -36,
- -40, -3, 22, 41, 34, -12, -35, -31, 18, 3, 31, 28, 4, -21, 2, -14,
- -24, -23, 19, -6, -7, -10, -1, -13, -13, 21, 52, 28, 7, 1, -25, -36,
- 2, 34, 10, -37, -31, -13, 19, 11, -4, -20, 15, -5, -18, 40, -13, 15,
- -36, 14, 18, 17, -21, 6, -39, 21, 7, -26, 8, -33, 24, 30, 32, -11,
- -26, -47, -39, 62, 10, 11, 5, -17, -21, 10, 0, 18, 15, -22, 7, 13,
- 14, -8, -9, 30, 33, -34, -41, -32, 37, 24, -19, -15, 1, 2, 10, 10,
- -27, -46, -14, -9, 9, 47, 1, -22, -18, 5, 37, 29, -3, -19, -19, -18,
- 8, 17, 1, -11, -6, -20, 27, 37, -2, -28, -34, -3, 22, 54, 34, -31,
- -43, -28, -30, -33, 26, 49, 45, 43, -15, -58, -13, -2, -27, -7, 41, 11,
- 19, -50, -74, -28, 31, 75, 39, -45, -7, 99, 44, -83, -47, 45, -1, -30,
- 23, 29, -55, -30, 31, 28, -19, 2, -44, -46, -49, 30, 22, 58, 31, -50,
- -20, 9, -38, -53, 49, 37, -9, 13, -25, -18, 18, -27, -7, 17, 3, 24,
- 57, 26, -51, -52, -54, -43, 53, 85, 31, -36, -44, 7, 13, 19, -23, -33,
- 36, 47, -38, -11, 37, -19, -6, 18, 17, 2, 31, 54, -29, -72, -80, -1,
- 27, 52, 10, -29, -40, -48, -72, 24, 108, 66, -44, -76, -32, -24, 21, 69,
- 54, 24, -2, -8, -28, -44, -50, 34, 95, 45, -40, -72, -32, 6, 28, -1,
- 18, -7, 27, 1, -14, 21, -8, -51, -62, -24, 64, 56, 12, 19, -36, -22,
- 10, 20, -10, -1, -5, -51, 36, 72, -42, -51, 70, 45, -48, -27, 54, 19,
- -46, 8, 0, -46, 10, 37, 35, -21, -32, -22, -44, -82, -33, 59, 105, 48,
- -32, -36, -31, 18, 60, -12, -49, 10, 89, 28, 12, 8, -45, -21, -6, -16,
- -32, -17, -18, 3, 29, -3, 0, -20, -51, -31, 24, 52, 1, -17, -20, 1,
- 35, 15, 5, 35, 27, 18, -19, 8, -71, -74, -8, 88, 57, -45, -37, 17,
- 51, -1, -13, -4, 3, -13, -24, -7, 30, -7, -25, -1, 16, -8, -43, -70,
- 11, 85, 77, 12, -62, -57, 35, 53, -33, -96, 8, 82, 21, -38, 25, 39,
- -1, -27, -14, 18, -16, -45, -24, 42, 7, -9, 22, 32, -39, -5, -8, -49,
- -17, 60, 88, 21, -93, -20, 82, 31, -26, -63, -17, 52, -28, -25, 13, -2,
- -32, -46, 55, 56, -37, 6, -57, -33, 65, 63, 5, -25, -31, 69, 86, -32,
- -34, -56, -23, -47, 14, 44, -23, 19, 6, 60, -27, -69, -37, 20, -14, -5,
- 50, 44, 15, 13, -23, -60, -46, 23, 40, -5, -25, 6, 46, -4, -10, -27,
- -12, 28, 45, 10, -13, -33, -19, -39, 42, 32, -23, -25, 24, -17, 13, 25,
- 13, -32, 13, 48, 4, -93, -5, 40, -7, 37, -39, -37, 41, 1, -13, -33,
- 43, -53, 106, 8, -57, -93, 55, 40, 56, -24, -4, -19, 7, -23, -65, -18,
- 34, -30, 7, 66, 92, 3, -43, -37, -23, 12, -7, -17, 14, -15, -9, -18,
- 18, 51, -1, -57, -17, 23, 19, 15, -40, -1, 0, -8, 39, -13, -43, 72,
- 57, -1, -54, -17, 32, -19, 11, 0, 36, 25, -23, -86, 21, -3, 14, -17,
- 76, 37, 23, 2, -23, -54, -42, -80, 61, 60, 63, -12, -57, -44, 15, 35,
- 26, 11, -44, -22, 8, 33, -24, -17, 21, 38, -25, -39, 16, 43, -36, -28,
- 54, 10, -52, -18, -34, -14, 76, 60, 24, -32, -19, 16, -13, -68, -5, 30,
- -13, -23, -14, 61, 24, 35, 39, 4, -50, -58, -39, 0, 43, 43, 21, 24,
- -20, -46, -36, 38, 8, -67, -8, 61, 38, 10, -12, 5, -4, -16, -47, -5,
- -18, -20, 37, 41, 24, 4, 7, -19, 11, -52, 0, 17, 20, -30, -33, -16,
- 60, 34, -15, -46, -77, 14, 29, 26, 21, 25, 8, 7, 36, 23, -39, -16,
- 21, 11, -23, 11, -4, -6, -35, 13, -8, -49, -17, 44, 19, -25, -17, 9,
- -5, -5, -1, -31, 11, 15, 17, -8, -31, -51, 12, 54, 85, 32, 4, -58,
- -35, -31, 0, 10, 21, -20, -20, -29, 15, 26, -7, 8, 4, 0, 30, 2,
- -26, 2, 19, 15, -18, -13, -20, -19, 47, 33, -6, -51, -30, -12, 12, 30,
- 34, 31, 4, -45, -81, -7, -22, 1, 73, 98, 24, -67, -13, 19, -32, -86,
- 6, 94, 4, -47, 21, -11, -50, 22, -3, -2, 50, 20, -37, -59, 35, 28,
- -16, -36, -30, -11, 4, 69, 98, -65, -84, 73, 27, -90, -17, 84, 10, -51,
- -14, 40, -24, -11, 16, -34, -26, 38, -43, -34, 58, 85, -33, -51, 17, 7,
- 4, 52, 25, -35, 0, 44, -21, -47, 40, 44, -69, -65, 37, 35, -21, 4,
- 32, -60, -75, 21, 64, 60, -6, -11, 6, 2, -41, -34, 19, 31, 9, 7,
- -1, 11, 6, -11, -26, -23, 16, 35, -39, -68, 6, 56, -3, -42, 29, 28,
- 3, 28, 14, -37, -16, 11, -8, -18, 15, -1, -8, 43, -20, -67, -12, 34,
- 7, -12, -9, 5, -4, 7, -12, 27, -3, -68, 26, 96, 30, -33, -28, -25,
- 19, 27, -33, -48, -3, 37, -1, -35, -11, 5, 42, 36, 6, -48, -38, 26,
- 54, -23, -41, 52, 44, -32, -22, 28, -23, -32, 12, 41, -16, -6, -6, -17,
- -18, -14, -12, -5, 18, 52, 45, -10, -16, 29, 11, -36, -26, 7, 36, 12,
- -57, -48, 48, 70, 16, 21, -13, -46, -33, -62, -63, -21, 94, 94, 20, -110,
- -47, 41, 67, -16, -57, -40, 85, 71, 7, -39, 15, -29, -50, -41, 18, -40,
- -42, 38, 69, 21, -8, -58, -19, 23, 24, -20, -10, 11, 41, 7, -6, -30,
- -23, 2, 16, 57, 38, -11, -50, 36, -16, -51, -51, 81, 24, -68, -84, 39,
- 112, 62, -79, -104, 24, 102, 15, -38, 20, 22, -49, -91, 15, 51, 30, -1,
- -15, -30, -12, 17, 42, -17, -48, 0, 49, 35, 2, -19, -16, -30, 9, 17,
- -12, -4, -15, 5, 34, -1, -56, -64, 7, 48, 54, -16, -51, 20, 62, -17,
- -27, -9, -10, -29, -1, 35, 44, -20, -23, -2, -12, -4, 31, 24, -24, -14,
- 2, -28, -27, 49, 61, -54, -61, 6, 23, -20, 2, 41, 26, 2, 15, -5,
- 6, -16, -36, -16, 2, -54, -53, -18, 62, 64, 10, -3, 91, 39, -54, -103,
- -5, 16, -31, -28, 75, 105, -32, -114, -52, 68, 32, -52, -19, 25, 54, 61,
- 14, -40, 12, 1, -56, -31, 74, 40, -73, -66, 0, 49, 36, 24, -20, 0,
- 13, -40, -99, -11, 55, 31, -33, 39, 24, 3, -18, 7, 10, 4, -29, 17,
- 19, 27, -30, -41, 9, 33, -24, -25, 30, 28, -34, -57, 8, -7, -46, 5,
- 48, -22, -6, 57, 58, -31, -72, -2, 72, 44, -53, -42, 41, 1, -54, 30,
- 54, -6, -79, -14, 33, -6, -22, 14, 10, -5, -8, 13, 23, 21, -47, -74,
- 22, 24, -10, -7, 39, 2, 12, -7, -2, 4, 33, -20, -33, 18, 22, -88,
- -71, 26, 81, 14, -37, 3, -24, 6, -8, 11, 40, 18, -7, -17, 20, -8,
- -15, -41, -11, 27, 52, -27, -46, 33, 21, 46, -30, -13, 26, -91, -106, -47,
- 54, 109, 67, -87, -90, 38, 92, 31, -10, -69, -73, -27, -6, 24, -6, 20,
- 30, 45, 33, -13, -25, 10, 57, -16, -32, 0, -14, -55, -20, 4, 7, -4,
- 3, 18, -11, 34, 11, -45, -45, -125, -38, -2, 19, 72, 82, 99, 98, 35,
- -51, -81, -53, 3, -39, 23, -4, -58, -63, -24, 40, 84, 48, -7, -18, -2,
- -8, -20, -10, 3, 21, 17, -39, -66, -20, -2, 37, 30, 39, 34, -5, -41,
- -26, 33, 40, 18, -2, 11, 13, -20, -60, -21, 33, -25, -35, 30, 65, 22,
- 13, -15, 2, 16, 11, -68, -18, 74, 10, -74, -34, -39, -17, 8, 59, 39,
- -22, -38, -8, 9, 30, 23, 11, -3, -12, 10, -1, 59, 9, -28, -72, -27,
- 32, 68, -11, -3, 27, 4, -33, -39, 7, -1, -5, -7, 26, -14, -26, -40,
- -12, 5, 5, 1, -12, 64, 63, -41, -56, 10, 26, 40, -26, -44, -42, 25,
- -6, 3, -1, 10, 9, -1, 9, 1, -28, 10, 24, 26, -33, -36, 46, 20,
- -43, -52, -35, 22, 53, 30, -6, 18, -16, -49, -36, 45, 10, 21, 7, 9,
- -33, -50, 21, 73, 33, -42, -46, 42, -12, -18, 5, -50, -25, 68, 55, -31,
- -79, -7, 77, 25, -6, 29, 78, 24, -87, -41, -30, -41, -23, 75, 35, -32,
- -65, -7, -13, 3, 41, 34, -24, -33, 25, 14, -52, -28, 19, 76, 45, -45,
- -47, -5, 24, 9, -14, -41, -5, 49, 22, 10, -31, -35, -1, -6, 3, 10,
- -1, -12, -20, -51, 9, 79, 53, -36, -38, -13, -14, -15, 50, 50, -36, -33,
- 0, 5, 22, 23, 24, -51, -81, -27, 56, 42, -10, -16, 0, 0, -5, 16,
- 12, -19, 11, 10, -15, -1, -32, -17, 1, 11, 62, -16, -21, 9, 21, -29,
- -50, 16, 82, 17, -35, -4, 11, 3, 8, 8, -9, -13, 10, -39, -63, -19,
- 54, 58, -16, -25, 18, 38, -8, -50, -54, -17, 18, 47, 17, -33, -45, 0,
- 52, 57, -5, -34, -17, 32, 10, -28, -10, -21, -3, -9, -20, 20, 47, 22,
- 5, -4, -15, -37, -22, -28, 9, 37, -18, -13, 3, 15, -33, -47, 20, 73,
- 0, -36, 33, 60, -11, -77, -13, 42, 13, -20, 9, 47, 22, -27, 29, 6,
- -71, -78, -20, 21, 4, 27, 23, 19, 31, 45, -29, -54, -10, 37, -78, -46,
- -14, 67, 108, 57, 12, -62, -108, -15, 116, 56, -58, -110, -33, 33, 30, -39,
- -26, 11, 29, 22, 8, 52, 76, 31, 0, -31, -50, -10, 59, 54, -13, -84,
- -65, -60, 0, 35, 105, 61, -30, -117, -62, 35, 88, 57, 48, -38, -85, 41,
- 12, -21, -6, 7, 15, 73, -30, -72, -37, 25, 0, -5, 65, 76, -90, -78,
- 24, 47, 2, -14, 40, 83, 0, -32, -46, -62, -26, 50, 37, -4, -44, -40,
- 55, 31, -38, -13, -17, -30, -4, 7, 68, 39, 1, -23, -38, -30, 6, -35,
- 14, 52, -9, -62, -47, 45, 44, 11, -17, -9, 6, 16, 34, -3, -32, -21,
- -33, -3, 21, 26, -39, 11, 65, 33, 19, -1, -49, -85, -97, 66, 58, -93,
- -15, 15, 5, 81, 76, 29, -2, -52, -51, -30, 65, 38, -45, -14, 1, 28,
- 22, 43, 19, -59, -109, -29, 29, -14, -22, -41, 0, 54, 76, 16, 8, 23,
- 15, -47, -39, -8, 5, 36, -6, -3, -4, 13, 13, 21, -47, -53, -6, -9,
- -27, -44, 8, 86, 64, 12, -5, -32, -10, -20, -27, -23, 8, 30, 1, 16,
- 42, -35, -8, 4, -39, -11, -62, -29, 108, 87, -20, -104, -18, -55, 8, 47,
- -16, 29, 38, 4, -44, -39, -20, 38, -13, 23, 82, 30, -67, -93, 26, 79,
- 20, -79, -74, -23, 33, 59, 80, 39, -42, -100, 0, 19, 38, 9, -55, 9,
- -15, 22, 68, -17, -55, -23, 1, 87, 19, -56, -60, 32, 37, 38, -67, -33,
- -1, 31, 24, 15, -30, -5, -36, -29, -27, 8, 27, -9, 12, 29, 38, 33,
- 0, -39, -18, 6, 19, 18, 8, 1, -33, 9, -1, 2, -29, -66, 0, 41,
- 6, -50, -13, 9, 73, -28, -47, -21, 30, 68, 31, 32, 29, -46, -14, 13,
- -44, -75, -3, 62, 55, 9, -49, -1, 54, 19, -6, 7, 16, 38, 13, -26,
- -55, -76, -23, 16, 21, -33, -22, 16, 61, 25, -14, -35, 12, 23, -7, -17,
- -32, -10, -16, -1, 7, 18, -1, 19, -2, -1, 21, -14, 1, -44, -44, -23,
- -29, -1, 28, -28, 47, 64, 12, -4, -15, -37, -7, 24, 50, 6, -15, -26,
- -5, 20, 12, -25, -21, -2, -18, -23, 9, 16, 24, 36, -30, -35, -12, 32,
- 19, -13, 19, -6, 2, -2, -22, -11, 14, 50, 10, -21, -55, -14, 23, 6,
- 6, -6, -26, -25, -8, 25, 14, 24, 14, -13, 18, 11, 23, -34, -49, -45,
- 6, 39, 37, 3, 0, -29, 8, 26, -6, -7, -21, 2, -11, 6, 16, -1,
- -17, 6, 32, -4, -54, -9, 22, -14, 6, 27, -1, -2, 34, 33, 8, 1,
- -8, -14, -32, 23, -22, -23, -29, -12, 5, 25, 22, -4, 14, 5, 24, -39,
- -29, 17, -21, -80, -60, -9, 78, 99, 81, -41, -53, 22, 11, -69, -22, -2,
- 70, 80, 18, -56, -54, -79, -27, 56, 46, 28, -1, 12, -37, -76, 23, 64,
- -4, -5, 4, 0, -2, -5, 10, -4, -9, 5, 3, 3, -2, 6, -2, -1,
- 0, 2, 0, 1, -2, 2, -3, -2, 0, 1, -1, 0, 0, -1, -1, -1,
- 0, -1, -1, -1, -1, 0, 0, -1, 0, -1, -1, -1, -1, -1, -1, 0,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -2, -3, -5, -6, -5, -5,
- -3, 0, -1, -3, -1, 7, 16, 20, 8, -8, -24, -35, -39, -36, -35, -42,
- -47, -35, -14, 0, 8, 17, 28, 45, 60, 65, 64, 66, 67, 60, 50, 39,
- 26, 14, 5, -14, -40, -54, -56, -56, -55, -47, -36, -20, 1, 13, 15, 16,
- 12, 2, -10, -20, -33, -43, -42, -38, -43, -40, -28, -17, -7, 6, 21, 34,
- 48, 60, 63, 64, 66, 61, 54, 51, 41, 23, 10, 1, -18, -37, -46, -54,
- -63, -60, -46, -30, -13, 5, 15, 16, 17, 11, -2, -11, -21, -34, -44, -45,
- -43, -42, -33, -21, -17, -10, 5, 23, 39, 54, 62, 61, 62, 63, 59, 53,
- 47, 38, 23, 10, -5, -23, -36, -42, -51, -61, -61, -48, -26, -2, 14, 16,
- 13, 13, 9, -1, -14, -27, -36, -42, -44, -48, -44, -31, -17, -10, -8, 1,
- 21, 47, 65, 67, 58, 54, 58, 61, 54, 41, 31, 23, 11, -9, -30, -41,
- -44, -45, -54, -61, -52, -21, 11, 25, 19, 8, 4, 7, 2, -15, -33, -39,
- -39, -44, -51, -48, -34, -12, -2, -4, -2, 19, 54, 74, 72, 58, 47, 51,
- 59, 54, 40, 26, 20, 7, -16, -37, -46, -44, -42, -51, -58, -47, -15, 19,
- 31, 25, 9, -1, -1, -4, -15, -30, -37, -41, -51, -55, -48, -28, -11, -4,
- -2, 6, 28, 58, 73, 74, 63, 50, 45, 46, 49, 42, 31, 19, -6, -30,
- -43, -44, -42, -51, -54, -49, -33, -3, 18, 30, 31, 17, 2, -13, -15, -15,
- -25, -31, -45, -62, -60, -45, -24, -16, -10, 6, 20, 40, 58, 68, 74, 69,
- 55, 41, 37, 44, 43, 34, 15, -17, -41, -48, -46, -51, -59, -51, -34, -16,
- 3, 17, 29, 33, 23, 2, -15, -18, -18, -22, -31, -50, -64, -61, -42, -30,
- -24, -8, 13, 35, 50, 57, 65, 70, 70, 58, 42, 40, 41, 40, 32, 6,
- -23, -45, -53, -55, -64, -60, -45, -24, -1, 10, 19, 27, 28, 23, 4, -9,
- -17, -22, -23, -36, -53, -61, -60, -47, -36, -22, -3, 19, 44, 56, 60, 65,
- 65, 65, 60, 52, 45, 39, 37, 23, -2, -26, -49, -63, -66, -63, -55, -42,
- -16, 3, 14, 25, 25, 22, 19, 11, -2, -17, -20, -29, -44, -50, -58, -64,
- -53, -32, -13, 0, 25, 45, 53, 65, 68, 61, 60, 63, 60, 47, 42, 33,
- 7, -10, -26, -56, -73, -68, -57, -53, -37, -12, -1, 14, 32, 26, 16, 17,
- 16, 1, -12, -19, -38, -52, -47, -55, -65, -50, -23, -9, 4, 27, 40, 48,
- 68, 72, 59, 58, 67, 64, 52, 42, 21, -5, -16, -31, -60, -73, -62, -54,
- -49, -34, -17, -4, 17, 32, 24, 13, 18, 20, 6, -11, -29, -46, -48, -46,
- -54, -59, -41, -17, -5, 6, 20, 35, 54, 71, 68, 55, 60, 74, 71, 53,
- 27, 5, -6, -16, -35, -62, -70, -57, -49, -45, -40, -25, 4, 25, 29, 15,
- 7, 23, 27, 10, -20, -46, -47, -41, -39, -47, -55, -34, -11, -1, 4, 11,
- 38, 67, 72, 62, 48, 61, 83, 76, 49, 9, -9, -7, -15, -31, -59, -70,
- -55, -48, -46, -43, -21, 16, 29, 22, 6, 1, 25, 32, 10, -28, -57, -47,
- -34, -30, -38, -49, -33, -12, -4, 3, 17, 50, 72, 68, 55, 44, 61, 86,
- 77, 41, -2, -16, -10, -13, -28, -56, -69, -58, -52, -47, -35, -7, 22, 25,
- 13, -4, -2, 25, 33, 7, -35, -58, -46, -29, -22, -32, -44, -34, -16, -5,
- 8, 30, 59, 72, 65, 46, 39, 62, 87, 76, 33, -8, -20, -13, -10, -28,
- -57, -70, -62, -51, -42, -24, 3, 23, 23, 4, -15, -4, 25, 34, 3, -38,
- -55, -45, -23, -17, -32, -43, -34, -15, -1, 14, 41, 64, 73, 59, 35, 35,
- 64, 89, 73, 26, -11, -23, -14, -11, -33, -60, -69, -59, -48, -39, -14, 11,
- 25, 17, -11, -24, -3, 30, 35, -3, -40, -54, -41, -18, -19, -36, -41, -28,
- -10, 0, 21, 51, 70, 71, 47, 24, 36, 72, 93, 65, 17, -14, -22, -13,
- -17, -43, -62, -63, -52, -48, -36, -5, 19, 26, 5, -26, -27, 5, 40, 31,
- -12, -42, -50, -34, -20, -28, -37, -33, -17, -8, -1, 29, 61, 75, 64, 31,
- 19, 44, 85, 93, 51, 9, -15, -18, -16, -30, -50, -57, -52, -48, -52, -32,
- 3, 25, 20, -10, -34, -21, 19, 42, 20, -17, -40, -43, -35, -30, -32, -32,
- -21, -12, -12, 3, 37, 67, 72, 50, 25, 24, 57, 92, 81, 42, 6, -12,
- -18, -25, -39, -53, -52, -44, -49, -51, -28, 6, 25, 13, -17, -32, -11, 29,
- 39, 8, -24, -38, -37, -33, -36, -39, -30, -10, -3, -9, 3, 38, 68, 71,
- 46, 23, 32, 68, 92, 71, 31, 5, -7, -16, -31, -50, -55, -45, -37, -49,
- -53, -27, 8, 23, 8, -20, -24, 3, 34, 28, -6, -28, -32, -30, -35, -46,
- -43, -23, 0, 0, -10, 5, 41, 67, 65, 42, 30, 47, 77, 83, 52, 23,
- 10, 2, -16, -43, -60, -55, -38, -36, -53, -53, -25, 8, 19, 3, -14, -8,
- 17, 29, 9, -17, -24, -22, -26, -43, -53, -42, -14, 4, -3, -9, 10, 44,
- 63, 58, 43, 43, 63, 77, 64, 38, 24, 20, 7, -23, -52, -62, -49, -38,
- -45, -57, -49, -19, 6, 11, 2, -1, 12, 22, 13, -7, -18, -15, -17, -32,
- -50, -52, -32, -11, -4, -8, -3, 21, 44, 55, 53, 52, 63, 70, 64, 49,
- 35, 34, 24, 0, -29, -53, -54, -50, -51, -56, -57, -37, -17, -2, 7, 9,
- 20, 21, 12, 1, -13, -11, -13, -24, -36, -49, -40, -30, -22, -12, -9, 10,
- 25, 38, 51, 57, 70, 71, 62, 57, 44, 42, 34, 15, -4, -30, -42, -53,
- -65, -61, -61, -49, -35, -22, -2, 10, 25, 27, 15, 11, -1, -8, -14, -22,
- -27, -37, -37, -37, -40, -26, -14, -2, 10, 24, 42, 54, 68, 73, 65, 65,
- 60, 49, 36, 27, 15, -7, -25, -43, -63, -69, -65, -61, -54, -36, -13, 3,
- 18, 26, 23, 20, 16, 1, -16, -21, -20, -31, -37, -38, -40, -38, -25, -15,
- -7, 11, 34, 48, 56, 66, 71, 72, 73, 61, 43, 34, 29, 11, -14, -31,
- -46, -63, -69, -72, -69, -53, -28, -7, 3, 16, 27, 30, 28, 15, -3, -14,
- -19, -25, -39, -42, -37, -38, -35, -30, -19, -2, 18, 39, 47, 56, 69, 75,
- 78, 71, 60, 49, 35, 22, -1, -20, -32, -50, -65, -76, -75, -63, -49, -27,
- -9, 6, 22, 28, 31, 27, 16, 6, -13, -26, -36, -43, -41, -42, -42, -36,
- -27, -10, 2, 18, 38, 52, 64, 70, 73, 79, 76, 70, 50, 27, 11, -5,
- -21, -41, -62, -69, -72, -68, -61, -50, -26, -4, 13, 21, 23, 32, 35, 27,
- 6, -21, -33, -37, -42, -48, -53, -45, -31, -19, -8, 3, 23, 45, 59, 65,
- 65, 73, 88, 88, 69, 40, 19, 10, -6, -30, -54, -69, -69, -68, -67, -59,
- -43, -18, 2, 10, 15, 22, 39, 46, 27, -3, -28, -34, -37, -48, -56, -60,
- -48, -29, -16, -1, 14, 35, 52, 58, 60, 64, 80, 96, 88, 64, 34, 16,
- 6, -11, -36, -62, -77, -75, -68, -58, -47, -33, -14, -1, 7, 15, 28, 43,
- 44, 24, -6, -30, -38, -40, -49, -63, -68, -56, -30, -5, 15, 27, 40, 51,
- 59, 63, 72, 84, 91, 83, 60, 32, 12, 1, -14, -45, -73, -84, -78, -62,
- -46, -36, -28, -17, 0, 11, 20, 31, 38, 35, 20, -6, -28, -40, -46, -58,
- -72, -71, -52, -26, 4, 26, 37, 45, 54, 64, 69, 74, 81, 80, 73, 59,
- 35, 13, -5, -28, -54, -75, -79, -74, -63, -43, -30, -21, -11, 0, 14, 23,
- 29, 33, 23, 14, -2, -25, -41, -58, -69, -71, -64, -43, -24, 3, 33, 47,
- 56, 60, 64, 73, 74, 75, 73, 62, 56, 38, 13, -12, -42, -57, -69, -77,
- -71, -63, -44, -25, -15, -3, 2, 13, 26, 23, 24, 19, 8, -2, -24, -44,
- -64, -74, -64, -60, -45, -16, 9, 34, 53, 63, 68, 66, 75, 73, 63, 66,
- 62, 49, 34, 11, -17, -43, -54, -66, -82, -72, -52, -43, -28, -10, 0, 4,
- 18, 27, 16, 13, 20, 8, -11, -26, -47, -66, -63, -59, -63, -47, -7, 20,
- 34, 56, 69, 65, 73, 81, 67, 54, 61, 63, 44, 25, 6, -23, -37, -44,
- -69, -85, -69, -48, -39, -26, -7, -4, 5, 27, 25, 9, 10, 15, 5, -17,
- -34, -52, -62, -54, -54, -60, -40, -5, 21, 41, 59, 67, 66, 78, 81, 64,
- 53, 58, 56, 39, 18, -3, -24, -34, -45, -64, -76, -67, -51, -37, -21, -8,
- -3, 11, 22, 20, 11, 9, 11, -4, -23, -38, -56, -57, -53, -50, -42, -31,
- -5, 21, 41, 63, 67, 72, 77, 69, 67, 58, 56, 49, 28, 16, -8, -28,
- -35, -50, -53, -62, -65, -53, -44, -20, -2, 2, 14, 10, 14, 17, 7, 5,
- -13, -27, -37, -60, -58, -55, -42, -22, -18, -2, 13, 36, 69, 73, 76, 71,
- 62, 70, 60, 53, 42, 23, 16, -13, -35, -45, -51, -40, -46, -58, -60, -52,
- -17, 4, 8, 11, 5, 14, 15, 4, -4, -20, -23, -37, -62, -67, -59, -27,
- -2, -3, -3, 3, 36, 70, 77, 75, 66, 67, 70, 57, 46, 32, 29, 19,
- -17, -49, -62, -46, -25, -33, -54, -68, -51, -15, 4, 8, 6, 11, 18, 8,
- -7, -19, -16, -12, -35, -68, -83, -56, -9, 13, 7, -7, 4, 40, 66, 73,
- 69, 73, 80, 69, 46, 27, 31, 42, 24, -23, -68, -69, -36, -14, -25, -57,
- -66, -43, -16, -3, -2, 11, 28, 23, -2, -31, -29, -4, -1, -34, -83, -89,
- -45, 3, 22, 6, -3, 16, 41, 56, 55, 68, 93, 93, 65, 23, 12, 38,
- 53, 27, -38, -80, -64, -29, -12, -31, -54, -49, -34, -22, -24, -11, 28, 47,
- 25, -24, -51, -27, 5, 5, -43, -90, -79, -34, 6, 11, 4, 17, 31, 39,
- 34, 38, 79, 114, 105, 50, 3, 12, 44, 56, 16, -49, -72, -54, -28, -29,
- -44, -37, -27, -28, -41, -45, -5, 46, 61, 17, -44, -53, -20, 7, -6, -53,
- -78, -62, -27, -7, -6, 14, 41, 45, 26, 11, 38, 93, 127, 101, 34, 1,
- 20, 48, 42, -1, -41, -53, -45, -40, -51, -44, -18, -9, -34, -61, -47, 7,
- 57, 58, 2, -46, -43, -14, -5, -27, -52, -58, -46, -31, -26, -12, 28, 59,
- 45, 10, 6, 50, 104, 124, 87, 30, 11, 30, 40, 19, -9, -26, -35, -44,
- -58, -62, -38, -4, -6, -46, -67, -37, 21, 56, 43, -4, -37, -30, -15, -25,
- -40, -44, -38, -38, -43, -38, -9, 40, 64, 37, 5, 14, 65, 106, 107, 75,
- 36, 26, 34, 24, 4, -8, -10, -24, -53, -70, -64, -30, 0, -16, -53, -61,
- -22, 28, 43, 29, -2, -21, -20, -26, -39, -43, -34, -26, -43, -54, -40, 0,
- 46, 56, 30, 12, 30, 75, 97, 90, 69, 47, 38, 29, 13, 2, 0, -1,
- -27, -61, -71, -55, -25, -14, -32, -50, -41, -6, 22, 25, 17, 4, -8, -19,
- -31, -38, -35, -28, -35, -53, -54, -29, 7, 31, 32, 23, 28, 51, 72, 78,
- 72, 65, 55, 42, 30, 19, 15, 11, -8, -36, -58, -58, -42, -35, -35, -43,
- -40, -18, 0, 12, 14, 11, 9, -4, -15, -25, -31, -28, -36, -49, -53, -45,
- -18, 1, 12, 19, 23, 43, 58, 64, 68, 64, 64, 57, 46, 40, 28, 22,
- 9, -17, -35, -48, -47, -44, -47, -45, -44, -31, -12, -2, 7, 10, 9, 7,
- -2, -8, -19, -28, -32, -44, -51, -48, -37, -21, -9, 5, 16, 26, 43, 55,
- 60, 64, 63, 61, 58, 55, 48, 34, 21, 6, -13, -27, -39, -49, -53, -50,
- -46, -41, -32, -16, -3, 5, 11, 9, 6, 5, -4, -17, -32, -40, -42, -44,
- -42, -40, -32, -12, 5, 17, 24, 35, 50, 58, 64, 64, 60, 65, 61, 50,
- 34, 18, 10, -2, -18, -38, -58, -56, -49, -45, -41, -38, -22, -4, 8, 14,
- 8, 11, 10, -5, -20, -38, -41, -36, -37, -40, -48, -37, -12, 4, 14, 19,
- 27, 46, 59, 66, 63, 62, 70, 64, 50, 34, 22, 17, 8, -11, -38, -59,
- -57, -50, -49, -47, -43, -28, -6, 10, 16, 10, 14, 8, 1, -5, -5, -4,
- -5, 5, 2, 2, 1, -1, 0, 1, 0, 2, 0, 0, -2, -1, -1, 2,
- 1, 1, 0, 0, -1, 0, -1, 0, 0, 0, 0, 0, 0, -1, -1, -1,
- 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, -1,
- -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1,
- -1, 0, 1, 0, 0, 0, 1, 0, 1, 0, -3, -10, -11, -8, -13, -25,
- -21, -10, 0, 2, 18, 41, 44, 42, 66, 62, 28, 10, 17, 17, -16, -10,
- 25, 28, 29, 34, 47, 34, -7, 7, 25, -12, -43, -44, -40, -61, -85, -78,
- -55, -42, -33, -10, 17, 31, 43, 59, 51, 25, 25, 40, 27, -1, 2, 25,
- 30, 15, 12, 27, 26, 13, 16, 9, -24, -43, -37, -49, -83, -92, -62, -40,
- -42, -36, 1, 33, 34, 45, 61, 46, 27, 32, 33, 10, -6, 15, 38, 26,
- 4, 15, 35, 19, 7, 17, 3, -26, -41, -50, -67, -91, -82, -48, -40, -46,
- -24, 18, 33, 32, 54, 62, 46, 30, 22, 20, 7, 4, 28, 33, 15, 10,
- 22, 25, 9, 13, 18, -2, -29, -54, -65, -74, -86, -68, -49, -46, -32, -8,
- 17, 29, 45, 65, 60, 43, 23, 13, 17, 12, 18, 28, 22, 19, 16, 13,
- 14, 16, 24, 13, -13, -40, -66, -72, -75, -74, -64, -55, -36, -20, -9, 15,
- 43, 63, 65, 51, 37, 17, 9, 19, 23, 21, 19, 24, 21, 3, 4, 24,
- 31, 18, -2, -20, -49, -77, -74, -65, -71, -69, -47, -27, -27, -10, 38, 66,
- 59, 52, 51, 34, 4, 11, 36, 26, 12, 22, 26, 2, -11, 25, 45, 18,
- 0, -1, -23, -72, -83, -55, -65, -83, -61, -34, -37, -36, 23, 71, 55, 43,
- 60, 55, 11, 1, 40, 37, 8, 16, 31, 6, -22, 14, 55, 27, -3, 8,
- 2, -52, -83, -57, -56, -89, -79, -43, -43, -55, -4, 66, 61, 35, 56, 68,
- 31, 4, 32, 46, 13, 7, 31, 16, -24, -4, 50, 42, 2, 7, 16, -25,
- -67, -60, -54, -86, -95, -55, -44, -63, -32, 40, 62, 40, 47, 67, 48, 22,
- 32, 42, 18, 4, 25, 25, -15, -16, 29, 44, 21, 11, 15, -5, -39, -49,
- -59, -85, -96, -72, -52, -62, -50, 7, 45, 49, 50, 56, 56, 43, 42, 39,
- 19, 9, 16, 21, 1, -16, 9, 32, 31, 24, 14, 5, -14, -34, -52, -81,
- -94, -85, -71, -62, -55, -21, 21, 41, 53, 55, 55, 57, 51, 44, 26, 13,
- 15, 11, 3, -3, 0, 19, 27, 29, 26, 11, 0, -16, -41, -70, -90, -88,
- -85, -80, -57, -34, -3, 26, 42, 57, 57, 60, 64, 50, 33, 20, 17, 9,
- -6, -1, 6, 10, 23, 26, 28, 22, 10, 1, -27, -60, -78, -87, -90, -94,
- -74, -42, -20, 10, 34, 44, 57, 65, 71, 58, 35, 30, 23, 8, -5, -7,
- 4, 7, 19, 33, 23, 19, 24, 17, -13, -53, -65, -75, -96, -98, -83, -61,
- -40, -7, 32, 38, 38, 66, 83, 65, 36, 36, 37, 8, -7, 1, 0, -5,
- 11, 39, 34, 10, 21, 36, 4, -45, -59, -59, -89, -106, -84, -67, -62, -32,
- 21, 41, 30, 47, 85, 80, 41, 34, 45, 20, -8, 0, 9, -7, -6, 31,
- 45, 21, 12, 32, 25, -27, -55, -52, -76, -104, -95, -70, -64, -57, -7, 33,
- 34, 38, 67, 84, 57, 35, 46, 29, -1, -4, 7, 7, -8, 12, 41, 31,
- 21, 24, 25, -5, -43, -45, -65, -98, -98, -82, -62, -58, -35, 13, 27, 38,
- 59, 70, 67, 45, 49, 39, 2, -3, 2, 9, 9, 6, 30, 30, 24, 31,
- 20, 3, -26, -37, -48, -91, -100, -88, -75, -53, -41, -9, 12, 23, 55, 65,
- 61, 54, 51, 51, 14, -6, 1, 1, 15, 18, 26, 29, 16, 30, 28, 4,
- -14, -29, -36, -71, -100, -93, -87, -64, -38, -16, 2, 6, 33, 61, 59, 56,
- 54, 55, 32, 1, -3, -4, 5, 25, 36, 36, 17, 14, 25, 14, -4, -19,
- -30, -53, -84, -94, -95, -82, -49, -16, 4, 2, 10, 37, 56, 61, 58, 54,
- 42, 19, 3, -9, -8, 14, 41, 53, 32, 10, 7, 10, 10, -7, -25, -43,
- -65, -81, -97, -99, -72, -29, 9, 11, 3, 10, 33, 61, 65, 55, 46, 30,
- 19, 0, -17, -5, 29, 62, 57, 24, -1, -6, 10, 8, -16, -35, -54, -64,
- -80, -105, -99, -57, -2, 26, 13, -2, 6, 42, 67, 60, 49, 36, 31, 22,
- -10, -24, 1, 49, 77, 53, 9, -14, -4, 10, -4, -26, -47, -56, -58, -89,
- -115, -93, -34, 23, 33, 6, -6, 16, 50, 62, 53, 39, 34, 40, 16, -24,
- -26, 15, 71, 82, 38, -5, -13, -1, 3, -13, -39, -53, -48, -61, -103, -119,
- -80, -6, 42, 27, -1, 2, 26, 51, 56, 43, 33, 43, 42, 4, -34, -23,
- 37, 87, 70, 20, -6, -10, -3, -5, -27, -49, -48, -44, -72, -115, -118, -56,
- 22, 43, 17, 3, 12, 33, 51, 45, 34, 38, 51, 38, -11, -42, -9, 59,
- 86, 53, 13, -5, -5, -3, -19, -42, -50, -43, -45, -85, -127, -105, -28, 34,
- 37, 15, 8, 23, 41, 42, 34, 33, 45, 55, 26, -27, -38, 12, 69, 77,
- 40, 9, 1, 0, -13, -33, -48, -49, -39, -55, -102, -124, -83, -8, 37, 31,
- 14, 19, 35, 39, 34, 30, 35, 51, 50, 9, -31, -25, 27, 72, 65, 30,
- 12, 9, -2, -23, -42, -52, -46, -43, -71, -109, -112, -63, 7, 36, 25, 20,
- 33, 42, 35, 29, 29, 40, 52, 35, -2, -28, -12, 40, 69, 51, 26, 18,
- 13, -8, -33, -48, -50, -46, -57, -84, -107, -98, -43, 14, 29, 24, 30, 44,
- 43, 30, 26, 34, 44, 40, 19, -8, -20, 4, 46, 59, 42, 29, 25, 10,
- -18, -40, -46, -47, -57, -73, -91, -100, -78, -30, 13, 25, 30, 44, 48, 39,
- 29, 31, 41, 35, 23, 9, -9, -5, 16, 43, 52, 40, 37, 25, 0, -23,
- -41, -43, -54, -74, -82, -93, -86, -60, -26, 12, 26, 41, 53, 44, 40, 33,
- 36, 38, 19, 12, 2, -3, 9, 18, 40, 48, 42, 41, 16, -6, -23, -41,
- -45, -68, -84, -86, -90, -71, -52, -22, 15, 32, 52, 54, 45, 45, 36, 36,
- 25, 6, 6, 0, 5, 15, 21, 41, 46, 46, 37, 10, -7, -24, -42, -57,
- -81, -88, -88, -83, -62, -43, -14, 16, 41, 59, 55, 48, 48, 40, 27, 10,
- 2, 2, 0, 8, 22, 30, 36, 45, 50, 32, 5, -9, -23, -48, -75, -86,
- -86, -88, -81, -54, -26, -11, 16, 52, 65, 55, 50, 53, 39, 9, -2, 4,
- 2, -4, 11, 36, 34, 27, 47, 51, 26, 0, -9, -23, -63, -91, -85, -81,
- -89, -79, -38, -13, -11, 23, 62, 67, 55, 52, 56, 29, -8, -7, 7, 0,
- -5, 19, 44, 30, 28, 49, 46, 21, -2, -10, -32, -79, -96, -83, -81, -87,
- -67, -27, -11, 0, 36, 65, 67, 58, 54, 48, 14, -15, -7, 3, 1, 6,
- 26, 35, 30, 38, 46, 37, 18, -2, -18, -48, -85, -96, -89, -81, -70, -52,
- -30, -8, 20, 48, 63, 66, 59, 50, 33, 6, -14, -15, -2, 13, 20, 21,
- 25, 36, 45, 42, 31, 12, -10, -31, -56, -84, -103, -96, -70, -50, -43, -31,
- 0, 35, 58, 68, 65, 51, 37, 26, 8, -19, -25, 2, 27, 27, 17, 20,
- 36, 45, 45, 29, 0, -27, -41, -55, -87, -111, -93, -57, -37, -33, -23, 5,
- 41, 70, 77, 59, 36, 26, 24, 4, -24, -22, 7, 31, 33, 19, 14, 29,
- 49, 50, 22, -16, -39, -48, -63, -92, -104, -86, -51, -25, -19, -16, 10, 53,
- 82, 74, 47, 26, 19, 16, -1, -18, -16, 7, 35, 37, 18, 10, 31, 55,
- 41, 4, -25, -45, -57, -73, -90, -95, -82, -42, -9, -8, -11, 20, 71, 84,
- 57, 39, 27, 13, 2, -6, -9, -12, 8, 45, 41, 8, 5, 42, 56, 20,
- -10, -24, -50, -73, -83, -83, -87, -76, -25, 10, -5, -9, 39, 84, 71, 44,
- 38, 26, 2, -9, -2, -4, -11, 17, 52, 36, 0, 11, 50, 43, 3, -19,
- -31, -57, -84, -84, -77, -82, -59, -9, 14, 1, 7, 55, 81, 61, 38, 29,
- 20, -2, -10, -1, -4, 0, 26, 42, 30, 8, 20, 41, 28, -4, -31, -46,
- -64, -84, -82, -79, -66, -37, -7, 15, 18, 30, 58, 68, 57, 33, 17, 9,
- 0, -3, -7, 0, 15, 23, 31, 29, 23, 24, 22, 14, -12, -43, -63, -72,
- -73, -83, -75, -47, -26, -2, 20, 37, 48, 50, 57, 52, 30, 6, -1, 11,
- 0, -9, 7, 16, 24, 28, 32, 33, 15, 7, 2, -21, -55, -79, -66, -67,
- -81, -63, -38, -12, 9, 29, 53, 48, 42, 51, 47, 22, -6, 5, 18, -4,
- -7, 6, 22, 28, 26, 39, 28, 2, -2, -8, -35, -73, -76, -56, -67, -77,
- -55, -20, 4, 16, 40, 54, 42, 41, 51, 37, 7, 0, 17, 13, -12, -9,
- 20, 31, 25, 29, 33, 15, -5, -8, -22, -57, -74, -62, -57, -74, -71, -33,
- 0, 11, 26, 44, 45, 41, 47, 45, 22, 3, 12, 19, 0, -15, 4, 30,
- 32, 27, 26, 17, 3, -4, -14, -44, -69, -66, -56, -63, -74, -52, -11, 12,
- 21, 29, 35, 41, 49, 51, 31, 9, 11, 19, 11, -8, -7, 20, 36, 34,
- 22, 10, 6, 5, -4, -33, -64, -66, -58, -58, -67, -63, -29, 4, 20, 21,
- 21, 35, 52, 57, 39, 12, 10, 18, 16, 3, -7, 8, 31, 39, 25, 5,
- 3, 10, 5, -22, -58, -67, -58, -56, -60, -64, -45, -11, 15, 19, 12, 24,
- 50, 62, 46, 17, 9, 18, 20, 12, 0, 2, 21, 37, 31, 7, 0, 11,
- 14, -12, -51, -66, -58, -53, -54, -59, -54, -29, 3, 16, 9, 17, 44, 62,
- 51, 22, 8, 17, 24, 21, 9, 1, 11, 30, 31, 14, 3, 11, 16, -4,
- -43, -65, -58, -49, -50, -53, -55, -43, -16, 5, 10, 16, 38, 59, 54, 26,
- 7, 18, 29, 24, 18, 8, 5, 16, 27, 23, 11, 14, 18, -1, -36, -63,
- -56, -43, -48, -47, -49, -52, -36, -12, 8, 17, 35, 55, 50, 28, 9, 17,
- 33, 25, 24, 20, 5, 4, 15, 27, 23, 20, 22, 0, -32, -58, -55, -40,
- -47, -44, -39, -52, -54, -34, -2, 19, 35, 53, 46, 27, 12, 18, 34, 26,
- 26, 33, 13, -6, 0, 22, 34, 32, 28, 3, -31, -53, -51, -39, -47, -45,
- -30, -45, -66, -56, -19, 15, 38, 52, 43, 22, 13, 22, 35, 26, 26, 41,
- 25, -7, -13, 10, 35, 46, 39, 10, -29, -50, -46, -37, -47, -46, -27, -35,
- -65, -72, -42, 2, 38, 55, 43, 19, 11, 24, 36, 27, 26, 43, 37, 2,
- -19, -6, 25, 53, 56, 20, -24, -46, -43, -36, -46, -48, -29, -28, -56, -77,
- -64, -22, 31, 61, 45, 16, 10, 23, 35, 30, 26, 41, 42, 16, -14, -21,
- 7, 51, 70, 36, -15, -38, -40, -35, -42, -49, -35, -29, -44, -71, -81, -49,
- 14, 60, 50, 18, 10, 21, 34, 34, 26, 37, 43, 30, 0, -27, -13, 37,
- 74, 54, 2, -29, -35, -32, -37, -49, -42, -32, -36, -57, -85, -73, -12, 46,
- 57, 27, 9, 17, 32, 38, 28, 30, 41, 39, 18, -20, -27, 15, 62, 68,
- 26, -17, -30, -28, -29, -45, -51, -40, -34, -45, -77, -86, -42, 18, 54, 43,
- 14, 12, 29, 42, 34, 25, 33, 41, 30, -2, -24, -5, 36, 65, 50, 3,
- -24, -24, -19, -33, -54, -52, -42, -45, -61, -75, -58, -15, 32, 48, 25, 10,
- 24, 45, 45, 27, 26, 32, 28, 13, -4, -6, 14, 44, 55, 24, -11, -18,
- -12, -20, -46, -57, -53, -54, -57, -63, -57, -33, 4, 35, 32, 16, 22, 40,
- 49, 36, 26, 28, 23, 17, 8, 1, 10, 27, 43, 33, 5, -6, -8, -14,
- -33, -53, -57, -61, -62, -61, -59, -38, -10, 15, 26, 20, 26, 40, 44, 41,
- 30, 27, 25, 18, 12, 3, 9, 26, 33, 28, 13, 5, 5, -8, -25, -45,
- -57, -60, -64, -66, -65, -49, -17, 6, 13, 16, 26, 43, 47, 39, 32, 27,
- 27, 25, 13, 3, 6, 22, 35, 26, 13, 10, 12, 5, -17, -40, -54, -58,
- -58, -68, -74, -61, -31, -1, 9, 10, 23, 40, 50, 45, 31, 24, 27, 31,
- 20, 3, 2, 17, 32, 31, 16, 12, 15, 12, -4, -31, -51, -55, -54, -62,
- -76, -73, -47, -17, 2, 8, 19, 37, 51, 50, 34, 24, 26, 31, 25, 9,
- 4, 13, 26, 34, 25, 9, 13, 20, -2, -33, -44, -43, -58, -78, -77, -59,
- -44, -33, -10, 17, 6, 12, -9, 32, 13, 4, -4, 6, -9, 27, 8, 2,
- -1, -3, -2, 3, -4, -3, 2, 0, -2, 1, -2, 1, -4, 2, 1, 0,
- -2, -1, -3, 2, 0, -1, -2, -2, -2, -1, -2, -2, -1, -2, -2, -2,
- -2, -1, -2, -1, 0, -1, -2, -2, -2, -1, 0, -2, -2, -2, -2, -1,
- -1, -2, -1, -2, -2, -2, -3, -1, -1, 0, 0, -1, -3, -2, 1, 3,
- 0, 0, -2, -8, -21, -17, -2, 12, 20, 19, 6, -13, -28, -73, -67, -64,
- -58, -39, -11, 19, 38, 60, 96, 80, 38, 12, 6, -20, -65, -83, -65, -61,
- -56, -17, 22, 35, 49, 74, 94, 55, 16, 20, -5, -52, -89, -81, -53, -65,
- -36, 21, 37, 48, 51, 85, 82, 25, 23, 9, -36, -80, -105, -58, -57, -54,
- 7, 36, 54, 44, 58, 97, 48, 26, 16, -21, -61, -115, -83, -45, -57, -12,
- 23, 57, 54, 36, 86, 77, 37, 21, -16, -40, -103, -110, -54, -46, -24, 6,
- 43, 68, 36, 62, 86, 60, 30, -12, -34, -80, -119, -76, -44, -24, -5, 24,
- 64, 51, 50, 76, 72, 48, 0, -34, -68, -106, -94, -56, -26, -7, 11, 45,
- 59, 58, 66, 71, 60, 23, -27, -68, -93, -93, -72, -37, -8, 10, 25, 50,
- 70, 68, 62, 62, 45, -10, -70, -88, -83, -79, -57, -15, 15, 13, 31, 73,
- 80, 59, 53, 61, 15, -67, -89, -73, -75, -75, -33, 21, 11, 10, 66, 92,
- 65, 42, 63, 42, -56, -92, -66, -66, -84, -57, 16, 19, -5, 50, 98, 76,
- 39, 56, 60, -35, -95, -64, -53, -84, -79, 0, 28, -8, 29, 96, 89, 42,
- 46, 69, -10, -90, -69, -41, -74, -95, -25, 28, -1, 13, 81, 101, 53, 37,
- 69, 11, -77, -75, -38, -53, -103, -55, 22, 8, 6, 61, 104, 75, 29, 59,
- 31, -61, -76, -43, -36, -91, -88, 6, 17, 1, 46, 96, 94, 34, 40, 48,
- -40, -80, -47, -27, -69, -107, -27, 26, 4, 29, 87, 105, 51, 24, 46, -10,
- -76, -58, -21, -49, -107, -62, 17, 16, 17, 70, 110, 67, 22, 38, 10, -60,
- -71, -24, -28, -97, -85, -6, 25, 18, 50, 106, 84, 28, 31, 16, -38, -71,
- -38, -17, -78, -94, -30, 15, 30, 41, 86, 92, 44, 31, 15, -25, -54, -53,
- -26, -57, -88, -51, -2, 33, 45, 68, 88, 59, 35, 17, -15, -42, -55, -41,
- -48, -73, -60, -19, 24, 50, 61, 74, 67, 46, 21, -8, -32, -48, -54, -53,
- -57, -57, -34, 9, 50, 63, 59, 65, 58, 29, -1, -24, -38, -62, -67, -48,
- -47, -40, -8, 43, 68, 48, 58, 66, 38, 6, -19, -26, -62, -85, -45, -35,
- -39, -21, 28, 72, 41, 47, 74, 45, 15, -14, -17, -53, -102, -50, -24, -36,
- -26, 10, 69, 42, 32, 81, 52, 21, -4, -15, -39, -109, -64, -12, -35, -26,
- -1, 54, 47, 21, 79, 65, 20, 7, -12, -33, -100, -82, -8, -27, -32, -2,
- 36, 47, 21, 66, 77, 25, 12, -2, -36, -88, -87, -18, -16, -36, -8, 27,
- 36, 30, 56, 77, 39, 12, 6, -33, -84, -79, -30, -11, -29, -20, 19, 27,
- 31, 58, 66, 50, 21, 5, -25, -81, -75, -32, -17, -17, -27, 2, 24, 28,
- 61, 61, 48, 35, 4, -22, -71, -77, -31, -19, -12, -23, -18, 16, 29, 59,
- 65, 45, 41, 10, -23, -59, -76, -37, -14, -11, -18, -29, -2, 29, 57, 68,
- 51, 37, 16, -21, -55, -67, -44, -12, -5, -21, -29, -19, 19, 59, 68, 61,
- 36, 14, -12, -55, -61, -44, -16, 3, -21, -29, -25, 0, 55, 72, 69, 43,
- 8, -6, -49, -63, -39, -18, 5, -15, -31, -26, -18, 39, 78, 75, 53, 8,
- -8, -40, -67, -37, -15, 2, -8, -30, -26, -29, 16, 79, 84, 59, 14, -11,
- -33, -66, -42, -9, -2, -6, -23, -26, -33, -7, 66, 94, 67, 22, -9, -32,
- -62, -48, -8, 0, -9, -16, -20, -35, -24, 46, 96, 78, 31, -2, -29, -59,
- -51, -13, 1, -10, -13, -9, -31, -35, 23, 86, 88, 42, 5, -22, -57, -53,
- -18, -3, -10, -13, 0, -19, -44, 2, 69, 90, 57, 12, -13, -50, -57, -21,
- -9, -13, -13, 1, -3, -41, -17, 51, 82, 69, 23, -9, -37, -57, -25, -12,
- -22, -15, 0, 10, -25, -32, 32, 69, 71, 37, -4, -25, -48, -30, -12, -32,
- -23, -3, 14, -2, -33, 11, 56, 63, 49, 3, -18, -32, -31, -13, -37, -38,
- -9, 11, 17, -16, -6, 41, 53, 51, 11, -17, -15, -23, -14, -35, -54, -22,
- 4, 26, 10, -10, 26, 43, 46, 19, -19, -6, -5, -10, -30, -65, -42, -9,
- 24, 35, 3, 12, 32, 37, 24, -20, -8, 14, 2, -23, -68, -62, -26, 10,
- 50, 28, 11, 22, 27, 24, -19, -19, 24, 21, -8, -63, -78, -45, -11, 47,
- 53, 23, 21, 19, 22, -17, -34, 21, 40, 15, -48, -89, -65, -34, 30, 68,
- 44, 27, 16, 16, -11, -47, 3, 49, 39, -22, -89, -82, -55, 3, 68, 61,
- 44, 21, 11, -6, -53, -21, 45, 56, 11, -74, -96, -72, -26, 52, 73, 60,
- 39, 10, -3, -48, -44, 27, 61, 42, -43, -101, -88, -52, 27, 73, 70, 59,
- 21, -1, -40, -60, 2, 52, 60, -4, -90, -100, -74, -2, 62, 72, 76, 42,
- 5, -30, -66, -22, 34, 63, 33, -62, -104, -92, -31, 44, 68, 84, 66, 21,
- -21, -64, -41, 13, 54, 55, -26, -94, -104, -57, 20, 56, 82, 84, 43, -6,
- -57, -54, -10, 36, 60, 7, -70, -107, -78, -6, 40, 73, 92, 66, 12, -45,
- -57, -27, 16, 52, 29, -41, -96, -90, -32, 20, 60, 91, 83, 34, -27, -52,
- -37, -3, 34, 36, -15, -77, -91, -52, -1, 43, 83, 93, 53, -5, -42, -40,
- -17, 14, 32, 1, -54, -81, -65, -21, 23, 71, 96, 67, 16, -25, -37, -24,
- -5, 21, 6, -36, -64, -69, -37, 3, 54, 93, 73, 35, -6, -28, -25, -19,
- 8, 4, -27, -46, -65, -46, -14, 34, 86, 73, 49, 15, -17, -19, -28, -4,
- -3, -28, -32, -56, -48, -24, 15, 74, 67, 55, 36, -2, -10, -28, -14, -9,
- -36, -25, -42, -50, -29, 1, 60, 59, 50, 55, 16, -3, -22, -20, -14, -46,
- -29, -28, -48, -33, -5, 47, 50, 40, 64, 40, 4, -14, -17, -19, -53, -40,
- -18, -40, -41, -6, 39, 39, 28, 61, 62, 17, -10, -7, -21, -59, -53, -20,
- -28, -47, -11, 38, 29, 15, 52, 77, 36, -6, 1, -12, -63, -66, -25, -20,
- -46, -19, 37, 28, 0, 38, 83, 54, 5, 5, -2, -57, -81, -34, -15, -44,
- -22, 29, 31, -4, 16, 85, 68, 17, 15, 1, -44, -87, -54, -8, -42, -27,
- 25, 24, 2, 0, 69, 88, 24, 25, 11, -42, -76, -75, -14, -25, -40, 23,
- 18, -3, 3, 42, 96, 45, 22, 29, -39, -70, -75, -40, -8, -39, 7, 24,
- -17, 8, 33, 79, 76, 22, 35, -21, -75, -64, -60, -15, -17, -14, 21, -21,
- -4, 40, 59, 88, 45, 24, -3, -71, -61, -59, -38, 1, -14, 0, -17, -18,
- 41, 54, 82, 74, 22, -3, -53, -61, -53, -54, -2, 3, -19, -25, -22, 30,
- 57, 73, 92, 38, -15, -40, -51, -50, -58, -17, 17, -23, -44, -22, 19, 55,
- 72, 97, 60, -22, -40, -35, -45, -55, -32, 14, -17, -60, -26, 11, 46, 75,
- 97, 78, -17, -46, -23, -38, -45, -37, -1, -14, -66, -31, 3, 34, 80, 98,
- 85, -4, -47, -19, -33, -33, -30, -20, -25, -63, -34, -4, 18, 79, 104, 84,
- 9, -38, -18, -29, -27, -14, -30, -46, -63, -32, -5, 3, 68, 111, 84, 18,
- -23, -12, -25, -28, -2, -25, -67, -75, -29, 1, -6, 46, 112, 91, 22, -11,
- 0, -18, -33, -1, -9, -76, -96, -34, 9, -8, 22, 101, 102, 27, -2, 14,
- -7, -36, -9, 4, -68, -114, -48, 13, -3, 5, 80, 109, 40, 4, 26, 6,
- -33, -18, 6, -52, -120, -67, 7, 4, -1, 55, 103, 58, 14, 31, 17, -21,
- -24, -4, -39, -110, -84, -10, 6, 2, 34, 87, 71, 29, 36, 25, -7, -23,
- -16, -33, -96, -90, -29, -1, 6, 22, 68, 75, 45, 45, 31, 4, -15, -24,
- -37, -84, -87, -43, -15, 3, 18, 53, 68, 57, 58, 38, 11, -7, -22, -45,
- -81, -79, -48, -29, -10, 17, 45, 57, 61, 71, 50, 17, 0, -15, -49, -85,
- -74, -45, -40, -25, 10, 42, 49, 55, 82, 65, 22, 7, -9, -43, -89, -80,
- -34, -47, -40, -1, 35, 52, 43, 85, 84, 25, 17, -4, -38, -85, -92, -28,
- -44, -55, -9, 21, 53, 42, 75, 100, 35, 22, 6, -38, -74, -99, -38, -34,
- -65, -18, 12, 42, 51, 63, 102, 52, 25, 21, -36, -70, -90, -56, -30, -64,
- -30, 7, 27, 55, 63, 90, 69, 33, 26, -26, -69, -79, -66, -43, -54, -37,
- -1, 17, 49, 69, 79, 72, 50, 30, -15, -61, -75, -68, -58, -52, -33, -12,
- 9, 42, 69, 78, 64, 60, 42, -9, -49, -71, -69, -68, -61, -25, -17, -1,
- 38, 64, 77, 59, 62, 58, -3, -37, -62, -72, -72, -73, -24, -12, -11, 35,
- 55, 73, 59, 58, 69, 8, -29, -48, -75, -76, -82, -31, -4, -14, 28, 49,
- 63, 61, 54, 73, 22, -21, -36, -71, -82, -88, -42, 0, -9, 21, 43, 53,
- 57, 56, 73, 33, -12, -25, -62, -89, -95, -49, -2, -2, 18, 37, 43, 49,
- 60, 75, 38, -2, -16, -49, -89, -105, -54, -7, 1, 19, 31, 37, 38, 59,
- 81, 39, 4, -7, -35, -83, -115, -62, -10, 0, 20, 27, 32, 30, 53, 87,
- 43, 4, 0, -24, -70, -118, -75, -12, -2, 19, 24, 27, 27, 45, 89, 52,
- 4, 1, -14, -55, -113, -87, -18, -3, 13, 20, 24, 28, 41, 85, 60, 7,
- -3, -9, -40, -100, -91, -28, -4, 7, 10, 21, 30, 43, 82, 62, 13, -8,
- -11, -26, -85, -87, -36, -10, 2, -4, 14, 35, 47, 81, 62, 18, -9, -21,
- -20, -65, -78, -38, -19, -4, -16, 0, 39, 54, 85, 65, 20, -7, -31, -24,
- -47, -62, -33, -26, -15, -25, -19, 35, 63, 90, 73, 22, -3, -39, -39, -35,
- -43, -20, -26, -30, -34, -36, 24, 71, 94, 85, 29, -3, -40, -58, -34, -24,
- -4, -16, -46, -47, -47, 6, 73, 100, 97, 42, -4, -39, -73, -45, -8, 12,
- 0, -51, -64, -56, -13, 66, 104, 106, 64, 2, -40, -82, -63, -3, 27, 18,
- -43, -82, -68, -28, 51, 104, 112, 86, 19, -42, -86, -81, -10, 40, 34, -26,
- -90, -86, -41, 31, 98, 116, 104, 46, -38, -92, -95, -25, 46, 48, -6, -84,
- -105, -55, 13, 84, 117, 114, 76, -20, -95, -105, -45, 41, 54, 8, -65, -112,
- -70, -1, 65, 109, 115, 100, 14, -85, -106, -62, 21, 50, 13, -44, -104, -84,
- -14, 45, 98, 112, 111, 53, -62, -105, -75, -3, 44, 12, -31, -85, -93, -27,
- 27, 82, 110, 110, 81, -27, -95, -81, -27, 31, 11, -31, -66, -90, -39, 12,
- 61, 106, 107, 94, 12, -73, -79, -48, 11, 13, -32, -57, -78, -46, -1, 38,
- 97, 109, 96, 43, -41, -69, -62, -13, 13, -30, -58, -68, -46, -11, 17, 81,
- 112, 97, 59, -7, -51, -67, -37, 6, -23, -62, -67, -42, -14, 2, 60, 110,
- 99, 65, 20, -24, -63, -56, -7, -15, -63, -75, -40, -12, -8, 39, 102, 103,
- 67, 35, 6, -48, -68, -25, -11, -56, -85, -46, -7, -10, 22, 86, 107, 72,
- 41, 29, -25, -70, -42, -14, -42, -91, -62, -5, -6, 9, 67, 105, 84, 40,
- 40, 3, -64, -56, -23, -30, -83, -85, -12, 3, 1, 50, 97, 96, 44, 36,
- 28, -45, -69, -33, -22, -67, -101, -34, 13, 2, 31, 88, 104, 56, 28, 37,
- -16, -71, -51, -18, -49, -103, -62, 9, 14, 18, 70, 109, 68, 26, 36, 6,
- -58, -68, -23, -28, -97, -84, -7, 23, 19, 50, 106, 84, 28, 31, -21, -26,
- -18, -30, -24, -77, -76, -48, -46, 31, 0, -1, 0, 0, 2, 0, 1, -2,
- 1, 0, -6, -7, -5, -3, 0, -3, -4, -2, 2, 0, -8, -11, -14, -10,
- -8, -4, 6, 13, 14, 9, 2, -6, -10, -9, -6, 9, 17, 15, 8, 0,
- 1, -4, -12, -19, -14, -8, -4, 3, 6, -2, -4, -6, -7, -10, -8, -12,
- -11, 3, 23, 27, 11, 4, -3, -5, 0, -9, -3, 6, 11, 19, 4, -8,
- -17, -20, -21, -3, 5, 8, 2, 3, 5, 2, -3, -3, -12, 4, 1, 3,
- -7, 0, 5, 6, 0, -7, -8, -5, -7, -5, -3, 4, 9, 5, -5, -5,
- -5, -17, -7, 3, 17, 15, 7, -2, -5, -3, 3, -8, -5, -3, 3, 8,
- 12, 5, -10, -27, -20, 1, 5, -4, -9, -17, 4, 10, 9, -2, -12, -16,
- -12, -2, 8, 16, 13, 11, 16, 19, 10, -2, -16, -21, -11, 14, 15, 21,
- 11, 6, -10, -8, -11, -24, -35, -31, -13, 9, 24, 17, -2, -11, -20, -11,
- -19, -7, 3, 8, 22, 21, 21, 2, -7, -10, 12, 24, 18, -3, -19, -6,
- 0, -5, -18, -17, 6, 12, 7, -16, -20, -22, -27, -19, -14, 12, 14, 3,
- 0, 2, 8, -3, -5, -3, 21, 29, 17, 6, -8, 3, 3, 10, 10, 3,
- 12, 4, -9, -18, -20, -20, -9, 6, 3, -9, -7, -14, -9, -8, -9, -23,
- -19, 7, 17, 20, 9, 8, 5, 9, 18, 9, 8, -10, -10, -4, 9, 25,
- -6, -19, -19, -5, -4, -7, -7, -17, -15, -7, -4, 0, 2, -2, -17, -4,
- 14, 23, 15, 2, -7, -5, 9, 11, 1, 0, -3, 0, 0, 15, 14, -4,
- -15, -20, -26, -22, -13, 0, 6, 12, 5, -10, 2, 8, -2, -18, -8, 6,
- 20, 28, 23, 0, -16, -7, 9, 7, 10, -12, -21, -19, 7, 12, 4, -17,
- -28, -24, -3, 14, 4, -19, -18, -9, 11, 22, 16, -13, -23, -15, 18, 32,
- 32, 17, -4, 1, 14, 11, 1, -20, -19, -3, 9, 13, -4, -13, -16, -18,
- -23, -12, -17, -16, -20, -15, -14, -4, 8, 12, 0, 8, 5, 12, 17, 26,
- 25, 14, 10, 11, 11, 18, 15, 4, -9, -13, -8, -9, -14, -20, -28, -32,
- -12, -9, -16, -17, -24, -18, -12, 5, 10, 4, 6, 8, 18, 35, 31, 17,
- 1, 12, 21, 33, 18, 6, -10, -11, -4, -9, -13, -19, -24, -24, -24, -18,
- -20, -18, -20, -13, -15, -10, -9, -5, 8, 10, 13, 23, 26, 29, 14, 13,
- 13, 13, 16, 25, 19, 17, 4, -15, -18, -15, -14, -17, -34, -23, -16, -12,
- -16, -26, -33, -23, -15, -4, 4, 10, 16, 19, 22, 29, 28, 7, 1, 2,
- 18, 26, 30, 21, 9, 3, -4, -10, -16, -29, -31, -27, -4, -9, -11, -28,
- -23, -17, -15, -13, -11, 4, 11, 9, 13, 16, 25, 18, 8, 10, 18, 17,
- 8, 18, 17, 11, -5, -19, -17, -12, -19, -38, -27, -8, 0, -3, -14, -19,
- -20, -14, -10, -13, -3, 6, 12, 26, 38, 34, 14, 2, -2, 11, 19, 14,
- 8, 5, 16, 9, -7, -19, -24, -29, -36, -26, -13, -12, -22, -28, -20, 5,
- -3, -10, -19, 7, 20, 18, 17, 24, 25, 14, 18, 19, 29, 21, 11, 10,
- 9, 13, -13, -29, -27, -20, -24, -30, -22, -12, -7, -15, -22, -21, -13, -14,
- -20, -8, 12, 26, 25, 21, 33, 27, 25, 16, 13, 16, 16, -2, 2, 11,
- 9, -2, -17, -18, -16, -25, -25, -26, -27, -30, -35, -30, -12, -6, -6, -6,
- -5, 19, 19, 11, 15, 17, 24, 23, 34, 28, 23, 13, 2, 9, 18, 16,
- -14, -18, -12, -7, -9, -31, -37, -33, -24, -14, -24, -20, -16, -21, -15, -7,
- 5, 9, 15, 20, 28, 38, 29, 21, 15, 22, 17, 4, 12, 6, 12, -4,
- -9, -15, -16, -19, -40, -38, -34, -23, -18, -17, -8, -10, -3, -7, 1, 3,
- 4, 11, 13, 36, 41, 36, 24, 9, 17, 20, 21, 14, -5, -9, -11, -8,
- -19, -14, -24, -30, -23, -18, -25, -30, -24, -17, -20, -9, -3, 6, 8, 22,
- 23, 20, 27, 18, 10, 10, 14, 18, 14, 23, 17, 6, 5, -4, -8, -26,
- -19, -24, -25, -24, -21, -27, -28, -15, -19, -16, -9, 0, 7, 9, 17, 14,
- 15, 24, 30, 29, 29, 32, 16, 10, 8, 0, -3, -10, -7, -17, -22, -25,
- -30, -36, -32, -25, -26, -22, -12, -16, -11, -3, 5, 7, 13, 21, 21, 26,
- 32, 28, 26, 28, 31, 17, 15, 15, 5, -4, -14, -18, -28, -25, -24, -28,
- -32, -33, -32, -29, -18, -17, -20, -10, -4, 6, 6, 18, 22, 22, 37, 38,
- 31, 27, 26, 23, 22, 23, 12, 4, -5, -2, -11, -19, -25, -35, -35, -36,
- -36, -43, -32, -24, -20, -12, -7, -3, -7, 3, 13, 23, 29, 35, 37, 35,
- 42, 33, 26, 22, 17, 12, 6, 4, -9, -23, -28, -34, -34, -33, -31, -40,
- -36, -27, -25, -22, -30, -20, -11, 2, 12, 22, 22, 26, 28, 35, 47, 44,
- 27, 29, 29, 29, 19, 2, 1, -9, -15, -21, -34, -35, -34, -40, -44, -42,
- -34, -31, -26, -21, -9, -12, -3, 10, 17, 29, 26, 27, 34, 48, 50, 34,
- 33, 25, 21, 16, 8, 3, -8, -11, -25, -30, -37, -37, -42, -51, -34, -28,
- -21, -26, -25, -19, -13, 4, 9, 17, 29, 41, 33, 33, 44, 45, 32, 31,
- 28, 22, 16, 5, -10, -13, -16, -23, -38, -39, -39, -45, -54, -40, -32, -24,
- -22, -17, -14, 0, 6, 9, 18, 41, 43, 34, 32, 40, 40, 31, 30, 27,
- 22, 19, 14, -2, -16, -21, -34, -48, -45, -41, -41, -41, -45, -38, -25, -21,
- -17, -20, -7, 11, 17, 19, 36, 40, 42, 44, 47, 46, 39, 33, 26, 15,
- 11, 8, -5, -19, -24, -29, -40, -44, -48, -44, -37, -37, -43, -43, -26, -19,
- -14, -2, 13, 23, 31, 36, 36, 43, 41, 47, 46, 44, 40, 24, 15, 14,
- 3, -12, -21, -23, -30, -36, -47, -51, -50, -47, -44, -46, -31, -19, -16, -11,
- 2, 16, 20, 25, 29, 40, 53, 51, 49, 45, 41, 35, 25, 18, 7, 5,
- -12, -18, -23, -34, -39, -56, -58, -54, -49, -50, -45, -35, -26, -12, -5, 6,
- 17, 29, 41, 42, 47, 50, 46, 49, 50, 50, 39, 30, 16, 2, -8, -15,
- -21, -30, -41, -49, -50, -46, -57, -63, -57, -41, -29, -24, -12, -3, 5, 12,
- 22, 33, 41, 50, 51, 53, 57, 55, 46, 36, 29, 16, 2, -4, -11, -21,
- -33, -40, -49, -47, -53, -60, -58, -51, -42, -34, -23, -13, -2, 5, 17, 27,
- 39, 49, 48, 51, 56, 54, 58, 44, 37, 28, 18, 4, -3, -15, -29, -39,
- -49, -49, -51, -62, -65, -64, -47, -42, -36, -26, -14, -5, 10, 24, 32, 45,
- 50, 49, 62, 65, 63, 47, 42, 41, 36, 23, 7, -7, -22, -31, -41, -53,
- -58, -62, -59, -62, -56, -54, -50, -44, -32, -16, 0, 11, 25, 35, 50, 54,
- 55, 56, 66, 65, 62, 54, 45, 36, 23, 14, -4, -22, -44, -55, -52, -62,
- -61, -66, -70, -68, -60, -54, -45, -29, -15, 4, 21, 34, 36, 44, 54, 62,
- 70, 73, 68, 67, 59, 50, 37, 21, -5, -12, -25, -39, -48, -53, -63, -76,
- -73, -71, -71, -67, -57, -45, -29, -12, 2, 13, 30, 42, 51, 61, 76, 71,
- 63, 66, 71, 60, 50, 40, 23, -2, -9, -20, -41, -54, -59, -72, -79, -71,
- -64, -73, -68, -60, -51, -36, -13, 2, 13, 27, 47, 54, 71, 78, 71, 60,
- 72, 74, 65, 54, 39, 28, 7, -6, -23, -50, -59, -64, -69, -75, -70, -78,
- -74, -73, -64, -52, -37, -13, 6, 18, 40, 51, 58, 64, 78, 79, 75, 68,
- 64, 68, 57, 45, 21, 4, -16, -34, -50, -65, -75, -83, -80, -71, -69, -68,
- -73, -63, -57, -36, -16, 6, 26, 45, 60, 70, 71, 79, 79, 81, 78, 80,
- 64, 55, 36, 16, -4, -23, -38, -54, -63, -69, -81, -85, -87, -76, -72, -66,
- -61, -52, -30, -12, 12, 24, 44, 55, 69, 78, 85, 84, 74, 70, 71, 71,
- 62, 41, 17, -11, -25, -42, -55, -66, -75, -87, -87, -81, -74, -76, -76, -63,
- -48, -32, -13, 7, 30, 51, 64, 76, 80, 82, 83, 81, 80, 82, 70, 61,
- 42, 19, 0, -28, -49, -61, -72, -78, -87, -90, -89, -88, -87, -82, -69, -54,
- -33, -13, 15, 36, 58, 68, 79, 90, 96, 90, 84, 86, 89, 79, 62, 38,
- 22, -3, -29, -55, -69, -81, -89, -94, -94, -94, -94, -89, -74, -62, -52, -35,
- -18, 14, 39, 54, 65, 76, 87, 98, 95, 94, 90, 82, 75, 69, 47, 26,
- -6, -33, -57, -72, -82, -88, -97, -90, -91, -88, -83, -80, -75, -59, -33, -9,
- 20, 42, 58, 68, 82, 90, 94, 93, 94, 88, 85, 77, 65, 43, 16, -10,
- -37, -60, -71, -84, -89, -95, -97, -102, -95, -84, -80, -72, -57, -26, -4, 19,
- 42, 62, 80, 89, 94, 97, 100, 99, 90, 83, 71, 65, 39, 14, -9, -43,
- -65, -83, -90, -95, -98, -96, -100, -96, -88, -76, -66, -51, -24, -12, 21, 45,
- 70, 85, 93, 95, 97, 101, 105, 92, 84, 69, 58, 35, 16, -14, -44, -68,
- -86, -88, -96, -101, -101, -102, -97, -90, -74, -69, -50, -19, 9, 35, 56, 76,
- 84, 92, 98, 96, 99, 97, 93, 84, 77, 59, 24, 2, -30, -52, -76, -87,
- -93, -98, -100, -102, -100, -96, -89, -81, -73, -46, -18, 12, 36, 62, 82, 88,
- 96, 104, 107, 105, 102, 92, 84, 77, 53, 26, -6, -35, -57, -75, -81, -92,
- -103, -114, -111, -108, -98, -88, -83, -67, -35, -7, 20, 39, 60, 70, 89, 106,
- 116, 107, 103, 99, 86, 90, 82, 53, 18, -13, -31, -52, -73, -92, -102, -106,
- -104, -97, -106, -99, -101, -92, -72, -42, -5, 16, 38, 66, 86, 101, 99, 101,
- 95, 112, 107, 99, 95, 81, 53, 16, -3, -29, -60, -81, -102, -98, -102, -102,
- -112, -114, -101, -104, -88, -69, -34, -8, 14, 41, 67, 92, 94, 99, 103, 104,
- 115, 109, 103, 90, 78, 52, 22, 0, -39, -65, -92, -95, -91, -103, -104, -118,
- -110, -102, -93, -84, -71, -36, -15, 19, 52, 81, 94, 89, 98, 103, 115, 117,
- 102, 92, 83, 80, 49, 23, -11, -43, -67, -90, -93, -102, -105, -110, -118, -104,
- -100, -89, -83, -64, -36, -7, 28, 50, 74, 88, 95, 104, 103, 115, 107, 106,
- 97, 87, 74, 50, 20, -17, -47, -75, -89, -93, -101, -102, -115, -117, -106, -97,
- -88, -90, -73, -38, 2, 36, 60, 75, 84, 96, 104, 115, 115, 102, 98, 96,
- 96, 84, 52, 10, -12, -32, -53, -71, -87, -101, -109, -112, -109, -106, -105, -102,
- -92, -74, -48, -19, 7, 33, 56, 76, 91, 101, 108, 111, 111, 108, 103, 96,
- 85, 63, 33, 1, -27, -51, -73, -90, -102, -109, -112, -110, -107, -103, -100, -93,
- -76, -50, -19, 10, 36, 58, 76, 91, 101, 108, 111, 111, 108, 103, 96, 85,
- 63, 33, 1, -27, -51, -73, -90, -102, -109, -112, -110, -107, -103, -100, -93, -76,
- -50, -19, 10, 36, 58, 76, -1, -2, -15, 21, -17, 23, -30, 1, 34, -34,
- 6, 5, -15, 19, 1, -25, 6, 20, -2, -28, 15, 10, -15, 0, -7, 10,
- 7, -5, -9, -6, 19, -3, -21, 3, 20, -4, -20, 1, 16, -3, -8, -2,
- 5, 1, -8, -6, 3, 9, 2, -13, -4, 15, -7, -9, 0, 3, 6, -7,
- -7, 5, 8, -8, -4, 0, 1, 1, -6, -4, 7, 2, -2, -7, 0, 4,
- -3, -4, 0, 2, 0, -2, -4, 1, 4, -2, -4, -3, 1, 3, -5, -4,
- 4, 3, -6, -5, 4, -1, -2, -3, 0, 3, -3, -1, -4, 3, 3, -5,
- -3, 1, 1, -2, -3, 1, 2, -2, -4, 0, 0, 0, -1, -3, 1, 1,
- -3, -2, 1, 0, -2, -2, 0, 0, -2, -1, 0, -1, 1, -2, -2, 1,
- 0, -2, 0, -1, 0, -1, -1, -1, 0, 0, -1, -3, 1, 1, -2, -2,
- 0, 1, -1, -2, -1, 0, 0, 0, -2, -1, 1, 0, -3, 0, 2, -1,
- -2, 0, 0, 0, -2, 0, -1, 0, -1, -1, 1, 0, -1, 0, -1, 1,
- 0, -13, 5, 7, -11, 24, -50, 41, 4, -29, 14, -11, 8, 11, -15, -12,
- 15, 18, -21, -14, 22, -2, -11, -3, -3, 18, -3, -5, -14, 9, 22, -24,
- -16, 23, 12, -23, -8, 9, 10, -4, -8, -3, 11, -4, -14, 0, 8, 8,
- -5, -14, 8, 10, -12, -4, -2, 10, 0, -11, -3, 11, 0, -7, -2, -1,
- 7, -6, -8, 3, 6, 0, -3, -8, 7, 2, -7, -2, 2, 1, -2, -4,
- -1, 3, 3, -4, -5, 1, 3, -3, -6, 2, 5, -1, -7, -1, 3, -1,
- -4, -3, 5, 0, -3, -2, -1, 4, -1, -5, -1, 3, -1, -4, -1, 3,
- 1, -4, -2, 1, 0, -2, -3, 0, 2, -1, -4, 1, 1, -1, -2, -2,
- 1, -1, -3, 0, 0, 0, -1, -2, 0, 0, -2, -1, 0, -1, 0, -2,
- -1, 0, -1, 0, -1, -2, 2, -1, -2, -1, 0, 1, -2, 0, -1, -1,
- 0, -1, -2, 0, 1, -1, -3, 0, 1, -1, -3, 0, 1, -2, -1, 0,
- 0, -1, -1, 0, -1, -1, -1, -1, 0, 0, -1, -1, 0, 0, -2, 0,
- 0, 0, 0, -2, 1, -1, 0, -1, 0, 0, 0, -1, 0, 0, 0, 0,
- -1, 0, 0, -1, 0, -1, 1, 0, 0, 0, 1, -1, -1, 0, 0, 0,
- 1, -2, 4, -3, 3, -40, 71, -73, 67, -27, -68, 127, -80, 3, 5, 1,
- 17, -14, 1, -30, 53, -3, -42, 15, 19, -9, -17, -1, 13, 16, -17, 4,
- -32, 43, 15, -68, 18, 54, -38, -7, -1, 11, 7, -3, -18, 5, 25, -27,
- -9, 9, 19, -6, -12, -8, 20, -1, -15, -1, 1, 17, -10, -16, 12, 12,
- -13, 0, -6, 10, 2, -16, -1, 14, -4, 4, -11, -2, 12, -6, -8, 4,
- 4, -2, -4, 1, -2, 4, 3, -7, -5, 8, 0, -10, 1, 4, 2, -4,
- -6, 4, 1, -1, -7, 1, 8, -9, 2, -5, 3, 3, -4, -3, 0, 3,
- -3, -5, 4, 3, -3, -4, 0, 2, 0, -3, -4, 5, 0, -5, -1, 2,
- 0, -3, 0, -1, 2, -2, -4, 3, 0, -1, -2, -1, 2, -2, -2, 1,
- -1, 0, -1, -3, 1, 1, -2, 1, -3, 1, 1, -3, -1, 1, 0, -1,
- -2, 1, -1, -1, 1, -2, 1, -1, -1, -1, -1, 0, 1, -3, 0, 0,
- 1, -4, 0, 1, -2, 0, -2, 0, 0, 0, -2, 1, -1, 0, -2, 0,
- 2, -2, -1, 0, -1, 2, -2, -1, 1, -2, 0, -1, 1, -1, -1, -1,
- 1, -2, 1, -1, -1, 2, -3, 0, 0, -1, 1, -1, 0, 1, 0, -2,
- 0, -1, 1, -2, 0, 0, -1, 1, 0, -2, 0, 1, -2, 1, 0, 0,
- -1, 0, 1, -1, -1, -1, 1, 1, -1, 0, 0, 0, -1, 1, 0, -1,
- 1, 0, 0, 1, 0, -1, 1, 0, 3, -40, 58, -39, 12, 42, -117, 108,
- 1, -66, 22, 17, 0, -9, 10, -39, 42, 4, -23, -12, 28, 3, -34, 9,
- 17, 3, -9, 10, -29, 13, 53, -79, 3, 64, -26, -24, 16, -9, 14, 2,
- -8, -15, 31, -9, -30, 11, 29, -15, -7, 0, 3, 6, -4, -9, -6, 22,
- 1, -24, 9, 11, -8, 0, -2, 2, 8, -12, -6, 10, 2, 2, -9, -4,
- 11, -2, -10, 3, 2, 3, -5, -1, 1, -1, 6, -4, -8, 9, 2, -8,
- -3, 6, 3, -4, -3, -1, 6, -2, -8, 0, 9, -4, -3, -2, 2, 4,
- -4, -1, -1, 4, -2, -6, 4, 2, -1, -4, 0, 1, 2, -3, -5, 3,
- 3, -3, -4, 3, 0, -1, 0, -2, 2, 0, -3, 0, 3, 0, -3, -1,
- 2, 0, -3, 1, 0, -1, 2, -2, -2, 2, -1, 0, -1, -1, 1, -1,
- -2, 0, 0, 1, -3, 1, 0, -1, 1, -2, -1, 2, -2, -1, 0, -1,
- 2, -3, -1, 1, 1, -2, -2, 2, 1, -2, -1, 0, 0, 1, -3, 1,
- 0, 0, 0, -2, 3, 0, -2, 0, 0, 1, 0, -1, 1, -2, 0, 0,
- 0, -1, 1, 0, 0, 0, -1, 1, -1, 1, 0, -1, 1, -2, 0, 1,
- 1, 0, 1, -2, 1, 0, 1, 0, 0, 3, -1, 0, 1, 0, 0, 3,
- -29, 35, -12, -16, 56, -88, 39, 62, -79, 5, 29, 1, -13, 12, -29, 26,
- 17, -28, -3, 12, 5, -11, -19, 28, 1, -5, 9, -21, -7, 60, -56, -20,
- 57, -10, -27, 21, -21, 16, 12, -12, -21, 24, 6, -29, 4, 19, 2, -7,
- -5, -3, 7, 6, -11, -9, 11, 13, -18, -4, 13, 1, -3, -6, -1, 10,
- -8, -6, 5, 3, 5, -3, -11, 4, 9, -11, 0, 4, 3, -4, -1, 0,
- 0, 7, 0, -14, 7, 5, -7, -4, 4, 5, -1, -4, -4, 4, 1, -4,
- -4, 7, -1, -1, -3, 0, 5, -1, -4, -1, 2, 0, -3, 1, 1, 2,
- -2, -4, 1, 2, 0, -5, 2, 3, -2, -2, 1, 1, -2, 2, -3, 0,
- 0, -1, -1, 0, 1, 0, -3, 0, 0, -1, 1, -1, -2, 1, -1, 0,
- -2, 2, 1, -2, -1, 1, 0, -1, -1, 0, 1, -1, 0, -2, 1, 1,
- -1, 0, -1, -1, 0, 0, -1, -1, 0, -1, -1, 2, -2, -1, 1, 0,
- 0, -1, -1, 1, 0, -1, 1, -1, 0, 1, -3, 1, 1, -1, -1, 0,
- 1, 0, 0, 0, -1, 0, 0, -1, 0, 1, 0, 0, 2, -2, 0, 1,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, -1, -1, -7, -9, 35, -52,
- 59, -33, -32, 64, -15, -41, 19, 22, -20, 9, -11, -3, 33, -27, 2, 7,
- -9, 19, -37, 24, 7, -11, 11, -1, -30, 37, 8, -57, 36, 19, -33, 14,
- 0, -17, 26, 1, -20, -5, 26, -18, -13, 14, 7, -6, 4, -9, -4, 11,
- 3, -14, -7, 20, 0, -18, 10, 1, 4, -5, -7, 6, 0, -3, -2, -2,
- 8, 5, -11, -6, 10, -1, -10, 6, -2, -1, 1, -3, 0, 3, 5, -9,
- -5, 9, -3, -4, 1, 1, 3, -1, -4, -1, 2, -2, -5, 5, -3, 0,
- 1, -5, 4, 2, -3, -3, 0, 0, -2, 1, 0, -2, 3, -2, -5, 2,
- 2, -2, -4, 3, 0, -2, 1, -2, -2, 5, -2, -6, 1, 2, -1, -1,
- 0, 1, -1, -2, -1, -1, 2, 0, -4, 0, 1, 0, -3, 0, 2, 0,
- -3, 0, 0, 1, -1, -1, 1, 0, -1, -2, 1, 0, 0, -1, 0, -2,
- 1, 0, -1, 1, -1, 0, -2, 1, 1, -2, -1, 2, -2, 1, -3, 1,
- 1, -1, 0, 0, -1, 1, 0, -2, 2, -1, -1, 0, 0, 1, 0, 1,
- 0, -2, 1, 0, 0, -1, 1, 0, 0, 0, 0, -3, -20, 45, -56, 40,
- -5, -34, 27, 24, -42, -1, 29, -14, -4, 2, -7, 24, -20, -1, 18, -25,
- 25, -29, 9, 21, -26, 14, 4, -20, 7, 27, -42, 5, 31, -24, -2, 19,
- -30, 21, 8, -11, -17, 20, 1, -22, 11, 7, -7, 6, -5, -7, 3, 11,
- -6, -18, 11, 16, -20, 1, 5, 2, -3, -3, 0, -3, 4, -1, -7, 2,
- 10, -9, -8, 7, 2, -9, 5, -1, -5, 2, 1, -3, -2, 9, -5, -8,
- 4, 1, -5, 0, 1, 2, -1, 0, -5, 4, -1, -5, 4, -3, 1, 1,
- -5, 3, 0, 0, -3, 0, -1, -2, 1, 2, -5, 2, 1, -5, -2, 3,
- -1, -5, 2, 1, -4, 2, -1, -4, 2, 3, -7, -1, 2, 0, -2, 1,
- 0, -2, -1, 0, -3, 1, 2, -3, -2, 3, 0, -3, -1, 1, 0, -1,
- -2, -1, 1, 0, 0, -1, 0, 0, -2, 0, 0, 1, -2, 2, -3, 1,
- 0, 0, -2, 1, 0, -1, 0, 0, -1, -1, 2, -3, 0, 0, -1, 0,
- 0, -1, 1, 0, -4, -13, 32, -41, 31, -10, -10, 4, 22, -25, -8, 21,
- -3, -14, 5, 1, 12, -23, 8, 18, -31, 25, -26, 10, 17, -23, 8, 5,
- -9, 0, 16, -25, 2, 23, -22, -2, 22, -30, 15, 7, -6, -13, 12, 1,
- -17, 9, 5, -6, 4, -3, -7, 5, 7, -6, -13, 7, 10, -11, 0, 0,
- 4, -3, -3, 2, -7, 4, 2, -5, 0, 6, -3, -8, 4, 2, -8, 7,
- 0, -8, -1, 6, 0, -8, 6, 0, -5, 1, 0, -5, 3, 2, -3, -2,
- 4, -5, -1, -1, -2, 3, -4, 1, -1, -3, 3, -1, -2, -2, 1, -2,
- -2, 1, 1, -4, 1, 2, -5, -3, 5, -3, -4, 4, -1, -4, 2, -1,
- -4, 3, 1, -5, -2, 2, 0, -2, 2, -1, -4, 3, -1, -3, 0, 1,
- -2, -2, 1, -1, -1, -1, 0, 0, -1, -1, -1, 0, -1, 1, -1, -1,
- 0, -2, 1, 0, -1, -1, 0, -1, -1, -1, 2, -2, -1, 1, -1, -2,
- 1, -1, -1, 1, -2, 1, -7, -3, 15, -23, 20, -16, 9, -12, 16, -12,
- -8, 11, 5, -18, 6, 8, 0, -18, 16, 4, -19, 16, -17, 10, 5, -8,
- -2, 9, -5, -4, 10, -17, 5, 13, -18, 2, 12, -17, 10, 0, -2, -8,
- 7, -4, -7, 6, 1, -3, 1, 3, -9, -2, 10, -7, -8, 4, 6, -6,
- 1, 0, 0, -2, 1, -1, -8, 6, 1, -5, 2, 4, -2, -4, 1, 1,
- -7, 5, -1, -4, -2, 4, 0, -4, 4, -3, -4, 1, 0, -3, 0, 2,
- -1, -2, 2, -2, -1, -3, 0, 3, -4, 3, -3, 0, 2, 0, -3, -1,
- 1, -3, -1, 2, 0, -1, 0, 0, -3, 0, 1, -4, -1, 2, 0, -2,
- 0, 1, -3, 1, 1, -3, -2, 2, -1, -1, 2, -1, -2, 1, 0, -1,
- -1, -1, -3, -8, -16, -20, -7, 14, 20, 19, 18, 16, 11, 3, -9, -21,
- -36, -43, -39, -24, 6, 38, 57, 55, 26, 0, -7, -10, -13, -12, -11, -29,
- -56, -59, -37, 0, 43, 74, 87, 75, 37, -2, -31, -51, -59, -45, -15, -16,
- -34, -20, -10, -5, 29, 61, 72, 51, 18, -2, -21, -39, -35, -24, 1, 0,
- -31, -29, -23, -44, -13, 48, 82, 79, 46, 16, -4, -44, -58, -26, 3, 6,
- -38, -52, -24, -42, -35, 47, 95, 88, 55, 19, 12, -22, -72, -38, 4, 3,
- -31, -67, -29, -24, -60, 23, 112, 111, 72, 22, 7, -20, -90, -73, -1, 19,
- -4, -57, -36, 3, -54, -32, 98, 125, 71, 14, 14, 0, -82, -106, 0, 42,
- 10, -48, -32, -2, -54, -63, 72, 125, 82, 24, 14, -8, -57, -104, -22, 52,
- 34, -34, -46, -16, -35, -83, 32, 127, 99, 26, 19, 4, -55, -110, -48, 45,
- 36, -12, -26, -22, -41, -64, -7, 107, 113, 56, 6, 4, -41, -92, -74, 35,
- 57, 12, -41, -21, -39, -67, -40, 86, 114, 71, 10, 22, -31, -83, -83, 16,
- 46, 34, -28, -18, -42, -58, -60, 55, 108, 97, 3, 21, -8, -77, -102, 10,
- 45, 42, -26, -2, -27, -68, -73, 45, 83, 92, 29, 25, -8, -56, -104, -13,
- 35, 52, -6, -7, -22, -46, -91, 10, 80, 95, 35, 26, 8, -38, -106, -34,
- 34, 42, 5, 1, -23, -39, -73, -28, 61, 89, 60, 20, 2, -7, -73, -86,
- 24, 52, 26, -12, -11, -19, -58, -86, 46, 91, 62, 17, 22, -15, -39, -106,
- 8, 55, 45, -13, -6, -30, -21, -102, 4, 82, 87, 7, 28, -3, -9, -115,
- -32, 50, 63, -23, 8, -19, -18, -94, -28, 61, 96, 14, 39, -4, 1, -85,
- -60, 23, 79, -3, 2, -20, -10, -82, -65, 25, 108, 28, 31, 19, 9, -65,
- -74, -5, 78, 16, -3, -9, -14, -65, -76, -3, 93, 60, 29, 22, 13, -43,
- -90, -30, 61, 49, -9, -1, 4, -52, -98, -16, 68, 72, 21, 38, 15, -31,
- -94, -34, 32, 67, 5, 9, 0, -28, -111, -33, 40, 85, 24, 37, 23, -6,
- -104, -44, 13, 69, 9, 14, 8, -11, -110, -53, 20, 80, 32, 48, 30, 5,
- -87, -66, -7, 63, 33, 12, 2, 5, -86, -94, -2, 79, 46, 26, 44, 22,
- -59, -88, -19, 54, 48, 13, 14, 4, -51, -112, -37, 67, 71, 21, 38, 29,
- -29, -104, -50, 44, 63, 11, 10, 14, -24, -103, -67, 49, 88, 20, 27, 43,
- -10, -90, -79, 24, 69, 21, 7, 18, -8, -82, -103, 17, 94, 38, 10, 54,
- 12, -70, -97, 1, 68, 37, -4, 27, -6, -56, -104, -21, 82, 67, -3, 46,
- 23, -37, -108, -31, 57, 58, -13, 29, 11, -32, -106, -50, 53, 92, -6, 38,
- 38, -15, -105, -54, 34, 79, -12, 20, 22, -11, -98, -70, 22, 99, 4, 16,
- 48, 14, -99, -75, 15, 82, 2, 0, 44, 8, -93, -80, 0, 84, 29, -3,
- 57, 32, -79, -94, 1, 66, 27, -19, 49, 29, -73, -109, -7, 54, 52, -17,
- 62, 53, -46, -113, -4, 43, 51, -30, 46, 37, -42, -128, -23, 26, 69, -18,
- 51, 59, -2, -122, -30, 24, 66, -27, 31, 51, 1, -128, -48, 13, 71, -11,
- 33, 66, 22, -110, -57, 8, 68, -9, 12, 53, 28, -104, -87, -4, 67, 8,
- 8, 72, 53, -80, -91, -4, 59, 10, -13, 63, 44, -81, -109, -19, 46, 33,
- -6, 76, 57, -43, -104, -24, 36, 42, -26, 55, 51, -34, -126, -39, 19, 58,
- -21, 68, 71, -8, -114, -32, 2, 62, -24, 52, 54, -4, -120, -53, -22, 71,
- -8, 49, 62, 31, -102, -52, -25, 70, -5, 24, 55, 35, -109, -69, -40, 59,
- 16, 25, 65, 55, -80, -70, -37, 47, 23, 7, 48, 51, -73, -97, -48, 30,
- 46, 6, 57, 74, -37, -98, -34, 21, 48, -10, 44, 58, -34, -123, -46, -2,
- 61, 2, 50, 69, 10, -110, -40, -5, 59, -9, 31, 53, 19, -126, -59, -20,
- 62, 8, 32, 64, 49, -105, -59, -16, 58, 2, 17, 50, 45, -102, -83, -31,
- 46, 24, 15, 53, 69, -65, -86, -24, 42, 25, -4, 45, 64, -58, -112, -37,
- 30, 41, -6, 51, 75, -24, -105, -32, 26, 41, -19, 39, 62, -14, -117, -51,
- 7, 54, -13, 35, 78, 19, -105, -47, 9, 58, -19, 21, 69, 18, -113, -66,
- -10, 52, -10, 14, 75, 42, -83, -60, -5, 52, 0, -3, 69, 43, -83, -83,
- -21, 35, 17, -13, 72, 57, -54, -82, -10, 29, 28, -29, 65, 52, -45, -98,
- -21, 1, 40, -30, 64, 63, -7, -94, -9, 1, 51, -36, 51, 54, -8, -115,
- -23, -22, 47, -30, 48, 65, 24, -90, -13, -15, 46, -26, 30, 55, 21, -100,
- -37, -26, 31, -10, 24, 65, 41, -71, -35, -10, 25, -2, 4, 58, 32, -69,
- -61, -16, 2, 8, 1, 67, 42, -33, -56, -1, -1, 20, -13, 59, 33, -28,
- -82, -10, -20, 22, -15, 64, 40, -1, -70, 0, -17, 29, -22, 53, 33, 1,
- -84, -15, -29, 22, -19, 53, 43, 22, -64, -7, -19, 25, -18, 37, 38, 16,
- -73, -30, -33, 11, -14, 32, 50, 31, -45, -17, -15, 16, -4, 16, 43, 23,
- -49, -43, -30, -2, -1, 8, 52, 36, -25, -32, -13, -1, 11, -1, 42, 30,
- -25, -49, -25, -18, 10, -7, 44, 40, -2, -34, -11, -15, 21, -6, 29, 33,
- -5, -54, -29, -30, 13, -6, 29, 46, 15, -32, -10, -18, 16, -1, 13, 36,
- 9, -45, -30, -32, 0, 1, 12, 43, 28, -23, -16, -16, 6, 9, 2, 33,
- 22, -33, -34, -27, -11, 2, 1, 35, 36, -14, -16, -11, -5, 8, 3, 24,
- 32, -19, -30, -29, -17, -4, 1, 20, 43, -5, -14, -13, -4, 0, 7, 11,
- 39, -9, -23, -28, -17, -16, 1, 9, 44, 3, -7, -15, -4, -4, 7, 5,
- 38, 3, -20, -30, -19, -19, -8, 0, 40, 17, -6, -7, -3, -2, -1, 4,
- 32, 16, -20, -21, -26, -17, -18, -3, 28, 32, -7, -1, -9, 4, -9, 3,
- 22, 34, -19, -14, -27, -13, -27, -10, 16, 44, -8, 5, -6, 3, -12, 1,
- 13, 40, -12, -11, -25, -17, -27, -15, 5, 45, 4, 2, 0, 0, -9, -5,
- 6, 38, 2, -17, -14, -20, -24, -23, 0, 38, 19, -4, 11, -4, -7, -10,
- 4, 27, 20, -20, -9, -23, -22, -30, -6, 26, 35, -8, 12, 2, -4, -15,
- 2, 20, 32, -16, -7, -15, -22, -37, -14, 18, 39, -3, 5, 8, -5, -18,
- -2, 18, 34, -4, -14, -4, -21, -35, -25, 15, 36, 8, -4, 21, -5, -17,
- -14, 23, 26, 9, -22, 4, -25, -32, -40, 14, 27, 24, -12, 30, 1, -8,
- -26, 24, 21, 19, -28, 9, -20, -28, -51, 7, 23, 30, -15, 27, 9, -7,
- -32, 16, 25, 23, -21, 4, -8, -27, -50, -10, 25, 29, -9, 13, 24, -7,
- -28, -3, 34, 20, -12, -9, 10, -31, -43, -29, 30, 23, 2, -3, 38, -9,
- -19, -19, 39, 18, -1, -20, 25, -29, -36, -42, 26, 17, 12, -14, 43, -3,
- -15, -29, 35, 19, 6, -28, 27, -18, -36, -48, 16, 17, 15, -15, 39, 12,
- -13, -29, 24, 24, 9, -25, 19, -1, -39, -50, 1, 18, 11, -11, 25, 26,
- -14, -26, 12, 32, 10, -17, 6, 17, -33, -48, -14, 20, 6, -7, 11, 36,
- -9, -26, -1, 34, 11, -9, -4, 25, -25, -49, -26, 19, 4, -4, 5, 41,
- 3, -21, -8, 31, 12, -7, -11, 23, -13, -47, -37, 13, 6, -3, 1, 40,
- 14, -17, -14, 26, 16, -2, -12, 20, -3, -40, -44, 2, 6, -2, -4, 35,
- 24, -9, -19, 19, 17, 2, -13, 16, 5, -29, -48, -7, 4, 3, -7, 28,
- 28, 2, -21, 13, 14, 9, -14, 11, 9, -15, -49, -17, -3, 6, -11, 20,
- 30, 14, -23, 7, 12, 14, -11, 6, 10, -4, -46, -24, -10, 6, -8, 11,
- 29, 24, -15, 0, 11, 14, -4, -2, 11, 3, -37, -36, -13, -3, -2, 2,
- 28, 27, -2, -10, 14, 9, 7, -8, 13, 3, -21, -42, -14, -14, 4, -6,
- 24, 24, 13, -16, 12, 3, 14, -8, 12, 4, -7, -44, -18, -20, 5, -6,
- 18, 22, 23, -13, 6, 2, 13, -4, 5, 5, 1, -36, -26, -20, -1, -1,
- 10, 23, 25, -3, -4, 5, 9, 5, -2, 8, 1, -24, -36, -18, -10, 4,
- 1, 24, 23, 11, -9, 8, 4, 12, -7, 9, 1, -12, -40, -19, -16, 4,
- -4, 21, 21, 16, -9, 6, 2, 13, -4, 6, 6, -4, -33, -24, -18, -2,
- -2, 10, 21, 18, 0, -3, 3, 8, 6, -1, 8, 0, -18, -31, -19, -10,
- 1, 0, 19, 20, 13, -5, 4, 5, 12, -4, 5, 2, -7, -34, -24, -17,
- 1, -4, 13, 20, 21, -3, 2, 5, 14, 0, 2, 4, 0, -26, -28, -20,
- -6, -4, 4, 18, 23, 6, -3, 5, 9, 7, -1, 6, 3, -14, -33, -22,
- -14, -1, -1, 16, 22, 17, -4, 4, 4, 10, -2, 4, 3, -4, -30, -25,
- -19, -2, -2, 11, 20, 23, 0, 0, 2, 10, 3, 1, 4, 1, -23, -30,
- -22, -8, -1, 4, 19, 23, 10, -3, 4, 6, 8, -2, 5, 2, -13, -33,
- -23, -15, 0, -1, 16, 21, 16, -3, 3, 4, 11, 0, 5, 6, -3, -27,
- -25, -19, -4, -2, 9, 19, 19, 2, -3, 2, 8, 6, -1, 8, 0, 0,
- 2, 33, 42, 58, 71, 79, 85, 88, 91, 94, 79, 95, 82, 106, 86, 105,
- 47, 16, -6, 13, 44, 31, -15, -38, -36, 20, 70, 41, 48, 58, 24, -57,
- -127, -119, -102, -126, -128, -111, -78, -82, -88, -87, -60, -66, -98, -104, -99, -97,
- -99, -104, -101, -88, -87, -91, -61, -27, -34, -54, -55, -45, -24, -10, -5, -4,
- 5, 34, 63, 101, 94, 78, 52, 51, 52, 74, 81, 77, 59, 46, 17, 7,
- 39, 53, 47, 42, 66, 83, 73, 52, 28, 22, 11, 8, 11, 0, -15, -23,
- -15, -14, -6, 16, 46, 62, 71, 76, 90, 102, 103, 103, 101, 100, 90, 75,
- 63, 67, 49, 37, 28, 12, 5, 6, 15, 15, 8, -7, -12, -4, -10, -28,
- -24, -17, -25, -50, -64, -81, -103, -116, -116, -113, -95, -72, -54, -41, -47, -65,
- -65, -50, -33, -24, -7, 11, 8, -4, -13, -28, -51, -75, -90, -91, -90, -90,
- -87, -88, -83, -84, -82, -81, -81, -76, -65, -71, -85, -84, -79, -83, -81, -77,
- -72, -70, -65, -66, -66, -65, -66, -68, -61, -56, -51, -36, -13, -3, -5, -8,
- -12, -12, 3, 16, 21, 31, 50, 69, 77, 82, 90, 102, 110, 114, 116, 117,
- 118, 119, 116, 112, 109, 105, 98, 99, 103, 102, 91, 73, 64, 63, 61, 57,
- 51, 40, 24, 35, 57, 75, 84, 79, 65, 37, 4, -26, -45, -57, -54, -46,
- -45, -54, -67, -67, -48, -16, 15, 35, 44, 45, 44, 45, 46, 38, 23, 2,
- -15, -34, -52, -60, -70, -77, -80, -79, -74, -77, -84, -86, -80, -72, -68, -72,
- -80, -87, -92, -96, -101, -104, -104, -101, -93, -90, -89, -86, -85, -84, -83, -82,
- -81, -79, -77, -76, -73, -71, -66, -62, -55, -39, -31, -27, -25, -31, -37, -46,
- -51, -53, -54, -48, -45, -38, -20, 3, 24, 35, 39, 32, 16, 5, 3, 0,
- -6, -13, -13, -11, -2, 14, 28, 40, 50, 53, 50, 55, 64, 74, 90, 105,
- 108, 112, 106, 104, 109, 112, 123, 127, 127, 127, 127, 127, 127, 118, 113, 107,
- 110, 114, 111, 104, 101, 101, 102, 103, 99, 99, 89, 73, 53, 35, 20, 0,
- -22, -43, -63, -77, -82, -76, -65, -48, -36, -29, -24, -25, -29, -37, -40, -49,
- -59, -67, -73, -76, -78, -79, -75, -73, -74, -75, -68, -52, -44, -30, -19, -9,
- -6, -9, -13, -24, -33, -35, -31, -30, -35, -40, -44, -45, -51, -53, -54, -50,
- -50, -47, -42, -50, -55, -54, -56, -56, -54, -54, -49, -48, -41, -32, -28, -18,
- -13, -5, 6, 18, 33, 49, 60, 71, 78, 88, 95, 97, 93, 88, 91, 93,
- 97, 98, 97, 94, 91, 85, 81, 72, 70, 66, 61, 60, 64, 66, 74, 83,
- 92, 102, 108, 109, 107, 102, 97, 95, 91, 87, 80, 74, 67, 62, 61, 58,
- 61, 61, 57, 53, 43, 35, 27, 25, 24, 20, 20, 22, 27, 34, 36, 32,
- 21, 8, -3, -10, -16, -18, -16, -16, -19, -15, -11, -11, -12, -20, -34, -45,
- -59, -72, -80, -89, -94, -95, -102, -111, -114, -111, -111, -108, -106, -104, -101, -98,
- -93, -90, -86, -86, -83, -82, -81, -79, -76, -73, -70, -72, -78, -81, -79, -79,
- -72, -60, -43, -31, -25, -27, -34, -37, -40, -42, -41, -39, -36, -34, -25, -12,
- -4, 5, 12, 16, 17, 15, 13, 6, -4, -7, -8, -6, -1, 4, 7, 9,
- 12, 16, 19, 19, 22, 28, 29, 28, 29, 30, 34, 40, 49, 57, 71, 78,
- 85, 92, 96, 95, 89, 85, 86, 93, 99, 104, 102, 100, 94, 85, 77, 73,
- 69, 66, 63, 60, 60, 59, 57, 52, 47, 41, 31, 18, 6, -3, -7, -11,
- -12, -14, -18, -22, -23, -22, -24, -30, -37, -41, -44, -50, -56, -64, -67, -65,
- -62, -58, -58, -58, -59, -61, -62, -66, -72, -78, -79, -77, -73, -68, -64, -61,
- -56, -53, -54, -52, -52, -57, -63, -69, -70, -68, -65, -62, -59, -57, -56, -58,
- -60, -61, -63, -64, -62, -61, -60, -58, -54, -49, -45, -42, -39, -36, -32, -28,
- -22, -13, -7, -3, 2, 13, 28, 41, 52, 64, 71, 73, 73, 70, 64, 61,
- 60, 64, 66, 65, 66, 64, 61, 60, 62, 65, 64, 66, 67, 67, 68, 66,
- 64, 66, 68, 73, 76, 74, 72, 66, 58, 52, 46, 42, 38, 38, 41, 47,
- 52, 52, 48, 45, 42, 40, 38, 34, 29, 27, 26, 28, 29, 28, 29, 30,
- 31, 28, 24, 21, 19, 17, 14, 10, 6, 3, -4, -9, -15, -19, -26, -33,
- -40, -49, -55, -60, -65, -70, -73, -72, -72, -71, -70, -71, -75, -78, -81, -83,
- -86, -86, -85, -84, -82, -80, -77, -72, -69, -66, -63, -61, -61, -61, -61, -61,
- -60, -58, -53, -48, -42, -36, -30, -28, -30, -32, -33, -32, -31, -28, -22, -18,
- -10, -5, 0, 3, 6, 11, 16, 19, 22, 24, 26, 27, 29, 34, 40, 46,
- 48, 48, 48, 45, 40, 36, 33, 31, 33, 35, 40, 48, 55, 62, 68, 73,
- 76, 78, 78, 77, 79, 82, 85, 87, 87, 87, 86, 86, 86, 83, 78, 71,
- 63, 55, 48, 44, 39, 36, 36, 36, 35, 32, 28, 24, 18, 13, 9, 6,
- 4, 1, -2, -5, -11, -17, -20, -21, -20, -21, -24, -28, -32, -34, -33, -33,
- -35, -37, -40, -43, -47, -52, -58, -63, -69, -74, -77, -80, -81, -82, -81, -80,
- -77, -74, -69, -62, -54, -48, -48, -51, -54, -57, -57, -57, -56, -55, -55, -56,
- -57, -56, -55, -54, -54, -54, -54, -52, -49, -45, -41, -38, -34, -31, -29, -27,
- -24, -20, -17, -11, -7, -3, 0, 5, 10, 16, 22, 27, 31, 34, 38, 42,
- 44, 45, 48, 50, 52, 57, 61, 64, 64, 65, 65, 63, 60, 57, 55, 55,
- 58, 61, 63, 65, 67, 69, 71, 74, 77, 79, 79, 77, 74, 71, 68, 66,
- 63, 60, 57, 55, 51, 46, 40, 36, 30, 25, 20, 17, 16, 17, 16, 14,
- 12, 10, 7, 3, -1, -5, -11, -15, -17, -18, -18, -19, -21, -25, -29, -32,
- -33, -33, -36, -39, -43, -46, -50, -53, -56, -58, -59, -60, -61, -62, -63, -65,
- -66, -67, -68, -70, -72, -72, -70, -67, -63, -61, -60, -60, -58, -56, -54, -53,
- -52, -52, -52, -51, -50, -49, -47, -45, -43, -40, -37, -35, -34, -32, -29, -25,
- -21, -18, -14, -9, -4, 0, 4, 7, 11, 15, 18, 21, 25, 28, 33, 37,
- 41, 44, 46, 47, 47, 46, 46, 45, 43, 42, 42, 43, 46, 48, 49, 50,
- 52, 55, 59, 62, 65, 66, 67, 68, 69, 69, 70, 72, 74, 74, 73, 72,
- 71, 69, 65, 61, 57, 53, 50, 46, 43, 38, 35, 32, 28, 23, 19, 17,
- 17, 15, 13, 11, 9, 5, 1, -3, -6, -9, -12, -14, -17, -19, -23, -27,
- -31, -35, -38, -40, -43, -46, -48, -52, -55, -57, -61, -64, -66, -67, -68, -69,
- -70, -70, -70, -69, -69, -70, -71, -70, -66, -62, -59, -55, -52, -50, -46, -43,
- -41, -38, -36, -35, -35, -34, -33, -33, -33, -33, -31, -30, -28, -26, -25, -24,
- -21, -20, -20, -19, -19, -18, -17, -16, -15, -13, -11, -8, -3, 2, 9, 15,
- 21, 27, 33, 38, 41, 45, 48, 51, 53, 55, 56, 56, 56, 56, 56, 56,
- 56, 55, 57, 58, 60, 61, 62, 62, 64, 66, 68, 69, 71, 72, 73, 74,
- 72, 70, 67, 63, 60, 57, 54, 50, 46, 41, 36, 31, 27, 23, 19, 16,
- 14, 12, 11, 9, 8, 5, 2, -1, -4, -8, -10, -15, -18, -19, -20, -22,
- -22, -23, -23, -24, -26, -29, -31, -33, -35, -36, -37, -38, -41, -44, -46, -48,
- -50, -52, -54, -56, -59, -61, -63, -63, -64, -65, -64, -63, -62, -61, -60, -59,
- -58, -57, -58, -57, -57, -55, -53, -50, -49, -47, -46, -43, -40, -37, -33, -31,
- -28, -26, -23, -20, -16, -14, -12, -9, -5, -2, 1, 5, 9, 13, 17, 21,
- 24, 26, 29, 32, 35, 37, 37, 38, 39, 41, 43, 44, 45, 46, 48, 50,
- 51, 53, 52, 52, 50, 48, 47, 46, 46, 46, 46, 47, 48, 49, 51, 54,
- 56, 58, 60, 61, 62, 62, 62, 61, 59, 57, 55, 54, 53, 52, 51, 49,
- 46, 41, 36, 31, 27, 22, 18, 14, 11, 9, 6, 3, 0, -2, -5, -8,
- -11, -16, -20, -25, -28, -31, -34, -37, -39, -41, -41, -42, -42, -42, -43, -45,
- -46, -47, -49, -50, -52, -54, -56, -57, -58, -60, -61, -63, -64, -64, -64, -63,
- -63, -61, -59, -58, -57, -55, -54, -53, -52, -52, -51, -50, -49, -47, -46, -45,
- -44, -42, -40, -38, -35, -32, -30, -28, -25, -22, -19, -17, -15, -12, -9, -5,
- -1, 3, 7, 11, 15, 19, 23, 25, 27, 30, 34, 36, 37, 38, 39, 40,
- 42, 44, 45, 46, 47, 49, 50, 52, 53, 52, 51, 49, 47, 47, 46, 46,
- 46, 47, 47, 48, 50, 52, 55, 57, 59, 61, 62, 62, 62, 61, 60, 58,
- 56, 54, 54, 53, 51, 50, 47, 44, 39, 34, 29, 25, 20, 16, 13, 10,
- 7, 4, 2, -1, -3, -6, -9, -14, -18, -22, -26, -30, -33, -35, -38, -40,
- -41, -41, -42, -42, -43, -44, -46, -47, -48, -49, -51, -53, -55, -56, -57, -59,
- -60, -62, -63, -64, -64, -63, -63, -62, -60, -59, -57, -56, -55, -53, -52, -52,
- -51, -51, -50, -48, -46, -45, -44, -43, -41, -39, -36, -34, -31, -29, -26, -24,
- -21, -16, -1, -2, -1, -3, 1, -2, -2, -4, 2, 6, 2, -2, -2, 0,
- 7, 8, 4, -2, -2, 6, 5, 6, 0, -2, 5, 12, 10, 0, -5, -3,
- 5, 10, 9, -7, -8, -7, 5, 8, 3, -9, -13, -5, 3, 5, -5, -9,
- -4, 0, 6, 0, -4, -11, -7, 3, 4, 0, -5, 0, -1, 5, 1, 4,
- -6, -5, -3, 12, 9, -2, -10, 4, 11, 8, -4, -5, -9, -6, 1, 19,
- 13, -2, -22, 4, 9, 6, -26, -4, 3, 12, -9, 0, 2, 0, -15, 4,
- 8, -8, -20, 0, 15, 8, -13, -2, -4, -4, -2, 12, 3, -14, -18, 1,
- 21, 13, -9, -25, -8, 17, 15, 5, -14, -17, 5, 19, 13, -15, -17, -3,
- 10, 20, 10, -27, -19, 5, 11, 12, 3, -13, -17, -1, 6, -3, -2, 1,
- -1, -11, -17, 7, 7, -7, -7, -13, 9, 0, -5, 9, -5, -9, 6, 5,
- -2, -16, -5, 15, 17, -10, -20, 1, 11, 14, -1, 1, 10, -11, -8, -1,
- 18, 13, -2, -12, 1, -16, -2, 34, 27, -28, -42, -3, 42, 26, -14, -39,
- -19, 7, 26, 25, -16, -55, -26, 32, 57, 4, -69, -48, 6, 75, 29, -51,
- -67, -32, 51, 56, 7, -57, -75, 14, 63, 43, -29, -82, -27, 31, 56, 28,
- -43, -81, -31, 59, 85, 1, -100, -59, 8, 102, 41, -42, -92, -52, 72, 79,
- 29, -103, -85, -1, 117, 49, -54, -113, 7, 24, 94, -28, -39, -84, 39, 28,
- 61, -44, -28, -67, 61, 23, 35, -40, -23, -37, 6, 38, 69, -42, -61, -53,
- 58, 86, 2, -93, -24, 19, 72, 17, -19, -87, 45, 10, 64, -13, -45, -57,
- 38, 48, 36, -51, -35, -37, 46, 26, 37, -73, -28, -12, 44, 22, 27, -84,
- -22, 6, 70, 17, -24, -82, -7, 26, 79, 9, -63, -78, 6, 90, 68, -55,
- -118, -3, 92, 62, -10, -73, -50, 14, 110, 15, -5, -118, 5, 69, 53, 22,
- -81, -45, 29, 47, 80, -69, -28, -52, 58, 66, -1, -25, -59, -22, 107, 2,
- 43, -108, -13, 20, 59, 56, -58, -66, -7, 34, 114, -42, -63, -50, 42, 69,
- 44, -63, -37, -50, 114, 27, 18, -49, -81, 20, 74, 51, -14, -102, -4, 40,
- 70, 38, -64, -73, 11, 60, 76, -41, -30, -78, 42, 46, 68, -63, -48, -56,
- 89, 43, 28, -100, -53, 41, 60, 11, -6, -76, -16, 44, 52, 9, -67, -48,
- 10, 69, 30, -1, -84, -4, 36, 72, -23, -22, -27, -33, 55, 74, -11, -86,
- -1, 27, 36, 31, -7, -101, 49, 5, 66, -7, -46, -39, 9, 64, 44, -63,
- -33, -22, 55, 23, 43, -79, -24, 5, 29, 54, -14, -59, -53, 63, 32, 20,
- -34, -32, -36, 93, -2, 20, -35, -38, 18, 51, 61, -94, 15, -14, 17, 69,
- 5, -87, 16, 28, 34, 1, 34, -57, -53, 118, -22, 34, -10, -71, 23, 70,
- 25, -29, -7, -19, -3, 117, -33, -12, -21, -19, 43, 84, -38, -57, 33, 0,
- 32, 41, -7, -103, 85, 2, 2, 58, -14, -103, 103, 7, -17, 34, -32, -59,
- 71, 51, -78, 76, -65, -30, 63, 48, -66, 9, -11, -28, 52, 50, -72, -37,
- 73, -61, 75, 7, -51, -44, 73, -3, -11, 40, -78, 7, 63, -15, -16, 30,
- -53, 12, 38, 12, -42, 39, -63, 47, 23, 0, -23, -11, 8, -25, 60, -37,
- -15, -3, -9, 12, 27, -14, -40, 22, 12, 14, 15, -31, -14, 15, 23, -12,
- 14, -31, 19, 13, 32, -39, 27, -51, 43, 8, 0, 5, -26, 16, 4, 19,
- -24, 17, -18, 6, -2, 49, -67, 39, -1, -30, 46, -13, -16, -9, 21, -17,
- 27, 2, -34, 19, -3, 24, 8, -38, 13, -10, 22, 15, -34, 2, 4, -10,
- 18, 14, -15, -15, 26, -12, 28, -21, 0, -6, 0, 7, 0, -15, 6, -2,
- -18, 9, 8, -18, -15, 59, -94, 81, -40, -24, 14, -18, 25, -15, 4, -21,
- -9, 24, -20, 3, 3, -52, 56, -29, 4, 5, -51, 45, -50, 73, -75, 13,
- 17, -48, 38, -10, -16, 5, 4, -22, 3, 17, -27, -23, 42, -30, -5, 41,
- -53, 10, 23, -28, 1, 29, -47, 9, 13, -3, -18, 9, -13, -11, 18, 12,
- -53, 28, 1, -41, 41, 7, -61, 32, 0, -34, 16, 9, -74, 45, -23, -33,
- 22, 39, -104, 49, 23, -96, 83, 5, -46, 36, -4, -45, 54, -25, -26, 21,
- 2, -39, 51, -25, -25, 43, -22, -25, 30, -2, -32, 39, 14, -69, 42, 22,
- -78, 60, 23, -83, 33, 44, -74, 19, 69, -113, 43, 53, -88, 51, 17, -74,
- 42, 1, -38, 4, 39, -67, 12, 35, -39, -23, 73, -82, -5, 67, -71, -5,
- 42, -36, -48, 78, -64, -4, 40, -48, -7, 50, -80, 17, 31, -56, 9, 6,
- -18, -36, 43, -37, -29, 47, -47, -18, 33, -29, -27, 40, -30, -37, 51, -46,
- -25, 61, -66, 7, 28, -48, 30, -15, -8, -6, 17, -14, -9, 26, -23, 4,
- 9, -15, 12, -9, 16, -22, 7, 22, -51, 59, -29, -23, 54, -49, 6, 20,
- -19, -11, 17, -3, -30, 32, -27, -5, 16, -28, 4, 4, -27, 32, -46, 27,
- -18, -8, 11, -25, 18, -6, -17, 10, 1, -18, 24, -33, 10, 8, -12, -10,
- 21, -19, 0, 8, -18, 14, 11, -44, 39, -22, -4, -6, 11, -15, -13, 17,
- -17, -6, 13, -22, -1, 7, -5, -8, 0, 4, -24, 29, -23, 0, 20, -25,
- -8, 30, -34, 31, -29, 11, -9, 21, -15, -1, 10, -9, -11, 32, -23, -2,
- -14, 27, -19, 10, -4, -23, 14, 13, -45, 48, -44, 11, -4, -7, -3, 4,
- -2, -34, -8, 37, -41, 20, -24, -4, -10, 2, 4, 12, -28, -30, 9, 32,
- -16, 6, -46, -23, 60, 0, -22, -3, -23, -15, 48, 12, -34, -17, -18, 10,
- 46, -1, -56, -8, 12, 9, 18, 13, -72, -3, 26, 9, 28, -14, -89, 15,
- 67, -18, 1, -19, -52, 45, 26, -8, -5, -25, -25, 36, 38, -13, -36, -18,
- -6, 55, 23, -51, -14, 4, 6, 25, 24, -41, -44, 38, 19, 10, 10, -59,
- -14, 42, 1, 6, -8, -43, -1, 43, 10, -30, -10, -36, 18, 35, -20, -14,
- -11, -19, 9, 20, -5, -22, -9, -6, 13, 26, -30, -23, 4, 1, 20, 9,
- -20, -22, 3, -1, 17, 28, -26, -25, 16, -2, -4, 12, -10, -16, 24, -2,
- -18, 17, -27, -1, 36, -6, -7, -4, -26, 6, 29, -3, -17, -6, -4, 18,
- 18, -26, -10, -4, 6, 30, -1, -6, -24, 0, 24, 12, 2, -16, -25, 13,
- 32, -3, -4, -3, -24, 15, 16, -7, 8, -20, -13, 36, 9, -24, -11, -10,
- 10, 20, -1, -13, -10, -9, 20, 17, -12, -9, -15, 9, 20, -11, -14, -6,
- 5, 10, 6, 5, -7, -11, 7, 19, 1, 3, -11, -10, 24, 14, -16, 2,
- -9, 11, 14, 7, -1, -11, -4, 15, 24, 3, -24, -4, 4, 15, 13, -3,
- -15, 0, 15, 8, 2, 0, -19, 16, 12, -1, 7, -13, -2, 18, 3, -3,
- 5, -9, -10, 12, 9, -2, 8, -9, 4, 9, 6, 1, -8, 10, 4, -2,
- 11, -14, 3, 5, 1, 9, 4, -15, 0, 10, 1, 5, -4, -10, 3, 7,
- -1, 8, -13, 1, 4, 10, 6, -9, -3, 1, 6, 14, -3, -4, 4, -10,
- 10, 13, -1, -4, 5, -3, 10, 13, -13, 4, 7, 1, 8, -1, 1, 4,
- 5, 4, 11, -5, -2, 1, 8, 6, 1, 3, -1, -5, 11, 3, -3, 4,
- -5, -1, 17, -4, -2, 6, -10, 10, 10, -4, 2, 3, -10, 10, 5, -2,
- -2, -1, 4, 3, -1, -2, -4, 1, 6, -4, 6, -4, -10, 8, 2, -4,
- 6, -4, -4, 12, -2, 2, 6, -9, 3, 2, 0, 7, -5, -3, 3, 2,
- 4, -4, -2, 7, 3, 5, 9, -3, 1, 12, -3, 7, 6, -9, 4, 9,
- -4, 12, 1, -7, 9, 2, 1, 10, -3, 1, 0, 0, 8, 0, -1, 5,
- -2, 8, 1, -3, 10, 2, 0, 11, -4, -1, 6, -3, 2, 3, -5, 4,
- 0, -5, 5, -3, 1, 3, 0, 4, -3, -3, 4, -2, -2, 5, -2, -1,
- 6, -5, 2, 3, -4, 4, -2, -3, 11, -8, 0, 5, -1, 1, 0, -3,
- 4, 2, 2, 6, -2, 4, 5, -3, 4, 7, -4, 11, -1, 0, 3, 0,
- 3, 7, -2, 5, 1, 0, 6, 3, 2, 4, -1, 2, 6, 0, 3, 5,
- -4, 6, 0, 2, 7, -4, -1, 2, -2, 7, 1, -1, 1, -2, 2, 4,
- -5, 0, 4, -1, 2, -1, -2, 1, -2, 3, 2, -3, 3, -1, -4, 5,
- -2, -2, 3, 0, -1, 2, -5, 2, 1, -4, 0, 1, -3, 5, -2, 2,
- 2, -3, 1, 3, -2, 3, 1, -2, 4, 1, 2, 5, -2, 3, 1, 2,
- 5, 0, -1, 4, 0, 1, 4, 2, 4, 4, -2, 0, 2, 3, 5, 0,
- 0, 0, 1, 5, -2, -3, 4, 0, 1, 2, -2, -4, -4, -5, -6, -7,
- -8, -9, -10, -11, -12, -13, -13, -14, -16, -18, -21, -25, -29, -34, -36, -38,
- -39, -40, -42, -44, -47, -50, -53, -56, -58, -59, -58, -55, -50, -44, -38, -31,
- -24, -18, -13, -9, -6, -3, 0, 3, 6, 9, 13, 17, 21, 27, 33, 42,
- 53, 63, 74, 83, 91, 98, 104, 108, 111, 113, 115, 118, 119, 121, 123, 125,
- 126, 127, 127, 127, 127, 126, 126, 126, 126, 127, 127, 127, 127, 127, 127, 127,
- 126, 125, 123, 121, 118, 114, 111, 107, 104, 101, 100, 99, 98, 98, 98, 98,
- 98, 99, 98, 98, 97, 95, 92, 88, 81, 73, 63, 54, 46, 39, 33, 29,
- 27, 25, 24, 22, 20, 18, 14, 10, 5, 0, -5, -8, -8, -7, -3, 2,
- 8, 14, 19, 23, 26, 28, 29, 30, 31, 32, 32, 31, 30, 28, 24, 20,
- 14, 9, 4, -1, -4, -7, -9, -10, -12, -13, -15, -17, -19, -22, -24, -25,
- -25, -23, -21, -19, -17, -15, -15, -14, -15, -15, -16, -17, -17, -17, -16, -16,
- -16, -17, -19, -22, -25, -30, -35, -39, -44, -47, -50, -53, -56, -58, -61, -63,
- -64, -65, -65, -63, -60, -55, -49, -43, -38, -34, -32, -31, -31, -32, -33, -35,
- -36, -37, -37, -36, -35, -34, -34, -34, -36, -39, -43, -49, -55, -61, -67, -72,
- -77, -81, -85, -88, -90, -92, -94, -94, -95, -94, -94, -94, -94, -95, -96, -98,
- -100, -102, -104, -105, -107, -108, -108, -109, -110, -110, -110, -109, -109, -109, -108, -108,
- -109, -109, -109, -109, -108, -108, -107, -106, -106, -105, -105, -105, -105, -105, -105, -104,
- -103, -101, -98, -93, -88, -82, -76, -70, -64, -58, -52, -47, -42, -38, -34, -31,
- -29, -27, -25, -22, -18, -13, -7, -1, 6, 13, 20, 26, 32, 37, 41, 45,
- 48, 51, 55, 58, 63, 68, 73, 77, 82, 85, 89, 91, 94, 96, 97, 98,
- 99, 99, 99, 100, 100, 100, 101, 101, 101, 101, 101, 101, 99, 97, 95, 93,
- 90, 87, 84, 81, 77, 73, 67, 60, 51, 40, 29, 17, 6, -5, -14, -23,
- -31, -38, -45, -52, -58, -65, -70, -75, -80, -84, -87, -90, -92, -94, -95, -96,
- -97, -98, -100, -101, -102, -102, -103, -103, -104, -104, -103, -102, -100, -97, -93, -89,
- -86, -82, -79, -77, -75, -72, -70, -67, -63, -59, -53, -47, -40, -33, -26, -20,
- -14, -9, -6, -3, 0, 3, 6, 9, 13, 17, 21, 26, 31, 37, 44, 51,
- 58, 64, 70, 75, 79, 83, 86, 88, 90, 92, 93, 95, 96, 97, 98, 100,
- 100, 101, 102, 102, 102, 102, 102, 102, 102, 102, 102, 103, 103, 103, 102, 102,
- 102, 101, 100, 98, 96, 94, 92, 90, 89, 88, 88, 87, 87, 87, 87, 87,
- 86, 85, 84, 82, 79, 76, 72, 67, 61, 55, 49, 43, 39, 35, 32, 30,
- 29, 27, 25, 24, 21, 18, 15, 12, 8, 5, 3, 3, 4, 6, 9, 12,
- 15, 18, 21, 23, 25, 27, 28, 30, 31, 31, 31, 30, 28, 25, 22, 18,
- 14, 10, 7, 5, 3, 1, 0, -2, -4, -6, -9, -11, -14, -16, -17, -17,
- -16, -14, -12, -11, -9, -9, -9, -10, -11, -12, -13, -14, -15, -15, -16, -16,
- -17, -19, -22, -26, -30, -34, -38, -42, -45, -48, -50, -52, -53, -54, -55, -56,
- -56, -55, -53, -50, -46, -42, -38, -35, -32, -31, -30, -31, -31, -33, -34, -35,
- -36, -36, -36, -35, -35, -35, -36, -38, -41, -45, -49, -54, -59, -64, -68, -73,
- -76, -80, -83, -86, -88, -89, -90, -91, -91, -91, -92, -92, -93, -95, -96, -98,
- -100, -101, -102, -103, -104, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105,
- -105, -105, -104, -104, -103, -102, -102, -101, -100, -100, -100, -99, -99, -99, -98, -96,
- -94, -91, -86, -82, -76, -71, -65, -59, -53, -48, -42, -37, -32, -28, -25, -22,
- -19, -16, -13, -8, -3, 3, 9, 16, 22, 28, 35, 40, 45, 49, 53, 56,
- 60, 63, 67, 71, 76, 80, 85, 88, 92, 94, 97, 99, 100, 102, 103, 103,
- 104, 104, 104, 104, 105, 105, 105, 105, 105, 104, 103, 101, 99, 97, 94, 91,
- 87, 84, 80, 76, 71, 65, 57, 48, 39, 28, 18, 8, -2, -11, -19, -27,
- -34, -41, -47, -54, -60, -65, -70, -75, -79, -82, -85, -87, -89, -91, -92, -94,
- -95, -96, -97, -98, -99, -100, -100, -100, -100, -100, -98, -96, -94, -90, -87, -84,
- -81, -78, -76, -73, -71, -68, -65, -61, -57, -52, -46, -40, -33, -27, -21, -15,
- -11, -7, -4, 0, 3, 7, 11, 15, 20, 24, 29, 35, 41, 48, 54, 61,
- 67, 72, 77, 81, 85, 88, 90, 92, 94, 95, 97, 98, 99, 101, 102, 103,
- 104, 104, 104, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 104,
- 104, 103, 101, 99, 98, 96, 95, 93, 93, 92, 92, 91, 91, 90, 90, 88,
- 87, 86, 84, 81, 78, 74, 69, 64, 59, 54, 49, 45, 42, 39, 37, 35,
- 33, 31, 29, 27, 24, 21, 18, 15, 13, 11, 11, 12, 13, 15, 17, 20,
- 22, 24, 25, 27, 28, 29, 30, 31, 31, 31, 30, 28, 26, 23, 20, 17,
- 14, 11, 9, 8, 6, 5, 3, 1, -1, -4, -6, -8, -10, -11, -11, -11,
- -10, -9, -8, -8, -8, -9, -10, -11, -13, -14, -15, -16, -17, -17, -18, -20,
- -22, -25, -28, -31, -35, -38, -41, -44, -46, -47, -49, -50, -51, -52, -52, -52,
- -51, -49, -47, -44, -40, -38, -35, -33, -33, -32, -33, -33, -34, -35, -36, -37,
- -38, -38, -38, -38, -39, -40, -42, -45, -49, -53, -57, -61, -65, -69, -73, -76,
- -79, -82, -85, -87, -88, -89, -90, -91, -91, -92, -93, -94, -95, -97, -98, -99,
- -100, -101, -102, -103, -103, -104, -104, -104, -104, -104, -104, -104, -104, -104, -103, -103,
- -103, -102, -102, -101, -100, -99, -99, -98, -97, -97, -96, -96, -95, -94, -92, -89,
- -86, -82, -77, -72, -67, -61, -56, -50, -45, -39, -34, -29, -25, -21, -18, -14,
- -11, -5, 4, 8, 14, 19, 25, 31, 37, 42, 47, 52, 57, 61, 65, 69,
- 72, 76, 79, 83, 86, 89, 92, 95, 97, 99, 101, 102, 104, 104, 105, 106,
- 106, 106, 106, 106, 106, 105, 104, 104, 103, 101, 99, 97, 95, 92, 89, 85,
- 81, 77, 73, 68, 62, 57, 50, 43, 35, 28, 19, 12, 4, -4, -11, -18,
- -25, -32, -38, -44, -50, -55, -61, -65, -69, -73, -77, -80, -82, -85, -87, -89,
- -91, -92, -93, -95, -95, -96, -97, -97, -97, -96, -96, -95, -93, -92, -90, -88,
- -86, -84, -82, -79, -77, -74, -71, -68, -64, -60, -55, -51, -46, -41, -36, -31,
- -26, -21, -16, -11, -7, -2, 3, 8, 14, 19, 25, 30, 36, 42, 47, 53,
- 58, 63, 68, 72, 76, 79, 82, 85, 87, 89, 91, 93, 95, 96, 98, 99,
- 101, 102, 103, 103, 104, 105, 105, 105, 106, 106, 106, 106, 106, 106, 106, 105,
- 105, 105, 104, 103, 103, 102, 101, 100, 99, 99, 98, 97, 96, 95, 93, 92,
- 91, 89, 87, 85, 82, 79, 76, 73, 70, 67, 63, 60, 58, 55, 53, 50,
- 48, 46, 44, 41, 39, 37, 34, 32, 31, 29, 28, 28, 27, 28, 28, 28,
- 28, 29, 29, 29, 29, 30, 30, 30, 29, 29, 28, 27, 26, 25, 23, 22,
- 20, 19, 17, 16, 15, 13, 12, 10, 8, 6, 4, 2, 1, -1, -2, -4,
- -5, -6, -7, -9, -10, -12, -13, -15, -17, -19, -21, -22, -24, -26, -27, -29,
- -31, -32, -34, -36, -38, -40, -42, -43, -45, -46, -47, -47, -48, -48, -49, -49,
- -48, -48, -47, -46, -45, -44, -44, -43, -43, -43, -44, -44, -45, -46, -47, -48,
- -49, -50, -51, -52, -53, -55, -57, -59, -61, -64, -67, -70, -72, -75, -78, -80,
- -82, -84, -86, -88, -90, -91, -92, -94, -95, -96, -97, -98, -98, -99, -100, -101,
- -101, -101, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -101, -101, -100, -100,
- -99, -98, -97, -96, -95, -94, -93, -92, -91, -89, -88, -87, -85, -83, -81, -78,
- -75, -71, -67, -63, -58, -54, -49, -44, -39, -33, -28, -23, -18, -13, -8, -3,
- 2, 7, 13, 18, 23, 29, 35, 40, 45, 51, 55, 60, 64, 68, 71, 75,
- 78, 82, 85, 88, 91, 93, 96, 98, 100, 101, 103, 104, 105, 105, 106, 106,
- 106, 106, 105, 105, 104, 104, 103, 101, 100, 98, 95, 93, 90, 86, 83, 79,
- 75, 70, 65, 60, 54, 47, 40, 33, 25, 18, 10, 2, -5, -12, -19, -26,
- -32, -38, -44, -50, -55, -60, -65, -69, -73, -76, -79, -82, -84, -87, -89, -90,
- -92, -93, -94, -95, -96, -96, -96, -96, -96, -95, -94, -93, -91, -90, -88, -86,
- -84, -81, -79, -76, -74, -70, -67, -63, -59, -54, -49, -44, -39, -34, -29, -24,
- -19, -14, -10, -5, -2, -1, 3, -2, 1, -3, 4, -2, 0, 0, 8, 0,
- 10, -9, -7, -128, -72, 13, -44, -13, -18, 4, -4, 12, 3, 31, 4, 66,
- 74, 38, 38, 36, 30, 25, 22, 18, 13, 7, 5, 2, 1, -5, -7, -9,
- -9, -11, -14, -12, -14, -12, -16, -13, -16, -13, -14, -16, -11, -14, -10, -13,
- -11, -13, -8, -8, -6, -6, -5, 0, -6, -3, -3, 3, -4, 6, -13, 17,
- -5, -5, 15, -1, -23, 6, 23, 28, 35, 13, 41, -3, 24, 25, -4, 6,
- 30, 4, 18, 10, -32, -64, -120, -64, -91, -76, -33, -45, -58, 2, 1, -19,
- -14, 18, 48, 50, 59, 51, 53, 47, 46, 41, 37, 35, 26, 28, 19, 21,
- 10, 13, 9, 3, 5, -4, 2, -5, -3, -8, -5, -8, -8, -10, -9, -10,
- -10, -12, -7, -17, -8, -11, -14, -5, -15, -5, -4, -10, -13, 11, -22, 3,
- -3, -4, -5, -11, 13, 2, -16, -9, -5, -12, 27, 15, 17, 21, 20, 20,
- 8, 14, 13, 0, 10, 35, 10, -1, -12, -52, -89, -78, -58, -85, -74, -51,
- -25, -25, -28, -30, -14, 12, 29, 44, 44, 51, 46, 50, 49, 43, 38, 36,
- 32, 29, 23, 19, 17, 14, 10, 6, 6, 2, 4, -8, 3, -7, -3, -6,
- -7, -11, -4, -12, -7, -6, -20, 1, -15, -14, -8, -7, -10, -10, -10, 2,
- -14, -12, 7, -10, -8, -5, -6, 1, 6, -2, -12, -19, -3, 3, 2, 19,
- 19, 14, 19, 24, 13, 5, 12, 12, 13, 21, 29, 5, -18, -43, -48, -64,
- -82, -82, -71, -44, -37, -37, -40, -33, -23, 5, 20, 33, 38, 45, 48, 51,
- 46, 44, 41, 38, 36, 27, 26, 24, 19, 13, 16, 5, 11, 4, -1, 3,
- -4, -3, 1, -9, -7, -2, -9, -6, -13, -4, -6, -17, -8, -6, -15, -10,
- -5, -10, -8, -10, -5, -7, -5, -2, -14, -10, 3, 5, -4, -3, -10, -17,
- -10, 3, 4, 5, 18, 18, 18, 16, 16, 10, 5, 11, 23, 26, 22, 7,
- -9, -16, -37, -62, -80, -76, -65, -46, -43, -43, -51, -41, -24, -4, 11, 24,
- 32, 41, 47, 43, 49, 45, 41, 40, 33, 31, 31, 20, 23, 18, 11, 16,
- 9, 5, 3, 2, 5, -2, -7, 2, -4, -10, -3, -5, -8, -10, -7, -8,
- -14, -10, -8, -11, -9, -6, -14, -10, -2, -3, -12, -10, -7, -9, 0, 6,
- -1, -11, -12, -11, -10, -7, 4, 7, 12, 17, 20, 18, 13, 6, 8, 19,
- 22, 24, 17, 14, 5, -8, -29, -54, -77, -71, -55, -50, -44, -54, -57, -39,
- -32, -15, 3, 15, 31, 34, 39, 47, 45, 44, 44, 37, 37, 33, 28, 27,
- 18, 20, 21, 10, 7, 10, 7, 1, 2, 2, 0, -5, 0, -2, -7, -3,
- -5, -8, -8, -5, -13, -13, -5, -6, -14, -11, -8, -8, -5, -5, -9, -17,
- -10, -2, 0, -2, -1, -9, -12, -14, -12, -6, -1, 3, 11, 19, 19, 14,
- 7, 9, 13, 17, 23, 22, 19, 21, 12, 2, -21, -55, -65, -59, -52, -47,
- -56, -56, -50, -53, -38, -22, -7, 10, 18, 29, 36, 40, 45, 43, 38, 41,
- 40, 32, 27, 26, 26, 19, 17, 17, 12, 9, 9, 6, 2, 4, 4, -1,
- -2, 2, -3, -3, 0, -2, -8, -9, -7, -7, -7, -6, -8, -12, -6, -4,
- -7, -12, -13, -10, -5, -2, -2, -3, -8, -12, -15, -16, -14, -13, -7, 2,
- 8, 11, 8, 4, 5, 8, 13, 20, 22, 23, 24, 23, 19, 6, -13, -23,
- -29, -32, -37, -42, -46, -53, -57, -53, -49, -39, -25, -12, -1, 10, 21, 28,
- 32, 35, 36, 34, 34, 32, 28, 25, 24, 21, 18, 19, 16, 10, 7, 8,
- 9, 8, 6, 5, 2, 3, 6, 7, 5, 2, -2, -4, -3, -1, -3, -4,
- -3, -1, -3, -8, -13, -14, -11, -4, -1, -2, -4, -6, -11, -16, -19, -21,
- -21, -17, -9, -3, 0, 0, -3, -5, -2, 4, 11, 18, 23, 25, 26, 24,
- 17, 10, 5, -1, -7, -12, -20, -29, -37, -44, -51, -55, -54, -47, -39, -28,
- -16, -4, 9, 18, 23, 27, 31, 31, 30, 30, 28, 23, 20, 22, 23, 20,
- 14, 10, 9, 9, 10, 9, 6, 4, 4, 6, 9, 10, 7, 2, 0, 1,
- -1, -2, -2, -1, 1, 2, -2, -10, -14, -11, -8, -5, -2, -1, -3, -6,
- -9, -14, -20, -23, -23, -18, -11, -5, -3, -4, -6, -8, -4, 2, 7, 14,
- 21, 25, 25, 23, 19, 13, 8, 4, -1, -9, -15, -23, -31, -39, -48, -53,
- -51, -48, -44, -34, -20, -8, 3, 12, 20, 24, 27, 30, 31, 29, 24, 22,
- 22, 23, 22, 18, 13, 10, 10, 11, 11, 9, 5, 3, 5, 10, 11, 9,
- 7, 5, 4, 2, 0, -3, -1, 3, 5, 2, -3, -8, -11, -10, -7, -5,
- -3, -2, -2, -4, -7, -14, -20, -24, -24, -19, -12, -6, -6, -8, -8, -8,
- -7, -2, 5, 12, 19, 23, 24, 22, 20, 16, 12, 7, 1, -5, -10, -17,
- -27, -36, -42, -47, -52, -51, -45, -36, -26, -12, 0, 9, 15, 21, 27, 30,
- 29, 26, 23, 22, 23, 23, 21, 17, 12, 9, 10, 12, 10, 6, 3, 4,
- 7, 10, 11, 9, 8, 9, 7, 2, -1, 0, 2, 6, 6, 3, -2, -7,
- -9, -8, -6, -4, -3, -1, -1, -2, -6, -13, -21, -26, -24, -18, -13, -10,
- -9, -10, -11, -11, -10, -5, 3, 10, 17, 21, 22, 22, 21, 19, 14, 8,
- 5, 1, -7, -14, -21, -29, -38, -45, -49, -50, -48, -40, -28, -16, -6, 3,
- 11, 19, 26, 27, 26, 24, 22, 22, 24, 24, 20, 14, 11, 11, 12, 11,
- 8, 4, 3, 6, 8, 9, 9, 10, 11, 10, 6, 2, 0, 2, 5, 8,
- 7, 3, -2, -5, -6, -7, -6, -4, -3, -1, 1, 1, -5, -13, -21, -24,
- -23, -18, -14, -12, -11, -12, -13, -14, -13, -8, 0, 8, 14, 17, 21, 22,
- 21, 18, 15, 12, 8, 2, -3, -9, -16, -24, -32, -40, -47, -51, -49, -41,
- -30, -21, -12, -1, 9, 17, 23, 25, 24, 21, 21, 24, 24, 22, 17, 12,
- 11, 13, 12, 8, 4, 3, 4, 6, 7, 7, 9, 11, 12, 10, 6, 3,
- 3, 6, 9, 10, 8, 5, 1, -2, -3, -3, -2, -1, 1, 3, 3, 1,
- -5, -12, -18, -20, -20, -18, -16, -16, -16, -17, -19, -20, -17, -11, -5, 1,
- 8, 13, 17, 18, 18, 17, 16, 14, 11, 7, 2, -3, -8, -14, -22, -34,
- -43, -46, -42, -35, -28, -20, -11, -2, 7, 15, 19, 19, 19, 19, 20, 20,
- 17, 14, 11, 10, 9, 7, 1, -4, -6, -4, 0, 2, 4, 6, 7, 8,
- 9, 8, 7, 7, 10, 13, 15, 15, 13, 9, 6, 3, 2, 4, 7, 9,
- 11, 11, 7, 1, -5, -10, -13, -14, -14, -14, -16, -19, -23, -26, -28, -27,
- -23, -18, -13, -7, -1, 6, 11, 14, 15, 14, 14, 15, 15, 12, 7, 2,
- -1, -4, -11, -22, -34, -41, -40, -34, -26, -19, -12, -4, 4, 10, 14, 17,
- 17, 18, 19, 18, 15, 12, 10, 9, 8, 6, 0, -6, -11, -10, -6, -1,
- 3, 5, 6, 6, 6, 7, 7, 8, 10, 13, 16, 18, 17, 13, 9, 5,
- 3, 4, 7, 11, 13, 14, 11, 5, -2, -7, -11, -12, -12, -13, -14, -17,
- -22, -26, -28, -29, -27, -22, -17, -11, -5, 1, 7, 12, 14, 14, 13, 14,
- 15, 14, 11, 5, 0, -2, -6, -15, -27, -37, -42, -38, -31, -24, -17, -9,
- -1, 6, 12, 15, 17, 18, 19, 19, 17, 13, 11, 9, 9, 8, 4, -2,
- -8, -11, -9, -4, 1, 4, 5, 6, 6, 6, 7, 7, 9, 11, 14, 17,
- 18, 16, 12, 8, 4, 3, 5, 9, 12, 14, 13, 9, 2, -4, -9, -12,
- -13, -12, -13, -15, -19, -23, -27, -29, -28, -25, -20, -15, -9, -3, 3, 9,
- 13, 15, 14, 13, 15, 15, 13, 9, 3, -1, -3, -9, -19, -31, -40, -41,
- -36, -28, -21, -14, -6, 2, 9, 13, 16, 17, 18, 19, 18, 16, 12, 10,
- 9, 9, 7, 2, -4, -10, -11, -8, -2, 2, 5, 5, 6, 6, 7, 7,
- 8, 9, 12, 16, 18, 17, 14, 10, 6, 4, 4, 6, 10, 13, 14, 12,
- 7, 0, -6, -10, -12, -13, -13, -14, -16, -21, -25, -28, -29, -28, -24, -18,
- -13, -7, -1, 6, 11, 14, 15, 13, 14, 15, 15, 12, 7, 2, -1, -5,
- -12, -23, -35, -41, -40, -34, -26, -19, -12, -3, 4, 10, 14, 17, 18, 18,
- 19, 18, 14, 11, 9, 9, 8, 6, 0, -7, -11, -10, -6, 0, 2, -1,
- -2, -9, -24, 4, -3, 3, -3, 10, 7, 4, 13, -4, 1, 3, 3, 0,
- 2, 8, -9, -9, 2, 1, -1, 7, 17, 21, 37, 25, 13, 14, -2, 15,
- 20, 5, 0, -3, -7, -27, -14, -18, -19, -29, -20, -4, -18, -32, -30, -30,
- -29, -32, -22, -26, -19, -19, -1, -6, 4, 7, 5, 2, 0, -8, -16, -12,
- -13, -17, -17, 19, 20, 24, 16, 8, -4, 8, 0, 13, 28, 33, 16, 11,
- 5, -3, -1, 4, 12, 12, 40, 20, 11, 4, 5, 8, -1, 2, 5, 5,
- 22, 13, 21, 8, 9, 18, 20, 13, 20, 26, 11, 24, 17, 10, 27, 30,
- 22, 28, 30, 41, 47, 57, 36, 36, 20, -16, 4, 6, -19, -21, -41, -39,
- -33, -38, -41, -46, -42, -36, -18, -37, -65, -75, -77, -78, -62, -63, -62, -68,
- -63, -63, -44, -50, -30, -41, -43, -26, -34, -35, -36, -45, -49, -27, 1, -6,
- -4, -7, -20, -16, -20, -21, -13, 2, -6, -1, -12, 0, -1, 15, 19, 20,
- 26, 37, 40, 46, 37, 50, 35, 34, 41, 43, 51, 54, 55, 50, 56, 47,
- 59, 51, 51, 75, 67, 66, 71, 59, 60, 72, 75, 72, 80, 79, 82, 98,
- 99, 87, 93, 62, 49, 58, 41, 42, 28, 5, -6, -6, -18, -24, -23, -30,
- -25, -20, -38, -60, -75, -77, -80, -75, -71, -75, -70, -73, -69, -76, -60, -66,
- -71, -66, -57, -62, -61, -61, -87, -90, -69, -63, -46, -31, -35, -47, -42, -53,
- -63, -53, -45, -33, -36, -39, -37, -43, -39, -34, -30, -19, -9, 2, -9, -1,
- -3, 1, -3, 5, 7, 15, 24, 22, 23, 20, 32, 43, 33, 48, 63, 67,
- 70, 68, 52, 59, 73, 73, 77, 85, 73, 81, 103, 98, 116, 115, 87, 80,
- 76, 72, 69, 60, 37, 27, 29, 12, 19, 4, -12, 1, 3, -3, -31, -42,
- -57, -67, -67, -61, -61, -61, -48, -58, -51, -41, -46, -48, -40, -35, -33, -26,
- -36, -67, -68, -65, -59, -47, -28, -34, -37, -36, -52, -61, -61, -47, -34, -39,
- -39, -42, -42, -48, -36, -38, -37, -20, -19, -16, -16, -18, -20, -22, -26, -22,
- -16, -15, 1, -4, -6, 10, 12, 13, 22, 32, 41, 54, 52, 44, 54, 66,
- 61, 78, 81, 71, 87, 89, 99, 119, 107, 91, 77, 76, 69, 76, 68, 47,
- 49, 35, 33, 37, 22, 14, 24, 37, 26, 13, -10, -26, -41, -43, -34, -40,
- -34, -33, -43, -39, -25, -27, -27, -18, -25, -15, -1, -10, -29, -42, -39, -39,
- -19, -7, -10, -10, -11, -20, -35, -44, -33, -30, -28, -36, -34, -47, -41, -36,
- -46, -42, -34, -27, -29, -25, -34, -30, -32, -40, -36, -36, -31, -16, -25, -25,
- -15, -21, -14, -9, -11, 1, 17, 15, 9, 25, 20, 25, 46, 39, 46, 50,
- 51, 68, 85, 87, 72, 65, 52, 50, 59, 44, 42, 29, 23, 22, 23, 11,
- -5, 8, 14, 19, 8, -6, -23, -38, -43, -42, -48, -41, -34, -42, -38, -19,
- -23, -16, -15, -19, -10, 8, 8, -9, -18, -27, -30, -10, -4, 7, 6, 15,
- 8, -8, -17, -15, -8, -11, -3, -15, -17, -14, -16, -27, -30, -26, -22, -19,
- -21, -22, -19, -30, -27, -26, -36, -22, -9, -13, -10, -10, -8, -9, -6, -12,
- -1, 16, 6, 11, 16, 6, 19, 24, 27, 38, 38, 38, 48, 71, 72, 78,
- 66, 51, 54, 52, 49, 42, 32, 21, 25, 26, 13, 1, -1, 10, 15, 8,
- 1, -22, -38, -47, -56, -58, -46, -43, -46, -33, -25, -17, -11, -9, -19, -9,
- 16, 18, 12, 1, -17, -18, -9, 3, 9, 17, 24, 26, 9, -4, -1, -6,
- 2, 9, 0, -2, 2, -3, -13, -16, -15, -8, -8, -8, -1, -6, -17, -11,
- -22, -24, -16, -12, -9, -9, -9, -9, -6, -8, -16, 2, 6, 2, 13, 9,
- 7, 10, 17, 19, 30, 31, 22, 37, 49, 61, 70, 56, 43, 37, 36, 31,
- 32, 15, 4, 11, 9, 4, -14, -16, -7, -5, -1, -8, -28, -46, -56, -75,
- -74, -67, -70, -67, -62, -55, -47, -36, -32, -42, -28, -9, 1, 4, -4, -17,
- -30, -18, -12, -2, 4, 15, 21, 7, 1, -7, -6, -1, 7, 0, 0, 3,
- -3, -8, -15, -18, -6, -9, -6, 5, -2, -2, 0, -7, -12, -7, -3, 2,
- 7, 3, 4, 14, 2, 1, 12, 11, 17, 20, 19, 16, 19, 20, 24, 39,
- 36, 37, 42, 55, 71, 84, 76, 63, 56, 47, 49, 46, 29, 18, 14, 18,
- 11, -5, -11, -8, -3, 4, 4, -16, -27, -44, -60, -64, -59, -62, -62, -55,
- -55, -47, -28, -32, -35, -29, -15, -3, 4, 3, -15, -25, -24, -13, -11, -3,
- 10, 14, 12, 4, -5, -9, -1, 2, -1, 1, 1, -1, -7, -17, -16, -12,
- -17, -8, 0, -1, -1, -2, -8, -13, -9, -9, 0, 9, 1, 14, 16, 6,
- 7, 10, 12, 18, 26, 20, 22, 22, 16, 25, 32, 36, 34, 36, 43, 60,
- 75, 72, 67, 52, 44, 50, 45, 38, 17, 14, 17, 11, -2, -9, -14, -10,
- 0, -4, -12, -24, -41, -59, -67, -63, -70, -69, -62, -70, -55, -40, -38, -42,
- -38, -29, -16, -3, -3, -9, -29, -31, -25, -26, -20, -7, 0, 2, -1, -14,
- -18, -14, -14, -12, -10, -10, -4, -13, -21, -19, -22, -24, -16, -10, -6, -2,
- -2, -10, -12, -15, -17, -4, -4, -5, 7, 9, 3, 4, 7, 5, 18, 23,
- 22, 28, 25, 22, 27, 34, 39, 43, 38, 41, 62, 71, 79, 78, 62, 55,
- 55, 57, 49, 31, 23, 30, 21, 15, 7, -5, 1, 8, 9, 8, -3, -16,
- -39, -46, -50, -60, -55, -58, -62, -53, -36, -33, -34, -34, -29, -18, -6, 5,
- -2, -17, -23, -22, -24, -17, -8, 1, 9, 10, -4, -7, -8, -9, -6, -9,
- -6, 0, -11, -14, -14, -21, -24, -21, -16, -10, 1, -3, -3, -5, -14, -11,
- -7, -7, -5, 6, 9, 4, 8, 1, 3, 11, 16, 20, 26, 24, 20, 25,
- 29, 36, 41, 32, 40, 51, 64, 77, 78, 67, 55, 54, 57, 53, 33, 27,
- 25, 22, 20, 9, -3, -3, 3, 7, 6, 4, -16, -32, -42, -55, -60, -61,
- -64, -70, -62, -49, -39, -41, -40, -37, -33, -18, -5, -8, -16, -24, -29, -31,
- -28, -24, -15, -1, 1, -7, -11, -14, -13, -14, -18, -11, -8, -14, -16, -16,
- -25, -31, -29, -31, -20, -12, -13, -6, -11, -19, -19, -14, -17, -12, -1, 2,
- 6, 7, 2, 4, 8, 11, 18, 24, 21, 22, 19, 21, 33, 33, 32, 32,
- 40, 55, 71, 76, 72, 58, 55, 62, 56, 42, 34, 28, 29, 26, 17, 4,
- 2, 6, 4, 13, 12, -4, -18, -30, -45, -50, -51, -59, -63, -61, -47, -37,
- -33, -32, -34, -32, -19, -4, -3, -5, -13, -21, -23, -22, -24, -13, 1, 5,
- 5, -3, -6, -1, -7, -9, -2, 1, -2, -2, -4, -13, -16, -22, -22, -15,
- -10, -4, 2, -1, -11, -8, -7, -12, -6, 1, 6, 12, 11, 8, 9, 9,
- 9, 20, 23, 26, 25, 20, 24, 32, 34, 35, 33, 35, 49, 63, 74, 74,
- 58, 55, 60, 54, 45, 33, 27, 25, 26, 19, 6, 4, 1, 1, 9, 12,
- -1, -10, -26, -43, -50, -54, -61, -70, -69, -61, -50, -43, -40, -44, -44, -34,
- -18, -12, -9, -15, -24, -25, -28, -31, -22, -12, -2, 1, -8, -8, -5, -12,
- -14, -8, -8, -8, -5, -9, -11, -18, -27, -26, -22, -19, -12, -1, -4, -9,
- -8, -11, -14, -12, -8, 0, 7, 5, 5, 6, 0, 3, 8, 13, 20, 18,
- 13, 15, 22, 27, 29, 25, 26, 36, 51, 70, 71, 59, 56, 57, 55, 47,
- 37, 25, 24, 27, 17, 9, 3, -2, -2, 8, 9, 6, -2, -16, -34, -44,
- -47, -54, -63, -66, -63, -55, -44, -39, -42, -44, -35, -23, -11, -4, -10, -16,
- -17, -23, -25, -22, -13, 1, 6, 1, 1, 4, -2, -4, 1, -1, 4, 3,
- 2, 2, -3, -12, -15, -14, -15, -7, 3, 5, 3, 2, 1, -2, -4, -4,
- 3, 9, 10, 13, 11, 9, 8, 9, 15, 22, 22, 20, 19, 21, 27, 30,
- 28, 28, 28, 42, 61, 69, 65, 60, 60, 58, 55, 47, 35, 30, 30, 24,
- 18, 10, 0, -1, 2, 6, 7, 3, -8, -24, -36, -43, -50, -59, -65, -66,
- -62, -52, -43, -43, -44, -41, -35, -21, -12, -12, -13, -17, -23, -26, -30, -24,
- -12, -4, -5, -3, -2, -5, -6, -6, -5, -3, -2, -1, 2, 2, -5, -3,
- 2, 8, 17, 26, 32, 42, 50, 56, 68, 73, 64, 63, 65, 48, 56, 71,
- 48, 49, 50, 26, 30, 30, 16, 25, 21, -2, 0, -13, -15, -2, -19, -17,
- -16, -50, -49, -49, -81, -85, -88, -108, -112, -116, -127, -126, -113, -113, -106, -79,
- -65, -48, -17, 5, 20, 41, 58, 63, 69, 59, 28, 17, 0, -32, -41, -52,
- -69, -63, -61, -59, -41, -26, -19, 6, 28, 33, 52, 67, 70, 81, 87, 84,
- 90, 93, 84, 72, 69, 60, 45, 56, 57, 40, 46, 39, 25, 29, 25, 16,
- 21, 12, -1, -3, -11, -8, -5, -16, -12, -21, -41, -38, -48, -68, -70, -77,
- -91, -93, -98, -106, -103, -93, -92, -82, -60, -47, -30, -4, 13, 27, 44, 56,
- 60, 62, 47, 23, 13, -8, -32, -40, -54, -64, -59, -59, -53, -36, -26, -14,
- 12, 27, 36, 56, 66, 72, 84, 86, 86, 93, 92, 82, 73, 70, 57, 49,
- 59, 52, 43, 47, 37, 29, 30, 24, 18, 18, 7, -2, -6, -11, -7, -10,
- -16, -14, -29, -42, -42, -57, -71, -73, -83, -93, -96, -102, -107, -101, -93, -90,
- -75, -55, -41, -22, 3, 19, 33, 50, 59, 61, 60, 41, 21, 10, -14, -33,
- -43, -57, -63, -60, -61, -51, -36, -27, -9, 15, 26, 40, 59, 66, 74, 85,
- 85, 88, 94, 90, 80, 75, 69, 56, 54, 60, 50, 47, 46, 36, 31, 30,
- 23, 19, 15, 4, -3, -7, -10, -9, -14, -17, -19, -35, -44, -47, -63, -73,
- -77, -88, -96, -98, -104, -107, -99, -92, -86, -69, -50, -35, -14, 9, 24, 38,
- 54, 60, 61, 56, 36, 19, 4, -20, -35, -46, -60, -62, -61, -60, -48, -35,
- -25, -3, 17, 27, 45, 60, 66, 77, 85, 86, 91, 94, 88, 80, 75, 67,
- 56, 58, 59, 50, 49, 45, 36, 33, 30, 23, 19, 13, 2, -5, -8, -10,
- -11, -16, -18, -25, -40, -45, -53, -68, -76, -81, -91, -97, -100, -106, -106, -97,
- -90, -81, -63, -44, -28, -6, 15, 28, 44, 57, 61, 61, 52, 31, 16, -1,
- -24, -37, -50, -61, -62, -62, -59, -46, -35, -22, 1, 18, 30, 48, 61, 68,
- 79, 85, 87, 92, 93, 86, 80, 75, 66, 58, 60, 58, 51, 50, 44, 37,
- 33, 29, 23, 17, 10, 0, -6, -9, -10, -14, -18, -21, -31, -43, -48, -59,
- -72, -78, -85, -94, -99, -102, -107, -104, -95, -88, -76, -56, -39, -22, 2, 20,
- 33, 49, 59, 61, 60, 47, 27, 12, -7, -27, -40, -53, -62, -62, -63, -57,
- -44, -34, -18, 5, 19, 33, 51, 61, 70, 81, 85, 88, 94, 92, 85, 80,
- 74, 65, 60, 62, 57, 52, 50, 43, 37, 33, 28, 22, 15, 8, -2, -7,
- -10, -12, -16, -20, -24, -36, -46, -52, -64, -75, -81, -89, -97, -100, -104, -107,
- -102, -93, -85, -70, -50, -33, -14, 8, 25, 38, 53, 61, 61, 58, 42, 24,
- 8, -12, -30, -43, -56, -62, -63, -63, -54, -43, -32, -13, 7, 20, 37, 53,
- 62, 72, 82, 85, 89, 94, 90, 84, 80, 73, 64, 62, 62, 56, 53, 49,
- 43, 37, 33, 27, 20, 14, 5, -3, -8, -11, -13, -18, -22, -28, -40, -49,
- -57, -69, -78, -84, -92, -99, -102, -105, -106, -99, -90, -81, -64, -44, -27, -7,
- 14, 29, 43, 56, 61, 61, 54, 37, 20, 4, -17, -33, -46, -58, -62, -64,
- -62, -52, -42, -29, -9, 9, 23, 40, 55, 64, 74, 83, 86, 91, 93, 89,
- 84, 80, 72, 65, 64, 62, 56, 53, 49, 42, 37, 33, 26, 19, 12, 3,
- -5, -8, -12, -16, -20, -24, -33, -44, -52, -61, -73, -80, -87, -95, -100, -103,
- -106, -104, -96, -88, -76, -57, -38, -21, 0, 20, 33, 47, 59, 62, 60, 51,
- 33, 17, -1, -21, -36, -49, -59, -63, -64, -61, -51, -40, -25, -5, 11, 26,
- 43, 56, 65, 76, 83, 87, 92, 93, 88, 84, 79, 71, 65, 65, 61, 56,
- 53, 48, 42, 37, 32, 25, 17, 10, 1, -6, -10, -13, -18, -22, -27, -37,
- -48, -55, -65, -76, -83, -90, -97, -101, -104, -106, -102, -94, -84, -71, -51, -33,
- -15, 7, 24, 38, 51, 60, 62, 59, 46, 29, 13, -6, -25, -39, -52, -60,
- -63, -64, -59, -49, -38, -21, -1, 14, 29, 46, 57, 67, 78, 84, 88, 92,
- 92, 87, 83, 78, 70, 66, 65, 61, 57, 53, 48, 42, 37, 31, 23, 15,
- 7, -1, -7, -11, -15, -20, -24, -31, -41, -51, -59, -69, -79, -85, -93, -99,
- -102, -105, -106, -100, -91, -80, -65, -45, -27, -8, 13, 29, 42, 55, 61, 61,
- 56, 42, 25, 8, -11, -28, -42, -54, -61, -64, -64, -57, -47, -35, -17, 1,
- 16, 33, 48, 59, 69, 79, 84, 89, 93, 91, 87, 83, 77, 70, 67, 65,
- 60, 57, 53, 47, 41, 36, 29, 21, 14, 5, -3, -8, -12, -17, -22, -27,
- -35, -45, -54, -63, -73, -81, -88, -95, -100, -103, -105, -104, -97, -88, -76, -58,
- -39, -21, -1, 18, 33, 46, 58, 62, 61, 53, 38, 21, 4, -15, -31, -45,
- -56, -62, -65, -64, -56, -46, -32, -13, 4, 19, 36, 50, 61, 71, 80, 85,
- 90, 92, 90, 86, 82, 76, 70, 68, 65, 60, 57, 52, 46, 41, 35, 27,
- 19, 12, 3, -5, -9, -14, -19, -24, -29, -38, -48, -57, -66, -76, -84, -91,
- -97, -101, -104, -105, -102, -94, -84, -71, -52, -33, -15, 5, 23, 37, 50, 60,
- 62, 60, 50, 34, 17, -1, -19, -35, -48, -58, -63, -65, -62, -54, -43, -28,
- -10, 7, 22, 39, 52, 62, 73, 81, 86, 91, 92, 89, 86, 82, 75, 70,
- 68, 64, 60, 57, 52, 46, 40, 34, 26, 17, 9, 1, -6, -11, -15, -21,
- -26, -32, -42, -52, -60, -70, -79, -86, -93, -99, -102, -104, -105, -100, -91, -80,
- -65, -46, -27, -9, 11, 28, 42, 54, 61, 62, 58, 46, 30, 13, -6, -23,
- -38, -51, -60, -64, -65, -61, -52, -41, -25, -6, 9, 26, 42, 54, 64, 75,
- 82, 87, 91, 91, 89, 85, 81, 74, 71, 68, 64, 60, 56, 51, 45, 39,
- 32, 24, 16, 7, -1, -7, -12, -17, -23, -28, -36, -45, -55, -64, -73, -82,
- -88, -95, -100, -103, -105, -104, -97, -88, -76, -59, -40, -22, -2, 17, 32, 45,
- 57, 62, 62, 56, 42, 26, 9, -10, -27, -41, -53, -61, -65, -65, -60, -50,
- -38, -21, -3, 12, 29, 44, 55, 66, 76, 82, 88, 91, 91, 88, 85, 80,
- 74, 71, 68, 63, 60, 56, 50, 44, 38, 30, 22, 14, 5, -3, -9, -14,
- -19, -25, -31, -39, -49, -58, -67, -77, -84, -91, -97, -101, -103, -105, -102, -95,
- -84, -71, -53, -34, -16, 4, 22, 37, 49, 59, 63, 61, 53, 38, 22, 4,
- -14, -30, -44, -56, -62, -66, -65, -58, -48, -35, -17, -1, 15, 32, 46, 57,
- 68, 77, 83, 88, 91, 90, 88, 84, 79, 74, 71, 67, 63, 60, 55, 49,
- 43, 37, 28, 20, 12, 3, -5, -10, -15, -21, -27, -33, -43, -52, -61, -70,
- -79, -86, -93, -98, -102, -104, -104, -100, -92, -81, -66, -47, -28, -10, 10, 27,
- 40, 53, 61, 63, 59, 49, 34, 18, -1, -18, -34, -47, -58, -63, -66, -64,
- -56, -46, -31, -14, 2, 18, 35, 48, 59, 70, 78, 84, 89, 91, 90, 87,
- 83, 78, 74, 71, 67, 63, 59, 54, 49, 42, 35, 27, 18, 9, 1, -6,
- -12, -17, -23, -29, -36, -46, -55, -64, -73, -82, -89, -95, -100, -102, -104, -103,
- -97, -88, -76, -60, -41, -23, -4, 15, 31, 44, 55, 62, 62, 57, 46, 30,
- 13, -5, -22, -37, -50, -59, -64, -66, -62, -55, -43, -28, -11, 5, 22, 37,
- 50, 61, 71, 79, 85, 89, 91, 89, 87, 82, 77, 73, 70, 66, 63, 59,
- 53, 47, 41, 33, 24, 16, 7, -1, -8, -14, -19, -25, -32, -40, -49, -58,
- -67, -76, -84, -91, -96, -101, -103, -104, -102, -95, -85, -72, -55, -37, -18, 1,
- 19, 34, 47, 57, 62, 62, 56, 43, 28, 10, -8, -25, -39, -52, -60, -65,
- -66, -62, -53, -42, -25, -9, 8, 24, 39, 51, 62, 72, 80, 86, 90, 90,
- 89, 86, 82, 77, 73, 70, 66, 62, 58, 53, 47, 40, 33, 24, 15, 6,
- -2, -8, -14, -19, -25, -32, -40, -49, -58, -67, -72, -103, -18, -76, 0, 0,
- 0, 0, 1, 2, 3, 5, 6, 0, -7, -8, -15, -9, 10, 8, 17, 33,
- 14, 5, 38, 44, 31, 63, 70, 51, 73, 82, 68, 85, 100, 96, 97, 103,
- 115, 114, 112, 127, 122, 110, 116, 113, 109, 120, 120, 118, 113, 91, 93, 109,
- 97, 98, 115, 110, 109, 120, 112, 94, 75, 63, 69, 72, 64, 64, 59, 45,
- 39, 36, 35, 42, 42, 24, 5, 2, 3, 4, 7, 9, 11, 14, 17, 19,
- 14, -3, -20, -26, -30, -26, -24, -31, -32, -34, -40, -39, -33, -34, -45, -56,
- -60, -66, -64, -55, -60, -62, -56, -59, -58, -50, -56, -70, -73, -76, -86, -77,
- -70, -80, -76, -71, -77, -71, -66, -76, -85, -82, -90, -95, -80, -82, -92, -85,
- -86, -94, -85, -79, -86, -92, -90, -94, -101, -92, -85, -90, -84, -77, -78, -74,
- -73, -85, -86, -85, -95, -85, -77, -90, -88, -83, -94, -93, -83, -81, -81, -86,
- -89, -89, -94, -88, -77, -77, -71, -59, -58, -59, -63, -72, -74, -77, -73, -61,
- -67, -72, -67, -73, -80, -74, -68, -60, -56, -65, -70, -67, -72, -66, -52, -49,
- -40, -27, -27, -32, -39, -47, -50, -42, -30, -31, -34, -32, -38, -46, -46, -43,
- -35, -20, -16, -24, -30, -30, -31, -24, -13, -6, 4, 13, 11, 3, -5, -9,
- -2, 12, 15, 15, 16, 9, 3, -2, -5, -1, 12, 24, 30, 29, 20, 17,
- 22, 25, 30, 41, 47, 49, 46, 37, 32, 41, 52, 54, 60, 61, 52, 48,
- 45, 36, 35, 43, 51, 60, 67, 69, 60, 57, 63, 63, 64, 73, 75, 72,
- 69, 63, 67, 78, 78, 82, 89, 80, 73, 76, 67, 60, 64, 67, 73, 79,
- 83, 88, 82, 75, 80, 81, 77, 83, 83, 76, 74, 77, 83, 85, 86, 94,
- 89, 80, 82, 78, 69, 68, 68, 69, 78, 80, 81, 90, 83, 73, 79, 77,
- 70, 73, 70, 62, 65, 73, 75, 76, 84, 82, 70, 71, 69, 59, 57, 54,
- 48, 53, 63, 64, 68, 76, 66, 57, 58, 51, 42, 40, 33, 28, 37, 46,
- 49, 55, 56, 42, 37, 37, 27, 22, 20, 10, 4, 8, 15, 24, 30, 31,
- 24, 14, 8, -3, -14, -21, -26, -26, -15, -4, -1, -4, -13, -21, -26, -34,
- -39, -42, -50, -57, -63, -66, -60, -47, -43, -48, -51, -57, -66, -75, -82, -88,
- -91, -88, -78, -74, -81, -86, -85, -92, -101, -100, -102, -109, -109, -110, -112, -113,
- -115, -109, -106, -113, -113, -107, -110, -110, -106, -108, -112, -109, -110, -114, -111, -98,
- -95, -98, -93, -93, -98, -94, -89, -81, -69, -65, -71, -73, -73, -77, -73, -62,
- -56, -48, -40, -41, -45, -47, -47, -37, -20, -11, -4, 5, 4, 3, 6, 9,
- 16, 30, 39, 47, 51, 44, 40, 45, 47, 50, 59, 64, 66, 68, 65, 65,
- 75, 80, 78, 87, 95, 91, 93, 98, 96, 98, 104, 100, 96, 99, 104, 101,
- 100, 106, 107, 105, 108, 109, 109, 110, 111, 110, 101, 87, 82, 84, 81, 82,
- 88, 89, 90, 91, 85, 71, 57, 49, 48, 51, 52, 55, 59, 58, 58, 60,
- 61, 61, 57, 42, 24, 14, 7, 5, 9, 11, 15, 20, 21, 19, 11, -3,
- -18, -27, -33, -31, -25, -24, -21, -16, -16, -14, -11, -17, -29, -40, -49, -59,
- -61, -55, -54, -52, -45, -42, -41, -41, -48, -59, -65, -72, -81, -79, -72, -73,
- -69, -62, -61, -59, -60, -69, -76, -79, -87, -92, -84, -81, -82, -76, -72, -71,
- -67, -66, -72, -79, -81, -87, -94, -92, -87, -86, -82, -76, -75, -75, -78, -85,
- -87, -91, -96, -91, -82, -83, -80, -74, -74, -71, -64, -64, -68, -73, -77, -81,
- -87, -88, -82, -79, -76, -70, -69, -72, -76, -80, -84, -87, -82, -71, -67, -64,
- -58, -57, -55, -49, -43, -39, -40, -47, -54, -58, -64, -66, -61, -58, -54, -49,
- -50, -55, -59, -63, -65, -58, -45, -38, -32, -25, -24, -23, -18, -13, -5, 3,
- 4, -2, -11, -17, -23, -26, -23, -20, -18, -15, -18, -24, -28, -28, -21, -7,
- 3, 11, 18, 20, 19, 22, 24, 30, 40, 47, 51, 49, 40, 32, 28, 24,
- 23, 25, 25, 23, 20, 15, 15, 23, 34, 43, 51, 59, 59, 58, 59, 58,
- 60, 67, 73, 78, 84, 85, 78, 71, 68, 63, 60, 60, 57, 53, 50, 50,
- 56, 65, 70, 76, 84, 84, 81, 81, 79, 76, 79, 84, 87, 91, 96, 98,
- 94, 88, 85, 81, 76, 73, 70, 66, 66, 70, 76, 80, 84, 91, 92, 87,
- 86, 83, 78, 76, 78, 81, 85, 88, 91, 96, 93, 86, 83, 78, 71, 68,
- 64, 61, 64, 71, 74, 78, 84, 86, 80, 76, 72, 64, 59, 56, 55, 59,
- 66, 69, 74, 79, 76, 69, 64, 57, 48, 43, 39, 39, 45, 52, 56, 62,
- 63, 55, 47, 41, 31, 21, 15, 8, 5, 9, 16, 24, 31, 35, 33, 26,
- 19, 10, 0, -6, -9, -7, -7, -13, -17, -22, -26, -31, -34, -37, -40, -42,
- -44, -46, -48, -50, -51, -54, -56, -58, -61, -64, -67, -70, -74, -78, -82, -86,
- -90, -93, -97, -99, -102, -104, -106, -108, -109, -110, -111, -112, -113, -113, -114, -114,
- -115, -115, -115, -115, -115, -114, -113, -111, -109, -107, -104, -100, -97, -93, -90, -87,
- -84, -82, -80, -78, -76, -74, -73, -71, -69, -67, -65, -61, -58, -53, -48, -42,
- -35, -28, -21, -13, -6, 1, 8, 15, 21, 26, 31, 35, 38, 41, 44, 46,
- 48, 50, 52, 55, 58, 61, 64, 68, 72, 76, 80, 83, 87, 90, 92, 94,
- 96, 98, 99, 100, 101, 102, 102, 103, 103, 103, 103, 104, 103, 103, 103, 102,
- 101, 99, 97, 94, 92, 88, 85, 81, 78, 74, 71, 67, 64, 61, 58, 55,
- 53, 51, 49, 47, 46, 44, 42, 40, 37, 34, 30, 26, 22, 17, 12, 8,
- 3, -1, -5, -9, -13, -16, -20, -23, -26, -29, -31, -33, -35, -37, -38, -40,
- -42, -44, -46, -48, -51, -54, -56, -59, -61, -64, -65, -67, -69, -70, -72, -74,
- -75, -77, -78, -80, -81, -82, -83, -84, -85, -86, -86, -87, -88, -89, -90, -90,
- -91, -92, -92, -92, -92, -92, -92, -91, -91, -92, -92, -92, -93, -93, -94, -94,
- -94, -95, -95, -95, -95, -95, -95, -95, -95, -95, -94, -93, -92, -91, -90, -89,
- -87, -86, -85, -85, -85, -84, -84, -85, -85, -85, -85, -85, -85, -85, -85, -85,
- -84, -83, -82, -81, -79, -77, -75, -73, -70, -68, -65, -63, -62, -60, -59, -59,
- -59, -59, -59, -59, -59, -60, -59, -59, -59, -58, -57, -55, -53, -50, -47, -44,
- -40, -36, -32, -29, -25, -22, -20, -18, -17, -16, -15, -15, -16, -16, -16, -16,
- -16, -16, -15, -13, -11, -9, -6, -2, 2, 6, 10, 15, 19, 22, 26, 29,
- 31, 33, 35, 36, 36, 36, 36, 35, 35, 35, 35, 35, 36, 38, 40, 42,
- 45, 48, 52, 55, 58, 61, 64, 67, 70, 72, 73, 74, 75, 76, 76, 76,
- 75, 75, 74, 74, 74, 74, 74, 75, 77, 78, 80, 82, 83, 85, 87, 89,
- 90, 91, 92, 93, 94, 94, 94, 94, 94, 93, 93, 92, 91, 91, 90, 90,
- 90, 90, 91, 91, 92, 92, 93, 93, 94, 94, 94, 94, 94, 94, 94, 94,
- 93, 93, 92, 92, 91, 90, 89, 88, 87, 87, 86, 86, 85, 85, 85, 84,
- 84, 83, 83, 82, 81, 80, 79, 78, 77, 77, 76, 75, 74, 72, 71, 70,
- 68, 67, 65, 64, 63, 61, 60, 58, 57, 55, 53, 50, 48, 45, 43, 40,
- 38, 36, 34, 32, 30, 29, 27, 25, 23, 21, 19, 17, 14, 12, 9, 6,
- 3, 0, -4, -8, -12, -17, -21, -25, -29, -33, -36, -39, -42, -45, -47, -49,
- -51, -53, -55, -58, -60, -63, -65, -68, -71, -74, -77, -81, -84, -87, -91, -94,
- -97, -99, -102, -104, -105, -107, -108, -109, -110, -111, -111, -112, -112, -113, -113, -113,
- -113, -113, -113, -112, -111, -109, -107, -105, -102, -99, -96, -93, -90, -87, -84, -82,
- -79, -77, -75, -73, -70, -69, -66, -64, -60, -58, -53, -49, -44, -39, -32, -27,
- -19, -14, -8, -3, 3, 11, 22, 10, 8, 1, 1, 1, 1, 1, 2, 2,
- 2, 2, 3, 3, 3, 3, 4, 4, 5, 5, 6, 5, 6, 6, 6, 6,
- 6, 6, 7, 5, 7, 5, 6, 4, 6, 4, 4, 4, 4, 3, 3, 2,
- 3, 1, 3, -2, 2, 0, 0, 0, 0, -2, -1, -2, -3, -3, 0, -5,
- -1, -2, -2, -2, -1, 0, -3, -1, -1, 0, 1, -1, 0, -1, 0, 0,
- 1, 0, 0, 1, -1, 1, -1, 1, -2, -1, -3, 0, -2, -1, -2, -2,
- -2, -3, -2, -3, -4, -5, -6, -5, -9, -8, -9, -9, -9, -11, -10, -13,
- -14, -14, -15, -16, -15, -17, -19, -19, -21, -18, -21, -20, -22, -20, -24, -21,
- -22, -19, -20, -21, -17, -19, -16, -17, -15, -17, -13, -11, -10, -7, -5, -3,
- 2, 6, 4, 8, 9, 18, 14, 31, 25, 24, 25, 24, 21, 13, 15, 15,
- 11, 9, 1, 4, -20, -18, -38, -44, -57, -57, -55, -55, -52, -55, -46, -47,
- -40, -32, -26, -19, -16, -2, 3, 13, 19, 28, 30, 37, 40, 44, 39, 38,
- 35, 34, 37, 41, 48, 51, 53, 58, 61, 70, 74, 76, 76, 80, 81, 86,
- 83, 83, 78, 78, 73, 69, 65, 55, 47, 40, 36, 29, 23, 16, 14, 8,
- -2, -4, -11, -11, -19, -22, -26, -25, -34, -39, -40, -41, -45, -49, -51, -57,
- -56, -58, -59, -66, -70, -70, -72, -65, -64, -59, -53, -49, -45, -34, -29, -21,
- -15, -10, -6, -6, -3, -4, 2, 3, 3, 3, -1, -3, -11, -11, -13, -16,
- -22, -24, -27, -32, -34, -37, -35, -31, -30, -26, -25, -22, -21, -15, -13, -15,
- -10, -12, -12, -7, 2, 15, 22, 27, 24, 28, 22, 22, 21, 22, 17, 13,
- 14, 9, 5, 2, -8, -12, -16, -14, -17, -17, -17, -17, -14, -8, -3, -3,
- 0, 5, 3, 5, 6, 3, -2, -6, -9, -11, -13, -18, -19, -29, -42, -61,
- -72, -79, -81, -83, -82, -79, -76, -65, -54, -42, -33, -24, -14, 0, 18, 33,
- 48, 62, 75, 87, 93, 99, 100, 102, 102, 104, 102, 100, 100, 96, 93, 95,
- 96, 105, 109, 112, 111, 110, 106, 106, 104, 102, 97, 93, 85, 80, 71, 60,
- 48, 36, 26, 12, 0, -5, -13, -21, -28, -31, -36, -42, -49, -53, -56, -59,
- -61, -63, -64, -64, -63, -67, -70, -77, -75, -77, -78, -79, -80, -81, -80, -75,
- -69, -64, -57, -50, -43, -35, -26, -16, -6, 6, 13, 17, 22, 26, 25, 27,
- 27, 26, 23, 19, 11, 5, -5, -12, -19, -24, -31, -37, -42, -45, -50, -49,
- -48, -47, -43, -41, -38, -38, -37, -35, -35, -37, -42, -40, -33, -27, -20, -12,
- -11, -13, -10, -9, -10, -10, -10, -13, -11, -9, -8, -11, -13, -16, -18, -17,
- -15, -15, -14, -12, -8, -3, 3, 8, 16, 22, 25, 31, 34, 36, 36, 34,
- 31, 25, 23, 24, 26, 23, 13, -1, -16, -29, -38, -45, -51, -56, -57, -54,
- -48, -39, -34, -29, -20, -10, 0, 13, 27, 39, 54, 68, 79, 87, 92, 94,
- 96, 94, 92, 89, 87, 82, 76, 72, 71, 74, 76, 81, 83, 83, 84, 84,
- 85, 85, 82, 81, 82, 80, 75, 71, 66, 57, 46, 34, 24, 15, 5, -2,
- -8, -13, -19, -26, -31, -37, -41, -44, -48, -53, -54, -53, -54, -54, -57, -61,
- -64, -67, -70, -72, -75, -77, -79, -79, -76, -73, -70, -63, -58, -53, -47, -38,
- -29, -21, -13, -6, 0, 4, 7, 7, 8, 8, 6, 5, -1, -8, -15, -22,
- -30, -36, -41, -47, -51, -54, -56, -58, -59, -56, -50, -45, -42, -37, -31, -26,
- -23, -23, -23, -24, -21, -14, -6, 2, 8, 12, 15, 18, 21, 20, 20, 20,
- 20, 21, 23, 22, 18, 13, 10, 8, 6, 5, 4, 3, 2, 2, 4, 7,
- 10, 13, 18, 22, 24, 26, 28, 27, 21, 14, 8, 5, 4, 2, -3, -12,
- -24, -37, -50, -59, -67, -76, -80, -79, -75, -69, -61, -55, -47, -38, -27, -15,
- -2, 11, 27, 43, 58, 71, 82, 90, 94, 96, 98, 98, 98, 95, 89, 84,
- 81, 79, 81, 85, 88, 89, 91, 92, 92, 90, 89, 89, 88, 85, 82, 79,
- 75, 67, 58, 48, 37, 25, 14, 4, -4, -10, -17, -24, -31, -37, -42, -47,
- -51, -56, -59, -59, -59, -59, -61, -63, -65, -67, -70, -72, -74, -76, -78, -78,
- -78, -75, -70, -66, -61, -56, -50, -41, -33, -23, -14, -6, 2, 10, 16, 19,
- 21, 23, 24, 24, 22, 19, 13, 7, 0, -6, -14, -20, -25, -27, -32, -37,
- -39, -39, -38, -36, -33, -30, -27, -22, -19, -19, -20, -23, -24, -22, -18, -13,
- -8, -4, 0, 2, 5, 6, 5, 3, 2, 4, 6, 6, 5, 1, -2, -6,
- -8, -9, -10, -11, -13, -12, -12, -11, -9, -4, 0, 4, 8, 13, 18, 20,
- 19, 14, 10, 6, 4, 4, 4, 0, -8, -17, -28, -38, -49, -60, -68, -72,
- -72, -70, -65, -59, -54, -46, -37, -27, -17, -5, 8, 22, 37, 51, 66, 77,
- 84, 88, 91, 93, 94, 94, 91, 85, 79, 75, 74, 76, 77, 80, 83, 85,
- 85, 85, 86, 86, 85, 85, 85, 83, 81, 77, 70, 64, 55, 44, 32, 22,
- 13, 6, -1, -9, -16, -22, -27, -32, -38, -43, -46, -47, -47, -47, -48, -49,
- -49, -50, -52, -54, -56, -59, -62, -64, -66, -65, -64, -61, -59, -56, -53, -48,
- -41, -33, -25, -17, -10, -2, 4, 9, 13, 15, 16, 17, 17, 15, 11, 7,
- 1, -7, -15, -22, -27, -33, -38, -43, -47, -49, -50, -50, -49, -46, -42, -37,
- -31, -28, -28, -29, -30, -29, -26, -22, -17, -13, -8, -3, 2, 6, 7, 6,
- 5, 6, 8, 10, 12, 11, 8, 5, 3, 1, -1, -2, -3, -4, -6, -7,
- -6, -3, 0, 1, 5, 10, 16, 20, 21, 19, 15, 10, 8, 6, 6, 4,
- 0, -5, -12, -22, -33, -45, -57, -65, -70, -72, -70, -68, -64, -58, -51, -44,
- -36, -24, -13, -2, 11, 27, 43, 58, 70, 78, 83, 88, 92, 96, 97, 93,
- 89, 85, 81, 80, 81, 83, 86, 88, 90, 91, 91, 91, 91, 91, 91, 91,
- 89, 86, 83, 79, 72, 63, 52, 41, 30, 21, 13, 4, -5, -11, -17, -23,
- -31, -38, -44, -47, -49, -50, -52, -54, -55, -57, -57, -58, -60, -63, -66, -69,
- -72, -74, -73, -72, -70, -69, -67, -64, -59, -53, -45, -37, -30, -22, -14, -7,
- -2, 3, 8, 10, 12, 12, 13, 12, 8, 3, -4, -10, -16, -21, -27, -33,
- -37, -41, -44, -46, -48, -48, -45, -48, -43, -37, -33, -31, -32, -33, -32, -29,
- -26, -22, -18, -12, -5, 1, 6, 9, 9, 9, 9, 11, 14, 16, 16, 14,
- 12, 8, 5, 3, 2, 1, -1, -3, -4, -4, -2, -1, 2, 5, 11, 18,
- 24, 27, 27, 24, 20, 17, 15, 13, 11, 9, 5, -1, -10, -22, -35, -49,
- -61, -70, -75, -77, -76, -73, -69, -63, -56, -47, -36, -25, -13, 0, 16, 34,
- 52, 67, 79, 88, 95, 101, 106, 109, 108, 105, 100, 95, 92, 90, 91, 93,
- 96, 99, 100, 101, 101, 101, 101, 101, 101, 100, 97, 95, 91, 85, 78, 67,
- 55, 43, 31, 21, 11, 1, -7, -14, -21, -29, -37, -45, -51, -54, -56, -58,
- -60, -62, -64, -65, -66, -67, -69, -72, -76, -80, -82, -84, -83, -82, -80, -79,
- -77, -73, -67, -60, -51, -42, -34, -25, -16, -8, -2, 4, 9, 12, 13, 14,
- 14, 13, 9, 3, -5, -12, -18, -25, -31, -37, -42, -47, -50, -53, -54, -53,
- -48, -41, -36, -32, -31, -31, -32, -31, -28, -25, -22, -17, -12, -5, 1, 1,
- -2, -1, -9, -9, -6, 5, 6, -1, -10, 8, 24, 11, -2, -14, -9, -15,
- -13, 5, 14, 12, -6, -1, -12, 1, -9, 12, 12, 10, 5, -19, -11, -13,
- -2, 8, 5, 1, -2, -3, 9, -6, 6, 5, 6, -3, -17, -7, 3, 2,
- -1, 0, 7, -7, 5, 4, 6, -18, -24, 6, 20, -1, -4, -1, 10, 3,
- -10, 8, 7, -11, -17, -15, 5, 18, 4, 1, 8, -16, -4, 0, 11, 9,
- -10, -15, 0, -22, -12, 19, 34, 16, -9, -16, -7, -12, -10, 13, 23, -1,
- -10, -2, -3, -11, 13, 7, -6, -9, 3, 11, -10, -18, 12, 22, 7, -27,
- -29, -4, 20, 20, 10, 8, -16, -26, -6, 22, 21, 7, 15, 8, -50, -50,
- -7, 35, 22, -13, 32, 41, -33, -46, -10, 23, -7, -25, 23, 21, -38, -36,
- 14, 44, 2, 2, 34, -14, -51, -29, 11, 19, 7, 22, 13, -23, -21, -8,
- -9, 1, 14, 26, 26, -8, -34, -33, 4, 1, -6, -2, 16, -7, -23, 12,
- 27, 5, 6, 6, 0, -8, 0, -1, -17, -13, -12, 3, 9, 4, 11, 23,
- 36, 0, -43, -16, 4, -21, -26, 27, 16, -25, 3, 65, 4, -34, 24, -10,
- -38, -14, 13, 4, -15, 36, 44, -42, -51, 20, -5, -6, 68, 20, -18, -39,
- -11, 9, 17, 6, -33, -20, -13, 48, 30, 22, -4, -9, -53, -20, 32, 32,
- -16, 17, -11, -36, -8, -5, 39, 28, 33, 21, -64, -48, 3, -22, 15, 62,
- -26, 0, 3, 5, 73, -14, -48, -20, -59, 4, 70, 60, -7, -2, -88, -22,
- -17, 39, 17, 33, -3, 15, 28, -47, -80, -37, 5, 7, 104, 16, -99, -92,
- -36, 109, 78, 26, -15, -92, -21, 62, 48, -51, -81, -25, 55, 63, 35, 21,
- -115, -54, 101, 73, -41, -110, -66, 50, 107, 45, -8, -109, -38, 12, 102, 3,
- 17, -45, -2, -36, 39, 46, -12, -28, -27, -17, 17, -18, 82, -5, -3, -25,
- -5, -14, 15, 9, -3, -17, -6, 2, 7, -36, -13, 6, 21, -23, -20, 16,
- -18, 3, -2, 26, 0, 13, -23, -2, -19, -28, -18, 15, 12, 22, -4, 23,
- -17, -22, -9, -18, -4, 11, 13, 0, 34, -16, -20, 26, 23, 15, -4, -25,
- 7, 8, -9, 8, 44, 1, -40, 17, -32, 9, -30, -52, 52, 3, 2, -21,
- 83, 58, -14, -46, -61, -12, -67, -20, 64, 72, 57, -10, 5, 1, -77, 31,
- -47, -39, 12, 22, 57, 28, 0, 9, -76, 15, -74, 33, -12, 39, 114, -35,
- -36, -38, -23, 27, -21, 14, 56, 47, 6, -72, -61, -4, 18, -4, 19, 13,
- 45, 71, 48, -1, -125, -52, -56, -20, -18, -12, 51, 78, 68, -46, 32, -40,
- -29, -28, -81, -25, 75, 42, 58, -38, 1, -29, -34, 31, -36, -14, 10, 64,
- 37, 2, -31, -72, -17, -33, 30, -52, -54, 25, 43, 70, 81, -9, -73, 4,
- -65, 15, -28, 25, 0, 28, 19, 51, -26, 6, 0, -37, -15, -22, -20, -16,
- -5, 50, 56, 67, 25, 16, -35, -29, -14, -39, 19, -24, -52, -13, -32, -10,
- 39, 33, 59, 6, 37, 55, 11, -9, -35, -15, -57, -56, -36, -34, 19, 19,
- 6, 20, 17, -11, 5, 26, 19, 16, 7, -20, -26, -55, -62, -36, -18, 19,
- 37, 47, 25, -6, -14, 1, -4, -13, 12, 23, 34, 38, 41, 33, 31, -10,
- -56, -52, -49, -31, -40, -21, -12, 0, 5, 12, 22, 22, 21, 31, 12, 2,
- -8, -4, -18, -7, 3, 1, -1, 11, 12, 18, 17, 9, -2, -12, -13, -11,
- -1, 8, 3, 3, 2, 5, -5, -16, -15, -13, -8, -12, -9, -2, -1, 2,
- 7, 10, 7, 11, 14, 7, -1, -4, 5, -3, -2, 0, -6, -10, -1, -5,
- 3, 9, 0, -8, -9, -6, -6, 0, 6, 3, 6, 7, 10, 0, -8, -3,
- -5, -1, -8, -7, -4, -3, -3, 0, -1, -6, 2, 7, 7, 5, 4, 10,
- 5, 8, -1, -11, -15, -11, -15, -10, -1, -8, -12, -5, 1, 3, 6, 8,
- 11, 18, 22, 26, 10, -10, -1, -15, -3, -21, -16, -14, -12, -7, -8, -18,
- -20, -11, 9, 20, 27, 26, 11, 1, 21, 6, 3, -9, -15, -9, -20, 3,
- 5, 21, 14, 6, 11, -21, -22, -6, -21, -23, -18, 11, 6, 5, 21, 9,
- 23, 16, -3, -30, -7, -27, -4, 5, 18, 22, 16, 2, 7, -1, -2, -10,
- -14, -10, -17, -10, -15, -16, 3, 12, 30, 18, -1, -6, -15, -3, 5, 11,
- -18, -2, 8, 21, 11, -13, -4, -30, -7, 0, 12, 25, -3, 17, 14, -20,
- -6, -27, -41, -11, -12, 23, -8, 13, 24, 18, 27, -11, -8, -12, -2, 17,
- 23, 13, -20, -21, -2, -21, -34, -46, -23, 28, 48, 9, -10, 8, 29, 27,
- 5, -29, -12, 13, -5, -2, -35, 1, 3, 24, 13, 17, -18, -30, -21, 14,
- -1, 6, -8, 48, 45, -7, -34, -49, -32, -6, -26, 20, 29, 76, 30, -21,
- -66, -36, -15, 40, -5, 29, 3, 10, -39, -25, -2, 24, 19, 19, -4, -8,
- 3, -22, -23, -18, 13, 17, -3, -25, 23, 66, 26, -18, -27, -34, -30, -30,
- 36, 25, 28, -22, -17, -7, -22, 21, 18, 42, 8, -25, -28, -31, -10, 15,
- 18, 0, -1, -5, 16, -12, 13, 13, 12, -8, -37, -9, 13, -5, 8, -3,
- 13, -8, 4, 24, -16, -43, -18, 26, 26, -11, -9, 19, 9, -15, 9, 15,
- -12, -31, -27, 8, 29, 5, 7, 17, -33, -14, 14, 23, -1, -18, -18, -4,
- -35, -17, 47, 71, -16, -20, -11, -16, -25, 6, 37, 14, -18, 1, -8, -14,
- 10, 14, 2, -20, 0, 20, -10, -25, 14, 32, 7, -39, -38, -3, 34, 25,
- 13, 3, -24, -34, 5, 38, 18, 7, 29, -30, -74, -41, 36, 40, -12, 26,
- 55, -17, -59, -26, 28, -2, -31, 24, 25, -44, -39, 21, 44, -1, 10, 33,
- -34, -50, -12, 18, 13, 20, 17, -6, -31, -10, -6, -1, 7, 12, 14, 6,
- -16, -24, 6, 9, -16, -16, 6, 2, -10, 13, 12, -10, 0, 11, 11, 10,
- -3, -22, -22, -12, -7, 19, 17, -2, -12, 6, 16, 7, -11, -1, -20, -22,
- -8, 26, 16, -3, 12, 1, -33, 2, 30, -23, -5, 28, -17, -19, 21, 9,
- -28, -14, 25, -1, 4, 24, 0, -26, -9, 7, 2, -2, 20, -10, -11, 5,
- -3, -4, 8, -9, 14, 18, 25, -22, -15, -22, -3, -12, 27, 30, 15, -11,
- -26, -4, 15, -7, -14, 23, -23, -4, 34, -2, -38, 14, -11, -24, 16, 34,
- 11, -13, 3, -3, -19, -34, 0, -3, 24, 43, 1, -12, -38, -25, -11, 23,
- 35, 12, -28, -25, -16, 7, 22, 1, -10, 8, 8, -3, 6, -24, -20, -13,
- 9, 31, 12, -16, 7, -29, 5, 8, -28, 3, 4, 12, 26, -9, -15, -5,
- -20, 9, 21, 0, 1, -9, 0, 8, -3, -7, -9, -3, 22, 8, 3, -11,
- -9, -11, 3, 15, 9, -10, 1, -3, -3, -2, -5, 9, 0, 12, 7, -15,
- -7, 0, -8, 5, 9, -5, 7, -7, 10, 4, -11, -2, -8, -4, 9, 9,
- 0, -2, -11, -3, -4, 3, 4, 3, -2, 3, 3, -8, -9, -2, 0, 3,
- 5, -1, -10, -7, 2, 8, 3, 0, -5, -5, 2, 4, -2, -5, -3, 2,
- 3, 0, 2, -5, -3, 3, 2, -2, -4, -2, 1, 2, 1, 0, 0, 0,
- 0, -1, -7, -9, -5, 0, 2, 2, 5, 6, 0, -11, -13, -5, 3, 1,
- 0, 0, 1, -3, -9, -6, -1, 5, 3, -3, -5, -3, -1, -4, -3, -1,
- 2, -2, -9, -7, -2, -5, -18, -31, -36, -36, -41, -38, -29, -21, -27, -31,
- -26, -4, 37, 65, 67, 44, 22, 10, 2, -4, 8, 32, 44, 38, 24, 17,
- 9, 4, 3, 12, 26, 32, 32, 23, 16, 7, 1, -7, -13, -8, 1, -5,
- -39, -72, -79, -64, -49, -40, -24, -1, 12, 0, -25, -44, -43, -30, -14, 1,
- 13, 13, 4, 4, 16, 34, 46, 55, 65, 73, 67, 53, 54, 58, 62, 60,
- 51, 38, 33, 20, -7, -27, -40, -46, -55, -58, -41, -9, 7, 8, 2, -26,
- -49, -71, -92, -101, -93, -80, -70, -71, -73, -65, -67, -69, -61, -42, -15, 15,
- 18, -5, -33, -54, -54, -40, -18, 2, 21, 21, 3, -28, -52, -33, 9, 35,
- 33, 30, 34, 45, 46, 43, 54, 63, 65, 61, 56, 43, 45, 59, 77, 96,
- 104, 112, 115, 100, 78, 53, 22, -3, -6, 5, 24, 37, 38, 35, 25, 3,
- -19, -38, -51, -46, -33, -34, -42, -47, -48, -38, -27, -30, -40, -48, -45, -30,
- -24, -38, -44, -43, -47, -34, -13, 7, 27, 30, 9, -18, -38, -22, 19, 47,
- 70, 83, 68, 28, -13, -41, -41, -19, -1, 10, 8, 4, 4, -7, -12, 6,
- 32, 42, 31, 0, -39, -71, -99, -115, -111, -85, -56, -46, -61, -74, -66, -45,
- -22, 4, 21, 27, 25, 1, -30, -51, -37, 4, 37, 40, 26, 17, 12, 12,
- 5, 1, 2, 12, 29, 43, 44, 45, 54, 45, 28, 10, 13, 26, 32, 43,
- 59, 67, 62, 60, 66, 72, 61, 34, 11, 0, 1, -6, -18, -12, 19, 47,
- 51, 32, 9, -8, -22, -26, -27, -30, -29, -12, 7, 18, 13, -1, -11, -11,
- 5, 16, 14, 11, 5, -19, -47, -54, -29, 13, 37, 42, 33, 9, -17, -31,
- -21, 14, 61, 81, 68, 39, 4, -26, -46, -38, -17, -1, 1, -4, -14, -25,
- -23, -4, 24, 43, 49, 37, 4, -48, -97, -123, -116, -89, -66, -65, -73, -67,
- -64, -66, -69, -46, 3, 36, 27, -3, -25, -39, -38, -39, -36, -24, -9, 5,
- 13, 13, 4, -1, -13, -15, 0, 22, 47, 65, 76, 67, 35, 3, -4, 6,
- 27, 47, 58, 68, 72, 73, 72, 66, 59, 62, 61, 49, 28, -5, -30, -27,
- 9, 40, 51, 46, 40, 28, 1, -30, -56, -57, -41, -13, 5, 12, 7, -11,
- -38, -54, -40, -16, 12, 23, 13, -16, -49, -62, -55, -29, 4, 38, 45, 28,
- -5, -36, -36, -5, 39, 68, 77, 73, 55, 8, -35, -46, -29, -15, -15, -16,
- -12, -9, -23, -30, -18, 16, 48, 51, 24, -18, -45, -72, -96, -111, -101, -80,
- -67, -71, -79, -77, -70, -46, -22, -7, -4, -5, -4, -2, -15, -37, -43, -42,
- -27, -5, 9, 27, 38, 27, 4, -14, -15, 6, 30, 61, 93, 90, 52, 16,
- 2, 1, 5, 11, 34, 64, 79, 71, 48, 35, 43, 61, 59, 46, 27, 1,
- -22, -33, -25, -9, 15, 37, 56, 54, 28, -10, -44, -58, -49, -27, -8, 20,
- 29, 0, -42, -66, -60, -34, -7, 16, 30, 15, -20, -50, -64, -49, -11, 21,
- 34, 34, 17, -7, -31, -29, 3, 43, 69, 78, 73, 45, 10, -20, -32, -33,
- -26, -12, -6, -18, -41, -44, -27, -6, 10, 17, 19, 18, -4, -49, -87, -108,
- -100, -84, -87, -93, -83, -67, -54, -45, -45, -35, -23, -13, 6, 17, 14, 1,
- -22, -40, -35, -18, 2, 28, 57, 63, 33, -7, -21, -4, 23, 57, 89, 102,
- 94, 68, 37, 8, -4, 4, 37, 71, 88, 79, 54, 46, 55, 62, 55, 53,
- 54, 46, 20, -14, -40, -41, -16, 15, 44, 60, 59, 30, -21, -61, -70, -54,
- -26, 10, 29, 19, -16, -49, -63, -58, -33, 4, 29, 26, -1, -33, -49, -50,
- -34, -9, 16, 34, 34, 9, -20, -25, -9, 13, 29, 54, 87, 91, 56, 11,
- -12, -11, -12, -20, -22, -17, -11, -12, -22, -25, -15, 3, 19, 19, 9, -11,
- -38, -62, -76, -92, -107, -109, -95, -68, -53, -49, -49, -58, -63, -48, -25, -5,
- 12, 12, -7, -36, -56, -56, -32, 8, 50, 64, 36, 6, -10, -15, -11, 9,
- 47, 94, 118, 100, 58, 14, -3, 3, 19, 44, 72, 83, 78, 75, 66, 53,
- 45, 52, 66, 70, 52, 22, -8, -36, -36, -14, 21, 63, 84, 63, 14, -29,
- -55, -54, -42, -12, 28, 40, 14, -24, -52, -58, -42, -22, 6, 19, 16, -5,
- -34, -49, -43, -24, -12, 2, 14, 22, 10, -10, -20, -16, 3, 28, 60, 72,
- 61, 42, 25, 1, -26, -44, -46, -31, -25, -26, -32, -30, -24, -12, -12, -15,
- 0, 6, -3, -23, -47, -79, -112, -128, -115, -84, -61, -45, -42, -51, -64, -68,
- -61, -33, 9, 29, 12, -28, -54, -64, -56, -30, 9, 36, 41, 34, 10, -18,
- -38, -29, 13, 70, 105, 106, 79, 48, 31, 12, -1, 12, 51, 78, 89, 87,
- 75, 66, 49, 44, 56, 73, 79, 66, 23, -23, -42, -39, -9, 31, 65, 75,
- 52, 7, -32, -54, -57, -30, 3, 24, 19, 2, -18, -39, -50, -39, -10, 8,
- 10, -2, -12, -18, -21, -29, -33, -16, 11, 28, 17, 1, -4, 3, -3, -6,
- 13, 42, 64, 67, 56, 29, 2, -21, -36, -42, -40, -25, -15, -10, -7, -10,
- -27, -38, -24, 2, 19, 14, -6, -44, -86, -115, -121, -109, -81, -45, -27, -36,
- -58, -76, -81, -53, -13, 11, 8, -11, -24, -40, -58, -62, -30, 11, 42, 44,
- 17, -15, -36, -38, -22, 15, 53, 84, 88, 73, 52, 19, -6, -9, 13, 44,
- 71, 88, 93, 79, 54, 42, 46, 67, 82, 79, 54, 20, -10, -28, -27, 0,
- 46, 70, 61, 29, 2, -18, -38, -45, -23, 7, 16, 10, -8, -22, -26, -30,
- -32, -23, -13, -2, 6, -6, -15, -16, -18, -20, -9, 0, 2, 11, 19, 17,
- -2, -21, -12, 14, 33, 50, 65, 61, 43, 19, -17, -44, -50, -42, -21, 1,
- 11, 1, -31, -56, -45, -22, -1, 17, 18, -4, -44, -95, -126, -123, -95, -56,
- -36, -41, -51, -59, -68, -60, -38, -15, 5, 14, 7, -17, -47, -61, -37, 1,
- 27, 33, 24, 7, -13, -30, -43, -26, 13, 47, 70, 74, 68, 48, 12, -19,
- -14, 14, 46, 74, 81, 75, 64, 52, 48, 56, 67, 82, 78, 44, 9, -12,
- -20, -8, 18, 41, 57, 46, 23, 0, -23, -33, -21, -10, -10, -2, 3, 5,
- -2, -19, -33, -32, -24, -16, -11, -14, -6, 7, -2, -20, -25, -16, -6, 6,
- 17, 27, 22, 2, -10, -11, 0, 24, 51, 68, 79, 65, 25, -19, -49, -48,
- -30, -9, 8, 10, -12, -40, -57, -57, -34, -1, 25, 24, -7, -56, -95, -111,
- -102, -84, -69, -57, -44, -42, -59, -74, -71, -47, -17, 0, 3, -6, -21, -37,
- -38, -27, -6, 15, 23, 22, 12, -4, -23, -32, -26, 1, 36, 63, 82, 78,
- 46, 12, -1, 2, 20, 41, 64, 81, 79, 66, 59, 61, 67, 75, 76, 66,
- 49, 27, 5, -7, 2, 24, 41, 44, 38, 28, 13, -5, -19, -21, -17, -11,
- -2, 4, 4, -2, -14, -28, -32, -27, -21, -16, -13, -1, 6, -4, -21, -25,
- -17, -7, 6, 0, 0, -4, -4, -5, -8, -4, 3, 8, 6, 1, 1, 2,
- 3, 3, -2, -7, -11, -10, -5, -2, 4, 6, 0, -2, -5, -4, -4, -9,
- -9, -7, -11, -11, -10, -7, 4, 0, -4, -4, -1, 4, 0, -4, -3, -5,
- -6, -5, -4, 4, -1, 2, 11, 5, -13, -20, -30, -49, -50, -34, -22, -33,
- -27, -20, -17, 0, 34, 70, 73, 42, 3, -26, -37, -25, -1, 25, 48, 71,
- 75, 44, 22, 45, 69, 57, 44, 52, 58, 24, -23, -41, -50, -58, -67, -82,
- -66, -29, -29, -41, -34, -19, -4, -4, -1, 20, 50, 56, 35, 12, 4, -8,
- -15, 4, 28, 44, 46, 34, 17, 2, 0, 11, 28, 42, 22, -28, -51, -45,
- -34, -39, -37, -19, -17, -30, -32, -18, -4, 9, 19, 38, 35, 3, -24, -35,
- -40, -23, -11, -25, -47, -52, -51, -58, -61, -52, -47, -37, -17, -5, -5, -16,
- -31, -24, -11, -1, -3, -23, -40, -48, -40, -12, 15, 25, 17, -5, -2, 14,
- 21, 15, -12, -26, -18, -2, 28, 48, 55, 52, 42, 35, 35, 42, 38, 36,
- 40, 53, 55, 52, 44, 36, 49, 57, 56, 57, 55, 50, 39, 27, 31, 30,
- 15, 11, 12, 6, 4, 14, 28, 23, 1, -6, -17, -35, -44, -41, -33, -22,
- -9, -6, -12, -15, -13, -27, -29, -7, 14, -5, -55, -71, -49, -33, -37, -46,
- -33, -18, -43, -89, -96, -65, -23, 2, 8, 20, 24, -11, -50, -51, -12, 15,
- 4, 1, 20, 47, 53, 43, 52, 77, 98, 114, 110, 100, 88, 53, 10, -29,
- -55, -71, -83, -77, -58, -55, -57, -52, -48, -47, -46, -12, 34, 59, 52, 25,
- -10, -33, -21, 18, 49, 54, 46, 18, 13, 30, 41, 48, 54, 53, 44, 24,
- 1, -13, -25, -43, -38, -28, -35, -55, -71, -64, -40, -13, 10, 24, 38, 41,
- 21, -1, -11, 1, 15, 7, -6, -13, -39, -57, -64, -51, -20, -12, -24, -37,
- -30, -4, 17, 21, 12, -7, -16, -15, -7, 6, 1, -20, -34, -30, -1, 32,
- 44, 36, 22, 25, 21, 6, 1, -2, -13, -5, 19, 28, 24, 12, 11, 16,
- 19, 38, 54, 49, 38, 28, 28, 39, 52, 49, 32, 25, 33, 45, 49, 39,
- 40, 46, 20, -9, -6, 6, 1, -22, -29, 10, 48, 33, -17, -51, -55, -44,
- -49, -50, -36, -33, -57, -84, -71, -21, 11, 13, 4, -1, -8, -32, -45, -32,
- -10, 2, -13, -37, -39, -42, -57, -65, -63, -36, -11, 10, 33, 22, -12, -34,
- -28, -12, 2, 8, 6, -2, -4, 0, 10, 22, 36, 57, 82, 104, 122, 127,
- 109, 70, 17, -28, -45, -36, -20, -33, -68, -102, -114, -103, -76, -45, -20, -7,
- -11, -10, -2, 6, 0, -14, -5, 30, 48, 29, 3, -8, 10, 39, 67, 86,
- 83, 59, 32, 17, 32, 46, 40, 11, -29, -48, -57, -68, -69, -57, -43, -26,
- -13, -2, 1, 1, 3, 4, 8, 21, 20, 11, 3, -2, -6, -26, -39, -33,
- -34, -36, -28, -23, -27, -28, -17, -1, 0, -6, -10, -9, -7, -12, -26, -44,
- -54, -38, -16, 0, 18, 27, 17, -3, -18, -3, 19, 11, -9, -7, 10, 14,
- 5, 5, 18, 29, 29, 12, 16, 38, 43, 14, 2, 24, 55, 59, 33, 17,
- 24, 44, 65, 75, 77, 55, 15, -16, -20, 6, 31, 27, 17, 18, 19, 17,
- 7, 0, -5, -20, -22, -25, -49, -69, -73, -58, -45, -29, -4, 9, -1, -23,
- -51, -52, -24, -2, 11, 12, -16, -51, -75, -77, -67, -59, -59, -54, -35, -15,
- -9, -9, -9, -7, -8, -12, -1, 15, 22, 10, -14, -34, -28, -14, 11, 64,
- 113, 127, 117, 97, 87, 84, 68, 50, 37, 36, 24, -15, -58, -78, -84, -71,
- -40, -14, -12, -34, -48, -41, -14, 20, 37, 35, 16, -6, 1, 14, 15, 20,
- 23, 24, 38, 58, 69, 57, 40, 54, 73, 75, 65, 40, -3, -49, -68, -56,
- -42, -42, -53, -59, -44, -23, -9, -3, -11, -18, -13, -11, -5, 3, 13, 4,
- -25, -39, -22, -14, -16, -27, -38, -37, -42, -55, -51, -21, 8, 10, -8, -12,
- -4, -10, -39, -55, -38, -13, -4, -11, -15, -3, 15, 12, 2, 11, 28, 34,
- 15, -5, 3, 11, 6, 12, 25, 25, 13, 10, 15, 27, 48, 55, 38, 23,
- 17, 23, 32, 23, 32, 57, 75, 75, 52, 22, 10, 5, 12, 28, 33, 23,
- 2, -14, -4, 19, 30, 25, 15, 1, -27, -64, -78, -67, -49, -45, -48, -42,
- -31, -25, -40, -50, -39, -18, -4, 13, 19, 12, -10, -43, -59, -53, -47, -54,
- -61, -51, -20, -2, -12, -23, -25, -18, 5, 33, 51, 45, 16, -16, -46, -53,
- -38, -6, 33, 57, 74, 81, 75, 77, 89, 105, 114, 110, 83, 39, -6, -25,
- -28, -39, -48, -52, -55, -59, -67, -67, -57, -42, -23, -3, 10, 3, -19, -33,
- -30, -8, 20, 23, 2, -18, -17, 12, 40, 58, 65, 65, 66, 71, 64, 54,
- 38, 1, -41, -62, -47, -26, -31, -49, -55, -42, -21, -17, -19, -10, -2, -3,
- -10, -13, 2, 13, -10, -38, -27, 3, 8, -18, -46, -61, -65, -53, -36, -18,
- -5, -6, -14, -22, -18, -12, -19, -29, -28, -21, -10, -15, -24, -18, -4, 16,
- 23, 17, 14, 10, 9, 13, 15, 28, 35, 19, 4, 2, -2, 9, 34, 62,
- 66, 43, 13, -2, 15, 42, 50, 48, 51, 56, 56, 45, 44, 45, 48, 40,
- 33, 31, 27, 10, -10, -4, 16, 41, 52, 48, 31, -1, -36, -56, -50, -27,
- -14, -25, -43, -60, -67, -47, -31, -38, -47, -40, -17, 13, 32, 28, -10, -50,
- -68, -62, -40, -21, -20, -33, -58, -72, -63, -45, -28, -11, 18, 48, 42, 15,
- -14, -43, -54, -40, -15, 4, 2, -5, 0, 20, 55, 91, 113, 120, 109, 89,
- 77, 63, 43, 26, 20, 12, -13, -47, -69, -68, -53, -49, -49, -36, -28, -27,
- -27, -28, -12, 5, 1, -9, -2, 14, 10, -25, -39, -6, 21, 35, 41, 53,
- 73, 82, 74, 64, 54, 39, 9, -23, -37, -30, -22, -30, -52, -62, -54, -32,
- -9, 2, 5, -3, -17, -25, -17, -1, 13, 8, -7, -12, -7, -7, -21, -40,
- -51, -51, -38, -21, -16, -22, -29, -33, -23, -10, -2, -9, -24, -33, -33, -29,
- -21, -8, 3, 2, -10, -18, -11, 8, 26, 32, 27, 21, 14, 7, 1, 3,
- 12, 22, 35, 45, 43, 29, 13, 10, 20, 37, 54, 59, 45, 28, 28, 37,
- 48, 55, 60, 60, 43, 17, 0, -3, 9, 24, 31, 31, 28, 28, 26, 14,
- -5, -22, -31, -30, -21, -7, -8, -34, -63, -82, -80, -63, -45, -28, -14, -5,
- 3, 2, -11, -27, -39, -33, -11, 2, -8, -39, -73, -95, -91, -54, -8, 19,
- 16, 4, 5, 14, 14, 2, -8, -14, -19, -33, -45, -38, -19, 2, 21, 54,
- 93, 106, 90, 74, 80, 97, 98, 76, 52, 34, 10, -18, -37, -36, -27, -35,
- -52, -62, -56, -44, -39, -37, -29, -17, -8, -2, 3, 4, -4, -16, -27, -32,
- -19, 1, 19, 41, 60, 70, 71, 67, 64, 61, 53, 38, 14, -8, -21, -29,
- -34, -38, -39, -29, -15, 0, 5, -5, -19, -25, -16, 5, 19, 17, 6, -3,
- -7, 0, -1, 1, -2, -5, 0, 0, 2, 0, -3, -2, 0, 1, 0, -2,
- -2, -2, 0, 3, 3, -2, -5, -1, -1, -1, -4, 3, 9, 1, -1, -2,
- -11, -7, 1, 9, 11, 8, -4, -11, -12, -9, -4, 18, 15, 14, 1, -22,
- -29, -14, 3, 30, 29, 14, -2, -35, -43, -11, 13, 36, 42, 15, -16, -49,
- -44, -10, 28, 47, 38, 11, -25, -66, -39, 4, 36, 58, 33, -3, -44, -65,
- -29, 19, 52, 54, 23, -13, -59, -65, -15, 32, 69, 49, 8, -30, -74, -51,
- 3, 43, 71, 40, -5, -48, -77, -31, 16, 57, 67, 24, -15, -67, -72, -12,
- 36, 66, 59, 5, -31, -80, -51, 3, 49, 75, 37, -2, -59, -81, -28, 20,
- 67, 66, 22, -23, -76, -65, -10, 41, 78, 48, 4, -36, -85, -47, 6, 59,
- 80, 31, -8, -69, -82, -22, 29, 73, 63, 17, -31, -81, -63, -1, 47, 79,
- 47, 3, -56, -90, -40, 19, 75, 73, 28, -25, -86, -74, -10, 48, 85, 56,
- 6, -51, -93, -48, 11, 67, 86, 33, -11, -78, -87, -29, 36, 89, 66, 13,
- -38, -91, -60, 2, 50, 83, 48, 0, -56, -90, -41, 16, 71, 78, 30, -17,
- -80, -75, -20, 31, 82, 62, 15, -32, -85, -66, -7, 48, 84, 50, 4, -53,
- -87, -44, 8, 62, 78, 35, -8, -65, -83, -30, 23, 70, 71, 24, -20, -76,
- -75, -12, 32, 73, 62, 15, -30, -85, -62, -2, 41, 76, 51, 9, -39, -86,
- -52, 1, 45, 79, 46, 8, -49, -89, -46, 3, 54, 80, 43, 7, -55, -83,
- -50, 0, 53, 76, 54, 11, -52, -83, -55, 0, 40, 67, 58, 22, -32, -79,
- -67, -11, 28, 63, 52, 37, -9, -70, -63, -28, 10, 42, 49, 53, 8, -46,
- -64, -41, 1, 22, 38, 51, 39, -16, -63, -46, -23, 5, 33, 38, 48, 14,
- -42, -57, -29, -5, 22, 37, 40, 28, -23, -53, -39, -10, 14, 30, 40, 31,
- -1, -48, -40, -18, 11, 19, 31, 26, 14, -20, -50, -25, -5, 11, 31, 30,
- 14, 0, -35, -39, -4, -1, 19, 27, 17, 9, -10, -39, -21, -8, 9, 24,
- 26, 13, -5, -19, -30, -12, -1, 17, 25, 16, 3, -19, -26, -13, -6, 17,
- 22, 20, 5, -16, -32, -19, -1, 23, 27, 23, 4, -30, -33, -23, -1, 35,
- 35, 24, -2, -41, -45, -21, 9, 45, 41, 22, -12, -50, -46, -18, 28, 55,
- 45, 10, -27, -78, -42, 0, 53, 66, 32, -1, -61, -74, -28, 27, 64, 64,
- 24, -28, -80, -66, -15, 53, 84, 48, 5, -59, -94, -41, 17, 75, 80, 26,
- -21, -91, -79, -12, 48, 87, 55, 10, -58, -96, -46, 9, 80, 81, 30, -23,
- -84, -80, -15, 49, 90, 49, 9, -57, -95, -45, 17, 76, 79, 26, -20, -91,
- -75, -18, 52, 90, 52, 6, -59, -92, -41, 15, 68, 80, 31, -21, -87, -76,
- -13, 45, 87, 49, 11, -60, -94, -35, 14, 80, 68, 22, -23, -89, -66, -7,
- 47, 93, 44, -8, -61, -95, -31, 24, 86, 75, 10, -35, -96, -66, -1, 61,
- 100, 44, -12, -77, -105, -33, 32, 97, 92, 16, -44, -111, -90, -5, 65, 121,
- 65, -3, -80, -123, -59, 17, 98, 111, 46, -25, -112, -109, -33, 42, 112, 90,
- 30, -55, -115, -84, -17, 66, 105, 71, 13, -73, -113, -61, 0, 77, 96, 56,
- 4, -80, -108, -50, 8, 78, 93, 47, 3, -88, -98, -40, 7, 65, 76, 53,
- 18, -71, -90, -44, 0, 39, 57, 43, 34, -19, -69, -54, -19, 18, 32, 31,
- 34, 7, -40, -36, -21, -1, 12, 12, 25, 27, -9, -32, -14, -14, 2, 0,
- 1, 20, 19, -2, -13, -11, -18, -12, -2, 18, 24, 12, -2, -14, -19, -19,
- -12, 18, 24, 22, -2, -15, -32, -20, 3, 22, 26, 17, -13, -31, -27, -13,
- 17, 33, 32, 5, -29, -47, -29, 2, 33, 42, 32, -6, -53, -52, -24, 22,
- 51, 41, 27, -32, -74, -45, 0, 45, 59, 33, -1, -62, -66, -31, 26, 73,
- 49, 17, -42, -80, -42, -8, 63, 72, 28, -10, -75, -72, -23, 32, 88, 47,
- 13, -56, -93, -38, 10, 76, 69, 26, -20, -96, -66, -10, 48, 90, 47, 0,
- -69, -103, -29, 25, 87, 73, 18, -35, -104, -68, -2, 61, 93, 47, -5, -83,
- -98, -31, 30, 92, 68, 17, -39, -97, -63, -5, 64, 88, 35, -9, -74, -86,
- -22, 31, 85, 54, 13, -44, -93, -46, 9, 65, 75, 23, -17, -75, -78, -15,
- 39, 84, 54, 3, -52, -96, -46, 12, 71, 90, 29, -18, -89, -87, -26, 36,
- 86, 72, 26, -37, -106, -77, -12, 45, 99, 68, 22, -46, -108, -73, -10, 43,
- 87, 69, 19, -27, -92, -79, -12, 27, 63, 57, 26, 4, -53, -75, -35, 12,
- 33, 37, 31, 26, -9, -53, -39, -16, 6, 20, 23, 22, 13, -8, -22, -23,
- -18, -3, 9, 25, 19, 4, -8, -20, -17, -10, 6, 16, 17, 13, -8, -34,
- -21, -6, 17, 33, 23, 6, -32, -51, -23, 11, 36, 46, 31, -11, -46, -65,
- -31, 15, 59, 55, 28, -20, -73, -64, -26, 42, 78, 51, 14, -53, -85, -48,
- -4, 70, 80, 38, -16, -80, -76, -32, 39, 90, 58, 19, -59, -99, -50, 14,
- 71, 75, 36, -21, -94, -70, -23, 51, 88, 53, 9, -68, -97, -40, 16, 83,
- 73, 29, -33, -100, -61, -13, 58, 87, 41, 0, -74, -81, -35, 24, 87, 55,
- 20, -41, -88, -58, 0, 69, 73, 34, -5, -86, -75, -20, 38, 79, 49, 13,
- -48, -90, -39, 2, 71, 68, 31, -16, -84, -67, -15, 38, 79, 42, 12, -50,
- -85, -37, 2, 62, 71, 34, -5, -83, -75, -24, 27, 82, 51, 27, -30, -88,
- -54, -15, 44, 73, 50, 16, -49, -81, -47, -6, 38, 58, 50, 27, -31, -69,
- -52, -13, 15, 36, 45, 33, -5, -41, -44, -23, 2, 14, 27, 33, 10, -25,
- -20, -18, -6, 1, -1, 17, 22, 3, -13, -10, -17, -13, -6, 13, 24, 15,
- 1, -11, -19, -19, -16, 12, 24, 24, 3, -12, -29, -26, -1, 18, 27, 19,
- -4, -31, -28, -19, 11, 30, 35, 12, -21, -46, -35, -6, 28, 42, 36, 5,
- -46, -57, -31, 10, 50, 43, 33, -16, -71, -55, -9, 35, 62, 38, 10, -51,
- -71, -40, 11, 69, 58, 24, -26, -81, -50, -18, 48, 79, 37, 1, -62, -81,
- -32, 16, 84, 59, 20, -37, -96, -50, -2, 63, 78, 33, -4, -85, -80, -20,
- 33, 88, 59, 10, -50, -107, -47, 14, 75, 85, 27, -19, -95, -83, -15, 47,
- 94, 60, 8, -66, -105, -46, 15, 83, 81, 26, -23, -91, -76, -18, 48, 92,
- 47, 1, -59, -94, -36, 18, 78, 66, 19, -27, -91, -60, -3, 53, 80, 35,
- -8, -62, -86, -28, 27, 79, 66, 13, -38, -94, -62, 1, 56, 95, 42, -6,
- -75, -96, -39, 22, 80, 80, 36, -20, -97, -92, -24, 30, 93, 79, 32, -27,
- -102, -87, -22, 31, 81, 79, 29, -14, -81, -91, -25, 19, 56, 63, 31, 11,
- -39, -77, -47, 3, 31, 37, 33, 27, 3, -48, -46, -20, 0, 18, 22, 23,
- 16, -3, -20, -19, -15, -4, 2, 8, 5, 0, 0, 0, 0, 2, 2, 5,
- 9, 12, 14, 12, 7, 6, 4, 0, -1, -1, 1, -2, -2, -11, -17, -32,
- -41, -49, -55, -58, -61, -61, -65, -61, -57, -47, -37, -27, -22, -15, -5, 6,
- 12, 16, 21, 27, 28, 32, 33, 35, 41, 44, 45, 47, 50, 54, 57, 56,
- 53, 53, 54, 50, 50, 52, 54, 56, 52, 53, 54, 50, 49, 46, 43, 38,
- 33, 27, 19, 8, 2, -11, -20, -27, -29, -30, -32, -35, -42, -52, -57, -57,
- -59, -48, -40, -27, -13, 4, 13, 20, 18, 14, 11, 7, 3, -1, -3, -10,
- -11, -20, -28, -46, -60, -72, -82, -92, -97, -97, -97, -94, -90, -81, -71, -61,
- -55, -55, -53, -47, -38, -29, -23, -11, -6, -3, 1, 2, 5, 6, 3, 3,
- 5, 15, 24, 28, 30, 30, 35, 37, 36, 39, 39, 44, 47, 48, 56, 62,
- 73, 84, 91, 96, 95, 91, 85, 76, 72, 63, 55, 47, 44, 43, 41, 38,
- 31, 19, 7, 0, -9, -7, -4, 8, 22, 40, 54, 67, 71, 70, 64, 56,
- 45, 32, 24, 15, 12, 3, -3, -21, -42, -66, -84, -102, -117, -124, -128, -127,
- -124, -118, -107, -96, -86, -86, -88, -86, -80, -70, -63, -50, -40, -33, -25, -23,
- -20, -18, -18, -21, -25, -22, -14, -8, -3, -3, -1, 1, 0, 1, -3, -1,
- 2, 4, 13, 24, 35, 49, 59, 67, 70, 69, 68, 59, 54, 46, 40, 31,
- 29, 27, 25, 23, 20, 12, -1, -9, -19, -22, -21, -11, 3, 23, 41, 60,
- 71, 76, 73, 71, 65, 56, 50, 44, 42, 35, 33, 24, 9, -13, -31, -48,
- -65, -76, -83, -83, -82, -77, -69, -59, -46, -40, -40, -41, -38, -30, -24, -13,
- -2, 8, 17, 22, 24, 25, 23, 20, 13, 9, 11, 15, 19, 16, 12, 9,
- 4, 1, -6, -10, -11, -14, -12, -5, 3, 15, 26, 35, 40, 41, 41, 35,
- 28, 19, 12, 3, -2, -6, -7, -10, -13, -19, -31, -39, -50, -56, -58, -52,
- -41, -22, -3, 18, 34, 46, 48, 47, 45, 38, 32, 26, 24, 20, 19, 15,
- 5, -14, -32, -49, -65, -79, -88, -91, -91, -88, -82, -75, -63, -52, -47, -46,
- -46, -38, -31, -21, -8, 4, 17, 26, 31, 36, 39, 42, 40, 35, 36, 39,
- 47, 48, 45, 43, 38, 36, 30, 24, 22, 19, 18, 23, 29, 40, 50, 61,
- 68, 72, 74, 71, 66, 57, 50, 40, 32, 24, 21, 16, 12, 7, -3, -14,
- -26, -38, -45, -46, -43, -31, -16, 3, 18, 33, 39, 39, 36, 31, 22, 13,
- 8, 3, -1, -4, -9, -24, -42, -60, -77, -94, -107, -115, -119, -120, -116, -112,
- -103, -91, -81, -78, -80, -75, -69, -61, -51, -39, -25, -13, -5, 2, 8, 14,
- 17, 16, 15, 16, 24, 31, 32, 32, 29, 29, 27, 22, 21, 20, 19, 22,
- 26, 35, 46, 59, 70, 77, 83, 85, 84, 79, 74, 66, 59, 50, 46, 41,
- 38, 35, 29, 21, 11, 0, -9, -14, -16, -11, 0, 16, 30, 48, 58, 62,
- 61, 58, 51, 40, 31, 25, 19, 15, 13, 4, -11, -28, -44, -61, -76, -87,
- -95, -100, -100, -99, -95, -86, -75, -68, -69, -68, -67, -62, -56, -49, -38, -27,
- -19, -13, -9, -3, 2, 1, -1, -3, 0, 7, 10, 10, 6, 5, 4, 0,
- -4, -5, -7, -7, -7, -2, 5, 16, 27, 36, 44, 49, 52, 50, 46, 40,
- 35, 26, 22, 18, 15, 15, 13, 9, 4, -5, -14, -19, -23, -21, -14, 0,
- 15, 33, 49, 60, 63, 63, 61, 53, 44, 38, 32, 27, 27, 23, 14, 0,
- -14, -29, -44, -58, -67, -74, -76, -76, -73, -67, -55, -45, -41, -41, -41, -39,
- -35, -30, -23, -12, -3, 4, 9, 14, 20, 21, 20, 17, 15, 19, 24, 26,
- 24, 21, 20, 18, 12, 9, 6, 3, 0, 1, 4, 11, 21, 30, 38, 43,
- 47, 48, 45, 38, 32, 23, 15, 9, 5, 3, 1, -2, -5, -13, -22, -30,
- -37, -41, -40, -30, -18, -3, 15, 30, 38, 41, 41, 37, 27, 19, 12, 6,
- 3, 2, -2, -13, -25, -39, -53, -67, -78, -88, -92, -92, -91, -86, -77, -63,
- -54, -50, -48, -47, -43, -38, -32, -23, -11, -1, 6, 11, 19, 25, 27, 26,
- 24, 26, 31, 36, 38, 36, 37, 37, 34, 32, 29, 27, 24, 22, 23, 27,
- 35, 45, 53, 61, 67, 70, 71, 66, 60, 51, 42, 34, 28, 24, 21, 18,
- 16, 11, 2, -8, -16, -24, -28, -25, -17, -5, 10, 26, 39, 45, 47, 45,
- 37, 27, 18, 9, 3, 0, -2, -10, -22, -36, -51, -67, -81, -93, -102, -107,
- -108, -107, -102, -90, -78, -71, -67, -66, -63, -59, -56, -49, -39, -28, -19, -13,
- -6, 1, 7, 8, 6, 5, 8, 14, 19, 19, 19, 20, 20, 19, 16, 15,
- 13, 12, 11, 13, 20, 30, 39, 49, 57, 63, 68, 68, 65, 58, 51, 43,
- 37, 32, 29, 27, 26, 24, 19, 11, 2, -5, -12, -14, -9, 0, 13, 30,
- 46, 56, 62, 65, 61, 53, 44, 35, 26, 22, 20, 15, 6, -6, -20, -36,
- -51, -66, -78, -87, -91, -92, -92, -85, -74, -65, -58, -56, -55, -52, -50, -46,
- -40, -30, -20, -14, -8, -2, 5, 7, 6, 3, 2, 5, 10, 11, 10, 9,
- 9, 8, 5, 2, 0, -2, -5, -5, -3, 5, 14, 23, 32, 39, 46, 50,
- 49, 45, 38, 31, 24, 17, 14, 11, 10, 9, 7, 2, -5, -12, -20, -25,
- -25, -19, -8, 7, 24, 40, 50, 58, 60, 56, 49, 41, 31, 24, 22, 20,
- 15, 6, -5, -19, -34, -48, -61, -72, -79, -83, -85, -81, -72, -62, -52, -47,
- -44, -41, -39, -35, -31, -24, -13, -5, 1, 7, 14, 20, 22, 21, 19, 18,
- 22, 25, 25, 24, 23, 23, 20, 17, 15, 12, 10, 7, 5, 9, 16, 24,
- 33, 40, 47, 53, 56, 54, 48, 41, 33, 25, 20, 15, 11, 9, 8, 5,
- -2, -10, -19, -27, -32, -31, -25, -15, 0, 17, 30, 40, 46, 46, 42, 35,
- 25, 15, 10, 9, 5, -2, -11, -23, -37, -52, -65, -79, -89, -95, -99, -100,
- -95, -85, -74, -65, -60, -55, -52, -48, -44, -40, -29, -18, -10, -4, 4, 12,
- 18, 20, 19, 17, 20, 24, 27, 27, 26, 26, 25, 23, 21, 19, 17, 15,
- 12, 13, 17, 25, 34, 41, 49, 57, 62, 65, 63, 57, 51, 42, 35, 30,
- 25, 22, 21, 19, 15, 8, 0, -9, -17, -21, -20, -14, -3, 13, 26, 38,
- 48, 53, 52, 47, 39, 28, 19, 15, 13, 8, 0, -10, -22, -37, -51, -65,
- -79, -88, -95, -100, -99, -94, -84, -74, -67, -61, -58, -55, -51, -49, -43, -33,
- -23, -17, -10, -2, 6, 10, 11, 9, 9, 12, 15, 17, 16, 16, 16, 14,
- 12, 11, 9, 8, 5, 3, 4, 10, 18, 26, 34, 42, 50, 57, 59, 57,
- 52, 45, 38, 32, 27, 23, 21, 20, 19, 14, 8, 1, -9, 2, 5, 7,
- 8, -1, 6, 15, 1, 20, 28, 1, 37, 41, 31, 29, 27, 61, 40, -12,
- 38, 52, -16, -20, -1, -23, -48, -56, -63, -61, -77, -100, -88, -76, -103, -113,
- -98, -103, -118, -120, -108, -107, -104, -110, -118, -104, -109, -128, -107, -83, -106, -86,
- -94, -100, -77, -113, -88, -43, -77, -46, -44, -69, -34, -54, -39, 4, -30, 11,
- 18, -25, 20, 16, 10, 52, 35, 52, 74, 33, 55, 74, 59, 70, 81, 85,
- 91, 81, 72, 89, 94, 82, 80, 99, 100, 85, 86, 91, 100, 91, 81, 91,
- 102, 83, 74, 92, 95, 63, 62, 75, 71, 63, 39, 54, 74, 15, 1, 31,
- 6, -5, -13, -20, -8, -44, -59, -38, -69, -73, -67, -86, -90, -68, -73, -77,
- -49, -82, -70, -43, -76, -27, 0, -29, 22, 25, -5, 44, 45, 29, 66, 71,
- 49, 84, 92, 73, 92, 74, 72, 91, 37, 48, 99, 47, 31, 44, 36, 33,
- -5, -11, 26, 6, -33, -22, -6, -32, -55, -44, -45, -52, -63, -73, -55, -51,
- -77, -79, -61, -73, -91, -83, -70, -77, -74, -82, -85, -68, -88, -98, -57, -67,
- -77, -58, -75, -66, -64, -78, -33, -37, -50, -19, -47, -38, -23, -41, 3, 6,
- -7, 30, 0, -4, 24, 15, 31, 45, 44, 66, 44, 34, 58, 54, 59, 67,
- 71, 87, 78, 60, 73, 84, 78, 76, 86, 95, 89, 76, 85, 94, 89, 73,
- 82, 99, 85, 66, 75, 93, 75, 50, 56, 69, 59, 31, 31, 61, 29, -15,
- 15, 5, -15, -14, -36, -25, -29, -69, -55, -53, -82, -78, -76, -95, -88, -69,
- -80, -65, -63, -86, -58, -67, -59, -12, -28, -9, 29, -8, 13, 44, 22, 44,
- 68, 53, 62, 91, 74, 81, 89, 64, 84, 78, 35, 78, 86, 44, 43, 47,
- 45, 22, -5, 17, 21, -16, -24, -14, -14, -34, -50, -40, -36, -63, -71, -58,
- -60, -69, -78, -78, -67, -81, -98, -78, -71, -89, -85, -84, -86, -82, -99, -82,
- -60, -76, -75, -74, -76, -71, -86, -68, -37, -51, -34, -41, -57, -37, -51, -31,
- -7, -17, -3, 1, 7, 22, 31, 46, 57, 41, 43, 56, 63, 62, 68, 85,
- 86, 80, 84, 92, 96, 93, 93, 104, 105, 96, 99, 108, 106, 102, 98, 102,
- 111, 99, 87, 106, 110, 85, 80, 88, 89, 79, 68, 70, 81, 48, 25, 39,
- 32, 18, 9, 12, 0, -29, -31, -38, -60, -52, -63, -79, -71, -66, -62, -59,
- -62, -74, -72, -73, -81, -43, -21, -28, 8, 10, -10, 16, 28, 27, 42, 50,
- 47, 66, 76, 68, 81, 73, 67, 72, 39, 40, 67, 41, 23, 25, 22, 12,
- -16, -22, -5, -27, -51, -44, -45, -57, -68, -73, -71, -74, -91, -89, -84, -90,
- -97, -98, -98, -102, -105, -108, -103, -97, -105, -109, -101, -107, -113, -106, -92, -87,
- -90, -92, -92, -92, -100, -92, -57, -56, -54, -40, -59, -58, -54, -61, -23, -9,
- -12, 16, 0, -14, 4, 5, 17, 32, 41, 57, 55, 43, 54, 66, 67, 68,
- 84, 89, 87, 87, 91, 98, 100, 96, 104, 109, 105, 103, 108, 111, 109, 105,
- 105, 113, 111, 99, 102, 115, 104, 88, 90, 97, 93, 80, 75, 86, 75, 37,
- 40, 43, 33, 20, 20, -14, -26, -36, -53, -52, -65, -75, -75, -69, -69, -69,
- -74, -77, -76, -74, -59, -34, -26, -9, 9, 5, 13, 32, 39, 42, 53, 58,
- 61, 73, 77, 77, 73, 61, 57, 46, 29, 37, 37, 17, 6, 2, -10, -27,
- -38, -41, -46, -58, -68, -69, -75, -85, -89, -92, -97, -101, -103, -106, -107, -108,
- -112, -111, -112, -115, -115, -115, -113, -111, -116, -115, -112, -116, -117, -110, -101, -98,
- -101, -101, -98, -101, -101, -86, -69, -65, -59, -57, -62, -58, -54, -39, -19, -12,
- 1, 7, -1, 5, 16, 24, 36, 46, 58, 64, 61, 64, 74, 79, 81, 90,
- 96, 97, 100, 100, 104, 108, 107, 111, 114, 113, 115, 115, 115, 118, 117, 116,
- 118, 119, 116, 115, 116, 117, 111, 104, 105, 107, 99, 93, 95, 91, 71, 57,
- 53, 47, 38, 29, 23, 14, -11, -28, -38, -49, -58, -67, -73, -80, -84, -84,
- -83, -82, -80, -78, -74, -67, -56, -42, -29, -16, -4, 7, 18, 29, 40, 49,
- 57, 64, 70, 74, 78, 79, 77, 72, 67, 60, 53, 48, 42, 33, 23, 14,
- 4, -6, -16, -24, -32, -40, -48, -55, -61, -68, -74, -78, -83, -87, -91, -94,
- -96, -99, -101, -103, -104, -106, -107, -107, -107, -107, -107, -108, -107, -107, -107, -105,
- -101, -98, -96, -94, -93, -91, -87, -82, -74, -67, -62, -57, -54, -49, -43, -35,
- -25, -16, -7, -1, 4, 10, 17, 25, 33, 41, 49, 55, 59, 63, 69, 74,
- 78, 83, 88, 91, 93, 96, 98, 100, 102, 104, 106, 107, 107, 108, 108, 109,
- 109, 108, 108, 108, 107, 105, 104, 102, 99, 94, 91, 87, 83, 78, 73, 66,
- 56, 46, 37, 28, 19, 9, 0, -11, -23, -35, -45, -55, -64, -71, -78, -83,
- -85, -84, -83, -81, -79, -75, -70, -61, -49, -36, -23, -10, 2, 12, 24, 35,
- 45, 53, 61, 67, 72, 76, 79, 78, 75, 70, 65, 58, 52, 46, 39, 29,
- 20, 11, 1, -9, -18, -26, -34, -42, -50, -56, -63, -69, -74, -79, -83, -88,
- -91, -94, -96, -98, -101, -102, -104, -105, -106, -106, -106, -106, -106, -106, -106, -106,
- -105, -102, -98, -96, -94, -92, -90, -88, -84, -77, -70, -64, -59, -55, -51, -45,
- -38, -29, -20, -11, -4, 2, 7, 13, 21, 29, 37, 44, 51, 56, 60, 65,
- 70, 75, 80, 84, 88, 91, 93, 96, 98, 100, 102, 104, 105, 106, 107, 107,
- 108, 108, 107, 107, 107, 106, 104, 103, 101, 99, 95, 91, 87, 83, 78, 73,
- 67, 59, 49, 39, 30, 21, 12, 3, -8, -19, -31, -41, -51, -60, -68, -75,
- -81, -84, -85, -84, -82, -80, -77, -73, -65, -55, -42, -29, -16, -4, 7, 18,
- 29, 40, 49, 57, 64, 70, 74, 78, 79, 77, 73, 68, 62, 56, 50, 44,
- 36, 26, 17, 7, -3, -12, -20, -28, -36, -44, -51, -58, -64, -70, -75, -79,
- -84, -88, -91, -93, -96, -98, -100, -102, -103, -105, -105, -105, -105, -105, -105, -105,
- -105, -104, -102, -99, -96, -94, -92, -90, -88, -85, -79, -72, -66, -61, -56, -52,
- -47, -41, -33, -24, -15, -8, -1, 4, 10, 17, 24, 32, 40, 47, 53, 57,
- 62, 67, 72, 77, 81, 85, 89, 91, 94, 96, 98, 100, 102, 104, 105, 105,
- 106, 106, 107, 106, 106, 106, 105, 104, 102, 101, 99, 95, 91, 87, 83, 79,
- 74, 68, 61, 52, 42, 33, 24, 15, 5, -5, -15, -27, -38, -48, -57, -66,
- -72, -79, -83, -85, -85, -83, -81, -79, -75, -69, -60, -48, -35, -23, -10, 2,
- 13, 24, 35, 45, 54, 61, 67, 72, 77, 78, 79, 76, 72, 66, 60, 54,
- 49, 41, 32, 23, 12, 3, -4, -17, -15, 1, -1, 0, 0, 1, 3, 5,
- 9, 13, 18, 24, 32, 38, 32, 18, -9, -48, -73, -41, 2, -3, -24, -34,
- -44, -72, -111, -124, -62, 40, 40, -51, -35, 45, 46, -22, -79, 35, 78, -47,
- -98, -88, -69, -57, -44, -31, -17, -9, -3, 6, 41, 85, 43, -91, -128, -65,
- -25, -21, -19, -12, 2, 16, 29, 39, 49, 48, 10, -69, -47, 50, 8, -52,
- -44, 5, 21, -40, -42, 33, 79, 66, 38, 24, 25, 26, 18, 21, 70, 117,
- 98, 28, -1, 20, 22, 0, 1, 9, -10, -49, -33, 39, 68, 39, -5, -17,
- -58, -76, 78, 104, 17, 6, -23, -43, -13, 58, 85, 43, 21, 35, 46, 31,
- 22, 35, 14, -48, -74, -38, 6, 10, -8, -17, -24, -37, -60, -69, -41, 15,
- 27, -21, -26, 18, 28, -1, -41, 5, 51, -9, -51, -48, -38, -31, -24, -16,
- -8, -2, 1, 6, 23, 52, 41, -39, -83, -50, -19, -13, -12, -8, 1, 10,
- 20, 27, 34, 35, 15, -40, -46, 27, 16, -35, -38, -6, 19, -18, -35, 17,
- 61, 55, 33, 21, 22, 25, 21, 18, 52, 98, 92, 31, -5, 9, 17, -1,
- -2, 7, -7, -47, -43, 24, 62, 39, -3, -20, -48, -88, 46, 113, 25, 4,
- -20, -45, -25, 42, 82, 47, 19, 28, 42, 32, 18, 30, 19, -39, -77, -51,
- -4, 10, -6, -18, -25, -37, -57, -70, -50, 4, 26, -15, -33, 9, 27, 6,
- -38, -12, 50, 6, -47, -50, -40, -32, -25, -17, -10, -3, 0, 4, 17, 45,
- 47, -23, -82, -60, -24, -14, -13, -10, -2, 7, 16, 24, 30, 33, 18, -32,
- -56, 13, 23, -31, -41, -15, 19, -6, -35, 4, 52, 55, 35, 21, 22, 25,
- 22, 15, 41, 89, 94, 38, -5, 4, 16, 2, -2, 7, -4, -41, -48, 12,
- 58, 43, 2, -20, -38, -89, 14, 118, 38, 3, -15, -43, -32, 28, 78, 53,
- 19, 24, 40, 34, 18, 26, 23, -28, -75, -61, -14, 10, -2, -16, -24, -34,
- -53, -68, -55, -7, 25, -8, -36, 1, 27, 12, -31, -26, 45, 22, -39, -50,
- -41, -32, -25, -17, -10, -4, 0, 3, 13, 38, 51, -5, -77, -69, -31, -15,
- -14, -11, -4, 5, 13, 21, 27, 31, 20, -24, -61, -3, 28, -23, -43, -23,
- 15, 5, -32, -6, 43, 53, 36, 22, 21, 26, 24, 14, 32, 79, 95, 46,
- -3, 0, 15, 5, -1, 7, -1, -36, -52, 2, 53, 46, 7, -18, -30, -84,
- -15, 114, 55, 4, -10, -40, -37, 15, 72, 59, 22, 20, 36, 36, 19, 23,
- 26, -18, -70, -68, -25, 7, 2, -13, -22, -32, -49, -65, -59, -16, 22, -1,
- -36, -8, 25, 17, -22, -35, 34, 36, -29, -48, -42, -32, -25, -18, -10, -4,
- 0, 3, 10, 32, 52, 11, -67, -76, -38, -16, -13, -11, -6, 3, 11, 19,
- 25, 30, 22, -15, -62, -19, 30, -14, -43, -30, 9, 13, -25, -15, 33, 51,
- 37, 23, 21, 26, 26, 15, 24, 68, 94, 54, 0, -3, 13, 8, 1, 8,
- 2, -30, -53, -8, 47, 49, 13, -16, -25, -75, -41, 102, 73, 6, -5, -36,
- -40, 2, 65, 64, 25, 18, 33, 37, 21, 21, 27, -8, -63, -73, -36, 2,
- 5, -10, -21, -30, -45, -62, -61, -25, 17, 5, -35, -17, 21, 21, -13, -39,
- 20, 46, -16, -46, -42, -32, -25, -17, -10, -4, 0, 3, 8, 27, 50, 25,
- -54, -81, -46, -19, -13, -12, -7, 1, 9, 17, 23, 28, 23, -8, -59, -35,
- 27, -5, -42, -35, 2, 20, -16, -20, 24, 47, 38, 24, 21, 27, 28, 17,
- 18, 58, 91, 62, 5, -6, 10, 10, 3, 9, 5, -24, -52, -17, 40, 50,
- 18, -13, -22, -64, -60, 83, 90, 12, -3, -31, -41, -8, 55, 67, 30, 17,
- 30, 37, 24, 19, 27, 1, -54, -75, -46, -4, 7, -7, -18, -28, -41, -58,
- -61, -32, 11, 10, -31, -24, 17, 23, -4, -39, 5, 52, -2, -42, -42, -32,
- -25, -17, -10, -4, 0, 3, 6, 22, 47, 35, -38, -82, -55, -23, -13, -12,
- -8, -1, 7, 15, 21, 26, 23, -1, -53, -48, 20, 5, -39, -39, -6, 22,
- -5, -22, 14, 43, 38, 25, 21, 27, 29, 19, 15, 47, 86, 68, 12, -7,
- 7, 11, 4, 10, 7, -18, -50, -25, 33, 51, 24, -10, -20, -52, -72, 58,
- 103, 21, -1, -26, -41, -17, 44, 67, 35, 16, 27, 36, 26, 18, 25, 8,
- -45, -76, -55, -13, 7, -3, -16, -26, -38, -55, -61, -38, 4, 13, -26, -30,
- 11, 25, 4, -36, -10, 51, 14, -37, -42, -33, -24, -17, -10, -4, 1, 3,
- 6, 18, 42, 42, -22, -80, -63, -28, -14, -12, -9, -3, 5, 12, 19, 24,
- 23, 3, -46, -58, 9, 14, -34, -41, -14, 21, 6, -21, 4, 36, 38, 26,
- 21, 26, 30, 22, 13, 37, 78, 73, 20, -7, 4, 11, 6, 10, 10, -11,
- -45, -33, 22, 49, 29, -4, -18, -40, -75, 23, 108, 40, 1, -18, -39, -26,
- 28, 65, 42, 17, 22, 34, 29, 18, 23, 15, -30, -71, -65, -27, 3, 2,
- -11, -22, -34, -49, -58, -45, -7, 13, -16, -35, -1, 24, 13, -23, -26, 37,
- 36, -20, -39, -34, -24, -17, -10, -4, 1, 3, 5, 12, 33, 46, 6, -64,
- -75, -40, -17, -12, -10, -5, 2, 9, 15, 20, 22, 10, -30, -65, -18, 20,
- -19, -42, -27, 11, 21, -8, -8, 22, 34, 27, 22, 26, 31, 27, 14, 22,
- 60, 75, 34, -4, -2, 8, 8, 11, 14, -2, -36, -42, 6, 44, 36, 4,
- -15, -26, -66, -24, 95, 71, 8, -10, -33, -32, 7, 56, 51, 21, 17, 29,
- 32, 20, 19, 20, -12, -59, -72, -45, -8, 5, -5, -17, -28, -42, -54, -50,
- -21, 9, -5, -36, -16, 19, 21, -7, -34, 12, 51, 4, -33, -34, -25, -17,
- -10, -4, 1, 4, 5, 9, 23, 44, 29, -39, -79, -55, -24, -13, -10, -7,
- -1, 6, 12, 16, 20, 14, -15, -62, -46, 16, -2, -39, -36, -2, 29, 9,
- -12, 8, 28, 27, 23, 25, 31, 31, 17, 13, 43, 72, 46, 2, -5, 5,
- 8, 11, 16, 5, -26, -44, -8, 36, 40, 12, -12, -19, -52, -53, 67, 94,
- 20, -5, -27, -35, -7, 45, 55, 27, 15, 25, 32, 23, 17, 21, 0, -47,
- -73, -57, -19, 4, 0, -13, -24, -37, -50, -51, -29, 3, 1, -32, -26, 12,
- 23, 3, -32, -6, 52, 22, -26, -34, -25, -17, -10, -4, 1, 5, 6, 8,
- 18, 39, 38, -21, -76, -64, -30, -14, -10, -8, -2, 4, 10, 15, 18, 14,
- -9, -56, -57, 7, 7, -35, -39, -10, 27, 18, -10, 2, 23, 26, 23, 24,
- 31, 32, 20, 11, 35, 67, 51, 7, -6, 3, 8, 11, 17, 8, -20, -44,
- -15, 31, 41, 16, -9, -17, -43, -61, 44, 102, 31, -2, -23, -35, -15, 36,
- 56, 32, 0, -27, 1, -1, -1, 3, -4, -2, 1, -1, -2, 2, 3, -6,
- 1, 2, -6, 2, 2, -4, -1, 2, -5, 1, 4, -4, 0, -1, 0, -1,
- -2, 2, 2, -6, 0, 4, -3, -3, 4, -2, -3, -2, 0, 1, 1, -2,
- -2, 3, -8, 27, -42, 11, 21, -35, 34, -25, 12, 9, -24, 14, 13, -38,
- 53, -42, -3, 46, -73, 55, -16, -9, 28, -49, 38, -12, -21, 49, -51, 20,
- 32, -73, 64, -28, -7, 32, -50, 42, -11, -30, 49, -21, -31, 46, -25, -7,
- 20, -22, 18, -16, -10, 21, -23, 5, 28, -35, 8, 0, 8, -26, 19, 6,
- -11, -20, 64, -46, -18, 51, -73, 119, -117, 46, 36, -80, 67, -46, 22, 0,
- -24, 56, -59, 14, 26, -40, 24, -9, 20, -20, -15, 43, -26, -11, 9, 14,
- -3, -31, 6, 54, -62, 3, 67, -78, 20, 21, -25, 31, -41, 18, 27, -53,
- 32, 15, -48, 37, -11, 4, -12, -3, 31, -24, -21, 42, -10, -45, 55, -32,
- 34, -43, -14, 86, -78, 8, 39, -35, -2, 13, 2, 5, -11, -4, 7, 5,
- -31, 37, -4, -28, 28, -9, -11, 10, -1, 4, -18, 17, -9, -13, 24, -18,
- 20, -18, -30, 59, -25, -29, 48, -15, -29, 23, 4, -3, -18, 14, 6, -8,
- -19, 19, 8, -13, 0, 13, -18, 4, 1, 0, 0, 10, -14, -12, 39, -46,
- 23, 9, -22, 23, -20, -22, 63, -42, -28, 77, -66, 12, 38, -56, 31, 27,
- -77, 66, -11, -39, 59, -33, -41, 92, -54, -50, 96, -36, -46, 46, -17, 31,
- -43, -28, 98, -57, -50, 84, -22, -44, 39, -8, 17, -28, -13, 63, -67, 16,
- 10, 3, -15, -4, 36, -34, -1, 26, -27, -2, 13, 7, -22, 0, 27, -11,
- -19, 6, 26, -42, 14, 18, -7, -14, -10, 37, -14, -24, 25, -4, -5, -10,
- 3, 35, -39, -7, 31, -8, -23, 15, 4, -1, -25, 28, 7, -35, 34, -16,
- -1, 9, -35, 45, -22, -17, 48, -52, 24, 22, -65, 48, 7, -45, 47, -19,
- -33, 71, -70, 46, -7, -52, 68, -25, -35, 48, -13, -17, 14, 2, -12, 8,
- -10, 1, 22, -32, 4, 34, -26, -18, 29, -7, -19, 15, -7, 15, -8, -29,
- 50, -22, -35, 53, -19, -37, 47, -9, -40, 41, 1, -27, 7, 3, 0, 0,
- -7, 13, -7, -21, 26, 14, -44, 11, 40, -51, 10, 26, -28, 16, -13, -3,
- 31, -42, 11, 34, -52, 11, 34, -43, 10, 29, -19, -21, 27, -10, -5, 10,
- -14, 11, 3, -35, 43, 3, -52, 37, 22, -66, 49, -12, -19, 50, -58, 16,
- 42, -70, 50, -2, -42, 60, -69, 43, 11, -57, 54, -8, -31, 23, -8, -7,
- 24, -32, 11, 21, -51, 60, -44, -6, 68, -87, 33, 45, -79, 50, -7, -13,
- 21, -40, 31, 12, -41, 18, 24, -39, 15, 7, -17, 25, -20, -12, 43, -47,
- 17, 6, -16, 10, 4, -11, -1, 14, -10, -7, 6, 9, -23, 9, 3, 13,
- -30, 16, 16, -33, 17, 4, -17, 23, -29, 3, 54, -86, 50, 11, -41, 30,
- -23, 15, 18, -60, 56, 7, -65, 49, -4, -12, 1, -6, 19, -4, -33, 35,
- -10, -12, 13, -2, -2, -2, 2, -10, 16, -8, -11, 19, -6, -19, 24, -14,
- 9, 3, -24, 24, -6, -13, 19, -11, -6, 6, -9, 16, -8, -10, 14, -10,
- -1, -5, 16, -8, -25, 37, -11, -27, 37, -14, -13, 19, -17, 14, -5, -15,
- 26, -27, 10, 11, -23, 22, -5, -19, 25, -7, -28, 44, -35, 0, 25, -31,
- 31, -10, -26, 46, -41, 2, 33, -40, 24, 8, -43, 44, -12, -25, 37, -25,
- -6, 29, -27, 5, 24, -40, 24, -1, -25, 23, -1, -6, -2, -1, 14, -24,
- 8, 13, -11, 0, -13, 16, 15, -56, 43, 12, -35, 14, -9, 18, -10, -19,
- 28, -3, -27, 23, -2, -14, 27, -35, 10, 35, -68, 44, 7, -43, 46, -21,
- -25, 56, -35, -21, 51, -33, -8, 28, -27, 19, -2, -26, 36, -26, 3, 13,
- -12, 6, -10, 8, -14, 15, -12, 0, 13, -9, -16, 32, -27, 3, 23, -49,
- 49, -17, -31, 63, -64, 25, 36, -76, 61, -11, -47, 75, -54, -9, 69, -81,
- 32, 29, -63, 46, -7, -26, 39, -31, 6, 18, -26, 13, -5, 5, -5, -2,
- 5, -12, 17, -17, -2, 22, -25, 1, 20, -19, 3, 6, -6, 3, -9, 10,
- -6, -3, 7, -7, -3, 12, -5, -5, -11, 24, -7, -23, 24, 0, -14, 0,
- 12, -10, -2, 5, 0, 1, -10, 10, -2, -17, 26, -11, -16, 28, -22, 6,
- 4, -17, 30, -27, -7, 46, -54, 15, 29, -42, 25, -4, -15, 26, -29, 11,
- 15, -28, 19, -7, 1, 8, -20, 14, 1, -15, 11, -2, -2, 0, -10, 15,
- -5, -12, 15, -1, -15, 12, 4, -15, 9, -1, -9, 9, -5, -6, 13, -12,
- 1, 6, -6, -3, 6, -4, 0, -6, 11, -9, -2, 13, -12, -2, -1, 8,
- -11, 4, 2, -6, 4, -4, 4, 0, -13, 15, 0, -21, 23, -5, -15, 15,
- -2, -9, 6, -2, -4, 2, 3, -1, -7, 7, -2, -9, 6, 2, -9, 4,
- 5, -12, 10, -9, 4, 5, -16, 12, -2, -13, 20, -13, -4, 17, -23, 14,
- 2, -20, 22, -13, -3, 15, -22, 12, 4, -18, 17, -7, -7, 13, -14, 6,
- 4, -10, 9, -5, -6, 7, 0, -7, 8, -4, -1, 0, -6, 4, 7, -14,
- 2, 13, -16, 3, 10, -15, 7, -1, -10, 14, -10, -2, 11, -9, -4, 7,
- -6, 3, -3, -5, 9, -6, -3, 5, 1, -7, 3, -2, 0, -2, 0, 4,
- -3, -2, 4, -6, 4, -2, -2, 0, 1, 0, -7, 7, -2, -7, 9, -7,
- -4, 11, -15, 11, -2, -9, 9, -4, -3, 2, 3, -7, 5, 0, -5, 6,
- -7, 1, 7, -10, -2, 13, -9, -4, 8, -4, -2, -1, 1, 1, -7, 4,
- 5, -8, 0, 6, -6, 0, 3, -4, 0, 1, -2, 2, -4, -4, 8, -7,
- -1, 6, -9, 8, -3, -6, 12, -12, 1, 10, -11, 1, 5, -6, 3, -2,
- -3, 7, -10, 2, 7, -12, 5, 2, -5, 3, -5, 0, 6, -10, 3, 4,
- -8, 2, 2, -3, 3, -8, 8, 2, -14, 10, 3, -12, 8, 2, -11, 8,
- -2, -6, 9, -7, -4, 10, -9, -1, 7, -7, 1, 3, -8, 8, -2, -8,
- 10, -3, -5, 5, -6, 3, 1, -8, 10, -5, -5, 7, -4, -2, 2, -3,
- 1, -1, -3, 4, -3, 0, 0, 0, 0, -4, 3, -2, -3, 3, -5, 3,
- 0, -7, 5, 1, -8, 5, 1, -6, 6, -5, 0, 3, -7, 3, 2, -6,
- 3, 2, -6, 3, 1, -3, -2, 5, -4, -1, 3, -4, 0, 0, -3, 5,
- -5, -3, 7, -5, -3, 6, -4, 0, -1, -3, 3, -2, -1, 2, -1, -2,
- 1, -2, 1, -1, -7, 8, -1, 5, -7, 13, -22, 8, -7, 8, -110, -28,
- 24, 54, 36, 2, 60, -45, 57, 42, -43, 20, 41, -66, 24, -11, 18, -18,
- -38, -63, -36, 30, -11, 33, 25, 30, 18, 11, -18, -5, 5, -46, 40, 1,
- -13, -18, -20, -31, 20, 10, 29, -7, -18, 40, -29, -17, 42, -19, 6, -4,
- 6, -8, 10, -26, -5, 3, 1, -17, 6, 0, 19, -1, 8, 0, -6, -10,
- -1, -12, -1, 1, -3, 8, -7, 4, 11, 4, 14, -13, 16, -19, -4, -13,
- -13, -14, 6, 4, -1, 4, 11, -1, 11, -1, 1, -4, -1, -15, 6, -9,
- 1, -1, 0, 3, 1, -8, 3, -1, -1, 2, -2, 2, -2, 1, -5, -7,
- 3, -3, 6, -3, 4, -1, 0, -4, 2, -7, 3, -6, -1, -1, 4, 0,
- 3, -2, 2, -5, 5, -8, -3, -3, 2, -5, 7, -1, 4, -2, 4, -10,
- 6, -6, -1, -4, 5, -13, 7, -6, 5, -8, 17, -20, 14, -6, 9, -40,
- 71, -127, 9, -73, 127, 76, -28, 74, -32, 8, -62, -49, -38, 40, -68, 22,
- -12, 68, 10, 39, -10, 0, 35, -23, 0, -59, -15, -7, -3, -23, 1, -20,
- 37, 27, 2, 30, -2, 17, 2, -5, -7, -27, -29, 16, -3, -11, 1, -16,
- -5, -8, -10, 7, 32, 9, 5, -4, 16, 5, -8, -17, -16, 5, -13, 8,
- 11, 15, -10, -9, 0, -1, 2, 7, -3, -23, 9, 2, 3, 1, -13, -1,
- -6, 11, -6, 8, 1, 12, -12, 9, -14, 8, -1, 0, -3, -13, 4, -7,
- -4, 8, 5, -5, -7, 4, -2, -3, 2, 3, -6, 8, -3, 1, -3, -2,
- 2, -6, 2, -4, -3, -4, 3, 1, 0, 0, 1, -1, -1, 2, -2, 0,
- -4, -2, 1, 2, 0, -3, 1, -3, 0, -1, -3, -6, 2, -2, 3, -4,
- 10, -8, 9, -5, 12, -19, 46, 37, -128, 60, -90, 102, -65, 40, -57, 39,
- -6, 23, -8, 19, 24, 15, -17, -47, -27, -36, -16, 21, 3, 23, 14, 50,
- -8, 19, 25, 7, -9, -28, -63, -37, 0, -42, 54, -17, 68, -3, 30, -12,
- -4, 11, -15, 9, -25, -15, -2, -27, -25, 38, -8, -13, 33, 24, 12, -38,
- 39, -12, -3, -17, -44, 38, 2, 27, 3, -5, -4, -13, -30, -56, -4, 11,
- 1, 9, 17, 46, 25, -14, 6, -3, -7, -21, 2, 16, -5, -22, 2, -2,
- 6, -12, -25, -15, 10, 9, 8, 11, 43, 8, -5, -22, -16, 14, -31, 16,
- 7, -7, -26, -20, -2, 9, 11, 26, 7, 6, -20, -13, 0, 4, 17, -17,
- -18, 10, 2, -10, 27, -8, 24, -23, -14, 1, 0, 13, -19, 14, 10, -16,
- 16, -4, -20, 20, -33, 2, 2, 24, 21, -3, -26, -24, -18, -18, 10, 10,
- 24, 18, 2, 9, -24, 16, -14, -8, 9, -5, -14, 8, -5, 30, -11, 11,
- -13, -15, -12, 7, 4, -13, -13, 13, -13, 12, 23, 9, 0, 14, -10, -9,
- -35, -2, -21, 12, -1, 17, 19, 11, -4, 0, -18, -24, 11, -10, 1, 11,
- 12, -13, -16, 10, -23, 21, 9, -9, 3, 12, -6, 3, -5, 12, 0, -2,
- 0, -19, -9, 5, -11, -7, 10, 1, -3, 9, 18, -6, 0, -1, 1, -13,
- 2, 1, -3, -8, 17, -4, -9, 18, -15, 8, -1, -11, -5, -14, 11, -5,
- -7, 12, 16, -7, 7, -3, -11, -5, -6, 1, 4, -3, -3, 15, 5, 0,
- 3, 6, -16, 4, -14, -6, -9, -4, 2, 11, 11, 7, -2, 4, -12, -7,
- -14, -6, -7, 9, 4, 7, -2, 6, 5, 6, -4, -3, -4, 7, -7, -11,
- -9, 0, -3, 7, -2, -2, 3, 13, -4, -6, -15, 9, -7, -1, 4, 6,
- 5, 8, -6, -8, 0, -11, -4, 6, -8, 4, 3, 5, 13, -4, -9, -3,
- 4, -3, -3, 4, -1, -12, 6, -14, 2, 3, 15, 2, 6, -7, -8, 3,
- 1, -2, 3, -3, -12, -6, -14, 7, -2, 13, 6, 10, 6, 0, -2, -10,
- -12, -8, -6, -7, -6, 6, 4, -2, 5, 2, 0, -1, 3, -11, 4, 0,
- 20, -8, -2, 0, -1, -3, 7, -3, -4, -2, -6, -10, -10, -8, 1, 2,
- 5, 8, 2, 5, 8, 3, 4, 3, -2, -15, 0, -1, -7, -2, -5, -10,
- 10, -1, 5, 3, 5, -1, -2, -8, -5, -9, 1, -8, 6, 5, 4, 1,
- 1, 2, 3, -2, 4, -7, 1, -7, -9, -2, 0, 2, 3, 6, -8, 8,
- 3, 0, -2, -9, -3, -2, 0, 3, -1, -2, -3, 7, -3, 10, -8, 1,
- -12, 3, -7, 2, -3, 7, 4, 4, 0, 0, -6, -1, -5, -3, -4, -7,
- 0, 5, 7, 0, 2, -3, 10, -1, 3, -7, -5, -4, -9, -3, -7, 5,
- -4, 9, 2, 1, 4, 5, 0, -5, 1, -8, 4, -9, 5, -5, 0, 3,
- -2, -1, 1, 1, -7, 7, 0, 3, -5, 0, -3, -1, -1, -5, -1, 1,
- -1, 1, -1, 0, 2, 0, 2, -7, -7, 4, -1, 0, 3, 4, -1, -3,
- -4, -6, 3, -2, 4, -1, 5, -2, -1, -5, -2, -4, 1, 3, 2, 2,
- 0, -3, 1, 1, -3, -3, -1, 1, -3, -2, -1, -2, -3, -1, 0, 4,
- 3, 5, 2, 1, -4, -9, -3, -7, 1, -2, 7, -2, 3, 3, 3, 1,
- 0, -1, -6, -7, -6, -4, -1, 1, 0, 5, 2, -2, 2, -3, -1, 3,
- -1, 1, -4, -4, -5, 0, -7, 2, -4, 3, 4, 1, 2, -1, -1, -2,
- -2, 0, -1, 1, -1, -1, -3, 1, 1, 3, -3, -1, 1, 1, -2, -3,
- -8, -5, 0, -1, 5, 2, 3, 1, -2, -1, -1, -3, 1, 1, -2, -3,
- -3, -1, 0, -1, 1, 2, 2, 5, 0, -1, -2, -1, -2, 0, -4, 0,
- -5, -1, -1, 0, 1, 5, 4, -2, -1, -2, 0, -6, -1, 0, 1, -1,
- -2, 1, 0, 0, 3, 1, -2, 1, -2, -4, -1, 0, -1, -1, -4, -2,
- -4, 2, -1, 1, 0, 3, 2, 0, 4, -1, 4, -6, 2, -4, -3, -5,
- -4, -3, 0, 2, 0, 1, 4, 2, 2, -2, -2, -5, -6, -5, -3, -2,
- 1, -1, 0, 0, 2, 2, 2, 0, 4, -2, 3, 2, -1, -2, -3, -3,
- -3, -5, -5, -5, -1, -1, 0, 2, 2, 4, 1, 2, 1, 2, -1, -1,
- -3, -4, -5, -3, -2, -2, -1, 1, 4, 2, 2, 2, 1, -1, -2, -6,
- -2, -3, 2, -1, 1, -2, 0, 2, 1, 2, -2, 1, 0, -2, -2, -3,
- 0, -2, -1, -1, 0, -2, -2, 1, 0, 2, -1, 1, -1, 0, -1, -1,
- 0, -1, 0, -2, 2, 0, 2, 2, 5, 3, 6, 8, 12, 13, -6, -110,
- -7, 51, -99, -128, 10, -28, -39, 25, -33, -27, 41, 34, -5, 17, 23, 25,
- 24, 23, 20, 24, 25, 24, 21, 20, 23, 23, 16, 20, 9, 20, 18, 10,
- 14, 5, 14, 11, 7, 5, 3, 10, 2, 7, -4, 0, 3, 0, -3, -5,
- -6, -1, -12, -4, -17, -10, 9, -42, -40, 65, 40, -58, 29, 72, 39, 50,
- 31, -1, 30, 25, -7, -4, -33, -47, -29, -49, -74, -69, -71, -79, -61, -51,
- -57, -53, -34, -20, -22, -16, -10, -6, -2, 1, 3, 4, 8, 8, 12, 10,
- 9, 14, 13, 12, 12, 13, 12, 12, 14, 12, 12, 12, 12, 13, 12, 9,
- 11, 11, 11, 7, 8, 7, 8, 9, 2, 5, 8, -6, 2, 17, -17, -20,
- 18, 5, -15, 15, 27, 21, 37, 44, 41, 46, 38, 26, 32, 26, -4, -15,
- -6, -20, -44, -50, -54, -60, -59, -58, -58, -54, -46, -38, -32, -26, -19, -14,
- -9, -5, -1, 2, 5, 7, 8, 10, 11, 12, 13, 13, 14, 14, 14, 13,
- 13, 14, 15, 14, 11, 13, 14, 13, 12, 10, 12, 12, 10, 10, 8, 6,
- 11, 9, -1, 5, 11, -1, -6, 1, -1, -4, 0, -1, 0, 14, 25, 24,
- 28, 37, 38, 38, 38, 31, 22, 14, 4, -5, -15, -26, -38, -47, -52, -54,
- -56, -57, -55, -51, -45, -39, -34, -28, -22, -17, -13, -8, -3, -1, 2, 5,
- 7, 8, 10, 11, 12, 13, 13, 13, 13, 14, 14, 13, 13, 14, 13, 12,
- 13, 13, 12, 11, 12, 11, 9, 11, 9, 6, 7, 8, 5, 3, 2, 0,
- 0, 0, -2, -3, 0, 3, 6, 11, 18, 23, 27, 31, 34, 35, 32, 27,
- 21, 14, 5, -5, -15, -26, -35, -43, -48, -52, -53, -53, -52, -49, -44, -40,
- -35, -29, -24, -19, -14, -10, -6, -3, 1, 3, 5, 7, 9, 10, 11, 12,
- 13, 13, 13, 13, 13, 13, 13, 13, 13, 12, 13, 12, 11, 13, 11, 10,
- 10, 9, 9, 8, 7, 7, 5, 4, 3, 2, 0, -1, -1, 0, 2, 4,
- 8, 12, 17, 22, 25, 28, 30, 30, 28, 24, 19, 12, 3, -5, -14, -23,
- -31, -37, -43, -46, -46, -48, -47, -43, -41, -38, -33, -29, -25, -21, -16, -12,
- -8, -5, -2, 0, 3, 5, 7, 9, 10, 11, 12, 12, 13, 14, 13, 13,
- 13, 13, 13, 12, 12, 12, 11, 11, 11, 10, 9, 9, 8, 7, 7, 6,
- 5, 4, 4, 3, 3, 3, 3, 5, 6, 8, 10, 12, 14, 17, 18, 19,
- 20, 19, 17, 14, 10, 5, 0, -6, -11, -17, -22, -26, -29, -32, -34, -34,
- -35, -34, -32, -31, -28, -26, -23, -20, -17, -14, -11, -8, -5, -3, 0, 2,
- 4, 6, 7, 8, 9, 10, 11, 11, 12, 12, 12, 12, 11, 11, 11, 10,
- 10, 9, 9, 8, 8, 7, 7, 6, 5, 5, 5, 4, 4, 5, 5, 5,
- 6, 7, 8, 9, 10, 11, 12, 13, 13, 13, 13, 12, 10, 8, 5, 2,
- -2, -6, -10, -14, -18, -21, -24, -26, -28, -29, -29, -30, -29, -28, -27, -25,
- -23, -20, -18, -15, -12, -10, -7, -4, -2, 0, 2, 4, 6, 7, 9, 10,
- 10, 11, 11, 12, 12, 12, 12, 11, 11, 11, 10, 10, 9, 9, 8, 8,
- 7, 7, 6, 6, 5, 5, 5, 5, 6, 6, 7, 7, 8, 9, 10, 11,
- 12, 13, 13, 13, 12, 11, 10, 8, 5, 2, -1, -5, -9, -13, -16, -19,
- -22, -24, -26, -27, -28, -28, -28, -27, -26, -24, -22, -20, -18, -15, -13, -10,
- -7, -5, -2, 0, 2, 4, 5, 7, 8, 9, 10, 11, 11, 11, 11, 11,
- 11, 11, 11, 10, 10, 9, 9, 8, 8, 7, 7, 6, 6, 6, 5, 5,
- 5, 5, 6, 6, 6, 7, 8, 9, 10, 11, 11, 12, 12, 12, 11, 10,
- 9, 7, 5, 2, -1, -5, -8, -12, -15, -18, -21, -23, -25, -26, -27, -27,
- -27, -26, -25, -24, -22, -20, -18, -16, -13, -11, -8, -6, -3, -1, 1, 3,
- 4, 6, 7, 8, 9, 10, 10, 10, 11, 11, 11, 10, 10, 10, 10, 9,
- 9, 8, 8, 7, 7, 6, 6, 6, 5, 5, 5, 5, 6, 6, 6, 7,
- 8, 9, 9, 10, 11, 11, 11, 11, 11, 10, 9, 7, 4, 2, -1, -4,
- -7, -11, -14, -17, -19, -21, -23, -24, -25, -26, -26, -25, -24, -23, -22, -20,
- -18, -16, -13, -11, -9, -6, -4, -2, 0, 2, 4, 5, 7, 8, 9, 9,
- 10, 10, 11, 11, 11, 11, 10, 10, 10, 9, 9, 8, 8, 7, 7, 7,
- 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 8, 9, 9, 10, 11, 11,
- 11, 11, 10, 10, 8, 7, 5, 2, -1, -3, -7, -10, -13, -15, -18, -20,
- -22, -23, -24, -25, -25, -24, -24, -23, -21, -20, -18, -16, -14, -11, -9, -7,
- -5, -2, 0, 1, 3, 5, 6, 7, 8, 9, 9, 10, 10, 10, 10, 10,
- 10, 10, 9, 9, 8, 8, 8, 7, 7, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 7, 7, 8, 8, 9, 9, 9, 10, 9, 9, 8, 7, 6, 4,
- 2, 0, -2, -5, -7, -10, -12, -15, -17, -18, -20, -21, -21, -22, -22, -21,
- -21, -20, -18, -17, -15, -13, -12, -10, -8, -6, -4, -2, 0, 1, 3, 4,
- 5, 6, 7, 8, 8, 8, 9, 9, 9, 9, 9, 8, 8, 8, 8, 7,
- 7, 7, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8,
- 8, 8, 8, 8, 7, 6, 5, 4, 3, 1, -1, -3, -5, -7, -9, -10,
- -12, -14, -15, -16, -17, -18, -18, -18, -18, -17, -17, -16, -15, -13, -12, -11,
- -9, -7, -6, -4, -3, -1, 0, 1, 3, 4, 5, 5, 6, 7, 7, 7,
- 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 6, 5,
- 4, 3, 2, 0, -1, -3, -5, -7, -9, -10, -12, -13, -15, -16, -17, -17,
- -18, -18, -18, -17, -17, -16, -15, -14, -12, -11, -9, -8, -6, -5, -3, -2,
- -1, 1, 2, 3, 4, 5, 5, 6, 6, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 6, 6, 5, 4, 3, 2, 0, -1, -3,
- 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 2, 3, 4, 5,
- 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 6, 7, 8, 9, 10, 10,
- 11, 12, 12, 13, 13, 14, 15, 17, 18, 19, 20, 21, 22, 23, 24, 26,
- 27, 29, 29, 29, 28, 28, 28, 29, 30, 31, 31, 31, 31, 28, 19, -8,
- -41, -53, -57, -59, -60, -62, -62, -63, -64, -65, -65, -66, -67, -69, -69, -69,
- -72, -74, -73, -74, -76, -78, -79, -81, -82, -82, -83, -81, -83, -85, -81, -81,
- -88, -90, -80, -64, -47, -32, -23, -18, -15, -13, -12, -12, -12, -13, -13, -13,
- -13, -13, -12, -12, -11, -9, -7, -6, -4, -2, -1, 0, 1, 2, 4, 5,
- 7, 10, 12, 14, 16, 18, 19, 18, 19, 21, 19, 20, 22, 22, 22, 25,
- 27, 28, 29, 29, 29, 29, 29, 30, 31, 31, 31, 33, 34, 34, 35, 34,
- 33, 31, 30, 29, 26, 25, 26, 25, 22, 22, 21, 20, 20, 19, 19, 19,
- 18, 18, 18, 17, 17, 17, 17, 16, 16, 16, 15, 13, 13, 14, 14, 15,
- 13, 12, 13, 13, 11, 12, 14, 14, 16, 17, 15, 16, 19, 19, 19, 19,
- 21, 19, 17, 18, 19, 18, 15, 15, 17, 18, 18, 13, 11, 14, 15, 14,
- 11, 6, 5, 10, 13, 17, 18, 11, 2, -2, -2, -3, 2, 14, 24, 30,
- 37, 47, 52, 52, 56, 63, 65, 65, 63, 65, 72, 75, 73, 71, 73, 77,
- 82, 82, 77, 77, 82, 90, 99, 104, 99, 89, 84, 86, 94, 106, 119, 127,
- 126, 117, 104, 87, 64, 42, 24, 10, -2, -15, -22, -25, -27, -30, -35, -37,
- -36, -34, -33, -36, -40, -42, -44, -43, -44, -48, -53, -57, -59, -57, -53, -52,
- -53, -57, -62, -68, -73, -75, -75, -71, -63, -56, -48, -40, -34, -29, -26, -23,
- -22, -21, -19, -19, -20, -21, -22, -22, -22, -22, -22, -21, -21, -21, -20, -19,
- -19, -18, -18, -17, -17, -16, -14, -14, -13, -11, -9, -9, -9, -9, -9, -8,
- -8, -8, -8, -8, -7, -6, -7, -6, -4, -3, -2, -2, -3, -4, -3, -3,
- -2, -1, 0, 0, -1, -1, 0, -1, -1, -1, -3, -5, -5, -8, -10, -10,
- -9, -9, -10, -11, -11, -11, -11, -11, -10, -9, -10, -10, -10, -11, -12, -12,
- -13, -12, -11, -12, -14, -14, -11, -10, -12, -11, -11, -12, -12, -11, -11, -13,
- -12, -9, -6, -6, -7, -7, -6, -5, -4, -4, -5, -8, -12, -11, -8, -4,
- -3, -5, -6, -7, -9, -12, -13, -8, -3, -2, -4, -8, -11, -14, -15, -17,
- -19, -19, -15, -8, -1, 2, 4, 8, 12, 17, 23, 26, 25, 24, 25, 30,
- 36, 40, 39, 36, 33, 32, 33, 37, 43, 49, 53, 53, 49, 45, 43, 43,
- 46, 52, 60, 67, 76, 82, 82, 78, 69, 58, 47, 37, 26, 14, 2, -9,
- -16, -21, -24, -28, -32, -35, -37, -38, -37, -36, -36, -36, -39, -43, -46, -49,
- -51, -49, -47, -46, -45, -45, -48, -52, -58, -62, -65, -66, -65, -62, -58, -54,
- -50, -45, -39, -34, -30, -28, -25, -23, -21, -20, -20, -20, -20, -19, -18, -19,
- -20, -18, -17, -18, -17, -17, -18, -17, -16, -15, -15, -13, -12, -10, -10, -10,
- -9, -8, -7, -6, -4, -4, -5, -6, -5, -4, -4, -3, -2, -2, -1, -1,
- -1, 0, 2, 3, 2, 2, 3, 2, 1, 2, 4, 5, 5, 4, 4, 4,
- 3, 2, 2, 1, 0, 0, -1, -4, -5, -4, -2, -2, -3, -3, -3, -2,
- -1, -2, -3, -2, -3, -4, -4, -3, -4, -6, -7, -4, 0, 0, -2, -4,
- -4, -3, -2, -2, -3, -4, -4, -3, -2, -1, 3, 6, 8, 6, 3, 0,
- 0, 2, 4, 5, 4, 3, 2, 2, 2, 1, 0, -1, 2, 7, 11, 9,
- 6, 2, -1, -3, -3, -5, -7, -8, -6, -3, 2, 8, 13, 17, 18, 18,
- 19, 23, 28, 34, 40, 42, 42, 40, 39, 39, 40, 42, 46, 50, 55, 59,
- 59, 55, 51, 48, 48, 51, 57, 63, 70, 76, 82, 86, 88, 89, 86, 80,
- 71, 61, 51, 43, 34, 25, 18, 10, 2, -5, -9, -12, -13, -12, -12, -13,
- -14, -17, -22, -26, -29, -28, -27, -25, -24, -24, -25, -27, -31, -35, -40, -43,
- -46, -47, -49, -49, -46, -43, -40, -36, -32, -28, -24, -21, -18, -16, -14, -13,
- -13, -12, -11, -11, -12, -11, -10, -9, -11, -11, -11, -12, -12, -12, -10, -10,
- -10, -10, -9, -8, -7, -6, -5, -4, -4, -4, -4, -4, -3, -2, -2, -1,
- -2, -3, -2, -1, 0, 0, 1, 2, 3, 2, 1, 1, 2, 3, 3, 4,
- 5, 4, 4, 5, 6, 7, 6, 4, 3, 3, 3, 2, -1, -3, -3, -1,
- -1, -2, -3, -3, -2, -1, 1, 0, -1, -1, -2, -5, -6, -5, -4, -4,
- -4, -4, -6, -6, -4, -1, 0, -2, -6, -9, -10, -8, -5, -4, -3, -3,
- -1, 1, 1, -1, -3, -4, -2, 0, 2, 2, 0, -3, -6, -7, -6, -4,
- -3, -2, -1, -1, -1, 0, 1, 0, -3, -9, -14, -18, -18, -15, -12, -9,
- -8, -7, -5, -3, -2, 0, 5, 11, 17, 22, 25, 24, 23, 21, 20, 22,
- 27, 32, 37, 40, 41, 40, 39, 37, 35, 34, 34, 35, 39, 45, 52, 59,
- 66, 71, 73, 75, 74, 71, 65, 60, 55, 48, 39, 28, 17, 7, -1, -7,
- -11, -13, -13, -14, -17, -21, -24, -28, -31, -32, -32, -32, -32, -31, -29, -29,
- -30, -33, -36, -40, -44, -47, -50, -52, -54, -55, -54, -52, -49, -47, -43, -39,
- -35, -31, -28, -26, -24, -22, -21, -19, -18, -17, -17, -16, -15, -16, -18, -17,
- -16, -16, -17, -18, -18, -17, -16, -16, -14, -13, -13, -12, -12, -12, -11, -10,
- -10, -9, -7, -8, -9, -10, -10, -8, -6, -5, -6, -6, -5, -3, -3, -4,
- -4, -4, -3, -2, -2, -1, -1, -1, 0, 2, 3, 3, 3, 2, 1, 0,
- -1, -1, -1, -2, -3, -5, -5, -4, -2, -3, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1,
- 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 1, 3, 2, 0,
- -1, 1, 2, 1, -1, -1, 2, 2, 0, 1, 2, 2, -1, -4, -10, -21,
- -30, -36, -41, -44, -40, -30, -18, -10, -8, -11, -13, -8, 3, 18, 32, 41,
- 44, 45, 48, 49, 43, 32, 23, 14, 7, 8, 16, 27, 35, 37, 30, 18,
- 9, 5, 3, 2, 1, 1, -1, -6, -11, -12, -6, -2, -5, -11, -18, -28,
- -39, -47, -55, -69, -86, -99, -102, -92, -70, -46, -28, -15, -3, 7, 17, 26,
- 28, 24, 23, 30, 42, 53, 57, 50, 36, 21, 5, -5, -4, 6, 20, 31,
- 35, 34, 29, 26, 27, 37, 56, 76, 85, 80, 71, 63, 55, 47, 34, 13,
- -13, -32, -39, -40, -46, -65, -93, -117, -128, -128, -126, -120, -110, -96, -78, -58,
- -36, -14, 3, 10, 20, 41, 60, 68, 63, 54, 45, 39, 36, 32, 28, 29,
- 35, 41, 47, 46, 41, 39, 43, 53, 68, 80, 78, 64, 46, 28, 13, 3,
- -9, -35, -64, -80, -82, -74, -66, -71, -91, -111, -121, -118, -105, -86, -68, -57,
- -49, -37, -22, -7, 5, 14, 26, 42, 55, 56, 46, 35, 25, 14, 6, 2,
- 1, 3, 11, 22, 32, 40, 43, 42, 46, 60, 77, 88, 90, 78, 54, 30,
- 14, 2, -15, -37, -62, -82, -90, -89, -86, -90, -99, -107, -109, -101, -81, -54,
- -29, -14, -5, 7, 24, 40, 49, 56, 68, 83, 92, 92, 87, 74, 54, 32,
- 12, -5, -19, -25, -24, -18, -7, 1, -1, -6, -4, 13, 41, 69, 84, 80,
- 63, 44, 32, 29, 25, 11, -10, -25, -31, -35, -40, -48, -65, -87, -104, -109,
- -102, -87, -69, -58, -54, -42, -21, 0, 13, 29, 51, 71, 84, 89, 86, 75,
- 54, 33, 14, -3, -19, -29, -27, -22, -18, -11, -8, -16, -26, -19, 2, 24,
- 40, 48, 42, 27, 21, 29, 34, 24, 7, -5, -14, -23, -28, -32, -45, -67,
- -82, -85, -78, -63, -46, -34, -29, -24, -13, 0, 12, 25, 44, 65, 79, 85,
- 86, 78, 60, 41, 27, 12, -5, -15, -15, -14, -13, -8, -7, -17, -27, -23,
- -3, 23, 44, 51, 43, 25, 12, 11, 14, 8, -3, -10, -15, -22, -28, -30,
- -36, -55, -73, -78, -74, -71, -63, -51, -43, -39, -34, -25, -18, -9, 8, 28,
- 46, 56, 61, 62, 58, 47, 36, 28, 20, 12, 11, 16, 19, 20, 21, 15,
- 0, -6, 10, 37, 57, 63, 55, 36, 15, 2, -3, -9, -19, -27, -34, -43,
- -49, -49, -52, -66, -82, -86, -81, -77, -71, -61, -51, -47, -43, -35, -22, -12,
- 2, 24, 47, 58, 63, 67, 66, 58, 51, 45, 34, 18, 9, 7, 7, 7,
- 8, 1, -14, -24, -12, 18, 47, 64, 68, 63, 53, 42, 37, 38, 36, 29,
- 21, 16, 11, 5, -2, -17, -36, -49, -52, -56, -62, -63, -61, -61, -63, -60,
- -56, -49, -37, -19, 2, 17, 25, 30, 34, 37, 37, 37, 34, 25, 15, 11,
- 13, 14, 14, 8, -7, -21, -16, 9, 37, 53, 60, 61, 53, 40, 33, 34,
- 32, 22, 14, 12, 10, 6, -2, -15, -32, -48, -57, -60, -63, -67, -66, -63,
- -63, -65, -64, -58, -49, -34, -13, 6, 16, 21, 28, 34, 38, 41, 43, 36,
- 25, 19, 21, 26, 27, 20, 4, -11, -11, 7, 31, 53, 66, 70, 66, 57,
- 49, 47, 44, 33, 21, 17, 16, 10, 1, -9, -26, -46, -60, -67, -76, -84,
- -84, -80, -78, -79, -78, -73, -65, -52, -32, -11, 4, 10, 17, 25, 32, 36,
- 40, 37, 24, 13, 15, 23, 23, 11, -5, -19, -25, -16, 9, 38, 59, 70,
- 72, 67, 63, 63, 60, 50, 39, 32, 28, 22, 14, 3, -14, -34, -53, -65,
- -76, -87, -94, -93, -91, -94, -96, -93, -86, -76, -56, -30, -9, 4, 16, 29,
- 40, 51, 63, 65, 52, 39, 39, 45, 42, 29, 11, -7, -22, -24, -8, 19,
- 42, 54, 60, 63, 61, 58, 57, 53, 43, 36, 36, 34, 28, 21, 11, -5,
- -24, -39, -52, -65, -75, -77, -75, -75, -78, -80, -78, -73, -61, -43, -23, -9,
- 1, 10, 23, 39, 52, 56, 47, 36, 35, 41, 42, 33, 17, -2, -24, -35,
- -26, -3, 18, 32, 42, 50, 52, 53, 52, 47, 38, 31, 30, 31, 29, 26,
- 22, 14, -1, -18, -33, -46, -58, -65, -65, -65, -71, -79, -81, -79, -75, -62,
- -42, -27, -21, -14, 1, 19, 34, 40, 36, 29, 27, 31, 38, 39, 29, 9,
- -12, -27, -28, -14, 8, 25, 37, 50, 62, 67, 66, 62, 53, 42, 36, 37,
- 36, 32, 30, 25, 12, -7, -24, -39, -54, -65, -67, -67, -72, -78, -81, -82,
- -81, -70, -51, -35, -29, -23, -7, 15, 30, 37, 40, 35, 25, 25, 36, 41,
- 33, 15, -6, -26, -36, -27, -9, 7, 20, 35, 50, 58, 59, 58, 52, 43,
- 37, 37, 37, 36, 34, 31, 24, 8, -11, -29, -44, -57, -67, -70, -73, -79,
- -86, -92, -93, -87, -72, -59, -53, -46, -29, -9, 7, 20, 28, 26, 19, 17,
- 27, 38, 38, 26, 7, -12, -25, -26, -15, 1, 14, 28, 47, 61, 67, 68,
- 68, 63, 54, 51, 53, 51, 49, 49, 47, 34, 14, -5, -22, -39, -56, -65,
- -67, -73, -86, -96, -97, -92, -86, -77, -69, -61, -49, -28, -6, 10, 22, 27,
- 25, 24, 33, 49, 56, 48, 32, 13, -5, -15, -12, -2, 7, 18, 35, 50,
- 59, 63, 65, 61, 53, 48, 46, 44, 43, 46, 49, 43, 27, 10, -6, -25,
- -45, -53, -53, -60, -75, -87, -90, -90, -88, -81, -75, -72, -65, -48, -25, -6,
- 5, 10, 13, 18, 31, 49, 60, 58, 44, 28, 12, -1, -7, -7, -1, 8,
- 23, 41, 54, 61, 65, 66, 63, 56, 48, 43, 41, 42, 44, 43, 37, 25,
- 8, -12, -32, -44, -49, -53, -64, -80, -91, -95, -93, -89, -85, -82, -78, -68,
- -50, -27, -6, 0, -1, 0, 0, 0, 1, 2, 3, 6, 9, 13, 17, 19,
- 13, -4, -15, -10, 4, 19, 26, 15, -9, -16, 6, -2, -18, 38, 64, 21,
- -48, 30, 82, -23, -63, -50, -26, -7, 12, 26, 47, 83, 100, 3, -108, -87,
- -30, -6, 5, 18, 33, 46, 47, 21, -52, -46, 48, 3, -54, -32, 22, 25,
- -7, 12, 9, -18, -33, -24, 2, 44, 88, 92, 10, -28, -1, 1, 20, 42,
- 1, -17, 53, 72, 12, -16, -74, -31, 127, 52, 1, -35, -46, 13, 39, -13,
- -13, 13, 12, 11, 8, -57, -80, -44, -5, 14, 18, 6, -13, -26, -11, -8,
- -24, 3, 30, 14, -28, -12, 41, -2, -37, -35, -23, -12, -1, 6, 17, 34,
- 53, 19, -55, -67, -32, -13, -5, 2, 12, 19, 24, 14, -24, -47, 12, 11,
- -36, -35, -1, 18, -3, 0, 5, -13, -25, -22, -5, 19, 53, 69, 21, -28,
- -10, -5, 6, 28, 8, -25, 23, 57, 17, -17, -49, -63, 84, 70, 3, -23,
- -50, -6, 36, -2, -20, 8, 14, 9, 13, -37, -82, -58, -19, 8, 17, 10,
- -9, -26, -19, -7, -24, -9, 25, 22, -17, -28, 33, 16, -32, -37, -27, -15,
- -4, 4, 13, 27, 48, 35, -35, -72, -43, -17, -7, -1, 9, 16, 23, 17,
- -12, -51, -7, 21, -27, -40, -12, 19, 6, -3, 5, -9, -22, -23, -8, 11,
- 42, 68, 38, -23, -16, -6, 3, 25, 19, -24, 8, 54, 31, -13, -33, -76,
- 46, 95, 13, -13, -48, -20, 32, 13, -22, 2, 15, 10, 15, -17, -77, -67,
- -31, 3, 17, 15, -3, -21, -23, -7, -20, -18, 18, 27, -4, -34, 17, 33,
- -21, -36, -29, -16, -6, 4, 11, 23, 42, 47, -12, -69, -54, -22, -8, -2,
- 7, 15, 22, 20, -2, -46, -27, 23, -13, -41, -22, 15, 16, -2, 4, -5,
- -18, -21, -10, 5, 32, 64, 53, -12, -21, -6, 0, 21, 27, -16, -6, 48,
- 42, -6, -22, -71, 2, 106, 31, -6, -41, -32, 22, 25, -18, -4, 15, 12,
- 14, -1, -64, -74, -42, -5, 16, 19, 4, -16, -25, -10, -14, -23, 9, 29,
- 9, -31, -2, 42, -5, -33, -30, -18, -8, 3, 9, 19, 36, 51, 10, -58,
- -63, -29, -11, -2, 4, 13, 20, 21, 6, -35, -44, 16, 1, -38, -30, 7,
- 23, 3, 2, -2, -16, -20, -12, 2, 23, 56, 62, 3, -24, -7, -2, 17,
- 30, -5, -17, 37, 49, 4, -17, -57, -37, 99, 55, 0, -31, -41, 9, 33,
- -10, -11, 13, 14, 12, 9, -47, -78, -53, -15, 12, 20, 9, -10, -24, -14,
- -11, -25, -2, 27, 18, -21, -20, 39, 13, -29, -31, -20, -9, 1, 8, 17,
- 30, 49, 29, -41, -70, -39, -15, -4, 2, 11, 17, 21, 11, -22, -52, 0,
- 14, -31, -36, -4, 25, 11, 1, -1, -13, -19, -13, 0, 15, 45, 65, 20,
- -24, -10, -4, 12, 30, 8, -22, 24, 52, 17, -14, -39, -61, 71, 81, 8,
- -21, -44, -5, 34, 2, -16, 9, 16, 11, 14, -29, -76, -62, -27, 6, 20,
- 15, -4, -21, -19, -9, -23, -12, 22, 25, -8, -30, 26, 30, -20, -31, -23,
- -11, -1, 8, 14, 25, 44, 42, -19, -69, -50, -20, -6, 1, 9, 15, 20,
- 15, -11, -51, -19, 20, -20, -39, -15, 23, 20, 2, 0, -11, -17, -14, -2,
- 9, 35, 63, 37, -19, -14, -5, 8, 28, 18, -22, 9, 50, 28, -11, -26,
- -68, 32, 100, 22, -13, -43, -18, 30, 15, -17, 4, 16, 12, 15, -12, -69,
- -69, -39, -2, 18, 19, 2, -17, -22, -10, -19, -20, 15, 27, 4, -31, 7,
- 41, -7, -30, -25, -13, -3, 6, 12, 22, 38, 48, 3, -61, -60, -27, -9,
- 0, 7, 13, 19, 17, -2, -44, -37, 18, -7, -39, -24, 15, 28, 7, 0,
- -9, -16, -14, -3, 6, 25, 57, 49, -9, -18, -7, 3, 25, 26, -15, -4,
- 45, 38, -5, -18, -61, -8, 103, 42, -6, -37, -30, 21, 25, -13, -3, 16,
- 13, 14, 2, -56, -73, -49, -12, 15, 21, 8, -11, -23, -13, -15, -24, 4,
- 28, 14, -25, -12, 42, 9, -26, -26, -15, -5, 5, 11, 19, 32, 48, 22,
- -46, -67, -36, -12, -2, 4, 12, 17, 18, 4, -33, -50, 6, 6, -35, -31,
- 4, 31, 14, 0, -8, -15, -14, -4, 4, 17, 48, 57, 4, -21, -8, -1,
- 21, 30, -5, -15, 36, 44, 5, -14, -46, -40, 88, 67, 2, -29, -37, 9,
- 31, -6, -9, 14, 15, 13, 11, -40, -74, -58, -24, 9, 22, 13, -6, -21,
- -17, -13, -25, -6, 25, 21, -13, -25, 33, 26, -19, -27, -18, -6, 3, 10,
- 16, 27, 45, 36, -26, -69, -46, -17, -4, 2, 10, 15, 18, 9, -22, -55,
- -11, 15, -26, -36, -8, 30, 23, 2, -6, -14, -14, -6, 4, 11, 37, 59,
- 19, -20, -10, -4, 16, 31, 7, -20, 23, 47, 15, -13, -32, -58, 58, 88,
- 13, -21, -40, -5, 32, 4, -13, 10, 17, 12, 14, -23, -70, -65, -35, 1,
- 20, 17, 0, -18, -20, -12, -23, -16, 19, 25, -1, -30, 16, 39, -8, -26,
- -20, -8, 1, 9, 14, 23, 39, 44, -5, -63, -57, -24, -7, 1, 8, 13,
- 17, 12, -12, -52, -30, 17, -15, -38, -18, 23, 32, 7, -6, -13, -14, -7,
- 3, 8, 27, 55, 33, -16, -13, -6, 10, 30, 17, -20, 10, 46, 25, -9,
- -21, -60, 19, 100, 31, -13, -39, -17, 27, 15, -13, 4, 17, 13, 15, -8,
- -61, -69, -46, -10, 17, 21, 6, -13, -22, -13, -20, -22, 10, 27, 9, -27,
- -4, 44, 6, -24, -22, -11, -1, 8, 13, 20, 33, 46, 14, -50, -65, -33,
- -11, 0, 5, 12, 15, 14, -4, -43, -46, 10, -2, -36, -27, 13, 36, 15,
- -4, -13, -14, -8, 3, 7, 18, 49, 43, -7, -16, -7, 5, 27, 24, -14,
- -3, 42, 33, -3, -16, -51, -17, 97, 51, -3, -38, -5, -13, 1, -7, 5,
- -22, -32, -35, -32, -43, -35, -55, -42, -66, -48, -80, -57, -17, -128, -59, -76,
- 0, -26, 1, -33, 21, 3, 16, 15, 26, 43, 28, 66, 6, 97, 40, 103,
- 67, 101, 102, 98, 94, 21, 98, 90, 57, 78, 89, 81, 61, -6, 54, 4,
- 62, 19, 27, 34, 12, 16, 14, -17, 19, -5, -2, -13, -38, -24, -3, -33,
- -14, -11, -16, 0, -13, 7, -26, -13, -16, 6, -57, -23, -28, -13, -9, -34,
- -32, -20, -87, -62, -28, -38, -75, -37, -27, -41, -71, -48, -30, -44, -83, -67,
- -52, -48, -45, -46, -45, -63, -47, -40, -32, -45, -24, -32, -43, -21, -17, 0,
- 21, 26, 43, 51, 62, 47, 41, 55, 57, 68, 34, 53, 63, 62, 71, 60,
- 61, 56, 53, 56, 54, 38, 50, 58, 50, 40, 28, 54, 39, 41, 38, 22,
- 32, 20, -3, 19, -1, -7, -6, -16, -16, -14, -27, -29, -46, -66, -61, -51,
- -54, -61, -41, -50, -47, -52, -55, -45, -44, -28, -58, -56, -31, -37, -36, -32,
- -18, -16, -34, -29, -9, -21, -20, -30, -22, -17, -19, -8, -12, -14, -6, -14,
- -6, -11, -2, 4, -6, 9, 8, 17, 23, 13, 31, 13, 24, 30, 28, 29,
- 30, 43, 34, 37, 52, 42, 44, 50, 67, 59, 49, 54, 48, 43, 51, 45,
- 42, 62, 47, 39, 37, 36, 24, 28, 13, 3, 9, -11, -3, -9, -14, -18,
- -34, -27, -29, -39, -42, -38, -46, -37, -46, -43, -41, -35, -38, -31, -38, -34,
- -39, -39, -34, -48, -44, -47, -49, -54, -52, -44, -53, -37, -47, -38, -31, -38,
- -27, -19, -19, -15, -16, 0, 0, 2, 7, 13, 29, 22, 32, 32, 39, 47,
- 41, 40, 55, 48, 41, 44, 57, 43, 36, 47, 43, 42, 37, 32, 32, 27,
- 33, 36, 30, 23, 25, 25, 22, 18, 22, 20, 16, 8, 6, 12, 7, 0,
- 1, 3, -5, -14, -9, -7, -8, -19, -15, -16, -23, -21, -21, -32, -31, -29,
- -26, -27, -29, -33, -26, -29, -30, -39, -28, -41, -43, -35, -34, -32, -29, -28,
- -28, -25, -27, -24, -27, -27, -27, -22, -23, -17, -9, -10, -14, -10, -8, -4,
- -2, -1, -3, 5, 4, 10, 11, 7, 13, 11, 14, 27, 22, 22, 22, 27,
- 36, 34, 36, 37, 45, 44, 47, 48, 51, 49, 52, 51, 52, 48, 50, 47,
- 48, 42, 40, 29, 33, 24, 22, 12, 5, 0, -3, -5, -9, -21, -21, -25,
- -19, -28, -28, -30, -33, -39, -42, -42, -46, -46, -45, -42, -43, -47, -47, -36,
- -32, -30, -34, -31, -22, -29, -29, -30, -26, -28, -30, -21, -26, -27, -21, -19,
- -16, -11, -12, -8, -2, 1, -4, 1, 0, 1, 9, 8, 7, 12, 10, 13,
- 20, 17, 18, 21, 26, 29, 30, 30, 29, 34, 33, 34, 33, 30, 32, 33,
- 28, 33, 29, 35, 32, 31, 30, 31, 30, 25, 27, 24, 21, 21, 20, 16,
- 17, 12, 6, 4, -3, 1, -6, -7, -11, -13, -11, -10, -8, -13, -12, -9,
- -17, -14, -19, -24, -22, -24, -30, -32, -30, -33, -37, -39, -40, -42, -39, -41,
- -39, -40, -41, -35, -35, -35, -37, -36, -33, -30, -25, -25, -19, -16, -16, -10,
- -6, -7, -4, -2, 1, 3, 6, 10, 9, 15, 17, 18, 17, 13, 19, 18,
- 17, 19, 20, 24, 24, 27, 27, 29, 30, 26, 28, 28, 27, 28, 26, 25,
- 24, 25, 20, 19, 17, 18, 15, 12, 13, 10, 6, 8, 6, 3, 4, 3,
- 0, -3, 0, -1, -2, -5, -4, -5, -4, -5, -6, -8, -9, -9, -12, -11,
- -16, -16, -15, -15, -13, -17, -16, -17, -17, -21, -20, -25, -24, -24, -24, -26,
- -30, -30, -27, -30, -26, -26, -27, -27, -25, -24, -19, -20, -17, -13, -12, -8,
- -8, -8, -6, -5, -2, -1, 0, 3, 8, 10, 12, 16, 18, 24, 25, 25,
- 28, 30, 28, 32, 33, 31, 32, 31, 35, 33, 31, 31, 27, 28, 26, 23,
- 23, 20, 22, 18, 16, 13, 11, 9, 5, 4, -2, -2, -3, -8, -9, -11,
- -12, -13, -15, -15, -15, -15, -15, -14, -12, -12, -13, -13, -8, -11, -10, -12,
- -10, -12, -12, -8, -8, -9, -9, -9, -8, -9, -10, -11, -11, -10, -13, -14,
- -13, -16, -16, -17, -17, -18, -19, -18, -17, -16, -16, -15, -15, -13, -12, -10,
- -12, -10, -9, -8, -6, -6, -3, 0, 0, 1, 2, 2, 3, 4, 4, 5,
- 6, 7, 8, 9, 10, 11, 12, 12, 13, 14, 14, 15, 15, 15, 16, 16,
- 16, 16, 16, 16, 16, 16, 16, 16, 15, 15, 14, 13, 13, 12, 11, 10,
- 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, -1, -1, -2, -3, -4, -5,
- -5, -6, -7, -7, -8, -9, -9, -10, -11, -11, -12, -12, -13, -13, -13, -13,
- -14, -14, -14, -15, -15, -15, -15, -15, -15, -16, -16, -16, -15, -15, -15, -14,
- -13, -13, -12, -11, -10, -9, -8, -7, -6, -5, -4, -2, -1, 0, 1, 2,
- 4, 5, 6, 7, 8, 9, 10, 11, 12, 12, 13, 13, 14, 14, 15, 15,
- 15, 15, 16, 16, 16, 16, 17, 17, 17, 17, 17, 17, 16, 16, 15, 15,
- 14, 14, 13, 12, 11, 10, 9, 7, 6, 5, 3, 1, 0, -2, -4, -5,
- -7, -9, -10, -11, -13, -14, -15, -15, -16, -17, -17, -18, -18, -18, -18, -18,
- -18, -18, -18, -18, -18, -18, -18, -17, -17, -16, -16, -15, -14, -14, -13, -12,
- -11, -10, -9, -8, -7, -6, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5,
- 6, 7, 8, 9, 9, 10, 11, 11, 12, 13, 13, 13, 14, 14, 14, 15,
- 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 14, 14, 14, 13, 12, 12,
- 11, 10, 9, 8, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0, -1, 0,
- 0, -1, 2, 1, 0, 1, 4, 2, 2, 2, 5, 2, 5, 5, 8, 4,
- 13, 15, 19, -62, -65, 56, -18, -128, -39, 15, -57, -10, 19, -22, -11, 36,
- 30, 5, 19, 25, 17, 21, 21, 16, 21, 18, 17, 17, 15, 14, 13, 12,
- 10, 6, 8, 6, 6, -1, 1, -4, 7, -10, -36, 35, 64, -25, -18, 83,
- 50, 22, 39, 21, 19, -4, -20, 28, 0, -88, -55, -5, -55, -83, -64, -58,
- -77, -61, -22, -39, -57, -15, 2, -14, -9, -1, 1, 1, 2, 9, 5, 6,
- 11, 9, 9, 10, 11, 12, 12, 10, 9, 9, 13, 7, 3, 14, 4, -3,
- 2, 2, 17, 40, 12, 14, 55, 58, 44, 39, 38, 37, 6, 4, 31, -6,
- -50, -25, -15, -49, -52, -41, -60, -68, -32, -25, -47, -36, -9, -5, -7, -3,
- 3, 4, 6, 8, 11, 9, 10, 14, 14, 11, 13, 15, 14, 13, 14, 12,
- 11, 12, 12, 8, 8, 3, 4, 5, -1, 8, 32, 21, 14, 43, 50, 39,
- 47, 39, 20, 23, 16, 5, -9, -23, -26, -34, -48, -37, -48, -71, -56, -34,
- -43, -49, -36, -20, -14, -13, -9, -4, -1, 1, 3, 6, 6, 6, 9, 10,
- 8, 10, 11, 11, 11, 11, 10, 10, 10, 10, 6, 6, 4, 3, 6, -3,
- 2, 25, 23, 16, 34, 38, 43, 51, 31, 19, 38, 22, -10, -7, 0, -25,
- -45, -34, -32, -54, -62, -47, -39, -45, -47, -36, -24, -19, -16, -11, -6, -3,
- 0, 2, 4, 6, 7, 8, 10, 11, 9, 11, 12, 11, 11, 12, 11, 10,
- 10, 8, 7, 6, 3, 5, 4, 0, 13, 28, 23, 19, 36, 50, 42, 30,
- 31, 39, 24, -6, -2, 7, -21, -40, -27, -34, -51, -51, -44, -42, -45, -45,
- -37, -27, -22, -18, -13, -9, -6, -2, 1, 2, 5, 7, 7, 9, 11, 10,
- 10, 12, 12, 11, 12, 11, 10, 10, 9, 7, 7, 4, 5, 7, 1, 7,
- 27, 24, 15, 34, 47, 37, 32, 36, 36, 26, 4, -1, 4, -13, -30, -27,
- -34, -47, -46, -42, -43, -45, -44, -38, -31, -25, -21, -17, -12, -8, -5, -1,
- 1, 3, 5, 6, 8, 9, 10, 10, 10, 11, 11, 11, 11, 11, 10, 9,
- 7, 7, 6, 3, 6, 5, 6, 17, 23, 19, 29, 40, 35, 33, 36, 34,
- 26, 14, 3, 0, -6, -18, -26, -32, -39, -40, -38, -39, -41, -40, -36, -31,
- -27, -23, -19, -15, -12, -8, -4, -2, 0, 3, 4, 5, 7, 8, 9, 9,
- 9, 10, 10, 10, 10, 10, 9, 8, 8, 8, 7, 8, 10, 11, 14, 19,
- 22, 25, 28, 29, 29, 29, 27, 21, 14, 7, -1, -5, -11, -19, -26, -29,
- -31, -32, -33, -34, -33, -32, -29, -26, -24, -21, -18, -15, -12, -9, -6, -4,
- -2, 0, 2, 3, 5, 6, 7, 7, 8, 8, 9, 9, 9, 9, 9, 9,
- 10, 10, 11, 12, 14, 16, 18, 20, 22, 23, 24, 24, 23, 20, 17, 12,
- 7, 2, -3, -8, -13, -17, -21, -23, -25, -26, -27, -27, -27, -26, -25, -23,
- -21, -19, -17, -14, -12, -9, -7, -5, -3, -1, 1, 2, 4, 5, 6, 6,
- 7, 7, 8, 8, 9, 9, 10, 10, 11, 12, 13, 15, 16, 18, 19, 21,
- 22, 22, 22, 21, 19, 17, 13, 9, 4, 0, -5, -10, -14, -18, -21, -23,
- -25, -26, -26, -26, -26, -25, -23, -22, -20, -18, -15, -13, -11, -9, -6, -4,
- -2, 0, 1, 3, 4, 5, 6, 7, 7, 8, 8, 8, 9, 9, 10, 11,
- 12, 13, 14, 15, 17, 18, 20, 21, 21, 21, 21, 19, 17, 14, 11, 7,
- 2, -3, -7, -11, -15, -19, -21, -23, -25, -25, -26, -25, -25, -24, -22, -21,
- -19, -17, -15, -12, -10, -8, -6, -4, -2, 0, 1, 3, 4, 5, 6, 6,
- 7, 8, 8, 9, 9, 10, 11, 11, 12, 13, 15, 16, 17, 19, 20, 20,
- 21, 20, 19, 18, 15, 12, 8, 4, 0, -4, -9, -13, -16, -19, -21, -23,
- -24, -25, -25, -25, -24, -23, -21, -20, -18, -16, -14, -12, -9, -7, -5, -3,
- -2, 0, 1, 3, 4, 5, 6, 6, 7, 8, 8, 9, 10, 10, 11, 12,
- 13, 14, 15, 17, 18, 19, 20, 20, 20, 19, 18, 16, 13, 10, 6, 2,
- -2, -6, -10, -13, -16, -19, -21, -23, -24, -24, -24, -24, -23, -22, -20, -19,
- -17, -15, -13, -11, -8, -6, -5, -3, -1, 0, 2, 3, 4, 5, 6, 7,
- 7, 8, 9, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 19, 20,
- 19, 18, 16, 14, 11, 8, 4, 0, -3, -7, -11, -14, -17, -19, -21, -22,
- -23, -23, -23, -23, -22, -21, -19, -18, -16, -14, -12, -10, -8, -6, -4, -2,
- -1, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 10, 11, 12, 12, 13,
- 14, 15, 16, 17, 18, 19, 19, 19, 18, 17, 15, 12, 9, 6, 3, -1,
- -5, -9, -12, -15, -17, -19, -21, -22, -23, -23, -23, -22, -21, -20, -18, -17,
- -15, -13, -11, -9, -7, -6, -4, -2, -1, 1, 2, 3, 4, 5, 6, 7,
- 8, 9, 9, 10, 11, 12, 13, 14, 15, 16, 17, 17, 18, 18, 18, 17,
- 16, 14, 12, 10, 7, 4, 0, -3, -6, -9, -12, -15, -17, -18, -20, -20,
- -21, -21, -21, -20, -19, -18, -17, -15, -14, -12, -10, -9, -7, -5, -4, -2,
- -1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 14,
- 15, 15, 16, 16, 16, 16, 16, 15, 14, 12, 11, 8, 6, 3, 0, -3,
- -6, -9, -12, 1, -1, 2, -1, 4, 2, 8, 5, 10, -5, 0, 5, 17,
- -11, 0, 19, -17, 26, 65, 15, 29, 3, 35, 67, 50, 88, 59, 117, 28,
- -6, -16, 29, 63, 62, -40, 59, 22, -95, -49, -55, 19, 36, -15, 26, -117,
- 60, 8, -101, -115, 23, 60, -32, -106, -84, -88, -127, -99, -117, -110, -56, -42,
- -53, -79, -44, 43, 10, -11, 72, 22, 61, 10, -92, -106, -111, -35, -68, -128,
- -67, -36, -118, -97, -96, -4, 75, 70, 113, 36, 73, 115, 37, 6, 79, 97,
- 89, -8, -38, -8, -72, -8, -29, -35, 73, 98, 66, 12, 40, 113, 106, 87,
- 126, 112, 127, 87, -3, -21, -23, 40, 14, -68, -20, 21, -57, -67, -67, -4,
- 69, 53, 90, 17, 36, 78, -7, -54, -2, 32, 21, -71, -109, -89, -124, -103,
- -114, -113, -37, -4, -30, -88, -83, 15, 13, -35, 42, 28, 33, 14, -90, -92,
- -104, -37, -34, -115, -73, -9, -75, -89, -85, -29, 67, 51, 97, 55, 47, 115,
- 46, -9, 42, 90, 96, 26, -36, 11, -43, -25, -6, -37, 59, 104, 88, 31,
- 22, 96, 116, 69, 110, 119, 119, 109, 11, -15, -26, 18, 37, -45, -32, 34,
- -13, -62, -62, -30, 61, 47, 75, 46, 14, 72, 14, -58, -35, 16, 30, -38,
- -109, -78, -109, -116, -102, -123, -57, -2, -11, -58, -95, -18, 22, -41, -3, 36,
- 20, 31, -69, -94, -100, -72, -21, -91, -92, -9, -33, -82, -81, -57, 48, 52,
- 70, 81, 35, 97, 69, -10, 8, 66, 94, 55, -27, 4, -5, -40, -1, -33,
- 30, 102, 101, 61, 19, 70, 121, 72, 77, 123, 112, 121, 36, -13, -21, -10,
- 38, -18, -43, 27, 25, -40, -59, -45, 40, 54, 52, 68, 15, 56, 35, -48,
- -58, -12, 25, -10, -98, -84, -83, -122, -101, -123, -81, -8, -3, -28, -85, -47,
- 20, -28, -39, 23, 18, 31, -38, -99, -92, -97, -35, -66, -102, -26, -3, -60,
- -77, -69, 18, 59, 47, 87, 46, 73, 86, 3, -13, 34, 80, 70, -8, -12,
- 19, -32, -12, -21, 3, 91, 105, 87, 34, 51, 114, 89, 53, 106, 115, 119,
- 65, -10, -13, -25, 20, 4, -45, 9, 44, -8, -49, -51, 14, 61, 39, 68,
- 34, 39, 51, -30, -67, -41, 7, 5, -76, -96, -65, -111, -110, -115, -103, -20,
- -1, -9, -58, -65, 8, -9, -55, -6, 17, 24, -11, -94, -89, -102, -64, -50,
- -101, -51, 6, -30, -66, -71, -12, 59, 40, 72, 67, 58, 91, 24, -21, 6,
- 56, 74, 14, -22, 23, -8, -24, -14, -13, 71, 106, 101, 62, 42, 101, 105,
- 49, 76, 114, 114, 87, 3, -12, -23, -6, 13, -37, -11, 45, 24, -29, -49,
- -8, 57, 40, 53, 54, 32, 56, -6, -65, -61, -21, 6, -52, -101, -65, -85,
- -115, -109, -116, -42, 0, -1, -27, -65, -12, 7, -51, -37, 7, 17, 6, -76,
- -95, -94, -91, -52, -90, -76, -2, -4, -46, -66, -35, 46, 46, 49, 78, 57,
- 85, 50, -17, -13, 26, 64, 34, -22, 9, 18, -22, -14, -18, 42, 103, 105,
- 88, 50, 83, 114, 63, 49, 96, 110, 99, 26, -14, -15, -23, 6, -24, -29,
- 33, 45, 0, -38, -23, 44, 50, 37, 60, 38, 52, 21, -54, -70, -48, -7,
- -31, -95, -78, -63, -104, -108, -117, -69, -4, -1, -5, -47, -30, 13, -33, -58,
- -14, 8, 11, -50, -99, -87, -101, -70, -77, -92, -22, 10, -22, -52, -46, 23,
- 55, 36, 70, 66, 74, 69, -2, -23, 1, 43, 43, -11, -8, 29, -4, -17,
- -16, 18, 91, 105, 102, 71, 72, 112, 83, 40, 70, 101, 102, 50, -10, -10,
- -24, -10, -13, -36, 14, 52, 27, -18, -28, 26, 58, 33, 51, 49, 46, 40,
- -34, -70, -66, -31, -22, -81, -92, -56, -83, -105, -112, -91, -17, 0, 2, -22,
- -37, 7, -12, -61, -39, -5, 7, -27, -93, -90, -96, -90, -72, -95, -48, 9,
- -1, -33, -46, 0, 55, 37, 50, 72, 68, 77, 20, -25, -15, 17, 40, 3,
- -20, 22, 19, -12, -14, 2, 70, 105, 106, 92, 72, 104, 100, 48, 46, 83,
- 98, 70, 3, -12, -16, -23, -11, -34, -8, 46, 47, 11, -21, 8, 57, 41,
- 36, 53, 45, 48, -6, -64, -72, -57, -28, -61, -98, -65, -60, -94, -105, -103,
- -41, 1, 0, -1, -29, -6, 5, -48, -60, -26, -3, -12, -74, -97, -86, -100,
- -80, -89, -74, -6, 13, -10, -35, -18, 41, 48, 33, 64, 68, 75, 46, -15,
- -25, -7, 24, 16, -20, 4, 33, 5, -11, -5, 43, 98, 105, 105, 85, 93,
- 110, 67, 35, 59, 87, 81, 25, -13, -9, -23, -18, -27, -25, 30, 55, 37,
- -1, -3, 46, 53, 29, 44, 47, 48, 20, -48, -72, -72, -47, -48, -93, -82,
- -51, -73, -96, -102, -66, -6, 0, 5, -10, -16, 10, -26, -66, -49, -20, -10,
- -51, -98, -86, -93, -93, -85, -88, -32, 14, 8, -16, -23, 22, 54, 32, 45,
- 67, 70, 61, 4, -27, -21, 2, 17, -13, -13, 29, 26, -1, -5, 23, 83,
- 104, 106, 100, 90, 110, 87, 40, 38, 68, 80, 45, -6, -9, -14, -24, -23,
- -32, 8, 52, 53, 25, 1, 31, 60, 35, 30, 45, 45, 36, -24, -68, -76,
- -67, -49, -80, -94, -57, -54, -81, -95, -82, -23, 2, 1, 4, -12, 4, -5,
- -57, -65, -40, -20, -36, -87, -94, -83, -97, -87, -90, -57, 2, 18, 2, -12,
- 8, 10, -20, 30, 25, 21, 14, 4, 15, -48, -33, 11, -70, 54, -5, -21,
- -8, -3, 73, -52, 65, -55, 80, -28, -67, -3, -13, 21, -49, -2, 11, 36,
- 59, -60, 34, -28, 21, -25, -45, 54, 5, 0, -19, -12, 20, 54, -51, -23,
- 22, 36, -59, -20, 8, 28, -9, -54, 127, -44, 69, -128, 5, 69, -8, -98,
- 45, 69, 20, -97, 23, -7, 121, -81, -2, -21, 51, -67, -14, -24, 127, -60,
- 45, -116, 127, -29, -93, -23, 107, -5, -21, -62, 37, 41, 29, -74, -63, 103,
- 24, -59, -44, 62, 43, -28, -46, 7, 72, 19, -70, -47, 42, 53, -68, -13,
- 37, 59, -38, -60, 39, 66, 27, -128, 36, 77, 15, -74, -15, 75, 38, -49,
- -11, -39, 16, -8, -30, 35, 41, -1, -2, 17, -68, 99, -97, 60, -49, 32,
- -44, -29, 82, -26, 39, -35, 10, 38, -20, -21, -92, 83, -24, 13, 31, -33,
- 22, 45, -31, -24, 9, -24, -32, 42, -17, 34, 7, -27, 6, 61, -9, -34,
- -5, -8, -17, -6, -34, 17, 43, -9, 35, -34, 16, 27, -24, -17, -17, 5,
- -17, 42, -31, 22, 17, -26, -22, 32, 41, -27, -25, -10, -5, 16, -2, 13,
- -1, 48, -33, -27, 6, 16, 13, -37, -11, 18, 25, -42, -11, 46, -7, -15,
- 9, 15, 4, -3, -36, -24, 31, -8, 14, 12, 27, -19, -17, -14, -7, 42,
- -5, -15, 5, 1, -15, 14, 43, -19, 1, -25, -35, 16, 16, 29, -12, 8,
- -14, 1, 21, -8, -12, -22, -4, 24, 26, -16, -22, 37, 3, -41, 7, 4,
- 3, 30, 4, -27, 11, -6, -26, 33, 23, -23, -14, -20, -7, -4, 36, 0,
- 18, 10, -27, 1, 1, 16, -1, -4, -44, -5, 17, 9, 13, -4, -3, 31,
- 24, -14, -26, 9, -27, -28, 19, 22, 32, -11, -15, 5, 15, -23, -21, 16,
- 14, 18, -11, -26, 13, 10, -12, -12, 11, 14, -6, -13, -3, 6, -6, 3,
- 12, 32, 14, -22, -45, -10, 37, 11, -50, -11, 50, 22, -13, -4, -4, 15,
- -16, -33, 7, 34, -9, -14, -1, 21, 15, -14, -12, -6, 7, 8, 2, 0,
- -5, 6, 15, 4, -9, 13, 3, -51, -18, 27, 10, 5, -11, 6, -1, 5,
- 22, 2, -14, -39, -12, 19, 17, 4, 11, 5, -25, 2, 23, 8, 2, -3,
- -39, -22, 4, 18, 6, 14, 25, 20, -17, -20, 17, 7, -43, -38, -18, 17,
- 24, -6, 30, 44, 6, -36, -20, 7, 24, 1, -69, -25, 47, 15, -4, 35,
- 19, -18, -22, -12, 20, 39, -36, -49, 9, 28, -16, 9, 34, 36, -22, -69,
- -16, 39, 7, -28, -3, 33, -18, -7, 18, 53, 24, -37, -61, -10, 38, 2,
- -24, -11, 12, 17, 0, 28, 50, -5, -59, -57, 22, 14, -15, -5, 22, 9,
- -20, 19, 33, 31, -33, -62, -13, -2, 45, -9, -4, -3, 19, 8, -8, 40,
- 8, -16, -44, -19, 16, 3, 23, -32, 22, 5, -9, 5, 26, 21, -27, -18,
- -45, 3, 15, 0, 7, 7, 7, 13, 18, -10, 3, -5, -30, -30, -3, 9,
- 31, 17, -10, 19, 28, -33, -20, 31, 14, -67, -27, 13, 20, 29, 1, -2,
- 24, -3, -26, -12, 32, -7, -31, -17, 5, 22, 11, -6, 6, 7, 2, 7,
- 5, -12, -22, -17, -24, 22, 47, 1, 2, 10, 5, -29, -5, 13, 1, -30,
- -28, -5, 23, 25, 6, 5, 1, 7, 0, 5, 3, -33, -37, -6, 19, 20,
- 26, -1, -15, 21, 9, -14, -13, 0, -11, -24, -9, 9, 23, 1, 1, 32,
- 11, -25, -18, 5, -5, -6, -9, -10, 2, 18, 4, 12, 6, -2, -8, 2,
- 2, -7, 2, -22, -5, 17, 25, 15, -5, -1, -24, -8, -10, -5, 12, 7,
- -4, -10, 4, 8, 22, 11, -1, -12, -31, -17, 6, 12, 11, 5, -3, -1,
- 22, 0, -4, 3, -18, -17, -3, 16, 9, 2, -5, 0, 4, -9, 18, 17,
- -22, -19, -8, -6, 21, 11, -6, -16, 33, 13, -15, -3, -15, 1, -3, -10,
- -7, 8, 17, -11, 9, 19, 0, 5, 0, -18, -13, 2, -20, 10, 29, -11,
- -13, 5, 11, 16, 4, -25, -21, 13, -5, 1, 3, -1, 6, 13, -7, -1,
- 17, -6, -6, -9, -6, -3, -1, 1, 18, 11, -22, 2, 18, -2, -15, 1,
- 5, -12, -10, -7, 9, 26, 10, -11, 5, 0, -7, -3, -11, -9, -3, 2,
- -10, 19, 28, -3, -3, -4, 9, -14, -5, -7, 8, -3, -27, 5, 37, 11,
- -2, 3, -27, -15, 12, -2, 14, 2, -8, -16, 22, 11, -1, 10, -17, -8,
- -5, -23, 2, 29, 8, -21, 8, 12, 6, 8, -17, 3, -2, -12, -27, 16,
- 25, -5, -7, 2, 19, 1, -15, 7, 2, -5, -34, 2, 18, 17, -10, 2,
- 18, -1, -12, -10, 5, 1, -16, -9, 12, 21, 4, -10, 2, 12, 1, -19,
- -11, 20, 5, -14, -21, 5, 17, -5, 3, 17, 4, -25, -5, 5, 4, 0,
- -5, 2, 2, -1, 1, 13, 0, -11, -8, 3, 2, -1, -3, -3, 11, 8,
- -6, 2, 7, 4, -5, -23, -2, 14, -1, -15, -2, 15, 10, 1, -4, 16,
- 1, -24, -12, 8, 8, -20, -2, 14, 13, 10, 2, 2, -9, -6, -9, -3,
- 5, 7, -3, -9, 0, 2, 8, 3, -1, 2, -4, 0, -1, -1, -1, -2,
- -8, -14, -19, -28, -51, -53, -49, -48, -49, -44, -37, -30, -23, -14, -8, -11,
- -5, 3, 11, 2, 0, 8, 19, 10, 1, 6, 18, 15, 4, 4, 17, 19,
- 13, 9, 20, 27, 26, 26, 33, 42, 45, 53, 59, 68, 69, 83, 89, 92,
- 85, 88, 91, 80, 56, 37, 29, 9, -25, -54, -65, -74, -94, -113, -112, -103,
- -101, -103, -93, -79, -66, -62, -50, -41, -33, -27, -17, -11, -12, -8, 0, 7,
- -1, -2, 5, 15, 8, -1, 3, 15, 13, 2, 2, 12, 17, 12, 8, 15,
- 23, 24, 25, 29, 38, 42, 50, 56, 65, 68, 78, 87, 91, 87, 87, 91,
- 84, 64, 43, 33, 16, -14, -44, -60, -70, -87, -107, -111, -105, -101, -103, -96,
- -84, -70, -64, -55, -45, -36, -30, -22, -14, -14, -11, -4, 4, 0, -3, 1,
- 11, 8, -1, 0, 10, 12, 3, 0, 9, 15, 11, 7, 14, 22, 23, 24,
- 28, 37, 42, 49, 55, 64, 67, 78, 87, 91, 88, 88, 93, 86, 67, 47,
- 36, 20, -10, -40, -56, -67, -84, -104, -109, -105, -101, -103, -96, -85, -71, -65,
- -56, -46, -38, -31, -23, -16, -15, -12, -6, 2, -1, -5, 0, 9, 6, -1,
- -1, 8, 11, 3, 0, 8, 14, 11, 7, 13, 21, 23, 23, 27, 37, 41,
- 48, 54, 63, 67, 77, 86, 91, 89, 89, 93, 87, 70, 51, 39, 23, -6,
- -36, -53, -64, -81, -101, -107, -103, -100, -102, -96, -85, -72, -66, -57, -47, -39,
- -32, -25, -17, -16, -13, -7, 0, -3, -5, -1, 7, 6, -2, -2, 7, 9,
- 2, -1, 7, 13, 10, 7, 12, 20, 22, 23, 27, 36, 41, 48, 54, 63,
- 68, 77, 87, 91, 91, 91, 95, 89, 73, 54, 43, 27, -1, -31, -49, -61,
- -78, -98, -105, -102, -99, -101, -96, -85, -73, -66, -58, -48, -40, -33, -26, -19,
- -17, -14, -9, -2, -4, -6, -3, 5, 4, -3, -3, 5, 8, 1, -1, 6,
- 12, 10, 7, 11, 20, 22, 23, 27, 35, 41, 47, 54, 62, 68, 76, 86,
- 91, 91, 92, 96, 91, 76, 58, 46, 30, 3, -27, -45, -57, -75, -94, -103,
- -100, -98, -100, -96, -85, -74, -67, -59, -49, -41, -34, -28, -20, -19, -15, -10,
- -3, -5, -7, -4, 3, 3, -4, -4, 4, 7, 1, -2, 5, 11, 9, 6,
- 11, 19, 21, 22, 26, 35, 40, 46, 53, 61, 67, 76, 86, 91, 92, 93,
- 97, 93, 78, 61, 49, 33, 7, -22, -41, -54, -72, -91, -100, -99, -97, -100,
- -96, -86, -74, -67, -60, -51, -42, -35, -29, -22, -20, -17, -11, -5, -6, -8,
- -5, 2, 1, -5, -5, 2, 5, 0, -3, 3, 10, 8, 5, 10, 18, 21,
- 21, 25, 34, 39, 45, 52, 61, 67, 75, 85, 91, 92, 94, 97, 94, 81,
- 64, 52, 37, 11, -18, -37, -51, -69, -88, -98, -98, -96, -99, -95, -86, -75,
- -68, -61, -52, -44, -36, -30, -23, -21, -17, -13, -6, -7, -9, -6, 0, 0,
- -5, -5, 1, 4, -1, -3, 2, 8, 8, 5, 10, 17, 20, 21, 25, 33,
- 39, 45, 51, 60, 66, 75, 85, 91, 93, 94, 98, 95, 83, 67, 55, 40,
- 15, -14, -33, -48, -66, -85, -96, -96, -95, -98, -95, -86, -75, -69, -62, -53,
- -45, -38, -32, -25, -22, -19, -14, -8, -9, -10, -8, -2, -1, -6, -7, -1,
- 2, -2, -4, 1, 7, 6, 5, 8, 16, 19, 20, 24, 32, 38, 44, 50,
- 59, 66, 74, 84, 91, 93, 95, 99, 97, 85, 70, 58, 43, 18, -10, -30,
- -45, -63, -82, -93, -95, -94, -97, -95, -87, -76, -70, -63, -54, -46, -39, -33,
- -26, -23, -20, -16, -10, -10, -12, -9, -3, -3, -7, -8, -2, 1, -2, -5,
- 0, 6, 6, 4, 8, 15, 18, 20, 23, 31, 37, 43, 50, 58, 65, 74,
- 83, 91, 93, 96, 100, 98, 87, 72, 61, 46, 22, -6, -27, -42, -60, -79,
- -91, -94, -93, -97, -95, -87, -77, -70, -64, -55, -47, -40, -34, -28, -25, -22,
- -17, -12, -11, -13, -11, -5, -4, -8, -9, -3, 0, -4, -6, -1, 5, 5,
- 3, 7, 14, 18, 19, 23, 30, 36, 42, 49, 57, 65, 73, 83, 90, 94,
- 96, 100, 99, 89, 75, 63, 49, 25, -2, -23, -38, -56, -76, -88, -92, -92,
- -95, -94, -87, -77, -71, -65, -57, -48, -41, -36, -29, -26, -23, -19, -13, -12,
- -14, -12, -7, -6, -9, -10, -5, -1, -4, -7, -2, 2, 5, 4, 6, 12,
- 18, 20, 24, 30, 38, 45, 52, 61, 70, 79, 89, 99, 106, 109, 113, 115,
- 109, 96, 81, 66, 44, 16, -12, -32, -52, -74, -92, -101, -104, -107, -108, -103,
- -94, -85, -78, -70, -60, -52, -45, -38, -33, -29, -25, -19, -16, -17, -16, -12,
- -9, -10, -12, -9, -5, -5, -7, -5, 0, 3, 3, 5, 11, 17, 20, 23,
- 29, 37, 44, 51, 59, 69, 78, 88, 98, 105, 110, 114, 116, 110, 98, 84,
- 69, 48, 20, -7, -29, -49, -71, -89, -99, -102, -105, -107, -103, -94, -86, -79,
- -71, -62, -54, -47, -40, -34, -30, -26, -21, -18, -18, -17, -14, -10, -12, -14,
- -11, -5, -10, 43, -94, 44, -13, 27, -98, 1, 9, 77, 63, 4, 8, -128,
- 63, -73, 78, -116, 127, -14, 111, -87, -67, -43, -45, 38, 53, 99, -37, 14,
- -51, -58, -23, -32, 34, 27, 75, 9, 51, -104, -71, -33, 27, 67, 0, -1,
- 25, 0, -35, 1, -70, 28, -4, 109, 3, 5, -42, -7, 42, -15, 37, -62,
- 67, -14, 48, -85, -46, -94, 37, 35, 23, 15, -79, 35, -50, 91, -64, 40,
- -69, 46, 20, 43, -21, -51, 8, -1, 95, -47, 69, -104, 98, -44, 74, -61,
- -14, -19, 7, 52, -40, 8, -89, 58, -53, 106, -106, 42, -82, 61, -1, -8,
- -10, -59, 53, -18, 85, -83, 63, -73, 89, -32, 50, -62, 10, 13, 20, 62,
- -81, 41, -84, 88, -32, 41, -78, 27, -30, 51, -6, -42, 6, -49, 74, -41,
- 41, -89, 27, -33, 57, 0, -16, -8, -4, 45, 8, 20, -63, 36, -29, 75,
- -23, -17, -23, -14, 45, -7, 17, -56, 20, -12, 45, -16, -13, -31, 6, 31,
- -7, 17, -81, 40, -35, 73, -34, 0, -31, 10, 35, -4, 19, -60, 44, -30,
- 83, -66, 41, -87, 59, -6, 23, -4, -59, 34, -33, 77, -70, 49, -89, 88,
- -45, 63, -62, 4, -20, 18, 46, -49, 45, -101, 91, -56, 78, -79, 35, -51,
- 67, -12, -2, -14, -49, 66, -35, 72, -87, 51, -74, 83, -38, 29, -36, -10,
- 23, 3, 30, -59, 27, -59, 91, -44, 41, -63, 12, 2, 23, 8, -36, 14,
- -35, 66, -38, 32, -59, 25, -11, 40, -6, -25, -2, -24, 55, -25, 29, -58,
- 30, -17, 41, -18, -17, -3, -13, 50, -25, 26, -63, 35, -23, 50, -22, -5,
- -18, 0, 33, -19, 22, -67, 57, -39, 63, -45, 6, -27, 13, 23, -6, 15,
- -55, 44, -42, 70, -59, 36, -60, 56, -13, 15, -9, -50, 49, -38, 72, -63,
- 37, -65, 67, -48, 55, -51, 10, 2, -5, 45, -61, 46, -83, 91, -58, 72,
- -69, 23, -27, 35, -8, -3, -2, -33, 66, -61, 79, -100, 67, -60, 66, -26,
- 13, -21, -13, 23, -11, 29, -49, 40, -53, 80, -67, 52, -63, 28, 6, -1,
- 23, -45, 25, -30, 42, -25, 22, -42, 33, -26, 39, -26, -9, 10, -28, 61,
- -50, 33, -43, 18, 2, 6, 4, -18, 4, -8, 24, -21, 22, -49, 50, -40,
- 52, -35, -10, 17, -34, 64, -53, 38, -47, 37, -28, 40, -47, 33, -32, 28,
- 3, -20, 30, -69, 79, -75, 88, -72, 39, -34, 22, -7, 9, -18, 1, 19,
- -27, 58, -89, 81, -90, 89, -58, 42, -27, -5, 16, -21, 29, -34, 28, -37,
- 59, -65, 72, -90, 69, -45, 31, 6, -36, 40, -53, 56, -47, 39, -42, 40,
- -38, 50, -52, 34, -31, 7, 32, -47, 62, -79, 66, -51, 41, -27, 12, -10,
- 12, -5, 3, -5, -18, 33, -44, 70, -75, 60, -52, 27, 4, -19, 22, -29,
- 27, -15, 18, -31, 26, -36, 50, -41, 35, -31, 3, 19, -37, 55, -62, 51,
- -38, 25, -11, 1, -13, 12, -7, 13, 4, -33, 38, -56, 72, -64, 52, -43,
- 20, 6, -20, 25, -40, 34, -25, 38, -41, 43, -68, 68, -59, 53, -28, -7,
- 27, -45, 63, -70, 56, -60, 59, -41, 48, -56, 39, -43, 35, -3, -19, 40,
- -70, 85, -81, 76, -75, 48, -36, 41, -20, 12, -23, 0, 16, -23, 51, -76,
- 78, -82, 80, -57, 29, -23, 3, 14, -2, 9, -29, 17, -31, 55, -51, 53,
- -66, 49, -27, 17, 3, -35, 36, -33, 44, -27, 11, -30, 24, -18, 37, -29,
- 4, -3, -15, 45, -47, 42, -57, 46, -19, 18, -11, -20, 10, -3, 24, -18,
- 14, -46, 52, -50, 64, -57, 25, -14, 1, 33, -42, 30, -52, 50, -28, 47,
- -54, 32, -49, 53, -25, 14, -4, -34, 57, -54, 69, -78, 46, -45, 52, -21,
- 21, -37, 7, 1, 3, 29, -57, 56, -74, 90, -66, 47, -51, 16, 6, 10,
- 10, -29, 9, -32, 58, -47, 59, -84, 65, -49, 52, -24, -18, 14, -30, 61,
- -39, 31, -57, 39, -38, 67, -56, 37, -46, 26, 10, -15, 18, -49, 45, -27,
- 42, -37, 11, -24, 30, -15, 21, -34, 15, -5, 11, 5, -24, 11, -16, 30,
- -16, 6, -20, 7, 3, 11, -9, -5, -6, 4, 16, -15, 9, -29, 22, -6,
- 14, -6, -16, 9, -12, 28, -22, 15, -27, 22, -11, 21, -23, 5, -10, 8,
- 17, -22, 19, -42, 41, -31, 39, -37, 20, -20, 19, -3, -7, 2, -17, 27,
- -20, 30, -43, 30, -34, 38, -24, 13, -13, -1, 16, -16, 19, -36, 28, -21,
- 30, -22, 7, -17, 11, 2, 1, 1, -19, 22, -21, 32, -34, 18, -21, 17,
- 6, -8, 5, -25, 21, -13, 24, -24, 12, -22, 24, -11, 10, -14, -7, 15,
- -11, 28, -36, 21, -30, 30, -10, 10, -13, -5, 6, -2, 14, -22, 15, -25,
- 33, -22, 23, -31, 11, -6, 8, 11, -21, 14, -28, 32, -23, 25, -31, 19,
- -15, 19, -7, -7, 1, -13, 26, -19, 24, -37, 25, -24, 30, -18, 6, -9,
- -2, 17, -16, 17, -34, 27, -19, 28, -21, 6, -15, 10, 4, 0, 2, -20,
- 22, -19, -21, 0, -3, -3, 2, 1, -1, 2, -2, -1, 4, 3, -3, -15,
- -21, -20, -23, -42, -45, -31, -27, -17, -8, 9, 29, 41, 44, 33, 20, 13,
- 6, 12, 16, 25, 43, 44, 33, 33, 35, 15, -5, -3, 8, 16, 8, -10,
- -6, 8, 4, -4, 1, -18, -38, -43, -51, -54, -55, -71, -85, -68, -58, -61,
- -50, -33, -27, -15, -5, 22, 67, 100, 109, 114, 110, 91, 69, 50, 37, 35,
- 46, 48, 37, 36, 14, -24, -38, -42, -38, -38, -59, -91, -86, -57, -44, -32,
- -15, -26, -44, -30, -30, -30, -16, -31, -50, -34, -43, -59, -49, -44, -52, -62,
- -69, -50, -4, 47, 83, 105, 120, 111, 88, 72, 55, 57, 76, 69, 59, 55,
- 41, 10, -18, -32, -28, -19, -36, -68, -76, -72, -71, -46, -35, -47, -43, -43,
- -61, -48, -28, -25, -22, -19, -23, -15, -7, 3, 4, -8, -28, -37, -5, 42,
- 72, 107, 127, 122, 117, 90, 48, 37, 48, 51, 54, 56, 43, 24, -8, -37,
- -33, -11, -28, -55, -61, -75, -75, -51, -58, -55, -33, -33, -41, -35, -30, -21,
- -16, -17, -24, -26, -20, -18, -17, -12, -36, -72, -65, -45, -6, 53, 88, 106,
- 119, 107, 71, 52, 50, 59, 75, 87, 85, 76, 43, -1, -7, 9, -1, -13,
- -34, -69, -80, -74, -80, -73, -65, -67, -65, -56, -44, -33, -23, -18, -24, -25,
- -16, -20, -9, -1, -21, -38, -55, -64, -40, 3, 39, 82, 113, 114, 95, 71,
- 54, 56, 68, 76, 87, 94, 57, 10, -9, -17, -17, -15, -35, -60, -75, -89,
- -92, -85, -76, -71, -74, -70, -53, -41, -20, -9, -9, 4, 4, 10, 33, 38,
- 25, 15, -17, -43, -33, -15, 3, 40, 77, 94, 91, 69, 37, 31, 33, 37,
- 68, 96, 82, 53, 25, 8, 22, 28, 9, -9, -27, -46, -56, -65, -62, -61,
- -60, -51, -51, -39, -25, -23, -11, -3, -15, -10, 5, 12, 20, 18, -11, -41,
- -52, -47, -34, -2, 33, 65, 82, 70, 51, 45, 28, 21, 49, 74, 86, 74,
- 33, 5, 10, 14, 7, -10, -28, -45, -67, -68, -73, -76, -66, -66, -65, -46,
- -39, -31, -9, -3, -6, 1, 8, 22, 41, 49, 33, 8, -16, -34, -30, -17,
- 7, 49, 73, 64, 63, 50, 19, 5, 13, 32, 62, 65, 37, 8, -5, 4,
- -1, -8, -15, -36, -50, -57, -71, -65, -53, -58, -49, -37, -40, -28, -10, -3,
- 0, 2, -2, 5, 30, 41, 36, 22, -7, -33, -39, -46, -30, 15, 44, 56,
- 72, 65, 44, 21, 2, 15, 42, 59, 49, 18, 2, -3, -4, 0, -10, -25,
- -34, -52, -65, -59, -56, -50, -37, -33, -33, -25, -12, -2, 10, 12, 3, 6,
- 27, 42, 52, 43, 16, -3, -24, -48, -41, -11, 16, 48, 67, 78, 75, 49,
- 21, 13, 36, 64, 63, 47, 25, -1, -2, 2, -12, -18, -28, -53, -65, -71,
- -76, -70, -55, -53, -49, -41, -35, -24, -1, 5, 1, 4, 8, 28, 51, 43,
- 26, 18, -14, -42, -51, -49, -23, 5, 31, 55, 67, 58, 26, -2, 11, 35,
- 49, 55, 35, 8, 3, -2, -5, -6, -13, -30, -38, -49, -61, -56, -45, -43,
- -36, -31, -37, -25, -7, 1, 6, 1, -10, 11, 33, 29, 27, 17, -6, -34,
- -58, -67, -57, -34, -4, 21, 50, 63, 37, 11, 8, 17, 45, 63, 55, 39,
- 26, 12, 11, 10, -1, -11, -19, -35, -51, -52, -52, -45, -35, -36, -41, -31,
- -24, -9, 9, -3, -12, 2, 19, 33, 40, 37, 25, -3, -30, -51, -59, -42,
- -24, -3, 38, 58, 51, 32, 8, 2, 25, 45, 50, 49, 35, 18, 16, 19,
- 10, 9, 4, -13, -27, -36, -45, -36, -24, -32, -29, -31, -33, -10, 6, 1,
- -4, -6, 4, 19, 30, 37, 30, 12, -13, -48, -59, -57, -56, -35, 2, 31,
- 48, 41, 12, -2, 7, 25, 41, 52, 44, 29, 25, 22, 18, 20, 15, 1,
- -6, -26, -38, -28, -26, -21, -17, -31, -33, -19, -4, 0, -8, -16, -15, -11,
- 9, 19, 22, 24, -2, -34, -49, -61, -70, -57, -32, 4, 38, 46, 26, 5,
- -1, 7, 29, 45, 44, 38, 32, 23, 27, 30, 23, 24, 14, -8, -16, -24,
- -24, -12, -10, -19, -27, -26, -9, -2, -4, -6, -16, -14, -2, 8, 23, 34,
- 17, -6, -26, -47, -61, -62, -50, -18, 26, 50, 48, 31, 12, 6, 24, 40,
- 44, 51, 40, 29, 34, 28, 27, 32, 20, 7, -5, -23, -26, -19, -9, -12,
- -25, -25, -17, -8, 1, -4, -13, -12, -16, -9, 13, 26, 23, 8, -13, -37,
- -55, -71, -78, -59, -18, 16, 35, 34, 8, -3, 4, 13, 31, 40, 34, 34,
- 29, 23, 30, 31, 27, 21, 7, -6, -21, -21, -10, -10, -19, -24, -28, -17,
- -6, -8, -9, -9, -19, -21, -5, 12, 23, 22, 5, -16, -34, -55, -80, -78,
- -56, -22, 18, 33, 24, 14, 3, 7, 25, 31, 37, 41, 33, 29, 29, 32,
- 33, 30, 24, 7, -16, -22, -18, -15, -14, -24, -31, -22, -13, -12, -8, -6,
- -18, -27, -22, -6, -5, -1, -1, -1, 1, 2, 7, 13, 19, 10, -12, -31,
- -13, 17, 29, -4, -29, 24, 53, 18, 92, 15, -15, 23, 13, -35, -52, 127,
- 9, 3, -9, 31, -63, -64, -5, -50, 14, 33, -29, -42, 0, 43, 39, -15,
- -59, -45, 3, 33, 12, -35, -10, 51, 18, 49, 55, -28, 16, 4, 3, -64,
- 54, 53, -12, 0, 5, -4, -72, -7, -31, -14, 26, -2, -37, -14, 17, 35,
- 4, -33, -45, -12, 15, 21, -16, -23, 22, 28, 12, 55, -7, -2, 7, 7,
- -34, -10, 65, -4, 1, -5, 14, -46, -28, -9, -29, 13, 13, -23, -23, 4,
- 27, 18, -17, -39, -25, 5, 20, 0, -26, 1, 34, 7, 41, 24, -20, 11,
- 1, -6, -45, 53, 22, -6, -4, 9, -17, -52, -4, -30, -6, 20, -9, -29,
- -8, 18, 27, -2, -33, -36, -6, 16, 13, -20, -16, 27, 19, 18, 49, -17,
- 3, 2, 6, -42, 9, 55, -9, 1, -3, 9, -54, -19, -16, -24, 16, 7,
- -27, -19, 8, 28, 12, -22, -40, -20, 8, 19, -7, -25, 9, 31, 7, 48,
- 9, -14, 9, 2, -17, -35, 62, 9, -2, -6, 13, -30, -44, -4, -31, 2,
- 18, -15, -27, -3, 22, 24, -8, -36, -32, -2, 17, 8, -23, -9, 31, 13,
- 28, 40, -21, 8, 1, 3, -47, 29, 43, -9, 0, 1, 1, -57, -11, -22,
- -17, 19, 2, -28, -14, 12, 29, 7, -27, -39, -14, 11, 17, -13, -22, 17,
- 27, 10, 51, -4, -7, 7, 5, -27, -19, 64, -1, 1, -6, 14, -41, -34,
- -8, -30, 8, 15, -20, -24, 2, 25, 20, -14, -38, -27, 2, 18, 2, -25,
- -1, 33, 9, 37, 29, -21, 11, 0, -3, -46, 46, 29, -7, -2, 7, -9,
- -54, -6, -27, -10, 20, -4, -28, -9, 16, 28, 1, -30, -37, -8, 14, 14,
- -18, -17, 25, 22, 16, 50, -13, 1, 4, 5, -37, 0, 59, -7, 2, -4,
- 12, -49, -24, -13, -26, 13, 11, -23, -19, 6, 27, 15, -19, -39, -21, 6,
- 18, -4, -24, 7, 32, 8, 45, 15, -16, 10, 2, -12, -39, 58, 16, -3,
- -5, 11, -22, -48, -4, -30, -2, 19, -10, -26, -4, 20, 25, -5, -34, -33,
- -4, 16, 10, -21, -11, 30, 16, 25, 43, -19, 7, 1, 4, -44, 20, 49,
- -8, 1, -1, 6, -54, -15, -19, -20, 17, 6, -26, -15, 10, 29, 9, -23,
- -39, -16, 9, 17, -10, -22, 15, 29, 10, 50, 2, -10, 8, 3, -22, -26,
- 63, 5, 0, -6, 14, -34, -39, -6, -30, 4, 17, -15, -24, 0, 24, 22,
- -11, -36, -28, 1, 17, 5, -23, -3, 32, 12, 34, 33, -21, 10, 0, 0,
- -46, 39, 36, -7, -1, 4, -3, -54, -9, -24, -14, 19, 0, -26, -10, 14,
- 28, 4, -27, -37, -11, 12, 15, -15, -18, 22, 24, 14, 50, -9, -2, 5,
- 5, -32, -8, 61, -3, 2, -5, 14, -44, -29, -10, -27, 10, 13, -20, -20,
- 4, 26, 17, -16, -37, -23, 4, 18, -1, -23, 5, 32, 9, 42, 20, -18,
- 11, 1, -7, -41, 53, 22, -4, -3, 9, -14, -50, -6, -27, -7, 19, -6,
- -26, -5, 18, 26, -2, -31, -34, -6, 14, 11, -19, -12, 28, 19, 22, 45,
- -17, 4, 2, 5, -40, 11, 54, -6, 2, -3, 10, -51, -20, -16, -23, 14,
- 9, -23, -15, 8, 28, 12, -20, -38, -18, 7, 17, -7, -22, 13, 30, 10,
- 47, 7, -12, 9, 2, -17, -31, 61, 10, 0, -5, 13, -26, -43, -6, -29,
- 0, 18, -11, -23, -1, 22, 23, -8, -34, -30, -1, 15, 7, -22, -5, 31,
- 14, 30, 37, -20, 9, 0, 2, -44, 30, 42, -7, 1, 2, 2, -53, -12,
- -21, -17, 17, 4, -25, -11, 12, 28, 6, -25, -37, -13, 10, 15, -13, -18,
- 20, 26, 13, 49, -5, -5, 6, 4, -27, -16, 62, 1, 2, -5, 14, -38,
- -34, -9, -28, 6, 15, -16, -20, 3, 25, 19, -13, -36, -25, 2, 16, 1,
- -23, 3, 32, 11, 38, 25, -19, 11, 0, -4, -43, 46, 29, -4, -2, 7,
- -8, -51, -8, -25, -10, 18, -2, -25, -7, 16, 27, 0, -28, -35, -8, 12,
- 12, -17, -13, 26, 21, 19, 46, -14, 2, 3, 4, -36, 2, 57, -4, 3,
- -4, 12, -46, -25, -13, -25, 11, 12, -20, -16, 7, 27, 14, -18, -37, -20,
- 5, 16, -5, -21, 10, 31, 10, 45, 12, -14, 10, 1, -12, -36, 57, 16,
- -1, -4, 11, -20, -46, -6, -28, -4, 18, -8, -23, -3, 20, 24, -5, -32,
- -31, -4, 13, 8, -20, -6, 29, 17, 27, 39, -19, 7, 0, 3, -42, 21,
- 47, -6, 2, 0, 7, -51, -17, -18, -20, 15, 7, -23, -12, 10, 28, 8,
- -22, -37, -15, 8, 15, -10, -19, 18, 27, 13, 47, 0, -8, 8, 3, -24,
- -20, 52, -36, -2, 0, -2, 3, 5, -4, -28, 22, -43, 36, -13, -127, -43,
- 2, -18, 126, 78, -127, -48, 68, -74, -67, 33, 62, 83, 42, -32, -46, -70,
- -26, 115, 21, -66, 72, 52, -27, 44, 50, 50, 61, 28, -12, 3, -59, 49,
- 3, -19, 39, 94, 16, 31, 6, 29, 3, -100, -1, -4, -60, 19, 7, -29,
- -28, -38, -3, -47, -20, -21, -1, 5, -55, -12, -55, -39, 26, 47, -22, -9,
- -41, -21, -19, -37, 0, 45, -56, 24, 75, -50, -9, 31, 28, 26, 13, -3,
- -15, -27, 1, 1, -31, -10, 38, -1, 7, 43, 19, 21, 41, 33, 9, -17,
- -3, -42, -76, -30, -8, -9, -1, 21, 22, 38, 32, 22, 0, -18, -32, -58,
- -12, 5, -48, -13, 64, 29, -2, 2, 19, 43, 25, -19, -39, -69, -92, -15,
- 23, 30, 30, 51, 37, 35, 37, 30, -27, -63, 5, -30, -56, -16, 26, 52,
- 20, 14, 59, 27, -9, 22, -4, -20, -37, -17, -34, -34, -1, 35, 26, 31,
- 5, -16, 4, 33, 22, 8, 5, -28, -41, -20, -10, -6, -2, -16, 12, 31,
- -23, 7, -2, -39, -28, -13, 8, 5, 16, -4, -6, -18, -24, -27, -50, -6,
- 5, 12, 0, -2, -14, -23, 5, -28, -10, 2, 28, 15, 2, 22, 27, 41,
- 31, 2, 12, 31, 5, 12, -6, 15, 40, 34, 18, 26, 26, 12, 34, 23,
- 34, 30, 22, 10, -26, -22, 1, 0, -1, 12, -4, -21, -5, -5, -20, -31,
- -25, -24, -42, -44, -41, -41, -37, -29, -28, -29, -40, -17, -21, -38, -42, -38,
- -40, -36, -13, -14, -8, -15, -7, -6, 5, 12, -1, -17, -1, 9, 2, 16,
- 30, 27, 37, 36, 38, 36, 36, 19, 45, 45, 33, 26, 33, 28, 36, 31,
- 17, 12, 22, 11, 11, 17, 5, -13, 6, 10, 2, -6, 2, 9, 15, -6,
- -8, -23, -44, -3, -11, -35, -25, -35, -23, -21, 0, -11, -21, -17, 11, -6,
- -11, -17, -33, -16, -16, -4, -7, -7, -9, -4, 1, 1, -3, 6, 7, 4,
- -17, -11, -6, -4, 1, 3, 6, 4, 5, -4, 17, 7, 3, 9, -20, 0,
- -7, -3, -5, 4, 9, 16, 2, 3, 8, 15, 15, 1, -3, 8, -1, 5,
- 14, 7, 4, 8, -8, 2, -3, 5, 11, 5, 3, -4, 10, 17, 13, -11,
- -5, 1, -3, 0, -6, -12, 2, -3, 13, -5, -25, -15, -7, 4, 1, -8,
- -4, -12, -16, 3, 9, -6, 3, -21, -4, 4, -14, 1, -1, -2, 3, -8,
- -5, 0, 7, -2, -3, -1, 3, -9, 5, -4, -17, -1, 9, 3, 7, 1,
- -4, -3, 5, 2, -7, -9, 12, -6, -14, -16, 2, -1, 16, 2, 2, 7,
- -6, -26, 3, -2, -4, -2, 10, 3, -7, 3, 8, 9, 5, 4, 1, -5,
- -5, 11, 8, 7, 11, 12, -1, -5, -16, 13, 7, 2, 11, 4, -4, 9,
- -8, -8, 14, 11, -8, 0, -1, -5, -2, -1, -10, -5, -9, -9, -16, -12,
- -8, -16, 5, -10, -4, -11, -3, 1, 0, -3, -5, -13, -9, -2, -8, 5,
- -9, -7, -2, 2, -11, -7, 13, 8, -3, 2, 7, -2, -1, 5, 0, 11,
- 6, 13, 15, 1, -4, 9, 5, 3, 8, -3, -4, 16, 4, 11, 9, 0,
- 8, 1, -6, -5, -18, 3, 7, -18, -4, 0, -3, -3, -6, -4, -5, -5,
- -10, -2, -9, -5, -2, -4, -11, -2, 1, -5, -2, 11, -6, -9, 1, 4,
- -6, -1, -5, 1, 2, 9, 5, 0, 4, 4, -2, 7, 0, -10, 5, 2,
- -3, 0, -6, 7, -4, -3, 6, -1, -6, -1, -1, 2, -2, -6, -3, 0,
- 8, -6, 4, -1, -5, -3, 3, 1, -5, -6, -2, -3, 5, 6, 0, 7,
- -3, 3, -1, 0, -2, 9, 1, 1, -3, 4, 5, -5, 2, -2, 2, -11,
- -2, -4, 11, 4, 5, 0, -5, -12, -6, -5, -5, 3, -2, -2, 2, 2,
- 1, 0, -1, -8, -5, -5, -3, 2, -1, 3, -1, 3, 0, -1, 0, -1,
- 1, 1, -4, -4, 2, -2, 1, -6, 1, 2, 4, 2, 2, -5, -1, 6,
- -3, -1, -4, 11, 3, -9, -2, -6, -3, 2, 4, 2, 1, 2, 4, 3,
- -6, -4, -3, -2, 0, 2, -2, 5, 2, -1, 3, -9, -3, -3, -4, -4,
- -1, 0, -2, 7, 3, 1, 1, -2, -4, -2, -3, -2, -4, 2, 4, -1,
- 2, 3, 0, 3, -1, 0, -2, -2, -3, 1, -1, -4, 5, -1, 5, 0,
- -3, -2, -1, -4, 3, -1, -3, -2, -2, -1, 0, 0, 1, -1, 0, -2,
- -2, 0, -3, -1, 0, 0, 1, 1, -2, -1, 1, -3, 1, 2, 0, -1,
- 0, -1, 1, 5, -2, 1, -3, -3, -1, -3, 0, 1, 3, 2, -1, -1,
- -2, -2, -1, 1, 0, -1, -2, -2, -2, -3, -3, -3, -2, -2, -2, -2,
- -2, -2, -2, -1, 0, 1, 1, -2, -2, 0, 0, 2, -3, -16, -22, -20,
- -28, -35, -31, -17, 19, 33, 36, 33, 34, 40, 36, 25, 18, 20, 18, 14,
- 17, 12, 14, 10, -24, -36, -27, -38, -55, -69, -66, -47, -33, -13, 3, 5,
- 10, 22, 25, 15, 28, 43, 41, 51, 56, 58, 58, 31, -18, -52, -64, -71,
- -92, -105, -98, -77, -50, -17, 23, 59, 85, 99, 94, 76, 55, 14, -9, -5,
- -7, -18, -17, -35, -53, -53, -33, -23, -33, -36, -15, 17, 32, 24, 12, 19,
- 37, 54, 49, 38, 21, -14, -44, -30, -22, -15, 5, 8, -1, -26, -42, -46,
- -49, -51, -37, -17, 1, -4, -19, -4, 45, 84, 91, 79, 57, 3, -30, -29,
- -35, -25, -8, -6, -26, -61, -75, -73, -77, -72, -54, -19, 9, 6, -10, 3,
- 47, 85, 92, 103, 92, 45, 21, 6, 4, 16, 27, 27, -1, -48, -69, -78,
- -80, -84, -72, -33, -10, -24, -41, -20, 40, 82, 99, 123, 102, 69, 49, 30,
- 27, 34, 42, 41, -2, -58, -96, -108, -103, -106, -83, -37, -10, -18, -38, -18,
- 40, 65, 92, 110, 84, 44, 1, -26, -23, -7, 21, 32, 7, -39, -78, -84,
- -79, -82, -61, -19, 5, -14, -52, -25, 25, 59, 102, 127, 116, 86, 40, 13,
- 4, 9, 27, 29, 4, -47, -88, -94, -87, -83, -56, -18, 15, -13, -49, -30,
- -2, 29, 69, 87, 80, 50, 9, -15, -27, -10, 18, 44, 36, -9, -45, -53,
- -53, -46, -33, 6, 31, -8, -36, -28, -11, 21, 54, 76, 76, 44, 4, -33,
- -53, -45, -18, 13, 10, -35, -62, -70, -61, -44, -19, 38, 63, 30, 9, 4,
- 9, 35, 60, 81, 75, 51, 14, -25, -44, -37, -9, 29, 24, -11, -41, -59,
- -51, -54, -33, 23, 35, 6, -13, -28, -18, 8, 43, 73, 76, 63, 33, -1,
- -21, -22, 10, 43, 35, 5, -32, -47, -51, -68, -44, 6, 14, 0, -21, -34,
- -25, 0, 37, 65, 73, 64, 35, 5, -22, -25, 11, 40, 39, 13, -20, -28,
- -42, -64, -32, 6, 15, -1, -25, -39, -39, -16, 19, 44, 58, 53, 27, -2,
- -39, -38, -2, 30, 40, 13, -16, -19, -45, -60, -29, 6, 17, 1, -21, -40,
- -44, -24, 9, 38, 58, 51, 38, 8, -31, -29, 0, 34, 44, 9, -11, -23,
- -58, -69, -42, -6, 9, 0, -16, -33, -36, -12, 19, 55, 72, 68, 58, 18,
- -22, -25, -6, 29, 31, 2, -5, -23, -57, -69, -45, -8, 12, 10, 0, -22,
- -24, -7, 20, 52, 61, 65, 59, 21, -15, -28, -11, 26, 20, 2, -2, -22,
- -56, -71, -49, -14, 3, 8, -5, -26, -28, -19, 14, 42, 54, 71, 67, 38,
- 8, -11, 16, 47, 37, 26, 18, -10, -51, -74, -59, -35, -19, -12, -24, -37,
- -44, -34, 0, 24, 44, 67, 64, 43, 3, -18, 11, 35, 28, 22, 18, -4,
- -47, -68, -55, -34, -11, -7, -15, -27, -43, -32, -1, 18, 42, 58, 60, 43,
- -8, -29, -6, 11, 7, 4, 4, -17, -59, -75, -66, -41, -13, -3, 1, -11,
- -29, -19, 1, 19, 42, 53, 64, 45, -8, -28, -9, 7, 4, 4, 9, -13,
- -51, -71, -69, -43, -19, -7, 3, -11, -25, -17, -2, 23, 43, 60, 78, 55,
- 1, -19, -5, 8, 3, 7, 13, -8, -41, -66, -67, -40, -19, 3, 16, 1,
- -7, -5, 10, 34, 46, 67, 87, 62, 11, -13, -1, 8, 4, 15, 20, 1,
- -33, -64, -65, -48, -30, -2, 6, -5, -14, -18, 1, 21, 32, 62, 86, 66,
- 20, -3, 6, 7, 5, 16, 20, 7, -29, -62, -65, -59, -39, -13, -5, -8,
- -22, -27, -6, 7, 17, 49, 74, 58, 14, -5, -2, -4, -3, 7, 14, 6,
- -32, -59, -66, -63, -40, -16, -2, -2, -19, -20, -1, 6, 18, 49, 77, 62,
- 21, 3, -1, -5, -2, 5, 18, 10, -26, -50, -65, -64, -43, -24, -5, -6,
- -24, -23, -8, -2, 10, 45, 75, 60, 25, 6, -4, -4, -5, 3, 20, 8,
- -20, -43, -60, -58, -45, -24, 1, -1, -15, -12, -1, 3, 16, 53, 83, 70,
- 42, 19, 9, 7, 3, 16, 29, 17, -7, -35, -55, -56, -49, -24, 2, -1,
- -11, -7, 3, 4, 16, 55, 83, 75, 50, 25, 15, 6, 0, 13, 21, 13,
- -9, -40, -58, -66, -62, -35, -11, -11, -18, -13, -3, -7, 9, 49, 75, 74,
- 51, 28, 19, 5, 1, 13, 20, 16, -3, -28, -48, -62, -61, -37, -16, -13,
- -20, -15, -12, -19, -5, 21, 50, 61, 47, 28, 15, -1, -6, 0, 9, 14,
- 1, -19, -37, -55, -56, -38, -16, -11, -13, -9, -9, -16, -8, 18, 48, 59,
- 44, 28, 9, 15, -3, 2, -5, 3, 3, 4, 1, 7, -2, 7, -4, 2,
- -124, -37, 33, -48, 7, -27, 8, -14, 77, 26, -9, 26, 7, 20, 10, 13,
- 8, 9, 7, 4, 5, 2, 3, 2, 1, -1, 0, -3, -2, -5, 1, -10,
- 11, 70, -6, 21, 5, 27, -2, 41, -15, -61, -66, -128, 0, -48, -21, -46,
- -6, -55, 23, 53, -6, 11, 2, 14, 11, 10, 11, 8, 9, 9, 8, 5,
- 8, 5, 6, 5, 6, 2, 7, -4, 6, 5, -23, 62, 29, 24, 8, 33,
- 4, 32, 36, -30, -16, -124, -58, -39, -18, -51, -3, -43, -40, 53, 19, 12,
- 4, 9, 12, 13, 10, 11, 9, 8, 11, 6, 5, 8, 6, 3, 9, 1,
- 7, 2, -5, 22, -33, 20, 37, 35, 7, 29, 14, 8, 52, -5, 17, -64,
- -84, -70, -15, -55, -23, -12, -72, 1, 28, 16, 8, 6, 7, 12, 10, 8,
- 11, 6, 8, 10, 5, 4, 10, 1, 8, 4, 2, 10, -15, 26, -16, -9,
- 14, 42, 17, 19, 29, -3, 42, 14, 28, -8, -45, -92, -37, -41, -54, 0,
- -53, -48, 2, 18, 10, 8, 4, 8, 12, 8, 10, 10, 6, 9, 10, 2,
- 10, 5, 3, 9, -2, 18, -16, 17, 3, -9, -12, 26, 28, 13, 35, 3,
- 27, 19, 31, 17, 4, -60, -67, -33, -66, -22, -22, -58, -38, 2, 11, 9,
- 7, 4, 9, 10, 8, 10, 9, 5, 12, 5, 5, 9, 2, 11, -5, 21,
- -8, 4, 10, 5, -17, -1, 28, 11, 34, 13, 20, 17, 28, 24, 27, -6,
- -61, -41, -57, -51, -17, -36, -56, -32, -1, 7, 8, 5, 6, 8, 10, 8,
- 12, 6, 9, 9, 5, 9, 1, 15, -7, 15, 5, -2, 4, 14, -3, -18,
- 15, 8, 28, 21, 20, 16, 23, 23, 29, 30, -20, -38, -45, -63, -38, -23,
- -43, -53, -29, -5, 5, 5, 5, 5, 9, 7, 11, 8, 8, 10, 5, 12,
- -2, 16, -1, 4, 11, 4, -3, 8, 15, -16, 0, 1, 16, 23, 23, 17,
- 20, 21, 21, 39, 19, -14, -28, -52, -58, -33, -28, -47, -50, -30, -6, 2,
- 5, 4, 6, 6, 9, 10, 7, 12, 3, 15, 0, 10, 8, 1, 6, 11,
- 2, -4, 20, -1, -6, -5, 4, 15, 24, 20, 18, 23, 15, 30, 38, 13,
- -6, -27, -56, -52, -30, -34, -48, -50, -28, -8, 2, 3, 5, 5, 6, 11,
- 5, 13, 3, 12, 6, 5, 10, 5, 2, 7, 13, -8, 10, 11, 0, -6,
- -4, 3, 17, 23, 16, 24, 18, 17, 36, 32, 13, -1, -30, -57, -45, -31,
- -36, -51, -49, -28, -7, -1, 3, 6, 2, 11, 5, 12, 6, 9, 10, 5,
- 8, 8, 5, -1, 16, 1, -1, 11, 9, -1, -5, -5, 4, 20, 17, 20,
- 24, 14, 23, 37, 29, 16, 2, -33, -53, -42, -30, -39, -52, -49, -27, -9,
- -3, 5, 0, 8, 5, 10, 8, 6, 10, 6, 7, 6, 11, -3, 8, 11,
- 0, 2, 11, 8, -1, -5, -7, 9, 18, 16, 24, 20, 14, 27, 35, 27,
- 21, 1, -33, -50, -38, -32, -42, -53, -48, -25, -14, -1, -2, 4, 3, 6,
- 9, 5, 9, 7, 7, 4, 12, 4, 1, 10, 6, 2, 6, 10, 4, 0,
- -6, -2, 11, 14, 18, 22, 17, 20, 32, 34, 28, 20, 0, -26, -36, -34,
- -37, -45, -54, -44, -30, -13, -8, -3, 1, 2, 6, 4, 7, 8, 8, 2,
- 8, 10, 1, 4, 6, 5, 5, 9, 6, 1, -3, -5, 3, 10, 14, 18,
- 18, 17, 26, 35, 35, 29, 17, -1, -17, -24, -32, -41, -50, -51, -44, -28,
- -18, -12, -5, -2, 2, 3, 3, 6, 9, 4, 3, 9, 6, 2, 2, 4,
- 5, 9, 10, 4, -2, -5, -1, 5, 10, 14, 16, 15, 19, 30, 38, 37,
- 29, 15, 1, -5, -14, -31, -43, -50, -52, -42, -29, -22, -16, -9, -3, 0,
- 0, 2, 6, 6, 2, 4, 7, 6, 2, 1, 2, 6, 11, 10, 2, -5,
- -4, 0, 5, 10, 14, 15, 14, 21, 32, 39, 38, 29, 14, 4, 0, -3,
- -19, -32, -40, -43, -41, -36, -31, -25, -19, -12, -9, -8, -6, -1, 2, 2,
- 0, -3, -4, -1, 3, 6, 6, 2, -3, -6, -2, 2, 2, 1, 2, 7,
- 16, 25, 32, 35, 35, 36, 36, 33, 24, 11, -3, -18, -32, -40, -42, -40,
- -36, -30, -25, -18, -12, -9, -8, -5, -1, 2, 2, 0, -3, -4, -1, 3,
- 7, 6, 2, -4, -5, -2, 2, 2, 1, 2, 8, 17, 25, 32, 35, 36,
- 36, 36, 32, 23, 10, -4, -20, -33, -41, -42, -40, -35, -30, -24, -18, -12,
- -9, -8, -5, -1, 3, 2, -1, -4, -4, -1, 4, 7, 6, 1, -4, -5,
- -2, -1, 3, 1, 3, 5, 3, -3, -1, -1, 1, -15, 1, 1, -5, -7,
- 7, -2, -4, 3, -2, -5, -1, -3, -3, -1, 6, 3, 2, 3, -26, -117,
- 35, -8, -19, 24, 58, -7, -6, 25, -9, 7, 4, 10, 2, 7, 6, 6,
- 0, 6, -2, -1, -3, -3, 8, 71, 0, 17, 27, 20, -102, -115, 39, -32,
- -18, -5, 58, -15, -12, 13, -10, -4, 1, 2, 1, 0, 6, 2, 1, 2,
- 0, -4, 0, -5, 2, 67, 9, 14, 28, 29, -72, -126, 27, -25, -19, -14,
- 58, -6, -11, 13, -5, -3, 3, 3, 4, 1, 8, 3, 3, 3, 3, -2,
- 2, -3, -3, 62, 17, 14, 27, 35, -45, -128, 11, -19, -20, -22, 53, 1,
- -12, 11, -3, -4, 2, 3, 4, 1, 7, 3, 3, 3, 3, -2, 2, -2,
- -9, 57, 22, 14, 25, 37, -23, -125, -8, -15, -20, -30, 46, 9, -12, 10,
- -2, -3, 0, 3, 3, 1, 6, 4, 2, 3, 2, -2, 1, 0, -16, 50,
- 26, 13, 22, 37, -2, -117, -27, -13, -18, -36, 36, 16, -13, 9, -2, -2,
- -2, 3, 2, 2, 4, 5, 1, 4, 2, -1, 0, 4, -20, 43, 29, 15,
- 20, 36, 14, -102, -43, -15, -16, -40, 26, 22, -12, 8, -2, -2, -3, 3,
- 1, 3, 2, 6, 1, 5, 1, 0, -1, 7, -23, 35, 31, 18, 18, 33,
- 27, -83, -57, -20, -14, -42, 14, 26, -9, 7, -2, 0, -5, 3, 1, 4,
- 1, 7, 0, 5, 1, 1, -2, 10, -24, 26, 31, 20, 17, 30, 36, -62,
- -65, -27, -12, -43, 2, 28, -7, 6, -2, 0, -5, 3, 0, 4, 0, 7,
- 0, 5, 1, 2, -4, 11, -23, 17, 32, 22, 16, 27, 42, -44, -67, -36,
- -9, -42, -8, 28, -3, 5, -1, 1, -5, 2, 0, 4, 1, 7, 1, 5,
- 1, 3, -5, 13, -22, 10, 31, 23, 17, 22, 45, -25, -66, -45, -8, -40,
- -18, 27, 0, 5, -1, 1, -5, 1, 0, 4, 0, 6, 2, 4, 2, 3,
- -6, 14, -19, 2, 29, 25, 19, 19, 47, -10, -60, -54, -10, -37, -27, 24,
- 4, 4, 0, 1, -5, 0, 0, 3, 1, 5, 2, 4, 2, 4, -7, 15,
- -16, -4, 27, 25, 21, 15, 48, 4, -51, -61, -12, -33, -34, 19, 7, 4,
- 1, 0, -4, -1, 0, 3, 2, 5, 3, 3, 3, 5, -8, 15, -11, -10,
- 24, 25, 23, 12, 45, 15, -39, -66, -18, -28, -40, 12, 10, 4, 2, 1,
- -3, -2, 0, 2, 2, 4, 3, 3, 3, 5, -8, 13, -6, -14, 19, 25,
- 25, 10, 43, 24, -25, -67, -25, -24, -45, 4, 11, 5, 3, 0, -2, -3,
- -1, 1, 2, 3, 3, 3, 2, 6, -9, 11, -2, -17, 15, 24, 27, 9,
- 39, 31, -13, -66, -33, -19, -48, -3, 11, 5, 3, 1, -2, -3, -1, 1,
- 2, 4, 3, 3, 2, 8, -9, 9, 3, -18, 10, 22, 29, 9, 35, 35,
- 0, -61, -41, -17, -49, -11, 10, 6, 3, 2, -2, -3, -2, 1, 1, 4,
- 3, 5, 1, 9, -9, 7, 6, -18, 5, 20, 29, 10, 32, 38, 11, -47,
- -45, -18, -47, -20, 5, 6, 4, 2, -1, -3, -2, 0, 1, 5, 1, 6,
- 1, 7, -7, 6, 6, -16, 1, 16, 27, 11, 29, 40, 20, -30, -43, -23,
- -46, -28, -2, 4, 4, 2, -1, -3, -2, -1, 0, 6, -1, 7, 2, 5,
- -6, 5, 6, -15, -3, 13, 25, 12, 26, 41, 26, -14, -36, -26, -44, -35,
- -11, 1, 4, 2, 0, -4, -3, -3, -1, 7, -2, 7, 4, 4, -6, 4,
- 7, -13, -6, 10, 23, 12, 24, 42, 31, 0, -24, -28, -42, -40, -19, -4,
- 4, 2, 1, -4, -3, -4, -3, 8, -3, 6, 6, 3, -6, 4, 7, -11,
- -8, 7, 20, 12, 21, 41, 34, -2, -31, -34, -29, -21, -12, -3, -4, -10,
- -7, -5, -6, -4, 5, 8, -3, -1, 7, -1, -11, -7, 0, 1, 6, 16,
- 28, 33, 33, 30, 13, -1, -26, -35, -30, -24, -14, -5, -4, -11, -7, -5,
- -6, -6, 3, 8, -2, -2, 7, 1, -11, -9, -1, 0, 4, 14, 26, 32,
- 33, 32, 17, 3, -22, -34, -31, -25, -16, -6, -3, -10, -8, -5, -6, -7,
- 2, 9, 0, -3, 6, 3, -9, -10, -2, 0, 3, 12, 24, 32, -1, 0,
- -3, -1, -8, -5, -16, -5, -14, -4, -13, -5, -1, -7, 16, -17, 28, -16,
- 47, 1, 70, 35, 97, 71, 98, 66, 32, -5, -71, -69, -122, -69, -105, -33,
- -67, -6, -35, 2, -12, -2, 4, -12, 16, -19, 29, -16, 44, 2, 66, 37,
- 92, 76, 95, 74, 33, 5, -69, -63, -122, -69, -106, -36, -66, -11, -33, -3,
- -9, -7, 7, -16, 18, -22, 29, -17, 42, 3, 61, 40, 86, 81, 91, 82,
- 34, 15, -67, -57, -122, -69, -105, -40, -64, -17, -29, -9, -6, -12, 10, -20,
- 20, -23, 28, -17, 39, 4, 56, 42, 80, 85, 88, 89, 35, 24, -63, -53,
- -119, -70, -104, -45, -62, -22, -26, -14, -2, -16, 12, -23, 20, -25, 27, -16,
- 35, 7, 51, 45, 74, 89, 85, 96, 38, 32, -58, -49, -116, -72, -102, -50,
- -60, -27, -24, -19, 0, -20, 14, -24, 20, -24, 24, -14, 31, 10, 45, 48,
- 69, 92, 82, 102, 40, 39, -53, -45, -112, -74, -100, -55, -57, -33, -21, -24,
- 3, -24, 15, -26, 19, -24, 22, -12, 27, 12, 40, 50, 63, 95, 80, 106,
- 43, 45, -47, -42, -107, -76, -97, -60, -55, -38, -18, -28, 4, -26, 15, -27,
- 18, -23, 19, -10, 23, 15, 35, 53, 59, 97, 78, 110, 47, 50, -39, -39,
- -102, -79, -94, -65, -52, -43, -16, -32, 5, -28, 14, -27, 16, -21, 15, -7,
- 18, 18, 30, 55, 54, 98, 76, 113, 51, 55, -32, -37, -96, -81, -91, -70,
- -50, -48, -15, -35, 6, -30, 13, -26, 13, -19, 11, -5, 13, 20, 25, 56,
- 50, 99, 75, 115, 56, 59, -24, -35, -90, -83, -88, -75, -48, -52, -14, -38,
- 5, -30, 11, -25, 10, -17, 7, -2, 9, 22, 21, 57, 47, 99, 75, 116,
- 61, 62, -15, -33, -82, -86, -84, -80, -47, -56, -14, -39, 4, -30, 9, -24,
- 6, -15, 3, 1, 5, 24, 17, 57, 44, 98, 75, 116, 66, 65, -6, -31,
- -75, -88, -81, -83, -46, -59, -14, -41, 3, -30, 6, -22, 3, -12, -1, 3,
- 1, 26, 13, 57, 41, 96, 75, 115, 72, 68, 2, -29, -69, -89, -78, -87,
- -45, -62, -15, -42, 0, -29, 3, -20, -1, -10, -5, 5, -2, 26, 11, 56,
- 40, 94, 76, 114, 77, 69, 12, -28, -61, -91, -75, -89, -45, -64, -16, -42,
- -2, -28, 0, -18, -5, -8, -9, 7, -6, 27, 8, 55, 38, 91, 77, 112,
- 82, 71, 20, -25, -55, -91, -73, -91, -46, -65, -18, -42, -5, -26, -4, -15,
- -10, -5, -13, 9, -9, 27, 7, 53, 37, 88, 78, 110, 87, 72, 29, -23,
- -48, -90, -71, -93, -47, -66, -21, -41, -9, -24, -8, -13, -13, -3, -16, 9,
- -11, 27, 5, 51, 37, 84, 79, 108, 93, 74, 37, -20, -42, -90, -70, -94,
- -49, -66, -24, -40, -12, -23, -12, -12, -16, -2, -18, 10, -12, 25, 5, 48,
- 37, 80, 81, 105, 98, 75, 45, -16, -36, -88, -68, -94, -51, -66, -28, -39,
- -16, -21, -15, -10, -19, -1, -21, 10, -13, 24, 4, 45, 37, 76, 82, 102,
- 102, 76, 52, -13, -30, -85, -67, -94, -54, -66, -31, -38, -20, -19, -19, -9,
- -22, 0, -22, 9, -14, 22, 4, 41, 37, 71, 83, 99, 105, 77, 59, -8,
- -25, -82, -67, -93, -56, -65, -35, -37, -23, -18, -22, -7, -25, 0, -24, 8,
- -14, 20, 5, 37, 38, 67, 84, 96, 108, 79, 65, -3, -20, -79, -66, -92,
- -59, -65, -39, -36, -27, -17, -25, -7, -27, -1, -24, 6, -14, 17, 6, 34,
- 39, 63, 84, 93, 111, 80, 71, 1, -15, -75, -66, -90, -62, -64, -43, -35,
- -31, -16, -28, -6, -28, -1, -25, 5, -14, 14, 6, 30, 39, 58, 85, 90,
- 113, 82, 76, 7, -11, -70, -66, -88, -66, -62, -46, -34, -34, -15, -30, -7,
- -30, -2, -25, 2, -13, 11, 7, 26, 40, 53, 84, 87, 115, 84, 81, 13,
- -7, -65, -66, -85, -68, -61, -50, -33, -37, -15, -32, -7, -30, -4, -25, 0,
- -12, 7, 9, 19, 37, 52, 80, 97, 118, 113, 98, 54, 7, -41, -72, -87,
- -87, -75, -65, -47, -42, -29, -30, -22, -24, -19, -19, -14, -9, -2, 8, 17,
- 36, 50, 77, 95, 117, 115, 101, 60, 13, -35, -69, -85, -88, -75, -66, -49,
- -44, -31, -31, -23, -25, -20, -20, -15, -9, -2, -1, 0, 0, 0, 0, -1,
- -1, -1, 3, 9, 14, 14, 10, -3, -17, -13, 1, 1, 23, 33, -14, -55,
- -59, -80, -75, -35, -7, 51, 40, -29, -35, -53, -128, -31, 111, 72, 46, 55,
- -19, -73, -23, 14, 64, 104, 87, 105, 68, -54, -76, -1, -18, 12, 92, 23,
- -79, -93, -105, -119, -64, -20, 39, 70, 2, -45, -52, -107, -82, 73, 106, 56,
- 53, 12, -57, -37, 14, 52, 105, 101, 94, 85, -5, -75, -25, -1, -8, 59,
- 52, -45, -89, -94, -117, -90, -42, 1, 53, 29, -29, -45, -79, -104, 3, 99,
- 78, 63, 42, -25, -49, -7, 30, 83, 112, 103, 99, 40, -54, -58, -11, -7,
- 36, 68, -4, -80, -98, -114, -106, -57, -15, 33, 42, -10, -46, -66, -97, -45,
- 68, 90, 67, 53, 4, -40, -20, 18, 60, 103, 107, 100, 69, -15, -62, -31,
- -9, 15, 60, 31, -50, -90, -108, -115, -79, -33, 11, 42, 15, -33, -58, -87,
- -75, 21, 87, 79, 63, 27, -26, -33, 1, 40, 88, 111, 105, 85, 20, -50,
- -49, -17, 5, 46, 49, -17, -77, -102, -115, -95, -49, -7, 31, 28, -15, -50,
- -76, -84, -21, 64, 84, 71, 45, -4, -32, -13, 22, 66, 103, 108, 95, 50,
- -23, -56, -32, -5, 30, 55, 14, -53, -92, -111, -107, -68, -24, 16, 34, 4,
- -37, -66, -85, -53, 32, 81, 77, 58, 17, -25, -24, 6, 46, 89, 108, 101,
- 71, 6, -49, -45, -16, 15, 49, 36, -26, -77, -103, -110, -85, -41, 0, 30,
- 20, -21, -55, -79, -72, -5, 65, 81, 67, 36, -10, -28, -8, 27, 71, 102,
- 104, 85, 34, -31, -51, -29, 1, 37, 48, 2, -57, -93, -109, -97, -58, -16,
- 20, 28, -4, -42, -70, -79, -36, 39, 78, 74, 51, 9, -24, -18, 11, 51,
- 91, 105, 94, 57, -6, -48, -41, -12, 22, 48, 26, -33, -79, -103, -104, -74,
- -32, 6, 28, 12, -27, -60, -78, -59, 8, 66, 78, 62, 27, -13, -24, -3,
- 33, 74, 100, 99, 74, 20, -35, -48, -25, 8, 40, 40, -7, -61, -94, -106,
- -88, -49, -9, 21, 21, -11, -47, -72, -71, -22, 45, 76, 71, 43, 2, -22,
- -13, 16, 56, 91, 101, 85, 43, -15, -47, -36, -6, 28, 45, 16, -38, -80,
- -102, -97, -65, -24, 11, 25, 4, -33, -63, -75, -46, 18, 66, 75, 56, 19,
- -15, -20, 2, 38, 77, 98, 93, 62, 8, -38, -44, -20, 14, 41, 32, -15,
- -64, -94, -101, -79, -40, -2, 22, 15, -17, -52, -72, -61, -9, 49, 74, 66,
- 36, -2, -21, -9, 22, 61, 91, 96, 76, 31, -22, -45, -32, 0, 32, 40,
- 7, -43, -82, -99, -89, -56, -17, 14, 21, -2, -38, -65, -69, -33, 26, 66,
- 71, 50, 13, -16, -16, 7, 43, 79, 95, 85, 50, -2, -40, -40, -14, 20,
- 40, 24, -22, -66, -93, -95, -70, -32, 3, 21, 9, -23, -55, -70, -51, 1,
- 52, 71, 60, 28, -6, -19, -4, 27, 64, 90, 91, 66, 19, -27, -43, -26,
- 6, 34, 35, -1, -48, -83, -96, -81, -47, -10, 16, 17, -9, -43, -66, -62,
- -22, 33, 66, 67, 43, 7, -16, -13, 12, 48, 80, 91, 77, 39, -10, -40,
- -36, -8, 24, 38, 17, -28, -69, -92, -89, -62, -25, 7, 19, 4, -29, -58,
- -67, -42, 10, 55, 70, 55, 22, -9, -17, 0, 33, 68, 90, 86, 57, 10,
- -31, -41, -21, 12, 36, 30, -8, -53, -85, -94, -75, -41, -5, 17, 13, -15,
- -48, -67, -57, -13, 39, 68, 64, 37, 3, -16, -9, 18, 54, 84, 91, 72,
- 30, -17, -41, -33, -2, 28, 37, 10, -35, -74, -94, -86, -56, -19, 10, 17,
- -2, -36, -63, -66, -34, 19, 60, 70, 51, 17, -11, -15, 5, 39, 74, 92,
- 83, 49, 1, -36, -40, -16, 18, 37, 24, -17, -61, -90, -93, -70, -34, 1,
- 18, 8, -22, -55, -69, -50, -2, 47, 70, 61, 31, -3, -17, -5, 26, 62,
- 88, 90, 65, 19, -25, -42, -27, 5, 33, 33, 1, -45, -81, -95, -81, -48,
- -11, 14, 15, -10, -43, -66, -61, -22, 31, 65, 68, 43, 9, -14, -11, 12,
- 49, 80, 92, 76, 38, -10, -39, -36, -8, 24, 38, 16, -27, -70, -92, -89,
- -61, -25, 7, 17, 3, -31, -59, -68, -39, 8, 55, 55, 19, 0, -9, -10,
- -14, -13, -21, -30, -32, -44, -49, -57, -65, -72, -83, -98, -104, -117, -123, -128,
- -127, -128, -128, -128, -128, -127, -128, -120, -117, -109, -100, -90, -83, -72, -66, -55,
- -50, -33, -42, -18, -29, -18, 15, -6, 11, 7, 19, 3, 38, 5, 48, 44,
- 64, 57, 97, 82, 111, 104, 110, 107, 120, 116, 125, 126, 126, 126, 126, 127,
- 117, 125, 123, 100, 127, 101, 124, 102, 121, 109, 126, 96, 125, 116, 127, 90,
- 119, 87, 127, 90, 118, 95, 123, 93, 106, 90, 100, 104, 74, 84, 73, 97,
- 72, 71, 57, 66, 80, 36, 59, 38, 55, 35, 57, -6, 64, 10, 25, 19,
- 19, -22, 65, -26, 14, 2, -17, -12, 22, -40, -3, -31, -24, -38, -1, -56,
- -6, -48, -36, -54, -19, -56, -33, -49, -69, -49, -52, -53, -60, -61, -84, -76,
- -85, -96, -95, -95, -114, -93, -117, -104, -93, -101, -98, -100, -101, -96, -78, -95,
- -71, -70, -72, -52, -63, -70, -43, -77, -41, -48, -65, -53, -53, -59, -42, -56,
- -37, -64, -54, -52, -50, -54, -56, -54, -55, -62, -51, -47, -44, -67, -60, -63,
- -56, -64, -53, -48, -61, -53, -58, -38, -48, -32, -38, -34, -28, -26, -23, -25,
- -22, -6, -7, -12, -1, 5, 6, 6, -7, 22, -4, 27, 15, 18, 24, 37,
- 30, 47, 24, 53, 29, 63, 29, 46, 46, 51, 52, 53, 36, 54, 65, 55,
- 33, 64, 36, 69, 54, 26, 62, 66, 36, 68, 30, 47, 54, 58, 20, 55,
- 31, 40, 50, 35, 19, 56, 33, 25, 46, 18, 22, 42, 21, 25, 32, 19,
- 19, 26, 18, 23, 29, 24, 7, 27, 6, 33, 8, 17, -2, 14, 3, 23,
- 14, 7, 5, -9, -13, -10, -23, -12, -16, -27, -8, -18, -15, -3, -18, -24,
- -5, -23, -9, 0, -11, 4, -1, 4, 2, 5, -2, 3, -1, -7, 4, -11,
- 1, -12, -4, -7, -10, -11, -11, -16, -23, -15, -20, -22, -23, -20, -30, -23,
- -31, -25, -32, -35, -41, -34, -44, -39, -34, -49, -33, -30, -36, -29, -33, -14,
- -24, -32, -18, -15, -7, -9, -11, 5, -14, 27, -11, 16, -10, 13, -9, 23,
- -10, 19, 10, 18, 11, 29, 1, 47, 27, -4, 45, 3, 43, 40, 14, 13,
- 57, 16, 34, 27, 22, 30, 32, 14, 24, 27, 20, 20, 17, 4, 20, 20,
- 8, 8, 0, 10, -3, 17, -8, -1, -4, 1, 0, 6, -7, -3, -3, -13,
- -5, -6, -18, -5, -28, -12, -13, -5, -11, -5, -28, -7, -15, -10, -6, -28,
- -16, -12, -17, -8, -10, -19, -10, -24, -30, -32, -26, -31, -36, -32, -33, -27,
- -25, -26, -26, -25, -25, -23, -16, -22, -10, -11, -7, -7, 4, -10, 10, -9,
- 11, -8, 4, -6, 4, -8, 3, -4, 2, -3, -5, -3, -11, -8, -6, -12,
- -11, -7, -24, -4, -17, -9, -18, -28, -16, -29, -23, -38, -24, -34, -22, -38,
- -18, -27, -10, -22, -19, -21, -2, -23, 10, -19, 0, 4, 16, 7, 0, 3,
- 17, 14, 26, 8, 25, 27, 30, 25, 38, 31, 49, 37, 42, 45, 48, 55,
- 63, 46, 54, 54, 56, 59, 56, 47, 50, 53, 47, 50, 44, 42, 35, 40,
- 31, 37, 35, 27, 20, 23, 19, 26, 24, 18, 11, 14, 18, 24, 18, 12,
- 10, 3, 12, 2, 9, 4, 0, 0, 3, -4, 11, 1, 1, -1, -5, -7,
- 1, -6, -1, 2, -4, 1, -1, -7, -9, -11, -21, -19, -20, -28, -27, -22,
- -29, -24, -26, -32, -22, -25, -31, -24, -19, -22, -11, -19, -15, -4, -5, -4,
- 0, -6, -6, 2, -9, -5, -5, -9, -10, -7, -18, -8, -14, -14, -19, -29,
- -25, -16, -25, -30, -30, -30, -21, -29, -38, -37, -36, -41, -44, -53, -48, -43,
- -44, -55, -46, -40, -33, -36, -40, -40, -28, -25, -24, -23, -17, -15, 1, -3,
- -1, 5, 2, 9, 1, 4, 12, 13, 14, 15, 9, 21, 26, 32, 31, 28,
- 28, 41, 38, 49, 45, 46, 53, 56, 57, 57, 57, 58, 55, 48, 56, 56,
- 56, 45, 39, 41, 41, 44, 42, 25, 28, 27, 24, 28, 21, 14, 17, 8,
- 15, 22, 13, 15, 16, 3, 11, 10, 4, 6, 4, -8, 0, -2, -2, -3,
- -2, 1, 3, -3, -3, -6, -8, -5, 4, 3, 2, -4, -2, -1, 5, 3,
- -2, -2, -2, 3, 7, -2, -26, -37, -34, -30, -13, -14, -21, -24, -27, -24,
- -13, -7, -15, 6, 3, -30, -50, -48, -47, -41, -26, -8, 28, 43, 38, 57,
- 63, 56, 75, 118, 127, 117, 99, 86, 85, 66, 46, 59, 80, 69, 43, 27,
- -6, -47, -74, -80, -71, -57, -40, -44, -56, -78, -88, -78, -59, -52, -51, -56,
- -57, -47, -36, -36, -39, -39, -32, -17, 6, 24, 33, 10, -14, -14, -2, -11,
- -20, -15, -24, -28, -28, -25, -28, -54, -73, -65, -43, -18, 6, 27, 21, 23,
- 17, 22, 18, 16, 31, 50, 45, 25, 22, 8, -20, -17, 8, 29, 10, -22,
- -41, -45, -51, -53, -31, -18, -23, -7, 37, 54, 38, 36, 60, 100, 119, 120,
- 122, 125, 110, 88, 94, 99, 90, 85, 82, 54, 26, -5, -49, -83, -85, -67,
- -36, -14, -30, -55, -76, -86, -65, -41, -45, -60, -53, -43, -35, -34, -41, -43,
- -45, -35, 10, 40, 32, 3, -3, -14, -30, -38, -33, -23, -29, -26, -18, -10,
- -17, -37, -46, -58, -61, -45, -17, -4, -2, 19, 31, 27, 13, 22, 38, 49,
- 59, 69, 60, 23, -13, -11, 13, 24, 19, 24, 8, -30, -58, -58, -66, -85,
- -90, -61, -19, -1, -11, -5, 25, 42, 61, 92, 109, 106, 110, 104, 93, 93,
- 89, 82, 86, 81, 71, 51, 13, -40, -74, -87, -73, -35, -24, -50, -71, -73,
- -53, -50, -58, -68, -60, -61, -54, -30, -25, -40, -52, -25, 13, 32, 45, 49,
- 44, 28, 22, 29, 32, 20, 3, 7, 6, 0, -1, -4, -30, -63, -69, -62,
- -57, -49, -25, 2, 17, 24, 27, 30, 10, 4, 38, 77, 66, 32, 13, 7,
- 0, 9, 31, 43, 23, -11, -25, -23, -46, -83, -87, -63, -42, -19, -6, -3,
- 6, 27, 49, 81, 108, 121, 123, 124, 115, 110, 98, 80, 78, 77, 77, 69,
- 54, 8, -56, -99, -92, -53, -46, -64, -75, -73, -70, -75, -62, -67, -86, -88,
- -54, -28, -33, -46, -50, -40, -24, -3, 29, 51, 48, 34, 44, 44, 30, 18,
- 13, -3, -15, -7, -1, -10, -36, -56, -65, -79, -100, -91, -64, -52, -40, -5,
- 20, 9, -14, -9, 21, 49, 59, 58, 49, 25, -1, 11, 39, 39, 22, 19,
- 20, 8, -19, -49, -72, -69, -58, -43, -27, -24, -13, -5, 12, 38, 74, 97,
- 110, 124, 126, 126, 114, 105, 100, 87, 91, 108, 115, 73, 5, -41, -49, -49,
- -53, -45, -49, -69, -77, -60, -51, -71, -94, -96, -68, -49, -46, -44, -45, -60,
- -60, -27, 0, 11, 26, 37, 37, 37, 40, 42, 34, 8, -1, 14, 15, -5,
- -12, -18, -44, -75, -85, -88, -98, -99, -76, -36, -12, -19, -24, -11, -9, 1,
- 36, 71, 58, 29, 13, 17, 33, 33, 30, 35, 44, 44, 27, -3, -39, -51,
- -61, -55, -41, -31, -25, -29, -21, -1, 23, 46, 76, 102, 109, 110, 116, 118,
- 92, 61, 76, 112, 120, 93, 57, 14, -28, -54, -50, -46, -60, -83, -82, -64,
- -62, -82, -89, -93, -101, -88, -59, -52, -64, -75, -76, -63, -50, -30, -1, 9,
- 8, 11, 32, 44, 36, 29, 32, 27, 20, 22, 28, 24, 0, -21, -30, -45,
- -78, -97, -83, -66, -50, -32, -17, -16, -23, -20, 4, 38, 51, 47, 37, 28,
- 29, 27, 27, 31, 42, 54, 55, 43, 20, -5, -29, -40, -37, -30, -27, -23,
- -15, -12, -11, 8, 43, 67, 78, 100, 122, 126, 107, 84, 81, 92, 106, 115,
- 110, 79, 31, -3, -13, -26, -47, -56, -56, -58, -58, -56, -59, -72, -86, -84,
- -66, -57, -56, -56, -60, -74, -74, -51, -32, -24, -14, 3, 14, 15, 19, 28,
- 33, 19, 11, 22, 29, 18, 8, 9, 0, 0, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -1,
- -1, -1, -1, -1, -1, -1, -1, 0, -1, -3, -2, -1, 0, 2, -4, -13,
- -21, -23, -19, -8, 7, 17, 23, 26, 33, 38, 32, 17, -5, -17, -24, -20,
- -6, -3, -16, -29, -26, -17, -5, -1, 2, 7, 11, 17, 15, 9, 9, 3,
- 10, 15, 9, -14, -33, -27, -18, -6, -7, -10, -6, 0, 12, 15, 29, 38,
- 36, 32, 11, 0, -30, -45, -50, -39, -23, -27, -24, -15, 6, 25, 37, 51,
- 46, 40, 0, -19, -22, -34, -30, -40, -45, -51, -34, -1, 25, 48, 40, 43,
- 51, 64, 58, 5, -22, -49, -63, -69, -68, -58, -54, -16, 13, 44, 66, 61,
- 68, 72, 86, 47, -17, -56, -82, -88, -93, -72, -58, -40, 4, 45, 94, 98,
- 84, 65, 68, 71, 15, -46, -88, -90, -88, -85, -62, -56, -34, -4, 41, 80,
- 82, 74, 54, 70, 66, 25, -29, -70, -74, -90, -87, -79, -73, -46, -10, 54,
- 90, 103, 88, 76, 90, 69, 25, -38, -76, -96, -119, -111, -103, -81, -57, -12,
- 50, 90, 113, 98, 100, 112, 103, 60, -11, -54, -95, -121, -124, -119, -95, -71,
- -10, 53, 103, 116, 93, 91, 89, 80, 31, -28, -67, -108, -122, -128, -110, -87,
- -53, 8, 60, 107, 107, 89, 83, 83, 76, 27, -14, -52, -84, -99, -103, -82,
- -72, -40, 4, 53, 92, 92, 88, 85, 97, 87, 42, 3, -45, -74, -106, -111,
- -105, -101, -70, -30, 27, 65, 77, 83, 87, 106, 90, 58, 16, -30, -67, -101,
- -100, -101, -93, -68, -27, 29, 60, 77, 79, 93, 111, 96, 71, 24, -21, -73,
- -109, -118, -127, -118, -98, -50, 6, 43, 65, 70, 99, 115, 108, 82, 40, -1,
- -53, -80, -94, -105, -101, -82, -31, 18, 56, 66, 72, 95, 103, 97, 64, 29,
- -15, -63, -85, -102, -105, -104, -81, -35, 13, 53, 58, 69, 86, 97, 94, 67,
- 39, -12, -54, -80, -97, -102, -103, -77, -38, 9, 40, 45, 60, 77, 95, 88,
- 70, 41, -8, -46, -74, -87, -99, -100, -78, -42, 10, 37, 50, 66, 89, 110,
- 103, 91, 57, 9, -33, -68, -86, -105, -105, -89, -51, -2, 23, 40, 53, 80,
- 99, 98, 89, 53, 8, -37, -68, -90, -107, -106, -94, -51, -5, 25, 43, 58,
- 86, 95, 98, 86, 52, 9, -36, -64, -92, -105, -108, -95, -53, -11, 22, 37,
- 57, 81, 90, 96, 82, 52, 6, -34, -64, -92, -104, -113, -97, -59, -18, 15,
- 31, 58, 79, 92, 98, 87, 57, 9, -29, -63, -87, -100, -109, -91, -58, -13,
- 16, 36, 62, 78, 93, 96, 88, 56, 12, -25, -62, -83, -101, -106, -89, -57,
- -15, 6, 30, 52, 71, 87, 94, 89, 55, 18, -21, -55, -76, -96, -100, -88,
- -53, -16, 6, 31, 53, 76, 93, 105, 98, 64, 26, -18, -52, -78, -99, -105,
- -95, -59, -26, 0, 24, 45, 66, 81, 97, 88, 62, 28, -12, -40, -67, -84,
- -95, -83, -50, -21, 4, 24, 47, 64, 81, 96, 85, 63, 26, -11, -41, -69,
- -88, -102, -91, -64, -36, -12, 10, 34, 51, 74, 87, 81, 62, 26, -7, -40,
- -63, -83, -95, -83, -58, -31, -10, 14, 34, 51, 75, 85, 82, 61, 30, -3,
- -34, -57, -81, -92, -83, -60, -36, -15, 11, 27, 47, 69, 80, 79, 59, 30,
- -5, -33, -57, -82, -93, -84, -61, -38, -15, 10, 25, 48, 68, 80, 77, 58,
- 29, -4, -30, -56, -80, -89, -78, -54, -34, -8, 10, 0, 0, 1, 0, -2,
- -2, -5, -8, -3, 3, -4, -10, 2, 8, 3, 4, 5, -3, -9, 10, 26,
- 26, 12, -4, -40, -64, -50, 1, 55, 69, 28, -23, -65, -83, -52, 13, 67,
- 67, 39, 16, -15, -48, -38, 10, 53, 44, 5, -5, -14, -43, -35, 16, 54,
- 37, -1, -26, -53, -82, -37, 35, 67, 44, 2, -10, -20, -39, -19, 27, 55,
- 42, 3, -26, -67, -107, -62, 43, 110, 102, 43, -18, -63, -91, -35, 73, 120,
- 77, -6, -72, -113, -109, -36, 53, 78, 50, 0, -46, -72, -71, -20, 67, 112,
- 100, 44, -24, -88, -123, -84, 5, 71, 97, 66, 7, -53, -100, -80, -1, 83,
- 127, 108, 38, -57, -121, -119, -57, 24, 84, 97, 62, -4, -77, -97, -46, 32,
- 101, 108, 56, -20, -103, -119, -69, 18, 105, 126, 90, 6, -92, -126, -90, -3,
- 85, 108, 75, 0, -86, -117, -85, -6, 76, 115, 101, 30, -68, -118, -105, -33,
- 57, 105, 102, 41, -46, -104, -112, -59, 25, 95, 121, 81, -5, -88, -126, -94,
- -12, 63, 101, 76, 7, -67, -107, -73, 11, 94, 127, 102, 21, -74, -124, -95,
- -21, 57, 101, 82, 21, -48, -89, -59, 6, 67, 95, 60, -11, -82, -115, -81,
- -13, 52, 84, 52, -9, -68, -96, -56, 9, 66, 93, 63, 10, -52, -86, -54,
- 1, 60, 96, 70, 19, -44, -80, -51, 0, 55, 94, 69, 20, -42, -88, -76,
- -40, 24, 79, 72, 34, -28, -75, -63, -23, 35, 71, 48, 4, -57, -95, -67,
- -10, 62, 103, 75, 18, -61, -110, -86, -22, 61, 110, 90, 37, -45, -100, -87,
- -39, 34, 81, 70, 33, -39, -88, -76, -24, 54, 94, 76, 32, -46, -100, -92,
- -42, 35, 73, 62, 26, -46, -97, -93, -44, 36, 81, 75, 35, -38, -87, -81,
- -26, 58, 99, 85, 37, -44, -101, -103, -46, 47, 98, 97, 56, -27, -90, -99,
- -49, 37, 88, 95, 62, -12, -74, -93, -51, 27, 69, 71, 35, -30, -78, -87,
- -38, 41, 84, 90, 57, -11, -71, -96, -56, 21, 69, 86, 60, -4, -67, -97,
- -61, 12, 65, 88, 65, 3, -61, -94, -60, 14, 71, 96, 68, 3, -66, -104,
- -70, 3, 59, 84, 59, -1, -67, -107, -76, -3, 59, 89, 64, 3, -67, -111,
- -82, -9, 57, 92, 76, 26, -43, -93, -71, -9, 50, 80, 64, 16, -51, -100,
- -79, -17, 49, 88, 77, 30, -41, -95, -79, -17, 49, 87, 77, 34, -36, -92,
- -78, -19, 44, 82, 73, 33, -37, -95, -84, -23, 47, 89, 83, 43, -30, -92,
- -83, -28, 39, 79, 74, 40, -28, -87, -82, -31, 34, 71, 67, 35, -31, -88,
- -85, -36, 28, 68, 69, 44, -20, -79, -83, -43, 19, 59, 64, 41, -25, -89,
- -100, -61, 9, 60, 76, 57, -10, -75, -90, -51, 22, 74, 88, 66, 1, -61,
- -78, -42, 25, 71, 84, 63, -1, -67, -90, -59, 8, 59, 81, 68, 8, -56,
- -85, -62, 1, 50, 74, 63, 7, -53, -84, -60, 5, 55, 80, 70, 17, -43,
- -76, -55, 4, 49, 73, 65, 17, -41, -77, -62, -9, 38, 68, 64, 17, -43,
- -84, -73, -22, 23, 56, 57, 18, -36, -77, -68, -23, 20, 51, 52, 16, -36,
- -77, -70, -26, 18, 54, 59, 28, -22, -64, -59, -20, 21, 56, 63, 36, -12,
- -55, -52, -16, 25, 58, 63, 35, -14, -59, -57, -22, 18, 51, 57, 31, -16,
- -58, -58, -27, 10, 43, 51, 30, -16, -59, -60, -28, 12, 48, 57, 35, -13,
- -59, -64, -35, 7, 47, 63, 47, 1, -46, -55, -32, 7, 47, 0, 0, -1,
- -1, -4, 1, -1, -3, -13, -8, -14, -3, -2, -2, 1, 8, 5, 7, -21,
- -13, -2, -6, -8, -22, -6, 5, 11, 34, 41, 33, 13, 28, 33, 48, 35,
- 21, -3, -26, -18, -10, 3, 7, 22, 21, 63, 40, 41, 43, 4, -8, -43,
- -63, -77, -77, -59, -18, 3, 2, -21, -46, -74, -90, -108, -101, -94, -89, -84,
- -85, -77, -59, -50, -33, -7, 18, 37, 47, 64, 101, 127, 125, 127, 126, 126,
- 126, 122, 100, 87, 62, 37, 28, 27, 25, 27, 34, 25, -4, -45, -85, -123,
- -128, -126, -128, -127, -123, -92, -73, -55, -45, -37, -33, -32, -33, -43, -53, -55,
- -43, -20, 3, 20, 34, 42, 49, 55, 63, 74, 84, 93, 101, 107, 112, 117,
- 109, 92, 63, 33, 8, -13, -25, -29, -30, -27, -27, -32, -46, -63, -82, -98,
- -109, -116, -121, -118, -104, -80, -49, -12, 21, 45, 58, 64, 66, 66, 61, 51,
- 44, 37, 32, 32, 33, 33, 28, 23, 15, 8, 3, 2, 9, 16, 20, 24,
- 23, 14, -1, -20, -37, -48, -53, -52, -47, -38, -26, -13, -5, -1, -4, -10,
- -22, -34, -43, -48, -46, -34, -16, 5, 25, 45, 65, 78, 84, 83, 71, 55,
- 39, 24, 9, -3, -12, -23, -34, -45, -57, -65, -71, -71, -63, -49, -34, -21,
- -11, -2, 2, 8, 11, 12, 14, 14, 20, 28, 38, 50, 58, 63, 61, 56,
- 46, 33, 17, -1, -19, -34, -45, -48, -44, -32, -19, -5, 5, 7, 4, -2,
- -7, -11, -15, -18, -21, -23, -26, -28, -30, -31, -29, -26, -20, -12, -1, 11,
- 21, 32, 42, 51, 55, 55, 52, 46, 41, 37, 32, 30, 28, 27, 24, 19,
- 12, -1, -21, -45, -67, -89, -103, -107, -101, -90, -70, -51, -33, -18, -2, 11,
- 23, 33, 39, 44, 49, 52, 57, 59, 59, 56, 52, 48, 41, 35, 28, 20,
- 15, 11, 4, 0, -5, -11, -18, -25, -34, -42, -47, -48, -46, -40, -33, -27,
- -24, -21, -24, -32, -42, -51, -56, -58, -56, -47, -35, -18, 2, 24, 48, 70,
- 88, 99, 104, 102, 97, 89, 79, 69, 59, 49, 37, 27, 14, 0, -14, -29,
- -44, -58, -71, -81, -87, -88, -88, -85, -81, -77, -72, -63, -51, -37, -21, -5,
- 12, 29, 43, 53, 59, 61, 57, 48, 36, 24, 13, 8, 8, 15, 25, 38,
- 48, 54, 54, 50, 43, 33, 22, 11, 3, -6, -15, -25, -35, -46, -54, -61,
- -65, -68, -69, -69, -68, -64, -59, -52, -43, -32, -20, -7, 6, 19, 31, 42,
- 51, 58, 62, 64, 62, 58, 52, 44, 35, 26, 17, 9, 1, -5, -10, -15,
- -18, -19, -20, -19, -18, -16, -15, -14, -14, -15, -16, -17, -18, -19, -19, -19,
- -19, -18, -16, -14, -11, -9, -6, -3, 0, 3, 6, 10, 14, 18, 22, 27,
- 32, 35, 37, 37, 35, 30, 23, 14, 4, -6, -15, -24, -31, -36, -39, -40,
- -39, -37, -32, -26, -19, -10, -1, 8, 17, 24, 29, 32, 33, 32, 29, 25,
- 20, 15, 11, 7, 3, -1, -5, -9, -14, -19, -24, -28, -31, -32, -31, -27,
- -23, -16, -10, -3, 2, 7, 10, 12, 13, 13, 13, 12, 10, 8, 7, 5,
- 5, 5, 5, 6, 8, 10, 13, 17, 20, 23, 25, 26, 25, 21, 16, 9,
- 1, -7, -16, -24, -31, -37, -42, -47, -49, -51, -52, -51, -48, -43, -37, -30,
- -20, -7, 6, 19, -1, -4, -4, 0, -1, -4, -3, 4, 4, -2, -3, 2,
- 1, -4, 0, 5, 0, -4, 2, -10, -26, -29, -34, -49, -61, -44, -21, -8,
- -3, -3, 1, 20, 32, 38, 32, 12, -4, 1, 14, 28, 51, 68, 78, 80,
- 72, 38, 1, -6, 16, 23, 2, -14, -15, -20, -33, -62, -65, -37, -18, -27,
- -29, -26, -45, -38, 8, 52, 55, 31, 26, 16, 17, 45, 80, 87, 77, 62,
- 54, 24, -23, -50, -43, -28, -47, -72, -86, -86, -87, -61, -35, -38, -57, -69,
- -55, -27, 1, 4, 22, 45, 54, 31, 0, -7, -5, -3, 0, -9, -21, -20,
- -15, -27, -31, -10, 5, 9, 3, -21, -67, -83, -46, -3, 8, 18, 22, 4,
- -3, 5, 35, 52, 67, 72, 83, 89, 71, 37, 19, 25, 8, -11, -37, -58,
- -80, -85, -68, -33, -24, -57, -60, -34, -16, -14, 17, 73, 96, 77, 48, 17,
- -7, -9, 4, -1, -3, 6, 3, -12, -10, 19, 33, 33, 41, 35, -29, -70,
- -64, -38, -18, 3, 17, -5, -26, -35, -5, 31, 63, 73, 86, 94, 80, 64,
- 50, 46, 37, 28, -2, -32, -65, -91, -84, -63, -59, -82, -97, -80, -66, -65,
- -43, 8, 49, 60, 61, 42, 27, 23, 23, 14, 15, 18, 10, -12, -17, -9,
- -13, 8, 35, 42, 2, -41, -76, -87, -67, -46, -31, -32, -45, -72, -53, -5,
- 32, 46, 72, 92, 96, 92, 77, 75, 73, 61, 44, 12, -32, -68, -72, -54,
- -58, -75, -85, -67, -57, -61, -60, -46, -11, 24, 35, 22, 15, 6, -1, -13,
- 8, 23, 8, -1, -1, -6, -8, 35, 71, 86, 79, 50, -11, -46, -38, -31,
- -29, -21, -30, -64, -68, -43, -12, 10, 28, 62, 89, 88, 84, 85, 90, 89,
- 95, 83, 28, -32, -53, -36, -44, -62, -64, -55, -59, -54, -52, -48, -23, 19,
- 48, 37, 39, 42, 31, 12, 19, 20, 5, 4, 1, -23, -40, -14, 14, 42,
- 68, 64, 14, -33, -53, -52, -32, -18, -24, -43, -67, -62, -36, -18, -1, 25,
- 54, 57, 58, 56, 54, 50, 66, 80, 44, -21, -50, -40, -52, -69, -77, -60,
- -56, -54, -53, -62, -49, -9, 28, 41, 58, 58, 47, 43, 49, 41, 34, 37,
- 18, -19, -44, -47, -36, 1, 35, 38, 19, -20, -62, -71, -59, -36, -34, -47,
- -63, -63, -50, -38, -17, 7, 37, 56, 74, 80, 73, 61, 87, 116, 99, 47,
- -7, -26, -22, -20, -32, -57, -72, -76, -76, -71, -47, -9, 13, 24, 29, 29,
- 25, 27, 52, 68, 62, 9, -38, -67, -66, -39, -11, -4, -24, -37, -47, -51,
- -49, -44, -55, -39, -6, -17, -52, -54, -19, 1, 15, 24, 31, 41, 55, 71,
- 79, 89, 111, 115, 88, 54, 22, -2, -8, -5, -7, -27, -49, -57, -69, -72,
- -64, -30, -3, 17, 31, 37, 29, 14, 39, 67, 73, 47, 10, -40, -72, -58,
- -23, -12, -19, -19, -39, -49, -42, -46, -62, -44, -8, -11, -36, -51, -39, -15,
- 0, 13, 21, 25, 40, 55, 63, 73, 95, 115, 115, 85, 53, 20, 2, -1,
- -2, -10, -32, -48, -64, -73, -77, -62, -33, -9, 16, 33, 31, 18, 17, 44,
- 67, 70, 49, 6, -45, -69, -53, -24, -13, -19, -24, -40, -47, -45, -50, -62,
- -43, -10, -13, -37, -51, -39, -15, 0, -3, -1, 1, -1, -6, -6, -4, -1,
- -2, -6, -8, -7, -4, -5, -10, -14, -16, -16, -16, -17, -18, -18, -17, -15,
- -15, -16, -15, -13, -10, -9, -9, -11, -13, -14, -11, -9, -8, -9, -7, -3,
- -2, -5, -8, -6, 1, 5, 4, 1, 0, 1, 4, 4, 4, 5, 7, 9,
- 9, 8, 8, 9, 10, 9, 5, 2, 3, 5, 7, 7, 9, 11, 11, 12,
- 14, 14, 12, 8, 7, 8, 5, 1, 3, 8, 9, 9, 10, 14, 16, 15,
- 14, 12, 11, 9, 7, 3, -2, -3, 3, 5, 0, -5, -1, -1, -6, -10,
- -16, -23, -28, -29, -32, -39, -36, -23, -16, -19, -19, -10, -7, -12, -11, -5,
- -6, -11, -13, -11, -9, -8, -2, 6, 8, 8, 9, 6, 2, 4, 8, 9,
- 4, 4, 12, 18, 17, 14, 17, 20, 20, 16, 9, 7, 7, 5, 3, 4,
- 1, -2, 0, 3, 2, -1, 1, 3, 3, 1, 2, 2, 0, 3, 6, 9,
- 8, 0, -5, -3, 7, 12, 8, -2, -2, 9, 10, 2, -3, 2, 5, 1,
- -3, -5, -6, -2, -3, -11, -20, -26, -28, -30, -32, -37, -43, -45, -43, -40,
- -42, -41, -31, -22, -20, -18, -16, -16, -19, -15, -8, -3, -3, 3, 17, 26,
- 22, 16, 18, 23, 27, 26, 23, 17, 15, 21, 25, 24, 25, 31, 36, 32,
- 29, 23, 17, 15, 11, 5, 1, 4, 6, 8, 6, 7, 8, 10, 14, 18,
- 22, 20, 17, 14, 15, 13, 10, 15, 15, 12, 9, 10, 15, 14, 9, 3,
- 6, 10, 5, -3, -9, -16, -16, -10, -11, -20, -24, -18, -20, -32, -42, -48,
- -55, -70, -84, -95, -100, -92, -75, -65, -68, -67, -56, -55, -51, -41, -33, -37,
- -42, -38, -33, -31, -26, -6, 19, 30, 25, 25, 28, 30, 27, 19, 16, 18,
- 31, 44, 46, 48, 56, 71, 77, 74, 66, 54, 47, 37, 19, 3, 2, 3,
- 3, 4, 13, 20, 21, 25, 24, 25, 19, 18, 19, 19, 14, 6, 17, 14,
- 1, 3, 12, 27, 29, 25, 13, 14, 24, 22, 6, -7, -7, 0, 11, 12,
- 1, 0, 10, 8, -13, -32, -46, -52, -57, -70, -88, -106, -101, -81, -74, -82,
- -75, -49, -37, -42, -44, -42, -46, -51, -47, -40, -32, -27, -6, 3, 16, 32,
- 29, 25, 24, 30, 54, 69, 74, 78, 90, 108, 118, 124, 117, 107, 102, 93,
- 76, 61, 50, 41, 35, 31, 26, 13, 4, 0, -1, 0, -6, -12, -10, -8,
- -4, 0, -3, -20, -31, -27, -18, -16, -22, -29, -28, -9, 0, -3, -1, 2,
- 11, 20, 24, 18, 22, 34, 32, 16, -1, -18, -34, -46, -55, -67, -91, -102,
- -91, -72, -73, -81, -68, -55, -55, -65, -74, -79, -87, -87, -83, -81, -77, -60,
- -25, 4, 4, -3, 0, 13, 29, 29, 24, 23, 29, 51, 67, 72, 77, 88,
- 105, 114, 122, 116, 106, 100, 93, 77, 63, 51, 42, 36, 31, 27, 15, 5,
- 0, -1, 0, -4, -10, -9, -7, -3, 2, -1, -16, -28, -26, -16, -13, -18,
- -25, -25, -8, 2, 1, 2, 5, 13, 21, 26, 20, 23, 35, 35, 20, 3,
- -14, -32, -45, -54, -67, -91, -102, -90, -72, -75, -82, -68, -56, -56, -66, -75,
- -81, -88, -88, -83, -82, -77, -59, -22, 4, 1, -1, -2, -3, -3, -1, -1,
- -6, -8, -9, -12, -5, 6, 15, 21, 22, 21, 9, -8, -16, -23, -32, -22,
- 4, 27, 32, 17, -2, -21, -34, -37, -30, -24, -3, 24, 47, 58, 50, 23,
- -12, -41, -52, -47, -33, -2, 28, 48, 45, 28, 0, -36, -58, -53, -34, -4,
- 26, 52, 75, 73, 45, -5, -66, -101, -90, -61, -14, 23, 59, 87, 89, 63,
- 10, -46, -79, -80, -55, -23, -3, 27, 58, 62, 41, -6, -66, -92, -77, -29,
- 19, 41, 65, 74, 69, 42, -9, -73, -109, -107, -67, -17, 23, 70, 104, 111,
- 83, 21, -56, -104, -109, -62, -21, 4, 34, 68, 89, 75, 19, -46, -89, -85,
- -38, -1, 23, 45, 64, 74, 62, 8, -53, -98, -93, -47, -9, 16, 36, 62,
- 86, 78, 13, -67, -121, -109, -56, -9, 25, 58, 89, 109, 81, 8, -70, -119,
- -106, -56, -7, 32, 63, 90, 108, 74, -3, -89, -128, -118, -70, -22, 23, 62,
- 101, 126, 98, 26, -64, -117, -110, -72, -32, 6, 44, 93, 124, 100, 28, -63,
- -116, -110, -71, -26, 16, 54, 101, 121, 92, 13, -86, -128, -120, -79, -28, 15,
- 60, 111, 127, 95, 11, -83, -127, -116, -80, -29, 15, 67, 117, 127, 100, 17,
- -75, -118, -108, -75, -31, 7, 60, 109, 123, 87, 3, -83, -118, -106, -67, -23,
- 13, 62, 106, 119, 85, 3, -77, -106, -95, -61, -27, 2, 52, 103, 124, 97,
- 19, -61, -95, -92, -63, -34, -4, 45, 94, 116, 87, 8, -63, -91, -85, -58,
- -36, -9, 36, 81, 104, 76, 2, -60, -87, -77, -52, -32, -2, 48, 97, 119,
- 86, 7, -59, -90, -85, -65, -50, -22, 26, 78, 107, 79, 11, -49, -78, -73,
- -58, -46, -18, 31, 85, 112, 75, 1, -59, -84, -73, -55, -40, -12, 30, 80,
- 106, 74, 10, -46, -70, -62, -49, -39, -13, 31, 86, 110, 74, 8, -49, -70,
- -59, -46, -33, -6, 38, 92, 111, 76, 13, -42, -62, -56, -51, -44, -23, 19,
- 75, 97, 67, 8, -44, -63, -58, -56, -48, -26, 19, 75, 94, 64, 8, -40,
- -55, -50, -49, -42, -25, 18, 69, 85, 57, 4, -41, -54, -51, -50, -45, -28,
- 18, 71, 88, 60, 8, -35, -46, -47, -48, -46, -30, 16, 66, 84, 59, 9,
- -30, -41, -43, -42, -40, -22, 25, 73, 88, 60, 8, -30, -42, -46, -45, -42,
- -21, 28, 74, 83, 52, -1, -36, -46, -45, -40, -37, -17, 26, 66, 73, 41,
- -10, -42, -54, -53, -48, -43, -19, 27, 68, 76, 44, -4, -34, -44, -41, -37,
- -33, -10, 34, 71, 75, 40, -7, -36, -47, -43, -39, -35, -9, 35, 72, 75,
- 39, -7, -38, -49, -45, -43, -38, -11, 33, 68, 70, 36, -4, -31, -39, -36,
- -35, -31, -5, 36, 69, 69, 35, -4, -31, -38, -35, -37, -33, -8, 31, 64,
- 63, 31, -7, -34, -42, -40, -43, -38, -12, 28, 61, 59, 27, -10, -34, -40,
- -38, -41, -35, -9, 31, 63, 60, 29, -6, -31, -37, -38, -42, -35, -10, 29,
- 60, 56, 27, -8, -30, -33, -34, -38, -32, -10, 28, 56, 51, 23, -9, -29,
- -32, -34, -38, -33, -10, 29, 55, 50, 23, -9, -28, -30, -33, -37, -32, -8,
- 32, 56, 52, 23, 23, 0, -2, 0, -2, -6, -6, -6, -5, -2, -1, 5,
- 15, 20, 11, 12, 12, 6, 0, -8, -19, -12, -4, -19, -19, -4, 4, -7,
- -3, 5, 8, 11, 14, 9, 9, 8, -4, -11, -6, -8, -16, -14, -7, -1,
- -3, 1, 10, 13, 24, 28, 12, 10, 14, 11, -14, -29, -19, -12, -21, -25,
- -16, 2, 0, -11, -7, 7, 10, 0, 0, 5, 11, 6, 10, 21, 13, 7,
- 14, 4, -4, -9, -5, -11, -16, -7, -3, 3, 15, -2, 2, 17, 6, -19,
- -16, 3, 3, -14, -10, 7, 7, 4, 8, 11, 4, -5, -12, -9, -6, -14,
- -13, -17, -13, -8, 5, 9, 3, 10, 12, 24, 28, 26, 35, 20, -3, 24,
- 23, -19, -31, -23, -23, -38, -34, -18, -10, -8, -6, -4, -1, 5, -4, -8,
- 2, 15, 12, 26, 56, 37, 10, 25, 25, -4, -21, -24, -23, -26, -30, -27,
- -8, 10, -5, 3, 30, 6, -26, -7, 13, -2, -19, -2, 11, 3, 14, 21,
- 8, 12, 5, -19, -26, -12, 9, 1, -8, -8, 20, 27, 17, 16, 15, 0,
- 23, 39, 11, -4, -13, -21, -21, -32, -36, -27, -20, -24, -10, -4, 5, 14,
- 4, -11, -10, 7, -8, -7, 7, 7, 2, 15, 29, 55, 26, 4, 22, 37,
- 32, 14, 10, 18, 7, -1, -28, -49, -24, -14, -41, -53, -37, -28, -27, -15,
- 1, 2, 14, 14, 13, 3, 0, 1, 18, 9, 7, 11, 23, 23, 25, 16,
- -7, 1, 13, 26, 26, 9, 13, 28, 28, 1, -29, -29, -26, -27, -43, -43,
- -31, -12, -26, -15, 6, 16, 6, 22, 11, -4, 0, 3, 0, -4, -20, -9,
- 15, 23, 19, 7, 25, 19, 42, 63, 40, 13, 22, 24, 1, -41, -60, -55,
- -63, -69, -61, -31, -7, 10, 8, 0, 7, 4, 4, 20, 5, -4, 9, 27,
- 31, 27, 23, 13, 19, 12, 2, 4, 15, 20, 35, 19, 16, 26, 3, -30,
- -48, -31, -40, -60, -59, -47, -13, -3, 12, 22, 11, 7, 9, 8, 3, -10,
- -34, -5, 6, 24, 38, 19, 13, 21, 40, 15, 2, 27, 26, 16, 44, 47,
- -7, -43, -41, -29, -44, -80, -81, -58, -26, -17, 3, 16, 30, 19, 10, 25,
- 16, 6, -12, -3, 13, 30, 38, 20, 17, 22, 25, 18, 13, 16, -3, 1,
- 32, 44, -11, -48, -51, -34, -38, -49, -64, -70, -23, -10, -14, -1, 20, 18,
- 20, 21, 11, 3, -8, -3, 13, 14, 22, 18, 32, 37, 30, 25, 16, 27,
- 27, 18, 37, 52, 12, -26, -56, -57, -46, -71, -92, -86, -50, -21, -10, 8,
- 15, 15, 18, 28, 17, 1, 1, 2, 13, 13, 23, 23, 21, 29, 31, 29,
- 15, 20, 33, 32, 29, 46, 21, -31, -49, -53, -51, -66, -82, -76, -54, -32,
- -10, 12, 19, 29, 18, 3, 0, 16, 20, 29, 31, 20, 25, 31, 43, 41,
- 34, 44, 27, 29, 65, 54, -15, -70, -79, -63, -86, -114, -114, -79, -26, -2,
- 6, 18, 19, 10, 19, 26, 15, 5, 0, 16, 23, 29, 30, 21, 25, 28,
- 37, 37, 38, 44, 32, 29, 66, 65, -7, -67, -74, -59, -82, -114, -117, -85,
- -31, -2, 11, 20, 18, 9, 20, 30, 15, 5, 0, 0, 1, 1, 2, 3,
- 3, 3, 4, 4, 5, 6, 6, 7, 8, 8, 7, 7, 7, 7, 7, 6,
- 4, 3, 2, 0, -1, -2, -3, -5, -6, -8, -9, -9, -11, -12, -14, -15,
- -17, -17, -17, -18, -19, -19, -19, -18, -17, -16, -15, -13, -11, -8, -7, -6,
- -5, -3, -1, 0, 0, 1, 3, 5, 8, 10, 12, 14, 17, 19, 21, 23,
- 26, 27, 28, 28, 28, 26, 25, 24, 23, 23, 21, 19, 18, 16, 15, 14,
- 13, 12, 11, 11, 11, 10, 8, 6, 5, 5, 4, 2, 0, -2, -4, -5,
- -7, -10, -11, -12, -13, -14, -15, -15, -15, -15, -15, -16, -17, -18, -18, -19,
- -21, -23, -25, -27, -28, -29, -29, -30, -30, -29, -27, -25, -23, -22, -20, -18,
- -16, -14, -13, -12, -11, -11, -10, -9, -8, -6, -5, -4, -3, -1, 1, 3,
- 4, 6, 7, 8, 8, 9, 10, 11, 12, 13, 13, 13, 13, 15, 18, 21,
- 23, 24, 25, 25, 28, 31, 33, 34, 34, 32, 31, 31, 31, 30, 27, 22,
- 16, 12, 10, 9, 7, 3, -5, -13, -19, -22, -22, -23, -25, -28, -31, -33,
- -33, -32, -32, -31, -32, -33, -32, -29, -25, -21, -19, -19, -19, -19, -18, -15,
- -9, -3, 2, 6, 9, 12, 16, 21, 27, 32, 37, 39, 40, 40, 39, 39,
- 40, 41, 40, 38, 35, 34, 34, 33, 29, 22, 16, 11, 10, 11, 12, 12,
- 10, 8, 7, 5, 3, 2, 0, -6, -12, -19, -23, -23, -22, -23, -26, -30,
- -33, -33, -33, -34, -35, -37, -40, -45, -50, -53, -52, -48, -42, -37, -32, -27,
- -22, -20, -18, -16, -16, -18, -21, -26, -30, -33, -34, -35, -36, -38, -40, -41,
- -41, -38, -36, -36, -38, -41, -40, -38, -34, -30, -27, -25, -22, -20, -16, -15,
- -16, -17, -18, -16, -13, -10, -7, -4, -2, 1, 6, 11, 16, 21, 24, 25,
- 26, 24, 22, 19, 18, 19, 22, 24, 26, 30, 33, 38, 44, 50, 56, 61,
- 63, 68, 72, 74, 73, 68, 64, 57, 50, 47, 46, 44, 37, 21, 3, -11,
- -20, -23, -25, -30, -33, -36, -36, -34, -31, -27, -22, -21, -22, -21, -18, -21,
- -24, -27, -31, -33, -32, -27, -21, -14, -13, -17, -17, -10, 0, 10, 15, 16,
- 14, 8, 6, 10, 16, 25, 34, 39, 43, 47, 53, 62, 72, 82, 89, 92,
- 90, 84, 79, 77, 77, 76, 67, 54, 42, 33, 26, 18, 5, -11, -27, -41,
- -53, -65, -73, -77, -79, -81, -86, -93, -102, -110, -116, -118, -120, -124, -127, -128,
- -128, -126, -122, -116, -107, -96, -85, -78, -72, -64, -54, -45, -39, -40, -46, -49,
- -49, -47, -45, -44, -45, -45, -44, -42, -38, -33, -29, -26, -23, -20, -18, -14,
- -11, -8, -5, -2, 2, 7, 11, 10, 8, 7, 9, 16, 22, 26, 28, 31,
- 34, 39, 44, 49, 53, 57, 60, 62, 63, 63, 65, 66, 63, 57, 51, 46,
- 46, 50, 53, 54, 55, 54, 55, 57, 63, 69, 73, 75, 73, 69, 66, 64,
- 65, 63, 55, 43, 30, 18, 11, 3, -6, -15, -23, -29, -32, -32, -28, -22,
- -16, -13, -16, -16, -11, -2, 9, 15, 1, 0, 0, 0, -1, 0, -3, 0,
- -1, 0, -18, 21, -22, 23, -41, 20, 84, -39, 50, -61, 26, -126, -19, -37,
- 15, 2, 70, -33, 127, -55, 117, -73, 15, -45, -50, 8, -11, 23, 33, 1,
- 26, -67, 26, -25, 14, -45, 57, -124, 12, -4, -23, 107, -54, 127, -49, 43,
- 27, -59, -30, 15, -128, 5, -128, 86, -39, 82, 12, 62, 9, 51, -59, 53,
- -95, 67, -92, 68, -28, 94, 21, 47, -11, -1, -41, 0, -25, -9, 18, -68,
- 15, -27, 49, -27, 103, -4, 3, -36, 58, -98, 56, -116, -31, -123, 25, -58,
- 89, -21, 110, -25, 73, -28, 39, -21, 35, -40, 37, -20, 50, 55, 51, 6,
- 1, -47, -11, -32, -23, 38, -67, 3, -54, 34, -55, 79, 1, 32, -61, 89,
- -86, 53, -67, -10, -128, -6, -68, 51, -4, 82, 15, 83, -16, 63, -24, 55,
- -29, 8, 0, 6, 11, 54, 14, 16, -39, -9, -12, -47, 37, -40, -22, -60,
- 21, -76, 51, -17, 74, -63, 98, -36, 44, -33, 24, -113, -37, -89, 20, -30,
- 67, 18, 87, 0, 67, -6, 38, 1, -2, -18, -5, -20, 32, 17, 21, -8,
- -30, 15, -47, 11, -17, 11, -97, 43, -87, 27, -36, 91, -41, 66, 3, 44,
- -28, 55, -74, -37, -92, -21, -37, 33, -1, 75, 22, 36, 14, 26, 8, 8,
- -12, -7, -21, -1, 27, 11, 21, -30, 21, -37, -3, -13, 23, -27, -32, -10,
- -23, -44, 56, -1, 43, -12, 76, -29, 48, -9, -25, -71, -70, -48, -20, 2,
- 9, 56, 8, 56, -10, 52, -12, 31, -29, 27, -60, 62, -42, 83, -45, 30,
- -24, 4, -26, 33, -23, 5, -18, -25, -53, -7, -6, -6, 19, 16, 31, 3,
- 58, -14, 0, -64, -33, -58, -8, -43, 42, -18, 57, -9, 54, 1, 47, -3,
- 36, -18, 3, 4, 6, 2, -17, 8, -14, -27, 35, 2, -3, 1, -8, -43,
- -34, -1, -22, 12, 2, 37, -6, 53, 14, 16, -43, -22, -75, -2, -67, 23,
- -24, 39, -3, 39, 6, 44, 9, 37, 5, 1, 3, 5, 12, -18, 0, 0,
- -31, 5, 23, 1, -3, 10, -20, -48, -6, -30, 7, -18, 35, -4, 32, 21,
- 39, -26, -1, -75, -9, -65, -3, -28, 20, -5, 32, 5, 36, 20, 30, 30,
- 3, 10, -1, 16, -10, -7, -1, -17, -23, 18, 14, -3, 8, 9, -45, -14,
- -35, -1, -27, 18, -2, 29, 1, 61, -14, 20, -56, -19, -51, -22, -38, 9,
- -14, 22, 5, 24, 27, 23, 41, 13, 20, -7, 23, -2, -8, -2, -9, -26,
- -6, 14, 11, -11, 37, -33, -12, -38, -6, -33, 7, -14, 30, -12, 55, 4,
- 33, -32, -14, -45, -22, -43, -7, -15, 18, 18, 33, 17, 41, 22, 15, 14,
- 8, -24, -16, -18, -16, -7, 6, 16, -2, 8, -14, -6, -23, 0, -22, 1,
- -23, 21, 4, 24, -1, 9, -9, -11, -14, -13, -16, -14, -15, -12, -16, -5,
- 8, 28, 25, 28, 34, 27, 15, 16, 2, -20, -22, -20, -15, -8, 10, 11,
- 7, -3, -5, -16, -10, -13, -5, -16, -5, 4, 17, 13, 6, 1, -9, -1,
- -2, -3, -4, -4, -5, -5, -5, -5, -5, -5, -5, -5, -5, -5, -5, -6,
- -6, -6, -6, -6, -5, -3, -3, -5, -5, -5, -7, -8, -5, 4, 5, 13,
- 12, -12, -5, 10, 5, 4, 0, 3, 26, 33, 10, -15, -69, -89, -25, 25,
- 58, 70, 22, -41, -62, -31, 18, 17, -17, -12, -9, 20, 99, 96, 0, -88,
- -123, -69, 61, 116, 54, -11, -45, -28, 40, 38, -42, -59, -53, -31, 63, 78,
- -9, -65, -83, -59, 48, 110, 50, -11, -51, -54, 41, 96, 9, -87, -119, -77,
- 42, 118, 67, -18, -57, -46, 24, 89, 81, 22, -43, -77, -65, -41, -23, -3,
- 4, 8, -13, -54, -52, -21, 30, 89, 86, 8, -49, -76, -56, 30, 55, 52,
- 47, -7, -45, -49, -48, -10, 68, 74, 43, 22, -27, -25, 12, 20, -5, -43,
- -69, -46, 21, 53, 51, 38, -8, -32, 6, 20, -1, -19, -56, -67, -26, 27,
- 76, 95, 23, -64, -60, -15, 33, 39, -8, -37, -24, -7, 7, 4, -25, -23,
- -10, -14, -7, -5, -12, 2, 28, 31, 37, 21, -18, -16, -4, -22, -37, -46,
- -56, -8, 58, 64, 53, 31, -9, -9, -2, -57, -85, -52, -13, 59, 92, 21,
- -42, -47, -33, 27, 75, 27, -22, -38, -44, 18, 77, 32, -21, -46, -50, 34,
- 89, 22, -37, -60, -56, 31, 95, 36, -27, -57, -82, -15, 53, 15, -13, -25,
- -44, 14, 66, 14, -32, -53, -62, 25, 96, 50, 3, -32, -56, 25, 98, 51,
- -9, -56, -78, 7, 92, 71, 28, -31, -92, -42, 28, 20, 24, 8, -34, 22,
- 70, 18, -17, -53, -88, -20, 39, 7, -2, -8, -28, 35, 80, 19, -23, -55,
- -93, -22, 63, 54, 47, 19, -52, -35, 2, -36, -32, -18, -49, -9, 41, 15,
- 26, 34, -22, -6, 31, 1, 8, 9, -43, -15, 30, -3, -1, -7, -73, -48,
- 6, -14, 5, 13, -47, -30, 12, -13, 6, 18, -37, -13, 39, 27, 45, 38,
- -37, -32, 12, 3, 32, 46, -10, 6, 48, 16, 15, 15, -32, -2, 47, 24,
- 26, 18, -51, -51, -15, -29, -1, 19, -28, -15, 21, 2, 18, 22, -34, -24,
- 13, -3, 15, 14, -45, -34, 7, 10, 38, 31, -34, -30, 4, 5, 43, 61,
- 13, 4, 6, -22, 4, 24, -13, -13, -10, -34, 0, 23, -16, -16, -13, -42,
- -18, -4, -36, -17, 5, -10, 14, 22, -21, -22, -16, -37, -6, 20, -2, 17,
- 36, 19, 43, 43, -9, -15, -12, -29, 6, 31, 6, 10, 7, -23, -2, 9,
- -23, -15, -10, -26, 3, 20, -5, 1, 0, -22, 5, 22, -6, -8, -16, -37,
- -5, 20, 2, 11, 6, -19, 11, 33, 12, 20, 16, -7, 20, 35, 11, 11,
- -3, -28, 2, 19, -1, 3, -6, -29, -5, 2, -25, -17, -12, -16, 22, 34,
- 3, -4, -21, -36, 4, 26, 8, -1, -30, -54, -23, -3, -11, 0, -12, -27,
- 7, 24, 13, 19, -1, -21, 10, 27, 14, 17, 0, -14, 18, 33, 19, 14,
- -17, -41, -10, 9, 2, 7, -14, -30, 4, 20, 9, 9, -15, -35, -3, 16,
- 9, 0, -1, -2, -3, 4, 7, 4, -2, -3, 0, 3, -1, -1, 4, 5,
- -2, -13, -9, 1, 4, 2, 1, 2, 2, -2, -8, -4, 0, 4, 4, -3,
- -4, -3, 1, 2, -1, 3, 14, 1, -7, -12, -4, -2, 1, 1, 9, 5,
- -6, -5, -2, -1, -1, 1, 14, 6, -6, -7, 3, 8, -2, -4, 13, 12,
- -10, -17, -10, -5, -4, 2, 3, 7, -6, -6, -1, -1, -4, 1, 11, 6,
- -6, -9, 10, 11, 3, 1, 14, 15, -12, -20, -12, -9, -15, -1, 7, 2,
- -16, -7, 6, 0, -2, 10, 26, 17, -6, -11, 24, 21, 1, 0, 18, 15,
- -17, -31, -28, -23, -14, 0, -4, 0, -16, -8, 8, -4, -3, 7, 15, 5,
- -3, -3, 26, 25, 12, 8, 28, 17, -15, -28, -18, -17, -18, -7, -3, -7,
- -20, 0, 7, 1, -9, 6, 9, -4, -9, 2, 15, 24, 34, 31, 10, -4,
- -15, -29, -17, -21, -41, -40, -5, 19, -20, 3, 11, 33, 28, 21, 18, 15,
- 16, 3, -1, 18, 17, 15, 1, -15, -10, -5, -14, -42, -48, -43, -26, 4,
- -29, -14, -9, 32, 20, 12, 15, 21, 39, 24, 8, 26, 33, 6, -3, 0,
- 1, -7, -16, -41, -44, -51, -34, -3, -6, -6, -19, 26, 10, 15, 35, 46,
- 32, 20, 16, 23, 38, 15, -4, -10, 17, -6, -41, -48, -53, -70, -52, -9,
- -9, -22, -15, 19, 24, 22, 30, 49, 34, 10, 1, 15, 33, 15, 1, 17,
- 46, 12, -38, -59, -50, -57, -46, -13, -16, -30, -24, 26, 37, 33, 30, 45,
- 40, 2, -11, 17, 41, 24, -4, 16, 48, 15, -38, -67, -64, -65, -46, -18,
- -18, -35, -32, 35, 39, 37, 21, 45, 42, -2, -19, 14, 37, 22, 7, 24,
- 40, 13, -42, -68, -63, -63, -38, -6, -12, -34, -25, 39, 43, 39, 17, 47,
- 45, 3, -19, 21, 45, 25, 2, 21, 31, 0, -45, -71, -78, -83, -48, 2,
- 7, -27, -32, 34, 45, 49, 23, 44, 36, 5, -5, 38, 60, 27, -13, 21,
- 42, -13, -69, -81, -86, -79, -38, -9, -11, -41, -36, 38, 56, 45, 10, 43,
- 43, 10, -6, 36, 57, 41, 10, 36, 46, -16, -67, -66, -71, -80, -44, -8,
- -5, -29, -27, 30, 43, 46, 20, 52, 39, -9, -21, 40, 68, 42, -1, 20,
- 32, -14, -70, -86, -94, -90, -45, -2, 0, -31, -17, 36, 47, 46, 18, 44,
- 29, -2, -11, 46, 74, 51, 14, 36, 46, -15, -78, -87, -91, -89, -46, -12,
- -11, -28, -5, 41, 46, 40, 17, 51, 33, -6, -13, 49, 75, 52, 15, 30,
- 34, -21, -79, -88, -93, -88, -42, -9, -4, -25, -3, 36, 40, 34, 16, 44,
- 23, -8, -10, 52, 83, 55, 17, 38, 31, -31, -82, -91, -93, -82, -39, -16,
- -10, -25, 5, 33, 42, 32, 20, 54, 25, -9, -3, 59, 85, 63, 24, 37,
- 24, -39, -86, -92, -97, -80, -34, -17, -15, -24, 10, 35, 45, 32, 16, 45,
- 12, -23, -2, 62, 78, 53, 21, 37, 26, -39, -91, -95, -96, -77, -29, -16,
- -16, -25, 10, -1, 0, 3, 21, -26, 18, -30, 32, -19, -15, -27, 2, 0,
- 103, -84, -53, -52, 79, 51, 36, -69, -31, 48, 71, 33, -74, -64, 10, 51,
- 49, -68, -91, -16, 30, 33, -31, -58, -42, 14, 24, -25, 23, -71, 79, -22,
- 123, -74, 28, 28, 115, 99, -7, 9, -15, 72, 1, 16, -47, -5, -71, -18,
- -75, -26, -71, -28, -56, -24, -57, -19, -33, -5, 7, -3, 14, -8, 82, 100,
- 23, -32, -15, 80, 98, 68, -30, -21, 24, 71, 28, -41, -96, -22, 32, 37,
- -57, -110, -67, 28, 35, -22, -112, -79, 13, 70, 27, -55, -63, 31, 95, 86,
- -4, -40, 29, 110, 110, 28, -50, -12, 66, 80, 14, -87, -81, -7, 36, -5,
- -95, -118, -42, 26, 8, -69, -121, -48, 37, 60, -6, -68, -29, 67, 104, 61,
- -24, -17, 70, 123, 92, -5, -43, 23, 82, 67, -28, -96, -54, 18, 30, -39,
- -115, -96, -7, 25, -13, -99, -101, -13, 52, 42, -35, -62, 9, 88, 93, 28,
- -32, 15, 97, 118, 58, -29, -24, 51, 82, 39, -61, -88, -26, 28, 9, -70,
- -117, -63, 7, 14, -46, -109, -71, 15, 55, 16, -51, -42, 43, 94, 75, 2,
- -21, 48, 107, 101, 23, -36, 4, 65, 70, 1, -81, -69, -3, 26, -19, -94,
- -106, -32, 14, -3, -74, -103, -37, 34, 46, -10, -56, -12, 66, 91, 49, -15,
- 1, 74, 111, 76, -4, -28, 31, 72, 50, -33, -85, -43, 11, 15, -46, -106,
- -80, -11, 13, -26, -92, -84, -8, 44, 29, -30, -48, 19, 80, 81, 26, -18,
- 27, 91, 103, 49, -22, -10, 48, 68, 22, -60, -75, -22, 17, -5, -71, -105,
- -54, 3, 3, -49, -98, -58, 14, 44, 11, -44, -27, 45, 85, 65, 5, -8,
- 53, 100, 87, 21, -26, 11, 60, 56, -6, -74, -58, -4, 13, -25, -90, -91,
- -29, 7, -12, -72, -90, -29, 32, 37, -10, -46, -2, 66, 83, 47, -8, 10,
- 74, 101, 68, -3, -19, 31, 62, 38, -36, -77, -40, 6, 4, -49, -100, -72,
- -12, 3, -31, -86, -73, -4, 37, 25, -28, -36, 25, 75, 74, 25, -9, 34,
- 88, 94, 43, -16, -4, 47, 58, 15, -57, -69, -22, 6, -12, -73, -96, -50,
- -4, -7, -53, -89, -49, 13, 36, 5, -37, -17, 47, 77, 59, 9, 2, 58,
- 92, 79, 19, -17, 16, 54, 45, -13, -69, -52, -8, 3, -33, -85, -82, -29,
- -2, -20, -68, -79, -23, 24, 29, -11, -34, 7, 61, 73, 41, 0, 22, 73,
- 90, 58, 1, -9, 32, 52, 26, -36, -69, -35, -3, -7, -53, -90, -63, -16,
- -7, -36, -78, -60, -4, 29, 16, -22, -23, 29, 68, 64, 26, 2, 42, 80,
- 81, 38, -8, 5, 42, 44, 4, -53, -57, -21, -2, -22, -69, -83, -43, -10,
- -15, -51, -77, -38, 11, 27, 3, -27, -5, 46, 68, 52, 13, 15, 58, 83,
- 68, 19, -8, 21, 46, 32, -16, -60, -44, -12, -6, -36, -76, -74, -34, -10,
- -20, -57, -73, -33, 12, 27, 3, -1, -6, -11, -3, 4, 0, -7, -8, 1,
- 21, 14, 28, 33, 25, -1, 7, 4, -13, -21, -44, -29, -17, -31, -32, 2,
- 0, -20, 4, 3, 4, 0, -2, -5, -4, -14, 3, 14, 9, 28, 34, 54,
- 43, 54, 39, 19, 17, -1, 5, -23, -31, -25, -35, -46, -60, -29, -29, -13,
- -37, -22, -16, -20, -27, -21, -6, -16, 8, -5, 15, 26, 69, 65, 74, 85,
- 81, 76, 51, 22, -10, -10, -19, -3, -39, -73, -55, -36, -18, -45, -49, -45,
- -52, -47, -74, -73, -56, -31, -15, -16, -5, 18, 65, 86, 108, 94, 97, 90,
- 79, 54, 30, 19, 10, 25, -16, -34, -37, -9, -16, -35, -44, -60, -60, -50,
- -62, -70, -66, -44, -34, -34, -29, -10, 23, 61, 85, 79, 75, 70, 61, 41,
- 31, 7, 8, 3, -22, -42, -28, 0, -13, -29, -39, -52, -56, -55, -58, -60,
- -57, -41, -35, -37, -19, 5, 35, 71, 87, 85, 97, 112, 97, 71, 56, 52,
- 53, 43, 18, -7, -3, 10, 0, -17, -39, -55, -58, -64, -80, -106, -121, -112,
- -110, -113, -105, -82, -51, -8, 16, 20, 45, 66, 66, 49, 46, 59, 75, 78,
- 63, 62, 74, 80, 80, 69, 51, 27, 11, 0, -14, -40, -53, -48, -55, -68,
- -71, -56, -34, -1, 14, 24, 49, 62, 59, 42, 34, 43, 47, 43, 26, 30,
- 33, 38, 26, 4, -17, -41, -66, -81, -92, -112, -120, -115, -116, -128, -125, -103,
- -71, -36, -11, 9, 33, 56, 59, 54, 61, 67, 77, 77, 77, 79, 74, 75,
- 73, 55, 30, 10, -21, -38, -46, -61, -70, -67, -70, -81, -77, -64, -45, -23,
- -4, 10, 30, 44, 44, 39, 42, 48, 51, 50, 51, 58, 58, 65, 65, 47,
- 29, 12, -14, -31, -41, -53, -63, -60, -62, -64, -58, -44, -26, -11, 1, 10,
- 20, 22, 17, 9, 5, 6, 6, 2, 4, 10, 10, 17, 19, 9, 7, -1,
- -14, -18, -13, -14, -9, 1, 7, 12, 17, 23, 31, 35, 36, 35, 38, 31,
- 21, 16, 3, 0, -8, -11, -11, -13, -19, -20, -23, -34, -39, -51, -69, -78,
- -81, -83, -83, -78, -70, -60, -47, -34, -19, 2, 20, 39, 57, 60, 66, 67,
- 63, 61, 53, 50, 51, 47, 37, 32, 23, 13, 6, -3, -17, -23, -28, -34,
- -37, -35, -27, -15, -2, 4, 12, 23, 30, 44, 47, 43, 41, 35, 29, 22,
- 15, 13, 14, 7, -1, -5, -11, -19, -20, -25, -37, -43, -41, -43, -47, -47,
- -40, -29, -17, -7, 5, 13, 23, 38, 44, 37, 34, 31, 23, 17, 6, 1,
- -2, -10, -20, -25, -35, -45, -50, -54, -64, -68, -65, -66, -65, -59, -47, -30,
- -19, -7, 5, 14, 28, 48, 62, 66, 72, 75, 78, 76, 67, 60, 56, 46,
- 32, 20, 9, -2, -10, -21, -35, -43, -44, -49, -56, -57, -51, -38, -25, -13,
- -2, 9, 25, 42, 56, 59, 64, 65, 67, 65, 57, 52, 49, 41, 28, 18,
- 8, -2, -10, 0, 8, 13, 21, 20, 20, 17, 10, 8, -2, -6, -17, -21,
- -29, -23, -25, -14, -7, -2, 7, 10, 20, 21, 22, 23, 19, 14, 9, -2,
- -6, -18, -20, -28, -25, -23, -18, -10, -3, 5, 9, 22, 17, 28, 22, 21,
- 17, 11, 2, -8, -18, -23, -27, -26, -24, -19, -13, -6, 3, 9, 17, 20,
- 28, 24, 25, 21, 13, 6, -5, -14, -21, -29, -29, -30, -23, -19, -7, -1,
- 10, 18, 25, 29, 27, 28, 20, 17, 5, -7, -13, -26, -29, -30, -30, -27,
- -20, -12, 0, 11, 19, 25, 27, 30, 26, 28, 19, 11, -2, -12, -24, -30,
- -35, -34, -30, -24, -14, -2, 9, 18, 23, 28, 26, 33, 31, 29, 24, 12,
- 5, -12, -23, -30, -37, -36, -36, -26, -19, -5, 5, 19, 22, 32, 32, 36,
- 35, 26, 21, 3, -6, -22, -34, -41, -44, -38, -31, -18, -6, 6, 15, 23,
- 32, 33, 39, 34, 31, 23, 10, -2, -21, -32, -44, -47, -45, -37, -23, -12,
- 6, 13, 28, 30, 38, 40, 40, 38, 23, 17, -6, -15, -35, -42, -50, -49,
- -41, -31, -14, 0, 14, 26, 35, 42, 45, 45, 40, 27, 18, -4, -14, -33,
- -42, -54, -52, -47, -36, -21, -5, 13, 24, 39, 43, 52, 47, 42, 36, 20,
- 7, -15, -32, -45, -55, -56, -54, -43, -27, -8, 12, 26, 38, 45, 50, 51,
- 48, 40, 27, 9, -11, -30, -46, -58, -62, -58, -49, -31, -11, 9, 24, 41,
- 45, 54, 53, 54, 45, 30, 14, -10, -27, -48, -58, -67, -64, -56, -35, -15,
- 6, 24, 37, 45, 54, 56, 56, 49, 39, 18, 0, -26, -45, -60, -74, -70,
- -63, -41, -23, 4, 21, 39, 48, 53, 61, 58, 59, 43, 29, 3, -20, -46,
- -64, -77, -77, -69, -50, -27, 0, 20, 36, 49, 56, 64, 64, 63, 51, 34,
- 6, -17, -46, -65, -79, -83, -76, -58, -33, -6, 17, 38, 49, 60, 67, 68,
- 66, 53, 37, 13, -13, -38, -65, -79, -90, -82, -68, -41, -15, 14, 36, 52,
- 63, 70, 73, 69, 62, 44, 19, -8, -38, -63, -83, -93, -90, -77, -49, -20,
- 12, 34, 54, 65, 72, 75, 76, 65, 51, 26, -1, -33, -62, -86, -98, -96,
- -86, -58, -29, 6, 32, 54, 66, 73, 79, 76, 73, 58, 36, 4, -27, -60,
- -85, -101, -104, -92, -70, -36, -1, 31, 53, 70, 75, 81, 80, 78, 65, 41,
- 15, -24, -56, -84, -105, -109, -101, -79, -46, -7, 25, 56, 65, 77, 82, 85,
- 83, 69, 51, 19, -14, -50, -83, -103, -115, -107, -88, -55, -17, 21, 50, 67,
- 81, 86, 89, 85, 79, 55, 28, -8, -46, -77, -103, -116, -117, -97, -67, -25,
- 1, 39, 66, 81, 92, 96, 97, 90, 73, 45, 11, -27, -64, -97, -120, -128,
- -117, -89, -49, -5, 35, 65, 81, 93, 98, 99, 91, 75, 46, 12, -27, 28,
- -9, -42, -57, -50, -18, 33, 77, 77, 17, -64, -96, -55, 22, 73, 68, 17,
- -43, -77, -67, -15, 59, 102, 79, 12, -48, -71, -57, -28, -3, 11, 10, -3,
- -17, -4, 44, 88, 79, 10, -69, -103, -74, -6, 54, 75, 53, -4, -63, -80,
- -38, 32, 73, 59, 7, -43, -67, -57, -18, 33, 71, 71, 24, -31, -47, -17,
- 20, 23, -14, -58, -73, -47, 10, 73, 110, 93, 20, -62, -97, -68, -6, 43,
- 54, 28, -13, -51, -65, -35, 26, 74, 69, 12, -50, -68, -37, 9, 37, 37,
- 16, -12, -26, -7, 36, 65, 45, -19, -87, -112, -75, -7, 58, 97, 92, 41,
- -30, -75, -62, -3, 49, 52, 7, -44, -63, -45, -6, 37, 60, 42, -5, -42,
- -41, -3, 38, 41, 8, -33, -51, -38, 3, 54, 90, 79, 12, -76, -127, -106,
- -29, 47, 78, 63, 23, -19, -36, -16, 24, 50, 35, -15, -59, -64, -27, 17,
- 40, 35, 11, -20, -39, -26, 19, 63, 67, 14, -61, -97, -72, -5, 64, 101,
- 87, 26, -49, -96, -86, -32, 24, 40, 17, -11, -17, -3, 24, 51, 55, 29,
- -20, -66, -69, -23, 35, 55, 25, -26, -59, -55, -14, 44, 86, 80, 23, -56,
- -105, -87, -19, 48, 79, 67, 27, -18, -46, -43, -14, 17, 16, -20, -54, -47,
- 3, 59, 83, 66, 18, -35, -64, -54, -8, 44, 59, 18, -48, -87, -72, -16,
- 49, 88, 84, 37, -31, -81, -79, -26, 33, 52, 29, -5, -19, -6, 20, 34,
- 27, -5, -51, -84, -71, -9, 62, 95, 71, 12, -40, -58, -37, 8, 52, 63,
- 22, -53, -103, -88, -23, 47, 80, 64, 24, -14, -33, -28, -3, 21, 18, -15,
- -45, -39, 5, 57, 78, 54, -1, -60, -97, -89, -29, 50, 92, 67, 0, -53,
- -57, -13, 38, 64, 52, 10, -44, -82, -76, -26, 28, 49, 32, 1, -14, -1,
- 24, 40, 38, 9, -43, -87, -79, -13, 69, 110, 80, 4, -65, -90, -69, -21,
- 32, 58, 39, -9, -48, -45, 0, 52, 69, 46, 5, -34, -57, -50, -14, 23,
- 28, -8, -48, -48, 4, 71, 99, 69, 3, -63, -99, -88, -30, 46, 92, 78,
- 16, -45, -66, -44, -6, 25, 34, 16, -24, -55, -43, 10, 67, 80, 37, -22,
- -48, -29, 7, 30, 27, -5, -51, -84, -73, -11, 71, 116, 95, 27, -43, -84,
- -84, -43, 18, 63, 60, 10, -44, -53, -9, 41, 49, 14, -31, -57, -50, -15,
- 29, 61, 57, 14, -37, -51, -14, 38, 63, 47, -1, -61, -106, -105, -47, 44,
- 115, 113, 42, -36, -64, -42, -2, 23, 20, -3, -28, -39, -21, 24, 64, 59,
- 7, -48, -67, -47, -7, 36, 59, 47, 2, -55, -77, -31, 55, 111, 89, 7,
- -75, -113, -96, -42, 21, 62, 64, 28, -13, -18, 17, 45, 28, -2, -7, -6,
- -7, -7, -8, -8, -8, -8, -7, -6, -5, -4, -3, -3, -2, -2, -1, 0,
- 1, 2, 4, 5, 6, 8, 9, 10, 11, 12, 13, 13, 14, 15, 16, 17,
- 17, 17, 17, 17, 16, 16, 15, 15, 14, 14, 13, 12, 10, 10, 9, 8,
- 7, 6, 5, 5, 4, 3, 2, 1, 0, -2, -3, -4, -5, -6, -7, -8,
- -9, -10, -11, -12, -13, -13, -14, -14, -14, -14, -14, -15, -15, -15, -15, -16,
- -16, -14, -14, -12, -10, -13, -10, -13, -7, -3, -5, -1, -1, -5, -5, 8,
- 13, 10, 10, 15, 16, 17, 30, 34, 19, 17, 22, 29, 27, 22, 16, 1,
- -3, 8, 18, 11, 6, 8, 8, 1, 6, 18, 5, -8, -4, 4, 5, 3,
- 5, -3, -6, 12, 30, 23, 9, 5, 6, 9, 15, 27, 20, 2, 0, 10,
- 17, 8, -1, -4, -8, -8, -3, -7, -19, -28, -24, -22, -31, -42, -47, -50,
- -50, -42, -35, -35, -43, -41, -31, -27, -23, -17, -9, -7, 3, 26, 37, 38,
- 37, 41, 39, 39, 49, 55, 50, 46, 53, 58, 51, 44, 36, 24, 9, 5,
- 2, -12, -25, -28, -26, -33, -42, -44, -55, -66, -69, -62, -60, -65, -57, -42,
- -33, -26, -15, -5, -6, 0, 15, 29, 34, 41, 55, 61, 62, 68, 71, 62,
- 49, 49, 49, 39, 29, 24, 14, -2, -10, -16, -34, -56, -67, -70, -77, -83,
- -85, -88, -93, -92, -79, -74, -78, -74, -61, -49, -41, -23, -9, -2, 11, 35,
- 54, 56, 58, 64, 69, 73, 81, 91, 86, 77, 78, 77, 67, 50, 39, 24,
- 6, -4, -10, -22, -41, -49, -52, -62, -73, -81, -87, -98, -97, -83, -74, -70,
- -63, -46, -33, -23, -6, 9, 18, 26, 48, 69, 77, 85, 97, 106, 107, 111,
- 114, 104, 89, 83, 84, 75, 60, 50, 34, 13, -5, -16, -34, -59, -74, -80,
- -86, -95, -97, -96, -104, -104, -95, -86, -86, -82, -66, -49, -32, -11, 12, 26,
- 36, 55, 73, 81, 84, 94, 104, 107, 114, 120, 116, 102, 92, 88, 73, 54,
- 37, 21, 0, -16, -23, -37, -58, -76, -85, -94, -108, -114, -116, -120, -119, -106,
- -89, -84, -78, -64, -49, -37, -21, 1, 13, 25, 46, 71, 88, 95, 105, 113,
- 112, 113, 116, 112, 97, 91, 91, 83, 68, 51, 35, 11, -10, -23, -38, -60,
- -80, -86, -93, -102, -107, -110, -116, -121, -114, -102, -98, -93, -77, -55, -38, -18,
- 1, 13, 25, 46, 71, 88, 95, 105, 113, 112, 113, 116, 112, 97, 91, 91,
- 83, 68, 51, 35, 11, -10, -23, -38, -60, -80, -86, -93, -102, -107, -110, -116,
- -121, -114, -102, -98, -93, -77, -55, -38, -18, 1, -3, -7, -8, -3, 1, 0,
- 3, -5, -9, -14, -15, -4, 0, 7, 12, 12, 11, 18, 16, 14, 14, 11,
- 20, 14, 19, 7, 12, 8, 13, 8, 7, 9, 0, 9, -7, -4, -5, -8,
- -7, -9, -7, -2, -7, -4, 1, 1, 0, -2, 3, 2, 1, 2, 1, -2,
- -3, -7, -2, -2, -2, -5, -4, -4, -4, 3, 6, 8, 3, 0, -3, -2,
- 3, 4, 3, 2, 2, -2, 1, 0, 2, 3, 9, 8, 2, -3, -4, -2,
- 1, 4, 0, -2, 3, 1, 7, 1, -4, 0, 2, 3, 1, 1, 2, -5,
- 3, -3, -4, -3, -8, 2, -7, 1, -3, -2, -5, -8, -7, -8, -7, -5,
- -7, -4, -8, -10, -7, -8, -7, -5, 0, -2, 0, -2, -3, -3, -2, 0,
- 1, 0, 1, 0, -3, -3, -5, -5, -9, -9, -13, -16, -21, -26, -25, -25,
- -16, -16, -12, -13, -15, -9, 3, 25, 44, 66, 68, 66, 49, 17, 13, 18,
- 41, 51, 40, 35, 25, 23, -2, -16, -28, -8, -4, -12, -18, -34, -29, -31,
- -28, -18, -4, 2, 16, 13, 20, 9, 4, 2, -3, -4, -9, -9, -9, -8,
- -9, -10, -13, -14, -15, -13, -4, 7, 13, 19, 18, 16, 9, 7, 4, 6,
- 8, 7, 7, 3, -3, -15, -19, -24, -21, -16, -9, 0, 3, 7, 4, 4,
- -3, -2, 6, 13, 20, 14, 16, 14, 11, 7, 0, -4, -3, -3, -7, -12,
- -12, -9, -5, -5, -7, -9, -4, -2, -2, -2, -4, -9, -10, -13, -13, -14,
- -15, -13, -9, -8, -9, -9, -7, -4, 2, 2, 6, 9, 8, 11, 9, 11,
- 9, 8, 6, 0, -7, -13, -21, -29, -36, -45, -53, -63, -72, -73, -61, -41,
- 0, 52, 98, 109, 81, 64, 54, 78, 77, 45, 39, 44, 25, 19, 6, -8,
- 25, 30, 44, 62, 46, -20, -85, -89, -88, -47, -29, -30, 2, 11, 8, 12,
- 24, 33, 29, 25, 22, 1, -15, -34, -37, -36, -41, -36, -28, -15, 2, 9,
- 11, 14, 12, 8, 12, 17, 18, 19, 23, 20, 20, 20, 8, -5, -14, -15,
- -15, -13, -13, -18, -19, -24, -29, -32, -31, -23, -12, -2, 12, 20, 23, 24,
- 25, 20, 22, 18, 16, 14, 9, 7, 2, 1, -9, -10, -19, -15, -12, -13,
- -8, -5, -4, -4, -7, -10, -12, -12, -16, -14, -8, -9, -13, -14, -18, -15,
- -10, -5, -3, 3, 4, 6, 11, 13, 13, 16, 16, 16, 12, 6, -3, -10,
- -16, -21, -28, -37, -48, -61, -77, -88, -87, -68, -34, 28, 92, 127, 99, 64,
- 50, 72, 92, 55, 43, 51, 41, 32, 4, -8, -7, -17, -23, -31, -33, -35,
- -32, -28, -23, -18, -12, -8, -4, -2, 0, 1, 2, 2, 3, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 3, 4, 6, 7, 7, 7, 8, 9, 9, 8,
- 8, 9, 11, 14, 18, 22, 27, 32, 33, 30, 21, 6, -12, -30, -45, -54,
- -56, -51, -41, -29, -17, -9, -3, 0, 1, 1, 1, 1, 1, 1, 1, 2,
- 2, 3, 3, 3, 3, 3, 2, 3, 4, 5, 8, 9, 10, 9, 8, 7,
- 7, 8, 10, 15, 20, 25, 30, 35, 39, 39, 32, 19, 0, -22, -42, -56,
- -62, -61, -53, -40, -27, -15, -7, -3, -1, 0, 0, 0, 0, 2, 3, 4,
- 5, 5, 5, 4, 2, 0, -1, 0, 2, 5, 8, 9, 10, 10, 9, 9,
- 8, 9, 10, 14, 19, 24, 28, 32, 34, 38, 36, 29, 17, -5, -28, -49,
- -61, -65, -61, -52, -39, -25, -14, -7, -3, -2, -1, -2, -1, 0, 2, 4,
- 6, 7, 7, 5, 3, 0, -1, -1, 0, 3, 7, 11, 13, 14, 13, 12,
- 10, 8, 8, 9, 12, 17, 22, 26, 29, 31, 33, 31, 26, 18, 3, -16,
- -35, -50, -59, -61, -56, -46, -35, -23, -14, -6, -2, 0, 1, 2, 3, 4,
- 4, 5, 5, 5, 4, 2, 1, -1, -1, 0, 2, 5, 9, 12, 13, 13,
- 12, 11, 9, 7, 7, 8, 11, 15, 20, 24, 29, 33, 35, 34, 30, 21,
- 4, -16, -37, -55, -66, -68, -63, -50, -35, -21, -9, -1, 4, 5, 5, 4,
- 4, 3, 3, 3, 3, 2, 2, 1, 0, -1, -1, 1, 6, 10, 13, 15,
- 15, 13, 11, 8, 5, 4, 4, 7, 11, 17, 22, 27, 32, 36, 39, 39,
- 36, 24, 6, -20, -48, -70, -81, -79, -67, -48, -29, -12, -1, 5, 7, 7,
- 4, 2, 1, 1, 2, 2, 3, 2, 2, -1, -2, -3, -3, -1, 3, 8,
- 13, 16, 17, 16, 12, 8, 3, -1, -3, -2, 2, 11, 21, 29, 36, 38,
- 39, 42, 48, 57, 52, 23, -27, -76, -107, -113, -98, -71, -42, -18, -1, 8,
- 12, 13, 10, 7, 3, 1, 1, 2, 3, 2, 1, 0, -2, -3, -3, -1,
- 2, 8, 13, 17, 18, 17, 12, 7, 1, -3, -4, -3, 20, 30, 38, 41,
- 39, 38, 46, 65, 75, 45, -23, -89, -126, -127, -101, -64, -31, -7, 5, 11,
- 13, 14, 13, 9, 4, 1, 0, 1, 2, 1, -1, -3, -4, -4, -2, 2,
- 6, 10, 14, 18, 18, 15, 9, 1, -6, -10, -13, -10, -4, 7, 20, 0,
- 14, 19, 23, 26, 28, 28, 26, 23, 18, 11, 3, -4, -10, -16, -21, -23,
- -24, -22, -20, -16, -12, -8, -3, 3, 8, 13, 19, 23, 26, 27, 26, 23,
- 17, 10, 4, -3, -9, -15, -20, -24, -25, -25, -22, -17, -11, -3, 3, 9,
- 14, 18, 20, 22, 23, 23, 21, 17, 13, 6, 1, -6, -11, -15, -18, -20,
- -19, -19, -17, -16, -13, -11, -8, -5, -1, 2, 5, 7, 9, 9, 8, 6,
- 3, 0, -3, -7, -10, -14, -17, -19, -19, -18, -16, -12, -7, -2, 3, 8,
- 13, 16, 18, 19, 17, 14, 8, -1, -11, -21, -31, -38, -41, -40, -34, -25,
- -12, 2, 17, 32, 45, 56, 62, 65, 63, 58, 49, 38, 25, 10, -6, -18,
- -28, -37, -44, -51, -59, -64, -64, -56, -40, -17, 7, 29, 46, 56, 58, 59,
- 56, 51, 45, 33, 19, 4, -13, -26, -39, -49, -56, -59, -55, -46, -34, -19,
- -4, 10, 21, 30, 40, 46, 51, 52, 49, 43, 31, 18, 5, -8, -16, -21,
- -23, -26, -29, -35, -39, -42, -40, -34, -22, -11, 2, 11, 18, 21, 24, 23,
- 22, 19, 14, 7, -3, -13, -21, -30, -39, -46, -50, -52, -49, -42, -31, -17,
- -3, 12, 26, 39, 49, 57, 60, 58, 51, 39, 22, 1, -23, -47, -68, -82,
- -89, -88, -77, -60, -37, -11, 16, 43, 65, 83, 94, 100, 101, 96, 87, 71,
- 51, 29, 4, -18, -38, -58, -75, -91, -104, -109, -105, -87, -61, -27, 8, 39,
- 67, 87, 97, 97, 88, 71, 54, 36, 16, -2, -23, -42, -57, -70, -75, -75,
- -71, -60, -43, -23, -1, 18, 31, 47, 57, 66, 71, 68, 61, 49, 32, 17,
- 1, -11, -22, -33, -41, -47, -54, -59, -63, -62, -57, -46, -30, -12, 1, 17,
- 30, 41, 49, 50, 47, 40, 29, 17, 3, -14, -30, -46, -60, -70, -76, -77,
- -73, -63, -48, -28, -4, 20, 44, 65, 81, 91, 93, 88, 77, 60, 37, 11,
- -19, -49, -76, -97, -109, -110, -100, -81, -56, -25, 7, 38, 67, 91, 109, 121,
- 127, 126, 116, 96, 68, 38, 8, -18, -43, -68, -90, -110, -124, -127, -116, -91,
- -59, -22, 14, 47, 77, 98, 107, 105, 93, 74, 54, 33, 13, -6, -26, -45,
- -60, -71, -78, -79, -74, -61, -42, -21, 1, 18, 33, 49, 60, 68, 73, 70,
- 62, 48, 32, 15, 0, -13, -24, -34, -42, -48, -55, -61, -65, -65, -60, -48,
- -32, -15, 2, 19, 32, 43, 50, 51, 47, 40, 28, 16, 1, -14, 2, -2,
- 2, -5, -3, -1, 0, -4, -4, -6, -4, -6, -4, -4, -7, -6, -7, -6,
- -1, 0, 3, 13, 14, 16, 12, 13, 2, 1, 0, -1, -1, -1, -2, -2,
- -2, -3, -3, -4, -8, -4, -4, -5, -5, -5, -7, -9, -12, -8, -14, -11,
- -14, -18, -8, 1, 31, 71, 68, 24, -5, -11, -7, -5, -5, -5, -3, -2,
- -5, -5, -9, -8, -7, -7, -9, -12, -11, -17, -14, -16, -15, -20, -26, -30,
- -27, -15, 16, 51, 87, 101, 70, 8, -18, -11, -14, -7, -7, -1, -2, -5,
- -7, -12, -14, -10, -10, -13, -14, -13, -16, -16, -17, -18, -35, -31, -30, -34,
- -9, 16, 56, 84, 89, 60, 30, 5, -7, -5, -8, -3, -4, -4, -6, -12,
- -14, -13, -10, -12, -12, -9, -10, -8, -12, -13, -15, -19, -23, -26, -33, -29,
- -28, -9, 12, 43, 71, 88, 72, 48, 29, -2, -16, -19, -12, -12, -12, -7,
- -11, -10, -10, -10, -11, -13, -15, -18, -19, -17, -16, -15, -13, -12, -13, -9,
- -13, -17, -21, -18, 2, 34, 59, 87, 92, 98, 38, -30, -24, -27, -18, -16,
- -11, -11, -13, -15, -12, -14, -15, -18, -17, -20, -18, -15, -10, -7, -3, -1,
- 2, -8, -11, -22, -22, -20, 7, 31, 61, 97, 106, 43, -23, -28, -25, -20,
- -12, -7, -5, -7, -10, -13, -13, -13, -11, -14, -15, -15, -12, -8, -7, -4,
- -2, -4, -10, -15, -19, -26, -10, 12, 42, 72, 101, 90, 20, -25, -27, -22,
- -18, -10, -6, -9, -11, -16, -17, -16, -14, -10, -8, -9, -9, -9, -9, -9,
- -8, -5, -3, -6, -10, -17, -24, -21, 4, 30, 61, 84, 96, 79, -16, -38,
- -27, -26, -17, -12, -8, -12, -13, -14, -14, -11, -8, -4, -4, -7, -9, -8,
- -10, -12, -8, -5, -4, -7, -10, -18, -24, -11, 14, 42, 70, 79, 93, 36,
- -32, -26, -28, -19, -15, -9, -9, -13, -16, -14, -12, -8, -5, -3, -7, -9,
- -9, -9, -11, -8, -5, -1, -6, -9, -15, -24, -23, 6, 28, 63, 86, 127,
- 37, -45, -27, -28, -26, -19, -4, -5, -8, -11, -12, -14, -12, -8, -4, -8,
- -8, -10, -8, -13, -8, -8, -3, -8, -8, -16, -23, -17, 7, 34, 69, 83,
- 113, 37, -50, -28, -25, -22, -16, 0, -3, -8, -12, -12, -14, -14, -10, -5,
- -7, -6, -9, -9, -13, -9, -10, -7, -9, -9, -15, -20, -14, 8, 33, 64,
- 81, 90, 57, -29, -28, 0, -4, 10, 10, 11, -15, 4, -1, 3, -11, 11,
- 2, -12, 3, 18, -10, -62, 89, -16, -95, 118, -128, 122, -128, 112, -100, 109,
- -121, 120, -104, 58, 10, -88, 127, -102, 6, 98, -126, 35, 89, -111, -7, 112,
- -53, -94, 92, 64, -106, -53, 109, 52, -100, -75, 86, 95, -45, -119, -12, 111,
- 74, -58, -118, -27, 97, 100, -4, -107, -95, 17, 109, 92, -4, -99, -109, -26,
- 78, 115, 66, -27, -104, -109, -41, 55, 112, 98, 32, -53, -109, -105, -44, 41,
- 102, 109, 67, -4, -74, -112, -102, -47, 27, 88, 112, 93, 45, -19, -78, -110,
- -105, -65, -4, 59, 101, 110, 87, 43, -13, -67, -103, -111, -89, -44, 13, 65,
- 100, 109, 93, 59, 14, -36, -78, -104, -108, -90, -53, -6, 43, 83, 104, 106,
- 88, 57, 17, -27, -66, -95, -108, -102, -80, -44, -2, 41, 77, 99, 106, 98,
- 77, 46, 10, -29, -64, -91, -105, -105, -91, -64, -29, 10, 48, 78, 98, 105,
- 100, 84, 59, 30, -3, -36, -65, -88, -101, -105, -99, -83, -60, -32, -1, 30,
- 58, 80, 96, 103, 102, 94, 80, 62, 40, 16, -10, -35, -58, -78, -92, -101,
- -104, -100, -91, -77, -58, -36, -13, 12, 36, 57, 75, 89, 98, 102, 102, 97,
- 88, 76, 61, 44, 25, 5, -15, -35, -54, -70, -84, -94, -101, -104, -103, -98,
- -89, -77, -63, -46, -27, -8, 12, 31, 49, 65, 79, 90, 97, 102, 104, 102,
- 97, 90, 81, 70, 57, 42, 27, 10, -7, -24, -40, -56, -70, -81, -91, -99,
- -103, -105, -105, -101, -95, -87, -76, -63, -49, -34, -18, -1, 16, 32, 48, 62,
- 74, 85, 93, 100, 104, 105, 105, 102, 97, 90, 82, 72, 61, 48, 35, 21,
- 6, -9, -24, -38, -52, -65, -76, -86, -94, -101, -105, -108, -108, -106, -102, -96,
- -87, -78, -66, -54, -40, -26, -11, 4, 19, 34, 48, 61, 73, 83, 92, 99,
- 104, 107, 108, 108, 105, 101, 96, 89, 80, 70, 60, 48, 36, 22, 9, -5,
- -19, -33, -46, -58, -69, -80, -89, -96, -102, -107, -109, -110, -110, -107, -102, -97,
- -89, -80, -70, -59, -47, -33, -20, -6, 7, 19, 30, 41, 50, 58, 65, 71,
- 75, 78, 79, 80, 79, 77, 74, 70, 65, 60, 54, 48, 42, 36, 29, 22,
- 16, 10, 4, -2, -7, -12, -16, -19, -22, -24, -26, -27, -27, -27, -26, -25,
- -23, -22, -19, -17, -14, -12, -10, -1, -1, -4, -9, -9, -7, -6, -7, -3,
- 4, 8, 10, 11, 13, 10, 4, -3, -10, -15, -13, -9, -10, -11, -5, 4,
- 12, 14, 12, 13, 14, 9, 1, -8, -15, -21, -23, -22, -13, -3, 7, 17,
- 24, 27, 19, 11, 16, 15, -5, -24, -29, -23, -27, -32, -21, 5, 18, 20,
- 21, 24, 24, 15, 11, 8, -6, -30, -31, -19, -17, -24, -14, 2, 17, 15,
- 12, 17, 16, 19, 8, -5, -2, -1, -17, -17, -3, 6, 5, -4, 0, 1,
- -12, -9, 9, 11, -4, -14, -8, 9, -2, -21, -14, 4, 9, 9, 11, 18,
- 21, 10, 8, 16, 10, 26, 35, 6, -14, -28, -25, -24, -55, -65, -33, -17,
- 1, -6, -6, 8, 23, 33, 49, 37, 19, 16, 11, 24, 42, 17, -37, -36,
- 3, 7, -23, -36, -9, 9, -12, -20, -8, -2, -4, -23, -17, -6, 0, 10,
- 24, 24, 40, 46, 33, 39, 26, 5, 6, 9, -12, -26, -33, -42, -61, -52,
- -43, -37, -21, -4, 7, 13, 28, 36, 31, 24, 1, -1, 20, 24, 23, 21,
- 26, 27, 8, -32, -44, -3, 28, -1, -36, -30, -6, 13, -12, -34, -18, -6,
- 9, 21, 25, 16, 10, 38, 62, 46, 17, -11, -7, 10, -8, -44, -53, -33,
- -35, -38, -29, -27, -16, 0, 1, 9, 37, 50, 36, 2, -20, -12, 15, 21,
- 24, 32, 29, 20, 23, 12, -8, -3, 4, -10, -5, 2, -19, -63, -70, -21,
- 20, 41, 23, 33, 57, 61, 42, 21, 15, 10, -45, -82, -60, -29, -44, -77,
- -50, -7, 4, -4, 10, 32, 56, 42, 1, -10, -18, 2, 22, 28, 33, 42,
- 47, 43, 47, 11, -23, 0, 10, -40, -81, -70, -28, -29, -68, -29, 19, 6,
- 7, 21, 40, 41, 32, 22, 28, 47, 69, 66, 35, 21, 15, -3, -20, -34,
- -24, -6, -19, -59, -47, -42, -35, -28, 15, 45, 51, 66, 78, 83, 37, 1,
- 13, 7, -51, -81, -92, -83, -87, -74, -58, -73, -51, 12, 35, 26, 35, 47,
- 69, 70, 63, 65, 49, 47, 68, 73, 52, 33, 15, -12, -30, -50, -51, -46,
- -45, -60, -50, -50, -50, -54, -24, 38, 78, 90, 106, 99, 40, -6, -11, -46,
- -110, -127, -107, -76, -67, -53, -41, -41, -23, 14, 33, 27, 34, 49, 70, 71,
- 66, 65, 51, 51, 69, 72, 52, 32, 10, -12, 0, -5, -2, -5, 2, -29,
- 22, 0, -27, 67, -59, 45, -13, -37, 28, 65, -4, 6, 60, 5, 58, 44,
- 60, 27, 43, 96, 71, 81, 48, 96, 70, 23, 90, 66, 80, 88, 40, 20,
- 61, 64, 12, 36, 24, 4, 7, 5, -27, -38, -26, -33, -49, -50, -70, -69,
- -93, -92, -94, -104, -104, -101, -110, -107, -111, -111, -126, -87, -119, -100, -94, -112,
- -93, -93, -80, -81, -76, -58, -56, -70, -30, -21, -42, -13, -3, 2, 8, 20,
- 28, 41, 45, 59, 62, 69, 84, 85, 90, 103, 109, 111, 118, 121, 121, 123,
- 121, 122, 121, 122, 121, 122, 121, 121, 120, 121, 120, 121, 120, 121, 120, 120,
- 119, 120, 119, 120, 118, 105, 106, 110, 83, 89, 92, 75, 67, 61, 57, 47,
- 40, 33, 24, 17, 10, 3, -2, -10, -20, -31, -31, -37, -49, -50, -63, -66,
- -69, -74, -79, -91, -89, -92, -95, -102, -106, -104, -107, -113, -113, -110, -113, -116,
- -114, -115, -114, -115, -114, -113, -114, -113, -114, -113, -112, -113, -109, -105, -111, -106,
- -107, -103, -100, -103, -99, -97, -98, -99, -92, -92, -93, -92, -92, -90, -88, -90,
- -88, -86, -89, -85, -85, -87, -85, -85, -82, -83, -82, -80, -78, -79, -76, -74,
- -73, -73, -69, -68, -66, -64, -65, -62, -58, -56, -56, -52, -50, -47, -43, -42,
- -39, -35, -33, -31, -27, -23, -21, -16, -16, -8, -7, -3, 1, 0, 10, 15,
- 15, 19, 26, 29, 30, 38, 41, 42, 47, 54, 54, 57, 63, 68, 69, 72,
- 77, 78, 80, 85, 84, 86, 87, 86, 87, 86, 85, 86, 85, 84, 85, 84,
- 83, 84, 83, 82, 82, 83, 82, 81, 82, 81, 80, 81, 80, 79, 80, 79,
- 79, 78, 79, 78, 78, 77, 74, 70, 66, 64, 61, 55, 52, 49, 45, 40,
- 35, 32, 29, 24, 19, 15, 12, 8, 4, 0, -4, -8, -11, -15, -17, -20,
- -25, -26, -29, -32, -34, -37, -39, -41, -43, -45, -46, -48, -49, -50, -50, -52,
- -52, -53, -52, -53, -54, -53, -53, -52, -52, -51, -50, -50, -49, -48, -48, -46,
- -45, -44, -42, -41, -40, -39, -37, -35, -34, -32, -30, -28, -27, -24, -23, -22,
- -20, -19, -17, -15, -14, -13, -12, -10, -9, -8, -8, -6, -6, -5, -4, -4,
- -3, -3, -2, -2, -1, -2, -1, -2, -1, -1, 0, -1, -1, 1, 0, 0,
- -3, -1, 1, -4, -4, -3, -2, -5, -3, 0, -1, -1, -3, -1, 0, 2,
- 0, -2, -5, 5, 4, 1, 7, 2, 2, 1, 8, 1, 6, 2, -4, 2,
- 1, -4, 6, -8, -3, -7, -2, -6, -1, -9, 1, -2, -4, 1, 2, 1,
- -2, 8, 2, 0, 14, 9, 10, 5, 3, 5, 6, 4, 3, -8, -2, -4,
- -10, -1, -5, -3, -4, -6, -13, -5, -4, -4, -3, 2, -13, -6, 3, 6,
- 6, 7, 1, 1, 6, 6, 16, 13, 9, 10, 9, 2, 7, 10, 4, -4,
- -3, -17, -7, -6, -6, -10, -17, -17, -10, -11, -9, -5, -6, -8, 2, 1,
- 8, 19, 15, 18, 24, 19, 16, 17, 19, 11, 7, 1, -5, -8, -9, -15,
- -8, -9, -14, -20, -19, -9, -18, -10, -13, -23, -13, -12, -7, 0, -1, 5,
- 16, 12, 28, 30, 32, 34, 34, 19, 24, 23, 16, 11, 5, -7, -19, -17,
- -16, -21, -26, -23, -32, -31, -30, -25, -26, -24, -19, -13, -9, -1, 0, 4,
- 6, 13, 15, 19, 17, 13, 8, 8, 8, 7, 0, -4, -8, -10, -7, -5,
- -6, -6, -9, -12, -8, -10, -9, -9, -11, -13, -12, -9, -4, -1, 4, 9,
- 19, 27, 31, 26, 16, 14, 16, 16, 12, 1, -8, -14, -11, -9, -6, -11,
- -11, -12, -14, -10, -11, -13, -15, -19, -23, -19, -14, -8, -5, -1, 8, 34,
- 62, 59, 12, 14, 32, 22, 6, 20, 6, -9, -54, -16, -1, -19, 7, -15,
- -13, -12, -14, -15, -14, -22, -24, -30, -30, -20, -12, -6, 3, 26, 66, 88,
- 39, 0, 47, 36, -2, 26, -23, 21, 13, -6, -60, -42, 6, -22, 4, -18,
- -16, -4, -16, -19, -24, -39, -31, -25, -32, -26, -11, 12, 55, 104, 75, 10,
- 35, 62, 9, 26, -16, -8, 19, 3, -9, -61, -46, 2, -26, -7, -16, -10,
- 2, -7, -22, -23, -38, -40, -37, -44, -33, -8, 37, 101, 124, 36, -5, 89,
- 20, 38, 5, -26, 3, 1, 5, -28, -65, -21, 1, -22, -12, -26, 1, -7,
- -10, -24, -26, -33, -37, -48, -50, -36, 5, 63, 122, 109, 7, 35, 84, 5,
- 59, -36, -4, -11, -1, -5, -40, -55, -4, -15, -21, -16, -22, 5, -10, -17,
- -20, -27, -23, -44, -54, -62, -23, 29, 114, 127, 51, 7, -2, -4, -2, 4,
- 11, 14, 10, 2, -7, -9, -9, -15, -16, -7, 3, 2, -10, -21, -17, 6,
- 10, -8, -28, -11, 45, 66, 64, 47, 36, 49, 49, 27, 9, -12, -18, -25,
- -30, -11, 0, -5, 0, -1, -18, -36, -33, -18, -10, -13, -31, -26, -25, -17,
- 4, 28, 70, 89, 48, 9, -32, -58, -56, -70, -57, -17, -38, -48, -35, -32,
- -7, 35, 38, 53, 62, 44, 33, 27, -6, -35, -52, -65, -54, -40, -43, -30,
- -25, 2, 63, 54, 34, 17, 34, 70, 60, 8, -15, -3, 0, 39, 55, 35,
- 39, 60, 75, 36, 20, -7, -25, -66, -110, -89, -89, -71, -36, -12, 9, 31,
- 41, 54, 46, 45, 59, 41, 22, 3, -69, -110, -126, -116, -64, -15, 9, 29,
- 33, 30, 56, 42, 12, 23, 6, -27, -36, -21, -22, -32, -21, -30, -29, -5,
- 9, 16, 22, -9, -12, 31, 24, -17, -41, -23, 32, 32, 26, 34, 64, 66,
- 109, 104, 51, 5, 12, 16, -36, -58, -59, -66, -63, -82, -64, -23, -9, 11,
- 16, 20, 19, 13, 12, 33, 37, 41, 46, 28, 7, -58, -93, -79, -64, -33,
- -1, 22, -4, 2, 19, 4, -7, -3, -3, 5, 1, -10, -3, 12, -6, -38,
- -29, -17, -5, 11, 2, -33, -20, 44, 42, 20, -30, -24, 9, 44, 38, 20,
- 36, 71, 61, 86, 72, 25, -8, 10, 17, -35, -54, -63, -67, -70, -78, -58,
- -16, -7, 19, 22, 20, 21, 29, 21, 16, 35, 36, 16, -8, -27, -61, -58,
- -67, -43, 3, 35, 38, -2, -2, 10, -9, -29, -14, -5, -1, -5, 2, 12,
- -6, -32, -23, -22, -16, -5, 3, -9, -29, 27, 56, 39, 11, -27, -28, 23,
- 34, 28, 18, 20, 62, 82, 71, 74, 24, -4, 16, 18, -39, -54, -65, -61,
- -52, -64, -49, -11, -4, 12, 17, 16, 25, 24, 6, 23, 36, 18, 18, -1,
- -42, -50, -90, -43, 3, 35, 38, -2, -2, 10, -9, -29, -14, -5, -1, -5,
- 2, 12, -6, -32, -23, -22, -16, -5, 3, -9, -29, 27, 56, 39, 11, -27,
- -28, 23, 34, 28, 18, 20, 62, 82, 71, 74, 24, -4, 16, 18, -39, -54,
- -65, -61, -52, -64, -49, -11, -4, 12, 17, 16, 25, 24, 6, 23, 36, 18,
- 18, -1, -42, -50, -90, -43, 0, 1, 6, -11, 19, -25, 24, -15, 11, -6,
- 1, 9, -6, -3, 11, -18, 28, -23, 8, 6, -2, -1, 0, -5, 18, -23,
- 24, -28, 27, -12, -1, -2, 6, 4, -14, 19, -29, 42, -40, 22, -6, -3,
- 14, -16, 4, 8, -9, 13, -22, 17, 5, -24, 37, -34, 20, -4, -11, 19,
- -20, 21, -16, 1, 17, -17, 5, -9, 25, -31, 31, -40, 32, -11, -7, 4,
- -4, 13, -23, 29, -40, 51, -49, 20, 3, -20, 38, -47, 34, -21, 14, -9,
- 4, -13, 20, -29, 37, -57, 59, -48, 23, -5, -7, 5, -6, -5, 13, -17,
- 9, -4, -12, 22, -19, -8, 10, -5, -7, 8, -18, 19, -13, 5, -12, 6,
- -10, 18, -40, 66, -91, 82, -56, 17, 19, -51, 56, -45, 30, -19, 5, -6,
- 7, -9, -4, -2, -5, 13, -19, 1, 20, -28, 13, -6, 0, -17, 33, -48,
- 38, -16, -20, 53, -75, 75, -61, 30, -12, -9, 2, 5, -9, -7, 15, -17,
- 9, 4, -46, 70, -85, 86, -67, 29, 18, -60, 76, -70, 29, -8, -1, 1,
- 14, -58, 93, -118, 127, -125, 85, -36, -2, 17, -39, 46, -61, 70, -99, 122,
- -120, 56, 15, -85, 116, -101, 30, 43, -108, 127, -122, 72, -38, -3, 20, -31,
- 29, -37, 42, -50, 63, -72, 40, -7, -46, 66, -82, 53, -25, 1, 1, -1,
- -3, 3, -24, 24, -34, 27, -24, 36, -49, 37, -38, 35, -42, 13, -4, -14,
- 14, -29, 42, -58, 58, -60, 41, -39, 27, -35, 27, -32, 25, -37, 43, -50,
- 32, -20, -4, 4, -14, 16, -43, 66, -93, 79, -58, 27, -11, -21, 34, -40,
- 24, -7, -25, 31, -29, 19, -18, -2, 1, -6, 4, -31, 47, -63, 62, -64,
- 32, 2, -29, 23, -21, 19, -41, 59, -76, 62, -52, 26, -11, -1, -10, 6,
- -10, -7, 17, -42, 34, -12, -34, 73, -106, 92, -61, 26, -24, 8, -7, -2,
- 3, -24, 31, -44, 27, -9, -22, 38, -43, 15, -4, -3, -2, -12, 5, 1,
- -7, 7, -25, 17, -17, 4, -15, 27, -40, 34, -18, 6, -13, 12, -3, -9,
- -6, 8, -18, 18, -36, 54, -55, 30, -25, 26, -41, 38, -49, 48, -38, 8,
- 16, -40, 47, -52, 34, -12, -4, 2, -13, 0, 1, 6, -11, 19, -25, 24,
- -15, 11, -6, 1, 9, -6, -3, 11, -18, 28, -23, 8, 6, -2, -1, 0,
- -5, 18, -23, 24, -28, 27, -12, -1, -2, 6, 4, -14, 19, -29, 42, -40,
- 22, -6, -3, 14, -16, 4, 8, -9, 13, -22, 17, 5, -24, 37, -34, 20,
- -4, -11, 19, -20, 21, -16, 1, 17, -17, 5, -9, 25, -31, 31, -40, 32,
- -11, -7, 4, -4, 13, -23, 29, -40, 51, -49, 20, 3, -20, 38, -47, 34,
- -21, 14, -9, 4, -13, 20, -29, 37, -57, 59, -48, 23, -5, -7, 5, -6,
- -5, 13, -17, 9, -4, -12, 22, -19, -8, 10, -5, -7, 8, -18, 19, -13,
- 5, -12, 6, -10, 18, -40, 66, -91, 82, -56, 17, 19, -51, 56, -45, 30,
- -19, 5, -6, 7, -9, -4, -2, -5, 13, -19, 1, 20, -28, 13, -6, 0,
- -17, 33, -48, 38, -16, -20, 53, -75, 75, -61, 30, -12, -9, 2, 5, -9,
- -7, 15, -17, 9, 4, -46, 70, -85, 86, -67, 29, 18, -60, 76, -70, 29,
- -8, -1, 1, 14, -58, 93, -118, 127, -125, 85, -36, -2, 17, -39, 46, -61,
- 70, -99, 122, -120, 56, 15, -85, 116, -101, 30, 43, -108, 127, -122, 72, -38,
- -3, 20, -31, 29, -37, 42, -50, 63, -72, 40, -7, -46, 66, -82, 53, -25,
- 1, 1, -1, -3, 3, -24, 24, -34, 27, -24, 36, -49, 37, -38, 35, -42,
- 13, -4, -14, 14, -29, 42, -58, 58, -60, 41, -39, 27, -35, 27, -32, 25,
- -37, 43, -50, 32, -20, -4, 4, -14, 16, -43, 66, -93, 79, -58, 27, -11,
- -21, 34, -40, 24, -7, -25, 31, -29, 19, -18, -2, 1, -6, 4, -31, 47,
- -63, 62, -64, 32, 2, -29, 23, -21, 19, -41, 59, -76, 62, -52, 26, -11,
- -1, -10, 6, -10, -7, 17, -42, 34, -12, -34, 73, -106, 92, -61, 26, -24,
- 8, -7, -2, 3, -24, 31, -44, 27, -9, -22, 38, -43, 15, -4, -3, -2,
- -12, 5, 1, -7, 7, -25, 17, -17, 4, -15, 27, -40, 34, -18, 6, -13,
- 12, -3, -9, -6, 8, -18, 18, -36, 54, -55, 30, -25, 26, -41, 38, -49,
- 48, -38, 8, 16, -40, 47, -52, 34, -12, -4, 2, -13, -1, -2, -1, -4,
- -3, -25, -41, 8, 16, 27, 2, 16, 1, 13, 21, -8, -6, -29, 17, 8,
- 8, 20, -13, 5, 4, 25, 17, 30, 22, 14, 15, 19, 7, 51, -16, -15,
- -32, -13, 12, -8, -17, -49, -27, -29, -29, -52, -66, -55, -32, -20, -41, -21,
- -36, -11, -16, 22, 3, 19, 0, -6, -10, 0, -38, -17, -35, -19, -27, 0,
- -35, -27, -9, -17, -14, -2, 20, 50, 63, 57, 49, 70, 70, 97, 81, 68,
- 52, 78, 93, 98, 102, 56, 34, 20, 53, 60, 45, 24, -18, 21, -10, 0,
- -38, -79, -38, -37, -13, -27, -41, -50, -51, 14, 10, 16, -21, -13, -22, -20,
- -48, -53, -55, -66, -76, -65, -91, -105, -92, -87, -101, -79, -56, -34, -7, -4,
- 7, 20, 15, 26, 29, 32, -8, 36, 47, 50, 66, 29, 18, -33, -11, -4,
- -10, -24, -42, -31, -22, 2, -23, -75, -34, -36, 5, 1, 1, -17, -47, 20,
- 43, 68, 28, 30, 9, 29, 7, -9, -5, -32, -46, -36, -15, -40, -35, -15,
- -26, -21, 2, 21, 49, 62, 83, 87, 106, 77, 97, 94, 67, 60, 85, 79,
- 110, 80, 61, 1, 8, 16, 50, 36, 2, -22, 4, -2, 21, -35, -33, -19,
- 4, 24, 19, 10, -58, -23, 18, 45, 34, 8, -12, -6, -5, -48, -51, -75,
- -72, -77, -37, -65, -80, -57, -66, -68, -38, -38, 2, 10, 38, 31, 58, 22,
- 39, 37, 27, -9, 23, 9, 35, 18, 15, -31, -50, -44, -5, 6, -10, -63,
- -41, -56, -15, -41, -71, -45, -37, 7, -6, 5, -56, -71, -6, 21, 41, 8,
- -13, -14, -40, -30, -41, -40, -56, -31, -31, -9, -15, -5, 10, 42, 27, 73,
- 82, 73, 73, 79, 70, 38, 28, 31, 23, 45, 42, 44, 30, -40, 8, 28,
- 52, 30, -18, -29, -40, -14, -45, -50, -55, -68, -39, -6, -29, -45, -59, -32,
- 4, 31, 23, 16, 20, 11, -1, 1, -28, -45, -53, -56, -67, -60, -55, -40,
- -31, -25, -16, 11, 20, 36, 67, 70, 75, 77, 81, 65, 46, 38, 34, 39,
- 51, 44, 57, 7, -4, 13, 37, 46, 19, -8, -29, -1, -9, -21, -32, -43,
- -55, -58, -40, -8, 15, 29, 38, 44, 59, 63, 51, 20, -20, -47, -61, -58,
- -48, -42, -43, -35, -15, 15, 41, 55, 61, 62, 70, 67, 45, 11, -31, -62,
- -80, -78, -71, -62, -54, -39, -15, 18, 50, 68, 79, 83, 92, 88, 57, 16,
- -31, -71, -94, -95, -90, -83, -71, -55, -28, 7, 49, 77, 93, 100, 109, 107,
- 78, 36, -20, -71, -99, -104, -100, -92, -83, -69, -43, -5, 42, 79, 100, 108,
- 114, 112, 90, 51, -9, -65, -100, -110, -105, -95, -87, -76, -52, -11, 35, 75,
- 100, 107, 111, 106, 90, 52, -4, -60, -97, -109, -99, -87, -80, -65, -35, 5,
- 43, 75, 91, 95, 93, 87, 71, 31, -19, -64, -93, -99, -88, -76, -66, -44,
- -9, 28, 59, 79, 84, 80, 71, 59, 35, -5, -45, -76, -96, -95, -77, -59,
- -39, -9, 28, 61, 86, 98, 93, 74, 52, 28, -6, -43, -72, -94, -108, -99,
- -77, -52, -20, 19, 56, 84, 106, 115, 106, 79, 45, 3, -40, -74, -93, -108,
- -112, -100, -79, -46, -1, 45, 78, 100, 113, 118, 108, 81, 39, -19, -67, -93,
- -103, -108, -104, -94, -74, -32, 19, 61, 88, 102, 108, 109, 100, 73, 21, -44,
- -87, -102, -104, -97, -90, -78, -49, 0, 46, 78, 90, 92, 89, 87, 77, 43,
- -15, -72, -101, -104, -93, -79, -69, -47, -3, 47, 84, 96, 89, 74, 65, 58,
- 37, -7, -61, -99, -110, -101, -82, -62, -38, 2, 49, 92, 112, 106, 82, 59,
- 41, 18, -19, -61, -95, -111, -110, -98, -74, -39, 6, 54, 99, 122, 123, 104,
- 79, 50, 12, -32, -72, -100, -111, -110, -106, -90, -54, -4, 49, 99, 123, 126,
- 113, 95, 69, 24, -27, -72, -102, -114, -109, -104, -94, -64, -16, 36, 87, 116,
- 121, 111, 97, 76, 36, -15, -61, -94, -110, -108, -98, -86, -60, -19, 29, 77,
- 104, 109, 99, 86, 67, 35, -7, -47, -82, -98, -101, -92, -77, -48, -14, 25,
- 67, 92, 95, 83, 66, 45, 18, -9, -37, -62, -77, -81, -78, -54, -16, 0,
- 0, 0, 12, -10, 16, -14, -18, 17, -31, -2, 3, -19, -8, 17, 28, 37,
- 31, -1, -25, -16, -47, -13, -43, -22, 6, 34, 41, 49, 41, 27, 6, -33,
- -62, -54, -59, -32, -13, 29, 53, 73, 60, 54, 16, -19, -58, -77, -89, -42,
- -46, 17, 55, 78, 86, 81, 33, -3, -35, -84, -110, -75, -70, 0, 39, 78,
- 92, 105, 70, 13, -15, -82, -107, -103, -84, -41, 20, 81, 85, 127, 86, 39,
- -4, -63, -103, -99, -107, -69, 2, 68, 82, 127, 84, 58, 28, -44, -88, -104,
- -108, -83, -13, 29, 69, 116, 87, 77, 40, -16, -65, -89, -104, -89, -40, -1,
- 47, 96, 90, 85, 52, 9, -38, -62, -96, -95, -62, -22, 21, 73, 78, 86,
- 65, 35, -15, -41, -80, -92, -69, -48, 1, 43, 65, 80, 73, 49, 8, -23,
- -59, -75, -74, -60, -22, 17, 49, 69, 65, 60, 25, -1, -36, -59, -70, -61,
- -40, -9, 30, 52, 57, 63, 37, 17, -12, -41, -61, -57, -50, -30, 9, 30,
- 49, 60, 47, 28, 6, -20, -49, -51, -53, -42, -11, 13, 34, 53, 50, 34,
- 18, -3, -35, -39, -52, -49, -23, 0, 18, 41, 47, 36, 31, 10, -21, -28,
- -43, -49, -31, -13, 2, 28, 39, 35, 38, 19, -7, -18, -33, -42, -36, -26,
- -12, 19, 30, 34, 36, 22, 6, -5, -25, -38, -36, -29, -17, 8, 19, 26,
- 35, 28, 12, 3, -17, -30, -29, -29, -22, -3, 9, 19, 33, 26, 14, 8,
- -9, -18, -22, -28, -25, -9, 3, 15, 22, 20, 18, 12, 1, -11, -22, -24,
- -21, -13, -3, 8, 11, 20, 21, 12, 5, -6, -19, -16, -17, -17, -7, 3,
- 8, 20, 17, 7, 7, -2, -11, -13, -16, -17, -5, 2, 5, 12, 13, 8,
- 6, 3, -9, -11, -9, -14, -5, 1, -3, 6, 11, 6, 7, 2, -6, -4,
- -4, -10, -6, -3, -4, 5, 8, 2, 5, 4, -2, 0, -3, -9, -4, -3,
- -3, 2, 3, 0, 6, 4, 0, -1, -2, -2, 0, 0, 0, 12, -10, 16,
- -14, -18, 17, -31, -2, 3, -19, -8, 17, 28, 37, 31, -1, -25, -16, -47,
- -13, -43, -22, 6, 34, 41, 49, 41, 27, 6, -33, -62, -54, -59, -32, -13,
- 29, 53, 73, 60, 54, 16, -19, -58, -77, -89, -42, -46, 17, 55, 78, 86,
- 81, 33, -3, -35, -84, -110, -75, -70, 0, 39, 78, 92, 105, 70, 13, -15,
- -82, -107, -103, -84, -41, 20, 81, 85, 127, 86, 39, -4, -63, -103, -99, -107,
- -69, 2, 68, 82, 127, 84, 58, 28, -44, -88, -104, -108, -83, -13, 29, 69,
- 116, 87, 77, 40, -16, -65, -89, -104, -89, -40, -1, 47, 96, 90, 85, 52,
- 9, -38, -62, -96, -95, -62, -22, 21, 73, 78, 86, 65, 35, -15, -41, -80,
- -92, -69, -48, 1, 43, 65, 80, 73, 49, 8, -23, -59, -75, -74, -60, -22,
- 17, 49, 69, 65, 60, 25, -1, -36, -59, -70, -61, -40, -9, 30, 52, 57,
- 63, 37, 17, -12, -41, -61, -57, -50, -30, 9, 30, 49, 60, 47, 28, 6,
- -20, -49, -51, -53, -42, -11, 13, 34, 53, 50, 34, 18, -3, -35, -39, -52,
- -49, -23, 0, 18, 41, 47, 36, 31, 10, -21, -28, -43, -49, -31, -13, 2,
- 28, 39, 35, 38, 19, -7, -18, -33, -42, -36, -26, -12, 19, 30, 34, 36,
- 22, 6, -5, -25, -38, -36, -29, -17, 8, 19, 26, 35, 28, 12, 3, -17,
- -30, -29, -29, -22, -3, 9, 19, 33, 26, 14, 8, -9, -18, -22, -28, -25,
- -9, 3, 15, 22, 20, 18, 12, 1, -11, -22, -24, -21, -13, -3, 8, 11,
- 20, 21, 12, 5, -6, -19, -16, -17, -17, -7, 3, 8, 20, 17, 7, 7,
- -2, -11, -13, -16, -17, -5, 2, 5, 12, 13, 8, 6, 3, -9, -11, -9,
- -14, -5, 1, -3, 6, 11, 6, 7, 2, -6, -4, -4, -10, -6, -3, -4,
- 5, 8, 2, 5, 4, -2, 0, -3, -9, -4, -3, -3, 2, 3, 0, 6,
- 4, 0, -1, -2, -2, 0, -1, -1, -3, -7, -14, -23, -32, -45, -55, -66,
- -74, -83, -88, -80, -77, -71, -64, -54, -46, -37, -31, -25, -19, -12, -6, -1,
- 4, 8, 12, 17, 21, 23, 25, 25, 27, 29, 32, 35, 36, 34, 32, 31,
- 32, 35, 37, 37, 35, 31, 29, 29, 31, 33, 34, 32, 29, 26, 25, 27,
- 30, 32, 31, 29, 27, 27, 29, 31, 34, 35, 35, 35, 36, 38, 41, 43,
- 45, 47, 49, 52, 55, 57, 59, 61, 63, 66, 69, 70, 70, 68, 66, 63,
- 61, 58, 54, 47, 36, 24, 11, 1, -9, -20, -33, -48, -64, -78, -89, -97,
- -103, -110, -116, -123, -128, -128, -126, -121, -116, -112, -107, -102, -95, -88, -78, -69,
- -61, -54, -47, -41, -34, -27, -21, -16, -12, -7, -2, 2, 5, 6, 8, 10,
- 13, 16, 19, 19, 19, 17, 18, 19, 22, 24, 24, 22, 19, 18, 19, 21,
- 23, 24, 22, 19, 17, 18, 20, 22, 24, 24, 22, 21, 22, 24, 27, 29,
- 30, 30, 31, 32, 35, 37, 40, 42, 45, 47, 50, 53, 56, 58, 60, 62,
- 66, 68, 70, 69, 68, 65, 63, 61, 59, 54, 46, 36, 24, 13, -1, -14,
- -28, -43, -57, -68, -78, -86, -94, -102, -109, -114, -117, -117, -115, -112, -109, -106,
- -101, -96, -89, -81, -73, -67, -59, -53, -46, -40, -34, -28, -23, -18, -13, -9,
- -5, -2, 0, 2, 5, 7, 10, 12, 14, 15, 15, 15, 16, 18, 19, 20,
- 20, 19, 18, 18, 19, 21, 22, 22, 21, 20, 19, 21, 23, 24, 25, 25,
- 25, 25, 26, 29, 31, 33, 34, 35, 36, 38, 40, 43, 46, 48, 51, 53,
- 56, 59, 62, 65, 68, 71, 74, 77, 78, 79, 78, 77, 76, 74, 71, 66,
- 58, 49, 39, 28, 17, 6, -6, -20, -35, -50, -64, -75, -85, -94, -102, -110,
- -117, -122, -124, -123, -121, -118, -114, -110, -106, -99, -92, -84, -76, -69, -61, -55,
- -48, -41, -34, -29, -23, -18, -13, -9, -5, -2, 0, -1, -1, 0, 2, 0,
- 3, 2, 2, 4, 5, 4, 4, 4, 4, 5, 3, 4, 3, 1, 2, 0,
- 0, -1, -3, -4, -2, -3, -5, -3, -4, -5, -5, -4, -3, -3, -6, -5,
- -4, -2, -5, -5, -2, -3, -3, -3, 1, 4, 4, 8, 8, 8, 13, 12,
- 13, 14, 12, 9, 8, 6, 6, 3, -2, -2, -5, -5, -4, -5, -11, -16,
- -12, -7, -3, -5, -10, -11, -6, -2, -2, -1, -4, -6, -6, -7, -8, -5,
- -2, 2, 5, 6, 8, 8, 9, 13, 16, 16, 14, 11, 7, 5, 4, 2,
- 0, -2, -3, -3, 0, -3, -13, -28, -11, 7, -1, -15, -1, -5, -18, -10,
- 6, 11, -11, -1, -10, -14, -13, -13, -4, 4, 6, 14, 13, 10, 10, 15,
- 17, 24, 24, 13, 12, 10, 1, 0, 2, -4, 0, -6, 2, 7, -22, -68,
- 2, 35, -40, 14, -24, -3, -10, -9, -20, -3, 28, 2, -9, -12, -28, -19,
- -4, -1, 15, 17, 17, 16, 12, 16, 22, 25, 28, 6, 17, 9, -1, -2,
- -3, 2, 12, -6, 6, -5, -35, -89, 32, 28, -39, 20, -36, 9, -20, -9,
- -34, 3, 34, 8, -16, -11, -37, -15, -3, 0, 26, 18, 13, 15, 13, 25,
- 27, 29, 20, 3, 21, 2, -2, 0, -8, 11, 16, -1, 8, -21, -76, -81,
- 87, -25, 4, -4, -23, 6, -26, -20, -35, 23, 28, 0, -18, -16, -43, 2,
- -9, 17, 25, 15, 9, 18, 17, 37, 28, 35, 3, 14, 12, -5, -1, -1,
- -5, 27, 0, 16, -11, -49, -128, 36, 40, -36, 35, -41, 21, -27, -14, -45,
- 4, 24, 20, -23, -6, -41, -9, -1, 6, 23, 19, 5, 15, 14, 33, 35,
- 40, 16, 5, 16, -3, -5, 4, -12, 24, 10, 18, 1, -38, -128, -21, 72,
- -50, 42, -38, 19, -16, -16, -43, -10, 21, 24, -22, -11, -30, -15, 6, 4,
- 22, 18, 6, 11, 13, 27, 39, 42, 22, 4, -3, -2, -2, -5, -3, -5,
- -3, -2, -6, -5, -5, -6, -5, -3, -5, -3, -5, -4, -6, -3, -1, -2,
- -1, 0, -2, 1, 2, 1, 4, 4, 5, 5, 5, 8, 10, 11, 9, 10,
- 11, 8, 5, 10, 7, 5, 5, 0, -3, 1, 0, -5, -2, -8, -9, -7,
- -7, -5, -9, -11, -9, -8, -8, -7, -9, -7, -6, -7, -5, -6, -5, -3,
- -3, -3, -4, -4, -2, 0, 1, 2, 5, 9, 12, 16, 19, 22, 22, 24,
- 22, 22, 19, 13, 11, 7, 7, 4, -2, -7, -9, -9, -8, -10, -14, -14,
- -15, -15, -13, -14, -17, -18, -14, -12, -12, -8, -9, -7, -6, -6, -6, -8,
- -9, -9, -11, -13, -11, -6, -1, 3, 9, 20, 27, 33, 37, 46, 46, 42,
- 37, 28, 21, 14, 11, 10, 14, 20, -2, -40, -47, -22, -5, -4, -1, 4,
- -15, -53, -56, -7, -33, -14, -2, -19, -7, -8, -15, -6, -9, -8, -3, -9,
- -15, -18, -26, -19, -6, -5, -6, 0, 12, 22, 29, 30, 28, 32, 29, 21,
- 15, 13, 5, 5, 3, 19, 30, 3, -68, -26, 2, -17, 17, -12, 15, -1,
- -12, -48, -43, -19, -1, 3, 6, -8, -4, -10, -10, -4, 0, -6, -1, -7,
- -9, -17, -12, -6, -9, -14, -5, 14, 33, 33, 41, 32, 41, 35, 20, 10,
- 8, 4, 10, -2, 36, 40, 3, -110, -8, -7, -6, 16, -18, 27, -2, -4,
- -56, -57, -33, 16, -2, 12, -11, -5, -17, -9, -5, 10, -6, 0, -12, -11,
- -20, -10, -8, -12, -17, -3, 17, 38, 34, 45, 36, 51, 37, 18, 4, -3,
- 3, 8, 8, 54, 48, -34, -128, 28, -33, 28, -13, 1, 21, 3, -20, -59,
- -65, -10, 17, -1, 7, -17, -10, -19, -8, 5, 11, -4, -2, -16, -17, -20,
- -9, -11, -18, -11, 3, 31, 36, 41, 41, 44, 53, 30, 10, 1, -13, 12,
- -5, 42, 63, 43, -127, -55, 19, -27, 28, -1, 0, 3, 5, 8, 12, 14,
- 15, 15, 14, 12, 8, 5, 1, -3, -9, -14, -17, -19, -18, -16, -12, -8,
- -5, -4, -2, -1, -1, -2, -3, -4, -3, -2, -1, -1, 0, 0, 0, 2,
- 8, 12, 16, 19, 23, 26, 34, 40, 39, 28, 11, -8, -26, -36, -40, -39,
- -35, -27, -19, -10, -5, -6, -10, -12, -15, -14, -12, -9, -5, -3, -1, 1,
- 6, 8, 7, 7, 7, 8, 13, 20, 28, 35, 43, 48, 55, 57, 51, 32,
- 3, -29, -56, -68, -67, -60, -46, -31, -17, -7, -4, -7, -11, -15, -16, -15,
- -10, -5, -1, 1, 3, 5, 7, 9, 11, 12, 12, 10, 13, 19, 26, 36,
- 43, 51, 58, 65, 61, 40, 6, -30, -60, -75, -73, -64, -49, -32, -16, -5,
- -1, -4, -11, -18, -23, -23, -19, -12, -5, 2, 8, 12, 13, 11, 9, 8,
- 8, 10, 15, 21, 27, 32, 37, 42, 49, 55, 63, 55, 32, -3, -39, -66,
- -79, -73, -56, -39, -24, -12, -7, -7, -12, -19, -24, -24, -21, -14, -6, 3,
- 8, 11, 12, 11, 10, 10, 10, 11, 14, 17, 21, 27, 33, 41, 49, 56,
- 63, 66, 49, 15, -27, -61, -82, -85, -73, -52, -33, -18, -9, -5, -7, -12,
- -18, -21, -20, -15, -9, -1, 4, 8, 12, 15, 15, 14, 11, 8, 7, 10,
- 15, 22, 32, 45, 59, 72, 86, 95, 75, 22, -40, -93, -119, -120, -97, -64,
- -32, -9, 5, 9, 5, -3, -14, -21, -23, -20, -13, -5, 4, 12, 17, 18,
- 15, 10, 7, 4, 3, 6, 9, 15, 21, 30, 40, 56, 77, 99, 99, 54,
- -19, -86, -123, -127, -103, -66, -27, 1, 16, 18, 11, -1, -12, -21, -23, -21,
- -16, -8, 1, 9, 16, 19, 16, 11, 8, 5, 5, 7, 9, 14, 19, 27,
- 35, 49, 68, 90, 101, 73, 6, -66, -114, -128, -113, -78, -39, -6, 13, 19,
- 11, -1, 0, 10, 30, 35, 40, 39, 37, 28, 18, 6, -9, -20, -30, -35,
- -33, -30, -28, -23, -24, -23, -19, -20, -15, -11, -8, -3, 0, 1, 0, -2,
- -4, -1, 0, 10, 15, 21, 27, 25, 25, 22, 13, 10, -5, -9, -15, -19,
- -17, -17, -12, -7, 0, 4, 10, 8, 5, -5, -13, -23, -31, -30, -24, -13,
- 11, 36, 62, 81, 83, 78, 54, 35, 19, -11, -29, -49, -57, -47, -35, -20,
- -19, -26, -27, -33, -30, -26, -22, -11, -8, 3, 11, 6, 0, -16, -23, -23,
- -11, 9, 23, 35, 45, 51, 46, 49, 26, 12, -13, -26, -37, -45, -31, -35,
- -17, -4, 8, 23, 24, 23, 9, -10, -22, -37, -40, -38, -33, -12, 22, 67,
- 100, 119, 111, 79, 50, 10, -12, -32, -52, -69, -62, -38, -14, -9, -21, -42,
- -60, -50, -39, -19, -4, -1, 3, 15, 19, 2, -16, -43, -57, -48, -21, 19,
- 38, 63, 66, 69, 74, 59, 39, 4, -33, -52, -67, -58, -39, -25, 2, 10,
- 32, 35, 36, 18, -7, -25, -37, -31, -28, -23, -10, 11, 53, 101, 121, 123,
- 92, 48, 11, -24, -42, -60, -66, -67, -48, -20, 2, -16, -41, -67, -87, -62,
- -44, -10, 8, 19, 30, 34, 35, 4, -36, -66, -78, -75, -27, 22, 49, 83,
- 91, 97, 90, 69, 39, -18, -61, -104, -98, -75, -32, 19, 47, 68, 70, 56,
- 16, -33, -77, -89, -76, -47, 7, 35, 64, 100, 123, 125, 107, 60, 5, -39,
- -76, -94, -101, -93, -69, -36, -3, 17, 10, -15, -56, -80, -86, -69, -40, -7,
- 25, 49, 66, 72, 54, 19, -19, -55, -77, -67, -40, 4, 45, 76, 96, 100,
- 92, 67, 32, -11, -56, -88, -91, -73, -33, 9, 41, 61, 65, 52, 17, -28,
- -67, -80, -68, -36, 6, 47, 82, 114, 126, 114, 74, 18, -32, -73, -93, -101,
- -93, -70, -36, -3, 17, 10, -15, 0, -1, -2, -2, 0, 2, 3, 6, 7,
- 6, 6, 3, 2, -1, -4, -8, -12, -14, -13, -13, -11, -5, -1, 5, 10,
- 14, 17, 19, 18, 15, 12, 7, 3, 1, -2, -4, -4, -7, -11, -13, -16,
- -16, -12, -9, -6, -3, -1, -1, -1, -4, -8, -11, -15, -16, -15, -10, -2,
- 7, 18, 25, 28, 28, 24, 16, 10, 4, -2, -5, -5, -4, -4, -1, 0,
- 0, 1, 1, 0, -1, -3, -6, -11, -11, -14, -16, -17, -19, -19, -16, -10,
- -2, 8, 19, 27, 33, 35, 32, 26, 21, 14, 7, 0, -6, -11, -18, -25,
- -31, -32, -27, -19, -9, 1, 10, 15, 14, 10, 0, -13, -28, -38, -42, -40,
- -26, -4, 17, 40, 58, 66, 62, 51, 35, 17, 3, -8, -16, -18, -18, -15,
- -13, -15, -17, -17, -15, -13, -11, -12, -3, -2, 1, -3, -15, -28, -36, -42,
- -40, -28, -11, 14, 45, 63, 70, 69, 56, 44, 36, 21, 3, -12, -18, -26,
- -37, -47, -58, -55, -41, -20, 4, 22, 34, 43, 37, 22, -7, -43, -71, -88,
- -86, -64, -31, 7, 56, 99, 115, 106, 85, 48, 17, 1, -14, -28, -33, -20,
- -11, -12, -18, -37, -44, -41, -29, -23, -7, 15, 31, 40, 33, 8, -27, -56,
- -73, -74, -63, -33, 4, 50, 93, 101, 91, 79, 56, 43, 24, 5, -17, -32,
- -31, -43, -56, -63, -72, -57, -32, 3, 26, 46, 62, 63, 45, 9, -39, -85,
- -112, -106, -84, -49, 6, 60, 104, 127, 115, 83, 46, 16, -1, -16, -21, -26,
- -16, -2, -8, -25, -47, -67, -62, -49, -26, 2, 34, 60, 74, 65, 33, -21,
- -71, -98, -92, -77, -36, 21, 69, 106, 112, 88, 58, 29, 9, -8, -18, -24,
- -17, -4, -10, -26, -47, -67, -62, -49, -26, 2, 34, 60, 74, 65, 33, 17,
- 16, -38, 9, 40, -58, 27, 43, -80, 52, -2, -54, 64, -27, -17, 32, 4,
- -49, 53, -22, -47, 90, -73, 17, 42, -45, 8, 23, -41, -1, 58, -74, 40,
- 25, -66, 56, -19, -45, 58, -9, -39, 45, 3, -48, 55, -41, -27, 78, -66,
- 13, 40, -38, 0, 29, -51, 12, 57, -79, 38, 31, -64, 40, -4, -47, 63,
- -16, -40, 55, -16, -32, 45, -31, -29, 76, -64, 0, 58, -49, 4, 31, -52,
- 31, 5, -35, 45, -21, 4, -5, 3, -17, -7, 55, -72, 43, 35, -88, 80,
- -57, 3, 45, -62, 53, -14, -2, -17, 46, -77, 42, 23, -61, 75, -54, 39,
- -40, 31, -42, 25, 11, -48, 93, -97, 62, -27, -13, 7, 0, 30, -59, 82,
- -74, 28, 10, -53, 65, -47, 46, -41, 40, -48, 7, 45, -95, 127, -99, 43,
- -9, -25, 40, -58, 84, -84, 78, -66, 11, 50, -96, 111, -85, 51, -26, -14,
- 36, -60, 91, -84, 58, -26, -22, 56, -87, 98, -71, 47, -25, -11, 44, -84,
- 103, -92, 69, -32, -3, 25, -59, 87, -90, 70, -45, 17, 16, -57, 81, -73,
- 50, -33, 14, 0, -35, 75, -84, 69, -42, 8, 11, -46, 74, -69, 57, -47,
- 36, -26, -20, 69, -89, 83, -58, 37, -24, -7, 41, -58, 54, -53, 53, -42,
- 14, 28, -54, 52, -55, 46, -41, 22, 30, -57, 58, -64, 56, -54, 26, 31,
- -55, 63, -73, 66, -68, 49, -3, -38, 61, -71, 75, -87, 69, -15, -27, 37,
- -55, 74, -84, 73, -34, -5, 26, -59, 74, -85, 84, -33, -12, 30, -57, 65,
- -85, 86, -40, 9, 15, -50, 69, -94, 93, -53, 15, 11, -38, 58, -86, 96,
- -64, 11, 21, -30, 17, -3, -3, 0, 0, -3, -4, -4, -3, -4, -4, -5,
- -6, -6, -8, -5, -6, -3, 0, 2, 4, 7, 8, 12, 12, 14, 13, 13,
- 12, 8, 7, 2, 2, -4, -6, -10, -11, -12, -12, -14, -10, -9, -3, -3,
- 2, 3, 3, 2, 1, 1, -3, -3, -4, -3, -3, -3, -4, 0, -3, -3,
- -3, 0, -3, 0, -3, 0, 1, 0, 0, 0, 0, 0, -3, 1, -3, 1,
- -3, 2, 1, 0, 0, -3, -4, -5, -9, -10, -15, -16, -17, -17, -14, -10,
- -3, 4, 9, 14, 19, 24, 25, 26, 28, 30, 34, 42, 31, 9, -31, -39,
- -23, -15, -17, -23, -30, -23, -12, -10, 4, 9, 19, 13, 14, 6, 0, -9,
- -11, -12, -9, -8, 0, 0, 2, 1, 1, -3, -3, -5, -3, -5, -3, -4,
- 0, -3, -4, -4, -3, -5, -3, -5, -3, 0, 3, 2, 7, 7, 7, 3,
- 0, -14, -17, -26, -26, -28, -21, -17, -11, -10, 2, 6, 19, 18, 32, 32,
- 60, 69, 98, 60, 7, -58, -8, -8, -14, -39, -30, -14, -47, -21, -45, -3,
- 7, 20, 14, 31, 12, 10, -15, -5, -23, -14, -15, -4, -8, 2, 1, 7,
- -3, 2, -8, -4, -6, -6, -3, 0, -6, -6, -8, -10, -11, -12, -9, -9,
- -4, -3, 0, 8, 10, 12, 15, 13, 4, -10, -15, -30, -32, -30, -23, -22,
- -19, -14, -4, 3, 10, 14, 26, 40, 70, 102, 127, 62, -17, -39, 9, -25,
- -9, -87, -12, -16, 0, -30, -27, -19, -9, 6, 18, 21, 19, 6, 0, -9,
- -17, -14, -16, -8, -6, 0, 4, 4, -5, -4, -11, -3, -6, 2, 2, 0,
- -6, 0, -2, -4, -8, -14, -21, -25, -28, -32, -36, -40, -44, -48, -51, -55,
- -59, -63, -67, -71, -74, -78, -82, -86, -90, -94, -98, -101, -84, -60, -38, -15,
- 8, 28, 27, 23, 19, 16, 11, 21, 46, 68, 93, 109, 106, 102, 98, 95,
- 91, 87, 83, 79, 75, 71, 67, 64, 60, 56, 52, 49, 45, 41, 37, 33,
- 30, 26, 22, 18, 15, 11, 7, 3, -1, -5, -9, -13, -17, -20, -24, -28,
- -32, -35, -39, -43, -47, -51, -54, -58, -62, -66, -69, -73, -77, -81, -85, -89,
- -93, -97, -100, -105, -95, -70, -48, -23, -7, -10, -14, -17, -22, -18, 4, 26,
- 50, 72, 96, 107, 103, 100, 96, 92, 88, 84, 80, 76, 72, 68, 64, 61,
- 57, 53, 49, 46, 42, 38, 34, 30, 26, 23, 19, 15, 11, 8, 4, 0,
- -4, -8, -11, -15, -19, -23, -27, -30, -35, -38, -43, -46, -51, -54, -58, -61,
- -66, -56, -31, -9, 16, 33, 30, 26, 22, 18, 15, 11, 7, 3, -1, -5,
- -9, -13, -16, -20, -24, -28, -32, -36, -40, -43, -48, -51, -55, -59, -63, -50,
- -26, -4, 20, 42, 64, 67, 62, 59, 55, 51, 47, 43, 39, 35, 31, 27,
- 23, 20, 16, 12, 8, 4, 0, -4, -7, -11, -15, -19, -22, -27, -17, 8,
- 30, 55, 72, 69, 65, 61, 57, 54, 50, 46, 42, 38, 34, 30, 26, 22,
- 18, 15, 11, 7, 3, 0, -4, -8, -12, -15, -19, -23, -27, -31, -35, -38,
- -42, -46, -50, -54, -57, -61, -65, -69, -73, -77, -81, -85, -89, -92, -96, -100,
- -100, -79, -64, -47, -31, -15, 0, 0, -4, -3, -6, -8, 6, 10, -8, -13,
- 22, 55, 15, -58, -102, -88, -25, 51, 77, 79, 82, 19, -45, -107, -128, -88,
- 19, 81, 86, 71, 35, -16, -50, -73, -55, -27, -14, 7, 77, 89, 31, -22,
- -27, -61, -86, -34, 40, 55, 67, 80, 57, -1, -48, -60, -41, -46, -31, 28,
- 62, 47, 43, 33, -5, -34, -45, -52, -33, 26, 66, 70, 41, 17, -34, -79,
- -93, -41, -6, 22, 53, 93, 62, 17, -20, -66, -118, -88, -4, 45, 60, 69,
- 67, 2, -72, -109, -95, -78, -7, 67, 101, 78, 69, 19, -56, -110, -89, -64,
- -19, 45, 100, 86, 36, -11, -65, -107, -108, -41, 24, 69, 93, 111, 56, -15,
- -70, -81, -88, -38, 30, 88, 90, 83, 43, -24, -81, -82, -57, -24, 38, 100,
- 115, 70, 26, -25, -75, -108, -66, -20, 29, 71, 105, 67, 7, -46, -67, -83,
- -60, 0, 58, 82, 81, 57, -9, -72, -99, -78, -60, -8, 54, 95, 69, 44,
- 0, -51, -92, -69, -26, 18, 53, 81, 63, 6, -44, -74, -88, -79, -19, 40,
- 75, 75, 72, 18, -42, -80, -74, -69, -25, 32, 76, 66, 39, 5, -41, -82,
- -76, -34, 3, 42, 79, 88, 38, -12, -49, -74, -92, -48, 8, 51, 70, 83,
- 50, -7, -58, -68, -65, -43, 13, 70, 82, 62, 34, -17, -72, -94, -65, -28,
- 17, 69, 101, 71, 25, -21, -60, -88, -66, -13, 37, 62, 82, 68, 11, -47,
- -73, -79, -66, -15, 49, 82, 76, 57, 11, -51, -88, -78, -48, -9, 49, 0,
- 0, 0, 0, 0, 0, -3, -5, -5, -7, -6, -2, 5, 16, 24, 21, 17,
- 12, 3, -10, -31, -44, -47, -42, -28, -2, 26, 29, 36, 35, 1, -26, -39,
- -52, -53, -38, -10, -32, -41, -7, 2, 22, 65, 89, 74, 15, -16, -24, 12,
- 62, 39, 6, -12, -3, 47, 48, 21, 109, 127, 119, 53, -9, 19, 9, -50,
- -55, -43, -71, -46, -5, -2, -20, -12, -9, 12, -27, -66, -50, -8, -19, -58,
- -22, -8, -19, -34, -42, 10, 32, -4, 4, 46, 96, 34, -51, -10, -8, -93,
- -70, -58, -46, -16, -32, -30, 6, 7, -41, -29, 3, 25, 73, 67, 45, 37,
- 30, 83, 0, -31, -4, -50, -28, -41, -75, -110, -53, -13, -3, 22, 14, 14,
- 13, 7, 9, 38, 47, 39, 17, -8, 90, 75, -5, -29, -46, -54, -102, -66,
- -35, -27, -29, -21, 32, 5, 1, 1, -2, 16, 16, 19, 30, 50, 89, 41,
- 6, 40, -10, -15, -41, -46, -43, -77, -100, -100, -48, -37, -26, -4, -9, 0,
- 13, 36, 70, 75, 59, 34, 12, -13, -27, 37, 71, 48, 53, 37, 7, 8,
- 34, 48, 40, 31, 25, 2, -20, -15, -5, 12, -11, -49, -20, 15, -13, -42,
- -29, 16, -6, -58, -28, 17, 12, -20, -11, 16, -3, -37, -14, 3, -32, -10,
- 40, 54, 53, 27, -3, -5, -34, -47, -49, -90, -68, -36, -32, -31, -16, 26,
- 3, 0, -2, -2, 15, 16, 19, 30, 51, 88, 40, 6, 39, -10, 3, -2,
- 11, -7, 23, 19, 74, 39, 32, -13, -21, -7, -39, -44, -128, -58, -21, 52,
- -86, -74, -94, 75, 61, 72, -38, 13, 59, 116, 71, -9, -33, -12, 68, -2,
- -35, -128, -42, -43, 39, -78, -57, -81, 56, 59, 63, -13, 7, 69, 98, 87,
- -13, -9, -24, 70, -11, -23, -128, -42, -48, 28, -68, -61, -69, 34, 64, 46,
- 8, -5, 79, 82, 100, -17, 5, -29, 69, -13, -21, -122, -49, -43, 11, -55,
- -72, -54, 13, 73, 30, 23, -16, 87, 72, 107, -17, 10, -26, 64, -6, -26,
- -109, -61, -31, -6, -40, -86, -41, -4, 80, 17, 31, -22, 88, 70, 106, -10,
- 6, -16, 53, 7, -37, -93, -76, -17, -21, -28, -99, -33, -15, 83, 12, 31,
- -21, 83, 76, 98, 2, -4, -1, 41, 24, -49, -77, -89, -6, -31, -20, -106,
- -32, -19, 79, 14, 23, -15, 71, 87, 87, 17, -16, 13, 30, 39, -57, -67,
- -97, -1, -34, -19, -106, -38, -16, 69, 23, 11, -5, 56, 100, 75, 32, -28,
- 25, 22, 50, -59, -62, -98, -2, -30, -24, -100, -52, -9, 55, 36, -4, 5,
- 41, 112, 67, 43, -34, 30, 21, 55, -53, -65, -93, -11, -18, -34, -88, -69,
- 0, 41, 48, -17, 12, 29, 118, 65, 49, -34, 28, 27, 53, -42, -72, -83,
- -23, -6, -44, -77, -85, 5, -69, 1, -12, -29, -28, -13, 1, 9, -4, -27,
- -18, -5, 11, 65, 87, 54, 59, 66, 30, 12, 8, -6, -7, 4, -7, -39,
- -59, -63, -48, -23, -13, -6, 22, 61, 68, 15, -59, -87, -41, 3, 5, -10,
- -17, -17, -20, -23, -20, -28, -17, -3, -10, -29, 23, 11, 25, 52, 56, 62,
- 80, 54, 22, -15, -31, -38, -5, 11, -9, -7, -36, -44, -6, 52, 127, 26,
- -68, -125, -105, 22, 15, -27, -27, 13, 25, 69, 28, -42, -77, -57, -70, 15,
- 44, 14, 26, 57, 69, 43, 33, 41, 33, 32, 25, -50, -98, -100, -38, 24,
- 7, -35, -38, -2, 76, 64, 15, -79, -93, -50, -12, 27, 45, 32, -4, 23,
- 6, -36, -47, -33, -52, -15, 37, 78, 49, 40, 17, 14, 14, 70, 81, 60,
- -3, -4, -12, -42, -50, -28, -20, 5, 9, 27, 46, -13, -69, -99, -88, -47,
- 5, -4, -10, 17, 39, -12, -8, -21, -16, 22, 9, -9, 1, 15, 15, 33,
- 29, 17, 11, 38, 72, 29, -8, -36, -27, -42, 17, -40, 25, 25, 8, -3,
- 14, 15, 2, 43, 33, -2, -19, -24, -8, 2, -69, -114, -94, -77, -87, 22,
- 27, 19, 24, 57, 121, 94, 40, -27, -29, 4, 28, -12, 5, -21, -28, -18,
- 0, -9, 1, 36, 22, 7, 6, 12, 7, 8, 55, 6, -2, -7, -13, -12,
- -12, -8, -5, -5, -1, -4, -4, -3, -1, 5, 11, 15, 18, 16, 11, 5,
- -5, -12, -16, -17, -14, -10, -7, -3, -2, -3, -3, -5, -3, 2, 9, 18,
- 22, 23, 18, 11, -2, -14, -20, -22, -18, -12, -8, -5, -3, -5, -6, -6,
- -5, 1, 11, 22, 30, 31, 24, 15, -1, -12, -20, -23, -19, -13, -8, -3,
- -3, -2, -6, -8, -9, -5, 6, 21, 32, 35, 29, 19, 1, -15, -27, -29,
- -25, -15, -9, -4, -1, -2, -7, -14, -15, -10, 4, 24, 42, 48, 43, 26,
- 4, -20, -36, -38, -30, -17, -7, -3, 0, -1, -4, -16, -24, -19, -3, 26,
- 49, 61, 60, 40, 9, -23, -45, -52, -39, -22, -5, -2, 1, 3, -2, -18,
- -32, -30, -10, 22, 55, 77, 78, 52, 15, -22, -51, -66, -52, -29, -5, 0,
- 2, 9, 6, -15, -37, -42, -22, 10, 55, 89, 99, 71, 22, -20, -58, -79,
- -68, -35, -8, 6, 1, 12, 13, -9, -37, -50, -35, 0, 46, 93, 116, 90,
- 33, -15, -60, -89, -84, -44, -9, 10, 3, 13, 19, -3, -35, -53, -43, -12,
- 34, 91, 127, 109, 46, -9, -57, -95, -96, -57, -13, 11, 7, 10, 25, 2,
- -2, -35, 0, 2, 7, 12, -7, -79, -68, 2, -6, -5, 19, 40, 33, 55,
- 56, 17, 32, 32, 2, -20, 5, 51, 27, -21, -13, -11, -17, -20, -6, -63,
- -125, -116, -86, -59, -34, 11, 23, 20, 39, 66, 50, 47, 54, 46, 11, -4,
- 44, 67, 30, 11, 16, 6, -2, 7, -4, -77, -114, -107, -70, -50, -20, 29,
- 26, 12, 48, 69, 44, 47, 49, 28, -8, 9, 53, 49, 15, 9, 8, -3,
- -11, 7, -33, -107, -123, -101, -62, -49, -5, 25, 6, 13, 55, 49, 32, 40,
- 39, 7, -17, 18, 49, 32, 7, 8, 1, -12, -3, 7, -62, -113, -109, -74,
- -50, -31, 23, 32, 13, 40, 69, 48, 46, 54, 42, 2, 1, 42, 52, 25,
- 10, 11, 0, -11, 10, -10, -90, -115, -101, -64, -52, -15, 29, 16, 10, 51,
- 59, 41, 46, 49, 25, -9, 15, 48, 42, 15, 10, 7, -9, -7, 16, -43,
- -107, -113, -89, -60, -47, 4, 27, 4, 19, 58, 47, 38, 46, 43, 6, -9,
- 28, 47, 29, 10, 11, 2, -14, 5, 5, -73, -111, -106, -73, -56, -29, 24,
- 22, 6, 40, 61, 43, 43, 52, 37, -3, 6, 41, 47, 23, 12, 11, 0,
- -14, 1, 3, 5, 5, 6, 8, 6, 4, 0, -4, -5, -6, -9, -9, -11,
- -11, -12, -13, -13, -13, -12, -11, -9, -5, -2, -1, 1, 4, 6, 9, 11,
- 12, 12, 11, 8, 5, 2, -2, -2, -2, -2, 0, -1, -1, -2, -5, -5,
- -5, -1, 4, 10, 17, 20, 22, 19, 15, 7, -1, -9, -15, -19, -21, -21,
- -18, -16, -13, -11, -12, -15, -19, -23, -24, -20, -13, -3, 9, 20, 34, 44,
- 50, 46, 35, 21, 7, -4, -14, -20, -19, -13, -8, 2, 0, -5, -15, -28,
- -32, -29, -14, 0, 11, 27, 42, 58, 59, 45, 22, 4, -15, -26, -37, -43,
- -42, -37, -17, 1, 18, 23, 8, -5, -29, -47, -47, -43, -25, -5, 20, 52,
- 80, 92, 76, 43, 9, -20, -35, -38, -46, -41, -29, -12, 19, 35, 22, 4,
- -34, -53, -58, -40, -26, -16, 14, 47, 88, 108, 90, 50, 16, -9, -36, -51,
- -64, -64, -52, -33, -1, 32, 40, 24, 3, -29, -62, -58, -65, -52, -18, 23,
- 68, 114, 127, 95, 41, 1, -36, -54, -56, -68, -55, -35, -17, 19, 42, 29,
- 13, -16, -46, -60, -54, -56, -47, -11, 29, 72, 116, 127, 94, 41, -3, 0,
- 16, 39, 54, 46, 18, 7, -15, -36, -9, -6, -16, -5, -15, -30, -23, -35,
- -20, 22, 3, -19, -20, -13, -9, 19, 23, 10, 12, 35, 66, 54, 4, -43,
- -58, -15, -10, 16, 55, 18, -39, -38, -30, 2, 9, 27, 51, -32, -60, -72,
- -4, 32, 71, 19, -8, 56, -2, -42, 10, 21, -6, 31, -9, -70, 8, -6,
- -19, -93, -20, -5, -31, 10, 5, 56, 24, -45, 11, 66, 48, 61, 89, 49,
- -57, -6, -20, -69, -104, -83, -50, 32, 10, -16, -87, -78, 30, 127, 63, -17,
- -91, -2, -12, 45, 83, 30, 56, 54, 42, 7, 79, -26, -52, -64, -97, 12,
- -3, -107, -99, -39, 34, 86, 19, -25, 25, 90, -8, -38, 65, 36, 10, 30,
- 36, 19, -6, 38, -47, -101, -52, -45, 30, -9, -106, 18, -10, -37, 16, 100,
- -94, -111, -25, -35, -12, -8, -9, 51, 24, -5, -70, -52, -52, -19, -11, 48,
- 93, 61, 17, 113, 125, 73, -16, -30, -57, -78, -116, -55, -38, -10, -5, -4,
- 38, 31, -3, -46, -46, -50, -20, -10, 52, 84, 48, 14, 115, 119, 64, -16,
- -1, 4, 0, -9, -11, -1, 6, 2, -2, 4, -6, -10, -2, 11, 14, 3,
- -10, -15, -1, 17, 4, 6, 4, -12, -18, 6, 10, 4, 6, -8, -36, 2,
- 3, 3, 5, 15, -20, -17, 9, 8, 11, 17, -8, -26, 18, 2, 5, 5,
- 13, -24, -8, -2, 2, 5, 7, -21, -18, 13, 5, -5, 17, 7, -14, -13,
- -12, 0, 14, 3, -12, -26, 13, 3, 10, 18, 12, -15, -14, -1, 3, 19,
- 0, -10, -29, 11, 4, 17, 15, 12, -24, -20, 6, 9, 22, -3, -13, -15,
- 9, 1, 7, 6, 18, -19, -26, -18, 2, 22, 0, -25, -20, 15, 8, -4,
- 8, 31, -12, -20, -15, 9, 33, 9, -29, -2, 27, 7, -11, 8, 20, -20,
- -41, -10, 15, 35, 15, -21, 11, 49, 6, -6, 4, 3, -48, -76, -35, 14,
- 37, 22, -24, 29, 68, 20, 3, 7, -5, -68, -90, -59, 19, 36, 28, -13,
- 59, 93, 30, 2, 18, -25, -88, -105, -81, 13, 26, 30, -4, 88, 109, 33,
- 0, 22, -30, -88, -112, -76, 17, 31, 18, 5, 94, 114, 30, -4, 0, 4,
- -30, -1, 0, -2, -2, -2, -1, 4, 11, 18, 30, 7, -64, -60, -30, -7,
- 0, 2, 22, 67, 117, 23, -128, -74, -30, -5, -2, 1, 19, 62, 116, 38,
- -123, -82, -31, -8, -1, -1, 16, 57, 114, 52, -117, -88, -33, -10, -2, -3,
- 14, 52, 112, 64, -108, -96, -35, -13, -2, -4, 12, 49, 108, 77, -99, -102,
- -37, -15, -2, -5, 10, 43, 104, 86, -87, -109, -40, -18, -2, -6, 8, 40,
- 100, 95, -73, -115, -42, -21, -2, -8, 7, 35, 95, 102, -59, -120, -45, -24,
- -2, -8, 5, 32, 90, 109, -44, -124, -49, -26, -3, -9, 3, 28, 85, 114,
- -29, -126, -53, -28, -4, -9, 2, 25, 81, 116, -13, -127, -58, -29, -6, -9,
- 0, 22, 75, 119, 3, -126, -63, -31, -7, -9, -2, 19, 70, 120, 18, -124,
- -69, -32, -9, -9, -3, 16, 65, 119, 34, -63, -107, -58, -23, -11, -7, 7,
- 46, 107, 89, -52, -109, -62, -25, -12, -8, 5, 42, 104, 97, -41, -87, -70,
- -36, -18, -11, 0, 30, 85, 100, -2, -87, -5, 11, -23, -10, -3, -20, -3,
- -17, -24, -33, -26, -1, -13, -12, -6, -9, 6, 25, 19, -7, -1, 22, -6,
- -20, 13, 6, -12, 26, 48, 0, -7, 34, 23, 4, 32, 23, -41, -11, 49,
- -3, -30, 35, 45, -14, -2, 62, 18, -44, -2, 26, -4, -28, -6, 16, 2,
- -9, -9, 2, 18, 24, 9, -25, -57, -36, 30, 38, -21, -63, -37, 9, 37,
- 40, 0, -56, -56, 3, 39, 20, -23, -52, -58, -46, 8, 67, 56, -18, -61,
- -18, 36, 70, 95, 73, -35, -128, -127, -73, -17, 32, 48, 29, 28, 60, 106,
- 113, 91, 36, -26, -67, -90, -91, -71, -44, -25, -13, 9, 36, 51, 69, 70,
- 32, -40, -92, -99, -70, -25, 12, 29, 21, 3, -9, 10, 21, 12, -11, -22,
- -27, -44, -23, 10, 30, 25, 24, 39, 18, 3, 8, 19, -1, -19, -8, 6,
- 5, 13, 50, 43, 37, 36, 40, 37, 4, 12, -10, -33, -31, -25, -1, 1,
- 7, 14, 10, -4, -11, -10, -6, -19, -42, -28, -54, -51, -18, -5, 3, 2,
- -10, -10, 10, 28, 27, 16, 5, -5, -24, -26, -7, -14, -25, -16, 53, 33,
- -49, -30, 53, 50, -24, -34, 40, 82, -118, -23, 120, -56, -70, -72, 106, -10,
- -48, 3, 87, 28, -126, -16, 81, 4, -84, -51, 38, 62, -32, 36, 84, -12,
- -41, 72, -42, -60, -64, 4, 77, -24, -79, -9, 122, 6, -94, 52, 43, 35,
- 13, -62, -7, -89, 24, -30, 16, 29, 56, -59, 83, 42, 31, 36, -76, -2,
- -128, -2, 45, 27, -104, -31, 66, 21, 19, 36, 121, 11, -76, -26, -93, 34,
- 24, -34, -65, -53, 53, 17, 73, 46, 75, -9, -64, -21, -103, 41, 51, -41,
- -83, -43, 108, 6, -11, 28, 127, 2, -84, -38, -72, 39, 17, -23, -15, -67,
- 37, 6, 29, 64, 79, 17, -39, -39, -120, 55, 23, -17, -62, -51, 81, 23,
- 20, 24, 99, -38, -99, 4, 17, -66, -41, -33, 63, 62, 16, 53, 91, 56,
- -65, -36, -99, -38, 14, -47, -29, -38, 35, 83, 9, 48, 83, 62, -45, -31,
- -103, -49, 14, 2, 6, -33, 33, -4, -1, 34, -93, 60, -49, 68, -21, 41,
- -38, -38, 27, -87, 127, -34, 38, -3, -34, -2, -85, 79, -24, 4, 75, -23,
- 11, -70, 1, -6, -6, 63, -48, 76, -71, 2, -7, -15, 46, -32, 48, -25,
- -5, 10, -31, 18, -23, 5, 6, 17, 11, 3, 24, -46, -21, -1, -5, 31,
- 1, 36, -23, -11, -4, -29, 14, -5, 29, 9, -2, -2, -20, -2, -15, 13,
- 7, 4, 15, -11, 4, -13, -1, 1, -13, 15, -6, 9, 9, -2, -4, -11,
- -2, -11, 7, 12, 9, 5, -6, -6, -16, -2, 3, 6, 13, 1, 7, -14,
- -3, -11, -1, 8, 0, 18, -3, -3, -6, -13, 0, 4, 2, 9, 2, 2,
- -6, -4, -1, -8, 2, 4, 2, 7, -4, 2, 1, -7, -3, -2, 0, 2,
- 8, -2, 2, -1, -7, -3, -1, 3, 4, 3, 3, -3, -4, -4, 0, 2,
- 1, 5, -1, -2, 1, -4, -1, 1, 0, 2, -5, -8, -3, -3, -9, -2,
- -2, 5, 10, 16, 11, 5, -3, -5, -1, -4, -6, -7, -15, -18, -27, -31,
- -21, -11, 22, 56, 90, 66, -17, -25, -25, 0, -12, -15, -25, -32, -39, -37,
- -26, 6, 33, 65, 69, 44, -1, -13, -12, 1, 0, -9, -14, -22, -40, -44,
- -42, -23, 8, 39, 60, 84, 57, -16, -25, -19, 2, -8, -11, -18, -32, -51,
- -45, -32, -6, 28, 54, 85, 96, -5, -29, -23, -7, -10, -17, -16, -28, -53,
- -44, -40, -7, 22, 52, 82, 112, 17, -37, -25, -20, -11, -18, -10, -23, -33,
- -51, -40, -23, 10, 45, 65, 96, 64, -21, -35, -34, -19, -20, -13, -5, -14,
- -35, -41, -39, -17, 9, 45, 58, 82, 98, -2, -57, -47, -23, -12, -11, -2,
- -18, -28, -39, -36, -24, -1, 26, 57, 84, 121, 23, -65, -50, -40, -12, -11,
- -4, -14, -20, -34, -32, -27, -5, 19, 56, 80, 127, 15, -66, -50, -2, -5,
- -5, 2, 10, 8, -7, -16, -9, 6, 17, 8, -19, -20, 14, 38, 34, 20,
- -5, 1, 50, 37, -50, -54, -66, -32, 32, -3, -13, -18, -17, 46, 89, -17,
- -62, 45, 127, 57, -57, -67, -109, -11, 88, -31, -90, -88, -27, 63, 97, -27,
- -105, -44, 65, 110, 60, -12, -30, -27, 17, 49, -2, -39, -6, 30, -16, -36,
- -43, 32, 67, -54, -58, -38, -21, 47, 95, 76, -33, -78, -62, 10, 107, 24,
- -106, -107, 12, 52, 27, 78, 8, -75, 25, 6, -26, 59, 32, -17, -7, -19,
- 11, 32, -51, -52, 41, -9, -13, 94, 2, -65, 5, -46, -86, 34, 62, 85,
- 29, -93, -89, -29, 44, 35, -31, -33, -19, 56, 127, 7, -9, -62, -52, 23,
- 46, 44, -56, -16, -55, -46, 22, 83, -13, -42, -7, 13, 81, 49, 3, -9,
- -30, -47, -30, 3, 23, 6, -7, -20, -44, 10, 96, -13, 0, 16, 31, 47,
- 61, 75, 87, 98, 107, 115, 121, 125, 127, 127, 125, 121, 116, 108, 99, 88,
- 75, 62, 47, 32, 16, 0, -16, -31, -47, -61, -75, -87, -98, -108, -116, -122,
- -126, -128, -128, -126, -123, -117, -109, -100, -89, -77, -64, -49, -34, -18, -2, 14,
- 29, 45, 59, 73, 86, 97, 106, 114, 121, 125, 127, 127, 126, 122, 116, 109,
- 100, 89, 77, 63, 49, 34, 18, 2, -14, -30, -45, -60, -73, -86, -97, -107,
- -115, -121, -126, -128, -128, -127, -123, -118, -110, -101, -91, -79, -65, -51, -36, -20,
- -4, 12, 28, 43, 58, 72, 84, 96, 106, 114, 120, 124, 127, 127, 126, 122,
- 117, 109, 100, 90, 78, 64, 50, 35, 19, 3, -13, -29, -44, -59, -73, -85,
- -97, -107, -115, -121, -125, -128, -128, -127, -123, -118, -110, -101, -91, -79, -65, -51,
- -36, -20, -4, 12, 2, 5, 5, 0, -16, -9, -2, -19, 4, 18, 6, 10,
- -16, -21, 22, -2, 3, -7, 21, 43, -57, -37, 46, -39, -31, 78, 23, -23,
- -10, -10, -7, -52, 44, 50, -44, 9, -9, -46, 47, 12, -75, 40, 45, 32,
- -10, -25, -15, -45, 24, 44, -40, -10, 18, -48, -29, 63, 44, -30, -1, 83,
- -45, -94, 96, 0, -103, 21, 29, -42, 21, 80, -25, -15, 26, 39, -79, -18,
- 73, -111, -45, 61, 29, 55, -22, -77, 40, 9, -72, 78, 35, -1, -1, -69,
- 12, -50, -42, 123, 45, -7, -39, -86, 3, 51, 30, 28, -4, -33, -41, -66,
- 54, -8, -30, 127, -7, -30, -32, -39, 48, -65, 20, 121, -33, -14, -53, -32,
- 46, -24, 36, 98, -49, -39, -61, 1, 49, -54, 65, 59, -83, -11, -49, 32,
- 39, -72, 113, 59, -83, -11, -49, 32, 39, -72, 113, 59, -2, -4, -4, -7,
- -8, -8, -7, -4, -3, -2, 1, 4, 6, 6, 6, 4, 2, 0, -2, -3,
- -4, -7, -7, -5, -3, 0, 4, 9, 11, 11, 9, 7, 4, 1, -3, -7,
- -9, -12, -13, -16, -19, -19, -13, -2, 9, 17, 19, 20, 18, 13, 8, 3,
- 0, -2, -3, -8, -14, -21, -25, -21, -9, 4, 15, 23, 28, 25, 20, 9,
- -7, -21, -14, 3, 3, -18, -38, -49, -32, -7, 8, 14, 26, 37, 42, 37,
- 26, 7, -18, -27, -5, 8, -7, -24, -34, -40, -32, -19, 1, 17, 42, 56,
- 58, 40, -19, -81, 1, 67, 0, -60, -49, -27, -24, 0, -18, -24, -8, 37,
- 67, 70, 59, 34, -42, -81, 7, 51, -12, -54, -37, -14, -25, -14, -16, -24,
- 4, 55, 75, 102, 52, -102, -104, 90, 30, -48, -76, 1, -14, 0, -2, -2,
- -3, -5, -7, -8, -8, -7, -6, -4, -2, 0, 1, 3, 4, 6, 6, 6,
- 6, 5, 4, 3, 1, 0, 0, -3, -4, -7, -10, -11, -11, -8, -6, 1,
- 5, 6, 8, 11, 11, 8, 5, 5, 2, 1, 0, 0, -2, 1, -4, -16,
- -36, -27, -5, 6, -3, -6, 0, -6, 2, 27, 24, 19, 16, 9, 3, 0,
- -4, 2, 1, 9, 19, -14, -79, -32, 22, -4, -22, -14, 25, 8, -11, 13,
- 28, 16, 19, 16, 1, -2, -4, -3, -6, 28, 38, -59, -111, 25, 16, -16,
- -40, 16, 24, -20, 4, 24, 29, 17, 27, 13, 1, -10, -6, -10, -8, 43,
- 61, -68, -128, 28, 12, -15, -39, 12, 21, -28, 12, 37, 25, 12, 27, 11,
- 0, -16, -2, -12, -11, 52, 67, -68, 35, 54, 47, 4, -60, -92, -68, -27,
- 0, -2, -18, -20, -6, 2, -8, -15, -11, -3, 3, -7, -11, -6, -2, 7,
- 15, 18, 19, 22, 27, 40, 40, 29, 20, 24, 28, 34, 30, 25, 32, 20,
- 14, 9, 16, 19, 17, 6, -1, 3, -6, -14, -23, -18, -7, 1, -18, -18,
- -24, -25, -24, -35, -35, -35, -21, -12, -14, -21, -17, -29, -24, -31, -34, -9,
- -11, -9, -3, -7, -7, 6, -17, -22, 7, 16, 14, -4, -11, 10, 33, 24,
- 21, 27, 3, -19, -25, -18, 17, 50, 48, 49, 61, 31, -48, -103, -73, 9,
- 56, 70, 82, 109, 127, 71, -46, -127, -96, -30, -4, 9, 47, 103, 117, 60,
- -39, -110, -119, -94, -64, -40, -4, 35, -8, -14, -9, -5, -4, -3, 6, 18,
- 19, 6, -14, -20, -12, -3, -3, -6, 2, 21, 28, 13, -16, -26, -14, -6,
- -6, -7, 1, 27, 36, 18, -15, -27, -15, -3, -2, -10, -6, 25, 41, 22,
- -17, -34, -18, -4, -3, -16, -12, 29, 56, 31, -24, -44, -20, -4, -1, -19,
- -22, 31, 73, 47, -27, -62, -25, -2, 4, -21, -36, 26, 91, 61, -27, -79,
- -33, 0, 10, -18, -49, 14, 106, 82, -24, -94, -40, 8, 14, -12, -59, 1,
- 112, 105, -19, -106, -51, 12, 16, -4, -63, -13, 110, 127, -12, -114, -51, 0,
- -1, -4, -8, -11, -8, -2, 0, 7, 14, 21, 46, 92, 120, 76, -36, -121,
- -119, -73, -31, -7, 3, 2, -4, -6, 2, 22, 60, 106, 116, 43, -72, -128,
- -105, -57, -21, -3, 3, -1, -6, -5, 7, 33, 76, 117, 102, 5, -100, -127,
- -89, -43, -13, 0, 2, -3, -7, -2, 14, 46, 92, 122, 79, -34, -118, -118,
- -72, -31, -8, 1, 0, -5, -7, 2, 23, 61, 107, 118, 46, -69, -126, -104,
- -56, -21, -4, 1, 0, -4, -5, 0, 16, 48, 87, 103, 60, -25, -87, -94,
- -58, -20, -4, -11, 12, 24, 31, -36, 29, -9, 2, -38, -5, -5, -10, -33,
- -10, -24, -20, -39, -36, -18, -38, -58, -5, -22, -15, -15, 90, -42, -3, -8,
- 25, 6, 28, 25, 17, 25, -16, 28, 80, 22, 12, -6, 35, 22, 8, -7,
- 28, 29, -19, 7, 8, -1, -29, -23, 10, -23, -13, -26, -17, -20, -33, -41,
- -19, -28, -64, -13, -21, -13, -29, 54, 25, -20, -36, 42, -4, 13, 52, -8,
- 47, -14, 9, 42, 88, -12, 20, -5, 43, 22, -11, 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, -128, -128, -128, -128, -128, -128, -128, -128,
- -128, -128, -128, -128, -128, -128, -128, 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, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
- 127, -128, 1, 4, 7, 10, 12, 16, 19, 22, 25, 28, 31, 35, 38, 42,
- 45, 49, 51, 56, 58, 63, 65, 70, 73, 78, 80, 85, 87, 93, 95, 100,
- 102, 108, 109, 117, 114, 127, 85, -63, -60, -64, -60, -62, -59, -61, -59, -61,
- -58, -60, -58, -59, -58, -58, -57, -57, -55, -55, -54, -54, -52, -51, -50, -49,
- -47, -46, -44, -43, -41, -40, -37, -36, -34, -32, -30, -28, -25, -24, -21, -19,
- -16, -14, -11, -9, -6, 1, 1, 4, 7, 10, 12, 16, 19, 22, 25, 28,
- 31, 35, 38, 42, 45, 49, 51, 56, 58, 63, 65, 70, 73, 78, 80, 85,
- 87, 93, 95, 100, 102, 108, 109, 117, 114, 127, 85, -63, -60, -64, -60, -62,
- -59, -61, -59, -61, -58, -60, -58, -59, -58, -58, -57, -57, -55, -55, -54, -54,
- -52, -51, -50, -49, -47, -46, -44, -43, -41, -40, -37, -36, -34, -32, -30, -28,
- -25, -24, -21, -19, -16, -14, -11, -9, -6, 1, -3, -19, -24, -14, -8, -19,
- -12, -10, -5, -12, -50, -19, 23, 35, 4, -20, -7, -26, 9, 40, 69, 16,
- -88, -69, -38, -32, -27, 41, 65, 55, 18, -40, -38, -20, 66, 127, 121, 57,
- -23, -55, -48, 13, 53, 31, -20, -38, -13, 10, 8, 0, 12, 17, 13, 2,
- -1, -3, -3, 6, 13, 7, -17, -24, -12, 4, 3, -10, -20, -32, -22, -18,
- -12, -3, 6, 16, 22, 29, 30, 27, 20, 11, 0, -7, -12, -11, -5, 0,
- -3, -14, -20, -16, -9, -9, -17, -25, -29, -31, -33, -35, -33, -29, -25, -22,
- -20, -17, -14, -13, -12, -11, -9, -10, -13, -15, -11, -5, 3, 9, 10, 9,
- 9, 12, 18, 30, 50, 80, 119, 127, 102, 82, 77, 60, 37, 5, -34, -70,
- -84, -83, -74, -60, -46, -29, -12, -2, 6, -23, 28, -20, 50, 50, -14, 14,
- -28, -2, 28, 52, -25, -13, -52, 43, -41, -9, -26, 36, -25, -20, -17, 3,
- -11, 38, 30, -61, 12, -6, 5, 45, 41, -4, 4, -20, -12, 45, 33, -11,
- -29, -44, 27, -17, -36, -1, 17, -11, -31, -12, 4, -10, 37, 20, -39, -23,
- 0, -104, -55, -11, 24, 33, 30, 7, -15, -31, -30, -25, -23, -20, -9, 10,
- 31, 59, 91, 111, 115, 92, 51, 7, -33, -64, -81, -81, -71, -51, -22, 16,
- 52, 74, 82, 81, 68, 38, 0, -40, -81, -112, -124, -102, -57, -11, 0, 7,
- -23, -58, -85, -100, -104, -100, -92, -81, -69, -57, -45, -33, -22, -11, -1, 8,
- 18, 27, 37, 49, 62, 79, 99, 118, 124, 111, 84, 53, 26, 5, -8, -14,
- -15, -12, -6, 2, 12, 21, 28, 26, 9, -22, -58, -20, 7, 10, 21, -14,
- 9, 22, 57, 62, 127, 56, 28, 26, -28, 10, -81, -31, -81, -35, -19, -55,
- -27, -4, -4, 23, 49, 88, 85, 22, 1, 0, -3, 18, -22, -12, -39, -14,
- -47, -67, -53, -53, -33, -20, 8, -22, 25, 30, 6, -19, -62, -19, 10, 83,
- 57, -67, -88, -52, 63, 127, 42, -63, -121, -70, 82, 111, 46, -43, -114, -35,
- 45, 73, 39, -19, -54, -41, 9, 49, 24, -16, -14, -9, -6, 10, 8, -22,
- 25, 30, 6, -19, -62, -19, 10, 83, 57, -67, -88, -52, 63, 127, 42, -63,
- -121, -70, 82, 111, 46, -43, -114, -35, 45, 73, 39, -19, -54, -41, 9, 49,
- 24, -16, -14, -9, -6, 10, 8, -22, 25, 30, 6, -19, -62, -19, 10, 83,
- 57, -67, -88, -52, 63, 127, 42, -63, -121, -70, 82, 111, 46, -43, -114, -35,
- 45, 73, 39, -19, -54, -41, 9, 49, 24, -16, -14, -9, -6, 10, -18, -15,
- 80, 127, 20, 18, 72, 60, -36, 22, 33, -73, -105, -27, 29, 25, 8, 43,
- 23, -22, -35, -14, -8, -34, -25, -5, -18, -46, -13, -28, -3, -19, -10, -28,
- -10, 17, -18, 96, 127, 123, 127, 126, 126, 95, 61, 22, -17, -56, -95, -118,
- -123, -128, -128, -128, -128, -128, -128, -128, -128, -124, -93, -55, -17, 25, 62, 100,
- 107, 119, 119, 127, 41, -4, -4, -10, -27, -62, -102, -128, -117, -85, -76, -49,
- -25, -7, 15, 24, 14, 0, -9, -12, -3, 33, 81, 105, 111, 101, 80, 62,
- 45, 30, 16, 8, 1, -4, 126, 86, -44, -68, -88, -63, 4, 84, 127, 14,
- -29, -51, -127, -47, 58, 87, 82, 24, -17, -112, -113, 18, 46, 72, 102, 19,
- -72, -118, -51, 9, 27, 126, 19, -53, -114, -108, 15, 122, 111, 21, -71, -70,
- 5, 59, 83, 23, -72, -84, -49, 12, 37, 38, -28, -65, -26, 7, -2, 11,
- 5, 23, 68, 19, 27, -54, 15, -24, -31, 46, 71, 81, -24, -33, -87, -41,
- -71, -61, -70, -36, -44, -3, 12, -25, -20, 20, 68, 85, 127, 15, 50, -5,
- 27, 51, 82, 106, 127, 118, 101, 92, 74, 52, 39, 37, 14, -41, -105, -108,
- -94, -119, -124, -93, -57, -40, -37, -45, -51, -41, -5, 51, 127, 127, -128, -128,
- -128, -128, -128, -128, -128, -128, -128, -128, 127, 127, 127, 127, 127, 127, 127, 127,
- 127, 127
+ 0, 0, -3, -4, -6, -8, -10, -12, -12, -11, -8, -3, 3, 7, 10, 14,
+ 16, 16, 15, 12, 9, 4, -4, -12, -18, -21, -21, -19, -18, -15, -10, -3,
+ 10, 20, 34, 44, 51, 52, 48, 43, 38, 26, 8, -15, -37, -52, -61, -64,
+ -66, -64, -59, -47, -31, -13, 4, 18, 30, 37, 40, 36, 30, 24, 19, 11,
+ -2, -17, -24, -28, -28, -21, -18, -16, -10, -3, 12, 27, 39, 49, 53, 53,
+ 50, 43, 37, 25, 11, -11, -31, -46, -57, -63, -66, -63, -57, -46, -34, -19,
+ -3, 13, 27, 35, 39, 37, 32, 26, 20, 11, 0, -13, -20, -24, -25, -21,
+ -19, -14, -8, -2, 9, 23, 37, 47, 53, 52, 49, 42, 35, 25, 13, -6,
+ -28, -48, -60, -67, -67, -64, -60, -51, -39, -23, -7, 10, 23, 35, 39, 38,
+ 32, 26, 21, 15, 4, -9, -20, -22, -21, -19, -14, -11, -5, 1, 9, 19,
+ 31, 45, 51, 52, 47, 39, 35, 25, 15, -3, -23, -42, -58, -70, -71, -66,
+ -60, -51, -43, -30, -13, 6, 22, 32, 40, 40, 38, 33, 27, 19, 9, -5,
+ -17, -25, -26, -22, -16, -11, -8, -4, 7, 21, 35, 48, 53, 56, 50, 43,
+ 34, 22, 13, -2, -22, -44, -63, -75, -76, -69, -61, -51, -43, -29, -13, 6,
+ 23, 32, 41, 43, 41, 37, 26, 18, 7, -8, -19, -25, -25, -22, -15, -9,
+ -5, 0, 10, 24, 37, 44, 48, 52, 52, 46, 33, 20, 8, -5, -20, -38,
+ -59, -74, -79, -73, -67, -55, -43, -26, -11, 4, 18, 29, 41, 45, 45, 38,
+ 29, 21, 11, -3, -15, -25, -27, -22, -16, -11, -8, 0, 10, 25, 38, 44,
+ 47, 50, 53, 49, 37, 20, 7, -5, -17, -34, -58, -74, -82, -76, -67, -59,
+ -47, -29, -12, 3, 14, 25, 38, 50, 52, 46, 33, 23, 14, 3, -11, -25,
+ -28, -27, -21, -16, -13, -7, 8, 27, 41, 44, 45, 47, 54, 55, 44, 25,
+ 7, -7, -18, -32, -53, -71, -81, -81, -72, -67, -55, -37, -16, 3, 15, 23,
+ 34, 48, 57, 56, 44, 30, 19, 5, -12, -26, -33, -31, -25, -19, -16, -11,
+ 7, 25, 45, 49, 49, 52, 57, 59, 48, 32, 11, -5, -22, -39, -56, -73,
+ -82, -88, -84, -75, -60, -38, -16, 5, 21, 30, 39, 52, 59, 61, 53, 37,
+ 22, 7, -12, -28, -35, -36, -30, -22, -19, -16, -2, 21, 41, 52, 51, 52,
+ 57, 62, 54, 40, 18, -2, -18, -36, -54, -70, -80, -86, -87, -81, -69, -48,
+ -23, 0, 18, 28, 35, 45, 57, 64, 59, 46, 27, 9, -11, -24, -30, -32,
+ -29, -25, -20, -16, -5, 15, 36, 47, 50, 49, 53, 57, 54, 43, 24, 5,
+ -14, -32, -50, -65, -75, -82, -86, -86, -77, -58, -32, -8, 14, 25, 30, 41,
+ 56, 69, 69, 57, 36, 17, -4, -20, -29, -32, -27, -28, -27, -23, -13, 10,
+ 33, 46, 50, 48, 50, 54, 55, 48, 34, 16, -6, -29, -50, -68, -75, -78,
+ -82, -86, -84, -72, -47, -16, 11, 28, 34, 41, 51, 64, 70, 64, 49, 27,
+ 5, -17, -30, -33, -29, -29, -30, -30, -22, -2, 23, 41, 49, 51, 51, 54,
+ 56, 50, 42, 25, 4, -20, -44, -62, -70, -76, -83, -87, -89, -78, -56, -29,
+ 0, 19, 31, 38, 48, 63, 72, 71, 60, 40, 14, -12, -25, -29, -26, -27,
+ -33, -37, -30, -12, 11, 31, 41, 48, 51, 53, 55, 55, 51, 39, 17, -12,
+ -38, -58, -67, -74, -82, -92, -98, -89, -69, -41, -13, 10, 29, 41, 50, 64,
+ 72, 78, 74, 57, 29, 0, -18, -26, -28, -32, -38, -42, -38, -23, -3, 18,
+ 30, 42, 52, 58, 60, 61, 57, 48, 28, 2, -30, -51, -62, -70, -81, -94,
+ -101, -93, -75, -49, -23, -2, 18, 36, 50, 61, 69, 77, 78, 66, 42, 11,
+ -11, -22, -27, -32, -39, -46, -46, -36, -14, 8, 25, 41, 52, 59, 62, 63,
+ 62, 57, 38, 11, -20, -47, -61, -69, -78, -89, -98, -94, -80, -60, -37, -12,
+ 13, 33, 48, 62, 70, 78, 81, 72, 52, 23, 0, -14, -24, -33, -43, -49,
+ -49, -39, -23, -2, 15, 33, 47, 57, 63, 62, 62, 57, 40, 20, -7, -34,
+ -52, -65, -74, -83, -94, -92, -81, -63, -42, -22, 0, 21, 39, 54, 63, 73,
+ 79, 76, 61, 37, 12, -5, -19, -28, -37, -46, -51, -47, -32, -13, 7, 25,
+ 43, 54, 58, 60, 60, 61, 48, 27, 3, -25, -45, -60, -72, -81, -90, -92,
+ -84, -71, -52, -32, -9, 14, 33, 50, 61, 74, 80, 78, 67, 47, 24, 6,
+ -12, -26, -37, -50, -56, -52, -37, -19, -2, 16, 35, 52, 61, 63, 61, 59,
+ 51, 35, 12, -15, -38, -55, -66, -77, -83, -83, -80, -68, -55, -39, -19, 4,
+ 25, 41, 54, 66, 73, 75, 68, 52, 31, 11, -7, -22, -33, -46, -54, -51,
+ -39, -24, -5, 12, 32, 48, 56, 60, 61, 58, 50, 36, 17, -8, -30, -46,
+ -63, -74, -80, -80, -74, -69, -58, -43, -27, -5, 15, 31, 48, 60, 68, 72,
+ 68, 57, 39, 20, 2, -16, -30, -44, -51, -50, -41, -27, -10, 9, 28, 43,
+ 53, 57, 57, 54, 48, 37, 19, -3, -25, -41, -56, -69, -75, -73, -69, -63,
+ -59, -49, -32, -13, 9, 25, 37, 48, 58, 66, 65, 58, 42, 25, 8, -9,
+ -22, -36, -41, -43, -37, -26, -14, 4, 21, 37, 48, 52, 53, 47, 42, 34,
+ 21, 3, -18, -39, -51, -64, -67, -62, -60, -60, -58, -50, -36, -16, 3, 17,
+ 29, 41, 49, 58, 61, 60, 49, 29, 11, -7, -19, -28, -32, -33, -30, -25,
+ -14, 2, 19, 33, 41, 45, 42, 38, 36, 29, 20, 6, -14, -28, -43, -54,
+ -58, -55, -50, -51, -54, -51, -41, -22, -4, 11, 19, 30, 37, 47, 55, 56,
+ 51, 34, 16, 0, -15, -19, -23, -22, -22, -21, -14, 0, 15, 29, 39, 43,
+ 37, 31, 25, 21, 18, 6, -11, -28, -42, -50, -51, -48, -44, -41, -44, -43,
+ -41, -25, -8, 9, 16, 22, 26, 35, 43, 50, 48, 33, 16, -3, -13, -16,
+ -16, -15, -13, -11, -6, 5, 16, 28, 38, 41, 35, 24, 15, 12, 10, 4,
+ -11, -27, -39, -46, -46, -45, -40, -36, -36, -37, -38, -29, -13, 6, 16, 19,
+ 22, 27, 37, 43, 42, 32, 19, 2, -10, -13, -12, -7, -4, -2, 2, 10,
+ 18, 27, 36, 38, 32, 20, 9, 4, -2, -4, -11, -23, -34, -42, -42, -38,
+ -31, -28, -29, -32, -33, -30, -18, 0, 10, 12, 12, 17, 26, 35, 36, 31,
+ 19, 5, -6, -11, -9, -2, 7, 14, 13, 13, 16, 23, 31, 34, 29, 15,
+ -3, -8, -10, -10, -14, -20, -26, -30, -32, -30, -25, -18, -17, -24, -31, -32,
+ -26, -11, 2, 7, 8, 9, 17, 25, 29, 28, 21, 9, -2, -7, -5, 4,
+ 12, 21, 24, 23, 25, 26, 29, 31, 27, 15, -2, -15, -21, -23, -23, -23,
+ -28, -30, -31, -27, -19, -10, -9, -13, -21, -22, -20, -11, -4, -3, -5, -2,
+ 5, 13, 17, 17, 16, 10, 6, 0, 3, 11, 23, 32, 33, 30, 28, 27,
+ 24, 24, 19, 9, -6, -19, -29, -29, -26, -20, -19, -22, -24, -23, -16, -10,
+ -9, -14, -20, -24, -21, -16, -10, -6, -5, 1, 5, 11, 12, 13, 11, 8,
+ 6, 1, 4, 9, 23, 33, 39, 36, 32, 32, 28, 22, 17, 7, -7, -22,
+ -31, -33, -31, -24, -19, -18, -18, -16, -13, -7, -6, -8, -14, -21, -24, -20,
+ -15, -12, -9, -6, 0, 4, 6, 8, 8, 5, 5, 2, 7, 15, 27, 37,
+ 42, 45, 41, 39, 32, 22, 13, 3, -11, -26, -37, -41, -37, -29, -21, -18,
+ -15, -11, -6, -2, -2, -4, -7, -13, -16, -20, -21, -16, -14, -10, -6, -3,
+ -3, 0, 3, 2, 3, 3, 9, 18, 32, 41, 46, 49, 44, 43, 35, 24,
+ 12, 1, -14, -27, -39, -40, -36, -31, -22, -16, -13, -6, -3, -3, -4, -9,
+ -9, -13, -16, -20, -21, -16, -15, -11, -6, -4, -4, -5, -5, -3, -3, 0,
+ 10, 19, 33, 44, 51, 56, 52, 50, 40, 23, 11, -6, -19, -30, -40, -43,
+ -40, -35, -24, -16, -7, 2, 6, 5, 1, -6, -9, -9, -9, -12, -19, -21,
+ -21, -17, -9, -7, -9, -11, -15, -14, -9, -7, 7, 19, 36, 51, 57, 61,
+ 59, 56, 48, 33, 13, -8, -24, -35, -45, -51, -46, -38, -26, -14, -7, 3,
+ 11, 15, 12, 3, -5, -7, -6, -9, -15, -22, -25, -23, -17, -13, -12, -16,
+ -19, -21, -18, -12, 3, 21, 38, 50, 58, 67, 65, 64, 55, 41, 21, -4,
+ -25, -38, -46, -50, -49, -43, -33, -23, -11, 3, 14, 19, 16, 8, 0, -2,
+ -2, 0, -8, -19, -27, -30, -25, -22, -20, -20, -22, -25, -24, -16, 1, 22,
+ 43, 56, 62, 67, 68, 65, 60, 46, 24, -3, -25, -40, -45, -49, -50, -46,
+ -37, -23, -10, 1, 12, 20, 20, 14, 7, 2, 3, 3, -4, -15, -26, -31,
+ -30, -27, -26, -26, -29, -33, -33, -25, -8, 17, 41, 57, 65, 71, 73, 73,
+ 66, 53, 33, 5, -23, -41, -48, -50, -48, -48, -40, -30, -14, 1, 12, 21,
+ 24, 18, 13, 6, 5, 5, 0, -11, -25, -37, -39, -35, -31, -31, -33, -38,
+ -37, -29, -12, 15, 40, 59, 67, 71, 72, 73, 69, 59, 39, 14, -16, -38,
+ -50, -51, -50, -48, -45, -36, -21, -4, 12, 25, 30, 25, 18, 11, 11, 10,
+ 6, -8, -25, -39, -46, -42, -38, -37, -37, -40, -42, -34, -15, 13, 40, 57,
+ 66, 71, 72, 72, 69, 61, 45, 19, -10, -34, -46, -48, -47, -45, -45, -41,
+ -28, -12, 7, 23, 27, 25, 18, 15, 17, 17, 12, 1, -20, -37, -47, -50,
+ -46, -45, -44, -45, -46, -41, -21, 7, 37, 60, 69, 73, 72, 72, 72, 67,
+ 52, 25, -6, -33, -47, -50, -47, -47, -47, -45, -35, -16, 6, 23, 31, 30,
+ 24, 23, 24, 25, 18, 4, -15, -33, -50, -56, -57, -53, -48, -49, -49, -45,
+ -29, 2, 35, 58, 68, 71, 72, 74, 73, 68, 56, 34, 5, -26, -43, -48,
+ -45, -42, -46, -46, -41, -24, 0, 21, 33, 34, 31, 25, 27, 27, 19, 6,
+ -14, -36, -55, -64, -64, -60, -50, -47, -45, -44, -31, -4, 32, 58, 71, 72,
+ 68, 70, 70, 66, 57, 36, 11, -20, -43, -50, -48, -41, -37, -42, -40, -28,
+ -5, 21, 36, 38, 34, 26, 29, 28, 20, 8, -13, -33, -52, -68, -69, -65,
+ -55, -49, -47, -44, -31, -3, 30, 55, 67, 70, 68, 70, 70, 65, 57, 39,
+ 15, -13, -38, -49, -47, -40, -35, -39, -41, -30, -9, 17, 37, 44, 45, 38,
+ 32, 29, 22, 9, -10, -34, -54, -70, -75, -73, -64, -52, -45, -43, -31, -7,
+ 25, 53, 67, 72, 70, 72, 70, 62, 53, 38, 16, -10, -32, -49, -50, -43,
+ -35, -33, -36, -29, -10, 16, 35, 46, 46, 41, 35, 30, 23, 10, -10, -34,
+ -53, -69, -75, -74, -66, -53, -45, -42, -34, -13, 17, 46, 63, 68, 66, 63,
+ 65, 63, 54, 43, 24, 0, -20, -40, -43, -42, -36, -32, -32, -28, -16, 7,
+ 29, 47, 52, 47, 39, 31, 21, 10, -9, -30, -50, -66, -78, -77, -71, -59,
+ -49, -42, -34, -17, 9, 37, 56, 66, 66, 62, 62, 61, 56, 45, 30, 7,
+ -13, -31, -39, -40, -36, -33, -32, -28, -18, 1, 21, 41, 54, 52, 44, 36,
+ 26, 13, -8, -29, -48, -66, -76, -80, -74, -64, -55, -45, -34, -18, 5, 29,
+ 50, 65, 68, 66, 64, 60, 59, 47, 33, 15, -5, -23, -37, -43, -41, -37,
+ -35, -31, -21, -4, 16, 36, 52, 59, 54, 45, 33, 17, -5, -25, -45, -60,
+ -74, -83, -82, -71, -59, -49, -37, -23, -2, 22, 43, 59, 66, 65, 64, 60,
+ 58, 50, 39, 23, 2, -17, -32, -39, -40, -38, -35, -32, -23, -6, 14, 33,
+ 49, 59, 58, 49, 34, 16, -5, -25, -43, -60, -74, -83, -83, -76, -63, -53,
+ -40, -24, -5, 16, 36, 54, 65, 67, 65, 61, 57, 52, 43, 27, 9, -12,
+ -26, -37, -40, -39, -36, -32, -28, -13, 6, 27, 46, 58, 60, 52, 39, 23,
+ 5, -16, -36, -53, -66, -77, -84, -81, -72, -60, -45, -32, -15, 5, 25, 48,
+ 62, 69, 71, 69, 65, 58, 50, 34, 16, -6, -24, -36, -42, -45, -44, -39,
+ -33, -21, -2, 22, 43, 59, 64, 60, 47, 34, 17, -6, -28, -50, -66, -76,
+ -84, -86, -82, -72, -57, -40, -21, -2, 21, 42, 58, 66, 73, 76, 71, 64,
+ 53, 40, 26, 4, -17, -34, -45, -49, -48, -43, -38, -28, -10, 15, 40, 58,
+ 66, 64, 56, 42, 25, 4, -21, -44, -62, -73, -81, -87, -86, -78, -65, -47,
+ -31, -9, 15, 34, 52, 62, 72, 79, 80, 72, 61, 49, 34, 12, -12, -32,
+ -43, -49, -54, -55, -48, -36, -16, 10, 35, 56, 67, 71, 67, 54, 38, 15,
+ -10, -34, -57, -72, -85, -93, -97, -89, -76, -59, -40, -20, 8, 32, 50, 67,
+ 77, 87, 89, 81, 66, 52, 35, 16, -6, -30, -47, -58, -61, -57, -50, -37,
+ -19, 6, 29, 51, 65, 73, 73, 62, 44, 18, -6, -28, -49, -67, -81, -93,
+ -97, -94, -83, -65, -47, -28, -5, 19, 42, 61, 76, 87, 90, 88, 80, 66,
+ 48, 27, 3, -17, -40, -56, -65, -66, -58, -49, -30, -6, 17, 41, 59, 71,
+ 77, 70, 56, 36, 11, -13, -34, -53, -71, -89, -98, -100, -94, -79, -62, -44,
+ -21, 3, 27, 52, 74, 90, 98, 95, 86, 75, 59, 37, 12, -14, -35, -54,
+ -64, -67, -64, -51, -34, -10, 11, 32, 50, 65, 73, 71, 58, 37, 14, -10,
+ -29, -48, -64, -81, -93, -98, -94, -82, -63, -45, -26, -5, 16, 40, 65, 83,
+ 94, 94, 84, 75, 63, 46, 23, -3, -27, -47, -58, -64, -64, -56, -39, -17,
+ 3, 20, 38, 57, 71, 72, 61, 45, 24, 1, -19, -37, -56, -73, -91, -99,
+ -100, -92, -74, -53, -34, -16, 7, 31, 59, 82, 97, 101, 92, 78, 65, 48,
+ 29, 6, -21, -43, -55, -64, -66, -58, -40, -18, 3, 17, 32, 51, 69, 71,
+ 62, 45, 27, 6, -15, -34, -50, -64, -81, -93, -99, -96, -80, -59, -40, -23,
+ -4, 21, 50, 77, 94, 100, 93, 81, 67, 53, 36, 14, -12, -36, -53, -58,
+ -63, -56, -42, -22, -5, 10, 23, 42, 63, 70, 62, 47, 29, 13, -6, -27,
+ -43, -57, -72, -84, -98, -99, -87, -66, -44, -27, -11, 10, 38, 67, 91, 99,
+ 92, 82, 70, 57, 41, 21, -3, -27, -47, -58, -63, -58, -44, -23, -5, 7,
+ 17, 35, 55, 66, 61, 46, 29, 13, -4, -22, -39, -51, -65, -78, -90, -95,
+ -85, -69, -47, -30, -12, 9, 30, 57, 83, 96, 91, 81, 67, 57, 42, 26,
+ 6, -18, -39, -55, -62, -58, -43, -24, -8, 2, 14, 30, 47, 60, 60, 49,
+ 34, 17, 0, -16, -31, -43, -58, -71, -86, -93, -86, -72, -52, -32, -15, 3,
+ 22, 48, 76, 90, 89, 78, 69, 59, 46, 32, 14, -6, -27, -47, -57, -56,
+ -45, -29, -12, -5, 4, 18, 37, 54, 58, 51, 36, 21, 6, -8, -20, -33,
+ -52, -68, -84, -90, -85, -74, -58, -42, -22, 0, 20, 42, 67, 83, 87, 80,
+ 68, 58, 47, 34, 19, 0, -20, -40, -52, -53, -45, -27, -13, -4, 6, 17,
+ 33, 47, 53, 52, 38, 21, 3, -11, -24, -35, -50, -65, -80, -89, -85, -71,
+ -55, -39, -21, -2, 20, 39, 59, 74, 81, 75, 67, 57, 47, 38, 23, 4,
+ -17, -32, -43, -45, -39, -26, -14, -4, 4, 12, 26, 38, 47, 48, 35, 19,
+ 4, -10, -20, -29, -41, -56, -71, -78, -81, -71, -56, -43, -23, -6, 15, 35,
+ 49, 62, 72, 69, 63, 54, 45, 41, 28, 11, -11, -27, -37, -40, -35, -24,
+ -17, -7, 2, 9, 22, 35, 46, 49, 37, 21, 4, -9, -18, -27, -41, -55,
+ -71, -79, -79, -70, -53, -38, -23, -8, 9, 31, 46, 58, 63, 63, 59, 52,
+ 45, 40, 32, 14, -6, -24, -32, -31, -30, -23, -18, -12, 1, 9, 21, 31,
+ 41, 44, 33, 21, 5, -6, -20, -29, -43, -57, -69, -77, -73, -65, -52, -41,
+ -27, -8, 11, 32, 49, 57, 64, 61, 55, 47, 39, 36, 29, 13, -8, -25,
+ -36, -35, -26, -16, -9, -5, 1, 9, 22, 36, 45, 43, 33, 17, 1, -11,
+ -21, -32, -45, -57, -71, -78, -73, -61, -45, -33, -23, -8, 11, 31, 46, 53,
+ 57, 54, 48, 40, 34, 31, 27, 14, -4, -20, -29, -28, -22, -12, -4, 1,
+ 4, 8, 21, 34, 43, 43, 31, 17, 1, -11, -22, -31, -44, -59, -72, -78,
+ -70, -54, -40, -28, -19, -8, 10, 28, 45, 53, 57, 53, 43, 34, 28, 27,
+ 26, 18, 0, -18, -31, -29, -20, -11, -3, 2, 5, 10, 19, 31, 43, 44,
+ 34, 19, 2, -13, -23, -32, -43, -55, -68, -77, -73, -57, -41, -26, -15, -6,
+ 11, 28, 43, 52, 52, 49, 41, 33, 24, 22, 21, 14, 1, -14, -25, -24,
+ -18, -7, -2, 2, 7, 10, 20, 31, 40, 43, 33, 18, 3, -13, -24, -35,
+ -44, -55, -70, -78, -74, -59, -40, -26, -11, 1, 13, 29, 44, 53, 57, 54,
+ 45, 32, 24, 18, 13, 9, -4, -16, -26, -29, -22, -10, 1, 8, 13, 18,
+ 23, 35, 42, 45, 37, 21, 5, -14, -30, -41, -49, -57, -69, -77, -76, -61,
+ -39, -20, -5, 9, 20, 34, 47, 53, 55, 48, 39, 27, 14, 8, 3, 2,
+ -4, -15, -23, -24, -16, -3, 6, 11, 19, 24, 30, 34, 41, 43, 35, 18,
+ 1, -17, -31, -44, -52, -59, -68, -75, -73, -61, -38, -19, 1, 13, 23, 30,
+ 42, 52, 52, 47, 36, 23, 14, 7, 4, 0, -6, -11, -20, -24, -18, -5,
+ 7, 15, 18, 22, 28, 36, 43, 43, 38, 24, 4, -13, -30, -44, -55, -64,
+ -69, -77, -76, -65, -44, -19, 1, 15, 27, 35, 46, 53, 53, 46, 36, 23,
+ 11, 3, -5, -7, -9, -14, -20, -23, -19, -7, 11, 18, 21, 25, 30, 40,
+ 43, 43, 38, 24, 7, -14, -30, -41, -55, -65, -73, -77, -74, -66, -49, -24,
+ -2, 17, 29, 35, 44, 51, 54, 49, 35, 23, 11, 1, -6, -12, -15, -16,
+ -20, -24, -21, -10, 8, 21, 27, 33, 35, 42, 48, 47, 37, 23, 7, -12,
+ -28, -44, -60, -69, -75, -78, -74, -65, -49, -25, -2, 17, 30, 40, 48, 54,
+ 55, 48, 36, 20, 6, -4, -9, -14, -20, -22, -24, -21, -15, -6, 7, 21,
+ 32, 39, 43, 44, 49, 50, 38, 21, 4, -13, -28, -47, -62, -74, -77, -78,
+ -77, -65, -48, -26, -4, 15, 28, 40, 50, 56, 54, 46, 33, 20, 9, -2,
+ -10, -16, -21, -21, -23, -21, -15, -5, 9, 19, 30, 38, 42, 44, 46, 47,
+ 36, 22, 6, -10, -23, -39, -57, -74, -78, -79, -75, -65, -51, -33, -11, 9,
+ 25, 37, 46, 55, 56, 48, 34, 21, 10, 4, -4, -14, -20, -25, -24, -21,
+ -12, -3, 8, 17, 26, 36, 47, 50, 50, 47, 36, 25, 10, -5, -21, -40,
+ -57, -75, -82, -79, -75, -64, -51, -37, -16, 5, 25, 40, 48, 55, 55, 49,
+ 37, 25, 15, 6, -6, -18, -26, -29, -25, -20, -16, -7, 5, 17, 29, 39,
+ 49, 56, 56, 51, 39, 28, 15, 0, -17, -38, -58, -75, -86, -86, -80, -70,
+ -54, -37, -16, 7, 25, 42, 50, 55, 58, 52, 40, 25, 11, 2, -5, -14,
+ -21, -26, -26, -18, -12, -5, 4, 13, 25, 34, 45, 53, 55, 48, 39, 25,
+ 16, 3, -13, -31, -54, -70, -83, -85, -78, -68, -55, -38, -20, 1, 20, 36,
+ 46, 51, 55, 48, 39, 27, 17, 7, -5, -13, -20, -23, -23, -18, -10, -4,
+ 3, 10, 21, 29, 40, 48, 52, 50, 40, 28, 20, 10, -5, -24, -48, -67,
+ -82, -87, -81, -73, -56, -44, -25, -5, 15, 34, 46, 52, 55, 51, 39, 27,
+ 18, 7, -2, -13, -22, -25, -24, -16, -9, 1, 8, 13, 22, 30, 42, 48,
+ 50, 47, 38, 26, 15, 6, -8, -22, -41, -61, -77, -86, -81, -70, -54, -40,
+ -27, -8, 12, 31, 42, 49, 50, 48, 38, 26, 16, 7, -4, -11, -18, -22,
+ -21, -16, -9, 0, 9, 15, 21, 26, 35, 47, 50, 46, 36, 28, 18, 7,
+ -7, -22, -37, -53, -70, -81, -83, -72, -58, -43, -30, -14, 5, 22, 37, 44,
+ 46, 44, 37, 26, 17, 8, 2, -7, -12, -17, -16, -12, -6, 3, 8, 13,
+ 17, 22, 31, 42, 43, 43, 35, 29, 25, 14, 2, -17, -35, -51, -65, -77,
+ -80, -75, -63, -47, -34, -18, 4, 21, 32, 38, 41, 41, 36, 28, 17, 8,
+ 1, -9, -12, -16, -15, -9, -2, 8, 13, 15, 17, 23, 28, 39, 43, 38,
+ 30, 21, 17, 11, 4, -12, -28, -45, -60, -68, -71, -66, -58, -49, -38, -23,
+ -5, 15, 27, 34, 34, 32, 28, 23, 18, 13, 4, -2, -7, -9, -7, -4,
+ 5, 14, 16, 16, 14, 15, 24, 35, 39, 35, 23, 17, 15, 11, 8, -4,
+ -19, -37, -53, -62, -65, -62, -57, -53, -43, -31, -14, 5, 19, 27, 31, 28,
+ 26, 23, 20, 18, 11, 5, -2, -5, 0, 3, 8, 14, 16, 15, 11, 7,
+ 12, 23, 32, 32, 21, 12, 10, 13, 12, 6, -9, -27, -43, -50, -55, -53,
+ -51, -52, -44, -38, -23, -6, 7, 18, 22, 19, 16, 15, 16, 19, 17, 12,
+ 6, 3, 7, 10, 16, 20, 23, 20, 14, 8, 9, 17, 27, 26, 17, 6,
+ 3, 7, 10, 7, -5, -18, -32, -41, -46, -45, -45, -45, -44, -40, -30, -16,
+ -3, 8, 15, 12, 10, 11, 16, 19, 19, 16, 12, 10, 11, 15, 20, 25,
+ 26, 24, 18, 11, 6, 11, 17, 21, 15, 3, -6, -2, 4, 7, 2, -14,
+ -25, -32, -36, -38, -37, -37, -35, -33, -33, -25, -15, -4, 3, 4, 0, -3,
+ 2, 13, 21, 21, 20, 17, 19, 23, 27, 31, 33, 31, 24, 16, 4, 2,
+ 7, 13, 13, 3, -10, -9, 0, 8, 7, -3, -15, -22, -24, -30, -32, -37,
+ -39, -38, -37, -34, -28, -17, -8, -2, -4, -4, 4, 16, 26, 30, 26, 22,
+ 22, 25, 29, 31, 30, 29, 24, 17, 6, -2, 7, 10, 13, 4, -11, -15,
+ -10, 3, 8, 2, -10, -17, -17, -17, -23, -29, -35, -37, -34, -36, -35, -28,
+ -19, -10, -11, -14, -8, 8, 21, 26, 26, 21, 24, 31, 38, 40, 38, 37,
+ 33, 26, 15, 4, 1, 2, 1, -6, -19, -24, -18, -7, 2, 5, -4, -10,
+ -9, -6, -7, -16, -27, -33, -35, -38, -41, -38, -32, -22, -20, -18, -10, 4,
+ 20, 29, 31, 30, 28, 32, 38, 43, 42, 39, 34, 28, 14, 4, 1, 3,
+ 4, -5, -21, -30, -26, -14, 1, 3, -4, -8, -8, 0, 0, -8, -15, -26,
+ -29, -35, -40, -40, -36, -30, -28, -29, -22, -10, 9, 22, 28, 28, 27, 30,
+ 39, 46, 50, 50, 43, 33, 21, 9, 3, 3, 1, -10, -22, -35, -34, -22,
+ -8, 2, 0, -6, -7, 0, 5, -2, -9, -18, -28, -34, -41, -43, -39, -35,
+ -33, -33, -25, -12, 5, 19, 26, 29, 31, 31, 39, 46, 51, 52, 47, 38,
+ 27, 18, 10, 5, -3, -13, -22, -33, -36, -28, -16, -4, -2, -4, -6, 0,
+ 8, 7, 0, -12, -22, -33, -40, -42, -39, -37, -38, -39, -32, -17, 2, 15,
+ 24, 25, 28, 33, 39, 47, 51, 53, 51, 44, 35, 23, 15, 8, 1, -12,
+ -25, -37, -41, -33, -22, -11, -4, -5, -3, 3, 10, 13, 6, -5, -17, -28,
+ -38, -43, -44, -44, -44, -43, -36, -23, -7, 7, 20, 26, 29, 35, 43, 51,
+ 54, 58, 56, 52, 44, 29, 18, 9, -2, -12, -28, -39, -45, -38, -26, -16,
+ -7, -3, 1, 6, 12, 15, 12, 3, -11, -25, -37, -41, -43, -46, -47, -46,
+ -39, -28, -15, 0, 11, 21, 25, 31, 38, 46, 53, 60, 62, 59, 53, 42,
+ 32, 19, 6, -10, -27, -41, -47, -47, -39, -31, -21, -9, -2, 5, 11, 16,
+ 19, 13, 2, -15, -30, -35, -37, -43, -47, -49, -42, -32, -21, -11, 0, 8,
+ 19, 27, 38, 47, 51, 58, 63, 63, 59, 50, 41, 28, 10, -9, -26, -37,
+ -43, -44, -40, -33, -23, -11, 0, 6, 9, 14, 15, 13, 1, -15, -25, -32,
+ -34, -43, -49, -50, -43, -30, -20, -13, -9, 0, 10, 23, 36, 46, 52, 55,
+ 62, 65, 66, 61, 51, 36, 15, -7, -24, -34, -42, -45, -46, -42, -34, -20,
+ -5, 5, 11, 14, 16, 13, 2, -10, -18, -24, -31, -39, -49, -48, -42, -34,
+ -24, -18, -15, -8, 2, 13, 29, 42, 51, 57, 62, 65, 70, 69, 60, 45,
+ 20, -3, -24, -37, -43, -46, -49, -48, -39, -24, -6, 5, 12, 17, 20, 16,
+ 6, -9, -15, -21, -26, -38, -50, -56, -50, -37, -26, -23, -19, -14, -4, 11,
+ 27, 42, 54, 58, 63, 65, 68, 70, 63, 50, 26, 1, -21, -37, -43, -44,
+ -44, -44, -40, -28, -11, 5, 10, 16, 18, 14, 5, -12, -19, -22, -24, -33,
+ -47, -52, -52, -38, -25, -17, -17, -16, -10, 4, 22, 39, 53, 59, 62, 63,
+ 66, 68, 66, 55, 32, 9, -17, -34, -43, -42, -39, -38, -38, -31, -19, -3,
+ 10, 17, 19, 12, 3, -12, -21, -24, -24, -31, -40, -49, -52, -41, -30, -18,
+ -15, -17, -10, 0, 16, 33, 47, 59, 65, 64, 65, 67, 63, 56, 38, 13,
+ -12, -32, -41, -39, -35, -33, -32, -27, -17, -4, 8, 15, 16, 13, 4, -11,
+ -20, -25, -27, -32, -40, -48, -52, -46, -37, -25, -18, -16, -10, 1, 16, 33,
+ 49, 59, 66, 67, 65, 66, 62, 51, 38, 15, -9, -30, -38, -41, -33, -29,
+ -26, -23, -17, -5, 7, 16, 15, 14, 5, -9, -19, -27, -31, -34, -40, -47,
+ -52, -49, -40, -30, -22, -16, -8, 4, 19, 32, 46, 59, 67, 71, 69, 64,
+ 57, 49, 36, 17, -7, -27, -38, -40, -35, -28, -23, -19, -12, -5, 6, 12,
+ 16, 15, 10, -5, -19, -28, -32, -36, -39, -46, -53, -52, -45, -34, -25, -18,
+ -7, 6, 20, 33, 46, 60, 67, 74, 71, 65, 56, 46, 37, 18, -2, -20,
+ -33, -38, -38, -30, -22, -16, -12, -6, 2, 6, 15, 15, 11, 1, -11, -19,
+ -31, -37, -42, -46, -51, -54, -53, -46, -35, -26, -14, 3, 17, 33, 45, 57,
+ 67, 75, 77, 71, 62, 50, 36, 18, 0, -19, -31, -36, -37, -31, -23, -17,
+ -11, -6, 1, 6, 11, 15, 14, 8, -3, -16, -27, -37, -41, -47, -52, -58,
+ -60, -55, -46, -32, -16, 0, 17, 32, 46, 59, 70, 79, 80, 75, 65, 51,
+ 35, 20, 2, -15, -27, -38, -42, -36, -27, -17, -10, -4, 3, 7, 12, 18,
+ 19, 14, 5, -7, -22, -37, -46, -53, -57, -62, -67, -65, -58, -43, -22, 1,
+ 20, 35, 48, 60, 69, 79, 82, 79, 68, 53, 36, 21, 4, -11, -24, -36,
+ -40, -38, -31, -21, -14, -5, 1, 5, 11, 17, 22, 19, 14, -2, -17, -35,
+ -48, -55, -63, -67, -73, -72, -64, -49, -27, -4, 19, 36, 52, 64, 73, 81,
+ 85, 82, 72, 56, 36, 20, 3, -14, -24, -33, -36, -35, -32, -22, -13, -6,
+ 2, 7, 10, 15, 19, 19, 17, 6, -10, -29, -48, -58, -67, -71, -75, -78,
+ -72, -58, -35, -10, 16, 35, 52, 65, 74, 80, 86, 87, 79, 62, 39, 21,
+ 5, -11, -22, -33, -39, -39, -34, -25, -15, -7, 3, 8, 16, 17, 21, 22,
+ 19, 9, -6, -27, -47, -60, -71, -77, -80, -81, -73, -61, -39, -12, 16, 36,
+ 52, 63, 73, 80, 85, 87, 76, 59, 41, 23, 8, -7, -18, -29, -36, -38,
+ -33, -23, -13, -8, 1, 6, 14, 18, 19, 23, 23, 17, 1, -20, -43, -57,
+ -67, -78, -83, -89, -81, -67, -45, -19, 9, 35, 55, 67, 74, 80, 87, 91,
+ 83, 68, 44, 24, 6, -9, -21, -29, -36, -39, -39, -31, -20, -10, 1, 13,
+ 20, 26, 26, 27, 28, 22, 8, -16, -40, -60, -75, -86, -93, -95, -89, -75,
+ -52, -24, 7, 37, 57, 69, 77, 83, 90, 93, 85, 70, 48, 27, 8, -8,
+ -19, -26, -32, -35, -39, -37, -28, -17, -2, 9, 19, 21, 27, 31, 32, 29,
+ 12, -9, -32, -54, -71, -86, -94, -96, -90, -82, -62, -33, 2, 34, 56, 69,
+ 78, 87, 94, 94, 85, 69, 49, 29, 9, -10, -21, -27, -30, -33, -37, -36,
+ -29, -17, -5, 9, 19, 25, 27, 31, 33, 33, 21, -2, -25, -51, -71, -86,
+ -95, -95, -92, -85, -69, -42, -8, 27, 52, 67, 74, 83, 92, 95, 89, 75,
+ 56, 35, 16, -6, -17, -26, -28, -34, -41, -39, -37, -25, -9, 6, 20, 28,
+ 31, 37, 37, 34, 24, 3, -20, -46, -69, -85, -96, -99, -97, -89, -73, -47,
+ -11, 21, 45, 61, 73, 84, 92, 95, 89, 77, 61, 41, 20, -2, -13, -20,
+ -28, -36, -43, -46, -40, -30, -16, 0, 12, 24, 30, 38, 43, 41, 33, 13,
+ -14, -39, -63, -80, -93, -98, -100, -94, -76, -52, -19, 14, 38, 56, 70, 80,
+ 90, 94, 88, 75, 58, 40, 22, 6, -8, -19, -25, -33, -39, -41, -38, -31,
+ -19, -5, 7, 21, 31, 39, 45, 42, 32, 15, -8, -32, -55, -77, -93, -102,
+ -101, -94, -80, -57, -29, 5, 34, 54, 70, 78, 88, 96, 92, 80, 62, 41,
+ 24, 8, -9, -21, -32, -35, -38, -41, -39, -35, -22, -6, 6, 21, 31, 39,
+ 46, 44, 35, 18, -5, -27, -49, -70, -86, -97, -102, -96, -84, -58, -30, -2,
+ 26, 45, 62, 74, 82, 89, 89, 80, 66, 46, 28, 12, -3, -14, -26, -36,
+ -39, -42, -40, -36, -28, -15, 0, 17, 30, 37, 45, 48, 40, 23, 3, -20,
+ -43, -64, -81, -93, -98, -96, -85, -65, -38, -8, 20, 40, 55, 68, 80, 88,
+ 88, 82, 68, 54, 35, 18, 2, -12, -24, -35, -40, -45, -45, -41, -33, -20,
+ -4, 15, 31, 41, 49, 52, 48, 32, 13, -14, -38, -59, -77, -92, -101, -102,
+ -91, -70, -45, -15, 15, 38, 53, 65, 77, 89, 91, 85, 71, 52, 38, 21,
+ 5, -12, -26, -36, -42, -45, -45, -43, -34, -22, -7, 9, 26, 39, 50, 56,
+ 50, 34, 14, -7, -29, -50, -69, -84, -96, -98, -90, -72, -50, -24, 7, 32,
+ 48, 57, 68, 84, 91, 88, 74, 58, 44, 30, 11, -9, -26, -38, -41, -46,
+ -45, -44, -38, -23, -7, 9, 24, 36, 49, 55, 51, 35, 18, -3, -24, -45,
+ -64, -78, -89, -93, -90, -75, -54, -29, 0, 23, 42, 54, 67, 80, 90, 91,
+ 81, 65, 48, 31, 13, -5, -24, -41, -50, -53, -51, -46, -42, -28, -10, 8,
+ 23, 36, 50, 59, 56, 44, 26, 8, -13, -35, -56, -77, -89, -94, -92, -80,
+ -61, -39, -11, 14, 33, 50, 63, 77, 88, 89, 81, 67, 54, 38, 21, 1,
+ -23, -39, -50, -54, -53, -46, -42, -31, -17, 1, 17, 33, 46, 56, 56, 46,
+ 33, 16, -4, -24, -46, -67, -82, -92, -94, -87, -67, -45, -19, 4, 22, 43,
+ 62, 76, 87, 90, 87, 76, 59, 40, 20, 1, -22, -40, -55, -62, -58, -50,
+ -40, -29, -17, -3, 14, 33, 49, 59, 58, 49, 35, 21, 2, -17, -39, -59,
+ -76, -90, -93, -86, -70, -49, -29, -8, 12, 33, 57, 75, 84, 87, 84, 78,
+ 65, 47, 28, 6, -18, -39, -58, -65, -64, -57, -44, -33, -22, -10, 6, 26,
+ 44, 56, 56, 48, 40, 27, 11, -8, -30, -49, -65, -80, -86, -87, -72, -51,
+ -31, -13, 5, 24, 48, 70, 81, 86, 83, 79, 69, 51, 30, 8, -16, -37,
+ -55, -65, -67, -61, -48, -36, -21, -10, 5, 22, 40, 55, 58, 53, 43, 31,
+ 16, -2, -23, -45, -60, -74, -82, -86, -75, -56, -36, -16, 1, 21, 44, 65,
+ 81, 88, 85, 81, 72, 54, 33, 8, -18, -41, -58, -71, -74, -70, -56, -41,
+ -23, -6, 8, 23, 38, 53, 60, 59, 50, 37, 22, 1, -20, -41, -56, -69,
+ -79, -83, -78, -62, -42, -20, 2, 22, 41, 59, 77, 86, 87, 79, 67, 50,
+ 31, 10, -15, -36, -52, -63, -69, -69, -59, -41, -23, -9, 4, 15, 29, 44,
+ 55, 56, 53, 43, 27, 12, -8, -27, -44, -57, -68, -78, -77, -67, -48, -29,
+ -12, 12, 32, 52, 70, 79, 84, 82, 73, 59, 38, 15, -9, -33, -52, -63,
+ -71, -72, -66, -50, -30, -13, 2, 12, 27, 42, 50, 54, 54, 46, 34, 19,
+ -2, -19, -35, -47, -61, -71, -72, -66, -51, -36, -19, 5, 27, 46, 63, 74,
+ 79, 79, 70, 58, 41, 21, 3, -24, -44, -58, -66, -66, -65, -52, -36, -22,
+ -10, 4, 18, 34, 43, 49, 52, 48, 43, 31, 14, -4, -21, -35, -51, -61,
+ -66, -64, -56, -43, -29, -8, 16, 37, 54, 67, 72, 74, 70, 61, 46, 27,
+ 7, -19, -40, -56, -62, -62, -63, -55, -43, -26, -10, 3, 13, 26, 38, 44,
+ 47, 43, 39, 30, 19, 5, -12, -24, -40, -47, -51, -53, -51, -44, -32, -14,
+ 6, 24, 41, 54, 61, 63, 61, 56, 47, 32, 13, -9, -31, -46, -56, -53,
+ -54, -54, -48, -37, -18, -3, 8, 17, 27, 33, 38, 39, 39, 37, 30, 18,
+ 1, -16, -29, -35, -39, -42, -47, -47, -39, -22, -3, 14, 29, 42, 51, 57,
+ 56, 54, 45, 36, 20, -2, -23, -41, -50, -51, -52, -53, -51, -42, -27, -8,
+ 5, 12, 19, 28, 35, 40, 39, 40, 37, 28, 12, -7, -23, -28, -30, -37,
+ -43, -49, -45, -32, -15, 3, 19, 34, 45, 49, 49, 51, 47, 41, 26, 6,
+ -18, -34, -43, -45, -45, -48, -51, -49, -33, -15, -2, 8, 12, 19, 26, 33,
+ 38, 38, 38, 34, 25, 8, -11, -19, -20, -23, -32, -43, -48, -41, -24, -8,
+ 10, 21, 31, 38, 43, 47, 48, 45, 34, 16, -9, -31, -41, -42, -42, -46,
+ -52, -52, -40, -23, -6, 6, 11, 17, 24, 30, 35, 38, 39, 40, 29, 14,
+ -3, -14, -14, -15, -24, -36, -47, -45, -33, -15, 3, 14, 23, 29, 35, 39,
+ 44, 45, 38, 22, -3, -26, -38, -37, -37, -41, -50, -56, -45, -26, -8, 5,
+ 12, 16, 22, 27, 32, 39, 41, 41, 33, 17, 1, -9, -8, -8, -16, -30,
+ -41, -45, -35, -21, -5, 10, 18, 24, 28, 31, 38, 42, 39, 25, 2, -23,
+ -36, -36, -37, -39, -47, -53, -47, -31, -11, 3, 12, 16, 23, 27, 32, 37,
+ 40, 41, 33, 18, 2, -7, -8, -6, -10, -23, -36, -41, -35, -20, -6, 7,
+ 14, 17, 24, 29, 36, 42, 40, 28, 5, -20, -35, -38, -38, -39, -45, -51,
+ -46, -33, -15, 2, 13, 22, 27, 28, 27, 30, 37, 41, 35, 20, 5, -4,
+ -4, -2, -3, -13, -28, -35, -32, -23, -10, 3, 11, 14, 14, 20, 28, 37,
+ 40, 27, 7, -16, -31, -36, -37, -36, -41, -44, -45, -35, -18, 1, 12, 19,
+ 25, 26, 27, 31, 34, 39, 34, 20, 8, 0, 0, 1, 0, -9, -23, -33,
+ -34, -24, -10, 2, 8, 8, 10, 16, 27, 34, 35, 27, 10, -10, -27, -35,
+ -35, -34, -39, -46, -47, -38, -22, -3, 10, 19, 26, 31, 32, 32, 35, 41,
+ 39, 25, 9, -2, -3, -2, -2, -7, -19, -30, -33, -26, -14, -3, 6, 6,
+ 7, 12, 26, 37, 37, 26, 10, -8, -25, -35, -39, -39, -42, -47, -49, -42,
+ -27, -4, 12, 20, 29, 33, 36, 35, 35, 38, 37, 27, 10, -3, -6, -3,
+ -2, -7, -16, -24, -28, -24, -13, -4, 4, 5, 7, 9, 19, 30, 33, 28,
+ 12, -6, -24, -35, -40, -39, -42, -47, -47, -41, -26, -8, 10, 22, 31, 36,
+ 41, 39, 34, 33, 33, 29, 15, 2, -7, -8, -6, -6, -10, -18, -24, -24,
+ -15, -5, 6, 7, 7, 10, 17, 23, 23, 18, 9, -7, -23, -36, -42, -41,
+ -41, -45, -45, -39, -28, -11, 7, 21, 31, 36, 39, 39, 34, 31, 33, 29,
+ 19, 7, -5, -6, -6, -4, -6, -13, -17, -20, -16, -8, 1, 6, 7, 7,
+ 11, 16, 20, 18, 9, -7, -24, -37, -43, -42, -42, -42, -45, -41, -28, -11,
+ 7, 19, 28, 35, 40, 42, 38, 33, 29, 27, 21, 10, -2, -8, -8, -6,
+ -8, -11, -13, -16, -14, -8, 1, 5, 8, 9, 15, 19, 20, 18, 9, -4,
+ -18, -34, -42, -46, -47, -45, -47, -45, -36, -20, 0, 13, 26, 36, 45, 48,
+ 42, 35, 29, 28, 26, 20, 6, -6, -10, -10, -6, -7, -8, -10, -14, -10,
+ -7, 0, 6, 8, 13, 14, 16, 13, 7, -3, -13, -27, -37, -44, -49, -44,
+ -42, -40, -37, -25, -9, 9, 23, 31, 41, 44, 44, 37, 30, 27, 28, 27,
+ 15, 2, -7, -9, -6, -7, -9, -8, -13, -12, -8, -3, 4, 9, 13, 14,
+ 14, 11, 6, 0, -9, -23, -34, -43, -49, -46, -42, -40, -35, -29, -13, 3,
+ 19, 31, 41, 45, 43, 37, 31, 29, 30, 28, 19, 4, -5, -7, -7, -5,
+ -8, -7, -9, -11, -9, -4, 0, 6, 12, 14, 13, 9, 5, -3, -9, -19,
+ -28, -37, -48, -48, -45, -39, -34, -30, -18, -5, 12, 23, 34, 42, 44, 39,
+ 34, 32, 31, 33, 30, 18, 8, 1, -5, -6, -5, -5, -8, -13, -16, -14,
+ -7, 2, 7, 11, 10, 7, 4, -2, -7, -12, -22, -32, -45, -50, -45, -38,
+ -33, -30, -24, -13, 2, 20, 31, 39, 43, 42, 38, 36, 33, 33, 33, 24,
+ 14, 1, -8, -9, -7, -4, -5, -11, -16, -16, -11, -4, 2, 9, 8, 7,
+ 3, -3, -6, -9, -15, -24, -38, -47, -48, -42, -35, -32, -29, -21, -9, 11,
+ 27, 35, 42, 42, 42, 40, 40, 38, 36, 30, 19, 8, -4, -9, -8, -5,
+ -5, -12, -18, -20, -15, -5, -2, 3, 4, 5, 6, 1, -3, -8, -12, -19,
+ -31, -43, -47, -43, -36, -35, -36, -32, -19, 2, 19, 30, 38, 42, 46, 49,
+ 50, 47, 43, 39, 28, 16, 1, -10, -13, -11, -9, -14, -21, -25, -20, -10,
+ -4, 1, 3, 4, 7, 4, -3, -7, -7, -10, -23, -38, -47, -46, -41, -37,
+ -38, -37, -27, -11, 11, 24, 33, 38, 45, 50, 53, 52, 48, 43, 37, 25,
+ 10, -3, -11, -11, -11, -13, -20, -27, -29, -22, -14, -7, -2, 2, 6, 3,
+ -2, -3, 0, 0, -11, -28, -41, -45, -39, -35, -36, -39, -37, -24, -7, 11,
+ 22, 32, 41, 51, 55, 56, 54, 53, 50, 40, 23, 6, -5, -10, -11, -14,
+ -20, -28, -34, -33, -25, -16, -10, -5, 0, 0, 1, 2, 4, 5, -4, -16,
+ -29, -35, -37, -37, -35, -39, -39, -32, -19, 0, 13, 23, 36, 46, 54, 58,
+ 57, 59, 56, 47, 33, 16, 3, -5, -9, -11, -19, -29, -36, -39, -33, -26,
+ -18, -12, -7, -5, -2, 4, 11, 15, 10, -3, -18, -29, -32, -35, -36, -41,
+ -44, -40, -30, -18, 0, 13, 28, 41, 50, 59, 63, 66, 66, 60, 44, 26,
+ 11, 2, -6, -12, -19, -29, -38, -44, -41, -33, -25, -16, -9, -8, -6, 1,
+ 11, 18, 16, 8, -6, -17, -27, -32, -36, -39, -43, -44, -37, -30, -12, 8,
+ 26, 39, 46, 56, 64, 70, 72, 66, 51, 36, 18, 7, -4, -11, -18, -29,
+ -42, -50, -51, -45, -35, -23, -14, -10, -9, 0, 14, 27, 29, 20, 7, -5,
+ -15, -23, -30, -38, -45, -50, -49, -43, -30, -9, 13, 31, 41, 52, 65, 75,
+ 79, 77, 66, 50, 30, 13, 3, -6, -14, -26, -41, -53, -57, -54, -44, -32,
+ -23, -17, -13, -5, 10, 24, 31, 28, 20, 9, -5, -17, -26, -35, -40, -48,
+ -54, -53, -44, -23, 0, 21, 35, 46, 60, 73, 81, 83, 77, 60, 42, 25,
+ 11, 1, -11, -25, -42, -57, -64, -62, -54, -43, -33, -24, -17, -6, 9, 23,
+ 37, 37, 33, 19, 6, -9, -20, -30, -41, -49, -57, -59, -54, -38, -16, 10,
+ 31, 46, 58, 70, 78, 85, 84, 73, 54, 32, 16, 5, -5, -22, -41, -60,
+ -72, -71, -66, -54, -43, -30, -19, -6, 10, 25, 41, 47, 43, 32, 20, 7,
+ -10, -25, -40, -52, -61, -68, -65, -54, -34, -11, 16, 39, 57, 72, 80, 88,
+ 91, 83, 67, 46, 28, 13, 1, -18, -40, -62, -77, -77, -70, -63, -54, -43,
+ -30, -12, 7, 25, 40, 51, 51, 42, 31, 19, 3, -13, -32, -48, -60, -68,
+ -71, -63, -49, -28, -2, 23, 46, 66, 77, 86, 92, 89, 82, 62, 43, 22,
+ 7, -12, -39, -59, -74, -80, -78, -72, -63, -50, -35, -17, 5, 22, 35, 45,
+ 49, 49, 42, 31, 13, -7, -25, -38, -49, -59, -66, -65, -57, -42, -20, 8,
+ 34, 55, 69, 79, 84, 84, 84, 77, 64, 42, 18, -6, -29, -49, -69, -82,
+ -87, -87, -78, -66, -48, -27, -4, 17, 33, 47, 56, 60, 58, 49, 31, 8,
+ -18, -36, -47, -57, -67, -75, -74, -60, -36, -3, 25, 48, 65, 76, 83, 87,
+ 90, 88, 77, 52, 24, -4, -26, -42, -61, -77, -91, -94, -85, -70, -54, -34,
+ -11, 12, 30, 44, 56, 63, 66, 61, 43, 19, -8, -27, -39, -49, -62, -74,
+ -80, -71, -49, -20, 9, 34, 56, 70, 79, 86, 93, 96, 91, 70, 41, 11,
+ -18, -39, -58, -77, -91, -99, -95, -83, -65, -42, -17, 7, 27, 43, 57, 66,
+ 69, 67, 55, 32, 5, -21, -32, -42, -56, -73, -84, -79, -60, -33, -5, 21,
+ 44, 61, 72, 80, 92, 100, 99, 82, 54, 23, -10, -31, -51, -71, -87, -101,
+ -101, -92, -76, -49, -24, 1, 21, 37, 52, 66, 72, 72, 64, 44, 18, -7,
+ -23, -31, -45, -64, -79, -83, -71, -46, -18, 7, 27, 46, 62, 72, 85, 97,
+ 100, 92, 65, 35, 2, -22, -40, -60, -78, -92, -100, -96, -82, -59, -29, -6,
+ 15, 28, 44, 57, 65, 67, 65, 49, 27, 2, -17, -23, -35, -53, -70, -79,
+ -73, -52, -27, -4, 16, 35, 54, 65, 77, 88, 95, 93, 73, 44, 12, -17,
+ -38, -54, -74, -86, -97, -98, -89, -69, -37, -11, 9, 27, 42, 56, 65, 68,
+ 71, 59, 39, 13, -9, -20, -30, -45, -62, -74, -75, -60, -41, -18, 3, 23,
+ 43, 60, 74, 83, 91, 91, 78, 52, 22, -8, -30, -46, -66, -82, -90, -92,
+ -85, -70, -44, -17, 5, 22, 33, 45, 56, 60, 63, 56, 39, 21, 5, -9,
+ -20, -33, -49, -62, -70, -62, -47, -28, -9, 11, 29, 47, 60, 73, 83, 87,
+ 81, 62, 32, 4, -21, -39, -60, -78, -88, -90, -86, -73, -55, -28, -2, 18,
+ 30, 42, 50, 57, 58, 53, 44, 27, 15, 4, -10, -24, -40, -53, -59, -57,
+ -49, -38, -21, -3, 17, 34, 49, 62, 75, 81, 76, 63, 39, 15, -11, -31,
+ -50, -69, -79, -84, -82, -73, -57, -34, -7, 12, 26, 35, 42, 50, 56, 53,
+ 42, 31, 20, 13, 1, -16, -30, -43, -50, -51, -49, -42, -28, -11, 7, 23,
+ 38, 52, 65, 75, 73, 62, 43, 20, -2, -24, -43, -60, -69, -74, -74, -69,
+ -59, -42, -19, 2, 19, 27, 34, 41, 48, 50, 45, 39, 33, 25, 13, -3,
+ -18, -32, -42, -47, -49, -47, -40, -27, -8, 11, 28, 43, 57, 69, 73, 65,
+ 50, 31, 8, -16, -36, -53, -63, -70, -72, -70, -62, -46, -25, -6, 11, 23,
+ 30, 38, 45, 49, 50, 46, 42, 33, 22, 6, -13, -25, -37, -43, -48, -50,
+ -45, -35, -18, 2, 21, 39, 51, 61, 64, 63, 53, 38, 19, -6, -30, -49,
+ -59, -63, -65, -66, -64, -52, -31, -14, 2, 13, 25, 35, 42, 46, 46, 47,
+ 48, 44, 33, 15, -6, -21, -32, -37, -42, -48, -46, -39, -26, -8, 12, 31,
+ 45, 55, 58, 57, 51, 39, 22, 2, -21, -39, -49, -56, -59, -62, -59, -52,
+ -38, -22, -9, 5, 16, 25, 32, 40, 46, 51, 54, 52, 40, 24, 5, -11,
+ -20, -28, -35, -44, -48, -43, -33, -17, 0, 18, 32, 44, 48, 49, 48, 40,
+ 28, 11, -10, -26, -37, -45, -52, -58, -57, -51, -41, -29, -19, -10, 3, 15,
+ 27, 36, 40, 50, 59, 60, 51, 33, 15, 2, -11, -21, -34, -45, -49, -45,
+ -36, -25, -11, 8, 26, 38, 43, 42, 41, 39, 31, 16, -5, -24, -31, -37,
+ -43, -51, -54, -49, -40, -31, -24, -13, -3, 12, 22, 29, 33, 43, 55, 60,
+ 53, 37, 18, 5, -4, -12, -23, -35, -44, -42, -35, -26, -15, -2, 15, 26,
+ 33, 31, 31, 29, 28, 21, 6, -13, -27, -30, -37, -44, -48, -45, -39, -34,
+ -28, -18, -8, 4, 17, 23, 31, 40, 51, 58, 56, 42, 25, 12, 2, -7,
+ -16, -27, -36, -39, -37, -31, -21, -12, 3, 14, 21, 25, 23, 23, 25, 23,
+ 11, -4, -16, -21, -26, -34, -39, -40, -34, -31, -30, -23, -17, -3, 9, 16,
+ 23, 31, 42, 54, 57, 49, 29, 14, 7, 4, -3, -15, -26, -32, -32, -31,
+ -24, -16, -5, 5, 8, 10, 9, 10, 16, 19, 14, 4, -8, -14, -16, -21,
+ -29, -34, -33, -30, -29, -26, -20, -10, 2, 11, 20, 28, 40, 51, 55, 51,
+ 33, 17, 9, 6, 4, -9, -20, -28, -32, -29, -25, -20, -11, -2, 3, 4,
+ 1, 6, 12, 18, 16, 8, -5, -10, -14, -17, -20, -23, -25, -26, -28, -26,
+ -21, -12, -2, 6, 13, 20, 29, 40, 48, 48, 37, 23, 13, 8, 7, 3,
+ -6, -15, -22, -24, -24, -21, -16, -10, -6, -11, -15, -10, 1, 12, 15, 9,
+ 4, 3, 1, -5, -11, -18, -18, -22, -25, -29, -27, -19, -7, 4, 10, 14,
+ 21, 35, 46, 48, 40, 27, 16, 13, 11, 11, 5, -5, -14, -19, -21, -24,
+ -19, -14, -13, -17, -21, -21, -11, 1, 11, 12, 5, 3, 2, 5, 6, 0,
+ -6, -16, -20, -25, -26, -20, -12, -4, 1, 5, 11, 25, 38, 46, 41, 33,
+ 21, 17, 15, 15, 14, 8, -3, -14, -23, -27, -26, -21, -20, -22, -26, -25,
+ -20, -7, 5, 10, 10, 8, 5, 6, 6, 5, 1, -7, -14, -20, -23, -21,
+ -17, -11, -4, 2, 7, 17, 29, 38, 40, 37, 30, 23, 21, 20, 17, 14,
+ 5, -6, -19, -26, -29, -25, -24, -27, -28, -28, -26, -18, -4, 6, 9, 8,
+ 4, 5, 10, 12, 11, 3, -8, -15, -18, -18, -15, -11, -10, -5, 1, 8,
+ 16, 26, 35, 35, 31, 24, 22, 21, 22, 21, 16, 5, -12, -24, -30, -31,
+ -29, -31, -32, -31, -32, -22, -12, 0, 7, 11, 12, 10, 11, 15, 13, 10,
+ 2, -10, -13, -16, -17, -14, -14, -12, -6, 0, 10, 20, 26, 32, 30, 29,
+ 27, 26, 28, 26, 22, 13, -2, -16, -25, -30, -32, -33, -35, -35, -34, -28,
+ -19, -12, -5, 1, 5, 9, 11, 16, 17, 18, 11, 3, -4, -10, -12, -13,
+ -12, -13, -14, -10, -4, 8, 20, 27, 31, 31, 28, 29, 31, 30, 26, 17,
+ 5, -9, -23, -32, -37, -36, -34, -35, -34, -32, -24, -16, -7, 2, 4, 6,
+ 10, 16, 17, 15, 12, 8, 3, -5, -11, -11, -10, -11, -12, -11, -5, 3,
+ 13, 22, 30, 32, 27, 25, 25, 28, 27, 19, 7, -8, -22, -31, -34, -32,
+ -30, -28, -31, -31, -29, -21, -12, -4, 1, 1, 3, 10, 16, 18, 18, 14,
+ 12, 3, -5, -8, -7, -8, -10, -12, -12, -5, 6, 16, 26, 30, 29, 24,
+ 25, 26, 29, 23, 13, -2, -16, -26, -32, -33, -30, -30, -30, -30, -29, -25,
+ -18, -12, -5, -2, 2, 8, 14, 18, 16, 18, 14, 10, 4, 0, -5, -4,
+ -7, -9, -14, -10, -3, 9, 19, 26, 26, 23, 23, 26, 29, 28, 21, 7,
+ -10, -19, -25, -26, -27, -27, -29, -30, -32, -31, -27, -19, -13, -9, -7, 0,
+ 9, 18, 24, 26, 21, 13, 9, 8, 4, -2, -6, -9, -11, -11, -7, 4,
+ 16, 24, 26, 21, 19, 22, 26, 29, 23, 7, -10, -17, -19, -19, -23, -25,
+ -25, -25, -26, -26, -29, -26, -17, -14, -9, -7, 1, 12, 21, 26, 23, 18,
+ 13, 11, 11, 6, -4, -6, -10, -10, -9, -2, 9, 20, 25, 23, 18, 18,
+ 23, 26, 24, 10, -5, -13, -17, -14, -15, -17, -20, -24, -25, -29, -31, -32,
+ -28, -22, -16, -13, -8, 2, 14, 25, 27, 27, 22, 17, 15, 13, 10, 5,
+ -3, -6, -8, -6, 1, 11, 18, 20, 13, 11, 15, 19, 20, 14, 4, -4,
+ -12, -12, -12, -12, -14, -17, -23, -30, -35, -37, -31, -26, -20, -16, -12, -4,
+ 9, 22, 28, 26, 22, 17, 14, 15, 11, 8, 6, 2, 0, -2, 4, 11,
+ 16, 16, 12, 7, 8, 13, 13, 10, 1, -5, -8, -8, -8, -7, -7, -10,
+ -20, -26, -34, -36, -33, -31, -29, -25, -19, -12, 4, 18, 27, 28, 23, 22,
+ 18, 19, 17, 14, 9, 7, 4, 0, 2, 8, 14, 16, 12, 2, 0, 2,
+ 5, 6, 2, -4, -7, -6, -2, -2, -3, -5, -11, -19, -28, -37, -37, -37,
+ -34, -29, -24, -18, -8, 7, 20, 25, 25, 25, 22, 21, 21, 21, 19, 15,
+ 11, 6, 6, 6, 10, 11, 6, -2, -5, -5, -2, 0, 0, 0, -4, 0,
+ 2, 4, 2, -2, -8, -16, -25, -34, -39, -42, -39, -33, -26, -21, -16, -4,
+ 11, 22, 25, 27, 25, 23, 23, 24, 25, 22, 17, 13, 10, 9, 12, 10,
+ 4, -5, -12, -12, -11, -9, -8, -6, -5, 1, 4, 8, 10, 7, 4, -7,
+ -18, -26, -34, -39, -43, -42, -34, -28, -22, -13, 2, 14, 18, 21, 23, 27,
+ 30, 32, 31, 28, 23, 20, 20, 15, 14, 10, 2, -5, -13, -15, -16, -16,
+ -12, -12, -5, 1, 5, 8, 8, 10, 8, 0, -13, -23, -27, -33, -40, -44,
+ -41, -32, -24, -17, -6, 3, 9, 17, 22, 25, 29, 34, 39, 36, 32, 26,
+ 25, 23, 19, 11, 1, -9, -16, -18, -17, -19, -21, -17, -8, 0, 4, 7,
+ 8, 10, 11, 6, -4, -13, -21, -25, -35, -40, -41, -37, -26, -21, -13, -8,
+ -3, 6, 15, 23, 27, 35, 40, 41, 38, 33, 31, 29, 24, 16, 5, -5,
+ -16, -23, -23, -23, -18, -14, -6, 2, 3, 4, 7, 11, 13, 7, -5, -13,
+ -21, -25, -32, -40, -42, -37, -28, -21, -14, -13, -9, 1, 11, 22, 27, 33,
+ 39, 43, 42, 41, 33, 29, 25, 18, 7, -6, -17, -25, -24, -23, -21, -16,
+ -9, 2, 6, 5, 5, 10, 15, 12, 3, -8, -16, -22, -29, -39, -44, -42,
+ -34, -27, -22, -21, -17, -8, 4, 19, 29, 40, 48, 53, 51, 49, 43, 38,
+ 28, 19, 6, -9, -19, -27, -30, -30, -24, -16, -10, -3, 3, 6, 5, 6,
+ 9, 11, 7, 2, -7, -16, -25, -34, -37, -37, -33, -31, -28, -27, -24, -20,
+ -10, 8, 22, 35, 46, 52, 53, 54, 49, 46, 37, 23, 9, -7, -18, -24,
+ -30, -32, -28, -22, -12, -5, 1, 6, 4, 8, 9, 11, 9, 3, -3, -13,
+ -21, -32, -37, -38, -35, -34, -32, -32, -32, -27, -14, 5, 24, 38, 48, 55,
+ 56, 56, 54, 50, 40, 23, 4, -10, -18, -24, -26, -29, -29, -24, -17, -5,
+ 2, 9, 9, 6, 6, 7, 12, 11, 6, -7, -18, -30, -36, -36, -37, -35,
+ -38, -40, -41, -36, -24, -2, 20, 35, 47, 55, 60, 62, 62, 61, 47, 26,
+ 7, -12, -18, -22, -24, -28, -33, -31, -24, -12, -2, 7, 9, 5, 4, 5,
+ 11, 14, 13, 7, -8, -24, -37, -41, -38, -34, -37, -44, -50, -46, -33, -10,
+ 16, 36, 49, 57, 61, 64, 66, 65, 55, 34, 11, -14, -24, -26, -26, -24,
+ -30, -34, -33, -24, -7, 5, 12, 10, 5, 6, 9, 16, 22, 21, 10, -10,
+ -32, -45, -44, -38, -38, -47, -61, -60, -48, -21, 11, 34, 51, 60, 63, 66,
+ 70, 69, 63, 45, 18, -10, -27, -27, -23, -20, -28, -36, -37, -32, -17, -2,
+ 8, 9, 5, 6, 8, 15, 24, 30, 25, 5, -22, -41, -44, -40, -38, -50,
+ -64, -72, -62, -37, -3, 29, 52, 62, 66, 69, 73, 78, 72, 54, 26, -5,
+ -25, -32, -29, -24, -27, -34, -37, -36, -26, -11, 5, 15, 15, 11, 9, 15,
+ 26, 35, 33, 14, -14, -37, -49, -47, -45, -51, -63, -72, -66, -42, -10, 22,
+ 49, 64, 69, 69, 70, 75, 73, 59, 34, 4, -20, -30, -30, -25, -24, -29,
+ -36, -40, -35, -22, -2, 16, 20, 17, 14, 15, 27, 39, 41, 27, -4, -32,
+ -48, -54, -53, -59, -65, -73, -71, -55, -23, 16, 49, 67, 70, 68, 71, 77,
+ 78, 65, 40, 10, -17, -31, -34, -28, -24, -26, -31, -40, -40, -30, -10, 10,
+ 21, 18, 15, 16, 26, 40, 48, 40, 13, -20, -44, -55, -61, -63, -69, -76,
+ -76, -63, -35, 6, 41, 66, 75, 71, 71, 75, 77, 67, 44, 17, -10, -25,
+ -34, -35, -29, -27, -28, -35, -40, -35, -18, 1, 16, 21, 20, 19, 25, 38,
+ 47, 43, 23, -9, -34, -50, -59, -65, -72, -76, -74, -66, -43, -9, 27, 58,
+ 71, 69, 70, 71, 73, 67, 48, 25, 2, -18, -28, -33, -29, -25, -25, -31,
+ -39, -41, -28, -10, 8, 19, 20, 23, 27, 36, 45, 45, 31, 4, -22, -45,
+ -58, -67, -74, -75, -73, -66, -50, -21, 16, 49, 67, 73, 72, 72, 74, 69,
+ 53, 33, 9, -11, -25, -34, -35, -31, -27, -30, -38, -43, -33, -16, 6, 18,
+ 24, 27, 30, 38, 45, 46, 34, 10, -16, -40, -61, -70, -77, -76, -72, -66,
+ -52, -31, 2, 36, 60, 71, 72, 69, 71, 68, 57, 44, 20, 2, -17, -32,
+ -36, -33, -31, -31, -40, -46, -41, -29, -5, 16, 27, 34, 35, 41, 49, 51,
+ 41, 17, -11, -34, -56, -71, -79, -80, -76, -68, -57, -36, -10, 21, 48, 64,
+ 71, 71, 73, 69, 61, 48, 32, 11, -5, -21, -31, -34, -34, -37, -43, -48,
+ -45, -34, -14, 8, 25, 34, 41, 43, 49, 51, 43, 26, -2, -27, -49, -65,
+ -74, -77, -74, -70, -58, -42, -20, 9, 38, 56, 64, 67, 69, 71, 66, 53,
+ 37, 16, 1, -15, -30, -33, -39, -38, -41, -45, -42, -35, -15, 7, 25, 36,
+ 41, 45, 49, 49, 40, 23, 1, -20, -41, -59, -71, -75, -73, -65, -57, -45,
+ -28, -6, 22, 42, 56, 63, 67, 71, 70, 59, 44, 28, 12, -3, -19, -32,
+ -40, -41, -46, -47, -46, -37, -20, -2, 20, 34, 45, 48, 52, 53, 42, 26,
+ 4, -15, -35, -51, -65, -70, -70, -68, -61, -50, -34, -15, 9, 28, 45, 54,
+ 64, 71, 72, 67, 53, 40, 24, 8, -10, -27, -37, -41, -49, -53, -53, -42,
+ -25, -8, 14, 31, 43, 52, 56, 56, 46, 30, 11, -8, -26, -43, -59, -70,
+ -69, -68, -62, -55, -44, -25, -4, 17, 36, 48, 62, 69, 69, 67, 57, 47,
+ 33, 17, -2, -21, -33, -41, -47, -52, -53, -43, -25, -10, 9, 23, 36, 46,
+ 52, 54, 47, 31, 14, -4, -19, -32, -49, -57, -62, -60, -57, -58, -51, -39,
+ -19, 6, 23, 38, 51, 60, 68, 71, 67, 58, 44, 27, 7, -17, -32, -41,
+ -47, -52, -54, -46, -31, -12, 7, 22, 35, 45, 51, 53, 46, 33, 18, 2,
+ -12, -26, -42, -55, -61, -60, -56, -57, -55, -46, -29, -8, 10, 27, 42, 55,
+ 65, 70, 69, 61, 49, 34, 16, -5, -23, -36, -45, -51, -54, -50, -35, -17,
+ 3, 17, 29, 37, 44, 51, 47, 39, 21, 6, -8, -20, -31, -44, -52, -58,
+ -60, -58, -58, -51, -39, -22, -4, 14, 31, 48, 62, 70, 69, 65, 57, 45,
+ 28, 7, -15, -31, -44, -50, -53, -50, -39, -24, -6, 11, 24, 33, 43, 46,
+ 45, 35, 25, 14, 1, -13, -23, -35, -44, -53, -57, -59, -59, -57, -47, -33,
+ -15, 3, 21, 39, 56, 69, 72, 69, 60, 49, 36, 17, -5, -25, -42, -52,
+ -52, -48, -40, -26, -9, 9, 20, 29, 34, 39, 40, 34, 25, 16, 6, -6,
+ -16, -27, -34, -44, -50, -55, -58, -57, -52, -41, -27, -11, 11, 31, 51, 67,
+ 70, 68, 61, 53, 43, 30, 7, -14, -35, -49, -54, -50, -40, -26, -13, -2,
+ 9, 22, 30, 38, 41, 36, 28, 20, 12, 4, -5, -15, -26, -41, -52, -58,
+ -60, -60, -59, -55, -41, -25, -5, 19, 42, 62, 74, 75, 70, 63, 55, 43,
+ 22, -3, -24, -42, -51, -50, -45, -32, -22, -14, -2, 14, 28, 35, 34, 33,
+ 30, 25, 21, 11, 4, -6, -18, -32, -46, -56, -61, -61, -62, -60, -51, -39,
+ -16, 11, 37, 58, 70, 75, 72, 67, 58, 46, 31, 10, -17, -35, -48, -49,
+ -41, -28, -17, -14, -7, 4, 18, 28, 32, 29, 27, 21, 19, 16, 7, 2,
+ -11, -22, -35, -48, -57, -61, -60, -60, -56, -47, -30, -5, 23, 48, 63, 72,
+ 75, 71, 64, 53, 39, 20, -2, -22, -40, -48, -45, -34, -21, -17, -10, -4,
+ 10, 22, 27, 28, 29, 26, 26, 22, 14, 7, -3, -14, -30, -46, -59, -65,
+ -65, -65, -64, -56, -41, -17, 15, 42, 62, 73, 77, 75, 69, 57, 43, 25,
+ 6, -12, -31, -44, -46, -37, -24, -16, -11, -3, 6, 20, 24, 23, 24, 23,
+ 25, 23, 16, 9, 1, -10, -23, -41, -56, -63, -67, -67, -66, -59, -47, -25,
+ 3, 32, 54, 70, 75, 76, 70, 62, 47, 32, 15, -3, -21, -38, -44, -41,
+ -31, -21, -15, -11, -2, 8, 18, 24, 27, 28, 29, 29, 24, 17, 8, -2,
+ -17, -35, -54, -66, -73, -74, -71, -66, -55, -35, -6, 24, 50, 69, 77, 79,
+ 74, 63, 51, 38, 22, 2, -17, -35, -42, -39, -32, -24, -17, -11, -5, 6,
+ 13, 20, 28, 31, 33, 29, 23, 15, 10, 3, -12, -30, -51, -65, -73, -75,
+ -71, -67, -58, -41, -18, 11, 38, 60, 75, 77, 74, 64, 53, 42, 31, 15,
+ -7, -25, -38, -40, -37, -29, -24, -15, -11, -2, 9, 17, 28, 33, 36, 33,
+ 27, 18, 13, 4, -8, -26, -48, -65, -75, -76, -72, -68, -58, -43, -18, 11,
+ 37, 58, 72, 76, 73, 63, 51, 40, 28, 13, -6, -23, -35, -41, -40, -33,
+ -24, -16, -9, -2, 7, 18, 29, 38, 42, 38, 31, 21, 11, 3, -10, -26,
+ -47, -65, -75, -79, -75, -69, -58, -39, -19, 7, 33, 54, 71, 77, 75, 66,
+ 52, 39, 27, 15, -2, -22, -35, -41, -41, -36, -27, -17, -8, 1, 11, 22,
+ 33, 41, 47, 45, 35, 21, 11, 4, -7, -24, -46, -66, -77, -81, -79, -73,
+ -62, -44, -24, -2, 23, 47, 69, 79, 79, 70, 57, 45, 33, 20, 5, -18,
+ -36, -43, -41, -37, -32, -23, -14, -3, 8, 20, 34, 45, 53, 52, 41, 27,
+ 16, 7, -5, -24, -47, -69, -83, -86, -84, -74, -62, -44, -22, 1, 24, 47,
+ 66, 78, 76, 69, 57, 43, 31, 17, 5, -13, -33, -43, -46, -41, -31, -22,
+ -12, 0, 11, 24, 39, 49, 57, 58, 48, 30, 15, 4, -8, -26, -52, -74,
+ -86, -89, -83, -74, -60, -43, -21, 1, 22, 45, 65, 78, 79, 68, 54, 40,
+ 26, 17, 7, -9, -31, -45, -46, -40, -31, -21, -11, 0, 8, 21, 39, 51,
+ 60, 60, 52, 36, 19, 4, -9, -25, -49, -71, -87, -92, -89, -79, -63, -45,
+ -24, 0, 22, 43, 65, 75, 80, 70, 57, 44, 30, 16, 2, -14, -31, -46,
+ -52, -47, -35, -21, -9, 1, 12, 26, 44, 59, 68, 68, 59, 42, 22, 6,
+ -11, -29, -49, -72, -87, -96, -95, -86, -67, -46, -23, -4, 16, 38, 59, 76,
+ 82, 74, 61, 45, 31, 20, 3, -14, -30, -44, -51, -51, -41, -26, -11, 3,
+ 13, 25, 44, 61, 71, 72, 59, 45, 28, 9, -10, -33, -53, -70, -83, -93,
+ -96, -91, -74, -53, -27, -6, 15, 35, 53, 71, 80, 77, 66, 51, 34, 20,
+ 3, -15, -30, -45, -53, -55, -48, -32, -17, 1, 16, 29, 47, 62, 73, 77,
+ 67, 50, 30, 9, -10, -32, -55, -73, -86, -93, -94, -90, -76, -54, -27, -4,
+ 17, 32, 48, 64, 74, 78, 68, 55, 38, 17, 1, -15, -28, -39, -47, -52,
+ -49, -37, -21, -3, 16, 31, 46, 61, 70, 75, 70, 55, 36, 13, -9, -32,
+ -56, -72, -84, -89, -93, -91, -81, -61, -30, -5, 18, 32, 45, 58, 71, 76,
+ 70, 57, 40, 18, 1, -17, -28, -35, -45, -52, -50, -39, -25, -7, 15, 33,
+ 48, 60, 67, 73, 70, 60, 42, 19, -8, -34, -57, -69, -77, -83, -87, -92,
+ -85, -66, -39, -10, 12, 27, 39, 52, 62, 73, 72, 61, 46, 25, 4, -14,
+ -27, -34, -41, -46, -48, -43, -30, -11, 14, 38, 53, 63, 66, 69, 72, 65,
+ 48, 23, -4, -31, -56, -72, -81, -83, -87, -91, -87, -72, -46, -15, 11, 28,
+ 40, 50, 60, 71, 75, 69, 54, 32, 8, -13, -29, -39, -45, -48, -50, -48,
+ -40, -21, 9, 37, 57, 66, 71, 74, 75, 71, 55, 32, 2, -29, -55, -73,
+ -81, -84, -87, -89, -88, -75, -49, -19, 10, 29, 39, 48, 53, 62, 72, 68,
+ 58, 35, 9, -11, -27, -34, -39, -42, -44, -46, -41, -26, 5, 35, 56, 65,
+ 69, 72, 73, 72, 59, 37, 9, -22, -50, -71, -83, -83, -83, -86, -88, -81,
+ -55, -24, 5, 24, 37, 48, 54, 59, 64, 66, 59, 41, 17, -9, -27, -36,
+ -38, -39, -42, -45, -41, -28, -2, 28, 53, 65, 68, 71, 71, 70, 58, 40,
+ 16, -14, -46, -67, -79, -81, -80, -83, -87, -83, -64, -36, -4, 19, 35, 46,
+ 51, 58, 65, 69, 64, 49, 26, -2, -25, -38, -41, -39, -40, -43, -45, -33,
+ -8, 24, 52, 65, 72, 74, 72, 66, 55, 40, 20, -7, -38, -65, -80, -85,
+ -80, -82, -84, -82, -65, -38, -9, 13, 29, 41, 49, 57, 62, 64, 59, 48,
+ 29, 6, -19, -36, -39, -37, -35, -38, -39, -31, -11, 19, 47, 63, 70, 71,
+ 71, 65, 55, 38, 17, -4, -33, -58, -76, -83, -79, -79, -80, -82, -70, -46,
+ -19, 8, 25, 36, 43, 51, 59, 63, 62, 50, 34, 14, -9, -27, -35, -38,
+ -36, -38, -39, -30, -15, 10, 34, 52, 67, 73, 74, 68, 54, 37, 21, 2,
+ -21, -45, -68, -78, -81, -81, -80, -79, -70, -51, -28, -4, 17, 32, 40, 48,
+ 56, 59, 57, 46, 34, 18, 3, -20, -34, -39, -35, -31, -30, -26, -13, 8,
+ 31, 48, 61, 67, 69, 66, 53, 38, 16, -4, -23, -41, -58, -72, -78, -80,
+ -76, -74, -64, -50, -33, -8, 12, 28, 35, 41, 50, 57, 53, 44, 31, 20,
+ 10, -8, -24, -34, -34, -30, -25, -21, -13, 5, 22, 38, 52, 61, 66, 65,
+ 53, 36, 15, -4, -18, -33, -45, -61, -73, -79, -78, -72, -62, -49, -33, -13,
+ 3, 19, 29, 38, 48, 52, 49, 41, 29, 22, 14, 2, -11, -25, -27, -25,
+ -20, -15, -8, 4, 19, 30, 42, 53, 57, 61, 50, 32, 15, -7, -18, -27,
+ -37, -50, -65, -73, -72, -66, -57, -49, -37, -19, -3, 13, 23, 32, 41, 44,
+ 41, 35, 29, 26, 21, 10, -2, -13, -21, -18, -14, -8, -4, 3, 12, 21,
+ 29, 42, 51, 54, 49, 32, 14, -5, -15, -22, -28, -39, -55, -69, -68, -62,
+ -52, -44, -37, -25, -11, 4, 16, 24, 32, 37, 35, 28, 23, 23, 23, 18,
+ 8, -4, -12, -12, -8, -2, 5, 9, 14, 18, 23, 31, 41, 45, 43, 29,
+ 11, -8, -18, -23, -21, -29, -43, -60, -65, -58, -50, -39, -32, -26, -17, -6,
+ 8, 18, 25, 31, 29, 24, 17, 20, 24, 25, 19, 8, 0, -5, -3, 4,
+ 11, 13, 12, 14, 16, 22, 31, 38, 37, 27, 9, -11, -22, -24, -22, -25,
+ -36, -50, -57, -53, -46, -37, -30, -24, -17, -9, 1, 10, 16, 20, 19, 17,
+ 13, 14, 21, 24, 24, 19, 10, 8, 9, 13, 18, 20, 15, 12, 11, 14,
+ 21, 27, 30, 21, 8, -12, -23, -24, -22, -20, -29, -40, -49, -47, -41, -33,
+ -26, -23, -20, -16, -11, -2, 7, 12, 14, 14, 13, 14, 19, 26, 30, 26,
+ 20, 11, 11, 16, 21, 26, 22, 18, 15, 14, 15, 19, 20, 16, 4, -15,
+ -29, -32, -27, -21, -24, -34, -40, -41, -33, -28, -24, -21, -20, -15, -14, -10,
+ -5, 1, 7, 10, 10, 12, 18, 26, 36, 34, 27, 21, 17, 20, 23, 25,
+ 24, 19, 11, 10, 9, 12, 16, 14, 3, -16, -32, -34, -27, -19, -20, -27,
+ -34, -35, -31, -27, -22, -18, -18, -19, -19, -20, -15, -7, 2, 6, 8, 9,
+ 18, 26, 38, 41, 37, 28, 21, 23, 25, 27, 25, 20, 13, 7, 3, 5,
+ 9, 11, 4, -14, -31, -35, -29, -20, -18, -23, -26, -32, -29, -25, -23, -15,
+ -17, -18, -21, -25, -23, -15, -6, 0, 5, 6, 16, 25, 37, 45, 43, 36,
+ 27, 25, 28, 30, 29, 26, 16, 7, -2, -2, 2, 3, -2, -15, -31, -38,
+ -35, -23, -15, -15, -19, -23, -26, -23, -21, -15, -12, -18, -24, -27, -25, -19,
+ -9, -3, 2, 5, 12, 19, 32, 42, 45, 41, 31, 28, 31, 33, 37, 33,
+ 26, 14, 4, -2, -3, -3, -5, -18, -34, -43, -42, -31, -20, -18, -17, -19,
+ -18, -16, -13, -9, -8, -13, -22, -32, -32, -28, -19, -11, -6, -2, 7, 18,
+ 31, 42, 46, 46, 41, 36, 32, 35, 39, 39, 30, 17, 5, -3, -3, -3,
+ -7, -19, -32, -39, -41, -36, -26, -17, -12, -13, -18, -20, -14, -7, -6, -11,
+ -23, -32, -34, -28, -23, -15, -9, -2, 9, 17, 28, 37, 44, 48, 45, 38,
+ 32, 35, 41, 45, 37, 23, 10, 1, -3, -5, -8, -20, -35, -44, -44, -42,
+ -34, -24, -14, -10, -12, -14, -11, -6, -2, -5, -15, -25, -32, -29, -24, -19,
+ -15, -10, 1, 10, 20, 31, 40, 45, 48, 43, 39, 39, 45, 51, 43, 28,
+ 15, 2, -4, -8, -13, -20, -34, -42, -45, -45, -36, -26, -13, -8, -11, -13,
+ -8, -2, 1, -4, -13, -22, -30, -33, -28, -25, -18, -12, -5, 3, 13, 25,
+ 37, 46, 47, 45, 40, 41, 47, 53, 49, 35, 21, 10, 2, -6, -11, -22,
+ -32, -43, -50, -50, -47, -34, -17, -9, -9, -12, -9, 3, 7, 4, -8, -18,
+ -25, -31, -31, -27, -21, -16, -11, -8, 2, 17, 31, 45, 47, 44, 40, 43,
+ 54, 60, 58, 42, 26, 14, 4, -5, -14, -26, -37, -47, -54, -53, -49, -38,
+ -22, -13, -9, -7, -3, 6, 11, 6, -5, -14, -22, -28, -31, -30, -29, -24,
+ -18, -15, -2, 14, 29, 42, 45, 47, 45, 48, 56, 63, 59, 46, 29, 17,
+ 5, -4, -11, -23, -36, -49, -53, -52, -48, -40, -29, -21, -16, -11, -2, 5,
+ 6, 3, -5, -10, -13, -17, -21, -25, -26, -23, -19, -15, -8, 5, 20, 31,
+ 38, 42, 41, 46, 55, 62, 63, 50, 36, 24, 12, 5, -7, -20, -33, -46,
+ -51, -51, -48, -40, -33, -27, -20, -15, 0, 9, 7, 1, -6, -10, -11, -16,
+ -22, -25, -30, -28, -25, -21, -11, 2, 17, 28, 32, 41, 47, 55, 64, 66,
+ 64, 54, 41, 32, 19, 4, -9, -24, -37, -48, -54, -55, -51, -41, -33, -29,
+ -24, -15, 0, 13, 14, 8, 1, -5, -6, -10, -17, -24, -30, -32, -33, -32,
+ -22, -9, 9, 21, 25, 35, 45, 56, 67, 71, 71, 63, 49, 37, 25, 11,
+ -5, -19, -32, -45, -54, -59, -54, -43, -36, -31, -27, -18, -3, 11, 13, 9,
+ 2, -3, -6, -9, -13, -20, -25, -29, -33, -30, -23, -9, 2, 11, 19, 28,
+ 40, 51, 63, 68, 71, 66, 55, 44, 31, 16, 1, -15, -30, -41, -50, -57,
+ -56, -46, -37, -32, -30, -21, -7, 8, 17, 12, 5, 3, -2, -6, -11, -19,
+ -23, -27, -33, -34, -28, -19, -6, 3, 13, 24, 38, 51, 62, 70, 72, 68,
+ 60, 48, 38, 22, 6, -13, -27, -39, -46, -53, -52, -48, -42, -37, -36, -25,
+ -9, 4, 11, 9, 7, 8, 6, 2, -6, -13, -20, -24, -28, -31, -30, -27,
+ -19, -10, 4, 19, 33, 45, 57, 67, 74, 74, 70, 60, 47, 31, 10, -8,
+ -25, -36, -42, -51, -56, -56, -51, -40, -35, -28, -16, -4, 7, 7, 10, 12,
+ 13, 11, 3, -8, -18, -21, -25, -29, -33, -33, -30, -20, -8, 11, 27, 42,
+ 54, 64, 72, 77, 76, 69, 56, 34, 14, -5, -20, -32, -43, -50, -57, -59,
+ -57, -47, -39, -31, -17, -5, 6, 8, 9, 17, 19, 16, 5, -9, -13, -18,
+ -21, -26, -33, -37, -35, -28, -15, 1, 18, 34, 47, 58, 68, 76, 77, 76,
+ 65, 47, 25, 6, -12, -24, -37, -49, -57, -62, -64, -58, -50, -40, -24, -12,
+ 3, 9, 13, 22, 26, 26, 17, 4, -9, -21, -25, -30, -36, -41, -44, -41,
+ -27, -8, 12, 31, 44, 57, 68, 77, 81, 80, 72, 56, 34, 12, -6, -19,
+ -30, -41, -53, -65, -68, -65, -56, -44, -30, -17, -8, 2, 10, 23, 31, 32,
+ 25, 10, -4, -14, -20, -25, -31, -39, -45, -45, -35, -17, 2, 22, 37, 51,
+ 63, 72, 79, 78, 74, 62, 43, 20, 2, -12, -24, -34, -49, -61, -69, -70,
+ -63, -48, -35, -23, -11, 0, 9, 20, 31, 36, 32, 20, 7, -9, -18, -24,
+ -30, -38, -47, -50, -44, -29, -9, 10, 27, 45, 60, 71, 78, 80, 78, 68,
+ 54, 33, 13, -5, -18, -29, -44, -57, -68, -74, -66, -54, -41, -30, -18, -5,
+ 8, 19, 26, 33, 32, 24, 13, -4, -15, -22, -24, -29, -40, -44, -42, -29,
+ -14, 0, 15, 31, 48, 63, 69, 74, 74, 72, 64, 47, 27, 11, -4, -17,
+ -33, -50, -66, -78, -78, -68, -54, -38, -25, -11, 4, 18, 31, 38, 40, 34,
+ 21, 5, -12, -23, -28, -34, -43, -50, -51, -39, -22, -6, 10, 26, 46, 61,
+ 70, 75, 79, 76, 67, 52, 34, 18, 4, -11, -27, -45, -63, -76, -78, -70,
+ -57, -44, -29, -15, 0, 14, 26, 35, 39, 34, 23, 9, -7, -18, -23, -30,
+ -40, -49, -51, -41, -24, -9, 5, 19, 39, 55, 67, 74, 77, 79, 72, 56,
+ 39, 24, 12, -5, -23, -42, -60, -73, -78, -74, -62, -48, -33, -18, -6, 10,
+ 25, 34, 37, 34, 26, 16, -2, -15, -23, -28, -32, -42, -46, -44, -31, -16,
+ -4, 11, 28, 44, 56, 64, 69, 75, 73, 63, 50, 37, 22, 6, -10, -27,
+ -47, -68, -81, -80, -68, -52, -39, -25, -13, 2, 17, 29, 36, 37, 32, 23,
+ 4, -14, -24, -26, -26, -36, -44, -45, -36, -20, -7, 9, 25, 38, 49, 58,
+ 66, 75, 77, 67, 52, 39, 26, 14, -3, -21, -43, -65, -81, -84, -74, -56,
+ -40, -27, -15, -2, 15, 27, 37, 38, 35, 26, 8, -11, -23, -26, -27, -34,
+ -42, -45, -40, -27, -13, 4, 19, 33, 45, 54, 60, 67, 72, 67, 57, 44,
+ 32, 20, 5, -11, -32, -55, -72, -82, -76, -62, -46, -31, -21, -5, 6, 19,
+ 29, 34, 33, 26, 12, -6, -17, -22, -23, -28, -38, -42, -38, -27, -14, 1,
+ 14, 27, 40, 48, 53, 62, 68, 67, 58, 44, 32, 21, 9, -5, -22, -43,
+ -63, -76, -75, -62, -46, -30, -24, -13, 0, 10, 20, 28, 31, 27, 12, -5,
+ -16, -20, -19, -21, -29, -35, -35, -27, -16, -6, 9, 21, 33, 41, 47, 53,
+ 61, 63, 60, 51, 39, 27, 15, 3, -13, -33, -55, -72, -75, -67, -52, -37,
+ -26, -18, -7, 4, 15, 26, 27, 25, 14, 0, -10, -15, -16, -19, -24, -31,
+ -32, -27, -17, -5, 5, 15, 26, 35, 43, 49, 54, 57, 57, 52, 42, 29,
+ 18, 10, -3, -23, -46, -64, -71, -66, -53, -39, -27, -19, -11, 0, 5, 16,
+ 22, 23, 15, 1, -10, -15, -18, -17, -17, -20, -24, -22, -14, -4, 7, 16,
+ 25, 31, 36, 41, 47, 49, 49, 46, 41, 32, 21, 13, 3, -14, -33, -51,
+ -60, -60, -52, -39, -28, -20, -14, -7, 1, 9, 14, 16, 10, 1, -10, -15,
+ -14, -15, -15, -15, -17, -14, -11, -4, 5, 13, 22, 29, 33, 35, 39, 43,
+ 45, 45, 42, 35, 26, 17, 7, -10, -25, -38, -48, -53, -53, -46, -33, -23,
+ -16, -13, -8, -3, 4, 9, 7, 1, -6, -10, -13, -12, -12, -8, -7, -6,
+ -2, 3, 6, 10, 14, 23, 28, 29, 30, 29, 34, 39, 40, 36, 30, 21,
+ 13, 1, -15, -27, -36, -44, -48, -45, -36, -26, -17, -13, -10, -6, -2, 2,
+ 3, -3, -6, -10, -14, -13, -12, -7, -3, 1, 2, 5, 6, 10, 15, 19,
+ 25, 25, 26, 26, 29, 34, 35, 32, 29, 20, 13, 4, -12, -20, -27, -33,
+ -38, -41, -36, -27, -19, -13, -10, -8, -8, -7, -5, -5, -7, -9, -13, -18,
+ -15, -12, -5, 3, 7, 10, 10, 11, 13, 20, 27, 27, 23, 20, 20, 24,
+ 27, 25, 26, 23, 17, 7, -6, -13, -16, -20, -26, -32, -33, -28, -20, -13,
+ -12, -12, -16, -15, -15, -12, -10, -13, -13, -16, -12, -7, 0, 9, 14, 18,
+ 18, 14, 11, 14, 18, 21, 17, 10, 11, 15, 20, 21, 20, 20, 17, 9,
+ 2, -5, -10, -14, -21, -25, -29, -27, -23, -17, -13, -13, -16, -18, -20, -20,
+ -12, -8, -9, -15, -16, -10, -2, 9, 14, 18, 18, 18, 14, 14, 17, 20,
+ 18, 12, 8, 11, 13, 16, 18, 19, 16, 9, 3, 1, 1, -6, -13, -20,
+ -23, -21, -19, -15, -15, -14, -17, -21, -22, -22, -17, -11, -11, -13, -18, -14,
+ -4, 12, 21, 22, 23, 21, 20, 17, 16, 16, 12, 7, 1, 5, 7, 8,
+ 12, 15, 15, 10, 3, 0, 3, 1, -5, -12, -19, -19, -16, -11, -9, -11,
+ -14, -23, -28, -29, -24, -17, -13, -15, -19, -18, -10, 7, 22, 29, 30, 24,
+ 22, 18, 17, 17, 11, 4, -2, -3, 2, 4, 8, 13, 16, 13, 7, 4,
+ 9, 8, 2, -7, -16, -15, -14, -12, -10, -12, -12, -19, -25, -29, -25, -18,
+ -15, -18, -21, -19, -12, 1, 16, 28, 34, 32, 29, 23, 18, 15, 11, 4,
+ -3, -10, -8, -5, 0, 7, 12, 14, 10, 6, 10, 15, 13, 3, -7, -11,
+ -13, -13, -13, -12, -14, -20, -28, -31, -29, -20, -13, -14, -18, -18, -15, -3,
+ 12, 24, 33, 32, 29, 25, 22, 16, 11, 3, -3, -6, -7, -8, -3, 2,
+ 8, 11, 11, 9, 10, 13, 13, 8, 0, -6, -9, -9, -9, -10, -11, -18,
+ -26, -30, -29, -22, -17, -18, -20, -21, -17, -7, 6, 21, 34, 38, 34, 29,
+ 21, 17, 13, 8, 1, -8, -13, -15, -10, -3, 5, 10, 11, 10, 11, 15,
+ 16, 11, 3, -4, -7, -9, -8, -10, -13, -19, -26, -26, -23, -17, -15, -16,
+ -17, -17, -15, -9, -2, 10, 26, 31, 31, 24, 21, 18, 13, 6, 1, -6,
+ -8, -9, -8, -4, 0, 6, 10, 12, 15, 14, 13, 9, 5, -2, -7, -8,
+ -9, -8, -10, -18, -25, -25, -23, -18, -16, -19, -22, -18, -16, -10, 0, 10,
+ 24, 33, 35, 29, 22, 17, 13, 7, -3, -8, -12, -14, -12, -7, -3, 4,
+ 10, 14, 16, 17, 16, 16, 11, 3, -7, -11, -10, -7, -10, -19, -26, -27,
+ -23, -17, -14, -14, -17, -18, -16, -12, -3, 7, 20, 26, 28, 24, 20, 16,
+ 15, 10, 2, -8, -13, -11, -7, -2, -2, 4, 6, 9, 14, 17, 19, 15,
+ 8, -4, -12, -15, -11, -5, -8, -18, -25, -24, -17, -9, -6, -7, -11, -15,
+ -15, -13, -6, 4, 11, 15, 16, 15, 16, 13, 9, 5, 1, -3, -7, -5,
+ -2, 3, 5, 6, 8, 10, 14, 17, 18, 14, 3, -8, -15, -13, -9, -6,
+ -9, -19, -22, -19, -13, -6, -4, -5, -8, -13, -15, -10, -5, 5, 8, 8,
+ 8, 11, 14, 14, 8, 2, 1, 1, 2, -2, 1, 5, 6, 7, 7, 6,
+ 11, 13, 16, 13, 3, -6, -13, -14, -8, -5, -6, -15, -20, -15, -10, -5,
+ -2, -6, -6, -8, -12, -10, -8, -3, 5, 3, 3, 5, 7, 10, 6, 2,
+ -3, -2, 2, 8, 9, 12, 11, 8, 9, 8, 11, 13, 11, 10, 0, -12,
+ -20, -21, -13, -10, -11, -14, -16, -10, -3, 4, 8, 5, 2, -2, -4, -4,
+ -7, -4, -4, -5, -7, -8, -5, 0, 2, 2, 0, 1, 6, 11, 15, 19,
+ 19, 18, 14, 10, 12, 12, 11, 6, -6, -16, -23, -23, -17, -13, -12, -12,
+ -13, -8, -2, 8, 13, 13, 8, 4, 1, -3, -3, -3, -4, -11, -16, -16,
+ -13, -9, -5, -4, -2, 1, 6, 13, 17, 21, 24, 23, 18, 14, 10, 11,
+ 12, 8, -3, -16, -26, -27, -20, -17, -21, -21, -17, -7, 2, 10, 16, 19,
+ 18, 13, 10, 5, 2, -2, -5, -14, -22, -26, -21, -15, -11, -11, -6, -2,
+ 6, 16, 22, 27, 28, 28, 23, 17, 13, 10, 12, 7, -4, -18, -29, -32,
+ -24, -20, -21, -22, -18, -5, 5, 14, 19, 21, 20, 17, 13, 8, 5, -2,
+ -9, -18, -26, -26, -21, -14, -12, -11, -8, -2, 10, 16, 21, 24, 25, 27,
+ 24, 16, 11, 6, 7, 6, -4, -16, -25, -29, -25, -19, -19, -22, -18, -7,
+ 6, 15, 17, 18, 19, 18, 15, 10, 8, 3, -5, -15, -24, -30, -27, -19,
+ -15, -15, -13, -8, 5, 14, 20, 25, 28, 31, 30, 26, 18, 11, 9, 7,
+ -2, -14, -27, -33, -30, -25, -25, -27, -26, -15, 2, 17, 22, 23, 23, 22,
+ 22, 18, 14, 7, -4, -14, -24, -31, -30, -25, -19, -16, -16, -11, -3, 8,
+ 17, 24, 29, 31, 31, 29, 22, 17, 12, 8, 2, -12, -26, -36, -35, -30,
+ -26, -26, -29, -20, -5, 13, 24, 26, 26, 26, 28, 23, 19, 11, 1, -9,
+ -24, -34, -33, -30, -24, -21, -21, -17, -11, 1, 9, 19, 27, 33, 34, 30,
+ 28, 24, 21, 16, 7, -6, -23, -35, -40, -36, -33, -31, -32, -27, -13, 3,
+ 17, 25, 29, 34, 34, 30, 23, 17, 11, 0, -14, -27, -32, -33, -30, -26,
+ -21, -18, -15, -9, 1, 11, 22, 29, 32, 33, 30, 28, 23, 21, 13, 3,
+ -15, -30, -37, -38, -35, -35, -33, -28, -18, -5, 10, 22, 30, 37, 36, 32,
+ 26, 21, 14, 7, -6, -19, -28, -34, -32, -27, -21, -20, -21, -20, -11, 5,
+ 17, 25, 29, 30, 33, 35, 31, 27, 19, 8, -7, -25, -37, -42, -41, -39,
+ -35, -30, -22, -11, 4, 21, 32, 38, 39, 36, 29, 22, 15, 9, -4, -15,
+ -24, -32, -35, -31, -24, -18, -18, -19, -14, -3, 11, 21, 27, 31, 32, 34,
+ 34, 31, 27, 18, 1, -19, -33, -39, -38, -40, -39, -35, -28, -17, -3, 14,
+ 28, 37, 41, 40, 34, 30, 24, 18, 7, -6, -20, -30, -36, -34, -30, -26,
+ -26, -27, -26, -16, 0, 16, 26, 30, 33, 36, 42, 43, 38, 27, 10, -10,
+ -27, -39, -43, -43, -43, -40, -34, -26, -14, 2, 21, 36, 42, 40, 36, 33,
+ 30, 24, 16, 5, -11, -25, -34, -35, -32, -29, -30, -31, -31, -27, -15, 5,
+ 21, 27, 30, 34, 42, 51, 48, 40, 20, -3, -21, -32, -38, -40, -43, -42,
+ -38, -30, -18, -3, 15, 29, 40, 41, 39, 34, 31, 28, 20, 10, -4, -18,
+ -29, -33, -34, -34, -35, -37, -38, -34, -21, -6, 12, 22, 26, 33, 44, 55,
+ 56, 46, 26, 5, -11, -25, -36, -42, -47, -47, -43, -37, -24, -11, 9, 25,
+ 36, 38, 38, 40, 39, 39, 28, 17, 3, -10, -23, -30, -37, -38, -42, -44,
+ -43, -40, -30, -16, 3, 17, 26, 34, 44, 57, 61, 52, 34, 9, -7, -21,
+ -30, -38, -46, -49, -48, -39, -27, -13, 5, 22, 32, 35, 35, 37, 41, 43,
+ 33, 19, 4, -8, -16, -25, -32, -39, -42, -44, -42, -41, -33, -20, -4, 11,
+ 21, 28, 38, 49, 58, 54, 36, 16, -6, -16, -21, -28, -36, -46, -49, -42,
+ -29, -17, 0, 13, 26, 30, 30, 35, 41, 47, 41, 25, 9, -4, -12, -17,
+ -28, -38, -46, -52, -51, -49, -39, -23, -9, 4, 12, 23, 39, 54, 66, 62,
+ 43, 23, 2, -10, -16, -26, -36, -45, -51, -50, -37, -20, 0, 16, 27, 28,
+ 29, 38, 47, 50, 44, 28, 13, -2, -10, -16, -26, -35, -45, -55, -57, -56,
+ -44, -27, -13, -4, 5, 17, 34, 53, 64, 64, 46, 29, 13, 1, -8, -17,
+ -28, -39, -48, -51, -42, -26, -8, 9, 18, 20, 24, 34, 46, 53, 47, 33,
+ 15, 4, -4, -13, -22, -35, -47, -56, -59, -56, -48, -32, -18, -8, 3, 14,
+ 33, 52, 65, 64, 49, 31, 17, 5, -3, -13, -25, -36, -45, -49, -44, -31,
+ -14, 7, 16, 21, 21, 31, 48, 57, 53, 38, 20, 8, -3, -9, -21, -35,
+ -47, -57, -62, -62, -54, -38, -22, -12, -5, 7, 26, 49, 66, 69, 56, 37,
+ 24, 15, 6, -4, -17, -30, -43, -53, -47, -34, -18, -2, 9, 14, 17, 29,
+ 46, 58, 56, 43, 25, 13, 2, -5, -15, -30, -45, -59, -66, -65, -57, -43,
+ -28, -16, -10, 2, 21, 44, 66, 71, 62, 43, 28, 19, 13, 3, -12, -25,
+ -42, -51, -50, -38, -18, -3, 5, 12, 17, 30, 48, 59, 58, 45, 26, 11,
+ 0, -6, -15, -29, -45, -63, -71, -68, -58, -41, -28, -19, -12, -4, 16, 42,
+ 62, 70, 61, 43, 29, 21, 16, 8, -6, -20, -35, -45, -45, -37, -21, -6,
+ 3, 8, 14, 24, 42, 54, 58, 47, 29, 16, 3, -3, -12, -27, -42, -62,
+ -73, -74, -66, -52, -34, -23, -14, -5, 12, 38, 60, 72, 68, 49, 34, 23,
+ 17, 10, -3, -18, -31, -42, -42, -36, -20, -4, 5, 9, 11, 22, 37, 51,
+ 55, 46, 29, 13, 2, -9, -14, -25, -38, -53, -67, -72, -67, -53, -35, -23,
+ -17, -10, 6, 32, 55, 69, 67, 53, 36, 26, 19, 12, 2, -13, -26, -37,
+ -40, -36, -24, -7, 3, 9, 13, 20, 36, 49, 52, 47, 32, 17, 3, -12,
+ -19, -29, -38, -52, -66, -75, -72, -56, -36, -20, -15, -10, 2, 25, 48, 63,
+ 63, 52, 39, 28, 20, 14, 5, -6, -19, -30, -38, -35, -25, -8, 4, 8,
+ 11, 17, 33, 47, 54, 47, 34, 18, 4, -9, -19, -28, -40, -53, -65, -75,
+ -74, -60, -41, -22, -15, -12, -2, 18, 43, 59, 63, 55, 41, 31, 27, 20,
+ 13, 3, -11, -24, -35, -34, -26, -11, 2, 8, 9, 11, 22, 37, 47, 49,
+ 39, 22, 6, -7, -19, -26, -36, -48, -60, -74, -77, -66, -47, -26, -13, -8,
+ 1, 15, 36, 53, 63, 56, 45, 30, 22, 16, 10, 5, -7, -19, -32, -34,
+ -25, -7, 8, 16, 17, 17, 23, 37, 48, 51, 40, 22, 4, -14, -24, -33,
+ -39, -49, -61, -72, -77, -66, -47, -27, -13, -5, 1, 13, 30, 47, 59, 57,
+ 47, 31, 23, 17, 15, 6, -5, -18, -26, -30, -24, -10, 8, 19, 21, 20,
+ 22, 30, 40, 48, 41, 25, 3, -17, -29, -32, -37, -46, -59, -70, -73, -65,
+ -46, -27, -14, -4, 3, 15, 29, 41, 52, 54, 45, 31, 19, 15, 15, 9,
+ 1, -14, -26, -27, -21, -8, 10, 17, 23, 23, 23, 32, 39, 45, 44, 29,
+ 7, -16, -32, -40, -42, -49, -61, -72, -76, -69, -50, -28, -12, -2, 5, 17,
+ 31, 43, 48, 49, 44, 34, 24, 15, 13, 9, 5, -8, -24, -27, -21, -7,
+ 10, 20, 25, 29, 29, 32, 36, 41, 41, 34, 14, -12, -35, -46, -49, -52,
+ -61, -74, -78, -73, -56, -31, -14, 2, 10, 19, 31, 44, 54, 53, 47, 34,
+ 24, 16, 9, 4, -2, -12, -25, -28, -22, -7, 9, 23, 32, 36, 36, 36,
+ 37, 42, 42, 33, 15, -14, -36, -50, -57, -56, -62, -74, -81, -77, -59, -36,
+ -15, 2, 11, 20, 31, 44, 56, 56, 51, 39, 26, 15, 7, 1, -3, -13,
+ -26, -33, -31, -14, 9, 25, 36, 41, 40, 41, 40, 44, 44, 35, 17, -13,
+ -39, -54, -61, -64, -69, -76, -81, -78, -63, -39, -15, 4, 14, 24, 35, 45,
+ 54, 56, 53, 41, 25, 14, 7, 3, -4, -14, -26, -34, -31, -15, 9, 25,
+ 36, 41, 43, 44, 43, 46, 45, 35, 16, -9, -31, -49, -63, -69, -75, -78,
+ -84, -79, -66, -45, -22, 0, 13, 23, 35, 48, 56, 58, 53, 43, 30, 19,
+ 10, 4, -7, -18, -26, -33, -30, -17, 4, 24, 37, 44, 50, 50, 49, 46,
+ 43, 35, 16, -7, -30, -52, -65, -75, -78, -83, -85, -82, -70, -50, -26, -4,
+ 14, 26, 39, 53, 63, 64, 59, 49, 35, 18, 6, -2, -13, -25, -35, -40,
+ -36, -22, 3, 26, 38, 47, 54, 60, 61, 57, 50, 39, 20, -5, -26, -49,
+ -66, -80, -87, -91, -93, -88, -74, -54, -34, -12, 8, 24, 40, 55, 68, 70,
+ 66, 55, 41, 26, 14, 6, -9, -25, -37, -43, -39, -28, -9, 15, 32, 41,
+ 48, 59, 65, 65, 58, 45, 25, 5, -17, -38, -61, -77, -91, -97, -100, -94,
+ -79, -64, -44, -23, -2, 24, 42, 57, 72, 77, 74, 63, 48, 33, 21, 10,
+ -7, -27, -43, -45, -41, -29, -14, 4, 26, 40, 49, 58, 66, 69, 64, 48,
+ 29, 7, -13, -31, -53, -73, -89, -100, -102, -95, -83, -67, -51, -29, -7, 17,
+ 37, 55, 72, 81, 77, 67, 55, 40, 25, 12, -4, -22, -40, -45, -42, -31,
+ -19, -4, 15, 34, 48, 55, 63, 67, 66, 57, 41, 20, -4, -25, -46, -69,
+ -88, -104, -110, -106, -95, -79, -63, -39, -13, 15, 39, 60, 75, 88, 91, 81,
+ 66, 44, 27, 13, -3, -22, -41, -50, -48, -38, -26, -13, 6, 29, 46, 55,
+ 62, 66, 69, 63, 48, 26, 5, -14, -33, -57, -84, -105, -115, -113, -102, -88,
+ -73, -53, -26, 1, 31, 57, 78, 91, 95, 88, 75, 60, 41, 22, 1, -19,
+ -38, -51, -53, -48, -36, -22, -6, 19, 39, 53, 62, 65, 69, 67, 55, 36,
+ 14, -6, -28, -54, -79, -100, -111, -116, -110, -98, -83, -61, -35, -6, 26, 53,
+ 75, 89, 96, 96, 87, 71, 50, 29, 10, -9, -30, -44, -53, -50, -45, -32,
+ -19, 2, 23, 43, 55, 62, 66, 66, 62, 49, 30, 11, -12, -39, -70, -95,
+ -112, -118, -118, -109, -94, -74, -48, -18, 17, 47, 70, 88, 98, 99, 95, 80,
+ 61, 37, 14, -9, -26, -43, -51, -52, -48, -40, -25, -6, 17, 37, 52, 57,
+ 63, 64, 62, 55, 36, 17, -8, -34, -62, -86, -106, -117, -118, -110, -99, -83,
+ -57, -27, 10, 42, 67, 85, 96, 101, 101, 91, 69, 46, 21, 1, -21, -38,
+ -49, -54, -49, -44, -35, -18, 2, 24, 44, 55, 64, 67, 63, 59, 46, 29,
+ 7, -21, -51, -79, -104, -117, -122, -117, -108, -94, -70, -40, 0, 34, 63, 85,
+ 96, 104, 105, 99, 82, 59, 31, 4, -20, -37, -46, -51, -51, -50, -44, -28,
+ -8, 17, 38, 53, 60, 65, 67, 64, 54, 40, 18, -10, -40, -71, -98, -115,
+ -121, -118, -113, -103, -82, -52, -14, 22, 53, 77, 94, 106, 109, 104, 93, 76,
+ 50, 21, -11, -33, -43, -48, -53, -56, -56, -46, -27, 2, 29, 48, 58, 62,
+ 63, 62, 58, 49, 33, 5, -27, -57, -87, -108, -119, -118, -114, -106, -91, -68,
+ -31, 8, 42, 69, 88, 102, 110, 110, 100, 83, 60, 33, 3, -23, -39, -46,
+ -52, -57, -57, -51, -35, -14, 15, 38, 54, 63, 65, 66, 58, 51, 40, 17,
+ -11, -44, -76, -101, -114, -116, -111, -106, -96, -77, -47, -11, 28, 58, 81, 97,
+ 109, 112, 105, 95, 77, 53, 23, -9, -30, -45, -52, -58, -64, -61, -52, -35,
+ -9, 20, 44, 62, 67, 67, 65, 62, 54, 35, 7, -24, -60, -91, -110, -119,
+ -116, -112, -105, -90, -65, -31, 8, 43, 73, 94, 109, 117, 113, 105, 91, 68,
+ 39, 4, -24, -43, -56, -64, -67, -67, -61, -47, -21, 9, 35, 55, 63, 66,
+ 66, 61, 56, 46, 23, -10, -46, -81, -100, -111, -115, -112, -107, -94, -75, -48,
+ -12, 28, 59, 84, 103, 116, 120, 114, 103, 81, 56, 22, -10, -35, -53, -64,
+ -71, -73, -71, -59, -39, -10, 19, 43, 60, 66, 68, 67, 64, 53, 33, 7,
+ -27, -64, -91, -108, -115, -113, -108, -97, -82, -59, -27, 11, 46, 75, 98, 112,
+ 119, 117, 109, 89, 64, 34, 4, -24, -50, -62, -69, -69, -70, -65, -49, -23,
+ 8, 32, 52, 61, 64, 65, 64, 55, 39, 15, -16, -46, -76, -97, -109, -110,
+ -107, -102, -91, -71, -42, -4, 34, 66, 90, 106, 116, 121, 118, 101, 78, 47,
+ 15, -15, -44, -60, -70, -73, -75, -74, -63, -39, -7, 23, 45, 60, 66, 69,
+ 69, 62, 49, 29, 1, -32, -65, -94, -108, -112, -109, -102, -97, -83, -58, -22,
+ 18, 54, 84, 103, 116, 121, 120, 112, 91, 63, 29, -6, -34, -54, -66, -75,
+ -79, -81, -72, -50, -22, 9, 33, 50, 59, 67, 70, 70, 60, 43, 13, -20,
+ -51, -78, -97, -107, -111, -109, -105, -94, -72, -37, 5, 42, 72, 96, 114, 124,
+ 127, 118, 100, 75, 42, 10, -22, -47, -62, -72, -79, -84, -82, -64, -35, -2,
+ 23, 39, 50, 61, 69, 71, 66, 51, 27, -6, -36, -62, -81, -96, -104, -105,
+ -106, -101, -83, -52, -11, 27, 57, 82, 103, 120, 127, 122, 107, 82, 53, 19,
+ -12, -39, -55, -65, -73, -81, -81, -67, -40, -8, 16, 30, 41, 52, 62, 68,
+ 66, 56, 34, 3, -28, -53, -71, -86, -96, -102, -106, -103, -88, -62, -25, 15,
+ 47, 72, 90, 109, 120, 123, 115, 93, 63, 31, 1, -24, -40, -52, -64, -76,
+ -82, -73, -50, -22, 1, 18, 27, 39, 51, 63, 67, 61, 44, 18, -13, -38,
+ -53, -69, -83, -96, -105, -103, -93, -69, -36, -3, 30, 56, 77, 95, 111, 116,
+ 113, 97, 72, 42, 13, -12, -25, -38, -54, -70, -79, -74, -57, -32, -11, 4,
+ 15, 26, 40, 55, 65, 62, 51, 28, 1, -24, -40, -56, -73, -89, -101, -102,
+ -95, -79, -50, -17, 16, 47, 68, 88, 104, 114, 115, 102, 80, 53, 24, 0,
+ -18, -31, -45, -60, -73, -74, -63, -42, -21, -6, 6, 16, 28, 45, 56, 59,
+ 51, 35, 14, -9, -26, -41, -57, -73, -87, -97, -95, -85, -62, -32, -2, 26,
+ 50, 71, 91, 105, 111, 105, 89, 64, 40, 16, -4, -20, -35, -49, -64, -70,
+ -68, -53, -35, -18, -6, 5, 14, 29, 45, 55, 54, 39, 21, 4, -13, -25,
+ -42, -63, -77, -89, -90, -80, -66, -44, -19, 10, 35, 57, 76, 93, 104, 104,
+ 91, 68, 48, 29, 13, -6, -24, -42, -56, -63, -61, -54, -42, -27, -17, -6,
+ 5, 18, 33, 44, 47, 39, 25, 10, 0, -14, -29, -50, -67, -79, -85, -81,
+ -70, -53, -32, -5, 24, 47, 67, 84, 98, 103, 95, 77, 56, 37, 22, 6,
+ -14, -34, -48, -56, -57, -52, -48, -37, -28, -17, -6, 8, 23, 34, 41, 38,
+ 28, 15, 4, -4, -16, -38, -59, -73, -78, -75, -66, -54, -37, -19, 7, 32,
+ 53, 72, 87, 95, 92, 78, 58, 44, 32, 20, 2, -21, -38, -47, -48, -47,
+ -46, -42, -36, -26, -14, -5, 9, 20, 32, 35, 30, 19, 12, 8, -5, -25,
+ -48, -63, -71, -70, -63, -58, -44, -26, -6, 20, 40, 59, 79, 92, 93, 83,
+ 60, 47, 37, 29, 13, -10, -28, -40, -44, -44, -48, -47, -41, -33, -22, -13,
+ 0, 14, 29, 36, 34, 24, 18, 15, 4, -13, -39, -60, -69, -72, -68, -62,
+ -51, -34, -13, 9, 31, 52, 73, 88, 95, 87, 70, 55, 45, 35, 20, -2,
+ -23, -36, -42, -47, -48, -51, -50, -40, -30, -17, -8, 7, 23, 36, 37, 30,
+ 22, 19, 13, -3, -24, -49, -65, -71, -71, -64, -54, -40, -20, -3, 21, 44,
+ 65, 85, 92, 87, 72, 57, 48, 39, 29, 11, -12, -27, -36, -41, -42, -47,
+ -49, -45, -37, -28, -17, -4, 13, 28, 33, 29, 26, 23, 17, 6, -11, -33,
+ -53, -64, -66, -62, -55, -44, -29, -12, 10, 31, 51, 71, 84, 85, 77, 61,
+ 50, 41, 36, 22, 2, -17, -33, -38, -42, -45, -48, -46, -41, -34, -23, -9,
+ 7, 24, 35, 32, 28, 23, 17, 10, -4, -26, -49, -64, -68, -64, -58, -46,
+ -32, -13, 8, 28, 45, 65, 78, 82, 76, 62, 52, 45, 37, 23, 6, -10,
+ -26, -35, -41, -45, -46, -48, -48, -39, -27, -11, 3, 14, 23, 27, 28, 25,
+ 23, 15, 2, -17, -34, -52, -60, -61, -56, -44, -32, -17, -3, 16, 34, 54,
+ 66, 73, 68, 58, 47, 42, 37, 29, 17, 3, -14, -25, -31, -36, -39, -44,
+ -48, -44, -33, -20, -9, 2, 13, 22, 26, 24, 20, 14, 5, -7, -22, -39,
+ -50, -55, -51, -43, -32, -20, -7, 10, 28, 44, 57, 65, 67, 64, 54, 44,
+ 36, 28, 18, 4, -9, -23, -32, -39, -42, -46, -44, -38, -29, -19, -12, -4,
+ 10, 22, 27, 22, 14, 8, 1, -6, -17, -30, -43, -49, -47, -38, -26, -18,
+ -10, 3, 17, 34, 45, 54, 59, 57, 53, 45, 37, 30, 22, 11, -3, -14,
+ -24, -34, -40, -45, -43, -39, -29, -21, -14, -6, 3, 16, 20, 17, 10, 3,
+ 0, -6, -15, -25, -33, -38, -37, -31, -21, -12, -6, 5, 15, 27, 39, 46,
+ 50, 51, 47, 44, 36, 29, 20, 10, 1, -10, -18, -27, -36, -40, -42, -37,
+ -29, -21, -14, -7, 1, 10, 16, 10, 3, -2, -3, -6, -12, -22, -28, -30,
+ -28, -23, -16, -11, -7, 0, 7, 19, 31, 42, 47, 47, 46, 46, 40, 33,
+ 21, 10, 2, -6, -12, -24, -33, -37, -38, -36, -31, -21, -14, -7, -2, 2,
+ 7, 8, 4, -2, -7, -12, -14, -19, -23, -24, -20, -16, -11, -6, -2, 3,
+ 9, 16, 24, 33, 37, 40, 44, 44, 40, 33, 22, 13, 5, -3, -8, -21,
+ -30, -35, -34, -32, -30, -23, -13, -6, -3, -3, -2, -2, -4, -7, -9, -12,
+ -13, -13, -14, -14, -11, -12, -4, -2, 2, 0, 3, 10, 18, 27, 32, 35,
+ 38, 40, 37, 32, 23, 13, 8, 2, -4, -11, -22, -27, -31, -30, -29, -24,
+ -14, -7, -8, -7, -10, -10, -10, -10, -11, -12, -13, -12, -11, -11, -7, -2,
+ 4, 5, 3, -2, 0, 8, 15, 21, 26, 30, 32, 37, 37, 32, 26, 16,
+ 10, 4, -4, -9, -16, -21, -26, -29, -28, -23, -15, -11, -9, -11, -13, -14,
+ -14, -13, -13, -12, -13, -12, -8, -3, 3, 6, 8, 10, 7, 1, -3, 2,
+ 8, 17, 22, 22, 27, 32, 37, 35, 29, 18, 11, 2, -4, -8, -14, -17,
+ -21, -23, -25, -22, -17, -11, -9, -11, -16, -16, -16, -16, -14, -15, -14, -11,
+ -5, 0, 4, 5, 6, 7, 6, 4, 0, 3, 8, 16, 21, 20, 24, 28,
+ 34, 35, 29, 17, 8, 3, 1, -3, -9, -15, -20, -21, -23, -22, -21, -17,
+ -13, -14, -18, -23, -22, -17, -13, -10, -9, -8, 0, 6, 9, 10, 8, 6,
+ 6, 4, 0, -2, 1, 10, 17, 20, 22, 25, 29, 31, 29, 20, 10, 2,
+ -2, 0, -5, -11, -18, -20, -19, -19, -19, -18, -16, -14, -18, -26, -26, -22,
+ -16, -13, -9, -6, 1, 7, 10, 10, 7, 7, 7, 5, 0, -4, -2, 7,
+ 14, 19, 22, 26, 30, 32, 30, 22, 13, 6, 1, -2, -7, -13, -16, -18,
+ -19, -19, -21, -21, -19, -17, -16, -23, -25, -23, -17, -10, -9, -4, 2, 8,
+ 10, 12, 9, 7, 5, 4, 2, -3, -2, 3, 9, 18, 23, 28, 29, 28,
+ 27, 26, 19, 12, 6, 0, -7, -11, -15, -17, -20, -21, -20, -22, -23, -25,
+ -24, -26, -27, -25, -20, -13, -5, 3, 9, 11, 15, 17, 15, 10, 4, 0,
+ -4, -5, -4, 2, 5, 13, 19, 25, 29, 28, 26, 25, 20, 16, 11, 2,
+ -5, -10, -10, -10, -14, -17, -21, -24, -26, -29, -27, -28, -28, -26, -23, -17,
+ -8, 1, 12, 15, 16, 14, 13, 10, 6, 0, -5, -6, -5, 1, 6, 12,
+ 20, 27, 30, 28, 24, 23, 21, 17, 11, 4, -6, -9, -10, -10, -11, -16,
+ -18, -21, -24, -26, -29, -28, -27, -25, -23, -18, -11, -2, 11, 15, 15, 12,
+ 11, 9, 6, 1, -6, -6, -2, 3, 7, 11, 19, 26, 28, 26, 22, 21,
+ 23, 24, 17, 10, 4, 0, -2, -5, -10, -15, -20, -25, -32, -36, -36, -35,
+ -32, -30, -26, -19, -10, 2, 14, 21, 21, 17, 13, 10, 7, 1, -5, -5,
+ -6, -4, 0, 6, 12, 19, 22, 24, 20, 21, 24, 29, 28, 20, 13, 8,
+ 3, 2, -4, -9, -16, -27, -34, -41, -44, -41, -38, -35, -31, -27, -18, -3,
+ 13, 26, 29, 23, 18, 14, 11, 8, 4, -2, -8, -11, -9, -6, 4, 9,
+ 16, 17, 16, 16, 23, 33, 37, 33, 26, 19, 12, 8, 1, -7, -15, -30,
+ -41, -50, -53, -50, -43, -38, -34, -28, -17, -3, 13, 26, 30, 26, 19, 14,
+ 12, 9, 4, -2, -10, -14, -13, -7, 4, 9, 12, 13, 13, 17, 25, 32,
+ 40, 39, 32, 24, 15, 11, 8, 1, -10, -27, -43, -51, -55, -52, -49, -45,
+ -40, -32, -21, -8, 9, 23, 31, 30, 24, 19, 17, 16, 11, 4, -7, -15,
+ -18, -14, -6, 2, 5, 7, 9, 14, 24, 35, 45, 48, 45, 34, 25, 16,
+ 8, 2, -11, -27, -46, -59, -64, -61, -53, -46, -40, -35, -24, -9, 8, 23,
+ 30, 31, 27, 24, 21, 17, 12, 4, -6, -15, -19, -17, -12, -3, 3, 4,
+ 6, 12, 25, 37, 45, 47, 47, 43, 35, 23, 12, 2, -10, -24, -42, -60,
+ -71, -71, -63, -55, -45, -36, -22, -7, 9, 22, 30, 35, 34, 31, 24, 19,
+ 13, 6, -3, -13, -20, -21, -16, -9, -3, -2, 4, 11, 26, 38, 45, 50,
+ 49, 48, 42, 31, 16, 4, -9, -21, -38, -59, -72, -77, -70, -61, -53, -41,
+ -26, -9, 7, 17, 26, 34, 41, 41, 35, 25, 17, 9, 0, -10, -21, -24,
+ -22, -15, -9, -7, -2, 10, 25, 39, 44, 47, 49, 52, 50, 39, 22, 6,
+ -8, -20, -34, -54, -70, -78, -77, -68, -61, -49, -33, -15, 3, 16, 25, 32,
+ 43, 49, 47, 37, 25, 16, 3, -10, -22, -29, -27, -22, -15, -12, -7, 7,
+ 25, 42, 47, 50, 53, 57, 57, 46, 31, 11, -5, -22, -39, -56, -72, -81,
+ -85, -81, -71, -56, -36, -16, 4, 19, 29, 37, 48, 55, 56, 48, 34, 20,
+ 7, -10, -25, -32, -34, -28, -21, -17, -14, 0, 20, 40, 50, 51, 53, 58,
+ 61, 53, 39, 18, -2, -18, -36, -53, -70, -80, -85, -86, -79, -67, -46, -23,
+ -2, 17, 27, 35, 44, 55, 62, 57, 44, 26, 9, -10, -23, -29, -32, -28,
+ -24, -20, -15, -4, 15, 35, 47, 50, 49, 53, 57, 53, 43, 24, 5, -14,
+ -32, -50, -64, -5, 0, -2, -3, -3, -3, -3, -2, -2, 1, 2, 3, 5,
+ 8, 11, 11, 10, 8, 5, 1, -6, -13, -19, -21, -18, -15, -13, -10, -7,
+ -2, 4, 8, 12, 17, 28, 33, 29, 23, 14, 7, -5, -19, -33, -42, -36,
+ -28, -24, -17, -13, -8, 1, 7, 15, 23, 33, 42, 42, 35, 26, 15, 0,
+ -16, -30, -44, -45, -34, -27, -20, -16, -13, -4, 4, 12, 21, 29, 40, 45,
+ 40, 30, 20, 6, -13, -25, -38, -45, -38, -31, -24, -18, -15, -10, -4, 5,
+ 17, 27, 35, 44, 43, 37, 27, 15, -4, -19, -31, -44, -44, -35, -30, -22,
+ -19, -16, -8, 2, 15, 25, 32, 42, 47, 42, 32, 18, 0, -16, -26, -39,
+ -45, -38, -31, -25, -19, -18, -14, -5, 11, 23, 29, 39, 46, 45, 38, 25,
+ 7, -8, -18, -31, -44, -43, -35, -30, -25, -25, -20, -9, 7, 21, 27, 36,
+ 48, 51, 44, 32, 14, -3, -16, -28, -42, -46, -41, -33, -27, -24, -23, -15,
+ 1, 16, 27, 33, 42, 47, 46, 38, 21, 5, -9, -21, -34, -44, -45, -39,
+ -31, -28, -26, -20, -8, 9, 25, 34, 41, 49, 51, 47, 31, 11, -6, -18,
+ -30, -42, -48, -45, -36, -28, -26, -23, -12, 6, 23, 33, 38, 43, 51, 50,
+ 36, 15, 0, -12, -22, -35, -50, -50, -40, -31, -29, -27, -18, 1, 20, 32,
+ 36, 43, 52, 56, 45, 23, 2, -10, -20, -33, -48, -56, -49, -36, -30, -26,
+ -18, -5, 17, 33, 39, 40, 46, 52, 49, 32, 9, -8, -18, -26, -40, -54,
+ -53, -39, -30, -28, -23, -12, 10, 31, 39, 38, 42, 54, 54, 41, 17, -5,
+ -15, -22, -35, -53, -59, -47, -36, -30, -24, -14, 6, 27, 40, 42, 43, 51,
+ 56, 46, 26, 3, -13, -22, -33, -49, -61, -55, -41, -32, -26, -18, 0, 22,
+ 38, 45, 43, 48, 55, 50, 33, 11, -10, -21, -29, -43, -59, -60, -46, -35,
+ -28, -18, -6, 15, 35, 45, 46, 45, 52, 53, 41, 20, -6, -19, -26, -38,
+ -54, -62, -53, -39, -29, -19, -11, 6, 29, 44, 48, 45, 47, 52, 49, 32,
+ 5, -18, -26, -32, -45, -61, -61, -48, -35, -23, -14, -2, 22, 42, 52, 50,
+ 46, 50, 50, 38, 12, -15, -26, -31, -43, -59, -65, -53, -37, -25, -16, -6,
+ 16, 40, 53, 53, 47, 49, 51, 42, 22, -10, -27, -31, -38, -54, -67, -63,
+ -46, -27, -18, -7, 10, 31, 52, 59, 53, 48, 50, 46, 32, 3, -24, -34,
+ -39, -50, -66, -68, -54, -35, -20, -8, 6, 23, 47, 62, 59, 52, 50, 48,
+ 37, 13, -18, -35, -40, -46, -62, -72, -63, -43, -25, -10, 6, 20, 41, 59,
+ 63, 55, 49, 46, 39, 21, -9, -31, -39, -42, -52, -68, -68, -52, -32, -17,
+ -4, 9, 31, 54, 66, 63, 54, 51, 44, 32, 6, -26, -40, -44, -51, -65,
+ -72, -61, -41, -23, -5, 9, 25, 48, 64, 66, 59, 54, 46, 33, 12, -17,
+ -36, -45, -51, -62, -73, -67, -48, -31, -11, 8, 21, 44, 64, 70, 64, 57,
+ 49, 36, 20, -8, -34, -47, -52, -58, -68, -73, -59, -40, -19, 4, 17, 36,
+ 58, 72, 73, 65, 56, 41, 26, 4, -24, -44, -55, -63, -69, -73, -66, -51,
+ -28, -2, 18, 32, 51, 67, 75, 72, 62, 46, 29, 11, -13, -37, -54, -64,
+ -70, -71, -70, -58, -38, -13, 14, 30, 48, 64, 73, 76, 69, 52, 34, 15,
+ -7, -31, -50, -62, -69, -71, -71, -66, -47, -19, 8, 26, 40, 58, 73, 81,
+ 76, 57, 39, 23, 2, -22, -45, -62, -71, -73, -71, -69, -57, -32, 0, 26,
+ 41, 55, 70, 81, 83, 64, 41, 24, 6, -15, -39, -60, -71, -73, -69, -69,
+ -62, -40, -11, 20, 39, 51, 65, 78, 86, 75, 50, 29, 11, -8, -30, -53,
+ -70, -77, -71, -66, -67, -53, -22, 13, 37, 49, 60, 75, 89, 84, 58, 33,
+ 16, -2, -22, -47, -68, -77, -72, -67, -68, -60, -34, 0, 29, 47, 56, 69,
+ 85, 88, 69, 40, 20, 4, -13, -35, -61, -76, -74, -65, -66, -65, -47, -15,
+ 20, 43, 53, 64, 81, 89, 77, 50, 26, 9, -10, -29, -51, -71, -78, -71,
+ -66, -64, -52, -27, 9, 38, 54, 62, 73, 85, 82, 60, 34, 13, -3, -19,
+ -40, -65, -80, -74, -68, -69, -61, -40, -4, 29, 49, 61, 72, 86, 86, 70,
+ 45, 21, 3, -16, -33, -56, -80, -78, -70, -70, -65, -50, -18, 20, 48, 62,
+ 68, 80, 88, 78, 53, 26, 5, -12, -26, -45, -72, -81, -71, -67, -64, -56,
+ -34, 4, 37, 57, 63, 73, 85, 83, 63, 37, 16, 0, -17, -36, -63, -79,
+ -74, -70, -69, -63, -44, -10, 26, 52, 62, 69, 81, 84, 69, 45, 22, 3,
+ -15, -28, -52, -75, -76, -69, -67, -64, -52, -24, 14, 45, 60, 65, 74, 82,
+ 75, 54, 32, 12, -6, -21, -44, -68, -78, -74, -71, -69, -60, -34, 2, 34,
+ 55, 66, 73, 79, 78, 61, 39, 20, 2, -16, -34, -56, -72, -74, -70, -71,
+ -66, -47, -14, 21, 48, 61, 68, 76, 80, 69, 46, 27, 11, -7, -26, -50,
+ -68, -72, -70, -70, -69, -54, -24, 10, 39, 57, 66, 72, 76, 70, 52, 33,
+ 16, -4, -20, -39, -59, -70, -71, -69, -67, -60, -37, -6, 27, 50, 62, 67,
+ 72, 74, 61, 41, 25, 10, -10, -31, -51, -67, -74, -73, -73, -68, -48, -16,
+ 17, 45, 60, 66, 73, 75, 66, 48, 29, 15, -3, -24, -45, -62, -70, -72,
+ -74, -70, -55, -26, 7, 32, 51, 63, 70, 73, 67, 51, 35, 24, 9, -16,
+ -38, -54, -64, -68, -75, -75, -62, -36, -5, 22, 45, 60, 69, 74, 68, 57,
+ 43, 29, 15, -9, -29, -45, -60, -67, -75, -76, -64, -44, -16, 10, 32, 52,
+ 63, 68, 66, 59, 48, 36, 24, 6, -17, -35, -51, -60, -70, -78, -72, -55,
+ -27, 1, 20, 39, 56, 65, 68, 60, 51, 41, 31, 15, -9, -27, -44, -58,
+ -67, -75, -73, -58, -35, -8, 11, 32, 50, 60, 61, 57, 53, 47, 37, 25,
+ 4, -19, -35, -48, -60, -73, -76, -67, -46, -18, 2, 20, 40, 56, 64, 62,
+ 56, 49, 43, 34, 15, -10, -31, -45, -57, -70, -78, -69, -52, -27, -4, 13,
+ 34, 52, 60, 57, 53, 52, 46, 36, 22, 1, -19, -35, -50, -65, -73, -70,
+ -58, -41, -17, 4, 22, 42, 55, 58, 57, 55, 50, 43, 32, 12, -11, -30,
+ -47, -61, -71, -72, -63, -46, -26, -6, 13, 30, 47, 53, 54, 56, 52, 46,
+ 38, 24, 5, -20, -39, -52, -63, -67, -66, -57, -37, -15, 3, 18, 37, 50,
+ 55, 59, 55, 49, 45, 32, 15, -10, -34, -50, -61, -66, -66, -58, -42, -24,
+ -4, 11, 27, 44, 50, 54, 57, 53, 49, 39, 23, 2, -23, -43, -57, -64,
+ -67, -62, -50, -33, -14, 4, 18, 37, 48, 53, 57, 55, 52, 44, 30, 13,
+ -14, -38, -54, -62, -65, -62, -54, -42, -24, -2, 13, 28, 41, 48, 56, 57,
+ 52, 45, 37, 23, 0, -28, -47, -57, -62, -63, -59, -50, -34, -14, 1, 16,
+ 35, 48, 56, 59, 59, 54, 45, 31, 8, -20, -42, -56, -62, -64, -60, -52,
+ -40, -23, -5, 10, 28, 43, 52, 56, 57, 56, 49, 38, 21, -8, -33, -46,
+ -56, -60, -59, -56, -47, -32, -15, 0, 17, 34, 47, 55, 58, 57, 53, 43,
+ 30, 8, -24, -42, -52, -59, -58, -57, -51, -42, -26, -8, 11, 29, 42, 50,
+ 57, 59, 55, 48, 34, 15, -15, -36, -45, -52, -55, -58, -55, -43, -31, -17,
+ -2, 16, 37, 50, 56, 58, 58, 54, 43, 23, -8, -33, -40, -47, -54, -57,
+ -58, -48, -34, -23, -10, 9, 31, 48, 54, 55, 55, 57, 50, 32, 3, -28,
+ -37, -41, -49, -55, -58, -49, -36, -27, -17, 1, 21, 41, 50, 52, 51, 54,
+ 55, 41, 13, -18, -32, -35, -42, -50, -57, -55, -41, -32, -24, -10, 10, 33,
+ 47, 50, 51, 54, 59, 49, 24, -8, -26, -30, -37, -46, -56, -59, -46, -35,
+ -29, -18, 2, 25, 44, 48, 47, 51, 57, 56, 36, 5, -20, -28, -31, -40,
+ -51, -58, -52, -39, -33, -25, -8, 15, 38, 49, 47, 50, 56, 60, 46, 15,
+ -11, -25, -30, -36, -49, -60, -54, -39, -33, -30, -14, 8, 32, 47, 44, 44,
+ 51, 59, 52, 26, -4, -20, -24, -29, -41, -54, -55, -43, -34, -33, -26, -8,
+ 17, 37, 43, 42, 48, 59, 60, 42, 13, -11, -21, -25, -36, -51, -59, -51,
+ -38, -34, -32, -17, 10, 33, 43, 43, 44, 55, 60, 46, 21, -6, -18, -22,
+ -28, -42, -54, -52, -39, -30, -32, -25, -4, 20, 36, 39, 39, 48, 60, 57,
+ 36, 10, -11, -19, -22, -34, -51, -58, -48, -35, -36, -34, -13, 13, 35, 41,
+ 38, 46, 59, 61, 44, 20, -5, -20, -22, -30, -46, -56, -53, -39, -34, -36,
+ -22, 1, 25, 39, 39, 42, 53, 60, 54, 34, 10, -10, -17, -21, -39, -57,
+ -59, -48, -38, -43, -35, -11, 16, 37, 43, 42, 52, 61, 58, 41, 19, -3,
+ -16, -21, -31, -50, -59, -53, -40, -39, -39, -22, 5, 30, 40, 38, 45, 58,
+ 64, 52, 28, 5, -12, -17, -23, -44, -58, -56, -46, -40, -43, -33, -7, 22,
+ 39, 41, 44, 55, 64, 60, 40, 13, -7, -16, -21, -35, -56, -60, -52, -44,
+ -43, -40, -21, 11, 34, 40, 40, 50, 61, 64, 53, 29, 6, -10, -16, -25,
+ -47, -62, -61, -53, -49, -47, -35, -5, 26, 42, 45, 49, 58, 65, 59, 39,
+ 15, -5, -16, -22, -37, -56, -61, -56, -50, -47, -42, -21, 11, 33, 40, 44,
+ 53, 63, 66, 54, 29, 8, -6, -15, -28, -52, -64, -60, -57, -53, -49, -31,
+ 1, 28, 40, 42, 51, 63, 66, 56, 36, 14, -3, -13, -25, -45, -61, -61,
+ -58, -54, -47, -38, -11, 20, 36, 41, 44, 55, 64, 60, 47, 28, 9, -4,
+ -15, -32, -56, -67, -64, -62, -55, -48, -27, 8, 29, 41, 47, 57, 66, 65,
+ 56, 39, 17, 0, -13, -27, -49, -66, -68, -67, -58, -48, -36, -8, 22, 38,
+ 45, 53, 63, 65, 61, 51, 28, 11, -4, -20, -40, -62, -70, -71, -68, -55,
+ -44, -24, 9, 30, 42, 52, 66, 69, 64, 58, 42, 20, 4, -14, -34, -57,
+ -71, -73, -73, -63, -51, -35, -5, 23, 38, 48, 62, 71, 69, 65, 54, 32,
+ 14, -6, -26, -48, -68, -79, -82, -72, -57, -42, -18, 11, 33, 48, 63, 73,
+ 72, 68, 62, 46, 22, 0, -21, -42, -63, -76, -83, -80, -65, -49, -28, -2,
+ 23, 42, 58, 71, 75, 72, 68, 56, 33, 10, -12, -32, -54, -73, -84, -87,
+ -73, -54, -36, -15, 11, 34, 52, 67, 73, 73, 72, 66, 48, 21, -6, -26,
+ -47, -67, -80, -88, -81, -62, -41, -23, 0, 27, 47, 65, 74, 74, 71, 67,
+ 57, 33, 4, -20, -42, -64, -77, -88, -88, -72, -49, -27, -7, 16, 40, 63,
+ 75, 75, 74, 69, 64, 46, 16, -13, -35, -57, -74, -87, -93, -81, -58, -35,
+ -17, 6, 33, 59, 73, 76, 76, 71, 68, 58, 29, -4, -29, -48, -68, -83,
+ -94, -92, -70, -42, -22, -4, 21, 51, 73, 78, 76, 73, 70, 63, 40, 7,
+ -24, -42, -60, -79, -91, -92, -76, -52, -30, -12, 9, 39, 66, 76, 76, 75,
+ 74, 70, 54, 24, -12, -36, -52, -72, -93, -100, -90, -64, -38, -21, -5, 25,
+ 61, 81, 81, 77, 78, 76, 63, 33, -5, -33, -49, -67, -90, -100, -92, -71,
+ -44, -21, -8, 14, 49, 75, 82, 77, 76, 75, 66, 45, 10, -27, -45, -59,
+ -80, -98, -98, -81, -52, -26, -12, 2, 34, 71, 86, 80, 75, 77, 71, 54,
+ 23, -17, -44, -57, -74, -93, -99, -87, -65, -36, -14, -4, 20, 55, 79, 82,
+ 78, 78, 75, 65, 41, 1, -34, -52, -67, -88, -104, -98, -76, -47, -23, -12,
+ 6, 45, 81, 90, 81, 79, 81, 72, 50, 11, -28, -50, -61, -81, -102, -103,
+ -84, -57, -30, -13, 1, 30, 70, 92, 88, 81, 80, 75, 59, 27, -15, -48,
+ -62, -76, -97, -106, -94, -69, -39, -16, -4, 17, 59, 92, 94, 87, 86, 83,
+ 67, 36, -4, -38, -61, -77, -96, -111, -102, -80, -53, -26, -8, 14, 50, 89,
+ 101, 93, 87, 83, 73, 46, 7, -31, -58, -72, -87, -106, -106, -88, -59, -31,
+ -12, 5, 33, 74, 99, 99, 90, 84, 78, 57, 22, -18, -49, -70, -84, -100,
+ -108, -96, -72, -43, -21, -3, 24, 61, 95, 106, 99, 90, 82, 65, 34, -6,
+ -40, -66, -83, -96, -106, -102, -82, -52, -27, -8, 15, 48, 86, 107, 105, 94,
+ 85, 73, 45, 6, -32, -61, -80, -91, -102, -106, -92, -63, -35, -15, 8, 37,
+ 74, 102, 109, 98, 87, 76, 54, 21, -16, -50, -76, -89, -98, -104, -98, -76,
+ -46, -23, -2, 25, 60, 93, 111, 106, 92, 82, 65, 35, -5, -39, -66, -83,
+ -95, -105, -105, -86, -57, -33, -11, 15, 50, 86, 111, 115, 102, 88, 71, 43,
+ 7, -32, -64, -86, -96, -100, -102, -92, -67, -40, -13, 13, 42, 75, 103, 116,
+ 106, 90, 74, 49, 16, -21, -54, -80, -94, -98, -100, -94, -75, -50, -23, 4,
+ 30, 62, 95, 117, 115, 100, 81, 57, 28, -10, -46, -75, -95, -102, -101, -97,
+ -83, -61, -32, -2, 24, 55, 87, 111, 118, 106, 88, 65, 35, 0, -36, -67,
+ -89, -101, -102, -98, -89, -68, -43, -13, 16, 46, 80, 107, 121, 116, 98, 75,
+ 47, 11, -27, -62, -87, -101, -104, -100, -93, -77, -51, -18, 13, 36, 67, 99,
+ 119, 119, 103, 81, 53, 21, -16, -52, -79, -96, -106, -102, -93, -82, -60, -30,
+ 3, 30, 59, 88, 111, 121, 111, 89, 61, 30, -4, -41, -74, -94, -106, -104,
+ -95, -87, -70, -41, -8, 22, 49, 81, 106, 120, 118, 98, 73, 41, 8, -30,
+ -64, -87, -104, -111, -100, -91, -77, -51, -21, 13, 41, 73, 100, 117, 122, 107,
+ 83, 52, 19, -18, -55, -82, -101, -111, -105, -93, -83, -60, -29, 5, 35, 64,
+ 92, 112, 121, 112, 88, 61, 29, -7, -45, -75, -94, -108, -108, -96, -87, -67,
+ -37, -5, 26, 52, 83, 105, 116, 116, 97, 70, 41, 7, -33, -67, -91, -105,
+ -110, -99, -88, -73, -48, -18, 15, 45, 74, 98, 114, 118, 104, 79, 51, 17,
+ -21, -58, -86, -102, -109, -103, -90, -77, -54, -23, 9, 36, 62, 88, 107, 114,
+ 107, 88, 63, 30, -8, -46, -77, -96, -107, -108, -97, -81, -63, -36, -4, 30,
+ 59, 84, 104, 115, 112, 95, 69, 38, 5, -33, -69, -94, -104, -105, -99, -87,
+ -72, -44, -11, 21, 47, 71, 97, 113, 113, 99, 77, 49, 17, -19, -57, -87,
+ -101, -105, -103, -90, -72, -54, -24, 10, 41, 64, 86, 104, 111, 104, 85, 57,
+ 25, -7, -42, -75, -96, -101, -98, -92, -79, -61, -36, -4, 28, 51, 74, 98,
+ 110, 107, 94, 70, 38, 5, -30, -64, -89, -101, -101, -95, -79, -63, -43, -14,
+ 21, 48, 68, 90, 105, 108, 97, 74, 44, 12, -20, -52, -83, -96, -96, -92,
+ -82, -67, -49, -24, 10, 39, 59, 79, 99, 107, 101, 83, 54, 21, -11, -41,
+ -71, -92, -98, -95, -84, -68, -54, -35, -5, 28, 54, 73, 92, 103, 103, 90,
+ 64, 31, -4, -34, -63, -85, -94, -92, -84, -70, -56, -38, -11, 19, 44, 64,
+ 83, 95, 98, 90, 66, 39, 9, -22, -50, -73, -86, -89, -84, -72, -59, -45,
+ -23, 6, 35, 58, 75, 89, 96, 92, 75, 49, 19, -14, -42, -63, -80, -88,
+ -84, -74, -60, -48, -30, -5, 23, 52, 70, 82, 91, 91, 79, 57, 29, -3,
+ -33, -54, -70, -84, -87, -79, -65, -50, -35, -16, 10, 41, 68, 80, 85, 88,
+ 82, 64, 36, 3, -28, -49, -60, -72, -83, -81, -66, -49, -37, -22, -2, 28,
+ 58, 74, 78, 83, 81, 69, 45, 14, -18, -42, -55, -66, -77, -79, -68, -53,
+ -39, -25, -8, 17, 46, 67, 72, 75, 74, 70, 53, 24, -9, -34, -48, -55,
+ -64, -74, -70, -55, -40, -28, -17, 3, 33, 61, 70, 71, 69, 68, 61, 37,
+ 3, -28, -44, -50, -57, -70, -73, -58, -41, -30, -21, -8, 21, 52, 67, 69,
+ 66, 66, 64, 44, 10, -22, -39, -48, -52, -61, -72, -62, -43, -29, -20, -12,
+ 7, 38, 62, 68, 61, 56, 60, 51, 23, -12, -36, -43, -44, -49, -65, -65,
+ -45, -29, -22, -19, -7, 24, 52, 65, 57, 52, 58, 57, 36, 0, -30, -38,
+ -37, -39, -55, -66, -52, -33, -23, -21, -14, 10, 40, 60, 59, 49, 51, 54,
+ 43, 11, -21, -35, -37, -33, -42, -55, -49, -29, -19, -20, -19, -5, 23, 49,
+ 54, 43, 42, 50, 49, 23, -12, -30, -34, -29, -31, -49, -54, -35, -19, -16,
+ -18, -11, 10, 39, 55, 45, 35, 41, 47, 31, -3, -26, -33, -28, -23, -36,
+ -47, -36, -18, -11, -16, -16, -3, 21, 42, 42, 32, 32, 40, 35, 13, -13,
+ -25, -24, -17, -22, -37, -38, -25, -16, -16, -19, -11, 7, 30, 42, 34, 27,
+ 33, 35, 19, -6, -21, -23, -17, -14, -23, -29, -21, -11, -10, -17, -16, -4,
+ 14, 30, 31, 20, 21, 29, 24, 6, -11, -16, -11, -5, -10, -20, -22, -15,
+ -12, -17, -21, -15, 0, 20, 29, 22, 17, 23, 25, 16, -2, -14, -14, -7,
+ -2, -9, -14, -12, -9, -11, -17, -17, -11, 3, 18, 17, 9, 13, 19, 17,
+ 7, -5, -5, 3, 8, 3, -7, -10, -12, -14, -20, -22, -17, -7, 9, 17,
+ 10, 8, 15, 18, 11, 2, -3, 1, 8, 9, 5, -3, -9, -12, -18, -21,
+ -21, -19, -4, 10, 9, 2, 5, 14, 16, 11, 4, 5, 13, 16, 14, 6,
+ -8, -14, -19, -23, -24, -21, -13, -2, 7, 3, -2, 8, 12, 11, 9, 10,
+ 14, 19, 20, 16, 4, -9, -17, -23, -26, -27, -24, -14, -2, 1, -5, 3,
+ 15, 17, 14, 14, 17, 22, 25, 20, 9, -8, -19, -25, -30, -29, -26, -22,
+ -11, 0, -3, -3, 9, 16, 19, 20, 21, 24, 28, 28, 20, 2, -16, -25,
+ -30, -34, -33, -32, -23, -9, -6, -8, 2, 15, 21, 24, 26, 29, 33, 34,
+ 30, 14, -11, -26, -33, -38, -38, -37, -34, -23, -12, -7, 0, 11, 21, 29,
+ 34, 35, 37, 39, 35, 21, -5, -26, -34, -39, -40, -42, -42, -31, -17, -9,
+ -4, 7, 19, 31, 38, 38, 41, 42, 40, 28, 3, -22, -36, -42, -45, -46,
+ -46, -37, -23, -14, -6, 6, 20, 32, 40, 40, 44, 46, 41, 31, 13, -12,
+ -32, -44, -47, -48, -49, -44, -32, -20, -8, 3, 15, 27, 40, 45, 47, 50,
+ 47, 39, 21, -6, -29, -42, -46, -51, -56, -52, -41, -24, -13, -4, 11, 27,
+ 41, 51, 52, 53, 52, 45, 29, 2, -25, -45, -50, -52, -57, -56, -49, -32,
+ -16, -4, 9, 22, 36, 49, 55, 56, 56, 50, 35, 11, -14, -37, -51, -57,
+ -61, -61, -56, -41, -23, -8, 8, 21, 33, 48, 61, 64, 60, 54, 40, 17,
+ -8, -34, -52, -59, -62, -63, -60, -49, -30, -14, 2, 19, 33, 47, 60, 66,
+ 67, 65, 50, 25, -3, -26, -47, -59, -68, -72, -66, -57, -38, -20, -5, 14,
+ 30, 44, 61, 71, 71, 68, 57, 34, 7, -20, -43, -58, -68, -72, -69, -62,
+ -45, -25, -10, 7, 24, 42, 59, 70, 74, 73, 65, 46, 16, -15, -38, -53,
+ -65, -77, -77, -70, -54, -34, -19, 0, 20, 41, 60, 74, 82, 80, 71, 54,
+ 27, -8, -36, -55, -68, -78, -82, -76, -61, -40, -20, -2, 17, 36, 57, 74,
+ 83, 82, 74, 62, 39, 3, -31, -49, -62, -75, -84, -84, -69, -47, -27, -13,
+ 6, 31, 56, 73, 82, 86, 80, 68, 49, 14, -24, -46, -60, -74, -83, -86,
+ -76, -54, -32, -15, 3, 23, 48, 71, 85, 87, 80, 71, 57, 27, -12, -41,
+ -57, -68, -78, -88, -84, -64, -41, -23, -5, 16, 40, 65, 84, 90, 87, 77,
+ 63, 36, -3, -34, -57, -69, -76, -85, -87, -73, -48, -27, -8, 13, 34, 60,
+ 83, 91, 86, 77, 66, 44, 9, -26, -53, -68, -74, -83, -88, -80, -56, -33,
+ -13, 9, 29, 55, 79, 93, 89, 76, 67, 52, 21, -15, -46, -69, -74, -77,
+ -84, -86, -67, -42, -20, 4, 23, 43, 71, 94, 95, 80, 67, 56, 32, 0,
+ -37, -66, -74, -73, -78, -87, -76, -50, -25, 1, 21, 37, 61, 88, 97, 84,
+ 67, 57, 38, 8, -25, -59, -77, -77, -76, -81, -80, -61, -34, -6, 20, 36,
+ 55, 80, 96, 91, 70, 54, 39, 17, -14, -51, -75, -79, -75, -77, -80, -68,
+ -40, -11, 15, 33, 48, 71, 92, 91, 73, 57, 45, 24, -3, -38, -68, -79,
+ -77, -76, -80, -74, -51, -19, 12, 32, 46, 65, 88, 96, 83, 59, 40, 24,
+ 4, -31, -67, -83, -80, -73, -73, -72, -55, -24, 9, 31, 44, 58, 78, 90,
+ 84, 63, 42, 28, 10, -18, -53, -77, -82, -76, -73, -74, -65, -37, -2, 27,
+ 42, 55, 73, 88, 90, 72, 47, 28, 13, -12, -45, -74, -84, -78, -70, -68,
+ -63, -43, -9, 23, 42, 52, 64, 78, 84, 75, 52, 32, 17, -3, -32, -62,
+ -79, -78, -71, -67, -65, -52, -19, 15, 38, 50, 61, 73, 80, 79, 59, 34,
+ 18, 3, -21, -51, -75, -81, -72, -64, -61, -54, -31, 4, 31, 48, 55, 63,
+ 73, 78, 67, 40, 21, 8, -12, -39, -65, -80, -76, -65, -58, -52, -38, -8,
+ 25, 45, 56, 61, 67, 74, 69, 47, 22, 7, -10, -31, -56, -75, -77, -66,
+ -57, -49, -37, -14, 16, 40, 53, 57, 61, 67, 69, 55, 30, 11, -6, -25,
+ -47, -69, -78, -70, -59, -51, -40, -20, 10, 34, 51, 58, 59, 63, 66, 59,
+ 36, 14, -2, -19, -40, -61, -75, -71, -59, -51, -41, -27, -2, 26, 47, 58,
+ 58, 59, 64, 63, 46, 19, -2, -17, -35, -56, -71, -75, -64, -50, -40, -26,
+ -6, 21, 43, 55, 57, 56, 58, 59, 47, 23, 1, -13, -29, -48, -63, -69,
+ -61, -48, -40, -29, -11, 13, 35, 48, 53, 51, 53, 57, 50, 33, 9, -10,
+ -25, -42, -56, -65, -64, -51, -40, -29, -13, 9, 30, 44, 50, 48, 47, 50,
+ 46, 35, 13, -8, -20, -33, -47, -57, -56, -48, -38, -30, -16, 1, 21, 35,
+ 44, 46, 42, 44, 44, 39, 21, -3, -18, -30, -40, -51, -57, -51, -37, -26,
+ -14, 0, 16, 33, 42, 43, 37, 34, 37, 35, 22, 1, -17, -27, -34, -41,
+ -48, -45, -36, -25, -11, 0, 11, 24, 34, 38, 35, 30, 29, 30, 24, 8,
+ -11, -24, -31, -36, -42, -42, -35, -25, -12, -2, 9, 21, 29, 33, 32, 27,
+ 25, 26, 23, 9, -8, -21, -31, -34, -36, -37, -33, -26, -13, -2, 8, 18,
+ 24, 28, 29, 27, 22, 20, 21, 14, -2, -17, -27, -30, -31, -33, -32, -26,
+ -14, -3, 6, 15, 22, 27, 26, 25, 22, 17, 17, 13, 3, -12, -25, -30,
+ -31, -30, -27, -24, -14, 0, 8, 16, 20, 22, 22, 21, 16, 11, 13, 13,
+ 3, -8, -21, -27, -26, -25, -25, -23, -12, 0, 6, 12, 18, 20, 22, 20,
+ 15, 9, 9, 10, 3, -9, -21, -29, -28, -23, -20, -19, -10, 3, 13, 17,
+ 19, 19, 21, 17, 11, 4, 1, 4, 0, -8, -17, -25, -24, -21, -19, -16,
+ -9, 4, 13, 17, 19, 20, 22, 19, 11, 3, -4, -3, -4, -12, -18, -26,
+ -28, -23, -16, -10, -5, 5, 18, 25, 25, 22, 21, 19, 9, 0, -9, -11,
+ -10, -13, -16, -24, -27, -22, -14, -8, -2, 7, 17, 25, 25, 22, 20, 17,
+ 10, -2, -10, -12, -13, -15, -18, -20, -24, -22, -16, -8, 3, 11, 17, 25,
+ 27, 23, 21, 17, 9, 0, -10, -12, -13, -18, -19, -20, -24, -23, -17, -10,
+ 0, 11, 19, 26, 30, 26, 24, 20, 12, 3, -8, -15, -18, -22, -25, -25,
+ -25, -24, -20, -12, 2, 15, 20, 25, 31, 33, 29, 23, 12, 3, -5, -15,
+ -23, -28, -28, -25, -22, -22, -18, -10, 2, 15, 19, 23, 30, 32, 28, 24,
+ 15, 7, 1, -13, -23, -27, -29, -28, -26, -24, -20, -14, -2, 13, 20, 24,
+ 32, 34, 32, 29, 22, 9, -2, -10, -21, -30, -34, -34, -29, -22, -20, -18,
+ -5, 14, 23, 25, 31, 36, 35, 30, 22, 10, 0, -8, -21, -34, -39, -36,
+ -32, -27, -20, -15, -5, 14, 27, 28, 32, 36, 35, 33, 25, 14, 0, -11,
+ -21, -34, -40, -41, -39, -30, -20, -13, -6, 10, 27, 30, 32, 35, 34, 36,
+ 29, 17, 5, -7, -16, -33, -45, -45, -43, -33, -24, -18, -9, 8, 26, 32,
+ 33, 39, 38, 36, 31, 20, 10, -6, -19, -32, -45, -47, -46, -39, -25, -12,
+ -3, 8, 22, 32, 32, 35, 35, 32, 31, 23, 14, 0, -15, -26, -43, -51,
+ -50, -43, -29, -17, -6, 5, 19, 34, 36, 33, 37, 37, 34, 25, 16, 5,
+ -11, -26, -41, -51, -55, -51, -36, -21, -7, 7, 16, 28, 37, 35, 35, 36,
+ 34, 30, 20, 9, -7, -22, -37, -49, -56, -54, -42, -25, -11, 2, 13, 24,
+ 35, 38, 37, 38, 37, 32, 25, 16, 1, -21, -38, -47, -56, -58, -50, -34,
+ -14, 4, 13, 20, 31, 40, 39, 35, 36, 34, 28, 20, 5, -15, -33, -44,
+ -55, -63, -54, -38, -19, -2, 10, 17, 30, 40, 41, 36, 38, 41, 33, 22,
+ 9, -13, -36, -50, -55, -63, -61, -44, -22, 2, 18, 22, 28, 38, 42, 39,
+ 34, 35, 34, 27, 14, -7, -29, -43, -51, -60, -63, -50, -30, -10, 8, 16,
+ 21, 32, 40, 40, 38, 39, 41, 35, 24, 6, -20, -41, -54, -62, -65, -58,
+ -39, -16, 7, 18, 22, 29, 39, 43, 40, 35, 38, 37, 27, 12, -14, -37,
+ -51, -58, -64, -64, -47, -22, -2, 14, 18, 24, 36, 44, 45, 41, 43, 43,
+ 32, 17, -8, -35, -54, -63, -67, -68, -56, -29, -4, 16, 24, 26, 35, 44,
+ 47, 43, 38, 38, 36, 24, 0, -30, -50, -57, -59, -63, -61, -40, -11, 11,
+ 20, 20, 26, 39, 48, 46, 40, 39, 42, 33, 12, -20, -47, -58, -60, -62,
+ -61, -49, -23, 2, 17, 21, 22, 33, 48, 51, 45, 43, 43, 38, 20, -10,
+ -41, -58, -61, -64, -62, -55, -35, -9, 10, 21, 23, 32, 50, 57, 49, 45,
+ 45, 43, 26, -6, -38, -58, -62, -65, -67, -61, -44, -15, 10, 23, 26, 28,
+ 44, 59, 55, 46, 42, 41, 33, 6, -30, -57, -64, -62, -64, -62, -50, -26,
+ 2, 18, 26, 28, 39, 59, 60, 48, 43, 43, 37, 14, -22, -53, -67, -63,
+ -65, -66, -55, -33, -2, 19, 28, 31, 37, 55, 64, 53, 41, 39, 37, 20,
+ -16, -48, -66, -65, -62, -66, -60, -43, -12, 15, 26, 31, 37, 53, 69, 63,
+ 46, 39, 38, 27, -5, -44, -72, -73, -65, -65, -63, -52, -24, 11, 31, 36,
+ 38, 48, 65, 70, 53, 38, 34, 28, 5, -35, -69, -78, -70, -65, -63, -53,
+ -30, 2, 26, 38, 43, 49, 62, 69, 58, 40, 33, 28, 9, -25, -61, -78,
+ -75, -69, -64, -55, -37, -7, 22, 36, 43, 49, 57, 66, 62, 44, 31, 29,
+ 15, -16, -52, -76, -77, -69, -63, -57, -44, -16, 14, 33, 42, 48, 54, 65,
+ 68, 52, 33, 27, 19, -6, -41, -72, -82, -74, -65, -59, -48, -24, 7, 29,
+ 43, 50, 53, 60, 67, 58, 39, 28, 22, 2, -31, -64, -82, -79, -71, -61,
+ -49, -31, -2, 22, 40, 51, 55, 58, 65, 63, 46, 29, 21, 9, -21, -56,
+ -79, -83, -77, -65, -54, -37, -10, 16, 36, 50, 57, 60, 65, 64, 50, 33,
+ 22, 11, -13, -47, -73, -82, -80, -70, -57, -42, -19, 8, 30, 49, 58, 61,
+ 62, 64, 56, 41, 24, 11, -6, -35, -66, -80, -82, -75, -61, -45, -25, -2,
+ 22, 43, 57, 63, 64, 63, 58, 49, 31, 15, -2, -26, -58, -79, -85, -81,
+ -66, -49, -31, -9, 17, 39, 55, 64, 69, 67, 61, 53, 35, 16, 1, -20,
+ -49, -75, -86, -85, -74, -54, -34, -11, 11, 33, 53, 64, 70, 68, 59, 51,
+ 40, 22, 5, -15, -40, -66, -79, -81, -78, -63, -41, -19, 4, 25, 44, 58,
+ 67, 72, 65, 57, 47, 29, 11, -8, -31, -61, -81, -85, -82, -68, -47, -25,
+ -3, 21, 44, 59, 68, 73, 68, 56, 47, 33, 15, -7, -27, -52, -76, -82,
+ -82, -72, -52, -30, -7, 13, 36, 57, 67, 74, 72, 61, 48, 36, 20, -4,
+ -25, -47, -71, -81, -81, -75, -56, -33, -10, 11, 30, 49, 63, 73, 74, 63,
+ 48, 37, 25, 6, -20, -41, -63, -79, -81, -77, -65, -43, -19, 4, 25, 45,
+ 63, 73, 76, 70, 55, 41, 28, 10, -15, -38, -59, -77, -83, -79, -70, -49,
+ -25, -4, 20, 40, 59, 74, 76, 73, 62, 46, 33, 16, -10, -34, -51, -68,
+ -83, -85, -75, -58, -34, -11, 14, 35, 55, 73, 79, 76, 69, 51, 33, 20,
+ -2, -30, -53, -67, -81, -84, -76, -61, -39, -14, 11, 32, 49, 67, 77, 74,
+ 68, 55, 37, 23, 5, -22, -45, -59, -73, -84, -82, -68, -46, -24, 3, 26,
+ 43, 62, 75, 74, 72, 61, 42, 25, 10, -15, -40, -57, -70, -83, -84, -71,
+ -49, -28, -6, 20, 41, 59, 72, 72, 69, 63, 48, 29, 13, -8, -31, -51,
+ -66, -79, -84, -75, -56, -37, -16, 12, 36, 55, 71, 74, 72, 69, 54, 34,
+ 16, -5, -28, -47, -61, -75, -85, -80, -60, -38, -20, 4, 30, 53, 68, 71,
+ 69, 67, 57, 39, 20, 0, -21, -41, -58, -71, -79, -79, -66, -45, -25, -3,
+ 23, 45, 61, 68, 69, 70, 63, 47, 29, 8, -16, -37, -56, -71, -80, -81,
+ -71, -52, -30, -7, 17, 41, 60, 67, 67, 68, 65, 50, 30, 10, -14, -31,
+ -47, -65, -77, -79, -70, -53, -33, -14, 8, 34, 56, 62, 62, 66, 64, 54,
+ 36, 15, -8, -27, -42, -61, -73, -75, -70, -56, -36, -14, 5, 26, 49, 60,
+ 59, 61, 60, 54, 42, 23, -2, -22, -35, -53, -69, -75, -70, -58, -41, -20,
+ -3, 18, 43, 59, 57, 57, 60, 56, 44, 28, 7, -17, -32, -47, -63, -73,
+ -72, -62, -46, -23, -6, 12, 35, 55, 60, 57, 59, 56, 49, 35, 14, -13,
+ -28, -40, -58, -72, -73, -62, -50, -31, -13, 5, 30, 51, 59, 56, 58, 61,
+ 56, 38, 17, -9, -26, -37, -52, -68, -74, -63, -50, -32, -14, 1, 22, 45,
+ 57, 56, 51, 54, 54, 41, 21, -4, -22, -31, -44, -59, -69, -63, -48, -36,
+ -21, -7, 11, 35, 52, 56, 53, 54, 58, 48, 30, 8, -17, -32, -43, -57,
+ -68, -69, -56, -39, -22, -8, 6, 28, 49, 57, 54, 51, 55, 52, 35, 13,
+ -13, -29, -36, -49, -64, -70, -58, -39, -23, -11, 0, 19, 43, 57, 55, 47,
+ 49, 55, 43, 18, -9, -28, -35, -42, -57, -69, -65, -45, -25, -11, 1, 14,
+ 37, 55, 60, 50, 45, 48, 42, 21, -4, -25, -35, -40, -50, -60, -61, -46,
+ -27, -15, -6, 6, 25, 46, 56, 50, 43, 45, 47, 33, 9, -15, -30, -37,
+ -45, -58, -64, -56, -36, -18, -8, 4, 18, 40, 58, 59, 47, 39, 41, 35,
+ 12, -15, -32, -38, -39, -46, -57, -55, -37, -17, -7, 1, 11, 27, 48, 56,
+ 47, 37, 38, 38, 21, -6, -24, -32, -37, -43, -54, -57, -44, -25, -9, 2,
+ 11, 24, 44, 57, 51, 38, 32, 31, 21, -5, -28, -35, -36, -36, -45, -51,
+ -41, -25, -8, 3, 8, 17, 33, 48, 49, 37, 31, 30, 25, 7, -18, -30,
+ -34, -37, -40, -48, -47, -33, -16, 1, 11, 16, 28, 42, 50, 43, 30, 25,
+ 22, 10, -12, -28, -33, -34, -35, -41, -44, -33, -18, -2, 9, 12, 20, 32,
+ 43, 41, 29, 24, 22, 14, -3, -21, -29, -30, -31, -35, -41, -35, -21, -6,
+ 9, 13, 18, 27, 38, 42, 29, 18, 16, 13, 4, -15, -27, -28, -27, -28,
+ -34, -34, -23, -10, 5, 11, 14, 22, 32, 37, 31, 20, 16, 12, 6, -9,
+ -22, -25, -27, -26, -32, -34, -27, -15, 0, 10, 12, 18, 28, 36, 35, 23,
+ 14, 11, 8, -3, -19, -28, -28, -25, -27, -32, -28, -16, -2, 11, 14, 14,
+ 22, 30, 31, 24, 15, 11, 8, 2, -11, -22, -25, -25, -26, -30, -28, -18,
+ -7, 5, 12, 14, 19, 27, 30, 26, 19, 13, 9, 4, -6, -20, -26, -23,
+ -24, -27, -27, -19, -6, 4, 12, 12, 13, 22, 26, 22, 15, 11, 10, 6,
+ -2, -12, -19, -19, -21, -25, -25, -20, -11, -3, 5, 9, 13, 19, 24, 24,
+ 21, 15, 12, 7, 2, -9, -20, -22, -22, -23, -24, -22, -11, -2, 7, 11,
+ 13, 17, 21, 21, 18, 13, 11, 7, 1, -7, -15, -19, -19, -21, -20, -18,
+ -12, -4, 2, 8, 11, 15, 17, 16, 15, 13, 11, 8, 4, -3, -11, -16,
+ -15, -19, -20, -16, -12, -5, 2, 5, 8, 14, 17, 15, 11, 10, 9, 8,
+ 4, -2, -6, -11, -12, -14, -18, -13, -7, -6, -3, 2, 6, 10, 13, 13,
+ 9, 8, 9, 6, 1, 0, -5, -9, -12, -12, -13, -12, -4, 1, 3, 4,
+ 4, 7, 11, 10, 7, 3, 3, 4, 2, -2, -3, -6, -7, -6, -6, -8,
+ -5, 2, 1, 1, 0, 1, 5, 5, 3, 0, 0, 5, 5, 2, 3, 0,
+ -3, -5, -6, -8, -7, -2, -3, -4, -2, -2, 3, 6, 4, 1, -3, 1,
+ 5, 3, 2, 0, -2, -3, -4, -5, -5, 1, 2, -3, -3, -4, -3, 4,
+ 4, 0, -5, -3, 3, 3, 2, 1, 1, 0, 0, 0, -3, -2, 1, -2,
+ -4, -3, -4, 1, 5, 2, -5, -7, -2, 2, -2, -2, 0, 2, 3, 2,
+ 2, 3, 6, 4, -2, -5, -6, -2, 3, -2, -9, -11, -5, 0, -3, -4,
+ -2, 3, 7, 8, 4, 2, 4, 3, 0, -6, -8, -6, 2, 4, -3, -10,
+ -10, -5, -2, -4, -5, -3, 5, 11, 11, 8, 5, 5, 4, -2, -9, -9,
+ -2, 0, -5, -13, -14, -10, -5, -4, -2, 2, 6, 14, 15, 11, 8, 6,
+ 1, -5, -10, -12, -6, 1, -2, -10, -15, -11, -4, -3, -6, -5, 2, 14,
+ 19, 14, 10, 10, 8, 3, -6, -15, -12, -4, -4, -12, -18, -17, -10, -2,
+ 0, 1, 6, 16, 25, 21, 12, 8, 4, -2, -8, -18, -20, -11, -6, -9,
+ -14, -14, -10, -3, 0, 1, 6, 13, 23, 25, 17, 13, 9, 1, -6, -13,
+ -18, -14, -11, -13, -17, -19, -14, -8, -3, 1, 7, 14, 24, 30, 24, 16,
+ 12, 4, -5, -11, -18, -19, -15, -12, -14, -19, -18, -14, -9, 0, 8, 13,
+ 19, 27, 28, 22, 18, 9, -4, -11, -14, -16, -15, -16, -16, -17, -16, -14,
+ -13, -6, 4, 12, 19, 26, 31, 27, 19, 13, 3, -8, -12, -16, -18, -19,
+ -17, -16, -20, -18, -15, -10, 1, 10, 18, 24, 31, 30, 22, 18, 9, -4,
+ -10, -14, -17, -20, -22, -19, -19, -22, -18, -13, -2, 9, 16, 21, 29, 36,
+ 29, 19, 12, 1, -7, -10, -15, -22, -24, -20, -18, -21, -21, -17, -8, 7,
+ 16, 23, 27, 33, 35, 26, 17, 7, -5, -11, -14, -22, -27, -24, -19, -22,
+ -25, -19, -11, 5, 16, 21, 25, 33, 38, 31, 18, 9, -2, -10, -13, -22,
+ -29, -28, -21, -18, -24, -22, -15, -3, 14, 21, 24, 30, 38, 36, 24, 13,
+ 4, -5, -9, -16, -28, -32, -25, -21, -25, -27, -18, -7, 8, 18, 24, 31,
+ 40, 40, 29, 16, 6, -3, -8, -16, -27, -31, -27, -22, -24, -27, -21, -10,
+ 4, 16, 22, 28, 37, 40, 33, 19, 7, 1, -5, -12, -23, -32, -28, -23,
+ -23, -27, -26, -15, -2, 13, 21, 25, 34, 41, 38, 28, 14, 4, -3, -11,
+ -22, -34, -35, -30, -26, -28, -29, -20, -3, 14, 24, 27, 32, 41, 42, 34,
+ 17, 4, -4, -11, -20, -32, -38, -33, -28, -27, -27, -22, -9, 7, 20, 29,
+ 34, 39, 40, 37, 24, 10, 2, -7, -16, -28, -40, -40, -33, -29, -28, -27,
+ -16, 5, 21, 28, 32, 36, 41, 40, 30, 12, 1, -6, -11, -22, -37, -42,
+ -34, -30, -29, -27, -20, -3, 16, 27, 32, 34, 39, 41, 35, 20, 6, -4,
+ -11, -16, -32, -45, -41, -33, -31, -27, -23, -10, 13, 28, 33, 35, 38, 39,
+ 36, 25, 8, -6, -11, -14, -26, -42, -45, -34, -29, -25, -23, -15, 6, 26,
+ 36, 36, 36, 37, 36, 29, 14, -2, -12, -14, -23, -42, -50, -42, -32, -23,
+ -18, -15, 3, 25, 38, 39, 35, 35, 37, 33, 18, -3, -15, -18, -20, -34,
+ -48, -47, -34, -22, -14, -12, -4, 17, 35, 41, 37, 34, 33, 33, 24, 6,
+ -13, -22, -22, -30, -45, -51, -39, -23, -10, -6, -3, 13, 32, 41, 37, 30,
+ 29, 31, 27, 10, -10, -22, -23, -26, -38, -48, -44, -28, -12, -5, -3, 9,
+ 27, 38, 38, 32, 28, 29, 27, 17, -4, -21, -26, -27, -35, -47, -49, -33,
+ -12, 2, 5, 9, 23, 35, 40, 34, 21, 23, 25, 22, 5, -20, -28, -28,
+ -29, -39, -50, -43, -19, 3, 10, 7, 15, 29, 41, 43, 28, 22, 23, 22,
+ 12, -16, -33, -32, -32, -38, -46, -43, -21, 3, 15, 13, 16, 29, 35, 35,
+ 27, 19, 19, 19, 15, -8, -30, -31, -30, -32, -40, -44, -29, -2, 18, 17,
+ 11, 22, 34, 37, 32, 21, 18, 20, 17, -2, -28, -37, -34, -34, -38, -42,
+ -30, -7, 16, 22, 16, 20, 31, 31, 29, 23, 17, 18, 19, 6, -21, -37,
+ -35, -34, -35, -38, -35, -15, 14, 27, 21, 13, 23, 31, 31, 26, 16, 12,
+ 16, 12, -10, -35, -39, -35, -36, -36, -34, -21, 6, 24, 24, 16, 20, 29,
+ 28, 27, 22, 16, 17, 15, -4, -29, -41, -39, -40, -39, -36, -29, -6, 20,
+ 27, 21, 19, 28, 33, 31, 27, 18, 14, 13, 2, -22, -41, -43, -40, -39,
+ -34, -28, -12, 16, 28, 24, 19, 25, 29, 27, 24, 19, 15, 12, 4, -15,
+ -34, -41, -40, -37, -32, -26, -18, 5, 24, 24, 20, 21, 26, 27, 26, 24,
+ 18, 12, 6, -9, -30, -44, -45, -41, -33, -26, -19, -2, 23, 29, 24, 22,
+ 24, 28, 25, 22, 18, 13, 7, -7, -24, -40, -46, -42, -36, -28, -21, -6,
+ 15, 28, 25, 22, 25, 29, 28, 23, 20, 14, 6, -6, -22, -40, -47, -42,
+ -36, -28, -23, -10, 13, 30, 28, 21, 23, 27, 28, 21, 18, 16, 9, -2,
+ -17, -33, -44, -44, -38, -31, -23, -14, 5, 25, 32, 25, 23, 26, 29, 24,
+ 16, 13, 8, -2, -15, -31, -43, -44, -37, -30, -23, -14, 1, 21, 31, 27,
+ 22, 24, 28, 25, 17, 13, 10, 3, -10, -27, -40, -44, -38, -32, -26, -17,
+ -3, 16, 31, 31, 25, 25, 30, 29, 17, 8, 7, 3, -8, -25, -39, -43,
+ -37, -31, -27, -18, -4, 13, 29, 32, 26, 24, 27, 27, 17, 9, 8, 6,
+ -5, -20, -34, -39, -37, -34, -30, -21, -8, 6, 23, 34, 31, 29, 28, 27,
+ 22, 13, 6, 5, -4, -18, -34, -40, -37, -34, -29, -23, -10, 5, 21, 32,
+ 29, 27, 29, 26, 20, 12, 4, 3, 0, -12, -28, -37, -35, -31, -29, -23,
+ -13, 1, 16, 30, 33, 29, 27, 25, 21, 15, 5, -2, -3, -9, -22, -35,
+ -36, -31, -29, -24, -14, 0, 12, 27, 35, 31, 29, 26, 21, 16, 8, -2,
+ -3, -7, -19, -34, -36, -32, -31, -28, -18, -3, 11, 22, 32, 32, 30, 29,
+ 23, 16, 11, 2, -3, -6, -17, -32, -37, -32, -30, -31, -23, -6, 9, 18,
+ 30, 36, 32, 31, 25, 17, 13, 4, -6, -8, -14, -26, -36, -34, -31, -31,
+ -25, -11, 6, 16, 24, 34, 35, 33, 28, 17, 16, 10, -3, -9, -13, -23,
+ -34, -36, -32, -31, -27, -16, 2, 16, 22, 30, 35, 33, 30, 21, 15, 11,
+ 0, -7, -11, -20, -31, -35, -31, -31, -29, -21, -6, 13, 21, 25, 32, 34,
+ 33, 26, 18, 13, 4, -6, -10, -19, -29, -34, -34, -29, -27, -24, -12, 7,
+ 20, 25, 30, 33, 32, 29, 21, 13, 7, -5, -11, -18, -28, -35, -36, -29,
+ -25, -24, -16, 3, 21, 26, 28, 34, 37, 34, 26, 12, 4, -5, -13, -20,
+ -30, -35, -39, -35, -24, -19, -13, -2, 15, 27, 30, 32, 34, 31, 28, 18,
+ 5, -6, -15, -20, -24, -31, -37, -35, -24, -19, -16, -9, 8, 24, 30, 30,
+ 33, 35, 35, 24, 5, -5, -11, -20, -27, -34, -40, -39, -30, -21, -16, -9,
+ 4, 20, 32, 36, 36, 36, 35, 31, 13, -3, -13, -23, -27, -29, -41, -44,
+ -33, -19, -11, -10, -4, 14, 32, 38, 34, 33, 36, 33, 18, -4, -13, -20,
+ -25, -28, -37, -43, -34, -22, -14, -8, -4, 9, 26, 39, 38, 35, 35, 34,
+ 23, 3, -12, -21, -28, -28, -31, -41, -40, -27, -15, -7, -6, 2, 20, 37,
+ 42, 36, 34, 35, 28, 9, -10, -18, -24, -26, -29, -38, -42, -32, -21, -11,
+ -6, -3, 12, 33, 45, 41, 37, 37, 29, 13, -4, -17, -26, -28, -28, -33,
+ -39, -37, -26, -15, -8, -7, 6, 29, 47, 46, 39, 34, 30, 20, 1, -18,
+ -26, -26, -25, -29, -37, -40, -31, -17, -8, -7, 0, 20, 42, 51, 45, 38,
+ 30, 18, 7, -10, -24, -27, -26, -24, -29, -38, -37, -27, -14, -9, -6, 11,
+ 36, 51, 47, 42, 34, 24, 14, -3, -20, -25, -23, -22, -26, -37, -42, -33,
+ -17, -8, -7, 4, 28, 50, 54, 45, 35, 24, 15, 3, -16, -24, -25, -22,
+ -23, -32, -41, -37, -22, -11, -8, 0, 21, 44, 54, 46, 34, 26, 18, 7,
+ -11, -22, -21, -20, -21, -28, -40, -43, -30, -15, -10, -3, 16, 40, 56, 52,
+ 37, 24, 16, 9, -6, -21, -22, -18, -17, -22, -35, -43, -34, -21, -14, -9,
+ 7, 34, 53, 54, 40, 29, 21, 14, 4, -14, -21, -17, -17, -22, -33, -46,
+ -45, -31, -16, -8, 4, 25, 50, 60, 49, 31, 20, 15, 9, -5, -17, -18,
+ -15, -17, -26, -42, -50, -40, -24, -11, -2, 18, 43, 56, 52, 35, 21, 17,
+ 11, 0, -12, -18, -14, -15, -22, -36, -50, -46, -30, -15, -3, 12, 35, 53,
+ 55, 41, 24, 18, 12, 5, -4, -15, -18, -15, -20, -33, -46, -49, -37, -21,
+ -7, 7, 25, 46, 54, 45, 27, 18, 14, 10, 3, -8, -15, -16, -18, -28,
+ -41, -49, -44, -29, -12, 4, 17, 35, 49, 49, 34, 19, 16, 15, 9, 1,
+ -10, -14, -16, -24, -38, -50, -49, -36, -18, -3, 10, 26, 43, 49, 38, 22,
+ 18, 20, 16, 9, -5, -13, -16, -23, -36, -50, -53, -43, -25, -8, 6, 21,
+ 38, 48, 44, 27, 19, 21, 19, 13, -2, -13, -17, -21, -30, -45, -52, -46,
+ -29, -10, 3, 14, 29, 42, 44, 30, 17, 19, 21, 17, 6, -8, -14, -19,
+ -26, -39, -49, -48, -36, -18, -2, 11, 27, 37, 42, 37, 22, 18, 21, 19,
+ 9, -5, -13, -18, -24, -33, -45, -46, -39, -24, -8, 6, 20, 33, 40, 38,
+ 27, 19, 22, 23, 17, 4, -8, -14, -22, -29, -43, -48, -43, -32, -16, -2,
+ 13, 25, 34, 39, 33, 23, 21, 23, 20, 9, -4, -11, -19, -25, -33, -43,
+ -42, -34, -20, -7, 3, 14, 24, 32, 31, 22, 20, 26, 28, 20, 6, -5,
+ -11, -18, -28, -42, -44, -38, -28, -15, -5, 8, 19, 28, 31, 24, 21, 25,
+ 27, 22, 10, 0, -6, -12, -22, -34, -38, -34, -30, -20, -11, 0, 11, 20,
+ 26, 23, 19, 22, 27, 25, 17, 7, -2, -7, -17, -29, -35, -35, -34, -26,
+ -16, -5, 7, 15, 23, 28, 24, 21, 22, 24, 20, 11, -2, -8, -14, -24,
+ -29, -31, -31, -27, -18, -9, 0, 8, 15, 22, 23, 20, 21, 24, 24, 19,
+ 7, -4, -10, -19, -26, -32, -34, -33, -24, -12, -2, 6, 14, 22, 26, 23,
+ 22, 22, 22, 21, 10, 0, -6, -15, -21, -24, -28, -31, -28, -17, -7, 2,
+ 7, 13, 19, 23, 23, 21, 19, 21, 18, 8, -2, -11, -17, -21, -24, -30,
+ -33, -25, -11, 0, 4, 9, 16, 20, 21, 20, 18, 18, 20, 14, 4, -6,
+ -12, -15, -17, -25, -32, -32, -20, -6, -3, -3, 7, 18, 23, 19, 16, 19,
+ 26, 24, 11, 0, -6, -9, -15, -25, -33, -35, -26, -15, -9, -6, 5, 17,
+ 22, 21, 17, 18, 25, 26, 16, 4, -5, -7, -9, -18, -29, -38, -35, -21,
+ -11, -9, -4, 9, 22, 25, 20, 16, 22, 30, 24, 8, -4, -5, -5, -13,
+ -25, -36, -38, -26, -16, -11, -10, 2, 19, 25, 18, 12, 19, 30, 28, 14,
+ 1, -2, 3, -3, -17, -31, -36, -29, -21, -18, -19, -11, 7, 20, 16, 10,
+ 16, 30, 36, 24, 8, 4, 8, 6, -12, -32, -40, -35, -26, -21, -20, -14,
+ 2, 19, 20, 10, 12, 24, 35, 29, 13, 5, 7, 9, -3, -23, -37, -37,
+ -31, -23, -21, -19, -8, 12, 19, 10, 6, 19, 36, 37, 23, 11, 12, 16,
+ 7, -15, -35, -43, -38, -30, -27, -23, -16, 2, 18, 16, 7, 13, 30, 38,
+ 29, 17, 12, 16, 15, -4, -27, -40, -39, -32, -28, -28, -24, -8, 12, 14,
+ 5, 7, 26, 40, 36, 24, 18, 21, 21, 4, -20, -38, -41, -37, -34, -30,
+ -26, -15, 4, 14, 7, 3, 18, 37, 41, 33, 24, 22, 25, 14, -10, -33,
+ -44, -42, -36, -32, -29, -22, -6, 10, 9, 2, 9, 29, 40, 37, 32, 28,
+ 29, 21, 0, -24, -39, -44, -44, -38, -31, -24, -16, 0, 7, 3, 8, 24,
+ 38, 43, 41, 32, 28, 25, 9, -15, -34, -44, -44, -39, -31, -26, -20, -10,
+ 3, 2, 1, 14, 32, 44, 46, 39, 33, 31, 20, -7, -31, -45, -47, -44,
+ -38, -30, -26, -16, 0, 5, 4, 12, 30, 45, 52, 47, 36, 30, 22, 0,
+ -24, -40, -50, -49, -42, -31, -24, -19, -10, -3, 3, 11, 24, 39, 51, 55,
+ 49, 37, 27, 8, -18, -36, -50, -54, -47, -36, -29, -25, -16, -6, 4, 10,
+ 18, 34, 52, 59, 53, 39, 28, 15, -8, -29, -45, -53, -51, -43, -34, -29,
+ -23, -14, -4, 7, 17, 33, 52, 62, 61, 50, 37, 23, -4, -28, -44, -55,
+ -55, -48, -38, -30, -25, -18, -8, 5, 13, 25, 46, 61, 65, 57, 43, 30,
+ 8, -17, -36, -50, -55, -53, -47, -39, -32, -24, -15, -3, 11, 25, 45, 62,
+ 68, 63, 51, 37, 14, -14, -34, -46, -56, -57, -51, -44, -33, -25, -18, -6,
+ 8, 19, 36, 55, 67, 65, 53, 42, 23, -4, -26, -40, -50, -56, -54, -49,
+ -41, -31, -23, -12, 1, 15, 34, 53, 65, 68, 59, 49, 33, 6, -21, -37,
+ -47, -57, -60, -56, -48, -38, -28, -16, -2, 14, 33, 51, 64, 70, 63, 53,
+ 38, 13, -14, -34, -44, -53, -59, -59, -53, -42, -30, -19, -8, 5, 26, 47,
+ 61, 68, 64, 57, 48, 26, -3, -26, -39, -49, -58, -63, -59, -49, -37, -24,
+ -13, 1, 20, 42, 55, 65, 69, 64, 54, 34, 7, -18, -34, -44, -55, -65,
+ -64, -54, -42, -31, -19, -8, 12, 37, 54, 61, 67, 67, 60, 46, 22, -8,
+ -29, -40, -50, -64, -70, -63, -50, -34, -21, -13, 2, 28, 51, 62, 68, 68,
+ 61, 51, 32, 3, -23, -36, -47, -60, -70, -67, -58, -44, -27, -14, -2, 22,
+ 45, 58, 65, 70, 68, 56, 38, 16, -11, -32, -45, -58, -69, -70, -62, -52,
+ -34, -17, -6, 13, 38, 54, 64, 70, 67, 59, 47, 29, -2, -28, -40, -51,
+ -65, -74, -67, -54, -37, -20, -11, 5, 33, 53, 59, 63, 67, 62, 51, 34,
+ 7, -20, -35, -46, -59, -72, -70, -60, -46, -27, -12, 1, 24, 47, 60, 64,
+ 69, 66, 54, 39, 15, -13, -32, -44, -54, -68, -71, -60, -48, -32, -18, -7,
+ 14, 38, 54, 61, 68, 70, 60, 46, 26, -2, -23, -38, -50, -63, -72, -68,
+ -55, -39, -24, -13, 5, 31, 52, 61, 67, 71, 64, 53, 34, 7, -21, -36,
+ -46, -57, -69, -72, -60, -42, -27, -17, -2, 21, 45, 58, 65, 69, 66, 57,
+ 42, 15, -13, -30, -43, -54, -66, -72, -65, -47, -30, -18, -5, 15, 40, 57,
+ 64, 67, 62, 56, 46, 23, -6, -27, -39, -50, -58, -67, -67, -51, -32, -20,
+ -9, 9, 31, 51, 60, 64, 64, 58, 48, 27, 1, -20, -34, -46, -56, -65,
+ -70, -57, -37, -22, -14, 2, 26, 48, 62, 66, 64, 59, 51, 34, 8, -18,
+ -31, -42, -52, -61, -70, -63, -42, -24, -15, -3, 19, 43, 60, 63, 60, 57,
+ 52, 39, 14, -14, -28, -36, -46, -54, -65, -66, -49, -29, -17, -9, 10, 33,
+ 54, 64, 62, 58, 53, 42, 23, -5, -25, -35, -46, -54, -63, -67, -54, -33,
+ -17, -7, 7, 30, 51, 61, 58, 55, 51, 43, 28, 3, -21, -30, -37, -46,
+ -56, -63, -56, -39, -22, -12, -5, 16, 40, 57, 58, 55, 53, 48, 38, 19,
+ -10, -27, -35, -45, -56, -66, -65, -49, -28, -14, -6, 8, 34, 57, 60, 55,
+ 54, 50, 42, 26, -4, -28, -35, -42, -52, -62, -63, -51, -32, -14, -5, 3,
+ 24, 47, 57, 53, 50, 47, 41, 33, 11, -20, -35, -40, -46, -56, -65, -58,
+ -38, -17, -4, 1, 15, 41, 57, 55, 47, 45, 42, 35, 17, -13, -33, -38,
+ -41, -49, -58, -55, -41, -21, -4, 0, 7, 29, 50, 52, 45, 42, 40, 37,
+ 25, 0, -28, -38, -38, -44, -53, -58, -46, -26, -6, 3, 4, 18, 42, 53,
+ 47, 41, 39, 37, 30, 10, -21, -41, -43, -41, -47, -54, -46, -29, -8, 7,
+ 9, 13, 31, 46, 45, 37, 33, 33, 28, 15, -10, -35, -42, -38, -39, -45,
+ -46, -32, -10, 6, 9, 8, 19, 38, 44, 38, 30, 29, 30, 19, -3, -29,
+ -42, -38, -34, -40, -43, -32, -14, 3, 11, 11, 15, 30, 41, 39, 30, 25,
+ 25, 19, 4, -21, -40, -42, -32, -30, -33, -29, -15, 2, 11, 10, 8, 17,
+ 30, 35, 30, 23, 24, 23, 11, -11, -32, -43, -34, -26, -29, -29, -18, -3,
+ 9, 12, 9, 12, 26, 35, 32, 21, 18, 18, 12, -6, -29, -43, -36, -22,
+ -22, -25, -15, 1, 10, 11, 10, 8, 17, 29, 29, 21, 16, 17, 15, 2,
+ -21, -39, -39, -24, -17, -20, -16, -5, 9, 13, 10, 7, 12, 24, 28, 23,
+ 14, 12, 11, 4, -14, -33, -39, -28, -15, -14, -12, -6, 5, 11, 9, 7,
+ 7, 16, 26, 25, 16, 10, 11, 6, -8, -24, -37, -32, -17, -12, -11, -5,
+ 5, 11, 11, 10, 7, 12, 21, 21, 16, 7, 4, 3, -6, -20, -32, -32,
+ -20, -8, -5, 0, 5, 11, 11, 9, 8, 8, 13, 17, 16, 9, 3, 2,
+ -3, -13, -25, -31, -23, -9, -4, -2, 5, 11, 14, 11, 7, 6, 12, 15,
+ 12, 5, -2, -2, -3, -11, -22, -29, -24, -9, 0, 3, 8, 13, 13, 12,
+ 8, 4, 5, 7, 9, 6, -3, -5, -4, -5, -14, -24, -23, -13, 0, 4,
+ 6, 10, 14, 14, 9, 3, 3, 5, 6, 4, -4, -6, -5, -5, -9, -18,
+ -20, -15, -4, 6, 9, 11, 13, 13, 10, 5, 1, 0, -3, 0, -4, -6,
+ -6, -5, -4, -11, -16, -16, -9, 3, 8, 11, 11, 10, 11, 8, 3, -2,
+ -5, -4, -3, -5, -6, -6, -2, -5, -12, -15, -13, -2, 8, 9, 11, 11,
+ 11, 7, 4, 0, -6, -6, -4, -4, -6, -6, -2, 0, -7, -13, -15, -5,
+ 8, 13, 12, 9, 11, 9, 4, -5, -11, -11, -8, -5, -5, -5, 0, 4,
+ 3, -4, -11, -8, 3, 11, 12, 8, 7, 4, 2, -2, -10, -14, -13, -7,
+ -3, -4, -2, 3, 4, 1, -8, -8, 3, 13, 17, 12, 11, 7, 1, -6,
+ -16, -21, -19, -13, -7, -2, 3, 7, 10, 10, 1, -6, -2, 8, 14, 12,
+ 10, 4, -2, -6, -15, -21, -20, -15, -8, -2, 3, 5, 9, 14, 5, -6,
+ 1, 12, 18, 14, 9, 7, 2, -4, -18, -28, -27, -22, -12, -5, 3, 9,
+ 13, 18, 16, 5, 1, 7, 14, 13, 8, 5, -5, -9, -17, -26, -26, -23,
+ -15, -4, 5, 8, 11, 17, 17, 7, 2, 7, 16, 18, 10, 4, -2, -6,
+ -16, -31, -33, -27, -18, -9, 0, 7, 12, 18, 22, 16, 9, 9, 16, 20,
+ 13, 5, -2, -9, -18, -33, -37, -29, -22, -13, -4, 7, 15, 21, 25, 21,
+ 15, 13, 17, 20, 14, 5, -3, -8, -18, -35, -42, -36, -24, -16, -6, 5,
+ 13, 23, 27, 25, 20, 17, 19, 20, 15, 5, -3, -8, -21, -35, -45, -39,
+ -25, -18, -11, 3, 16, 25, 29, 27, 26, 24, 23, 21, 17, 8, -4, -12,
+ -23, -35, -46, -46, -34, -22, -15, -3, 13, 25, 31, 33, 34, 31, 28, 25,
+ 20, 11, -4, -12, -22, -38, -49, -51, -39, -26, -21, -11, 8, 24, 34, 35,
+ 36, 37, 35, 29, 21, 13, 0, -11, -20, -36, -48, -52, -46, -31, -22, -14,
+ 1, 19, 34, 38, 39, 40, 38, 34, 24, 15, 0, -14, -21, -34, -47, -53,
+ -50, -35, -22, -17, -5, 13, 31, 37, 38, 42, 41, 37, 28, 21, 9, -8,
+ -19, -30, -44, -50, -53, -46, -32, -23, -11, 7, 26, 39, 43, 49, 48, 42,
+ 32, 20, 9, -9, -21, -31, -46, -52, -54, -50, -35, -24, -13, 4, 23, 40,
+ 46, 48, 49, 46, 37, 26, 13, -4, -20, -29, -42, -50, -53, -54, -43, -31,
+ -21, -2, 17, 36, 47, 53, 56, 51, 42, 29, 17, 3, -16, -30, -41, -51,
+ -55, -57, -51, -35, -24, -9, 11, 30, 47, 53, 57, 55, 46, 34, 20, 6,
+ -12, -29, -43, -52, -55, -55, -55, -42, -29, -12, 8, 25, 41, 55, 62, 59,
+ 51, 37, 23, 10, -6, -24, -40, -51, -56, -58, -58, -48, -33, -19, 2, 22,
+ 41, 55, 61, 61, 56, 45, 28, 11, -3, -19, -37, -51, -57, -58, -58, -54,
+ -39, -23, -2, 20, 36, 52, 64, 65, 58, 48, 33, 19, 4, -13, -35, -51,
+ -58, -61, -62, -60, -47, -29, -7, 17, 34, 50, 67, 70, 62, 50, 35, 20,
+ 6, -8, -29, -47, -57, -62, -61, -60, -54, -37, -15, 10, 29, 44, 60, 68,
+ 66, 56, 42, 24, 12, 1, -19, -41, -55, -60, -62, -61, -57, -43, -21, 7,
+ 24, 36, 53, 66, 67, 59, 46, 30, 15, 5, -11, -32, -48, -58, -63, -62,
+ -59, -50, -32, -3, 22, 35, 49, 60, 66, 63, 53, 38, 19, 8, -5, -25,
+ -43, -57, -64, -64, -62, -54, -39, -13, 16, 32, 46, 59, 65, 66, 56, 45,
+ 26, 11, 3, -17, -39, -56, -65, -67, -62, -56, -44, -21, 10, 29, 40, 54,
+ 63, 68, 61, 49, 33, 13, 2, -14, -34, -50, -64, -67, -63, -56, -44, -26,
+ 2, 27, 38, 49, 57, 64, 61, 50, 36, 17, 6, -7, -27, -44, -60, -67,
+ -63, -57, -48, -32, -7, 22, 36, 44, 53, 60, 62, 55, 41, 21, 7, -3,
+ -20, -40, -58, -68, -65, -57, -47, -34, -14, 16, 37, 42, 47, 55, 59, 53,
+ 42, 27, 10, -2, -14, -30, -47, -60, -63, -57, -49, -38, -20, 5, 30, 40,
+ 44, 52, 57, 57, 46, 31, 13, -2, -12, -27, -44, -57, -64, -61, -50, -38,
+ -20, 2, 25, 39, 41, 49, 55, 54, 45, 32, 17, 0, -12, -23, -37, -50,
+ -59, -61, -52, -38, -22, -6, 17, 35, 39, 42, 48, 53, 48, 36, 22, 4,
+ -9, -18, -30, -45, -56, -59, -54, -42, -27, -10, 12, 29, 37, 38, 44, 50,
+ 47, 37, 25, 9, -5, -13, -23, -38, -50, -55, -54, -45, -32, -17, 5, 25,
+ 34, 35, 39, 46, 48, 40, 29, 13, -3, -11, -21, -33, -44, -51, -54, -47,
+ -34, -17, 2, 21, 32, 34, 34, 38, 42, 39, 27, 15, 1, -7, -13, -25,
+ -36, -45, -49, -46, -36, -23, -6, 15, 27, 31, 31, 34, 39, 38, 30, 18,
+ 3, -6, -10, -19, -32, -40, -46, -45, -36, -24, -11, 8, 24, 29, 27, 29,
+ 34, 36, 30, 18, 4, -5, -5, -12, -25, -34, -39, -41, -37, -24, -11, 4,
+ 18, 24, 25, 25, 29, 29, 26, 19, 5, -6, -6, -6, -18, -28, -33, -37,
+ -34, -24, -11, 2, 15, 24, 23, 20, 24, 27, 22, 14, 4, -4, -4, -5,
+ -15, -24, -26, -29, -32, -27, -13, 2, 14, 21, 21, 18, 21, 23, 20, 13,
+ 5, -3, -5, -4, -9, -16, -21, -25, -28, -25, -14, 1, 10, 16, 19, 16,
+ 16, 18, 16, 11, 5, -2, -5, -4, -6, -12, -17, -20, -22, -22, -17, -4,
+ 8, 13, 16, 15, 13, 15, 14, 10, 4, -4, -6, -6, -5, -7, -11, -15,
+ -17, -17, -15, -3, 10, 13, 14, 11, 7, 8, 9, 5, -3, -8, -7, -4,
+ -2, -2, -6, -10, -9, -10, -12, -5, 11, 15, 13, 11, 5, 6, 7, 3,
+ -6, -10, -8, -6, -6, -2, 1, -2, -6, -6, -7, -5, 8, 14, 10, 7,
+ 4, 0, 1, -2, -6, -12, -11, -6, -2, 4, 8, 4, -2, -2, -4, -5,
+ 3, 12, 8, 5, 4, 0, 0, -2, -8, -13, -15, -12, -7, -3, 6, 10,
+ 7, 5, 6, 4, 6, 14, 10, 3, 0, -6, -10, -7, -10, -16, -19, -15,
+ -8, 0, 11, 17, 13, 10, 11, 7, 5, 8, 9, 2, -4, -7, -12, -10,
+ -10, -16, -21, -19, -13, -4, 10, 21, 22, 17, 17, 14, 9, 9, 9, 3,
+ -7, -12, -17, -16, -14, -20, -25, -21, -15, -5, 10, 23, 27, 25, 22, 18,
+ 11, 8, 4, -2, -9, -14, -18, -19, -14, -15, -23, -25, -20, -10, 9, 22,
+ 29, 29, 26, 23, 16, 12, 6, 1, -6, -14, -18, -22, -20, -19, -27, -28,
+ -25, -18, 0, 19, 32, 36, 33, 31, 23, 14, 7, 1, -4, -15, -23, -25,
+ -24, -19, -25, -32, -29, -20, -3, 16, 31, 40, 38, 36, 29, 16, 9, 1,
+ -4, -12, -23, -26, -28, -24, -26, -34, -33, -24, -8, 12, 29, 41, 44, 44,
+ 37, 22, 11, 4, -4, -11, -24, -31, -32, -31, -30, -36, -39, -30, -11, 11,
+ 29, 43, 51, 50, 44, 32, 15, 4, -4, -11, -24, -32, -33, -33, -34, -38,
+ -42, -35, -17, 4, 24, 42, 56, 60, 52, 38, 19, 7, 1, -13, -28, -37,
+ -37, -35, -37, -39, -43, -37, -19, 3, 22, 41, 57, 64, 57, 44, 26, 7,
+ -2, -11, -24, -35, -41, -40, -38, -39, -43, -40, -24, 0, 20, 37, 55, 65,
+ 63, 50, 32, 9, -4, -10, -24, -36, -42, -42, -41, -41, -41, -39, -26, -2,
+ 19, 34, 51, 64, 66, 55, 38, 15, -3, -8, -20, -34, -42, -44, -43, -44,
+ -45, -45, -35, -12, 14, 31, 50, 66, 73, 65, 49, 28, 7, -6, -18, -35,
+ -45, -49, -51, -53, -51, -47, -37, -16, 10, 30, 49, 69, 78, 72, 56, 35,
+ 14, -4, -17, -33, -46, -51, -55, -56, -54, -51, -40, -20, 5, 26, 44, 64,
+ 76, 77, 64, 41, 19, 1, -14, -30, -43, -50, -57, -60, -58, -54, -43, -24,
+ -2, 21, 39, 61, 76, 79, 72, 52, 28, 9, -10, -26, -41, -49, -54, -61,
+ -62, -59, -51, -33, -10, 14, 34, 55, 75, 81, 79, 63, 39, 19, -2, -23,
+ -40, -51, -56, -64, -67, -64, -56, -39, -16, 9, 29, 51, 73, 83, 82, 73,
+ 50, 27, 9, -18, -40, -52, -56, -63, -69, -69, -61, -43, -20, 2, 21, 42,
+ 66, 81, 82, 76, 59, 36, 19, -6, -33, -50, -57, -61, -71, -76, -68, -52,
+ -28, -2, 17, 36, 62, 83, 86, 82, 69, 43, 22, 2, -28, -51, -60, -63,
+ -67, -76, -74, -57, -34, -7, 14, 29, 53, 76, 87, 84, 75, 54, 33, 14,
+ -18, -46, -58, -62, -69, -80, -84, -68, -44, -18, 7, 26, 49, 75, 91, 92,
+ 82, 64, 42, 21, -8, -43, -63, -68, -68, -75, -86, -76, -48, -22, 4, 23,
+ 41, 66, 87, 92, 83, 69, 51, 31, 6, -31, -59, -67, -69, -74, -88, -87,
+ -62, -34, -7, 17, 36, 62, 87, 96, 90, 76, 60, 39, 14, -23, -58, -70,
+ -71, -73, -83, -89, -68, -37, -13, 9, 26, 51, 79, 94, 91, 80, 68, 52,
+ 28, -8, -48, -67, -70, -73, -84, -96, -83, -49, -22, 0, 20, 44, 75, 96,
+ 98, 88, 75, 61, 40, 6, -39, -67, -72, -75, -83, -95, -91, -60, -29, -7,
+ 13, 36, 66, 89, 97, 92, 78, 65, 50, 22, -21, -58, -71, -73, -78, -91,
+ -98, -79, -45, -15, 4, 25, 56, 84, 101, 99, 86, 73, 60, 35, -9, -53,
+ -72, -77, -80, -90, -98, -85, -51, -20, -2, 18, 48, 77, 96, 99, 87, 75,
+ 62, 46, 9, -39, -68, -75, -75, -83, -95, -94, -67, -30, -7, 8, 34, 68,
+ 92, 102, 93, 82, 72, 58, 26, -24, -61, -75, -78, -85, -97, -99, -78, -42,
+ -12, 6, 28, 59, 87, 102, 99, 86, 74, 62, 38, -7, -52, -76, -81, -83,
+ -93, -100, -90, -57, -23, -2, 18, 48, 80, 102, 103, 92, 81, 71, 51, 9,
+ -41, -72, -83, -85, -93, -100, -92, -65, -32, -7, 13, 39, 72, 97, 103, 95,
+ 85, 73, 55, 25, -21, -61, -79, -83, -90, -99, -97, -77, -45, -17, 1, 24,
+ 59, 93, 107, 103, 92, 85, 72, 42, -6, -54, -80, -86, -91, -104, -105, -87,
+ -56, -23, 0, 18, 48, 85, 106, 106, 96, 87, 77, 52, 13, -35, -71, -84,
+ -88, -98, -106, -96, -70, -40, -14, 6, 31, 70, 103, 111, 103, 95, 88, 68,
+ 29, -19, -61, -84, -91, -99, -106, -101, -80, -51, -22, 2, 23, 56, 91, 109,
+ 108, 98, 89, 76, 45, 1, -44, -76, -87, -92, -102, -104, -90, -64, -34, -11,
+ 8, 37, 78, 108, 113, 106, 96, 85, 61, 19, -29, -68, -88, -94, -102, -104,
+ -93, -73, -46, -21, 2, 28, 63, 98, 113, 109, 100, 89, 70, 33, -14, -55,
+ -81, -91, -98, -104, -98, -79, -54, -30, -9, 18, 52, 89, 108, 110, 104, 96,
+ 79, 46, 2, -40, -71, -90, -100, -104, -100, -86, -67, -44, -19, 7, 40, 77,
+ 105, 115, 109, 99, 86, 58, 17, -29, -63, -86, -97, -101, -101, -92, -74, -50,
+ -26, -4, 28, 66, 98, 114, 113, 102, 90, 68, 33, -15, -53, -76, -93, -101,
+ -104, -96, -79, -57, -34, -15, 15, 56, 90, 110, 115, 105, 93, 75, 44, 0,
+ -43, -68, -86, -98, -101, -98, -83, -65, -42, -22, 4, 41, 79, 104, 113, 107,
+ 96, 81, 57, 16, -31, -59, -79, -95, -101, -100, -90, -71, -49, -30, -9, 28,
+ 67, 97, 110, 107, 97, 86, 65, 30, -14, -47, -67, -84, -98, -102, -96, -79,
+ -59, -41, -22, 14, 53, 90, 110, 111, 101, 90, 75, 45, 2, -39, -64, -79,
+ -93, -102, -101, -87, -64, -44, -28, 0, 39, 81, 108, 110, 102, 93, 82, 58,
+ 18, -25, -54, -70, -85, -101, -103, -94, -72, -53, -39, -14, 25, 70, 104, 112,
+ 103, 96, 88, 70, 34, -13, -48, -65, -78, -97, -108, -101, -79, -55, -42, -24,
+ 11, 56, 96, 111, 103, 94, 90, 77, 46, 5, -34, -56, -71, -92, -109, -109,
+ -91, -64, -46, -30, 0, 44, 89, 112, 108, 95, 88, 80, 57, 16, -27, -54,
+ -66, -82, -104, -112, -100, -71, -46, -34, -13, 29, 80, 111, 112, 97, 86, 84,
+ 69, 32, -15, -48, -61, -72, -94, -109, -106, -82, -54, -37, -23, 11, 61, 101,
+ 113, 101, 85, 80, 75, 48, 4, -37, -56, -64, -84, -107, -112, -90, -60, -37,
+ -29, -7, 43, 91, 111, 103, 86, 80, 77, 58, 20, -24, -52, -61, -75, -100,
+ -111, -99, -72, -44, -27, -12, 29, 77, 105, 106, 91, 80, 75, 64, 33, -9,
+ -43, -58, -69, -94, -111, -104, -78, -49, -28, -18, 11, 62, 97, 107, 94, 80,
+ 75, 69, 47, 6, -36, -55, -62, -81, -105, -108, -87, -59, -33, -18, 1, 46,
+ 86, 103, 97, 83, 75, 69, 52, 19, -23, -50, -59, -74, -97, -106, -91, -64,
+ -38, -21, -9, 26, 70, 95, 95, 80, 71, 69, 60, 35, -6, -40, -53, -64,
+ -87, -102, -96, -72, -45, -25, -14, 13, 56, 87, 95, 86, 75, 69, 60, 41,
+ 6, -32, -54, -62, -77, -95, -99, -79, -51, -23, -8, 6, 39, 75, 92, 87,
+ 72, 64, 62, 49, 21, -17, -47, -57, -67, -86, -97, -87, -59, -32, -16, -4,
+ 25, 63, 89, 92, 78, 67, 63, 53, 27, -10, -40, -55, -63, -78, -93, -89,
+ -65, -36, -17, -7, 11, 44, 77, 89, 79, 65, 61, 58, 41, 8, -26, -50,
+ -59, -67, -83, -90, -76, -47, -25, -13, 3, 30, 63, 85, 82, 70, 63, 58,
+ 45, 14, -18, -43, -56, -63, -74, -84, -78, -52, -26, -13, -2, 19, 46, 73,
+ 81, 68, 57, 55, 49, 27, -5, -32, -48, -54, -63, -77, -80, -60, -34, -17,
+ -5, 10, 34, 62, 79, 71, 57, 52, 48, 31, 2, -26, -45, -50, -53, -65,
+ -75, -63, -37, -16, -6, 4, 19, 45, 68, 70, 57, 49, 49, 39, 16, -11,
+ -33, -45, -49, -56, -70, -71, -51, -26, -8, 2, 13, 35, 63, 76, 63, 48,
+ 43, 38, 23, -7, -32, -45, -47, -47, -58, -67, -55, -30, -8, 0, 4, 20,
+ 46, 68, 65, 47, 38, 38, 31, 8, -19, -37, -44, -42, -48, -63, -62, -41,
+ -16, -2, 5, 16, 37, 61, 68, 53, 38, 34, 31, 14, -14, -33, -40, -38,
+ -41, -54, -60, -46, -20, -5, -3, 6, 25, 49, 63, 55, 38, 32, 33, 24,
+ 1, -23, -34, -35, -36, -45, -59, -55, -30, -9, -3, 2, 16, 39, 59, 59,
+ 44, 32, 30, 26, 7, -20, -33, -33, -32, -40, -53, -54, -35, -12, -3, -2,
+ 10, 29, 48, 55, 45, 32, 28, 27, 14, -10, -27, -30, -28, -34, -46, -53,
+ -41, -17, -5, -5, 5, 24, 44, 54, 46, 32, 25, 25, 18, -4, -25, -31,
+ -24, -27, -39, -47, -42, -21, -4, -2, 1, 15, 35, 46, 44, 31, 22, 23,
+ 20, 6, -15, -26, -23, -20, -29, -41, -42, -29, -11, -4, -4, 7, 26, 42,
+ 47, 37, 25, 21, 19, 9, -10, -25, -25, -18, -24, -38, -40, -29, -11, 1,
+ 0, 3, 19, 34, 42, 33, 19, 14, 15, 10, -5, -21, -24, -15, -13, -26,
+ -35, -31, -17, -2, 0, -2, 11, 26, 37, 34, 20, 14, 13, 12, 2, -17,
+ -25, -17, -12, -21, -31, -30, -19, -4, 4, 1, 9, 22, 32, 32, 19, 9,
+ 9, 10, 4, -11, -21, -16, -9, -14, -23, -26, -20, -8, 0, -2, 3, 15,
+ 26, 31, 24, 12, 9, 10, 6, -5, -17, -19, -12, -11, -18, -25, -22, -10,
+ 1, 2, 2, 11, 22, 29, 24, 10, 3, 5, 4, -4, -13, -15, -8, -5,
+ -10, -16, -18, -14, -5, -2, 0, 6, 13, 20, 23, 16, 6, 5, 5, 0,
+ -7, -12, -12, -8, -7, -12, -19, -18, -7, 0, 2, 7, 13, 18, 20, 13,
+ 3, -2, 1, -2, -6, -8, -6, -3, -2, -2, -10, -14, -10, -6, -4, 0,
+ 4, 9, 14, 15, 6, -2, -2, -2, -4, -4, -5, -3, 2, 3, -3, -10,
+ -9, -5, 0, 0, 0, 3, 8, 10, 3, -5, -7, -6, -4, 0, -2, -2,
+ 3, 7, 7, 2, -5, -6, -3, 2, 2, 0, 0, 2, 2, -4, -9, -9,
+ -7, -3, 2, 4, 8, 9, 6, 2, -3, -4, -3, -2, -2, -2, 0, 1,
+ -3, -8, -11, -8, -6, -4, 2, 6, 9, 10, 9, 8, 5, -4, -7, -3,
+ 1, 1, -6, -7, -6, -6, -11, -14, -10, -5, 3, 9, 12, 14, 13, 10,
+ 9, 1, -6, -5, -4, -3, -4, -6, -8, -12, -12, -13, -13, -11, -3, 9,
+ 16, 18, 15, 13, 14, 11, -2, -6, -4, -3, -5, -11, -13, -12, -14, -15,
+ -14, -10, -4, 6, 15, 22, 21, 16, 13, 12, 3, -7, -8, -7, -7, -10,
+ -14, -17, -16, -13, -12, -10, -7, 3, 15, 24, 26, 19, 16, 18, 12, -3,
+ -9, -10, -9, -11, -18, -22, -21, -17, -14, -14, -10, 0, 14, 26, 32, 28,
+ 23, 22, 21, 5, -9, -12, -16, -18, -22, -27, -27, -23, -17, -13, -8, 2,
+ 12, 25, 35, 36, 29, 21, 20, 11, -6, -14, -17, -19, -22, -27, -28, -24,
+ -20, -15, -11, -4, 7, 19, 32, 39, 35, 28, 25, 19, 4, -10, -17, -24,
+ -28, -31, -33, -30, -26, -19, -11, -3, 8, 19, 31, 42, 42, 34, 27, 21,
+ 9, -9, -19, -26, -31, -35, -34, -30, -26, -23, -13, -4, 4, 14, 25, 42,
+ 49, 41, 31, 27, 20, 3, -15, -28, -37, -38, -39, -38, -35, -29, -16, 0,
+ 9, 17, 26, 41, 52, 48, 36, 26, 19, 6, -16, -30, -39, -43, -41, -39,
+ -33, -29, -22, -5, 7, 13, 21, 36, 55, 56, 46, 34, 24, 15, -8, -29,
+ -44, -54, -50, -44, -39, -35, -27, -7, 11, 20, 25, 34, 54, 63, 53, 38,
+ 22, 14, 0, -27, -45, -56, -56, -46, -39, -36, -31, -14, 8, 19, 23, 29,
+ 46, 63, 61, 47, 30, 20, 8, -15, -39, -56, -62, -54, -44, -41, -38, -23,
+ -2, 16, 23, 28, 42, 63, 69, 58, 41, 25, 13, -7, -34, -56, -68, -64,
+ -50, -45, -43, -29, -7, 15, 26, 29, 40, 58, 72, 67, 48, 30, 16, 0,
+ -26, -53, -68, -69, -57, -47, -46, -36, -16, 9, 25, 30, 38, 53, 71, 74,
+ 58, 37, 17, 2, -21, -49, -70, -76, -64, -49, -43, -38, -21, 3, 25, 33,
+ 37, 49, 65, 74, 65, 45, 24, 8, -11, -40, -68, -79, -72, -57, -48, -42,
+ -29, -6, 20, 34, 39, 48, 63, 77, 74, 56, 31, 11, -8, -33, -61, -79,
+ -80, -68, -53, -45, -34, -16, 11, 31, 41, 51, 61, 75, 78, 64, 42, 19,
+ -3, -27, -55, -78, -84, -73, -59, -48, -37, -20, 5, 27, 40, 49, 58, 71,
+ 80, 71, 49, 23, 2, -20, -47, -72, -86, -82, -66, -52, -39, -26, -5, 20,
+ 39, 51, 59, 69, 79, 77, 61, 34, 7, -16, -42, -68, -88, -90, -75, -58,
+ -41, -26, -8, 17, 39, 52, 59, 65, 74, 77, 65, 41, 12, -12, -35, -60,
+ -81, -89, -79, -60, -45, -33, -17, 6, 31, 49, 59, 64, 73, 80, 74, 51,
+ 22, -5, -29, -54, -78, -92, -90, -70, -49, -35, -18, 3, 26, 48, 60, 64,
+ 68, 75, 75, 58, 31, 1, -25, -48, -73, -88, -90, -77, -56, -41, -23, -3,
+ 21, 43, 58, 64, 70, 75, 77, 64, 40, 12, -18, -44, -70, -87, -94, -87,
+ -64, -42, -22, -4, 16, 39, 58, 65, 66, 67, 74, 68, 46, 18, -12, -38,
+ -62, -82, -92, -89, -67, -45, -28, -9, 13, 31, 52, 64, 67, 66, 72, 71,
+ 53, 29, -3, -34, -59, -79, -94, -96, -77, -50, -29, -8, 12, 30, 49, 63,
+ 68, 67, 68, 70, 56, 34, 6, -29, -57, -77, -92, -99, -84, -56, -32, -10,
+ 11, 29, 45, 61, 69, 69, 68, 70, 60, 37, 12, -20, -50, -73, -90, -100,
+ -91, -64, -37, -14, 7, 25, 42, 57, 66, 67, 65, 67, 64, 45, 21, -9,
+ -41, -66, -84, -98, -95, -74, -47, -21, 3, 23, 39, 54, 64, 69, 69, 67,
+ 63, 50, 27, 0, -33, -63, -83, -94, -95, -79, -54, -26, -2, 18, 35, 49,
+ 61, 67, 67, 65, 64, 55, 33, 6, -25, -55, -82, -95, -98, -84, -60, -32,
+ -6, 17, 36, 48, 56, 64, 66, 65, 62, 55, 39, 14, -16, -46, -76, -92,
+ -96, -88, -69, -41, -9, 15, 33, 46, 54, 62, 68, 66, 59, 54, 44, 20,
+ -12, -41, -72, -92, -97, -90, -71, -46, -14, 15, 34, 48, 55, 59, 62, 63,
+ 60, 51, 42, 24, -6, -34, -63, -87, -95, -89, -75, -52, -23, 10, 31, 45,
+ 54, 58, 62, 66, 63, 51, 42, 30, 1, -32, -59, -84, -96, -93, -80, -58,
+ -28, 7, 32, 45, 53, 60, 64, 67, 62, 52, 41, 31, 9, -25, -55, -78,
+ -92, -91, -82, -65, -39, -2, 30, 43, 49, 56, 61, 65, 63, 54, 44, 33,
+ 16, -15, -47, -72, -88, -91, -84, -70, -45, -12, 22, 42, 48, 54, 58, 61,
+ 63, 56, 43, 32, 20, -4, -36, -65, -82, -87, -82, -72, -53, -23, 15, 40,
+ 46, 48, 55, 61, 62, 55, 43, 32, 21, 4, -26, -57, -75, -82, -80, -73,
+ -58, -30, 5, 35, 46, 47, 51, 57, 61, 57, 46, 34, 22, 9, -15, -47,
+ -71, -81, -80, -75, -62, -36, -4, 28, 46, 47, 49, 56, 60, 57, 48, 35,
+ 23, 12, -9, -39, -67, -78, -76, -71, -65, -45, -13, 21, 45, 50, 46, 50,
+ 58, 59, 49, 35, 23, 12, -4, -31, -62, -78, -74, -70, -65, -49, -18, 18,
+ 43, 51, 45, 48, 56, 56, 45, 30, 20, 12, 0, -24, -53, -71, -69, -63,
+ -60, -51, -25, 9, 36, 50, 47, 44, 50, 52, 45, 32, 21, 12, 1, -18,
+ -44, -66, -70, -64, -59, -51, -31, 2, 32, 50, 51, 46, 47, 52, 47, 32,
+ 17, 9, 0, -14, -34, -57, -67, -62, -56, -50, -33, -6, 24, 44, 51, 48,
+ 47, 48, 46, 34, 21, 12, 2, -13, -32, -51, -62, -62, -56, -51, -38, -13,
+ 18, 40, 51, 50, 45, 47, 46, 36, 20, 9, -2, -14, -28, -45, -59, -61,
+ -54, -48, -37, -15, 14, 36, 49, 52, 48, 44, 42, 33, 19, 10, 0, -13,
+ -26, -39, -52, -58, -54, -47, -37, -19, 9, 30, 44, 52, 48, 40, 38, 31,
+ 19, 7, -3, -12, -22, -31, -42, -51, -49, -43, -36, -22, 1, 22, 35, 45,
+ 47, 41, 37, 31, 23, 13, 3, -11, -22, -28, -36, -48, -53, -46, -35, -23,
+ -4, 17, 31, 45, 49, 41, 33, 29, 23, 13, 2, -11, -22, -26, -29, -38,
+ -46, -45, -34, -21, -6, 14, 25, 38, 46, 43, 35, 27, 19, 10, 3, -7,
+ -20, -28, -28, -32, -38, -41, -35, -23, -8, 10, 23, 33, 44, 44, 36, 27,
+ 18, 10, 0, -9, -22, -28, -28, -28, -33, -37, -32, -21, -7, 8, 20, 28,
+ 38, 41, 36, 27, 17, 8, -2, -6, -17, -28, -31, -28, -27, -30, -30, -22,
+ -7, 9, 19, 26, 35, 41, 37, 26, 16, 6, -5, -11, -18, -28, -31, -28,
+ -22, -23, -23, -18, -4, 11, 19, 24, 27, 33, 33, 24, 14, 3, -8, -11,
+ -15, -23, -29, -29, -21, -18, -19, -15, -5, 9, 16, 21, 26, 30, 32, 25,
+ 13, 2, -9, -13, -16, -21, -27, -27, -20, -12, -13, -14, -7, 9, 17, 20,
+ 24, 25, 26, 27, 15, 2, -9, -17, -17, -20, -25, -28, -23, -11, -6, -8,
+ -5, 7, 19, 23, 24, 24, 24, 25, 16, 0, -13, -22, -22, -22, -26, -28,
+ -22, -8, 2, 1, 0, 8, 18, 24, 24, 20, 18, 20, 15, 1, -12, -22,
+ -24, -22, -23, -25, -22, -13, 2, 7, 3, 8, 16, 25, 28, 21, 15, 15,
+ 15, 4, -13, -25, -29, -24, -20, -24, -21, -12, 1, 12, 10, 9, 16, 23,
+ 27, 21, 14, 12, 10, 3, -10, -21, -28, -27, -22, -22, -20, -14, -4, 10,
+ 14, 11, 17, 23, 29, 26, 15, 11, 10, 4, -12, -25, -33, -33, -26, -23,
+ -22, -12, 0, 13, 22, 19, 20, 25, 29, 25, 12, 5, 3, 0, -12, -25,
+ -32, -34, -27, -21, -20, -11, -2, 7, 18, 21, 22, 26, 30, 29, 21, 11,
+ 4, -5, -14, -29, -38, -38, -33, -27, -23, -10, 4, 12, 22, 29, 30, 30,
+ 31, 30, 21, 10, 0, -11, -19, -30, -39, -40, -36, -28, -20, -9, 4, 12,
+ 20, 29, 32, 30, 32, 32, 23, 12, 3, -8, -18, -27, -39, -44, -40, -32,
+ -25, -15, 1, 13, 22, 30, 37, 38, 36, 34, 26, 14, 2, -11, -22, -31,
+ -40, -45, -42, -35, -26, -14, 0, 12, 19, 26, 35, 39, 36, 33, 28, 18,
+ 6, -7, -18, -28, -37, -43, -43, -37, -30, -19, -6, 8, 20, 25, 34, 42,
+ 41, 37, 32, 22, 8, -7, -19, -32, -40, -44, -44, -38, -30, -20, -6, 8,
+ 19, 24, 30, 40, 41, 36, 29, 23, 13, -3, -16, -28, -39, -43, -44, -41,
+ -34, -23, -11, 2, 16, 25, 32, 41, 46, 42, 34, 26, 15, 0, -16, -29,
+ -40, -45, -45, -40, -32, -24, -12, -2, 12, 22, 26, 37, 45, 44, 34, 24,
+ 18, 6, -12, -24, -37, -41, -40, -40, -36, -30, -17, -4, 9, 18, 25, 37,
+ 45, 45, 40, 29, 19, 8, -8, -22, -38, -43, -42, -42, -35, -28, -17, -4,
+ 7, 17, 23, 33, 43, 43, 38, 28, 19, 12, -3, -19, -34, -40, -38, -40,
+ -38, -31, -22, -8, 5, 14, 21, 31, 44, 47, 41, 31, 20, 13, 3, -15,
+ -33, -45, -45, -41, -38, -31, -24, -10, 4, 15, 21, 29, 42, 47, 41, 33,
+ 22, 13, 4, -13, -29, -40, -41, -41, -41, -36, -26, -14, -2, 8, 17, 29,
+ 42, 50, 46, 37, 27, 17, 7, -9, -27, -41, -48, -45, -42, -38, -29, -15,
+ -2, 10, 18, 26, 38, 50, 51, 40, 28, 17, 6, -7, -24, -36, -43, -45,
+ -41, -38, -31, -18, -8, 2, 13, 26, 38, 44, 49, 42, 33, 22, 8, -4,
+ -20, -32, -41, -46, -44, -37, -32, -21, -8, 2, 14, 25, 35, 42, 47, 44,
+ 31, 19, 7, -4, -15, -28, -36, -42, -40, -34, -31, -24, -9, 0, 7, 18,
+ 30, 40, 44, 42, 32, 22, 12, 2, -10, -23, -31, -38, -42, -38, -31, -26,
+ -13, -3, 2, 14, 29, 40, 41, 40, 36, 26, 13, 1, -10, -19, -26, -35,
+ -43, -41, -33, -27, -17, -6, 1, 12, 27, 43, 47, 42, 37, 29, 14, 0,
+ -10, -21, -29, -34, -40, -42, -33, -26, -18, -5, 3, 10, 23, 39, 45, 39,
+ 33, 30, 18, 3, -8, -15, -22, -29, -37, -43, -36, -27, -22, -13, -4, 6,
+ 19, 36, 47, 47, 37, 33, 25, 6, -8, -15, -25, -31, -36, -43, -42, -32,
+ -21, -11, 0, 5, 15, 32, 46, 45, 35, 31, 28, 12, -6, -13, -20, -24,
+ -31, -41, -46, -38, -26, -18, -9, 1, 14, 31, 43, 48, 42, 33, 28, 15,
+ -5, -15, -18, -24, -31, -38, -41, -34, -26, -19, -8, 1, 10, 23, 37, 43,
+ 41, 32, 26, 19, 3, -12, -15, -18, -24, -34, -42, -38, -28, -20, -13, -4,
+ 6, 21, 37, 44, 43, 36, 28, 21, 8, -9, -16, -19, -25, -34, -42, -39,
+ -29, -21, -13, -3, 8, 19, 34, 42, 41, 36, 28, 20, 8, -7, -15, -16,
+ -19, -30, -41, -42, -31, -23, -15, -8, 3, 19, 36, 43, 39, 36, 30, 23,
+ 13, -6, -19, -21, -20, -26, -38, -43, -35, -25, -15, -7, 3, 14, 30, 42,
+ 40, 35, 28, 23, 16, 0, -14, -20, -19, -22, -34, -42, -37, -26, -15, -8,
+ 0, 12, 27, 40, 41, 35, 29, 22, 16, 4, -9, -19, -20, -20, -29, -39,
+ -39, -30, -19, -10, -3, 10, 24, 37, 42, 37, 31, 25, 18, 7, -7, -17,
+ -21, -20, -28, -38, -40, -33, -22, -11, -5, 9, 25, 37, 44, 40, 32, 24,
+ 17, 10, -5, -18, -24, -23, -28, -35, -38, -35, -26, -14, -5, 5, 19, 34,
+ 44, 42, 33, 23, 18, 13, 0, -15, -20, -22, -26, -33, -39, -35, -28, -18,
+ -10, 1, 18, 33, 43, 45, 38, 28, 20, 11, 2, -12, -22, -24, -28, -31,
+ -36, -35, -29, -21, -11, 0, 15, 30, 40, 44, 39, 31, 21, 13, 8, -5,
+ -17, -20, -25, -28, -32, -36, -34, -27, -18, -7, 9, 26, 39, 46, 45, 36,
+ 25, 14, 10, -2, -16, -24, -29, -31, -31, -36, -36, -27, -16, -7, 6, 23,
+ 37, 45, 44, 36, 26, 14, 8, 1, -14, -22, -23, -29, -32, -35, -36, -29,
+ -21, -14, 0, 16, 35, 46, 45, 39, 33, 20, 8, 3, -9, -21, -28, -32,
+ -34, -35, -36, -32, -25, -15, 1, 17, 32, 45, 49, 44, 35, 23, 7, 0,
+ -7, -17, -25, -30, -31, -32, -34, -31, -25, -18, -7, 10, 27, 43, 50, 45,
+ 35, 24, 13, 3, -7, -17, -24, -28, -30, -30, -33, -34, -26, -19, -11, 5,
+ 22, 39, 50, 48, 37, 26, 16, 5, -7, -18, -23, -27, -28, -28, -33, -34,
+ -24, -16, -11, 2, 17, 33, 48, 48, 37, 27, 18, 7, -5, -14, -20, -25,
+ -30, -31, -32, -37, -31, -20, -15, -3, 15, 30, 46, 53, 43, 31, 20, 11,
+ 0, -12, -21, -27, -31, -30, -30, -36, -33, -20, -10, -5, 9, 25, 41, 52,
+ 46, 34, 23, 15, 6, -9, -21, -27, -30, -31, -31, -37, -39, -25, -12, -7,
+ 1, 18, 36, 52, 53, 40, 28, 22, 13, -2, -18, -29, -32, -35, -34, -39,
+ -40, -28, -13, -7, -2, 12, 33, 50, 56, 44, 30, 24, 18, 4, -15, -29,
+ -32, -33, -33, -35, -40, -35, -20, -7, -2, 8, 25, 43, 54, 49, 35, 25,
+ 18, 8, -7, -23, -32, -32, -34, -34, -37, -36, -24, -11, -5, 2, 18, 36,
+ 51, 51, 39, 30, 24, 14, 0, -19, -32, -35, -35, -37, -38, -39, -29, -12,
+ -2, 3, 14, 29, 47, 54, 45, 33, 26, 17, 5, -12, -31, -37, -36, -38,
+ -38, -38, -32, -17, -3, 3, 9, 25, 42, 53, 49, 39, 31, 23, 10, -9,
+ -27, -38, -40, -41, -41, -41, -36, -23, -5, 5, 8, 18, 36, 51, 51, 43,
+ 34, 26, 16, 1, -20, -36, -40, -41, -42, -40, -38, -28, -10, 4, 7, 14,
+ 30, 48, 51, 45, 39, 31, 21, 4, -16, -33, -41, -43, -43, -39, -38, -32,
+ -15, 1, 7, 13, 25, 42, 52, 48, 39, 31, 22, 9, -10, -29, -40, -40,
+ -40, -38, -35, -34, -20, -2, 5, 9, 17, 33, 49, 50, 43, 34, 25, 13,
+ -4, -21, -36, -44, -44, -40, -35, -34, -26, -8, 5, 11, 17, 26, 43, 51,
+ 46, 36, 27, 16, 1, -16, -31, -42, -46, -43, -37, -35, -29, -12, 3, 11,
+ 17, 23, 37, 50, 52, 41, 29, 20, 4, -15, -30, -43, -49, -46, -39, -37,
+ -33, -15, 3, 13, 19, 23, 35, 52, 55, 44, 29, 20, 8, -12, -28, -40,
+ -48, -45, -39, -35, -32, -20, -2, 12, 16, 19, 28, 45, 55, 49, 35, 24,
+ 14, -3, -20, -36, -49, -53, -45, -38, -35, -27, -9, 8, 19, 23, 26, 40,
+ 55, 55, 41, 25, 15, -2, -19, -33, -46, -53, -47, -39, -35, -29, -14, 6,
+ 19, 24, 25, 35, 53, 59, 47, 29, 17, 7, -12, -30, -47, -58, -56, -47,
+ -39, -35, -22, -2, 17, 28, 30, 34, 50, 63, 56, 35, 19, 8, -9, -26,
+ -43, -56, -58, -49, -42, -38, -27, -9, 12, 26, 33, 34, 44, 60, 62, 44,
+ 23, 9, -4, -20, -40, -56, -63, -56, -44, -39, -30, -14, 8, 26, 35, 35,
+ 43, 60, 64, 50, 28, 13, 2, -16, -37, -53, -62, -61, -50, -42, -32, -17,
+ 2, 18, 32, 40, 44, 54, 63, 55, 37, 17, 4, -10, -31, -48, -61, -67,
+ -59, -45, -36, -24, -5, 17, 33, 43, 47, 54, 64, 59, 42, 20, 3, -10,
+ -28, -49, -63, -68, -63, -50, -37, -25, -7, 13, 31, 44, 48, 54, 61, 59,
+ 48, 27, 6, -10, -24, -43, -59, -67, -67, -56, -39, -28, -13, 8, 24, 42,
+ 51, 54, 58, 58, 52, 37, 14, -6, -20, -38, -54, -65, -70, -63, -45, -29,
+ -17, 2, 18, 37, 52, 56, 58, 56, 51, 42, 23, -2, -19, -34, -50, -62,
+ -70, -69, -52, -30, -17, -3, 15, 33, 50, 58, 58, 56, 52, 46, 29, 3,
+ -15, -31, -45, -58, -68, -71, -60, -38, -20, -5, 11, 25, 42, 58, 62, 58,
+ 51, 44, 36, 15, -10, -29, -43, -53, -64, -72, -67, -45, -21, -8, 4, 20,
+ 40, 60, 65, 57, 53, 48, 42, 21, -8, -27, -40, -50, -62, -71, -71, -54,
+ -29, -9, 3, 18, 34, 54, 68, 65, 57, 48, 40, 28, 2, -23, -41, -52,
+ -60, -71, -75, -60, -34, -12, 0, 13, 31, 52, 69, 66, 56, 50, 44, 33,
+ 7, -21, -38, -47, -55, -65, -75, -67, -41, -15, 2, 11, 23, 41, 61, 68,
+ 59, 49, 40, 34, 17, -11, -35, -47, -48, -55, -69, -72, -50, -21, 0, 8,
+ 15, 33, 56, 69, 62, 52, 44, 40, 26, -4, -30, -44, -48, -56, -69, -77,
+ -59, -28, -7, 7, 15, 30, 52, 68, 66, 55, 45, 38, 30, 6, -24, -43,
+ -49, -52, -64, -75, -65, -35, -10, 4, 11, 25, 45, 65, 67, 55, 48, 43,
+ 34, 13, -18, -39, -45, -49, -61, -75, -72, -45, -17, -2, 9, 20, 39, 61,
+ 70, 62, 52, 45, 36, 18, -9, -34, -47, -52, -58, -69, -72, -52, -23, -5,
+ 7, 17, 35, 54, 65, 63, 55, 45, 37, 23, 0, -27, -45, -49, -53, -63,
+ -71, -59, -31, -8, 7, 15, 28, 47, 61, 65, 58, 47, 38, 27, 6, -21,
+ -41, -49, -53, -62, -69, -62, -39, -14, 3, 14, 28, 46, 59, 64, 62, 51,
+ 39, 29, 11, -16, -40, -52, -55, -58, -65, -65, -47, -20, 1, 14, 24, 39,
+ 52, 59, 64, 56, 43, 33, 16, -8, -32, -49, -55, -58, -63, -65, -54, -29,
+ -3, 12, 21, 36, 51, 60, 65, 59, 46, 35, 21, -4, -28, -48, -56, -57,
+ -59, -60, -55, -37, -12, 9, 19, 32, 46, 54, 58, 58, 48, 36, 26, 7,
+ -18, -41, -53, -53, -52, -57, -58, -45, -19, 6, 15, 26, 42, 54, 59, 59,
+ 52, 39, 28, 10, -16, -40, -56, -56, -52, -51, -53, -45, -22, 4, 17, 24,
+ 35, 46, 56, 57, 52, 40, 30, 18, -7, -33, -54, -58, -52, -49, -53, -51,
+ -33, -5, 17, 26, 34, 43, 54, 58, 53, 42, 31, 19, 0, -24, -47, -60,
+ -55, -46, -46, -50, -39, -13, 13, 25, 32, 38, 48, 56, 52, 41, 30, 20,
+ 7, -15, -41, -58, -55, -44, -41, -44, -40, -19, 10, 25, 28, 32, 41, 53,
+ 52, 42, 31, 21, 13, -5, -32, -55, -60, -47, -36, -38, -40, -26, 2, 24,
+ 29, 28, 32, 46, 48, 40, 29, 21, 14, 1, -23, -48, -56, -46, -34, -33,
+ -36, -29, -7, 20, 28, 25, 26, 37, 46, 42, 30, 19, 15, 7, -13, -39,
+ -58, -54, -37, -27, -27, -29, -17, 13, 29, 28, 24, 31, 42, 42, 34, 21,
+ 11, 5, -10, -32, -51, -52, -40, -28, -24, -24, -18, 6, 27, 30, 26, 28,
+ 36, 38, 33, 22, 11, 6, -7, -26, -44, -49, -42, -30, -21, -17, -16, -5,
+ 18, 29, 26, 25, 29, 33, 33, 25, 13, 7, 0, -18, -36, -46, -45, -31,
+ -20, -16, -16, -9, 12, 28, 29, 24, 25, 29, 31, 26, 13, 2, -5, -15,
+ -26, -39, -46, -37, -19, -9, -9, -11, 1, 21, 31, 26, 21, 23, 26, 25,
+ 15, 4, -4, -10, -20, -32, -41, -38, -22, -10, -7, -9, -6, 11, 26, 29,
+ 22, 20, 21, 24, 19, 7, -6, -12, -17, -23, -30, -36, -27, -12, -3, 0,
+ -5, 3, 18, 28, 25, 18, 15, 16, 15, 7, -4, -10, -14, -19, -24, -30,
+ -26, -13, -3, 2, -3, -2, 12, 23, 26, 18, 13, 13, 14, 9, 0, -11,
+ -14, -15, -18, -24, -26, -16, -4, 4, 0, -5, 6, 17, 25, 21, 11, 7,
+ 8, 8, 1, -11, -14, -11, -10, -13, -20, -18, -7, 5, 7, -3, -2, 8,
+ 21, 23, 12, 4, 4, 8, 7, -5, -15, -14, -11, -9, -15, -20, -13, 1,
+ 8, 3, 0, 6, 17, 24, 16, 3, -2, 1, 0, -10, -17, -14, -8, -4,
+ -5, -11, -12, 0, 9, 6, -3, 1, 10, 18, 16, 5, -3, 0, 3, -4,
+ -13, -15, -10, -6, -4, -8, -13, -8, 5, 8, 5, 3, 9, 17, 18, 13,
+ 0, -7, -5, -5, -11, -14, -11, -6, 2, 2, -6, -9, 1, 8, 5, -2,
+ 1, 8, 14, 12, 2, -6, -5, -2, -6, -12, -10, -2, 3, 4, -5, -11,
+ -6, 5, 6, 0, 0, 7, 12, 14, 6, -7, -8, -6, -6, -9, -10, -5,
+ 4, 8, 4, -7, -11, -2, 6, 3, -2, 2, 9, 15, 12, -2, -8, -6,
+ -3, -5, -11, -9, 2, 10, 7, -5, -15, -10, 4, 6, -2, -2, 8, 14,
+ 14, 3, -9, -8, -5, -4, -8, -10, 0, 8, 9, 3, -9, -12, -3, 6,
+ 3, -3, 1, 8, 13, 5, -9, -13, -7, -2, -2, -6, -2, 9, 13, 6,
+ -6, -13, -10, 2, 4, -3, -2, 7, 13, 9, -6, -12, -11, -6, 0, -5,
+ -5, 7, 15, 13, 1, -10, -13, -4, 5, -2, -7, -2, 9, 9, -3, -11,
+ -11, -8, 2, 1, -3, 7, 15, 12, 4, -7, -13, -11, -2, 1, -4, -3,
+ 7, 11, 3, -8, -11, -10, 0, 1, -5, 2, 12, 17, 11, -2, -11, -11,
+ -3, 4, -4, -9, 1, 10, 3, -9, -11, -8, 0, 5, 1, 2, 11, 14,
+ 9, 1, -11, -15, -11, -3, 1, -3, 3, 12, 11, 1, -7, -9, -6, -3,
+ -5, -5, 5, 12, 9, 4, -3, -8, -8, -5, 0, -4, -3, 5, 6, -3,
+ -10, -7, -3, 0, 2, 3, 10, 14, 11, 4, -3, -11, -15, -15, -9, -5,
+ -5, 5, 13, 5, -2, 0, 2, 4, 1, -3, 4, 12, 11, 2, -5, -10,
+ -13, -13, -11, -6, -4, 3, 13, 9, 1, -2, 4, 5, 1, -5, 3, 12,
+ 13, 4, -9, -12, -14, -16, -17, -12, -5, 5, 16, 17, 6, 3, 9, 9,
+ 2, -8, -7, 2, 7, 4, -8, -12, -10, -13, -14, -13, -6, 4, 13, 19,
+ 10, 0, 6, 14, 8, -6, -9, 0, 7, 5, -8, -17, -13, -9, -14, -18,
+ -13, 2, 15, 23, 16, 4, 5, 16, 15, 0, -10, -6, 3, 6, -4, -15,
+ -15, -10, -11, -16, -16, -5, 10, 21, 18, 7, 2, 12, 18, 6, -7, -9,
+ 1, 7, 1, -14, -19, -15, -13, -16, -18, -8, 7, 19, 24, 16, 5, 8,
+ 16, 9, -4, -9, -5, 3, 4, -9, -19, -18, -13, -12, -17, -12, 2, 16,
+ 22, 17, 6, 4, 14, 13, 1, -8, -6, 2, 6, -5, -18, -20, -16, -14,
+ -18, -17, -5, 12, 23, 24, 14, 9, 15, 19, 9, -5, -8, -3, 2, -6,
+ -17, -23, -19, -14, -16, -17, -8, 7, 19, 24, 19, 10, 11, 17, 13, 3,
+ -5, -3, -2, -4, -14, -24, -25, -20, -18, -16, -10, 3, 16, 26, 28, 18,
+ 11, 15, 17, 9, -4, -7, -6, -6, -12, -24, -29, -22, -16, -15, -10, 0,
+ 13, 24, 27, 22, 14, 13, 16, 13, 2, -6, -7, -9, -12, -21, -29, -27,
+ -21, -15, -10, -3, 8, 21, 29, 26, 17, 13, 17, 19, 9, -5, -10, -9,
+ -12, -21, -30, -29, -22, -14, -10, -4, 7, 17, 26, 23, 17, 13, 12, 18,
+ 16, 5, -6, -10, -11, -19, -29, -32, -27, -18, -10, -4, 4, 13, 25, 26,
+ 21, 16, 11, 16, 17, 8, -5, -12, -12, -16, -25, -30, -27, -19, -10, -6,
+ 0, 10, 21, 24, 18, 15, 13, 16, 20, 14, 1, -10, -12, -15, -26, -31,
+ -29, -22, -12, -5, 0, 8, 19, 25, 22, 17, 14, 14, 19, 17, 4, -10,
+ -15, -15, -22, -30, -30, -26, -16, -6, 1, 7, 15, 23, 23, 18, 17, 17,
+ 17, 17, 8, -6, -15, -18, -24, -31, -29, -26, -19, -8, 2, 7, 15, 23,
+ 24, 21, 17, 15, 15, 17, 13, -4, -16, -20, -23, -30, -32, -27, -19, -8,
+ 3, 7, 14, 23, 24, 20, 16, 16, 15, 14, 10, 0, -12, -20, -24, -31,
+ -32, -25, -19, -10, 0, 9, 14, 22, 27, 23, 17, 17, 18, 12, 8, 1,
+ -12, -18, -23, -31, -34, -26, -17, -9, -2, 6, 14, 22, 27, 22, 16, 15,
+ 18, 17, 10, 3, -9, -17, -21, -31, -38, -32, -23, -13, -5, 4, 14, 21,
+ 30, 30, 21, 17, 18, 17, 10, 3, -8, -20, -23, -29, -38, -34, -25, -12,
+ 0, 3, 11, 17, 26, 31, 23, 15, 13, 16, 14, 5, -4, -15, -19, -23,
+ -35, -38, -32, -19, -7, -5, 6, 16, 25, 36, 32, 22, 19, 19, 15, 3,
+ -7, -16, -23, -26, -35, -42, -34, -19, -3, 1, 6, 18, 26, 37, 34, 20,
+ 15, 14, 14, 5, -7, -15, -21, -23, -28, -39, -37, -22, -5, 1, 3, 15,
+ 25, 35, 40, 27, 14, 14, 14, 6, -7, -14, -20, -25, -27, -36, -41, -28,
+ -8, 2, 4, 14, 24, 33, 40, 32, 17, 13, 12, 5, -7, -14, -17, -24,
+ -28, -34, -40, -32, -14, 1, 4, 13, 26, 33, 41, 40, 26, 15, 12, 4,
+ -9, -17, -20, -25, -31, -34, -41, -38, -20, 0, 7, 12, 24, 32, 40, 41,
+ 30, 17, 11, 4, -10, -18, -19, -21, -27, -31, -35, -36, -24, -5, 5, 9,
+ 21, 31, 37, 41, 36, 21, 11, 4, -8, -15, -18, -21, -26, -31, -34, -37,
+ -30, -12, 3, 9, 18, 30, 38, 44, 42, 29, 15, 7, -6, -18, -23, -24,
+ -25, -31, -34, -36, -33, -15, 3, 9, 17, 28, 38, 44, 42, 34, 20, 8,
+ -5, -18, -23, -22, -24, -30, -35, -35, -35, -24, -6, 6, 14, 25, 36, 42,
+ 45, 42, 28, 13, 1, -15, -26, -27, -26, -29, -35, -39, -38, -28, -10, 5,
+ 13, 21, 36, 47, 48, 45, 36, 21, 6, -11, -25, -31, -30, -29, -35, -41,
+ -41, -34, -18, 1, 15, 24, 35, 47, 52, 51, 42, 26, 8, -9, -25, -32,
+ -34, -32, -34, -40, -41, -35, -22, -5, 11, 21, 30, 44, 52, 51, 45, 32,
+ 15, -3, -19, -28, -33, -34, -36, -42, -44, -41, -30, -13, 6, 20, 29, 43,
+ 54, 56, 50, 37, 22, 4, -17, -31, -39, -39, -38, -40, -44, -41, -31, -14,
+ 4, 18, 26, 37, 52, 57, 54, 44, 29, 11, -9, -26, -38, -42, -40, -41,
+ -45, -46, -39, -24, -2, 17, 25, 35, 49, 59, 59, 52, 36, 19, -2, -22,
+ -38, -46, -45, -43, -44, -47, -41, -28, -7, 12, 22, 32, 45, 58, 60, 52,
+ 40, 26, 9, -14, -36, -46, -47, -44, -44, -50, -47, -34, -14, 8, 21, 30,
+ 42, 58, 65, 58, 46, 32, 14, -7, -30, -47, -51, -50, -45, -50, -51, -38,
+ -20, 4, 19, 28, 38, 53, 67, 63, 50, 40, 23, 2, -22, -43, -54, -55,
+ -50, -53, -57, -48, -31, -6, 17, 28, 39, 53, 69, 72, 60, 47, 29, 7,
+ -18, -39, -54, -59, -56, -53, -55, -52, -37, -16, 10, 25, 36, 48, 65, 75,
+ 68, 54, 40, 20, -6, -31, -52, -61, -61, -59, -63, -62, -46, -24, 2, 20,
+ 33, 50, 67, 79, 75, 62, 49, 30, 2, -29, -50, -63, -66, -65, -64, -64,
+ -50, -28, -6, 18, 34, 48, 62, 74, 79, 70, 54, 38, 14, -19, -45, -62,
+ -70, -71, -67, -68, -61, -39, -15, 10, 28, 45, 63, 77, 82, 77, 62, 47,
+ 25, -9, -40, -61, -70, -73, -69, -70, -66, -47, -23, 2, 23, 41, 57, 71,
+ 79, 83, 72, 55, 37, 6, -27, -51, -67, -76, -78, -77, -75, -60, -35, -12,
+ 13, 37, 59, 75, 82, 86, 81, 66, 48, 17, -23, -50, -66, -77, -83, -83,
+ -78, -66, -43, -18, 7, 31, 54, 73, 83, 87, 87, 74, 55, 29, -10, -41,
+ -61, -76, -85, -88, -84, -72, -53, -28, -3, 22, 51, 75, 84, 88, 92, 87,
+ 67, 40, 0, -38, -60, -77, -89, -94, -89, -77, -59, -34, -7, 17, 44, 73,
+ 88, 90, 91, 88, 74, 49, 12, -29, -57, -73, -84, -93, -94, -84, -68, -44,
+ -17, 8, 33, 64, 85, 90, 92, 91, 83, 63, 30, -15, -50, -71, -82, -92,
+ -96, -90, -74, -52, -26, 0, 24, 56, 82, 92, 93, 92, 89, 74, 42, 0,
+ -41, -67, -80, -93, -100, -97, -83, -62, -35, -8, 16, 43, 74, 91, 96, 96,
+ 93, 83, 56, 16, -28, -61, -79, -92, -99, -99, -90, -71, -45, -16, 9, 36,
+ 66, 88, 98, 97, 93, 87, 68, 31, -16, -52, -75, -89, -98, -103, -98, -81,
+ -54, -23, 1, 25, 56, 83, 97, 98, 92, 88, 76, 46, 1, -42, -68, -81,
+ -91, -99, -97, -82, -58, -30, -6, 15, 44, 73, 91, 94, 89, 85, 78, 55,
+ 16, -28, -59, -77, -87, -93, -95, -85, -65, -40, -16, 6, 33, 62, 85, 94,
+ 90, 86, 81, 66, 32, -15, -52, -73, -84, -90, -93, -87, -69, -45, -22, 0,
+ 22, 48, 75, 88, 88, 85, 80, 67, 42, 4, -36, -62, -77, -87, -90, -85,
+ -72, -52, -30, -11, 11, 36, 63, 83, 86, 86, 82, 74, 54, 17, -25, -55,
+ -72, -81, -88, -87, -77, -57, -34, -16, 4, 26, 54, 77, 84, 84, 82, 75,
+ 58, 27, -12, -45, -65, -76, -84, -84, -76, -61, -41, -24, -7, 15, 41, 67,
+ 78, 81, 80, 76, 67, 42, 5, -30, -54, -67, -79, -85, -79, -67, -50, -32,
+ -16, 6, 32, 58, 73, 77, 81, 78, 68, 49, 16, -19, -45, -63, -74, -80,
+ -77, -67, -53, -35, -20, -3, 20, 45, 65, 72, 76, 75, 68, 56, 29, -6,
+ -33, -52, -65, -75, -77, -70, -57, -42, -28, -13, 9, 34, 57, 70, 73, 75,
+ 72, 63, 41, 7, -24, -46, -60, -70, -75, -72, -59, -45, -31, -18, 0, 25,
+ 48, 63, 68, 70, 71, 65, 47, 17, -13, -33, -49, -62, -73, -73, -61, -48,
+ -37, -25, -10, 14, 39, 57, 64, 67, 70, 69, 54, 28, -3, -27, -44, -57,
+ -68, -74, -66, -50, -39, -26, -13, 5, 30, 50, 60, 62, 64, 65, 58, 38,
+ 9, -17, -35, -46, -59, -69, -67, -52, -40, -31, -20, -6, 18, 42, 55, 58,
+ 60, 65, 62, 47, 20, -10, -28, -39, -51, -66, -70, -58, -44, -34, -23, -10,
+ 11, 34, 51, 57, 58, 62, 63, 51, 29, 2, -21, -34, -46, -60, -69, -63,
+ -49, -37, -27, -15, 3, 26, 45, 55, 56, 58, 62, 55, 37, 11, -14, -29,
+ -39, -52, -65, -66, -52, -40, -30, -18, -5, 17, 39, 52, 54, 55, 58, 57,
+ 44, 21, -8, -24, -33, -45, -59, -66, -57, -43, -31, -20, -11, 7, 30, 47,
+ 53, 51, 52, 55, 51, 33, 4, -20, -29, -36, -49, -64, -63, -50, -36, -24,
+ -14, 0, 22, 43, 55, 53, 49, 52, 51, 39, 12, -16, -27, -33, -45, -60,
+ -66, -53, -37, -25, -16, -6, 16, 40, 53, 53, 47, 49, 51, 43, 22, 0,
+ 0, 0, 0, 0, 0, 0, 0, 22, 0, 0, -2, -2, -2, -2, 0, -2,
+ 0, 0, 1, 2, 3, 4, 4, 4, 5, 6, 7, 6, 3, 1, 0, -3,
+ -5, -11, -17, -20, -20, -18, -16, -17, -17, -14, -10, -9, -13, -18, -19, -15,
+ -13, -12, -13, -8, 1, 12, 25, 32, 40, 45, 50, 49, 41, 32, 24, 16,
+ 9, 1, -12, -20, -23, -24, -20, -20, -18, -12, -11, -12, -7, 0, 10, 17,
+ 23, 25, 24, 21, 22, 23, 21, 10, 1, -5, -8, -11, -19, -29, -33, -32,
+ -26, -19, -16, -14, -12, -8, -7, -11, -19, -27, -29, -27, -25, -25, -24, -17,
+ -4, 13, 26, 34, 43, 54, 59, 56, 46, 33, 23, 15, 5, -11, -23, -32,
+ -35, -32, -30, -27, -23, -16, -11, -5, 3, 11, 23, 31, 36, 33, 28, 27,
+ 26, 21, 11, 1, -9, -14, -18, -23, -28, -35, -33, -26, -18, -12, -11, -7,
+ -4, -2, 0, -8, -19, -29, -33, -32, -30, -30, -25, -17, -4, 13, 26, 36,
+ 47, 55, 59, 53, 43, 32, 23, 12, 0, -14, -23, -30, -35, -35, -35, -33,
+ -28, -19, -11, -6, 3, 11, 22, 33, 39, 38, 34, 30, 27, 20, 11, 0,
+ -9, -17, -21, -26, -31, -34, -29, -19, -8, -3, 0, -3, 1, 4, 1, -11,
+ -25, -35, -37, -39, -35, -32, -27, -17, 0, 15, 29, 42, 55, 63, 62, 55,
+ 47, 38, 27, 14, -4, -20, -31, -40, -44, -46, -45, -41, -34, -25, -14, -3,
+ 8, 22, 32, 43, 44, 40, 36, 34, 26, 18, 8, -2, -11, -20, -25, -29,
+ -33, -31, -21, -10, -2, -2, -2, 4, 6, 9, 0, -14, -28, -35, -39, -38,
+ -38, -36, -30, -16, 0, 16, 29, 41, 55, 65, 67, 59, 49, 39, 28, 13,
+ -3, -19, -32, -42, -48, -51, -53, -47, -36, -22, -12, 0, 10, 24, 38, 46,
+ 48, 43, 39, 32, 26, 17, 6, -7, -16, -21, -26, -31, -34, -28, -16, -2,
+ 3, 1, 2, 8, 16, 12, 2, -15, -27, -34, -37, -41, -47, -44, -33, -16,
+ 1, 16, 31, 47, 65, 75, 73, 63, 52, 41, 27, 9, -14, -34, -47, -54,
+ -55, -58, -57, -50, -35, -17, 0, 8, 20, 34, 47, 54, 49, 42, 36, 29,
+ 21, 9, -4, -14, -21, -26, -30, -33, -28, -18, -5, 4, 6, 6, 8, 13,
+ 17, 12, -4, -21, -33, -39, -44, -49, -50, -46, -35, -15, 4, 22, 36, 55,
+ 72, 81, 78, 69, 54, 42, 27, 6, -19, -38, -52, -57, -62, -65, -64, -52,
+ -35, -17, -3, 8, 19, 33, 45, 50, 48, 42, 35, 29, 18, 7, -5, -11,
+ -20, -26, -29, -27, -20, -13, -4, 3, 8, 9, 11, 12, 12, 5, -8, -22,
+ -33, -42, -50, -53, -51, -42, -27, -11, 9, 27, 45, 62, 75, 78, 73, 60,
+ 48, 32, 14, -8, -30, -46, -54, -60, -64, -62, -53, -39, -23, -8, 5, 17,
+ 30, 41, 46, 44, 38, 30, 22, 11, 4, -5, -12, -20, -25, -26, -24, -17,
+ -7, 3, 8, 11, 12, 14, 15, 14, 9, -4, -17, -32, -44, -54, -57, -56,
+ -48, -36, -22, -5, 18, 41, 61, 74, 79, 75, 67, 55, 39, 20, -2, -20,
+ -37, -47, -56, -62, -63, -57, -44, -31, -18, -5, 7, 16, 28, 35, 38, 37,
+ 32, 25, 16, 8, 3, -2, -5, -11, -19, -21, -16, -7, 3, 6, 8, 7,
+ 8, 10, 9, 5, -4, -13, -23, -37, -49, -54, -54, -47, -38, -25, -9, 9,
+ 30, 50, 67, 77, 75, 69, 58, 42, 26, 7, -12, -31, -46, -52, -56, -59,
+ -58, -49, -36, -19, -5, 8, 14, 22, 28, 33, 35, 30, 23, 13, 4, 3,
+ 3, 0, -8, -12, -13, -10, -6, 2, 8, 11, 12, 11, 9, 4, -2, -5,
+ -12, -23, -35, -46, -52, -54, -48, -36, -22, -8, 9, 28, 46, 61, 70, 72,
+ 68, 58, 45, 27, 9, -8, -22, -35, -43, -48, -48, -46, -39, -33, -23, -12,
+ 1, 8, 11, 14, 16, 19, 19, 17, 11, 7, 8, 11, 13, 7, 5, 2,
+ 2, 2, 4, 6, 6, 5, 2, -3, -5, -9, -11, -17, -23, -29, -34, -40,
+ -45, -41, -32, -18, -5, 7, 19, 36, 54, 64, 67, 61, 55, 48, 36, 18,
+ 3, -11, -23, -36, -45, -46, -42, -39, -34, -27, -20, -11, 0, 10, 13, 14,
+ 12, 13, 13, 10, 7, 6, 9, 11, 11, 11, 10, 10, 8, 9, 9, 9,
+ 6, 1, -4, -12, -16, -22, -25, -28, -29, -30, -39, -43, -39, -26, -11, 0,
+ 8, 19, 33, 48, 58, 63, 61, 56, 50, 40, 25, 8, -5, -15, -24, -35,
+ -41, -42, -39, -32, -29, -25, -21, -13, -6, 0, 4, 2, 2, 3, 6, 6,
+ 7, 11, 17, 20, 22, 23, 24, 23, 21, 17, 12, 4, -5, -13, -22, -29,
+ -37, -41, -40, -36, -31, -32, -34, -34, -22, -6, 8, 14, 20, 29, 41, 50,
+ 56, 56, 49, 45, 39, 30, 17, 5, -8, -19, -28, -34, -35, -32, -27, -25,
+ -25, -23, -19, -12, -7, -4, -6, -10, -11, -7, 0, 4, 10, 14, 19, 26,
+ 32, 35, 34, 31, 25, 16, 6, -5, -17, -29, -39, -47, -51, -50, -44, -35,
+ -28, -27, -25, -18, -6, 10, 18, 21, 25, 31, 40, 46, 49, 48, 44, 42,
+ 37, 29, 19, 8, -5, -14, -21, -29, -30, -30, -27, -28, -32, -33, -31, -22,
+ -17, -15, -17, -19, -19, -9, 5, 16, 22, 25, 31, 38, 44, 47, 43, 34,
+ 20, 6, -9, -21, -35, -49, -59, -62, -60, -53, -42, -30, -22, -15, -6, 4,
+ 14, 23, 27, 28, 27, 30, 35, 38, 39, 42, 38, 35, 30, 25, 20, 12,
+ 4, -6, -18, -23, -22, -20, -22, -30, -37, -39, -34, -29, -27, -27, -26, -23,
+ -16, -3, 10, 21, 29, 35, 43, 46, 50, 49, 41, 28, 15, -2, -19, -35,
+ -50, -62, -67, -67, -60, -50, -36, -23, -14, -6, 3, 11, 21, 27, 27, 24,
+ 25, 27, 29, 31, 36, 41, 42, 39, 33, 27, 22, 17, 8, -3, -11, -15,
+ -15, -18, -25, -35, -42, -45, -42, -41, -41, -40, -38, -28, -12, 7, 22, 34,
+ 43, 51, 59, 62, 59, 49, 37, 20, 1, -19, -38, -54, -65, -73, -74, -69,
+ -55, -35, -19, -10, -2, 8, 18, 23, 25, 25, 22, 20, 19, 20, 22, 30,
+ 39, 44, 42, 39, 35, 32, 29, 18, 4, -8, -13, -15, -17, -24, -33, -43,
+ -47, -44, -42, -40, -40, -39, -32, -17, 3, 16, 28, 39, 47, 53, 56, 56,
+ 52, 40, 24, 5, -12, -29, -43, -54, -65, -72, -71, -56, -36, -20, -13, -4,
+ 5, 12, 18, 21, 23, 20, 18, 14, 16, 19, 27, 38, 45, 45, 42, 41,
+ 42, 37, 27, 15, 1, -8, -12, -13, -17, -30, -40, -47, -48, -47, -46, -46,
+ -45, -41, -28, -9, 11, 26, 38, 45, 51, 55, 58, 55, 47, 31, 10, -12,
+ -27, -39, -49, -58, -67, -69, -62, -46, -26, -13, -4, 2, 7, 14, 18, 21,
+ 20, 15, 11, 12, 14, 21, 32, 40, 44, 42, 42, 40, 37, 33, 22, 11,
+ 1, -7, -11, -11, -19, -30, -39, -43, -43, -42, -43, -44, -44, -36, -20, 0,
+ 14, 25, 35, 42, 46, 50, 50, 48, 36, 17, -3, -18, -30, -36, -43, -52,
+ -59, -60, -49, -35, -20, -12, -7, -4, 2, 8, 12, 12, 9, 9, 12, 16,
+ 23, 29, 39, 45, 46, 46, 43, 41, 37, 30, 20, 7, -5, -10, -11, -15,
+ -25, -39, -46, -45, -43, -42, -45, -46, -39, -26, -8, 8, 20, 31, 41, 45,
+ 48, 46, 44, 36, 21, 1, -20, -31, -33, -36, -44, -53, -59, -54, -41, -26,
+ -17, -12, -6, -3, 5, 7, 9, 11, 11, 12, 15, 20, 29, 36, 42, 46,
+ 45, 42, 40, 38, 33, 25, 13, 4, -7, -10, -11, -17, -29, -38, -38, -34,
+ -35, -39, -41, -39, -31, -16, -6, 4, 14, 24, 30, 34, 34, 35, 32, 22,
+ 8, -9, -16, -16, -17, -22, -33, -43, -46, -41, -34, -30, -25, -19, -14, -9,
+ -6, -2, 5, 9, 13, 15, 21, 29, 36, 43, 47, 46, 46, 42, 39, 37,
+ 31, 20, 10, 0, -6, -9, -14, -22, -29, -33, -31, -30, -34, -37, -37, -30,
+ -21, -12, -5, 1, 10, 20, 28, 31, 31, 28, 20, 12, 0, -8, -10, -10,
+ -16, -24, -33, -39, -44, -42, -35, -28, -23, -18, -14, -10, -4, 6, 12, 16,
+ 17, 22, 29, 33, 35, 38, 41, 43, 41, 38, 34, 30, 24, 16, 9, 3,
+ -4, -10, -15, -21, -23, -23, -23, -24, -28, -32, -31, -28, -22, -15, -10, -6,
+ 2, 11, 20, 23, 25, 19, 14, 9, 5, 3, 2, -2, -8, -19, -28, -36,
+ -42, -44, -39, -33, -28, -26, -20, -11, 0, 8, 15, 22, 28, 33, 35, 36,
+ 37, 38, 41, 40, 38, 32, 27, 21, 17, 11, 4, -3, -8, -12, -17, -18,
+ -16, -16, -15, -18, -22, -25, -26, -25, -23, -19, -15, -9, -2, 8, 13, 17,
+ 18, 17, 16, 15, 13, 10, 6, 0, -9, -21, -32, -42, -47, -46, -43, -36,
+ -30, -22, -15, -6, 4, 14, 22, 28, 33, 36, 37, 36, 35, 37, 36, 36,
+ 32, 27, 23, 16, 10, 5, 0, -7, -10, -12, -11, -11, -11, -10, -9, -11,
+ -16, -22, -27, -30, -30, -30, -25, -19, -9, 0, 7, 13, 18, 23, 27, 27,
+ 26, 20, 12, 1, -13, -27, -40, -50, -54, -54, -49, -42, -33, -21, -10, 1,
+ 14, 24, 30, 39, 44, 43, 38, 36, 38, 37, 34, 31, 28, 22, 13, 7,
+ 5, -2, -7, -11, -14, -13, -13, -8, -6, -6, -10, -12, -14, -19, -26, -34,
+ -38, -33, -26, -15, -7, 2, 7, 17, 26, 35, 40, 37, 29, 19, 7, -12,
+ -31, -44, -53, -56, -61, -62, -59, -46, -27, -9, 5, 14, 25, 36, 47, 53,
+ 51, 45, 37, 34, 32, 29, 26, 23, 18, 13, 5, 0, -3, -4, -6, -10,
+ -12, -12, -6, 2, 6, 2, -6, -12, -17, -21, -31, -41, -47, -43, -32, -20,
+ -11, -4, 9, 21, 40, 50, 48, 42, 34, 22, 5, -16, -36, -53, -58, -63,
+ -69, -73, -63, -43, -19, -2, 9, 19, 34, 50, 60, 61, 53, 42, 37, 32,
+ 30, 24, 21, 16, 11, 4, -4, -7, -6, -5, -5, -10, -14, -11, -4, 3,
+ 2, -2, -8, -13, -19, -26, -36, -42, -40, -33, -21, -9, 1, 10, 22, 36,
+ 49, 53, 47, 36, 19, 1, -18, -36, -51, -60, -65, -67, -67, -63, -47, -24,
+ -4, 11, 20, 33, 48, 57, 57, 52, 42, 33, 30, 28, 25, 19, 16, 12,
+ 8, 3, -2, -2, -2, -2, -5, -8, -10, -5, -2, 0, 0, -5, -8, -15,
+ -23, -32, -39, -38, -33, -24, -15, -7, 5, 16, 30, 45, 52, 49, 40, 23,
+ 4, -14, -29, -42, -55, -63, -67, -67, -61, -50, -35, -19, 0, 16, 31, 46,
+ 56, 59, 56, 47, 38, 34, 31, 28, 23, 16, 10, 4, 0, -2, -2, 0,
+ -5, -9, -12, -11, -7, -3, -3, -4, -5, -4, -7, -14, -26, -33, -32, -27,
+ -20, -15, -7, 2, 13, 21, 34, 42, 46, 40, 25, 7, -13, -27, -35, -44,
+ -54, -62, -64, -60, -51, -39, -26, -10, 8, 24, 40, 51, 58, 60, 54, 44,
+ 36, 29, 24, 19, 13, 8, 0, -6, -5, 0, 1, 0, -4, -3, -2, 0,
+ 1, -2, -5, -5, -4, -7, -17, -27, -31, -29, -24, -19, -15, -9, -3, 7,
+ 18, 27, 34, 39, 37, 26, 9, -9, -24, -32, -39, -47, -55, -60, -57, -51,
+ -42, -32, -20, -6, 14, 31, 48, 57, 60, 58, 52, 45, 35, 25, 21, 17,
+ 9, 0, -8, -10, -8, -7, -6, -9, -9, -6, -2, 0, -3, -6, -6, -2,
+ 1, -6, -15, -25, -25, -20, -17, -13, -11, -7, 1, 8, 16, 24, 31, 34,
+ 29, 16, -3, -17, -28, -35, -41, -47, -54, -56, -54, -46, -37, -27, -15, 4,
+ 23, 40, 50, 58, 60, 58, 50, 42, 34, 26, 19, 14, 4, -6, -13, -13,
+ -13, -14, -16, -15, -12, -9, -7, -7, -4, -4, 2, 7, 5, 0, -8, -11,
+ -13, -13, -11, -10, -11, -11, -9, 0, 8, 14, 22, 24, 19, 9, -3, -14,
+ -23, -29, -32, -38, -47, -54, -52, -44, -32, -23, -9, 8, 23, 39, 52, 59,
+ 58, 51, 46, 43, 33, 25, 16, 9, 4, -4, -11, -15, -16, -16, -15, -14,
+ -15, -16, -13, -7, -5, 2, 5, 5, 5, 6, 3, -4, -6, -4, -5, -10,
+ -16, -16, -13, -6, 4, 12, 15, 17, 14, 10, 4, -8, -17, -23, -30, -38,
+ -46, -52, -51, -41, -30, -20, -8, 9, 29, 47, 56, 57, 55, 52, 50, 45,
+ 34, 20, 10, 2, -2, -9, -16, -22, -24, -22, -21, -22, -19, -14, -7, -4,
+ 1, 5, 11, 15, 20, 17, 9, 3, 3, 0, -6, -15, -21, -23, -16, -9,
+ -3, 4, 10, 13, 15, 13, 4, -9, -15, -20, -27, -39, -48, -51, -47, -38,
+ -29, -21, -7, 16, 36, 48, 51, 52, 55, 60, 59, 49, 33, 20, 12, 7,
+ -2, -13, -24, -28, -27, -26, -30, -32, -29, -20, -9, 0, 3, 8, 16, 25,
+ 28, 23, 17, 12, 6, -2, -14, -26, -31, -27, -18, -10, -3, 7, 15, 22,
+ 24, 18, 9, 0, -9, -19, -34, -46, -57, -57, -51, -44, -38, -26, -5, 21,
+ 42, 48, 53, 58, 67, 75, 71, 57, 37, 23, 12, 3, -12, -27, -39, -43,
+ -43, -45, -47, -42, -28, -12, 2, 7, 12, 20, 32, 38, 37, 30, 21, 13,
+ 1, -13, -26, -34, -33, -26, -17, -10, -3, 9, 20, 25, 22, 13, 5, -3,
+ -13, -28, -43, -53, -56, -51, -46, -40, -31, -14, 10, 31, 41, 47, 56, 67,
+ 76, 73, 63, 46, 30, 19, 9, -7, -25, -39, -47, -50, -54, -52, -50, -38,
+ -22, -9, 4, 12, 22, 30, 39, 41, 39, 31, 22, 12, -3, -19, -30, -32,
+ -29, -23, -17, -9, 1, 12, 20, 24, 18, 10, 2, -7, -19, -35, -50, -59,
+ -59, -54, -49, -43, -31, -9, 15, 32, 41, 53, 70, 85, 87, 80, 64, 49,
+ 37, 23, 2, -23, -42, -52, -59, -66, -69, -68, -56, -38, -18, -2, 9, 19,
+ 31, 41, 49, 51, 44, 35, 21, 5, -9, -22, -29, -30, -26, -20, -14, -7,
+ 5, 15, 17, 14, 9, 2, -4, -16, -29, -45, -55, -56, -50, -46, -44, -36,
+ -19, 1, 19, 33, 46, 63, 79, 86, 84, 73, 60, 47, 32, 12, -10, -30,
+ -48, -59, -68, -72, -73, -64, -49, -30, -12, 2, 12, 26, 35, 45, 51, 51,
+ 44, 30, 15, 3, -9, -17, -20, -21, -19, -18, -14, 0, 10, 16, 15, 7,
+ -4, -10, -14, -24, -38, -51, -58, -55, -50, -44, -36, -23, -7, 10, 26, 41,
+ 57, 76, 89, 89, 81, 70, 59, 45, 25, 0, -24, -41, -56, -67, -75, -80,
+ -76, -63, -45, -26, -9, 6, 20, 32, 44, 52, 54, 53, 47, 35, 18, 3,
+ -6, -11, -14, -16, -19, -19, -12, -4, 5, 5, 0, -8, -12, -15, -21, -34,
+ -47, -51, -45, -39, -34, -30, -23, -12, 4, 17, 31, 45, 60, 72, 78, 75,
+ 69, 62, 53, 40, 18, -5, -24, -38, -50, -62, -73, -78, -74, -59, -41, -28,
+ -17, -4, 14, 33, 47, 55, 58, 55, 48, 39, 29, 16, 4, -5, -11, -18,
+ -21, -20, -15, -8, -7, -9, -13, -15, -16, -17, -23, -33, -43, -44, -41, -34,
+ -28, -23, -16, -8, 5, 21, 36, 50, 62, 73, 76, 73, 68, 59, 48, 30,
+ 9, -16, -35, -48, -59, -70, -77, -79, -72, -54, -38, -24, -8, 8, 29, 45,
+ 56, 61, 62, 56, 51, 39, 27, 16, 4, -8, -16, -22, -23, -25, -19, -16,
+ -17, -19, -20, -21, -18, -19, -25, -32, -38, -34, -24, -19, -15, -12, -7, 3,
+ 15, 28, 39, 48, 56, 63, 63, 63, 57, 47, 32, 14, -5, -22, -36, -46,
+ -58, -68, -73, -71, -61, -47, -35, -23, -9, 10, 29, 43, 52, 56, 56, 56,
+ 52, 45, 33, 19, 6, -5, -15, -22, -25, -26, -26, -29, -29, -26, -24, -20,
+ -19, -23, -27, -30, -27, -21, -18, -14, -10, -7, 0, 8, 18, 30, 40, 47,
+ 52, 54, 54, 55, 49, 39, 22, 7, -9, -24, -37, -50, -58, -65, -71, -67,
+ -59, -50, -39, -23, -6, 15, 32, 43, 51, 57, 61, 64, 61, 52, 37, 21,
+ 4, -11, -20, -26, -30, -35, -37, -39, -35, -29, -22, -17, -20, -22, -20, -18,
+ -17, -16, -13, -8, -3, 2, 7, 10, 17, 27, 35, 42, 43, 44, 45, 44,
+ 38, 28, 16, 3, -10, -22, -33, -46, -57, -64, -64, -59, -53, -46, -34, -17,
+ 3, 21, 32, 41, 48, 55, 60, 60, 54, 44, 31, 18, 3, -10, -19, -27,
+ -30, -32, -34, -35, -30, -23, -17, -17, -20, -20, -20, -17, -15, -13, -11, -8,
+ 1, 8, 12, 17, 23, 30, 39, 39, 37, 36, 35, 34, 27, 14, 0, -10,
+ -15, -23, -34, -46, -56, -60, -56, -49, -39, -32, -23, -8, 8, 23, 32, 38,
+ 44, 54, 58, 57, 48, 37, 29, 17, 4, -11, -21, -28, -29, -31, -34, -35,
+ -27, -20, -15, -16, -16, -17, -13, -10, -10, -11, -10, -4, 5, 11, 13, 15,
+ 21, 29, 33, 32, 28, 25, 25, 23, 16, 5, -6, -10, -16, -21, -30, -42,
+ -48, -48, -43, -34, -29, -21, -13, -3, 11, 22, 27, 34, 39, 48, 53, 48,
+ 42, 32, 23, 16, 4, -7, -18, -24, -24, -26, -28, -24, -19, -14, -13, -16,
+ -18, -18, -16, -14, -15, -16, -15, -7, 3, 11, 14, 21, 27, 33, 36, 33,
+ 30, 25, 22, 17, 9, -4, -15, -21, -24, -31, -39, -44, -44, -39, -30, -23,
+ -16, -8, 4, 14, 21, 23, 25, 29, 37, 43, 42, 36, 31, 25, 18, 11,
+ 4, -7, -11, -13, -16, -21, -22, -18, -14, -13, -16, -19, -21, -21, -19, -19,
+ -20, -18, -11, -2, 8, 14, 18, 23, 30, 34, 35, 31, 27, 21, 13, 2,
+ -11, -17, -23, -28, -36, -39, -40, -37, -31, -23, -14, -9, 0, 7, 13, 15,
+ 15, 16, 22, 27, 30, 28, 29, 32, 29, 23, 16, 9, 4, 1, -2, -7,
+ -14, -19, -14, -10, -10, -14, -18, -22, -24, -23, -26, -28, -27, -18, -8, -3,
+ 2, 9, 22, 33, 40, 40, 36, 30, 25, 20, 8, -8, -22, -29, -32, -39,
+ -48, -50, -42, -30, -19, -13, -8, 2, 11, 22, 25, 21, 17, 15, 20, 23,
+ 21, 20, 20, 19, 19, 16, 11, 9, 7, 7, 3, 0, -3, -5, -5, -5,
+ -7, -12, -22, -28, -32, -35, -35, -36, -30, -21, -12, -4, 3, 16, 29, 39,
+ 46, 45, 40, 34, 26, 13, -2, -17, -28, -37, -48, -57, -60, -52, -36, -19,
+ -12, -8, 2, 16, 28, 33, 28, 23, 21, 22, 21, 19, 18, 16, 14, 12,
+ 8, 6, 5, 5, 7, 5, 4, 5, 7, 9, 7, 3, -5, -13, -22, -28,
+ -35, -44, -49, -48, -38, -26, -14, -7, 4, 20, 38, 49, 54, 53, 49, 40,
+ 26, 8, -11, -24, -33, -46, -61, -70, -67, -52, -31, -14, -5, 4, 14, 27,
+ 36, 36, 33, 29, 26, 25, 21, 14, 10, 7, 8, 6, 5, 5, 6, 8,
+ 9, 10, 14, 18, 17, 13, 5, -4, -12, -20, -28, -37, -49, -56, -56, -48,
+ -36, -25, -15, -2, 16, 36, 51, 55, 57, 55, 48, 37, 20, 1, -17, -30,
+ -43, -60, -73, -76, -63, -43, -24, -14, -6, 7, 23, 39, 44, 38, 34, 31,
+ 32, 30, 24, 16, 8, 5, 6, 6, 5, 5, 6, 10, 10, 13, 16, 19,
+ 19, 14, 5, -7, -18, -25, -34, -45, -55, -61, -59, -51, -39, -25, -12, 5,
+ 27, 48, 58, 60, 61, 58, 49, 32, 14, -4, -20, -36, -54, -69, -79, -75,
+ -57, -35, -21, -15, -4, 12, 28, 39, 42, 41, 38, 38, 38, 33, 23, 13,
+ 8, 9, 11, 9, 5, 3, 6, 10, 13, 14, 15, 17, 16, 9, -6, -16,
+ -21, -27, -40, -56, -65, -67, -57, -45, -33, -23, -5, 21, 44, 60, 66, 67,
+ 65, 61, 47, 25, 2, -16, -34, -53, -72, -83, -82, -70, -51, -33, -20, -8,
+ 8, 25, 39, 46, 43, 43, 43, 43, 38, 27, 17, 9, 8, 10, 11, 9,
+ 5, 5, 8, 13, 14, 18, 20, 18, 12, -2, -13, -19, -25, -34, -48, -62,
+ -69, -67, -58, -46, -32, -14, 9, 30, 48, 60, 69, 72, 69, 57, 36, 13,
+ -6, -27, -47, -66, -79, -83, -77, -64, -46, -29, -13, 4, 17, 30, 39, 41,
+ 46, 48, 45, 40, 31, 20, 12, 10, 13, 14, 12, 11, 10, 10, 15, 17,
+ 20, 20, 17, 12, 0, -14, -24, -30, -37, -47, -60, -69, -68, -62, -51, -36,
+ -18, 5, 25, 45, 58, 65, 68, 67, 59, 42, 20, -2, -22, -42, -61, -75,
+ -81, -77, -66, -51, -35, -20, -4, 14, 28, 37, 38, 38, 42, 47, 43, 35,
+ 24, 17, 14, 14, 17, 20, 20, 17, 13, 14, 17, 18, 18, 17, 11, -2,
+ -15, -24, -31, -38, -46, -52, -58, -62, -61, -52, -38, -22, -4, 16, 35, 48,
+ 55, 60, 62, 57, 46, 26, 6, -17, -35, -53, -68, -76, -75, -66, -51, -38,
+ -23, -7, 10, 25, 35, 38, 37, 39, 40, 39, 30, 21, 16, 15, 15, 16,
+ 20, 24, 26, 27, 27, 26, 24, 21, 19, 11, -3, -16, -29, -40, -44, -50,
+ -54, -57, -58, -55, -48, -36, -21, -5, 13, 29, 41, 48, 52, 53, 50, 41,
+ 26, 7, -14, -33, -49, -62, -70, -69, -61, -48, -36, -21, -5, 16, 30, 35,
+ 35, 35, 32, 31, 29, 24, 17, 13, 13, 14, 15, 18, 26, 34, 39, 37,
+ 32, 29, 26, 22, 13, 1, -15, -29, -40, -46, -51, -54, -55, -52, -46, -40,
+ -32, -22, -10, 5, 19, 28, 33, 35, 37, 38, 33, 21, 8, -7, -20, -35,
+ -50, -57, -57, -49, -37, -28, -21, -8, 10, 25, 32, 32, 31, 27, 24, 22,
+ 20, 15, 13, 13, 15, 15, 19, 26, 36, 42, 43, 40, 33, 27, 22, 16,
+ 3, -13, -26, -37, -44, -50, -55, -54, -48, -42, -32, -24, -18, -10, -3, 8,
+ 20, 30, 31, 26, 22, 20, 15, 7, -7, -20, -32, -43, -52, -52, -46, -36,
+ -25, -16, -5, 9, 24, 38, 42, 39, 30, 23, 19, 15, 11, 8, 6, 6,
+ 6, 9, 18, 30, 42, 47, 45, 43, 38, 31, 22, 8, -9, -21, -33, -45,
+ -55, -59, -56, -47, -37, -29, -21, -13, -5, 2, 8, 13, 19, 22, 20, 15,
+ 9, 5, -3, -9, -20, -30, -39, -46, -45, -40, -31, -24, -16, -6, 7, 21,
+ 35, 39, 36, 31, 24, 22, 15, 10, 8, 5, 6, 3, 4, 12, 25, 40,
+ 48, 50, 48, 43, 37, 30, 17, -2, -18, -33, -45, -57, -64, -62, -53, -40,
+ -31, -23, -13, -3, 4, 11, 16, 19, 18, 17, 13, 7, -3, -10, -16, -22,
+ -31, -40, -45, -45, -41, -32, -24, -15, -5, 8, 24, 39, 47, 44, 38, 32,
+ 26, 20, 12, 3, -4, -4, -5, -4, 1, 11, 29, 41, 49, 51, 49, 45,
+ 38, 27, 9, -11, -27, -38, -52, -60, -64, -58, -45, -32, -21, -14, -5, 3,
+ 10, 13, 13, 14, 14, 12, 4, -6, -12, -17, -21, -25, -31, -35, -40, -39,
+ -33, -27, -19, -12, 1, 16, 29, 38, 42, 40, 36, 33, 30, 22, 11, 1,
+ -2, -2, -3, -2, 2, 16, 32, 44, 48, 46, 44, 39, 31, 19, 1, -21,
+ -36, -48, -58, -62, -59, -49, -38, -28, -20, -12, -2, 9, 16, 16, 15, 16,
+ 14, 9, 2, -7, -14, -19, -25, -31, -36, -38, -38, -36, -34, -28, -20, -7,
+ 8, 22, 33, 41, 46, 46, 42, 39, 33, 25, 14, 4, -4, -8, -8, -4,
+ 4, 16, 30, 38, 42, 46, 45, 38, 25, 10, -7, -24, -39, -51, -58, -59,
+ -53, -43, -34, -28, -21, -9, 5, 15, 17, 16, 15, 16, 15, 10, 2, -10,
+ -17, -21, -26, -33, -38, -40, -37, -34, -33, -28, -17, 0, 15, 29, 40, 48,
+ 50, 48, 44, 40, 34, 26, 15, 3, -6, -11, -11, -4, 7, 18, 24, 30,
+ 36, 38, 35, 31, 24, 13, -7, -25, -40, -50, -53, -51, -47, -41, -38, -33,
+ -25, -10, 4, 14, 19, 21, 22, 19, 19, 17, 7, -5, -15, -23, -31, -39,
+ -46, -49, -49, -46, -41, -33, -19, 0, 21, 39, 53, 61, 64, 63, 56, 50,
+ 42, 31, 15, -2, -13, -19, -19, -11, 0, 10, 15, 19, 27, 33, 37, 35,
+ 25, 9, -13, -28, -38, -44, -46, -50, -53, -51, -46, -38, -23, -7, 10, 20,
+ 21, 24, 25, 28, 28, 19, 8, -7, -18, -28, -36, -43, -52, -56, -57, -51,
+ -44, -31, -13, 7, 29, 46, 60, 66, 71, 68, 61, 54, 45, 32, 13, -5,
+ -17, -22, -20, -15, -8, -2, 8, 14, 24, 31, 35, 32, 21, 4, -13, -24,
+ -34, -42, -49, -55, -58, -54, -48, -38, -23, -4, 14, 26, 32, 31, 32, 36,
+ 34, 23, 7, -12, -25, -35, -47, -61, -68, -68, -61, -53, -42, -26, -7, 22,
+ 45, 61, 71, 75, 78, 74, 66, 56, 42, 24, 7, -13, -24, -29, -25, -18,
+ -11, -7, 2, 14, 27, 36, 38, 32, 19, 1, -14, -22, -33, -44, -56, -64,
+ -65, -60, -47, -32, -16, 3, 18, 31, 37, 37, 38, 41, 35, 20, 0, -18,
+ -31, -43, -56, -64, -69, -68, -60, -50, -36, -15, 6, 31, 50, 62, 71, 77,
+ 78, 74, 66, 54, 38, 20, 2, -15, -23, -26, -24, -22, -17, -7, 8, 20,
+ 29, 35, 33, 25, 13, -2, -14, -29, -42, -57, -67, -72, -67, -57, -42, -24,
+ -5, 13, 31, 43, 46, 47, 48, 43, 32, 14, -5, -22, -40, -55, -63, -68,
+ -69, -66, -57, -44, -25, -5, 18, 37, 55, 66, 75, 78, 75, 70, 62, 47,
+ 28, 9, -7, -19, -27, -30, -27, -21, -11, 5, 18, 28, 34, 36, 32, 24,
+ 12, -4, -20, -38, -55, -68, -75, -71, -65, -53, -35, -14, 6, 24, 39, 47,
+ 50, 48, 44, 36, 22, 5, -16, -34, -47, -56, -60, -60, -59, -54, -45, -28,
+ -9, 9, 25, 41, 53, 63, 67, 66, 65, 62, 54, 40, 22, 6, -8, -16,
+ -22, -23, -20, -11, 1, 13, 22, 27, 29, 26, 24, 15, 2, -15, -33, -49,
+ -64, -74, -74, -67, -55, -39, -20, -2, 16, 32, 45, 50, 49, 43, 35, 26,
+ 11, -9, -25, -35, -44, -49, -52, -54, -50, -39, -26, -12, 1, 14, 27, 39,
+ 48, 53, 55, 57, 56, 48, 36, 25, 15, 6, -5, -12, -17, -14, -8, 3,
+ 14, 21, 26, 23, 21, 21, 14, 3, -11, -26, -44, -61, -72, -72, -68, -56,
+ -42, -25, -11, 7, 24, 37, 44, 44, 40, 33, 25, 13, 0, -12, -24, -32,
+ -39, -41, -39, -36, -30, -24, -18, -10, 1, 11, 21, 29, 36, 41, 47, 51,
+ 51, 42, 35, 27, 19, 10, 1, -6, -10, -9, -2, 6, 11, 13, 13, 15,
+ 14, 10, 4, -9, -19, -31, -45, -58, -67, -68, -56, -43, -31, -20, -9, 7,
+ 21, 31, 35, 35, 33, 27, 18, 7, -3, -9, -13, -20, -27, -32, -33, -29,
+ -23, -19, -16, -12, -4, 6, 15, 23, 30, 39, 47, 49, 42, 35, 31, 27,
+ 22, 14, 2, -8, -9, -4, 5, 8, 8, 9, 7, 6, 3, 0, -5, -12,
+ -22, -35, -50, -58, -58, -50, -39, -32, -26, -19, -8, 7, 21, 26, 27, 25,
+ 22, 18, 11, 5, 2, 1, -3, -10, -19, -24, -23, -16, -15, -17, -20, -17,
+ -10, -2, 6, 12, 21, 32, 44, 45, 38, 30, 27, 31, 31, 21, 8, 1,
+ 0, 2, 8, 10, 7, 1, -3, -2, -4, -9, -12, -17, -25, -37, -47, -53,
+ -50, -42, -32, -27, -26, -22, -11, 5, 15, 18, 20, 22, 23, 22, 18, 15,
+ 14, 11, 7, -3, -14, -18, -17, -18, -22, -27, -27, -21, -14, -6, 3, 12,
+ 24, 34, 40, 39, 35, 32, 31, 34, 30, 19, 10, 4, 2, 5, 7, 7,
+ 1, -6, -10, -9, -8, -8, -11, -16, -25, -34, -41, -41, -36, -32, -33, -33,
+ -29, -22, -11, -2, 6, 13, 17, 22, 23, 22, 22, 24, 23, 20, 12, 0,
+ -7, -11, -14, -20, -26, -28, -26, -22, -15, -9, 2, 13, 25, 32, 33, 35,
+ 36, 37, 38, 35, 29, 19, 9, 5, 7, 6, 4, -3, -9, -12, -11, -6,
+ -4, -5, -10, -17, -26, -33, -37, -38, -38, -38, -41, -39, -31, -20, -9, -2,
+ 6, 15, 23, 31, 31, 31, 30, 29, 28, 21, 13, 2, -9, -17, -20, -23,
+ -26, -27, -26, -20, -14, -6, 6, 14, 22, 26, 32, 34, 35, 37, 37, 36,
+ 27, 15, 6, 6, 7, 5, -3, -13, -17, -17, -11, -5, -5, -6, -11, -18,
+ -24, -27, -30, -35, -40, -44, -44, -39, -28, -16, -6, 1, 9, 20, 31, 34,
+ 36, 37, 36, 33, 23, 14, 5, -3, -10, -17, -23, -30, -34, -31, -22, -14,
+ -8, 0, 7, 15, 20, 26, 30, 35, 40, 40, 34, 27, 18, 14, 9, 8,
+ 5, -2, -11, -15, -13, -8, -4, 0, 1, -6, -12, -18, -23, -29, -38, -45,
+ -52, -53, -47, -37, -28, -16, -5, 6, 17, 28, 37, 42, 43, 40, 37, 31,
+ 19, 8, 1, -7, -14, -22, -27, -33, -34, -28, -18, -8, 0, 5, 10, 14,
+ 19, 25, 33, 38, 39, 35, 27, 18, 13, 9, 8, 4, -3, -8, -12, -13,
+ -10, -4, 4, 4, -2, -7, -14, -21, -28, -36, -45, -53, -54, -50, -44, -34,
+ -20, -5, 7, 18, 28, 37, 39, 42, 40, 35, 28, 17, 7, 0, -7, -12,
+ -18, -23, -28, -28, -23, -17, -8, 2, 8, 9, 10, 12, 17, 25, 32, 33,
+ 28, 20, 13, 10, 10, 8, 6, 5, 1, -5, -6, -3, 3, 10, 10, 5,
+ -6, -15, -21, -28, -38, -49, -59, -62, -59, -51, -39, -25, -8, 7, 17, 28,
+ 37, 42, 44, 43, 38, 30, 17, 7, 0, -4, -10, -16, -24, -26, -27, -21,
+ -14, -9, -2, 5, 11, 14, 12, 13, 19, 26, 29, 26, 19, 13, 8, 8,
+ 9, 5, 2, 2, 4, 3, 1, 1, 5, 8, 7, 0, -10, -18, -25, -32,
+ -42, -52, -56, -53, -48, -38, -29, -14, 1, 14, 23, 30, 33, 33, 35, 33,
+ 26, 17, 9, 2, 1, 0, -5, -12, -19, -22, -21, -13, -8, -4, 5, 10,
+ 12, 10, 10, 14, 21, 25, 24, 15, 5, 3, 5, 7, 5, 2, 5, 10,
+ 12, 10, 9, 11, 13, 10, 2, -8, -18, -25, -32, -40, -50, -55, -53, -45,
+ -35, -27, -17, -4, 11, 20, 28, 30, 28, 29, 30, 28, 19, 10, 6, 6,
+ 5, 0, -10, -18, -20, -18, -14, -11, -10, -4, 6, 13, 13, 11, 13, 20,
+ 25, 24, 15, 7, 3, 4, 5, 4, 0, 3, 9, 14, 15, 11, 9, 8,
+ 8, 6, -5, -16, -24, -29, -35, -43, -48, -47, -42, -31, -23, -17, -7, 5,
+ 17, 24, 26, 22, 19, 19, 20, 17, 11, 5, 2, 2, 0, -4, -10, -14,
+ -14, -10, -8, -6, 1, 10, 19, 23, 22, 17, 16, 19, 18, 11, 1, -8,
+ -11, -10, -7, -4, 1, 7, 15, 22, 22, 18, 17, 16, 12, 4, -8, -21,
+ -29, -34, -39, -46, -49, -46, -37, -28, -19, -9, -2, 8, 19, 22, 20, 18,
+ 18, 19, 19, 12, 6, 3, 2, 0, -5, -10, -16, -18, -14, -9, -8, -3,
+ 6, 17, 25, 27, 26, 24, 25, 22, 15, 3, -8, -13, -13, -12, -11, -6,
+ 0, 9, 16, 19, 19, 16, 13, 10, 6, -5, -14, -22, -26, -32, -37, -41,
+ -39, -32, -23, -17, -14, -10, -3, 9, 17, 18, 10, 7, 10, 16, 18, 12,
+ 5, 1, 1, -4, -13, -18, -18, -15, -12, -11, -10, 1, 15, 29, 37, 35,
+ 31, 30, 30, 24, 11, -8, -18, -18, -15, -17, -20, -17, -6, 8, 15, 18,
+ 16, 15, 11, 12, 8, 0, -10, -16, -20, -28, -35, -38, -33, -27, -23, -21,
+ -19, -13, 0, 11, 14, 12, 9, 11, 18, 21, 19, 10, 2, -3, -5, -12,
+ -21, -28, -26, -20, -15, -12, -6, 9, 25, 38, 43, 42, 40, 38, 34, 23,
+ 6, -12, -18, -18, -18, -23, -25, -22, -13, 0, 7, 9, 8, 8, 11, 12,
+ 9, 6, 2, -5, -14, -21, -24, -24, -22, -22, -21, -22, -20, -12, -3, 4,
+ 5, 5, 6, 11, 15, 16, 10, 4, -2, -7, -11, -20, -25, -27, -21, -13,
+ -11, -5, 6, 22, 37, 46, 50, 49, 44, 39, 31, 16, -3, -15, -21, -24,
+ -27, -32, -33, -28, -17, -5, 5, 7, 7, 10, 15, 16, 15, 10, 4, -4,
+ -11, -18, -22, -22, -20, -22, -21, -21, -17, -10, 1, 6, 9, 10, 15, 19,
+ 18, 12, 5, 0, -9, -15, -23, -31, -36, -32, -24, -17, -11, -4, 12, 31,
+ 47, 53, 58, 60, 56, 49, 35, 15, -4, -16, -21, -25, -32, -42, -45, -35,
+ -23, -14, -8, 0, 6, 13, 20, 21, 19, 15, 9, 1, -6, -11, -13, -16,
+ -18, -20, -23, -20, -14, -8, 0, 2, 5, 11, 18, 18, 14, 6, -2, -10,
+ -18, -27, -34, -41, -40, -31, -20, -12, -7, 4, 23, 47, 64, 71, 71, 63,
+ 56, 46, 30, 12, -7, -22, -35, -42, -49, -52, -48, -34, -22, -14, -7, 3,
+ 15, 24, 27, 27, 24, 15, 6, -4, -8, -11, -13, -13, -15, -16, -14, -12,
+ -7, -2, 3, 10, 12, 14, 15, 7, 0, -7, -16, -25, -32, -40, -44, -44,
+ -36, -24, -11, 0, 6, 16, 36, 58, 72, 76, 71, 62, 51, 38, 24, 5,
+ -13, -30, -42, -50, -52, -53, -46, -33, -21, -15, -6, 7, 20, 25, 25, 21,
+ 18, 14, 7, 2, -5, -9, -9, -7, -8, -9, -10, -7, -3, 1, 6, 7,
+ 8, 9, 6, -2, -13, -23, -30, -35, -41, -45, -44, -38, -26, -15, -3, 11,
+ 19, 33, 52, 69, 75, 72, 65, 54, 42, 29, 13, -6, -25, -41, -49, -54,
+ -55, -48, -38, -26, -18, -8, 1, 13, 24, 29, 26, 19, 11, 5, 2, -2,
+ -6, -6, -6, -5, -7, -5, 1, 5, 9, 11, 8, 8, 7, 4, -6, -17,
+ -28, -35, -42, -47, -48, -45, -39, -29, -16, -5, 7, 18, 32, 45, 57, 64,
+ 67, 62, 54, 45, 35, 22, 5, -13, -28, -40, -47, -49, -46, -42, -32, -21,
+ -11, -4, 6, 15, 21, 21, 16, 12, 6, 1, -3, -5, -3, 3, 8, 9,
+ 8, 7, 7, 11, 12, 11, 6, -2, -9, -13, -20, -29, -40, -47, -47, -45,
+ -42, -37, -29, -16, -5, 7, 17, 27, 38, 48, 56, 59, 53, 44, 40, 37,
+ 30, 17, -2, -16, -25, -32, -35, -36, -35, -31, -23, -16, -10, -3, 4, 10,
+ 11, 8, 1, 0, 0, 0, 0, 1, 6, 14, 20, 21, 19, 15, 14, 13,
+ 11, 7, 0, -13, -21, -28, -37, -46, -51, -48, -43, -37, -32, -28, -21, -9,
+ 4, 17, 27, 32, 40, 45, 50, 51, 46, 40, 38, 35, 27, 12, -3, -13,
+ -23, -27, -29, -30, -29, -28, -23, -15, -10, -5, 2, 5, 5, 1, -2, -2,
+ 1, 4, 4, 8, 14, 19, 25, 26, 21, 15, 13, 12, 12, 5, -9, -21,
+ -30, -37, -43, -50, -51, -47, -42, -38, -34, -27, -17, -5, 10, 22, 30, 38,
+ 44, 49, 50, 46, 40, 37, 38, 33, 19, 4, -8, -14, -18, -22, -24, -24,
+ -22, -18, -16, -14, -10, -6, 1, 1, -6, -8, -9, -6, 0, 2, 8, 14,
+ 21, 28, 31, 27, 24, 21, 20, 16, 9, -3, -16, -26, -33, -42, -50, -55,
+ -56, -50, -43, -39, -38, -29, -13, 6, 18, 27, 33, 42, 51, 54, 53, 48,
+ 41, 39, 38, 29, 12, -5, -15, -19, -20, -23, -24, -22, -18, -17, -13, -12,
+ -10, -4, -3, -4, -7, -8, -9, -9, -7, 2, 9, 14, 21, 26, 27, 27,
+ 22, 20, 19, 17, 12, 1, -14, -25, -35, -41, -45, -50, -53, -54, -51, -47,
+ -41, -31, -18, -3, 12, 24, 35, 47, 55, 58, 57, 55, 49, 46, 40, 26,
+ 11, -5, -17, -22, -23, -23, -22, -21, -21, -18, -15, -9, -5, -3, -4, -6,
+ -7, -9, -12, -12, -8, 1, 7, 13, 14, 19, 23, 27, 26, 25, 25, 20,
+ 13, 4, -9, -22, -36, -42, -48, -55, -61, -62, -59, -54, -43, -32, -18, 0,
+ 18, 35, 49, 57, 60, 62, 63, 61, 57, 48, 33, 15, -2, -15, -24, -28,
+ -27, -22, -23, -24, -21, -13, -4, 3, 3, 1, -2, -4, -4, -9, -15, -16,
+ -13, -9, -5, 2, 7, 11, 19, 24, 28, 31, 29, 28, 24, 12, -4, -21,
+ -33, -38, -48, -61, -72, -76, -71, -61, -47, -34, -20, 2, 26, 45, 58, 65,
+ 69, 74, 75, 68, 55, 41, 28, 13, -7, -22, -32, -32, -29, -24, -23, -22,
+ -19, -7, 6, 7, 2, -2, -3, 0, -3, -10, -20, -24, -19, -12, -5, 1,
+ 5, 14, 23, 30, 33, 37, 39, 36, 24, 8, -10, -25, -33, -43, -55, -71,
+ -82, -82, -71, -57, -44, -29, -11, 13, 34, 52, 64, 70, 73, 77, 76, 65,
+ 50, 35, 20, 4, -13, -26, -31, -32, -27, -26, -25, -21, -10, 2, 8, 5,
+ 3, 0, 1, 2, -3, -12, -22, -24, -21, -16, -9, -3, 6, 14, 22, 28,
+ 34, 41, 42, 35, 23, 6, -10, -21, -32, -45, -61, -76, -85, -82, -70, -54,
+ -43, -29, -7, 18, 40, 55, 64, 71, 77, 81, 76, 62, 48, 32, 19, 6,
+ -10, -23, -30, -29, -28, -30, -27, -20, -10, -2, 3, 1, 0, 3, 6, 4,
+ -9, -18, -24, -22, -18, -14, -8, 0, 8, 16, 24, 32, 38, 42, 42, 31,
+ 15, -2, -14, -25, -38, -52, -67, -81, -85, -76, -63, -49, -37, -19, 3, 26,
+ 43, 57, 67, 75, 82, 79, 70, 56, 41, 28, 15, 1, -12, -22, -27, -27,
+ -28, -26, -21, -12, -3, 3, -2, -2, 1, 3, 1, -12, -22, -28, -29, -27,
+ -23, -18, -11, 3, 16, 25, 34, 44, 51, 52, 43, 27, 12, -2, -17, -34,
+ -51, -71, -82, -86, -83, -75, -61, -45, -27, -7, 16, 37, 53, 63, 72, 78,
+ 77, 68, 60, 45, 33, 20, 10, -2, -9, -15, -18, -22, -23, -19, -15, -8,
+ -5, -7, -8, -7, -4, -3, -10, -22, -29, -29, -24, -21, -18, -14, -3, 12,
+ 23, 27, 35, 44, 49, 47, 34, 18, 1, -11, -23, -40, -57, -73, -81, -80,
+ -74, -64, -50, -36, -19, 2, 22, 38, 49, 61, 69, 74, 69, 60, 50, 40,
+ 29, 20, 10, 2, -5, -9, -12, -16, -18, -14, -9, -6, -10, -13, -12, -10,
+ -11, -15, -23, -30, -31, -27, -25, -23, -19, -8, 8, 20, 28, 36, 45, 49,
+ 49, 41, 29, 15, -2, -15, -31, -49, -65, -76, -79, -77, -67, -55, -43, -30,
+ -13, 7, 25, 40, 51, 60, 66, 66, 62, 54, 45, 37, 29, 22, 14, 7,
+ 3, -3, -7, -10, -12, -10, -8, -12, -18, -19, -16, -13, -15, -23, -31, -33,
+ -29, -26, -25, -23, -15, 1, 14, 23, 31, 40, 50, 52, 46, 36, 21, 7,
+ -8, -24, -41, -58, -70, -75, -74, -67, -57, -43, -30, -18, -3, 13, 26, 39,
+ 48, 56, 60, 58, 51, 45, 42, 36, 29, 25, 20, 14, 9, 6, 3, 0,
+ -5, -6, -12, -17, -22, -21, -20, -24, -33, -37, -38, -35, -30, -28, -24, -17,
+ -3, 12, 24, 33, 43, 50, 52, 49, 40, 28, 13, -3, -18, -34, -51, -63,
+ -71, -72, -67, -59, -49, -37, -24, -10, 3, 16, 27, 37, 46, 50, 53, 51,
+ 49, 46, 43, 37, 32, 29, 25, 21, 17, 10, 4, -3, -8, -10, -11, -18,
+ -25, -29, -31, -34, -37, -40, -40, -37, -31, -25, -20, -13, 0, 17, 31, 41,
+ 48, 50, 49, 46, 36, 22, 8, -5, -20, -36, -49, -61, -67, -67, -61, -51,
+ -44, -36, -23, -9, 4, 13, 20, 30, 38, 46, 48, 47, 44, 44, 44, 46,
+ 42, 35, 31, 28, 24, 15, 5, -3, -6, -10, -18, -28, -35, -39, -41, -41,
+ -43, -45, -42, -36, -29, -23, -15, 1, 15, 28, 40, 47, 51, 51, 46, 37,
+ 27, 14, 2, -14, -29, -42, -49, -54, -62, -63, -57, -49, -41, -31, -21, -12,
+ -3, 6, 17, 25, 32, 40, 45, 49, 50, 48, 49, 49, 48, 44, 39, 34,
+ 26, 13, 4, -4, -11, -17, -23, -32, -41, -48, -48, -49, -48, -44, -39, -36,
+ -31, -21, -5, 13, 24, 35, 44, 51, 52, 47, 39, 30, 21, 8, -6, -18,
+ -34, -44, -50, -54, -59, -58, -53, -46, -38, -28, -18, -10, -4, 6, 16, 24,
+ 30, 37, 42, 48, 49, 47, 48, 51, 51, 49, 45, 35, 27, 17, 9, 0,
+ -12, -23, -32, -41, -48, -53, -55, -54, -53, -49, -43, -38, -27, -13, 5, 20,
+ 33, 44, 52, 58, 57, 50, 40, 29, 16, 5, -11, -29, -43, -53, -56, -62,
+ -65, -63, -54, -42, -33, -24, -16, -8, 3, 16, 23, 29, 33, 38, 44, 46,
+ 45, 43, 45, 49, 52, 48, 42, 37, 28, 19, 10, 0, -13, -25, -36, -42,
+ -47, -56, -58, -56, -53, -49, -48, -40, -26, -6, 13, 27, 39, 49, 59, 64,
+ 62, 53, 42, 29, 16, 2, -18, -37, -52, -60, -65, -71, -75, -68, -55, -41,
+ -30, -19, -10, 0, 14, 24, 33, 37, 38, 39, 42, 45, 45, 43, 45, 48,
+ 47, 46, 41, 35, 28, 19, 8, -6, -20, -30, -38, -44, -50, -55, -57, -59,
+ -57, -53, -46, -35, -19, 0, 17, 32, 45, 59, 66, 66, 59, 54, 46, 32,
+ 15, -5, -24, -43, -57, -65, -71, -76, -78, -71, -58, -41, -27, -16, -5, 5,
+ 15, 27, 37, 43, 43, 42, 42, 42, 43, 46, 46, 46, 45, 42, 41, 35,
+ 28, 18, 7, -6, -18, -29, -37, -44, -51, -56, -59, -61, -60, -55, -45, -33,
+ -18, -2, 18, 37, 50, 61, 67, 68, 65, 59, 47, 31, 10, -11, -32, -47,
+ -58, -71, -81, -86, -83, -70, -52, -36, -21, -9, 2, 13, 25, 35, 41, 44,
+ 43, 40, 39, 39, 40, 43, 43, 40, 39, 40, 40, 36, 28, 18, 9, -5,
+ -18, -28, -36, -44, -52, -57, -61, -64, -63, -56, -43, -27, -13, 6, 26, 44,
+ 56, 66, 71, 71, 64, 55, 42, 23, 3, -19, -38, -52, -66, -76, -82, -86,
+ -81, -67, -49, -32, -19, -8, 3, 15, 28, 36, 42, 43, 43, 41, 41, 40,
+ 40, 41, 40, 40, 41, 41, 36, 30, 24, 17, 10, -5, -19, -29, -37, -43,
+ -50, -57, -64, -66, -60, -50, -40, -28, -10, 12, 32, 45, 54, 59, 64, 67,
+ 63, 54, 35, 14, -6, -22, -35, -50, -64, -75, -82, -81, -73, -59, -46, -33,
+ -21, -8, 5, 19, 27, 33, 40, 44, 44, 42, 40, 42, 41, 40, 38, 39,
+ 38, 38, 35, 30, 21, 13, 4, -8, -16, -25, -35, -45, -53, -62, -65, -63,
+ -56, -47, -39, -25, -6, 15, 32, 45, 53, 58, 64, 65, 60, 48, 30, 9,
+ -7, -19, -31, -47, -60, -72, -79, -79, -73, -61, -50, -37, -24, -10, 3, 12,
+ 22, 33, 43, 47, 46, 44, 43, 45, 46, 45, 45, 43, 41, 38, 34, 26,
+ 16, 7, -2, -10, -19, -29, -39, -50, -59, -64, -62, -58, -51, -44, -34, -22,
+ -2, 16, 30, 41, 52, 56, 57, 58, 54, 42, 29, 13, 2, -12, -27, -42,
+ -56, -67, -71, -73, -70, -63, -55, -42, -26, -10, 2, 11, 20, 33, 41, 46,
+ 45, 43, 49, 53, 52, 48, 44, 43, 42, 38, 33, 22, 12, 4, -5, -13,
+ -23, -34, -43, -50, -57, -61, -60, -55, -49, -40, -29, -14, -2, 12, 25, 35,
+ 44, 51, 56, 56, 49, 39, 30, 20, 10, -2, -17, -32, -48, -60, -67, -74,
+ -77, -74, -66, -50, -36, -21, -9, 0, 14, 30, 43, 51, 53, 57, 62, 64,
+ 62, 58, 53, 48, 42, 36, 25, 12, 4, -4, -12, -21, -31, -38, -43, -45,
+ -47, -49, -47, -44, -40, -34, -28, -22, -11, 1, 11, 21, 28, 39, 49, 53,
+ 52, 49, 44, 38, 29, 16, -4, -24, -41, -57, -74, -86, -90, -86, -73, -59,
+ -44, -30, -16, 1, 21, 40, 54, 61, 66, 67, 71, 72, 65, 57, 49, 41,
+ 33, 24, 12, 1, -8, -12, -15, -22, -31, -37, -35, -31, -33, -36, -39, -40,
+ -38, -34, -32, -29, -24, -14, -2, 11, 24, 36, 48, 56, 61, 63, 59, 54,
+ 44, 27, 6, -19, -46, -68, -84, -94, -99, -98, -90, -72, -51, -30, -15, 1,
+ 22, 46, 64, 76, 78, 80, 81, 78, 72, 60, 45, 34, 24, 13, 0, -13,
+ -18, -18, -18, -22, -28, -29, -24, -19, -19, -26, -33, -38, -40, -40, -41, -42,
+ -41, -32, -15, 6, 22, 37, 50, 62, 74, 79, 76, 65, 50, 30, 6, -24,
+ -54, -78, -94, -106, -110, -103, -89, -69, -49, -29, -10, 11, 36, 57, 73, 78,
+ 80, 82, 83, 77, 66, 51, 37, 24, 14, 5, -5, -12, -17, -17, -17, -18,
+ -19, -17, -13, -13, -19, -28, -37, -44, -44, -48, -53, -59, -54, -35, -12, 11,
+ 29, 46, 61, 78, 88, 90, 84, 68, 49, 24, -6, -39, -71, -92, -104, -115,
+ -116, -108, -89, -66, -43, -21, 1, 24, 49, 68, 78, 82, 81, 81, 79, 71,
+ 56, 37, 24, 15, 6, -4, -9, -11, -9, -6, -6, -10, -11, -6, -4, -8,
+ -20, -33, -44, -55, -61, -65, -70, -68, -55, -31, -6, 15, 38, 61, 82, 97,
+ 101, 94, 80, 61, 37, 9, -25, -60, -88, -107, -119, -123, -116, -99, -77, -53,
+ -30, -5, 20, 47, 68, 80, 82, 82, 80, 77, 70, 57, 40, 23, 10, 3,
+ -2, -3, -4, -3, 2, 5, 7, 5, 5, 4, -4, -17, -32, -45, -60, -69,
+ -74, -79, -80, -70, -47, -20, 9, 32, 55, 76, 94, 104, 103, 91, 71, 46,
+ 16, -16, -48, -75, -97, -115, -121, -117, -101, -80, -57, -32, -8, 15, 39, 58,
+ 68, 73, 73, 73, 69, 61, 50, 39, 26, 15, 7, 4, 7, 12, 18, 19,
+ 20, 18, 17, 15, 10, -4, -20, -41, -57, -68, -77, -85, -91, -90, -76, -53,
+ -25, 2, 28, 55, 79, 97, 106, 104, 94, 77, 52, 22, -9, -39, -67, -92,
+ -111, -119, -115, -99, -79, -55, -33, -11, 15, 37, 55, 67, 71, 68, 61, 51,
+ 44, 40, 35, 24, 10, 3, 4, 13, 25, 36, 42, 41, 34, 29, 20, 12,
+ -2, -21, -43, -66, -84, -94, -96, -96, -93, -81, -55, -26, 4, 30, 56, 80,
+ 98, 107, 106, 95, 77, 53, 24, -8, -38, -64, -85, -101, -109, -109, -100, -80,
+ -55, -31, -8, 13, 31, 46, 56, 61, 59, 52, 43, 36, 30, 25, 16, 8,
+ 7, 11, 23, 37, 48, 56, 59, 56, 48, 33, 17, -5, -29, -54, -79, -96,
+ -106, -109, -105, -96, -82, -57, -25, 8, 38, 61, 79, 94, 103, 102, 92, 73,
+ 46, 19, -10, -36, -62, -81, -95, -101, -100, -90, -71, -47, -25, -3, 18, 31,
+ 41, 49, 53, 50, 42, 32, 21, 13, 9, 7, 8, 8, 12, 30, 49, 63,
+ 71, 76, 75, 67, 48, 25, -3, -30, -59, -87, -107, -120, -124, -117, -105, -89,
+ -63, -31, 5, 40, 63, 81, 92, 100, 100, 88, 69, 46, 20, -6, -31, -55,
+ -73, -87, -91, -88, -80, -64, -45, -22, 1, 16, 27, 34, 39, 45, 41, 31,
+ 20, 9, 4, 3, 1, 3, 6, 15, 32, 53, 71, 81, 85, 86, 78, 61,
+ 35, 3, -29, -63, -93, -113, -124, -128, -124, -110, -89, -64, -32, 5, 38, 62,
+ 80, 91, 98, 93, 80, 63, 42, 19, -5, -29, -51, -68, -78, -81, -79, -72,
+ -58, -40, -19, 0, 13, 21, 29, 35, 35, 29, 21, 14, 8, 2, -2, -3,
+ 1, 10, 20, 36, 56, 73, 84, 89, 89, 81, 65, 41, 6, -32, -63, -90,
+ -110, -124, -127, -123, -110, -89, -61, -30, 2, 33, 56, 71, 81, 86, 85, 74,
+ 58, 38, 17, -5, -21, -38, -52, -62, -69, -69, -64, -50, -34, -18, -5, 5,
+ 13, 23, 28, 27, 22, 15, 10, 6, 1, 0, -2, 2, 9, 23, 41, 56,
+ 72, 84, 88, 89, 81, 66, 45, 15, -20, -55, -84, -106, -119, -121, -116, -105,
+ -89, -67, -38, -7, 21, 44, 58, 69, 75, 74, 64, 50, 36, 22, 8, -10,
+ -26, -39, -47, -54, -56, -53, -47, -36, -25, -11, -2, 5, 14, 23, 24, 20,
+ 12, 7, 6, 6, 6, 4, 5, 10, 22, 39, 57, 72, 80, 82, 80, 73,
+ 62, 45, 18, -13, -48, -78, -96, -105, -105, -104, -97, -81, -64, -40, -15, 10,
+ 28, 40, 49, 54, 53, 49, 42, 31, 22, 13, 2, -9, -17, -22, -30, -38,
+ -40, -37, -33, -28, -22, -16, -10, -5, 5, 11, 11, 6, 3, 5, 11, 16,
+ 16, 18, 22, 29, 40, 54, 68, 75, 74, 72, 63, 49, 35, 15, -10, -37,
+ -63, -83, -94, -95, -89, -82, -73, -63, -46, -24, -2, 16, 25, 31, 35, 39,
+ 41, 37, 30, 22, 15, 11, 4, -3, -11, -18, -25, -31, -35, -33, -28, -22,
+ -18, -16, -13, -4, 5, 10, 11, 10, 5, 6, 14, 21, 23, 24, 27, 33,
+ 45, 59, 68, 72, 67, 57, 46, 34, 19, 0, -24, -49, -70, -81, -82, -77,
+ -70, -65, -60, -49, -34, -15, 2, 9, 13, 14, 18, 20, 21, 19, 18, 17,
+ 16, 15, 13, 10, 5, -3, -12, -20, -26, -28, -27, -24, -26, -25, -18, -9,
+ 3, 9, 10, 10, 11, 18, 27, 32, 33, 33, 35, 42, 51, 58, 59, 55,
+ 46, 36, 25, 16, 3, -15, -33, -50, -61, -65, -64, -59, -57, -56, -52, -42,
+ -29, -14, -5, -2, -3, 1, 8, 12, 13, 13, 16, 16, 18, 19, 19, 14,
+ 4, -3, -10, -19, -24, -24, -22, -20, -24, -23, -16, -2, 10, 16, 14, 13,
+ 16, 28, 35, 36, 35, 32, 33, 40, 45, 49, 47, 41, 31, 20, 12, 4,
+ -8, -16, -29, -41, -50, -53, -50, -49, -51, -51, -48, -40, -30, -20, -13, -13,
+ -12, -6, 2, 8, 12, 13, 16, 21, 26, 27, 23, 15, 8, 0, -10, -19,
+ -23, -24, -24, -26, -25, -21, -9, 5, 15, 19, 20, 22, 28, 36, 39, 38,
+ 36, 33, 33, 35, 37, 38, 36, 30, 20, 9, 4, -3, -10, -17, -26, -35,
+ -40, -45, -47, -51, -52, -49, -46, -39, -30, -23, -19, -17, -12, -5, 1, 4,
+ 7, 11, 18, 22, 22, 22, 20, 17, 12, 3, -8, -16, -18, -16, -17, -19,
+ -18, -12, 3, 13, 19, 20, 24, 29, 34, 35, 33, 32, 31, 31, 30, 26,
+ 24, 24, 25, 21, 14, 6, 0, -4, -5, -10, -19, -31, -37, -40, -47, -51,
+ -50, -49, -45, -39, -31, -25, -19, -12, -6, -3, 0, 2, 6, 13, 17, 18,
+ 16, 15, 16, 14, 7, -3, -10, -12, -13, -13, -14, -13, -6, 6, 18, 24,
+ 25, 26, 29, 33, 32, 26, 24, 23, 23, 22, 18, 14, 15, 21, 24, 22,
+ 14, 6, 4, 4, 1, -9, -21, -32, -41, -47, -50, -54, -54, -51, -47, -37,
+ -30, -21, -10, -3, 1, 4, 6, 7, 8, 7, 7, 7, 7, 6, 6, 5,
+ 2, -3, -8, -8, -6, -3, 1, 3, 9, 17, 25, 29, 32, 33, 29, 26,
+ 24, 23, 20, 17, 14, 11, 8, 8, 14, 21, 22, 17, 13, 9, 9, 7,
+ 1, -11, -25, -37, -44, -52, -53, -55, -55, -51, -43, -35, -24, -14, -4, 3,
+ 4, 4, 6, 7, 6, 3, -2, -2, 2, 6, 5, 1, -4, -8, -7, -5,
+ 3, 9, 9, 12, 17, 25, 32, 37, 37, 32, 25, 21, 19, 17, 15, 9,
+ 6, 6, 6, 8, 14, 23, 24, 20, 15, 14, 11, 3, -6, -18, -31, -44,
+ -53, -54, -57, -58, -55, -47, -37, -26, -16, -4, 7, 10, 10, 9, 7, 3,
+ -2, -6, -8, -6, -5, -4, -7, -10, -8, -6, 0, 6, 12, 16, 20, 27,
+ 33, 35, 35, 36, 34, 28, 21, 16, 10, 7, 7, 5, 3, 1, 5, 12,
+ 21, 25, 23, 17, 14, 13, 9, -3, -17, -30, -41, -50, -54, -59, -61, -55,
+ -46, -37, -26, -15, -4, 7, 14, 15, 12, 6, 1, -3, -7, -12, -14, -15,
+ -13, -12, -12, -12, -8, 0, 8, 15, 20, 25, 31, 36, 40, 41, 41, 38,
+ 33, 27, 21, 12, 4, 1, 0, -4, -5, -2, 5, 12, 17, 19, 19, 18,
+ 14, 11, 2, -9, -21, -32, -42, -49, -55, -57, -56, -49, -39, -30, -20, -8,
+ 3, 12, 17, 18, 12, 5, -2, -8, -14, -18, -21, -22, -21, -21, -19, -13,
+ -7, 4, 14, 24, 32, 39, 44, 48, 47, 44, 41, 38, 33, 27, 17, 7,
+ -3, -5, -5, -5, -5, -5, 3, 12, 17, 19, 16, 11, 7, 3, -6, -15,
+ -26, -36, -42, -48, -53, -54, -50, -40, -31, -22, -12, -2, 11, 19, 20, 13,
+ 6, 2, -5, -12, -21, -26, -29, -31, -30, -27, -21, -13, -2, 12, 25, 36,
+ 48, 57, 62, 60, 51, 46, 43, 37, 28, 15, 3, -8, -12, -14, -12, -10,
+ -7, -4, 8, 16, 20, 17, 14, 10, 6, -2, -12, -24, -32, -39, -45, -51,
+ -54, -52, -43, -32, -21, -12, -2, 11, 22, 28, 24, 13, 4, -6, -14, -23,
+ -32, -38, -41, -42, -39, -31, -20, -8, 6, 21, 37, 50, 63, 69, 68, 61,
+ 55, 48, 39, 29, 20, 9, -6, -15, -17, -13, -11, -7, -4, 3, 11, 13,
+ 16, 15, 10, 5, 0, -8, -15, -25, -31, -37, -42, -49, -52, -46, -37, -30,
+ -21, -12, 0, 14, 25, 28, 25, 15, 2, -11, -22, -29, -36, -44, -49, -49,
+ -43, -32, -18, -5, 13, 30, 50, 66, 74, 75, 71, 68, 61, 50, 37, 26,
+ 15, 3, -13, -22, -22, -20, -16, -14, -9, 1, 9, 11, 11, 9, 9, 9,
+ 6, -3, -15, -25, -32, -37, -41, -50, -53, -50, -41, -30, -20, -8, 6, 21,
+ 31, 33, 26, 15, 0, -12, -23, -34, -46, -56, -60, -54, -44, -31, -19, -2,
+ 21, 44, 66, 77, 81, 79, 75, 72, 63, 51, 35, 23, 10, -4, -16, -25,
+ -28, -26, -22, -16, -12, -7, -2, 4, 8, 10, 14, 14, 7, -3, -12, -20,
+ -28, -36, -42, -48, -53, -53, -43, -31, -19, -6, 12, 25, 31, 30, 26, 15,
+ -2, -17, -28, -40, -52, -60, -61, -53, -40, -25, -9, 11, 32, 56, 74, 84,
+ 85, 81, 76, 72, 61, 46, 29, 13, -2, -16, -23, -29, -33, -31, -25, -19,
+ -14, -8, 2, 10, 14, 18, 19, 17, 8, 1, -12, -24, -35, -42, -49, -54,
+ -57, -53, -43, -30, -13, 7, 22, 32, 34, 32, 26, 11, -8, -24, -40, -50,
+ -60, -66, -63, -53, -36, -17, 2, 23, 45, 67, 84, 90, 91, 85, 78, 72,
+ 62, 44, 24, 4, -9, -21, -32, -39, -41, -36, -30, -23, -17, -9, 2, 13,
+ 23, 27, 26, 19, 12, 2, -12, -26, -38, -47, -54, -59, -59, -53, -41, -23,
+ -5, 14, 28, 36, 36, 31, 21, 6, -13, -31, -46, -58, -66, -70, -65, -50,
+ -28, -7, 14, 35, 58, 76, 89, 96, 94, 90, 82, 72, 54, 35, 16, -5,
+ -21, -31, -40, -48, -47, -38, -28, -20, -13, 1, 15, 28, 33, 33, 27, 18,
+ 8, -6, -21, -37, -52, -64, -66, -65, -58, -47, -30, -9, 13, 28, 38, 43,
+ 40, 31, 15, -5, -24, -40, -57, -69, -75, -74, -65, -48, -26, -2, 24, 47,
+ 66, 83, 97, 102, 102, 101, 91, 73, 51, 28, 7, -15, -33, -45, -56, -60,
+ -54, -42, -28, -17, -4, 13, 26, 36, 38, 36, 29, 16, 2, -14, -34, -52,
+ -62, -66, -65, -63, -53, -36, -15, 9, 27, 36, 41, 40, 35, 25, 8, -16,
+ -37, -55, -68, -77, -81, -75, -60, -37, -12, 12, 35, 57, 75, 94, 105, 107,
+ 103, 97, 84, 64, 41, 18, -6, -25, -40, -51, -57, -56, -46, -32, -19, -6,
+ 7, 20, 30, 34, 32, 24, 12, 0, -17, -33, -47, -60, -65, -64, -58, -46,
+ -31, -12, 8, 26, 37, 43, 44, 41, 28, 11, -12, -31, -49, -67, -81, -87,
+ -85, -72, -52, -30, -6, 21, 45, 69, 87, 101, 110, 113, 110, 100, 77, 51,
+ 27, 8, -11, -32, -49, -59, -59, -53, -41, -27, -11, 3, 14, 24, 28, 28,
+ 24, 17, 5, -15, -32, -45, -54, -61, -58, -54, -44, -32, -13, 8, 26, 37,
+ 41, 40, 36, 29, 16, -3, -24, -47, -66, -81, -89, -88, -76, -58, -37, -16,
+ 10, 34, 58, 78, 94, 106, 111, 107, 97, 81, 58, 37, 17, 0, -17, -33,
+ -45, -51, -48, -38, -26, -14, -3, 9, 16, 19, 17, 14, 10, 0, -15, -30,
+ -42, -49, -52, -49, -44, -37, -25, -8, 9, 21, 29, 32, 35, 33, 29, 19,
+ 1, -18, -38, -58, -75, -85, -85, -79, -70, -52, -29, -6, 20, 44, 67, 89,
+ 101, 110, 114, 107, 93, 72, 49, 28, 10, -9, -25, -38, -48, -49, -42, -31,
+ -20, -11, 0, 9, 13, 12, 7, 5, 0, -11, -24, -36, -42, -44, -43, -38,
+ -28, -16, -4, 8, 16, 22, 29, 30, 29, 24, 13, 2, -14, -32, -51, -68,
+ -79, -83, -77, -69, -56, -41, -19, 6, 31, 53, 74, 90, 101, 108, 109, 101,
+ 83, 60, 38, 24, 9, -10, -25, -36, -40, -37, -29, -21, -13, -8, 0, 3,
+ 0, -5, -6, -8, -16, -27, -35, -39, -40, -33, -27, -21, -11, 3, 14, 21,
+ 24, 27, 26, 22, 19, 13, 3, -14, -32, -53, -66, -74, -80, -80, -75, -63,
+ -47, -28, -4, 19, 41, 66, 85, 99, 105, 106, 104, 95, 76, 51, 29, 13,
+ 2, -12, -27, -36, -38, -32, -22, -15, -12, -8, -3, -4, -9, -12, -14, -18,
+ -26, -31, -35, -36, -29, -20, -10, -2, 7, 16, 25, 25, 24, 19, 15, 10,
+ 4, -4, -16, -30, -44, -57, -67, -73, -75, -70, -60, -48, -34, -16, 5, 27,
+ 51, 71, 85, 92, 99, 101, 95, 82, 64, 44, 28, 14, 1, -12, -22, -28,
+ -27, -22, -18, -17, -15, -15, -15, -21, -23, -25, -24, -27, -31, -34, -30, -21,
+ -6, 7, 13, 17, 22, 27, 28, 24, 16, 7, -3, -10, -17, -27, -35, -43,
+ -50, -58, -68, -70, -65, -53, -42, -32, -22, -4, 15, 36, 54, 70, 83, 89,
+ 92, 91, 82, 68, 54, 42, 29, 14, 2, -9, -17, -21, -22, -20, -21, -20,
+ -23, -26, -30, -32, -32, -29, -27, -28, -30, -26, -15, 0, 15, 25, 25, 25,
+ 26, 27, 21, 11, 0, -9, -17, -24, -30, -38, -45, -47, -49, -55, -59, -56,
+ -48, -39, -28, -20, -9, 7, 26, 44, 55, 65, 72, 79, 80, 77, 66, 57,
+ 49, 41, 30, 19, 7, -2, -7, -12, -17, -22, -25, -29, -33, -36, -39, -41,
+ -36, -29, -26, -26, -22, -11, 2, 17, 28, 32, 31, 29, 28, 23, 11, -2,
+ -9, -17, -24, -36, -44, -48, -49, -50, -53, -54, -54, -47, -36, -25, -17, -7,
+ 7, 21, 36, 47, 55, 63, 70, 72, 69, 60, 52, 46, 42, 34, 23, 15,
+ 8, 3, 0, -7, -14, -21, -24, -27, -32, -39, -44, -43, -37, -29, -25, -23,
+ -16, -2, 14, 26, 32, 33, 32, 30, 25, 16, 4, -6, -16, -25, -36, -45,
+ -50, -54, -51, -51, -54, -54, -48, -36, -23, -15, -6, 5, 17, 31, 42, 51,
+ 59, 62, 63, 61, 56, 51, 43, 40, 38, 28, 20, 13, 9, 7, 2, -8,
+ -16, -23, -27, -31, -36, -40, -43, -39, -31, -23, -20, -15, -4, 11, 24, 31,
+ 32, 31, 30, 25, 17, 7, -3, -13, -23, -36, -48, -56, -58, -57, -53, -50,
+ -52, -51, -40, -25, -12, 0, 7, 16, 25, 36, 49, 58, 60, 59, 57, 54,
+ 49, 43, 36, 31, 26, 18, 13, 10, 6, 4, 0, -6, -12, -19, -22, -26,
+ -31, -35, -35, -32, -27, -22, -16, -7, 4, 13, 21, 26, 30, 29, 27, 22,
+ 15, 4, -7, -19, -31, -44, -55, -59, -59, -58, -54, -52, -49, -41, -28, -14,
+ 0, 10, 18, 26, 33, 44, 50, 53, 51, 50, 48, 46, 41, 37, 30, 24,
+ 21, 18, 15, 13, 8, 4, 0, -6, -9, -14, -19, -23, -27, -33, -33, -31,
+ -25, -19, -11, -3, 3, 11, 20, 28, 31, 28, 22, 14, 8, -3, -15, -29,
+ -40, -49, -57, -62, -60, -56, -50, -47, -42, -32, -18, -3, 11, 20, 25, 29,
+ 35, 43, 49, 51, 47, 43, 41, 37, 33, 29, 24, 18, 15, 14, 13, 11,
+ 8, 5, 1, 0, -5, -11, -19, -23, -24, -25, -25, -26, -22, -15, -9, -3,
+ 4, 12, 19, 25, 26, 24, 17, 11, 2, -11, -26, -37, -45, -53, -58, -59,
+ -57, -53, -47, -42, -35, -25, -10, 5, 15, 19, 22, 29, 37, 45, 48, 47,
+ 44, 44, 43, 40, 33, 24, 19, 14, 13, 12, 8, 2, -2, 1, 1, 1,
+ -4, -12, -15, -14, -13, -14, -18, -18, -15, -12, -8, -5, 2, 10, 18, 21,
+ 20, 15, 10, 3, -7, -18, -31, -42, -47, -50, -53, -57, -57, -51, -42, -34,
+ -25, -15, -5, 7, 16, 22, 30, 35, 40, 43, 42, 39, 39, 38, 38, 31,
+ 22, 16, 14, 15, 17, 16, 12, 6, 4, 5, 7, 6, 0, -8, -12, -13,
+ -15, -19, -21, -20, -17, -14, -11, -6, 2, 10, 18, 21, 21, 19, 11, -2,
+ -17, -29, -37, -42, -46, -52, -55, -58, -52, -42, -34, -24, -15, -5, 5, 12,
+ 17, 24, 32, 37, 37, 36, 33, 33, 35, 35, 32, 26, 22, 16, 17, 19,
+ 19, 14, 7, 5, 5, 6, 5, 0, -7, -10, -9, -6, -7, -13, -17, -15,
+ -11, -8, -7, -6, 1, 7, 12, 13, 11, 7, 0, -12, -25, -35, -40, -42,
+ -43, -44, -47, -49, -43, -34, -22, -12, -7, 0, 4, 9, 17, 25, 31, 33,
+ 33, 31, 30, 27, 28, 30, 29, 25, 20, 17, 20, 24, 22, 17, 11, 10,
+ 9, 9, 5, -6, -11, -13, -9, -5, -9, -16, -19, -16, -9, -6, -6, -2,
+ 4, 8, 11, 11, 6, -4, -11, -21, -34, -39, -41, -40, -38, -40, -44, -38,
+ -28, -17, -10, -6, -5, -3, 3, 10, 15, 17, 20, 23, 26, 25, 24, 26,
+ 28, 30, 30, 28, 25, 24, 23, 25, 22, 18, 14, 9, 5, 0, -7, -12,
+ -13, -12, -7, -6, -9, -12, -10, -4, 2, 2, 3, 3, 3, 6, 7, 3,
+ -9, -21, -28, -35, -40, -40, -37, -37, -36, -36, -29, -22, -11, -3, 2, 3,
+ 0, 1, 3, 6, 9, 10, 10, 10, 13, 16, 21, 24, 29, 31, 33, 33,
+ 33, 32, 30, 27, 23, 16, 12, 7, -2, -7, -14, -19, -16, -10, -5, -7,
+ -9, -9, -6, 2, 6, 8, 7, 4, 3, 1, -3, -9, -16, -25, -34, -39,
+ -41, -37, -33, -31, -31, -29, -22, -12, -4, 2, 7, 5, 1, -2, 0, 4,
+ 4, 2, 2, 5, 10, 14, 19, 24, 28, 32, 36, 38, 36, 34, 31, 27,
+ 23, 18, 11, 3, -5, -12, -15, -15, -11, -6, -5, -6, -8, -7, -3, 1,
+ 4, 6, 3, -2, -7, -9, -12, -19, -24, -30, -34, -36, -35, -32, -29, -26,
+ -22, -16, -10, -3, 4, 8, 9, 4, 0, -3, 0, 1, -5, -7, -5, 1,
+ 7, 13, 14, 17, 27, 35, 38, 37, 35, 33, 31, 29, 25, 19, 11, 3,
+ 0, -6, -10, -10, -7, -5, -5, -7, -7, -6, -3, 1, 4, 3, 0, -8,
+ -15, -18, -20, -23, -27, -30, -32, -33, -29, -28, -25, -20, -16, -13, -6, 1,
+ 6, 7, 4, 0, -5, -5, -5, -6, -7, -6, -2, 5, 10, 15, 20, 25,
+ 32, 34, 34, 34, 32, 29, 24, 22, 19, 14, 9, 6, 4, 2, 0, 0,
+ 2, 2, -2, -4, -6, -5, -5, -4, -4, -7, -12, -19, -25, -26, -26, -26,
+ -26, -29, -28, -28, -25, -22, -18, -14, -10, -5, 0, 3, 4, 5, 4, 3,
+ -2, -7, -10, -12, -9, -6, 0, 6, 11, 14, 16, 22, 30, 33, 34, 29,
+ 25, 23, 21, 22, 22, 20, 18, 16, 14, 13, 11, 11, 11, 6, -4, -12,
+ -16, -17, -16, -13, -16, -22, -26, -30, -30, -25, -21, -18, -17, -19, -18, -20,
+ -19, -15, -13, -9, -7, -6, -5, -2, 3, 5, 4, 0, -5, -8, -6, -6,
+ -6, -2, 4, 9, 11, 13, 15, 19, 23, 25, 22, 19, 16, 17, 20, 21,
+ 22, 23, 24, 25, 24, 23, 22, 21, 16, 7, -4, -14, -21, -23, -24, -24,
+ -28, -34, -38, -36, -31, -21, -13, -9, -8, -10, -11, -12, -14, -13, -12, -9,
+ -10, -12, -11, -9, -4, 3, 4, 1, -3, -4, 1, 4, 7, 10, 10, 11,
+ 12, 11, 8, 9, 11, 13, 11, 5, 4, 11, 20, 26, 29, 32, 35, 39,
+ 39, 34, 30, 23, 15, 5, -10, -23, -31, -34, -32, -33, -37, -42, -41, -32,
+ -21, -11, -6, -3, -3, -6, -8, -11, -14, -15, -14, -14, -14, -19, -20, -15,
+ -7, 0, -2, -3, 0, 4, 10, 17, 19, 18, 18, 20, 18, 11, 5, 1,
+ -2, -4, -7, -8, -4, 4, 14, 24, 32, 38, 46, 51, 52, 46, 37, 28,
+ 19, 5, -12, -29, -39, -44, -46, -46, -50, -48, -39, -29, -14, -4, 6, 9,
+ 8, 6, 0, -8, -13, -15, -18, -22, -28, -30, -26, -18, -9, -7, -4, 2,
+ 10, 18, 24, 26, 26, 23, 22, 21, 14, 3, -5, -9, -14, -16, -16, -11,
+ -4, 6, 14, 24, 37, 50, 58, 58, 53, 45, 36, 28, 17, 1, -18, -36,
+ -47, -53, -54, -53, -51, -43, -33, -20, -8, 5, 15, 17, 13, 5, -4, -12,
+ -14, -18, -23, -30, -34, -32, -24, -15, -10, -6, -3, 7, 18, 27, 32, 33,
+ 30, 28, 24, 19, 12, 2, -10, -18, -24, -26, -23, -16, -6, 4, 12, 25,
+ 39, 53, 60, 60, 58, 51, 42, 30, 16, 0, -20, -37, -49, -57, -61, -57,
+ -50, -40, -29, -17, -4, 9, 17, 17, 11, 5, -3, -8, -13, -21, -30, -35,
+ -34, -29, -22, -16, -11, -6, 1, 12, 24, 34, 39, 39, 35, 28, 21, 16,
+ 8, -3, -16, -29, -35, -34, -26, -16, -9, 1, 14, 30, 46, 56, 60, 62,
+ 59, 57, 46, 32, 15, -2, -17, -35, -51, -61, -61, -55, -46, -39, -30, -19,
+ -4, 10, 14, 13, 7, 3, -2, -6, -15, -24, -31, -33, -31, -26, -23, -19,
+ -11, -2, 6, 17, 30, 38, 41, 39, 34, 25, 18, 14, 6, -9, -24, -34,
+ -38, -34, -28, -18, -9, 0, 14, 32, 44, 52, 58, 63, 66, 59, 45, 31,
+ 18, 4, -17, -36, -53, -60, -59, -54, -46, -39, -30, -18, -3, 6, 8, 6,
+ 3, 1, -3, -11, -22, -29, -28, -23, -20, -20, -18, -10, -2, 7, 17, 27,
+ 34, 37, 38, 33, 26, 19, 15, 11, 0, -17, -31, -39, -40, -34, -27, -20,
+ -11, 1, 16, 31, 43, 52, 59, 67, 70, 62, 47, 32, 19, 4, -18, -39,
+ -53, -60, -57, -51, -44, -37, -30, -17, -6, 1, 2, 1, 0, -2, -7, -15,
+ -23, -27, -25, -19, -16, -15, -12, -4, 5, 15, 25, 33, 37, 34, 31, 27,
+ 22, 17, 11, 2, -11, -25, -35, -41, -41, -34, -23, -13, -4, 6, 18, 31,
+ 43, 54, 61, 65, 62, 53, 44, 34, 22, 2, -20, -38, -47, -50, -47, -43,
+ -42, -41, -32, -19, -13, -11, -10, -7, -5, -5, -9, -14, -18, -17, -12, -9,
+ -8, -6, 1, 6, 12, 16, 21, 25, 25, 23, 19, 18, 14, 11, 8, 0,
+ -10, -23, -34, -36, -32, -24, -16, -12, -6, 4, 15, 30, 42, 52, 59, 60,
+ 58, 53, 46, 39, 27, 5, -19, -35, -43, -44, -43, -45, -49, -48, -39, -31,
+ -27, -24, -19, -11, -6, -3, -4, -6, -8, -5, 3, 5, 7, 6, 7, 9,
+ 12, 13, 15, 14, 12, 11, 11, 9, 8, 5, 4, 0, -12, -22, -28, -26,
+ -21, -17, -13, -10, -5, 4, 14, 22, 32, 44, 56, 61, 59, 56, 48, 38,
+ 25, 7, -10, -24, -33, -38, -44, -50, -51, -47, -41, -41, -41, -37, -26, -14,
+ -6, 0, -2, -3, 5, 13, 19, 21, 16, 12, 9, 9, 10, 7, 3, 2,
+ 2, 1, -2, 0, 3, 4, 1, -4, -12, -16, -16, -9, -9, -10, -9, -5,
+ 2, 7, 11, 17, 27, 39, 51, 54, 52, 52, 49, 42, 28, 10, -4, -15,
+ -25, -36, -48, -56, -58, -56, -52, -53, -54, -45, -28, -11, -2, 3, 8, 15,
+ 24, 30, 34, 30, 22, 16, 12, 6, -4, -9, -9, -8, -12, -14, -12, -5,
+ 3, 4, 2, -3, -4, 0, 3, 2, -4, -6, -6, -5, -4, -5, -3, 8,
+ 21, 36, 44, 50, 55, 58, 55, 45, 33, 20, 5, -11, -27, -43, -55, -60,
+ -61, -62, -64, -66, -58, -40, -20, -6, 3, 8, 16, 26, 34, 39, 38, 30,
+ 21, 11, 2, -9, -14, -13, -13, -15, -16, -14, -6, 1, 4, 4, 3, 4,
+ 7, 10, 10, 5, -3, -7, -8, -9, -12, -14, -11, 0, 13, 28, 40, 51,
+ 58, 61, 60, 56, 47, 33, 15, -8, -28, -44, -55, -62, -72, -81, -83, -74,
+ -58, -39, -21, -6, 8, 18, 30, 40, 47, 49, 44, 33, 19, 6, -6, -14,
+ -19, -23, -26, -24, -19, -13, -5, -2, 2, 5, 8, 11, 14, 13, 9, 2,
+ -4, -8, -12, -15, -19, -18, -13, -3, 14, 30, 44, 53, 62, 66, 66, 59,
+ 48, 33, 12, -10, -31, -46, -58, -71, -79, -84, -81, -71, -54, -34, -14, 1,
+ 14, 26, 37, 44, 48, 49, 41, 29, 12, -3, -13, -17, -19, -24, -26, -22,
+ -16, -8, -3, -2, 3, 6, 10, 13, 12, 10, 6, 2, -4, -11, -18, -22,
+ -22, -19, -14, -3, 13, 30, 46, 61, 68, 71, 70, 64, 52, 32, 10, -12,
+ -31, -51, -67, -81, -88, -91, -84, -69, -51, -32, -12, 8, 25, 37, 43, 47,
+ 52, 50, 40, 23, 5, -8, -13, -18, -23, -28, -26, -19, -12, -6, -4, -2,
+ 2, 6, 11, 11, 5, 3, 4, 1, -9, -17, -21, -23, -22, -19, -14, 0,
+ 17, 37, 54, 65, 70, 75, 76, 67, 50, 30, 6, -15, -35, -56, -75, -88,
+ -93, -88, -78, -64, -47, -26, -3, 17, 31, 37, 42, 46, 48, 42, 27, 10,
+ 0, -3, -7, -14, -21, -21, -13, -4, 1, -2, -3, 1, 5, 7, 4, -3,
+ -8, -7, -7, -14, -19, -22, -23, -21, -20, -16, -6, 12, 32, 51, 63, 70,
+ 76, 78, 75, 63, 44, 20, -5, -26, -46, -67, -83, -94, -93, -83, -69, -55,
+ -40, -17, 8, 25, 34, 38, 43, 48, 45, 35, 20, 8, 2, 3, -2, -12,
+ -18, -15, -8, 0, 0, -5, -6, -4, -3, -5, -11, -15, -14, -12, -13, -16,
+ -19, -20, -20, -16, -10, -2, 11, 24, 42, 57, 64, 70, 73, 72, 64, 48,
+ 26, 4, -15, -35, -50, -68, -81, -88, -81, -68, -55, -44, -29, -10, 9, 22,
+ 25, 30, 37, 38, 35, 24, 14, 11, 13, 14, 9, 0, -5, -3, 3, 4,
+ -2, -10, -15, -15, -15, -19, -25, -24, -20, -18, -19, -20, -18, -16, -13, -9,
+ 1, 12, 25, 37, 53, 63, 69, 74, 73, 69, 56, 37, 15, -6, -25, -42,
+ -59, -75, -82, -81, -72, -61, -50, -35, -17, -2, 13, 20, 27, 31, 34, 34,
+ 28, 19, 14, 13, 15, 14, 8, 4, 3, 5, 5, 1, -6, -15, -18, -22,
+ -27, -33, -34, -31, -25, -24, -20, -19, -17, -10, -2, 9, 18, 28, 39, 51,
+ 60, 67, 71, 72, 67, 53, 35, 16, -4, -21, -40, -57, -70, -76, -74, -65,
+ -55, -44, -34, -21, -7, 6, 15, 18, 20, 24, 24, 21, 16, 15, 16, 17,
+ 17, 16, 13, 12, 13, 13, 9, 0, -12, -17, -22, -31, -40, -43, -40, -35,
+ -30, -26, -24, -20, -11, -2, 9, 19, 29, 39, 46, 54, 60, 66, 67, 66,
+ 58, 41, 21, 5, -11, -29, -47, -62, -68, -68, -65, -57, -49, -39, -27, -13,
+ -2, 6, 11, 18, 23, 24, 21, 19, 19, 21, 21, 18, 15, 11, 13, 15,
+ 15, 10, -2, -8, -14, -21, -30, -39, -44, -44, -40, -33, -29, -27, -21, -12,
+ -3, 6, 16, 28, 40, 48, 54, 56, 59, 61, 62, 57, 44, 28, 12, -3,
+ -22, -40, -55, -64, -63, -61, -56, -51, -41, -29, -15, -6, 1, 8, 15, 20,
+ 20, 18, 17, 18, 23, 23, 20, 17, 15, 18, 20, 20, 15, 4, -5, -11,
+ -20, -32, -43, -49, -48, -43, -36, -32, -29, -21, -13, 0, 11, 20, 30, 38,
+ 46, 50, 51, 53, 56, 53, 48, 41, 30, 19, 5, -10, -26, -42, -50, -56,
+ -57, -56, -53, -46, -38, -27, -18, -10, -2, 8, 16, 19, 24, 24, 22, 23,
+ 25, 23, 17, 16, 15, 16, 14, 10, 3, -5, -11, -20, -28, -35, -42, -44,
+ -42, -35, -29, -25, -19, -11, 0, 10, 20, 26, 31, 38, 45, 48, 46, 46,
+ 44, 41, 37, 30, 22, 13, 1, -15, -27, -36, -44, -49, -51, -52, -49, -44,
+ -37, -27, -20, -12, 1, 10, 19, 23, 28, 29, 28, 28, 24, 19, 17, 16,
+ 15, 14, 10, 4, -3, -10, -15, -23, -31, -36, -41, -41, -39, -32, -24, -19,
+ -11, -3, 5, 15, 24, 31, 36, 42, 45, 44, 41, 37, 33, 31, 29, 23,
+ 14, 2, -8, -16, -22, -31, -40, -44, -46, -46, -46, -44, -37, -28, -20, -10,
+ 2, 11, 20, 28, 32, 32, 29, 26, 22, 19, 17, 14, 12, 11, 8, 2,
+ -5, -14, -20, -24, -30, -34, -37, -38, -36, -30, -21, -14, -6, 2, 11, 19,
+ 26, 30, 34, 41, 44, 42, 38, 32, 27, 25, 24, 21, 11, 1, -9, -16,
+ -25, -34, -40, -43, -45, -48, -50, -49, -40, -27, -15, -6, 4, 15, 27, 36,
+ 40, 37, 32, 27, 22, 15, 11, 10, 8, 6, 0, -8, -14, -16, -17, -18,
+ -24, -31, -33, -33, -27, -22, -17, -10, -4, 6, 13, 17, 22, 27, 33, 38,
+ 39, 37, 35, 33, 31, 27, 23, 19, 11, 3, -7, -20, -30, -38, -42, -42,
+ -46, -53, -58, -53, -41, -27, -13, -2, 10, 19, 30, 39, 43, 38, 29, 23,
+ 18, 12, 8, 6, 6, 4, -3, -8, -12, -13, -10, -12, -17, -24, -25, -23,
+ -23, -23, -19, -12, -4, 2, 5, 9, 14, 22, 32, 37, 39, 39, 37, 37,
+ 33, 28, 27, 21, 12, 0, -14, -25, -33, -38, -43, -48, -54, -60, -59, -48,
+ -36, -20, -8, 2, 12, 26, 39, 44, 40, 32, 27, 23, 16, 8, 3, 3,
+ 2, 1, -4, -9, -9, -6, -6, -8, -13, -16, -18, -21, -22, -21, -16, -7,
+ -2, 0, -2, 2, 13, 25, 30, 34, 34, 34, 34, 33, 33, 31, 26, 21,
+ 11, -3, -15, -25, -31, -37, -48, -57, -62, -63, -56, -46, -35, -25, -12, 5,
+ 18, 32, 40, 40, 36, 32, 29, 22, 15, 7, 3, 0, 0, 0, 1, -2,
+ -2, 0, 0, -3, -4, -7, -13, -22, -28, -25, -17, -10, -10, -11, -10, -4,
+ 12, 26, 36, 39, 40, 41, 40, 37, 35, 33, 28, 19, 3, -11, -22, -30,
+ -37, -46, -56, -63, -65, -59, -52, -43, -29, -17, -4, 10, 23, 32, 36, 36,
+ 34, 29, 24, 19, 12, 5, -2, 0, 4, 7, 10, 9, 6, 5, 5, 5,
+ 0, -10, -20, -26, -29, -26, -20, -18, -19, -17, -9, 3, 16, 28, 36, 40,
+ 42, 43, 41, 40, 36, 33, 26, 16, 3, -10, -21, -31, -42, -53, -61, -65,
+ -63, -58, -52, -41, -31, -18, -4, 9, 21, 26, 29, 30, 31, 31, 28, 21,
+ 12, 6, 5, 10, 13, 13, 14, 9, 8, 7, 5, 0, -8, -17, -24, -28,
+ -27, -23, -17, -14, -12, -8, 2, 15, 26, 32, 36, 39, 38, 37, 36, 33,
+ 28, 21, 16, 10, 1, -13, -25, -34, -41, -50, -59, -62, -62, -53, -44, -37,
+ -28, -19, -6, 7, 14, 18, 22, 26, 28, 28, 21, 13, 6, 6, 15, 19,
+ 21, 20, 20, 18, 16, 13, 7, -3, -12, -21, -27, -31, -30, -24, -15, -11,
+ -8, 0, 10, 23, 29, 32, 34, 34, 34, 33, 32, 27, 23, 20, 17, 10,
+ -2, -15, -25, -34, -43, -52, -61, -63, -58, -49, -43, -41, -33, -22, -9, 3,
+ 11, 17, 21, 26, 30, 28, 23, 17, 15, 18, 22, 22, 20, 21, 21, 18,
+ 12, 4, -5, -11, -16, -22, -28, -32, -24, -14, -7, -5, 1, 11, 20, 27,
+ 30, 26, 25, 29, 30, 29, 22, 17, 18, 22, 20, 9, -8, -18, -25, -31,
+ -40, -53, -60, -58, -54, -46, -45, -42, -32, -20, -10, -2, 5, 12, 19, 25,
+ 27, 22, 18, 18, 21, 24, 25, 22, 24, 26, 27, 22, 10, 0, -7, -9,
+ -12, -21, -28, -28, -20, -9, -4, -2, 5, 14, 22, 24, 21, 15, 18, 24,
+ 28, 24, 19, 21, 26, 30, 22, 7, -6, -15, -23, -34, -50, -61, -66, -61,
+ -52, -50, -49, -45, -36, -22, -10, 1, 11, 15, 20, 26, 26, 24, 21, 21,
+ 27, 28, 24, 21, 22, 26, 24, 16, 5, -5, -7, -5, -11, -17, -22, -17,
+ -7, 0, 1, 4, 9, 16, 19, 18, 13, 12, 16, 22, 24, 23, 23, 28,
+ 33, 27, 16, 2, -12, -23, -33, -45, -57, -64, -64, -55, -51, -52, -49, -39,
+ -25, -13, -6, 1, 6, 12, 16, 18, 20, 18, 20, 25, 28, 28, 29, 31,
+ 36, 37, 28, 15, 7, 3, 0, -4, -14, -21, -23, -16, -7, -4, -3, 1,
+ 10, 16, 17, 10, 7, 9, 18, 24, 24, 24, 28, 34, 34, 26, 12, -3,
+ -15, -26, -40, -53, -61, -65, -62, -59, -57, -55, -49, -39, -27, -18, -6, 3,
+ 8, 14, 17, 21, 25, 26, 27, 28, 30, 32, 32, 31, 32, 28, 22, 14,
+ 6, 3, 0, -3, -8, -12, -12, -5, 0, 2, 1, 3, 6, 11, 11, 7,
+ 4, 6, 13, 20, 24, 28, 31, 32, 28, 19, 7, -7, -20, -32, -44, -53,
+ -58, -58, -55, -54, -53, -50, -46, -40, -27, -14, -6, -6, -5, 0, 8, 16,
+ 20, 23, 25, 30, 37, 42, 43, 41, 39, 34, 28, 18, 9, 4, 3, 0,
+ -10, -13, -12, -10, -5, 1, 1, 0, 4, 8, 7, 5, 6, 11, 19, 23,
+ 27, 32, 33, 27, 20, 10, 0, -15, -30, -41, -49, -52, -54, -55, -55, -53,
+ -50, -45, -40, -32, -24, -16, -11, -10, -8, -3, 6, 13, 17, 21, 29, 37,
+ 43, 48, 47, 43, 38, 35, 30, 19, 11, 7, 2, -5, -9, -9, -5, 1,
+ 1, 0, -2, 1, 3, 6, 5, 4, 5, 10, 16, 20, 24, 27, 25, 18,
+ 10, 3, -9, -21, -31, -39, -44, -47, -47, -44, -46, -48, -48, -45, -39, -36,
+ -30, -26, -25, -23, -19, -9, 4, 14, 24, 32, 41, 48, 54, 56, 57, 52,
+ 47, 40, 28, 17, 10, 4, -3, -8, -10, -8, -6, -5, -5, -5, -3, 0,
+ 3, 4, 4, 5, 7, 12, 19, 26, 27, 24, 18, 12, 5, -3, -12, -24,
+ -34, -43, -46, -48, -48, -46, -46, -45, -44, -42, -38, -33, -29, -26, -26, -22,
+ -14, -5, 5, 13, 23, 32, 40, 47, 52, 56, 57, 55, 52, 47, 36, 27,
+ 19, 11, 3, -5, -6, -8, -10, -13, -15, -14, -13, -11, -6, 1, 4, 7,
+ 11, 17, 21, 26, 28, 26, 19, 10, 2, -7, -17, -26, -36, -41, -45, -47,
+ -45, -44, -44, -41, -39, -40, -40, -37, -33, -34, -32, -26, -18, -9, 2, 12,
+ 26, 40, 47, 56, 63, 66, 66, 63, 60, 53, 40, 27, 14, 3, -8, -11,
+ -12, -15, -19, -19, -18, -15, -12, -8, 0, 6, 11, 13, 14, 17, 23, 29,
+ 27, 18, 9, 1, -7, -16, -25, -35, -43, -49, -47, -44, -43, -42, -40, -36,
+ -34, -33, -33, -33, -35, -34, -30, -23, -16, -9, 2, 14, 27, 39, 49, 58,
+ 66, 69, 68, 66, 61, 53, 45, 32, 18, 1, -11, -14, -17, -17, -20, -23,
+ -21, -17, -13, -3, 4, 10, 13, 14, 17, 18, 21, 24, 22, 15, 6, -4,
+ -12, -22, -28, -38, -49, -51, -48, -45, -43, -40, -38, -36, -35, -34, -33, -33,
+ -34, -35, -33, -29, -18, -6, 6, 19, 33, 46, 59, 71, 78, 78, 78, 74,
+ 67, 54, 39, 22, 6, -8, -16, -22, -25, -25, -26, -22, -17, -12, -3, 6,
+ 15, 17, 16, 14, 14, 16, 17, 16, 13, 6, -2, -11, -20, -27, -34, -43,
+ -49, -48, -44, -41, -39, -36, -33, -34, -33, -34, -32, -33, -35, -35, -30, -21,
+ -11, 0, 9, 23, 38, 52, 65, 74, 76, 76, 74, 70, 62, 47, 28, 13,
+ 2, -6, -14, -21, -23, -20, -18, -16, -13, -7, 1, 8, 10, 11, 9, 11,
+ 11, 13, 15, 16, 13, 8, -2, -11, -19, -27, -37, -47, -52, -51, -48, -46,
+ -43, -40, -38, -36, -35, -35, -38, -38, -33, -27, -21, -16, -7, 6, 21, 36,
+ 49, 61, 70, 75, 79, 78, 73, 62, 49, 35, 22, 8, -3, -12, -17, -20,
+ -18, -14, -13, -15, -12, -5, 4, 7, 8, 8, 9, 8, 9, 11, 14, 14,
+ 10, 4, -6, -15, -25, -35, -41, -48, -54, -53, -47, -42, -38, -37, -35, -31,
+ -31, -30, -30, -29, -26, -24, -19, -12, -2, 10, 22, 35, 48, 60, 70, 76,
+ 76, 73, 67, 57, 44, 28, 14, 5, -3, -8, -13, -14, -13, -10, -11, -11,
+ -8, -2, 4, 6, 5, 5, 5, 6, 10, 11, 10, 8, 4, -2, -9, -15,
+ -24, -35, -44, -50, -52, -49, -45, -42, -42, -40, -37, -37, -37, -33, -29, -26,
+ -24, -21, -16, -7, 6, 18, 30, 41, 54, 66, 75, 77, 79, 76, 67, 53,
+ 37, 21, 8, 2, -5, -10, -14, -14, -12, -12, -11, -10, -5, 4, 7, 4,
+ 1, 2, 6, 9, 9, 7, 5, 4, 0, -7, -14, -23, -32, -37, -43, -48,
+ -50, -51, -47, -42, -34, -32, -32, -34, -32, -26, -21, -18, -17, -14, -11, -4,
+ 5, 13, 24, 40, 55, 67, 72, 74, 76, 75, 67, 51, 37, 23, 11, 4,
+ -4, -11, -15, -17, -17, -16, -14, -13, -8, -2, 1, 1, 1, 3, 5, 9,
+ 7, 5, 4, 4, 3, -5, -14, -24, -32, -38, -41, -47, -52, -53, -49, -41,
+ -35, -34, -35, -33, -29, -24, -19, -13, -10, -9, -7, -2, 8, 17, 29, 43,
+ 56, 67, 74, 75, 75, 72, 64, 53, 38, 23, 13, 4, -5, -12, -16, -20,
+ -21, -18, -16, -14, -11, -8, -5, -3, 0, 2, 6, 6, 6, 5, 5, 6,
+ 3, -6, -19, -31, -37, -41, -45, -50, -52, -53, -48, -39, -32, -30, -26, -25,
+ -22, -16, -10, -7, -11, -10, -8, -2, 6, 17, 31, 45, 58, 68, 78, 80,
+ 76, 70, 65, 55, 37, 18, 5, -4, -10, -19, -25, -26, -24, -18, -13, -11,
+ -9, -6, -2, 4, 6, 5, 4, 3, 4, 2, 1, -3, -4, -11, -20, -29,
+ -38, -43, -45, -48, -51, -48, -44, -39, -35, -34, -31, -30, -25, -15, -8, -8,
+ -10, -8, 1, 11, 22, 33, 42, 54, 66, 76, 80, 75, 70, 66, 59, 42,
+ 23, 6, -4, -9, -17, -22, -27, -25, -19, -9, -7, -8, -5, 0, 4, 5,
+ 2, -2, -5, -5, -4, -6, -7, -6, -10, -16, -21, -29, -34, -37, -38, -41,
+ -44, -42, -36, -32, -33, -37, -39, -35, -27, -17, -12, -13, -12, -6, 6, 22,
+ 36, 44, 54, 66, 77, 82, 80, 75, 68, 59, 47, 29, 10, -3, -13, -18,
+ -23, -26, -27, -24, -16, -9, -5, -4, -2, 3, 6, 4, -2, -6, -8, -7,
+ -8, -8, -9, -10, -13, -16, -22, -29, -31, -30, -34, -36, -36, -32, -28, -30,
+ -36, -39, -38, -33, -28, -24, -24, -22, -15, -2, 13, 26, 38, 53, 67, 78,
+ 84, 88, 85, 81, 71, 59, 39, 13, -5, -14, -19, -26, -32, -34, -30, -22,
+ -13, -5, 0, 6, 7, 10, 8, 2, -4, -10, -12, -15, -18, -20, -20, -20,
+ -22, -24, -26, -26, -23, -23, -23, -24, -21, -17, -18, -25, -31, -35, -37, -37,
+ -36, -33, -29, -22, -10, 5, 19, 31, 45, 62, 75, 84, 86, 88, 87, 80,
+ 66, 45, 22, 4, -9, -18, -26, -34, -37, -33, -24, -15, -9, -3, 6, 13,
+ 15, 11, 2, -5, -10, -13, -20, -25, -27, -26, -25, -26, -29, -29, -23, -18,
+ -16, -19, -18, -15, -9, -6, -12, -21, -32, -36, -36, -40, -39, -36, -30, -21,
+ -10, 6, 20, 36, 55, 69, 79, 85, 90, 92, 88, 75, 56, 33, 12, -3,
+ -15, -24, -33, -37, -35, -28, -20, -12, -4, 6, 14, 18, 16, 9, 0, -8,
+ -15, -19, -27, -33, -35, -34, -34, -36, -36, -29, -19, -10, -10, -10, -8, -4,
+ -2, -2, -8, -18, -28, -36, -43, -48, -46, -36, -25, -14, -4, 10, 27, 46,
+ 65, 78, 86, 89, 87, 85, 78, 64, 42, 19, 0, -12, -20, -29, -34, -36,
+ -30, -22, -12, -6, 1, 8, 16, 18, 13, 2, -7, -12, -17, -24, -33, -38,
+ -39, -36, -36, -36, -34, -26, -18, -11, -7, -6, -5, -5, 1, 1, -5, -14,
+ -24, -33, -41, -42, -37, -28, -19, -10, 3, 16, 30, 47, 64, 76, 83, 85,
+ 83, 78, 69, 54, 37, 17, -2, -14, -21, -28, -32, -32, -27, -18, -11, -6,
+ 2, 12, 18, 16, 5, -5, -11, -14, -19, -30, -40, -47, -45, -38, -36, -34,
+ -33, -26, -15, -6, -2, 1, 1, 3, 5, 4, -3, -13, -26, -35, -41, -39,
+ -33, -23, -13, -5, 7, 21, 36, 53, 68, 79, 82, 78, 72, 66, 59, 47,
+ 30, 10, -6, -16, -21, -22, -25, -27, -25, -18, -10, -4, 4, 10, 11, 6,
+ -4, -11, -13, -18, -25, -34, -43, -45, -41, -36, -34, -32, -27, -19, -10, -5,
+ 0, 2, 5, 5, 5, 1, -7, -16, -25, -33, -38, -35, -25, -13, -6, 0,
+ 11, 27, 46, 60, 69, 70, 68, 69, 68, 62, 52, 39, 22, 8, -2, -11,
+ -18, -21, -22, -23, -24, -17, -10, -5, 1, 5, 5, 2, -3, -5, -9, -17,
+ -28, -41, -46, -48, -43, -42, -42, -39, -30, -19, -9, -3, 6, 11, 15, 16,
+ 12, 5, -2, -12, -23, -33, -37, -34, -25, -18, -8, 1, 15, 32, 48, 62,
+ 69, 68, 67, 63, 62, 58, 50, 34, 15, -2, -8, -10, -11, -16, -24, -24,
+ -19, -12, -6, -2, 2, 3, 1, 0, -6, -10, -17, -26, -37, -46, -48, -45,
+ -44, -42, -38, -32, -22, -12, -6, 4, 10, 14, 16, 15, 11, 5, -2, -11,
+ -23, -31, -29, -22, -18, -16, -11, 3, 17, 34, 50, 56, 59, 61, 63, 62,
+ 59, 53, 44, 32, 16, 3, -8, -9, -13, -20, -26, -27, -21, -16, -11, -9,
+ -6, 1, 7, 7, 0, -10, -15, -20, -30, -39, -45, -48, -48, -46, -41, -36,
+ -29, -20, -11, 3, 11, 14, 19, 21, 19, 15, 6, -3, -13, -18, -18, -17,
+ -20, -19, -12, 2, 15, 26, 36, 43, 51, 59, 61, 61, 57, 54, 49, 37,
+ 21, 9, 1, -8, -17, -25, -29, -28, -27, -23, -19, -13, -5, 2, 8, 5,
+ -4, -11, -13, -17, -27, -40, -49, -53, -53, -50, -44, -37, -28, -19, -7, 8,
+ 18, 22, 26, 26, 23, 17, 10, 0, -8, -15, -20, -25, -23, -19, -11, 0,
+ 13, 25, 34, 44, 54, 60, 62, 60, 58, 56, 52, 38, 21, 6, -6, -16,
+ -26, -32, -33, -30, -26, -24, -17, -8, 3, 13, 16, 10, 1, -7, -12, -18,
+ -34, -50, -61, -63, -58, -54, -50, -45, -33, -13, 6, 21, 27, 34, 37, 36,
+ 30, 20, 11, -2, -13, -24, -32, -37, -34, -24, -10, 2, 12, 25, 41, 55,
+ 61, 64, 65, 67, 64, 59, 48, 32, 16, 0, -12, -20, -27, -33, -33, -31,
+ -28, -23, -12, 0, 10, 13, 9, 2, -2, -7, -13, -25, -41, -56, -65, -66,
+ -62, -56, -53, -42, -25, -5, 13, 24, 34, 39, 42, 39, 32, 22, 11, -2,
+ -15, -27, -36, -37, -31, -22, -13, 0, 12, 27, 43, 55, 61, 64, 65, 63,
+ 60, 53, 42, 28, 10, -6, -20, -27, -28, -28, -25, -23, -20, -13, -2, 11,
+ 16, 14, 8, 2, -6, -14, -25, -38, -53, -67, -73, -73, -67, -58, -46, -32,
+ -14, 6, 24, 36, 43, 45, 44, 39, 30, 18, 5, -11, -25, -35, -39, -37,
+ -28, -17, -7, 4, 16, 32, 48, 58, 64, 66, 63, 61, 56, 46, 31, 18,
+ 3, -13, -21, -25, -23, -19, -15, -11, -7, -2, 6, 13, 14, 8, -3, -12,
+ -21, -32, -40, -55, -70, -78, -75, -67, -56, -47, -29, -12, 10, 29, 40, 47,
+ 49, 48, 43, 31, 15, 0, -16, -29, -39, -45, -41, -32, -18, -6, 3, 13,
+ 27, 43, 57, 64, 65, 61, 58, 52, 43, 32, 18, 6, -9, -18, -20, -17,
+ -12, -4, 1, 3, 7, 12, 17, 16, 9, -3, -15, -27, -39, -48, -60, -72,
+ -82, -82, -73, -58, -45, -33, -14, 7, 28, 42, 49, 51, 51, 48, 38, 22,
+ 2, -16, -30, -37, -42, -45, -40, -26, -11, 3, 11, 20, 34, 52, 65, 69,
+ 64, 54, 46, 38, 28, 16, 4, -11, -18, -16, -10, -4, 3, 13, 21, 23,
+ 22, 20, 18, 11, -2, -16, -34, -47, -59, -70, -76, -83, -83, -76, -64, -48,
+ -31, -12, 10, 30, 42, 50, 53, 51, 46, 37, 25, 8, -13, -30, -41, -45,
+ -43, -35, -23, -15, -5, 8, 17, 28, 40, 56, 64, 63, 55, 45, 34, 24,
+ 14, 7, -4, -12, -13, -9, -2, 11, 23, 31, 33, 33, 31, 26, 17, 4,
+ -14, -31, -48, -62, -75, -86, -90, -87, -79, -68, -54, -39, -18, 4, 23, 39,
+ 47, 52, 52, 47, 39, 29, 15, -5, -23, -35, -41, -40, -34, -26, -16, -8,
+ 2, 12, 22, 30, 43, 52, 58, 54, 45, 36, 25, 16, 7, -2, -7, -8,
+ -3, 4, 13, 24, 32, 39, 42, 39, 30, 19, 6, -10, -25, -44, -62, -79,
+ -88, -90, -85, -78, -70, -59, -45, -24, 0, 20, 35, 43, 48, 48, 46, 42,
+ 33, 20, 2, -19, -32, -38, -41, -37, -29, -19, -8, 1, 11, 19, 26, 35,
+ 43, 48, 48, 41, 35, 26, 16, 7, 0, 0, 3, 6, 10, 16, 24, 32,
+ 40, 44, 43, 33, 21, 8, -5, -19, -37, -54, -72, -84, -87, -81, -75, -68,
+ -61, -50, -33, -12, 8, 22, 29, 34, 40, 42, 41, 35, 24, 13, -2, -16,
+ -27, -33, -33, -27, -22, -17, -13, -4, 9, 18, 25, 31, 36, 42, 44, 40,
+ 32, 21, 12, 9, 7, 8, 9, 13, 17, 23, 29, 35, 40, 40, 35, 26,
+ 13, 0, -11, -24, -41, -60, -74, -80, -79, -73, -68, -63, -56, -43, -27, -10,
+ 6, 18, 24, 29, 34, 38, 37, 30, 20, 9, -3, -14, -24, -27, -27, -25,
+ -23, -18, -9, 2, 10, 19, 25, 30, 37, 40, 41, 33, 22, 16, 10, 6,
+ 6, 10, 16, 21, 28, 31, 35, 38, 44, 45, 34, 19, 5, -5, -17, -33,
+ -52, -68, -76, -78, -75, -71, -67, -62, -51, -37, -20, -7, 4, 13, 21, 29,
+ 34, 36, 33, 26, 17, 10, 0, -8, -13, -19, -21, -21, -17, -11, -6, 4,
+ 10, 13, 19, 25, 30, 31, 28, 20, 14, 10, 7, 7, 11, 20, 26, 32,
+ 36, 39, 41, 44, 46, 41, 30, 13, 0, -13, -27, -44, -62, -72, -74, -74,
+ -74, -71, -66, -57, -47, -32, -19, -9, 2, 14, 24, 28, 32, 34, 33, 25,
+ 17, 9, 2, -5, -10, -17, -22, -18, -13, -7, 0, 4, 10, 17, 23, 26,
+ 25, 21, 15, 9, 9, 7, 4, 7, 16, 27, 34, 39, 43, 48, 49, 52,
+ 49, 39, 24, 9, -3, -17, -32, -52, -67, -75, -75, -71, -70, -70, -66, -56,
+ -43, -31, -21, -12, -2, 11, 21, 27, 30, 33, 31, 29, 22, 15, 8, 0,
+ -6, -13, -14, -14, -11, -5, 0, 4, 8, 13, 16, 18, 15, 12, 10, 7,
+ 7, 6, 7, 14, 24, 36, 44, 46, 46, 49, 52, 53, 47, 35, 21, 9,
+ -6, -23, -43, -59, -68, -71, -74, -74, -76, -73, -64, -52, -39, -31, -25, -15,
+ 0, 12, 20, 24, 29, 32, 30, 26, 21, 16, 10, 4, -2, -7, -7, -5,
+ -3, 0, 3, 5, 6, 9, 8, 8, 6, 3, 2, 4, 5, 7, 14, 22,
+ 34, 43, 49, 57, 57, 55, 52, 48, 43, 31, 17, 2, -13, -33, -49, -59,
+ -63, -66, -72, -75, -76, -70, -61, -52, -44, -37, -30, -18, -4, 11, 20, 25,
+ 28, 32, 32, 30, 26, 19, 13, 5, 0, -4, -5, -3, 1, 2, 1, -3,
+ -2, 2, 6, 4, 2, -3, -2, 3, 10, 13, 18, 27, 40, 49, 56, 59,
+ 60, 56, 52, 47, 41, 30, 17, 1, -19, -39, -55, -64, -67, -70, -76, -81,
+ -78, -69, -56, -46, -40, -33, -24, -12, 3, 15, 22, 25, 26, 29, 27, 23,
+ 19, 14, 9, 4, 0, -2, 1, 5, 9, 7, 2, -3, -3, 3, 3, -2,
+ -10, -13, -10, -2, 7, 14, 22, 31, 45, 59, 65, 68, 65, 62, 58, 50,
+ 41, 28, 12, -9, -31, -49, -59, -65, -70, -76, -84, -84, -77, -63, -50, -45,
+ -40, -32, -21, -7, 7, 16, 24, 28, 29, 28, 23, 18, 15, 11, 6, 0,
+ -4, -3, 4, 11, 14, 11, 6, 5, 7, 7, 2, -7, -12, -16, -13, -6,
+ 1, 8, 17, 32, 50, 63, 68, 68, 69, 70, 65, 56, 43, 27, 7, -17,
+ -38, -52, -62, -71, -78, -86, -88, -84, -73, -59, -50, -43, -34, -25, -11, 2,
+ 11, 19, 23, 26, 26, 21, 17, 12, 9, 7, 5, 2, 2, 4, 11, 16,
+ 14, 10, 9, 10, 9, 1, -8, -16, -19, -16, -11, -6, 0, 8, 24, 43,
+ 57, 66, 70, 72, 72, 67, 63, 52, 37, 18, -5, -23, -41, -54, -62, -70,
+ -78, -81, -82, -76, -67, -56, -45, -36, -31, -22, -12, 0, 10, 16, 20, 21,
+ 17, 13, 7, 3, 3, 6, 6, 6, 9, 14, 20, 21, 20, 17, 17, 15,
+ 9, -3, -15, -23, -27, -20, -14, -9, -4, 9, 31, 49, 64, 70, 75, 78,
+ 76, 70, 60, 45, 31, 12, -11, -31, -46, -58, -66, -70, -73, -77, -74, -67,
+ -59, -52, -44, -36, -29, -22, -14, -6, 1, 11, 14, 14, 11, 6, 6, 7,
+ 10, 11, 12, 15, 18, 24, 23, 21, 19, 20, 18, 12, 0, -13, -20, -27,
+ -27, -22, -16, -11, 1, 19, 36, 52, 64, 73, 79, 81, 77, 69, 56, 43,
+ 26, 5, -16, -37, -54, -62, -66, -69, -72, -71, -65, -62, -56, -47, -39, -33,
+ -26, -19, -14, -12, -3, 9, 9, 3, -6, -4, 5, 11, 12, 11, 12, 20,
+ 29, 31, 29, 25, 25, 27, 24, 11, -6, -17, -25, -31, -32, -30, -26, -16,
+ 0, 17, 35, 51, 66, 78, 87, 88, 84, 73, 57, 40, 23, 3, -20, -42,
+ -57, -65, -69, -71, -70, -68, -63, -58, -52, -45, -38, -30, -26, -24, -23, -16,
+ -8, -2, -5, -9, -6, 1, 9, 12, 13, 17, 24, 32, 37, 37, 34, 32,
+ 33, 31, 19, 2, -15, -25, -31, -36, -38, -35, -27, -13, 4, 23, 40, 59,
+ 76, 91, 96, 91, 80, 69, 55, 35, 13, -12, -35, -52, -61, -66, -71, -70,
+ -63, -54, -48, -44, -42, -36, -31, -30, -34, -36, -33, -26, -20, -20, -21, -18,
+ -9, 5, 13, 18, 21, 29, 40, 47, 50, 49, 44, 40, 34, 23, 6, -14,
+ -27, -39, -45, -48, -45, -35, -23, -7, 11, 30, 51, 73, 89, 97, 96, 89,
+ 80, 63, 44, 25, 4, -18, -39, -53, -59, -63, -61, -58, -55, -52, -49, -45,
+ -39, -35, -37, -41, -46, -43, -38, -33, -29, -25, -18, -11, 3, 13, 20, 25,
+ 30, 38, 46, 51, 50, 47, 43, 37, 26, 9, -7, -19, -32, -45, -52, -51,
+ -40, -28, -12, 4, 19, 38, 61, 83, 94, 95, 89, 82, 67, 50, 30, 12,
+ -8, -26, -40, -52, -57, -56, -52, -48, -46, -44, -40, -34, -32, -32, -37, -44,
+ -47, -45, -41, -39, -35, -28, -17, -6, 7, 15, 23, 32, 40, 47, 52, 52,
+ 51, 46, 39, 32, 17, 1, -14, -26, -37, -46, -50, -45, -35, -25, -11, 5,
+ 24, 44, 62, 79, 88, 86, 79, 70, 59, 45, 25, 7, -13, -25, -36, -46,
+ -50, -51, -50, -46, -43, -41, -37, -34, -33, -36, -40, -43, -46, -46, -41, -36,
+ -31, -22, -10, 4, 13, 21, 30, 40, 47, 50, 53, 52, 47, 39, 30, 18,
+ 3, -12, -22, -33, -42, -47, -45, -36, -25, -14, -2, 14, 34, 52, 67, 76,
+ 77, 72, 65, 55, 43, 27, 12, -7, -21, -29, -36, -41, -44, -43, -39, -36,
+ -32, -27, -26, -26, -29, -33, -36, -43, -49, -48, -44, -38, -32, -22, -11, 4,
+ 15, 25, 34, 44, 50, 53, 54, 52, 44, 35, 23, 9, -4, -15, -27, -37,
+ -43, -45, -42, -34, -21, -9, 5, 19, 34, 50, 63, 70, 69, 63, 54, 46,
+ 35, 20, 4, -11, -23, -29, -33, -37, -41, -40, -33, -25, -20, -19, -21, -22,
+ -23, -26, -34, -42, -47, -46, -43, -36, -30, -22, -11, 5, 17, 28, 37, 45,
+ 52, 55, 53, 49, 41, 30, 19, 4, -12, -23, -33, -41, -45, -45, -40, -31,
+ -18, -3, 11, 23, 38, 51, 63, 64, 58, 51, 45, 36, 25, 10, -4, -15,
+ -24, -28, -32, -36, -35, -29, -19, -13, -13, -14, -13, -13, -13, -21, -33, -43,
+ -45, -45, -41, -38, -34, -25, -11, 4, 17, 29, 39, 49, 57, 60, 55, 48,
+ 39, 29, 16, 1, -14, -27, -35, -42, -47, -48, -42, -29, -15, -3, 10, 20,
+ 34, 48, 56, 57, 51, 45, 38, 30, 20, 7, -7, -17, -22, -26, -32, -36,
+ -31, -21, -9, -6, -8, -8, -4, 1, -4, -13, -26, -35, -39, -40, -42, -44,
+ -40, -29, -13, 3, 16, 29, 43, 58, 67, 67, 59, 49, 39, 27, 11, -9,
+ -28, -39, -47, -50, -53, -52, -44, -29, -12, 5, 13, 25, 38, 51, 57, 52,
+ 45, 38, 30, 21, 9, -4, -14, -21, -26, -29, -33, -28, -18, -7, 2, 2,
+ 2, 4, 8, 10, 5, -10, -25, -36, -42, -45, -49, -49, -45, -33, -14, 5,
+ 22, 35, 54, 69, 78, 76, 67, 53, 41, 27, 6, -17, -36, -50, -55, -60,
+ -63, -62, -51, -34, -16, -2, 9, 20, 34, 45, 50, 48, 42, 35, 29, 18,
+ 7, 0, 0, 0, 0, 0, 0, 7, 0, -1, -7, -18, -16, 3, 6, -18,
+ -29, -21, 6, 6, -12, -10, -10, -2, 4, 15, 21, 14, 4, 9, 29, 27,
+ 15, 9, 13, 20, 0, -21, -11, 3, -11, -37, -36, -7, 11, -4, -26, -23,
+ -4, 15, -4, -15, -11, -10, -1, 9, 23, 15, 8, 6, 24, 35, 19, 14,
+ 6, 17, 10, -15, -26, -7, -1, -23, -40, -24, 4, 10, -16, -25, -13, 11,
+ 10, -14, -15, -12, -6, 1, 19, 22, 6, 7, 15, 40, 31, 22, 7, 7,
+ 15, 5, -22, -21, -5, -9, -33, -32, -15, 5, -4, -19, -20, 1, 17, -4,
+ -15, -11, -12, -4, 9, 27, 13, 7, 11, 32, 44, 30, 14, 2, 7, 9,
+ -8, -25, -18, -9, -19, -30, -21, -4, 2, -10, -21, -13, 15, 8, -11, -13,
+ -16, -12, 0, 20, 24, 9, 9, 19, 44, 47, 25, 6, 2, 11, -1, -21,
+ -27, -19, -17, -20, -23, -17, -5, -5, -14, -20, 0, 15, -4, -7, -17, -17,
+ -8, 7, 25, 18, 7, 11, 31, 54, 41, 14, -1, 10, 3, -14, -27, -29,
+ -21, -16, -16, -18, -17, -11, -10, -16, -16, 10, 6, -3, -9, -19, -16, -2,
+ 18, 27, 16, 8, 19, 45, 54, 29, 5, 6, 4, -9, -18, -29, -30, -18,
+ -10, -9, -14, -20, -12, -13, -17, -5, 12, 7, 2, -16, -22, -13, 8, 25,
+ 23, 12, 11, 32, 53, 48, 17, 9, 9, -7, -16, -24, -37, -28, -12, -4,
+ -2, -18, -21, -18, -23, -17, 7, 11, 10, -4, -16, -22, -7, 21, 28, 18,
+ 9, 20, 43, 55, 37, 11, 11, 1, -14, -17, -31, -34, -21, -10, 4, -2,
+ -20, -23, -26, -29, -3, 6, 13, 8, -5, -23, -27, 7, 28, 27, 15, 12,
+ 32, 48, 50, 24, 9, 8, -12, -19, -26, -37, -35, -19, 3, 6, -12, -21,
+ -31, -38, -17, 6, 4, 14, 6, -8, -35, -15, 19, 26, 21, 7, 23, 43,
+ 52, 42, 14, 9, -2, -16, -21, -25, -33, -33, -4, 13, 3, -13, -30, -47,
+ -37, 1, 6, 7, 12, 6, -15, -31, -1, 22, 30, 14, 9, 37, 48, 50,
+ 26, 8, 6, -11, -22, -22, -25, -45, -22, 13, 15, 1, -22, -43, -56, -21,
+ 7, 6, 10, 15, -7, -25, -21, 7, 28, 21, 2, 25, 47, 53, 39, 11,
+ 10, 1, -20, -22, -18, -37, -42, 2, 15, 15, -8, -32, -57, -48, -9, 9,
+ 5, 14, 8, -14, -20, -13, 17, 33, 8, 9, 37, 52, 55, 25, 7, 8,
+ -11, -23, -15, -23, -47, -20, 12, 21, 10, -23, -50, -57, -31, 2, 10, 9,
+ 11, -8, -10, -18, -3, 30, 22, 1, 22, 45, 57, 45, 11, 11, 0, -23,
+ -22, -16, -36, -36, -6, 15, 18, -3, -43, -56, -49, -21, 5, 11, 12, -2,
+ -8, -9, -15, 12, 31, 9, 10, 34, 48, 60, 29, 16, 10, -17, -24, -21,
+ -27, -31, -17, 5, 14, 12, -22, -50, -48, -41, -9, 7, 13, -1, -8, -2,
+ -11, -5, 26, 19, 6, 21, 37, 55, 49, 25, 22, -5, -20, -24, -26, -29,
+ -23, -9, 8, 13, -1, -41, -48, -47, -30, -3, 12, 7, -12, -2, 1, -8,
+ 10, 20, 11, 16, 26, 40, 54, 42, 36, 7, -13, -18, -26, -29, -26, -14,
+ -2, 7, 8, -18, -45, -48, -45, -19, 6, 11, -10, -8, 5, -7, 2, 12,
+ 17, 15, 16, 23, 45, 55, 48, 27, -7, -12, -18, -30, -31, -17, -5, -3,
+ 4, 5, -24, -40, -50, -38, -8, 8, 1, -13, 1, -1, 3, 8, 15, 18,
+ 15, 15, 28, 52, 59, 47, 9, -9, -10, -25, -40, -29, -3, -5, -13, 1,
+ 3, -26, -47, -53, -23, -2, 5, -11, -6, 4, 6, 10, 10, 19, 11, 13,
+ 15, 42, 61, 61, 32, 3, -5, -12, -35, -43, -14, 1, -16, -13, 9, -1,
+ -33, -57, -46, -19, -3, -1, -16, -2, 5, 15, 6, 17, 9, 5, 9, 26,
+ 54, 65, 52, 21, 3, -6, -21, -48, -33, -4, -7, -22, -2, 18, -4, -47,
+ -58, -33, -11, 2, -13, -15, 3, 16, 15, 9, 15, -1, 5, 14, 48, 66,
+ 65, 37, 23, 2, -11, -42, -48, -20, -4, -23, -18, 18, 19, -17, -61, -52,
+ -27, -2, -5, -24, -7, 9, 20, 14, 18, 2, -3, 7, 34, 63, 68, 50,
+ 37, 19, -9, -25, -49, -38, -14, -14, -28, 6, 25, 9, -40, -62, -45, -17,
+ 3, -21, -16, -3, 12, 18, 18, 10, -6, 0, 16, 56, 69, 63, 43, 38,
+ 2, -20, -42, -44, -33, -14, -25, -10, 22, 18, -11, -55, -57, -37, -3, -10,
+ -26, -10, 2, 17, 21, 20, -3, -2, 5, 39, 67, 73, 56, 47, 22, -17,
+ -35, -43, -36, -28, -18, -20, 9, 22, 8, -33, -56, -53, -26, -2, -23, -24,
+ -11, 4, 23, 30, 4, -3, 0, 27, 60, 71, 69, 58, 43, -6, -35, -43,
+ -35, -36, -27, -18, -2, 19, 17, -9, -41, -51, -45, -10, -12, -31, -21, -9,
+ 8, 33, 17, 0, 2, 8, 50, 69, 75, 70, 64, 16, -31, -47, -35, -32,
+ -34, -25, -14, 10, 16, 5, -26, -42, -50, -32, -8, -22, -31, -22, -8, 22,
+ 32, 7, 6, 4, 28, 63, 69, 71, 78, 43, -20, -51, -41, -23, -34, -30,
+ -22, 2, 13, 9, -10, -31, -45, -44, -21, -19, -27, -36, -26, 2, 29, 24,
+ 12, 11, 13, 45, 69, 68, 81, 70, 6, -47, -52, -28, -23, -27, -26, -14,
+ 11, 10, -2, -18, -33, -43, -34, -25, -22, -36, -44, -14, 14, 29, 27, 22,
+ 18, 29, 60, 65, 71, 86, 41, -32, -57, -41, -23, -22, -22, -24, -4, 10,
+ 0, -11, -21, -31, -37, -37, -29, -29, -53, -33, -3, 16, 33, 31, 27, 23,
+ 46, 64, 65, 85, 71, -4, -48, -47, -31, -20, -15, -15, -19, 1, 0, -5,
+ -14, -21, -26, -40, -39, -28, -51, -50, -18, 4, 26, 38, 36, 30, 32, 61,
+ 64, 70, 80, 31, -35, -43, -40, -25, -19, -6, -17, -11, 0, -6, -11, -17,
+ -15, -31, -47, -39, -45, -62, -34, -8, 12, 36, 38, 41, 37, 51, 65, 60,
+ 71, 56, -7, -36, -38, -35, -27, -11, -5, -17, -8, -8, -9, -17, -13, -20,
+ -37, -47, -50, -62, -49, -16, 1, 25, 34, 43, 53, 49, 62, 58, 62, 65,
+ 22, -23, -31, -34, -35, -19, -3, -8, -18, -7, -4, -14, -17, -9, -27, -40,
+ -56, -68, -64, -27, -4, 9, 28, 37, 54, 60, 61, 59, 54, 63, 43, -1,
+ -25, -23, -37, -28, -8, 4, -10, -15, -3, -7, -26, -15, -11, -29, -51, -71,
+ -71, -49, -8, 5, 14, 30, 48, 66, 68, 63, 51, 56, 51, 18, -18, -20,
+ -25, -39, -23, -5, 3, -13, -6, -5, -21, -28, -10, -18, -43, -67, -78, -64,
+ -25, 1, 8, 15, 38, 60, 75, 74, 58, 54, 57, 28, -7, -18, -8, -31,
+ -34, -15, 4, -2, -4, 0, -15, -32, -21, -8, -28, -57, -77, -75, -44, -12,
+ 6, 8, 20, 49, 68, 77, 71, 53, 61, 41, 3, -18, -4, -14, -36, -28,
+ -7, 1, 7, 6, -8, -34, -35, -16, -15, -41, -66, -75, -59, -31, -4, 10,
+ 11, 31, 56, 72, 85, 63, 58, 55, 14, -17, -10, -1, -24, -30, -22, -6,
+ 11, 16, 9, -27, -43, -27, -15, -26, -53, -63, -66, -46, -21, 3, 13, 15,
+ 40, 63, 83, 78, 60, 67, 38, -9, -20, 4, -7, -23, -25, -22, 6, 24,
+ 20, -8, -48, -43, -24, -16, -39, -55, -57, -57, -36, -10, 9, 11, 22, 50,
+ 73, 88, 71, 65, 59, 14, -24, -9, -3, -15, -18, -31, -14, 25, 28, 10,
+ -36, -56, -41, -21, -29, -48, -47, -51, -50, -26, -2, 11, 6, 30, 57, 82,
+ 83, 69, 65, 35, -12, -16, -3, -10, -12, -21, -26, 11, 33, 26, -7, -56,
+ -54, -32, -26, -41, -39, -37, -52, -41, -16, 5, 7, 11, 37, 72, 91, 78,
+ 66, 55, 11, -19, -14, -15, -9, -7, -19, -8, 22, 30, 13, -32, -62, -44,
+ -31, -34, -40, -29, -40, -46, -29, -8, 2, 1, 18, 49, 84, 86, 72, 67,
+ 39, -6, -21, -25, -16, 2, -6, -12, 6, 23, 18, -7, -51, -56, -39, -33,
+ -41, -30, -24, -41, -36, -17, -8, -5, 7, 32, 66, 84, 78, 75, 58, 20,
+ -15, -29, -33, 2, 4, -1, 1, 11, 17, 4, -27, -56, -46, -36, -37, -39,
+ -22, -24, -38, -23, -16, -16, -7, 18, 46, 72, 82, 81, 72, 44, -1, -25,
+ -41, -18, 14, 8, 10, 0, 5, 2, -11, -40, -50, -42, -38, -37, -33, -11,
+ -27, -26, -20, -22, -13, 0, 31, 52, 73, 82, 80, 61, 26, -16, -37, -40,
+ 0, 18, 17, 12, -5, -8, -10, -21, -41, -43, -44, -36, -35, -20, -12, -23,
+ -14, -32, -21, -12, 15, 38, 58, 76, 82, 72, 46, 4, -26, -41, -23, 14,
+ 25, 18, 2, -23, -18, -14, -29, -35, -45, -42, -35, -29, -15, -19, -3, -23,
+ -32, -19, -1, 27, 40, 67, 81, 76, 61, 26, -11, -33, -36, -6, 28, 28,
+ 13, -15, -38, -19, -20, -26, -36, -46, -35, -32, -20, -21, -4, -4, -28, -25,
+ -16, 13, 31, 49, 74, 79, 69, 48, 8, -16, -33, -21, 7, 33, 24, 5,
+ -32, -38, -22, -21, -22, -41, -43, -32, -25, -23, -16, 6, -9, -29, -28, -5,
+ 20, 39, 58, 75, 71, 60, 22, 0, -18, -27, -10, 16, 30, 15, -14, -49,
+ -34, -19, -16, -27, -43, -31, -25, -27, -24, -1, 7, -15, -32, -22, 3, 28,
+ 50, 61, 67, 59, 38, 13, 5, -17, -16, -3, 21, 23, 3, -34, -49, -28,
+ -17, -19, -34, -34, -18, -26, -32, -16, 14, 6, -23, -34, -11, 14, 44, 54,
+ 56, 60, 44, 25, 18, 2, -18, -9, 3, 21, 9, -14, -45, -39, -24, -22,
+ -28, -32, -18, -17, -36, -30, 5, 21, -5, -31, -27, 1, 30, 56, 46, 50,
+ 47, 32, 29, 20, -4, -9, -9, 4, 10, -2, -28, -38, -31, -33, -26, -26,
+ -19, -9, -24, -38, -11, 24, 10, -17, -36, -14, 14, 48, 49, 37, 43, 39,
+ 33, 32, 11, 1, -5, -11, -6, -3, -16, -29, -28, -40, -38, -27, -20, -6,
+ -11, -31, -29, 15, 22, 0, -25, -25, 2, 31, 51, 38, 35, 41, 41, 34,
+ 27, 8, 6, -7, -20, -14, -7, -20, -19, -34, -52, -35, -23, -11, -5, -18,
+ -33, -5, 26, 5, -11, -27, -11, 17, 43, 43, 30, 29, 46, 45, 38, 17,
+ 6, 2, -22, -27, -16, -16, -18, -18, -53, -48, -23, -19, -3, -10, -21, -19,
+ 18, 12, -6, -20, -21, 6, 29, 42, 31, 23, 37, 54, 48, 31, 13, 13,
+ -13, -31, -25, -16, -16, -11, -38, -62, -33, -28, -7, -3, -12, -17, 6, 16,
+ 2, -11, -17, -5, 15, 35, 34, 25, 23, 44, 55, 41, 22, 14, 2, -29,
+ -32, -23, -11, -13, -18, -60, -50, -32, -16, -6, -11, -4, 3, 11, 3, -1,
+ -14, -8, 5, 20, 39, 31, 24, 26, 54, 57, 37, 16, 8, -19, -32, -27,
+ -17, -17, -17, -36, -58, -40, -32, -11, -11, -2, 6, 10, 2, 0, -4, -12,
+ 1, 8, 33, 42, 26, 17, 35, 63, 53, 26, 6, -9, -27, -30, -25, -17,
+ -23, -24, -47, -51, -38, -17, -11, -6, 12, 17, 8, -8, -1, -10, -7, 4,
+ 18, 40, 33, 18, 22, 49, 70, 46, 12, -11, -16, -23, -27, -19, -28, -26,
+ -36, -50, -48, -31, -13, -13, 10, 20, 21, 0, -6, -1, -7, 3, 15, 32,
+ 40, 24, 17, 31, 58, 67, 28, -2, -21, -14, -31, -18, -24, -33, -33, -49,
+ -49, -41, -18, -20, -2, 20, 23, 19, -12, -7, -2, -3, 10, 22, 33, 37,
+ 21, 23, 39, 72, 51, 10, -17, -18, -20, -29, -17, -33, -36, -49, -48, -47,
+ -24, -16, -15, 11, 24, 30, 6, -12, -2, -2, -1, 18, 29, 35, 27, 25,
+ 25, 56, 63, 23, -5, -19, -14, -23, -21, -21, -38, -52, -54, -40, -32, -15,
+ -23, -7, 18, 31, 22, -2, -7, 3, 0, 12, 21, 34, 31, 28, 22, 35,
+ 66, 40, 2, -19, -19, -15, -21, -16, -30, -60, -62, -42, -33, -18, -18, -22,
+ 4, 29, 29, 14, -2, -4, 5, 6, 16, 28, 36, 24, 29, 26, 52, 49,
+ 14, -13, -24, -19, -14, -15, -17, -53, -75, -54, -32, -18, -11, -26, -18, 18,
+ 28, 25, 13, -6, 4, 13, 9, 17, 37, 24, 28, 33, 37, 49, 26, 1,
+ -19, -26, -16, -11, -7, -33, -77, -71, -45, -15, -8, -18, -30, 1, 25, 21,
+ 26, 3, 5, 17, 14, 11, 33, 27, 17, 34, 38, 42, 33, 6, -11, -28,
+ -22, -12, -3, -16, -60, -81, -62, -25, -2, -14, -27, -17, 20, 18, 24, 18,
+ 6, 16, 21, 12, 24, 28, 12, 26, 44, 42, 35, 13, -5, -21, -31, -18,
+ -2, -2, -42, -77, -76, -47, -10, -6, -22, -24, 4, 16, 18, 25, 18, 18,
+ 24, 20, 20, 32, 14, 11, 40, 49, 41, 21, -6, -13, -27, -28, -5, 5,
+ -18, -59, -79, -63, -30, -6, -11, -28, -11, 8, 10, 23, 27, 17, 24, 25,
+ 25, 28, 19, 8, 25, 47, 46, 27, -5, -15, -18, -33, -20, -5, -3, -35,
+ -70, -66, -51, -22, -7, -21, -19, -3, 6, 17, 29, 26, 23, 28, 25, 32,
+ 23, 14, 11, 39, 50, 38, 3, -19, -10, -21, -29, -12, -3, -12, -55, -65,
+ -56, -42, -14, -10, -23, -11, -3, 10, 23, 32, 26, 28, 28, 35, 29, 22,
+ 13, 18, 41, 43, 18, -16, -18, -14, -29, -21, -11, -8, -32, -61, -52, -52,
+ -30, -11, -18, -16, -10, 2, 22, 35, 30, 25, 32, 34, 40, 27, 19, 11,
+ 23, 39, 32, -1, -22, -14, -22, -23, -14, -11, -17, -45, -52, -51, -51, -22,
+ -17, -19, -17, -10, 11, 35, 39, 29, 26, 34, 43, 43, 27, 16, 12, 25,
+ 31, 18, -13, -20, -19, -22, -12, -14, -15, -28, -44, -47, -53, -33, -15, -22,
+ -24, -20, 5, 27, 38, 31, 21, 27, 46, 51, 40, 18, 8, 13, 23, 24,
+ 3, -21, -22, -22, -8, -9, -22, -26, -31, -40, -51, -44, -17, -15, -26, -31,
+ -10, 24, 35, 37, 25, 21, 42, 57, 53, 30, 11, 7, 11, 21, 12, -11,
+ -23, -25, -12, 0, -18, -32, -31, -30, -45, -46, -26, -13, -25, -39, -25, 15,
+ 36, 29, 25, 20, 37, 58, 63, 46, 15, 3, -2, 19, 16, -2, -19, -25,
+ -23, 4, -4, -31, -36, -29, -32, -43, -37, -17, -16, -39, -43, -2, 34, 31,
+ 21, 17, 30, 62, 67, 62, 27, 9, -9, 3, 26, 8, -18, -26, -26, -5,
+ 9, -23, -44, -33, -26, -33, -40, -28, -12, -30, -52, -24, 23, 33, 15, 14,
+ 22, 54, 75, 68, 47, 14, -9, -12, 19, 23, -12, -20, -20, -13, 11, -6,
+ -40, -41, -19, -23, -34, -34, -14, -13, -48, -48, 4, 35, 23, 7, 13, 40,
+ 77, 78, 57, 31, -3, -18, 3, 27, 7, -24, -19, -16, 1, 5, -29, -49,
+ -28, -13, -26, -34, -26, -4, -30, -57, -24, 22, 30, 6, 7, 31, 63, 86,
+ 68, 42, 10, -19, -13, 15, 25, -10, -22, -14, -7, 6, -11, -45, -40, -14,
+ -24, -35, -31, -12, -8, -51, -44, -2, 29, 11, -1, 22, 47, 74, 78, 49,
+ 25, -8, -26, -4, 26, 12, -16, -19, -11, -1, -1, -28, -45, -22, -13, -29,
+ -29, -23, -1, -26, -55, -26, 14, 20, -3, 13, 39, 63, 80, 61, 33, 8,
+ -22, -25, 10, 22, -1, -14, -15, -7, -1, -14, -37, -26, -13, -25, -28, -26,
+ -2, -5, -48, -44, -7, 18, 3, 9, 30, 49, 71, 70, 45, 23, -13, -33,
+ -5, 22, 11, -7, -17, -14, -6, -8, -29, -29, -15, -19, -26, -31, -15, 6,
+ -25, -52, -30, 7, 7, 2, 21, 40, 60, 67, 52, 33, 7, -29, -19, 16,
+ 22, 4, -8, -15, -11, -6, -23, -24, -10, -11, -23, -27, -22, 1, 0, -34,
+ -45, -14, 2, 1, 15, 35, 52, 62, 49, 36, 21, -16, -26, 1, 20, 12,
+ -7, -10, -20, -10, -19, -28, -9, -8, -15, -26, -27, -11, 2, -15, -41, -34,
+ -10, -7, 6, 32, 48, 56, 51, 35, 26, 1, -24, -10, 15, 18, 2, -9,
+ -17, -18, -11, -32, -6, 2, -9, -18, -22, -17, -3, -2, -21, -34, -26, -13,
+ -8, 20, 47, 53, 52, 38, 24, 5, -14, -15, 9, 14, 4, -6, -14, -21,
+ -14, -28, -22, 12, 0, -10, -23, -24, -13, 2, -10, -23, -34, -26, -13, 4,
+ 39, 58, 51, 45, 28, 6, -9, -11, 3, 17, 7, -3, -10, -18, -15, -22,
+ -35, 2, 18, 2, -11, -23, -20, -1, 0, -15, -24, -39, -25, -6, 17, 52,
+ 56, 47, 35, 6, -10, -8, 0, 13, 13, -2, -9, -13, -13, -25, -43, -16,
+ 21, 19, -3, -21, -25, -10, 2, -5, -14, -30, -40, -13, -1, 34, 58, 51,
+ 44, 18, -10, -9, -2, 6, 12, 7, -7, -12, -12, -18, -40, -33, 9, 32,
+ 19, -9, -23, -15, 1, 3, -9, -18, -40, -28, -4, 7, 47, 59, 49, 24,
+ 1, -13, -5, 1, 10, 11, 5, -12, -12, -15, -35, -42, -9, 23, 33, 9,
+ -22, -24, -5, 1, -5, -12, -30, -40, -7, -3, 22, 56, 58, 35, 11, -12,
+ -9, -5, -1, 7, 13, -4, -13, -13, -25, -43, -29, 10, 34, 32, -6, -27,
+ -8, 3, -5, -13, -22, -40, -18, -3, -1, 37, 61, 46, 23, -5, -13, -4,
+ -4, -7, 12, 14, -10, -18, -22, -34, -35, -10, 22, 39, 23, -15, -14, 5,
+ 3, -8, -15, -36, -23, -1, -7, 14, 51, 57, 37, 8, -13, -7, -2, -14,
+ -6, 20, 3, -21, -26, -27, -30, -27, 1, 28, 36, 7, -10, 0, 5, -8,
+ -14, -30, -29, -3, -10, -5, 31, 56, 46, 19, -7, -10, 3, -11, -21, 9,
+ 19, -10, -30, -29, -19, -24, -20, 10, 35, 29, 8, -1, 5, -2, -13, -28,
+ -33, -3, -1, -13, 12, 49, 55, 31, -1, -12, 2, -3, -26, -2, 21, 2,
+ -28, -34, -21, -17, -29, -12, 23, 34, 19, 6, 7, 4, -4, -23, -40, -10,
+ 7, -12, -2, 34, 55, 36, 8, -10, 1, 3, -19, -18, 15, 15, -10, -33,
+ -30, -9, -19, -25, 4, 32, 30, 16, 11, 10, 3, -15, -35, -27, 9, -4,
+ -10, 16, 52, 42, 12, -7, -6, 4, -6, -21, -2, 17, 0, -20, -41, -13,
+ -9, -31, -16, 18, 34, 23, 14, 9, 10, -7, -26, -34, -3, 10, -10, 2,
+ 42, 51, 16, -8, -11, -2, -2, -11, -9, 9, 2, -8, -36, -31, 3, -23,
+ -30, -1, 27, 27, 23, 15, 18, 3, -17, -31, -19, 8, 1, -4, 24, 51,
+ 30, -11, -16, -6, -3, -5, -10, 3, 1, -10, -22, -41, -4, -6, -29, -18,
+ 12, 25, 26, 23, 20, 11, -10, -21, -27, -4, 7, 0, 13, 41, 40, 3,
+ -24, -11, -1, -2, -3, 5, 5, -14, -15, -35, -20, 0, -19, -24, -4, 11,
+ 23, 31, 24, 16, -3, -13, -23, -14, 2, 3, 18, 32, 38, 21, -20, -29,
+ -5, -2, 0, 5, 11, -14, -22, -25, -26, -3, -11, -26, -11, -2, 8, 32,
+ 34, 24, 2, -8, -16, -13, 1, 1, 10, 31, 31, 33, 1, -36, -22, 0,
+ 0, 8, 18, -3, -27, -22, -22, -10, -9, -24, -16, -5, -16, 16, 40, 34,
+ 8, -3, -13, -12, 1, 1, 3, 30, 30, 24, 18, -28, -35, -13, -2, 6,
+ 19, 10, -25, -28, -15, -9, -10, -19, -20, -3, -15, -8, 27, 42, 25, 1,
+ -14, -18, 7, 9, -1, 19, 37, 19, 23, -10, -41, -26, -9, 2, 20, 19,
+ -17, -35, -21, 0, -9, -18, -20, -7, -8, -24, 6, 37, 43, 14, -10, -22,
+ 3, 18, 4, 6, 36, 23, 16, 4, -32, -37, -19, -3, 17, 27, 0, -37,
+ -34, -3, 7, -17, -27, -19, -1, -20, -13, 17, 44, 35, 2, -22, -9, 19,
+ 20, 2, 26, 32, 15, 5, -17, -40, -29, -9, 10, 28, 17, -23, -41, -21,
+ 9, -2, -27, -30, -5, -7, -21, -4, 27, 47, 27, -14, -21, 11, 29, 14,
+ 15, 32, 20, 4, -11, -31, -38, -15, 2, 22, 22, -3, -32, -34, -6, 8,
+ -13, -38, -19, 0, -16, -14, 6, 37, 39, 11, -18, -4, 25, 25, 16, 24,
+ 27, 7, -10, -24, -38, -25, 0, 12, 23, 8, -16, -31, -23, 0, 0, -27,
+ -33, -2, -9, -16, -11, 17, 41, 32, 5, -15, 12, 25, 24, 21, 27, 14,
+ -4, -21, -31, -29, -4, 9, 19, 9, -9, -19, -25, -10, -5, -15, -38, -13,
+ -6, -13, -17, -1, 30, 36, 27, -2, 2, 20, 24, 25, 24, 19, 2, -16,
+ -32, -29, -13, 8, 18, 16, -6, -13, -21, -15, -14, -13, -26, -22, -6, -11,
+ -14, -14, 11, 30, 37, 17, 1, 13, 20, 23, 24, 21, 5, -10, -32, -31,
+ -15, 0, 17, 22, -3, -15, -17, -11, -15, -19, -23, -22, -8, -8, -13, -18,
+ -8, 18, 40, 38, 12, 12, 15, 21, 23, 24, 7, -9, -22, -34, -19, -6,
+ 11, 30, 9, -17, -20, -16, -11, -22, -30, -27, -8, -7, -10, -19, -16, -2,
+ 32, 52, 31, 17, 16, 13, 21, 19, 19, -9, -17, -30, -25, -7, 3, 29,
+ 25, -9, -21, -20, -11, -14, -29, -37, -14, 2, -5, -14, -22, -12, 13, 50,
+ 49, 27, 23, 15, 13, 9, 18, 7, -22, -22, -28, -11, -5, 19, 35, 13,
+ -20, -24, -18, -8, -22, -38, -31, 2, 3, -6, -26, -22, -3, 38, 56, 42,
+ 34, 21, 12, 6, 11, 17, -15, -24, -20, -15, -6, 9, 29, 29, -4, -28,
+ -23, -14, -13, -30, -39, -16, 9, 6, -12, -33, -16, 19, 57, 49, 41, 30,
+ 13, 4, -1, 6, -4, -27, -21, -13, -6, 2, 12, 34, 12, -24, -24, -20,
+ -16, -24, -38, -33, 2, 12, -2, -30, -31, 2, 45, 59, 46, 41, 24, 8,
+ -3, -6, 1, -15, -25, -16, -3, 5, 2, 21, 28, -11, -26, -23, -18, -20,
+ -32, -40, -14, 14, 11, -10, -40, -20, 30, 60, 55, 42, 34, 15, 6, -12,
+ -12, -4, -19, -21, -9, 8, 4, 10, 28, 6, -25, -22, -20, -22, -29, -38,
+ -27, 5, 16, 4, -24, -39, 12, 51, 61, 51, 41, 27, 10, -7, -25, -9,
+ -10, -17, -15, 0, 9, 5, 21, 15, -13, -27, -17, -21, -23, -38, -33, -11,
+ 10, 6, -4, -38, -17, 36, 55, 55, 45, 35, 21, 4, -27, -25, -2, -10,
+ -14, -13, 3, 5, 14, 16, 0, -24, -21, -18, -22, -36, -39, -17, -3, 5,
+ 3, -15, -28, 16, 50, 53, 52, 43, 29, 13, -14, -36, -10, -1, -15, -15,
+ -6, 6, 5, 13, 4, -11, -24, -17, -18, -27, -43, -18, -12, -7, 4, 3,
+ -17, -4, 38, 53, 52, 48, 41, 23, 0, -31, -30, 2, -7, -14, -13, -5,
+ 3, 11, 7, -4, -21, -25, -21, -19, -39, -23, -9, -19, -8, 5, -1, -10,
+ 24, 46, 48, 46, 44, 32, 10, -18, -37, -7, 0, -12, -14, -13, -4, 8,
+ 9, 1, -16, -29, -28, -17, -33, -31, -6, -21, -21, -4, 12, 3, 13, 41,
+ 46, 44, 46, 44, 20, -7, -36, -27, 6, -3, -18, -21, -12, 2, 12, 6,
+ -5, -27, -36, -21, -20, -34, -12, -8, -29, -16, 11, 15, 10, 28, 47, 46,
+ 41, 45, 35, 5, -24, -30, -5, 3, -14, -26, -16, -7, 7, 8, -3, -18,
+ -39, -32, -16, -28, -26, -8, -23, -26, 0, 19, 16, 20, 42, 55, 45, 38,
+ 39, 20, -11, -24, -13, -2, -6, -25, -22, -7, -5, 13, 0, -11, -36, -41,
+ -20, -16, -29, -16, -14, -28, -12, 13, 17, 15, 32, 50, 57, 41, 38, 30,
+ 2, -14, -9, -3, -3, -19, -33, -10, -7, 7, 7, -13, -30, -42, -28, -13,
+ -17, -26, -14, -22, -15, 7, 19, 15, 26, 46, 59, 51, 34, 33, 12, -7,
+ -11, -4, -5, -13, -38, -23, -3, 3, 15, -7, -32, -45, -34, -21, -11, -27,
+ -25, -21, -19, -1, 13, 15, 22, 37, 53, 62, 46, 34, 15, -2, 0, -4,
+ -8, -9, -34, -38, -8, 4, 17, 3, -25, -50, -44, -26, -12, -13, -32, -24,
+ -20, -7, 11, 18, 17, 33, 50, 65, 57, 41, 24, 0, 5, 5, -9, -11,
+ -25, -44, -25, -1, 17, 13, -18, -42, -51, -33, -20, -7, -27, -29, -23, -16,
+ 0, 14, 14, 28, 48, 60, 66, 51, 34, 4, 0, 15, -3, -14, -20, -35,
+ -37, -12, 12, 27, -7, -37, -50, -40, -29, -15, -15, -30, -24, -15, -7, 6,
+ 17, 25, 46, 59, 68, 63, 43, 20, -6, 14, 10, -8, -20, -30, -34, -22,
+ -2, 24, 15, -30, -49, -49, -37, -28, -15, -26, -28, -18, -11, -7, 7, 27,
+ 42, 58, 70, 70, 53, 35, 4, 0, 18, -1, -15, -32, -31, -26, -12, 12,
+ 28, -4, -44, -53, -44, -39, -25, -23, -28, -19, -11, -12, -16, 13, 42, 56,
+ 71, 71, 57, 45, 23, -3, 10, 11, -6, -27, -35, -25, -22, -1, 23, 17,
+ -29, -54, -46, -44, -39, -29, -28, -21, -15, -15, -26, -12, 39, 57, 70, 73,
+ 60, 49, 41, 13, 1, 11, 0, -16, -32, -25, -15, -14, 10, 23, -5, -48,
+ -46, -42, -49, -43, -31, -24, -15, -13, -24, -32, 18, 59, 71, 77, 67, 57,
+ 47, 33, 3, 5, 5, -9, -23, -33, -16, -14, -5, 17, 12, -29, -44, -35,
+ -50, -57, -43, -30, -18, -11, -22, -39, -9, 44, 68, 82, 69, 61, 49, 42,
+ 18, 5, 5, -8, -12, -26, -14, -7, -9, 5, 16, -6, -36, -32, -42, -62,
+ -55, -39, -29, -15, -14, -34, -30, 20, 59, 82, 79, 66, 58, 45, 38, 9,
+ 1, -7, -11, -16, -19, -3, -6, -6, 9, 5, -22, -32, -32, -58, -70, -56,
+ -42, -24, -16, -25, -39, -9, 41, 72, 86, 73, 65, 46, 40, 30, -4, -7,
+ -14, -12, -20, -3, 4, -5, 1, 8, -9, -27, -25, -40, -67, -67, -55, -38,
+ -24, -17, -25, -28, 16, 61, 81, 82, 71, 60, 37, 42, 17, -14, -17, -11,
+ -13, -8, 10, 2, -2, 1, -1, -17, -20, -26, -54, -69, -70, -58, -34, -25,
+ -16, -23, -9, 37, 70, 87, 80, 68, 44, 38, 39, -5, -27, -19, -12, -6,
+ 13, 10, 4, 1, 1, -5, -19, -20, -37, -59, -71, -71, -54, -35, -17, -9,
+ -20, 11, 49, 80, 86, 72, 54, 36, 45, 23, -25, -34, -16, -9, 11, 17,
+ 8, 5, -4, -2, -15, -19, -26, -50, -69, -77, -71, -51, -29, -7, -11, -6,
+ 26, 64, 87, 78, 60, 40, 42, 45, 2, -38, -34, -12, 10, 24, 10, 11,
+ 3, -1, -6, -20, -16, -31, -61, -81, -80, -69, -41, -16, -5, -8, 10, 47,
+ 81, 86, 70, 44, 36, 48, 32, -21, -48, -31, -3, 24, 24, 10, 15, 0,
+ 2, -17, -21, -18, -45, -81, -87, -80, -57, -33, -11, -6, 2, 30, 74, 86,
+ 77, 55, 34, 42, 48, 13, -39, -50, -20, 15, 34, 14, 16, 12, 4, -5,
+ -26, -16, -19, -64, -92, -91, -65, -43, -26, -12, -1, 16, 47, 83, 76, 66,
+ 40, 33, 45, 33, -8, -52, -41, -5, 32, 30, 15, 25, 13, 8, -22, -28,
+ -11, -34, -85, -101, -86, -52, -36, -25, -13, 15, 32, 69, 80, 69, 52, 32,
+ 37, 39, 19, -30, -54, -24, 10, 38, 25, 25, 22, 18, -6, -35, -20, -14,
+ -59, -98, -99, -68, -41, -30, -23, 5, 28, 52, 74, 67, 59, 43, 32, 35,
+ 32, -2, -47, -38, -13, 23, 33, 31, 26, 27, 16, -29, -37, -15, -33, -80,
+ -104, -89, -54, -35, -31, -11, 17, 42, 63, 68, 60, 59, 37, 27, 33, 22,
+ -28, -37, -26, 3, 32, 38, 30, 25, 30, -3, -41, -29, -23, -55, -90, -98,
+ -76, -39, -32, -21, 4, 36, 52, 61, 61, 63, 48, 24, 28, 34, -10, -31,
+ -29, -14, 15, 37, 37, 28, 31, 19, -27, -40, -24, -38, -69, -95, -96, -60,
+ -32, -26, -10, 19, 45, 53, 58, 59, 58, 29, 23, 39, 14, -21, -25, -23,
+ 1, 27, 43, 34, 34, 21, 0, -36, -32, -31, -49, -84, -102, -83, -41, -22,
+ -19, -1, 35, 49, 52, 53, 56, 39, 23, 34, 33, -3, -23, -22, -10, 17,
+ 36, 36, 39, 26, 8, -16, -34, -29, -36, -61, -93, -95, -58, -26, -18, -11,
+ 22, 48, 53, 53, 51, 41, 31, 33, 37, 16, -15, -24, -14, 4, 29, 34,
+ 41, 32, 8, -7, -19, -28, -30, -54, -83, -101, -76, -40, -20, -21, 1, 36,
+ 54, 55, 44, 33, 32, 35, 36, 30, 7, -26, -19, -5, 22, 36, 37, 37,
+ 15, -3, -5, -15, -24, -43, -75, -94, -87, -47, -29, -25, -14, 26, 48, 62,
+ 49, 29, 23, 35, 45, 38, 19, -16, -28, -7, 10, 29, 32, 38, 23, -2,
+ -10, -6, -12, -28, -67, -90, -98, -59, -32, -28, -25, 3, 43, 56, 59, 25,
+ 16, 24, 46, 43, 31, 0, -31, -14, 5, 25, 29, 32, 29, 6, -13, -6,
+ -3, -8, -49, -85, -97, -75, -31, -30, -30, -12, 31, 50, 61, 40, 12, 14,
+ 34, 53, 43, 20, -23, -20, -3, 21, 29, 23, 24, 15, -10, -8, -1, 2,
+ -25, -75, -98, -92, -42, -31, -35, -24, 14, 41, 50, 49, 22, 11, 20, 45,
+ 52, 39, 0, -26, -12, 9, 35, 25, 18, 14, 1, -13, -6, 4, 3, -49,
+ -89, -102, -61, -27, -30, -27, -4, 34, 46, 46, 32, 17, 13, 26, 47, 50,
+ 29, -19, -22, -4, 30, 37, 15, 7, 7, -5, -10, -4, 9, -20, -72, -100,
+ -86, -41, -33, -31, -16, 18, 43, 34, 32, 27, 23, 15, 31, 47, 48, 9,
+ -24, -16, 12, 43, 25, -2, 0, 9, -9, -15, 2, 8, -40, -87, -99, -69,
+ -37, -31, -19, 6, 38, 35, 25, 31, 35, 26, 18, 36, 49, 40, -10, -22,
+ -9, 29, 40, 6, -12, 6, 6, -16, -11, 9, -6, -61, -95, -90, -58, -35,
+ -26, -5, 23, 36, 18, 21, 36, 41, 28, 22, 38, 52, 23, -17, -17, 7,
+ 39, 21, -12, -13, 16, -8, -22, -5, 6, -25, -77, -93, -79, -46, -30, -11,
+ 15, 36, 22, 5, 29, 47, 47, 24, 22, 41, 48, 7, -15, -4, 22, 33,
+ 6, -23, 4, 8, -21, -15, -1, -5, -49, -79, -92, -71, -43, -20, 11, 31,
+ 29, 4, 16, 40, 55, 41, 22, 31, 50, 25, -9, -2, 8, 23, 16, -17,
+ -6, 8, -10, -15, -6, -4, -29, -56, -80, -86, -61, -42, 0, 30, 33, 12,
+ 2, 24, 47, 55, 37, 28, 39, 40, 4, -1, 6, 6, 16, -4, -13, 1,
+ -2, -9, -11, -11, -21, -35, -55, -82, -80, -64, -24, 27, 36, 23, 3, 10,
+ 35, 61, 55, 40, 35, 35, 19, 6, 12, 4, 1, 3, -12, -3, -2, -4,
+ -4, -14, -23, -30, -37, -58, -83, -84, -58, 8, 37, 33, 11, 3, 20, 46,
+ 62, 55, 50, 28, 16, 12, 15, 9, -4, -9, -9, -4, -5, -7, 2, -7,
+ -28, -35, -31, -36, -67, -90, -86, -23, 28, 38, 25, 5, 13, 34, 58, 58,
+ 69, 50, 15, 10, 20, 16, -3, -14, -14, -2, 1, -12, -3, 3, -20, -36,
+ -39, -26, -46, -81, -98, -61, 6, 27, 30, 16, 12, 25, 50, 57, 66, 74,
+ 31, 4, 16, 21, 8, -13, -21, -10, 8, -5, -11, 6, -8, -31, -40, -29,
+ -30, -66, -93, -84, -22, 17, 22, 26, 16, 20, 43, 56, 56, 70, 60, 17,
+ 8, 18, 15, -10, -26, -21, 6, 7, -12, -1, 1, -20, -33, -34, -31, -51,
+ -79, -92, -52, -6, 9, 19, 23, 21, 40, 57, 59, 60, 72, 43, 17, 13,
+ 18, 3, -23, -32, -5, 14, -7, -11, 7, -12, -26, -31, -37, -46, -66, -85,
+ -67, -21, -5, 3, 16, 22, 37, 54, 59, 55, 60, 58, 30, 16, 13, 11,
+ -15, -34, -23, 9, 7, -12, -2, -4, -19, -16, -31, -49, -64, -76, -72, -35,
+ -12, -14, 0, 15, 34, 53, 60, 58, 53, 57, 43, 30, 18, 12, -4, -27,
+ -28, -8, 14, -3, -9, -2, -13, -9, -17, -49, -66, -70, -69, -44, -15, -19,
+ -11, 2, 21, 53, 64, 68, 55, 48, 44, 36, 28, 15, -1, -18, -23, -19,
+ -4, 5, -3, 1, -9, -7, -1, -35, -70, -74, -70, -50, -21, -14, -22, -7,
+ -1, 39, 66, 77, 69, 46, 38, 36, 38, 22, 5, -12, -16, -12, -17, -8,
+ -5, 2, 1, -6, 5, -13, -64, -78, -73, -60, -31, -14, -17, -16, -10, 7,
+ 61, 79, 81, 57, 38, 28, 32, 24, 9, -4, -10, -4, -11, -20, -13, -2,
+ 11, 4, 4, -2, -41, -76, -76, -69, -43, -22, -12, -17, -14, -14, 25, 74,
+ 92, 79, 47, 31, 26, 26, 11, 3, -5, 0, 0, -20, -26, -11, 9, 14,
+ 9, 4, -24, -61, -76, -74, -53, -30, -13, -8, -12, -25, -8, 51, 90, 93,
+ 63, 42, 21, 18, 13, 6, 2, 1, 8, -12, -30, -27, -2, 14, 18, 11,
+ -13, -48, -68, -79, -70, -44, -19, -2, -5, -21, -31, 18, 77, 100, 81, 55,
+ 29, 7, 8, 6, 7, 4, 14, 0, -26, -34, -13, 9, 16, 17, 1, -35,
+ -58, -70, -82, -62, -29, -2, 1, -14, -36, -15, 50, 89, 95, 71, 46, 5,
+ -6, 4, 11, 3, 11, 14, -12, -31, -22, -2, 8, 16, 16, -15, -53, -56,
+ -80, -81, -41, -5, 9, -3, -30, -34, 17, 73, 97, 86, 63, 25, -12, -6,
+ 11, 13, 1, 15, 4, -19, -25, -5, 2, 9, 19, 10, -39, -48, -61, -95,
+ -67, -17, 12, 8, -23, -43, -9, 49, 85, 91, 76, 50, 1, -23, 2, 22,
+ 5, 2, 14, -5, -23, -12, 0, -2, 13, 17, -15, -48, -43, -83, -88, -38,
+ 5, 17, -11, -41, -28, 27, 67, 83, 82, 65, 29, -21, -18, 21, 19, -7,
+ 3, 6, -8, -14, 1, 0, 0, 13, 2, -34, -42, -59, -99, -63, -12, 17,
+ 0, -35, -42, 1, 53, 69, 79, 72, 53, -1, -34, 2, 32, 3, -8, 1,
+ 2, -2, -3, 8, -2, 3, 7, -18, -40, -39, -76, -81, -35, 9, 17, -22,
+ -46, -24, 34, 59, 68, 74, 66, 27, -26, -22, 31, 24, -10, -11, 0, 14,
+ 1, 5, 8, -5, -2, -10, -34, -35, -48, -77, -59, -13, 20, -4, -37, -35,
+ 8, 47, 55, 68, 74, 49, -4, -34, 10, 39, 1, -13, -11, 14, 14, 3,
+ 20, 6, -9, -14, -29, -37, -28, -56, -66, -42, 9, 9, -25, -38, -14, 27,
+ 45, 54, 72, 61, 21, -25, -14, 31, 19, -10, -15, -2, 22, 6, 22, 24,
+ -4, -20, -28, -38, -24, -28, -54, -57, -20, 14, -10, -29, -26, 2, 29, 39,
+ 61, 66, 39, -6, -25, 16, 30, 0, -16, -8, 12, 13, 18, 38, 10, -20,
+ -36, -34, -31, -16, -33, -56, -42, 0, 0, -21, -22, -12, 11, 25, 49, 68,
+ 53, 14, -20, -3, 29, 15, -11, -12, 3, 13, 13, 42, 34, -12, -39, -37,
+ -27, -22, -18, -44, -50, -21, 3, -12, -15, -18, -5, 9, 27, 60, 60, 32,
+ -6, -12, 21, 25, -4, -12, -2, 7, 8, 33, 53, 8, -37, -41, -25, -22,
+ -16, -27, -47, -34, -10, -10, -15, -15, -15, -5, 5, 41, 63, 44, 12, -11,
+ 10, 32, 10, -14, -8, 8, 5, 19, 53, 34, -24, -43, -25, -14, -15, -19,
+ -35, -35, -20, -12, -8, -14, -17, -19, -13, 19, 55, 53, 22, -8, 4, 31,
+ 26, -8, -13, 6, 10, 7, 39, 50, -2, -41, -31, -10, -13, -23, -31, -33,
+ -24, -15, -7, -13, -16, -22, -23, -6, 38, 55, 34, 1, -1, 23, 34, 9,
+ -18, -3, 14, 9, 20, 51, 24, -28, -37, -6, 2, -20, -30, -27, -21, -22,
+ -6, -12, -17, -21, -32, -27, 9, 49, 43, 12, -4, 14, 34, 24, -9, -12,
+ 12, 19, 13, 30, 37, -3, -35, -15, 12, -10, -31, -30, -15, -18, -13, -3,
+ -19, -20, -31, -35, -17, 28, 44, 22, 0, 7, 28, 27, 5, -15, 1, 20,
+ 20, 17, 28, 19, -21, -23, 12, 8, -22, -32, -20, -8, -15, 0, -13, -23,
+ -25, -43, -36, 4, 37, 30, 11, 4, 22, 28, 15, 0, -10, 9, 23, 14,
+ 11, 24, 5, -21, 2, 17, -8, -27, -27, -7, -10, -6, -1, -20, -26, -39,
+ -53, -20, 23, 36, 17, 7, 14, 28, 16, 12, -3, 2, 19, 16, 2, 14,
+ 19, -8, -5, 17, 4, -15, -26, -10, -4, -12, 1, -8, -23, -38, -58, -41,
+ 0, 29, 23, 11, 16, 21, 15, 9, 11, -6, 11, 20, 4, 3, 24, 5,
+ -5, 10, 17, -6, -15, -15, 6, -15, -8, 0, -11, -37, -54, -56, -24, 13,
+ 29, 12, 15, 20, 19, 6, 16, 5, -2, 10, 11, -3, 22, 18, 0, 6,
+ 20, 10, -6, -12, 1, -6, -23, 0, 1, -23, -56, -60, -43, -10, 19, 22,
+ 15, 22, 18, 6, 11, 17, -2, -5, 10, 4, 7, 23, 1, 3, 16, 22,
+ 5, -1, 0, 5, -21, -14, 6, -6, -46, -64, -54, -29, 1, 17, 18, 24,
+ 25, 10, 1, 17, 9, -8, -1, 15, 6, 20, 11, 2, 14, 25, 16, 9,
+ 5, 7, -11, -26, -5, 4, -27, -62, -62, -40, -17, 8, 11, 21, 29, 17,
+ -2, 10, 17, -8, -16, 6, 13, 11, 15, 3, 8, 24, 26, 14, 12, 12,
+ 4, -26, -15, 1, -12, -50, -64, -48, -27, -10, 5, 8, 32, 31, 1, -1,
+ 18, 0, -23, -6, 18, 14, 11, 5, 3, 17, 35, 25, 16, 18, 14, -11,
+ -27, -8, -6, -30, -55, -53, -36, -20, -5, 5, 14, 43, 13, -6, 11, 11,
+ -22, -22, 7, 19, 13, 10, 1, 7, 30, 36, 22, 23, 23, 6, -28, -20,
+ -6, -23, -43, -49, -43, -29, -19, 3, 1, 34, 29, -4, 3, 13, -13, -32,
+ -3, 20, 14, 11, 5, 2, 23, 42, 34, 22, 23, 21, -13, -26, -14, -19,
+ -32, -38, -43, -32, -29, -6, 4, 16, 35, 9, -4, 11, 0, -33, -22, 9,
+ 13, 12, 9, 3, 14, 35, 47, 34, 23, 27, 8, -22, -19, -16, -30, -29,
+ -42, -33, -32, -23, 4, 9, 24, 20, -1, 3, 10, -20, -36, -5, 13, 9,
+ 11, 8, 8, 21, 43, 48, 27, 22, 23, -7, -25, -20, -28, -25, -31, -36,
+ -28, -33, -8, 11, 14, 14, 6, -8, 7, -5, -39, -25, 7, 14, 9, 10,
+ 12, 15, 29, 55, 41, 23, 22, 9, -12, -23, -28, -24, -23, -34, -26, -31,
+ -21, 9, 19, 9, 1, -3, -1, 7, -32, -38, -9, 13, 11, 9, 11, 14,
+ 21, 46, 53, 32, 24, 12, -2, -16, -26, -24, -17, -34, -33, -25, -24, -4,
+ 17, 14, -3, -4, -7, 3, -13, -46, -25, 2, 17, 5, 8, 12, 18, 32,
+ 56, 38, 29, 15, 8, -4, -22, -30, -14, -22, -42, -25, -15, -10, 6, 17,
+ 1, -5, -7, -10, -2, -38, -37, -7, 15, 9, 2, 8, 21, 26, 43, 44,
+ 29, 18, 7, 12, -9, -25, -24, -11, -35, -43, -17, -5, 3, 10, 9, -3,
+ -3, -23, -9, -23, -45, -22, 7, 15, 2, 4, 17, 33, 31, 45, 35, 23,
+ 8, 17, 6, -16, -26, -14, -20, -48, -27, -2, 6, 11, 9, -1, 6, -15,
+ -28, -18, -39, -32, -7, 11, 7, 6, 7, 33, 30, 31, 41, 27, 7, 13,
+ 24, -3, -18, -22, -9, -40, -41, -10, 4, 9, 17, 3, 5, -4, -37, -29,
+ -29, -35, -19, 1, 10, 3, 7, 25, 41, 19, 31, 32, 13, 5, 27, 14,
+ -6, -19, -12, -23, -48, -22, 7, 8, 16, 11, 1, 6, -29, -46, -32, -32,
+ -20, -5, 7, 4, 3, 21, 43, 32, 15, 29, 16, 8, 19, 26, 3, -9,
+ -22, -13, -42, -37, -8, 11, 14, 25, 9, 4, -17, -50, -44, -30, -25, -14,
+ -1, 11, 1, 18, 36, 41, 12, 14, 18, 14, 15, 20, 17, 6, -14, -18,
+ -27, -39, -19, 5, 12, 24, 27, 8, -13, -49, -53, -32, -27, -19, -12, 7,
+ 7, 12, 31, 43, 26, 2, 8, 14, 22, 13, 17, 18, 6, -17, -26, -36,
+ -28, -6, 14, 25, 35, 20, -6, -42, -57, -37, -23, -23, -20, 0, 9, 8,
+ 25, 41, 40, 7, -4, 1, 23, 21, 14, 22, 20, -2, -24, -34, -31, -13,
+ 8, 24, 37, 33, 8, -32, -62, -44, -20, -22, -27, -9, 9, 7, 16, 31,
+ 42, 20, -10, -13, 10, 26, 7, 13, 25, 18, -11, -35, -39, -20, 0, 17,
+ 37, 37, 19, -17, -58, -55, -26, -18, -25, -21, 0, 14, 12, 20, 38, 35,
+ 0, -19, -9, 24, 19, 3, 21, 31, 17, -24, -42, -30, -3, 13, 34, 42,
+ 28, -2, -45, -62, -38, -22, -19, -20, -12, 12, 17, 11, 29, 42, 18, -16,
+ -20, 3, 24, 2, 4, 26, 36, 0, -38, -45, -13, 12, 27, 41, 34, 14,
+ -27, -62, -55, -30, -19, -15, -16, -2, 18, 11, 14, 37, 31, -6, -22, -12,
+ 15, 10, -10, 12, 36, 30, -19, -46, -33, 11, 24, 28, 35, 28, -5, -44,
+ -65, -44, -23, -11, -9, -8, 5, 14, 10, 25, 37, 14, -17, -18, -2, 14,
+ -7, -6, 23, 43, 10, -33, -38, -9, 24, 24, 28, 30, 11, -21, -57, -61,
+ -39, -12, -5, -5, -3, 7, 10, 17, 31, 30, -3, -20, -14, 6, 1, -16,
+ 2, 38, 38, -5, -30, -24, 13, 25, 21, 28, 15, 1, -34, -64, -62, -23,
+ 0, 2, -1, -1, 5, 14, 24, 33, 14, -12, -23, -4, 7, -18, -18, 18,
+ 43, 25, -9, -22, -2, 21, 19, 24, 20, 11, -13, -47, -69, -46, -7, 5,
+ 6, -1, -4, 9, 21, 31, 25, 5, -15, -20, 3, -8, -33, -7, 29, 37,
+ 20, -10, -10, 9, 15, 17, 14, 12, 1, -23, -55, -70, -30, 5, 13, 2,
+ -8, -1, 15, 25, 30, 15, -1, -20, -8, -3, -31, -28, 8, 31, 41, 15,
+ -6, 0, 9, 14, 12, 9, 8, -10, -28, -63, -55, -12, 17, 11, -7, -13,
+ 8, 22, 26, 19, 9, -7, -13, -5, -23, -39, -10, 17, 41, 38, 8, 0,
+ 5, 7, 12, 5, 7, -6, -8, -39, -60, -35, 7, 19, 6, -10, -6, 15,
+ 26, 22, 15, 9, -8, -13, -24, -45, -29, -1, 29, 48, 30, 2, 6, 5,
+ 9, 5, -1, -5, -4, -13, -51, -51, -16, 20, 13, 0, -11, 7, 25, 22,
+ 18, 17, 10, -8, -22, -50, -43, -13, 15, 46, 42, 16, 7, 8, 7, 7,
+ -1, -6, -10, -4, -27, -45, -36, 5, 16, 7, -5, -5, 20, 22, 19, 19,
+ 22, 7, -15, -43, -62, -29, 3, 35, 43, 27, 11, 9, 8, 4, 2, -9,
+ -13, -7, -15, -30, -43, -16, 12, 13, 4, -8, 12, 24, 17, 16, 24, 25,
+ -3, -38, -72, -52, -9, 25, 42, 30, 21, 8, 14, 4, 6, -3, -13, -12,
+ -13, -18, -36, -34, 3, 14, 9, -9, 5, 26, 18, 13, 26, 34, 13, -31,
+ -69, -68, -16, 19, 35, 29, 22, 6, 16, 3, 2, 6, -5, -15, -20, -19,
+ -21, -34, -17, 8, 16, -2, -3, 24, 27, 16, 23, 34, 32, -10, -56, -80,
+ -45, 6, 29, 29, 22, 10, 14, 13, -4, 6, 7, -8, -27, -27, -18, -20,
+ -28, -8, 14, 8, -7, 11, 29, 21, 17, 25, 35, 16, -36, -77, -67, -14,
+ 25, 30, 22, 11, 10, 19, 5, 2, 6, 5, -18, -34, -25, -13, -23, -19,
+ 4, 13, 0, 7, 24, 32, 24, 22, 31, 30, -12, -62, -76, -41, 9, 28,
+ 24, 15, 6, 18, 16, 6, 6, 7, -7, -32, -37, -16, -18, -24, -8, 11,
+ 7, 7, 20, 31, 35, 25, 24, 33, 9, -40, -72, -58, -16, 17, 27, 16,
+ 6, 10, 22, 12, 8, 8, 2, -23, -43, -26, -16, -24, -18, 2, 6, 7,
+ 21, 29, 36, 32, 21, 27, 22, -21, -57, -67, -38, -4, 26, 21, 9, 3,
+ 18, 25, 18, 10, 2, -11, -42, -36, -24, -27, -23, -9, 5, 2, 17, 32,
+ 42, 36, 27, 18, 25, -2, -39, -58, -51, -27, 11, 27, 11, 1, 9, 24,
+ 25, 21, 5, -8, -31, -37, -30, -33, -24, -15, 0, -2, 13, 31, 48, 47,
+ 33, 15, 18, 10, -27, -50, -52, -44, -12, 21, 21, 5, -1, 13, 33, 30,
+ 16, -6, -26, -39, -33, -35, -28, -20, -10, -8, 4, 27, 51, 61, 45, 21,
+ 13, 14, -11, -39, -40, -44, -36, 1, 25, 16, 1, 2, 27, 40, 28, 3,
+ -22, -38, -38, -32, -33, -21, -18, -14, -8, 18, 50, 66, 60, 27, 7, 12,
+ -3, -31, -36, -37, -46, -27, 18, 26, 5, -3, 8, 35, 43, 16, -14, -36,
+ -43, -32, -32, -25, -16, -23, -14, 6, 46, 64, 74, 49, 9, 4, 7, -23,
+ -37, -34, -41, -44, -8, 31, 19, -5, 0, 21, 47, 33, -2, -33, -43, -43,
+ -32, -29, -14, -22, -23, -6, 34, 62, 75, 71, 30, 0, 8, -13, -37, -34,
+ -35, -45, -34, 18, 31, 5, -5, 7, 35, 44, 12, -23, -45, -49, -40, -29,
+ -18, -18, -27, -15, 22, 57, 74, 80, 57, 15, 4, -1, -39, -34, -34, -40,
+ -46, -4, 25, 13, -3, 2, 22, 44, 25, -10, -38, -44, -50, -34, -20, -14,
+ -31, -21, 5, 47, 63, 81, 76, 38, 8, 9, -30, -45, -35, -36, -43, -20,
+ 9, 14, 5, 3, 7, 36, 32, 3, -32, -43, -50, -40, -28, -13, -24, -28,
+ -2, 35, 56, 73, 86, 58, 23, 21, -10, -49, -45, -33, -39, -25, -3, 5,
+ 5, 8, 5, 18, 32, 17, -19, -45, -49, -41, -35, -22, -19, -31, -12, 28,
+ 52, 59, 76, 74, 41, 31, 10, -39, -58, -41, -32, -27, -5, -3, 3, 8,
+ 8, 10, 24, 22, -4, -39, -52, -42, -35, -30, -18, -28, -22, 20, 53, 52,
+ 60, 73, 62, 43, 31, -18, -56, -61, -35, -28, -9, -6, -3, 3, 9, 10,
+ 12, 18, 8, -23, -53, -50, -31, -35, -24, -28, -26, 3, 48, 55, 52, 59,
+ 66, 57, 46, 7, -37, -67, -53, -24, -11, -4, -6, 0, 3, 13, 10, 7,
+ 10, -6, -38, -58, -36, -30, -30, -26, -26, -11, 33, 60, 56, 49, 59, 67,
+ 58, 32, -15, -58, -69, -34, -14, -8, -6, 1, -4, 7, 8, 2, 4, 4,
+ -21, -54, -49, -30, -30, -28, -29, -18, 13, 53, 60, 50, 44, 63, 61, 49,
+ 11, -33, -71, -49, -19, -9, -10, 5, 2, -1, 4, -1, 4, 5, -5, -38,
+ -55, -40, -28, -21, -25, -26, -2, 40, 61, 56, 39, 53, 66, 54, 33, -4,
+ -55, -63, -29, -18, -12, 3, 11, -4, -4, -9, -3, 4, 4, -18, -49, -49,
+ -35, -18, -18, -25, -16, 24, 51, 60, 42, 43, 66, 57, 42, 21, -23, -63,
+ -44, -26, -18, -10, 13, 9, -8, -18, -17, 5, 5, -4, -35, -47, -42, -24,
+ -11, -20, -21, 5, 36, 56, 53, 37, 60, 59, 40, 34, 11, -34, -52, -33,
+ -21, -15, 1, 21, 2, -19, -33, -10, 8, 3, -20, -42, -41, -33, -14, -16,
+ -18, -7, 21, 43, 54, 39, 47, 61, 44, 31, 27, -4, -41, -47, -28, -23,
+ -9, 11, 15, -9, -34, -34, 1, 10, -2, -30, -38, -34, -18, -15, -17, -10,
+ 10, 27, 43, 42, 42, 53, 54, 36, 24, 14, -15, -42, -36, -32, -22, 1,
+ 13, 7, -26, -48, -24, 11, 10, -14, -35, -32, -19, -16, -15, -11, 5, 18,
+ 31, 34, 41, 48, 51, 46, 28, 26, 8, -26, -36, -33, -35, -12, 7, 12,
+ -8, -45, -47, -9, 13, 5, -24, -32, -17, -14, -16, -11, 6, 14, 20, 26,
+ 27, 47, 49, 49, 34, 25, 22, -6, -31, -27, -39, -30, -10, 13, 6, -28,
+ -57, -31, -3, 12, -7, -28, -19, -8, -21, -18, -2, 18, 17, 17, 19, 34,
+ 47, 53, 42, 34, 30, 13, -22, -20, -30, -44, -32, -4, 15, -7, -45, -49,
+ -18, 4, 10, -14, -18, 0, -11, -26, -7, 15, 23, 10, 10, 20, 34, 51,
+ 49, 38, 41, 30, -8, -28, -15, -39, -47, -28, 5, 10, -26, -55, -34, -9,
+ 10, 3, -13, -4, 1, -21, -19, 3, 25, 13, 5, 9, 18, 36, 54, 39,
+ 40, 46, 16, -27, -17, -23, -47, -47, -18, 9, -2, -47, -51, -23, 0, 4,
+ 0, 1, 9, -11, -20, -9, 20, 23, 4, 2, 8, 20, 45, 46, 38, 53,
+ 41, -13, -30, -19, -36, -52, -40, -9, 5, -23, -53, -35, -6, 4, 3, 6,
+ 10, 5, -16, -17, 6, 30, 12, 0, -4, 9, 32, 47, 43, 55, 57, 16,
+ -27, -30, -28, -44, -52, -31, -6, -8, -43, -43, -15, -1, -1, 8, 10, 13,
+ 2, -18, -11, 21, 23, 6, -5, 0, 19, 33, 41, 56, 67, 44, -5, -34,
+ -35, -32, -46, -47, -27, -7, -30, -44, -23, -2, -2, 3, 7, 14, 18, -1,
+ -19, 4, 20, 16, -5, -9, 10, 27, 30, 46, 65, 63, 26, -22, -42, -34,
+ -41, -46, -40, -18, -25, -39, -28, -4, 1, -1, 5, 10, 24, 19, -8, -6,
+ 11, 20, 4, -13, 2, 22, 24, 36, 59, 70, 51, 5, -39, -39, -43, -47,
+ -45, -31, -30, -39, -33, -7, 1, -2, 1, 4, 19, 25, 5, -5, 1, 12,
+ 13, -12, -12, 18, 25, 21, 46, 68, 69, 36, -17, -39, -44, -51, -43, -33,
+ -35, -41, -38, -15, 8, 0, 0, 0, 13, 26, 19, 5, 0, -1, 10, -2,
+ -14, 5, 25, 19, 29, 54, 71, 59, 9, -31, -43, -56, -50, -32, -38, -47,
+ -42, -26, 8, 10, -3, -3, 7, 20, 23, 16, 8, -5, 3, 2, -17, -6,
+ 22, 20, 18, 40, 66, 71, 37, -13, -36, -52, -61, -38, -32, -47, -51, -38,
+ -7, 19, 6, -6, 4, 14, 19, 21, 19, 2, -5, 0, -13, -12, 14, 21,
+ 13, 27, 53, 71, 57, 12, -25, -42, -61, -54, -33, -38, -52, -50, -22, 13,
+ 17, -4, 1, 16, 17, 19, 25, 11, -2, -2, -11, -18, 6, 21, 15, 18,
+ 43, 66, 67, 34, -7, -30, -49, -58, -42, -36, -42, -54, -36, -2, 20, 4,
+ -4, 11, 16, 17, 26, 17, 4, 1, -8, -22, -8, 17, 16, 17, 27, 55,
+ 66, 48, 10, -25, -36, -49, -52, -42, -39, -47, -46, -18, 13, 14, -1, 3,
+ 13, 19, 27, 18, 2, 5, 1, -14, -17, 6, 13, 16, 26, 44, 64, 54,
+ 27, -15, -30, -33, -49, -50, -43, -44, -45, -30, -1, 13, 3, 6, 10, 22,
+ 30, 21, 3, 2, 2, -3, -18, -9, 8, 11, 23, 35, 55, 58, 37, 1,
+ -25, -18, -33, -51, -48, -46, -41, -30, -17, 6, 3, 7, 9, 16, 30, 27,
+ 9, 3, 3, 1, -10, -18, 0, 3, 12, 37, 46, 52, 40, 15, -23, -16,
+ -14, -39, -48, -48, -45, -31, -20, -7, 1, 4, 14, 13, 21, 26, 16, 2,
+ 1, 1, 1, -16, -12, 1, 5, 29, 50, 47, 39, 21, -11, -21, -3, -23,
+ -41, -45, -47, -37, -21, -13, -6, 1, 16, 20, 22, 22, 18, 10, 2, 1,
+ 6, -7, -16, -10, 0, 16, 51, 53, 38, 22, -1, -21, -1, -4, -30, -41,
+ -45, -45, -28, -13, -13, -8, 13, 24, 26, 15, 13, 15, 8, -4, 1, -2,
+ -11, -15, -11, 2, 40, 56, 44, 21, 1, -16, -10, 5, -16, -32, -38, -41,
+ -36, -22, -14, -15, 4, 24, 32, 18, 7, 14, 14, 4, -2, -1, -8, -12,
+ -15, -6, 24, 50, 51, 28, 1, -13, -14, 4, 1, -18, -31, -35, -36, -33,
+ -21, -21, -5, 19, 38, 23, 3, 5, 17, 15, 2, -3, -7, -8, -18, -14,
+ 12, 39, 50, 35, 2, -14, -14, -3, 6, -6, -24, -27, -32, -40, -25, -22,
+ -12, 8, 35, 34, 10, 2, 5, 19, 9, -6, -4, -3, -15, -18, 4, 30,
+ 42, 40, 13, -17, -16, -7, 3, 5, -14, -21, -24, -41, -37, -23, -18, -1,
+ 22, 37, 17, 4, -1, 11, 17, 1, -7, -4, -12, -22, -6, 24, 35, 33,
+ 25, -7, -26, -15, 2, 14, 3, -16, -19, -33, -42, -27, -23, -10, 15, 28,
+ 27, 8, 2, 5, 20, 11, -4, -6, -7, -19, -11, 17, 31, 26, 25, 6,
+ -24, -25, -6, 11, 14, -3, -13, -25, -39, -33, -23, -17, 7, 19, 26, 19,
+ 4, 1, 15, 14, -1, -5, -10, -14, -22, 8, 33, 28, 20, 16, -13, -26,
+ -17, 9, 22, 5, -8, -18, -37, -35, -28, -23, -4, 12, 16, 28, 12, 1,
+ 12, 18, 3, -2, -9, -10, -27, -10, 29, 34, 18, 16, 2, -26, -29, -3,
+ 27, 19, -4, -10, -29, -36, -30, -29, -12, 9, 3, 18, 21, 7, 12, 17,
+ 3, -2, -7, -7, -19, -26, 15, 36, 21, 12, 9, -15, -30, -18, 19, 30,
+ 6, -5, -21, -32, -25, -29, -22, 6, 0, 3, 20, 14, 12, 18, 12, 0,
+ -9, -12, -9, -26, -4, 31, 28, 11, 10, -6, -24, -29, 3, 35, 19, -3,
+ -15, -26, -19, -23, -31, -6, 4, -7, 13, 19, 17, 20, 18, 9, -9, -19,
+ -5, -17, -20, 16, 34, 18, 9, 0, -16, -25, -10, 30, 29, 3, -10, -19,
+ -19, -16, -29, -19, 3, -9, -5, 13, 21, 24, 16, 13, 1, -23, -14, -12,
+ -19, -2, 28, 21, 8, 1, -11, -23, -19, 16, 41, 14, -8, -13, -9, -13,
+ -18, -27, -4, -5, -12, -1, 19, 31, 18, 10, 16, -20, -22, -13, -14, -12,
+ 18, 26, 12, 4, -4, -17, -18, -1, 38, 31, -5, -14, -7, -7, -14, -24,
+ -13, -3, -13, -12, 7, 30, 34, 14, 18, -5, -33, -18, -10, -14, 1, 19,
+ 14, 6, -8, -13, -15, -2, 19, 40, 8, -13, -9, -4, -8, -18, -20, -9,
+ -14, -16, -7, 22, 37, 23, 16, 10, -26, -28, -13, -9, -5, 14, 14, 9,
+ -9, -17, -13, -1, 8, 31, 26, -6, -10, -4, -2, -12, -19, -11, -11, -17,
+ -12, 6, 34, 29, 15, 16, -7, -35, -25, -9, -6, 8, 14, 12, 1, -15,
+ -14, 3, 10, 19, 29, 8, -10, -9, 1, -7, -20, -10, -9, -17, -17, -1,
+ 30, 35, 18, 15, 5, -28, -33, -17, -6, -4, 8, 13, 5, -14, -19, 1,
+ 14, 14, 20, 17, 0, -8, -2, -3, -14, -18, -9, -12, -18, -6, 21, 37,
+ 26, 7, 10, -13, -33, -24, -6, -2, 0, 9, 11, -5, -19, -7, 16, 18,
+ 13, 18, 11, -2, -6, -3, -6, -22, -10, -11, -16, -11, 17, 34, 32, 9,
+ 9, 2, -26, -30, -14, -2, -5, 3, 8, 3, -16, -12, 8, 21, 13, 13,
+ 15, 2, -3, -5, -5, -20, -16, -8, -16, -20, 6, 32, 34, 14, -4, 6,
+ -12, -26, -20, -7, -6, -4, 4, 7, -2, -15, 1, 17, 15, 9, 15, 10,
+ 0, -3, -7, -15, -22, -4, -7, -19, -7, 29, 36, 20, -6, -1, 0, -17,
+ -19, -12, -9, -7, -1, 2, 6, -3, -8, 10, 18, 9, 8, 21, 4, -2,
+ -8, -13, -20, -12, -2, -16, -14, 14, 39, 26, -3, -17, 1, -6, -16, -12,
+ -7, -9, -9, 0, 3, 11, -3, 0, 15, 13, 3, 19, 12, -8, -6, -14,
+ -19, -16, 0, -6, -17, 3, 33, 35, 5, -18, -9, 1, -15, -11, -8, -8,
+ -16, -8, 1, 15, 15, 3, 11, 19, 2, 12, 26, 0, -10, -13, -21, -11,
+ 1, -1, -18, -2, 23, 35, 17, -12, -21, -2, -8, -9, -8, -9, -12, -17,
+ -5, 10, 22, 8, 7, 18, 7, -1, 23, 13, -13, -19, -23, -14, 5, 2,
+ -15, -13, 17, 30, 22, -3, -24, -7, -2, -9, -6, -10, -8, -21, -19, 5,
+ 22, 22, 13, 15, 13, -3, 11, 18, -4, -20, -28, -20, 4, 11, -10, -18,
+ 6, 26, 17, 3, -20, -12, -2, -11, -7, -8, -8, -16, -27, -7, 19, 30,
+ 21, 19, 15, 4, 3, 18, 2, -17, -33, -24, 0, 17, 1, -16, -6, 24,
+ 19, 5, -17, -18, 1, -8, -12, -7, -11, -10, -22, -14, 10, 29, 29, 32,
+ 23, 13, 0, 9, 6, -12, -28, -36, -7, 13, 12, -8, -17, 12, 24, 6,
+ -10, -20, 1, 1, -13, -9, -12, -16, -20, -17, 0, 21, 27, 31, 35, 20,
+ 7, 0, 2, -13, -19, -37, -19, 8, 18, 9, -16, -9, 20, 11, -2, -25,
+ -13, 8, -4, -16, -13, -18, -23, -17, 0, 14, 29, 27, 43, 35, 17, -1,
+ -4, -13, -22, -29, -31, -2, 17, 20, -5, -21, 6, 16, 5, -16, -25, 4,
+ 11, -12, -17, -20, -27, -19, -2, 13, 26, 27, 36, 46, 32, 7, -8, -18,
+ -26, -25, -32, -16, 12, 26, 11, -18, -11, 4, 13, -1, -27, -12, 14, 2,
+ -21, -23, -31, -26, -11, 10, 24, 30, 29, 43, 50, 24, -4, -16, -34, -28,
+ -28, -27, -1, 27, 24, -5, -21, -12, 6, 16, -13, -28, 1, 13, -9, -23,
+ -33, -32, -18, 2, 24, 34, 33, 34, 50, 49, 12, -11, -34, -37, -28, -25,
+ -14, 14, 28, 10, -10, -25, -9, 21, 15, -27, -15, 12, 2, -18, -33, -36,
+ -24, -7, 13, 30, 39, 42, 35, 54, 36, 1, -29, -45, -35, -26, -17, -1,
+ 20, 19, 2, -23, -30, 1, 30, -5, -32, 1, 7, -8, -27, -37, -25, -12,
+ -1, 23, 37, 51, 38, 41, 49, 16, -15, -41, -40, -31, -21, -11, 4, 19,
+ 15, -8, -33, -19, 22, 20, -21, -13, 2, -6, -17, -36, -32, -11, -8, 9,
+ 28, 48, 54, 36, 48, 30, 3, -30, -41, -34, -24, -15, -6, 2, 17, 8,
+ -19, -37, 0, 31, 3, -20, -6, -4, -7, -31, -35, -9, -3, -4, 16, 37,
+ 62, 44, 41, 33, 13, -11, -36, -39, -29, -21, -11, -11, 6, 14, -2, -28,
+ -24, 15, 22, -5, -10, -11, -10, -20, -35, -13, 2, -5, 2, 21, 55, 64,
+ 46, 37, 19, 2, -23, -36, -28, -23, -17, -18, -17, 10, 11, -12, -32, -7,
+ 23, 16, -7, -14, -17, -8, -27, -23, 1, 1, 0, 6, 31, 63, 60, 46,
+ 21, 7, -12, -29, -24, -18, -24, -23, -27, -11, 11, 5, -16, -19, 11, 21,
+ 4, -9, -21, -15, -17, -30, -5, 7, 2, -1, 9, 48, 65, 59, 30, 13,
+ -4, -25, -19, -6, -22, -33, -32, -31, -3, 7, -3, -20, -4, 14, 11, -1,
+ -11, -19, -13, -20, -16, 9, 7, 2, -3, 27, 60, 69, 44, 12, 7, -18,
+ -20, 1, -4, -35, -38, -34, -22, -9, 4, -2, -11, 8, 8, 2, -6, -19,
+ -23, -14, -16, 3, 13, 2, 2, 12, 47, 65, 62, 22, 10, -3, -21, -9,
+ 9, -17, -46, -40, -34, -23, -6, 4, -1, 3, 7, 2, -4, -13, -25, -18,
+ -11, -4, 18, 3, -2, 5, 30, 58, 66, 39, 12, 9, -10, -18, 8, 5,
+ -41, -49, -38, -33, -18, -4, 2, 7, 8, 2, -7, -12, -18, -23, -12, -6,
+ 18, 15, -8, 0, 21, 44, 62, 48, 22, 14, 7, -16, -7, 18, -18, -52,
+ -44, -42, -32, -18, -1, 12, 10, 6, -8, -20, -11, -18, -19, -10, 14, 24,
+ 2, -5, 14, 34, 57, 51, 27, 19, 20, -1, -13, 15, -1, -42, -45, -49,
+ -38, -28, -15, 13, 19, 10, -1, -23, -16, -11, -24, -10, 6, 21, 14, -5,
+ 3, 24, 48, 58, 29, 17, 24, 18, -6, 4, 8, -28, -38, -46, -50, -36,
+ -29, 3, 22, 15, 4, -18, -31, -7, -20, -17, 5, 11, 18, 4, -2, 15,
+ 37, 58, 35, 11, 26, 31, 11, -2, 6, -13, -32, -39, -55, -45, -38, -17,
+ 21, 23, 11, -10, -31, -18, -11, -25, 1, 9, 14, 15, 0, 7, 26, 49,
+ 49, 13, 10, 33, 26, 8, 4, -5, -25, -35, -46, -53, -41, -35, 5, 24,
+ 17, 0, -25, -26, -14, -24, -9, 6, 5, 17, 6, 6, 20, 38, 55, 30,
+ 3, 25, 38, 18, 10, -4, -16, -30, -42, -51, -46, -41, -16, 21, 23, 14,
+ -16, -30, -16, -17, -17, 0, 2, 12, 16, 3, 17, 28, 46, 49, 14, 13,
+ 39, 30, 17, 4, -9, -20, -38, -49, -50, -50, -34, 4, 21, 20, 4, -29,
+ -23, -15, -15, -8, -3, 7, 19, 8, 9, 26, 35, 47, 29, 6, 29, 35,
+ 26, 13, -5, -18, -29, -42, -49, -51, -50, -16, 11, 23, 18, -17, -34, -14,
+ -15, -9, -10, -2, 17, 14, 5, 21, 33, 44, 38, 14, 23, 37, 30, 20,
+ 6, -8, -26, -34, -47, -52, -54, -34, 0, 16, 19, 5, -29, -20, -13, -10,
+ -9, -10, 4, 19, 11, 13, 29, 37, 36, 22, 22, 39, 32, 23, 10, 2,
+ -18, -32, -40, -54, -56, -49, -23, 8, 17, 11, -15, -26, -11, -13, -9, -15,
+ -11, 14, 17, 10, 23, 34, 36, 24, 21, 35, 42, 26, 12, 2, -4, -23,
+ -31, -47, -57, -50, -33, -7, 17, 11, -2, -18, -12, -12, -11, -10, -21, -6,
+ 18, 19, 21, 33, 35, 28, 23, 34, 51, 40, 12, -2, 1, -9, -27, -43,
+ -59, -53, -39, -23, 4, 15, 1, -10, -14, -9, -8, -10, -22, -18, 5, 19,
+ 16, 27, 34, 28, 23, 27, 47, 53, 27, -3, -4, -1, -13, -33, -53, -57,
+ -45, -31, -13, 14, 4, -4, -11, -9, -9, -11, -19, -28, -16, 10, 24, 23,
+ 35, 24, 26, 26, 38, 60, 44, 2, -13, -3, -5, -19, -44, -58, -49, -33,
+ -26, 1, 14, 1, -4, -5, 0, -7, -14, -29, -26, -11, 20, 27, 30, 32,
+ 21, 27, 34, 59, 58, 22, -11, -10, -6, -10, -29, -55, -53, -38, -34, -16,
+ 12, 9, -5, -8, 5, 1, -16, -31, -32, -28, 0, 26, 26, 33, 23, 24,
+ 33, 49, 61, 37, 3, -15, -8, -11, -19, -43, -56, -44, -34, -25, -2, 17,
+ 5, -11, 2, 12, -2, -23, -32, -35, -23, 14, 26, 27, 35, 23, 32, 45,
+ 58, 47, 19, -5, -9, -10, -16, -27, -46, -48, -41, -34, -18, 11, 20, -6,
+ -10, 12, 9, -18, -34, -38, -29, -7, 17, 27, 32, 30, 30, 46, 52, 51,
+ 28, 6, -8, -9, -15, -24, -32, -41, -45, -40, -30, -1, 23, 10, -12, 2,
+ 17, -2, -31, -39, -32, -18, -6, 18, 29, 38, 32, 45, 54, 54, 33, 11,
+ 2, -9, -11, -19, -32, -33, -41, -45, -40, -18, 16, 19, 2, -6, 13, 12,
+ -20, -43, -35, -21, -18, -5, 21, 35, 36, 46, 58, 52, 38, 17, 9, -5,
+ -9, -13, -29, -32, -28, -41, -43, -36, 0, 22, 18, -4, -3, 17, 2, -33,
+ -43, -25, -18, -16, 4, 27, 38, 47, 64, 57, 40, 18, 10, 5, -7, -10,
+ -22, -39, -24, -30, -42, -39, -22, 13, 28, 14, -9, 3, 17, -16, -51, -36,
+ -17, -23, -18, 8, 35, 50, 66, 68, 43, 23, 12, 13, -1, -11, -17, -32,
+ -27, -22, -40, -38, -37, -10, 22, 34, 1, -10, 8, 6, -39, -48, -27, -19,
+ -25, -10, 18, 49, 66, 78, 54, 26, 17, 16, 3, -7, -15, -25, -29, -12,
+ -32, -37, -35, -28, 3, 38, 26, -7, -4, 11, -15, -46, -42, -26, -23, -24,
+ -2, 34, 66, 81, 70, 30, 19, 21, 10, -5, -11, -25, -29, -12, -20, -37,
+ -33, -39, -17, 25, 46, 6, -11, 2, 0, -29, -44, -41, -30, -27, -17, 12,
+ 58, 79, 84, 46, 19, 22, 19, 2, -7, -26, -35, -12, -1, -29, -33, -39,
+ -36, 3, 46, 31, -11, -6, -1, -14, -38, -46, -39, -32, -22, -5, 40, 76,
+ 88, 64, 23, 22, 30, 12, -8, -20, -39, -22, 0, -13, -29, -33, -43, -20,
+ 24, 49, 13, -12, 2, -6, -26, -45, -45, -39, -32, -15, 19, 68, 85, 77,
+ 32, 22, 35, 27, 0, -18, -36, -38, -6, 3, -17, -29, -44, -37, -2, 40,
+ 34, -8, -6, 3, -18, -44, -47, -44, -43, -21, 3, 49, 76, 80, 53, 21,
+ 35, 39, 15, -18, -35, -42, -23, 2, -3, -19, -33, -42, -23, 16, 46, 16,
+ -8, 2, -6, -37, -45, -47, -51, -33, -8, 31, 68, 74, 66, 33, 35, 45,
+ 36, -3, -33, -40, -34, -7, 5, -8, -18, -35, -39, -13, 32, 32, 3, -1,
+ 5, -26, -46, -50, -52, -44, -20, 15, 59, 68, 69, 50, 32, 42, 48, 21,
+ -26, -42, -42, -24, 2, 2, -8, -20, -38, -35, 6, 33, 17, -2, 5, -6,
+ -41, -55, -57, -46, -33, -6, 40, 64, 62, 63, 45, 38, 54, 40, -4, -42,
+ -50, -40, -11, 6, -2, -8, -24, -41, -19, 17, 28, 10, 0, 1, -26, -52,
+ -64, -51, -40, -23, 19, 54, 56, 61, 60, 38, 52, 55, 24, -30, -50, -47,
+ -27, 4, 8, -6, -11, -30, -36, -6, 19, 25, 4, 1, -9, -38, -64, -61,
+ -42, -36, 0, 44, 55, 51, 66, 50, 49, 62, 46, -5, -48, -51, -40, -11,
+ 11, 4, -14, -15, -36, -25, 1, 19, 15, -1, -2, -18, -53, -69, -48, -42,
+ -20, 21, 51, 45, 56, 62, 51, 60, 59, 23, -32, -53, -49, -28, 5, 17,
+ -12, -18, -22, -32, -12, 9, 20, 1, -6, -5, -29, -70, -62, -48, -32, 2,
+ 36, 45, 44, 62, 62, 60, 64, 47, -10, -45, -54, -42, -11, 21, 5, -19,
+ -18, -23, -20, -1, 15, 4, -6, -2, -6, -51, -72, -57, -44, -13, 19, 40,
+ 41, 51, 65, 66, 69, 63, 14, -32, -47, -50, -30, 10, 14, -12, -16, -18,
+ -16, -14, 7, 8, -6, -8, -1, -21, -65, -67, -54, -29, 1, 26, 38, 44,
+ 53, 69, 77, 73, 37, -17, -41, -46, -37, -10, 13, -1, -11, -14, -14, -10,
+ -6, 9, -5, -6, -11, -3, -43, -67, -68, -42, -15, 12, 27, 40, 47, 65,
+ 80, 83, 55, 7, -34, -43, -34, -22, -5, 2, -3, -2, -13, -10, -11, 3,
+ -2, -4, -13, -5, -15, -51, -72, -63, -31, -3, 16, 29, 42, 55, 78, 91,
+ 68, 25, -11, -40, -32, -22, -21, -9, -1, 8, -1, -19, -11, -3, 1, -5,
+ -11, -12, -3, -29, -58, -70, -48, -18, 6, 15, 35, 50, 68, 89, 84, 37,
+ 11, -27, -38, -19, -20, -23, -8, 10, 18, -10, -19, -8, 4, 0, -11, -14,
+ -7, -20, -42, -63, -60, -37, -4, 7, 23, 41, 67, 82, 90, 53, 19, -4,
+ -34, -23, -20, -31, -22, 5, 25, 8, -17, -20, 0, 10, -5, -20, -9, -12,
+ -31, -47, -60, -53, -26, -3, 12, 32, 58, 81, 85, 70, 27, 9, -19, -26,
+ -19, -28, -31, -8, 24, 21, -2, -26, -11, 14, 10, -20, -18, -8, -24, -33,
+ -53, -56, -44, -23, 3, 22, 44, 77, 85, 74, 40, 17, -3, -21, -21, -24,
+ -36, -25, 11, 22, 15, -13, -28, 5, 23, 0, -28, -12, -19, -26, -42, -56,
+ -48, -39, -17, 12, 34, 62, 84, 73, 52, 26, 9, -12, -21, -22, -31, -30,
+ -1, 15, 16, 6, -25, -14, 23, 19, -17, -21, -13, -24, -34, -54, -44, -39,
+ -36, -9, 27, 46, 79, 79, 59, 38, 16, -2, -17, -25, -25, -27, -10, 5,
+ 10, 15, -4, -24, 5, 29, 5, -24, -18, -19, -28, -48, -50, -35, -38, -28,
+ 10, 33, 62, 82, 62, 46, 27, 4, -8, -23, -24, -25, -15, -3, 0, 8,
+ 6, -12, -9, 22, 25, -6, -21, -22, -28, -45, -53, -39, -30, -37, -11, 20,
+ 43, 75, 66, 53, 41, 10, -8, -16, -25, -23, -15, -2, -4, -5, 4, 1,
+ -7, 8, 29, 19, -9, -21, -24, -42, -55, -48, -30, -31, -19, 5, 23, 61,
+ 74, 58, 53, 26, -7, -11, -18, -25, -14, 0, 1, -16, -8, 4, 0, 3,
+ 20, 28, 11, -16, -19, -38, -58, -55, -35, -27, -16, -1, 5, 32, 63, 61,
+ 56, 44, 3, -17, -13, -22, -19, -4, 5, -8, -21, -6, 7, 8, 12, 25,
+ 25, 2, -17, -26, -54, -64, -47, -32, -11, 5, 3, 16, 40, 60, 58, 56,
+ 26, -16, -19, -16, -20, -8, 0, -4, -20, -22, 1, 12, 9, 17, 30, 20,
+ -2, -15, -42, -68, -57, -44, -19, 11, 6, 10, 19, 42, 58, 58, 45, 6,
+ -23, -18, -13, -13, -3, -3, -10, -26, -14, 9, 15, 12, 26, 27, 10, -7,
+ -25, -61, -68, -54, -36, 10, 15, 13, 16, 19, 42, 55, 52, 31, -9, -25,
+ -18, -15, -7, -3, -9, -23, -26, -2, 15, 19, 19, 26, 18, 7, -10, -41,
+ -72, -60, -51, -8, 25, 22, 20, 13, 19, 45, 51, 44, 19, -15, -28, -15,
+ -7, -4, -9, -19, -28, -14, 6, 18, 18, 24, 22, 12, 1, -17, -55, -67,
+ -56, -35, 19, 33, 30, 20, 9, 23, 44, 48, 39, 6, -22, -25, -9, -8,
+ -9, -15, -29, -21, -3, 10, 16, 20, 23, 13, 7, -4, -31, -63, -61, -50,
+ -11, 33, 37, 30, 12, 7, 24, 44, 48, 28, -4, -28, -14, -4, -14, -14,
+ -27, -27, -8, 5, 13, 15, 19, 19, 11, 3, -12, -44, -64, -58, -31, 17,
+ 40, 39, 24, 8, 3, 30, 46, 42, 16, -18, -21, -6, -16, -18, -26, -32,
+ -15, 1, 6, 10, 10, 15, 12, 10, -3, -23, -51, -63, -50, -4, 34, 41,
+ 33, 17, -4, 10, 35, 42, 32, 5, -15, -8, -10, -18, -21, -30, -22, 0,
+ 3, -2, -2, 6, 5, 4, 3, -7, -25, -45, -45, -18, 25, 33, 32, 21,
+ 7, 8, 20, 30, 31, 20, 3, -7, -10, -14, -17, -23, -29, -12, 6, -2,
+ -11, -11, -4, 2, 3, -7, -10, -27, -33, -21, 13, 27, 23, 19, 8, 15,
+ 17, 18, 21, 23, 19, 2, -12, -10, -9, -15, -27, -28, -2, 9, -8, -18,
+ -17, -4, 9, -6, -7, -10, -17, -13, 2, 21, 20, 14, 4, 15, 25, 15,
+ 11, 14, 19, 13, -13, -17, -6, -5, -20, -36, -23, 4, 6, -18, -28, -20,
+ 6, 6, 0, 3, 5, 5, 28, 31, 31, 49, 55, 35, 11, 27, 26, 4,
+ 7, 11, 31, 54, 38, 26, 34, 35, 20, -10, -32, -43, -47, -43, -20, -7,
+ -37, -55, -62, -61, -63, -34, -21, -35, -28, -10, 15, 24, 23, 5, -31, -38,
+ -6, 23, 19, 15, 24, 20, 31, 57, 54, 28, 13, 33, 20, 1, 4, 17,
+ 38, 44, 33, 31, 43, 36, 10, -14, -34, -53, -53, -46, -22, -22, -38, -46,
+ -54, -60, -58, -29, -25, -39, -29, -12, 11, 25, 27, 6, -31, -33, -3, 27,
+ 32, 21, 13, 16, 38, 60, 53, 26, 18, 28, 11, -2, 8, 26, 37, 34,
+ 36, 42, 47, 31, 6, -14, -41, -61, -54, -49, -26, -30, -41, -40, -44, -54,
+ -48, -23, -28, -41, -33, -7, 14, 26, 29, 3, -32, -27, 6, 33, 35, 18,
+ 5, 21, 45, 61, 49, 25, 30, 22, 0, -5, 9, 37, 39, 27, 33, 47,
+ 50, 31, 1, -22, -51, -65, -59, -45, -31, -40, -36, -29, -35, -49, -41, -28,
+ -39, -44, -26, -8, 6, 27, 31, -5, -31, -18, 14, 33, 31, 17, 4, 25,
+ 48, 57, 45, 32, 27, 9, -6, -5, 14, 43, 36, 29, 39, 51, 50, 31,
+ 0, -32, -65, -73, -62, -37, -36, -46, -36, -23, -26, -37, -32, -35, -46, -42,
+ -22, -11, 2, 30, 28, -8, -29, -12, 22, 33, 32, 15, 4, 25, 49, 58,
+ 50, 36, 20, 2, -9, -3, 21, 43, 37, 32, 44, 55, 53, 33, -7, -42,
+ -67, -72, -64, -43, -43, -46, -35, -17, -17, -24, -31, -40, -47, -39, -18, -15,
+ 0, 33, 22, -14, -22, 5, 29, 29, 28, 11, 7, 23, 49, 54, 50, 37,
+ 13, -6, -11, -6, 25, 44, 38, 26, 40, 57, 54, 28, -12, -48, -70, -73,
+ -66, -43, -43, -43, -29, -12, -15, -16, -32, -48, -51, -38, -24, -19, 4, 31,
+ 12, -16, -14, 21, 34, 24, 24, 13, 10, 27, 49, 53, 53, 33, 6, -9,
+ -16, -4, 33, 48, 37, 24, 45, 61, 54, 23, -15, -60, -76, -76, -60, -48,
+ -45, -38, -26, -11, -3, -5, -33, -49, -52, -35, -25, -21, 7, 24, 1, -15,
+ -1, 34, 30, 23, 29, 17, 5, 26, 49, 55, 53, 26, -3, -16, -16, 4,
+ 38, 43, 33, 33, 49, 59, 45, 19, -18, -63, -78, -79, -58, -50, -39, -31,
+ -21, -11, -2, -3, -30, -49, -51, -35, -29, -20, 8, 12, -10, -11, 17, 37,
+ 27, 29, 29, 13, 2, 33, 56, 55, 38, 18, -7, -19, -17, 13, 40, 42,
+ 33, 35, 52, 58, 40, 10, -28, -68, -84, -78, -56, -47, -36, -30, -17, -7,
+ 5, -4, -30, -49, -51, -34, -30, -18, 10, 1, -18, -9, 30, 39, 26, 32,
+ 28, 9, 7, 38, 51, 45, 35, 16, -13, -28, -11, 27, 41, 41, 34, 45,
+ 58, 54, 29, 7, -33, -69, -80, -78, -59, -43, -31, -24, -15, -3, 9, -4,
+ -29, -51, -51, -33, -27, -8, 8, -13, -24, -1, 40, 41, 29, 31, 22, 7,
+ 15, 46, 48, 38, 33, 11, -19, -28, -7, 26, 42, 36, 39, 54, 54, 48,
+ 20, 3, -39, -68, -79, -78, -54, -37, -32, -27, -16, 5, 11, -6, -31, -50,
+ -49, -33, -24, -3, -3, -29, -26, 13, 44, 36, 30, 32, 17, 7, 28, 43,
+ 37, 31, 28, 4, -17, -27, -5, 24, 46, 43, 48, 56, 50, 41, 20, -1,
+ -47, -64, -82, -78, -48, -35, -34, -26, -14, 6, 9, -10, -31, -46, -43, -33,
+ -21, 1, -16, -38, -15, 24, 38, 35, 44, 33, 10, 15, 37, 43, 30, 22,
+ 18, 4, -20, -29, 0, 30, 43, 48, 54, 52, 46, 35, 19, -9, -41, -60,
+ -83, -73, -44, -29, -37, -27, -12, 6, 8, -10, -28, -45, -43, -25, -9, -3,
+ -33, -43, -4, 32, 35, 37, 49, 24, 7, 26, 47, 35, 17, 11, 14, 3,
+ -21, -30, 6, 30, 44, 60, 56, 44, 37, 33, 15, -11, -40, -63, -82, -61,
+ -36, -33, -39, -26, -13, 0, 4, -9, -29, -42, -37, -18, -7, -13, -39, -34,
+ 2, 30, 34, 45, 49, 16, 11, 37, 45, 26, 11, 8, 9, -1, -26, -25,
+ 17, 31, 46, 62, 52, 42, 29, 26, 15, -12, -45, -64, -71, -48, -34, -35,
+ -33, -27, -16, 1, 2, -10, -23, -41, -32, -12, -6, -29, -46, -28, 12, 26,
+ 36, 54, 43, 10, 23, 52, 43, 18, -2, 5, 5, -7, -25, -11, 19, 22,
+ 49, 61, 50, 40, 24, 20, 15, -10, -47, -62, -62, -45, -34, -30, -30, -23,
+ -16, -6, -1, -8, -25, -38, -29, -9, -10, -39, -42, -19, 5, 23, 48, 57,
+ 33, 7, 32, 57, 39, 8, -7, 3, -2, -16, -16, 1, 20, 22, 48, 55,
+ 46, 39, 17, 16, 17, -9, -48, -58, -54, -40, -37, -28, -26, -22, -23, -5,
+ 2, -11, -28, -37, -27, -10, -18, -44, -35, -18, 3, 31, 54, 52, 25, 13,
+ 45, 61, 29, -4, -10, 0, -5, -16, -8, 4, 21, 21, 50, 54, 45, 31,
+ 4, 20, 18, -15, -43, -48, -48, -39, -33, -28, -25, -22, -21, 0, -1, -19,
+ -29, -29, -22, -11, -29, -42, -30, -17, 3, 38, 61, 46, 24, 25, 53, 58,
+ 20, -10, -9, -5, -16, -12, 4, 11, 22, 17, 48, 51, 43, 16, 2, 18,
+ 13, -15, -35, -46, -43, -38, -31, -23, -27, -24, -13, 3, -8, -25, -29, -27,
+ -22, -18, -36, -38, -31, -19, 6, 46, 60, 36, 24, 33, 56, 44, 10, -8,
+ -9, -12, -24, -7, 14, 23, 18, 11, 45, 47, 39, 13, 5, 16, 1, -19,
+ -22, -39, -45, -45, -31, -20, -24, -16, -6, -3, -19, -24, -25, -26, -22, -24,
+ -39, -35, -25, -13, 8, 54, 64, 36, 29, 41, 56, 36, 5, -12, -11, -14,
+ -26, -6, 24, 33, 7, 12, 45, 44, 30, 13, 10, 17, -4, -17, -16, -34,
+ -46, -50, -30, -20, -23, -12, 1, -11, -26, -27, -24, -21, -19, -34, -48, -32,
+ -23, -10, 13, 66, 65, 33, 32, 48, 55, 25, 0, -8, -1, -18, -36, -4,
+ 40, 33, -1, 17, 37, 35, 25, 10, 14, 10, -13, -15, -9, -26, -46, -51,
+ -32, -18, -15, -4, 3, -17, -31, -28, -25, -20, -26, -48, -48, -27, -20, -13,
+ 19, 71, 61, 28, 33, 56, 50, 12, -8, -2, 5, -24, -41, 2, 52, 29,
+ -1, 24, 36, 26, 16, 14, 19, 6, -19, -12, 1, -21, -49, -50, -28, -12,
+ -3, 2, -2, -25, -32, -29, -24, -14, -31, -61, -44, -17, -15, -9, 28, 72,
+ 61, 25, 38, 61, 41, 7, -7, 4, 3, -32, -36, 9, 45, 21, 4, 30,
+ 33, 15, 11, 18, 17, -1, -18, -7, -4, -22, -47, -45, -24, -6, 2, 5,
+ -7, -27, -34, -28, -21, -14, -42, -69, -40, -11, -16, -3, 41, 68, 53, 29,
+ 48, 61, 32, 0, -5, 8, 2, -33, -28, 9, 31, 16, 16, 34, 22, 0,
+ 10, 24, 10, -9, -19, -6, -8, -26, -38, -34, -20, -10, 1, 11, -9, -33,
+ -31, -32, -25, -18, -50, -65, -40, -15, -8, 13, 47, 65, 50, 33, 54, 62,
+ 24, -2, 2, 12, -6, -31, -20, 12, 21, 10, 28, 34, 9, -5, 20, 20,
+ -2, -13, -10, -4, -18, -33, -26, -16, -19, -14, 6, 8, -14, -31, -32, -29,
+ -29, -31, -51, -69, -47, -12, 2, 21, 49, 56, 43, 45, 62, 54, 16, -2,
+ 7, 9, -13, -22, -4, 12, 7, 13, 37, 33, 7, -4, 23, 9, -8, -8,
+ -2, -8, -33, -38, -7, -1, -22, -19, 11, 7, -21, -29, -29, -29, -31, -32,
+ -55, -80, -49, -7, 16, 31, 43, 45, 44, 56, 66, 45, 12, 2, 10, 3,
+ -18, -13, 7, 9, -2, 17, 38, 22, 1, 5, 17, 4, -14, -12, -1, -11,
+ -43, -38, 6, 5, -22, -15, 12, 0, -23, -26, -28, -31, -32, -36, -60, -82,
+ -46, 3, 24, 35, 38, 41, 46, 59, 62, 41, 13, -1, 3, -6, -18, 3,
+ 22, 2, -9, 20, 36, 18, 10, 7, 4, -5, -17, -9, -2, -18, -55, -30,
+ 17, 6, -20, -10, 6, -5, -16, -26, -32, -27, -30, -42, -69, -84, -41, 13,
+ 31, 42, 37, 38, 45, 63, 65, 41, 12, 3, 1, -18, -10, 23, 27, -2,
+ -12, 17, 36, 26, 13, 4, -2, -5, -14, -14, -11, -26, -54, -19, 21, 8,
+ -16, -8, 6, -7, -20, -30, -33, -24, -33, -50, -74, -82, -32, 18, 34, 42,
+ 38, 34, 50, 69, 58, 34, 16, 7, -9, -29, -2, 41, 32, -7, -15, 11,
+ 34, 30, 9, 2, -3, -7, -23, -21, -15, -30, -52, -10, 18, 10, -8, -4,
+ 5, -4, -25, -33, -26, -22, -42, -59, -79, -72, -20, 23, 36, 41, 37, 34,
+ 54, 74, 53, 22, 17, 15, -17, -34, 10, 52, 37, -8, -11, 12, 33, 23,
+ 8, 4, -1, -16, -31, -25, -18, -38, -49, -3, 19, 11, -4, 0, 7, -8,
+ -34, -31, -19, -26, -52, -62, -79, -55, -7, 23, 41, 47, 41, 33, 61, 75,
+ 43, 22, 21, 13, -26, -33, 17, 58, 39, -6, -8, 13, 27, 10, 5, 13,
+ -2, -32, -43, -32, -19, -38, -36, -3, 12, 4, 4, 13, 6, -22, -41, -31,
+ -13, -33, -59, -71, -76, -35, 2, 20, 39, 53, 47, 39, 60, 62, 37, 26,
+ 22, 5, -33, -29, 26, 64, 40, 0, -5, 12, 21, 8, 16, 10, -13, -39,
+ -49, -37, -25, -41, -30, -6, 9, 9, 13, 23, 0, -30, -44, -26, -13, -45,
+ -67, -76, -68, -20, 10, 19, 39, 55, 50, 46, 57, 50, 37, 30, 16, -3,
+ -34, -22, 34, 65, 40, 13, -2, 6, 19, 12, 21, 5, -23, -49, -52, -38,
+ -33, -36, -24, -9, 10, 12, 25, 23, -11, -29, -43, -27, -21, -55, -73, -77,
+ -50, -2, 19, 19, 35, 59, 59, 49, 45, 40, 36, 27, 4, -10, -24, -12,
+ 31, 59, 44, 22, -5, 4, 19, 20, 12, -4, -27, -52, -50, -45, -39, -24,
+ -23, -13, 16, 20, 30, 15, -16, -28, -37, -30, -36, -64, -79, -73, -28, 17,
+ 24, 14, 36, 65, 68, 45, 33, 39, 40, 22, -2, -5, -11, -11, 28, 58,
+ 57, 20, -13, 0, 27, 23, 1, -15, -35, -58, -55, -52, -39, -20, -22, -9,
+ 20, 29, 30, 10, -15, -31, -39, -32, -48, -72, -86, -59, -4, 27, 19, 17,
+ 44, 77, 69, 31, 26, 40, 38, 14, -6, 0, 1, -11, 26, 67, 62, 10,
+ -18, 6, 31, 20, -5, -22, -44, -66, -61, -50, -31, -17, -24, -7, 24, 34,
+ 31, 3, -17, -31, -36, -40, -61, -73, -76, -46, 11, 34, 20, 22, 56, 83,
+ 60, 22, 24, 46, 32, 5, -4, 9, 0, -8, 31, 73, 53, 0, -13, 16,
+ 28, 14, -15, -31, -51, -74, -64, -43, -25, -22, -25, -1, 30, 37, 20, -2,
+ -20, -36, -39, -55, -69, -75, -69, -32, 21, 36, 22, 31, 63, 76, 50, 22,
+ 25, 49, 29, 3, 4, 9, 2, 0, 43, 74, 37, -8, -1, 28, 24, 8,
+ -22, -42, -65, -80, -60, -31, -25, -31, -24, 8, 41, 37, 10, -3, -22, -40,
+ -45, -60, -69, -69, -55, -15, 32, 37, 25, 42, 72, 70, 37, 21, 32, 41,
+ 20, 5, 15, 8, 0, 9, 46, 62, 26, -7, 8, 28, 21, 4, -29, -53,
+ -79, -82, -57, -25, -27, -32, -21, 14, 48, 35, -1, -7, -24, -44, -52, -70,
+ -69, -60, -38, 1, 34, 33, 32, 57, 70, 58, 34, 26, 31, 31, 16, 14,
+ 14, 3, 8, 25, 47, 47, 18, -2, 13, 25, 19, -2, -33, -64, -87, -83,
+ -53, -24, -29, -32, -17, 21, 46, 27, -4, -12, -30, -51, -61, -73, -60, -46,
+ -17, 9, 25, 32, 47, 69, 61, 48, 41, 30, 26, 24, 18, 24, 15, 2,
+ 14, 37, 42, 34, 17, 9, 19, 20, 11, -7, -35, -79, -97, -79, -45, -21,
+ -29, -33, -12, 26, 43, 27, -3, -15, -43, -58, -66, -69, -52, -37, -2, 16,
+ 24, 38, 61, 72, 56, 43, 41, 32, 28, 22, 22, 26, 12, 1, 23, 45,
+ 34, 21, 8, 17, 22, 19, 4, -18, -47, -93, -97, -70, -40, -29, -33, -22,
+ -5, 24, 44, 19, -6, -23, -53, -60, -74, -63, -41, -20, 10, 18, 19, 40,
+ 70, 70, 47, 41, 43, 37, 27, 14, 24, 32, 10, 1, 29, 44, 27, 12,
+ 7, 28, 32, 9, -11, -27, -56, -100, -94, -64, -43, -38, -31, -7, 0, 27,
+ 41, 11, -7, -35, -60, -62, -75, -54, -29, -5, 17, 22, 14, 46, 80, 72,
+ 46, 42, 44, 42, 24, 16, 31, 32, 9, 4, 33, 45, 22, 5, 8, 41,
+ 34, 0, -22, -36, -69, -100, -92, -65, -40, -44, -25, 0, 5, 28, 36, 4,
+ -12, -50, -64, -64, -68, -46, -19, 2, 25, 28, 19, 44, 72, 67, 46, 45,
+ 44, 39, 21, 21, 38, 29, 1, 9, 39, 39, 13, -4, 9, 54, 41, -11,
+ -38, -51, -76, -91, -92, -65, -44, -47, -17, 12, 11, 21, 27, 6, -24, -59,
+ -65, -67, -61, -40, -17, 8, 31, 26, 20, 49, 74, 65, 45, 48, 47, 36,
+ 25, 28, 36, 25, 5, 19, 42, 28, 6, -2, 21, 56, 27, -22, -45, -62,
+ -83, -92, -84, -65, -49, -37, -8, 15, 16, 22, 23, -1, -38, -65, -66, -65,
+ -51, -35, -15, 20, 42, 26, 25, 51, 70, 60, 45, 52, 47, 25, 25, 39,
+ 33, 24, 16, 31, 37, 14, 3, 2, 33, 55, 14, -35, -55, -67, -84, -88,
+ -84, -68, -47, -28, -1, 17, 22, 24, 17, -14, -54, -66, -64, -61, -46, -32,
+ -10, 26, 45, 24, 29, 52, 66, 57, 49, 56, 41, 16, 29, 46, 31, 22,
+ 24, 37, 30, 12, -1, 5, 40, 39, 1, -41, -63, -72, -89, -89, -77, -62,
+ -48, -17, 5, 13, 26, 31, 10, -29, -62, -64, -65, -54, -41, -25, -4, 32,
+ 52, 29, 32, 55, 61, 55, 56, 57, 35, 17, 33, 40, 28, 27, 37, 36,
+ 26, 14, -3, 13, 41, 22, -13, -45, -65, -78, -90, -87, -70, -56, -47, -12,
+ 9, 18, 35, 27, -5, -41, -63, -61, -65, -52, -37, -17, 5, 35, 52, 34,
+ 38, 55, 58, 53, 60, 54, 31, 21, 33, 34, 30, 35, 40, 32, 29, 15,
+ -4, 18, 30, 11, -25, -53, -69, -85, -91, -82, -66, -54, -36, -7, 6, 20,
+ 40, 19, -17, -52, -63, -60, -65, -50, -32, -11, 9, 34, 50, 40, 46, 51,
+ 56, 60, 60, 50, 28, 23, 33, 33, 31, 40, 43, 38, 38, 13, -6, 13,
+ 19, -2, -34, -57, -78, -91, -85, -73, -63, -55, -28, -1, 6, 26, 39, 13,
+ -28, -56, -61, -55, -61, -43, -27, -13, 12, 38, 48, 49, 54, 46, 52, 64,
+ 64, 48, 27, 22, 28, 33, 36, 44, 42, 39, 44, 15, -3, 10, 6, -19,
+ -46, -60, -81, -92, -83, -73, -52, -44, -22, -5, 5, 38, 37, -6, -41, -55,
+ -54, -49, -53, -45, -28, -9, 19, 41, 47, 56, 57, 41, 56, 69, 64, 42,
+ 26, 23, 27, 36, 39, 44, 39, 48, 53, 12, -4, 2, -8, -33, -61, -72,
+ -84, -87, -80, -73, -49, -36, -12, -5, 9, 42, 24, -15, -44, -50, -51, -51,
+ -51, -45, -26, -4, 20, 40, 47, 64, 58, 38, 61, 71, 55, 37, 32, 23,
+ 30, 34, 39, 50, 43, 58, 53, 9, 4, -3, -27, -49, -71, -79, -79, -79,
+ -82, -70, -44, -26, -7, -5, 16, 36, 9, -18, -40, -47, -49, -45, -42, -43,
+ -20, 1, 21, 40, 53, 72, 54, 36, 64, 66, 41, 30, 36, 26, 28, 31,
+ 44, 57, 48, 62, 45, 13, 3, -14, -47, -65, -77, -87, -78, -71, -75, -68,
+ -43, -16, -2, -1, 18, 20, -4, -18, -37, -46, -50, -36, -39, -46, -15, 7,
+ 23, 41, 62, 72, 49, 41, 69, 59, 33, 29, 38, 24, 28, 31, 52, 59,
+ 49, 61, 45, 21, 2, -31, -64, -73, -78, -89, -79, -71, -77, -62, -36, -8,
+ 3, 5, 15, 5, -10, -17, -34, -49, -50, -27, -37, -43, -12, 14, 25, 45,
+ 67, 68, 48, 48, 64, 48, 27, 33, 41, 25, 24, 32, 64, 66, 51, 62,
+ 41, 21, -7, -43, -77, -81, -83, -87, -74, -71, -77, -54, -29, -1, 7, 13,
+ 12, -6, -9, -18, -38, -54, -44, -21, -37, -41, -8, 16, 28, 53, 73, 61,
+ 46, 52, 60, 35, 25, 34, 38, 20, 25, 42, 73, 62, 60, 58, 39, 22,
+ -19, -54, -85, -88, -95, -88, -65, -69, -73, -47, -22, 3, 14, 15, -5, -14,
+ -6, -23, -42, -52, -34, -19, -42, -38, 0, 18, 30, 62, 76, 61, 49, 52,
+ 49, 26, 23, 34, 33, 22, 21, 50, 78, 68, 66, 47, 40, 22, -23, -66,
+ -95, -102, -97, -74, -61, -77, -68, -36, -12, 9, 15, 13, -18, -14, -5, -31,
+ -50, -44, -21, -25, -49, -25, 8, 16, 30, 70, 82, 56, 45, 55, 39, 21,
+ 25, 31, 24, 21, 28, 64, 81, 68, 64, 47, 44, 15, -30, -77, -101, -104,
+ -96, -71, -66, -76, -53, -22, -9, 6, 22, 10, -22, -15, -13, -38, -48, -32,
+ -9, -33, -49, -14, 10, 11, 37, 77, 85, 51, 44, 48, 30, 18, 21, 26,
+ 16, 21, 36, 71, 76, 73, 68, 48, 35, 4, -38, -81, -103, -109, -91, -67,
+ -71, -69, -40, -15, -12, 3, 23, 7, -23, -17, -24, -41, -45, -24, -11, -46,
+ -46, -1, 10, 8, 49, 84, 83, 48, 50, 48, 27, 16, 18, 20, 14, 26,
+ 44, 72, 75, 82, 71, 47, 26, -6, -45, -80, -107, -110, -88, -70, -69, -58,
+ -28, -9, -12, 2, 23, 2, -21, -19, -35, -38, -33, -13, -17, -50, -35, 8,
+ 9, 10, 57, 89, 74, 45, 52, 41, 24, 15, 11, 14, 13, 22, 54, 72,
+ 74, 86, 72, 41, 13, -14, -47, -86, -113, -111, -88, -72, -67, -42, -18, -11,
+ -11, 2, 18, -2, -17, -27, -44, -37, -28, -12, -26, -49, -22, 9, 3, 21,
+ 69, 87, 63, 46, 49, 36, 24, 13, 11, 11, 8, 26, 64, 68, 76, 89,
+ 74, 38, 3, -17, -44, -86, -117, -114, -86, -65, -58, -38, -19, -7, 0, 8,
+ 9, -5, -20, -37, -45, -29, -19, -15, -36, -39, -10, 6, 4, 33, 79, 81,
+ 55, 48, 42, 30, 23, 10, 13, 10, 3, 27, 62, 60, 76, 88, 68, 30,
+ -5, -21, -49, -89, -120, -115, -81, -54, -46, -34, -14, -1, 7, 9, 1, -6,
+ -18, -45, -52, -29, -16, -17, -35, -36, -12, 5, 11, 47, 81, 72, 53, 51,
+ 39, 28, 24, 9, 13, 7, 5, 36, 57, 55, 82, 90, 62, 31, -10, -29,
+ -55, -91, -121, -115, -76, -47, -38, -34, -13, 1, 13, 9, -4, -9, -17, -49,
+ -56, -26, -9, -12, -33, -40, -17, 12, 25, 57, 71, 62, 52, 50, 35, 22,
+ 21, 14, 11, -2, 10, 41, 50, 48, 85, 87, 66, 29, -15, -34, -64, -97,
+ -121, -108, -73, -43, -37, -28, -7, 7, 16, 6, -7, -5, -15, -59, -56, -19,
+ -4, -14, -37, -42, -10, 21, 38, 66, 63, 57, 52, 49, 28, 22, 28, 16,
+ 5, -3, 22, 47, 38, 45, 79, 85, 68, 23, -16, -34, -70, -100, -122, -107,
+ -62, -39, -38, -25, -4, 15, 18, 2, -3, 0, -27, -70, -51, -17, -3, -16,
+ -44, -40, -1, 27, 45, 67, 57, 54, 48, 39, 17, 18, 28, 17, 3, -3,
+ 27, 49, 37, 42, 69, 86, 66, 16, -17, -37, -72, -99, -117, -101, -55, -39,
+ -36, -24, 1, 20, 13, 4, 4, -5, -46, -74, -43, -9, -4, -28, -49, -33,
+ 6, 33, 63, 68, 54, 53, 49, 33, 18, 21, 24, 15, 7, 9, 33, 42,
+ 35, 39, 70, 85, 55, 10, -16, -40, -75, -98, -113, -92, -47, -38, -35, -21,
+ 1, 21, 15, 8, 7, -14, -62, -70, -30, -11, -15, -34, -49, -23, 9, 39,
+ 64, 58, 51, 56, 42, 20, 16, 19, 16, 16, 4, 13, 40, 46, 33, 31,
+ 65, 83, 49, 3, -24, -41, -73, -98, -105, -77, -45, -41, -30, -13, 7, 19,
+ 12, 13, 8, -26, -68, -61, -22, -14, -25, -38, -40, -18, 12, 47, 68, 59,
+ 49, 51, 42, 19, 17, 17, 12, 13, 5, 18, 41, 47, 26, 26, 67, 78,
+ 44, -2, -31, -47, -71, -97, -96, -67, -44, -42, -29, -11, 13, 21, 13, 17,
+ 8, -34, -68, -54, -17, -18, -36, -43, -35, -12, 14, 50, 69, 56, 49, 44,
+ 35, 16, 13, 17, 13, 13, 6, 27, 46, 50, 24, 28, 66, 64, 28, 0,
+ -25, -49, -75, -99, -87, -54, -42, -38, -28, -8, 20, 19, 11, 17, 1, -41,
+ -62, -49, -18, -27, -41, -39, -29, -8, 15, 55, 73, 55, 42, 42, 33, 16,
+ 12, 12, 9, 6, 14, 40, 52, 48, 21, 31, 60, 50, 23, 0, -32, -60,
+ -76, -90, -73, -44, -39, -36, -32, 1, 29, 20, 6, 13, -3, -41, -53, -43,
+ -21, -34, -47, -38, -22, -2, 22, 54, 65, 49, 38, 42, 32, 17, 12, 7,
+ 6, 3, 21, 48, 53, 42, 24, 39, 53, 38, 15, -3, -38, -65, -76, -85,
+ -59, -36, -35, -40, -26, 15, 26, 12, 6, 10, -12, -40, -49, -33, -26, -41,
+ -53, -36, -12, 5, 28, 50, 61, 46, 34, 37, 31, 20, 12, 1, 0, 5,
+ 32, 53, 56, 41, 23, 39, 48, 35, 13, -10, -44, -72, -81, -79, -50, -27,
+ -34, -41, -18, 20, 27, 12, 5, 1, -19, -36, -40, -22, -34, -50, -55, -33,
+ -3, 14, 33, 52, 54, 35, 27, 36, 37, 25, 7, -13, 1, 19, 41, 50,
+ 50, 38, 32, 43, 41, 32, 6, -17, -46, -69, -79, -75, -43, -20, -34, -38,
+ -8, 23, 26, 12, 6, -8, -23, -30, -30, -23, -46, -56, -52, -29, 6, 23,
+ 35, 44, 47, 31, 25, 33, 40, 26, -4, -22, 3, 28, 39, 40, 50, 40,
+ 28, 34, 37, 28, 0, -22, -50, -70, -81, -72, -34, -22, -36, -33, 2, 24,
+ 25, 12, 4, -15, -24, -26, -25, -23, -46, -56, -50, -24, 10, 33, 36, 40,
+ 35, 21, 25, 43, 47, 25, -13, -25, 11, 40, 36, 40, 56, 38, 27, 31,
+ 33, 24, -4, -24, -53, -71, -80, -59, -34, -27, -31, -27, 8, 24, 25, 17,
+ 2, -22, -25, -26, -19, -24, -51, -58, -40, -9, 14, 37, 36, 35, 27, 14,
+ 28, 48, 46, 19, -19, -24, 18, 40, 29, 41, 50, 29, 29, 27, 33, 18,
+ -12, -29, -53, -71, -75, -48, -33, -32, -25, -14, 13, 24, 19, 17, 2, -25,
+ -28, -28, -18, -28, -55, -59, -30, -3, 20, 41, 34, 24, 15, 15, 36, 49,
+ 39, 17, -17, -17, 22, 41, 33, 45, 38, 26, 30, 24, 27, 10, -11, -34,
+ -58, -70, -66, -38, -32, -36, -21, -2, 14, 28, 19, 14, 0, -25, -29, -28,
+ -17, -30, -57, -51, -22, 3, 23, 39, 34, 15, 11, 17, 38, 46, 39, 15,
+ -18, -14, 27, 40, 37, 45, 32, 28, 30, 29, 28, 1, -16, -38, -55, -65,
+ -62, -37, -31, -34, -17, 9, 18, 27, 18, 9, -1, -22, -35, -29, -17, -32,
+ -57, -45, -17, 15, 30, 30, 25, 8, 10, 19, 35, 46, 37, 4, -19, -8,
+ 31, 33, 33, 42, 28, 22, 24, 29, 23, -6, -21, -43, -54, -59, -55, -32,
+ -34, -39, -10, 19, 30, 25, 9, 2, -2, -20, -38, -30, -23, -41, -51, -35,
+ -12, 24, 32, 22, 12, 8, 16, 23, 32, 48, 33, 1, -16, 0, 29, 30,
+ 33, 36, 24, 23, 22, 33, 14, -14, -20, -42, -55, -50, -44, -27, -38, -41,
+ -3, 31, 35, 23, 5, -2, -4, -15, -34, -33, -38, -47, -40, -26, -3, 31,
+ 31, 9, 2, 13, 14, 20, 38, 53, 27, -6, -14, 11, 30, 23, 32, 28,
+ 25, 22, 24, 32, 5, -20, -26, -45, -49, -40, -36, -37, -48, -40, 8, 40,
+ 37, 16, -3, -6, -2, -9, -27, -42, -52, -48, -32, -21, 8, 39, 28, -2,
+ -5, 13, 17, 23, 40, 45, 19, -4, -3, 18, 15, 19, 33, 30, 29, 22,
+ 21, 22, 0, -17, -27, -46, -48, -33, -31, -38, -53, -33, 23, 43, 31, 11,
+ -7, -5, -3, -8, -26, -49, -59, -48, -25, -14, 15, 41, 23, -8, -6, 11,
+ 10, 26, 49, 41, 12, 0, 10, 19, 4, 22, 31, 25, 25, 24, 20, 12,
+ -4, -10, -37, -50, -37, -23, -26, -43, -55, -18, 34, 41, 28, 10, -9, -6,
+ -3, -8, -27, -57, -62, -37, -15, -8, 24, 44, 23, -10, -6, 3, 8, 39,
+ 55, 30, 12, 11, 20, 8, 3, 27, 26, 20, 21, 24, 19, -1, -10, -14,
+ -42, -47, -25, -14, -28, -49, -50, -5, 38, 38, 23, 9, -11, -9, -1, -5,
+ -33, -64, -59, -34, -14, -2, 32, 49, 17, -11, -6, -2, 11, 46, 46, 19,
+ 16, 23, 24, -3, 3, 29, 29, 16, 17, 22, 11, -12, -12, -18, -50, -43,
+ -15, -11, -30, -53, -38, 10, 31, 31, 25, 3, -16, -3, 3, -8, -41, -67,
+ -53, -24, -14, 3, 35, 46, 17, -2, -7, -9, 16, 49, 41, 20, 22, 34,
+ 21, -5, 5, 31, 29, 12, 14, 18, 8, -22, -17, -20, -52, -38, -13, -19,
+ -32, -48, -25, 11, 23, 29, 26, 1, -14, 1, 1, -18, -47, -60, -47, -31,
+ -11, 13, 45, 39, 8, -2, -2, -11, 16, 43, 35, 25, 34, 40, 18, -7,
+ 6, 34, 28, 14, 7, 11, 2, -23, -25, -29, -51, -30, -11, -24, -38, -40,
+ -15, 9, 18, 29, 32, -1, -10, 0, -9, -27, -48, -52, -46, -30, -2, 27,
+ 47, 30, 10, 7, -6, -15, 12, 35, 28, 30, 45, 42, 19, -4, 11, 29,
+ 21, 6, 1, 3, -3, -27, -31, -34, -40, -22, -18, -31, -35, -30, -18, 5,
+ 19, 32, 28, -9, -7, 1, -14, -30, -42, -45, -47, -28, 7, 38, 45, 23,
+ 14, 20, -2, -24, 7, 32, 30, 37, 43, 41, 22, 7, 18, 22, 14, 4,
+ -7, 4, -7, -36, -37, -37, -27, -15, -26, -34, -34, -29, -18, 4, 19, 31,
+ 20, -4, 0, -3, -21, -32, -37, -41, -40, -25, 14, 49, 44, 18, 19, 25,
+ -1, -19, 5, 26, 35, 38, 46, 41, 18, 18, 16, 13, 12, 2, -5, -3,
+ -23, -44, -37, -32, -20, -20, -33, -28, -32, -32, -16, 1, 17, 31, 17, -2,
+ 2, -3, -22, -33, -39, -40, -34, -23, 15, 56, 44, 15, 27, 23, -4, -14,
+ 2, 22, 38, 37, 48, 40, 25, 24, 15, 11, 2, -2, -3, -15, -31, -40,
+ -37, -33, -17, -17, -28, -29, -41, -34, -7, 1, 13, 31, 17, -2, 4, 1,
+ -20, -35, -47, -37, -24, -10, 22, 52, 38, 26, 35, 26, -2, -9, 4, 23,
+ 40, 38, 46, 39, 32, 31, 16, 2, -7, -8, -2, -21, -38, -44, -38, -31,
+ -18, -15, -29, -35, -45, -32, -1, -3, 4, 30, 16, 3, 8, 4, -20, -42,
+ -48, -30, -17, -8, 21, 49, 41, 30, 38, 23, -2, -5, 1, 21, 35, 37,
+ 44, 40, 40, 33, 17, 1, -13, -10, -9, -35, -41, -41, -39, -33, -19, -12,
+ -27, -40, -48, -28, -4, -10, 10, 28, 15, 9, 12, 5, -24, -43, -43, -23,
+ -18, 0, 26, 47, 43, 35, 40, 20, -1, 1, 4, 20, 28, 37, 42, 42,
+ 46, 31, 22, 8, -17, -15, -15, -42, -41, -37, -44, -37, -16, -13, -33, -41,
+ -41, -20, -11, -17, 10, 18, 13, 16, 17, 1, -24, -38, -38, -27, -21, 9,
+ 29, 46, 44, 43, 38, 18, 3, 6, 6, 12, 19, 38, 41, 47, 44, 28,
+ 29, 11, -26, -25, -27, -45, -39, -39, -48, -41, -18, -13, -33, -38, -36, -21,
+ -19, -14, 13, 11, 11, 26, 17, -6, -25, -32, -32, -35, -14, 21, 31, 38,
+ 49, 49, 34, 19, 13, 10, 4, 9, 20, 37, 41, 45, 39, 29, 35, 6,
+ -28, -28, -35, -43, -37, -42, -50, -44, -20, -20, -37, -37, -27, -16, -23, -11,
+ 10, 5, 17, 36, 16, -16, -23, -21, -33, -38, -5, 23, 28, 35, 55, 55,
+ 31, 17, 18, 12, 3, 4, 21, 33, 41, 45, 31, 32, 39, 3, -29, -35,
+ -41, -40, -38, -45, -55, -45, -26, -31, -36, -26, -22, -22, -29, 1, 9, -1,
+ 24, 39, 8, -19, -17, -14, -32, -34, 5, 29, 29, 35, 58, 51, 32, 29,
+ 23, 11, 1, 6, 29, 37, 38, 36, 24, 43, 39, -2, -32, -44, -45, -36,
+ -36, -45, -55, -51, -37, -35, -30, -22, -20, -32, -24, 6, 2, 3, 30, 36,
+ 3, -17, -16, -18, -29, -24, 10, 31, 25, 34, 58, 44, 33, 37, 26, 8,
+ 5, 10, 37, 36, 35, 29, 22, 47, 36, -6, -36, -51, -49, -34, -38, -48,
+ -58, -53, -46, -42, -24, -23, -22, -32, -13, 4, -7, 8, 35, 30, 6, -14,
+ -20, -19, -21, -20, 14, 34, 29, 43, 52, 37, 39, 43, 24, 8, 7, 15,
+ 45, 33, 36, 24, 25, 43, 25, -10, -39, -53, -47, -34, -39, -53, -56, -54,
+ -56, -42, -21, -23, -29, -25, -5, 1, -10, 12, 35, 27, 7, -14, -25, -19,
+ -11, -10, 13, 31, 37, 44, 42, 37, 45, 44, 24, 14, 13, 24, 40, 28,
+ 35, 23, 31, 35, 15, -16, -38, -53, -45, -37, -48, -56, -54, -63, -63, -40,
+ -23, -24, -27, -19, 3, 1, -11, 14, 33, 24, 5, -16, -28, -17, -6, -1,
+ 15, 38, 39, 38, 29, 36, 54, 42, 20, 20, 19, 32, 38, 30, 31, 23,
+ 33, 23, -1, -17, -35, -44, -43, -47, -51, -51, -56, -71, -67, -45, -28, -23,
+ -23, -13, 12, -1, -15, 15, 33, 20, -2, -22, -25, -17, -3, 10, 24, 46,
+ 44, 31, 26, 41, 53, 42, 23, 23, 26, 39, 37, 32, 24, 28, 36, 11,
+ -7, -19, -38, -39, -37, -49, -54, -51, -62, -76, -68, -51, -28, -19, -21, 1,
+ 22, -3, -11, 14, 25, 16, -5, -25, -25, -15, -2, 20, 36, 51, 42, 19,
+ 19, 43, 58, 43, 25, 21, 35, 46, 41, 34, 17, 26, 33, 5, -15, -25,
+ -39, -34, -37, -55, -50, -49, -69, -80, -67, -50, -31, -18, -12, 12, 17, -5,
+ -5, 14, 17, 6, -15, -27, -22, -14, 3, 37, 49, 48, 40, 22, 22, 36,
+ 51, 44, 29, 22, 42, 49, 41, 29, 16, 29, 31, -9, -30, -33, -35, -29,
+ -38, -55, -45, -54, -79, -80, -65, -51, -34, -16, -2, 18, 18, 5, 7, 8,
+ 6, 3, -19, -21, -22, -19, 12, 51, 53, 48, 39, 22, 18, 36, 46, 42,
+ 35, 31, 44, 46, 42, 31, 24, 35, 21, -25, -39, -33, -30, -24, -41, -53,
+ -47, -60, -81, -81, -63, -53, -40, -14, 6, 24, 20, 8, 7, 0, -1, -4,
+ -21, -23, -29, -16, 30, 60, 55, 50, 37, 19, 19, 35, 43, 46, 37, 29,
+ 43, 49, 43, 32, 27, 31, 13, -35, -46, -36, -26, -28, -44, -52, -47, -65,
+ -84, -84, -68, -49, -27, 0, 10, 15, 19, 15, 9, -3, -10, -16, -20, -26,
+ -28, -2, 41, 59, 62, 56, 37, 16, 15, 31, 43, 50, 42, 30, 41, 49,
+ 49, 38, 28, 23, 5, -42, -55, -42, -21, -22, -40, -49, -54, -71, -86, -81,
+ -62, -44, -21, 5, 17, 16, 25, 23, 0, -13, -17, -17, -24, -32, -21, 15,
+ 45, 58, 66, 52, 33, 15, 9, 35, 42, 44, 44, 36, 38, 50, 52, 40,
+ 28, 16, -11, -48, -60, -43, -22, -21, -40, -53, -58, -78, -90, -79, -61, -42,
+ -9, 14, 15, 16, 22, 21, -4, -20, -21, -19, -30, -31, -10, 26, 54, 63,
+ 69, 51, 33, 12, 13, 40, 42, 45, 42, 33, 36, 53, 57, 44, 24, 3,
+ -24, -53, -63, -45, -21, -15, -39, -57, -63, -78, -89, -76, -55, -34, 3, 18,
+ 9, 16, 21, 15, -8, -26, -28, -25, -32, -24, 4, 34, 56, 67, 75, 48,
+ 22, 7, 23, 44, 39, 40, 40, 35, 40, 59, 59, 44, 18, -6, -31, -54,
+ -58, -44, -20, -13, -43, -63, -69, -80, -88, -71, -48, -21, 12, 16, 12, 18,
+ 13, 6, -12, -27, -32, -30, -34, -20, 13, 46, 63, 74, 73, 40, 15, 13,
+ 39, 46, 33, 32, 35, 36, 48, 58, 61, 43, 16, -13, -36, -57, -62, -41,
+ -22, -16, -42, -66, -73, -79, -85, -65, -38, -7, 13, 9, 7, 16, 11, -2,
+ -18, -36, -39, -26, -25, -16, 21, 53, 64, 74, 68, 36, 19, 22, 38, 44,
+ 32, 28, 32, 38, 52, 60, 56, 43, 13, -25, -39, -54, -52, -35, -30, -27,
+ -46, -70, -79, -80, -79, -58, -26, 3, 15, 6, 0, 12, 6, -8, -27, -45,
+ -39, -17, -16, -13, 28, 57, 67, 71, 57, 37, 22, 25, 41, 46, 29, 24,
+ 34, 44, 56, 55, 52, 44, 7, -27, -38, -48, -44, -35, -31, -29, -46, -77,
+ -83, -73, -70, -48, -15, 6, 9, 1, 1, 9, -3, -20, -41, -48, -30, -5,
+ -14, -9, 39, 63, 70, 66, 47, 36, 25, 32, 40, 43, 26, 21, 36, 47,
+ 59, 50, 49, 35, 0, -26, -36, -44, -41, -36, -35, -33, -50, -79, -79, -66,
+ -63, -36, -8, 6, -3, -9, 2, 3, -13, -30, -49, -46, -18, -2, -15, 4,
+ 42, 58, 65, 61, 50, 38, 28, 37, 40, 38, 28, 30, 38, 48, 50, 42,
+ 46, 28, -3, -28, -37, -36, -36, -39, -36, -37, -59, -79, -69, -62, -52, -24,
+ -2, 3, -12, -11, 4, -5, -29, -42, -53, -39, -12, -4, -4, 14, 37, 52,
+ 63, 58, 50, 37, 34, 37, 36, 37, 38, 36, 35, 47, 46, 44, 42, 18,
+ -7, -30, -34, -32, -34, -41, -37, -45, -66, -74, -64, -57, -36, -12, 1, -8,
+ -23, -7, 6, -18, -39, -49, -53, -29, -5, -1, 10, 19, 30, 46, 59, 58,
+ 50, 36, 37, 37, 32, 40, 46, 38, 34, 44, 42, 41, 36, 9, -9, -27,
+ -29, -26, -34, -40, -40, -56, -69, -66, -56, -46, -22, -7, -7, -19, -21, 3,
+ 1, -35, -48, -53, -49, -22, -3, 12, 23, 18, 22, 46, 66, 59, 47, 38,
+ 43, 35, 30, 46, 51, 39, 33, 41, 37, 42, 24, 2, -8, -22, -23, -24,
+ -33, -39, -50, -66, -69, -59, -49, -31, -13, -10, -17, -25, -16, 1, -17, -50,
+ -55, -58, -42, -17, -1, 20, 31, 14, 15, 48, 70, 59, 42, 38, 45, 33,
+ 33, 51, 53, 36, 35, 37, 36, 37, 12, 0, -9, -16, -18, -22, -33, -42,
+ -59, -67, -62, -52, -40, -20, -11, -15, -23, -23, -11, -3, -28, -51, -59, -61,
+ -38, -14, 4, 26, 30, 10, 18, 53, 71, 56, 40, 42, 45, 32, 34, 53,
+ 52, 37, 36, 32, 37, 32, 10, -3, -10, -10, -11, -17, -31, -46, -62, -63,
+ -54, -44, -30, -14, -14, -23, -27, -22, -11, -11, -35, -51, -65, -59, -32, -11,
+ 11, 29, 25, 8, 24, 63, 73, 51, 38, 46, 44, 29, 34, 51, 51, 39,
+ 34, 27, 34, 23, 3, -5, -9, -6, -10, -18, -33, -51, -66, -60, -50, -35,
+ -20, -10, -21, -33, -29, -17, -9, -20, -39, -55, -71, -57, -26, -7, 11, 23,
+ 22, 11, 35, 70, 71, 46, 39, 48, 42, 29, 33, 51, 47, 38, 31, 28,
+ 35, 17, 0, -12, -7, 0, -4, -15, -36, -56, -67, -56, -42, -26, -15, -12,
+ -29, -36, -28, -15, -13, -25, -40, -58, -70, -49, -23, -6, 8, 19, 17, 18,
+ 49, 76, 66, 40, 42, 49, 39, 25, 35, 51, 43, 40, 30, 31, 32, 15,
+ -1, -14, -7, 1, -2, -17, -40, -59, -61, -51, -38, -21, -10, -17, -34, -35,
+ -28, -18, -17, -24, -40, -64, -65, -40, -18, -8, 5, 13, 17, 31, 61, 75,
+ 60, 41, 43, 47, 34, 20, 36, 47, 43, 41, 31, 32, 26, 7, -7, -16,
+ -6, 0, -3, -22, -44, -60, -56, -47, -34, -19, -8, -20, -39, -40, -27, -18,
+ -20, -29, -44, -63, -56, -38, -23, -11, 4, 14, 21, 42, 65, 71, 59, 45,
+ 42, 34, 21, 20, 42, 48, 44, 41, 31, 34, 24, 6, -10, -20, -11, 4,
+ 0, -20, -48, -57, -47, -39, -30, -17, -4, -24, -43, -40, -26, -19, -24, -29,
+ -45, -59, -51, -37, -25, -14, 3, 15, 27, 51, 72, 76, 61, 44, 38, 23,
+ 12, 21, 43, 46, 45, 40, 31, 35, 21, 5, -17, -22, -13, 3, 1, -24,
+ -51, -52, -43, -37, -28, -8, -7, -38, -46, -36, -21, -21, -31, -33, -45, -51,
+ -47, -40, -30, -13, 4, 14, 33, 60, 76, 76, 61, 47, 30, 16, 8, 20,
+ 40, 45, 48, 37, 37, 37, 22, 3, -19, -20, -10, 4, -6, -30, -49, -44,
+ -41, -38, -23, -1, -14, -41, -44, -36, -22, -26, -35, -33, -45, -52, -48, -40,
+ -32, -9, 6, 18, 35, 65, 85, 80, 62, 46, 24, 6, -1, 23, 41, 48,
+ 45, 31, 42, 40, 23, -6, -21, -15, -6, 0, -13, -31, -44, -41, -38, -32,
+ -15, 0, -22, -40, -41, -36, -24, -31, -28, -32, -46, -49, -47, -43, -30, -6,
+ 9, 19, 46, 77, 87, 77, 61, 42, 18, -2, -7, 22, 39, 51, 41, 32,
+ 43, 35, 13, -18, -18, -10, -5, -8, -21, -29, -39, -42, -41, -23, -3, -3,
+ -32, -39, -38, -34, -31, -35, -23, -32, -46, -50, -51, -46, -26, 0, 12, 20,
+ 54, 87, 91, 72, 60, 38, 13, -10, -11, 24, 44, 52, 43, 39, 45, 34,
+ 2, -19, -8, -1, -8, -19, -19, -25, -35, -42, -39, -17, 7, -7, -38, -36,
+ -36, -37, -37, -31, -20, -34, -49, -53, -50, -43, -19, 6, 10, 25, 66, 91,
+ 84, 67, 60, 36, 1, -18, -10, 27, 48, 52, 42, 42, 38, 25, -3, -18,
+ -5, -2, -13, -22, -24, -28, -35, -45, -35, -4, 14, -17, -41, -36, -33, -35,
+ -41, -29, -20, -38, -51, -54, -46, -33, -14, 6, 14, 37, 74, 87, 76, 65,
+ 64, 29, -9, -22, -7, 23, 52, 55, 46, 42, 25, 17, -5, -12, -4, -3,
+ -17, -25, -33, -36, -33, -39, -30, 5, 12, -25, -37, -33, -34, -42, -41, -25,
+ -22, -41, -52, -53, -40, -25, -10, 11, 21, 43, 72, 78, 74, 69, 58, 15,
+ -13, -15, -4, 22, 54, 58, 53, 41, 15, 6, -2, -1, -3, -6, -18, -24,
+ -42, -40, -29, -32, -20, 13, 8, -25, -35, -34, -29, -42, -43, -27, -27, -42,
+ -51, -50, -30, -14, -5, 17, 26, 46, 70, 72, 72, 69, 48, 2, -13, -9,
+ -3, 19, 55, 59, 53, 30, 1, -1, 5, 8, -7, -15, -19, -25, -48, -45,
+ -31, -28, -10, 15, 1, -24, -35, -35, -22, -37, -43, -36, -35, -41, -47, -45,
+ -18, -6, -1, 24, 32, 51, 65, 65, 67, 63, 37, -3, -13, -9, 1, 29,
+ 54, 60, 50, 18, -4, -4, 13, 9, -10, -15, -17, -30, -54, -47, -29, -20,
+ -8, 4, -8, -15, -29, -35, -21, -37, -43, -46, -37, -33, -48, -39, -10, 3,
+ 13, 31, 34, 54, 56, 57, 63, 56, 32, -3, -16, -6, 14, 38, 48, 53,
+ 40, 11, -3, 1, 6, -2, -11, -9, -11, -28, -54, -54, -29, -8, 2, -8,
+ -16, -13, -27, -31, -21, -32, -45, -54, -36, -27, -44, -33, 1, 16, 25, 29,
+ 39, 56, 48, 51, 57, 48, 22, 3, -14, 0, 22, 39, 42, 46, 36, 7,
+ -7, 0, 0, -3, -8, -8, -15, -34, -50, -49, -27, -3, 0, -15, -14, -16,
+ -28, -26, -21, -34, -56, -55, -32, -30, -41, -23, 8, 20, 31, 33, 45, 53,
+ 38, 42, 54, 40, 18, -3, -9, 14, 33, 37, 34, 34, 27, 8, -5, -1,
+ -9, -3, -1, -8, -19, -35, -43, -42, -28, -7, 1, -18, -13, -17, -29, -24,
+ -21, -34, -55, -52, -34, -30, -26, -9, 15, 28, 28, 32, 55, 50, 29, 38,
+ 45, 35, 17, -3, -1, 18, 36, 40, 27, 24, 19, 0, -5, -1, -14, -7,
+ -2, -12, -20, -30, -40, -42, -25, -5, -5, -24, -14, -16, -25, -20, -26, -38,
+ -52, -49, -35, -31, -13, 8, 16, 28, 29, 42, 57, 40, 23, 32, 35, 30,
+ 12, -5, 9, 22, 40, 38, 19, 17, 16, -1, -9, -7, -12, -6, -5, -13,
+ -18, -29, -39, -39, -18, -3, -19, -26, -11, -18, -24, -19, -30, -40, -51, -45,
+ -30, -24, 0, 19, 22, 28, 36, 49, 54, 41, 22, 30, 31, 26, 10, 2,
+ 10, 26, 43, 28, 14, 16, 7, -6, -12, -9, -9, -5, -12, -19, -16, -29,
+ -35, -34, -8, -8, -35, -20, -7, -26, -23, -23, -30, -39, -53, -38, -25, -12,
+ 11, 24, 24, 29, 47, 50, 48, 36, 20, 29, 24, 15, 5, 8, 12, 32,
+ 40, 21, 17, 11, 0, -3, -15, -14, -7, -4, -13, -17, -16, -28, -31, -23,
+ -6, -20, -37, -15, -12, -29, -22, -28, -30, -38, -54, -34, -20, -4, 21, 33,
+ 24, 33, 50, 45, 40, 33, 27, 28, 14, 8, 8, 11, 11, 30, 33, 26,
+ 20, -1, -8, -4, -17, -16, -2, -7, -22, -20, -20, -26, -26, -15, -10, -27,
+ -35, -12, -19, -31, -21, -23, -23, -42, -57, -31, -11, 9, 35, 33, 23, 39,
+ 53, 47, 40, 31, 31, 21, 10, 9, 11, 10, 13, 26, 35, 33, 13, -11,
+ -10, -4, -19, -22, 3, -2, -28, -26, -16, -21, -24, -12, -12, -31, -34, -17,
+ -27, -34, -25, -17, -19, -48, -59, -29, -2, 27, 46, 26, 22, 43, 54, 44,
+ 38, 30, 29, 16, 6, 15, 15, 6, 9, 22, 36, 37, 9, -20, -10, -5,
+ -21, -21, 2, -5, -29, -31, -18, -11, -17, -11, -15, -32, -34, -23, -30, -30,
+ -25, -15, -22, -52, -50, -17, 9, 36, 42, 26, 29, 50, 53, 40, 33, 32,
+ 27, 14, 7, 9, 7, 4, 12, 22, 36, 36, 3, -27, -16, -9, -20, -21,
+ -1, -12, -31, -27, -13, -12, -18, -12, -17, -33, -39, -29, -34, -35, -23, -7,
+ -25, -55, -42, -10, 20, 43, 40, 27, 33, 51, 51, 37, 34, 31, 21, 9,
+ 8, 5, 2, 11, 16, 18, 34, 35, 3, -22, -17, -16, -20, -17, -7, -20,
+ -32, -28, -14, -12, -10, -8, -17, -34, -41, -35, -34, -31, -19, -8, -27, -48,
+ -29, -4, 26, 50, 44, 32, 37, 50, 49, 40, 36, 22, 11, 11, 12, 5,
+ 3, 14, 12, 13, 34, 37, 9, -23, -24, -16, -21, -16, -17, -30, -27, -27,
+ -20, -10, -10, -9, -18, -39, -46, -42, -35, -31, -14, -9, -33, -42, -19, 1,
+ 36, 55, 41, 32, 46, 55, 47, 35, 32, 18, 6, 7, 9, -2, 7, 17,
+ 8, 13, 34, 32, 10, -22, -27, -14, -20, -21, -26, -31, -23, -27, -22, -6,
+ -5, -11, -21, -39, -46, -46, -37, -30, -14, -12, -33, -31, -8, 6, 41, 55,
+ 40, 38, 54, 57, 39, 30, 33, 17, 2, 1, 4, 7, 14, 14, -2, 11,
+ 37, 31, 11, -26, -30, -16, -20, -18, -21, -27, -32, -28, -12, 0, -4, -11,
+ -23, -40, -46, -43, -33, -26, -16, -15, -29, -19, -1, 13, 44, 58, 41, 49,
+ 68, 59, 36, 28, 36, 18, -9, -9, 4, 17, 20, 7, -6, 18, 36, 22,
+ -1, -30, -26, -19, -25, -26, -31, -35, -33, -21, -3, -8, -10, -14, -24, -40,
+ -45, -43, -35, -20, -18, -20, -22, -12, 0, 15, 48, 58, 41, 58, 77, 57,
+ 30, 27, 33, 7, -23, -16, 11, 23, 21, 2, -5, 24, 33, 10, -10, -24,
+ -19, -25, -37, -30, -30, -34, -29, -14, -5, -16, -8, -8, -26, -50, -47, -41,
+ -30, -16, -25, -24, -14, -6, 3, 23, 50, 51, 49, 69, 81, 56, 29, 33,
+ 30, -2, -29, -14, 15, 26, 18, 2, -1, 31, 28, 0, -20, -21, -21, -32,
+ -43, -34, -33, -36, -23, -4, -8, -20, -8, -11, -25, -44, -41, -39, -32, -17,
+ -30, -22, -4, 1, 6, 31, 48, 47, 63, 80, 82, 52, 31, 38, 23, -13,
+ -33, -11, 20, 29, 14, -1, 9, 34, 19, -12, -26, -13, -23, -46, -46, -38,
+ -39, -35, -24, -3, -7, -17, -15, -16, -25, -45, -37, -37, -33, -26, -36, -20,
+ 5, 3, 4, 32, 42, 50, 76, 83, 75, 49, 34, 36, 17, -24, -33, -12,
+ 23, 32, 10, 1, 23, 30, 7, -17, -22, -8, -27, -49, -50, -42, -38, -28,
+ -18, -3, -8, -13, -14, -15, -24, -43, -35, -33, -29, -27, -34, -15, 16, 8,
+ 5, 32, 43, 62, 84, 84, 73, 53, 40, 30, 6, -26, -34, -15, 25, 28,
+ 8, 9, 38, 27, -4, -26, -21, -12, -33, -54, -47, -48, -38, -21, -14, -2,
+ -3, -11, -25, -18, -26, -32, -34, -34, -29, -31, -35, -10, 18, 11, 7, 33,
+ 47, 68, 83, 81, 71, 58, 42, 20, -5, -25, -36, -15, 23, 23, 7, 20,
+ 40, 21, -14, -35, -21, -16, -40, -58, -52, -52, -31, -11, -9, -6, -1, -15,
+ -26, -15, -29, -31, -36, -31, -29, -36, -32, -4, 17, 8, 15, 36, 48, 66,
+ 77, 83, 77, 59, 38, 9, -11, -20, -34, -12, 22, 20, 14, 33, 39, 16,
+ -22, -36, -23, -21, -40, -56, -52, -47, -24, -10, -4, 3, 1, -17, -22, -18,
+ -28, -26, -32, -30, -32, -30, -22, 1, 15, 15, 27, 42, 52, 62, 75, 85,
+ 80, 59, 35, 1, -16, -20, -35, -12, 18, 17, 18, 40, 34, 5, -34, -38,
+ -27, -28, -42, -60, -58, -48, -18, -4, 0, 3, -4, -18, -20, -22, -35, -29,
+ -27, -34, -42, -28, -12, 3, 8, 19, 31, 40, 45, 60, 75, 79, 76, 62,
+ 37, -2, -20, -22, -31, -11, 13, 15, 31, 43, 27, 0, -28, -33, -36, -37,
+ -43, -58, -61, -47, -13, 1, 1, 3, -5, -12, -17, -25, -36, -27, -25, -39,
+ -45, -24, 1, 0, 8, 25, 43, 45, 42, 57, 76, 76, 73, 60, 37, -8,
+ -25, -22, -25, -6, 9, 21, 41, 41, 15, -6, -18, -33, -48, -40, -38, -57,
+ -64, -46, -6, 9, -4, 1, -1, -9, -18, -28, -33, -24, -27, -42, -45, -18,
+ 2, 3, 13, 31, 49, 43, 37, 60, 74, 68, 68, 60, 30, -12, -28, -23,
+ -19, -8, 5, 26, 48, 37, 11, -12, -17, -37, -54, -40, -41, -58, -65, -42,
+ 5, 12, -8, 0, 2, -6, -22, -29, -30, -28, -37, -44, -42, -9, 6, 7,
+ 17, 33, 44, 42, 40, 61, 72, 57, 63, 61, 24, -16, -34, -21, -15, -12,
+ 3, 31, 47, 28, 7, -10, -15, -43, -51, -38, -45, -61, -61, -31, 10, 8,
+ -3, 6, 5, -8, -24, -27, -28, -31, -44, -42, -29, -3, 6, 10, 24, 40,
+ 44, 45, 46, 57, 62, 56, 65, 56, 16, -13, -32, -18, -12, -10, 11, 32,
+ 39, 25, 6, -10, -19, -48, -44, -38, -49, -63, -61, -19, 12, 3, 4, 6,
+ 3, -9, -25, -26, -27, -38, -46, -39, -18, 1, 12, 20, 29, 33, 36, 49,
+ 47, 54, 59, 49, 63, 51, 8, -12, -25, -18, -18, -6, 20, 33, 28, 19,
+ 4, -9, -27, -43, -41, -45, -55, -64, -51, -13, 7, -3, 0, 7, 3, -12,
+ -28, -27, -33, -46, -51, -33, -10, -5, 15, 31, 34, 26, 32, 47, 51, 53,
+ 47, 50, 61, 41, 1, -8, -12, -21, -20, 5, 27, 29, 16, 13, 8, -9,
+ -28, -40, -40, -44, -55, -62, -40, -8, 5, -2, 4, 11, 4, -15, -26, -26,
+ -37, -49, -47, -27, -8, -3, 22, 45, 38, 22, 34, 47, 55, 52, 39, 44,
+ 58, 32, 2, 0, -7, -25, -21, 10, 29, 30, 9, 0, 0, -7, -26, -38,
+ -40, -53, -61, -53, -30, -5, 1, -2, 5, 10, 3, -18, -25, -33, -43, -51,
+ -46, -20, -10, -8, 26, 52, 35, 19, 32, 47, 56, 46, 33, 44, 48, 20,
+ 10, 11, -7, -29, -20, 15, 35, 28, 2, -9, -8, -6, -26, -32, -36, -54,
+ -64, -52, -22, 1, 3, 2, 3, 15, 2, -22, -24, -34, -41, -45, -39, -19,
+ -9, 1, 35, 57, 37, 18, 27, 46, 52, 41, 37, 44, 40, 18, 16, 13,
+ -7, -29, -14, 23, 36, 17, -6, -17, -2, 1, -24, -38, -43, -59, -62, -44,
+ -22, -4, 7, 2, 5, 16, -2, -24, -27, -36, -43, -48, -37, -20, -5, 14,
+ 40, 52, 36, 20, 26, 43, 46, 40, 41, 42, 28, 19, 19, 9, -4, -21,
+ -10, 27, 32, 10, -6, -16, -4, -5, -14, -37, -48, -59, -58, -36, -24, -1,
+ 13, -3, 7, 16, -5, -19, -32, -38, -46, -43, -32, -22, -7, 22, 49, 57,
+ 37, 22, 20, 37, 41, 36, 46, 41, 21, 19, 16, 9, -2, -25, -9, 27,
+ 24, 8, -12, -11, -2, -9, -10, -39, -51, -59, -59, -35, -21, 2, 15, -5,
+ 10, 11, -12, -19, -35, -39, -46, -35, -29, -26, -5, 37, 60, 53, 36, 26,
+ 19, 33, 37, 33, 48, 41, 18, 17, 19, 11, -8, -23, -3, 30, 21, -5,
+ -14, -2, -6, -9, -9, -42, -59, -64, -54, -33, -16, 6, 14, 0, 15, 4,
+ -14, -17, -35, -45, -46, -33, -27, -22, 2, 42, 56, 49, 37, 26, 19, 26,
+ 23, 36, 58, 44, 11, 8, 23, 10, -7, -15, 3, 26, 12, -10, -8, 3,
+ -10, -7, -13, -46, -58, -60, -57, -40, -11, 9, 9, 3, 13, -6, -12, -17,
+ -42, -53, -45, -28, -23, -14, 11, 49, 60, 49, 40, 27, 14, 16, 13, 43,
+ 62, 46, 6, 8, 22, 7, -9, -10, 11, 23, 4, -17, 2, 6, -6, -7,
+ -21, -51, -58, -58, -55, -38, -12, 12, 10, 13, 1, -15, -7, -14, -47, -62,
+ -45, -29, -19, -2, 21, 51, 63, 46, 37, 31, 16, 0, 4, 43, 64, 43,
+ 6, 9, 24, 4, -15, -2, 14, 9, -9, -15, 14, 7, -11, -10, -29, -53,
+ -54, -57, -48, -35, -9, 13, 9, 11, -5, -6, -2, -22, -57, -60, -39, -24,
+ -11, 5, 30, 52, 62, 49, 42, 38, 11, -9, 7, 45, 61, 44, 10, 15,
+ 21, -4, -15, 3, 13, 1, -13, -9, 13, 7, -9, -13, -32, -51, -53, -56,
+ -44, -35, -9, 15, 11, 7, -8, 0, -2, -34, -65, -56, -31, -24, -7, 20,
+ 37, 49, 56, 47, 47, 39, -3, -16, 12, 40, 53, 45, 16, 23, 17, -7,
+ -8, 7, 8, -5, -12, -7, 7, 7, -4, -17, -38, -56, -60, -50, -37, -33,
+ -8, 7, 9, 0, -6, 7, -8, -47, -71, -50, -25, -23, 0, 33, 41, 46,
+ 52, 53, 54, 35, -6, -9, 13, 32, 50, 48, 23, 25, 13, -4, -3, 0,
+ -1, -7, -7, -8, 3, 6, -3, -22, -41, -55, -62, -46, -30, -24, -5, 0,
+ 5, 2, 3, 10, -20, -57, -69, -41, -19, -16, 5, 37, 47, 46, 49, 54,
+ 58, 29, -4, -6, 7, 21, 49, 49, 24, 24, 12, -2, -5, -9, 0, 0,
+ -10, -15, 2, 8, -4, -23, -42, -57, -66, -43, -22, -16, -11, -8, 3, 5,
+ 7, 4, -28, -61, -61, -36, -19, -11, 10, 45, 51, 43, 46, 52, 54, 26,
+ 3, -8, -3, 15, 52, 48, 27, 30, 15, -1, -9, -14, 0, -2, -15, -17,
+ -2, -1, -5, -23, -37, -62, -64, -34, -17, -15, -19, -8, 4, 7, 8, -8,
+ -37, -55, -50, -33, -19, -5, 16, 49, 54, 44, 45, 52, 53, 32, 3, -12,
+ -5, 14, 46, 46, 38, 34, 21, 6, -13, -21, -2, -3, -18, -19, -14, -9,
+ -2, -14, -44, -74, -56, -26, -15, -16, -18, -6, -1, 7, 6, -20, -43, -48,
+ -35, -32, -24, 1, 23, 51, 54, 41, 42, 52, 49, 32, 3, -14, -5, 19,
+ 42, 47, 43, 38, 27, 10, -18, -19, -5, -7, -18, -27, -23, -9, 2, -8,
+ -51, -75, -41, -19, -15, -13, -15, -11, -5, 10, 1, -30, -37, -40, -30, -33,
+ -24, 6, 30, 49, 49, 45, 43, 52, 39, 24, 7, -10, -7, 12, 33, 44,
+ 48, 43, 36, 7, -29, -18, -6, -14, -23, -36, -32, -12, 2, -16, -60, -65,
+ -27, -22, -22, -9, -6, -14, -6, 11, -10, -38, -35, -27, -26, -35, -15, 18,
+ 39, 47, 48, 51, 55, 51, 28, 22, 13, -5, -6, 5, 27, 46, 57, 49,
+ 39, 1, -29, -12, -7, -15, -28, -48, -39, -11, -1, -28, -61, -51, -22, -30,
+ -22, -3, -4, -21, -6, 8, -23, -45, -29, -18, -27, -32, -11, 24, 44, 40,
+ 46, 56, 61, 44, 17, 18, 19, 1, -11, -2, 24, 48, 57, 54, 45, 2,
+ -27, -12, -11, -18, -32, -49, -41, -16, -10, -32, -47, -33, -25, -34, -13, 6,
+ -5, -24, -13, -4, -29, -43, -29, -18, -25, -21, -1, 25, 44, 40, 49, 67,
+ 60, 31, 12, 18, 24, -2, -18, -5, 22, 45, 62, 65, 46, -5, -21, -12,
+ -12, -17, -36, -57, -48, -23, -15, -29, -35, -28, -33, -31, -3, 12, -16, -32,
+ -12, -19, -36, -33, -25, -22, -29, -10, 14, 30, 41, 35, 51, 73, 57, 27,
+ 16, 21, 14, -4, -12, -2, 21, 41, 62, 71, 43, -7, -12, -19, -22, -23,
+ -46, -57, -51, -35, -20, -17, -22, -26, -37, -27, 7, 12, -24, -31, -14, -29,
+ -34, -30, -22, -20, -21, 2, 15, 26, 40, 45, 55, 66, 52, 28, 20, 17,
+ 10, -1, -12, -4, 21, 43, 65, 74, 39, 1, -9, -25, -27, -24, -45, -61,
+ -55, -43, -22, -9, -12, -24, -32, -26, 9, 7, -25, -31, -30, -40, -31, -26,
+ -19, -20, -11, 14, 18, 27, 45, 54, 52, 61, 49, 33, 24, 15, 5, 0,
+ -14, -2, 24, 44, 62, 67, 37, 12, -9, -30, -29, -33, -49, -66, -58, -51,
+ -25, -2, -6, -19, -31, -24, 6, 3, -21, -37, -43, -42, -31, -25, -17, -19,
+ -5, 15, 19, 30, 52, 56, 45, 54, 52, 38, 22, 11, 8, 0, -16, 2,
+ 27, 44, 63, 60, 34, 16, -10, -25, -31, -38, -55, -68, -62, -53, -18, 5,
+ -2, -17, -31, -16, 5, -4, -22, -43, -50, -38, -32, -21, -16, -11, 8, 10,
+ 19, 32, 60, 60, 43, 46, 51, 37, 24, 13, 8, -6, -17, 4, 32, 52,
+ 56, 52, 39, 23, -5, -23, -41, -48, -64, -65, -63, -57, -14, 9, 3, -18,
+ -28, -9, 0, -11, -25, -47, -53, -38, -30, -19, -11, 0, 10, 11, 23, 42,
+ 66, 60, 42, 49, 53, 36, 24, 20, 9, -17, -18, 3, 39, 59, 49, 41,
+ 39, 26, 1, -24, -53, -59, -70, -61, -66, -58, -12, 17, 7, -20, -26, -7,
+ -7, -16, -30, -51, -60, -45, -26, -11, -5, 5, 8, 10, 23, 48, 66, 55,
+ 40, 48, 48, 33, 30, 25, 2, -21, -15, 10, 41, 51, 44, 37, 41, 27,
+ 6, -28, -60, -65, -70, -63, -70, -55, -6, 21, 1, -20, -15, -2, -15, -24,
+ -32, -54, -66, -45, -22, -8, 6, 13, 5, 15, 31, 51, 64, 58, 41, 42,
+ 44, 35, 36, 29, 0, -20, -9, 14, 43, 53, 46, 39, 39, 24, 7, -33,
+ -69, -75, -73, -70, -75, -46, 4, 17, -2, -18, -6, 3, -18, -32, -38, -61,
+ -65, -39, -17, -2, 10, 10, 5, 19, 33, 55, 61, 54, 39, 40, 41, 41,
+ 40, 30, -6, -25, -6, 22, 44, 48, 42, 42, 37, 23, 11, -42, -73, -77,
+ -75, -74, -75, -39, 4, 8, -5, -15, 1, -1, -30, -33, -38, -69, -66, -40,
+ -14, 3, 16, 8, 5, 21, 39, 60, 59, 48, 40, 38, 39, 42, 42, 30,
+ -8, -20, 0, 26, 48, 51, 48, 43, 29, 21, 1, -47, -70, -80, -83, -80,
+ -70, -25, 0, -2, -9, -6, 9, -7, -29, -33, -49, -72, -59, -29, -3, 3,
+ 11, 6, 14, 27, 47, 61, 54, 47, 43, 34, 42, 45, 39, 21, -10, -17,
+ 4, 29, 53, 54, 47, 39, 29, 22, -11, -53, -70, -83, -86, -77, -61, -19,
+ -6, -7, -12, -2, 9, -14, -29, -35, -61, -70, -54, -25, -8, 2, 11, 8,
+ 17, 27, 54, 60, 50, 45, 42, 40, 43, 39, 35, 18, -9, -7, 8, 28,
+ 55, 56, 49, 32, 30, 15, -21, -53, -71, -88, -87, -74, -45, -12, -11, -15,
+ -14, 6, 12, -12, -30, -48, -66, -60, -44, -18, -8, 5, 13, 15, 21, 31,
+ 51, 57, 48, 43, 42, 40, 43, 37, 29, 16, -3, -1, 7, 35, 60, 54,
+ 38, 26, 29, 5, -30, -54, -72, -93, -87, -69, -34, -14, -19, -25, -12, 13,
+ 6, -17, -37, -56, -66, -49, -38, -18, -11, 1, 17, 24, 26, 32, 47, 52,
+ 50, 49, 45, 39, 40, 33, 32, 13, 4, 3, 3, 47, 65, 52, 29, 27,
+ 20, -5, -35, -56, -76, -90, -79, -63, -27, -17, -26, -24, 0, 12, -2, -16,
+ -33, -61, -61, -42, -33, -17, -16, -6, 22, 30, 25, 29, 45, 50, 46, 53,
+ 41, 37, 37, 33, 28, 17, 15, 2, 15, 54, 64, 46, 21, 25, 9, -12,
+ -39, -58, -77, -87, -75, -46, -21, -23, -34, -24, 9, 9, -7, -17, -40, -67,
+ -53, -33, -27, -22, -26, -4, 34, 34, 25, 27, 46, 44, 52, 59, 37, 30,
+ 35, 32, 26, 25, 16, 2, 30, 62, 57, 33, 19, 17, -7, -25, -43, -58,
+ -80, -82, -64, -36, -26, -26, -33, -17, 11, 4, -9, -18, -45, -62, -44, -30,
+ -24, -28, -29, 5, 38, 32, 25, 30, 48, 41, 53, 57, 35, 28, 26, 27,
+ 31, 29, 14, 12, 47, 63, 48, 35, 24, 4, -19, -32, -46, -55, -76, -77,
+ -58, -31, -30, -33, -36, -8, 12, -4, -9, -22, -51, -57, -30, -23, -27, -40,
+ -31, 18, 36, 31, 30, 33, 39, 36, 56, 51, 32, 27, 20, 24, 39, 30,
+ 16, 29, 55, 53, 43, 36, 21, -5, -28, -39, -45, -55, -71, -70, -47, -27,
+ -35, -36, -25, -2, 1, -4, -6, -23, -48, -48, -25, -16, -25, -46, -23, 24,
+ 30, 35, 34, 29, 33, 37, 51, 41, 30, 21, 12, 27, 47, 33, 19, 38,
+ 51, 43, 39, 36, 15, -17, -35, -35, -42, -55, -68, -62, -45, -33, -40, -36,
+ -19, -5, -4, -3, -6, -24, -47, -38, -17, -13, -37, -48, -13, 26, 30, 36,
+ 32, 27, 29, 36, 48, 38, 27, 9, 5, 34, 47, 31, 30, 49, 47, 36,
+ 38, 28, 11, -21, -32, -32, -47, -56, -60, -54, -40, -39, -42, -31, -12, -5,
+ -7, -1, -4, -21, -39, -28, -11, -13, -45, -42, -2, 23, 25, 42, 33, 26,
+ 26, 33, 44, 34, 20, 1, 5, 36, 47, 38, 40, 47, 37, 35, 38, 20,
+ 1, -23, -26, -35, -49, -56, -55, -48, -40, -46, -42, -28, -12, -12, -10, 2,
+ -6, -25, -32, -25, -13, -22, -43, -30, 5, 18, 24, 45, 35, 29, 21, 27,
+ 39, 28, 16, 2, 9, 39, 40, 44, 55, 45, 25, 31, 34, 15, -1, -18,
+ -25, -41, -49, -50, -52, -46, -42, -48, -40, -23, -9, -18, -13, 9, -1, -24,
+ -27, -22, -14, -30, -41, -26, 8, 15, 25, 40, 36, 26, 15, 26, 35, 21,
+ 11, 2, 17, 44, 37, 54, 63, 37, 16, 31, 27, 12, -3, -12, -24, -45,
+ -47, -46, -45, -40, -44, -55, -40, -17, -12, -22, -7, 19, -2, -22, -24, -15,
+ -17, -36, -36, -11, 16, 10, 17, 38, 43, 25, 15, 25, 26, 14, 7, 2,
+ 25, 39, 38, 63, 67, 30, 16, 25, 18, 14, -5, -9, -26, -43, -45, -47,
+ -42, -38, -52, -57, -35, -14, -22, -27, 0, 23, -5, -24, -22, -12, -21, -40,
+ -31, 1, 19, 6, 11, 35, 44, 22, 18, 28, 14, 4, 4, 11, 32, 34,
+ 38, 70, 68, 22, 18, 17, 15, 17, 0, -10, -31, -45, -43, -42, -34, -36,
+ -62, -61, -25, -11, -28, -29, 3, 25, -3, -26, -15, -12, -28, -34, -21, 9,
+ 17, 2, 10, 31, 40, 24, 23, 28, 5, -3, 6, 19, 35, 33, 42, 72,
+ 59, 22, 22, 12, 17, 17, 2, -11, -31, -40, -40, -36, -28, -40, -66, -57,
+ -18, -15, -32, -22, 9, 22, -3, -23, -8, -12, -31, -32, -12, 18, 15, -1,
+ 9, 25, 36, 26, 27, 20, -7, -5, 12, 23, 29, 33, 45, 70, 48, 25,
+ 20, 8, 16, 9, 4, -11, -33, -39, -37, -34, -30, -46, -65, -50, -23, -22,
+ -30, -19, 13, 22, -4, -21, -6, -15, -32, -28, -3, 18, 9, 0, 9, 21,
+ 30, 28, 30, 12, -14, -1, 17, 19, 27, 41, 51, 63, 35, 28, 22, 12,
+ 10, 6, 9, -14, -31, -36, -31, -27, -38, -49, -62, -48, -29, -25, -27, -13,
+ 13, 13, -3, -9, -9, -21, -30, -20, 4, 12, 4, 5, 12, 19, 27, 33,
+ 29, 6, -12, 2, 21, 17, 31, 45, 54, 55, 31, 31, 25, 14, 3, 5,
+ 11, -14, -27, -33, -24, -27, -41, -49, -63, -53, -37, -26, -22, -7, 11, 8,
+ 0, -3, -14, -19, -27, -14, 8, 5, 2, 9, 12, 20, 25, 31, 18, 0,
+ -6, 8, 20, 14, 27, 43, 59, 48, 24, 28, 25, 14, 2, 8, 6, -15,
+ -26, -30, -16, -28, -44, -53, -61, -58, -37, -27, -21, -4, 8, 3, 1, -2,
+ -18, -21, -24, -11, 3, -4, 3, 15, 17, 20, 22, 29, 15, 3, -2, 8,
+ 17, 18, 30, 46, 56, 40, 21, 29, 26, 14, -1, 5, 4, -6, -22, -29,
+ -13, -27, -46, -51, -62, -61, -37, -28, -14, 2, 7, 0, 5, -2, -16, -17,
+ -19, -10, -7, -9, 11, 20, 22, 18, 17, 25, 19, 4, -1, 10, 19, 25,
+ 32, 44, 53, 36, 19, 29, 24, 10, -4, 5, 4, -2, -22, -24, -13, -31,
+ -48, -56, -63, -60, -40, -31, -11, 8, 8, 2, 8, -6, -20, -17, -12, -10,
+ -20, -12, 14, 30, 26, 10, 14, 24, 24, -1, -7, 12, 25, 27, 30, 40,
+ 52, 34, 17, 28, 24, 7, -9, 1, 8, 3, -20, -20, -16, -33, -53, -59,
+ -62, -61, -47, -29, -5, 15, 5, 1, 9, -8, -20, -14, -5, -12, -30, -11,
+ 20, 37, 25, 10, 19, 25, 19, -5, -2, 18, 28, 26, 29, 41, 49, 31,
+ 20, 30, 24, 1, -8, 4, 10, 3, -17, -12, -18, -40, -57, -61, -62, -59,
+ -48, -23, 0, 18, 5, 5, 12, -9, -19, -9, -2, -20, -37, -7, 25, 39,
+ 23, 11, 25, 26, 10, -10, 5, 23, 24, 26, 30, 40, 42, 27, 23, 31,
+ 18, -7, -5, 2, 7, -1, -10, -10, -22, -45, -59, -63, -62, -58, -45, -21,
+ -1, 17, 10, 13, 7, -18, -21, -5, -3, -27, -38, -7, 26, 38, 21, 20,
+ 31, 23, 0, -9, 15, 25, 21, 28, 33, 35, 35, 29, 28, 31, 12, -5,
+ 0, 0, 4, 0, -3, -14, -27, -48, -57, -69, -66, -61, -40, -19, 1, 16,
+ 13, 16, -3, -18, -17, -4, -9, -30, -33, -1, 24, 35, 28, 34, 31, 16,
+ -4, -2, 22, 29, 20, 27, 38, 33, 30, 30, 31, 33, 9, 1, -3, -7,
+ 2, 6, -1, -22, -31, -50, -61, -74, -67, -52, -34, -25, 1, 19, 21, 14,
+ -8, -18, -14, -10, -14, -27, -26, -5, 21, 35, 38, 40, 31, 12, -1, 5,
+ 22, 29, 19, 31, 41, 28, 30, 28, 31, 28, 12, 7, -13, -11, -2, 13,
+ -5, -26, -32, -52, -67, -80, -65, -46, -34, -26, 2, 15, 25, 9, -8, -14,
+ -16, -10, -18, -25, -25, -9, 20, 37, 46, 35, 26, 10, 7, 8, 18, 27,
+ 18, 31, 39, 25, 29, 29, 34, 26, 20, 2, -18, -10, -5, 12, -9, -22,
+ -31, -48, -74, -79, -66, -42, -34, -22, -1, 14, 25, 13, -6, -19, -16, -8,
+ -19, -22, -21, -5, 21, 41, 51, 32, 25, 14, 19, 13, 14, 21, 21, 32,
+ 34, 26, 26, 30, 32, 25, 25, -3, -19, -13, -2, 8, -12, -24, -32, -46,
+ -75, -79, -67, -43, -33, -18, -7, 12, 25, 18, 0, -23, -13, -7, -23, -18,
+ -15, -4, 21, 48, 51, 27, 27, 23, 22, 12, 12, 19, 22, 28, 28, 28,
+ 28, 31, 28, 23, 28, -3, -20, -22, -5, 0, -14, -23, -28, -50, -78, -81,
+ -63, -44, -34, -19, -14, 10, 25, 18, -6, -19, -5, -11, -30, -17, -8, 2,
+ 21, 54, 45, 25, 28, 33, 25, 9, 12, 21, 26, 23, 24, 33, 37, 35,
+ 20, 23, 32, -1, -21, -25, -12, -11, -12, -19, -27, -53, -78, -79, -55, -42,
+ -31, -26, -18, 12, 24, 13, -9, -12, 0, -20, -33, -13, 1, 6, 26, 55,
+ 38, 25, 33, 45, 26, 7, 13, 21, 26, 16, 18, 38, 44, 33, 14, 25,
+ 30, 4, -24, -32, -21, -18, -19, -19, -25, -54, -79, -78, -53, -43, -29, -28,
+ -20, 6, 20, 12, -3, 0, -3, -35, -28, 1, 9, 8, 25, 46, 34, 30,
+ 37, 44, 19, 13, 20, 17, 20, 12, 18, 49, 49, 23, 13, 28, 33, 3,
+ -34, -37, -28, -30, -21, -10, -26, -57, -77, -74, -52, -40, -25, -32, -22, 3,
+ 17, 12, 3, 8, -15, -40, -18, 10, 10, 4, 32, 39, 27, 38, 48, 39,
+ 11, 18, 28, 17, 15, 5, 23, 61, 46, 21, 23, 35, 26, -3, -31, -37,
+ -39, -38, -23, -3, -29, -60, -74, -68, -58, -37, -27, -35, -22, -7, 15, 23,
+ 14, 8, -27, -41, -6, 19, 14, 9, 35, 31, 31, 48, 54, 35, 11, 27,
+ 26, 4, 7, 11, 31, 54, 38, 25, 34, 35, 20, -10, 19, 3, -8, -45,
+ 64, -15, -41, 23, 40, -58, 22, 29, -27, -28, 42, -36, 21, -12, -19, 39,
+ -14, 3, -18, 32, -27, 18, -8, -43, 43, 25, -52, 6, 19, 13, -7, -50,
+ 55, 5, -46, -22, 94, -53, -33, 35, 27, -45, -2, 20, 19, -30, -23, 47,
+ 8, -58, 5, 76, -67, -22, 42, 30, -54, 8, 23, 11, -51, 3, 47, -33,
+ -7, 5, 27, -33, 34, -35, 17, 4, -26, 5, 17, -30, 33, 5, -29, -5,
+ 44, -18, -50, 60, -33, 10, -5, 10, -7, 1, -5, 19, -36, 3, 37, -17,
+ -51, 52, 37, -64, 9, 4, 37, -44, -13, 25, 45, -75, -9, 79, -34, -57,
+ 53, 24, -59, 18, 22, -3, -24, 10, -2, 18, -53, 29, 35, -20, -43, 37,
+ 18, -17, -31, 8, 45, -49, 8, 11, 9, -23, 30, -24, -22, 29, 14, -43,
+ 27, 13, -22, -1, 2, 22, -37, 5, -5, 38, -43, 6, 36, -21, -20, 20,
+ 0, -5, -27, 27, 21, -53, 4, 52, -2, -84, 70, 5, -29, -19, 36, -6,
+ -8, -12, 3, 35, -32, -25, 48, 6, -60, 49, 4, -27, -13, 31, -15, -9,
+ -4, 31, -13, -25, 29, 12, -34, -6, 30, -41, 36, -23, 6, 31, -30, 0,
+ 17, -45, 47, -5, -47, 19, 28, -8, -30, 27, -6, 15, -54, 34, 21, -27,
+ -9, 25, 3, -45, 26, 27, -52, 22, 20, -29, 34, -46, 22, 40, -69, -27,
+ 108, -49, -54, 69, -11, -3, -18, 3, 15, -12, -23, 29, -8, 4, -23, 50,
+ -38, -8, 33, -32, -2, 26, -27, 12, 13, -39, 56, -31, -22, 28, 2, -39,
+ 54, -20, -36, 51, -6, -34, 15, 2, 1, 2, -36, 42, 2, -10, -39, 64,
+ -36, -16, 24, 1, -1, -18, -10, 54, -27, -54, 80, -18, -61, 51, 27, -76,
+ 64, -30, -1, 9, -19, 24, 13, -29, -13, 49, -18, -46, 43, 6, -47, 42,
+ -28, 14, 18, -18, 2, 14, -39, 25, 16, -58, 33, 29, -49, 16, 41, -62,
+ 43, -17, -17, 25, -10, -28, 41, -5, -30, 27, 14, -53, 27, 35, -63, 16,
+ 30, 0, -30, -10, 22, 31, -57, 0, 68, -59, 2, 37, -30, 6, -3, -19,
+ 35, -29, 1, 20, 22, -68, 33, 39, -71, 21, 27, -22, -1, 3, 0, 18,
+ -16, -13, 17, 4, -37, 44, -15, -26, 48, -29, -11, 34, -25, -4, 25, -48,
+ 43, 4, -49, 28, 42, -72, 7, 59, -36, -28, 45, -9, -28, 25, -19, 23,
+ -9, -40, 47, 18, -85, 78, -2, -53, 39, -17, 2, 14, -36, 10, 63, -78,
+ 17, 59, -66, -8, 54, -49, 14, 1, 5, 2, -18, 16, -12, 30, -58, 22,
+ 53, -83, 17, 79, -84, 19, 17, -34, 44, -33, -27, 82, -62, -19, 91, -93,
+ 22, 49, -51, -25, 48, -12, -6, 1, -2, -1, 22, -32, -1, 59, -78, 12,
+ 58, -49, -26, 70, -40, -8, 16, -8, 12, 10, -65, 74, -1, -97, 90, 0,
+ -56, 23, 25, -17, 11, -23, 14, 9, -24, -31, 77, -41, -48, 95, -38, -46,
+ 59, -1, -57, 49, -33, 19, 18, -46, 34, 31, -79, 47, 11, -38, 10, 19,
+ -14, -10, 26, -29, 28, -17, -27, 48, -15, -51, 78, -14, -73, 64, 12, -55,
+ 29, 3, -24, 52, -65, 26, 50, -75, -5, 81, -76, 0, 42, -6, -26, 10,
+ 18, -14, 4, -24, 33, 2, -69, 61, 43, -101, 40, 54, -73, 22, 18, -41,
+ 44, -19, -43, 94, -69, -13, 65, -26, -46, 35, 24, -34, -2, 23, -13, 6,
+ -19, 4, 38, -56, 14, 40, -37, -19, 66, -57, -9, 50, -47, 21, 6, -31,
+ 55, -34, -50, 98, -44, -47, 44, 28, -51, 6, 31, -3, -34, 8, 11, 6,
+ -18, -27, 78, -48, -28, 55, -2, -60, 57, -37, 14, 15, -48, 49, 22, -96,
+ 74, 23, -83, 36, 18, -17, -25, 41, -12, -4, -2, 1, 9, -14, -18, 36,
+ 12, -77, 54, 32, -67, 20, 38, -67, 61, -53, 32, 21, -60, 27, 41, -74,
+ 27, 33, -30, -6, 22, -1, -30, 20, 1, -4, -22, 9, 8, 37, -65, 18,
+ 61, -69, -3, 37, -19, -15, 15, -16, 57, -78, 20, 66, -67, -27, 76, -37,
+ -16, 11, 11, -5, -18, 10, 16, -5, -38, 36, 9, -20, -32, 73, -41, -36,
+ 62, -33, -9, 34, -41, 35, -7, -40, 65, -35, -26, 33, 2, -43, 42, -4,
+ -9, 5, -11, 19, -10, -16, 11, 16, -28, -9, 41, 2, -70, 67, -3, -55,
+ 23, 33, -26, 6, -29, 43, 16, -85, 51, 28, -54, 7, 27, -9, 2, -18,
+ 27, -4, -42, 31, 10, -19, -9, 18, 8, -24, -3, 45, -57, 25, 0, -7,
+ 15, -28, 10, 33, -46, -6, 52, -36, -15, 46, -29, -4, 12, -14, 34, -57,
+ 16, 40, -41, 3, 16, 8, -32, 16, 15, -17, -27, 47, -30, -1, 14, -5,
+ 16, -17, -33, 70, -44, -42, 84, -34, -27, 18, 15, 3, -20, -22, 55, -35,
+ -22, 31, 10, -11, -27, 27, 13, -28, -10, 41, -21, -3, -22, 41, -21, -13,
+ 6, 34, -68, 46, 25, -65, 50, -21, -1, 10, -33, 34, 1, -43, 58, -34,
+ -2, 13, 8, -25, 0, -2, 34, -29, -26, 45, -12, 4, -34, 32, 15, -54,
+ 17, 53, -76, 41, 4, -17, 13, -26, 13, 31, -47, 1, 52, -53, 11, 8,
+ 14, -31, -7, 19, 30, -60, 26, 27, -22, -10, 0, 18, -13, -24, 52, -38,
+ -17, 68, -60, 26, -9, -25, 41, -29, -8, 40, -25, -9, 26, -28, 15, -9,
+ -3, 11, -21, -1, 44, -47, 19, 0, 3, -14, -12, 38, -22, -23, 37, -10,
+ -13, 9, -6, 21, -14, -39, 61, -4, -68, 60, 6, -43, 28, -14, 21, -22,
+ -13, 36, -7, -40, 46, -14, -5, -18, 20, 22, -49, 22, 10, -18, 21, -30,
+ 9, 34, -54, 19, 22, -34, 27, 7, -45, 30, 0, -20, 23, -23, 29, -10,
+ -21, 25, 3, -23, -1, 5, 16, -33, 14, 25, -21, -11, 16, 3, -22, 5,
+ 6, 32, -73, 27, 62, -72, 5, 26, -21, 30, -37, 4, 40, -45, 5, 18,
+ -18, -1, 12, -3, 0, -18, 28, -8, -14, 11, -11, 13, -15, -3, 27, -17,
+ -30, 65, -45, -5, 28, -25, 1, 20, -36, 38, -11, -20, 35, -23, -20, 27,
+ 11, -42, 13, 17, 1, -25, 20, 10, -33, 10, 6, -7, 9, -26, 40, -3,
+ -63, 74, -30, -11, 10, -10, 5, 17, -47, 53, -10, -47, 29, 31, -45, 4,
+ 16, 14, -15, -33, 40, -11, -3, -10, 2, 18, -20, 9, 22, -44, 19, 20,
+ -42, 25, -5, -11, 25, -25, -3, 47, -63, 28, 20, -42, 7, 39, -41, 2,
+ 13, 10, -24, -8, 41, -26, -1, -13, 9, 42, -60, 0, 61, -54, -4, 19,
+ -6, 11, -19, -13, 52, -37, -26, 66, -38, -30, 49, -18, -11, 5, 7, 10,
+ -30, 4, 17, 2, -12, -15, 38, -19, -20, 30, -16, -23, 38, -13, -16, 29,
+ -22, 26, -17, -35, 62, -30, -35, 51, -16, -27, 40, -16, 3, -8, -4, 9,
+ 4, -26, 11, 20, -11, -38, 56, -19, -29, 31, 7, -39, 17, 10, 6, -8,
+ -41, 45, 26, -79, 36, 42, -58, 21, 6, -10, 7, -19, 17, -1, -15, -12,
+ 53, -22, -32, 24, 25, -59, 24, 22, -36, 10, 18, -27, 44, -45, 0, 42,
+ -45, -2, 30, -27, 12, 23, -38, 13, 5, 4, -4, -20, 1, 43, -27, -36,
+ 43, 14, -51, 12, 40, -41, 5, 18, -11, -1, -5, -11, 53, -56, -29, 91,
+ -41, -45, 57, -7, -18, -3, -4, 29, -20, -19, 20, 26, -57, 31, 17, -22,
+ -13, 28, -31, 3, 36, -33, 9, 17, -39, 42, -9, -54, 58, 6, -69, 44,
+ 30, -50, 24, 3, -17, 9, -20, 17, 8, -23, 1, 46, -50, 1, 27, 1,
+ -49, 37, 5, -17, 4, -5, 7, 18, -55, 39, 36, -85, 37, 48, -63, 5,
+ 27, -13, -6, -4, 5, 24, -26, -12, 42, -25, -34, 33, 20, -33, -13, 29,
+ -2, 7, -34, 12, 37, -50, 1, 47, -46, -1, 56, -54, -18, 59, -35, -6,
+ 12, -16, 20, -2, -27, 43, -12, -34, 22, 25, -41, -7, 43, -20, -18, 19,
+ -1, 1, -6, -20, 54, -55, -12, 67, -24, -56, 56, -8, -12, -7, -3, 16,
+ 20, -48, 20, 32, -46, 8, 23, -17, -38, 54, 1, -34, 2, 30, -1, -21,
+ -18, 38, -14, -35, 41, 3, -36, 19, 22, -45, 40, -32, 12, 12, -26, 2,
+ 35, -54, 34, 14, -25, -30, 47, 10, -53, 24, 13, -4, -18, 3, 5, 27,
+ -61, 38, 15, -39, 6, 40, -36, 0, 2, -6, 28, -40, 7, 46, -37, -30,
+ 59, -21, -29, 6, 48, -55, 12, 30, -21, -6, 5, -2, 1, -14, -7, 46,
+ -41, -4, 35, -8, -33, 29, -20, 26, -31, -10, 63, -46, -4, 12, 7, -11,
+ -15, 26, -14, -22, 54, -47, 12, 9, -1, -8, -7, -8, 41, -12, -60, 77,
+ -21, -26, 11, 13, 1, -26, -9, 59, -45, -16, 38, -3, -27, -1, 28, -8,
+ -19, 11, 20, -41, 34, -23, 22, -20, -9, 6, 51, -79, 40, 18, -40, 23,
+ -5, -19, 13, 2, 3, -4, -35, 71, -39, 5, -30, 33, 6, -29, -3, 38,
+ -29, -5, 18, -9, -4, -11, 16, 15, -32, -14, 77, -83, 30, 10, -10, -19,
+ 20, 15, -17, -19, 29, 7, -32, 6, -1, 14, -14, -6, 5, 36, -58, 47,
+ -18, -14, 4, 8, 8, -24, -15, 60, -36, -20, 43, -32, 3, -2, 1, 9,
+ -5, -8, 30, -33, 6, 6, 2, -12, -11, 24, 1, -22, 9, 34, -61, 25,
+ 11, -5, -18, -1, 38, -19, -33, 49, -19, -21, 18, -7, 1, 5, -4, -3,
+ 13, -30, 25, -5, -12, 2, 8, 17, -37, 0, 50, -38, -26, 40, -15, 7,
+ -24, 31, -11, -8, 6, -6, -3, 1, 9, -8, 6, -20, 25, 0, -21, 7,
+ 22, -48, 29, -4, 10, -22, 7, 22, -9, -34, 45, -15, -31, 30, -2, 0,
+ -30, 46, -18, -6, -17, 31, -6, -7, -21, 8, 45, -47, -7, 31, -17, -11,
+ 25, -20, 17, -30, 47, -38, -2, 5, 16, -36, 24, -2, 3, -7, 6, 10,
+ -23, 5, -11, 35, -42, 17, 0, 21, -35, 11, 16, -18, -15, 36, -24, -3,
+ 9, 5, 13, -49, 36, -11, -2, -14, 37, -32, 13, -1, 0, -2, -2, -8,
+ 17, -11, -21, 30, -1, -1, -41, 72, -65, 14, 14, 12, -41, 21, 4, 15,
+ -32, -1, 25, -9, -18, 3, 29, -38, 35, -22, 14, -20, 16, -6, -6, -13,
+ 29, -4, -17, 7, 14, -6, -38, 54, -32, 3, -16, 36, -39, 42, -40, 36,
+ -22, -13, 17, 14, -36, 12, 23, -25, 6, -25, 53, -33, -12, 5, 37, -46,
+ 6, 20, 9, -53, 52, -16, -22, 24, -9, 10, -17, 12, -20, 48, -73, 40,
+ 18, -30, -20, 52, -34, 11, -6, 0, 1, -15, 24, -16, 16, -30, 44, -27,
+ -10, 0, 34, -52, 24, 3, 2, -6, 12, -25, 35, -38, -14, 72, -73, 7,
+ 31, 15, -50, 20, 12, -5, -25, 23, 3, -10, -9, 15, 9, -41, 28, 6,
+ -5, -36, 44, -13, 10, -19, 2, 14, -10, -29, 56, -27, -35, 58, -19, -27,
+ 17, 16, -30, 10, -7, 15, -12, -3, 11, 18, -30, -13, 38, -17, -16, 3,
+ 32, -37, 23, -24, 30, -12, -26, 40, -14, -52, 59, 12, -55, 16, 35, -20,
+ -30, 39, -24, 21, -26, 12, 13, -10, -19, 23, 2, -35, 17, 33, -30, -17,
+ 39, -15, 12, -53, 50, -13, -25, 2, 50, -42, -1, 25, -22, 6, -5, 3,
+ -4, 2, -18, 39, -25, -3, 1, 29, -57, 22, 26, -22, -18, 34, -10, -10,
+ -11, 13, 31, -77, 46, 23, -22, -35, 61, -24, -13, 7, -3, 0, 4, -24,
+ 27, 12, -50, 35, 13, -19, -37, 69, -46, -4, 13, 5, -8, 6, -25, 40,
+ -26, -13, 38, -12, -28, 21, 22, -57, 40, -15, 11, -19, 4, 19, 9, -36,
+ 3, 42, -35, -30, 46, 0, -50, 59, -26, 9, -16, 12, -10, 10, -33, 44,
+ -8, -29, 8, 42, -43, -6, 26, -19, 14, -30, 34, 4, -21, -17, 49, -31,
+ -24, 34, 14, -53, 32, 13, -26, 12, -22, 26, -3, -22, -11, 66, -59, 0,
+ 43, -27, -23, 42, -32, 7, -7, 11, 9, -19, -1, 15, 16, -58, 43, 1,
+ -32, 11, 36, -44, 18, 0, 4, -4, -7, -22, 50, -22, -44, 67, -14, -43,
+ 37, 2, -32, 15, 7, 8, -22, -1, 14, 19, -43, 0, 40, -30, -14, 28,
+ 10, -32, 11, 1, 21, -33, -9, 31, 15, -72, 61, 4, -40, 21, 14, -37,
+ 22, 4, -4, -9, 5, -8, 23, -16, -22, 35, -24, 0, 12, 3, -17, 15,
+ 2, -10, -6, -8, 21, 7, -58, 40, 43, -75, 25, 28, -25, -18, 28, -15,
+ 6, -5, -4, 22, -5, -39, 37, 1, -30, 12, 23, -27, -8, 34, -22, 0,
+ -12, 15, 10, -28, 2, 45, -45, -9, 36, -22, -7, 13, -7, 6, 2, -18,
+ 17, 10, -34, 9, 18, -22, -1, 22, -9, -17, 23, -1, -22, 21, -20, 20,
+ -17, -6, 38, -33, -18, 55, -32, -21, 26, -5, -9, 5, -8, 16, 9, -47,
+ 36, 11, -36, -3, 38, -7, -48, 44, -2, -11, 2, -16, 15, 11, -36, 33,
+ -3, -18, 9, 19, -46, 26, -1, -11, 20, -24, 12, 16, -16, -17, 37, -32,
+ -6, 13, 13, -33, 25, 14, -27, 8, 1, -18, 22, -5, -15, 32, -46, 37,
+ -2, -19, -13, 38, -32, 8, 2, -4, 15, -12, -4, 19, -25, -10, 37, -19,
+ -11, -10, 57, -54, 19, -17, 18, 3, -18, -9, 27, -6, -36, 57, -23, -21,
+ 14, 11, -23, 32, -53, 56, -24, -5, -3, 11, -16, 16, -7, -20, 17, 11,
+ -3, -31, 42, -33, 14, -6, -2, -8, 39, -56, 48, -21, -20, 30, -8, -20,
+ 12, 15, -32, 41, -36, 29, -25, 14, -22, 22, -19, 9, 4, 10, -31, 17,
+ 11, -14, -1, -7, 17, -16, 6, -18, 64, -88, 47, 6, -20, -5, 22, -13,
+ 18, -28, 2, 25, -19, -10, -3, 29, -23, 11, -22, 39, -25, 13, -27, 20,
+ -2, -18, 15, -3, 3, 9, -17, -8, 38, -57, 35, 1, -9, -24, 43, -32,
+ 30, -30, -3, 19, -3, -21, 12, 14, -12, 2, -5, 11, -37, 37, -3, -13,
+ -4, 10, 11, -4, -38, 41, -9, -27, 37, -37, 16, 17, -7, -15, 22, -40,
+ 33, -2, -16, 4, 3, 8, -4, -20, 21, -3, -10, 8, -26, 37, -21, 8,
+ 0, -3, -3, 0, -8, 20, -15, -32, 54, -10, -26, 17, -12, 10, 24, -71,
+ 51, 3, -21, 9, -3, 17, -22, 2, 15, -21, -11, 39, -25, 11, -27, 28,
+ 3, -11, -26, 45, -43, 24, 7, -39, 47, -24, -15, 27, -13, -15, 35, -27,
+ 15, -17, 9, 0, -7, 0, 4, -9, 13, -3, -16, 28, -29, 21, -23, 11,
+ -4, 10, -30, 64, -63, 13, 28, -30, 16, -13, 0, 25, -39, -2, 53, -40,
+ 5, -19, 41, -25, -6, -3, 37, -40, 6, 8, 0, 6, -34, 32, 4, -27,
+ 13, 15, -34, 52, -63, 40, -5, -22, 5, 24, -32, 22, 11, -26, 14, -22,
+ 26, -21, 10, -8, 5, -10, 46, -66, 44, -20, 14, -7, -27, 23, 30, -53,
+ 24, 10, -37, 44, -40, 21, -11, 3, 6, 20, -47, 27, 5, -2, -18, -4,
+ 29, -13, -20, 27, 9, -47, 43, -37, 55, -62, 14, 33, -13, -28, 24, -9,
+ 23, -35, -4, 32, -14, -13, 28, -10, -30, 46, -43, 43, -46, 13, 13, -10,
+ 7, -3, -20, 39, -19, -19, 14, -15, 39, -31, -10, 25, 2, -34, 41, -35,
+ 15, -4, -3, 22, -18, -27, 46, -1, -36, 10, -4, 42, -56, 13, 31, -19,
+ -18, 28, -29, 27, -32, 24, 10, -44, 20, 32, -32, -17, 32, -13, 13, -35,
+ 20, 32, -53, 20, 9, -16, 16, -36, 39, -3, -33, 43, -26, 2, 2, 2,
+ -17, 24, -22, 14, -3, -12, 31, -28, -8, 26, -29, 19, -4, -15, 33, -39,
+ 22, 16, -37, 6, 17, -4, -13, -12, 37, 9, -65, 34, 25, -27, -9, 7,
+ 5, 10, -36, 45, -11, -41, 42, -6, -21, 7, -5, 31, -5, -57, 62, -12,
+ -15, -16, 23, 4, -24, 12, 26, -35, -11, 44, -25, -8, -1, -4, 28, -11,
+ -37, 61, -48, 23, -1, -30, 29, -8, -2, 6, -19, 18, 15, -41, 30, -4,
+ -11, -11, 28, -10, -4, -37, 81, -45, -43, 61, -19, 1, -11, 0, 31, -30,
+ -25, 68, -43, -11, 0, 27, -1, -33, -7, 77, -54, -30, 44, -6, -5, -14,
+ 17, -6, -10, 6, 30, -68, 50, -16, 5, 5, -30, 30, 26, -69, 36, 8,
+ -34, 37, -28, 11, 0, -1, 9, 1, -41, 53, -22, -24, 23, 5, -9, -11,
+ 12, 28, -61, 28, 36, -68, 51, -33, 25, -6, -26, 7, 53, -65, 2, 47,
+ -25, -23, 17, 20, -4, -51, 38, 29, -67, 31, 1, 22, -35, -8, 40, -9,
+ -46, 47, -13, -8, 5, -15, 37, -27, -20, 45, -16, -45, 59, -37, 19, -6,
+ 2, 1, -11, -3, 34, -42, 0, 33, -30, 16, -13, 13, 2, -23, 18, -5,
+ -26, 43, -24, 15, -26, 4, 35, -15, -62, 64, 19, -75, 50, -8, 8, -14,
+ -12, 31, -19, -30, 45, -10, -12, -10, 36, 3, -53, 14, 45, -37, -22, 42,
+ -25, 21, -36, 21, 37, -61, 5, 47, -49, 19, -4, 5, 1, -12, 7, 3,
+ -11, 2, 18, -28, 13, -4, 18, -13, -20, 33, -22, -8, 21, -12, -10, 24,
+ -9, 2, -27, 15, 33, -41, -18, 56, -40, 9, -5, 6, 20, -44, 11, 39,
+ -35, -22, 50, -7, -36, -6, 41, -10, -30, 15, 20, -22, 7, -11, 16, 6,
+ -51, 59, -21, -26, 24, 12, -24, 8, -7, 12, 3, -36, 27, 18, -42, 22,
+ 9, -22, 11, -2, 15, -40, 38, -13, -16, 8, 24, -33, 15, -13, 4, 23,
+ -42, 17, 30, -34, -5, 28, -22, 11, -23, 30, -14, -28, 37, 12, -46, 11,
+ 31, -23, -12, -7, 36, -17, -6, -4, 25, -18, 4, -29, 53, -48, 4, 24,
+ -9, -21, 30, -1, -20, 2, -13, 51, -51, -1, 39, -23, -18, 33, -23, 3,
+ 3, 2, -13, 11, 4, -13, 15, -14, -3, 1, 24, -53, 55, -24, -17, 36,
+ -1, -49, 45, -7, -12, -2, -4, 24, -23, 1, 6, 23, -51, 30, -8, 14,
+ -29, 17, 12, -9, -21, 21, 1, 3, -32, 21, 30, -59, 27, 25, -21, -26,
+ 36, -24, 16, -23, 15, 10, -15, 11, -11, -3, 14, 1, -30, 32, -24, 27,
+ -25, 10, -12, 29, -33, 7, -5, 25, -29, 14, 15, -42, 20, 18, -27, 1,
+ 21, -19, 17, -18, 2, 19, -12, -34, 47, -21, -6, 9, -2, 14, -32, 32,
+ -23, 14, -21, 21, 0, -13, -8, 42, -35, -19, 33, 4, -34, 23, -5, -6,
+ 22, -31, 21, -8, -5, -3, 15, -22, 10, 2, 7, -17, 11, 3, -10, 2,
+ -1, -2, -9, 25, -20, 11, -18, 17, -3, -12, 2, 9, -1, -10, 5, 0,
+ 15, -40, 36, -5, -28, 16, 24, -34, 16, -1, 13, -32, 11, 9, 5, -26,
+ 5, 32, -32, 4, -1, 29, -38, 8, 7, -6, 5, -2, -5, 18, -26, -2,
+ 39, -42, 0, 26, 2, -43, 45, -30, 20, -11, -6, -3, 16, -7, -6, 3,
+ 12, -13, 5, -7, -21, 47, -29, -11, 9, 36, -45, 8, 0, 22, -28, -7,
+ 32, -22, -9, 20, 12, -40, 24, -8, 14, -28, 10, 9, 12, -29, 15, -7,
+ 15, -23, 5, 14, -24, 12, 8, 4, -38, 36, -4, -7, -30, 47, -13, -24,
+ 16, 23, -46, 29, -3, -10, 20, -43, 35, 0, -4, -30, 47, -18, -21, 16,
+ 19, -35, 11, 19, -21, -11, 27, -12, -9, 16, -21, 23, -32, 30, 3, -22,
+ -15, 51, -38, -1, -2, 11, 15, -28, -1, 16, 13, -42, 23, 4, -6, -32,
+ 61, -24, -35, 34, 29, -55, 4, 13, 9, -6, -26, 35, -6, -11, -11, 19,
+ -6, -3, -15, 43, -41, 4, 22, -1, -34, 18, 15, -35, 18, -1, 23, -35,
+ 18, -2, -9, 1, 10, -18, 17, -18, 21, -8, -17, 24, -1, -20, -7, 26,
+ -11, 6, -33, 42, 0, -40, 9, 46, -48, -6, 24, 13, -39, 8, 41, -43,
+ 3, 6, 6, -7, -6, -8, 42, -37, -11, 39, -16, -26, 25, 3, -24, 9,
+ 11, 6, -34, 17, 14, -12, -22, 20, 0, 14, -38, 27, 10, -37, 22, -1,
+ -5, -7, 11, 4, -3, -29, 38, -5, -26, 4, 20, -17, 6, 2, 11, -17,
+ -10, 40, -49, 10, 26, -8, -24, 11, 12, 5, -36, 21, 20, -22, -29, 28,
+ 30, -30, -24, 31, 25, -70, 39, 4, -16, 3, 9, -13, 16, -26, 23, 19,
+ -46, 1, 29, 6, -37, 8, 27, -8, -33, 36, -24, 5, 14, -8, -8, 1,
+ 4, 15, -27, -11, 44, -38, 6, 12, -3, -12, 20, -17, 16, -35, 28, -4,
+ 0, -13, 8, 23, -24, -16, 28, 11, -58, 48, 6, -39, 11, 24, -9, -8,
+ -25, 42, -16, -14, 12, 2, 13, -31, 6, 26, -10, -48, 64, -22, -21, 6,
+ 28, -15, -11, -2, 22, -30, 11, 15, -25, 13, 2, -1, -7, -4, 6, 17,
+ -37, 17, 0, 1, 14, -23, 4, 16, -23, 6, 12, -31, 30, 6, -18, -25,
+ 45, -7, -20, -15, 44, -38, 9, 22, -37, 24, 6, -20, 14, -17, -8, 44,
+ -27, -22, 16, 30, -33, -18, 20, 31, -50, 11, 27, -21, -4, -3, 26, -15,
+ -24, 15, 20, -27, 16, -12, 9, 5, -24, 3, 26, -27, 5, 15, -19, 9,
+ -9, 26, -25, -5, 10, -4, -6, 31, -45, 18, 24, -23, -23, 27, -3, 2,
+ -18, 9, 13, -18, 19, -17, 7, -1, -24, 31, 5, -49, 31, 32, -40, -7,
+ 10, 14, -12, -12, 5, 21, -30, 25, -12, 4, -18, 9, 11, -13, -20, 37,
+ -8, -3, -13, -3, 33, -21, -32, 44, -7, -22, 28, -24, 5, 12, -19, 2,
+ 6, 2, -16, 11, 10, -6, -23, 31, -25, 7, 6, -16, 18, 1, -35, 40,
+ -9, -18, 12, 4, -2, -25, 20, 19, -16, -35, 46, -14, -8, -3, -1, 24,
+ -12, -25, 26, -4, -6, 3, -12, 20, -24, 18, 9, -20, -2, 18, -13, -1,
+ -16, 8, 26, -35, 12, 10, -11, 6, 2, -30, 46, -43, 16, 6, 1, -20,
+ 26, -18, 8, -13, 9, -3, 3, 1, -25, 29, 13, -50, 12, 41, -47, 15,
+ 14, -12, 2, -3, -1, 14, -25, -3, 26, -23, 19, -35, 41, -5, -23, -1,
+ 31, -30, 8, -15, 32, -29, -7, 22, 10, -35, 12, 6, -2, 20, -50, 36,
+ 7, -17, -4, -1, 7, 2, -21, 19, -12, 1, 28, -25, -5, 9, -3, -12,
+ 32, -45, 16, 21, 0, -43, 21, 28, -19, -38, 45, -15, -8, 28, -43, 39,
+ -12, -23, 13, 19, -39, 23, -3, 17, -32, 6, 20, -5, -32, 23, 8, -15,
+ -1, 11, 9, -28, 5, 20, -18, -6, 9, -18, 50, -50, -8, 49, -30, -5,
+ -4, 14, -19, 28, -21, 2, 4, 11, -20, 6, 3, -5, -24, 54, -34, -14,
+ 26, -4, -2, -16, 5, 20, -23, 1, 6, -9, 32, -37, 1, 25, -22, -8,
+ 31, -6, -37, 31, 0, 3, -37, 24, 25, -27, -20, 27, 1, 4, -26, 13,
+ 3, -14, 12, -6, 6, -3, -6, 18, -14, -27, 38, 5, -36, 14, 13, -22,
+ 26, -13, -22, 36, -23, -5, 3, 18, -12, -23, 31, -5, -24, 23, -15, 17,
+ -7, -23, 20, 6, -4, -19, 20, -8, 15, -32, 13, 17, -30, 17, 13, -19,
+ -8, 4, 24, -18, -29, 36, 7, -21, -20, 28, 13, -17, -31, 36, -9, -7,
+ 7, 6, -9, -4, 7, -6, 10, -32, 41, -26, 12, -10, -12, 35, -10, -39,
+ 36, -9, -7, 7, 6, -9, -4, 11, -14, 5, -7, 9, -13, 24, -27, 4,
+ 14, 7, -31, 19, -14, 17, -5, -34, 57, -31, -7, -6, 28, -15, -11, 2,
+ 25, -21, -14, 15, 18, -35, 12, 1, 9, -20, -2, 32, -37, 26, -17, 7,
+ 1, -10, -18, 54, -37, -16, 23, 11, -13, -23, 34, -5, -16, -10, 25, -28,
+ 30, -10, -7, -5, 18, -24, 25, -24, 18, -11, 0, 3, -19, 34, -12, -12,
+ 2, 3, -13, 32, -37, 20, 4, -6, -25, 29, -3, -2, -11, -2, 28, -38,
+ 18, 7, -5, -7, 0, -4, 21, -36, 30, -19, 25, -29, -15, 48, -11, -43,
+ 33, 33, -64, 17, 26, -12, -18, 9, -1, 18, -33, 23, -13, 21, -18, -13,
+ 18, -2, -20, 20, 6, -15, 4, -12, 28, -27, 1, 10, -5, 3, 0, -17,
+ 15, 17, -30, 2, 5, -8, 17, -11, -2, 9, -20, 23, -27, 23, -10, -3,
+ 7, -3, -25, 31, 9, -28, -9, 30, -5, -28, 15, 29, -36, -9, 29, -11,
+ -20, 33, -27, 21, -14, -12, 21, -3, -9, -2, 12, -5, -27, 27, 7, -20,
+ -11, 32, -9, -15, -1, 9, 20, -42, 12, 9, -4, 3, -6, -3, 6, 0,
+ -12, 15, -25, 27, -6, -6, -6, 6, -2, -4, 5, 9, -20, 12, 8, -17,
+ -10, 30, -12, -24, 25, -15, 18, -21, 21, -8, -6, -9, 12, -6, 15, -33,
+ 26, 8, -32, 13, 21, -12, -28, 20, 11, -6, -28, 27, 11, -21, -10, 22,
+ -1, -11, -7, 24, -12, -27, 35, -8, 0, -20, 23, -10, 9, -30, 32, -15,
+ 3, -7, 6, -2, 10, -17, 1, 8, -4, -5, -3, 14, -9, 1, -11, 18,
+ -13, 15, -33, 22, 14, -32, 11, 9, -1, -17, 14, 0, -3, -16, 29, -21,
+ -4, -1, 28, -24, -2, -11, 41, -25, -23, 24, 6, -18, -13, 37, -21, -2,
+ -4, 29, -40, 11, 12, 4, -25, 12, -9, 23, -17, -14, 27, -2, -26, 9,
+ 18, -14, -1, -15, 29, -18, -4, 5, 12, -26, 18, -3, -7, 3, 13, -10,
+ -25, 44, -38, 11, 8, -2, -25, 28, -9, 12, -13, -13, 10, 27, -53, 19,
+ 16, -4, -20, 12, 12, -21, 5, 12, 3, -35, 22, 8, 0, -28, 18, 16,
+ -25, -3, 9, 8, -3, -19, 8, 24, -34, -4, 38, -16, -30, 29, -1, -2,
+ -25, 28, -1, -21, 11, 10, -18, -1, 10, 1, -7, 0, 1, -7, 15, -15,
+ -5, 16, 2, -22, 8, 0, -1, 26, -34, -22, 56, -26, -11, 12, 9, -9,
+ -9, 4, 7, -8, -1, 8, 0, -21, 10, 19, -8, -25, 17, 10, -18, 3,
+ -4, 26, -15, -29, 30, 9, -46, 36, 12, -33, 1, 18, -2, -16, 4, 16,
+ -10, -16, 11, 2, 8, -19, 5, 1, 10, -21, 20, -8, -1, -3, 1, 7,
+ -19, 7, 11, -12, 5, 5, -26, 29, -11, -5, -2, 12, -13, 9, -22, 23,
+ 3, -20, 4, 17, -16, -13, 17, 15, -16, -34, 37, -5, 8, -32, 23, 17,
+ -36, -2, 36, -25, -4, 28, -18, -20, 15, 4, 7, -12, -24, 43, -19, 0,
+ -11, 25, -9, -12, -7, 10, -1, 11, -2, -12, 13, -27, 30, -9, -15, 8,
+ 17, -28, 18, -9, 3, 7, -8, -10, 16, -26, 35, -22, -10, 37, -35, 1,
+ 11, 11, -19, -2, 9, 17, -37, 11, 10, 9, -16, -12, 27, -11, -22, 16,
+ 24, -48, 25, -1, -3, 4, -20, 13, 39, -72, 34, 1, 2, -6, 4, -1,
+ -8, 2, -8, 18, -10, -1, -5, 19, -30, 5, 30, -16, -26, 36, -26, 3,
+ 21, -27, 10, 4, -10, 0, -4, 15, 9, -41, 32, -11, 2, -11, 15, -3,
+ -7, -8, 16, -3, -21, 23, -2, -9, -4, -2, 20, -5, -37, 49, -20, -6,
+ -9, 17, 17, -36, -8, 40, -24, -5, 3, 8, 5, -12, -6, 15, 2, -27,
+ 28, -4, -23, 16, 5, -1, -26, 29, 11, -38, 22, -12, -8, 38, -34, -3,
+ 10, 4, -2, -5, -8, 24, -16, -20, 21, 1, -7, 11, -7, -4, -15, 15,
+ 15, -21, -6, 10, -1, 17, -45, 23, 29, -42, 2, 18, -5, -6, -1, 22,
+ -20, -19, 16, 21, -20, -18, 23, 2, 5, -41, 36, 10, -34, 12, 12, -25,
+ 11, 1, 6, -6, -11, 20, -11, 10, -11, -12, 13, 8, -21, 5, -1, 14,
+ 3, -26, 5, 27, -39, 18, 7, -27, 34, -20, 13, -20, 7, -4, 25, -23,
+ -16, 7, 47, -35, -29, 37, 10, -35, 4, 12, -1, 0, -15, 25, -23, -12,
+ 35, 7, -51, 28, -1, 16, -33, 5, 27, -21, 2, -5, 13, -3, 0, -20,
+ 27, -30, 8, 16, -4, -13, 14, -15, 19, -12, -6, 8, -9, 19, -27, 4,
+ 20, -9, -12, 21, -37, 41, -22, 1, 1, 13, -33, 20, 14, -30, -2, 22,
+ 21, -51, 3, 38, -7, -35, 17, 6, 11, -43, 33, 9, -36, 10, 31, -24,
+ -13, 16, -6, 24, -36, -1, 16, 19, -45, 20, 11, 2, -30, 31, -21, -14,
+ 29, -4, -12, 3, -6, 9, 15, -37, 20, -4, 8, -18, 12, -7, 17, -8,
+ -12, -9, 23, 8, -28, 1, 29, -19, -18, 27, -2, -8, -28, 44, -4, -36,
+ 15, 33, -30, -13, 13, 14, -20, -7, 25, -11, -5, -8, 21, -1, -8, -37,
+ 50, 1, -53, 27, 28, -21, -10, 4, 16, -24, 10, 6, -12, 0, 2, 6,
+ 1, -13, 2, 21, -26, 3, 13, -19, 10, 9, -18, -3, 22, -18, -1, -2,
+ 14, -1, -23, 21, -6, -2, -9, 20, 5, -35, 1, 34, -21, -16, 22, 1,
+ -8, -5, 1, 18, -12, -23, 18, 5, -17, -7, 37, -6, -35, 6, 47, -44,
+ -7, 20, 5, -10, -23, 35, -6, -12, -12, 39, -27, -10, 9, 21, -21, -6,
+ 2, 5, 1, 6, -28, 17, 20, -31, -3, 15, 7, -26, 31, -40, 43, -32,
+ 23, -19, 11, -22, 26, -6, -1, -25, 33, 2, -25, -7, 9, 26, -16, -30,
+ 29, 20, -47, 13, 16, -9, -19, 18, 23, -32, -17, 32, 21, -38, -13, 14,
+ 43, -66, 19, 23, 5, -50, 47, -20, 2, -11, 22, -5, -6, -21, 4, 38,
+ -15, -32, 12, 35, -35, -4, 7, 18, -17, -1, -7, 6, 5, 0, 0, -7,
+ 0, -8, 21, -10, 5, -28, 30, 3, -17, -29, 57, -16, -17, -10, 28, -9,
+ -20, 26, -12, 3, -20, 27, -3, -7, -42, 65, -9, -45, -3, 63, -33, -11,
+ -6, 28, -17, -1, -6, 6, 7, -12, 0, 25, -21, -30, 54, -9, -37, 1,
+ 28, 7, -42, 18, 11, 17, -46, 24, -9, 27, -38, 22, -20, 23, -21, 11,
+ -6, 42, -71, 20, 32, -11, -43, 44, -3, -4, -27, 12, 24, -8, -18, -8,
+ 30, -19, -23, 44, -8, -30, 0, 45, -39, 0, -1, 28, -16, -17, -15, 44,
+ -13, -11, -13, 36, -24, -11, 12, 17, -30, 8, 17, -10, -18, 9, 22, -18,
+ -15, 3, 25, -25, 11, -6, 5, 7, -18, -3, 15, -1, -17, 8, 28, -32,
+ -17, 36, 8, -41, 12, 7, 13, -22, -14, 18, 41, -57, -1, 25, 10, -40,
+ 18, 11, -8, -23, 25, -16, 37, -45, 17, 10, 2, -60, 64, -15, -3, -16,
+ 22, -9, 9, -27, 30, -7, -21, 3, 20, -10, 6, -12, 15, -19, 14, -19,
+ 3, 22, -8, -29, 37, -28, 29, -26, 11, -15, 15, -17, 21, -26, 18, 5,
+ -5, -11, 2, 16, -10, -10, -5, 29, -30, 4, 3, 18, -21, 4, 1, 8,
+ -13, -10, 1, 40, -35, -26, 44, 5, -38, 8, 30, -24, 0, -1, 0, 12,
+ -18, -1, 18, -8, -28, 39, -18, 24, -35, 24, -36, 46, -41, 12, -3, 24,
+ -37, 31, -28, 32, -16, 2, -27, 39, -34, 7, 24, -19, -6, 14, -10, -1,
+ 14, -16, -4, 25, -26, -4, 8, 22, -40, 33, -30, 22, -15, 36, -63, 39,
+ 1, 10, -54, 36, 9, 5, -51, 49, -13, 5, -7, -7, 15, -9, -10, 2,
+ 12, -18, 6, 3, 18, -29, 9, 10, -10, 1, -20, 20, -3, -1, -13, 21,
+ -26, 41, -36, 2, 23, -23, -10, 39, -41, 17, -10, 8, 7, -13, 23, -54,
+ 66, -26, -50, 54, 17, -66, 59, -46, 30, -10, 6, -8, -18, 19, 16, -32,
+ 12, 6, -2, 3, -36, 33, -6, -7, 12, -16, 6, 14, -21, 14, 16, -58,
+ 37, 3, 0, -35, 44, -16, 17, -38, 28, -14, 25, -45, 28, -21, 32, -31,
+ 11, 17, -24, 11, 5, -24, 18, -6, -3, 0, -3, 21, -33, 24, 20, -78,
+ 66, -8, -24, 3, 17, -14, 24, -41, 34, -25, 27, -32, 17, -5, 13, -26,
+ 28, -29, 22, -8, -16, 33, -30, 2, 25, -27, 1, 31, -36, -7, 31, -8,
+ -12, -5, 17, -7, 5, -26, 32, 1, -18, -16, 27, -7, -10, 2, 21, -42,
+ 30, -3, -19, 33, -40, 19, 6, -13, -5, 17, -10, 28, -63, 40, 6, -10,
+ -9, 7, -3, 12, -20, -1, 17, -1, -6, -14, 18, 1, -19, 12, 5, -9,
+ -2, -14, 33, -3, -44, 51, -17, -6, -16, 36, -35, 29, -31, 31, -24, 15,
+ -23, 33, -35, 20, -4, -1, -19, 27, -1, -29, 25, 1, -20, 25, -23, -13,
+ 62, -50, -18, 43, -20, 1, -4, 16, -18, 4, -16, 36, -42, 42, -42, 38,
+ -28, 9, -10, 31, -40, 30, -39, 30, 8, -28, 11, 9, -7, -6, -8, 10,
+ 22, -36, -5, 26, 4, -41, 30, 12, -11, -10, -14, 37, -29, 3, -6, 9,
+ -5, 15, -30, 40, -26, 12, -25, 25, -21, -12, 46, -17, -39, 47, 7, -57,
+ 45, -14, 1, -13, 21, -21, 14, -7, 7, -11, 18, -34, 25, 7, -28, 22,
+ 1, -12, 11, -24, 4, 38, -44, 17, 2, -12, 19, -17, 0, 9, 17, -55,
+ 29, 3, 3, -27, 48, -38, 16, -17, 24, -19, 26, -49, 29, 9, -18, -25,
+ 50, 2, -31, -20, 43, -3, -35, 23, 13, -34, 9, 20, -15, -8, 29, -37,
+ 29, -21, 4, -8, 36, -52, 29, -8, 6, -18, 35, -34, 22, -21, 10, 5,
+ -11, -13, 35, -26, -3, 12, -17, 13, 1, -12, -4, 24, -18, -6, 18, -7,
+ -13, 17, -4, -30, 48, -41, 10, 34, -39, -22, 73, -48, -12, 12, 22, -14,
+ -31, 18, 29, -17, -21, 22, -3, -8, -12, 25, -11, 13, -41, 36, -3, -2,
+ -27, 37, -6, -36, 17, 18, -7, -10, 4, -5, 10, -21, 13, 15, -21, 2,
+ -1, -5, 8, -1, -16, 29, -24, 14, -18, 26, -24, 17, -26, 21, -18, 24,
+ -49, 82, -52, -11, 36, -22, -17, 30, -21, 1, 1, -1, 8, -2, -7, 2,
+ 17, -9, -36, 37, -5, -15, -4, 27, -20, 11, -31, 46, -18, -13, -11, 58,
+ -67, 19, -4, 40, -43, 9, -14, 41, -32, -16, 46, -19, -13, 5, -5, 6,
+ 2, -16, 10, -9, 18, -13, 3, 24, -37, 11, 1, 0, -8, -9, 28, -1,
+ -41, 40, -10, 6, -13, 1, -11, 30, -28, -10, 30, 1, -36, 17, 28, -54,
+ 51, -24, 1, -6, 6, -12, 33, -48, 23, 18, -17, -23, 27, 11, -23, -13,
+ 27, -7, -1, -24, 35, 3, -48, 35, 8, -20, -3, 3, 16, -11, 8, -35,
+ 32, 7, -27, -22, 81, -85, 36, -7, 16, -16, 2, 0, 13, -28, 12, -16,
+ 24, 6, -25, -14, 47, -15, -25, 3, 37, -41, -5, 32, -25, 11, 6, -16,
+ 25, -34, 14, 8, 13, -52, 30, 6, 13, -56, 56, -27, 13, -11, -6, 16,
+ -12, -1, 18, -40, 18, 19, -13, -11, 7, -2, 9, 10, -39, 9, 46, -48,
+ -18, 59, -32, -3, 14, -10, 10, -13, 10, -13, 14, -11, -10, 5, 31, -43,
+ 10, 23, -16, 3, -29, 50, -23, -19, 16, 15, -19, 3, -20, 39, -19, -14,
+ -6, 54, -44, -12, 18, 30, -56, 28, -15, 22, -16, -15, 31, -8, -9, -1,
+ 1, 1, 2, -8, 9, 10, -43, 41, -9, 8, -48, 62, -30, -9, 13, 6,
+ -24, 32, -31, 8, -4, 16, -27, 27, -19, -1, -6, 37, -40, 14, -3, 0,
+ 25, -59, 34, 18, -18, -21, 17, 13, -11, -8, -11, 43, -40, 1, 6, 24,
+ -37, 10, 14, -4, -12, -2, 17, 11, -40, 10, 16, 17, -51, 24, 14, -4,
+ -31, 22, 18, -32, 15, -24, 46, -38, 9, 2, -2, 14, -15, -12, 15, 3,
+ -28, 29, -7, -6, 13, -7, -6, 2, 3, -17, 28, -28, -9, 37, -17, 0,
+ 3, 10, -19, -5, 19, -17, 12, -25, 30, -19, 8, -27, 49, -15, -27, 9,
+ 10, 7, -31, 6, 30, -12, -45, 41, 24, -42, -1, 28, -2, -38, 29, -18,
+ 23, -4, -43, 35, 26, -54, 23, 7, 6, -30, 17, -14, 32, -40, 24, -13,
+ 17, -15, -11, 16, 16, -20, -26, 47, -10, -26, -6, 41, -19, -22, 36, -41,
+ 33, 5, -32, 12, 28, -51, 19, 27, -40, 7, 35, -34, 9, -22, 42, -20,
+ -15, -3, 43, -55, 15, 23, -10, -11, 3, 14, -32, 31, -26, 21, 7, -44,
+ 15, 40, -22, -41, 54, -17, -17, 8, -6, 10, 11, -17, -6, 15, -2, -20,
+ 31, -19, 4, -17, 22, 0, 2, -36, 39, 0, -31, 23, -38, 59, -15, -29,
+ -13, 69, -50, -22, 43, -11, -16, 0, 16, -9, -10, 13, 5, -8, -18, 27,
+ -8, -2, -12, 13, -1, -16, 16, -18, 27, -11, -19, 39, -28, -26, 28, 36,
+ -85, 72, -40, 24, -10, 0, -9, 30, -29, -11, 22, -13, -7, 23, -10, -14,
+ 6, 13, -15, 22, -31, 12, 0, 0, -3, -15, 19, 14, -21, -22, 27, 35,
+ -72, 36, -3, 18, -54, 50, -29, 38, -47, 14, 19, -11, -25, 27, 9, -23,
+ -2, 2, 16, -6, -24, 22, 10, -27, 7, 16, -30, 11, 24, -40, 31, -28,
+ 29, 1, -28, 7, 17, 3, -45, 40, -11, -7, 4, 19, -45, 24, 24, -50,
+ 48, -35, 11, 9, -12, -14, 30, -23, 8, 7, -15, -7, 53, -59, 13, 5,
+ 15, -46, 49, -48, 57, -36, -20, 34, 1, -10, -15, 15, 20, -36, -9, 35,
+ 6, -39, 7, 14, 27, -81, 70, -21, 5, -22, 21, -6, 1, -13, 19, -19,
+ 4, -10, 35, -43, 31, -3, -7, -15, 40, -56, 33, -1, -33, 51, -35, -2,
+ 24, -18, 5, 0, 4, -16, 10, -6, 9, -28, 37, -38, 45, -35, 0, 37,
+ -38, 7, 19, -32, 3, 17, -2, -23, 19, 15, -23, 5, -2, 13, 1, -37,
+ 8, 59, -80, 26, 13, 15, -31, -8, 30, -7, -7, -19, 22, -2, -9, -2,
+ 12, -7, 3, 1, -25, 47, -53, 35, -5, -27, 21, 15, -25, 13, -24, 42,
+ -41, 19, 2, -13, 1, 23, -40, 37, -45, 46, -8, -41, 44, -11, -17, 23,
+ -9, -20, 22, -3, -15, 22, -23, 19, -7, 2, -34, 65, -56, 7, 28, -8,
+ -37, 37, 3, -8, -34, 39, -11, 9, -29, 6, 35, -14, -49, 48, 5, -25,
+ 5, -25, 66, -47, -9, 28, -7, -12, 0, 17, -20, -2, 21, -12, -23, 54,
+ -50, 20, 7, -20, 7, -2, 3, 4, -26, 26, -6, -14, 15, -3, -10, 12,
+ -10, -4, 23, -33, 14, -12, 38, -55, 36, 0, -6, -5, 0, -4, 7, 0,
+ -14, 2, 8, -11, 13, 5, -33, 41, 4, -62, 40, 8, -6, -8, -31, 52,
+ -4, -44, 25, 20, -18, -24, 32, -11, -9, -4, 30, -37, 34, -31, 7, 30,
+ -29, -14, 28, -10, -9, 6, 0, -5, 14, -9, -3, -2, 10, -22, 29, -22,
+ -2, 6, -5, 16, -25, 6, 27, -19, -9, -11, 29, -13, -5, -6, 16, 5,
+ -20, -1, 30, -20, -8, 7, -8, -2, 3, 14, -9, -24, 35, -7, -14, -12,
+ 32, -5, -18, -15, 35, -7, -13, -1, -4, 27, -20, -30, 58, -15, -29, 9,
+ 15, -16, -3, 1, 4, 5, -4, -11, 17, 3, -29, 28, -10, -18, 20, -7,
+ -2, 4, 2, -17, 22, -3, -31, 23, 23, -32, -14, 34, -3, -14, -13, 11,
+ 21, -26, -16, 36, -7, -13, 15, -8, -3, -1, -11, 15, -8, -4, -4, 24,
+ -21, 1, 11, 3, -22, 5, 15, -24, 0, 37, -31, 7, -18, 15, 16, -15,
+ -19, 26, 0, -10, -26, 31, 6, -19, -6, 21, -19, 20, -13, -3, 13, -2,
+ -32, 24, 2, -8, -10, 36, -29, -10, 19, 10, -25, 5, -9, 31, -23, -21,
+ 21, 26, -25, -9, -5, 35, -17, -34, 17, 42, -44, -11, 30, 11, -40, 18,
+ 8, -6, -11, 11, -26, 39, -18, -23, 37, -12, -32, 45, -8, -22, 5, 16,
+ -15, -10, 6, 17, -15, -3, 9, -22, 41, -22, -25, 29, 5, -30, 6, 12,
+ 17, -32, 7, 20, -26, 9, 9, -10, 7, -17, 10, 11, -16, -7, 12, 5,
+ -4, -26, 25, 24, -46, -4, 50, -39, -11, 8, 35, -36, 2, -9, 33, -7,
+ -22, -26, 76, -37, -41, 33, 28, -43, 14, 6, 2, -8, 2, -20, 34, -19,
+ -2, -4, 15, -6, -23, 28, -3, -32, 33, -16, 7, -11, 14, 9, -10, -30,
+ 35, -25, 17, -14, 1, 14, 12, -38, 16, 15, -7, -30, 15, 18, -24, -6,
+ 47, -38, 6, 7, -9, -2, -3, 1, 12, -8, -23, 20, 35, -47, -14, 51,
+ -9, -48, 19, 20, 0, -25, -2, 20, 16, -29, -25, 60, -17, -23, -8, 31,
+ -4, -30, 12, 20, -14, -4, -1, 17, -11, -9, 7, 7, -17, 1, -12, 25,
+ -5, -20, 15, 19, -29, 2, 5, 11, -19, -18, 31, 1, -27, 18, -17, 51,
+ -53, -2, 29, 4, -37, 17, 11, -11, -23, 41, -17, -10, 13, -4, -8, 18,
+ -27, 17, 1, -19, -7, 51, -37, -28, 53, 4, -47, 5, 18, 17, -32, -8,
+ 14, 36, -46, 3, 11, 11, -24, 4, 0, 16, -7, -26, 25, 20, -44, 7,
+ 20, -12, 2, -14, 4, 33, -38, 1, 8, 20, -34, -12, 61, -46, -19, 44,
+ -10, -4, -18, 12, 12, -8, -26, 16, 22, 2, -51, 18, 53, -56, -5, 30,
+ -9, -22, 32, -11, -18, 18, 13, -25, -7, 8, 9, 3, -20, 1, 32, -27,
+ -9, 5, 19, -20, -13, 18, 8, 3, -35, 22, 31, -47, -2, 16, -8, 15,
+ -10, -22, 54, -20, -23, -6, 51, -52, -13, 48, -23, -11, 28, -30, 38, -6,
+ -50, 28, 33, -58, 2, 34, 16, -53, -1, 55, -13, -42, 15, 23, -7, -33,
+ 13, 21, -14, -6, 2, -2, 27, -43, 27, 11, -19, -16, 26, -16, -4, 16,
+ -17, 1, 20, -17, 8, -17, 6, 26, -25, -24, 40, -13, 6, -14, -14, 29,
+ 3, -32, -5, 46, -21, -28, 38, -30, 6, 28, -47, 3, 65, -67, -5, 61,
+ -34, -27, 31, 12, -30, -7, 11, 19, 0, -43, 18, 47, -52, -20, 52, -14,
+ -9, -10, -5, 55, -45, -29, 55, 16, -83, 28, 36, -23, 6, -8, -13, 37,
+ -17, -30, 32, -9, -6, 10, -19, 16, 4, 9, -35, 22, -1, -17, 3, 8,
+ 10, -10, -21, 40, -27, -5, 16, -6, -27, 47, -23, -26, 48, -18, -19, 14,
+ -1, -9, 5, 1, -20, 58, -57, -14, 55, -16, -40, 37, -6, 11, -19, -22,
+ 43, 2, -55, 27, 37, -38, -29, 58, -6, -11, -22, 4, 26, -7, -67, 67,
+ 21, -56, 19, 15, -5, 0, 2, -41, 37, 10, -65, 49, 8, 1, -19, 1,
+ 9, 8, -20, -9, 22, -14, -3, 4, -1, 13, -6, -11, 15, -8, -15, 13,
+ 16, -38, 14, 24, -39, 20, 9, -17, 14, -15, 7, 3, -12, -3, 30, -25,
+ -24, 43, -1, -40, 18, 17, 0, -22, -14, 31, 20, -68, 35, 32, -43, -9,
+ 35, -16, 4, 2, -35, 35, 27, -81, 40, 31, -21, -30, 29, -12, 13, 10,
+ -42, 26, 17, -33, -1, 16, 12, -29, 6, 4, 21, -27, -9, 39, -6, -54,
+ 40, -14, 15, -4, -17, 20, 4, -18, -4, 23, -24, -3, 30, -41, 15, 17,
+ -4, -29, 19, 4, -9, -10, 12, 17, -21, -7, 26, -19, -17, 17, 3, 1,
+ -3, -30, 47, 16, -62, -4, 68, -29, -54, 43, -1, -4, 20, -42, 22, 34,
+ -32, -43, 63, -12, -26, 8, -6, 10, 22, -66, 55, 25, -65, 15, 9, 21,
+ -22, -28, 36, 5, -16, -51, 102, -49, -12, 6, 21, -12, -23, 24, -15, 11,
+ -14, -8, 31, 4, -53, 64, -35, 13, -28, 23, -23, 22, -16, 13, -22, 23,
+ 27, -51, -8, 41, 6, -66, 36, 13, 4, -26, 7, 11, 9, -34, 0, 35,
+ -21, -15, 10, 34, -57, 60, -69, 60, -22, 1, -27, 27, 14, -27, 1, -13,
+ 35, -2, -51, 36, 35, -49, 5, -1, 31, -42, 25, -26, 34, -7, -60, 98,
+ -46, -22, -1, 49, -45, -2, 10, 26, -33, 25, -36, 37, -19, 4, -3, -7,
+ 9, 7, -8, -29, 48, -23, 0, -33, 45, 0, -23, -16, 47, -7, -31, -9,
+ 38, -2, -36, 18, -8, 43, -55, 16, -1, 41, -72, 54, -35, 24, 4, -46,
+ 47, -11, 6, -40, 24, 10, 8, -38, 16, 16, 24, -98, 80, 2, -28, -28,
+ 44, 11, -47, 31, -7, 35, -42, -25, 41, 12, -64, 34, 14, -2, -21, 24,
+ -14, 11, -3, -24, 22, -28, 46, -51, 38, -22, 35, -40, 2, 11, 22, -48,
+ 23, -9, 34, -35, -24, 52, -7, -37, 9, 36, -21, 0, -32, 61, -44, 6,
+ -1, -16, 41, -28, 19, -37, 49, -11, -38, -8, 65, -53, 9, -21, 59, -37,
+ 8, -33, 59, -13, -80, 67, 19, -39, -28, 70, -21, -25, -3, 23, 17, -29,
+ -44, 83, -41, 0, -23, 53, -27, -12, 21, -19, 21, -21, 13, -4, -12, -5,
+ 38, -58, 34, 10, -22, -16, 47, -8, -39, 19, 12, 4, -46, 39, -24, 48,
+ -69, 45, -18, 10, -5, -2, -4, 10, -5, 7, -17, -3, 20, 0, -40, 26,
+ 40, -64, 11, 34, 1, -49, 11, 35, -22, -14, -32, 98, -47, -37, 9, 76,
+ -70, -8, 7, 63, -92, 56, -49, 77, -64, 2, 41, -28, -25, 37, 0, -26,
+ 35, -40, 16, 3, 14, -46, 22, 18, -6, -9, -11, 22, 26, -44, -46, 94,
+ -60, 18, -37, 69, -33, 5, -20, 42, -32, -20, 24, -1, -10, -12, 39, -31,
+ 13, 1, 9, -47, 42, -26, 39, -73, 48, 48, -73, -13, 56, 14, -78, 38,
+ 11, 12, -50, 8, 39, 3, -79, 73, 2, -25, -17, 23, 27, -58, 26, -37,
+ 67, -49, 11, -12, 62, -82, 64, -41, 3, 26, -17, -45, 55, -4, -22, 10,
+ -2, 38, -54, 8, 5, 47, -79, 7, 54, -7, -64, 41, 49, -73, 29, -24,
+ 54, -51, -4, 14, 33, -84, 82, -46, 17, -25, 57, -44, -2, 11, 8, 15,
+ -66, 46, 19, -25, -44, 58, 10, -38, -23, 77, -48, -3, -12, 24, 24, -70,
+ 37, 21, -15, -48, 81, -66, 44, -29, 6, 4, 9, -30, 31, -24, 5, 19,
+ -51, 34, 21, 11, -92, 78, 19, -44, -54, 104, -47, -8, -19, 29, 45, -78,
+ 6, 55, -11, -75, 66, -10, 8, -38, 24, 10, 4, -57, 66, -20, -25, 20,
+ 6, 9, -71, 100, -60, -6, 8, 28, -37, 29, -42, 78, -58, -22, 42, 10,
+ -69, 34, 33, -36, 29, -54, 81, -54, 0, 7, 1, -19, 22, -14, 4, -3,
+ 32, -13, -59, 86, -54, 4, 0, 21, -35, 43, -68, 91, -31, -53, 38, 48,
+ -72, -15, 50, 3, -11, -72, 96, -1, -49, -23, 81, -21, -57, 15, 63, -67,
+ 5, 25, -27, 34, -48, 49, -26, 12, -33, 66, -73, 14, 35, -20, -27, 45,
+ -24, 12, -12, 0, 24, -50, 33, -26, 45, -65, 47, -7, -4, -9, 19, -19,
+ -2, 15, -17, 30, -39, 25, 2, -3, -57, 109, -86, 10, 14, 31, -53, 7,
+ 32, 5, -44, -20, 84, -35, -34, -6, 99, -97, 1, 23, 40, -65, 15, 9,
+ 36, -45, -22, 55, 4, -55, -3, 73, -80, 63, -49, 28, 2, -10, -19, 24,
+ -13, 8, 1, -15, 5, 22, -4, -57, 72, -41, 16, -45, 76, -57, 30, -26,
+ 38, -16, -34, 32, 12, -53, 22, 47, -46, -4, 6, 45, -65, 32, -21, 45,
+ -44, -22, 69, -44, -16, 29, 19, -59, 40, -7, 42, -77, 39, -4, 29, -74,
+ 27, 38, -12, -60, 69, 7, -32, 1, -9, 50, -56, -15, 19, 47, -75, 44,
+ 5, -22, 27, -7, -22, 0, 23, -30, 1, 4, 33, -44, 29, -24, 57, -67,
+ 17, 18, 4, -59, 32, 48, -72, 28, -2, 13, -10, -21, 16, 58, -117, 85,
+ -14, -5, -34, 21, 29, -27, -20, 31, 23, -49, 16, -14, 51, -74, 24, 38,
+ -38, -16, 56, -33, -7, 3, 0, 36, -80, 49, 23, -19, -48, 76, -61, 43,
+ -41, 27, -11, 23, -30, 8, 3, 15, -14, -22, 16, 3, 15, -39, 11, 38,
+ -13, -70, 88, -41, 2, 4, -30, 80, -84, 15, 37, -6, -61, 58, -19, 27,
+ -72, 64, -6, -16, -30, 59, -21, -21, -12, 44, 22, -101, 78, -10, -16, -11,
+ 20, -21, 31, -36, 37, -18, -20, 46, -24, -23, 10, 21, -36, 32, -38, 68,
+ -50, 12, -6, 19, -33, 14, -16, 20, -11, -14, 47, -59, 56, -14, -27, 5,
+ 29, -43, 49, -96, 106, -35, -41, 28, 35, -30, -29, 37, 12, -11, -58, 79,
+ -31, -16, -11, 43, -13, -25, 3, 71, -76, -13, 64, -39, 3, -45, 66, -13,
+ -1, -45, 80, -40, 6, -29, 26, -12, 6, -19, 21, -4, 9, 0, -37, 44,
+ -28, 11, -22, 19, 7, 1, -45, 60, -13, -42, 32, -16, 31, -50, 35, 10,
+ -22, -23, 60, -62, 21, -2, 39, -49, -4, 24, 30, -53, -23, 66, -33, 2,
+ -34, 69, -33, -10, 7, 24, -51, 28, 0, 9, -24, -3, 38, -24, -16, -9,
+ 68, -81, 38, -16, 35, -34, -4, 16, 20, -43, 10, 7, -3, 14, -30, 38,
+ -39, 38, -20, -12, -20, 78, -79, 22, -4, 44, -48, -6, 37, -2, -25, -24,
+ 60, -41, 15, -30, 50, -43, 7, 9, 27, -64, 45, 5, -15, -17, 1, 49,
+ -56, 3, -11, 69, -78, 37, -5, 38, -60, 26, -2, 9, -51, 53, -20, -3,
+ 9, -1, 38, -74, 40, 6, -13, -54, 69, -24, 6, -22, 31, 0, -17, 12,
+ -13, 8, -9, 20, -53, 56, -27, 29, -63, 41, 8, 11, -73, 59, 15, -25,
+ -21, -1, 61, -69, 10, 17, 28, -59, 34, -14, 32, -54, 17, 22, -11, -47,
+ 63, 7, -56, 46, -28, 50, -96, 60, 2, 0, -37, 36, -11, 15, -38, 41,
+ -19, -31, 46, -12, -25, 9, 49, -67, 47, -48, 51, -30, -15, 23, 19, -43,
+ 8, 17, 4, -11, -29, 54, -48, 38, -28, 10, -9, 38, -48, 27, -47, 55,
+ 3, -59, 22, 41, -5, -59, 38, 5, 31, -101, 72, 11, -36, -18, 54, -25,
+ -1, -30, 54, -28, -34, 61, -27, 13, -46, 55, -21, -10, -21, 52, -34, -8,
+ 30, -21, 20, -11, -21, 22, -2, -46, 79, -84, 60, -9, 13, -57, 51, 2,
+ -16, -38, 34, 15, -23, -7, -6, 53, -38, -22, 29, 23, -63, 65, -34, -21,
+ 34, -7, -19, -8, 24, 13, -8, -63, 110, -56, -8, -37, 79, -56, -3, -3,
+ 62, -57, 19, 9, 8, -20, -29, 27, 13, -28, -19, 79, -80, 58, -31, 24,
+ -16, -35, 46, 0, -52, 36, 21, -29, 16, -23, 26, -29, 38, -42, 26, -41,
+ 60, -29, -16, -4, 42, 7, -85, 53, 47, -54, -29, 67, -53, 39, -58, 45,
+ -5, 5, -37, 61, -56, 27, 17, -40, 1, 15, 17, -43, 19, 4, 30, -49,
+ 12, -1, 49, -64, -27, 96, -41, -47, 45, 8, -38, 35, -50, 74, -81, 54,
+ -14, 24, -64, 57, -5, -25, -19, 27, 16, -27, 4, 16, 2, -25, 26, -31,
+ 22, -35, 56, -54, 0, 55, -23, -29, 9, 38, -38, 12, -41, 74, -28, -29,
+ -3, 61, -71, 36, -32, 43, -19, -14, 21, 0, -10, -19, 32, -42, 20, 11,
+ 23, -94, 107, -13, -53, 5, 35, -17, -11, -25, 32, 40, -76, 29, 32, -9,
+ -65, 80, -42, 6, -22, 42, -27, -2, 10, -2, 13, -41, 32, 10, -17, -26,
+ 53, -50, 40, -42, 30, -19, 41, -50, 33, -20, -1, 40, -67, 8, 29, 15,
+ -58, 25, 32, 15, -81, 46, 14, -8, -51, 24, 40, -44, 17, 10, 2, -26,
+ 47, -68, 49, -49, 50, -27, -3, -20, 84, -62, -32, 52, 12, -52, 0, 42,
+ -30, 24, -47, 45, -16, 11, -51, 74, -47, -9, 45, -19, -18, -5, 41, -39,
+ 11, -33, 56, -20, -14, -8, 64, -85, 60, -23, -13, -3, 33, -20, -25, 57,
+ -34, 2, -23, 42, -21, 3, -49, 85, -35, -27, 1, 54, -34, -31, 24, 15,
+ 6, -45, 54, -30, 12, -27, 40, -61, 39, 1, -5, -18, 17, 14, 7, -33,
+ -27, 83, -44, -40, 21, 66, -82, 32, -7, 33, -54, 27, 3, 2, -13, -15,
+ 52, -57, 14, 14, -6, -27, 54, -45, 23, -11, 16, -27, 27, -33, -3, 36,
+ -46, 47, -15, -8, -7, 67, -93, 12, 34, 17, -73, 32, 15, 29, -44, -17,
+ 47, 2, -40, -31, 81, -43, 3, -24, 52, -32, 4, 1, 20, -48, 20, 40,
+ -68, 23, 14, 19, -64, 46, -8, 17, -48, 55, -29, 23, -59, 48, -2, -27,
+ 11, 1, 21, -30, 25, -24, 29, -41, 21, 0, -15, -17, 64, -47, 1, 31,
+ -22, 2, -11, 22, -56, 69, -53, 32, -30, 31, -16, 32, -68, 29, 42, -39,
+ -49, 80, 17, -74, 17, 0, 55, -88, 25, 29, 14, -72, 56, 0, 0, -33,
+ 20, 5, -34, 35, -33, 45, -37, 23, -9, 10, -54, 67, -22, -13, -15, 41,
+ -14, -16, 8, 0, 19, -51, 56, -51, 39, -20, 19, -34, 26, -18, 19, -31,
+ 23, 0, 12, -31, 7, 45, -65, 22, 4, 24, -73, 74, -13, -34, 18, 23,
+ -16, -25, -2, 40, 5, -84, 76, -4, 6, -74, 75, -7, -10, -51, 60, -13,
+ 0, -45, 50, 18, -57, 20, 21, -7, -26, 47, -51, 28, -19, 12, -13, 3,
+ -1, 20, -23, 1, 28, -18, 3, -41, 67, -72, 34, -11, 33, -47, 47, -9,
+ -20, -2, 28, -21, -27, 11, 26, -15, -25, 57, -44, 46, -67, 49, -5, -30,
+ 1, 42, -36, -9, 22, 7, -13, -34, 67, -29, -16, -26, 84, -49, -21, -11,
+ 77, -53, -43, 62, 0, -3, -32, 23, 13, -5, -69, 88, -42, 7, -17, 37,
+ -35, 27, -6, -13, -11, 31, -17, -28, 45, -17, 8, -32, 41, -48, 39, -35,
+ 41, -16, -28, 41, -3, -13, -26, 23, 12, -22, -50, 104, -57, 9, -28, 67,
+ -53, -7, 0, 45, -41, -22, 50, -8, -21, -9, 38, -19, -18, -2, 55, -76,
+ 38, -12, 39, -49, -14, 64, -24, -45, 25, 50, -66, 23, -15, 32, -36, 32,
+ -46, 44, -14, 2, -16, 22, -7, -11, 14, -28, 21, 4, -10, -18, 63, -66,
+ 30, -20, 36, -35, -16, 26, 12, -37, 6, 50, -35, -15, 6, 48, -64, 4,
+ 12, 46, -85, 33, 12, 25, -49, -11, 77, -53, -18, 19, 29, -41, -1, 3,
+ 39, -70, 55, -6, -1, -23, 38, -22, -12, 1, -11, 36, -39, 5, 15, 33,
+ -55, 32, -8, 6, -37, 39, -32, 4, 27, -23, 11, -1, 10, -28, 19, -24,
+ 52, -69, 27, 21, 11, -72, 52, 17, -35, -13, 16, 33, -44, 4, 19, 18,
+ -60, 13, 35, 12, -93, 82, 9, -35, -20, 26, 40, -74, 14, 18, 28, -66,
+ 37, 4, 9, -43, 34, -15, 17, -35, 38, -11, -14, 14, -5, 2, -36, 54,
+ -35, 2, 1, 29, -35, 9, -4, 24, -32, -5, 31, -19, -17, 28, 34, -86,
+ 49, 13, -16, -52, 71, -29, 3, -30, 51, -1, -36, 6, 25, 4, -75, 56,
+ 10, -21, -18, 37, -16, 17, -53, 60, -7, -38, -9, 63, -18, -70, 67, 1,
+ -19, -32, 50, -20, 11, -23, 24, -10, -3, -21, 32, -26, 7, 12, -19, 35,
+ -29, 26, -41, 32, -22, 14, -43, 41, 7, -16, -24, 57, -20, -35, 25, 7,
+ -11, -20, 31, -18, 10, -34, 44, -7, -22, -9, 49, -33, -18, 26, -4, 12,
+ -63, 51, 11, -16, -40, 80, -28, -37, 5, 61, -78, 22, 16, -3, -10, -5,
+ 26, -8, -2, -43, 68, -42, -24, 39, 11, -31, 15, -9, 18, -20, -1, 7,
+ -17, 26, -30, 31, -31, 42, -28, -1, -15, 49, -51, -2, 26, 3, -12, -11,
+ 7, 22, -9, -51, 70, -27, -14, -13, 53, -37, -12, 9, 44, -57, -14, 51,
+ -6, -27, -10, 60, -55, 2, 14, 18, -45, 32, -19, 29, -27, -12, 31, 14,
+ -54, 17, 41, -62, 51, -40, 40, -40, 12, -8, 28, -39, 16, 10, 10, -46,
+ 37, 12, -42, 17, -4, 2, -17, 35, -34, 38, -30, 21, -6, -36, 36, 13,
+ -56, 14, 53, -36, -13, -1, 61, -64, 7, -3, 54, -63, 5, 14, 34, -67,
+ 10, 46, -27, -18, 26, 20, -41, 14, -13, 40, -66, 20, 38, -34, -11, 39,
+ -16, 11, -26, 7, 28, -58, 26, 0, 30, -61, 44, 11, -30, -17, 66, -40,
+ -33, 35, 6, -21, -2, 9, 16, -13, -39, 79, -71, 27, 9, -9, -29, 28,
+ 4, -17, 1, 14, 2, -20, -2, 16, 24, -67, 20, 37, -4, -80, 75, 18,
+ -46, 2, 10, 25, -31, -28, 43, 19, -75, 59, -13, 14, -40, 29, 7, -22,
+ -20, 44, -20, -16, 10, 32, -21, -42, 61, -19, -29, 12, 39, -55, 32, -4,
+ 0, -2, -24, 40, -19, -38, 34, 22, -33, 11, -3, 31, -49, 21, -16, 40,
+ -54, 12, 29, -19, -8, 17, 17, -52, 28, 22, -39, -2, 45, -42, 23, -46,
+ 51, 11, -68, 26, 55, -34, -44, 45, 9, -19, -43, 57, -16, -5, -9, 40,
+ -24, -12, 8, 29, -54, -4, 50, -37, 0, 11, 7, -4, 0, -25, 57, -62,
+ 19, 18, -7, -22, 12, 19, -27, 9, -5, 15, -19, 2, 15, 4, -45, 36,
+ -5, 8, -48, 60, -13, -35, 36, -19, 21, -24, -7, 23, -24, -22, 73, -58,
+ -5, 34, 25, -71, 19, 30, 0, -43, -4, 50, -9, -21, -21, 69, -28, -46,
+ 24, 29, -45, 12, 3, 21, -13, -28, 47, -9, -37, 21, 22, -46, 21, 8,
+ -1, -32, 42, -22, 14, -27, 19, 16, -29, 3, 17, -1, -39, 28, 21, -42,
+ 8, 47, -45, 2, -16, 50, -20, -54, 50, 9, -25, -12, 41, -29, 8, -3,
+ -5, -13, 25, -16, 19, -30, 15, 15, -2, -52, 38, 38, -69, 12, 37, 9,
+ -54, 10, 36, 5, -79, 27, 57, -35, -40, 48, 21, -41, 13, -3, 10, -29,
+ 4, 18, 4, -50, 52, 1, -28, -6, 41, -25, -22, 34, -22, 10, -5, 3,
+ -6, -1, 2, 26, -48, 24, 12, 5, -54, 36, 18, -32, -6, -3, 48, -28,
+ -21, 22, 35, -63, 6, 43, -28, -27, 42, -7, -22, 6, 21, 8, -56, 31,
+ 23, -10, -73, 76, 18, -49, -26, 70, -21, -23, -8, 35, 0, -42, 7, 42,
+ -26, -28, 47, -31, 0, 13, 11, -25, 14, -6, 10, -13, -26, 40, -14, -5,
+ -8, 42, -36, 1, 15, -10, -34, 47, -24, 5, -22, 38, 14, -39, -10, 53,
+ -26, -67, 72, 0, -15, -25, 29, 19, -29, -25, 50, -14, -31, 10, 42, -44,
+ -24, 81, -40, -32, 12, 45, -41, -5, -1, 47, -27, -54, 54, 32, -64, 4,
+ 26, 1, -1, -41, 44, 4, -22, -22, 47, -30, 7, 5, 3, -37, 45, 1,
+ -53, 44, -1, -20, 7, 12, -13, 9, -23, 26, -2, -47, 32, 37, -61, 6,
+ 42, 0, -25, -43, 76, -23, -38, -10, 73, -24, -57, 47, 45, -70, 3, 19,
+ 7, -19, -8, 10, 24, -12, -36, 66, -60, -1, 50, -32, -19, 8, 26, 2,
+ -44, 11, 53, -42, -26, 20, 42, -52, 14, 16, -26, -11, 42, -41, 16, 16,
+ -23, 13, 1, -6, 17, -18, -41, 71, -39, -23, 40, 13, -30, 2, 19, 0,
+ -39, 10, 24, -15, -25, 12, 66, -81, 6, 47, 9, -69, 12, 47, -9, -36,
+ -27, 76, 9, -107, 58, 53, -68, 19, -10, 39, -49, 8, 14, -11, -17, 21,
+ 18, -25, -17, 47, -4, -48, 32, -9, -4, -3, 8, -5, 29, -40, 13, 14,
+ -31, 24, 7, -48, 27, 37, -61, 22, 15, 7, -46, 17, 10, 22, -45, -9,
+ 56, 1, -73, 43, 34, -51, -15, 40, 2, -47, 35, 8, 27, -87, 31, 86,
+ -94, -27, 67, 10, -44, -15, 43, 11, -46, 6, 9, 33, -71, 35, 26, -30,
+ -18, 37, -18, -9, 20, -15, 1, 5, 9, -2, -23, -11, 50, -42, -3, 24,
+ 6, -21, 17, -5, -8, 11, -26, 24, -19, -9, 33, 22, -78, 38, 44, -48,
+ -53, 80, 6, -66, 14, 36, 8, -37, -15, 66, -24, -75, 87, -14, -27, -10,
+ 45, -12, -38, 13, 33, 7, -67, 20, 75, -55, -67, 85, 8, -52, -11, 45,
+ -10, 13, -34, 12, 26, -36, 7, -1, -1, -7, 23, -27, 18, 15, -12, -28,
+ 27, -6, 9, -52, 40, 26, -50, 3, 51, -10, -71, 67, 10, -59, 4, 56,
+ -27, -20, -19, 58, 6, -81, 38, 49, -39, -39, 47, 14, -25, -40, 54, -2,
+ -20, -38, 82, -25, -51, 44, 24, -60, 8, 51, -47, -2, 6, 22, 9, -34,
+ -20, 78, -56, -25, 36, 19, -49, 17, 32, -50, 44, -29, 4, -11, 14, 3,
+ -13, -11, 19, 13, -24, 28, -32, 33, -37, 39, -61, 119, -76, 120, -70, 99,
+ -122, 89, -113, 91, -123, 122, -123, 77, 86, -116, 6, -118, 123, -23, 64, -93,
+ 17, 24, -125, 124, -125, 124, -24, -12, 56, 87, -54, 38, -91, 64, -2, -41,
+ 126, -127, 20, 8, -48, -62, 127, -128, 88, -43, -18, 86, -100, 44, -32, -26,
+ 71, -13, 6, 51, -33, -50, 106, -59, 33, 5, -20, 69, -56, 54, -48, -6,
+ 38, -5, -38, 35, -1, 12, -1, 4, 23, -56, 19, -7, 5, -4, 31, -38,
+ 3, -12, -9, -25, -7, 24, -32, 17, -21, -22, 24, -20, 6, -18, 0, -15,
+ 5, -16, 15, 3, 2, -10, 3, 27, -31, 37, -12, 32, -5, 2, -21, 27,
+ -14, 20, -8, 5, 15, -7, -11, 20, -37, 7, -23, 17, -22, 11, -14, 8,
+ -44, 39, -52, 26, 3, 14, -10, 51, -45, 29, -19, 19, -3, 41, -21, 46,
+ -23, 10, 16, -25, 3, 7, -30, 19, -9, -5, -1, 1, -19, 1, -24, -23,
+ 51, -48, -10, 17, -34, -38, 60, -71, 26, -43, 65, -59, 70, -26, 61, -51,
+ 63, -51, 42, -25, 58, -36, 31, 10, -14, -9, 8, -18, 8, 4, 8, 7,
+ 31, -52, 39, -53, 53, -56, 24, 11, 1, -20, -8, -32, -18, -10, -25, 4,
+ 1, 37, -37, 42, -42, 53, -57, 52, -18, 30, 11, 20, -52, 55, -61, 56,
+ -50, 24, -26, 38, -42, 36, -1, -43, 58, -46, 6, 18, -35, 31, -36, 28,
+ -55, 55, -98, 52, -41, 26, -24, 48, -31, 48, -26, 30, 19, -17, 23, -8,
+ 13, 15, 19, -7, -23, 41, -36, 20, -39, 65, -64, 66, -38, -9, 7, -14,
+ -10, -3, 6, 15, -19, -40, 53, -67, -11, -12, -25, 23, -11, -12, 46, -48,
+ 39, -20, 20, -14, 31, -54, 71, -25, 2, -8, -5, -9, 1, 7, 27, 17,
+ -14, 43, -31, 27, 11, -33, 20, -2, -33, 45, -38, 17, -9, -11, -17, -22,
+ -19, 20, -25, 4, 29, -35, 14, -17, 1, -7, 19, 2, 16, 32, -3, -17,
+ 4, 0, -9, 17, 5, -8, 52, -32, 40, -39, -5, -18, 14, -21, 31, 10,
+ -17, 8, -34, -7, 1, -44, 7, 10, -8, -6, -18, -25, -1, -19, 16, -29,
+ 62, 6, 9, 21, 0, -14, 4, 5, 20, 13, 27, -1, 18, -5, 21, -31,
+ 11, 2, -9, -4, 21, -27, 8, -21, -28, -19, 14, -12, 5, -20, 20, -36,
+ 4, -18, -27, -4, -4, 15, 4, 48, -7, -11, 20, -6, 7, 20, 1, 20,
+ 0, 35, -35, 28, -37, 7, -43, 21, -22, 23, -18, 12, -22, -13, -20, -11,
+ 7, 23, -10, 19, -18, 17, -41, 4, -16, -8, 21, 11, -4, 10, 30, -24,
+ 32, -15, 15, -13, 28, -5, 38, -10, 0, -22, -13, -12, 24, -18, 30, -7,
+ 4, -16, 27, -28, -3, -1, 18, -14, 31, -24, -3, -13, -19, -36, -2, -31,
+ 9, -2, -12, 17, 12, -50, 46, -49, 43, -15, 13, 22, 15, -25, 10, -8,
+ -6, 14, -2, 24, 15, 9, 17, -13, 5, 14, -15, 7, 20, 4, 4, 18,
+ -16, 3, -47, 31, -46, 19, -24, 5, -19, -1, -42, 14, -44, 18, -7, -1,
+ 15, 9, -35, 32, -44, 39, -46, 23, -16, 36, -25, 45, -34, 32, -8, 10,
+ 5, 28, 0, 12, 11, 3, 20, -23, 6, -8, 16, 7, 17, -19, 32, -44,
+ 3, -8, -21, -8, -5, 2, -29, 2, -3, -19, -14, 3, 7, -23, 10, 1,
+ 3, 8, 13, -44, 20, 21, -16, 23, 3, 5, 10, -11, 32, -11, 13, -7,
+ 30, 4, 16, -7, -6, -7, 14, -40, 4, -16, -26, 3, -1, 0, -6, 5,
+ -50, 37, -27, 18, -16, -14, 6, -1, -4, -15, 8, -12, 14, 9, -22, 42,
+ -10, 23, -11, 36, -15, 13, 30, 1, 47, -20, 33, -14, -12, 1, -20, -9,
+ -9, -11, -13, 7, -37, 25, -47, 14, -13, 4, -12, 9, -32, 18, -48, -1,
+ -35, -1, -7, 35, -20, 53, -4, 34, -7, 13, 19, 9, 30, 6, 45, -22,
+ 23, -18, -6, -1, 3, -30, 14, -15, 9, -39, 10, -33, -13, -24, 10, 14,
+ 14, -10, 2, -34, -4, -20, -21, -14, 40, -10, 17, -14, 28, -17, 37, -26,
+ 69, -15, 38, 2, 21, -25, 37, -61, 13, -9, 5, -17, 18, -41, 22, -57,
+ -1, -9, -13, 24, -10, 38, -5, 8, -16, -2, 1, 12, -25, -2, -13, 2,
+ 2, -16, -19, 32, -30, 22, 20, -4, 12, 11, -17, 19, -17, -3, 20, -33,
+ 65, -27, 32, -14, 8, -8, 13, -19, 9, -2, 7, 33, -40, 18, -18, -18,
+ 6, -23, -11, -11, -28, 4, -11, -15, -14, -8, -5, 34, -6, 19, 1, -3,
+ 9, -1, 5, 5, 14, -11, 40, -3, 18, -20, 16, -7, 2, -5, 9, -16,
+ 9, -17, 0, -17, 4, -17, -3, 3, 8, -14, -19, 12, -21, -7, 1, -2,
+ -8, 16, 3, -6, 35, -23, 33, -13, 11, 12, 3, -7, 26, -11, 19, -18,
+ 23, -22, 39, -49, 39, -50, 11, -38, 26, -29, 10, -6, -22, 15, -8, 15,
+ -37, 36, -43, 39, -43, 18, -26, 1, 11, 4, -2, 9, 7, 2, 7, 19,
+ 1, 1, -4, 16, -5, 16, -9, -3, 4, -4, -1, -17, 0, 11, 16, -27,
+ 12, -15, 15, -3, 0, 10, -3, -5, 12, -13, -7, -13, -31, -1, -3, -17,
+ 15, -31, 25, -10, 15, -1, 2, 4, 10, 7, 32, -13, 7, -22, 2, -10,
+ 16, 1, -15, 19, -24, 16, -18, -12, 18, -9, 9, 24, -8, 8, 11, 0,
+ -31, 17, -55, 21, -43, 40, -40, 29, -54, 44, -34, 22, 11, 16, 7, 19,
+ 21, -6, 2, -7, -16, 22, 0, -1, -4, 5, -8, 26, -42, 4, -6, -21,
+ 35, -16, 8, 0, -22, -13, 11, -31, 7, -28, 4, 17, -12, -18, -2, -23,
+ 23, -1, 19, 34, 7, 7, 35, -19, 11, -8, -17, 8, 4, 16, -16, -13,
+ 9, -15, -5, -1, -6, 7, 3, 11, 1, -7, -24, 21, -31, 36, -3, -10,
+ 8, 2, -17, 12, -24, 6, -3, 9, 15, 3, 13, -8, -13, -3, 6, -19,
+ 14, -33, 16, -17, -5, -31, 3, -29, 24, -7, -6, 35, -20, -5, 34, -20,
+ 25, -3, 10, 25, 8, 14, -13, 0, 1, 17, -33, 51, -38, 45, -32, 39,
+ -3, -2, -24, 3, -18, 14, -4, -44, 2, -25, -15, -2, -23, 3, -2, -2,
+ 20, -14, 8, -10, -4, 21, 11, -13, 32, -4, 8, 19, -16, -2, -2, -2,
+ 14, -2, -1, 27, -26, 20, 11, -13, 10, -3, -7, 12, -13, -3, -30, -16,
+ 10, -26, -3, -10, -2, -9, 15, -17, 1, -2, -7, 14, -8, 12, -3, -1,
+ 2, 47, -26, 22, -19, 16, 2, 13, -3, 21, -10, 22, -32, 43, -24, 16,
+ 0, 5, -2, 12, -44, -12, 1, -26, 1, -36, 5, 2, 9, -17, 20, -37,
+ 14, -9, -5, 6, -3, -13, 23, -19, 25, -33, 6, 17, 10, 19, 15, -4,
+ 12, 5, -9, 33, -20, 26, -9, 11, -2, 11, -21, -7, -13, -4, -8, -12,
+ 0, -10, -9, 8, -33, 9, -26, 8, 6, -8, 12, 7, -8, 0, 7, -16,
+ 25, -8, 27, 12, 0, 9, -9, 4, -17, 14, -16, 11, -8, 18, -2, 4,
+ 2, -20, -18, 22, -16, -5, 3, -24, 13, -10, -12, -10, 2, -16, 33, -15,
+ 21, -15, -4, -19, 29, -22, 18, 2, 20, 12, 18, -22, -7, -16, 7, -19,
+ 14, 1, -17, 33, -22, 38, -8, 3, -3, 21, -17, 51, -43, 15, -22, -23,
+ -6, -12, -14, 14, 9, 6, 4, -31, 3, -16, -14, 22, -22, 5, 13, -25,
+ 17, -2, -18, 7, 1, 5, 36, -16, 23, 4, -15, 29, -20, 10, 1, 24,
+ 17, 16, -4, -16, -37, -11, 1, -33, 27, -36, 17, -22, 2, -33, 16, -29,
+ 32, -7, 24, -12, 14, -12, 22, -16, 15, -20, 19, 9, 14, 12, -1, -24,
+ 13, -6, -1, 32, -19, 24, 12, -26, 4, -31, -38, 18, -16, -13, 3, -14,
+ -1, 11, -15, 15, 0, -2, 30, -6, 35, -23, 10, -35, 5, -14, 17, -21,
+ 20, 4, 7, 8, -5, -15, 20, -25, 26, 6, -3, 3, 5, -24, 26, -35,
+ 4, 0, -6, 13, -23, 8, -25, 1, -2, 9, 3, 17, 4, 0, 13, -15,
+ 3, -21, -16, 4, -5, -10, 11, -2, 7, 23, -22, 25, -19, 18, 25, -9,
+ 14, -21, -7, 11, -24, 22, -12, -7, 6, 9, -33, 11, -20, 2, -9, 2,
+ 3, -13, 12, -15, 23, -21, 16, -16, -2, 8, 13, -12, 18, -10, 16, -12,
+ 20, -18, 18, -1, 21, -21, 20, -30, -6, 10, -2, 13, -6, -15, 6, 2,
+ -1, 1, -19, 9, -15, -3, -11, 0, -5, 1, 5, 1, -4, -8, 1, -16,
+ 23, 0, -23, 2, 8, -6, 38, -4, 2, 13, -17, 31, -4, -8, 22, -14,
+ 0, 12, -22, 7, -7, 11, 4, -4, -12, -9, -22, 2, -17, -17, -11, 7,
+ -17, 19, -24, 9, -8, -6, 29, -4, 10, 4, 4, 23, -1, 9, -6, -12,
+ 23, 16, -6, 33, -29, 12, -7, -10, 17, -4, -18, 21, 0, -14, -2, -20,
+ -21, 10, -28, 5, -18, -4, 0, -11, 1, 5, -17, 3, 9, 20, 6, 1,
+ -7, 2, -7, 3, 9, -22, 29, 6, -1, 25, -10, 6, -1, 4, 12, 18,
+ -13, 28, -11, 6, -15, -14, -22, -7, 5, -14, 1, -16, -12, -5, 5, -9,
+ 4, -1, -14, 21, -10, -5, 0, -17, -7, 2, -10, 6, 11, 1, 37, -17,
+ 6, 21, -24, 41, 2, 23, 0, 10, -18, 16, -26, 14, -21, -19, 18, -9,
+ -14, -1, -9, -14, -3, -7, -10, 7, -7, 19, -11, 15, -25, -3, -6, 2,
+ 8, -10, 4, 12, -3, 11, -2, -2, 5, 31, -9, 39, -21, 14, -23, 18,
+ -16, -1, -3, -6, 0, 22, -9, -5, -17, -4, -12, 2, -3, -7, 10, -10,
+ 7, -20, -19, -10, 0, -14, 32, -15, -18, 13, -9, 2, 17, -14, 6, 36,
+ -9, 28, 1, 0, 17, -10, 5, 17, -8, 12, -2, 3, 2, -22, -6, -14,
+ 6, 8, -11, -14, 2, -23, 25, -35, 3, -18, 1, -14, 22, -1, -12, -7,
+ -9, 13, -4, 12, 4, -3, 18, 0, 1, 8, -14, 14, -2, 1, 17, -3,
+ -14, 35, -17, 19, -14, -6, 1, -9, 18, -17, -4, -13, -2, -14, 10, -10,
+ -6, 0, 3, 5, -12, -13, -3, -6, -6, 11, -13, -7, 13, -2, 6, 13,
+ -7, 11, -5, 23, 1, 29, -17, 23, -10, 18, -16, 12, -20, 10, 7, -9,
+ -5, -21, -9, 5, -13, -2, 0, -15, -11, 3, 0, -18, 5, -25, -2, 3,
+ -2, -3, 4, 8, 14, -7, 15, 4, 8, 19, 9, 11, 7, -3, 14, -11,
+ 1, 15, -35, 3, 3, -10, -16, 0, -15, 2, 3, -12, 27, -23, 32, -15,
+ 10, -14, 3, -27, 10, -15, 12, -24, 7, 2, 9, -2, -2, -1, 3, 1,
+ 1, 8, -4, 0, 6, -6, 1, 1, -1, 8, -11, 31, -27, 13, 4, -3,
+ 5, -1, 0, 2, 9, 0, 12, -31, 4, -27, 1, -25, 20, -21, -14, 12,
+ -14, 0, -5, -23, 18, -1, 15, 19, -5, 20, -8, 14, -7, 16, 3, 0,
+ 8, 10, 0, -8, -10, 3, -8, 9, -12, 4, 15, -6, 2, -12, -29, -3,
+ -16, -11, 35, -18, -1, -28, 7, -12, 0, 7, -5, 22, 10, 10, -4, 6,
+ -13, 21, -23, 20, 8, -13, 11, 15, -6, -6, -22, -1, 3, 14, 7, 11,
+ -27, 12, -17, -12, 8, -15, 3, -8, 12, -12, 5, -30, 12, -18, 9, -2,
+ 3, 4, 15, 1, 5, -9, 0, -8, 24, -2, 21, 5, -4, -4, 14, -15,
+ 0, -1, 3, 17, -5, 13, -19, -10, -4, -6, -4, -7, 18, -27, 8, 1,
+ -12, -21, -13, 1, -9, 11, 1, -3, -1, 22, -21, 9, 6, -3, 20, -2,
+ 17, 7, -12, 1, 4, 4, -9, 9, -20, 24, 7, -9, -3, -7, -6, 10,
+ 7, 3, 9, -2, -3, -4, 1, -19, -8, -16, 0, -12, 0, -25, 4, -22,
+ 10, -9, 0, -3, 15, -1, 8, 11, -15, 10, 13, 1, 22, -5, 15, 1,
+ 24, 6, 0, -6, 5, 5, 10, 8, -1, -11, -14, 3, -31, 2, -22, -4,
+ -8, -15, -2, -31, -12, 6, -7, 5, 2, 3, -4, 19, 3, 4, 7, 7,
+ -8, 31, -6, 26, 1, -2, 2, -3, -10, -4, -4, 9, 3, 12, -16, 16,
+ -9, -1, 5, 4, -7, 13, -17, 0, -11, -13, -22, 1, -9, 4, -7, 7,
+ -10, 5, -1, -6, -3, -21, 7, -10, 18, -3, 1, -7, -11, 11, -8, 12,
+ 20, 3, 13, 16, -1, 3, 13, -3, 23, 16, -3, 15, -14, 12, -6, -8,
+ -28, 0, -33, 4, -11, -12, -13, -21, -17, -16, -5, -12, 16, -7, 15, -6,
+ -5, 3, -9, 21, 17, 13, 14, 11, 21, -12, 31, -18, 7, 12, 8, 9,
+ 7, 1, -3, -7, -14, 17, -35, -10, -2, -18, -8, -10, -20, -22, 2, -10,
+ -3, 1, -1, 4, -5, 11, -20, 11, -6, 27, 7, 18, 8, -1, 2, 3,
+ 11, -9, 5, 5, -7, 29, -6, 20, -21, 23, -15, 19, -19, 2, -22, 11,
+ -26, -7, -10, -30, -1, -3, -6, 15, -22, 16, -7, -9, -2, -7, -5, 11,
+ 17, -13, 2, 8, -5, 6, 27, -6, 12, -6, 4, 15, 3, 14, -3, -12,
+ 11, -2, 6, 5, 4, -6, -12, 0, -32, 2, -22, 22, -12, -5, -7, -11,
+ -7, 6, -1, -3, -3, -16, 2, -1, 0, 0, -7, -2, 1, 12, -4, 5,
+ 20, 1, 16, -2, 14, -1, 19, 8, 29, -8, 7, -14, -2, 3, -13, 8,
+ -40, 22, -18, 2, -14, -8, -11, -8, 12, -21, -1, -10, -12, -6, -4, -14,
+ 6, -19, 7, 14, 1, 11, 11, -11, 25, 1, 14, -5, 31, 0, 22, 4,
+ 1, 3, 6, -3, 4, -2, -20, -7, -26, 1, -12, -7, -10, 2, -1, -5,
+ -7, -8, -10, 6, -7, -6, 10, -17, 6, 3, 15, -8, 15, -7, 12, 1,
+ 9, -4, -2, 10, 9, -1, 10, -4, 9, -8, 17, 0, -13, -7, -2, -11,
+ 3, -2, -15, -4, -11, -5, -9, 1, 8, -10, 8, -8, -6, -18, 21, -19,
+ 26, -19, -1, -11, 10, 4, 12, -10, 16, -10, 17, 8, 13, -1, 17, 1,
+ 5, -1, 11, -8, 9, 16, -17, 3, -26, -17, -14, 6, -17, 4, -20, 0,
+ -1, -6, -4, 2, -15, 13, -3, -1, 0, -2, -8, 11, 7, -3, -8, 5,
+ 14, -1, 28, -19, 13, -4, 8, 1, 11, 7, 6, -8, -2, -13, -10, -22,
+ 6, 11, -1, -1, -5, -13, 18, 3, -10, 9, -17, -8, 9, -9, 1, -17,
+ -4, -16, 18, -6, 15, -10, 17, 5, 0, -5, 0, -11, 12, 15, 4, 8,
+ 5, -4, 0, -2, 3, -17, -2, -1, 11, -6, -7, 2, -33, 23, -6, -1,
+ -2, -2, -1, -8, 3, -29, -2, -34, 16, -3, 16, 1, 10, -12, 23, 0,
+ -3, 16, 12, 19, 23, -1, 8, -26, 16, -32, 26, -13, 2, -11, 5, -1,
+ -15, -9, -16, 7, -6, 14, -15, 5, -10, -7, -9, -9, 6, -17, 13, 18,
+ -5, -3, -4, -4, -18, 28, -6, 13, 17, 24, -2, 9, -14, 1, -11, 7,
+ 17, 1, -15, 10, -23, -4, -12, 5, -20, 17, -10, 6, 0, -9, 4, -8,
+ -15, 6, -16, 7, 9, 3, 6, -12, -17, 0, 4, 13, 22, -4, 10, -8,
+ 7, -12, 5, 5, 1, 11, 2, 10, -3, -2, 3, -10, -5, -7, -4, -18,
+ 17, -2, -14, -16, -7, -10, -3, 6, -1, 14, -11, 15, -18, 2, -6, 0,
+ -1, 0, 20, -17, 1, 6, 2, 6, 12, -3, 7, 25, -5, 17, -14, 0,
+ -6, 0, -2, -5, -1, -10, 8, 2, -9, -19, -7, -17, 5, 3, -7, 4,
+ -15, -5, 9, -12, -1, -5, 3, -5, 26, -2, 3, -4, 5, 3, 7, 10,
+ 5, 6, 6, 26, -17, 0, -1, 3, -3, 10, -7, -7, -9, 11, -18, 0,
+ -16, -6, -5, 3, 7, -14, -14, 0, -21, 14, -8, -1, -12, 2, 1, 2,
+ -3, -1, -3, 18, 5, 5, 9, 12, 7, 18, 8, 5, -25, 16, -15, 16,
+ -7, 9, -22, 1, 14, -13, -5, 2, -6, -8, 13, -17, 6, -16, 1, -5,
+ -14, -6, -6, -15, -2, 9, -9, -18, 15, -19, 12, 7, 4, 8, 14, 15,
+ 6, 10, -3, 9, -7, 23, -17, 21, -20, 7, 0, -9, 8, -10, 1, 4,
+ 2, 3, -9, -9, -15, -6, -21, -16, -6, 0, -11, 19, -8, -9, 5, -6,
+ 0, 5, 14, 7, 1, 12, 8, 7, -5, 12, 8, -4, 19, 4, -7, 2,
+ 3, -12, -8, -1, 0, 5, 7, -5, -8, -22, -8, -21, -2, -9, 10, -20,
+ 13, -6, 8, -17, -9, -6, 2, 5, 8, 6, -3, 10, -9, -2, 15, -6,
+ 20, 7, 11, 10, -3, -4, -8, 25, -25, 18, -12, 17, -6, 20, -22, -1,
+ -17, -10, 5, -10, 9, -13, -9, -6, 10, -25, -5, -2, -5, 13, 2, -5,
+ -8, -10, 11, -27, 10, -4, 11, 0, 33, -4, 10, -14, 1, 12, -2, 27,
+ -8, 6, 11, 9, -12, -4, -10, -13, 12, 5, 1, -10, -14, -15, -8, -7,
+ -9, 3, -5, 10, 3, -11, -12, -13, -3, -3, 3, 2, 9, 17, -6, 25,
+ -3, -3, -8, 19, 3, 30, -10, 12, -22, 7, -5, -10, -3, 21, -8, 12,
+ 6, -5, -13, -13, -9, -9, -1, -23, 13, -17, 15, -22, -11, -18, 8, -14,
+ 20, 1, 4, -5, 3, 3, 5, 11, 1, 2, 27, 1, 10, -7, -8, -2,
+ -2, 7, -1, 17, -5, 24, -7, 5, -10, -20, -6, 5, -4, -5, -1, -18,
+ -5, -14, -1, -20, 1, 7, -7, 12, -4, -2, -4, 2, 8, 0, 7, 1,
+ 6, -2, 18, -5, -7, 4, 3, -2, 13, 4, 0, 2, -3, 2, -10, -6,
+ 1, -6, 6, -7, -3, -21, -2, -12, 5, -1, -9, 7, -3, 13, 5, 5,
+ -8, 0, -8, 19, -5, 13, 13, -7, 3, 0, -10, 0, -8, 20, -8, 13,
+ -20, -5, -7, 3, 5, -7, 2, -5, -4, -14, 11, -23, -13, 2, -1, 12,
+ 13, 5, -6, 23, -9, 9, -6, -9, 18, -13, 16, -3, -7, -17, 3, -13,
+ 12, -9, 4, 0, 0, 13, -18, -1, 3, -13, 20, -5, 1, -20, 15, -23,
+ 18, -4, -8, 5, -7, 16, 4, 6, -3, 7, -21, 19, -17, -7, 9, 5,
+ 3, -5, -3, -16, -9, 25, -9, 12, -5, 10, -5, 9, -4, -6, -3, 4,
+ 10, -2, 11, -12, -2, -14, 8, -23, -5, 0, -8, 9, -2, -11, -3, -9,
+ 9, 2, 2, 4, -5, 7, 11, -16, 0, -6, 7, 6, 25, 5, 6, -4,
+ 3, 4, 3, 2, -8, -3, 5, -1, -11, -4, -9, -3, -15, 10, -12, -5,
+ 11, -4, -7, 6, -29, -5, 6, 11, 3, 9, -18, 13, -14, 19, -1, -2,
+ 4, 5, 12, 1, 5, -8, 3, 1, 20, -6, 2, 3, -16, 10, -10, -18,
+ -11, -7, -7, 9, -4, -8, 9, -15, 13, -13, -3, -7, 3, 8, 11, -6,
+ -16, 1, -8, 20, 4, 15, -5, -3, 11, -5, 6, 0, -5, 10, 13, 0,
+ -6, -11, 0, 11, -11, 10, -7, -8, 1, 16, -9, 2, -22, -9, 0, 4,
+ 5, -12, -22, 2, -8, -8, 14, -16, 0, 13, 0, 9, -7, 2, -1, 7,
+ 8, -3, -3, 2, 15, 5, 10, -7, 12, -4, 22, -4, -3, -12, -2, -15,
+ 8, -2, -22, 7, -10, 5, 12, -20, -9, -11, -2, -12, 2, -9, 5, -3,
+ 11, 7, -9, 4, -4, 24, -7, 21, -15, -3, 2, 14, -1, 5, 18, -12,
+ 13, 3, 5, -10, -11, 0, -8, -2, -4, 2, -15, 9, -10, -16, -9, -7,
+ 0, -1, 3, -8, -10, 5, -8, 4, -3, 8, -2, 20, 1, 6, -4, -9,
+ 4, 14, 7, -1, 3, -5, 18, -7, 20, -6, -10, 8, 1, -2, 3, -4,
+ -5, -3, -6, 0, -16, -7, 12, 0, -17, 4, -31, -7, 1, 1, -4, 8,
+ -11, 6, -1, 11, -5, -7, -4, 2, 4, 15, -3, 21, -5, 20, 3, -12,
+ 21, -1, 10, 5, 6, -20, -1, -18, 2, 3, -4, -5, -1, 6, -2, -11,
+ -17, -15, -13, 0, 6, -18, 7, -18, 7, -7, 6, 7, -10, 18, 16, 2,
+ -1, 3, -11, 6, 14, 1, 15, -2, 29, -8, 17, -14, 2, -19, 12, 8,
+ -6, -1, -23, 6, -11, 7, -19, -18, 0, 1, -8, -8, -4, -20, 8, -8,
+ 4, 10, -12, 13, 0, 18, -10, -3, -4, 6, 4, 17, 7, -2, 18, -9,
+ 14, -10, -4, -11, 4, 3, 23, -17, -6, -2, -7, -7, 9, -10, 1, 2,
+ -4, -14, -7, -6, -8, -4, 7, 2, -3, 3, 0, 13, -10, -4, -9, -6,
+ 18, 11, -4, 16, -8, -4, 1, -1, 7, 3, 3, 3, 10, -15, -2, -9,
+ 9, 0, 2, 2, -9, 12, -7, 0, -23, -7, -19, 2, -1, 0, 4, -15,
+ 7, 3, -3, 0, 9, -12, 19, 4, 8, -13, -6, 5, -1, 14, 10, 9,
+ 13, -3, 16, -18, 13, -18, 7, -10, 13, -6, -11, -3, 7, -23, -6, -11,
+ -21, 9, -1, 4, -3, -16, 0, -12, 7, 14, -5, 15, 0, 6, -5, -3,
+ -9, 9, 4, 10, 4, -2, -7, 10, -1, 10, -6, -14, 15, -4, 13, -4,
+ -4, -14, 5, -2, 4, -9, 3, -14, 2, 3, -10, -1, -9, 0, 3, -6,
+ 12, -16, 0, 4, 10, -25, 6, -5, 2, 8, 3, -2, -4, 15, 4, 7,
+ 2, -1, -6, 10, 11, 2, -2, -14, 6, -3, 0, -3, -9, -10, 1, -1,
+ -15, 9, -29, 9, -10, 7, -3, -3, -10, -2, 14, 4, -6, 0, 1, 12,
+ 4, 18, -15, 19, 1, 15, 1, 1, 3, -10, 8, -1, 7, -30, 8, -19,
+ -2, -5, -9, -10, 0, -1, 6, -4, -12, 1, -18, 10, -1, -12, 2, 7,
+ 12, 11, 0, -4, -1, 6, 10, 17, -8, 1, -12, 5, -2, 1, -7, -1,
+ 4, 3, -3, -1, -18, 8, -9, 0, -2, 8, -12, 12, 7, -5, -2, -16,
+ -7, 9, -5, 11, -9, -4, 3, 1, -9, -1, -2, -6, 7, 12, 0, -8,
+ 9, -10, 3, 0, 2, -3, 11, 14, 4, 3, -12, 3, -3, 2, 12, -4,
+ -2, -2, 9, -21, -5, -28, -6, -10, 6, 7, -6, -3, -24, 7, -11, 10,
+ 0, 8, 13, 10, 6, -7, -2, -5, 7, -1, 9, 18, -2, 12, -4, 7,
+ -26, 13, -6, 19, 6, 6, -5, -16, -6, -8, -18, -2, 1, -11, 3, 4,
+ -16, -8, -10, -3, 2, -3, 5, 5, 0, 11, 0, -14, 0, 1, 14, 11,
+ 13, 0, -2, 5, -1, -4, -2, -4, 5, 21, 3, 14, -5, -22, 5, -11,
+ -3, -6, -3, -11, 0, -5, -13, -10, -18, 3, 9, -10, 2, 3, -11, 11,
+ -11, 5, -19, 23, -1, 20, 18, 4, -3, -6, 9, 4, -3, 8, 4, 6,
+ 2, 5, -14, -6, -3, 2, -6, -4, -3, -11, 0, -5, 0, -21, -2, -10,
+ 11, 5, -4, -5, -5, -8, 10, -10, 4, -1, 6, 12, 9, 2, 8, -20,
+ 8, -2, 11, -11, 1, -4, 5, 6, -6, 6, -14, 14, 4, -2, 12, -3,
+ -10, 8, -5, -15, -9, -1, 5, 8, -3, 0, -23, -9, -11, 4, -12, 3,
+ -4, 4, 1, 15, -12, 3, 13, 2, 5, 8, -8, 7, 11, -3, 17, -11,
+ 5, 3, 19, 13, 3, -11, -11, -2, -9, -7, -4, -24, -1, -17, -3, -17,
+ 0, -15, 2, -1, -5, -4, 3, 2, 2, 11, -4, 3, -6, 11, 8, 3,
+ 6, 3, 7, 7, 6, -6, 2, 0, 14, 14, 3, 8, -6, 4, -3, 6,
+ -13, -2, -9, -4, 5, -13, -5, -21, -1, -6, -1, -5, -14, 8, -7, 5,
+ -7, -17, -11, 7, 3, 20, 7, 1, -3, 4, 5, 14, -3, 5, 3, 10,
+ 8, 6, -6, -2, 6, 3, 7, -6, -3, -3, -6, -1, -27, -11, -17, 0,
+ 11, 7, 1, -7, -9, -13, 5, -11, 0, -10, 15, 2, 5, -2, -5, 1,
+ 6, 6, -6, -5, 6, 2, 5, 3, 10, -16, 11, 8, 18, 3, 13, -11,
+ 7, 5, -7, -6, -20, 15, -1, 10, -1, -13, -17, -11, -3, -13, -4, -14,
+ -3, -2, -6, 6, -28, 9, -8, 10, 0, 12, -2, 10, 9, 1, 3, -6,
+ 5, 17, 24, 18, 3, 4, -9, -4, 2, -8, -4, -2, -11, 1, -8, -12,
+ -9, -10, 5, 0, -7, -9, 7, -18, 6, -10, -12, -1, -1, 13, 1, 18,
+ 2, -3, 4, 3, 3, -3, 3, 10, 9, 7, 5, -8, -7, 0, 3, -7,
+ 7, -2, -2, 5, -10, 2, -5, -3, -1, 4, 1, -2, -10, 4, -9, -5,
+ -12, -18, 3, 6, -3, 3, -15, -1, -13, 6, -2, 8, 0, 8, 16, -2,
+ 17, -4, 8, 3, 23, -1, 11, -8, 10, -4, -5, -3, -13, -2, -1, -2,
+ 2, -9, -13, -13, -2, -11, -2, -20, -5, 0, 3, 2, -1, -10, 1, 8,
+ 3, 9, 6, 4, -3, 13, 3, 4, 11, 2, 11, 8, -2, -1, -2, -2,
+ -2, -1, -21, -1, -14, 8, 6, -8, -10, 2, -16, 4, -3, -1, -10, 7,
+ -1, 4, -4, -12, 3, -2, 13, 2, -3, -9, -2, 6, -7, 8, -8, -5,
+ 12, 7, 8, -3, 6, -1, 16, 0, 7, -8, 3, -7, -1, 0, -6, -4,
+ -8, 6, -1, 4, -19, 2, -3, -8, -3, -12, 4, -6, 2, -7, 1, -13,
+ 2, 9, -1, 17, -19, 3, -3, 23, 9, 6, 3, 6, 6, -5, 11, -11,
+ 1, 0, -5, 6, -6, -4, -5, -7, 3, -4, -14, -9, -7, -1, 5, -11,
+ 4, -19, 14, -4, 3, 4, 2, 0, 9, -2, -3, 2, -2, 10, 15, -3,
+ 14, -6, -4, 6, 1, -8, 11, -9, 4, 3, -9, 2, 2, -2, 2, -2,
+ -9, -2, -2, 1, -6, -6, -22, -16, -10, 12, 0, 5, -8, -2, -4, -2,
+ 5, -1, 7, 7, 9, 1, 7, 6, -1, 10, 11, 5, -3, 8, 1, -1,
+ 8, -15, -6, -10, 12, 0, 2, -5, -9, -12, -7, -4, -14, -4, 0, -1,
+ 5, -7, -8, -12, 0, 2, 16, -3, 11, -4, 16, 11, 2, -3, 2, 8,
+ -1, 7, -13, 4, -3, -1, 3, -10, -2, -11, 3, 2, 3, -7, -10, -5,
+ -10, 12, -8, 5, -7, 15, 1, -10, 7, -16, 1, 3, 4, -5, 7, -7,
+ 4, -2, -1, -8, 0, -2, 17, 10, -2, 6, -5, 3, 10, -7, 2, -3,
+ 4, 5, 5, -3, -8, -8, -1, 1, 7, -5, -11, -2, -10, -4, -15, -7,
+ -10, -2, 2, -4, -10, -8, 0, 2, 6, 3, 2, 3, 10, 14, 8, 7,
+ 3, 5, -5, 20, -6, -1, -2, 0, 1, -2, -2, -8, 3, -3, 10, -14,
+ 3, -3, -2, 0, -5, 0, -15, 4, -2, 0, 4, -7, 3, -8, 7, -14,
+ -2, -6, 4, 2, 3, -10, -2, 5, -3, 12, -2, -5, -9, 1, 4, 1,
+ 11, -12, 15, 5, 20, 10, -5, 1, 5, 3, -13, 6, -16, 5, 1, -5,
+ -8, -3, -14, -6, -2, -5, -8, -17, -9, 3, -6, -2, -3, -3, 1, 14,
+ 2, 4, 5, 3, 8, 7, 12, 0, 11, 4, 16, 2, -3, -9, -1, 1,
+ -1, -3, -6, -14, 4, -6, 2, -14, -9, -11, -1, 0, 0, -5, -6, -10,
+ 5, -5, 2, -3, 2, 2, 17, -2, -1, -3, 3, 11, 1, 10, 2, 7,
+ 6, 5, -5, -3, -3, -2, 7, 2, 1, -18, -5, -2, -3, -5, 0, -2,
+ 0, 8, -9, -10, -15, -7, -2, -1, 6, -8, 16, -10, 13, -4, 2, -4,
+ 4, 7, 9, 6, -5, -2, 8, -1, 11, -6, -1, 5, 8, 0, 9, -20,
+ 0, -9, 4, -3, 1, -4, -11, 2, -6, 0, -12, 0, 1, 5, -2, 1,
+ -7, -4, 3, -1, -10, 3, -3, 7, 4, 8, -9, -6, -10, 0, 0, 2,
+ -4, 6, 9, 10, 2, 0, -1, 2, 14, 3, 7, -7, 2, -2, -2, -6,
+ -9, 2, -3, 6, -3, -7, -9, -10, -2, 2, -1, -11, 2, 1, 7, -4,
+ -7, -19, 3, -1, 6, 6, 6, 6, 0, 6, 7, 3, -1, 3, 8, 3,
+ 4, -10, -5, -7, 5, -4, -14, 2, -8, 5, -2, 2, -16, -4, -11, 2,
+ 4, -1, 2, -1, 0, 5, 4, -12, 3, 9, 7, 13, -3, -7, 2, 6,
+ -1, 7, -1, -1, 5, -5, 7, -11, -9, -13, 2, 5, 2, -2, -7, 5,
+ 4, -4, -2, -15, -4, 3, 0, 0, -5, 2, -7, -1, 9, -2, -1, 5,
+ 1, 1, -4, -5, -4, 6, 8, 7, -5, 4, -7, 4, 0, 1, -6, -5,
+ -2, 5, -1, 0, 1, 1, 3, 9, -4, -2, -4, -9, -1, 4, -17, 1,
+ -13, 11, -1, 6, -9, -1, 5, 1, 8, -3, 4, -5, 1, 7, -5, 1,
+ -3, 5, 3, 4, -7, -11, -7, 1, 5, -13, 11, -11, 1, 3, 6, -9,
+ 6, -5, -7, 4, -13, 5, -7, 10, 5, 6, -15, -1, 6, 4, 18, -7,
+ -7, -3, -4, 2, -5, 3, -4, 9, -4, 3, 3, -3, -10, 0, -1, 2,
+ 5, -3, 7, 3, 2, -6, -11, -2, -1, 4, -5, 4, -5, 0, -5, 5,
+ -5, -4, 2, 4, 2, 5, -8, -13, -3, 0, -1, -2, 4, 6, 9, 1,
+ 3, -7, -1, 1, 12, 1, 1, -1, -5, -1, 2, -8, -9, -7, -2, 3,
+ 10, -6, -7, -12, -7, -4, -5, 6, 0, 10, 5, 7, -4, -2, -8, 10,
+ 5, 9, 4, -1, -1, -1, -1, -1, -2, -3, 3, 9, -2, 9, -14, -13,
+ -8, -10, 1, 1, 3, 3, 1, -3, -12, -5, -7, 1, 6, 6, -2, -7,
+ -3, -3, 2, 2, 4, -9, 14, 8, 11, -3, 5, -11, 1, -1, 5, 3,
+ 8, 2, 8, -2, -6, -13, -10, 0, 4, 3, 4, -3, -9, 1, -5, -5,
+ -6, 1, -2, 2, -10, -6, -15, 1, -5, 4, -1, 2, 2, 4, 10, 4,
+ 2, -13, 0, 4, 8, 17, 2, 5, 4, 2, -6, 5, -5, 0, 8, -2,
+ -1, -5, -4, -5, -1, -5, -4, -5, 0, 0, 1, -9, -15, -3, -12, 1,
+ -1, -7, 10, 2, 5, -1, 2, -6, 2, 2, 10, 10, -1, 2, -2, 4,
+ 5, 0, -6, 12, 5, 3, -1, -8, -8, -4, -4, 3, -11, 0, -1, -1,
+ 0, -2, -14, -6, -9, 2, 1, 7, -4, 3, -1, 0, -3, 1, 2, 7,
+ 5, 4, 3, -2, -3, 1, 6, -1, 6, -11, 7, 2, -6, 2, -4, 0,
+ 2, 3, -7, -9, 3, 0, 4, -6, 0, -21, 0, -5, -1, 0, -1, 1,
+ -6, -1, -1, 0, -7, 5, 7, -2, 8, -4, -1, 3, 9, -6, 10, -6,
+ 7, 9, 10, 9, -6, 5, -14, 6, -5, 1, 2, -3, 0, -9, -10, -14,
+ -2, -3, 6, -8, -15, 3, -9, 0, -3, 0, -6, -1, 3, 9, 10, 3,
+ 3, -10, 6, 1, 3, -1, 9, 12, 4, 4, -9, -7, -5, 8, 6, 1,
+ 1, -4, -5, -5, -1, -11, -3, -4, 1, -1, 1, -10, -7, -2, -3, -4,
+ -3, -6, 11, 5, 3, 2, -8, -5, -2, 3, 9, 13, 5, 4, 4, 0,
+ -5, -1, -5, 9, 2, 3, -9, -4, 3, -6, 2, 1, -9, 5, -2, 3,
+ -2, -9, -8, -15, -5, -3, 3, -13, 11, 6, -3, 1, -6, -6, -1, 6,
+ 4, 6, 7, 1, 5, 0, 8, -6, 7, 2, 6, 2, -5, 0, -3, -1,
+ 3, -7, -1, -3, 5, 7, 6, -18, -10, -11, -7, -3, 10, -4, 3, -4,
+ -8, -5, -12, -3, -4, 12, 10, 2, -4, 6, 3, 1, 2, 0, -3, 3,
+ 7, 7, -5, 2, -4, 1, 3, 11, 2, 3, 4, -2, -7, -5, -17, -11,
+ 4, -3, 5, -7, -7, -6, -1, -8, -5, -5, 1, 7, 1, 2, -1, -9,
+ 7, 1, 7, 3, 3, 6, 9, 6, 1, -6, -4, 2, 5, 7, 4, -2,
+ 1, 3, -11, -1, -16, -2, -6, 1, 3, -8, -15, -11, 4, -1, 9, -2,
+ -5, 0, 6, 0, -7, 0, -8, 4, 2, 6, 2, 0, 2, 6, 2, -2,
+ 4, -2, 4, 14, 2, 2, -6, -6, -3, 4, -4, -1, -4, 1, -3, -6,
+ -1, -13, -1, -2, 7, -8, -7, -10, 0, 4, 3, -8, -3, 1, 4, 6,
+ 4, 6, -3, 5, 3, 4, 0, 6, 1, 4, 7, -3, -10, 8, -1, 9,
+ -1, 1, -11, -7, -3, -3, -6, -8, -9, -6, 1, -3, -6, -6, -5, 0,
+ 0, 2, -3, 0, 6, 4, 3, 2, 7, 4, 11, 14, 5, -1, -5, 1,
+ -2, 7, 3, 0, 1, 2, -5, -7, -10, -12, -10, -5, -5, -6, -6, -9,
+ 1, -8, -2, -1, -9, 1, 8, 2, -5, -2, -5, 0, 5, 6, 6, 7,
+ 8, 10, 2, 0, -3, -1, 2, 13, 3, 0, -6, 0, 1, -3, 0, -12,
+ -2, 4, -4, 4, -8, -11, -1, -2, 1, -1, 2, -12, 3, -6, 1, -12,
+ -7, -7, 3, 0, 9, 0, 1, 6, 1, -1, 2, 1, 2, 8, 9, -3,
+ -1, 0, 7, 3, 8, -1, -4, -1, 1, 3, -9, -1, -17, -3, -2, -4,
+ -4, -3, -4, -6, -11, -15, -2, -5, 6, 10, 1, 3, -1, -3, 13, 7,
+ 1, 6, 4, 4, 9, 5, -3, -5, 9, 3, 5, -3, 1, -3, 3, 0,
+ -7, -5, -7, 0, -5, 0, -1, -15, -11, -4, -5, -10, 2, -7, 5, -4,
+ 1, -9, 2, 1, 8, 7, 10, 2, 2, 0, 4, 3, -2, 0, 4, 2,
+ 6, 8, -2, 4, 4, -2, 5, -3, -6, 3, -3, -5, -9, -8, -11, -5,
+ -1, -1, -5, -7, -5, -8, 0, -3, 5, -7, 11, 1, 0, 2, -3, -1,
+ 3, 9, 6, -3, 8, 1, 11, 2, 8, -3, -3, 6, 2, 1, 2, -7,
+ -3, -2, -4, -8, -3, -3, 5, -10, -10, -4, -12, -2, 3, -5, 3, -6,
+ -8, -2, 5, -3, 0, 1, 4, 8, 4, 5, 0, 4, 8, 1, 7, -3,
+ 0, 3, 4, 4, -5, -2, -7, -3, 0, 5, -5, -9, 3, -2, -1, -2,
+ -5, -1, -4, -3, -11, -4, -5, -6, 0, 5, 0, -5, 5, 3, 8, -1,
+ 3, 3, 2, 5, 7, -4, 3, 1, 3, 10, 2, -7, 1, 0, 6, -4,
+ -3, -5, -7, -2, -4, -3, -6, 0, -10, 4, -6, -4, -7, -2, 1, -4,
+ -1, -3, -1, 2, 6, 2, 4, -2, 2, 4, 2, 5, -3, 4, 2, 1,
+ 0, 8, -3, 2, 5, -5, 3, -5, -2, 5, -5, 3, -1, -4, -3, 4,
+ -10, -5, -7, -4, -4, 0, 0, -7, -1, -1, 2, 1, -2, -12, -4, -1,
+ 0, 4, -5, 2, 0, 3, 12, 11, 3, 11, -1, -3, 6, -6, 1, 1,
+ 7, 6, -7, -1, -7, -4, -4, -7, -8, -1, -6, -6, -2, -3, -5, 0,
+ -4, 8, -7, 1, 4, -3, 6, 1, -7, 3, 5, 6, 5, 13, 2, 2,
+ -4, 4, -3, 1, 4, -4, 2, -3, -10, -10, -7, -2, -2, -2, 0, -6,
+ -2, 1, -3, -4, -2, -5, -2, 7, 1, 6, -5, 6, -1, -1, 2, -3,
+ 4, 11, 2, -1, 2, -7, -5, 8, 0, 3, -3, -5, -1, -2, 3, 1,
+ -4, 4, 7, 0, 2, 3, -3, 0, 1, -5, -15, -5, -3, 1, 3, -3,
+ -11, -4, -7, 1, -2, -1, -1, 0, 1, 1, -5, -1, 3, -2, 7, 1,
+ -4, -1, 0, 4, 5, 3, 3, -1, 8, 11, 1, 4, 1, -5, 7, -6,
+ -4, -2, -4, -2, 3, -8, -3, -13, -6, 3, -3, -7, -4, -7, 3, 3,
+ -3, 2, -1, 1, -4, -2, -2, -5, 1, 11, 9, -2, 6, -3, 7, 7,
+ 1, 1, -7, 2, -3, 1, 4, -4, -4, 5, 1, 0, -3, -6, 2, -3,
+ 0, -8, -12, -6, -2, -3, 6, -1, -9, 0, -1, 1, 3, -2, -1, 0,
+ 1, 6, 0, -3, 5, 1, 6, 1, -1, 4, 1, 7, -3, -1, -1, -4,
+ 4, 14, -1, -1, 2, -4, -1, -6, -8, -8, -3, -2, 2, -9, -5, -7,
+ -12, 5, 0, -3, -4, -3, 5, 4, 3, -2, -6, 4, 7, 3, 5, 7,
+ -3, 8, 0, -5, -1, -1, 11, 10, 3, 4, -8, -3, -3, 1, -3, 0,
+ -4, -3, 1, -7, -8, -16, -7, -6, -2, 3, -7, -2, 1, -4, 0, -5,
+ -5, 1, 5, 10, 5, 0, 3, 0, 1, 13, 0, 5, 9, 6, 8, -1,
+ -4, 0, -3, 6, 4, -4, 0, -3, -15, -2, -12, -15, -3, -6, 2, 1,
+ -3, -4, -9, -9, -3, -3, -2, 3, 4, 9, 0, 2, 1, 2, 14, 5,
+ 3, 8, 2, 7, 4, -4, -4, -1, -9, 9, -5, -1, -7, -10, -2, -7,
+ -4, 0, -5, 2, 5, 1, 0, -5, -5, -1, -1, -3, 4, -8, 5, 3,
+ -4, 4, -5, -3, 9, 4, 8, 0, 0, 2, 0, -2, 0, -2, -7, 12,
+ -1, 5, -4, 2, -3, 0, 2, -2, -4, -2, 2, -5, 3, -7, -9, -4,
+ -3, -2, -6, -6, -2, -6, -1, -7, -8, 1, 3, 6, 10, 4, 5, 0,
+ 5, 8, 1, 3, 8, 5, 11, 12, -7, 4, 0, -3, 2, -1, -8, -7,
+ -4, -2, -6, -9, -6, -13, -4, -1, 0, -9, -5, -3, -4, -2, 3, 1,
+ 1, 9, 4, 2, 6, -1, 3, 6, 2, 0, -3, 3, 2, 6, 3, -1,
+ -4, 4, 1, 2, 2, -5, -8, -1, -3, -1, -9, -4, 1, -5, 5, -7,
+ -4, 0, 3, -10, 3, -3, -5, 1, 5, 4, 1, -5, 1, -5, 4, 1,
+ -6, 0, 5, 8, 8, 1, 6, 0, 3, 4, 2, -3, 1, -3, -3, 3,
+ -10, -6, -8, -2, -1, -3, -6, -6, -5, -6, -6, -5, 5, -3, 5, 6,
+ -2, -1, -1, -4, 6, -2, 6, 6, 2, 12, 8, -2, 3, -6, -2, 5,
+ 4, -3, -2, -5, -4, -7, -6, 1, -5, 2, 2, 0, 1, -7, 0, -4,
+ -2, -1, -2, -5, 7, -5, -2, -3, -2, -3, 4, 4, 9, 0, 1, 1,
+ -5, -3, -4, -4, 4, 3, 6, 1, -2, -2, -7, 4, 1, 1, -3, 3,
+ -1, 2, 0, -7, 0, 0, -1, -3, -2, -1, -5, -2, -3, -8, -5, -5,
+ -1, 5, 5, 2, 2, -3, 4, 3, 4, 6, 3, -1, 10, -4, -3, -2,
+ -3, 0, -4, 0, -2, -2, 0, 2, -5, -2, -5, -9, 8, -2, -1, -1,
+ -3, -3, -2, -6, 2, 1, 2, 9, 0, 1, 4, -5, 2, 4, -6, -1,
+ 2, -1, 6, 3, 0, -5, -3, -1, 0, 3, -3, 0, -6, -2, -3, -4,
+ -2, 0, 3, 2, 2, 0, -10, 1, -6, -5, -1, -2, 5, 3, 6, -2,
+ -6, -1, -3, 2, 4, 1, -1, 0, 1, 1, 3, -1, 5, -1, 7, 6,
+ 1, -2, 0, -6, -2, -2, -8, -2, -2, -3, -5, -5, -8, -3, -1, 5,
+ -3, 1, 2, 1, 2, -3, -2, -3, 2, 6, 2, 6, 0, 0, -2, 9,
+ -1, 3, -2, 3, 0, 0, 0, -6, -6, -1, -5, -7, 1, -3, -6, 2,
+ -2, -1, -5, -2, 1, 4, 2, 2, -3, -1, 6, -2, 2, 4, -3, 2,
+ 2, 2, -3, 1, 0, -4, 2, -1, -2, 3, 1, 1, -1, -5, -8, -2,
+ -5, 0, 1, -6, 3, -4, 2, 3, -6, 3, 0, 2, -2, -1, -4, -2,
+ -4, 4, 0, -3, 0, -6, -3, 10, -3, 3, 0, 4, 7, 3, 0, 5,
+ 1, 5, 1, -3, -2, 0, -6, 3, -1, -7, -5, -7, -1, -2, -2, -2,
+ -3, -2, 2, -2, -1, -3, -3, 2, -2, -6, -3, -3, 4, 3, 2, 0,
+ -1, 5, 5, 8, 2, 2, -2, 4, 0, 5, -5, -3, -1, -3, -3, -6,
+ -4, -2, 3, 0, -2, -2, -5, 5, -1, 3, -1, -1, -3, 0, 0, -5,
+ -4, -3, -2, 5, 0, -4, -4, 1, 2, 6, 0, -3, -1, 2, 3, 7,
+ -3, 0, -4, -2, 4, 3, 0, 1, 3, -3, 1, -7, -4, 0, 1, 1,
+ -4, -4, -4, -9, -1, -2, -3, -2, -3, -3, 4, 3, -1, -4, 2, 4,
+ 4, 3, 2, -1, 0, 9, -1, 4, 2, 7, -1, 6, -2, -2, -5, -1,
+ -9, -2, -2, -6, -1, -1, 1, -8, -6, -5, -1, -1, 1, -4, -5, 3,
+ 1, 5, 3, -3, 0, -2, 7, 0, 1, -2, 3, -1, 5, -1, -5, 7,
+ -1, 3, 2, -5, -6, -2, 4, 2, -1, -3, -1, -1, -1, -1, -2, -4,
+ 1, -5, 3, -1, -3, -5, 2, 6, -6, -1, -5, -4, 4, -1, -1, -2,
+ -1, 2, 0, 3, 1, 4, 2, 7, -1, 2, 0, -2, 1, 4, -5, -3,
+ -7, -2, 0, -1, -1, -3, 0, 0, -2, -6, 2, -4, 2, -4, 1, -7,
+ -2, -1, 5, 3, -2, -7, -4, 1, 6, 4, 5, 1, 4, 0, 5, 1,
+ -1, 2, 0, -3, -3, -5, -6, 3, -1, 5, -1, -2, 1, 1, 4, 2,
+ -6, -3, -4, -3, 2, -2, -8, -3, -6, -4, -2, -11, 0, 0, 1, 6,
+ -3, -2, 1, 2, 10, 8, 4, -2, -1, 2, 2, 1, -2, 3, 1, 5,
+ 3, -1, 0, -4, 4, -7, -2, -7, -8, -4, -3, -2, -7, -7, -3, -1,
+ 5, -2, 0, -7, 2, -1, 3, 1, 4, 6, 5, 8, 3, 2, -1, 3,
+ -3, 0, 0, -5, -1, 1, 1, -5, -3, -2, 6, 4, 5, -4, -8, -4,
+ -3, -2, -5, -4, -4, -4, 2, -3, -2, -4, -4, -4, 6, 1, 0, 1,
+ 3, 3, 5, 2, 1, 0, 6, 2, -1, 1, -3, -3, 2, -1, 0, 1,
+ 3, 1, 4, -4, -5, -10, -8, 1, -6, -3, -4, -6, -3, 0, 2, -3,
+ -1, 2, 0, 8, 1, 4, 4, 3, 6, 3, 1, 3, 5, 1, 2, -4,
+ -7, -3, -3, 3, 0, -7, -5, 0, -3, -1, -2, -4, 0, -5, 1, -6,
+ -1, -5, -3, 1, 4, -1, -3, 3, 3, 5, -1, -2, 2, -1, 2, 1,
+ -1, -5, 5, 1, 2, 2, -4, 0, -1, 3, 0, -2, -1, 2, 1, 5,
+ 4, -3, -5, 0, -2, -2, -6, -3, -3, -4, -1, -5, -4, -1, -2, 0,
+ 2, -2, -6, -3, 1, 1, 1, -1, 3, 4, 7, 2, 3, 4, -1, 7,
+ 2, 3, 1, -1, 1, -2, 0, -4, -5, -6, 0, -2, -7, -2, -5, -5,
+ 1, -4, -5, -5, 3, -1, 1, 2, -2, 0, 1, 4, 1, -4, 2, 2,
+ 0, 9, 2, 0, 4, 3, 1, 2, -4, -2, -4, 3, -4, -2, -6, 0,
+ -1, 5, 2, -4, 0, -4, -4, -1, -5, -4, -7, -3, 1, 0, -2, -1,
+ -5, 1, 0, -1, 0, 2, 4, 0, 3, -2, 1, 2, 6, 0, 1, 5,
+ 0, 3, 3, 2, -5, -2, 1, 5, 2, -2, -5, -9, 0, -6, -1, -6,
+ -7, -5, -4, 0, -2, -5, -3, 2, -2, 3, 2, 0, 9, 2, 0, 4,
+ -3, 4, 5, 8, 6, -2, -4, -1, 0, -2, -2, 1, -5, 2, -5, -1,
+ -4, -3, -4, 0, -2, -7, -3, -1, 0, -1, 0, -6, 3, -2, 5, 2,
+ -1, -2, 1, 0, 1, -1, -3, 2, 3, 1, 2, -4, -3, -1, 5, 5,
+ 3, -4, 0, 1, 2, 5, -5, 1, -5, 2, -2, 2, -4, -3, 0, -4,
+ -3, -9, -7, -4, 2, -2, 1, -6, -3, 0, 1, 5, 1, -5, 0, 0,
+ 2, 1, 2, 0, 6, 4, 6, 3, 2, 3, 1, -2, -2, -9, -4, -1,
+ 4, 0, -1, -5, -8, -5, -4, 0, -4, -1, -3, 0, 0, -4, -3, -1,
+ 1, 2, 0, -2, -3, 1, 3, 2, 3, 3, 0, 8, 2, 7, -1, 3,
+ -2, 4, 0, 0, 1, -4, 5, -1, -3, -3, -6, -4, 2, 1, -5, -4,
+ -7, -4, -4, -7, -2, -10, 1, 0, 1, -3, 4, -2, 5, 2, 1, -3,
+ -1, 2, 8, 4, 5, 0, 1, 4, 5, 2, 2, -2, 1, -4, 0, -3,
+ -3, -1, 0, 2, -4, -4, -5, -1, -7, 0, -4, -5, -1, -3, 2, -2,
+ 0, 3, 0, 2, 0, 1, -2, 2, 4, -1, 0, -3, -1, 1, 3, 2,
+ -3, 2, 0, 2, 2, -1, 2, -2, -3, 0, 0, -2, 2, -2, 4, -3,
+ -6, -7, -6, 2, -1, -4, -1, -7, -1, -3, 3, -1, 0, -2, 2, 2,
+ -3, 3, -4, 5, 7, 6, 3, 1, -1, 6, 2, 1, 0, -1, -1, 1,
+ -3, 1, -3, -5, -5, -3, -8, -3, -11, -1, -1, 0, -8, -2, -5, 3,
+ 4, 0, 1, -2, 2, 0, 6, 4, 1, 4, 1, 5, 0, 0, 1, 2,
+ 5, 0, 1, -10, 0, -5, 2, 0, -6, -6, -2, -2, 2, -3, 0, -4,
+ 2, -4, 1, -3, -4, 1, -2, 2, 1, -2, 0, 3, 2, -3, -1, -5,
+ -3, 4, 2, 3, -1, 4, 1, 5, -1, 2, -3, 2, -3, 0, -3, -2,
+ 1, 1, 5, 1, -2, -5, 1, -1, -4, -3, -7, 0, -5, -4, -4, 0,
+ -4, 4, 0, -1, 1, -8, 1, 0, 9, 1, 2, -2, 5, 5, 1, 6,
+ -1, 6, 3, 1, 1, -2, -2, -4, -3, -2, -3, -7, -4, -4, -1, -3,
+ -8, -1, -8, 4, -5, 0, -3, 1, 0, 4, -1, 0, 1, 3, 3, 4,
+ -4, 6, -2, 2, 5, 4, -3, 4, -3, 5, 0, -4, 0, 0, -1, 0,
+ -4, -4, 3, -1, -2, -4, -8, -9, -5, -4, 4, -4, 1, -4, 1, 1,
+ -1, -1, -1, 3, 2, 3, 0, 1, 2, 1, 5, 3, 1, 0, 5, 3,
+ 3, 0, -5, -4, -2, 5, 0, -2, -5, -2, -6, -2, -5, -8, -2, 1,
+ -1, -3, -7, -8, -6, 0, 4, 7, -2, 7, -1, 7, 3, 2, -5, 0,
+ 2, 0, 1, -3, 2, 2, 3, 3, -3, 0, -2, 3, -1, -1, -4, -6,
+ -2, -3, 4, -4, 0, -4, 6, -2, -6, -2, -7, 1, 2, -1, -3, -2,
+ -2, 3, -1, 0, -3, -1, 4, 7, 4, 0, 2, -1, 0, 6, -2, 1,
+ 1, 5, 4, 1, -3, -3, -2, 2, 2, 1, -6, -6, -3, -4, -2, -6,
+ -5, -4, -5, -2, -8, -8, -3, 0, 4, 0, 1, -1, 2, 5, 4, 2,
+ 2, 3, 3, 4, 10, 0, 2, 0, 3, 1, 1, 0, -3, 1, -3, 1,
+ -7, 0, 1, -2, 1, -6, -4, -10, -1, -4, -2, -2, -3, 2, -4, 1,
+ -5, -4, -4, 2, 1, 1, -4, -1, 3, 1, 6, 2, -2, -2, 3, 3,
+ 2, 7, -5, 5, 0, 8, 1, -1, 2, 3, -1, -6, 0, -10, 3, -1,
+ -1, -5, -6, -8, -2, 0, -3, -5, -8, -4, 2, -3, -1, -2, 0, -1,
+ 7, -1, 3, 2, 4, 7, 3, 4, -1, 5, 1, 9, 1, -2, -1, -1,
+ 1, -3, -2, -6, -7, 1, -3, -1, -9, -4, -6, 0, 2, -3, -2, -4,
+ -3, 0, -4, -1, -4, 0, 1, 6, -1, 1, -1, 3, 5, -1, 3, 4,
+ 5, 7, 4, -2, 0, -2, 0, 3, 1, -1, -8, -2, -1, -2, -5, -1,
+ -2, -2, 2, -5, -7, -9, -2, -3, -2, 1, -5, 4, -4, 5, -1, -1,
+ -3, 2, 3, 7, 3, -1, 3, 4, -1, 5, -4, 0, 4, 4, 3, 4,
+ -9, 1, -5, 2, -2, -2, -3, -7, -1, -2, -2, -5, -3, -1, 1, -2,
+ -1, -4, -4, 1, -1, -7, 0, -1, 2, 5, 4, -4, -5, -4, 0, 2,
+ 1, -1, 3, 5, 4, 0, 0, -1, 3, 8, 3, 3, -4, 0, 1, 0,
+ -2, -6, -2, -4, 3, -2, -3, -5, -6, -3, -1, -1, -7, 0, 0, 3,
+ -5, -4, -11, 0, 0, 3, 3, 1, 1, 1, 4, 6, 1, 1, 2, 9,
+ 3, 3, -4, -4, -3, 2, -1, -6, 1, -5, 2, 0, -1, -8, -5, -6,
+ 1, 0, -2, -1, -2, -1, 2, 0, -9, 0, 5, 4, 7, -3, -3, 3,
+ 4, 2, 4, 0, -1, 3, 1, 5, -5, -6, -7, 0, 3, 0, -2, -4,
+ 3, 3, -3, -4, -7, -2, 4, 1, -1, -4, -1, -6, -2, 3, -2, -3,
+ 1, 4, 1, -1, -4, -3, 3, 4, 5, -2, 2, -3, 4, 0, 3, -3,
+ -3, 0, 3, 1, -2, -1, -3, 2, 4, -2, -2, -3, -1, -1, 3, -11,
+ -2, -8, 5, -1, 3, -5, -2, 2, -1, 3, -3, 0, -1, -1, 5, -2,
+ 0, -2, 3, 2, 3, -2, -6, -3, 2, 4, -6, 5, -6, 1, 2, 3,
+ -6, 2, -3, -4, 3, -9, 2, -6, 3, 4, 2, -9, -1, 1, 2, 8,
+ -3, -4, -1, -2, 2, -2, 2, -3, 3, -1, 1, 2, -1, -6, 1, 2,
+ 2, 1, -2, 2, 3, 1, -3, -6, -3, 0, 1, -3, 0, -3, -1, -4,
+ 2, -4, -3, -1, 4, 0, 5, -6, -7, -1, 0, 0, -3, -1, 2, 4,
+ 0, 3, -4, -1, 1, 7, 4, 2, -1, -4, 0, 2, -4, -5, -5, -1,
+ 1, 4, -5, -4, -6, -3, -2, -3, 2, -2, 5, 2, 3, -4, -2, -5,
+ 6, 3, 4, 2, -3, 1, 0, 0, 1, -3, -1, 1, 7, 0, 6, -6,
+ -7, -2, -7, 0, -1, 0, 2, 1, -2, -7, -2, -5, 0, 2, 0, -3,
+ -5, -1, -3, 0, -1, 0, -6, 8, 4, 5, -1, 1, -4, 1, 1, 4,
+ 2, 5, 3, 6, 0, -2, -9, -4, -1, 0, 0, 1, -1, -4, -1, -5,
+ -5, -5, 0, 0, 1, -6, -5, -9, 0, -3, 0, -2, 0, 0, 3, 4,
+ 2, 1, -7, 1, 3, 4, 9, 1, 4, 4, 2, -4, 2, -2, 1, 5,
+ -2, 0, -3, -4, -3, -2, -4, -4, -4, 1, -1, 2, -6, -8, -3, -8,
+ -1, -2, -4, 5, 2, 3, -1, 0, -4, 2, -1, 5, 5, -1, 3, 0,
+ 3, 3, 0, -4, 9, 4, 2, -1, -6, -4, -2, -2, 2, -7, 0, 0,
+ -2, -2, -2, -10, -4, -7, 0, -2, 2, -2, 2, 1, 0, -3, 0, 1,
+ 6, 3, 2, 0, 0, -1, 2, 3, -1, 4, -5, 6, 2, -3, 0, -3,
+ 0, 1, 0, -5, -6, 1, 0, 1, -5, -2, -14, 0, -4, -1, -1, -1,
+ 1, -3, 0, -2, -1, -4, 4, 5, -1, 5, -1, 3, 3, 5, -3, 5,
+ -3, 5, 5, 6, 4, -6, 2, -9, 4, -4, 0, 1, -2, -1, -8, -6,
+ -11, -2, -3, 3, -6, -8, 3, -5, 1, -3, 1, -3, 1, 3, 5, 6,
+ 2, 1, -6, 4, -1, 1, 0, 7, 7, 2, 3, -6, -4, -4, 3, 3,
+ 0, 1, -1, -2, -4, 0, -8, -2, -3, 1, -2, 1, -5, -2, -1, -3,
+ -3, -4, -3, 7, 4, 1, -1, -6, -5, -3, 2, 5, 8, 3, 3, 2,
+ 1, -4, -1, -2, 6, 3, 2, -4, -1, 1, -5, -1, -1, -5, 2, -2,
+ 1, -2, -7, -5, -11, -4, -3, 3, -8, 8, 4, -2, -2, -4, -4, -1,
+ 4, 3, 5, 5, 2, 4, -1, 6, -3, 6, 2, 3, 0, -4, 0, -2,
+ -2, 0, -5, -2, -1, 4, 3, 1, -13, -8, -8, -5, -3, 7, -2, 3,
+ -2, -5, -3, -8, -2, -3, 8, 6, 1, -2, 5, 3, 1, 2, 0, -1,
+ 2, 4, 3, -5, 1, -3, 0, 1, 7, 1, 2, 3, -1, -4, -4, -10,
+ -7, 3, 0, 2, -5, -5, -4, -1, -7, -3, -3, 1, 3, 0, 0, -1,
+ -6, 6, 1, 4, 1, 2, 5, 6, 4, -1, -4, -3, 1, 2, 5, 2,
+ -1, 1, 3, -8, -1, -10, -2, -5, 0, -1, -6, -10, -7, 2, -2, 6,
+ -1, -2, 1, 4, -1, -5, -1, -5, 4, 1, 4, 2, 1, 3, 4, 0,
+ -2, 1, -1, 3, 8, 2, 1, -4, -3, -3, 3, -3, -1, -4, 0, -4,
+ -6, -2, -8, 1, -2, 5, -6, -5, -6, 0, 3, 1, -6, -3, 1, 2,
+ 4, 2, 4, -2, 3, 3, 3, 1, 5, 1, 2, 3, -2, -6, 6, -1,
+ 6, -2, 1, -7, -5, -2, -3, -6, -6, -6, -4, 0, -2, -4, -4, -3,
+ 0, -1, 1, -3, -1, 3, 1, 1, 0, 6, 4, 8, 10, 5, 0, -3,
+ 1, -2, 5, 2, 1, 1, 1, -4, -6, -8, -8, -8, -5, -4, -5, -4,
+ -5, 0, -5, -3, 0, -7, 0, 4, 1, -4, -1, -4, -2, 4, 4, 5,
+ 6, 6, 7, 0, 0, -1, 0, 2, 9, 2, 1, -3, 0, 1, -3, 1,
+ -9, -1, 3, -4, 3, -6, -7, -2, -1, -1, -1, 1, -9, 2, -5, 1,
+ -8, -6, -6, 1, -1, 6, 0, 2, 5, 2, 0, 2, 1, 2, 6, 5,
+ -2, -1, 0, 4, 1, 6, 0, -2, 1, 0, 3, -7, -1, -13, -4, -3,
+ -3, -3, -2, -3, -5, -9, -11, -2, -3, 4, 7, -1, 2, 0, -2, 8,
+ 5, 1, 4, 3, 2, 7, 3, -2, -4, 7, 2, 3, -2, 1, -1, 2,
+ 0, -5, -4, -4, 0, -4, 0, -1, -10, -9, -3, -5, -8, 1, -5, 3,
+ -3, 0, -7, 1, 0, 5, 4, 7, 1, 1, 0, 2, 2, -2, -1, 2,
+ 1, 4, 6, -1, 4, 3, -1, 4, -2, -3, 3, -1, -2, -6, -6, -7,
+ -3, -1, 0, -4, -6, -5, -6, 0, -3, 3, -5, 7, 0, -1, 1, -3,
+ -1, 1, 6, 3, -3, 7, 1, 10, 1, 6, -1, -2, 5, 2, 1, 1,
+ -4, -2, 0, -3, -7, -2, -4, 4, -8, -8, -4, -10, -2, 2, -4, 1,
+ -5, -7, -1, 3, -1, 1, 1, 4, 6, 2, 2, 0, 4, 7, 0, 5,
+ -2, 0, 3, 3, 3, -3, -1, -5, -2, 0, 3, -4, -6, 2, -1, 0,
+ -2, -4, 0, -4, -3, -9, -3, -4, -4, 0, 3, -1, -4, 3, 1, 5,
+ -2, 1, 2, 2, 4, 5, -3, 2, 1, 3, 7, 1, -5, 1, 0, 5,
+ -3, -2, -3, -4, 0, -3, -2, -5, 0, -8, 3, -6, -4, -6, -2, 2,
+ -4, -2, -3, -2, 1, 4, 2, 3, -2, 2, 4, 1, 4, -2, 3, 2,
+ 1, 1, 7, -1, 2, 4, -4, 2, -4, -2, 5, -4, 3, -1, -3, -2,
+ 3, -8, -4, -6, -3, -3, -1, 0, -6, -1, 0, 1, 1, -2, -10, -3,
+ -1, 0, 2, -5, 1, 1, 2, 10, 8, 2, 8, -1, -2, 4, -5, 2,
+ 2, 7, 6, -6, -1, -5, -4, -3, -6, -7, 0, -5, -5, -1, -2, -5,
+ 0, -4, 6, -6, 0, 3, -3, 4, 0, -6, 2, 5, 5, 4, 10, 0,
+ 2, -3, 3, -2, 0, 3, -3, 2, -3, -8, -8, -5, -1, -1, -1, 0,
+ -5, -2, 0, -3, -4, -1, -5, -2, 5, 0, 5, -4, 4, -1, -1, 1,
+ -3, 3, 9, 2, -1, 1, -6, -3, 7, 1, 3, -2, -4, 0, -1, 3,
+ 1, -3, 4, 6, 0, 1, 2, -3, 0, 0, -5, -13, -4, -2, 1, 2,
+ -3, -10, -4, -7, 1, -2, -2, -1, 0, 1, 1, -4, -1, 2, -2, 7,
+ 1, -3, 0, 0, 4, 5, 2, 2, -1, 6, 9, 1, 3, 1, -5, 5,
+ -6, -5, -2, -4, -2, 2, -7, -4, -11, -5, 3, -3, -6, -4, -6, 3,
+ 3, -3, 2, 0, 1, -3, -1, -2, -4, 1, 10, 8, -2, 4, -3, 6,
+ 6, 1, 0, -7, 2, -2, 1, 3, -4, -4, 4, 1, 0, -2, -5, 2,
+ -2, 0, -7, -11, -5, -2, -2, 5, -1, -8, -1, -1, 1, 2, -2, -1,
+ 1, 1, 5, 0, -3, 5, 1, 6, 1, -1, 3, 1, 6, -3, -1, -1,
+ -3, 4, 12, -1, -1, 2, -4, -1, -6, -8, -7, -3, -2, 1, -9, -5,
+ -6, -10, 5, 1, -2, -3, -2, 5, 4, 3, -1, -5, 4, 6, 3, 4,
+ 6, -2, 7, 0, -4, -1, -1, 9, 8, 2, 2, -8, -3, -3, 0, -2,
+ 0, -4, -2, 0, -6, -7, -14, -6, -5, -1, 3, -6, -2, 1, -3, 0,
+ -4, -5, 1, 5, 9, 4, 0, 3, 0, 1, 12, 0, 4, 8, 5, 7,
+ -1, -4, 0, -3, 5, 4, -4, 0, -3, -13, -2, -10, -14, -3, -5, 2,
+ 1, -3, -4, -8, -8, -3, -2, -2, 3, 4, 8, 0, 2, 1, 2, 12,
+ 5, 3, 8, 2, 6, 3, -4, -4, -2, -8, 8, -5, -2, -6, -10, -2,
+ -6, -4, 0, -4, 2, 5, 1, 0, -4, -4, -1, -1, -3, 4, -7, 4,
+ 3, -3, 4, -4, -3, 8, 4, 7, 0, 0, 2, -1, -2, -1, -2, -7,
+ 11, -1, 5, -4, 2, -2, 0, 2, -2, -4, -2, 1, -5, 3, -6, -9,
+ -3, -3, -2, -5, -5, -2, -6, -2, -7, -8, 1, 3, 5, 9, 4, 4,
+ 0, 5, 8, 1, 3, 7, 5, 10, 11, -7, 3, 0, -3, 1, -1, -7,
+ -7, -3, -2, -6, -9, -6, -12, -4, -1, 0, -8, -5, -3, -3, -2, 3,
+ 1, 1, 9, 4, 2, 5, -1, 2, 6, 2, 0, -3, 2, 2, 5, 2,
+ -1, -4, 4, 1, 1, 2, -5, -8, -1, -3, -1, -9, -4, 1, -4, 5,
+ -6, -4, 0, 3, -9, 3, -3, -5, 1, 4, 4, 1, -4, 1, -4, 4,
+ 1, -6, 0, 5, 7, 8, 1, 6, 0, 3, 4, 2, -3, 1, -3, -3,
+ 3, -9, -6, -7, -2, -1, -3, -5, -6, -5, -5, -6, -5, 4, -3, 5,
+ 5, -2, -1, -1, -3, 6, -2, 5, 6, 2, 11, 8, -1, 3, -6, -2,
+ 5, 4, -3, -3, -5, -3, -7, -5, 0, -5, 2, 1, 0, 1, -7, 0,
+ -3, -2, -1, -2, -5, 7, -4, -2, -3, -2, -3, 4, 4, 9, 0, 1,
+ 1, -5, -3, -4, -4, 4, 3, 6, 0, -2, -2, -6, 4, 1, 1, -3,
+ 3, -1, 2, 0, -7, 0, 0, -1, -3, -2, -1, -5, -2, -3, -8, -5,
+ -5, -1, 5, 5, 2, 2, -3, 4, 3, 3, 6, 3, -1, 10, -4, -3,
+ -2, -3, 0, -4, 0, -2, -2, 0, 1, -4, -2, -5, -9, 8, -2, -1,
+ -1, -3, -3, -2, -6, 2, 1, 2, 9, 0, 1, 3, -4, 2, 4, -6,
+ -1, 2, -1, 6, 3, 0, -5, -3, -1, 0, 3, -3, 0, -6, -2, -3,
+ -4, -2, 0, 3, 2, 2, 0, -10, 1, -6, -5, -1, -2, 5, 3, 6,
+ -2, -6, -1, -3, 2, -1, 0, 0, -1, 0, 0, 0, 1, -2, 2, -2,
+ -5, -1, -2, 16, 12, -18, -10, 3, -14, -10, 16, -1, -3, -16, 28, 3,
+ -1, -1, 12, -5, -6, 6, 7, -7, -18, -28, 11, 0, 6, -2, 26, -21,
+ -10, -1, 24, -3, 20, -19, 15, -14, -3, -3, 15, -35, -2, 6, -14, 30,
+ 6, -36, -8, 17, 0, -27, 26, 16, -38, 8, -14, 57, 3, -31, -14, 34,
+ -20, 33, 2, -6, -7, -28, 20, -24, 8, 13, 8, -39, 17, 40, -42, -11,
+ 13, -46, 1, 28, -22, 11, -3, -14, 5, 20, -12, -4, 49, -22, -24, 39,
+ -11, -1, -9, 37, -30, 13, 34, 4, -11, -25, 18, -22, 1, 29, -17, -3,
+ -26, -16, -21, 12, -18, 7, -17, -6, 51, 0, -21, 10, 24, -45, 8, 14,
+ 31, -10, -37, 6, 0, 24, 3, -18, -13, 14, 11, 0, 7, -1, -38, -29,
+ -21, 32, -30, 22, -26, 14, -40, 55, -36, 30, -12, 8, 31, -16, 19, -15,
+ 23, -48, 36, 1, 63, 3, 24, 0, -3, 14, 26, -21, 15, 47, -21, -80,
+ 14, -4, -25, -33, 11, 25, -35, -44, 13, -2, -48, -11, -23, -7, 27, -4,
+ -15, -22, 5, 26, -36, 50, 23, 11, -23, -14, 19, 32, 14, 38, -66, 56,
+ -11, 26, 18, -12, 17, -30, -6, -54, 22, 77, -62, -12, -16, 34, -25, 2,
+ 14, -62, 12, 20, -22, -50, 58, -29, -58, 4, 28, 30, 13, 25, -78, 38,
+ 45, -19, -7, 52, -61, 27, 17, -21, -4, 6, 37, -24, -38, 73, 8, -16,
+ 21, -2, -15, -19, -19, 18, 3, 7, -48, -10, -10, 10, 4, 13, -13, -4,
+ 0, 46, -12, 6, -18, -25, 4, 14, 27, -22, -37, 14, -6, -17, 55, 40,
+ -111, 63, 9, -38, -16, 46, -35, 4, 0, -10, -8, -12, 58, -69, 1, 66,
+ -38, 21, -33, -6, 10, 0, 10, -11, 18, -16, 32, -7, -10, -25, 65, -42,
+ 42, -62, 18, -3, -2, -8, 21, 4, -71, 13, 40, -3, 18, -19, -29, 15,
+ -66, 60, -50, -6, 67, -80, 17, 66, -21, -20, -15, 68, -16, 72, -4, -23,
+ 4, 53, -8, 8, -4, 0, 27, -26, -22, 25, -31, 7, -39, -18, 27, -43,
+ -25, -33, -6, 17, -16, 0, -55, 6, 26, -3, -67, 7, 60, -83, 25, 15,
+ 45, -8, 51, -55, 28, 42, 42, -17, 37, -6, 17, 8, 11, -1, 59, -7,
+ -45, 14, -41, 107, -49, -50, -25, 63, -58, -27, -57, 19, 13, -13, -27, 19,
+ -42, 63, -113, -1, 44, 8, 1, -10, -33, 0, 55, -41, 15, 0, 76, -17,
+ -39, 60, -20, 28, 54, -93, 15, 83, -30, 4, -56, 49, -58, 30, -28, 2,
+ 54, -64, 83, -128, 86, 24, -40, -27, -66, 51, 11, -51, 59, 6, 20, -58,
+ -24, 78, -7, -23, -27, 1, -3, -24, 10, -6, -16, 34, 39, -37, -17, 26,
+ 52, -69, -7, 11, 24, -62, 38, -13, 41, 5, -2, -5, -12, 15, 77, -49,
+ -10, 74, -12, -11, -38, 32, -24, 25, -6, 19, -24, -2, -38, 63, -91, 64,
+ -27, -11, -56, -43, 27, -41, -55, -15, 1, -4, 27, 8, 37, -57, 3, 28,
+ -11, -4, 46, -39, 3, 12, 100, -33, 39, 17, 6, 49, 5, 38, -12, 10,
+ 21, -35, 23, -6, -36, 10, -9, 3, -1, 13, -65, -40, 36, -25, -28, 5,
+ -37, -20, -14, 31, -16, -32, -16, 4, 15, -11, 26, -16, 29, -42, 46, 7,
+ 39, -1, -5, -9, 33, -31, 35, -33, -7, 17, 56, -24, 22, 14, -22, -34,
+ 44, 16, 11, -46, 43, -48, -27, 43, 36, -45, 21, 11, 0, -98, -22, 87,
+ -126, 52, -45, 34, -28, -17, -31, 23, -38, 23, 25, -11, 25, -63, 21, 13,
+ 19, 47, 28, -23, 20, 21, -5, -14, 112, -30, -67, 37, 43, -12, -57, 34,
+ -9, -29, 52, -19, 14, -51, 0, 26, -69, 3, -18, -24, -34, 31, -15, -33,
+ -36, 10, -20, -38, 63, 0, 44, -50, 72, 25, -16, -6, 6, 15, 23, 31,
+ 3, -20, -9, 19, 63, 17, -18, -5, -12, -87, 31, 26, -37, -29, 49, -42,
+ -15, 14, 11, -16, -31, 46, -19, -13, -37, 59, -91, 47, 4, -11, -26, 39,
+ -29, -24, 48, 10, 39, -11, 45, -51, -1, -24, 47, -19, 39, -34, -29, -17,
+ 1, 56, -25, -16, -13, 0, 48, -71, 49, 2, -2, -45, -10, 59, -17, -25,
+ 9, 9, 44, 42, -32, -23, -49, 46, -11, -50, 76, -43, -45, -1, 41, -8,
+ 2, 71, -36, -61, 35, 21, -13, -36, 44, -45, 26, -45, -21, 28, -37, 39,
+ -29, 15, 4, -5, 24, -7, 7, 3, 68, -80, 26, 24, -22, 8, 26, 28,
+ 10, -26, -3, 16, -51, 85, -8, -14, -54, 39, -28, -9, -25, 46, -39, -20,
+ 34, 11, -25, -7, -12, -41, 12, -17, -5, -43, -8, 0, 18, 13, 9, 28,
+ -40, 34, 0, 13, 40, -20, 5, 22, -25, -13, 51, 9, -34, 43, -16, -18,
+ 2, 35, -4, -28, 14, -37, 6, -8, 31, -49, 9, -31, 61, -55, 35, -46,
+ -37, -12, 32, 74, -59, -30, -21, 5, 38, 3, 48, -35, -42, 2, 29, 81,
+ -8, -37, 24, 42, -31, 18, -11, -21, -67, 98, -18, 11, -26, -14, -76, 11,
+ 71, -70, 30, -52, 37, -45, 61, 6, -33, -44, 58, 24, -16, -51, 49, -28,
+ 51, -6, -15, 46, 10, -24, 36, -4, 6, -30, 46, -66, 54, 27, -16, -34,
+ -23, 90, -61, -49, 22, -3, -22, 17, -35, -11, -59, 23, 2, -25, 69, -24,
+ -26, -28, 37, 12, 11, -63, 27, 18, 3, 34, -25, 9, -14, 29, 4, 24,
+ 21, -77, 12, 14, 37, 1, 45, -63, 1, 49, -14, -23, -7, -4, -42, 48,
+ -57, 18, -36, 17, 15, -37, 47, 1, -41, -14, 11, 49, -32, 32, -36, -19,
+ 21, -11, 39, -31, 43, 0, -24, 15, 6, 9, -46, 5, 21, -23, 2, -28,
+ -15, 59, -13, -29, 50, -7, -45, -12, 23, -1, 27, 6, -17, 7, -4, -3,
+ -3, 53, -10, 17, -52, 19, 24, -8, -7, 19, -51, -30, 55, -22, -22, 29,
+ -38, -25, 39, 3, 34, -84, 26, -37, 42, 15, 4, -4, -16, -33, 29, 17,
+ 43, -93, 24, -6, -20, -14, 107, -29, -36, 69, -21, 10, -7, 74, -67, 38,
+ -23, -8, 27, -35, -49, 29, -8, -4, 7, -8, 5, -38, -28, -33, 22, 70,
+ -37, -10, -56, 26, 5, 7, 59, -21, -58, 10, -2, 6, 49, -16, -9, -38,
+ 60, 13, 43, -43, 23, -14, -9, 38, 17, -38, -15, 29, 6, -5, -11, -3,
+ -4, -65, 45, -13, 26, -13, -4, -5, -38, 48, 0, 4, -40, 40, -48, 23,
+ 21, 23, -42, 5, -17, 13, -9, 12, -3, 5, -25, 34, -24, -3, -18, 16,
+ -44, 13, 27, -30, 44, -54, 6, -18, -3, 4, 21, -25, -13, 22, -20, -12,
+ 37, -10, -10, 5, 24, -17, 23, 9, 0, 4, 3, 12, 26, -27, 17, 9,
+ -41, 69, -1, 15, -37, 15, -6, 0, -1, 3, -13, -23, -18, 27, -5, 21,
+ -16, -41, -2, 20, 13, -27, 6, -21, 8, 6, 0, 6, -5, -21, -22, 73,
+ -40, 4, 6, 21, -8, -5, 29, -47, -1, 1, 19, 3, -10, -1, 2, -48,
+ -11, 45, -27, 11, -33, -21, 21, 7, 12, -22, 21, -40, 13, 27, -20, 37,
+ 5, -18, -18, 35, 40, -11, 20, -25, 10, -4, 33, 12, -29, 9, -20, -30,
+ 34, 24, -9, -10, -24, -16, 8, 22, 6, -58, -5, -13, 18, 5, -43, 10,
+ -16, -25, 13, 70, -25, -7, -25, -19, 16, 58, -46, -5, 6, -5, 40, -24,
+ 22, 50, -73, -7, 7, 32, 39, -27, -23, -23, 56, -35, 21, 17, -40, 40,
+ -52, 4, 0, 49, -29, -42, 24, 9, 31, 2, -46, 0, -9, -5, 9, -31,
+ 64, -5, -45, -26, 42, -4, -34, -8, -3, 32, -15, -8, 22, -24, 13, -31,
+ -2, 31, 10, -10, -18, 8, 24, 20, -29, 2, 14, 23, 25, -4, -19, 20,
+ -25, -5, -3, 23, -8, 52, -42, -17, -7, 29, -26, 2, -19, 55, -50, -28,
+ 1, -10, -7, 7, -41, 16, 21, 1, -20, 0, 16, -19, 14, -39, 86, -17,
+ -34, -64, 73, 0, 20, -28, 30, -22, 9, 58, -4, -8, -18, -20, 31, -21,
+ 1, 26, -49, 5, 41, -25, -13, -6, -7, 6, 10, 42, -30, -26, -43, 11,
+ 44, -54, 31, -10, -11, -17, 25, 32, -43, 64, -23, 3, -37, 33, -30, -4,
+ -35, 47, -29, 9, 23, -34, -5, 64, -37, 32, -11, -44, 21, 25, -19, 8,
+ 6, -25, 34, 2, -18, -23, 38, 20, 7, 21, 1, -32, -37, 50, -9, -25,
+ 34, -61, 55, -32, 7, -48, 20, 13, 0, -35, 17, 9, -42, -28, 14, 42,
+ -33, -25, -5, 21, 41, -60, 32, -7, 38, -9, -3, 20, -4, 29, -69, 62,
+ -16, 35, -64, 45, 10, 5, -1, -18, -18, -1, 5, 32, 0, -21, -12, -23,
+ 29, -15, 13, -39, -3, -3, 6, 35, -24, -23, -7, -2, 44, -10, -37, 25,
+ 25, -25, -23, 7, 40, 4, -40, -18, 21, -2, -3, 1, -16, 45, -26, -2,
+ -16, 18, 41, -64, 8, -26, 40, 5, -32, 8, 18, -1, 15, -1, 9, 2,
+ 2, -13, -12, 35, -9, 13, -62, -29, 72, 18, 7, -30, 26, -7, -29, 39,
+ -38, 31, -56, -25, -3, 17, 2, -3, -46, 35, 6, 27, -39, -3, 3, 31,
+ -25, -19, -2, 38, 26, -77, 22, 18, 40, 3, -22, 65, -48, 33, -16, -37,
+ 78, -34, 1, -52, 23, 16, 1, -37, 17, 12, 1, -4, 8, -27, -1, -11,
+ -18, 27, -23, -10, -11, -19, -6, -7, 51, -74, 16, 20, 17, -14, 7, 7,
+ -13, -8, -5, -11, 39, 21, -5, -44, 31, 64, -38, -18, 20, 40, -4, -10,
+ 10, -23, 23, -6, -20, 11, 9, 10, 6, -23, -11, 1, 17, -56, 56, -40,
+ 0, -17, -60, 84, -80, 16, -13, 4, -25, 12, 17, -42, -26, 54, -29, 12,
+ -5, 37, 16, -62, 94, -5, -2, -2, -2, -9, 5, 51, -25, -5, -11, 5,
+ 16, -14, -9, 43, -44, -8, 27, 2, -1, 9, -18, -6, 5, 23, -46, -9,
+ 13, 16, -10, -10, -23, 59, -47, -14, 23, 29, -15, -14, -30, 21, -21, 0,
+ 14, -3, 25, -16, -35, -2, -8, 32, -19, 22, -23, -37, 30, -33, -19, 11,
+ 12, -32, 47, -4, 27, 11, 9, -35, 39, 29, -18, -2, -11, 27, -2, 13,
+ 0, 18, -26, 15, -25, 26, -4, 21, -29, -33, 18, -8, -31, -5, 21, -1,
+ -38, -28, 41, -18, -4, -22, 47, -12, -44, 55, -79, -5, 19, -10, 25, 4,
+ 21, 15, -28, 13, -6, 45, -24, 25, 10, -26, 4, 2, 31, 3, -7, 3,
+ 5, -23, 51, -9, -32, -5, 35, -32, -21, -20, 35, -40, -10, 20, -8, 7,
+ -5, -38, -1, -24, 39, -26, 20, -16, -9, -27, 25, 34, -32, 1, 12, -13,
+ 3, 37, 13, 3, -31, 27, 30, 5, -15, -21, 2, 10, -13, 16, 36, -9,
+ -59, 41, -10, 61, -60, -35, -11, 7, 5, -28, 30, 5, -23, -66, 34, 50,
+ -26, -19, -10, 11, 8, 8, -35, -5, -11, 56, -24, 10, 35, 16, -10, -19,
+ 30, 4, -11, 23, 0, -6, 6, 36, -15, 0, 15, -14, -26, -8, -5, 15,
+ -31, -45, 42, -30, 0, -9, 6, -22, 9, -22, 7, -8, 15, -19, -3, -13,
+ 29, -14, 9, -16, 3, -5, -10, 63, 0, 4, 4, 20, 16, -21, 18, 31,
+ -24, -19, 31, 54, -39, -7, -16, 5, -3, 0, -29, 16, 6, -29, -25, -52,
+ 49, -9, -66, -3, 50, -3, -2, -14, 4, -8, 33, -40, 2, 15, -6, -17,
+ -4, 10, 48, -16, 14, -9, 27, 10, 2, 2, 40, -35, 5, -10, 7, 28,
+ 1, 4, -30, -4, 0, 1, -14, -13, -11, 26, -17, 13, -44, -9, -6, -23,
+ 17, 11, 11, -21, -11, 0, 9, 8, 8, -30, 29, 10, -26, -12, 15, 17,
+ 4, -26, 14, 19, 20, -9, -24, 39, 23, -10, -35, 8, -6, 18, -25, 15,
+ -17, 41, -48, -31, -5, 47, -14, -20, -4, -7, 5, -19, 3, 21, 12, -23,
+ 15, -24, 8, 3, -25, 2, 28, 14, 21, 25, -72, 15, 26, -6, 45, -27,
+ 29, -30, -17, 23, 6, -2, 27, -46, 13, 9, 15, -57, 27, 1, -18, 1,
+ -11, -2, -20, -16, -23, 24, 18, -21, -5, -15, -14, 26, -12, 30, -48, 37,
+ -24, -3, 23, 9, -5, 9, 8, -43, 23, 26, 6, 28, -29, 30, -8, -12,
+ 25, -18, 33, -48, -4, 29, 1, -8, -4, -20, 41, -22, 1, 12, -33, 0,
+ -17, -16, 29, -3, -2, -36, 6, -1, -11, 4, -24, 40, -24, -5, 26, -2,
+ -28, 13, -11, 35, -9, -2, -3, -6, 13, 10, 1, 11, -22, 22, -27, -5,
+ 20, 11, -1, 8, -23, 8, 7, -7, 17, -6, 16, -9, -10, 3, 13, -3,
+ -17, 19, -21, 6, -13, -15, -7, 22, -15, -7, 11, -20, -19, -6, 0, 28,
+ -10, -7, -13, 9, 7, 1, -11, -6, 21, -33, -4, 52, -11, -1, -2, -2,
+ -4, 32, 17, -31, 7, 12, 2, -5, 11, -1, -6, 1, 3, -11, 5, 4,
+ -15, -8, 10, 5, -18, 5, -26, -11, 22, -15, -23, 22, 19, -30, 3, 1,
+ -5, 10, -17, 10, -2, 10, 7, -17, -5, 36, -12, -24, 27, 22, -3, -11,
+ -6, -7, 20, 5, -21, 0, 23, -31, -27, 14, 2, 8, 7, -15, 0, 13,
+ -7, -3, -21, 33, -4, -26, 7, 5, -7, -7, 1, 3, 4, 11, -24, 6,
+ 11, -7, 14, -9, -11, -1, 34, -22, 11, 1, -18, 17, 4, -19, 28, -15,
+ -7, -11, 12, 1, -7, -9, -12, 17, -20, 6, 5, 2, -10, 12, -23, -3,
+ 26, -1, 4, 6, -25, 12, -3, -26, 2, 15, 14, -18, -6, -17, 14, 4,
+ -10, 21, -13, 5, -15, -20, 27, 6, 8, -11, 18, 15, -34, 17, -2, -13,
+ 41, -9, -10, -6, -2, 7, -11, -4, 28, -26, -6, 25, 17, -36, -2, 33,
+ -39, -15, 11, -2, 26, -32, -31, 21, 26, -11, -24, 12, -17, 4, -33, 24,
+ 14, -10, 12, -19, -3, 28, 11, -8, 0, 26, -17, -7, 8, -6, 20, 26,
+ -29, -27, 25, -14, -2, 10, -16, 39, -24, -17, -4, -13, 24, -10, -3, -20,
+ 25, -1, -24, 24, -20, -5, 21, -26, 7, 21, -26, 15, 17, 6, -34, 5,
+ 11, -27, 20, 17, -13, -8, -16, 9, 33, -36, 19, 5, 4, -2, -33, -12,
+ 38, -17, -10, -4, 19, 14, -4, -32, -41, 64, 5, -38, 28, 6, -2, -11,
+ -22, 11, 17, 17, -24, 23, -7, 9, 10, -38, 0, 25, -9, -6, -27, 20,
+ 2, -27, 34, -23, 17, -22, 4, 12, -43, 29, -8, 25, -19, 13, -17, -11,
+ 27, -8, 14, -19, 12, 9, -22, -6, 11, -10, 17, -4, 2, -3, 15, -47,
+ 32, -18, 11, 14, 0, 8, -33, -14, -12, 23, 17, -12, -4, 13, -27, 10,
+ -17, 20, -2, -11, -11, 27, 18, -21, -6, 26, -18, 9, -7, 27, -12, 3,
+ -9, -9, 22, 7, -38, -2, 14, -16, 12, -21, -10, 22, 1, -28, 20, 31,
+ -11, -49, 9, 16, -4, -7, -4, -5, 46, -39, 9, -18, 16, 22, -24, -13,
+ 14, 29, -10, 3, -23, 4, 11, -33, 30, 18, -9, 5, -11, 4, -20, 30,
+ -9, -14, -7, -9, 4, 0, 4, -15, -11, 23, 5, -24, 26, -6, -8, -17,
+ 21, 0, 3, 13, -10, -13, 19, -16, -10, -5, 10, 8, 22, -19, 4, -8,
+ 0, -24, 38, 12, -33, 10, -9, 5, -13, 11, 3, 7, -18, -12, 11, -4,
+ 8, -17, -7, 16, -9, -2, -9, 0, 10, -2, -1, -1, 12, -6, 13, -18,
+ 18, -6, 10, 1, -3, 9, -2, -30, 23, -9, 29, -11, -31, 10, 6, -21,
+ -19, 54, -30, 18, -12, -26, 23, -10, -31, 23, -5, 49, -34, 4, -18, 3,
+ 11, -24, 27, 12, -24, 3, -13, 3, 16, -6, -7, 1, 19, -8, -3, -11,
+ 13, -14, 19, 10, 17, -21, 14, -40, 12, 13, -5, -3, 21, -14, -29, 16,
+ -24, 1, 10, -1, -3, 6, -15, -16, 16, -4, 2, 23, -32, -1, 7, -5,
+ 13, 4, -15, 33, 1, -7, -7, -12, 13, 6, -8, 2, 21, 2, -21, 17,
+ -14, -19, 36, -2, -16, -4, 3, 9, 15, -39, 3, 9, -10, -3, -12, -7,
+ 28, -19, 8, -18, 22, -18, -11, -2, 17, 23, -15, -24, 11, 13, -14, -10,
+ 9, 4, 14, -10, -13, 13, -3, -12, 25, 6, -12, 12, -19, -3, 19, -10,
+ -13, 19, 10, 18, -31, -15, 19, -9, -14, -6, 25, -18, 2, 17, -41, 11,
+ 16, -20, 3, -10, 16, 9, 14, -27, -1, -3, 9, -19, 36, -6, -4, -4,
+ -16, 5, -7, 24, -1, -30, 13, -8, -4, -9, 47, -37, 3, 21, -24, 1,
+ 3, 11, 5, -10, -8, 20, -31, 16, 10, -1, 0, -9, -1, -6, 14, -6,
+ 6, -17, 20, 3, -23, 10, -14, 17, -16, -2, 26, 7, -20, -10, 9, -18,
+ 31, -35, 3, 14, -8, 13, -27, -4, -4, 26, -20, -9, 14, 22, -27, -4,
+ 18, 9, 9, 3, -13, -20, 15, -13, 6, 12, -5, -6, -12, 0, 4, -10,
+ 18, -7, -8, -15, 1, -11, 17, 5, -11, 14, -6, -11, 4, 10, -5, 13,
+ 0, -7, 15, -2, -16, 2, -3, 9, -6, 2, 34, -11, -17, -8, 21, 13,
+ -21, -4, 14, -7, -7, -19, 13, -7, 4, -25, 7, 16, -14, -40, -11, 36,
+ 3, -10, 4, -10, 7, -1, -1, 4, 14, 6, -14, -14, 17, 23, -13, -2,
+ -1, -12, 9, 8, 1, -7, 22, -29, 7, 7, 0, -24, 13, -10, 18, -1,
+ -3, 13, -24, 30, -32, -5, 18, -2, -6, -8, 11, -18, -12, 17, -11, 0,
+ 5, -4, -14, 31, -15, -16, 13, 12, -4, 4, -4, -1, -11, -15, 26, -18,
+ 29, -15, -3, -8, 6, 6, -34, 22, 0, 11, -18, 16, 20, -19, -21, -5,
+ 11, 21, 10, 10, -27, -5, 3, 2, -5, 9, -9, -1, 1, -11, -3, 8,
+ 4, 1, -1, -11, 19, -1, -21, -5, -2, 11, -2, -8, 10, -7, -1, 2,
+ -18, 3, 0, 7, 2, 7, 1, 1, -28, -14, 10, 19, 12, -21, 7, -19,
+ 20, -2, -3, -1, 17, -11, -13, -16, 32, 4, -5, -3, 4, -4, 18, -2,
+ -17, -6, 16, -3, 4, -12, 4, -2, 2, 6, -18, 20, -24, 17, -10, 19,
+ -16, -17, 8, -7, -5, 16, -12, -18, 11, 9, 2, -8, 17, -9, -3, -13,
+ 7, -6, 30, -15, -11, 5, 14, -2, -15, -5, 14, 13, -12, -24, -10, 22,
+ -2, -8, -1, 21, -5, -19, -16, 8, 42, -6, -27, -12, 23, 10, -17, -14,
+ 16, 14, -16, -2, 9, -2, 16, -9, -31, 22, 0, -2, 3, 4, -5, 20,
+ -24, -5, 13, -1, -5, -10, -6, 8, -11, 2, 8, -8, -5, -9, 1, -6,
+ 16, -1, -18, 4, 9, -3, 6, -4, 6, 9, -7, -9, -1, 10, -7, 4,
+ 3, -3, 4, -8, -5, 3, -4, 10, 6, -15, 2, 3, -5, -2, -3, -12,
+ 18, 2, -16, 7, 13, 0, -19, -8, 11, -6, -1, -9, 5, 13, -8, -6,
+ 6, 7, 11, -11, -6, 13, -2, -5, -1, 9, -2, -7, -15, 10, 5, -1,
+ -13, 8, 0, -6, -2, -2, 18, -16, -7, 2, 3, -4, 6, -11, 4, 6,
+ 1, -5, 22, -11, -5, -6, -3, 11, -1, -1, 4, 1, -4, -13, -4, 11,
+ -9, 1, 9, -1, -8, 1, -5, -7, 5, -14, 18, -1, -12, 11, -12, 16,
+ -5, -11, 11, -2, 15, -7, -18, -10, 0, 18, -12, 8, 3, 6, -16, -3,
+ 3, 6, 0, -1, -3, 4, 9, 3, -17, -7, 11, 11, -19, 5, 15, -12,
+ -3, -12, 4, 11, -19, 0, 0, -14, 21, -15, 2, 8, 3, 8, -8, 5,
+ -18, 9, -2, -8, 23, -5, -16, 5, 3, -20, 13, 11, -6, -15, 5, 4,
+ -12, 2, 10, -5, -12, 5, -14, -2, 18, 11, -14, 0, 28, -10, -20, 4,
+ 7, 9, -13, -6, 15, 11, -9, -6, 14, -8, 10, 4, -12, 11, -18, 13,
+ -17, -9, 16, -4, -14, -7, 17, -24, -5, 4, 6, -6, 14, 2, -24, -22,
+ 11, 13, 8, -16, 6, 13, -28, 10, -2, 11, 8, -1, -8, -14, 22, 3,
+ -5, -13, 18, 7, -26, 15, 20, -6, -10, 4, 11, 5, -8, -3, -5, 0,
+ -1, -6, 0, 4, 4, -14, -1, 1, 8, -14, -10, -4, 6, 4, -8, 3,
+ -9, 0, 11, -4, -7, 5, 4, 6, -29, 18, 22, -19, -16, -11, 17, 7,
+ -4, 3, -23, 20, 8, -19, 3, 13, 13, -16, -18, 15, -6, 0, 3, 17,
+ -7, -4, 2, -22, 21, -1, -2, -1, -15, 13, 3, -7, 4, 0, -7, 8,
+ -7, 11, 3, -2, -8, 10, -15, 0, 9, -14, -8, 8, -2, -9, 10, -13,
+ 9, 7, -6, 2, -12, -4, 6, -12, 8, 12, 3, -10, 6, 7, 1, -2,
+ -11, -1, 7, -7, 8, -13, -10, 11, -9, -10, -8, 20, 9, -11, 8, -5,
+ -4, 6, -3, 5, 13, -13, -7, -7, 6, 19, 0, -9, 9, -1, -3, 4,
+ -7, 0, -2, -4, -5, 5, 0, -5, 14, -19, -14, 18, -1, -5, 3, -12,
+ 18, -19, 4, -15, -10, 10, 10, -17, -4, 19, -6, -2, 5, 11, -4, -3,
+ 9, -22, 28, -6, -5, 0, -1, 11, -11, -13, 22, 3, -8, -9, 1, 3,
+ 0, 1, 2, 7, -5, -25, 10, 6, 6, 2, -11, 8, -16, 15, -20, 5,
+ 9, -6, -13, -5, 14, 6, -21, 22, -7, -14, 4, 26, -8, -13, 8, 1,
+ -10, -13, 11, 10, -10, 2, -13, -9, 15, 0, 10, -30, 14, 7, -13, -5,
+ -12, 8, 10, -4, 10, 12, -15, -7, 5, 2, 2, 10, -13, -3, 0, 21,
+ -2, -16, 9, 3, -1, 6, 15, -3, -21, 10, -8, 5, 1, 1, 2, -19,
+ 10, -7, -3, -1, 8, 6, -26, -10, 18, -28, -3, -3, 4, 0, -7, 6,
+ -10, -2, 25, -19, 5, -11, -2, 14, 4, -5, -3, 4, -5, 6, -2, -3,
+ 11, -1, 13, -12, 5, 20, -15, -3, 17, 4, -14, -5, 11, 3, 1, 6,
+ 11, -20, 10, -4, -4, -4, -4, -18, -7, 5, 10, -25, 7, -9, -15, 1,
+ -4, 4, 4, -4, -1, -18, 9, -6, 4, 7, -19, 10, 0, 3, -6, 12,
+ 18, -5, 2, 4, -4, 11, 2, 5, 2, 1, 3, -4, 3, 4, -3, -2,
+ -8, 11, 5, -10, -12, 12, -6, 6, -9, -6, 4, 9, 0, -9, 4, 3,
+ -7, -5, -12, 19, 2, -28, 1, 0, 9, -10, -6, 3, 3, -11, -4, 6,
+ 7, -7, -3, 5, -12, 9, 10, -12, 7, 5, 5, -6, -9, 16, 6, -16,
+ 3, 8, -17, 12, -5, 2, 1, 21, -25, -10, 5, -2, 15, -6, 1, 3,
+ 5, -16, -2, -16, 32, -17, 7, -13, 6, -1, -4, 0, -4, 10, -2, -17,
+ -7, 29, 0, -13, -1, -1, 2, 12, -4, 3, -2, 4, -19, -1, 18, 2,
+ -3, -15, -2, 10, -4, 1, -2, -5, 20, -5, -6, -7, 9, 0, -2, -24,
+ 5, 15, -2, -11, 1, 0, -2, -14, -2, -4, 7, 4, -4, -9, 2, 4,
+ -8, 8, -1, 2, 10, -13, 4, 10, -4, 27, -22, 17, -18, -2, 5, 8,
+ -1, 4, -6, 2, -1, 9, 1, -3, 16, -21, -18, 2, 10, -14, 9, 3,
+ -14, -9, 0, -16, 9, -10, 11, -12, -3, 1, -10, 3, -2, 2, -13, 13,
+ 10, -1, 4, 4, 1, -3, 9, 0, 4, 8, -14, 10, -4, 0, 8, 11,
+ -2, 2, -11, 3, -13, -8, 11, 4, 1, -7, 4, -21, 0, 1, -4, -22,
+ 17, -8, -16, 10, 4, -2, 0, -4, 2, -2, 2, -6, 10, 3, 3, 5,
+ -1, 6, 5, 2, -6, -3, -2, 7, -4, -4, 12, 1, -30, 12, -7, 3,
+ 4, -6, -7, -9, 9, -1, 7, -10, 12, -16, 2, -8, 23, -5, -5, -1,
+ -8, 10, 3, -14, -12, 25, 7, -13, -6, 4, 15, -3, -23, 9, 12, -9,
+ -13, 18, -9, 5, 1, -17, -4, 13, -10, 11, -10, -1, 6, 0, -7, -2,
+ 9, -4, 9, -24, 7, 6, -5, 4, 15, -15, 11, -5, -24, 9, 11, -16,
+ 2, 0, -9, -2, 10, 7, -12, 8, -12, -6, 10, 6, 10, -14, -5, 20,
+ -16, 7, 8, -1, -19, 24, 2, -10, 15, 6, -6, -21, 3, -3, 15, -9,
+ -3, 3, -2, -4, -3, -9, 5, 0, -5, -3, -15, -4, -1, 1, -14, 33,
+ -12, -18, 9, -2, -10, 9, 9, -1, -1, -5, 10, -3, 2, 4, 2, -9,
+ -1, 25, -2, -3, 15, -17, -7, 8, -7, 0, 10, -13, 9, -11, 0, -3,
+ 18, -15, -11, 5, 0, -12, -2, 7, -6, -4, -9, 11, -6, 8, 1, -14,
+ 3, 16, -10, -3, 2, 6, 4, 9, -9, -2, 0, 2, -3, 15, 3, -10,
+ -4, -8, -1, 10, -13, -9, 16, -9, -3, -2, 5, -6, -6, -9, 10, 8,
+ -4, 14, -7, -19, 12, 1, 2, 1, 4, -1, -6, -3, -3, 5, 7, -2,
+ 0, 0, -5, 0, -6, 1, 6, -5, -4, 5, -6, 5, -4, -8, 15, -5,
+ -7, 0, 3, -8, 0, 3, -8, -4, 6, -4, -4, 15, -5, -8, -7, 4,
+ 7, -10, -6, 15, -4, -13, 7, 2, 2, 1, -4, 5, 0, 0, 1, 4,
+ -7, 4, 4, -2, 4, 5, 1, -18, 12, 4, -3, -6, 11, 0, -13, -1,
+ 1, -12, 3, 13, -9, -15, 7, 0, -4, -8, 0, 5, 0, -9, 1, 1,
+ -3, 0, 3, 5, -10, 6, -1, -4, 4, 15, -15, -5, -9, 18, -2, 0,
+ 15, -11, -9, 0, 6, -2, 8, 1, -8, -9, 7, 3, -7, -3, 6, 1,
+ -5, 0, -5, -5, 0, -3, 11, 1, -3, -8, -4, -4, 5, 9, -6, -7,
+ 4, 15, -13, 5, -4, 2, -6, -2, 0, 5, 4, -4, 0, -6, 8, 3,
+ -2, -4, -4, -11, 4, 10, -1, -4, -2, -1, -3, 1, -4, -2, 3, 1,
+ -4, -11, 12, -4, 5, -2, 7, -12, -2, 4, -4, 5, 8, 1, -8, 14,
+ -11, -1, 1, 4, 0, 5, -5, 2, -7, -7, 10, 3, 1, -13, 0, -4,
+ 5, -9, -1, 1, -11, -5, 5, 2, -6, 5, -5, -8, 12, -2, 7, -1,
+ -10, -5, -7, 14, 9, 3, -5, -2, 5, 4, -2, 0, -5, 2, 3, 3,
+ -12, 6, 3, 2, -9, -1, 24, -13, -9, -1, -2, 0, 7, -6, -17, 14,
+ -12, -5, 10, 1, -4, -1, -1, 1, -3, 2, -2, -11, 1, -1, -1, 1,
+ 10, -3, 2, 1, 5, -7, 1, -1, -5, 7, 1, 7, -4, 5, -11, -8,
+ -8, 7, 8, 6, 0, -15, -1, 7, 0, -6, -3, 7, -4, -3, -2, 1,
+ 5, 8, -6, -4, 11, 3, -14, -6, -3, -6, 9, -5, 4, -5, 2, 3,
+ -13, -3, 1, -4, -3, 11, -1, 0, 7, -16, -6, 11, 5, 0, 4, 5,
+ -2, -3, -2, 8, 7, -16, 1, 2, 6, 3, -17, 11, -2, -2, -9, 6,
+ 0, -7, 6, -22, -2, 14, 3, -11, 0, -6, -2, -7, -7, 1, 4, 14,
+ -1, -6, 0, 7, 3, -14, 4, 15, -4, -9, -2, 12, 14, -10, 5, 9,
+ -11, -2, -9, 2, -9, 11, 2, -21, 7, 6, -11, -1, 0, 0, 1, -9,
+ 4, 0, -10, 1, 3, -3, -7, 12, -9, -2, 4, 6, 3, -8, 0, 1,
+ -2, -14, 12, 11, -5, 10, -3, -1, 3, -6, 1, 0, -3, 8, -1, -18,
+ 12, 5, -13, -4, 17, -1, -6, 1, -11, 0, -6, 2, -2, -2, 5, 3,
+ -17, 2, -5, 11, -4, 8, 8, -19, -6, 14, -6, -6, 0, 5, 0, -8,
+ 7, 13, -6, -5, 6, -2, -9, -1, 8, 3, -4, -4, 10, -10, -9, 7,
+ 2, -6, 14, 0, -15, 3, 5, -4, -10, 8, 0, -6, -11, 3, 10, -9,
+ 1, 8, -7, 2, -1, -6, -8, 6, 2, -8, -2, 16, -3, -3, -1, 5,
+ -3, -8, 6, 9, -6, 1, -1, -1, 2, -6, 6, -1, -9, 3, 9, -10,
+ 1, 5, -4, -14, 2, 1, 7, -5, 3, -2, -13, 5, 10, -9, -8, 14,
+ -6, -19, -3, 19, -3, -3, 6, -4, -10, 3, -1, -4, 5, 5, 1, 0,
+ -1, 11, 4, -10, 3, -5, 4, -7, 1, 8, -3, 1, 2, 0, -10, 2,
+ 5, -15, -3, 8, -8, -6, 5, -2, -5, -5, 11, 0, -12, -7, 5, 2,
+ -5, 2, -1, -4, 2, 7, -12, 5, 6, -3, 5, -1, 12, 7, -13, -3,
+ 0, 3, 0, 13, -1, -4, 0, -9, 5, -6, 5, -2, -10, -6, -2, 9,
+ -8, 5, -6, -10, 5, 4, -6, -2, 1, 1, 6, -14, 10, -3, -4, -5,
+ 1, 8, -16, 7, 7, -1, 0, 3, -5, 2, -1, -3, 11, -11, 9, 8,
+ -18, 3, 8, 13, -4, -5, -9, 4, -2, -4, 9, 5, -6, -5, -15, -3,
+ 17, -6, 2, -8, 4, 4, -4, -12, -3, -2, -2, -4, 5, -4, 1, 7,
+ -12, -6, 8, 6, -2, 1, -3, 3, 10, -3, 7, -11, 12, 4, -1, -1,
+ 1, 0, -11, 11, 4, 0, -2, -9, -2, -2, -8, -1, 5, -4, -5, -5,
+ 1, 10, -8, -11, -5, -4, 5, -1, 1, 6, -2, -5, -5, 3, 6, -2,
+ 6, -3, 0, 4, 5, 2, 4, -2, 1, 5, -2, -6, 11, -1, -5, 8,
+ -14, 6, -2, -6, -11, 4, 2, -14, 6, -9, 5, -4, -3, 4, -12, -2,
+ 2, -5, 4, 7, -5, 3, 6, -1, -3, -6, 0, 7, 0, 1, 6, 9,
+ 4, -2, -7, -4, 7, 4, 4, -5, -5, 0, 3, -6, -1, 7, -2, -18,
+ -1, 3, -15, 5, -2, -2, 0, 4, -10, -4, 3, 4, -10, 4, -1, 5,
+ 4, -7, 8, -7, 0, 3, 2, -7, 13, 0, -2, -6, -6, 5, 10, -10,
+ 4, -1, 2, -1, -5, 7, 5, -3, -7, 1, -5, 10, 1, -11, 7, 6,
+ -10, -15, 12, 2, -4, 1, 0, -5, 3, 0, -2, 6, -5, -4, -13, -2,
+ 3, 1, 4, 3, 3, -10, -7, -7, 11, -2, 2, 2, -7, 4, -1, 6,
+ 2, 0, 8, 3, 0, -7, 8, 3, 5, -8, -3, -2, 2, 3, -12, -4,
+ -3, 12, -12, -4, 7, -3, -10, -10, -4, 6, -2, -8, 9, 1, 1, 1,
+ -3, -6, 12, -5, -6, -1, 11, -7, 5, 6, 2, 9, -11, 6, -2, 8,
+ 1, -6, 4, 3, -6, -3, 5, -4, 4, 1, -19, -1, 3, 4, 0, 0,
+ -10, -1, -3, -5, -3, 0, 11, -1, -12, -2, 6, 0, -3, 3, 4, -1,
+ -7, 1, -2, -1, 2, -1, 0, 2, -2, 4, -5, -4, 11, -4, -5, -3,
+ 7, 5, -8, 3, 6, -9, 0, 9, -5, -2, 5, -4, -6, 0, 7, -1,
+ -2, 0, -1, -6, -9, -6, -1, 8, 4, -1, -9, -5, 13, 2, -11, -5,
+ 9, 0, -8, -1, 5, -2, -5, -3, -2, 7, 5, -4, -13, 3, 11, -8,
+ 3, 0, 2, 5, -12, -6, 6, 3, -4, -1, 8, 1, -5, -7, -6, 2,
+ 8, 5, -2, -9, 7, -6, -2, 13, -7, 2, 1, -1, -5, 3, 7, -1,
+ -11, 9, -6, -4, -2, -5, -1, 2, -1, 3, 8, -7, -1, -9, 0, 0,
+ -1, 2, 5, -2, 1, -2, -3, 6, 6, -3, -6, -5, 4, -1, 1, 5,
+ 1, -1, -2, -3, -4, 4, 3, 1, -7, 5, -1, 0, -8, -6, 1, 7,
+ -3, -6, -2, 3, -1, -3, 2, 2, 0, -9, 1, -2, 4, 4, -5, 1,
+ -1, 1, 6, -2, 2, -5, -4, -1, 14, -3, 2, -9, 1, -2, -4, 1,
+ -1, 7, -9, 5, 2, -3, 2, -2, -9, -2, 4, -1, 2, -2, -2, 0,
+ -1, -1, -2, 3, 1, -1, -3, -6, 3, 7, -5, -3, 9, -5, -4, -5,
+ 8, -4, 2, 2, 8, -10, -1, 8, -14, 0, 6, -7, -1, 2, -3, 2,
+ -4, 5, 2, -5, -4, 5, 1, -6, 3, 6, -4, -1, -3, 3, -7, 0,
+ 1, 0, -4, 7, 6, -13, -3, 3, 2, -15, 8, 3, -3, -6, 9, -4,
+ -1, 9, 1, -6, -6, 7, 1, 1, -2, 6, -1, -4, -1, -1, -7, 5,
+ 3, 0, -5, -2, 8, -2, -8, 6, 7, -16, -5, 6, -6, -1, 1, 7,
+ -4, -3, -6, 3, -10, -3, 8, -9, -1, 5, -1, -7, 5, 2, -1, 1,
+ 5, 1, 2, -4, -5, 1, 1, 3, 1, -5, -2, 3, 2, -7, -1, 7,
+ 5, -5, -7, 5, 0, 3, -1, -4, -4, 4, 0, -4, 1, 6, -3, -7,
+ 0, -3, -3, -1, 0, -2, -4, 2, 1, -2, 3, -1, 0, -1, -6, 9,
+ -5, 4, -1, -1, 4, -2, 5, -8, 2, -3, -2, 2, -3, 10, 2, -3,
+ -5, 2, -4, -1, -3, -7, 9, 1, 0, 0, -5, 1, -2, -12, 6, 8,
+ -18, 4, -1, 4, -1, 5, -5, -3, 3, -1, 4, -5, 9, -5, -4, -5,
+ 2, 5, -1, -4, 0, -3, -2, 8, -5, 2, 1, -13, 3, 1, 4, 5,
+ -8, 2, 8, 1, -1, 1, -9, 1, -2, -4, 1, 4, -3, 4, -4, -5,
+ 6, 5, -6, -3, -3, 1, 1, -7, 1, 2, 1, -5, -4, -2, 2, -6,
+ 6, 3, 7, -10, -9, 4, 1, -5, 6, 9, 3, 1, -2, -4, 3, 4,
+ -1, -6, 3, 1, -2, -9, 4, 4, -5, 4, -10, 2, -4, -5, -1, 1,
+ 2, 0, 2, -8, 1, 3, -4, -13, 0, 10, -1, -4, 5, 0, -4, 5,
+ -3, 2, -5, 2, 1, 2, 4, 2, 2, -10, 5, 3, -11, -2, 3, 3,
+ 0, -6, -2, 1, 1, 2, -1, -8, -1, -5, -4, -3, 5, 8, -4, -4,
+ 2, 0, -2, -2, 1, -5, 0, 13, -8, -6, 4, 8, -6, -1, 6, -2,
+ 4, -5, 3, 5, -7, -8, -2, -3, 7, 8, -8, -3, 1, 5, -5, -5,
+ 9, -4, -7, -5, 4, 3, -6, 5, 1, -1, 3, 0, -6, -9, 0, -6,
+ 1, 4, 10, 5, -13, 0, 6, -2, -4, 2, -2, 6, -1, -4, 0, -11,
+ 6, 3, -1, -3, 14, -1, -15, 1, 2, 3, -1, 4, -3, -6, 0, 3,
+ 0, -6, 10, -3, -14, -2, 10, -3, -9, -4, 0, 6, -1, 7, -3, -5,
+ -6, 1, 0, -5, 11, -2, 1, -2, 5, -1, -4, -1, -3, -4, 2, 11,
+ 2, -4, 1, 2, -12, 7, 3, -1, -11, 3, 15, -8, -11, 0, 0, 2,
+ -7, 1, -3, -4, -3, -5, -4, 6, 11, -7, -8, -1, 6, -5, -3, 6,
+ 8, 3, -6, 1, -1, -1, -1, -5, -3, 8, 7, 4, -9, 1, -2, -4,
+ -6, 9, -4, 3, -8, 0, 6, -2, -4, -2, -2, -6, 8, -7, 3, 1,
+ 3, -1, -3, 2, 1, -6, -9, 3, -5, 8, 5, -10, 7, 5, -3, -2,
+ -1, -3, -1, -4, -7, 6, 6, 3, -7, 0, 0, 1, 0, -7, 3, -1,
+ 0, 1, 2, 2, 2, -11, -8, 9, 6, 2, -6, -1, 1, -3, 3, 1,
+ -6, 2, -3, -2, -1, 2, -4, 0, -4, -2, 0, -3, -2, -6, 5, 2,
+ 0, -1, -3, -1, 3, 1, -2, 0, 2, 2, 0, 1, 7, 1, -4, -2,
+ -6, 4, 3, -1, -4, -1, 3, 3, -9, -2, 0, -2, -1, -5, 6, 1,
+ -5, 1, -5, 9, -10, -4, 0, -4, 6, 1, -3, -5, 9, -2, -5, 2,
+ 0, 6, -6, 2, 5, 10, -8, -3, -2, -1, 4, -3, -1, -4, 0, -1,
+ 1, -4, 0, 5, -8, -1, -5, -1, -1, 3, 3, 3, 2, -14, -5, 1,
+ 2, 3, 1, -1, 2, 5, -2, 2, -5, 2, 3, -2, -2, -3, 4, 4,
+ 4, -6, 3, 1, -10, 1, -6, 6, -2, -3, 0, -3, 1, -3, 1, -1,
+ -4, -5, -4, 7, -2, -2, -3, 6, -5, -5, 2, -6, 1, 4, 3, -8,
+ 11, 4, -4, -1, 2, 3, -5, -2, 1, 7, -4, 2, 4, -10, 7, -7,
+ -1, 0, -3, 5, -4, -1, -4, 5, -7, 3, 3, -11, -2, -1, 5, 1,
+ -1, 0, 6, -11, 0, 1, -2, 1, 0, -1, -4, 2, 9, -2, -9, -4,
+ 2, 0, 2, -1, 1, 1, -7, 5, -3, 4, -1, -3, -8, 5, 7, -1,
+ -1, -3, 3, -7, 0, 4, -3, -3, 1, 6, 0, -1, 0, -5, -1, 0,
+ -4, 0, 0, -3, 1, -4, 1, 7, -3, -13, -2, -2, -1, 3, 5, 2,
+ -6, 1, 6, -2, -6, 8, -1, -6, 0, 4, 6, -2, 0, -2, -4, 3,
+ 5, -4, -7, 2, 5, -3, -3, 3, 1, -10, -7, 3, 1, -3, 2, 4,
+ -7, -3, 0, 2, -5, -3, 3, -2, 0, 3, 5, -6, -1, 4, -2, 0,
+ 5, 1, -2, -2, 3, 2, -1, -3, -3, -7, 7, 3, -1, -2, 0, 0,
+ 1, -2, 1, 0, -15, -1, 3, 2, -3, 4, 0, -7, 0, -1, -1, -4,
+ -3, 2, -1, -1, 11, -3, -1, -5, -1, 2, 2, 0, 1, 2, 3, 4,
+ -6, -3, -2, 1, 0, -4, 2, 1, -1, -5, 1, -1, -7, 2, -2, -5,
+ 0, 2, -2, 3, 5, 0, -2, -6, 6, -7, 3, -4, -6, 1, 6, 3,
+ 1, -2, -3, -4, -6, -1, 7, -2, 0, -3, 0, 9, -3, -5, -1, 3,
+ 0, -1, -3, 6, 1, -6, -3, 3, 6, 0, -6, -4, 2, 1, -1, 2,
+ -5, 4, 1, -2, -5, 0, 7, -9, 3, -1, 1, -6, 0, -5, -1, 1,
+ -1, 0, -4, 2, -2, -2, 1, 6, -1, -5, 0, 0, 0, 1, 3, 2,
+ 2, -1, -3, 0, 1, 5, 1, -5, -7, 2, 6, -3, -3, -3, 2, -7,
+ -5, 5, 0, 0, -3, -4, -1, 3, -4, -5, 1, 5, -1, -2, -4, 0,
+ 5, 2, 0, 2, 2, -1, -1, -5, 5, 3, -1, -4, 1, 0, -1, -2,
+ -1, 2, 2, -4, -4, 2, -2, -3, -4, -3, 0, 3, -3, -2, -2, 4,
+ 1, -2, -2, 1, 2, -6, -1, 2, 6, 1, -2, 0, 4, -3, -1, -2,
+ -1, 5, 1, -11, 4, 3, -1, -6, 2, -2, 3, -4, -8, -2, -1, 4,
+ 0, 3, -2, -1, -2, -2, 1, 3, 3, -7, 0, 2, 10, 0, -4, 3,
+ -3, 0, 0, 3, -4, 6, -4, -8, 2, 1, 3, -14, 1, -1, -2, 0,
+ 0, -5, -1, 2, -6, -1, 3, 0, -5, -3, 3, 1, 6, -2, 0, 6,
+ 2, -7, 1, 3, -5, 5, 8, 0, -1, 1, -4, -6, -2, 6, 4, -4,
+ -1, 1, -10, 0, -4, 0, -3, 2, 0, -8, 3, -3, 0, 2, -1, 1,
+ -8, -1, -1, -3, -1, 4, 1, 6, 1, 0, 0, -2, 0, -2, 7, -4,
+ 3, -1, 2, 0, -2, -2, -8, 3, 2, -1, -4, 3, 0, -3, -5, 2,
+ -3, -3, -2, 5, 2, 1, 1, -4, 1, -1, 4, 6, -4, 0, -6, -4,
+ 1, 3, 3, -1, -2, -7, -1, -3, 6, -6, 2, 1, 5, -8, -5, -1,
+ 2, -1, -3, -1, -1, 5, -7, 3, 3, 1, 4, -4, -3, -3, 8, 1,
+ -2, 4, 4, -2, -8, 2, 1, 0, 2, 0, -6, 3, -2, -8, -2, 5,
+ -1, -6, 0, 2, -1, -5, -2, -2, 6, 0, -5, -2, 3, 0, -5, -1,
+ 6, 7, 2, -8, -4, 6, 2, -6, -4, 12, 2, -5, -2, -6, 1, 1,
+ -3, -7, -3, 11, -3, -6, -1, 3, -2, -4, -4, 4, -3, 4, -2, -3,
+ 1, 7, 0, -8, 7, 1, -2, -4, -6, 13, 0, -3, 1, 2, -1, -4,
+ -3, 1, 3, -2, -3, -1, 0, 3, -1, -10, -1, 2, -8, -3, 3, 2,
+ 1, 4, -6, -2, 1, -3, -1, -4, 6, 5, -1, -5, -1, 9, -2, 0,
+ -4, 0, 1, -3, 4, -5, 1, 3, -4, -6, 0, 4, -2, -6, 9, -1,
+ -3, 2, -4, 0, 4, -7, -4, -1, 1, 4, 0, -1, 6, -2, -2, 4,
+ -3, -1, -6, -2, 2, 3, 1, -3, 8, -10, -10, 7, 0, -2, -1, -4,
+ 3, -6, 0, -5, -5, 5, 3, -6, 1, 5, 0, -1, 1, -1, 0, 0,
+ 0, -5, 7, -2, -1, 2, -1, 3, 0, -6, 4, -3, -2, -3, -2, 1,
+ 3, 3, 0, -2, -1, -9, 2, 2, -1, 4, -4, 4, -10, 7, -8, 2,
+ 1, -1, 0, -1, 4, 2, -7, 7, -6, -4, 3, 11, -5, -6, 1, 3,
+ -4, -6, 2, 2, -2, -3, -7, -4, 6, 0, 7, -13, 6, 2, -9, -2,
+ -5, 3, 8, 0, 0, 5, -5, -4, 3, 0, 2, 4, -7, 0, -1, 10,
+ -3, -6, 7, 2, -1, 0, 6, -2, -7, 4, -2, -1, -2, 1, -3, -9,
+ 6, 0, -4, 0, 3, 3, -11, -4, 7, -16, -2, 0, 2, 1, -2, 2,
+ -5, -1, 12, -6, 2, -7, 2, 6, 0, -4, -1, 1, -3, 2, -1, 0,
+ 7, -2, 2, -6, 2, 7, -9, -4, 8, 2, -9, -3, 8, 1, -1, 4,
+ 5, -11, 2, 1, -1, 0, 0, -6, -2, 2, 6, -13, 2, -3, -8, 1,
+ 1, 3, -2, -3, -2, -7, 4, -6, -2, 3, -10, 5, -2, 1, -3, 5,
+ 8, -4, -1, 2, -1, 6, 2, 3, 2, -2, 0, -1, 0, 4, 1, -1,
+ -2, 7, 1, -7, -5, 7, -5, 2, -5, -4, 0, 3, 3, -2, 0, -1,
+ -9, -4, -9, 10, 1, -14, 0, -1, 6, -8, -3, 3, -1, -6, -1, 5,
+ 3, -5, -1, 3, -6, 5, 7, -10, 5, 5, 2, -4, -3, 9, 4, -11,
+ 0, 5, -11, 7, -6, 2, 2, 12, -15, -8, 2, -3, 7, -5, 3, 3,
+ 1, -10, 0, -9, 17, -11, 7, -6, 2, 1, -3, 0, -1, 5, -2, -10,
+ -4, 16, -1, -7, -1, -3, 1, 11, -3, 1, -3, 2, -12, -2, 12, 3,
+ -1, -10, -2, 6, -3, 1, -1, -4, 12, -1, -2, -7, 6, -1, -1, -16,
+ 5, 11, -3, -7, 1, -1, -2, -6, -4, -5, 3, 4, -3, -8, -1, 3,
+ -5, 3, 1, 2, 6, -10, 1, 7, 0, 21, -15, 11, -12, 0, 1, 4,
+ 1, 4, -4, -1, 3, 7, 0, -5, 10, -15, -14, 2, 6, -11, 5, 3,
+ -10, -6, -1, -11, 4, -9, 6, -9, -2, 2, -8, 3, 0, 2, -9, 7,
+ 7, 2, 2, 0, 3, 1, 6, 0, 3, 6, -10, 6, -4, 1, 7, 9,
+ -1, 0, -7, 1, -11, -8, 9, 4, 0, -6, 2, -16, 0, 1, -2, -16,
+ 10, -7, -12, 7, 4, -1, -1, -4, 2, -1, 2, -5, 8, 3, 3, 4,
+ -2, 4, 3, 2, -4, -2, -1, 5, -5, -3, 9, 2, -22, 8, -6, 1,
+ 3, -5, -4, -6, 7, 0, 5, -8, 9, -13, 0, -6, 18, -3, -3, -1,
+ -6, 7, 3, -11, -9, 19, 6, -10, -6, 3, 12, -2, -18, 7, 8, -7,
+ -10, 14, -8, 5, 1, -15, -4, 11, -6, 9, -8, -1, 5, 1, -6, -2,
+ 7, -3, 7, -20, 6, 5, -4, 3, 12, -12, 11, -4, -22, 7, 9, -13,
+ 1, 0, -8, -1, 9, 6, -10, 5, -9, -5, 8, 5, 8, -12, -4, 16,
+ -14, 7, 6, -1, -16, 21, 2, -9, 13, 5, -4, -19, 2, -3, 12, -7,
+ -2, 3, -2, -4, -3, -8, 4, 1, -4, -4, -14, -3, -1, 1, -11, 30,
+ -11, -16, 8, -2, -9, 8, 8, -1, -1, -5, 10, -4, 1, 4, 3, -8,
+ -1, 23, -2, -2, 14, -15, -7, 7, -7, 0, 9, -12, 8, -10, 0, -3,
+ 16, -13, -11, 5, -1, -10, -2, 6, -5, -4, -9, 10, -6, 7, 1, -13,
+ 2, 14, -9, -3, 2, 6, 4, 8, -8, -2, 0, 2, -3, 14, 3, -10,
+ -4, -8, -1, 10, -13, -8, 15, -9, -3, -2, 5, -5, -6, -9, 9, 7,
+ -4, 14, -7, -18, 12, 1, 2, 1, 4, -2, -6, -3, -2, 5, 7, -2,
+ 0, 0, -4, 0, -6, 1, 5, -5, -4, 5, -6, 5, -4, -8, 15, -5,
+ -6, 0, 3, -8, 0, 3, 0, -1, 0, -4, 6, -16, 22, -7, 3, -5,
+ 2, 2, 1, -3, 4, -8, 4, 4, 0, -5, -9, 4, -5, -4, 3, 2,
+ 1, 3, -4, 6, -15, -1, 4, 1, -9, 3, 1, -8, 3, -6, 11, -5,
+ 6, -11, 17, -15, -2, -19, -11, 1, -4, 8, 0, 5, 18, -11, 0, 13,
+ -4, 6, -13, 4, -11, -1, -7, -7, 11, 10, -9, 17, -11, 20, -6, 7,
+ -14, 23, -7, -2, -2, 7, -10, 2, 0, 2, 5, 6, -8, 5, -4, -10,
+ 9, -4, 6, 0, -7, 8, -7, 1, -20, -4, -1, -3, 6, -10, -6, -15,
+ -11, 10, -5, 19, 3, 1, -19, -11, -1, -9, 9, 22, 24, 10, -5, -18,
+ -8, -23, 14, 11, 0, 31, 43, -9, 0, -7, -15, -28, -35, -30, 3, 5,
+ -5, 11, 52, 55, 7, -5, -10, -12, -25, -43, -12, 4, -37, -47, -21, -5,
+ 4, -11, 1, 31, 27, 34, 46, 48, 61, 10, 16, 8, 7, -14, -40, -47,
+ -36, -51, -42, -15, 4, 12, -32, -42, -10, -4, 10, 1, 15, 50, 31, 5,
+ 15, 38, 37, 29, 15, 22, 11, -4, -35, 10, 3, -18, 1, -14, -33, -5,
+ -47, -25, -13, -2, 15, -6, 5, -29, -17, -19, -1, 3, 7, 2, 17, 28,
+ -8, -23, 7, 7, 36, 15, 2, 1, -2, -9, 1, 6, 20, 6, 14, -3,
+ 21, -11, -12, -35, 11, -20, -18, -36, -23, -27, -19, 1, 10, 14, 27, 6,
+ 44, 14, -9, 3, 20, 27, 45, -8, -13, 16, -16, 24, -10, -9, -3, -38,
+ -19, -14, -38, -38, -41, 13, 40, -37, 5, -7, -7, -4, 4, -31, 32, 22,
+ 15, 9, 13, 10, 10, -17, 22, 30, 9, -6, 27, 66, 47, -17, -21, -20,
+ -9, -36, -73, -3, 22, -35, -12, 6, 7, 4, -17, -45, 22, 17, -17, 3,
+ -9, -4, 11, -10, 13, -4, 8, 38, 3, 20, 42, -22, 9, 23, -28, -21,
+ 3, 10, 1, 26, -28, -18, -9, 7, -30, -41, -24, -9, 10, -6, 31, -5,
+ 2, 29, -9, 1, -27, -24, 7, -19, -5, 10, -13, 21, 21, 3, 30, -11,
+ -17, 34, -11, 8, 7, -8, 1, 11, -1, 7, -13, 1, -3, 23, -12, 8,
+ -19, -3, 20, -78, 42, -23, 4, -29, -16, -5, 38, -49, 30, -26, 26, 16,
+ 8, -33, 53, 19, -20, 12, 5, 23, -11, 4, -6, 42, -111, 67, -40, 29,
+ -32, -20, -77, 113, -46, -12, 8, -5, -14, 35, -52, 94, -5, -61, 58, -36,
+ 41, -83, 21, -19, 61, -68, 37, -37, 12, 66, -69, -16, 100, -88, 48, 21,
+ -39, 73, -24, -2, 45, 65, -59, 53, -103, 95, -97, 1, -14, -4, -41, 9,
+ -13, -18, 16, -26, 9, 26, -15, 25, -16, 6, 8, 26, -52, 35, -21, 4,
+ -2, -11, -4, 22, 0, 21, -40, 65, -6, -13, -11, -7, 32, -46, -48, 16,
+ -26, -3, 0, -42, 87, -68, 34, 17, -14, 43, 23, -15, 30, 20, 47, -19,
+ -33, -12, 15, 1, -37, 15, -12, -11, -7, 15, -75, 36, -41, 27, -8, -7,
+ -12, 10, -4, 49, -6, 42, -32, 4, 20, 33, -65, 24, -52, 10, 13, -17,
+ -15, 60, -14, -55, 35, -16, 50, -83, -3, 29, 58, -75, 71, -46, 47, -32,
+ 44, -57, 10, -43, 33, 22, -48, 51, -41, 6, 7, 39, -3, -41, 7, -9,
+ 37, -66, 22, 26, -13, 74, -87, 127, -39, -16, -29, -11, -8, -57, -15, -45,
+ 52, -74, -5, -2, 103, -126, 85, 20, 28, -7, 53, -38, 58, -10, -11, 33,
+ -70, 20, 1, 40, -36, 26, -58, 58, -23, 61, -71, -7, -39, 43, 22, -18,
+ -1, -61, 90, -37, 35, -58, 30, -62, 27, -45, 47, -59, -6, -35, 70, -49,
+ 9, -30, 92, -15, 21, 1, 26, 6, -19, 90, -43, 49, -46, 10, 6, 15,
+ -90, 67, -51, -11, 4, 28, -36, 24, 41, -68, 24, -34, 63, -40, 17, -30,
+ 18, -39, 14, -38, 15, 9, -54, 54, -20, 36, -21, -14, -13, 11, 23, 11,
+ -54, 56, -25, 37, -46, 49, -74, 81, -40, 51, -44, 57, -69, 51, -50, 61,
+ 27, -112, 111, -114, 106, -85, 49, -61, 75, -18, 26, -68, 32, -15, -25, 21,
+ -15, 38, -46, 80, -119, 126, -85, 41, -40, 77, -65, 28, -6, -39, 45, -87,
+ 39, -63, 81, -32, 4, -32, 44, -25, 42, -12, -15, 21, -1, -56, 21, 23,
+ -30, 33, -28, -3, 32, 4, -36, 60, -20, 13, -3, 22, -43, 101, -88, 59,
+ -53, 18, 8, 22, -33, -52, 34, -32, 35, -90, 112, -107, 56, -59, 43, -60,
+ -18, -4, -21, 45, 11, -48, 11, 38, -27, 58, -49, 65, 19, 54, -38, 35,
+ -37, 24, -11, 44, -62, 41, -16, -48, -8, 31, -68, 17, -3, -5, 52, -51,
+ -10, 16, -26, 18, -29, 56, -41, 3, 5, -10, -37, 61, -14, -10, -9, 20,
+ -8, 8, -2, -16, 44, -17, 14, -33, 30, -2, -27, 16, 3, 0, 51, -42,
+ 32, -20, 8, -11, -24, 10, 12, -15, 6, -32, 10, 21, -38, -11, -12, 23,
+ 13, -64, 19, 34, -23, -23, 16, 10, 39, 2, -36, 55, -31, 0, -29, 18,
+ 8, 12, -61, 73, -28, 54, -34, 21, 9, 7, 53, -34, -29, 19, -7, -44,
+ 7, 15, -16, -18, -31, 10, -29, 36, -69, 7, 4, 33, -72, 45, 14, 0,
+ -8, 35, -13, 26, 16, -28, -3, -32, 45, -4, 8, -20, 65, -24, 2, -24,
+ 40, -16, -16, 20, 8, 2, -3, -2, 23, -15, -11, -30, 19, -51, -19, -5,
+ -36, 18, 24, -4, -1, 46, -90, 60, 4, 23, -17, 16, 60, -24, 0, 18,
+ 0, 5, -6, -24, 27, -34, -28, -7, -4, 22, -30, -11, -3, -1, -44, 36,
+ -38, -6, -9, 55, -34, 16, 27, 28, -65, 62, 22, -32, 36, 7, 2, 27,
+ -19, 50, -71, 44, -19, -67, 13, -3, -14, -30, 33, 5, -12, -48, 60, -47,
+ -28, 9, -6, 24, -11, -1, 13, 62, -53, 26, 7, -9, 6, 58, -38, -10,
+ 0, 5, -23, 23, 8, -14, -19, 21, -9, 35, -17, -28, 14, 27, -17, -14,
+ -29, 24, 6, -85, 74, -16, -18, -2, -19, 47, -29, -18, -15, 52, 0, 7,
+ -10, -23, 45, 13, -11, 12, -28, 27, -26, 19, -69, 74, -55, 35, -21, 41,
+ -24, -11, 39, -19, 7, 0, 7, -31, 10, 7, -45, -17, 25, -12, 9, -19,
+ 3, 28, -53, 76, -19, -25, 49, -2, 6, -11, 24, -12, -23, 17, -1, -15,
+ -10, -36, 26, -25, 0, -44, 59, -67, 45, -31, 5, 15, 56, -12, -14, 12,
+ 10, 24, -52, 37, 5, -35, 52, 23, -55, -6, 24, -49, 26, 31, -24, 10,
+ -33, 33, -11, 1, -49, 8, 7, 6, -78, 12, -22, 10, -11, 13, 13, -18,
+ 38, 50, -18, -5, 64, -52, 59, 33, 3, -9, -6, -6, 26, -64, 18, -38,
+ -47, 18, -33, 4, -39, 40, -31, -1, -23, 48, -30, 18, 17, 32, -20, 32,
+ 19, 24, -58, 49, -38, -9, 15, -28, 16, -3, -2, -28, 33, -22, 23, -1,
+ -34, 33, -48, 67, -55, 21, 51, -66, -2, 21, -5, -17, 24, -63, 53, 8,
+ -19, 9, -11, 36, -37, -35, 43, -35, -3, -44, 68, -43, 53, -24, -5, 45,
+ -16, -7, 14, 49, 3, -16, 22, -10, 2, -28, -9, -6, -5, 32, -76, -22,
+ 35, -26, -35, -12, 0, 3, 13, 6, 36, 7, -32, 69, -15, 45, -20, -21,
+ 35, 35, 1, -25, 11, 34, -24, -33, -9, 5, -25, -49, 31, -41, 15, -42,
+ 25, -30, 42, -80, 32, 2, -18, 33, -12, -9, 43, -1, 4, -12, 54, -51,
+ 22, -1, 18, 28, -29, 18, 7, 10, -19, 8, -1, 12, -21, -6, -11, 4,
+ 4, -28, -8, 22, -27, -5, 9, -25, 20, -19, -36, 41, -8, 20, -32, 16,
+ -29, 29, -13, 13, 4, 1, 17, 8, 0, 9, 22, -1, -3, 28, -11, -39,
+ 36, -31, 5, -11, -27, 22, -39, 7, 15, -24, 19, 8, -37, 75, -52, 54,
+ -65, 22, -13, 23, -26, 32, -19, 10, -8, -3, 12, 16, -44, 25, -23, 14,
+ 9, -46, 20, 2, -4, -8, -6, 18, 4, -2, -3, -15, 4, 16, -9, -5,
+ 34, -29, 27, -54, 98, -65, 11, -18, 16, -13, 0, -2, 0, 22, -43, 31,
+ -46, 58, 2, -25, -2, 16, -2, -29, 17, 18, -26, 21, -17, 5, -4, -9,
+ 0, -34, 50, -27, -3, 4, 31, -3, -47, 32, -25, 36, 6, -47, 33, -28,
+ 39, -36, 42, -28, 5, -3, -2, 25, 27, -47, 20, 22, -5, -15, 1, -9,
+ 16, -25, -10, -43, 40, -12, -19, 22, -24, -5, 14, -44, 42, -32, 32, -45,
+ 40, 41, -17, 27, -44, 38, -16, 15, -36, 39, -13, -19, -4, 34, 1, -9,
+ 9, -16, -2, -29, 31, -31, -4, 35, -21, -52, 63, -41, 2, -7, 30, -35,
+ 13, 9, 15, -4, 14, -36, 18, -14, 55, -50, -6, 22, -23, -11, -5, 12,
+ 17, -13, -43, 44, -33, 41, -42, 45, 3, -12, 26, 11, -11, 35, -76, 39,
+ 2, 0, 3, -4, 15, -19, -6, -33, 11, 5, 16, -25, -2, 19, -7, -43,
+ 30, 20, -27, -18, 12, 14, 33, -50, 14, -15, 23, 8, 2, -10, -4, 53,
+ -86, 24, -9, 41, -34, -21, 22, 24, -54, 27, 13, 2, -9, 14, -29, 21,
+ 40, -43, -9, -3, 27, -3, -22, 18, 10, -23, -15, 1, 14, -12, 3, -30,
+ 30, -22, -28, 36, -15, 39, -57, 21, 3, -3, 33, -13, -2, 6, 20, -6,
+ 4, -13, -5, -18, 13, -7, 7, 26, -26, 16, 7, -64, 37, -7, 10, -20,
+ 12, -11, 7, -34, 37, -12, -24, 34, -18, -18, 39, 9, -42, -24, 43, 2,
+ -16, 25, 12, -16, 8, 12, -44, 32, -9, 23, 1, -37, 40, -23, -17, 18,
+ -42, 23, -12, -7, 10, -6, 6, -13, -13, 30, -23, 36, -4, 7, 17, -18,
+ 18, -3, 8, 5, -1, -13, -15, 2, -5, -16, 7, -52, 23, -38, 30, -30,
+ 16, -26, 21, -22, 24, 3, 20, -28, 22, 22, -31, 42, -16, -11, 32, -26,
+ 0, 31, -14, 11, -15, 14, -17, -9, 10, 11, 27, -38, -4, 14, -18, 36,
+ -44, 0, -11, 16, -14, -2, 16, -34, -23, 22, 4, -24, 14, -13, 16, 31,
+ -28, -10, -6, 51, -27, 13, -49, 3, 68, -38, 1, 8, -27, 26, -16, 0,
+ 15, -36, 7, -6, 38, -11, 0, -14, 10, -4, 22, -48, 31, -1, 23, -38,
+ 1, 15, -7, 10, -1, -3, 4, -1, 10, -2, -12, 3, -22, 5, 9, 8,
+ 4, -14, 12, -3, -7, 22, -20, 3, -6, 13, -15, -8, -7, 16, -14, -1,
+ -3, 6, -17, 12, 22, -44, 68, -67, 50, 13, -20, -11, -4, -20, -3, 22,
+ -13, -20, 28, -7, 2, 11, -9, -23, 5, 5, -26, 24, -31, 2, 20, 15,
+ 2, -7, 4, 19, -6, 41, -51, -3, 24, 27, -30, 25, -37, 1, -7, -2,
+ -4, -26, -1, 12, 5, -12, 9, -30, 5, 11, 26, -18, -32, 42, 7, 0,
+ -23, 10, 10, -20, 53, -49, 6, -39, 18, 3, -27, 41, -21, 16, 28, 14,
+ -24, -15, 19, 5, 16, -31, -1, 45, -25, -6, -16, -4, -19, 37, -47, 21,
+ 2, -14, -7, 30, -35, 13, -30, 14, 21, 11, -18, -28, 37, 12, -18, 9,
+ 5, -1, 33, -41, 3, -7, -19, 8, -14, 12, 15, -18, -4, 44, -25, 22,
+ -46, 19, 40, -25, -12, -5, 17, 7, -53, 25, 4, -10, 14, 16, -31, 40,
+ -27, -11, -4, 28, -40, -5, -9, -3, 34, -47, 33, -5, 11, -33, 33, 0,
+ -14, 35, -18, -27, 11, 14, -37, 35, -20, 7, 15, 2, 27, -17, 15, -31,
+ -1, 11, -27, 24, -26, 14, 13, -35, 20, -13, -2, 16, 16, -6, 2, 15,
+ -7, -22, 51, -36, -2, 20, -19, 23, -20, -19, -9, -14, 8, -4, -13, 35,
+ -66, 36, -37, 3, 19, -1, 15, 32, -45, 71, -15, -5, 12, 34, -33, 24,
+ -5, 20, -43, 42, -59, 13, -12, -69, 66, -29, -34, 17, 7, -28, 24, 5,
+ -27, 51, -40, -9, 46, 3, -17, 36, -56, 63, -7, -31, -19, 53, -12, -10,
+ 4, 19, -47, 35, 0, -40, 17, -14, 13, -11, 11, 3, -39, 22, 5, 21,
+ -19, -11, 25, -4, -5, 20, -13, 25, -6, -16, -16, 29, -61, 25, -33, 12,
+ -17, 7, -19, 34, -27, 15, -19, 32, -26, 54, -46, 6, 9, 14, -6, -6,
+ 23, -32, 58, -19, -5, 15, 46, -42, 39, -7, -23, -7, -14, -22, 42, -66,
+ 0, 4, -8, -11, -4, -3, -7, 7, -23, 30, -14, 19, 8, -9, 20, 36,
+ 5, -24, 25, 12, -20, 16, -53, 60, -49, -26, 24, -87, 67, -49, 13, -7,
+ 5, -14, 5, 11, 38, -3, -15, 27, 26, -36, 20, 30, -47, 29, -5, 9,
+ -10, 38, -65, 47, -49, -4, -10, -6, 1, -1, -28, 16, -14, 3, -14, 27,
+ -8, 1, 2, 23, 21, -53, 40, 24, -16, -12, -2, 11, 17, -8, -18, 8,
+ -25, 28, -10, -12, 13, -51, 10, 35, -10, -8, -9, 8, 10, 14, -20, 4,
+ -9, 37, -5, -2, 2, 4, -9, -5, 16, -16, -23, 13, 7, -9, 14, -49,
+ 13, 8, -3, -13, -9, 22, -8, 12, -13, 36, -36, 35, -17, 23, -12, 0,
+ -37, 50, -31, -8, -31, 43, -4, -11, 0, 3, -7, -19, 16, -16, -28, 46,
+ -28, 27, -13, 33, -21, -1, 39, -13, 3, -4, 4, -39, 74, -30, -17, 33,
+ -3, -20, -12, 24, -94, 75, -63, 54, -62, 23, 4, 12, -33, 22, -35, 16,
+ 12, -28, 34, 2, -12, -3, 22, 23, -31, -6, 26, 4, -41, 8, 37, -15,
+ 21, -7, 18, -51, 42, -27, 35, -45, 35, -30, 18, 9, -20, 1, 18, -12,
+ -51, 61, -61, 24, -20, 1, 11, -5, -2, -12, 11, 20, -35, -2, 37, -21,
+ 23, -15, -2, 19, -51, 82, -50, 20, 29, -26, -34, 49, -2, -16, 11, -17,
+ -4, 6, 15, -35, 13, -15, -10, -17, 15, 4, -42, 43, -31, 34, -30, 53,
+ -43, 40, -22, 9, 9, -24, 64, -41, 29, -17, 8, -15, 8, 2, -27, 7,
+ 10, -28, 0, 30, -50, 6, -13, -14, -21, 11, 9, 13, -47, 35, -11, 32,
+ 28, -28, 1, 32, 2, -19, 28, -24, 9, 0, 19, -6, 16, -33, 6, -23,
+ 33, -31, -1, -4, 26, -22, -22, -10, -11, 18, -26, 19, -8, -4, 21, -14,
+ 36, -2, 12, -48, 49, -1, -13, -5, 8, -3, 9, -4, -18, 15, 28, -50,
+ 10, 4, -7, 4, -39, 37, -39, 11, 2, -20, 13, 4, -6, 0, 35, -17,
+ -9, 6, 38, -21, -1, -1, 12, -2, -16, 15, 7, -22, 18, -23, 11, 3,
+ -9, -39, 29, -31, 44, -41, 0, 5, 21, -9, -25, 25, -6, 38, -55, 38,
+ -14, 6, -26, 38, -24, 39, -39, -15, 17, 16, -20, -27, 17, 24, -20, -20,
+ 33, 8, -31, 2, 2, 27, 11, -4, -7, 31, -20, -9, 4, -4, 17, -32,
+ 2, -18, 31, -35, 38, -52, 42, -1, -28, -26, 25, 3, -51, 42, -35, 35,
+ -39, 44, -38, 20, 20, -51, 34, 45, -10, -7, 27, -19, 33, -49, 22, 2,
+ -7, -5, -27, 59, -24, -20, 21, -8, -15, 24, -51, 3, 9, -23, 24, -30,
+ 2, 29, -26, -2, 4, 10, 0, -18, 50, 3, 9, -14, 17, -18, 24, -13,
+ -33, 7, 25, -50, 2, -2, 30, -58, 31, -8, 23, -11, -1, -24, 21, 1,
+ -41, 47, -30, 28, -39, 56, -16, -20, 51, -45, 33, 6, 23, -12, -19, -2,
+ 7, 1, -14, -5, -11, -20, 25, -17, 7, -22, 21, -19, 34, -47, -2, 1,
+ 33, -30, 14, 20, 6, -9, 17, 13, -22, 19, -58, 23, 26, -15, -52, 2,
+ 18, 10, -13, 46, -5, -8, -6, 4, -14, 5, 11, -13, -7, 42, -25, 8,
+ -37, 35, -10, 6, -25, 16, 15, -15, -9, -20, 18, -23, 26, -34, 35, -22,
+ -10, 9, 14, -6, -21, 27, -8, 4, 1, 3, -19, 28, 2, -7, 30, -8,
+ -13, 11, -9, -9, -19, 12, 0, -23, -1, -23, -6, 27, -31, 41, -28, 13,
+ 5, 9, -21, 6, 2, -2, 18, -16, 31, -25, 40, -38, 39, -13, 8, 14,
+ -3, 9, -30, 6, -12, -7, -15, 30, -64, 6, -22, 13, -8, 14, -40, 9,
+ 32, -35, 14, -1, 12, -25, 63, -25, 35, -2, 19, -5, -3, 20, -29, -1,
+ 35, -37, 53, -46, 4, -14, 22, -27, 23, -64, 8, 5, -25, 41, -18, 14,
+ -42, 53, -56, 35, -42, 71, -63, 45, -38, 29, -12, 33, -22, 0, 24, -13,
+ 3, 13, 1, -10, -19, 11, 19, -38, 5, -2, -18, -21, 33, -54, 41, 9,
+ 4, -1, -21, 3, 3, 37, -31, 34, -40, 34, -19, 30, -26, 23, -53, 55,
+ -8, -13, -16, 7, -13, 46, -38, 2, -3, 17, -1, -26, 18, -57, 68, -27,
+ 23, -19, 32, -39, 2, 2, -18, 12, -16, 4, -23, 38, -65, 40, -5, 13,
+ 19, -26, -13, 60, -25, 7, 1, 10, 22, -24, 23, -20, -16, -17, 14, -32,
+ 26, -4, 17, -15, 9, -29, 4, -29, 11, 36, -18, -19, -2, 5, 28, -23,
+ 31, 6, 4, 18, -14, 4, -7, 0, -45, 61, -31, 5, -15, -23, -21, 52,
+ -62, 4, 22, 1, -9, 15, -24, -27, 60, -49, 38, 0, -6, 1, 13, 7,
+ 4, 19, 6, 0, 27, -28, -14, -21, 17, -1, -30, 23, 10, -36, 18, -19,
+ 2, -18, 0, 6, -1, 7, -1, -37, 26, 15, -35, 41, -24, 10, 10, -9,
+ -12, 12, 7, 3, 10, -11, 11, -14, 27, -49, 71, -55, 25, 8, -11, 11,
+ -5, -22, 7, 15, -17, -11, 18, 4, -54, 43, -38, 27, -1, 7, -13, 19,
+ 10, -41, 50, -41, 13, 9, 10, -41, 38, -13, 13, -2, -2, -4, 9, -36,
+ -5, 22, -31, -18, 8, 21, -22, 21, -24, 12, 3, 16, -24, 25, -16, 22,
+ -35, 14, 3, 11, 12, -22, 40, -11, -25, 14, 0, 14, -2, 2, -10, -12,
+ 14, -51, 11, -21, 55, -27, 9, 3, 38, 7, -25, 5, -19, 6, -14, 0,
+ -10, 21, -57, 35, 18, -21, 21, -40, -13, 24, -24, -12, 10, -1, 11, 10,
+ -12, -5, 38, -45, 23, 26, -13, -9, 32, 6, -3, 30, -28, -28, 27, 3,
+ -10, -11, -10, 16, -28, 21, -12, -3, -1, -33, 14, -30, 12, -20, 40, -15,
+ 7, 19, -18, -1, -1, 9, 4, -23, 32, 17, -19, 12, 16, -45, 4, -6,
+ 18, -28, 36, -44, 44, -29, 10, 4, 14, -8, -13, 9, -30, 39, -17, -5,
+ 10, -10, 5, -1, -16, 17, -7, -9, -10, 15, -21, 9, 10, 8, -10, -6,
+ 3, -21, 34, -3, 6, -4, 15, 3, -2, 4, 26, -44, 30, -43, 2, 9,
+ -5, -7, -18, 16, -28, 0, 5, -7, 0, 7, 0, -7, 21, -14, 17, 15,
+ 2, -40, 7, 44, -30, 55, -33, -19, 40, -30, 17, -1, -20, -20, -20, 5,
+ 14, 1, -7, -32, 26, -11, -11, 24, -23, 17, 17, 8, -19, 18, 11, -6,
+ 17, -4, -13, 14, -9, 21, 9, -16, -8, 2, -16, 3, -9, -32, 6, -36,
+ -4, 0, 10, -36, 26, -11, 3, 31, -20, 1, 7, 4, 45, -35, 39, 0,
+ 4, 28, -21, 29, -39, 27, 15, -6, -14, 17, -25, -33, 16, -15, 18, -43,
+ 28, -61, 33, 1, -27, 13, -19, -20, 26, 11, -27, 16, -21, 33, -13, 43,
+ -44, 13, 24, -10, 35, -39, 36, 20, -39, 68, -68, 23, -16, -7, 0, 36,
+ -30, -13, -27, 42, -21, -4, -23, -2, 23, 0, -3, -3, 2, 4, -15, -5,
+ 28, -10, -20, 24, -7, 27, -58, 31, -7, -29, 39, -40, 41, -35, 8, -25,
+ 30, 31, -17, -9, 3, 36, -8, -18, -11, 29, -2, 6, -25, 21, -5, -8,
+ -17, -24, 20, -26, 20, -23, 46, -26, -13, 8, 13, 2, -15, 4, -9, 28,
+ -25, -19, 49, 18, -50, 45, -11, -17, 5, -61, 15, 4, -22, -1, 22, 23,
+ 33, -55, 46, -25, 37, 18, 2, -9, 11, -47, 23, -8, -25, 37, -32, 2,
+ 5, 12, -18, -5, 19, -27, -7, 20, -40, 32, -44, -21, -29, 58, 8, -9,
+ 57, -28, 29, -32, 14, -14, 4, 23, -33, 16, -4, -16, 21, 38, -37, 23,
+ 10, -32, 17, 17, -12, -59, 9, -3, -12, 22, -13, -8, -26, 16, 1, 33,
+ -9, -17, 16, -7, 21, -44, 26, 5, 35, -36, -1, 13, 36, -36, 39, -36,
+ 17, -13, 2, -33, 20, -13, -51, -2, 9, -2, 35, -21, 19, -20, 18, -19,
+ -5, 30, -39, 30, 22, -35, 74, -52, 33, -15, 17, -21, -13, 11, 6, -25,
+ 25, -31, 29, -18, 18, -52, 40, -11, -17, -26, 56, -56, 69, -53, -14, 32,
+ -10, -8, -2, 18, -14, 20, -18, 20, 22, -27, 0, -25, 56, -46, 16, -28,
+ 52, -5, -33, 76, -75, 36, -1, -42, 42, -46, 13, -13, 25, -7, 35, -55,
+ 5, 63, -56, 11, -24, 13, -8, -10, -27, 15, -15, 44, -66, 52, -3, -6,
+ 0, 23, -33, 79, -55, 30, -27, 37, -18, -6, -2, -19, 52, -22, -50, 60,
+ -32, 28, -56, 44, -28, 15, -37, -9, -28, 63, -75, 9, 39, 28, -21, 5,
+ -17, 15, 2, -13, 30, 13, -14, 10, -12, 30, -22, -10, 4, -8, -9, 14,
+ 6, -39, 34, -6, 4, 1, -5, 0, 33, -73, 34, -12, 23, -9, 53, -47,
+ 17, 3, -18, -6, 2, -19, -12, -7, -45, 72, -9, -71, 55, -58, 50, -18,
+ -36, 37, 19, -11, 13, -35, 32, 6, 5, 18, -6, 19, -26, 32, 16, 20,
+ -43, 20, -10, -7, 16, -7, -68, 21, -36, 7, 19, -22, 19, -3, -35, -37,
+ 25, 21, -57, 67, -9, 9, 32, -11, 28, -18, 35, -41, 60, -19, 29, 0,
+ -38, 29, -6, -35, 0, 25, -37, -1, -31, -42, 30, -19, -21, 36, -66, 53,
+ -33, 15, 16, -13, 20, -35, 73, -4, 18, 39, 4, 1, 3, 21, -2, -12,
+ -18, -51, 44, -17, -50, 48, -30, -16, -13, -35, -7, 25, -33, -14, 14, 0,
+ 8, -30, 45, -13, 50, -53, 28, 60, -33, 23, -7, -2, 15, 36, -11, 9,
+ 19, -44, 4, -21, 19, -5, -27, -45, 48, 9, -47, -23, 12, 3, -25, -8,
+ -21, 63, 1, -29, 31, -18, 19, 16, -24, -17, 50, -65, 65, -56, 93, -45,
+ -17, -25, 45, -18, 23, -53, 50, -15, -12, -39, 51, -11, 11, 13, -31, 54,
+ -14, -29, 22, -11, 10, -41, -19, 52, 10, -51, -60, 72, -13, 12, -38, 19,
+ -2, 31, -56, 37, -4, -10, 22, -14, -33, 48, -40, 38, -14, 27, -24, 19,
+ 29, 17, -31, -2, -41, 34, -17, 2, 5, 5, -13, -30, 14, 9, -9, 7,
+ -11, 15, 5, -28, -2, 0, 45, -30, -25, 1, 10, 29, -55, -24, 52, -5,
+ 5, 20, -25, 20, -15, 14, -64, 95, -53, 32, 13, -26, 31, -8, -27, 18,
+ 48, -57, -3, -10, 25, -24, -32, -9, 18, 18, -33, -15, 27, -22, 14, -5,
+ 10, 51, -21, -25, 19, 5, -15, -29, 16, 1, 33, -39, -12, 56, 14, -63,
+ 36, -2, -17, 52, -11, -37, 5, 19, -52, 38, -23, -60, 93, -75, 52, -30,
+ -2, -11, 49, -11, -25, 1, 42, -35, 26, -35, -9, 24, -1, 10, -6, -12,
+ 7, 4, 22, -10, 41, -25, -8, -4, -2, 28, -43, 19, -32, 4, -27, 9,
+ -47, 51, -16, 12, -52, 49, 8, 7, -37, 27, -33, 80, -44, 6, 5, 28,
+ -15, 16, 15, 2, -12, 50, -77, 38, -38, -45, 30, 8, -37, -13, -8, -18,
+ 50, 3, -54, 29, 29, -20, 4, 52, -57, 62, -52, -2, -9, 62, -64, -5,
+ 24, 23, 0, -7, -23, 48, 25, -78, -9, 38, 18, -46, 30, -51, 39, 4,
+ -48, 22, 15, 13, -39, 8, 10, 31, -20, -22, 21, -17, 17, -23, 22, 22,
+ -24, -36, 11, 31, -16, -28, 34, -4, 0, -20, 6, -2, 35, -13, -60, 36,
+ 24, -45, 21, -2, 36, 0, -73, 66, -37, 39, -66, -18, 22, 17, -17, -25,
+ 24, 36, -47, 3, 25, 7, 8, 0, 1, 14, 20, -21, 4, 21, 12, -77,
+ 17, -4, -12, 31, -57, 38, -11, -4, -31, -6, 29, -34, 11, 13, -20, 82,
+ -36, -36, 40, -28, 77, -68, 12, 2, 34, -23, 5, -31, 11, -5, 44, -105,
+ 79, -31, -29, -16, 37, 8, 18, -14, -9, 32, -10, -11, -7, 0, 41, 34,
+ -56, 7, 13, -2, -31, 33, -67, 42, -31, -2, 22, -49, 18, -34, -11, 38,
+ -40, 56, -16, 14, -2, 24, 0, 0, 41, -21, -8, 6, -11, 11, 11, -45,
+ 26, 4, -17, -7, -26, -30, 7, -21, -29, 56, -29, 37, -3, 2, -8, -3,
+ 22, 11, 40, -13, 58, -6, -38, 48, -23, 15, -52, -14, -6, 49, -66, -20,
+ -11, 34, -32, -44, 41, 4, 20, -59, -24, 77, 23, -24, -17, 42, 19, -3,
+ -19, -34, 54, 17, -22, -17, 46, -24, -9, 3, -22, 40, -47, -49, 72, 4,
+ -18, -48, -33, 55, -4, -41, -51, 105, -26, -3, -22, 64, 28, -51, 31, 2,
+ 15, 27, -62, 18, 21, 6, -15, -54, 52, -14, -46, 7, -30, 32, -1, 6,
+ -37, 39, -3, -23, -20, 24, 23, 17, -25, -6, 67, -36, -11, -37, 56, -79,
+ 3, 30, 45, -39, -17, -2, 21, 2, -4, -3, 3, 1, 16, -16, 9, 30,
+ -37, 8, -6, 46, -65, 3, 14, -59, 104, -60, 2, 46, -29, -30, -2, -10,
+ 24, -52, 63, -31, 81, -85, 18, 35, 16, -32, -18, -24, 45, -16, -15, -13,
+ 37, -15, -20, -42, 91, -45, -15, -9, -16, 64, -11, -23, 31, -18, 38, -42,
+ 3, 12, 1, 5, -5, 22, -44, 69, -31, -18, 15, 21, -64, -13, 34, -37,
+ 30, -26, -15, 6, -3, 44, -28, 11, -3, -1, 16, -18, 25, -14, -26, 69,
+ -56, -5, 31, -51, 24, 3, -36, 9, 52, -34, 31, 21, -11, -68, 31, -24,
+ 53, -25, -29, 31, 23, -20, 9, -15, -11, 19, 12, -47, 84, -60, -16, -11,
+ 17, -4, -15, 30, -45, 32, 34, -63, -7, 68, 0, -35, 17, 7, 33, -31,
+ -8, 7, -32, 43, -13, -18, 15, 31, -32, -34, 5, 8, -16, 20, -26, -29,
+ 32, -9, -20, 17, 33, -31, -13, -5, 86, -52, 23, -19, 2, 13, 14, -7,
+ -20, 36, -16, -3, 8, 0, 14, -69, 76, -77, 25, -14, -17, 3, 39, -14,
+ -46, 31, -2, -7, 37, -45, -6, 24, 28, -37, 22, 13, -35, 4, 8, 23,
+ 7, -43, 53, -59, 23, 16, 4, -25, -15, 23, -9, -20, 26, -18, -1, 25,
+ -3, -48, 53, 2, -43, 7, 14, -34, 15, 28, -33, 53, -2, -59, 31, -34,
+ 40, 19, -27, 20, -2, 8, 2, 3, -8, -8, 4, -57, 62, 24, -72, -4,
+ 17, -17, -3, -10, -26, 42, -30, 12, -29, 31, -10, 3, 24, 2, 21, -1,
+ -36, 52, -7, 21, 14, -32, -18, 73, -45, -6, 8, -12, -66, 21, 25, -17,
+ -6, -35, -14, 27, 26, -47, 40, -51, 56, -19, -24, 31, 6, 4, 11, -3,
+ 37, -47, 41, -32, 50, 0, -72, 25, 16, -19, -1, -2, -4, -41, 20, 6,
+ 9, -3, -44, 32, -54, 83, -30, -26, -8, 46, -47, 29, 5, -19, 37, -9,
+ -20, 65, -14, -21, -4, 10, 28, -28, 18, -29, 35, -25, 3, -17, -31, 4,
+ -4, 0, -9, 41, -42, -34, 40, -15, 8, -24, -8, 36, 22, -18, -27, 70,
+ -39, 39, 1, -5, 57, -54, 12, 36, 3, -13, -1, -32, 69, 6, -64, -50,
+ 13, -13, -34, 22, -13, 0, -10, -38, 41, -11, -22, -3, 11, 4, 38, 22,
+ -10, 24, 32, -23, 23, -6, 8, -4, 21, -61, 66, -35, -41, 7, 5, -29,
+ -19, -45, 23, -2, 46, -84, 78, -59, 40, -10, -18, 79, -35, -5, -1, 36,
+ 16, 13, -21, -31, 52, 2, -50, 34, -5, -36, -37, 65, -42, 1, 16, -42,
+ 35, -8, -50, -6, 41, -16, 27, -41, 22, 64, -50, -11, 31, -18, -17, 5,
+ -3, 34, 34, -40, -41, 66, -37, 20, -11, -20, 29, -5, -14, -15, 45, -33,
+ -37, -11, 36, -25, 18, -8, 20, 1, -23, 60, -32, 0, 34, -24, -32, 64,
+ -39, -35, 48, -7, -13, 4, -39, 32, 0, 1, -31, 2, -12, 43, -38, -8,
+ 26, 0, -57, 53, 19, -22, -10, 17, -30, 57, 6, -31, 33, 10, 0, -48,
+ 29, -4, -23, 6, -7, 31, -39, 15, -41, 38, -19, 5, -37, 23, 11, -28,
+ -14, 59, -48, 8, 22, -20, 50, 15, -34, -26, 67, -8, -15, -21, 53, -27,
+ -9, 13, -24, -35, -10, 9, -15, -13, 18, -38, 28, 22, -14, 2, -22, 42,
+ -20, 22, 12, -20, 45, -16, 17, -16, 22, 34, -27, -13, -7, 1, -21, -1,
+ 13, -44, 36, -51, -8, 16, -7, -30, -46, 90, -54, 35, 1, 11, 9, 5,
+ 1, -19, 20, 11, 21, -1, -49, 41, -6, 0, 37, -74, 9, 20, -12, -47,
+ 65, -68, 28, -5, -26, 15, 14, -3, -23, 8, 18, -22, 13, 3, 31, -21,
+ -5, 8, 24, -21, 48, -20, -21, 41, -43, 4, 18, 21, -60, 9, -27, 1,
+ 13, -15, -33, 15, 23, -48, -8, 53, -50, 1, 6, -40, 90, -10, -15, 51,
+ -52, 53, 29, -68, 50, 52, -30, -21, 7, -1, -8, -29, 11, -47, 6, 18,
+ -12, -25, 53, -34, -23, -6, 19, -7, -13, 7, 5, -2, 14, 11, -15, 51,
+ -29, 6, 12, 20, -27, 29, -12, 4, -18, -5, 2, -17, 10, -19, 2, -8,
+ -5, 56, -82, 49, 0, -42, 48, -25, 19, 6, -41, 17, 35, -18, -17, -29,
+ 26, 10, 4, -24, 26, -35, 47, -36, 2, 2, -23, 27, -42, 55, 0, -21,
+ 19, 21, -8, 1, -3, -15, 7, 12, -23, -29, 47, -12, 4, -28, 17, 16,
+ -7, -31, -8, 25, -6, 0, 13, -20, 6, 3, -7, 19, -21, -37, 27, 41,
+ 7, -14, 12, -59, 57, 6, -49, -2, -8, 0, 19, 13, -20, -5, 16, 23,
+ 4, -15, -33, 14, 2, 15, -26, -28, 10, 45, -17, -24, 14, 17, -39, 22,
+ -8, 48, -51, -1, -16, 52, -34, -21, 11, 13, 18, -57, 26, 15, 27, -36,
+ -12, 40, -7, -14, 15, -86, 91, -20, -13, -7, 53, -43, 33, -25, 13, 3,
+ -38, -19, 28, 28, -18, -74, 58, -3, 40, -27, -34, 30, 28, -1, -22, 2,
+ 9, -8, -12, 12, 21, -35, -2, -17, 17, 2, -27, 22, -36, 38, -11, 2,
+ -20, 7, 20, -29, 39, 11, -3, 9, -24, 47, -36, 28, -14, -16, 38, -37,
+ 12, -15, 18, -69, 56, -31, 17, -16, -18, -13, 21, -6, -9, -25, 37, 6,
+ -1, -2, 5, -1, -26, 39, 6, -3, -10, 0, 12, 30, -12, -31, 24, 13,
+ -14, 9, -23, 31, -43, -17, -2, 13, -23, -14, -21, 21, 19, -22, -12, 24,
+ 41, -26, 10, 12, 19, -3, 9, -12, 26, 12, -52, -4, 16, -3, 0, -43,
+ 7, 5, -14, -9, 12, -28, 15, -23, -2, 35, -12, -8, -10, 24, 57, -55,
+ 26, -18, 19, 44, -30, 0, -5, 50, -56, -1, 8, -5, -39, 9, 19, -39,
+ 38, -73, 30, -1, 2, 16, -24, 6, 29, -71, 70, -18, -6, 8, 31, 4,
+ -13, 23, -11, 31, -56, 57, -25, 10, 15, -44, -10, 16, -17, -44, 18, -28,
+ 10, 8, -21, -4, -9, 28, 20, -16, 17, -17, -6, 30, 0, 11, -21, 25,
+ 25, -1, 31, -56, 31, 14, -32, 2, -19, 4, -17, -26, -13, 42, -59, 15,
+ -29, 53, -4, 1, -23, 13, 31, 5, -22, 3, 30, -28, 2, -24, 37, 1,
+ -3, -18, 18, 41, -40, 3, -40, 48, -31, -5, -20, 5, 9, 0, -30, -1,
+ 26, -15, -5, -6, 51, -25, -27, 7, 44, -11, 10, -32, 14, 46, -31, 6,
+ -11, 37, -33, -14, 19, -4, 22, -50, 26, -45, 21, 1, -23, 10, -15, 17,
+ -63, 53, -14, -18, 56, -49, 21, 25, -7, 4, -21, 52, -33, 19, 3, 11,
+ -9, -7, 0, -49, 22, -17, 25, -10, -11, 5, -19, 35, -26, 20, -7, -21,
+ 37, -25, 29, -23, 3, 6, 17, -26, 27, 5, -16, 10, -9, -24, 11, -4,
+ -17, 9, -5, -13, 1, -2, 10, 5, -13, 21, 0, 8, 9, -22, 12, 13,
+ -24, -3, -22, 42, -18, 3, -4, -15, 1, -2, 8, -17, -13, -2, 1, 23,
+ 10, -2, -31, 23, 17, -15, -9, -24, 31, 2, 19, -24, 4, -22, 28, -5,
+ -20, 34, -57, 26, 71, -51, 28, -24, -12, 28, 10, -35, -4, -6, 7, -7,
+ 8, -52, 61, -52, 7, -9, -21, 9, 18, -19, 3, 34, -53, 56, -29, 20,
+ -11, 22, 4, -1, 23, 2, 1, 24, -15, 3, -32, 13, 21, -37, 6, -11,
+ -25, 22, 7, -2, -41, 4, 10, -30, 39, -24, -7, 8, 12, 9, -1, -35,
+ 13, 3, 9, -18, 21, 26, -14, 41, -8, -35, 31, -29, 17, -20, -12, 20,
+ -30, 27, -26, 21, -9, -6, 5, -14, 3, -11, 15, 2, 8, -14, -5, 20,
+ 4, 0, -31, 9, 4, 25, -24, 5, -5, -13, 27, -7, -32, 1, -5, -10,
+ 28, 7, -4, 11, 10, 22, -3, -22, -15, 6, -3, -3, -27, -25, 5, 8,
+ -10, -17, 18, -18, 12, 32, -18, 1, 25, -25, 50, 7, 2, 0, -3, -3,
+ 16, -20, 9, -14, -15, 21, -27, -3, -17, 23, -31, -4, -18, 31, -21, 6,
+ 0, 18, -16, 27, 3, -7, -17, 17, -15, -11, 19, -16, 6, 1, 12, -18,
+ 5, -6, 24, 0, -19, 22, -23, 43, -35, 18, 22, -40, 1, 12, -4, -18,
+ 26, -53, 34, 1, -10, 1, -18, 27, -25, -24, 33, -31, 9, -43, 53, -29,
+ 33, -17, 5, 23, -7, 2, 23, 29, 1, -8, 20, -10, -1, -22, -3, -17,
+ 4, 22, -61, -23, 31, -26, -29, -12, 2, -3, 12, 10, 26, 5, -29, 61,
+ -9, 32, -18, -14, 29, 31, 2, -19, 9, 31, -20, -31, -7, 5, -22, -47,
+ 31, -40, 15, -39, 22, -27, 40, -78, 31, 4, -19, 33, -13, -8, 41, -1,
+ 5, -12, 53, -51, 22, -1, 18, 28, -29, -1, 0, 0, 11, 13, -2, -7,
+ -5, -3, -3, 1, 2, -6, 0, 3, 8, 9, 5, 0, 14, -5, -28, -39,
+ -39, -36, -37, -27, -43, -49, -13, 4, 6, -7, 0, -1, 3, 23, 39, 29,
+ 35, 41, 21, 35, 0, 0, 21, 59, 67, 31, 21, 13, -3, 18, 34, 28,
+ 5, 3, 13, 3, 0, 12, -7, -33, -27, -39, -14, -34, -50, -30, -37, -35,
+ -53, -74, -70, -61, -62, -62, -50, -44, -61, -36, -3, -23, -15, -12, -17, -20,
+ -6, 11, -6, -12, -6, -17, 7, 46, 71, 87, 79, 70, 77, 104, 109, 66,
+ 37, 34, 27, 31, 40, 43, 31, 23, 17, 2, 10, 24, 32, 66, 56, 17,
+ -13, -55, -54, -21, 19, -19, -56, -77, -37, -27, -10, -6, -38, -36, -37, -3,
+ 23, 25, 25, 19, 35, 34, -7, -5, 28, 60, 66, 65, 51, 34, 22, 53,
+ 51, 15, 20, 11, 21, 21, 16, 24, -2, -23, -36, -35, -21, -29, -51, -51,
+ -47, -57, -85, -80, -70, -100, -97, -82, -78, -76, -64, -51, -56, -54, -49, -70,
+ -62, -53, -54, -60, -57, -65, -78, -76, -62, -39, 0, 31, 13, 6, 31, 54,
+ 55, 43, 30, 13, 9, 31, 23, 43, 28, 24, 36, 36, 24, 30, 54, 70,
+ 113, 103, 75, 4, -3, 40, 55, 50, 23, 9, 25, 29, 48, 41, 29, 14,
+ 6, 40, 63, 49, 39, 71, 80, 64, 21, 12, 17, 29, 68, 71, 52, 36,
+ 24, 37, 24, 1, 5, 3, -6, -4, 1, 13, -3, -22, -35, -31, -27, -58,
+ -59, -43, -55, -71, -76, -71, -88, -103, -95, -98, -85, -77, -68, -71, -58, -50,
+ -47, -52, -46, -40, -47, -44, -48, -56, -60, -91, -96, -68, -15, -6, -16, 9,
+ 3, 29, 31, 29, 8, 10, -6, 5, 10, -6, -4, -6, 15, 7, -2, 2,
+ -5, 30, 91, 107, 74, 8, -3, 14, 27, 32, 26, 17, 21, 18, 34, 49,
+ 20, -3, 2, 30, 42, 20, 36, 68, 79, 81, 52, 27, 22, 37, 80, 95,
+ 77, 77, 72, 74, 57, 55, 56, 41, 35, 22, 40, 58, 32, 23, 24, 26,
+ 0, -7, 6, -2, -16, -26, -31, -45, -46, -64, -77, -79, -73, -72, -75, -59,
+ -49, -56, -35, -48, -44, -50, -43, -59, -58, -40, -78, -119, -123, -95, -73, -40,
+ -52, -45, -29, -18, -3, -1, -11, -21, -28, -12, -24, -29, -21, -29, -16, -3,
+ -5, -30, -40, 1, 69, 96, 78, 31, 14, 23, 17, 19, 33, 20, 9, 9,
+ 45, 50, 14, 3, 12, 13, 16, 7, 14, 35, 54, 75, 56, 24, 1, 18,
+ 47, 47, 60, 62, 66, 69, 46, 54, 53, 38, 11, 18, 44, 41, 28, 33,
+ 37, 22, 14, 15, 13, 13, 1, -1, -13, -6, -11, -38, -33, -47, -40, -46,
+ -31, -29, -22, -9, -5, -9, 9, 4, -23, -14, -4, -3, -26, -69, -87, -74,
+ -60, -42, -49, -33, -28, -16, 9, 2, -16, -22, -25, -25, -33, -32, -44, -58,
+ -41, -11, -19, -51, -77, -43, 24, 47, 49, 34, 21, 5, -9, 5, 18, -10,
+ -14, 2, 23, 26, -3, -7, -4, 2, -3, -10, -4, -6, 38, 64, 50, 25,
+ 1, 11, 17, 21, 36, 58, 62, 46, 46, 61, 56, 27, 11, 20, 18, 27,
+ 15, 31, 26, 23, 17, 7, 16, 0, -9, -10, -3, -8, -14, -25, -36, -56,
+ -41, -39, -50, -30, -12, -23, -8, 10, 23, 17, -2, 3, 14, 26, 7, -33,
+ -48, -53, -52, -35, -30, -30, -23, 3, 21, 17, 8, 7, -8, -1, 0, -6,
+ -29, -50, -26, 10, 5, -38, -64, -41, 5, 22, 49, 63, 38, 20, 13, 26,
+ 15, -7, -9, -1, 28, 9, 1, -4, -12, -1, -5, -20, -38, -32, 6, 38,
+ 36, 16, 10, 0, -8, -13, 15, 41, 25, 30, 30, 52, 35, 17, 8, 3,
+ -5, -5, -6, 4, 7, 4, 4, 3, 3, -20, -25, -23, -28, -22, -18, -47,
+ -50, -54, -62, -67, -62, -48, -43, -44, -31, -10, 17, 10, -8, 1, 22, 24,
+ 17, -1, -21, -40, -39, -26, -38, -32, -21, 2, 17, 26, 29, 18, 5, 15,
+ 35, 19, -11, -37, -9, 33, 17, -6, -30, -23, -10, 22, 65, 73, 71, 47,
+ 57, 66, 38, 15, 16, 23, 34, 35, 27, 10, 11, 21, 32, -4, -26, -29,
+ 4, 29, 28, 38, 32, 17, -6, -6, 17, 32, 21, 31, 39, 49, 36, 27,
+ 25, 13, -1, -11, -8, -1, -15, -11, 4, -7, -9, -14, -38, -46, -35, -31,
+ -43, -53, -54, -72, -84, -88, -86, -79, -73, -86, -69, -40, -16, -23, -28, -13,
+ -9, 5, 5, -10, -34, -45, -48, -52, -61, -59, -42, -38, -9, 13, 19, 8,
+ -14, 18, 42, 28, -18, -31, -3, 11, 21, 13, -9, -17, -22, 9, 57, 71,
+ 62, 68, 83, 82, 65, 38, 38, 31, 52, 57, 45, 23, 25, 51, 56, 21,
+ -2, -8, 7, 21, 28, 55, 55, 37, 15, 17, 30, 30, 30, 48, 55, 65,
+ 55, 54, 61, 42, 24, 22, 13, 6, 6, 4, 4, 17, 19, 1, -20, -23,
+ -25, -27, -26, -44, -44, -62, -79, -91, -83, -76, -99, -104, -87, -63, -51, -40,
+ -42, -40, -29, -16, -6, -31, -40, -47, -63, -68, -81, -76, -81, -75, -49, -15,
+ -5, -34, -38, 2, 15, 8, -29, -43, -33, -18, -11, 8, -9, -42, -45, -14,
+ 25, 33, 41, 54, 67, 75, 71, 46, 30, 23, 52, 55, 38, 20, 25, 53,
+ 59, 35, 17, 6, 3, 5, 27, 64, 61, 49, 40, 40, 45, 36, 38, 63,
+ 69, 69, 77, 85, 78, 76, 63, 48, 38, 42, 28, 15, 30, 35, 41, 27,
+ 14, 0, -4, -2, -14, -16, -15, -35, -65, -63, -56, -64, -80, -94, -77, -71,
+ -46, -34, -42, -37, -21, -6, -5, -16, -20, -35, -44, -62, -66, -66, -96, -94,
+ -58, -26, -32, -44, -50, -14, 2, -9, -26, -41, -53, -49, -27, -5, -28, -59,
+ -65, -47, -20, -11, 7, 15, 28, 51, 57, 32, 7, 2, 30, 32, 15, 0,
+ 7, 30, 30, 24, 21, -2, -19, -20, 6, 37, 40, 31, 40, 45, 30, 29,
+ 35, 49, 52, 69, 74, 78, 89, 79, 72, 62, 60, 51, 37, 29, 29, 42,
+ 51, 46, 30, 32, 18, 2, 8, 13, 15, -13, -35, -35, -38, -40, -53, -71,
+ -70, -58, -34, -38, -32, -28, -9, 10, 10, 7, 11, -7, -28, -21, -26, -47,
+ -80, -84, -49, -18, -28, -38, -32, -8, -4, 4, 3, -23, -46, -44, -19, -5,
+ -22, -42, -55, -56, -35, -25, -12, -8, 11, 43, 51, 33, 1, 0, 24, 18,
+ 1, -5, 0, 1, 9, 15, 21, -2, -38, -36, -19, 2, 2, 19, 26, 19,
+ 20, 10, 11, 20, 31, 37, 49, 62, 64, 61, 60, 61, 50, 51, 32, 10,
+ 16, 27, 31, 33, 33, 36, 7, -6, 3, 14, 12, -10, -21, -40, -34, -33,
+ -47, -65, -67, -60, -40, -40, -44, -25, -10, -4, 14, 26, 22, 4, -7, 8,
+ 8, -22, -67, -65, -33, -19, -24, -20, -18, -8, 1, 26, 30, -2, -22, -25,
+ -6, 5, -1, -13, -38, -43, -31, -21, -16, -16, 9, 47, 61, 35, 22, 22,
+ 31, 24, 10, 13, 5, -2, 0, 28, 34, 1, -21, -30, -28, -18, -5, 5,
+ 18, 20, 14, 6, 6, 12, 9, 20, 33, 39, 51, 51, 42, 51, 51, 48,
+ 20, 9, 7, 5, 7, 15, 28, 19, -1, -16, -15, -4, 4, -16, -30, -41,
+ -45, -41, -50, -79, -77, -69, -65, -64, -56, -45, -40, -28, -4, 21, 17, -8,
+ -9, 21, 16, -18, -56, -58, -44, -39, -24, -22, -28, -22, -4, 29, 31, 13,
+ -9, -16, -3, 11, 13, 1, -18, -33, -15, -11, -23, -22, 11, 52, 58, 50,
+ 46, 50, 49, 36, 40, 40, 17, 6, 20, 37, 45, 29, 9, -7, -12, -11,
+ -6, 9, 30, 25, 26, 26, 17, 19, 15, 21, 24, 46, 55, 47, 43, 56,
+ 64, 52, 33, 25, 13, -3, 2, 10, 21, 26, 4, -15, -16, -13, -2, -11,
+ -32, -43, -37, -44, -61, -77, -78, -82, -82, -80, -71, -61, -72, -59, -21, 5,
+ -2, -27, -10, 15, 7, -14, -44, -59, -67, -55, -37, -38, -50, -45, -23, 5,
+ 23, 9, -6, -19, -15, 5, 14, 2, -22, -22, -10, -17, -35, -38, -3, 35,
+ 38, 43, 57, 51, 44, 49, 57, 46, 25, 14, 24, 35, 54, 41, 31, 22,
+ 1, -7, -4, 12, 23, 34, 37, 35, 35, 36, 26, 24, 33, 55, 62, 53,
+ 58, 70, 70, 73, 62, 51, 38, 14, 6, 20, 31, 32, 27, 4, -9, -1,
+ 9, -8, -21, -22, -27, -33, -53, -64, -67, -82, -86, -83, -67, -75, -97, -77,
+ -36, -15, -27, -32, -18, -1, -1, -6, -31, -62, -73, -68, -52, -52, -68, -69,
+ -50, -21, -2, 4, -10, -33, -29, -4, 2, -10, -29, -22, -8, -27, -55, -49,
+ -27, -6, 12, 31, 43, 31, 38, 44, 54, 48, 25, 11, 19, 30, 36, 41,
+ 41, 29, 11, -1, -9, 0, 15, 27, 34, 36, 46, 46, 26, 27, 39, 51,
+ 59, 62, 62, 73, 76, 77, 85, 78, 58, 35, 23, 21, 37, 53, 37, 22,
+ 15, 16, 20, 3, 0, -2, -2, -14, -33, -35, -45, -69, -77, -59, -53, -76,
+ -96, -74, -41, -30, -25, -26, -19, -4, 7, 11, -8, -40, -62, -62, -51, -55,
+ -69, -74, -71, -44, -15, -2, -14, -36, -38, -8, -7, -27, -33, -17, -12, -38,
+ -51, -57, -58, -41, -14, 8, 19, 15, 15, 31, 46, 40, 21, 9, 7, 10,
+ 20, 25, 33, 28, 16, 1, -18, -13, 0, 6, 12, 30, 39, 39, 26, 20,
+ 32, 41, 45, 53, 64, 63, 62, 80, 84, 87, 81, 51, 29, 21, 44, 52,
+ 41, 33, 29, 31, 27, 12, 8, 16, 10, -4, -7, -7, -29, -62, -57, -37,
+ -44, -68, -81, -70, -48, -33, -23, -22, -17, -5, 16, 31, 14, -15, -33, -42,
+ -41, -37, -53, -65, -74, -54, -16, 2, -12, -33, -19, -1, -10, -22, -17, -8,
+ -8, -18, -33, -48, -62, -57, -31, -1, 7, 0, 9, 22, 40, 40, 27, 14,
+ 4, 3, 10, 14, 21, 31, 20, 0, -13, -19, -17, -15, -7, 12, 29, 28,
+ 13, 20, 18, 18, 31, 38, 47, 49, 51, 56, 67, 87, 84, 56, 30, 20,
+ 31, 41, 31, 24, 32, 33, 20, 7, 14, 15, -2, -1, 13, 4, -28, -53,
+ -45, -34, -38, -59, -75, -72, -58, -44, -26, -26, -29, -8, 14, 34, 28, 10,
+ -9, -22, -26, -24, -30, -54, -78, -56, -13, -4, -17, -16, -5, 1, -6, -9,
+ -8, -1, 3, -2, -4, -28, -53, -58, -37, -10, 1, -1, 6, 20, 34, 46,
+ 40, 25, 19, 11, 7, 10, 23, 33, 28, 16, -3, -3, -17, -31, -14, 4,
+ 15, 20, 20, 16, 10, 14, 19, 23, 37, 45, 35, 37, 53, 76, 83, 62,
+ 34, 20, 27, 28, 13, 17, 29, 21, 7, 9, 13, -4, -17, -4, 13, 2,
+ -27, -53, -47, -39, -46, -56, -77, -87, -77, -58, -45, -46, -47, -33, -6, 17,
+ 22, 16, 1, -20, -25, -10, -21, -57, -79, -57, -32, -24, -23, -18, -3, -1,
+ -6, -4, -4, -5, 3, 13, 14, -6, -38, -51, -39, -22, -4, -1, 3, 14,
+ 32, 45, 46, 46, 33, 25, 15, 9, 28, 38, 32, 28, 26, 14, -9, -21,
+ -15, -5, 10, 24, 22, 22, 21, 15, 15, 23, 36, 42, 35, 31, 41, 72,
+ 87, 68, 46, 42, 34, 19, 14, 25, 25, 11, 14, 18, 14, -7, -24, -7,
+ 12, 4, -19, -41, -47, -44, -41, -52, -74, -92, -88, -72, -59, -63, -68, -53,
+ -34, -11, 12, 19, -7, -27, -15, -5, -22, -54, -76, -66, -52, -47, -41, -29,
+ -17, -12, -12, -10, -11, -19, -7, 12, 19, 3, -23, -42, -48, -31, -19, -14,
+ -6, 1, 20, 35, 39, 50, 51, 33, 16, 17, 30, 31, 32, 41, 39, 28,
+ 14, -7, -14, -5, 8, 18, 27, 34, 29, 22, 21, 26, 38, 51, 39, 27,
+ 43, 75, 84, 73, 75, 68, 46, 32, 31, 35, 27, 15, 23, 36, 26, 0,
+ -13, -4, 12, 14, 1, -23, -36, -36, -32, -36, -60, -83, -84, -70, -67, -70,
+ -66, -67, -62, -27, 8, 13, -11, -22, -7, 4, -16, -44, -63, -67, -63, -63,
+ -53, -42, -33, -25, -15, -10, -22, -27, -18, -1, 16, 9, -13, -32, -46, -42,
+ -31, -30, -24, -8, 5, 11, 25, 49, 50, 33, 25, 20, 21, 24, 29, 34,
+ 41, 41, 26, 5, -5, -7, -4, 12, 23, 33, 37, 29, 19, 24, 49, 53,
+ 33, 33, 49, 65, 73, 80, 89, 85, 63, 48, 50, 46, 30, 20, 35, 46,
+ 39, 17, 0, 2, 15, 23, 18, -2, -20, -24, -12, -19, -45, -60, -66, -70,
+ -66, -56, -61, -74, -74, -38, 0, 6, -8, -15, 3, 13, -1, -24, -42, -52,
+ -65, -64, -54, -54, -47, -31, -19, -12, -21, -32, -27, -12, 7, 13, -2, -24,
+ -36, -37, -44, -47, -32, -20, -18, -9, 12, 30, 38, 35, 26, 18, 17, 16,
+ 13, 25, 36, 37, 32, 18, 2, -11, -10, -5, 3, 28, 38, 20, 8, 25,
+ 42, 40, 28, 30, 40, 46, 54, 70, 87, 82, 66, 61, 59, 48, 28, 20,
+ 32, 43, 43, 24, 8, 1, 7, 23, 25, 3, -13, -9, -8, -15, -28, -40,
+ -58, -71, -60, -49, -58, -80, -82, -50, -17, -5, -13, -12, 6, 13, 8, -3,
+ -24, -42, -54, -59, -57, -60, -59, -43, -24, -15, -20, -30, -35, -25, 1, 11,
+ -2, -12, -18, -33, -48, -49, -41, -37, -32, -21, -8, 13, 27, 27, 27, 23,
+ 16, 8, 7, 15, 22, 32, 35, 22, 9, 0, -18, -26, -8, 20, 25, 11,
+ 4, 18, 32, 29, 22, 29, 30, 27, 38, 60, 75, 70, 68, 69, 67, 52,
+ 30, 19, 27, 36, 40, 34, 10, -2, 6, 21, 20, 4, -2, -4, -7, -9,
+ -12, -25, -52, -66, -53, -42, -53, -79, -86, -58, -33, -23, -16, -12, 0, 12,
+ 17, 13, -5, -24, -38, -44, -50, -59, -61, -51, -33, -15, -11, -28, -36, -23,
+ -4, 5, 5, 7, -3, -17, -31, -40, -38, -37, -36, -29, -14, 4, 15, 25,
+ 34, 30, 24, 19, 9, 8, 22, 33, 31, 30, 31, 16, -14, -26, -13, 14,
+ 17, 7, 8, 18, 24, 23, 28, 31, 23, 18, 30, 50, 62, 61, 63, 75,
+ 73, 59, 40, 23, 20, 30, 43, 35, 11, 0, 8, 15, 12, 6, 3, -6,
+ -10, -3, -1, -15, -46, -62, -47, -38, -54, -77, -84, -70, -53, -40, -30, -21,
+ -12, 1, 16, 20, 5, -12, -21, -33, -44, -52, -64, -64, -44, -17, -15, -27,
+ -30, -26, -15, -3, 6, 12, 9, -2, -17, -26, -29, -36, -41, -32, -21, -10,
+ 6, 18, 27, 34, 37, 25, 11, 14, 21, 26, 27, 37, 48, 33, -1, -19,
+ -8, 7, 8, 8, 16, 16, 17, 25, 34, 36, 23, 16, 28, 44, 53, 54,
+ 61, 74, 79, 75, 56, 30, 19, 31, 45, 35, 15, 9, 9, 9, 11, 9,
+ 5, -8, -14, 0, 9, -10, -40, -53, -44, -38, -51, -72, -84, -80, -69, -58,
+ -45, -38, -30, -13, 5, 13, 8, 0, -14, -25, -30, -46, -67, -72, -55, -34,
+ -26, -28, -31, -31, -26, -17, -4, 9, 11, 2, -4, -12, -22, -33, -38, -40,
+ -34, -18, -7, 2, 17, 33, 38, 29, 19, 20, 22, 17, 19, 38, 57, 43,
+ 15, 2, -1, 1, 3, 10, 18, 15, 14, 25, 38, 40, 27, 21, 28, 38,
+ 46, 50, 55, 66, 81, 90, 71, 40, 30, 37, 44, 39, 26, 18, 12, 8,
+ 14, 19, 8, -11, -13, 5, 15, -2, -28, -42, -36, -34, -45, -60, -76, -83,
+ -77, -65, -59, -55, -43, -28, -13, 5, 11, 2, -9, -11, -17, -37, -61, -71,
+ -65, -49, -38, -36, -34, -35, -36, -32, -16, -2, 1, 3, 0, -7, -13, -25,
+ -39, -46, -42, -30, -22, -15, 2, 21, 30, 24, 22, 28, 19, 5, 11, 33,
+ 50, 45, 31, 17, 6, -1, 0, 8, 16, 12, 11, 23, 37, 40, 33, 29,
+ 29, 33, 45, 48, 46, 58, 83, 97, 84, 59, 45, 46, 47, 46, 42, 31,
+ 16, 12, 23, 29, 16, -5, -9, 10, 21, 10, -12, -24, -25, -25, -29, -42,
+ -64, -73, -70, -66, -63, -58, -52, -42, -22, 0, 8, 4, 1, 3, -1, -19,
+ -44, -61, -63, -57, -50, -39, -33, -37, -39, -36, -27, -14, -4, 0, 0, 0,
+ -1, -13, -30, -42, -43, -37, -36, -30, -10, 8, 12, 15, 26, 31, 16, 1,
+ 4, 21, 37, 41, 38, 29, 13, 0, -1, 6, 8, 3, 7, 17, 26, 34,
+ 35, 27, 24, 32, 40, 37, 32, 45, 72, 89, 86, 70, 57, 48, 45, 49,
+ 50, 37, 16, 11, 25, 34, 20, -3, -7, 7, 18, 15, 2, -14, -20, -15,
+ -17, -32, -49, -61, -67, -65, -60, -61, -63, -54, -33, -12, -1, 1, 2, 10,
+ 12, -3, -26, -43, -57, -60, -54, -45, -38, -38, -39, -39, -35, -23, -13, -6,
+ -3, 2, 7, -2, -20, -30, -34, -42, -47, -38, -19, -9, -5, 7, 24, 31,
+ 19, 3, 0, 10, 23, 33, 40, 36, 18, 5, 4, 4, 0, 0, 0, 5,
+ 16, 29, 30, 22, 22, 31, 36, 27, 21, 32, 54, 74, 81, 77, 65, 49,
+ 44, 50, 55, 40, 16, 10, 24, 31, 20, 3, -6, -1, 11, 16, 5, -9,
+ -13, -12, -14, -22, -36, -53, -63, -62, -59, -63, -69, -67, -48, -25, -14, -10,
+ -1, 10, 16, 10, -6, -26, -45, -54, -55, -50, -42, -39, -39, -40, -39, -29,
+ -19, -15, -8, 4, 11, 3, -6, -11, -21, -38, -48, -40, -26, -21, -16, -3,
+ 18, 30, 24, 12, 6, 4, 11, 29, 41, 39, 28, 18, 11, 8, 5, 1,
+ -4, -2, 11, 25, 25, 19, 23, 33, 35, 25, 17, 23, 39, 57, 74, 81,
+ 72, 53, 47, 56, 60, 44, 23, 16, 22, 29, 25, 10, -4, -3, 7, 11,
+ 6, -3, -9, -11, -9, -12, -26, -42, -56, -59, -55, -61, -73, -75, -60, -42,
+ -32, -23, -12, 0, 12, 15, 7, -10, -30, -46, -53, -53, -46, -41, -43, -45,
+ -41, -32, -30, -26, -14, -1, 5, 2, 3, 3, -9, -30, -43, -40, -31, -31,
+ -28, -12, 8, 20, 25, 22, 9, 0, 6, 21, 34, 39, 35, 26, 18, 16,
+ 14, 4, -7, -5, 9, 21, 19, 16, 23, 35, 37, 28, 20, 20, 26, 43,
+ 67, 82, 74, 57, 54, 62, 63, 52, 33, 21, 23, 30, 28, 14, 1, -1,
+ 3, 8, 7, -1, -7, -9, -6, -5, -15, -34, -49, -51, -51, -60, -72, -76,
+ -70, -57, -46, -37, -25, -13, 3, 14, 14, 3, -15, -33, -48, -52, -47, -45,
+ -49, -49, -41, -37, -39, -35, -21, -10, -5, -2, 6, 12, 1, -19, -32, -34,
+ -36, -39, -34, -23, -9, 9, 23, 25, 14, 3, 2, 12, 25, 36, 37, 30,
+ 24, 25, 24, 10, -5, -4, 9, 18, 15, 14, 23, 34, 38, 36, 30, 19,
+ 15, 32, 61, 78, 75, 63, 60, 67, 71, 62, 42, 29, 30, 33, 32, 20,
+ 8, 4, 6, 8, 8, 3, -5, -9, -2, 3, -7, -25, -37, -42, -45, -54,
+ -66, -74, -74, -67, -58, -49, -40, -27, -9, 5, 13, 13, 0, -21, -39, -45,
+ -44, -49, -54, -50, -44, -44, -47, -42, -29, -21, -19, -11, 5, 12, 4, -8,
+ -18, -28, -36, -40, -40, -36, -24, -4, 14, 21, 17, 7, 0, 3, 17, 32,
+ 34, 29, 28, 34, 33, 17, 0, 0, 9, 13, 12, 14, 20, 27, 38, 46,
+ 39, 21, 11, 24, 51, 71, 74, 66, 64, 73, 78, 71, 54, 40, 38, 41,
+ 38, 28, 17, 11, 9, 12, 14, 7, -3, -5, 3, 9, 2, -12, -23, -28,
+ -35, -45, -55, -65, -71, -68, -62, -57, -50, -37, -22, -7, 10, 20, 12, -8,
+ -24, -32, -39, -48, -52, -49, -45, -49, -52, -44, -34, -33, -30, -18, -3, 5,
+ 5, 1, -8, -19, -29, -37, -43, -45, -37, -18, 0, 13, 18, 10, -1, -3,
+ 10, 24, 26, 23, 29, 38, 37, 21, 8, 5, 6, 8, 10, 12, 11, 16,
+ 34, 49, 46, 27, 10, 15, 38, 59, 67, 63, 63, 72, 81, 77, 61, 48,
+ 45, 45, 42, 35, 23, 13, 11, 17, 18, 9, -3, -5, 3, 10, 6, -3,
+ -12, -19, -24, -34, -46, -57, -64, -65, -66, -63, -56, -48, -39, -22, 1, 17,
+ 16, 3, -8, -17, -30, -44, -47, -44, -47, -53, -52, -44, -41, -41, -38, -28,
+ -14, -3, 3, 3, -2, -9, -17, -28, -42, -49, -46, -34, -17, 3, 14, 9,
+ -3, -6, 5, 15, 13, 15, 26, 36, 35, 25, 16, 8, 2, 4, 9, 6,
+ 1, 4, 22, 43, 48, 31, 11, 7, 24, 45, 55, 54, 55, 68, 79, 77,
+ 66, 54, 48, 47, 47, 41, 27, 14, 11, 18, 20, 10, -2, -6, 0, 7,
+ 8, 2, -6, -12, -14, -23, -38, -49, -55, -62, -66, -63, -60, -59, -53, -37,
+ -12, 8, 13, 10, 7, -4, -21, -35, -37, -39, -47, -53, -51, -45, -44, -44,
+ -42, -36, -24, -10, 0, 2, 1, 1, -3, -15, -30, -42, -49, -45, -30, -6,
+ 10, 7, -2, -3, 5, 9, 6, 11, 23, 32, 35, 33, 25, 14, 6, 9,
+ 12, 8, -2, -4, 13, 36, 48, 39, 18, 7, 17, 34, 43, 45, 50, 62,
+ 74, 78, 71, 59, 51, 49, 52, 48, 32, 16, 12, 19, 21, 13, 1, -6,
+ -5, 2, 6, 2, -4, -6, -9, -18, -29, -40, -51, -60, -65, -63, -63, -68,
+ -68, -53, -30, -12, 0, 10, 13, 3, -14, -25, -29, -35, -45, -52, -52, -49,
+ -47, -47, -47, -46, -35, -20, -10, -5, -1, 4, 4, -4, -15, -30, -47, -54,
+ -41, -15, 1, 0, -2, 2, 6, 4, 3, 7, 16, 26, 35, 38, 32, 20,
+ 12, 14, 18, 12, -1, -8, 3, 27, 46, 44, 26, 14, 17, 28, 35, 38,
+ 44, 55, 69, 78, 77, 66, 55, 54, 60, 58, 41, 24, 17, 19, 23, 20,
+ 7, -4, -4, 0, 2, 1, 0, -2, -4, -10, -17, -28, -42, -55, -59, -56,
+ -61, -72, -74, -63, -47, -32, -14, 5, 13, 7, -4, -12, -19, -28, -38, -46,
+ -51, -50, -46, -47, -51, -52, -43, -30, -20, -13, -5, 0, 4, 4, 2, -13,
+ -40, -55, -47, -25, -12, -8, -3, 3, 5, 4, 2, 3, 7, 18, 32, 41,
+ 36, 25, 18, 21, 25, 21, 5, -9, -3, 19, 41, 45, 34, 24, 23, 27,
+ 30, 33, 38, 47, 62, 78, 82, 72, 61, 61, 67, 66, 54, 37, 24, 23,
+ 28, 25, 15, 5, 0, 0, 0, 1, 2, 2, -1, -4, -5, -15, -34, -47,
+ -49, -49, -58, -69, -73, -70, -63, -51, -30, -8, 5, 7, 3, -4, -11, -20,
+ -29, -41, -49, -50, -46, -49, -54, -56, -50, -42, -33, -22, -13, -10, -6, 5,
+ 12, -1, -30, -50, -50, -38, -27, -18, -10, -3, 1, 2, 2, -2, -4, 6,
+ 24, 36, 36, 27, 19, 22, 30, 28, 10, -8, -10, 9, 30, 39, 35, 30,
+ 26, 26, 28, 29, 29, 35, 53, 73, 80, 74, 65, 63, 69, 72, 64, 47,
+ 33, 28, 29, 28, 21, 12, 6, 2, -2, 1, 4, 1, -2, 2, 6, -4,
+ -23, -35, -38, -42, -51, -60, -66, -70, -71, -63, -45, -23, -5, 4, 6, 3,
+ -2, -7, -18, -32, -42, -43, -43, -47, -52, -54, -53, -51, -42, -27, -20, -21,
+ -14, 4, 17, 10, -13, -35, -45, -44, -37, -26, -17, -11, -3, 3, 3, -3,
+ -9, -4, 13, 31, 35, 27, 19, 23, 34, 36, 19, -3, -10, 2, 19, 31,
+ 35, 33, 29, 30, 32, 28, 22, 26, 43, 63, 76, 75, 67, 65, 71, 75,
+ 70, 57, 43, 36, 34, 30, 26, 21, 14, 5, 1, 4, 3, -2, -2, 6,
+ 11, 3, -11, -22, -29, -36, -43, -50, -57, -67, -74, -72, -60, -40, -19, -5,
+ 2, 4, 6, 3, -8, -23, -32, -35, -40, -45, -47, -51, -57, -58, -47, -33,
+ -30, -32, -24, -5, 13, 14, 1, -18, -36, -45, -42, -35, -27, -20, -11, 0,
+ 3, -3, -12, -12, 1, 21, 31, 25, 16, 20, 34, 40, 26, 5, -7, -6,
+ 7, 21, 27, 26, 27, 31, 33, 27, 17, 15, 28, 50, 65, 68, 64, 62,
+ 68, 74, 72, 61, 51, 44, 35, 29, 28, 25, 15, 7, 5, 5, -1, -8,
+ -5, 3, 8, 4, -4, -12, -22, -32, -38, -42, -50, -61, -72, -77, -73, -57,
+ -36, -20, -11, -2, 7, 8, -3, -14, -22, -30, -38, -41, -42, -49, -60, -62,
+ -52, -41, -40, -41, -34, -18, 0, 11, 10, -3, -23, -38, -42, -40, -36, -31,
+ -20, -6, 2, -1, -13, -19, -9, 12, 25, 20, 12, 17, 30, 39, 34, 17,
+ -2, -8, 1, 13, 19, 21, 23, 31, 37, 32, 18, 10, 18, 36, 55, 62,
+ 60, 60, 67, 73, 72, 68, 61, 51, 41, 35, 34, 28, 18, 12, 11, 8,
+ -2, -9, -7, 0, 4, 5, 3, -3, -14, -24, -31, -36, -41, -50, -64, -77,
+ -80, -68, -51, -37, -26, -11, 3, 6, 2, -3, -13, -24, -32, -33, -34, -46,
+ -60, -62, -54, -47, -46, -47, -43, -31, -13, 4, 12, 6, -9, -23, -34, -39,
+ -40, -38, -29, -14, 0, 2, -11, -22, -15, 4, 17, 16, 11, 13, 25, 39,
+ 41, 28, 9, -3, 0, 9, 15, 15, 19, 30, 40, 39, 26, 12, 11, 28,
+ 45, 54, 56, 60, 66, 70, 73, 74, 69, 58, 49, 45, 42, 32, 22, 18,
+ 19, 14, 3, -6, -7, -4, 0, 5, 6, 3, -5, -14, -24, -30, -32, -38,
+ -53, -71, -78, -72, -63, -54, -39, -22, -8, 1, 6, 6, -4, -18, -25, -23,
+ -25, -39, -54, -58, -54, -49, -49, -50, -49, -42, -26, -7, 7, 9, 2, -9,
+ -20, -30, -38, -43, -39, -22, -2, 3, -9, -20, -16, -2, 11, 14, 10, 10,
+ 20, 36, 46, 40, 22, 8, 6, 11, 13, 12, 15, 26, 41, 46, 36, 20,
+ 14, 24, 38, 47, 54, 60, 64, 69, 76, 81, 76, 66, 60, 58, 53, 40,
+ 30, 27, 27, 22, 12, 3, -3, -4, -1, 4, 8, 8, 5, -4, -15, -21,
+ -21, -25, -41, -58, -69, -71, -70, -64, -51, -35, -23, -9, 5, 10, 1, -13,
+ -17, -15, -19, -32, -46, -54, -54, -51, -50, -52, -55, -53, -40, -22, -6, 3,
+ 4, -2, -10, -19, -32, -47, -49, -32, -11, -3, -10, -20, -20, -10, 2, 7,
+ 5, 2, 10, 28, 42, 41, 29, 16, 10, 11, 11, 7, 6, 17, 35, 45,
+ 39, 26, 18, 19, 26, 37, 47, 53, 56, 61, 73, 81, 76, 68, 65, 65,
+ 59, 46, 36, 31, 28, 25, 19, 9, -1, -6, -4, -1, 2, 8, 9, 0,
+ -10, -15, -14, -18, -32, -46, -57, -68, -74, -71, -61, -51, -41, -23, -2, 8,
+ 2, -8, -11, -10, -13, -23, -37, -48, -53, -51, -49, -53, -59, -60, -53, -37,
+ -19, -7, -3, -2, -1, -6, -22, -43, -52, -42, -21, -9, -12, -20, -23, -16,
+ -4, 3, -1, -6, 0, 18, 34, 40, 33, 22, 16, 16, 13, 5, 0, 9,
+ 27, 39, 40, 32, 24, 18, 19, 29, 40, 44, 46, 55, 69, 77, 75, 71,
+ 70, 70, 65, 55, 45, 37, 32, 30, 26, 17, 7, 0, -5, -6, -1, 8,
+ 11, 4, -5, -7, -7, -13, -21, -30, -44, -59, -69, -69, -65, -63, -56, -36,
+ -13, 1, 1, -4, -6, -5, -6, -12, -25, -40, -47, -47, -46, -50, -56, -62,
+ -61, -48, -30, -18, -12, -6, 4, 6, -7, -32, -49, -46, -30, -16, -12, -19,
+ -25, -20, -7, 0, -3, -9, -7, 8, 26, 36, 34, 27, 24, 24, 19, 7,
+ -2, 4, 18, 31, 38, 38, 30, 20, 18, 26, 34, 35, 38, 48, 62, 71,
+ 73, 72, 73, 72, 70, 64, 53, 43, 38, 35, 30, 23, 16, 7, -4, -10,
+ -4, 6, 8, 3, -1, -2, -4, -9, -12, -19, -33, -51, -61, -65, -69, -73,
+ -70, -52, -30, -13, -6, -5, -7, -5, -2, -5, -17, -31, -41, -45, -44, -45,
+ -53, -64, -67, -58, -43, -31, -26, -17, -1, 10, 3, -19, -41, -48, -39, -23,
+ -16, -21, -27, -24, -12, -3, -5, -13, -15, -3, 16, 28, 29, 26, 28, 31,
+ 24, 10, 0, 0, 8, 20, 33, 38, 32, 22, 19, 24, 28, 28, 30, 40,
+ 52, 61, 68, 71, 72, 73, 73, 69, 59, 51, 45, 39, 32, 28, 26, 15,
+ 0, -9, -5, 2, 4, 2, 1, -1, -4, -6, -5, -10, -24, -41, -50, -56,
+ -66, -76, -77, -66, -47, -27, -15, -11, -10, -5, 0, -1, -8, -20, -33, -40,
+ -40, -40, -48, -62, -70, -64, -51, -43, -39, -29, -11, 7, 10, -5, -28, -43,
+ -41, -28, -20, -22, -29, -28, -17, -6, -5, -14, -20, -12, 6, 19, 22, 23,
+ 30, 35, 31, 20, 8, 0, 1, 13, 29, 37, 33, 26, 25, 27, 27, 25,
+ 26, 33, 43, 54, 63, 67, 70, 74, 76, 72, 66, 61, 54, 44, 37, 36,
+ 34, 24, 8, -3, -4, -2, 0, 2, 3, -1, -5, -3, 2, -2, -16, -29,
+ -36, -44, -57, -70, -79, -76, -60, -41, -27, -19, -14, -8, -1, 3, 0, -10,
+ -24, -33, -33, -32, -40, -55, -65, -63, -56, -51, -48, -40, -23, -1, 12, 7,
+ -13, -32, -37, -29, -21, -21, -28, -29, -19, -6, -2, -12, -20, -14, 0, 11,
+ 16, 22, 30, 37, 38, 33, 21, 7, 0, 9, 26, 36, 35, 32, 32, 32,
+ 31, 28, 27, 30, 38, 50, 58, 63, 70, 78, 79, 76, 74, 72, 64, 53,
+ 46, 45, 44, 34, 20, 9, 3, -1, 1, 7, 7, 0, -4, 2, 8, 5,
+ -5, -15, -23, -30, -41, -58, -73, -77, -68, -53, -38, -28, -21, -14, -5, 4,
+ 7, -1, -15, -25, -25, -24, -32, -48, -59, -61, -59, -57, -57, -54, -39, -16,
+ 4, 8, -5, -24, -33, -30, -24, -24, -32, -35, -26, -11, -6, -14, -20, -19,
+ -10, -2, 5, 13, 21, 29, 37, 40, 30, 11, 0, 4, 17, 27, 30, 31,
+ 31, 32, 32, 29, 23, 23, 31, 40, 45, 52, 63, 72, 74, 73, 75, 75,
+ 67, 56, 51, 50, 46, 38, 29, 18, 6, -3, -1, 5, 3, -4, -7, -2,
+ 4, 5, -2, -11, -17, -21, -30, -47, -66, -78, -77, -66, -53, -42, -34, -27,
+ -16, -3, 6, 1, -12, -21, -21, -21, -28, -42, -54, -60, -60, -61, -65, -67,
+ -57, -35, -11, 1, -3, -18, -30, -30, -25, -27, -36, -41, -32, -19, -13, -17,
+ -22, -22, -19, -14, -6, 2, 7, 17, 31, 41, 34, 17, 3, 1, 8, 17,
+ 23, 25, 26, 30, 32, 28, 22, 21, 25, 30, 34, 42, 54, 63, 66, 70,
+ 77, 77, 69, 61, 57, 55, 49, 44, 39, 28, 11, 2, 2, 5, 3, -3,
+ -8, -4, 3, 6, 2, -4, -9, -11, -16, -31, -52, -68, -75, -71, -61, -50,
+ -43, -38, -26, -8, 5, 4, -6, -13, -14, -13, -19, -31, -44, -51, -52, -55,
+ -64, -71, -67, -49, -24, -4, -1, -12, -22, -21, -18, -22, -33, -39, -33, -22,
+ -16, -16, -17, -19, -20, -16, -9, -4, -2, 5, 18, 31, 37, 32, 21, 11,
+ 9, 12, 17, 20, 24, 28, 32, 31, 28, 26, 26, 26, 28, 34, 43, 51,
+ 57, 65, 74, 77, 75, 72, 68, 63, 59, 56, 53, 44, 31, 19, 12, 11,
+ 8, 3, -2, -3, 0, 4, 5, 2, 0, -1, -3, -11, -25, -42, -58, -66,
+ -65, -59, -54, -51, -42, -27, -11, -2, -3, -6, -7, -7, -9, -16, -27, -36,
+ -40, -44, -52, -63, -70, -66, -49, -28, -15, -13, -16, -16, -13, -16, -24, -31,
+ -33, -29, -24, -19, -17, -19, -20, -18, -14, -13, -12, -6, 7, 22, 33, 35,
+ 28, 18, 12, 12, 14, 17, 21, 27, 31, 31, 30, 30, 28, 25, 25, 30,
+ 36, 42, 49, 58, 67, 74, 76, 75, 71, 66, 62, 60, 59, 53, 41, 29,
+ 19, 14, 11, 7, 1, -3, -2, 1, 3, 3, 1, 0, 0, -3, -11, -26,
+ -44, -59, -65, -63, -60, -57, -52, -41, -25, -11, -4, -4, -6, -6, -6, -9,
+ -17, -27, -35, -39, -44, -53, -65, -71, -65, -47, -28, -16, -15, -16, -15, -14,
+ -17, -25, -32, -33, -29, -24, -19, -17, -19, -20, -18, -14, -13, -12, -6, -2,
+ 1, 6, 5, 21, 46, 42, 15, 0, 5, 34, 48, 29, -4, -31, -33, -17,
+ 26, 49, 32, 0, -21, -15, 14, 24, 24, 16, 0, 3, 11, 11, 11, 5,
+ 9, 9, 8, 11, 30, 27, 22, 7, -3, -3, 10, 2, -2, -4, -13, -4,
+ -4, -2, -2, -3, -7, -6, -14, -15, -14, -14, -13, -3, -14, -16, -18, -13,
+ -15, -16, -22, -20, -14, -3, -6, -4, -14, -11, -6, -10, -15, -15, -16, -9,
+ -10, -19, -3, -5, -17, -15, -18, -16, -14, -14, -12, -15, -7, -22, -19, -17,
+ -20, -11, -17, -14, -11, -8, -10, -13, -12, -11, -6, -6, -9, 1, 1, -3,
+ 0, 6, -2, -9, 7, -8, 8, 4, 3, 1, -6, -2, -2, 2, -5, -7,
+ -4, -7, -8, -9, -6, -6, 0, -8, -12, -12, -13, -8, -4, -7, -3, -11,
+ -6, -15, -7, -9, -9, -3, -10, -8, -9, -15, -10, -2, 2, -7, -16, -17,
+ -15, -13, -9, -6, -5, -7, -9, -15, -17, -12, -19, -12, -8, -8, -4, -6,
+ -3, 0, -4, -11, -13, -7, -6, -2, 4, 4, 8, 10, 4, 3, 3, 4,
+ 7, 12, 11, 14, 15, 20, 20, 18, 16, 17, 15, 14, 15, 22, 23, 28,
+ 34, 29, 28, 17, 22, 24, 23, 25, 28, 28, 30, 24, 19, 16, 13, 18,
+ 20, 15, 8, 2, 3, 0, 2, 0, -3, -2, -9, -20, -23, -25, -24, -23,
+ -27, -33, -38, -39, -44, -36, -42, -44, -48, -53, -54, -56, -52, -50, -40, -35,
+ -44, -43, -44, -39, -28, -24, -23, -22, -15, -9, 2, 11, 19, 28, 31, 31,
+ 32, 35, 43, 61, 70, 78, 81, 73, 78, 78, 78, 85, 82, 85, 88, 87,
+ 84, 83, 83, 79, 74, 62, 49, 45, 42, 43, 44, 38, 30, 18, 6, -5,
+ -15, -17, -15, -22, -28, -38, -46, -48, -50, -58, -59, -72, -80, -83, -89, -88,
+ -89, -87, -81, -84, -93, -105, -110, -109, -110, -102, -96, -82, -65, -62, -60, -60,
+ -60, -51, -43, -37, -28, -16, 1, 15, 28, 35, 41, 46, 53, 56, 60, 66,
+ 77, 91, 101, 102, 101, 99, 104, 103, 97, 91, 86, 90, 91, 86, 85, 79,
+ 75, 71, 59, 48, 39, 35, 33, 32, 28, 22, 15, 13, 7, 3, -7, -15,
+ -16, -18, -19, -23, -28, -29, -33, -37, -47, -52, -56, -63, -61, -70, -67, -70,
+ -72, -72, -80, -93, -91, -99, -103, -96, -108, -105, -109, -112, -94, -81, -73, -67,
+ -71, -77, -69, -63, -57, -38, -27, -15, 0, 4, 6, 19, 26, 41, 53, 49,
+ 56, 58, 69, 84, 91, 95, 101, 103, 98, 93, 85, 87, 102, 102, 103, 95,
+ 81, 78, 78, 71, 66, 60, 51, 50, 44, 39, 34, 34, 32, 27, 15, 0,
+ -6, -8, -3, -3, -11, -10, -18, -21, -26, -35, -39, -38, -44, -48, -53, -63,
+ -61, -61, -71, -63, -86, -89, -86, -107, -99, -109, -108, -109, -108, -121, -128, -105,
+ -102, -83, -67, -88, -82, -76, -78, -62, -47, -41, -19, -6, 1, 7, 13, 33,
+ 44, 64, 61, 59, 68, 73, 93, 98, 107, 114, 109, 123, 107, 100, 105, 100,
+ 111, 117, 100, 93, 92, 86, 85, 80, 70, 59, 58, 47, 38, 41, 33, 40,
+ 38, 25, 16, 1, -2, -3, -3, -4, -10, -16, -12, -21, -28, -28, -36, -38,
+ -39, -52, -61, -61, -67, -63, -65, -76, -77, -86, -95, -95, -107, -109, -112, -112,
+ -121, -121, -122, -105, -79, -80, -71, -80, -84, -73, -70, -56, -43, -28, -10, 6,
+ 11, 17, 31, 43, 63, 69, 69, 65, 77, 88, 101, 113, 112, 127, 122, 122,
+ 115, 104, 112, 116, 122, 117, 106, 99, 97, 96, 94, 86, 75, 70, 61, 53,
+ 44, 41, 46, 47, 45, 28, 19, 9, 5, 9, 1, -8, -14, -20, -24, -26,
+ -28, -29, -36, -39, -42, -45, -41, -42, -45, -46, -49, -47, -50, -55, -53, -61,
+ -63, -67, -83, -78, -89, -91, -88, -100, -93, -108, -110, -110, -115, -90, -100, -91,
+ -80, -91, -73, -62, -60, -41, -33, -36, -25, -16, -9, 8, 18, 35, 40, 57,
+ 61, 66, 95, 94, 106, 114, 105, 117, 111, 117, 118, 115, 120, 111, 109, 111,
+ 104, 102, 106, 93, 88, 76, 66, 63, 52, 53, 31, 27, 25, 5, 12, 1,
+ -5, 0, -15, -17, -23, -27, -27, -31, -31, -37, -44, -41, -43, -43, -35, -45,
+ -43, -41, -50, -49, -51, -57, -58, -62, -72, -76, -79, -81, -82, -86, -92, -94,
+ -100, -109, -110, -102, -99, -96, -83, -96, -83, -67, -73, -45, -41, -42, -27, -27,
+ -19, -5, 7, 14, 30, 44, 46, 57, 75, 84, 98, 108, 102, 112, 114, 110,
+ 120, 115, 116, 117, 108, 112, 107, 104, 108, 99, 96, 90, 73, 69, 66, 57,
+ 48, 36, 26, 18, 13, 6, -3, 3, -8, -14, -15, -26, -25, -26, -33, -33,
+ -40, -45, -45, -45, -42, -43, -44, -45, -48, -46, -55, -57, -58, -62, -67, -73,
+ -78, -80, -81, -82, -89, -93, -99, -106, -108, -115, -100, -95, -103, -77, -91, -85,
+ -59, -63, -48, -32, -36, -33, -18, -14, -6, 11, 21, 27, 47, 55, 56, 81,
+ 92, 96, 114, 106, 111, 116, 110, 121, 113, 115, 115, 105, 111, 106, 101, 103,
+ 100, 92, 84, 74, 66, 60, 58, 43, 29, 29, 13, 9, 10, -6, -2, -6,
+ -16, -18, -22, -27, -30, -30, -35, -44, -43, -46, -46, -42, -44, -48, -45, -46,
+ -50, -54, -51, -61, -63, -61, -85, -76, -80, -94, -75, -98, -97, -93, -111, -103,
+ -106, -97, -97, -90, -79, -93, -73, -64, -67, -39, -38, -41, -20, -20, -12, 11,
+ 10, 30, 40, 48, 62, 62, 85, 91, 99, 111, 101, 112, 111, 113, 120, 112,
+ 119, 111, 108, 114, 101, 102, 104, 89, 91, 79, 63, 67, 56, 52, 41, 29,
+ 26, 12, 14, 3, -5, 1, -14, -15, -19, -27, -24, -30, -31, -34, -43, -43,
+ -45, -48, -40, -48, -48, -45, -51, -49, -53, -56, -57, -63, -69, -76, -86, -80,
+ -86, -90, -87, -98, -101, -101, -108, -103, -88, -96, -88, -77, -89, -70, -60, -56,
+ -39, -34, -30, -26, -11, -4, 6, 26, 27, 42, 54, 57, 72, 86, 95, 105,
+ 107, 108, 112, 109, 116, 118, 112, 117, 108, 109, 107, 104, 103, 99, 97, 83,
+ 77, 71, 57, 60, 49, 35, 30, 21, 11, 11, 4, -2, -3, -13, -17, -22,
+ -24, -28, -29, -29, -39, -39, -44, -44, -41, -45, -44, -50, -49, -49, -56, -50,
+ -60, -62, -55, -82, -70, -82, -90, -80, -95, -95, -100, -105, -112, -112, -93, -102,
+ -91, -81, -91, -77, -60, -65, -45, -33, -40, -25, -21, -14, 5, 10, 30, 35,
+ 49, 61, 61, 87, 94, 102, 109, 109, 112, 112, 116, 117, 116, 118, 116, 106,
+ 113, 108, 101, 110, 96, 91, 84, 69, 66, 58, 54, 38, 29, 26, 12, 11,
+ 6, -2, -2, -8, -16, -20, -23, -27, -28, -33, -34, -44, -43, -43, -47, -39,
+ -44, -47, -43, -47, -49, -50, -52, -57, -58, -68, -75, -76, -83, -86, -86, -91,
+ -97, -98, -103, -109, -102, -91, -99, -84, -81, -93, -65, -66, -60, -37, -42, -33,
+ -25, -18, -9, 6, 16, 28, 41, 49, 57, 68, 84, 93, 102, 106, 106, 110,
+ 107, 116, 114, 111, 119, 106, 111, 108, 101, 104, 99, 94, 85, 76, 68, 61,
+ 56, 49, 34, 28, 21, 10, 10, 2, -3, -3, -13, -15, -24, -26, -28, -34,
+ -31, -42, -45, -43, -48, -44, -43, -47, -47, -47, -48, -51, -57, -57, -63, -70,
+ -72, -80, -86, -81, -92, -88, -96, -103, -100, -113, -110, -96, -101, -96, -79, -91,
+ -82, -59, -68, -47, -34, -39, -29, -18, -13, -5, 18, 22, 32, 54, 52, 64,
+ 83, 90, 100, 108, 109, 110, 113, 113, 116, 113, 117, 113, 106, 111, 103, 100,
+ 101, 98, 86, 82, 73, 59, 61, 53, 36, 34, 24, 12, 10, 5, -5, -3,
+ -8, -17, -18, -24, -27, -29, -30, -35, -40, -41, -45, -43, -43, -42, -45, -46,
+ -44, -50, -49, -55, -58, -55, -71, -70, -79, -87, -77, -92, -88, -95, -104, -100,
+ -115, -107, -91, -105, -85, -83, -97, -67, -68, -65, -37, -43, -33, -29, -21, -9,
+ 0, 18, 23, 35, 55, 48, 69, 87, 86, 108, 107, 103, 117, 106, 117, 118,
+ 113, 122, 109, 111, 111, 102, 110, 101, 98, 92, 77, 73, 62, 59, 54, 34,
+ 34, 21, 11, 15, 2, 2, 2, -14, -12, -23, -26, -26, -33, -30, -40, -44,
+ -42, -49, -41, -41, -44, -43, -46, -49, -51, -59, -54, -63, -67, -64, -84, -79,
+ -76, -91, -82, -87, -100, -100, -101, -118, -101, -89, -107, -81, -82, -93, -65, -57,
+ -57, -36, -26, -39, -17, -9, -13, 14, 21, 26, 45, 53, 54, 76, 88, 95,
+ 111, 106, 111, 114, 109, 120, 115, 115, 116, 110, 105, 109, 104, 98, 105, 94,
+ 83, 81, 68, 60, 62, 49, 32, 33, 18, 9, 12, 0, -3, -3, -13, -18,
+ -20, -24, -27, -26, -31, -37, -40, -42, -42, -43, -42, -44, -48, -48, -47, -51,
+ -54, -52, -56, -64, -68, -75, -84, -79, -89, -91, -93, -104, -105, -110, -114, -97,
+ -97, -96, -78, -89, -81, -58, -66, -47, -34, -40, -31, -23, -14, -6, 14, 22,
+ 31, 54, 55, 63, 87, 91, 103, 113, 105, 111, 113, 109, 119, 112, 117, 114,
+ 106, 113, 106, 105, 105, 99, 93, 81, 74, 61, 58, 55, 36, 30, 25, 10,
+ 11, 6, -5, 1, -8, -16, -19, -25, -27, -32, -32, -37, -44, -41, -47, -43,
+ -39, -43, -44, -45, -46, -46, -56, -53, -55, -72, -64, -74, -91, -72, -88, -97,
+ -80, -100, -105, -100, -111, -111, -88, -100, -99, -74, -97, -79, -54, -68, -43, -32,
+ -41, -26, -10, -16, 6, 22, 19, 41, 51, 49, 69, 86, 88, 103, 107, 100,
+ 119, 110, 111, 125, 110, 115, 115, 104, 108, 106, 99, 98, 98, 82, 76, 71,
+ 60, 60, 52, 34, 30, 25, 9, 11, 3, -6, 0, -15, -18, -21, -27, -27,
+ -30, -31, -38, -39, -43, -43, -39, -43, -44, -46, -47, -47, -54, -53, -59, -58,
+ -65, -71, -75, -81, -75, -90, -83, -90, -100, -95, -111, -109, -101, -97, -100, -84,
+ -86, -89, -62, -64, -50, -34, -37, -30, -21, -11, -8, 10, 19, 26, 47, 49,
+ 59, 76, 89, 99, 107, 109, 110, 115, 113, 119, 115, 114, 115, 106, 111, 103,
+ 103, 101, 98, 94, 81, 78, 65, 63, 59, 43, 34, 25, 17, 10, 7, -4,
+ -3, -6, -14, -16, -23, -24, -28, -29, -33, -41, -41, -46, -43, -40, -44, -44,
+ -46, -46, -47, -50, -54, -56, -58, -69, -70, -76, -83, -75, -87, -87, -91, -100,
+ -100, -109, -108, -97, -98, -93, -83, -88, -76, -61, -59, -43, -36, -33, -28, -18,
+ -11, -4, 14, 21, 31, 52, 51, 63, 84, 90, 101, 111, 104, 113, 113, 111,
+ 118, 112, 114, 109, 108, 109, 102, 106, 101, 98, 94, 79, 74, 66, 58, 55,
+ 39, 29, 24, 13, 11, 5, -4, 0, -10, -15, -17, -24, -25, -28, -29, -34,
+ -41, -41, -47, -42, -44, -46, -45, -50, -45, -50, -55, -48, -60, -60, -65, -76,
+ -77, -83, -84, -91, -92, -94, -106, -103, -109, -106, -89, -101, -82, -81, -88, -63,
+ -66, -54, -36, -40, -31, -25, -16, -7, 6, 17, 30, 41, 55, 56, 73, 89,
+ 92, 109, 104, 106, 114, 104, 117, 113, 110, 116, 105, 108, 106, 100, 102, 98,
+ 94, 85, 74, 67, 59, 55, 48, 31, 28, 19, 10, 12, 0, 2, -2, -11,
+ -11, -21, -21, -26, -30, -30, -40, -43, -43, -44, -40, -39, -41, -43, -42, -46,
+ -52, -52, -58, -63, -65, -75, -79, -83, -80, -89, -85, -88, -101, -94, -104, -114,
+ -93, -97, -104, -78, -92, -89, -60, -68, -48, -36, -36, -26, -21, -8, -5, 12,
+ 23, 26, 47, 50, 54, 77, 85, 96, 109, 102, 114, 112, 109, 125, 112, 114,
+ 118, 102, 110, 103, 99, 101, 96, 92, 79, 76, 66, 59, 61, 43, 32, 31,
+ 14, 10, 9, -5, -2, -9, -17, -18, -28, -25, -31, -31, -31, -42, -38, -43,
+ -41, -39, -43, -44, -47, -45, -48, -51, -53, -54, -61, -64, -67, -77, -76, -82,
+ -81, -89, -93, -97, -106, -108, -105, -96, -99, -88, -82, -92, -67, -64, -60, -38,
+ -38, -36, -24, -20, -16, 4, 11, 21, 36, 46, 53, 66, 85, 88, 103, 108,
+ 102, 115, 107, 112, 115, 109, 114, 104, 106, 106, 99, 102, 101, 92, 89, 81,
+ 67, 66, 58, 47, 39, 28, 21, 11, 12, 2, -2, 2, -12, -12, -17, -25,
+ -24, -29, -30, -36, -39, -41, -41, -41, -39, -41, -44, -44, -47, -51, -52, -54,
+ -59, -63, -65, -75, -79, -75, -90, -81, -89, -99, -92, -109, -109, -105, -99, -97,
+ -92, -80, -90, -71, -58, -60, -37, -32, -37, -19, -15, -14, 9, 14, 23, 42,
+ 46, 56, 67, 83, 96, 100, 111, 106, 111, 114, 111, 117, 111, 112, 109, 103,
+ 107, 100, 99, 103, 92, 88, 82, 65, 66, 59, 48, 39, 27, 22, 12, 9,
+ 5, -5, 0, -12, -16, -17, -26, -25, -26, -31, -34, -40, -41, -41, -41, -40,
+ -42, -47, -43, -46, -46, -52, -50, -52, -61, -59, -74, -75, -77, -83, -84, -91,
+ -92, -105, -100, -106, -109, -81, -103, -86, -73, -96, -64, -62, -59, -38, -39, -36,
+ -28, -15, -11, 3, 18, 25, 37, 53, 53, 67, 89, 85, 106, 103, 98, 115,
+ 99, 114, 115, 103, 116, 103, 104, 109, 98, 101, 98, 91, 84, 75, 67, 60,
+ 55, 50, 31, 28, 20, 7, 15, 0, -3, 2, -15, -12, -19, -25, -24, -32,
+ -32, -38, -44, -44, -45, -42, -41, -44, -43, -46, -44, -44, -58, -48, -63, -67,
+ -63, -87, -75, -83, -90, -81, -94, -95, -95, -107, -109, -99, -95, -99, -85, -85,
+ -90, -68, -62, -60, -36, -34, -39, -15, -13, -9, 14, 15, 29, 42, 50, 55,
+ 68, 87, 91, 101, 107, 106, 110, 113, 114, 115, 114, 112, 108, 105, 106, 98,
+ 98, 100, 88, 84, 75, 63, 63, 57, 46, 34, 28, 18, 10, 8, 0, -5,
+ -5, -15, -19, -20, -26, -26, -26, -31, -36, -40, -42, -43, -42, -39, -44, -44,
+ -42, -44, -47, -51, -52, -54, -65, -63, -76, -81, -68, -93, -84, -85, -104, -92,
+ -105, -109, -95, -95, -96, -84, -82, -84, -64, -64, -52, -39, -37, -33, -23, -11,
+ -9, 10, 20, 25, 49, 46, 60, 76, 82, 98, 101, 104, 110, 108, 108, 116,
+ 111, 111, 113, 104, 108, 106, 101, 98, 99, 92, 80, 79, 63, 61, 59, 41,
+ 35, 27, 18, 13, 9, 2, 0, -5, -12, -15, -20, -22, -26, -27, -30, -38,
+ -39, -42, -40, -39, -40, -40, -45, -43, -47, -49, -54, -53, -57, -70, -59, -80,
+ -77, -72, -93, -75, -91, -99, -93, -105, -108, -97, -92, -99, -80, -84, -84, -61,
+ -59, -49, -35, -28, -34, -14, -9, -10, 19, 17, 27, 47, 47, 61, 72, 87,
+ 95, 105, 104, 110, 111, 109, 117, 109, 111, 109, 103, 103, 102, 97, 95, 100,
+ 85, 81, 77, 61, 64, 55, 42, 34, 26, 17, 10, 9, -3, -2, -5, -13,
+ -15, -20, -23, -27, -27, -32, -37, -38, -41, -40, -41, -39, -43, -43, -40, -48,
+ -47, -49, -55, -61, -59, -70, -80, -69, -87, -83, -79, -97, -89, -98, -101, -107,
+ -96, -93, -101, -77, -90, -84, -62, -63, -49, -36, -34, -30, -15, -12, -2, 11,
+ 20, 32, 39, 53, 56, 71, 87, 89, 103, 101, 109, 109, 109, 118, 106, 114,
+ 111, 101, 107, 102, 93, 99, 94, 84, 85, 71, 65, 62, 54, 45, 32, 30,
+ 16, 12, 8, -5, -2, -9, -14, -16, -24, -22, -27, -29, -31, -38, -41, -38,
+ -44, -42, -41, -47, -45, -44, -48, -50, -50, -52, -62, -57, -69, -79, -69, -83,
+ -88, -78, -99, -97, -92, -109, -106, -91, -100, -93, -76, -91, -80, -60, -66, -48,
+ -37, -38, -32, -18, -15, -4, 11, 14, 31, 42, 48, 60, 69, 85, 94, 96,
+ 102, 107, 103, 109, 115, 104, 112, 109, 100, 106, 103, 95, 97, 96, 84, 82,
+ 73, 60, 62, 54, 41, 33, 27, 17, 14, 7, 0, 0, -8, -11, -16, -23,
+ -23, -29, -29, -32, -39, -40, -40, -40, -41, -40, -46, -48, -45, -50, -51, -54,
+ -56, -64, -63, -71, -78, -73, -84, -82, -87, -95, -93, -102, -102, -108, -95, -96,
+ -95, -76, -90, -77, -57, -61, -42, -33, -35, -26, -13, -14, 3, 15, 17, 36,
+ 45, 54, 60, 80, 89, 96, 108, 101, 111, 110, 109, 118, 107, 110, 109, 102,
+ 103, 103, 95, 97, 96, 83, 82, 70, 60, 61, 51, 38, 28, 23, 11, 8,
+ 4, -7, -3, -10, -16, -17, -22, -25, -27, -29, -35, -38, -43, -42, -41, -40,
+ -39, -43, -42, -44, -45, -46, -53, -51, -55, -68, -65, -75, -79, -77, -88, -83,
+ -94, -93, -101, -105, -96, -96, -92, -85, -85, -83, -71, -64, -57, -41, -41, -31,
+ -27, -17, -7, 2, 18, 23, 38, 48, 51, 68, 78, 91, 98, 102, 106, 108,
+ 110, 112, 115, 110, 115, 107, 107, 108, 99, 102, 97, 94, 87, 76, 70, 63,
+ 60, 49, 39, 30, 22, 16, 8, 4, 0, -4, -10, -14, -20, -24, -25, -31,
+ -30, -37, -41, -40, -41, -38, -39, -40, -42, -41, -43, -48, -44, -55, -58, -57,
+ -71, -71, -73, -78, -79, -80, -88, -89, -95, -99, -103, -101, -88, -98, -85, -79,
+ -90, -62, -60, -54, -35, -35, -27, -21, -9, -3, 7, 22, 26, 38, 52, 54,
+ 67, 87, 89, 101, 105, 103, 114, 107, 117, 112, 107, 116, 100, 105, 103, 94,
+ 98, 93, 87, 80, 73, 65, 59, 56, 45, 31, 28, 19, 6, 10, -3, -5,
+ -4, -17, -16, -22, -24, -25, -30, -28, -39, -37, -40, -44, -40, -44, -46, -46,
+ -47, -51, -50, -55, -55, -60, -67, -65, -81, -75, -78, -93, -78, -97, -101, -94,
+ -113, -104, -92, -96, -91, -79, -86, -79, -58, -58, -49, -34, -34, -33, -14, -12,
+ -5, 20, 19, 34, 49, 49, 66, 76, 91, 98, 98, 105, 104, 107, 111, 110,
+ 109, 108, 108, 103, 101, 102, 97, 95, 96, 80, 75, 71, 56, 58, 49, 33,
+ 28, 20, 13, 7, 4, -4, -7, -9, -18, -22, -22, -28, -30, -30, -38, -41,
+ -41, -43, -40, -41, -40, -44, -43, -45, -48, -49, -55, -55, -59, -67, -66, -82,
+ -70, -81, -86, -78, -101, -92, -98, -111, -98, -95, -95, -89, -76, -91, -70, -56,
+ -61, -38, -34, -33, -25, -12, -10, 1, 21, 15, 39, 47, 48, 68, 75, 90,
+ 97, 101, 103, 106, 106, 110, 111, 104, 111, 101, 99, 103, 96, 94, 95, 92,
+ 75, 79, 64, 55, 64, 43, 36, 30, 17, 13, 9, 3, -4, -3, -12, -16,
+ -18, -23, -25, -26, -29, -35, -38, -42, -40, -39, -41, -38, -48, -42, -45, -50,
+ -49, -52, -57, -63, -57, -78, -76, -67, -94, -75, -88, -100, -92, -103, -106, -97,
+ -88, -96, -81, -77, -85, -60, -55, -51, -35, -30, -33, -19, -9, -10, 17, 16,
+ 30, 46, 48, 64, 72, 86, 96, 101, 104, 105, 111, 104, 116, 109, 107, 110,
+ 104, 101, 104, 100, 93, 100, 86, 77, 78, 59, 60, 54, 40, 32, 23, 18,
+ 9, 9, 0, -5, -6, -14, -17, -20, -23, -25, -26, -31, -35, -39, -40, -36,
+ -40, -37, -40, -45, -42, -45, -48, -51, -50, -57, -64, -62, -76, -78, -71, -90,
+ -84, -88, -101, -97, -105, -108, -94, -97, -92, -81, -87, -76, -63, -58, -42, -36,
+ -33, -27, -15, -10, -2, 18, 19, 34, 49, 47, 66, 78, 86, 102, 104, 104,
+ 111, 109, 112, 115, 112, 110, 108, 106, 101, 102, 98, 96, 97, 86, 79, 72,
+ 62, 61, 51, 39, 32, 20, 15, 10, 2, 1, -4, -9, -13, -18, -22, -24,
+ -25, -29, -33, -37, -41, -39, -37, -39, -39, -43, -46, -46, -49, -49, -56, -54,
+ -57, -68, -66, -73, -77, -79, -83, -90, -96, -95, -107, -110, -98, -97, -98, -76,
+ -87, -83, -56, -68, -49, -34, -43, -28, -26, -18, -8, 3, 14, 22, 39, 47,
+ 54, 70, 83, 90, 101, 100, 104, 107, 102, 113, 103, 106, 109, 95, 106, 99,
+ 95, 101, 92, 93, 83, 74, 66, 60, 56, 44, 33, 26, 17, 12, 8, 1,
+ 2, -4, -11, -10, -21, -19, -25, -29, -28, -39, -38, -41, -41, -37, -40, -42,
+ -43, -42, -45, -47, -48, -56, -52, -59, -69, -67, -78, -78, -79, -88, -86, -95,
+ -100, -99, -112, -95, -92, -101, -77, -86, -86, -62, -65, -51, -39, -35, -31, -26,
+ -8, -11, 7, 26, 21, 45, 53, 50, 76, 86, 90, 105, 102, 105, 109, 108,
+ 115, 107, 112, 110, 100, 108, 100, 96, 100, 93, 89, 79, 72, 64, 58, 56,
+ 42, 31, 28, 14, 10, 9, -5, -2, -6, -14, -15, -22, -22, -27, -28, -31,
+ -41, -37, -41, -42, -37, -41, -45, -43, -45, -47, -48, -49, -58, -53, -64, -71,
+ -68, -82, -75, -83, -91, -87, -103, -97, -104, -111, -90, -98, -95, -77, -91, -76,
+ -61, -63, -43, -41, -35, -29, -23, -7, -7, 13, 22, 24, 50, 50, 59, 82,
+ 82, 99, 102, 100, 110, 105, 111, 113, 104, 114, 103, 104, 107, 96, 102, 97,
+ 92, 90, 77, 73, 64, 58, 53, 38, 31, 23, 13, 12, 3, 0, -2, -11,
+ -10, -17, -21, -20, -29, -27, -33, -40, -38, -44, -39, -39, -43, -41, -42, -42,
+ -46, -42, -53, -53, -52, -71, -67, -73, -83, -80, -81, -89, -93, -91, -100, -106,
+ -97, -96, -93, -88, -81, -85, -79, -59, -58, -48, -30, -36, -28, -11, -9, -2,
+ 21, 22, 32, 50, 52, 58, 79, 89, 90, 104, 104, 100, 113, 111, 109, 114,
+ 109, 107, 103, 104, 99, 94, 97, 91, 78, 79, 65, 58, 61, 47, 37, 30,
+ 23, 14, 10, 7, -7, -4, -8, -21, -17, -23, -30, -26, -30, -36, -37, -39,
+ -38, -38, -36, -38, -45, -41, -45, -49, -51, -56, -57, -63, -64, -69, -78, -70,
+ -80, -84, -84, -91, -100, -98, -106, -108, -90, -103, -90, -80, -93, -65, -64, -52,
+ -38, -37, -27, -26, -12, -6, 3, 18, 22, 36, 48, 54, 69, 84, 89, 105,
+ 103, 106, 117, 105, 117, 113, 106, 113, 101, 105, 101, 99, 98, 93, 94, 83,
+ 75, 70, 60, 55, 49, 33, 27, 19, 10, 8, -2, -2, -7, -13, -12, -22,
+ -20, -23, -28, -28, -35, -39, -40, -41, -40, -42, -40, -43, -42, -42, -44, -46,
+ -49, -52, -59, -60, -70, -74, -71, -84, -82, -88, -96, -98, -100, -105, -102, -88,
+ -95, -83, -79, -87, -62, -62, -52, -40, -39, -31, -27, -14, -10, 7, 17, 25,
+ 42, 49, 59, 72, 85, 92, 103, 103, 102, 111, 104, 113, 110, 104, 112, 102,
+ 107, 103, 101, 99, 97, 92, 81, 76, 64, 61, 54, 42, 33, 24, 17, 11,
+ 8, -2, -2, -5, -13, -12, -22, -23, -26, -31, -32, -38, -40, -43, -39, -40,
+ -41, -40, -44, -41, -44, -47, -51, -49, -62, -55, -68, -78, -68, -89, -79, -81,
+ -96, -85, -101, -100, -103, -98, -91, -97, -79, -83, -87, -61, -64, -55, -31, -41,
+ -29, -15, -19, 3, 9, 18, 33, 36, 56, 54, 71, 87, 87, 103, 103, 103,
+ 110, 107, 113, 112, 108, 111, 101, 104, 103, 92, 101, 92, 84, 84, 66, 65,
+ 59, 51, 45, 31, 27, 16, 10, 6, -3, -3, -9, -15, -16, -22, -24, -25,
+ -30, -28, -36, -40, -36, -42, -38, -41, -45, -44, -47, -47, -49, -51, -52, -54,
+ -62, -68, -73, -78, -81, -84, -83, -97, -94, -101, -113, -100, -99, -96, -87, -83,
+ -85, -75, -60, -60, -43, -36, -38, -27, -20, -15, 0, 14, 19, 33, 47, 49,
+ 67, 78, 90, 100, 103, 105, 107, 108, 110, 112, 109, 109, 107, 102, 105, 100,
+ 99, 98, 95, 84, 80, 69, 59, 60, 48, 36, 31, 18, 14, 9, 3, -2,
+ -5, -10, -15, -19, -24, -25, -28, -31, -34, -39, -41, -40, -38, -40, -38, -43,
+ -43, -42, -48, -47, -53, -54, -58, -67, -63, -79, -73, -78, -90, -80, -98, -97,
+ -101, -109, -105, -93, -98, -90, -76, -93, -66, -60, -59, -33, -42, -32, -26, -18,
+ -9, 0, 17, 21, 38, 48, 53, 69, 82, 93, 101, 107, 102, 112, 108, 111,
+ 115, 105, 112, 103, 105, 104, 96, 103, 95, 95, 85, 76, 68, 63, 59, 47,
+ 38, 26, 19, 13, 7, 1, -3, -4, -14, -12, -19, -23, -21, -29, -29, -35,
+ -40, -41, -42, -39, -43, -42, -46, -43, -47, -45, -48, -54, -47, -66, -61, -68,
+ -85, -66, -90, -84, -84, -103, -91, -106, -105, -96, -90, -92, -81, -79, -86, -59,
+ -59, -53, -34, -36, -33, -19, -10, -10, 17, 20, 26, 52, 48, 60, 75, 85,
+ 95, 102, 104, 102, 111, 107, 113, 110, 109, 111, 103, 107, 102, 97, 96, 95,
+ 85, 77, 73, 56, 60, 52, 37, 33, 22, 16, 11, 7, -3, -4, -6, -16,
+ -14, -21, -24, -24, -28, -32, -37, -38, -42, -36, -37, -39, -39, -43, -40, -42,
+ -48, -50, -50, -64, -57, -70, -84, -63, -90, -81, -77, -101, -85, -99, -105, -102,
+ -100, -92, -99, -79, -89, -86, -58, -65, -49, -29, -41, -26, -11, -19, 6, 12,
+ 14, 39, 37, 52, 60, 68, 90, 90, 104, 102, 106, 111, 108, 118, 109, 109,
+ 111, 98, 106, 101, 90, 101, 90, 82, 86, 63, 65, 63, 48, 47, 29, 25,
+ 16, 10, 6, -6, -3, -13, -18, -16, -26, -25, -25, -32, -30, -39, -43, -37,
+ -43, -39, -39, -48, -44, -46, -53, -50, -56, -59, -59, -67, -72, -77, -76, -84,
+ -83, -84, -100, -95, -103, -115, -98, -93, -103, -82, -82, -91, -60, -62, -54, -34,
+ -35, -31, -23, -13, -11, 7, 19, 21, 43, 48, 55, 73, 85, 94, 104, 102,
+ 109, 110, 105, 118, 107, 109, 113, 98, 106, 103, 96, 99, 98, 90, 82, 79,
+ 62, 62, 58, 41, 34, 26, 14, 10, 8, -3, -2, -5, -14, -13, -20, -20,
+ -24, -26, -28, -38, -39, -42, -42, -41, -41, -42, -48, -41, -43, -50, -41, -49,
+ -59, -50, -68, -74, -67, -82, -80, -89, -87, -101, -101, -93, -121, -85, -90, -105,
+ -65, -93, -82, -55, -69, -49, -38, -46, -32, -27, -19, -5, 3, 19, 26, 41,
+ 53, 52, 81, 81, 95, 104, 90, 113, 101, 105, 118, 99, 113, 109, 100, 109,
+ 104, 98, 104, 96, 89, 83, 71, 66, 57, 56, 38, 28, 29, 8, 17, 6,
+ -2, 3, -24, -13, -79, -103, -120, -116, -104, -87, -76, -63, 63, 82, 97, 108,
+ 119, 99, 70, 69, 80, 91, 92, 98, 115, 124, 127, 113, 82, 42, 4, -44,
+ -70, -82, -100, -87, -62, -58, -71, -65, -79, -60, -102, -113, -62, -44, -31, -31,
+ -22, -18, -3, 4, 11, 20, 28, 11, 15, 18, 27, 18, 7, 13, 26, 11,
+ -19, -69, -108, -84, -51, -21, -3, -6, -18, -17, -31, -33, -18, 2, 4, 26,
+ 47, 48, 77, 117, 127, 127, 127, 121, 110, 86, 72, 62, 46, 11, 17, -2,
+ -7, -13, -44, -60, -61, -61, -63, -72, -79, -99, -116, -127, -128, -128, -124, -81,
+ -51, -4, 5, -6, 7, 8, 9, 31, 31, 16, 34, 28, 34, 34, 46, 78,
+ 84, 93, 69, 47, 40, 64, 44, 27, 22, 0, -29, -8, 15, -6, -36, -66,
+ -68, -42, 0, 6, 1, 13, 24, 41, 64, 58, 50, 40, 4, 0, 3, -24,
+ -3, 21, 28, 26, 9, -30, -42, -61, -85, -92, -91, -96, -87, -74, -31, -20,
+ -38, -14, -44, -17, 18, -25, -9, 7, 1, 11, -2, -19, 12, 47, 76, 72,
+ 58, 68, 69, 82, 86, 76, 58, 9, -23, -12, -7, -22, -2, 0, -9, -2,
+ -15, -10, -3, -22, -17, -38, -44, -33, -24, -27, -16, 0, -15, 20, 19, 18,
+ 1, 10, 41, -1, -25, -25, -11, 30, 37, 9, 45, 37, -30, -30, 21, 5,
+ -26, -43, -56, -42, -48, -48, -29, -62, -76, -42, -23, -12, -14, 8, 45, 36,
+ 40, 25, 14, 11, 40, 46, 55, 65, 30, 17, 30, 36, 33, 18, 13, 16,
+ 15, 46, 37, 2, -1, -26, -36, -19, -21, -36, -62, -51, -48, -20, -2, 3,
+ -12, -12, -10, -35, -37, -49, -22, 14, 61, 40, 60, 75, 33, 41, 48, 38,
+ 29, -32, -45, -56, -64, -61, -30, -20, 30, 10, -46, -37, -35, -30, -24, -12,
+ -23, -34, -29, -22, -20, -14, 4, 44, 77, 49, 10, 8, 24, 20, 28, 31,
+ 27, 40, 35, 69, 39, 54, 38, 26, 22, 43, 36, 7, 14, 2, -25, -50,
+ -51, -56, -42, -55, -46, -36, -44, -36, -35, 1, 23, 11, -3, -34, -66, -33,
+ -12, -31, -27, -13, -1, 21, 31, 23, 0, -11, -3, -2, 9, 27, 5, -8,
+ -2, -17, -13, 10, 9, 3, 35, 32, 43, 24, 15, 2, -15, -9, -5, 2,
+ 5, 27, 25, 42, 76, 61, 17, 25, 14, -5, -17, -24, -6, 11, 23, 7,
+ -8, 5, -11, -23, -27, -48, -30, -12, -26, -36, -37, -39, -46, -61, -55, -23,
+ -20, -22, -14, -10, -16, -16, -22, -11, -3, -14, -34, -16, 9, 28, 25, 50,
+ 63, 52, 56, 46, 50, 54, 56, 45, 54, 29, 20, 21, 0, 0, 6, 16,
+ 28, 14, -1, -9, -10, -4, -9, -13, -7, -21, -27, -29, -40, -41, -35, -42,
+ -64, -11, 9, 2, -12, -24, -37, -40, -34, -29, -34, -12, -26, -20, -6, -4,
+ 5, 5, 27, 1, -17, 2, 21, 12, 8, 9, 15, 23, 24, 1, 5, 22,
+ 25, 28, 57, 55, 41, 33, 36, 27, 5, 1, 15, 34, 23, 4, 20, 18,
+ -1, -21, -22, -15, -17, -8, -6, -6, -12, -15, -26, 1, 29, -8, -40, -52,
+ -55, -19, -21, -36, -48, -56, -29, -15, -29, -39, -46, -35, -14, -11, -16, 1,
+ 27, 22, -10, -14, -7, -12, -12, 23, 55, 48, 65, 42, 20, 46, 45, 49,
+ 42, 38, 34, 25, 33, 21, 10, 38, 40, 26, 22, 37, 33, 12, 4, 7,
+ -14, -49, -41, -36, -53, -40, -35, -44, -31, -22, -19, -50, -78, -80, -78, -48,
+ -31, -18, -27, -28, -7, -17, -11, 5, 32, 39, 19, 14, 22, 34, 37, 23,
+ 20, 40, 40, 27, 14, 11, 7, 29, 34, 19, 32, 7, -15, -12, -24, -12,
+ 8, 6, 21, 34, 29, -6, -22, -15, 1, -1, 24, 27, 20, 36, 42, 45,
+ 27, -14, -50, -34, -14, -26, -25, -10, 10, -4, -28, -30, -34, -69, -91, -85,
+ -74, -51, -38, -24, -19, -9, -7, -30, -35, -30, -36, -12, 25, 32, 44, 50,
+ 45, 51, 68, 94, 90, 74, 60, 52, 64, 48, 30, 11, 11, 11, 2, 14,
+ 24, 16, 13, -7, -17, -9, -12, -20, -32, -45, -54, -58, -35, -23, -46, -51,
+ -33, -28, -29, -24, -36, -30, -24, -22, -20, -13, -9, -14, -7, 10, 26, 22,
+ 9, 9, 10, -2, -9, -15, -11, -1, 19, 27, 33, 28, 5, 3, 5, 6,
+ 10, 14, 24, 32, 36, 40, 41, 37, 19, 11, 3, -7, -10, -7, 6, 27,
+ 38, 28, 23, 16, 18, 15, -7, -33, -20, -13, -24, -25, -19, -15, -26, -52,
+ -56, -48, -41, -36, -30, -32, -30, -15, -38, -49, -47, -32, -17, -17, -11, -3,
+ 3, 8, 24, 28, 16, 6, 1, 7, 28, 41, 42, 69, 87, 78, 73, 62,
+ 30, 14, 9, 7, 15, 32, 20, 10, -8, -20, 2, 9, -2, 5, 12, -4,
+ -12, -19, -32, -37, -29, -24, -28, -39, -43, -40, -44, -28, -25, -33, -39, -37,
+ -34, -29, -28, -25, -19, -1, -5, -22, -12, 2, 6, 38, 46, 25, 30, 41,
+ 47, 37, 21, 7, -7, -8, 11, 39, 48, 43, 35, 27, 25, 22, -1, -22,
+ -11, 13, -4, -13, -3, -8, -7, -11, -17, -5, 5, 9, 8, 15, 25, 16,
+ 22, 20, 5, -16, -27, -29, -30, -9, 9, 9, 3, -14, -50, -56, -56, -79,
+ -92, -80, -57, -24, 12, 10, 11, 4, -22, -21, -13, -2, 4, 10, 15, 8,
+ 35, 72, 53, 44, 25, 25, 48, 56, 69, 53, 50, 75, 85, 71, 33, 12,
+ -16, -32, -25, -14, -5, -16, -23, -19, -22, -39, -41, -47, -45, -33, -35, -39,
+ -38, -35, -34, -29, -28, -28, -23, -10, -7, -9, -11, -18, -5, 13, 1, -13,
+ -8, -5, 6, 27, 46, 43, 25, 8, 11, 16, 18, 23, 30, 12, 5, 10,
+ 7, 5, -6, -4, -5, 1, 10, 9, 15, 21, 17, 10, -8, -16, 10, 33,
+ 34, 23, 13, 17, 17, 9, 11, 7, -4, -8, -8, -22, -27, -26, -19, -7,
+ -18, -16, -16, -47, -62, -55, -36, -16, -25, -33, -30, -34, -42, -49, -41, -43,
+ -31, -20, -3, 28, 48, 66, 64, 36, 20, 26, 21, 22, 39, 51, 45, 39,
+ 40, 53, 56, 39, 24, 16, 12, 16, 24, 27, 16, 13, 7, -18, -33, -50,
+ -47, -33, -24, -20, -26, -32, -31, -46, -53, -58, -56, -29, -13, -11, -2, 8,
+ -11, -24, -11, -9, -6, -2, -6, 1, 4, 5, 11, 6, 7, 16, 30, 28,
+ 19, 15, 7, 4, 11, 27, 22, 6, 9, 11, 3, 4, 17, 27, 18, 11,
+ 12, 5, 2, -2, -6, -7, -2, 10, 12, 9, 1, -2, 3, 4, 11, 21,
+ 30, 28, 6, -9, -18, -22, -22, -38, -41, -27, -18, -18, -27, -27, -23, -32,
+ -35, -32, -34, -30, -25, -24, -18, -9, -5, 5, -5, -26, -19, -11, -4, 11,
+ 37, 48, 46, 50, 53, 50, 45, 45, 37, 18, 24, 44, 38, 43, 47, 29,
+ 15, 11, 10, 12, 4, -8, -6, -4, -17, -27, -28, -36, -34, -37, -53, -53,
+ -46, -38, -38, -37, -28, -24, -23, -37, -42, -30, 0, 20, 18, 12, 14, 9,
+ 2, 6, 15, 13, 10, 14, 12, 2, 12, 29, 21, 1, 7, 21, 19, 14,
+ 15, 15, 4, -1, 5, -1, -4, 0, -2, 3, 6, 6, 13, 21, 15, 7,
+ 3, 5, 2, -3, 3, 3, 5, 8, 10, 16, 14, -1, -7, 2, 11, 12,
+ -10, -35, -42, -26, -21, -37, -44, -44, -47, -42, -27, -27, -23, -15, -16, -20,
+ -21, -14, -12, -9, -7, -6, 0, 13, 30, 32, 37, 38, 31, 24, 25, 43,
+ 54, 49, 46, 44, 40, 41, 30, 9, -1, 6, 22, 31, 22, 9, 0, -14,
+ -23, -29, -29, -28, -35, -39, -39, -39, -33, -25, -30, -44, -49, -45, -45, -35,
+ -19, 2, 16, 16, 9, 0, 0, 6, 2, -1, 11, 27, 40, 32, 16, -2,
+ -2, 1, 3, 1, 7, 12, 6, 8, 11, 5, -1, -2, -1, 1, 8, 10,
+ 5, 4, 14, 17, 6, -1, 0, 4, 4, 17, 23, 19, 25, 20, 5, -8,
+ -9, -2, -1, -6, -3, 13, 16, 1, -13, -19, -21, -26, -34, -37, -23, -13,
+ -13, -24, -40, -42, -40, -39, -29, -22, -21, -18, -12, -2, 18, 24, 10, 0,
+ -6, -4, 15, 33, 34, 34, 44, 41, 31, 33, 44, 43, 31, 22, 20, 17,
+ 16, 23, 22, 19, 21, 10, -5, -6, -9, -8, -2, -5, -16, -28, -36, -47,
+ -53, -39, -23, -21, -24, -32, -43, -39, -34, -24, -18, -14, -11, -12, -6, 10,
+ 29, 41, 40, 27, 14, 10, 4, 1, 3, 2, 9, 19, 21, 9, -10, -16,
+ -10, 8, 18, 20, 13, -3, -8, -4, -1, 2, 5, 5, -1, 3, 9, 12,
+ 16, 16, 14, 9, 3, 5, 10, 4, -6, 1, 6, 5, 13, 20, 11, 1,
+ -7, -21, -30, -25, -12, -9, -13, -19, -24, -29, -34, -30, -32, -39, -33, -24,
+ -20, -22, -24, -13, 3, 6, 2, 1, 3, 5, 16, 30, 35, 35, 24, 16,
+ 15, 19, 31, 37, 33, 28, 29, 29, 30, 26, 20, 15, 13, 10, 10, 12,
+ 9, 7, -3, -21, -39, -44, -43, -42, -34, -26, -23, -18, -12, -18, -32, -36,
+ -31, -27, -20, -10, -7, -9, -11, -5, 2, 12, 19, 19, 25, 24, 11, 3,
+ 15, 29, 30, 20, 9, 1, -1, 1, 5, 2, -3, -2, 0, -6, -18, -27,
+ -20, -3, 8, 13, 15, 11, 7, 10, 18, 16, 10, 6, 3, -1, 1, 11,
+ 19, 19, 15, 14, 5, -2, -2, -7, -12, -15, -20, -16, -10, -5, 2, 1,
+ -13, -29, -33, -24, -10, -6, -13, -18, -23, -31, -32, -26, -22, -18, -13, -3,
+ 2, 3, 7, 8, 10, 19, 27, 32, 33, 33, 35, 38, 43, 41, 29, 9,
+ -4, -9, 2, 16, 17, 13, 15, 17, 13, 10, 5, -1, -8, -18, -29, -32,
+ -27, -21, -22, -30, -31, -31, -33, -31, -27, -18, -7, -6, -15, -16, -8, -1,
+ 4, 12, 18, 22, 20, 16, 11, 10, 14, 18, 16, 15, 14, 9, 6, 4,
+ 3, 3, 0, -5, -13, -18, -15, -13, -9, -7, -8, -5, -2, -5, -1, 5,
+ 8, 10, 11, 12, 17, 19, 16, 10, 4, 4, 8, 8, 8, 13, 14, 9,
+ 3, 0, -1, 0, 0, -7, -19, -24, -20, -15, -12, -15, -21, -23, -24, -26,
+ -28, -29, -28, -21, -10, -1, 5, 6, -3, -12, -14, -11, -1, 12, 16, 17,
+ 28, 36, 28, 20, 25, 27, 24, 25, 28, 21, 15, 11, 3, 4, 12, 11,
+ 0, -7, -5, -1, -1, -5, -8, -11, -17, -23, -22, -19, -21, -20, -20, -22,
+ -24, -22, -17, -20, -24, -20, -10, 2, 10, 13, 14, 14, 11, 8, 8, 12,
+ 17, 18, 20, 20, 14, 4, -1, -2, -1, 3, 11, 12, 6, 0, -9, -20,
+ -25, -18, -9, -8, -13, -18, -19, -14, -6, 0, 4, 11, 19, 22, 20, 19,
+ 15, 13, 14, 18, 17, 12, 7, 9, 14, 9, -1, -4, -1, -5, -10, -12,
+ -16, -23, -19, -7, -5, -10, -10, -11, -19, -27, -24, -14, -6, -3, -10, -21,
+ -24, -15, -6, 0, 9, 15, 12, 8, 6, 9, 9, 11, 20, 26, 31, 35,
+ 30, 21, 16, 16, 13, 6, 2, 4, 5, 3, -2, -10, -13, -11, -8, -9,
+ -13, -16, -18, -18, -19, -22, -18, -8, -3, -1, 0, -5, -11, -10, -9, -11,
+ -9, -2, 2, 4, 10, 15, 18, 19, 21, 21, 22, 22, 15, 4, -4, -8,
+ -7, -6, -10, -14, -18, -23, -20, -15, -8, -1, 0, -4, -7, -9, -9, -6,
+ -2, 2, 6, 7, 4, 1, 0, 7, 13, 11, 14, 22, 22, 15, 8, 2,
+ 4, 10, 16, 17, 13, 10, 9, 6, -3, -13, -23, -26, -21, -17, -14, -12,
+ -13, -16, -14, -9, -8, -8, -11, -18, -18, -12, -4, 0, 2, 6, 6, -1,
+ -6, 0, 8, 11, 13, 11, 6, 6, 9, 13, 16, 16, 15, 10, 7, 10,
+ 10, 4, 0, -2, -3, -1, 2, 2, -1, -5, -13, -21, -27, -30, -26, -16,
+ -4, 5, 8, 6, 2, -3, -5, -1, 4, 8, 9, 11, 11, 6, 0, 0,
+ 7, 12, 13, 11, 7, 1, -4, -3, 0, 5, 6, 5, -2, -10, -13, -13,
+ -10, -5, -4, -9, -18, -28, -31, -24, -14, -10, -4, 2, 5, 4, 2, 4,
+ 13, 20, 21, 19, 14, 11, 11, 12, 13, 14, 15, 17, 18, 18, 14, 5,
+ -3, -5, -8, -11, -11, -12, -15, -15, -13, -13, -15, -13, -12, -15, -16, -11,
+ -7, -6, -4, -1, 4, 6, -1, -10, -11, -7, -4, -1, 4, 9, 11, 12,
+ 9, 7, 8, 8, 7, 9, 13, 15, 12, 4, 1, 1, -2, -9, -10, -7,
+ -1, 3, 3, -1, -9, -12, -9, -5, 1, 3, -2, -10, -10, -7, -4, 2,
+ 8, 6, 4, 6, 5, -1, -1, 7, 17, 20, 17, 16, 19, 16, 7, -3,
+ -8, -9, -9, -11, -15, -24, -27, -20, -15, -12, -11, -7, -3, -4, -6, -7,
+ -6, -8, -14, -18, -18, -15, -10, -5, 3, 12, 18, 20, 17, 11, 10, 16,
+ 21, 22, 23, 23, 22, 17, 9, 0, -3, 2, 10, 15, 16, 11, 2, -9,
+ -19, -23, -22, -15, -10, -8, -11, -13, -15, -17, -19, -18, -15, -10, -3, 1,
+ -2, -6, -3, 0, -3, -3, 0, 6, 10, 9, 7, 4, -1, -4, 0, 10,
+ 17, 16, 11, 5, 0, -1, 2, 5, 1, -6, -10, -10, -8, -6, -4, -2,
+ -4, -7, -9, -9, -6, 2, 12, 17, 16, 11, 8, 7, 6, 5, 7, 9,
+ 12, 14, 14, 9, 3, -1, -3, -5, -4, 0, 4, -1, -10, -18, -24, -29,
+ -28, -20, -14, -13, -12, -8, -5, -5, -9, -13, -14, -11, -10, -9, -4, 1,
+ 3, 2, 3, 8, 16, 20, 18, 13, 10, 14, 24, 29, 29, 27, 23, 17,
+ 14, 16, 17, 15, 9, -1, -7, -10, -14, -18, -16, -11, -8, -7, -8, -12,
+ -18, -26, -29, -26, -19, -11, -5, -3, -3, -2, 0, 2, 0, -3, -3, -2,
+ -3, -4, -2, -1, 3, 7, 9, 8, 7, 3, 1, 4, 5, 2, 3, 5,
+ 5, 0, -7, -9, -6, -1, 5, 9, 8, 3, -2, -6, -5, 3, 9, 12,
+ 11, 8, 4, 3, 4, 6, 11, 13, 8, 1, 0, 4, 9, 13, 12, 5,
+ 2, 3, 3, 0, -6, -16, -26, -30, -28, -26, -22, -18, -17, -19, -22, -24,
+ -19, -12, -7, -2, 1, 0, -2, -4, -5, -2, 4, 10, 14, 15, 15, 16,
+ 16, 17, 19, 22, 26, 25, 19, 13, 10, 7, 9, 11, 10, 7, 4, 1,
+ -5, -8, -8, -4, 0, 1, -4, -11, -16, -17, -16, -14, -12, -10, -11, -14,
+ -15, -16, -13, -9, -3, 1, 2, 1, 0, 0, -3, -9, -13, -10, -8, -7,
+ -4, 0, 3, 6, 9, 9, 5, 3, 3, 5, 8, 12, 12, 6, -1, -2,
+ 2, 8, 8, 4, -2, -5, -1, 4, 10, 13, 14, 13, 13, 14, 14, 12,
+ 10, 8, 8, 8, 6, 6, 9, 6, -1, -9, -15, -19, -22, -24, -23, -25,
+ -25, -23, -20, -19, -19, -21, -20, -20, -21, -19, -11, -2, 2, 1, 0, 3,
+ 9, 13, 15, 16, 14, 10, 5, 3, 8, 14, 16, 18, 20, 22, 24, 21,
+ 15, 9, 6, 8, 14, 18, 15, 9, 4, 1, 0, -2, -4, -4, -3, -3,
+ -4, -7, -11, -13, -12, -11, -15, -19, -22, -25, -25, -21, -14, -11, -15, -19,
+ -18, -14, -7, -1, 4, 2, -3, -6, -4, 0, 5, 10, 16, 17, 12, 7,
+ 2, -1, -3, 0, 3, 6, 10, 14, 12, 6, 2, 5, 10, 15, 18, 18,
+ 16, 14, 11, 6, 4, 3, 1, 1, 2, 6, 9, 9, 3, -2, -3, -4,
+ -6, -8, -10, -15, -19, -20, -19, -18, -17, -15, -16, -17, -18, -20, -22, -21,
+ -16, -11, -4, 1, 0, -4, -4, -1, 1, 2, 4, 4, 3, 3, 4, 7,
+ 11, 16, 21, 20, 15, 11, 9, 12, 16, 21, 24, 23, 21, 17, 13, 11,
+ 9, 4, 0, 0, 1, 3, 4, 0, -4, -7, -7, -9, -13, -17, -20, -22,
+ -23, -21, -16, -12, -12, -15, -17, -17, -15, -12, -10, -10, -11, -12, -15, -15,
+ -10, -4, 0, -1, -1, 1, 4, 7, 13, 19, 22, 23, 21, 19, 18, 17,
+ 11, 5, 2, 5, 10, 13, 15, 15, 14, 13, 10, 5, 1, 0, 2, 5,
+ 8, 10, 9, 6, 4, 2, -1, -5, -7, -8, -7, -8, -11, -13, -14, -16,
+ -19, -21, -22, -22, -24, -23, -20, -17, -16, -16, -15, -16, -16, -15, -13, -11,
+ -9, -5, 0, 6, 12, 15, 18, 18, 17, 17, 19, 20, 19, 19, 20, 23,
+ 25, 25, 23, 20, 17, 13, 11, 9, 9, 8, 6, 3, 1, -2, -5, -5,
+ -2, -1, -3, -7, -6, -3, 0, -2, -9, -21, -29, -32, -32, -30, -27, -27,
+ -29, -30, -28, -24, -23, -21, -16, -7, 0, 1, 2, 2, 4, 7, 10, 14,
+ 16, 14, 12, 13, 15, 18, 20, 22, 23, 20, 15, 8, 3, 2, 7, 13,
+ 15, 13, 7, 2, 0, 0, -1, -2, -1, 1, 2, 1, 0, 2, 3, 4,
+ 4, 6, 7, 5, 0, -10, -21, -30, -36, -36, -33, -28, -23, -18, -15, -14,
+ -17, -19, -19, -17, -12, -5, -2, -2, -3, -1, 2, 6, 10, 12, 14, 13,
+ 12, 13, 18, 25, 29, 28, 24, 19, 14, 10, 6, 6, 9, 12, 13, 15,
+ 17, 18, 18, 14, 7, 0, -1, 1, 1, -2, -6, -8, -10, -11, -13, -17,
+ -19, -18, -17, -16, -14, -14, -15, -17, -19, -22, -26, -26, -24, -20, -17, -14,
+ -13, -12, -10, -7, -4, 1, 5, 7, 9, 10, 13, 15, 17, 18, 21, 24,
+ 22, 21, 19, 17, 15, 13, 14, 14, 16, 17, 18, 16, 12, 10, 8, 6,
+ 5, 3, 0, -3, -6, -7, -5, -4, -4, -5, -5, -4, -4, -4, -8, -13,
+ -19, -24, -27, -28, -27, -25, -25, -27, -27, -25, -19, -14, -8, -3, 1, 6,
+ 9, 8, 3, -3, -6, -4, -1, 4, 9, 14, 18, 20, 22, 22, 23, 23,
+ 22, 21, 20, 20, 21, 21, 19, 15, 9, 3, -2, -4, -3, 0, 2, 2,
+ 2, 3, 3, 1, -4, -10, -15, -19, -19, -16, -11, -7, -7, -9, -13, -17,
+ -23, -28, -30, -29, -24, -20, -18, -19, -20, -19, -18, -19, -18, -13, -5, 1,
+ 6, 9, 11, 13, 16, 21, 26, 29, 30, 29, 29, 28, 26, 23, 20, 20,
+ 21, 21, 20, 18, 15, 9, 2, -4, -6, -5, -3, -3, -4, -6, -7, -9,
+ -10, -10, -10, -10, -11, -13, -12, -11, -8, -6, -6, -10, -17, -26, -32, -35,
+ -35, -34, -32, -27, -19, -9, -3, -1, -2, -5, -7, -6, -1, 7, 14, 18,
+ 21, 23, 25, 26, 26, 23, 20, 20, 23, 24, 24, 21, 19, 14, 8, 2,
+ -1, 0, 1, 2, 3, 6, 8, 8, 5, 2, -2, -5, -5, -4, -1, 1,
+ 1, -1, -6, -9, -11, -13, -17, -20, -24, -26, -27, -26, -23, -21, -20, -23,
+ -26, -27, -26, -24, -20, -15, -9, -2, 4, 8, 10, 13, 16, 19, 21, 23,
+ 25, 28, 33, 36, 38, 38, 35, 32, 29, 24, 16, 11, 6, 2, -2, -6,
+ -6, -5, -4, -4, -7, -11, -14, -13, -10, -8, -8, -8, -9, -11, -12, -12,
+ -11, -11, -12, -14, -17, -19, -19, -18, -18, -20, -22, -23, -21, -18, -14, -11,
+ -8, -4, -1, 5, 11, 13, 11, 8, 6, 7, 9, 11, 13, 15, 19, 22,
+ 23, 25, 27, 27, 22, 17, 11, 6, 4, 5, 9, 13, 15, 15, 11, 6,
+ 0, -4, -7, -8, -6, -3, -2, -3, -6, -9, -13, -18, -22, -23, -20, -15,
+ -11, -10, -11, -14, -19, -24, -27, -28, -28, -27, -26, -23, -19, -15, -10, -6,
+ -1, 4, 8, 10, 11, 11, 13, 15, 17, 20, 23, 24, 24, 26, 28, 28,
+ 28, 27, 26, 24, 22, 20, 16, 13, 10, 8, 6, 3, -3, -9, -15, -17,
+ -16, -15, -13, -13, -14, -17, -19, -20, -20, -17, -14, -12, -13, -14, -13, -13,
+ -14, -15, -14, -13, -12, -12, -12, -10, -8, -7, -8, -9, -9, -7, -4, 0,
+ 3, 6, 8, 10, 12, 14, 18, 22, 25, 26, 27, 28, 28, 27, 24, 20,
+ 16, 13, 11, 9, 6, 3, 0, -3, -3, -2, 1, 3, 5, 3, 0, -4,
+ -8, -12, -17, -21, -22, -20, -17, -15, -14, -14, -13, -15, -19, -22, -21, -18,
+ -14, -13, -15, -16, -17, -17, -19, -19, -16, -11, -4, 1, 6, 10, 13, 17,
+ 20, 23, 24, 24, 24, 25, 28, 33, 37, 38, 35, 30, 24, 20, 16, 13,
+ 9, 2, -4, -8, -8, -8, -7, -7, -9, -12, -16, -18, -18, -16, -15, -16,
+ -16, -16, -13, -10, -10, -11, -13, -15, -15, -15, -15, -16, -17, -16, -14, -13,
+ -13, -13, -13, -12, -9, -5, -2, 1, 3, 6, 12, 18, 22, 22, 21, 18,
+ 16, 16, 19, 23, 29, 32, 30, 24, 18, 13, 9, 6, 3, 0, -2, -4,
+ -6, -8, -10, -11, -10, -6, -3, -2, -3, -5, -5, -6, -6, -7, -6, -5,
+ -4, -5, -8, -10, -11, -12, -14, -16, -18, -20, -21, -21, -22, -23, -24, -24,
+ -22, -18, -11, -4, 1, 4, 5, 6, 8, 11, 15, 20, 24, 26, 27, 28,
+ 31, 32, 31, 30, 28, 27, 24, 20, 17, 14, 12, 9, 3, -3, -9, -12,
+ -15, -16, -17, -15, -13, -10, -10, -11, -13, -14, -15, -17, -19, -21, -23, -24,
+ -22, -18, -13, -9, -8, -8, -8, -9, -9, -9, -7, -4, 0, 2, 3, 5,
+ 5, 3, 3, 4, 5, 6, 7, 10, 14, 17, 20, 20, 20, 21, 22, 20,
+ 18, 16, 15, 14, 12, 9, 7, 6, 4, 2, -2, -5, -7, -9, -9, -8,
+ -5, -2, 0, 0, -1, -3, -7, -12, -16, -16, -15, -13, -12, -13, -13, -12,
+ -11, -11, -12, -15, -19, -23, -24, -22, -19, -16, -13, -10, -5, -1, 3, 6,
+ 7, 8, 8, 10, 13, 17, 21, 25, 27, 28, 28, 26, 24, 24, 25, 27,
+ 28, 29, 28, 25, 19, 12, 4, -3, -10, -15, -19, -22, -24, -25, -26, -25,
+ -23, -21, -20, -18, -17, -16, -14, -12, -11, -12, -14, -14, -13, -13, -15, -16,
+ -16, -16, -15, -11, -4, 0, -2, 0, 0, 3, 14, 34, 24, -3, -14, -12,
+ 6, 6, -11, -23, -5, 15, 20, 15, -19, -12, 3, 19, 11, -5, 1, 4,
+ 7, -13, -3, 5, -13, 0, -2, 8, 0, -6, 16, 23, 13, 6, 2, 14,
+ 25, 2, 11, 3, -7, -8, -24, -6, -4, -18, 6, 30, 14, 9, 0, 0,
+ 13, -7, 0, -3, 9, 8, -6, -14, -15, -23, -19, -7, 0, -3, 1, -8,
+ -10, -10, -17, -12, -7, -10, 1, -12, -13, 0, -15, -20, -25, -16, -6, -7,
+ -6, -6, -2, -4, -13, -12, -6, -6, -5, 2, 8, -5, -13, -3, -4, -11,
+ -16, -3, 12, -2, -8, -4, -4, 4, -15, -17, -6, -2, 5, -4, 3, -2,
+ -10, -4, -5, -7, -8, 4, 17, 1, -3, -14, -4, -2, -7, -4, -6, 10,
+ 5, -6, -7, -8, 10, -5, -3, 3, -8, 11, 7, -5, -3, -13, -7, 0,
+ -6, 4, 0, -7, 12, -9, -17, -7, 5, 2, -3, -4, -7, 7, -2, -13,
+ -5, -2, 5, 4, 0, 7, -3, 4, 1, -2, -4, 6, 8, 8, 0, -2,
+ 2, 3, 2, 1, -2, 5, 12, 6, 3, 2, -3, 2, 3, 1, 8, 6,
+ 7, 2, -5, -3, 1, 5, 2, 0, -3, 2, 7, 2, 0, -9, 0, 5,
+ 1, 3, 1, 4, 6, -5, -3, -2, 2, 6, 4, 6, 1, 2, 4, 4,
+ -2, 2, 5, 5, 7, 7, 2, 6, 0, 3, 0, -3, 8, 4, 4, 9,
+ -3, 2, 1, 1, 2, 1, 5, 5, 4, 6, 1, -6, -2, 3, 5, 6,
+ 4, 3, 4, 1, 2, -4, 0, 6, 2, 2, 4, 3, 5, -3, -2, -5,
+ -3, 5, 2, 1, 3, 1, -2, -3, -4, -6, 3, 5, 1, -2, 1, 2,
+ -2, -2, -2, -3, 3, 5, 3, 4, 2, 2, 1, 0, 1, 4, 9, 9,
+ 5, 2, 1, 6, 4, 4, 5, 5, 7, 8, 4, 5, 1, 2, 3, 1,
+ 1, 4, 2, 3, 0, -4, -7, -5, 0, -3, -3, -3, -5, 0, -8, -7,
+ -8, -5, -3, -6, -3, -4, -5, 0, -7, -4, -5, -3, 1, 1, -2, 1,
+ -2, 2, 0, 0, -2, 3, 5, 4, 5, 4, 2, 4, 2, 4, 5, 6,
+ 5, 6, 4, 4, 4, 4, 3, 4, 2, 4, 4, 2, -2, -2, 0, -3,
+ -3, -3, -4, -2, -7, -6, -7, -9, -7, -10, -9, -10, -10, -8, -11, -9,
+ -9, -12, -10, -13, -12, -7, -8, -6, -6, -9, -6, -5, -3, 0, 0, 1,
+ 1, 4, 3, 4, 8, 6, 8, 7, 6, 10, 9, 12, 12, 11, 12, 8,
+ 13, 10, 11, 10, 8, 9, 8, 6, 9, 4, 5, 0, -3, -5, -5, -6,
+ -7, -9, -12, -15, -17, -21, -18, -22, -21, -23, -25, -24, -27, -27, -26, -30,
+ -27, -27, -28, -20, -22, -19, -14, -15, -12, -10, -10, -2, 3, 4, 12, 12,
+ 14, 20, 17, 25, 27, 29, 33, 35, 35, 40, 38, 41, 39, 36, 38, 36,
+ 36, 38, 31, 33, 25, 21, 14, 8, 1, 2, 0, -3, -5, -15, -23, -28,
+ -40, -39, -43, -46, -43, -52, -53, -59, -66, -62, -69, -63, -64, -64, -50, -56,
+ -44, -45, -43, -38, -36, -31, -20, -8, 4, 12, 19, 18, 28, 31, 40, 52,
+ 57, 68, 73, 73, 77, 73, 81, 79, 82, 82, 77, 82, 77, 75, 69, 59,
+ 53, 42, 33, 24, 22, 17, 11, 1, -17, -25, -36, -42, -46, -55, -60, -64,
+ -73, -77, -88, -90, -92, -97, -98, -100, -100, -92, -85, -79, -80, -76, -79, -69,
+ -56, -50, -32, -24, -15, 0, -2, 11, 15, 29, 45, 55, 67, 72, 82, 88,
+ 95, 101, 102, 109, 109, 112, 109, 110, 110, 106, 104, 91, 81, 77, 68, 66,
+ 54, 42, 32, 14, 6, -6, -12, -20, -29, -43, -55, -65, -76, -76, -85, -89,
+ -97, -105, -107, -114, -115, -117, -117, -113, -112, -104, -101, -91, -85, -84, -70, -72,
+ -55, -42, -34, -14, -8, 5, 16, 22, 35, 44, 57, 69, 78, 89, 94, 101,
+ 104, 109, 109, 119, 118, 117, 120, 110, 114, 114, 99, 102, 84, 74, 72, 57,
+ 52, 43, 32, 22, 10, -7, -20, -28, -34, -47, -54, -60, -67, -71, -80, -87,
+ -90, -105, -105, -110, -120, -115, -120, -123, -113, -111, -109, -97, -98, -92, -83, -82,
+ -76, -63, -61, -48, -39, -30, -16, -3, 10, 22, 32, 42, 49, 61, 67, 76,
+ 84, 91, 101, 105, 115, 116, 117, 125, 115, 119, 116, 106, 111, 102, 97, 92,
+ 84, 79, 70, 64, 50, 45, 31, 19, 14, -2, -9, -19, -30, -35, -47, -54,
+ -62, -67, -73, -82, -86, -96, -100, -105, -109, -116, -118, -120, -120, -117, -111, -110,
+ -97, -96, -90, -84, -78, -73, -64, -55, -50, -39, -25, -20, 1, 11, 19, 37,
+ 40, 51, 61, 68, 76, 85, 94, 97, 105, 114, 112, 120, 122, 119, 121, 117,
+ 110, 106, 105, 92, 90, 84, 69, 71, 57, 48, 45, 29, 22, 14, -2, -9,
+ -22, -31, -40, -47, -59, -62, -68, -76, -80, -87, -97, -96, -111, -111, -116, -124,
+ -119, -123, -120, -109, -109, -98, -95, -93, -84, -81, -75, -66, -55, -51, -37, -28,
+ -16, 1, 12, 23, 39, 40, 55, 59, 68, 77, 86, 94, 103, 104, 116, 117,
+ 118, 125, 122, 117, 120, 107, 108, 104, 95, 92, 85, 72, 70, 60, 48, 43,
+ 29, 18, 10, -7, -12, -22, -30, -38, -49, -58, -63, -72, -75, -84, -90, -93,
+ -100, -110, -103, -121, -115, -115, -124, -110, -112, -111, -92, -98, -86, -81, -77, -69,
+ -61, -53, -48, -34, -27, -13, 1, 9, 28, 37, 45, 58, 59, 76, 78, 85,
+ 97, 98, 109, 114, 111, 123, 120, 119, 121, 116, 111, 110, 101, 93, 92, 79,
+ 73, 68, 55, 52, 40, 30, 21, 10, 0, -13, -23, -29, -41, -47, -58, -64,
+ -69, -75, -84, -89, -93, -103, -105, -110, -120, -115, -117, -128, -105, -114, -109, -88,
+ -102, -86, -76, -84, -64, -63, -56, -43, -37, -25, -10, 4, 11, 31, 36, 46,
+ 56, 58, 74, 78, 84, 100, 95, 110, 114, 110, 124, 120, 116, 121, 110, 105,
+ 108, 97, 96, 91, 79, 75, 66, 57, 51, 38, 29, 17, 5, -3, -13, -20,
+ -28, -40, -46, -55, -66, -68, -76, -85, -88, -97, -102, -106, -110, -117, -115, -120,
+ -122, -108, -117, -103, -98, -96, -86, -79, -77, -66, -59, -54, -46, -33, -31, -10,
+ -2, 11, 27, 36, 47, 58, 62, 74, 78, 86, 94, 96, 106, 109, 115, 120,
+ 118, 121, 119, 112, 114, 104, 98, 94, 85, 77, 72, 63, 56, 49, 37, 31,
+ 20, 6, -2, -15, -24, -33, -44, -50, -58, -63, -68, -76, -82, -89, -95, -105,
+ -105, -116, -118, -117, -126, -114, -111, -118, -92, -105, -92, -83, -88, -72, -71, -65,
+ -51, -50, -31, -25, -9, 2, 16, 29, 35, 50, 53, 67, 73, 75, 92, 88,
+ 104, 112, 108, 122, 117, 119, 123, 114, 116, 110, 104, 98, 94, 86, 80, 75,
+ 63, 59, 47, 36, 29, 13, 9, -5, -16, -21, -36, -40, -50, -61, -61, -73,
+ -77, -85, -93, -95, -103, -108, -117, -120, -118, -125, -117, -108, -116, -96, -98, -97,
+ -83, -82, -78, -66, -61, -54, -43, -32, -25, -2, 3, 16, 33, 36, 52, 56,
+ 66, 75, 78, 94, 91, 103, 113, 108, 122, 119, 119, 121, 116, 112, 110, 106,
+ 93, 96, 83, 76, 74, 59, 58, 47, 34, 28, 14, 6, -6, -17, -27, -36,
+ -44, -54, -61, -63, -70, -76, -86, -90, -99, -102, -108, -117, -115, -121, -123, -111,
+ -120, -102, -100, -101, -84, -91, -76, -74, -70, -54, -56, -41, -30, -20, -3, 8,
+ 23, 31, 46, 47, 59, 70, 71, 83, 89, 90, 108, 108, 115, 120, 121, 122,
+ 118, 118, 109, 110, 102, 93, 93, 82, 78, 72, 62, 57, 45, 37, 22, 15,
+ 4, -10, -18, -30, -36, -42, -54, -57, -63, -68, -77, -86, -91, -102, -103, -108,
+ -117, -114, -119, -117, -115, -110, -106, -100, -91, -99, -79, -81, -77, -59, -61, -50,
+ -36, -33, -16, -4, 10, 16, 35, 39, 48, 62, 64, 76, 85, 89, 98, 105,
+ 110, 113, 120, 119, 118, 123, 112, 111, 110, 100, 98, 93, 82, 78, 70, 58,
+ 54, 45, 30, 24, 12, 0, -7, -20, -28, -36, -45, -55, -61, -66, -73, -79,
+ -88, -93, -103, -105, -112, -119, -115, -124, -123, -109, -119, -103, -98, -102, -92, -84,
+ -83, -75, -62, -59, -50, -34, -34, -12, 1, 7, 26, 33, 42, 50, 62, 67,
+ 76, 88, 90, 101, 110, 108, 118, 121, 119, 122, 121, 111, 113, 110, 98, 98,
+ 91, 80, 78, 66, 58, 53, 40, 29, 20, 8, -4, -11, -22, -33, -37, -49,
+ -57, -61, -68, -77, -81, -90, -96, -101, -110, -112, -116, -120, -116, -121, -119, -104,
+ -111, -96, -91, -96, -79, -79, -76, -59, -57, -46, -33, -25, -14, 5, 11, 26,
+ 39, 42, 55, 61, 70, 81, 86, 94, 101, 105, 114, 116, 120, 121, 119, 119,
+ 115, 111, 107, 102, 94, 90, 82, 73, 68, 59, 50, 41, 28, 20, 7, -4,
+ -12, -22, -30, -41, -48, -56, -62, -69, -75, -83, -90, -98, -100, -107, -111, -119,
+ -112, -124, -120, -107, -119, -101, -93, -104, -80, -85, -83, -61, -65, -55, -40, -38,
+ -25, -7, -3, 13, 29, 34, 45, 57, 59, 74, 79, 87, 98, 98, 108, 111,
+ 112, 122, 117, 119, 119, 111, 110, 107, 96, 96, 89, 76, 74, 63, 54, 51,
+ 35, 27, 19, 5, -3, -12, -25, -29, -43, -52, -58, -64, -71, -78, -82, -92,
+ -98, -101, -108, -110, -114, -120, -119, -118, -115, -110, -106, -95, -97, -82, -84, -76,
+ -62, -63, -51, -42, -39, -20, -12, 2, 15, 29, 36, 47, 58, 62, 74, 80,
+ 85, 95, 101, 106, 111, 116, 118, 117, 122, 113, 115, 111, 99, 103, 90, 85,
+ 80, 68, 63, 56, 46, 36, 28, 17, 5, -5, -19, -25, -35, -43, -52, -58,
+ -62, -72, -75, -83, -94, -94, -105, -105, -115, -115, -116, -122, -114, -112, -108, -98,
+ -99, -89, -86, -82, -72, -69, -58, -52, -44, -31, -21, -6, 4, 17, 28, 39,
+ 48, 53, 66, 72, 80, 88, 92, 104, 108, 113, 116, 119, 121, 116, 119, 112,
+ 108, 107, 94, 94, 85, 79, 72, 62, 57, 48, 37, 25, 17, 8, -8, -15,
+ -26, -35, -42, -55, -59, -65, -73, -75, -87, -89, -97, -104, -109, -116, -116, -121,
+ -120, -120, -109, -108, -103, -90, -97, -78, -78, -77, -60, -64, -50, -41, -34, -16,
+ -7, 9, 19, 33, 42, 52, 60, 65, 77, 79, 87, 96, 99, 109, 113, 118,
+ 124, 117, 121, 117, 109, 110, 99, 94, 93, 83, 77, 73, 63, 55, 50, 32,
+ 26, 18, 0, -6, -20, -29, -34, -49, -53, -57, -63, -71, -76, -83, -91, -97,
+ -108, -112, -114, -122, -115, -124, -112, -105, -112, -89, -99, -90, -78, -89, -72, -66,
+ -61, -49, -41, -28, -16, 2, 6, 25, 35, 36, 53, 54, 67, 77, 79, 93,
+ 97, 105, 112, 111, 122, 118, 119, 117, 112, 109, 108, 99, 95, 92, 82, 76,
+ 71, 59, 56, 43, 30, 24, 10, 0, -9, -18, -26, -36, -45, -55, -59, -68,
+ -75, -81, -88, -94, -99, -106, -109, -110, -119, -117, -119, -116, -111, -105, -101, -91,
+ -92, -83, -75, -75, -61, -52, -52, -35, -29, -18, 0, 9, 22, 36, 41, 51,
+ 64, 68, 78, 88, 90, 101, 103, 109, 113, 115, 121, 117, 118, 116, 109, 109,
+ 102, 94, 90, 80, 71, 67, 57, 47, 42, 30, 19, 14, -4, -9, -19, -31,
+ -36, -50, -55, -61, -68, -74, -79, -87, -93, -101, -107, -107, -115, -118, -118, -123,
+ -112, -110, -109, -92, -93, -94, -74, -83, -71, -57, -61, -45, -34, -31, -10, 0,
+ 12, 27, 37, 42, 55, 61, 70, 77, 87, 95, 96, 106, 112, 113, 123, 122,
+ 117, 122, 112, 109, 110, 96, 96, 92, 76, 74, 68, 55, 50, 40, 28, 20,
+ 7, -6, -10, -23, -31, -42, -51, -59, -65, -70, -76, -82, -88, -92, -104, -104,
+ -105, -122, -113, -122, -126, -106, -119, -103, -91, -99, -82, -80, -76, -66, -59, -54,
+ -46, -34, -30, -9, 1, 13, 33, 34, 51, 57, 63, 76, 77, 91, 95, 95,
+ 110, 108, 115, 122, 120, 120, 123, 112, 110, 110, 94, 95, 87, 70, 74, 62,
+ 55, 50, 39, 29, 20, 7, -5, -13, -26, -35, -44, -56, -61, -65, -69, -75,
+ -83, -86, -98, -104, -104, -121, -115, -119, -128, -110, -117, -116, -92, -100, -90, -78,
+ -83, -75, -63, -64, -55, -41, -39, -20, -7, 1, 21, 31, 40, 51, 55, 67,
+ 72, 77, 91, 93, 99, 110, 109, 118, 125, 118, 124, 119, 108, 114, 101, 93,
+ 96, 81, 75, 73, 59, 57, 48, 35, 27, 15, 1, -7, -20, -29, -37, -49,
+ -56, -61, -65, -69, -74, -83, -91, -98, -107, -113, -117, -120, -122, -118, -115, -111,
+ -103, -101, -92, -89, -85, -80, -77, -65, -61, -51, -41, -33, -16, -4, 8, 21,
+ 34, 40, 49, 57, 63, 73, 82, 89, 98, 104, 109, 117, 118, 123, 122, 119,
+ 116, 110, 108, 100, 97, 93, 83, 80, 70, 64, 55, 45, 34, 22, 12, -2,
+ -10, -20, -30, -35, -48, -55, -62, -67, -71, -78, -86, -91, -101, -104, -110, -117,
+ -117, -120, -123, -111, -111, -110, -90, -99, -90, -76, -85, -71, -58, -63, -45, -37,
+ -33, -14, 1, 4, 27, 34, 41, 53, 59, 66, 79, 84, 92, 100, 103, 110,
+ 115, 116, 123, 118, 118, 117, 107, 110, 101, 95, 93, 79, 76, 68, 57, 52,
+ 43, 30, 23, 11, -3, -8, -20, -30, -34, -48, -55, -60, -69, -74, -81, -89,
+ -92, -101, -105, -108, -114, -117, -118, -122, -112, -113, -108, -95, -101, -87, -82, -83,
+ -68, -60, -56, -45, -38, -28, -17, -2, 6, 23, 33, 40, 54, 60, 68, 80,
+ 85, 94, 96, 103, 109, 110, 119, 118, 118, 121, 113, 112, 110, 100, 98, 90,
+ 77, 73, 66, 55, 51, 41, 29, 25, 8, 1, -9, -23, -28, -42, -51, -59,
+ -64, -67, -75, -79, -86, -94, -98, -105, -111, -115, -117, -121, -123, -111, -120, -102,
+ -95, -100, -79, -84, -81, -61, -69, -55, -46, -42, -27, -14, -3, 11, 30, 35,
+ 49, 57, 60, 76, 76, 86, 95, 95, 109, 108, 116, 122, 121, 123, 120, 116,
+ 114, 106, 100, 94, 88, 78, 73, 65, 59, 52, 38, 33, 20, 10, -2, -15,
+ -22, -32, -42, -51, -58, -62, -67, -77, -80, -86, -94, -100, -106, -113, -115, -119,
+ -122, -118, -117, -107, -106, -98, -89, -89, -78, -76, -71, -57, -56, -46, -36, -25,
+ -12, 0, 16, 26, 39, 49, 54, 67, 72, 80, 88, 94, 101, 104, 115, 113,
+ 121, 125, 116, 123, 116, 110, 109, 98, 93, 88, 78, 69, 65, 56, 47, 42,
+ 27, 20, 8, -6, -15, -27, -33, -43, -53, -58, -64, -68, -74, -86, -87, -96,
+ -106, -103, -117, -116, -117, -123, -117, -106, -114, -97, -96, -96, -81, -81, -80, -62,
+ -64, -49, -45, -34, -19, -8, 4, 17, 28, 40, 47, 54, 66, 73, 79, 93,
+ 95, 102, 113, 110, 117, 123, 119, 121, 117, 113, 111, 106, 96, 95, 88, 78,
+ 72, 63, 55, 47, 35, 26, 14, 4, -9, -19, -24, -35, -43, -51, -61, -65,
+ -72, -79, -88, -88, -99, -107, -107, -120, -114, -120, -122, -113, -116, -102, -106, -95,
+ -89, -95, -72, -80, -70, -50, -58, -37, -30, -20, -5, 6, 18, 29, 44, 45,
+ 57, 72, 68, 89, 89, 97, 109, 104, 120, 113, 118, 124, 112, 120, 112, 107,
+ 106, 96, 91, 87, 78, 66, 65, 52, 40, 39, 17, 17, 4, -13, -13, -30,
+ -35, -44, -58, -59, -66, -72, -78, -85, -93, -97, -106, -114, -110, -120, -120, -118,
+ -120, -109, -110, -98, -100, -89, -81, -87, -68, -68, -59, -44, -46, -29, -18, -5,
+ 5, 22, 32, 39, 54, 56, 68, 79, 79, 94, 98, 102, 110, 112, 117, 119,
+ 124, 117, 116, 116, 104, 106, 97, 89, 86, 74, 67, 60, 53, 41, 34, 24,
+ 12, 4, -9, -19, -28, -38, -47, -58, -60, -68, -73, -77, -88, -93, -96, -111,
+ -109, -115, -124, -118, -122, -120, -107, -109, -102, -91, -95, -82, -78, -78, -60, -59,
+ -51, -36, -35, -14, -3, 6, 24, 34, 41, 56, 59, 67, 81, 82, 92, 103,
+ 102, 112, 119, 114, 123, 123, 116, 121, 112, 106, 107, 93, 91, 84, 74, 69,
+ 61, 52, 43, 32, 21, 13, -2, -10, -22, -31, -38, -51, -56, -59, -69, -71,
+ -76, -87, -90, -100, -107, -110, -119, -118, -120, -123, -108, -118, -101, -92, -102, -77,
+ -85, -83, -63, -71, -58, -45, -44, -27, -15, -2, 10, 30, 32, 46, 57, 56,
+ 74, 73, 84, 93, 95, 109, 108, 117, 117, 124, 119, 119, 119, 112, 109, 100,
+ 96, 90, 81, 75, 65, 59, 51, 41, 33, 22, 12, 0, -12, -23, -30, -40,
+ -51, -57, -64, -71, -73, -83, -84, -95, -102, -102, -116, -117, -118, -128, -116, -114,
+ -116, -102, -99, -95, -86, -80, -80, -71, -58, -61, -46, -38, -30, -10, -4, 12,
+ 26, 37, 47, 54, 67, 68, 79, 89, 86, 104, 104, 111, 118, 118, 123, 121,
+ 119, 116, 112, 109, 99, 96, 88, 80, 75, 66, 58, 49, 41, 29, 19, 10,
+ -5, -10, -25, -35, -39, -53, -58, -64, -69, -75, -81, -87, -100, -99, -112, -116,
+ -118, -126, -123, -115, -120, -111, -102, -100, -93, -86, -85, -76, -69, -64, -56, -47,
+ -38, -25, -10, 4, 16, 31, 40, 46, 61, 65, 70, 83, 86, 93, 103, 105,
+ 114, 125, 118, 124, 125, 112, 120, 111, 98, 103, 91, 86, 83, 71, 66, 61,
+ 49, 38, 32, 16, 7, -4, -17, -26, -36, -44, -54, -60, -59, -71, -75, -79,
+ -94, -95, -103, -117, -112, -120, -127, -120, -118, -117, -104, -102, -99, -88, -84, -86,
+ -73, -70, -64, -51, -47, -37, -17, -10, 7, 19, 32, 40, 52, 56, 67, 73,
+ 80, 87, 92, 103, 109, 110, 123, 119, 121, 126, 111, 113, 112, 98, 98, 91,
+ 80, 80, 71, 60, 61, 47, 36, 30, 13, 5, -5, -19, -27, -35, -43, -52,
+ -58, -62, -71, -76, -84, -96, -100, -105, -118, -115, -121, -123, -121, -114, -117, -110,
+ -98, -105, -91, -83, -90, -71, -68, -64, -48, -43, -33, -17, -5, 3, 23, 32,
+ 38, 54, 59, 66, 79, 82, 92, 100, 105, 108, 116, 119, 117, 126, 116, 115,
+ 118, 106, 105, 99, 91, 85, 78, 67, 60, 54, 41, 33, 24, 11, 0, 3,
+ 10, 14, -8, 46, 7, -20, -23, -28, 17, 9, 47, -7, -15, -35, -1, -26,
+ 44, 34, -31, 31, -47, -32, 30, -2, 32, 15, -15, -17, -39, 16, -2, 26,
+ 23, 3, -43, 11, -37, 14, 37, 7, 4, -21, -30, -9, 14, 18, 38, -13,
+ -16, -21, -24, 8, 38, 3, 16, -29, -11, -26, 20, 15, 24, -9, 0, -34,
+ -21, 32, -16, 41, -1, -20, -7, -7, -7, 27, 0, -2, -2, -11, -11, 19,
+ -16, 32, -19, -4, 11, -40, 49, -13, -12, 12, -32, 12, 17, 1, 23, -34,
+ -20, 14, -20, 33, 44, -51, 7, -21, -38, 46, 19, 37, -28, -29, -17, -40,
+ 63, 36, -33, 42, -45, -57, 16, 37, -3, 54, 0, -64, -25, -7, 15, 37,
+ 34, -2, -65, -12, -3, -7, 76, -2, -6, -28, -22, -30, 40, 11, 12, 21,
+ -43, -6, -1, -31, 73, -35, 33, -1, -67, 29, -24, 16, 42, 4, -26, 17,
+ -71, 32, 0, 0, 72, -56, 4, -2, -75, 76, -25, 39, 24, -42, -6, -20,
+ -31, 56, 1, 3, 49, -63, -12, -16, -10, 49, 12, 29, -32, -59, 35, -39,
+ 35, 45, -33, -21, 46, -68, 13, 16, 12, 0, 2, 32, -70, 12, 30, -62,
+ 64, 5, -31, 22, -30, 11, -30, 43, 2, -8, 16, -3, -60, 39, -11, -13,
+ 63, -32, 8, -6, -45, 39, -38, 30, 49, -89, 96, -84, 0, 43, -51, 52,
+ -4, -6, 7, -31, -10, 12, -22, 62, 8, -57, 65, -101, 1, 69, -46, 76,
+ -18, -34, -24, -33, 50, -6, 55, 16, -70, -19, 2, -33, 59, 61, -40, 7,
+ -44, -33, -7, 61, 31, -15, 5, -32, -70, 47, 34, 8, 22, -16, -44, -47,
+ 56, -6, 12, 56, -46, -32, -3, 7, -4, 42, 19, -41, -35, 41, -59, 43,
+ 45, -44, 9, -9, -7, -19, 36, 2, -50, 49, -6, -34, 33, -1, -38, 17,
+ 44, -33, 5, 28, -68, -13, 62, -25, 15, 45, -57, -32, 23, -14, 37, 11,
+ 29, -56, -48, 46, -55, 48, 94, -74, 22, -40, -59, 36, 9, 75, -19, -31,
+ 6, -104, 39, 80, -23, 59, -12, -104, 10, -12, 24, 59, 5, 9, -78, -12,
+ 24, -47, 116, -6, -51, 34, -71, -26, 55, 3, 11, 38, -31, -9, -45, 21,
+ -11, 4, 92, -79, 16, -16, -41, 29, 27, 19, -5, -19, -13, -35, 29, 22,
+ -7, 20, -35, 6, -21, 30, -2, 6, -8, -20, -12, 30, -13, 8, 23, -52,
+ 21, 8, -16, 40, -20, -7, -15, -38, 62, -33, 48, 5, -66, 28, -25, 15,
+ 39, 5, -46, 8, -46, 32, 12, 37, -9, -49, 43, -78, 43, 46, -43, 39,
+ -41, -36, 13, 19, 48, -21, 9, -37, -54, 45, 32, -14, 41, -32, -66, 42,
+ -8, 37, 12, -10, -12, -74, 71, -30, 16, 65, -64, -1, -13, -12, 17, 24,
+ 10, -16, -31, -1, -3, 1, 68, -47, -7, -8, -41, 74, -16, 32, -27, -42,
+ 22, -49, 80, -11, 0, 23, -84, 34, -24, 31, 48, -37, 23, -55, -25, 22,
+ 14, 22, 59, -78, -11, -1, -45, 90, -35, 32, 0, -75, 63, -65, 34, 52,
+ -71, 70, -56, -14, 30, -22, 10, 55, -74, 41, -19, -47, 88, -62, 50, -11,
+ -57, 44, -54, 59, 17, -23, 12, -40, -41, 60, 3, 15, 28, -71, -1, -17,
+ 11, 61, -28, 47, -59, -48, 35, -18, 51, 27, -20, -35, -36, 14, 6, 44,
+ 23, -30, -33, -17, -1, 14, 49, -2, -32, -12, -20, 5, 29, 34, -33, 9,
+ -34, -26, 36, -2, 40, -28, 5, -26, -39, 65, -27, 19, 31, -54, 0, -8,
+ 12, 2, 30, -5, -25, -22, 24, -29, 26, 52, -57, 7, 5, -56, 46, 1,
+ 8, 4, -5, 1, -51, 28, 14, -21, 48, -17, -46, 4, 11, -6, 35, 7,
+ -16, -31, -10, 25, -49, 95, -28, -29, 19, -46, -5, 32, 21, 8, -1, -24,
+ -36, -17, 59, -7, 33, 10, -76, -14, 19, -1, 56, 16, -23, -64, -8, 7,
+ 8, 85, 0, -57, -21, -35, -7, 72, 23, 28, -66, -16, -47, 2, 68, 24,
+ 5, 0, -69, -26, 22, -7, 72, 0, -12, -20, -51, 15, -11, 44, 44, -46,
+ 36, -59, -38, 32, 19, -3, 71, -45, -28, -29, -17, 36, 8, 79, -47, -53,
+ 18, -65, 38, 75, -24, 20, -36, -34, -26, 38, 39, -7, -3, 7, -85, 44,
+ 26, -17, 42, -20, -29, -26, 26, 18, -8, 36, -17, -73, 40, 4, -1, 52,
+ -16, -47, -15, 14, 4, 29, 30, -41, -44, 15, -2, 16, 60, -26, -54, 17,
+ -33, 22, 48, -5, -15, -20, -13, -15, 31, 37, -28, 6, -17, -22, -10, 64,
+ -43, 16, 22, -71, 41, 3, -1, 6, -12, 12, -38, 11, 38, -49, 37, 24,
+ -64, 27, 18, -73, 81, -33, 14, -3, -32, 43, -60, 53, 24, -76, 70, -29,
+ -33, 50, -18, -34, 48, -38, 37, -15, -5, 25, -80, 70, -4, -45, 89, -72,
+ -3, 13, -23, 28, 21, -9, -9, -25, -11, 24, -26, 62, -14, -49, 67, -97,
+ 57, 12, -23, 46, -46, 9, -20, -4, 25, -1, 5, 18, -31, -25, 38, -43,
+ 44, 17, -42, 37, -66, 37, -16, 26, 18, -16, -17, -4, -17, 7, 38, -11,
+ 4, -3, -51, 32, -17, 38, 18, -34, 23, -58, 4, 25, 0, 26, 3, -35,
+ -11, -10, 16, 24, 8, 4, -33, -30, 22, -2, 14, 52, -61, 10, -23, -4,
+ 20, 10, 32, -44, -2, 1, -36, 37, 32, -25, 2, 0, -40, 14, 24, -5,
+ 13, -28, 20, -51, 41, 15, -23, 25, -12, -41, 30, -2, -11, 40, -34, 14,
+ -24, 3, 22, -31, 44, -22, -31, 57, -55, 28, 0, -9, 1, 11, -10, 8,
+ -13, 3, -2, -23, 60, -49, 23, 10, -59, 36, -3, -3, 35, -23, 5, -42,
+ 15, 7, -2, 35, 0, -45, 8, -4, -27, 63, -4, -14, 9, -39, 1, 1,
+ 27, 19, -27, 24, -49, -6, 34, -5, 10, 19, -32, -20, 14, -12, 16, 26,
+ -9, -19, -9, -8, 8, 7, 40, -29, -14, -4, -25, 7, 56, -15, 6, -20,
+ -36, 3, 10, 33, 20, -23, -5, -42, -18, 54, -17, 63, -5, -59, 2, -44,
+ 12, 57, 17, 15, -33, -44, -16, -17, 65, 40, -9, 10, -72, -51, 39, 10,
+ 65, 19, -25, -47, -51, 17, 20, 53, 30, -35, -35, -34, -16, 36, 48, 12,
+ -3, -35, -42, -9, 28, 34, 12, 15, -42, -39, 7, 8, 24, 28, 1, -31,
+ -36, 9, -1, 28, 29, -14, -34, 14, -43, 23, 34, -7, 24, -44, 10, -28,
+ -5, 53, -29, 29, -7, -33, 2, -1, 5, 19, 10, -17, 2, -33, 14, 1,
+ 8, 32, -36, 17, -28, -18, 36, -22, 29, 2, -25, 5, -17, 13, 1, 16,
+ -1, -10, -12, 3, -9, 10, 19, -22, 16, -3, -20, 24, -22, 15, -3, -14,
+ 22, -30, 31, -14, -11, 12, -11, 8, 17, -9, -4, -13, -13, 7, 10, 19,
+ -6, -7, -2, -32, 24, 8, 0, 17, -20, -10, -15, 13, 10, 11, 4, -1,
+ -40, 19, -4, -6, 42, -31, -1, -5, -12, 19, 6, 7, -5, -26, 10, -12,
+ 15, 20, -8, -19, 12, -40, 31, 15, -3, 16, -23, -27, 7, -5, 31, 6,
+ 3, -6, -41, 14, -2, 7, 38, -10, -29, 11, -44, 17, 29, 6, 20, -26,
+ 1, -45, 9, 31, -18, 40, -1, -47, 8, -10, -4, 29, 33, -25, 1, -31,
+ -12, -9, 35, 30, -25, 31, -48, -28, 20, 17, 9, 30, -19, -39, -13, 6,
+ 8, 38, 15, -10, -42, 0, -24, 15, 49, -9, -12, 5, -44, -5, 42, 4,
+ 6, 8, -27, -29, 5, 24, -2, 10, 28, -56, 1, 23, -29, 29, 15, -19,
+ -11, 1, -4, -8, 24, 6, -15, 2, 7, -27, 12, 21, -40, 36, -15, -12,
+ 22, -16, 17, -17, 15, -6, -18, 23, -3, -26, 39, -27, -5, 26, -20, 8,
+ 5, -11, 7, -21, 19, -11, -8, 35, -25, 2, 18, -35, 9, 16, -21, 29,
+ -16, 1, -13, -13, 28, -18, 23, 13, -36, 6, -1, -23, 26, 12, -15, 17,
+ -20, -2, -7, 3, 22, -22, 27, -11, -34, 36, -30, 11, 17, 2, -12, 13,
+ -22, -11, 11, -5, 26, -17, 26, -25, -32, 44, -47, 39, 25, -31, 16, -35,
+ -1, -4, 26, 16, 3, -16, -10, -23, -8, 55, -27, 26, 0, -63, 41, -26,
+ 28, 22, -23, 14, -42, 5, 20, -13, 28, 3, -42, 20, -6, -17, 52, -32,
+ 6, -2, -37, 42, -27, 29, 15, -51, 40, -38, 2, 33, -19, 6, 11, -43,
+ 25, 0, -19, 57, -54, 31, -9, -43, 58, -52, 36, 11, -44, 50, -44, 8,
+ 23, -24, 12, 6, -34, 25, -9, -15, 50, -55, 35, -7, -25, 49, -48, 32,
+ -23, -18, 37, -30, 28, 8, -27, 7, -2, -19, 22, 10, -11, 10, -27, 4,
+ -16, 18, 29, -19, 20, -22, -36, 16, -2, 18, 14, 3, -24, -15, -5, 12,
+ 13, 20, 4, -40, 2, -23, 8, 29, 7, 9, -23, -10, -13, 5, 19, 9,
+ -3, -14, -7, -19, 21, 6, 5, 10, -20, 0, -14, 12, 0, 2, 5, -13,
+ 1, -3, 12, -12, 20, -13, -7, 6, -11, 5, 0, 5, -5, -4, 10, -10,
+ 2, 6, -5, -12, 18, -13, -9, 19, -17, 11, -1, 8, -5, -22, 26, -26,
+ 1, 29, -17, -7, 16, -22, -8, 23, -3, 4, -3, -2, -15, -20, 42, -21,
+ 4, 40, -55, 8, 8, -22, 21, 20, -17, 2, -14, -7, -2, 10, 31, -25,
+ 10, -3, -54, 40, 5, -12, 42, -17, -37, 13, -12, 7, 24, 10, -6, -36,
+ 12, -9, -25, 74, -24, -19, 38, -64, 5, 25, 0, 16, 1, -9, -25, -23,
+ 36, -8, 6, 50, -58, -12, 22, -53, 52, 18, -12, 16, -51, 15, -30, 25,
+ 46, -37, 31, -26, -49, 30, 9, -1, 42, -19, -28, -13, -5, 16, 4, 42,
+ -18, -40, 20, -30, 1, 49, -4, -15, 0, -21, -19, 21, 26, 0, -9, 9,
+ -43, -1, 26, -5, 21, -7, -6, -32, 9, 12, -3, 34, -17, -12, -17, -4,
+ 9, 7, 28, -19, -3, -13, -11, 7, 15, 15, -19, 15, -38, -5, 17, -1,
+ 29, -20, 15, -39, -11, 41, -33, 45, -8, -21, -11, -3, 7, 0, 28, -7,
+ -19, -8, 7, -20, 23, 24, -40, 24, -17, -16, 26, -9, 21, -27, 13, -11,
+ -22, 29, -7, 0, 22, -22, -16, 14, -12, 12, 11, -5, -6, -17, 14, -15,
+ 9, 30, -28, 5, 1, -26, 8, 18, -7, 1, 6, -12, -15, 9, 13, -13,
+ 13, 13, -42, 14, 3, -16, 20, 7, -3, -22, 25, -26, 4, 16, -7, 3,
+ -8, 17, -33, 14, 9, -21, 25, -3, -11, -1, 1, -13, 1, 23, -20, 26,
+ -18, 0, -18, 3, 24, -25, 36, -15, -29, 22, -22, 3, 24, -5, -1, 0,
+ -18, 2, -11, 20, 10, -17, 30, -37, -15, 29, -33, 39, 11, -23, 7, -34,
+ 8, 0, 11, 36, -27, -12, 9, -47, 29, 31, -29, 40, -37, -14, 3, -17,
+ 45, -11, 8, 12, -60, 20, -2, -2, 41, -12, -18, 3, -37, 27, 12, -4,
+ 37, -56, 17, -21, -5, 44, -20, 14, -2, -40, 20, 0, 3, 22, -13, -10,
+ -6, -16, 29, -12, 14, 15, -49, 24, -11, -7, 39, -18, 3, -20, -12, 19,
+ -10, 32, 2, -34, 10, -13, -13, 37, 1, -7, 3, -33, 4, 2, 18, 25,
+ -25, 8, -33, -13, 34, -7, 24, 4, -33, -10, -2, 2, 25, 12, -1, -25,
+ -12, 3, -18, 34, 12, -15, 4, -9, -25, 10, 17, -3, 9, 2, -13, -23,
+ 9, 8, -13, 37, -10, -15, 1, -13, -1, 0, 31, -15, 0, 5, -29, 6,
+ 5, 15, -9, 16, -9, -29, 15, -10, 3, 15, 9, -11, -12, 11, -29, 17,
+ 14, -7, 6, -6, -7, -24, 30, -11, 9, 18, -20, -8, -6, 6, -10, 22,
+ 10, -29, 14, -13, -8, 13, 17, -13, 2, 1, -24, 5, 5, 12, -10, 15,
+ -7, -28, 21, -2, -8, 22, -9, -14, -2, 6, -5, 5, 12, -7, -15, 14,
+ -4, -16, 27, -10, -14, 13, -5, -9, 10, 5, -8, -5, 16, -20, 2, 13,
+ -14, -3, 17, -18, 2, 10, -12, 9, -6, -2, -16, 13, 10, -15, 33, -24,
+ -17, 10, -4, 15, 1, 9, -23, -9, 6, -5, 5, 21, -10, -13, 11, -21,
+ -2, 19, -10, 23, -20, 10, -16, -21, 33, -17, 17, 18, -30, 1, -14, -1,
+ 20, -2, 18, -15, -24, 6, -5, 6, 36, -26, 6, -18, -23, 34, -12, 25,
+ 1, -30, -1, -11, 10, 22, -1, 4, -19, -28, 21, -11, 22, 25, -33, 4,
+ -21, -7, 22, 7, 19, -23, -13, -3, -13, 21, 17, -11, 7, -19, -12, 12,
+ -10, 30, -13, -5, 4, -30, 27, -9, 17, -3, -25, 13, -23, 13, 27, -15,
+ -5, 3, -35, 17, 19, -8, 29, -37, 1, -15, -10, 48, -20, 26, -7, -49,
+ 22, -23, 21, 33, -10, -8, -17, -34, 11, 19, 12, 40, -39, -14, -13, -36,
+ 64, -4, 20, 9, -55, 3, -24, 21, 31, 10, -1, -22, -30, -7, 12, 18,
+ 29, -10, -7, -28, -22, 22, 3, 26, 4, -13, -18, -16, 21, -9, 28, -1,
+ -21, 0, -12, 5, 6, 5, 10, -20, 1, 3, -20, 21, 7, -23, 24, -25,
+ -6, 21, -13, 25, -19, -8, 2, -14, 20, 13, -23, 25, -31, -7, 24, -16,
+ 20, 6, -25, 8, -24, 12, 15, -10, 24, -25, -2, 0, -12, 14, 10, -13,
+ 4, 1, -17, 9, 6, -9, 9, 0, -3, -8, 11, -10, -2, 7, -1, -6,
+ 6, 1, -12, 1, 18, -31, 23, -2, -21, 21, -6, -8, 15, -14, 4, -6,
+ -1, 17, -22, 20, -6, -35, 37, -17, -6, 47, -41, 6, -6, -16, 12, 16,
+ 6, 1, -36, 18, -26, 4, 59, -36, -1, 16, -64, 30, 14, 1, 16, -13,
+ 0, -35, 17, 13, -8, 12, 14, -45, 11, 12, -24, 27, 12, -27, 10, -6,
+ -9, 1, 14, -7, -6, 8, -4, -8, 8, 8, -24, 13, 7, -27, 28, -1,
+ -28, 27, -19, -2, 17, -5, 6, -10, -5, 4, -25, 32, 2, -22, 32, -28,
+ -20, 35, -20, 16, 7, -18, 1, -22, 20, 0, 2, 20, -15, -25, 24, -25,
+ 12, 25, -23, 10, -19, -5, 8, 2, 20, -6, -13, 0, -22, 12, 15, -3,
+ 13, -13, -25, 12, -6, 18, 13, -3, -14, -22, 3, -2, 14, 25, -10, -16,
+ -5, -13, 2, 22, 9, -2, -11, -12, -20, 15, 20, 1, 14, -19, -17, -9,
+ 1, 19, 5, 0, 4, -35, 17, -7, 5, 20, -16, 2, -8, -11, 11, -2,
+ 2, 7, -19, 15, -10, 2, 12, -14, -3, 2, -9, 17, -3, 2, -7, -16,
+ 10, 2, 9, 10, -14, -9, -6, -11, 21, 5, 4, 6, -24, -5, -4, 6,
+ 18, 0, 8, -21, -18, 8, -8, 21, 16, -11, -9, -12, -15, 15, 3, 27,
+ -9, -16, 5, -30, 13, 23, -11, 21, -19, -15, -3, -9, 30, -9, 14, -6,
+ -22, -5, 15, -11, 23, -1, -14, -4, -9, 8, 4, 1, 20, -34, 9, 1,
+ -17, 24, -6, 1, -9, 1, -4, 3, 6, 8, -16, 0, 2, -13, 11, 21,
+ -31, 24, -21, -4, 13, -2, 7, -9, -3, 0, -18, 29, -4, -9, 16, -19,
+ -13, 25, -5, -1, 15, -24, 4, -15, 22, 4, -11, 20, -21, -25, 39, -23,
+ 14, 14, -23, 1, -8, 3, 12, -9, 23, -19, -18, 24, -22, 5, 30, -32,
+ 11, 2, -21, 18, -6, 5, 1, -9, 13, -22, 4, 19, -28, 26, 3, -28,
+ 21, -4, -25, 32, -15, 5, 0, -2, -4, -9, 15, 0, -13, 21, -14, -20,
+ 31, -19, 2, 17, -14, -9, 12, -6, 4, -1, 4, -17, -1, 12, -2, 0,
+ 20, -31, -8, 12, -8, 17, 14, -13, -16, -9, -7, 20, 11, 18, -13, -28,
+ -3, -12, 13, 40, -12, 4, -20, -32, 8, 17, 14, 21, -10, -28, -18, -2,
+ 11, 22, 17, 0, -34, -6, -3, -17, 50, 1, -13, 4, -22, -21, 17, 16,
+ 4, 7, 0, -27, -11, 4, 10, 2, 24, -6, -28, 7, -12, -2, 33, -3,
+ -6, 2, -37, 3, 9, 7, 24, -4, -14, -6, -24, 25, -1, 11, 16, -36,
+ -9, 12, -25, 45, 5, -20, 11, -36, 11, 7, 0, 30, -32, -1, 7, -33,
+ 37, 0, -9, 15, -21, -10, 12, -15, 24, -8, 3, 4, -20, 7, 3, -15,
+ 28, -14, -7, 13, -23, 2, 11, 0, 4, 7, -9, -16, 1, 7, -7, 19,
+ -3, -12, -14, 15, -10, 7, 30, -26, -13, 15, -30, 15, 26, -12, -1, -8,
+ -9, -5, 13, 22, -12, -12, 7, -36, 17, 31, -24, 27, -21, -24, 15, -10,
+ 26, 4, -12, 4, -36, 13, 14, -5, 27, -14, -22, 7, -12, 6, 23, -13,
+ 7, -19, -2, 7, -8, 25, -5, -17, 18, -25, 3, 14, -8, 4, 0, -1,
+ -11, 4, 12, -18, 15, 2, -23, 12, -2, -7, 12, 1, -1, -15, 11, -3,
+ -17, 41, -24, -7, 13, -25, 3, 22, -9, 15, -12, -9, 0, -17, 32, -5,
+ -5, 19, -49, 19, 3, -11, 45, -30, 2, -4, -28, 29, 0, 7, 12, -34,
+ 6, -10, 1, 33, -9, -6, 4, -41, 25, 2, 4, 29, -40, 8, -17, -9,
+ 42, -16, 16, -10, -33, 11, -7, 22, 12, -6, -6, -25, -4, 18, -3, 25,
+ -4, -29, 5, -17, 8, 22, 1, 4, -22, 1, -13, 2, 31, -19, 9, 2,
+ -36, 17, 5, -7, 20, -11, -2, -13, 4, 9, -18, 24, -3, -30, 33, -19,
+ -11, 31, -21, 6, 0, -5, 3, -10, 17, -7, -19, 30, -24, 0, 26, -23,
+ 3, 7, -17, 9, -3, 9, -1, -17, 23, -25, -3, 34, -27, 10, 15, -34,
+ 9, 1, 1, 7, -1, 12, -31, 4, 16, -27, 32, 10, -33, 10, -1, -27,
+ 29, 9, -9, 0, -1, -16, -6, 24, 2, -17, 23, -20, -24, 33, -11, -2,
+ 17, -7, -21, 13, 1, -7, 10, 1, -12, -9, 13, -1, -5, 20, -16, -15,
+ 15, -8, 5, 13, -10, -7, -9, 5, 2, 10, 7, -7, -22, 12, -13, 6,
+ 26, -14, -6, 0, -17, 3, 16, 6, 0, -11, 3, -26, 13, 15, -6, 7,
+ 4, -29, 6, 7, -3, 13, 1, -11, -9, 2, -1, 3, 9, -3, -8, 1,
+ -4, 0, 5, 0, 0, -2, 0, -1, 0, 0, -2, 11, 23, 22, 24, 25,
+ 20, 21, 15, 40, -1, -24, -42, -5, -19, -11, -8, 4, -46, -31, -14, -33,
+ -40, -44, -48, -89, -63, -47, -33, -27, -10, -6, 22, 25, 26, 28, 37, 11,
+ 15, 51, 44, 54, 66, 66, 71, 111, 84, 70, 63, 47, 39, 22, 47, -28,
+ -79, -111, -90, -91, -112, -81, -87, -49, -46, -5, -24, 26, 24, 47, 29, 23,
+ 30, 30, 13, -1, 4, -14, 17, 35, 62, 31, 53, 59, 72, 64, 27, 26,
+ 9, 9, -61, -44, -88, -74, -81, -83, -124, -96, -37, -78, -48, -56, -68, -60,
+ 7, 44, 39, 54, 77, 102, 110, 108, 89, 101, 100, 105, 64, 22, -1, 44,
+ 40, -19, -29, -35, -16, -27, -40, -77, -82, -113, -104, -93, -57, -72, -56, -3,
+ 1, 7, -1, 49, 39, 30, 31, 23, 10, 31, 11, 7, -19, -2, -2, 28,
+ 62, 92, 75, 33, 34, -20, -47, -61, -85, -105, -93, -119, -112, -54, -70, -67,
+ -32, -1, 4, 4, 20, 29, 62, 70, 54, 62, 78, 115, 92, 85, 78, 52,
+ 21, 19, 27, 2, -8, 13, 0, 5, 3, 9, 18, 0, -59, -61, -45, -57,
+ -65, -76, -89, -102, -48, -24, 17, 6, 26, 33, 35, 26, 41, 63, 20, 12,
+ 29, 34, 8, 7, 31, 21, 31, 39, 33, -5, -8, -55, -57, -98, -94, -88,
+ -64, -82, -74, -39, -14, 3, 16, 22, 8, 2, 17, 5, 36, 76, 74, 71,
+ 57, 73, 62, 47, 30, 32, 19, 4, 7, -14, -18, -2, 17, -5, 13, 22,
+ 31, 10, 8, -13, -47, -80, -85, -86, -71, -73, -60, -35, -10, 9, 19, 49,
+ 53, 47, 60, 73, 43, 33, 20, 13, -1, -7, -7, 7, 9, -2, 5, -14,
+ -40, -69, -61, -66, -67, -84, -58, -58, -33, 2, -7, -5, 12, 32, 18, 25,
+ 19, 24, 65, 59, 62, 64, 63, 55, 60, 52, 31, 19, -12, -26, -4, -7,
+ -10, -3, 6, -22, -14, 12, 19, 4, -26, -38, -40, -56, -61, -66, -59, -65,
+ -51, -20, 29, 40, 51, 52, 62, 61, 53, 26, 20, 6, 8, 6, 9, -14,
+ -14, -15, -2, -11, -23, -36, -38, -60, -77, -69, -60, -51, -56, -44, -27, 10,
+ -2, 14, 10, 22, 16, 41, 60, 39, 35, 60, 62, 43, 45, 63, 52, 17,
+ 12, 15, -1, -2, 0, -38, -48, -32, -22, -7, 3, 13, 10, -2, -1, -8,
+ -12, -25, -48, -46, -52, -49, -36, -17, 9, 17, 26, 48, 57, 55, 69, 60,
+ 32, 6, 4, -6, -20, -24, -9, -21, -25, -14, -18, -38, -38, -32, -51, -52,
+ -60, -34, -6, -6, -16, -11, -2, -1, 17, 19, 3, 11, 25, 31, 41, 39,
+ 33, 33, 41, 34, 34, 23, 21, 15, 6, -13, -24, -28, -20, -8, -12, -19,
+ -12, -5, 9, 14, 2, -12, -25, -28, -21, -28, -23, -22, -18, -26, -5, 24,
+ 45, 46, 47, 39, 33, 36, 42, 29, 7, -5, -10, -21, -29, -39, -39, -31,
+ -24, -29, -39, -51, -43, -27, -22, -18, -25, -26, -20, 9, 19, 18, 4, -2,
+ 19, 30, 38, 25, 24, 28, 33, 41, 38, 34, 32, 38, 24, 8, 4, -8,
+ -11, -15, -25, -31, -25, -20, -22, -15, -11, -9, -12, -17, -20, -20, -15, -6,
+ -11, -8, 0, 11, 29, 19, 17, 17, 18, 28, 31, 25, 18, 23, 18, 10,
+ 1, -7, -18, -26, -24, -30, -41, -38, -44, -32, -31, -31, -35, -25, -12, -2,
+ -8, -11, -13, -13, -2, 8, 15, 19, 29, 35, 37, 39, 43, 42, 40, 35,
+ 27, 25, 18, 15, 9, 4, -4, -15, -28, -28, -26, -28, -18, -15, -25, -23,
+ -12, -11, -14, -10, -2, -4, -1, 8, 15, 19, 22, 25, 16, 16, 17, 5,
+ 7, 13, 18, 13, 9, 6, 6, 4, -4, -21, -31, -28, -37, -39, -34, -38,
+ -38, -32, -17, -6, -4, -14, -19, -9, 3, -2, 3, 4, 7, 8, 13, 23,
+ 35, 38, 43, 42, 31, 25, 23, 17, 8, 3, 4, -7, -7, -10, -13, -20,
+ -19, -28, -33, -30, -23, -18, -13, -17, -12, 3, 14, 23, 31, 27, 23, 21,
+ 22, 19, 12, 4, 2, 2, -2, 0, 4, 11, 11, 6, 4, -2, -5, -14,
+ -17, -30, -38, -44, -42, -28, -21, -23, -21, -15, -15, -4, 8, 11, 4, -7,
+ -15, -7, 5, 10, 21, 26, 28, 27, 34, 37, 36, 28, 19, 10, 11, 8,
+ -2, -18, -17, -19, -19, -22, -24, -21, -24, -18, -17, -13, -19, -13, -1, 12,
+ 19, 22, 21, 19, 19, 30, 34, 24, 13, 7, 2, 1, 1, 2, -1, -2,
+ -6, 0, 0, -2, -15, -21, -17, -21, -28, -32, -31, -31, -32, -27, -24, -17,
+ -4, 1, -3, -1, 1, 4, 7, 8, 15, 16, 15, 15, 20, 32, 36, 38,
+ 32, 19, 12, 3, 2, -2, -4, -11, -19, -17, -15, -11, -16, -20, -27, -30,
+ -28, -22, -13, -6, -2, 2, 12, 23, 29, 45, 44, 36, 32, 21, 16, 14,
+ 10, 1, -9, -8, -2, -1, -7, -13, -13, -12, -9, -11, -18, -24, -26, -28,
+ -30, -24, -21, -21, -21, -11, -11, -10, 0, -2, 0, 4, 12, 13, 14, 12,
+ 17, 22, 28, 30, 28, 20, 16, 13, 8, 2, -2, -6, -15, -14, -18, -15,
+ -15, -16, -18, -18, -16, -19, -18, -17, -10, 0, -1, 4, 13, 22, 37, 39,
+ 36, 27, 27, 32, 26, 15, 6, -1, -4, -5, -7, -11, -11, -9, -15, -15,
+ -14, -18, -21, -19, -17, -21, -19, -15, -15, -10, -15, -14, -12, -11, -6, -2,
+ 1, -2, 1, 5, 14, 22, 33, 35, 23, 18, 16, 13, 11, 6, 1, -9,
+ -18, -11, -6, -7, -8, -9, -11, -11, -12, -13, -17, -21, -24, -24, -15, -4,
+ 7, 12, 17, 25, 30, 28, 31, 32, 31, 27, 22, 15, 12, 3, -2, -8,
+ -6, -3, -9, -13, -22, -24, -20, -18, -22, -24, -18, -14, -13, -10, -11, -9,
+ -3, -2, -3, -5, -10, -10, -5, -1, 4, 11, 15, 19, 22, 27, 23, 20,
+ 16, 14, 5, -3, -11, -15, -16, -12, -12, -11, -5, 1, -3, -10, -13, -15,
+ -11, -10, -10, -11, -8, -3, 2, 7, 9, 15, 25, 30, 33, 31, 25, 21,
+ 20, 16, 13, 7, -2, -8, -5, -4, -11, -20, -21, -22, -21, -17, -20, -21,
+ -22, -19, -19, -11, -4, -2, -2, -2, 2, 5, 2, 0, 0, -3, 1, 8,
+ 16, 13, 14, 17, 15, 13, 8, 5, -1, -6, -10, -13, -14, -14, -13, -10,
+ -7, -8, -8, -6, -6, -3, -1, -1, -9, -12, -7, 3, 13, 17, 14, 13,
+ 17, 22, 23, 24, 18, 15, 18, 18, 18, 15, 8, 0, -5, -8, -11, -15,
+ -17, -21, -26, -26, -24, -26, -24, -13, -9, -6, -3, -2, 3, 4, 6, 7,
+ 5, 2, 4, 2, -2, -4, -3, 5, 13, 17, 10, 3, -1, -2, -4, -5,
+ -11, -14, -13, -11, -8, -8, -8, -6, -3, 0, -1, -5, -5, 0, 4, 3,
+ 1, 2, 0, 0, 6, 13, 20, 17, 17, 18, 21, 18, 14, 13, 11, 11,
+ 7, 9, 3, -5, -12, -14, -18, -21, -23, -26, -26, -13, -3, -6, -13, -14,
+ -5, 5, 8, 3, 0, 1, 3, 6, 4, -1, -1, 1, 3, 7, 5, 3,
+ 0, 1, -1, 3, 0, -3, -11, -11, -9, -10, -9, -8, -5, -7, -7, -10,
+ -9, -6, -1, 4, 6, 4, 2, 5, 10, 13, 9, 12, 13, 14, 15, 16,
+ 13, 12, 10, 13, 14, 13, 8, 2, -1, -4, -6, -9, -15, -20, -21, -19,
+ -14, -16, -22, -21, -13, -5, -3, -3, -1, 3, 5, 10, 9, 9, 6, 8,
+ 7, 7, 7, 3, -4, -6, -4, -1, -4, -8, -10, -11, -8, -4, -6, -10,
+ -7, -8, -11, -11, -8, -5, -4, 0, 3, 3, 8, 10, 10, 12, 12, 11,
+ 10, 13, 12, 10, 6, 8, 9, 9, 11, 13, 11, 9, 10, 7, 2, -3,
+ -8, -9, -14, -16, -16, -19, -18, -14, -13, -11, -11, -10, -5, -1, 3, 5,
+ 2, 2, 9, 14, 11, 9, 10, 7, 2, 0, 2, -2, -9, -13, -15, -18,
+ -17, -15, -13, -10, -5, -5, -7, -7, -4, -1, 0, -2, -4, -2, 1, 4,
+ 9, 10, 10, 11, 11, 13, 14, 10, 11, 9, 9, 4, 6, 5, 4, 5,
+ 7, 8, 10, 9, 4, -4, -8, -9, -10, -11, -12, -14, -15, -17, -15, -9,
+ -4, -1, -6, -5, 2, 8, 8, 6, 5, 3, 4, 5, 9, 10, 10, 5,
+ -1, -5, -10, -12, -14, -16, -18, -17, -11, -10, -11, -8, -5, -2, -2, 0,
+ 3, 4, 5, 3, 2, 3, 5, 9, 12, 12, 11, 10, 12, 14, 12, 8,
+ 5, 0, -1, 1, 3, 0, 1, 3, 5, 6, 5, 0, -5, -11, -10, -13,
+ -12, -13, -15, -14, -8, -4, -3, -3, -4, 0, 4, 5, 3, 6, 4, 4,
+ 7, 10, 9, 9, 8, 5, 5, 2, -4, -10, -15, -17, -20, -22, -22, -19,
+ -14, -11, -10, -8, -6, 0, 3, 5, 3, 4, 8, 11, 11, 12, 13, 12,
+ 12, 15, 15, 16, 16, 13, 11, 6, 3, -2, -5, -5, -3, -2, -1, 2,
+ 0, -3, -4, -5, -7, -10, -12, -11, -12, -11, -8, -4, -2, 0, 1, 2,
+ 2, 2, 4, 3, 3, 4, 5, 9, 10, 6, 2, 1, 2, 0, -3, -7,
+ -13, -18, -19, -18, -16, -18, -20, -19, -14, -8, -4, -1, 3, 3, 5, 7,
+ 9, 9, 10, 12, 13, 13, 13, 13, 16, 15, 13, 9, 6, 3, 2, 1,
+ 0, -3, -5, -6, -4, -2, -2, -4, -4, -5, -5, -3, -3, -4, -6, -6,
+ -7, -4, 0, 2, 3, 2, 2, 1, 2, 2, 1, 4, 5, 4, 1, 0,
+ 2, 2, 0, -2, -6, -8, -6, -7, -9, -11, -15, -18, -19, -18, -18, -17,
+ -13, -9, -2, 2, 3, 5, 10, 12, 13, 14, 14, 15, 17, 17, 16, 16,
+ 15, 13, 11, 7, 2, -6, -10, -8, -6, -8, -8, -7, -6, -6, -3, -4,
+ -6, -5, -3, -2, -2, 0, 1, 0, 2, 2, 3, 2, 3, 2, 3, 3,
+ 5, 2, 0, 4, 6, 5, -1, -4, -2, -1, -2, -6, -8, -9, -10, -12,
+ -10, -14, -17, -22, -22, -21, -19, -15, -8, -3, 1, 7, 12, 12, 15, 19,
+ 22, 21, 18, 16, 16, 16, 13, 12, 6, 3, 3, 2, -3, -6, -7, -12,
+ -12, -11, -8, -9, -8, -7, -3, 0, 0, 0, 0, -2, -2, 0, 1, 2,
+ 2, 4, 6, 6, 7, 5, 4, 3, 4, 5, 3, 0, -2, -2, -4, -6,
+ -10, -8, -8, -10, -11, -12, -12, -12, -13, -16, -16, -16, -14, -11, -8, -4,
+ -2, 1, 6, 12, 17, 19, 20, 20, 21, 21, 19, 13, 10, 9, 5, 0,
+ -3, -4, -4, -5, -6, -6, -4, -7, -10, -12, -12, -12, -10, -7, -4, -2,
+ 4, 6, 8, 7, 7, 7, 7, 8, 8, 7, 5, 6, 6, 4, 1, -1,
+ -1, 0, -3, -7, -10, -10, -8, -11, -14, -14, -12, -11, -9, -6, -8, -8,
+ -8, -11, -13, -12, -9, -8, -5, 0, 4, 8, 11, 14, 18, 18, 20, 23,
+ 23, 20, 14, 9, 4, 0, -3, -6, -8, -8, -8, -8, -9, -10, -11, -10,
+ -9, -8, -8, -7, -6, -3, 0, 3, 6, 12, 16, 16, 14, 10, 8, 9,
+ 7, 4, 1, 0, 0, -2, -1, 0, 0, -3, -7, -10, -13, -13, -12, -13,
+ -15, -14, -13, -9, -6, -5, -5, -7, -8, -9, -7, -6, -5, -7, -5, 1,
+ 8, 13, 17, 19, 20, 21, 22, 22, 18, 12, 9, 5, -1, -5, -9, -11,
+ -13, -12, -12, -11, -10, -8, -7, -7, -6, -7, -6, -3, 0, 1, 3, 7,
+ 10, 11, 12, 15, 15, 14, 9, 6, 3, 1, 0, -2, -2, -2, -3, -6,
+ -8, -10, -11, -13, -15, -15, -15, -13, -12, -12, -7, -5, -5, -5, -4, -3,
+ -3, -4, -4, -1, -1, 1, 4, 7, 10, 12, 14, 17, 20, 22, 19, 14,
+ 8, 5, 2, -2, -5, -10, -14, -13, -11, -10, -10, -10, -10, -8, -6, -3,
+ -3, -3, -1, -1, 2, 6, 10, 13, 14, 15, 15, 15, 13, 11, 8, 5,
+ 1, -1, -3, -3, -6, -10, -12, -12, -12, -12, -13, -15, -18, -19, -15, -11,
+ -6, -4, -3, -4, -4, -2, 1, 4, 2, -1, -2, 1, 4, 6, 8, 7,
+ 7, 11, 14, 15, 15, 15, 13, 10, 6, 1, -3, -6, -9, -13, -15, -15,
+ -13, -11, -9, -9, -9, -7, -3, 0, 2, 2, 4, 7, 11, 15, 16, 14,
+ 11, 12, 13, 15, 13, 9, 4, 1, -1, -4, -6, -8, -11, -15, -17, -17,
+ -17, -17, -15, -13, -13, -12, -10, -7, -6, -4, 1, 2, 2, 3, 4, 5,
+ 4, 4, 3, 5, 6, 6, 8, 7, 7, 9, 11, 10, 9, 8, 5, 2,
+ 0, -2, -6, -10, -13, -13, -14, -14, -13, -11, -9, -4, -1, -1, -1, 2,
+ 6, 8, 10, 11, 12, 14, 14, 14, 13, 11, 10, 7, 4, 2, 3, 1,
+ -3, -6, -10, -14, -17, -18, -18, -19, -19, -17, -15, -13, -9, -5, -1, 1,
+ 0, 1, 3, 5, 6, 6, 6, 7, 8, 9, 8, 4, 1, 0, 2, 4,
+ 5, 6, 5, 4, 4, 4, 3, 1, -3, -7, -9, -11, -12, -12, -12, -11,
+ -10, -7, -4, -2, 1, 4, 5, 8, 11, 13, 14, 14, 11, 11, 11, 10,
+ 10, 9, 6, 5, 3, 1, -2, -5, -10, -14, -16, -17, -18, -19, -20, -19,
+ -17, -14, -10, -5, -1, 1, 3, 5, 6, 6, 6, 6, 6, 6, 6, 6,
+ 8, 7, 6, 4, 2, 0, -1, 0, 0, 1, 2, 1, 1, 2, 1, -2,
+ -5, -8, -9, -10, -11, -12, -12, -10, -7, -4, -1, 2, 8, 11, 13, 15,
+ 15, 13, 12, 11, 10, 9, 8, 6, 5, 4, 4, 3, 0, -3, -6, -10,
+ -14, -18, -21, -22, -21, -18, -16, -13, -10, -6, -3, 0, 3, 5, 5, 5,
+ 6, 7, 8, 8, 8, 7, 8, 7, 6, 5, 4, 1, 0, -2, -4, -4,
+ -5, -4, -4, -3, -2, -1, -2, -3, -4, -7, -8, -9, -9, -9, -8, -5,
+ -2, 2, 4, 8, 11, 14, 15, 15, 14, 12, 10, 7, 5, 4, 4, 2,
+ 1, 1, 2, -1, -3, -7, -10, -15, -18, -18, -18, -18, -17, -15, -11, -7,
+ -3, 1, 3, 4, 5, 6, 7, 7, 8, 8, 9, 10, 10, 9, 6, 4,
+ 2, 0, -3, -4, -6, -7, -7, -6, -5, -3, -2, -2, -2, -2, -3, -4,
+ -5, -6, -6, -6, -6, -5, -4, -1, 4, 7, 9, 11, 12, 12, 11, 10,
+ 9, 8, 7, 5, 3, 3, 2, 1, 0, -1, -4, -7, -8, -10, -13, -14,
+ -15, -15, -15, -14, -11, -9, -6, -3, 0, 2, 4, 5, 6, 7, 8, 9,
+ 10, 10, 9, 8, 6, 5, 3, 1, -3, -6, -8, -8, -7, -7, -7, -6,
+ -4, -2, 0, -1, -2, -3, -3, -3, -3, -4, -3, -3, -1, 1, 3, 4,
+ 6, 7, 8, 9, 10, 10, 9, 7, 6, 6, 4, 3, 2, 1, -1, -2,
+ -4, -6, -9, -11, -12, -12, -12, -11, -11, -10, -9, -8, -7, -5, -4, -1,
+ 1, 3, 5, 7, 9, 10, 11, 10, 9, 8, 7, 6, 2, -1, -3, -4,
+ -6, -7, -7, -7, -7, -6, -5, -5, -4, -3, -3, -4, -4, -4, -3, -2,
+ 0, 0, 1, 1, 2, 4, 6, 6, 7, 7, 8, 7, 7, 7, 7, 7,
+ 6, 5, 2, 0, -2, -4, -5, -7, -8, -8, -8, -9, -10, -10, -9, -8,
+ -7, -7, -7, -5, -3, -2, 0, 1, 2, 4, 6, 9, 10, 11, 12, 10,
+ 8, 6, 3, 1, -2, -4, -6, -7, -7, -7, -7, -8, -7, -7, -6, -6,
+ -5, -4, -3, -3, -2, -1, 1, 2, 2, 3, 4, 5, 5, 5, 6, 6,
+ 6, 5, 5, 6, 6, 6, 4, 3, 2, 1, -1, -3, -4, -6, -8, -9,
+ -9, -8, -8, -6, -5, -5, -5, -6, -6, -6, -5, -4, -2, 0, 2, 4,
+ 6, 7, 8, 9, 9, 9, 9, 6, 4, 1, -1, -3, -5, -6, -7, -7,
+ -7, -6, -6, -6, -6, -6, -5, -4, -3, -3, -2, -1, 1, 3, 4, 5,
+ 5, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 1,
+ -1, -3, -4, -5, -6, -7, -7, -7, -7, -7, -6, -5, -4, -4, -3, -3,
+ -3, -3, -2, -1, 0, 1, 3, 5, 7, 8, 8, 8, 7, 6, 4, 2,
+ 0, -2, -3, -4, -5, -6, -7, -7, -7, -7, -6, -6, -5, -5, -5, -3,
+ -2, 0, 1, 2, 3, 4, 5, 6, 6, 6, 5, 5, 4, 3, 3, 3,
+ 3, 3, 3, 2, 1, 1, -1, -2, -3, -4, -5, -6, -6, -7, -6, -5,
+ -4, -3, -3, -3, -3, -3, -2, -1, -1, 0, 1, 1, 1, 2, 3, 5,
+ 6, 6, 6, 5, 4, 2, 1, 0, -2, -4, -5, -5, -6, -6, -6, -7,
+ -7, -7, -6, -5, -4, -3, -2, -1, 0, 2, 3, 3, 4, 4, 5, 5,
+ 5, 4, 4, 4, 4, 3, 3, 2, 1, 1, 0, 0, -1, -1, -2, -3,
+ -4, -5, -5, -5, -5, -5, -4, -4, -3, -3, -2, -1, -1, -1, -1, 0,
+ 0, 0, 1, 2, 3, 3, 4, 4, 4, 4, 4, 3, 1, 0, 0, -2,
+ -3, -4, -5, -5, -6, -6, -6, -5, -4, -4, -4, -3, -2, -2, -1, 0,
+ 2, 3, 3, 4, 4, 4, 4, 3, 3, 3, 3, 2, 2, 1, 1, 1,
+ 0, -1, -1, -2, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -2, -2,
+ -2, -1, -1, -1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2,
+ 2, 1, 1, 0, 0, -1, -1, -2, -3, -3, -3, -4, -4, -4, -4, -3,
+ -3, -2, -1, -1, -1, 0, 1, 1, 1, 2, 2, 2, 3, 3, 2, 2,
+ 1, 1, 1, 0, 0, 0, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -5, -41, -25, -37, -9, 28, 14, 6, 1,
+ 19, 16, -83, -53, -35, -44, -29, 8, -23, -29, -6, -20, -22, -19, -40, -2,
+ 14, 34, 78, 59, 73, 93, 73, 83, 124, 94, 87, 61, 98, 80, 29, 27,
+ 6, 8, -9, -8, -26, -33, -35, -32, -25, -32, -28, -59, -46, -31, -19, -12,
+ -12, 14, 14, -41, -59, -46, -33, -32, -52, -31, -29, -49, -51, -53, -85, -53,
+ -60, -100, -85, -84, -66, -37, -26, -11, -8, 22, 41, 33, 39, 27, 29, 75,
+ 59, 45, 52, 69, 66, 73, 90, 91, 103, 81, 46, 16, -21, -32, -13, -34,
+ -22, -42, -51, -35, -53, -62, -45, -35, -34, -29, 25, 62, 61, 39, -8, -20,
+ -5, -7, 2, 28, 1, -24, 8, 29, 11, -9, -54, -34, -35, -57, -41, -63,
+ -50, -16, -18, 26, 23, -2, 38, 9, 17, 41, 39, 82, 64, 64, 103, 64,
+ 43, 43, 51, 26, -3, 30, 1, 9, 14, -26, 20, -27, -50, -39, -47, -31,
+ -23, -33, 25, 56, 51, 20, -19, -60, -41, -27, -10, 3, -36, -30, -22, -46,
+ -5, -12, -7, -4, -54, 3, -25, -10, -1, -42, -75, -27, -84, -60, -88, -107,
+ -73, -29, -67, -53, 9, -10, 17, -29, -33, 55, 12, 7, 121, 70, 42, 123,
+ 96, 127, 74, 28, 51, 21, 60, 23, -10, 25, 103, 113, 65, 45, 15, -1,
+ 10, 2, -26, 1, -16, 19, 27, -8, -8, -24, -20, -17, -35, -86, -87, -32,
+ -51, -26, -60, -60, -50, -15, -31, -30, -50, -55, -19, 22, 14, 30, 49, 42,
+ 15, -11, -57, -15, -29, -65, -37, -56, -29, 15, 70, 69, 36, 24, 19, 21,
+ 19, 4, 60, 55, 18, -17, 0, -2, -21, 51, 49, -6, 22, 14, -24, -63,
+ -5, 4, -53, -33, -1, -37, -34, 40, 30, 12, -6, -1, 12, 12, 23, 20,
+ 43, 34, 11, -26, -40, 25, 56, -1, -41, -50, -37, -10, 20, -58, -65, -43,
+ -26, 42, 57, 77, 57, 26, -4, -10, -57, -45, -23, -49, -1, -59, -41, -26,
+ -27, 24, 52, -3, -12, 19, -44, -31, 33, 11, -14, 43, 31, 7, 58, 84,
+ 45, 35, 18, -5, 6, -21, -6, -20, -7, 41, 53, 29, 25, 55, 68, 37,
+ -29, -17, -41, -67, -76, -90, -112, -104, -60, -21, 25, 16, -23, -9, 30, 47,
+ 17, 3, 19, 4, -2, 30, 24, 1, 26, 33, 34, 10, 14, 1, -5, 16,
+ -2, -60, -32, -51, -48, -38, -34, -42, -20, 16, 17, -16, -32, -6, 4, -39,
+ -18, 1, -20, -22, 55, 70, 34, 5, -1, 13, 2, 1, 28, 20, -31, -2,
+ 51, 26, 24, 19, 11, -1, 2, 30, 13, 2, 70, 36, 15, 24, 5, 9,
+ 14, 48, 43, 8, 2, -10, 18, 33, 22, -27, -19, -17, -22, 11, 19, -5,
+ 0, -55, -60, -49, -63, -72, -45, -80, -55, -18, -8, 32, 52, 22, 0, -40,
+ -42, -30, -68, -51, -9, -67, -52, -10, 7, 35, 12, 36, 64, 23, 13, 64,
+ 39, 32, 73, 3, 6, -10, -6, 16, 18, 53, 51, 21, -20, -15, 13, -3,
+ 2, -39, -30, -7, -3, 6, 10, -4, -25, -7, -10, -10, -18, -31, -23, -38,
+ -48, -3, -26, -43, -7, 11, 31, 62, 41, -7, -34, -42, -24, 17, 12, 44,
+ 25, 24, 18, 11, 32, 51, 46, 46, 51, 33, 24, 32, 30, 40, 8, -30,
+ -39, -30, -44, -19, -33, -55, -41, -36, -70, -67, -64, -34, -37, -46, 1, 19,
+ 27, 81, 23, 13, 10, -5, -18, -19, -51, -14, -48, -75, 11, 51, 43, 63,
+ 37, 20, 19, 4, -23, 27, 47, 71, 29, 16, 15, -17, -11, 32, 40, 22,
+ 6, 16, -7, 5, 34, 61, 12, -21, -24, -13, -38, -41, -36, -33, 2, 9,
+ -45, -54, -36, 12, -18, -41, -25, -18, 19, 31, -11, -16, -22, -62, -65, -68,
+ -42, -4, -48, -49, 4, 38, 65, 47, 12, -20, -20, -8, 3, 32, 69, 84,
+ 44, 28, 31, 18, 36, 57, 74, 35, 19, 6, 24, 29, 36, 35, 6, -13,
+ -25, -43, -45, -35, -33, -44, -23, -41, -57, -52, -41, -35, -21, -16, -22, -11,
+ 33, 42, 14, 19, 16, 0, -6, -34, -17, -37, -25, -7, 6, 48, 47, 3,
+ -14, -17, -19, -11, -9, -11, 42, 42, 16, 1, 6, 15, 51, 42, 33, 29,
+ 20, -5, -3, 4, 54, 42, 8, -30, -19, -15, -15, -20, -6, -7, -24, -32,
+ -24, -17, -1, -16, -18, -36, -55, -38, -2, 8, 16, 7, -21, -35, -56, -67,
+ -17, -58, -67, -36, 21, 67, 48, 15, 8, 13, -9, -8, -1, 21, 107, 56,
+ 40, 56, 32, 33, 71, 60, 36, 30, 3, 31, 15, 4, 21, 2, -2, -25,
+ -30, -26, -13, -9, -26, -20, -34, -34, -51, -28, 6, -9, -24, -49, -67, -54,
+ -54, -52, -41, -42, -58, -37, 16, 39, 31, 16, 19, 11, -4, -23, -5, 24,
+ 1, 10, 24, 26, 15, 34, 70, 77, 56, 33, 43, 28, 17, 25, 12, 2,
+ 0, -12, -15, -2, 10, -19, -28, -45, -41, -28, -17, -3, -2, -9, -3, -25,
+ -45, -14, 23, 10, -5, -19, -32, -22, -10, -1, -15, -16, -6, 13, 48, 70,
+ 55, 23, 23, 10, -8, -14, 6, 8, -12, -5, 13, 10, -14, 0, 33, 23,
+ 18, 43, 21, 26, 33, 13, -14, -7, -3, -31, -29, -5, -5, -25, -27, -35,
+ -56, -45, -21, -17, -40, -14, 2, -23, -38, -9, 8, -16, -16, -7, -13, -25,
+ -4, -12, -21, -14, 3, 13, 44, 65, 60, 40, 15, 5, -20, -22, -3, 3,
+ 20, 39, 39, 9, 6, 21, 48, 24, 25, 25, 11, 0, 4, -5, -31, -34,
+ -22, -45, -40, -24, -24, -41, -38, -47, -54, -45, -16, -22, -32, -7, 16, -1,
+ -11, 23, 31, -1, -10, -20, -19, -9, 15, -10, -28, -21, 4, 24, 45, 60,
+ 56, 46, 30, 26, 23, 36, 48, 33, 46, 40, 34, 19, 12, 23, 43, 37,
+ 41, 43, 22, 24, 11, -11, -2, -5, 8, -28, -33, -11, -5, -26, -30, -25,
+ -45, -21, -8, -26, -35, -37, -39, -54, -56, -20, -23, -42, -52, -49, -63, -47,
+ -31, -29, -16, -21, -7, 14, 26, 48, 32, 12, -10, -22, -24, -6, 0, 33,
+ 44, 31, 25, 15, 10, 34, 48, 38, 14, 9, 16, 12, -23, -15, -15, -8,
+ -9, -19, -22, -2, -8, -10, -32, -27, 4, 12, -5, 1, -1, 4, -5, -3,
+ -5, 10, 37, 18, -8, -19, -3, 0, -10, -5, -31, -32, -29, -2, 18, 32,
+ 33, 14, -12, -15, 6, 8, 36, 66, 48, 38, 37, 42, 29, 49, 50, 42,
+ 28, 25, 33, 15, 2, 4, 2, 4, 2, -11, -1, 6, 3, 9, -14, -12,
+ -5, -12, -33, -36, -29, -26, -38, -44, -42, -38, -38, -52, -67, -70, -50, -32,
+ -27, -29, -38, -26, -27, 1, 21, 23, 16, -17, -34, -26, -18, -20, 2, 11,
+ 13, 5, 10, 13, 12, 28, 33, 35, 14, 14, 14, -8, -24, -25, -8, -16,
+ -23, -14, 12, 8, 21, 25, 13, 25, 29, 25, 6, 3, 36, 26, 34, 11,
+ 30, 29, 34, 23, 0, 1, 7, 8, 1, -10, -9, -13, 5, 17, 30, 26,
+ 25, 3, -11, -4, -4, 9, 13, 17, 6, 4, 17, -1, -4, 9, 16, 22,
+ 3, -2, -4, -16, -28, -22, -13, -34, -37, -31, -9, -7, -12, -16, -26, -12,
+ -14, -11, -23, -16, -24, -33, -24, -30, -17, -28, -34, -44, -51, -34, -24, -22,
+ -25, -2, 14, 23, 38, 46, 43, 28, 10, -6, -11, 1, 0, 5, 18, 16,
+ -3, 12, 27, 23, 32, 48, 42, 34, 21, 21, 10, -3, -10, -10, -20, -38,
+ -34, -29, -22, -16, -15, -17, -9, 7, 6, 6, -6, 1, 7, 6, 3, 11,
+ 30, 30, 15, 11, 11, 10, 17, 22, 23, 24, 9, 15, 5, -2, 4, 3,
+ -17, -21, -4, -21, -6, 8, -9, -1, 0, 8, -7, -18, -16, -3, -14, -13,
+ -8, -17, -10, -8, -26, -37, -28, -17, -35, -17, -10, 1, -6, 1, 25, 32,
+ 26, 9, -18, -19, 1, -12, -20, 2, 12, 5, -4, 15, 14, 15, 15, 17,
+ 14, 2, 6, 3, -18, -21, -9, -1, -15, -11, -15, -22, -1, 3, -7, 0,
+ 14, 14, -4, -13, 4, 18, 12, 15, 19, 25, 28, 27, 12, 9, 9, -10,
+ -17, -4, -5, -4, -20, -19, 11, 20, 13, 0, -19, -8, 6, -9, 6, 26,
+ 18, 14, 17, 22, 24, 18, 21, 37, 20, 7, 11, -8, -11, -4, -3, -8,
+ -22, -16, -18, -15, -4, -9, -21, -10, 5, -8, -7, -17, -7, -9, -20, -28,
+ -35, -31, -23, -23, -29, -28, -28, -33, -28, -24, -6, 0, -4, 7, 29, 25,
+ 15, -6, -19, 1, -2, -22, 4, 10, 1, 9, 10, 13, 4, 6, 21, 15,
+ 5, 21, 11, -18, -21, -15, -3, -4, -15, -15, -19, 4, 19, 11, 2, 17,
+ 16, 2, 14, 14, 17, 20, 22, 20, 10, 16, 27, 12, 8, 11, 5, -9,
+ -10, -6, -1, -7, -12, -3, 3, 8, 9, -5, -3, 6, -5, -6, 23, 14,
+ 11, 12, 21, 21, 4, 18, 30, 7, 12, 25, 3, -11, -16, -15, -10, -13,
+ -8, -6, -21, 2, -2, -25, -18, -8, -22, -22, -17, -12, -7, -12, -15, -20,
+ -41, -28, -24, -23, -12, -12, -15, -10, -7, 2, 1, 6, 18, 29, 23, 21,
+ 20, 9, -3, -9, -9, -10, -15, -8, -11, -2, 6, 14, 7, 7, 11, 9,
+ 14, 2, 3, 7, 6, 6, -21, -20, -10, -12, -15, -16, -18, -14, -11, -14,
+ 0, 0, -5, 3, 14, 12, 9, 0, -11, 5, 5, 12, 11, -1, 5, 3,
+ 1, 4, -1, -1, 13, 16, 8, 14, 9, -2, -7, -11, -17, -12, -5, -9,
+ -10, -13, -4, 1, 0, 4, 5, 0, 2, 3, 5, 14, 18, 9, -3, 2,
+ 15, 14, 6, 2, 1, -1, -5, -6, 0, 0, 0, 7, 20, 22, 23, 13,
+ 13, 17, 20, 35, 25, 20, 20, 14, 17, 16, 3, 7, 18, 15, 13, 17,
+ 6, -5, -6, -13, -23, -19, -19, -22, -22, -24, -17, -18, -22, -27, -31, -30,
+ -29, -30, -33, -36, -34, -37, -47, -38, -24, -28, -27, -31, -30, -28, -26, -20,
+ -14, -14, -9, 4, 17, 21, 15, 12, 25, 29, 33, 33, 30, 30, 31, 19,
+ 20, 14, 4, 10, 17, 18, 21, 28, 19, 20, 20, 5, -2, -3, -7, -10,
+ -2, 1, 4, 6, 4, 5, 3, 2, -1, -4, -7, -10, -3, -6, -16, -5,
+ -1, -8, -7, -6, -9, -10, -11, -7, -6, -10, -11, 2, 11, 7, 1, 6,
+ 12, 16, 18, 15, 11, 14, 16, 9, 11, 6, 5, 13, 14, 13, 11, 0,
+ -11, -4, -4, -8, -7, -5, -6, -3, -1, 2, -1, -6, -7, -9, -9, -9,
+ -15, -11, -14, -17, -16, -18, -17, -12, -7, -8, -7, -6, -2, -3, -12, -15,
+ -15, -18, -13, -19, -23, -24, -21, -21, -13, -12, -7, -3, -7, -6, -4, 2,
+ 1, 1, 3, 9, 23, 28, 23, 17, 24, 27, 22, 19, 16, 19, 10, 9,
+ 10, 10, 19, 8, 11, 16, 15, 11, 13, 14, 7, 5, -3, -7, -12, -15,
+ -16, -17, -10, -5, 4, -2, -2, -9, -13, -9, -8, -10, -10, -12, -5, 3,
+ 7, 3, 9, 3, 4, -1, -2, 2, -4, -9, -4, 0, 4, 4, -6, -3,
+ 12, 10, 15, 12, 7, 7, 1, -1, 8, 11, 9, 9, 13, 17, 17, 9,
+ 11, 4, 0, -3, -6, -8, -9, -10, -17, -20, -24, -17, -19, -22, -20, -21,
+ -15, -16, -19, -23, -21, -28, -26, -15, -14, -4, -1, -6, -3, -1, 4, 9,
+ 2, 4, 7, 7, 11, 15, 6, 17, 24, 16, 15, 9, 6, 6, 3, 1,
+ 3, 2, -2, 6, 6, 6, 3, -6, -3, -8, -7, -10, -13, -17, -18, -16,
+ -19, -13, -9, -3, 4, 10, 7, 7, 12, 11, 13, 10, 6, 1, 2, 4,
+ 4, 10, 10, 7, 4, 1, 4, -5, -12, -3, 1, 10, 7, 6, 4, 19,
+ 22, 20, 23, 16, 15, 19, 17, 14, 9, 7, 4, 4, 2, 5, 3, 0,
+ 0, -7, -7, -8, -7, -14, -15, -18, -25, -21, -21, -16, -13, -14, -17, -18,
+ -23, -21, -23, -29, -32, -33, -30, -23, -13, -11, -10, -8, -7, -2, 1, -3,
+ -1, 5, 13, 17, 13, 11, 13, 16, 14, 10, 11, 8, 16, 13, 4, 0,
+ 7, 13, 14, 15, 15, 17, 17, 9, 8, 9, 9, 2, 5, 11, 14, 7,
+ 4, 11, 10, 5, 7, 2, -1, -4, -9, -16, -15, -12, -9, -15, -23, -21,
+ -22, -22, -20, -22, -22, -21, -22, -22, -13, -6, 4, 2, -2, 2, 7, 6,
+ 10, 8, 9, 12, 21, 16, 11, 7, 11, 13, 11, 10, 11, 13, 9, 6,
+ 6, 5, 4, -5, 1, 4, 5, -1, -2, 6, 3, 3, -3, -10, -14, -14,
+ -14, -16, -8, -6, -1, -6, -7, -5, -7, -6, -9, -8, -8, -4, -5, -8,
+ -6, 3, 12, 4, -2, 3, 1, 1, -1, -4, -4, 5, 6, 1, -4, -3,
+ 5, 9, 8, 18, 20, 22, 15, 11, 11, 15, 12, 9, 11, 11, 11, 5,
+ 10, 12, 5, 3, -2, -4, -9, -9, -16, -17, -14, -12, -14, -20, -15, -16,
+ -17, -17, -19, -20, -19, -15, -17, -15, -13, -2, -3, -13, -8, 0, 4, 7,
+ 6, 4, 11, 13, 14, 11, 5, 6, 3, -1, -2, 2, 3, -1, -2, -6,
+ -4, -1, -3, 0, 3, 1, -2, -5, -5, -3, -6, -9, -7, -15, -13, -10,
+ -8, -4, 1, 9, 7, 2, 8, 8, 9, 12, 14, 7, 12, 12, 12, 8,
+ 14, 19, 11, 7, 10, 13, 10, 2, -2, -6, -1, 2, 6, 3, 1, 4,
+ 2, 2, 5, 8, 8, 7, 7, 2, 0, -3, -6, -3, -1, -6, -12, -9,
+ -6, -7, -9, -10, -14, -16, -12, -12, -11, -13, -16, -16, -20, -18, -14, -10,
+ -8, -9, -13, -9, -8, -9, -7, -9, -8, -3, -4, -3, -6, 0, 2, 3,
+ -3, 2, 5, 1, 6, 5, 5, 10, 11, 17, 15, 20, 25, 20, 15, 17,
+ 13, 12, 11, 7, 4, -1, -2, 6, 7, 7, 9, 10, 7, 9, 7, 5,
+ 5, 1, -6, -2, -5, -6, -3, -3, -1, -3, -5, -3, -6, -8, -7, -8,
+ -11, -12, -16, -19, -19, -14, -14, -17, -17, -11, -12, -15, -6, -8, -12, -12,
+ -9, -7, -6, 2, 9, 6, 8, 11, 13, 15, 14, 11, 7, 3, 3, 4,
+ 7, 9, 10, 6, 6, 5, 7, 11, 11, 4, 1, 1, -3, -5, -1, -1,
+ -1, -5, -2, -1, -1, 1, 1, -3, -7, -7, -9, -12, -11, -3, -3, -7,
+ -6, -6, -5, -5, 0, -3, -4, -2, 2, -1, 0, 6, 7, 7, 4, 3,
+ 5, -1, 0, -1, -7, -9, -8, -11, -5, 0, -1, 0, 2, 2, 5, 10,
+ 10, 7, 7, 7, 8, 8, 9, 11, 9, 8, 9, 6, 4, 2, 0, -3,
+ -5, -8, -8, -12, -8, -1, -4, -4, -5, -7, -9, -6, -5, -6, -8, -6,
+ -3, -7, 0, 5, 6, 3, 1, 6, 6, 4, 3, 1, -2, -4, -6, -4,
+ 3, 7, 3, 0, -1, -3, -2, -1, -2, -5, -8, -9, -7, -9, -8, -6,
+ -9, -7, -9, -7, -6, -7, -6, -7, -7, -7, -7, -8, -2, 1, 2, 4,
+ 3, 5, 6, 10, 11, 9, 10, 12, 9, 9, 11, 9, 10, 8, 7, 7,
+ 6, 7, 5, 4, 5, 4, -1, -4, -3, -5, -1, -2, -4, -4, -4, -4,
+ -2, -2, -3, -4, -2, -1, 0, 1, 8, 8, 4, 4, 4, 2, -2, -3,
+ -5, -6, -9, -10, -8, -5, 2, 1, -2, -2, -2, -2, -2, -5, -5, -7,
+ -7, -3, -4, -6, -4, -3, -5, -7, -5, -4, -7, -9, -6, -6, -9, -7,
+ -6, -2, 3, 3, 4, 5, 3, 4, 5, 2, 0, 2, 3, 2, 5, 7,
+ 10, 9, 7, 7, 6, 4, 1, -2, -5, -6, -10, -10, -8, 2, 8, 7,
+ 6, 7, 5, 5, 7, 6, 3, 4, 3, 4, 1, 3, 2, 4, 2, 1,
+ 1, -1, -3, -3, -4, -6, -9, -9, -9, -7, -6, -5, -5, -4, -5, -2,
+ -1, -2, -3, -1, -1, -3, -2, 2, 2, 3, 4, 4, 2, 0, -1, -3,
+ -4, -4, -5, -7, -2, 2, 2, -1, -3, -1, -4, -3, -2, -4, -4, -2,
+ -1, -2, -4, -2, -2, -1, -2, -2, -2, -3, -2, 0, 2, 0, -2, -2,
+ 0, 2, 3, 5, 4, 4, 4, 6, 3, 1, 0, 0, 0, 0, 5, 5,
+ 4, 6, 4, 2, 0, -2, -3, -6, -9, -8, -10, -10, -2, 3, 4, 4,
+ 4, 5, 4, 4, 5, 4, 4, 4, 4, 2, 3, 2, 2, 2, 1, 1,
+ 0, -2, -3, -3, -4, -6, -8, -7, -4, -6, -3, -3, -3, -2, 1, 0,
+ -1, -2, -2, -1, -1, 0, 1, 0, 0, 1, 0, 0, 0, -1, -2, -3,
+ -3, -4, -5, -4, -3, -3, -3, -3, -3, -3, -2, -1, 0, -1, 0, 0,
+ 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 2, 3,
+ 3, 2, 2, 0, -1, -1, -2, -3, -3, -4, -5, -4, 0, 3, 3, 3,
+ 3, 2, 3, 4, 6, 4, 4, 3, 2, 1, 2, 1, 0, 0, -1, -2,
+ -3, -3, -2, -2, -3, -3, -3, -3, -3, -2, -2, -2, -2, -2, -2, -2,
+ -2, -3, -2, -3, -2, -2, 0, 0, 0, 0, 0, -1, -1, -2, -2, -3,
+ -2, -4, -4, -3, 0, -1, 0, 0, 0, 0, 0, 1, 2, 1, 1, 1,
+ 0, 0, 0, -1, 0, -1, -1, -1, -1, -1, 0, 0, -1, 0, 0, 0,
+ 1, 1, 1, 1, 1, 1, 0, 0, 0, -1, 0, -1, 0, 0, 0, 0,
+ 0, 0, -1, -1, -2, -2, -2, -2, -2, -3, -3, -1, 0, 0, 0, 0,
+ 0, 0, 0, 1, 1, 1, 0, 0, 0, -8, -33, -24, -25, -25, -26, -27,
+ -32, -28, -36, -31, -36, -22, -34, 11, -74, -14, 94, 41, 28, 33, 30, 40,
+ 34, 23, 41, 40, 60, 56, 59, 60, 44, 39, 54, 45, 52, 17, 44, 62,
+ 34, 33, 19, 18, 43, 35, 22, 36, -15, -10, 32, -7, -12, -6, -8, -50,
+ -47, -44, -4, -25, -48, -76, -58, -75, -96, -85, -118, -114, -63, -106, -103, -83,
+ -110, -99, -84, -76, -58, -63, -61, -51, -53, -36, -32, -41, -27, -11, 11, 8,
+ 27, 19, 30, 35, 28, 57, 53, 38, 71, 51, 68, 110, 78, 89, 109, 97,
+ 82, 94, 115, 114, 79, 70, 79, 94, 85, 76, 84, 95, 83, 82, 55, 54,
+ 54, 41, 41, 27, 20, 6, -11, -21, -16, -14, -33, -33, -52, -54, -59, -62,
+ -71, -79, -88, -88, -78, -78, -72, -71, -94, -99, -93, -90, -78, -87, -105, -103,
+ -79, -62, -71, -78, -63, -61, -66, -49, -23, -10, -11, -24, -20, -4, -22, 9,
+ 8, 27, 43, 34, 38, 51, 83, 65, 58, 74, 75, 70, 73, 71, 65, 100,
+ 89, 94, 65, 84, 49, 49, 61, 54, 43, 51, 58, 53, 35, 40, 36, 38,
+ 34, 23, 14, -12, -10, -1, -1, -11, -12, -19, -33, -66, -52, -42, -37, -55,
+ -42, -28, -32, -29, -35, -41, -28, -25, -46, -85, -64, -62, -55, -49, -68, -55,
+ -53, -52, -47, -43, -26, -32, -41, -34, -35, -40, -26, -8, -1, -6, -11, 5,
+ -2, 8, 3, 8, 6, 4, 20, 29, 43, 24, 33, 20, 30, 24, 39, 38,
+ 40, 29, 37, 36, 39, 61, 58, 41, 51, 59, 51, 55, 58, 48, 32, 45,
+ 40, 27, 30, 41, 44, 26, 19, 23, -3, 7, 0, -3, 2, 3, -6, -5,
+ -14, -6, -10, -27, -45, -47, -41, -38, -50, -51, -46, -43, -45, -65, -65, -80,
+ -95, -82, -74, -66, -69, -67, -33, -31, -53, -48, -51, -43, -18, -24, -24, -33,
+ -26, -10, 0, -17, -6, 17, 31, 2, 23, 45, 46, 12, 75, 38, 63, 69,
+ 31, 38, 80, 57, 48, 59, 81, 74, 32, 52, 72, 24, 60, 44, 55, 40,
+ 28, 48, 33, 24, 10, -2, 21, 34, 13, 18, 7, -1, -12, -20, -18, -30,
+ -9, -7, -30, -27, -26, -38, -20, -54, -55, -64, -53, -36, -62, -37, -71, -47,
+ -42, -71, -45, -55, -50, -54, -56, -36, -37, -54, -36, -12, -38, -33, -26, -7,
+ -22, -44, -10, 2, 3, 15, 8, 18, 6, 12, 8, 15, 28, 22, 50, 35,
+ 55, 42, 36, 49, 52, 64, 48, 60, 49, 60, 62, 40, 47, 68, 52, 59,
+ 61, 44, 53, 44, 35, 31, 31, 47, 22, 6, 4, -7, 5, -4, -21, -13,
+ -9, -10, -27, -46, -32, -44, -46, -62, -44, -51, -67, -53, -59, -63, -74, -67,
+ -61, -61, -65, -47, -58, -57, -45, -41, -46, -41, -38, -22, -25, -34, -16, -10,
+ -18, 0, 1, -6, 5, 17, 15, 10, 23, 38, 28, 28, 54, 40, 19, 55,
+ 55, 41, 46, 53, 40, 49, 51, 52, 41, 56, 39, 53, 38, 33, 35, 18,
+ 15, 38, 30, 23, 27, 13, 11, 7, 16, -1, 0, 0, 13, -6, -10, -15,
+ -10, -10, -24, -20, -16, -38, -36, -21, -40, -32, -42, -38, -52, -53, -41, -48,
+ -58, -50, -47, -37, -41, -45, -29, -41, -6, -48, -24, -25, -15, -9, -10, -10,
+ -10, -1, -17, 4, 3, 10, -4, 9, 15, 25, 24, 19, 23, 34, 28, 33,
+ 37, 38, 26, 36, 47, 35, 46, 45, 28, 35, 32, 32, 24, 21, 26, 23,
+ 19, 37, 20, 9, 29, -2, 26, 24, 8, 4, 14, 21, 11, -9, -8, 4,
+ -9, -31, -11, -15, -21, -24, -29, -22, -33, -26, -29, -48, -32, -44, -28, -22,
+ -35, -30, -38, -31, -46, -44, -36, -27, -23, -29, -24, -11, -20, -28, -13, -34,
+ -19, -1, 7, -3, -1, 6, -3, 5, 4, 8, 17, 26, 19, 33, 27, 16,
+ 35, 14, 36, 39, 22, 32, 31, 19, 32, 23, 29, 21, 30, 29, 23, 31,
+ 13, 24, 17, 11, 26, 18, 12, 5, 23, 16, 9, 15, -10, 3, 18, -15,
+ -4, -4, 6, -14, -15, -5, -34, -11, -20, -18, -8, -17, -29, -30, -29, -19,
+ -34, -35, -20, -36, -20, -16, -21, -38, -16, -30, -24, -25, -19, -18, -15, -7,
+ -5, -5, -10, -23, -3, -14, 0, -1, -12, -9, 7, 7, 2, 12, 5, 7,
+ 19, 10, 21, 21, 27, 30, 22, 18, 34, 22, 11, 26, 24, 20, 21, 25,
+ 29, 22, 27, 27, 20, 10, 20, 16, 22, 15, 16, 16, 5, 19, 10, 3,
+ 22, -5, -5, -7, -16, -4, -11, -22, -7, -16, -11, -23, -16, -30, -24, -28,
+ -20, -29, -24, -32, -22, -22, -30, -17, -23, -28, -22, -20, -21, -21, -17, -30,
+ -15, -14, -20, -9, 3, 6, 5, -20, 10, 13, -2, 11, 8, -1, 7, 16,
+ 5, 22, 23, 13, 22, 13, 22, 25, 15, 16, 11, 15, 13, 7, 12, 19,
+ 18, 20, 12, 23, 11, 6, 10, 1, 11, 19, 5, 20, 0, 11, 11, 1,
+ 14, 15, -3, -1, -7, 6, -6, -9, -9, 4, -3, -10, -20, -14, -9, -14,
+ -7, -10, -5, -4, -29, -14, -12, -26, -21, -27, -18, -10, -19, -27, -18, -8,
+ -25, -8, -13, -15, -14, -15, 5, -13, -7, -11, -4, -12, 0, 15, 5, 4,
+ 1, 11, 6, 4, 3, 6, 21, 19, 8, 15, 13, 6, 14, 16, 18, 17,
+ 20, 15, 11, 15, 24, 13, 11, 19, 7, 17, 14, 6, 17, 7, 7, 6,
+ 6, 5, 11, 0, 6, 0, -6, 5, 1, -11, -6, -1, -8, -9, -15, -7,
+ -4, -16, -17, -13, -13, -17, -14, -12, -12, -28, -13, -19, -25, -31, -24, -17,
+ -17, -16, -7, -15, -12, -8, -15, -8, -16, -10, -4, -1, -2, 3, 5, 2,
+ -2, 5, 3, 6, 10, 8, 11, 14, 14, 13, 15, 22, 16, 14, 18, 13,
+ 17, 19, 16, 10, 17, 8, 17, 14, 3, 14, 7, 10, 10, 7, 6, 6,
+ -1, 6, 1, 0, 12, -6, 6, 12, -4, -5, -4, -2, -2, -1, -2, -8,
+ -11, -9, -11, -11, -18, -6, -5, -16, -9, -14, -10, -13, -10, -11, -15, -14,
+ -14, -12, -17, -17, -17, -7, -11, -14, -15, -12, -6, -15, -5, -13, -9, 0,
+ 12, -2, -2, 6, 2, -7, 4, 10, 2, 9, 8, 7, 4, 5, 11, 15,
+ 11, 10, 18, 9, 13, 13, 13, 21, 11, 18, 19, 13, 14, 16, 6, 8,
+ 1, 19, 11, 10, 11, 1, 3, -1, -1, 5, -11, 5, -1, -5, -3, -13,
+ -10, -6, -7, -5, -15, -10, -11, -18, -8, -16, -20, -18, -9, -12, -17, -21,
+ -21, -13, -21, -8, -10, -10, -5, -16, -7, 2, -6, -6, -9, -7, -2, -9,
+ -5, 6, -7, 1, 3, -1, 2, 1, 2, 9, 8, 5, 15, 12, 1, 11,
+ 9, 8, 10, 15, 14, 5, 13, 17, 14, 15, 10, 7, 16, 5, 5, 5,
+ 8, 9, 10, 10, 7, 0, 4, 6, 9, -10, -4, 5, 2, -1, 0, -3,
+ -4, -5, -10, -5, -8, -9, -10, -3, -13, -6, -9, -20, -15, -11, -18, -14,
+ -10, -12, -20, -14, -14, -7, -12, -21, -14, -9, -8, -11, -5, -2, -7, -4,
+ 4, -2, -3, -1, 0, -1, 8, 6, 9, 7, 10, 6, 3, 4, 7, 10,
+ 11, 6, 9, 17, 11, 9, 7, -2, 16, 13, 12, 18, 5, 16, 9, 4,
+ 9, 6, 8, 9, 4, 4, 3, -2, -3, 2, -6, -3, 1, -7, -6, -3,
+ -6, -14, -8, -9, -4, -13, -9, -8, -16, -10, -12, -13, -11, -7, -8, -12,
+ -9, -8, -7, -11, -4, -8, -7, -8, -3, -13, -10, -3, 6, -5, -5, 0,
+ -5, -3, 6, -2, -2, 4, -2, 6, 2, -2, 5, 5, -2, 5, 15, 13,
+ 4, 6, 6, 14, 9, 4, 8, 7, 3, 11, 12, 2, 10, 7, 10, 8,
+ 4, 6, 2, 0, 3, 2, 4, 2, -6, -2, 2, -4, 3, -5, -6, -5,
+ -5, -5, -4, -8, -7, -4, -4, -7, -8, -7, -13, -10, -10, -11, -9, -8,
+ -8, -7, -11, -7, -3, -9, -6, -7, -3, -4, -5, 3, -3, -1, -2, -4,
+ 1, 4, 0, 3, 0, 5, 2, 0, 5, 4, 1, 3, 1, 0, 1, 7,
+ 3, 0, 4, 3, 6, 5, 0, 9, 5, 7, 6, 3, 6, 2, 3, 5,
+ -4, 9, 0, 4, 10, 0, 5, 1, -2, 4, -3, -3, -2, 0, 2, -7,
+ 3, -10, -1, -6, -9, -2, -4, -10, -3, -7, -6, -4, -10, -6, -6, -11,
+ -6, 0, -6, -8, -4, -1, -9, -10, 0, -6, -7, -2, -7, 1, -5, -5,
+ -1, 1, -6, 2, 0, -3, -1, 7, -4, 0, 7, 0, 8, 2, 3, 4,
+ 4, 2, 5, -1, 6, 7, 5, 6, 4, 2, 4, 6, 8, 6, 3, 1,
+ 8, 9, 2, -1, 4, 3, 4, 3, -3, 7, 4, 3, -2, 2, -4, -6,
+ -2, -5, -2, -3, 0, -5, -6, -13, -5, -6, -11, -9, -10, -5, -4, -9,
+ -9, -7, -7, -8, -8, -6, -5, -7, -5, -1, -3, -4, -2, -2, 2, -3,
+ 1, 2, -3, 1, 2, 1, 0, 1, 5, 0, 2, 5, 2, 0, 4, 1,
+ 7, 3, 2, 6, 0, 5, 7, 5, 5, 1, 3, 3, 5, 10, 3, 4,
+ 8, 2, 7, 3, -2, 3, 0, -1, -1, 1, 0, 1, -3, -2, -5, -4,
+ -3, -1, -7, -8, -4, -4, -10, -2, -8, -8, -8, -8, -9, -6, -8, -9,
+ -4, -2, -7, -5, -2, -7, -6, -9, -2, 0, -4, 4, -6, -3, -4, -1,
+ 2, 1, 2, 9, 0, 3, 0, 6, 4, 0, 5, 6, 2, 7, 7, 5,
+ 7, 6, 8, 6, 6, 5, 5, 1, 6, 5, -1, 3, 4, -1, 4, 1,
+ 4, 3, -5, 0, 4, 1, 4, -2, -3, -4, 0, -4, -8, -2, -5, -4,
+ -8, -6, -5, -3, -3, -7, -9, -6, -10, -10, -6, -6, -5, -4, -7, -6,
+ -4, -10, -3, -10, 0, -2, -2, -6, -1, 3, -3, -3, 1, 2, 1, 4,
+ 3, 4, 3, 4, 1, 2, 6, 5, 5, 5, 7, 9, 1, 5, 4, 4,
+ 7, 2, 9, 2, 4, 8, 2, 5, 6, 3, -2, -2, -1, -2, -1, 1,
+ -2, -4, 1, -6, -2, -5, -3, -5, -5, -6, -4, -3, -4, -10, -4, -3,
+ -8, -4, 0, -3, -5, -6, -6, -3, -1, -7, -3, 1, -1, -4, -2, 1,
+ -2, 0, -1, -2, 0, 0, 5, -2, 0, 3, 3, 1, 5, 2, 4, 1,
+ 4, 1, 2, 3, 3, 3, 4, 3, 3, 5, 1, 4, 2, 3, 1, 2,
+ 0, 2, 1, -2, -2, -1, 0, -2, -1, -1, -3, -5, -2, 0, -5, -1,
+ 0, -5, -2, -2, -2, -3, -3, -1, -4, -1, -2, -4, -2, -1, -2, -1,
+ 0, -3, -1, -1, 0, 1, -1, -1, 3, -4, -2, -2, 4, -2, -1, -1,
+ -1, 0, 0, -1, -1, -1, -1, 2, 0, -1, 2, -1, 0, -1, 2, 0,
+ 3, 5, -2, 1, 2, 0, 5, 0, -3, 4, -3, 1, 2, 0, 4, -1,
+ -2, 1, 0, 0, 0, -1, 1, -2, 0, 1, 1, 0, -5, 1, -2, -1,
+ 0, -2, -3, -1, -3, 0, -2, -3, -4, 1, -2, -3, -2, -2, -1, -1,
+ -2, -1, -4, -5, 2, -4, 0, 1, -1, 2, -2, -1, 0, 0, 1, -3,
+ 3, 2, 0, -2, 2, 1, 2, -2, 5, 3, -2, -2, -1, 1, 0, 0,
+ 1, 3, 2, 0, 0, -1, -2, 1, 1, 2, 1, 1, -1, 0, -1, -1,
+ -1, -3, 1, 1, 2, -2, -1, 0, 0, -2, 0, -1, -1, 2, -2, 1,
+ -1, 0, 0, -1, -1, -2, 0, -1, 1, -1, -1, 2, -2, 0, -1, -1,
+ 2, -1, 0, -3, -1, 0, 0, 0, -3, -3, -2, 0, 0, -1, -1, 0,
+ -4, 2, 0, -2, 0, 1, -3, -1, 2, 1, 0, -1, 0, 0, -1, 0,
+ 2, -1, -1, 0, 0, -2, 1, 1, 0, 1, 0, 2, -3, -2, 2, -1,
+ -1, 2, -2, 1, 1, 0, 0, 1, 1, 0, -4, 3, -1, 2, 0, 2,
+ -1, -2, 0, 1, 1, -1, -1, -1, -1, -1, -2, -2, -2, -2, -2, -1,
+ -1, 1, 0, -5, 0, -1, -1, -1, 1, -1, 1, -1, 1, 0, -2, 0,
+ -2, 1, -1, 1, 0, -1, -2, 0, -1, 0, 0, 2, 0, 0, 0, 1,
+ 0, 0, 2, 0, -1, 0, 0, 0, 2, -1, 1, 1, -1, -1, 0, 0,
+ 1, 1, 0, 0, 0, 0, -1, 0, 0, -2, 0, 0, -1, 1, -2, -1,
+ -1, -1, -2, -1, -2, 1, -1, 0, -2, -2, 1, -2, -1, 1, 0, 1,
+ 1, -1, -1, 0, -1, 0, 0, 0, -2, 0, -1, 0, 0, -1, -2, -2,
+ -2, 1, -1, 0, 0, -1, 1, 1, -2, -1, -2, -1, 1, -1, -1, -2,
+ -2, 0, 0, 1, -1, -1, -1, -1, -2, 2, 0, 0, 1, 1, 1, -2,
+ 0, -1, 0, -1, -1, 2, 0, -1, -1, -1, 1, -1, 2, 0, -1, 1,
+ 1, 0, 1, 0, -1, -1, -1, -1, -3, 0, 0, -1, 1, 0, 0, -2,
+ -2, -2, 0, -1, 0, 0, -1, 0, -1, -2, -1, -2, 0, -2, 0, 0,
+ -1, -2, 1, -2, 0, -1, -2, 2, 0, -1, 2, -1, 1, -1, 0, 0,
+ -1, 0, 0, 0, -1, 0, 1, 0, 0, 1, 0, -1, -1, 0, -2, -1,
+ 0, 0, 1, 0, 0, 0, 0, -1, -1, 1, -1, -2, -1, 0, 0, -2,
+ 0, -1, 0, 0, 0, 1, 0, 0, -1, 1, 0, -1, 0, 1, -1, 0,
+ -1, -2, 0, -1, 0, -1, -1, -1, 0, -1, 0, 0, 0, -1, -1, 0,
+ -2, 0, 0, 0, -2, -2, 0, -2, -1, -1, -1, -2, 0, -1, -1, -1,
+ 0, 0, -1, -1, 0, 1, -1, -1, 0, -1, 0, 0, 1, 1, 0, 0,
+ -1, 0, 0, 0, 0, 0, 1, -1, 0, 0, 0, 1, 0, 0, -1, 0,
+ 0, -1, -1, 0, -1, -1, 0, -1, 0, -1, -1, 0, -2, -1, 0, -1,
+ -1, -1, -1, 0, -1, 0, 0, 0, 0, -1, 1, 0, 0, 0, -1, -1,
+ 0, -1, -1, 0, 0, 0, 0, 0, -1, -1, 0, -1, -1, 0, 0, -1,
+ 0, -2, 0, -1, -1, -1, 0, -1, -1, 0, -1, 0, 0, 0, -2, -1,
+ 0, -1, -1, 0, 1, -1, -1, 0, 0, 0, 0, -1, -1, -1, -1, 0,
+ 1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, -1, 0, 0,
+ -1, 0, 0, -1, -1, -1, 0, 0, -1, -1, 0, -1, 0, 0, 0, -1,
+ 0, -1, -1, 0, -2, -1, -1, -1, 0, -1, 0, -1, -1, 0, 0, -1,
+ 0, -1, 0, -1, -1, -1, 0, -1, 0, -1, 0, 0, -1, 0, -1, 0,
+ 0, -1, -1, 0, 0, 0, -1, 0, -1, 0, 1, -1, 0, 0, 0, 0,
+ 0, -1, 0, 0, 0, -1, 0, 0, -1, -1, 0, 0, 0, -1, 0, 1,
+ -1, -1, -1, 0, 0, -1, -1, -1, -1, 0, -1, 0, 0, 0, 0, 0,
+ 0, -1, -1, 0, -1, -1, 0, -1, 0, -1, -1, -1, -1, 0, -1, -1,
+ -1, -1, -1, -1, -1, 0, -1, 0, -1, 0, 0, -1, -1, 0, -1, 0,
+ -1, 0, 0, -1, 0, -1, -1, -1, 0, -1, 0, 0, 0, 0, 0, -1,
+ -1, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, -1, 0, 0, 0,
+ 0, -1, 0, -1, 0, 0, 0, -1, -1, 0, 0, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, 0, 0, -1, -1, -1, 0, 0, 0, -1, 0, -1, -1,
+ 0, -1, 0, 0, -1, -1, -1, -1, -1, 0, 0, -1, 0, 0, -1, 0,
+ 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, -1, 0, 0, 0, 0,
+ -1, 0, 0, 0, 0, -1, 0, 0, -1, 0, -1, 0, 0, -1, -1, -1,
+ 0, -1, -1, 0, -1, -1, 0, 0, -1, -1, -1, -1, 0, -1, -1, 0,
+ 0, -1, 0, 0, 0, -1, -1, 0, -1, -1, -1, 0, 0, -1, -1, -1,
+ -1, -1, 0, -1, 0, 0, -1, -1, 0, 0, -1, 0, 0, -1, -1, -1,
+ 0, -1, 0, 0, -1, -1, 0, 0, -1, -1, 0, 0, 0, -1, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1,
+ 0, 0, 0, -1, 0, -1, 0, -1, -1, -1, -1, -1, -1, 0, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, 0, -4, 11, 6, 16, 10, -16, -48,
+ -44, 2, 67, 42, -17, -51, 15, 71, 12, -22, -14, -44, -35, 11, 17, -18,
+ 2, -15, 19, 12, -1, -44, -15, 50, 45, -25, -61, 17, 10, -10, 31, 18,
+ -72, -27, 57, 26, -13, -17, -2, 6, -1, -23, -54, 17, 39, 8, 30, 28,
+ -6, -71, -5, 33, 27, -5, 17, 10, -23, -6, 12, -26, -6, -7, -9, -14,
+ 11, 37, 41, 8, -33, -14, 8, -31, -38, 13, 9, 15, 35, 33, 11, 17,
+ -41, -48, -33, 29, 25, 16, -9, -9, -17, -19, -29, 43, 64, -2, -55, -42,
+ -1, -21, -4, 29, 34, -25, -67, -29, 1, 51, 49, 25, -6, -15, -48, -76,
+ -3, 60, 78, 33, 19, 13, -38, -35, -35, -2, 62, 19, -4, -12, -4, -4,
+ -32, -30, 8, 68, -43, -66, -28, 55, 51, 20, -28, -29, -19, 20, -2, 8,
+ 21, -15, -43, 24, 22, -7, -2, 35, 15, -2, -24, -12, 3, 31, 13, -15,
+ -20, -17, -17, 26, -26, 24, -3, 7, 21, 26, -3, -17, -26, -50, -26, 33,
+ 58, 49, -22, -67, -17, 24, 7, -57, 5, 42, -11, -3, 32, -3, 7, 13,
+ -11, -9, 27, 17, 1, -5, -9, -18, -19, -3, -23, -5, 7, -8, 9, 13,
+ 12, -5, 7, -37, 22, 26, 21, 24, -20, -35, 23, 24, -35, -15, 46, -38,
+ -48, -14, -4, 0, -22, 3, 43, 38, -1, -14, -8, -5, -14, 1, 21, 23,
+ 29, -19, -47, -42, -49, -10, 66, 77, 48, -29, -32, 1, -11, 8, 17, -17,
+ 3, 43, 33, -22, -19, -41, 29, 22, -42, 9, 63, 28, -23, -59, -65, 7,
+ 53, -22, -10, -27, -30, 36, 48, -4, -6, -22, -16, 10, 14, -7, 22, 50,
+ -4, -25, -41, -55, -62, 23, 68, -16, -31, 49, 57, 21, -38, 14, 12, -43,
+ -49, -16, 28, 7, -12, -50, -17, 49, 65, 18, 1, -8, 28, 2, -27, -13,
+ 12, -11, -52, 4, 31, -32, -39, 15, 8, -19, 6, 25, -1, -23, 13, 34,
+ 59, 36, -16, -5, -7, -28, -30, 1, -14, -42, 10, 43, 26, -25, -37, -61,
+ 1, 63, 62, 1, -36, -24, 38, -7, -26, 27, 10, 4, 2, -19, -22, -27,
+ -24, 0, 33, -8, -57, -12, 62, 77, 51, -10, -42, -27, -28, -31, -3, 5,
+ 21, 10, 15, -27, -18, -18, -10, 3, 17, 19, 18, -16, -20, 25, -3, -19,
+ -5, 32, 17, -3, -32, -8, 2, -11, -24, -17, -11, 3, 42, 15, -12, -2,
+ 26, 9, -4, -30, -3, 16, 7, 13, 34, 40, 114, 11, -104, -71, 7, -14,
+ -34, -26, 35, 45, 47, 7, -7, -16, 11, -6, -29, -32, 1, 24, 32, 10,
+ 29, -10, -74, -80, -20, 18, 9, 18, 61, 38, -27, -44, 13, 16, -26, 20,
+ 69, 14, -14, -46, -7, -6, -35, 0, 9, 5, 58, 71, -36, -78, -15, 43,
+ 34, -61, -101, -27, 45, 26, -10, 23, 69, 69, 5, -72, -62, 19, 16, -37,
+ -60, 37, 60, 10, -49, -10, -2, -1, 43, 44, 10, -50, -5, 19, 8, -43,
+ -58, -17, 32, 28, 4, -1, -18, -10, 13, 8, 1, 1, 22, -3, -4, 9,
+ -8, -9, 17, 3, -15, -8, 14, 11, -14, -11, -5, 13, -24, -34, -1, -16,
+ -4, 32, 35, -32, 9, 22, 12, -27, -16, 14, 15, 0, -2, -12, -31, -24,
+ 14, 48, 10, -14, -7, -22, 4, -8, -14, 19, 21, -21, -25, -12, 19, 24,
+ 19, 27, -3, -15, -16, 10, 21, -14, 3, 8, 3, -11, -33, -16, 7, 5,
+ -8, 2, -3, 12, 5, -34, -19, -6, 26, 19, 0, -4, -12, 5, 12, 20,
+ 16, 19, 18, -13, -42, -26, -1, 0, -18, -16, 10, 27, 23, -5, -7, 9,
+ -8, 7, 22, 10, -28, -51, -26, 13, 44, 17, 16, 25, 14, -32, -45, -36,
+ -40, -3, 22, 41, 34, -12, -35, -31, 18, 3, 31, 28, 4, -21, 2, -14,
+ -24, -23, 19, -6, -7, -10, -1, -13, -13, 21, 52, 28, 7, 1, -25, -36,
+ 2, 34, 10, -37, -31, -13, 19, 11, -4, -20, 15, -5, -18, 40, -13, 15,
+ -36, 14, 18, 17, -21, 6, -39, 21, 7, -26, 8, -33, 24, 30, 32, -11,
+ -26, -47, -39, 62, 10, 11, 5, -17, -21, 10, 0, 18, 15, -22, 7, 13,
+ 14, -8, -9, 30, 33, -34, -41, -32, 37, 24, -19, -15, 1, 2, 10, 10,
+ -27, -46, -14, -9, 9, 47, 1, -22, -18, 5, 37, 29, -3, -19, -19, -18,
+ 8, 17, 1, -11, -6, -20, 27, 37, -2, -28, -34, -3, 22, 54, 34, -31,
+ -43, -28, -30, -33, 26, 49, 45, 43, -15, -58, -13, -2, -27, -7, 41, 11,
+ 19, -50, -74, -28, 31, 75, 39, -45, -7, 99, 44, -83, -47, 45, -1, -30,
+ 23, 29, -55, -30, 31, 28, -19, 2, -44, -46, -49, 30, 22, 58, 31, -50,
+ -20, 9, -38, -53, 49, 37, -9, 13, -25, -18, 18, -27, -7, 17, 3, 24,
+ 57, 26, -51, -52, -54, -43, 53, 85, 31, -36, -44, 7, 13, 19, -23, -33,
+ 36, 47, -38, -11, 37, -19, -6, 18, 17, 2, 31, 54, -29, -72, -80, -1,
+ 27, 52, 10, -29, -40, -48, -72, 24, 108, 66, -44, -76, -32, -24, 21, 69,
+ 54, 24, -2, -8, -28, -44, -50, 34, 95, 45, -40, -72, -32, 6, 28, -1,
+ 18, -7, 27, 1, -14, 21, -8, -51, -62, -24, 64, 56, 12, 19, -36, -22,
+ 10, 20, -10, -1, -5, -51, 36, 72, -42, -51, 70, 45, -48, -27, 54, 19,
+ -46, 8, 0, -46, 10, 37, 35, -21, -32, -22, -44, -82, -33, 59, 105, 48,
+ -32, -36, -31, 18, 60, -12, -49, 10, 89, 28, 12, 8, -45, -21, -6, -16,
+ -32, -17, -18, 3, 29, -3, 0, -20, -51, -31, 24, 52, 1, -17, -20, 1,
+ 35, 15, 5, 35, 27, 18, -19, 8, -71, -74, -8, 88, 57, -45, -37, 17,
+ 51, -1, -13, -4, 3, -13, -24, -7, 30, -7, -25, -1, 16, -8, -43, -70,
+ 11, 85, 77, 12, -62, -57, 35, 53, -33, -96, 8, 82, 21, -38, 25, 39,
+ -1, -27, -14, 18, -16, -45, -24, 42, 7, -9, 22, 32, -39, -5, -8, -49,
+ -17, 60, 88, 21, -93, -20, 82, 31, -26, -63, -17, 52, -28, -25, 13, -2,
+ -32, -46, 55, 56, -37, 6, -57, -33, 65, 63, 5, -25, -31, 69, 86, -32,
+ -34, -56, -23, -47, 14, 44, -23, 19, 6, 60, -27, -69, -37, 20, -14, -5,
+ 50, 44, 15, 13, -23, -60, -46, 23, 40, -5, -25, 6, 46, -4, -10, -27,
+ -12, 28, 45, 10, -13, -33, -19, -39, 42, 32, -23, -25, 24, -17, 13, 25,
+ 13, -32, 13, 48, 4, -93, -5, 40, -7, 37, -39, -37, 41, 1, -13, -33,
+ 43, -53, 106, 8, -57, -93, 55, 40, 56, -24, -4, -19, 7, -23, -65, -18,
+ 34, -30, 7, 66, 92, 3, -43, -37, -23, 12, -7, -17, 14, -15, -9, -18,
+ 18, 51, -1, -57, -17, 23, 19, 15, -40, -1, 0, -8, 39, -13, -43, 72,
+ 57, -1, -54, -17, 32, -19, 11, 0, 36, 25, -23, -86, 21, -3, 14, -17,
+ 76, 37, 23, 2, -23, -54, -42, -80, 61, 60, 63, -12, -57, -44, 15, 35,
+ 26, 11, -44, -22, 8, 33, -24, -17, 21, 38, -25, -39, 16, 43, -36, -28,
+ 54, 10, -52, -18, -34, -14, 76, 60, 24, -32, -19, 16, -13, -68, -5, 30,
+ -13, -23, -14, 61, 24, 35, 39, 4, -50, -58, -39, 0, 43, 43, 21, 24,
+ -20, -46, -36, 38, 8, -67, -8, 61, 38, 10, -12, 5, -4, -16, -47, -5,
+ -18, -20, 37, 41, 24, 4, 7, -19, 11, -52, 0, 17, 20, -30, -33, -16,
+ 60, 34, -15, -46, -77, 14, 29, 26, 21, 25, 8, 7, 36, 23, -39, -16,
+ 21, 11, -23, 11, -4, -6, -35, 13, -8, -49, -17, 44, 19, -25, -17, 9,
+ -5, -5, -1, -31, 11, 15, 17, -8, -31, -51, 12, 54, 85, 32, 4, -58,
+ -35, -31, 0, 10, 21, -20, -20, -29, 15, 26, -7, 8, 4, 0, 30, 2,
+ -26, 2, 19, 15, -18, -13, -20, -19, 47, 33, -6, -51, -30, -12, 12, 30,
+ 34, 31, 4, -45, -81, -7, -22, 1, 73, 98, 24, -67, -13, 19, -32, -86,
+ 6, 94, 4, -47, 21, -11, -50, 22, -3, -2, 50, 20, -37, -59, 35, 28,
+ -16, -36, -30, -11, 4, 69, 98, -65, -84, 73, 27, -90, -17, 84, 10, -51,
+ -14, 40, -24, -11, 16, -34, -26, 38, -43, -34, 58, 85, -33, -51, 17, 7,
+ 4, 52, 25, -35, 0, 44, -21, -47, 40, 44, -69, -65, 37, 35, -21, 4,
+ 32, -60, -75, 21, 64, 60, -6, -11, 6, 2, -41, -34, 19, 31, 9, 7,
+ -1, 11, 6, -11, -26, -23, 16, 35, -39, -68, 6, 56, -3, -42, 29, 28,
+ 3, 28, 14, -37, -16, 11, -8, -18, 15, -1, -8, 43, -20, -67, -12, 34,
+ 7, -12, -9, 5, -4, 7, -12, 27, -3, -68, 26, 96, 30, -33, -28, -25,
+ 19, 27, -33, -48, -3, 37, -1, -35, -11, 5, 42, 36, 6, -48, -38, 26,
+ 54, -23, -41, 52, 44, -32, -22, 28, -23, -32, 12, 41, -16, -6, -6, -17,
+ -18, -14, -12, -5, 18, 52, 45, -10, -16, 29, 11, -36, -26, 7, 36, 12,
+ -57, -48, 48, 70, 16, 21, -13, -46, -33, -62, -63, -21, 94, 94, 20, -110,
+ -47, 41, 67, -16, -57, -40, 85, 71, 7, -39, 15, -29, -50, -41, 18, -40,
+ -42, 38, 69, 21, -8, -58, -19, 23, 24, -20, -10, 11, 41, 7, -6, -30,
+ -23, 2, 16, 57, 38, -11, -50, 36, -16, -51, -51, 81, 24, -68, -84, 39,
+ 112, 62, -79, -104, 24, 102, 15, -38, 20, 22, -49, -91, 15, 51, 30, -1,
+ -15, -30, -12, 17, 42, -17, -48, 0, 49, 35, 2, -19, -16, -30, 9, 17,
+ -12, -4, -15, 5, 34, -1, -56, -64, 7, 48, 54, -16, -51, 20, 62, -17,
+ -27, -9, -10, -29, -1, 35, 44, -20, -23, -2, -12, -4, 31, 24, -24, -14,
+ 2, -28, -27, 49, 61, -54, -61, 6, 23, -20, 2, 41, 26, 2, 15, -5,
+ 6, -16, -36, -16, 2, -54, -53, -18, 62, 64, 10, -3, 91, 39, -54, -103,
+ -5, 16, -31, -28, 75, 105, -32, -114, -52, 68, 32, -52, -19, 25, 54, 61,
+ 14, -40, 12, 1, -56, -31, 74, 40, -73, -66, 0, 49, 36, 24, -20, 0,
+ 13, -40, -99, -11, 55, 31, -33, 39, 24, 3, -18, 7, 10, 4, -29, 17,
+ 19, 27, -30, -41, 9, 33, -24, -25, 30, 28, -34, -57, 8, -7, -46, 5,
+ 48, -22, -6, 57, 58, -31, -72, -2, 72, 44, -53, -42, 41, 1, -54, 30,
+ 54, -6, -79, -14, 33, -6, -22, 14, 10, -5, -8, 13, 23, 21, -47, -74,
+ 22, 24, -10, -7, 39, 2, 12, -7, -2, 4, 33, -20, -33, 18, 22, -88,
+ -71, 26, 81, 14, -37, 3, -24, 6, -8, 11, 40, 18, -7, -17, 20, -8,
+ -15, -41, -11, 27, 52, -27, -46, 33, 21, 46, -30, -13, 26, -91, -106, -47,
+ 54, 109, 67, -87, -90, 38, 92, 31, -10, -69, -73, -27, -6, 24, -6, 20,
+ 30, 45, 33, -13, -25, 10, 57, -16, -32, 0, -14, -55, -20, 4, 7, -4,
+ 3, 18, -11, 34, 11, -45, -45, -125, -38, -2, 19, 72, 82, 99, 98, 35,
+ -51, -81, -53, 3, -39, 23, -4, -58, -63, -24, 40, 84, 48, -7, -18, -2,
+ -8, -20, -10, 3, 21, 17, -39, -66, -20, -2, 37, 30, 39, 34, -5, -41,
+ -26, 33, 40, 18, -2, 11, 13, -20, -60, -21, 33, -25, -35, 30, 65, 22,
+ 13, -15, 2, 16, 11, -68, -18, 74, 10, -74, -34, -39, -17, 8, 59, 39,
+ -22, -38, -8, 9, 30, 23, 11, -3, -12, 10, -1, 59, 9, -28, -72, -27,
+ 32, 68, -11, -3, 27, 4, -33, -39, 7, -1, -5, -7, 26, -14, -26, -40,
+ -12, 5, 5, 1, -12, 64, 63, -41, -56, 10, 26, 40, -26, -44, -42, 25,
+ -6, 3, -1, 10, 9, -1, 9, 1, -28, 10, 24, 26, -33, -36, 46, 20,
+ -43, -52, -35, 22, 53, 30, -6, 18, -16, -49, -36, 45, 10, 21, 7, 9,
+ -33, -50, 21, 73, 33, -42, -46, 42, -12, -18, 5, -50, -25, 68, 55, -31,
+ -79, -7, 77, 25, -6, 29, 78, 24, -87, -41, -30, -41, -23, 75, 35, -32,
+ -65, -7, -13, 3, 41, 34, -24, -33, 25, 14, -52, -28, 19, 76, 45, -45,
+ -47, -5, 24, 9, -14, -41, -5, 49, 22, 10, -31, -35, -1, -6, 3, 10,
+ -1, -12, -20, -51, 9, 79, 53, -36, -38, -13, -14, -15, 50, 50, -36, -33,
+ 0, 5, 22, 23, 24, -51, -81, -27, 56, 42, -10, -16, 0, 0, -5, 16,
+ 12, -19, 11, 10, -15, -1, -32, -17, 1, 11, 62, -16, -21, 9, 21, -29,
+ -50, 16, 82, 17, -35, -4, 11, 3, 8, 8, -9, -13, 10, -39, -63, -19,
+ 54, 58, -16, -25, 18, 38, -8, -50, -54, -17, 18, 47, 17, -33, -45, 0,
+ 52, 57, -5, -34, -17, 32, 10, -28, -10, -21, -3, -9, -20, 20, 47, 22,
+ 5, -4, -15, -37, -22, -28, 9, 37, -18, -13, 3, 15, -33, -47, 20, 73,
+ 0, -36, 33, 60, -11, -77, -13, 42, 13, -20, 9, 47, 22, -27, 29, 6,
+ -71, -78, -20, 21, 4, 27, 23, 19, 31, 45, -29, -54, -10, 37, -78, -46,
+ -14, 67, 108, 57, 12, -62, -108, -15, 116, 56, -58, -110, -33, 33, 30, -39,
+ -26, 11, 29, 22, 8, 52, 76, 31, 0, -31, -50, -10, 59, 54, -13, -84,
+ -65, -60, 0, 35, 105, 61, -30, -117, -62, 35, 88, 57, 48, -38, -85, 41,
+ 12, -21, -6, 7, 15, 73, -30, -72, -37, 25, 0, -5, 65, 76, -90, -78,
+ 24, 47, 2, -14, 40, 83, 0, -32, -46, -62, -26, 50, 37, -4, -44, -40,
+ 55, 31, -38, -13, -17, -30, -4, 7, 68, 39, 1, -23, -38, -30, 6, -35,
+ 14, 52, -9, -62, -47, 45, 44, 11, -17, -9, 6, 16, 34, -3, -32, -21,
+ -33, -3, 21, 26, -39, 11, 65, 33, 19, -1, -49, -85, -97, 66, 58, -93,
+ -15, 15, 5, 81, 76, 29, -2, -52, -51, -30, 65, 38, -45, -14, 1, 28,
+ 22, 43, 19, -59, -109, -29, 29, -14, -22, -41, 0, 54, 76, 16, 8, 23,
+ 15, -47, -39, -8, 5, 36, -6, -3, -4, 13, 13, 21, -47, -53, -6, -9,
+ -27, -44, 8, 86, 64, 12, -5, -32, -10, -20, -27, -23, 8, 30, 1, 16,
+ 42, -35, -8, 4, -39, -11, -62, -29, 108, 87, -20, -104, -18, -55, 8, 47,
+ -16, 29, 38, 4, -44, -39, -20, 38, -13, 23, 82, 30, -67, -93, 26, 79,
+ 20, -79, -74, -23, 33, 59, 80, 39, -42, -100, 0, 19, 38, 9, -55, 9,
+ -15, 22, 68, -17, -55, -23, 1, 87, 19, -56, -60, 32, 37, 38, -67, -33,
+ -1, 31, 24, 15, -30, -5, -36, -29, -27, 8, 27, -9, 12, 29, 38, 33,
+ 0, -39, -18, 6, 19, 18, 8, 1, -33, 9, -1, 2, -29, -66, 0, 41,
+ 6, -50, -13, 9, 73, -28, -47, -21, 30, 68, 31, 32, 29, -46, -14, 13,
+ -44, -75, -3, 62, 55, 9, -49, -1, 54, 19, -6, 7, 16, 38, 13, -26,
+ -55, -76, -23, 16, 21, -33, -22, 16, 61, 25, -14, -35, 12, 23, -7, -17,
+ -32, -10, -16, -1, 7, 18, -1, 19, -2, -1, 21, -14, 1, -44, -44, -23,
+ -29, -1, 28, -28, 47, 64, 12, -4, -15, -37, -7, 24, 50, 6, -15, -26,
+ -5, 20, 12, -25, -21, -2, -18, -23, 9, 16, 24, 36, -30, -35, -12, 32,
+ 19, -13, 19, -6, 2, -2, -22, -11, 14, 50, 10, -21, -55, -14, 23, 6,
+ 6, -6, -26, -25, -8, 25, 14, 24, 14, -13, 18, 11, 23, -34, -49, -45,
+ 6, 39, 37, 3, 0, -29, 8, 26, -6, -7, -21, 2, -11, 6, 16, -1,
+ -17, 6, 32, -4, -54, -9, 22, -14, 6, 27, -1, -2, 34, 33, 8, 1,
+ -8, -14, -32, 23, -22, -23, -29, -12, 5, 25, 22, -4, 14, 5, 24, -39,
+ -29, 17, -21, -80, -60, -9, 78, 99, 81, -41, -53, 22, 11, -69, -22, -2,
+ 70, 80, 18, -56, -54, -79, -27, 56, 46, 28, -1, 12, -37, -76, 23, 64,
+ -4, -5, 4, 0, -2, -5, 10, -4, -9, 5, 3, 3, -2, 6, -2, -1,
+ 0, 2, 0, 1, -2, 2, -3, -2, 0, 1, -1, 0, 0, -1, -1, -1,
+ 0, -1, -1, -1, -1, 0, 0, -1, 0, -1, -1, -1, -1, -1, -1, 0,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -2, -3, -5, -6, -5, -5,
+ -3, 0, -1, -3, -1, 7, 16, 20, 8, -8, -24, -35, -39, -36, -35, -42,
+ -47, -35, -14, 0, 8, 17, 28, 45, 60, 65, 64, 66, 67, 60, 50, 39,
+ 26, 14, 5, -14, -40, -54, -56, -56, -55, -47, -36, -20, 1, 13, 15, 16,
+ 12, 2, -10, -20, -33, -43, -42, -38, -43, -40, -28, -17, -7, 6, 21, 34,
+ 48, 60, 63, 64, 66, 61, 54, 51, 41, 23, 10, 1, -18, -37, -46, -54,
+ -63, -60, -46, -30, -13, 5, 15, 16, 17, 11, -2, -11, -21, -34, -44, -45,
+ -43, -42, -33, -21, -17, -10, 5, 23, 39, 54, 62, 61, 62, 63, 59, 53,
+ 47, 38, 23, 10, -5, -23, -36, -42, -51, -61, -61, -48, -26, -2, 14, 16,
+ 13, 13, 9, -1, -14, -27, -36, -42, -44, -48, -44, -31, -17, -10, -8, 1,
+ 21, 47, 65, 67, 58, 54, 58, 61, 54, 41, 31, 23, 11, -9, -30, -41,
+ -44, -45, -54, -61, -52, -21, 11, 25, 19, 8, 4, 7, 2, -15, -33, -39,
+ -39, -44, -51, -48, -34, -12, -2, -4, -2, 19, 54, 74, 72, 58, 47, 51,
+ 59, 54, 40, 26, 20, 7, -16, -37, -46, -44, -42, -51, -58, -47, -15, 19,
+ 31, 25, 9, -1, -1, -4, -15, -30, -37, -41, -51, -55, -48, -28, -11, -4,
+ -2, 6, 28, 58, 73, 74, 63, 50, 45, 46, 49, 42, 31, 19, -6, -30,
+ -43, -44, -42, -51, -54, -49, -33, -3, 18, 30, 31, 17, 2, -13, -15, -15,
+ -25, -31, -45, -62, -60, -45, -24, -16, -10, 6, 20, 40, 58, 68, 74, 69,
+ 55, 41, 37, 44, 43, 34, 15, -17, -41, -48, -46, -51, -59, -51, -34, -16,
+ 3, 17, 29, 33, 23, 2, -15, -18, -18, -22, -31, -50, -64, -61, -42, -30,
+ -24, -8, 13, 35, 50, 57, 65, 70, 70, 58, 42, 40, 41, 40, 32, 6,
+ -23, -45, -53, -55, -64, -60, -45, -24, -1, 10, 19, 27, 28, 23, 4, -9,
+ -17, -22, -23, -36, -53, -61, -60, -47, -36, -22, -3, 19, 44, 56, 60, 65,
+ 65, 65, 60, 52, 45, 39, 37, 23, -2, -26, -49, -63, -66, -63, -55, -42,
+ -16, 3, 14, 25, 25, 22, 19, 11, -2, -17, -20, -29, -44, -50, -58, -64,
+ -53, -32, -13, 0, 25, 45, 53, 65, 68, 61, 60, 63, 60, 47, 42, 33,
+ 7, -10, -26, -56, -73, -68, -57, -53, -37, -12, -1, 14, 32, 26, 16, 17,
+ 16, 1, -12, -19, -38, -52, -47, -55, -65, -50, -23, -9, 4, 27, 40, 48,
+ 68, 72, 59, 58, 67, 64, 52, 42, 21, -5, -16, -31, -60, -73, -62, -54,
+ -49, -34, -17, -4, 17, 32, 24, 13, 18, 20, 6, -11, -29, -46, -48, -46,
+ -54, -59, -41, -17, -5, 6, 20, 35, 54, 71, 68, 55, 60, 74, 71, 53,
+ 27, 5, -6, -16, -35, -62, -70, -57, -49, -45, -40, -25, 4, 25, 29, 15,
+ 7, 23, 27, 10, -20, -46, -47, -41, -39, -47, -55, -34, -11, -1, 4, 11,
+ 38, 67, 72, 62, 48, 61, 83, 76, 49, 9, -9, -7, -15, -31, -59, -70,
+ -55, -48, -46, -43, -21, 16, 29, 22, 6, 1, 25, 32, 10, -28, -57, -47,
+ -34, -30, -38, -49, -33, -12, -4, 3, 17, 50, 72, 68, 55, 44, 61, 86,
+ 77, 41, -2, -16, -10, -13, -28, -56, -69, -58, -52, -47, -35, -7, 22, 25,
+ 13, -4, -2, 25, 33, 7, -35, -58, -46, -29, -22, -32, -44, -34, -16, -5,
+ 8, 30, 59, 72, 65, 46, 39, 62, 87, 76, 33, -8, -20, -13, -10, -28,
+ -57, -70, -62, -51, -42, -24, 3, 23, 23, 4, -15, -4, 25, 34, 3, -38,
+ -55, -45, -23, -17, -32, -43, -34, -15, -1, 14, 41, 64, 73, 59, 35, 35,
+ 64, 89, 73, 26, -11, -23, -14, -11, -33, -60, -69, -59, -48, -39, -14, 11,
+ 25, 17, -11, -24, -3, 30, 35, -3, -40, -54, -41, -18, -19, -36, -41, -28,
+ -10, 0, 21, 51, 70, 71, 47, 24, 36, 72, 93, 65, 17, -14, -22, -13,
+ -17, -43, -62, -63, -52, -48, -36, -5, 19, 26, 5, -26, -27, 5, 40, 31,
+ -12, -42, -50, -34, -20, -28, -37, -33, -17, -8, -1, 29, 61, 75, 64, 31,
+ 19, 44, 85, 93, 51, 9, -15, -18, -16, -30, -50, -57, -52, -48, -52, -32,
+ 3, 25, 20, -10, -34, -21, 19, 42, 20, -17, -40, -43, -35, -30, -32, -32,
+ -21, -12, -12, 3, 37, 67, 72, 50, 25, 24, 57, 92, 81, 42, 6, -12,
+ -18, -25, -39, -53, -52, -44, -49, -51, -28, 6, 25, 13, -17, -32, -11, 29,
+ 39, 8, -24, -38, -37, -33, -36, -39, -30, -10, -3, -9, 3, 38, 68, 71,
+ 46, 23, 32, 68, 92, 71, 31, 5, -7, -16, -31, -50, -55, -45, -37, -49,
+ -53, -27, 8, 23, 8, -20, -24, 3, 34, 28, -6, -28, -32, -30, -35, -46,
+ -43, -23, 0, 0, -10, 5, 41, 67, 65, 42, 30, 47, 77, 83, 52, 23,
+ 10, 2, -16, -43, -60, -55, -38, -36, -53, -53, -25, 8, 19, 3, -14, -8,
+ 17, 29, 9, -17, -24, -22, -26, -43, -53, -42, -14, 4, -3, -9, 10, 44,
+ 63, 58, 43, 43, 63, 77, 64, 38, 24, 20, 7, -23, -52, -62, -49, -38,
+ -45, -57, -49, -19, 6, 11, 2, -1, 12, 22, 13, -7, -18, -15, -17, -32,
+ -50, -52, -32, -11, -4, -8, -3, 21, 44, 55, 53, 52, 63, 70, 64, 49,
+ 35, 34, 24, 0, -29, -53, -54, -50, -51, -56, -57, -37, -17, -2, 7, 9,
+ 20, 21, 12, 1, -13, -11, -13, -24, -36, -49, -40, -30, -22, -12, -9, 10,
+ 25, 38, 51, 57, 70, 71, 62, 57, 44, 42, 34, 15, -4, -30, -42, -53,
+ -65, -61, -61, -49, -35, -22, -2, 10, 25, 27, 15, 11, -1, -8, -14, -22,
+ -27, -37, -37, -37, -40, -26, -14, -2, 10, 24, 42, 54, 68, 73, 65, 65,
+ 60, 49, 36, 27, 15, -7, -25, -43, -63, -69, -65, -61, -54, -36, -13, 3,
+ 18, 26, 23, 20, 16, 1, -16, -21, -20, -31, -37, -38, -40, -38, -25, -15,
+ -7, 11, 34, 48, 56, 66, 71, 72, 73, 61, 43, 34, 29, 11, -14, -31,
+ -46, -63, -69, -72, -69, -53, -28, -7, 3, 16, 27, 30, 28, 15, -3, -14,
+ -19, -25, -39, -42, -37, -38, -35, -30, -19, -2, 18, 39, 47, 56, 69, 75,
+ 78, 71, 60, 49, 35, 22, -1, -20, -32, -50, -65, -76, -75, -63, -49, -27,
+ -9, 6, 22, 28, 31, 27, 16, 6, -13, -26, -36, -43, -41, -42, -42, -36,
+ -27, -10, 2, 18, 38, 52, 64, 70, 73, 79, 76, 70, 50, 27, 11, -5,
+ -21, -41, -62, -69, -72, -68, -61, -50, -26, -4, 13, 21, 23, 32, 35, 27,
+ 6, -21, -33, -37, -42, -48, -53, -45, -31, -19, -8, 3, 23, 45, 59, 65,
+ 65, 73, 88, 88, 69, 40, 19, 10, -6, -30, -54, -69, -69, -68, -67, -59,
+ -43, -18, 2, 10, 15, 22, 39, 46, 27, -3, -28, -34, -37, -48, -56, -60,
+ -48, -29, -16, -1, 14, 35, 52, 58, 60, 64, 80, 96, 88, 64, 34, 16,
+ 6, -11, -36, -62, -77, -75, -68, -58, -47, -33, -14, -1, 7, 15, 28, 43,
+ 44, 24, -6, -30, -38, -40, -49, -63, -68, -56, -30, -5, 15, 27, 40, 51,
+ 59, 63, 72, 84, 91, 83, 60, 32, 12, 1, -14, -45, -73, -84, -78, -62,
+ -46, -36, -28, -17, 0, 11, 20, 31, 38, 35, 20, -6, -28, -40, -46, -58,
+ -72, -71, -52, -26, 4, 26, 37, 45, 54, 64, 69, 74, 81, 80, 73, 59,
+ 35, 13, -5, -28, -54, -75, -79, -74, -63, -43, -30, -21, -11, 0, 14, 23,
+ 29, 33, 23, 14, -2, -25, -41, -58, -69, -71, -64, -43, -24, 3, 33, 47,
+ 56, 60, 64, 73, 74, 75, 73, 62, 56, 38, 13, -12, -42, -57, -69, -77,
+ -71, -63, -44, -25, -15, -3, 2, 13, 26, 23, 24, 19, 8, -2, -24, -44,
+ -64, -74, -64, -60, -45, -16, 9, 34, 53, 63, 68, 66, 75, 73, 63, 66,
+ 62, 49, 34, 11, -17, -43, -54, -66, -82, -72, -52, -43, -28, -10, 0, 4,
+ 18, 27, 16, 13, 20, 8, -11, -26, -47, -66, -63, -59, -63, -47, -7, 20,
+ 34, 56, 69, 65, 73, 81, 67, 54, 61, 63, 44, 25, 6, -23, -37, -44,
+ -69, -85, -69, -48, -39, -26, -7, -4, 5, 27, 25, 9, 10, 15, 5, -17,
+ -34, -52, -62, -54, -54, -60, -40, -5, 21, 41, 59, 67, 66, 78, 81, 64,
+ 53, 58, 56, 39, 18, -3, -24, -34, -45, -64, -76, -67, -51, -37, -21, -8,
+ -3, 11, 22, 20, 11, 9, 11, -4, -23, -38, -56, -57, -53, -50, -42, -31,
+ -5, 21, 41, 63, 67, 72, 77, 69, 67, 58, 56, 49, 28, 16, -8, -28,
+ -35, -50, -53, -62, -65, -53, -44, -20, -2, 2, 14, 10, 14, 17, 7, 5,
+ -13, -27, -37, -60, -58, -55, -42, -22, -18, -2, 13, 36, 69, 73, 76, 71,
+ 62, 70, 60, 53, 42, 23, 16, -13, -35, -45, -51, -40, -46, -58, -60, -52,
+ -17, 4, 8, 11, 5, 14, 15, 4, -4, -20, -23, -37, -62, -67, -59, -27,
+ -2, -3, -3, 3, 36, 70, 77, 75, 66, 67, 70, 57, 46, 32, 29, 19,
+ -17, -49, -62, -46, -25, -33, -54, -68, -51, -15, 4, 8, 6, 11, 18, 8,
+ -7, -19, -16, -12, -35, -68, -83, -56, -9, 13, 7, -7, 4, 40, 66, 73,
+ 69, 73, 80, 69, 46, 27, 31, 42, 24, -23, -68, -69, -36, -14, -25, -57,
+ -66, -43, -16, -3, -2, 11, 28, 23, -2, -31, -29, -4, -1, -34, -83, -89,
+ -45, 3, 22, 6, -3, 16, 41, 56, 55, 68, 93, 93, 65, 23, 12, 38,
+ 53, 27, -38, -80, -64, -29, -12, -31, -54, -49, -34, -22, -24, -11, 28, 47,
+ 25, -24, -51, -27, 5, 5, -43, -90, -79, -34, 6, 11, 4, 17, 31, 39,
+ 34, 38, 79, 114, 105, 50, 3, 12, 44, 56, 16, -49, -72, -54, -28, -29,
+ -44, -37, -27, -28, -41, -45, -5, 46, 61, 17, -44, -53, -20, 7, -6, -53,
+ -78, -62, -27, -7, -6, 14, 41, 45, 26, 11, 38, 93, 127, 101, 34, 1,
+ 20, 48, 42, -1, -41, -53, -45, -40, -51, -44, -18, -9, -34, -61, -47, 7,
+ 57, 58, 2, -46, -43, -14, -5, -27, -52, -58, -46, -31, -26, -12, 28, 59,
+ 45, 10, 6, 50, 104, 124, 87, 30, 11, 30, 40, 19, -9, -26, -35, -44,
+ -58, -62, -38, -4, -6, -46, -67, -37, 21, 56, 43, -4, -37, -30, -15, -25,
+ -40, -44, -38, -38, -43, -38, -9, 40, 64, 37, 5, 14, 65, 106, 107, 75,
+ 36, 26, 34, 24, 4, -8, -10, -24, -53, -70, -64, -30, 0, -16, -53, -61,
+ -22, 28, 43, 29, -2, -21, -20, -26, -39, -43, -34, -26, -43, -54, -40, 0,
+ 46, 56, 30, 12, 30, 75, 97, 90, 69, 47, 38, 29, 13, 2, 0, -1,
+ -27, -61, -71, -55, -25, -14, -32, -50, -41, -6, 22, 25, 17, 4, -8, -19,
+ -31, -38, -35, -28, -35, -53, -54, -29, 7, 31, 32, 23, 28, 51, 72, 78,
+ 72, 65, 55, 42, 30, 19, 15, 11, -8, -36, -58, -58, -42, -35, -35, -43,
+ -40, -18, 0, 12, 14, 11, 9, -4, -15, -25, -31, -28, -36, -49, -53, -45,
+ -18, 1, 12, 19, 23, 43, 58, 64, 68, 64, 64, 57, 46, 40, 28, 22,
+ 9, -17, -35, -48, -47, -44, -47, -45, -44, -31, -12, -2, 7, 10, 9, 7,
+ -2, -8, -19, -28, -32, -44, -51, -48, -37, -21, -9, 5, 16, 26, 43, 55,
+ 60, 64, 63, 61, 58, 55, 48, 34, 21, 6, -13, -27, -39, -49, -53, -50,
+ -46, -41, -32, -16, -3, 5, 11, 9, 6, 5, -4, -17, -32, -40, -42, -44,
+ -42, -40, -32, -12, 5, 17, 24, 35, 50, 58, 64, 64, 60, 65, 61, 50,
+ 34, 18, 10, -2, -18, -38, -58, -56, -49, -45, -41, -38, -22, -4, 8, 14,
+ 8, 11, 10, -5, -20, -38, -41, -36, -37, -40, -48, -37, -12, 4, 14, 19,
+ 27, 46, 59, 66, 63, 62, 70, 64, 50, 34, 22, 17, 8, -11, -38, -59,
+ -57, -50, -49, -47, -43, -28, -6, 10, 16, 10, 14, 8, 1, -5, -5, -4,
+ -5, 5, 2, 2, 1, -1, 0, 1, 0, 2, 0, 0, -2, -1, -1, 2,
+ 1, 1, 0, 0, -1, 0, -1, 0, 0, 0, 0, 0, 0, -1, -1, -1,
+ 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, -1,
+ -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1,
+ -1, 0, 1, 0, 0, 0, 1, 0, 1, 0, -3, -10, -11, -8, -13, -25,
+ -21, -10, 0, 2, 18, 41, 44, 42, 66, 62, 28, 10, 17, 17, -16, -10,
+ 25, 28, 29, 34, 47, 34, -7, 7, 25, -12, -43, -44, -40, -61, -85, -78,
+ -55, -42, -33, -10, 17, 31, 43, 59, 51, 25, 25, 40, 27, -1, 2, 25,
+ 30, 15, 12, 27, 26, 13, 16, 9, -24, -43, -37, -49, -83, -92, -62, -40,
+ -42, -36, 1, 33, 34, 45, 61, 46, 27, 32, 33, 10, -6, 15, 38, 26,
+ 4, 15, 35, 19, 7, 17, 3, -26, -41, -50, -67, -91, -82, -48, -40, -46,
+ -24, 18, 33, 32, 54, 62, 46, 30, 22, 20, 7, 4, 28, 33, 15, 10,
+ 22, 25, 9, 13, 18, -2, -29, -54, -65, -74, -86, -68, -49, -46, -32, -8,
+ 17, 29, 45, 65, 60, 43, 23, 13, 17, 12, 18, 28, 22, 19, 16, 13,
+ 14, 16, 24, 13, -13, -40, -66, -72, -75, -74, -64, -55, -36, -20, -9, 15,
+ 43, 63, 65, 51, 37, 17, 9, 19, 23, 21, 19, 24, 21, 3, 4, 24,
+ 31, 18, -2, -20, -49, -77, -74, -65, -71, -69, -47, -27, -27, -10, 38, 66,
+ 59, 52, 51, 34, 4, 11, 36, 26, 12, 22, 26, 2, -11, 25, 45, 18,
+ 0, -1, -23, -72, -83, -55, -65, -83, -61, -34, -37, -36, 23, 71, 55, 43,
+ 60, 55, 11, 1, 40, 37, 8, 16, 31, 6, -22, 14, 55, 27, -3, 8,
+ 2, -52, -83, -57, -56, -89, -79, -43, -43, -55, -4, 66, 61, 35, 56, 68,
+ 31, 4, 32, 46, 13, 7, 31, 16, -24, -4, 50, 42, 2, 7, 16, -25,
+ -67, -60, -54, -86, -95, -55, -44, -63, -32, 40, 62, 40, 47, 67, 48, 22,
+ 32, 42, 18, 4, 25, 25, -15, -16, 29, 44, 21, 11, 15, -5, -39, -49,
+ -59, -85, -96, -72, -52, -62, -50, 7, 45, 49, 50, 56, 56, 43, 42, 39,
+ 19, 9, 16, 21, 1, -16, 9, 32, 31, 24, 14, 5, -14, -34, -52, -81,
+ -94, -85, -71, -62, -55, -21, 21, 41, 53, 55, 55, 57, 51, 44, 26, 13,
+ 15, 11, 3, -3, 0, 19, 27, 29, 26, 11, 0, -16, -41, -70, -90, -88,
+ -85, -80, -57, -34, -3, 26, 42, 57, 57, 60, 64, 50, 33, 20, 17, 9,
+ -6, -1, 6, 10, 23, 26, 28, 22, 10, 1, -27, -60, -78, -87, -90, -94,
+ -74, -42, -20, 10, 34, 44, 57, 65, 71, 58, 35, 30, 23, 8, -5, -7,
+ 4, 7, 19, 33, 23, 19, 24, 17, -13, -53, -65, -75, -96, -98, -83, -61,
+ -40, -7, 32, 38, 38, 66, 83, 65, 36, 36, 37, 8, -7, 1, 0, -5,
+ 11, 39, 34, 10, 21, 36, 4, -45, -59, -59, -89, -106, -84, -67, -62, -32,
+ 21, 41, 30, 47, 85, 80, 41, 34, 45, 20, -8, 0, 9, -7, -6, 31,
+ 45, 21, 12, 32, 25, -27, -55, -52, -76, -104, -95, -70, -64, -57, -7, 33,
+ 34, 38, 67, 84, 57, 35, 46, 29, -1, -4, 7, 7, -8, 12, 41, 31,
+ 21, 24, 25, -5, -43, -45, -65, -98, -98, -82, -62, -58, -35, 13, 27, 38,
+ 59, 70, 67, 45, 49, 39, 2, -3, 2, 9, 9, 6, 30, 30, 24, 31,
+ 20, 3, -26, -37, -48, -91, -100, -88, -75, -53, -41, -9, 12, 23, 55, 65,
+ 61, 54, 51, 51, 14, -6, 1, 1, 15, 18, 26, 29, 16, 30, 28, 4,
+ -14, -29, -36, -71, -100, -93, -87, -64, -38, -16, 2, 6, 33, 61, 59, 56,
+ 54, 55, 32, 1, -3, -4, 5, 25, 36, 36, 17, 14, 25, 14, -4, -19,
+ -30, -53, -84, -94, -95, -82, -49, -16, 4, 2, 10, 37, 56, 61, 58, 54,
+ 42, 19, 3, -9, -8, 14, 41, 53, 32, 10, 7, 10, 10, -7, -25, -43,
+ -65, -81, -97, -99, -72, -29, 9, 11, 3, 10, 33, 61, 65, 55, 46, 30,
+ 19, 0, -17, -5, 29, 62, 57, 24, -1, -6, 10, 8, -16, -35, -54, -64,
+ -80, -105, -99, -57, -2, 26, 13, -2, 6, 42, 67, 60, 49, 36, 31, 22,
+ -10, -24, 1, 49, 77, 53, 9, -14, -4, 10, -4, -26, -47, -56, -58, -89,
+ -115, -93, -34, 23, 33, 6, -6, 16, 50, 62, 53, 39, 34, 40, 16, -24,
+ -26, 15, 71, 82, 38, -5, -13, -1, 3, -13, -39, -53, -48, -61, -103, -119,
+ -80, -6, 42, 27, -1, 2, 26, 51, 56, 43, 33, 43, 42, 4, -34, -23,
+ 37, 87, 70, 20, -6, -10, -3, -5, -27, -49, -48, -44, -72, -115, -118, -56,
+ 22, 43, 17, 3, 12, 33, 51, 45, 34, 38, 51, 38, -11, -42, -9, 59,
+ 86, 53, 13, -5, -5, -3, -19, -42, -50, -43, -45, -85, -127, -105, -28, 34,
+ 37, 15, 8, 23, 41, 42, 34, 33, 45, 55, 26, -27, -38, 12, 69, 77,
+ 40, 9, 1, 0, -13, -33, -48, -49, -39, -55, -102, -124, -83, -8, 37, 31,
+ 14, 19, 35, 39, 34, 30, 35, 51, 50, 9, -31, -25, 27, 72, 65, 30,
+ 12, 9, -2, -23, -42, -52, -46, -43, -71, -109, -112, -63, 7, 36, 25, 20,
+ 33, 42, 35, 29, 29, 40, 52, 35, -2, -28, -12, 40, 69, 51, 26, 18,
+ 13, -8, -33, -48, -50, -46, -57, -84, -107, -98, -43, 14, 29, 24, 30, 44,
+ 43, 30, 26, 34, 44, 40, 19, -8, -20, 4, 46, 59, 42, 29, 25, 10,
+ -18, -40, -46, -47, -57, -73, -91, -100, -78, -30, 13, 25, 30, 44, 48, 39,
+ 29, 31, 41, 35, 23, 9, -9, -5, 16, 43, 52, 40, 37, 25, 0, -23,
+ -41, -43, -54, -74, -82, -93, -86, -60, -26, 12, 26, 41, 53, 44, 40, 33,
+ 36, 38, 19, 12, 2, -3, 9, 18, 40, 48, 42, 41, 16, -6, -23, -41,
+ -45, -68, -84, -86, -90, -71, -52, -22, 15, 32, 52, 54, 45, 45, 36, 36,
+ 25, 6, 6, 0, 5, 15, 21, 41, 46, 46, 37, 10, -7, -24, -42, -57,
+ -81, -88, -88, -83, -62, -43, -14, 16, 41, 59, 55, 48, 48, 40, 27, 10,
+ 2, 2, 0, 8, 22, 30, 36, 45, 50, 32, 5, -9, -23, -48, -75, -86,
+ -86, -88, -81, -54, -26, -11, 16, 52, 65, 55, 50, 53, 39, 9, -2, 4,
+ 2, -4, 11, 36, 34, 27, 47, 51, 26, 0, -9, -23, -63, -91, -85, -81,
+ -89, -79, -38, -13, -11, 23, 62, 67, 55, 52, 56, 29, -8, -7, 7, 0,
+ -5, 19, 44, 30, 28, 49, 46, 21, -2, -10, -32, -79, -96, -83, -81, -87,
+ -67, -27, -11, 0, 36, 65, 67, 58, 54, 48, 14, -15, -7, 3, 1, 6,
+ 26, 35, 30, 38, 46, 37, 18, -2, -18, -48, -85, -96, -89, -81, -70, -52,
+ -30, -8, 20, 48, 63, 66, 59, 50, 33, 6, -14, -15, -2, 13, 20, 21,
+ 25, 36, 45, 42, 31, 12, -10, -31, -56, -84, -103, -96, -70, -50, -43, -31,
+ 0, 35, 58, 68, 65, 51, 37, 26, 8, -19, -25, 2, 27, 27, 17, 20,
+ 36, 45, 45, 29, 0, -27, -41, -55, -87, -111, -93, -57, -37, -33, -23, 5,
+ 41, 70, 77, 59, 36, 26, 24, 4, -24, -22, 7, 31, 33, 19, 14, 29,
+ 49, 50, 22, -16, -39, -48, -63, -92, -104, -86, -51, -25, -19, -16, 10, 53,
+ 82, 74, 47, 26, 19, 16, -1, -18, -16, 7, 35, 37, 18, 10, 31, 55,
+ 41, 4, -25, -45, -57, -73, -90, -95, -82, -42, -9, -8, -11, 20, 71, 84,
+ 57, 39, 27, 13, 2, -6, -9, -12, 8, 45, 41, 8, 5, 42, 56, 20,
+ -10, -24, -50, -73, -83, -83, -87, -76, -25, 10, -5, -9, 39, 84, 71, 44,
+ 38, 26, 2, -9, -2, -4, -11, 17, 52, 36, 0, 11, 50, 43, 3, -19,
+ -31, -57, -84, -84, -77, -82, -59, -9, 14, 1, 7, 55, 81, 61, 38, 29,
+ 20, -2, -10, -1, -4, 0, 26, 42, 30, 8, 20, 41, 28, -4, -31, -46,
+ -64, -84, -82, -79, -66, -37, -7, 15, 18, 30, 58, 68, 57, 33, 17, 9,
+ 0, -3, -7, 0, 15, 23, 31, 29, 23, 24, 22, 14, -12, -43, -63, -72,
+ -73, -83, -75, -47, -26, -2, 20, 37, 48, 50, 57, 52, 30, 6, -1, 11,
+ 0, -9, 7, 16, 24, 28, 32, 33, 15, 7, 2, -21, -55, -79, -66, -67,
+ -81, -63, -38, -12, 9, 29, 53, 48, 42, 51, 47, 22, -6, 5, 18, -4,
+ -7, 6, 22, 28, 26, 39, 28, 2, -2, -8, -35, -73, -76, -56, -67, -77,
+ -55, -20, 4, 16, 40, 54, 42, 41, 51, 37, 7, 0, 17, 13, -12, -9,
+ 20, 31, 25, 29, 33, 15, -5, -8, -22, -57, -74, -62, -57, -74, -71, -33,
+ 0, 11, 26, 44, 45, 41, 47, 45, 22, 3, 12, 19, 0, -15, 4, 30,
+ 32, 27, 26, 17, 3, -4, -14, -44, -69, -66, -56, -63, -74, -52, -11, 12,
+ 21, 29, 35, 41, 49, 51, 31, 9, 11, 19, 11, -8, -7, 20, 36, 34,
+ 22, 10, 6, 5, -4, -33, -64, -66, -58, -58, -67, -63, -29, 4, 20, 21,
+ 21, 35, 52, 57, 39, 12, 10, 18, 16, 3, -7, 8, 31, 39, 25, 5,
+ 3, 10, 5, -22, -58, -67, -58, -56, -60, -64, -45, -11, 15, 19, 12, 24,
+ 50, 62, 46, 17, 9, 18, 20, 12, 0, 2, 21, 37, 31, 7, 0, 11,
+ 14, -12, -51, -66, -58, -53, -54, -59, -54, -29, 3, 16, 9, 17, 44, 62,
+ 51, 22, 8, 17, 24, 21, 9, 1, 11, 30, 31, 14, 3, 11, 16, -4,
+ -43, -65, -58, -49, -50, -53, -55, -43, -16, 5, 10, 16, 38, 59, 54, 26,
+ 7, 18, 29, 24, 18, 8, 5, 16, 27, 23, 11, 14, 18, -1, -36, -63,
+ -56, -43, -48, -47, -49, -52, -36, -12, 8, 17, 35, 55, 50, 28, 9, 17,
+ 33, 25, 24, 20, 5, 4, 15, 27, 23, 20, 22, 0, -32, -58, -55, -40,
+ -47, -44, -39, -52, -54, -34, -2, 19, 35, 53, 46, 27, 12, 18, 34, 26,
+ 26, 33, 13, -6, 0, 22, 34, 32, 28, 3, -31, -53, -51, -39, -47, -45,
+ -30, -45, -66, -56, -19, 15, 38, 52, 43, 22, 13, 22, 35, 26, 26, 41,
+ 25, -7, -13, 10, 35, 46, 39, 10, -29, -50, -46, -37, -47, -46, -27, -35,
+ -65, -72, -42, 2, 38, 55, 43, 19, 11, 24, 36, 27, 26, 43, 37, 2,
+ -19, -6, 25, 53, 56, 20, -24, -46, -43, -36, -46, -48, -29, -28, -56, -77,
+ -64, -22, 31, 61, 45, 16, 10, 23, 35, 30, 26, 41, 42, 16, -14, -21,
+ 7, 51, 70, 36, -15, -38, -40, -35, -42, -49, -35, -29, -44, -71, -81, -49,
+ 14, 60, 50, 18, 10, 21, 34, 34, 26, 37, 43, 30, 0, -27, -13, 37,
+ 74, 54, 2, -29, -35, -32, -37, -49, -42, -32, -36, -57, -85, -73, -12, 46,
+ 57, 27, 9, 17, 32, 38, 28, 30, 41, 39, 18, -20, -27, 15, 62, 68,
+ 26, -17, -30, -28, -29, -45, -51, -40, -34, -45, -77, -86, -42, 18, 54, 43,
+ 14, 12, 29, 42, 34, 25, 33, 41, 30, -2, -24, -5, 36, 65, 50, 3,
+ -24, -24, -19, -33, -54, -52, -42, -45, -61, -75, -58, -15, 32, 48, 25, 10,
+ 24, 45, 45, 27, 26, 32, 28, 13, -4, -6, 14, 44, 55, 24, -11, -18,
+ -12, -20, -46, -57, -53, -54, -57, -63, -57, -33, 4, 35, 32, 16, 22, 40,
+ 49, 36, 26, 28, 23, 17, 8, 1, 10, 27, 43, 33, 5, -6, -8, -14,
+ -33, -53, -57, -61, -62, -61, -59, -38, -10, 15, 26, 20, 26, 40, 44, 41,
+ 30, 27, 25, 18, 12, 3, 9, 26, 33, 28, 13, 5, 5, -8, -25, -45,
+ -57, -60, -64, -66, -65, -49, -17, 6, 13, 16, 26, 43, 47, 39, 32, 27,
+ 27, 25, 13, 3, 6, 22, 35, 26, 13, 10, 12, 5, -17, -40, -54, -58,
+ -58, -68, -74, -61, -31, -1, 9, 10, 23, 40, 50, 45, 31, 24, 27, 31,
+ 20, 3, 2, 17, 32, 31, 16, 12, 15, 12, -4, -31, -51, -55, -54, -62,
+ -76, -73, -47, -17, 2, 8, 19, 37, 51, 50, 34, 24, 26, 31, 25, 9,
+ 4, 13, 26, 34, 25, 9, 13, 20, -2, -33, -44, -43, -58, -78, -77, -59,
+ -44, -33, -10, 17, 6, 12, -9, 32, 13, 4, -4, 6, -9, 27, 8, 2,
+ -1, -3, -2, 3, -4, -3, 2, 0, -2, 1, -2, 1, -4, 2, 1, 0,
+ -2, -1, -3, 2, 0, -1, -2, -2, -2, -1, -2, -2, -1, -2, -2, -2,
+ -2, -1, -2, -1, 0, -1, -2, -2, -2, -1, 0, -2, -2, -2, -2, -1,
+ -1, -2, -1, -2, -2, -2, -3, -1, -1, 0, 0, -1, -3, -2, 1, 3,
+ 0, 0, -2, -8, -21, -17, -2, 12, 20, 19, 6, -13, -28, -73, -67, -64,
+ -58, -39, -11, 19, 38, 60, 96, 80, 38, 12, 6, -20, -65, -83, -65, -61,
+ -56, -17, 22, 35, 49, 74, 94, 55, 16, 20, -5, -52, -89, -81, -53, -65,
+ -36, 21, 37, 48, 51, 85, 82, 25, 23, 9, -36, -80, -105, -58, -57, -54,
+ 7, 36, 54, 44, 58, 97, 48, 26, 16, -21, -61, -115, -83, -45, -57, -12,
+ 23, 57, 54, 36, 86, 77, 37, 21, -16, -40, -103, -110, -54, -46, -24, 6,
+ 43, 68, 36, 62, 86, 60, 30, -12, -34, -80, -119, -76, -44, -24, -5, 24,
+ 64, 51, 50, 76, 72, 48, 0, -34, -68, -106, -94, -56, -26, -7, 11, 45,
+ 59, 58, 66, 71, 60, 23, -27, -68, -93, -93, -72, -37, -8, 10, 25, 50,
+ 70, 68, 62, 62, 45, -10, -70, -88, -83, -79, -57, -15, 15, 13, 31, 73,
+ 80, 59, 53, 61, 15, -67, -89, -73, -75, -75, -33, 21, 11, 10, 66, 92,
+ 65, 42, 63, 42, -56, -92, -66, -66, -84, -57, 16, 19, -5, 50, 98, 76,
+ 39, 56, 60, -35, -95, -64, -53, -84, -79, 0, 28, -8, 29, 96, 89, 42,
+ 46, 69, -10, -90, -69, -41, -74, -95, -25, 28, -1, 13, 81, 101, 53, 37,
+ 69, 11, -77, -75, -38, -53, -103, -55, 22, 8, 6, 61, 104, 75, 29, 59,
+ 31, -61, -76, -43, -36, -91, -88, 6, 17, 1, 46, 96, 94, 34, 40, 48,
+ -40, -80, -47, -27, -69, -107, -27, 26, 4, 29, 87, 105, 51, 24, 46, -10,
+ -76, -58, -21, -49, -107, -62, 17, 16, 17, 70, 110, 67, 22, 38, 10, -60,
+ -71, -24, -28, -97, -85, -6, 25, 18, 50, 106, 84, 28, 31, 16, -38, -71,
+ -38, -17, -78, -94, -30, 15, 30, 41, 86, 92, 44, 31, 15, -25, -54, -53,
+ -26, -57, -88, -51, -2, 33, 45, 68, 88, 59, 35, 17, -15, -42, -55, -41,
+ -48, -73, -60, -19, 24, 50, 61, 74, 67, 46, 21, -8, -32, -48, -54, -53,
+ -57, -57, -34, 9, 50, 63, 59, 65, 58, 29, -1, -24, -38, -62, -67, -48,
+ -47, -40, -8, 43, 68, 48, 58, 66, 38, 6, -19, -26, -62, -85, -45, -35,
+ -39, -21, 28, 72, 41, 47, 74, 45, 15, -14, -17, -53, -102, -50, -24, -36,
+ -26, 10, 69, 42, 32, 81, 52, 21, -4, -15, -39, -109, -64, -12, -35, -26,
+ -1, 54, 47, 21, 79, 65, 20, 7, -12, -33, -100, -82, -8, -27, -32, -2,
+ 36, 47, 21, 66, 77, 25, 12, -2, -36, -88, -87, -18, -16, -36, -8, 27,
+ 36, 30, 56, 77, 39, 12, 6, -33, -84, -79, -30, -11, -29, -20, 19, 27,
+ 31, 58, 66, 50, 21, 5, -25, -81, -75, -32, -17, -17, -27, 2, 24, 28,
+ 61, 61, 48, 35, 4, -22, -71, -77, -31, -19, -12, -23, -18, 16, 29, 59,
+ 65, 45, 41, 10, -23, -59, -76, -37, -14, -11, -18, -29, -2, 29, 57, 68,
+ 51, 37, 16, -21, -55, -67, -44, -12, -5, -21, -29, -19, 19, 59, 68, 61,
+ 36, 14, -12, -55, -61, -44, -16, 3, -21, -29, -25, 0, 55, 72, 69, 43,
+ 8, -6, -49, -63, -39, -18, 5, -15, -31, -26, -18, 39, 78, 75, 53, 8,
+ -8, -40, -67, -37, -15, 2, -8, -30, -26, -29, 16, 79, 84, 59, 14, -11,
+ -33, -66, -42, -9, -2, -6, -23, -26, -33, -7, 66, 94, 67, 22, -9, -32,
+ -62, -48, -8, 0, -9, -16, -20, -35, -24, 46, 96, 78, 31, -2, -29, -59,
+ -51, -13, 1, -10, -13, -9, -31, -35, 23, 86, 88, 42, 5, -22, -57, -53,
+ -18, -3, -10, -13, 0, -19, -44, 2, 69, 90, 57, 12, -13, -50, -57, -21,
+ -9, -13, -13, 1, -3, -41, -17, 51, 82, 69, 23, -9, -37, -57, -25, -12,
+ -22, -15, 0, 10, -25, -32, 32, 69, 71, 37, -4, -25, -48, -30, -12, -32,
+ -23, -3, 14, -2, -33, 11, 56, 63, 49, 3, -18, -32, -31, -13, -37, -38,
+ -9, 11, 17, -16, -6, 41, 53, 51, 11, -17, -15, -23, -14, -35, -54, -22,
+ 4, 26, 10, -10, 26, 43, 46, 19, -19, -6, -5, -10, -30, -65, -42, -9,
+ 24, 35, 3, 12, 32, 37, 24, -20, -8, 14, 2, -23, -68, -62, -26, 10,
+ 50, 28, 11, 22, 27, 24, -19, -19, 24, 21, -8, -63, -78, -45, -11, 47,
+ 53, 23, 21, 19, 22, -17, -34, 21, 40, 15, -48, -89, -65, -34, 30, 68,
+ 44, 27, 16, 16, -11, -47, 3, 49, 39, -22, -89, -82, -55, 3, 68, 61,
+ 44, 21, 11, -6, -53, -21, 45, 56, 11, -74, -96, -72, -26, 52, 73, 60,
+ 39, 10, -3, -48, -44, 27, 61, 42, -43, -101, -88, -52, 27, 73, 70, 59,
+ 21, -1, -40, -60, 2, 52, 60, -4, -90, -100, -74, -2, 62, 72, 76, 42,
+ 5, -30, -66, -22, 34, 63, 33, -62, -104, -92, -31, 44, 68, 84, 66, 21,
+ -21, -64, -41, 13, 54, 55, -26, -94, -104, -57, 20, 56, 82, 84, 43, -6,
+ -57, -54, -10, 36, 60, 7, -70, -107, -78, -6, 40, 73, 92, 66, 12, -45,
+ -57, -27, 16, 52, 29, -41, -96, -90, -32, 20, 60, 91, 83, 34, -27, -52,
+ -37, -3, 34, 36, -15, -77, -91, -52, -1, 43, 83, 93, 53, -5, -42, -40,
+ -17, 14, 32, 1, -54, -81, -65, -21, 23, 71, 96, 67, 16, -25, -37, -24,
+ -5, 21, 6, -36, -64, -69, -37, 3, 54, 93, 73, 35, -6, -28, -25, -19,
+ 8, 4, -27, -46, -65, -46, -14, 34, 86, 73, 49, 15, -17, -19, -28, -4,
+ -3, -28, -32, -56, -48, -24, 15, 74, 67, 55, 36, -2, -10, -28, -14, -9,
+ -36, -25, -42, -50, -29, 1, 60, 59, 50, 55, 16, -3, -22, -20, -14, -46,
+ -29, -28, -48, -33, -5, 47, 50, 40, 64, 40, 4, -14, -17, -19, -53, -40,
+ -18, -40, -41, -6, 39, 39, 28, 61, 62, 17, -10, -7, -21, -59, -53, -20,
+ -28, -47, -11, 38, 29, 15, 52, 77, 36, -6, 1, -12, -63, -66, -25, -20,
+ -46, -19, 37, 28, 0, 38, 83, 54, 5, 5, -2, -57, -81, -34, -15, -44,
+ -22, 29, 31, -4, 16, 85, 68, 17, 15, 1, -44, -87, -54, -8, -42, -27,
+ 25, 24, 2, 0, 69, 88, 24, 25, 11, -42, -76, -75, -14, -25, -40, 23,
+ 18, -3, 3, 42, 96, 45, 22, 29, -39, -70, -75, -40, -8, -39, 7, 24,
+ -17, 8, 33, 79, 76, 22, 35, -21, -75, -64, -60, -15, -17, -14, 21, -21,
+ -4, 40, 59, 88, 45, 24, -3, -71, -61, -59, -38, 1, -14, 0, -17, -18,
+ 41, 54, 82, 74, 22, -3, -53, -61, -53, -54, -2, 3, -19, -25, -22, 30,
+ 57, 73, 92, 38, -15, -40, -51, -50, -58, -17, 17, -23, -44, -22, 19, 55,
+ 72, 97, 60, -22, -40, -35, -45, -55, -32, 14, -17, -60, -26, 11, 46, 75,
+ 97, 78, -17, -46, -23, -38, -45, -37, -1, -14, -66, -31, 3, 34, 80, 98,
+ 85, -4, -47, -19, -33, -33, -30, -20, -25, -63, -34, -4, 18, 79, 104, 84,
+ 9, -38, -18, -29, -27, -14, -30, -46, -63, -32, -5, 3, 68, 111, 84, 18,
+ -23, -12, -25, -28, -2, -25, -67, -75, -29, 1, -6, 46, 112, 91, 22, -11,
+ 0, -18, -33, -1, -9, -76, -96, -34, 9, -8, 22, 101, 102, 27, -2, 14,
+ -7, -36, -9, 4, -68, -114, -48, 13, -3, 5, 80, 109, 40, 4, 26, 6,
+ -33, -18, 6, -52, -120, -67, 7, 4, -1, 55, 103, 58, 14, 31, 17, -21,
+ -24, -4, -39, -110, -84, -10, 6, 2, 34, 87, 71, 29, 36, 25, -7, -23,
+ -16, -33, -96, -90, -29, -1, 6, 22, 68, 75, 45, 45, 31, 4, -15, -24,
+ -37, -84, -87, -43, -15, 3, 18, 53, 68, 57, 58, 38, 11, -7, -22, -45,
+ -81, -79, -48, -29, -10, 17, 45, 57, 61, 71, 50, 17, 0, -15, -49, -85,
+ -74, -45, -40, -25, 10, 42, 49, 55, 82, 65, 22, 7, -9, -43, -89, -80,
+ -34, -47, -40, -1, 35, 52, 43, 85, 84, 25, 17, -4, -38, -85, -92, -28,
+ -44, -55, -9, 21, 53, 42, 75, 100, 35, 22, 6, -38, -74, -99, -38, -34,
+ -65, -18, 12, 42, 51, 63, 102, 52, 25, 21, -36, -70, -90, -56, -30, -64,
+ -30, 7, 27, 55, 63, 90, 69, 33, 26, -26, -69, -79, -66, -43, -54, -37,
+ -1, 17, 49, 69, 79, 72, 50, 30, -15, -61, -75, -68, -58, -52, -33, -12,
+ 9, 42, 69, 78, 64, 60, 42, -9, -49, -71, -69, -68, -61, -25, -17, -1,
+ 38, 64, 77, 59, 62, 58, -3, -37, -62, -72, -72, -73, -24, -12, -11, 35,
+ 55, 73, 59, 58, 69, 8, -29, -48, -75, -76, -82, -31, -4, -14, 28, 49,
+ 63, 61, 54, 73, 22, -21, -36, -71, -82, -88, -42, 0, -9, 21, 43, 53,
+ 57, 56, 73, 33, -12, -25, -62, -89, -95, -49, -2, -2, 18, 37, 43, 49,
+ 60, 75, 38, -2, -16, -49, -89, -105, -54, -7, 1, 19, 31, 37, 38, 59,
+ 81, 39, 4, -7, -35, -83, -115, -62, -10, 0, 20, 27, 32, 30, 53, 87,
+ 43, 4, 0, -24, -70, -118, -75, -12, -2, 19, 24, 27, 27, 45, 89, 52,
+ 4, 1, -14, -55, -113, -87, -18, -3, 13, 20, 24, 28, 41, 85, 60, 7,
+ -3, -9, -40, -100, -91, -28, -4, 7, 10, 21, 30, 43, 82, 62, 13, -8,
+ -11, -26, -85, -87, -36, -10, 2, -4, 14, 35, 47, 81, 62, 18, -9, -21,
+ -20, -65, -78, -38, -19, -4, -16, 0, 39, 54, 85, 65, 20, -7, -31, -24,
+ -47, -62, -33, -26, -15, -25, -19, 35, 63, 90, 73, 22, -3, -39, -39, -35,
+ -43, -20, -26, -30, -34, -36, 24, 71, 94, 85, 29, -3, -40, -58, -34, -24,
+ -4, -16, -46, -47, -47, 6, 73, 100, 97, 42, -4, -39, -73, -45, -8, 12,
+ 0, -51, -64, -56, -13, 66, 104, 106, 64, 2, -40, -82, -63, -3, 27, 18,
+ -43, -82, -68, -28, 51, 104, 112, 86, 19, -42, -86, -81, -10, 40, 34, -26,
+ -90, -86, -41, 31, 98, 116, 104, 46, -38, -92, -95, -25, 46, 48, -6, -84,
+ -105, -55, 13, 84, 117, 114, 76, -20, -95, -105, -45, 41, 54, 8, -65, -112,
+ -70, -1, 65, 109, 115, 100, 14, -85, -106, -62, 21, 50, 13, -44, -104, -84,
+ -14, 45, 98, 112, 111, 53, -62, -105, -75, -3, 44, 12, -31, -85, -93, -27,
+ 27, 82, 110, 110, 81, -27, -95, -81, -27, 31, 11, -31, -66, -90, -39, 12,
+ 61, 106, 107, 94, 12, -73, -79, -48, 11, 13, -32, -57, -78, -46, -1, 38,
+ 97, 109, 96, 43, -41, -69, -62, -13, 13, -30, -58, -68, -46, -11, 17, 81,
+ 112, 97, 59, -7, -51, -67, -37, 6, -23, -62, -67, -42, -14, 2, 60, 110,
+ 99, 65, 20, -24, -63, -56, -7, -15, -63, -75, -40, -12, -8, 39, 102, 103,
+ 67, 35, 6, -48, -68, -25, -11, -56, -85, -46, -7, -10, 22, 86, 107, 72,
+ 41, 29, -25, -70, -42, -14, -42, -91, -62, -5, -6, 9, 67, 105, 84, 40,
+ 40, 3, -64, -56, -23, -30, -83, -85, -12, 3, 1, 50, 97, 96, 44, 36,
+ 28, -45, -69, -33, -22, -67, -101, -34, 13, 2, 31, 88, 104, 56, 28, 37,
+ -16, -71, -51, -18, -49, -103, -62, 9, 14, 18, 70, 109, 68, 26, 36, 6,
+ -58, -68, -23, -28, -97, -84, -7, 23, 19, 50, 106, 84, 28, 31, -21, -26,
+ -18, -30, -24, -77, -76, -48, -46, 31, 0, -1, 0, 0, 2, 0, 1, -2,
+ 1, 0, -6, -7, -5, -3, 0, -3, -4, -2, 2, 0, -8, -11, -14, -10,
+ -8, -4, 6, 13, 14, 9, 2, -6, -10, -9, -6, 9, 17, 15, 8, 0,
+ 1, -4, -12, -19, -14, -8, -4, 3, 6, -2, -4, -6, -7, -10, -8, -12,
+ -11, 3, 23, 27, 11, 4, -3, -5, 0, -9, -3, 6, 11, 19, 4, -8,
+ -17, -20, -21, -3, 5, 8, 2, 3, 5, 2, -3, -3, -12, 4, 1, 3,
+ -7, 0, 5, 6, 0, -7, -8, -5, -7, -5, -3, 4, 9, 5, -5, -5,
+ -5, -17, -7, 3, 17, 15, 7, -2, -5, -3, 3, -8, -5, -3, 3, 8,
+ 12, 5, -10, -27, -20, 1, 5, -4, -9, -17, 4, 10, 9, -2, -12, -16,
+ -12, -2, 8, 16, 13, 11, 16, 19, 10, -2, -16, -21, -11, 14, 15, 21,
+ 11, 6, -10, -8, -11, -24, -35, -31, -13, 9, 24, 17, -2, -11, -20, -11,
+ -19, -7, 3, 8, 22, 21, 21, 2, -7, -10, 12, 24, 18, -3, -19, -6,
+ 0, -5, -18, -17, 6, 12, 7, -16, -20, -22, -27, -19, -14, 12, 14, 3,
+ 0, 2, 8, -3, -5, -3, 21, 29, 17, 6, -8, 3, 3, 10, 10, 3,
+ 12, 4, -9, -18, -20, -20, -9, 6, 3, -9, -7, -14, -9, -8, -9, -23,
+ -19, 7, 17, 20, 9, 8, 5, 9, 18, 9, 8, -10, -10, -4, 9, 25,
+ -6, -19, -19, -5, -4, -7, -7, -17, -15, -7, -4, 0, 2, -2, -17, -4,
+ 14, 23, 15, 2, -7, -5, 9, 11, 1, 0, -3, 0, 0, 15, 14, -4,
+ -15, -20, -26, -22, -13, 0, 6, 12, 5, -10, 2, 8, -2, -18, -8, 6,
+ 20, 28, 23, 0, -16, -7, 9, 7, 10, -12, -21, -19, 7, 12, 4, -17,
+ -28, -24, -3, 14, 4, -19, -18, -9, 11, 22, 16, -13, -23, -15, 18, 32,
+ 32, 17, -4, 1, 14, 11, 1, -20, -19, -3, 9, 13, -4, -13, -16, -18,
+ -23, -12, -17, -16, -20, -15, -14, -4, 8, 12, 0, 8, 5, 12, 17, 26,
+ 25, 14, 10, 11, 11, 18, 15, 4, -9, -13, -8, -9, -14, -20, -28, -32,
+ -12, -9, -16, -17, -24, -18, -12, 5, 10, 4, 6, 8, 18, 35, 31, 17,
+ 1, 12, 21, 33, 18, 6, -10, -11, -4, -9, -13, -19, -24, -24, -24, -18,
+ -20, -18, -20, -13, -15, -10, -9, -5, 8, 10, 13, 23, 26, 29, 14, 13,
+ 13, 13, 16, 25, 19, 17, 4, -15, -18, -15, -14, -17, -34, -23, -16, -12,
+ -16, -26, -33, -23, -15, -4, 4, 10, 16, 19, 22, 29, 28, 7, 1, 2,
+ 18, 26, 30, 21, 9, 3, -4, -10, -16, -29, -31, -27, -4, -9, -11, -28,
+ -23, -17, -15, -13, -11, 4, 11, 9, 13, 16, 25, 18, 8, 10, 18, 17,
+ 8, 18, 17, 11, -5, -19, -17, -12, -19, -38, -27, -8, 0, -3, -14, -19,
+ -20, -14, -10, -13, -3, 6, 12, 26, 38, 34, 14, 2, -2, 11, 19, 14,
+ 8, 5, 16, 9, -7, -19, -24, -29, -36, -26, -13, -12, -22, -28, -20, 5,
+ -3, -10, -19, 7, 20, 18, 17, 24, 25, 14, 18, 19, 29, 21, 11, 10,
+ 9, 13, -13, -29, -27, -20, -24, -30, -22, -12, -7, -15, -22, -21, -13, -14,
+ -20, -8, 12, 26, 25, 21, 33, 27, 25, 16, 13, 16, 16, -2, 2, 11,
+ 9, -2, -17, -18, -16, -25, -25, -26, -27, -30, -35, -30, -12, -6, -6, -6,
+ -5, 19, 19, 11, 15, 17, 24, 23, 34, 28, 23, 13, 2, 9, 18, 16,
+ -14, -18, -12, -7, -9, -31, -37, -33, -24, -14, -24, -20, -16, -21, -15, -7,
+ 5, 9, 15, 20, 28, 38, 29, 21, 15, 22, 17, 4, 12, 6, 12, -4,
+ -9, -15, -16, -19, -40, -38, -34, -23, -18, -17, -8, -10, -3, -7, 1, 3,
+ 4, 11, 13, 36, 41, 36, 24, 9, 17, 20, 21, 14, -5, -9, -11, -8,
+ -19, -14, -24, -30, -23, -18, -25, -30, -24, -17, -20, -9, -3, 6, 8, 22,
+ 23, 20, 27, 18, 10, 10, 14, 18, 14, 23, 17, 6, 5, -4, -8, -26,
+ -19, -24, -25, -24, -21, -27, -28, -15, -19, -16, -9, 0, 7, 9, 17, 14,
+ 15, 24, 30, 29, 29, 32, 16, 10, 8, 0, -3, -10, -7, -17, -22, -25,
+ -30, -36, -32, -25, -26, -22, -12, -16, -11, -3, 5, 7, 13, 21, 21, 26,
+ 32, 28, 26, 28, 31, 17, 15, 15, 5, -4, -14, -18, -28, -25, -24, -28,
+ -32, -33, -32, -29, -18, -17, -20, -10, -4, 6, 6, 18, 22, 22, 37, 38,
+ 31, 27, 26, 23, 22, 23, 12, 4, -5, -2, -11, -19, -25, -35, -35, -36,
+ -36, -43, -32, -24, -20, -12, -7, -3, -7, 3, 13, 23, 29, 35, 37, 35,
+ 42, 33, 26, 22, 17, 12, 6, 4, -9, -23, -28, -34, -34, -33, -31, -40,
+ -36, -27, -25, -22, -30, -20, -11, 2, 12, 22, 22, 26, 28, 35, 47, 44,
+ 27, 29, 29, 29, 19, 2, 1, -9, -15, -21, -34, -35, -34, -40, -44, -42,
+ -34, -31, -26, -21, -9, -12, -3, 10, 17, 29, 26, 27, 34, 48, 50, 34,
+ 33, 25, 21, 16, 8, 3, -8, -11, -25, -30, -37, -37, -42, -51, -34, -28,
+ -21, -26, -25, -19, -13, 4, 9, 17, 29, 41, 33, 33, 44, 45, 32, 31,
+ 28, 22, 16, 5, -10, -13, -16, -23, -38, -39, -39, -45, -54, -40, -32, -24,
+ -22, -17, -14, 0, 6, 9, 18, 41, 43, 34, 32, 40, 40, 31, 30, 27,
+ 22, 19, 14, -2, -16, -21, -34, -48, -45, -41, -41, -41, -45, -38, -25, -21,
+ -17, -20, -7, 11, 17, 19, 36, 40, 42, 44, 47, 46, 39, 33, 26, 15,
+ 11, 8, -5, -19, -24, -29, -40, -44, -48, -44, -37, -37, -43, -43, -26, -19,
+ -14, -2, 13, 23, 31, 36, 36, 43, 41, 47, 46, 44, 40, 24, 15, 14,
+ 3, -12, -21, -23, -30, -36, -47, -51, -50, -47, -44, -46, -31, -19, -16, -11,
+ 2, 16, 20, 25, 29, 40, 53, 51, 49, 45, 41, 35, 25, 18, 7, 5,
+ -12, -18, -23, -34, -39, -56, -58, -54, -49, -50, -45, -35, -26, -12, -5, 6,
+ 17, 29, 41, 42, 47, 50, 46, 49, 50, 50, 39, 30, 16, 2, -8, -15,
+ -21, -30, -41, -49, -50, -46, -57, -63, -57, -41, -29, -24, -12, -3, 5, 12,
+ 22, 33, 41, 50, 51, 53, 57, 55, 46, 36, 29, 16, 2, -4, -11, -21,
+ -33, -40, -49, -47, -53, -60, -58, -51, -42, -34, -23, -13, -2, 5, 17, 27,
+ 39, 49, 48, 51, 56, 54, 58, 44, 37, 28, 18, 4, -3, -15, -29, -39,
+ -49, -49, -51, -62, -65, -64, -47, -42, -36, -26, -14, -5, 10, 24, 32, 45,
+ 50, 49, 62, 65, 63, 47, 42, 41, 36, 23, 7, -7, -22, -31, -41, -53,
+ -58, -62, -59, -62, -56, -54, -50, -44, -32, -16, 0, 11, 25, 35, 50, 54,
+ 55, 56, 66, 65, 62, 54, 45, 36, 23, 14, -4, -22, -44, -55, -52, -62,
+ -61, -66, -70, -68, -60, -54, -45, -29, -15, 4, 21, 34, 36, 44, 54, 62,
+ 70, 73, 68, 67, 59, 50, 37, 21, -5, -12, -25, -39, -48, -53, -63, -76,
+ -73, -71, -71, -67, -57, -45, -29, -12, 2, 13, 30, 42, 51, 61, 76, 71,
+ 63, 66, 71, 60, 50, 40, 23, -2, -9, -20, -41, -54, -59, -72, -79, -71,
+ -64, -73, -68, -60, -51, -36, -13, 2, 13, 27, 47, 54, 71, 78, 71, 60,
+ 72, 74, 65, 54, 39, 28, 7, -6, -23, -50, -59, -64, -69, -75, -70, -78,
+ -74, -73, -64, -52, -37, -13, 6, 18, 40, 51, 58, 64, 78, 79, 75, 68,
+ 64, 68, 57, 45, 21, 4, -16, -34, -50, -65, -75, -83, -80, -71, -69, -68,
+ -73, -63, -57, -36, -16, 6, 26, 45, 60, 70, 71, 79, 79, 81, 78, 80,
+ 64, 55, 36, 16, -4, -23, -38, -54, -63, -69, -81, -85, -87, -76, -72, -66,
+ -61, -52, -30, -12, 12, 24, 44, 55, 69, 78, 85, 84, 74, 70, 71, 71,
+ 62, 41, 17, -11, -25, -42, -55, -66, -75, -87, -87, -81, -74, -76, -76, -63,
+ -48, -32, -13, 7, 30, 51, 64, 76, 80, 82, 83, 81, 80, 82, 70, 61,
+ 42, 19, 0, -28, -49, -61, -72, -78, -87, -90, -89, -88, -87, -82, -69, -54,
+ -33, -13, 15, 36, 58, 68, 79, 90, 96, 90, 84, 86, 89, 79, 62, 38,
+ 22, -3, -29, -55, -69, -81, -89, -94, -94, -94, -94, -89, -74, -62, -52, -35,
+ -18, 14, 39, 54, 65, 76, 87, 98, 95, 94, 90, 82, 75, 69, 47, 26,
+ -6, -33, -57, -72, -82, -88, -97, -90, -91, -88, -83, -80, -75, -59, -33, -9,
+ 20, 42, 58, 68, 82, 90, 94, 93, 94, 88, 85, 77, 65, 43, 16, -10,
+ -37, -60, -71, -84, -89, -95, -97, -102, -95, -84, -80, -72, -57, -26, -4, 19,
+ 42, 62, 80, 89, 94, 97, 100, 99, 90, 83, 71, 65, 39, 14, -9, -43,
+ -65, -83, -90, -95, -98, -96, -100, -96, -88, -76, -66, -51, -24, -12, 21, 45,
+ 70, 85, 93, 95, 97, 101, 105, 92, 84, 69, 58, 35, 16, -14, -44, -68,
+ -86, -88, -96, -101, -101, -102, -97, -90, -74, -69, -50, -19, 9, 35, 56, 76,
+ 84, 92, 98, 96, 99, 97, 93, 84, 77, 59, 24, 2, -30, -52, -76, -87,
+ -93, -98, -100, -102, -100, -96, -89, -81, -73, -46, -18, 12, 36, 62, 82, 88,
+ 96, 104, 107, 105, 102, 92, 84, 77, 53, 26, -6, -35, -57, -75, -81, -92,
+ -103, -114, -111, -108, -98, -88, -83, -67, -35, -7, 20, 39, 60, 70, 89, 106,
+ 116, 107, 103, 99, 86, 90, 82, 53, 18, -13, -31, -52, -73, -92, -102, -106,
+ -104, -97, -106, -99, -101, -92, -72, -42, -5, 16, 38, 66, 86, 101, 99, 101,
+ 95, 112, 107, 99, 95, 81, 53, 16, -3, -29, -60, -81, -102, -98, -102, -102,
+ -112, -114, -101, -104, -88, -69, -34, -8, 14, 41, 67, 92, 94, 99, 103, 104,
+ 115, 109, 103, 90, 78, 52, 22, 0, -39, -65, -92, -95, -91, -103, -104, -118,
+ -110, -102, -93, -84, -71, -36, -15, 19, 52, 81, 94, 89, 98, 103, 115, 117,
+ 102, 92, 83, 80, 49, 23, -11, -43, -67, -90, -93, -102, -105, -110, -118, -104,
+ -100, -89, -83, -64, -36, -7, 28, 50, 74, 88, 95, 104, 103, 115, 107, 106,
+ 97, 87, 74, 50, 20, -17, -47, -75, -89, -93, -101, -102, -115, -117, -106, -97,
+ -88, -90, -73, -38, 2, 36, 60, 75, 84, 96, 104, 115, 115, 102, 98, 96,
+ 96, 84, 52, 10, -12, -32, -53, -71, -87, -101, -109, -112, -109, -106, -105, -102,
+ -92, -74, -48, -19, 7, 33, 56, 76, 91, 101, 108, 111, 111, 108, 103, 96,
+ 85, 63, 33, 1, -27, -51, -73, -90, -102, -109, -112, -110, -107, -103, -100, -93,
+ -76, -50, -19, 10, 36, 58, 76, 91, 101, 108, 111, 111, 108, 103, 96, 85,
+ 63, 33, 1, -27, -51, -73, -90, -102, -109, -112, -110, -107, -103, -100, -93, -76,
+ -50, -19, 10, 36, 58, 76, -1, -2, -15, 21, -17, 23, -30, 1, 34, -34,
+ 6, 5, -15, 19, 1, -25, 6, 20, -2, -28, 15, 10, -15, 0, -7, 10,
+ 7, -5, -9, -6, 19, -3, -21, 3, 20, -4, -20, 1, 16, -3, -8, -2,
+ 5, 1, -8, -6, 3, 9, 2, -13, -4, 15, -7, -9, 0, 3, 6, -7,
+ -7, 5, 8, -8, -4, 0, 1, 1, -6, -4, 7, 2, -2, -7, 0, 4,
+ -3, -4, 0, 2, 0, -2, -4, 1, 4, -2, -4, -3, 1, 3, -5, -4,
+ 4, 3, -6, -5, 4, -1, -2, -3, 0, 3, -3, -1, -4, 3, 3, -5,
+ -3, 1, 1, -2, -3, 1, 2, -2, -4, 0, 0, 0, -1, -3, 1, 1,
+ -3, -2, 1, 0, -2, -2, 0, 0, -2, -1, 0, -1, 1, -2, -2, 1,
+ 0, -2, 0, -1, 0, -1, -1, -1, 0, 0, -1, -3, 1, 1, -2, -2,
+ 0, 1, -1, -2, -1, 0, 0, 0, -2, -1, 1, 0, -3, 0, 2, -1,
+ -2, 0, 0, 0, -2, 0, -1, 0, -1, -1, 1, 0, -1, 0, -1, 1,
+ 0, -13, 5, 7, -11, 24, -50, 41, 4, -29, 14, -11, 8, 11, -15, -12,
+ 15, 18, -21, -14, 22, -2, -11, -3, -3, 18, -3, -5, -14, 9, 22, -24,
+ -16, 23, 12, -23, -8, 9, 10, -4, -8, -3, 11, -4, -14, 0, 8, 8,
+ -5, -14, 8, 10, -12, -4, -2, 10, 0, -11, -3, 11, 0, -7, -2, -1,
+ 7, -6, -8, 3, 6, 0, -3, -8, 7, 2, -7, -2, 2, 1, -2, -4,
+ -1, 3, 3, -4, -5, 1, 3, -3, -6, 2, 5, -1, -7, -1, 3, -1,
+ -4, -3, 5, 0, -3, -2, -1, 4, -1, -5, -1, 3, -1, -4, -1, 3,
+ 1, -4, -2, 1, 0, -2, -3, 0, 2, -1, -4, 1, 1, -1, -2, -2,
+ 1, -1, -3, 0, 0, 0, -1, -2, 0, 0, -2, -1, 0, -1, 0, -2,
+ -1, 0, -1, 0, -1, -2, 2, -1, -2, -1, 0, 1, -2, 0, -1, -1,
+ 0, -1, -2, 0, 1, -1, -3, 0, 1, -1, -3, 0, 1, -2, -1, 0,
+ 0, -1, -1, 0, -1, -1, -1, -1, 0, 0, -1, -1, 0, 0, -2, 0,
+ 0, 0, 0, -2, 1, -1, 0, -1, 0, 0, 0, -1, 0, 0, 0, 0,
+ -1, 0, 0, -1, 0, -1, 1, 0, 0, 0, 1, -1, -1, 0, 0, 0,
+ 1, -2, 4, -3, 3, -40, 71, -73, 67, -27, -68, 127, -80, 3, 5, 1,
+ 17, -14, 1, -30, 53, -3, -42, 15, 19, -9, -17, -1, 13, 16, -17, 4,
+ -32, 43, 15, -68, 18, 54, -38, -7, -1, 11, 7, -3, -18, 5, 25, -27,
+ -9, 9, 19, -6, -12, -8, 20, -1, -15, -1, 1, 17, -10, -16, 12, 12,
+ -13, 0, -6, 10, 2, -16, -1, 14, -4, 4, -11, -2, 12, -6, -8, 4,
+ 4, -2, -4, 1, -2, 4, 3, -7, -5, 8, 0, -10, 1, 4, 2, -4,
+ -6, 4, 1, -1, -7, 1, 8, -9, 2, -5, 3, 3, -4, -3, 0, 3,
+ -3, -5, 4, 3, -3, -4, 0, 2, 0, -3, -4, 5, 0, -5, -1, 2,
+ 0, -3, 0, -1, 2, -2, -4, 3, 0, -1, -2, -1, 2, -2, -2, 1,
+ -1, 0, -1, -3, 1, 1, -2, 1, -3, 1, 1, -3, -1, 1, 0, -1,
+ -2, 1, -1, -1, 1, -2, 1, -1, -1, -1, -1, 0, 1, -3, 0, 0,
+ 1, -4, 0, 1, -2, 0, -2, 0, 0, 0, -2, 1, -1, 0, -2, 0,
+ 2, -2, -1, 0, -1, 2, -2, -1, 1, -2, 0, -1, 1, -1, -1, -1,
+ 1, -2, 1, -1, -1, 2, -3, 0, 0, -1, 1, -1, 0, 1, 0, -2,
+ 0, -1, 1, -2, 0, 0, -1, 1, 0, -2, 0, 1, -2, 1, 0, 0,
+ -1, 0, 1, -1, -1, -1, 1, 1, -1, 0, 0, 0, -1, 1, 0, -1,
+ 1, 0, 0, 1, 0, -1, 1, 0, 3, -40, 58, -39, 12, 42, -117, 108,
+ 1, -66, 22, 17, 0, -9, 10, -39, 42, 4, -23, -12, 28, 3, -34, 9,
+ 17, 3, -9, 10, -29, 13, 53, -79, 3, 64, -26, -24, 16, -9, 14, 2,
+ -8, -15, 31, -9, -30, 11, 29, -15, -7, 0, 3, 6, -4, -9, -6, 22,
+ 1, -24, 9, 11, -8, 0, -2, 2, 8, -12, -6, 10, 2, 2, -9, -4,
+ 11, -2, -10, 3, 2, 3, -5, -1, 1, -1, 6, -4, -8, 9, 2, -8,
+ -3, 6, 3, -4, -3, -1, 6, -2, -8, 0, 9, -4, -3, -2, 2, 4,
+ -4, -1, -1, 4, -2, -6, 4, 2, -1, -4, 0, 1, 2, -3, -5, 3,
+ 3, -3, -4, 3, 0, -1, 0, -2, 2, 0, -3, 0, 3, 0, -3, -1,
+ 2, 0, -3, 1, 0, -1, 2, -2, -2, 2, -1, 0, -1, -1, 1, -1,
+ -2, 0, 0, 1, -3, 1, 0, -1, 1, -2, -1, 2, -2, -1, 0, -1,
+ 2, -3, -1, 1, 1, -2, -2, 2, 1, -2, -1, 0, 0, 1, -3, 1,
+ 0, 0, 0, -2, 3, 0, -2, 0, 0, 1, 0, -1, 1, -2, 0, 0,
+ 0, -1, 1, 0, 0, 0, -1, 1, -1, 1, 0, -1, 1, -2, 0, 1,
+ 1, 0, 1, -2, 1, 0, 1, 0, 0, 3, -1, 0, 1, 0, 0, 3,
+ -29, 35, -12, -16, 56, -88, 39, 62, -79, 5, 29, 1, -13, 12, -29, 26,
+ 17, -28, -3, 12, 5, -11, -19, 28, 1, -5, 9, -21, -7, 60, -56, -20,
+ 57, -10, -27, 21, -21, 16, 12, -12, -21, 24, 6, -29, 4, 19, 2, -7,
+ -5, -3, 7, 6, -11, -9, 11, 13, -18, -4, 13, 1, -3, -6, -1, 10,
+ -8, -6, 5, 3, 5, -3, -11, 4, 9, -11, 0, 4, 3, -4, -1, 0,
+ 0, 7, 0, -14, 7, 5, -7, -4, 4, 5, -1, -4, -4, 4, 1, -4,
+ -4, 7, -1, -1, -3, 0, 5, -1, -4, -1, 2, 0, -3, 1, 1, 2,
+ -2, -4, 1, 2, 0, -5, 2, 3, -2, -2, 1, 1, -2, 2, -3, 0,
+ 0, -1, -1, 0, 1, 0, -3, 0, 0, -1, 1, -1, -2, 1, -1, 0,
+ -2, 2, 1, -2, -1, 1, 0, -1, -1, 0, 1, -1, 0, -2, 1, 1,
+ -1, 0, -1, -1, 0, 0, -1, -1, 0, -1, -1, 2, -2, -1, 1, 0,
+ 0, -1, -1, 1, 0, -1, 1, -1, 0, 1, -3, 1, 1, -1, -1, 0,
+ 1, 0, 0, 0, -1, 0, 0, -1, 0, 1, 0, 0, 2, -2, 0, 1,
+ 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, -1, -1, -7, -9, 35, -52,
+ 59, -33, -32, 64, -15, -41, 19, 22, -20, 9, -11, -3, 33, -27, 2, 7,
+ -9, 19, -37, 24, 7, -11, 11, -1, -30, 37, 8, -57, 36, 19, -33, 14,
+ 0, -17, 26, 1, -20, -5, 26, -18, -13, 14, 7, -6, 4, -9, -4, 11,
+ 3, -14, -7, 20, 0, -18, 10, 1, 4, -5, -7, 6, 0, -3, -2, -2,
+ 8, 5, -11, -6, 10, -1, -10, 6, -2, -1, 1, -3, 0, 3, 5, -9,
+ -5, 9, -3, -4, 1, 1, 3, -1, -4, -1, 2, -2, -5, 5, -3, 0,
+ 1, -5, 4, 2, -3, -3, 0, 0, -2, 1, 0, -2, 3, -2, -5, 2,
+ 2, -2, -4, 3, 0, -2, 1, -2, -2, 5, -2, -6, 1, 2, -1, -1,
+ 0, 1, -1, -2, -1, -1, 2, 0, -4, 0, 1, 0, -3, 0, 2, 0,
+ -3, 0, 0, 1, -1, -1, 1, 0, -1, -2, 1, 0, 0, -1, 0, -2,
+ 1, 0, -1, 1, -1, 0, -2, 1, 1, -2, -1, 2, -2, 1, -3, 1,
+ 1, -1, 0, 0, -1, 1, 0, -2, 2, -1, -1, 0, 0, 1, 0, 1,
+ 0, -2, 1, 0, 0, -1, 1, 0, 0, 0, 0, -3, -20, 45, -56, 40,
+ -5, -34, 27, 24, -42, -1, 29, -14, -4, 2, -7, 24, -20, -1, 18, -25,
+ 25, -29, 9, 21, -26, 14, 4, -20, 7, 27, -42, 5, 31, -24, -2, 19,
+ -30, 21, 8, -11, -17, 20, 1, -22, 11, 7, -7, 6, -5, -7, 3, 11,
+ -6, -18, 11, 16, -20, 1, 5, 2, -3, -3, 0, -3, 4, -1, -7, 2,
+ 10, -9, -8, 7, 2, -9, 5, -1, -5, 2, 1, -3, -2, 9, -5, -8,
+ 4, 1, -5, 0, 1, 2, -1, 0, -5, 4, -1, -5, 4, -3, 1, 1,
+ -5, 3, 0, 0, -3, 0, -1, -2, 1, 2, -5, 2, 1, -5, -2, 3,
+ -1, -5, 2, 1, -4, 2, -1, -4, 2, 3, -7, -1, 2, 0, -2, 1,
+ 0, -2, -1, 0, -3, 1, 2, -3, -2, 3, 0, -3, -1, 1, 0, -1,
+ -2, -1, 1, 0, 0, -1, 0, 0, -2, 0, 0, 1, -2, 2, -3, 1,
+ 0, 0, -2, 1, 0, -1, 0, 0, -1, -1, 2, -3, 0, 0, -1, 0,
+ 0, -1, 1, 0, -4, -13, 32, -41, 31, -10, -10, 4, 22, -25, -8, 21,
+ -3, -14, 5, 1, 12, -23, 8, 18, -31, 25, -26, 10, 17, -23, 8, 5,
+ -9, 0, 16, -25, 2, 23, -22, -2, 22, -30, 15, 7, -6, -13, 12, 1,
+ -17, 9, 5, -6, 4, -3, -7, 5, 7, -6, -13, 7, 10, -11, 0, 0,
+ 4, -3, -3, 2, -7, 4, 2, -5, 0, 6, -3, -8, 4, 2, -8, 7,
+ 0, -8, -1, 6, 0, -8, 6, 0, -5, 1, 0, -5, 3, 2, -3, -2,
+ 4, -5, -1, -1, -2, 3, -4, 1, -1, -3, 3, -1, -2, -2, 1, -2,
+ -2, 1, 1, -4, 1, 2, -5, -3, 5, -3, -4, 4, -1, -4, 2, -1,
+ -4, 3, 1, -5, -2, 2, 0, -2, 2, -1, -4, 3, -1, -3, 0, 1,
+ -2, -2, 1, -1, -1, -1, 0, 0, -1, -1, -1, 0, -1, 1, -1, -1,
+ 0, -2, 1, 0, -1, -1, 0, -1, -1, -1, 2, -2, -1, 1, -1, -2,
+ 1, -1, -1, 1, -2, 1, -7, -3, 15, -23, 20, -16, 9, -12, 16, -12,
+ -8, 11, 5, -18, 6, 8, 0, -18, 16, 4, -19, 16, -17, 10, 5, -8,
+ -2, 9, -5, -4, 10, -17, 5, 13, -18, 2, 12, -17, 10, 0, -2, -8,
+ 7, -4, -7, 6, 1, -3, 1, 3, -9, -2, 10, -7, -8, 4, 6, -6,
+ 1, 0, 0, -2, 1, -1, -8, 6, 1, -5, 2, 4, -2, -4, 1, 1,
+ -7, 5, -1, -4, -2, 4, 0, -4, 4, -3, -4, 1, 0, -3, 0, 2,
+ -1, -2, 2, -2, -1, -3, 0, 3, -4, 3, -3, 0, 2, 0, -3, -1,
+ 1, -3, -1, 2, 0, -1, 0, 0, -3, 0, 1, -4, -1, 2, 0, -2,
+ 0, 1, -3, 1, 1, -3, -2, 2, -1, -1, 2, -1, -2, 1, 0, -1,
+ -1, -1, -3, -8, -16, -20, -7, 14, 20, 19, 18, 16, 11, 3, -9, -21,
+ -36, -43, -39, -24, 6, 38, 57, 55, 26, 0, -7, -10, -13, -12, -11, -29,
+ -56, -59, -37, 0, 43, 74, 87, 75, 37, -2, -31, -51, -59, -45, -15, -16,
+ -34, -20, -10, -5, 29, 61, 72, 51, 18, -2, -21, -39, -35, -24, 1, 0,
+ -31, -29, -23, -44, -13, 48, 82, 79, 46, 16, -4, -44, -58, -26, 3, 6,
+ -38, -52, -24, -42, -35, 47, 95, 88, 55, 19, 12, -22, -72, -38, 4, 3,
+ -31, -67, -29, -24, -60, 23, 112, 111, 72, 22, 7, -20, -90, -73, -1, 19,
+ -4, -57, -36, 3, -54, -32, 98, 125, 71, 14, 14, 0, -82, -106, 0, 42,
+ 10, -48, -32, -2, -54, -63, 72, 125, 82, 24, 14, -8, -57, -104, -22, 52,
+ 34, -34, -46, -16, -35, -83, 32, 127, 99, 26, 19, 4, -55, -110, -48, 45,
+ 36, -12, -26, -22, -41, -64, -7, 107, 113, 56, 6, 4, -41, -92, -74, 35,
+ 57, 12, -41, -21, -39, -67, -40, 86, 114, 71, 10, 22, -31, -83, -83, 16,
+ 46, 34, -28, -18, -42, -58, -60, 55, 108, 97, 3, 21, -8, -77, -102, 10,
+ 45, 42, -26, -2, -27, -68, -73, 45, 83, 92, 29, 25, -8, -56, -104, -13,
+ 35, 52, -6, -7, -22, -46, -91, 10, 80, 95, 35, 26, 8, -38, -106, -34,
+ 34, 42, 5, 1, -23, -39, -73, -28, 61, 89, 60, 20, 2, -7, -73, -86,
+ 24, 52, 26, -12, -11, -19, -58, -86, 46, 91, 62, 17, 22, -15, -39, -106,
+ 8, 55, 45, -13, -6, -30, -21, -102, 4, 82, 87, 7, 28, -3, -9, -115,
+ -32, 50, 63, -23, 8, -19, -18, -94, -28, 61, 96, 14, 39, -4, 1, -85,
+ -60, 23, 79, -3, 2, -20, -10, -82, -65, 25, 108, 28, 31, 19, 9, -65,
+ -74, -5, 78, 16, -3, -9, -14, -65, -76, -3, 93, 60, 29, 22, 13, -43,
+ -90, -30, 61, 49, -9, -1, 4, -52, -98, -16, 68, 72, 21, 38, 15, -31,
+ -94, -34, 32, 67, 5, 9, 0, -28, -111, -33, 40, 85, 24, 37, 23, -6,
+ -104, -44, 13, 69, 9, 14, 8, -11, -110, -53, 20, 80, 32, 48, 30, 5,
+ -87, -66, -7, 63, 33, 12, 2, 5, -86, -94, -2, 79, 46, 26, 44, 22,
+ -59, -88, -19, 54, 48, 13, 14, 4, -51, -112, -37, 67, 71, 21, 38, 29,
+ -29, -104, -50, 44, 63, 11, 10, 14, -24, -103, -67, 49, 88, 20, 27, 43,
+ -10, -90, -79, 24, 69, 21, 7, 18, -8, -82, -103, 17, 94, 38, 10, 54,
+ 12, -70, -97, 1, 68, 37, -4, 27, -6, -56, -104, -21, 82, 67, -3, 46,
+ 23, -37, -108, -31, 57, 58, -13, 29, 11, -32, -106, -50, 53, 92, -6, 38,
+ 38, -15, -105, -54, 34, 79, -12, 20, 22, -11, -98, -70, 22, 99, 4, 16,
+ 48, 14, -99, -75, 15, 82, 2, 0, 44, 8, -93, -80, 0, 84, 29, -3,
+ 57, 32, -79, -94, 1, 66, 27, -19, 49, 29, -73, -109, -7, 54, 52, -17,
+ 62, 53, -46, -113, -4, 43, 51, -30, 46, 37, -42, -128, -23, 26, 69, -18,
+ 51, 59, -2, -122, -30, 24, 66, -27, 31, 51, 1, -128, -48, 13, 71, -11,
+ 33, 66, 22, -110, -57, 8, 68, -9, 12, 53, 28, -104, -87, -4, 67, 8,
+ 8, 72, 53, -80, -91, -4, 59, 10, -13, 63, 44, -81, -109, -19, 46, 33,
+ -6, 76, 57, -43, -104, -24, 36, 42, -26, 55, 51, -34, -126, -39, 19, 58,
+ -21, 68, 71, -8, -114, -32, 2, 62, -24, 52, 54, -4, -120, -53, -22, 71,
+ -8, 49, 62, 31, -102, -52, -25, 70, -5, 24, 55, 35, -109, -69, -40, 59,
+ 16, 25, 65, 55, -80, -70, -37, 47, 23, 7, 48, 51, -73, -97, -48, 30,
+ 46, 6, 57, 74, -37, -98, -34, 21, 48, -10, 44, 58, -34, -123, -46, -2,
+ 61, 2, 50, 69, 10, -110, -40, -5, 59, -9, 31, 53, 19, -126, -59, -20,
+ 62, 8, 32, 64, 49, -105, -59, -16, 58, 2, 17, 50, 45, -102, -83, -31,
+ 46, 24, 15, 53, 69, -65, -86, -24, 42, 25, -4, 45, 64, -58, -112, -37,
+ 30, 41, -6, 51, 75, -24, -105, -32, 26, 41, -19, 39, 62, -14, -117, -51,
+ 7, 54, -13, 35, 78, 19, -105, -47, 9, 58, -19, 21, 69, 18, -113, -66,
+ -10, 52, -10, 14, 75, 42, -83, -60, -5, 52, 0, -3, 69, 43, -83, -83,
+ -21, 35, 17, -13, 72, 57, -54, -82, -10, 29, 28, -29, 65, 52, -45, -98,
+ -21, 1, 40, -30, 64, 63, -7, -94, -9, 1, 51, -36, 51, 54, -8, -115,
+ -23, -22, 47, -30, 48, 65, 24, -90, -13, -15, 46, -26, 30, 55, 21, -100,
+ -37, -26, 31, -10, 24, 65, 41, -71, -35, -10, 25, -2, 4, 58, 32, -69,
+ -61, -16, 2, 8, 1, 67, 42, -33, -56, -1, -1, 20, -13, 59, 33, -28,
+ -82, -10, -20, 22, -15, 64, 40, -1, -70, 0, -17, 29, -22, 53, 33, 1,
+ -84, -15, -29, 22, -19, 53, 43, 22, -64, -7, -19, 25, -18, 37, 38, 16,
+ -73, -30, -33, 11, -14, 32, 50, 31, -45, -17, -15, 16, -4, 16, 43, 23,
+ -49, -43, -30, -2, -1, 8, 52, 36, -25, -32, -13, -1, 11, -1, 42, 30,
+ -25, -49, -25, -18, 10, -7, 44, 40, -2, -34, -11, -15, 21, -6, 29, 33,
+ -5, -54, -29, -30, 13, -6, 29, 46, 15, -32, -10, -18, 16, -1, 13, 36,
+ 9, -45, -30, -32, 0, 1, 12, 43, 28, -23, -16, -16, 6, 9, 2, 33,
+ 22, -33, -34, -27, -11, 2, 1, 35, 36, -14, -16, -11, -5, 8, 3, 24,
+ 32, -19, -30, -29, -17, -4, 1, 20, 43, -5, -14, -13, -4, 0, 7, 11,
+ 39, -9, -23, -28, -17, -16, 1, 9, 44, 3, -7, -15, -4, -4, 7, 5,
+ 38, 3, -20, -30, -19, -19, -8, 0, 40, 17, -6, -7, -3, -2, -1, 4,
+ 32, 16, -20, -21, -26, -17, -18, -3, 28, 32, -7, -1, -9, 4, -9, 3,
+ 22, 34, -19, -14, -27, -13, -27, -10, 16, 44, -8, 5, -6, 3, -12, 1,
+ 13, 40, -12, -11, -25, -17, -27, -15, 5, 45, 4, 2, 0, 0, -9, -5,
+ 6, 38, 2, -17, -14, -20, -24, -23, 0, 38, 19, -4, 11, -4, -7, -10,
+ 4, 27, 20, -20, -9, -23, -22, -30, -6, 26, 35, -8, 12, 2, -4, -15,
+ 2, 20, 32, -16, -7, -15, -22, -37, -14, 18, 39, -3, 5, 8, -5, -18,
+ -2, 18, 34, -4, -14, -4, -21, -35, -25, 15, 36, 8, -4, 21, -5, -17,
+ -14, 23, 26, 9, -22, 4, -25, -32, -40, 14, 27, 24, -12, 30, 1, -8,
+ -26, 24, 21, 19, -28, 9, -20, -28, -51, 7, 23, 30, -15, 27, 9, -7,
+ -32, 16, 25, 23, -21, 4, -8, -27, -50, -10, 25, 29, -9, 13, 24, -7,
+ -28, -3, 34, 20, -12, -9, 10, -31, -43, -29, 30, 23, 2, -3, 38, -9,
+ -19, -19, 39, 18, -1, -20, 25, -29, -36, -42, 26, 17, 12, -14, 43, -3,
+ -15, -29, 35, 19, 6, -28, 27, -18, -36, -48, 16, 17, 15, -15, 39, 12,
+ -13, -29, 24, 24, 9, -25, 19, -1, -39, -50, 1, 18, 11, -11, 25, 26,
+ -14, -26, 12, 32, 10, -17, 6, 17, -33, -48, -14, 20, 6, -7, 11, 36,
+ -9, -26, -1, 34, 11, -9, -4, 25, -25, -49, -26, 19, 4, -4, 5, 41,
+ 3, -21, -8, 31, 12, -7, -11, 23, -13, -47, -37, 13, 6, -3, 1, 40,
+ 14, -17, -14, 26, 16, -2, -12, 20, -3, -40, -44, 2, 6, -2, -4, 35,
+ 24, -9, -19, 19, 17, 2, -13, 16, 5, -29, -48, -7, 4, 3, -7, 28,
+ 28, 2, -21, 13, 14, 9, -14, 11, 9, -15, -49, -17, -3, 6, -11, 20,
+ 30, 14, -23, 7, 12, 14, -11, 6, 10, -4, -46, -24, -10, 6, -8, 11,
+ 29, 24, -15, 0, 11, 14, -4, -2, 11, 3, -37, -36, -13, -3, -2, 2,
+ 28, 27, -2, -10, 14, 9, 7, -8, 13, 3, -21, -42, -14, -14, 4, -6,
+ 24, 24, 13, -16, 12, 3, 14, -8, 12, 4, -7, -44, -18, -20, 5, -6,
+ 18, 22, 23, -13, 6, 2, 13, -4, 5, 5, 1, -36, -26, -20, -1, -1,
+ 10, 23, 25, -3, -4, 5, 9, 5, -2, 8, 1, -24, -36, -18, -10, 4,
+ 1, 24, 23, 11, -9, 8, 4, 12, -7, 9, 1, -12, -40, -19, -16, 4,
+ -4, 21, 21, 16, -9, 6, 2, 13, -4, 6, 6, -4, -33, -24, -18, -2,
+ -2, 10, 21, 18, 0, -3, 3, 8, 6, -1, 8, 0, -18, -31, -19, -10,
+ 1, 0, 19, 20, 13, -5, 4, 5, 12, -4, 5, 2, -7, -34, -24, -17,
+ 1, -4, 13, 20, 21, -3, 2, 5, 14, 0, 2, 4, 0, -26, -28, -20,
+ -6, -4, 4, 18, 23, 6, -3, 5, 9, 7, -1, 6, 3, -14, -33, -22,
+ -14, -1, -1, 16, 22, 17, -4, 4, 4, 10, -2, 4, 3, -4, -30, -25,
+ -19, -2, -2, 11, 20, 23, 0, 0, 2, 10, 3, 1, 4, 1, -23, -30,
+ -22, -8, -1, 4, 19, 23, 10, -3, 4, 6, 8, -2, 5, 2, -13, -33,
+ -23, -15, 0, -1, 16, 21, 16, -3, 3, 4, 11, 0, 5, 6, -3, -27,
+ -25, -19, -4, -2, 9, 19, 19, 2, -3, 2, 8, 6, -1, 8, 0, 0,
+ 2, 33, 42, 58, 71, 79, 85, 88, 91, 94, 79, 95, 82, 106, 86, 105,
+ 47, 16, -6, 13, 44, 31, -15, -38, -36, 20, 70, 41, 48, 58, 24, -57,
+ -127, -119, -102, -126, -128, -111, -78, -82, -88, -87, -60, -66, -98, -104, -99, -97,
+ -99, -104, -101, -88, -87, -91, -61, -27, -34, -54, -55, -45, -24, -10, -5, -4,
+ 5, 34, 63, 101, 94, 78, 52, 51, 52, 74, 81, 77, 59, 46, 17, 7,
+ 39, 53, 47, 42, 66, 83, 73, 52, 28, 22, 11, 8, 11, 0, -15, -23,
+ -15, -14, -6, 16, 46, 62, 71, 76, 90, 102, 103, 103, 101, 100, 90, 75,
+ 63, 67, 49, 37, 28, 12, 5, 6, 15, 15, 8, -7, -12, -4, -10, -28,
+ -24, -17, -25, -50, -64, -81, -103, -116, -116, -113, -95, -72, -54, -41, -47, -65,
+ -65, -50, -33, -24, -7, 11, 8, -4, -13, -28, -51, -75, -90, -91, -90, -90,
+ -87, -88, -83, -84, -82, -81, -81, -76, -65, -71, -85, -84, -79, -83, -81, -77,
+ -72, -70, -65, -66, -66, -65, -66, -68, -61, -56, -51, -36, -13, -3, -5, -8,
+ -12, -12, 3, 16, 21, 31, 50, 69, 77, 82, 90, 102, 110, 114, 116, 117,
+ 118, 119, 116, 112, 109, 105, 98, 99, 103, 102, 91, 73, 64, 63, 61, 57,
+ 51, 40, 24, 35, 57, 75, 84, 79, 65, 37, 4, -26, -45, -57, -54, -46,
+ -45, -54, -67, -67, -48, -16, 15, 35, 44, 45, 44, 45, 46, 38, 23, 2,
+ -15, -34, -52, -60, -70, -77, -80, -79, -74, -77, -84, -86, -80, -72, -68, -72,
+ -80, -87, -92, -96, -101, -104, -104, -101, -93, -90, -89, -86, -85, -84, -83, -82,
+ -81, -79, -77, -76, -73, -71, -66, -62, -55, -39, -31, -27, -25, -31, -37, -46,
+ -51, -53, -54, -48, -45, -38, -20, 3, 24, 35, 39, 32, 16, 5, 3, 0,
+ -6, -13, -13, -11, -2, 14, 28, 40, 50, 53, 50, 55, 64, 74, 90, 105,
+ 108, 112, 106, 104, 109, 112, 123, 127, 127, 127, 127, 127, 127, 118, 113, 107,
+ 110, 114, 111, 104, 101, 101, 102, 103, 99, 99, 89, 73, 53, 35, 20, 0,
+ -22, -43, -63, -77, -82, -76, -65, -48, -36, -29, -24, -25, -29, -37, -40, -49,
+ -59, -67, -73, -76, -78, -79, -75, -73, -74, -75, -68, -52, -44, -30, -19, -9,
+ -6, -9, -13, -24, -33, -35, -31, -30, -35, -40, -44, -45, -51, -53, -54, -50,
+ -50, -47, -42, -50, -55, -54, -56, -56, -54, -54, -49, -48, -41, -32, -28, -18,
+ -13, -5, 6, 18, 33, 49, 60, 71, 78, 88, 95, 97, 93, 88, 91, 93,
+ 97, 98, 97, 94, 91, 85, 81, 72, 70, 66, 61, 60, 64, 66, 74, 83,
+ 92, 102, 108, 109, 107, 102, 97, 95, 91, 87, 80, 74, 67, 62, 61, 58,
+ 61, 61, 57, 53, 43, 35, 27, 25, 24, 20, 20, 22, 27, 34, 36, 32,
+ 21, 8, -3, -10, -16, -18, -16, -16, -19, -15, -11, -11, -12, -20, -34, -45,
+ -59, -72, -80, -89, -94, -95, -102, -111, -114, -111, -111, -108, -106, -104, -101, -98,
+ -93, -90, -86, -86, -83, -82, -81, -79, -76, -73, -70, -72, -78, -81, -79, -79,
+ -72, -60, -43, -31, -25, -27, -34, -37, -40, -42, -41, -39, -36, -34, -25, -12,
+ -4, 5, 12, 16, 17, 15, 13, 6, -4, -7, -8, -6, -1, 4, 7, 9,
+ 12, 16, 19, 19, 22, 28, 29, 28, 29, 30, 34, 40, 49, 57, 71, 78,
+ 85, 92, 96, 95, 89, 85, 86, 93, 99, 104, 102, 100, 94, 85, 77, 73,
+ 69, 66, 63, 60, 60, 59, 57, 52, 47, 41, 31, 18, 6, -3, -7, -11,
+ -12, -14, -18, -22, -23, -22, -24, -30, -37, -41, -44, -50, -56, -64, -67, -65,
+ -62, -58, -58, -58, -59, -61, -62, -66, -72, -78, -79, -77, -73, -68, -64, -61,
+ -56, -53, -54, -52, -52, -57, -63, -69, -70, -68, -65, -62, -59, -57, -56, -58,
+ -60, -61, -63, -64, -62, -61, -60, -58, -54, -49, -45, -42, -39, -36, -32, -28,
+ -22, -13, -7, -3, 2, 13, 28, 41, 52, 64, 71, 73, 73, 70, 64, 61,
+ 60, 64, 66, 65, 66, 64, 61, 60, 62, 65, 64, 66, 67, 67, 68, 66,
+ 64, 66, 68, 73, 76, 74, 72, 66, 58, 52, 46, 42, 38, 38, 41, 47,
+ 52, 52, 48, 45, 42, 40, 38, 34, 29, 27, 26, 28, 29, 28, 29, 30,
+ 31, 28, 24, 21, 19, 17, 14, 10, 6, 3, -4, -9, -15, -19, -26, -33,
+ -40, -49, -55, -60, -65, -70, -73, -72, -72, -71, -70, -71, -75, -78, -81, -83,
+ -86, -86, -85, -84, -82, -80, -77, -72, -69, -66, -63, -61, -61, -61, -61, -61,
+ -60, -58, -53, -48, -42, -36, -30, -28, -30, -32, -33, -32, -31, -28, -22, -18,
+ -10, -5, 0, 3, 6, 11, 16, 19, 22, 24, 26, 27, 29, 34, 40, 46,
+ 48, 48, 48, 45, 40, 36, 33, 31, 33, 35, 40, 48, 55, 62, 68, 73,
+ 76, 78, 78, 77, 79, 82, 85, 87, 87, 87, 86, 86, 86, 83, 78, 71,
+ 63, 55, 48, 44, 39, 36, 36, 36, 35, 32, 28, 24, 18, 13, 9, 6,
+ 4, 1, -2, -5, -11, -17, -20, -21, -20, -21, -24, -28, -32, -34, -33, -33,
+ -35, -37, -40, -43, -47, -52, -58, -63, -69, -74, -77, -80, -81, -82, -81, -80,
+ -77, -74, -69, -62, -54, -48, -48, -51, -54, -57, -57, -57, -56, -55, -55, -56,
+ -57, -56, -55, -54, -54, -54, -54, -52, -49, -45, -41, -38, -34, -31, -29, -27,
+ -24, -20, -17, -11, -7, -3, 0, 5, 10, 16, 22, 27, 31, 34, 38, 42,
+ 44, 45, 48, 50, 52, 57, 61, 64, 64, 65, 65, 63, 60, 57, 55, 55,
+ 58, 61, 63, 65, 67, 69, 71, 74, 77, 79, 79, 77, 74, 71, 68, 66,
+ 63, 60, 57, 55, 51, 46, 40, 36, 30, 25, 20, 17, 16, 17, 16, 14,
+ 12, 10, 7, 3, -1, -5, -11, -15, -17, -18, -18, -19, -21, -25, -29, -32,
+ -33, -33, -36, -39, -43, -46, -50, -53, -56, -58, -59, -60, -61, -62, -63, -65,
+ -66, -67, -68, -70, -72, -72, -70, -67, -63, -61, -60, -60, -58, -56, -54, -53,
+ -52, -52, -52, -51, -50, -49, -47, -45, -43, -40, -37, -35, -34, -32, -29, -25,
+ -21, -18, -14, -9, -4, 0, 4, 7, 11, 15, 18, 21, 25, 28, 33, 37,
+ 41, 44, 46, 47, 47, 46, 46, 45, 43, 42, 42, 43, 46, 48, 49, 50,
+ 52, 55, 59, 62, 65, 66, 67, 68, 69, 69, 70, 72, 74, 74, 73, 72,
+ 71, 69, 65, 61, 57, 53, 50, 46, 43, 38, 35, 32, 28, 23, 19, 17,
+ 17, 15, 13, 11, 9, 5, 1, -3, -6, -9, -12, -14, -17, -19, -23, -27,
+ -31, -35, -38, -40, -43, -46, -48, -52, -55, -57, -61, -64, -66, -67, -68, -69,
+ -70, -70, -70, -69, -69, -70, -71, -70, -66, -62, -59, -55, -52, -50, -46, -43,
+ -41, -38, -36, -35, -35, -34, -33, -33, -33, -33, -31, -30, -28, -26, -25, -24,
+ -21, -20, -20, -19, -19, -18, -17, -16, -15, -13, -11, -8, -3, 2, 9, 15,
+ 21, 27, 33, 38, 41, 45, 48, 51, 53, 55, 56, 56, 56, 56, 56, 56,
+ 56, 55, 57, 58, 60, 61, 62, 62, 64, 66, 68, 69, 71, 72, 73, 74,
+ 72, 70, 67, 63, 60, 57, 54, 50, 46, 41, 36, 31, 27, 23, 19, 16,
+ 14, 12, 11, 9, 8, 5, 2, -1, -4, -8, -10, -15, -18, -19, -20, -22,
+ -22, -23, -23, -24, -26, -29, -31, -33, -35, -36, -37, -38, -41, -44, -46, -48,
+ -50, -52, -54, -56, -59, -61, -63, -63, -64, -65, -64, -63, -62, -61, -60, -59,
+ -58, -57, -58, -57, -57, -55, -53, -50, -49, -47, -46, -43, -40, -37, -33, -31,
+ -28, -26, -23, -20, -16, -14, -12, -9, -5, -2, 1, 5, 9, 13, 17, 21,
+ 24, 26, 29, 32, 35, 37, 37, 38, 39, 41, 43, 44, 45, 46, 48, 50,
+ 51, 53, 52, 52, 50, 48, 47, 46, 46, 46, 46, 47, 48, 49, 51, 54,
+ 56, 58, 60, 61, 62, 62, 62, 61, 59, 57, 55, 54, 53, 52, 51, 49,
+ 46, 41, 36, 31, 27, 22, 18, 14, 11, 9, 6, 3, 0, -2, -5, -8,
+ -11, -16, -20, -25, -28, -31, -34, -37, -39, -41, -41, -42, -42, -42, -43, -45,
+ -46, -47, -49, -50, -52, -54, -56, -57, -58, -60, -61, -63, -64, -64, -64, -63,
+ -63, -61, -59, -58, -57, -55, -54, -53, -52, -52, -51, -50, -49, -47, -46, -45,
+ -44, -42, -40, -38, -35, -32, -30, -28, -25, -22, -19, -17, -15, -12, -9, -5,
+ -1, 3, 7, 11, 15, 19, 23, 25, 27, 30, 34, 36, 37, 38, 39, 40,
+ 42, 44, 45, 46, 47, 49, 50, 52, 53, 52, 51, 49, 47, 47, 46, 46,
+ 46, 47, 47, 48, 50, 52, 55, 57, 59, 61, 62, 62, 62, 61, 60, 58,
+ 56, 54, 54, 53, 51, 50, 47, 44, 39, 34, 29, 25, 20, 16, 13, 10,
+ 7, 4, 2, -1, -3, -6, -9, -14, -18, -22, -26, -30, -33, -35, -38, -40,
+ -41, -41, -42, -42, -43, -44, -46, -47, -48, -49, -51, -53, -55, -56, -57, -59,
+ -60, -62, -63, -64, -64, -63, -63, -62, -60, -59, -57, -56, -55, -53, -52, -52,
+ -51, -51, -50, -48, -46, -45, -44, -43, -41, -39, -36, -34, -31, -29, -26, -24,
+ -21, -16, -1, -2, -1, -3, 1, -2, -2, -4, 2, 6, 2, -2, -2, 0,
+ 7, 8, 4, -2, -2, 6, 5, 6, 0, -2, 5, 12, 10, 0, -5, -3,
+ 5, 10, 9, -7, -8, -7, 5, 8, 3, -9, -13, -5, 3, 5, -5, -9,
+ -4, 0, 6, 0, -4, -11, -7, 3, 4, 0, -5, 0, -1, 5, 1, 4,
+ -6, -5, -3, 12, 9, -2, -10, 4, 11, 8, -4, -5, -9, -6, 1, 19,
+ 13, -2, -22, 4, 9, 6, -26, -4, 3, 12, -9, 0, 2, 0, -15, 4,
+ 8, -8, -20, 0, 15, 8, -13, -2, -4, -4, -2, 12, 3, -14, -18, 1,
+ 21, 13, -9, -25, -8, 17, 15, 5, -14, -17, 5, 19, 13, -15, -17, -3,
+ 10, 20, 10, -27, -19, 5, 11, 12, 3, -13, -17, -1, 6, -3, -2, 1,
+ -1, -11, -17, 7, 7, -7, -7, -13, 9, 0, -5, 9, -5, -9, 6, 5,
+ -2, -16, -5, 15, 17, -10, -20, 1, 11, 14, -1, 1, 10, -11, -8, -1,
+ 18, 13, -2, -12, 1, -16, -2, 34, 27, -28, -42, -3, 42, 26, -14, -39,
+ -19, 7, 26, 25, -16, -55, -26, 32, 57, 4, -69, -48, 6, 75, 29, -51,
+ -67, -32, 51, 56, 7, -57, -75, 14, 63, 43, -29, -82, -27, 31, 56, 28,
+ -43, -81, -31, 59, 85, 1, -100, -59, 8, 102, 41, -42, -92, -52, 72, 79,
+ 29, -103, -85, -1, 117, 49, -54, -113, 7, 24, 94, -28, -39, -84, 39, 28,
+ 61, -44, -28, -67, 61, 23, 35, -40, -23, -37, 6, 38, 69, -42, -61, -53,
+ 58, 86, 2, -93, -24, 19, 72, 17, -19, -87, 45, 10, 64, -13, -45, -57,
+ 38, 48, 36, -51, -35, -37, 46, 26, 37, -73, -28, -12, 44, 22, 27, -84,
+ -22, 6, 70, 17, -24, -82, -7, 26, 79, 9, -63, -78, 6, 90, 68, -55,
+ -118, -3, 92, 62, -10, -73, -50, 14, 110, 15, -5, -118, 5, 69, 53, 22,
+ -81, -45, 29, 47, 80, -69, -28, -52, 58, 66, -1, -25, -59, -22, 107, 2,
+ 43, -108, -13, 20, 59, 56, -58, -66, -7, 34, 114, -42, -63, -50, 42, 69,
+ 44, -63, -37, -50, 114, 27, 18, -49, -81, 20, 74, 51, -14, -102, -4, 40,
+ 70, 38, -64, -73, 11, 60, 76, -41, -30, -78, 42, 46, 68, -63, -48, -56,
+ 89, 43, 28, -100, -53, 41, 60, 11, -6, -76, -16, 44, 52, 9, -67, -48,
+ 10, 69, 30, -1, -84, -4, 36, 72, -23, -22, -27, -33, 55, 74, -11, -86,
+ -1, 27, 36, 31, -7, -101, 49, 5, 66, -7, -46, -39, 9, 64, 44, -63,
+ -33, -22, 55, 23, 43, -79, -24, 5, 29, 54, -14, -59, -53, 63, 32, 20,
+ -34, -32, -36, 93, -2, 20, -35, -38, 18, 51, 61, -94, 15, -14, 17, 69,
+ 5, -87, 16, 28, 34, 1, 34, -57, -53, 118, -22, 34, -10, -71, 23, 70,
+ 25, -29, -7, -19, -3, 117, -33, -12, -21, -19, 43, 84, -38, -57, 33, 0,
+ 32, 41, -7, -103, 85, 2, 2, 58, -14, -103, 103, 7, -17, 34, -32, -59,
+ 71, 51, -78, 76, -65, -30, 63, 48, -66, 9, -11, -28, 52, 50, -72, -37,
+ 73, -61, 75, 7, -51, -44, 73, -3, -11, 40, -78, 7, 63, -15, -16, 30,
+ -53, 12, 38, 12, -42, 39, -63, 47, 23, 0, -23, -11, 8, -25, 60, -37,
+ -15, -3, -9, 12, 27, -14, -40, 22, 12, 14, 15, -31, -14, 15, 23, -12,
+ 14, -31, 19, 13, 32, -39, 27, -51, 43, 8, 0, 5, -26, 16, 4, 19,
+ -24, 17, -18, 6, -2, 49, -67, 39, -1, -30, 46, -13, -16, -9, 21, -17,
+ 27, 2, -34, 19, -3, 24, 8, -38, 13, -10, 22, 15, -34, 2, 4, -10,
+ 18, 14, -15, -15, 26, -12, 28, -21, 0, -6, 0, 7, 0, -15, 6, -2,
+ -18, 9, 8, -18, -15, 59, -94, 81, -40, -24, 14, -18, 25, -15, 4, -21,
+ -9, 24, -20, 3, 3, -52, 56, -29, 4, 5, -51, 45, -50, 73, -75, 13,
+ 17, -48, 38, -10, -16, 5, 4, -22, 3, 17, -27, -23, 42, -30, -5, 41,
+ -53, 10, 23, -28, 1, 29, -47, 9, 13, -3, -18, 9, -13, -11, 18, 12,
+ -53, 28, 1, -41, 41, 7, -61, 32, 0, -34, 16, 9, -74, 45, -23, -33,
+ 22, 39, -104, 49, 23, -96, 83, 5, -46, 36, -4, -45, 54, -25, -26, 21,
+ 2, -39, 51, -25, -25, 43, -22, -25, 30, -2, -32, 39, 14, -69, 42, 22,
+ -78, 60, 23, -83, 33, 44, -74, 19, 69, -113, 43, 53, -88, 51, 17, -74,
+ 42, 1, -38, 4, 39, -67, 12, 35, -39, -23, 73, -82, -5, 67, -71, -5,
+ 42, -36, -48, 78, -64, -4, 40, -48, -7, 50, -80, 17, 31, -56, 9, 6,
+ -18, -36, 43, -37, -29, 47, -47, -18, 33, -29, -27, 40, -30, -37, 51, -46,
+ -25, 61, -66, 7, 28, -48, 30, -15, -8, -6, 17, -14, -9, 26, -23, 4,
+ 9, -15, 12, -9, 16, -22, 7, 22, -51, 59, -29, -23, 54, -49, 6, 20,
+ -19, -11, 17, -3, -30, 32, -27, -5, 16, -28, 4, 4, -27, 32, -46, 27,
+ -18, -8, 11, -25, 18, -6, -17, 10, 1, -18, 24, -33, 10, 8, -12, -10,
+ 21, -19, 0, 8, -18, 14, 11, -44, 39, -22, -4, -6, 11, -15, -13, 17,
+ -17, -6, 13, -22, -1, 7, -5, -8, 0, 4, -24, 29, -23, 0, 20, -25,
+ -8, 30, -34, 31, -29, 11, -9, 21, -15, -1, 10, -9, -11, 32, -23, -2,
+ -14, 27, -19, 10, -4, -23, 14, 13, -45, 48, -44, 11, -4, -7, -3, 4,
+ -2, -34, -8, 37, -41, 20, -24, -4, -10, 2, 4, 12, -28, -30, 9, 32,
+ -16, 6, -46, -23, 60, 0, -22, -3, -23, -15, 48, 12, -34, -17, -18, 10,
+ 46, -1, -56, -8, 12, 9, 18, 13, -72, -3, 26, 9, 28, -14, -89, 15,
+ 67, -18, 1, -19, -52, 45, 26, -8, -5, -25, -25, 36, 38, -13, -36, -18,
+ -6, 55, 23, -51, -14, 4, 6, 25, 24, -41, -44, 38, 19, 10, 10, -59,
+ -14, 42, 1, 6, -8, -43, -1, 43, 10, -30, -10, -36, 18, 35, -20, -14,
+ -11, -19, 9, 20, -5, -22, -9, -6, 13, 26, -30, -23, 4, 1, 20, 9,
+ -20, -22, 3, -1, 17, 28, -26, -25, 16, -2, -4, 12, -10, -16, 24, -2,
+ -18, 17, -27, -1, 36, -6, -7, -4, -26, 6, 29, -3, -17, -6, -4, 18,
+ 18, -26, -10, -4, 6, 30, -1, -6, -24, 0, 24, 12, 2, -16, -25, 13,
+ 32, -3, -4, -3, -24, 15, 16, -7, 8, -20, -13, 36, 9, -24, -11, -10,
+ 10, 20, -1, -13, -10, -9, 20, 17, -12, -9, -15, 9, 20, -11, -14, -6,
+ 5, 10, 6, 5, -7, -11, 7, 19, 1, 3, -11, -10, 24, 14, -16, 2,
+ -9, 11, 14, 7, -1, -11, -4, 15, 24, 3, -24, -4, 4, 15, 13, -3,
+ -15, 0, 15, 8, 2, 0, -19, 16, 12, -1, 7, -13, -2, 18, 3, -3,
+ 5, -9, -10, 12, 9, -2, 8, -9, 4, 9, 6, 1, -8, 10, 4, -2,
+ 11, -14, 3, 5, 1, 9, 4, -15, 0, 10, 1, 5, -4, -10, 3, 7,
+ -1, 8, -13, 1, 4, 10, 6, -9, -3, 1, 6, 14, -3, -4, 4, -10,
+ 10, 13, -1, -4, 5, -3, 10, 13, -13, 4, 7, 1, 8, -1, 1, 4,
+ 5, 4, 11, -5, -2, 1, 8, 6, 1, 3, -1, -5, 11, 3, -3, 4,
+ -5, -1, 17, -4, -2, 6, -10, 10, 10, -4, 2, 3, -10, 10, 5, -2,
+ -2, -1, 4, 3, -1, -2, -4, 1, 6, -4, 6, -4, -10, 8, 2, -4,
+ 6, -4, -4, 12, -2, 2, 6, -9, 3, 2, 0, 7, -5, -3, 3, 2,
+ 4, -4, -2, 7, 3, 5, 9, -3, 1, 12, -3, 7, 6, -9, 4, 9,
+ -4, 12, 1, -7, 9, 2, 1, 10, -3, 1, 0, 0, 8, 0, -1, 5,
+ -2, 8, 1, -3, 10, 2, 0, 11, -4, -1, 6, -3, 2, 3, -5, 4,
+ 0, -5, 5, -3, 1, 3, 0, 4, -3, -3, 4, -2, -2, 5, -2, -1,
+ 6, -5, 2, 3, -4, 4, -2, -3, 11, -8, 0, 5, -1, 1, 0, -3,
+ 4, 2, 2, 6, -2, 4, 5, -3, 4, 7, -4, 11, -1, 0, 3, 0,
+ 3, 7, -2, 5, 1, 0, 6, 3, 2, 4, -1, 2, 6, 0, 3, 5,
+ -4, 6, 0, 2, 7, -4, -1, 2, -2, 7, 1, -1, 1, -2, 2, 4,
+ -5, 0, 4, -1, 2, -1, -2, 1, -2, 3, 2, -3, 3, -1, -4, 5,
+ -2, -2, 3, 0, -1, 2, -5, 2, 1, -4, 0, 1, -3, 5, -2, 2,
+ 2, -3, 1, 3, -2, 3, 1, -2, 4, 1, 2, 5, -2, 3, 1, 2,
+ 5, 0, -1, 4, 0, 1, 4, 2, 4, 4, -2, 0, 2, 3, 5, 0,
+ 0, 0, 1, 5, -2, -3, 4, 0, 1, 2, -2, -4, -4, -5, -6, -7,
+ -8, -9, -10, -11, -12, -13, -13, -14, -16, -18, -21, -25, -29, -34, -36, -38,
+ -39, -40, -42, -44, -47, -50, -53, -56, -58, -59, -58, -55, -50, -44, -38, -31,
+ -24, -18, -13, -9, -6, -3, 0, 3, 6, 9, 13, 17, 21, 27, 33, 42,
+ 53, 63, 74, 83, 91, 98, 104, 108, 111, 113, 115, 118, 119, 121, 123, 125,
+ 126, 127, 127, 127, 127, 126, 126, 126, 126, 127, 127, 127, 127, 127, 127, 127,
+ 126, 125, 123, 121, 118, 114, 111, 107, 104, 101, 100, 99, 98, 98, 98, 98,
+ 98, 99, 98, 98, 97, 95, 92, 88, 81, 73, 63, 54, 46, 39, 33, 29,
+ 27, 25, 24, 22, 20, 18, 14, 10, 5, 0, -5, -8, -8, -7, -3, 2,
+ 8, 14, 19, 23, 26, 28, 29, 30, 31, 32, 32, 31, 30, 28, 24, 20,
+ 14, 9, 4, -1, -4, -7, -9, -10, -12, -13, -15, -17, -19, -22, -24, -25,
+ -25, -23, -21, -19, -17, -15, -15, -14, -15, -15, -16, -17, -17, -17, -16, -16,
+ -16, -17, -19, -22, -25, -30, -35, -39, -44, -47, -50, -53, -56, -58, -61, -63,
+ -64, -65, -65, -63, -60, -55, -49, -43, -38, -34, -32, -31, -31, -32, -33, -35,
+ -36, -37, -37, -36, -35, -34, -34, -34, -36, -39, -43, -49, -55, -61, -67, -72,
+ -77, -81, -85, -88, -90, -92, -94, -94, -95, -94, -94, -94, -94, -95, -96, -98,
+ -100, -102, -104, -105, -107, -108, -108, -109, -110, -110, -110, -109, -109, -109, -108, -108,
+ -109, -109, -109, -109, -108, -108, -107, -106, -106, -105, -105, -105, -105, -105, -105, -104,
+ -103, -101, -98, -93, -88, -82, -76, -70, -64, -58, -52, -47, -42, -38, -34, -31,
+ -29, -27, -25, -22, -18, -13, -7, -1, 6, 13, 20, 26, 32, 37, 41, 45,
+ 48, 51, 55, 58, 63, 68, 73, 77, 82, 85, 89, 91, 94, 96, 97, 98,
+ 99, 99, 99, 100, 100, 100, 101, 101, 101, 101, 101, 101, 99, 97, 95, 93,
+ 90, 87, 84, 81, 77, 73, 67, 60, 51, 40, 29, 17, 6, -5, -14, -23,
+ -31, -38, -45, -52, -58, -65, -70, -75, -80, -84, -87, -90, -92, -94, -95, -96,
+ -97, -98, -100, -101, -102, -102, -103, -103, -104, -104, -103, -102, -100, -97, -93, -89,
+ -86, -82, -79, -77, -75, -72, -70, -67, -63, -59, -53, -47, -40, -33, -26, -20,
+ -14, -9, -6, -3, 0, 3, 6, 9, 13, 17, 21, 26, 31, 37, 44, 51,
+ 58, 64, 70, 75, 79, 83, 86, 88, 90, 92, 93, 95, 96, 97, 98, 100,
+ 100, 101, 102, 102, 102, 102, 102, 102, 102, 102, 102, 103, 103, 103, 102, 102,
+ 102, 101, 100, 98, 96, 94, 92, 90, 89, 88, 88, 87, 87, 87, 87, 87,
+ 86, 85, 84, 82, 79, 76, 72, 67, 61, 55, 49, 43, 39, 35, 32, 30,
+ 29, 27, 25, 24, 21, 18, 15, 12, 8, 5, 3, 3, 4, 6, 9, 12,
+ 15, 18, 21, 23, 25, 27, 28, 30, 31, 31, 31, 30, 28, 25, 22, 18,
+ 14, 10, 7, 5, 3, 1, 0, -2, -4, -6, -9, -11, -14, -16, -17, -17,
+ -16, -14, -12, -11, -9, -9, -9, -10, -11, -12, -13, -14, -15, -15, -16, -16,
+ -17, -19, -22, -26, -30, -34, -38, -42, -45, -48, -50, -52, -53, -54, -55, -56,
+ -56, -55, -53, -50, -46, -42, -38, -35, -32, -31, -30, -31, -31, -33, -34, -35,
+ -36, -36, -36, -35, -35, -35, -36, -38, -41, -45, -49, -54, -59, -64, -68, -73,
+ -76, -80, -83, -86, -88, -89, -90, -91, -91, -91, -92, -92, -93, -95, -96, -98,
+ -100, -101, -102, -103, -104, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105,
+ -105, -105, -104, -104, -103, -102, -102, -101, -100, -100, -100, -99, -99, -99, -98, -96,
+ -94, -91, -86, -82, -76, -71, -65, -59, -53, -48, -42, -37, -32, -28, -25, -22,
+ -19, -16, -13, -8, -3, 3, 9, 16, 22, 28, 35, 40, 45, 49, 53, 56,
+ 60, 63, 67, 71, 76, 80, 85, 88, 92, 94, 97, 99, 100, 102, 103, 103,
+ 104, 104, 104, 104, 105, 105, 105, 105, 105, 104, 103, 101, 99, 97, 94, 91,
+ 87, 84, 80, 76, 71, 65, 57, 48, 39, 28, 18, 8, -2, -11, -19, -27,
+ -34, -41, -47, -54, -60, -65, -70, -75, -79, -82, -85, -87, -89, -91, -92, -94,
+ -95, -96, -97, -98, -99, -100, -100, -100, -100, -100, -98, -96, -94, -90, -87, -84,
+ -81, -78, -76, -73, -71, -68, -65, -61, -57, -52, -46, -40, -33, -27, -21, -15,
+ -11, -7, -4, 0, 3, 7, 11, 15, 20, 24, 29, 35, 41, 48, 54, 61,
+ 67, 72, 77, 81, 85, 88, 90, 92, 94, 95, 97, 98, 99, 101, 102, 103,
+ 104, 104, 104, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 104,
+ 104, 103, 101, 99, 98, 96, 95, 93, 93, 92, 92, 91, 91, 90, 90, 88,
+ 87, 86, 84, 81, 78, 74, 69, 64, 59, 54, 49, 45, 42, 39, 37, 35,
+ 33, 31, 29, 27, 24, 21, 18, 15, 13, 11, 11, 12, 13, 15, 17, 20,
+ 22, 24, 25, 27, 28, 29, 30, 31, 31, 31, 30, 28, 26, 23, 20, 17,
+ 14, 11, 9, 8, 6, 5, 3, 1, -1, -4, -6, -8, -10, -11, -11, -11,
+ -10, -9, -8, -8, -8, -9, -10, -11, -13, -14, -15, -16, -17, -17, -18, -20,
+ -22, -25, -28, -31, -35, -38, -41, -44, -46, -47, -49, -50, -51, -52, -52, -52,
+ -51, -49, -47, -44, -40, -38, -35, -33, -33, -32, -33, -33, -34, -35, -36, -37,
+ -38, -38, -38, -38, -39, -40, -42, -45, -49, -53, -57, -61, -65, -69, -73, -76,
+ -79, -82, -85, -87, -88, -89, -90, -91, -91, -92, -93, -94, -95, -97, -98, -99,
+ -100, -101, -102, -103, -103, -104, -104, -104, -104, -104, -104, -104, -104, -104, -103, -103,
+ -103, -102, -102, -101, -100, -99, -99, -98, -97, -97, -96, -96, -95, -94, -92, -89,
+ -86, -82, -77, -72, -67, -61, -56, -50, -45, -39, -34, -29, -25, -21, -18, -14,
+ -11, -5, 4, 8, 14, 19, 25, 31, 37, 42, 47, 52, 57, 61, 65, 69,
+ 72, 76, 79, 83, 86, 89, 92, 95, 97, 99, 101, 102, 104, 104, 105, 106,
+ 106, 106, 106, 106, 106, 105, 104, 104, 103, 101, 99, 97, 95, 92, 89, 85,
+ 81, 77, 73, 68, 62, 57, 50, 43, 35, 28, 19, 12, 4, -4, -11, -18,
+ -25, -32, -38, -44, -50, -55, -61, -65, -69, -73, -77, -80, -82, -85, -87, -89,
+ -91, -92, -93, -95, -95, -96, -97, -97, -97, -96, -96, -95, -93, -92, -90, -88,
+ -86, -84, -82, -79, -77, -74, -71, -68, -64, -60, -55, -51, -46, -41, -36, -31,
+ -26, -21, -16, -11, -7, -2, 3, 8, 14, 19, 25, 30, 36, 42, 47, 53,
+ 58, 63, 68, 72, 76, 79, 82, 85, 87, 89, 91, 93, 95, 96, 98, 99,
+ 101, 102, 103, 103, 104, 105, 105, 105, 106, 106, 106, 106, 106, 106, 106, 105,
+ 105, 105, 104, 103, 103, 102, 101, 100, 99, 99, 98, 97, 96, 95, 93, 92,
+ 91, 89, 87, 85, 82, 79, 76, 73, 70, 67, 63, 60, 58, 55, 53, 50,
+ 48, 46, 44, 41, 39, 37, 34, 32, 31, 29, 28, 28, 27, 28, 28, 28,
+ 28, 29, 29, 29, 29, 30, 30, 30, 29, 29, 28, 27, 26, 25, 23, 22,
+ 20, 19, 17, 16, 15, 13, 12, 10, 8, 6, 4, 2, 1, -1, -2, -4,
+ -5, -6, -7, -9, -10, -12, -13, -15, -17, -19, -21, -22, -24, -26, -27, -29,
+ -31, -32, -34, -36, -38, -40, -42, -43, -45, -46, -47, -47, -48, -48, -49, -49,
+ -48, -48, -47, -46, -45, -44, -44, -43, -43, -43, -44, -44, -45, -46, -47, -48,
+ -49, -50, -51, -52, -53, -55, -57, -59, -61, -64, -67, -70, -72, -75, -78, -80,
+ -82, -84, -86, -88, -90, -91, -92, -94, -95, -96, -97, -98, -98, -99, -100, -101,
+ -101, -101, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -101, -101, -100, -100,
+ -99, -98, -97, -96, -95, -94, -93, -92, -91, -89, -88, -87, -85, -83, -81, -78,
+ -75, -71, -67, -63, -58, -54, -49, -44, -39, -33, -28, -23, -18, -13, -8, -3,
+ 2, 7, 13, 18, 23, 29, 35, 40, 45, 51, 55, 60, 64, 68, 71, 75,
+ 78, 82, 85, 88, 91, 93, 96, 98, 100, 101, 103, 104, 105, 105, 106, 106,
+ 106, 106, 105, 105, 104, 104, 103, 101, 100, 98, 95, 93, 90, 86, 83, 79,
+ 75, 70, 65, 60, 54, 47, 40, 33, 25, 18, 10, 2, -5, -12, -19, -26,
+ -32, -38, -44, -50, -55, -60, -65, -69, -73, -76, -79, -82, -84, -87, -89, -90,
+ -92, -93, -94, -95, -96, -96, -96, -96, -96, -95, -94, -93, -91, -90, -88, -86,
+ -84, -81, -79, -76, -74, -70, -67, -63, -59, -54, -49, -44, -39, -34, -29, -24,
+ -19, -14, -10, -5, -2, -1, 3, -2, 1, -3, 4, -2, 0, 0, 8, 0,
+ 10, -9, -7, -128, -72, 13, -44, -13, -18, 4, -4, 12, 3, 31, 4, 66,
+ 74, 38, 38, 36, 30, 25, 22, 18, 13, 7, 5, 2, 1, -5, -7, -9,
+ -9, -11, -14, -12, -14, -12, -16, -13, -16, -13, -14, -16, -11, -14, -10, -13,
+ -11, -13, -8, -8, -6, -6, -5, 0, -6, -3, -3, 3, -4, 6, -13, 17,
+ -5, -5, 15, -1, -23, 6, 23, 28, 35, 13, 41, -3, 24, 25, -4, 6,
+ 30, 4, 18, 10, -32, -64, -120, -64, -91, -76, -33, -45, -58, 2, 1, -19,
+ -14, 18, 48, 50, 59, 51, 53, 47, 46, 41, 37, 35, 26, 28, 19, 21,
+ 10, 13, 9, 3, 5, -4, 2, -5, -3, -8, -5, -8, -8, -10, -9, -10,
+ -10, -12, -7, -17, -8, -11, -14, -5, -15, -5, -4, -10, -13, 11, -22, 3,
+ -3, -4, -5, -11, 13, 2, -16, -9, -5, -12, 27, 15, 17, 21, 20, 20,
+ 8, 14, 13, 0, 10, 35, 10, -1, -12, -52, -89, -78, -58, -85, -74, -51,
+ -25, -25, -28, -30, -14, 12, 29, 44, 44, 51, 46, 50, 49, 43, 38, 36,
+ 32, 29, 23, 19, 17, 14, 10, 6, 6, 2, 4, -8, 3, -7, -3, -6,
+ -7, -11, -4, -12, -7, -6, -20, 1, -15, -14, -8, -7, -10, -10, -10, 2,
+ -14, -12, 7, -10, -8, -5, -6, 1, 6, -2, -12, -19, -3, 3, 2, 19,
+ 19, 14, 19, 24, 13, 5, 12, 12, 13, 21, 29, 5, -18, -43, -48, -64,
+ -82, -82, -71, -44, -37, -37, -40, -33, -23, 5, 20, 33, 38, 45, 48, 51,
+ 46, 44, 41, 38, 36, 27, 26, 24, 19, 13, 16, 5, 11, 4, -1, 3,
+ -4, -3, 1, -9, -7, -2, -9, -6, -13, -4, -6, -17, -8, -6, -15, -10,
+ -5, -10, -8, -10, -5, -7, -5, -2, -14, -10, 3, 5, -4, -3, -10, -17,
+ -10, 3, 4, 5, 18, 18, 18, 16, 16, 10, 5, 11, 23, 26, 22, 7,
+ -9, -16, -37, -62, -80, -76, -65, -46, -43, -43, -51, -41, -24, -4, 11, 24,
+ 32, 41, 47, 43, 49, 45, 41, 40, 33, 31, 31, 20, 23, 18, 11, 16,
+ 9, 5, 3, 2, 5, -2, -7, 2, -4, -10, -3, -5, -8, -10, -7, -8,
+ -14, -10, -8, -11, -9, -6, -14, -10, -2, -3, -12, -10, -7, -9, 0, 6,
+ -1, -11, -12, -11, -10, -7, 4, 7, 12, 17, 20, 18, 13, 6, 8, 19,
+ 22, 24, 17, 14, 5, -8, -29, -54, -77, -71, -55, -50, -44, -54, -57, -39,
+ -32, -15, 3, 15, 31, 34, 39, 47, 45, 44, 44, 37, 37, 33, 28, 27,
+ 18, 20, 21, 10, 7, 10, 7, 1, 2, 2, 0, -5, 0, -2, -7, -3,
+ -5, -8, -8, -5, -13, -13, -5, -6, -14, -11, -8, -8, -5, -5, -9, -17,
+ -10, -2, 0, -2, -1, -9, -12, -14, -12, -6, -1, 3, 11, 19, 19, 14,
+ 7, 9, 13, 17, 23, 22, 19, 21, 12, 2, -21, -55, -65, -59, -52, -47,
+ -56, -56, -50, -53, -38, -22, -7, 10, 18, 29, 36, 40, 45, 43, 38, 41,
+ 40, 32, 27, 26, 26, 19, 17, 17, 12, 9, 9, 6, 2, 4, 4, -1,
+ -2, 2, -3, -3, 0, -2, -8, -9, -7, -7, -7, -6, -8, -12, -6, -4,
+ -7, -12, -13, -10, -5, -2, -2, -3, -8, -12, -15, -16, -14, -13, -7, 2,
+ 8, 11, 8, 4, 5, 8, 13, 20, 22, 23, 24, 23, 19, 6, -13, -23,
+ -29, -32, -37, -42, -46, -53, -57, -53, -49, -39, -25, -12, -1, 10, 21, 28,
+ 32, 35, 36, 34, 34, 32, 28, 25, 24, 21, 18, 19, 16, 10, 7, 8,
+ 9, 8, 6, 5, 2, 3, 6, 7, 5, 2, -2, -4, -3, -1, -3, -4,
+ -3, -1, -3, -8, -13, -14, -11, -4, -1, -2, -4, -6, -11, -16, -19, -21,
+ -21, -17, -9, -3, 0, 0, -3, -5, -2, 4, 11, 18, 23, 25, 26, 24,
+ 17, 10, 5, -1, -7, -12, -20, -29, -37, -44, -51, -55, -54, -47, -39, -28,
+ -16, -4, 9, 18, 23, 27, 31, 31, 30, 30, 28, 23, 20, 22, 23, 20,
+ 14, 10, 9, 9, 10, 9, 6, 4, 4, 6, 9, 10, 7, 2, 0, 1,
+ -1, -2, -2, -1, 1, 2, -2, -10, -14, -11, -8, -5, -2, -1, -3, -6,
+ -9, -14, -20, -23, -23, -18, -11, -5, -3, -4, -6, -8, -4, 2, 7, 14,
+ 21, 25, 25, 23, 19, 13, 8, 4, -1, -9, -15, -23, -31, -39, -48, -53,
+ -51, -48, -44, -34, -20, -8, 3, 12, 20, 24, 27, 30, 31, 29, 24, 22,
+ 22, 23, 22, 18, 13, 10, 10, 11, 11, 9, 5, 3, 5, 10, 11, 9,
+ 7, 5, 4, 2, 0, -3, -1, 3, 5, 2, -3, -8, -11, -10, -7, -5,
+ -3, -2, -2, -4, -7, -14, -20, -24, -24, -19, -12, -6, -6, -8, -8, -8,
+ -7, -2, 5, 12, 19, 23, 24, 22, 20, 16, 12, 7, 1, -5, -10, -17,
+ -27, -36, -42, -47, -52, -51, -45, -36, -26, -12, 0, 9, 15, 21, 27, 30,
+ 29, 26, 23, 22, 23, 23, 21, 17, 12, 9, 10, 12, 10, 6, 3, 4,
+ 7, 10, 11, 9, 8, 9, 7, 2, -1, 0, 2, 6, 6, 3, -2, -7,
+ -9, -8, -6, -4, -3, -1, -1, -2, -6, -13, -21, -26, -24, -18, -13, -10,
+ -9, -10, -11, -11, -10, -5, 3, 10, 17, 21, 22, 22, 21, 19, 14, 8,
+ 5, 1, -7, -14, -21, -29, -38, -45, -49, -50, -48, -40, -28, -16, -6, 3,
+ 11, 19, 26, 27, 26, 24, 22, 22, 24, 24, 20, 14, 11, 11, 12, 11,
+ 8, 4, 3, 6, 8, 9, 9, 10, 11, 10, 6, 2, 0, 2, 5, 8,
+ 7, 3, -2, -5, -6, -7, -6, -4, -3, -1, 1, 1, -5, -13, -21, -24,
+ -23, -18, -14, -12, -11, -12, -13, -14, -13, -8, 0, 8, 14, 17, 21, 22,
+ 21, 18, 15, 12, 8, 2, -3, -9, -16, -24, -32, -40, -47, -51, -49, -41,
+ -30, -21, -12, -1, 9, 17, 23, 25, 24, 21, 21, 24, 24, 22, 17, 12,
+ 11, 13, 12, 8, 4, 3, 4, 6, 7, 7, 9, 11, 12, 10, 6, 3,
+ 3, 6, 9, 10, 8, 5, 1, -2, -3, -3, -2, -1, 1, 3, 3, 1,
+ -5, -12, -18, -20, -20, -18, -16, -16, -16, -17, -19, -20, -17, -11, -5, 1,
+ 8, 13, 17, 18, 18, 17, 16, 14, 11, 7, 2, -3, -8, -14, -22, -34,
+ -43, -46, -42, -35, -28, -20, -11, -2, 7, 15, 19, 19, 19, 19, 20, 20,
+ 17, 14, 11, 10, 9, 7, 1, -4, -6, -4, 0, 2, 4, 6, 7, 8,
+ 9, 8, 7, 7, 10, 13, 15, 15, 13, 9, 6, 3, 2, 4, 7, 9,
+ 11, 11, 7, 1, -5, -10, -13, -14, -14, -14, -16, -19, -23, -26, -28, -27,
+ -23, -18, -13, -7, -1, 6, 11, 14, 15, 14, 14, 15, 15, 12, 7, 2,
+ -1, -4, -11, -22, -34, -41, -40, -34, -26, -19, -12, -4, 4, 10, 14, 17,
+ 17, 18, 19, 18, 15, 12, 10, 9, 8, 6, 0, -6, -11, -10, -6, -1,
+ 3, 5, 6, 6, 6, 7, 7, 8, 10, 13, 16, 18, 17, 13, 9, 5,
+ 3, 4, 7, 11, 13, 14, 11, 5, -2, -7, -11, -12, -12, -13, -14, -17,
+ -22, -26, -28, -29, -27, -22, -17, -11, -5, 1, 7, 12, 14, 14, 13, 14,
+ 15, 14, 11, 5, 0, -2, -6, -15, -27, -37, -42, -38, -31, -24, -17, -9,
+ -1, 6, 12, 15, 17, 18, 19, 19, 17, 13, 11, 9, 9, 8, 4, -2,
+ -8, -11, -9, -4, 1, 4, 5, 6, 6, 6, 7, 7, 9, 11, 14, 17,
+ 18, 16, 12, 8, 4, 3, 5, 9, 12, 14, 13, 9, 2, -4, -9, -12,
+ -13, -12, -13, -15, -19, -23, -27, -29, -28, -25, -20, -15, -9, -3, 3, 9,
+ 13, 15, 14, 13, 15, 15, 13, 9, 3, -1, -3, -9, -19, -31, -40, -41,
+ -36, -28, -21, -14, -6, 2, 9, 13, 16, 17, 18, 19, 18, 16, 12, 10,
+ 9, 9, 7, 2, -4, -10, -11, -8, -2, 2, 5, 5, 6, 6, 7, 7,
+ 8, 9, 12, 16, 18, 17, 14, 10, 6, 4, 4, 6, 10, 13, 14, 12,
+ 7, 0, -6, -10, -12, -13, -13, -14, -16, -21, -25, -28, -29, -28, -24, -18,
+ -13, -7, -1, 6, 11, 14, 15, 13, 14, 15, 15, 12, 7, 2, -1, -5,
+ -12, -23, -35, -41, -40, -34, -26, -19, -12, -3, 4, 10, 14, 17, 18, 18,
+ 19, 18, 14, 11, 9, 9, 8, 6, 0, -7, -11, -10, -6, 0, 2, -1,
+ -2, -9, -24, 4, -3, 3, -3, 10, 7, 4, 13, -4, 1, 3, 3, 0,
+ 2, 8, -9, -9, 2, 1, -1, 7, 17, 21, 37, 25, 13, 14, -2, 15,
+ 20, 5, 0, -3, -7, -27, -14, -18, -19, -29, -20, -4, -18, -32, -30, -30,
+ -29, -32, -22, -26, -19, -19, -1, -6, 4, 7, 5, 2, 0, -8, -16, -12,
+ -13, -17, -17, 19, 20, 24, 16, 8, -4, 8, 0, 13, 28, 33, 16, 11,
+ 5, -3, -1, 4, 12, 12, 40, 20, 11, 4, 5, 8, -1, 2, 5, 5,
+ 22, 13, 21, 8, 9, 18, 20, 13, 20, 26, 11, 24, 17, 10, 27, 30,
+ 22, 28, 30, 41, 47, 57, 36, 36, 20, -16, 4, 6, -19, -21, -41, -39,
+ -33, -38, -41, -46, -42, -36, -18, -37, -65, -75, -77, -78, -62, -63, -62, -68,
+ -63, -63, -44, -50, -30, -41, -43, -26, -34, -35, -36, -45, -49, -27, 1, -6,
+ -4, -7, -20, -16, -20, -21, -13, 2, -6, -1, -12, 0, -1, 15, 19, 20,
+ 26, 37, 40, 46, 37, 50, 35, 34, 41, 43, 51, 54, 55, 50, 56, 47,
+ 59, 51, 51, 75, 67, 66, 71, 59, 60, 72, 75, 72, 80, 79, 82, 98,
+ 99, 87, 93, 62, 49, 58, 41, 42, 28, 5, -6, -6, -18, -24, -23, -30,
+ -25, -20, -38, -60, -75, -77, -80, -75, -71, -75, -70, -73, -69, -76, -60, -66,
+ -71, -66, -57, -62, -61, -61, -87, -90, -69, -63, -46, -31, -35, -47, -42, -53,
+ -63, -53, -45, -33, -36, -39, -37, -43, -39, -34, -30, -19, -9, 2, -9, -1,
+ -3, 1, -3, 5, 7, 15, 24, 22, 23, 20, 32, 43, 33, 48, 63, 67,
+ 70, 68, 52, 59, 73, 73, 77, 85, 73, 81, 103, 98, 116, 115, 87, 80,
+ 76, 72, 69, 60, 37, 27, 29, 12, 19, 4, -12, 1, 3, -3, -31, -42,
+ -57, -67, -67, -61, -61, -61, -48, -58, -51, -41, -46, -48, -40, -35, -33, -26,
+ -36, -67, -68, -65, -59, -47, -28, -34, -37, -36, -52, -61, -61, -47, -34, -39,
+ -39, -42, -42, -48, -36, -38, -37, -20, -19, -16, -16, -18, -20, -22, -26, -22,
+ -16, -15, 1, -4, -6, 10, 12, 13, 22, 32, 41, 54, 52, 44, 54, 66,
+ 61, 78, 81, 71, 87, 89, 99, 119, 107, 91, 77, 76, 69, 76, 68, 47,
+ 49, 35, 33, 37, 22, 14, 24, 37, 26, 13, -10, -26, -41, -43, -34, -40,
+ -34, -33, -43, -39, -25, -27, -27, -18, -25, -15, -1, -10, -29, -42, -39, -39,
+ -19, -7, -10, -10, -11, -20, -35, -44, -33, -30, -28, -36, -34, -47, -41, -36,
+ -46, -42, -34, -27, -29, -25, -34, -30, -32, -40, -36, -36, -31, -16, -25, -25,
+ -15, -21, -14, -9, -11, 1, 17, 15, 9, 25, 20, 25, 46, 39, 46, 50,
+ 51, 68, 85, 87, 72, 65, 52, 50, 59, 44, 42, 29, 23, 22, 23, 11,
+ -5, 8, 14, 19, 8, -6, -23, -38, -43, -42, -48, -41, -34, -42, -38, -19,
+ -23, -16, -15, -19, -10, 8, 8, -9, -18, -27, -30, -10, -4, 7, 6, 15,
+ 8, -8, -17, -15, -8, -11, -3, -15, -17, -14, -16, -27, -30, -26, -22, -19,
+ -21, -22, -19, -30, -27, -26, -36, -22, -9, -13, -10, -10, -8, -9, -6, -12,
+ -1, 16, 6, 11, 16, 6, 19, 24, 27, 38, 38, 38, 48, 71, 72, 78,
+ 66, 51, 54, 52, 49, 42, 32, 21, 25, 26, 13, 1, -1, 10, 15, 8,
+ 1, -22, -38, -47, -56, -58, -46, -43, -46, -33, -25, -17, -11, -9, -19, -9,
+ 16, 18, 12, 1, -17, -18, -9, 3, 9, 17, 24, 26, 9, -4, -1, -6,
+ 2, 9, 0, -2, 2, -3, -13, -16, -15, -8, -8, -8, -1, -6, -17, -11,
+ -22, -24, -16, -12, -9, -9, -9, -9, -6, -8, -16, 2, 6, 2, 13, 9,
+ 7, 10, 17, 19, 30, 31, 22, 37, 49, 61, 70, 56, 43, 37, 36, 31,
+ 32, 15, 4, 11, 9, 4, -14, -16, -7, -5, -1, -8, -28, -46, -56, -75,
+ -74, -67, -70, -67, -62, -55, -47, -36, -32, -42, -28, -9, 1, 4, -4, -17,
+ -30, -18, -12, -2, 4, 15, 21, 7, 1, -7, -6, -1, 7, 0, 0, 3,
+ -3, -8, -15, -18, -6, -9, -6, 5, -2, -2, 0, -7, -12, -7, -3, 2,
+ 7, 3, 4, 14, 2, 1, 12, 11, 17, 20, 19, 16, 19, 20, 24, 39,
+ 36, 37, 42, 55, 71, 84, 76, 63, 56, 47, 49, 46, 29, 18, 14, 18,
+ 11, -5, -11, -8, -3, 4, 4, -16, -27, -44, -60, -64, -59, -62, -62, -55,
+ -55, -47, -28, -32, -35, -29, -15, -3, 4, 3, -15, -25, -24, -13, -11, -3,
+ 10, 14, 12, 4, -5, -9, -1, 2, -1, 1, 1, -1, -7, -17, -16, -12,
+ -17, -8, 0, -1, -1, -2, -8, -13, -9, -9, 0, 9, 1, 14, 16, 6,
+ 7, 10, 12, 18, 26, 20, 22, 22, 16, 25, 32, 36, 34, 36, 43, 60,
+ 75, 72, 67, 52, 44, 50, 45, 38, 17, 14, 17, 11, -2, -9, -14, -10,
+ 0, -4, -12, -24, -41, -59, -67, -63, -70, -69, -62, -70, -55, -40, -38, -42,
+ -38, -29, -16, -3, -3, -9, -29, -31, -25, -26, -20, -7, 0, 2, -1, -14,
+ -18, -14, -14, -12, -10, -10, -4, -13, -21, -19, -22, -24, -16, -10, -6, -2,
+ -2, -10, -12, -15, -17, -4, -4, -5, 7, 9, 3, 4, 7, 5, 18, 23,
+ 22, 28, 25, 22, 27, 34, 39, 43, 38, 41, 62, 71, 79, 78, 62, 55,
+ 55, 57, 49, 31, 23, 30, 21, 15, 7, -5, 1, 8, 9, 8, -3, -16,
+ -39, -46, -50, -60, -55, -58, -62, -53, -36, -33, -34, -34, -29, -18, -6, 5,
+ -2, -17, -23, -22, -24, -17, -8, 1, 9, 10, -4, -7, -8, -9, -6, -9,
+ -6, 0, -11, -14, -14, -21, -24, -21, -16, -10, 1, -3, -3, -5, -14, -11,
+ -7, -7, -5, 6, 9, 4, 8, 1, 3, 11, 16, 20, 26, 24, 20, 25,
+ 29, 36, 41, 32, 40, 51, 64, 77, 78, 67, 55, 54, 57, 53, 33, 27,
+ 25, 22, 20, 9, -3, -3, 3, 7, 6, 4, -16, -32, -42, -55, -60, -61,
+ -64, -70, -62, -49, -39, -41, -40, -37, -33, -18, -5, -8, -16, -24, -29, -31,
+ -28, -24, -15, -1, 1, -7, -11, -14, -13, -14, -18, -11, -8, -14, -16, -16,
+ -25, -31, -29, -31, -20, -12, -13, -6, -11, -19, -19, -14, -17, -12, -1, 2,
+ 6, 7, 2, 4, 8, 11, 18, 24, 21, 22, 19, 21, 33, 33, 32, 32,
+ 40, 55, 71, 76, 72, 58, 55, 62, 56, 42, 34, 28, 29, 26, 17, 4,
+ 2, 6, 4, 13, 12, -4, -18, -30, -45, -50, -51, -59, -63, -61, -47, -37,
+ -33, -32, -34, -32, -19, -4, -3, -5, -13, -21, -23, -22, -24, -13, 1, 5,
+ 5, -3, -6, -1, -7, -9, -2, 1, -2, -2, -4, -13, -16, -22, -22, -15,
+ -10, -4, 2, -1, -11, -8, -7, -12, -6, 1, 6, 12, 11, 8, 9, 9,
+ 9, 20, 23, 26, 25, 20, 24, 32, 34, 35, 33, 35, 49, 63, 74, 74,
+ 58, 55, 60, 54, 45, 33, 27, 25, 26, 19, 6, 4, 1, 1, 9, 12,
+ -1, -10, -26, -43, -50, -54, -61, -70, -69, -61, -50, -43, -40, -44, -44, -34,
+ -18, -12, -9, -15, -24, -25, -28, -31, -22, -12, -2, 1, -8, -8, -5, -12,
+ -14, -8, -8, -8, -5, -9, -11, -18, -27, -26, -22, -19, -12, -1, -4, -9,
+ -8, -11, -14, -12, -8, 0, 7, 5, 5, 6, 0, 3, 8, 13, 20, 18,
+ 13, 15, 22, 27, 29, 25, 26, 36, 51, 70, 71, 59, 56, 57, 55, 47,
+ 37, 25, 24, 27, 17, 9, 3, -2, -2, 8, 9, 6, -2, -16, -34, -44,
+ -47, -54, -63, -66, -63, -55, -44, -39, -42, -44, -35, -23, -11, -4, -10, -16,
+ -17, -23, -25, -22, -13, 1, 6, 1, 1, 4, -2, -4, 1, -1, 4, 3,
+ 2, 2, -3, -12, -15, -14, -15, -7, 3, 5, 3, 2, 1, -2, -4, -4,
+ 3, 9, 10, 13, 11, 9, 8, 9, 15, 22, 22, 20, 19, 21, 27, 30,
+ 28, 28, 28, 42, 61, 69, 65, 60, 60, 58, 55, 47, 35, 30, 30, 24,
+ 18, 10, 0, -1, 2, 6, 7, 3, -8, -24, -36, -43, -50, -59, -65, -66,
+ -62, -52, -43, -43, -44, -41, -35, -21, -12, -12, -13, -17, -23, -26, -30, -24,
+ -12, -4, -5, -3, -2, -5, -6, -6, -5, -3, -2, -1, 2, 2, -5, -3,
+ 2, 8, 17, 26, 32, 42, 50, 56, 68, 73, 64, 63, 65, 48, 56, 71,
+ 48, 49, 50, 26, 30, 30, 16, 25, 21, -2, 0, -13, -15, -2, -19, -17,
+ -16, -50, -49, -49, -81, -85, -88, -108, -112, -116, -127, -126, -113, -113, -106, -79,
+ -65, -48, -17, 5, 20, 41, 58, 63, 69, 59, 28, 17, 0, -32, -41, -52,
+ -69, -63, -61, -59, -41, -26, -19, 6, 28, 33, 52, 67, 70, 81, 87, 84,
+ 90, 93, 84, 72, 69, 60, 45, 56, 57, 40, 46, 39, 25, 29, 25, 16,
+ 21, 12, -1, -3, -11, -8, -5, -16, -12, -21, -41, -38, -48, -68, -70, -77,
+ -91, -93, -98, -106, -103, -93, -92, -82, -60, -47, -30, -4, 13, 27, 44, 56,
+ 60, 62, 47, 23, 13, -8, -32, -40, -54, -64, -59, -59, -53, -36, -26, -14,
+ 12, 27, 36, 56, 66, 72, 84, 86, 86, 93, 92, 82, 73, 70, 57, 49,
+ 59, 52, 43, 47, 37, 29, 30, 24, 18, 18, 7, -2, -6, -11, -7, -10,
+ -16, -14, -29, -42, -42, -57, -71, -73, -83, -93, -96, -102, -107, -101, -93, -90,
+ -75, -55, -41, -22, 3, 19, 33, 50, 59, 61, 60, 41, 21, 10, -14, -33,
+ -43, -57, -63, -60, -61, -51, -36, -27, -9, 15, 26, 40, 59, 66, 74, 85,
+ 85, 88, 94, 90, 80, 75, 69, 56, 54, 60, 50, 47, 46, 36, 31, 30,
+ 23, 19, 15, 4, -3, -7, -10, -9, -14, -17, -19, -35, -44, -47, -63, -73,
+ -77, -88, -96, -98, -104, -107, -99, -92, -86, -69, -50, -35, -14, 9, 24, 38,
+ 54, 60, 61, 56, 36, 19, 4, -20, -35, -46, -60, -62, -61, -60, -48, -35,
+ -25, -3, 17, 27, 45, 60, 66, 77, 85, 86, 91, 94, 88, 80, 75, 67,
+ 56, 58, 59, 50, 49, 45, 36, 33, 30, 23, 19, 13, 2, -5, -8, -10,
+ -11, -16, -18, -25, -40, -45, -53, -68, -76, -81, -91, -97, -100, -106, -106, -97,
+ -90, -81, -63, -44, -28, -6, 15, 28, 44, 57, 61, 61, 52, 31, 16, -1,
+ -24, -37, -50, -61, -62, -62, -59, -46, -35, -22, 1, 18, 30, 48, 61, 68,
+ 79, 85, 87, 92, 93, 86, 80, 75, 66, 58, 60, 58, 51, 50, 44, 37,
+ 33, 29, 23, 17, 10, 0, -6, -9, -10, -14, -18, -21, -31, -43, -48, -59,
+ -72, -78, -85, -94, -99, -102, -107, -104, -95, -88, -76, -56, -39, -22, 2, 20,
+ 33, 49, 59, 61, 60, 47, 27, 12, -7, -27, -40, -53, -62, -62, -63, -57,
+ -44, -34, -18, 5, 19, 33, 51, 61, 70, 81, 85, 88, 94, 92, 85, 80,
+ 74, 65, 60, 62, 57, 52, 50, 43, 37, 33, 28, 22, 15, 8, -2, -7,
+ -10, -12, -16, -20, -24, -36, -46, -52, -64, -75, -81, -89, -97, -100, -104, -107,
+ -102, -93, -85, -70, -50, -33, -14, 8, 25, 38, 53, 61, 61, 58, 42, 24,
+ 8, -12, -30, -43, -56, -62, -63, -63, -54, -43, -32, -13, 7, 20, 37, 53,
+ 62, 72, 82, 85, 89, 94, 90, 84, 80, 73, 64, 62, 62, 56, 53, 49,
+ 43, 37, 33, 27, 20, 14, 5, -3, -8, -11, -13, -18, -22, -28, -40, -49,
+ -57, -69, -78, -84, -92, -99, -102, -105, -106, -99, -90, -81, -64, -44, -27, -7,
+ 14, 29, 43, 56, 61, 61, 54, 37, 20, 4, -17, -33, -46, -58, -62, -64,
+ -62, -52, -42, -29, -9, 9, 23, 40, 55, 64, 74, 83, 86, 91, 93, 89,
+ 84, 80, 72, 65, 64, 62, 56, 53, 49, 42, 37, 33, 26, 19, 12, 3,
+ -5, -8, -12, -16, -20, -24, -33, -44, -52, -61, -73, -80, -87, -95, -100, -103,
+ -106, -104, -96, -88, -76, -57, -38, -21, 0, 20, 33, 47, 59, 62, 60, 51,
+ 33, 17, -1, -21, -36, -49, -59, -63, -64, -61, -51, -40, -25, -5, 11, 26,
+ 43, 56, 65, 76, 83, 87, 92, 93, 88, 84, 79, 71, 65, 65, 61, 56,
+ 53, 48, 42, 37, 32, 25, 17, 10, 1, -6, -10, -13, -18, -22, -27, -37,
+ -48, -55, -65, -76, -83, -90, -97, -101, -104, -106, -102, -94, -84, -71, -51, -33,
+ -15, 7, 24, 38, 51, 60, 62, 59, 46, 29, 13, -6, -25, -39, -52, -60,
+ -63, -64, -59, -49, -38, -21, -1, 14, 29, 46, 57, 67, 78, 84, 88, 92,
+ 92, 87, 83, 78, 70, 66, 65, 61, 57, 53, 48, 42, 37, 31, 23, 15,
+ 7, -1, -7, -11, -15, -20, -24, -31, -41, -51, -59, -69, -79, -85, -93, -99,
+ -102, -105, -106, -100, -91, -80, -65, -45, -27, -8, 13, 29, 42, 55, 61, 61,
+ 56, 42, 25, 8, -11, -28, -42, -54, -61, -64, -64, -57, -47, -35, -17, 1,
+ 16, 33, 48, 59, 69, 79, 84, 89, 93, 91, 87, 83, 77, 70, 67, 65,
+ 60, 57, 53, 47, 41, 36, 29, 21, 14, 5, -3, -8, -12, -17, -22, -27,
+ -35, -45, -54, -63, -73, -81, -88, -95, -100, -103, -105, -104, -97, -88, -76, -58,
+ -39, -21, -1, 18, 33, 46, 58, 62, 61, 53, 38, 21, 4, -15, -31, -45,
+ -56, -62, -65, -64, -56, -46, -32, -13, 4, 19, 36, 50, 61, 71, 80, 85,
+ 90, 92, 90, 86, 82, 76, 70, 68, 65, 60, 57, 52, 46, 41, 35, 27,
+ 19, 12, 3, -5, -9, -14, -19, -24, -29, -38, -48, -57, -66, -76, -84, -91,
+ -97, -101, -104, -105, -102, -94, -84, -71, -52, -33, -15, 5, 23, 37, 50, 60,
+ 62, 60, 50, 34, 17, -1, -19, -35, -48, -58, -63, -65, -62, -54, -43, -28,
+ -10, 7, 22, 39, 52, 62, 73, 81, 86, 91, 92, 89, 86, 82, 75, 70,
+ 68, 64, 60, 57, 52, 46, 40, 34, 26, 17, 9, 1, -6, -11, -15, -21,
+ -26, -32, -42, -52, -60, -70, -79, -86, -93, -99, -102, -104, -105, -100, -91, -80,
+ -65, -46, -27, -9, 11, 28, 42, 54, 61, 62, 58, 46, 30, 13, -6, -23,
+ -38, -51, -60, -64, -65, -61, -52, -41, -25, -6, 9, 26, 42, 54, 64, 75,
+ 82, 87, 91, 91, 89, 85, 81, 74, 71, 68, 64, 60, 56, 51, 45, 39,
+ 32, 24, 16, 7, -1, -7, -12, -17, -23, -28, -36, -45, -55, -64, -73, -82,
+ -88, -95, -100, -103, -105, -104, -97, -88, -76, -59, -40, -22, -2, 17, 32, 45,
+ 57, 62, 62, 56, 42, 26, 9, -10, -27, -41, -53, -61, -65, -65, -60, -50,
+ -38, -21, -3, 12, 29, 44, 55, 66, 76, 82, 88, 91, 91, 88, 85, 80,
+ 74, 71, 68, 63, 60, 56, 50, 44, 38, 30, 22, 14, 5, -3, -9, -14,
+ -19, -25, -31, -39, -49, -58, -67, -77, -84, -91, -97, -101, -103, -105, -102, -95,
+ -84, -71, -53, -34, -16, 4, 22, 37, 49, 59, 63, 61, 53, 38, 22, 4,
+ -14, -30, -44, -56, -62, -66, -65, -58, -48, -35, -17, -1, 15, 32, 46, 57,
+ 68, 77, 83, 88, 91, 90, 88, 84, 79, 74, 71, 67, 63, 60, 55, 49,
+ 43, 37, 28, 20, 12, 3, -5, -10, -15, -21, -27, -33, -43, -52, -61, -70,
+ -79, -86, -93, -98, -102, -104, -104, -100, -92, -81, -66, -47, -28, -10, 10, 27,
+ 40, 53, 61, 63, 59, 49, 34, 18, -1, -18, -34, -47, -58, -63, -66, -64,
+ -56, -46, -31, -14, 2, 18, 35, 48, 59, 70, 78, 84, 89, 91, 90, 87,
+ 83, 78, 74, 71, 67, 63, 59, 54, 49, 42, 35, 27, 18, 9, 1, -6,
+ -12, -17, -23, -29, -36, -46, -55, -64, -73, -82, -89, -95, -100, -102, -104, -103,
+ -97, -88, -76, -60, -41, -23, -4, 15, 31, 44, 55, 62, 62, 57, 46, 30,
+ 13, -5, -22, -37, -50, -59, -64, -66, -62, -55, -43, -28, -11, 5, 22, 37,
+ 50, 61, 71, 79, 85, 89, 91, 89, 87, 82, 77, 73, 70, 66, 63, 59,
+ 53, 47, 41, 33, 24, 16, 7, -1, -8, -14, -19, -25, -32, -40, -49, -58,
+ -67, -76, -84, -91, -96, -101, -103, -104, -102, -95, -85, -72, -55, -37, -18, 1,
+ 19, 34, 47, 57, 62, 62, 56, 43, 28, 10, -8, -25, -39, -52, -60, -65,
+ -66, -62, -53, -42, -25, -9, 8, 24, 39, 51, 62, 72, 80, 86, 90, 90,
+ 89, 86, 82, 77, 73, 70, 66, 62, 58, 53, 47, 40, 33, 24, 15, 6,
+ -2, -8, -14, -19, -25, -32, -40, -49, -58, -67, -72, -103, -18, -76, 0, 0,
+ 0, 0, 1, 2, 3, 5, 6, 0, -7, -8, -15, -9, 10, 8, 17, 33,
+ 14, 5, 38, 44, 31, 63, 70, 51, 73, 82, 68, 85, 100, 96, 97, 103,
+ 115, 114, 112, 127, 122, 110, 116, 113, 109, 120, 120, 118, 113, 91, 93, 109,
+ 97, 98, 115, 110, 109, 120, 112, 94, 75, 63, 69, 72, 64, 64, 59, 45,
+ 39, 36, 35, 42, 42, 24, 5, 2, 3, 4, 7, 9, 11, 14, 17, 19,
+ 14, -3, -20, -26, -30, -26, -24, -31, -32, -34, -40, -39, -33, -34, -45, -56,
+ -60, -66, -64, -55, -60, -62, -56, -59, -58, -50, -56, -70, -73, -76, -86, -77,
+ -70, -80, -76, -71, -77, -71, -66, -76, -85, -82, -90, -95, -80, -82, -92, -85,
+ -86, -94, -85, -79, -86, -92, -90, -94, -101, -92, -85, -90, -84, -77, -78, -74,
+ -73, -85, -86, -85, -95, -85, -77, -90, -88, -83, -94, -93, -83, -81, -81, -86,
+ -89, -89, -94, -88, -77, -77, -71, -59, -58, -59, -63, -72, -74, -77, -73, -61,
+ -67, -72, -67, -73, -80, -74, -68, -60, -56, -65, -70, -67, -72, -66, -52, -49,
+ -40, -27, -27, -32, -39, -47, -50, -42, -30, -31, -34, -32, -38, -46, -46, -43,
+ -35, -20, -16, -24, -30, -30, -31, -24, -13, -6, 4, 13, 11, 3, -5, -9,
+ -2, 12, 15, 15, 16, 9, 3, -2, -5, -1, 12, 24, 30, 29, 20, 17,
+ 22, 25, 30, 41, 47, 49, 46, 37, 32, 41, 52, 54, 60, 61, 52, 48,
+ 45, 36, 35, 43, 51, 60, 67, 69, 60, 57, 63, 63, 64, 73, 75, 72,
+ 69, 63, 67, 78, 78, 82, 89, 80, 73, 76, 67, 60, 64, 67, 73, 79,
+ 83, 88, 82, 75, 80, 81, 77, 83, 83, 76, 74, 77, 83, 85, 86, 94,
+ 89, 80, 82, 78, 69, 68, 68, 69, 78, 80, 81, 90, 83, 73, 79, 77,
+ 70, 73, 70, 62, 65, 73, 75, 76, 84, 82, 70, 71, 69, 59, 57, 54,
+ 48, 53, 63, 64, 68, 76, 66, 57, 58, 51, 42, 40, 33, 28, 37, 46,
+ 49, 55, 56, 42, 37, 37, 27, 22, 20, 10, 4, 8, 15, 24, 30, 31,
+ 24, 14, 8, -3, -14, -21, -26, -26, -15, -4, -1, -4, -13, -21, -26, -34,
+ -39, -42, -50, -57, -63, -66, -60, -47, -43, -48, -51, -57, -66, -75, -82, -88,
+ -91, -88, -78, -74, -81, -86, -85, -92, -101, -100, -102, -109, -109, -110, -112, -113,
+ -115, -109, -106, -113, -113, -107, -110, -110, -106, -108, -112, -109, -110, -114, -111, -98,
+ -95, -98, -93, -93, -98, -94, -89, -81, -69, -65, -71, -73, -73, -77, -73, -62,
+ -56, -48, -40, -41, -45, -47, -47, -37, -20, -11, -4, 5, 4, 3, 6, 9,
+ 16, 30, 39, 47, 51, 44, 40, 45, 47, 50, 59, 64, 66, 68, 65, 65,
+ 75, 80, 78, 87, 95, 91, 93, 98, 96, 98, 104, 100, 96, 99, 104, 101,
+ 100, 106, 107, 105, 108, 109, 109, 110, 111, 110, 101, 87, 82, 84, 81, 82,
+ 88, 89, 90, 91, 85, 71, 57, 49, 48, 51, 52, 55, 59, 58, 58, 60,
+ 61, 61, 57, 42, 24, 14, 7, 5, 9, 11, 15, 20, 21, 19, 11, -3,
+ -18, -27, -33, -31, -25, -24, -21, -16, -16, -14, -11, -17, -29, -40, -49, -59,
+ -61, -55, -54, -52, -45, -42, -41, -41, -48, -59, -65, -72, -81, -79, -72, -73,
+ -69, -62, -61, -59, -60, -69, -76, -79, -87, -92, -84, -81, -82, -76, -72, -71,
+ -67, -66, -72, -79, -81, -87, -94, -92, -87, -86, -82, -76, -75, -75, -78, -85,
+ -87, -91, -96, -91, -82, -83, -80, -74, -74, -71, -64, -64, -68, -73, -77, -81,
+ -87, -88, -82, -79, -76, -70, -69, -72, -76, -80, -84, -87, -82, -71, -67, -64,
+ -58, -57, -55, -49, -43, -39, -40, -47, -54, -58, -64, -66, -61, -58, -54, -49,
+ -50, -55, -59, -63, -65, -58, -45, -38, -32, -25, -24, -23, -18, -13, -5, 3,
+ 4, -2, -11, -17, -23, -26, -23, -20, -18, -15, -18, -24, -28, -28, -21, -7,
+ 3, 11, 18, 20, 19, 22, 24, 30, 40, 47, 51, 49, 40, 32, 28, 24,
+ 23, 25, 25, 23, 20, 15, 15, 23, 34, 43, 51, 59, 59, 58, 59, 58,
+ 60, 67, 73, 78, 84, 85, 78, 71, 68, 63, 60, 60, 57, 53, 50, 50,
+ 56, 65, 70, 76, 84, 84, 81, 81, 79, 76, 79, 84, 87, 91, 96, 98,
+ 94, 88, 85, 81, 76, 73, 70, 66, 66, 70, 76, 80, 84, 91, 92, 87,
+ 86, 83, 78, 76, 78, 81, 85, 88, 91, 96, 93, 86, 83, 78, 71, 68,
+ 64, 61, 64, 71, 74, 78, 84, 86, 80, 76, 72, 64, 59, 56, 55, 59,
+ 66, 69, 74, 79, 76, 69, 64, 57, 48, 43, 39, 39, 45, 52, 56, 62,
+ 63, 55, 47, 41, 31, 21, 15, 8, 5, 9, 16, 24, 31, 35, 33, 26,
+ 19, 10, 0, -6, -9, -7, -7, -13, -17, -22, -26, -31, -34, -37, -40, -42,
+ -44, -46, -48, -50, -51, -54, -56, -58, -61, -64, -67, -70, -74, -78, -82, -86,
+ -90, -93, -97, -99, -102, -104, -106, -108, -109, -110, -111, -112, -113, -113, -114, -114,
+ -115, -115, -115, -115, -115, -114, -113, -111, -109, -107, -104, -100, -97, -93, -90, -87,
+ -84, -82, -80, -78, -76, -74, -73, -71, -69, -67, -65, -61, -58, -53, -48, -42,
+ -35, -28, -21, -13, -6, 1, 8, 15, 21, 26, 31, 35, 38, 41, 44, 46,
+ 48, 50, 52, 55, 58, 61, 64, 68, 72, 76, 80, 83, 87, 90, 92, 94,
+ 96, 98, 99, 100, 101, 102, 102, 103, 103, 103, 103, 104, 103, 103, 103, 102,
+ 101, 99, 97, 94, 92, 88, 85, 81, 78, 74, 71, 67, 64, 61, 58, 55,
+ 53, 51, 49, 47, 46, 44, 42, 40, 37, 34, 30, 26, 22, 17, 12, 8,
+ 3, -1, -5, -9, -13, -16, -20, -23, -26, -29, -31, -33, -35, -37, -38, -40,
+ -42, -44, -46, -48, -51, -54, -56, -59, -61, -64, -65, -67, -69, -70, -72, -74,
+ -75, -77, -78, -80, -81, -82, -83, -84, -85, -86, -86, -87, -88, -89, -90, -90,
+ -91, -92, -92, -92, -92, -92, -92, -91, -91, -92, -92, -92, -93, -93, -94, -94,
+ -94, -95, -95, -95, -95, -95, -95, -95, -95, -95, -94, -93, -92, -91, -90, -89,
+ -87, -86, -85, -85, -85, -84, -84, -85, -85, -85, -85, -85, -85, -85, -85, -85,
+ -84, -83, -82, -81, -79, -77, -75, -73, -70, -68, -65, -63, -62, -60, -59, -59,
+ -59, -59, -59, -59, -59, -60, -59, -59, -59, -58, -57, -55, -53, -50, -47, -44,
+ -40, -36, -32, -29, -25, -22, -20, -18, -17, -16, -15, -15, -16, -16, -16, -16,
+ -16, -16, -15, -13, -11, -9, -6, -2, 2, 6, 10, 15, 19, 22, 26, 29,
+ 31, 33, 35, 36, 36, 36, 36, 35, 35, 35, 35, 35, 36, 38, 40, 42,
+ 45, 48, 52, 55, 58, 61, 64, 67, 70, 72, 73, 74, 75, 76, 76, 76,
+ 75, 75, 74, 74, 74, 74, 74, 75, 77, 78, 80, 82, 83, 85, 87, 89,
+ 90, 91, 92, 93, 94, 94, 94, 94, 94, 93, 93, 92, 91, 91, 90, 90,
+ 90, 90, 91, 91, 92, 92, 93, 93, 94, 94, 94, 94, 94, 94, 94, 94,
+ 93, 93, 92, 92, 91, 90, 89, 88, 87, 87, 86, 86, 85, 85, 85, 84,
+ 84, 83, 83, 82, 81, 80, 79, 78, 77, 77, 76, 75, 74, 72, 71, 70,
+ 68, 67, 65, 64, 63, 61, 60, 58, 57, 55, 53, 50, 48, 45, 43, 40,
+ 38, 36, 34, 32, 30, 29, 27, 25, 23, 21, 19, 17, 14, 12, 9, 6,
+ 3, 0, -4, -8, -12, -17, -21, -25, -29, -33, -36, -39, -42, -45, -47, -49,
+ -51, -53, -55, -58, -60, -63, -65, -68, -71, -74, -77, -81, -84, -87, -91, -94,
+ -97, -99, -102, -104, -105, -107, -108, -109, -110, -111, -111, -112, -112, -113, -113, -113,
+ -113, -113, -113, -112, -111, -109, -107, -105, -102, -99, -96, -93, -90, -87, -84, -82,
+ -79, -77, -75, -73, -70, -69, -66, -64, -60, -58, -53, -49, -44, -39, -32, -27,
+ -19, -14, -8, -3, 3, 11, 22, 10, 8, 1, 1, 1, 1, 1, 2, 2,
+ 2, 2, 3, 3, 3, 3, 4, 4, 5, 5, 6, 5, 6, 6, 6, 6,
+ 6, 6, 7, 5, 7, 5, 6, 4, 6, 4, 4, 4, 4, 3, 3, 2,
+ 3, 1, 3, -2, 2, 0, 0, 0, 0, -2, -1, -2, -3, -3, 0, -5,
+ -1, -2, -2, -2, -1, 0, -3, -1, -1, 0, 1, -1, 0, -1, 0, 0,
+ 1, 0, 0, 1, -1, 1, -1, 1, -2, -1, -3, 0, -2, -1, -2, -2,
+ -2, -3, -2, -3, -4, -5, -6, -5, -9, -8, -9, -9, -9, -11, -10, -13,
+ -14, -14, -15, -16, -15, -17, -19, -19, -21, -18, -21, -20, -22, -20, -24, -21,
+ -22, -19, -20, -21, -17, -19, -16, -17, -15, -17, -13, -11, -10, -7, -5, -3,
+ 2, 6, 4, 8, 9, 18, 14, 31, 25, 24, 25, 24, 21, 13, 15, 15,
+ 11, 9, 1, 4, -20, -18, -38, -44, -57, -57, -55, -55, -52, -55, -46, -47,
+ -40, -32, -26, -19, -16, -2, 3, 13, 19, 28, 30, 37, 40, 44, 39, 38,
+ 35, 34, 37, 41, 48, 51, 53, 58, 61, 70, 74, 76, 76, 80, 81, 86,
+ 83, 83, 78, 78, 73, 69, 65, 55, 47, 40, 36, 29, 23, 16, 14, 8,
+ -2, -4, -11, -11, -19, -22, -26, -25, -34, -39, -40, -41, -45, -49, -51, -57,
+ -56, -58, -59, -66, -70, -70, -72, -65, -64, -59, -53, -49, -45, -34, -29, -21,
+ -15, -10, -6, -6, -3, -4, 2, 3, 3, 3, -1, -3, -11, -11, -13, -16,
+ -22, -24, -27, -32, -34, -37, -35, -31, -30, -26, -25, -22, -21, -15, -13, -15,
+ -10, -12, -12, -7, 2, 15, 22, 27, 24, 28, 22, 22, 21, 22, 17, 13,
+ 14, 9, 5, 2, -8, -12, -16, -14, -17, -17, -17, -17, -14, -8, -3, -3,
+ 0, 5, 3, 5, 6, 3, -2, -6, -9, -11, -13, -18, -19, -29, -42, -61,
+ -72, -79, -81, -83, -82, -79, -76, -65, -54, -42, -33, -24, -14, 0, 18, 33,
+ 48, 62, 75, 87, 93, 99, 100, 102, 102, 104, 102, 100, 100, 96, 93, 95,
+ 96, 105, 109, 112, 111, 110, 106, 106, 104, 102, 97, 93, 85, 80, 71, 60,
+ 48, 36, 26, 12, 0, -5, -13, -21, -28, -31, -36, -42, -49, -53, -56, -59,
+ -61, -63, -64, -64, -63, -67, -70, -77, -75, -77, -78, -79, -80, -81, -80, -75,
+ -69, -64, -57, -50, -43, -35, -26, -16, -6, 6, 13, 17, 22, 26, 25, 27,
+ 27, 26, 23, 19, 11, 5, -5, -12, -19, -24, -31, -37, -42, -45, -50, -49,
+ -48, -47, -43, -41, -38, -38, -37, -35, -35, -37, -42, -40, -33, -27, -20, -12,
+ -11, -13, -10, -9, -10, -10, -10, -13, -11, -9, -8, -11, -13, -16, -18, -17,
+ -15, -15, -14, -12, -8, -3, 3, 8, 16, 22, 25, 31, 34, 36, 36, 34,
+ 31, 25, 23, 24, 26, 23, 13, -1, -16, -29, -38, -45, -51, -56, -57, -54,
+ -48, -39, -34, -29, -20, -10, 0, 13, 27, 39, 54, 68, 79, 87, 92, 94,
+ 96, 94, 92, 89, 87, 82, 76, 72, 71, 74, 76, 81, 83, 83, 84, 84,
+ 85, 85, 82, 81, 82, 80, 75, 71, 66, 57, 46, 34, 24, 15, 5, -2,
+ -8, -13, -19, -26, -31, -37, -41, -44, -48, -53, -54, -53, -54, -54, -57, -61,
+ -64, -67, -70, -72, -75, -77, -79, -79, -76, -73, -70, -63, -58, -53, -47, -38,
+ -29, -21, -13, -6, 0, 4, 7, 7, 8, 8, 6, 5, -1, -8, -15, -22,
+ -30, -36, -41, -47, -51, -54, -56, -58, -59, -56, -50, -45, -42, -37, -31, -26,
+ -23, -23, -23, -24, -21, -14, -6, 2, 8, 12, 15, 18, 21, 20, 20, 20,
+ 20, 21, 23, 22, 18, 13, 10, 8, 6, 5, 4, 3, 2, 2, 4, 7,
+ 10, 13, 18, 22, 24, 26, 28, 27, 21, 14, 8, 5, 4, 2, -3, -12,
+ -24, -37, -50, -59, -67, -76, -80, -79, -75, -69, -61, -55, -47, -38, -27, -15,
+ -2, 11, 27, 43, 58, 71, 82, 90, 94, 96, 98, 98, 98, 95, 89, 84,
+ 81, 79, 81, 85, 88, 89, 91, 92, 92, 90, 89, 89, 88, 85, 82, 79,
+ 75, 67, 58, 48, 37, 25, 14, 4, -4, -10, -17, -24, -31, -37, -42, -47,
+ -51, -56, -59, -59, -59, -59, -61, -63, -65, -67, -70, -72, -74, -76, -78, -78,
+ -78, -75, -70, -66, -61, -56, -50, -41, -33, -23, -14, -6, 2, 10, 16, 19,
+ 21, 23, 24, 24, 22, 19, 13, 7, 0, -6, -14, -20, -25, -27, -32, -37,
+ -39, -39, -38, -36, -33, -30, -27, -22, -19, -19, -20, -23, -24, -22, -18, -13,
+ -8, -4, 0, 2, 5, 6, 5, 3, 2, 4, 6, 6, 5, 1, -2, -6,
+ -8, -9, -10, -11, -13, -12, -12, -11, -9, -4, 0, 4, 8, 13, 18, 20,
+ 19, 14, 10, 6, 4, 4, 4, 0, -8, -17, -28, -38, -49, -60, -68, -72,
+ -72, -70, -65, -59, -54, -46, -37, -27, -17, -5, 8, 22, 37, 51, 66, 77,
+ 84, 88, 91, 93, 94, 94, 91, 85, 79, 75, 74, 76, 77, 80, 83, 85,
+ 85, 85, 86, 86, 85, 85, 85, 83, 81, 77, 70, 64, 55, 44, 32, 22,
+ 13, 6, -1, -9, -16, -22, -27, -32, -38, -43, -46, -47, -47, -47, -48, -49,
+ -49, -50, -52, -54, -56, -59, -62, -64, -66, -65, -64, -61, -59, -56, -53, -48,
+ -41, -33, -25, -17, -10, -2, 4, 9, 13, 15, 16, 17, 17, 15, 11, 7,
+ 1, -7, -15, -22, -27, -33, -38, -43, -47, -49, -50, -50, -49, -46, -42, -37,
+ -31, -28, -28, -29, -30, -29, -26, -22, -17, -13, -8, -3, 2, 6, 7, 6,
+ 5, 6, 8, 10, 12, 11, 8, 5, 3, 1, -1, -2, -3, -4, -6, -7,
+ -6, -3, 0, 1, 5, 10, 16, 20, 21, 19, 15, 10, 8, 6, 6, 4,
+ 0, -5, -12, -22, -33, -45, -57, -65, -70, -72, -70, -68, -64, -58, -51, -44,
+ -36, -24, -13, -2, 11, 27, 43, 58, 70, 78, 83, 88, 92, 96, 97, 93,
+ 89, 85, 81, 80, 81, 83, 86, 88, 90, 91, 91, 91, 91, 91, 91, 91,
+ 89, 86, 83, 79, 72, 63, 52, 41, 30, 21, 13, 4, -5, -11, -17, -23,
+ -31, -38, -44, -47, -49, -50, -52, -54, -55, -57, -57, -58, -60, -63, -66, -69,
+ -72, -74, -73, -72, -70, -69, -67, -64, -59, -53, -45, -37, -30, -22, -14, -7,
+ -2, 3, 8, 10, 12, 12, 13, 12, 8, 3, -4, -10, -16, -21, -27, -33,
+ -37, -41, -44, -46, -48, -48, -45, -48, -43, -37, -33, -31, -32, -33, -32, -29,
+ -26, -22, -18, -12, -5, 1, 6, 9, 9, 9, 9, 11, 14, 16, 16, 14,
+ 12, 8, 5, 3, 2, 1, -1, -3, -4, -4, -2, -1, 2, 5, 11, 18,
+ 24, 27, 27, 24, 20, 17, 15, 13, 11, 9, 5, -1, -10, -22, -35, -49,
+ -61, -70, -75, -77, -76, -73, -69, -63, -56, -47, -36, -25, -13, 0, 16, 34,
+ 52, 67, 79, 88, 95, 101, 106, 109, 108, 105, 100, 95, 92, 90, 91, 93,
+ 96, 99, 100, 101, 101, 101, 101, 101, 101, 100, 97, 95, 91, 85, 78, 67,
+ 55, 43, 31, 21, 11, 1, -7, -14, -21, -29, -37, -45, -51, -54, -56, -58,
+ -60, -62, -64, -65, -66, -67, -69, -72, -76, -80, -82, -84, -83, -82, -80, -79,
+ -77, -73, -67, -60, -51, -42, -34, -25, -16, -8, -2, 4, 9, 12, 13, 14,
+ 14, 13, 9, 3, -5, -12, -18, -25, -31, -37, -42, -47, -50, -53, -54, -53,
+ -48, -41, -36, -32, -31, -31, -32, -31, -28, -25, -22, -17, -12, -5, 1, 1,
+ -2, -1, -9, -9, -6, 5, 6, -1, -10, 8, 24, 11, -2, -14, -9, -15,
+ -13, 5, 14, 12, -6, -1, -12, 1, -9, 12, 12, 10, 5, -19, -11, -13,
+ -2, 8, 5, 1, -2, -3, 9, -6, 6, 5, 6, -3, -17, -7, 3, 2,
+ -1, 0, 7, -7, 5, 4, 6, -18, -24, 6, 20, -1, -4, -1, 10, 3,
+ -10, 8, 7, -11, -17, -15, 5, 18, 4, 1, 8, -16, -4, 0, 11, 9,
+ -10, -15, 0, -22, -12, 19, 34, 16, -9, -16, -7, -12, -10, 13, 23, -1,
+ -10, -2, -3, -11, 13, 7, -6, -9, 3, 11, -10, -18, 12, 22, 7, -27,
+ -29, -4, 20, 20, 10, 8, -16, -26, -6, 22, 21, 7, 15, 8, -50, -50,
+ -7, 35, 22, -13, 32, 41, -33, -46, -10, 23, -7, -25, 23, 21, -38, -36,
+ 14, 44, 2, 2, 34, -14, -51, -29, 11, 19, 7, 22, 13, -23, -21, -8,
+ -9, 1, 14, 26, 26, -8, -34, -33, 4, 1, -6, -2, 16, -7, -23, 12,
+ 27, 5, 6, 6, 0, -8, 0, -1, -17, -13, -12, 3, 9, 4, 11, 23,
+ 36, 0, -43, -16, 4, -21, -26, 27, 16, -25, 3, 65, 4, -34, 24, -10,
+ -38, -14, 13, 4, -15, 36, 44, -42, -51, 20, -5, -6, 68, 20, -18, -39,
+ -11, 9, 17, 6, -33, -20, -13, 48, 30, 22, -4, -9, -53, -20, 32, 32,
+ -16, 17, -11, -36, -8, -5, 39, 28, 33, 21, -64, -48, 3, -22, 15, 62,
+ -26, 0, 3, 5, 73, -14, -48, -20, -59, 4, 70, 60, -7, -2, -88, -22,
+ -17, 39, 17, 33, -3, 15, 28, -47, -80, -37, 5, 7, 104, 16, -99, -92,
+ -36, 109, 78, 26, -15, -92, -21, 62, 48, -51, -81, -25, 55, 63, 35, 21,
+ -115, -54, 101, 73, -41, -110, -66, 50, 107, 45, -8, -109, -38, 12, 102, 3,
+ 17, -45, -2, -36, 39, 46, -12, -28, -27, -17, 17, -18, 82, -5, -3, -25,
+ -5, -14, 15, 9, -3, -17, -6, 2, 7, -36, -13, 6, 21, -23, -20, 16,
+ -18, 3, -2, 26, 0, 13, -23, -2, -19, -28, -18, 15, 12, 22, -4, 23,
+ -17, -22, -9, -18, -4, 11, 13, 0, 34, -16, -20, 26, 23, 15, -4, -25,
+ 7, 8, -9, 8, 44, 1, -40, 17, -32, 9, -30, -52, 52, 3, 2, -21,
+ 83, 58, -14, -46, -61, -12, -67, -20, 64, 72, 57, -10, 5, 1, -77, 31,
+ -47, -39, 12, 22, 57, 28, 0, 9, -76, 15, -74, 33, -12, 39, 114, -35,
+ -36, -38, -23, 27, -21, 14, 56, 47, 6, -72, -61, -4, 18, -4, 19, 13,
+ 45, 71, 48, -1, -125, -52, -56, -20, -18, -12, 51, 78, 68, -46, 32, -40,
+ -29, -28, -81, -25, 75, 42, 58, -38, 1, -29, -34, 31, -36, -14, 10, 64,
+ 37, 2, -31, -72, -17, -33, 30, -52, -54, 25, 43, 70, 81, -9, -73, 4,
+ -65, 15, -28, 25, 0, 28, 19, 51, -26, 6, 0, -37, -15, -22, -20, -16,
+ -5, 50, 56, 67, 25, 16, -35, -29, -14, -39, 19, -24, -52, -13, -32, -10,
+ 39, 33, 59, 6, 37, 55, 11, -9, -35, -15, -57, -56, -36, -34, 19, 19,
+ 6, 20, 17, -11, 5, 26, 19, 16, 7, -20, -26, -55, -62, -36, -18, 19,
+ 37, 47, 25, -6, -14, 1, -4, -13, 12, 23, 34, 38, 41, 33, 31, -10,
+ -56, -52, -49, -31, -40, -21, -12, 0, 5, 12, 22, 22, 21, 31, 12, 2,
+ -8, -4, -18, -7, 3, 1, -1, 11, 12, 18, 17, 9, -2, -12, -13, -11,
+ -1, 8, 3, 3, 2, 5, -5, -16, -15, -13, -8, -12, -9, -2, -1, 2,
+ 7, 10, 7, 11, 14, 7, -1, -4, 5, -3, -2, 0, -6, -10, -1, -5,
+ 3, 9, 0, -8, -9, -6, -6, 0, 6, 3, 6, 7, 10, 0, -8, -3,
+ -5, -1, -8, -7, -4, -3, -3, 0, -1, -6, 2, 7, 7, 5, 4, 10,
+ 5, 8, -1, -11, -15, -11, -15, -10, -1, -8, -12, -5, 1, 3, 6, 8,
+ 11, 18, 22, 26, 10, -10, -1, -15, -3, -21, -16, -14, -12, -7, -8, -18,
+ -20, -11, 9, 20, 27, 26, 11, 1, 21, 6, 3, -9, -15, -9, -20, 3,
+ 5, 21, 14, 6, 11, -21, -22, -6, -21, -23, -18, 11, 6, 5, 21, 9,
+ 23, 16, -3, -30, -7, -27, -4, 5, 18, 22, 16, 2, 7, -1, -2, -10,
+ -14, -10, -17, -10, -15, -16, 3, 12, 30, 18, -1, -6, -15, -3, 5, 11,
+ -18, -2, 8, 21, 11, -13, -4, -30, -7, 0, 12, 25, -3, 17, 14, -20,
+ -6, -27, -41, -11, -12, 23, -8, 13, 24, 18, 27, -11, -8, -12, -2, 17,
+ 23, 13, -20, -21, -2, -21, -34, -46, -23, 28, 48, 9, -10, 8, 29, 27,
+ 5, -29, -12, 13, -5, -2, -35, 1, 3, 24, 13, 17, -18, -30, -21, 14,
+ -1, 6, -8, 48, 45, -7, -34, -49, -32, -6, -26, 20, 29, 76, 30, -21,
+ -66, -36, -15, 40, -5, 29, 3, 10, -39, -25, -2, 24, 19, 19, -4, -8,
+ 3, -22, -23, -18, 13, 17, -3, -25, 23, 66, 26, -18, -27, -34, -30, -30,
+ 36, 25, 28, -22, -17, -7, -22, 21, 18, 42, 8, -25, -28, -31, -10, 15,
+ 18, 0, -1, -5, 16, -12, 13, 13, 12, -8, -37, -9, 13, -5, 8, -3,
+ 13, -8, 4, 24, -16, -43, -18, 26, 26, -11, -9, 19, 9, -15, 9, 15,
+ -12, -31, -27, 8, 29, 5, 7, 17, -33, -14, 14, 23, -1, -18, -18, -4,
+ -35, -17, 47, 71, -16, -20, -11, -16, -25, 6, 37, 14, -18, 1, -8, -14,
+ 10, 14, 2, -20, 0, 20, -10, -25, 14, 32, 7, -39, -38, -3, 34, 25,
+ 13, 3, -24, -34, 5, 38, 18, 7, 29, -30, -74, -41, 36, 40, -12, 26,
+ 55, -17, -59, -26, 28, -2, -31, 24, 25, -44, -39, 21, 44, -1, 10, 33,
+ -34, -50, -12, 18, 13, 20, 17, -6, -31, -10, -6, -1, 7, 12, 14, 6,
+ -16, -24, 6, 9, -16, -16, 6, 2, -10, 13, 12, -10, 0, 11, 11, 10,
+ -3, -22, -22, -12, -7, 19, 17, -2, -12, 6, 16, 7, -11, -1, -20, -22,
+ -8, 26, 16, -3, 12, 1, -33, 2, 30, -23, -5, 28, -17, -19, 21, 9,
+ -28, -14, 25, -1, 4, 24, 0, -26, -9, 7, 2, -2, 20, -10, -11, 5,
+ -3, -4, 8, -9, 14, 18, 25, -22, -15, -22, -3, -12, 27, 30, 15, -11,
+ -26, -4, 15, -7, -14, 23, -23, -4, 34, -2, -38, 14, -11, -24, 16, 34,
+ 11, -13, 3, -3, -19, -34, 0, -3, 24, 43, 1, -12, -38, -25, -11, 23,
+ 35, 12, -28, -25, -16, 7, 22, 1, -10, 8, 8, -3, 6, -24, -20, -13,
+ 9, 31, 12, -16, 7, -29, 5, 8, -28, 3, 4, 12, 26, -9, -15, -5,
+ -20, 9, 21, 0, 1, -9, 0, 8, -3, -7, -9, -3, 22, 8, 3, -11,
+ -9, -11, 3, 15, 9, -10, 1, -3, -3, -2, -5, 9, 0, 12, 7, -15,
+ -7, 0, -8, 5, 9, -5, 7, -7, 10, 4, -11, -2, -8, -4, 9, 9,
+ 0, -2, -11, -3, -4, 3, 4, 3, -2, 3, 3, -8, -9, -2, 0, 3,
+ 5, -1, -10, -7, 2, 8, 3, 0, -5, -5, 2, 4, -2, -5, -3, 2,
+ 3, 0, 2, -5, -3, 3, 2, -2, -4, -2, 1, 2, 1, 0, 0, 0,
+ 0, -1, -7, -9, -5, 0, 2, 2, 5, 6, 0, -11, -13, -5, 3, 1,
+ 0, 0, 1, -3, -9, -6, -1, 5, 3, -3, -5, -3, -1, -4, -3, -1,
+ 2, -2, -9, -7, -2, -5, -18, -31, -36, -36, -41, -38, -29, -21, -27, -31,
+ -26, -4, 37, 65, 67, 44, 22, 10, 2, -4, 8, 32, 44, 38, 24, 17,
+ 9, 4, 3, 12, 26, 32, 32, 23, 16, 7, 1, -7, -13, -8, 1, -5,
+ -39, -72, -79, -64, -49, -40, -24, -1, 12, 0, -25, -44, -43, -30, -14, 1,
+ 13, 13, 4, 4, 16, 34, 46, 55, 65, 73, 67, 53, 54, 58, 62, 60,
+ 51, 38, 33, 20, -7, -27, -40, -46, -55, -58, -41, -9, 7, 8, 2, -26,
+ -49, -71, -92, -101, -93, -80, -70, -71, -73, -65, -67, -69, -61, -42, -15, 15,
+ 18, -5, -33, -54, -54, -40, -18, 2, 21, 21, 3, -28, -52, -33, 9, 35,
+ 33, 30, 34, 45, 46, 43, 54, 63, 65, 61, 56, 43, 45, 59, 77, 96,
+ 104, 112, 115, 100, 78, 53, 22, -3, -6, 5, 24, 37, 38, 35, 25, 3,
+ -19, -38, -51, -46, -33, -34, -42, -47, -48, -38, -27, -30, -40, -48, -45, -30,
+ -24, -38, -44, -43, -47, -34, -13, 7, 27, 30, 9, -18, -38, -22, 19, 47,
+ 70, 83, 68, 28, -13, -41, -41, -19, -1, 10, 8, 4, 4, -7, -12, 6,
+ 32, 42, 31, 0, -39, -71, -99, -115, -111, -85, -56, -46, -61, -74, -66, -45,
+ -22, 4, 21, 27, 25, 1, -30, -51, -37, 4, 37, 40, 26, 17, 12, 12,
+ 5, 1, 2, 12, 29, 43, 44, 45, 54, 45, 28, 10, 13, 26, 32, 43,
+ 59, 67, 62, 60, 66, 72, 61, 34, 11, 0, 1, -6, -18, -12, 19, 47,
+ 51, 32, 9, -8, -22, -26, -27, -30, -29, -12, 7, 18, 13, -1, -11, -11,
+ 5, 16, 14, 11, 5, -19, -47, -54, -29, 13, 37, 42, 33, 9, -17, -31,
+ -21, 14, 61, 81, 68, 39, 4, -26, -46, -38, -17, -1, 1, -4, -14, -25,
+ -23, -4, 24, 43, 49, 37, 4, -48, -97, -123, -116, -89, -66, -65, -73, -67,
+ -64, -66, -69, -46, 3, 36, 27, -3, -25, -39, -38, -39, -36, -24, -9, 5,
+ 13, 13, 4, -1, -13, -15, 0, 22, 47, 65, 76, 67, 35, 3, -4, 6,
+ 27, 47, 58, 68, 72, 73, 72, 66, 59, 62, 61, 49, 28, -5, -30, -27,
+ 9, 40, 51, 46, 40, 28, 1, -30, -56, -57, -41, -13, 5, 12, 7, -11,
+ -38, -54, -40, -16, 12, 23, 13, -16, -49, -62, -55, -29, 4, 38, 45, 28,
+ -5, -36, -36, -5, 39, 68, 77, 73, 55, 8, -35, -46, -29, -15, -15, -16,
+ -12, -9, -23, -30, -18, 16, 48, 51, 24, -18, -45, -72, -96, -111, -101, -80,
+ -67, -71, -79, -77, -70, -46, -22, -7, -4, -5, -4, -2, -15, -37, -43, -42,
+ -27, -5, 9, 27, 38, 27, 4, -14, -15, 6, 30, 61, 93, 90, 52, 16,
+ 2, 1, 5, 11, 34, 64, 79, 71, 48, 35, 43, 61, 59, 46, 27, 1,
+ -22, -33, -25, -9, 15, 37, 56, 54, 28, -10, -44, -58, -49, -27, -8, 20,
+ 29, 0, -42, -66, -60, -34, -7, 16, 30, 15, -20, -50, -64, -49, -11, 21,
+ 34, 34, 17, -7, -31, -29, 3, 43, 69, 78, 73, 45, 10, -20, -32, -33,
+ -26, -12, -6, -18, -41, -44, -27, -6, 10, 17, 19, 18, -4, -49, -87, -108,
+ -100, -84, -87, -93, -83, -67, -54, -45, -45, -35, -23, -13, 6, 17, 14, 1,
+ -22, -40, -35, -18, 2, 28, 57, 63, 33, -7, -21, -4, 23, 57, 89, 102,
+ 94, 68, 37, 8, -4, 4, 37, 71, 88, 79, 54, 46, 55, 62, 55, 53,
+ 54, 46, 20, -14, -40, -41, -16, 15, 44, 60, 59, 30, -21, -61, -70, -54,
+ -26, 10, 29, 19, -16, -49, -63, -58, -33, 4, 29, 26, -1, -33, -49, -50,
+ -34, -9, 16, 34, 34, 9, -20, -25, -9, 13, 29, 54, 87, 91, 56, 11,
+ -12, -11, -12, -20, -22, -17, -11, -12, -22, -25, -15, 3, 19, 19, 9, -11,
+ -38, -62, -76, -92, -107, -109, -95, -68, -53, -49, -49, -58, -63, -48, -25, -5,
+ 12, 12, -7, -36, -56, -56, -32, 8, 50, 64, 36, 6, -10, -15, -11, 9,
+ 47, 94, 118, 100, 58, 14, -3, 3, 19, 44, 72, 83, 78, 75, 66, 53,
+ 45, 52, 66, 70, 52, 22, -8, -36, -36, -14, 21, 63, 84, 63, 14, -29,
+ -55, -54, -42, -12, 28, 40, 14, -24, -52, -58, -42, -22, 6, 19, 16, -5,
+ -34, -49, -43, -24, -12, 2, 14, 22, 10, -10, -20, -16, 3, 28, 60, 72,
+ 61, 42, 25, 1, -26, -44, -46, -31, -25, -26, -32, -30, -24, -12, -12, -15,
+ 0, 6, -3, -23, -47, -79, -112, -128, -115, -84, -61, -45, -42, -51, -64, -68,
+ -61, -33, 9, 29, 12, -28, -54, -64, -56, -30, 9, 36, 41, 34, 10, -18,
+ -38, -29, 13, 70, 105, 106, 79, 48, 31, 12, -1, 12, 51, 78, 89, 87,
+ 75, 66, 49, 44, 56, 73, 79, 66, 23, -23, -42, -39, -9, 31, 65, 75,
+ 52, 7, -32, -54, -57, -30, 3, 24, 19, 2, -18, -39, -50, -39, -10, 8,
+ 10, -2, -12, -18, -21, -29, -33, -16, 11, 28, 17, 1, -4, 3, -3, -6,
+ 13, 42, 64, 67, 56, 29, 2, -21, -36, -42, -40, -25, -15, -10, -7, -10,
+ -27, -38, -24, 2, 19, 14, -6, -44, -86, -115, -121, -109, -81, -45, -27, -36,
+ -58, -76, -81, -53, -13, 11, 8, -11, -24, -40, -58, -62, -30, 11, 42, 44,
+ 17, -15, -36, -38, -22, 15, 53, 84, 88, 73, 52, 19, -6, -9, 13, 44,
+ 71, 88, 93, 79, 54, 42, 46, 67, 82, 79, 54, 20, -10, -28, -27, 0,
+ 46, 70, 61, 29, 2, -18, -38, -45, -23, 7, 16, 10, -8, -22, -26, -30,
+ -32, -23, -13, -2, 6, -6, -15, -16, -18, -20, -9, 0, 2, 11, 19, 17,
+ -2, -21, -12, 14, 33, 50, 65, 61, 43, 19, -17, -44, -50, -42, -21, 1,
+ 11, 1, -31, -56, -45, -22, -1, 17, 18, -4, -44, -95, -126, -123, -95, -56,
+ -36, -41, -51, -59, -68, -60, -38, -15, 5, 14, 7, -17, -47, -61, -37, 1,
+ 27, 33, 24, 7, -13, -30, -43, -26, 13, 47, 70, 74, 68, 48, 12, -19,
+ -14, 14, 46, 74, 81, 75, 64, 52, 48, 56, 67, 82, 78, 44, 9, -12,
+ -20, -8, 18, 41, 57, 46, 23, 0, -23, -33, -21, -10, -10, -2, 3, 5,
+ -2, -19, -33, -32, -24, -16, -11, -14, -6, 7, -2, -20, -25, -16, -6, 6,
+ 17, 27, 22, 2, -10, -11, 0, 24, 51, 68, 79, 65, 25, -19, -49, -48,
+ -30, -9, 8, 10, -12, -40, -57, -57, -34, -1, 25, 24, -7, -56, -95, -111,
+ -102, -84, -69, -57, -44, -42, -59, -74, -71, -47, -17, 0, 3, -6, -21, -37,
+ -38, -27, -6, 15, 23, 22, 12, -4, -23, -32, -26, 1, 36, 63, 82, 78,
+ 46, 12, -1, 2, 20, 41, 64, 81, 79, 66, 59, 61, 67, 75, 76, 66,
+ 49, 27, 5, -7, 2, 24, 41, 44, 38, 28, 13, -5, -19, -21, -17, -11,
+ -2, 4, 4, -2, -14, -28, -32, -27, -21, -16, -13, -1, 6, -4, -21, -25,
+ -17, -7, 6, 0, 0, -4, -4, -5, -8, -4, 3, 8, 6, 1, 1, 2,
+ 3, 3, -2, -7, -11, -10, -5, -2, 4, 6, 0, -2, -5, -4, -4, -9,
+ -9, -7, -11, -11, -10, -7, 4, 0, -4, -4, -1, 4, 0, -4, -3, -5,
+ -6, -5, -4, 4, -1, 2, 11, 5, -13, -20, -30, -49, -50, -34, -22, -33,
+ -27, -20, -17, 0, 34, 70, 73, 42, 3, -26, -37, -25, -1, 25, 48, 71,
+ 75, 44, 22, 45, 69, 57, 44, 52, 58, 24, -23, -41, -50, -58, -67, -82,
+ -66, -29, -29, -41, -34, -19, -4, -4, -1, 20, 50, 56, 35, 12, 4, -8,
+ -15, 4, 28, 44, 46, 34, 17, 2, 0, 11, 28, 42, 22, -28, -51, -45,
+ -34, -39, -37, -19, -17, -30, -32, -18, -4, 9, 19, 38, 35, 3, -24, -35,
+ -40, -23, -11, -25, -47, -52, -51, -58, -61, -52, -47, -37, -17, -5, -5, -16,
+ -31, -24, -11, -1, -3, -23, -40, -48, -40, -12, 15, 25, 17, -5, -2, 14,
+ 21, 15, -12, -26, -18, -2, 28, 48, 55, 52, 42, 35, 35, 42, 38, 36,
+ 40, 53, 55, 52, 44, 36, 49, 57, 56, 57, 55, 50, 39, 27, 31, 30,
+ 15, 11, 12, 6, 4, 14, 28, 23, 1, -6, -17, -35, -44, -41, -33, -22,
+ -9, -6, -12, -15, -13, -27, -29, -7, 14, -5, -55, -71, -49, -33, -37, -46,
+ -33, -18, -43, -89, -96, -65, -23, 2, 8, 20, 24, -11, -50, -51, -12, 15,
+ 4, 1, 20, 47, 53, 43, 52, 77, 98, 114, 110, 100, 88, 53, 10, -29,
+ -55, -71, -83, -77, -58, -55, -57, -52, -48, -47, -46, -12, 34, 59, 52, 25,
+ -10, -33, -21, 18, 49, 54, 46, 18, 13, 30, 41, 48, 54, 53, 44, 24,
+ 1, -13, -25, -43, -38, -28, -35, -55, -71, -64, -40, -13, 10, 24, 38, 41,
+ 21, -1, -11, 1, 15, 7, -6, -13, -39, -57, -64, -51, -20, -12, -24, -37,
+ -30, -4, 17, 21, 12, -7, -16, -15, -7, 6, 1, -20, -34, -30, -1, 32,
+ 44, 36, 22, 25, 21, 6, 1, -2, -13, -5, 19, 28, 24, 12, 11, 16,
+ 19, 38, 54, 49, 38, 28, 28, 39, 52, 49, 32, 25, 33, 45, 49, 39,
+ 40, 46, 20, -9, -6, 6, 1, -22, -29, 10, 48, 33, -17, -51, -55, -44,
+ -49, -50, -36, -33, -57, -84, -71, -21, 11, 13, 4, -1, -8, -32, -45, -32,
+ -10, 2, -13, -37, -39, -42, -57, -65, -63, -36, -11, 10, 33, 22, -12, -34,
+ -28, -12, 2, 8, 6, -2, -4, 0, 10, 22, 36, 57, 82, 104, 122, 127,
+ 109, 70, 17, -28, -45, -36, -20, -33, -68, -102, -114, -103, -76, -45, -20, -7,
+ -11, -10, -2, 6, 0, -14, -5, 30, 48, 29, 3, -8, 10, 39, 67, 86,
+ 83, 59, 32, 17, 32, 46, 40, 11, -29, -48, -57, -68, -69, -57, -43, -26,
+ -13, -2, 1, 1, 3, 4, 8, 21, 20, 11, 3, -2, -6, -26, -39, -33,
+ -34, -36, -28, -23, -27, -28, -17, -1, 0, -6, -10, -9, -7, -12, -26, -44,
+ -54, -38, -16, 0, 18, 27, 17, -3, -18, -3, 19, 11, -9, -7, 10, 14,
+ 5, 5, 18, 29, 29, 12, 16, 38, 43, 14, 2, 24, 55, 59, 33, 17,
+ 24, 44, 65, 75, 77, 55, 15, -16, -20, 6, 31, 27, 17, 18, 19, 17,
+ 7, 0, -5, -20, -22, -25, -49, -69, -73, -58, -45, -29, -4, 9, -1, -23,
+ -51, -52, -24, -2, 11, 12, -16, -51, -75, -77, -67, -59, -59, -54, -35, -15,
+ -9, -9, -9, -7, -8, -12, -1, 15, 22, 10, -14, -34, -28, -14, 11, 64,
+ 113, 127, 117, 97, 87, 84, 68, 50, 37, 36, 24, -15, -58, -78, -84, -71,
+ -40, -14, -12, -34, -48, -41, -14, 20, 37, 35, 16, -6, 1, 14, 15, 20,
+ 23, 24, 38, 58, 69, 57, 40, 54, 73, 75, 65, 40, -3, -49, -68, -56,
+ -42, -42, -53, -59, -44, -23, -9, -3, -11, -18, -13, -11, -5, 3, 13, 4,
+ -25, -39, -22, -14, -16, -27, -38, -37, -42, -55, -51, -21, 8, 10, -8, -12,
+ -4, -10, -39, -55, -38, -13, -4, -11, -15, -3, 15, 12, 2, 11, 28, 34,
+ 15, -5, 3, 11, 6, 12, 25, 25, 13, 10, 15, 27, 48, 55, 38, 23,
+ 17, 23, 32, 23, 32, 57, 75, 75, 52, 22, 10, 5, 12, 28, 33, 23,
+ 2, -14, -4, 19, 30, 25, 15, 1, -27, -64, -78, -67, -49, -45, -48, -42,
+ -31, -25, -40, -50, -39, -18, -4, 13, 19, 12, -10, -43, -59, -53, -47, -54,
+ -61, -51, -20, -2, -12, -23, -25, -18, 5, 33, 51, 45, 16, -16, -46, -53,
+ -38, -6, 33, 57, 74, 81, 75, 77, 89, 105, 114, 110, 83, 39, -6, -25,
+ -28, -39, -48, -52, -55, -59, -67, -67, -57, -42, -23, -3, 10, 3, -19, -33,
+ -30, -8, 20, 23, 2, -18, -17, 12, 40, 58, 65, 65, 66, 71, 64, 54,
+ 38, 1, -41, -62, -47, -26, -31, -49, -55, -42, -21, -17, -19, -10, -2, -3,
+ -10, -13, 2, 13, -10, -38, -27, 3, 8, -18, -46, -61, -65, -53, -36, -18,
+ -5, -6, -14, -22, -18, -12, -19, -29, -28, -21, -10, -15, -24, -18, -4, 16,
+ 23, 17, 14, 10, 9, 13, 15, 28, 35, 19, 4, 2, -2, 9, 34, 62,
+ 66, 43, 13, -2, 15, 42, 50, 48, 51, 56, 56, 45, 44, 45, 48, 40,
+ 33, 31, 27, 10, -10, -4, 16, 41, 52, 48, 31, -1, -36, -56, -50, -27,
+ -14, -25, -43, -60, -67, -47, -31, -38, -47, -40, -17, 13, 32, 28, -10, -50,
+ -68, -62, -40, -21, -20, -33, -58, -72, -63, -45, -28, -11, 18, 48, 42, 15,
+ -14, -43, -54, -40, -15, 4, 2, -5, 0, 20, 55, 91, 113, 120, 109, 89,
+ 77, 63, 43, 26, 20, 12, -13, -47, -69, -68, -53, -49, -49, -36, -28, -27,
+ -27, -28, -12, 5, 1, -9, -2, 14, 10, -25, -39, -6, 21, 35, 41, 53,
+ 73, 82, 74, 64, 54, 39, 9, -23, -37, -30, -22, -30, -52, -62, -54, -32,
+ -9, 2, 5, -3, -17, -25, -17, -1, 13, 8, -7, -12, -7, -7, -21, -40,
+ -51, -51, -38, -21, -16, -22, -29, -33, -23, -10, -2, -9, -24, -33, -33, -29,
+ -21, -8, 3, 2, -10, -18, -11, 8, 26, 32, 27, 21, 14, 7, 1, 3,
+ 12, 22, 35, 45, 43, 29, 13, 10, 20, 37, 54, 59, 45, 28, 28, 37,
+ 48, 55, 60, 60, 43, 17, 0, -3, 9, 24, 31, 31, 28, 28, 26, 14,
+ -5, -22, -31, -30, -21, -7, -8, -34, -63, -82, -80, -63, -45, -28, -14, -5,
+ 3, 2, -11, -27, -39, -33, -11, 2, -8, -39, -73, -95, -91, -54, -8, 19,
+ 16, 4, 5, 14, 14, 2, -8, -14, -19, -33, -45, -38, -19, 2, 21, 54,
+ 93, 106, 90, 74, 80, 97, 98, 76, 52, 34, 10, -18, -37, -36, -27, -35,
+ -52, -62, -56, -44, -39, -37, -29, -17, -8, -2, 3, 4, -4, -16, -27, -32,
+ -19, 1, 19, 41, 60, 70, 71, 67, 64, 61, 53, 38, 14, -8, -21, -29,
+ -34, -38, -39, -29, -15, 0, 5, -5, -19, -25, -16, 5, 19, 17, 6, -3,
+ -7, 0, -1, 1, -2, -5, 0, 0, 2, 0, -3, -2, 0, 1, 0, -2,
+ -2, -2, 0, 3, 3, -2, -5, -1, -1, -1, -4, 3, 9, 1, -1, -2,
+ -11, -7, 1, 9, 11, 8, -4, -11, -12, -9, -4, 18, 15, 14, 1, -22,
+ -29, -14, 3, 30, 29, 14, -2, -35, -43, -11, 13, 36, 42, 15, -16, -49,
+ -44, -10, 28, 47, 38, 11, -25, -66, -39, 4, 36, 58, 33, -3, -44, -65,
+ -29, 19, 52, 54, 23, -13, -59, -65, -15, 32, 69, 49, 8, -30, -74, -51,
+ 3, 43, 71, 40, -5, -48, -77, -31, 16, 57, 67, 24, -15, -67, -72, -12,
+ 36, 66, 59, 5, -31, -80, -51, 3, 49, 75, 37, -2, -59, -81, -28, 20,
+ 67, 66, 22, -23, -76, -65, -10, 41, 78, 48, 4, -36, -85, -47, 6, 59,
+ 80, 31, -8, -69, -82, -22, 29, 73, 63, 17, -31, -81, -63, -1, 47, 79,
+ 47, 3, -56, -90, -40, 19, 75, 73, 28, -25, -86, -74, -10, 48, 85, 56,
+ 6, -51, -93, -48, 11, 67, 86, 33, -11, -78, -87, -29, 36, 89, 66, 13,
+ -38, -91, -60, 2, 50, 83, 48, 0, -56, -90, -41, 16, 71, 78, 30, -17,
+ -80, -75, -20, 31, 82, 62, 15, -32, -85, -66, -7, 48, 84, 50, 4, -53,
+ -87, -44, 8, 62, 78, 35, -8, -65, -83, -30, 23, 70, 71, 24, -20, -76,
+ -75, -12, 32, 73, 62, 15, -30, -85, -62, -2, 41, 76, 51, 9, -39, -86,
+ -52, 1, 45, 79, 46, 8, -49, -89, -46, 3, 54, 80, 43, 7, -55, -83,
+ -50, 0, 53, 76, 54, 11, -52, -83, -55, 0, 40, 67, 58, 22, -32, -79,
+ -67, -11, 28, 63, 52, 37, -9, -70, -63, -28, 10, 42, 49, 53, 8, -46,
+ -64, -41, 1, 22, 38, 51, 39, -16, -63, -46, -23, 5, 33, 38, 48, 14,
+ -42, -57, -29, -5, 22, 37, 40, 28, -23, -53, -39, -10, 14, 30, 40, 31,
+ -1, -48, -40, -18, 11, 19, 31, 26, 14, -20, -50, -25, -5, 11, 31, 30,
+ 14, 0, -35, -39, -4, -1, 19, 27, 17, 9, -10, -39, -21, -8, 9, 24,
+ 26, 13, -5, -19, -30, -12, -1, 17, 25, 16, 3, -19, -26, -13, -6, 17,
+ 22, 20, 5, -16, -32, -19, -1, 23, 27, 23, 4, -30, -33, -23, -1, 35,
+ 35, 24, -2, -41, -45, -21, 9, 45, 41, 22, -12, -50, -46, -18, 28, 55,
+ 45, 10, -27, -78, -42, 0, 53, 66, 32, -1, -61, -74, -28, 27, 64, 64,
+ 24, -28, -80, -66, -15, 53, 84, 48, 5, -59, -94, -41, 17, 75, 80, 26,
+ -21, -91, -79, -12, 48, 87, 55, 10, -58, -96, -46, 9, 80, 81, 30, -23,
+ -84, -80, -15, 49, 90, 49, 9, -57, -95, -45, 17, 76, 79, 26, -20, -91,
+ -75, -18, 52, 90, 52, 6, -59, -92, -41, 15, 68, 80, 31, -21, -87, -76,
+ -13, 45, 87, 49, 11, -60, -94, -35, 14, 80, 68, 22, -23, -89, -66, -7,
+ 47, 93, 44, -8, -61, -95, -31, 24, 86, 75, 10, -35, -96, -66, -1, 61,
+ 100, 44, -12, -77, -105, -33, 32, 97, 92, 16, -44, -111, -90, -5, 65, 121,
+ 65, -3, -80, -123, -59, 17, 98, 111, 46, -25, -112, -109, -33, 42, 112, 90,
+ 30, -55, -115, -84, -17, 66, 105, 71, 13, -73, -113, -61, 0, 77, 96, 56,
+ 4, -80, -108, -50, 8, 78, 93, 47, 3, -88, -98, -40, 7, 65, 76, 53,
+ 18, -71, -90, -44, 0, 39, 57, 43, 34, -19, -69, -54, -19, 18, 32, 31,
+ 34, 7, -40, -36, -21, -1, 12, 12, 25, 27, -9, -32, -14, -14, 2, 0,
+ 1, 20, 19, -2, -13, -11, -18, -12, -2, 18, 24, 12, -2, -14, -19, -19,
+ -12, 18, 24, 22, -2, -15, -32, -20, 3, 22, 26, 17, -13, -31, -27, -13,
+ 17, 33, 32, 5, -29, -47, -29, 2, 33, 42, 32, -6, -53, -52, -24, 22,
+ 51, 41, 27, -32, -74, -45, 0, 45, 59, 33, -1, -62, -66, -31, 26, 73,
+ 49, 17, -42, -80, -42, -8, 63, 72, 28, -10, -75, -72, -23, 32, 88, 47,
+ 13, -56, -93, -38, 10, 76, 69, 26, -20, -96, -66, -10, 48, 90, 47, 0,
+ -69, -103, -29, 25, 87, 73, 18, -35, -104, -68, -2, 61, 93, 47, -5, -83,
+ -98, -31, 30, 92, 68, 17, -39, -97, -63, -5, 64, 88, 35, -9, -74, -86,
+ -22, 31, 85, 54, 13, -44, -93, -46, 9, 65, 75, 23, -17, -75, -78, -15,
+ 39, 84, 54, 3, -52, -96, -46, 12, 71, 90, 29, -18, -89, -87, -26, 36,
+ 86, 72, 26, -37, -106, -77, -12, 45, 99, 68, 22, -46, -108, -73, -10, 43,
+ 87, 69, 19, -27, -92, -79, -12, 27, 63, 57, 26, 4, -53, -75, -35, 12,
+ 33, 37, 31, 26, -9, -53, -39, -16, 6, 20, 23, 22, 13, -8, -22, -23,
+ -18, -3, 9, 25, 19, 4, -8, -20, -17, -10, 6, 16, 17, 13, -8, -34,
+ -21, -6, 17, 33, 23, 6, -32, -51, -23, 11, 36, 46, 31, -11, -46, -65,
+ -31, 15, 59, 55, 28, -20, -73, -64, -26, 42, 78, 51, 14, -53, -85, -48,
+ -4, 70, 80, 38, -16, -80, -76, -32, 39, 90, 58, 19, -59, -99, -50, 14,
+ 71, 75, 36, -21, -94, -70, -23, 51, 88, 53, 9, -68, -97, -40, 16, 83,
+ 73, 29, -33, -100, -61, -13, 58, 87, 41, 0, -74, -81, -35, 24, 87, 55,
+ 20, -41, -88, -58, 0, 69, 73, 34, -5, -86, -75, -20, 38, 79, 49, 13,
+ -48, -90, -39, 2, 71, 68, 31, -16, -84, -67, -15, 38, 79, 42, 12, -50,
+ -85, -37, 2, 62, 71, 34, -5, -83, -75, -24, 27, 82, 51, 27, -30, -88,
+ -54, -15, 44, 73, 50, 16, -49, -81, -47, -6, 38, 58, 50, 27, -31, -69,
+ -52, -13, 15, 36, 45, 33, -5, -41, -44, -23, 2, 14, 27, 33, 10, -25,
+ -20, -18, -6, 1, -1, 17, 22, 3, -13, -10, -17, -13, -6, 13, 24, 15,
+ 1, -11, -19, -19, -16, 12, 24, 24, 3, -12, -29, -26, -1, 18, 27, 19,
+ -4, -31, -28, -19, 11, 30, 35, 12, -21, -46, -35, -6, 28, 42, 36, 5,
+ -46, -57, -31, 10, 50, 43, 33, -16, -71, -55, -9, 35, 62, 38, 10, -51,
+ -71, -40, 11, 69, 58, 24, -26, -81, -50, -18, 48, 79, 37, 1, -62, -81,
+ -32, 16, 84, 59, 20, -37, -96, -50, -2, 63, 78, 33, -4, -85, -80, -20,
+ 33, 88, 59, 10, -50, -107, -47, 14, 75, 85, 27, -19, -95, -83, -15, 47,
+ 94, 60, 8, -66, -105, -46, 15, 83, 81, 26, -23, -91, -76, -18, 48, 92,
+ 47, 1, -59, -94, -36, 18, 78, 66, 19, -27, -91, -60, -3, 53, 80, 35,
+ -8, -62, -86, -28, 27, 79, 66, 13, -38, -94, -62, 1, 56, 95, 42, -6,
+ -75, -96, -39, 22, 80, 80, 36, -20, -97, -92, -24, 30, 93, 79, 32, -27,
+ -102, -87, -22, 31, 81, 79, 29, -14, -81, -91, -25, 19, 56, 63, 31, 11,
+ -39, -77, -47, 3, 31, 37, 33, 27, 3, -48, -46, -20, 0, 18, 22, 23,
+ 16, -3, -20, -19, -15, -4, 2, 8, 5, 0, 0, 0, 0, 2, 2, 5,
+ 9, 12, 14, 12, 7, 6, 4, 0, -1, -1, 1, -2, -2, -11, -17, -32,
+ -41, -49, -55, -58, -61, -61, -65, -61, -57, -47, -37, -27, -22, -15, -5, 6,
+ 12, 16, 21, 27, 28, 32, 33, 35, 41, 44, 45, 47, 50, 54, 57, 56,
+ 53, 53, 54, 50, 50, 52, 54, 56, 52, 53, 54, 50, 49, 46, 43, 38,
+ 33, 27, 19, 8, 2, -11, -20, -27, -29, -30, -32, -35, -42, -52, -57, -57,
+ -59, -48, -40, -27, -13, 4, 13, 20, 18, 14, 11, 7, 3, -1, -3, -10,
+ -11, -20, -28, -46, -60, -72, -82, -92, -97, -97, -97, -94, -90, -81, -71, -61,
+ -55, -55, -53, -47, -38, -29, -23, -11, -6, -3, 1, 2, 5, 6, 3, 3,
+ 5, 15, 24, 28, 30, 30, 35, 37, 36, 39, 39, 44, 47, 48, 56, 62,
+ 73, 84, 91, 96, 95, 91, 85, 76, 72, 63, 55, 47, 44, 43, 41, 38,
+ 31, 19, 7, 0, -9, -7, -4, 8, 22, 40, 54, 67, 71, 70, 64, 56,
+ 45, 32, 24, 15, 12, 3, -3, -21, -42, -66, -84, -102, -117, -124, -128, -127,
+ -124, -118, -107, -96, -86, -86, -88, -86, -80, -70, -63, -50, -40, -33, -25, -23,
+ -20, -18, -18, -21, -25, -22, -14, -8, -3, -3, -1, 1, 0, 1, -3, -1,
+ 2, 4, 13, 24, 35, 49, 59, 67, 70, 69, 68, 59, 54, 46, 40, 31,
+ 29, 27, 25, 23, 20, 12, -1, -9, -19, -22, -21, -11, 3, 23, 41, 60,
+ 71, 76, 73, 71, 65, 56, 50, 44, 42, 35, 33, 24, 9, -13, -31, -48,
+ -65, -76, -83, -83, -82, -77, -69, -59, -46, -40, -40, -41, -38, -30, -24, -13,
+ -2, 8, 17, 22, 24, 25, 23, 20, 13, 9, 11, 15, 19, 16, 12, 9,
+ 4, 1, -6, -10, -11, -14, -12, -5, 3, 15, 26, 35, 40, 41, 41, 35,
+ 28, 19, 12, 3, -2, -6, -7, -10, -13, -19, -31, -39, -50, -56, -58, -52,
+ -41, -22, -3, 18, 34, 46, 48, 47, 45, 38, 32, 26, 24, 20, 19, 15,
+ 5, -14, -32, -49, -65, -79, -88, -91, -91, -88, -82, -75, -63, -52, -47, -46,
+ -46, -38, -31, -21, -8, 4, 17, 26, 31, 36, 39, 42, 40, 35, 36, 39,
+ 47, 48, 45, 43, 38, 36, 30, 24, 22, 19, 18, 23, 29, 40, 50, 61,
+ 68, 72, 74, 71, 66, 57, 50, 40, 32, 24, 21, 16, 12, 7, -3, -14,
+ -26, -38, -45, -46, -43, -31, -16, 3, 18, 33, 39, 39, 36, 31, 22, 13,
+ 8, 3, -1, -4, -9, -24, -42, -60, -77, -94, -107, -115, -119, -120, -116, -112,
+ -103, -91, -81, -78, -80, -75, -69, -61, -51, -39, -25, -13, -5, 2, 8, 14,
+ 17, 16, 15, 16, 24, 31, 32, 32, 29, 29, 27, 22, 21, 20, 19, 22,
+ 26, 35, 46, 59, 70, 77, 83, 85, 84, 79, 74, 66, 59, 50, 46, 41,
+ 38, 35, 29, 21, 11, 0, -9, -14, -16, -11, 0, 16, 30, 48, 58, 62,
+ 61, 58, 51, 40, 31, 25, 19, 15, 13, 4, -11, -28, -44, -61, -76, -87,
+ -95, -100, -100, -99, -95, -86, -75, -68, -69, -68, -67, -62, -56, -49, -38, -27,
+ -19, -13, -9, -3, 2, 1, -1, -3, 0, 7, 10, 10, 6, 5, 4, 0,
+ -4, -5, -7, -7, -7, -2, 5, 16, 27, 36, 44, 49, 52, 50, 46, 40,
+ 35, 26, 22, 18, 15, 15, 13, 9, 4, -5, -14, -19, -23, -21, -14, 0,
+ 15, 33, 49, 60, 63, 63, 61, 53, 44, 38, 32, 27, 27, 23, 14, 0,
+ -14, -29, -44, -58, -67, -74, -76, -76, -73, -67, -55, -45, -41, -41, -41, -39,
+ -35, -30, -23, -12, -3, 4, 9, 14, 20, 21, 20, 17, 15, 19, 24, 26,
+ 24, 21, 20, 18, 12, 9, 6, 3, 0, 1, 4, 11, 21, 30, 38, 43,
+ 47, 48, 45, 38, 32, 23, 15, 9, 5, 3, 1, -2, -5, -13, -22, -30,
+ -37, -41, -40, -30, -18, -3, 15, 30, 38, 41, 41, 37, 27, 19, 12, 6,
+ 3, 2, -2, -13, -25, -39, -53, -67, -78, -88, -92, -92, -91, -86, -77, -63,
+ -54, -50, -48, -47, -43, -38, -32, -23, -11, -1, 6, 11, 19, 25, 27, 26,
+ 24, 26, 31, 36, 38, 36, 37, 37, 34, 32, 29, 27, 24, 22, 23, 27,
+ 35, 45, 53, 61, 67, 70, 71, 66, 60, 51, 42, 34, 28, 24, 21, 18,
+ 16, 11, 2, -8, -16, -24, -28, -25, -17, -5, 10, 26, 39, 45, 47, 45,
+ 37, 27, 18, 9, 3, 0, -2, -10, -22, -36, -51, -67, -81, -93, -102, -107,
+ -108, -107, -102, -90, -78, -71, -67, -66, -63, -59, -56, -49, -39, -28, -19, -13,
+ -6, 1, 7, 8, 6, 5, 8, 14, 19, 19, 19, 20, 20, 19, 16, 15,
+ 13, 12, 11, 13, 20, 30, 39, 49, 57, 63, 68, 68, 65, 58, 51, 43,
+ 37, 32, 29, 27, 26, 24, 19, 11, 2, -5, -12, -14, -9, 0, 13, 30,
+ 46, 56, 62, 65, 61, 53, 44, 35, 26, 22, 20, 15, 6, -6, -20, -36,
+ -51, -66, -78, -87, -91, -92, -92, -85, -74, -65, -58, -56, -55, -52, -50, -46,
+ -40, -30, -20, -14, -8, -2, 5, 7, 6, 3, 2, 5, 10, 11, 10, 9,
+ 9, 8, 5, 2, 0, -2, -5, -5, -3, 5, 14, 23, 32, 39, 46, 50,
+ 49, 45, 38, 31, 24, 17, 14, 11, 10, 9, 7, 2, -5, -12, -20, -25,
+ -25, -19, -8, 7, 24, 40, 50, 58, 60, 56, 49, 41, 31, 24, 22, 20,
+ 15, 6, -5, -19, -34, -48, -61, -72, -79, -83, -85, -81, -72, -62, -52, -47,
+ -44, -41, -39, -35, -31, -24, -13, -5, 1, 7, 14, 20, 22, 21, 19, 18,
+ 22, 25, 25, 24, 23, 23, 20, 17, 15, 12, 10, 7, 5, 9, 16, 24,
+ 33, 40, 47, 53, 56, 54, 48, 41, 33, 25, 20, 15, 11, 9, 8, 5,
+ -2, -10, -19, -27, -32, -31, -25, -15, 0, 17, 30, 40, 46, 46, 42, 35,
+ 25, 15, 10, 9, 5, -2, -11, -23, -37, -52, -65, -79, -89, -95, -99, -100,
+ -95, -85, -74, -65, -60, -55, -52, -48, -44, -40, -29, -18, -10, -4, 4, 12,
+ 18, 20, 19, 17, 20, 24, 27, 27, 26, 26, 25, 23, 21, 19, 17, 15,
+ 12, 13, 17, 25, 34, 41, 49, 57, 62, 65, 63, 57, 51, 42, 35, 30,
+ 25, 22, 21, 19, 15, 8, 0, -9, -17, -21, -20, -14, -3, 13, 26, 38,
+ 48, 53, 52, 47, 39, 28, 19, 15, 13, 8, 0, -10, -22, -37, -51, -65,
+ -79, -88, -95, -100, -99, -94, -84, -74, -67, -61, -58, -55, -51, -49, -43, -33,
+ -23, -17, -10, -2, 6, 10, 11, 9, 9, 12, 15, 17, 16, 16, 16, 14,
+ 12, 11, 9, 8, 5, 3, 4, 10, 18, 26, 34, 42, 50, 57, 59, 57,
+ 52, 45, 38, 32, 27, 23, 21, 20, 19, 14, 8, 1, -9, 2, 5, 7,
+ 8, -1, 6, 15, 1, 20, 28, 1, 37, 41, 31, 29, 27, 61, 40, -12,
+ 38, 52, -16, -20, -1, -23, -48, -56, -63, -61, -77, -100, -88, -76, -103, -113,
+ -98, -103, -118, -120, -108, -107, -104, -110, -118, -104, -109, -128, -107, -83, -106, -86,
+ -94, -100, -77, -113, -88, -43, -77, -46, -44, -69, -34, -54, -39, 4, -30, 11,
+ 18, -25, 20, 16, 10, 52, 35, 52, 74, 33, 55, 74, 59, 70, 81, 85,
+ 91, 81, 72, 89, 94, 82, 80, 99, 100, 85, 86, 91, 100, 91, 81, 91,
+ 102, 83, 74, 92, 95, 63, 62, 75, 71, 63, 39, 54, 74, 15, 1, 31,
+ 6, -5, -13, -20, -8, -44, -59, -38, -69, -73, -67, -86, -90, -68, -73, -77,
+ -49, -82, -70, -43, -76, -27, 0, -29, 22, 25, -5, 44, 45, 29, 66, 71,
+ 49, 84, 92, 73, 92, 74, 72, 91, 37, 48, 99, 47, 31, 44, 36, 33,
+ -5, -11, 26, 6, -33, -22, -6, -32, -55, -44, -45, -52, -63, -73, -55, -51,
+ -77, -79, -61, -73, -91, -83, -70, -77, -74, -82, -85, -68, -88, -98, -57, -67,
+ -77, -58, -75, -66, -64, -78, -33, -37, -50, -19, -47, -38, -23, -41, 3, 6,
+ -7, 30, 0, -4, 24, 15, 31, 45, 44, 66, 44, 34, 58, 54, 59, 67,
+ 71, 87, 78, 60, 73, 84, 78, 76, 86, 95, 89, 76, 85, 94, 89, 73,
+ 82, 99, 85, 66, 75, 93, 75, 50, 56, 69, 59, 31, 31, 61, 29, -15,
+ 15, 5, -15, -14, -36, -25, -29, -69, -55, -53, -82, -78, -76, -95, -88, -69,
+ -80, -65, -63, -86, -58, -67, -59, -12, -28, -9, 29, -8, 13, 44, 22, 44,
+ 68, 53, 62, 91, 74, 81, 89, 64, 84, 78, 35, 78, 86, 44, 43, 47,
+ 45, 22, -5, 17, 21, -16, -24, -14, -14, -34, -50, -40, -36, -63, -71, -58,
+ -60, -69, -78, -78, -67, -81, -98, -78, -71, -89, -85, -84, -86, -82, -99, -82,
+ -60, -76, -75, -74, -76, -71, -86, -68, -37, -51, -34, -41, -57, -37, -51, -31,
+ -7, -17, -3, 1, 7, 22, 31, 46, 57, 41, 43, 56, 63, 62, 68, 85,
+ 86, 80, 84, 92, 96, 93, 93, 104, 105, 96, 99, 108, 106, 102, 98, 102,
+ 111, 99, 87, 106, 110, 85, 80, 88, 89, 79, 68, 70, 81, 48, 25, 39,
+ 32, 18, 9, 12, 0, -29, -31, -38, -60, -52, -63, -79, -71, -66, -62, -59,
+ -62, -74, -72, -73, -81, -43, -21, -28, 8, 10, -10, 16, 28, 27, 42, 50,
+ 47, 66, 76, 68, 81, 73, 67, 72, 39, 40, 67, 41, 23, 25, 22, 12,
+ -16, -22, -5, -27, -51, -44, -45, -57, -68, -73, -71, -74, -91, -89, -84, -90,
+ -97, -98, -98, -102, -105, -108, -103, -97, -105, -109, -101, -107, -113, -106, -92, -87,
+ -90, -92, -92, -92, -100, -92, -57, -56, -54, -40, -59, -58, -54, -61, -23, -9,
+ -12, 16, 0, -14, 4, 5, 17, 32, 41, 57, 55, 43, 54, 66, 67, 68,
+ 84, 89, 87, 87, 91, 98, 100, 96, 104, 109, 105, 103, 108, 111, 109, 105,
+ 105, 113, 111, 99, 102, 115, 104, 88, 90, 97, 93, 80, 75, 86, 75, 37,
+ 40, 43, 33, 20, 20, -14, -26, -36, -53, -52, -65, -75, -75, -69, -69, -69,
+ -74, -77, -76, -74, -59, -34, -26, -9, 9, 5, 13, 32, 39, 42, 53, 58,
+ 61, 73, 77, 77, 73, 61, 57, 46, 29, 37, 37, 17, 6, 2, -10, -27,
+ -38, -41, -46, -58, -68, -69, -75, -85, -89, -92, -97, -101, -103, -106, -107, -108,
+ -112, -111, -112, -115, -115, -115, -113, -111, -116, -115, -112, -116, -117, -110, -101, -98,
+ -101, -101, -98, -101, -101, -86, -69, -65, -59, -57, -62, -58, -54, -39, -19, -12,
+ 1, 7, -1, 5, 16, 24, 36, 46, 58, 64, 61, 64, 74, 79, 81, 90,
+ 96, 97, 100, 100, 104, 108, 107, 111, 114, 113, 115, 115, 115, 118, 117, 116,
+ 118, 119, 116, 115, 116, 117, 111, 104, 105, 107, 99, 93, 95, 91, 71, 57,
+ 53, 47, 38, 29, 23, 14, -11, -28, -38, -49, -58, -67, -73, -80, -84, -84,
+ -83, -82, -80, -78, -74, -67, -56, -42, -29, -16, -4, 7, 18, 29, 40, 49,
+ 57, 64, 70, 74, 78, 79, 77, 72, 67, 60, 53, 48, 42, 33, 23, 14,
+ 4, -6, -16, -24, -32, -40, -48, -55, -61, -68, -74, -78, -83, -87, -91, -94,
+ -96, -99, -101, -103, -104, -106, -107, -107, -107, -107, -107, -108, -107, -107, -107, -105,
+ -101, -98, -96, -94, -93, -91, -87, -82, -74, -67, -62, -57, -54, -49, -43, -35,
+ -25, -16, -7, -1, 4, 10, 17, 25, 33, 41, 49, 55, 59, 63, 69, 74,
+ 78, 83, 88, 91, 93, 96, 98, 100, 102, 104, 106, 107, 107, 108, 108, 109,
+ 109, 108, 108, 108, 107, 105, 104, 102, 99, 94, 91, 87, 83, 78, 73, 66,
+ 56, 46, 37, 28, 19, 9, 0, -11, -23, -35, -45, -55, -64, -71, -78, -83,
+ -85, -84, -83, -81, -79, -75, -70, -61, -49, -36, -23, -10, 2, 12, 24, 35,
+ 45, 53, 61, 67, 72, 76, 79, 78, 75, 70, 65, 58, 52, 46, 39, 29,
+ 20, 11, 1, -9, -18, -26, -34, -42, -50, -56, -63, -69, -74, -79, -83, -88,
+ -91, -94, -96, -98, -101, -102, -104, -105, -106, -106, -106, -106, -106, -106, -106, -106,
+ -105, -102, -98, -96, -94, -92, -90, -88, -84, -77, -70, -64, -59, -55, -51, -45,
+ -38, -29, -20, -11, -4, 2, 7, 13, 21, 29, 37, 44, 51, 56, 60, 65,
+ 70, 75, 80, 84, 88, 91, 93, 96, 98, 100, 102, 104, 105, 106, 107, 107,
+ 108, 108, 107, 107, 107, 106, 104, 103, 101, 99, 95, 91, 87, 83, 78, 73,
+ 67, 59, 49, 39, 30, 21, 12, 3, -8, -19, -31, -41, -51, -60, -68, -75,
+ -81, -84, -85, -84, -82, -80, -77, -73, -65, -55, -42, -29, -16, -4, 7, 18,
+ 29, 40, 49, 57, 64, 70, 74, 78, 79, 77, 73, 68, 62, 56, 50, 44,
+ 36, 26, 17, 7, -3, -12, -20, -28, -36, -44, -51, -58, -64, -70, -75, -79,
+ -84, -88, -91, -93, -96, -98, -100, -102, -103, -105, -105, -105, -105, -105, -105, -105,
+ -105, -104, -102, -99, -96, -94, -92, -90, -88, -85, -79, -72, -66, -61, -56, -52,
+ -47, -41, -33, -24, -15, -8, -1, 4, 10, 17, 24, 32, 40, 47, 53, 57,
+ 62, 67, 72, 77, 81, 85, 89, 91, 94, 96, 98, 100, 102, 104, 105, 105,
+ 106, 106, 107, 106, 106, 106, 105, 104, 102, 101, 99, 95, 91, 87, 83, 79,
+ 74, 68, 61, 52, 42, 33, 24, 15, 5, -5, -15, -27, -38, -48, -57, -66,
+ -72, -79, -83, -85, -85, -83, -81, -79, -75, -69, -60, -48, -35, -23, -10, 2,
+ 13, 24, 35, 45, 54, 61, 67, 72, 77, 78, 79, 76, 72, 66, 60, 54,
+ 49, 41, 32, 23, 12, 3, -4, -17, -15, 1, -1, 0, 0, 1, 3, 5,
+ 9, 13, 18, 24, 32, 38, 32, 18, -9, -48, -73, -41, 2, -3, -24, -34,
+ -44, -72, -111, -124, -62, 40, 40, -51, -35, 45, 46, -22, -79, 35, 78, -47,
+ -98, -88, -69, -57, -44, -31, -17, -9, -3, 6, 41, 85, 43, -91, -128, -65,
+ -25, -21, -19, -12, 2, 16, 29, 39, 49, 48, 10, -69, -47, 50, 8, -52,
+ -44, 5, 21, -40, -42, 33, 79, 66, 38, 24, 25, 26, 18, 21, 70, 117,
+ 98, 28, -1, 20, 22, 0, 1, 9, -10, -49, -33, 39, 68, 39, -5, -17,
+ -58, -76, 78, 104, 17, 6, -23, -43, -13, 58, 85, 43, 21, 35, 46, 31,
+ 22, 35, 14, -48, -74, -38, 6, 10, -8, -17, -24, -37, -60, -69, -41, 15,
+ 27, -21, -26, 18, 28, -1, -41, 5, 51, -9, -51, -48, -38, -31, -24, -16,
+ -8, -2, 1, 6, 23, 52, 41, -39, -83, -50, -19, -13, -12, -8, 1, 10,
+ 20, 27, 34, 35, 15, -40, -46, 27, 16, -35, -38, -6, 19, -18, -35, 17,
+ 61, 55, 33, 21, 22, 25, 21, 18, 52, 98, 92, 31, -5, 9, 17, -1,
+ -2, 7, -7, -47, -43, 24, 62, 39, -3, -20, -48, -88, 46, 113, 25, 4,
+ -20, -45, -25, 42, 82, 47, 19, 28, 42, 32, 18, 30, 19, -39, -77, -51,
+ -4, 10, -6, -18, -25, -37, -57, -70, -50, 4, 26, -15, -33, 9, 27, 6,
+ -38, -12, 50, 6, -47, -50, -40, -32, -25, -17, -10, -3, 0, 4, 17, 45,
+ 47, -23, -82, -60, -24, -14, -13, -10, -2, 7, 16, 24, 30, 33, 18, -32,
+ -56, 13, 23, -31, -41, -15, 19, -6, -35, 4, 52, 55, 35, 21, 22, 25,
+ 22, 15, 41, 89, 94, 38, -5, 4, 16, 2, -2, 7, -4, -41, -48, 12,
+ 58, 43, 2, -20, -38, -89, 14, 118, 38, 3, -15, -43, -32, 28, 78, 53,
+ 19, 24, 40, 34, 18, 26, 23, -28, -75, -61, -14, 10, -2, -16, -24, -34,
+ -53, -68, -55, -7, 25, -8, -36, 1, 27, 12, -31, -26, 45, 22, -39, -50,
+ -41, -32, -25, -17, -10, -4, 0, 3, 13, 38, 51, -5, -77, -69, -31, -15,
+ -14, -11, -4, 5, 13, 21, 27, 31, 20, -24, -61, -3, 28, -23, -43, -23,
+ 15, 5, -32, -6, 43, 53, 36, 22, 21, 26, 24, 14, 32, 79, 95, 46,
+ -3, 0, 15, 5, -1, 7, -1, -36, -52, 2, 53, 46, 7, -18, -30, -84,
+ -15, 114, 55, 4, -10, -40, -37, 15, 72, 59, 22, 20, 36, 36, 19, 23,
+ 26, -18, -70, -68, -25, 7, 2, -13, -22, -32, -49, -65, -59, -16, 22, -1,
+ -36, -8, 25, 17, -22, -35, 34, 36, -29, -48, -42, -32, -25, -18, -10, -4,
+ 0, 3, 10, 32, 52, 11, -67, -76, -38, -16, -13, -11, -6, 3, 11, 19,
+ 25, 30, 22, -15, -62, -19, 30, -14, -43, -30, 9, 13, -25, -15, 33, 51,
+ 37, 23, 21, 26, 26, 15, 24, 68, 94, 54, 0, -3, 13, 8, 1, 8,
+ 2, -30, -53, -8, 47, 49, 13, -16, -25, -75, -41, 102, 73, 6, -5, -36,
+ -40, 2, 65, 64, 25, 18, 33, 37, 21, 21, 27, -8, -63, -73, -36, 2,
+ 5, -10, -21, -30, -45, -62, -61, -25, 17, 5, -35, -17, 21, 21, -13, -39,
+ 20, 46, -16, -46, -42, -32, -25, -17, -10, -4, 0, 3, 8, 27, 50, 25,
+ -54, -81, -46, -19, -13, -12, -7, 1, 9, 17, 23, 28, 23, -8, -59, -35,
+ 27, -5, -42, -35, 2, 20, -16, -20, 24, 47, 38, 24, 21, 27, 28, 17,
+ 18, 58, 91, 62, 5, -6, 10, 10, 3, 9, 5, -24, -52, -17, 40, 50,
+ 18, -13, -22, -64, -60, 83, 90, 12, -3, -31, -41, -8, 55, 67, 30, 17,
+ 30, 37, 24, 19, 27, 1, -54, -75, -46, -4, 7, -7, -18, -28, -41, -58,
+ -61, -32, 11, 10, -31, -24, 17, 23, -4, -39, 5, 52, -2, -42, -42, -32,
+ -25, -17, -10, -4, 0, 3, 6, 22, 47, 35, -38, -82, -55, -23, -13, -12,
+ -8, -1, 7, 15, 21, 26, 23, -1, -53, -48, 20, 5, -39, -39, -6, 22,
+ -5, -22, 14, 43, 38, 25, 21, 27, 29, 19, 15, 47, 86, 68, 12, -7,
+ 7, 11, 4, 10, 7, -18, -50, -25, 33, 51, 24, -10, -20, -52, -72, 58,
+ 103, 21, -1, -26, -41, -17, 44, 67, 35, 16, 27, 36, 26, 18, 25, 8,
+ -45, -76, -55, -13, 7, -3, -16, -26, -38, -55, -61, -38, 4, 13, -26, -30,
+ 11, 25, 4, -36, -10, 51, 14, -37, -42, -33, -24, -17, -10, -4, 1, 3,
+ 6, 18, 42, 42, -22, -80, -63, -28, -14, -12, -9, -3, 5, 12, 19, 24,
+ 23, 3, -46, -58, 9, 14, -34, -41, -14, 21, 6, -21, 4, 36, 38, 26,
+ 21, 26, 30, 22, 13, 37, 78, 73, 20, -7, 4, 11, 6, 10, 10, -11,
+ -45, -33, 22, 49, 29, -4, -18, -40, -75, 23, 108, 40, 1, -18, -39, -26,
+ 28, 65, 42, 17, 22, 34, 29, 18, 23, 15, -30, -71, -65, -27, 3, 2,
+ -11, -22, -34, -49, -58, -45, -7, 13, -16, -35, -1, 24, 13, -23, -26, 37,
+ 36, -20, -39, -34, -24, -17, -10, -4, 1, 3, 5, 12, 33, 46, 6, -64,
+ -75, -40, -17, -12, -10, -5, 2, 9, 15, 20, 22, 10, -30, -65, -18, 20,
+ -19, -42, -27, 11, 21, -8, -8, 22, 34, 27, 22, 26, 31, 27, 14, 22,
+ 60, 75, 34, -4, -2, 8, 8, 11, 14, -2, -36, -42, 6, 44, 36, 4,
+ -15, -26, -66, -24, 95, 71, 8, -10, -33, -32, 7, 56, 51, 21, 17, 29,
+ 32, 20, 19, 20, -12, -59, -72, -45, -8, 5, -5, -17, -28, -42, -54, -50,
+ -21, 9, -5, -36, -16, 19, 21, -7, -34, 12, 51, 4, -33, -34, -25, -17,
+ -10, -4, 1, 4, 5, 9, 23, 44, 29, -39, -79, -55, -24, -13, -10, -7,
+ -1, 6, 12, 16, 20, 14, -15, -62, -46, 16, -2, -39, -36, -2, 29, 9,
+ -12, 8, 28, 27, 23, 25, 31, 31, 17, 13, 43, 72, 46, 2, -5, 5,
+ 8, 11, 16, 5, -26, -44, -8, 36, 40, 12, -12, -19, -52, -53, 67, 94,
+ 20, -5, -27, -35, -7, 45, 55, 27, 15, 25, 32, 23, 17, 21, 0, -47,
+ -73, -57, -19, 4, 0, -13, -24, -37, -50, -51, -29, 3, 1, -32, -26, 12,
+ 23, 3, -32, -6, 52, 22, -26, -34, -25, -17, -10, -4, 1, 5, 6, 8,
+ 18, 39, 38, -21, -76, -64, -30, -14, -10, -8, -2, 4, 10, 15, 18, 14,
+ -9, -56, -57, 7, 7, -35, -39, -10, 27, 18, -10, 2, 23, 26, 23, 24,
+ 31, 32, 20, 11, 35, 67, 51, 7, -6, 3, 8, 11, 17, 8, -20, -44,
+ -15, 31, 41, 16, -9, -17, -43, -61, 44, 102, 31, -2, -23, -35, -15, 36,
+ 56, 32, 0, -27, 1, -1, -1, 3, -4, -2, 1, -1, -2, 2, 3, -6,
+ 1, 2, -6, 2, 2, -4, -1, 2, -5, 1, 4, -4, 0, -1, 0, -1,
+ -2, 2, 2, -6, 0, 4, -3, -3, 4, -2, -3, -2, 0, 1, 1, -2,
+ -2, 3, -8, 27, -42, 11, 21, -35, 34, -25, 12, 9, -24, 14, 13, -38,
+ 53, -42, -3, 46, -73, 55, -16, -9, 28, -49, 38, -12, -21, 49, -51, 20,
+ 32, -73, 64, -28, -7, 32, -50, 42, -11, -30, 49, -21, -31, 46, -25, -7,
+ 20, -22, 18, -16, -10, 21, -23, 5, 28, -35, 8, 0, 8, -26, 19, 6,
+ -11, -20, 64, -46, -18, 51, -73, 119, -117, 46, 36, -80, 67, -46, 22, 0,
+ -24, 56, -59, 14, 26, -40, 24, -9, 20, -20, -15, 43, -26, -11, 9, 14,
+ -3, -31, 6, 54, -62, 3, 67, -78, 20, 21, -25, 31, -41, 18, 27, -53,
+ 32, 15, -48, 37, -11, 4, -12, -3, 31, -24, -21, 42, -10, -45, 55, -32,
+ 34, -43, -14, 86, -78, 8, 39, -35, -2, 13, 2, 5, -11, -4, 7, 5,
+ -31, 37, -4, -28, 28, -9, -11, 10, -1, 4, -18, 17, -9, -13, 24, -18,
+ 20, -18, -30, 59, -25, -29, 48, -15, -29, 23, 4, -3, -18, 14, 6, -8,
+ -19, 19, 8, -13, 0, 13, -18, 4, 1, 0, 0, 10, -14, -12, 39, -46,
+ 23, 9, -22, 23, -20, -22, 63, -42, -28, 77, -66, 12, 38, -56, 31, 27,
+ -77, 66, -11, -39, 59, -33, -41, 92, -54, -50, 96, -36, -46, 46, -17, 31,
+ -43, -28, 98, -57, -50, 84, -22, -44, 39, -8, 17, -28, -13, 63, -67, 16,
+ 10, 3, -15, -4, 36, -34, -1, 26, -27, -2, 13, 7, -22, 0, 27, -11,
+ -19, 6, 26, -42, 14, 18, -7, -14, -10, 37, -14, -24, 25, -4, -5, -10,
+ 3, 35, -39, -7, 31, -8, -23, 15, 4, -1, -25, 28, 7, -35, 34, -16,
+ -1, 9, -35, 45, -22, -17, 48, -52, 24, 22, -65, 48, 7, -45, 47, -19,
+ -33, 71, -70, 46, -7, -52, 68, -25, -35, 48, -13, -17, 14, 2, -12, 8,
+ -10, 1, 22, -32, 4, 34, -26, -18, 29, -7, -19, 15, -7, 15, -8, -29,
+ 50, -22, -35, 53, -19, -37, 47, -9, -40, 41, 1, -27, 7, 3, 0, 0,
+ -7, 13, -7, -21, 26, 14, -44, 11, 40, -51, 10, 26, -28, 16, -13, -3,
+ 31, -42, 11, 34, -52, 11, 34, -43, 10, 29, -19, -21, 27, -10, -5, 10,
+ -14, 11, 3, -35, 43, 3, -52, 37, 22, -66, 49, -12, -19, 50, -58, 16,
+ 42, -70, 50, -2, -42, 60, -69, 43, 11, -57, 54, -8, -31, 23, -8, -7,
+ 24, -32, 11, 21, -51, 60, -44, -6, 68, -87, 33, 45, -79, 50, -7, -13,
+ 21, -40, 31, 12, -41, 18, 24, -39, 15, 7, -17, 25, -20, -12, 43, -47,
+ 17, 6, -16, 10, 4, -11, -1, 14, -10, -7, 6, 9, -23, 9, 3, 13,
+ -30, 16, 16, -33, 17, 4, -17, 23, -29, 3, 54, -86, 50, 11, -41, 30,
+ -23, 15, 18, -60, 56, 7, -65, 49, -4, -12, 1, -6, 19, -4, -33, 35,
+ -10, -12, 13, -2, -2, -2, 2, -10, 16, -8, -11, 19, -6, -19, 24, -14,
+ 9, 3, -24, 24, -6, -13, 19, -11, -6, 6, -9, 16, -8, -10, 14, -10,
+ -1, -5, 16, -8, -25, 37, -11, -27, 37, -14, -13, 19, -17, 14, -5, -15,
+ 26, -27, 10, 11, -23, 22, -5, -19, 25, -7, -28, 44, -35, 0, 25, -31,
+ 31, -10, -26, 46, -41, 2, 33, -40, 24, 8, -43, 44, -12, -25, 37, -25,
+ -6, 29, -27, 5, 24, -40, 24, -1, -25, 23, -1, -6, -2, -1, 14, -24,
+ 8, 13, -11, 0, -13, 16, 15, -56, 43, 12, -35, 14, -9, 18, -10, -19,
+ 28, -3, -27, 23, -2, -14, 27, -35, 10, 35, -68, 44, 7, -43, 46, -21,
+ -25, 56, -35, -21, 51, -33, -8, 28, -27, 19, -2, -26, 36, -26, 3, 13,
+ -12, 6, -10, 8, -14, 15, -12, 0, 13, -9, -16, 32, -27, 3, 23, -49,
+ 49, -17, -31, 63, -64, 25, 36, -76, 61, -11, -47, 75, -54, -9, 69, -81,
+ 32, 29, -63, 46, -7, -26, 39, -31, 6, 18, -26, 13, -5, 5, -5, -2,
+ 5, -12, 17, -17, -2, 22, -25, 1, 20, -19, 3, 6, -6, 3, -9, 10,
+ -6, -3, 7, -7, -3, 12, -5, -5, -11, 24, -7, -23, 24, 0, -14, 0,
+ 12, -10, -2, 5, 0, 1, -10, 10, -2, -17, 26, -11, -16, 28, -22, 6,
+ 4, -17, 30, -27, -7, 46, -54, 15, 29, -42, 25, -4, -15, 26, -29, 11,
+ 15, -28, 19, -7, 1, 8, -20, 14, 1, -15, 11, -2, -2, 0, -10, 15,
+ -5, -12, 15, -1, -15, 12, 4, -15, 9, -1, -9, 9, -5, -6, 13, -12,
+ 1, 6, -6, -3, 6, -4, 0, -6, 11, -9, -2, 13, -12, -2, -1, 8,
+ -11, 4, 2, -6, 4, -4, 4, 0, -13, 15, 0, -21, 23, -5, -15, 15,
+ -2, -9, 6, -2, -4, 2, 3, -1, -7, 7, -2, -9, 6, 2, -9, 4,
+ 5, -12, 10, -9, 4, 5, -16, 12, -2, -13, 20, -13, -4, 17, -23, 14,
+ 2, -20, 22, -13, -3, 15, -22, 12, 4, -18, 17, -7, -7, 13, -14, 6,
+ 4, -10, 9, -5, -6, 7, 0, -7, 8, -4, -1, 0, -6, 4, 7, -14,
+ 2, 13, -16, 3, 10, -15, 7, -1, -10, 14, -10, -2, 11, -9, -4, 7,
+ -6, 3, -3, -5, 9, -6, -3, 5, 1, -7, 3, -2, 0, -2, 0, 4,
+ -3, -2, 4, -6, 4, -2, -2, 0, 1, 0, -7, 7, -2, -7, 9, -7,
+ -4, 11, -15, 11, -2, -9, 9, -4, -3, 2, 3, -7, 5, 0, -5, 6,
+ -7, 1, 7, -10, -2, 13, -9, -4, 8, -4, -2, -1, 1, 1, -7, 4,
+ 5, -8, 0, 6, -6, 0, 3, -4, 0, 1, -2, 2, -4, -4, 8, -7,
+ -1, 6, -9, 8, -3, -6, 12, -12, 1, 10, -11, 1, 5, -6, 3, -2,
+ -3, 7, -10, 2, 7, -12, 5, 2, -5, 3, -5, 0, 6, -10, 3, 4,
+ -8, 2, 2, -3, 3, -8, 8, 2, -14, 10, 3, -12, 8, 2, -11, 8,
+ -2, -6, 9, -7, -4, 10, -9, -1, 7, -7, 1, 3, -8, 8, -2, -8,
+ 10, -3, -5, 5, -6, 3, 1, -8, 10, -5, -5, 7, -4, -2, 2, -3,
+ 1, -1, -3, 4, -3, 0, 0, 0, 0, -4, 3, -2, -3, 3, -5, 3,
+ 0, -7, 5, 1, -8, 5, 1, -6, 6, -5, 0, 3, -7, 3, 2, -6,
+ 3, 2, -6, 3, 1, -3, -2, 5, -4, -1, 3, -4, 0, 0, -3, 5,
+ -5, -3, 7, -5, -3, 6, -4, 0, -1, -3, 3, -2, -1, 2, -1, -2,
+ 1, -2, 1, -1, -7, 8, -1, 5, -7, 13, -22, 8, -7, 8, -110, -28,
+ 24, 54, 36, 2, 60, -45, 57, 42, -43, 20, 41, -66, 24, -11, 18, -18,
+ -38, -63, -36, 30, -11, 33, 25, 30, 18, 11, -18, -5, 5, -46, 40, 1,
+ -13, -18, -20, -31, 20, 10, 29, -7, -18, 40, -29, -17, 42, -19, 6, -4,
+ 6, -8, 10, -26, -5, 3, 1, -17, 6, 0, 19, -1, 8, 0, -6, -10,
+ -1, -12, -1, 1, -3, 8, -7, 4, 11, 4, 14, -13, 16, -19, -4, -13,
+ -13, -14, 6, 4, -1, 4, 11, -1, 11, -1, 1, -4, -1, -15, 6, -9,
+ 1, -1, 0, 3, 1, -8, 3, -1, -1, 2, -2, 2, -2, 1, -5, -7,
+ 3, -3, 6, -3, 4, -1, 0, -4, 2, -7, 3, -6, -1, -1, 4, 0,
+ 3, -2, 2, -5, 5, -8, -3, -3, 2, -5, 7, -1, 4, -2, 4, -10,
+ 6, -6, -1, -4, 5, -13, 7, -6, 5, -8, 17, -20, 14, -6, 9, -40,
+ 71, -127, 9, -73, 127, 76, -28, 74, -32, 8, -62, -49, -38, 40, -68, 22,
+ -12, 68, 10, 39, -10, 0, 35, -23, 0, -59, -15, -7, -3, -23, 1, -20,
+ 37, 27, 2, 30, -2, 17, 2, -5, -7, -27, -29, 16, -3, -11, 1, -16,
+ -5, -8, -10, 7, 32, 9, 5, -4, 16, 5, -8, -17, -16, 5, -13, 8,
+ 11, 15, -10, -9, 0, -1, 2, 7, -3, -23, 9, 2, 3, 1, -13, -1,
+ -6, 11, -6, 8, 1, 12, -12, 9, -14, 8, -1, 0, -3, -13, 4, -7,
+ -4, 8, 5, -5, -7, 4, -2, -3, 2, 3, -6, 8, -3, 1, -3, -2,
+ 2, -6, 2, -4, -3, -4, 3, 1, 0, 0, 1, -1, -1, 2, -2, 0,
+ -4, -2, 1, 2, 0, -3, 1, -3, 0, -1, -3, -6, 2, -2, 3, -4,
+ 10, -8, 9, -5, 12, -19, 46, 37, -128, 60, -90, 102, -65, 40, -57, 39,
+ -6, 23, -8, 19, 24, 15, -17, -47, -27, -36, -16, 21, 3, 23, 14, 50,
+ -8, 19, 25, 7, -9, -28, -63, -37, 0, -42, 54, -17, 68, -3, 30, -12,
+ -4, 11, -15, 9, -25, -15, -2, -27, -25, 38, -8, -13, 33, 24, 12, -38,
+ 39, -12, -3, -17, -44, 38, 2, 27, 3, -5, -4, -13, -30, -56, -4, 11,
+ 1, 9, 17, 46, 25, -14, 6, -3, -7, -21, 2, 16, -5, -22, 2, -2,
+ 6, -12, -25, -15, 10, 9, 8, 11, 43, 8, -5, -22, -16, 14, -31, 16,
+ 7, -7, -26, -20, -2, 9, 11, 26, 7, 6, -20, -13, 0, 4, 17, -17,
+ -18, 10, 2, -10, 27, -8, 24, -23, -14, 1, 0, 13, -19, 14, 10, -16,
+ 16, -4, -20, 20, -33, 2, 2, 24, 21, -3, -26, -24, -18, -18, 10, 10,
+ 24, 18, 2, 9, -24, 16, -14, -8, 9, -5, -14, 8, -5, 30, -11, 11,
+ -13, -15, -12, 7, 4, -13, -13, 13, -13, 12, 23, 9, 0, 14, -10, -9,
+ -35, -2, -21, 12, -1, 17, 19, 11, -4, 0, -18, -24, 11, -10, 1, 11,
+ 12, -13, -16, 10, -23, 21, 9, -9, 3, 12, -6, 3, -5, 12, 0, -2,
+ 0, -19, -9, 5, -11, -7, 10, 1, -3, 9, 18, -6, 0, -1, 1, -13,
+ 2, 1, -3, -8, 17, -4, -9, 18, -15, 8, -1, -11, -5, -14, 11, -5,
+ -7, 12, 16, -7, 7, -3, -11, -5, -6, 1, 4, -3, -3, 15, 5, 0,
+ 3, 6, -16, 4, -14, -6, -9, -4, 2, 11, 11, 7, -2, 4, -12, -7,
+ -14, -6, -7, 9, 4, 7, -2, 6, 5, 6, -4, -3, -4, 7, -7, -11,
+ -9, 0, -3, 7, -2, -2, 3, 13, -4, -6, -15, 9, -7, -1, 4, 6,
+ 5, 8, -6, -8, 0, -11, -4, 6, -8, 4, 3, 5, 13, -4, -9, -3,
+ 4, -3, -3, 4, -1, -12, 6, -14, 2, 3, 15, 2, 6, -7, -8, 3,
+ 1, -2, 3, -3, -12, -6, -14, 7, -2, 13, 6, 10, 6, 0, -2, -10,
+ -12, -8, -6, -7, -6, 6, 4, -2, 5, 2, 0, -1, 3, -11, 4, 0,
+ 20, -8, -2, 0, -1, -3, 7, -3, -4, -2, -6, -10, -10, -8, 1, 2,
+ 5, 8, 2, 5, 8, 3, 4, 3, -2, -15, 0, -1, -7, -2, -5, -10,
+ 10, -1, 5, 3, 5, -1, -2, -8, -5, -9, 1, -8, 6, 5, 4, 1,
+ 1, 2, 3, -2, 4, -7, 1, -7, -9, -2, 0, 2, 3, 6, -8, 8,
+ 3, 0, -2, -9, -3, -2, 0, 3, -1, -2, -3, 7, -3, 10, -8, 1,
+ -12, 3, -7, 2, -3, 7, 4, 4, 0, 0, -6, -1, -5, -3, -4, -7,
+ 0, 5, 7, 0, 2, -3, 10, -1, 3, -7, -5, -4, -9, -3, -7, 5,
+ -4, 9, 2, 1, 4, 5, 0, -5, 1, -8, 4, -9, 5, -5, 0, 3,
+ -2, -1, 1, 1, -7, 7, 0, 3, -5, 0, -3, -1, -1, -5, -1, 1,
+ -1, 1, -1, 0, 2, 0, 2, -7, -7, 4, -1, 0, 3, 4, -1, -3,
+ -4, -6, 3, -2, 4, -1, 5, -2, -1, -5, -2, -4, 1, 3, 2, 2,
+ 0, -3, 1, 1, -3, -3, -1, 1, -3, -2, -1, -2, -3, -1, 0, 4,
+ 3, 5, 2, 1, -4, -9, -3, -7, 1, -2, 7, -2, 3, 3, 3, 1,
+ 0, -1, -6, -7, -6, -4, -1, 1, 0, 5, 2, -2, 2, -3, -1, 3,
+ -1, 1, -4, -4, -5, 0, -7, 2, -4, 3, 4, 1, 2, -1, -1, -2,
+ -2, 0, -1, 1, -1, -1, -3, 1, 1, 3, -3, -1, 1, 1, -2, -3,
+ -8, -5, 0, -1, 5, 2, 3, 1, -2, -1, -1, -3, 1, 1, -2, -3,
+ -3, -1, 0, -1, 1, 2, 2, 5, 0, -1, -2, -1, -2, 0, -4, 0,
+ -5, -1, -1, 0, 1, 5, 4, -2, -1, -2, 0, -6, -1, 0, 1, -1,
+ -2, 1, 0, 0, 3, 1, -2, 1, -2, -4, -1, 0, -1, -1, -4, -2,
+ -4, 2, -1, 1, 0, 3, 2, 0, 4, -1, 4, -6, 2, -4, -3, -5,
+ -4, -3, 0, 2, 0, 1, 4, 2, 2, -2, -2, -5, -6, -5, -3, -2,
+ 1, -1, 0, 0, 2, 2, 2, 0, 4, -2, 3, 2, -1, -2, -3, -3,
+ -3, -5, -5, -5, -1, -1, 0, 2, 2, 4, 1, 2, 1, 2, -1, -1,
+ -3, -4, -5, -3, -2, -2, -1, 1, 4, 2, 2, 2, 1, -1, -2, -6,
+ -2, -3, 2, -1, 1, -2, 0, 2, 1, 2, -2, 1, 0, -2, -2, -3,
+ 0, -2, -1, -1, 0, -2, -2, 1, 0, 2, -1, 1, -1, 0, -1, -1,
+ 0, -1, 0, -2, 2, 0, 2, 2, 5, 3, 6, 8, 12, 13, -6, -110,
+ -7, 51, -99, -128, 10, -28, -39, 25, -33, -27, 41, 34, -5, 17, 23, 25,
+ 24, 23, 20, 24, 25, 24, 21, 20, 23, 23, 16, 20, 9, 20, 18, 10,
+ 14, 5, 14, 11, 7, 5, 3, 10, 2, 7, -4, 0, 3, 0, -3, -5,
+ -6, -1, -12, -4, -17, -10, 9, -42, -40, 65, 40, -58, 29, 72, 39, 50,
+ 31, -1, 30, 25, -7, -4, -33, -47, -29, -49, -74, -69, -71, -79, -61, -51,
+ -57, -53, -34, -20, -22, -16, -10, -6, -2, 1, 3, 4, 8, 8, 12, 10,
+ 9, 14, 13, 12, 12, 13, 12, 12, 14, 12, 12, 12, 12, 13, 12, 9,
+ 11, 11, 11, 7, 8, 7, 8, 9, 2, 5, 8, -6, 2, 17, -17, -20,
+ 18, 5, -15, 15, 27, 21, 37, 44, 41, 46, 38, 26, 32, 26, -4, -15,
+ -6, -20, -44, -50, -54, -60, -59, -58, -58, -54, -46, -38, -32, -26, -19, -14,
+ -9, -5, -1, 2, 5, 7, 8, 10, 11, 12, 13, 13, 14, 14, 14, 13,
+ 13, 14, 15, 14, 11, 13, 14, 13, 12, 10, 12, 12, 10, 10, 8, 6,
+ 11, 9, -1, 5, 11, -1, -6, 1, -1, -4, 0, -1, 0, 14, 25, 24,
+ 28, 37, 38, 38, 38, 31, 22, 14, 4, -5, -15, -26, -38, -47, -52, -54,
+ -56, -57, -55, -51, -45, -39, -34, -28, -22, -17, -13, -8, -3, -1, 2, 5,
+ 7, 8, 10, 11, 12, 13, 13, 13, 13, 14, 14, 13, 13, 14, 13, 12,
+ 13, 13, 12, 11, 12, 11, 9, 11, 9, 6, 7, 8, 5, 3, 2, 0,
+ 0, 0, -2, -3, 0, 3, 6, 11, 18, 23, 27, 31, 34, 35, 32, 27,
+ 21, 14, 5, -5, -15, -26, -35, -43, -48, -52, -53, -53, -52, -49, -44, -40,
+ -35, -29, -24, -19, -14, -10, -6, -3, 1, 3, 5, 7, 9, 10, 11, 12,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 12, 13, 12, 11, 13, 11, 10,
+ 10, 9, 9, 8, 7, 7, 5, 4, 3, 2, 0, -1, -1, 0, 2, 4,
+ 8, 12, 17, 22, 25, 28, 30, 30, 28, 24, 19, 12, 3, -5, -14, -23,
+ -31, -37, -43, -46, -46, -48, -47, -43, -41, -38, -33, -29, -25, -21, -16, -12,
+ -8, -5, -2, 0, 3, 5, 7, 9, 10, 11, 12, 12, 13, 14, 13, 13,
+ 13, 13, 13, 12, 12, 12, 11, 11, 11, 10, 9, 9, 8, 7, 7, 6,
+ 5, 4, 4, 3, 3, 3, 3, 5, 6, 8, 10, 12, 14, 17, 18, 19,
+ 20, 19, 17, 14, 10, 5, 0, -6, -11, -17, -22, -26, -29, -32, -34, -34,
+ -35, -34, -32, -31, -28, -26, -23, -20, -17, -14, -11, -8, -5, -3, 0, 2,
+ 4, 6, 7, 8, 9, 10, 11, 11, 12, 12, 12, 12, 11, 11, 11, 10,
+ 10, 9, 9, 8, 8, 7, 7, 6, 5, 5, 5, 4, 4, 5, 5, 5,
+ 6, 7, 8, 9, 10, 11, 12, 13, 13, 13, 13, 12, 10, 8, 5, 2,
+ -2, -6, -10, -14, -18, -21, -24, -26, -28, -29, -29, -30, -29, -28, -27, -25,
+ -23, -20, -18, -15, -12, -10, -7, -4, -2, 0, 2, 4, 6, 7, 9, 10,
+ 10, 11, 11, 12, 12, 12, 12, 11, 11, 11, 10, 10, 9, 9, 8, 8,
+ 7, 7, 6, 6, 5, 5, 5, 5, 6, 6, 7, 7, 8, 9, 10, 11,
+ 12, 13, 13, 13, 12, 11, 10, 8, 5, 2, -1, -5, -9, -13, -16, -19,
+ -22, -24, -26, -27, -28, -28, -28, -27, -26, -24, -22, -20, -18, -15, -13, -10,
+ -7, -5, -2, 0, 2, 4, 5, 7, 8, 9, 10, 11, 11, 11, 11, 11,
+ 11, 11, 11, 10, 10, 9, 9, 8, 8, 7, 7, 6, 6, 6, 5, 5,
+ 5, 5, 6, 6, 6, 7, 8, 9, 10, 11, 11, 12, 12, 12, 11, 10,
+ 9, 7, 5, 2, -1, -5, -8, -12, -15, -18, -21, -23, -25, -26, -27, -27,
+ -27, -26, -25, -24, -22, -20, -18, -16, -13, -11, -8, -6, -3, -1, 1, 3,
+ 4, 6, 7, 8, 9, 10, 10, 10, 11, 11, 11, 10, 10, 10, 10, 9,
+ 9, 8, 8, 7, 7, 6, 6, 6, 5, 5, 5, 5, 6, 6, 6, 7,
+ 8, 9, 9, 10, 11, 11, 11, 11, 11, 10, 9, 7, 4, 2, -1, -4,
+ -7, -11, -14, -17, -19, -21, -23, -24, -25, -26, -26, -25, -24, -23, -22, -20,
+ -18, -16, -13, -11, -9, -6, -4, -2, 0, 2, 4, 5, 7, 8, 9, 9,
+ 10, 10, 11, 11, 11, 11, 10, 10, 10, 9, 9, 8, 8, 7, 7, 7,
+ 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 8, 9, 9, 10, 11, 11,
+ 11, 11, 10, 10, 8, 7, 5, 2, -1, -3, -7, -10, -13, -15, -18, -20,
+ -22, -23, -24, -25, -25, -24, -24, -23, -21, -20, -18, -16, -14, -11, -9, -7,
+ -5, -2, 0, 1, 3, 5, 6, 7, 8, 9, 9, 10, 10, 10, 10, 10,
+ 10, 10, 9, 9, 8, 8, 8, 7, 7, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 7, 7, 8, 8, 9, 9, 9, 10, 9, 9, 8, 7, 6, 4,
+ 2, 0, -2, -5, -7, -10, -12, -15, -17, -18, -20, -21, -21, -22, -22, -21,
+ -21, -20, -18, -17, -15, -13, -12, -10, -8, -6, -4, -2, 0, 1, 3, 4,
+ 5, 6, 7, 8, 8, 8, 9, 9, 9, 9, 9, 8, 8, 8, 8, 7,
+ 7, 7, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8,
+ 8, 8, 8, 8, 7, 6, 5, 4, 3, 1, -1, -3, -5, -7, -9, -10,
+ -12, -14, -15, -16, -17, -18, -18, -18, -18, -17, -17, -16, -15, -13, -12, -11,
+ -9, -7, -6, -4, -3, -1, 0, 1, 3, 4, 5, 5, 6, 7, 7, 7,
+ 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 6, 5,
+ 4, 3, 2, 0, -1, -3, -5, -7, -9, -10, -12, -13, -15, -16, -17, -17,
+ -18, -18, -18, -17, -17, -16, -15, -14, -12, -11, -9, -8, -6, -5, -3, -2,
+ -1, 1, 2, 3, 4, 5, 5, 6, 6, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 6, 6, 5, 4, 3, 2, 0, -1, -3,
+ 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 2, 3, 4, 5,
+ 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 6, 7, 8, 9, 10, 10,
+ 11, 12, 12, 13, 13, 14, 15, 17, 18, 19, 20, 21, 22, 23, 24, 26,
+ 27, 29, 29, 29, 28, 28, 28, 29, 30, 31, 31, 31, 31, 28, 19, -8,
+ -41, -53, -57, -59, -60, -62, -62, -63, -64, -65, -65, -66, -67, -69, -69, -69,
+ -72, -74, -73, -74, -76, -78, -79, -81, -82, -82, -83, -81, -83, -85, -81, -81,
+ -88, -90, -80, -64, -47, -32, -23, -18, -15, -13, -12, -12, -12, -13, -13, -13,
+ -13, -13, -12, -12, -11, -9, -7, -6, -4, -2, -1, 0, 1, 2, 4, 5,
+ 7, 10, 12, 14, 16, 18, 19, 18, 19, 21, 19, 20, 22, 22, 22, 25,
+ 27, 28, 29, 29, 29, 29, 29, 30, 31, 31, 31, 33, 34, 34, 35, 34,
+ 33, 31, 30, 29, 26, 25, 26, 25, 22, 22, 21, 20, 20, 19, 19, 19,
+ 18, 18, 18, 17, 17, 17, 17, 16, 16, 16, 15, 13, 13, 14, 14, 15,
+ 13, 12, 13, 13, 11, 12, 14, 14, 16, 17, 15, 16, 19, 19, 19, 19,
+ 21, 19, 17, 18, 19, 18, 15, 15, 17, 18, 18, 13, 11, 14, 15, 14,
+ 11, 6, 5, 10, 13, 17, 18, 11, 2, -2, -2, -3, 2, 14, 24, 30,
+ 37, 47, 52, 52, 56, 63, 65, 65, 63, 65, 72, 75, 73, 71, 73, 77,
+ 82, 82, 77, 77, 82, 90, 99, 104, 99, 89, 84, 86, 94, 106, 119, 127,
+ 126, 117, 104, 87, 64, 42, 24, 10, -2, -15, -22, -25, -27, -30, -35, -37,
+ -36, -34, -33, -36, -40, -42, -44, -43, -44, -48, -53, -57, -59, -57, -53, -52,
+ -53, -57, -62, -68, -73, -75, -75, -71, -63, -56, -48, -40, -34, -29, -26, -23,
+ -22, -21, -19, -19, -20, -21, -22, -22, -22, -22, -22, -21, -21, -21, -20, -19,
+ -19, -18, -18, -17, -17, -16, -14, -14, -13, -11, -9, -9, -9, -9, -9, -8,
+ -8, -8, -8, -8, -7, -6, -7, -6, -4, -3, -2, -2, -3, -4, -3, -3,
+ -2, -1, 0, 0, -1, -1, 0, -1, -1, -1, -3, -5, -5, -8, -10, -10,
+ -9, -9, -10, -11, -11, -11, -11, -11, -10, -9, -10, -10, -10, -11, -12, -12,
+ -13, -12, -11, -12, -14, -14, -11, -10, -12, -11, -11, -12, -12, -11, -11, -13,
+ -12, -9, -6, -6, -7, -7, -6, -5, -4, -4, -5, -8, -12, -11, -8, -4,
+ -3, -5, -6, -7, -9, -12, -13, -8, -3, -2, -4, -8, -11, -14, -15, -17,
+ -19, -19, -15, -8, -1, 2, 4, 8, 12, 17, 23, 26, 25, 24, 25, 30,
+ 36, 40, 39, 36, 33, 32, 33, 37, 43, 49, 53, 53, 49, 45, 43, 43,
+ 46, 52, 60, 67, 76, 82, 82, 78, 69, 58, 47, 37, 26, 14, 2, -9,
+ -16, -21, -24, -28, -32, -35, -37, -38, -37, -36, -36, -36, -39, -43, -46, -49,
+ -51, -49, -47, -46, -45, -45, -48, -52, -58, -62, -65, -66, -65, -62, -58, -54,
+ -50, -45, -39, -34, -30, -28, -25, -23, -21, -20, -20, -20, -20, -19, -18, -19,
+ -20, -18, -17, -18, -17, -17, -18, -17, -16, -15, -15, -13, -12, -10, -10, -10,
+ -9, -8, -7, -6, -4, -4, -5, -6, -5, -4, -4, -3, -2, -2, -1, -1,
+ -1, 0, 2, 3, 2, 2, 3, 2, 1, 2, 4, 5, 5, 4, 4, 4,
+ 3, 2, 2, 1, 0, 0, -1, -4, -5, -4, -2, -2, -3, -3, -3, -2,
+ -1, -2, -3, -2, -3, -4, -4, -3, -4, -6, -7, -4, 0, 0, -2, -4,
+ -4, -3, -2, -2, -3, -4, -4, -3, -2, -1, 3, 6, 8, 6, 3, 0,
+ 0, 2, 4, 5, 4, 3, 2, 2, 2, 1, 0, -1, 2, 7, 11, 9,
+ 6, 2, -1, -3, -3, -5, -7, -8, -6, -3, 2, 8, 13, 17, 18, 18,
+ 19, 23, 28, 34, 40, 42, 42, 40, 39, 39, 40, 42, 46, 50, 55, 59,
+ 59, 55, 51, 48, 48, 51, 57, 63, 70, 76, 82, 86, 88, 89, 86, 80,
+ 71, 61, 51, 43, 34, 25, 18, 10, 2, -5, -9, -12, -13, -12, -12, -13,
+ -14, -17, -22, -26, -29, -28, -27, -25, -24, -24, -25, -27, -31, -35, -40, -43,
+ -46, -47, -49, -49, -46, -43, -40, -36, -32, -28, -24, -21, -18, -16, -14, -13,
+ -13, -12, -11, -11, -12, -11, -10, -9, -11, -11, -11, -12, -12, -12, -10, -10,
+ -10, -10, -9, -8, -7, -6, -5, -4, -4, -4, -4, -4, -3, -2, -2, -1,
+ -2, -3, -2, -1, 0, 0, 1, 2, 3, 2, 1, 1, 2, 3, 3, 4,
+ 5, 4, 4, 5, 6, 7, 6, 4, 3, 3, 3, 2, -1, -3, -3, -1,
+ -1, -2, -3, -3, -2, -1, 1, 0, -1, -1, -2, -5, -6, -5, -4, -4,
+ -4, -4, -6, -6, -4, -1, 0, -2, -6, -9, -10, -8, -5, -4, -3, -3,
+ -1, 1, 1, -1, -3, -4, -2, 0, 2, 2, 0, -3, -6, -7, -6, -4,
+ -3, -2, -1, -1, -1, 0, 1, 0, -3, -9, -14, -18, -18, -15, -12, -9,
+ -8, -7, -5, -3, -2, 0, 5, 11, 17, 22, 25, 24, 23, 21, 20, 22,
+ 27, 32, 37, 40, 41, 40, 39, 37, 35, 34, 34, 35, 39, 45, 52, 59,
+ 66, 71, 73, 75, 74, 71, 65, 60, 55, 48, 39, 28, 17, 7, -1, -7,
+ -11, -13, -13, -14, -17, -21, -24, -28, -31, -32, -32, -32, -32, -31, -29, -29,
+ -30, -33, -36, -40, -44, -47, -50, -52, -54, -55, -54, -52, -49, -47, -43, -39,
+ -35, -31, -28, -26, -24, -22, -21, -19, -18, -17, -17, -16, -15, -16, -18, -17,
+ -16, -16, -17, -18, -18, -17, -16, -16, -14, -13, -13, -12, -12, -12, -11, -10,
+ -10, -9, -7, -8, -9, -10, -10, -8, -6, -5, -6, -6, -5, -3, -3, -4,
+ -4, -4, -3, -2, -2, -1, -1, -1, 0, 2, 3, 3, 3, 2, 1, 0,
+ -1, -1, -1, -2, -3, -5, -5, -4, -2, -3, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1,
+ 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 1, 3, 2, 0,
+ -1, 1, 2, 1, -1, -1, 2, 2, 0, 1, 2, 2, -1, -4, -10, -21,
+ -30, -36, -41, -44, -40, -30, -18, -10, -8, -11, -13, -8, 3, 18, 32, 41,
+ 44, 45, 48, 49, 43, 32, 23, 14, 7, 8, 16, 27, 35, 37, 30, 18,
+ 9, 5, 3, 2, 1, 1, -1, -6, -11, -12, -6, -2, -5, -11, -18, -28,
+ -39, -47, -55, -69, -86, -99, -102, -92, -70, -46, -28, -15, -3, 7, 17, 26,
+ 28, 24, 23, 30, 42, 53, 57, 50, 36, 21, 5, -5, -4, 6, 20, 31,
+ 35, 34, 29, 26, 27, 37, 56, 76, 85, 80, 71, 63, 55, 47, 34, 13,
+ -13, -32, -39, -40, -46, -65, -93, -117, -128, -128, -126, -120, -110, -96, -78, -58,
+ -36, -14, 3, 10, 20, 41, 60, 68, 63, 54, 45, 39, 36, 32, 28, 29,
+ 35, 41, 47, 46, 41, 39, 43, 53, 68, 80, 78, 64, 46, 28, 13, 3,
+ -9, -35, -64, -80, -82, -74, -66, -71, -91, -111, -121, -118, -105, -86, -68, -57,
+ -49, -37, -22, -7, 5, 14, 26, 42, 55, 56, 46, 35, 25, 14, 6, 2,
+ 1, 3, 11, 22, 32, 40, 43, 42, 46, 60, 77, 88, 90, 78, 54, 30,
+ 14, 2, -15, -37, -62, -82, -90, -89, -86, -90, -99, -107, -109, -101, -81, -54,
+ -29, -14, -5, 7, 24, 40, 49, 56, 68, 83, 92, 92, 87, 74, 54, 32,
+ 12, -5, -19, -25, -24, -18, -7, 1, -1, -6, -4, 13, 41, 69, 84, 80,
+ 63, 44, 32, 29, 25, 11, -10, -25, -31, -35, -40, -48, -65, -87, -104, -109,
+ -102, -87, -69, -58, -54, -42, -21, 0, 13, 29, 51, 71, 84, 89, 86, 75,
+ 54, 33, 14, -3, -19, -29, -27, -22, -18, -11, -8, -16, -26, -19, 2, 24,
+ 40, 48, 42, 27, 21, 29, 34, 24, 7, -5, -14, -23, -28, -32, -45, -67,
+ -82, -85, -78, -63, -46, -34, -29, -24, -13, 0, 12, 25, 44, 65, 79, 85,
+ 86, 78, 60, 41, 27, 12, -5, -15, -15, -14, -13, -8, -7, -17, -27, -23,
+ -3, 23, 44, 51, 43, 25, 12, 11, 14, 8, -3, -10, -15, -22, -28, -30,
+ -36, -55, -73, -78, -74, -71, -63, -51, -43, -39, -34, -25, -18, -9, 8, 28,
+ 46, 56, 61, 62, 58, 47, 36, 28, 20, 12, 11, 16, 19, 20, 21, 15,
+ 0, -6, 10, 37, 57, 63, 55, 36, 15, 2, -3, -9, -19, -27, -34, -43,
+ -49, -49, -52, -66, -82, -86, -81, -77, -71, -61, -51, -47, -43, -35, -22, -12,
+ 2, 24, 47, 58, 63, 67, 66, 58, 51, 45, 34, 18, 9, 7, 7, 7,
+ 8, 1, -14, -24, -12, 18, 47, 64, 68, 63, 53, 42, 37, 38, 36, 29,
+ 21, 16, 11, 5, -2, -17, -36, -49, -52, -56, -62, -63, -61, -61, -63, -60,
+ -56, -49, -37, -19, 2, 17, 25, 30, 34, 37, 37, 37, 34, 25, 15, 11,
+ 13, 14, 14, 8, -7, -21, -16, 9, 37, 53, 60, 61, 53, 40, 33, 34,
+ 32, 22, 14, 12, 10, 6, -2, -15, -32, -48, -57, -60, -63, -67, -66, -63,
+ -63, -65, -64, -58, -49, -34, -13, 6, 16, 21, 28, 34, 38, 41, 43, 36,
+ 25, 19, 21, 26, 27, 20, 4, -11, -11, 7, 31, 53, 66, 70, 66, 57,
+ 49, 47, 44, 33, 21, 17, 16, 10, 1, -9, -26, -46, -60, -67, -76, -84,
+ -84, -80, -78, -79, -78, -73, -65, -52, -32, -11, 4, 10, 17, 25, 32, 36,
+ 40, 37, 24, 13, 15, 23, 23, 11, -5, -19, -25, -16, 9, 38, 59, 70,
+ 72, 67, 63, 63, 60, 50, 39, 32, 28, 22, 14, 3, -14, -34, -53, -65,
+ -76, -87, -94, -93, -91, -94, -96, -93, -86, -76, -56, -30, -9, 4, 16, 29,
+ 40, 51, 63, 65, 52, 39, 39, 45, 42, 29, 11, -7, -22, -24, -8, 19,
+ 42, 54, 60, 63, 61, 58, 57, 53, 43, 36, 36, 34, 28, 21, 11, -5,
+ -24, -39, -52, -65, -75, -77, -75, -75, -78, -80, -78, -73, -61, -43, -23, -9,
+ 1, 10, 23, 39, 52, 56, 47, 36, 35, 41, 42, 33, 17, -2, -24, -35,
+ -26, -3, 18, 32, 42, 50, 52, 53, 52, 47, 38, 31, 30, 31, 29, 26,
+ 22, 14, -1, -18, -33, -46, -58, -65, -65, -65, -71, -79, -81, -79, -75, -62,
+ -42, -27, -21, -14, 1, 19, 34, 40, 36, 29, 27, 31, 38, 39, 29, 9,
+ -12, -27, -28, -14, 8, 25, 37, 50, 62, 67, 66, 62, 53, 42, 36, 37,
+ 36, 32, 30, 25, 12, -7, -24, -39, -54, -65, -67, -67, -72, -78, -81, -82,
+ -81, -70, -51, -35, -29, -23, -7, 15, 30, 37, 40, 35, 25, 25, 36, 41,
+ 33, 15, -6, -26, -36, -27, -9, 7, 20, 35, 50, 58, 59, 58, 52, 43,
+ 37, 37, 37, 36, 34, 31, 24, 8, -11, -29, -44, -57, -67, -70, -73, -79,
+ -86, -92, -93, -87, -72, -59, -53, -46, -29, -9, 7, 20, 28, 26, 19, 17,
+ 27, 38, 38, 26, 7, -12, -25, -26, -15, 1, 14, 28, 47, 61, 67, 68,
+ 68, 63, 54, 51, 53, 51, 49, 49, 47, 34, 14, -5, -22, -39, -56, -65,
+ -67, -73, -86, -96, -97, -92, -86, -77, -69, -61, -49, -28, -6, 10, 22, 27,
+ 25, 24, 33, 49, 56, 48, 32, 13, -5, -15, -12, -2, 7, 18, 35, 50,
+ 59, 63, 65, 61, 53, 48, 46, 44, 43, 46, 49, 43, 27, 10, -6, -25,
+ -45, -53, -53, -60, -75, -87, -90, -90, -88, -81, -75, -72, -65, -48, -25, -6,
+ 5, 10, 13, 18, 31, 49, 60, 58, 44, 28, 12, -1, -7, -7, -1, 8,
+ 23, 41, 54, 61, 65, 66, 63, 56, 48, 43, 41, 42, 44, 43, 37, 25,
+ 8, -12, -32, -44, -49, -53, -64, -80, -91, -95, -93, -89, -85, -82, -78, -68,
+ -50, -27, -6, 0, -1, 0, 0, 0, 1, 2, 3, 6, 9, 13, 17, 19,
+ 13, -4, -15, -10, 4, 19, 26, 15, -9, -16, 6, -2, -18, 38, 64, 21,
+ -48, 30, 82, -23, -63, -50, -26, -7, 12, 26, 47, 83, 100, 3, -108, -87,
+ -30, -6, 5, 18, 33, 46, 47, 21, -52, -46, 48, 3, -54, -32, 22, 25,
+ -7, 12, 9, -18, -33, -24, 2, 44, 88, 92, 10, -28, -1, 1, 20, 42,
+ 1, -17, 53, 72, 12, -16, -74, -31, 127, 52, 1, -35, -46, 13, 39, -13,
+ -13, 13, 12, 11, 8, -57, -80, -44, -5, 14, 18, 6, -13, -26, -11, -8,
+ -24, 3, 30, 14, -28, -12, 41, -2, -37, -35, -23, -12, -1, 6, 17, 34,
+ 53, 19, -55, -67, -32, -13, -5, 2, 12, 19, 24, 14, -24, -47, 12, 11,
+ -36, -35, -1, 18, -3, 0, 5, -13, -25, -22, -5, 19, 53, 69, 21, -28,
+ -10, -5, 6, 28, 8, -25, 23, 57, 17, -17, -49, -63, 84, 70, 3, -23,
+ -50, -6, 36, -2, -20, 8, 14, 9, 13, -37, -82, -58, -19, 8, 17, 10,
+ -9, -26, -19, -7, -24, -9, 25, 22, -17, -28, 33, 16, -32, -37, -27, -15,
+ -4, 4, 13, 27, 48, 35, -35, -72, -43, -17, -7, -1, 9, 16, 23, 17,
+ -12, -51, -7, 21, -27, -40, -12, 19, 6, -3, 5, -9, -22, -23, -8, 11,
+ 42, 68, 38, -23, -16, -6, 3, 25, 19, -24, 8, 54, 31, -13, -33, -76,
+ 46, 95, 13, -13, -48, -20, 32, 13, -22, 2, 15, 10, 15, -17, -77, -67,
+ -31, 3, 17, 15, -3, -21, -23, -7, -20, -18, 18, 27, -4, -34, 17, 33,
+ -21, -36, -29, -16, -6, 4, 11, 23, 42, 47, -12, -69, -54, -22, -8, -2,
+ 7, 15, 22, 20, -2, -46, -27, 23, -13, -41, -22, 15, 16, -2, 4, -5,
+ -18, -21, -10, 5, 32, 64, 53, -12, -21, -6, 0, 21, 27, -16, -6, 48,
+ 42, -6, -22, -71, 2, 106, 31, -6, -41, -32, 22, 25, -18, -4, 15, 12,
+ 14, -1, -64, -74, -42, -5, 16, 19, 4, -16, -25, -10, -14, -23, 9, 29,
+ 9, -31, -2, 42, -5, -33, -30, -18, -8, 3, 9, 19, 36, 51, 10, -58,
+ -63, -29, -11, -2, 4, 13, 20, 21, 6, -35, -44, 16, 1, -38, -30, 7,
+ 23, 3, 2, -2, -16, -20, -12, 2, 23, 56, 62, 3, -24, -7, -2, 17,
+ 30, -5, -17, 37, 49, 4, -17, -57, -37, 99, 55, 0, -31, -41, 9, 33,
+ -10, -11, 13, 14, 12, 9, -47, -78, -53, -15, 12, 20, 9, -10, -24, -14,
+ -11, -25, -2, 27, 18, -21, -20, 39, 13, -29, -31, -20, -9, 1, 8, 17,
+ 30, 49, 29, -41, -70, -39, -15, -4, 2, 11, 17, 21, 11, -22, -52, 0,
+ 14, -31, -36, -4, 25, 11, 1, -1, -13, -19, -13, 0, 15, 45, 65, 20,
+ -24, -10, -4, 12, 30, 8, -22, 24, 52, 17, -14, -39, -61, 71, 81, 8,
+ -21, -44, -5, 34, 2, -16, 9, 16, 11, 14, -29, -76, -62, -27, 6, 20,
+ 15, -4, -21, -19, -9, -23, -12, 22, 25, -8, -30, 26, 30, -20, -31, -23,
+ -11, -1, 8, 14, 25, 44, 42, -19, -69, -50, -20, -6, 1, 9, 15, 20,
+ 15, -11, -51, -19, 20, -20, -39, -15, 23, 20, 2, 0, -11, -17, -14, -2,
+ 9, 35, 63, 37, -19, -14, -5, 8, 28, 18, -22, 9, 50, 28, -11, -26,
+ -68, 32, 100, 22, -13, -43, -18, 30, 15, -17, 4, 16, 12, 15, -12, -69,
+ -69, -39, -2, 18, 19, 2, -17, -22, -10, -19, -20, 15, 27, 4, -31, 7,
+ 41, -7, -30, -25, -13, -3, 6, 12, 22, 38, 48, 3, -61, -60, -27, -9,
+ 0, 7, 13, 19, 17, -2, -44, -37, 18, -7, -39, -24, 15, 28, 7, 0,
+ -9, -16, -14, -3, 6, 25, 57, 49, -9, -18, -7, 3, 25, 26, -15, -4,
+ 45, 38, -5, -18, -61, -8, 103, 42, -6, -37, -30, 21, 25, -13, -3, 16,
+ 13, 14, 2, -56, -73, -49, -12, 15, 21, 8, -11, -23, -13, -15, -24, 4,
+ 28, 14, -25, -12, 42, 9, -26, -26, -15, -5, 5, 11, 19, 32, 48, 22,
+ -46, -67, -36, -12, -2, 4, 12, 17, 18, 4, -33, -50, 6, 6, -35, -31,
+ 4, 31, 14, 0, -8, -15, -14, -4, 4, 17, 48, 57, 4, -21, -8, -1,
+ 21, 30, -5, -15, 36, 44, 5, -14, -46, -40, 88, 67, 2, -29, -37, 9,
+ 31, -6, -9, 14, 15, 13, 11, -40, -74, -58, -24, 9, 22, 13, -6, -21,
+ -17, -13, -25, -6, 25, 21, -13, -25, 33, 26, -19, -27, -18, -6, 3, 10,
+ 16, 27, 45, 36, -26, -69, -46, -17, -4, 2, 10, 15, 18, 9, -22, -55,
+ -11, 15, -26, -36, -8, 30, 23, 2, -6, -14, -14, -6, 4, 11, 37, 59,
+ 19, -20, -10, -4, 16, 31, 7, -20, 23, 47, 15, -13, -32, -58, 58, 88,
+ 13, -21, -40, -5, 32, 4, -13, 10, 17, 12, 14, -23, -70, -65, -35, 1,
+ 20, 17, 0, -18, -20, -12, -23, -16, 19, 25, -1, -30, 16, 39, -8, -26,
+ -20, -8, 1, 9, 14, 23, 39, 44, -5, -63, -57, -24, -7, 1, 8, 13,
+ 17, 12, -12, -52, -30, 17, -15, -38, -18, 23, 32, 7, -6, -13, -14, -7,
+ 3, 8, 27, 55, 33, -16, -13, -6, 10, 30, 17, -20, 10, 46, 25, -9,
+ -21, -60, 19, 100, 31, -13, -39, -17, 27, 15, -13, 4, 17, 13, 15, -8,
+ -61, -69, -46, -10, 17, 21, 6, -13, -22, -13, -20, -22, 10, 27, 9, -27,
+ -4, 44, 6, -24, -22, -11, -1, 8, 13, 20, 33, 46, 14, -50, -65, -33,
+ -11, 0, 5, 12, 15, 14, -4, -43, -46, 10, -2, -36, -27, 13, 36, 15,
+ -4, -13, -14, -8, 3, 7, 18, 49, 43, -7, -16, -7, 5, 27, 24, -14,
+ -3, 42, 33, -3, -16, -51, -17, 97, 51, -3, -38, -5, -13, 1, -7, 5,
+ -22, -32, -35, -32, -43, -35, -55, -42, -66, -48, -80, -57, -17, -128, -59, -76,
+ 0, -26, 1, -33, 21, 3, 16, 15, 26, 43, 28, 66, 6, 97, 40, 103,
+ 67, 101, 102, 98, 94, 21, 98, 90, 57, 78, 89, 81, 61, -6, 54, 4,
+ 62, 19, 27, 34, 12, 16, 14, -17, 19, -5, -2, -13, -38, -24, -3, -33,
+ -14, -11, -16, 0, -13, 7, -26, -13, -16, 6, -57, -23, -28, -13, -9, -34,
+ -32, -20, -87, -62, -28, -38, -75, -37, -27, -41, -71, -48, -30, -44, -83, -67,
+ -52, -48, -45, -46, -45, -63, -47, -40, -32, -45, -24, -32, -43, -21, -17, 0,
+ 21, 26, 43, 51, 62, 47, 41, 55, 57, 68, 34, 53, 63, 62, 71, 60,
+ 61, 56, 53, 56, 54, 38, 50, 58, 50, 40, 28, 54, 39, 41, 38, 22,
+ 32, 20, -3, 19, -1, -7, -6, -16, -16, -14, -27, -29, -46, -66, -61, -51,
+ -54, -61, -41, -50, -47, -52, -55, -45, -44, -28, -58, -56, -31, -37, -36, -32,
+ -18, -16, -34, -29, -9, -21, -20, -30, -22, -17, -19, -8, -12, -14, -6, -14,
+ -6, -11, -2, 4, -6, 9, 8, 17, 23, 13, 31, 13, 24, 30, 28, 29,
+ 30, 43, 34, 37, 52, 42, 44, 50, 67, 59, 49, 54, 48, 43, 51, 45,
+ 42, 62, 47, 39, 37, 36, 24, 28, 13, 3, 9, -11, -3, -9, -14, -18,
+ -34, -27, -29, -39, -42, -38, -46, -37, -46, -43, -41, -35, -38, -31, -38, -34,
+ -39, -39, -34, -48, -44, -47, -49, -54, -52, -44, -53, -37, -47, -38, -31, -38,
+ -27, -19, -19, -15, -16, 0, 0, 2, 7, 13, 29, 22, 32, 32, 39, 47,
+ 41, 40, 55, 48, 41, 44, 57, 43, 36, 47, 43, 42, 37, 32, 32, 27,
+ 33, 36, 30, 23, 25, 25, 22, 18, 22, 20, 16, 8, 6, 12, 7, 0,
+ 1, 3, -5, -14, -9, -7, -8, -19, -15, -16, -23, -21, -21, -32, -31, -29,
+ -26, -27, -29, -33, -26, -29, -30, -39, -28, -41, -43, -35, -34, -32, -29, -28,
+ -28, -25, -27, -24, -27, -27, -27, -22, -23, -17, -9, -10, -14, -10, -8, -4,
+ -2, -1, -3, 5, 4, 10, 11, 7, 13, 11, 14, 27, 22, 22, 22, 27,
+ 36, 34, 36, 37, 45, 44, 47, 48, 51, 49, 52, 51, 52, 48, 50, 47,
+ 48, 42, 40, 29, 33, 24, 22, 12, 5, 0, -3, -5, -9, -21, -21, -25,
+ -19, -28, -28, -30, -33, -39, -42, -42, -46, -46, -45, -42, -43, -47, -47, -36,
+ -32, -30, -34, -31, -22, -29, -29, -30, -26, -28, -30, -21, -26, -27, -21, -19,
+ -16, -11, -12, -8, -2, 1, -4, 1, 0, 1, 9, 8, 7, 12, 10, 13,
+ 20, 17, 18, 21, 26, 29, 30, 30, 29, 34, 33, 34, 33, 30, 32, 33,
+ 28, 33, 29, 35, 32, 31, 30, 31, 30, 25, 27, 24, 21, 21, 20, 16,
+ 17, 12, 6, 4, -3, 1, -6, -7, -11, -13, -11, -10, -8, -13, -12, -9,
+ -17, -14, -19, -24, -22, -24, -30, -32, -30, -33, -37, -39, -40, -42, -39, -41,
+ -39, -40, -41, -35, -35, -35, -37, -36, -33, -30, -25, -25, -19, -16, -16, -10,
+ -6, -7, -4, -2, 1, 3, 6, 10, 9, 15, 17, 18, 17, 13, 19, 18,
+ 17, 19, 20, 24, 24, 27, 27, 29, 30, 26, 28, 28, 27, 28, 26, 25,
+ 24, 25, 20, 19, 17, 18, 15, 12, 13, 10, 6, 8, 6, 3, 4, 3,
+ 0, -3, 0, -1, -2, -5, -4, -5, -4, -5, -6, -8, -9, -9, -12, -11,
+ -16, -16, -15, -15, -13, -17, -16, -17, -17, -21, -20, -25, -24, -24, -24, -26,
+ -30, -30, -27, -30, -26, -26, -27, -27, -25, -24, -19, -20, -17, -13, -12, -8,
+ -8, -8, -6, -5, -2, -1, 0, 3, 8, 10, 12, 16, 18, 24, 25, 25,
+ 28, 30, 28, 32, 33, 31, 32, 31, 35, 33, 31, 31, 27, 28, 26, 23,
+ 23, 20, 22, 18, 16, 13, 11, 9, 5, 4, -2, -2, -3, -8, -9, -11,
+ -12, -13, -15, -15, -15, -15, -15, -14, -12, -12, -13, -13, -8, -11, -10, -12,
+ -10, -12, -12, -8, -8, -9, -9, -9, -8, -9, -10, -11, -11, -10, -13, -14,
+ -13, -16, -16, -17, -17, -18, -19, -18, -17, -16, -16, -15, -15, -13, -12, -10,
+ -12, -10, -9, -8, -6, -6, -3, 0, 0, 1, 2, 2, 3, 4, 4, 5,
+ 6, 7, 8, 9, 10, 11, 12, 12, 13, 14, 14, 15, 15, 15, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 15, 15, 14, 13, 13, 12, 11, 10,
+ 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, -1, -1, -2, -3, -4, -5,
+ -5, -6, -7, -7, -8, -9, -9, -10, -11, -11, -12, -12, -13, -13, -13, -13,
+ -14, -14, -14, -15, -15, -15, -15, -15, -15, -16, -16, -16, -15, -15, -15, -14,
+ -13, -13, -12, -11, -10, -9, -8, -7, -6, -5, -4, -2, -1, 0, 1, 2,
+ 4, 5, 6, 7, 8, 9, 10, 11, 12, 12, 13, 13, 14, 14, 15, 15,
+ 15, 15, 16, 16, 16, 16, 17, 17, 17, 17, 17, 17, 16, 16, 15, 15,
+ 14, 14, 13, 12, 11, 10, 9, 7, 6, 5, 3, 1, 0, -2, -4, -5,
+ -7, -9, -10, -11, -13, -14, -15, -15, -16, -17, -17, -18, -18, -18, -18, -18,
+ -18, -18, -18, -18, -18, -18, -18, -17, -17, -16, -16, -15, -14, -14, -13, -12,
+ -11, -10, -9, -8, -7, -6, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5,
+ 6, 7, 8, 9, 9, 10, 11, 11, 12, 13, 13, 13, 14, 14, 14, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 14, 14, 14, 13, 12, 12,
+ 11, 10, 9, 8, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0, -1, 0,
+ 0, -1, 2, 1, 0, 1, 4, 2, 2, 2, 5, 2, 5, 5, 8, 4,
+ 13, 15, 19, -62, -65, 56, -18, -128, -39, 15, -57, -10, 19, -22, -11, 36,
+ 30, 5, 19, 25, 17, 21, 21, 16, 21, 18, 17, 17, 15, 14, 13, 12,
+ 10, 6, 8, 6, 6, -1, 1, -4, 7, -10, -36, 35, 64, -25, -18, 83,
+ 50, 22, 39, 21, 19, -4, -20, 28, 0, -88, -55, -5, -55, -83, -64, -58,
+ -77, -61, -22, -39, -57, -15, 2, -14, -9, -1, 1, 1, 2, 9, 5, 6,
+ 11, 9, 9, 10, 11, 12, 12, 10, 9, 9, 13, 7, 3, 14, 4, -3,
+ 2, 2, 17, 40, 12, 14, 55, 58, 44, 39, 38, 37, 6, 4, 31, -6,
+ -50, -25, -15, -49, -52, -41, -60, -68, -32, -25, -47, -36, -9, -5, -7, -3,
+ 3, 4, 6, 8, 11, 9, 10, 14, 14, 11, 13, 15, 14, 13, 14, 12,
+ 11, 12, 12, 8, 8, 3, 4, 5, -1, 8, 32, 21, 14, 43, 50, 39,
+ 47, 39, 20, 23, 16, 5, -9, -23, -26, -34, -48, -37, -48, -71, -56, -34,
+ -43, -49, -36, -20, -14, -13, -9, -4, -1, 1, 3, 6, 6, 6, 9, 10,
+ 8, 10, 11, 11, 11, 11, 10, 10, 10, 10, 6, 6, 4, 3, 6, -3,
+ 2, 25, 23, 16, 34, 38, 43, 51, 31, 19, 38, 22, -10, -7, 0, -25,
+ -45, -34, -32, -54, -62, -47, -39, -45, -47, -36, -24, -19, -16, -11, -6, -3,
+ 0, 2, 4, 6, 7, 8, 10, 11, 9, 11, 12, 11, 11, 12, 11, 10,
+ 10, 8, 7, 6, 3, 5, 4, 0, 13, 28, 23, 19, 36, 50, 42, 30,
+ 31, 39, 24, -6, -2, 7, -21, -40, -27, -34, -51, -51, -44, -42, -45, -45,
+ -37, -27, -22, -18, -13, -9, -6, -2, 1, 2, 5, 7, 7, 9, 11, 10,
+ 10, 12, 12, 11, 12, 11, 10, 10, 9, 7, 7, 4, 5, 7, 1, 7,
+ 27, 24, 15, 34, 47, 37, 32, 36, 36, 26, 4, -1, 4, -13, -30, -27,
+ -34, -47, -46, -42, -43, -45, -44, -38, -31, -25, -21, -17, -12, -8, -5, -1,
+ 1, 3, 5, 6, 8, 9, 10, 10, 10, 11, 11, 11, 11, 11, 10, 9,
+ 7, 7, 6, 3, 6, 5, 6, 17, 23, 19, 29, 40, 35, 33, 36, 34,
+ 26, 14, 3, 0, -6, -18, -26, -32, -39, -40, -38, -39, -41, -40, -36, -31,
+ -27, -23, -19, -15, -12, -8, -4, -2, 0, 3, 4, 5, 7, 8, 9, 9,
+ 9, 10, 10, 10, 10, 10, 9, 8, 8, 8, 7, 8, 10, 11, 14, 19,
+ 22, 25, 28, 29, 29, 29, 27, 21, 14, 7, -1, -5, -11, -19, -26, -29,
+ -31, -32, -33, -34, -33, -32, -29, -26, -24, -21, -18, -15, -12, -9, -6, -4,
+ -2, 0, 2, 3, 5, 6, 7, 7, 8, 8, 9, 9, 9, 9, 9, 9,
+ 10, 10, 11, 12, 14, 16, 18, 20, 22, 23, 24, 24, 23, 20, 17, 12,
+ 7, 2, -3, -8, -13, -17, -21, -23, -25, -26, -27, -27, -27, -26, -25, -23,
+ -21, -19, -17, -14, -12, -9, -7, -5, -3, -1, 1, 2, 4, 5, 6, 6,
+ 7, 7, 8, 8, 9, 9, 10, 10, 11, 12, 13, 15, 16, 18, 19, 21,
+ 22, 22, 22, 21, 19, 17, 13, 9, 4, 0, -5, -10, -14, -18, -21, -23,
+ -25, -26, -26, -26, -26, -25, -23, -22, -20, -18, -15, -13, -11, -9, -6, -4,
+ -2, 0, 1, 3, 4, 5, 6, 7, 7, 8, 8, 8, 9, 9, 10, 11,
+ 12, 13, 14, 15, 17, 18, 20, 21, 21, 21, 21, 19, 17, 14, 11, 7,
+ 2, -3, -7, -11, -15, -19, -21, -23, -25, -25, -26, -25, -25, -24, -22, -21,
+ -19, -17, -15, -12, -10, -8, -6, -4, -2, 0, 1, 3, 4, 5, 6, 6,
+ 7, 8, 8, 9, 9, 10, 11, 11, 12, 13, 15, 16, 17, 19, 20, 20,
+ 21, 20, 19, 18, 15, 12, 8, 4, 0, -4, -9, -13, -16, -19, -21, -23,
+ -24, -25, -25, -25, -24, -23, -21, -20, -18, -16, -14, -12, -9, -7, -5, -3,
+ -2, 0, 1, 3, 4, 5, 6, 6, 7, 8, 8, 9, 10, 10, 11, 12,
+ 13, 14, 15, 17, 18, 19, 20, 20, 20, 19, 18, 16, 13, 10, 6, 2,
+ -2, -6, -10, -13, -16, -19, -21, -23, -24, -24, -24, -24, -23, -22, -20, -19,
+ -17, -15, -13, -11, -8, -6, -5, -3, -1, 0, 2, 3, 4, 5, 6, 7,
+ 7, 8, 9, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 19, 20,
+ 19, 18, 16, 14, 11, 8, 4, 0, -3, -7, -11, -14, -17, -19, -21, -22,
+ -23, -23, -23, -23, -22, -21, -19, -18, -16, -14, -12, -10, -8, -6, -4, -2,
+ -1, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 10, 11, 12, 12, 13,
+ 14, 15, 16, 17, 18, 19, 19, 19, 18, 17, 15, 12, 9, 6, 3, -1,
+ -5, -9, -12, -15, -17, -19, -21, -22, -23, -23, -23, -22, -21, -20, -18, -17,
+ -15, -13, -11, -9, -7, -6, -4, -2, -1, 1, 2, 3, 4, 5, 6, 7,
+ 8, 9, 9, 10, 11, 12, 13, 14, 15, 16, 17, 17, 18, 18, 18, 17,
+ 16, 14, 12, 10, 7, 4, 0, -3, -6, -9, -12, -15, -17, -18, -20, -20,
+ -21, -21, -21, -20, -19, -18, -17, -15, -14, -12, -10, -9, -7, -5, -4, -2,
+ -1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 14,
+ 15, 15, 16, 16, 16, 16, 16, 15, 14, 12, 11, 8, 6, 3, 0, -3,
+ -6, -9, -12, 1, -1, 2, -1, 4, 2, 8, 5, 10, -5, 0, 5, 17,
+ -11, 0, 19, -17, 26, 65, 15, 29, 3, 35, 67, 50, 88, 59, 117, 28,
+ -6, -16, 29, 63, 62, -40, 59, 22, -95, -49, -55, 19, 36, -15, 26, -117,
+ 60, 8, -101, -115, 23, 60, -32, -106, -84, -88, -127, -99, -117, -110, -56, -42,
+ -53, -79, -44, 43, 10, -11, 72, 22, 61, 10, -92, -106, -111, -35, -68, -128,
+ -67, -36, -118, -97, -96, -4, 75, 70, 113, 36, 73, 115, 37, 6, 79, 97,
+ 89, -8, -38, -8, -72, -8, -29, -35, 73, 98, 66, 12, 40, 113, 106, 87,
+ 126, 112, 127, 87, -3, -21, -23, 40, 14, -68, -20, 21, -57, -67, -67, -4,
+ 69, 53, 90, 17, 36, 78, -7, -54, -2, 32, 21, -71, -109, -89, -124, -103,
+ -114, -113, -37, -4, -30, -88, -83, 15, 13, -35, 42, 28, 33, 14, -90, -92,
+ -104, -37, -34, -115, -73, -9, -75, -89, -85, -29, 67, 51, 97, 55, 47, 115,
+ 46, -9, 42, 90, 96, 26, -36, 11, -43, -25, -6, -37, 59, 104, 88, 31,
+ 22, 96, 116, 69, 110, 119, 119, 109, 11, -15, -26, 18, 37, -45, -32, 34,
+ -13, -62, -62, -30, 61, 47, 75, 46, 14, 72, 14, -58, -35, 16, 30, -38,
+ -109, -78, -109, -116, -102, -123, -57, -2, -11, -58, -95, -18, 22, -41, -3, 36,
+ 20, 31, -69, -94, -100, -72, -21, -91, -92, -9, -33, -82, -81, -57, 48, 52,
+ 70, 81, 35, 97, 69, -10, 8, 66, 94, 55, -27, 4, -5, -40, -1, -33,
+ 30, 102, 101, 61, 19, 70, 121, 72, 77, 123, 112, 121, 36, -13, -21, -10,
+ 38, -18, -43, 27, 25, -40, -59, -45, 40, 54, 52, 68, 15, 56, 35, -48,
+ -58, -12, 25, -10, -98, -84, -83, -122, -101, -123, -81, -8, -3, -28, -85, -47,
+ 20, -28, -39, 23, 18, 31, -38, -99, -92, -97, -35, -66, -102, -26, -3, -60,
+ -77, -69, 18, 59, 47, 87, 46, 73, 86, 3, -13, 34, 80, 70, -8, -12,
+ 19, -32, -12, -21, 3, 91, 105, 87, 34, 51, 114, 89, 53, 106, 115, 119,
+ 65, -10, -13, -25, 20, 4, -45, 9, 44, -8, -49, -51, 14, 61, 39, 68,
+ 34, 39, 51, -30, -67, -41, 7, 5, -76, -96, -65, -111, -110, -115, -103, -20,
+ -1, -9, -58, -65, 8, -9, -55, -6, 17, 24, -11, -94, -89, -102, -64, -50,
+ -101, -51, 6, -30, -66, -71, -12, 59, 40, 72, 67, 58, 91, 24, -21, 6,
+ 56, 74, 14, -22, 23, -8, -24, -14, -13, 71, 106, 101, 62, 42, 101, 105,
+ 49, 76, 114, 114, 87, 3, -12, -23, -6, 13, -37, -11, 45, 24, -29, -49,
+ -8, 57, 40, 53, 54, 32, 56, -6, -65, -61, -21, 6, -52, -101, -65, -85,
+ -115, -109, -116, -42, 0, -1, -27, -65, -12, 7, -51, -37, 7, 17, 6, -76,
+ -95, -94, -91, -52, -90, -76, -2, -4, -46, -66, -35, 46, 46, 49, 78, 57,
+ 85, 50, -17, -13, 26, 64, 34, -22, 9, 18, -22, -14, -18, 42, 103, 105,
+ 88, 50, 83, 114, 63, 49, 96, 110, 99, 26, -14, -15, -23, 6, -24, -29,
+ 33, 45, 0, -38, -23, 44, 50, 37, 60, 38, 52, 21, -54, -70, -48, -7,
+ -31, -95, -78, -63, -104, -108, -117, -69, -4, -1, -5, -47, -30, 13, -33, -58,
+ -14, 8, 11, -50, -99, -87, -101, -70, -77, -92, -22, 10, -22, -52, -46, 23,
+ 55, 36, 70, 66, 74, 69, -2, -23, 1, 43, 43, -11, -8, 29, -4, -17,
+ -16, 18, 91, 105, 102, 71, 72, 112, 83, 40, 70, 101, 102, 50, -10, -10,
+ -24, -10, -13, -36, 14, 52, 27, -18, -28, 26, 58, 33, 51, 49, 46, 40,
+ -34, -70, -66, -31, -22, -81, -92, -56, -83, -105, -112, -91, -17, 0, 2, -22,
+ -37, 7, -12, -61, -39, -5, 7, -27, -93, -90, -96, -90, -72, -95, -48, 9,
+ -1, -33, -46, 0, 55, 37, 50, 72, 68, 77, 20, -25, -15, 17, 40, 3,
+ -20, 22, 19, -12, -14, 2, 70, 105, 106, 92, 72, 104, 100, 48, 46, 83,
+ 98, 70, 3, -12, -16, -23, -11, -34, -8, 46, 47, 11, -21, 8, 57, 41,
+ 36, 53, 45, 48, -6, -64, -72, -57, -28, -61, -98, -65, -60, -94, -105, -103,
+ -41, 1, 0, -1, -29, -6, 5, -48, -60, -26, -3, -12, -74, -97, -86, -100,
+ -80, -89, -74, -6, 13, -10, -35, -18, 41, 48, 33, 64, 68, 75, 46, -15,
+ -25, -7, 24, 16, -20, 4, 33, 5, -11, -5, 43, 98, 105, 105, 85, 93,
+ 110, 67, 35, 59, 87, 81, 25, -13, -9, -23, -18, -27, -25, 30, 55, 37,
+ -1, -3, 46, 53, 29, 44, 47, 48, 20, -48, -72, -72, -47, -48, -93, -82,
+ -51, -73, -96, -102, -66, -6, 0, 5, -10, -16, 10, -26, -66, -49, -20, -10,
+ -51, -98, -86, -93, -93, -85, -88, -32, 14, 8, -16, -23, 22, 54, 32, 45,
+ 67, 70, 61, 4, -27, -21, 2, 17, -13, -13, 29, 26, -1, -5, 23, 83,
+ 104, 106, 100, 90, 110, 87, 40, 38, 68, 80, 45, -6, -9, -14, -24, -23,
+ -32, 8, 52, 53, 25, 1, 31, 60, 35, 30, 45, 45, 36, -24, -68, -76,
+ -67, -49, -80, -94, -57, -54, -81, -95, -82, -23, 2, 1, 4, -12, 4, -5,
+ -57, -65, -40, -20, -36, -87, -94, -83, -97, -87, -90, -57, 2, 18, 2, -12,
+ 8, 10, -20, 30, 25, 21, 14, 4, 15, -48, -33, 11, -70, 54, -5, -21,
+ -8, -3, 73, -52, 65, -55, 80, -28, -67, -3, -13, 21, -49, -2, 11, 36,
+ 59, -60, 34, -28, 21, -25, -45, 54, 5, 0, -19, -12, 20, 54, -51, -23,
+ 22, 36, -59, -20, 8, 28, -9, -54, 127, -44, 69, -128, 5, 69, -8, -98,
+ 45, 69, 20, -97, 23, -7, 121, -81, -2, -21, 51, -67, -14, -24, 127, -60,
+ 45, -116, 127, -29, -93, -23, 107, -5, -21, -62, 37, 41, 29, -74, -63, 103,
+ 24, -59, -44, 62, 43, -28, -46, 7, 72, 19, -70, -47, 42, 53, -68, -13,
+ 37, 59, -38, -60, 39, 66, 27, -128, 36, 77, 15, -74, -15, 75, 38, -49,
+ -11, -39, 16, -8, -30, 35, 41, -1, -2, 17, -68, 99, -97, 60, -49, 32,
+ -44, -29, 82, -26, 39, -35, 10, 38, -20, -21, -92, 83, -24, 13, 31, -33,
+ 22, 45, -31, -24, 9, -24, -32, 42, -17, 34, 7, -27, 6, 61, -9, -34,
+ -5, -8, -17, -6, -34, 17, 43, -9, 35, -34, 16, 27, -24, -17, -17, 5,
+ -17, 42, -31, 22, 17, -26, -22, 32, 41, -27, -25, -10, -5, 16, -2, 13,
+ -1, 48, -33, -27, 6, 16, 13, -37, -11, 18, 25, -42, -11, 46, -7, -15,
+ 9, 15, 4, -3, -36, -24, 31, -8, 14, 12, 27, -19, -17, -14, -7, 42,
+ -5, -15, 5, 1, -15, 14, 43, -19, 1, -25, -35, 16, 16, 29, -12, 8,
+ -14, 1, 21, -8, -12, -22, -4, 24, 26, -16, -22, 37, 3, -41, 7, 4,
+ 3, 30, 4, -27, 11, -6, -26, 33, 23, -23, -14, -20, -7, -4, 36, 0,
+ 18, 10, -27, 1, 1, 16, -1, -4, -44, -5, 17, 9, 13, -4, -3, 31,
+ 24, -14, -26, 9, -27, -28, 19, 22, 32, -11, -15, 5, 15, -23, -21, 16,
+ 14, 18, -11, -26, 13, 10, -12, -12, 11, 14, -6, -13, -3, 6, -6, 3,
+ 12, 32, 14, -22, -45, -10, 37, 11, -50, -11, 50, 22, -13, -4, -4, 15,
+ -16, -33, 7, 34, -9, -14, -1, 21, 15, -14, -12, -6, 7, 8, 2, 0,
+ -5, 6, 15, 4, -9, 13, 3, -51, -18, 27, 10, 5, -11, 6, -1, 5,
+ 22, 2, -14, -39, -12, 19, 17, 4, 11, 5, -25, 2, 23, 8, 2, -3,
+ -39, -22, 4, 18, 6, 14, 25, 20, -17, -20, 17, 7, -43, -38, -18, 17,
+ 24, -6, 30, 44, 6, -36, -20, 7, 24, 1, -69, -25, 47, 15, -4, 35,
+ 19, -18, -22, -12, 20, 39, -36, -49, 9, 28, -16, 9, 34, 36, -22, -69,
+ -16, 39, 7, -28, -3, 33, -18, -7, 18, 53, 24, -37, -61, -10, 38, 2,
+ -24, -11, 12, 17, 0, 28, 50, -5, -59, -57, 22, 14, -15, -5, 22, 9,
+ -20, 19, 33, 31, -33, -62, -13, -2, 45, -9, -4, -3, 19, 8, -8, 40,
+ 8, -16, -44, -19, 16, 3, 23, -32, 22, 5, -9, 5, 26, 21, -27, -18,
+ -45, 3, 15, 0, 7, 7, 7, 13, 18, -10, 3, -5, -30, -30, -3, 9,
+ 31, 17, -10, 19, 28, -33, -20, 31, 14, -67, -27, 13, 20, 29, 1, -2,
+ 24, -3, -26, -12, 32, -7, -31, -17, 5, 22, 11, -6, 6, 7, 2, 7,
+ 5, -12, -22, -17, -24, 22, 47, 1, 2, 10, 5, -29, -5, 13, 1, -30,
+ -28, -5, 23, 25, 6, 5, 1, 7, 0, 5, 3, -33, -37, -6, 19, 20,
+ 26, -1, -15, 21, 9, -14, -13, 0, -11, -24, -9, 9, 23, 1, 1, 32,
+ 11, -25, -18, 5, -5, -6, -9, -10, 2, 18, 4, 12, 6, -2, -8, 2,
+ 2, -7, 2, -22, -5, 17, 25, 15, -5, -1, -24, -8, -10, -5, 12, 7,
+ -4, -10, 4, 8, 22, 11, -1, -12, -31, -17, 6, 12, 11, 5, -3, -1,
+ 22, 0, -4, 3, -18, -17, -3, 16, 9, 2, -5, 0, 4, -9, 18, 17,
+ -22, -19, -8, -6, 21, 11, -6, -16, 33, 13, -15, -3, -15, 1, -3, -10,
+ -7, 8, 17, -11, 9, 19, 0, 5, 0, -18, -13, 2, -20, 10, 29, -11,
+ -13, 5, 11, 16, 4, -25, -21, 13, -5, 1, 3, -1, 6, 13, -7, -1,
+ 17, -6, -6, -9, -6, -3, -1, 1, 18, 11, -22, 2, 18, -2, -15, 1,
+ 5, -12, -10, -7, 9, 26, 10, -11, 5, 0, -7, -3, -11, -9, -3, 2,
+ -10, 19, 28, -3, -3, -4, 9, -14, -5, -7, 8, -3, -27, 5, 37, 11,
+ -2, 3, -27, -15, 12, -2, 14, 2, -8, -16, 22, 11, -1, 10, -17, -8,
+ -5, -23, 2, 29, 8, -21, 8, 12, 6, 8, -17, 3, -2, -12, -27, 16,
+ 25, -5, -7, 2, 19, 1, -15, 7, 2, -5, -34, 2, 18, 17, -10, 2,
+ 18, -1, -12, -10, 5, 1, -16, -9, 12, 21, 4, -10, 2, 12, 1, -19,
+ -11, 20, 5, -14, -21, 5, 17, -5, 3, 17, 4, -25, -5, 5, 4, 0,
+ -5, 2, 2, -1, 1, 13, 0, -11, -8, 3, 2, -1, -3, -3, 11, 8,
+ -6, 2, 7, 4, -5, -23, -2, 14, -1, -15, -2, 15, 10, 1, -4, 16,
+ 1, -24, -12, 8, 8, -20, -2, 14, 13, 10, 2, 2, -9, -6, -9, -3,
+ 5, 7, -3, -9, 0, 2, 8, 3, -1, 2, -4, 0, -1, -1, -1, -2,
+ -8, -14, -19, -28, -51, -53, -49, -48, -49, -44, -37, -30, -23, -14, -8, -11,
+ -5, 3, 11, 2, 0, 8, 19, 10, 1, 6, 18, 15, 4, 4, 17, 19,
+ 13, 9, 20, 27, 26, 26, 33, 42, 45, 53, 59, 68, 69, 83, 89, 92,
+ 85, 88, 91, 80, 56, 37, 29, 9, -25, -54, -65, -74, -94, -113, -112, -103,
+ -101, -103, -93, -79, -66, -62, -50, -41, -33, -27, -17, -11, -12, -8, 0, 7,
+ -1, -2, 5, 15, 8, -1, 3, 15, 13, 2, 2, 12, 17, 12, 8, 15,
+ 23, 24, 25, 29, 38, 42, 50, 56, 65, 68, 78, 87, 91, 87, 87, 91,
+ 84, 64, 43, 33, 16, -14, -44, -60, -70, -87, -107, -111, -105, -101, -103, -96,
+ -84, -70, -64, -55, -45, -36, -30, -22, -14, -14, -11, -4, 4, 0, -3, 1,
+ 11, 8, -1, 0, 10, 12, 3, 0, 9, 15, 11, 7, 14, 22, 23, 24,
+ 28, 37, 42, 49, 55, 64, 67, 78, 87, 91, 88, 88, 93, 86, 67, 47,
+ 36, 20, -10, -40, -56, -67, -84, -104, -109, -105, -101, -103, -96, -85, -71, -65,
+ -56, -46, -38, -31, -23, -16, -15, -12, -6, 2, -1, -5, 0, 9, 6, -1,
+ -1, 8, 11, 3, 0, 8, 14, 11, 7, 13, 21, 23, 23, 27, 37, 41,
+ 48, 54, 63, 67, 77, 86, 91, 89, 89, 93, 87, 70, 51, 39, 23, -6,
+ -36, -53, -64, -81, -101, -107, -103, -100, -102, -96, -85, -72, -66, -57, -47, -39,
+ -32, -25, -17, -16, -13, -7, 0, -3, -5, -1, 7, 6, -2, -2, 7, 9,
+ 2, -1, 7, 13, 10, 7, 12, 20, 22, 23, 27, 36, 41, 48, 54, 63,
+ 68, 77, 87, 91, 91, 91, 95, 89, 73, 54, 43, 27, -1, -31, -49, -61,
+ -78, -98, -105, -102, -99, -101, -96, -85, -73, -66, -58, -48, -40, -33, -26, -19,
+ -17, -14, -9, -2, -4, -6, -3, 5, 4, -3, -3, 5, 8, 1, -1, 6,
+ 12, 10, 7, 11, 20, 22, 23, 27, 35, 41, 47, 54, 62, 68, 76, 86,
+ 91, 91, 92, 96, 91, 76, 58, 46, 30, 3, -27, -45, -57, -75, -94, -103,
+ -100, -98, -100, -96, -85, -74, -67, -59, -49, -41, -34, -28, -20, -19, -15, -10,
+ -3, -5, -7, -4, 3, 3, -4, -4, 4, 7, 1, -2, 5, 11, 9, 6,
+ 11, 19, 21, 22, 26, 35, 40, 46, 53, 61, 67, 76, 86, 91, 92, 93,
+ 97, 93, 78, 61, 49, 33, 7, -22, -41, -54, -72, -91, -100, -99, -97, -100,
+ -96, -86, -74, -67, -60, -51, -42, -35, -29, -22, -20, -17, -11, -5, -6, -8,
+ -5, 2, 1, -5, -5, 2, 5, 0, -3, 3, 10, 8, 5, 10, 18, 21,
+ 21, 25, 34, 39, 45, 52, 61, 67, 75, 85, 91, 92, 94, 97, 94, 81,
+ 64, 52, 37, 11, -18, -37, -51, -69, -88, -98, -98, -96, -99, -95, -86, -75,
+ -68, -61, -52, -44, -36, -30, -23, -21, -17, -13, -6, -7, -9, -6, 0, 0,
+ -5, -5, 1, 4, -1, -3, 2, 8, 8, 5, 10, 17, 20, 21, 25, 33,
+ 39, 45, 51, 60, 66, 75, 85, 91, 93, 94, 98, 95, 83, 67, 55, 40,
+ 15, -14, -33, -48, -66, -85, -96, -96, -95, -98, -95, -86, -75, -69, -62, -53,
+ -45, -38, -32, -25, -22, -19, -14, -8, -9, -10, -8, -2, -1, -6, -7, -1,
+ 2, -2, -4, 1, 7, 6, 5, 8, 16, 19, 20, 24, 32, 38, 44, 50,
+ 59, 66, 74, 84, 91, 93, 95, 99, 97, 85, 70, 58, 43, 18, -10, -30,
+ -45, -63, -82, -93, -95, -94, -97, -95, -87, -76, -70, -63, -54, -46, -39, -33,
+ -26, -23, -20, -16, -10, -10, -12, -9, -3, -3, -7, -8, -2, 1, -2, -5,
+ 0, 6, 6, 4, 8, 15, 18, 20, 23, 31, 37, 43, 50, 58, 65, 74,
+ 83, 91, 93, 96, 100, 98, 87, 72, 61, 46, 22, -6, -27, -42, -60, -79,
+ -91, -94, -93, -97, -95, -87, -77, -70, -64, -55, -47, -40, -34, -28, -25, -22,
+ -17, -12, -11, -13, -11, -5, -4, -8, -9, -3, 0, -4, -6, -1, 5, 5,
+ 3, 7, 14, 18, 19, 23, 30, 36, 42, 49, 57, 65, 73, 83, 90, 94,
+ 96, 100, 99, 89, 75, 63, 49, 25, -2, -23, -38, -56, -76, -88, -92, -92,
+ -95, -94, -87, -77, -71, -65, -57, -48, -41, -36, -29, -26, -23, -19, -13, -12,
+ -14, -12, -7, -6, -9, -10, -5, -1, -4, -7, -2, 2, 5, 4, 6, 12,
+ 18, 20, 24, 30, 38, 45, 52, 61, 70, 79, 89, 99, 106, 109, 113, 115,
+ 109, 96, 81, 66, 44, 16, -12, -32, -52, -74, -92, -101, -104, -107, -108, -103,
+ -94, -85, -78, -70, -60, -52, -45, -38, -33, -29, -25, -19, -16, -17, -16, -12,
+ -9, -10, -12, -9, -5, -5, -7, -5, 0, 3, 3, 5, 11, 17, 20, 23,
+ 29, 37, 44, 51, 59, 69, 78, 88, 98, 105, 110, 114, 116, 110, 98, 84,
+ 69, 48, 20, -7, -29, -49, -71, -89, -99, -102, -105, -107, -103, -94, -86, -79,
+ -71, -62, -54, -47, -40, -34, -30, -26, -21, -18, -18, -17, -14, -10, -12, -14,
+ -11, -5, -10, 43, -94, 44, -13, 27, -98, 1, 9, 77, 63, 4, 8, -128,
+ 63, -73, 78, -116, 127, -14, 111, -87, -67, -43, -45, 38, 53, 99, -37, 14,
+ -51, -58, -23, -32, 34, 27, 75, 9, 51, -104, -71, -33, 27, 67, 0, -1,
+ 25, 0, -35, 1, -70, 28, -4, 109, 3, 5, -42, -7, 42, -15, 37, -62,
+ 67, -14, 48, -85, -46, -94, 37, 35, 23, 15, -79, 35, -50, 91, -64, 40,
+ -69, 46, 20, 43, -21, -51, 8, -1, 95, -47, 69, -104, 98, -44, 74, -61,
+ -14, -19, 7, 52, -40, 8, -89, 58, -53, 106, -106, 42, -82, 61, -1, -8,
+ -10, -59, 53, -18, 85, -83, 63, -73, 89, -32, 50, -62, 10, 13, 20, 62,
+ -81, 41, -84, 88, -32, 41, -78, 27, -30, 51, -6, -42, 6, -49, 74, -41,
+ 41, -89, 27, -33, 57, 0, -16, -8, -4, 45, 8, 20, -63, 36, -29, 75,
+ -23, -17, -23, -14, 45, -7, 17, -56, 20, -12, 45, -16, -13, -31, 6, 31,
+ -7, 17, -81, 40, -35, 73, -34, 0, -31, 10, 35, -4, 19, -60, 44, -30,
+ 83, -66, 41, -87, 59, -6, 23, -4, -59, 34, -33, 77, -70, 49, -89, 88,
+ -45, 63, -62, 4, -20, 18, 46, -49, 45, -101, 91, -56, 78, -79, 35, -51,
+ 67, -12, -2, -14, -49, 66, -35, 72, -87, 51, -74, 83, -38, 29, -36, -10,
+ 23, 3, 30, -59, 27, -59, 91, -44, 41, -63, 12, 2, 23, 8, -36, 14,
+ -35, 66, -38, 32, -59, 25, -11, 40, -6, -25, -2, -24, 55, -25, 29, -58,
+ 30, -17, 41, -18, -17, -3, -13, 50, -25, 26, -63, 35, -23, 50, -22, -5,
+ -18, 0, 33, -19, 22, -67, 57, -39, 63, -45, 6, -27, 13, 23, -6, 15,
+ -55, 44, -42, 70, -59, 36, -60, 56, -13, 15, -9, -50, 49, -38, 72, -63,
+ 37, -65, 67, -48, 55, -51, 10, 2, -5, 45, -61, 46, -83, 91, -58, 72,
+ -69, 23, -27, 35, -8, -3, -2, -33, 66, -61, 79, -100, 67, -60, 66, -26,
+ 13, -21, -13, 23, -11, 29, -49, 40, -53, 80, -67, 52, -63, 28, 6, -1,
+ 23, -45, 25, -30, 42, -25, 22, -42, 33, -26, 39, -26, -9, 10, -28, 61,
+ -50, 33, -43, 18, 2, 6, 4, -18, 4, -8, 24, -21, 22, -49, 50, -40,
+ 52, -35, -10, 17, -34, 64, -53, 38, -47, 37, -28, 40, -47, 33, -32, 28,
+ 3, -20, 30, -69, 79, -75, 88, -72, 39, -34, 22, -7, 9, -18, 1, 19,
+ -27, 58, -89, 81, -90, 89, -58, 42, -27, -5, 16, -21, 29, -34, 28, -37,
+ 59, -65, 72, -90, 69, -45, 31, 6, -36, 40, -53, 56, -47, 39, -42, 40,
+ -38, 50, -52, 34, -31, 7, 32, -47, 62, -79, 66, -51, 41, -27, 12, -10,
+ 12, -5, 3, -5, -18, 33, -44, 70, -75, 60, -52, 27, 4, -19, 22, -29,
+ 27, -15, 18, -31, 26, -36, 50, -41, 35, -31, 3, 19, -37, 55, -62, 51,
+ -38, 25, -11, 1, -13, 12, -7, 13, 4, -33, 38, -56, 72, -64, 52, -43,
+ 20, 6, -20, 25, -40, 34, -25, 38, -41, 43, -68, 68, -59, 53, -28, -7,
+ 27, -45, 63, -70, 56, -60, 59, -41, 48, -56, 39, -43, 35, -3, -19, 40,
+ -70, 85, -81, 76, -75, 48, -36, 41, -20, 12, -23, 0, 16, -23, 51, -76,
+ 78, -82, 80, -57, 29, -23, 3, 14, -2, 9, -29, 17, -31, 55, -51, 53,
+ -66, 49, -27, 17, 3, -35, 36, -33, 44, -27, 11, -30, 24, -18, 37, -29,
+ 4, -3, -15, 45, -47, 42, -57, 46, -19, 18, -11, -20, 10, -3, 24, -18,
+ 14, -46, 52, -50, 64, -57, 25, -14, 1, 33, -42, 30, -52, 50, -28, 47,
+ -54, 32, -49, 53, -25, 14, -4, -34, 57, -54, 69, -78, 46, -45, 52, -21,
+ 21, -37, 7, 1, 3, 29, -57, 56, -74, 90, -66, 47, -51, 16, 6, 10,
+ 10, -29, 9, -32, 58, -47, 59, -84, 65, -49, 52, -24, -18, 14, -30, 61,
+ -39, 31, -57, 39, -38, 67, -56, 37, -46, 26, 10, -15, 18, -49, 45, -27,
+ 42, -37, 11, -24, 30, -15, 21, -34, 15, -5, 11, 5, -24, 11, -16, 30,
+ -16, 6, -20, 7, 3, 11, -9, -5, -6, 4, 16, -15, 9, -29, 22, -6,
+ 14, -6, -16, 9, -12, 28, -22, 15, -27, 22, -11, 21, -23, 5, -10, 8,
+ 17, -22, 19, -42, 41, -31, 39, -37, 20, -20, 19, -3, -7, 2, -17, 27,
+ -20, 30, -43, 30, -34, 38, -24, 13, -13, -1, 16, -16, 19, -36, 28, -21,
+ 30, -22, 7, -17, 11, 2, 1, 1, -19, 22, -21, 32, -34, 18, -21, 17,
+ 6, -8, 5, -25, 21, -13, 24, -24, 12, -22, 24, -11, 10, -14, -7, 15,
+ -11, 28, -36, 21, -30, 30, -10, 10, -13, -5, 6, -2, 14, -22, 15, -25,
+ 33, -22, 23, -31, 11, -6, 8, 11, -21, 14, -28, 32, -23, 25, -31, 19,
+ -15, 19, -7, -7, 1, -13, 26, -19, 24, -37, 25, -24, 30, -18, 6, -9,
+ -2, 17, -16, 17, -34, 27, -19, 28, -21, 6, -15, 10, 4, 0, 2, -20,
+ 22, -19, -21, 0, -3, -3, 2, 1, -1, 2, -2, -1, 4, 3, -3, -15,
+ -21, -20, -23, -42, -45, -31, -27, -17, -8, 9, 29, 41, 44, 33, 20, 13,
+ 6, 12, 16, 25, 43, 44, 33, 33, 35, 15, -5, -3, 8, 16, 8, -10,
+ -6, 8, 4, -4, 1, -18, -38, -43, -51, -54, -55, -71, -85, -68, -58, -61,
+ -50, -33, -27, -15, -5, 22, 67, 100, 109, 114, 110, 91, 69, 50, 37, 35,
+ 46, 48, 37, 36, 14, -24, -38, -42, -38, -38, -59, -91, -86, -57, -44, -32,
+ -15, -26, -44, -30, -30, -30, -16, -31, -50, -34, -43, -59, -49, -44, -52, -62,
+ -69, -50, -4, 47, 83, 105, 120, 111, 88, 72, 55, 57, 76, 69, 59, 55,
+ 41, 10, -18, -32, -28, -19, -36, -68, -76, -72, -71, -46, -35, -47, -43, -43,
+ -61, -48, -28, -25, -22, -19, -23, -15, -7, 3, 4, -8, -28, -37, -5, 42,
+ 72, 107, 127, 122, 117, 90, 48, 37, 48, 51, 54, 56, 43, 24, -8, -37,
+ -33, -11, -28, -55, -61, -75, -75, -51, -58, -55, -33, -33, -41, -35, -30, -21,
+ -16, -17, -24, -26, -20, -18, -17, -12, -36, -72, -65, -45, -6, 53, 88, 106,
+ 119, 107, 71, 52, 50, 59, 75, 87, 85, 76, 43, -1, -7, 9, -1, -13,
+ -34, -69, -80, -74, -80, -73, -65, -67, -65, -56, -44, -33, -23, -18, -24, -25,
+ -16, -20, -9, -1, -21, -38, -55, -64, -40, 3, 39, 82, 113, 114, 95, 71,
+ 54, 56, 68, 76, 87, 94, 57, 10, -9, -17, -17, -15, -35, -60, -75, -89,
+ -92, -85, -76, -71, -74, -70, -53, -41, -20, -9, -9, 4, 4, 10, 33, 38,
+ 25, 15, -17, -43, -33, -15, 3, 40, 77, 94, 91, 69, 37, 31, 33, 37,
+ 68, 96, 82, 53, 25, 8, 22, 28, 9, -9, -27, -46, -56, -65, -62, -61,
+ -60, -51, -51, -39, -25, -23, -11, -3, -15, -10, 5, 12, 20, 18, -11, -41,
+ -52, -47, -34, -2, 33, 65, 82, 70, 51, 45, 28, 21, 49, 74, 86, 74,
+ 33, 5, 10, 14, 7, -10, -28, -45, -67, -68, -73, -76, -66, -66, -65, -46,
+ -39, -31, -9, -3, -6, 1, 8, 22, 41, 49, 33, 8, -16, -34, -30, -17,
+ 7, 49, 73, 64, 63, 50, 19, 5, 13, 32, 62, 65, 37, 8, -5, 4,
+ -1, -8, -15, -36, -50, -57, -71, -65, -53, -58, -49, -37, -40, -28, -10, -3,
+ 0, 2, -2, 5, 30, 41, 36, 22, -7, -33, -39, -46, -30, 15, 44, 56,
+ 72, 65, 44, 21, 2, 15, 42, 59, 49, 18, 2, -3, -4, 0, -10, -25,
+ -34, -52, -65, -59, -56, -50, -37, -33, -33, -25, -12, -2, 10, 12, 3, 6,
+ 27, 42, 52, 43, 16, -3, -24, -48, -41, -11, 16, 48, 67, 78, 75, 49,
+ 21, 13, 36, 64, 63, 47, 25, -1, -2, 2, -12, -18, -28, -53, -65, -71,
+ -76, -70, -55, -53, -49, -41, -35, -24, -1, 5, 1, 4, 8, 28, 51, 43,
+ 26, 18, -14, -42, -51, -49, -23, 5, 31, 55, 67, 58, 26, -2, 11, 35,
+ 49, 55, 35, 8, 3, -2, -5, -6, -13, -30, -38, -49, -61, -56, -45, -43,
+ -36, -31, -37, -25, -7, 1, 6, 1, -10, 11, 33, 29, 27, 17, -6, -34,
+ -58, -67, -57, -34, -4, 21, 50, 63, 37, 11, 8, 17, 45, 63, 55, 39,
+ 26, 12, 11, 10, -1, -11, -19, -35, -51, -52, -52, -45, -35, -36, -41, -31,
+ -24, -9, 9, -3, -12, 2, 19, 33, 40, 37, 25, -3, -30, -51, -59, -42,
+ -24, -3, 38, 58, 51, 32, 8, 2, 25, 45, 50, 49, 35, 18, 16, 19,
+ 10, 9, 4, -13, -27, -36, -45, -36, -24, -32, -29, -31, -33, -10, 6, 1,
+ -4, -6, 4, 19, 30, 37, 30, 12, -13, -48, -59, -57, -56, -35, 2, 31,
+ 48, 41, 12, -2, 7, 25, 41, 52, 44, 29, 25, 22, 18, 20, 15, 1,
+ -6, -26, -38, -28, -26, -21, -17, -31, -33, -19, -4, 0, -8, -16, -15, -11,
+ 9, 19, 22, 24, -2, -34, -49, -61, -70, -57, -32, 4, 38, 46, 26, 5,
+ -1, 7, 29, 45, 44, 38, 32, 23, 27, 30, 23, 24, 14, -8, -16, -24,
+ -24, -12, -10, -19, -27, -26, -9, -2, -4, -6, -16, -14, -2, 8, 23, 34,
+ 17, -6, -26, -47, -61, -62, -50, -18, 26, 50, 48, 31, 12, 6, 24, 40,
+ 44, 51, 40, 29, 34, 28, 27, 32, 20, 7, -5, -23, -26, -19, -9, -12,
+ -25, -25, -17, -8, 1, -4, -13, -12, -16, -9, 13, 26, 23, 8, -13, -37,
+ -55, -71, -78, -59, -18, 16, 35, 34, 8, -3, 4, 13, 31, 40, 34, 34,
+ 29, 23, 30, 31, 27, 21, 7, -6, -21, -21, -10, -10, -19, -24, -28, -17,
+ -6, -8, -9, -9, -19, -21, -5, 12, 23, 22, 5, -16, -34, -55, -80, -78,
+ -56, -22, 18, 33, 24, 14, 3, 7, 25, 31, 37, 41, 33, 29, 29, 32,
+ 33, 30, 24, 7, -16, -22, -18, -15, -14, -24, -31, -22, -13, -12, -8, -6,
+ -18, -27, -22, -6, -5, -1, -1, -1, 1, 2, 7, 13, 19, 10, -12, -31,
+ -13, 17, 29, -4, -29, 24, 53, 18, 92, 15, -15, 23, 13, -35, -52, 127,
+ 9, 3, -9, 31, -63, -64, -5, -50, 14, 33, -29, -42, 0, 43, 39, -15,
+ -59, -45, 3, 33, 12, -35, -10, 51, 18, 49, 55, -28, 16, 4, 3, -64,
+ 54, 53, -12, 0, 5, -4, -72, -7, -31, -14, 26, -2, -37, -14, 17, 35,
+ 4, -33, -45, -12, 15, 21, -16, -23, 22, 28, 12, 55, -7, -2, 7, 7,
+ -34, -10, 65, -4, 1, -5, 14, -46, -28, -9, -29, 13, 13, -23, -23, 4,
+ 27, 18, -17, -39, -25, 5, 20, 0, -26, 1, 34, 7, 41, 24, -20, 11,
+ 1, -6, -45, 53, 22, -6, -4, 9, -17, -52, -4, -30, -6, 20, -9, -29,
+ -8, 18, 27, -2, -33, -36, -6, 16, 13, -20, -16, 27, 19, 18, 49, -17,
+ 3, 2, 6, -42, 9, 55, -9, 1, -3, 9, -54, -19, -16, -24, 16, 7,
+ -27, -19, 8, 28, 12, -22, -40, -20, 8, 19, -7, -25, 9, 31, 7, 48,
+ 9, -14, 9, 2, -17, -35, 62, 9, -2, -6, 13, -30, -44, -4, -31, 2,
+ 18, -15, -27, -3, 22, 24, -8, -36, -32, -2, 17, 8, -23, -9, 31, 13,
+ 28, 40, -21, 8, 1, 3, -47, 29, 43, -9, 0, 1, 1, -57, -11, -22,
+ -17, 19, 2, -28, -14, 12, 29, 7, -27, -39, -14, 11, 17, -13, -22, 17,
+ 27, 10, 51, -4, -7, 7, 5, -27, -19, 64, -1, 1, -6, 14, -41, -34,
+ -8, -30, 8, 15, -20, -24, 2, 25, 20, -14, -38, -27, 2, 18, 2, -25,
+ -1, 33, 9, 37, 29, -21, 11, 0, -3, -46, 46, 29, -7, -2, 7, -9,
+ -54, -6, -27, -10, 20, -4, -28, -9, 16, 28, 1, -30, -37, -8, 14, 14,
+ -18, -17, 25, 22, 16, 50, -13, 1, 4, 5, -37, 0, 59, -7, 2, -4,
+ 12, -49, -24, -13, -26, 13, 11, -23, -19, 6, 27, 15, -19, -39, -21, 6,
+ 18, -4, -24, 7, 32, 8, 45, 15, -16, 10, 2, -12, -39, 58, 16, -3,
+ -5, 11, -22, -48, -4, -30, -2, 19, -10, -26, -4, 20, 25, -5, -34, -33,
+ -4, 16, 10, -21, -11, 30, 16, 25, 43, -19, 7, 1, 4, -44, 20, 49,
+ -8, 1, -1, 6, -54, -15, -19, -20, 17, 6, -26, -15, 10, 29, 9, -23,
+ -39, -16, 9, 17, -10, -22, 15, 29, 10, 50, 2, -10, 8, 3, -22, -26,
+ 63, 5, 0, -6, 14, -34, -39, -6, -30, 4, 17, -15, -24, 0, 24, 22,
+ -11, -36, -28, 1, 17, 5, -23, -3, 32, 12, 34, 33, -21, 10, 0, 0,
+ -46, 39, 36, -7, -1, 4, -3, -54, -9, -24, -14, 19, 0, -26, -10, 14,
+ 28, 4, -27, -37, -11, 12, 15, -15, -18, 22, 24, 14, 50, -9, -2, 5,
+ 5, -32, -8, 61, -3, 2, -5, 14, -44, -29, -10, -27, 10, 13, -20, -20,
+ 4, 26, 17, -16, -37, -23, 4, 18, -1, -23, 5, 32, 9, 42, 20, -18,
+ 11, 1, -7, -41, 53, 22, -4, -3, 9, -14, -50, -6, -27, -7, 19, -6,
+ -26, -5, 18, 26, -2, -31, -34, -6, 14, 11, -19, -12, 28, 19, 22, 45,
+ -17, 4, 2, 5, -40, 11, 54, -6, 2, -3, 10, -51, -20, -16, -23, 14,
+ 9, -23, -15, 8, 28, 12, -20, -38, -18, 7, 17, -7, -22, 13, 30, 10,
+ 47, 7, -12, 9, 2, -17, -31, 61, 10, 0, -5, 13, -26, -43, -6, -29,
+ 0, 18, -11, -23, -1, 22, 23, -8, -34, -30, -1, 15, 7, -22, -5, 31,
+ 14, 30, 37, -20, 9, 0, 2, -44, 30, 42, -7, 1, 2, 2, -53, -12,
+ -21, -17, 17, 4, -25, -11, 12, 28, 6, -25, -37, -13, 10, 15, -13, -18,
+ 20, 26, 13, 49, -5, -5, 6, 4, -27, -16, 62, 1, 2, -5, 14, -38,
+ -34, -9, -28, 6, 15, -16, -20, 3, 25, 19, -13, -36, -25, 2, 16, 1,
+ -23, 3, 32, 11, 38, 25, -19, 11, 0, -4, -43, 46, 29, -4, -2, 7,
+ -8, -51, -8, -25, -10, 18, -2, -25, -7, 16, 27, 0, -28, -35, -8, 12,
+ 12, -17, -13, 26, 21, 19, 46, -14, 2, 3, 4, -36, 2, 57, -4, 3,
+ -4, 12, -46, -25, -13, -25, 11, 12, -20, -16, 7, 27, 14, -18, -37, -20,
+ 5, 16, -5, -21, 10, 31, 10, 45, 12, -14, 10, 1, -12, -36, 57, 16,
+ -1, -4, 11, -20, -46, -6, -28, -4, 18, -8, -23, -3, 20, 24, -5, -32,
+ -31, -4, 13, 8, -20, -6, 29, 17, 27, 39, -19, 7, 0, 3, -42, 21,
+ 47, -6, 2, 0, 7, -51, -17, -18, -20, 15, 7, -23, -12, 10, 28, 8,
+ -22, -37, -15, 8, 15, -10, -19, 18, 27, 13, 47, 0, -8, 8, 3, -24,
+ -20, 52, -36, -2, 0, -2, 3, 5, -4, -28, 22, -43, 36, -13, -127, -43,
+ 2, -18, 126, 78, -127, -48, 68, -74, -67, 33, 62, 83, 42, -32, -46, -70,
+ -26, 115, 21, -66, 72, 52, -27, 44, 50, 50, 61, 28, -12, 3, -59, 49,
+ 3, -19, 39, 94, 16, 31, 6, 29, 3, -100, -1, -4, -60, 19, 7, -29,
+ -28, -38, -3, -47, -20, -21, -1, 5, -55, -12, -55, -39, 26, 47, -22, -9,
+ -41, -21, -19, -37, 0, 45, -56, 24, 75, -50, -9, 31, 28, 26, 13, -3,
+ -15, -27, 1, 1, -31, -10, 38, -1, 7, 43, 19, 21, 41, 33, 9, -17,
+ -3, -42, -76, -30, -8, -9, -1, 21, 22, 38, 32, 22, 0, -18, -32, -58,
+ -12, 5, -48, -13, 64, 29, -2, 2, 19, 43, 25, -19, -39, -69, -92, -15,
+ 23, 30, 30, 51, 37, 35, 37, 30, -27, -63, 5, -30, -56, -16, 26, 52,
+ 20, 14, 59, 27, -9, 22, -4, -20, -37, -17, -34, -34, -1, 35, 26, 31,
+ 5, -16, 4, 33, 22, 8, 5, -28, -41, -20, -10, -6, -2, -16, 12, 31,
+ -23, 7, -2, -39, -28, -13, 8, 5, 16, -4, -6, -18, -24, -27, -50, -6,
+ 5, 12, 0, -2, -14, -23, 5, -28, -10, 2, 28, 15, 2, 22, 27, 41,
+ 31, 2, 12, 31, 5, 12, -6, 15, 40, 34, 18, 26, 26, 12, 34, 23,
+ 34, 30, 22, 10, -26, -22, 1, 0, -1, 12, -4, -21, -5, -5, -20, -31,
+ -25, -24, -42, -44, -41, -41, -37, -29, -28, -29, -40, -17, -21, -38, -42, -38,
+ -40, -36, -13, -14, -8, -15, -7, -6, 5, 12, -1, -17, -1, 9, 2, 16,
+ 30, 27, 37, 36, 38, 36, 36, 19, 45, 45, 33, 26, 33, 28, 36, 31,
+ 17, 12, 22, 11, 11, 17, 5, -13, 6, 10, 2, -6, 2, 9, 15, -6,
+ -8, -23, -44, -3, -11, -35, -25, -35, -23, -21, 0, -11, -21, -17, 11, -6,
+ -11, -17, -33, -16, -16, -4, -7, -7, -9, -4, 1, 1, -3, 6, 7, 4,
+ -17, -11, -6, -4, 1, 3, 6, 4, 5, -4, 17, 7, 3, 9, -20, 0,
+ -7, -3, -5, 4, 9, 16, 2, 3, 8, 15, 15, 1, -3, 8, -1, 5,
+ 14, 7, 4, 8, -8, 2, -3, 5, 11, 5, 3, -4, 10, 17, 13, -11,
+ -5, 1, -3, 0, -6, -12, 2, -3, 13, -5, -25, -15, -7, 4, 1, -8,
+ -4, -12, -16, 3, 9, -6, 3, -21, -4, 4, -14, 1, -1, -2, 3, -8,
+ -5, 0, 7, -2, -3, -1, 3, -9, 5, -4, -17, -1, 9, 3, 7, 1,
+ -4, -3, 5, 2, -7, -9, 12, -6, -14, -16, 2, -1, 16, 2, 2, 7,
+ -6, -26, 3, -2, -4, -2, 10, 3, -7, 3, 8, 9, 5, 4, 1, -5,
+ -5, 11, 8, 7, 11, 12, -1, -5, -16, 13, 7, 2, 11, 4, -4, 9,
+ -8, -8, 14, 11, -8, 0, -1, -5, -2, -1, -10, -5, -9, -9, -16, -12,
+ -8, -16, 5, -10, -4, -11, -3, 1, 0, -3, -5, -13, -9, -2, -8, 5,
+ -9, -7, -2, 2, -11, -7, 13, 8, -3, 2, 7, -2, -1, 5, 0, 11,
+ 6, 13, 15, 1, -4, 9, 5, 3, 8, -3, -4, 16, 4, 11, 9, 0,
+ 8, 1, -6, -5, -18, 3, 7, -18, -4, 0, -3, -3, -6, -4, -5, -5,
+ -10, -2, -9, -5, -2, -4, -11, -2, 1, -5, -2, 11, -6, -9, 1, 4,
+ -6, -1, -5, 1, 2, 9, 5, 0, 4, 4, -2, 7, 0, -10, 5, 2,
+ -3, 0, -6, 7, -4, -3, 6, -1, -6, -1, -1, 2, -2, -6, -3, 0,
+ 8, -6, 4, -1, -5, -3, 3, 1, -5, -6, -2, -3, 5, 6, 0, 7,
+ -3, 3, -1, 0, -2, 9, 1, 1, -3, 4, 5, -5, 2, -2, 2, -11,
+ -2, -4, 11, 4, 5, 0, -5, -12, -6, -5, -5, 3, -2, -2, 2, 2,
+ 1, 0, -1, -8, -5, -5, -3, 2, -1, 3, -1, 3, 0, -1, 0, -1,
+ 1, 1, -4, -4, 2, -2, 1, -6, 1, 2, 4, 2, 2, -5, -1, 6,
+ -3, -1, -4, 11, 3, -9, -2, -6, -3, 2, 4, 2, 1, 2, 4, 3,
+ -6, -4, -3, -2, 0, 2, -2, 5, 2, -1, 3, -9, -3, -3, -4, -4,
+ -1, 0, -2, 7, 3, 1, 1, -2, -4, -2, -3, -2, -4, 2, 4, -1,
+ 2, 3, 0, 3, -1, 0, -2, -2, -3, 1, -1, -4, 5, -1, 5, 0,
+ -3, -2, -1, -4, 3, -1, -3, -2, -2, -1, 0, 0, 1, -1, 0, -2,
+ -2, 0, -3, -1, 0, 0, 1, 1, -2, -1, 1, -3, 1, 2, 0, -1,
+ 0, -1, 1, 5, -2, 1, -3, -3, -1, -3, 0, 1, 3, 2, -1, -1,
+ -2, -2, -1, 1, 0, -1, -2, -2, -2, -3, -3, -3, -2, -2, -2, -2,
+ -2, -2, -2, -1, 0, 1, 1, -2, -2, 0, 0, 2, -3, -16, -22, -20,
+ -28, -35, -31, -17, 19, 33, 36, 33, 34, 40, 36, 25, 18, 20, 18, 14,
+ 17, 12, 14, 10, -24, -36, -27, -38, -55, -69, -66, -47, -33, -13, 3, 5,
+ 10, 22, 25, 15, 28, 43, 41, 51, 56, 58, 58, 31, -18, -52, -64, -71,
+ -92, -105, -98, -77, -50, -17, 23, 59, 85, 99, 94, 76, 55, 14, -9, -5,
+ -7, -18, -17, -35, -53, -53, -33, -23, -33, -36, -15, 17, 32, 24, 12, 19,
+ 37, 54, 49, 38, 21, -14, -44, -30, -22, -15, 5, 8, -1, -26, -42, -46,
+ -49, -51, -37, -17, 1, -4, -19, -4, 45, 84, 91, 79, 57, 3, -30, -29,
+ -35, -25, -8, -6, -26, -61, -75, -73, -77, -72, -54, -19, 9, 6, -10, 3,
+ 47, 85, 92, 103, 92, 45, 21, 6, 4, 16, 27, 27, -1, -48, -69, -78,
+ -80, -84, -72, -33, -10, -24, -41, -20, 40, 82, 99, 123, 102, 69, 49, 30,
+ 27, 34, 42, 41, -2, -58, -96, -108, -103, -106, -83, -37, -10, -18, -38, -18,
+ 40, 65, 92, 110, 84, 44, 1, -26, -23, -7, 21, 32, 7, -39, -78, -84,
+ -79, -82, -61, -19, 5, -14, -52, -25, 25, 59, 102, 127, 116, 86, 40, 13,
+ 4, 9, 27, 29, 4, -47, -88, -94, -87, -83, -56, -18, 15, -13, -49, -30,
+ -2, 29, 69, 87, 80, 50, 9, -15, -27, -10, 18, 44, 36, -9, -45, -53,
+ -53, -46, -33, 6, 31, -8, -36, -28, -11, 21, 54, 76, 76, 44, 4, -33,
+ -53, -45, -18, 13, 10, -35, -62, -70, -61, -44, -19, 38, 63, 30, 9, 4,
+ 9, 35, 60, 81, 75, 51, 14, -25, -44, -37, -9, 29, 24, -11, -41, -59,
+ -51, -54, -33, 23, 35, 6, -13, -28, -18, 8, 43, 73, 76, 63, 33, -1,
+ -21, -22, 10, 43, 35, 5, -32, -47, -51, -68, -44, 6, 14, 0, -21, -34,
+ -25, 0, 37, 65, 73, 64, 35, 5, -22, -25, 11, 40, 39, 13, -20, -28,
+ -42, -64, -32, 6, 15, -1, -25, -39, -39, -16, 19, 44, 58, 53, 27, -2,
+ -39, -38, -2, 30, 40, 13, -16, -19, -45, -60, -29, 6, 17, 1, -21, -40,
+ -44, -24, 9, 38, 58, 51, 38, 8, -31, -29, 0, 34, 44, 9, -11, -23,
+ -58, -69, -42, -6, 9, 0, -16, -33, -36, -12, 19, 55, 72, 68, 58, 18,
+ -22, -25, -6, 29, 31, 2, -5, -23, -57, -69, -45, -8, 12, 10, 0, -22,
+ -24, -7, 20, 52, 61, 65, 59, 21, -15, -28, -11, 26, 20, 2, -2, -22,
+ -56, -71, -49, -14, 3, 8, -5, -26, -28, -19, 14, 42, 54, 71, 67, 38,
+ 8, -11, 16, 47, 37, 26, 18, -10, -51, -74, -59, -35, -19, -12, -24, -37,
+ -44, -34, 0, 24, 44, 67, 64, 43, 3, -18, 11, 35, 28, 22, 18, -4,
+ -47, -68, -55, -34, -11, -7, -15, -27, -43, -32, -1, 18, 42, 58, 60, 43,
+ -8, -29, -6, 11, 7, 4, 4, -17, -59, -75, -66, -41, -13, -3, 1, -11,
+ -29, -19, 1, 19, 42, 53, 64, 45, -8, -28, -9, 7, 4, 4, 9, -13,
+ -51, -71, -69, -43, -19, -7, 3, -11, -25, -17, -2, 23, 43, 60, 78, 55,
+ 1, -19, -5, 8, 3, 7, 13, -8, -41, -66, -67, -40, -19, 3, 16, 1,
+ -7, -5, 10, 34, 46, 67, 87, 62, 11, -13, -1, 8, 4, 15, 20, 1,
+ -33, -64, -65, -48, -30, -2, 6, -5, -14, -18, 1, 21, 32, 62, 86, 66,
+ 20, -3, 6, 7, 5, 16, 20, 7, -29, -62, -65, -59, -39, -13, -5, -8,
+ -22, -27, -6, 7, 17, 49, 74, 58, 14, -5, -2, -4, -3, 7, 14, 6,
+ -32, -59, -66, -63, -40, -16, -2, -2, -19, -20, -1, 6, 18, 49, 77, 62,
+ 21, 3, -1, -5, -2, 5, 18, 10, -26, -50, -65, -64, -43, -24, -5, -6,
+ -24, -23, -8, -2, 10, 45, 75, 60, 25, 6, -4, -4, -5, 3, 20, 8,
+ -20, -43, -60, -58, -45, -24, 1, -1, -15, -12, -1, 3, 16, 53, 83, 70,
+ 42, 19, 9, 7, 3, 16, 29, 17, -7, -35, -55, -56, -49, -24, 2, -1,
+ -11, -7, 3, 4, 16, 55, 83, 75, 50, 25, 15, 6, 0, 13, 21, 13,
+ -9, -40, -58, -66, -62, -35, -11, -11, -18, -13, -3, -7, 9, 49, 75, 74,
+ 51, 28, 19, 5, 1, 13, 20, 16, -3, -28, -48, -62, -61, -37, -16, -13,
+ -20, -15, -12, -19, -5, 21, 50, 61, 47, 28, 15, -1, -6, 0, 9, 14,
+ 1, -19, -37, -55, -56, -38, -16, -11, -13, -9, -9, -16, -8, 18, 48, 59,
+ 44, 28, 9, 15, -3, 2, -5, 3, 3, 4, 1, 7, -2, 7, -4, 2,
+ -124, -37, 33, -48, 7, -27, 8, -14, 77, 26, -9, 26, 7, 20, 10, 13,
+ 8, 9, 7, 4, 5, 2, 3, 2, 1, -1, 0, -3, -2, -5, 1, -10,
+ 11, 70, -6, 21, 5, 27, -2, 41, -15, -61, -66, -128, 0, -48, -21, -46,
+ -6, -55, 23, 53, -6, 11, 2, 14, 11, 10, 11, 8, 9, 9, 8, 5,
+ 8, 5, 6, 5, 6, 2, 7, -4, 6, 5, -23, 62, 29, 24, 8, 33,
+ 4, 32, 36, -30, -16, -124, -58, -39, -18, -51, -3, -43, -40, 53, 19, 12,
+ 4, 9, 12, 13, 10, 11, 9, 8, 11, 6, 5, 8, 6, 3, 9, 1,
+ 7, 2, -5, 22, -33, 20, 37, 35, 7, 29, 14, 8, 52, -5, 17, -64,
+ -84, -70, -15, -55, -23, -12, -72, 1, 28, 16, 8, 6, 7, 12, 10, 8,
+ 11, 6, 8, 10, 5, 4, 10, 1, 8, 4, 2, 10, -15, 26, -16, -9,
+ 14, 42, 17, 19, 29, -3, 42, 14, 28, -8, -45, -92, -37, -41, -54, 0,
+ -53, -48, 2, 18, 10, 8, 4, 8, 12, 8, 10, 10, 6, 9, 10, 2,
+ 10, 5, 3, 9, -2, 18, -16, 17, 3, -9, -12, 26, 28, 13, 35, 3,
+ 27, 19, 31, 17, 4, -60, -67, -33, -66, -22, -22, -58, -38, 2, 11, 9,
+ 7, 4, 9, 10, 8, 10, 9, 5, 12, 5, 5, 9, 2, 11, -5, 21,
+ -8, 4, 10, 5, -17, -1, 28, 11, 34, 13, 20, 17, 28, 24, 27, -6,
+ -61, -41, -57, -51, -17, -36, -56, -32, -1, 7, 8, 5, 6, 8, 10, 8,
+ 12, 6, 9, 9, 5, 9, 1, 15, -7, 15, 5, -2, 4, 14, -3, -18,
+ 15, 8, 28, 21, 20, 16, 23, 23, 29, 30, -20, -38, -45, -63, -38, -23,
+ -43, -53, -29, -5, 5, 5, 5, 5, 9, 7, 11, 8, 8, 10, 5, 12,
+ -2, 16, -1, 4, 11, 4, -3, 8, 15, -16, 0, 1, 16, 23, 23, 17,
+ 20, 21, 21, 39, 19, -14, -28, -52, -58, -33, -28, -47, -50, -30, -6, 2,
+ 5, 4, 6, 6, 9, 10, 7, 12, 3, 15, 0, 10, 8, 1, 6, 11,
+ 2, -4, 20, -1, -6, -5, 4, 15, 24, 20, 18, 23, 15, 30, 38, 13,
+ -6, -27, -56, -52, -30, -34, -48, -50, -28, -8, 2, 3, 5, 5, 6, 11,
+ 5, 13, 3, 12, 6, 5, 10, 5, 2, 7, 13, -8, 10, 11, 0, -6,
+ -4, 3, 17, 23, 16, 24, 18, 17, 36, 32, 13, -1, -30, -57, -45, -31,
+ -36, -51, -49, -28, -7, -1, 3, 6, 2, 11, 5, 12, 6, 9, 10, 5,
+ 8, 8, 5, -1, 16, 1, -1, 11, 9, -1, -5, -5, 4, 20, 17, 20,
+ 24, 14, 23, 37, 29, 16, 2, -33, -53, -42, -30, -39, -52, -49, -27, -9,
+ -3, 5, 0, 8, 5, 10, 8, 6, 10, 6, 7, 6, 11, -3, 8, 11,
+ 0, 2, 11, 8, -1, -5, -7, 9, 18, 16, 24, 20, 14, 27, 35, 27,
+ 21, 1, -33, -50, -38, -32, -42, -53, -48, -25, -14, -1, -2, 4, 3, 6,
+ 9, 5, 9, 7, 7, 4, 12, 4, 1, 10, 6, 2, 6, 10, 4, 0,
+ -6, -2, 11, 14, 18, 22, 17, 20, 32, 34, 28, 20, 0, -26, -36, -34,
+ -37, -45, -54, -44, -30, -13, -8, -3, 1, 2, 6, 4, 7, 8, 8, 2,
+ 8, 10, 1, 4, 6, 5, 5, 9, 6, 1, -3, -5, 3, 10, 14, 18,
+ 18, 17, 26, 35, 35, 29, 17, -1, -17, -24, -32, -41, -50, -51, -44, -28,
+ -18, -12, -5, -2, 2, 3, 3, 6, 9, 4, 3, 9, 6, 2, 2, 4,
+ 5, 9, 10, 4, -2, -5, -1, 5, 10, 14, 16, 15, 19, 30, 38, 37,
+ 29, 15, 1, -5, -14, -31, -43, -50, -52, -42, -29, -22, -16, -9, -3, 0,
+ 0, 2, 6, 6, 2, 4, 7, 6, 2, 1, 2, 6, 11, 10, 2, -5,
+ -4, 0, 5, 10, 14, 15, 14, 21, 32, 39, 38, 29, 14, 4, 0, -3,
+ -19, -32, -40, -43, -41, -36, -31, -25, -19, -12, -9, -8, -6, -1, 2, 2,
+ 0, -3, -4, -1, 3, 6, 6, 2, -3, -6, -2, 2, 2, 1, 2, 7,
+ 16, 25, 32, 35, 35, 36, 36, 33, 24, 11, -3, -18, -32, -40, -42, -40,
+ -36, -30, -25, -18, -12, -9, -8, -5, -1, 2, 2, 0, -3, -4, -1, 3,
+ 7, 6, 2, -4, -5, -2, 2, 2, 1, 2, 8, 17, 25, 32, 35, 36,
+ 36, 36, 32, 23, 10, -4, -20, -33, -41, -42, -40, -35, -30, -24, -18, -12,
+ -9, -8, -5, -1, 3, 2, -1, -4, -4, -1, 4, 7, 6, 1, -4, -5,
+ -2, -1, 3, 1, 3, 5, 3, -3, -1, -1, 1, -15, 1, 1, -5, -7,
+ 7, -2, -4, 3, -2, -5, -1, -3, -3, -1, 6, 3, 2, 3, -26, -117,
+ 35, -8, -19, 24, 58, -7, -6, 25, -9, 7, 4, 10, 2, 7, 6, 6,
+ 0, 6, -2, -1, -3, -3, 8, 71, 0, 17, 27, 20, -102, -115, 39, -32,
+ -18, -5, 58, -15, -12, 13, -10, -4, 1, 2, 1, 0, 6, 2, 1, 2,
+ 0, -4, 0, -5, 2, 67, 9, 14, 28, 29, -72, -126, 27, -25, -19, -14,
+ 58, -6, -11, 13, -5, -3, 3, 3, 4, 1, 8, 3, 3, 3, 3, -2,
+ 2, -3, -3, 62, 17, 14, 27, 35, -45, -128, 11, -19, -20, -22, 53, 1,
+ -12, 11, -3, -4, 2, 3, 4, 1, 7, 3, 3, 3, 3, -2, 2, -2,
+ -9, 57, 22, 14, 25, 37, -23, -125, -8, -15, -20, -30, 46, 9, -12, 10,
+ -2, -3, 0, 3, 3, 1, 6, 4, 2, 3, 2, -2, 1, 0, -16, 50,
+ 26, 13, 22, 37, -2, -117, -27, -13, -18, -36, 36, 16, -13, 9, -2, -2,
+ -2, 3, 2, 2, 4, 5, 1, 4, 2, -1, 0, 4, -20, 43, 29, 15,
+ 20, 36, 14, -102, -43, -15, -16, -40, 26, 22, -12, 8, -2, -2, -3, 3,
+ 1, 3, 2, 6, 1, 5, 1, 0, -1, 7, -23, 35, 31, 18, 18, 33,
+ 27, -83, -57, -20, -14, -42, 14, 26, -9, 7, -2, 0, -5, 3, 1, 4,
+ 1, 7, 0, 5, 1, 1, -2, 10, -24, 26, 31, 20, 17, 30, 36, -62,
+ -65, -27, -12, -43, 2, 28, -7, 6, -2, 0, -5, 3, 0, 4, 0, 7,
+ 0, 5, 1, 2, -4, 11, -23, 17, 32, 22, 16, 27, 42, -44, -67, -36,
+ -9, -42, -8, 28, -3, 5, -1, 1, -5, 2, 0, 4, 1, 7, 1, 5,
+ 1, 3, -5, 13, -22, 10, 31, 23, 17, 22, 45, -25, -66, -45, -8, -40,
+ -18, 27, 0, 5, -1, 1, -5, 1, 0, 4, 0, 6, 2, 4, 2, 3,
+ -6, 14, -19, 2, 29, 25, 19, 19, 47, -10, -60, -54, -10, -37, -27, 24,
+ 4, 4, 0, 1, -5, 0, 0, 3, 1, 5, 2, 4, 2, 4, -7, 15,
+ -16, -4, 27, 25, 21, 15, 48, 4, -51, -61, -12, -33, -34, 19, 7, 4,
+ 1, 0, -4, -1, 0, 3, 2, 5, 3, 3, 3, 5, -8, 15, -11, -10,
+ 24, 25, 23, 12, 45, 15, -39, -66, -18, -28, -40, 12, 10, 4, 2, 1,
+ -3, -2, 0, 2, 2, 4, 3, 3, 3, 5, -8, 13, -6, -14, 19, 25,
+ 25, 10, 43, 24, -25, -67, -25, -24, -45, 4, 11, 5, 3, 0, -2, -3,
+ -1, 1, 2, 3, 3, 3, 2, 6, -9, 11, -2, -17, 15, 24, 27, 9,
+ 39, 31, -13, -66, -33, -19, -48, -3, 11, 5, 3, 1, -2, -3, -1, 1,
+ 2, 4, 3, 3, 2, 8, -9, 9, 3, -18, 10, 22, 29, 9, 35, 35,
+ 0, -61, -41, -17, -49, -11, 10, 6, 3, 2, -2, -3, -2, 1, 1, 4,
+ 3, 5, 1, 9, -9, 7, 6, -18, 5, 20, 29, 10, 32, 38, 11, -47,
+ -45, -18, -47, -20, 5, 6, 4, 2, -1, -3, -2, 0, 1, 5, 1, 6,
+ 1, 7, -7, 6, 6, -16, 1, 16, 27, 11, 29, 40, 20, -30, -43, -23,
+ -46, -28, -2, 4, 4, 2, -1, -3, -2, -1, 0, 6, -1, 7, 2, 5,
+ -6, 5, 6, -15, -3, 13, 25, 12, 26, 41, 26, -14, -36, -26, -44, -35,
+ -11, 1, 4, 2, 0, -4, -3, -3, -1, 7, -2, 7, 4, 4, -6, 4,
+ 7, -13, -6, 10, 23, 12, 24, 42, 31, 0, -24, -28, -42, -40, -19, -4,
+ 4, 2, 1, -4, -3, -4, -3, 8, -3, 6, 6, 3, -6, 4, 7, -11,
+ -8, 7, 20, 12, 21, 41, 34, -2, -31, -34, -29, -21, -12, -3, -4, -10,
+ -7, -5, -6, -4, 5, 8, -3, -1, 7, -1, -11, -7, 0, 1, 6, 16,
+ 28, 33, 33, 30, 13, -1, -26, -35, -30, -24, -14, -5, -4, -11, -7, -5,
+ -6, -6, 3, 8, -2, -2, 7, 1, -11, -9, -1, 0, 4, 14, 26, 32,
+ 33, 32, 17, 3, -22, -34, -31, -25, -16, -6, -3, -10, -8, -5, -6, -7,
+ 2, 9, 0, -3, 6, 3, -9, -10, -2, 0, 3, 12, 24, 32, -1, 0,
+ -3, -1, -8, -5, -16, -5, -14, -4, -13, -5, -1, -7, 16, -17, 28, -16,
+ 47, 1, 70, 35, 97, 71, 98, 66, 32, -5, -71, -69, -122, -69, -105, -33,
+ -67, -6, -35, 2, -12, -2, 4, -12, 16, -19, 29, -16, 44, 2, 66, 37,
+ 92, 76, 95, 74, 33, 5, -69, -63, -122, -69, -106, -36, -66, -11, -33, -3,
+ -9, -7, 7, -16, 18, -22, 29, -17, 42, 3, 61, 40, 86, 81, 91, 82,
+ 34, 15, -67, -57, -122, -69, -105, -40, -64, -17, -29, -9, -6, -12, 10, -20,
+ 20, -23, 28, -17, 39, 4, 56, 42, 80, 85, 88, 89, 35, 24, -63, -53,
+ -119, -70, -104, -45, -62, -22, -26, -14, -2, -16, 12, -23, 20, -25, 27, -16,
+ 35, 7, 51, 45, 74, 89, 85, 96, 38, 32, -58, -49, -116, -72, -102, -50,
+ -60, -27, -24, -19, 0, -20, 14, -24, 20, -24, 24, -14, 31, 10, 45, 48,
+ 69, 92, 82, 102, 40, 39, -53, -45, -112, -74, -100, -55, -57, -33, -21, -24,
+ 3, -24, 15, -26, 19, -24, 22, -12, 27, 12, 40, 50, 63, 95, 80, 106,
+ 43, 45, -47, -42, -107, -76, -97, -60, -55, -38, -18, -28, 4, -26, 15, -27,
+ 18, -23, 19, -10, 23, 15, 35, 53, 59, 97, 78, 110, 47, 50, -39, -39,
+ -102, -79, -94, -65, -52, -43, -16, -32, 5, -28, 14, -27, 16, -21, 15, -7,
+ 18, 18, 30, 55, 54, 98, 76, 113, 51, 55, -32, -37, -96, -81, -91, -70,
+ -50, -48, -15, -35, 6, -30, 13, -26, 13, -19, 11, -5, 13, 20, 25, 56,
+ 50, 99, 75, 115, 56, 59, -24, -35, -90, -83, -88, -75, -48, -52, -14, -38,
+ 5, -30, 11, -25, 10, -17, 7, -2, 9, 22, 21, 57, 47, 99, 75, 116,
+ 61, 62, -15, -33, -82, -86, -84, -80, -47, -56, -14, -39, 4, -30, 9, -24,
+ 6, -15, 3, 1, 5, 24, 17, 57, 44, 98, 75, 116, 66, 65, -6, -31,
+ -75, -88, -81, -83, -46, -59, -14, -41, 3, -30, 6, -22, 3, -12, -1, 3,
+ 1, 26, 13, 57, 41, 96, 75, 115, 72, 68, 2, -29, -69, -89, -78, -87,
+ -45, -62, -15, -42, 0, -29, 3, -20, -1, -10, -5, 5, -2, 26, 11, 56,
+ 40, 94, 76, 114, 77, 69, 12, -28, -61, -91, -75, -89, -45, -64, -16, -42,
+ -2, -28, 0, -18, -5, -8, -9, 7, -6, 27, 8, 55, 38, 91, 77, 112,
+ 82, 71, 20, -25, -55, -91, -73, -91, -46, -65, -18, -42, -5, -26, -4, -15,
+ -10, -5, -13, 9, -9, 27, 7, 53, 37, 88, 78, 110, 87, 72, 29, -23,
+ -48, -90, -71, -93, -47, -66, -21, -41, -9, -24, -8, -13, -13, -3, -16, 9,
+ -11, 27, 5, 51, 37, 84, 79, 108, 93, 74, 37, -20, -42, -90, -70, -94,
+ -49, -66, -24, -40, -12, -23, -12, -12, -16, -2, -18, 10, -12, 25, 5, 48,
+ 37, 80, 81, 105, 98, 75, 45, -16, -36, -88, -68, -94, -51, -66, -28, -39,
+ -16, -21, -15, -10, -19, -1, -21, 10, -13, 24, 4, 45, 37, 76, 82, 102,
+ 102, 76, 52, -13, -30, -85, -67, -94, -54, -66, -31, -38, -20, -19, -19, -9,
+ -22, 0, -22, 9, -14, 22, 4, 41, 37, 71, 83, 99, 105, 77, 59, -8,
+ -25, -82, -67, -93, -56, -65, -35, -37, -23, -18, -22, -7, -25, 0, -24, 8,
+ -14, 20, 5, 37, 38, 67, 84, 96, 108, 79, 65, -3, -20, -79, -66, -92,
+ -59, -65, -39, -36, -27, -17, -25, -7, -27, -1, -24, 6, -14, 17, 6, 34,
+ 39, 63, 84, 93, 111, 80, 71, 1, -15, -75, -66, -90, -62, -64, -43, -35,
+ -31, -16, -28, -6, -28, -1, -25, 5, -14, 14, 6, 30, 39, 58, 85, 90,
+ 113, 82, 76, 7, -11, -70, -66, -88, -66, -62, -46, -34, -34, -15, -30, -7,
+ -30, -2, -25, 2, -13, 11, 7, 26, 40, 53, 84, 87, 115, 84, 81, 13,
+ -7, -65, -66, -85, -68, -61, -50, -33, -37, -15, -32, -7, -30, -4, -25, 0,
+ -12, 7, 9, 19, 37, 52, 80, 97, 118, 113, 98, 54, 7, -41, -72, -87,
+ -87, -75, -65, -47, -42, -29, -30, -22, -24, -19, -19, -14, -9, -2, 8, 17,
+ 36, 50, 77, 95, 117, 115, 101, 60, 13, -35, -69, -85, -88, -75, -66, -49,
+ -44, -31, -31, -23, -25, -20, -20, -15, -9, -2, -1, 0, 0, 0, 0, -1,
+ -1, -1, 3, 9, 14, 14, 10, -3, -17, -13, 1, 1, 23, 33, -14, -55,
+ -59, -80, -75, -35, -7, 51, 40, -29, -35, -53, -128, -31, 111, 72, 46, 55,
+ -19, -73, -23, 14, 64, 104, 87, 105, 68, -54, -76, -1, -18, 12, 92, 23,
+ -79, -93, -105, -119, -64, -20, 39, 70, 2, -45, -52, -107, -82, 73, 106, 56,
+ 53, 12, -57, -37, 14, 52, 105, 101, 94, 85, -5, -75, -25, -1, -8, 59,
+ 52, -45, -89, -94, -117, -90, -42, 1, 53, 29, -29, -45, -79, -104, 3, 99,
+ 78, 63, 42, -25, -49, -7, 30, 83, 112, 103, 99, 40, -54, -58, -11, -7,
+ 36, 68, -4, -80, -98, -114, -106, -57, -15, 33, 42, -10, -46, -66, -97, -45,
+ 68, 90, 67, 53, 4, -40, -20, 18, 60, 103, 107, 100, 69, -15, -62, -31,
+ -9, 15, 60, 31, -50, -90, -108, -115, -79, -33, 11, 42, 15, -33, -58, -87,
+ -75, 21, 87, 79, 63, 27, -26, -33, 1, 40, 88, 111, 105, 85, 20, -50,
+ -49, -17, 5, 46, 49, -17, -77, -102, -115, -95, -49, -7, 31, 28, -15, -50,
+ -76, -84, -21, 64, 84, 71, 45, -4, -32, -13, 22, 66, 103, 108, 95, 50,
+ -23, -56, -32, -5, 30, 55, 14, -53, -92, -111, -107, -68, -24, 16, 34, 4,
+ -37, -66, -85, -53, 32, 81, 77, 58, 17, -25, -24, 6, 46, 89, 108, 101,
+ 71, 6, -49, -45, -16, 15, 49, 36, -26, -77, -103, -110, -85, -41, 0, 30,
+ 20, -21, -55, -79, -72, -5, 65, 81, 67, 36, -10, -28, -8, 27, 71, 102,
+ 104, 85, 34, -31, -51, -29, 1, 37, 48, 2, -57, -93, -109, -97, -58, -16,
+ 20, 28, -4, -42, -70, -79, -36, 39, 78, 74, 51, 9, -24, -18, 11, 51,
+ 91, 105, 94, 57, -6, -48, -41, -12, 22, 48, 26, -33, -79, -103, -104, -74,
+ -32, 6, 28, 12, -27, -60, -78, -59, 8, 66, 78, 62, 27, -13, -24, -3,
+ 33, 74, 100, 99, 74, 20, -35, -48, -25, 8, 40, 40, -7, -61, -94, -106,
+ -88, -49, -9, 21, 21, -11, -47, -72, -71, -22, 45, 76, 71, 43, 2, -22,
+ -13, 16, 56, 91, 101, 85, 43, -15, -47, -36, -6, 28, 45, 16, -38, -80,
+ -102, -97, -65, -24, 11, 25, 4, -33, -63, -75, -46, 18, 66, 75, 56, 19,
+ -15, -20, 2, 38, 77, 98, 93, 62, 8, -38, -44, -20, 14, 41, 32, -15,
+ -64, -94, -101, -79, -40, -2, 22, 15, -17, -52, -72, -61, -9, 49, 74, 66,
+ 36, -2, -21, -9, 22, 61, 91, 96, 76, 31, -22, -45, -32, 0, 32, 40,
+ 7, -43, -82, -99, -89, -56, -17, 14, 21, -2, -38, -65, -69, -33, 26, 66,
+ 71, 50, 13, -16, -16, 7, 43, 79, 95, 85, 50, -2, -40, -40, -14, 20,
+ 40, 24, -22, -66, -93, -95, -70, -32, 3, 21, 9, -23, -55, -70, -51, 1,
+ 52, 71, 60, 28, -6, -19, -4, 27, 64, 90, 91, 66, 19, -27, -43, -26,
+ 6, 34, 35, -1, -48, -83, -96, -81, -47, -10, 16, 17, -9, -43, -66, -62,
+ -22, 33, 66, 67, 43, 7, -16, -13, 12, 48, 80, 91, 77, 39, -10, -40,
+ -36, -8, 24, 38, 17, -28, -69, -92, -89, -62, -25, 7, 19, 4, -29, -58,
+ -67, -42, 10, 55, 70, 55, 22, -9, -17, 0, 33, 68, 90, 86, 57, 10,
+ -31, -41, -21, 12, 36, 30, -8, -53, -85, -94, -75, -41, -5, 17, 13, -15,
+ -48, -67, -57, -13, 39, 68, 64, 37, 3, -16, -9, 18, 54, 84, 91, 72,
+ 30, -17, -41, -33, -2, 28, 37, 10, -35, -74, -94, -86, -56, -19, 10, 17,
+ -2, -36, -63, -66, -34, 19, 60, 70, 51, 17, -11, -15, 5, 39, 74, 92,
+ 83, 49, 1, -36, -40, -16, 18, 37, 24, -17, -61, -90, -93, -70, -34, 1,
+ 18, 8, -22, -55, -69, -50, -2, 47, 70, 61, 31, -3, -17, -5, 26, 62,
+ 88, 90, 65, 19, -25, -42, -27, 5, 33, 33, 1, -45, -81, -95, -81, -48,
+ -11, 14, 15, -10, -43, -66, -61, -22, 31, 65, 68, 43, 9, -14, -11, 12,
+ 49, 80, 92, 76, 38, -10, -39, -36, -8, 24, 38, 16, -27, -70, -92, -89,
+ -61, -25, 7, 17, 3, -31, -59, -68, -39, 8, 55, 55, 19, 0, -9, -10,
+ -14, -13, -21, -30, -32, -44, -49, -57, -65, -72, -83, -98, -104, -117, -123, -128,
+ -127, -128, -128, -128, -128, -127, -128, -120, -117, -109, -100, -90, -83, -72, -66, -55,
+ -50, -33, -42, -18, -29, -18, 15, -6, 11, 7, 19, 3, 38, 5, 48, 44,
+ 64, 57, 97, 82, 111, 104, 110, 107, 120, 116, 125, 126, 126, 126, 126, 127,
+ 117, 125, 123, 100, 127, 101, 124, 102, 121, 109, 126, 96, 125, 116, 127, 90,
+ 119, 87, 127, 90, 118, 95, 123, 93, 106, 90, 100, 104, 74, 84, 73, 97,
+ 72, 71, 57, 66, 80, 36, 59, 38, 55, 35, 57, -6, 64, 10, 25, 19,
+ 19, -22, 65, -26, 14, 2, -17, -12, 22, -40, -3, -31, -24, -38, -1, -56,
+ -6, -48, -36, -54, -19, -56, -33, -49, -69, -49, -52, -53, -60, -61, -84, -76,
+ -85, -96, -95, -95, -114, -93, -117, -104, -93, -101, -98, -100, -101, -96, -78, -95,
+ -71, -70, -72, -52, -63, -70, -43, -77, -41, -48, -65, -53, -53, -59, -42, -56,
+ -37, -64, -54, -52, -50, -54, -56, -54, -55, -62, -51, -47, -44, -67, -60, -63,
+ -56, -64, -53, -48, -61, -53, -58, -38, -48, -32, -38, -34, -28, -26, -23, -25,
+ -22, -6, -7, -12, -1, 5, 6, 6, -7, 22, -4, 27, 15, 18, 24, 37,
+ 30, 47, 24, 53, 29, 63, 29, 46, 46, 51, 52, 53, 36, 54, 65, 55,
+ 33, 64, 36, 69, 54, 26, 62, 66, 36, 68, 30, 47, 54, 58, 20, 55,
+ 31, 40, 50, 35, 19, 56, 33, 25, 46, 18, 22, 42, 21, 25, 32, 19,
+ 19, 26, 18, 23, 29, 24, 7, 27, 6, 33, 8, 17, -2, 14, 3, 23,
+ 14, 7, 5, -9, -13, -10, -23, -12, -16, -27, -8, -18, -15, -3, -18, -24,
+ -5, -23, -9, 0, -11, 4, -1, 4, 2, 5, -2, 3, -1, -7, 4, -11,
+ 1, -12, -4, -7, -10, -11, -11, -16, -23, -15, -20, -22, -23, -20, -30, -23,
+ -31, -25, -32, -35, -41, -34, -44, -39, -34, -49, -33, -30, -36, -29, -33, -14,
+ -24, -32, -18, -15, -7, -9, -11, 5, -14, 27, -11, 16, -10, 13, -9, 23,
+ -10, 19, 10, 18, 11, 29, 1, 47, 27, -4, 45, 3, 43, 40, 14, 13,
+ 57, 16, 34, 27, 22, 30, 32, 14, 24, 27, 20, 20, 17, 4, 20, 20,
+ 8, 8, 0, 10, -3, 17, -8, -1, -4, 1, 0, 6, -7, -3, -3, -13,
+ -5, -6, -18, -5, -28, -12, -13, -5, -11, -5, -28, -7, -15, -10, -6, -28,
+ -16, -12, -17, -8, -10, -19, -10, -24, -30, -32, -26, -31, -36, -32, -33, -27,
+ -25, -26, -26, -25, -25, -23, -16, -22, -10, -11, -7, -7, 4, -10, 10, -9,
+ 11, -8, 4, -6, 4, -8, 3, -4, 2, -3, -5, -3, -11, -8, -6, -12,
+ -11, -7, -24, -4, -17, -9, -18, -28, -16, -29, -23, -38, -24, -34, -22, -38,
+ -18, -27, -10, -22, -19, -21, -2, -23, 10, -19, 0, 4, 16, 7, 0, 3,
+ 17, 14, 26, 8, 25, 27, 30, 25, 38, 31, 49, 37, 42, 45, 48, 55,
+ 63, 46, 54, 54, 56, 59, 56, 47, 50, 53, 47, 50, 44, 42, 35, 40,
+ 31, 37, 35, 27, 20, 23, 19, 26, 24, 18, 11, 14, 18, 24, 18, 12,
+ 10, 3, 12, 2, 9, 4, 0, 0, 3, -4, 11, 1, 1, -1, -5, -7,
+ 1, -6, -1, 2, -4, 1, -1, -7, -9, -11, -21, -19, -20, -28, -27, -22,
+ -29, -24, -26, -32, -22, -25, -31, -24, -19, -22, -11, -19, -15, -4, -5, -4,
+ 0, -6, -6, 2, -9, -5, -5, -9, -10, -7, -18, -8, -14, -14, -19, -29,
+ -25, -16, -25, -30, -30, -30, -21, -29, -38, -37, -36, -41, -44, -53, -48, -43,
+ -44, -55, -46, -40, -33, -36, -40, -40, -28, -25, -24, -23, -17, -15, 1, -3,
+ -1, 5, 2, 9, 1, 4, 12, 13, 14, 15, 9, 21, 26, 32, 31, 28,
+ 28, 41, 38, 49, 45, 46, 53, 56, 57, 57, 57, 58, 55, 48, 56, 56,
+ 56, 45, 39, 41, 41, 44, 42, 25, 28, 27, 24, 28, 21, 14, 17, 8,
+ 15, 22, 13, 15, 16, 3, 11, 10, 4, 6, 4, -8, 0, -2, -2, -3,
+ -2, 1, 3, -3, -3, -6, -8, -5, 4, 3, 2, -4, -2, -1, 5, 3,
+ -2, -2, -2, 3, 7, -2, -26, -37, -34, -30, -13, -14, -21, -24, -27, -24,
+ -13, -7, -15, 6, 3, -30, -50, -48, -47, -41, -26, -8, 28, 43, 38, 57,
+ 63, 56, 75, 118, 127, 117, 99, 86, 85, 66, 46, 59, 80, 69, 43, 27,
+ -6, -47, -74, -80, -71, -57, -40, -44, -56, -78, -88, -78, -59, -52, -51, -56,
+ -57, -47, -36, -36, -39, -39, -32, -17, 6, 24, 33, 10, -14, -14, -2, -11,
+ -20, -15, -24, -28, -28, -25, -28, -54, -73, -65, -43, -18, 6, 27, 21, 23,
+ 17, 22, 18, 16, 31, 50, 45, 25, 22, 8, -20, -17, 8, 29, 10, -22,
+ -41, -45, -51, -53, -31, -18, -23, -7, 37, 54, 38, 36, 60, 100, 119, 120,
+ 122, 125, 110, 88, 94, 99, 90, 85, 82, 54, 26, -5, -49, -83, -85, -67,
+ -36, -14, -30, -55, -76, -86, -65, -41, -45, -60, -53, -43, -35, -34, -41, -43,
+ -45, -35, 10, 40, 32, 3, -3, -14, -30, -38, -33, -23, -29, -26, -18, -10,
+ -17, -37, -46, -58, -61, -45, -17, -4, -2, 19, 31, 27, 13, 22, 38, 49,
+ 59, 69, 60, 23, -13, -11, 13, 24, 19, 24, 8, -30, -58, -58, -66, -85,
+ -90, -61, -19, -1, -11, -5, 25, 42, 61, 92, 109, 106, 110, 104, 93, 93,
+ 89, 82, 86, 81, 71, 51, 13, -40, -74, -87, -73, -35, -24, -50, -71, -73,
+ -53, -50, -58, -68, -60, -61, -54, -30, -25, -40, -52, -25, 13, 32, 45, 49,
+ 44, 28, 22, 29, 32, 20, 3, 7, 6, 0, -1, -4, -30, -63, -69, -62,
+ -57, -49, -25, 2, 17, 24, 27, 30, 10, 4, 38, 77, 66, 32, 13, 7,
+ 0, 9, 31, 43, 23, -11, -25, -23, -46, -83, -87, -63, -42, -19, -6, -3,
+ 6, 27, 49, 81, 108, 121, 123, 124, 115, 110, 98, 80, 78, 77, 77, 69,
+ 54, 8, -56, -99, -92, -53, -46, -64, -75, -73, -70, -75, -62, -67, -86, -88,
+ -54, -28, -33, -46, -50, -40, -24, -3, 29, 51, 48, 34, 44, 44, 30, 18,
+ 13, -3, -15, -7, -1, -10, -36, -56, -65, -79, -100, -91, -64, -52, -40, -5,
+ 20, 9, -14, -9, 21, 49, 59, 58, 49, 25, -1, 11, 39, 39, 22, 19,
+ 20, 8, -19, -49, -72, -69, -58, -43, -27, -24, -13, -5, 12, 38, 74, 97,
+ 110, 124, 126, 126, 114, 105, 100, 87, 91, 108, 115, 73, 5, -41, -49, -49,
+ -53, -45, -49, -69, -77, -60, -51, -71, -94, -96, -68, -49, -46, -44, -45, -60,
+ -60, -27, 0, 11, 26, 37, 37, 37, 40, 42, 34, 8, -1, 14, 15, -5,
+ -12, -18, -44, -75, -85, -88, -98, -99, -76, -36, -12, -19, -24, -11, -9, 1,
+ 36, 71, 58, 29, 13, 17, 33, 33, 30, 35, 44, 44, 27, -3, -39, -51,
+ -61, -55, -41, -31, -25, -29, -21, -1, 23, 46, 76, 102, 109, 110, 116, 118,
+ 92, 61, 76, 112, 120, 93, 57, 14, -28, -54, -50, -46, -60, -83, -82, -64,
+ -62, -82, -89, -93, -101, -88, -59, -52, -64, -75, -76, -63, -50, -30, -1, 9,
+ 8, 11, 32, 44, 36, 29, 32, 27, 20, 22, 28, 24, 0, -21, -30, -45,
+ -78, -97, -83, -66, -50, -32, -17, -16, -23, -20, 4, 38, 51, 47, 37, 28,
+ 29, 27, 27, 31, 42, 54, 55, 43, 20, -5, -29, -40, -37, -30, -27, -23,
+ -15, -12, -11, 8, 43, 67, 78, 100, 122, 126, 107, 84, 81, 92, 106, 115,
+ 110, 79, 31, -3, -13, -26, -47, -56, -56, -58, -58, -56, -59, -72, -86, -84,
+ -66, -57, -56, -56, -60, -74, -74, -51, -32, -24, -14, 3, 14, 15, 19, 28,
+ 33, 19, 11, 22, 29, 18, 8, 9, 0, 0, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -1,
+ -1, -1, -1, -1, -1, -1, -1, 0, -1, -3, -2, -1, 0, 2, -4, -13,
+ -21, -23, -19, -8, 7, 17, 23, 26, 33, 38, 32, 17, -5, -17, -24, -20,
+ -6, -3, -16, -29, -26, -17, -5, -1, 2, 7, 11, 17, 15, 9, 9, 3,
+ 10, 15, 9, -14, -33, -27, -18, -6, -7, -10, -6, 0, 12, 15, 29, 38,
+ 36, 32, 11, 0, -30, -45, -50, -39, -23, -27, -24, -15, 6, 25, 37, 51,
+ 46, 40, 0, -19, -22, -34, -30, -40, -45, -51, -34, -1, 25, 48, 40, 43,
+ 51, 64, 58, 5, -22, -49, -63, -69, -68, -58, -54, -16, 13, 44, 66, 61,
+ 68, 72, 86, 47, -17, -56, -82, -88, -93, -72, -58, -40, 4, 45, 94, 98,
+ 84, 65, 68, 71, 15, -46, -88, -90, -88, -85, -62, -56, -34, -4, 41, 80,
+ 82, 74, 54, 70, 66, 25, -29, -70, -74, -90, -87, -79, -73, -46, -10, 54,
+ 90, 103, 88, 76, 90, 69, 25, -38, -76, -96, -119, -111, -103, -81, -57, -12,
+ 50, 90, 113, 98, 100, 112, 103, 60, -11, -54, -95, -121, -124, -119, -95, -71,
+ -10, 53, 103, 116, 93, 91, 89, 80, 31, -28, -67, -108, -122, -128, -110, -87,
+ -53, 8, 60, 107, 107, 89, 83, 83, 76, 27, -14, -52, -84, -99, -103, -82,
+ -72, -40, 4, 53, 92, 92, 88, 85, 97, 87, 42, 3, -45, -74, -106, -111,
+ -105, -101, -70, -30, 27, 65, 77, 83, 87, 106, 90, 58, 16, -30, -67, -101,
+ -100, -101, -93, -68, -27, 29, 60, 77, 79, 93, 111, 96, 71, 24, -21, -73,
+ -109, -118, -127, -118, -98, -50, 6, 43, 65, 70, 99, 115, 108, 82, 40, -1,
+ -53, -80, -94, -105, -101, -82, -31, 18, 56, 66, 72, 95, 103, 97, 64, 29,
+ -15, -63, -85, -102, -105, -104, -81, -35, 13, 53, 58, 69, 86, 97, 94, 67,
+ 39, -12, -54, -80, -97, -102, -103, -77, -38, 9, 40, 45, 60, 77, 95, 88,
+ 70, 41, -8, -46, -74, -87, -99, -100, -78, -42, 10, 37, 50, 66, 89, 110,
+ 103, 91, 57, 9, -33, -68, -86, -105, -105, -89, -51, -2, 23, 40, 53, 80,
+ 99, 98, 89, 53, 8, -37, -68, -90, -107, -106, -94, -51, -5, 25, 43, 58,
+ 86, 95, 98, 86, 52, 9, -36, -64, -92, -105, -108, -95, -53, -11, 22, 37,
+ 57, 81, 90, 96, 82, 52, 6, -34, -64, -92, -104, -113, -97, -59, -18, 15,
+ 31, 58, 79, 92, 98, 87, 57, 9, -29, -63, -87, -100, -109, -91, -58, -13,
+ 16, 36, 62, 78, 93, 96, 88, 56, 12, -25, -62, -83, -101, -106, -89, -57,
+ -15, 6, 30, 52, 71, 87, 94, 89, 55, 18, -21, -55, -76, -96, -100, -88,
+ -53, -16, 6, 31, 53, 76, 93, 105, 98, 64, 26, -18, -52, -78, -99, -105,
+ -95, -59, -26, 0, 24, 45, 66, 81, 97, 88, 62, 28, -12, -40, -67, -84,
+ -95, -83, -50, -21, 4, 24, 47, 64, 81, 96, 85, 63, 26, -11, -41, -69,
+ -88, -102, -91, -64, -36, -12, 10, 34, 51, 74, 87, 81, 62, 26, -7, -40,
+ -63, -83, -95, -83, -58, -31, -10, 14, 34, 51, 75, 85, 82, 61, 30, -3,
+ -34, -57, -81, -92, -83, -60, -36, -15, 11, 27, 47, 69, 80, 79, 59, 30,
+ -5, -33, -57, -82, -93, -84, -61, -38, -15, 10, 25, 48, 68, 80, 77, 58,
+ 29, -4, -30, -56, -80, -89, -78, -54, -34, -8, 10, 0, 0, 1, 0, -2,
+ -2, -5, -8, -3, 3, -4, -10, 2, 8, 3, 4, 5, -3, -9, 10, 26,
+ 26, 12, -4, -40, -64, -50, 1, 55, 69, 28, -23, -65, -83, -52, 13, 67,
+ 67, 39, 16, -15, -48, -38, 10, 53, 44, 5, -5, -14, -43, -35, 16, 54,
+ 37, -1, -26, -53, -82, -37, 35, 67, 44, 2, -10, -20, -39, -19, 27, 55,
+ 42, 3, -26, -67, -107, -62, 43, 110, 102, 43, -18, -63, -91, -35, 73, 120,
+ 77, -6, -72, -113, -109, -36, 53, 78, 50, 0, -46, -72, -71, -20, 67, 112,
+ 100, 44, -24, -88, -123, -84, 5, 71, 97, 66, 7, -53, -100, -80, -1, 83,
+ 127, 108, 38, -57, -121, -119, -57, 24, 84, 97, 62, -4, -77, -97, -46, 32,
+ 101, 108, 56, -20, -103, -119, -69, 18, 105, 126, 90, 6, -92, -126, -90, -3,
+ 85, 108, 75, 0, -86, -117, -85, -6, 76, 115, 101, 30, -68, -118, -105, -33,
+ 57, 105, 102, 41, -46, -104, -112, -59, 25, 95, 121, 81, -5, -88, -126, -94,
+ -12, 63, 101, 76, 7, -67, -107, -73, 11, 94, 127, 102, 21, -74, -124, -95,
+ -21, 57, 101, 82, 21, -48, -89, -59, 6, 67, 95, 60, -11, -82, -115, -81,
+ -13, 52, 84, 52, -9, -68, -96, -56, 9, 66, 93, 63, 10, -52, -86, -54,
+ 1, 60, 96, 70, 19, -44, -80, -51, 0, 55, 94, 69, 20, -42, -88, -76,
+ -40, 24, 79, 72, 34, -28, -75, -63, -23, 35, 71, 48, 4, -57, -95, -67,
+ -10, 62, 103, 75, 18, -61, -110, -86, -22, 61, 110, 90, 37, -45, -100, -87,
+ -39, 34, 81, 70, 33, -39, -88, -76, -24, 54, 94, 76, 32, -46, -100, -92,
+ -42, 35, 73, 62, 26, -46, -97, -93, -44, 36, 81, 75, 35, -38, -87, -81,
+ -26, 58, 99, 85, 37, -44, -101, -103, -46, 47, 98, 97, 56, -27, -90, -99,
+ -49, 37, 88, 95, 62, -12, -74, -93, -51, 27, 69, 71, 35, -30, -78, -87,
+ -38, 41, 84, 90, 57, -11, -71, -96, -56, 21, 69, 86, 60, -4, -67, -97,
+ -61, 12, 65, 88, 65, 3, -61, -94, -60, 14, 71, 96, 68, 3, -66, -104,
+ -70, 3, 59, 84, 59, -1, -67, -107, -76, -3, 59, 89, 64, 3, -67, -111,
+ -82, -9, 57, 92, 76, 26, -43, -93, -71, -9, 50, 80, 64, 16, -51, -100,
+ -79, -17, 49, 88, 77, 30, -41, -95, -79, -17, 49, 87, 77, 34, -36, -92,
+ -78, -19, 44, 82, 73, 33, -37, -95, -84, -23, 47, 89, 83, 43, -30, -92,
+ -83, -28, 39, 79, 74, 40, -28, -87, -82, -31, 34, 71, 67, 35, -31, -88,
+ -85, -36, 28, 68, 69, 44, -20, -79, -83, -43, 19, 59, 64, 41, -25, -89,
+ -100, -61, 9, 60, 76, 57, -10, -75, -90, -51, 22, 74, 88, 66, 1, -61,
+ -78, -42, 25, 71, 84, 63, -1, -67, -90, -59, 8, 59, 81, 68, 8, -56,
+ -85, -62, 1, 50, 74, 63, 7, -53, -84, -60, 5, 55, 80, 70, 17, -43,
+ -76, -55, 4, 49, 73, 65, 17, -41, -77, -62, -9, 38, 68, 64, 17, -43,
+ -84, -73, -22, 23, 56, 57, 18, -36, -77, -68, -23, 20, 51, 52, 16, -36,
+ -77, -70, -26, 18, 54, 59, 28, -22, -64, -59, -20, 21, 56, 63, 36, -12,
+ -55, -52, -16, 25, 58, 63, 35, -14, -59, -57, -22, 18, 51, 57, 31, -16,
+ -58, -58, -27, 10, 43, 51, 30, -16, -59, -60, -28, 12, 48, 57, 35, -13,
+ -59, -64, -35, 7, 47, 63, 47, 1, -46, -55, -32, 7, 47, 0, 0, -1,
+ -1, -4, 1, -1, -3, -13, -8, -14, -3, -2, -2, 1, 8, 5, 7, -21,
+ -13, -2, -6, -8, -22, -6, 5, 11, 34, 41, 33, 13, 28, 33, 48, 35,
+ 21, -3, -26, -18, -10, 3, 7, 22, 21, 63, 40, 41, 43, 4, -8, -43,
+ -63, -77, -77, -59, -18, 3, 2, -21, -46, -74, -90, -108, -101, -94, -89, -84,
+ -85, -77, -59, -50, -33, -7, 18, 37, 47, 64, 101, 127, 125, 127, 126, 126,
+ 126, 122, 100, 87, 62, 37, 28, 27, 25, 27, 34, 25, -4, -45, -85, -123,
+ -128, -126, -128, -127, -123, -92, -73, -55, -45, -37, -33, -32, -33, -43, -53, -55,
+ -43, -20, 3, 20, 34, 42, 49, 55, 63, 74, 84, 93, 101, 107, 112, 117,
+ 109, 92, 63, 33, 8, -13, -25, -29, -30, -27, -27, -32, -46, -63, -82, -98,
+ -109, -116, -121, -118, -104, -80, -49, -12, 21, 45, 58, 64, 66, 66, 61, 51,
+ 44, 37, 32, 32, 33, 33, 28, 23, 15, 8, 3, 2, 9, 16, 20, 24,
+ 23, 14, -1, -20, -37, -48, -53, -52, -47, -38, -26, -13, -5, -1, -4, -10,
+ -22, -34, -43, -48, -46, -34, -16, 5, 25, 45, 65, 78, 84, 83, 71, 55,
+ 39, 24, 9, -3, -12, -23, -34, -45, -57, -65, -71, -71, -63, -49, -34, -21,
+ -11, -2, 2, 8, 11, 12, 14, 14, 20, 28, 38, 50, 58, 63, 61, 56,
+ 46, 33, 17, -1, -19, -34, -45, -48, -44, -32, -19, -5, 5, 7, 4, -2,
+ -7, -11, -15, -18, -21, -23, -26, -28, -30, -31, -29, -26, -20, -12, -1, 11,
+ 21, 32, 42, 51, 55, 55, 52, 46, 41, 37, 32, 30, 28, 27, 24, 19,
+ 12, -1, -21, -45, -67, -89, -103, -107, -101, -90, -70, -51, -33, -18, -2, 11,
+ 23, 33, 39, 44, 49, 52, 57, 59, 59, 56, 52, 48, 41, 35, 28, 20,
+ 15, 11, 4, 0, -5, -11, -18, -25, -34, -42, -47, -48, -46, -40, -33, -27,
+ -24, -21, -24, -32, -42, -51, -56, -58, -56, -47, -35, -18, 2, 24, 48, 70,
+ 88, 99, 104, 102, 97, 89, 79, 69, 59, 49, 37, 27, 14, 0, -14, -29,
+ -44, -58, -71, -81, -87, -88, -88, -85, -81, -77, -72, -63, -51, -37, -21, -5,
+ 12, 29, 43, 53, 59, 61, 57, 48, 36, 24, 13, 8, 8, 15, 25, 38,
+ 48, 54, 54, 50, 43, 33, 22, 11, 3, -6, -15, -25, -35, -46, -54, -61,
+ -65, -68, -69, -69, -68, -64, -59, -52, -43, -32, -20, -7, 6, 19, 31, 42,
+ 51, 58, 62, 64, 62, 58, 52, 44, 35, 26, 17, 9, 1, -5, -10, -15,
+ -18, -19, -20, -19, -18, -16, -15, -14, -14, -15, -16, -17, -18, -19, -19, -19,
+ -19, -18, -16, -14, -11, -9, -6, -3, 0, 3, 6, 10, 14, 18, 22, 27,
+ 32, 35, 37, 37, 35, 30, 23, 14, 4, -6, -15, -24, -31, -36, -39, -40,
+ -39, -37, -32, -26, -19, -10, -1, 8, 17, 24, 29, 32, 33, 32, 29, 25,
+ 20, 15, 11, 7, 3, -1, -5, -9, -14, -19, -24, -28, -31, -32, -31, -27,
+ -23, -16, -10, -3, 2, 7, 10, 12, 13, 13, 13, 12, 10, 8, 7, 5,
+ 5, 5, 5, 6, 8, 10, 13, 17, 20, 23, 25, 26, 25, 21, 16, 9,
+ 1, -7, -16, -24, -31, -37, -42, -47, -49, -51, -52, -51, -48, -43, -37, -30,
+ -20, -7, 6, 19, -1, -4, -4, 0, -1, -4, -3, 4, 4, -2, -3, 2,
+ 1, -4, 0, 5, 0, -4, 2, -10, -26, -29, -34, -49, -61, -44, -21, -8,
+ -3, -3, 1, 20, 32, 38, 32, 12, -4, 1, 14, 28, 51, 68, 78, 80,
+ 72, 38, 1, -6, 16, 23, 2, -14, -15, -20, -33, -62, -65, -37, -18, -27,
+ -29, -26, -45, -38, 8, 52, 55, 31, 26, 16, 17, 45, 80, 87, 77, 62,
+ 54, 24, -23, -50, -43, -28, -47, -72, -86, -86, -87, -61, -35, -38, -57, -69,
+ -55, -27, 1, 4, 22, 45, 54, 31, 0, -7, -5, -3, 0, -9, -21, -20,
+ -15, -27, -31, -10, 5, 9, 3, -21, -67, -83, -46, -3, 8, 18, 22, 4,
+ -3, 5, 35, 52, 67, 72, 83, 89, 71, 37, 19, 25, 8, -11, -37, -58,
+ -80, -85, -68, -33, -24, -57, -60, -34, -16, -14, 17, 73, 96, 77, 48, 17,
+ -7, -9, 4, -1, -3, 6, 3, -12, -10, 19, 33, 33, 41, 35, -29, -70,
+ -64, -38, -18, 3, 17, -5, -26, -35, -5, 31, 63, 73, 86, 94, 80, 64,
+ 50, 46, 37, 28, -2, -32, -65, -91, -84, -63, -59, -82, -97, -80, -66, -65,
+ -43, 8, 49, 60, 61, 42, 27, 23, 23, 14, 15, 18, 10, -12, -17, -9,
+ -13, 8, 35, 42, 2, -41, -76, -87, -67, -46, -31, -32, -45, -72, -53, -5,
+ 32, 46, 72, 92, 96, 92, 77, 75, 73, 61, 44, 12, -32, -68, -72, -54,
+ -58, -75, -85, -67, -57, -61, -60, -46, -11, 24, 35, 22, 15, 6, -1, -13,
+ 8, 23, 8, -1, -1, -6, -8, 35, 71, 86, 79, 50, -11, -46, -38, -31,
+ -29, -21, -30, -64, -68, -43, -12, 10, 28, 62, 89, 88, 84, 85, 90, 89,
+ 95, 83, 28, -32, -53, -36, -44, -62, -64, -55, -59, -54, -52, -48, -23, 19,
+ 48, 37, 39, 42, 31, 12, 19, 20, 5, 4, 1, -23, -40, -14, 14, 42,
+ 68, 64, 14, -33, -53, -52, -32, -18, -24, -43, -67, -62, -36, -18, -1, 25,
+ 54, 57, 58, 56, 54, 50, 66, 80, 44, -21, -50, -40, -52, -69, -77, -60,
+ -56, -54, -53, -62, -49, -9, 28, 41, 58, 58, 47, 43, 49, 41, 34, 37,
+ 18, -19, -44, -47, -36, 1, 35, 38, 19, -20, -62, -71, -59, -36, -34, -47,
+ -63, -63, -50, -38, -17, 7, 37, 56, 74, 80, 73, 61, 87, 116, 99, 47,
+ -7, -26, -22, -20, -32, -57, -72, -76, -76, -71, -47, -9, 13, 24, 29, 29,
+ 25, 27, 52, 68, 62, 9, -38, -67, -66, -39, -11, -4, -24, -37, -47, -51,
+ -49, -44, -55, -39, -6, -17, -52, -54, -19, 1, 15, 24, 31, 41, 55, 71,
+ 79, 89, 111, 115, 88, 54, 22, -2, -8, -5, -7, -27, -49, -57, -69, -72,
+ -64, -30, -3, 17, 31, 37, 29, 14, 39, 67, 73, 47, 10, -40, -72, -58,
+ -23, -12, -19, -19, -39, -49, -42, -46, -62, -44, -8, -11, -36, -51, -39, -15,
+ 0, 13, 21, 25, 40, 55, 63, 73, 95, 115, 115, 85, 53, 20, 2, -1,
+ -2, -10, -32, -48, -64, -73, -77, -62, -33, -9, 16, 33, 31, 18, 17, 44,
+ 67, 70, 49, 6, -45, -69, -53, -24, -13, -19, -24, -40, -47, -45, -50, -62,
+ -43, -10, -13, -37, -51, -39, -15, 0, -3, -1, 1, -1, -6, -6, -4, -1,
+ -2, -6, -8, -7, -4, -5, -10, -14, -16, -16, -16, -17, -18, -18, -17, -15,
+ -15, -16, -15, -13, -10, -9, -9, -11, -13, -14, -11, -9, -8, -9, -7, -3,
+ -2, -5, -8, -6, 1, 5, 4, 1, 0, 1, 4, 4, 4, 5, 7, 9,
+ 9, 8, 8, 9, 10, 9, 5, 2, 3, 5, 7, 7, 9, 11, 11, 12,
+ 14, 14, 12, 8, 7, 8, 5, 1, 3, 8, 9, 9, 10, 14, 16, 15,
+ 14, 12, 11, 9, 7, 3, -2, -3, 3, 5, 0, -5, -1, -1, -6, -10,
+ -16, -23, -28, -29, -32, -39, -36, -23, -16, -19, -19, -10, -7, -12, -11, -5,
+ -6, -11, -13, -11, -9, -8, -2, 6, 8, 8, 9, 6, 2, 4, 8, 9,
+ 4, 4, 12, 18, 17, 14, 17, 20, 20, 16, 9, 7, 7, 5, 3, 4,
+ 1, -2, 0, 3, 2, -1, 1, 3, 3, 1, 2, 2, 0, 3, 6, 9,
+ 8, 0, -5, -3, 7, 12, 8, -2, -2, 9, 10, 2, -3, 2, 5, 1,
+ -3, -5, -6, -2, -3, -11, -20, -26, -28, -30, -32, -37, -43, -45, -43, -40,
+ -42, -41, -31, -22, -20, -18, -16, -16, -19, -15, -8, -3, -3, 3, 17, 26,
+ 22, 16, 18, 23, 27, 26, 23, 17, 15, 21, 25, 24, 25, 31, 36, 32,
+ 29, 23, 17, 15, 11, 5, 1, 4, 6, 8, 6, 7, 8, 10, 14, 18,
+ 22, 20, 17, 14, 15, 13, 10, 15, 15, 12, 9, 10, 15, 14, 9, 3,
+ 6, 10, 5, -3, -9, -16, -16, -10, -11, -20, -24, -18, -20, -32, -42, -48,
+ -55, -70, -84, -95, -100, -92, -75, -65, -68, -67, -56, -55, -51, -41, -33, -37,
+ -42, -38, -33, -31, -26, -6, 19, 30, 25, 25, 28, 30, 27, 19, 16, 18,
+ 31, 44, 46, 48, 56, 71, 77, 74, 66, 54, 47, 37, 19, 3, 2, 3,
+ 3, 4, 13, 20, 21, 25, 24, 25, 19, 18, 19, 19, 14, 6, 17, 14,
+ 1, 3, 12, 27, 29, 25, 13, 14, 24, 22, 6, -7, -7, 0, 11, 12,
+ 1, 0, 10, 8, -13, -32, -46, -52, -57, -70, -88, -106, -101, -81, -74, -82,
+ -75, -49, -37, -42, -44, -42, -46, -51, -47, -40, -32, -27, -6, 3, 16, 32,
+ 29, 25, 24, 30, 54, 69, 74, 78, 90, 108, 118, 124, 117, 107, 102, 93,
+ 76, 61, 50, 41, 35, 31, 26, 13, 4, 0, -1, 0, -6, -12, -10, -8,
+ -4, 0, -3, -20, -31, -27, -18, -16, -22, -29, -28, -9, 0, -3, -1, 2,
+ 11, 20, 24, 18, 22, 34, 32, 16, -1, -18, -34, -46, -55, -67, -91, -102,
+ -91, -72, -73, -81, -68, -55, -55, -65, -74, -79, -87, -87, -83, -81, -77, -60,
+ -25, 4, 4, -3, 0, 13, 29, 29, 24, 23, 29, 51, 67, 72, 77, 88,
+ 105, 114, 122, 116, 106, 100, 93, 77, 63, 51, 42, 36, 31, 27, 15, 5,
+ 0, -1, 0, -4, -10, -9, -7, -3, 2, -1, -16, -28, -26, -16, -13, -18,
+ -25, -25, -8, 2, 1, 2, 5, 13, 21, 26, 20, 23, 35, 35, 20, 3,
+ -14, -32, -45, -54, -67, -91, -102, -90, -72, -75, -82, -68, -56, -56, -66, -75,
+ -81, -88, -88, -83, -82, -77, -59, -22, 4, 1, -1, -2, -3, -3, -1, -1,
+ -6, -8, -9, -12, -5, 6, 15, 21, 22, 21, 9, -8, -16, -23, -32, -22,
+ 4, 27, 32, 17, -2, -21, -34, -37, -30, -24, -3, 24, 47, 58, 50, 23,
+ -12, -41, -52, -47, -33, -2, 28, 48, 45, 28, 0, -36, -58, -53, -34, -4,
+ 26, 52, 75, 73, 45, -5, -66, -101, -90, -61, -14, 23, 59, 87, 89, 63,
+ 10, -46, -79, -80, -55, -23, -3, 27, 58, 62, 41, -6, -66, -92, -77, -29,
+ 19, 41, 65, 74, 69, 42, -9, -73, -109, -107, -67, -17, 23, 70, 104, 111,
+ 83, 21, -56, -104, -109, -62, -21, 4, 34, 68, 89, 75, 19, -46, -89, -85,
+ -38, -1, 23, 45, 64, 74, 62, 8, -53, -98, -93, -47, -9, 16, 36, 62,
+ 86, 78, 13, -67, -121, -109, -56, -9, 25, 58, 89, 109, 81, 8, -70, -119,
+ -106, -56, -7, 32, 63, 90, 108, 74, -3, -89, -128, -118, -70, -22, 23, 62,
+ 101, 126, 98, 26, -64, -117, -110, -72, -32, 6, 44, 93, 124, 100, 28, -63,
+ -116, -110, -71, -26, 16, 54, 101, 121, 92, 13, -86, -128, -120, -79, -28, 15,
+ 60, 111, 127, 95, 11, -83, -127, -116, -80, -29, 15, 67, 117, 127, 100, 17,
+ -75, -118, -108, -75, -31, 7, 60, 109, 123, 87, 3, -83, -118, -106, -67, -23,
+ 13, 62, 106, 119, 85, 3, -77, -106, -95, -61, -27, 2, 52, 103, 124, 97,
+ 19, -61, -95, -92, -63, -34, -4, 45, 94, 116, 87, 8, -63, -91, -85, -58,
+ -36, -9, 36, 81, 104, 76, 2, -60, -87, -77, -52, -32, -2, 48, 97, 119,
+ 86, 7, -59, -90, -85, -65, -50, -22, 26, 78, 107, 79, 11, -49, -78, -73,
+ -58, -46, -18, 31, 85, 112, 75, 1, -59, -84, -73, -55, -40, -12, 30, 80,
+ 106, 74, 10, -46, -70, -62, -49, -39, -13, 31, 86, 110, 74, 8, -49, -70,
+ -59, -46, -33, -6, 38, 92, 111, 76, 13, -42, -62, -56, -51, -44, -23, 19,
+ 75, 97, 67, 8, -44, -63, -58, -56, -48, -26, 19, 75, 94, 64, 8, -40,
+ -55, -50, -49, -42, -25, 18, 69, 85, 57, 4, -41, -54, -51, -50, -45, -28,
+ 18, 71, 88, 60, 8, -35, -46, -47, -48, -46, -30, 16, 66, 84, 59, 9,
+ -30, -41, -43, -42, -40, -22, 25, 73, 88, 60, 8, -30, -42, -46, -45, -42,
+ -21, 28, 74, 83, 52, -1, -36, -46, -45, -40, -37, -17, 26, 66, 73, 41,
+ -10, -42, -54, -53, -48, -43, -19, 27, 68, 76, 44, -4, -34, -44, -41, -37,
+ -33, -10, 34, 71, 75, 40, -7, -36, -47, -43, -39, -35, -9, 35, 72, 75,
+ 39, -7, -38, -49, -45, -43, -38, -11, 33, 68, 70, 36, -4, -31, -39, -36,
+ -35, -31, -5, 36, 69, 69, 35, -4, -31, -38, -35, -37, -33, -8, 31, 64,
+ 63, 31, -7, -34, -42, -40, -43, -38, -12, 28, 61, 59, 27, -10, -34, -40,
+ -38, -41, -35, -9, 31, 63, 60, 29, -6, -31, -37, -38, -42, -35, -10, 29,
+ 60, 56, 27, -8, -30, -33, -34, -38, -32, -10, 28, 56, 51, 23, -9, -29,
+ -32, -34, -38, -33, -10, 29, 55, 50, 23, -9, -28, -30, -33, -37, -32, -8,
+ 32, 56, 52, 23, 23, 0, -2, 0, -2, -6, -6, -6, -5, -2, -1, 5,
+ 15, 20, 11, 12, 12, 6, 0, -8, -19, -12, -4, -19, -19, -4, 4, -7,
+ -3, 5, 8, 11, 14, 9, 9, 8, -4, -11, -6, -8, -16, -14, -7, -1,
+ -3, 1, 10, 13, 24, 28, 12, 10, 14, 11, -14, -29, -19, -12, -21, -25,
+ -16, 2, 0, -11, -7, 7, 10, 0, 0, 5, 11, 6, 10, 21, 13, 7,
+ 14, 4, -4, -9, -5, -11, -16, -7, -3, 3, 15, -2, 2, 17, 6, -19,
+ -16, 3, 3, -14, -10, 7, 7, 4, 8, 11, 4, -5, -12, -9, -6, -14,
+ -13, -17, -13, -8, 5, 9, 3, 10, 12, 24, 28, 26, 35, 20, -3, 24,
+ 23, -19, -31, -23, -23, -38, -34, -18, -10, -8, -6, -4, -1, 5, -4, -8,
+ 2, 15, 12, 26, 56, 37, 10, 25, 25, -4, -21, -24, -23, -26, -30, -27,
+ -8, 10, -5, 3, 30, 6, -26, -7, 13, -2, -19, -2, 11, 3, 14, 21,
+ 8, 12, 5, -19, -26, -12, 9, 1, -8, -8, 20, 27, 17, 16, 15, 0,
+ 23, 39, 11, -4, -13, -21, -21, -32, -36, -27, -20, -24, -10, -4, 5, 14,
+ 4, -11, -10, 7, -8, -7, 7, 7, 2, 15, 29, 55, 26, 4, 22, 37,
+ 32, 14, 10, 18, 7, -1, -28, -49, -24, -14, -41, -53, -37, -28, -27, -15,
+ 1, 2, 14, 14, 13, 3, 0, 1, 18, 9, 7, 11, 23, 23, 25, 16,
+ -7, 1, 13, 26, 26, 9, 13, 28, 28, 1, -29, -29, -26, -27, -43, -43,
+ -31, -12, -26, -15, 6, 16, 6, 22, 11, -4, 0, 3, 0, -4, -20, -9,
+ 15, 23, 19, 7, 25, 19, 42, 63, 40, 13, 22, 24, 1, -41, -60, -55,
+ -63, -69, -61, -31, -7, 10, 8, 0, 7, 4, 4, 20, 5, -4, 9, 27,
+ 31, 27, 23, 13, 19, 12, 2, 4, 15, 20, 35, 19, 16, 26, 3, -30,
+ -48, -31, -40, -60, -59, -47, -13, -3, 12, 22, 11, 7, 9, 8, 3, -10,
+ -34, -5, 6, 24, 38, 19, 13, 21, 40, 15, 2, 27, 26, 16, 44, 47,
+ -7, -43, -41, -29, -44, -80, -81, -58, -26, -17, 3, 16, 30, 19, 10, 25,
+ 16, 6, -12, -3, 13, 30, 38, 20, 17, 22, 25, 18, 13, 16, -3, 1,
+ 32, 44, -11, -48, -51, -34, -38, -49, -64, -70, -23, -10, -14, -1, 20, 18,
+ 20, 21, 11, 3, -8, -3, 13, 14, 22, 18, 32, 37, 30, 25, 16, 27,
+ 27, 18, 37, 52, 12, -26, -56, -57, -46, -71, -92, -86, -50, -21, -10, 8,
+ 15, 15, 18, 28, 17, 1, 1, 2, 13, 13, 23, 23, 21, 29, 31, 29,
+ 15, 20, 33, 32, 29, 46, 21, -31, -49, -53, -51, -66, -82, -76, -54, -32,
+ -10, 12, 19, 29, 18, 3, 0, 16, 20, 29, 31, 20, 25, 31, 43, 41,
+ 34, 44, 27, 29, 65, 54, -15, -70, -79, -63, -86, -114, -114, -79, -26, -2,
+ 6, 18, 19, 10, 19, 26, 15, 5, 0, 16, 23, 29, 30, 21, 25, 28,
+ 37, 37, 38, 44, 32, 29, 66, 65, -7, -67, -74, -59, -82, -114, -117, -85,
+ -31, -2, 11, 20, 18, 9, 20, 30, 15, 5, 0, 0, 1, 1, 2, 3,
+ 3, 3, 4, 4, 5, 6, 6, 7, 8, 8, 7, 7, 7, 7, 7, 6,
+ 4, 3, 2, 0, -1, -2, -3, -5, -6, -8, -9, -9, -11, -12, -14, -15,
+ -17, -17, -17, -18, -19, -19, -19, -18, -17, -16, -15, -13, -11, -8, -7, -6,
+ -5, -3, -1, 0, 0, 1, 3, 5, 8, 10, 12, 14, 17, 19, 21, 23,
+ 26, 27, 28, 28, 28, 26, 25, 24, 23, 23, 21, 19, 18, 16, 15, 14,
+ 13, 12, 11, 11, 11, 10, 8, 6, 5, 5, 4, 2, 0, -2, -4, -5,
+ -7, -10, -11, -12, -13, -14, -15, -15, -15, -15, -15, -16, -17, -18, -18, -19,
+ -21, -23, -25, -27, -28, -29, -29, -30, -30, -29, -27, -25, -23, -22, -20, -18,
+ -16, -14, -13, -12, -11, -11, -10, -9, -8, -6, -5, -4, -3, -1, 1, 3,
+ 4, 6, 7, 8, 8, 9, 10, 11, 12, 13, 13, 13, 13, 15, 18, 21,
+ 23, 24, 25, 25, 28, 31, 33, 34, 34, 32, 31, 31, 31, 30, 27, 22,
+ 16, 12, 10, 9, 7, 3, -5, -13, -19, -22, -22, -23, -25, -28, -31, -33,
+ -33, -32, -32, -31, -32, -33, -32, -29, -25, -21, -19, -19, -19, -19, -18, -15,
+ -9, -3, 2, 6, 9, 12, 16, 21, 27, 32, 37, 39, 40, 40, 39, 39,
+ 40, 41, 40, 38, 35, 34, 34, 33, 29, 22, 16, 11, 10, 11, 12, 12,
+ 10, 8, 7, 5, 3, 2, 0, -6, -12, -19, -23, -23, -22, -23, -26, -30,
+ -33, -33, -33, -34, -35, -37, -40, -45, -50, -53, -52, -48, -42, -37, -32, -27,
+ -22, -20, -18, -16, -16, -18, -21, -26, -30, -33, -34, -35, -36, -38, -40, -41,
+ -41, -38, -36, -36, -38, -41, -40, -38, -34, -30, -27, -25, -22, -20, -16, -15,
+ -16, -17, -18, -16, -13, -10, -7, -4, -2, 1, 6, 11, 16, 21, 24, 25,
+ 26, 24, 22, 19, 18, 19, 22, 24, 26, 30, 33, 38, 44, 50, 56, 61,
+ 63, 68, 72, 74, 73, 68, 64, 57, 50, 47, 46, 44, 37, 21, 3, -11,
+ -20, -23, -25, -30, -33, -36, -36, -34, -31, -27, -22, -21, -22, -21, -18, -21,
+ -24, -27, -31, -33, -32, -27, -21, -14, -13, -17, -17, -10, 0, 10, 15, 16,
+ 14, 8, 6, 10, 16, 25, 34, 39, 43, 47, 53, 62, 72, 82, 89, 92,
+ 90, 84, 79, 77, 77, 76, 67, 54, 42, 33, 26, 18, 5, -11, -27, -41,
+ -53, -65, -73, -77, -79, -81, -86, -93, -102, -110, -116, -118, -120, -124, -127, -128,
+ -128, -126, -122, -116, -107, -96, -85, -78, -72, -64, -54, -45, -39, -40, -46, -49,
+ -49, -47, -45, -44, -45, -45, -44, -42, -38, -33, -29, -26, -23, -20, -18, -14,
+ -11, -8, -5, -2, 2, 7, 11, 10, 8, 7, 9, 16, 22, 26, 28, 31,
+ 34, 39, 44, 49, 53, 57, 60, 62, 63, 63, 65, 66, 63, 57, 51, 46,
+ 46, 50, 53, 54, 55, 54, 55, 57, 63, 69, 73, 75, 73, 69, 66, 64,
+ 65, 63, 55, 43, 30, 18, 11, 3, -6, -15, -23, -29, -32, -32, -28, -22,
+ -16, -13, -16, -16, -11, -2, 9, 15, 1, 0, 0, 0, -1, 0, -3, 0,
+ -1, 0, -18, 21, -22, 23, -41, 20, 84, -39, 50, -61, 26, -126, -19, -37,
+ 15, 2, 70, -33, 127, -55, 117, -73, 15, -45, -50, 8, -11, 23, 33, 1,
+ 26, -67, 26, -25, 14, -45, 57, -124, 12, -4, -23, 107, -54, 127, -49, 43,
+ 27, -59, -30, 15, -128, 5, -128, 86, -39, 82, 12, 62, 9, 51, -59, 53,
+ -95, 67, -92, 68, -28, 94, 21, 47, -11, -1, -41, 0, -25, -9, 18, -68,
+ 15, -27, 49, -27, 103, -4, 3, -36, 58, -98, 56, -116, -31, -123, 25, -58,
+ 89, -21, 110, -25, 73, -28, 39, -21, 35, -40, 37, -20, 50, 55, 51, 6,
+ 1, -47, -11, -32, -23, 38, -67, 3, -54, 34, -55, 79, 1, 32, -61, 89,
+ -86, 53, -67, -10, -128, -6, -68, 51, -4, 82, 15, 83, -16, 63, -24, 55,
+ -29, 8, 0, 6, 11, 54, 14, 16, -39, -9, -12, -47, 37, -40, -22, -60,
+ 21, -76, 51, -17, 74, -63, 98, -36, 44, -33, 24, -113, -37, -89, 20, -30,
+ 67, 18, 87, 0, 67, -6, 38, 1, -2, -18, -5, -20, 32, 17, 21, -8,
+ -30, 15, -47, 11, -17, 11, -97, 43, -87, 27, -36, 91, -41, 66, 3, 44,
+ -28, 55, -74, -37, -92, -21, -37, 33, -1, 75, 22, 36, 14, 26, 8, 8,
+ -12, -7, -21, -1, 27, 11, 21, -30, 21, -37, -3, -13, 23, -27, -32, -10,
+ -23, -44, 56, -1, 43, -12, 76, -29, 48, -9, -25, -71, -70, -48, -20, 2,
+ 9, 56, 8, 56, -10, 52, -12, 31, -29, 27, -60, 62, -42, 83, -45, 30,
+ -24, 4, -26, 33, -23, 5, -18, -25, -53, -7, -6, -6, 19, 16, 31, 3,
+ 58, -14, 0, -64, -33, -58, -8, -43, 42, -18, 57, -9, 54, 1, 47, -3,
+ 36, -18, 3, 4, 6, 2, -17, 8, -14, -27, 35, 2, -3, 1, -8, -43,
+ -34, -1, -22, 12, 2, 37, -6, 53, 14, 16, -43, -22, -75, -2, -67, 23,
+ -24, 39, -3, 39, 6, 44, 9, 37, 5, 1, 3, 5, 12, -18, 0, 0,
+ -31, 5, 23, 1, -3, 10, -20, -48, -6, -30, 7, -18, 35, -4, 32, 21,
+ 39, -26, -1, -75, -9, -65, -3, -28, 20, -5, 32, 5, 36, 20, 30, 30,
+ 3, 10, -1, 16, -10, -7, -1, -17, -23, 18, 14, -3, 8, 9, -45, -14,
+ -35, -1, -27, 18, -2, 29, 1, 61, -14, 20, -56, -19, -51, -22, -38, 9,
+ -14, 22, 5, 24, 27, 23, 41, 13, 20, -7, 23, -2, -8, -2, -9, -26,
+ -6, 14, 11, -11, 37, -33, -12, -38, -6, -33, 7, -14, 30, -12, 55, 4,
+ 33, -32, -14, -45, -22, -43, -7, -15, 18, 18, 33, 17, 41, 22, 15, 14,
+ 8, -24, -16, -18, -16, -7, 6, 16, -2, 8, -14, -6, -23, 0, -22, 1,
+ -23, 21, 4, 24, -1, 9, -9, -11, -14, -13, -16, -14, -15, -12, -16, -5,
+ 8, 28, 25, 28, 34, 27, 15, 16, 2, -20, -22, -20, -15, -8, 10, 11,
+ 7, -3, -5, -16, -10, -13, -5, -16, -5, 4, 17, 13, 6, 1, -9, -1,
+ -2, -3, -4, -4, -5, -5, -5, -5, -5, -5, -5, -5, -5, -5, -5, -6,
+ -6, -6, -6, -6, -5, -3, -3, -5, -5, -5, -7, -8, -5, 4, 5, 13,
+ 12, -12, -5, 10, 5, 4, 0, 3, 26, 33, 10, -15, -69, -89, -25, 25,
+ 58, 70, 22, -41, -62, -31, 18, 17, -17, -12, -9, 20, 99, 96, 0, -88,
+ -123, -69, 61, 116, 54, -11, -45, -28, 40, 38, -42, -59, -53, -31, 63, 78,
+ -9, -65, -83, -59, 48, 110, 50, -11, -51, -54, 41, 96, 9, -87, -119, -77,
+ 42, 118, 67, -18, -57, -46, 24, 89, 81, 22, -43, -77, -65, -41, -23, -3,
+ 4, 8, -13, -54, -52, -21, 30, 89, 86, 8, -49, -76, -56, 30, 55, 52,
+ 47, -7, -45, -49, -48, -10, 68, 74, 43, 22, -27, -25, 12, 20, -5, -43,
+ -69, -46, 21, 53, 51, 38, -8, -32, 6, 20, -1, -19, -56, -67, -26, 27,
+ 76, 95, 23, -64, -60, -15, 33, 39, -8, -37, -24, -7, 7, 4, -25, -23,
+ -10, -14, -7, -5, -12, 2, 28, 31, 37, 21, -18, -16, -4, -22, -37, -46,
+ -56, -8, 58, 64, 53, 31, -9, -9, -2, -57, -85, -52, -13, 59, 92, 21,
+ -42, -47, -33, 27, 75, 27, -22, -38, -44, 18, 77, 32, -21, -46, -50, 34,
+ 89, 22, -37, -60, -56, 31, 95, 36, -27, -57, -82, -15, 53, 15, -13, -25,
+ -44, 14, 66, 14, -32, -53, -62, 25, 96, 50, 3, -32, -56, 25, 98, 51,
+ -9, -56, -78, 7, 92, 71, 28, -31, -92, -42, 28, 20, 24, 8, -34, 22,
+ 70, 18, -17, -53, -88, -20, 39, 7, -2, -8, -28, 35, 80, 19, -23, -55,
+ -93, -22, 63, 54, 47, 19, -52, -35, 2, -36, -32, -18, -49, -9, 41, 15,
+ 26, 34, -22, -6, 31, 1, 8, 9, -43, -15, 30, -3, -1, -7, -73, -48,
+ 6, -14, 5, 13, -47, -30, 12, -13, 6, 18, -37, -13, 39, 27, 45, 38,
+ -37, -32, 12, 3, 32, 46, -10, 6, 48, 16, 15, 15, -32, -2, 47, 24,
+ 26, 18, -51, -51, -15, -29, -1, 19, -28, -15, 21, 2, 18, 22, -34, -24,
+ 13, -3, 15, 14, -45, -34, 7, 10, 38, 31, -34, -30, 4, 5, 43, 61,
+ 13, 4, 6, -22, 4, 24, -13, -13, -10, -34, 0, 23, -16, -16, -13, -42,
+ -18, -4, -36, -17, 5, -10, 14, 22, -21, -22, -16, -37, -6, 20, -2, 17,
+ 36, 19, 43, 43, -9, -15, -12, -29, 6, 31, 6, 10, 7, -23, -2, 9,
+ -23, -15, -10, -26, 3, 20, -5, 1, 0, -22, 5, 22, -6, -8, -16, -37,
+ -5, 20, 2, 11, 6, -19, 11, 33, 12, 20, 16, -7, 20, 35, 11, 11,
+ -3, -28, 2, 19, -1, 3, -6, -29, -5, 2, -25, -17, -12, -16, 22, 34,
+ 3, -4, -21, -36, 4, 26, 8, -1, -30, -54, -23, -3, -11, 0, -12, -27,
+ 7, 24, 13, 19, -1, -21, 10, 27, 14, 17, 0, -14, 18, 33, 19, 14,
+ -17, -41, -10, 9, 2, 7, -14, -30, 4, 20, 9, 9, -15, -35, -3, 16,
+ 9, 0, -1, -2, -3, 4, 7, 4, -2, -3, 0, 3, -1, -1, 4, 5,
+ -2, -13, -9, 1, 4, 2, 1, 2, 2, -2, -8, -4, 0, 4, 4, -3,
+ -4, -3, 1, 2, -1, 3, 14, 1, -7, -12, -4, -2, 1, 1, 9, 5,
+ -6, -5, -2, -1, -1, 1, 14, 6, -6, -7, 3, 8, -2, -4, 13, 12,
+ -10, -17, -10, -5, -4, 2, 3, 7, -6, -6, -1, -1, -4, 1, 11, 6,
+ -6, -9, 10, 11, 3, 1, 14, 15, -12, -20, -12, -9, -15, -1, 7, 2,
+ -16, -7, 6, 0, -2, 10, 26, 17, -6, -11, 24, 21, 1, 0, 18, 15,
+ -17, -31, -28, -23, -14, 0, -4, 0, -16, -8, 8, -4, -3, 7, 15, 5,
+ -3, -3, 26, 25, 12, 8, 28, 17, -15, -28, -18, -17, -18, -7, -3, -7,
+ -20, 0, 7, 1, -9, 6, 9, -4, -9, 2, 15, 24, 34, 31, 10, -4,
+ -15, -29, -17, -21, -41, -40, -5, 19, -20, 3, 11, 33, 28, 21, 18, 15,
+ 16, 3, -1, 18, 17, 15, 1, -15, -10, -5, -14, -42, -48, -43, -26, 4,
+ -29, -14, -9, 32, 20, 12, 15, 21, 39, 24, 8, 26, 33, 6, -3, 0,
+ 1, -7, -16, -41, -44, -51, -34, -3, -6, -6, -19, 26, 10, 15, 35, 46,
+ 32, 20, 16, 23, 38, 15, -4, -10, 17, -6, -41, -48, -53, -70, -52, -9,
+ -9, -22, -15, 19, 24, 22, 30, 49, 34, 10, 1, 15, 33, 15, 1, 17,
+ 46, 12, -38, -59, -50, -57, -46, -13, -16, -30, -24, 26, 37, 33, 30, 45,
+ 40, 2, -11, 17, 41, 24, -4, 16, 48, 15, -38, -67, -64, -65, -46, -18,
+ -18, -35, -32, 35, 39, 37, 21, 45, 42, -2, -19, 14, 37, 22, 7, 24,
+ 40, 13, -42, -68, -63, -63, -38, -6, -12, -34, -25, 39, 43, 39, 17, 47,
+ 45, 3, -19, 21, 45, 25, 2, 21, 31, 0, -45, -71, -78, -83, -48, 2,
+ 7, -27, -32, 34, 45, 49, 23, 44, 36, 5, -5, 38, 60, 27, -13, 21,
+ 42, -13, -69, -81, -86, -79, -38, -9, -11, -41, -36, 38, 56, 45, 10, 43,
+ 43, 10, -6, 36, 57, 41, 10, 36, 46, -16, -67, -66, -71, -80, -44, -8,
+ -5, -29, -27, 30, 43, 46, 20, 52, 39, -9, -21, 40, 68, 42, -1, 20,
+ 32, -14, -70, -86, -94, -90, -45, -2, 0, -31, -17, 36, 47, 46, 18, 44,
+ 29, -2, -11, 46, 74, 51, 14, 36, 46, -15, -78, -87, -91, -89, -46, -12,
+ -11, -28, -5, 41, 46, 40, 17, 51, 33, -6, -13, 49, 75, 52, 15, 30,
+ 34, -21, -79, -88, -93, -88, -42, -9, -4, -25, -3, 36, 40, 34, 16, 44,
+ 23, -8, -10, 52, 83, 55, 17, 38, 31, -31, -82, -91, -93, -82, -39, -16,
+ -10, -25, 5, 33, 42, 32, 20, 54, 25, -9, -3, 59, 85, 63, 24, 37,
+ 24, -39, -86, -92, -97, -80, -34, -17, -15, -24, 10, 35, 45, 32, 16, 45,
+ 12, -23, -2, 62, 78, 53, 21, 37, 26, -39, -91, -95, -96, -77, -29, -16,
+ -16, -25, 10, -1, 0, 3, 21, -26, 18, -30, 32, -19, -15, -27, 2, 0,
+ 103, -84, -53, -52, 79, 51, 36, -69, -31, 48, 71, 33, -74, -64, 10, 51,
+ 49, -68, -91, -16, 30, 33, -31, -58, -42, 14, 24, -25, 23, -71, 79, -22,
+ 123, -74, 28, 28, 115, 99, -7, 9, -15, 72, 1, 16, -47, -5, -71, -18,
+ -75, -26, -71, -28, -56, -24, -57, -19, -33, -5, 7, -3, 14, -8, 82, 100,
+ 23, -32, -15, 80, 98, 68, -30, -21, 24, 71, 28, -41, -96, -22, 32, 37,
+ -57, -110, -67, 28, 35, -22, -112, -79, 13, 70, 27, -55, -63, 31, 95, 86,
+ -4, -40, 29, 110, 110, 28, -50, -12, 66, 80, 14, -87, -81, -7, 36, -5,
+ -95, -118, -42, 26, 8, -69, -121, -48, 37, 60, -6, -68, -29, 67, 104, 61,
+ -24, -17, 70, 123, 92, -5, -43, 23, 82, 67, -28, -96, -54, 18, 30, -39,
+ -115, -96, -7, 25, -13, -99, -101, -13, 52, 42, -35, -62, 9, 88, 93, 28,
+ -32, 15, 97, 118, 58, -29, -24, 51, 82, 39, -61, -88, -26, 28, 9, -70,
+ -117, -63, 7, 14, -46, -109, -71, 15, 55, 16, -51, -42, 43, 94, 75, 2,
+ -21, 48, 107, 101, 23, -36, 4, 65, 70, 1, -81, -69, -3, 26, -19, -94,
+ -106, -32, 14, -3, -74, -103, -37, 34, 46, -10, -56, -12, 66, 91, 49, -15,
+ 1, 74, 111, 76, -4, -28, 31, 72, 50, -33, -85, -43, 11, 15, -46, -106,
+ -80, -11, 13, -26, -92, -84, -8, 44, 29, -30, -48, 19, 80, 81, 26, -18,
+ 27, 91, 103, 49, -22, -10, 48, 68, 22, -60, -75, -22, 17, -5, -71, -105,
+ -54, 3, 3, -49, -98, -58, 14, 44, 11, -44, -27, 45, 85, 65, 5, -8,
+ 53, 100, 87, 21, -26, 11, 60, 56, -6, -74, -58, -4, 13, -25, -90, -91,
+ -29, 7, -12, -72, -90, -29, 32, 37, -10, -46, -2, 66, 83, 47, -8, 10,
+ 74, 101, 68, -3, -19, 31, 62, 38, -36, -77, -40, 6, 4, -49, -100, -72,
+ -12, 3, -31, -86, -73, -4, 37, 25, -28, -36, 25, 75, 74, 25, -9, 34,
+ 88, 94, 43, -16, -4, 47, 58, 15, -57, -69, -22, 6, -12, -73, -96, -50,
+ -4, -7, -53, -89, -49, 13, 36, 5, -37, -17, 47, 77, 59, 9, 2, 58,
+ 92, 79, 19, -17, 16, 54, 45, -13, -69, -52, -8, 3, -33, -85, -82, -29,
+ -2, -20, -68, -79, -23, 24, 29, -11, -34, 7, 61, 73, 41, 0, 22, 73,
+ 90, 58, 1, -9, 32, 52, 26, -36, -69, -35, -3, -7, -53, -90, -63, -16,
+ -7, -36, -78, -60, -4, 29, 16, -22, -23, 29, 68, 64, 26, 2, 42, 80,
+ 81, 38, -8, 5, 42, 44, 4, -53, -57, -21, -2, -22, -69, -83, -43, -10,
+ -15, -51, -77, -38, 11, 27, 3, -27, -5, 46, 68, 52, 13, 15, 58, 83,
+ 68, 19, -8, 21, 46, 32, -16, -60, -44, -12, -6, -36, -76, -74, -34, -10,
+ -20, -57, -73, -33, 12, 27, 3, -1, -6, -11, -3, 4, 0, -7, -8, 1,
+ 21, 14, 28, 33, 25, -1, 7, 4, -13, -21, -44, -29, -17, -31, -32, 2,
+ 0, -20, 4, 3, 4, 0, -2, -5, -4, -14, 3, 14, 9, 28, 34, 54,
+ 43, 54, 39, 19, 17, -1, 5, -23, -31, -25, -35, -46, -60, -29, -29, -13,
+ -37, -22, -16, -20, -27, -21, -6, -16, 8, -5, 15, 26, 69, 65, 74, 85,
+ 81, 76, 51, 22, -10, -10, -19, -3, -39, -73, -55, -36, -18, -45, -49, -45,
+ -52, -47, -74, -73, -56, -31, -15, -16, -5, 18, 65, 86, 108, 94, 97, 90,
+ 79, 54, 30, 19, 10, 25, -16, -34, -37, -9, -16, -35, -44, -60, -60, -50,
+ -62, -70, -66, -44, -34, -34, -29, -10, 23, 61, 85, 79, 75, 70, 61, 41,
+ 31, 7, 8, 3, -22, -42, -28, 0, -13, -29, -39, -52, -56, -55, -58, -60,
+ -57, -41, -35, -37, -19, 5, 35, 71, 87, 85, 97, 112, 97, 71, 56, 52,
+ 53, 43, 18, -7, -3, 10, 0, -17, -39, -55, -58, -64, -80, -106, -121, -112,
+ -110, -113, -105, -82, -51, -8, 16, 20, 45, 66, 66, 49, 46, 59, 75, 78,
+ 63, 62, 74, 80, 80, 69, 51, 27, 11, 0, -14, -40, -53, -48, -55, -68,
+ -71, -56, -34, -1, 14, 24, 49, 62, 59, 42, 34, 43, 47, 43, 26, 30,
+ 33, 38, 26, 4, -17, -41, -66, -81, -92, -112, -120, -115, -116, -128, -125, -103,
+ -71, -36, -11, 9, 33, 56, 59, 54, 61, 67, 77, 77, 77, 79, 74, 75,
+ 73, 55, 30, 10, -21, -38, -46, -61, -70, -67, -70, -81, -77, -64, -45, -23,
+ -4, 10, 30, 44, 44, 39, 42, 48, 51, 50, 51, 58, 58, 65, 65, 47,
+ 29, 12, -14, -31, -41, -53, -63, -60, -62, -64, -58, -44, -26, -11, 1, 10,
+ 20, 22, 17, 9, 5, 6, 6, 2, 4, 10, 10, 17, 19, 9, 7, -1,
+ -14, -18, -13, -14, -9, 1, 7, 12, 17, 23, 31, 35, 36, 35, 38, 31,
+ 21, 16, 3, 0, -8, -11, -11, -13, -19, -20, -23, -34, -39, -51, -69, -78,
+ -81, -83, -83, -78, -70, -60, -47, -34, -19, 2, 20, 39, 57, 60, 66, 67,
+ 63, 61, 53, 50, 51, 47, 37, 32, 23, 13, 6, -3, -17, -23, -28, -34,
+ -37, -35, -27, -15, -2, 4, 12, 23, 30, 44, 47, 43, 41, 35, 29, 22,
+ 15, 13, 14, 7, -1, -5, -11, -19, -20, -25, -37, -43, -41, -43, -47, -47,
+ -40, -29, -17, -7, 5, 13, 23, 38, 44, 37, 34, 31, 23, 17, 6, 1,
+ -2, -10, -20, -25, -35, -45, -50, -54, -64, -68, -65, -66, -65, -59, -47, -30,
+ -19, -7, 5, 14, 28, 48, 62, 66, 72, 75, 78, 76, 67, 60, 56, 46,
+ 32, 20, 9, -2, -10, -21, -35, -43, -44, -49, -56, -57, -51, -38, -25, -13,
+ -2, 9, 25, 42, 56, 59, 64, 65, 67, 65, 57, 52, 49, 41, 28, 18,
+ 8, -2, -10, 0, 8, 13, 21, 20, 20, 17, 10, 8, -2, -6, -17, -21,
+ -29, -23, -25, -14, -7, -2, 7, 10, 20, 21, 22, 23, 19, 14, 9, -2,
+ -6, -18, -20, -28, -25, -23, -18, -10, -3, 5, 9, 22, 17, 28, 22, 21,
+ 17, 11, 2, -8, -18, -23, -27, -26, -24, -19, -13, -6, 3, 9, 17, 20,
+ 28, 24, 25, 21, 13, 6, -5, -14, -21, -29, -29, -30, -23, -19, -7, -1,
+ 10, 18, 25, 29, 27, 28, 20, 17, 5, -7, -13, -26, -29, -30, -30, -27,
+ -20, -12, 0, 11, 19, 25, 27, 30, 26, 28, 19, 11, -2, -12, -24, -30,
+ -35, -34, -30, -24, -14, -2, 9, 18, 23, 28, 26, 33, 31, 29, 24, 12,
+ 5, -12, -23, -30, -37, -36, -36, -26, -19, -5, 5, 19, 22, 32, 32, 36,
+ 35, 26, 21, 3, -6, -22, -34, -41, -44, -38, -31, -18, -6, 6, 15, 23,
+ 32, 33, 39, 34, 31, 23, 10, -2, -21, -32, -44, -47, -45, -37, -23, -12,
+ 6, 13, 28, 30, 38, 40, 40, 38, 23, 17, -6, -15, -35, -42, -50, -49,
+ -41, -31, -14, 0, 14, 26, 35, 42, 45, 45, 40, 27, 18, -4, -14, -33,
+ -42, -54, -52, -47, -36, -21, -5, 13, 24, 39, 43, 52, 47, 42, 36, 20,
+ 7, -15, -32, -45, -55, -56, -54, -43, -27, -8, 12, 26, 38, 45, 50, 51,
+ 48, 40, 27, 9, -11, -30, -46, -58, -62, -58, -49, -31, -11, 9, 24, 41,
+ 45, 54, 53, 54, 45, 30, 14, -10, -27, -48, -58, -67, -64, -56, -35, -15,
+ 6, 24, 37, 45, 54, 56, 56, 49, 39, 18, 0, -26, -45, -60, -74, -70,
+ -63, -41, -23, 4, 21, 39, 48, 53, 61, 58, 59, 43, 29, 3, -20, -46,
+ -64, -77, -77, -69, -50, -27, 0, 20, 36, 49, 56, 64, 64, 63, 51, 34,
+ 6, -17, -46, -65, -79, -83, -76, -58, -33, -6, 17, 38, 49, 60, 67, 68,
+ 66, 53, 37, 13, -13, -38, -65, -79, -90, -82, -68, -41, -15, 14, 36, 52,
+ 63, 70, 73, 69, 62, 44, 19, -8, -38, -63, -83, -93, -90, -77, -49, -20,
+ 12, 34, 54, 65, 72, 75, 76, 65, 51, 26, -1, -33, -62, -86, -98, -96,
+ -86, -58, -29, 6, 32, 54, 66, 73, 79, 76, 73, 58, 36, 4, -27, -60,
+ -85, -101, -104, -92, -70, -36, -1, 31, 53, 70, 75, 81, 80, 78, 65, 41,
+ 15, -24, -56, -84, -105, -109, -101, -79, -46, -7, 25, 56, 65, 77, 82, 85,
+ 83, 69, 51, 19, -14, -50, -83, -103, -115, -107, -88, -55, -17, 21, 50, 67,
+ 81, 86, 89, 85, 79, 55, 28, -8, -46, -77, -103, -116, -117, -97, -67, -25,
+ 1, 39, 66, 81, 92, 96, 97, 90, 73, 45, 11, -27, -64, -97, -120, -128,
+ -117, -89, -49, -5, 35, 65, 81, 93, 98, 99, 91, 75, 46, 12, -27, 28,
+ -9, -42, -57, -50, -18, 33, 77, 77, 17, -64, -96, -55, 22, 73, 68, 17,
+ -43, -77, -67, -15, 59, 102, 79, 12, -48, -71, -57, -28, -3, 11, 10, -3,
+ -17, -4, 44, 88, 79, 10, -69, -103, -74, -6, 54, 75, 53, -4, -63, -80,
+ -38, 32, 73, 59, 7, -43, -67, -57, -18, 33, 71, 71, 24, -31, -47, -17,
+ 20, 23, -14, -58, -73, -47, 10, 73, 110, 93, 20, -62, -97, -68, -6, 43,
+ 54, 28, -13, -51, -65, -35, 26, 74, 69, 12, -50, -68, -37, 9, 37, 37,
+ 16, -12, -26, -7, 36, 65, 45, -19, -87, -112, -75, -7, 58, 97, 92, 41,
+ -30, -75, -62, -3, 49, 52, 7, -44, -63, -45, -6, 37, 60, 42, -5, -42,
+ -41, -3, 38, 41, 8, -33, -51, -38, 3, 54, 90, 79, 12, -76, -127, -106,
+ -29, 47, 78, 63, 23, -19, -36, -16, 24, 50, 35, -15, -59, -64, -27, 17,
+ 40, 35, 11, -20, -39, -26, 19, 63, 67, 14, -61, -97, -72, -5, 64, 101,
+ 87, 26, -49, -96, -86, -32, 24, 40, 17, -11, -17, -3, 24, 51, 55, 29,
+ -20, -66, -69, -23, 35, 55, 25, -26, -59, -55, -14, 44, 86, 80, 23, -56,
+ -105, -87, -19, 48, 79, 67, 27, -18, -46, -43, -14, 17, 16, -20, -54, -47,
+ 3, 59, 83, 66, 18, -35, -64, -54, -8, 44, 59, 18, -48, -87, -72, -16,
+ 49, 88, 84, 37, -31, -81, -79, -26, 33, 52, 29, -5, -19, -6, 20, 34,
+ 27, -5, -51, -84, -71, -9, 62, 95, 71, 12, -40, -58, -37, 8, 52, 63,
+ 22, -53, -103, -88, -23, 47, 80, 64, 24, -14, -33, -28, -3, 21, 18, -15,
+ -45, -39, 5, 57, 78, 54, -1, -60, -97, -89, -29, 50, 92, 67, 0, -53,
+ -57, -13, 38, 64, 52, 10, -44, -82, -76, -26, 28, 49, 32, 1, -14, -1,
+ 24, 40, 38, 9, -43, -87, -79, -13, 69, 110, 80, 4, -65, -90, -69, -21,
+ 32, 58, 39, -9, -48, -45, 0, 52, 69, 46, 5, -34, -57, -50, -14, 23,
+ 28, -8, -48, -48, 4, 71, 99, 69, 3, -63, -99, -88, -30, 46, 92, 78,
+ 16, -45, -66, -44, -6, 25, 34, 16, -24, -55, -43, 10, 67, 80, 37, -22,
+ -48, -29, 7, 30, 27, -5, -51, -84, -73, -11, 71, 116, 95, 27, -43, -84,
+ -84, -43, 18, 63, 60, 10, -44, -53, -9, 41, 49, 14, -31, -57, -50, -15,
+ 29, 61, 57, 14, -37, -51, -14, 38, 63, 47, -1, -61, -106, -105, -47, 44,
+ 115, 113, 42, -36, -64, -42, -2, 23, 20, -3, -28, -39, -21, 24, 64, 59,
+ 7, -48, -67, -47, -7, 36, 59, 47, 2, -55, -77, -31, 55, 111, 89, 7,
+ -75, -113, -96, -42, 21, 62, 64, 28, -13, -18, 17, 45, 28, -2, -7, -6,
+ -7, -7, -8, -8, -8, -8, -7, -6, -5, -4, -3, -3, -2, -2, -1, 0,
+ 1, 2, 4, 5, 6, 8, 9, 10, 11, 12, 13, 13, 14, 15, 16, 17,
+ 17, 17, 17, 17, 16, 16, 15, 15, 14, 14, 13, 12, 10, 10, 9, 8,
+ 7, 6, 5, 5, 4, 3, 2, 1, 0, -2, -3, -4, -5, -6, -7, -8,
+ -9, -10, -11, -12, -13, -13, -14, -14, -14, -14, -14, -15, -15, -15, -15, -16,
+ -16, -14, -14, -12, -10, -13, -10, -13, -7, -3, -5, -1, -1, -5, -5, 8,
+ 13, 10, 10, 15, 16, 17, 30, 34, 19, 17, 22, 29, 27, 22, 16, 1,
+ -3, 8, 18, 11, 6, 8, 8, 1, 6, 18, 5, -8, -4, 4, 5, 3,
+ 5, -3, -6, 12, 30, 23, 9, 5, 6, 9, 15, 27, 20, 2, 0, 10,
+ 17, 8, -1, -4, -8, -8, -3, -7, -19, -28, -24, -22, -31, -42, -47, -50,
+ -50, -42, -35, -35, -43, -41, -31, -27, -23, -17, -9, -7, 3, 26, 37, 38,
+ 37, 41, 39, 39, 49, 55, 50, 46, 53, 58, 51, 44, 36, 24, 9, 5,
+ 2, -12, -25, -28, -26, -33, -42, -44, -55, -66, -69, -62, -60, -65, -57, -42,
+ -33, -26, -15, -5, -6, 0, 15, 29, 34, 41, 55, 61, 62, 68, 71, 62,
+ 49, 49, 49, 39, 29, 24, 14, -2, -10, -16, -34, -56, -67, -70, -77, -83,
+ -85, -88, -93, -92, -79, -74, -78, -74, -61, -49, -41, -23, -9, -2, 11, 35,
+ 54, 56, 58, 64, 69, 73, 81, 91, 86, 77, 78, 77, 67, 50, 39, 24,
+ 6, -4, -10, -22, -41, -49, -52, -62, -73, -81, -87, -98, -97, -83, -74, -70,
+ -63, -46, -33, -23, -6, 9, 18, 26, 48, 69, 77, 85, 97, 106, 107, 111,
+ 114, 104, 89, 83, 84, 75, 60, 50, 34, 13, -5, -16, -34, -59, -74, -80,
+ -86, -95, -97, -96, -104, -104, -95, -86, -86, -82, -66, -49, -32, -11, 12, 26,
+ 36, 55, 73, 81, 84, 94, 104, 107, 114, 120, 116, 102, 92, 88, 73, 54,
+ 37, 21, 0, -16, -23, -37, -58, -76, -85, -94, -108, -114, -116, -120, -119, -106,
+ -89, -84, -78, -64, -49, -37, -21, 1, 13, 25, 46, 71, 88, 95, 105, 113,
+ 112, 113, 116, 112, 97, 91, 91, 83, 68, 51, 35, 11, -10, -23, -38, -60,
+ -80, -86, -93, -102, -107, -110, -116, -121, -114, -102, -98, -93, -77, -55, -38, -18,
+ 1, 13, 25, 46, 71, 88, 95, 105, 113, 112, 113, 116, 112, 97, 91, 91,
+ 83, 68, 51, 35, 11, -10, -23, -38, -60, -80, -86, -93, -102, -107, -110, -116,
+ -121, -114, -102, -98, -93, -77, -55, -38, -18, 1, -3, -7, -8, -3, 1, 0,
+ 3, -5, -9, -14, -15, -4, 0, 7, 12, 12, 11, 18, 16, 14, 14, 11,
+ 20, 14, 19, 7, 12, 8, 13, 8, 7, 9, 0, 9, -7, -4, -5, -8,
+ -7, -9, -7, -2, -7, -4, 1, 1, 0, -2, 3, 2, 1, 2, 1, -2,
+ -3, -7, -2, -2, -2, -5, -4, -4, -4, 3, 6, 8, 3, 0, -3, -2,
+ 3, 4, 3, 2, 2, -2, 1, 0, 2, 3, 9, 8, 2, -3, -4, -2,
+ 1, 4, 0, -2, 3, 1, 7, 1, -4, 0, 2, 3, 1, 1, 2, -5,
+ 3, -3, -4, -3, -8, 2, -7, 1, -3, -2, -5, -8, -7, -8, -7, -5,
+ -7, -4, -8, -10, -7, -8, -7, -5, 0, -2, 0, -2, -3, -3, -2, 0,
+ 1, 0, 1, 0, -3, -3, -5, -5, -9, -9, -13, -16, -21, -26, -25, -25,
+ -16, -16, -12, -13, -15, -9, 3, 25, 44, 66, 68, 66, 49, 17, 13, 18,
+ 41, 51, 40, 35, 25, 23, -2, -16, -28, -8, -4, -12, -18, -34, -29, -31,
+ -28, -18, -4, 2, 16, 13, 20, 9, 4, 2, -3, -4, -9, -9, -9, -8,
+ -9, -10, -13, -14, -15, -13, -4, 7, 13, 19, 18, 16, 9, 7, 4, 6,
+ 8, 7, 7, 3, -3, -15, -19, -24, -21, -16, -9, 0, 3, 7, 4, 4,
+ -3, -2, 6, 13, 20, 14, 16, 14, 11, 7, 0, -4, -3, -3, -7, -12,
+ -12, -9, -5, -5, -7, -9, -4, -2, -2, -2, -4, -9, -10, -13, -13, -14,
+ -15, -13, -9, -8, -9, -9, -7, -4, 2, 2, 6, 9, 8, 11, 9, 11,
+ 9, 8, 6, 0, -7, -13, -21, -29, -36, -45, -53, -63, -72, -73, -61, -41,
+ 0, 52, 98, 109, 81, 64, 54, 78, 77, 45, 39, 44, 25, 19, 6, -8,
+ 25, 30, 44, 62, 46, -20, -85, -89, -88, -47, -29, -30, 2, 11, 8, 12,
+ 24, 33, 29, 25, 22, 1, -15, -34, -37, -36, -41, -36, -28, -15, 2, 9,
+ 11, 14, 12, 8, 12, 17, 18, 19, 23, 20, 20, 20, 8, -5, -14, -15,
+ -15, -13, -13, -18, -19, -24, -29, -32, -31, -23, -12, -2, 12, 20, 23, 24,
+ 25, 20, 22, 18, 16, 14, 9, 7, 2, 1, -9, -10, -19, -15, -12, -13,
+ -8, -5, -4, -4, -7, -10, -12, -12, -16, -14, -8, -9, -13, -14, -18, -15,
+ -10, -5, -3, 3, 4, 6, 11, 13, 13, 16, 16, 16, 12, 6, -3, -10,
+ -16, -21, -28, -37, -48, -61, -77, -88, -87, -68, -34, 28, 92, 127, 99, 64,
+ 50, 72, 92, 55, 43, 51, 41, 32, 4, -8, -7, -17, -23, -31, -33, -35,
+ -32, -28, -23, -18, -12, -8, -4, -2, 0, 1, 2, 2, 3, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 3, 4, 6, 7, 7, 7, 8, 9, 9, 8,
+ 8, 9, 11, 14, 18, 22, 27, 32, 33, 30, 21, 6, -12, -30, -45, -54,
+ -56, -51, -41, -29, -17, -9, -3, 0, 1, 1, 1, 1, 1, 1, 1, 2,
+ 2, 3, 3, 3, 3, 3, 2, 3, 4, 5, 8, 9, 10, 9, 8, 7,
+ 7, 8, 10, 15, 20, 25, 30, 35, 39, 39, 32, 19, 0, -22, -42, -56,
+ -62, -61, -53, -40, -27, -15, -7, -3, -1, 0, 0, 0, 0, 2, 3, 4,
+ 5, 5, 5, 4, 2, 0, -1, 0, 2, 5, 8, 9, 10, 10, 9, 9,
+ 8, 9, 10, 14, 19, 24, 28, 32, 34, 38, 36, 29, 17, -5, -28, -49,
+ -61, -65, -61, -52, -39, -25, -14, -7, -3, -2, -1, -2, -1, 0, 2, 4,
+ 6, 7, 7, 5, 3, 0, -1, -1, 0, 3, 7, 11, 13, 14, 13, 12,
+ 10, 8, 8, 9, 12, 17, 22, 26, 29, 31, 33, 31, 26, 18, 3, -16,
+ -35, -50, -59, -61, -56, -46, -35, -23, -14, -6, -2, 0, 1, 2, 3, 4,
+ 4, 5, 5, 5, 4, 2, 1, -1, -1, 0, 2, 5, 9, 12, 13, 13,
+ 12, 11, 9, 7, 7, 8, 11, 15, 20, 24, 29, 33, 35, 34, 30, 21,
+ 4, -16, -37, -55, -66, -68, -63, -50, -35, -21, -9, -1, 4, 5, 5, 4,
+ 4, 3, 3, 3, 3, 2, 2, 1, 0, -1, -1, 1, 6, 10, 13, 15,
+ 15, 13, 11, 8, 5, 4, 4, 7, 11, 17, 22, 27, 32, 36, 39, 39,
+ 36, 24, 6, -20, -48, -70, -81, -79, -67, -48, -29, -12, -1, 5, 7, 7,
+ 4, 2, 1, 1, 2, 2, 3, 2, 2, -1, -2, -3, -3, -1, 3, 8,
+ 13, 16, 17, 16, 12, 8, 3, -1, -3, -2, 2, 11, 21, 29, 36, 38,
+ 39, 42, 48, 57, 52, 23, -27, -76, -107, -113, -98, -71, -42, -18, -1, 8,
+ 12, 13, 10, 7, 3, 1, 1, 2, 3, 2, 1, 0, -2, -3, -3, -1,
+ 2, 8, 13, 17, 18, 17, 12, 7, 1, -3, -4, -3, 20, 30, 38, 41,
+ 39, 38, 46, 65, 75, 45, -23, -89, -126, -127, -101, -64, -31, -7, 5, 11,
+ 13, 14, 13, 9, 4, 1, 0, 1, 2, 1, -1, -3, -4, -4, -2, 2,
+ 6, 10, 14, 18, 18, 15, 9, 1, -6, -10, -13, -10, -4, 7, 20, 0,
+ 14, 19, 23, 26, 28, 28, 26, 23, 18, 11, 3, -4, -10, -16, -21, -23,
+ -24, -22, -20, -16, -12, -8, -3, 3, 8, 13, 19, 23, 26, 27, 26, 23,
+ 17, 10, 4, -3, -9, -15, -20, -24, -25, -25, -22, -17, -11, -3, 3, 9,
+ 14, 18, 20, 22, 23, 23, 21, 17, 13, 6, 1, -6, -11, -15, -18, -20,
+ -19, -19, -17, -16, -13, -11, -8, -5, -1, 2, 5, 7, 9, 9, 8, 6,
+ 3, 0, -3, -7, -10, -14, -17, -19, -19, -18, -16, -12, -7, -2, 3, 8,
+ 13, 16, 18, 19, 17, 14, 8, -1, -11, -21, -31, -38, -41, -40, -34, -25,
+ -12, 2, 17, 32, 45, 56, 62, 65, 63, 58, 49, 38, 25, 10, -6, -18,
+ -28, -37, -44, -51, -59, -64, -64, -56, -40, -17, 7, 29, 46, 56, 58, 59,
+ 56, 51, 45, 33, 19, 4, -13, -26, -39, -49, -56, -59, -55, -46, -34, -19,
+ -4, 10, 21, 30, 40, 46, 51, 52, 49, 43, 31, 18, 5, -8, -16, -21,
+ -23, -26, -29, -35, -39, -42, -40, -34, -22, -11, 2, 11, 18, 21, 24, 23,
+ 22, 19, 14, 7, -3, -13, -21, -30, -39, -46, -50, -52, -49, -42, -31, -17,
+ -3, 12, 26, 39, 49, 57, 60, 58, 51, 39, 22, 1, -23, -47, -68, -82,
+ -89, -88, -77, -60, -37, -11, 16, 43, 65, 83, 94, 100, 101, 96, 87, 71,
+ 51, 29, 4, -18, -38, -58, -75, -91, -104, -109, -105, -87, -61, -27, 8, 39,
+ 67, 87, 97, 97, 88, 71, 54, 36, 16, -2, -23, -42, -57, -70, -75, -75,
+ -71, -60, -43, -23, -1, 18, 31, 47, 57, 66, 71, 68, 61, 49, 32, 17,
+ 1, -11, -22, -33, -41, -47, -54, -59, -63, -62, -57, -46, -30, -12, 1, 17,
+ 30, 41, 49, 50, 47, 40, 29, 17, 3, -14, -30, -46, -60, -70, -76, -77,
+ -73, -63, -48, -28, -4, 20, 44, 65, 81, 91, 93, 88, 77, 60, 37, 11,
+ -19, -49, -76, -97, -109, -110, -100, -81, -56, -25, 7, 38, 67, 91, 109, 121,
+ 127, 126, 116, 96, 68, 38, 8, -18, -43, -68, -90, -110, -124, -127, -116, -91,
+ -59, -22, 14, 47, 77, 98, 107, 105, 93, 74, 54, 33, 13, -6, -26, -45,
+ -60, -71, -78, -79, -74, -61, -42, -21, 1, 18, 33, 49, 60, 68, 73, 70,
+ 62, 48, 32, 15, 0, -13, -24, -34, -42, -48, -55, -61, -65, -65, -60, -48,
+ -32, -15, 2, 19, 32, 43, 50, 51, 47, 40, 28, 16, 1, -14, 2, -2,
+ 2, -5, -3, -1, 0, -4, -4, -6, -4, -6, -4, -4, -7, -6, -7, -6,
+ -1, 0, 3, 13, 14, 16, 12, 13, 2, 1, 0, -1, -1, -1, -2, -2,
+ -2, -3, -3, -4, -8, -4, -4, -5, -5, -5, -7, -9, -12, -8, -14, -11,
+ -14, -18, -8, 1, 31, 71, 68, 24, -5, -11, -7, -5, -5, -5, -3, -2,
+ -5, -5, -9, -8, -7, -7, -9, -12, -11, -17, -14, -16, -15, -20, -26, -30,
+ -27, -15, 16, 51, 87, 101, 70, 8, -18, -11, -14, -7, -7, -1, -2, -5,
+ -7, -12, -14, -10, -10, -13, -14, -13, -16, -16, -17, -18, -35, -31, -30, -34,
+ -9, 16, 56, 84, 89, 60, 30, 5, -7, -5, -8, -3, -4, -4, -6, -12,
+ -14, -13, -10, -12, -12, -9, -10, -8, -12, -13, -15, -19, -23, -26, -33, -29,
+ -28, -9, 12, 43, 71, 88, 72, 48, 29, -2, -16, -19, -12, -12, -12, -7,
+ -11, -10, -10, -10, -11, -13, -15, -18, -19, -17, -16, -15, -13, -12, -13, -9,
+ -13, -17, -21, -18, 2, 34, 59, 87, 92, 98, 38, -30, -24, -27, -18, -16,
+ -11, -11, -13, -15, -12, -14, -15, -18, -17, -20, -18, -15, -10, -7, -3, -1,
+ 2, -8, -11, -22, -22, -20, 7, 31, 61, 97, 106, 43, -23, -28, -25, -20,
+ -12, -7, -5, -7, -10, -13, -13, -13, -11, -14, -15, -15, -12, -8, -7, -4,
+ -2, -4, -10, -15, -19, -26, -10, 12, 42, 72, 101, 90, 20, -25, -27, -22,
+ -18, -10, -6, -9, -11, -16, -17, -16, -14, -10, -8, -9, -9, -9, -9, -9,
+ -8, -5, -3, -6, -10, -17, -24, -21, 4, 30, 61, 84, 96, 79, -16, -38,
+ -27, -26, -17, -12, -8, -12, -13, -14, -14, -11, -8, -4, -4, -7, -9, -8,
+ -10, -12, -8, -5, -4, -7, -10, -18, -24, -11, 14, 42, 70, 79, 93, 36,
+ -32, -26, -28, -19, -15, -9, -9, -13, -16, -14, -12, -8, -5, -3, -7, -9,
+ -9, -9, -11, -8, -5, -1, -6, -9, -15, -24, -23, 6, 28, 63, 86, 127,
+ 37, -45, -27, -28, -26, -19, -4, -5, -8, -11, -12, -14, -12, -8, -4, -8,
+ -8, -10, -8, -13, -8, -8, -3, -8, -8, -16, -23, -17, 7, 34, 69, 83,
+ 113, 37, -50, -28, -25, -22, -16, 0, -3, -8, -12, -12, -14, -14, -10, -5,
+ -7, -6, -9, -9, -13, -9, -10, -7, -9, -9, -15, -20, -14, 8, 33, 64,
+ 81, 90, 57, -29, -28, 0, -4, 10, 10, 11, -15, 4, -1, 3, -11, 11,
+ 2, -12, 3, 18, -10, -62, 89, -16, -95, 118, -128, 122, -128, 112, -100, 109,
+ -121, 120, -104, 58, 10, -88, 127, -102, 6, 98, -126, 35, 89, -111, -7, 112,
+ -53, -94, 92, 64, -106, -53, 109, 52, -100, -75, 86, 95, -45, -119, -12, 111,
+ 74, -58, -118, -27, 97, 100, -4, -107, -95, 17, 109, 92, -4, -99, -109, -26,
+ 78, 115, 66, -27, -104, -109, -41, 55, 112, 98, 32, -53, -109, -105, -44, 41,
+ 102, 109, 67, -4, -74, -112, -102, -47, 27, 88, 112, 93, 45, -19, -78, -110,
+ -105, -65, -4, 59, 101, 110, 87, 43, -13, -67, -103, -111, -89, -44, 13, 65,
+ 100, 109, 93, 59, 14, -36, -78, -104, -108, -90, -53, -6, 43, 83, 104, 106,
+ 88, 57, 17, -27, -66, -95, -108, -102, -80, -44, -2, 41, 77, 99, 106, 98,
+ 77, 46, 10, -29, -64, -91, -105, -105, -91, -64, -29, 10, 48, 78, 98, 105,
+ 100, 84, 59, 30, -3, -36, -65, -88, -101, -105, -99, -83, -60, -32, -1, 30,
+ 58, 80, 96, 103, 102, 94, 80, 62, 40, 16, -10, -35, -58, -78, -92, -101,
+ -104, -100, -91, -77, -58, -36, -13, 12, 36, 57, 75, 89, 98, 102, 102, 97,
+ 88, 76, 61, 44, 25, 5, -15, -35, -54, -70, -84, -94, -101, -104, -103, -98,
+ -89, -77, -63, -46, -27, -8, 12, 31, 49, 65, 79, 90, 97, 102, 104, 102,
+ 97, 90, 81, 70, 57, 42, 27, 10, -7, -24, -40, -56, -70, -81, -91, -99,
+ -103, -105, -105, -101, -95, -87, -76, -63, -49, -34, -18, -1, 16, 32, 48, 62,
+ 74, 85, 93, 100, 104, 105, 105, 102, 97, 90, 82, 72, 61, 48, 35, 21,
+ 6, -9, -24, -38, -52, -65, -76, -86, -94, -101, -105, -108, -108, -106, -102, -96,
+ -87, -78, -66, -54, -40, -26, -11, 4, 19, 34, 48, 61, 73, 83, 92, 99,
+ 104, 107, 108, 108, 105, 101, 96, 89, 80, 70, 60, 48, 36, 22, 9, -5,
+ -19, -33, -46, -58, -69, -80, -89, -96, -102, -107, -109, -110, -110, -107, -102, -97,
+ -89, -80, -70, -59, -47, -33, -20, -6, 7, 19, 30, 41, 50, 58, 65, 71,
+ 75, 78, 79, 80, 79, 77, 74, 70, 65, 60, 54, 48, 42, 36, 29, 22,
+ 16, 10, 4, -2, -7, -12, -16, -19, -22, -24, -26, -27, -27, -27, -26, -25,
+ -23, -22, -19, -17, -14, -12, -10, -1, -1, -4, -9, -9, -7, -6, -7, -3,
+ 4, 8, 10, 11, 13, 10, 4, -3, -10, -15, -13, -9, -10, -11, -5, 4,
+ 12, 14, 12, 13, 14, 9, 1, -8, -15, -21, -23, -22, -13, -3, 7, 17,
+ 24, 27, 19, 11, 16, 15, -5, -24, -29, -23, -27, -32, -21, 5, 18, 20,
+ 21, 24, 24, 15, 11, 8, -6, -30, -31, -19, -17, -24, -14, 2, 17, 15,
+ 12, 17, 16, 19, 8, -5, -2, -1, -17, -17, -3, 6, 5, -4, 0, 1,
+ -12, -9, 9, 11, -4, -14, -8, 9, -2, -21, -14, 4, 9, 9, 11, 18,
+ 21, 10, 8, 16, 10, 26, 35, 6, -14, -28, -25, -24, -55, -65, -33, -17,
+ 1, -6, -6, 8, 23, 33, 49, 37, 19, 16, 11, 24, 42, 17, -37, -36,
+ 3, 7, -23, -36, -9, 9, -12, -20, -8, -2, -4, -23, -17, -6, 0, 10,
+ 24, 24, 40, 46, 33, 39, 26, 5, 6, 9, -12, -26, -33, -42, -61, -52,
+ -43, -37, -21, -4, 7, 13, 28, 36, 31, 24, 1, -1, 20, 24, 23, 21,
+ 26, 27, 8, -32, -44, -3, 28, -1, -36, -30, -6, 13, -12, -34, -18, -6,
+ 9, 21, 25, 16, 10, 38, 62, 46, 17, -11, -7, 10, -8, -44, -53, -33,
+ -35, -38, -29, -27, -16, 0, 1, 9, 37, 50, 36, 2, -20, -12, 15, 21,
+ 24, 32, 29, 20, 23, 12, -8, -3, 4, -10, -5, 2, -19, -63, -70, -21,
+ 20, 41, 23, 33, 57, 61, 42, 21, 15, 10, -45, -82, -60, -29, -44, -77,
+ -50, -7, 4, -4, 10, 32, 56, 42, 1, -10, -18, 2, 22, 28, 33, 42,
+ 47, 43, 47, 11, -23, 0, 10, -40, -81, -70, -28, -29, -68, -29, 19, 6,
+ 7, 21, 40, 41, 32, 22, 28, 47, 69, 66, 35, 21, 15, -3, -20, -34,
+ -24, -6, -19, -59, -47, -42, -35, -28, 15, 45, 51, 66, 78, 83, 37, 1,
+ 13, 7, -51, -81, -92, -83, -87, -74, -58, -73, -51, 12, 35, 26, 35, 47,
+ 69, 70, 63, 65, 49, 47, 68, 73, 52, 33, 15, -12, -30, -50, -51, -46,
+ -45, -60, -50, -50, -50, -54, -24, 38, 78, 90, 106, 99, 40, -6, -11, -46,
+ -110, -127, -107, -76, -67, -53, -41, -41, -23, 14, 33, 27, 34, 49, 70, 71,
+ 66, 65, 51, 51, 69, 72, 52, 32, 10, -12, 0, -5, -2, -5, 2, -29,
+ 22, 0, -27, 67, -59, 45, -13, -37, 28, 65, -4, 6, 60, 5, 58, 44,
+ 60, 27, 43, 96, 71, 81, 48, 96, 70, 23, 90, 66, 80, 88, 40, 20,
+ 61, 64, 12, 36, 24, 4, 7, 5, -27, -38, -26, -33, -49, -50, -70, -69,
+ -93, -92, -94, -104, -104, -101, -110, -107, -111, -111, -126, -87, -119, -100, -94, -112,
+ -93, -93, -80, -81, -76, -58, -56, -70, -30, -21, -42, -13, -3, 2, 8, 20,
+ 28, 41, 45, 59, 62, 69, 84, 85, 90, 103, 109, 111, 118, 121, 121, 123,
+ 121, 122, 121, 122, 121, 122, 121, 121, 120, 121, 120, 121, 120, 121, 120, 120,
+ 119, 120, 119, 120, 118, 105, 106, 110, 83, 89, 92, 75, 67, 61, 57, 47,
+ 40, 33, 24, 17, 10, 3, -2, -10, -20, -31, -31, -37, -49, -50, -63, -66,
+ -69, -74, -79, -91, -89, -92, -95, -102, -106, -104, -107, -113, -113, -110, -113, -116,
+ -114, -115, -114, -115, -114, -113, -114, -113, -114, -113, -112, -113, -109, -105, -111, -106,
+ -107, -103, -100, -103, -99, -97, -98, -99, -92, -92, -93, -92, -92, -90, -88, -90,
+ -88, -86, -89, -85, -85, -87, -85, -85, -82, -83, -82, -80, -78, -79, -76, -74,
+ -73, -73, -69, -68, -66, -64, -65, -62, -58, -56, -56, -52, -50, -47, -43, -42,
+ -39, -35, -33, -31, -27, -23, -21, -16, -16, -8, -7, -3, 1, 0, 10, 15,
+ 15, 19, 26, 29, 30, 38, 41, 42, 47, 54, 54, 57, 63, 68, 69, 72,
+ 77, 78, 80, 85, 84, 86, 87, 86, 87, 86, 85, 86, 85, 84, 85, 84,
+ 83, 84, 83, 82, 82, 83, 82, 81, 82, 81, 80, 81, 80, 79, 80, 79,
+ 79, 78, 79, 78, 78, 77, 74, 70, 66, 64, 61, 55, 52, 49, 45, 40,
+ 35, 32, 29, 24, 19, 15, 12, 8, 4, 0, -4, -8, -11, -15, -17, -20,
+ -25, -26, -29, -32, -34, -37, -39, -41, -43, -45, -46, -48, -49, -50, -50, -52,
+ -52, -53, -52, -53, -54, -53, -53, -52, -52, -51, -50, -50, -49, -48, -48, -46,
+ -45, -44, -42, -41, -40, -39, -37, -35, -34, -32, -30, -28, -27, -24, -23, -22,
+ -20, -19, -17, -15, -14, -13, -12, -10, -9, -8, -8, -6, -6, -5, -4, -4,
+ -3, -3, -2, -2, -1, -2, -1, -2, -1, -1, 0, -1, -1, 1, 0, 0,
+ -3, -1, 1, -4, -4, -3, -2, -5, -3, 0, -1, -1, -3, -1, 0, 2,
+ 0, -2, -5, 5, 4, 1, 7, 2, 2, 1, 8, 1, 6, 2, -4, 2,
+ 1, -4, 6, -8, -3, -7, -2, -6, -1, -9, 1, -2, -4, 1, 2, 1,
+ -2, 8, 2, 0, 14, 9, 10, 5, 3, 5, 6, 4, 3, -8, -2, -4,
+ -10, -1, -5, -3, -4, -6, -13, -5, -4, -4, -3, 2, -13, -6, 3, 6,
+ 6, 7, 1, 1, 6, 6, 16, 13, 9, 10, 9, 2, 7, 10, 4, -4,
+ -3, -17, -7, -6, -6, -10, -17, -17, -10, -11, -9, -5, -6, -8, 2, 1,
+ 8, 19, 15, 18, 24, 19, 16, 17, 19, 11, 7, 1, -5, -8, -9, -15,
+ -8, -9, -14, -20, -19, -9, -18, -10, -13, -23, -13, -12, -7, 0, -1, 5,
+ 16, 12, 28, 30, 32, 34, 34, 19, 24, 23, 16, 11, 5, -7, -19, -17,
+ -16, -21, -26, -23, -32, -31, -30, -25, -26, -24, -19, -13, -9, -1, 0, 4,
+ 6, 13, 15, 19, 17, 13, 8, 8, 8, 7, 0, -4, -8, -10, -7, -5,
+ -6, -6, -9, -12, -8, -10, -9, -9, -11, -13, -12, -9, -4, -1, 4, 9,
+ 19, 27, 31, 26, 16, 14, 16, 16, 12, 1, -8, -14, -11, -9, -6, -11,
+ -11, -12, -14, -10, -11, -13, -15, -19, -23, -19, -14, -8, -5, -1, 8, 34,
+ 62, 59, 12, 14, 32, 22, 6, 20, 6, -9, -54, -16, -1, -19, 7, -15,
+ -13, -12, -14, -15, -14, -22, -24, -30, -30, -20, -12, -6, 3, 26, 66, 88,
+ 39, 0, 47, 36, -2, 26, -23, 21, 13, -6, -60, -42, 6, -22, 4, -18,
+ -16, -4, -16, -19, -24, -39, -31, -25, -32, -26, -11, 12, 55, 104, 75, 10,
+ 35, 62, 9, 26, -16, -8, 19, 3, -9, -61, -46, 2, -26, -7, -16, -10,
+ 2, -7, -22, -23, -38, -40, -37, -44, -33, -8, 37, 101, 124, 36, -5, 89,
+ 20, 38, 5, -26, 3, 1, 5, -28, -65, -21, 1, -22, -12, -26, 1, -7,
+ -10, -24, -26, -33, -37, -48, -50, -36, 5, 63, 122, 109, 7, 35, 84, 5,
+ 59, -36, -4, -11, -1, -5, -40, -55, -4, -15, -21, -16, -22, 5, -10, -17,
+ -20, -27, -23, -44, -54, -62, -23, 29, 114, 127, 51, 7, -2, -4, -2, 4,
+ 11, 14, 10, 2, -7, -9, -9, -15, -16, -7, 3, 2, -10, -21, -17, 6,
+ 10, -8, -28, -11, 45, 66, 64, 47, 36, 49, 49, 27, 9, -12, -18, -25,
+ -30, -11, 0, -5, 0, -1, -18, -36, -33, -18, -10, -13, -31, -26, -25, -17,
+ 4, 28, 70, 89, 48, 9, -32, -58, -56, -70, -57, -17, -38, -48, -35, -32,
+ -7, 35, 38, 53, 62, 44, 33, 27, -6, -35, -52, -65, -54, -40, -43, -30,
+ -25, 2, 63, 54, 34, 17, 34, 70, 60, 8, -15, -3, 0, 39, 55, 35,
+ 39, 60, 75, 36, 20, -7, -25, -66, -110, -89, -89, -71, -36, -12, 9, 31,
+ 41, 54, 46, 45, 59, 41, 22, 3, -69, -110, -126, -116, -64, -15, 9, 29,
+ 33, 30, 56, 42, 12, 23, 6, -27, -36, -21, -22, -32, -21, -30, -29, -5,
+ 9, 16, 22, -9, -12, 31, 24, -17, -41, -23, 32, 32, 26, 34, 64, 66,
+ 109, 104, 51, 5, 12, 16, -36, -58, -59, -66, -63, -82, -64, -23, -9, 11,
+ 16, 20, 19, 13, 12, 33, 37, 41, 46, 28, 7, -58, -93, -79, -64, -33,
+ -1, 22, -4, 2, 19, 4, -7, -3, -3, 5, 1, -10, -3, 12, -6, -38,
+ -29, -17, -5, 11, 2, -33, -20, 44, 42, 20, -30, -24, 9, 44, 38, 20,
+ 36, 71, 61, 86, 72, 25, -8, 10, 17, -35, -54, -63, -67, -70, -78, -58,
+ -16, -7, 19, 22, 20, 21, 29, 21, 16, 35, 36, 16, -8, -27, -61, -58,
+ -67, -43, 3, 35, 38, -2, -2, 10, -9, -29, -14, -5, -1, -5, 2, 12,
+ -6, -32, -23, -22, -16, -5, 3, -9, -29, 27, 56, 39, 11, -27, -28, 23,
+ 34, 28, 18, 20, 62, 82, 71, 74, 24, -4, 16, 18, -39, -54, -65, -61,
+ -52, -64, -49, -11, -4, 12, 17, 16, 25, 24, 6, 23, 36, 18, 18, -1,
+ -42, -50, -90, -43, 3, 35, 38, -2, -2, 10, -9, -29, -14, -5, -1, -5,
+ 2, 12, -6, -32, -23, -22, -16, -5, 3, -9, -29, 27, 56, 39, 11, -27,
+ -28, 23, 34, 28, 18, 20, 62, 82, 71, 74, 24, -4, 16, 18, -39, -54,
+ -65, -61, -52, -64, -49, -11, -4, 12, 17, 16, 25, 24, 6, 23, 36, 18,
+ 18, -1, -42, -50, -90, -43, 0, 1, 6, -11, 19, -25, 24, -15, 11, -6,
+ 1, 9, -6, -3, 11, -18, 28, -23, 8, 6, -2, -1, 0, -5, 18, -23,
+ 24, -28, 27, -12, -1, -2, 6, 4, -14, 19, -29, 42, -40, 22, -6, -3,
+ 14, -16, 4, 8, -9, 13, -22, 17, 5, -24, 37, -34, 20, -4, -11, 19,
+ -20, 21, -16, 1, 17, -17, 5, -9, 25, -31, 31, -40, 32, -11, -7, 4,
+ -4, 13, -23, 29, -40, 51, -49, 20, 3, -20, 38, -47, 34, -21, 14, -9,
+ 4, -13, 20, -29, 37, -57, 59, -48, 23, -5, -7, 5, -6, -5, 13, -17,
+ 9, -4, -12, 22, -19, -8, 10, -5, -7, 8, -18, 19, -13, 5, -12, 6,
+ -10, 18, -40, 66, -91, 82, -56, 17, 19, -51, 56, -45, 30, -19, 5, -6,
+ 7, -9, -4, -2, -5, 13, -19, 1, 20, -28, 13, -6, 0, -17, 33, -48,
+ 38, -16, -20, 53, -75, 75, -61, 30, -12, -9, 2, 5, -9, -7, 15, -17,
+ 9, 4, -46, 70, -85, 86, -67, 29, 18, -60, 76, -70, 29, -8, -1, 1,
+ 14, -58, 93, -118, 127, -125, 85, -36, -2, 17, -39, 46, -61, 70, -99, 122,
+ -120, 56, 15, -85, 116, -101, 30, 43, -108, 127, -122, 72, -38, -3, 20, -31,
+ 29, -37, 42, -50, 63, -72, 40, -7, -46, 66, -82, 53, -25, 1, 1, -1,
+ -3, 3, -24, 24, -34, 27, -24, 36, -49, 37, -38, 35, -42, 13, -4, -14,
+ 14, -29, 42, -58, 58, -60, 41, -39, 27, -35, 27, -32, 25, -37, 43, -50,
+ 32, -20, -4, 4, -14, 16, -43, 66, -93, 79, -58, 27, -11, -21, 34, -40,
+ 24, -7, -25, 31, -29, 19, -18, -2, 1, -6, 4, -31, 47, -63, 62, -64,
+ 32, 2, -29, 23, -21, 19, -41, 59, -76, 62, -52, 26, -11, -1, -10, 6,
+ -10, -7, 17, -42, 34, -12, -34, 73, -106, 92, -61, 26, -24, 8, -7, -2,
+ 3, -24, 31, -44, 27, -9, -22, 38, -43, 15, -4, -3, -2, -12, 5, 1,
+ -7, 7, -25, 17, -17, 4, -15, 27, -40, 34, -18, 6, -13, 12, -3, -9,
+ -6, 8, -18, 18, -36, 54, -55, 30, -25, 26, -41, 38, -49, 48, -38, 8,
+ 16, -40, 47, -52, 34, -12, -4, 2, -13, 0, 1, 6, -11, 19, -25, 24,
+ -15, 11, -6, 1, 9, -6, -3, 11, -18, 28, -23, 8, 6, -2, -1, 0,
+ -5, 18, -23, 24, -28, 27, -12, -1, -2, 6, 4, -14, 19, -29, 42, -40,
+ 22, -6, -3, 14, -16, 4, 8, -9, 13, -22, 17, 5, -24, 37, -34, 20,
+ -4, -11, 19, -20, 21, -16, 1, 17, -17, 5, -9, 25, -31, 31, -40, 32,
+ -11, -7, 4, -4, 13, -23, 29, -40, 51, -49, 20, 3, -20, 38, -47, 34,
+ -21, 14, -9, 4, -13, 20, -29, 37, -57, 59, -48, 23, -5, -7, 5, -6,
+ -5, 13, -17, 9, -4, -12, 22, -19, -8, 10, -5, -7, 8, -18, 19, -13,
+ 5, -12, 6, -10, 18, -40, 66, -91, 82, -56, 17, 19, -51, 56, -45, 30,
+ -19, 5, -6, 7, -9, -4, -2, -5, 13, -19, 1, 20, -28, 13, -6, 0,
+ -17, 33, -48, 38, -16, -20, 53, -75, 75, -61, 30, -12, -9, 2, 5, -9,
+ -7, 15, -17, 9, 4, -46, 70, -85, 86, -67, 29, 18, -60, 76, -70, 29,
+ -8, -1, 1, 14, -58, 93, -118, 127, -125, 85, -36, -2, 17, -39, 46, -61,
+ 70, -99, 122, -120, 56, 15, -85, 116, -101, 30, 43, -108, 127, -122, 72, -38,
+ -3, 20, -31, 29, -37, 42, -50, 63, -72, 40, -7, -46, 66, -82, 53, -25,
+ 1, 1, -1, -3, 3, -24, 24, -34, 27, -24, 36, -49, 37, -38, 35, -42,
+ 13, -4, -14, 14, -29, 42, -58, 58, -60, 41, -39, 27, -35, 27, -32, 25,
+ -37, 43, -50, 32, -20, -4, 4, -14, 16, -43, 66, -93, 79, -58, 27, -11,
+ -21, 34, -40, 24, -7, -25, 31, -29, 19, -18, -2, 1, -6, 4, -31, 47,
+ -63, 62, -64, 32, 2, -29, 23, -21, 19, -41, 59, -76, 62, -52, 26, -11,
+ -1, -10, 6, -10, -7, 17, -42, 34, -12, -34, 73, -106, 92, -61, 26, -24,
+ 8, -7, -2, 3, -24, 31, -44, 27, -9, -22, 38, -43, 15, -4, -3, -2,
+ -12, 5, 1, -7, 7, -25, 17, -17, 4, -15, 27, -40, 34, -18, 6, -13,
+ 12, -3, -9, -6, 8, -18, 18, -36, 54, -55, 30, -25, 26, -41, 38, -49,
+ 48, -38, 8, 16, -40, 47, -52, 34, -12, -4, 2, -13, -1, -2, -1, -4,
+ -3, -25, -41, 8, 16, 27, 2, 16, 1, 13, 21, -8, -6, -29, 17, 8,
+ 8, 20, -13, 5, 4, 25, 17, 30, 22, 14, 15, 19, 7, 51, -16, -15,
+ -32, -13, 12, -8, -17, -49, -27, -29, -29, -52, -66, -55, -32, -20, -41, -21,
+ -36, -11, -16, 22, 3, 19, 0, -6, -10, 0, -38, -17, -35, -19, -27, 0,
+ -35, -27, -9, -17, -14, -2, 20, 50, 63, 57, 49, 70, 70, 97, 81, 68,
+ 52, 78, 93, 98, 102, 56, 34, 20, 53, 60, 45, 24, -18, 21, -10, 0,
+ -38, -79, -38, -37, -13, -27, -41, -50, -51, 14, 10, 16, -21, -13, -22, -20,
+ -48, -53, -55, -66, -76, -65, -91, -105, -92, -87, -101, -79, -56, -34, -7, -4,
+ 7, 20, 15, 26, 29, 32, -8, 36, 47, 50, 66, 29, 18, -33, -11, -4,
+ -10, -24, -42, -31, -22, 2, -23, -75, -34, -36, 5, 1, 1, -17, -47, 20,
+ 43, 68, 28, 30, 9, 29, 7, -9, -5, -32, -46, -36, -15, -40, -35, -15,
+ -26, -21, 2, 21, 49, 62, 83, 87, 106, 77, 97, 94, 67, 60, 85, 79,
+ 110, 80, 61, 1, 8, 16, 50, 36, 2, -22, 4, -2, 21, -35, -33, -19,
+ 4, 24, 19, 10, -58, -23, 18, 45, 34, 8, -12, -6, -5, -48, -51, -75,
+ -72, -77, -37, -65, -80, -57, -66, -68, -38, -38, 2, 10, 38, 31, 58, 22,
+ 39, 37, 27, -9, 23, 9, 35, 18, 15, -31, -50, -44, -5, 6, -10, -63,
+ -41, -56, -15, -41, -71, -45, -37, 7, -6, 5, -56, -71, -6, 21, 41, 8,
+ -13, -14, -40, -30, -41, -40, -56, -31, -31, -9, -15, -5, 10, 42, 27, 73,
+ 82, 73, 73, 79, 70, 38, 28, 31, 23, 45, 42, 44, 30, -40, 8, 28,
+ 52, 30, -18, -29, -40, -14, -45, -50, -55, -68, -39, -6, -29, -45, -59, -32,
+ 4, 31, 23, 16, 20, 11, -1, 1, -28, -45, -53, -56, -67, -60, -55, -40,
+ -31, -25, -16, 11, 20, 36, 67, 70, 75, 77, 81, 65, 46, 38, 34, 39,
+ 51, 44, 57, 7, -4, 13, 37, 46, 19, -8, -29, -1, -9, -21, -32, -43,
+ -55, -58, -40, -8, 15, 29, 38, 44, 59, 63, 51, 20, -20, -47, -61, -58,
+ -48, -42, -43, -35, -15, 15, 41, 55, 61, 62, 70, 67, 45, 11, -31, -62,
+ -80, -78, -71, -62, -54, -39, -15, 18, 50, 68, 79, 83, 92, 88, 57, 16,
+ -31, -71, -94, -95, -90, -83, -71, -55, -28, 7, 49, 77, 93, 100, 109, 107,
+ 78, 36, -20, -71, -99, -104, -100, -92, -83, -69, -43, -5, 42, 79, 100, 108,
+ 114, 112, 90, 51, -9, -65, -100, -110, -105, -95, -87, -76, -52, -11, 35, 75,
+ 100, 107, 111, 106, 90, 52, -4, -60, -97, -109, -99, -87, -80, -65, -35, 5,
+ 43, 75, 91, 95, 93, 87, 71, 31, -19, -64, -93, -99, -88, -76, -66, -44,
+ -9, 28, 59, 79, 84, 80, 71, 59, 35, -5, -45, -76, -96, -95, -77, -59,
+ -39, -9, 28, 61, 86, 98, 93, 74, 52, 28, -6, -43, -72, -94, -108, -99,
+ -77, -52, -20, 19, 56, 84, 106, 115, 106, 79, 45, 3, -40, -74, -93, -108,
+ -112, -100, -79, -46, -1, 45, 78, 100, 113, 118, 108, 81, 39, -19, -67, -93,
+ -103, -108, -104, -94, -74, -32, 19, 61, 88, 102, 108, 109, 100, 73, 21, -44,
+ -87, -102, -104, -97, -90, -78, -49, 0, 46, 78, 90, 92, 89, 87, 77, 43,
+ -15, -72, -101, -104, -93, -79, -69, -47, -3, 47, 84, 96, 89, 74, 65, 58,
+ 37, -7, -61, -99, -110, -101, -82, -62, -38, 2, 49, 92, 112, 106, 82, 59,
+ 41, 18, -19, -61, -95, -111, -110, -98, -74, -39, 6, 54, 99, 122, 123, 104,
+ 79, 50, 12, -32, -72, -100, -111, -110, -106, -90, -54, -4, 49, 99, 123, 126,
+ 113, 95, 69, 24, -27, -72, -102, -114, -109, -104, -94, -64, -16, 36, 87, 116,
+ 121, 111, 97, 76, 36, -15, -61, -94, -110, -108, -98, -86, -60, -19, 29, 77,
+ 104, 109, 99, 86, 67, 35, -7, -47, -82, -98, -101, -92, -77, -48, -14, 25,
+ 67, 92, 95, 83, 66, 45, 18, -9, -37, -62, -77, -81, -78, -54, -16, 0,
+ 0, 0, 12, -10, 16, -14, -18, 17, -31, -2, 3, -19, -8, 17, 28, 37,
+ 31, -1, -25, -16, -47, -13, -43, -22, 6, 34, 41, 49, 41, 27, 6, -33,
+ -62, -54, -59, -32, -13, 29, 53, 73, 60, 54, 16, -19, -58, -77, -89, -42,
+ -46, 17, 55, 78, 86, 81, 33, -3, -35, -84, -110, -75, -70, 0, 39, 78,
+ 92, 105, 70, 13, -15, -82, -107, -103, -84, -41, 20, 81, 85, 127, 86, 39,
+ -4, -63, -103, -99, -107, -69, 2, 68, 82, 127, 84, 58, 28, -44, -88, -104,
+ -108, -83, -13, 29, 69, 116, 87, 77, 40, -16, -65, -89, -104, -89, -40, -1,
+ 47, 96, 90, 85, 52, 9, -38, -62, -96, -95, -62, -22, 21, 73, 78, 86,
+ 65, 35, -15, -41, -80, -92, -69, -48, 1, 43, 65, 80, 73, 49, 8, -23,
+ -59, -75, -74, -60, -22, 17, 49, 69, 65, 60, 25, -1, -36, -59, -70, -61,
+ -40, -9, 30, 52, 57, 63, 37, 17, -12, -41, -61, -57, -50, -30, 9, 30,
+ 49, 60, 47, 28, 6, -20, -49, -51, -53, -42, -11, 13, 34, 53, 50, 34,
+ 18, -3, -35, -39, -52, -49, -23, 0, 18, 41, 47, 36, 31, 10, -21, -28,
+ -43, -49, -31, -13, 2, 28, 39, 35, 38, 19, -7, -18, -33, -42, -36, -26,
+ -12, 19, 30, 34, 36, 22, 6, -5, -25, -38, -36, -29, -17, 8, 19, 26,
+ 35, 28, 12, 3, -17, -30, -29, -29, -22, -3, 9, 19, 33, 26, 14, 8,
+ -9, -18, -22, -28, -25, -9, 3, 15, 22, 20, 18, 12, 1, -11, -22, -24,
+ -21, -13, -3, 8, 11, 20, 21, 12, 5, -6, -19, -16, -17, -17, -7, 3,
+ 8, 20, 17, 7, 7, -2, -11, -13, -16, -17, -5, 2, 5, 12, 13, 8,
+ 6, 3, -9, -11, -9, -14, -5, 1, -3, 6, 11, 6, 7, 2, -6, -4,
+ -4, -10, -6, -3, -4, 5, 8, 2, 5, 4, -2, 0, -3, -9, -4, -3,
+ -3, 2, 3, 0, 6, 4, 0, -1, -2, -2, 0, 0, 0, 12, -10, 16,
+ -14, -18, 17, -31, -2, 3, -19, -8, 17, 28, 37, 31, -1, -25, -16, -47,
+ -13, -43, -22, 6, 34, 41, 49, 41, 27, 6, -33, -62, -54, -59, -32, -13,
+ 29, 53, 73, 60, 54, 16, -19, -58, -77, -89, -42, -46, 17, 55, 78, 86,
+ 81, 33, -3, -35, -84, -110, -75, -70, 0, 39, 78, 92, 105, 70, 13, -15,
+ -82, -107, -103, -84, -41, 20, 81, 85, 127, 86, 39, -4, -63, -103, -99, -107,
+ -69, 2, 68, 82, 127, 84, 58, 28, -44, -88, -104, -108, -83, -13, 29, 69,
+ 116, 87, 77, 40, -16, -65, -89, -104, -89, -40, -1, 47, 96, 90, 85, 52,
+ 9, -38, -62, -96, -95, -62, -22, 21, 73, 78, 86, 65, 35, -15, -41, -80,
+ -92, -69, -48, 1, 43, 65, 80, 73, 49, 8, -23, -59, -75, -74, -60, -22,
+ 17, 49, 69, 65, 60, 25, -1, -36, -59, -70, -61, -40, -9, 30, 52, 57,
+ 63, 37, 17, -12, -41, -61, -57, -50, -30, 9, 30, 49, 60, 47, 28, 6,
+ -20, -49, -51, -53, -42, -11, 13, 34, 53, 50, 34, 18, -3, -35, -39, -52,
+ -49, -23, 0, 18, 41, 47, 36, 31, 10, -21, -28, -43, -49, -31, -13, 2,
+ 28, 39, 35, 38, 19, -7, -18, -33, -42, -36, -26, -12, 19, 30, 34, 36,
+ 22, 6, -5, -25, -38, -36, -29, -17, 8, 19, 26, 35, 28, 12, 3, -17,
+ -30, -29, -29, -22, -3, 9, 19, 33, 26, 14, 8, -9, -18, -22, -28, -25,
+ -9, 3, 15, 22, 20, 18, 12, 1, -11, -22, -24, -21, -13, -3, 8, 11,
+ 20, 21, 12, 5, -6, -19, -16, -17, -17, -7, 3, 8, 20, 17, 7, 7,
+ -2, -11, -13, -16, -17, -5, 2, 5, 12, 13, 8, 6, 3, -9, -11, -9,
+ -14, -5, 1, -3, 6, 11, 6, 7, 2, -6, -4, -4, -10, -6, -3, -4,
+ 5, 8, 2, 5, 4, -2, 0, -3, -9, -4, -3, -3, 2, 3, 0, 6,
+ 4, 0, -1, -2, -2, 0, -1, -1, -3, -7, -14, -23, -32, -45, -55, -66,
+ -74, -83, -88, -80, -77, -71, -64, -54, -46, -37, -31, -25, -19, -12, -6, -1,
+ 4, 8, 12, 17, 21, 23, 25, 25, 27, 29, 32, 35, 36, 34, 32, 31,
+ 32, 35, 37, 37, 35, 31, 29, 29, 31, 33, 34, 32, 29, 26, 25, 27,
+ 30, 32, 31, 29, 27, 27, 29, 31, 34, 35, 35, 35, 36, 38, 41, 43,
+ 45, 47, 49, 52, 55, 57, 59, 61, 63, 66, 69, 70, 70, 68, 66, 63,
+ 61, 58, 54, 47, 36, 24, 11, 1, -9, -20, -33, -48, -64, -78, -89, -97,
+ -103, -110, -116, -123, -128, -128, -126, -121, -116, -112, -107, -102, -95, -88, -78, -69,
+ -61, -54, -47, -41, -34, -27, -21, -16, -12, -7, -2, 2, 5, 6, 8, 10,
+ 13, 16, 19, 19, 19, 17, 18, 19, 22, 24, 24, 22, 19, 18, 19, 21,
+ 23, 24, 22, 19, 17, 18, 20, 22, 24, 24, 22, 21, 22, 24, 27, 29,
+ 30, 30, 31, 32, 35, 37, 40, 42, 45, 47, 50, 53, 56, 58, 60, 62,
+ 66, 68, 70, 69, 68, 65, 63, 61, 59, 54, 46, 36, 24, 13, -1, -14,
+ -28, -43, -57, -68, -78, -86, -94, -102, -109, -114, -117, -117, -115, -112, -109, -106,
+ -101, -96, -89, -81, -73, -67, -59, -53, -46, -40, -34, -28, -23, -18, -13, -9,
+ -5, -2, 0, 2, 5, 7, 10, 12, 14, 15, 15, 15, 16, 18, 19, 20,
+ 20, 19, 18, 18, 19, 21, 22, 22, 21, 20, 19, 21, 23, 24, 25, 25,
+ 25, 25, 26, 29, 31, 33, 34, 35, 36, 38, 40, 43, 46, 48, 51, 53,
+ 56, 59, 62, 65, 68, 71, 74, 77, 78, 79, 78, 77, 76, 74, 71, 66,
+ 58, 49, 39, 28, 17, 6, -6, -20, -35, -50, -64, -75, -85, -94, -102, -110,
+ -117, -122, -124, -123, -121, -118, -114, -110, -106, -99, -92, -84, -76, -69, -61, -55,
+ -48, -41, -34, -29, -23, -18, -13, -9, -5, -2, 0, -1, -1, 0, 2, 0,
+ 3, 2, 2, 4, 5, 4, 4, 4, 4, 5, 3, 4, 3, 1, 2, 0,
+ 0, -1, -3, -4, -2, -3, -5, -3, -4, -5, -5, -4, -3, -3, -6, -5,
+ -4, -2, -5, -5, -2, -3, -3, -3, 1, 4, 4, 8, 8, 8, 13, 12,
+ 13, 14, 12, 9, 8, 6, 6, 3, -2, -2, -5, -5, -4, -5, -11, -16,
+ -12, -7, -3, -5, -10, -11, -6, -2, -2, -1, -4, -6, -6, -7, -8, -5,
+ -2, 2, 5, 6, 8, 8, 9, 13, 16, 16, 14, 11, 7, 5, 4, 2,
+ 0, -2, -3, -3, 0, -3, -13, -28, -11, 7, -1, -15, -1, -5, -18, -10,
+ 6, 11, -11, -1, -10, -14, -13, -13, -4, 4, 6, 14, 13, 10, 10, 15,
+ 17, 24, 24, 13, 12, 10, 1, 0, 2, -4, 0, -6, 2, 7, -22, -68,
+ 2, 35, -40, 14, -24, -3, -10, -9, -20, -3, 28, 2, -9, -12, -28, -19,
+ -4, -1, 15, 17, 17, 16, 12, 16, 22, 25, 28, 6, 17, 9, -1, -2,
+ -3, 2, 12, -6, 6, -5, -35, -89, 32, 28, -39, 20, -36, 9, -20, -9,
+ -34, 3, 34, 8, -16, -11, -37, -15, -3, 0, 26, 18, 13, 15, 13, 25,
+ 27, 29, 20, 3, 21, 2, -2, 0, -8, 11, 16, -1, 8, -21, -76, -81,
+ 87, -25, 4, -4, -23, 6, -26, -20, -35, 23, 28, 0, -18, -16, -43, 2,
+ -9, 17, 25, 15, 9, 18, 17, 37, 28, 35, 3, 14, 12, -5, -1, -1,
+ -5, 27, 0, 16, -11, -49, -128, 36, 40, -36, 35, -41, 21, -27, -14, -45,
+ 4, 24, 20, -23, -6, -41, -9, -1, 6, 23, 19, 5, 15, 14, 33, 35,
+ 40, 16, 5, 16, -3, -5, 4, -12, 24, 10, 18, 1, -38, -128, -21, 72,
+ -50, 42, -38, 19, -16, -16, -43, -10, 21, 24, -22, -11, -30, -15, 6, 4,
+ 22, 18, 6, 11, 13, 27, 39, 42, 22, 4, -3, -2, -2, -5, -3, -5,
+ -3, -2, -6, -5, -5, -6, -5, -3, -5, -3, -5, -4, -6, -3, -1, -2,
+ -1, 0, -2, 1, 2, 1, 4, 4, 5, 5, 5, 8, 10, 11, 9, 10,
+ 11, 8, 5, 10, 7, 5, 5, 0, -3, 1, 0, -5, -2, -8, -9, -7,
+ -7, -5, -9, -11, -9, -8, -8, -7, -9, -7, -6, -7, -5, -6, -5, -3,
+ -3, -3, -4, -4, -2, 0, 1, 2, 5, 9, 12, 16, 19, 22, 22, 24,
+ 22, 22, 19, 13, 11, 7, 7, 4, -2, -7, -9, -9, -8, -10, -14, -14,
+ -15, -15, -13, -14, -17, -18, -14, -12, -12, -8, -9, -7, -6, -6, -6, -8,
+ -9, -9, -11, -13, -11, -6, -1, 3, 9, 20, 27, 33, 37, 46, 46, 42,
+ 37, 28, 21, 14, 11, 10, 14, 20, -2, -40, -47, -22, -5, -4, -1, 4,
+ -15, -53, -56, -7, -33, -14, -2, -19, -7, -8, -15, -6, -9, -8, -3, -9,
+ -15, -18, -26, -19, -6, -5, -6, 0, 12, 22, 29, 30, 28, 32, 29, 21,
+ 15, 13, 5, 5, 3, 19, 30, 3, -68, -26, 2, -17, 17, -12, 15, -1,
+ -12, -48, -43, -19, -1, 3, 6, -8, -4, -10, -10, -4, 0, -6, -1, -7,
+ -9, -17, -12, -6, -9, -14, -5, 14, 33, 33, 41, 32, 41, 35, 20, 10,
+ 8, 4, 10, -2, 36, 40, 3, -110, -8, -7, -6, 16, -18, 27, -2, -4,
+ -56, -57, -33, 16, -2, 12, -11, -5, -17, -9, -5, 10, -6, 0, -12, -11,
+ -20, -10, -8, -12, -17, -3, 17, 38, 34, 45, 36, 51, 37, 18, 4, -3,
+ 3, 8, 8, 54, 48, -34, -128, 28, -33, 28, -13, 1, 21, 3, -20, -59,
+ -65, -10, 17, -1, 7, -17, -10, -19, -8, 5, 11, -4, -2, -16, -17, -20,
+ -9, -11, -18, -11, 3, 31, 36, 41, 41, 44, 53, 30, 10, 1, -13, 12,
+ -5, 42, 63, 43, -127, -55, 19, -27, 28, -1, 0, 3, 5, 8, 12, 14,
+ 15, 15, 14, 12, 8, 5, 1, -3, -9, -14, -17, -19, -18, -16, -12, -8,
+ -5, -4, -2, -1, -1, -2, -3, -4, -3, -2, -1, -1, 0, 0, 0, 2,
+ 8, 12, 16, 19, 23, 26, 34, 40, 39, 28, 11, -8, -26, -36, -40, -39,
+ -35, -27, -19, -10, -5, -6, -10, -12, -15, -14, -12, -9, -5, -3, -1, 1,
+ 6, 8, 7, 7, 7, 8, 13, 20, 28, 35, 43, 48, 55, 57, 51, 32,
+ 3, -29, -56, -68, -67, -60, -46, -31, -17, -7, -4, -7, -11, -15, -16, -15,
+ -10, -5, -1, 1, 3, 5, 7, 9, 11, 12, 12, 10, 13, 19, 26, 36,
+ 43, 51, 58, 65, 61, 40, 6, -30, -60, -75, -73, -64, -49, -32, -16, -5,
+ -1, -4, -11, -18, -23, -23, -19, -12, -5, 2, 8, 12, 13, 11, 9, 8,
+ 8, 10, 15, 21, 27, 32, 37, 42, 49, 55, 63, 55, 32, -3, -39, -66,
+ -79, -73, -56, -39, -24, -12, -7, -7, -12, -19, -24, -24, -21, -14, -6, 3,
+ 8, 11, 12, 11, 10, 10, 10, 11, 14, 17, 21, 27, 33, 41, 49, 56,
+ 63, 66, 49, 15, -27, -61, -82, -85, -73, -52, -33, -18, -9, -5, -7, -12,
+ -18, -21, -20, -15, -9, -1, 4, 8, 12, 15, 15, 14, 11, 8, 7, 10,
+ 15, 22, 32, 45, 59, 72, 86, 95, 75, 22, -40, -93, -119, -120, -97, -64,
+ -32, -9, 5, 9, 5, -3, -14, -21, -23, -20, -13, -5, 4, 12, 17, 18,
+ 15, 10, 7, 4, 3, 6, 9, 15, 21, 30, 40, 56, 77, 99, 99, 54,
+ -19, -86, -123, -127, -103, -66, -27, 1, 16, 18, 11, -1, -12, -21, -23, -21,
+ -16, -8, 1, 9, 16, 19, 16, 11, 8, 5, 5, 7, 9, 14, 19, 27,
+ 35, 49, 68, 90, 101, 73, 6, -66, -114, -128, -113, -78, -39, -6, 13, 19,
+ 11, -1, 0, 10, 30, 35, 40, 39, 37, 28, 18, 6, -9, -20, -30, -35,
+ -33, -30, -28, -23, -24, -23, -19, -20, -15, -11, -8, -3, 0, 1, 0, -2,
+ -4, -1, 0, 10, 15, 21, 27, 25, 25, 22, 13, 10, -5, -9, -15, -19,
+ -17, -17, -12, -7, 0, 4, 10, 8, 5, -5, -13, -23, -31, -30, -24, -13,
+ 11, 36, 62, 81, 83, 78, 54, 35, 19, -11, -29, -49, -57, -47, -35, -20,
+ -19, -26, -27, -33, -30, -26, -22, -11, -8, 3, 11, 6, 0, -16, -23, -23,
+ -11, 9, 23, 35, 45, 51, 46, 49, 26, 12, -13, -26, -37, -45, -31, -35,
+ -17, -4, 8, 23, 24, 23, 9, -10, -22, -37, -40, -38, -33, -12, 22, 67,
+ 100, 119, 111, 79, 50, 10, -12, -32, -52, -69, -62, -38, -14, -9, -21, -42,
+ -60, -50, -39, -19, -4, -1, 3, 15, 19, 2, -16, -43, -57, -48, -21, 19,
+ 38, 63, 66, 69, 74, 59, 39, 4, -33, -52, -67, -58, -39, -25, 2, 10,
+ 32, 35, 36, 18, -7, -25, -37, -31, -28, -23, -10, 11, 53, 101, 121, 123,
+ 92, 48, 11, -24, -42, -60, -66, -67, -48, -20, 2, -16, -41, -67, -87, -62,
+ -44, -10, 8, 19, 30, 34, 35, 4, -36, -66, -78, -75, -27, 22, 49, 83,
+ 91, 97, 90, 69, 39, -18, -61, -104, -98, -75, -32, 19, 47, 68, 70, 56,
+ 16, -33, -77, -89, -76, -47, 7, 35, 64, 100, 123, 125, 107, 60, 5, -39,
+ -76, -94, -101, -93, -69, -36, -3, 17, 10, -15, -56, -80, -86, -69, -40, -7,
+ 25, 49, 66, 72, 54, 19, -19, -55, -77, -67, -40, 4, 45, 76, 96, 100,
+ 92, 67, 32, -11, -56, -88, -91, -73, -33, 9, 41, 61, 65, 52, 17, -28,
+ -67, -80, -68, -36, 6, 47, 82, 114, 126, 114, 74, 18, -32, -73, -93, -101,
+ -93, -70, -36, -3, 17, 10, -15, 0, -1, -2, -2, 0, 2, 3, 6, 7,
+ 6, 6, 3, 2, -1, -4, -8, -12, -14, -13, -13, -11, -5, -1, 5, 10,
+ 14, 17, 19, 18, 15, 12, 7, 3, 1, -2, -4, -4, -7, -11, -13, -16,
+ -16, -12, -9, -6, -3, -1, -1, -1, -4, -8, -11, -15, -16, -15, -10, -2,
+ 7, 18, 25, 28, 28, 24, 16, 10, 4, -2, -5, -5, -4, -4, -1, 0,
+ 0, 1, 1, 0, -1, -3, -6, -11, -11, -14, -16, -17, -19, -19, -16, -10,
+ -2, 8, 19, 27, 33, 35, 32, 26, 21, 14, 7, 0, -6, -11, -18, -25,
+ -31, -32, -27, -19, -9, 1, 10, 15, 14, 10, 0, -13, -28, -38, -42, -40,
+ -26, -4, 17, 40, 58, 66, 62, 51, 35, 17, 3, -8, -16, -18, -18, -15,
+ -13, -15, -17, -17, -15, -13, -11, -12, -3, -2, 1, -3, -15, -28, -36, -42,
+ -40, -28, -11, 14, 45, 63, 70, 69, 56, 44, 36, 21, 3, -12, -18, -26,
+ -37, -47, -58, -55, -41, -20, 4, 22, 34, 43, 37, 22, -7, -43, -71, -88,
+ -86, -64, -31, 7, 56, 99, 115, 106, 85, 48, 17, 1, -14, -28, -33, -20,
+ -11, -12, -18, -37, -44, -41, -29, -23, -7, 15, 31, 40, 33, 8, -27, -56,
+ -73, -74, -63, -33, 4, 50, 93, 101, 91, 79, 56, 43, 24, 5, -17, -32,
+ -31, -43, -56, -63, -72, -57, -32, 3, 26, 46, 62, 63, 45, 9, -39, -85,
+ -112, -106, -84, -49, 6, 60, 104, 127, 115, 83, 46, 16, -1, -16, -21, -26,
+ -16, -2, -8, -25, -47, -67, -62, -49, -26, 2, 34, 60, 74, 65, 33, -21,
+ -71, -98, -92, -77, -36, 21, 69, 106, 112, 88, 58, 29, 9, -8, -18, -24,
+ -17, -4, -10, -26, -47, -67, -62, -49, -26, 2, 34, 60, 74, 65, 33, 17,
+ 16, -38, 9, 40, -58, 27, 43, -80, 52, -2, -54, 64, -27, -17, 32, 4,
+ -49, 53, -22, -47, 90, -73, 17, 42, -45, 8, 23, -41, -1, 58, -74, 40,
+ 25, -66, 56, -19, -45, 58, -9, -39, 45, 3, -48, 55, -41, -27, 78, -66,
+ 13, 40, -38, 0, 29, -51, 12, 57, -79, 38, 31, -64, 40, -4, -47, 63,
+ -16, -40, 55, -16, -32, 45, -31, -29, 76, -64, 0, 58, -49, 4, 31, -52,
+ 31, 5, -35, 45, -21, 4, -5, 3, -17, -7, 55, -72, 43, 35, -88, 80,
+ -57, 3, 45, -62, 53, -14, -2, -17, 46, -77, 42, 23, -61, 75, -54, 39,
+ -40, 31, -42, 25, 11, -48, 93, -97, 62, -27, -13, 7, 0, 30, -59, 82,
+ -74, 28, 10, -53, 65, -47, 46, -41, 40, -48, 7, 45, -95, 127, -99, 43,
+ -9, -25, 40, -58, 84, -84, 78, -66, 11, 50, -96, 111, -85, 51, -26, -14,
+ 36, -60, 91, -84, 58, -26, -22, 56, -87, 98, -71, 47, -25, -11, 44, -84,
+ 103, -92, 69, -32, -3, 25, -59, 87, -90, 70, -45, 17, 16, -57, 81, -73,
+ 50, -33, 14, 0, -35, 75, -84, 69, -42, 8, 11, -46, 74, -69, 57, -47,
+ 36, -26, -20, 69, -89, 83, -58, 37, -24, -7, 41, -58, 54, -53, 53, -42,
+ 14, 28, -54, 52, -55, 46, -41, 22, 30, -57, 58, -64, 56, -54, 26, 31,
+ -55, 63, -73, 66, -68, 49, -3, -38, 61, -71, 75, -87, 69, -15, -27, 37,
+ -55, 74, -84, 73, -34, -5, 26, -59, 74, -85, 84, -33, -12, 30, -57, 65,
+ -85, 86, -40, 9, 15, -50, 69, -94, 93, -53, 15, 11, -38, 58, -86, 96,
+ -64, 11, 21, -30, 17, -3, -3, 0, 0, -3, -4, -4, -3, -4, -4, -5,
+ -6, -6, -8, -5, -6, -3, 0, 2, 4, 7, 8, 12, 12, 14, 13, 13,
+ 12, 8, 7, 2, 2, -4, -6, -10, -11, -12, -12, -14, -10, -9, -3, -3,
+ 2, 3, 3, 2, 1, 1, -3, -3, -4, -3, -3, -3, -4, 0, -3, -3,
+ -3, 0, -3, 0, -3, 0, 1, 0, 0, 0, 0, 0, -3, 1, -3, 1,
+ -3, 2, 1, 0, 0, -3, -4, -5, -9, -10, -15, -16, -17, -17, -14, -10,
+ -3, 4, 9, 14, 19, 24, 25, 26, 28, 30, 34, 42, 31, 9, -31, -39,
+ -23, -15, -17, -23, -30, -23, -12, -10, 4, 9, 19, 13, 14, 6, 0, -9,
+ -11, -12, -9, -8, 0, 0, 2, 1, 1, -3, -3, -5, -3, -5, -3, -4,
+ 0, -3, -4, -4, -3, -5, -3, -5, -3, 0, 3, 2, 7, 7, 7, 3,
+ 0, -14, -17, -26, -26, -28, -21, -17, -11, -10, 2, 6, 19, 18, 32, 32,
+ 60, 69, 98, 60, 7, -58, -8, -8, -14, -39, -30, -14, -47, -21, -45, -3,
+ 7, 20, 14, 31, 12, 10, -15, -5, -23, -14, -15, -4, -8, 2, 1, 7,
+ -3, 2, -8, -4, -6, -6, -3, 0, -6, -6, -8, -10, -11, -12, -9, -9,
+ -4, -3, 0, 8, 10, 12, 15, 13, 4, -10, -15, -30, -32, -30, -23, -22,
+ -19, -14, -4, 3, 10, 14, 26, 40, 70, 102, 127, 62, -17, -39, 9, -25,
+ -9, -87, -12, -16, 0, -30, -27, -19, -9, 6, 18, 21, 19, 6, 0, -9,
+ -17, -14, -16, -8, -6, 0, 4, 4, -5, -4, -11, -3, -6, 2, 2, 0,
+ -6, 0, -2, -4, -8, -14, -21, -25, -28, -32, -36, -40, -44, -48, -51, -55,
+ -59, -63, -67, -71, -74, -78, -82, -86, -90, -94, -98, -101, -84, -60, -38, -15,
+ 8, 28, 27, 23, 19, 16, 11, 21, 46, 68, 93, 109, 106, 102, 98, 95,
+ 91, 87, 83, 79, 75, 71, 67, 64, 60, 56, 52, 49, 45, 41, 37, 33,
+ 30, 26, 22, 18, 15, 11, 7, 3, -1, -5, -9, -13, -17, -20, -24, -28,
+ -32, -35, -39, -43, -47, -51, -54, -58, -62, -66, -69, -73, -77, -81, -85, -89,
+ -93, -97, -100, -105, -95, -70, -48, -23, -7, -10, -14, -17, -22, -18, 4, 26,
+ 50, 72, 96, 107, 103, 100, 96, 92, 88, 84, 80, 76, 72, 68, 64, 61,
+ 57, 53, 49, 46, 42, 38, 34, 30, 26, 23, 19, 15, 11, 8, 4, 0,
+ -4, -8, -11, -15, -19, -23, -27, -30, -35, -38, -43, -46, -51, -54, -58, -61,
+ -66, -56, -31, -9, 16, 33, 30, 26, 22, 18, 15, 11, 7, 3, -1, -5,
+ -9, -13, -16, -20, -24, -28, -32, -36, -40, -43, -48, -51, -55, -59, -63, -50,
+ -26, -4, 20, 42, 64, 67, 62, 59, 55, 51, 47, 43, 39, 35, 31, 27,
+ 23, 20, 16, 12, 8, 4, 0, -4, -7, -11, -15, -19, -22, -27, -17, 8,
+ 30, 55, 72, 69, 65, 61, 57, 54, 50, 46, 42, 38, 34, 30, 26, 22,
+ 18, 15, 11, 7, 3, 0, -4, -8, -12, -15, -19, -23, -27, -31, -35, -38,
+ -42, -46, -50, -54, -57, -61, -65, -69, -73, -77, -81, -85, -89, -92, -96, -100,
+ -100, -79, -64, -47, -31, -15, 0, 0, -4, -3, -6, -8, 6, 10, -8, -13,
+ 22, 55, 15, -58, -102, -88, -25, 51, 77, 79, 82, 19, -45, -107, -128, -88,
+ 19, 81, 86, 71, 35, -16, -50, -73, -55, -27, -14, 7, 77, 89, 31, -22,
+ -27, -61, -86, -34, 40, 55, 67, 80, 57, -1, -48, -60, -41, -46, -31, 28,
+ 62, 47, 43, 33, -5, -34, -45, -52, -33, 26, 66, 70, 41, 17, -34, -79,
+ -93, -41, -6, 22, 53, 93, 62, 17, -20, -66, -118, -88, -4, 45, 60, 69,
+ 67, 2, -72, -109, -95, -78, -7, 67, 101, 78, 69, 19, -56, -110, -89, -64,
+ -19, 45, 100, 86, 36, -11, -65, -107, -108, -41, 24, 69, 93, 111, 56, -15,
+ -70, -81, -88, -38, 30, 88, 90, 83, 43, -24, -81, -82, -57, -24, 38, 100,
+ 115, 70, 26, -25, -75, -108, -66, -20, 29, 71, 105, 67, 7, -46, -67, -83,
+ -60, 0, 58, 82, 81, 57, -9, -72, -99, -78, -60, -8, 54, 95, 69, 44,
+ 0, -51, -92, -69, -26, 18, 53, 81, 63, 6, -44, -74, -88, -79, -19, 40,
+ 75, 75, 72, 18, -42, -80, -74, -69, -25, 32, 76, 66, 39, 5, -41, -82,
+ -76, -34, 3, 42, 79, 88, 38, -12, -49, -74, -92, -48, 8, 51, 70, 83,
+ 50, -7, -58, -68, -65, -43, 13, 70, 82, 62, 34, -17, -72, -94, -65, -28,
+ 17, 69, 101, 71, 25, -21, -60, -88, -66, -13, 37, 62, 82, 68, 11, -47,
+ -73, -79, -66, -15, 49, 82, 76, 57, 11, -51, -88, -78, -48, -9, 49, 0,
+ 0, 0, 0, 0, 0, -3, -5, -5, -7, -6, -2, 5, 16, 24, 21, 17,
+ 12, 3, -10, -31, -44, -47, -42, -28, -2, 26, 29, 36, 35, 1, -26, -39,
+ -52, -53, -38, -10, -32, -41, -7, 2, 22, 65, 89, 74, 15, -16, -24, 12,
+ 62, 39, 6, -12, -3, 47, 48, 21, 109, 127, 119, 53, -9, 19, 9, -50,
+ -55, -43, -71, -46, -5, -2, -20, -12, -9, 12, -27, -66, -50, -8, -19, -58,
+ -22, -8, -19, -34, -42, 10, 32, -4, 4, 46, 96, 34, -51, -10, -8, -93,
+ -70, -58, -46, -16, -32, -30, 6, 7, -41, -29, 3, 25, 73, 67, 45, 37,
+ 30, 83, 0, -31, -4, -50, -28, -41, -75, -110, -53, -13, -3, 22, 14, 14,
+ 13, 7, 9, 38, 47, 39, 17, -8, 90, 75, -5, -29, -46, -54, -102, -66,
+ -35, -27, -29, -21, 32, 5, 1, 1, -2, 16, 16, 19, 30, 50, 89, 41,
+ 6, 40, -10, -15, -41, -46, -43, -77, -100, -100, -48, -37, -26, -4, -9, 0,
+ 13, 36, 70, 75, 59, 34, 12, -13, -27, 37, 71, 48, 53, 37, 7, 8,
+ 34, 48, 40, 31, 25, 2, -20, -15, -5, 12, -11, -49, -20, 15, -13, -42,
+ -29, 16, -6, -58, -28, 17, 12, -20, -11, 16, -3, -37, -14, 3, -32, -10,
+ 40, 54, 53, 27, -3, -5, -34, -47, -49, -90, -68, -36, -32, -31, -16, 26,
+ 3, 0, -2, -2, 15, 16, 19, 30, 51, 88, 40, 6, 39, -10, 3, -2,
+ 11, -7, 23, 19, 74, 39, 32, -13, -21, -7, -39, -44, -128, -58, -21, 52,
+ -86, -74, -94, 75, 61, 72, -38, 13, 59, 116, 71, -9, -33, -12, 68, -2,
+ -35, -128, -42, -43, 39, -78, -57, -81, 56, 59, 63, -13, 7, 69, 98, 87,
+ -13, -9, -24, 70, -11, -23, -128, -42, -48, 28, -68, -61, -69, 34, 64, 46,
+ 8, -5, 79, 82, 100, -17, 5, -29, 69, -13, -21, -122, -49, -43, 11, -55,
+ -72, -54, 13, 73, 30, 23, -16, 87, 72, 107, -17, 10, -26, 64, -6, -26,
+ -109, -61, -31, -6, -40, -86, -41, -4, 80, 17, 31, -22, 88, 70, 106, -10,
+ 6, -16, 53, 7, -37, -93, -76, -17, -21, -28, -99, -33, -15, 83, 12, 31,
+ -21, 83, 76, 98, 2, -4, -1, 41, 24, -49, -77, -89, -6, -31, -20, -106,
+ -32, -19, 79, 14, 23, -15, 71, 87, 87, 17, -16, 13, 30, 39, -57, -67,
+ -97, -1, -34, -19, -106, -38, -16, 69, 23, 11, -5, 56, 100, 75, 32, -28,
+ 25, 22, 50, -59, -62, -98, -2, -30, -24, -100, -52, -9, 55, 36, -4, 5,
+ 41, 112, 67, 43, -34, 30, 21, 55, -53, -65, -93, -11, -18, -34, -88, -69,
+ 0, 41, 48, -17, 12, 29, 118, 65, 49, -34, 28, 27, 53, -42, -72, -83,
+ -23, -6, -44, -77, -85, 5, -69, 1, -12, -29, -28, -13, 1, 9, -4, -27,
+ -18, -5, 11, 65, 87, 54, 59, 66, 30, 12, 8, -6, -7, 4, -7, -39,
+ -59, -63, -48, -23, -13, -6, 22, 61, 68, 15, -59, -87, -41, 3, 5, -10,
+ -17, -17, -20, -23, -20, -28, -17, -3, -10, -29, 23, 11, 25, 52, 56, 62,
+ 80, 54, 22, -15, -31, -38, -5, 11, -9, -7, -36, -44, -6, 52, 127, 26,
+ -68, -125, -105, 22, 15, -27, -27, 13, 25, 69, 28, -42, -77, -57, -70, 15,
+ 44, 14, 26, 57, 69, 43, 33, 41, 33, 32, 25, -50, -98, -100, -38, 24,
+ 7, -35, -38, -2, 76, 64, 15, -79, -93, -50, -12, 27, 45, 32, -4, 23,
+ 6, -36, -47, -33, -52, -15, 37, 78, 49, 40, 17, 14, 14, 70, 81, 60,
+ -3, -4, -12, -42, -50, -28, -20, 5, 9, 27, 46, -13, -69, -99, -88, -47,
+ 5, -4, -10, 17, 39, -12, -8, -21, -16, 22, 9, -9, 1, 15, 15, 33,
+ 29, 17, 11, 38, 72, 29, -8, -36, -27, -42, 17, -40, 25, 25, 8, -3,
+ 14, 15, 2, 43, 33, -2, -19, -24, -8, 2, -69, -114, -94, -77, -87, 22,
+ 27, 19, 24, 57, 121, 94, 40, -27, -29, 4, 28, -12, 5, -21, -28, -18,
+ 0, -9, 1, 36, 22, 7, 6, 12, 7, 8, 55, 6, -2, -7, -13, -12,
+ -12, -8, -5, -5, -1, -4, -4, -3, -1, 5, 11, 15, 18, 16, 11, 5,
+ -5, -12, -16, -17, -14, -10, -7, -3, -2, -3, -3, -5, -3, 2, 9, 18,
+ 22, 23, 18, 11, -2, -14, -20, -22, -18, -12, -8, -5, -3, -5, -6, -6,
+ -5, 1, 11, 22, 30, 31, 24, 15, -1, -12, -20, -23, -19, -13, -8, -3,
+ -3, -2, -6, -8, -9, -5, 6, 21, 32, 35, 29, 19, 1, -15, -27, -29,
+ -25, -15, -9, -4, -1, -2, -7, -14, -15, -10, 4, 24, 42, 48, 43, 26,
+ 4, -20, -36, -38, -30, -17, -7, -3, 0, -1, -4, -16, -24, -19, -3, 26,
+ 49, 61, 60, 40, 9, -23, -45, -52, -39, -22, -5, -2, 1, 3, -2, -18,
+ -32, -30, -10, 22, 55, 77, 78, 52, 15, -22, -51, -66, -52, -29, -5, 0,
+ 2, 9, 6, -15, -37, -42, -22, 10, 55, 89, 99, 71, 22, -20, -58, -79,
+ -68, -35, -8, 6, 1, 12, 13, -9, -37, -50, -35, 0, 46, 93, 116, 90,
+ 33, -15, -60, -89, -84, -44, -9, 10, 3, 13, 19, -3, -35, -53, -43, -12,
+ 34, 91, 127, 109, 46, -9, -57, -95, -96, -57, -13, 11, 7, 10, 25, 2,
+ -2, -35, 0, 2, 7, 12, -7, -79, -68, 2, -6, -5, 19, 40, 33, 55,
+ 56, 17, 32, 32, 2, -20, 5, 51, 27, -21, -13, -11, -17, -20, -6, -63,
+ -125, -116, -86, -59, -34, 11, 23, 20, 39, 66, 50, 47, 54, 46, 11, -4,
+ 44, 67, 30, 11, 16, 6, -2, 7, -4, -77, -114, -107, -70, -50, -20, 29,
+ 26, 12, 48, 69, 44, 47, 49, 28, -8, 9, 53, 49, 15, 9, 8, -3,
+ -11, 7, -33, -107, -123, -101, -62, -49, -5, 25, 6, 13, 55, 49, 32, 40,
+ 39, 7, -17, 18, 49, 32, 7, 8, 1, -12, -3, 7, -62, -113, -109, -74,
+ -50, -31, 23, 32, 13, 40, 69, 48, 46, 54, 42, 2, 1, 42, 52, 25,
+ 10, 11, 0, -11, 10, -10, -90, -115, -101, -64, -52, -15, 29, 16, 10, 51,
+ 59, 41, 46, 49, 25, -9, 15, 48, 42, 15, 10, 7, -9, -7, 16, -43,
+ -107, -113, -89, -60, -47, 4, 27, 4, 19, 58, 47, 38, 46, 43, 6, -9,
+ 28, 47, 29, 10, 11, 2, -14, 5, 5, -73, -111, -106, -73, -56, -29, 24,
+ 22, 6, 40, 61, 43, 43, 52, 37, -3, 6, 41, 47, 23, 12, 11, 0,
+ -14, 1, 3, 5, 5, 6, 8, 6, 4, 0, -4, -5, -6, -9, -9, -11,
+ -11, -12, -13, -13, -13, -12, -11, -9, -5, -2, -1, 1, 4, 6, 9, 11,
+ 12, 12, 11, 8, 5, 2, -2, -2, -2, -2, 0, -1, -1, -2, -5, -5,
+ -5, -1, 4, 10, 17, 20, 22, 19, 15, 7, -1, -9, -15, -19, -21, -21,
+ -18, -16, -13, -11, -12, -15, -19, -23, -24, -20, -13, -3, 9, 20, 34, 44,
+ 50, 46, 35, 21, 7, -4, -14, -20, -19, -13, -8, 2, 0, -5, -15, -28,
+ -32, -29, -14, 0, 11, 27, 42, 58, 59, 45, 22, 4, -15, -26, -37, -43,
+ -42, -37, -17, 1, 18, 23, 8, -5, -29, -47, -47, -43, -25, -5, 20, 52,
+ 80, 92, 76, 43, 9, -20, -35, -38, -46, -41, -29, -12, 19, 35, 22, 4,
+ -34, -53, -58, -40, -26, -16, 14, 47, 88, 108, 90, 50, 16, -9, -36, -51,
+ -64, -64, -52, -33, -1, 32, 40, 24, 3, -29, -62, -58, -65, -52, -18, 23,
+ 68, 114, 127, 95, 41, 1, -36, -54, -56, -68, -55, -35, -17, 19, 42, 29,
+ 13, -16, -46, -60, -54, -56, -47, -11, 29, 72, 116, 127, 94, 41, -3, 0,
+ 16, 39, 54, 46, 18, 7, -15, -36, -9, -6, -16, -5, -15, -30, -23, -35,
+ -20, 22, 3, -19, -20, -13, -9, 19, 23, 10, 12, 35, 66, 54, 4, -43,
+ -58, -15, -10, 16, 55, 18, -39, -38, -30, 2, 9, 27, 51, -32, -60, -72,
+ -4, 32, 71, 19, -8, 56, -2, -42, 10, 21, -6, 31, -9, -70, 8, -6,
+ -19, -93, -20, -5, -31, 10, 5, 56, 24, -45, 11, 66, 48, 61, 89, 49,
+ -57, -6, -20, -69, -104, -83, -50, 32, 10, -16, -87, -78, 30, 127, 63, -17,
+ -91, -2, -12, 45, 83, 30, 56, 54, 42, 7, 79, -26, -52, -64, -97, 12,
+ -3, -107, -99, -39, 34, 86, 19, -25, 25, 90, -8, -38, 65, 36, 10, 30,
+ 36, 19, -6, 38, -47, -101, -52, -45, 30, -9, -106, 18, -10, -37, 16, 100,
+ -94, -111, -25, -35, -12, -8, -9, 51, 24, -5, -70, -52, -52, -19, -11, 48,
+ 93, 61, 17, 113, 125, 73, -16, -30, -57, -78, -116, -55, -38, -10, -5, -4,
+ 38, 31, -3, -46, -46, -50, -20, -10, 52, 84, 48, 14, 115, 119, 64, -16,
+ -1, 4, 0, -9, -11, -1, 6, 2, -2, 4, -6, -10, -2, 11, 14, 3,
+ -10, -15, -1, 17, 4, 6, 4, -12, -18, 6, 10, 4, 6, -8, -36, 2,
+ 3, 3, 5, 15, -20, -17, 9, 8, 11, 17, -8, -26, 18, 2, 5, 5,
+ 13, -24, -8, -2, 2, 5, 7, -21, -18, 13, 5, -5, 17, 7, -14, -13,
+ -12, 0, 14, 3, -12, -26, 13, 3, 10, 18, 12, -15, -14, -1, 3, 19,
+ 0, -10, -29, 11, 4, 17, 15, 12, -24, -20, 6, 9, 22, -3, -13, -15,
+ 9, 1, 7, 6, 18, -19, -26, -18, 2, 22, 0, -25, -20, 15, 8, -4,
+ 8, 31, -12, -20, -15, 9, 33, 9, -29, -2, 27, 7, -11, 8, 20, -20,
+ -41, -10, 15, 35, 15, -21, 11, 49, 6, -6, 4, 3, -48, -76, -35, 14,
+ 37, 22, -24, 29, 68, 20, 3, 7, -5, -68, -90, -59, 19, 36, 28, -13,
+ 59, 93, 30, 2, 18, -25, -88, -105, -81, 13, 26, 30, -4, 88, 109, 33,
+ 0, 22, -30, -88, -112, -76, 17, 31, 18, 5, 94, 114, 30, -4, 0, 4,
+ -30, -1, 0, -2, -2, -2, -1, 4, 11, 18, 30, 7, -64, -60, -30, -7,
+ 0, 2, 22, 67, 117, 23, -128, -74, -30, -5, -2, 1, 19, 62, 116, 38,
+ -123, -82, -31, -8, -1, -1, 16, 57, 114, 52, -117, -88, -33, -10, -2, -3,
+ 14, 52, 112, 64, -108, -96, -35, -13, -2, -4, 12, 49, 108, 77, -99, -102,
+ -37, -15, -2, -5, 10, 43, 104, 86, -87, -109, -40, -18, -2, -6, 8, 40,
+ 100, 95, -73, -115, -42, -21, -2, -8, 7, 35, 95, 102, -59, -120, -45, -24,
+ -2, -8, 5, 32, 90, 109, -44, -124, -49, -26, -3, -9, 3, 28, 85, 114,
+ -29, -126, -53, -28, -4, -9, 2, 25, 81, 116, -13, -127, -58, -29, -6, -9,
+ 0, 22, 75, 119, 3, -126, -63, -31, -7, -9, -2, 19, 70, 120, 18, -124,
+ -69, -32, -9, -9, -3, 16, 65, 119, 34, -63, -107, -58, -23, -11, -7, 7,
+ 46, 107, 89, -52, -109, -62, -25, -12, -8, 5, 42, 104, 97, -41, -87, -70,
+ -36, -18, -11, 0, 30, 85, 100, -2, -87, -5, 11, -23, -10, -3, -20, -3,
+ -17, -24, -33, -26, -1, -13, -12, -6, -9, 6, 25, 19, -7, -1, 22, -6,
+ -20, 13, 6, -12, 26, 48, 0, -7, 34, 23, 4, 32, 23, -41, -11, 49,
+ -3, -30, 35, 45, -14, -2, 62, 18, -44, -2, 26, -4, -28, -6, 16, 2,
+ -9, -9, 2, 18, 24, 9, -25, -57, -36, 30, 38, -21, -63, -37, 9, 37,
+ 40, 0, -56, -56, 3, 39, 20, -23, -52, -58, -46, 8, 67, 56, -18, -61,
+ -18, 36, 70, 95, 73, -35, -128, -127, -73, -17, 32, 48, 29, 28, 60, 106,
+ 113, 91, 36, -26, -67, -90, -91, -71, -44, -25, -13, 9, 36, 51, 69, 70,
+ 32, -40, -92, -99, -70, -25, 12, 29, 21, 3, -9, 10, 21, 12, -11, -22,
+ -27, -44, -23, 10, 30, 25, 24, 39, 18, 3, 8, 19, -1, -19, -8, 6,
+ 5, 13, 50, 43, 37, 36, 40, 37, 4, 12, -10, -33, -31, -25, -1, 1,
+ 7, 14, 10, -4, -11, -10, -6, -19, -42, -28, -54, -51, -18, -5, 3, 2,
+ -10, -10, 10, 28, 27, 16, 5, -5, -24, -26, -7, -14, -25, -16, 53, 33,
+ -49, -30, 53, 50, -24, -34, 40, 82, -118, -23, 120, -56, -70, -72, 106, -10,
+ -48, 3, 87, 28, -126, -16, 81, 4, -84, -51, 38, 62, -32, 36, 84, -12,
+ -41, 72, -42, -60, -64, 4, 77, -24, -79, -9, 122, 6, -94, 52, 43, 35,
+ 13, -62, -7, -89, 24, -30, 16, 29, 56, -59, 83, 42, 31, 36, -76, -2,
+ -128, -2, 45, 27, -104, -31, 66, 21, 19, 36, 121, 11, -76, -26, -93, 34,
+ 24, -34, -65, -53, 53, 17, 73, 46, 75, -9, -64, -21, -103, 41, 51, -41,
+ -83, -43, 108, 6, -11, 28, 127, 2, -84, -38, -72, 39, 17, -23, -15, -67,
+ 37, 6, 29, 64, 79, 17, -39, -39, -120, 55, 23, -17, -62, -51, 81, 23,
+ 20, 24, 99, -38, -99, 4, 17, -66, -41, -33, 63, 62, 16, 53, 91, 56,
+ -65, -36, -99, -38, 14, -47, -29, -38, 35, 83, 9, 48, 83, 62, -45, -31,
+ -103, -49, 14, 2, 6, -33, 33, -4, -1, 34, -93, 60, -49, 68, -21, 41,
+ -38, -38, 27, -87, 127, -34, 38, -3, -34, -2, -85, 79, -24, 4, 75, -23,
+ 11, -70, 1, -6, -6, 63, -48, 76, -71, 2, -7, -15, 46, -32, 48, -25,
+ -5, 10, -31, 18, -23, 5, 6, 17, 11, 3, 24, -46, -21, -1, -5, 31,
+ 1, 36, -23, -11, -4, -29, 14, -5, 29, 9, -2, -2, -20, -2, -15, 13,
+ 7, 4, 15, -11, 4, -13, -1, 1, -13, 15, -6, 9, 9, -2, -4, -11,
+ -2, -11, 7, 12, 9, 5, -6, -6, -16, -2, 3, 6, 13, 1, 7, -14,
+ -3, -11, -1, 8, 0, 18, -3, -3, -6, -13, 0, 4, 2, 9, 2, 2,
+ -6, -4, -1, -8, 2, 4, 2, 7, -4, 2, 1, -7, -3, -2, 0, 2,
+ 8, -2, 2, -1, -7, -3, -1, 3, 4, 3, 3, -3, -4, -4, 0, 2,
+ 1, 5, -1, -2, 1, -4, -1, 1, 0, 2, -5, -8, -3, -3, -9, -2,
+ -2, 5, 10, 16, 11, 5, -3, -5, -1, -4, -6, -7, -15, -18, -27, -31,
+ -21, -11, 22, 56, 90, 66, -17, -25, -25, 0, -12, -15, -25, -32, -39, -37,
+ -26, 6, 33, 65, 69, 44, -1, -13, -12, 1, 0, -9, -14, -22, -40, -44,
+ -42, -23, 8, 39, 60, 84, 57, -16, -25, -19, 2, -8, -11, -18, -32, -51,
+ -45, -32, -6, 28, 54, 85, 96, -5, -29, -23, -7, -10, -17, -16, -28, -53,
+ -44, -40, -7, 22, 52, 82, 112, 17, -37, -25, -20, -11, -18, -10, -23, -33,
+ -51, -40, -23, 10, 45, 65, 96, 64, -21, -35, -34, -19, -20, -13, -5, -14,
+ -35, -41, -39, -17, 9, 45, 58, 82, 98, -2, -57, -47, -23, -12, -11, -2,
+ -18, -28, -39, -36, -24, -1, 26, 57, 84, 121, 23, -65, -50, -40, -12, -11,
+ -4, -14, -20, -34, -32, -27, -5, 19, 56, 80, 127, 15, -66, -50, -2, -5,
+ -5, 2, 10, 8, -7, -16, -9, 6, 17, 8, -19, -20, 14, 38, 34, 20,
+ -5, 1, 50, 37, -50, -54, -66, -32, 32, -3, -13, -18, -17, 46, 89, -17,
+ -62, 45, 127, 57, -57, -67, -109, -11, 88, -31, -90, -88, -27, 63, 97, -27,
+ -105, -44, 65, 110, 60, -12, -30, -27, 17, 49, -2, -39, -6, 30, -16, -36,
+ -43, 32, 67, -54, -58, -38, -21, 47, 95, 76, -33, -78, -62, 10, 107, 24,
+ -106, -107, 12, 52, 27, 78, 8, -75, 25, 6, -26, 59, 32, -17, -7, -19,
+ 11, 32, -51, -52, 41, -9, -13, 94, 2, -65, 5, -46, -86, 34, 62, 85,
+ 29, -93, -89, -29, 44, 35, -31, -33, -19, 56, 127, 7, -9, -62, -52, 23,
+ 46, 44, -56, -16, -55, -46, 22, 83, -13, -42, -7, 13, 81, 49, 3, -9,
+ -30, -47, -30, 3, 23, 6, -7, -20, -44, 10, 96, -13, 0, 16, 31, 47,
+ 61, 75, 87, 98, 107, 115, 121, 125, 127, 127, 125, 121, 116, 108, 99, 88,
+ 75, 62, 47, 32, 16, 0, -16, -31, -47, -61, -75, -87, -98, -108, -116, -122,
+ -126, -128, -128, -126, -123, -117, -109, -100, -89, -77, -64, -49, -34, -18, -2, 14,
+ 29, 45, 59, 73, 86, 97, 106, 114, 121, 125, 127, 127, 126, 122, 116, 109,
+ 100, 89, 77, 63, 49, 34, 18, 2, -14, -30, -45, -60, -73, -86, -97, -107,
+ -115, -121, -126, -128, -128, -127, -123, -118, -110, -101, -91, -79, -65, -51, -36, -20,
+ -4, 12, 28, 43, 58, 72, 84, 96, 106, 114, 120, 124, 127, 127, 126, 122,
+ 117, 109, 100, 90, 78, 64, 50, 35, 19, 3, -13, -29, -44, -59, -73, -85,
+ -97, -107, -115, -121, -125, -128, -128, -127, -123, -118, -110, -101, -91, -79, -65, -51,
+ -36, -20, -4, 12, 2, 5, 5, 0, -16, -9, -2, -19, 4, 18, 6, 10,
+ -16, -21, 22, -2, 3, -7, 21, 43, -57, -37, 46, -39, -31, 78, 23, -23,
+ -10, -10, -7, -52, 44, 50, -44, 9, -9, -46, 47, 12, -75, 40, 45, 32,
+ -10, -25, -15, -45, 24, 44, -40, -10, 18, -48, -29, 63, 44, -30, -1, 83,
+ -45, -94, 96, 0, -103, 21, 29, -42, 21, 80, -25, -15, 26, 39, -79, -18,
+ 73, -111, -45, 61, 29, 55, -22, -77, 40, 9, -72, 78, 35, -1, -1, -69,
+ 12, -50, -42, 123, 45, -7, -39, -86, 3, 51, 30, 28, -4, -33, -41, -66,
+ 54, -8, -30, 127, -7, -30, -32, -39, 48, -65, 20, 121, -33, -14, -53, -32,
+ 46, -24, 36, 98, -49, -39, -61, 1, 49, -54, 65, 59, -83, -11, -49, 32,
+ 39, -72, 113, 59, -83, -11, -49, 32, 39, -72, 113, 59, -2, -4, -4, -7,
+ -8, -8, -7, -4, -3, -2, 1, 4, 6, 6, 6, 4, 2, 0, -2, -3,
+ -4, -7, -7, -5, -3, 0, 4, 9, 11, 11, 9, 7, 4, 1, -3, -7,
+ -9, -12, -13, -16, -19, -19, -13, -2, 9, 17, 19, 20, 18, 13, 8, 3,
+ 0, -2, -3, -8, -14, -21, -25, -21, -9, 4, 15, 23, 28, 25, 20, 9,
+ -7, -21, -14, 3, 3, -18, -38, -49, -32, -7, 8, 14, 26, 37, 42, 37,
+ 26, 7, -18, -27, -5, 8, -7, -24, -34, -40, -32, -19, 1, 17, 42, 56,
+ 58, 40, -19, -81, 1, 67, 0, -60, -49, -27, -24, 0, -18, -24, -8, 37,
+ 67, 70, 59, 34, -42, -81, 7, 51, -12, -54, -37, -14, -25, -14, -16, -24,
+ 4, 55, 75, 102, 52, -102, -104, 90, 30, -48, -76, 1, -14, 0, -2, -2,
+ -3, -5, -7, -8, -8, -7, -6, -4, -2, 0, 1, 3, 4, 6, 6, 6,
+ 6, 5, 4, 3, 1, 0, 0, -3, -4, -7, -10, -11, -11, -8, -6, 1,
+ 5, 6, 8, 11, 11, 8, 5, 5, 2, 1, 0, 0, -2, 1, -4, -16,
+ -36, -27, -5, 6, -3, -6, 0, -6, 2, 27, 24, 19, 16, 9, 3, 0,
+ -4, 2, 1, 9, 19, -14, -79, -32, 22, -4, -22, -14, 25, 8, -11, 13,
+ 28, 16, 19, 16, 1, -2, -4, -3, -6, 28, 38, -59, -111, 25, 16, -16,
+ -40, 16, 24, -20, 4, 24, 29, 17, 27, 13, 1, -10, -6, -10, -8, 43,
+ 61, -68, -128, 28, 12, -15, -39, 12, 21, -28, 12, 37, 25, 12, 27, 11,
+ 0, -16, -2, -12, -11, 52, 67, -68, 35, 54, 47, 4, -60, -92, -68, -27,
+ 0, -2, -18, -20, -6, 2, -8, -15, -11, -3, 3, -7, -11, -6, -2, 7,
+ 15, 18, 19, 22, 27, 40, 40, 29, 20, 24, 28, 34, 30, 25, 32, 20,
+ 14, 9, 16, 19, 17, 6, -1, 3, -6, -14, -23, -18, -7, 1, -18, -18,
+ -24, -25, -24, -35, -35, -35, -21, -12, -14, -21, -17, -29, -24, -31, -34, -9,
+ -11, -9, -3, -7, -7, 6, -17, -22, 7, 16, 14, -4, -11, 10, 33, 24,
+ 21, 27, 3, -19, -25, -18, 17, 50, 48, 49, 61, 31, -48, -103, -73, 9,
+ 56, 70, 82, 109, 127, 71, -46, -127, -96, -30, -4, 9, 47, 103, 117, 60,
+ -39, -110, -119, -94, -64, -40, -4, 35, -8, -14, -9, -5, -4, -3, 6, 18,
+ 19, 6, -14, -20, -12, -3, -3, -6, 2, 21, 28, 13, -16, -26, -14, -6,
+ -6, -7, 1, 27, 36, 18, -15, -27, -15, -3, -2, -10, -6, 25, 41, 22,
+ -17, -34, -18, -4, -3, -16, -12, 29, 56, 31, -24, -44, -20, -4, -1, -19,
+ -22, 31, 73, 47, -27, -62, -25, -2, 4, -21, -36, 26, 91, 61, -27, -79,
+ -33, 0, 10, -18, -49, 14, 106, 82, -24, -94, -40, 8, 14, -12, -59, 1,
+ 112, 105, -19, -106, -51, 12, 16, -4, -63, -13, 110, 127, -12, -114, -51, 0,
+ -1, -4, -8, -11, -8, -2, 0, 7, 14, 21, 46, 92, 120, 76, -36, -121,
+ -119, -73, -31, -7, 3, 2, -4, -6, 2, 22, 60, 106, 116, 43, -72, -128,
+ -105, -57, -21, -3, 3, -1, -6, -5, 7, 33, 76, 117, 102, 5, -100, -127,
+ -89, -43, -13, 0, 2, -3, -7, -2, 14, 46, 92, 122, 79, -34, -118, -118,
+ -72, -31, -8, 1, 0, -5, -7, 2, 23, 61, 107, 118, 46, -69, -126, -104,
+ -56, -21, -4, 1, 0, -4, -5, 0, 16, 48, 87, 103, 60, -25, -87, -94,
+ -58, -20, -4, -11, 12, 24, 31, -36, 29, -9, 2, -38, -5, -5, -10, -33,
+ -10, -24, -20, -39, -36, -18, -38, -58, -5, -22, -15, -15, 90, -42, -3, -8,
+ 25, 6, 28, 25, 17, 25, -16, 28, 80, 22, 12, -6, 35, 22, 8, -7,
+ 28, 29, -19, 7, 8, -1, -29, -23, 10, -23, -13, -26, -17, -20, -33, -41,
+ -19, -28, -64, -13, -21, -13, -29, 54, 25, -20, -36, 42, -4, 13, 52, -8,
+ 47, -14, 9, 42, 88, -12, 20, -5, 43, 22, -11, 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, -128, -128, -128, -128, -128, -128, -128, -128,
+ -128, -128, -128, -128, -128, -128, -128, 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, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, -128, 1, 4, 7, 10, 12, 16, 19, 22, 25, 28, 31, 35, 38, 42,
+ 45, 49, 51, 56, 58, 63, 65, 70, 73, 78, 80, 85, 87, 93, 95, 100,
+ 102, 108, 109, 117, 114, 127, 85, -63, -60, -64, -60, -62, -59, -61, -59, -61,
+ -58, -60, -58, -59, -58, -58, -57, -57, -55, -55, -54, -54, -52, -51, -50, -49,
+ -47, -46, -44, -43, -41, -40, -37, -36, -34, -32, -30, -28, -25, -24, -21, -19,
+ -16, -14, -11, -9, -6, 1, 1, 4, 7, 10, 12, 16, 19, 22, 25, 28,
+ 31, 35, 38, 42, 45, 49, 51, 56, 58, 63, 65, 70, 73, 78, 80, 85,
+ 87, 93, 95, 100, 102, 108, 109, 117, 114, 127, 85, -63, -60, -64, -60, -62,
+ -59, -61, -59, -61, -58, -60, -58, -59, -58, -58, -57, -57, -55, -55, -54, -54,
+ -52, -51, -50, -49, -47, -46, -44, -43, -41, -40, -37, -36, -34, -32, -30, -28,
+ -25, -24, -21, -19, -16, -14, -11, -9, -6, 1, -3, -19, -24, -14, -8, -19,
+ -12, -10, -5, -12, -50, -19, 23, 35, 4, -20, -7, -26, 9, 40, 69, 16,
+ -88, -69, -38, -32, -27, 41, 65, 55, 18, -40, -38, -20, 66, 127, 121, 57,
+ -23, -55, -48, 13, 53, 31, -20, -38, -13, 10, 8, 0, 12, 17, 13, 2,
+ -1, -3, -3, 6, 13, 7, -17, -24, -12, 4, 3, -10, -20, -32, -22, -18,
+ -12, -3, 6, 16, 22, 29, 30, 27, 20, 11, 0, -7, -12, -11, -5, 0,
+ -3, -14, -20, -16, -9, -9, -17, -25, -29, -31, -33, -35, -33, -29, -25, -22,
+ -20, -17, -14, -13, -12, -11, -9, -10, -13, -15, -11, -5, 3, 9, 10, 9,
+ 9, 12, 18, 30, 50, 80, 119, 127, 102, 82, 77, 60, 37, 5, -34, -70,
+ -84, -83, -74, -60, -46, -29, -12, -2, 6, -23, 28, -20, 50, 50, -14, 14,
+ -28, -2, 28, 52, -25, -13, -52, 43, -41, -9, -26, 36, -25, -20, -17, 3,
+ -11, 38, 30, -61, 12, -6, 5, 45, 41, -4, 4, -20, -12, 45, 33, -11,
+ -29, -44, 27, -17, -36, -1, 17, -11, -31, -12, 4, -10, 37, 20, -39, -23,
+ 0, -104, -55, -11, 24, 33, 30, 7, -15, -31, -30, -25, -23, -20, -9, 10,
+ 31, 59, 91, 111, 115, 92, 51, 7, -33, -64, -81, -81, -71, -51, -22, 16,
+ 52, 74, 82, 81, 68, 38, 0, -40, -81, -112, -124, -102, -57, -11, 0, 7,
+ -23, -58, -85, -100, -104, -100, -92, -81, -69, -57, -45, -33, -22, -11, -1, 8,
+ 18, 27, 37, 49, 62, 79, 99, 118, 124, 111, 84, 53, 26, 5, -8, -14,
+ -15, -12, -6, 2, 12, 21, 28, 26, 9, -22, -58, -20, 7, 10, 21, -14,
+ 9, 22, 57, 62, 127, 56, 28, 26, -28, 10, -81, -31, -81, -35, -19, -55,
+ -27, -4, -4, 23, 49, 88, 85, 22, 1, 0, -3, 18, -22, -12, -39, -14,
+ -47, -67, -53, -53, -33, -20, 8, -22, 25, 30, 6, -19, -62, -19, 10, 83,
+ 57, -67, -88, -52, 63, 127, 42, -63, -121, -70, 82, 111, 46, -43, -114, -35,
+ 45, 73, 39, -19, -54, -41, 9, 49, 24, -16, -14, -9, -6, 10, 8, -22,
+ 25, 30, 6, -19, -62, -19, 10, 83, 57, -67, -88, -52, 63, 127, 42, -63,
+ -121, -70, 82, 111, 46, -43, -114, -35, 45, 73, 39, -19, -54, -41, 9, 49,
+ 24, -16, -14, -9, -6, 10, 8, -22, 25, 30, 6, -19, -62, -19, 10, 83,
+ 57, -67, -88, -52, 63, 127, 42, -63, -121, -70, 82, 111, 46, -43, -114, -35,
+ 45, 73, 39, -19, -54, -41, 9, 49, 24, -16, -14, -9, -6, 10, -18, -15,
+ 80, 127, 20, 18, 72, 60, -36, 22, 33, -73, -105, -27, 29, 25, 8, 43,
+ 23, -22, -35, -14, -8, -34, -25, -5, -18, -46, -13, -28, -3, -19, -10, -28,
+ -10, 17, -18, 96, 127, 123, 127, 126, 126, 95, 61, 22, -17, -56, -95, -118,
+ -123, -128, -128, -128, -128, -128, -128, -128, -128, -124, -93, -55, -17, 25, 62, 100,
+ 107, 119, 119, 127, 41, -4, -4, -10, -27, -62, -102, -128, -117, -85, -76, -49,
+ -25, -7, 15, 24, 14, 0, -9, -12, -3, 33, 81, 105, 111, 101, 80, 62,
+ 45, 30, 16, 8, 1, -4, 126, 86, -44, -68, -88, -63, 4, 84, 127, 14,
+ -29, -51, -127, -47, 58, 87, 82, 24, -17, -112, -113, 18, 46, 72, 102, 19,
+ -72, -118, -51, 9, 27, 126, 19, -53, -114, -108, 15, 122, 111, 21, -71, -70,
+ 5, 59, 83, 23, -72, -84, -49, 12, 37, 38, -28, -65, -26, 7, -2, 11,
+ 5, 23, 68, 19, 27, -54, 15, -24, -31, 46, 71, 81, -24, -33, -87, -41,
+ -71, -61, -70, -36, -44, -3, 12, -25, -20, 20, 68, 85, 127, 15, 50, -5,
+ 27, 51, 82, 106, 127, 118, 101, 92, 74, 52, 39, 37, 14, -41, -105, -108,
+ -94, -119, -124, -93, -57, -40, -37, -45, -51, -41, -5, 51, 127, 127, -128, -128,
+ -128, -128, -128, -128, -128, -128, -128, -128, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127
};
-const EAS_U32 eas_sampleLengths[] =
+const EAS_U32 eas_sampleLengths[] =
{
- 16820, 16708, 16592, 11754, 10954, 10295, 9922, 7489,
- 5779, 5462, 4452, 3779, 3115, 3093, 3057, 3024,
- 2818, 2776, 2171, 2168, 2052, 1902, 1835, 1614,
- 1603, 1528, 1517, 1480, 1455, 1424, 1387, 1302,
- 1262, 1254, 1230, 1227, 1185, 1181, 1178, 1168,
- 1132, 1120, 1034, 1033, 1018, 994, 964, 926,
- 907, 886, 881, 866, 830, 817, 816, 813,
- 749, 748, 739, 720, 652, 610, 610, 583,
- 564, 561, 556, 549, 542, 535, 530, 530,
- 516, 508, 492, 478, 461, 448, 437, 431,
- 423, 418, 403, 402, 400, 394, 387, 387,
- 367, 357, 347, 347, 341, 336, 334, 329,
- 325, 312, 294, 284, 277, 265, 255, 233,
- 230, 213, 207, 205, 194, 193, 184, 181,
- 181, 167, 164, 158, 152, 152, 145, 139,
- 128, 103, 100, 88, 87, 84, 84, 72,
- 71, 55, 46, 45, 43, 40, 40, 40,
- 37, 35, 32, 32, 30, 29, 27, 23,
- 22, 21, 21, 21, 21, 20
+ 16820, 16708, 16592, 11754, 10954, 10295, 9922, 7489,
+ 5779, 5462, 4452, 3779, 3115, 3093, 3057, 3024,
+ 2818, 2776, 2171, 2168, 2052, 1902, 1835, 1614,
+ 1603, 1528, 1517, 1480, 1455, 1424, 1387, 1302,
+ 1262, 1254, 1230, 1227, 1185, 1181, 1178, 1168,
+ 1132, 1120, 1034, 1033, 1018, 994, 964, 926,
+ 907, 886, 881, 866, 830, 817, 816, 813,
+ 749, 748, 739, 720, 652, 610, 610, 583,
+ 564, 561, 556, 549, 542, 535, 530, 530,
+ 516, 508, 492, 478, 461, 448, 437, 431,
+ 423, 418, 403, 402, 400, 394, 387, 387,
+ 367, 357, 347, 347, 341, 336, 334, 329,
+ 325, 312, 294, 284, 277, 265, 255, 233,
+ 230, 213, 207, 205, 194, 193, 184, 181,
+ 181, 167, 164, 158, 152, 152, 145, 139,
+ 128, 103, 100, 88, 87, 84, 84, 72,
+ 71, 55, 46, 45, 43, 40, 40, 40,
+ 37, 35, 32, 32, 30, 29, 27, 23,
+ 22, 21, 21, 21, 21, 20
};
-const EAS_U32 eas_sampleOffsets[] =
+const EAS_U32 eas_sampleOffsets[] =
{
- 0x00000000, 0x000041b4, 0x000082f8, 0x0000c3c8, 0x0000f1b2, 0x00011c7c, 0x000144b3, 0x00016b75,
- 0x000188b6, 0x00019f49, 0x0001b49f, 0x0001c603, 0x0001d4c6, 0x0001e0f1, 0x0001ed06, 0x0001f8f7,
- 0x000204c7, 0x00020fc9, 0x00021aa1, 0x0002231c, 0x00022b94, 0x00023398, 0x00023b06, 0x00024231,
- 0x0002487f, 0x00024ec2, 0x000254ba, 0x00025aa7, 0x0002606f, 0x0002661e, 0x00026bae, 0x00027119,
- 0x0002762f, 0x00027b1d, 0x00028003, 0x000284d1, 0x0002899c, 0x00028e3d, 0x000292da, 0x00029774,
- 0x00029c04, 0x0002a070, 0x0002a4d0, 0x0002a8da, 0x0002ace3, 0x0002b0dd, 0x0002b4bf, 0x0002b883,
- 0x0002bc21, 0x0002bfac, 0x0002c322, 0x0002c693, 0x0002c9f5, 0x0002cd33, 0x0002d064, 0x0002d394,
- 0x0002d6c1, 0x0002d9ae, 0x0002dc9a, 0x0002df7d, 0x0002e24d, 0x0002e4d9, 0x0002e73b, 0x0002e99d,
- 0x0002ebe4, 0x0002ee18, 0x0002f049, 0x0002f275, 0x0002f49a, 0x0002f6b8, 0x0002f8cf, 0x0002fae1,
- 0x0002fcf3, 0x0002fef7, 0x000300f3, 0x000302df, 0x000304bd, 0x0003068a, 0x0003084a, 0x000309ff,
- 0x00030bae, 0x00030d55, 0x00030ef7, 0x0003108a, 0x0003121c, 0x000313ac, 0x00031536, 0x000316b9,
- 0x0003183c, 0x000319ab, 0x00031b10, 0x00031c6b, 0x00031dc6, 0x00031f1b, 0x0003206b, 0x000321b9,
- 0x00032302, 0x00032447, 0x0003257f, 0x000326a5, 0x000327c1, 0x000328d6, 0x000329df, 0x00032ade,
- 0x00032bc7, 0x00032cad, 0x00032d82, 0x00032e51, 0x00032f1e, 0x00032fe0, 0x000330a1, 0x00033159,
- 0x0003320e, 0x000332c3, 0x0003336a, 0x0003340e, 0x000334ac, 0x00033544, 0x000335dc, 0x0003366d,
- 0x000336f8, 0x00033778, 0x000337df, 0x00033843, 0x0003389b, 0x000338f2, 0x00033946, 0x0003399a,
- 0x000339e2, 0x00033a29, 0x00033a60, 0x00033a8e, 0x00033abb, 0x00033ae6, 0x00033b0e, 0x00033b36,
- 0x00033b5e, 0x00033b83, 0x00033ba6, 0x00033bc6, 0x00033be6, 0x00033c04, 0x00033c21, 0x00033c3c,
- 0x00033c53, 0x00033c69, 0x00033c7e, 0x00033c93, 0x00033ca8, 0x00033cbd
+ 0x00000000, 0x000041b4, 0x000082f8, 0x0000c3c8, 0x0000f1b2, 0x00011c7c, 0x000144b3, 0x00016b75,
+ 0x000188b6, 0x00019f49, 0x0001b49f, 0x0001c603, 0x0001d4c6, 0x0001e0f1, 0x0001ed06, 0x0001f8f7,
+ 0x000204c7, 0x00020fc9, 0x00021aa1, 0x0002231c, 0x00022b94, 0x00023398, 0x00023b06, 0x00024231,
+ 0x0002487f, 0x00024ec2, 0x000254ba, 0x00025aa7, 0x0002606f, 0x0002661e, 0x00026bae, 0x00027119,
+ 0x0002762f, 0x00027b1d, 0x00028003, 0x000284d1, 0x0002899c, 0x00028e3d, 0x000292da, 0x00029774,
+ 0x00029c04, 0x0002a070, 0x0002a4d0, 0x0002a8da, 0x0002ace3, 0x0002b0dd, 0x0002b4bf, 0x0002b883,
+ 0x0002bc21, 0x0002bfac, 0x0002c322, 0x0002c693, 0x0002c9f5, 0x0002cd33, 0x0002d064, 0x0002d394,
+ 0x0002d6c1, 0x0002d9ae, 0x0002dc9a, 0x0002df7d, 0x0002e24d, 0x0002e4d9, 0x0002e73b, 0x0002e99d,
+ 0x0002ebe4, 0x0002ee18, 0x0002f049, 0x0002f275, 0x0002f49a, 0x0002f6b8, 0x0002f8cf, 0x0002fae1,
+ 0x0002fcf3, 0x0002fef7, 0x000300f3, 0x000302df, 0x000304bd, 0x0003068a, 0x0003084a, 0x000309ff,
+ 0x00030bae, 0x00030d55, 0x00030ef7, 0x0003108a, 0x0003121c, 0x000313ac, 0x00031536, 0x000316b9,
+ 0x0003183c, 0x000319ab, 0x00031b10, 0x00031c6b, 0x00031dc6, 0x00031f1b, 0x0003206b, 0x000321b9,
+ 0x00032302, 0x00032447, 0x0003257f, 0x000326a5, 0x000327c1, 0x000328d6, 0x000329df, 0x00032ade,
+ 0x00032bc7, 0x00032cad, 0x00032d82, 0x00032e51, 0x00032f1e, 0x00032fe0, 0x000330a1, 0x00033159,
+ 0x0003320e, 0x000332c3, 0x0003336a, 0x0003340e, 0x000334ac, 0x00033544, 0x000335dc, 0x0003366d,
+ 0x000336f8, 0x00033778, 0x000337df, 0x00033843, 0x0003389b, 0x000338f2, 0x00033946, 0x0003399a,
+ 0x000339e2, 0x00033a29, 0x00033a60, 0x00033a8e, 0x00033abb, 0x00033ae6, 0x00033b0e, 0x00033b36,
+ 0x00033b5e, 0x00033b83, 0x00033ba6, 0x00033bc6, 0x00033be6, 0x00033c04, 0x00033c21, 0x00033c3c,
+ 0x00033c53, 0x00033c69, 0x00033c7e, 0x00033c93, 0x00033ca8, 0x00033cbd
};
/*----------------------------------------------------------------------------
* S_EAS
*----------------------------------------------------------------------------
*/
-const S_EAS easSoundLib =
+const S_EAS easSoundLib =
{
- 0x01534145,
- 0x00105622,
- eas_banks,
- eas_programs,
- eas_regions,
- eas_articulations,
- eas_sampleLengths,
- eas_sampleOffsets,
- eas_samples,
- 0,
- 1,
- 1,
- 377,
- 185,
- 150,
- 0
+ 0x01534145,
+ 0x00105622,
+ eas_banks,
+ eas_programs,
+ eas_regions,
+ eas_articulations,
+ eas_sampleLengths,
+ eas_sampleOffsets,
+ eas_samples,
+ 0,
+ 1,
+ 1,
+ 377,
+ 185,
+ 150,
+ 0
}; /* end S_EAS */
/*----------------------------------------------------------------------------
diff --git a/arm-wt-22k/misc/eas_host.c b/arm-wt-22k/misc/eas_host.c
index 89eb87a..01e5ce3 100644
--- a/arm-wt-22k/misc/eas_host.c
+++ b/arm-wt-22k/misc/eas_host.c
@@ -1,37 +1,37 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_host.c
- *
- * Contents and purpose:
- * This file contains the host wrapper functions for stdio, stdlib, etc.
- * This is a sample version that wraps the standard library functions.
- * Modify this file to suit the needs of your particular system.
- *
- * EAS_MAX_FILE_HANDLES sets the maximum number of MIDI streams within
- * a MIDI type 1 file that can be played. To maintain efficiency, data
- * is buffered locally when byte access is used (EAS_HWGetByte). The
- * size of the buffer is set by EAS_FILE_BUFFER_SIZE.
- *
- * EAS_HW_FILE is a structure to support local file buffering. It
- * comprises the OS File handle, some data related to the local file
- * buffer, the position of the next byte of data to be read, the dup
- * flag which when set, indicates that the handle has been duplicated,
- * and the data buffer. Since the data buffer is only used for byte
- * access, it does not need to be large.
- *
- * If the file system supports duplicate file handles and buffering,
- * this entire subsystem can be replaced with direct calls to the
- * native file I/O routines.
- *
- * If the system has enough memory to support reading the entire file
- * into memory, it will be much more efficient to do so on the call to
- * EAS_HWOpenFile and then close the file. Simply substitute a memory
- * pointer for the FILE* pointer. Calls to EAS_HW_DupHandle will work
- * as they do in this version. In the call to EAS_HWCloseFile, instead
- * of calling fclose, free the memory containing the file data.
- *
- * Copyright 2005 Sonic Network Inc.
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_host.c
+ *
+ * Contents and purpose:
+ * This file contains the host wrapper functions for stdio, stdlib, etc.
+ * This is a sample version that wraps the standard library functions.
+ * Modify this file to suit the needs of your particular system.
+ *
+ * EAS_MAX_FILE_HANDLES sets the maximum number of MIDI streams within
+ * a MIDI type 1 file that can be played. To maintain efficiency, data
+ * is buffered locally when byte access is used (EAS_HWGetByte). The
+ * size of the buffer is set by EAS_FILE_BUFFER_SIZE.
+ *
+ * EAS_HW_FILE is a structure to support local file buffering. It
+ * comprises the OS File handle, some data related to the local file
+ * buffer, the position of the next byte of data to be read, the dup
+ * flag which when set, indicates that the handle has been duplicated,
+ * and the data buffer. Since the data buffer is only used for byte
+ * access, it does not need to be large.
+ *
+ * If the file system supports duplicate file handles and buffering,
+ * this entire subsystem can be replaced with direct calls to the
+ * native file I/O routines.
+ *
+ * If the system has enough memory to support reading the entire file
+ * into memory, it will be much more efficient to do so on the call to
+ * EAS_HWOpenFile and then close the file. Simply substitute a memory
+ * pointer for the FILE* pointer. Calls to EAS_HW_DupHandle will work
+ * as they do in this version. In the call to EAS_HWCloseFile, instead
+ * of calling fclose, free the memory containing the file data.
+ *
+ * Copyright 2005 Sonic Network Inc.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -44,744 +44,744 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 853 $
- * $Date: 2007-09-05 09:54:17 -0700 (Wed, 05 Sep 2007) $
- *----------------------------------------------------------------------------
-*/
-
-#ifdef _lint
-#include "lint_stdlib.h"
-#else
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#endif
-
-#include "eas_host.h"
-
-// #define DEBUG_FILE_IO
-
-/* Only for debugging LED, vibrate, and backlight functions */
-#include "eas_report.h"
-
-#ifndef EAS_MAX_FILE_HANDLES
-#define EAS_MAX_FILE_HANDLES 32
-#endif
-
-#ifndef EAS_FILE_BUFFER_SIZE
-#define EAS_FILE_BUFFER_SIZE 32
-#endif
-
-/*
- * this structure and the related function are here
- * to support the ability to create duplicate handles
- * and buffering into a single file. If the OS supports
- * duplicate file handles natively, this code can be
- * stripped to eliminate double-buffering.
- */
-typedef struct eas_hw_file_tag
-{
- FILE *pFile;
- EAS_I32 bytesInBuffer;
- EAS_I32 readIndex;
- EAS_I32 filePos;
- EAS_BOOL dup;
- EAS_U8 buffer[EAS_FILE_BUFFER_SIZE];
-} EAS_HW_FILE;
-
-typedef struct eas_hw_inst_data_tag
-{
- EAS_HW_FILE files[EAS_MAX_FILE_HANDLES];
-} EAS_HW_INST_DATA;
-
-/* local memory for files and streams */
-#ifdef _STATIC_MEMORY
-EAS_HW_INST_DATA fileData;
-#endif
-
-/*----------------------------------------------------------------------------
- * EAS_HWInit
- *
- * Initialize host wrapper interface
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT EAS_HWInit (EAS_HW_DATA_HANDLE *pHWInstData)
-{
-
- /* need to track file opens for duplicate handles */
-#ifndef _STATIC_MEMORY
- *pHWInstData = malloc(sizeof(EAS_HW_INST_DATA));
- if (!(*pHWInstData))
- return EAS_ERROR_MALLOC_FAILED;
-#else
- *pHWInstData = &fileData;
-#endif
- EAS_HWMemSet(*pHWInstData, 0, sizeof(EAS_HW_INST_DATA));
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * EAS_HWShutdown
- *
- * Shut down host wrapper interface
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, hwInstData) hwInstData available for customer use */
-EAS_RESULT EAS_HWShutdown (EAS_HW_DATA_HANDLE hwInstData)
-{
-
-#ifndef _STATIC_MEMORY
- free(hwInstData);
-#endif
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- *
- * EAS_HWMalloc
- *
- * Allocates dynamic memory
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, hwInstData) hwInstData available for customer use */
-#ifdef _STATIC_MEMORY
-/*lint -esym(715, size) not used in static memory model */
-#endif
-void *EAS_HWMalloc (EAS_HW_DATA_HANDLE hwInstData, EAS_I32 size)
-{
-#ifdef _STATIC_MEMORY
- return NULL;
-#else
- return malloc((EAS_U32)size);
-#endif
-}
-
-/*----------------------------------------------------------------------------
- *
- * EAS_HWFree
- *
- * Frees dynamic memory
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, hwInstData) hwInstData available for customer use */
-#ifdef _STATIC_MEMORY
-/*lint -esym(715, p) not used in static memory model */
-#endif
-void EAS_HWFree(EAS_HW_DATA_HANDLE hwInstData, void *p)
-{
-#ifndef _STATIC_MEMORY
- free(p);
-#endif
-}
-
-/*----------------------------------------------------------------------------
- *
- * EAS_HWMemCpy
- *
- * Copy memory wrapper
- *
- *----------------------------------------------------------------------------
-*/
-void *EAS_HWMemCpy (void *dest, const void *src, EAS_I32 amount)
-{
- return memcpy(dest,src,(size_t) amount);
-}
-
-/*----------------------------------------------------------------------------
- *
- * EAS_HWMemSet
- *
- * Set memory wrapper
- *
- *----------------------------------------------------------------------------
-*/
-void *EAS_HWMemSet (void *dest, int val, EAS_I32 amount)
-{
- return memset(dest,val,(size_t) amount);
-}
-
-/*----------------------------------------------------------------------------
- *
- * EAS_HWMemCmp
- *
- * Compare memory wrapper
- *
- *----------------------------------------------------------------------------
-*/
-EAS_I32 EAS_HWMemCmp (const void *s1, const void *s2, EAS_I32 amount)
-{
- return (EAS_I32) memcmp(s1, s2, (size_t) amount);
-}
-
-/*----------------------------------------------------------------------------
- *
- * EAS_HWOpenFile
- *
- * Open a file for read or write
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT EAS_HWOpenFile (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_LOCATOR locator, EAS_FILE_HANDLE *pFile, EAS_FILE_MODE mode)
-{
- EAS_HW_FILE *file;
- int i;
-
- /* set return value to NULL */
- *pFile = NULL;
-
- /* only support read mode at this time */
- if (mode != EAS_FILE_READ)
- return EAS_ERROR_INVALID_FILE_MODE;
-
- /* find an empty entry in the file table */
- file = hwInstData->files;
- for (i = 0; i < EAS_MAX_FILE_HANDLES; i++)
- {
- /* is this slot being used? */
- if (file->pFile == NULL)
- {
- /* open the file */
- if (locator->path)
- file->pFile = fopen((const char*) locator->path, "rb");
- if (file->pFile == NULL)
- return EAS_ERROR_FILE_OPEN_FAILED;
-
-#ifdef DEBUG_FILE_IO
- EAS_ReportX(_EAS_SEVERITY_NOFILTER, "EAS_HWOpenFile: Open file %d\n", i);
-#endif
-
- /* initialize some values */
- file->bytesInBuffer = 0;
- file->readIndex = 0;
- file->filePos = 0;
- file->dup = EAS_FALSE;
-
- *pFile = file;
- return EAS_SUCCESS;
- }
- file++;
- }
-
- /* too many open files */
- return EAS_ERROR_MAX_FILES_OPEN;
-}
-
-/*----------------------------------------------------------------------------
- *
- * EAS_HWFillBuffer
- *
- * Fill buffer from file
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, hwInstData) hwInstData available for customer use */
-EAS_RESULT EAS_HWFillBuffer (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file)
-{
- /* reposition the file pointer */
- if (fseek(file->pFile, file->filePos, SEEK_SET) != 0)
- return EAS_ERROR_FILE_SEEK;
-
- /* read some data from the file */
- file->bytesInBuffer = (EAS_I32) fread(file->buffer, 1, EAS_FILE_BUFFER_SIZE, file->pFile);
- file->readIndex = 0;
- if (file->bytesInBuffer == 0)
- return EAS_EOF;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- *
- * EAS_HWReadFile
- *
- * Read data from a file
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, hwInstData) hwInstData available for customer use */
-EAS_RESULT EAS_HWReadFile (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, void *pBuffer, EAS_I32 n, EAS_I32 *pBytesRead)
-{
- EAS_RESULT result;
- EAS_I32 temp;
- EAS_U8 *p = pBuffer;
- EAS_I32 bytesLeft = n;
-
- *pBytesRead = 0;
-
- /* check handle integrity */
- if (file->pFile == NULL)
- return EAS_ERROR_INVALID_HANDLE;
-
-#ifdef DEBUG_FILE_IO
- EAS_ReportX(_EAS_SEVERITY_NOFILTER, "EAS_HWReadFile: Reading %d bytes from position %d\n", n, file->filePos);
-#endif
-
- /* try to fulfill request from buffer */
- for (;bytesLeft > 0;)
- {
- /* how many bytes can we get from buffer? */
- temp = file->bytesInBuffer - file->readIndex;
- if (temp > bytesLeft)
- temp = bytesLeft;
-
- /* copy data from buffer */
- EAS_HWMemCpy(p, &file->buffer[file->readIndex], temp);
- *pBytesRead += temp;
- file->readIndex += temp;
- file->filePos += temp;
- bytesLeft -= temp;
- p += temp;
-
- /* don't refill buffer if request is bigger than buffer */
- if ((bytesLeft == 0) || (bytesLeft >= EAS_FILE_BUFFER_SIZE))
- break;
-
- /* refill buffer */
- if ((result = EAS_HWFillBuffer(hwInstData, file)) != EAS_SUCCESS)
- return result;
- }
-
- /* more to read? do unbuffered read directly to target memory */
- if (bytesLeft)
- {
-
- /* position the file pointer */
- if (fseek(file->pFile, file->filePos, SEEK_SET) != 0)
- return EAS_ERROR_FILE_SEEK;
-
- /* read data in the buffer */
- /*lint -e{826} lint doesn't like this with STATIC_MEMORY defined for some reason */
- temp = (EAS_I32) fread(p, 1, (size_t) bytesLeft, file->pFile);
- *pBytesRead += temp;
- file->filePos += temp;
-
- /* reset buffer info */
- file->bytesInBuffer = 0;
- file->readIndex = 0;
- }
-
-#ifdef DEBUG_FILE_IO
- {
-#define BYTES_PER_LINE 16
- char str[BYTES_PER_LINE * 3 + 1];
- EAS_INT i;
- for (i = 0; i < (n > BYTES_PER_LINE ? BYTES_PER_LINE : n) ; i ++)
- sprintf(&str[i*3], "%02x ", ((EAS_U8*)pBuffer)[i]);
- if (i)
- EAS_ReportX(_EAS_SEVERITY_NOFILTER, "%s\n", str);
- }
-#endif
-
- /* were n bytes read? */
- if (*pBytesRead != n)
- return EAS_EOF;
-
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- *
- * EAS_HWGetByte
- *
- * Read a byte from a file
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, hwInstData) hwInstData available for customer use */
-EAS_RESULT EAS_HWGetByte (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, void *p)
-{
- EAS_RESULT result;
-
- /* check handle integrity */
- if (file->pFile == NULL)
- return EAS_ERROR_INVALID_HANDLE;
-
- /* use local buffer - do we have any data? */
- if (file->readIndex >= file->bytesInBuffer)
- {
- if ((result = EAS_HWFillBuffer(hwInstData, file)) != EAS_SUCCESS)
- return result;
-
- /* if nothing to read, return EOF */
- if (file->bytesInBuffer == 0)
- return EAS_EOF;
- }
-
- /* get a character from the buffer */
- *((EAS_U8*) p) = file->buffer[file->readIndex++];
-
-#ifdef DEBUG_FILE_IO
- EAS_ReportX(_EAS_SEVERITY_NOFILTER, "EAS_HWGetByte: Reading from position %d, byte = 0x%02x\n", file->filePos, *(EAS_U8*)p);
-#endif
-
- file->filePos++;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- *
- * EAS_HWGetWord
- *
- * Read a 16-bit value from the file
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT EAS_HWGetWord (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, void *p, EAS_BOOL msbFirst)
-{
- EAS_RESULT result;
- EAS_I32 count;
- EAS_U8 c[2];
-
-#ifdef DEBUG_FILE_IO
- EAS_ReportX(_EAS_SEVERITY_NOFILTER, "EAS_HWGetWord: Reading 2 bytes from position %d\n", file->filePos);
-#endif
-
- /* read 2 bytes from the file */
- if ((result = EAS_HWReadFile(hwInstData, file, c, 2, &count)) != EAS_SUCCESS)
- return result;
-
- /* order them as requested */
- if (msbFirst)
- *((EAS_U16*) p) = ((EAS_U16) c[0] << 8) | c[1];
- else
- *((EAS_U16*) p) = ((EAS_U16) c[1] << 8) | c[0];
-
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- *
- * EAS_HWGetDWord
- *
- * Read a 16-bit value from the file
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT EAS_HWGetDWord (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, void *p, EAS_BOOL msbFirst)
-{
- EAS_RESULT result;
- EAS_I32 count;
- EAS_U8 c[4];
-
-#ifdef DEBUG_FILE_IO
- EAS_ReportX(_EAS_SEVERITY_NOFILTER, "EAS_HWGetDWord: Reading 4 bytes from position %d\n", file->filePos);
-#endif
-
- /* read 4 bytes from the file */
- if ((result = EAS_HWReadFile(hwInstData, file, c, 4, &count)) != EAS_SUCCESS)
- return result;
-
- /* order them as requested */
- if (msbFirst)
- *((EAS_U32*) p) = ((EAS_U32) c[0] << 24) | ((EAS_U32) c[1] << 16) | ((EAS_U32) c[2] << 8) | c[3];
- else
- *((EAS_U32*) p) = ((EAS_U32) c[3] << 24) | ((EAS_U32) c[2] << 16) | ((EAS_U32) c[1] << 8) | c[0];
-
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- *
- * EAS_HWFilePos
- *
- * Returns the current location in the file
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, hwInstData) hwInstData available for customer use */
-EAS_RESULT EAS_HWFilePos (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, EAS_I32 *pPosition)
-{
-
- /* check handle integrity */
- if (file->pFile == NULL)
- return EAS_ERROR_INVALID_HANDLE;
-
- *pPosition = file->filePos;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- *
- * EAS_HWFileSeek
- *
- * Seek to a specific location in the file
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, hwInstData) hwInstData available for customer use */
-EAS_RESULT EAS_HWFileSeek (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, EAS_I32 position)
-{
- EAS_I32 newIndex;
-
- /* check handle integrity */
- if (file->pFile == NULL)
- return EAS_ERROR_INVALID_HANDLE;
-
-#ifdef DEBUG_FILE_IO
- EAS_ReportX(_EAS_SEVERITY_NOFILTER, "EAS_HWFileSeek: Seeking to new position %d\n", file->filePos);
-#endif
-
- /* is new position in current buffer? */
- newIndex = position - file->filePos + file->readIndex;
- if ((newIndex >= 0) && (newIndex < file->bytesInBuffer))
- {
- file->readIndex = newIndex;
- file->filePos = position;
- return EAS_SUCCESS;
- }
-
- /* save new position and reset buffer info so EAS_HWGetByte doesn't fail */
- file->filePos = position;
- file->bytesInBuffer = 0;
- file->readIndex = 0;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- *
- * EAS_HWFileSeekOfs
- *
- * Seek forward or back relative to the current position
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, hwInstData) hwInstData available for customer use */
-EAS_RESULT EAS_HWFileSeekOfs (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, EAS_I32 position)
-{
- EAS_I32 temp;
-
-#ifdef DEBUG_FILE_IO
- EAS_ReportX(_EAS_SEVERITY_NOFILTER, "EAS_HWFileSeekOfs: Seeking to new position %d\n", file->filePos + position);
-#endif
-
- /* check handle integrity */
- if (file->pFile == NULL)
- return EAS_ERROR_INVALID_HANDLE;
-
- /* is new position in current buffer? */
- temp = position + file->readIndex;
- if ((temp >= 0) && (temp < file->bytesInBuffer))
- {
- file->readIndex = temp;
- file->filePos += position;
- return EAS_SUCCESS;
- }
-
- /* save new position and reset buffer info so EAS_HWGetByte doesn't fail */
- file->filePos += position;
- file->bytesInBuffer = 0;
- file->readIndex = 0;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- *
- * EAS_HWFileLength
- *
- * Return the file length
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, hwInstData) hwInstData available for customer use */
-EAS_RESULT EAS_HWFileLength (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, EAS_I32 *pLength)
-{
- long pos;
-
- /* check handle integrity */
- if (file->pFile == NULL)
- return EAS_ERROR_INVALID_HANDLE;
-
- if ((pos = ftell(file->pFile)) == -1L)
- return EAS_ERROR_FILE_LENGTH;
- if (fseek(file->pFile, 0L, SEEK_END) != 0)
- return EAS_ERROR_FILE_LENGTH;
- if ((*pLength = ftell(file->pFile)) == -1L)
- return EAS_ERROR_FILE_LENGTH;
- if (fseek(file->pFile, pos, SEEK_SET) != 0)
- return EAS_ERROR_FILE_LENGTH;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- *
- * EAS_HWDupHandle
- *
- * Duplicate a file handle
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT EAS_HWDupHandle (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, EAS_FILE_HANDLE* pDupFile)
-{
- EAS_HW_FILE *dupfile;
- int i;
-
- /* check handle integrity */
- *pDupFile = NULL;
- if (file->pFile == NULL)
- return EAS_ERROR_INVALID_HANDLE;
-
- /* find an empty entry in the file table */
- dupfile = hwInstData->files;
- for (i = 0; i < EAS_MAX_FILE_HANDLES; i++)
- {
- /* is this slot being used? */
- if (dupfile->pFile == NULL)
- {
-
- /* copy info from the handle to be duplicated */
- dupfile->filePos = file->filePos;
- dupfile->pFile = file->pFile;
-
- /* set the duplicate handle flag */
- dupfile->dup = file->dup = EAS_TRUE;
-
- /* initialize some values */
- dupfile->bytesInBuffer = 0;
- dupfile->readIndex = 0;
-
- *pDupFile = dupfile;
- return EAS_SUCCESS;
- }
- dupfile++;
- }
-
- /* too many open files */
- return EAS_ERROR_MAX_FILES_OPEN;
-}
-
-/*----------------------------------------------------------------------------
- *
- * EAS_HWClose
- *
- * Wrapper for fclose function
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT EAS_HWCloseFile (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file1)
-{
- EAS_HW_FILE *file2,*dupFile;
- int i;
-
- /* check handle integrity */
- if (file1->pFile == NULL)
- return EAS_ERROR_INVALID_HANDLE;
-
- /* check for duplicate handle */
- if (file1->dup)
- {
- dupFile = NULL;
- file2 = hwInstData->files;
- for (i = 0; i < EAS_MAX_FILE_HANDLES; i++)
- {
- /* check for duplicate */
- if ((file1 != file2) && (file2->pFile == file1->pFile))
- {
- /* is there more than one duplicate? */
- if (dupFile != NULL)
- {
- /* clear this entry and return */
- file1->pFile = NULL;
- return EAS_SUCCESS;
- }
-
- /* this is the first duplicate found */
- dupFile = file2;
- }
- file2++;
- }
-
- /* there is only one duplicate, clear the dup flag */
- if (dupFile)
- dupFile->dup = EAS_FALSE;
- else
- /* if we get here, there's a serious problem */
- return EAS_ERROR_HANDLE_INTEGRITY;
-
- /* clear this entry and return */
- file1->pFile = NULL;
- return EAS_SUCCESS;
- }
-
- /* no duplicates - close the file */
- if (fclose(file1->pFile) != 0)
- return EAS_ERROR_CLOSE_FAILED;
-
- /* clear this entry and return */
- file1->pFile = NULL;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- *
- * EAS_HWVibrate
- *
- * Turn on/off vibrate function
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, hwInstData) hwInstData available for customer use */
-EAS_RESULT EAS_HWVibrate (EAS_HW_DATA_HANDLE hwInstData, EAS_BOOL state)
-{
- EAS_ReportX(_EAS_SEVERITY_NOFILTER, "Vibrate state: %d\n", state);
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- *
- * EAS_HWLED
- *
- * Turn on/off LED
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, hwInstData) hwInstData available for customer use */
-EAS_RESULT EAS_HWLED (EAS_HW_DATA_HANDLE hwInstData, EAS_BOOL state)
-{
- EAS_ReportX(_EAS_SEVERITY_NOFILTER, "LED state: %d\n", state);
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- *
- * EAS_HWBackLight
- *
- * Turn on/off backlight
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, hwInstData) hwInstData available for customer use */
-EAS_RESULT EAS_HWBackLight (EAS_HW_DATA_HANDLE hwInstData, EAS_BOOL state)
-{
- EAS_ReportX(_EAS_SEVERITY_NOFILTER, "Backlight state: %d\n", state);
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- *
- * EAS_HWYield
- *
- * This function is called periodically by the EAS library to give the
- * host an opportunity to allow other tasks to run. There are two ways to
- * use this call:
- *
- * If you have a multi-tasking OS, you can call the yield function in the
- * OS to allow other tasks to run. In this case, return EAS_FALSE to tell
- * the EAS library to continue processing when control returns from this
- * function.
- *
- * If tasks run in a single thread by sequential function calls (sometimes
- * call a "commutator loop"), return EAS_TRUE to cause the EAS Library to
- * return to the caller. Be sure to check the number of bytes rendered
- * before passing the audio buffer to the codec - it may not be filled.
- * The next call to EAS_Render will continue processing until the buffer
- * has been filled.
- *
- *----------------------------------------------------------------------------
-*/
-/*lint -esym(715, hwInstData) hwInstData available for customer use */
-EAS_BOOL EAS_HWYield (EAS_HW_DATA_HANDLE hwInstData)
-{
- /* put your code here */
- return EAS_FALSE;
-}
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 853 $
+ * $Date: 2007-09-05 09:54:17 -0700 (Wed, 05 Sep 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+#ifdef _lint
+#include "lint_stdlib.h"
+#else
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#endif
+
+#include "eas_host.h"
+
+// #define DEBUG_FILE_IO
+
+/* Only for debugging LED, vibrate, and backlight functions */
+#include "eas_report.h"
+
+#ifndef EAS_MAX_FILE_HANDLES
+#define EAS_MAX_FILE_HANDLES 32
+#endif
+
+#ifndef EAS_FILE_BUFFER_SIZE
+#define EAS_FILE_BUFFER_SIZE 32
+#endif
+
+/*
+ * this structure and the related function are here
+ * to support the ability to create duplicate handles
+ * and buffering into a single file. If the OS supports
+ * duplicate file handles natively, this code can be
+ * stripped to eliminate double-buffering.
+ */
+typedef struct eas_hw_file_tag
+{
+ FILE *pFile;
+ EAS_I32 bytesInBuffer;
+ EAS_I32 readIndex;
+ EAS_I32 filePos;
+ EAS_BOOL dup;
+ EAS_U8 buffer[EAS_FILE_BUFFER_SIZE];
+} EAS_HW_FILE;
+
+typedef struct eas_hw_inst_data_tag
+{
+ EAS_HW_FILE files[EAS_MAX_FILE_HANDLES];
+} EAS_HW_INST_DATA;
+
+/* local memory for files and streams */
+#ifdef _STATIC_MEMORY
+EAS_HW_INST_DATA fileData;
+#endif
+
+/*----------------------------------------------------------------------------
+ * EAS_HWInit
+ *
+ * Initialize host wrapper interface
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_HWInit (EAS_HW_DATA_HANDLE *pHWInstData)
+{
+
+ /* need to track file opens for duplicate handles */
+#ifndef _STATIC_MEMORY
+ *pHWInstData = malloc(sizeof(EAS_HW_INST_DATA));
+ if (!(*pHWInstData))
+ return EAS_ERROR_MALLOC_FAILED;
+#else
+ *pHWInstData = &fileData;
+#endif
+ EAS_HWMemSet(*pHWInstData, 0, sizeof(EAS_HW_INST_DATA));
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_HWShutdown
+ *
+ * Shut down host wrapper interface
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, hwInstData) hwInstData available for customer use */
+EAS_RESULT EAS_HWShutdown (EAS_HW_DATA_HANDLE hwInstData)
+{
+
+#ifndef _STATIC_MEMORY
+ free(hwInstData);
+#endif
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_HWMalloc
+ *
+ * Allocates dynamic memory
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, hwInstData) hwInstData available for customer use */
+#ifdef _STATIC_MEMORY
+/*lint -esym(715, size) not used in static memory model */
+#endif
+void *EAS_HWMalloc (EAS_HW_DATA_HANDLE hwInstData, EAS_I32 size)
+{
+#ifdef _STATIC_MEMORY
+ return NULL;
+#else
+ return malloc((EAS_U32)size);
+#endif
+}
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_HWFree
+ *
+ * Frees dynamic memory
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, hwInstData) hwInstData available for customer use */
+#ifdef _STATIC_MEMORY
+/*lint -esym(715, p) not used in static memory model */
+#endif
+void EAS_HWFree(EAS_HW_DATA_HANDLE hwInstData, void *p)
+{
+#ifndef _STATIC_MEMORY
+ free(p);
+#endif
+}
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_HWMemCpy
+ *
+ * Copy memory wrapper
+ *
+ *----------------------------------------------------------------------------
+*/
+void *EAS_HWMemCpy (void *dest, const void *src, EAS_I32 amount)
+{
+ return memcpy(dest,src,(size_t) amount);
+}
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_HWMemSet
+ *
+ * Set memory wrapper
+ *
+ *----------------------------------------------------------------------------
+*/
+void *EAS_HWMemSet (void *dest, int val, EAS_I32 amount)
+{
+ return memset(dest,val,(size_t) amount);
+}
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_HWMemCmp
+ *
+ * Compare memory wrapper
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_I32 EAS_HWMemCmp (const void *s1, const void *s2, EAS_I32 amount)
+{
+ return (EAS_I32) memcmp(s1, s2, (size_t) amount);
+}
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_HWOpenFile
+ *
+ * Open a file for read or write
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_HWOpenFile (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_LOCATOR locator, EAS_FILE_HANDLE *pFile, EAS_FILE_MODE mode)
+{
+ EAS_HW_FILE *file;
+ int i;
+
+ /* set return value to NULL */
+ *pFile = NULL;
+
+ /* only support read mode at this time */
+ if (mode != EAS_FILE_READ)
+ return EAS_ERROR_INVALID_FILE_MODE;
+
+ /* find an empty entry in the file table */
+ file = hwInstData->files;
+ for (i = 0; i < EAS_MAX_FILE_HANDLES; i++)
+ {
+ /* is this slot being used? */
+ if (file->pFile == NULL)
+ {
+ /* open the file */
+ if (locator->path)
+ file->pFile = fopen((const char*) locator->path, "rb");
+ if (file->pFile == NULL)
+ return EAS_ERROR_FILE_OPEN_FAILED;
+
+#ifdef DEBUG_FILE_IO
+ EAS_ReportX(_EAS_SEVERITY_NOFILTER, "EAS_HWOpenFile: Open file %d\n", i);
+#endif
+
+ /* initialize some values */
+ file->bytesInBuffer = 0;
+ file->readIndex = 0;
+ file->filePos = 0;
+ file->dup = EAS_FALSE;
+
+ *pFile = file;
+ return EAS_SUCCESS;
+ }
+ file++;
+ }
+
+ /* too many open files */
+ return EAS_ERROR_MAX_FILES_OPEN;
+}
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_HWFillBuffer
+ *
+ * Fill buffer from file
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, hwInstData) hwInstData available for customer use */
+EAS_RESULT EAS_HWFillBuffer (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file)
+{
+ /* reposition the file pointer */
+ if (fseek(file->pFile, file->filePos, SEEK_SET) != 0)
+ return EAS_ERROR_FILE_SEEK;
+
+ /* read some data from the file */
+ file->bytesInBuffer = (EAS_I32) fread(file->buffer, 1, EAS_FILE_BUFFER_SIZE, file->pFile);
+ file->readIndex = 0;
+ if (file->bytesInBuffer == 0)
+ return EAS_EOF;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_HWReadFile
+ *
+ * Read data from a file
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, hwInstData) hwInstData available for customer use */
+EAS_RESULT EAS_HWReadFile (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, void *pBuffer, EAS_I32 n, EAS_I32 *pBytesRead)
+{
+ EAS_RESULT result;
+ EAS_I32 temp;
+ EAS_U8 *p = pBuffer;
+ EAS_I32 bytesLeft = n;
+
+ *pBytesRead = 0;
+
+ /* check handle integrity */
+ if (file->pFile == NULL)
+ return EAS_ERROR_INVALID_HANDLE;
+
+#ifdef DEBUG_FILE_IO
+ EAS_ReportX(_EAS_SEVERITY_NOFILTER, "EAS_HWReadFile: Reading %d bytes from position %d\n", n, file->filePos);
+#endif
+
+ /* try to fulfill request from buffer */
+ for (;bytesLeft > 0;)
+ {
+ /* how many bytes can we get from buffer? */
+ temp = file->bytesInBuffer - file->readIndex;
+ if (temp > bytesLeft)
+ temp = bytesLeft;
+
+ /* copy data from buffer */
+ EAS_HWMemCpy(p, &file->buffer[file->readIndex], temp);
+ *pBytesRead += temp;
+ file->readIndex += temp;
+ file->filePos += temp;
+ bytesLeft -= temp;
+ p += temp;
+
+ /* don't refill buffer if request is bigger than buffer */
+ if ((bytesLeft == 0) || (bytesLeft >= EAS_FILE_BUFFER_SIZE))
+ break;
+
+ /* refill buffer */
+ if ((result = EAS_HWFillBuffer(hwInstData, file)) != EAS_SUCCESS)
+ return result;
+ }
+
+ /* more to read? do unbuffered read directly to target memory */
+ if (bytesLeft)
+ {
+
+ /* position the file pointer */
+ if (fseek(file->pFile, file->filePos, SEEK_SET) != 0)
+ return EAS_ERROR_FILE_SEEK;
+
+ /* read data in the buffer */
+ /*lint -e{826} lint doesn't like this with STATIC_MEMORY defined for some reason */
+ temp = (EAS_I32) fread(p, 1, (size_t) bytesLeft, file->pFile);
+ *pBytesRead += temp;
+ file->filePos += temp;
+
+ /* reset buffer info */
+ file->bytesInBuffer = 0;
+ file->readIndex = 0;
+ }
+
+#ifdef DEBUG_FILE_IO
+ {
+#define BYTES_PER_LINE 16
+ char str[BYTES_PER_LINE * 3 + 1];
+ EAS_INT i;
+ for (i = 0; i < (n > BYTES_PER_LINE ? BYTES_PER_LINE : n) ; i ++)
+ sprintf(&str[i*3], "%02x ", ((EAS_U8*)pBuffer)[i]);
+ if (i)
+ EAS_ReportX(_EAS_SEVERITY_NOFILTER, "%s\n", str);
+ }
+#endif
+
+ /* were n bytes read? */
+ if (*pBytesRead != n)
+ return EAS_EOF;
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_HWGetByte
+ *
+ * Read a byte from a file
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, hwInstData) hwInstData available for customer use */
+EAS_RESULT EAS_HWGetByte (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, void *p)
+{
+ EAS_RESULT result;
+
+ /* check handle integrity */
+ if (file->pFile == NULL)
+ return EAS_ERROR_INVALID_HANDLE;
+
+ /* use local buffer - do we have any data? */
+ if (file->readIndex >= file->bytesInBuffer)
+ {
+ if ((result = EAS_HWFillBuffer(hwInstData, file)) != EAS_SUCCESS)
+ return result;
+
+ /* if nothing to read, return EOF */
+ if (file->bytesInBuffer == 0)
+ return EAS_EOF;
+ }
+
+ /* get a character from the buffer */
+ *((EAS_U8*) p) = file->buffer[file->readIndex++];
+
+#ifdef DEBUG_FILE_IO
+ EAS_ReportX(_EAS_SEVERITY_NOFILTER, "EAS_HWGetByte: Reading from position %d, byte = 0x%02x\n", file->filePos, *(EAS_U8*)p);
+#endif
+
+ file->filePos++;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_HWGetWord
+ *
+ * Read a 16-bit value from the file
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_HWGetWord (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, void *p, EAS_BOOL msbFirst)
+{
+ EAS_RESULT result;
+ EAS_I32 count;
+ EAS_U8 c[2];
+
+#ifdef DEBUG_FILE_IO
+ EAS_ReportX(_EAS_SEVERITY_NOFILTER, "EAS_HWGetWord: Reading 2 bytes from position %d\n", file->filePos);
+#endif
+
+ /* read 2 bytes from the file */
+ if ((result = EAS_HWReadFile(hwInstData, file, c, 2, &count)) != EAS_SUCCESS)
+ return result;
+
+ /* order them as requested */
+ if (msbFirst)
+ *((EAS_U16*) p) = ((EAS_U16) c[0] << 8) | c[1];
+ else
+ *((EAS_U16*) p) = ((EAS_U16) c[1] << 8) | c[0];
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_HWGetDWord
+ *
+ * Read a 16-bit value from the file
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_HWGetDWord (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, void *p, EAS_BOOL msbFirst)
+{
+ EAS_RESULT result;
+ EAS_I32 count;
+ EAS_U8 c[4];
+
+#ifdef DEBUG_FILE_IO
+ EAS_ReportX(_EAS_SEVERITY_NOFILTER, "EAS_HWGetDWord: Reading 4 bytes from position %d\n", file->filePos);
+#endif
+
+ /* read 4 bytes from the file */
+ if ((result = EAS_HWReadFile(hwInstData, file, c, 4, &count)) != EAS_SUCCESS)
+ return result;
+
+ /* order them as requested */
+ if (msbFirst)
+ *((EAS_U32*) p) = ((EAS_U32) c[0] << 24) | ((EAS_U32) c[1] << 16) | ((EAS_U32) c[2] << 8) | c[3];
+ else
+ *((EAS_U32*) p) = ((EAS_U32) c[3] << 24) | ((EAS_U32) c[2] << 16) | ((EAS_U32) c[1] << 8) | c[0];
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_HWFilePos
+ *
+ * Returns the current location in the file
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, hwInstData) hwInstData available for customer use */
+EAS_RESULT EAS_HWFilePos (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, EAS_I32 *pPosition)
+{
+
+ /* check handle integrity */
+ if (file->pFile == NULL)
+ return EAS_ERROR_INVALID_HANDLE;
+
+ *pPosition = file->filePos;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_HWFileSeek
+ *
+ * Seek to a specific location in the file
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, hwInstData) hwInstData available for customer use */
+EAS_RESULT EAS_HWFileSeek (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, EAS_I32 position)
+{
+ EAS_I32 newIndex;
+
+ /* check handle integrity */
+ if (file->pFile == NULL)
+ return EAS_ERROR_INVALID_HANDLE;
+
+#ifdef DEBUG_FILE_IO
+ EAS_ReportX(_EAS_SEVERITY_NOFILTER, "EAS_HWFileSeek: Seeking to new position %d\n", file->filePos);
+#endif
+
+ /* is new position in current buffer? */
+ newIndex = position - file->filePos + file->readIndex;
+ if ((newIndex >= 0) && (newIndex < file->bytesInBuffer))
+ {
+ file->readIndex = newIndex;
+ file->filePos = position;
+ return EAS_SUCCESS;
+ }
+
+ /* save new position and reset buffer info so EAS_HWGetByte doesn't fail */
+ file->filePos = position;
+ file->bytesInBuffer = 0;
+ file->readIndex = 0;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_HWFileSeekOfs
+ *
+ * Seek forward or back relative to the current position
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, hwInstData) hwInstData available for customer use */
+EAS_RESULT EAS_HWFileSeekOfs (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, EAS_I32 position)
+{
+ EAS_I32 temp;
+
+#ifdef DEBUG_FILE_IO
+ EAS_ReportX(_EAS_SEVERITY_NOFILTER, "EAS_HWFileSeekOfs: Seeking to new position %d\n", file->filePos + position);
+#endif
+
+ /* check handle integrity */
+ if (file->pFile == NULL)
+ return EAS_ERROR_INVALID_HANDLE;
+
+ /* is new position in current buffer? */
+ temp = position + file->readIndex;
+ if ((temp >= 0) && (temp < file->bytesInBuffer))
+ {
+ file->readIndex = temp;
+ file->filePos += position;
+ return EAS_SUCCESS;
+ }
+
+ /* save new position and reset buffer info so EAS_HWGetByte doesn't fail */
+ file->filePos += position;
+ file->bytesInBuffer = 0;
+ file->readIndex = 0;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_HWFileLength
+ *
+ * Return the file length
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, hwInstData) hwInstData available for customer use */
+EAS_RESULT EAS_HWFileLength (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, EAS_I32 *pLength)
+{
+ long pos;
+
+ /* check handle integrity */
+ if (file->pFile == NULL)
+ return EAS_ERROR_INVALID_HANDLE;
+
+ if ((pos = ftell(file->pFile)) == -1L)
+ return EAS_ERROR_FILE_LENGTH;
+ if (fseek(file->pFile, 0L, SEEK_END) != 0)
+ return EAS_ERROR_FILE_LENGTH;
+ if ((*pLength = ftell(file->pFile)) == -1L)
+ return EAS_ERROR_FILE_LENGTH;
+ if (fseek(file->pFile, pos, SEEK_SET) != 0)
+ return EAS_ERROR_FILE_LENGTH;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_HWDupHandle
+ *
+ * Duplicate a file handle
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_HWDupHandle (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, EAS_FILE_HANDLE* pDupFile)
+{
+ EAS_HW_FILE *dupfile;
+ int i;
+
+ /* check handle integrity */
+ *pDupFile = NULL;
+ if (file->pFile == NULL)
+ return EAS_ERROR_INVALID_HANDLE;
+
+ /* find an empty entry in the file table */
+ dupfile = hwInstData->files;
+ for (i = 0; i < EAS_MAX_FILE_HANDLES; i++)
+ {
+ /* is this slot being used? */
+ if (dupfile->pFile == NULL)
+ {
+
+ /* copy info from the handle to be duplicated */
+ dupfile->filePos = file->filePos;
+ dupfile->pFile = file->pFile;
+
+ /* set the duplicate handle flag */
+ dupfile->dup = file->dup = EAS_TRUE;
+
+ /* initialize some values */
+ dupfile->bytesInBuffer = 0;
+ dupfile->readIndex = 0;
+
+ *pDupFile = dupfile;
+ return EAS_SUCCESS;
+ }
+ dupfile++;
+ }
+
+ /* too many open files */
+ return EAS_ERROR_MAX_FILES_OPEN;
+}
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_HWClose
+ *
+ * Wrapper for fclose function
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_HWCloseFile (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file1)
+{
+ EAS_HW_FILE *file2,*dupFile;
+ int i;
+
+ /* check handle integrity */
+ if (file1->pFile == NULL)
+ return EAS_ERROR_INVALID_HANDLE;
+
+ /* check for duplicate handle */
+ if (file1->dup)
+ {
+ dupFile = NULL;
+ file2 = hwInstData->files;
+ for (i = 0; i < EAS_MAX_FILE_HANDLES; i++)
+ {
+ /* check for duplicate */
+ if ((file1 != file2) && (file2->pFile == file1->pFile))
+ {
+ /* is there more than one duplicate? */
+ if (dupFile != NULL)
+ {
+ /* clear this entry and return */
+ file1->pFile = NULL;
+ return EAS_SUCCESS;
+ }
+
+ /* this is the first duplicate found */
+ dupFile = file2;
+ }
+ file2++;
+ }
+
+ /* there is only one duplicate, clear the dup flag */
+ if (dupFile)
+ dupFile->dup = EAS_FALSE;
+ else
+ /* if we get here, there's a serious problem */
+ return EAS_ERROR_HANDLE_INTEGRITY;
+
+ /* clear this entry and return */
+ file1->pFile = NULL;
+ return EAS_SUCCESS;
+ }
+
+ /* no duplicates - close the file */
+ if (fclose(file1->pFile) != 0)
+ return EAS_ERROR_CLOSE_FAILED;
+
+ /* clear this entry and return */
+ file1->pFile = NULL;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_HWVibrate
+ *
+ * Turn on/off vibrate function
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, hwInstData) hwInstData available for customer use */
+EAS_RESULT EAS_HWVibrate (EAS_HW_DATA_HANDLE hwInstData, EAS_BOOL state)
+{
+ EAS_ReportX(_EAS_SEVERITY_NOFILTER, "Vibrate state: %d\n", state);
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_HWLED
+ *
+ * Turn on/off LED
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, hwInstData) hwInstData available for customer use */
+EAS_RESULT EAS_HWLED (EAS_HW_DATA_HANDLE hwInstData, EAS_BOOL state)
+{
+ EAS_ReportX(_EAS_SEVERITY_NOFILTER, "LED state: %d\n", state);
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_HWBackLight
+ *
+ * Turn on/off backlight
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, hwInstData) hwInstData available for customer use */
+EAS_RESULT EAS_HWBackLight (EAS_HW_DATA_HANDLE hwInstData, EAS_BOOL state)
+{
+ EAS_ReportX(_EAS_SEVERITY_NOFILTER, "Backlight state: %d\n", state);
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_HWYield
+ *
+ * This function is called periodically by the EAS library to give the
+ * host an opportunity to allow other tasks to run. There are two ways to
+ * use this call:
+ *
+ * If you have a multi-tasking OS, you can call the yield function in the
+ * OS to allow other tasks to run. In this case, return EAS_FALSE to tell
+ * the EAS library to continue processing when control returns from this
+ * function.
+ *
+ * If tasks run in a single thread by sequential function calls (sometimes
+ * call a "commutator loop"), return EAS_TRUE to cause the EAS Library to
+ * return to the caller. Be sure to check the number of bytes rendered
+ * before passing the audio buffer to the codec - it may not be filled.
+ * The next call to EAS_Render will continue processing until the buffer
+ * has been filled.
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, hwInstData) hwInstData available for customer use */
+EAS_BOOL EAS_HWYield (EAS_HW_DATA_HANDLE hwInstData)
+{
+ /* put your code here */
+ return EAS_FALSE;
+}